ZGlmZiAtLWdpdCBhLy5naXRpZ25vcmUgYi8uZ2l0aWdub3JlCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNiM2ZkNzMKLS0tIC9kZXYvbnVsbAorKysgYi8uZ2l0aWdub3JlCkBAIC0wLDAgKzEsNiBAQAordGFyZ2V0LworKi90YXJnZXQvCituYnByb2plY3QvcHJpdmF0ZS8KKy5tMi8KK3dlYnJldgorc3JjL21haW4vamF2YS9qYXZheC9tYWlsL1ZlcnNpb25cLmphdmEKZGlmZiAtLWdpdCBhLy5oZ2lnbm9yZSBiLy5oZ2lnbm9yZQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNzc0ZGVjCi0tLSAvZGV2L251bGwKKysrIGIvLmhnaWdub3JlCkBAIC0wLDAgKzEsNiBAQAorXnRhcmdldC8KKy90YXJnZXQvCitebmJwcm9qZWN0L3ByaXZhdGUvCiteXC5tMi8KK153ZWJyZXYKK15zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvVmVyc2lvblwuamF2YSQKZGlmZiAtLWdpdCBhLy5oZ3RhZ3MgYi8uaGd0YWdzCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRmY2RhNTEKLS0tIC9kZXYvbnVsbAorKysgYi8uaGd0YWdzCkBAIC0wLDAgKzEsMzMgQEAKK2RhMTljYmIyMDE0NTkwMzQ4MjczOTgzODE1YjM1YWM4YTQ4NzE3YzUgSkFWQU1BSUwtMV80XzEKK2RmYjcwOTkxOTM1M2VlYzUzZTlkY2E2MWIzNzkxNjMxODZmNGQxNTQgMS40LjItYmV0YQorMjRjODlkMTAzNzU1ZDQ5ZDYyYzY3MzY4Y2VhNWMxM2IzOWMyYjM5OSBKQVZBTUFJTC0xXzRfMgorZGZhYTU2ZTQ3Mzg2NTQ0ZjQwMDJhZGU1MTFmMmNiMDIwNzEwNzczNCBKQVZBTUFJTC0xXzRfMy1SQzEKKzIwMGI1YTcyOWNmZjI4NmQxMjg4YjY0Mjg3ZGMzMzkyMzNjZDUwNDAgSkFWQU1BSUwtMV80XzMKKzIwMGI1YTcyOWNmZjI4NmQxMjg4YjY0Mjg3ZGMzMzkyMzNjZDUwNDAgSkFWQU1BSUwtMV80XzMKKzFmM2Y2OTllZDE3YWEyYzc0MGViMDlkZWY1ZDgzZGQ4MDY3MTc0OGEgSkFWQU1BSUwtMV80XzMKKzBhOTk3MjhlZTFkMWQzZDJiMjdhYjc2ZTBkYjA1ZDk2NTJlZTEwNjMgSkFWQU1BSUwtMV80XzQtUkMxCis5Y2ZmMjVjNmQ3M2M4Zjg2ZmYyN2Y0Y2IzOWY3YzNjMDkyYzM0ZGQ3IEpBVkFNQUlMLTFfNF80CitjZTAwZDU5MDA3NTczOTdjYmM3OTQzYjY4NjAzNWU4YjI3YWE5NDQ5IEpBVkFNQUlMLTFfNF81LVJDMQorZTBlY2UzOGRiOWEwYTZiNDZmZTAzNTc1YmZmYmE2NjA1NjAzNzYxZCBKQVZBTUFJTC0xXzRfNQorZGE2ZTI1NjA4ZWMxNzVjZjA1NTZjNmI3YjdkMWZlZTQwY2JlMDljNSBKQVZBTUFJTC0xXzRfNi1SQzEKK2I5YzAwYjBjZjNjZjU2MDA3N2NkM2MzOTNjNTk3ZTRlZDlmMWJmMTQgSkFWQU1BSUwtMV80XzYKK2I5YzAwYjBjZjNjZjU2MDA3N2NkM2MzOTNjNTk3ZTRlZDlmMWJmMTQgSkFWQU1BSUwtMV80XzYKKzNkYmE4Yzc4NjM0ZmNiMWZmZDlhMzJlODQwYmNmYWI5MWE4M2E1NTEgSkFWQU1BSUwtMV80XzYKK2JhNGU3MzRmZGZhOTkxNmMwZTg4NjdiOGVhOGI0MjE4ZTI3NmJlMGUgSkFWQU1BSUwtMV80XzcKK2ZhMWVkYjgxNzg3ZDBiMjY4MjhjZWU0MzhhNmQ1NGRmNjE5ZmE2ZGEgSkFWQU1BSUwtMV81XzAKK2Y2YzRkMzE4MWYwNmRlMDgwYmIzYjEwNzM4MjQ2NGZhZDg3NWRmZGIgSkFWQU1BSUwtMV81XzEKKzFjYmUzODdmZDY4NDFhZTBmMWM1YzZkYTFlN2Y4NzJjNDkyNTVmMWQgSkFWQU1BSUwtMV81XzIKK2E2MzY2M2IxYmIwN2FlODEyZjljZjEzYjAzZmJjZjNlOGUxMjk1MjEgSkFWQU1BSUwtMV81XzMKKzE1YjViYTliNTg3MTJkMDY0MTc4YjI1MzBhMmI3Zjg5ZTFkMmViYzEgSkFWQU1BSUwtMV81XzQKKzZmODU0YjcwMzE5MDY1ODFmMWM5MWJmNzBhMTM3MzRjYmVjMThlMGEgSkFWQU1BSUwtMV81XzUKK2RkY2I4NjA4Y2M2NTRlMjczZGExY2QxMTk2OWE0MWQ2MGM3YzA3ZGIgSkFWQU1BSUwtMV81XzYKK2Q5MGIwMjMwZmZkZTM2ZTcxZDA2Y2M4ZWZjMzVjMWJjNjYyZDM3MzEgSkFWQU1BSUwtMV82XzAtUkMxCis5NDY2NDMwMjFmN2E0ZmFjZGJmMWQ5ODIzOGIyY2ZlZTI4ZTY1NmVmIEpBVkFNQUlMLTFfNl8wLVJDMgorZTRjYjNiM2QzYWVlZmQxYWZhYjdlOTY1MzE3NjA0YmNkNjY0NDcwMCBKQVZBTUFJTC0xXzZfMAorZGZiNzA5OTE5MzUzZWVjNTNlOWRjYTYxYjM3OTE2MzE4NmY0ZDE1NCAxLjQuMi1iZXRhCiswMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwIDEuNC4yLWJldGEKKzQ4ZjgxNDJkMmRjNDcxYTkzODY2ZjFkYTZjMTM0MzYzNzFkOTAyNGMgSkFWQU1BSUwtMV82XzEKK2Q4NDEwMjkxZjhlZDEwOGU5NGNlMDY2NGUxZjFhMDFkOWE1MmUxNGEgSkFWQU1BSUxfMV82XzIKK2Q4NDEwMjkxZjhlZDEwOGU5NGNlMDY2NGUxZjFhMDFkOWE1MmUxNGEgSkFWQU1BSUxfMV82XzIKKzAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAgSkFWQU1BSUxfMV82XzIKKzNlNjU4YTBmYjdiOGQzNjkxMmRmMGIyOWY5ODY4OTQ2ZmJmZmMxOWMgSkFWQU1BSUwtMV82XzIKZGlmZiAtLWdpdCBhL0NPTlRSSUJVVElORy5tZCBiL0NPTlRSSUJVVElORy5tZApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kYjFmMTQ2Ci0tLSAvZGV2L251bGwKKysrIGIvQ09OVFJJQlVUSU5HLm1kCkBAIC0wLDAgKzEsNDUgQEAKKyMgQ29udHJpYnV0aW5nIHRvIEVjbGlwc2UgUHJvamVjdCBmb3IgSmF2YU1haWwKKworVGhhbmtzIGZvciB5b3VyIGludGVyZXN0IGluIHRoaXMgcHJvamVjdC4KKworIyMgUHJvamVjdCBkZXNjcmlwdGlvbgorCitUaGUgSmF2YU1haWwgQVBJIHByb3ZpZGVzIGEgcGxhdGZvcm0taW5kZXBlbmRlbnQgYW5kIHByb3RvY29sLWluZGVwZW5kZW50CitmcmFtZXdvcmsgdG8gYnVpbGQgbWFpbCBhbmQgbWVzc2FnaW5nIGFwcGxpY2F0aW9ucy4gVGhlIEphdmFNYWlsIEFQSSBpcworYXZhaWxhYmxlIGFzIGFuIG9wdGlvbmFsIHBhY2thZ2UgZm9yIHVzZSB3aXRoIHRoZSBKYXZhIFNFIHBsYXRmb3JtIGFuZCBpcyBhbHNvCitpbmNsdWRlZCBpbiB0aGUgSmF2YSBFRSBwbGF0Zm9ybS4KKworKiBodHRwczovL3Byb2plY3RzLmVjbGlwc2Uub3JnL3Byb2plY3RzL2VlNGouamF2YW1haWwKKworIyMgRGV2ZWxvcGVyIHJlc291cmNlcworCitJbmZvcm1hdGlvbiByZWdhcmRpbmcgc291cmNlIGNvZGUgbWFuYWdlbWVudCwgYnVpbGRzLCBjb2Rpbmcgc3RhbmRhcmRzLCBhbmQKK21vcmUuCisKKyogaHR0cHM6Ly9wcm9qZWN0cy5lY2xpcHNlLm9yZy9wcm9qZWN0cy9lZTRqLmphdmFtYWlsL2RldmVsb3BlcgorCitUaGUgcHJvamVjdCBtYWludGFpbnMgdGhlIGZvbGxvd2luZyBzb3VyY2UgY29kZSByZXBvc2l0b3JpZXMKKworKiBodHRwczovL2dpdGh1Yi5jb20vZWNsaXBzZS1lZTRqL2phdmFtYWlsCisKKyMjIEVjbGlwc2UgQ29udHJpYnV0b3IgQWdyZWVtZW50CisKK0JlZm9yZSB5b3VyIGNvbnRyaWJ1dGlvbiBjYW4gYmUgYWNjZXB0ZWQgYnkgdGhlIHByb2plY3QgdGVhbSBjb250cmlidXRvcnMgbXVzdAorZWxlY3Ryb25pY2FsbHkgc2lnbiB0aGUgRWNsaXBzZSBDb250cmlidXRvciBBZ3JlZW1lbnQgKEVDQSkuCisKKyogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9FQ0EucGhwCisKK0NvbW1pdHMgdGhhdCBhcmUgcHJvdmlkZWQgYnkgbm9uLWNvbW1pdHRlcnMgbXVzdCBoYXZlIGEgU2lnbmVkLW9mZi1ieSBmaWVsZCBpbgordGhlIGZvb3RlciBpbmRpY2F0aW5nIHRoYXQgdGhlIGF1dGhvciBpcyBhd2FyZSBvZiB0aGUgdGVybXMgYnkgd2hpY2ggdGhlCitjb250cmlidXRpb24gaGFzIGJlZW4gcHJvdmlkZWQgdG8gdGhlIHByb2plY3QuIFRoZSBub24tY29tbWl0dGVyIG11c3QKK2FkZGl0aW9uYWxseSBoYXZlIGFuIEVjbGlwc2UgRm91bmRhdGlvbiBhY2NvdW50IGFuZCBtdXN0IGhhdmUgYSBzaWduZWQgRWNsaXBzZQorQ29udHJpYnV0b3IgQWdyZWVtZW50IChFQ0EpIG9uIGZpbGUuCisKK0ZvciBtb3JlIGluZm9ybWF0aW9uLCBwbGVhc2Ugc2VlIHRoZSBFY2xpcHNlIENvbW1pdHRlciBIYW5kYm9vazoKK2h0dHBzOi8vd3d3LmVjbGlwc2Uub3JnL3Byb2plY3RzL2hhbmRib29rLyNyZXNvdXJjZXMtY29tbWl0CisKKyMjIENvbnRhY3QKKworQ29udGFjdCB0aGUgcHJvamVjdCBkZXZlbG9wZXJzIHZpYSB0aGUgcHJvamVjdCdzICJkZXYiIGxpc3QuCisKKyogaHR0cHM6Ly9hY2NvdW50cy5lY2xpcHNlLm9yZy9tYWlsaW5nLWxpc3QvamF2YW1haWwtZGV2CmRpZmYgLS1naXQgYS9MSUNFTlNFLm1kIGIvTElDRU5TRS5tZApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ZGUzZDFiCi0tLSAvZGV2L251bGwKKysrIGIvTElDRU5TRS5tZApAQCAtMCwwICsxLDYzNyBAQAorIyBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIC0gdiAyLjAKKworICAgICAgICBUSEUgQUNDT01QQU5ZSU5HIFBST0dSQU0gSVMgUFJPVklERUQgVU5ERVIgVEhFIFRFUk1TIE9GIFRISVMgRUNMSVBTRQorICAgICAgICBQVUJMSUMgTElDRU5TRSAoIkFHUkVFTUVOVCIpLiBBTlkgVVNFLCBSRVBST0RVQ1RJT04gT1IgRElTVFJJQlVUSU9OCisgICAgICAgIE9GIFRIRSBQUk9HUkFNIENPTlNUSVRVVEVTIFJFQ0lQSUVOVCdTIEFDQ0VQVEFOQ0UgT0YgVEhJUyBBR1JFRU1FTlQuCisKKyAgICAxLiBERUZJTklUSU9OUworCisgICAgIkNvbnRyaWJ1dGlvbiIgbWVhbnM6CisKKyAgICAgIGEpIGluIHRoZSBjYXNlIG9mIHRoZSBpbml0aWFsIENvbnRyaWJ1dG9yLCB0aGUgaW5pdGlhbCBjb250ZW50CisgICAgICAgICBEaXN0cmlidXRlZCB1bmRlciB0aGlzIEFncmVlbWVudCwgYW5kCisKKyAgICAgIGIpIGluIHRoZSBjYXNlIG9mIGVhY2ggc3Vic2VxdWVudCBDb250cmlidXRvcjogCisgICAgICAgICBpKSBjaGFuZ2VzIHRvIHRoZSBQcm9ncmFtLCBhbmQgCisgICAgICAgICBpaSkgYWRkaXRpb25zIHRvIHRoZSBQcm9ncmFtOworICAgICAgd2hlcmUgc3VjaCBjaGFuZ2VzIGFuZC9vciBhZGRpdGlvbnMgdG8gdGhlIFByb2dyYW0gb3JpZ2luYXRlIGZyb20KKyAgICAgIGFuZCBhcmUgRGlzdHJpYnV0ZWQgYnkgdGhhdCBwYXJ0aWN1bGFyIENvbnRyaWJ1dG9yLiBBIENvbnRyaWJ1dGlvbgorICAgICAgIm9yaWdpbmF0ZXMiIGZyb20gYSBDb250cmlidXRvciBpZiBpdCB3YXMgYWRkZWQgdG8gdGhlIFByb2dyYW0gYnkKKyAgICAgIHN1Y2ggQ29udHJpYnV0b3IgaXRzZWxmIG9yIGFueW9uZSBhY3Rpbmcgb24gc3VjaCBDb250cmlidXRvcidzIGJlaGFsZi4KKyAgICAgIENvbnRyaWJ1dGlvbnMgZG8gbm90IGluY2x1ZGUgY2hhbmdlcyBvciBhZGRpdGlvbnMgdG8gdGhlIFByb2dyYW0gdGhhdAorICAgICAgYXJlIG5vdCBNb2RpZmllZCBXb3Jrcy4KKworICAgICJDb250cmlidXRvciIgbWVhbnMgYW55IHBlcnNvbiBvciBlbnRpdHkgdGhhdCBEaXN0cmlidXRlcyB0aGUgUHJvZ3JhbS4KKworICAgICJMaWNlbnNlZCBQYXRlbnRzIiBtZWFuIHBhdGVudCBjbGFpbXMgbGljZW5zYWJsZSBieSBhIENvbnRyaWJ1dG9yIHdoaWNoCisgICAgYXJlIG5lY2Vzc2FyaWx5IGluZnJpbmdlZCBieSB0aGUgdXNlIG9yIHNhbGUgb2YgaXRzIENvbnRyaWJ1dGlvbiBhbG9uZQorICAgIG9yIHdoZW4gY29tYmluZWQgd2l0aCB0aGUgUHJvZ3JhbS4KKworICAgICJQcm9ncmFtIiBtZWFucyB0aGUgQ29udHJpYnV0aW9ucyBEaXN0cmlidXRlZCBpbiBhY2NvcmRhbmNlIHdpdGggdGhpcworICAgIEFncmVlbWVudC4KKworICAgICJSZWNpcGllbnQiIG1lYW5zIGFueW9uZSB3aG8gcmVjZWl2ZXMgdGhlIFByb2dyYW0gdW5kZXIgdGhpcyBBZ3JlZW1lbnQKKyAgICBvciBhbnkgU2Vjb25kYXJ5IExpY2Vuc2UgKGFzIGFwcGxpY2FibGUpLCBpbmNsdWRpbmcgQ29udHJpYnV0b3JzLgorCisgICAgIkRlcml2YXRpdmUgV29ya3MiIHNoYWxsIG1lYW4gYW55IHdvcmssIHdoZXRoZXIgaW4gU291cmNlIENvZGUgb3Igb3RoZXIKKyAgICBmb3JtLCB0aGF0IGlzIGJhc2VkIG9uIChvciBkZXJpdmVkIGZyb20pIHRoZSBQcm9ncmFtIGFuZCBmb3Igd2hpY2ggdGhlCisgICAgZWRpdG9yaWFsIHJldmlzaW9ucywgYW5ub3RhdGlvbnMsIGVsYWJvcmF0aW9ucywgb3Igb3RoZXIgbW9kaWZpY2F0aW9ucworICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLgorCisgICAgIk1vZGlmaWVkIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrIGluIFNvdXJjZSBDb2RlIG9yIG90aGVyIGZvcm0gdGhhdAorICAgIHJlc3VsdHMgZnJvbSBhbiBhZGRpdGlvbiB0bywgZGVsZXRpb24gZnJvbSwgb3IgbW9kaWZpY2F0aW9uIG9mIHRoZQorICAgIGNvbnRlbnRzIG9mIHRoZSBQcm9ncmFtLCBpbmNsdWRpbmcsIGZvciBwdXJwb3NlcyBvZiBjbGFyaXR5IGFueSBuZXcgZmlsZQorICAgIGluIFNvdXJjZSBDb2RlIGZvcm0gdGhhdCBjb250YWlucyBhbnkgY29udGVudHMgb2YgdGhlIFByb2dyYW0uIE1vZGlmaWVkCisgICAgV29ya3Mgc2hhbGwgbm90IGluY2x1ZGUgd29ya3MgdGhhdCBjb250YWluIG9ubHkgZGVjbGFyYXRpb25zLAorICAgIGludGVyZmFjZXMsIHR5cGVzLCBjbGFzc2VzLCBzdHJ1Y3R1cmVzLCBvciBmaWxlcyBvZiB0aGUgUHJvZ3JhbSBzb2xlbHkKKyAgICBpbiBlYWNoIGNhc2UgaW4gb3JkZXIgdG8gbGluayB0bywgYmluZCBieSBuYW1lLCBvciBzdWJjbGFzcyB0aGUgUHJvZ3JhbQorICAgIG9yIE1vZGlmaWVkIFdvcmtzIHRoZXJlb2YuCisKKyAgICAiRGlzdHJpYnV0ZSIgbWVhbnMgdGhlIGFjdHMgb2YgYSkgZGlzdHJpYnV0aW5nIG9yIGIpIG1ha2luZyBhdmFpbGFibGUKKyAgICBpbiBhbnkgbWFubmVyIHRoYXQgZW5hYmxlcyB0aGUgdHJhbnNmZXIgb2YgYSBjb3B5LgorCisgICAgIlNvdXJjZSBDb2RlIiBtZWFucyB0aGUgZm9ybSBvZiBhIFByb2dyYW0gcHJlZmVycmVkIGZvciBtYWtpbmcKKyAgICBtb2RpZmljYXRpb25zLCBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLAorICAgIGRvY3VtZW50YXRpb24gc291cmNlLCBhbmQgY29uZmlndXJhdGlvbiBmaWxlcy4KKworICAgICJTZWNvbmRhcnkgTGljZW5zZSIgbWVhbnMgZWl0aGVyIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAgICBWZXJzaW9uIDIuMCwgb3IgYW55IGxhdGVyIHZlcnNpb25zIG9mIHRoYXQgbGljZW5zZSwgaW5jbHVkaW5nIGFueQorICAgIGV4Y2VwdGlvbnMgb3IgYWRkaXRpb25hbCBwZXJtaXNzaW9ucyBhcyBpZGVudGlmaWVkIGJ5IHRoZSBpbml0aWFsCisgICAgQ29udHJpYnV0b3IuCisKKyAgICAyLiBHUkFOVCBPRiBSSUdIVFMKKworICAgICAgYSkgU3ViamVjdCB0byB0aGUgdGVybXMgb2YgdGhpcyBBZ3JlZW1lbnQsIGVhY2ggQ29udHJpYnV0b3IgaGVyZWJ5CisgICAgICBncmFudHMgUmVjaXBpZW50IGEgbm9uLWV4Y2x1c2l2ZSwgd29ybGR3aWRlLCByb3lhbHR5LWZyZWUgY29weXJpZ2h0CisgICAgICBsaWNlbnNlIHRvIHJlcHJvZHVjZSwgcHJlcGFyZSBEZXJpdmF0aXZlIFdvcmtzIG9mLCBwdWJsaWNseSBkaXNwbGF5LAorICAgICAgcHVibGljbHkgcGVyZm9ybSwgRGlzdHJpYnV0ZSBhbmQgc3VibGljZW5zZSB0aGUgQ29udHJpYnV0aW9uIG9mIHN1Y2gKKyAgICAgIENvbnRyaWJ1dG9yLCBpZiBhbnksIGFuZCBzdWNoIERlcml2YXRpdmUgV29ya3MuCisKKyAgICAgIGIpIFN1YmplY3QgdG8gdGhlIHRlcm1zIG9mIHRoaXMgQWdyZWVtZW50LCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieQorICAgICAgZ3JhbnRzIFJlY2lwaWVudCBhIG5vbi1leGNsdXNpdmUsIHdvcmxkd2lkZSwgcm95YWx0eS1mcmVlIHBhdGVudAorICAgICAgbGljZW5zZSB1bmRlciBMaWNlbnNlZCBQYXRlbnRzIHRvIG1ha2UsIHVzZSwgc2VsbCwgb2ZmZXIgdG8gc2VsbCwKKyAgICAgIGltcG9ydCBhbmQgb3RoZXJ3aXNlIHRyYW5zZmVyIHRoZSBDb250cmlidXRpb24gb2Ygc3VjaCBDb250cmlidXRvciwKKyAgICAgIGlmIGFueSwgaW4gU291cmNlIENvZGUgb3Igb3RoZXIgZm9ybS4gVGhpcyBwYXRlbnQgbGljZW5zZSBzaGFsbAorICAgICAgYXBwbHkgdG8gdGhlIGNvbWJpbmF0aW9uIG9mIHRoZSBDb250cmlidXRpb24gYW5kIHRoZSBQcm9ncmFtIGlmLCBhdAorICAgICAgdGhlIHRpbWUgdGhlIENvbnRyaWJ1dGlvbiBpcyBhZGRlZCBieSB0aGUgQ29udHJpYnV0b3IsIHN1Y2ggYWRkaXRpb24KKyAgICAgIG9mIHRoZSBDb250cmlidXRpb24gY2F1c2VzIHN1Y2ggY29tYmluYXRpb24gdG8gYmUgY292ZXJlZCBieSB0aGUKKyAgICAgIExpY2Vuc2VkIFBhdGVudHMuIFRoZSBwYXRlbnQgbGljZW5zZSBzaGFsbCBub3QgYXBwbHkgdG8gYW55IG90aGVyCisgICAgICBjb21iaW5hdGlvbnMgd2hpY2ggaW5jbHVkZSB0aGUgQ29udHJpYnV0aW9uLiBObyBoYXJkd2FyZSBwZXIgc2UgaXMKKyAgICAgIGxpY2Vuc2VkIGhlcmV1bmRlci4KKworICAgICAgYykgUmVjaXBpZW50IHVuZGVyc3RhbmRzIHRoYXQgYWx0aG91Z2ggZWFjaCBDb250cmlidXRvciBncmFudHMgdGhlCisgICAgICBsaWNlbnNlcyB0byBpdHMgQ29udHJpYnV0aW9ucyBzZXQgZm9ydGggaGVyZWluLCBubyBhc3N1cmFuY2VzIGFyZQorICAgICAgcHJvdmlkZWQgYnkgYW55IENvbnRyaWJ1dG9yIHRoYXQgdGhlIFByb2dyYW0gZG9lcyBub3QgaW5mcmluZ2UgdGhlCisgICAgICBwYXRlbnQgb3Igb3RoZXIgaW50ZWxsZWN0dWFsIHByb3BlcnR5IHJpZ2h0cyBvZiBhbnkgb3RoZXIgZW50aXR5LgorICAgICAgRWFjaCBDb250cmlidXRvciBkaXNjbGFpbXMgYW55IGxpYWJpbGl0eSB0byBSZWNpcGllbnQgZm9yIGNsYWltcworICAgICAgYnJvdWdodCBieSBhbnkgb3RoZXIgZW50aXR5IGJhc2VkIG9uIGluZnJpbmdlbWVudCBvZiBpbnRlbGxlY3R1YWwKKyAgICAgIHByb3BlcnR5IHJpZ2h0cyBvciBvdGhlcndpc2UuIEFzIGEgY29uZGl0aW9uIHRvIGV4ZXJjaXNpbmcgdGhlCisgICAgICByaWdodHMgYW5kIGxpY2Vuc2VzIGdyYW50ZWQgaGVyZXVuZGVyLCBlYWNoIFJlY2lwaWVudCBoZXJlYnkKKyAgICAgIGFzc3VtZXMgc29sZSByZXNwb25zaWJpbGl0eSB0byBzZWN1cmUgYW55IG90aGVyIGludGVsbGVjdHVhbAorICAgICAgcHJvcGVydHkgcmlnaHRzIG5lZWRlZCwgaWYgYW55LiBGb3IgZXhhbXBsZSwgaWYgYSB0aGlyZCBwYXJ0eQorICAgICAgcGF0ZW50IGxpY2Vuc2UgaXMgcmVxdWlyZWQgdG8gYWxsb3cgUmVjaXBpZW50IHRvIERpc3RyaWJ1dGUgdGhlCisgICAgICBQcm9ncmFtLCBpdCBpcyBSZWNpcGllbnQncyByZXNwb25zaWJpbGl0eSB0byBhY3F1aXJlIHRoYXQgbGljZW5zZQorICAgICAgYmVmb3JlIGRpc3RyaWJ1dGluZyB0aGUgUHJvZ3JhbS4KKworICAgICAgZCkgRWFjaCBDb250cmlidXRvciByZXByZXNlbnRzIHRoYXQgdG8gaXRzIGtub3dsZWRnZSBpdCBoYXMKKyAgICAgIHN1ZmZpY2llbnQgY29weXJpZ2h0IHJpZ2h0cyBpbiBpdHMgQ29udHJpYnV0aW9uLCBpZiBhbnksIHRvIGdyYW50CisgICAgICB0aGUgY29weXJpZ2h0IGxpY2Vuc2Ugc2V0IGZvcnRoIGluIHRoaXMgQWdyZWVtZW50LgorCisgICAgICBlKSBOb3R3aXRoc3RhbmRpbmcgdGhlIHRlcm1zIG9mIGFueSBTZWNvbmRhcnkgTGljZW5zZSwgbm8KKyAgICAgIENvbnRyaWJ1dG9yIG1ha2VzIGFkZGl0aW9uYWwgZ3JhbnRzIHRvIGFueSBSZWNpcGllbnQgKG90aGVyIHRoYW4KKyAgICAgIHRob3NlIHNldCBmb3J0aCBpbiB0aGlzIEFncmVlbWVudCkgYXMgYSByZXN1bHQgb2Ygc3VjaCBSZWNpcGllbnQncworICAgICAgcmVjZWlwdCBvZiB0aGUgUHJvZ3JhbSB1bmRlciB0aGUgdGVybXMgb2YgYSBTZWNvbmRhcnkgTGljZW5zZQorICAgICAgKGlmIHBlcm1pdHRlZCB1bmRlciB0aGUgdGVybXMgb2YgU2VjdGlvbiAzKS4KKworICAgIDMuIFJFUVVJUkVNRU5UUworCisgICAgMy4xIElmIGEgQ29udHJpYnV0b3IgRGlzdHJpYnV0ZXMgdGhlIFByb2dyYW0gaW4gYW55IGZvcm0sIHRoZW46CisKKyAgICAgIGEpIHRoZSBQcm9ncmFtIG11c3QgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSBhcyBTb3VyY2UgQ29kZSwgaW4KKyAgICAgIGFjY29yZGFuY2Ugd2l0aCBzZWN0aW9uIDMuMiwgYW5kIHRoZSBDb250cmlidXRvciBtdXN0IGFjY29tcGFueQorICAgICAgdGhlIFByb2dyYW0gd2l0aCBhIHN0YXRlbWVudCB0aGF0IHRoZSBTb3VyY2UgQ29kZSBmb3IgdGhlIFByb2dyYW0KKyAgICAgIGlzIGF2YWlsYWJsZSB1bmRlciB0aGlzIEFncmVlbWVudCwgYW5kIGluZm9ybXMgUmVjaXBpZW50cyBob3cgdG8KKyAgICAgIG9idGFpbiBpdCBpbiBhIHJlYXNvbmFibGUgbWFubmVyIG9uIG9yIHRocm91Z2ggYSBtZWRpdW0gY3VzdG9tYXJpbHkKKyAgICAgIHVzZWQgZm9yIHNvZnR3YXJlIGV4Y2hhbmdlOyBhbmQKKworICAgICAgYikgdGhlIENvbnRyaWJ1dG9yIG1heSBEaXN0cmlidXRlIHRoZSBQcm9ncmFtIHVuZGVyIGEgbGljZW5zZQorICAgICAgZGlmZmVyZW50IHRoYW4gdGhpcyBBZ3JlZW1lbnQsIHByb3ZpZGVkIHRoYXQgc3VjaCBsaWNlbnNlOgorICAgICAgICAgaSkgZWZmZWN0aXZlbHkgZGlzY2xhaW1zIG9uIGJlaGFsZiBvZiBhbGwgb3RoZXIgQ29udHJpYnV0b3JzIGFsbAorICAgICAgICAgd2FycmFudGllcyBhbmQgY29uZGl0aW9ucywgZXhwcmVzcyBhbmQgaW1wbGllZCwgaW5jbHVkaW5nCisgICAgICAgICB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMgb2YgdGl0bGUgYW5kIG5vbi1pbmZyaW5nZW1lbnQsIGFuZAorICAgICAgICAgaW1wbGllZCB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMgb2YgbWVyY2hhbnRhYmlsaXR5IGFuZCBmaXRuZXNzCisgICAgICAgICBmb3IgYSBwYXJ0aWN1bGFyIHB1cnBvc2U7CisKKyAgICAgICAgIGlpKSBlZmZlY3RpdmVseSBleGNsdWRlcyBvbiBiZWhhbGYgb2YgYWxsIG90aGVyIENvbnRyaWJ1dG9ycyBhbGwKKyAgICAgICAgIGxpYWJpbGl0eSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGRpcmVjdCwgaW5kaXJlY3QsIHNwZWNpYWwsCisgICAgICAgICBpbmNpZGVudGFsIGFuZCBjb25zZXF1ZW50aWFsIGRhbWFnZXMsIHN1Y2ggYXMgbG9zdCBwcm9maXRzOworCisgICAgICAgICBpaWkpIGRvZXMgbm90IGF0dGVtcHQgdG8gbGltaXQgb3IgYWx0ZXIgdGhlIHJlY2lwaWVudHMnIHJpZ2h0cworICAgICAgICAgaW4gdGhlIFNvdXJjZSBDb2RlIHVuZGVyIHNlY3Rpb24gMy4yOyBhbmQKKworICAgICAgICAgaXYpIHJlcXVpcmVzIGFueSBzdWJzZXF1ZW50IGRpc3RyaWJ1dGlvbiBvZiB0aGUgUHJvZ3JhbSBieSBhbnkKKyAgICAgICAgIHBhcnR5IHRvIGJlIHVuZGVyIGEgbGljZW5zZSB0aGF0IHNhdGlzZmllcyB0aGUgcmVxdWlyZW1lbnRzCisgICAgICAgICBvZiB0aGlzIHNlY3Rpb24gMy4KKworICAgIDMuMiBXaGVuIHRoZSBQcm9ncmFtIGlzIERpc3RyaWJ1dGVkIGFzIFNvdXJjZSBDb2RlOgorCisgICAgICBhKSBpdCBtdXN0IGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoaXMgQWdyZWVtZW50LCBvciBpZiB0aGUKKyAgICAgIFByb2dyYW0gKGkpIGlzIGNvbWJpbmVkIHdpdGggb3RoZXIgbWF0ZXJpYWwgaW4gYSBzZXBhcmF0ZSBmaWxlIG9yCisgICAgICBmaWxlcyBtYWRlIGF2YWlsYWJsZSB1bmRlciBhIFNlY29uZGFyeSBMaWNlbnNlLCBhbmQgKGlpKSB0aGUgaW5pdGlhbAorICAgICAgQ29udHJpYnV0b3IgYXR0YWNoZWQgdG8gdGhlIFNvdXJjZSBDb2RlIHRoZSBub3RpY2UgZGVzY3JpYmVkIGluCisgICAgICBFeGhpYml0IEEgb2YgdGhpcyBBZ3JlZW1lbnQsIHRoZW4gdGhlIFByb2dyYW0gbWF5IGJlIG1hZGUgYXZhaWxhYmxlCisgICAgICB1bmRlciB0aGUgdGVybXMgb2Ygc3VjaCBTZWNvbmRhcnkgTGljZW5zZXMsIGFuZAorCisgICAgICBiKSBhIGNvcHkgb2YgdGhpcyBBZ3JlZW1lbnQgbXVzdCBiZSBpbmNsdWRlZCB3aXRoIGVhY2ggY29weSBvZgorICAgICAgdGhlIFByb2dyYW0uCisKKyAgICAzLjMgQ29udHJpYnV0b3JzIG1heSBub3QgcmVtb3ZlIG9yIGFsdGVyIGFueSBjb3B5cmlnaHQsIHBhdGVudCwKKyAgICB0cmFkZW1hcmssIGF0dHJpYnV0aW9uIG5vdGljZXMsIGRpc2NsYWltZXJzIG9mIHdhcnJhbnR5LCBvciBsaW1pdGF0aW9ucworICAgIG9mIGxpYWJpbGl0eSAoIm5vdGljZXMiKSBjb250YWluZWQgd2l0aGluIHRoZSBQcm9ncmFtIGZyb20gYW55IGNvcHkgb2YKKyAgICB0aGUgUHJvZ3JhbSB3aGljaCB0aGV5IERpc3RyaWJ1dGUsIHByb3ZpZGVkIHRoYXQgQ29udHJpYnV0b3JzIG1heSBhZGQKKyAgICB0aGVpciBvd24gYXBwcm9wcmlhdGUgbm90aWNlcy4KKworICAgIDQuIENPTU1FUkNJQUwgRElTVFJJQlVUSU9OCisKKyAgICBDb21tZXJjaWFsIGRpc3RyaWJ1dG9ycyBvZiBzb2Z0d2FyZSBtYXkgYWNjZXB0IGNlcnRhaW4gcmVzcG9uc2liaWxpdGllcworICAgIHdpdGggcmVzcGVjdCB0byBlbmQgdXNlcnMsIGJ1c2luZXNzIHBhcnRuZXJzIGFuZCB0aGUgbGlrZS4gV2hpbGUgdGhpcworICAgIGxpY2Vuc2UgaXMgaW50ZW5kZWQgdG8gZmFjaWxpdGF0ZSB0aGUgY29tbWVyY2lhbCB1c2Ugb2YgdGhlIFByb2dyYW0sCisgICAgdGhlIENvbnRyaWJ1dG9yIHdobyBpbmNsdWRlcyB0aGUgUHJvZ3JhbSBpbiBhIGNvbW1lcmNpYWwgcHJvZHVjdAorICAgIG9mZmVyaW5nIHNob3VsZCBkbyBzbyBpbiBhIG1hbm5lciB3aGljaCBkb2VzIG5vdCBjcmVhdGUgcG90ZW50aWFsCisgICAgbGlhYmlsaXR5IGZvciBvdGhlciBDb250cmlidXRvcnMuIFRoZXJlZm9yZSwgaWYgYSBDb250cmlidXRvciBpbmNsdWRlcworICAgIHRoZSBQcm9ncmFtIGluIGEgY29tbWVyY2lhbCBwcm9kdWN0IG9mZmVyaW5nLCBzdWNoIENvbnRyaWJ1dG9yCisgICAgKCJDb21tZXJjaWFsIENvbnRyaWJ1dG9yIikgaGVyZWJ5IGFncmVlcyB0byBkZWZlbmQgYW5kIGluZGVtbmlmeSBldmVyeQorICAgIG90aGVyIENvbnRyaWJ1dG9yICgiSW5kZW1uaWZpZWQgQ29udHJpYnV0b3IiKSBhZ2FpbnN0IGFueSBsb3NzZXMsCisgICAgZGFtYWdlcyBhbmQgY29zdHMgKGNvbGxlY3RpdmVseSAiTG9zc2VzIikgYXJpc2luZyBmcm9tIGNsYWltcywgbGF3c3VpdHMKKyAgICBhbmQgb3RoZXIgbGVnYWwgYWN0aW9ucyBicm91Z2h0IGJ5IGEgdGhpcmQgcGFydHkgYWdhaW5zdCB0aGUgSW5kZW1uaWZpZWQKKyAgICBDb250cmlidXRvciB0byB0aGUgZXh0ZW50IGNhdXNlZCBieSB0aGUgYWN0cyBvciBvbWlzc2lvbnMgb2Ygc3VjaAorICAgIENvbW1lcmNpYWwgQ29udHJpYnV0b3IgaW4gY29ubmVjdGlvbiB3aXRoIGl0cyBkaXN0cmlidXRpb24gb2YgdGhlIFByb2dyYW0KKyAgICBpbiBhIGNvbW1lcmNpYWwgcHJvZHVjdCBvZmZlcmluZy4gVGhlIG9ibGlnYXRpb25zIGluIHRoaXMgc2VjdGlvbiBkbyBub3QKKyAgICBhcHBseSB0byBhbnkgY2xhaW1zIG9yIExvc3NlcyByZWxhdGluZyB0byBhbnkgYWN0dWFsIG9yIGFsbGVnZWQKKyAgICBpbnRlbGxlY3R1YWwgcHJvcGVydHkgaW5mcmluZ2VtZW50LiBJbiBvcmRlciB0byBxdWFsaWZ5LCBhbiBJbmRlbW5pZmllZAorICAgIENvbnRyaWJ1dG9yIG11c3Q6IGEpIHByb21wdGx5IG5vdGlmeSB0aGUgQ29tbWVyY2lhbCBDb250cmlidXRvciBpbgorICAgIHdyaXRpbmcgb2Ygc3VjaCBjbGFpbSwgYW5kIGIpIGFsbG93IHRoZSBDb21tZXJjaWFsIENvbnRyaWJ1dG9yIHRvIGNvbnRyb2wsCisgICAgYW5kIGNvb3BlcmF0ZSB3aXRoIHRoZSBDb21tZXJjaWFsIENvbnRyaWJ1dG9yIGluLCB0aGUgZGVmZW5zZSBhbmQgYW55CisgICAgcmVsYXRlZCBzZXR0bGVtZW50IG5lZ290aWF0aW9ucy4gVGhlIEluZGVtbmlmaWVkIENvbnRyaWJ1dG9yIG1heQorICAgIHBhcnRpY2lwYXRlIGluIGFueSBzdWNoIGNsYWltIGF0IGl0cyBvd24gZXhwZW5zZS4KKworICAgIEZvciBleGFtcGxlLCBhIENvbnRyaWJ1dG9yIG1pZ2h0IGluY2x1ZGUgdGhlIFByb2dyYW0gaW4gYSBjb21tZXJjaWFsCisgICAgcHJvZHVjdCBvZmZlcmluZywgUHJvZHVjdCBYLiBUaGF0IENvbnRyaWJ1dG9yIGlzIHRoZW4gYSBDb21tZXJjaWFsCisgICAgQ29udHJpYnV0b3IuIElmIHRoYXQgQ29tbWVyY2lhbCBDb250cmlidXRvciB0aGVuIG1ha2VzIHBlcmZvcm1hbmNlCisgICAgY2xhaW1zLCBvciBvZmZlcnMgd2FycmFudGllcyByZWxhdGVkIHRvIFByb2R1Y3QgWCwgdGhvc2UgcGVyZm9ybWFuY2UKKyAgICBjbGFpbXMgYW5kIHdhcnJhbnRpZXMgYXJlIHN1Y2ggQ29tbWVyY2lhbCBDb250cmlidXRvcidzIHJlc3BvbnNpYmlsaXR5CisgICAgYWxvbmUuIFVuZGVyIHRoaXMgc2VjdGlvbiwgdGhlIENvbW1lcmNpYWwgQ29udHJpYnV0b3Igd291bGQgaGF2ZSB0bworICAgIGRlZmVuZCBjbGFpbXMgYWdhaW5zdCB0aGUgb3RoZXIgQ29udHJpYnV0b3JzIHJlbGF0ZWQgdG8gdGhvc2UgcGVyZm9ybWFuY2UKKyAgICBjbGFpbXMgYW5kIHdhcnJhbnRpZXMsIGFuZCBpZiBhIGNvdXJ0IHJlcXVpcmVzIGFueSBvdGhlciBDb250cmlidXRvciB0bworICAgIHBheSBhbnkgZGFtYWdlcyBhcyBhIHJlc3VsdCwgdGhlIENvbW1lcmNpYWwgQ29udHJpYnV0b3IgbXVzdCBwYXkKKyAgICB0aG9zZSBkYW1hZ2VzLgorCisgICAgNS4gTk8gV0FSUkFOVFkKKworICAgIEVYQ0VQVCBBUyBFWFBSRVNTTFkgU0VUIEZPUlRIIElOIFRISVMgQUdSRUVNRU5ULCBBTkQgVE8gVEhFIEVYVEVOVAorICAgIFBFUk1JVFRFRCBCWSBBUFBMSUNBQkxFIExBVywgVEhFIFBST0dSQU0gSVMgUFJPVklERUQgT04gQU4gIkFTIElTIgorICAgIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgRUlUSEVSIEVYUFJFU1MgT1IKKyAgICBJTVBMSUVEIElOQ0xVRElORywgV0lUSE9VVCBMSU1JVEFUSU9OLCBBTlkgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GCisgICAgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSBPUiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKKyAgICBQVVJQT1NFLiBFYWNoIFJlY2lwaWVudCBpcyBzb2xlbHkgcmVzcG9uc2libGUgZm9yIGRldGVybWluaW5nIHRoZQorICAgIGFwcHJvcHJpYXRlbmVzcyBvZiB1c2luZyBhbmQgZGlzdHJpYnV0aW5nIHRoZSBQcm9ncmFtIGFuZCBhc3N1bWVzIGFsbAorICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBpdHMgZXhlcmNpc2Ugb2YgcmlnaHRzIHVuZGVyIHRoaXMgQWdyZWVtZW50LAorICAgIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIHJpc2tzIGFuZCBjb3N0cyBvZiBwcm9ncmFtIGVycm9ycywKKyAgICBjb21wbGlhbmNlIHdpdGggYXBwbGljYWJsZSBsYXdzLCBkYW1hZ2UgdG8gb3IgbG9zcyBvZiBkYXRhLCBwcm9ncmFtcworICAgIG9yIGVxdWlwbWVudCwgYW5kIHVuYXZhaWxhYmlsaXR5IG9yIGludGVycnVwdGlvbiBvZiBvcGVyYXRpb25zLgorCisgICAgNi4gRElTQ0xBSU1FUiBPRiBMSUFCSUxJVFkKKworICAgIEVYQ0VQVCBBUyBFWFBSRVNTTFkgU0VUIEZPUlRIIElOIFRISVMgQUdSRUVNRU5ULCBBTkQgVE8gVEhFIEVYVEVOVAorICAgIFBFUk1JVFRFRCBCWSBBUFBMSUNBQkxFIExBVywgTkVJVEhFUiBSRUNJUElFTlQgTk9SIEFOWSBDT05UUklCVVRPUlMKKyAgICBTSEFMTCBIQVZFIEFOWSBMSUFCSUxJVFkgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLAorICAgIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcgV0lUSE9VVCBMSU1JVEFUSU9OIExPU1QKKyAgICBQUk9GSVRTKSwgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOCisgICAgQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkKKyAgICBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT1IgRElTVFJJQlVUSU9OIE9GIFRIRSBQUk9HUkFNIE9SIFRIRQorICAgIEVYRVJDSVNFIE9GIEFOWSBSSUdIVFMgR1JBTlRFRCBIRVJFVU5ERVIsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUKKyAgICBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRVMuCisKKyAgICA3LiBHRU5FUkFMCisKKyAgICBJZiBhbnkgcHJvdmlzaW9uIG9mIHRoaXMgQWdyZWVtZW50IGlzIGludmFsaWQgb3IgdW5lbmZvcmNlYWJsZSB1bmRlcgorICAgIGFwcGxpY2FibGUgbGF3LCBpdCBzaGFsbCBub3QgYWZmZWN0IHRoZSB2YWxpZGl0eSBvciBlbmZvcmNlYWJpbGl0eSBvZgorICAgIHRoZSByZW1haW5kZXIgb2YgdGhlIHRlcm1zIG9mIHRoaXMgQWdyZWVtZW50LCBhbmQgd2l0aG91dCBmdXJ0aGVyCisgICAgYWN0aW9uIGJ5IHRoZSBwYXJ0aWVzIGhlcmV0bywgc3VjaCBwcm92aXNpb24gc2hhbGwgYmUgcmVmb3JtZWQgdG8gdGhlCisgICAgbWluaW11bSBleHRlbnQgbmVjZXNzYXJ5IHRvIG1ha2Ugc3VjaCBwcm92aXNpb24gdmFsaWQgYW5kIGVuZm9yY2VhYmxlLgorCisgICAgSWYgUmVjaXBpZW50IGluc3RpdHV0ZXMgcGF0ZW50IGxpdGlnYXRpb24gYWdhaW5zdCBhbnkgZW50aXR5CisgICAgKGluY2x1ZGluZyBhIGNyb3NzLWNsYWltIG9yIGNvdW50ZXJjbGFpbSBpbiBhIGxhd3N1aXQpIGFsbGVnaW5nIHRoYXQgdGhlCisgICAgUHJvZ3JhbSBpdHNlbGYgKGV4Y2x1ZGluZyBjb21iaW5hdGlvbnMgb2YgdGhlIFByb2dyYW0gd2l0aCBvdGhlciBzb2Z0d2FyZQorICAgIG9yIGhhcmR3YXJlKSBpbmZyaW5nZXMgc3VjaCBSZWNpcGllbnQncyBwYXRlbnQocyksIHRoZW4gc3VjaCBSZWNpcGllbnQncworICAgIHJpZ2h0cyBncmFudGVkIHVuZGVyIFNlY3Rpb24gMihiKSBzaGFsbCB0ZXJtaW5hdGUgYXMgb2YgdGhlIGRhdGUgc3VjaAorICAgIGxpdGlnYXRpb24gaXMgZmlsZWQuCisKKyAgICBBbGwgUmVjaXBpZW50J3MgcmlnaHRzIHVuZGVyIHRoaXMgQWdyZWVtZW50IHNoYWxsIHRlcm1pbmF0ZSBpZiBpdAorICAgIGZhaWxzIHRvIGNvbXBseSB3aXRoIGFueSBvZiB0aGUgbWF0ZXJpYWwgdGVybXMgb3IgY29uZGl0aW9ucyBvZiB0aGlzCisgICAgQWdyZWVtZW50IGFuZCBkb2VzIG5vdCBjdXJlIHN1Y2ggZmFpbHVyZSBpbiBhIHJlYXNvbmFibGUgcGVyaW9kIG9mCisgICAgdGltZSBhZnRlciBiZWNvbWluZyBhd2FyZSBvZiBzdWNoIG5vbmNvbXBsaWFuY2UuIElmIGFsbCBSZWNpcGllbnQncworICAgIHJpZ2h0cyB1bmRlciB0aGlzIEFncmVlbWVudCB0ZXJtaW5hdGUsIFJlY2lwaWVudCBhZ3JlZXMgdG8gY2Vhc2UgdXNlCisgICAgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgUHJvZ3JhbSBhcyBzb29uIGFzIHJlYXNvbmFibHkgcHJhY3RpY2FibGUuCisgICAgSG93ZXZlciwgUmVjaXBpZW50J3Mgb2JsaWdhdGlvbnMgdW5kZXIgdGhpcyBBZ3JlZW1lbnQgYW5kIGFueSBsaWNlbnNlcworICAgIGdyYW50ZWQgYnkgUmVjaXBpZW50IHJlbGF0aW5nIHRvIHRoZSBQcm9ncmFtIHNoYWxsIGNvbnRpbnVlIGFuZCBzdXJ2aXZlLgorCisgICAgRXZlcnlvbmUgaXMgcGVybWl0dGVkIHRvIGNvcHkgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoaXMgQWdyZWVtZW50LAorICAgIGJ1dCBpbiBvcmRlciB0byBhdm9pZCBpbmNvbnNpc3RlbmN5IHRoZSBBZ3JlZW1lbnQgaXMgY29weXJpZ2h0ZWQgYW5kCisgICAgbWF5IG9ubHkgYmUgbW9kaWZpZWQgaW4gdGhlIGZvbGxvd2luZyBtYW5uZXIuIFRoZSBBZ3JlZW1lbnQgU3Rld2FyZAorICAgIHJlc2VydmVzIHRoZSByaWdodCB0byBwdWJsaXNoIG5ldyB2ZXJzaW9ucyAoaW5jbHVkaW5nIHJldmlzaW9ucykgb2YKKyAgICB0aGlzIEFncmVlbWVudCBmcm9tIHRpbWUgdG8gdGltZS4gTm8gb25lIG90aGVyIHRoYW4gdGhlIEFncmVlbWVudAorICAgIFN0ZXdhcmQgaGFzIHRoZSByaWdodCB0byBtb2RpZnkgdGhpcyBBZ3JlZW1lbnQuIFRoZSBFY2xpcHNlIEZvdW5kYXRpb24KKyAgICBpcyB0aGUgaW5pdGlhbCBBZ3JlZW1lbnQgU3Rld2FyZC4gVGhlIEVjbGlwc2UgRm91bmRhdGlvbiBtYXkgYXNzaWduIHRoZQorICAgIHJlc3BvbnNpYmlsaXR5IHRvIHNlcnZlIGFzIHRoZSBBZ3JlZW1lbnQgU3Rld2FyZCB0byBhIHN1aXRhYmxlIHNlcGFyYXRlCisgICAgZW50aXR5LiBFYWNoIG5ldyB2ZXJzaW9uIG9mIHRoZSBBZ3JlZW1lbnQgd2lsbCBiZSBnaXZlbiBhIGRpc3Rpbmd1aXNoaW5nCisgICAgdmVyc2lvbiBudW1iZXIuIFRoZSBQcm9ncmFtIChpbmNsdWRpbmcgQ29udHJpYnV0aW9ucykgbWF5IGFsd2F5cyBiZQorICAgIERpc3RyaWJ1dGVkIHN1YmplY3QgdG8gdGhlIHZlcnNpb24gb2YgdGhlIEFncmVlbWVudCB1bmRlciB3aGljaCBpdCB3YXMKKyAgICByZWNlaXZlZC4gSW4gYWRkaXRpb24sIGFmdGVyIGEgbmV3IHZlcnNpb24gb2YgdGhlIEFncmVlbWVudCBpcyBwdWJsaXNoZWQsCisgICAgQ29udHJpYnV0b3IgbWF5IGVsZWN0IHRvIERpc3RyaWJ1dGUgdGhlIFByb2dyYW0gKGluY2x1ZGluZyBpdHMKKyAgICBDb250cmlidXRpb25zKSB1bmRlciB0aGUgbmV3IHZlcnNpb24uCisKKyAgICBFeGNlcHQgYXMgZXhwcmVzc2x5IHN0YXRlZCBpbiBTZWN0aW9ucyAyKGEpIGFuZCAyKGIpIGFib3ZlLCBSZWNpcGllbnQKKyAgICByZWNlaXZlcyBubyByaWdodHMgb3IgbGljZW5zZXMgdG8gdGhlIGludGVsbGVjdHVhbCBwcm9wZXJ0eSBvZiBhbnkKKyAgICBDb250cmlidXRvciB1bmRlciB0aGlzIEFncmVlbWVudCwgd2hldGhlciBleHByZXNzbHksIGJ5IGltcGxpY2F0aW9uLAorICAgIGVzdG9wcGVsIG9yIG90aGVyd2lzZS4gQWxsIHJpZ2h0cyBpbiB0aGUgUHJvZ3JhbSBub3QgZXhwcmVzc2x5IGdyYW50ZWQKKyAgICB1bmRlciB0aGlzIEFncmVlbWVudCBhcmUgcmVzZXJ2ZWQuIE5vdGhpbmcgaW4gdGhpcyBBZ3JlZW1lbnQgaXMgaW50ZW5kZWQKKyAgICB0byBiZSBlbmZvcmNlYWJsZSBieSBhbnkgZW50aXR5IHRoYXQgaXMgbm90IGEgQ29udHJpYnV0b3Igb3IgUmVjaXBpZW50LgorICAgIE5vIHRoaXJkLXBhcnR5IGJlbmVmaWNpYXJ5IHJpZ2h0cyBhcmUgY3JlYXRlZCB1bmRlciB0aGlzIEFncmVlbWVudC4KKworICAgIEV4aGliaXQgQSAtIEZvcm0gb2YgU2Vjb25kYXJ5IExpY2Vuc2VzIE5vdGljZQorCisgICAgIlRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyAKKyAgICBTZWNvbmRhcnkgTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIAorICAgIGluIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlLCB2LiAyLjAgYXJlIHNhdGlzZmllZDoge25hbWUgbGljZW5zZShzKSwKKyAgICB2ZXJzaW9uKHMpLCBhbmQgZXhjZXB0aW9ucyBvciBhZGRpdGlvbmFsIHBlcm1pc3Npb25zIGhlcmV9LiIKKworICAgICAgU2ltcGx5IGluY2x1ZGluZyBhIGNvcHkgb2YgdGhpcyBBZ3JlZW1lbnQsIGluY2x1ZGluZyB0aGlzIEV4aGliaXQgQQorICAgICAgaXMgbm90IHN1ZmZpY2llbnQgdG8gbGljZW5zZSB0aGUgU291cmNlIENvZGUgdW5kZXIgU2Vjb25kYXJ5IExpY2Vuc2VzLgorCisgICAgICBJZiBpdCBpcyBub3QgcG9zc2libGUgb3IgZGVzaXJhYmxlIHRvIHB1dCB0aGUgbm90aWNlIGluIGEgcGFydGljdWxhcgorICAgICAgZmlsZSwgdGhlbiBZb3UgbWF5IGluY2x1ZGUgdGhlIG5vdGljZSBpbiBhIGxvY2F0aW9uIChzdWNoIGFzIGEgTElDRU5TRQorICAgICAgZmlsZSBpbiBhIHJlbGV2YW50IGRpcmVjdG9yeSkgd2hlcmUgYSByZWNpcGllbnQgd291bGQgYmUgbGlrZWx5IHRvCisgICAgICBsb29rIGZvciBzdWNoIGEgbm90aWNlLgorCisgICAgICBZb3UgbWF5IGFkZCBhZGRpdGlvbmFsIGFjY3VyYXRlIG5vdGljZXMgb2YgY29weXJpZ2h0IG93bmVyc2hpcC4KKworLS0tCisKKyMjICAgIFRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSAoR1BMKSBWZXJzaW9uIDIsIEp1bmUgMTk5MQorCisgICAgQ29weXJpZ2h0IChDKSAxOTg5LCAxOTkxIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgSW5jLgorICAgIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IKKyAgICBCb3N0b24sIE1BIDAyMTEwLTEzMzUKKyAgICBVU0EKKworICAgIEV2ZXJ5b25lIGlzIHBlcm1pdHRlZCB0byBjb3B5IGFuZCBkaXN0cmlidXRlIHZlcmJhdGltIGNvcGllcworICAgIG9mIHRoaXMgbGljZW5zZSBkb2N1bWVudCwgYnV0IGNoYW5naW5nIGl0IGlzIG5vdCBhbGxvd2VkLgorCisgICAgUHJlYW1ibGUKKworICAgIFRoZSBsaWNlbnNlcyBmb3IgbW9zdCBzb2Z0d2FyZSBhcmUgZGVzaWduZWQgdG8gdGFrZSBhd2F5IHlvdXIgZnJlZWRvbSB0bworICAgIHNoYXJlIGFuZCBjaGFuZ2UgaXQuIEJ5IGNvbnRyYXN0LCB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgaXMKKyAgICBpbnRlbmRlZCB0byBndWFyYW50ZWUgeW91ciBmcmVlZG9tIHRvIHNoYXJlIGFuZCBjaGFuZ2UgZnJlZSBzb2Z0d2FyZS0tdG8KKyAgICBtYWtlIHN1cmUgdGhlIHNvZnR3YXJlIGlzIGZyZWUgZm9yIGFsbCBpdHMgdXNlcnMuIFRoaXMgR2VuZXJhbCBQdWJsaWMKKyAgICBMaWNlbnNlIGFwcGxpZXMgdG8gbW9zdCBvZiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uJ3Mgc29mdHdhcmUgYW5kCisgICAgdG8gYW55IG90aGVyIHByb2dyYW0gd2hvc2UgYXV0aG9ycyBjb21taXQgdG8gdXNpbmcgaXQuIChTb21lIG90aGVyIEZyZWUKKyAgICBTb2Z0d2FyZSBGb3VuZGF0aW9uIHNvZnR3YXJlIGlzIGNvdmVyZWQgYnkgdGhlIEdOVSBMaWJyYXJ5IEdlbmVyYWwKKyAgICBQdWJsaWMgTGljZW5zZSBpbnN0ZWFkLikgWW91IGNhbiBhcHBseSBpdCB0byB5b3VyIHByb2dyYW1zLCB0b28uCisKKyAgICBXaGVuIHdlIHNwZWFrIG9mIGZyZWUgc29mdHdhcmUsIHdlIGFyZSByZWZlcnJpbmcgdG8gZnJlZWRvbSwgbm90IHByaWNlLgorICAgIE91ciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlcyBhcmUgZGVzaWduZWQgdG8gbWFrZSBzdXJlIHRoYXQgeW91IGhhdmUgdGhlCisgICAgZnJlZWRvbSB0byBkaXN0cmlidXRlIGNvcGllcyBvZiBmcmVlIHNvZnR3YXJlIChhbmQgY2hhcmdlIGZvciB0aGlzCisgICAgc2VydmljZSBpZiB5b3Ugd2lzaCksIHRoYXQgeW91IHJlY2VpdmUgc291cmNlIGNvZGUgb3IgY2FuIGdldCBpdCBpZiB5b3UKKyAgICB3YW50IGl0LCB0aGF0IHlvdSBjYW4gY2hhbmdlIHRoZSBzb2Z0d2FyZSBvciB1c2UgcGllY2VzIG9mIGl0IGluIG5ldworICAgIGZyZWUgcHJvZ3JhbXM7IGFuZCB0aGF0IHlvdSBrbm93IHlvdSBjYW4gZG8gdGhlc2UgdGhpbmdzLgorCisgICAgVG8gcHJvdGVjdCB5b3VyIHJpZ2h0cywgd2UgbmVlZCB0byBtYWtlIHJlc3RyaWN0aW9ucyB0aGF0IGZvcmJpZCBhbnlvbmUKKyAgICB0byBkZW55IHlvdSB0aGVzZSByaWdodHMgb3IgdG8gYXNrIHlvdSB0byBzdXJyZW5kZXIgdGhlIHJpZ2h0cy4gVGhlc2UKKyAgICByZXN0cmljdGlvbnMgdHJhbnNsYXRlIHRvIGNlcnRhaW4gcmVzcG9uc2liaWxpdGllcyBmb3IgeW91IGlmIHlvdQorICAgIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZSBzb2Z0d2FyZSwgb3IgaWYgeW91IG1vZGlmeSBpdC4KKworICAgIEZvciBleGFtcGxlLCBpZiB5b3UgZGlzdHJpYnV0ZSBjb3BpZXMgb2Ygc3VjaCBhIHByb2dyYW0sIHdoZXRoZXIgZ3JhdGlzCisgICAgb3IgZm9yIGEgZmVlLCB5b3UgbXVzdCBnaXZlIHRoZSByZWNpcGllbnRzIGFsbCB0aGUgcmlnaHRzIHRoYXQgeW91IGhhdmUuCisgICAgWW91IG11c3QgbWFrZSBzdXJlIHRoYXQgdGhleSwgdG9vLCByZWNlaXZlIG9yIGNhbiBnZXQgdGhlIHNvdXJjZSBjb2RlLgorICAgIEFuZCB5b3UgbXVzdCBzaG93IHRoZW0gdGhlc2UgdGVybXMgc28gdGhleSBrbm93IHRoZWlyIHJpZ2h0cy4KKworICAgIFdlIHByb3RlY3QgeW91ciByaWdodHMgd2l0aCB0d28gc3RlcHM6ICgxKSBjb3B5cmlnaHQgdGhlIHNvZnR3YXJlLCBhbmQKKyAgICAoMikgb2ZmZXIgeW91IHRoaXMgbGljZW5zZSB3aGljaCBnaXZlcyB5b3UgbGVnYWwgcGVybWlzc2lvbiB0byBjb3B5LAorICAgIGRpc3RyaWJ1dGUgYW5kL29yIG1vZGlmeSB0aGUgc29mdHdhcmUuCisKKyAgICBBbHNvLCBmb3IgZWFjaCBhdXRob3IncyBwcm90ZWN0aW9uIGFuZCBvdXJzLCB3ZSB3YW50IHRvIG1ha2UgY2VydGFpbgorICAgIHRoYXQgZXZlcnlvbmUgdW5kZXJzdGFuZHMgdGhhdCB0aGVyZSBpcyBubyB3YXJyYW50eSBmb3IgdGhpcyBmcmVlCisgICAgc29mdHdhcmUuIElmIHRoZSBzb2Z0d2FyZSBpcyBtb2RpZmllZCBieSBzb21lb25lIGVsc2UgYW5kIHBhc3NlZCBvbiwgd2UKKyAgICB3YW50IGl0cyByZWNpcGllbnRzIHRvIGtub3cgdGhhdCB3aGF0IHRoZXkgaGF2ZSBpcyBub3QgdGhlIG9yaWdpbmFsLCBzbworICAgIHRoYXQgYW55IHByb2JsZW1zIGludHJvZHVjZWQgYnkgb3RoZXJzIHdpbGwgbm90IHJlZmxlY3Qgb24gdGhlIG9yaWdpbmFsCisgICAgYXV0aG9ycycgcmVwdXRhdGlvbnMuCisKKyAgICBGaW5hbGx5LCBhbnkgZnJlZSBwcm9ncmFtIGlzIHRocmVhdGVuZWQgY29uc3RhbnRseSBieSBzb2Z0d2FyZSBwYXRlbnRzLgorICAgIFdlIHdpc2ggdG8gYXZvaWQgdGhlIGRhbmdlciB0aGF0IHJlZGlzdHJpYnV0b3JzIG9mIGEgZnJlZSBwcm9ncmFtIHdpbGwKKyAgICBpbmRpdmlkdWFsbHkgb2J0YWluIHBhdGVudCBsaWNlbnNlcywgaW4gZWZmZWN0IG1ha2luZyB0aGUgcHJvZ3JhbQorICAgIHByb3ByaWV0YXJ5LiBUbyBwcmV2ZW50IHRoaXMsIHdlIGhhdmUgbWFkZSBpdCBjbGVhciB0aGF0IGFueSBwYXRlbnQgbXVzdAorICAgIGJlIGxpY2Vuc2VkIGZvciBldmVyeW9uZSdzIGZyZWUgdXNlIG9yIG5vdCBsaWNlbnNlZCBhdCBhbGwuCisKKyAgICBUaGUgcHJlY2lzZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgY29weWluZywgZGlzdHJpYnV0aW9uIGFuZAorICAgIG1vZGlmaWNhdGlvbiBmb2xsb3cuCisKKyAgICBURVJNUyBBTkQgQ09ORElUSU9OUyBGT1IgQ09QWUlORywgRElTVFJJQlVUSU9OIEFORCBNT0RJRklDQVRJT04KKworICAgIDAuIFRoaXMgTGljZW5zZSBhcHBsaWVzIHRvIGFueSBwcm9ncmFtIG9yIG90aGVyIHdvcmsgd2hpY2ggY29udGFpbnMgYQorICAgIG5vdGljZSBwbGFjZWQgYnkgdGhlIGNvcHlyaWdodCBob2xkZXIgc2F5aW5nIGl0IG1heSBiZSBkaXN0cmlidXRlZCB1bmRlcgorICAgIHRoZSB0ZXJtcyBvZiB0aGlzIEdlbmVyYWwgUHVibGljIExpY2Vuc2UuIFRoZSAiUHJvZ3JhbSIsIGJlbG93LCByZWZlcnMKKyAgICB0byBhbnkgc3VjaCBwcm9ncmFtIG9yIHdvcmssIGFuZCBhICJ3b3JrIGJhc2VkIG9uIHRoZSBQcm9ncmFtIiBtZWFucworICAgIGVpdGhlciB0aGUgUHJvZ3JhbSBvciBhbnkgZGVyaXZhdGl2ZSB3b3JrIHVuZGVyIGNvcHlyaWdodCBsYXc6IHRoYXQgaXMKKyAgICB0byBzYXksIGEgd29yayBjb250YWluaW5nIHRoZSBQcm9ncmFtIG9yIGEgcG9ydGlvbiBvZiBpdCwgZWl0aGVyCisgICAgdmVyYmF0aW0gb3Igd2l0aCBtb2RpZmljYXRpb25zIGFuZC9vciB0cmFuc2xhdGVkIGludG8gYW5vdGhlciBsYW5ndWFnZS4KKyAgICAoSGVyZWluYWZ0ZXIsIHRyYW5zbGF0aW9uIGlzIGluY2x1ZGVkIHdpdGhvdXQgbGltaXRhdGlvbiBpbiB0aGUgdGVybQorICAgICJtb2RpZmljYXRpb24iLikgRWFjaCBsaWNlbnNlZSBpcyBhZGRyZXNzZWQgYXMgInlvdSIuCisKKyAgICBBY3Rpdml0aWVzIG90aGVyIHRoYW4gY29weWluZywgZGlzdHJpYnV0aW9uIGFuZCBtb2RpZmljYXRpb24gYXJlIG5vdAorICAgIGNvdmVyZWQgYnkgdGhpcyBMaWNlbnNlOyB0aGV5IGFyZSBvdXRzaWRlIGl0cyBzY29wZS4gVGhlIGFjdCBvZiBydW5uaW5nCisgICAgdGhlIFByb2dyYW0gaXMgbm90IHJlc3RyaWN0ZWQsIGFuZCB0aGUgb3V0cHV0IGZyb20gdGhlIFByb2dyYW0gaXMKKyAgICBjb3ZlcmVkIG9ubHkgaWYgaXRzIGNvbnRlbnRzIGNvbnN0aXR1dGUgYSB3b3JrIGJhc2VkIG9uIHRoZSBQcm9ncmFtCisgICAgKGluZGVwZW5kZW50IG9mIGhhdmluZyBiZWVuIG1hZGUgYnkgcnVubmluZyB0aGUgUHJvZ3JhbSkuIFdoZXRoZXIgdGhhdAorICAgIGlzIHRydWUgZGVwZW5kcyBvbiB3aGF0IHRoZSBQcm9ncmFtIGRvZXMuCisKKyAgICAxLiBZb3UgbWF5IGNvcHkgYW5kIGRpc3RyaWJ1dGUgdmVyYmF0aW0gY29waWVzIG9mIHRoZSBQcm9ncmFtJ3Mgc291cmNlCisgICAgY29kZSBhcyB5b3UgcmVjZWl2ZSBpdCwgaW4gYW55IG1lZGl1bSwgcHJvdmlkZWQgdGhhdCB5b3UgY29uc3BpY3VvdXNseQorICAgIGFuZCBhcHByb3ByaWF0ZWx5IHB1Ymxpc2ggb24gZWFjaCBjb3B5IGFuIGFwcHJvcHJpYXRlIGNvcHlyaWdodCBub3RpY2UKKyAgICBhbmQgZGlzY2xhaW1lciBvZiB3YXJyYW50eTsga2VlcCBpbnRhY3QgYWxsIHRoZSBub3RpY2VzIHRoYXQgcmVmZXIgdG8KKyAgICB0aGlzIExpY2Vuc2UgYW5kIHRvIHRoZSBhYnNlbmNlIG9mIGFueSB3YXJyYW50eTsgYW5kIGdpdmUgYW55IG90aGVyCisgICAgcmVjaXBpZW50cyBvZiB0aGUgUHJvZ3JhbSBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlIGFsb25nIHdpdGggdGhlIFByb2dyYW0uCisKKyAgICBZb3UgbWF5IGNoYXJnZSBhIGZlZSBmb3IgdGhlIHBoeXNpY2FsIGFjdCBvZiB0cmFuc2ZlcnJpbmcgYSBjb3B5LCBhbmQKKyAgICB5b3UgbWF5IGF0IHlvdXIgb3B0aW9uIG9mZmVyIHdhcnJhbnR5IHByb3RlY3Rpb24gaW4gZXhjaGFuZ2UgZm9yIGEgZmVlLgorCisgICAgMi4gWW91IG1heSBtb2RpZnkgeW91ciBjb3B5IG9yIGNvcGllcyBvZiB0aGUgUHJvZ3JhbSBvciBhbnkgcG9ydGlvbiBvZgorICAgIGl0LCB0aHVzIGZvcm1pbmcgYSB3b3JrIGJhc2VkIG9uIHRoZSBQcm9ncmFtLCBhbmQgY29weSBhbmQgZGlzdHJpYnV0ZQorICAgIHN1Y2ggbW9kaWZpY2F0aW9ucyBvciB3b3JrIHVuZGVyIHRoZSB0ZXJtcyBvZiBTZWN0aW9uIDEgYWJvdmUsIHByb3ZpZGVkCisgICAgdGhhdCB5b3UgYWxzbyBtZWV0IGFsbCBvZiB0aGVzZSBjb25kaXRpb25zOgorCisgICAgICAgIGEpIFlvdSBtdXN0IGNhdXNlIHRoZSBtb2RpZmllZCBmaWxlcyB0byBjYXJyeSBwcm9taW5lbnQgbm90aWNlcworICAgICAgICBzdGF0aW5nIHRoYXQgeW91IGNoYW5nZWQgdGhlIGZpbGVzIGFuZCB0aGUgZGF0ZSBvZiBhbnkgY2hhbmdlLgorCisgICAgICAgIGIpIFlvdSBtdXN0IGNhdXNlIGFueSB3b3JrIHRoYXQgeW91IGRpc3RyaWJ1dGUgb3IgcHVibGlzaCwgdGhhdCBpbgorICAgICAgICB3aG9sZSBvciBpbiBwYXJ0IGNvbnRhaW5zIG9yIGlzIGRlcml2ZWQgZnJvbSB0aGUgUHJvZ3JhbSBvciBhbnkgcGFydAorICAgICAgICB0aGVyZW9mLCB0byBiZSBsaWNlbnNlZCBhcyBhIHdob2xlIGF0IG5vIGNoYXJnZSB0byBhbGwgdGhpcmQgcGFydGllcworICAgICAgICB1bmRlciB0aGUgdGVybXMgb2YgdGhpcyBMaWNlbnNlLgorCisgICAgICAgIGMpIElmIHRoZSBtb2RpZmllZCBwcm9ncmFtIG5vcm1hbGx5IHJlYWRzIGNvbW1hbmRzIGludGVyYWN0aXZlbHkKKyAgICAgICAgd2hlbiBydW4sIHlvdSBtdXN0IGNhdXNlIGl0LCB3aGVuIHN0YXJ0ZWQgcnVubmluZyBmb3Igc3VjaAorICAgICAgICBpbnRlcmFjdGl2ZSB1c2UgaW4gdGhlIG1vc3Qgb3JkaW5hcnkgd2F5LCB0byBwcmludCBvciBkaXNwbGF5IGFuCisgICAgICAgIGFubm91bmNlbWVudCBpbmNsdWRpbmcgYW4gYXBwcm9wcmlhdGUgY29weXJpZ2h0IG5vdGljZSBhbmQgYSBub3RpY2UKKyAgICAgICAgdGhhdCB0aGVyZSBpcyBubyB3YXJyYW50eSAob3IgZWxzZSwgc2F5aW5nIHRoYXQgeW91IHByb3ZpZGUgYQorICAgICAgICB3YXJyYW50eSkgYW5kIHRoYXQgdXNlcnMgbWF5IHJlZGlzdHJpYnV0ZSB0aGUgcHJvZ3JhbSB1bmRlciB0aGVzZQorICAgICAgICBjb25kaXRpb25zLCBhbmQgdGVsbGluZyB0aGUgdXNlciBob3cgdG8gdmlldyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlLgorICAgICAgICAoRXhjZXB0aW9uOiBpZiB0aGUgUHJvZ3JhbSBpdHNlbGYgaXMgaW50ZXJhY3RpdmUgYnV0IGRvZXMgbm90CisgICAgICAgIG5vcm1hbGx5IHByaW50IHN1Y2ggYW4gYW5ub3VuY2VtZW50LCB5b3VyIHdvcmsgYmFzZWQgb24gdGhlIFByb2dyYW0KKyAgICAgICAgaXMgbm90IHJlcXVpcmVkIHRvIHByaW50IGFuIGFubm91bmNlbWVudC4pCisKKyAgICBUaGVzZSByZXF1aXJlbWVudHMgYXBwbHkgdG8gdGhlIG1vZGlmaWVkIHdvcmsgYXMgYSB3aG9sZS4gSWYKKyAgICBpZGVudGlmaWFibGUgc2VjdGlvbnMgb2YgdGhhdCB3b3JrIGFyZSBub3QgZGVyaXZlZCBmcm9tIHRoZSBQcm9ncmFtLCBhbmQKKyAgICBjYW4gYmUgcmVhc29uYWJseSBjb25zaWRlcmVkIGluZGVwZW5kZW50IGFuZCBzZXBhcmF0ZSB3b3JrcyBpbgorICAgIHRoZW1zZWx2ZXMsIHRoZW4gdGhpcyBMaWNlbnNlLCBhbmQgaXRzIHRlcm1zLCBkbyBub3QgYXBwbHkgdG8gdGhvc2UKKyAgICBzZWN0aW9ucyB3aGVuIHlvdSBkaXN0cmlidXRlIHRoZW0gYXMgc2VwYXJhdGUgd29ya3MuIEJ1dCB3aGVuIHlvdQorICAgIGRpc3RyaWJ1dGUgdGhlIHNhbWUgc2VjdGlvbnMgYXMgcGFydCBvZiBhIHdob2xlIHdoaWNoIGlzIGEgd29yayBiYXNlZCBvbgorICAgIHRoZSBQcm9ncmFtLCB0aGUgZGlzdHJpYnV0aW9uIG9mIHRoZSB3aG9sZSBtdXN0IGJlIG9uIHRoZSB0ZXJtcyBvZiB0aGlzCisgICAgTGljZW5zZSwgd2hvc2UgcGVybWlzc2lvbnMgZm9yIG90aGVyIGxpY2Vuc2VlcyBleHRlbmQgdG8gdGhlIGVudGlyZQorICAgIHdob2xlLCBhbmQgdGh1cyB0byBlYWNoIGFuZCBldmVyeSBwYXJ0IHJlZ2FyZGxlc3Mgb2Ygd2hvIHdyb3RlIGl0LgorCisgICAgVGh1cywgaXQgaXMgbm90IHRoZSBpbnRlbnQgb2YgdGhpcyBzZWN0aW9uIHRvIGNsYWltIHJpZ2h0cyBvciBjb250ZXN0CisgICAgeW91ciByaWdodHMgdG8gd29yayB3cml0dGVuIGVudGlyZWx5IGJ5IHlvdTsgcmF0aGVyLCB0aGUgaW50ZW50IGlzIHRvCisgICAgZXhlcmNpc2UgdGhlIHJpZ2h0IHRvIGNvbnRyb2wgdGhlIGRpc3RyaWJ1dGlvbiBvZiBkZXJpdmF0aXZlIG9yCisgICAgY29sbGVjdGl2ZSB3b3JrcyBiYXNlZCBvbiB0aGUgUHJvZ3JhbS4KKworICAgIEluIGFkZGl0aW9uLCBtZXJlIGFnZ3JlZ2F0aW9uIG9mIGFub3RoZXIgd29yayBub3QgYmFzZWQgb24gdGhlIFByb2dyYW0KKyAgICB3aXRoIHRoZSBQcm9ncmFtIChvciB3aXRoIGEgd29yayBiYXNlZCBvbiB0aGUgUHJvZ3JhbSkgb24gYSB2b2x1bWUgb2YgYQorICAgIHN0b3JhZ2Ugb3IgZGlzdHJpYnV0aW9uIG1lZGl1bSBkb2VzIG5vdCBicmluZyB0aGUgb3RoZXIgd29yayB1bmRlciB0aGUKKyAgICBzY29wZSBvZiB0aGlzIExpY2Vuc2UuCisKKyAgICAzLiBZb3UgbWF5IGNvcHkgYW5kIGRpc3RyaWJ1dGUgdGhlIFByb2dyYW0gKG9yIGEgd29yayBiYXNlZCBvbiBpdCwKKyAgICB1bmRlciBTZWN0aW9uIDIpIGluIG9iamVjdCBjb2RlIG9yIGV4ZWN1dGFibGUgZm9ybSB1bmRlciB0aGUgdGVybXMgb2YKKyAgICBTZWN0aW9ucyAxIGFuZCAyIGFib3ZlIHByb3ZpZGVkIHRoYXQgeW91IGFsc28gZG8gb25lIG9mIHRoZSBmb2xsb3dpbmc6CisKKyAgICAgICAgYSkgQWNjb21wYW55IGl0IHdpdGggdGhlIGNvbXBsZXRlIGNvcnJlc3BvbmRpbmcgbWFjaGluZS1yZWFkYWJsZQorICAgICAgICBzb3VyY2UgY29kZSwgd2hpY2ggbXVzdCBiZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgdGVybXMgb2YgU2VjdGlvbnMgMQorICAgICAgICBhbmQgMiBhYm92ZSBvbiBhIG1lZGl1bSBjdXN0b21hcmlseSB1c2VkIGZvciBzb2Z0d2FyZSBpbnRlcmNoYW5nZTsgb3IsCisKKyAgICAgICAgYikgQWNjb21wYW55IGl0IHdpdGggYSB3cml0dGVuIG9mZmVyLCB2YWxpZCBmb3IgYXQgbGVhc3QgdGhyZWUKKyAgICAgICAgeWVhcnMsIHRvIGdpdmUgYW55IHRoaXJkIHBhcnR5LCBmb3IgYSBjaGFyZ2Ugbm8gbW9yZSB0aGFuIHlvdXIgY29zdAorICAgICAgICBvZiBwaHlzaWNhbGx5IHBlcmZvcm1pbmcgc291cmNlIGRpc3RyaWJ1dGlvbiwgYSBjb21wbGV0ZQorICAgICAgICBtYWNoaW5lLXJlYWRhYmxlIGNvcHkgb2YgdGhlIGNvcnJlc3BvbmRpbmcgc291cmNlIGNvZGUsIHRvIGJlCisgICAgICAgIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSB0ZXJtcyBvZiBTZWN0aW9ucyAxIGFuZCAyIGFib3ZlIG9uIGEgbWVkaXVtCisgICAgICAgIGN1c3RvbWFyaWx5IHVzZWQgZm9yIHNvZnR3YXJlIGludGVyY2hhbmdlOyBvciwKKworICAgICAgICBjKSBBY2NvbXBhbnkgaXQgd2l0aCB0aGUgaW5mb3JtYXRpb24geW91IHJlY2VpdmVkIGFzIHRvIHRoZSBvZmZlciB0bworICAgICAgICBkaXN0cmlidXRlIGNvcnJlc3BvbmRpbmcgc291cmNlIGNvZGUuIChUaGlzIGFsdGVybmF0aXZlIGlzIGFsbG93ZWQKKyAgICAgICAgb25seSBmb3Igbm9uY29tbWVyY2lhbCBkaXN0cmlidXRpb24gYW5kIG9ubHkgaWYgeW91IHJlY2VpdmVkIHRoZQorICAgICAgICBwcm9ncmFtIGluIG9iamVjdCBjb2RlIG9yIGV4ZWN1dGFibGUgZm9ybSB3aXRoIHN1Y2ggYW4gb2ZmZXIsIGluCisgICAgICAgIGFjY29yZCB3aXRoIFN1YnNlY3Rpb24gYiBhYm92ZS4pCisKKyAgICBUaGUgc291cmNlIGNvZGUgZm9yIGEgd29yayBtZWFucyB0aGUgcHJlZmVycmVkIGZvcm0gb2YgdGhlIHdvcmsgZm9yCisgICAgbWFraW5nIG1vZGlmaWNhdGlvbnMgdG8gaXQuIEZvciBhbiBleGVjdXRhYmxlIHdvcmssIGNvbXBsZXRlIHNvdXJjZSBjb2RlCisgICAgbWVhbnMgYWxsIHRoZSBzb3VyY2UgY29kZSBmb3IgYWxsIG1vZHVsZXMgaXQgY29udGFpbnMsIHBsdXMgYW55CisgICAgYXNzb2NpYXRlZCBpbnRlcmZhY2UgZGVmaW5pdGlvbiBmaWxlcywgcGx1cyB0aGUgc2NyaXB0cyB1c2VkIHRvIGNvbnRyb2wKKyAgICBjb21waWxhdGlvbiBhbmQgaW5zdGFsbGF0aW9uIG9mIHRoZSBleGVjdXRhYmxlLiBIb3dldmVyLCBhcyBhIHNwZWNpYWwKKyAgICBleGNlcHRpb24sIHRoZSBzb3VyY2UgY29kZSBkaXN0cmlidXRlZCBuZWVkIG5vdCBpbmNsdWRlIGFueXRoaW5nIHRoYXQgaXMKKyAgICBub3JtYWxseSBkaXN0cmlidXRlZCAoaW4gZWl0aGVyIHNvdXJjZSBvciBiaW5hcnkgZm9ybSkgd2l0aCB0aGUgbWFqb3IKKyAgICBjb21wb25lbnRzIChjb21waWxlciwga2VybmVsLCBhbmQgc28gb24pIG9mIHRoZSBvcGVyYXRpbmcgc3lzdGVtIG9uCisgICAgd2hpY2ggdGhlIGV4ZWN1dGFibGUgcnVucywgdW5sZXNzIHRoYXQgY29tcG9uZW50IGl0c2VsZiBhY2NvbXBhbmllcyB0aGUKKyAgICBleGVjdXRhYmxlLgorCisgICAgSWYgZGlzdHJpYnV0aW9uIG9mIGV4ZWN1dGFibGUgb3Igb2JqZWN0IGNvZGUgaXMgbWFkZSBieSBvZmZlcmluZyBhY2Nlc3MKKyAgICB0byBjb3B5IGZyb20gYSBkZXNpZ25hdGVkIHBsYWNlLCB0aGVuIG9mZmVyaW5nIGVxdWl2YWxlbnQgYWNjZXNzIHRvIGNvcHkKKyAgICB0aGUgc291cmNlIGNvZGUgZnJvbSB0aGUgc2FtZSBwbGFjZSBjb3VudHMgYXMgZGlzdHJpYnV0aW9uIG9mIHRoZSBzb3VyY2UKKyAgICBjb2RlLCBldmVuIHRob3VnaCB0aGlyZCBwYXJ0aWVzIGFyZSBub3QgY29tcGVsbGVkIHRvIGNvcHkgdGhlIHNvdXJjZQorICAgIGFsb25nIHdpdGggdGhlIG9iamVjdCBjb2RlLgorCisgICAgNC4gWW91IG1heSBub3QgY29weSwgbW9kaWZ5LCBzdWJsaWNlbnNlLCBvciBkaXN0cmlidXRlIHRoZSBQcm9ncmFtCisgICAgZXhjZXB0IGFzIGV4cHJlc3NseSBwcm92aWRlZCB1bmRlciB0aGlzIExpY2Vuc2UuIEFueSBhdHRlbXB0IG90aGVyd2lzZQorICAgIHRvIGNvcHksIG1vZGlmeSwgc3VibGljZW5zZSBvciBkaXN0cmlidXRlIHRoZSBQcm9ncmFtIGlzIHZvaWQsIGFuZCB3aWxsCisgICAgYXV0b21hdGljYWxseSB0ZXJtaW5hdGUgeW91ciByaWdodHMgdW5kZXIgdGhpcyBMaWNlbnNlLiBIb3dldmVyLCBwYXJ0aWVzCisgICAgd2hvIGhhdmUgcmVjZWl2ZWQgY29waWVzLCBvciByaWdodHMsIGZyb20geW91IHVuZGVyIHRoaXMgTGljZW5zZSB3aWxsCisgICAgbm90IGhhdmUgdGhlaXIgbGljZW5zZXMgdGVybWluYXRlZCBzbyBsb25nIGFzIHN1Y2ggcGFydGllcyByZW1haW4gaW4KKyAgICBmdWxsIGNvbXBsaWFuY2UuCisKKyAgICA1LiBZb3UgYXJlIG5vdCByZXF1aXJlZCB0byBhY2NlcHQgdGhpcyBMaWNlbnNlLCBzaW5jZSB5b3UgaGF2ZSBub3QKKyAgICBzaWduZWQgaXQuIEhvd2V2ZXIsIG5vdGhpbmcgZWxzZSBncmFudHMgeW91IHBlcm1pc3Npb24gdG8gbW9kaWZ5IG9yCisgICAgZGlzdHJpYnV0ZSB0aGUgUHJvZ3JhbSBvciBpdHMgZGVyaXZhdGl2ZSB3b3Jrcy4gVGhlc2UgYWN0aW9ucyBhcmUKKyAgICBwcm9oaWJpdGVkIGJ5IGxhdyBpZiB5b3UgZG8gbm90IGFjY2VwdCB0aGlzIExpY2Vuc2UuIFRoZXJlZm9yZSwgYnkKKyAgICBtb2RpZnlpbmcgb3IgZGlzdHJpYnV0aW5nIHRoZSBQcm9ncmFtIChvciBhbnkgd29yayBiYXNlZCBvbiB0aGUKKyAgICBQcm9ncmFtKSwgeW91IGluZGljYXRlIHlvdXIgYWNjZXB0YW5jZSBvZiB0aGlzIExpY2Vuc2UgdG8gZG8gc28sIGFuZCBhbGwKKyAgICBpdHMgdGVybXMgYW5kIGNvbmRpdGlvbnMgZm9yIGNvcHlpbmcsIGRpc3RyaWJ1dGluZyBvciBtb2RpZnlpbmcgdGhlCisgICAgUHJvZ3JhbSBvciB3b3JrcyBiYXNlZCBvbiBpdC4KKworICAgIDYuIEVhY2ggdGltZSB5b3UgcmVkaXN0cmlidXRlIHRoZSBQcm9ncmFtIChvciBhbnkgd29yayBiYXNlZCBvbiB0aGUKKyAgICBQcm9ncmFtKSwgdGhlIHJlY2lwaWVudCBhdXRvbWF0aWNhbGx5IHJlY2VpdmVzIGEgbGljZW5zZSBmcm9tIHRoZQorICAgIG9yaWdpbmFsIGxpY2Vuc29yIHRvIGNvcHksIGRpc3RyaWJ1dGUgb3IgbW9kaWZ5IHRoZSBQcm9ncmFtIHN1YmplY3QgdG8KKyAgICB0aGVzZSB0ZXJtcyBhbmQgY29uZGl0aW9ucy4gWW91IG1heSBub3QgaW1wb3NlIGFueSBmdXJ0aGVyIHJlc3RyaWN0aW9ucworICAgIG9uIHRoZSByZWNpcGllbnRzJyBleGVyY2lzZSBvZiB0aGUgcmlnaHRzIGdyYW50ZWQgaGVyZWluLiBZb3UgYXJlIG5vdAorICAgIHJlc3BvbnNpYmxlIGZvciBlbmZvcmNpbmcgY29tcGxpYW5jZSBieSB0aGlyZCBwYXJ0aWVzIHRvIHRoaXMgTGljZW5zZS4KKworICAgIDcuIElmLCBhcyBhIGNvbnNlcXVlbmNlIG9mIGEgY291cnQganVkZ21lbnQgb3IgYWxsZWdhdGlvbiBvZiBwYXRlbnQKKyAgICBpbmZyaW5nZW1lbnQgb3IgZm9yIGFueSBvdGhlciByZWFzb24gKG5vdCBsaW1pdGVkIHRvIHBhdGVudCBpc3N1ZXMpLAorICAgIGNvbmRpdGlvbnMgYXJlIGltcG9zZWQgb24geW91ICh3aGV0aGVyIGJ5IGNvdXJ0IG9yZGVyLCBhZ3JlZW1lbnQgb3IKKyAgICBvdGhlcndpc2UpIHRoYXQgY29udHJhZGljdCB0aGUgY29uZGl0aW9ucyBvZiB0aGlzIExpY2Vuc2UsIHRoZXkgZG8gbm90CisgICAgZXhjdXNlIHlvdSBmcm9tIHRoZSBjb25kaXRpb25zIG9mIHRoaXMgTGljZW5zZS4gSWYgeW91IGNhbm5vdCBkaXN0cmlidXRlCisgICAgc28gYXMgdG8gc2F0aXNmeSBzaW11bHRhbmVvdXNseSB5b3VyIG9ibGlnYXRpb25zIHVuZGVyIHRoaXMgTGljZW5zZSBhbmQKKyAgICBhbnkgb3RoZXIgcGVydGluZW50IG9ibGlnYXRpb25zLCB0aGVuIGFzIGEgY29uc2VxdWVuY2UgeW91IG1heSBub3QKKyAgICBkaXN0cmlidXRlIHRoZSBQcm9ncmFtIGF0IGFsbC4gRm9yIGV4YW1wbGUsIGlmIGEgcGF0ZW50IGxpY2Vuc2Ugd291bGQKKyAgICBub3QgcGVybWl0IHJveWFsdHktZnJlZSByZWRpc3RyaWJ1dGlvbiBvZiB0aGUgUHJvZ3JhbSBieSBhbGwgdGhvc2Ugd2hvCisgICAgcmVjZWl2ZSBjb3BpZXMgZGlyZWN0bHkgb3IgaW5kaXJlY3RseSB0aHJvdWdoIHlvdSwgdGhlbiB0aGUgb25seSB3YXkgeW91CisgICAgY291bGQgc2F0aXNmeSBib3RoIGl0IGFuZCB0aGlzIExpY2Vuc2Ugd291bGQgYmUgdG8gcmVmcmFpbiBlbnRpcmVseSBmcm9tCisgICAgZGlzdHJpYnV0aW9uIG9mIHRoZSBQcm9ncmFtLgorCisgICAgSWYgYW55IHBvcnRpb24gb2YgdGhpcyBzZWN0aW9uIGlzIGhlbGQgaW52YWxpZCBvciB1bmVuZm9yY2VhYmxlIHVuZGVyCisgICAgYW55IHBhcnRpY3VsYXIgY2lyY3Vtc3RhbmNlLCB0aGUgYmFsYW5jZSBvZiB0aGUgc2VjdGlvbiBpcyBpbnRlbmRlZCB0bworICAgIGFwcGx5IGFuZCB0aGUgc2VjdGlvbiBhcyBhIHdob2xlIGlzIGludGVuZGVkIHRvIGFwcGx5IGluIG90aGVyCisgICAgY2lyY3Vtc3RhbmNlcy4KKworICAgIEl0IGlzIG5vdCB0aGUgcHVycG9zZSBvZiB0aGlzIHNlY3Rpb24gdG8gaW5kdWNlIHlvdSB0byBpbmZyaW5nZSBhbnkKKyAgICBwYXRlbnRzIG9yIG90aGVyIHByb3BlcnR5IHJpZ2h0IGNsYWltcyBvciB0byBjb250ZXN0IHZhbGlkaXR5IG9mIGFueQorICAgIHN1Y2ggY2xhaW1zOyB0aGlzIHNlY3Rpb24gaGFzIHRoZSBzb2xlIHB1cnBvc2Ugb2YgcHJvdGVjdGluZyB0aGUKKyAgICBpbnRlZ3JpdHkgb2YgdGhlIGZyZWUgc29mdHdhcmUgZGlzdHJpYnV0aW9uIHN5c3RlbSwgd2hpY2ggaXMgaW1wbGVtZW50ZWQKKyAgICBieSBwdWJsaWMgbGljZW5zZSBwcmFjdGljZXMuIE1hbnkgcGVvcGxlIGhhdmUgbWFkZSBnZW5lcm91cworICAgIGNvbnRyaWJ1dGlvbnMgdG8gdGhlIHdpZGUgcmFuZ2Ugb2Ygc29mdHdhcmUgZGlzdHJpYnV0ZWQgdGhyb3VnaCB0aGF0CisgICAgc3lzdGVtIGluIHJlbGlhbmNlIG9uIGNvbnNpc3RlbnQgYXBwbGljYXRpb24gb2YgdGhhdCBzeXN0ZW07IGl0IGlzIHVwIHRvCisgICAgdGhlIGF1dGhvci9kb25vciB0byBkZWNpZGUgaWYgaGUgb3Igc2hlIGlzIHdpbGxpbmcgdG8gZGlzdHJpYnV0ZQorICAgIHNvZnR3YXJlIHRocm91Z2ggYW55IG90aGVyIHN5c3RlbSBhbmQgYSBsaWNlbnNlZSBjYW5ub3QgaW1wb3NlIHRoYXQgY2hvaWNlLgorCisgICAgVGhpcyBzZWN0aW9uIGlzIGludGVuZGVkIHRvIG1ha2UgdGhvcm91Z2hseSBjbGVhciB3aGF0IGlzIGJlbGlldmVkIHRvIGJlCisgICAgYSBjb25zZXF1ZW5jZSBvZiB0aGUgcmVzdCBvZiB0aGlzIExpY2Vuc2UuCisKKyAgICA4LiBJZiB0aGUgZGlzdHJpYnV0aW9uIGFuZC9vciB1c2Ugb2YgdGhlIFByb2dyYW0gaXMgcmVzdHJpY3RlZCBpbgorICAgIGNlcnRhaW4gY291bnRyaWVzIGVpdGhlciBieSBwYXRlbnRzIG9yIGJ5IGNvcHlyaWdodGVkIGludGVyZmFjZXMsIHRoZQorICAgIG9yaWdpbmFsIGNvcHlyaWdodCBob2xkZXIgd2hvIHBsYWNlcyB0aGUgUHJvZ3JhbSB1bmRlciB0aGlzIExpY2Vuc2UgbWF5CisgICAgYWRkIGFuIGV4cGxpY2l0IGdlb2dyYXBoaWNhbCBkaXN0cmlidXRpb24gbGltaXRhdGlvbiBleGNsdWRpbmcgdGhvc2UKKyAgICBjb3VudHJpZXMsIHNvIHRoYXQgZGlzdHJpYnV0aW9uIGlzIHBlcm1pdHRlZCBvbmx5IGluIG9yIGFtb25nIGNvdW50cmllcworICAgIG5vdCB0aHVzIGV4Y2x1ZGVkLiBJbiBzdWNoIGNhc2UsIHRoaXMgTGljZW5zZSBpbmNvcnBvcmF0ZXMgdGhlCisgICAgbGltaXRhdGlvbiBhcyBpZiB3cml0dGVuIGluIHRoZSBib2R5IG9mIHRoaXMgTGljZW5zZS4KKworICAgIDkuIFRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24gbWF5IHB1Ymxpc2ggcmV2aXNlZCBhbmQvb3IgbmV3CisgICAgdmVyc2lvbnMgb2YgdGhlIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZnJvbSB0aW1lIHRvIHRpbWUuIFN1Y2ggbmV3CisgICAgdmVyc2lvbnMgd2lsbCBiZSBzaW1pbGFyIGluIHNwaXJpdCB0byB0aGUgcHJlc2VudCB2ZXJzaW9uLCBidXQgbWF5CisgICAgZGlmZmVyIGluIGRldGFpbCB0byBhZGRyZXNzIG5ldyBwcm9ibGVtcyBvciBjb25jZXJucy4KKworICAgIEVhY2ggdmVyc2lvbiBpcyBnaXZlbiBhIGRpc3Rpbmd1aXNoaW5nIHZlcnNpb24gbnVtYmVyLiBJZiB0aGUgUHJvZ3JhbQorICAgIHNwZWNpZmllcyBhIHZlcnNpb24gbnVtYmVyIG9mIHRoaXMgTGljZW5zZSB3aGljaCBhcHBsaWVzIHRvIGl0IGFuZCAiYW55CisgICAgbGF0ZXIgdmVyc2lvbiIsIHlvdSBoYXZlIHRoZSBvcHRpb24gb2YgZm9sbG93aW5nIHRoZSB0ZXJtcyBhbmQKKyAgICBjb25kaXRpb25zIGVpdGhlciBvZiB0aGF0IHZlcnNpb24gb3Igb2YgYW55IGxhdGVyIHZlcnNpb24gcHVibGlzaGVkIGJ5CisgICAgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gSWYgdGhlIFByb2dyYW0gZG9lcyBub3Qgc3BlY2lmeSBhIHZlcnNpb24KKyAgICBudW1iZXIgb2YgdGhpcyBMaWNlbnNlLCB5b3UgbWF5IGNob29zZSBhbnkgdmVyc2lvbiBldmVyIHB1Ymxpc2hlZCBieSB0aGUKKyAgICBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCisKKyAgICAxMC4gSWYgeW91IHdpc2ggdG8gaW5jb3Jwb3JhdGUgcGFydHMgb2YgdGhlIFByb2dyYW0gaW50byBvdGhlciBmcmVlCisgICAgcHJvZ3JhbXMgd2hvc2UgZGlzdHJpYnV0aW9uIGNvbmRpdGlvbnMgYXJlIGRpZmZlcmVudCwgd3JpdGUgdG8gdGhlCisgICAgYXV0aG9yIHRvIGFzayBmb3IgcGVybWlzc2lvbi4gRm9yIHNvZnR3YXJlIHdoaWNoIGlzIGNvcHlyaWdodGVkIGJ5IHRoZQorICAgIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgd2UKKyAgICBzb21ldGltZXMgbWFrZSBleGNlcHRpb25zIGZvciB0aGlzLiBPdXIgZGVjaXNpb24gd2lsbCBiZSBndWlkZWQgYnkgdGhlCisgICAgdHdvIGdvYWxzIG9mIHByZXNlcnZpbmcgdGhlIGZyZWUgc3RhdHVzIG9mIGFsbCBkZXJpdmF0aXZlcyBvZiBvdXIgZnJlZQorICAgIHNvZnR3YXJlIGFuZCBvZiBwcm9tb3RpbmcgdGhlIHNoYXJpbmcgYW5kIHJldXNlIG9mIHNvZnR3YXJlIGdlbmVyYWxseS4KKworICAgIE5PIFdBUlJBTlRZCisKKyAgICAxMS4gQkVDQVVTRSBUSEUgUFJPR1JBTSBJUyBMSUNFTlNFRCBGUkVFIE9GIENIQVJHRSwgVEhFUkUgSVMgTk8KKyAgICBXQVJSQU5UWSBGT1IgVEhFIFBST0dSQU0sIFRPIFRIRSBFWFRFTlQgUEVSTUlUVEVEIEJZIEFQUExJQ0FCTEUgTEFXLgorICAgIEVYQ0VQVCBXSEVOIE9USEVSV0lTRSBTVEFURUQgSU4gV1JJVElORyBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EL09SCisgICAgT1RIRVIgUEFSVElFUyBQUk9WSURFIFRIRSBQUk9HUkFNICJBUyBJUyIgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwKKyAgICBFSVRIRVIgRVhQUkVTU0VEIE9SIElNUExJRUQsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRAorICAgIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gVEhFCisgICAgRU5USVJFIFJJU0sgQVMgVE8gVEhFIFFVQUxJVFkgQU5EIFBFUkZPUk1BTkNFIE9GIFRIRSBQUk9HUkFNIElTIFdJVEgKKyAgICBZT1UuIFNIT1VMRCBUSEUgUFJPR1JBTSBQUk9WRSBERUZFQ1RJVkUsIFlPVSBBU1NVTUUgVEhFIENPU1QgT0YgQUxMCisgICAgTkVDRVNTQVJZIFNFUlZJQ0lORywgUkVQQUlSIE9SIENPUlJFQ1RJT04uCisKKyAgICAxMi4gSU4gTk8gRVZFTlQgVU5MRVNTIFJFUVVJUkVEIEJZIEFQUExJQ0FCTEUgTEFXIE9SIEFHUkVFRCBUTyBJTgorICAgIFdSSVRJTkcgV0lMTCBBTlkgQ09QWVJJR0hUIEhPTERFUiwgT1IgQU5ZIE9USEVSIFBBUlRZIFdITyBNQVkgTU9ESUZZCisgICAgQU5EL09SIFJFRElTVFJJQlVURSBUSEUgUFJPR1JBTSBBUyBQRVJNSVRURUQgQUJPVkUsIEJFIExJQUJMRSBUTyBZT1UgRk9SCisgICAgREFNQUdFUywgSU5DTFVESU5HIEFOWSBHRU5FUkFMLCBTUEVDSUFMLCBJTkNJREVOVEFMIE9SIENPTlNFUVVFTlRJQUwKKyAgICBEQU1BR0VTIEFSSVNJTkcgT1VUIE9GIFRIRSBVU0UgT1IgSU5BQklMSVRZIFRPIFVTRSBUSEUgUFJPR1JBTQorICAgIChJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIExPU1MgT0YgREFUQSBPUiBEQVRBIEJFSU5HIFJFTkRFUkVECisgICAgSU5BQ0NVUkFURSBPUiBMT1NTRVMgU1VTVEFJTkVEIEJZIFlPVSBPUiBUSElSRCBQQVJUSUVTIE9SIEEgRkFJTFVSRSBPRgorICAgIFRIRSBQUk9HUkFNIFRPIE9QRVJBVEUgV0lUSCBBTlkgT1RIRVIgUFJPR1JBTVMpLCBFVkVOIElGIFNVQ0ggSE9MREVSIE9SCisgICAgT1RIRVIgUEFSVFkgSEFTIEJFRU4gQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0VTLgorCisgICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCisKKyAgICBIb3cgdG8gQXBwbHkgVGhlc2UgVGVybXMgdG8gWW91ciBOZXcgUHJvZ3JhbXMKKworICAgIElmIHlvdSBkZXZlbG9wIGEgbmV3IHByb2dyYW0sIGFuZCB5b3Ugd2FudCBpdCB0byBiZSBvZiB0aGUgZ3JlYXRlc3QKKyAgICBwb3NzaWJsZSB1c2UgdG8gdGhlIHB1YmxpYywgdGhlIGJlc3Qgd2F5IHRvIGFjaGlldmUgdGhpcyBpcyB0byBtYWtlIGl0CisgICAgZnJlZSBzb2Z0d2FyZSB3aGljaCBldmVyeW9uZSBjYW4gcmVkaXN0cmlidXRlIGFuZCBjaGFuZ2UgdW5kZXIgdGhlc2UgdGVybXMuCisKKyAgICBUbyBkbyBzbywgYXR0YWNoIHRoZSBmb2xsb3dpbmcgbm90aWNlcyB0byB0aGUgcHJvZ3JhbS4gSXQgaXMgc2FmZXN0IHRvCisgICAgYXR0YWNoIHRoZW0gdG8gdGhlIHN0YXJ0IG9mIGVhY2ggc291cmNlIGZpbGUgdG8gbW9zdCBlZmZlY3RpdmVseSBjb252ZXkKKyAgICB0aGUgZXhjbHVzaW9uIG9mIHdhcnJhbnR5OyBhbmQgZWFjaCBmaWxlIHNob3VsZCBoYXZlIGF0IGxlYXN0IHRoZQorICAgICJjb3B5cmlnaHQiIGxpbmUgYW5kIGEgcG9pbnRlciB0byB3aGVyZSB0aGUgZnVsbCBub3RpY2UgaXMgZm91bmQuCisKKyAgICAgICAgT25lIGxpbmUgdG8gZ2l2ZSB0aGUgcHJvZ3JhbSdzIG5hbWUgYW5kIGEgYnJpZWYgaWRlYSBvZiB3aGF0IGl0IGRvZXMuCisgICAgICAgIENvcHlyaWdodCAoQykgPHllYXI+IDxuYW1lIG9mIGF1dGhvcj4KKworICAgICAgICBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQorICAgICAgICBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQorICAgICAgICB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvcgorICAgICAgICAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgorCisgICAgICAgIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQKKyAgICAgICAgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgorICAgICAgICBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuIFNlZSB0aGUgR05VCisgICAgICAgIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KKworICAgICAgICBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQorICAgICAgICBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQorICAgICAgICBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMzUgVVNBCisKKyAgICBBbHNvIGFkZCBpbmZvcm1hdGlvbiBvbiBob3cgdG8gY29udGFjdCB5b3UgYnkgZWxlY3Ryb25pYyBhbmQgcGFwZXIgbWFpbC4KKworICAgIElmIHRoZSBwcm9ncmFtIGlzIGludGVyYWN0aXZlLCBtYWtlIGl0IG91dHB1dCBhIHNob3J0IG5vdGljZSBsaWtlIHRoaXMKKyAgICB3aGVuIGl0IHN0YXJ0cyBpbiBhbiBpbnRlcmFjdGl2ZSBtb2RlOgorCisgICAgICAgIEdub21vdmlzaW9uIHZlcnNpb24gNjksIENvcHlyaWdodCAoQykgeWVhciBuYW1lIG9mIGF1dGhvcgorICAgICAgICBHbm9tb3Zpc2lvbiBjb21lcyB3aXRoIEFCU09MVVRFTFkgTk8gV0FSUkFOVFk7IGZvciBkZXRhaWxzIHR5cGUKKyAgICAgICAgYHNob3cgdycuIFRoaXMgaXMgZnJlZSBzb2Z0d2FyZSwgYW5kIHlvdSBhcmUgd2VsY29tZSB0byByZWRpc3RyaWJ1dGUKKyAgICAgICAgaXQgdW5kZXIgY2VydGFpbiBjb25kaXRpb25zOyB0eXBlIGBzaG93IGMnIGZvciBkZXRhaWxzLgorCisgICAgVGhlIGh5cG90aGV0aWNhbCBjb21tYW5kcyBgc2hvdyB3JyBhbmQgYHNob3cgYycgc2hvdWxkIHNob3cgdGhlCisgICAgYXBwcm9wcmlhdGUgcGFydHMgb2YgdGhlIEdlbmVyYWwgUHVibGljIExpY2Vuc2UuIE9mIGNvdXJzZSwgdGhlIGNvbW1hbmRzCisgICAgeW91IHVzZSBtYXkgYmUgY2FsbGVkIHNvbWV0aGluZyBvdGhlciB0aGFuIGBzaG93IHcnIGFuZCBgc2hvdyBjJzsgdGhleQorICAgIGNvdWxkIGV2ZW4gYmUgbW91c2UtY2xpY2tzIG9yIG1lbnUgaXRlbXMtLXdoYXRldmVyIHN1aXRzIHlvdXIgcHJvZ3JhbS4KKworICAgIFlvdSBzaG91bGQgYWxzbyBnZXQgeW91ciBlbXBsb3llciAoaWYgeW91IHdvcmsgYXMgYSBwcm9ncmFtbWVyKSBvciB5b3VyCisgICAgc2Nob29sLCBpZiBhbnksIHRvIHNpZ24gYSAiY29weXJpZ2h0IGRpc2NsYWltZXIiIGZvciB0aGUgcHJvZ3JhbSwgaWYKKyAgICBuZWNlc3NhcnkuIEhlcmUgaXMgYSBzYW1wbGU7IGFsdGVyIHRoZSBuYW1lczoKKworICAgICAgICBZb3lvZHluZSwgSW5jLiwgaGVyZWJ5IGRpc2NsYWltcyBhbGwgY29weXJpZ2h0IGludGVyZXN0IGluIHRoZQorICAgICAgICBwcm9ncmFtIGBHbm9tb3Zpc2lvbicgKHdoaWNoIG1ha2VzIHBhc3NlcyBhdCBjb21waWxlcnMpIHdyaXR0ZW4gYnkKKyAgICAgICAgSmFtZXMgSGFja2VyLgorCisgICAgICAgIHNpZ25hdHVyZSBvZiBUeSBDb29uLCAxIEFwcmlsIDE5ODkKKyAgICAgICAgVHkgQ29vbiwgUHJlc2lkZW50IG9mIFZpY2UKKworICAgIFRoaXMgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBkb2VzIG5vdCBwZXJtaXQgaW5jb3Jwb3JhdGluZyB5b3VyIHByb2dyYW0KKyAgICBpbnRvIHByb3ByaWV0YXJ5IHByb2dyYW1zLiBJZiB5b3VyIHByb2dyYW0gaXMgYSBzdWJyb3V0aW5lIGxpYnJhcnksIHlvdQorICAgIG1heSBjb25zaWRlciBpdCBtb3JlIHVzZWZ1bCB0byBwZXJtaXQgbGlua2luZyBwcm9wcmlldGFyeSBhcHBsaWNhdGlvbnMKKyAgICB3aXRoIHRoZSBsaWJyYXJ5LiBJZiB0aGlzIGlzIHdoYXQgeW91IHdhbnQgdG8gZG8sIHVzZSB0aGUgR05VIExpYnJhcnkKKyAgICBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGluc3RlYWQgb2YgdGhpcyBMaWNlbnNlLgorCistLS0KKworIyMgQ0xBU1NQQVRIIEVYQ0VQVElPTgorCisgICAgTGlua2luZyB0aGlzIGxpYnJhcnkgc3RhdGljYWxseSBvciBkeW5hbWljYWxseSB3aXRoIG90aGVyIG1vZHVsZXMgaXMKKyAgICBtYWtpbmcgYSBjb21iaW5lZCB3b3JrIGJhc2VkIG9uIHRoaXMgbGlicmFyeS4gIFRodXMsIHRoZSB0ZXJtcyBhbmQKKyAgICBjb25kaXRpb25zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgY292ZXIgdGhlIHdob2xlCisgICAgY29tYmluYXRpb24uCisKKyAgICBBcyBhIHNwZWNpYWwgZXhjZXB0aW9uLCB0aGUgY29weXJpZ2h0IGhvbGRlcnMgb2YgdGhpcyBsaWJyYXJ5IGdpdmUgeW91CisgICAgcGVybWlzc2lvbiB0byBsaW5rIHRoaXMgbGlicmFyeSB3aXRoIGluZGVwZW5kZW50IG1vZHVsZXMgdG8gcHJvZHVjZSBhbgorICAgIGV4ZWN1dGFibGUsIHJlZ2FyZGxlc3Mgb2YgdGhlIGxpY2Vuc2UgdGVybXMgb2YgdGhlc2UgaW5kZXBlbmRlbnQKKyAgICBtb2R1bGVzLCBhbmQgdG8gY29weSBhbmQgZGlzdHJpYnV0ZSB0aGUgcmVzdWx0aW5nIGV4ZWN1dGFibGUgdW5kZXIKKyAgICB0ZXJtcyBvZiB5b3VyIGNob2ljZSwgcHJvdmlkZWQgdGhhdCB5b3UgYWxzbyBtZWV0LCBmb3IgZWFjaCBsaW5rZWQKKyAgICBpbmRlcGVuZGVudCBtb2R1bGUsIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB0aGUgbGljZW5zZSBvZiB0aGF0CisgICAgbW9kdWxlLiAgQW4gaW5kZXBlbmRlbnQgbW9kdWxlIGlzIGEgbW9kdWxlIHdoaWNoIGlzIG5vdCBkZXJpdmVkIGZyb20gb3IKKyAgICBiYXNlZCBvbiB0aGlzIGxpYnJhcnkuICBJZiB5b3UgbW9kaWZ5IHRoaXMgbGlicmFyeSwgeW91IG1heSBleHRlbmQgdGhpcworICAgIGV4Y2VwdGlvbiB0byB5b3VyIHZlcnNpb24gb2YgdGhlIGxpYnJhcnksIGJ1dCB5b3UgYXJlIG5vdCBvYmxpZ2F0ZWQgdG8KKyAgICBkbyBzby4gIElmIHlvdSBkbyBub3Qgd2lzaCB0byBkbyBzbywgZGVsZXRlIHRoaXMgZXhjZXB0aW9uIHN0YXRlbWVudAorICAgIGZyb20geW91ciB2ZXJzaW9uLgpkaWZmIC0tZ2l0IGEvTk9USUNFLm1kIGIvTk9USUNFLm1kCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlhNTE1OWUKLS0tIC9kZXYvbnVsbAorKysgYi9OT1RJQ0UubWQKQEAgLTAsMCArMSw1MCBAQAorIyBOb3RpY2VzIGZvciBFY2xpcHNlIFByb2plY3QgZm9yIEphdmFNYWlsCisKK1RoaXMgY29udGVudCBpcyBwcm9kdWNlZCBhbmQgbWFpbnRhaW5lZCBieSB0aGUgRWNsaXBzZSBQcm9qZWN0IGZvciBKYXZhTWFpbAorcHJvamVjdC4KKworKiBQcm9qZWN0IGhvbWU6IGh0dHBzOi8vcHJvamVjdHMuZWNsaXBzZS5vcmcvcHJvamVjdHMvZWU0ai5qYXZhbWFpbAorCisjIyBUcmFkZW1hcmtzCisKK0VjbGlwc2UgUHJvamVjdCBmb3IgSmF2YU1haWwgaXMgYSB0cmFkZW1hcmsgb2YgdGhlIEVjbGlwc2UgRm91bmRhdGlvbi4KKworIyMgQ29weXJpZ2h0CisKK0FsbCBjb250ZW50IGlzIHRoZSBwcm9wZXJ0eSBvZiB0aGUgcmVzcGVjdGl2ZSBhdXRob3JzIG9yIHRoZWlyIGVtcGxveWVycy4gRm9yCittb3JlIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBhdXRob3JzaGlwIG9mIGNvbnRlbnQsIHBsZWFzZSBjb25zdWx0IHRoZSBsaXN0ZWQKK3NvdXJjZSBjb2RlIHJlcG9zaXRvcnkgbG9ncy4KKworIyMgRGVjbGFyZWQgUHJvamVjdCBMaWNlbnNlcworCitUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMKK29mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCB3aGljaCBpcyBhdmFpbGFibGUgYXQKK2h0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4gVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlCithdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkgTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaAorYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VCitHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLCB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24gd2hpY2ggaXMKK2F2YWlsYWJsZSBhdCBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisKK1NQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorCisjIyBTb3VyY2UgQ29kZQorCitUaGUgcHJvamVjdCBtYWludGFpbnMgdGhlIGZvbGxvd2luZyBzb3VyY2UgY29kZSByZXBvc2l0b3JpZXM6CisKKyogaHR0cHM6Ly9naXRodWIuY29tL2VjbGlwc2UtZWU0ai9qYXZhbWFpbAorCisjIyBUaGlyZC1wYXJ0eSBDb250ZW50CisKK1RoaXMgcHJvamVjdCBsZXZlcmFnZXMgdGhlIGZvbGxvd2luZyB0aGlyZCBwYXJ0eSBjb250ZW50LgorCitOb25lCisKKyMjIENyeXB0b2dyYXBoeQorCitDb250ZW50IG1heSBjb250YWluIGVuY3J5cHRpb24gc29mdHdhcmUuIFRoZSBjb3VudHJ5IGluIHdoaWNoIHlvdSBhcmUgY3VycmVudGx5CittYXkgaGF2ZSByZXN0cmljdGlvbnMgb24gdGhlIGltcG9ydCwgcG9zc2Vzc2lvbiwgYW5kIHVzZSwgYW5kL29yIHJlLWV4cG9ydCB0bworYW5vdGhlciBjb3VudHJ5LCBvZiBlbmNyeXB0aW9uIHNvZnR3YXJlLiBCRUZPUkUgdXNpbmcgYW55IGVuY3J5cHRpb24gc29mdHdhcmUsCitwbGVhc2UgY2hlY2sgdGhlIGNvdW50cnkncyBsYXdzLCByZWd1bGF0aW9ucyBhbmQgcG9saWNpZXMgY29uY2VybmluZyB0aGUgaW1wb3J0LAorcG9zc2Vzc2lvbiwgb3IgdXNlLCBhbmQgcmUtZXhwb3J0IG9mIGVuY3J5cHRpb24gc29mdHdhcmUsIHRvIHNlZSBpZiB0aGlzIGlzCitwZXJtaXR0ZWQuCisKZGlmZiAtLWdpdCBhL1JFQURNRS5tZCBiL1JFQURNRS5tZApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMWM4MzkyCi0tLSAvZGV2L251bGwKKysrIGIvUkVBRE1FLm1kCkBAIC0wLDAgKzEgQEAKK1NlZSB0aGUgW0phdmFNYWlsIHdlYiBzaXRlXShodHRwczovL2phdmFlZS5naXRodWIuaW8vamF2YW1haWwpLgpkaWZmIC0tZ2l0IGEvYW5kcm9pZC9hY3RpdmF0aW9uL2V4Y2x1ZGUueG1sIGIvYW5kcm9pZC9hY3RpdmF0aW9uL2V4Y2x1ZGUueG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNjYTczOTQKLS0tIC9kZXYvbnVsbAorKysgYi9hbmRyb2lkL2FjdGl2YXRpb24vZXhjbHVkZS54bWwKQEAgLTAsMCArMSwzOCBAQAorPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KKzwhLS0KKworICAgIENvcHlyaWdodCAoYykgMjAxMCwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorCisgICAgVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgICAgdGVybXMgb2YgdGhlIEVjbGlwc2UgRGlzdHJpYnV0aW9uIExpY2Vuc2Ugdi4gMS4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisKKyAgICBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQlNELTMtQ2xhdXNlCisKKy0tPgorCis8IS0tIEZpbmRCdWdzIGV4Y2x1ZGUgbGlzdCBmb3IgSkFGIC0tPgorCis8RmluZEJ1Z3NGaWx0ZXI+CisgICAgPCEtLQorCVdlJ3JlIHB1cnBvc2VseSB1c2luZyB0aGUgcGxhdGZvcm0gZGVmYXVsdCBlbmNvZGluZyB3aGVuIHJlYWRpbmcKKwl0aGVzZSBmaWxlcy4KKyAgICAtLT4KKyAgICA8TWF0Y2g+CisJPE9yPgorCSAgICA8Q2xhc3MgbmFtZT0iY29tLnN1bi5hY3RpdmF0aW9uLnJlZ2lzdHJpZXMuTWFpbGNhcEZpbGUiLz4KKwkgICAgPENsYXNzIG5hbWU9ImNvbS5zdW4uYWN0aXZhdGlvbi5yZWdpc3RyaWVzLk1pbWVUeXBlRmlsZSIvPgorCTwvT3I+CisJPEJ1ZyBwYXR0ZXJuPSJETV9ERUZBVUxUX0VOQ09ESU5HIi8+CisgICAgPC9NYXRjaD4KKworICAgIDwhLS0KKwlXZSdyZSBwdXJwb3NlbHkgdXNpbmcgdGhlIHBsYXRmb3JtIGRlZmF1bHQgZW5jb2Rpbmcgd2hlbiB3cml0aW5nCisJYSBTdHJpbmcgdG8gYW4gT3V0cHV0U3RyZWFtLgorICAgIC0tPgorICAgIDxNYXRjaD4KKwk8Q2xhc3MgbmFtZT0iamF2YXguYWN0aXZhdGlvbi5PYmplY3REYXRhQ29udGVudEhhbmRsZXIiLz4KKwk8TWV0aG9kIG5hbWU9IndyaXRlVG8iLz4KKwk8QnVnIHBhdHRlcm49IkRNX0RFRkFVTFRfRU5DT0RJTkciLz4KKyAgICA8L01hdGNoPgorPC9GaW5kQnVnc0ZpbHRlcj4KZGlmZiAtLWdpdCBhL2FuZHJvaWQvYWN0aXZhdGlvbi9wb20ueG1sIGIvYW5kcm9pZC9hY3RpdmF0aW9uL3BvbS54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDkyZTY5OAotLS0gL2Rldi9udWxsCisrKyBiL2FuZHJvaWQvYWN0aXZhdGlvbi9wb20ueG1sCkBAIC0wLDAgKzEsMjAzIEBACis8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJpc28tODg1OS0xIj8+Cis8IS0tCisKKyAgICBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKworICAgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICAgIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9vcmcvZG9jdW1lbnRzL2VkbC12MTAucGhwLgorCisgICAgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorCistLT4KKworPHByb2plY3QgeG1sbnM9Imh0dHA6Ly9tYXZlbi5hcGFjaGUub3JnL1BPTS80LjAuMCIKKwl4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIgorCXhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL21hdmVuLmFwYWNoZS5vcmcvUE9NLzQuMC4wCisJCQkgICAgaHR0cDovL21hdmVuLmFwYWNoZS5vcmcvbWF2ZW4tdjRfMF8wLnhzZCI+CisgICAgPHBhcmVudD4KKwk8Z3JvdXBJZD5jb20uc3VuLm1haWw8L2dyb3VwSWQ+CisJPGFydGlmYWN0SWQ+YW5kcm9pZDwvYXJ0aWZhY3RJZD4KKwk8dmVyc2lvbj4xLjYuMzwvdmVyc2lvbj4KKyAgICA8L3BhcmVudD4KKyAgICA8bW9kZWxWZXJzaW9uPjQuMC4wPC9tb2RlbFZlcnNpb24+CisgICAgPGdyb3VwSWQ+Y29tLnN1bi5tYWlsPC9ncm91cElkPgorICAgIDxhcnRpZmFjdElkPmFuZHJvaWQtYWN0aXZhdGlvbjwvYXJ0aWZhY3RJZD4KKyAgICA8cGFja2FnaW5nPmphcjwvcGFja2FnaW5nPgorICAgIDxuYW1lPkphdmFCZWFucyBBY3RpdmF0aW9uIEZyYW1ld29yayBmb3JrIGZvciBBbmRyb2lkPC9uYW1lPgorCisgICAgPCEtLQorCVRoaXMgaXMgYSBmb3JrIG9mIHRoZSBKYXZhQmVhbnMgQWN0aXZhdGlvbiBGcmFtZXdvcmsgKEpBRikgdGhhdAorCWlzIHN1ZmZpY2llbnQgZm9yIHVzZSBieSBKYXZhTWFpbCB3aGVuIHJ1bm5pbmcgb24gQW5kcm9pZC4KKwlBbmRyb2lkIGlzIG5vdCBKYXZhIENvbXBhdGlibGUsIGFuZCBpcyBtaXNzaW5nIHRoZSBqYXZhLmF3dC5kYXRhdHJhbnNmZXIKKwljbGFzc2VzLiAgVGhpcyBmb3JrIG9mIEpBRiBicmVha3MgdGhlIGRlcGVuZGVuY3kgb24gdGhlCisJamF2YS5hd3QuZGF0YXRyYW5zZmVyIGNsYXNzZXMgYW5kIHRodXMgaXNuJ3QgY29tcGF0aWJsZSB3aXRoCisJdGhlIEpBRiBzcGVjaWZpY2F0aW9uLiAgSXQgc2hvdWxkIG5vdCBiZSB1c2VkIGJ5IGFueXRoaW5nIG90aGVyCisJdGhhbiB0aGlzIEFuZHJvaWQtc3BlY2lmaWMgdmVyc2lvbiBvZiBKYXZhTWFpbC4KKyAgICAtLT4KKworICAgIDxwcm9wZXJ0aWVzPgorCTxhY3RpdmF0aW9uLnNwZWMudmVyc2lvbj4xLjI8L2FjdGl2YXRpb24uc3BlYy52ZXJzaW9uPgorCTxhY3RpdmF0aW9uLmV4dGVuc2lvbk5hbWU+CisJICAgIGpha2FydGEuYWN0aXZhdGlvbi5hbmRyb2lkCisJPC9hY3RpdmF0aW9uLmV4dGVuc2lvbk5hbWU+CisJPGFjdGl2YXRpb24uc3BlY2lmaWNhdGlvblRpdGxlPgorCSAgICBKYXZhQmVhbnMoVE0pIEFjdGl2YXRpb24gRnJhbWV3b3JrIFNwZWNpZmljYXRpb24KKwk8L2FjdGl2YXRpb24uc3BlY2lmaWNhdGlvblRpdGxlPgorCTxhY3RpdmF0aW9uLmltcGxlbWVudGF0aW9uVGl0bGU+CisJICAgIGphdmF4LmFjdGl2YXRpb24KKwk8L2FjdGl2YXRpb24uaW1wbGVtZW50YXRpb25UaXRsZT4KKwk8YWN0aXZhdGlvbi5idW5kbGUuc3ltYm9saWNOYW1lPgorCSAgICAke3Byb2plY3QuZ3JvdXBJZH0uJHtwcm9qZWN0LmFydGlmYWN0SWR9CisJPC9hY3RpdmF0aW9uLmJ1bmRsZS5zeW1ib2xpY05hbWU+CisJPGFjdGl2YXRpb24ucGFja2FnZXMuZXhwb3J0PgorCSAgICBqYXZheC5hY3RpdmF0aW9uLio7IHZlcnNpb249JHthY3RpdmF0aW9uLnNwZWMudmVyc2lvbn0sCisJICAgIGNvbS5zdW4uYWN0aXZhdGlvbi4qOyB2ZXJzaW9uPSR7YWN0aXZhdGlvbi5vc2dpdmVyc2lvbn0KKwk8L2FjdGl2YXRpb24ucGFja2FnZXMuZXhwb3J0PgorCTxmaW5kYnVncy5za2lwPgorCSAgICBmYWxzZQorCTwvZmluZGJ1Z3Muc2tpcD4KKwk8ZmluZGJ1Z3MuZXhjbHVkZT4KKwkgICAgJHtwcm9qZWN0LmJhc2VkaXJ9L2V4Y2x1ZGUueG1sCisJPC9maW5kYnVncy5leGNsdWRlPgorICAgIDwvcHJvcGVydGllcz4KKworICAgIDxidWlsZD4KKwk8cmVzb3VyY2VzPgorCSAgICA8cmVzb3VyY2U+CisJCTxkaXJlY3Rvcnk+c3JjL21haW4vcmVzb3VyY2VzPC9kaXJlY3Rvcnk+CisJCTxmaWx0ZXJpbmc+dHJ1ZTwvZmlsdGVyaW5nPgorCSAgICA8L3Jlc291cmNlPgorCTwvcmVzb3VyY2VzPgorCTxwbHVnaW5zPgorCSAgICA8IS0tCisJCUNvbmZpZ3VyZSBjb21waWxlciBwbHVnaW4gdG8gcHJpbnQgbGludCB3YXJuaW5ncy4KKwkgICAgLS0+CisJICAgIDxwbHVnaW4+CisJCTxhcnRpZmFjdElkPm1hdmVuLWNvbXBpbGVyLXBsdWdpbjwvYXJ0aWZhY3RJZD4KKwkJPGV4ZWN1dGlvbnM+CisJCSAgICA8ZXhlY3V0aW9uPgorCQkJPGlkPmRlZmF1bHQtY29tcGlsZTwvaWQ+CisJCQk8Y29uZmlndXJhdGlvbj4KKwkJCSAgICA8c291cmNlPjEuNzwvc291cmNlPgorCQkJICAgIDx0YXJnZXQ+MS43PC90YXJnZXQ+CisJCQkgICAgPGZvcms+dHJ1ZTwvZm9yaz4KKwkJCSAgICA8IS0tCisJCQkJaWdub3JlIHRoZSBlcnJvcnMgdGhhdCBJIGRvbid0CisJCQkJd2FudCB0byBmaXggbm93CisJCQkgICAgLS0+CisJCQkgICAgPGNvbXBpbGVyQXJncz4KKwkJCQk8YXJnPi1YbGludDwvYXJnPgorCQkJCTxhcmc+LVhsaW50Oi1vcHRpb25zPC9hcmc+CisJCQkJPGFyZz4tWGxpbnQ6LXBhdGg8L2FyZz4KKwkJCQk8YXJnPi1YbGludDotcmF3dHlwZXM8L2FyZz4KKwkJCQk8YXJnPi1YbGludDotdW5jaGVja2VkPC9hcmc+CisJCQkJPGFyZz4tWGxpbnQ6LWZpbmFsbHk8L2FyZz4KKwkJCQk8YXJnPi1YbGludDotc2VyaWFsPC9hcmc+CisJCQkJPGFyZz4tWGxpbnQ6LWNhc3Q8L2FyZz4KKwkJCQk8YXJnPi1YbGludDotZGVwcmVjYXRpb248L2FyZz4KKwkJCQk8YXJnPi1YbGludDotZGVwLWFubjwvYXJnPgorCQkJCTxhcmc+LVdlcnJvcjwvYXJnPgorCQkJICAgIDwvY29tcGlsZXJBcmdzPgorCQkJICAgIDxzaG93V2FybmluZ3M+dHJ1ZTwvc2hvd1dhcm5pbmdzPgorCQkJPC9jb25maWd1cmF0aW9uPgorCQkgICAgPC9leGVjdXRpb24+CisJCSAgICA8ZXhlY3V0aW9uPgorCQkJPGlkPmRlZmF1bHQtdGVzdENvbXBpbGU8L2lkPgorCQkJPGNvbmZpZ3VyYXRpb24+CisJCQkgICAgPHNvdXJjZT4xLjc8L3NvdXJjZT4KKwkJCSAgICA8dGFyZ2V0PjEuNzwvdGFyZ2V0PgorCQkJPC9jb25maWd1cmF0aW9uPgorCQkgICAgPC9leGVjdXRpb24+CisJCTwvZXhlY3V0aW9ucz4KKwkgICAgPC9wbHVnaW4+CisKKwkgICAgPCEtLQorCQlDb25maWd1cmUgdGVzdCBwbHVnaW4gdG8gZmluZCAqVGVzdFN1aXRlIGNsYXNzZXMuCisJICAgIC0tPgorCSAgICA8cGx1Z2luPgorCQk8Z3JvdXBJZD5vcmcuYXBhY2hlLm1hdmVuLnBsdWdpbnM8L2dyb3VwSWQ+CisJCTxhcnRpZmFjdElkPm1hdmVuLXN1cmVmaXJlLXBsdWdpbjwvYXJ0aWZhY3RJZD4KKwkJPGNvbmZpZ3VyYXRpb24+CisJCSAgICA8aW5jbHVkZXM+CisJCQk8aW5jbHVkZT4qKi8qVGVzdC5qYXZhPC9pbmNsdWRlPgorCQkJPGluY2x1ZGU+KiovKlRlc3RTdWl0ZS5qYXZhPC9pbmNsdWRlPgorCQkgICAgPC9pbmNsdWRlcz4KKwkJPC9jb25maWd1cmF0aW9uPgorCSAgICA8L3BsdWdpbj4KKworCSAgICA8cGx1Z2luPgorCQk8Z3JvdXBJZD5vcmcuYXBhY2hlLmZlbGl4PC9ncm91cElkPgorCQk8YXJ0aWZhY3RJZD5tYXZlbi1idW5kbGUtcGx1Z2luPC9hcnRpZmFjdElkPgorCQk8Y29uZmlndXJhdGlvbj4KKwkJICAgIDxpbnN0cnVjdGlvbnM+CisJCQk8QnVuZGxlLVN5bWJvbGljTmFtZT4KKwkJCSAgICAke2FjdGl2YXRpb24uYnVuZGxlLnN5bWJvbGljTmFtZX0KKwkJCTwvQnVuZGxlLVN5bWJvbGljTmFtZT4KKwkJCTxFeHBvcnQtUGFja2FnZT4KKwkJCSAgICAke2FjdGl2YXRpb24ucGFja2FnZXMuZXhwb3J0fQorCQkJPC9FeHBvcnQtUGFja2FnZT4KKwkJCTxJbXBvcnQtUGFja2FnZT4KKwkJCSAgICAke2FjdGl2YXRpb24ucGFja2FnZXMuaW1wb3J0fQorCQkJPC9JbXBvcnQtUGFja2FnZT4KKwkJCTxQcml2YXRlLVBhY2thZ2U+CisJCQkgICAgJHthY3RpdmF0aW9uLnBhY2thZ2VzLnByaXZhdGV9CisJCQk8L1ByaXZhdGUtUGFja2FnZT4KKwkJCTxEeW5hbWljSW1wb3J0LVBhY2thZ2U+CisJCQkgICAgKgorCQkJPC9EeW5hbWljSW1wb3J0LVBhY2thZ2U+CisJCSAgICA8L2luc3RydWN0aW9ucz4KKwkJPC9jb25maWd1cmF0aW9uPgorCQk8IS0tCisJCSAgICBTaW5jZSB3ZSBkb24ndCBjaGFuZ2UgdGhlIHBhY2thZ2luZyB0eXBlIHRvIGJ1bmRsZSwgd2UKKwkJICAgIG5lZWQgdG8gY29uZmlndXJlIHRoZSBwbHVnaW4gdG8gZXhlY3V0ZSB0aGUgbWFuaWZlc3QgZ29hbAorCQkgICAgZHVyaW5nIHRoZSBwcm9jZXNzLWNsYXNzZXMgcGhhc2Ugb2YgdGhlIGJ1aWxkIGxpZmUgY3ljbGUuCisJCS0tPgorCQk8ZXhlY3V0aW9ucz4KKwkJICAgIDxleGVjdXRpb24+CisJCQk8aWQ+b3NnaS1tYW5pZmVzdDwvaWQ+CisJCQk8cGhhc2U+cHJvY2Vzcy1jbGFzc2VzPC9waGFzZT4KKwkJCTxnb2Fscz4KKwkJCSAgICA8Z29hbD5tYW5pZmVzdDwvZ29hbD4KKwkJCTwvZ29hbHM+CisJCSAgICA8L2V4ZWN1dGlvbj4KKwkJPC9leGVjdXRpb25zPgorCSAgICA8L3BsdWdpbj4KKworCSAgICA8IS0tCisJCVNpbmNlIHdlIGRvbid0IHdhbnQgYSBxdWFsaWZpZXIgbGlrZSBiMDUgb3IgU05BUFNIT1QgdG8KKwkJYXBwZWFyIGluIHRoZSBPU0dpIHBhY2thZ2UgdmVyc2lvbiBhdHRyaWJ1dGUsIHdlIHVzZQorCQl0aGUgZm9sbG93aW5nIHBsdWdpbiB0byBwb3B1bGF0ZSBhIHByb2plY3QgcHJvcGVydHkKKwkJd2l0aCBhbiBPU0dpIHZlcnNpb24gdGhhdCBpcyBlcXVpdmFsZW50IHRvIHRoZSBtYXZlbgorCQl2ZXJzaW9uIHdpdGhvdXQgdGhlIHF1YWxpZmllci4KKwkgICAgLS0+CisJICAgIDxwbHVnaW4+CisJCTxncm91cElkPm9yZy5nbGFzc2Zpc2guaGsyPC9ncm91cElkPgorCQk8YXJ0aWZhY3RJZD5vc2dpdmVyc2lvbi1tYXZlbi1wbHVnaW48L2FydGlmYWN0SWQ+CisJCTx2ZXJzaW9uPiR7aGsyLnBsdWdpbi52ZXJzaW9ufTwvdmVyc2lvbj4KKwkJPGNvbmZpZ3VyYXRpb24+CisJCSAgICA8ZHJvcFZlcnNpb25Db21wb25lbnQ+cXVhbGlmaWVyPC9kcm9wVmVyc2lvbkNvbXBvbmVudD4KKwkJICAgIDx2ZXJzaW9uUHJvcGVydHlOYW1lPmFjdGl2YXRpb24ub3NnaXZlcnNpb248L3ZlcnNpb25Qcm9wZXJ0eU5hbWU+CisJCTwvY29uZmlndXJhdGlvbj4KKwkJPGV4ZWN1dGlvbnM+CisJCSAgICA8ZXhlY3V0aW9uPgorCQkJPGlkPmNvbXB1dGUtb3NnaS12ZXJzaW9uPC9pZD4KKwkJCTxnb2Fscz4KKwkJCSAgICA8Z29hbD5jb21wdXRlLW9zZ2ktdmVyc2lvbjwvZ29hbD4KKwkJCTwvZ29hbHM+CisJCSAgICA8L2V4ZWN1dGlvbj4KKwkJPC9leGVjdXRpb25zPgorCSAgICA8L3BsdWdpbj4KKwk8L3BsdWdpbnM+CisgICAgPC9idWlsZD4KKworICAgIDxkZXBlbmRlbmNpZXM+CisJPGRlcGVuZGVuY3k+CisJICAgIDxncm91cElkPmp1bml0PC9ncm91cElkPgorCSAgICA8YXJ0aWZhY3RJZD5qdW5pdDwvYXJ0aWZhY3RJZD4KKwkgICAgPHZlcnNpb24+NC4xMjwvdmVyc2lvbj4KKwkgICAgPHNjb3BlPnRlc3Q8L3Njb3BlPgorCSAgICA8b3B0aW9uYWw+dHJ1ZTwvb3B0aW9uYWw+CisJPC9kZXBlbmRlbmN5PgorICAgIDwvZGVwZW5kZW5jaWVzPgorPC9wcm9qZWN0PgpkaWZmIC0tZ2l0IGEvYW5kcm9pZC9hY3RpdmF0aW9uL3NyYy9tYWluL2phdmEvY29tL3N1bi9hY3RpdmF0aW9uL3JlZ2lzdHJpZXMvTG9nU3VwcG9ydC5qYXZhIGIvYW5kcm9pZC9hY3RpdmF0aW9uL3NyYy9tYWluL2phdmEvY29tL3N1bi9hY3RpdmF0aW9uL3JlZ2lzdHJpZXMvTG9nU3VwcG9ydC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMyMjhmM2MKLS0tIC9kZXYvbnVsbAorKysgYi9hbmRyb2lkL2FjdGl2YXRpb24vc3JjL21haW4vamF2YS9jb20vc3VuL2FjdGl2YXRpb24vcmVnaXN0cmllcy9Mb2dTdXBwb3J0LmphdmEKQEAgLTAsMCArMSw1NSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgRGlzdHJpYnV0aW9uIExpY2Vuc2Ugdi4gMS4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvb3JnL2RvY3VtZW50cy9lZGwtdjEwLnBocC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQlNELTMtQ2xhdXNlCisgKi8KKworcGFja2FnZSBjb20uc3VuLmFjdGl2YXRpb24ucmVnaXN0cmllczsKKworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZhLnV0aWwubG9nZ2luZy4qOworCisvKioKKyAqIExvZ2dpbmcgcmVsYXRlZCBtZXRob2RzLgorICovCitwdWJsaWMgY2xhc3MgTG9nU3VwcG9ydCB7CisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBkZWJ1ZyA9IGZhbHNlOworICAgIHByaXZhdGUgc3RhdGljIExvZ2dlciBsb2dnZXI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTGV2ZWwgbGV2ZWwgPSBMZXZlbC5GSU5FOworCisgICAgc3RhdGljIHsKKwl0cnkgeworCSAgICBkZWJ1ZyA9IEJvb2xlYW4uZ2V0Qm9vbGVhbigiamF2YXguYWN0aXZhdGlvbi5kZWJ1ZyIpOworCX0gY2F0Y2ggKFRocm93YWJsZSB0KSB7CisJICAgIC8vIGlnbm9yZSBhbnkgZXJyb3JzCisJfQorCWxvZ2dlciA9IExvZ2dlci5nZXRMb2dnZXIoImphdmF4LmFjdGl2YXRpb24iKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAgKi8KKyAgICBwcml2YXRlIExvZ1N1cHBvcnQoKSB7CisJLy8gcHJpdmF0ZSBjb25zdHJ1Y3RvciwgY2FuJ3QgY3JlYXRlIGluc3RhbmNlcworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBsb2coU3RyaW5nIG1zZykgeworCWlmIChkZWJ1ZykKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKG1zZyk7CisJbG9nZ2VyLmxvZyhsZXZlbCwgbXNnKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbG9nKFN0cmluZyBtc2csIFRocm93YWJsZSB0KSB7CisJaWYgKGRlYnVnKQorCSAgICBTeXN0ZW0ub3V0LnByaW50bG4obXNnICsgIjsgRXhjZXB0aW9uOiAiICsgdCk7CisJbG9nZ2VyLmxvZyhsZXZlbCwgbXNnLCB0KTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNMb2dnYWJsZSgpIHsKKwlyZXR1cm4gZGVidWcgfHwgbG9nZ2VyLmlzTG9nZ2FibGUobGV2ZWwpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2FuZHJvaWQvYWN0aXZhdGlvbi9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vYWN0aXZhdGlvbi9yZWdpc3RyaWVzL01haWxjYXBGaWxlLmphdmEgYi9hbmRyb2lkL2FjdGl2YXRpb24vc3JjL21haW4vamF2YS9jb20vc3VuL2FjdGl2YXRpb24vcmVnaXN0cmllcy9NYWlsY2FwRmlsZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFmY2I1ZDYKLS0tIC9kZXYvbnVsbAorKysgYi9hbmRyb2lkL2FjdGl2YXRpb24vc3JjL21haW4vamF2YS9jb20vc3VuL2FjdGl2YXRpb24vcmVnaXN0cmllcy9NYWlsY2FwRmlsZS5qYXZhCkBAIC0wLDAgKzEsNTQ4IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBEaXN0cmlidXRpb24gTGljZW5zZSB2LiAxLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9vcmcvZG9jdW1lbnRzL2VkbC12MTAucGhwLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBCU0QtMy1DbGF1c2UKKyAqLworCitwYWNrYWdlIGNvbS5zdW4uYWN0aXZhdGlvbi5yZWdpc3RyaWVzOworCitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmEudXRpbC4qOworCitwdWJsaWMgY2xhc3MgTWFpbGNhcEZpbGUgeworCisgICAgLyoqCisgICAgICogQSBNYXAgaW5kZXhlZCBieSBNSU1FIHR5cGUgKHN0cmluZykgdGhhdCByZWZlcmVuY2VzCisgICAgICogYSBNYXAgb2YgY29tbWFuZHMgZm9yIGVhY2ggdHlwZS4gIFRoZSBjb21hbmQgTWFwCisgICAgICogaXMgaW5kZXhlZCBieSB0aGUgY29tbWFuZCBuYW1lIGFuZCByZWZlcmVuY2VzIGEgTGlzdCBvZgorICAgICAqIGNsYXNzIG5hbWVzIChzdHJpbmdzKSBmb3IgZWFjaCBjb21tYW5kLgorICAgICAqLworICAgIHByaXZhdGUgTWFwIHR5cGVfaGFzaCA9IG5ldyBIYXNoTWFwKCk7CisKKyAgICAvKioKKyAgICAgKiBBbm90aGVyIE1hcCBsaWtlIGFib3ZlLCBidXQgZm9yIGZhbGxiYWNrIGVudHJpZXMuCisgICAgICovCisgICAgcHJpdmF0ZSBNYXAgZmFsbGJhY2tfaGFzaCA9IG5ldyBIYXNoTWFwKCk7CisKKyAgICAvKioKKyAgICAgKiBBIE1hcCBpbmRleGVkIGJ5IE1JTUUgdHlwZSAoc3RyaW5nKSB0aGF0IHJlZmVyZW5jZXMKKyAgICAgKiBhIExpc3Qgb2YgbmF0aXZlIGNvbW1hbmRzIChzdHJpbmcpIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHR5cGUuCisgICAgICovCisgICAgcHJpdmF0ZSBNYXAgbmF0aXZlX2NvbW1hbmRzID0gbmV3IEhhc2hNYXAoKTsKKworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gYWRkUmV2ZXJzZSA9IGZhbHNlOworCisgICAgc3RhdGljIHsKKwl0cnkgeworCSAgICBhZGRSZXZlcnNlID0gQm9vbGVhbi5nZXRCb29sZWFuKCJqYXZheC5hY3RpdmF0aW9uLmFkZHJldmVyc2UiKTsKKwl9IGNhdGNoIChUaHJvd2FibGUgdCkgeworCSAgICAvLyBpZ25vcmUgYW55IGVycm9ycworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgY29uc3RydWN0b3IgdGhhdCB0YWtlcyBhIGZpbGVuYW1lIGFzIGFuIGFyZ3VtZW50LgorICAgICAqCisgICAgICogQHBhcmFtIG5ld19mbmFtZSBUaGUgZmlsZSBuYW1lIG9mIHRoZSBtYWlsY2FwIGZpbGUuCisgICAgICovCisgICAgcHVibGljIE1haWxjYXBGaWxlKFN0cmluZyBuZXdfZm5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJaWYgKExvZ1N1cHBvcnQuaXNMb2dnYWJsZSgpKQorCSAgICBMb2dTdXBwb3J0LmxvZygibmV3IE1haWxjYXBGaWxlOiBmaWxlICIgKyBuZXdfZm5hbWUpOworCUZpbGVSZWFkZXIgcmVhZGVyID0gbnVsbDsKKwl0cnkgeworCSAgICByZWFkZXIgPSBuZXcgRmlsZVJlYWRlcihuZXdfZm5hbWUpOworCSAgICBwYXJzZShuZXcgQnVmZmVyZWRSZWFkZXIocmVhZGVyKSk7CisJfSBmaW5hbGx5IHsKKwkgICAgaWYgKHJlYWRlciAhPSBudWxsKSB7CisJCXRyeSB7CisJCSAgICByZWFkZXIuY2xvc2UoKTsKKwkJfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsgfQorCSAgICB9CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBjb25zdHJ1Y3RvciB0aGF0IHRha2VzIGFuIGlucHV0IHN0cmVhbSBhcyBhbiBhcmd1bWVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpcwl0aGUgaW5wdXQgc3RyZWFtCisgICAgICovCisgICAgcHVibGljIE1haWxjYXBGaWxlKElucHV0U3RyZWFtIGlzKSB0aHJvd3MgSU9FeGNlcHRpb24geworCWlmIChMb2dTdXBwb3J0LmlzTG9nZ2FibGUoKSkKKwkgICAgTG9nU3VwcG9ydC5sb2coIm5ldyBNYWlsY2FwRmlsZTogSW5wdXRTdHJlYW0iKTsKKwlwYXJzZShuZXcgQnVmZmVyZWRSZWFkZXIobmV3IElucHV0U3RyZWFtUmVhZGVyKGlzLCAiaXNvLTg4NTktMSIpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTWFpbGNhcCBmaWxlIGRlZmF1bHQgY29uc3RydWN0b3IuCisgICAgICovCisgICAgcHVibGljIE1haWxjYXBGaWxlKCkgeworCWlmIChMb2dTdXBwb3J0LmlzTG9nZ2FibGUoKSkKKwkgICAgTG9nU3VwcG9ydC5sb2coIm5ldyBNYWlsY2FwRmlsZTogZGVmYXVsdCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgTWFwIG9mIE1haWxjYXBFbnRyaWVzIGJhc2VkIG9uIHRoZSBNSU1FIHR5cGUuCisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiA8c3Ryb25nPlNlbWFudGljczo8L3N0cm9uZz4gRmlyc3QgY2hlY2sgZm9yIHRoZSBsaXRlcmFsIG1pbWUgdHlwZSwKKyAgICAgKiBpZiB0aGF0IGZhaWxzIGxvb2tzIGZvciB3aWxkY2FyZCA8aT50eXBlPC9pPi8qIGFuZCByZXR1cm4gdGhhdC4gUmV0dXJuIHRoZQorICAgICAqIGxpc3Qgb2YgYWxsIHRoYXQgaGl0LgorICAgICAqLworICAgIHB1YmxpYyBNYXAgZ2V0TWFpbGNhcExpc3QoU3RyaW5nIG1pbWVfdHlwZSkgeworCU1hcCBzZWFyY2hfcmVzdWx0ID0gbnVsbDsKKwlNYXAgd2lsZGNhcmRfcmVzdWx0ID0gbnVsbDsKKworCS8vIGZpcnN0IHRyeSB0aGUgbGl0ZXJhbAorCXNlYXJjaF9yZXN1bHQgPSAoTWFwKXR5cGVfaGFzaC5nZXQobWltZV90eXBlKTsKKworCS8vIG9rLCBub3cgdHJ5IHRoZSB3aWxkY2FyZAorCWludCBzZXBhcmF0b3IgPSBtaW1lX3R5cGUuaW5kZXhPZignLycpOworCVN0cmluZyBzdWJ0eXBlID0gbWltZV90eXBlLnN1YnN0cmluZyhzZXBhcmF0b3IgKyAxKTsKKwlpZiAoIXN1YnR5cGUuZXF1YWxzKCIqIikpIHsKKwkgICAgU3RyaW5nIHR5cGUgPSBtaW1lX3R5cGUuc3Vic3RyaW5nKDAsIHNlcGFyYXRvciArIDEpICsgIioiOworCSAgICB3aWxkY2FyZF9yZXN1bHQgPSAoTWFwKXR5cGVfaGFzaC5nZXQodHlwZSk7CisKKwkgICAgaWYgKHdpbGRjYXJkX3Jlc3VsdCAhPSBudWxsKSB7IC8vIGRhbW4sIHdlIGhhdmUgdG8gbWVyZ2UhISEKKwkJaWYgKHNlYXJjaF9yZXN1bHQgIT0gbnVsbCkKKwkJICAgIHNlYXJjaF9yZXN1bHQgPQorCQkJbWVyZ2VSZXN1bHRzKHNlYXJjaF9yZXN1bHQsIHdpbGRjYXJkX3Jlc3VsdCk7CisJCWVsc2UKKwkJICAgIHNlYXJjaF9yZXN1bHQgPSB3aWxkY2FyZF9yZXN1bHQ7CisJICAgIH0KKwl9CisJcmV0dXJuIHNlYXJjaF9yZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBNYXAgb2YgZmFsbGJhY2sgTWFpbGNhcEVudHJpZXMgYmFzZWQgb24gdGhlIE1JTUUgdHlwZS4KKyAgICAgKgorICAgICAqIDxwPgorICAgICAqIDxzdHJvbmc+U2VtYW50aWNzOjwvc3Ryb25nPiBGaXJzdCBjaGVjayBmb3IgdGhlIGxpdGVyYWwgbWltZSB0eXBlLAorICAgICAqIGlmIHRoYXQgZmFpbHMgbG9va3MgZm9yIHdpbGRjYXJkIDxpPnR5cGU8L2k+LyogYW5kIHJldHVybiB0aGF0LiBSZXR1cm4gdGhlCisgICAgICogbGlzdCBvZiBhbGwgdGhhdCBoaXQuCisgICAgICovCisgICAgcHVibGljIE1hcCBnZXRNYWlsY2FwRmFsbGJhY2tMaXN0KFN0cmluZyBtaW1lX3R5cGUpIHsKKwlNYXAgc2VhcmNoX3Jlc3VsdCA9IG51bGw7CisJTWFwIHdpbGRjYXJkX3Jlc3VsdCA9IG51bGw7CisKKwkvLyBmaXJzdCB0cnkgdGhlIGxpdGVyYWwKKwlzZWFyY2hfcmVzdWx0ID0gKE1hcClmYWxsYmFja19oYXNoLmdldChtaW1lX3R5cGUpOworCisJLy8gb2ssIG5vdyB0cnkgdGhlIHdpbGRjYXJkCisJaW50IHNlcGFyYXRvciA9IG1pbWVfdHlwZS5pbmRleE9mKCcvJyk7CisJU3RyaW5nIHN1YnR5cGUgPSBtaW1lX3R5cGUuc3Vic3RyaW5nKHNlcGFyYXRvciArIDEpOworCWlmICghc3VidHlwZS5lcXVhbHMoIioiKSkgeworCSAgICBTdHJpbmcgdHlwZSA9IG1pbWVfdHlwZS5zdWJzdHJpbmcoMCwgc2VwYXJhdG9yICsgMSkgKyAiKiI7CisJICAgIHdpbGRjYXJkX3Jlc3VsdCA9IChNYXApZmFsbGJhY2tfaGFzaC5nZXQodHlwZSk7CisKKwkgICAgaWYgKHdpbGRjYXJkX3Jlc3VsdCAhPSBudWxsKSB7IC8vIGRhbW4sIHdlIGhhdmUgdG8gbWVyZ2UhISEKKwkJaWYgKHNlYXJjaF9yZXN1bHQgIT0gbnVsbCkKKwkJICAgIHNlYXJjaF9yZXN1bHQgPQorCQkJbWVyZ2VSZXN1bHRzKHNlYXJjaF9yZXN1bHQsIHdpbGRjYXJkX3Jlc3VsdCk7CisJCWVsc2UKKwkJICAgIHNlYXJjaF9yZXN1bHQgPSB3aWxkY2FyZF9yZXN1bHQ7CisJICAgIH0KKwl9CisJcmV0dXJuIHNlYXJjaF9yZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIGFsbCB0aGUgTUlNRSB0eXBlcyBrbm93biB0byB0aGlzIG1haWxjYXAgZmlsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nW10gZ2V0TWltZVR5cGVzKCkgeworCVNldCB0eXBlcyA9IG5ldyBIYXNoU2V0KHR5cGVfaGFzaC5rZXlTZXQoKSk7CisJdHlwZXMuYWRkQWxsKGZhbGxiYWNrX2hhc2gua2V5U2V0KCkpOworCXR5cGVzLmFkZEFsbChuYXRpdmVfY29tbWFuZHMua2V5U2V0KCkpOworCVN0cmluZ1tdIG10cyA9IG5ldyBTdHJpbmdbdHlwZXMuc2l6ZSgpXTsKKwltdHMgPSAoU3RyaW5nW10pdHlwZXMudG9BcnJheShtdHMpOworCXJldHVybiBtdHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIGFsbCB0aGUgbmF0aXZlIGNvbWFuZHMgZm9yIHRoZSBnaXZlbiBNSU1FIHR5cGUuCisgICAgICovCisgICAgcHVibGljIFN0cmluZ1tdIGdldE5hdGl2ZUNvbW1hbmRzKFN0cmluZyBtaW1lX3R5cGUpIHsKKwlTdHJpbmdbXSBjbWRzID0gbnVsbDsKKwlMaXN0IHYgPQorCSAgICAoTGlzdCluYXRpdmVfY29tbWFuZHMuZ2V0KG1pbWVfdHlwZS50b0xvd2VyQ2FzZShMb2NhbGUuRU5HTElTSCkpOworCWlmICh2ICE9IG51bGwpIHsKKwkgICAgY21kcyA9IG5ldyBTdHJpbmdbdi5zaXplKCldOworCSAgICBjbWRzID0gKFN0cmluZ1tdKXYudG9BcnJheShjbWRzKTsKKwl9CisJcmV0dXJuIGNtZHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogTWVyZ2UgdGhlIGZpcnN0IGhhc2ggaW50byB0aGUgc2Vjb25kLgorICAgICAqIFRoaXMgbWVyZ2Ugd2lsbCBvbmx5IGVmZmVjdCB0aGUgaGFzaHRhYmxlIHRoYXQgaXMKKyAgICAgKiByZXR1cm5lZCwgd2UgZG9uJ3Qgd2FudCB0byB0b3VjaCB0aGUgb25lIHBhc3NlZCBpbiBzaW5jZQorICAgICAqIGl0cyBpbnRlZ3JpdHkgbXVzdCBiZSBtYWludGFpbmVkLgorICAgICAqLworICAgIHByaXZhdGUgTWFwIG1lcmdlUmVzdWx0cyhNYXAgZmlyc3QsIE1hcCBzZWNvbmQpIHsKKwlJdGVyYXRvciB2ZXJiX2VudW0gPSBzZWNvbmQua2V5U2V0KCkuaXRlcmF0b3IoKTsKKwlNYXAgY2xvbmVkSGFzaCA9IG5ldyBIYXNoTWFwKGZpcnN0KTsKKworCS8vIGl0ZXJhdGUgdGhyb3VnaCB0aGUgdmVyYnMgaW4gdGhlIHNlY29uZCBtYXAKKwl3aGlsZSAodmVyYl9lbnVtLmhhc05leHQoKSkgeworCSAgICBTdHJpbmcgdmVyYiA9IChTdHJpbmcpdmVyYl9lbnVtLm5leHQoKTsKKwkgICAgTGlzdCBjbWRWZWN0b3IgPSAoTGlzdCljbG9uZWRIYXNoLmdldCh2ZXJiKTsKKwkgICAgaWYgKGNtZFZlY3RvciA9PSBudWxsKSB7CisJCWNsb25lZEhhc2gucHV0KHZlcmIsIHNlY29uZC5nZXQodmVyYikpOworCSAgICB9IGVsc2UgeworCQkvLyBtZXJnZSB0aGUgdHdvCisJCUxpc3Qgb2xkViA9IChMaXN0KXNlY29uZC5nZXQodmVyYik7CisJCWNtZFZlY3RvciA9IG5ldyBBcnJheUxpc3QoY21kVmVjdG9yKTsKKwkJY21kVmVjdG9yLmFkZEFsbChvbGRWKTsKKwkJY2xvbmVkSGFzaC5wdXQodmVyYiwgY21kVmVjdG9yKTsKKwkgICAgfQorCX0KKwlyZXR1cm4gY2xvbmVkSGFzaDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBhcHBlbmRUb01haWxjYXA6IEFwcGVuZCB0byB0aGlzIE1haWxjYXAgREIsIHVzZSB0aGUgbWFpbGNhcAorICAgICAqIGZvcm1hdDoKKyAgICAgKiBDb21tZW50ID09ICIjIDxpPmNvbW1lbnQgc3RyaW5nPC9pPgorICAgICAqIEVudHJ5ID09ICJtaW1ldHlwZTsgICAgICAgIGphdmFiZWFuY2xhc3M8YnI+CisgICAgICoKKyAgICAgKiBFeGFtcGxlOgorICAgICAqICMgdGhpcyBpcyBhIGNvbW1lbnQKKyAgICAgKiBpbWFnZS9naWYgICAgICAgamFmLnZpZXdlcnMuSW1hZ2VWaWV3ZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhcHBlbmRUb01haWxjYXAoU3RyaW5nIG1haWxfY2FwKSB7CisJaWYgKExvZ1N1cHBvcnQuaXNMb2dnYWJsZSgpKQorCSAgICBMb2dTdXBwb3J0LmxvZygiYXBwZW5kVG9NYWlsY2FwOiAiICsgbWFpbF9jYXApOworCXRyeSB7CisJICAgIHBhcnNlKG5ldyBTdHJpbmdSZWFkZXIobWFpbF9jYXApKTsKKwl9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworCSAgICAvLyBjYW4ndCBoYXBwZW4KKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogcGFyc2UgZmlsZSBpbnRvIGEgaGFzaCB0YWJsZSBvZiBNQyBUeXBlIEVudHJ5IE9iagorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBwYXJzZShSZWFkZXIgcmVhZGVyKSB0aHJvd3MgSU9FeGNlcHRpb24geworCUJ1ZmZlcmVkUmVhZGVyIGJ1Zl9yZWFkZXIgPSBuZXcgQnVmZmVyZWRSZWFkZXIocmVhZGVyKTsKKwlTdHJpbmcgbGluZSA9IG51bGw7CisJU3RyaW5nIGNvbnRpbnVlZCA9IG51bGw7CisKKwl3aGlsZSAoKGxpbmUgPSBidWZfcmVhZGVyLnJlYWRMaW5lKCkpICE9IG51bGwpIHsKKwkgICAgLy8gICAgTG9nU3VwcG9ydC5sb2coInBhcnNpbmcgbGluZTogIiArIGxpbmUpOworCisJICAgIGxpbmUgPSBsaW5lLnRyaW0oKTsKKworCSAgICB0cnkgeworCQlpZiAobGluZS5jaGFyQXQoMCkgPT0gJyMnKQorCQkgICAgY29udGludWU7CisJCWlmIChsaW5lLmNoYXJBdChsaW5lLmxlbmd0aCgpIC0gMSkgPT0gJ1xcJykgeworCQkgICAgaWYgKGNvbnRpbnVlZCAhPSBudWxsKQorCQkJY29udGludWVkICs9IGxpbmUuc3Vic3RyaW5nKDAsIGxpbmUubGVuZ3RoKCkgLSAxKTsKKwkJICAgIGVsc2UKKwkJCWNvbnRpbnVlZCA9IGxpbmUuc3Vic3RyaW5nKDAsIGxpbmUubGVuZ3RoKCkgLSAxKTsKKwkJfSBlbHNlIGlmIChjb250aW51ZWQgIT0gbnVsbCkgeworCQkgICAgLy8gaGFuZGxlIHRoZSB0d28gc3RyaW5ncworCQkgICAgY29udGludWVkID0gY29udGludWVkICsgbGluZTsKKwkJICAgIC8vCUxvZ1N1cHBvcnQubG9nKCJwYXJzZTogIiArIGNvbnRpbnVlZCk7CisJCSAgICB0cnkgeworCQkJcGFyc2VMaW5lKGNvbnRpbnVlZCk7CisJCSAgICB9IGNhdGNoIChNYWlsY2FwUGFyc2VFeGNlcHRpb24gZSkgeworCQkJLy9lLnByaW50U3RhY2tUcmFjZSgpOworCQkgICAgfQorCQkgICAgY29udGludWVkID0gbnVsbDsKKwkJfQorCQllbHNlIHsKKwkJICAgIC8vCUxvZ1N1cHBvcnQubG9nKCJwYXJzZTogIiArIGxpbmUpOworCQkgICAgdHJ5IHsKKwkJCXBhcnNlTGluZShsaW5lKTsKKwkJCS8vIExvZ1N1cHBvcnQubG9nKCJoYXNoLnNpemUgPSAiICsgdHlwZV9oYXNoLnNpemUoKSk7CisJCSAgICB9IGNhdGNoIChNYWlsY2FwUGFyc2VFeGNlcHRpb24gZSkgeworCQkJLy9lLnByaW50U3RhY2tUcmFjZSgpOworCQkgICAgfQorCQl9CisJICAgIH0gY2F0Y2ggKFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkge30KKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICoJQSByb3V0aW5lIHRvIHBhcnNlIGluZGl2aWR1YWwgZW50cmllcyBpbiBhIE1haWxjYXAgZmlsZS4KKyAgICAgKgorICAgICAqCU5vdGUgdGhhdCB0aGlzIHJvdXRpbmUgZG9lcyBub3QgaGFuZGxlIGxpbmUgY29udGludWF0aW9ucy4KKyAgICAgKglUaGV5IHNob3VsZCBoYXZlIGJlZW4gaGFuZGxlZCBwcmlvciB0byBjYWxsaW5nIHRoaXMgcm91dGluZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBwYXJzZUxpbmUoU3RyaW5nIG1haWxjYXBFbnRyeSkKKwkJCQl0aHJvd3MgTWFpbGNhcFBhcnNlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisJTWFpbGNhcFRva2VuaXplciB0b2tlbml6ZXIgPSBuZXcgTWFpbGNhcFRva2VuaXplcihtYWlsY2FwRW50cnkpOworCXRva2VuaXplci5zZXRJc0F1dG9xdW90aW5nKGZhbHNlKTsKKworCWlmIChMb2dTdXBwb3J0LmlzTG9nZ2FibGUoKSkKKwkgICAgTG9nU3VwcG9ydC5sb2coInBhcnNlOiAiICsgbWFpbGNhcEVudHJ5KTsKKwkvLwlwYXJzZSB0aGUgcHJpbWFyeSB0eXBlCisJaW50IGN1cnJlbnRUb2tlbiA9IHRva2VuaXplci5uZXh0VG9rZW4oKTsKKwlpZiAoY3VycmVudFRva2VuICE9IE1haWxjYXBUb2tlbml6ZXIuU1RSSU5HX1RPS0VOKSB7CisJICAgIHJlcG9ydFBhcnNlRXJyb3IoTWFpbGNhcFRva2VuaXplci5TVFJJTkdfVE9LRU4sIGN1cnJlbnRUb2tlbiwKKwkJCQkJdG9rZW5pemVyLmdldEN1cnJlbnRUb2tlblZhbHVlKCkpOworCX0KKwlTdHJpbmcgcHJpbWFyeVR5cGUgPQorCSAgICB0b2tlbml6ZXIuZ2V0Q3VycmVudFRva2VuVmFsdWUoKS50b0xvd2VyQ2FzZShMb2NhbGUuRU5HTElTSCk7CisJU3RyaW5nIHN1YlR5cGUgPSAiKiI7CisKKwkvLwlwYXJzZSB0aGUgJy8nIGJldHdlZW4gcHJpbWFyeSBhbmQgc3ViCisJLy8JaWYgaXQncyBub3QgcHJlc2VudCB0aGF0J3Mgb2ssIHdlIGp1c3QgZG9uJ3QgaGF2ZSBhIHN1YnR5cGUKKwljdXJyZW50VG9rZW4gPSB0b2tlbml6ZXIubmV4dFRva2VuKCk7CisJaWYgKChjdXJyZW50VG9rZW4gIT0gTWFpbGNhcFRva2VuaXplci5TTEFTSF9UT0tFTikgJiYKKwkJCShjdXJyZW50VG9rZW4gIT0gTWFpbGNhcFRva2VuaXplci5TRU1JQ09MT05fVE9LRU4pKSB7CisJICAgIHJlcG9ydFBhcnNlRXJyb3IoTWFpbGNhcFRva2VuaXplci5TTEFTSF9UT0tFTiwKKwkJCQlNYWlsY2FwVG9rZW5pemVyLlNFTUlDT0xPTl9UT0tFTiwgY3VycmVudFRva2VuLAorCQkJCXRva2VuaXplci5nZXRDdXJyZW50VG9rZW5WYWx1ZSgpKTsKKwl9CisKKwkvLwlvbmx5IG5lZWQgdG8gbG9vayBmb3IgYSBzdWIgdHlwZSBpZiB3ZSBnb3QgYSAnLycKKwlpZiAoY3VycmVudFRva2VuID09IE1haWxjYXBUb2tlbml6ZXIuU0xBU0hfVE9LRU4pIHsKKwkgICAgLy8JcGFyc2UgdGhlIHN1YiB0eXBlCisJICAgIGN1cnJlbnRUb2tlbiA9IHRva2VuaXplci5uZXh0VG9rZW4oKTsKKwkgICAgaWYgKGN1cnJlbnRUb2tlbiAhPSBNYWlsY2FwVG9rZW5pemVyLlNUUklOR19UT0tFTikgeworCQlyZXBvcnRQYXJzZUVycm9yKE1haWxjYXBUb2tlbml6ZXIuU1RSSU5HX1RPS0VOLAorCQkJICAgIGN1cnJlbnRUb2tlbiwgdG9rZW5pemVyLmdldEN1cnJlbnRUb2tlblZhbHVlKCkpOworCSAgICB9CisJICAgIHN1YlR5cGUgPQorCQl0b2tlbml6ZXIuZ2V0Q3VycmVudFRva2VuVmFsdWUoKS50b0xvd2VyQ2FzZShMb2NhbGUuRU5HTElTSCk7CisKKwkgICAgLy8JZ2V0IHRoZSBuZXh0IHRva2VuIHRvIHNpbXBsaWZ5IHRoZSBuZXh0IHN0ZXAKKwkgICAgY3VycmVudFRva2VuID0gdG9rZW5pemVyLm5leHRUb2tlbigpOworCX0KKworCVN0cmluZyBtaW1lVHlwZSA9IHByaW1hcnlUeXBlICsgIi8iICsgc3ViVHlwZTsKKworCWlmIChMb2dTdXBwb3J0LmlzTG9nZ2FibGUoKSkKKwkgICAgTG9nU3VwcG9ydC5sb2coIiAgVHlwZTogIiArIG1pbWVUeXBlKTsKKworCS8vCW5vdyBzZXR1cCB0aGUgY29tbWFuZHMgaGFzaHRhYmxlCisJTWFwIGNvbW1hbmRzID0gbmV3IExpbmtlZEhhc2hNYXAoKTsJLy8ga2VlcCBjb21tYW5kcyBpbiBvcmRlciBmb3VuZAorCisJLy8JcGFyc2UgdGhlICc7JyB0aGF0IHNlcGFyYXRlcyB0aGUgdHlwZSBmcm9tIHRoZSBwYXJhbWV0ZXJzCisJaWYgKGN1cnJlbnRUb2tlbiAhPSBNYWlsY2FwVG9rZW5pemVyLlNFTUlDT0xPTl9UT0tFTikgeworCSAgICByZXBvcnRQYXJzZUVycm9yKE1haWxjYXBUb2tlbml6ZXIuU0VNSUNPTE9OX1RPS0VOLAorCQkJICAgIGN1cnJlbnRUb2tlbiwgdG9rZW5pemVyLmdldEN1cnJlbnRUb2tlblZhbHVlKCkpOworCX0KKwkvLwllYXQgaXQKKworCS8vCXBhcnNlIHRoZSByZXF1aXJlZCB2aWV3IGNvbW1hbmQKKwl0b2tlbml6ZXIuc2V0SXNBdXRvcXVvdGluZyh0cnVlKTsKKwljdXJyZW50VG9rZW4gPSB0b2tlbml6ZXIubmV4dFRva2VuKCk7CisJdG9rZW5pemVyLnNldElzQXV0b3F1b3RpbmcoZmFsc2UpOworCWlmICgoY3VycmVudFRva2VuICE9IE1haWxjYXBUb2tlbml6ZXIuU1RSSU5HX1RPS0VOKSAmJgorCQkgICAgKGN1cnJlbnRUb2tlbiAhPSBNYWlsY2FwVG9rZW5pemVyLlNFTUlDT0xPTl9UT0tFTikpIHsKKwkgICAgcmVwb3J0UGFyc2VFcnJvcihNYWlsY2FwVG9rZW5pemVyLlNUUklOR19UT0tFTiwKKwkJCSAgICBNYWlsY2FwVG9rZW5pemVyLlNFTUlDT0xPTl9UT0tFTiwgY3VycmVudFRva2VuLAorCQkJICAgIHRva2VuaXplci5nZXRDdXJyZW50VG9rZW5WYWx1ZSgpKTsKKwl9CisKKwlpZiAoY3VycmVudFRva2VuID09IE1haWxjYXBUb2tlbml6ZXIuU1RSSU5HX1RPS0VOKSB7CisJICAgIC8vIGhhdmUgYSBuYXRpdmUgY29tYW5kLCBzYXZlIHRoZSBlbnRpcmUgbWFpbGNhcCBlbnRyeQorCSAgICAvL1N0cmluZyBuYXRpdmVDb21tYW5kID0gdG9rZW5pemVyLmdldEN1cnJlbnRUb2tlblZhbHVlKCk7CisJICAgIExpc3QgdiA9IChMaXN0KW5hdGl2ZV9jb21tYW5kcy5nZXQobWltZVR5cGUpOworCSAgICBpZiAodiA9PSBudWxsKSB7CisJCXYgPSBuZXcgQXJyYXlMaXN0KCk7CisJCXYuYWRkKG1haWxjYXBFbnRyeSk7CisJCW5hdGl2ZV9jb21tYW5kcy5wdXQobWltZVR5cGUsIHYpOworCSAgICB9IGVsc2UgeworCQkvLyBYWFggLSBjaGVjayBmb3IgZHVwbGljYXRlcz8KKwkJdi5hZGQobWFpbGNhcEVudHJ5KTsKKwkgICAgfQorCX0KKworCS8vCW9ubHkgaGF2ZSB0byBnZXQgdGhlIG5leHQgdG9rZW4gaWYgdGhlIGN1cnJlbnQgb25lIGlzbid0IGEgJzsnCisJaWYgKGN1cnJlbnRUb2tlbiAhPSBNYWlsY2FwVG9rZW5pemVyLlNFTUlDT0xPTl9UT0tFTikgeworCSAgICBjdXJyZW50VG9rZW4gPSB0b2tlbml6ZXIubmV4dFRva2VuKCk7CisJfQorCisJLy8gbG9vayBmb3IgYSAnOycgd2hpY2ggd2lsbCBpbmRpY2F0ZSB3aGV0aGVyCisJLy8gYSBwYXJhbWV0ZXIgbGlzdCBpcyBwcmVzZW50IG9yIG5vdAorCWlmIChjdXJyZW50VG9rZW4gPT0gTWFpbGNhcFRva2VuaXplci5TRU1JQ09MT05fVE9LRU4pIHsKKwkgICAgYm9vbGVhbiBpc0ZhbGxiYWNrID0gZmFsc2U7CisJICAgIGRvIHsKKwkJLy8JZWF0IHRoZSAnOycKKworCQkvLwlwYXJzZSB0aGUgcGFyYW1ldGVyIG5hbWUKKwkJY3VycmVudFRva2VuID0gdG9rZW5pemVyLm5leHRUb2tlbigpOworCQlpZiAoY3VycmVudFRva2VuICE9IE1haWxjYXBUb2tlbml6ZXIuU1RSSU5HX1RPS0VOKSB7CisJCSAgICByZXBvcnRQYXJzZUVycm9yKE1haWxjYXBUb2tlbml6ZXIuU1RSSU5HX1RPS0VOLAorCQkJICAgIGN1cnJlbnRUb2tlbiwgdG9rZW5pemVyLmdldEN1cnJlbnRUb2tlblZhbHVlKCkpOworCQl9CisJCVN0cmluZyBwYXJhbU5hbWUgPSB0b2tlbml6ZXIuZ2V0Q3VycmVudFRva2VuVmFsdWUoKS4KKwkJCQkJCXRvTG93ZXJDYXNlKExvY2FsZS5FTkdMSVNIKTsKKworCQkvLwlwYXJzZSB0aGUgJz0nIHdoaWNoIHNlcGFyYXRlcyB0aGUgbmFtZSBmcm9tIHRoZSB2YWx1ZQorCQljdXJyZW50VG9rZW4gPSB0b2tlbml6ZXIubmV4dFRva2VuKCk7CisJCWlmICgoY3VycmVudFRva2VuICE9IE1haWxjYXBUb2tlbml6ZXIuRVFVQUxTX1RPS0VOKSAmJgorCQkgICAgKGN1cnJlbnRUb2tlbiAhPSBNYWlsY2FwVG9rZW5pemVyLlNFTUlDT0xPTl9UT0tFTikgJiYKKwkJICAgIChjdXJyZW50VG9rZW4gIT0gTWFpbGNhcFRva2VuaXplci5FT0lfVE9LRU4pKSB7CisJCSAgICByZXBvcnRQYXJzZUVycm9yKE1haWxjYXBUb2tlbml6ZXIuRVFVQUxTX1RPS0VOLAorCQkJICAgIE1haWxjYXBUb2tlbml6ZXIuU0VNSUNPTE9OX1RPS0VOLAorCQkJICAgIE1haWxjYXBUb2tlbml6ZXIuRU9JX1RPS0VOLAorCQkJICAgIGN1cnJlbnRUb2tlbiwgdG9rZW5pemVyLmdldEN1cnJlbnRUb2tlblZhbHVlKCkpOworCQl9CisKKwkJLy8Jd2Ugb25seSBoYXZlIGEgdXNlZnVsIGNvbW1hbmQgaWYgaXQgaXMgbmFtZWQKKwkJaWYgKGN1cnJlbnRUb2tlbiA9PSBNYWlsY2FwVG9rZW5pemVyLkVRVUFMU19UT0tFTikgeworCQkgICAgLy8JZWF0IGl0CisKKwkJICAgIC8vCXBhcnNlIHRoZSBwYXJhbWV0ZXIgdmFsdWUgKHdoaWNoIGlzIGF1dG9xdW90ZWQpCisJCSAgICB0b2tlbml6ZXIuc2V0SXNBdXRvcXVvdGluZyh0cnVlKTsKKwkJICAgIGN1cnJlbnRUb2tlbiA9IHRva2VuaXplci5uZXh0VG9rZW4oKTsKKwkJICAgIHRva2VuaXplci5zZXRJc0F1dG9xdW90aW5nKGZhbHNlKTsKKwkJICAgIGlmIChjdXJyZW50VG9rZW4gIT0gTWFpbGNhcFRva2VuaXplci5TVFJJTkdfVE9LRU4pIHsKKwkJCXJlcG9ydFBhcnNlRXJyb3IoTWFpbGNhcFRva2VuaXplci5TVFJJTkdfVE9LRU4sCisJCQljdXJyZW50VG9rZW4sIHRva2VuaXplci5nZXRDdXJyZW50VG9rZW5WYWx1ZSgpKTsKKwkJICAgIH0KKwkJICAgIFN0cmluZyBwYXJhbVZhbHVlID0KKwkJCQl0b2tlbml6ZXIuZ2V0Q3VycmVudFRva2VuVmFsdWUoKTsKKworCQkgICAgLy8gYWRkIHRoZSBjbGFzcyB0byB0aGUgbGlzdCBpZmYgaXQgaXMgb25lIHdlIGNhcmUgYWJvdXQKKwkJICAgIGlmIChwYXJhbU5hbWUuc3RhcnRzV2l0aCgieC1qYXZhLSIpKSB7CisJCQlTdHJpbmcgY29tbWFuZE5hbWUgPSBwYXJhbU5hbWUuc3Vic3RyaW5nKDcpOworCQkJLy8JNyA9PSAieC1qYXZhLSIubGVuZ3RoCisKKwkJCWlmIChjb21tYW5kTmFtZS5lcXVhbHMoImZhbGxiYWNrLWVudHJ5IikgJiYKKwkJCSAgICBwYXJhbVZhbHVlLmVxdWFsc0lnbm9yZUNhc2UoInRydWUiKSkgeworCQkJICAgIGlzRmFsbGJhY2sgPSB0cnVlOworCQkJfSBlbHNlIHsKKworCQkJICAgIC8vCXNldHVwIHRoZSBjbGFzcyBlbnRyeSBsaXN0CisJCQkgICAgaWYgKExvZ1N1cHBvcnQuaXNMb2dnYWJsZSgpKQorCQkJCUxvZ1N1cHBvcnQubG9nKCIgICAgQ29tbWFuZDogIiArIGNvbW1hbmROYW1lICsKKwkJCQkJCSAgICAiLCBDbGFzczogIiArIHBhcmFtVmFsdWUpOworCQkJICAgIExpc3QgY2xhc3NlcyA9IChMaXN0KWNvbW1hbmRzLmdldChjb21tYW5kTmFtZSk7CisJCQkgICAgaWYgKGNsYXNzZXMgPT0gbnVsbCkgeworCQkJCWNsYXNzZXMgPSBuZXcgQXJyYXlMaXN0KCk7CisJCQkJY29tbWFuZHMucHV0KGNvbW1hbmROYW1lLCBjbGFzc2VzKTsKKwkJCSAgICB9CisJCQkgICAgaWYgKGFkZFJldmVyc2UpCisJCQkJY2xhc3Nlcy5hZGQoMCwgcGFyYW1WYWx1ZSk7CisJCQkgICAgZWxzZQorCQkJCWNsYXNzZXMuYWRkKHBhcmFtVmFsdWUpOworCQkJfQorCQkgICAgfQorCisJCSAgICAvLwlzZXQgdXAgdGhlIG5leHQgaXRlcmF0aW9uCisJCSAgICBjdXJyZW50VG9rZW4gPSB0b2tlbml6ZXIubmV4dFRva2VuKCk7CisJCX0KKwkgICAgfSB3aGlsZSAoY3VycmVudFRva2VuID09IE1haWxjYXBUb2tlbml6ZXIuU0VNSUNPTE9OX1RPS0VOKTsKKworCSAgICBNYXAgbWFzdGVySGFzaCA9IGlzRmFsbGJhY2sgPyBmYWxsYmFja19oYXNoIDogdHlwZV9oYXNoOworCSAgICBNYXAgY3VyY29tbWFuZHMgPQorCQkoTWFwKW1hc3Rlckhhc2guZ2V0KG1pbWVUeXBlKTsKKwkgICAgaWYgKGN1cmNvbW1hbmRzID09IG51bGwpIHsKKwkJbWFzdGVySGFzaC5wdXQobWltZVR5cGUsIGNvbW1hbmRzKTsKKwkgICAgfSBlbHNlIHsKKwkJaWYgKExvZ1N1cHBvcnQuaXNMb2dnYWJsZSgpKQorCQkgICAgTG9nU3VwcG9ydC5sb2coIk1lcmdpbmcgY29tbWFuZHMgZm9yIHR5cGUgIiArIG1pbWVUeXBlKTsKKwkJLy8gaGF2ZSB0byBtZXJnZSBjdXJyZW50IGFuZCBuZXcgY29tbWFuZHMKKwkJLy8gZmlyc3QsIG1lcmdlIGxpc3Qgb2YgY2xhc3NlcyBmb3IgY29tbWFuZHMgYWxyZWFkeSBrbm93bgorCQlJdGVyYXRvciBjbiA9IGN1cmNvbW1hbmRzLmtleVNldCgpLml0ZXJhdG9yKCk7CisJCXdoaWxlIChjbi5oYXNOZXh0KCkpIHsKKwkJICAgIFN0cmluZyBjbWROYW1lID0gKFN0cmluZyljbi5uZXh0KCk7CisJCSAgICBMaXN0IGNjdiA9IChMaXN0KWN1cmNvbW1hbmRzLmdldChjbWROYW1lKTsKKwkJICAgIExpc3QgY3YgPSAoTGlzdCljb21tYW5kcy5nZXQoY21kTmFtZSk7CisJCSAgICBpZiAoY3YgPT0gbnVsbCkKKwkJCWNvbnRpbnVlOworCQkgICAgLy8gYWRkIGV2ZXJ5dGhpbmcgaW4gY3YgdG8gY2N2LCBpZiBpdCdzIG5vdCBhbHJlYWR5IHRoZXJlCisJCSAgICBJdGVyYXRvciBjdm4gPSBjdi5pdGVyYXRvcigpOworCQkgICAgd2hpbGUgKGN2bi5oYXNOZXh0KCkpIHsKKwkJCVN0cmluZyBjbGF6eiA9IChTdHJpbmcpY3ZuLm5leHQoKTsKKwkJCWlmICghY2N2LmNvbnRhaW5zKGNsYXp6KSkKKwkJCSAgICBpZiAoYWRkUmV2ZXJzZSkKKwkJCQljY3YuYWRkKDAsIGNsYXp6KTsKKwkJCSAgICBlbHNlCisJCQkJY2N2LmFkZChjbGF6eik7CisJCSAgICB9CisJCX0KKwkJLy8gbm93LCBhZGQgY29tbWFuZHMgbm90IHByZXZpb3VzbHkga25vd24KKwkJY24gPSBjb21tYW5kcy5rZXlTZXQoKS5pdGVyYXRvcigpOworCQl3aGlsZSAoY24uaGFzTmV4dCgpKSB7CisJCSAgICBTdHJpbmcgY21kTmFtZSA9IChTdHJpbmcpY24ubmV4dCgpOworCQkgICAgaWYgKGN1cmNvbW1hbmRzLmNvbnRhaW5zS2V5KGNtZE5hbWUpKQorCQkJY29udGludWU7CisJCSAgICBMaXN0IGN2ID0gKExpc3QpY29tbWFuZHMuZ2V0KGNtZE5hbWUpOworCQkgICAgY3VyY29tbWFuZHMucHV0KGNtZE5hbWUsIGN2KTsKKwkJfQorCSAgICB9CisJfSBlbHNlIGlmIChjdXJyZW50VG9rZW4gIT0gTWFpbGNhcFRva2VuaXplci5FT0lfVE9LRU4pIHsKKwkgICAgcmVwb3J0UGFyc2VFcnJvcihNYWlsY2FwVG9rZW5pemVyLkVPSV9UT0tFTiwKKwkJTWFpbGNhcFRva2VuaXplci5TRU1JQ09MT05fVE9LRU4sCisJCWN1cnJlbnRUb2tlbiwgdG9rZW5pemVyLmdldEN1cnJlbnRUb2tlblZhbHVlKCkpOworCX0KKyAgICAgfQorCisgICAgIHByb3RlY3RlZCBzdGF0aWMgdm9pZCByZXBvcnRQYXJzZUVycm9yKGludCBleHBlY3RlZFRva2VuLCBpbnQgYWN0dWFsVG9rZW4sCisJCVN0cmluZyBhY3R1YWxUb2tlblZhbHVlKSB0aHJvd3MgTWFpbGNhcFBhcnNlRXhjZXB0aW9uIHsKKyAgICAgCXRocm93IG5ldyBNYWlsY2FwUGFyc2VFeGNlcHRpb24oIkVuY291bnRlcmVkIGEgIiArCisJCU1haWxjYXBUb2tlbml6ZXIubmFtZUZvclRva2VuKGFjdHVhbFRva2VuKSArICIgdG9rZW4gKCIgKworCQlhY3R1YWxUb2tlblZhbHVlICsgIikgd2hpbGUgZXhwZWN0aW5nIGEgIiArCisJCU1haWxjYXBUb2tlbml6ZXIubmFtZUZvclRva2VuKGV4cGVjdGVkVG9rZW4pICsgIiB0b2tlbi4iKTsKKyAgICAgfQorCisgICAgIHByb3RlY3RlZCBzdGF0aWMgdm9pZCByZXBvcnRQYXJzZUVycm9yKGludCBleHBlY3RlZFRva2VuLAorCWludCBvdGhlckV4cGVjdGVkVG9rZW4sIGludCBhY3R1YWxUb2tlbiwgU3RyaW5nIGFjdHVhbFRva2VuVmFsdWUpCisJCQkJCXRocm93cyBNYWlsY2FwUGFyc2VFeGNlcHRpb24geworICAgICAJdGhyb3cgbmV3IE1haWxjYXBQYXJzZUV4Y2VwdGlvbigiRW5jb3VudGVyZWQgYSAiICsKKwkJTWFpbGNhcFRva2VuaXplci5uYW1lRm9yVG9rZW4oYWN0dWFsVG9rZW4pICsgIiB0b2tlbiAoIiArCisJCWFjdHVhbFRva2VuVmFsdWUgKyAiKSB3aGlsZSBleHBlY3RpbmcgYSAiICsKKwkJTWFpbGNhcFRva2VuaXplci5uYW1lRm9yVG9rZW4oZXhwZWN0ZWRUb2tlbikgKyAiIG9yIGEgIiArCisJCU1haWxjYXBUb2tlbml6ZXIubmFtZUZvclRva2VuKG90aGVyRXhwZWN0ZWRUb2tlbikgKyAiIHRva2VuLiIpOworICAgICB9CisKKyAgICAgcHJvdGVjdGVkIHN0YXRpYyB2b2lkIHJlcG9ydFBhcnNlRXJyb3IoaW50IGV4cGVjdGVkVG9rZW4sCisJICAgIGludCBvdGhlckV4cGVjdGVkVG9rZW4sIGludCBhbm90aGVyRXhwZWN0ZWRUb2tlbiwgaW50IGFjdHVhbFRva2VuLAorCSAgICBTdHJpbmcgYWN0dWFsVG9rZW5WYWx1ZSkgdGhyb3dzIE1haWxjYXBQYXJzZUV4Y2VwdGlvbiB7CisJaWYgKExvZ1N1cHBvcnQuaXNMb2dnYWJsZSgpKQorCSAgICBMb2dTdXBwb3J0LmxvZygiUEFSU0UgRVJST1I6ICIgKyAiRW5jb3VudGVyZWQgYSAiICsKKwkJTWFpbGNhcFRva2VuaXplci5uYW1lRm9yVG9rZW4oYWN0dWFsVG9rZW4pICsgIiB0b2tlbiAoIiArCisJCWFjdHVhbFRva2VuVmFsdWUgKyAiKSB3aGlsZSBleHBlY3RpbmcgYSAiICsKKwkJTWFpbGNhcFRva2VuaXplci5uYW1lRm9yVG9rZW4oZXhwZWN0ZWRUb2tlbikgKyAiLCBhICIgKworCQlNYWlsY2FwVG9rZW5pemVyLm5hbWVGb3JUb2tlbihvdGhlckV4cGVjdGVkVG9rZW4pICsgIiwgb3IgYSAiICsKKwkJTWFpbGNhcFRva2VuaXplci5uYW1lRm9yVG9rZW4oYW5vdGhlckV4cGVjdGVkVG9rZW4pICsgIiB0b2tlbi4iKTsKKyAgICAgCXRocm93IG5ldyBNYWlsY2FwUGFyc2VFeGNlcHRpb24oIkVuY291bnRlcmVkIGEgIiArCisJCU1haWxjYXBUb2tlbml6ZXIubmFtZUZvclRva2VuKGFjdHVhbFRva2VuKSArICIgdG9rZW4gKCIgKworCQlhY3R1YWxUb2tlblZhbHVlICsgIikgd2hpbGUgZXhwZWN0aW5nIGEgIiArCisJCU1haWxjYXBUb2tlbml6ZXIubmFtZUZvclRva2VuKGV4cGVjdGVkVG9rZW4pICsgIiwgYSAiICsKKwkJTWFpbGNhcFRva2VuaXplci5uYW1lRm9yVG9rZW4ob3RoZXJFeHBlY3RlZFRva2VuKSArICIsIG9yIGEgIiArCisJCU1haWxjYXBUb2tlbml6ZXIubmFtZUZvclRva2VuKGFub3RoZXJFeHBlY3RlZFRva2VuKSArICIgdG9rZW4uIik7CisgICAgIH0KKworICAgICAvKiogZm9yIGRlYnVnZ2luZworICAgICBwdWJsaWMgc3RhdGljIHZvaWQJbWFpbihTdHJpbmdbXSBhcmdzKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgCU1hcCBtYXN0ZXJIYXNoID0gbmV3IEhhc2hNYXAoKTsKKyAgICAgCWZvciAoaW50IGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7ICsraSkgeworCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkVudHJ5ICIgKyBpICsgIjogIiArIGFyZ3NbaV0pOworCSAgICBwYXJzZUxpbmUoYXJnc1tpXSwgbWFzdGVySGFzaCk7CisgICAgIAl9CisKKyAgICAgCUVudW1lcmF0aW9uIHR5cGVzID0gbWFzdGVySGFzaC5rZXlzKCk7CisgICAgIAl3aGlsZSAodHlwZXMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKKwkgICAgU3RyaW5nIGtleSA9IChTdHJpbmcpdHlwZXMubmV4dEVsZW1lbnQoKTsKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJNSU1FIFR5cGU6ICIgKyBrZXkpOworCisJICAgIE1hcCBjb21tYW5kSGFzaCA9IChNYXApbWFzdGVySGFzaC5nZXQoa2V5KTsKKwkgICAgRW51bWVyYXRpb24gY29tbWFuZHMgPSBjb21tYW5kSGFzaC5rZXlzKCk7CisJICAgIHdoaWxlIChjb21tYW5kcy5oYXNNb3JlRWxlbWVudHMoKSkgeworCQlTdHJpbmcgY29tbWFuZCA9IChTdHJpbmcpY29tbWFuZHMubmV4dEVsZW1lbnQoKTsKKwkJU3lzdGVtLm91dC5wcmludGxuKCIgICAgQ29tbWFuZDogIiArIGNvbW1hbmQpOworCisJCVZlY3RvciBjbGFzc2VzID0gKFZlY3Rvciljb21tYW5kSGFzaC5nZXQoY29tbWFuZCk7CisJCWZvciAoaW50IGkgPSAwOyBpIDwgY2xhc3Nlcy5zaXplKCk7ICsraSkgeworCQkJU3lzdGVtLm91dC5wcmludGxuKCIgICAgICAgIENsYXNzOiAiICsKKwkJCQkJICAgIChTdHJpbmcpY2xhc3Nlcy5lbGVtZW50QXQoaSkpOworCQl9CisJICAgIH0KKworCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiIpOworCX0KKyAgICB9CisgICAgKi8KK30KZGlmZiAtLWdpdCBhL2FuZHJvaWQvYWN0aXZhdGlvbi9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vYWN0aXZhdGlvbi9yZWdpc3RyaWVzL01haWxjYXBQYXJzZUV4Y2VwdGlvbi5qYXZhIGIvYW5kcm9pZC9hY3RpdmF0aW9uL3NyYy9tYWluL2phdmEvY29tL3N1bi9hY3RpdmF0aW9uL3JlZ2lzdHJpZXMvTWFpbGNhcFBhcnNlRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzU0YzQwNQotLS0gL2Rldi9udWxsCisrKyBiL2FuZHJvaWQvYWN0aXZhdGlvbi9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vYWN0aXZhdGlvbi9yZWdpc3RyaWVzL01haWxjYXBQYXJzZUV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsMjUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorICovCisKK3BhY2thZ2UJY29tLnN1bi5hY3RpdmF0aW9uLnJlZ2lzdHJpZXM7CisKKy8qKgorICoJQSBjbGFzcyB0byBlbmNhcHN1bGF0ZSBNYWlsY2FwIHBhcnNpbmcgcmVsYXRlZCBleGNlcHRpb25zCisgKi8KK3B1YmxpYyBjbGFzcyBNYWlsY2FwUGFyc2VFeGNlcHRpb24gZXh0ZW5kcyBFeGNlcHRpb24geworCisgICAgcHVibGljIE1haWxjYXBQYXJzZUV4Y2VwdGlvbigpIHsKKwlzdXBlcigpOworICAgIH0KKworICAgIHB1YmxpYyBNYWlsY2FwUGFyc2VFeGNlcHRpb24oU3RyaW5nIGluSW5mbykgeworCXN1cGVyKGluSW5mbyk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYW5kcm9pZC9hY3RpdmF0aW9uL3NyYy9tYWluL2phdmEvY29tL3N1bi9hY3RpdmF0aW9uL3JlZ2lzdHJpZXMvTWFpbGNhcFRva2VuaXplci5qYXZhIGIvYW5kcm9pZC9hY3RpdmF0aW9uL3NyYy9tYWluL2phdmEvY29tL3N1bi9hY3RpdmF0aW9uL3JlZ2lzdHJpZXMvTWFpbGNhcFRva2VuaXplci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY0Mzc5MzAKLS0tIC9kZXYvbnVsbAorKysgYi9hbmRyb2lkL2FjdGl2YXRpb24vc3JjL21haW4vamF2YS9jb20vc3VuL2FjdGl2YXRpb24vcmVnaXN0cmllcy9NYWlsY2FwVG9rZW5pemVyLmphdmEKQEAgLTAsMCArMSwzMDcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorICovCisKK3BhY2thZ2UJY29tLnN1bi5hY3RpdmF0aW9uLnJlZ2lzdHJpZXM7CisKKy8qKgorICoJQSB0b2tlbml6ZXIgZm9yIHN0cmluZ3MgaW4gdGhlIGZvcm0gb2YgImZvby9iYXI7IHByb3AxPXZhbDE7IC4uLiAiLgorICoJVXNlZnVsIGZvciBwYXJzaW5nIE1JTUUgY29udGVudCB0eXBlcy4KKyAqLworcHVibGljIGNsYXNzIE1haWxjYXBUb2tlbml6ZXIgeworCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVU5LTk9XTl9UT0tFTiA9IDA7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1RBUlRfVE9LRU4gPSAxOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUUklOR19UT0tFTiA9IDI7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU9JX1RPS0VOID0gNTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTTEFTSF9UT0tFTiA9ICcvJzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTRU1JQ09MT05fVE9LRU4gPSAnOyc7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVFVQUxTX1RPS0VOID0gJz0nOworCisgICAgLyoqCisgICAgICogIENvbnN0cnVjdG9yCisgICAgICoKKyAgICAgKiAgQHBhcmFtICBpbnB1dFN0cmluZyB0aGUgc3RyaW5nIHRvIHRva2VuaXplCisgICAgICovCisgICAgcHVibGljIE1haWxjYXBUb2tlbml6ZXIoU3RyaW5nIGlucHV0U3RyaW5nKSB7CisJZGF0YSA9IGlucHV0U3RyaW5nOworCWRhdGFJbmRleCA9IDA7CisJZGF0YUxlbmd0aCA9IGlucHV0U3RyaW5nLmxlbmd0aCgpOworCisJY3VycmVudFRva2VuID0gU1RBUlRfVE9LRU47CisJY3VycmVudFRva2VuVmFsdWUgPSAiIjsKKworCWlzQXV0b3F1b3RpbmcgPSBmYWxzZTsKKwlhdXRvcXVvdGVDaGFyID0gJzsnOworICAgIH0KKworICAgIC8qKgorICAgICAqICBTZXQgd2hldGhlciBhdXRvLXF1b3RpbmcgaXMgb24gb3Igb2ZmLgorICAgICAqCisgICAgICogIEF1dG8tcXVvdGluZyBtZWFucyB0aGF0IGFsbCBjaGFyYWN0ZXJzIGFmdGVyIHRoZSBmaXJzdAorICAgICAqICBub24td2hpdGVzcGFjZSwgbm9uLWNvbnRyb2wgY2hhcmFjdGVyIHVwIHRvIHRoZSBhdXRvLXF1b3RlCisgICAgICogIHRlcm1pbmF0b3IgY2hhcmFjdGVyIG9yIEVPSSAobWludXMgYW55IHdoaXRlc3BhY2UgaW1tZWRpYXRsZXkKKyAgICAgKiAgcHJlY2VlZGluZyBpdCkgaXMgY29uc2lkZXJlZCBhIHRva2VuLgorICAgICAqCisgICAgICogIFRoaXMgaXMgcmVxdWlyZWQgZm9yIGhhbmRsaW5nIGNvbW1hbmQgc3RyaW5ncyBpbiBhIG1haWxjYXAgZW50cnkuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0SXNBdXRvcXVvdGluZyhib29sZWFuIHZhbHVlKSB7CisJaXNBdXRvcXVvdGluZyA9IHZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqICBSZXRyaWV2ZSBjdXJyZW50IHRva2VuLgorICAgICAqCisgICAgICogIEByZXR1cm4gICAgVGhlIGN1cnJlbnQgdG9rZW4gdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEN1cnJlbnRUb2tlbigpIHsKKwlyZXR1cm4gY3VycmVudFRva2VuOworICAgIH0KKworICAgIC8qCisgICAgICogIEdldCBhIFN0cmluZyB0aGF0IGRlc2NyaWJlcyB0aGUgZ2l2ZW4gdG9rZW4uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgbmFtZUZvclRva2VuKGludCB0b2tlbikgeworCVN0cmluZyBuYW1lID0gInJlYWxseSB1bmtub3duIjsKKworCXN3aXRjaCh0b2tlbikgeworCSAgICBjYXNlIFVOS05PV05fVE9LRU46CisJCW5hbWUgPSAidW5rbm93biI7CisJCWJyZWFrOworCSAgICBjYXNlIFNUQVJUX1RPS0VOOgorCQluYW1lID0gInN0YXJ0IjsKKwkJYnJlYWs7CisJICAgIGNhc2UgU1RSSU5HX1RPS0VOOgorCQluYW1lID0gInN0cmluZyI7CisJCWJyZWFrOworCSAgICBjYXNlIEVPSV9UT0tFTjoKKwkJbmFtZSA9ICJFT0kiOworCQlicmVhazsKKwkgICAgY2FzZSBTTEFTSF9UT0tFTjoKKwkJbmFtZSA9ICInLyciOworCQlicmVhazsKKwkgICAgY2FzZSBTRU1JQ09MT05fVE9LRU46CisJCW5hbWUgPSAiJzsnIjsKKwkJYnJlYWs7CisJICAgIGNhc2UgRVFVQUxTX1RPS0VOOgorCQluYW1lID0gIic9JyI7CisJCWJyZWFrOworCX0KKworCXJldHVybiBuYW1lOworICAgIH0KKworICAgIC8qCisgICAgICogIFJldHJpZXZlIGN1cnJlbnQgdG9rZW4gdmFsdWUuCisgICAgICoKKyAgICAgKiAgQHJldHVybiAgICBBIFN0cmluZyBjb250YWluaW5nIHRoZSBjdXJyZW50IHRva2VuIHZhbHVlCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRDdXJyZW50VG9rZW5WYWx1ZSgpIHsKKwlyZXR1cm4gY3VycmVudFRva2VuVmFsdWU7CisgICAgfQorCisgICAgLyoKKyAgICAgKiAgUHJvY2VzcyB0aGUgbmV4dCB0b2tlbi4KKyAgICAgKgorICAgICAqICBAcmV0dXJuICAgIHRoZSBuZXh0IHRva2VuCisgICAgICovCisgICAgcHVibGljIGludCBuZXh0VG9rZW4oKSB7CisJaWYgKGRhdGFJbmRleCA8IGRhdGFMZW5ndGgpIHsKKwkgICAgLy8gIHNraXAgd2hpdGUgc3BhY2UKKwkgICAgd2hpbGUgKChkYXRhSW5kZXggPCBkYXRhTGVuZ3RoKSAmJgorCQkgICAgKGlzV2hpdGVTcGFjZUNoYXIoZGF0YS5jaGFyQXQoZGF0YUluZGV4KSkpKSB7CisJCSsrZGF0YUluZGV4OworCSAgICB9CisKKwkgICAgaWYgKGRhdGFJbmRleCA8IGRhdGFMZW5ndGgpIHsKKwkJLy8gIGV4YW1pbmUgdGhlIGN1cnJlbnQgY2hhcmFjdGVyIGFuZCBzZWUgd2hhdCBraW5kIG9mIHRva2VuIHdlIGhhdmUKKwkJY2hhciBjID0gZGF0YS5jaGFyQXQoZGF0YUluZGV4KTsKKwkJaWYgKGlzQXV0b3F1b3RpbmcpIHsKKwkJICAgIGlmIChjID09ICc7JyB8fCBjID09ICc9JykgeworCQkJY3VycmVudFRva2VuID0gYzsKKwkJCWN1cnJlbnRUb2tlblZhbHVlID0gbmV3IENoYXJhY3RlcihjKS50b1N0cmluZygpOworCQkJKytkYXRhSW5kZXg7CisJCSAgICB9IGVsc2UgeworCQkJcHJvY2Vzc0F1dG9xdW90ZVRva2VuKCk7CisJCSAgICB9CisJCX0gZWxzZSB7CisJCSAgICBpZiAoaXNTdHJpbmdUb2tlbkNoYXIoYykpIHsKKwkJCXByb2Nlc3NTdHJpbmdUb2tlbigpOworCQkgICAgfSBlbHNlIGlmICgoYyA9PSAnLycpIHx8IChjID09ICc7JykgfHwgKGMgPT0gJz0nKSkgeworCQkJY3VycmVudFRva2VuID0gYzsKKwkJCWN1cnJlbnRUb2tlblZhbHVlID0gbmV3IENoYXJhY3RlcihjKS50b1N0cmluZygpOworCQkJKytkYXRhSW5kZXg7CisJCSAgICB9IGVsc2UgeworCQkJY3VycmVudFRva2VuID0gVU5LTk9XTl9UT0tFTjsKKwkJCWN1cnJlbnRUb2tlblZhbHVlID0gbmV3IENoYXJhY3RlcihjKS50b1N0cmluZygpOworCQkJKytkYXRhSW5kZXg7CisJCSAgICB9CisJCX0KKwkgICAgfSBlbHNlIHsKKwkJY3VycmVudFRva2VuID0gRU9JX1RPS0VOOworCQljdXJyZW50VG9rZW5WYWx1ZSA9IG51bGw7CisJICAgIH0KKwl9IGVsc2UgeworCSAgICBjdXJyZW50VG9rZW4gPSBFT0lfVE9LRU47CisJICAgIGN1cnJlbnRUb2tlblZhbHVlID0gbnVsbDsKKwl9CisKKwlyZXR1cm4gY3VycmVudFRva2VuOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBwcm9jZXNzU3RyaW5nVG9rZW4oKSB7CisJLy8gIGNhcHR1cmUgdGhlIGluaXRpYWwgaW5kZXgKKwlpbnQgaW5pdGlhbEluZGV4ID0gZGF0YUluZGV4OworCisJLy8gIHNraXAgdG8gMXN0IG5vbiBzdHJpbmcgdG9rZW4gY2hhcmFjdGVyCisJd2hpbGUgKChkYXRhSW5kZXggPCBkYXRhTGVuZ3RoKSAmJgorCQlpc1N0cmluZ1Rva2VuQ2hhcihkYXRhLmNoYXJBdChkYXRhSW5kZXgpKSkgeworCSAgICArK2RhdGFJbmRleDsKKwl9CisKKwljdXJyZW50VG9rZW4gPSBTVFJJTkdfVE9LRU47CisJY3VycmVudFRva2VuVmFsdWUgPSBkYXRhLnN1YnN0cmluZyhpbml0aWFsSW5kZXgsIGRhdGFJbmRleCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHByb2Nlc3NBdXRvcXVvdGVUb2tlbigpIHsKKwkvLyAgY2FwdHVyZSB0aGUgaW5pdGlhbCBpbmRleAorCWludCBpbml0aWFsSW5kZXggPSBkYXRhSW5kZXg7CisKKwkvLyAgbm93IHNraXAgdG8gdGhlIDFzdCBub24tZXNjYXBlZCBhdXRvcXVvdGUgdGVybWluYXRpb24gY2hhcmFjdGVyCisJLy8gIFhYWCAtIGRvZXNuJ3QgYWN0dWFsbHkgY29uc2lkZXIgZXNjYXBpbmcKKwlib29sZWFuIGZvdW5kVGVybWluYXRvciA9IGZhbHNlOworCXdoaWxlICgoZGF0YUluZGV4IDwgZGF0YUxlbmd0aCkgJiYgIWZvdW5kVGVybWluYXRvcikgeworCSAgICBjaGFyIGMgPSBkYXRhLmNoYXJBdChkYXRhSW5kZXgpOworCSAgICBpZiAoYyAhPSBhdXRvcXVvdGVDaGFyKSB7CisJCSsrZGF0YUluZGV4OworCSAgICB9IGVsc2UgeworCQlmb3VuZFRlcm1pbmF0b3IgPSB0cnVlOworCSAgICB9CisJfQorCisJY3VycmVudFRva2VuID0gU1RSSU5HX1RPS0VOOworCWN1cnJlbnRUb2tlblZhbHVlID0KKwkgICAgZml4RXNjYXBlU2VxdWVuY2VzKGRhdGEuc3Vic3RyaW5nKGluaXRpYWxJbmRleCwgZGF0YUluZGV4KSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc1NwZWNpYWxDaGFyKGNoYXIgYykgeworCWJvb2xlYW4gbEFuc3dlciA9IGZhbHNlOworCisJc3dpdGNoKGMpIHsKKwkgICAgY2FzZSAnKCc6CisJICAgIGNhc2UgJyknOgorCSAgICBjYXNlICc8JzoKKwkgICAgY2FzZSAnPic6CisJICAgIGNhc2UgJ0AnOgorCSAgICBjYXNlICcsJzoKKwkgICAgY2FzZSAnOyc6CisJICAgIGNhc2UgJzonOgorCSAgICBjYXNlICdcXCc6CisJICAgIGNhc2UgJyInOgorCSAgICBjYXNlICcvJzoKKwkgICAgY2FzZSAnWyc6CisJICAgIGNhc2UgJ10nOgorCSAgICBjYXNlICc/JzoKKwkgICAgY2FzZSAnPSc6CisJCWxBbnN3ZXIgPSB0cnVlOworCQlicmVhazsKKwl9CisKKwlyZXR1cm4gbEFuc3dlcjsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzQ29udHJvbENoYXIoY2hhciBjKSB7CisJcmV0dXJuIENoYXJhY3Rlci5pc0lTT0NvbnRyb2woYyk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc1doaXRlU3BhY2VDaGFyKGNoYXIgYykgeworCXJldHVybiBDaGFyYWN0ZXIuaXNXaGl0ZXNwYWNlKGMpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNTdHJpbmdUb2tlbkNoYXIoY2hhciBjKSB7CisJcmV0dXJuICFpc1NwZWNpYWxDaGFyKGMpICYmICFpc0NvbnRyb2xDaGFyKGMpICYmICFpc1doaXRlU3BhY2VDaGFyKGMpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBmaXhFc2NhcGVTZXF1ZW5jZXMoU3RyaW5nIGlucHV0U3RyaW5nKSB7CisJaW50IGlucHV0TGVuZ3RoID0gaW5wdXRTdHJpbmcubGVuZ3RoKCk7CisJU3RyaW5nQnVmZmVyIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKwlidWZmZXIuZW5zdXJlQ2FwYWNpdHkoaW5wdXRMZW5ndGgpOworCisJZm9yIChpbnQgaSA9IDA7IGkgPCBpbnB1dExlbmd0aDsgKytpKSB7CisJICAgIGNoYXIgY3VycmVudENoYXIgPSBpbnB1dFN0cmluZy5jaGFyQXQoaSk7CisJICAgIGlmIChjdXJyZW50Q2hhciAhPSAnXFwnKSB7CisJCWJ1ZmZlci5hcHBlbmQoY3VycmVudENoYXIpOworCSAgICB9IGVsc2UgeworCQlpZiAoaSA8IGlucHV0TGVuZ3RoIC0gMSkgeworCQkgICAgY2hhciBuZXh0Q2hhciA9IGlucHV0U3RyaW5nLmNoYXJBdChpICsgMSk7CisJCSAgICBidWZmZXIuYXBwZW5kKG5leHRDaGFyKTsKKworCQkgICAgLy8gIGZvcmNlIGEgc2tpcCBvdmVyIHRoZSBuZXh0IGNoYXJhY3RlciB0b28KKwkJICAgICsraTsKKwkJfSBlbHNlIHsKKwkJICAgIGJ1ZmZlci5hcHBlbmQoY3VycmVudENoYXIpOworCQl9CisJICAgIH0KKwl9CisKKwlyZXR1cm4gYnVmZmVyLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBTdHJpbmcgIGRhdGE7CisgICAgcHJpdmF0ZSBpbnQgICAgIGRhdGFJbmRleDsKKyAgICBwcml2YXRlIGludCAgICAgZGF0YUxlbmd0aDsKKyAgICBwcml2YXRlIGludCAgICAgY3VycmVudFRva2VuOworICAgIHByaXZhdGUgU3RyaW5nICBjdXJyZW50VG9rZW5WYWx1ZTsKKyAgICBwcml2YXRlIGJvb2xlYW4gaXNBdXRvcXVvdGluZzsKKyAgICBwcml2YXRlIGNoYXIgICAgYXV0b3F1b3RlQ2hhcjsKKworICAgIC8qCisgICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykgeworCWZvciAoaW50IGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7ICsraSkgeworCSAgICBNYWlsY2FwVG9rZW5pemVyIHRva2VuaXplciA9IG5ldyBNYWlsY2FwVG9rZW5pemVyKGFyZ3NbaV0pOworCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiT3JpZ2luYWw6IHwiICsgYXJnc1tpXSArICJ8Iik7CisKKwkgICAgaW50IGN1cnJlbnRUb2tlbiA9IHRva2VuaXplci5uZXh0VG9rZW4oKTsKKwkgICAgd2hpbGUgKGN1cnJlbnRUb2tlbiAhPSBFT0lfVE9LRU4pIHsKKwkJc3dpdGNoKGN1cnJlbnRUb2tlbikgeworCQkgICAgY2FzZSBVTktOT1dOX1RPS0VOOgorCQkJU3lzdGVtLm91dC5wcmludGxuKCIgIFVua25vd24gVG9rZW46ICAgICAgICAgICB8IiArIHRva2VuaXplci5nZXRDdXJyZW50VG9rZW5WYWx1ZSgpICsgInwiKTsKKwkJCWJyZWFrOworCQkgICAgY2FzZSBTVEFSVF9UT0tFTjoKKwkJCVN5c3RlbS5vdXQucHJpbnRsbigiICBTdGFydCBUb2tlbjogICAgICAgICAgICAgfCIgKyB0b2tlbml6ZXIuZ2V0Q3VycmVudFRva2VuVmFsdWUoKSArICJ8Iik7CisJCQlicmVhazsKKwkJICAgIGNhc2UgU1RSSU5HX1RPS0VOOgorCQkJU3lzdGVtLm91dC5wcmludGxuKCIgIFN0cmluZyBUb2tlbjogICAgICAgICAgICB8IiArIHRva2VuaXplci5nZXRDdXJyZW50VG9rZW5WYWx1ZSgpICsgInwiKTsKKwkJCWJyZWFrOworCQkgICAgY2FzZSBFT0lfVE9LRU46CisJCQlTeXN0ZW0ub3V0LnByaW50bG4oIiAgRU9JIFRva2VuOiAgICAgICAgICAgICAgIHwiICsgdG9rZW5pemVyLmdldEN1cnJlbnRUb2tlblZhbHVlKCkgKyAifCIpOworCQkJYnJlYWs7CisJCSAgICBjYXNlIFNMQVNIX1RPS0VOOgorCQkJU3lzdGVtLm91dC5wcmludGxuKCIgIFNsYXNoIFRva2VuOiAgICAgICAgICAgICB8IiArIHRva2VuaXplci5nZXRDdXJyZW50VG9rZW5WYWx1ZSgpICsgInwiKTsKKwkJCWJyZWFrOworCQkgICAgY2FzZSBTRU1JQ09MT05fVE9LRU46CisJCQlTeXN0ZW0ub3V0LnByaW50bG4oIiAgU2VtaWNvbG9uIFRva2VuOiAgICAgICAgIHwiICsgdG9rZW5pemVyLmdldEN1cnJlbnRUb2tlblZhbHVlKCkgKyAifCIpOworCQkJYnJlYWs7CisJCSAgICBjYXNlIEVRVUFMU19UT0tFTjoKKwkJCVN5c3RlbS5vdXQucHJpbnRsbigiICBFcXVhbHMgVG9rZW46ICAgICAgICAgICAgfCIgKyB0b2tlbml6ZXIuZ2V0Q3VycmVudFRva2VuVmFsdWUoKSArICJ8Iik7CisJCQlicmVhazsKKwkJICAgIGRlZmF1bHQ6CisJCQlTeXN0ZW0ub3V0LnByaW50bG4oIiAgUmVhbGx5IFVua25vd24gVG9rZW46ICAgIHwiICsgdG9rZW5pemVyLmdldEN1cnJlbnRUb2tlblZhbHVlKCkgKyAifCIpOworCQkJYnJlYWs7CisJCX0KKworCQljdXJyZW50VG9rZW4gPSB0b2tlbml6ZXIubmV4dFRva2VuKCk7CisJICAgIH0KKworCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiIpOworCX0KKyAgICB9CisgICAgKi8KK30KZGlmZiAtLWdpdCBhL2FuZHJvaWQvYWN0aXZhdGlvbi9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vYWN0aXZhdGlvbi9yZWdpc3RyaWVzL01pbWVUeXBlRW50cnkuamF2YSBiL2FuZHJvaWQvYWN0aXZhdGlvbi9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vYWN0aXZhdGlvbi9yZWdpc3RyaWVzL01pbWVUeXBlRW50cnkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNTgyZjc3Ci0tLSAvZGV2L251bGwKKysrIGIvYW5kcm9pZC9hY3RpdmF0aW9uL3NyYy9tYWluL2phdmEvY29tL3N1bi9hY3RpdmF0aW9uL3JlZ2lzdHJpZXMvTWltZVR5cGVFbnRyeS5qYXZhCkBAIC0wLDAgKzEsMzUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorICovCisKK3BhY2thZ2UgY29tLnN1bi5hY3RpdmF0aW9uLnJlZ2lzdHJpZXM7CisKK2ltcG9ydCBqYXZhLmxhbmcuKjsKKworcHVibGljIGNsYXNzIE1pbWVUeXBlRW50cnkgeworICAgIHByaXZhdGUgU3RyaW5nIHR5cGU7CisgICAgcHJpdmF0ZSBTdHJpbmcgZXh0ZW5zaW9uOworCisgICAgcHVibGljIE1pbWVUeXBlRW50cnkoU3RyaW5nIG1pbWVfdHlwZSwgU3RyaW5nIGZpbGVfZXh0KSB7CisJdHlwZSA9IG1pbWVfdHlwZTsKKwlleHRlbnNpb24gPSBmaWxlX2V4dDsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldE1JTUVUeXBlKCkgeworCXJldHVybiB0eXBlOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0RmlsZUV4dGVuc2lvbigpIHsKKwlyZXR1cm4gZXh0ZW5zaW9uOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisJcmV0dXJuICJNSU1FVHlwZUVudHJ5OiAiICsgdHlwZSArICIsICIgKyBleHRlbnNpb247CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYW5kcm9pZC9hY3RpdmF0aW9uL3NyYy9tYWluL2phdmEvY29tL3N1bi9hY3RpdmF0aW9uL3JlZ2lzdHJpZXMvTWltZVR5cGVGaWxlLmphdmEgYi9hbmRyb2lkL2FjdGl2YXRpb24vc3JjL21haW4vamF2YS9jb20vc3VuL2FjdGl2YXRpb24vcmVnaXN0cmllcy9NaW1lVHlwZUZpbGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NjkyNzkxCi0tLSAvZGV2L251bGwKKysrIGIvYW5kcm9pZC9hY3RpdmF0aW9uL3NyYy9tYWluL2phdmEvY29tL3N1bi9hY3RpdmF0aW9uL3JlZ2lzdHJpZXMvTWltZVR5cGVGaWxlLmphdmEKQEAgLTAsMCArMSwzMDIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorICovCisKK3BhY2thZ2UgY29tLnN1bi5hY3RpdmF0aW9uLnJlZ2lzdHJpZXM7CisKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YS51dGlsLio7CisKK3B1YmxpYyBjbGFzcyBNaW1lVHlwZUZpbGUgeworICAgIHByaXZhdGUgU3RyaW5nIGZuYW1lID0gbnVsbDsKKyAgICBwcml2YXRlIEhhc2h0YWJsZSB0eXBlX2hhc2ggPSBuZXcgSGFzaHRhYmxlKCk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY29uc3RydXRvciB0aGF0IHRha2VzIGEgZmlsZW5hbWUgYXMgYW4gYXJndW1lbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmV3X2ZuYW1lIFRoZSBmaWxlIG5hbWUgb2YgdGhlIG1pbWUgdHlwZXMgZmlsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTWltZVR5cGVGaWxlKFN0cmluZyBuZXdfZm5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJRmlsZSBtaW1lX2ZpbGUgPSBudWxsOworCUZpbGVSZWFkZXIgZnIgPSBudWxsOworCisJZm5hbWUgPSBuZXdfZm5hbWU7IC8vIHJlbWVtYmVyIHRoZSBmaWxlIG5hbWUKKworCW1pbWVfZmlsZSA9IG5ldyBGaWxlKGZuYW1lKTsgLy8gZ2V0IGEgZmlsZSBvYmplY3QKKworCWZyID0gbmV3IEZpbGVSZWFkZXIobWltZV9maWxlKTsKKworCXRyeSB7CisJICAgIHBhcnNlKG5ldyBCdWZmZXJlZFJlYWRlcihmcikpOworCX0gZmluYWxseSB7CisJICAgIHRyeSB7CisJCWZyLmNsb3NlKCk7IC8vIGNsb3NlIGl0CisJICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKwkJLy8gaWdub3JlIGl0CisJICAgIH0KKwl9CisgICAgfQorCisgICAgcHVibGljIE1pbWVUeXBlRmlsZShJbnB1dFN0cmVhbSBpcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlwYXJzZShuZXcgQnVmZmVyZWRSZWFkZXIobmV3IElucHV0U3RyZWFtUmVhZGVyKGlzLCAiaXNvLTg4NTktMSIpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbiBlbXB0eSBEQi4KKyAgICAgKi8KKyAgICBwdWJsaWMgTWltZVR5cGVGaWxlKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIGdldCB0aGUgTWltZVR5cGVFbnRyeSBiYXNlZCBvbiB0aGUgZmlsZSBleHRlbnNpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgTWltZVR5cGVFbnRyeSBnZXRNaW1lVHlwZUVudHJ5KFN0cmluZyBmaWxlX2V4dCkgeworCXJldHVybiAoTWltZVR5cGVFbnRyeSl0eXBlX2hhc2guZ2V0KChPYmplY3QpZmlsZV9leHQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgTUlNRSB0eXBlIHN0cmluZyBjb3JyZXNwb25kaW5nIHRvIHRoZSBmaWxlIGV4dGVuc2lvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldE1JTUVUeXBlU3RyaW5nKFN0cmluZyBmaWxlX2V4dCkgeworCU1pbWVUeXBlRW50cnkgZW50cnkgPSB0aGlzLmdldE1pbWVUeXBlRW50cnkoZmlsZV9leHQpOworCisJaWYgKGVudHJ5ICE9IG51bGwpCisJICAgIHJldHVybiBlbnRyeS5nZXRNSU1FVHlwZSgpOworCWVsc2UKKwkgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXBwZW5kcyBzdHJpbmcgb2YgZW50cmllcyB0byB0aGUgdHlwZXMgcmVnaXN0cnksIG11c3QgYmUgdmFsaWQKKyAgICAgKiAubWltZS50eXBlcyBmb3JtYXQuCisgICAgICogQSBtaW1lLnR5cGVzIGVudHJ5IGlzIG9uZSBvZiB0d28gZm9ybXM6CisgICAgICoKKyAgICAgKgl0eXBlL3N1YnR5cGUJZXh0MSBleHQyIC4uLgorICAgICAqIG9yCisgICAgICoJdHlwZT10eXBlL3N1YnR5cGUgZGVzYz0iZGVzY3JpcHRpb24gb2YgdHlwZSIgZXh0cz1leHQxLGV4dDIsLi4uCisgICAgICoKKyAgICAgKiBFeGFtcGxlOgorICAgICAqICMgdGhpcyBpcyBhIHRlc3QKKyAgICAgKiBhdWRpby9iYXNpYyAgICAgICAgICAgIGF1CisgICAgICogdGV4dC9wbGFpbiAgICAgICAgICAgICB0eHQgdGV4dAorICAgICAqIHR5cGU9YXBwbGljYXRpb24vcG9zdHNjcmlwdCBleHRzPXBzLGVwcworICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFwcGVuZFRvUmVnaXN0cnkoU3RyaW5nIG1pbWVfdHlwZXMpIHsKKwl0cnkgeworCSAgICBwYXJzZShuZXcgQnVmZmVyZWRSZWFkZXIobmV3IFN0cmluZ1JlYWRlcihtaW1lX3R5cGVzKSkpOworCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisJICAgIC8vIGNhbid0IGhhcHBlbgorCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZSBhIHN0cmVhbSBvZiBtaW1lLnR5cGVzIGVudHJpZXMuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHBhcnNlKEJ1ZmZlcmVkUmVhZGVyIGJ1Zl9yZWFkZXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJU3RyaW5nIGxpbmUgPSBudWxsLCBwcmV2ID0gbnVsbDsKKworCXdoaWxlICgobGluZSA9IGJ1Zl9yZWFkZXIucmVhZExpbmUoKSkgIT0gbnVsbCkgeworCSAgICBpZiAocHJldiA9PSBudWxsKQorCQlwcmV2ID0gbGluZTsKKwkgICAgZWxzZQorCQlwcmV2ICs9IGxpbmU7CisJICAgIGludCBlbmQgPSBwcmV2Lmxlbmd0aCgpOworCSAgICBpZiAocHJldi5sZW5ndGgoKSA+IDAgJiYgcHJldi5jaGFyQXQoZW5kIC0gMSkgPT0gJ1xcJykgeworCQlwcmV2ID0gcHJldi5zdWJzdHJpbmcoMCwgZW5kIC0gMSk7CisJCWNvbnRpbnVlOworCSAgICB9CisJICAgIHRoaXMucGFyc2VFbnRyeShwcmV2KTsKKwkgICAgcHJldiA9IG51bGw7CisJfQorCWlmIChwcmV2ICE9IG51bGwpCisJICAgIHRoaXMucGFyc2VFbnRyeShwcmV2KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZSBzaW5nbGUgbWltZS50eXBlcyBlbnRyeS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcGFyc2VFbnRyeShTdHJpbmcgbGluZSkgeworCVN0cmluZyBtaW1lX3R5cGUgPSBudWxsOworCVN0cmluZyBmaWxlX2V4dCA9IG51bGw7CisJbGluZSA9IGxpbmUudHJpbSgpOworCisJaWYgKGxpbmUubGVuZ3RoKCkgPT0gMCkgLy8gZW1wdHkgbGluZS4uLgorCSAgICByZXR1cm47IC8vIEJBSUwhCisKKwkvLyBjaGVjayB0byBzZWUgaWYgdGhpcyBpcyBhIGNvbW1lbnQgbGluZT8KKwlpZiAobGluZS5jaGFyQXQoMCkgPT0gJyMnKQorCSAgICByZXR1cm47IC8vIHRoZW4gd2UgYXJlIGRvbmUhCisKKwkvLyBpcyBpdCBhIG5ldyBmb3JtYXQgbGluZSBvciBvbGQgZm9ybWF0PworCWlmIChsaW5lLmluZGV4T2YoJz0nKSA+IDApIHsKKwkgICAgLy8gbmV3IGZvcm1hdAorCSAgICBMaW5lVG9rZW5pemVyIGx0ID0gbmV3IExpbmVUb2tlbml6ZXIobGluZSk7CisJICAgIHdoaWxlIChsdC5oYXNNb3JlVG9rZW5zKCkpIHsKKwkJU3RyaW5nIG5hbWUgPSBsdC5uZXh0VG9rZW4oKTsKKwkJU3RyaW5nIHZhbHVlID0gbnVsbDsKKwkJaWYgKGx0Lmhhc01vcmVUb2tlbnMoKSAmJiBsdC5uZXh0VG9rZW4oKS5lcXVhbHMoIj0iKSAmJgorCQkJCQkJCWx0Lmhhc01vcmVUb2tlbnMoKSkKKwkJICAgIHZhbHVlID0gbHQubmV4dFRva2VuKCk7CisJCWlmICh2YWx1ZSA9PSBudWxsKSB7CisJCSAgICBpZiAoTG9nU3VwcG9ydC5pc0xvZ2dhYmxlKCkpCisJCQlMb2dTdXBwb3J0LmxvZygiQmFkIC5taW1lLnR5cGVzIGVudHJ5OiAiICsgbGluZSk7CisJCSAgICByZXR1cm47CisJCX0KKwkJaWYgKG5hbWUuZXF1YWxzKCJ0eXBlIikpCisJCSAgICBtaW1lX3R5cGUgPSB2YWx1ZTsKKwkJZWxzZSBpZiAobmFtZS5lcXVhbHMoImV4dHMiKSkgeworCQkgICAgU3RyaW5nVG9rZW5pemVyIHN0ID0gbmV3IFN0cmluZ1Rva2VuaXplcih2YWx1ZSwgIiwiKTsKKwkJICAgIHdoaWxlIChzdC5oYXNNb3JlVG9rZW5zKCkpIHsKKwkJCWZpbGVfZXh0ID0gc3QubmV4dFRva2VuKCk7CisJCQlNaW1lVHlwZUVudHJ5IGVudHJ5ID0KKwkJCQluZXcgTWltZVR5cGVFbnRyeShtaW1lX3R5cGUsIGZpbGVfZXh0KTsKKwkJCXR5cGVfaGFzaC5wdXQoZmlsZV9leHQsIGVudHJ5KTsKKwkJCWlmIChMb2dTdXBwb3J0LmlzTG9nZ2FibGUoKSkKKwkJCSAgICBMb2dTdXBwb3J0LmxvZygiQWRkZWQ6ICIgKyBlbnRyeS50b1N0cmluZygpKTsKKwkJICAgIH0KKwkJfQorCSAgICB9CisJfSBlbHNlIHsKKwkgICAgLy8gb2xkIGZvcm1hdAorCSAgICAvLyBjb3VudCB0aGUgdG9rZW5zCisJICAgIFN0cmluZ1Rva2VuaXplciBzdHJ0b2sgPSBuZXcgU3RyaW5nVG9rZW5pemVyKGxpbmUpOworCSAgICBpbnQgbnVtX3RvayA9IHN0cnRvay5jb3VudFRva2VucygpOworCisJICAgIGlmIChudW1fdG9rID09IDApIC8vIGVtcHR5IGxpbmUKKwkJcmV0dXJuOworCisJICAgIG1pbWVfdHlwZSA9IHN0cnRvay5uZXh0VG9rZW4oKTsgLy8gZ2V0IHRoZSBNSU1FIHR5cGUKKworCSAgICB3aGlsZSAoc3RydG9rLmhhc01vcmVUb2tlbnMoKSkgeworCQlNaW1lVHlwZUVudHJ5IGVudHJ5ID0gbnVsbDsKKworCQlmaWxlX2V4dCA9IHN0cnRvay5uZXh0VG9rZW4oKTsKKwkJZW50cnkgPSBuZXcgTWltZVR5cGVFbnRyeShtaW1lX3R5cGUsIGZpbGVfZXh0KTsKKwkJdHlwZV9oYXNoLnB1dChmaWxlX2V4dCwgZW50cnkpOworCQlpZiAoTG9nU3VwcG9ydC5pc0xvZ2dhYmxlKCkpCisJCSAgICBMb2dTdXBwb3J0LmxvZygiQWRkZWQ6ICIgKyBlbnRyeS50b1N0cmluZygpKTsKKwkgICAgfQorCX0KKyAgICB9CisKKyAgICAvLyBmb3IgZGVidWdnaW5nCisgICAgLyoKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmd2KSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlNaW1lVHlwZUZpbGUgbWYgPSBuZXcgTWltZVR5cGVGaWxlKGFyZ3ZbMF0pOworCVN5c3RlbS5vdXQucHJpbnRsbigiZXh0ICIgKyBhcmd2WzFdICsgIiB0eXBlICIgKworCQkJCQkJbWYuZ2V0TUlNRVR5cGVTdHJpbmcoYXJndlsxXSkpOworCVN5c3RlbS5leGl0KDApOworICAgIH0KKyAgICAqLworfQorCitjbGFzcyBMaW5lVG9rZW5pemVyIHsKKyAgICBwcml2YXRlIGludCBjdXJyZW50UG9zaXRpb247CisgICAgcHJpdmF0ZSBpbnQgbWF4UG9zaXRpb247CisgICAgcHJpdmF0ZSBTdHJpbmcgc3RyOworICAgIHByaXZhdGUgVmVjdG9yIHN0YWNrID0gbmV3IFZlY3RvcigpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBzaW5nbGVzID0gIj0iOwkvLyBzaW5nbGUgY2hhcmFjdGVyIHRva2VucworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIHRva2VuaXplciBmb3IgdGhlIHNwZWNpZmllZCBzdHJpbmcuCisgICAgICogPHA+CisgICAgICoKKyAgICAgKiBAcGFyYW0gICBzdHIgICAgICAgICAgICBhIHN0cmluZyB0byBiZSBwYXJzZWQuCisgICAgICovCisgICAgcHVibGljIExpbmVUb2tlbml6ZXIoU3RyaW5nIHN0cikgeworCWN1cnJlbnRQb3NpdGlvbiA9IDA7CisJdGhpcy5zdHIgPSBzdHI7CisJbWF4UG9zaXRpb24gPSBzdHIubGVuZ3RoKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2tpcHMgd2hpdGUgc3BhY2UuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHNraXBXaGl0ZVNwYWNlKCkgeworCXdoaWxlICgoY3VycmVudFBvc2l0aW9uIDwgbWF4UG9zaXRpb24pICYmCisJICAgICAgIENoYXJhY3Rlci5pc1doaXRlc3BhY2Uoc3RyLmNoYXJBdChjdXJyZW50UG9zaXRpb24pKSkgeworCSAgICBjdXJyZW50UG9zaXRpb24rKzsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdHMgaWYgdGhlcmUgYXJlIG1vcmUgdG9rZW5zIGF2YWlsYWJsZSBmcm9tIHRoaXMgdG9rZW5pemVyJ3Mgc3RyaW5nLgorICAgICAqCisgICAgICogQHJldHVybiAgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlcmUgYXJlIG1vcmUgdG9rZW5zIGF2YWlsYWJsZSBmcm9tIHRoaXMKKyAgICAgKiAgICAgICAgICB0b2tlbml6ZXIncyBzdHJpbmc7IDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaGFzTW9yZVRva2VucygpIHsKKwlpZiAoc3RhY2suc2l6ZSgpID4gMCkKKwkgICAgcmV0dXJuIHRydWU7CisJc2tpcFdoaXRlU3BhY2UoKTsKKwlyZXR1cm4gKGN1cnJlbnRQb3NpdGlvbiA8IG1heFBvc2l0aW9uKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IHRva2VuIGZyb20gdGhpcyB0b2tlbml6ZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuICAgICB0aGUgbmV4dCB0b2tlbiBmcm9tIHRoaXMgdG9rZW5pemVyLgorICAgICAqIEBleGNlcHRpb24gIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gIGlmIHRoZXJlIGFyZSBubyBtb3JlIHRva2VucyBpbiB0aGlzCisgICAgICogICAgICAgICAgICAgICB0b2tlbml6ZXIncyBzdHJpbmcuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBuZXh0VG9rZW4oKSB7CisJaW50IHNpemUgPSBzdGFjay5zaXplKCk7CisJaWYgKHNpemUgPiAwKSB7CisJICAgIFN0cmluZyB0ID0gKFN0cmluZylzdGFjay5lbGVtZW50QXQoc2l6ZSAtIDEpOworCSAgICBzdGFjay5yZW1vdmVFbGVtZW50QXQoc2l6ZSAtIDEpOworCSAgICByZXR1cm4gdDsKKwl9CisJc2tpcFdoaXRlU3BhY2UoKTsKKworCWlmIChjdXJyZW50UG9zaXRpb24gPj0gbWF4UG9zaXRpb24pIHsKKwkgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKKwl9CisKKwlpbnQgc3RhcnQgPSBjdXJyZW50UG9zaXRpb247CisJY2hhciBjID0gc3RyLmNoYXJBdChzdGFydCk7CisJaWYgKGMgPT0gJyInKSB7CisJICAgIGN1cnJlbnRQb3NpdGlvbisrOworCSAgICBib29sZWFuIGZpbHRlciA9IGZhbHNlOworCSAgICB3aGlsZSAoY3VycmVudFBvc2l0aW9uIDwgbWF4UG9zaXRpb24pIHsKKwkJYyA9IHN0ci5jaGFyQXQoY3VycmVudFBvc2l0aW9uKyspOworCQlpZiAoYyA9PSAnXFwnKSB7CisJCSAgICBjdXJyZW50UG9zaXRpb24rKzsKKwkJICAgIGZpbHRlciA9IHRydWU7CisJCX0gZWxzZSBpZiAoYyA9PSAnIicpIHsKKwkJICAgIFN0cmluZyBzOworCisJCSAgICBpZiAoZmlsdGVyKSB7CisJCQlTdHJpbmdCdWZmZXIgc2IgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CisJCQlmb3IgKGludCBpID0gc3RhcnQgKyAxOyBpIDwgY3VycmVudFBvc2l0aW9uIC0gMTsgaSsrKSB7CisJCQkgICAgYyA9IHN0ci5jaGFyQXQoaSk7CisJCQkgICAgaWYgKGMgIT0gJ1xcJykKKwkJCQlzYi5hcHBlbmQoYyk7CisJCQl9CisJCQlzID0gc2IudG9TdHJpbmcoKTsKKwkJICAgIH0gZWxzZQorCQkJcyA9IHN0ci5zdWJzdHJpbmcoc3RhcnQgKyAxLCBjdXJyZW50UG9zaXRpb24gLSAxKTsKKwkJICAgIHJldHVybiBzOworCQl9CisJICAgIH0KKwl9IGVsc2UgaWYgKHNpbmdsZXMuaW5kZXhPZihjKSA+PSAwKSB7CisJICAgIGN1cnJlbnRQb3NpdGlvbisrOworCX0gZWxzZSB7CisJICAgIHdoaWxlICgoY3VycmVudFBvc2l0aW9uIDwgbWF4UG9zaXRpb24pICYmIAorCQkgICBzaW5nbGVzLmluZGV4T2Yoc3RyLmNoYXJBdChjdXJyZW50UG9zaXRpb24pKSA8IDAgJiYKKwkJICAgIUNoYXJhY3Rlci5pc1doaXRlc3BhY2Uoc3RyLmNoYXJBdChjdXJyZW50UG9zaXRpb24pKSkgeworCQljdXJyZW50UG9zaXRpb24rKzsKKwkgICAgfQorCX0KKwlyZXR1cm4gc3RyLnN1YnN0cmluZyhzdGFydCwgY3VycmVudFBvc2l0aW9uKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBwdXNoVG9rZW4oU3RyaW5nIHRva2VuKSB7CisJc3RhY2suYWRkRWxlbWVudCh0b2tlbik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYW5kcm9pZC9hY3RpdmF0aW9uL3NyYy9tYWluL2phdmEvamF2YXgvYWN0aXZhdGlvbi9BY3RpdmF0aW9uRGF0YUZsYXZvci5qYXZhIGIvYW5kcm9pZC9hY3RpdmF0aW9uL3NyYy9tYWluL2phdmEvamF2YXgvYWN0aXZhdGlvbi9BY3RpdmF0aW9uRGF0YUZsYXZvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY0YjczZjAKLS0tIC9kZXYvbnVsbAorKysgYi9hbmRyb2lkL2FjdGl2YXRpb24vc3JjL21haW4vamF2YS9qYXZheC9hY3RpdmF0aW9uL0FjdGl2YXRpb25EYXRhRmxhdm9yLmphdmEKQEAgLTAsMCArMSwyMzQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorICovCisKK3BhY2thZ2UgamF2YXguYWN0aXZhdGlvbjsKKworLy9pbXBvcnQgamF2YS5hd3QuZGF0YXRyYW5zZmVyLkRhdGFGbGF2b3I7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5hY3RpdmF0aW9uLk1pbWVUeXBlOworCisvKioKKyAqIFRoZSBBY3RpdmF0aW9uRGF0YUZsYXZvciBjbGFzcyBpcyBhIHNwZWNpYWwgc3ViY2xhc3Mgb2YKKyAqIDxjb2RlPmphdmEuYXd0LmRhdGF0cmFuc2Zlci5EYXRhRmxhdm9yPC9jb2RlPi4gSXQgYWxsb3dzIHRoZSBKQUYgdG8KKyAqIHNldCBhbGwgdGhyZWUgdmFsdWVzIHN0b3JlZCBieSB0aGUgRGF0YUZsYXZvciBjbGFzcyB2aWEgYSBuZXcKKyAqIGNvbnN0cnVjdG9yLiBJdCBhbHNvIGNvbnRhaW5zIGltcHJvdmVkIE1JTUUgcGFyc2luZyBpbiB0aGUgPGNvZGU+ZXF1YWxzCisgKiA8L2NvZGU+IG1ldGhvZC4gRXhjZXB0IGZvciB0aGUgaW1wcm92ZWQgcGFyc2luZywgaXRzIHNlbWFudGljcyBhcmUKKyAqIGlkZW50aWNhbCB0byB0aGF0IG9mIHRoZSBKREsncyBEYXRhRmxhdm9yIGNsYXNzLgorICovCisKK3B1YmxpYyBjbGFzcyBBY3RpdmF0aW9uRGF0YUZsYXZvciAvKmV4dGVuZHMgRGF0YUZsYXZvciovIHsKKworICAgIC8qCisgICAgICogUmFpc29uIGQnZXRyZToKKyAgICAgKgorICAgICAqIFRoZSBEYXRhRmxhdm9yIGNsYXNzIGluY2x1ZGVkIGluIEpESyAxLjEgaGFzIHNldmVyYWwgbGltaXRhdGlvbnMKKyAgICAgKiBpbmNsdWRpbmcgcGlzcyBwb29yIE1JTUUgdHlwZSBwYXJzaW5nLCBhbmQgdGhlIGxpbWl0YXRpb24gb2YKKyAgICAgKiBvbmx5IHN1cHBvcnRpbmcgc2VyaWFsaXplZCBvYmplY3RzIGFuZCBJbnB1dFN0cmVhbXMgYXMKKyAgICAgKiByZXByZXNlbnRhdGlvbiBvYmplY3RzLiBUaGlzIGNsYXNzICdmaXhlcycgdGhhdC4KKyAgICAgKi8KKworICAgIC8vIEkgdGhpbmsgZm9yIG5vdyBJJ2xsIGtlZXAgY29waWVzIG9mIGFsbCB0aGUgdmFyaWFibGVzIGFuZAorICAgIC8vIHRoZW4gbGF0ZXIgSSBtYXkgY2hvb3NlIHRyeSB0byBiZXR0ZXIgY29leGlzdCB3aXRoIHRoZSBiYXNlCisgICAgLy8gY2xhc3MgKnNpZ2gqCisgICAgcHJpdmF0ZSBTdHJpbmcgbWltZVR5cGUgPSBudWxsOworICAgIHByaXZhdGUgTWltZVR5cGUgbWltZU9iamVjdCA9IG51bGw7CisgICAgcHJpdmF0ZSBTdHJpbmcgaHVtYW5QcmVzZW50YWJsZU5hbWUgPSBudWxsOworICAgIHByaXZhdGUgQ2xhc3MgcmVwcmVzZW50YXRpb25DbGFzcyA9IG51bGw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYSBEYXRhRmxhdm9yIHRoYXQgcmVwcmVzZW50cyBhbiBhcmJpdHJhcnkKKyAgICAgKiBKYXZhIG9iamVjdC4gVGhpcyBjb25zdHJ1Y3RvciBpcyBhbiBleHRlbnNpb24gb2YgdGhlCisgICAgICogSkRLJ3MgRGF0YUZsYXZvciBpbiB0aGF0IGl0IGFsbG93cyB0aGUgZXhwbGljaXQgc2V0dGluZworICAgICAqIG9mIGFsbCB0aHJlZSBEYXRhRmxhdm9yIGF0dHJpYnV0ZXMuCisgICAgICogPHA+CisgICAgICogVGhlIHJldHVybmVkIERhdGFGbGF2b3Igd2lsbCBoYXZlIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyaXN0aWNzOgorICAgICAqIDxwPgorICAgICAqIHJlcHJlc2VudGF0aW9uQ2xhc3MgPSByZXByZXNlbnRhdGlvbkNsYXNzPGJyPgorICAgICAqIG1pbWVUeXBlICAgICAgICAgICAgPSBtaW1lVHlwZTxicj4KKyAgICAgKiBodW1hbk5hbWUgICAgICAgICAgID0gaHVtYW5OYW1lCisgICAgICogPHA+CisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVwcmVzZW50YXRpb25DbGFzcyB0aGUgY2xhc3MgdXNlZCBpbiB0aGlzIERhdGFGbGF2b3IKKyAgICAgKiBAcGFyYW0gbWltZVR5cGUgdGhlIE1JTUUgdHlwZSBvZiB0aGUgZGF0YSByZXByZXNlbnRlZCBieSB0aGlzIGNsYXNzCisgICAgICogQHBhcmFtIGh1bWFuUHJlc2VudGFibGVOYW1lIHRoZSBodW1hbiBwcmVzZW50YWJsZSBuYW1lIG9mIHRoZSBmbGF2b3IKKyAgICAgKi8KKyAgICBwdWJsaWMgQWN0aXZhdGlvbkRhdGFGbGF2b3IoQ2xhc3MgcmVwcmVzZW50YXRpb25DbGFzcywKKwkJICAgICAgU3RyaW5nIG1pbWVUeXBlLCBTdHJpbmcgaHVtYW5QcmVzZW50YWJsZU5hbWUpIHsKKwkvL3N1cGVyKG1pbWVUeXBlLCBodW1hblByZXNlbnRhYmxlTmFtZSk7IC8vIG5lZWQgdG8gY2FsbCBzdXBlcgorCisJLy8gaW5pdCBwcml2YXRlIHZhcmlhYmxlczoKKwl0aGlzLm1pbWVUeXBlID0gbWltZVR5cGU7CisJdGhpcy5odW1hblByZXNlbnRhYmxlTmFtZSA9IGh1bWFuUHJlc2VudGFibGVOYW1lOworCXRoaXMucmVwcmVzZW50YXRpb25DbGFzcyA9IHJlcHJlc2VudGF0aW9uQ2xhc3M7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGEgRGF0YUZsYXZvciB0aGF0IHJlcHJlc2VudHMgYSBNaW1lVHlwZS4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgcmV0dXJuZWQgRGF0YUZsYXZvciB3aWxsIGhhdmUgdGhlIGZvbGxvd2luZyBjaGFyYWN0ZXJpc3RpY3M6CisgICAgICogPHA+CisgICAgICogSWYgdGhlIG1pbWVUeXBlIGlzICJhcHBsaWNhdGlvbi94LWphdmEtc2VyaWFsaXplZC1vYmplY3Q7CisgICAgICogY2xhc3M9IiwgdGhlIHJlc3VsdCBpcyB0aGUgc2FtZSBhcyBjYWxsaW5nIG5ldworICAgICAqIERhdGFGbGF2b3IoQ2xhc3MuZm9yTmFtZSgpKSBhcyBhYm92ZS4KKyAgICAgKiA8cD4KKyAgICAgKiBvdGhlcndpc2U6CisgICAgICogPHA+CisgICAgICogcmVwcmVzZW50YXRpb25DbGFzcyA9IElucHV0U3RyZWFtPHA+CisgICAgICogbWltZVR5cGUgPSBtaW1lVHlwZTxwPgorICAgICAqCisgICAgICogQHBhcmFtIHJlcHJlc2VudGF0aW9uQ2xhc3MgdGhlIGNsYXNzIHVzZWQgaW4gdGhpcyBEYXRhRmxhdm9yCisgICAgICogQHBhcmFtIGh1bWFuUHJlc2VudGFibGVOYW1lIHRoZSBodW1hbiBwcmVzZW50YWJsZSBuYW1lIG9mIHRoZSBmbGF2b3IKKyAgICAgKi8KKyAgICBwdWJsaWMgQWN0aXZhdGlvbkRhdGFGbGF2b3IoQ2xhc3MgcmVwcmVzZW50YXRpb25DbGFzcywKKwkJCQlTdHJpbmcgaHVtYW5QcmVzZW50YWJsZU5hbWUpIHsKKwkvL3N1cGVyKHJlcHJlc2VudGF0aW9uQ2xhc3MsIGh1bWFuUHJlc2VudGFibGVOYW1lKTsKKwkvL3RoaXMubWltZVR5cGUgPSBzdXBlci5nZXRNaW1lVHlwZSgpOworCXRoaXMubWltZVR5cGUgPSAiYXBwbGljYXRpb24veC1qYXZhLXNlcmlhbGl6ZWQtb2JqZWN0IjsKKwl0aGlzLnJlcHJlc2VudGF0aW9uQ2xhc3MgPSByZXByZXNlbnRhdGlvbkNsYXNzOworICAgICAgCXRoaXMuaHVtYW5QcmVzZW50YWJsZU5hbWUgPSBodW1hblByZXNlbnRhYmxlTmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYSBEYXRhRmxhdm9yIHRoYXQgcmVwcmVzZW50cyBhIE1pbWVUeXBlLgorICAgICAqIDxwPgorICAgICAqIFRoZSByZXR1cm5lZCBEYXRhRmxhdm9yIHdpbGwgaGF2ZSB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcmlzdGljczoKKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGUgbWltZVR5cGUgaXMgImFwcGxpY2F0aW9uL3gtamF2YS1zZXJpYWxpemVkLW9iamVjdDsgY2xhc3M9IiwKKyAgICAgKiB0aGUgcmVzdWx0IGlzIHRoZSBzYW1lIGFzIGNhbGxpbmcgbmV3IERhdGFGbGF2b3IoQ2xhc3MuZm9yTmFtZSgpKSBhcworICAgICAqIGFib3ZlLCBvdGhlcndpc2U6CisgICAgICogPHA+CisgICAgICogcmVwcmVzZW50YXRpb25DbGFzcyA9IElucHV0U3RyZWFtPHA+CisgICAgICogbWltZVR5cGUgPSBtaW1lVHlwZQorICAgICAqCisgICAgICogQHBhcmFtIG1pbWVUeXBlIHRoZSBNSU1FIHR5cGUgb2YgdGhlIGRhdGEgcmVwcmVzZW50ZWQgYnkgdGhpcyBjbGFzcworICAgICAqIEBwYXJhbSBodW1hblByZXNlbnRhYmxlTmFtZSB0aGUgaHVtYW4gcHJlc2VudGFibGUgbmFtZSBvZiB0aGUgZmxhdm9yCisgICAgICovCisgICAgcHVibGljIEFjdGl2YXRpb25EYXRhRmxhdm9yKFN0cmluZyBtaW1lVHlwZSwgU3RyaW5nIGh1bWFuUHJlc2VudGFibGVOYW1lKSB7CisJLy9zdXBlcihtaW1lVHlwZSwgaHVtYW5QcmVzZW50YWJsZU5hbWUpOworCXRoaXMubWltZVR5cGUgPSBtaW1lVHlwZTsKKwl0cnkgeworCSAgICB0aGlzLnJlcHJlc2VudGF0aW9uQ2xhc3MgPSBDbGFzcy5mb3JOYW1lKCJqYXZhLmlvLklucHV0U3RyZWFtIik7CisJfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBleCkgeworCSAgICAvLyBYWFggLSBzaG91bGQgbmV2ZXIgaGFwcGVuLCBpZ25vcmUgaXQKKwl9CisgICAgICAJdGhpcy5odW1hblByZXNlbnRhYmxlTmFtZSA9IGh1bWFuUHJlc2VudGFibGVOYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgTUlNRSB0eXBlIGZvciB0aGlzIERhdGFGbGF2b3IuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBNSU1FIHR5cGUKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldE1pbWVUeXBlKCkgeworCXJldHVybiBtaW1lVHlwZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIHJlcHJlc2VudGF0aW9uIGNsYXNzLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgcmVwcmVzZW50YXRpb24gY2xhc3MKKyAgICAgKi8KKyAgICBwdWJsaWMgQ2xhc3MgZ2V0UmVwcmVzZW50YXRpb25DbGFzcygpIHsKKwlyZXR1cm4gcmVwcmVzZW50YXRpb25DbGFzczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIEh1bWFuIFByZXNlbnRhYmxlIG5hbWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBodW1hbiBwcmVzZW50YWJsZSBuYW1lCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRIdW1hblByZXNlbnRhYmxlTmFtZSgpIHsKKwlyZXR1cm4gaHVtYW5QcmVzZW50YWJsZU5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBodW1hbiBwcmVzZW50YWJsZSBuYW1lLgorICAgICAqCisgICAgICogQHBhcmFtIGh1bWFuUHJlc2VudGFibGVOYW1lCXRoZSBuYW1lIHRvIHNldAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEh1bWFuUHJlc2VudGFibGVOYW1lKFN0cmluZyBodW1hblByZXNlbnRhYmxlTmFtZSkgeworCXRoaXMuaHVtYW5QcmVzZW50YWJsZU5hbWUgPSBodW1hblByZXNlbnRhYmxlTmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGUgRGF0YUZsYXZvciBwYXNzZWQgaW4gd2l0aCB0aGlzIERhdGFGbGF2b3I7IGNhbGxzCisgICAgICogdGhlIDxjb2RlPmlzTWltZVR5cGVFcXVhbDwvY29kZT4gbWV0aG9kLgorICAgICAqCisgICAgICogQHBhcmFtIGRhdGFGbGF2b3IJdGhlIERhdGFGbGF2b3IgdG8gY29tcGFyZSB3aXRoCisgICAgICogQHJldHVybgkJCXRydWUgaWYgdGhlIE1JTUUgdHlwZSBhbmQgcmVwcmVzZW50YXRpb24gY2xhc3MKKyAgICAgKgkJCQlhcmUgdGhlIHNhbWUKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoQWN0aXZhdGlvbkRhdGFGbGF2b3IgZGF0YUZsYXZvcikgeworCXJldHVybiAoaXNNaW1lVHlwZUVxdWFsKGRhdGFGbGF2b3IubWltZVR5cGUpICYmCisJIAlkYXRhRmxhdm9yLmdldFJlcHJlc2VudGF0aW9uQ2xhc3MoKSA9PSByZXByZXNlbnRhdGlvbkNsYXNzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJcyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBNSU1FIHR5cGUgcGFzc2VkIGluIGVxdWl2YWxlbnQKKyAgICAgKiB0byB0aGUgTUlNRSB0eXBlIG9mIHRoaXMgRGF0YUZsYXZvci4gPHA+CisgICAgICoKKyAgICAgKiBBY3RpdmF0aW9uRGF0YUZsYXZvciBkZWxlZ2F0ZXMgdGhlIGNvbXBhcmlzb24gb2YgTUlNRSB0eXBlcyB0bworICAgICAqIHRoZSBNaW1lVHlwZSBjbGFzcyBpbmNsdWRlZCBhcyBwYXJ0IG9mIHRoZSBKYXZhQmVhbnMgQWN0aXZhdGlvbgorICAgICAqIEZyYW1ld29yay4gVGhpcyBwcm92aWRlcyBhIG1vcmUgcm9idXN0IGNvbXBhcmlzb24gdGhhbiBpcyBub3JtYWxseQorICAgICAqIGF2YWlsYWJsZSBpbiB0aGUgRGF0YUZsYXZvciBjbGFzcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtaW1lVHlwZQl0aGUgTUlNRSB0eXBlCisgICAgICogQHJldHVybgkJdHJ1ZSBpZiB0aGUgc2FtZSBNSU1FIHR5cGUKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc01pbWVUeXBlRXF1YWwoU3RyaW5nIG1pbWVUeXBlKSB7CisJTWltZVR5cGUgbXQgPSBudWxsOworCXRyeSB7CisJICAgIGlmIChtaW1lT2JqZWN0ID09IG51bGwpCisJCW1pbWVPYmplY3QgPSBuZXcgTWltZVR5cGUodGhpcy5taW1lVHlwZSk7CisJICAgIG10ID0gbmV3IE1pbWVUeXBlKG1pbWVUeXBlKTsKKwl9IGNhdGNoIChNaW1lVHlwZVBhcnNlRXhjZXB0aW9uIGUpIHsKKwkgICAgLy8gc29tZXRoaW5nIGRpZG4ndCBwYXJzZSwgZG8gYSBjcnVkZSBjb21wYXJpc29uCisJICAgIHJldHVybiB0aGlzLm1pbWVUeXBlLmVxdWFsc0lnbm9yZUNhc2UobWltZVR5cGUpOworCX0KKworCXJldHVybiBtaW1lT2JqZWN0Lm1hdGNoKG10KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDYWxsZWQgb24gRGF0YUZsYXZvciBmb3IgZXZlcnkgTUlNRSBUeXBlIHBhcmFtZXRlciB0byBhbGxvdyBEYXRhRmxhdm9yCisgICAgICogc3ViY2xhc3NlcyB0byBoYW5kbGUgc3BlY2lhbCBwYXJhbWV0ZXJzIGxpa2UgdGhlIHRleHQvcGxhaW4gY2hhcnNldAorICAgICAqIHBhcmFtZXRlcnMsIHdob3NlIHZhbHVlcyBhcmUgY2FzZSBpbnNlbnNpdGl2ZS4gIChNSU1FIHR5cGUgcGFyYW1ldGVyCisgICAgICogdmFsdWVzIGFyZSBzdXBwb3NlZCB0byBiZSBjYXNlIHNlbnNpdGl2ZSkuCisgICAgICogPHA+CisgICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGZvciBlYWNoIHBhcmFtZXRlciBuYW1lL3ZhbHVlIHBhaXIgYW5kIHNob3VsZAorICAgICAqIHJldHVybiB0aGUgbm9ybWFsaXplZCByZXByZXNlbnRhdGlvbiBvZiB0aGUgcGFyYW1ldGVyVmFsdWUuCisgICAgICogVGhpcyBtZXRob2QgaXMgbmV2ZXIgaW52b2tlZCBieSB0aGlzIGltcGxlbWVudGF0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlck5hbWUJdGhlIHBhcmFtZXRlciBuYW1lCisgICAgICogQHBhcmFtIHBhcmFtZXRlclZhbHVlCXRoZSBwYXJhbWV0ZXIgdmFsdWUKKyAgICAgKiBAcmV0dXJuCQkJdGhlIG5vcm1hbGl6ZWQgcGFyYW1ldGVyIHZhbHVlCisgICAgICogQGRlcHJlY2F0ZWQKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU3RyaW5nIG5vcm1hbGl6ZU1pbWVUeXBlUGFyYW1ldGVyKFN0cmluZyBwYXJhbWV0ZXJOYW1lLAorCQkJCQkJU3RyaW5nIHBhcmFtZXRlclZhbHVlKSB7CisJcmV0dXJuIHBhcmFtZXRlclZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENhbGxlZCBmb3IgZWFjaCBNSU1FIHR5cGUgc3RyaW5nIHRvIGdpdmUgRGF0YUZsYXZvciBzdWJ0eXBlcyB0aGUKKyAgICAgKiBvcHBvcnR1bml0eSB0byBjaGFuZ2UgaG93IHRoZSBub3JtYWxpemF0aW9uIG9mIE1JTUUgdHlwZXMgaXMKKyAgICAgKiBhY2NvbXBsaXNoZWQuCisgICAgICogT25lIHBvc3NpYmxlIHVzZSB3b3VsZCBiZSB0byBhZGQgZGVmYXVsdCBwYXJhbWV0ZXIvdmFsdWUgcGFpcnMgaW4gY2FzZXMKKyAgICAgKiB3aGVyZSBub25lIGFyZSBwcmVzZW50IGluIHRoZSBNSU1FIHR5cGUgc3RyaW5nIHBhc3NlZCBpbi4KKyAgICAgKiBUaGlzIG1ldGhvZCBpcyBuZXZlciBpbnZva2VkIGJ5IHRoaXMgaW1wbGVtZW50YXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWltZVR5cGUJdGhlIE1JTUUgdHlwZQorICAgICAqIEByZXR1cm4JCXRoZSBub3JtYWxpemVkIE1JTUUgdHlwZQorICAgICAqIEBkZXByZWNhdGVkCisgICAgICovCisgICAgcHJvdGVjdGVkIFN0cmluZyBub3JtYWxpemVNaW1lVHlwZShTdHJpbmcgbWltZVR5cGUpIHsKKwlyZXR1cm4gbWltZVR5cGU7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYW5kcm9pZC9hY3RpdmF0aW9uL3NyYy9tYWluL2phdmEvamF2YXgvYWN0aXZhdGlvbi9Db21tYW5kSW5mby5qYXZhIGIvYW5kcm9pZC9hY3RpdmF0aW9uL3NyYy9tYWluL2phdmEvamF2YXgvYWN0aXZhdGlvbi9Db21tYW5kSW5mby5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc5MmM1ODIKLS0tIC9kZXYvbnVsbAorKysgYi9hbmRyb2lkL2FjdGl2YXRpb24vc3JjL21haW4vamF2YS9qYXZheC9hY3RpdmF0aW9uL0NvbW1hbmRJbmZvLmphdmEKQEAgLTAsMCArMSwyMTUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorICovCisKK3BhY2thZ2UgamF2YXguYWN0aXZhdGlvbjsKKworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5JbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkFjY2Vzc0NvbnRyb2xsZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2aWxlZ2VkQWN0aW9uOworCisvKioKKyAqIFRoZSBDb21tYW5kSW5mbyBjbGFzcyBpcyB1c2VkIGJ5IENvbW1hbmRNYXAgaW1wbGVtZW50YXRpb25zIHRvCisgKiBkZXNjcmliZSB0aGUgcmVzdWx0cyBvZiBjb21tYW5kIHJlcXVlc3RzLiBJdCBwcm92aWRlcyB0aGUgcmVxdWVzdG9yCisgKiB3aXRoIGJvdGggdGhlIHZlcmIgcmVxdWVzdGVkLCBhcyB3ZWxsIGFzIGFuIGluc3RhbmNlIG9mIHRoZQorICogYmVhbi4gVGhlcmUgaXMgYWxzbyBhIG1ldGhvZCB0aGF0IHdpbGwgcmV0dXJuIHRoZSBuYW1lIG9mIHRoZQorICogY2xhc3MgdGhhdCBpbXBsZW1lbnRzIHRoZSBjb21tYW5kIGJ1dCA8aT5pdCBpcyBub3QgZ3VhcmFudGVlZCB0bworICogcmV0dXJuIGEgdmFsaWQgdmFsdWU8L2k+LiBUaGUgcmVhc29uIGZvciB0aGlzIGlzIHRvIGFsbG93IENvbW1hbmRNYXAKKyAqIGltcGxtZW50YXRpb25zIHRoYXQgc3ViY2xhc3MgQ29tbWFuZEluZm8gdG8gcHJvdmlkZSBzcGVjaWFsCisgKiBiZWhhdmlvci4gRm9yIGV4YW1wbGUgYSBDb21tYW5kTWFwIGNvdWxkIGR5bmFtaWNhbGx5IGdlbmVyYXRlCisgKiBKYXZhQmVhbnMuIEluIHRoaXMgY2FzZSwgaXQgbWlnaHQgbm90IGJlIHBvc3NpYmxlIHRvIGNyZWF0ZSBhbgorICogb2JqZWN0IHdpdGggYWxsIHRoZSBjb3JyZWN0IHN0YXRlIGluZm9ybWF0aW9uIHNvbGVseSBmcm9tIHRoZSBjbGFzcworICogbmFtZS4KKyAqLworCitwdWJsaWMgY2xhc3MgQ29tbWFuZEluZm8geworICAgIHByaXZhdGUgU3RyaW5nIHZlcmI7CisgICAgcHJpdmF0ZSBTdHJpbmcgY2xhc3NOYW1lOworCisgICAgLyoqCisgICAgICogVGhlIENvbnN0cnVjdG9yIGZvciBDb21tYW5kSW5mby4KKyAgICAgKiBAcGFyYW0gdmVyYiBUaGUgY29tbWFuZCB2ZXJiIHRoaXMgQ29tbWFuZEluZm8gZGVjcmliZXMuCisgICAgICogQHBhcmFtIGNsYXNzTmFtZSBUaGUgY29tbWFuZCdzIGZ1bGx5IHF1YWxpZmllZCBjbGFzcyBuYW1lLgorICAgICAqLworICAgIHB1YmxpYyBDb21tYW5kSW5mbyhTdHJpbmcgdmVyYiwgU3RyaW5nIGNsYXNzTmFtZSkgeworCXRoaXMudmVyYiA9IHZlcmI7CisJdGhpcy5jbGFzc05hbWUgPSBjbGFzc05hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBjb21tYW5kIHZlcmIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjb21tYW5kIHZlcmIuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRDb21tYW5kTmFtZSgpIHsKKwlyZXR1cm4gdmVyYjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIGNvbW1hbmQncyBjbGFzcyBuYW1lLiA8aT5UaGlzIG1ldGhvZCBNQVkgcmV0dXJuIG51bGwgaW4KKyAgICAgKiBjYXNlcyB3aGVyZSBhIENvbW1hbmRNYXAgc3ViY2xhc3NlZCBDb21tYW5kSW5mbyBmb3IgaXRzCisgICAgICogb3duIHB1cnBvc2VzLjwvaT4gSW4gb3RoZXIgd29yZHMsIGl0IG1pZ2h0IG5vdCBiZSBwb3NzaWJsZSB0bworICAgICAqIGNyZWF0ZSB0aGUgY29ycmVjdCBzdGF0ZSBpbiB0aGUgY29tbWFuZCBieSBtZXJlbHkga25vd2luZworICAgICAqIGl0cyBjbGFzcyBuYW1lLiA8Yj5ETyBOT1QgREVQRU5EIE9OIFRISVMgTUVUSE9EIFJFVFVSTklORworICAgICAqIEEgVkFMSUQgVkFMVUUhPC9iPgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgY2xhc3MgbmFtZSBvZiB0aGUgY29tbWFuZCwgb3IgPGk+bnVsbDwvaT4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldENvbW1hbmRDbGFzcygpIHsKKwlyZXR1cm4gY2xhc3NOYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgaW5zdGFudGlhdGVkIEphdmFCZWFuIGNvbXBvbmVudC4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGUgY3VycmVudCBydW50aW1lIGVudmlyb25tZW50IHN1cHBvcnRzCisgICAgICoge0BsaW5rIGphdmEuYmVhbnMuQmVhbnMjaW5zdGFudGlhdGUgQmVhbnMuaW5zdGFudGlhdGV9LAorICAgICAqIHVzZSBpdCB0byBpbnN0YW50aWF0ZSB0aGUgSmF2YUJlYW5zIGNvbXBvbmVudC4gIE90aGVyd2lzZSwgdXNlCisgICAgICoge0BsaW5rIGphdmEubGFuZy5DbGFzcyNmb3JOYW1lIENsYXNzLmZvck5hbWV9LgorICAgICAqIDxwPgorICAgICAqIFRoZSBjb21wb25lbnQgY2xhc3MgbmVlZHMgdG8gYmUgcHVibGljLgorICAgICAqIE9uIEphdmEgU0UgOSBhbmQgbmV3ZXIsIGlmIHRoZSBjb21wb25lbnQgY2xhc3MgaXMgaW4gYSBuYW1lZCBtb2R1bGUsCisgICAgICogaXQgbmVlZHMgdG8gYmUgaW4gYW4gZXhwb3J0ZWQgcGFja2FnZS4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGUgYmVhbiBpbXBsZW1lbnRzIHRoZSA8Y29kZT5qYXZheC5hY3RpdmF0aW9uLkNvbW1hbmRPYmplY3Q8L2NvZGU+CisgICAgICogaW50ZXJmYWNlLCBjYWxsIGl0cyA8Y29kZT5zZXRDb21tYW5kQ29udGV4dDwvY29kZT4gbWV0aG9kLgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSBEYXRhSGFuZGxlciBwYXJhbWV0ZXIgaXMgbnVsbCwgdGhlbiB0aGUgYmVhbiBpcworICAgICAqIGluc3RhbnRpYXRlZCB3aXRoIG5vIGRhdGEuIE5PVEU6IHRoaXMgbWF5IGJlIHVzZWZ1bAorICAgICAqIGlmIGZvciBzb21lIHJlYXNvbiB0aGUgRGF0YUhhbmRsZXIgdGhhdCBpcyBwYXNzZWQgaW4KKyAgICAgKiB0aHJvd3MgSU9FeGNlcHRpb25zIHdoZW4gdGhpcyBtZXRob2QgYXR0ZW1wdHMgdG8KKyAgICAgKiBhY2Nlc3MgaXRzIElucHV0U3RyZWFtLiBJdCB3aWxsIGFsbG93IHRoZSBjYWxsZXIgdG8KKyAgICAgKiByZXRyaWV2ZSBhIHJlZmVyZW5jZSB0byB0aGUgYmVhbiBpZiBpdCBjYW4gYmUKKyAgICAgKiBpbnN0YW50aWF0ZWQuCisgICAgICogPHA+CisgICAgICogSWYgdGhlIGJlYW4gZG9lcyBOT1QgaW1wbGVtZW50IHRoZSBDb21tYW5kT2JqZWN0IGludGVyZmFjZSwKKyAgICAgKiB0aGlzIG1ldGhvZCB3aWxsIGNoZWNrIGlmIGl0IGltcGxlbWVudHMgdGhlCisgICAgICogamF2YS5pby5FeHRlcm5hbGl6YWJsZSBpbnRlcmZhY2UuIElmIGl0IGRvZXMsIHRoZSBiZWFuJ3MKKyAgICAgKiByZWFkRXh0ZXJuYWwgbWV0aG9kIHdpbGwgYmUgY2FsbGVkIGlmIGFuIElucHV0U3RyZWFtCisgICAgICogY2FuIGJlIGFjcXVpcmVkIGZyb20gdGhlIERhdGFIYW5kbGVyLjxwPgorICAgICAqCisgICAgICogQHBhcmFtIGRoCVRoZSBEYXRhSGFuZGxlciB0aGF0IGRlc2NyaWJlcyB0aGUgZGF0YSB0byBiZQorICAgICAqCQkJcGFzc2VkIHRvIHRoZSBjb21tYW5kLgorICAgICAqIEBwYXJhbSBsb2FkZXIJVGhlIENsYXNzTG9hZGVyIHRvIGJlIHVzZWQgdG8gaW5zdGFudGlhdGUgdGhlIGJlYW4uCisgICAgICogQHJldHVybiBUaGUgYmVhbgorICAgICAqIEBleGNlcHRpb24JSU9FeGNlcHRpb24JZm9yIGZhaWx1cmVzIHJlYWRpbmcgZGF0YQorICAgICAqIEBleGNlcHRpb24JQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbglpZiBjb21tYW5kIG9iamVjdCBjbGFzcyBjYW4ndAorICAgICAqCQkJCQkJYmUgZm91bmQKKyAgICAgKiBAc2VlIGphdmEuYmVhbnMuQmVhbnMjaW5zdGFudGlhdGUKKyAgICAgKiBAc2VlIGphdmF4LmFjdGl2YXRpb24uQ29tbWFuZE9iamVjdAorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZ2V0Q29tbWFuZE9iamVjdChEYXRhSGFuZGxlciBkaCwgQ2xhc3NMb2FkZXIgbG9hZGVyKQorCQkJdGhyb3dzIElPRXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKwlPYmplY3QgbmV3X2JlYW4gPSBudWxsOworCisJLy8gdHJ5IHRvIGluc3RhbnRpYXRlIHRoZSBiZWFuCisJbmV3X2JlYW4gPSBCZWFucy5pbnN0YW50aWF0ZShsb2FkZXIsIGNsYXNzTmFtZSk7CisKKwkvLyBpZiB3ZSBnb3Qgb25lIGFuZCBpdCBpcyBhIENvbW1hbmRPYmplY3QKKwlpZiAobmV3X2JlYW4gIT0gbnVsbCkgeworCSAgICBpZiAobmV3X2JlYW4gaW5zdGFuY2VvZiBDb21tYW5kT2JqZWN0KSB7CisJCSgoQ29tbWFuZE9iamVjdCluZXdfYmVhbikuc2V0Q29tbWFuZENvbnRleHQodmVyYiwgZGgpOworCSAgICB9IGVsc2UgaWYgKG5ld19iZWFuIGluc3RhbmNlb2YgRXh0ZXJuYWxpemFibGUpIHsKKwkJaWYgKGRoICE9IG51bGwpIHsKKwkJICAgIElucHV0U3RyZWFtIGlzID0gZGguZ2V0SW5wdXRTdHJlYW0oKTsKKwkJICAgIGlmIChpcyAhPSBudWxsKSB7CisJCQkoKEV4dGVybmFsaXphYmxlKW5ld19iZWFuKS5yZWFkRXh0ZXJuYWwoCisJCQkJCSAgICAgICBuZXcgT2JqZWN0SW5wdXRTdHJlYW0oaXMpKTsKKwkJICAgIH0KKwkJfQorCSAgICB9CisJfQorCisJcmV0dXJuIG5ld19iZWFuOworICAgIH0KKworICAgIC8qKgorICAgICAqIEhlbHBlciBjbGFzcyB0byBpbnZva2UgQmVhbnMuaW5zdGFudGlhdGUgcmVmbGVjdGl2ZWx5IG9yIHRoZSBlcXVpdmFsZW50CisgICAgICogd2l0aCBjb3JlIHJlZmxlY3Rpb24gd2hlbiBtb2R1bGUgamF2YS5kZXNrdG9wIGlzIG5vdCByZWFkYWJsZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBCZWFucyB7CisgICAgICAgIHN0YXRpYyBmaW5hbCBNZXRob2QgaW5zdGFudGlhdGVNZXRob2Q7CisKKyAgICAgICAgc3RhdGljIHsKKyAgICAgICAgICAgIE1ldGhvZCBtOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBDbGFzczw/PiBjID0gQ2xhc3MuZm9yTmFtZSgiamF2YS5iZWFucy5CZWFucyIpOworICAgICAgICAgICAgICAgIG0gPSBjLmdldERlY2xhcmVkTWV0aG9kKCJpbnN0YW50aWF0ZSIsIENsYXNzTG9hZGVyLmNsYXNzLCBTdHJpbmcuY2xhc3MpOworICAgICAgICAgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgbSA9IG51bGw7CisgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hNZXRob2RFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIG0gPSBudWxsOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaW5zdGFudGlhdGVNZXRob2QgPSBtOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEVxdWl2YWxlbnQgdG8gaW52b2tpbmcgamF2YS5iZWFucy5CZWFucy5pbnN0YW50aWF0ZShsb2FkZXIsIGNuKQorICAgICAgICAgKi8KKyAgICAgICAgc3RhdGljIE9iamVjdCBpbnN0YW50aWF0ZShDbGFzc0xvYWRlciBsb2FkZXIsIFN0cmluZyBjbikKKyAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworCisgICAgICAgICAgICBFeGNlcHRpb24gZXhjZXB0aW9uOworCisgICAgICAgICAgICBpZiAoaW5zdGFudGlhdGVNZXRob2QgIT0gbnVsbCkgeworCisgICAgICAgICAgICAgICAgLy8gaW52b2tlIEJlYW5zLmluc3RhbnRpYXRlCisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGluc3RhbnRpYXRlTWV0aG9kLmludm9rZShudWxsLCBsb2FkZXIsIGNuKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgZXhjZXB0aW9uID0gZTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgZXhjZXB0aW9uID0gZTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIH0gZWxzZSB7CisKKwkJU2VjdXJpdHlNYW5hZ2VyIHNlY3VyaXR5ID0gU3lzdGVtLmdldFNlY3VyaXR5TWFuYWdlcigpOworCQlpZiAoc2VjdXJpdHkgIT0gbnVsbCkgeworCQkgICAgLy8gaWYgaXQncyBvayB3aXRoIHRoZSBTZWN1cml0eU1hbmFnZXIsIGl0J3Mgb2sgd2l0aCBtZS4KKwkJICAgIFN0cmluZyBjbmFtZSA9IGNuLnJlcGxhY2UoJy8nLCAnLicpOworCQkgICAgaWYgKGNuYW1lLnN0YXJ0c1dpdGgoIlsiKSkgeworCQkJaW50IGIgPSBjbmFtZS5sYXN0SW5kZXhPZignWycpICsgMjsKKwkJCWlmIChiID4gMSAmJiBiIDwgY25hbWUubGVuZ3RoKCkpIHsKKwkJCSAgICBjbmFtZSA9IGNuYW1lLnN1YnN0cmluZyhiKTsKKwkJCX0KKwkJICAgIH0KKwkJICAgIGludCBpID0gY25hbWUubGFzdEluZGV4T2YoJy4nKTsKKwkJICAgIGlmIChpICE9IC0xKSB7CisJCQlzZWN1cml0eS5jaGVja1BhY2thZ2VBY2Nlc3MoY25hbWUuc3Vic3RyaW5nKDAsIGkpKTsKKwkJICAgIH0KKwkJfQorCisgICAgICAgICAgICAgICAgLy8gQmVhbnMuaW5zdGFudGlhdGUgc3BlY2lmaWVkIHRvIHVzZSBTQ0wgd2hlbiBsb2FkZXIgaXMgbnVsbAorICAgICAgICAgICAgICAgIGlmIChsb2FkZXIgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBsb2FkZXIgPSAoQ2xhc3NMb2FkZXIpCisJCSAgICAgICAgQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7CisJCQkgICAgcHVibGljIE9iamVjdCBydW4oKSB7CisJCQkJQ2xhc3NMb2FkZXIgY2wgPSBudWxsOworCQkJCXRyeSB7CisJCQkJICAgIGNsID0gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKTsKKwkJCQl9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBleCkgeyB9CisJCQkJcmV0dXJuIGNsOworCQkJICAgIH0KKwkJCX0pOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBDbGFzczw/PiBiZWFuQ2xhc3MgPSBDbGFzcy5mb3JOYW1lKGNuLCB0cnVlLCBsb2FkZXIpOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBiZWFuQ2xhc3MubmV3SW5zdGFuY2UoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsYXNzTm90Rm91bmRFeGNlcHRpb24oYmVhbkNsYXNzICsgIjogIiArIGV4LCBleCk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2FuZHJvaWQvYWN0aXZhdGlvbi9zcmMvbWFpbi9qYXZhL2phdmF4L2FjdGl2YXRpb24vQ29tbWFuZE1hcC5qYXZhIGIvYW5kcm9pZC9hY3RpdmF0aW9uL3NyYy9tYWluL2phdmEvamF2YXgvYWN0aXZhdGlvbi9Db21tYW5kTWFwLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjlmNDkxMAotLS0gL2Rldi9udWxsCisrKyBiL2FuZHJvaWQvYWN0aXZhdGlvbi9zcmMvbWFpbi9qYXZhL2phdmF4L2FjdGl2YXRpb24vQ29tbWFuZE1hcC5qYXZhCkBAIC0wLDAgKzEsMjE5IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBEaXN0cmlidXRpb24gTGljZW5zZSB2LiAxLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9vcmcvZG9jdW1lbnRzL2VkbC12MTAucGhwLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBCU0QtMy1DbGF1c2UKKyAqLworCitwYWNrYWdlIGphdmF4LmFjdGl2YXRpb247CisKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5XZWFrSGFzaE1hcDsKKworCisvKioKKyAqIFRoZSBDb21tYW5kTWFwIGNsYXNzIHByb3ZpZGVzIGFuIGludGVyZmFjZSB0byBhIHJlZ2lzdHJ5IG9mCisgKiBjb21tYW5kIG9iamVjdHMgYXZhaWxhYmxlIGluIHRoZSBzeXN0ZW0uCisgKiBEZXZlbG9wZXJzIGFyZSBleHBlY3RlZCB0byBlaXRoZXIgdXNlIHRoZSBDb21tYW5kTWFwCisgKiBpbXBsZW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoaXMgcGFja2FnZSAoTWFpbGNhcENvbW1hbmRNYXApIG9yCisgKiBkZXZlbG9wIHRoZWlyIG93bi4gTm90ZSB0aGF0IHNvbWUgb2YgdGhlIG1ldGhvZHMgaW4gdGhpcyBjbGFzcyBhcmUKKyAqIGFic3RyYWN0LgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQ29tbWFuZE1hcCB7CisgICAgcHJpdmF0ZSBzdGF0aWMgQ29tbWFuZE1hcCBkZWZhdWx0Q29tbWFuZE1hcCA9IG51bGw7CisgICAgcHJpdmF0ZSBzdGF0aWMgTWFwPENsYXNzTG9hZGVyLENvbW1hbmRNYXA+IG1hcCA9CisJCQkJbmV3IFdlYWtIYXNoTWFwPENsYXNzTG9hZGVyLENvbW1hbmRNYXA+KCk7CisKKworICAgIC8qKgorICAgICAqIEdldCB0aGUgZGVmYXVsdCBDb21tYW5kTWFwLgorICAgICAqCisgICAgICogPHVsPgorICAgICAqIDxsaT4gSW4gY2FzZXMgd2hlcmUgYSBDb21tYW5kTWFwIGluc3RhbmNlIGhhcyBiZWVuIHByZXZpb3VzbHkgc2V0CisgICAgICogICAgICB0byBzb21lIHZhbHVlICh2aWEgPGk+c2V0RGVmYXVsdENvbW1hbmRNYXA8L2k+KQorICAgICAqICByZXR1cm4gdGhlIENvbW1hbmRNYXAuCisgICAgICogPGxpPgorICAgICAqICBJbiBjYXNlcyB3aGVyZSBubyBDb21tYW5kTWFwIGhhcyBiZWVuIHNldCwgdGhlIENvbW1hbmRNYXAKKyAgICAgKiAgICAgICBjcmVhdGVzIGFuIGluc3RhbmNlIG9mIDxjb2RlPk1haWxjYXBDb21tYW5kTWFwPC9jb2RlPiBhbmQKKyAgICAgKiAgICAgICBzZXQgdGhhdCB0byB0aGUgZGVmYXVsdCwgcmV0dXJuaW5nIGl0cyB2YWx1ZS4KKyAgICAgKgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBDb21tYW5kTWFwCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBzeW5jaHJvbml6ZWQgQ29tbWFuZE1hcCBnZXREZWZhdWx0Q29tbWFuZE1hcCgpIHsKKwlpZiAoZGVmYXVsdENvbW1hbmRNYXAgIT0gbnVsbCkKKwkgICAgcmV0dXJuIGRlZmF1bHRDb21tYW5kTWFwOworCisJLy8gZmV0Y2ggcGVyLXRocmVhZC1jb250ZXh0LWNsYXNzLWxvYWRlciBkZWZhdWx0CisJQ2xhc3NMb2FkZXIgdGNjbCA9IFNlY3VyaXR5U3VwcG9ydC5nZXRDb250ZXh0Q2xhc3NMb2FkZXIoKTsKKwlDb21tYW5kTWFwIGRlZiA9IG1hcC5nZXQodGNjbCk7CisJaWYgKGRlZiA9PSBudWxsKSB7CisJICAgIGRlZiA9IG5ldyBNYWlsY2FwQ29tbWFuZE1hcCgpOworCSAgICBtYXAucHV0KHRjY2wsIGRlZik7CisJfQorCXJldHVybiBkZWY7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBkZWZhdWx0IENvbW1hbmRNYXAuIFJlc2V0IHRoZSBDb21tYW5kTWFwIHRvIHRoZSBkZWZhdWx0IGJ5CisgICAgICogY2FsbGluZyB0aGlzIG1ldGhvZCB3aXRoIDxjb2RlPm51bGw8L2NvZGU+LgorICAgICAqCisgICAgICogQHBhcmFtIGNvbW1hbmRNYXAgVGhlIG5ldyBkZWZhdWx0IENvbW1hbmRNYXAuCisgICAgICogQGV4Y2VwdGlvbiBTZWN1cml0eUV4Y2VwdGlvbiBpZiB0aGUgY2FsbGVyIGRvZXNuJ3QgaGF2ZSBwZXJtaXNzaW9uCisgICAgICoJCQkJCXRvIGNoYW5nZSB0aGUgZGVmYXVsdAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgc3luY2hyb25pemVkIHZvaWQgc2V0RGVmYXVsdENvbW1hbmRNYXAoQ29tbWFuZE1hcCBjb21tYW5kTWFwKSB7CisJU2VjdXJpdHlNYW5hZ2VyIHNlY3VyaXR5ID0gU3lzdGVtLmdldFNlY3VyaXR5TWFuYWdlcigpOworCWlmIChzZWN1cml0eSAhPSBudWxsKSB7CisJICAgIHRyeSB7CisJCS8vIGlmIGl0J3Mgb2sgd2l0aCB0aGUgU2VjdXJpdHlNYW5hZ2VyLCBpdCdzIG9rIHdpdGggbWUuLi4KKwkJc2VjdXJpdHkuY2hlY2tTZXRGYWN0b3J5KCk7CisJICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGV4KSB7CisJCS8vIG90aGVyd2lzZSwgd2UgYWxzbyBhbGxvdyBpdCBpZiB0aGlzIGNvZGUgYW5kIHRoZQorCQkvLyBmYWN0b3J5IGNvbWUgZnJvbSB0aGUgc2FtZSAobm9uLXN5c3RlbSkgY2xhc3MgbG9hZGVyIChlLmcuLAorCQkvLyB0aGUgSkFGIGNsYXNzZXMgd2VyZSBsb2FkZWQgd2l0aCB0aGUgYXBwbGV0IGNsYXNzZXMpLgorCQlDbGFzc0xvYWRlciBjbCA9IENvbW1hbmRNYXAuY2xhc3MuZ2V0Q2xhc3NMb2FkZXIoKTsKKwkJaWYgKGNsID09IG51bGwgfHwgY2wuZ2V0UGFyZW50KCkgPT0gbnVsbCB8fAorCQkgICAgY2wgIT0gY29tbWFuZE1hcC5nZXRDbGFzcygpLmdldENsYXNzTG9hZGVyKCkpIHsKKwkJICAgIHRocm93IGV4OworCQl9CisJICAgIH0KKwl9CisJLy8gcmVtb3ZlIGFueSBwZXItdGhyZWFkLWNvbnRleHQtY2xhc3MtbG9hZGVyIENvbW1hbmRNYXAKKwltYXAucmVtb3ZlKFNlY3VyaXR5U3VwcG9ydC5nZXRDb250ZXh0Q2xhc3NMb2FkZXIoKSk7CisJZGVmYXVsdENvbW1hbmRNYXAgPSBjb21tYW5kTWFwOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgcHJlZmVycmVkIGNvbW1hbmQgbGlzdCBmcm9tIGEgTUlNRSBUeXBlLiBUaGUgYWN0dWFsIHNlbWFudGljcworICAgICAqIGFyZSBkZXRlcm1pbmVkIGJ5IHRoZSBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgQ29tbWFuZE1hcC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtaW1lVHlwZQl0aGUgTUlNRSB0eXBlCisgICAgICogQHJldHVybiB0aGUgQ29tbWFuZEluZm8gY2xhc3NlcyB0aGF0IHJlcHJlc2VudCB0aGUgY29tbWFuZCBCZWFucy4KKyAgICAgKi8KKyAgICBhYnN0cmFjdCBwdWJsaWMgIENvbW1hbmRJbmZvW10gZ2V0UHJlZmVycmVkQ29tbWFuZHMoU3RyaW5nIG1pbWVUeXBlKTsKKworICAgIC8qKgorICAgICAqIEdldCB0aGUgcHJlZmVycmVkIGNvbW1hbmQgbGlzdCBmcm9tIGEgTUlNRSBUeXBlLiBUaGUgYWN0dWFsIHNlbWFudGljcworICAgICAqIGFyZSBkZXRlcm1pbmVkIGJ5IHRoZSBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgQ29tbWFuZE1hcC4gPHA+CisgICAgICoKKyAgICAgKiBUaGUgPGNvZGU+RGF0YVNvdXJjZTwvY29kZT4gcHJvdmlkZXMgZXh0cmEgaW5mb3JtYXRpb24sIHN1Y2ggYXMKKyAgICAgKiB0aGUgZmlsZSBuYW1lLCB0aGF0IGEgQ29tbWFuZE1hcCBpbXBsZW1lbnRhdGlvbiBtYXkgdXNlIHRvIGZ1cnRoZXIKKyAgICAgKiByZWZpbmUgdGhlIGxpc3Qgb2YgY29tbWFuZHMgdGhhdCBhcmUgcmV0dXJuZWQuICBUaGUgaW1wbGVtZW50YXRpb24KKyAgICAgKiBpbiB0aGlzIGNsYXNzIHNpbXBseSBjYWxscyB0aGUgPGNvZGU+Z2V0UHJlZmVycmVkQ29tbWFuZHM8L2NvZGU+CisgICAgICogbWV0aG9kIHRoYXQgaWdub3JlcyB0aGlzIGFyZ3VtZW50LgorICAgICAqCisgICAgICogQHBhcmFtIG1pbWVUeXBlCXRoZSBNSU1FIHR5cGUKKyAgICAgKiBAcGFyYW0gZHMJYSBEYXRhU291cmNlIGZvciB0aGUgZGF0YQorICAgICAqIEByZXR1cm4gdGhlIENvbW1hbmRJbmZvIGNsYXNzZXMgdGhhdCByZXByZXNlbnQgdGhlIGNvbW1hbmQgQmVhbnMuCisgICAgICogQHNpbmNlCUpBRiAxLjEKKyAgICAgKi8KKyAgICBwdWJsaWMgQ29tbWFuZEluZm9bXSBnZXRQcmVmZXJyZWRDb21tYW5kcyhTdHJpbmcgbWltZVR5cGUsIERhdGFTb3VyY2UgZHMpIHsKKwlyZXR1cm4gZ2V0UHJlZmVycmVkQ29tbWFuZHMobWltZVR5cGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCBhbGwgdGhlIGF2YWlsYWJsZSBjb21tYW5kcyBmb3IgdGhpcyB0eXBlLiBUaGlzIG1ldGhvZAorICAgICAqIHNob3VsZCByZXR1cm4gYWxsIHRoZSBwb3NzaWJsZSBjb21tYW5kcyBmb3IgdGhpcyBNSU1FIHR5cGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWltZVR5cGUJdGhlIE1JTUUgdHlwZQorICAgICAqIEByZXR1cm4gdGhlIENvbW1hbmRJbmZvIG9iamVjdHMgcmVwcmVzZW50aW5nIGFsbCB0aGUgY29tbWFuZHMuCisgICAgICovCisgICAgYWJzdHJhY3QgcHVibGljIENvbW1hbmRJbmZvW10gZ2V0QWxsQ29tbWFuZHMoU3RyaW5nIG1pbWVUeXBlKTsKKworICAgIC8qKgorICAgICAqIEdldCBhbGwgdGhlIGF2YWlsYWJsZSBjb21tYW5kcyBmb3IgdGhpcyB0eXBlLiBUaGlzIG1ldGhvZAorICAgICAqIHNob3VsZCByZXR1cm4gYWxsIHRoZSBwb3NzaWJsZSBjb21tYW5kcyBmb3IgdGhpcyBNSU1FIHR5cGUuIDxwPgorICAgICAqCisgICAgICogVGhlIDxjb2RlPkRhdGFTb3VyY2U8L2NvZGU+IHByb3ZpZGVzIGV4dHJhIGluZm9ybWF0aW9uLCBzdWNoIGFzCisgICAgICogdGhlIGZpbGUgbmFtZSwgdGhhdCBhIENvbW1hbmRNYXAgaW1wbGVtZW50YXRpb24gbWF5IHVzZSB0byBmdXJ0aGVyCisgICAgICogcmVmaW5lIHRoZSBsaXN0IG9mIGNvbW1hbmRzIHRoYXQgYXJlIHJldHVybmVkLiAgVGhlIGltcGxlbWVudGF0aW9uCisgICAgICogaW4gdGhpcyBjbGFzcyBzaW1wbHkgY2FsbHMgdGhlIDxjb2RlPmdldEFsbENvbW1hbmRzPC9jb2RlPgorICAgICAqIG1ldGhvZCB0aGF0IGlnbm9yZXMgdGhpcyBhcmd1bWVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtaW1lVHlwZQl0aGUgTUlNRSB0eXBlCisgICAgICogQHBhcmFtIGRzCWEgRGF0YVNvdXJjZSBmb3IgdGhlIGRhdGEKKyAgICAgKiBAcmV0dXJuIHRoZSBDb21tYW5kSW5mbyBvYmplY3RzIHJlcHJlc2VudGluZyBhbGwgdGhlIGNvbW1hbmRzLgorICAgICAqIEBzaW5jZQlKQUYgMS4xCisgICAgICovCisgICAgcHVibGljIENvbW1hbmRJbmZvW10gZ2V0QWxsQ29tbWFuZHMoU3RyaW5nIG1pbWVUeXBlLCBEYXRhU291cmNlIGRzKSB7CisJcmV0dXJuIGdldEFsbENvbW1hbmRzKG1pbWVUeXBlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGRlZmF1bHQgY29tbWFuZCBjb3JyZXNwb25kaW5nIHRvIHRoZSBNSU1FIHR5cGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWltZVR5cGUJdGhlIE1JTUUgdHlwZQorICAgICAqIEBwYXJhbSBjbWROYW1lCXRoZSBjb21tYW5kIG5hbWUKKyAgICAgKiBAcmV0dXJuIHRoZSBDb21tYW5kSW5mbyBjb3JyZXNwb25kaW5nIHRvIHRoZSBjb21tYW5kLgorICAgICAqLworICAgIGFic3RyYWN0IHB1YmxpYyBDb21tYW5kSW5mbyBnZXRDb21tYW5kKFN0cmluZyBtaW1lVHlwZSwgU3RyaW5nIGNtZE5hbWUpOworCisgICAgLyoqCisgICAgICogR2V0IHRoZSBkZWZhdWx0IGNvbW1hbmQgY29ycmVzcG9uZGluZyB0byB0aGUgTUlNRSB0eXBlLiA8cD4KKyAgICAgKgorICAgICAqIFRoZSA8Y29kZT5EYXRhU291cmNlPC9jb2RlPiBwcm92aWRlcyBleHRyYSBpbmZvcm1hdGlvbiwgc3VjaCBhcworICAgICAqIHRoZSBmaWxlIG5hbWUsIHRoYXQgYSBDb21tYW5kTWFwIGltcGxlbWVudGF0aW9uIG1heSB1c2UgdG8gZnVydGhlcgorICAgICAqIHJlZmluZSB0aGUgY29tbWFuZCB0aGF0IGlzIGNob3Nlbi4gIFRoZSBpbXBsZW1lbnRhdGlvbgorICAgICAqIGluIHRoaXMgY2xhc3Mgc2ltcGx5IGNhbGxzIHRoZSA8Y29kZT5nZXRDb21tYW5kPC9jb2RlPgorICAgICAqIG1ldGhvZCB0aGF0IGlnbm9yZXMgdGhpcyBhcmd1bWVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtaW1lVHlwZQl0aGUgTUlNRSB0eXBlCisgICAgICogQHBhcmFtIGNtZE5hbWUJdGhlIGNvbW1hbmQgbmFtZQorICAgICAqIEBwYXJhbSBkcwlhIERhdGFTb3VyY2UgZm9yIHRoZSBkYXRhCisgICAgICogQHJldHVybiB0aGUgQ29tbWFuZEluZm8gY29ycmVzcG9uZGluZyB0byB0aGUgY29tbWFuZC4KKyAgICAgKiBAc2luY2UJSkFGIDEuMQorICAgICAqLworICAgIHB1YmxpYyBDb21tYW5kSW5mbyBnZXRDb21tYW5kKFN0cmluZyBtaW1lVHlwZSwgU3RyaW5nIGNtZE5hbWUsCisJCQkJRGF0YVNvdXJjZSBkcykgeworCXJldHVybiBnZXRDb21tYW5kKG1pbWVUeXBlLCBjbWROYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb2NhdGUgYSBEYXRhQ29udGVudEhhbmRsZXIgdGhhdCBjb3JyZXNwb25kcyB0byB0aGUgTUlNRSB0eXBlLgorICAgICAqIFRoZSBtZWNoYW5pc20gYW5kIHNlbWFudGljcyBmb3IgZGV0ZXJtaW5pbmcgdGhpcyBhcmUgZGV0ZXJtaW5lZAorICAgICAqIGJ5IHRoZSBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgcGFydGljdWxhciBDb21tYW5kTWFwLgorICAgICAqCisgICAgICogQHBhcmFtIG1pbWVUeXBlCXRoZSBNSU1FIHR5cGUKKyAgICAgKiBAcmV0dXJuCQl0aGUgRGF0YUNvbnRlbnRIYW5kbGVyIGZvciB0aGUgTUlNRSB0eXBlCisgICAgICovCisgICAgYWJzdHJhY3QgcHVibGljIERhdGFDb250ZW50SGFuZGxlciBjcmVhdGVEYXRhQ29udGVudEhhbmRsZXIoU3RyaW5nCisJCQkJCQkJCW1pbWVUeXBlKTsKKworICAgIC8qKgorICAgICAqIExvY2F0ZSBhIERhdGFDb250ZW50SGFuZGxlciB0aGF0IGNvcnJlc3BvbmRzIHRvIHRoZSBNSU1FIHR5cGUuCisgICAgICogVGhlIG1lY2hhbmlzbSBhbmQgc2VtYW50aWNzIGZvciBkZXRlcm1pbmluZyB0aGlzIGFyZSBkZXRlcm1pbmVkCisgICAgICogYnkgdGhlIGltcGxlbWVudGF0aW9uIG9mIHRoZSBwYXJ0aWN1bGFyIENvbW1hbmRNYXAuIDxwPgorICAgICAqCisgICAgICogVGhlIDxjb2RlPkRhdGFTb3VyY2U8L2NvZGU+IHByb3ZpZGVzIGV4dHJhIGluZm9ybWF0aW9uLCBzdWNoIGFzCisgICAgICogdGhlIGZpbGUgbmFtZSwgdGhhdCBhIENvbW1hbmRNYXAgaW1wbGVtZW50YXRpb24gbWF5IHVzZSB0byBmdXJ0aGVyCisgICAgICogcmVmaW5lIHRoZSBjaG9pY2Ugb2YgRGF0YUNvbnRlbnRIYW5kbGVyLiAgVGhlIGltcGxlbWVudGF0aW9uCisgICAgICogaW4gdGhpcyBjbGFzcyBzaW1wbHkgY2FsbHMgdGhlIDxjb2RlPmNyZWF0ZURhdGFDb250ZW50SGFuZGxlcjwvY29kZT4KKyAgICAgKiBtZXRob2QgdGhhdCBpZ25vcmVzIHRoaXMgYXJndW1lbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWltZVR5cGUJdGhlIE1JTUUgdHlwZQorICAgICAqIEBwYXJhbSBkcwlhIERhdGFTb3VyY2UgZm9yIHRoZSBkYXRhCisgICAgICogQHJldHVybgkJdGhlIERhdGFDb250ZW50SGFuZGxlciBmb3IgdGhlIE1JTUUgdHlwZQorICAgICAqIEBzaW5jZQlKQUYgMS4xCisgICAgICovCisgICAgcHVibGljIERhdGFDb250ZW50SGFuZGxlciBjcmVhdGVEYXRhQ29udGVudEhhbmRsZXIoU3RyaW5nIG1pbWVUeXBlLAorCQkJCURhdGFTb3VyY2UgZHMpIHsKKwlyZXR1cm4gY3JlYXRlRGF0YUNvbnRlbnRIYW5kbGVyKG1pbWVUeXBlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgYWxsIHRoZSBNSU1FIHR5cGVzIGtub3duIHRvIHRoaXMgY29tbWFuZCBtYXAuCisgICAgICogSWYgdGhlIGNvbW1hbmQgbWFwIGRvZXNuJ3Qgc3VwcG9ydCB0aGlzIG9wZXJhdGlvbiwKKyAgICAgKiBudWxsIGlzIHJldHVybmVkLgorICAgICAqCisgICAgICogQHJldHVybgkJYXJyYXkgb2YgTUlNRSB0eXBlcyBhcyBzdHJpbmdzLCBvciBudWxsIGlmIG5vdCBzdXBwb3J0ZWQKKyAgICAgKiBAc2luY2UJSkFGIDEuMQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRNaW1lVHlwZXMoKSB7CisJcmV0dXJuIG51bGw7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvYW5kcm9pZC9hY3RpdmF0aW9uL3NyYy9tYWluL2phdmEvamF2YXgvYWN0aXZhdGlvbi9Db21tYW5kT2JqZWN0LmphdmEgYi9hbmRyb2lkL2FjdGl2YXRpb24vc3JjL21haW4vamF2YS9qYXZheC9hY3RpdmF0aW9uL0NvbW1hbmRPYmplY3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NDhjNzMxCi0tLSAvZGV2L251bGwKKysrIGIvYW5kcm9pZC9hY3RpdmF0aW9uL3NyYy9tYWluL2phdmEvamF2YXgvYWN0aXZhdGlvbi9Db21tYW5kT2JqZWN0LmphdmEKQEAgLTAsMCArMSwzOCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgRGlzdHJpYnV0aW9uIExpY2Vuc2Ugdi4gMS4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvb3JnL2RvY3VtZW50cy9lZGwtdjEwLnBocC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQlNELTMtQ2xhdXNlCisgKi8KKworcGFja2FnZSBqYXZheC5hY3RpdmF0aW9uOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworLyoqCisgKiBKYXZhQmVhbnMgY29tcG9uZW50cyB0aGF0IGFyZSBBY3RpdmF0aW9uIEZyYW1ld29yayBhd2FyZSBpbXBsZW1lbnQKKyAqIHRoaXMgaW50ZXJmYWNlIHRvIGZpbmQgb3V0IHdoaWNoIGNvbW1hbmQgdmVyYiB0aGV5J3JlIGJlaW5nIGFza2VkCisgKiB0byBwZXJmb3JtLCBhbmQgdG8gb2J0YWluIHRoZSBEYXRhSGFuZGxlciByZXByZXNlbnRpbmcgdGhlCisgKiBkYXRhIHRoZXkgc2hvdWxkIG9wZXJhdGUgb24uICBKYXZhQmVhbnMgdGhhdCBkb24ndCBpbXBsZW1lbnQKKyAqIHRoaXMgaW50ZXJmYWNlIG1heSBiZSB1c2VkIGFzIHdlbGwuICBTdWNoIGNvbW1hbmRzIG1heSBvYnRhaW4KKyAqIHRoZSBkYXRhIHVzaW5nIHRoZSBFeHRlcm5hbGl6YWJsZSBpbnRlcmZhY2UsIG9yIHVzaW5nIGFuCisgKiBhcHBsaWNhdGlvbi1zcGVjaWZpYyBtZXRob2QuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgQ29tbWFuZE9iamVjdCB7CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplIHRoZSBDb21tYW5kIHdpdGggdGhlIHZlcmIgaXQgaXMgcmVxdWVzdGVkIHRvIGhhbmRsZQorICAgICAqIGFuZCB0aGUgRGF0YUhhbmRsZXIgdGhhdCBkZXNjcmliZXMgdGhlIGRhdGEgaXQgd2lsbAorICAgICAqIG9wZXJhdGUgb24uIDxiPk5PVEU6PC9iPiBpdCBpcyBhY2NlcHRhYmxlIGZvciB0aGUgY2FsbGVyCisgICAgICogdG8gcGFzcyA8aT5udWxsPC9pPiBhcyB0aGUgdmFsdWUgZm9yIDxjb2RlPkRhdGFIYW5kbGVyPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEBwYXJhbSB2ZXJiIFRoZSBDb21tYW5kIFZlcmIgdGhpcyBvYmplY3QgcmVmZXJzIHRvLgorICAgICAqIEBwYXJhbSBkaCBUaGUgRGF0YUhhbmRsZXIuCisgICAgICogQGV4Y2VwdGlvbglJT0V4Y2VwdGlvbglmb3IgZmFpbHVyZXMgYWNjZXNzaW5nIGRhdGEKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDb21tYW5kQ29udGV4dChTdHJpbmcgdmVyYiwgRGF0YUhhbmRsZXIgZGgpCisJCQkJCQl0aHJvd3MgSU9FeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9hbmRyb2lkL2FjdGl2YXRpb24vc3JjL21haW4vamF2YS9qYXZheC9hY3RpdmF0aW9uL0RhdGFDb250ZW50SGFuZGxlci5qYXZhIGIvYW5kcm9pZC9hY3RpdmF0aW9uL3NyYy9tYWluL2phdmEvamF2YXgvYWN0aXZhdGlvbi9EYXRhQ29udGVudEhhbmRsZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hZTc4NjUzCi0tLSAvZGV2L251bGwKKysrIGIvYW5kcm9pZC9hY3RpdmF0aW9uL3NyYy9tYWluL2phdmEvamF2YXgvYWN0aXZhdGlvbi9EYXRhQ29udGVudEhhbmRsZXIuamF2YQpAQCAtMCwwICsxLDgyIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBEaXN0cmlidXRpb24gTGljZW5zZSB2LiAxLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9vcmcvZG9jdW1lbnRzL2VkbC12MTAucGhwLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBCU0QtMy1DbGF1c2UKKyAqLworCitwYWNrYWdlIGphdmF4LmFjdGl2YXRpb247CisKKy8vaW1wb3J0IGphdmEuYXd0LmRhdGF0cmFuc2Zlci5EYXRhRmxhdm9yOworLy9pbXBvcnQgamF2YS5hd3QuZGF0YXRyYW5zZmVyLlVuc3VwcG9ydGVkRmxhdm9yRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZheC5hY3RpdmF0aW9uLkRhdGFTb3VyY2U7CisKKy8qKgorICogVGhlIERhdGFDb250ZW50SGFuZGxlciBpbnRlcmZhY2UgaXMgaW1wbGVtZW50ZWQgYnkgb2JqZWN0cyB0aGF0IGNhbgorICogYmUgdXNlZCB0byBleHRlbmQgdGhlIGNhcGFiaWxpdGllcyBvZiB0aGUgRGF0YUhhbmRsZXIncyBpbXBsZW1lbnRhdGlvbgorICogb2YgdGhlIFRyYW5zZmVyYWJsZSBpbnRlcmZhY2UuIFRocm91Z2ggPGNvZGU+RGF0YUNvbnRlbnRIYW5kbGVyczwvY29kZT4KKyAqIHRoZSBmcmFtZXdvcmsgY2FuIGJlIGV4dGVuZGVkIHRvIGNvbnZlcnQgc3RyZWFtcyBpbiB0byBvYmplY3RzLCBhbmQKKyAqIHRvIHdyaXRlIG9iamVjdHMgdG8gc3RyZWFtcy4gPHA+CisgKgorICogQXBwbGljYXRpb25zIGRvbid0IGdlbmVyYWxseSBjYWxsIHRoZSBtZXRob2RzIGluIERhdGFDb250ZW50SGFuZGxlcnMKKyAqIGRpcmVjdGx5LiBJbnN0ZWFkLCBhbiBhcHBsaWNhdGlvbiBjYWxscyB0aGUgZXF1aXZhbGVudCBtZXRob2RzIGluCisgKiBEYXRhSGFuZGxlci4gVGhlIERhdGFIYW5kbGVyIHdpbGwgYXR0ZW1wdCB0byBmaW5kIGFuIGFwcHJvcHJpYXRlCisgKiBEYXRhQ29udGVudEhhbmRsZXIgdGhhdCBjb3JyZXNwb25kcyB0byBpdHMgTUlNRSB0eXBlIHVzaW5nIHRoZQorICogY3VycmVudCBEYXRhQ29udGVudEhhbmRsZXJGYWN0b3J5LiBUaGUgRGF0YUhhbmRsZXIgdGhlbiBjYWxscworICogdGhyb3VnaCB0byB0aGUgbWV0aG9kcyBpbiB0aGUgRGF0YUNvbnRlbnRIYW5kbGVyLgorICovCisKK3B1YmxpYyBpbnRlcmZhY2UgRGF0YUNvbnRlbnRIYW5kbGVyIHsKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIERhdGFGbGF2b3Igb2JqZWN0cyBpbmRpY2F0aW5nIHRoZSBmbGF2b3JzIHRoZQorICAgICAqIGRhdGEgY2FuIGJlIHByb3ZpZGVkIGluLiBUaGUgYXJyYXkgc2hvdWxkIGJlIG9yZGVyZWQgYWNjb3JkaW5nIHRvCisgICAgICogcHJlZmVyZW5jZSBmb3IgcHJvdmlkaW5nIHRoZSBkYXRhIChmcm9tIG1vc3QgcmljaGx5IGRlc2NyaXB0aXZlIHRvCisgICAgICogbGVhc3QgZGVzY3JpcHRpdmUpLgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgRGF0YUZsYXZvcnMuCisgICAgICovCisgICAgcHVibGljIEFjdGl2YXRpb25EYXRhRmxhdm9yW10gZ2V0VHJhbnNmZXJEYXRhRmxhdm9ycygpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBvYmplY3Qgd2hpY2ggcmVwcmVzZW50cyB0aGUgZGF0YSB0byBiZSB0cmFuc2ZlcnJlZC4KKyAgICAgKiBUaGUgY2xhc3Mgb2YgdGhlIG9iamVjdCByZXR1cm5lZCBpcyBkZWZpbmVkIGJ5IHRoZSByZXByZXNlbnRhdGlvbiBjbGFzcworICAgICAqIG9mIHRoZSBmbGF2b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGYgVGhlIERhdGFGbGF2b3IgcmVwcmVzZW50aW5nIHRoZSByZXF1ZXN0ZWQgdHlwZS4KKyAgICAgKiBAcGFyYW0gZHMgVGhlIERhdGFTb3VyY2UgcmVwcmVzZW50aW5nIHRoZSBkYXRhIHRvIGJlIGNvbnZlcnRlZC4KKyAgICAgKiBAcmV0dXJuIFRoZSBjb25zdHJ1Y3RlZCBPYmplY3QuCisgICAgICogQGV4Y2VwdGlvbiBJT0V4Y2VwdGlvbglpZiB0aGUgZGF0YSBjYW4ndCBiZSBhY2Nlc3NlZAorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZ2V0VHJhbnNmZXJEYXRhKEFjdGl2YXRpb25EYXRhRmxhdm9yIGRmLCBEYXRhU291cmNlIGRzKQorCQkJCXRocm93cyAvKlVuc3VwcG9ydGVkRmxhdm9yRXhjZXB0aW9uLCovIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJuIGFuIG9iamVjdCByZXByZXNlbnRpbmcgdGhlIGRhdGEgaW4gaXRzIG1vc3QgcHJlZmVycmVkIGZvcm0uCisgICAgICogR2VuZXJhbGx5IHRoaXMgd2lsbCBiZSB0aGUgZm9ybSBkZXNjcmliZWQgYnkgdGhlIGZpcnN0IERhdGFGbGF2b3IKKyAgICAgKiByZXR1cm5lZCBieSB0aGUgPGNvZGU+Z2V0VHJhbnNmZXJEYXRhRmxhdm9yczwvY29kZT4gbWV0aG9kLgorICAgICAqCisgICAgICogQHBhcmFtIGRzIFRoZSBEYXRhU291cmNlIHJlcHJlc2VudGluZyB0aGUgZGF0YSB0byBiZSBjb252ZXJ0ZWQuCisgICAgICogQHJldHVybiBUaGUgY29uc3RydWN0ZWQgT2JqZWN0LgorICAgICAqIEBleGNlcHRpb24gSU9FeGNlcHRpb24JaWYgdGhlIGRhdGEgY2FuJ3QgYmUgYWNjZXNzZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IGdldENvbnRlbnQoRGF0YVNvdXJjZSBkcykgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQ29udmVydCB0aGUgb2JqZWN0IHRvIGEgYnl0ZSBzdHJlYW0gb2YgdGhlIHNwZWNpZmllZCBNSU1FIHR5cGUKKyAgICAgKiBhbmQgd3JpdGUgaXQgdG8gdGhlIG91dHB1dCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb2JqCVRoZSBvYmplY3QgdG8gYmUgY29udmVydGVkLgorICAgICAqIEBwYXJhbSBtaW1lVHlwZQlUaGUgcmVxdWVzdGVkIE1JTUUgdHlwZSBvZiB0aGUgcmVzdWx0aW5nIGJ5dGUgc3RyZWFtLgorICAgICAqIEBwYXJhbSBvcwlUaGUgb3V0cHV0IHN0cmVhbSBpbnRvIHdoaWNoIHRvIHdyaXRlIHRoZSBjb252ZXJ0ZWQKKyAgICAgKgkJCWJ5dGUgc3RyZWFtLgorICAgICAqIEBleGNlcHRpb24gSU9FeGNlcHRpb24JZXJyb3JzIHdyaXRpbmcgdG8gdGhlIHN0cmVhbQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oT2JqZWN0IG9iaiwgU3RyaW5nIG1pbWVUeXBlLCBPdXRwdXRTdHJlYW0gb3MpCisJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9hbmRyb2lkL2FjdGl2YXRpb24vc3JjL21haW4vamF2YS9qYXZheC9hY3RpdmF0aW9uL0RhdGFDb250ZW50SGFuZGxlckZhY3RvcnkuamF2YSBiL2FuZHJvaWQvYWN0aXZhdGlvbi9zcmMvbWFpbi9qYXZhL2phdmF4L2FjdGl2YXRpb24vRGF0YUNvbnRlbnRIYW5kbGVyRmFjdG9yeS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBjZDBmNWMKLS0tIC9kZXYvbnVsbAorKysgYi9hbmRyb2lkL2FjdGl2YXRpb24vc3JjL21haW4vamF2YS9qYXZheC9hY3RpdmF0aW9uL0RhdGFDb250ZW50SGFuZGxlckZhY3RvcnkuamF2YQpAQCAtMCwwICsxLDMxIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBEaXN0cmlidXRpb24gTGljZW5zZSB2LiAxLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9vcmcvZG9jdW1lbnRzL2VkbC12MTAucGhwLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBCU0QtMy1DbGF1c2UKKyAqLworCitwYWNrYWdlIGphdmF4LmFjdGl2YXRpb247CisKKy8qKgorICogVGhpcyBpbnRlcmZhY2UgZGVmaW5lcyBhIGZhY3RvcnkgZm9yIDxjb2RlPkRhdGFDb250ZW50SGFuZGxlcnM8L2NvZGU+LiBBbgorICogaW1wbGVtZW50YXRpb24gb2YgdGhpcyBpbnRlcmZhY2Ugc2hvdWxkIG1hcCBhIE1JTUUgdHlwZSBpbnRvIGFuCisgKiBpbnN0YW5jZSBvZiBEYXRhQ29udGVudEhhbmRsZXIuIFRoZSBkZXNpZ24gcGF0dGVybiBmb3IgY2xhc3NlcyBpbXBsZW1lbnRpbmcKKyAqIHRoaXMgaW50ZXJmYWNlIGlzIHRoZSBzYW1lIGFzIGZvciB0aGUgQ29udGVudEhhbmRsZXIgbWVjaGFuaXNtIHVzZWQgaW4KKyAqIDxjb2RlPmphdmEubmV0LlVSTDwvY29kZT4uCisgKi8KKworcHVibGljIGludGVyZmFjZSBEYXRhQ29udGVudEhhbmRsZXJGYWN0b3J5IHsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgRGF0YUNvbnRlbnRIYW5kbGVyIG9iamVjdCBmb3IgdGhlIE1JTUUgdHlwZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtaW1lVHlwZSB0aGUgTUlNRSB0eXBlIHRvIGNyZWF0ZSB0aGUgRGF0YUNvbnRlbnRIYW5kbGVyIGZvci4KKyAgICAgKiBAcmV0dXJuIFRoZSBuZXcgPGNvZGU+RGF0YUNvbnRlbnRIYW5kbGVyPC9jb2RlPiwgb3IgPGk+bnVsbDwvaT4KKyAgICAgKiBpZiBub25lIGFyZSBmb3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGF0YUNvbnRlbnRIYW5kbGVyIGNyZWF0ZURhdGFDb250ZW50SGFuZGxlcihTdHJpbmcgbWltZVR5cGUpOworfQpkaWZmIC0tZ2l0IGEvYW5kcm9pZC9hY3RpdmF0aW9uL3NyYy9tYWluL2phdmEvamF2YXgvYWN0aXZhdGlvbi9EYXRhSGFuZGxlci5qYXZhIGIvYW5kcm9pZC9hY3RpdmF0aW9uL3NyYy9tYWluL2phdmEvamF2YXgvYWN0aXZhdGlvbi9EYXRhSGFuZGxlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQwYTg0MmQKLS0tIC9kZXYvbnVsbAorKysgYi9hbmRyb2lkL2FjdGl2YXRpb24vc3JjL21haW4vamF2YS9qYXZheC9hY3RpdmF0aW9uL0RhdGFIYW5kbGVyLmphdmEKQEAgLTAsMCArMSw4ODEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorICovCisKK3BhY2thZ2UgamF2YXguYWN0aXZhdGlvbjsKKworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlBpcGVkSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5QaXBlZE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbVdyaXRlcjsKK2ltcG9ydCBqYXZhLm5ldC5VUkw7CisvL2ltcG9ydCBqYXZhLmF3dC5kYXRhdHJhbnNmZXIuVHJhbnNmZXJhYmxlOworLy9pbXBvcnQgamF2YS5hd3QuZGF0YXRyYW5zZmVyLkRhdGFGbGF2b3I7CisvL2ltcG9ydCBqYXZhLmF3dC5kYXRhdHJhbnNmZXIuVW5zdXBwb3J0ZWRGbGF2b3JFeGNlcHRpb247CisKKy8qKgorICogVGhlIERhdGFIYW5kbGVyIGNsYXNzIHByb3ZpZGVzIGEgY29uc2lzdGVudCBpbnRlcmZhY2UgdG8gZGF0YQorICogYXZhaWxhYmxlIGluIG1hbnkgZGlmZmVyZW50IHNvdXJjZXMgYW5kIGZvcm1hdHMuCisgKiBJdCBtYW5hZ2VzIHNpbXBsZSBzdHJlYW0gdG8gc3RyaW5nIGNvbnZlcnNpb25zIGFuZCByZWxhdGVkIG9wZXJhdGlvbnMKKyAqIHVzaW5nIERhdGFDb250ZW50SGFuZGxlcnMuCisgKiBJdCBwcm92aWRlcyBhY2Nlc3MgdG8gY29tbWFuZHMgdGhhdCBjYW4gb3BlcmF0ZSBvbiB0aGUgZGF0YS4KKyAqIFRoZSBjb21tYW5kcyBhcmUgZm91bmQgdXNpbmcgYSBDb21tYW5kTWFwLiA8cD4KKyAqCisgKiA8Yj5EYXRhSGFuZGxlciBhbmQgdGhlIFRyYW5zZmVyYWJsZSBJbnRlcmZhY2U8L2I+PHA+CisgKiBEYXRhSGFuZGxlciBpbXBsZW1lbnRzIHRoZSBUcmFuc2ZlcmFibGUgaW50ZXJmYWNlIHNvIHRoYXQgZGF0YSBjYW4KKyAqIGJlIHVzZWQgaW4gQVdUIGRhdGEgdHJhbnNmZXIgb3BlcmF0aW9ucywgc3VjaCBhcyBjdXQgYW5kIHBhc3RlIGFuZAorICogZHJhZyBhbmQgZHJvcC4gVGhlIGltcGxlbWVudGF0aW9uIG9mIHRoZSBUcmFuc2ZlcmFibGUgaW50ZXJmYWNlCisgKiByZWxpZXMgb24gdGhlIGF2YWlsYWJpbGl0eSBvZiBhbiBpbnN0YWxsZWQgRGF0YUNvbnRlbnRIYW5kbGVyCisgKiBvYmplY3QgY29ycmVzcG9uZGluZyB0byB0aGUgTUlNRSB0eXBlIG9mIHRoZSBkYXRhIHJlcHJlc2VudGVkIGluCisgKiB0aGUgc3BlY2lmaWMgaW5zdGFuY2Ugb2YgdGhlIERhdGFIYW5kbGVyLjxwPgorICoKKyAqIDxiPkRhdGFIYW5kbGVyIGFuZCBDb21tYW5kTWFwczwvYj48cD4KKyAqIFRoZSBEYXRhSGFuZGxlciBrZWVwcyB0cmFjayBvZiB0aGUgY3VycmVudCBDb21tYW5kTWFwIHRoYXQgaXQgdXNlcyB0bworICogc2VydmljZSByZXF1ZXN0cyBmb3IgY29tbWFuZHMgKDxjb2RlPmdldENvbW1hbmQ8L2NvZGU+LAorICogPGNvZGU+Z2V0QWxsQ29tbWFuZHM8L2NvZGU+LCA8Y29kZT5nZXRQcmVmZXJyZWRDb21tYW5kczwvY29kZT4pLgorICogRWFjaCBpbnN0YW5jZSBvZiBhIERhdGFIYW5kbGVyIG1heSBoYXZlIGEgQ29tbWFuZE1hcCBhc3NvY2lhdGVkIHdpdGgKKyAqIGl0IHVzaW5nIHRoZSA8Y29kZT5zZXRDb21tYW5kTWFwPC9jb2RlPiBtZXRob2QuICBJZiBhIENvbW1hbmRNYXAgd2FzCisgKiBub3Qgc2V0LCBEYXRhSGFuZGxlciBjYWxscyB0aGUgPGNvZGU+Z2V0RGVmYXVsdENvbW1hbmRNYXA8L2NvZGU+CisgKiBtZXRob2QgaW4gQ29tbWFuZE1hcCBhbmQgdXNlcyB0aGUgdmFsdWUgaXQgcmV0dXJucy4gU2VlCisgKiA8aT5Db21tYW5kTWFwPC9pPiBmb3IgbW9yZSBpbmZvcm1hdGlvbi4gPHA+CisgKgorICogPGI+RGF0YUhhbmRsZXIgYW5kIFVSTHM8L2I+PHA+CisgKiBUaGUgY3VycmVudCBEYXRhSGFuZGxlciBpbXBsZW1lbnRhdGlvbiBjcmVhdGVzIGEgcHJpdmF0ZQorICogaW5zdGFuY2Ugb2YgVVJMRGF0YVNvdXJjZSB3aGVuIGl0IGlzIGNvbnN0cnVjdGVkIHdpdGggYSBVUkwuCisgKgorICogQHNlZSBqYXZheC5hY3RpdmF0aW9uLkNvbW1hbmRNYXAKKyAqIEBzZWUgamF2YXguYWN0aXZhdGlvbi5EYXRhQ29udGVudEhhbmRsZXIKKyAqIEBzZWUgamF2YXguYWN0aXZhdGlvbi5EYXRhU291cmNlCisgKiBAc2VlIGphdmF4LmFjdGl2YXRpb24uVVJMRGF0YVNvdXJjZQorICovCisKK3B1YmxpYyBjbGFzcyBEYXRhSGFuZGxlciAvKmltcGxlbWVudHMgVHJhbnNmZXJhYmxlKi8geworCisgICAgLy8gVXNlIHRoZSBkYXRhc291cmNlIHRvIGluZGljYXRlIHdoZXRoZXIgd2Ugd2VyZSBzdGFydGVkIHZpYSB0aGUKKyAgICAvLyBEYXRhU291cmNlIGNvbnN0cnVjdG9yIG9yIHRoZSBvYmplY3QgY29uc3RydWN0b3IuCisgICAgcHJpdmF0ZSBEYXRhU291cmNlIGRhdGFTb3VyY2UgPSBudWxsOworICAgIHByaXZhdGUgRGF0YVNvdXJjZSBvYmpEYXRhU291cmNlID0gbnVsbDsKKworICAgIC8vIFRoZSBPYmplY3QgYW5kIG1pbWV0eXBlIGZyb20gdGhlIGNvbnN0cnVjdG9yIChpZiBwYXNzZWQgaW4pLgorICAgIC8vIG9iamVjdCByZW1haW5zIG51bGwgaWYgaXQgd2FzIGluc3RhbnRpYXRlZCB3aXRoIGEKKyAgICAvLyBEYXRhU291cmNlLgorICAgIHByaXZhdGUgT2JqZWN0IG9iamVjdCA9IG51bGw7CisgICAgcHJpdmF0ZSBTdHJpbmcgb2JqZWN0TWltZVR5cGUgPSBudWxsOworCisgICAgLy8gS2VlcCB0cmFjayBvZiB0aGUgQ29tbWFuZE1hcAorICAgIHByaXZhdGUgQ29tbWFuZE1hcCBjdXJyZW50Q29tbWFuZE1hcCA9IG51bGw7CisKKyAgICAvLyBvdXIgdHJhbnNmZXIgZmxhdm9ycworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEFjdGl2YXRpb25EYXRhRmxhdm9yIGVtcHR5Rmxhdm9yc1tdID0gbmV3IEFjdGl2YXRpb25EYXRhRmxhdm9yWzBdOworICAgIHByaXZhdGUgQWN0aXZhdGlvbkRhdGFGbGF2b3IgdHJhbnNmZXJGbGF2b3JzW10gPSBlbXB0eUZsYXZvcnM7CisKKyAgICAvLyBvdXIgRGF0YUNvbnRlbnRIYW5kbGVyCisgICAgcHJpdmF0ZSBEYXRhQ29udGVudEhhbmRsZXIgZGF0YUNvbnRlbnRIYW5kbGVyID0gbnVsbDsKKyAgICBwcml2YXRlIERhdGFDb250ZW50SGFuZGxlciBmYWN0b3J5RENIID0gbnVsbDsKKworICAgIC8vIG91ciBEYXRhQ29udGVudEhhbmRsZXJGYWN0b3J5CisgICAgcHJpdmF0ZSBzdGF0aWMgRGF0YUNvbnRlbnRIYW5kbGVyRmFjdG9yeSBmYWN0b3J5ID0gbnVsbDsKKyAgICBwcml2YXRlIERhdGFDb250ZW50SGFuZGxlckZhY3Rvcnkgb2xkRmFjdG9yeSA9IG51bGw7CisgICAgLy8gdGhlIHNob3J0IHJlcHJlc2VudGF0aW9uIG9mIHRoZSBDb250ZW50VHlwZSAoc2FucyBwYXJhbXMpCisgICAgcHJpdmF0ZSBTdHJpbmcgc2hvcnRUeXBlID0gbnVsbDsKKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIDxjb2RlPkRhdGFIYW5kbGVyPC9jb2RlPiBpbnN0YW5jZSByZWZlcmVuY2luZyB0aGUKKyAgICAgKiBzcGVjaWZpZWQgRGF0YVNvdXJjZS4gIFRoZSBkYXRhIGV4aXN0cyBpbiBhIGJ5dGUgc3RyZWFtIGZvcm0uCisgICAgICogVGhlIERhdGFTb3VyY2Ugd2lsbCBwcm92aWRlIGFuIElucHV0U3RyZWFtIHRvIGFjY2VzcyB0aGUgZGF0YS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkcwl0aGUgRGF0YVNvdXJjZQorICAgICAqLworICAgIHB1YmxpYyBEYXRhSGFuZGxlcihEYXRhU291cmNlIGRzKSB7CisJLy8gc2F2ZSBhIHJlZmVyZW5jZSB0byB0aGUgaW5jb21pbmcgRFMKKwlkYXRhU291cmNlID0gZHM7CisJb2xkRmFjdG9yeSA9IGZhY3Rvcnk7IC8vIGtlZXAgdHJhY2sgb2YgdGhlIGZhY3RvcnkKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSA8Y29kZT5EYXRhSGFuZGxlcjwvY29kZT4gaW5zdGFuY2UgcmVwcmVzZW50aW5nIGFuIG9iamVjdAorICAgICAqIG9mIHRoaXMgTUlNRSB0eXBlLiAgVGhpcyBjb25zdHJ1Y3RvciBpcworICAgICAqIHVzZWQgd2hlbiB0aGUgYXBwbGljYXRpb24gYWxyZWFkeSBoYXMgYW4gaW4tbWVtb3J5IHJlcHJlc2VudGF0aW9uCisgICAgICogb2YgdGhlIGRhdGEgaW4gdGhlIGZvcm0gb2YgYSBKYXZhIE9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvYmoJdGhlIEphdmEgT2JqZWN0CisgICAgICogQHBhcmFtIG1pbWVUeXBlCXRoZSBNSU1FIHR5cGUgb2YgdGhlIG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyBEYXRhSGFuZGxlcihPYmplY3Qgb2JqLCBTdHJpbmcgbWltZVR5cGUpIHsKKwlvYmplY3QgPSBvYmo7CisJb2JqZWN0TWltZVR5cGUgPSBtaW1lVHlwZTsKKwlvbGRGYWN0b3J5ID0gZmFjdG9yeTsgLy8ga2VlcCB0cmFjayBvZiB0aGUgZmFjdG9yeQorICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIDxjb2RlPkRhdGFIYW5kbGVyPC9jb2RlPiBpbnN0YW5jZSByZWZlcmVuY2luZyBhIFVSTC4KKyAgICAgKiBUaGUgRGF0YUhhbmRsZXIgaW50ZXJuYWxseSBjcmVhdGVzIGEgPGNvZGU+VVJMRGF0YVNvdXJjZTwvY29kZT4KKyAgICAgKiBpbnN0YW5jZSB0byByZXByZXNlbnQgdGhlIFVSTC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1cmwJYSBVUkwgb2JqZWN0CisgICAgICovCisgICAgcHVibGljIERhdGFIYW5kbGVyKFVSTCB1cmwpIHsKKwlkYXRhU291cmNlID0gbmV3IFVSTERhdGFTb3VyY2UodXJsKTsKKwlvbGRGYWN0b3J5ID0gZmFjdG9yeTsgLy8ga2VlcCB0cmFjayBvZiB0aGUgZmFjdG9yeQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgQ29tbWFuZE1hcCBmb3IgdGhpcyBpbnN0YW5jZSBvZiBEYXRhSGFuZGxlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN5bmNocm9uaXplZCBDb21tYW5kTWFwIGdldENvbW1hbmRNYXAoKSB7CisJaWYgKGN1cnJlbnRDb21tYW5kTWFwICE9IG51bGwpCisJICAgIHJldHVybiBjdXJyZW50Q29tbWFuZE1hcDsKKwllbHNlCisJICAgIHJldHVybiBDb21tYW5kTWFwLmdldERlZmF1bHRDb21tYW5kTWFwKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBEYXRhU291cmNlIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGluc3RhbmNlCisgICAgICogb2YgRGF0YUhhbmRsZXIuCisgICAgICogPHA+CisgICAgICogRm9yIERhdGFIYW5kbGVycyB0aGF0IGhhdmUgYmVlbiBpbnN0YW50aWF0ZWQgd2l0aCBhIERhdGFTb3VyY2UsCisgICAgICogdGhpcyBtZXRob2QgcmV0dXJucyB0aGUgRGF0YVNvdXJjZSB0aGF0IHdhcyB1c2VkIHRvIGNyZWF0ZSB0aGUKKyAgICAgKiBEYXRhSGFuZGxlciBvYmplY3QuIEluIG90aGVyIGNhc2VzIHRoZSBEYXRhSGFuZGxlcgorICAgICAqIGNvbnN0cnVjdHMgYSBEYXRhU291cmNlIGZyb20gdGhlIGRhdGEgdXNlZCB0byBjb25zdHJ1Y3QKKyAgICAgKiB0aGUgRGF0YUhhbmRsZXIuIERhdGFTb3VyY2VzIGNyZWF0ZWQgZm9yIERhdGFIYW5kbGVycyA8Yj5ub3Q8L2I+CisgICAgICogaW5zdGFudGlhdGVkIHdpdGggYSBEYXRhU291cmNlIGFyZSBjYWNoZWQgZm9yIHBlcmZvcm1hbmNlCisgICAgICogcmVhc29ucy4KKyAgICAgKgorICAgICAqIEByZXR1cm4JYSB2YWxpZCBEYXRhU291cmNlIG9iamVjdCBmb3IgdGhpcyBEYXRhSGFuZGxlcgorICAgICAqLworICAgIHB1YmxpYyBEYXRhU291cmNlIGdldERhdGFTb3VyY2UoKSB7CisJaWYgKGRhdGFTb3VyY2UgPT0gbnVsbCkgeworCSAgICAvLyBjcmVhdGUgb25lIG9uIHRoZSBmbHkKKwkgICAgaWYgKG9iakRhdGFTb3VyY2UgPT0gbnVsbCkKKwkJb2JqRGF0YVNvdXJjZSA9IG5ldyBEYXRhSGFuZGxlckRhdGFTb3VyY2UodGhpcyk7CisJICAgIHJldHVybiBvYmpEYXRhU291cmNlOworCX0KKwlyZXR1cm4gZGF0YVNvdXJjZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIG5hbWUgb2YgdGhlIGRhdGEgb2JqZWN0LiBJZiB0aGlzIERhdGFIYW5kbGVyCisgICAgICogd2FzIGNyZWF0ZWQgd2l0aCBhIERhdGFTb3VyY2UsIHRoaXMgbWV0aG9kIGNhbGxzIHRocm91Z2gKKyAgICAgKiB0byB0aGUgPGNvZGU+RGF0YVNvdXJjZS5nZXROYW1lPC9jb2RlPiBtZXRob2QsIG90aGVyd2lzZSBpdAorICAgICAqIHJldHVybnMgPGk+bnVsbDwvaT4uCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBuYW1lIG9mIHRoZSBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7CisJaWYgKGRhdGFTb3VyY2UgIT0gbnVsbCkKKwkgICAgcmV0dXJuIGRhdGFTb3VyY2UuZ2V0TmFtZSgpOworCWVsc2UKKwkgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBNSU1FIHR5cGUgb2YgdGhpcyBvYmplY3QgYXMgcmV0cmlldmVkIGZyb20KKyAgICAgKiB0aGUgc291cmNlIG9iamVjdC4gTm90ZSB0aGF0IHRoaXMgaXMgdGhlIDxpPmZ1bGw8L2k+CisgICAgICogdHlwZSB3aXRoIHBhcmFtZXRlcnMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBNSU1FIHR5cGUKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldENvbnRlbnRUeXBlKCkgeworCWlmIChkYXRhU291cmNlICE9IG51bGwpIC8vIGRhdGEgc291cmNlIGNhc2UKKwkgICAgcmV0dXJuIGRhdGFTb3VyY2UuZ2V0Q29udGVudFR5cGUoKTsKKwllbHNlCisJICAgIHJldHVybiBvYmplY3RNaW1lVHlwZTsgLy8gb2JqL3R5cGUgY2FzZQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgSW5wdXRTdHJlYW0gZm9yIHRoaXMgb2JqZWN0LiA8cD4KKyAgICAgKgorICAgICAqIEZvciBEYXRhSGFuZGxlcnMgaW5zdGFudGlhdGVkIHdpdGggYSBEYXRhU291cmNlLCB0aGUgRGF0YUhhbmRsZXIKKyAgICAgKiBjYWxscyB0aGUgPGNvZGU+RGF0YVNvdXJjZS5nZXRJbnB1dFN0cmVhbTwvY29kZT4gbWV0aG9kIGFuZAorICAgICAqIHJldHVybnMgdGhlIHJlc3VsdCB0byB0aGUgY2FsbGVyLgorICAgICAqIDxwPgorICAgICAqIEZvciBEYXRhSGFuZGxlcnMgaW5zdGFudGlhdGVkIHdpdGggYW4gT2JqZWN0LCB0aGUgRGF0YUhhbmRsZXIKKyAgICAgKiBmaXJzdCBhdHRlbXB0cyB0byBmaW5kIGEgRGF0YUNvbnRlbnRIYW5kbGVyIGZvciB0aGUgT2JqZWN0LiBJZgorICAgICAqIHRoZSBEYXRhSGFuZGxlciBjYW4gbm90IGZpbmQgYSBEYXRhQ29udGVudEhhbmRsZXIgZm9yIHRoaXMgTUlNRQorICAgICAqIHR5cGUsIGl0IHRocm93cyBhbiBVbnN1cHBvcnRlZERhdGFUeXBlRXhjZXB0aW9uLiAgSWYgaXQgaXMKKyAgICAgKiBzdWNjZXNzZnVsLCBpdCBjcmVhdGVzIGEgcGlwZSBhbmQgYSB0aHJlYWQuICBUaGUgdGhyZWFkIHVzZXMgdGhlCisgICAgICogRGF0YUNvbnRlbnRIYW5kbGVyJ3MgPGNvZGU+d3JpdGVUbzwvY29kZT4gbWV0aG9kIHRvIHdyaXRlIHRoZQorICAgICAqIHN0cmVhbSBkYXRhIGludG8gb25lIGVuZCBvZiB0aGUgcGlwZS4gIFRoZSBvdGhlciBlbmQgb2YgdGhlIHBpcGUKKyAgICAgKiBpcyByZXR1cm5lZCB0byB0aGUgY2FsbGVyLiAgQmVjYXVzZSBhIHRocmVhZCBpcyBjcmVhdGVkIHRvIGNvcHkKKyAgICAgKiB0aGUgZGF0YSwgSU9FeGNlcHRpb25zIHRoYXQgbWF5IG9jY3VyIGR1cmluZyB0aGUgY29weSBjYW4gbm90IGJlCisgICAgICogcHJvcGFnYXRlZCBiYWNrIHRvIHRoZSBjYWxsZXIuIFRoZSByZXN1bHQgaXMgYW4gZW1wdHkgc3RyZWFtLjxwPgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgSW5wdXRTdHJlYW0gcmVwcmVzZW50aW5nIHRoaXMgZGF0YQorICAgICAqIEBleGNlcHRpb24gSU9FeGNlcHRpb24JaWYgYW4gSS9PIGVycm9yIG9jY3VycworICAgICAqCisgICAgICogQHNlZSBqYXZheC5hY3RpdmF0aW9uLkRhdGFDb250ZW50SGFuZGxlciN3cml0ZVRvCisgICAgICogQHNlZSBqYXZheC5hY3RpdmF0aW9uLlVuc3VwcG9ydGVkRGF0YVR5cGVFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgSW5wdXRTdHJlYW0gZ2V0SW5wdXRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworCUlucHV0U3RyZWFtIGlucyA9IG51bGw7CisKKwlpZiAoZGF0YVNvdXJjZSAhPSBudWxsKSB7CisJICAgIGlucyA9IGRhdGFTb3VyY2UuZ2V0SW5wdXRTdHJlYW0oKTsKKwl9IGVsc2UgeworCSAgICBEYXRhQ29udGVudEhhbmRsZXIgZGNoID0gZ2V0RGF0YUNvbnRlbnRIYW5kbGVyKCk7CisJICAgIC8vIHdlIHdvbid0IGV2ZW4gdHJ5IGlmIHdlIGNhbid0IGdldCBhIGRjaAorCSAgICBpZiAoZGNoID09IG51bGwpCisJCXRocm93IG5ldyBVbnN1cHBvcnRlZERhdGFUeXBlRXhjZXB0aW9uKAorCQkJCSJubyBEQ0ggZm9yIE1JTUUgdHlwZSAiICsgZ2V0QmFzZVR5cGUoKSk7CisKKwkgICAgaWYgKGRjaCBpbnN0YW5jZW9mIE9iamVjdERhdGFDb250ZW50SGFuZGxlcikgeworCQlpZiAoKChPYmplY3REYXRhQ29udGVudEhhbmRsZXIpZGNoKS5nZXREQ0goKSA9PSBudWxsKQorCQkgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkRGF0YVR5cGVFeGNlcHRpb24oCisJCQkJIm5vIG9iamVjdCBEQ0ggZm9yIE1JTUUgdHlwZSAiICsgZ2V0QmFzZVR5cGUoKSk7CisJICAgIH0KKwkgICAgLy8gdGhlcmUgaXMgbm9uZSBidXQgdGhlIGRlZmF1bHReXl5eXl5eXl5eXl5eXl5eCisJICAgIGZpbmFsIERhdGFDb250ZW50SGFuZGxlciBmZGNoID0gZGNoOworCisJICAgIC8vIGZyb20gYmlsbCBzLgorCSAgICAvLyBjZSBuJ2VzdCBwYXMgdW5lIHBpcGUhCisJICAgIC8vCisJICAgIC8vIE5PVEU6IFRoaXMgYmxvY2sgb2YgY29kZSBuZWVkcyB0byB0aHJvdyBleGNlcHRpb25zLCBidXQKKwkgICAgLy8gY2FuJ3QgYmVjYXVzZSBpdCBpcyBpbiBhbm90aGVyIHRocmVhZCEhISBBUkchCisJICAgIC8vCisJICAgIGZpbmFsIFBpcGVkT3V0cHV0U3RyZWFtIHBvcyA9IG5ldyBQaXBlZE91dHB1dFN0cmVhbSgpOworCSAgICBQaXBlZElucHV0U3RyZWFtIHBpbiA9IG5ldyBQaXBlZElucHV0U3RyZWFtKHBvcyk7CisJICAgIG5ldyBUaHJlYWQoCisJCSAgICAgICBuZXcgUnVubmFibGUoKSB7CisJCXB1YmxpYyB2b2lkIHJ1bigpIHsKKwkJICAgIHRyeSB7CisJCQlmZGNoLndyaXRlVG8ob2JqZWN0LCBvYmplY3RNaW1lVHlwZSwgcG9zKTsKKwkJICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKworCQkgICAgfSBmaW5hbGx5IHsKKwkJCXRyeSB7CisJCQkgICAgcG9zLmNsb3NlKCk7CisJCQl9IGNhdGNoIChJT0V4Y2VwdGlvbiBpZSkgeyB9CisJCSAgICB9CisJCX0KKwkgICAgfSwKKwkJICAgICAgIkRhdGFIYW5kbGVyLmdldElucHV0U3RyZWFtIikuc3RhcnQoKTsKKwkgICAgaW5zID0gcGluOworCX0KKworCXJldHVybiBpbnM7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGUgdGhlIGRhdGEgdG8gYW4gPGNvZGU+T3V0cHV0U3RyZWFtPC9jb2RlPi48cD4KKyAgICAgKgorICAgICAqIElmIHRoZSBEYXRhSGFuZGxlciB3YXMgY3JlYXRlZCB3aXRoIGEgRGF0YVNvdXJjZSwgd3JpdGVUbworICAgICAqIHJldHJpZXZlcyB0aGUgSW5wdXRTdHJlYW0gYW5kIGNvcGllcyB0aGUgYnl0ZXMgZnJvbSB0aGUKKyAgICAgKiBJbnB1dFN0cmVhbSB0byB0aGUgT3V0cHV0U3RyZWFtIHBhc3NlZCBpbi4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiB0aGUgRGF0YUhhbmRsZXIgd2FzIGNyZWF0ZWQgd2l0aCBhbiBvYmplY3QsIHdyaXRlVG8KKyAgICAgKiByZXRyaWV2ZXMgdGhlIERhdGFDb250ZW50SGFuZGxlciBmb3IgdGhlIG9iamVjdCdzIHR5cGUuCisgICAgICogSWYgdGhlIERhdGFDb250ZW50SGFuZGxlciB3YXMgZm91bmQsIGl0IGNhbGxzIHRoZQorICAgICAqIDxjb2RlPndyaXRlVG88L2NvZGU+IG1ldGhvZCBvbiB0aGUgPGNvZGU+RGF0YUNvbnRlbnRIYW5kbGVyPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvcwl0aGUgT3V0cHV0U3RyZWFtIHRvIHdyaXRlIHRvCisgICAgICogQGV4Y2VwdGlvbiBJT0V4Y2VwdGlvbglpZiBhbiBJL08gZXJyb3Igb2NjdXJzCisgICAgICovCisgICAgcHVibGljIHZvaWQgd3JpdGVUbyhPdXRwdXRTdHJlYW0gb3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJLy8gZm9yIHRoZSBEYXRhU291cmNlIGNhc2UKKwlpZiAoZGF0YVNvdXJjZSAhPSBudWxsKSB7CisJICAgIElucHV0U3RyZWFtIGlzID0gbnVsbDsKKwkgICAgYnl0ZSBkYXRhW10gPSBuZXcgYnl0ZVs4KjEwMjRdOworCSAgICBpbnQgYnl0ZXNfcmVhZDsKKworCSAgICBpcyA9IGRhdGFTb3VyY2UuZ2V0SW5wdXRTdHJlYW0oKTsKKworCSAgICB0cnkgeworCQl3aGlsZSAoKGJ5dGVzX3JlYWQgPSBpcy5yZWFkKGRhdGEpKSA+IDApIHsKKwkJICAgIG9zLndyaXRlKGRhdGEsIDAsIGJ5dGVzX3JlYWQpOworCQl9CisJICAgIH0gZmluYWxseSB7CisJCWlzLmNsb3NlKCk7CisJCWlzID0gbnVsbDsKKwkgICAgfQorCX0gZWxzZSB7IC8vIGZvciB0aGUgT2JqZWN0IGNhc2UKKwkgICAgRGF0YUNvbnRlbnRIYW5kbGVyIGRjaCA9IGdldERhdGFDb250ZW50SGFuZGxlcigpOworCSAgICBkY2gud3JpdGVUbyhvYmplY3QsIG9iamVjdE1pbWVUeXBlLCBvcyk7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCBhbiBPdXRwdXRTdHJlYW0gZm9yIHRoaXMgRGF0YUhhbmRsZXIgdG8gYWxsb3cgb3ZlcndyaXRpbmcKKyAgICAgKiB0aGUgdW5kZXJseWluZyBkYXRhLgorICAgICAqIElmIHRoZSBEYXRhSGFuZGxlciB3YXMgY3JlYXRlZCB3aXRoIGEgRGF0YVNvdXJjZSwgdGhlCisgICAgICogRGF0YVNvdXJjZSdzIDxjb2RlPmdldE91dHB1dFN0cmVhbTwvY29kZT4gbWV0aG9kIGlzIGNhbGxlZC4KKyAgICAgKiBPdGhlcndpc2UsIDxjb2RlPm51bGw8L2NvZGU+IGlzIHJldHVybmVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgT3V0cHV0U3RyZWFtCisgICAgICoKKyAgICAgKiBAc2VlIGphdmF4LmFjdGl2YXRpb24uRGF0YVNvdXJjZSNnZXRPdXRwdXRTdHJlYW0KKyAgICAgKiBAc2VlIGphdmF4LmFjdGl2YXRpb24uVVJMRGF0YVNvdXJjZQorICAgICAqLworICAgIHB1YmxpYyBPdXRwdXRTdHJlYW0gZ2V0T3V0cHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlpZiAoZGF0YVNvdXJjZSAhPSBudWxsKQorCSAgICByZXR1cm4gZGF0YVNvdXJjZS5nZXRPdXRwdXRTdHJlYW0oKTsKKwllbHNlCisJICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgRGF0YUZsYXZvcnMgaW4gd2hpY2ggdGhpcyBkYXRhIGlzIGF2YWlsYWJsZS4gPHA+CisgICAgICoKKyAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIERhdGFGbGF2b3Igb2JqZWN0cyBpbmRpY2F0aW5nIHRoZSBmbGF2b3JzCisgICAgICogdGhlIGRhdGEgY2FuIGJlIHByb3ZpZGVkIGluLiBUaGUgYXJyYXkgaXMgdXN1YWxseSBvcmRlcmVkCisgICAgICogYWNjb3JkaW5nIHRvIHByZWZlcmVuY2UgZm9yIHByb3ZpZGluZyB0aGUgZGF0YSwgZnJvbSBtb3N0CisgICAgICogcmljaGx5IGRlc2NyaXB0aXZlIHRvIGxlYXN0IHJpY2hseSBkZXNjcmlwdGl2ZS48cD4KKyAgICAgKgorICAgICAqIFRoZSBEYXRhSGFuZGxlciBhdHRlbXB0cyB0byBmaW5kIGEgRGF0YUNvbnRlbnRIYW5kbGVyIHRoYXQKKyAgICAgKiBjb3JyZXNwb25kcyB0byB0aGUgTUlNRSB0eXBlIG9mIHRoZSBkYXRhLiBJZiBvbmUgaXMgbG9jYXRlZCwKKyAgICAgKiB0aGUgRGF0YUhhbmRsZXIgY2FsbHMgdGhlIERhdGFDb250ZW50SGFuZGxlcidzCisgICAgICogPGNvZGU+Z2V0VHJhbnNmZXJEYXRhRmxhdm9yczwvY29kZT4gbWV0aG9kLiA8cD4KKyAgICAgKgorICAgICAqIElmIGEgRGF0YUNvbnRlbnRIYW5kbGVyIGNhbiA8aT5ub3Q8L2k+IGJlIGxvY2F0ZWQsIGFuZCBpZiB0aGUKKyAgICAgKiBEYXRhSGFuZGxlciB3YXMgY3JlYXRlZCB3aXRoIGEgRGF0YVNvdXJjZSAob3IgVVJMKSwgb25lCisgICAgICogRGF0YUZsYXZvciBpcyByZXR1cm5lZCB0aGF0IHJlcHJlc2VudHMgdGhpcyBvYmplY3QncyBNSU1FIHR5cGUKKyAgICAgKiBhbmQgdGhlIDxjb2RlPmphdmEuaW8uSW5wdXRTdHJlYW08L2NvZGU+IGNsYXNzLiAgSWYgdGhlCisgICAgICogRGF0YUhhbmRsZXIgd2FzIGNyZWF0ZWQgd2l0aCBhbiBvYmplY3QgYW5kIGEgTUlNRSB0eXBlLAorICAgICAqIGdldFRyYW5zZmVyRGF0YUZsYXZvcnMgcmV0dXJucyBvbmUgRGF0YUZsYXZvciB0aGF0IHJlcHJlc2VudHMKKyAgICAgKiB0aGlzIG9iamVjdCdzIE1JTUUgdHlwZSBhbmQgdGhlIG9iamVjdCdzIGNsYXNzLgorICAgICAqCisgICAgICogQHJldHVybglhbiBhcnJheSBvZiBkYXRhIGZsYXZvcnMgaW4gd2hpY2ggdGhpcyBkYXRhIGNhbiBiZSB0cmFuc2ZlcnJlZAorICAgICAqIEBzZWUgamF2YXguYWN0aXZhdGlvbi5EYXRhQ29udGVudEhhbmRsZXIjZ2V0VHJhbnNmZXJEYXRhRmxhdm9ycworICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgQWN0aXZhdGlvbkRhdGFGbGF2b3JbXSBnZXRUcmFuc2ZlckRhdGFGbGF2b3JzKCkgeworCWlmIChmYWN0b3J5ICE9IG9sZEZhY3RvcnkpIC8vIGlmIHRoZSBmYWN0b3J5IGhhcyBjaGFuZ2VkLCBjbGVhciBjYWNoZQorCSAgICB0cmFuc2ZlckZsYXZvcnMgPSBlbXB0eUZsYXZvcnM7CisKKwkvLyBpZiBpdCdzIG5vdCBzZXQsIHNldCBpdC4uLgorCWlmICh0cmFuc2ZlckZsYXZvcnMgPT0gZW1wdHlGbGF2b3JzKQorCSAgICB0cmFuc2ZlckZsYXZvcnMgPSBnZXREYXRhQ29udGVudEhhbmRsZXIoKS5nZXRUcmFuc2ZlckRhdGFGbGF2b3JzKCk7CisJaWYgKHRyYW5zZmVyRmxhdm9ycyA9PSBlbXB0eUZsYXZvcnMpCisJICAgIHJldHVybiB0cmFuc2ZlckZsYXZvcnM7CS8vIG5vIG5lZWQgdG8gY2xvbmUgYW4gZW1wdHkgYXJyYXkKKwllbHNlCisJICAgIHJldHVybiB0cmFuc2ZlckZsYXZvcnMuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhlIHNwZWNpZmllZCBkYXRhIGZsYXZvciBpcyBzdXBwb3J0ZWQKKyAgICAgKiBmb3IgdGhpcyBvYmplY3QuPHA+CisgICAgICoKKyAgICAgKiBUaGlzIG1ldGhvZCBpdGVyYXRlcyB0aHJvdWdoIHRoZSBEYXRhRmxhdm9ycyByZXR1cm5lZCBmcm9tCisgICAgICogPGNvZGU+Z2V0VHJhbnNmZXJEYXRhRmxhdm9yczwvY29kZT4sIGNvbXBhcmluZyBlYWNoIHdpdGgKKyAgICAgKiB0aGUgc3BlY2lmaWVkIGZsYXZvci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmbGF2b3IJdGhlIHJlcXVlc3RlZCBmbGF2b3IgZm9yIHRoZSBkYXRhCisgICAgICogQHJldHVybgkJdHJ1ZSBpZiB0aGUgZGF0YSBmbGF2b3IgaXMgc3VwcG9ydGVkCisgICAgICogQHNlZSBqYXZheC5hY3RpdmF0aW9uLkRhdGFIYW5kbGVyI2dldFRyYW5zZmVyRGF0YUZsYXZvcnMKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0RhdGFGbGF2b3JTdXBwb3J0ZWQoQWN0aXZhdGlvbkRhdGFGbGF2b3IgZmxhdm9yKSB7CisJQWN0aXZhdGlvbkRhdGFGbGF2b3JbXSBsRmxhdm9ycyA9IGdldFRyYW5zZmVyRGF0YUZsYXZvcnMoKTsKKworCWZvciAoaW50IGkgPSAwOyBpIDwgbEZsYXZvcnMubGVuZ3RoOyBpKyspIHsKKwkgICAgaWYgKGxGbGF2b3JzW2ldLmVxdWFscyhmbGF2b3IpKQorCQlyZXR1cm4gdHJ1ZTsKKwl9CisJcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgZGF0YSB0byBiZQorICAgICAqIHRyYW5zZmVycmVkLiBUaGUgY2xhc3Mgb2YgdGhlIG9iamVjdCByZXR1cm5lZCBpcyBkZWZpbmVkIGJ5IHRoZQorICAgICAqIHJlcHJlc2VudGF0aW9uIGNsYXNzIG9mIHRoZSBkYXRhIGZsYXZvci48cD4KKyAgICAgKgorICAgICAqIDxiPkZvciBEYXRhSGFuZGxlcidzIGNyZWF0ZWQgd2l0aCBEYXRhU291cmNlcyBvciBVUkxzOjwvYj48cD4KKyAgICAgKgorICAgICAqIFRoZSBEYXRhSGFuZGxlciBhdHRlbXB0cyB0byBsb2NhdGUgYSBEYXRhQ29udGVudEhhbmRsZXIKKyAgICAgKiBmb3IgdGhpcyBNSU1FIHR5cGUuIElmIG9uZSBpcyBmb3VuZCwgdGhlIHBhc3NlZCBpbiBEYXRhRmxhdm9yCisgICAgICogYW5kIHRoZSB0eXBlIG9mIHRoZSBkYXRhIGFyZSBwYXNzZWQgdG8gaXRzIDxjb2RlPmdldFRyYW5zZmVyRGF0YTwvY29kZT4KKyAgICAgKiBtZXRob2QuIElmIHRoZSBEYXRhSGFuZGxlciBmYWlscyB0byBsb2NhdGUgYSBEYXRhQ29udGVudEhhbmRsZXIKKyAgICAgKiBhbmQgdGhlIGZsYXZvciBzcGVjaWZpZXMgdGhpcyBvYmplY3QncyBNSU1FIHR5cGUgYW5kIHRoZQorICAgICAqIDxjb2RlPmphdmEuaW8uSW5wdXRTdHJlYW08L2NvZGU+IGNsYXNzLCB0aGlzIG9iamVjdCdzIElucHV0U3RyZWFtCisgICAgICogaXMgcmV0dXJuZWQuCisgICAgICogT3RoZXJ3aXNlIGl0IHRocm93cyBhbiBVbnN1cHBvcnRlZEZsYXZvckV4Y2VwdGlvbi4gPHA+CisgICAgICoKKyAgICAgKiA8Yj5Gb3IgRGF0YUhhbmRsZXIncyBjcmVhdGVkIHdpdGggT2JqZWN0czo8L2I+PHA+CisgICAgICoKKyAgICAgKiBUaGUgRGF0YUhhbmRsZXIgYXR0ZW1wdHMgdG8gbG9jYXRlIGEgRGF0YUNvbnRlbnRIYW5kbGVyCisgICAgICogZm9yIHRoaXMgTUlNRSB0eXBlLiBJZiBvbmUgaXMgZm91bmQsIHRoZSBwYXNzZWQgaW4gRGF0YUZsYXZvcgorICAgICAqIGFuZCB0aGUgdHlwZSBvZiB0aGUgZGF0YSBhcmUgcGFzc2VkIHRvIGl0cyBnZXRUcmFuc2ZlckRhdGEKKyAgICAgKiBtZXRob2QuIElmIHRoZSBEYXRhSGFuZGxlciBmYWlscyB0byBsb2NhdGUgYSBEYXRhQ29udGVudEhhbmRsZXIKKyAgICAgKiBhbmQgdGhlIGZsYXZvciBzcGVjaWZpZXMgdGhpcyBvYmplY3QncyBNSU1FIHR5cGUgYW5kIGl0cyBjbGFzcywKKyAgICAgKiB0aGlzIERhdGFIYW5kbGVyJ3MgcmVmZXJlbmNlZCBvYmplY3QgaXMgcmV0dXJuZWQuICAKKyAgICAgKiBPdGhlcndpc2UgaXQgdGhyb3dzIGFuIFVuc3VwcG9ydGVkRmxhdm9yRXhjZXB0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIGZsYXZvcgl0aGUgcmVxdWVzdGVkIGZsYXZvciBmb3IgdGhlIGRhdGEKKyAgICAgKiBAcmV0dXJuCQl0aGUgb2JqZWN0CisgICAgICogQGV4Y2VwdGlvbiBJT0V4Y2VwdGlvbglpZiBhbiBJL08gZXJyb3Igb2NjdXJzCisgICAgICogQHNlZSBqYXZheC5hY3RpdmF0aW9uLkFjdGl2YXRpb25EYXRhRmxhdm9yCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBnZXRUcmFuc2ZlckRhdGEoQWN0aXZhdGlvbkRhdGFGbGF2b3IgZmxhdm9yKQorCQkJCXRocm93cyAvKlVuc3VwcG9ydGVkRmxhdm9yRXhjZXB0aW9uLCovIElPRXhjZXB0aW9uIHsKKwlyZXR1cm4gZ2V0RGF0YUNvbnRlbnRIYW5kbGVyKCkuZ2V0VHJhbnNmZXJEYXRhKGZsYXZvciwgZGF0YVNvdXJjZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBDb21tYW5kTWFwIGZvciB1c2UgYnkgdGhpcyBEYXRhSGFuZGxlci4KKyAgICAgKiBTZXR0aW5nIGl0IHRvIDxjb2RlPm51bGw8L2NvZGU+IGNhdXNlcyB0aGUgQ29tbWFuZE1hcCB0byByZXZlcnQKKyAgICAgKiB0byB0aGUgQ29tbWFuZE1hcCByZXR1cm5lZCBieSB0aGUKKyAgICAgKiA8Y29kZT5Db21tYW5kTWFwLmdldERlZmF1bHRDb21tYW5kTWFwPC9jb2RlPiBtZXRob2QuCisgICAgICogQ2hhbmdpbmcgdGhlIENvbW1hbmRNYXAsIG9yIHNldHRpbmcgaXQgdG8gPGNvZGU+bnVsbDwvY29kZT4sCisgICAgICogY2xlYXJzIG91dCBhbnkgZGF0YSBjYWNoZWQgZnJvbSB0aGUgcHJldmlvdXMgQ29tbWFuZE1hcC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb21tYW5kTWFwCXRoZSBDb21tYW5kTWFwIHRvIHVzZSBpbiB0aGlzIERhdGFIYW5kbGVyCisgICAgICoKKyAgICAgKiBAc2VlIGphdmF4LmFjdGl2YXRpb24uQ29tbWFuZE1hcCNzZXREZWZhdWx0Q29tbWFuZE1hcAorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXRDb21tYW5kTWFwKENvbW1hbmRNYXAgY29tbWFuZE1hcCkgeworCWlmIChjb21tYW5kTWFwICE9IGN1cnJlbnRDb21tYW5kTWFwIHx8IGNvbW1hbmRNYXAgPT0gbnVsbCkgeworCSAgICAvLyBjbGVhciBjYWNoZWQgdmFsdWVzLi4uCisJICAgIHRyYW5zZmVyRmxhdm9ycyA9IGVtcHR5Rmxhdm9yczsKKwkgICAgZGF0YUNvbnRlbnRIYW5kbGVyID0gbnVsbDsKKworCSAgICBjdXJyZW50Q29tbWFuZE1hcCA9IGNvbW1hbmRNYXA7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgPGk+cHJlZmVycmVkPC9pPiBjb21tYW5kcyBmb3IgdGhpcyB0eXBlIG9mIGRhdGEuCisgICAgICogVGhpcyBtZXRob2QgY2FsbHMgdGhlIDxjb2RlPmdldFByZWZlcnJlZENvbW1hbmRzPC9jb2RlPiBtZXRob2QKKyAgICAgKiBpbiB0aGUgQ29tbWFuZE1hcCBhc3NvY2lhdGVkIHdpdGggdGhpcyBpbnN0YW5jZSBvZiBEYXRhSGFuZGxlci4KKyAgICAgKiBUaGlzIG1ldGhvZCByZXR1cm5zIGFuIGFycmF5IHRoYXQgcmVwcmVzZW50cyBhIHN1YnNldCBvZgorICAgICAqIGF2YWlsYWJsZSBjb21tYW5kcy4gSW4gY2FzZXMgd2hlcmUgbXVsdGlwbGUgY29tbWFuZHMgZm9yIHRoZQorICAgICAqIE1JTUUgdHlwZSByZXByZXNlbnRlZCBieSB0aGlzIERhdGFIYW5kbGVyIGFyZSBwcmVzZW50LCB0aGUKKyAgICAgKiBpbnN0YWxsZWQgQ29tbWFuZE1hcCBjaG9vc2VzIHRoZSBhcHByb3ByaWF0ZSBjb21tYW5kcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIENvbW1hbmRJbmZvIG9iamVjdHMgcmVwcmVzZW50aW5nIHRoZSBwcmVmZXJyZWQgY29tbWFuZHMKKyAgICAgKgorICAgICAqIEBzZWUgamF2YXguYWN0aXZhdGlvbi5Db21tYW5kTWFwI2dldFByZWZlcnJlZENvbW1hbmRzCisgICAgICovCisgICAgcHVibGljIENvbW1hbmRJbmZvW10gZ2V0UHJlZmVycmVkQ29tbWFuZHMoKSB7CisJaWYgKGRhdGFTb3VyY2UgIT0gbnVsbCkKKwkgICAgcmV0dXJuIGdldENvbW1hbmRNYXAoKS5nZXRQcmVmZXJyZWRDb21tYW5kcyhnZXRCYXNlVHlwZSgpLAorCQkJCQkJCWRhdGFTb3VyY2UpOworCWVsc2UKKwkgICAgcmV0dXJuIGdldENvbW1hbmRNYXAoKS5nZXRQcmVmZXJyZWRDb21tYW5kcyhnZXRCYXNlVHlwZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYWxsIHRoZSBjb21tYW5kcyBmb3IgdGhpcyB0eXBlIG9mIGRhdGEuCisgICAgICogVGhpcyBtZXRob2QgcmV0dXJucyBhbiBhcnJheSBjb250YWluaW5nIGFsbCBjb21tYW5kcworICAgICAqIGZvciB0aGUgdHlwZSBvZiBkYXRhIHJlcHJlc2VudGVkIGJ5IHRoaXMgRGF0YUhhbmRsZXIuIFRoZQorICAgICAqIE1JTUUgdHlwZSBmb3IgdGhlIHVuZGVybHlpbmcgZGF0YSByZXByZXNlbnRlZCBieSB0aGlzIERhdGFIYW5kbGVyCisgICAgICogaXMgdXNlZCB0byBjYWxsIHRocm91Z2ggdG8gdGhlIDxjb2RlPmdldEFsbENvbW1hbmRzPC9jb2RlPiBtZXRob2QKKyAgICAgKiBvZiB0aGUgQ29tbWFuZE1hcCBhc3NvY2lhdGVkIHdpdGggdGhpcyBEYXRhSGFuZGxlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIENvbW1hbmRJbmZvIG9iamVjdHMgcmVwcmVzZW50aW5nIGFsbCB0aGUgY29tbWFuZHMKKyAgICAgKgorICAgICAqIEBzZWUgamF2YXguYWN0aXZhdGlvbi5Db21tYW5kTWFwI2dldEFsbENvbW1hbmRzCisgICAgICovCisgICAgcHVibGljIENvbW1hbmRJbmZvW10gZ2V0QWxsQ29tbWFuZHMoKSB7CisJaWYgKGRhdGFTb3VyY2UgIT0gbnVsbCkKKwkgICAgcmV0dXJuIGdldENvbW1hbmRNYXAoKS5nZXRBbGxDb21tYW5kcyhnZXRCYXNlVHlwZSgpLCBkYXRhU291cmNlKTsKKwllbHNlCisJICAgIHJldHVybiBnZXRDb21tYW5kTWFwKCkuZ2V0QWxsQ29tbWFuZHMoZ2V0QmFzZVR5cGUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBjb21tYW5kIDxpPmNtZE5hbWU8L2k+LiBVc2UgdGhlIHNlYXJjaCBzZW1hbnRpY3MgYXMKKyAgICAgKiBkZWZpbmVkIGJ5IHRoZSBDb21tYW5kTWFwIGluc3RhbGxlZCBpbiB0aGlzIERhdGFIYW5kbGVyLiBUaGUKKyAgICAgKiBNSU1FIHR5cGUgZm9yIHRoZSB1bmRlcmx5aW5nIGRhdGEgcmVwcmVzZW50ZWQgYnkgdGhpcyBEYXRhSGFuZGxlcgorICAgICAqIGlzIHVzZWQgdG8gY2FsbCB0aHJvdWdoIHRvIHRoZSA8Y29kZT5nZXRDb21tYW5kPC9jb2RlPiBtZXRob2QKKyAgICAgKiBvZiB0aGUgQ29tbWFuZE1hcCBhc3NvY2lhdGVkIHdpdGggdGhpcyBEYXRhSGFuZGxlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjbWROYW1lCXRoZSBjb21tYW5kIG5hbWUKKyAgICAgKiBAcmV0dXJuCXRoZSBDb21tYW5kSW5mbyBjb3JyZXNwb25kaW5nIHRvIHRoZSBjb21tYW5kCisgICAgICoKKyAgICAgKiBAc2VlIGphdmF4LmFjdGl2YXRpb24uQ29tbWFuZE1hcCNnZXRDb21tYW5kCisgICAgICovCisgICAgcHVibGljIENvbW1hbmRJbmZvIGdldENvbW1hbmQoU3RyaW5nIGNtZE5hbWUpIHsKKwlpZiAoZGF0YVNvdXJjZSAhPSBudWxsKQorCSAgICByZXR1cm4gZ2V0Q29tbWFuZE1hcCgpLmdldENvbW1hbmQoZ2V0QmFzZVR5cGUoKSwgY21kTmFtZSwKKwkJCQkJCQkJZGF0YVNvdXJjZSk7CisJZWxzZQorCSAgICByZXR1cm4gZ2V0Q29tbWFuZE1hcCgpLmdldENvbW1hbmQoZ2V0QmFzZVR5cGUoKSwgY21kTmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBkYXRhIGluIGl0cyBwcmVmZXJyZWQgT2JqZWN0IGZvcm0uIDxwPgorICAgICAqCisgICAgICogSWYgdGhlIERhdGFIYW5kbGVyIHdhcyBpbnN0YW50aWF0ZWQgd2l0aCBhbiBvYmplY3QsIHJldHVybgorICAgICAqIHRoZSBvYmplY3QuIDxwPgorICAgICAqCisgICAgICogSWYgdGhlIERhdGFIYW5kbGVyIHdhcyBpbnN0YW50aWF0ZWQgd2l0aCBhIERhdGFTb3VyY2UsCisgICAgICogdGhpcyBtZXRob2QgdXNlcyBhIERhdGFDb250ZW50SGFuZGxlciB0byByZXR1cm4gdGhlIGNvbnRlbnQKKyAgICAgKiBvYmplY3QgZm9yIHRoZSBkYXRhIHJlcHJlc2VudGVkIGJ5IHRoaXMgRGF0YUhhbmRsZXIuIElmIG5vCisgICAgICogPGNvZGU+RGF0YUNvbnRlbnRIYW5kbGVyPC9jb2RlPiBjYW4gYmUgZm91bmQgZm9yIHRoZQorICAgICAqIHRoZSB0eXBlIG9mIHRoaXMgZGF0YSwgdGhlIERhdGFIYW5kbGVyIHJldHVybnMgYW4KKyAgICAgKiBJbnB1dFN0cmVhbSBmb3IgdGhlIGRhdGEuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBjb250ZW50LgorICAgICAqIEBleGNlcHRpb24gSU9FeGNlcHRpb24gaWYgYW4gSU9FeGNlcHRpb24gb2NjdXJzIGR1cmluZworICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcyBvcGVyYXRpb24uCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBnZXRDb250ZW50KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlpZiAob2JqZWN0ICE9IG51bGwpCisJICAgIHJldHVybiBvYmplY3Q7CisJZWxzZQorCSAgICByZXR1cm4gZ2V0RGF0YUNvbnRlbnRIYW5kbGVyKCkuZ2V0Q29udGVudChnZXREYXRhU291cmNlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEEgY29udmVuaWVuY2UgbWV0aG9kIHRoYXQgdGFrZXMgYSBDb21tYW5kSW5mbyBvYmplY3QKKyAgICAgKiBhbmQgaW5zdGFudGlhdGVzIHRoZSBjb3JyZXNwb25kaW5nIGNvbW1hbmQsIHVzdWFsbHkKKyAgICAgKiBhIEphdmFCZWFuIGNvbXBvbmVudC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIG1ldGhvZCBjYWxscyB0aGUgQ29tbWFuZEluZm8ncyA8Y29kZT5nZXRDb21tYW5kT2JqZWN0PC9jb2RlPgorICAgICAqIG1ldGhvZCB3aXRoIHRoZSA8Y29kZT5DbGFzc0xvYWRlcjwvY29kZT4gdXNlZCB0byBsb2FkCisgICAgICogdGhlIDxjb2RlPmphdmF4LmFjdGl2YXRpb24uRGF0YUhhbmRsZXI8L2NvZGU+IGNsYXNzIGl0c2VsZi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjbWRpbmZvCXRoZSBDb21tYW5kSW5mbyBjb3JyZXNwb25kaW5nIHRvIGEgY29tbWFuZAorICAgICAqIEByZXR1cm4JdGhlIGluc3RhbnRpYXRlZCBjb21tYW5kIG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZ2V0QmVhbihDb21tYW5kSW5mbyBjbWRpbmZvKSB7CisJT2JqZWN0IGJlYW4gPSBudWxsOworCisJdHJ5IHsKKwkgICAgLy8gbWFrZSB0aGUgYmVhbgorCSAgICBDbGFzc0xvYWRlciBjbGQgPSBudWxsOworCSAgICAvLyBGaXJzdCB0cnkgdGhlICJhcHBsaWNhdGlvbidzIiBjbGFzcyBsb2FkZXIuCisJICAgIGNsZCA9IFNlY3VyaXR5U3VwcG9ydC5nZXRDb250ZXh0Q2xhc3NMb2FkZXIoKTsKKwkgICAgaWYgKGNsZCA9PSBudWxsKQorCQljbGQgPSB0aGlzLmdldENsYXNzKCkuZ2V0Q2xhc3NMb2FkZXIoKTsKKwkgICAgYmVhbiA9IGNtZGluZm8uZ2V0Q29tbWFuZE9iamVjdCh0aGlzLCBjbGQpOworCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKwl9IGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGUpIHsgfQorCisJcmV0dXJuIGJlYW47CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBEYXRhQ29udGVudEhhbmRsZXIgZm9yIHRoaXMgRGF0YUhhbmRsZXI6IDxwPgorICAgICAqCisgICAgICogSWYgYSBEYXRhQ29udGVudEhhbmRsZXJGYWN0b3J5IGlzIHNldCwgdXNlIGl0LgorICAgICAqIE90aGVyd2lzZSBsb29rIGZvciBhbiBvYmplY3QgdG8gc2VydmUgRENIIGluIHRoZQorICAgICAqIGZvbGxvd2luZyBvcmRlcjogPHA+CisgICAgICoKKyAgICAgKiAxKSBpZiBhIGZhY3RvcnkgaXMgc2V0LCB1c2UgaXQgPHA+CisgICAgICogMikgaWYgYSBDb21tYW5kTWFwIGlzIHNldCwgdXNlIGl0IDxwPgorICAgICAqIDMpIHVzZSB0aGUgZGVmYXVsdCBDb21tYW5kTWFwIDxwPgorICAgICAqCisgICAgICogSW4gYW55IGNhc2UsIHdyYXAgdGhlIHJlYWwgRGF0YUNvbnRlbnRIYW5kbGVyIHdpdGggb25lIG9mIG91ciBvd24KKyAgICAgKiB0byBoYW5kbGUgYW55IG1pc3NpbmcgY2FzZXMsIGZpbGwgaW4gZGVmYXVsdHMsIGFuZCB0byBlbnN1cmUgdGhhdAorICAgICAqIHdlIGFsd2F5cyBoYXZlIGEgbm9uLW51bGwgRGF0YUNvbnRlbnRIYW5kbGVyLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgcmVxdWVzdGVkIERhdGFDb250ZW50SGFuZGxlcgorICAgICAqLworICAgIHByaXZhdGUgc3luY2hyb25pemVkIERhdGFDb250ZW50SGFuZGxlciBnZXREYXRhQ29udGVudEhhbmRsZXIoKSB7CisKKwkvLyBtYWtlIHN1cmUgdGhlIGZhY3RvcnkgZGlkbid0IGNoYW5nZQorCWlmIChmYWN0b3J5ICE9IG9sZEZhY3RvcnkpIHsKKwkgICAgb2xkRmFjdG9yeSA9IGZhY3Rvcnk7CisJICAgIGZhY3RvcnlEQ0ggPSBudWxsOworCSAgICBkYXRhQ29udGVudEhhbmRsZXIgPSBudWxsOworCSAgICB0cmFuc2ZlckZsYXZvcnMgPSBlbXB0eUZsYXZvcnM7CisJfQorCisgCWlmIChkYXRhQ29udGVudEhhbmRsZXIgIT0gbnVsbCkKKyAJICAgIHJldHVybiBkYXRhQ29udGVudEhhbmRsZXI7CisKKwlTdHJpbmcgc2ltcGxlTVQgPSBnZXRCYXNlVHlwZSgpOworCisJaWYgKGZhY3RvcnlEQ0ggPT0gbnVsbCAmJiBmYWN0b3J5ICE9IG51bGwpCisJICAgIGZhY3RvcnlEQ0ggPSBmYWN0b3J5LmNyZWF0ZURhdGFDb250ZW50SGFuZGxlcihzaW1wbGVNVCk7CisKKyAJaWYgKGZhY3RvcnlEQ0ggIT0gbnVsbCkKKyAJICAgIGRhdGFDb250ZW50SGFuZGxlciA9IGZhY3RvcnlEQ0g7CisKKwlpZiAoZGF0YUNvbnRlbnRIYW5kbGVyID09IG51bGwpIHsKKwkgICAgaWYgKGRhdGFTb3VyY2UgIT0gbnVsbCkKKwkJZGF0YUNvbnRlbnRIYW5kbGVyID0gZ2V0Q29tbWFuZE1hcCgpLgorCQkJCWNyZWF0ZURhdGFDb250ZW50SGFuZGxlcihzaW1wbGVNVCwgZGF0YVNvdXJjZSk7CisJICAgIGVsc2UKKwkJZGF0YUNvbnRlbnRIYW5kbGVyID0gZ2V0Q29tbWFuZE1hcCgpLgorCQkJCWNyZWF0ZURhdGFDb250ZW50SGFuZGxlcihzaW1wbGVNVCk7CisJfQorCisJLy8gZ2V0RGF0YUNvbnRlbnRIYW5kbGVyIGFsd2F5cyB1c2VzIHRoZXNlICd3cmFwcGVyJyBoYW5kbGVycworCS8vIHRvIG1ha2Ugc3VyZSBpdCByZXR1cm5zIFNPTUVUSElORyBtZWFuaW5nZnVsLi4uCisJaWYgKGRhdGFTb3VyY2UgIT0gbnVsbCkKKwkgICAgZGF0YUNvbnRlbnRIYW5kbGVyID0gbmV3IERhdGFTb3VyY2VEYXRhQ29udGVudEhhbmRsZXIoCisJCQkJCQkgICAgICBkYXRhQ29udGVudEhhbmRsZXIsCisJCQkJCQkgICAgICBkYXRhU291cmNlKTsKKwllbHNlCisJICAgIGRhdGFDb250ZW50SGFuZGxlciA9IG5ldyBPYmplY3REYXRhQ29udGVudEhhbmRsZXIoCisJCQkJCQkgICAgICBkYXRhQ29udGVudEhhbmRsZXIsCisJCQkJCQkgICAgICBvYmplY3QsCisJCQkJCQkgICAgICBvYmplY3RNaW1lVHlwZSk7CisJcmV0dXJuIGRhdGFDb250ZW50SGFuZGxlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVc2UgdGhlIE1pbWVUeXBlIGNsYXNzIHRvIGV4dHJhY3QgdGhlIE1JTUUgdHlwZS9zdWJ0eXBlLAorICAgICAqIGlnbm9yaW5nIHRoZSBwYXJhbWV0ZXJzLiAgVGhlIHR5cGUgaXMgY2FjaGVkLgorICAgICAqLworICAgIHByaXZhdGUgc3luY2hyb25pemVkIFN0cmluZyBnZXRCYXNlVHlwZSgpIHsKKwlpZiAoc2hvcnRUeXBlID09IG51bGwpIHsKKwkgICAgU3RyaW5nIGN0ID0gZ2V0Q29udGVudFR5cGUoKTsKKwkgICAgdHJ5IHsKKwkJTWltZVR5cGUgbXQgPSBuZXcgTWltZVR5cGUoY3QpOworCQlzaG9ydFR5cGUgPSBtdC5nZXRCYXNlVHlwZSgpOworCSAgICB9IGNhdGNoIChNaW1lVHlwZVBhcnNlRXhjZXB0aW9uIGUpIHsKKwkJc2hvcnRUeXBlID0gY3Q7CisJICAgIH0KKwl9CisJcmV0dXJuIHNob3J0VHlwZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBEYXRhQ29udGVudEhhbmRsZXJGYWN0b3J5LiAgVGhlIERhdGFDb250ZW50SGFuZGxlckZhY3RvcnkKKyAgICAgKiBpcyBjYWxsZWQgZmlyc3QgdG8gZmluZCBEYXRhQ29udGVudEhhbmRsZXJzLgorICAgICAqIFRoZSBEYXRhQ29udGVudEhhbmRsZXJGYWN0b3J5IGNhbiBvbmx5IGJlIHNldCBvbmNlLgorICAgICAqIDxwPgorICAgICAqIElmIHRoZSBEYXRhQ29udGVudEhhbmRsZXJGYWN0b3J5IGhhcyBhbHJlYWR5IGJlZW4gc2V0LAorICAgICAqIHRoaXMgbWV0aG9kIHRocm93cyBhbiBFcnJvci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuZXdGYWN0b3J5CXRoZSBEYXRhQ29udGVudEhhbmRsZXJGYWN0b3J5CisgICAgICogQGV4Y2VwdGlvbiBFcnJvcglpZiB0aGUgZmFjdG9yeSBoYXMgYWxyZWFkeSBiZWVuIGRlZmluZWQuCisgICAgICoKKyAgICAgKiBAc2VlIGphdmF4LmFjdGl2YXRpb24uRGF0YUNvbnRlbnRIYW5kbGVyRmFjdG9yeQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgc3luY2hyb25pemVkIHZvaWQgc2V0RGF0YUNvbnRlbnRIYW5kbGVyRmFjdG9yeSgKKwkJCQkJIERhdGFDb250ZW50SGFuZGxlckZhY3RvcnkgbmV3RmFjdG9yeSkgeworCWlmIChmYWN0b3J5ICE9IG51bGwpCisJICAgIHRocm93IG5ldyBFcnJvcigiRGF0YUNvbnRlbnRIYW5kbGVyRmFjdG9yeSBhbHJlYWR5IGRlZmluZWQiKTsKKworCVNlY3VyaXR5TWFuYWdlciBzZWN1cml0eSA9IFN5c3RlbS5nZXRTZWN1cml0eU1hbmFnZXIoKTsKKwlpZiAoc2VjdXJpdHkgIT0gbnVsbCkgeworCSAgICB0cnkgeworCQkvLyBpZiBpdCdzIG9rIHdpdGggdGhlIFNlY3VyaXR5TWFuYWdlciwgaXQncyBvayB3aXRoIG1lLi4uCisJCXNlY3VyaXR5LmNoZWNrU2V0RmFjdG9yeSgpOworCSAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBleCkgeworCQkvLyBvdGhlcndpc2UsIHdlIGFsc28gYWxsb3cgaXQgaWYgdGhpcyBjb2RlIGFuZCB0aGUKKwkJLy8gZmFjdG9yeSBjb21lIGZyb20gdGhlIHNhbWUgY2xhc3MgbG9hZGVyIChlLmcuLAorCQkvLyB0aGUgSkFGIGNsYXNzZXMgd2VyZSBsb2FkZWQgd2l0aCB0aGUgYXBwbGV0IGNsYXNzZXMpLgorCQlpZiAoRGF0YUhhbmRsZXIuY2xhc3MuZ2V0Q2xhc3NMb2FkZXIoKSAhPQorCQkJbmV3RmFjdG9yeS5nZXRDbGFzcygpLmdldENsYXNzTG9hZGVyKCkpCisJCSAgICB0aHJvdyBleDsKKwkgICAgfQorCX0KKwlmYWN0b3J5ID0gbmV3RmFjdG9yeTsKKyAgICB9Cit9CisKKy8qKgorICogVGhlIERhdGFIYW5kZXJEYXRhU291cmNlIGNsYXNzIGltcGxlbWVudHMgdGhlCisgKiBEYXRhU291cmNlIGludGVyZmFjZSB3aGVuIHRoZSBEYXRhSGFuZGxlciBpcyBjb25zdHJ1Y3RlZAorICogd2l0aCBhbiBPYmplY3QgYW5kIGEgbWltZVR5cGUgc3RyaW5nLgorICovCitjbGFzcyBEYXRhSGFuZGxlckRhdGFTb3VyY2UgaW1wbGVtZW50cyBEYXRhU291cmNlIHsKKyAgICBEYXRhSGFuZGxlciBkYXRhSGFuZGxlciA9IG51bGw7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY29uc3RydWN0b3IuCisgICAgICovCisgICAgcHVibGljIERhdGFIYW5kbGVyRGF0YVNvdXJjZShEYXRhSGFuZGxlciBkaCkgeworCXRoaXMuZGF0YUhhbmRsZXIgPSBkaDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGFuIDxjb2RlPklucHV0U3RyZWFtPC9jb2RlPiByZXByZXNlbnRpbmcgdGhpcyBvYmplY3QuCisgICAgICogQHJldHVybgl0aGUgPGNvZGU+SW5wdXRTdHJlYW08L2NvZGU+CisgICAgICovCisgICAgcHVibGljIElucHV0U3RyZWFtIGdldElucHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlyZXR1cm4gZGF0YUhhbmRsZXIuZ2V0SW5wdXRTdHJlYW0oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSA8Y29kZT5PdXRwdXRTdHJlYW08L2NvZGU+IGZvciB0aGlzIG9iamVjdC4KKyAgICAgKiBAcmV0dXJuCXRoZSA8Y29kZT5PdXRwdXRTdHJlYW08L2NvZGU+CisgICAgICovCisgICAgcHVibGljIE91dHB1dFN0cmVhbSBnZXRPdXRwdXRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworCXJldHVybiBkYXRhSGFuZGxlci5nZXRPdXRwdXRTdHJlYW0oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBNSU1FIHR5cGUgb2YgdGhlIGRhdGEgcmVwcmVzZW50ZWQgYnkgdGhpcyBvYmplY3QuCisgICAgICogQHJldHVybgl0aGUgTUlNRSB0eXBlCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRDb250ZW50VHlwZSgpIHsKKwlyZXR1cm4gZGF0YUhhbmRsZXIuZ2V0Q29udGVudFR5cGUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoaXMgb2JqZWN0LgorICAgICAqIEByZXR1cm4JdGhlIG5hbWUgb2YgdGhpcyBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7CisJcmV0dXJuIGRhdGFIYW5kbGVyLmdldE5hbWUoKTsgLy8gd2hhdCBlbHNlIHdvdWxkIGl0IGJlPworICAgIH0KK30KKworLyoKKyAqIERhdGFTb3VyY2VEYXRhQ29udGVudEhhbmRsZXIKKyAqCisgKiBUaGlzIGlzIGEgPGk+cHJpdmF0ZTwvaT4gRGF0YUNvbnRlbnRIYW5kbGVyIHRoYXQgd3JhcHMgdGhlIHJlYWwKKyAqIERhdGFDb250ZW50SGFuZGxlciBpbiB0aGUgY2FzZSB3aGVyZSB0aGUgRGF0YUhhbmRsZXIgd2FzIGluc3RhbnRpYXRlZAorICogd2l0aCBhIERhdGFTb3VyY2UuCisgKi8KK2NsYXNzIERhdGFTb3VyY2VEYXRhQ29udGVudEhhbmRsZXIgaW1wbGVtZW50cyBEYXRhQ29udGVudEhhbmRsZXIgeworICAgIHByaXZhdGUgRGF0YVNvdXJjZSBkcyA9IG51bGw7CisgICAgcHJpdmF0ZSBBY3RpdmF0aW9uRGF0YUZsYXZvciB0cmFuc2ZlckZsYXZvcnNbXSA9IG51bGw7CisgICAgcHJpdmF0ZSBEYXRhQ29udGVudEhhbmRsZXIgZGNoID0gbnVsbDsKKworICAgIC8qKgorICAgICAqIFRoZSBjb25zdHJ1Y3Rvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGF0YVNvdXJjZURhdGFDb250ZW50SGFuZGxlcihEYXRhQ29udGVudEhhbmRsZXIgZGNoLCBEYXRhU291cmNlIGRzKSB7CisJdGhpcy5kcyA9IGRzOworCXRoaXMuZGNoID0gZGNoOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgRGF0YUZsYXZvcnMgZm9yIHRoaXMgPGNvZGU+RGF0YUNvbnRlbnRIYW5kbGVyPC9jb2RlPi4KKyAgICAgKiBAcmV0dXJuCXRoZSBEYXRhRmxhdm9ycworICAgICAqLworICAgIHB1YmxpYyBBY3RpdmF0aW9uRGF0YUZsYXZvcltdIGdldFRyYW5zZmVyRGF0YUZsYXZvcnMoKSB7CisKKwlpZiAodHJhbnNmZXJGbGF2b3JzID09IG51bGwpIHsKKwkgICAgaWYgKGRjaCAhPSBudWxsKSB7IC8vIGlzIHRoZXJlIGEgZGNoPworCQl0cmFuc2ZlckZsYXZvcnMgPSBkY2guZ2V0VHJhbnNmZXJEYXRhRmxhdm9ycygpOworCSAgICB9IGVsc2UgeworCQl0cmFuc2ZlckZsYXZvcnMgPSBuZXcgQWN0aXZhdGlvbkRhdGFGbGF2b3JbMV07CisJCXRyYW5zZmVyRmxhdm9yc1swXSA9CisJCSAgICBuZXcgQWN0aXZhdGlvbkRhdGFGbGF2b3IoZHMuZ2V0Q29udGVudFR5cGUoKSwKKwkJCQkJICAgICBkcy5nZXRDb250ZW50VHlwZSgpKTsKKwkgICAgfQorCX0KKwlyZXR1cm4gdHJhbnNmZXJGbGF2b3JzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgVHJhbnNmZXIgRGF0YSBvZiB0eXBlIERhdGFGbGF2b3IgZnJvbSBJbnB1dFN0cmVhbS4KKyAgICAgKiBAcGFyYW0gZGYJdGhlIERhdGFGbGF2b3IKKyAgICAgKiBAcGFyYW0gZHMJdGhlIERhdGFTb3VyY2UKKyAgICAgKiBAcmV0dXJuCQl0aGUgY29uc3RydWN0ZWQgT2JqZWN0CisgICAgICovCisgICAgcHVibGljIE9iamVjdCBnZXRUcmFuc2ZlckRhdGEoQWN0aXZhdGlvbkRhdGFGbGF2b3IgZGYsIERhdGFTb3VyY2UgZHMpIHRocm93cworCQkJCS8qVW5zdXBwb3J0ZWRGbGF2b3JFeGNlcHRpb24sKi8gSU9FeGNlcHRpb24geworCisJaWYgKGRjaCAhPSBudWxsKQorCSAgICByZXR1cm4gZGNoLmdldFRyYW5zZmVyRGF0YShkZiwgZHMpOworCWVsc2UgaWYgKGRmLmVxdWFscyhnZXRUcmFuc2ZlckRhdGFGbGF2b3JzKClbMF0pKSAvLyBvbmx5IGhhdmUgb25lIG5vdworCSAgICByZXR1cm4gZHMuZ2V0SW5wdXRTdHJlYW0oKTsKKwllbHNlCisJICAgIC8vdGhyb3cgbmV3IFVuc3VwcG9ydGVkRmxhdm9yRXhjZXB0aW9uKGRmKTsKKwkgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJVbnN1cHBvcnRlZCBEYXRhRmxhdm9yOiAiICsgZGYpOworICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZ2V0Q29udGVudChEYXRhU291cmNlIGRzKSB0aHJvd3MgSU9FeGNlcHRpb24geworCisJaWYgKGRjaCAhPSBudWxsKQorCSAgICByZXR1cm4gZGNoLmdldENvbnRlbnQoZHMpOworCWVsc2UKKwkgICAgcmV0dXJuIGRzLmdldElucHV0U3RyZWFtKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGUgdGhlIG9iamVjdCB0byB0aGUgb3V0cHV0IHN0cmVhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKE9iamVjdCBvYmosIFN0cmluZyBtaW1lVHlwZSwgT3V0cHV0U3RyZWFtIG9zKQorCQkJCQkJdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlpZiAoZGNoICE9IG51bGwpCisJICAgIGRjaC53cml0ZVRvKG9iaiwgbWltZVR5cGUsIG9zKTsKKwllbHNlCisJICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZERhdGFUeXBlRXhjZXB0aW9uKAorCQkJIm5vIERDSCBmb3IgY29udGVudCB0eXBlICIgKyBkcy5nZXRDb250ZW50VHlwZSgpKTsKKyAgICB9Cit9CisKKy8qCisgKiBPYmplY3REYXRhQ29udGVudEhhbmRsZXIKKyAqCisgKiBUaGlzIGlzIGEgPGk+cHJpdmF0ZTwvaT4gRGF0YUNvbnRlbnRIYW5kbGVyIHRoYXQgd3JhcHMgdGhlIHJlYWwKKyAqIERhdGFDb250ZW50SGFuZGxlciBpbiB0aGUgY2FzZSB3aGVyZSB0aGUgRGF0YUhhbmRsZXIgd2FzIGluc3RhbnRpYXRlZAorICogd2l0aCBhbiBvYmplY3QuCisgKi8KK2NsYXNzIE9iamVjdERhdGFDb250ZW50SGFuZGxlciBpbXBsZW1lbnRzIERhdGFDb250ZW50SGFuZGxlciB7CisgICAgcHJpdmF0ZSBBY3RpdmF0aW9uRGF0YUZsYXZvciB0cmFuc2ZlckZsYXZvcnNbXSA9IG51bGw7CisgICAgcHJpdmF0ZSBPYmplY3Qgb2JqOworICAgIHByaXZhdGUgU3RyaW5nIG1pbWVUeXBlOworICAgIHByaXZhdGUgRGF0YUNvbnRlbnRIYW5kbGVyIGRjaCA9IG51bGw7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY29uc3RydWN0b3IuCisgICAgICovCisgICAgcHVibGljIE9iamVjdERhdGFDb250ZW50SGFuZGxlcihEYXRhQ29udGVudEhhbmRsZXIgZGNoLAorCQkJCSAgICBPYmplY3Qgb2JqLCBTdHJpbmcgbWltZVR5cGUpIHsKKwl0aGlzLm9iaiA9IG9iajsKKwl0aGlzLm1pbWVUeXBlID0gbWltZVR5cGU7CisJdGhpcy5kY2ggPSBkY2g7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBEYXRhQ29udGVudEhhbmRsZXIgZm9yIHRoaXMgb2JqZWN0LgorICAgICAqIFVzZWQgb25seSBieSB0aGUgRGF0YUhhbmRsZXIgY2xhc3MuCisgICAgICovCisgICAgcHVibGljIERhdGFDb250ZW50SGFuZGxlciBnZXREQ0goKSB7CisJcmV0dXJuIGRjaDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIERhdGFGbGF2b3JzIGZvciB0aGlzIDxjb2RlPkRhdGFDb250ZW50SGFuZGxlcjwvY29kZT4uCisgICAgICogQHJldHVybgl0aGUgRGF0YUZsYXZvcnMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIEFjdGl2YXRpb25EYXRhRmxhdm9yW10gZ2V0VHJhbnNmZXJEYXRhRmxhdm9ycygpIHsKKwlpZiAodHJhbnNmZXJGbGF2b3JzID09IG51bGwpIHsKKwkgICAgaWYgKGRjaCAhPSBudWxsKSB7CisJCXRyYW5zZmVyRmxhdm9ycyA9IGRjaC5nZXRUcmFuc2ZlckRhdGFGbGF2b3JzKCk7CisJICAgIH0gZWxzZSB7CisJCXRyYW5zZmVyRmxhdm9ycyA9IG5ldyBBY3RpdmF0aW9uRGF0YUZsYXZvclsxXTsKKwkJdHJhbnNmZXJGbGF2b3JzWzBdID0gbmV3IEFjdGl2YXRpb25EYXRhRmxhdm9yKG9iai5nZXRDbGFzcygpLAorCQkJCQkgICAgIG1pbWVUeXBlLCBtaW1lVHlwZSk7CisJICAgIH0KKwl9CisJcmV0dXJuIHRyYW5zZmVyRmxhdm9yczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIFRyYW5zZmVyIERhdGEgb2YgdHlwZSBEYXRhRmxhdm9yIGZyb20gSW5wdXRTdHJlYW0uCisgICAgICogQHBhcmFtIGRmCXRoZSBEYXRhRmxhdm9yCisgICAgICogQHBhcmFtIGRzCXRoZSBEYXRhU291cmNlCisgICAgICogQHJldHVybgkJdGhlIGNvbnN0cnVjdGVkIE9iamVjdAorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZ2V0VHJhbnNmZXJEYXRhKEFjdGl2YXRpb25EYXRhRmxhdm9yIGRmLCBEYXRhU291cmNlIGRzKQorCQkJCXRocm93cyAvKlVuc3VwcG9ydGVkRmxhdm9yRXhjZXB0aW9uLCovIElPRXhjZXB0aW9uIHsKKworCWlmIChkY2ggIT0gbnVsbCkKKwkgICAgcmV0dXJuIGRjaC5nZXRUcmFuc2ZlckRhdGEoZGYsIGRzKTsKKwllbHNlIGlmIChkZi5lcXVhbHMoZ2V0VHJhbnNmZXJEYXRhRmxhdm9ycygpWzBdKSkgLy8gb25seSBoYXZlIG9uZSBub3cKKwkgICAgcmV0dXJuIG9iajsKKwllbHNlCisJICAgIC8vdGhyb3cgbmV3IFVuc3VwcG9ydGVkRmxhdm9yRXhjZXB0aW9uKGRmKTsKKwkgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJVbnN1cHBvcnRlZCBEYXRhRmxhdm9yOiAiICsgZGYpOworCisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBnZXRDb250ZW50KERhdGFTb3VyY2UgZHMpIHsKKwlyZXR1cm4gb2JqOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlIHRoZSBvYmplY3QgdG8gdGhlIG91dHB1dCBzdHJlYW0uCisgICAgICovCisgICAgcHVibGljIHZvaWQgd3JpdGVUbyhPYmplY3Qgb2JqLCBTdHJpbmcgbWltZVR5cGUsIE91dHB1dFN0cmVhbSBvcykKKwkJCQkJCXRocm93cyBJT0V4Y2VwdGlvbiB7CisJaWYgKGRjaCAhPSBudWxsKQorCSAgICBkY2gud3JpdGVUbyhvYmosIG1pbWVUeXBlLCBvcyk7CisJZWxzZSBpZiAob2JqIGluc3RhbmNlb2YgYnl0ZVtdKQorCSAgICBvcy53cml0ZSgoYnl0ZVtdKW9iaik7CisJZWxzZSBpZiAob2JqIGluc3RhbmNlb2YgU3RyaW5nKSB7CisJICAgIE91dHB1dFN0cmVhbVdyaXRlciBvc3cgPSBuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKG9zKTsKKwkgICAgb3N3LndyaXRlKChTdHJpbmcpb2JqKTsKKwkgICAgb3N3LmZsdXNoKCk7CisJfSBlbHNlCisJICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZERhdGFUeXBlRXhjZXB0aW9uKAorCQkJCSJubyBvYmplY3QgRENIIGZvciBNSU1FIHR5cGUgIiArIHRoaXMubWltZVR5cGUpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2FuZHJvaWQvYWN0aXZhdGlvbi9zcmMvbWFpbi9qYXZhL2phdmF4L2FjdGl2YXRpb24vRGF0YVNvdXJjZS5qYXZhIGIvYW5kcm9pZC9hY3RpdmF0aW9uL3NyYy9tYWluL2phdmEvamF2YXgvYWN0aXZhdGlvbi9EYXRhU291cmNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmY5YmRiNQotLS0gL2Rldi9udWxsCisrKyBiL2FuZHJvaWQvYWN0aXZhdGlvbi9zcmMvbWFpbi9qYXZhL2phdmF4L2FjdGl2YXRpb24vRGF0YVNvdXJjZS5qYXZhCkBAIC0wLDAgKzEsNzEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorICovCisKK3BhY2thZ2UgamF2YXguYWN0aXZhdGlvbjsKKworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworLyoqCisgKiBUaGUgRGF0YVNvdXJjZSBpbnRlcmZhY2UgcHJvdmlkZXMgdGhlIEphdmFCZWFucyBBY3RpdmF0aW9uIEZyYW1ld29yaworICogd2l0aCBhbiBhYnN0cmFjdGlvbiBvZiBhbiBhcmJpdHJhcnkgY29sbGVjdGlvbiBvZiBkYXRhLiAgSXQKKyAqIHByb3ZpZGVzIGEgdHlwZSBmb3IgdGhhdCBkYXRhIGFzIHdlbGwgYXMgYWNjZXNzCisgKiB0byBpdCBpbiB0aGUgZm9ybSBvZiA8Y29kZT5JbnB1dFN0cmVhbXM8L2NvZGU+IGFuZAorICogPGNvZGU+T3V0cHV0U3RyZWFtczwvY29kZT4gd2hlcmUgYXBwcm9wcmlhdGUuCisgKi8KKworcHVibGljIGludGVyZmFjZSBEYXRhU291cmNlIHsKKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIHJldHVybnMgYW4gPGNvZGU+SW5wdXRTdHJlYW08L2NvZGU+IHJlcHJlc2VudGluZworICAgICAqIHRoZSBkYXRhIGFuZCB0aHJvd3MgdGhlIGFwcHJvcHJpYXRlIGV4Y2VwdGlvbiBpZiBpdCBjYW4KKyAgICAgKiBub3QgZG8gc28uICBOb3RlIHRoYXQgYSBuZXcgPGNvZGU+SW5wdXRTdHJlYW08L2NvZGU+IG9iamVjdCBtdXN0IGJlCisgICAgICogcmV0dXJuZWQgZWFjaCB0aW1lIHRoaXMgbWV0aG9kIGlzIGNhbGxlZCwgYW5kIHRoZSBzdHJlYW0gbXVzdCBiZQorICAgICAqIHBvc2l0aW9uZWQgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgZGF0YS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gSW5wdXRTdHJlYW0KKyAgICAgKiBAZXhjZXB0aW9uCUlPRXhjZXB0aW9uCWZvciBmYWlsdXJlcyBjcmVhdGluZyB0aGUgSW5wdXRTdHJlYW0KKyAgICAgKi8KKyAgICBwdWJsaWMgSW5wdXRTdHJlYW0gZ2V0SW5wdXRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCByZXR1cm5zIGFuIDxjb2RlPk91dHB1dFN0cmVhbTwvY29kZT4gd2hlcmUgdGhlCisgICAgICogZGF0YSBjYW4gYmUgd3JpdHRlbiBhbmQgdGhyb3dzIHRoZSBhcHByb3ByaWF0ZSBleGNlcHRpb24gaWYgaXQgY2FuCisgICAgICogbm90IGRvIHNvLiAgTm90ZSB0aGF0IGEgbmV3IDxjb2RlPk91dHB1dFN0cmVhbTwvY29kZT4gb2JqZWN0IG11c3QKKyAgICAgKiBiZSByZXR1cm5lZCBlYWNoIHRpbWUgdGhpcyBtZXRob2QgaXMgY2FsbGVkLCBhbmQgdGhlIHN0cmVhbSBtdXN0CisgICAgICogYmUgcG9zaXRpb25lZCBhdCB0aGUgbG9jYXRpb24gdGhlIGRhdGEgaXMgdG8gYmUgd3JpdHRlbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gT3V0cHV0U3RyZWFtCisgICAgICogQGV4Y2VwdGlvbglJT0V4Y2VwdGlvbglmb3IgZmFpbHVyZXMgY3JlYXRpbmcgdGhlIE91dHB1dFN0cmVhbQorICAgICAqLworICAgIHB1YmxpYyBPdXRwdXRTdHJlYW0gZ2V0T3V0cHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgcmV0dXJucyB0aGUgTUlNRSB0eXBlIG9mIHRoZSBkYXRhIGluIHRoZSBmb3JtIG9mIGEKKyAgICAgKiBzdHJpbmcuIEl0IHNob3VsZCBhbHdheXMgcmV0dXJuIGEgdmFsaWQgdHlwZS4gSXQgaXMgc3VnZ2VzdGVkCisgICAgICogdGhhdCBnZXRDb250ZW50VHlwZSByZXR1cm4gImFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSIgaWYgdGhlCisgICAgICogRGF0YVNvdXJjZSBpbXBsZW1lbnRhdGlvbiBjYW4gbm90IGRldGVybWluZSB0aGUgZGF0YSB0eXBlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgTUlNRSBUeXBlCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRDb250ZW50VHlwZSgpOworCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSA8aT5uYW1lPC9pPiBvZiB0aGlzIG9iamVjdCB3aGVyZSB0aGUgbmFtZSBvZiB0aGUgb2JqZWN0CisgICAgICogaXMgZGVwZW5kYW50IG9uIHRoZSBuYXR1cmUgb2YgdGhlIHVuZGVybHlpbmcgb2JqZWN0cy4gRGF0YVNvdXJjZXMKKyAgICAgKiBlbmNhcHN1bGF0aW5nIGZpbGVzIG1heSBjaG9vc2UgdG8gcmV0dXJuIHRoZSBmaWxlbmFtZSBvZiB0aGUgb2JqZWN0LgorICAgICAqIChUeXBpY2FsbHkgdGhpcyB3b3VsZCBiZSB0aGUgbGFzdCBjb21wb25lbnQgb2YgdGhlIGZpbGVuYW1lLCBub3QgYW4KKyAgICAgKiBlbnRpcmUgcGF0aG5hbWUuKQorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGUgb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpOworfQpkaWZmIC0tZ2l0IGEvYW5kcm9pZC9hY3RpdmF0aW9uL3NyYy9tYWluL2phdmEvamF2YXgvYWN0aXZhdGlvbi9GaWxlRGF0YVNvdXJjZS5qYXZhIGIvYW5kcm9pZC9hY3RpdmF0aW9uL3NyYy9tYWluL2phdmEvamF2YXgvYWN0aXZhdGlvbi9GaWxlRGF0YVNvdXJjZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMwNDg5MTgKLS0tIC9kZXYvbnVsbAorKysgYi9hbmRyb2lkL2FjdGl2YXRpb24vc3JjL21haW4vamF2YS9qYXZheC9hY3RpdmF0aW9uL0ZpbGVEYXRhU291cmNlLmphdmEKQEAgLTAsMCArMSwxNDEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorICovCisKK3BhY2thZ2UgamF2YXguYWN0aXZhdGlvbjsKKworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZURlc2NyaXB0b3I7CitpbXBvcnQgamF2YS5pby5GaWxlTm90Rm91bmRFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgY29tLnN1bi5hY3RpdmF0aW9uLnJlZ2lzdHJpZXMuTWltZVR5cGVGaWxlOworCisvKioKKyAqIFRoZSBGaWxlRGF0YVNvdXJjZSBjbGFzcyBpbXBsZW1lbnRzIGEgc2ltcGxlIERhdGFTb3VyY2Ugb2JqZWN0CisgKiB0aGF0IGVuY2Fwc3VsYXRlcyBhIGZpbGUuIEl0IHByb3ZpZGVzIGRhdGEgdHlwaW5nIHNlcnZpY2VzIHZpYQorICogYSBGaWxlVHlwZU1hcCBvYmplY3QuIDxwPgorICoKKyAqIDxiPkZpbGVEYXRhU291cmNlIFR5cGluZyBTZW1hbnRpY3M8L2I+PHA+CisgKgorICogVGhlIEZpbGVEYXRhU291cmNlIGNsYXNzIGRlbGVnYXRlcyBkYXRhIHR5cGluZyBvZiBmaWxlcworICogdG8gYW4gb2JqZWN0IHN1YmNsYXNzZWQgZnJvbSB0aGUgRmlsZVR5cGVNYXAgY2xhc3MuCisgKiBUaGUgPGNvZGU+c2V0RmlsZVR5cGVNYXA8L2NvZGU+IG1ldGhvZCBjYW4gYmUgdXNlZCB0byBleHBsaWNpdGx5CisgKiBzZXQgdGhlIEZpbGVUeXBlTWFwIGZvciBhbiBpbnN0YW5jZSBvZiBGaWxlRGF0YVNvdXJjZS4gSWYgbm8KKyAqIEZpbGVUeXBlTWFwIGlzIHNldCwgdGhlIEZpbGVEYXRhU291cmNlIHdpbGwgY2FsbCB0aGUgRmlsZVR5cGVNYXAncworICogZ2V0RGVmYXVsdEZpbGVUeXBlTWFwIG1ldGhvZCB0byBnZXQgdGhlIFN5c3RlbSdzIGRlZmF1bHQgRmlsZVR5cGVNYXAuCisgKgorICogQHNlZSBqYXZheC5hY3RpdmF0aW9uLkRhdGFTb3VyY2UKKyAqIEBzZWUgamF2YXguYWN0aXZhdGlvbi5GaWxlVHlwZU1hcAorICogQHNlZSBqYXZheC5hY3RpdmF0aW9uLk1pbWV0eXBlc0ZpbGVUeXBlTWFwCisgKi8KK3B1YmxpYyBjbGFzcyBGaWxlRGF0YVNvdXJjZSBpbXBsZW1lbnRzIERhdGFTb3VyY2UgeworCisgICAgLy8ga2VlcCB0cmFjayBvZiBvcmlnaW5hbCAncmVmJyBwYXNzZWQgaW4sIG5vbi1udWxsCisgICAgLy8gb25lIGluZGljYXRlZCB3aGljaCB3YXMgcGFzc2VkIGluOgorICAgIHByaXZhdGUgRmlsZSBfZmlsZSA9IG51bGw7CisgICAgcHJpdmF0ZSBGaWxlVHlwZU1hcCB0eXBlTWFwID0gbnVsbDsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBGaWxlRGF0YVNvdXJjZSBmcm9tIGEgRmlsZSBvYmplY3QuIDxpPk5vdGU6CisgICAgICogVGhlIGZpbGUgd2lsbCBub3QgYWN0dWFsbHkgYmUgb3BlbmVkIHVudGlsIGEgbWV0aG9kIGlzCisgICAgICogY2FsbGVkIHRoYXQgcmVxdWlyZXMgdGhlIGZpbGUgdG8gYmUgb3BlbmVkLjwvaT4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmaWxlIHRoZSBmaWxlCisgICAgICovCisgICAgcHVibGljIEZpbGVEYXRhU291cmNlKEZpbGUgZmlsZSkgeworCV9maWxlID0gZmlsZTsJLy8gc2F2ZSB0aGUgZmlsZSBPYmplY3QuLi4KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgRmlsZURhdGFTb3VyY2UgZnJvbQorICAgICAqIHRoZSBzcGVjaWZpZWQgcGF0aCBuYW1lLiA8aT5Ob3RlOgorICAgICAqIFRoZSBmaWxlIHdpbGwgbm90IGFjdHVhbGx5IGJlIG9wZW5lZCB1bnRpbCBhIG1ldGhvZCBpcworICAgICAqIGNhbGxlZCB0aGF0IHJlcXVpcmVzIHRoZSBmaWxlIHRvIGJlIG9wZW5lZC48L2k+CisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSB0aGUgc3lzdGVtLWRlcGVuZGVudCBmaWxlIG5hbWUuCisgICAgICovCisgICAgcHVibGljIEZpbGVEYXRhU291cmNlKFN0cmluZyBuYW1lKSB7CisJdGhpcyhuZXcgRmlsZShuYW1lKSk7CS8vIHVzZSB0aGUgZmlsZSBjb25zdHJ1Y3RvcgorICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuIGFuIElucHV0U3RyZWFtIHJlcHJlc2VudGluZyB0aGUKKyAgICAgKiB0aGUgZGF0YSBhbmQgd2lsbCB0aHJvdyBhbiBJT0V4Y2VwdGlvbiBpZiBpdCBjYW4KKyAgICAgKiBub3QgZG8gc28uIFRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuIGEgbmV3CisgICAgICogaW5zdGFuY2Ugb2YgSW5wdXRTdHJlYW0gd2l0aCBlYWNoIGludm9jYXRpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIElucHV0U3RyZWFtCisgICAgICovCisgICAgcHVibGljIElucHV0U3RyZWFtIGdldElucHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlyZXR1cm4gbmV3IEZpbGVJbnB1dFN0cmVhbShfZmlsZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2Qgd2lsbCByZXR1cm4gYW4gT3V0cHV0U3RyZWFtIHJlcHJlc2VudGluZyB0aGUKKyAgICAgKiB0aGUgZGF0YSBhbmQgd2lsbCB0aHJvdyBhbiBJT0V4Y2VwdGlvbiBpZiBpdCBjYW4KKyAgICAgKiBub3QgZG8gc28uIFRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuIGEgbmV3IGluc3RhbmNlIG9mCisgICAgICogT3V0cHV0U3RyZWFtIHdpdGggZWFjaCBpbnZvY2F0aW9uLgorICAgICAqCisgICAgICogQHJldHVybiBhbiBPdXRwdXRTdHJlYW0KKyAgICAgKi8KKyAgICBwdWJsaWMgT3V0cHV0U3RyZWFtIGdldE91dHB1dFN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJcmV0dXJuIG5ldyBGaWxlT3V0cHV0U3RyZWFtKF9maWxlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCByZXR1cm5zIHRoZSBNSU1FIHR5cGUgb2YgdGhlIGRhdGEgaW4gdGhlIGZvcm0gb2YgYQorICAgICAqIHN0cmluZy4gVGhpcyBtZXRob2QgdXNlcyB0aGUgY3VycmVudGx5IGluc3RhbGxlZCBGaWxlVHlwZU1hcC4gSWYKKyAgICAgKiB0aGVyZSBpcyBubyBGaWxlVHlwZU1hcCBleHBsaWN0bHkgc2V0LCB0aGUgRmlsZURhdGFTb3VyY2Ugd2lsbAorICAgICAqIGNhbGwgdGhlIDxjb2RlPmdldERlZmF1bHRGaWxlVHlwZU1hcDwvY29kZT4gbWV0aG9kIG9uCisgICAgICogRmlsZVR5cGVNYXAgdG8gYWNxdWlyZSBhIGRlZmF1bHQgRmlsZVR5cGVNYXAuIDxpPk5vdGU6IEJ5CisgICAgICogZGVmYXVsdCwgdGhlIEZpbGVUeXBlTWFwIHVzZWQgd2lsbCBiZSBhIE1pbWV0eXBlc0ZpbGVUeXBlTWFwLjwvaT4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIE1JTUUgVHlwZQorICAgICAqIEBzZWUgamF2YXguYWN0aXZhdGlvbi5GaWxlVHlwZU1hcCNnZXREZWZhdWx0RmlsZVR5cGVNYXAKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldENvbnRlbnRUeXBlKCkgeworCS8vIGNoZWNrIHRvIHNlZSBpZiB0aGUgdHlwZSBtYXAgaXMgbnVsbD8KKwlpZiAodHlwZU1hcCA9PSBudWxsKQorCSAgICByZXR1cm4gRmlsZVR5cGVNYXAuZ2V0RGVmYXVsdEZpbGVUeXBlTWFwKCkuZ2V0Q29udGVudFR5cGUoX2ZpbGUpOworCWVsc2UKKwkgICAgcmV0dXJuIHR5cGVNYXAuZ2V0Q29udGVudFR5cGUoX2ZpbGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgPGk+bmFtZTwvaT4gb2YgdGhpcyBvYmplY3QuIFRoZSBGaWxlRGF0YVNvdXJjZQorICAgICAqIHdpbGwgcmV0dXJuIHRoZSBmaWxlIG5hbWUgb2YgdGhlIG9iamVjdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5hbWUgb2YgdGhlIG9iamVjdC4KKyAgICAgKiBAc2VlIGphdmF4LmFjdGl2YXRpb24uRGF0YVNvdXJjZQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKKwlyZXR1cm4gX2ZpbGUuZ2V0TmFtZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgRmlsZSBvYmplY3QgdGhhdCBjb3JyZXNwb25kcyB0byB0aGlzIEZpbGVEYXRhU291cmNlLgorICAgICAqIEByZXR1cm4gdGhlIEZpbGUgb2JqZWN0IGZvciB0aGUgZmlsZSByZXByZXNlbnRlZCBieSB0aGlzIG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRmlsZSBnZXRGaWxlKCkgeworCXJldHVybiBfZmlsZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIEZpbGVUeXBlTWFwIHRvIHVzZSB3aXRoIHRoaXMgRmlsZURhdGFTb3VyY2UKKyAgICAgKgorICAgICAqIEBwYXJhbSBtYXAgVGhlIEZpbGVUeXBlTWFwIGZvciB0aGlzIG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRGaWxlVHlwZU1hcChGaWxlVHlwZU1hcCBtYXApIHsKKwl0eXBlTWFwID0gbWFwOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2FuZHJvaWQvYWN0aXZhdGlvbi9zcmMvbWFpbi9qYXZhL2phdmF4L2FjdGl2YXRpb24vRmlsZVR5cGVNYXAuamF2YSBiL2FuZHJvaWQvYWN0aXZhdGlvbi9zcmMvbWFpbi9qYXZhL2phdmF4L2FjdGl2YXRpb24vRmlsZVR5cGVNYXAuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42ODNmOTk4Ci0tLSAvZGV2L251bGwKKysrIGIvYW5kcm9pZC9hY3RpdmF0aW9uL3NyYy9tYWluL2phdmEvamF2YXgvYWN0aXZhdGlvbi9GaWxlVHlwZU1hcC5qYXZhCkBAIC0wLDAgKzEsMTE1IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBEaXN0cmlidXRpb24gTGljZW5zZSB2LiAxLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9vcmcvZG9jdW1lbnRzL2VkbC12MTAucGhwLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBCU0QtMy1DbGF1c2UKKyAqLworCitwYWNrYWdlIGphdmF4LmFjdGl2YXRpb247CisKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuV2Vha0hhc2hNYXA7CisKKy8qKgorICogVGhlIEZpbGVUeXBlTWFwIGlzIGFuIGFic3RyYWN0IGNsYXNzIHRoYXQgcHJvdmlkZXMgYSBkYXRhIHR5cGluZworICogaW50ZXJmYWNlIGZvciBmaWxlcy4gSW1wbGVtZW50YXRpb25zIG9mIHRoaXMgY2xhc3Mgd2lsbAorICogaW1wbGVtZW50IHRoZSBnZXRDb250ZW50VHlwZSBtZXRob2RzIHdoaWNoIHdpbGwgZGVyaXZlIGEgY29udGVudAorICogdHlwZSBmcm9tIGEgZmlsZSBuYW1lIG9yIGEgRmlsZSBvYmplY3QuIEZpbGVUeXBlTWFwcyBjb3VsZCB1c2UgYW55CisgKiBzY2hlbWUgdG8gZGV0ZXJtaW5lIHRoZSBkYXRhIHR5cGUsIGZyb20gZXhhbWluaW5nIHRoZSBmaWxlIGV4dGVuc2lvbgorICogb2YgYSBmaWxlIChsaWtlIHRoZSBNaW1ldHlwZXNGaWxlVHlwZU1hcCkgdG8gb3BlbmluZyB0aGUgZmlsZSBhbmQKKyAqIHRyeWluZyB0byBkZXJpdmUgaXRzIHR5cGUgZnJvbSB0aGUgY29udGVudHMgb2YgdGhlIGZpbGUuIFRoZQorICogRmlsZURhdGFTb3VyY2UgY2xhc3MgdXNlcyB0aGUgZGVmYXVsdCBGaWxlVHlwZU1hcCAoYSBNaW1ldHlwZXNGaWxlVHlwZU1hcAorICogdW5sZXNzIGNoYW5nZWQpIHRvIGRldGVybWluZSB0aGUgY29udGVudCB0eXBlIG9mIGZpbGVzLgorICoKKyAqIEBzZWUgamF2YXguYWN0aXZhdGlvbi5GaWxlVHlwZU1hcAorICogQHNlZSBqYXZheC5hY3RpdmF0aW9uLkZpbGVEYXRhU291cmNlCisgKiBAc2VlIGphdmF4LmFjdGl2YXRpb24uTWltZXR5cGVzRmlsZVR5cGVNYXAKKyAqLworCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgRmlsZVR5cGVNYXAgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgRmlsZVR5cGVNYXAgZGVmYXVsdE1hcCA9IG51bGw7CisgICAgcHJpdmF0ZSBzdGF0aWMgTWFwPENsYXNzTG9hZGVyLEZpbGVUeXBlTWFwPiBtYXAgPQorCQkJCW5ldyBXZWFrSGFzaE1hcDxDbGFzc0xvYWRlcixGaWxlVHlwZU1hcD4oKTsKKworICAgIC8qKgorICAgICAqIFRoZSBkZWZhdWx0IGNvbnN0cnVjdG9yLgorICAgICAqLworICAgIHB1YmxpYyBGaWxlVHlwZU1hcCgpIHsKKwlzdXBlcigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgdHlwZSBvZiB0aGUgZmlsZSBvYmplY3QuIFRoaXMgbWV0aG9kIHNob3VsZAorICAgICAqIGFsd2F5cyByZXR1cm4gYSB2YWxpZCBNSU1FIHR5cGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmlsZSBBIGZpbGUgdG8gYmUgdHlwZWQuCisgICAgICogQHJldHVybiBUaGUgY29udGVudCB0eXBlLgorICAgICAqLworICAgIGFic3RyYWN0IHB1YmxpYyBTdHJpbmcgZ2V0Q29udGVudFR5cGUoRmlsZSBmaWxlKTsKKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgdHlwZSBvZiB0aGUgZmlsZSBwYXNzZWQgaW4uICBUaGlzIG1ldGhvZCBzaG91bGQKKyAgICAgKiBhbHdheXMgcmV0dXJuIGEgdmFsaWQgTUlNRSB0eXBlLgorICAgICAqCisgICAgICogQHBhcmFtIGZpbGVuYW1lIHRoZSBwYXRobmFtZSBvZiB0aGUgZmlsZS4KKyAgICAgKiBAcmV0dXJuIFRoZSBjb250ZW50IHR5cGUuCisgICAgICovCisgICAgYWJzdHJhY3QgcHVibGljIFN0cmluZyBnZXRDb250ZW50VHlwZShTdHJpbmcgZmlsZW5hbWUpOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZGVmYXVsdCBGaWxlVHlwZU1hcCBmb3IgdGhlIHN5c3RlbS4gVGhpcyBpbnN0YW5jZQorICAgICAqIHdpbGwgYmUgcmV0dXJuZWQgdG8gY2FsbGVycyBvZiBnZXREZWZhdWx0RmlsZVR5cGVNYXAuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmlsZVR5cGVNYXAgVGhlIEZpbGVUeXBlTWFwLgorICAgICAqIEBleGNlcHRpb24gU2VjdXJpdHlFeGNlcHRpb24gaWYgdGhlIGNhbGxlciBkb2Vzbid0IGhhdmUgcGVybWlzc2lvbgorICAgICAqCQkJCQl0byBjaGFuZ2UgdGhlIGRlZmF1bHQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHN5bmNocm9uaXplZCB2b2lkIHNldERlZmF1bHRGaWxlVHlwZU1hcChGaWxlVHlwZU1hcCBmaWxlVHlwZU1hcCkgeworCVNlY3VyaXR5TWFuYWdlciBzZWN1cml0eSA9IFN5c3RlbS5nZXRTZWN1cml0eU1hbmFnZXIoKTsKKwlpZiAoc2VjdXJpdHkgIT0gbnVsbCkgeworCSAgICB0cnkgeworCQkvLyBpZiBpdCdzIG9rIHdpdGggdGhlIFNlY3VyaXR5TWFuYWdlciwgaXQncyBvayB3aXRoIG1lLi4uCisJCXNlY3VyaXR5LmNoZWNrU2V0RmFjdG9yeSgpOworCSAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBleCkgeworCQkvLyBvdGhlcndpc2UsIHdlIGFsc28gYWxsb3cgaXQgaWYgdGhpcyBjb2RlIGFuZCB0aGUKKwkJLy8gZmFjdG9yeSBjb21lIGZyb20gdGhlIHNhbWUgKG5vbi1zeXN0ZW0pIGNsYXNzIGxvYWRlciAoZS5nLiwKKwkJLy8gdGhlIEpBRiBjbGFzc2VzIHdlcmUgbG9hZGVkIHdpdGggdGhlIGFwcGxldCBjbGFzc2VzKS4KKwkJQ2xhc3NMb2FkZXIgY2wgPSBGaWxlVHlwZU1hcC5jbGFzcy5nZXRDbGFzc0xvYWRlcigpOworCQlpZiAoY2wgPT0gbnVsbCB8fCBjbC5nZXRQYXJlbnQoKSA9PSBudWxsIHx8CisJCSAgICBjbCAhPSBmaWxlVHlwZU1hcC5nZXRDbGFzcygpLmdldENsYXNzTG9hZGVyKCkpCisJCSAgICB0aHJvdyBleDsKKwkgICAgfQorCX0KKwkvLyByZW1vdmUgYW55IHBlci10aHJlYWQtY29udGV4dC1jbGFzcy1sb2FkZXIgRmlsZVR5cGVNYXAKKwltYXAucmVtb3ZlKFNlY3VyaXR5U3VwcG9ydC5nZXRDb250ZXh0Q2xhc3NMb2FkZXIoKSk7CisJZGVmYXVsdE1hcCA9IGZpbGVUeXBlTWFwOwkKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIGRlZmF1bHQgRmlsZVR5cGVNYXAgZm9yIHRoZSBzeXN0ZW0uCisgICAgICogSWYgc2V0RGVmYXVsdEZpbGVUeXBlTWFwIHdhcyBjYWxsZWQsIHJldHVybgorICAgICAqIHRoYXQgaW5zdGFuY2UsIG90aGVyd2lzZSByZXR1cm4gYW4gaW5zdGFuY2Ugb2YKKyAgICAgKiA8Y29kZT5NaW1ldHlwZXNGaWxlVHlwZU1hcDwvY29kZT4uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSBkZWZhdWx0IEZpbGVUeXBlTWFwCisgICAgICogQHNlZSBqYXZheC5hY3RpdmF0aW9uLkZpbGVUeXBlTWFwI3NldERlZmF1bHRGaWxlVHlwZU1hcAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgc3luY2hyb25pemVkIEZpbGVUeXBlTWFwIGdldERlZmF1bHRGaWxlVHlwZU1hcCgpIHsKKwlpZiAoZGVmYXVsdE1hcCAhPSBudWxsKQorCSAgICByZXR1cm4gZGVmYXVsdE1hcDsKKworCS8vIGZldGNoIHBlci10aHJlYWQtY29udGV4dC1jbGFzcy1sb2FkZXIgZGVmYXVsdAorCUNsYXNzTG9hZGVyIHRjY2wgPSBTZWN1cml0eVN1cHBvcnQuZ2V0Q29udGV4dENsYXNzTG9hZGVyKCk7CisJRmlsZVR5cGVNYXAgZGVmID0gbWFwLmdldCh0Y2NsKTsKKwlpZiAoZGVmID09IG51bGwpIHsKKwkgICAgZGVmID0gbmV3IE1pbWV0eXBlc0ZpbGVUeXBlTWFwKCk7CisJICAgIG1hcC5wdXQodGNjbCwgZGVmKTsKKwl9CisJcmV0dXJuIGRlZjsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hbmRyb2lkL2FjdGl2YXRpb24vc3JjL21haW4vamF2YS9qYXZheC9hY3RpdmF0aW9uL01haWxjYXBDb21tYW5kTWFwLmphdmEgYi9hbmRyb2lkL2FjdGl2YXRpb24vc3JjL21haW4vamF2YS9qYXZheC9hY3RpdmF0aW9uL01haWxjYXBDb21tYW5kTWFwLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjVlMDY3MgotLS0gL2Rldi9udWxsCisrKyBiL2FuZHJvaWQvYWN0aXZhdGlvbi9zcmMvbWFpbi9qYXZhL2phdmF4L2FjdGl2YXRpb24vTWFpbGNhcENvbW1hbmRNYXAuamF2YQpAQCAtMCwwICsxLDcwNyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgRGlzdHJpYnV0aW9uIExpY2Vuc2Ugdi4gMS4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvb3JnL2RvY3VtZW50cy9lZGwtdjEwLnBocC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQlNELTMtQ2xhdXNlCisgKi8KKworcGFja2FnZSBqYXZheC5hY3RpdmF0aW9uOworCitpbXBvcnQgamF2YS51dGlsLio7CitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmEubmV0Lio7CitpbXBvcnQgamF2YS5zZWN1cml0eS5BY2Nlc3NDb250cm9sbGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmlsZWdlZEFjdGlvbjsKK2ltcG9ydCBjb20uc3VuLmFjdGl2YXRpb24ucmVnaXN0cmllcy5NYWlsY2FwRmlsZTsKK2ltcG9ydCBjb20uc3VuLmFjdGl2YXRpb24ucmVnaXN0cmllcy5Mb2dTdXBwb3J0OworCisvKioKKyAqIE1haWxjYXBDb21tYW5kTWFwIGV4dGVuZHMgdGhlIENvbW1hbmRNYXAKKyAqIGFic3RyYWN0IGNsYXNzLiBJdCBpbXBsZW1lbnRzIGEgQ29tbWFuZE1hcCB3aG9zZSBjb25maWd1cmF0aW9uCisgKiBpcyBiYXNlZCBvbiBtYWlsY2FwIGZpbGVzCisgKiAoPEEgSFJFRj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMTUyNC50eHQiPlJGQyAxNTI0PC9BPikuCisgKiBUaGUgTWFpbGNhcENvbW1hbmRNYXAgY2FuIGJlIGNvbmZpZ3VyZWQgYm90aCBwcm9ncmFtbWF0aWNhbGx5CisgKiBhbmQgdmlhIGNvbmZpZ3VyYXRpb24gZmlsZXMuCisgKiA8cD4KKyAqIDxiPk1haWxjYXAgZmlsZSBzZWFyY2ggb3JkZXI6PC9iPjxwPgorICogVGhlIE1haWxjYXBDb21tYW5kTWFwIGxvb2tzIGluIHZhcmlvdXMgcGxhY2VzIGluIHRoZSB1c2VyJ3MKKyAqIHN5c3RlbSBmb3IgbWFpbGNhcCBmaWxlIGVudHJpZXMuIFdoZW4gcmVxdWVzdHMgYXJlIG1hZGUKKyAqIHRvIHNlYXJjaCBmb3IgY29tbWFuZHMgaW4gdGhlIE1haWxjYXBDb21tYW5kTWFwLCBpdCBzZWFyY2hlcyAgCisgKiBtYWlsY2FwIGZpbGVzIGluIHRoZSBmb2xsb3dpbmcgb3JkZXI6CisgKiA8b2w+CisgKiA8bGk+IFByb2dyYW1hdGljYWxseSBhZGRlZCBlbnRyaWVzIHRvIHRoZSBNYWlsY2FwQ29tbWFuZE1hcCBpbnN0YW5jZS4KKyAqIDxsaT4gVGhlIGZpbGUgPGNvZGU+Lm1haWxjYXA8L2NvZGU+IGluIHRoZSB1c2VyJ3MgaG9tZSBkaXJlY3RvcnkuCisgKiA8bGk+IFRoZSBmaWxlIDxjb2RlPm1haWxjYXA8L2NvZGU+IGluIHRoZSBKYXZhIHJ1bnRpbWUuCisgKiA8bGk+IFRoZSBmaWxlIG9yIHJlc291cmNlcyBuYW1lZCA8Y29kZT5NRVRBLUlORi9tYWlsY2FwPC9jb2RlPi4KKyAqIDxsaT4gVGhlIGZpbGUgb3IgcmVzb3VyY2UgbmFtZWQgPGNvZGU+TUVUQS1JTkYvbWFpbGNhcC5kZWZhdWx0PC9jb2RlPgorICogKHVzdWFsbHkgZm91bmQgb25seSBpbiB0aGUgPGNvZGU+YWN0aXZhdGlvbi5qYXI8L2NvZGU+IGZpbGUpLgorICogPC9vbD4KKyAqIDxwPgorICogKFRoZSBjdXJyZW50IGltcGxlbWVudGF0aW9uIGxvb2tzIGZvciB0aGUgPGNvZGU+bWFpbGNhcDwvY29kZT4gZmlsZQorICogaW4gdGhlIEphdmEgcnVudGltZSBpbiB0aGUgZGlyZWN0b3J5IDxjb2RlPjxpPmphdmEuaG9tZTwvaT4vY29uZjwvY29kZT4KKyAqIGlmIGl0IGV4aXN0cywgYW5kIG90aGVyd2lzZSBpbiB0aGUgZGlyZWN0b3J5CisgKiA8Y29kZT48aT5qYXZhLmhvbWU8L2k+L2xpYjwvY29kZT4sIHdoZXJlIDxpPmphdmEuaG9tZTwvaT4gaXMgdGhlIHZhbHVlCisgKiBvZiB0aGUgImphdmEuaG9tZSIgU3lzdGVtIHByb3BlcnR5LiAgTm90ZSB0aGF0IHRoZSAiY29uZiIgZGlyZWN0b3J5IHdhcworICogaW50cm9kdWNlZCBpbiBKREsgOS4pCisgKiA8cD4KKyAqIDxiPk1haWxjYXAgZmlsZSBmb3JtYXQ6PC9iPjxwPgorICoKKyAqIE1haWxjYXAgZmlsZXMgbXVzdCBjb25mb3JtIHRvIHRoZSBtYWlsY2FwCisgKiBmaWxlIHNwZWNpZmljYXRpb24gKFJGQyAxNTI0LCA8aT5BIFVzZXIgQWdlbnQgQ29uZmlndXJhdGlvbiBNZWNoYW5pc20KKyAqIEZvciBNdWx0aW1lZGlhIE1haWwgRm9ybWF0IEluZm9ybWF0aW9uPC9pPikuIAorICogVGhlIGZpbGUgZm9ybWF0IGNvbnNpc3RzIG9mIGVudHJpZXMgY29ycmVzcG9uZGluZyB0bworICogcGFydGljdWxhciBNSU1FIHR5cGVzLiBJbiBnZW5lcmFsLCB0aGUgc3BlY2lmaWNhdGlvbiAKKyAqIHNwZWNpZmllcyA8aT5hcHBsaWNhdGlvbnM8L2k+IGZvciBjbGllbnRzIHRvIHVzZSB3aGVuIHRoZXkKKyAqIHRoZW1zZWx2ZXMgY2Fubm90IG9wZXJhdGUgb24gdGhlIHNwZWNpZmllZCBNSU1FIHR5cGUuIFRoZSAKKyAqIE1haWxjYXBDb21tYW5kTWFwIGV4dGVuZHMgdGhpcyBzcGVjaWZpY2F0aW9uIGJ5IHVzaW5nIGEgcGFyYW1ldGVyIG1lY2hhbmlzbQorICogaW4gbWFpbGNhcCBmaWxlcyB0aGF0IGFsbG93cyBKYXZhQmVhbnModG0pIGNvbXBvbmVudHMgdG8gYmUgc3BlY2lmaWVkIGFzCisgKiBjb3JyZXNwb25kaW5nIHRvIHBhcnRpY3VsYXIgY29tbWFuZHMgZm9yIGEgTUlNRSB0eXBlLjxwPgorICoKKyAqIFdoZW4gYSBtYWlsY2FwIGZpbGUgaXMKKyAqIHBhcnNlZCwgdGhlIE1haWxjYXBDb21tYW5kTWFwIHJlY29nbml6ZXMgY2VydGFpbiBwYXJhbWV0ZXIgc2lnbmF0dXJlcywKKyAqIHNwZWNpZmljYWxseSB0aG9zZSBwYXJhbWV0ZXIgbmFtZXMgdGhhdCBiZWdpbiB3aXRoIDxjb2RlPngtamF2YS08L2NvZGU+LgorICogVGhlIE1haWxjYXBDb21tYW5kTWFwIHVzZXMgdGhpcyBzaWduYXR1cmUgdG8gZmluZAorICogY29tbWFuZCBlbnRyaWVzIGZvciBpbmNsdXNpb24gaW50byBpdHMgcmVnaXN0cmllcy4KKyAqIFBhcmFtZXRlciBuYW1lcyB3aXRoIHRoZSBmb3JtIDxjb2RlPngtamF2YS0mbHQ7bmFtZSZndDs8L2NvZGU+CisgKiBhcmUgcmVhZCBieSB0aGUgTWFpbGNhcENvbW1hbmRNYXAgYXMgaWRlbnRpZnlpbmcgYSBjb21tYW5kCisgKiB3aXRoIHRoZSBuYW1lIDxpPm5hbWU8L2k+LiBXaGVuIHRoZSA8aT5uYW1lPC9pPiBpcyA8Y29kZT4KKyAqIGNvbnRlbnQtaGFuZGxlcjwvY29kZT4gdGhlIE1haWxjYXBDb21tYW5kTWFwIHJlY29nbml6ZXMgdGhlIGNsYXNzCisgKiBzaWduaWZpZWQgYnkgdGhpcyBwYXJhbWV0ZXIgYXMgYSA8aT5EYXRhQ29udGVudEhhbmRsZXI8L2k+LgorICogQWxsIG90aGVyIGNvbW1hbmRzIGFyZSBoYW5kbGVkIGdlbmVyaWNhbGx5IHJlZ2FyZGxlc3Mgb2YgY29tbWFuZCAKKyAqIG5hbWUuIFRoZSBjb21tYW5kIGltcGxlbWVudGF0aW9uIGlzIHNwZWNpZmllZCBieSBhIGZ1bGx5IHF1YWxpZmllZAorICogY2xhc3MgbmFtZSBvZiBhIEphdmFCZWFuKHRtKSBjb21wb25lbnQuIEZvciBleGFtcGxlOyBhIGNvbW1hbmQgZm9yIHZpZXdpbmcKKyAqIHNvbWUgZGF0YSBjYW4gYmUgc3BlY2lmaWVkIGFzOiA8Y29kZT54LWphdmEtdmlldz1jb20uZm9vLlZpZXdCZWFuPC9jb2RlPi48cD4KKyAqCisgKiBXaGVuIHRoZSBjb21tYW5kIG5hbWUgaXMgPGNvZGU+ZmFsbGJhY2stZW50cnk8L2NvZGU+LCB0aGUgdmFsdWUgb2YKKyAqIHRoZSBjb21tYW5kIG1heSBiZSA8Y29kZT50cnVlPC9jb2RlPiBvciA8Y29kZT5mYWxzZTwvY29kZT4uICBBbgorICogZW50cnkgZm9yIGEgTUlNRSB0eXBlIHRoYXQgaW5jbHVkZXMgYSBwYXJhbWV0ZXIgb2YKKyAqIDxjb2RlPngtamF2YS1mYWxsYmFjay1lbnRyeT10cnVlPC9jb2RlPiBkZWZpbmVzIGZhbGxiYWNrIGNvbW1hbmRzCisgKiBmb3IgdGhhdCBNSU1FIHR5cGUgdGhhdCB3aWxsIG9ubHkgYmUgdXNlZCBpZiBubyBub24tZmFsbGJhY2sgZW50cnkKKyAqIGNhbiBiZSBmb3VuZC4gIEZvciBleGFtcGxlLCBhbiBlbnRyeSBvZiB0aGUgZm9ybSA8Y29kZT50ZXh0Lyo7IDsKKyAqIHgtamF2YS1mYWxsYmFjay1lbnRyeT10cnVlOyB4LWphdmEtdmlldz1jb20uc3VuLlRleHRWaWV3ZXI8L2NvZGU+CisgKiBzcGVjaWZpZXMgYSB2aWV3IGNvbW1hbmQgdG8gYmUgdXNlZCBmb3IgYW55IHRleHQgTUlNRSB0eXBlLiAgVGhpcworICogdmlldyBjb21tYW5kIHdvdWxkIG9ubHkgYmUgdXNlZCBpZiBhIG5vbi1mYWxsYmFjayB2aWV3IGNvbW1hbmQgZm9yCisgKiB0aGUgTUlNRSB0eXBlIGNvdWxkIG5vdCBiZSBmb3VuZC48cD4KKyAqIAorICogTWFpbGNhcENvbW1hbmRNYXAgYXdhcmUgbWFpbGNhcCBmaWxlcyBoYXZlIHRoZSAKKyAqIGZvbGxvd2luZyBnZW5lcmFsIGZvcm06PHA+CisgKiA8Y29kZT4KKyAqICMgQ29tbWVudHMgYmVnaW4gd2l0aCBhICcjJyBhbmQgY29udGludWUgdG8gdGhlIGVuZCBvZiB0aGUgbGluZS48YnI+CisgKiAmbHQ7bWltZSB0eXBlJmd0OzsgOyAmbHQ7cGFyYW1ldGVyIGxpc3QmZ3Q7PGJyPgorICogIyBXaGVyZSBhIHBhcmFtZXRlciBsaXN0IGNvbnNpc3RzIG9mIG9uZSBvciBtb3JlIHBhcmFtZXRlcnMsPGJyPgorICogIyB3aGVyZSBwYXJhbWV0ZXJzIGxvb2sgbGlrZTogeC1qYXZhLXZpZXc9Y29tLnN1bi5UZXh0Vmlld2VyPGJyPgorICogIyBhbmQgYSBwYXJhbWV0ZXIgbGlzdCBsb29rcyBsaWtlOiA8YnI+CisgKiB0ZXh0L3BsYWluOyA7IHgtamF2YS12aWV3PWNvbS5zdW4uVGV4dFZpZXdlcjsgeC1qYXZhLWVkaXQ9Y29tLnN1bi5UZXh0RWRpdAorICogPGJyPgorICogIyBOb3RlIHRoYXQgbWFpbGNhcCBlbnRyaWVzIHRoYXQgZG8gbm90IGNvbnRhaW4gJ3gtamF2YScgcGFyYW1ldGVyczxicj4KKyAqICMgYW5kIGNvbXBseSB0byBSRkMgMTUyNCBhcmUgc2ltcGx5IGlnbm9yZWQ6PGJyPgorICogaW1hZ2UvZ2lmOyAvdXNyL2R0L2Jpbi9zZHRpbWFnZSAlczxicj4KKyAqCisgKiA8L2NvZGU+CisgKiA8cD4KKyAqCisgKiBAYXV0aG9yIEJhcnQgQ2FsZGVyCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCisKK3B1YmxpYyBjbGFzcyBNYWlsY2FwQ29tbWFuZE1hcCBleHRlbmRzIENvbW1hbmRNYXAgeworICAgIC8qCisgICAgICogV2UgbWFuYWdlIGEgY29sbGVjdGlvbiBvZiBkYXRhYmFzZXMsIHNlYXJjaGVkIGluIG9yZGVyLgorICAgICAqLworICAgIHByaXZhdGUgTWFpbGNhcEZpbGVbXSBEQjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUFJPRyA9IDA7CS8vIHByb2dyYW1tYXRpY2FsbHkgYWRkZWQgZW50cmllcworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIGNvbmZEaXI7CisKKyAgICBzdGF0aWMgeworCVN0cmluZyBkaXIgPSBudWxsOworCXRyeSB7CisJICAgIGRpciA9IChTdHJpbmcpQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQoCisJCW5ldyBQcml2aWxlZ2VkQWN0aW9uKCkgeworCQkgICAgcHVibGljIE9iamVjdCBydW4oKSB7CisJCQlTdHJpbmcgaG9tZSA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS5ob21lIik7CisJCQlTdHJpbmcgbmV3ZGlyID0gaG9tZSArIEZpbGUuc2VwYXJhdG9yICsgImNvbmYiOworCQkJRmlsZSBjb25mID0gbmV3IEZpbGUobmV3ZGlyKTsKKwkJCWlmIChjb25mLmV4aXN0cygpKQorCQkJICAgIHJldHVybiBuZXdkaXIgKyBGaWxlLnNlcGFyYXRvcjsKKwkJCWVsc2UKKwkJCSAgICByZXR1cm4gaG9tZSArIEZpbGUuc2VwYXJhdG9yICsgImxpYiIgKyBGaWxlLnNlcGFyYXRvcjsKKwkJICAgIH0KKwkJfSk7CisJfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJICAgIC8vIGlnbm9yZSBhbnkgZXhjZXB0aW9ucworCX0KKwljb25mRGlyID0gZGlyOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBkZWZhdWx0IENvbnN0cnVjdG9yLgorICAgICAqLworICAgIHB1YmxpYyBNYWlsY2FwQ29tbWFuZE1hcCgpIHsKKwlzdXBlcigpOworCUxpc3QgZGJ2ID0gbmV3IEFycmF5TGlzdCg1KTsJLy8gdXN1YWxseSA1IG9yIGxlc3MgZGF0YWJhc2VzCisJTWFpbGNhcEZpbGUgbWYgPSBudWxsOworCWRidi5hZGQobnVsbCk7CQkvLyBwbGFjZSBob2xkZXIgZm9yIFBST0cgZW50cnkKKworCUxvZ1N1cHBvcnQubG9nKCJNYWlsY2FwQ29tbWFuZE1hcDogbG9hZCBIT01FIik7CisJdHJ5IHsKKwkgICAgU3RyaW5nIHVzZXJfaG9tZSA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgidXNlci5ob21lIik7CisKKwkgICAgaWYgKHVzZXJfaG9tZSAhPSBudWxsKSB7CisJCVN0cmluZyBwYXRoID0gdXNlcl9ob21lICsgRmlsZS5zZXBhcmF0b3IgKyAiLm1haWxjYXAiOworCQltZiA9IGxvYWRGaWxlKHBhdGgpOworCQlpZiAobWYgIT0gbnVsbCkKKwkJICAgIGRidi5hZGQobWYpOworCSAgICB9CisJfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gZXgpIHt9CisKKwlMb2dTdXBwb3J0LmxvZygiTWFpbGNhcENvbW1hbmRNYXA6IGxvYWQgU1lTIik7CisJdHJ5IHsKKwkgICAgLy8gY2hlY2sgc3lzdGVtJ3MgaG9tZQorCSAgICBpZiAoY29uZkRpciAhPSBudWxsKSB7CisJCW1mID0gbG9hZEZpbGUoY29uZkRpciArICJtYWlsY2FwIik7CisJCWlmIChtZiAhPSBudWxsKQorCQkgICAgZGJ2LmFkZChtZik7CisJICAgIH0KKwl9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBleCkge30KKworCUxvZ1N1cHBvcnQubG9nKCJNYWlsY2FwQ29tbWFuZE1hcDogbG9hZCBKQVIiKTsKKwkvLyBsb2FkIGZyb20gdGhlIGFwcCdzIGphciBmaWxlCisJbG9hZEFsbFJlc291cmNlcyhkYnYsICJNRVRBLUlORi9tYWlsY2FwIik7CisKKwlMb2dTdXBwb3J0LmxvZygiTWFpbGNhcENvbW1hbmRNYXA6IGxvYWQgREVGIik7CisJbWYgPSBsb2FkUmVzb3VyY2UoIi9NRVRBLUlORi9tYWlsY2FwLmRlZmF1bHQiKTsKKworCWlmIChtZiAhPSBudWxsKQorCSAgICBkYnYuYWRkKG1mKTsKKworCURCID0gbmV3IE1haWxjYXBGaWxlW2Ridi5zaXplKCldOworCURCID0gKE1haWxjYXBGaWxlW10pZGJ2LnRvQXJyYXkoREIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIExvYWQgZnJvbSB0aGUgbmFtZWQgcmVzb3VyY2UuCisgICAgICovCisgICAgcHJpdmF0ZSBNYWlsY2FwRmlsZSBsb2FkUmVzb3VyY2UoU3RyaW5nIG5hbWUpIHsKKwlJbnB1dFN0cmVhbSBjbGlzID0gbnVsbDsKKwl0cnkgeworCSAgICBjbGlzID0gU2VjdXJpdHlTdXBwb3J0LmdldFJlc291cmNlQXNTdHJlYW0odGhpcy5nZXRDbGFzcygpLCBuYW1lKTsKKwkgICAgaWYgKGNsaXMgIT0gbnVsbCkgeworCQlNYWlsY2FwRmlsZSBtZiA9IG5ldyBNYWlsY2FwRmlsZShjbGlzKTsKKwkJaWYgKExvZ1N1cHBvcnQuaXNMb2dnYWJsZSgpKQorCQkgICAgTG9nU3VwcG9ydC5sb2coIk1haWxjYXBDb21tYW5kTWFwOiBzdWNjZXNzZnVsbHkgbG9hZGVkICIgKworCQkJIm1haWxjYXAgZmlsZTogIiArIG5hbWUpOworCQlyZXR1cm4gbWY7CisJICAgIH0gZWxzZSB7CisJCWlmIChMb2dTdXBwb3J0LmlzTG9nZ2FibGUoKSkKKwkJICAgIExvZ1N1cHBvcnQubG9nKCJNYWlsY2FwQ29tbWFuZE1hcDogbm90IGxvYWRpbmcgIiArCisJCQkibWFpbGNhcCBmaWxlOiAiICsgbmFtZSk7CisJICAgIH0KKwl9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisJICAgIGlmIChMb2dTdXBwb3J0LmlzTG9nZ2FibGUoKSkKKwkJTG9nU3VwcG9ydC5sb2coIk1haWxjYXBDb21tYW5kTWFwOiBjYW4ndCBsb2FkICIgKyBuYW1lLCBlKTsKKwl9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBzZXgpIHsKKwkgICAgaWYgKExvZ1N1cHBvcnQuaXNMb2dnYWJsZSgpKQorCQlMb2dTdXBwb3J0LmxvZygiTWFpbGNhcENvbW1hbmRNYXA6IGNhbid0IGxvYWQgIiArIG5hbWUsIHNleCk7CisJfSBmaW5hbGx5IHsKKwkgICAgdHJ5IHsKKwkJaWYgKGNsaXMgIT0gbnVsbCkKKwkJICAgIGNsaXMuY2xvc2UoKTsKKwkgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsgfQkvLyBpZ25vcmUgaXQKKwl9CisJcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogTG9hZCBhbGwgb2YgdGhlIG5hbWVkIHJlc291cmNlLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBsb2FkQWxsUmVzb3VyY2VzKExpc3QgdiwgU3RyaW5nIG5hbWUpIHsKKwlib29sZWFuIGFueUxvYWRlZCA9IGZhbHNlOworCXRyeSB7CisJICAgIFVSTFtdIHVybHM7CisJICAgIENsYXNzTG9hZGVyIGNsZCA9IG51bGw7CisJICAgIC8vIEZpcnN0IHRyeSB0aGUgImFwcGxpY2F0aW9uJ3MiIGNsYXNzIGxvYWRlci4KKwkgICAgY2xkID0gU2VjdXJpdHlTdXBwb3J0LmdldENvbnRleHRDbGFzc0xvYWRlcigpOworCSAgICBpZiAoY2xkID09IG51bGwpCisJCWNsZCA9IHRoaXMuZ2V0Q2xhc3MoKS5nZXRDbGFzc0xvYWRlcigpOworCSAgICBpZiAoY2xkICE9IG51bGwpCisJCXVybHMgPSBTZWN1cml0eVN1cHBvcnQuZ2V0UmVzb3VyY2VzKGNsZCwgbmFtZSk7CisJICAgIGVsc2UKKwkJdXJscyA9IFNlY3VyaXR5U3VwcG9ydC5nZXRTeXN0ZW1SZXNvdXJjZXMobmFtZSk7CisJICAgIGlmICh1cmxzICE9IG51bGwpIHsKKwkJaWYgKExvZ1N1cHBvcnQuaXNMb2dnYWJsZSgpKQorCQkgICAgTG9nU3VwcG9ydC5sb2coIk1haWxjYXBDb21tYW5kTWFwOiBnZXRSZXNvdXJjZXMiKTsKKwkJZm9yIChpbnQgaSA9IDA7IGkgPCB1cmxzLmxlbmd0aDsgaSsrKSB7CisJCSAgICBVUkwgdXJsID0gdXJsc1tpXTsKKwkJICAgIElucHV0U3RyZWFtIGNsaXMgPSBudWxsOworCQkgICAgaWYgKExvZ1N1cHBvcnQuaXNMb2dnYWJsZSgpKQorCQkJTG9nU3VwcG9ydC5sb2coIk1haWxjYXBDb21tYW5kTWFwOiBVUkwgIiArIHVybCk7CisJCSAgICB0cnkgeworCQkJY2xpcyA9IFNlY3VyaXR5U3VwcG9ydC5vcGVuU3RyZWFtKHVybCk7CisJCQlpZiAoY2xpcyAhPSBudWxsKSB7CisJCQkgICAgdi5hZGQobmV3IE1haWxjYXBGaWxlKGNsaXMpKTsKKwkJCSAgICBhbnlMb2FkZWQgPSB0cnVlOworCQkJICAgIGlmIChMb2dTdXBwb3J0LmlzTG9nZ2FibGUoKSkKKwkJCQlMb2dTdXBwb3J0LmxvZygiTWFpbGNhcENvbW1hbmRNYXA6ICIgKworCQkJCSAgICAic3VjY2Vzc2Z1bGx5IGxvYWRlZCAiICsKKwkJCQkgICAgIm1haWxjYXAgZmlsZSBmcm9tIFVSTDogIiArCisJCQkJICAgIHVybCk7CisJCQl9IGVsc2UgeworCQkJICAgIGlmIChMb2dTdXBwb3J0LmlzTG9nZ2FibGUoKSkKKwkJCQlMb2dTdXBwb3J0LmxvZygiTWFpbGNhcENvbW1hbmRNYXA6ICIgKworCQkJCSAgICAibm90IGxvYWRpbmcgbWFpbGNhcCAiICsKKwkJCQkgICAgImZpbGUgZnJvbSBVUkw6ICIgKyB1cmwpOworCQkJfQorCQkgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9leCkgeworCQkJaWYgKExvZ1N1cHBvcnQuaXNMb2dnYWJsZSgpKQorCQkJICAgIExvZ1N1cHBvcnQubG9nKCJNYWlsY2FwQ29tbWFuZE1hcDogY2FuJ3QgbG9hZCAiICsKKwkJCQkJCXVybCwgaW9leCk7CisJCSAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBzZXgpIHsKKwkJCWlmIChMb2dTdXBwb3J0LmlzTG9nZ2FibGUoKSkKKwkJCSAgICBMb2dTdXBwb3J0LmxvZygiTWFpbGNhcENvbW1hbmRNYXA6IGNhbid0IGxvYWQgIiArCisJCQkJCQl1cmwsIHNleCk7CisJCSAgICB9IGZpbmFsbHkgeworCQkJdHJ5IHsKKwkJCSAgICBpZiAoY2xpcyAhPSBudWxsKQorCQkJCWNsaXMuY2xvc2UoKTsKKwkJCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGNleCkgeyB9CisJCSAgICB9CisJCX0KKwkgICAgfQorCX0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCSAgICBpZiAoTG9nU3VwcG9ydC5pc0xvZ2dhYmxlKCkpCisJCUxvZ1N1cHBvcnQubG9nKCJNYWlsY2FwQ29tbWFuZE1hcDogY2FuJ3QgbG9hZCAiICsgbmFtZSwgZXgpOworCX0KKworCS8vIGlmIGZhaWxlZCB0byBsb2FkIGFueXRoaW5nLCBmYWxsIGJhY2sgdG8gb2xkIHRlY2huaXF1ZSwganVzdCBpbiBjYXNlCisJaWYgKCFhbnlMb2FkZWQpIHsKKwkgICAgaWYgKExvZ1N1cHBvcnQuaXNMb2dnYWJsZSgpKQorCQlMb2dTdXBwb3J0LmxvZygiTWFpbGNhcENvbW1hbmRNYXA6ICFhbnlMb2FkZWQiKTsKKwkgICAgTWFpbGNhcEZpbGUgbWYgPSBsb2FkUmVzb3VyY2UoIi8iICsgbmFtZSk7CisJICAgIGlmIChtZiAhPSBudWxsKQorCQl2LmFkZChtZik7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIExvYWQgZnJvbSB0aGUgbmFtZWQgZmlsZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIE1haWxjYXBGaWxlIGxvYWRGaWxlKFN0cmluZyBuYW1lKSB7CisJTWFpbGNhcEZpbGUgbXRmID0gbnVsbDsKKworCXRyeSB7CisJICAgIG10ZiA9IG5ldyBNYWlsY2FwRmlsZShuYW1lKTsKKwl9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisJICAgIC8vCWUucHJpbnRTdGFja1RyYWNlKCk7CisJfQorCXJldHVybiBtdGY7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IgdGhhdCBhbGxvd3MgdGhlIGNhbGxlciB0byBzcGVjaWZ5IHRoZSBwYXRoCisgICAgICogb2YgYSA8aT5tYWlsY2FwPC9pPiBmaWxlLgorICAgICAqCisgICAgICogQHBhcmFtIGZpbGVOYW1lIFRoZSBuYW1lIG9mIHRoZSA8aT5tYWlsY2FwPC9pPiBmaWxlIHRvIG9wZW4KKyAgICAgKiBAZXhjZXB0aW9uCUlPRXhjZXB0aW9uCWlmIHRoZSBmaWxlIGNhbid0IGJlIGFjY2Vzc2VkCisgICAgICovCisgICAgcHVibGljIE1haWxjYXBDb21tYW5kTWFwKFN0cmluZyBmaWxlTmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwl0aGlzKCk7CisKKwlpZiAoTG9nU3VwcG9ydC5pc0xvZ2dhYmxlKCkpCisJICAgIExvZ1N1cHBvcnQubG9nKCJNYWlsY2FwQ29tbWFuZE1hcDogbG9hZCBQUk9HIGZyb20gIiArIGZpbGVOYW1lKTsKKwlpZiAoREJbUFJPR10gPT0gbnVsbCkgeworCSAgICBEQltQUk9HXSA9IG5ldyBNYWlsY2FwRmlsZShmaWxlTmFtZSk7CisJfQorICAgIH0KKworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IgdGhhdCBhbGxvd3MgdGhlIGNhbGxlciB0byBzcGVjaWZ5IGFuIDxpPklucHV0U3RyZWFtPC9pPgorICAgICAqIGNvbnRhaW5pbmcgYSBtYWlsY2FwIGZpbGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaXMJSW5wdXRTdHJlYW0gb2YgdGhlIDxpPm1haWxjYXA8L2k+IGZpbGUgdG8gb3BlbgorICAgICAqLworICAgIHB1YmxpYyBNYWlsY2FwQ29tbWFuZE1hcChJbnB1dFN0cmVhbSBpcykgeworCXRoaXMoKTsKKworCUxvZ1N1cHBvcnQubG9nKCJNYWlsY2FwQ29tbWFuZE1hcDogbG9hZCBQUk9HIik7CisJaWYgKERCW1BST0ddID09IG51bGwpIHsKKwkgICAgdHJ5IHsKKwkJREJbUFJPR10gPSBuZXcgTWFpbGNhcEZpbGUoaXMpOworCSAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworCQkvLyBYWFggLSBzaG91bGQgdGhyb3cgaXQKKwkgICAgfQorCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIHByZWZlcnJlZCBjb21tYW5kIGxpc3QgZm9yIGEgTUlNRSBUeXBlLiBUaGUgTWFpbGNhcENvbW1hbmRNYXAKKyAgICAgKiBzZWFyY2hlcyB0aGUgbWFpbGNhcCBmaWxlcyBhcyBkZXNjcmliZWQgYWJvdmUgdW5kZXIKKyAgICAgKiA8aT5NYWlsY2FwIGZpbGUgc2VhcmNoIG9yZGVyPC9pPi48cD4KKyAgICAgKgorICAgICAqIFRoZSByZXN1bHQgb2YgdGhlIHNlYXJjaCBpcyBhIHByb3BlciBzdWJzZXQgb2YgYXZhaWxhYmxlCisgICAgICogY29tbWFuZHMgaW4gYWxsIG1haWxjYXAgZmlsZXMga25vd24gdG8gdGhpcyBpbnN0YW5jZSBvZiAKKyAgICAgKiBNYWlsY2FwQ29tbWFuZE1hcC4gIFRoZSBmaXJzdCBlbnRyeSBmb3IgYSBwYXJ0aWN1bGFyIGNvbW1hbmQKKyAgICAgKiBpcyBjb25zaWRlcmVkIHRoZSBwcmVmZXJyZWQgY29tbWFuZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtaW1lVHlwZQl0aGUgTUlNRSB0eXBlCisgICAgICogQHJldHVybiB0aGUgQ29tbWFuZEluZm8gb2JqZWN0cyByZXByZXNlbnRpbmcgdGhlIHByZWZlcnJlZCBjb21tYW5kcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIENvbW1hbmRJbmZvW10gZ2V0UHJlZmVycmVkQ29tbWFuZHMoU3RyaW5nIG1pbWVUeXBlKSB7CisJTGlzdCBjbWRMaXN0ID0gbmV3IEFycmF5TGlzdCgpOworCWlmIChtaW1lVHlwZSAhPSBudWxsKQorCSAgICBtaW1lVHlwZSA9IG1pbWVUeXBlLnRvTG93ZXJDYXNlKExvY2FsZS5FTkdMSVNIKTsKKworCWZvciAoaW50IGkgPSAwOyBpIDwgREIubGVuZ3RoOyBpKyspIHsKKwkgICAgaWYgKERCW2ldID09IG51bGwpCisJCWNvbnRpbnVlOworCSAgICBNYXAgY21kTWFwID0gREJbaV0uZ2V0TWFpbGNhcExpc3QobWltZVR5cGUpOworCSAgICBpZiAoY21kTWFwICE9IG51bGwpCisJCWFwcGVuZFByZWZDbWRzVG9MaXN0KGNtZE1hcCwgY21kTGlzdCk7CisJfQorCisJLy8gbm93IGFkZCB0aGUgZmFsbGJhY2sgY29tbWFuZHMKKwlmb3IgKGludCBpID0gMDsgaSA8IERCLmxlbmd0aDsgaSsrKSB7CisJICAgIGlmIChEQltpXSA9PSBudWxsKQorCQljb250aW51ZTsKKwkgICAgTWFwIGNtZE1hcCA9IERCW2ldLmdldE1haWxjYXBGYWxsYmFja0xpc3QobWltZVR5cGUpOworCSAgICBpZiAoY21kTWFwICE9IG51bGwpCisJCWFwcGVuZFByZWZDbWRzVG9MaXN0KGNtZE1hcCwgY21kTGlzdCk7CisJfQorCisJQ29tbWFuZEluZm9bXSBjbWRJbmZvcyA9IG5ldyBDb21tYW5kSW5mb1tjbWRMaXN0LnNpemUoKV07CisJY21kSW5mb3MgPSAoQ29tbWFuZEluZm9bXSljbWRMaXN0LnRvQXJyYXkoY21kSW5mb3MpOworCisJcmV0dXJuIGNtZEluZm9zOworICAgIH0KKworICAgIC8qKgorICAgICAqIFB1dCB0aGUgY29tbWFuZHMgdGhhdCBhcmUgaW4gdGhlIGhhc2ggdGFibGUsIGludG8gdGhlIGxpc3QuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGFwcGVuZFByZWZDbWRzVG9MaXN0KE1hcCBjbWRIYXNoLCBMaXN0IGNtZExpc3QpIHsKKwlJdGVyYXRvciB2ZXJiX2VudW0gPSBjbWRIYXNoLmtleVNldCgpLml0ZXJhdG9yKCk7CisKKwl3aGlsZSAodmVyYl9lbnVtLmhhc05leHQoKSkgeworCSAgICBTdHJpbmcgdmVyYiA9IChTdHJpbmcpdmVyYl9lbnVtLm5leHQoKTsKKwkgICAgaWYgKCFjaGVja0ZvclZlcmIoY21kTGlzdCwgdmVyYikpIHsKKwkJTGlzdCBjbWRMaXN0MiA9IChMaXN0KWNtZEhhc2guZ2V0KHZlcmIpOyAvLyBnZXQgdGhlIGxpc3QKKwkJU3RyaW5nIGNsYXNzTmFtZSA9IChTdHJpbmcpY21kTGlzdDIuZ2V0KDApOworCQljbWRMaXN0LmFkZChuZXcgQ29tbWFuZEluZm8odmVyYiwgY2xhc3NOYW1lKSk7CisJICAgIH0KKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2sgdGhlIGNtZExpc3QgdG8gc2VlIGlmIHRoaXMgY29tbWFuZCBleGlzdHMsIHJldHVybgorICAgICAqIHRydWUgaWYgdGhlIHZlcmIgaXMgdGhlcmUuCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGNoZWNrRm9yVmVyYihMaXN0IGNtZExpc3QsIFN0cmluZyB2ZXJiKSB7CisJSXRlcmF0b3IgZWUgPSBjbWRMaXN0Lml0ZXJhdG9yKCk7CisJd2hpbGUgKGVlLmhhc05leHQoKSkgeworCSAgICBTdHJpbmcgZW51bV92ZXJiID0KKwkJKFN0cmluZykoKENvbW1hbmRJbmZvKWVlLm5leHQoKSkuZ2V0Q29tbWFuZE5hbWUoKTsKKwkgICAgaWYgKGVudW1fdmVyYi5lcXVhbHModmVyYikpCisJCXJldHVybiB0cnVlOworCX0KKwlyZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IGFsbCB0aGUgYXZhaWxhYmxlIGNvbW1hbmRzIGluIGFsbCBtYWlsY2FwIGZpbGVzIGtub3duIHRvCisgICAgICogdGhpcyBpbnN0YW5jZSBvZiBNYWlsY2FwQ29tbWFuZE1hcCBmb3IgdGhpcyBNSU1FIHR5cGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWltZVR5cGUJdGhlIE1JTUUgdHlwZQorICAgICAqIEByZXR1cm4gdGhlIENvbW1hbmRJbmZvIG9iamVjdHMgcmVwcmVzZW50aW5nIGFsbCB0aGUgY29tbWFuZHMuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBDb21tYW5kSW5mb1tdIGdldEFsbENvbW1hbmRzKFN0cmluZyBtaW1lVHlwZSkgeworCUxpc3QgY21kTGlzdCA9IG5ldyBBcnJheUxpc3QoKTsKKwlpZiAobWltZVR5cGUgIT0gbnVsbCkKKwkgICAgbWltZVR5cGUgPSBtaW1lVHlwZS50b0xvd2VyQ2FzZShMb2NhbGUuRU5HTElTSCk7CisKKwlmb3IgKGludCBpID0gMDsgaSA8IERCLmxlbmd0aDsgaSsrKSB7CisJICAgIGlmIChEQltpXSA9PSBudWxsKQorCQljb250aW51ZTsKKwkgICAgTWFwIGNtZE1hcCA9IERCW2ldLmdldE1haWxjYXBMaXN0KG1pbWVUeXBlKTsKKwkgICAgaWYgKGNtZE1hcCAhPSBudWxsKQorCQlhcHBlbmRDbWRzVG9MaXN0KGNtZE1hcCwgY21kTGlzdCk7CisJfQorCisJLy8gbm93IGFkZCB0aGUgZmFsbGJhY2sgY29tbWFuZHMKKwlmb3IgKGludCBpID0gMDsgaSA8IERCLmxlbmd0aDsgaSsrKSB7CisJICAgIGlmIChEQltpXSA9PSBudWxsKQorCQljb250aW51ZTsKKwkgICAgTWFwIGNtZE1hcCA9IERCW2ldLmdldE1haWxjYXBGYWxsYmFja0xpc3QobWltZVR5cGUpOworCSAgICBpZiAoY21kTWFwICE9IG51bGwpCisJCWFwcGVuZENtZHNUb0xpc3QoY21kTWFwLCBjbWRMaXN0KTsKKwl9CisKKwlDb21tYW5kSW5mb1tdIGNtZEluZm9zID0gbmV3IENvbW1hbmRJbmZvW2NtZExpc3Quc2l6ZSgpXTsKKwljbWRJbmZvcyA9IChDb21tYW5kSW5mb1tdKWNtZExpc3QudG9BcnJheShjbWRJbmZvcyk7CisKKwlyZXR1cm4gY21kSW5mb3M7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHV0IHRoZSBjb21tYW5kcyB0aGF0IGFyZSBpbiB0aGUgaGFzaCB0YWJsZSwgaW50byB0aGUgbGlzdC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgYXBwZW5kQ21kc1RvTGlzdChNYXAgdHlwZUhhc2gsIExpc3QgY21kTGlzdCkgeworCUl0ZXJhdG9yIHZlcmJfZW51bSA9IHR5cGVIYXNoLmtleVNldCgpLml0ZXJhdG9yKCk7CisKKwl3aGlsZSAodmVyYl9lbnVtLmhhc05leHQoKSkgeworCSAgICBTdHJpbmcgdmVyYiA9IChTdHJpbmcpdmVyYl9lbnVtLm5leHQoKTsKKwkgICAgTGlzdCBjbWRMaXN0MiA9IChMaXN0KXR5cGVIYXNoLmdldCh2ZXJiKTsKKwkgICAgSXRlcmF0b3IgY21kX2VudW0gPSAoKExpc3QpY21kTGlzdDIpLml0ZXJhdG9yKCk7CisKKwkgICAgd2hpbGUgKGNtZF9lbnVtLmhhc05leHQoKSkgeworCQlTdHJpbmcgY21kID0gKFN0cmluZyljbWRfZW51bS5uZXh0KCk7CisJCWNtZExpc3QuYWRkKG5ldyBDb21tYW5kSW5mbyh2ZXJiLCBjbWQpKTsKKwkJLy8gY21kTGlzdC5hZGQoMCwgbmV3IENvbW1hbmRJbmZvKHZlcmIsIGNtZCkpOworCSAgICB9CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgY29tbWFuZCBjb3JyZXNwb25kaW5nIHRvIDxjb2RlPmNtZE5hbWU8L2NvZGU+IGZvciB0aGUgTUlNRSB0eXBlLgorICAgICAqCisgICAgICogQHBhcmFtIG1pbWVUeXBlCXRoZSBNSU1FIHR5cGUKKyAgICAgKiBAcGFyYW0gY21kTmFtZQl0aGUgY29tbWFuZCBuYW1lCisgICAgICogQHJldHVybiB0aGUgQ29tbWFuZEluZm8gb2JqZWN0IGNvcnJlc3BvbmRpbmcgdG8gdGhlIGNvbW1hbmQuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBDb21tYW5kSW5mbyBnZXRDb21tYW5kKFN0cmluZyBtaW1lVHlwZSwKKwkJCQkJCQlTdHJpbmcgY21kTmFtZSkgeworCWlmIChtaW1lVHlwZSAhPSBudWxsKQorCSAgICBtaW1lVHlwZSA9IG1pbWVUeXBlLnRvTG93ZXJDYXNlKExvY2FsZS5FTkdMSVNIKTsKKworCWZvciAoaW50IGkgPSAwOyBpIDwgREIubGVuZ3RoOyBpKyspIHsKKwkgICAgaWYgKERCW2ldID09IG51bGwpCisJCWNvbnRpbnVlOworCSAgICBNYXAgY21kTWFwID0gREJbaV0uZ2V0TWFpbGNhcExpc3QobWltZVR5cGUpOworCSAgICBpZiAoY21kTWFwICE9IG51bGwpIHsKKwkJLy8gZ2V0IHRoZSBjbWQgbGlzdCBmb3IgdGhlIGNtZAorCQlMaXN0IHYgPSAoTGlzdCljbWRNYXAuZ2V0KGNtZE5hbWUpOworCQlpZiAodiAhPSBudWxsKSB7CisJCSAgICBTdHJpbmcgY21kQ2xhc3NOYW1lID0gKFN0cmluZyl2LmdldCgwKTsKKworCQkgICAgaWYgKGNtZENsYXNzTmFtZSAhPSBudWxsKQorCQkJcmV0dXJuIG5ldyBDb21tYW5kSW5mbyhjbWROYW1lLCBjbWRDbGFzc05hbWUpOworCQl9CisJICAgIH0KKwl9CisKKwkvLyBub3cgdHJ5IHRoZSBmYWxsYmFjayBsaXN0CisJZm9yIChpbnQgaSA9IDA7IGkgPCBEQi5sZW5ndGg7IGkrKykgeworCSAgICBpZiAoREJbaV0gPT0gbnVsbCkKKwkJY29udGludWU7CisJICAgIE1hcCBjbWRNYXAgPSBEQltpXS5nZXRNYWlsY2FwRmFsbGJhY2tMaXN0KG1pbWVUeXBlKTsKKwkgICAgaWYgKGNtZE1hcCAhPSBudWxsKSB7CisJCS8vIGdldCB0aGUgY21kIGxpc3QgZm9yIHRoZSBjbWQKKwkJTGlzdCB2ID0gKExpc3QpY21kTWFwLmdldChjbWROYW1lKTsKKwkJaWYgKHYgIT0gbnVsbCkgeworCQkgICAgU3RyaW5nIGNtZENsYXNzTmFtZSA9IChTdHJpbmcpdi5nZXQoMCk7CisKKwkJICAgIGlmIChjbWRDbGFzc05hbWUgIT0gbnVsbCkKKwkJCXJldHVybiBuZXcgQ29tbWFuZEluZm8oY21kTmFtZSwgY21kQ2xhc3NOYW1lKTsKKwkJfQorCSAgICB9CisJfQorCXJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZCBlbnRyaWVzIHRvIHRoZSByZWdpc3RyeS4gIFByb2dyYW1tYXRpY2FsbHkgCisgICAgICogYWRkZWQgZW50cmllcyBhcmUgc2VhcmNoZWQgYmVmb3JlIG90aGVyIGVudHJpZXMuPHA+CisgICAgICoKKyAgICAgKiBUaGUgc3RyaW5nIHRoYXQgaXMgcGFzc2VkIGluIHNob3VsZCBiZSBpbiBtYWlsY2FwCisgICAgICogZm9ybWF0LgorICAgICAqCisgICAgICogQHBhcmFtIG1haWxfY2FwIGEgY29ycmVjdGx5IGZvcm1hdHRlZCBtYWlsY2FwIHN0cmluZworICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBhZGRNYWlsY2FwKFN0cmluZyBtYWlsX2NhcCkgeworCS8vIGNoZWNrIHRvIHNlZSBpZiBvbmUgZXhpc3RzCisJTG9nU3VwcG9ydC5sb2coIk1haWxjYXBDb21tYW5kTWFwOiBhZGQgdG8gUFJPRyIpOworCWlmIChEQltQUk9HXSA9PSBudWxsKQorCSAgICBEQltQUk9HXSA9IG5ldyBNYWlsY2FwRmlsZSgpOworCisJREJbUFJPR10uYXBwZW5kVG9NYWlsY2FwKG1haWxfY2FwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIERhdGFDb250ZW50SGFuZGxlciBmb3IgdGhlIHNwZWNpZmllZCBNSU1FIHR5cGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWltZVR5cGUJdGhlIE1JTUUgdHlwZQorICAgICAqIEByZXR1cm4JCXRoZSBEYXRhQ29udGVudEhhbmRsZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIERhdGFDb250ZW50SGFuZGxlciBjcmVhdGVEYXRhQ29udGVudEhhbmRsZXIoCisJCQkJCQkJU3RyaW5nIG1pbWVUeXBlKSB7CisJaWYgKExvZ1N1cHBvcnQuaXNMb2dnYWJsZSgpKQorCSAgICBMb2dTdXBwb3J0LmxvZygKKwkJIk1haWxjYXBDb21tYW5kTWFwOiBjcmVhdGVEYXRhQ29udGVudEhhbmRsZXIgZm9yICIgKyBtaW1lVHlwZSk7CisJaWYgKG1pbWVUeXBlICE9IG51bGwpCisJICAgIG1pbWVUeXBlID0gbWltZVR5cGUudG9Mb3dlckNhc2UoTG9jYWxlLkVOR0xJU0gpOworCisJZm9yIChpbnQgaSA9IDA7IGkgPCBEQi5sZW5ndGg7IGkrKykgeworCSAgICBpZiAoREJbaV0gPT0gbnVsbCkKKwkJY29udGludWU7CisJICAgIGlmIChMb2dTdXBwb3J0LmlzTG9nZ2FibGUoKSkKKwkJTG9nU3VwcG9ydC5sb2coIiAgc2VhcmNoIERCICMiICsgaSk7CisJICAgIE1hcCBjbWRNYXAgPSBEQltpXS5nZXRNYWlsY2FwTGlzdChtaW1lVHlwZSk7CisJICAgIGlmIChjbWRNYXAgIT0gbnVsbCkgeworCQlMaXN0IHYgPSAoTGlzdCljbWRNYXAuZ2V0KCJjb250ZW50LWhhbmRsZXIiKTsKKwkJaWYgKHYgIT0gbnVsbCkgeworCQkgICAgU3RyaW5nIG5hbWUgPSAoU3RyaW5nKXYuZ2V0KDApOworCQkgICAgRGF0YUNvbnRlbnRIYW5kbGVyIGRjaCA9IGdldERhdGFDb250ZW50SGFuZGxlcihuYW1lKTsKKwkJICAgIGlmIChkY2ggIT0gbnVsbCkKKwkJCXJldHVybiBkY2g7CisJCX0KKwkgICAgfQorCX0KKworCS8vIG5vdyB0cnkgdGhlIGZhbGxiYWNrIGVudHJpZXMKKwlmb3IgKGludCBpID0gMDsgaSA8IERCLmxlbmd0aDsgaSsrKSB7CisJICAgIGlmIChEQltpXSA9PSBudWxsKQorCQljb250aW51ZTsKKwkgICAgaWYgKExvZ1N1cHBvcnQuaXNMb2dnYWJsZSgpKQorCQlMb2dTdXBwb3J0LmxvZygiICBzZWFyY2ggZmFsbGJhY2sgREIgIyIgKyBpKTsKKwkgICAgTWFwIGNtZE1hcCA9IERCW2ldLmdldE1haWxjYXBGYWxsYmFja0xpc3QobWltZVR5cGUpOworCSAgICBpZiAoY21kTWFwICE9IG51bGwpIHsKKwkJTGlzdCB2ID0gKExpc3QpY21kTWFwLmdldCgiY29udGVudC1oYW5kbGVyIik7CisJCWlmICh2ICE9IG51bGwpIHsKKwkJICAgIFN0cmluZyBuYW1lID0gKFN0cmluZyl2LmdldCgwKTsKKwkJICAgIERhdGFDb250ZW50SGFuZGxlciBkY2ggPSBnZXREYXRhQ29udGVudEhhbmRsZXIobmFtZSk7CisJCSAgICBpZiAoZGNoICE9IG51bGwpCisJCQlyZXR1cm4gZGNoOworCQl9CisJICAgIH0KKwl9CisJcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHJpdmF0ZSBEYXRhQ29udGVudEhhbmRsZXIgZ2V0RGF0YUNvbnRlbnRIYW5kbGVyKFN0cmluZyBuYW1lKSB7CisJaWYgKExvZ1N1cHBvcnQuaXNMb2dnYWJsZSgpKQorCSAgICBMb2dTdXBwb3J0LmxvZygiICAgIGdvdCBjb250ZW50LWhhbmRsZXIiKTsKKwlpZiAoTG9nU3VwcG9ydC5pc0xvZ2dhYmxlKCkpCisJICAgIExvZ1N1cHBvcnQubG9nKCIgICAgICBjbGFzcyAiICsgbmFtZSk7CisJdHJ5IHsKKwkgICAgQ2xhc3NMb2FkZXIgY2xkID0gbnVsbDsKKwkgICAgLy8gRmlyc3QgdHJ5IHRoZSAiYXBwbGljYXRpb24ncyIgY2xhc3MgbG9hZGVyLgorCSAgICBjbGQgPSBTZWN1cml0eVN1cHBvcnQuZ2V0Q29udGV4dENsYXNzTG9hZGVyKCk7CisJICAgIGlmIChjbGQgPT0gbnVsbCkKKwkJY2xkID0gdGhpcy5nZXRDbGFzcygpLmdldENsYXNzTG9hZGVyKCk7CisJICAgIENsYXNzIGNsID0gbnVsbDsKKwkgICAgdHJ5IHsKKwkJY2wgPSBjbGQubG9hZENsYXNzKG5hbWUpOworCSAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKwkJLy8gaWYgYW55dGhpbmcgZ29lcyB3cm9uZywgZG8gaXQgdGhlIG9sZCB3YXkKKwkJY2wgPSBDbGFzcy5mb3JOYW1lKG5hbWUpOworCSAgICB9CisJICAgIGlmIChjbCAhPSBudWxsKQkJLy8gWFhYIC0gYWx3YXlzIHRydWU/CisJCXJldHVybiAoRGF0YUNvbnRlbnRIYW5kbGVyKWNsLm5ld0luc3RhbmNlKCk7CisJfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBlKSB7CisJICAgIGlmIChMb2dTdXBwb3J0LmlzTG9nZ2FibGUoKSkKKwkJTG9nU3VwcG9ydC5sb2coIkNhbid0IGxvYWQgRENIICIgKyBuYW1lLCBlKTsKKwl9IGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGUpIHsKKwkgICAgaWYgKExvZ1N1cHBvcnQuaXNMb2dnYWJsZSgpKQorCQlMb2dTdXBwb3J0LmxvZygiQ2FuJ3QgbG9hZCBEQ0ggIiArIG5hbWUsIGUpOworCX0gY2F0Y2ggKEluc3RhbnRpYXRpb25FeGNlcHRpb24gZSkgeworCSAgICBpZiAoTG9nU3VwcG9ydC5pc0xvZ2dhYmxlKCkpCisJCUxvZ1N1cHBvcnQubG9nKCJDYW4ndCBsb2FkIERDSCAiICsgbmFtZSwgZSk7CisJfQorCXJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCBhbGwgdGhlIE1JTUUgdHlwZXMga25vd24gdG8gdGhpcyBjb21tYW5kIG1hcC4KKyAgICAgKgorICAgICAqIEByZXR1cm4JCWFycmF5IG9mIE1JTUUgdHlwZXMgYXMgc3RyaW5ncworICAgICAqIEBzaW5jZQlKQUYgMS4xCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBTdHJpbmdbXSBnZXRNaW1lVHlwZXMoKSB7CisJTGlzdCBtdExpc3QgPSBuZXcgQXJyYXlMaXN0KCk7CisKKwlmb3IgKGludCBpID0gMDsgaSA8IERCLmxlbmd0aDsgaSsrKSB7CisJICAgIGlmIChEQltpXSA9PSBudWxsKQorCQljb250aW51ZTsKKwkgICAgU3RyaW5nW10gdHMgPSBEQltpXS5nZXRNaW1lVHlwZXMoKTsKKwkgICAgaWYgKHRzICE9IG51bGwpIHsKKwkJZm9yIChpbnQgaiA9IDA7IGogPCB0cy5sZW5ndGg7IGorKykgeworCQkgICAgLy8gZWxpbWluYXRlIGR1cGxpY2F0ZXMKKwkJICAgIGlmICghbXRMaXN0LmNvbnRhaW5zKHRzW2pdKSkKKwkJCW10TGlzdC5hZGQodHNbal0pOworCQl9CisJICAgIH0KKwl9CisKKwlTdHJpbmdbXSBtdHMgPSBuZXcgU3RyaW5nW210TGlzdC5zaXplKCldOworCW10cyA9IChTdHJpbmdbXSltdExpc3QudG9BcnJheShtdHMpOworCisJcmV0dXJuIG10czsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIG5hdGl2ZSBjb21tYW5kcyBmb3IgdGhlIGdpdmVuIE1JTUUgdHlwZS4KKyAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIHN0cmluZ3Mgd2hlcmUgZWFjaCBzdHJpbmcgaXMKKyAgICAgKiBhbiBlbnRpcmUgbWFpbGNhcCBmaWxlIGVudHJ5LiAgVGhlIGFwcGxpY2F0aW9uCisgICAgICogd2lsbCBuZWVkIHRvIHBhcnNlIHRoZSBlbnRyeSB0byBleHRyYWN0IHRoZSBhY3R1YWwKKyAgICAgKiBjb21tYW5kIGFzIHdlbGwgYXMgYW55IGF0dHJpYnV0ZXMgaXQgbmVlZHMuIFNlZQorICAgICAqIDxBIEhSRUY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzE1MjQudHh0Ij5SRkMgMTUyNDwvQT4KKyAgICAgKiBmb3IgZGV0YWlscyBvZiB0aGUgbWFpbGNhcCBlbnRyeSBzeW50YXguICBPbmx5IG1haWxjYXAKKyAgICAgKiBlbnRyaWVzIHRoYXQgc3BlY2lmeSBhIHZpZXcgY29tbWFuZCBmb3IgdGhlIHNwZWNpZmllZAorICAgICAqIE1JTUUgdHlwZSBhcmUgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0JbWltZVR5cGUJdGhlIE1JTUUgdHlwZQorICAgICAqIEByZXR1cm4JCWFycmF5IG9mIG5hdGl2ZSBjb21tYW5kIGVudHJpZXMKKyAgICAgKiBAc2luY2UJSkFGIDEuMQorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgU3RyaW5nW10gZ2V0TmF0aXZlQ29tbWFuZHMoU3RyaW5nIG1pbWVUeXBlKSB7CisJTGlzdCBjbWRMaXN0ID0gbmV3IEFycmF5TGlzdCgpOworCWlmIChtaW1lVHlwZSAhPSBudWxsKQorCSAgICBtaW1lVHlwZSA9IG1pbWVUeXBlLnRvTG93ZXJDYXNlKExvY2FsZS5FTkdMSVNIKTsKKworCWZvciAoaW50IGkgPSAwOyBpIDwgREIubGVuZ3RoOyBpKyspIHsKKwkgICAgaWYgKERCW2ldID09IG51bGwpCisJCWNvbnRpbnVlOworCSAgICBTdHJpbmdbXSBjbWRzID0gREJbaV0uZ2V0TmF0aXZlQ29tbWFuZHMobWltZVR5cGUpOworCSAgICBpZiAoY21kcyAhPSBudWxsKSB7CisJCWZvciAoaW50IGogPSAwOyBqIDwgY21kcy5sZW5ndGg7IGorKykgeworCQkgICAgLy8gZWxpbWluYXRlIGR1cGxpY2F0ZXMKKwkJICAgIGlmICghY21kTGlzdC5jb250YWlucyhjbWRzW2pdKSkKKwkJCWNtZExpc3QuYWRkKGNtZHNbal0pOworCQl9CisJICAgIH0KKwl9CisKKwlTdHJpbmdbXSBjbWRzID0gbmV3IFN0cmluZ1tjbWRMaXN0LnNpemUoKV07CisJY21kcyA9IChTdHJpbmdbXSljbWRMaXN0LnRvQXJyYXkoY21kcyk7CisKKwlyZXR1cm4gY21kczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBmb3IgZGVidWdnaW5nLi4uCisgICAgICoKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmd2KSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlNYWlsY2FwQ29tbWFuZE1hcCBtYXAgPSBuZXcgTWFpbGNhcENvbW1hbmRNYXAoKTsKKwlDb21tYW5kSW5mb1tdIGNtZEluZm87CisKKwljbWRJbmZvID0gbWFwLmdldFByZWZlcnJlZENvbW1hbmRzKGFyZ3ZbMF0pOworCVN5c3RlbS5vdXQucHJpbnRsbigiUHJlZmVycmVkIENvbW1hbmRzOiIpOworCWZvciAoaW50IGkgPSAwOyBpIDwgY21kSW5mby5sZW5ndGg7IGkrKykKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJDb21tYW5kICIgKyBjbWRJbmZvW2ldLmdldENvbW1hbmROYW1lKCkgKyAiIFsiICsKKwkJCQkJICAgIGNtZEluZm9baV0uZ2V0Q29tbWFuZENsYXNzKCkgKyAiXSIpOworCWNtZEluZm8gPSBtYXAuZ2V0QWxsQ29tbWFuZHMoYXJndlswXSk7CisJU3lzdGVtLm91dC5wcmludGxuKCk7CisJU3lzdGVtLm91dC5wcmludGxuKCJBbGwgQ29tbWFuZHM6Iik7CisJZm9yIChpbnQgaSA9IDA7IGkgPCBjbWRJbmZvLmxlbmd0aDsgaSsrKQorCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkNvbW1hbmQgIiArIGNtZEluZm9baV0uZ2V0Q29tbWFuZE5hbWUoKSArICIgWyIgKworCQkJCQkgICAgY21kSW5mb1tpXS5nZXRDb21tYW5kQ2xhc3MoKSArICJdIik7CisJRGF0YUNvbnRlbnRIYW5kbGVyIGRjaCA9IG1hcC5jcmVhdGVEYXRhQ29udGVudEhhbmRsZXIoYXJndlswXSk7CisJaWYgKGRjaCAhPSBudWxsKQorCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkRhdGFDb250ZW50SGFuZGxlciAiICsKKwkJCQkJCWRjaC5nZXRDbGFzcygpLnRvU3RyaW5nKCkpOworCVN5c3RlbS5leGl0KDApOworICAgIH0KKyAgICAqLworfQpkaWZmIC0tZ2l0IGEvYW5kcm9pZC9hY3RpdmF0aW9uL3NyYy9tYWluL2phdmEvamF2YXgvYWN0aXZhdGlvbi9NaW1lVHlwZS5qYXZhIGIvYW5kcm9pZC9hY3RpdmF0aW9uL3NyYy9tYWluL2phdmEvamF2YXgvYWN0aXZhdGlvbi9NaW1lVHlwZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ5ZmU2ZTUKLS0tIC9kZXYvbnVsbAorKysgYi9hbmRyb2lkL2FjdGl2YXRpb24vc3JjL21haW4vamF2YS9qYXZheC9hY3RpdmF0aW9uL01pbWVUeXBlLmphdmEKQEAgLTAsMCArMSwzMjkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorICovCisKK3BhY2thZ2UgamF2YXguYWN0aXZhdGlvbjsKKworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworCisvKioKKyAqIEEgTXVsdGlwdXJwb3NlIEludGVybmV0IE1haWwgRXh0ZW5zaW9uIChNSU1FKSB0eXBlLCBhcyBkZWZpbmVkCisgKiBpbiBSRkMgMjA0NSBhbmQgMjA0Ni4KKyAqLworcHVibGljIGNsYXNzIE1pbWVUeXBlIGltcGxlbWVudHMgRXh0ZXJuYWxpemFibGUgeworCisgICAgcHJpdmF0ZSBTdHJpbmcgICAgcHJpbWFyeVR5cGU7CisgICAgcHJpdmF0ZSBTdHJpbmcgICAgc3ViVHlwZTsKKyAgICBwcml2YXRlIE1pbWVUeXBlUGFyYW1ldGVyTGlzdCBwYXJhbWV0ZXJzOworCisgICAgLyoqCisgICAgICogQSBzdHJpbmcgdGhhdCBob2xkcyBhbGwgdGhlIHNwZWNpYWwgY2hhcnMuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRTUEVDSUFMUyA9ICIoKTw+QCw7Oi9bXT89XFxcIiI7CisKKyAgICAvKioKKyAgICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yLgorICAgICAqLworICAgIHB1YmxpYyBNaW1lVHlwZSgpIHsKKyAgICAgICAgcHJpbWFyeVR5cGUgPSAiYXBwbGljYXRpb24iOworICAgICAgICBzdWJUeXBlID0gIioiOworICAgICAgICBwYXJhbWV0ZXJzID0gbmV3IE1pbWVUeXBlUGFyYW1ldGVyTGlzdCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yIHRoYXQgYnVpbGRzIGEgTWltZVR5cGUgZnJvbSBhIFN0cmluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSByYXdkYXRhCXRoZSBNSU1FIHR5cGUgc3RyaW5nCisgICAgICogQGV4Y2VwdGlvbglNaW1lVHlwZVBhcnNlRXhjZXB0aW9uCWlmIHRoZSBNSU1FIHR5cGUgY2FuJ3QgYmUgcGFyc2VkCisgICAgICovCisgICAgcHVibGljIE1pbWVUeXBlKFN0cmluZyByYXdkYXRhKSB0aHJvd3MgTWltZVR5cGVQYXJzZUV4Y2VwdGlvbiB7CisgICAgICAgIHBhcnNlKHJhd2RhdGEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yIHRoYXQgYnVpbGRzIGEgTWltZVR5cGUgd2l0aCB0aGUgZ2l2ZW4gcHJpbWFyeSBhbmQgc3ViIHR5cGUKKyAgICAgKiBidXQgaGFzIGFuIGVtcHR5IHBhcmFtZXRlciBsaXN0LgorICAgICAqCisgICAgICogQHBhcmFtIHByaW1hcnkJdGhlIHByaW1hcnkgTUlNRSB0eXBlCisgICAgICogQHBhcmFtIHN1Ygl0aGUgTUlNRSBzdWItdHlwZQorICAgICAqIEBleGNlcHRpb24JTWltZVR5cGVQYXJzZUV4Y2VwdGlvbglpZiB0aGUgcHJpbWFyeSB0eXBlIG9yIHN1YnR5cGUKKyAgICAgKgkJCQkJCWlzIG5vdCBhIHZhbGlkIHRva2VuCisgICAgICovCisgICAgcHVibGljIE1pbWVUeXBlKFN0cmluZyBwcmltYXJ5LCBTdHJpbmcgc3ViKSB0aHJvd3MgTWltZVR5cGVQYXJzZUV4Y2VwdGlvbiB7CisgICAgICAgIC8vICAgIGNoZWNrIHRvIHNlZSBpZiBwcmltYXJ5IGlzIHZhbGlkCisgICAgICAgIGlmIChpc1ZhbGlkVG9rZW4ocHJpbWFyeSkpIHsKKyAgICAgICAgICAgIHByaW1hcnlUeXBlID0gcHJpbWFyeS50b0xvd2VyQ2FzZShMb2NhbGUuRU5HTElTSCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTWltZVR5cGVQYXJzZUV4Y2VwdGlvbigiUHJpbWFyeSB0eXBlIGlzIGludmFsaWQuIik7CisgICAgICAgIH0KKworICAgICAgICAvLyAgICBjaGVjayB0byBzZWUgaWYgc3ViIGlzIHZhbGlkCisgICAgICAgIGlmIChpc1ZhbGlkVG9rZW4oc3ViKSkgeworICAgICAgICAgICAgc3ViVHlwZSA9IHN1Yi50b0xvd2VyQ2FzZShMb2NhbGUuRU5HTElTSCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTWltZVR5cGVQYXJzZUV4Y2VwdGlvbigiU3ViIHR5cGUgaXMgaW52YWxpZC4iKTsKKyAgICAgICAgfQorCisgICAgICAgIHBhcmFtZXRlcnMgPSBuZXcgTWltZVR5cGVQYXJhbWV0ZXJMaXN0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQSByb3V0aW5lIGZvciBwYXJzaW5nIHRoZSBNSU1FIHR5cGUgb3V0IG9mIGEgU3RyaW5nLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBwYXJzZShTdHJpbmcgcmF3ZGF0YSkgdGhyb3dzIE1pbWVUeXBlUGFyc2VFeGNlcHRpb24geworICAgICAgICBpbnQgc2xhc2hJbmRleCA9IHJhd2RhdGEuaW5kZXhPZignLycpOworICAgICAgICBpbnQgc2VtSW5kZXggPSByYXdkYXRhLmluZGV4T2YoJzsnKTsKKyAgICAgICAgaWYgKChzbGFzaEluZGV4IDwgMCkgJiYgKHNlbUluZGV4IDwgMCkpIHsKKyAgICAgICAgICAgIC8vICAgIG5laXRoZXIgY2hhcmFjdGVyIGlzIHByZXNlbnQsIHNvIHRyZWF0IGl0CisgICAgICAgICAgICAvLyAgICBhcyBhbiBlcnJvcgorICAgICAgICAgICAgdGhyb3cgbmV3IE1pbWVUeXBlUGFyc2VFeGNlcHRpb24oIlVuYWJsZSB0byBmaW5kIGEgc3ViIHR5cGUuIik7CisgICAgICAgIH0gZWxzZSBpZiAoKHNsYXNoSW5kZXggPCAwKSAmJiAoc2VtSW5kZXggPj0gMCkpIHsKKyAgICAgICAgICAgIC8vICAgIHdlIGhhdmUgYSAnOycgKGFuZCB0aGVyZWZvcmUgYSBwYXJhbWV0ZXIgbGlzdCksCisgICAgICAgICAgICAvLyAgICBidXQgbm8gJy8nIGluZGljYXRpbmcgYSBzdWIgdHlwZSBpcyBwcmVzZW50CisgICAgICAgICAgICB0aHJvdyBuZXcgTWltZVR5cGVQYXJzZUV4Y2VwdGlvbigiVW5hYmxlIHRvIGZpbmQgYSBzdWIgdHlwZS4iKTsKKyAgICAgICAgfSBlbHNlIGlmICgoc2xhc2hJbmRleCA+PSAwKSAmJiAoc2VtSW5kZXggPCAwKSkgeworICAgICAgICAgICAgLy8gICAgd2UgaGF2ZSBhIHByaW1hcnkgYW5kIHN1YiB0eXBlIGJ1dCBubyBwYXJhbWV0ZXIgbGlzdAorICAgICAgICAgICAgcHJpbWFyeVR5cGUgPSByYXdkYXRhLnN1YnN0cmluZygwLCBzbGFzaEluZGV4KS50cmltKCkuCisJCQkJCQl0b0xvd2VyQ2FzZShMb2NhbGUuRU5HTElTSCk7CisgICAgICAgICAgICBzdWJUeXBlID0gcmF3ZGF0YS5zdWJzdHJpbmcoc2xhc2hJbmRleCArIDEpLnRyaW0oKS4KKwkJCQkJCXRvTG93ZXJDYXNlKExvY2FsZS5FTkdMSVNIKTsKKyAgICAgICAgICAgIHBhcmFtZXRlcnMgPSBuZXcgTWltZVR5cGVQYXJhbWV0ZXJMaXN0KCk7CisgICAgICAgIH0gZWxzZSBpZiAoc2xhc2hJbmRleCA8IHNlbUluZGV4KSB7CisgICAgICAgICAgICAvLyAgICB3ZSBoYXZlIGFsbCB0aHJlZSBpdGVtcyBpbiB0aGUgcHJvcGVyIHNlcXVlbmNlCisgICAgICAgICAgICBwcmltYXJ5VHlwZSA9IHJhd2RhdGEuc3Vic3RyaW5nKDAsIHNsYXNoSW5kZXgpLnRyaW0oKS4KKwkJCQkJCXRvTG93ZXJDYXNlKExvY2FsZS5FTkdMSVNIKTsKKyAgICAgICAgICAgIHN1YlR5cGUgPSByYXdkYXRhLnN1YnN0cmluZyhzbGFzaEluZGV4ICsgMSwgc2VtSW5kZXgpLnRyaW0oKS4KKwkJCQkJCXRvTG93ZXJDYXNlKExvY2FsZS5FTkdMSVNIKTsKKyAgICAgICAgICAgIHBhcmFtZXRlcnMgPSBuZXcgTWltZVR5cGVQYXJhbWV0ZXJMaXN0KHJhd2RhdGEuc3Vic3RyaW5nKHNlbUluZGV4KSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLyB3ZSBoYXZlIGEgJzsnIGxleGljYWxseSBiZWZvcmUgYSAnLycgd2hpY2ggbWVhbnMgd2UKKwkgICAgLy8gaGF2ZSBhIHByaW1hcnkgdHlwZSBhbmQgYSBwYXJhbWV0ZXIgbGlzdCBidXQgbm8gc3ViIHR5cGUKKyAgICAgICAgICAgIHRocm93IG5ldyBNaW1lVHlwZVBhcnNlRXhjZXB0aW9uKCJVbmFibGUgdG8gZmluZCBhIHN1YiB0eXBlLiIpOworICAgICAgICB9CisKKyAgICAgICAgLy8gICAgbm93IHZhbGlkYXRlIHRoZSBwcmltYXJ5IGFuZCBzdWIgdHlwZXMKKworICAgICAgICAvLyAgICBjaGVjayB0byBzZWUgaWYgcHJpbWFyeSBpcyB2YWxpZAorICAgICAgICBpZiAoIWlzVmFsaWRUb2tlbihwcmltYXJ5VHlwZSkpCisgICAgICAgICAgICB0aHJvdyBuZXcgTWltZVR5cGVQYXJzZUV4Y2VwdGlvbigiUHJpbWFyeSB0eXBlIGlzIGludmFsaWQuIik7CisKKyAgICAgICAgLy8gICAgY2hlY2sgdG8gc2VlIGlmIHN1YiBpcyB2YWxpZAorICAgICAgICBpZiAoIWlzVmFsaWRUb2tlbihzdWJUeXBlKSkKKyAgICAgICAgICAgIHRocm93IG5ldyBNaW1lVHlwZVBhcnNlRXhjZXB0aW9uKCJTdWIgdHlwZSBpcyBpbnZhbGlkLiIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHJpZXZlIHRoZSBwcmltYXJ5IHR5cGUgb2YgdGhpcyBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBwcmltYXJ5IE1JTUUgdHlwZQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHJpbWFyeVR5cGUoKSB7CisgICAgICAgIHJldHVybiBwcmltYXJ5VHlwZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHByaW1hcnkgdHlwZSBmb3IgdGhpcyBvYmplY3QgdG8gdGhlIGdpdmVuIFN0cmluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwcmltYXJ5CXRoZSBwcmltYXJ5IE1JTUUgdHlwZQorICAgICAqIEBleGNlcHRpb24JTWltZVR5cGVQYXJzZUV4Y2VwdGlvbglpZiB0aGUgcHJpbWFyeSB0eXBlCisgICAgICoJCQkJCQlpcyBub3QgYSB2YWxpZCB0b2tlbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFByaW1hcnlUeXBlKFN0cmluZyBwcmltYXJ5KSB0aHJvd3MgTWltZVR5cGVQYXJzZUV4Y2VwdGlvbiB7CisgICAgICAgIC8vICAgIGNoZWNrIHRvIHNlZSBpZiBwcmltYXJ5IGlzIHZhbGlkCisgICAgICAgIGlmICghaXNWYWxpZFRva2VuKHByaW1hcnlUeXBlKSkKKyAgICAgICAgICAgIHRocm93IG5ldyBNaW1lVHlwZVBhcnNlRXhjZXB0aW9uKCJQcmltYXJ5IHR5cGUgaXMgaW52YWxpZC4iKTsKKyAgICAgICAgcHJpbWFyeVR5cGUgPSBwcmltYXJ5LnRvTG93ZXJDYXNlKExvY2FsZS5FTkdMSVNIKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZSB0aGUgc3VidHlwZSBvZiB0aGlzIG9iamVjdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIE1JTUUgc3VidHlwZQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3ViVHlwZSgpIHsKKyAgICAgICAgcmV0dXJuIHN1YlR5cGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBzdWJ0eXBlIGZvciB0aGlzIG9iamVjdCB0byB0aGUgZ2l2ZW4gU3RyaW5nLgorICAgICAqCisgICAgICogQHBhcmFtIHN1Ygl0aGUgTUlNRSBzdWJ0eXBlCisgICAgICogQGV4Y2VwdGlvbglNaW1lVHlwZVBhcnNlRXhjZXB0aW9uCWlmIHRoZSBzdWJ0eXBlCisgICAgICoJCQkJCQlpcyBub3QgYSB2YWxpZCB0b2tlbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFN1YlR5cGUoU3RyaW5nIHN1YikgdGhyb3dzIE1pbWVUeXBlUGFyc2VFeGNlcHRpb24geworICAgICAgICAvLyAgICBjaGVjayB0byBzZWUgaWYgc3ViIGlzIHZhbGlkCisgICAgICAgIGlmICghaXNWYWxpZFRva2VuKHN1YlR5cGUpKQorICAgICAgICAgICAgdGhyb3cgbmV3IE1pbWVUeXBlUGFyc2VFeGNlcHRpb24oIlN1YiB0eXBlIGlzIGludmFsaWQuIik7CisgICAgICAgIHN1YlR5cGUgPSBzdWIudG9Mb3dlckNhc2UoTG9jYWxlLkVOR0xJU0gpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHJpZXZlIHRoaXMgb2JqZWN0J3MgcGFyYW1ldGVyIGxpc3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCWEgTWltZVR5cGVQYXJhbWV0ZXJMaXN0IG9iamVjdCByZXByZXNlbnRpbmcgdGhlIHBhcmFtZXRlcnMKKyAgICAgKi8KKyAgICBwdWJsaWMgTWltZVR5cGVQYXJhbWV0ZXJMaXN0IGdldFBhcmFtZXRlcnMoKSB7CisgICAgICAgIHJldHVybiBwYXJhbWV0ZXJzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHJpZXZlIHRoZSB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG5hbWUsIG9yIG51bGwgaWYgdGhlcmUKKyAgICAgKiBpcyBubyBjdXJyZW50IGFzc29jaWF0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUJdGhlIHBhcmFtZXRlciBuYW1lCisgICAgICogQHJldHVybgkJdGhlIHBhcmFtdGVyJ3MgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFBhcmFtZXRlcihTdHJpbmcgbmFtZSkgeworICAgICAgICByZXR1cm4gcGFyYW1ldGVycy5nZXQobmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSB2YWx1ZSB0byBiZSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG5hbWUsIHJlcGxhY2luZworICAgICAqIGFueSBwcmV2aW91cyBhc3NvY2lhdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCXRoZSBwYXJhbWV0ZXIgbmFtZQorICAgICAqIEBwYXJhbSB2YWx1ZQl0aGUgcGFyYW10ZXIncyB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFBhcmFtZXRlcihTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKSB7CisgICAgICAgIHBhcmFtZXRlcnMuc2V0KG5hbWUsIHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmUgYW55IHZhbHVlIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbmFtZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCXRoZSBwYXJhbWV0ZXIgbmFtZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlbW92ZVBhcmFtZXRlcihTdHJpbmcgbmFtZSkgeworICAgICAgICBwYXJhbWV0ZXJzLnJlbW92ZShuYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIFN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICByZXR1cm4gZ2V0QmFzZVR5cGUoKSArIHBhcmFtZXRlcnMudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYSBTdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBvYmplY3QKKyAgICAgKiB3aXRob3V0IHRoZSBwYXJhbWV0ZXIgbGlzdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIE1JTUUgdHlwZSBhbmQgc3ViLXR5cGUKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEJhc2VUeXBlKCkgeworICAgICAgICByZXR1cm4gcHJpbWFyeVR5cGUgKyAiLyIgKyBzdWJUeXBlOworICAgIH0KKworICAgIC8qKgorICAgICAqIERldGVybWluZSBpZiB0aGUgcHJpbWFyeSBhbmQgc3ViIHR5cGUgb2YgdGhpcyBvYmplY3QgaXMKKyAgICAgKiB0aGUgc2FtZSBhcyB3aGF0IGlzIGluIHRoZSBnaXZlbiB0eXBlLgorICAgICAqCisgICAgICogQHBhcmFtIHR5cGUJdGhlIE1pbWVUeXBlIG9iamVjdCB0byBjb21wYXJlIHdpdGgKKyAgICAgKiBAcmV0dXJuCQl0cnVlIGlmIHRoZXkgbWF0Y2gKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBtYXRjaChNaW1lVHlwZSB0eXBlKSB7CisgICAgICAgIHJldHVybiBwcmltYXJ5VHlwZS5lcXVhbHModHlwZS5nZXRQcmltYXJ5VHlwZSgpKQorICAgICAgICAgICAgICAgICAgICAmJiAoc3ViVHlwZS5lcXVhbHMoIioiKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IHR5cGUuZ2V0U3ViVHlwZSgpLmVxdWFscygiKiIpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgKHN1YlR5cGUuZXF1YWxzKHR5cGUuZ2V0U3ViVHlwZSgpKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERldGVybWluZSBpZiB0aGUgcHJpbWFyeSBhbmQgc3ViIHR5cGUgb2YgdGhpcyBvYmplY3QgaXMKKyAgICAgKiB0aGUgc2FtZSBhcyB0aGUgY29udGVudCB0eXBlIGRlc2NyaWJlZCBpbiByYXdkYXRhLgorICAgICAqCisgICAgICogQHBhcmFtIHJhd2RhdGEJdGhlIE1JTUUgdHlwZSBzdHJpbmcgdG8gY29tcGFyZSB3aXRoCisgICAgICogQHJldHVybgkJdHJ1ZSBpZiB0aGV5IG1hdGNoCisgICAgICogQGV4Y2VwdGlvbglNaW1lVHlwZVBhcnNlRXhjZXB0aW9uCWlmIHRoZSBNSU1FIHR5cGUgY2FuJ3QgYmUgcGFyc2VkCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gbWF0Y2goU3RyaW5nIHJhd2RhdGEpIHRocm93cyBNaW1lVHlwZVBhcnNlRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG1hdGNoKG5ldyBNaW1lVHlwZShyYXdkYXRhKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIG9iamVjdCBpbXBsZW1lbnRzIHRoZSB3cml0ZUV4dGVybmFsIG1ldGhvZCB0byBzYXZlIGl0cyBjb250ZW50cworICAgICAqIGJ5IGNhbGxpbmcgdGhlIG1ldGhvZHMgb2YgRGF0YU91dHB1dCBmb3IgaXRzIHByaW1pdGl2ZSB2YWx1ZXMgb3IKKyAgICAgKiBjYWxsaW5nIHRoZSB3cml0ZU9iamVjdCBtZXRob2Qgb2YgT2JqZWN0T3V0cHV0IGZvciBvYmplY3RzLCBzdHJpbmdzCisgICAgICogYW5kIGFycmF5cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvdXQJdGhlIE9iamVjdE91dHB1dCBvYmplY3QgdG8gd3JpdGUgdG8KKyAgICAgKiBAZXhjZXB0aW9uIElPRXhjZXB0aW9uIEluY2x1ZGVzIGFueSBJL08gZXhjZXB0aW9ucyB0aGF0IG1heSBvY2N1cgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHdyaXRlRXh0ZXJuYWwoT2JqZWN0T3V0cHV0IG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb3V0LndyaXRlVVRGKHRvU3RyaW5nKCkpOworCW91dC5mbHVzaCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBvYmplY3QgaW1wbGVtZW50cyB0aGUgcmVhZEV4dGVybmFsIG1ldGhvZCB0byByZXN0b3JlIGl0cworICAgICAqIGNvbnRlbnRzIGJ5IGNhbGxpbmcgdGhlIG1ldGhvZHMgb2YgRGF0YUlucHV0IGZvciBwcmltaXRpdmUKKyAgICAgKiB0eXBlcyBhbmQgcmVhZE9iamVjdCBmb3Igb2JqZWN0cywgc3RyaW5ncyBhbmQgYXJyYXlzLiAgVGhlCisgICAgICogcmVhZEV4dGVybmFsIG1ldGhvZCBtdXN0IHJlYWQgdGhlIHZhbHVlcyBpbiB0aGUgc2FtZSBzZXF1ZW5jZQorICAgICAqIGFuZCB3aXRoIHRoZSBzYW1lIHR5cGVzIGFzIHdlcmUgd3JpdHRlbiBieSB3cml0ZUV4dGVybmFsLgorICAgICAqCisgICAgICogQHBhcmFtIGluCXRoZSBPYmplY3RJbnB1dCBvYmplY3QgdG8gcmVhZCBmcm9tCisgICAgICogQGV4Y2VwdGlvbiBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIElmIHRoZSBjbGFzcyBmb3IgYW4gb2JqZWN0IGJlaW5nCisgICAgICogICAgICAgICAgICAgIHJlc3RvcmVkIGNhbm5vdCBiZSBmb3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZWFkRXh0ZXJuYWwoT2JqZWN0SW5wdXQgaW4pCisJCQkJdGhyb3dzIElPRXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHBhcnNlKGluLnJlYWRVVEYoKSk7CisgICAgICAgIH0gY2F0Y2ggKE1pbWVUeXBlUGFyc2VFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyAgICBiZWxvdyBoZXJlIGJlIHNjYXJ5IHBhcnNpbmcgcmVsYXRlZCB0aGluZ3MKKworICAgIC8qKgorICAgICAqIERldGVybWluZSB3aGV0aGVyIG9yIG5vdCBhIGdpdmVuIGNoYXJhY3RlciBiZWxvbmdzIHRvIGEgbGVnYWwgdG9rZW4uCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc1Rva2VuQ2hhcihjaGFyIGMpIHsKKyAgICAgICAgcmV0dXJuICgoYyA+IDA0MCkgJiYgKGMgPCAwMTc3KSkgJiYgKFRTUEVDSUFMUy5pbmRleE9mKGMpIDwgMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lIHdoZXRoZXIgb3Igbm90IGEgZ2l2ZW4gc3RyaW5nIGlzIGEgbGVnYWwgdG9rZW4uCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGlzVmFsaWRUb2tlbihTdHJpbmcgcykgeworICAgICAgICBpbnQgbGVuID0gcy5sZW5ndGgoKTsKKyAgICAgICAgaWYgKGxlbiA+IDApIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyArK2kpIHsKKyAgICAgICAgICAgICAgICBjaGFyIGMgPSBzLmNoYXJBdChpKTsKKyAgICAgICAgICAgICAgICBpZiAoIWlzVG9rZW5DaGFyKGMpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEEgc2ltcGxlIHBhcnNlciB0ZXN0LAorICAgICAqIGZvciBkZWJ1Z2dpbmcuLi4KKyAgICAgKgorICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpCisJCQkJdGhyb3dzIE1pbWVUeXBlUGFyc2VFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcmdzLmxlbmd0aDsgKytpKSB7CisgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIk9yaWdpbmFsOiAiICsgYXJnc1tpXSk7CisKKyAgICAgICAgICAgIE1pbWVUeXBlIHR5cGUgPSBuZXcgTWltZVR5cGUoYXJnc1tpXSk7CisKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiU2hvcnQ6ICAgICIgKyB0eXBlLmdldEJhc2VUeXBlKCkpOworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJQYXJzZWQ6ICAgIiArIHR5cGUudG9TdHJpbmcoKSk7CisgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oKTsKKyAgICAgICAgfQorICAgIH0KKyAgICAqLworfQpkaWZmIC0tZ2l0IGEvYW5kcm9pZC9hY3RpdmF0aW9uL3NyYy9tYWluL2phdmEvamF2YXgvYWN0aXZhdGlvbi9NaW1lVHlwZVBhcmFtZXRlckxpc3QuamF2YSBiL2FuZHJvaWQvYWN0aXZhdGlvbi9zcmMvbWFpbi9qYXZhL2phdmF4L2FjdGl2YXRpb24vTWltZVR5cGVQYXJhbWV0ZXJMaXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjI5ODA2MwotLS0gL2Rldi9udWxsCisrKyBiL2FuZHJvaWQvYWN0aXZhdGlvbi9zcmMvbWFpbi9qYXZhL2phdmF4L2FjdGl2YXRpb24vTWltZVR5cGVQYXJhbWV0ZXJMaXN0LmphdmEKQEAgLTAsMCArMSwzMjQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorICovCisKK3BhY2thZ2UgamF2YXguYWN0aXZhdGlvbjsKKworaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7CitpbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CisKKy8qKgorICogQSBwYXJhbWV0ZXIgbGlzdCBvZiBhIE1pbWVUeXBlCisgKiBhcyBkZWZpbmVkIGluIFJGQyAyMDQ1IGFuZCAyMDQ2LiBUaGUgUHJpbWFyeSB0eXBlIG9mIHRoZQorICogb2JqZWN0IG11c3QgYWxyZWFkeSBiZSBzdHJpcHBlZCBvZmYuCisgKgorICogQHNlZSBqYXZheC5hY3RpdmF0aW9uLk1pbWVUeXBlCisgKi8KK3B1YmxpYyBjbGFzcyBNaW1lVHlwZVBhcmFtZXRlckxpc3QgeworICAgIHByaXZhdGUgSGFzaHRhYmxlIHBhcmFtZXRlcnM7CisKKyAgICAvKioKKyAgICAgKiBBIHN0cmluZyB0aGF0IGhvbGRzIGFsbCB0aGUgc3BlY2lhbCBjaGFycy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVFNQRUNJQUxTID0gIigpPD5ALDs6L1tdPz1cXFwiIjsKKworCisgICAgLyoqCisgICAgICogRGVmYXVsdCBjb25zdHJ1Y3Rvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgTWltZVR5cGVQYXJhbWV0ZXJMaXN0KCkgeworICAgICAgICBwYXJhbWV0ZXJzID0gbmV3IEhhc2h0YWJsZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBuZXcgTWltZVR5cGVQYXJhbWV0ZXJMaXN0IHdpdGggdGhlIHBhc3NlZCBpbiBkYXRhLgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmFtZXRlckxpc3QgYW4gUkZDIDIwNDUsIDIwNDYgY29tcGxpYW50IHBhcmFtZXRlciBsaXN0LgorICAgICAqIEBleGNlcHRpb24JTWltZVR5cGVQYXJzZUV4Y2VwdGlvbglpZiB0aGUgTUlNRSB0eXBlIGNhbid0IGJlIHBhcnNlZAorICAgICAqLworICAgIHB1YmxpYyBNaW1lVHlwZVBhcmFtZXRlckxpc3QoU3RyaW5nIHBhcmFtZXRlckxpc3QpCisJCQkJCXRocm93cyBNaW1lVHlwZVBhcnNlRXhjZXB0aW9uIHsKKyAgICAgICAgcGFyYW1ldGVycyA9IG5ldyBIYXNodGFibGUoKTsKKworICAgICAgICAvLyAgICBub3cgcGFyc2UgcmF3ZGF0YQorICAgICAgICBwYXJzZShwYXJhbWV0ZXJMaXN0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBIHJvdXRpbmUgZm9yIHBhcnNpbmcgdGhlIHBhcmFtZXRlciBsaXN0IG91dCBvZiBhIFN0cmluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJMaXN0IGFuIFJGQyAyMDQ1LCAyMDQ2IGNvbXBsaWFudCBwYXJhbWV0ZXIgbGlzdC4KKyAgICAgKiBAZXhjZXB0aW9uCU1pbWVUeXBlUGFyc2VFeGNlcHRpb24JaWYgdGhlIE1JTUUgdHlwZSBjYW4ndCBiZSBwYXJzZWQKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBwYXJzZShTdHJpbmcgcGFyYW1ldGVyTGlzdCkgdGhyb3dzIE1pbWVUeXBlUGFyc2VFeGNlcHRpb24geworCWlmIChwYXJhbWV0ZXJMaXN0ID09IG51bGwpCisJICAgIHJldHVybjsKKworICAgICAgICBpbnQgbGVuZ3RoID0gcGFyYW1ldGVyTGlzdC5sZW5ndGgoKTsKKyAgICAgICAgaWYgKGxlbmd0aCA8PSAwKQorCSAgICByZXR1cm47CisKKwlpbnQgaTsKKwljaGFyIGM7CisJZm9yIChpID0gc2tpcFdoaXRlU3BhY2UocGFyYW1ldGVyTGlzdCwgMCk7CisJCWkgPCBsZW5ndGggJiYgKGMgPSBwYXJhbWV0ZXJMaXN0LmNoYXJBdChpKSkgPT0gJzsnOworCQlpID0gc2tpcFdoaXRlU3BhY2UocGFyYW1ldGVyTGlzdCwgaSkpIHsKKwkgICAgaW50IGxhc3RJbmRleDsKKwkgICAgU3RyaW5nIG5hbWU7CisJICAgIFN0cmluZyB2YWx1ZTsKKworCSAgICAvLyAgICBlYXQgdGhlICc7JworCSAgICBpKys7CisKKwkgICAgLy8gICAgbm93IHBhcnNlIHRoZSBwYXJhbWV0ZXIgbmFtZQorCisJICAgIC8vICAgIHNraXAgd2hpdGVzcGFjZQorCSAgICBpID0gc2tpcFdoaXRlU3BhY2UocGFyYW1ldGVyTGlzdCwgaSk7CisKKwkgICAgLy8gdG9sZXJhdGUgdHJhaWxpbmcgc2VtaWNvbG9uLCBldmVuIHRob3VnaCBpdCB2aW9sYXRlcyB0aGUgc3BlYworCSAgICBpZiAoaSA+PSBsZW5ndGgpCisJCXJldHVybjsKKworCSAgICAvLyAgICBmaW5kIHRoZSBlbmQgb2YgdGhlIHRva2VuIGNoYXIgcnVuCisJICAgIGxhc3RJbmRleCA9IGk7CisJICAgIHdoaWxlICgoaSA8IGxlbmd0aCkgJiYgaXNUb2tlbkNoYXIocGFyYW1ldGVyTGlzdC5jaGFyQXQoaSkpKQorCQlpKys7CisKKwkgICAgbmFtZSA9IHBhcmFtZXRlckxpc3Quc3Vic3RyaW5nKGxhc3RJbmRleCwgaSkuCisJCQkJCQl0b0xvd2VyQ2FzZShMb2NhbGUuRU5HTElTSCk7CisKKwkgICAgLy8gICAgbm93IHBhcnNlIHRoZSAnPScgdGhhdCBzZXBhcmF0ZXMgdGhlIG5hbWUgZnJvbSB0aGUgdmFsdWUKKwkgICAgaSA9IHNraXBXaGl0ZVNwYWNlKHBhcmFtZXRlckxpc3QsIGkpOworCisJICAgIGlmIChpID49IGxlbmd0aCB8fCBwYXJhbWV0ZXJMaXN0LmNoYXJBdChpKSAhPSAnPScpCisJCXRocm93IG5ldyBNaW1lVHlwZVBhcnNlRXhjZXB0aW9uKAorCQkgICAgIkNvdWxkbid0IGZpbmQgdGhlICc9JyB0aGF0IHNlcGFyYXRlcyBhICIgKworCQkgICAgInBhcmFtZXRlciBuYW1lIGZyb20gaXRzIHZhbHVlLiIpOworCisJICAgIC8vICAgIGVhdCBpdCBhbmQgcGFyc2UgdGhlIHBhcmFtZXRlciB2YWx1ZQorCSAgICBpKys7CisJICAgIGkgPSBza2lwV2hpdGVTcGFjZShwYXJhbWV0ZXJMaXN0LCBpKTsKKworCSAgICBpZiAoaSA+PSBsZW5ndGgpCisJCXRocm93IG5ldyBNaW1lVHlwZVBhcnNlRXhjZXB0aW9uKAorCQkJIkNvdWxkbid0IGZpbmQgYSB2YWx1ZSBmb3IgcGFyYW1ldGVyIG5hbWVkICIgKyBuYW1lKTsKKworCSAgICAvLyAgICBub3cgZmluZCBvdXQgd2hldGhlciBvciBub3Qgd2UgaGF2ZSBhIHF1b3RlZCB2YWx1ZQorCSAgICBjID0gcGFyYW1ldGVyTGlzdC5jaGFyQXQoaSk7CisJICAgIGlmIChjID09ICciJykgeworCQkvLyAgICB5dXAgaXQncyBxdW90ZWQgc28gZWF0IGl0IGFuZCBjYXB0dXJlIHRoZSBxdW90ZWQgc3RyaW5nCisJCWkrKzsKKwkJaWYgKGkgPj0gbGVuZ3RoKQorCQkgICAgdGhyb3cgbmV3IE1pbWVUeXBlUGFyc2VFeGNlcHRpb24oCisJCQkgICAgIkVuY291bnRlcmVkIHVudGVybWluYXRlZCBxdW90ZWQgcGFyYW1ldGVyIHZhbHVlLiIpOworCisJCWxhc3RJbmRleCA9IGk7CisKKwkJLy8gICAgZmluZCB0aGUgbmV4dCB1bmVzY2FwZWQgcXVvdGUKKwkJd2hpbGUgKGkgPCBsZW5ndGgpIHsKKwkJICAgIGMgPSBwYXJhbWV0ZXJMaXN0LmNoYXJBdChpKTsKKwkJICAgIGlmIChjID09ICciJykKKwkJCWJyZWFrOworCQkgICAgaWYgKGMgPT0gJ1xcJykgeworCQkJLy8gICAgZm91bmQgYW4gZXNjYXBlIHNlcXVlbmNlCisJCQkvLyAgICBzbyBza2lwIHRoaXMgYW5kIHRoZQorCQkJLy8gICAgbmV4dCBjaGFyYWN0ZXIKKwkJCWkrKzsKKwkJICAgIH0KKwkJICAgIGkrKzsKKwkJfQorCQlpZiAoYyAhPSAnIicpCisJCSAgICB0aHJvdyBuZXcgTWltZVR5cGVQYXJzZUV4Y2VwdGlvbigKKwkJCSJFbmNvdW50ZXJlZCB1bnRlcm1pbmF0ZWQgcXVvdGVkIHBhcmFtZXRlciB2YWx1ZS4iKTsKKworCQl2YWx1ZSA9IHVucXVvdGUocGFyYW1ldGVyTGlzdC5zdWJzdHJpbmcobGFzdEluZGV4LCBpKSk7CisJCS8vICAgIGVhdCB0aGUgcXVvdGUKKwkJaSsrOworCSAgICB9IGVsc2UgaWYgKGlzVG9rZW5DaGFyKGMpKSB7CisJCS8vICAgIG5vcGUgaXQncyBhbiBvcmRpbmFyeSB0b2tlbiBzbyBpdAorCQkvLyAgICBlbmRzIHdpdGggYSBub24tdG9rZW4gY2hhcgorCQlsYXN0SW5kZXggPSBpOworCQl3aGlsZSAoaSA8IGxlbmd0aCAmJiBpc1Rva2VuQ2hhcihwYXJhbWV0ZXJMaXN0LmNoYXJBdChpKSkpCisJCSAgICBpKys7CisJCXZhbHVlID0gcGFyYW1ldGVyTGlzdC5zdWJzdHJpbmcobGFzdEluZGV4LCBpKTsKKwkgICAgfSBlbHNlIHsKKwkJLy8gICAgaXQgYWluJ3QgYSB2YWx1ZQorCQl0aHJvdyBuZXcgTWltZVR5cGVQYXJzZUV4Y2VwdGlvbigKKwkJCSJVbmV4cGVjdGVkIGNoYXJhY3RlciBlbmNvdW50ZXJlZCBhdCBpbmRleCAiICsgaSk7CisJICAgIH0KKworCSAgICAvLyAgICBub3cgcHV0IHRoZSBkYXRhIGludG8gdGhlIGhhc2h0YWJsZQorCSAgICBwYXJhbWV0ZXJzLnB1dChuYW1lLCB2YWx1ZSk7CisJfQorCWlmIChpIDwgbGVuZ3RoKSB7CisJICAgIHRocm93IG5ldyBNaW1lVHlwZVBhcnNlRXhjZXB0aW9uKAorCQkiTW9yZSBjaGFyYWN0ZXJzIGVuY291bnRlcmVkIGluIGlucHV0IHRoYW4gZXhwZWN0ZWQuIik7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgbnVtYmVyIG9mIG5hbWUtdmFsdWUgcGFpcnMgaW4gdGhpcyBsaXN0LgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgbnVtYmVyIG9mIHBhcmFtZXRlcnMKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHNpemUoKSB7CisgICAgICAgIHJldHVybiBwYXJhbWV0ZXJzLnNpemUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmUgd2hldGhlciBvciBub3QgdGhpcyBsaXN0IGlzIGVtcHR5LgorICAgICAqCisgICAgICogQHJldHVybgl0cnVlIGlmIHRoZXJlIGFyZSBubyBwYXJhbWV0ZXJzCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpIHsKKyAgICAgICAgcmV0dXJuIHBhcmFtZXRlcnMuaXNFbXB0eSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHJpZXZlIHRoZSB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG5hbWUsIG9yIG51bGwgaWYgdGhlcmUKKyAgICAgKiBpcyBubyBjdXJyZW50IGFzc29jaWF0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUJdGhlIHBhcmFtZXRlciBuYW1lCisgICAgICogQHJldHVybgkJdGhlIHBhcmFtZXRlcidzIHZhbHVlCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXQoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgcmV0dXJuIChTdHJpbmcpcGFyYW1ldGVycy5nZXQobmFtZS50cmltKCkudG9Mb3dlckNhc2UoTG9jYWxlLkVOR0xJU0gpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHZhbHVlIHRvIGJlIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbmFtZSwgcmVwbGFjaW5nCisgICAgICogYW55IHByZXZpb3VzIGFzc29jaWF0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUJdGhlIHBhcmFtZXRlciBuYW1lCisgICAgICogQHBhcmFtIHZhbHVlCXRoZSBwYXJhbWV0ZXIncyB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldChTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKSB7CisgICAgICAgIHBhcmFtZXRlcnMucHV0KG5hbWUudHJpbSgpLnRvTG93ZXJDYXNlKExvY2FsZS5FTkdMSVNIKSwgdmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZSBhbnkgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBuYW1lLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUJdGhlIHBhcmFtZXRlciBuYW1lCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVtb3ZlKFN0cmluZyBuYW1lKSB7CisgICAgICAgIHBhcmFtZXRlcnMucmVtb3ZlKG5hbWUudHJpbSgpLnRvTG93ZXJDYXNlKExvY2FsZS5FTkdMSVNIKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0cmlldmUgYW4gZW51bWVyYXRpb24gb2YgYWxsIHRoZSBuYW1lcyBpbiB0aGlzIGxpc3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCWFuIGVudW1lcmF0aW9uIG9mIGFsbCBwYXJhbWV0ZXIgbmFtZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgRW51bWVyYXRpb24gZ2V0TmFtZXMoKSB7CisgICAgICAgIHJldHVybiBwYXJhbWV0ZXJzLmtleXMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgU3RyaW5nQnVmZmVyIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKyAgICAgICAgYnVmZmVyLmVuc3VyZUNhcGFjaXR5KHBhcmFtZXRlcnMuc2l6ZSgpICogMTYpOworCQkJLy8gICAgaGV1cmlzdGljOiA4IGNoYXJhY3RlcnMgcGVyIGZpZWxkCisKKyAgICAgICAgRW51bWVyYXRpb24ga2V5cyA9IHBhcmFtZXRlcnMua2V5cygpOworICAgICAgICB3aGlsZSAoa2V5cy5oYXNNb3JlRWxlbWVudHMoKSkgeworICAgICAgICAgICAgU3RyaW5nIGtleSA9IChTdHJpbmcpa2V5cy5uZXh0RWxlbWVudCgpOworICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgiOyAiKTsKKyAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoa2V5KTsKKyAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoJz0nKTsKKwkgICAgYnVmZmVyLmFwcGVuZChxdW90ZSgoU3RyaW5nKXBhcmFtZXRlcnMuZ2V0KGtleSkpKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBidWZmZXIudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvLyAgICBiZWxvdyBoZXJlIGJlIHNjYXJ5IHBhcnNpbmcgcmVsYXRlZCB0aGluZ3MKKworICAgIC8qKgorICAgICAqIERldGVybWluZSB3aGV0aGVyIG9yIG5vdCBhIGdpdmVuIGNoYXJhY3RlciBiZWxvbmdzIHRvIGEgbGVnYWwgdG9rZW4uCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc1Rva2VuQ2hhcihjaGFyIGMpIHsKKyAgICAgICAgcmV0dXJuICgoYyA+IDA0MCkgJiYgKGMgPCAwMTc3KSkgJiYgKFRTUEVDSUFMUy5pbmRleE9mKGMpIDwgMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogcmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgZmlyc3Qgbm9uIHdoaXRlIHNwYWNlIGNoYXJhY3RlciBpbgorICAgICAqIHJhd2RhdGEgYXQgb3IgYWZ0ZXIgaW5kZXggaS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBpbnQgc2tpcFdoaXRlU3BhY2UoU3RyaW5nIHJhd2RhdGEsIGludCBpKSB7CisgICAgICAgIGludCBsZW5ndGggPSByYXdkYXRhLmxlbmd0aCgpOworCXdoaWxlICgoaSA8IGxlbmd0aCkgJiYgQ2hhcmFjdGVyLmlzV2hpdGVzcGFjZShyYXdkYXRhLmNoYXJBdChpKSkpCisJICAgIGkrKzsKKyAgICAgICAgcmV0dXJuIGk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQSByb3V0aW5lIHRoYXQga25vd3MgaG93IGFuZCB3aGVuIHRvIHF1b3RlIGFuZCBlc2NhcGUgdGhlIGdpdmVuIHZhbHVlLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBxdW90ZShTdHJpbmcgdmFsdWUpIHsKKyAgICAgICAgYm9vbGVhbiBuZWVkc1F1b3RlcyA9IGZhbHNlOworCisgICAgICAgIC8vICAgIGNoZWNrIHRvIHNlZSBpZiB3ZSBhY3R1YWxseSBoYXZlIHRvIHF1b3RlIHRoaXMgdGhpbmcKKyAgICAgICAgaW50IGxlbmd0aCA9IHZhbHVlLmxlbmd0aCgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgKGkgPCBsZW5ndGgpICYmICFuZWVkc1F1b3RlczsgaSsrKSB7CisgICAgICAgICAgICBuZWVkc1F1b3RlcyA9ICFpc1Rva2VuQ2hhcih2YWx1ZS5jaGFyQXQoaSkpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKG5lZWRzUXVvdGVzKSB7CisgICAgICAgICAgICBTdHJpbmdCdWZmZXIgYnVmZmVyID0gbmV3IFN0cmluZ0J1ZmZlcigpOworICAgICAgICAgICAgYnVmZmVyLmVuc3VyZUNhcGFjaXR5KChpbnQpKGxlbmd0aCAqIDEuNSkpOworCisgICAgICAgICAgICAvLyAgICBhZGQgdGhlIGluaXRpYWwgcXVvdGUKKyAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoJyInKTsKKworICAgICAgICAgICAgLy8gICAgYWRkIHRoZSBwcm9wZXJseSBlc2NhcGVkIHRleHQKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgICAgICBjaGFyIGMgPSB2YWx1ZS5jaGFyQXQoaSk7CisgICAgICAgICAgICAgICAgaWYgKChjID09ICdcXCcpIHx8IChjID09ICciJykpCisgICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoJ1xcJyk7CisgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChjKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gICAgYWRkIHRoZSBjbG9zaW5nIHF1b3RlCisgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCciJyk7CisKKyAgICAgICAgICAgIHJldHVybiBidWZmZXIudG9TdHJpbmcoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEEgcm91dGluZSB0aGF0IGtub3dzIGhvdyB0byBzdHJpcCB0aGUgcXVvdGVzIGFuZAorICAgICAqIGVzY2FwZSBzZXF1ZW5jZXMgZnJvbSB0aGUgZ2l2ZW4gdmFsdWUuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIHVucXVvdGUoU3RyaW5nIHZhbHVlKSB7CisgICAgICAgIGludCB2YWx1ZUxlbmd0aCA9IHZhbHVlLmxlbmd0aCgpOworICAgICAgICBTdHJpbmdCdWZmZXIgYnVmZmVyID0gbmV3IFN0cmluZ0J1ZmZlcigpOworICAgICAgICBidWZmZXIuZW5zdXJlQ2FwYWNpdHkodmFsdWVMZW5ndGgpOworCisgICAgICAgIGJvb2xlYW4gZXNjYXBlZCA9IGZhbHNlOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbHVlTGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgIGNoYXIgY3VycmVudENoYXIgPSB2YWx1ZS5jaGFyQXQoaSk7CisgICAgICAgICAgICBpZiAoIWVzY2FwZWQgJiYgKGN1cnJlbnRDaGFyICE9ICdcXCcpKSB7CisgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChjdXJyZW50Q2hhcik7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGVzY2FwZWQpIHsKKyAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKGN1cnJlbnRDaGFyKTsKKyAgICAgICAgICAgICAgICBlc2NhcGVkID0gZmFsc2U7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGVzY2FwZWQgPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGJ1ZmZlci50b1N0cmluZygpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2FuZHJvaWQvYWN0aXZhdGlvbi9zcmMvbWFpbi9qYXZhL2phdmF4L2FjdGl2YXRpb24vTWltZVR5cGVQYXJzZUV4Y2VwdGlvbi5qYXZhIGIvYW5kcm9pZC9hY3RpdmF0aW9uL3NyYy9tYWluL2phdmEvamF2YXgvYWN0aXZhdGlvbi9NaW1lVHlwZVBhcnNlRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmQwMDBlMgotLS0gL2Rldi9udWxsCisrKyBiL2FuZHJvaWQvYWN0aXZhdGlvbi9zcmMvbWFpbi9qYXZhL2phdmF4L2FjdGl2YXRpb24vTWltZVR5cGVQYXJzZUV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsMzMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorICovCisKK3BhY2thZ2UgamF2YXguYWN0aXZhdGlvbjsKKworLyoqCisgKiBBIGNsYXNzIHRvIGVuY2Fwc3VsYXRlIE1pbWVUeXBlIHBhcnNpbmcgcmVsYXRlZCBleGNlcHRpb25zLgorICovCitwdWJsaWMgY2xhc3MgTWltZVR5cGVQYXJzZUV4Y2VwdGlvbiBleHRlbmRzIEV4Y2VwdGlvbiB7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgTWltZVR5cGVQYXJzZUV4Y2VwdGlvbiB3aXRoIG5vIHNwZWNpZmllZCBkZXRhaWwgbWVzc2FnZS4gCisgICAgICovCisgICAgcHVibGljIE1pbWVUeXBlUGFyc2VFeGNlcHRpb24oKSB7CisJc3VwZXIoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgTWltZVR5cGVQYXJzZUV4Y2VwdGlvbiB3aXRoIHRoZSBzcGVjaWZpZWQgZGV0YWlsIG1lc3NhZ2UuIAorICAgICAqCisgICAgICogQHBhcmFtICAgcyAgIHRoZSBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTWltZVR5cGVQYXJzZUV4Y2VwdGlvbihTdHJpbmcgcykgeworCXN1cGVyKHMpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2FuZHJvaWQvYWN0aXZhdGlvbi9zcmMvbWFpbi9qYXZhL2phdmF4L2FjdGl2YXRpb24vTWltZXR5cGVzRmlsZVR5cGVNYXAuamF2YSBiL2FuZHJvaWQvYWN0aXZhdGlvbi9zcmMvbWFpbi9qYXZhL2phdmF4L2FjdGl2YXRpb24vTWltZXR5cGVzRmlsZVR5cGVNYXAuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMmRmZmI3Ci0tLSAvZGV2L251bGwKKysrIGIvYW5kcm9pZC9hY3RpdmF0aW9uL3NyYy9tYWluL2phdmEvamF2YXgvYWN0aXZhdGlvbi9NaW1ldHlwZXNGaWxlVHlwZU1hcC5qYXZhCkBAIC0wLDAgKzEsMzQzIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBEaXN0cmlidXRpb24gTGljZW5zZSB2LiAxLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9vcmcvZG9jdW1lbnRzL2VkbC12MTAucGhwLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBCU0QtMy1DbGF1c2UKKyAqLworCitwYWNrYWdlIGphdmF4LmFjdGl2YXRpb247CisKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YS5uZXQuKjsKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkFjY2Vzc0NvbnRyb2xsZXI7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Qcml2aWxlZ2VkQWN0aW9uOworaW1wb3J0IGNvbS5zdW4uYWN0aXZhdGlvbi5yZWdpc3RyaWVzLk1pbWVUeXBlRmlsZTsKK2ltcG9ydCBjb20uc3VuLmFjdGl2YXRpb24ucmVnaXN0cmllcy5Mb2dTdXBwb3J0OworCisvKioKKyAqIFRoaXMgY2xhc3MgZXh0ZW5kcyBGaWxlVHlwZU1hcCBhbmQgcHJvdmlkZXMgZGF0YSB0eXBpbmcgb2YgZmlsZXMKKyAqIHZpYSB0aGVpciBmaWxlIGV4dGVuc2lvbi4gSXQgdXNlcyB0aGUgPGNvZGU+Lm1pbWUudHlwZXM8L2NvZGU+IGZvcm1hdC4gPHA+CisgKgorICogPGI+TUlNRSB0eXBlcyBmaWxlIHNlYXJjaCBvcmRlcjo8L2I+PHA+CisgKiBUaGUgTWltZXR5cGVzRmlsZVR5cGVNYXAgbG9va3MgaW4gdmFyaW91cyBwbGFjZXMgaW4gdGhlIHVzZXIncworICogc3lzdGVtIGZvciBNSU1FIHR5cGVzIGZpbGUgZW50cmllcy4gV2hlbiByZXF1ZXN0cyBhcmUgbWFkZQorICogdG8gc2VhcmNoIGZvciBNSU1FIHR5cGVzIGluIHRoZSBNaW1ldHlwZXNGaWxlVHlwZU1hcCwgaXQgc2VhcmNoZXMgIAorICogTUlNRSB0eXBlcyBmaWxlcyBpbiB0aGUgZm9sbG93aW5nIG9yZGVyOgorICogPG9sPgorICogPGxpPiBQcm9ncmFtbWF0aWNhbGx5IGFkZGVkIGVudHJpZXMgdG8gdGhlIE1pbWV0eXBlc0ZpbGVUeXBlTWFwIGluc3RhbmNlLgorICogPGxpPiBUaGUgZmlsZSA8Y29kZT4ubWltZS50eXBlczwvY29kZT4gaW4gdGhlIHVzZXIncyBob21lIGRpcmVjdG9yeS4KKyAqIDxsaT4gVGhlIGZpbGUgPGNvZGU+bWltZS50eXBlczwvY29kZT4gaW4gdGhlIEphdmEgcnVudGltZS4KKyAqIDxsaT4gVGhlIGZpbGUgb3IgcmVzb3VyY2VzIG5hbWVkIDxjb2RlPk1FVEEtSU5GL21pbWUudHlwZXM8L2NvZGU+LgorICogPGxpPiBUaGUgZmlsZSBvciByZXNvdXJjZSBuYW1lZCA8Y29kZT5NRVRBLUlORi9taW1ldHlwZXMuZGVmYXVsdDwvY29kZT4KKyAqICh1c3VhbGx5IGZvdW5kIG9ubHkgaW4gdGhlIDxjb2RlPmFjdGl2YXRpb24uamFyPC9jb2RlPiBmaWxlKS4KKyAqIDwvb2w+CisgKiA8cD4KKyAqIChUaGUgY3VycmVudCBpbXBsZW1lbnRhdGlvbiBsb29rcyBmb3IgdGhlIDxjb2RlPm1pbWUudHlwZXM8L2NvZGU+IGZpbGUKKyAqIGluIHRoZSBKYXZhIHJ1bnRpbWUgaW4gdGhlIGRpcmVjdG9yeSA8Y29kZT48aT5qYXZhLmhvbWU8L2k+L2NvbmY8L2NvZGU+CisgKiBpZiBpdCBleGlzdHMsIGFuZCBvdGhlcndpc2UgaW4gdGhlIGRpcmVjdG9yeQorICogPGNvZGU+PGk+amF2YS5ob21lPC9pPi9saWI8L2NvZGU+LCB3aGVyZSA8aT5qYXZhLmhvbWU8L2k+IGlzIHRoZSB2YWx1ZQorICogb2YgdGhlICJqYXZhLmhvbWUiIFN5c3RlbSBwcm9wZXJ0eS4gIE5vdGUgdGhhdCB0aGUgImNvbmYiIGRpcmVjdG9yeSB3YXMKKyAqIGludHJvZHVjZWQgaW4gSkRLIDkuKQorICogPHA+CisgKiA8Yj5NSU1FIHR5cGVzIGZpbGUgZm9ybWF0OjwvYj48cD4KKyAqCisgKiA8Y29kZT4KKyAqICMgY29tbWVudHMgYmVnaW4gd2l0aCBhICcjJzxicj4KKyAqICMgdGhlIGZvcm1hdCBpcyAmbHQ7bWltZSB0eXBlJmd0OyAmbHQ7c3BhY2Ugc2VwYXJhdGVkIGZpbGUgZXh0ZW5zaW9ucyZndDs8YnI+CisgKiAjIGZvciBleGFtcGxlOjxicj4KKyAqIHRleHQvcGxhaW4gICAgdHh0IHRleHQgVFhUPGJyPgorICogIyB0aGlzIHdvdWxkIG1hcCBmaWxlLnR4dCwgZmlsZS50ZXh0LCBhbmQgZmlsZS5UWFQgdG88YnI+CisgKiAjIHRoZSBtaW1lIHR5cGUgInRleHQvcGxhaW4iPGJyPgorICogPC9jb2RlPgorICoKKyAqIEBhdXRob3IgQmFydCBDYWxkZXIKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKi8KK3B1YmxpYyBjbGFzcyBNaW1ldHlwZXNGaWxlVHlwZU1hcCBleHRlbmRzIEZpbGVUeXBlTWFwIHsKKyAgICAvKgorICAgICAqIFdlIG1hbmFnZSBhIGNvbGxlY3Rpb24gb2YgZGF0YWJhc2VzLCBzZWFyY2hlZCBpbiBvcmRlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIE1pbWVUeXBlRmlsZVtdIERCOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBQUk9HID0gMDsJLy8gcHJvZ3JhbW1hdGljYWxseSBhZGRlZCBlbnRyaWVzCisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgZGVmYXVsdFR5cGUgPSAiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBjb25mRGlyOworCisgICAgc3RhdGljIHsKKwlTdHJpbmcgZGlyID0gbnVsbDsKKwl0cnkgeworCSAgICBkaXIgPSAoU3RyaW5nKUFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKAorCQluZXcgUHJpdmlsZWdlZEFjdGlvbigpIHsKKwkJICAgIHB1YmxpYyBPYmplY3QgcnVuKCkgeworCQkJU3RyaW5nIGhvbWUgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImphdmEuaG9tZSIpOworCQkJU3RyaW5nIG5ld2RpciA9IGhvbWUgKyBGaWxlLnNlcGFyYXRvciArICJjb25mIjsKKwkJCUZpbGUgY29uZiA9IG5ldyBGaWxlKG5ld2Rpcik7CisJCQlpZiAoY29uZi5leGlzdHMoKSkKKwkJCSAgICByZXR1cm4gbmV3ZGlyICsgRmlsZS5zZXBhcmF0b3I7CisJCQllbHNlCisJCQkgICAgcmV0dXJuIGhvbWUgKyBGaWxlLnNlcGFyYXRvciArICJsaWIiICsgRmlsZS5zZXBhcmF0b3I7CisJCSAgICB9CisJCX0pOworCX0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCSAgICAvLyBpZ25vcmUgYW55IGV4Y2VwdGlvbnMKKwl9CisJY29uZkRpciA9IGRpcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgZGVmYXVsdCBjb25zdHJ1Y3Rvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgTWltZXR5cGVzRmlsZVR5cGVNYXAoKSB7CisJVmVjdG9yIGRidiA9IG5ldyBWZWN0b3IoNSk7CS8vIHVzdWFsbHkgNSBvciBsZXNzIGRhdGFiYXNlcworCU1pbWVUeXBlRmlsZSBtZiA9IG51bGw7CisJZGJ2LmFkZEVsZW1lbnQobnVsbCk7CQkvLyBwbGFjZSBob2xkZXIgZm9yIFBST0cgZW50cnkKKworCUxvZ1N1cHBvcnQubG9nKCJNaW1ldHlwZXNGaWxlVHlwZU1hcDogbG9hZCBIT01FIik7CisJdHJ5IHsKKwkgICAgU3RyaW5nIHVzZXJfaG9tZSA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgidXNlci5ob21lIik7CisKKwkgICAgaWYgKHVzZXJfaG9tZSAhPSBudWxsKSB7CisJCVN0cmluZyBwYXRoID0gdXNlcl9ob21lICsgRmlsZS5zZXBhcmF0b3IgKyAiLm1pbWUudHlwZXMiOworCQltZiA9IGxvYWRGaWxlKHBhdGgpOworCQlpZiAobWYgIT0gbnVsbCkKKwkJICAgIGRidi5hZGRFbGVtZW50KG1mKTsKKwkgICAgfQorCX0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGV4KSB7fQorCisJTG9nU3VwcG9ydC5sb2coIk1pbWV0eXBlc0ZpbGVUeXBlTWFwOiBsb2FkIFNZUyIpOworCXRyeSB7CisJICAgIC8vIGNoZWNrIHN5c3RlbSdzIGhvbWUKKwkgICAgaWYgKGNvbmZEaXIgIT0gbnVsbCkgeworCQltZiA9IGxvYWRGaWxlKGNvbmZEaXIgKyAibWltZS50eXBlcyIpOworCQlpZiAobWYgIT0gbnVsbCkKKwkJICAgIGRidi5hZGRFbGVtZW50KG1mKTsKKwkgICAgfQorCX0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGV4KSB7fQorCisJTG9nU3VwcG9ydC5sb2coIk1pbWV0eXBlc0ZpbGVUeXBlTWFwOiBsb2FkIEpBUiIpOworCS8vIGxvYWQgZnJvbSB0aGUgYXBwJ3MgamFyIGZpbGUKKwlsb2FkQWxsUmVzb3VyY2VzKGRidiwgIk1FVEEtSU5GL21pbWUudHlwZXMiKTsKKworCUxvZ1N1cHBvcnQubG9nKCJNaW1ldHlwZXNGaWxlVHlwZU1hcDogbG9hZCBERUYiKTsKKwltZiA9IGxvYWRSZXNvdXJjZSgiL01FVEEtSU5GL21pbWV0eXBlcy5kZWZhdWx0Iik7CisKKwlpZiAobWYgIT0gbnVsbCkKKwkgICAgZGJ2LmFkZEVsZW1lbnQobWYpOworCisJREIgPSBuZXcgTWltZVR5cGVGaWxlW2Ridi5zaXplKCldOworCWRidi5jb3B5SW50byhEQik7CisgICAgfQorCisgICAgLyoqCisgICAgICogTG9hZCBmcm9tIHRoZSBuYW1lZCByZXNvdXJjZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIE1pbWVUeXBlRmlsZSBsb2FkUmVzb3VyY2UoU3RyaW5nIG5hbWUpIHsKKwlJbnB1dFN0cmVhbSBjbGlzID0gbnVsbDsKKwl0cnkgeworCSAgICBjbGlzID0gU2VjdXJpdHlTdXBwb3J0LmdldFJlc291cmNlQXNTdHJlYW0odGhpcy5nZXRDbGFzcygpLCBuYW1lKTsKKwkgICAgaWYgKGNsaXMgIT0gbnVsbCkgeworCQlNaW1lVHlwZUZpbGUgbWYgPSBuZXcgTWltZVR5cGVGaWxlKGNsaXMpOworCQlpZiAoTG9nU3VwcG9ydC5pc0xvZ2dhYmxlKCkpCisJCSAgICBMb2dTdXBwb3J0LmxvZygiTWltZXR5cGVzRmlsZVR5cGVNYXA6IHN1Y2Nlc3NmdWxseSAiICsKKwkJCSJsb2FkZWQgbWltZSB0eXBlcyBmaWxlOiAiICsgbmFtZSk7CisJCXJldHVybiBtZjsKKwkgICAgfSBlbHNlIHsKKwkJaWYgKExvZ1N1cHBvcnQuaXNMb2dnYWJsZSgpKQorCQkgICAgTG9nU3VwcG9ydC5sb2coIk1pbWV0eXBlc0ZpbGVUeXBlTWFwOiBub3QgbG9hZGluZyAiICsKKwkJCSJtaW1lIHR5cGVzIGZpbGU6ICIgKyBuYW1lKTsKKwkgICAgfQorCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKwkgICAgaWYgKExvZ1N1cHBvcnQuaXNMb2dnYWJsZSgpKQorCQlMb2dTdXBwb3J0LmxvZygiTWltZXR5cGVzRmlsZVR5cGVNYXA6IGNhbid0IGxvYWQgIiArIG5hbWUsIGUpOworCX0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHNleCkgeworCSAgICBpZiAoTG9nU3VwcG9ydC5pc0xvZ2dhYmxlKCkpCisJCUxvZ1N1cHBvcnQubG9nKCJNaW1ldHlwZXNGaWxlVHlwZU1hcDogY2FuJ3QgbG9hZCAiICsgbmFtZSwgc2V4KTsKKwl9IGZpbmFsbHkgeworCSAgICB0cnkgeworCQlpZiAoY2xpcyAhPSBudWxsKQorCQkgICAgY2xpcy5jbG9zZSgpOworCSAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeyB9CS8vIGlnbm9yZSBpdAorCX0KKwlyZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb2FkIGFsbCBvZiB0aGUgbmFtZWQgcmVzb3VyY2UuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGxvYWRBbGxSZXNvdXJjZXMoVmVjdG9yIHYsIFN0cmluZyBuYW1lKSB7CisJYm9vbGVhbiBhbnlMb2FkZWQgPSBmYWxzZTsKKwl0cnkgeworCSAgICBVUkxbXSB1cmxzOworCSAgICBDbGFzc0xvYWRlciBjbGQgPSBudWxsOworCSAgICAvLyBGaXJzdCB0cnkgdGhlICJhcHBsaWNhdGlvbidzIiBjbGFzcyBsb2FkZXIuCisJICAgIGNsZCA9IFNlY3VyaXR5U3VwcG9ydC5nZXRDb250ZXh0Q2xhc3NMb2FkZXIoKTsKKwkgICAgaWYgKGNsZCA9PSBudWxsKQorCQljbGQgPSB0aGlzLmdldENsYXNzKCkuZ2V0Q2xhc3NMb2FkZXIoKTsKKwkgICAgaWYgKGNsZCAhPSBudWxsKQorCQl1cmxzID0gU2VjdXJpdHlTdXBwb3J0LmdldFJlc291cmNlcyhjbGQsIG5hbWUpOworCSAgICBlbHNlCisJCXVybHMgPSBTZWN1cml0eVN1cHBvcnQuZ2V0U3lzdGVtUmVzb3VyY2VzKG5hbWUpOworCSAgICBpZiAodXJscyAhPSBudWxsKSB7CisJCWlmIChMb2dTdXBwb3J0LmlzTG9nZ2FibGUoKSkKKwkJICAgIExvZ1N1cHBvcnQubG9nKCJNaW1ldHlwZXNGaWxlVHlwZU1hcDogZ2V0UmVzb3VyY2VzIik7CisJCWZvciAoaW50IGkgPSAwOyBpIDwgdXJscy5sZW5ndGg7IGkrKykgeworCQkgICAgVVJMIHVybCA9IHVybHNbaV07CisJCSAgICBJbnB1dFN0cmVhbSBjbGlzID0gbnVsbDsKKwkJICAgIGlmIChMb2dTdXBwb3J0LmlzTG9nZ2FibGUoKSkKKwkJCUxvZ1N1cHBvcnQubG9nKCJNaW1ldHlwZXNGaWxlVHlwZU1hcDogVVJMICIgKyB1cmwpOworCQkgICAgdHJ5IHsKKwkJCWNsaXMgPSBTZWN1cml0eVN1cHBvcnQub3BlblN0cmVhbSh1cmwpOworCQkJaWYgKGNsaXMgIT0gbnVsbCkgeworCQkJICAgIHYuYWRkRWxlbWVudChuZXcgTWltZVR5cGVGaWxlKGNsaXMpKTsKKwkJCSAgICBhbnlMb2FkZWQgPSB0cnVlOworCQkJICAgIGlmIChMb2dTdXBwb3J0LmlzTG9nZ2FibGUoKSkKKwkJCQlMb2dTdXBwb3J0LmxvZygiTWltZXR5cGVzRmlsZVR5cGVNYXA6ICIgKworCQkJCSAgICAic3VjY2Vzc2Z1bGx5IGxvYWRlZCAiICsKKwkJCQkgICAgIm1pbWUgdHlwZXMgZnJvbSBVUkw6ICIgKyB1cmwpOworCQkJfSBlbHNlIHsKKwkJCSAgICBpZiAoTG9nU3VwcG9ydC5pc0xvZ2dhYmxlKCkpCisJCQkJTG9nU3VwcG9ydC5sb2coIk1pbWV0eXBlc0ZpbGVUeXBlTWFwOiAiICsKKwkJCQkgICAgIm5vdCBsb2FkaW5nICIgKworCQkJCSAgICAibWltZSB0eXBlcyBmcm9tIFVSTDogIiArIHVybCk7CisJCQl9CisJCSAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2V4KSB7CisJCQlpZiAoTG9nU3VwcG9ydC5pc0xvZ2dhYmxlKCkpCisJCQkgICAgTG9nU3VwcG9ydC5sb2coIk1pbWV0eXBlc0ZpbGVUeXBlTWFwOiBjYW4ndCBsb2FkICIgKworCQkJCQkJdXJsLCBpb2V4KTsKKwkJICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHNleCkgeworCQkJaWYgKExvZ1N1cHBvcnQuaXNMb2dnYWJsZSgpKQorCQkJICAgIExvZ1N1cHBvcnQubG9nKCJNaW1ldHlwZXNGaWxlVHlwZU1hcDogY2FuJ3QgbG9hZCAiICsKKwkJCQkJCXVybCwgc2V4KTsKKwkJICAgIH0gZmluYWxseSB7CisJCQl0cnkgeworCQkJICAgIGlmIChjbGlzICE9IG51bGwpCisJCQkJY2xpcy5jbG9zZSgpOworCQkJfSBjYXRjaCAoSU9FeGNlcHRpb24gY2V4KSB7IH0KKwkJICAgIH0KKwkJfQorCSAgICB9CisJfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJICAgIGlmIChMb2dTdXBwb3J0LmlzTG9nZ2FibGUoKSkKKwkJTG9nU3VwcG9ydC5sb2coIk1pbWV0eXBlc0ZpbGVUeXBlTWFwOiBjYW4ndCBsb2FkICIgKyBuYW1lLCBleCk7CisJfQorCisJLy8gaWYgZmFpbGVkIHRvIGxvYWQgYW55dGhpbmcsIGZhbGwgYmFjayB0byBvbGQgdGVjaG5pcXVlLCBqdXN0IGluIGNhc2UKKwlpZiAoIWFueUxvYWRlZCkgeworCSAgICBMb2dTdXBwb3J0LmxvZygiTWltZXR5cGVzRmlsZVR5cGVNYXA6ICFhbnlMb2FkZWQiKTsKKwkgICAgTWltZVR5cGVGaWxlIG1mID0gbG9hZFJlc291cmNlKCIvIiArIG5hbWUpOworCSAgICBpZiAobWYgIT0gbnVsbCkKKwkJdi5hZGRFbGVtZW50KG1mKTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogTG9hZCB0aGUgbmFtZWQgZmlsZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIE1pbWVUeXBlRmlsZSBsb2FkRmlsZShTdHJpbmcgbmFtZSkgeworCU1pbWVUeXBlRmlsZSBtdGYgPSBudWxsOworCisJdHJ5IHsKKwkgICAgbXRmID0gbmV3IE1pbWVUeXBlRmlsZShuYW1lKTsKKwl9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisJICAgIC8vCWUucHJpbnRTdGFja1RyYWNlKCk7CisJfQorCXJldHVybiBtdGY7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGEgTWltZXR5cGVzRmlsZVR5cGVNYXAgd2l0aCBwcm9ncmFtbWF0aWMgZW50cmllcworICAgICAqIGFkZGVkIGZyb20gdGhlIG5hbWVkIGZpbGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWltZVR5cGVGaWxlTmFtZQl0aGUgZmlsZSBuYW1lCisgICAgICogQGV4Y2VwdGlvbglJT0V4Y2VwdGlvbglmb3IgZXJyb3JzIHJlYWRpbmcgdGhlIGZpbGUKKyAgICAgKi8KKyAgICBwdWJsaWMgTWltZXR5cGVzRmlsZVR5cGVNYXAoU3RyaW5nIG1pbWVUeXBlRmlsZU5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJdGhpcygpOworCURCW1BST0ddID0gbmV3IE1pbWVUeXBlRmlsZShtaW1lVHlwZUZpbGVOYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYSBNaW1ldHlwZXNGaWxlVHlwZU1hcCB3aXRoIHByb2dyYW1tYXRpYyBlbnRyaWVzCisgICAgICogYWRkZWQgZnJvbSB0aGUgSW5wdXRTdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaXMJdGhlIGlucHV0IHN0cmVhbSB0byByZWFkIGZyb20KKyAgICAgKi8KKyAgICBwdWJsaWMgTWltZXR5cGVzRmlsZVR5cGVNYXAoSW5wdXRTdHJlYW0gaXMpIHsKKwl0aGlzKCk7CisJdHJ5IHsKKwkgICAgREJbUFJPR10gPSBuZXcgTWltZVR5cGVGaWxlKGlzKTsKKwl9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworCSAgICAvLyBYWFggLSByZWFsbHkgc2hvdWxkIHRocm93IGl0CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFByZXBlbmQgdGhlIE1JTUUgdHlwZSB2YWx1ZXMgdG8gdGhlIHJlZ2lzdHJ5LgorICAgICAqCisgICAgICogQHBhcmFtIG1pbWVfdHlwZXMgQSAubWltZS50eXBlcyBmb3JtYXR0ZWQgc3RyaW5nIG9mIGVudHJpZXMuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGFkZE1pbWVUeXBlcyhTdHJpbmcgbWltZV90eXBlcykgeworCS8vIGNoZWNrIHRvIHNlZSBpZiB3ZSBoYXZlIGNyZWF0ZWQgdGhlIHJlZ2lzdHJ5CisJaWYgKERCW1BST0ddID09IG51bGwpCisJICAgIERCW1BST0ddID0gbmV3IE1pbWVUeXBlRmlsZSgpOyAvLyBtYWtlIG9uZQorCisJREJbUFJPR10uYXBwZW5kVG9SZWdpc3RyeShtaW1lX3R5cGVzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIE1JTUUgdHlwZSBvZiB0aGUgZmlsZSBvYmplY3QuCisgICAgICogVGhlIGltcGxlbWVudGF0aW9uIGluIHRoaXMgY2xhc3MgY2FsbHMKKyAgICAgKiA8Y29kZT5nZXRDb250ZW50VHlwZShmLmdldE5hbWUoKSk8L2NvZGU+LgorICAgICAqCisgICAgICogQHBhcmFtIGYJdGhlIGZpbGUKKyAgICAgKiBAcmV0dXJuCXRoZSBmaWxlJ3MgTUlNRSB0eXBlCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRDb250ZW50VHlwZShGaWxlIGYpIHsKKwlyZXR1cm4gdGhpcy5nZXRDb250ZW50VHlwZShmLmdldE5hbWUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBNSU1FIHR5cGUgYmFzZWQgb24gdGhlIHNwZWNpZmllZCBmaWxlIG5hbWUuCisgICAgICogVGhlIE1JTUUgdHlwZSBlbnRyaWVzIGFyZSBzZWFyY2hlZCBhcyBkZXNjcmliZWQgYWJvdmUgdW5kZXIKKyAgICAgKiA8aT5NSU1FIHR5cGVzIGZpbGUgc2VhcmNoIG9yZGVyPC9pPi4KKyAgICAgKiBJZiBubyBlbnRyeSBpcyBmb3VuZCwgdGhlIHR5cGUgImFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSIgaXMgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmlsZW5hbWUJdGhlIGZpbGUgbmFtZQorICAgICAqIEByZXR1cm4JCXRoZSBmaWxlJ3MgTUlNRSB0eXBlCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBTdHJpbmcgZ2V0Q29udGVudFR5cGUoU3RyaW5nIGZpbGVuYW1lKSB7CisJaW50IGRvdF9wb3MgPSBmaWxlbmFtZS5sYXN0SW5kZXhPZigiLiIpOyAvLyBwZXJpb2QgaW5kZXgKKworCWlmIChkb3RfcG9zIDwgMCkKKwkgICAgcmV0dXJuIGRlZmF1bHRUeXBlOworCisJU3RyaW5nIGZpbGVfZXh0ID0gZmlsZW5hbWUuc3Vic3RyaW5nKGRvdF9wb3MgKyAxKTsKKwlpZiAoZmlsZV9leHQubGVuZ3RoKCkgPT0gMCkKKwkgICAgcmV0dXJuIGRlZmF1bHRUeXBlOworCisJZm9yIChpbnQgaSA9IDA7IGkgPCBEQi5sZW5ndGg7IGkrKykgeworCSAgICBpZiAoREJbaV0gPT0gbnVsbCkKKwkJY29udGludWU7CisJICAgIFN0cmluZyByZXN1bHQgPSBEQltpXS5nZXRNSU1FVHlwZVN0cmluZyhmaWxlX2V4dCk7CisJICAgIGlmIChyZXN1bHQgIT0gbnVsbCkKKwkJcmV0dXJuIHJlc3VsdDsKKwl9CisJcmV0dXJuIGRlZmF1bHRUeXBlOworICAgIH0KKworICAgIC8qKgorICAgICAqIGZvciBkZWJ1Z2dpbmcuLi4KKyAgICAgKgorICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3YpIHRocm93cyBFeGNlcHRpb24geworCU1pbWV0eXBlc0ZpbGVUeXBlTWFwIG1hcCA9IG5ldyBNaW1ldHlwZXNGaWxlVHlwZU1hcCgpOworCVN5c3RlbS5vdXQucHJpbnRsbigiRmlsZSAiICsgYXJndlswXSArICIgaGFzIE1JTUUgdHlwZSAiICsKKwkJCQkJCW1hcC5nZXRDb250ZW50VHlwZShhcmd2WzBdKSk7CisJU3lzdGVtLmV4aXQoMCk7CisgICAgfQorICAgICovCit9CmRpZmYgLS1naXQgYS9hbmRyb2lkL2FjdGl2YXRpb24vc3JjL21haW4vamF2YS9qYXZheC9hY3RpdmF0aW9uL1NlY3VyaXR5U3VwcG9ydC5qYXZhIGIvYW5kcm9pZC9hY3RpdmF0aW9uL3NyYy9tYWluL2phdmEvamF2YXgvYWN0aXZhdGlvbi9TZWN1cml0eVN1cHBvcnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMzcxNzRiCi0tLSAvZGV2L251bGwKKysrIGIvYW5kcm9pZC9hY3RpdmF0aW9uL3NyYy9tYWluL2phdmEvamF2YXgvYWN0aXZhdGlvbi9TZWN1cml0eVN1cHBvcnQuamF2YQpAQCAtMCwwICsxLDExNCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgRGlzdHJpYnV0aW9uIExpY2Vuc2Ugdi4gMS4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvb3JnL2RvY3VtZW50cy9lZGwtdjEwLnBocC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQlNELTMtQ2xhdXNlCisgKi8KKworcGFja2FnZSBqYXZheC5hY3RpdmF0aW9uOworCitpbXBvcnQgamF2YS5zZWN1cml0eS4qOworaW1wb3J0IGphdmEubmV0Lio7CitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmEudXRpbC4qOworCisvKioKKyAqIFNlY3VyaXR5IHJlbGF0ZWQgbWV0aG9kcyB0aGF0IG9ubHkgd29yayBvbiBKMlNFIDEuMiBhbmQgbmV3ZXIuCisgKi8KK2NsYXNzIFNlY3VyaXR5U3VwcG9ydCB7CisKKyAgICBwcml2YXRlIFNlY3VyaXR5U3VwcG9ydCgpIHsKKwkvLyBwcml2YXRlIGNvbnN0cnVjdG9yLCBjYW4ndCBjcmVhdGUgYW4gaW5zdGFuY2UKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIENsYXNzTG9hZGVyIGdldENvbnRleHRDbGFzc0xvYWRlcigpIHsKKwlyZXR1cm4gKENsYXNzTG9hZGVyKQorCQlBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZChuZXcgUHJpdmlsZWdlZEFjdGlvbigpIHsKKwkgICAgcHVibGljIE9iamVjdCBydW4oKSB7CisJCUNsYXNzTG9hZGVyIGNsID0gbnVsbDsKKwkJdHJ5IHsKKwkJICAgIGNsID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXRDb250ZXh0Q2xhc3NMb2FkZXIoKTsKKwkJfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gZXgpIHsgfQorCQlyZXR1cm4gY2w7CisJICAgIH0KKwl9KTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIElucHV0U3RyZWFtIGdldFJlc291cmNlQXNTdHJlYW0oZmluYWwgQ2xhc3MgYywKKwkJCQlmaW5hbCBTdHJpbmcgbmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwl0cnkgeworCSAgICByZXR1cm4gKElucHV0U3RyZWFtKQorCQlBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZChuZXcgUHJpdmlsZWdlZEV4Y2VwdGlvbkFjdGlvbigpIHsKKwkJICAgIHB1YmxpYyBPYmplY3QgcnVuKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkJCXJldHVybiBjLmdldFJlc291cmNlQXNTdHJlYW0obmFtZSk7CisJCSAgICB9CisJCX0pOworCX0gY2F0Y2ggKFByaXZpbGVnZWRBY3Rpb25FeGNlcHRpb24gZSkgeworCSAgICB0aHJvdyAoSU9FeGNlcHRpb24pZS5nZXRFeGNlcHRpb24oKTsKKwl9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBVUkxbXSBnZXRSZXNvdXJjZXMoZmluYWwgQ2xhc3NMb2FkZXIgY2wsIGZpbmFsIFN0cmluZyBuYW1lKSB7CisJcmV0dXJuIChVUkxbXSkKKwkJQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb24oKSB7CisJICAgIHB1YmxpYyBPYmplY3QgcnVuKCkgeworCQlVUkxbXSByZXQgPSBudWxsOworCQl0cnkgeworCQkgICAgTGlzdCB2ID0gbmV3IEFycmF5TGlzdCgpOworCQkgICAgRW51bWVyYXRpb24gZSA9IGNsLmdldFJlc291cmNlcyhuYW1lKTsKKwkJICAgIHdoaWxlIChlICE9IG51bGwgJiYgZS5oYXNNb3JlRWxlbWVudHMoKSkgeworCQkJVVJMIHVybCA9IChVUkwpZS5uZXh0RWxlbWVudCgpOworCQkJaWYgKHVybCAhPSBudWxsKQorCQkJICAgIHYuYWRkKHVybCk7CisJCSAgICB9CisJCSAgICBpZiAodi5zaXplKCkgPiAwKSB7CisJCQlyZXQgPSBuZXcgVVJMW3Yuc2l6ZSgpXTsKKwkJCXJldCA9IChVUkxbXSl2LnRvQXJyYXkocmV0KTsKKwkJICAgIH0KKwkJfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9leCkgeworCQl9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBleCkgeyB9CisJCXJldHVybiByZXQ7CisJICAgIH0KKwl9KTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFVSTFtdIGdldFN5c3RlbVJlc291cmNlcyhmaW5hbCBTdHJpbmcgbmFtZSkgeworCXJldHVybiAoVVJMW10pCisJCUFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKG5ldyBQcml2aWxlZ2VkQWN0aW9uKCkgeworCSAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHsKKwkJVVJMW10gcmV0ID0gbnVsbDsKKwkJdHJ5IHsKKwkJICAgIExpc3QgdiA9IG5ldyBBcnJheUxpc3QoKTsKKwkJICAgIEVudW1lcmF0aW9uIGUgPSBDbGFzc0xvYWRlci5nZXRTeXN0ZW1SZXNvdXJjZXMobmFtZSk7CisJCSAgICB3aGlsZSAoZSAhPSBudWxsICYmIGUuaGFzTW9yZUVsZW1lbnRzKCkpIHsKKwkJCVVSTCB1cmwgPSAoVVJMKWUubmV4dEVsZW1lbnQoKTsKKwkJCWlmICh1cmwgIT0gbnVsbCkKKwkJCSAgICB2LmFkZCh1cmwpOworCQkgICAgfQorCQkgICAgaWYgKHYuc2l6ZSgpID4gMCkgeworCQkJcmV0ID0gbmV3IFVSTFt2LnNpemUoKV07CisJCQlyZXQgPSAoVVJMW10pdi50b0FycmF5KHJldCk7CisJCSAgICB9CisJCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZXgpIHsKKwkJfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gZXgpIHsgfQorCQlyZXR1cm4gcmV0OworCSAgICB9CisJfSk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBJbnB1dFN0cmVhbSBvcGVuU3RyZWFtKGZpbmFsIFVSTCB1cmwpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJdHJ5IHsKKwkgICAgcmV0dXJuIChJbnB1dFN0cmVhbSkKKwkJQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRFeGNlcHRpb25BY3Rpb24oKSB7CisJCSAgICBwdWJsaWMgT2JqZWN0IHJ1bigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJCQlyZXR1cm4gdXJsLm9wZW5TdHJlYW0oKTsKKwkJICAgIH0KKwkJfSk7CisJfSBjYXRjaCAoUHJpdmlsZWdlZEFjdGlvbkV4Y2VwdGlvbiBlKSB7CisJICAgIHRocm93IChJT0V4Y2VwdGlvbillLmdldEV4Y2VwdGlvbigpOworCX0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hbmRyb2lkL2FjdGl2YXRpb24vc3JjL21haW4vamF2YS9qYXZheC9hY3RpdmF0aW9uL1VSTERhdGFTb3VyY2UuamF2YSBiL2FuZHJvaWQvYWN0aXZhdGlvbi9zcmMvbWFpbi9qYXZhL2phdmF4L2FjdGl2YXRpb24vVVJMRGF0YVNvdXJjZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFkMmExM2MKLS0tIC9kZXYvbnVsbAorKysgYi9hbmRyb2lkL2FjdGl2YXRpb24vc3JjL21haW4vamF2YS9qYXZheC9hY3RpdmF0aW9uL1VSTERhdGFTb3VyY2UuamF2YQpAQCAtMCwwICsxLDEyMCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgRGlzdHJpYnV0aW9uIExpY2Vuc2Ugdi4gMS4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvb3JnL2RvY3VtZW50cy9lZGwtdjEwLnBocC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQlNELTMtQ2xhdXNlCisgKi8KKworcGFja2FnZSBqYXZheC5hY3RpdmF0aW9uOworCitpbXBvcnQgamF2YS5uZXQuVVJMOworaW1wb3J0IGphdmEubmV0LlVSTENvbm5lY3Rpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCisvKioKKyAqIFRoZSBVUkxEYXRhU291cmNlIGNsYXNzIHByb3ZpZGVzIGFuIG9iamVjdCB0aGF0IHdyYXBzIGEgPGNvZGU+VVJMPC9jb2RlPgorICogb2JqZWN0IGluIGEgRGF0YVNvdXJjZSBpbnRlcmZhY2UuIFVSTERhdGFTb3VyY2Ugc2ltcGxpZmllcyB0aGUgaGFuZGxpbmcKKyAqIG9mIGRhdGEgZGVzY3JpYmVkIGJ5IFVSTHMgd2l0aGluIHRoZSBKYXZhQmVhbnMgQWN0aXZhdGlvbiBGcmFtZXdvcmsKKyAqIGJlY2F1c2UgdGhpcyBjbGFzcyBjYW4gYmUgdXNlZCB0byBjcmVhdGUgbmV3IERhdGFIYW5kbGVycy4gPGk+Tk9URTogVGhlCisgKiBEYXRhSGFuZGxlciBvYmplY3QgY3JlYXRlcyBhIFVSTERhdGFTb3VyY2UgaW50ZXJuYWxseSwKKyAqIHdoZW4gaXQgaXMgY29uc3RydWN0ZWQgd2l0aCBhIFVSTC48L2k+CisgKgorICogQHNlZSBqYXZheC5hY3RpdmF0aW9uLkRhdGFTb3VyY2UKKyAqIEBzZWUgamF2YXguYWN0aXZhdGlvbi5EYXRhSGFuZGxlcgorICovCitwdWJsaWMgY2xhc3MgVVJMRGF0YVNvdXJjZSBpbXBsZW1lbnRzIERhdGFTb3VyY2UgeworICAgIHByaXZhdGUgVVJMIHVybCA9IG51bGw7CisgICAgcHJpdmF0ZSBVUkxDb25uZWN0aW9uIHVybF9jb25uID0gbnVsbDsKKworICAgIC8qKgorICAgICAqIFVSTERhdGFTb3VyY2UgY29uc3RydWN0b3IuIFRoZSBVUkxEYXRhU291cmNlIGNsYXNzIHdpbGwKKyAgICAgKiBub3Qgb3BlbiBhIGNvbm5lY3Rpb24gdG8gdGhlIFVSTCB1bnRpbCBhIG1ldGhvZCByZXF1aXJpbmcgaXQKKyAgICAgKiB0byBkbyBzbyBpcyBjYWxsZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdXJsIFRoZSBVUkwgdG8gYmUgZW5jYXBzdWxhdGVkIGluIHRoaXMgb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyBVUkxEYXRhU291cmNlKFVSTCB1cmwpIHsKKwl0aGlzLnVybCA9IHVybDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgVVJMIGNvbnRlbnQtdHlwZSBoZWFkZXIgZmllbGQuCisgICAgICogSXQgY2FsbHMgdGhlIFVSTCdzIDxjb2RlPlVSTENvbm5lY3Rpb24uZ2V0Q29udGVudFR5cGU8L2NvZGU+IG1ldGhvZAorICAgICAqIGFmdGVyIHJldHJpZXZpbmcgYSBVUkxDb25uZWN0aW9uIG9iamVjdC4KKyAgICAgKiA8aT5Ob3RlOiB0aGlzIG1ldGhvZCBhdHRlbXB0cyB0byBjYWxsIHRoZSA8Y29kZT5vcGVuQ29ubmVjdGlvbjwvY29kZT4KKyAgICAgKiBtZXRob2Qgb24gdGhlIFVSTC4gSWYgdGhpcyBtZXRob2QgZmFpbHMsIG9yIGlmIGEgY29udGVudCB0eXBlIGlzIG5vdAorICAgICAqIHJldHVybmVkIGZyb20gdGhlIFVSTENvbm5lY3Rpb24sIGdldENvbnRlbnRUeXBlIHJldHVybnMKKyAgICAgKiAiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIiBhcyB0aGUgY29udGVudCB0eXBlLjwvaT4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGNvbnRlbnQgdHlwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldENvbnRlbnRUeXBlKCkgeworCVN0cmluZyB0eXBlID0gbnVsbDsKKworCXRyeSB7CisJICAgIGlmICh1cmxfY29ubiA9PSBudWxsKQorCQl1cmxfY29ubiA9IHVybC5vcGVuQ29ubmVjdGlvbigpOworCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsgfQorCQorCWlmICh1cmxfY29ubiAhPSBudWxsKQorCSAgICB0eXBlID0gdXJsX2Nvbm4uZ2V0Q29udGVudFR5cGUoKTsKKworCWlmICh0eXBlID09IG51bGwpCisJICAgIHR5cGUgPSAiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIjsKKwkKKwlyZXR1cm4gdHlwZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDYWxscyB0aGUgPGNvZGU+Z2V0RmlsZTwvY29kZT4gbWV0aG9kIG9uIHRoZSBVUkwgdXNlZCB0bworICAgICAqIGluc3RhbnRpYXRlIHRoZSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2YgY2FsbGluZyB0aGUgVVJMJ3MgZ2V0RmlsZSBtZXRob2QuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgeworCXJldHVybiB1cmwuZ2V0RmlsZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBnZXRJbnB1dFN0cmVhbSBtZXRob2QgZnJvbSB0aGUgVVJMLiBDYWxscyB0aGUKKyAgICAgKiA8Y29kZT5vcGVuU3RyZWFtPC9jb2RlPiBtZXRob2Qgb24gdGhlIFVSTC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIElucHV0U3RyZWFtLgorICAgICAqLworICAgIHB1YmxpYyBJbnB1dFN0cmVhbSBnZXRJbnB1dFN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJcmV0dXJuIHVybC5vcGVuU3RyZWFtKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIGdldE91dHB1dFN0cmVhbSBtZXRob2QgZnJvbSB0aGUgVVJMLiBGaXJzdCBhbiBhdHRlbXB0IGlzCisgICAgICogbWFkZSB0byBnZXQgdGhlIFVSTENvbm5lY3Rpb24gb2JqZWN0IGZvciB0aGUgVVJMLiBJZiB0aGF0CisgICAgICogc3VjY2VlZHMsIHRoZSBnZXRPdXRwdXRTdHJlYW0gbWV0aG9kIG9uIHRoZSBVUkxDb25uZWN0aW9uCisgICAgICogaXMgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBPdXRwdXRTdHJlYW0uCisgICAgICovCisgICAgcHVibGljIE91dHB1dFN0cmVhbSBnZXRPdXRwdXRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworCS8vIGdldCB0aGUgdXJsIGNvbm5lY3Rpb24gaWYgaXQgaXMgYXZhaWxhYmxlCisJdXJsX2Nvbm4gPSB1cmwub3BlbkNvbm5lY3Rpb24oKTsKKwkKKwlpZiAodXJsX2Nvbm4gIT0gbnVsbCkgeworCSAgICB1cmxfY29ubi5zZXREb091dHB1dCh0cnVlKTsKKwkgICAgcmV0dXJuIHVybF9jb25uLmdldE91dHB1dFN0cmVhbSgpOworCX0gZWxzZQorCSAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIFVSTCB1c2VkIHRvIGNyZWF0ZSB0aGlzIERhdGFTb3VyY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSBVUkwuCisgICAgICovCisgICAgcHVibGljIFVSTCBnZXRVUkwoKSB7CisJcmV0dXJuIHVybDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hbmRyb2lkL2FjdGl2YXRpb24vc3JjL21haW4vamF2YS9qYXZheC9hY3RpdmF0aW9uL1Vuc3VwcG9ydGVkRGF0YVR5cGVFeGNlcHRpb24uamF2YSBiL2FuZHJvaWQvYWN0aXZhdGlvbi9zcmMvbWFpbi9qYXZhL2phdmF4L2FjdGl2YXRpb24vVW5zdXBwb3J0ZWREYXRhVHlwZUV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIyNGE3ODgKLS0tIC9kZXYvbnVsbAorKysgYi9hbmRyb2lkL2FjdGl2YXRpb24vc3JjL21haW4vamF2YS9qYXZheC9hY3RpdmF0aW9uL1Vuc3VwcG9ydGVkRGF0YVR5cGVFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDQwIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBEaXN0cmlidXRpb24gTGljZW5zZSB2LiAxLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9vcmcvZG9jdW1lbnRzL2VkbC12MTAucGhwLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBCU0QtMy1DbGF1c2UKKyAqLworCitwYWNrYWdlIGphdmF4LmFjdGl2YXRpb247CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCisvKioKKyAqIFNpZ25hbHMgdGhhdCB0aGUgcmVxdWVzdGVkIG9wZXJhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IHRoZQorICogcmVxdWVzdGVkIGRhdGEgdHlwZS4KKyAqCisgKiBAc2VlIGphdmF4LmFjdGl2YXRpb24uRGF0YUhhbmRsZXIKKyAqLworCitwdWJsaWMgY2xhc3MgVW5zdXBwb3J0ZWREYXRhVHlwZUV4Y2VwdGlvbiBleHRlbmRzIElPRXhjZXB0aW9uIHsKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGFuIFVuc3VwcG9ydGVkRGF0YVR5cGVFeGNlcHRpb24gd2l0aCBubyBkZXRhaWwKKyAgICAgKiBtZXNzYWdlLgorICAgICAqLworICAgIHB1YmxpYyBVbnN1cHBvcnRlZERhdGFUeXBlRXhjZXB0aW9uKCkgeworCXN1cGVyKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhbiBVbnN1cHBvcnRlZERhdGFUeXBlRXhjZXB0aW9uIHdpdGggdGhlIHNwZWNpZmllZCAKKyAgICAgKiBtZXNzYWdlLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzIFRoZSBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgVW5zdXBwb3J0ZWREYXRhVHlwZUV4Y2VwdGlvbihTdHJpbmcgcykgeworCXN1cGVyKHMpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2FuZHJvaWQvYWN0aXZhdGlvbi9zcmMvbWFpbi9qYXZhL2phdmF4L2FjdGl2YXRpb24vcGFja2FnZS5odG1sIGIvYW5kcm9pZC9hY3RpdmF0aW9uL3NyYy9tYWluL2phdmEvamF2YXgvYWN0aXZhdGlvbi9wYWNrYWdlLmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzdiYjM0ZQotLS0gL2Rldi9udWxsCisrKyBiL2FuZHJvaWQvYWN0aXZhdGlvbi9zcmMvbWFpbi9qYXZhL2phdmF4L2FjdGl2YXRpb24vcGFja2FnZS5odG1sCkBAIC0wLDAgKzEsMjcgQEAKKzwhRE9DVFlQRSBodG1sIFBVQkxJQyAiLS8vVzNDLy9EVEQgSFRNTCA0LjAxIFRyYW5zaXRpb25hbC8vRU4iPgorPEhUTUw+Cis8SEVBRD4KKzxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PXV0Zi04Ij4KKzwhLS0KKworICAgIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorCisgICAgVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgICAgdGVybXMgb2YgdGhlIEVjbGlwc2UgRGlzdHJpYnV0aW9uIExpY2Vuc2Ugdi4gMS4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisKKyAgICBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQlNELTMtQ2xhdXNlCisKKy0tPgorCis8VElUTEU+amF2YXguYWN0aXZhdGlvbiBwYWNrYWdlPC9USVRMRT4KKzwvSEVBRD4KKzxCT0RZIEJHQ09MT1I9IndoaXRlIj4KKworPFA+CitUaGUgSmF2YUJlYW5zKFRNKSBBY3RpdmF0aW9uIEZyYW1ld29yayBpcyB1c2VkIGJ5IHRoZSBKYXZhTWFpbChUTSkKK0FQSSB0byBtYW5hZ2UgTUlNRSBkYXRhLgorPC9QPgorCis8L0JPRFk+Cis8L0hUTUw+CmRpZmYgLS1naXQgYS9hbmRyb2lkL2FjdGl2YXRpb24vc3JjL21haW4vcmVzb3VyY2VzL01FVEEtSU5GL21haWxjYXAuZGVmYXVsdCBiL2FuZHJvaWQvYWN0aXZhdGlvbi9zcmMvbWFpbi9yZXNvdXJjZXMvTUVUQS1JTkYvbWFpbGNhcC5kZWZhdWx0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjczY2UyZmMKLS0tIC9kZXYvbnVsbAorKysgYi9hbmRyb2lkL2FjdGl2YXRpb24vc3JjL21haW4vcmVzb3VyY2VzL01FVEEtSU5GL21haWxjYXAuZGVmYXVsdApAQCAtMCwwICsxLDkgQEAKKyMKKyMgVGhpcyBpcyBhIHZlcnkgc2ltcGxlICdtYWlsY2FwJyBmaWxlCisjCisjIE5vIGRlZmF1bHQgdmlld2VycyBhcmUgaW5jbHVkZWQgc28gdGhlc2UgZW50cmllcyBhcmUgY29tbWVudGVkIG91dC4KKyMKKyNpbWFnZS9naWY7OwkJeC1qYXZhLXZpZXc9Y29tLnN1bi5hY3RpdmF0aW9uLnZpZXdlcnMuSW1hZ2VWaWV3ZXIKKyNpbWFnZS9qcGVnOzsJCXgtamF2YS12aWV3PWNvbS5zdW4uYWN0aXZhdGlvbi52aWV3ZXJzLkltYWdlVmlld2VyCisjdGV4dC8qOzsJCXgtamF2YS12aWV3PWNvbS5zdW4uYWN0aXZhdGlvbi52aWV3ZXJzLlRleHRWaWV3ZXIKKyN0ZXh0Lyo7OwkJeC1qYXZhLWVkaXQ9Y29tLnN1bi5hY3RpdmF0aW9uLnZpZXdlcnMuVGV4dEVkaXRvcgpkaWZmIC0tZ2l0IGEvYW5kcm9pZC9hY3RpdmF0aW9uL3NyYy9tYWluL3Jlc291cmNlcy9NRVRBLUlORi9taW1ldHlwZXMuZGVmYXVsdCBiL2FuZHJvaWQvYWN0aXZhdGlvbi9zcmMvbWFpbi9yZXNvdXJjZXMvTUVUQS1JTkYvbWltZXR5cGVzLmRlZmF1bHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWI0MDU2YgotLS0gL2Rldi9udWxsCisrKyBiL2FuZHJvaWQvYWN0aXZhdGlvbi9zcmMvbWFpbi9yZXNvdXJjZXMvTUVUQS1JTkYvbWltZXR5cGVzLmRlZmF1bHQKQEAgLTAsMCArMSwyNSBAQAorIworIyBBIHNpbXBsZSwgb2xkIGZvcm1hdCwgbWltZS50eXBlcyBmaWxlCisjCit0ZXh0L2h0bWwJCWh0bWwgaHRtIEhUTUwgSFRNCit0ZXh0L3BsYWluCQl0eHQgdGV4dCBUWFQgVEVYVAoraW1hZ2UvZ2lmCQlnaWYgR0lGCitpbWFnZS9pZWYJCWllZgoraW1hZ2UvanBlZwkJanBlZyBqcGcganBlIEpQRworaW1hZ2UvdGlmZgkJdGlmZiB0aWYKK2ltYWdlL3BuZwkJcG5nIFBORworaW1hZ2UveC14d2luZG93ZHVtcAl4d2QKK2FwcGxpY2F0aW9uL3Bvc3RzY3JpcHQJYWkgZXBzIHBzCithcHBsaWNhdGlvbi9ydGYJCXJ0ZgorYXBwbGljYXRpb24veC10ZXgJdGV4CithcHBsaWNhdGlvbi94LXRleGluZm8JdGV4aW5mbyB0ZXhpCithcHBsaWNhdGlvbi94LXRyb2ZmCXQgdHIgcm9mZgorYXVkaW8vYmFzaWMJCWF1CithdWRpby9taWRpCQltaWRpIG1pZAorYXVkaW8veC1haWZjCQlhaWZjCithdWRpby94LWFpZmYgICAgICAgICAgICBhaWYgYWlmZgorYXVkaW8veC1tcGVnCQltcGVnIG1wZworYXVkaW8veC13YXYgICAgICAgICAgICAgd2F2Cit2aWRlby9tcGVnCQltcGVnIG1wZyBtcGUKK3ZpZGVvL3F1aWNrdGltZQkJcXQgbW92Cit2aWRlby94LW1zdmlkZW8JCWF2aQpkaWZmIC0tZ2l0IGEvYW5kcm9pZC9tYWlsL3BvbS54bWwgYi9hbmRyb2lkL21haWwvcG9tLnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MGE5ZWUxCi0tLSAvZGV2L251bGwKKysrIGIvYW5kcm9pZC9tYWlsL3BvbS54bWwKQEAgLTAsMCArMSwxNTEgQEAKKzw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9Imlzby04ODU5LTEiPz4KKzwhLS0KKworICAgIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorCisgICAgVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgICAgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisKKyAgICBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgICAgTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICAgIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICAgIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorCisgICAgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisKKy0tPgorCis8IS0tCisgICAgVGhpcyBwcm9qZWN0IGJ1aWxkcyB0aGUgSmF2YU1haWwgQW5kcm9pZCBqYXIgZmlsZS4KKy0tPgorCis8cHJvamVjdCB4bWxucz0iaHR0cDovL21hdmVuLmFwYWNoZS5vcmcvUE9NLzQuMC4wIgorCXhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiCisJeHNpOnNjaGVtYUxvY2F0aW9uPSJodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9QT00vNC4wLjAKKwkJCSAgICBodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9tYXZlbi12NF8wXzAueHNkIj4KKyAgICA8cGFyZW50PgorCTxncm91cElkPmNvbS5zdW4ubWFpbDwvZ3JvdXBJZD4KKwk8YXJ0aWZhY3RJZD5hbmRyb2lkPC9hcnRpZmFjdElkPgorCTx2ZXJzaW9uPjEuNi4zPC92ZXJzaW9uPgorICAgIDwvcGFyZW50PgorICAgIDxtb2RlbFZlcnNpb24+NC4wLjA8L21vZGVsVmVyc2lvbj4KKyAgICA8Z3JvdXBJZD5jb20uc3VuLm1haWw8L2dyb3VwSWQ+CisgICAgPGFydGlmYWN0SWQ+YW5kcm9pZC1tYWlsPC9hcnRpZmFjdElkPgorICAgIDxwYWNrYWdpbmc+amFyPC9wYWNrYWdpbmc+CisgICAgPG5hbWU+SmF2YU1haWwgQVBJIGZvciBBbmRyb2lkPC9uYW1lPgorCisgICAgPHByb3BlcnRpZXM+CisJPG1haWwuZXh0ZW5zaW9uTmFtZT4KKwkgICAgamFrYXJ0YS5tYWlsLmFuZHJvaWQKKwk8L21haWwuZXh0ZW5zaW9uTmFtZT4KKwk8bWFpbC5zcGVjaWZpY2F0aW9uVGl0bGU+CisJICAgIEphdmFNYWlsKFRNKSBBUEkgRGVzaWduIFNwZWNpZmljYXRpb24KKwk8L21haWwuc3BlY2lmaWNhdGlvblRpdGxlPgorCTxtYWlsLmltcGxlbWVudGF0aW9uVGl0bGU+CisJICAgIGphdmF4Lm1haWwuYW5kcm9pZAorCTwvbWFpbC5pbXBsZW1lbnRhdGlvblRpdGxlPgorCTxtYWlsLnBhY2thZ2VzLmV4cG9ydD4KKwkgICAgamF2YXgubWFpbC4qOyB2ZXJzaW9uPSR7bWFpbC5zcGVjLnZlcnNpb259LAorCSAgICBjb20uc3VuLm1haWwuaW1hcDsgdmVyc2lvbj0ke21haWwub3NnaXZlcnNpb259LAorCSAgICBjb20uc3VuLm1haWwuaW1hcC5wcm90b2NvbDsgdmVyc2lvbj0ke21haWwub3NnaXZlcnNpb259LAorCSAgICBjb20uc3VuLm1haWwuaWFwOyB2ZXJzaW9uPSR7bWFpbC5vc2dpdmVyc2lvbn0sCisJICAgIGNvbS5zdW4ubWFpbC5wb3AzOyB2ZXJzaW9uPSR7bWFpbC5vc2dpdmVyc2lvbn0sCisJICAgIGNvbS5zdW4ubWFpbC5zbXRwOyB2ZXJzaW9uPSR7bWFpbC5vc2dpdmVyc2lvbn0sCisJICAgIGNvbS5zdW4ubWFpbC51dGlsOyB2ZXJzaW9uPSR7bWFpbC5vc2dpdmVyc2lvbn0sCisJICAgIGNvbS5zdW4ubWFpbC51dGlsLmxvZ2dpbmc7IHZlcnNpb249JHttYWlsLm9zZ2l2ZXJzaW9ufSwKKwkgICAgY29tLnN1bi5tYWlsLmhhbmRsZXJzOyB2ZXJzaW9uPSR7bWFpbC5vc2dpdmVyc2lvbn0KKwk8L21haWwucGFja2FnZXMuZXhwb3J0PgorICAgIDwvcHJvcGVydGllcz4KKworICAgIDxidWlsZD4KKwk8cmVzb3VyY2VzPgorCSAgICA8cmVzb3VyY2U+CisJCTxkaXJlY3Rvcnk+c3JjL21haW4vcmVzb3VyY2VzPC9kaXJlY3Rvcnk+CisJCTxmaWx0ZXJpbmc+dHJ1ZTwvZmlsdGVyaW5nPgorCSAgICA8L3Jlc291cmNlPgorCTwvcmVzb3VyY2VzPgorCTxwbHVnaW5zPgorCSAgICA8cGx1Z2luPgorCQk8YXJ0aWZhY3RJZD5tYXZlbi1kZXBlbmRlbmN5LXBsdWdpbjwvYXJ0aWZhY3RJZD4KKwkJPGV4ZWN1dGlvbnM+CisJCSAgICA8ZXhlY3V0aW9uPgorCQkJPCEtLSBkb3dubG9hZCB0aGUgYmluYXJpZXMgLS0+CisJCQk8aWQ+Z2V0LWJpbmFyaWVzPC9pZD4KKwkJCTxwaGFzZT5jb21waWxlPC9waGFzZT4KKwkJCTxnb2Fscz4KKwkJCSAgICA8Z29hbD51bnBhY2s8L2dvYWw+CisJCQk8L2dvYWxzPgorCQkgICAgPC9leGVjdXRpb24+CisJCSAgICA8ZXhlY3V0aW9uPgorCQkJPCEtLSBkb3dubG9hZCB0aGUgc291cmNlcyAtLT4KKwkJCTxpZD5nZXQtc291cmNlczwvaWQ+CisJCQk8cGhhc2U+Y29tcGlsZTwvcGhhc2U+CisJCQk8Z29hbHM+CisJCQkgICAgPGdvYWw+dW5wYWNrPC9nb2FsPgorCQkJPC9nb2Fscz4KKwkJCTxjb25maWd1cmF0aW9uPgorCQkJICAgIDxhcnRpZmFjdEl0ZW1zPgorCQkJCTxhcnRpZmFjdEl0ZW0+CisJCQkJICAgIDxncm91cElkPmNvbS5zdW4ubWFpbDwvZ3JvdXBJZD4KKwkJCQkgICAgPGFydGlmYWN0SWQ+amFrYXJ0YS5tYWlsPC9hcnRpZmFjdElkPgorCQkJCSAgICA8dmVyc2lvbj4ke21haWwudmVyc2lvbn08L3ZlcnNpb24+CisJCQkJICAgIDxjbGFzc2lmaWVyPnNvdXJjZXM8L2NsYXNzaWZpZXI+CisJCQkJICAgIDxvdXRwdXREaXJlY3Rvcnk+CisJCQkJCSR7cHJvamVjdC5idWlsZC5kaXJlY3Rvcnl9L3NvdXJjZXMKKwkJCQkgICAgPC9vdXRwdXREaXJlY3Rvcnk+CisJCQkJPC9hcnRpZmFjdEl0ZW0+CisJCQkgICAgPC9hcnRpZmFjdEl0ZW1zPgorCQkJPC9jb25maWd1cmF0aW9uPgorCQkgICAgPC9leGVjdXRpb24+CisJCTwvZXhlY3V0aW9ucz4KKwkJPGNvbmZpZ3VyYXRpb24+CisJCSAgICA8YXJ0aWZhY3RJdGVtcz4KKwkJCTxhcnRpZmFjdEl0ZW0+CisJCQkgICAgPGdyb3VwSWQ+Y29tLnN1bi5tYWlsPC9ncm91cElkPgorCQkJICAgIDxhcnRpZmFjdElkPmpha2FydGEubWFpbDwvYXJ0aWZhY3RJZD4KKwkJCSAgICA8dmVyc2lvbj4ke21haWwudmVyc2lvbn08L3ZlcnNpb24+CisJCQk8L2FydGlmYWN0SXRlbT4KKwkJICAgIDwvYXJ0aWZhY3RJdGVtcz4KKwkJICAgIDxvdXRwdXREaXJlY3Rvcnk+CisJCQkke3Byb2plY3QuYnVpbGQub3V0cHV0RGlyZWN0b3J5fQorCQkgICAgPC9vdXRwdXREaXJlY3Rvcnk+CisJCSAgICA8ZXhjbHVkZXM+CisJCQljb20vc3VuL21haWwvaGFuZGxlcnMvaGFuZGxlcl9iYXNlLiosCisJCQljb20vc3VuL21haWwvaGFuZGxlcnMvaW1hZ2VfKiwKKwkJCWNvbS9zdW4vbWFpbC9hdXRoL09BdXRoMlNhc2wqLAorCQkJY29tL3N1bi9tYWlsL2ltYXAvcHJvdG9jb2wvSU1BUFNhc2xBdXRoZW50aWNhdG9yKiwKKwkJCWNvbS9zdW4vbWFpbC9zbXRwL1NNVFBTYXNsQXV0aGVudGljYXRvcioKKwkJICAgIDwvZXhjbHVkZXM+CisJCTwvY29uZmlndXJhdGlvbj4KKwkgICAgPC9wbHVnaW4+CisJICAgIDxwbHVnaW4+CisJCTxhcnRpZmFjdElkPm1hdmVuLWphci1wbHVnaW48L2FydGlmYWN0SWQ+CisJCTxjb25maWd1cmF0aW9uPgorCQkgICAgPGZpbmFsTmFtZT4ke3Byb2plY3QuYXJ0aWZhY3RJZH08L2ZpbmFsTmFtZT4KKwkJICAgIDxhcmNoaXZlPgorCQkJPG1hbmlmZXN0RmlsZT4KKwkJCSAgJHtwcm9qZWN0LmJ1aWxkLm91dHB1dERpcmVjdG9yeX0vTUVUQS1JTkYvTUFOSUZFU1QuTUYKKwkJCTwvbWFuaWZlc3RGaWxlPgorCQkgICAgPC9hcmNoaXZlPgorCQk8L2NvbmZpZ3VyYXRpb24+CisJICAgIDwvcGx1Z2luPgorCTwvcGx1Z2lucz4KKyAgICA8L2J1aWxkPgorCisgICAgPGRlcGVuZGVuY2llcz4KKwk8ZGVwZW5kZW5jeT4KKwkgICAgPGdyb3VwSWQ+Y29tLnN1bi5tYWlsPC9ncm91cElkPgorCSAgICA8YXJ0aWZhY3RJZD5hbmRyb2lkLWFjdGl2YXRpb248L2FydGlmYWN0SWQ+CisJICAgIDx2ZXJzaW9uPiR7bWFpbC52ZXJzaW9ufTwvdmVyc2lvbj4KKwk8L2RlcGVuZGVuY3k+CisJPGRlcGVuZGVuY3k+CisJICAgIDxncm91cElkPmp1bml0PC9ncm91cElkPgorCSAgICA8YXJ0aWZhY3RJZD5qdW5pdDwvYXJ0aWZhY3RJZD4KKwkgICAgPHZlcnNpb24+NC4xMjwvdmVyc2lvbj4KKwkgICAgPHNjb3BlPnRlc3Q8L3Njb3BlPgorCSAgICA8b3B0aW9uYWw+dHJ1ZTwvb3B0aW9uYWw+CisJPC9kZXBlbmRlbmN5PgorICAgIDwvZGVwZW5kZW5jaWVzPgorPC9wcm9qZWN0PgpkaWZmIC0tZ2l0IGEvYW5kcm9pZC9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2hhbmRsZXJzL2hhbmRsZXJfYmFzZS5qYXZhIGIvYW5kcm9pZC9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2hhbmRsZXJzL2hhbmRsZXJfYmFzZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRhZTE1OWYKLS0tIC9kZXYvbnVsbAorKysgYi9hbmRyb2lkL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaGFuZGxlcnMvaGFuZGxlcl9iYXNlLmphdmEKQEAgLTAsMCArMSw3NyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuaGFuZGxlcnM7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmF4LmFjdGl2YXRpb24uKjsKKworLyoqCisgKiBCYXNlIGNsYXNzIGZvciBvdGhlciBEYXRhQ29udGVudEhhbmRsZXJzLgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgaGFuZGxlcl9iYXNlIGltcGxlbWVudHMgRGF0YUNvbnRlbnRIYW5kbGVyIHsKKworICAgIC8qKgorICAgICAqIFJldHVybiBhbiBhcnJheSBvZiBBY3RpdmF0aW9uRGF0YUZsYXZvcnMgdGhhdCB3ZSBzdXBwb3J0LgorICAgICAqIFVzdWFsbHkgdGhlcmUgd2lsbCBiZSBvbmx5IG9uZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4JYXJyYXkgb2YgQWN0aXZhdGlvbkRhdGFGbGF2b3JzIHRoYXQgd2Ugc3VwcG9ydAorICAgICAqLworICAgIHByb3RlY3RlZCBhYnN0cmFjdCBBY3RpdmF0aW9uRGF0YUZsYXZvcltdIGdldERhdGFGbGF2b3JzKCk7CisKKyAgICAvKioKKyAgICAgKiBHaXZlbiB0aGUgZmxhdm9yIHRoYXQgbWF0Y2hlZCwgcmV0dXJuIHRoZSBhcHByb3ByaWF0ZSB0eXBlIG9mIG9iamVjdC4KKyAgICAgKiBVc3VhbGx5IHRoZXJlJ3Mgb25seSBvbmUgZmxhdm9yIHNvIGp1c3QgY2FsbCBnZXRDb250ZW50LgorICAgICAqCisgICAgICogQHBhcmFtCWFGbGF2b3IJdGhlIEFjdGl2YXRpb25EYXRhRmxhdm9yCisgICAgICogQHBhcmFtCWRzCURhdGFTb3VyY2UgY29udGFpbmluZyB0aGUgZGF0YQorICAgICAqIEByZXR1cm4JdGhlIG9iamVjdAorICAgICAqIEBleGNlcHRpb24JSU9FeGNlcHRpb24JZm9yIGVycm9ycyByZWFkaW5nIHRoZSBkYXRhCisgICAgICovCisgICAgcHJvdGVjdGVkIE9iamVjdCBnZXREYXRhKEFjdGl2YXRpb25EYXRhRmxhdm9yIGFGbGF2b3IsIERhdGFTb3VyY2UgZHMpCisJCQkJdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlyZXR1cm4gZ2V0Q29udGVudChkcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBEYXRhRmxhdm9ycyBmb3IgdGhpcyA8Y29kZT5EYXRhQ29udGVudEhhbmRsZXI8L2NvZGU+LgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgRGF0YUZsYXZvcnMKKyAgICAgKi8KKyAgICBwdWJsaWMgQWN0aXZhdGlvbkRhdGFGbGF2b3JbXSBnZXRUcmFuc2ZlckRhdGFGbGF2b3JzKCkgeworCXJldHVybiBnZXREYXRhRmxhdm9ycygpLmNsb25lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBUcmFuc2ZlciBEYXRhIG9mIHR5cGUgRGF0YUZsYXZvciBmcm9tIElucHV0U3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtCWRmCVRoZSBEYXRhRmxhdm9yCisgICAgICogQHBhcmFtCWRzCVRoZSBEYXRhU291cmNlIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGRhdGEKKyAgICAgKiBAcmV0dXJuCXRoZSBvYmplY3QKKyAgICAgKiBAZXhjZXB0aW9uCUlPRXhjZXB0aW9uCWZvciBlcnJvcnMgcmVhZGluZyB0aGUgZGF0YQorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZ2V0VHJhbnNmZXJEYXRhKEFjdGl2YXRpb25EYXRhRmxhdm9yIGRmLCBEYXRhU291cmNlIGRzKSAKKwkJCXRocm93cyBJT0V4Y2VwdGlvbiB7CisJQWN0aXZhdGlvbkRhdGFGbGF2b3JbXSBhZGYgPSBnZXREYXRhRmxhdm9ycygpOworCWZvciAoaW50IGkgPSAwOyBpIDwgYWRmLmxlbmd0aDsgaSsrKSB7CisJICAgIC8vIHVzZSBBY3RpdmF0aW9uRGF0YUZsYXZvci5lcXVhbHMsIHdoaWNoIHByb3Blcmx5CisJICAgIC8vIGlnbm9yZXMgQ29udGVudC1UeXBlIHBhcmFtZXRlcnMgaW4gY29tcGFyaXNvbgorCSAgICBpZiAoYWRmW2ldLmVxdWFscyhkZikpCisJCXJldHVybiBnZXREYXRhKGFkZltpXSwgZHMpOworCX0KKwlyZXR1cm4gbnVsbDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9hbmRyb2lkL3BvbS54bWwgYi9hbmRyb2lkL3BvbS54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWQ5ODY4NQotLS0gL2Rldi9udWxsCisrKyBiL2FuZHJvaWQvcG9tLnhtbApAQCAtMCwwICsxLDkwIEBACis8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJpc28tODg1OS0xIj8+Cis8IS0tCisKKyAgICBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKworICAgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICAgIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorCisgICAgVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICAgIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAgICBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAgICB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKworICAgIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorCistLT4KKworPHByb2plY3QgeG1sbnM9Imh0dHA6Ly9tYXZlbi5hcGFjaGUub3JnL1BPTS80LjAuMCIKKwl4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIgorCXhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL21hdmVuLmFwYWNoZS5vcmcvUE9NLzQuMC4wCisJCQkgICAgaHR0cDovL21hdmVuLmFwYWNoZS5vcmcvbWF2ZW4tdjRfMF8wLnhzZCI+CisgICAgPHBhcmVudD4KKwk8Z3JvdXBJZD5jb20uc3VuLm1haWw8L2dyb3VwSWQ+CisJPGFydGlmYWN0SWQ+YWxsPC9hcnRpZmFjdElkPgorCTx2ZXJzaW9uPjEuNi4zPC92ZXJzaW9uPgorICAgIDwvcGFyZW50PgorICAgIDxtb2RlbFZlcnNpb24+NC4wLjA8L21vZGVsVmVyc2lvbj4KKyAgICA8Z3JvdXBJZD5jb20uc3VuLm1haWw8L2dyb3VwSWQ+CisgICAgPGFydGlmYWN0SWQ+YW5kcm9pZDwvYXJ0aWZhY3RJZD4KKyAgICA8cGFja2FnaW5nPnBvbTwvcGFja2FnaW5nPgorICAgIDxuYW1lPkFuZHJvaWQgc3VwcG9ydCBmb3IgSmF2YU1haWw8L25hbWU+CisKKyAgICA8bW9kdWxlcz4KKwk8bW9kdWxlPmFjdGl2YXRpb248L21vZHVsZT4KKwk8bW9kdWxlPm1haWw8L21vZHVsZT4KKyAgICA8L21vZHVsZXM+CisKKyAgICA8cHJvcGVydGllcz4KKwk8IS0tCisJICAgIFRoZSBtaW5pbXVtIHJlcXVpcmVkIEFuZHJvaWQgQVBJIHZlcnNpb24uCisJICAgIFRoaXMgY29ycmVzcG9uZHMgdG8gQW5kcm9pZCBLaXRLYXQuCisJICAgIGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0FuZHJvaWRfdmVyc2lvbl9oaXN0b3J5CisJICAgIE9sZGVyIHZlcnNpb25zIG1heSBhbHNvIHdvcmsgYnV0IHRoaXMgc2VlbXMgb2xkIGVub3VnaC4KKwkgICAgU2VlIHRoZSBNYXZlbiByZXBvc2l0b3J5IGZvciBleGFjdCB2ZXJzaW9ucyBhdmFpbGFibGU6CisJICAgIGh0dHBzOi8vcmVwbzEubWF2ZW4ub3JnL21hdmVuMi9uZXQvc2YvYW5kcm9pZHNjZW50cy9zaWduYXR1cmUvCisJICAgIFRoaXMgb25seSBjaGVja3MgQVBJIHNpZ25hdHVyZXM7IGl0IGRvZXNuJ3QgaW1wbHkgdGhhdCBpdAorCSAgICB3b3JrcyBjb3JyZWN0bHkgaW4gYSBydW50aW1lIG9mIHRoYXQgdmVyc2lvbi4KKwktLT4KKwk8YW5kcm9pZC5hcGkubGV2ZWw+MTk8L2FuZHJvaWQuYXBpLmxldmVsPgorCTxhbmRyb2lkLnZlcnNpb24+NC40X3IxPC9hbmRyb2lkLnZlcnNpb24+CisgICAgPC9wcm9wZXJ0aWVzPgorCisgICAgPGJ1aWxkPgorCTxwbHVnaW5zPgorCSAgICA8cGx1Z2luPgorCQk8Z3JvdXBJZD5vcmcuY29kZWhhdXMubW9qbzwvZ3JvdXBJZD4KKwkJPGFydGlmYWN0SWQ+YW5pbWFsLXNuaWZmZXItbWF2ZW4tcGx1Z2luPC9hcnRpZmFjdElkPgorCQk8ZXhlY3V0aW9ucz4KKwkJICAgIDxleGVjdXRpb24+CisJCQk8aWQ+Y2hlY2stc2lnPC9pZD4KKwkJCTxwaGFzZT5wYWNrYWdlPC9waGFzZT4KKwkJCTxnb2Fscz4KKwkJCSAgICA8Z29hbD5jaGVjazwvZ29hbD4KKwkJCTwvZ29hbHM+CisJCSAgICA8L2V4ZWN1dGlvbj4KKwkJPC9leGVjdXRpb25zPgorCQk8Y29uZmlndXJhdGlvbj4KKwkJICAgIDxzaWduYXR1cmU+CisJCQk8Z3JvdXBJZD5uZXQuc2YuYW5kcm9pZHNjZW50cy5zaWduYXR1cmU8L2dyb3VwSWQ+CisJCQk8YXJ0aWZhY3RJZD5hbmRyb2lkLWFwaS1sZXZlbC0ke2FuZHJvaWQuYXBpLmxldmVsfTwvYXJ0aWZhY3RJZD4KKwkJCTx2ZXJzaW9uPiR7YW5kcm9pZC52ZXJzaW9ufTwvdmVyc2lvbj4KKwkJICAgIDwvc2lnbmF0dXJlPgorCQk8L2NvbmZpZ3VyYXRpb24+CisJICAgIDwvcGx1Z2luPgorCTwvcGx1Z2lucz4KKworCTxwbHVnaW5NYW5hZ2VtZW50PgorCSAgICA8cGx1Z2lucz4KKwkJPHBsdWdpbj4KKwkJICAgIDxncm91cElkPm9yZy5jb2RlaGF1cy5tb2pvPC9ncm91cElkPgorCQkgICAgPGFydGlmYWN0SWQ+YW5pbWFsLXNuaWZmZXItbWF2ZW4tcGx1Z2luPC9hcnRpZmFjdElkPgorCQkgICAgPHZlcnNpb24+MS4xNjwvdmVyc2lvbj4KKwkJPC9wbHVnaW4+CisJICAgIDwvcGx1Z2lucz4KKwk8L3BsdWdpbk1hbmFnZW1lbnQ+CisgICAgPC9idWlsZD4KKworPC9wcm9qZWN0PgpkaWZmIC0tZ2l0IGEvYW50LWNvbW1vbi54bWwgYi9hbnQtY29tbW9uLnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNWEwMWJiCi0tLSAvZGV2L251bGwKKysrIGIvYW50LWNvbW1vbi54bWwKQEAgLTAsMCArMSwxNjUgQEAKKzw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04Ij8+Cis8IS0tCisKKyAgICBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKworICAgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICAgIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorCisgICAgVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICAgIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAgICBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAgICB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKworICAgIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorCistLT4KKworPCEtLQorQ29udGFpbnMgY29tbW9uIGRlZmluaXRpb24gdGhhdCBhcmUgcGxhdGZvcm0gZGVwZW5kZW50CistLT4KKzx0YXJnZXQgbmFtZT0idG9vbHMuaW5pdCI+CisgICAgPGNvbmRpdGlvbiBwcm9wZXJ0eT0id2luZG93cyI+CisgICAgICAgIDxvcyBmYW1pbHk9IndpbmRvd3MiIC8+CisgICAgPC9jb25kaXRpb24+CisgICAgPGNvbmRpdGlvbiBwcm9wZXJ0eT0idW5peCI+CisgICAgICAgIDxvcyBmYW1pbHk9InVuaXgiIC8+CisgICAgPC9jb25kaXRpb24+CisgICAgPGNvbmRpdGlvbiBwcm9wZXJ0eT0ic29sYXJpcyI+CisgICAgICAgIDxvcyBuYW1lPSJTdW5PUyIvPgorICAgIDwvY29uZGl0aW9uPgorICAgIDxjb25kaXRpb24gcHJvcGVydHk9ImxpbnV4Ij4KKyAgICAgICAgPG9zIG5hbWU9IkxpbnV4Ii8+CisgICAgPC9jb25kaXRpb24+CisgICAgPGNvbmRpdGlvbiBwcm9wZXJ0eT0ibWFjIj4KKyAgICAgICAgPG9zIG5hbWU9Ik1hYyBPUyBYIi8+CisgICAgPC9jb25kaXRpb24+Cis8L3RhcmdldD4KKzx0YXJnZXQgbmFtZT0idG9vbHMuaW5pdC53aW5kb3dzIiBpZj0id2luZG93cyI+CisgICAgPHByb3BlcnR5IG5hbWU9IkpBVkFIIiB2YWx1ZT0iJHtqYXZhLmhvbWV9Ly4uL2Jpbi9qYXZhaC5leGUiLz4KKyAgICA8cHJvcGVydHkgbmFtZT0iTUFLRSIgdmFsdWU9ImdtYWtlIi8+Cis8L3RhcmdldD4KKzx0YXJnZXQgbmFtZT0idG9vbHMuaW5pdC51bml4IiBpZj0idW5peCIgdW5sZXNzPSJtYWMiPgorICAgIDxwcm9wZXJ0eSBuYW1lPSJKQVZBSCIgdmFsdWU9IiR7amF2YS5ob21lfS8uLi9iaW4vamF2YWgiLz4KKyAgICA8cHJvcGVydHkgbmFtZT0iTUFLRSIgdmFsdWU9ImdtYWtlIi8+Cis8L3RhcmdldD4KKyAgICA8dGFyZ2V0IG5hbWU9InRvb2xzLmluaXQubWFjIiBpZj0ibWFjIj4KKyAgICA8cHJvcGVydHkgbmFtZT0iSkFWQUgiIHZhbHVlPSIke2phdmEuaG9tZX0vYmluL2phdmFoIi8+CisgICAgPHByb3BlcnR5IG5hbWU9Ik1BS0UiIHZhbHVlPSJtYWtlIi8+Cis8L3RhcmdldD4KKzx0YXJnZXQgbmFtZT0idG9vbHMuaW5pdC5wbGF0Zm9ybSIgCisgICAgZGVwZW5kcz0idG9vbHMuaW5pdCwgdG9vbHMuaW5pdC53aW5kb3dzLCB0b29scy5pbml0LnVuaXgsIHRvb2xzLmluaXQubWFjIj4KKzwvdGFyZ2V0PgorICAgIAorCis8IS0tCisgICAgRGVmaW5pdGlvbnMgZm9yIENoZWNrc3R5bGUKKy0tPgorPHRhcmdldCBuYW1lPSJjaGVja3N0eWxlIgorICAgICAgICBkZXNjcmlwdGlvbj0iR2VuZXJhdGVzIGEgcmVwb3J0IG9mIGNvZGluZyBjb252ZW50aW9uIHZpb2xhdGlvbnMuIj4KKworICAgIDwhLS0gR2V0IHByb3BlcnRpZXMgZnJvbSBlbnZpcm9ubWVudCAtLT4KKyAgICA8cHJvcGVydHkgZW52aXJvbm1lbnQ9ImVudiIvPgorCisgICAgPCEtLSBTZXQgZGVmYXVsdCB2YWx1ZXMgaWYgdGhlc2UgYXJlIG5vdCBpbiB0aGUgZW52aXJvbm1lbnQgLyBjbWQgbGluZSAtLT4KKyAgICA8IS0tIE9yZGVyIG9mIHByZWZlcmVuY2UgaXMgY21kIGxpbmUsIGVudmlyb25tZW50LCBkZWZhdWx0IC0tPgorICAgIDxwcm9wZXJ0eSBuYW1lPSJlbnYuSldTX0VYVEVSTkFMX0NPTVBPTkVOVFNfRElSIiB2YWx1ZT0iL25ldC9rb29yaS5zZmJheS9vbmVzdG9wL3MxYXNwZS84LjAvZXh0ZXJuYWwiLz4KKyAgICA8cHJvcGVydHkgbmFtZT0iSldTX0VYVEVSTkFMX0NPTVBPTkVOVFNfRElSIiB2YWx1ZT0iJHtlbnYuSldTX0VYVEVSTkFMX0NPTVBPTkVOVFNfRElSfSIvPgorICAgIDxwcm9wZXJ0eSBuYW1lPSJlbnYuQ0hFQ0tTVFlMRV9IT01FIiB2YWx1ZT0iJHtKV1NfRVhURVJOQUxfQ09NUE9ORU5UU19ESVJ9L2NoZWNrc3R5bGUiLz4KKworICAgIDwhLS0gQ0hFQ0tTVFlMRV9IT01FIGNvbnRhaW5zIENoZWNrc3R5bGUgamFycyBhbmQgY29uZmlnIGZpbGVzIC0tPgorICAgIDxwcm9wZXJ0eSBuYW1lPSJDSEVDS1NUWUxFX0hPTUUiIHZhbHVlPSIke2Vudi5DSEVDS1NUWUxFX0hPTUV9Ii8+CisKKyAgICA8dGFza2RlZiByZXNvdXJjZT0iY2hlY2tzdHlsZXRhc2sucHJvcGVydGllcyIgY2xhc3NwYXRoPSIke0NIRUNLU1RZTEVfSE9NRX0vY2hlY2tzdHlsZS1hbGwtMy41Lmphcjoke0NIRUNLU1RZTEVfSE9NRX0vY2hlY2tzdHlsZS1zdW4tbW9kdWxlcy5qYXIiLz4KKworCisgICAgPCEtLSBDSEVDS1NUWUxFX0RJUiwgQ0hFQ0tTVFlMRV9GSUxFUywgQ0hFQ0tTVFlMRV9TVFlMRVNIRUVULCAKKyAgICAgICAgIENIRUNLU1RZTEVfQ09ORklHIGFuZCBDSEVDS1NUWUxFX09VVFBVVCB2YXJpYWJsZXMgaGF2ZSBkZWZhdWx0cyBiZWxvdy4KKwkgVGhleSBjYW4gYmUgb3ZlcnJpZGRlbiBieSBzZXR0aW5nIGNvcnJlc3BvbmRpbmcgZW52IHZhcmlhYmxlcyAKKwkgaW4gdGhlIHNoZWxsLCBvciBmcm9tIHRoZSBjb21tYW5kIGxpbmU6CisgICAgICAgICAlIGFudCAtRENIRUNLU1RZTEVfRElSPXNvbWVkaXIgLURDSEVDS1NUWUxFX0ZJTEVTPSIqLmphdmEiIC4uLi4KKyAgICAgICAgIChjb21tYW5kLWxpbmUgb3ZlcnJpZGVzIGVudmlyb25tZW50IHZhcnMpLiAgLS0+CisgICAgPGNvbmRpdGlvbiBwcm9wZXJ0eT0iQ0hFQ0tTVFlMRV9GSUxFUyIgCisJICAgICAgIHZhbHVlPSIke2Vudi5DSEVDS1NUWUxFX0ZJTEVTfSI+CisgICAgICAgIDxpc3NldCBwcm9wZXJ0eT0iZW52LkNIRUNLU1RZTEVfRklMRVMiLz4KKyAgICA8L2NvbmRpdGlvbj4KKyAgICA8cHJvcGVydHkgbmFtZT0iQ0hFQ0tTVFlMRV9GSUxFUyIgdmFsdWU9IioqLyouamF2YSIvPgorCisgICAgPGNvbmRpdGlvbiBwcm9wZXJ0eT0iQ0hFQ0tTVFlMRV9ESVIiIAorCSAgICAgICB2YWx1ZT0iJHtlbnYuQ0hFQ0tTVFlMRV9ESVJ9Ij4KKyAgICAgICAgPGlzc2V0IHByb3BlcnR5PSJlbnYuQ0hFQ0tTVFlMRV9ESVIiLz4KKyAgICA8L2NvbmRpdGlvbj4KKyAgICA8cHJvcGVydHkgbmFtZT0iQ0hFQ0tTVFlMRV9ESVIiIHZhbHVlPSIuIi8+CisKKyAgICA8Y29uZGl0aW9uIHByb3BlcnR5PSJDSEVDS1NUWUxFX1NUWUxFU0hFRVQiIAorCSAgICAgICB2YWx1ZT0iJHtlbnYuQ0hFQ0tTVFlMRV9TVFlMRVNIRUVUfSI+CisgICAgICAgIDxpc3NldCBwcm9wZXJ0eT0iZW52LkNIRUNLU1RZTEVfU1RZTEVTSEVFVCIvPgorICAgIDwvY29uZGl0aW9uPgorICAgIDxwcm9wZXJ0eSBuYW1lPSJDSEVDS1NUWUxFX1NUWUxFU0hFRVQiIAorICAgICAgICAgICAgICB2YWx1ZT0iJHtDSEVDS1NUWUxFX0hPTUV9L2NoZWNrc3R5bGUtbm9mcmFtZXMtc29ydGVkLnhzbCIvPgorCisgICAgPGNvbmRpdGlvbiBwcm9wZXJ0eT0iQ0hFQ0tTVFlMRV9PVVRQVVQiIAorCSAgICAgICB2YWx1ZT0iJHtlbnYuQ0hFQ0tTVFlMRV9PVVRQVVR9Ij4KKyAgICAgICAgPGlzc2V0IHByb3BlcnR5PSJlbnYuQ0hFQ0tTVFlMRV9PVVRQVVQiLz4KKyAgICA8L2NvbmRpdGlvbj4KKyAgICA8cHJvcGVydHkgbmFtZT0iQ0hFQ0tTVFlMRV9PVVRQVVQiIHZhbHVlPSJjaGVja3N0eWxlLXJlcG9ydC5odG1sIi8+CisKKyAgICA8Y29uZGl0aW9uIHByb3BlcnR5PSJDSEVDS1NUWUxFX0NPTkZJRyIgCisJICAgICAgIHZhbHVlPSIke2Vudi5DSEVDS1NUWUxFX0NPTkZJR30iPgorICAgICAgICA8aXNzZXQgcHJvcGVydHk9ImVudi5DSEVDS1NUWUxFX0NPTkZJRyIvPgorICAgIDwvY29uZGl0aW9uPgorICAgIDxwcm9wZXJ0eSBuYW1lPSJDSEVDS1NUWUxFX0NPTkZJRyIgdmFsdWU9IiR7Q0hFQ0tTVFlMRV9IT01FfS9hcy1jaGVja3MueG1sIi8+CisKKworICAgIDxlY2hvIG1lc3NhZ2U9IlJ1bm5pbmcgQ2hlY2tzdHlsZSBvbiAke0NIRUNLU1RZTEVfRElSfS8ke0NIRUNLU1RZTEVfRklMRVN9IHVzaW5nIGNvbmZpZ3VyYXRpb24gJHtDSEVDS1NUWUxFX0NPTkZJR30gYW5kIHdyaXRpbmcgcmVwb3J0IHRvICR7Q0hFQ0tTVFlMRV9PVVRQVVR9Ii8+CisKKyAgICA8Y2hlY2tzdHlsZSBjb25maWc9IiR7Q0hFQ0tTVFlMRV9DT05GSUd9IgorICAgICAgICAgICAgICAgIGZhaWxPblZpb2xhdGlvbj0iZmFsc2UiPgorICAgICAgICA8Zm9ybWF0dGVyIHR5cGU9InhtbCIgdG9maWxlPSJjaGVja3N0eWxlLXJlcG9ydC54bWwiLz4KKyAgICAgICAgPGZpbGVzZXQgZGlyPSIke0NIRUNLU1RZTEVfRElSfSIgaW5jbHVkZXM9IiR7Q0hFQ0tTVFlMRV9GSUxFU30iLz4KKyAgICA8L2NoZWNrc3R5bGU+CisKKyAgICA8c3R5bGUgaW49ImNoZWNrc3R5bGUtcmVwb3J0LnhtbCIgb3V0PSIke0NIRUNLU1RZTEVfT1VUUFVUfSIgc3R5bGU9IiR7Q0hFQ0tTVFlMRV9TVFlMRVNIRUVUfSIvPgorCisgICAgPGRlbGV0ZSBmaWxlPSJjaGVja3N0eWxlLXJlcG9ydC54bWwiLz4KKworPC90YXJnZXQ+CisKKworPHRhcmdldCBuYW1lPSItcHVzaC10by1tYXZlbi1pbml0IiBkZXNjcmlwdGlvbj0iZGVmaW5lIGEgdGFzayBmb3IgcHVzaGluZyBiaXRzIHRvIHRoZSBtYXZlbiByZXBvc2l0b3J5Ij4KKyAgICA8ZWNobz4ke21hdmVuLnJlcG8ubG9jYWx9L2NvbS5zdW4ud3RzLnRvb2xzLm1yaS9qYXJzL21hdmVuLXJlcG9zaXRvcnktaW1wb3J0ZXItJHtnbGFzc2Zpc2gubWF2ZW5fcmVwb3NpdG9yeV9pbXBvcnRlci52ZXJzaW9ufS5qYXI8L2VjaG8+CisgICAgPHRhc2tkZWYgcmVzb3VyY2U9Im1hdmVuLXJlcG9zaXRvcnktaW1wb3J0ZXIucHJvcGVydGllcyI+CisgICAgICAgIDxjbGFzc3BhdGg+CisgICAgICAgICAgICA8cGF0aGVsZW1lbnQgcGF0aD0iJHttYXZlbi5yZXBvLmxvY2FsfS9jb20uc3VuLnd0cy50b29scy5tcmkvamFycy9tYXZlbi1yZXBvc2l0b3J5LWltcG9ydGVyLSR7Z2xhc3NmaXNoLm1hdmVuX3JlcG9zaXRvcnlfaW1wb3J0ZXIudmVyc2lvbn0uamFyIiAvPgorICAgICAgICA8L2NsYXNzcGF0aD4KKyAgICA8L3Rhc2tkZWY+Cis8L3RhcmdldD4KKworPCEtLQorICBpbXBvcnQgZmlsZXMgdG8gQ1ZTCisgIAorICBGb3IgZXhhbXBsZSwgPGN2cy1pbXBvcnQgc3JjPSJidWlsZC9kb2MiIGRlc3Q9ImpheGIvd3d3L2RvYyIgLz4KKy0tPgorPG1hY3JvZGVmIG5hbWU9ImN2cy1pbXBvcnQiPgorICAgIDxhdHRyaWJ1dGUgbmFtZT0ic3JjIi8+CisgICAgPGF0dHJpYnV0ZSBuYW1lPSJkZXN0Ii8+CisgICAgPHNlcXVlbnRpYWw+CisgICAgICAgIDx0c3RhbXAgLz4KKyAgICAgICAgPGVjaG8+aW1wb3J0aW5nIHRvIENWUy4uLjwvZWNobz4KKyAgICAgICAgPGN2cyBkZXN0PSJAe3NyY30iPgorICAgICAgICAgICAgPGNvbW1hbmRsaW5lPgorICAgICAgICAgICAgICAgIDxhcmd1bWVudCB2YWx1ZT0iLWQke2dsYXNzZmlzaC5jdnNyb290fSIvPgorICAgICAgICAgICAgICAgIDxhcmd1bWVudCBsaW5lPSItejkgaW1wb3J0IC1rbyIvPgorICAgICAgICAgICAgICAgIDxhcmd1bWVudCB2YWx1ZT0iLVciLz4KKyAgICAgICAgICAgICAgICA8YXJndW1lbnQgbGluZT0iKi5qYXIgLWtiIi8+CisgICAgICAgICAgICAgICAgPGFyZ3VtZW50IHZhbHVlPSItbSIvPgorICAgICAgICAgICAgICAgIDxhcmd1bWVudCB2YWx1ZT0iZGVwbG95aW5nIG5ldyBqYXJzIHRvIHRoZSBqYXZhLm5ldCBtYXZlbiByZXBvc2l0b3J5Ii8+CisgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgPGFyZ3VtZW50IHZhbHVlPSJAe2Rlc3R9Ii8+CisgICAgICAgICAgICAgICAgPGFyZ3VtZW50IGxpbmU9ImRlcGxveW1lbnQtdG8tbWF2ZW4tcmVwb3NpdG9yeSB0JHtEU1RBTVB9JHtUU1RBTVB9IiAvPgorICAgICAgICAgICAgPC9jb21tYW5kbGluZT4KKyAgICAgICAgPC9jdnM+CisgICAgPC9zZXF1ZW50aWFsPgorPC9tYWNyb2RlZj4KZGlmZiAtLWdpdCBhL2J1aWxkLnByb3BlcnRpZXMgYi9idWlsZC5wcm9wZXJ0aWVzCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI1ZTEzOTgKLS0tIC9kZXYvbnVsbAorKysgYi9idWlsZC5wcm9wZXJ0aWVzCkBAIC0wLDAgKzEsMTA4IEBACisjCisjIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorIworIyBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyMgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyMgaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorIworIyBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisjIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyMgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisjIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisjIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyMKKyMgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisjCisKKyMjIyBDb21wb25lbnQgUHJvcGVydGllcyAjIyMKK3NyYy5kaXI9bWFpbC9zcmMvbWFpbi9qYXZhCityZXNvdXJjZXMuZGlyPW1haWwvc3JjL21haW4vcmVzb3VyY2VzCitjb21wb25lbnQuY2xhc3Nlcy5kaXI9bWFpbC90YXJnZXQvY2xhc3NlcworIyMjIFN1YmNvbXBvbmVudCBQcm9wZXJ0aWVzICMjIworIyBkc24KK3NyYy5kc24uZGlyPWRzbi9zcmMvbWFpbi9qYXZhCityZXNvdXJjZXMuZHNuLmRpcj1kc24vc3JjL21haW4vcmVzb3VyY2VzCitjb21wb25lbnQuY2xhc3Nlcy5kc24uZGlyPWRzbi90YXJnZXQvY2xhc3NlcworIyBnaW1hcAorc3JjLmdpbWFwLmRpcj1naW1hcC9zcmMvbWFpbi9qYXZhCityZXNvdXJjZXMuZ2ltYXAuZGlyPWdpbWFwL3NyYy9tYWluL3Jlc291cmNlcworY29tcG9uZW50LmNsYXNzZXMuZ2ltYXAuZGlyPWdpbWFwL3RhcmdldC9jbGFzc2VzCisjIGltYXAKK3Jlc291cmNlcy5pbWFwLmRpcj1pbWFwL3NyYy9tYWluL3Jlc291cmNlcworY29tcG9uZW50LmNsYXNzZXMuaW1hcC5kaXI9aW1hcC90YXJnZXQvY2xhc3NlcworIyBwb3AzCityZXNvdXJjZXMucG9wMy5kaXI9cG9wMy9zcmMvbWFpbi9yZXNvdXJjZXMKK2NvbXBvbmVudC5jbGFzc2VzLnBvcDMuZGlyPXBvcDMvdGFyZ2V0L2NsYXNzZXMKKyMgc210cAorcmVzb3VyY2VzLnNtdHAuZGlyPXNtdHAvc3JjL21haW4vcmVzb3VyY2VzCitjb21wb25lbnQuY2xhc3Nlcy5zbXRwLmRpcj1zbXRwL3RhcmdldC9jbGFzc2VzCisjIG1ib3gKK3NyYy5tYm94LmRpcj1tYm94L3NyYy9tYWluL2phdmEKK3Jlc291cmNlcy5tYm94LmRpcj1tYm94L3NyYy9tYWluL3Jlc291cmNlcworY29tcG9uZW50LmNsYXNzZXMubWJveC5kaXI9bWJveC90YXJnZXQvY2xhc3NlcworIyBkZW1vCitzcmMuZGVtby5kaXI9ZGVtby9zcmMvbWFpbi9qYXZhCitjb21wb25lbnQuY2xhc3Nlcy5kZW1vLmRpcj1kZW1vL3RhcmdldC9jbGFzc2VzCisjIGNsaWVudAorc3JjLmNsaWVudC5kaXI9Y2xpZW50L3NyYy9tYWluL2phdmEKK2NvbXBvbmVudC5jbGFzc2VzLmNsaWVudC5kaXI9Y2xpZW50L3RhcmdldC9jbGFzc2VzCisjIHNlcnZsZXQKK3NyYy5zZXJ2bGV0LmRpcj1zZXJ2bGV0L3NyYy9tYWluL2phdmEKK2NvbXBvbmVudC5jbGFzc2VzLnNlcnZsZXQuZGlyPXNlcnZsZXQvdGFyZ2V0L2NsYXNzZXMKKyMgd2ViYXBwCitzcmMud2ViYXBwLmRpcj13ZWJhcHAvc3JjL21haW4vamF2YQorZG9jcm9vdC53ZWJhcHAuZGlyPXdlYmFwcC9zcmMvbWFpbi93ZWJhcHAKKyMgdGFnbGliCitzcmMudGFnbGliLmRpcj10YWdsaWIvc3JjL21haW4vamF2YQorcmVzb3VyY2VzLnRhZ2xpYi5kaXI9dGFnbGliL3NyYy9tYWluL3Jlc291cmNlcworIyBsb2dnaW5nCitzcmMubG9nZ2luZy5kaXI9bG9nZ2luZy9zcmMvbWFpbi9qYXZhCitjb21wb25lbnQuY2xhc3Nlcy5sb2dnaW5nLmRpcj1sb2dnaW5nL3RhcmdldC9jbGFzc2VzCisjIGxlZ2FsCityZXNvdXJjZXMubGVnYWwuZGlyPW1haWwvc3JjL21haW4vcmVzb3VyY2VzCisjCittYXZlbi5uZXRiZWFucy5leGVjLmJ1aWxkPXRhcmdldC9jbGFzc2VzCisKKyMgbmVlZGVkIHRvIGJ1aWxkIGV2ZXJ5dGhpbmcgb24gSkRLIDEuNQorYWN0aXZhdGlvbi5qYXI9YWN0aXZhdGlvbi5qYXIKKyMgbmVlZGVkIHRvIGJ1aWxkIHNlcnZsZXQgYW5kIHdlYmFwcCBkZW1vIHByb2dyYW1zCitqYXZhZWUuamFyPWphdmFlZS5qYXIKKyMgZXh0ZXJuYWwgVVJMIHJlZmVyZW5jZXMgZm9yIGphdmFkb2NzCitqYXZhc2UudXJsPWh0dHA6Ly9kb2NzLm9yYWNsZS5jb20vamF2YXNlLzEuNS4wL2RvY3MvYXBpCitqYWYudXJsPWh0dHA6Ly9kb2NzLm9yYWNsZS5jb20vamF2YXNlLzYvZG9jcy9hcGkKKworIyMjIEFkZGl0b25hbCBDb21wb25lbnQgUHJvcGVydGllcyBmb3Igc3RhbmRhbG9uZSByZWxlYXNlICMjIworcmVsZWFzZS5kaXI9dGFyZ2V0L3JlbGVhc2UKK3JlbGVhc2Uuc3BlY3ZlcnNpb249MS41CityZWxlYXNlLnZlcnNpb249MS41LjEtU05BUFNIT1QKK3JlbGVhc2UubWFpbC5qYXI9JHtyZWxlYXNlLmRpcn0vbWFpbC5qYXIKK3JlbGVhc2UubWFpbGFwaS5qYXI9JHtyZWxlYXNlLmRpcn0vbGliL21haWxhcGkuamFyCityZWxlYXNlLmltYXAuamFyPSR7cmVsZWFzZS5kaXJ9L2xpYi9pbWFwLmphcgorcmVsZWFzZS5zbXRwLmphcj0ke3JlbGVhc2UuZGlyfS9saWIvc210cC5qYXIKK3JlbGVhc2UucG9wMy5qYXI9JHtyZWxlYXNlLmRpcn0vbGliL3BvcDMuamFyCityZWxlYXNlLmdpbWFwLmphcj0ke3JlbGVhc2UuZGlyfS9saWIvZ2ltYXAuamFyCityZWxlYXNlLmRzbi5qYXI9JHtyZWxlYXNlLmRpcn0vbGliL2Rzbi5qYXIKK3JlbGVhc2UubWJveC5qYXI9JHtyZWxlYXNlLmRpcn0vbGliL21ib3guamFyCityZWxlYXNlLmRvY3MuZGlyPSR7cmVsZWFzZS5kaXJ9L2RvY3MKK3JlbGVhc2UuamF2YWRvY3MuZGlyPSR7cmVsZWFzZS5kb2NzLmRpcn0vamF2YWRvY3MKKworIyBGb2xsb3dpbmcgZnJvbSBib290c3RyYXAvcHJvamVjdC5wcm9wZXJ0aWVzCisKKyMgVG8gc3VwcG9ydCBOZXRCZWFucycgZGVmYXVsdCBjb21waWxlIHNpbmdsZSBmaWxlIHRhcmdldC4KK2J1aWxkLmRpcj1idWlsZAorYnVpbGQuY2xhc3Nlcy5kaXI9JHtidWlsZC5kaXJ9L2NsYXNzZXMKKworIyMgTWF2ZW4gcmVwb3NpdG9yeSBpbXBvcnRlcgorZ2xhc3NmaXNoLm1hdmVuX3JlcG9zaXRvcnlfaW1wb3J0ZXIudmVyc2lvbj0xLjEKKworIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKKyMgIENvbXBpbGF0aW9uIEZsYWdzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjCisjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIworamF2YWMuZGVidWc9b24KK2phdmFjLm9wdGltaXplPW9mZgoramF2YWMuZGVwcmVjYXRpb249b2ZmCitqYXZhYy5zb3VyY2U9MS41CitqYXZhYy50YXJnZXQ9MS41CisKKyMjIyBVc2UgYW50LnZlcmJvc2U9LXZlcmJvc2UgZm9yIGRlYnVnZ2luZyBhbnQgdGFyZ2V0cworYW50LnZlcmJvc2U9CmRpZmYgLS1naXQgYS9idWlsZC54bWwgYi9idWlsZC54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWYxNjkzNwotLS0gL2Rldi9udWxsCisrKyBiL2J1aWxkLnhtbApAQCAtMCwwICsxLDU4OCBAQAorPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PgorPCEtLQorCisgICAgQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisKKyAgICBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAgICB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKworICAgIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAgICBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgICAgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgICAgdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisKKyAgICBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKworLS0+CisKKzwhRE9DVFlQRSBwcm9qZWN0IFsKKyAgPCFFTlRJVFkgY29tbW9uQnVpbGQgU1lTVEVNICJhbnQtY29tbW9uLnhtbCI+CitdPgorCis8IS0tCisKKyAgICBOT1RFOiBKYXZhTWFpbCBpcyBub3cgYnVpbHQgdXNpbmcgTWF2ZW46CisgICAgaHR0cHM6Ly9qYXZhLm5ldC9wcm9qZWN0cy9qYXZhbWFpbC9wYWdlcy9CdWlsZEluc3RydWN0aW9ucworCisgICAgVGhpcyBhbnQgYnVpbGQgZmlsZSBpcyBvYnNvbGV0ZSBhbmQgbWF5IG5vdCB3b3JrLgorCistLT4KKworPHByb2plY3QgbmFtZT0iSmF2YU1haWwiIGRlZmF1bHQ9ImFsbCIgYmFzZWRpcj0iLiI+CisKKzwhLS0gPT09PT09PT09PSBJbml0aWFsaXplIFByb3BlcnRpZXMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gLS0+CisKKyAgICA8IS0tCisgICAgICAgIGNvbXBvbmVudC5uYW1lOiByZXF1aXJlZCBwcm9wZXJ0eS4gIHRoZSB2YWx1ZSBzaG91bGQgYmUgdGhlCisgICAgICAgICAgICAgICAgICAgICAgICBuYW1lIG9mIHRoZSBjb21wb25lbnQgZGlyZWN0b3J5CisgICAgLS0+CisgICAgPHByb3BlcnR5IG5hbWU9ImNvbXBvbmVudC5uYW1lIiB2YWx1ZT0ibWFpbCIvPgorCisgICAgPHByb3BlcnR5IGZpbGU9Ii4vYnVpbGQucHJvcGVydGllcyIvPgorICAgIAorICAgICZjb21tb25CdWlsZDsKKworICAgIDwhLS0gYWxsIC0tPgorICAgIDx0YXJnZXQgbmFtZT0iYWxsIiBkZXBlbmRzPSJjb21waWxlLCBhc3NlbWJsZSIKKyAgICAgICAgICAgIGRlc2NyaXB0aW9uPSJCdWlsZCBlbnRpcmUgY29tcG9uZW50Ij4KKyAgICA8L3RhcmdldD4KKworICAgIDwhLS0gYnVpbGQgLS0+CisgICAgPHRhcmdldCBuYW1lPSJidWlsZCIgZGVwZW5kcz0iY29tcGlsZSwgYXNzZW1ibGUiCisgICAgICAgICAgICBkZXNjcmlwdGlvbj0iQnVpbGQgZW50aXJlIGNvbXBvbmVudCI+CisgICAgPC90YXJnZXQ+CisKKyAgICA8IS0tIGluaXQuIEluaXRpYWxpemF0aW9uIGludm9sdmVzIGNyZWF0aW5nIHB1Ymxpc2hpbmcgZGlyZWN0b3JpZXMgYW5kCisgICAgICAgICBPUyBzcGVjaWZpYyB0YXJnZXRzLiAtLT4KKyAgICA8dGFyZ2V0IG5hbWU9ImluaXQiIGRlc2NyaXB0aW9uPSIke2NvbXBvbmVudC5uYW1lfSBpbml0aWFsaXphdGlvbiI+CisgICAgICAgIDx0c3RhbXA+CisgICAgICAgICAgICA8Zm9ybWF0IHByb3BlcnR5PSJzdGFydC50aW1lIiBwYXR0ZXJuPSJNTS9kZC95eXl5IGhoOm1tIGFhIi8+CisgICAgICAgIDwvdHN0YW1wPgorICAgICAgICA8ZWNobyBtZXNzYWdlPSJCdWlsZGluZyBjb21wb25lbnQgJHtjb21wb25lbnQubmFtZX0iLz4KKyAgICAgICAgPG1rZGlyIGRpcj0iJHtjb21wb25lbnQuY2xhc3Nlcy5kaXJ9Ii8+CisgICAgPC90YXJnZXQ+CisKKyAgICA8IS0tIGNvbXBpbGUgLS0+CisgICAgPHRhcmdldCBuYW1lPSJjb21waWxlIiBkZXBlbmRzPSJpbml0IgorICAgICAgICAgICAgZGVzY3JpcHRpb249IkNvbXBpbGUgSmF2YU1haWwgc291cmNlcyI+CisKKyAgICAgICAgPGNvcHkgZmlsZT0iJHtyZXNvdXJjZXMuZGlyfS9qYXZheC9tYWlsL1ZlcnNpb24uamF2YSIKKwkJdG9GaWxlPSIke3NyYy5kaXJ9L2phdmF4L21haWwvVmVyc2lvbi5qYXZhIj4KKyAgICAgICAgICAgIDxmaWx0ZXJzZXQgYmVnaW50b2tlbj0iJCR7IiBlbmR0b2tlbj0ifSI+CisgICAgICAgICAgICAgICAgPGZpbHRlciB0b2tlbj0ibWFpbC52ZXJzaW9uIiB2YWx1ZT0iJHtyZWxlYXNlLnZlcnNpb259Ii8+CisgICAgICAgICAgICA8L2ZpbHRlcnNldD4KKyAgICAgICAgPC9jb3B5PgorICAgICAgICA8amF2YWMgc3JjZGlyPSIke3NyYy5kaXJ9IgorICAgICAgICAgICAgICAgZGVzdGRpcj0iJHtjb21wb25lbnQuY2xhc3Nlcy5kaXJ9IgorICAgICAgICAgICAgICAgZGVidWc9IiR7amF2YWMuZGVidWd9IgorICAgICAgICAgICAgICAgb3B0aW1pemU9IiR7amF2YWMub3B0aW1pemV9IgorICAgICAgICAgICAgICAgc291cmNlPSIke2phdmFjLnNvdXJjZX0iCisgICAgICAgICAgICAgICBkZXByZWNhdGlvbj0iJHtqYXZhYy5kZXByZWNhdGlvbn0iCisgICAgICAgICAgICAgICBmYWlsb25lcnJvcj0idHJ1ZSIKKyAgICAgICAgICAgICAgIHRhcmdldD0iJHtqYXZhYy50YXJnZXR9IgorCSAgICAgICBpbmNsdWRlYW50cnVudGltZT0iZmFsc2UiPgorICAgICAgICAgICAgPGNsYXNzcGF0aD4KKyAgICAgICAgICAgICAgICA8cGF0aGVsZW1lbnQgbG9jYXRpb249IiR7YWN0aXZhdGlvbi5qYXJ9Ii8+CisgICAgICAgICAgICA8L2NsYXNzcGF0aD4KKyAgICAgICAgICAgIDxpbmNsdWRlIG5hbWU9ImphdmF4L21haWwvKioiLz4KKyAgICAgICAgICAgIDxpbmNsdWRlIG5hbWU9ImNvbS9zdW4vbWFpbC8qKiIvPgorICAgICAgICA8L2phdmFjPgorICAgIDwvdGFyZ2V0PgorICAgIAorICAgIDwhLS0gcHJlcGFyZSBtYW5pZmVzdCBmaWxlcyBmb3IgamFycyAtLT4KKyAgICA8dGFyZ2V0IG5hbWU9ImNvb2stbWFuaWZlc3QiIGRlcGVuZHM9ImluaXQiCisgICAgICAgICAgICBkZXNjcmlwdGlvbj0iR2VuZXJhdGUgTUFOSUZFU1QuTUYgZmlsZXMiPgorCTwhLS0KKworCSAgICBDb3VsZCBtYWtlIHRoaXMgc2ltcGxlciB3aXRoIGFudC1jb250cmliIGZvcmVhY2ggdGFzay4uLgorCisJPGZvcmVhY2ggbGlzdD0iLGltYXAuLHBvcDMuLHNtdHAuLGRzbi4iIHRhcmdldD0iY29vay1tYW5pZmVzdC1maWxlIgorCSAgICBwYXJhbT0ibWYiLz4KKwktLT4KKyAgICAgICAgPG1rZGlyIGRpcj0iJHtjb21wb25lbnQuY2xhc3Nlcy5kaXJ9L21hbmlmZXN0Ii8+CisgICAgICAgIDxjb3B5IGZpbGU9IiR7cmVzb3VyY2VzLmRpcn0vTUVUQS1JTkYvTUFOSUZFU1QuTUYiCisJCXRvZmlsZT0iJHtjb21wb25lbnQuY2xhc3Nlcy5kaXJ9L21hbmlmZXN0L01BTklGRVNULk1GIj4KKyAgICAgICAgICAgIDxmaWx0ZXJzZXQgYmVnaW50b2tlbj0ieyIgZW5kdG9rZW49In0iPgorCQk8ZmlsdGVyIHRva2VuPSJtYWlsLnNwZWMudmVyc2lvbiIKKwkJICAgIHZhbHVlPSIke3JlbGVhc2Uuc3BlY3ZlcnNpb259Ii8+CisJCTxmaWx0ZXIgdG9rZW49Im1haWwudmVyc2lvbiIgdmFsdWU9IiR7cmVsZWFzZS52ZXJzaW9ufSIvPgorICAgICAgICAgICAgPC9maWx0ZXJzZXQ+CisgICAgICAgIDwvY29weT4KKyAgICAgICAgPG1rZGlyIGRpcj0iJHtjb21wb25lbnQuY2xhc3Nlcy5pbWFwLmRpcn0vbWFuaWZlc3QiLz4KKyAgICAgICAgPGNvcHkgZmlsZT0iJHtyZXNvdXJjZXMuaW1hcC5kaXJ9L01FVEEtSU5GL01BTklGRVNULk1GIgorCQl0b2ZpbGU9IiR7Y29tcG9uZW50LmNsYXNzZXMuaW1hcC5kaXJ9L21hbmlmZXN0L01BTklGRVNULk1GIj4KKyAgICAgICAgICAgIDxmaWx0ZXJzZXQgYmVnaW50b2tlbj0ieyIgZW5kdG9rZW49In0iPgorCQk8ZmlsdGVyIHRva2VuPSJtYWlsLnNwZWMudmVyc2lvbiIKKwkJICAgIHZhbHVlPSIke3JlbGVhc2Uuc3BlY3ZlcnNpb259Ii8+CisJCTxmaWx0ZXIgdG9rZW49Im1haWwudmVyc2lvbiIgdmFsdWU9IiR7cmVsZWFzZS52ZXJzaW9ufSIvPgorICAgICAgICAgICAgPC9maWx0ZXJzZXQ+CisgICAgICAgIDwvY29weT4KKyAgICAgICAgPG1rZGlyIGRpcj0iJHtjb21wb25lbnQuY2xhc3Nlcy5wb3AzLmRpcn0vbWFuaWZlc3QiLz4KKyAgICAgICAgPGNvcHkgZmlsZT0iJHtyZXNvdXJjZXMucG9wMy5kaXJ9L01FVEEtSU5GL01BTklGRVNULk1GIgorCQl0b2ZpbGU9IiR7Y29tcG9uZW50LmNsYXNzZXMucG9wMy5kaXJ9L21hbmlmZXN0L01BTklGRVNULk1GIj4KKyAgICAgICAgICAgIDxmaWx0ZXJzZXQgYmVnaW50b2tlbj0ieyIgZW5kdG9rZW49In0iPgorCQk8ZmlsdGVyIHRva2VuPSJtYWlsLnNwZWMudmVyc2lvbiIKKwkJICAgIHZhbHVlPSIke3JlbGVhc2Uuc3BlY3ZlcnNpb259Ii8+CisJCTxmaWx0ZXIgdG9rZW49Im1haWwudmVyc2lvbiIgdmFsdWU9IiR7cmVsZWFzZS52ZXJzaW9ufSIvPgorICAgICAgICAgICAgPC9maWx0ZXJzZXQ+CisgICAgICAgIDwvY29weT4KKyAgICAgICAgPG1rZGlyIGRpcj0iJHtjb21wb25lbnQuY2xhc3Nlcy5zbXRwLmRpcn0vbWFuaWZlc3QiLz4KKyAgICAgICAgPGNvcHkgZmlsZT0iJHtyZXNvdXJjZXMuc210cC5kaXJ9L01FVEEtSU5GL01BTklGRVNULk1GIgorCQl0b2ZpbGU9IiR7Y29tcG9uZW50LmNsYXNzZXMuc210cC5kaXJ9L21hbmlmZXN0L01BTklGRVNULk1GIj4KKyAgICAgICAgICAgIDxmaWx0ZXJzZXQgYmVnaW50b2tlbj0ieyIgZW5kdG9rZW49In0iPgorCQk8ZmlsdGVyIHRva2VuPSJtYWlsLnNwZWMudmVyc2lvbiIKKwkJICAgIHZhbHVlPSIke3JlbGVhc2Uuc3BlY3ZlcnNpb259Ii8+CisJCTxmaWx0ZXIgdG9rZW49Im1haWwudmVyc2lvbiIgdmFsdWU9IiR7cmVsZWFzZS52ZXJzaW9ufSIvPgorICAgICAgICAgICAgPC9maWx0ZXJzZXQ+CisgICAgICAgIDwvY29weT4KKyAgICAgICAgPG1rZGlyIGRpcj0iJHtjb21wb25lbnQuY2xhc3Nlcy5kc24uZGlyfS9tYW5pZmVzdCIvPgorICAgICAgICA8Y29weSBmaWxlPSIke3Jlc291cmNlcy5kc24uZGlyfS9NRVRBLUlORi9NQU5JRkVTVC5NRiIKKwkJdG9maWxlPSIke2NvbXBvbmVudC5jbGFzc2VzLmRzbi5kaXJ9L21hbmlmZXN0L01BTklGRVNULk1GIj4KKyAgICAgICAgICAgIDxmaWx0ZXJzZXQgYmVnaW50b2tlbj0ieyIgZW5kdG9rZW49In0iPgorCQk8ZmlsdGVyIHRva2VuPSJtYWlsLnNwZWMudmVyc2lvbiIKKwkJICAgIHZhbHVlPSIke3JlbGVhc2Uuc3BlY3ZlcnNpb259Ii8+CisJCTxmaWx0ZXIgdG9rZW49Im1haWwudmVyc2lvbiIgdmFsdWU9IiR7cmVsZWFzZS52ZXJzaW9ufSIvPgorICAgICAgICAgICAgPC9maWx0ZXJzZXQ+CisgICAgICAgIDwvY29weT4KKyAgICAgICAgPG1rZGlyIGRpcj0iJHtjb21wb25lbnQuY2xhc3Nlcy5naW1hcC5kaXJ9L21hbmlmZXN0Ii8+CisgICAgICAgIDxjb3B5IGZpbGU9IiR7cmVzb3VyY2VzLmdpbWFwLmRpcn0vTUVUQS1JTkYvTUFOSUZFU1QuTUYiCisJCXRvZmlsZT0iJHtjb21wb25lbnQuY2xhc3Nlcy5naW1hcC5kaXJ9L21hbmlmZXN0L01BTklGRVNULk1GIj4KKyAgICAgICAgICAgIDxmaWx0ZXJzZXQgYmVnaW50b2tlbj0ieyIgZW5kdG9rZW49In0iPgorCQk8ZmlsdGVyIHRva2VuPSJtYWlsLnNwZWMudmVyc2lvbiIKKwkJICAgIHZhbHVlPSIke3JlbGVhc2Uuc3BlY3ZlcnNpb259Ii8+CisJCTxmaWx0ZXIgdG9rZW49Im1haWwudmVyc2lvbiIgdmFsdWU9IiR7cmVsZWFzZS52ZXJzaW9ufSIvPgorICAgICAgICAgICAgPC9maWx0ZXJzZXQ+CisgICAgICAgIDwvY29weT4KKyAgICA8L3RhcmdldD4KKworICAgIDwhLS0KKworCVRoaXMgY291bGQgYmUgdXNlZCB3aXRoIGZvcmVhY2gsIGFib3ZlLgorCVhYWCAtIGRvIG5lc3RlZCB2YXJpYWJsZSByZWZlcmVuY2VzIHdvcms/CisKKyAgICA8dGFyZ2V0IG5hbWU9ImNvb2stbWFuaWZlc3QtZmlsZSI+CisgICAgICAgIDxta2RpciBkaXI9IiR7Y29tcG9uZW50LmNsYXNzZXMuJHttZn1kaXJ9L21hbmlmZXN0Ii8+CisgICAgICAgIDxjb3B5IGZpbGU9IiR7cmVzb3VyY2VzLiR7bWZ9ZGlyfS9NRVRBLUlORi9NQU5JRkVTVC5NRiIKKwkJdG9maWxlPSIke2NvbXBvbmVudC5jbGFzc2VzLiR7bWZ9ZGlyfS9tYW5pZmVzdC9NQU5JRkVTVC5NRiI+CisgICAgICAgICAgICA8ZmlsdGVyc2V0IGJlZ2ludG9rZW49InsiIGVuZHRva2VuPSJ9Ij4KKwkJPGZpbHRlciB0b2tlbj0ibWFpbC5zcGVjLnZlcnNpb24iCisJCSAgICB2YWx1ZT0iJHtyZWxlYXNlLnNwZWN2ZXJzaW9ufSIvPgorCQk8ZmlsdGVyIHRva2VuPSJtYWlsLnZlcnNpb24iIHZhbHVlPSIke3JlbGVhc2UudmVyc2lvbn0iLz4KKyAgICAgICAgICAgIDwvZmlsdGVyc2V0PgorICAgICAgICA8L2NvcHk+CisgICAgPC90YXJnZXQ+CisgICAgLS0+CisKKyAgICA8IS0tIGdpbWFwIGNvbXBpbGUgLS0+CisgICAgPHRhcmdldCBuYW1lPSJnaW1hcGNvbXBpbGUiIGRlcGVuZHM9ImluaXQiCisgICAgICAgICAgICBkZXNjcmlwdGlvbj0iQ29tcGlsZSBjb20vc3VuL21haWwvZ2ltYXAgc291cmNlcyI+CisKKyAgICAgICAgPG1rZGlyIGRpcj0iJHtjb21wb25lbnQuY2xhc3Nlcy5naW1hcC5kaXJ9Ii8+CisgICAgICAgIDxqYXZhYyBzcmNkaXI9IiR7c3JjLmdpbWFwLmRpcn0iCisgICAgICAgICAgICAgICBkZXN0ZGlyPSIke2NvbXBvbmVudC5jbGFzc2VzLmdpbWFwLmRpcn0iCisgICAgICAgICAgICAgICBkZWJ1Zz0iJHtqYXZhYy5kZWJ1Z30iCisgICAgICAgICAgICAgICBvcHRpbWl6ZT0iJHtqYXZhYy5vcHRpbWl6ZX0iCisgICAgICAgICAgICAgICBzb3VyY2U9IiR7amF2YWMuc291cmNlfSIKKyAgICAgICAgICAgICAgIGRlcHJlY2F0aW9uPSIke2phdmFjLmRlcHJlY2F0aW9ufSIKKyAgICAgICAgICAgICAgIGZhaWxvbmVycm9yPSJ0cnVlIgorICAgICAgICAgICAgICAgdGFyZ2V0PSIke2phdmFjLnRhcmdldH0iCisJICAgICAgIGluY2x1ZGVhbnRydW50aW1lPSJmYWxzZSI+CisgICAgICAgICAgICA8Y2xhc3NwYXRoPgorICAgICAgICAgICAgICAgIDxwYXRoZWxlbWVudCBsb2NhdGlvbj0iJHtjb21wb25lbnQuY2xhc3Nlcy5kaXJ9Ii8+CisgICAgICAgICAgICAgICAgPHBhdGhlbGVtZW50IGxvY2F0aW9uPSIke2FjdGl2YXRpb24uamFyfSIvPgorICAgICAgICAgICAgPC9jbGFzc3BhdGg+CisgICAgICAgICAgICA8aW5jbHVkZSBuYW1lPSJjb20vc3VuL21haWwvZ2ltYXAvKioiLz4KKyAgICAgICAgPC9qYXZhYz4KKyAgICA8L3RhcmdldD4KKworICAgIDwhLS0gZHNuIGNvbXBpbGUgLS0+CisgICAgPHRhcmdldCBuYW1lPSJkc25jb21waWxlIiBkZXBlbmRzPSJpbml0IgorICAgICAgICAgICAgZGVzY3JpcHRpb249IkNvbXBpbGUgY29tL3N1bi9tYWlsL2RzbiBzb3VyY2VzIj4KKworICAgICAgICA8bWtkaXIgZGlyPSIke2NvbXBvbmVudC5jbGFzc2VzLmRzbi5kaXJ9Ii8+CisgICAgICAgIDxqYXZhYyBzcmNkaXI9IiR7c3JjLmRzbi5kaXJ9IgorICAgICAgICAgICAgICAgZGVzdGRpcj0iJHtjb21wb25lbnQuY2xhc3Nlcy5kc24uZGlyfSIKKyAgICAgICAgICAgICAgIGRlYnVnPSIke2phdmFjLmRlYnVnfSIKKyAgICAgICAgICAgICAgIG9wdGltaXplPSIke2phdmFjLm9wdGltaXplfSIKKyAgICAgICAgICAgICAgIHNvdXJjZT0iJHtqYXZhYy5zb3VyY2V9IgorICAgICAgICAgICAgICAgZGVwcmVjYXRpb249IiR7amF2YWMuZGVwcmVjYXRpb259IgorICAgICAgICAgICAgICAgZmFpbG9uZXJyb3I9InRydWUiCisgICAgICAgICAgICAgICB0YXJnZXQ9IiR7amF2YWMudGFyZ2V0fSIKKwkgICAgICAgaW5jbHVkZWFudHJ1bnRpbWU9ImZhbHNlIj4KKyAgICAgICAgICAgIDxjbGFzc3BhdGg+CisgICAgICAgICAgICAgICAgPHBhdGhlbGVtZW50IGxvY2F0aW9uPSIke2NvbXBvbmVudC5jbGFzc2VzLmRpcn0iLz4KKyAgICAgICAgICAgICAgICA8cGF0aGVsZW1lbnQgbG9jYXRpb249IiR7YWN0aXZhdGlvbi5qYXJ9Ii8+CisgICAgICAgICAgICA8L2NsYXNzcGF0aD4KKyAgICAgICAgICAgIDxpbmNsdWRlIG5hbWU9ImNvbS9zdW4vbWFpbC9kc24vKioiLz4KKyAgICAgICAgPC9qYXZhYz4KKyAgICA8L3RhcmdldD4KKworICAgIDwhLS0gZGVtbyBjb21waWxlIC0tPgorICAgIDx0YXJnZXQgbmFtZT0iZGVtb2NvbXBpbGUiIGRlcGVuZHM9ImluaXQiCisgICAgICAgICAgICBkZXNjcmlwdGlvbj0iQ29tcGlsZSBkZW1vIHNvdXJjZXMiPgorCisgICAgICAgIDxta2RpciBkaXI9IiR7Y29tcG9uZW50LmNsYXNzZXMuZGVtby5kaXJ9Ii8+CisgICAgICAgIDxqYXZhYyBzcmNkaXI9IiR7c3JjLmRlbW8uZGlyfSIKKyAgICAgICAgICAgICAgIGRlc3RkaXI9IiR7Y29tcG9uZW50LmNsYXNzZXMuZGVtby5kaXJ9IgorICAgICAgICAgICAgICAgZGVidWc9IiR7amF2YWMuZGVidWd9IgorICAgICAgICAgICAgICAgb3B0aW1pemU9IiR7amF2YWMub3B0aW1pemV9IgorICAgICAgICAgICAgICAgc291cmNlPSIke2phdmFjLnNvdXJjZX0iCisgICAgICAgICAgICAgICBkZXByZWNhdGlvbj0iJHtqYXZhYy5kZXByZWNhdGlvbn0iCisgICAgICAgICAgICAgICBmYWlsb25lcnJvcj0idHJ1ZSIKKyAgICAgICAgICAgICAgIHRhcmdldD0iJHtqYXZhYy50YXJnZXR9IgorCSAgICAgICBpbmNsdWRlYW50cnVudGltZT0iZmFsc2UiPgorICAgICAgICAgICAgPGNsYXNzcGF0aD4KKyAgICAgICAgICAgICAgICA8cGF0aGVsZW1lbnQgbG9jYXRpb249IiR7Y29tcG9uZW50LmNsYXNzZXMuZGlyfSIvPgorICAgICAgICAgICAgICAgIDxwYXRoZWxlbWVudCBsb2NhdGlvbj0iJHthY3RpdmF0aW9uLmphcn0iLz4KKyAgICAgICAgICAgIDwvY2xhc3NwYXRoPgorICAgICAgICAgICAgPGluY2x1ZGUgbmFtZT0iKiIvPgorICAgICAgICA8L2phdmFjPgorCisgICAgICAgIDxta2RpciBkaXI9IiR7Y29tcG9uZW50LmNsYXNzZXMuY2xpZW50LmRpcn0iLz4KKyAgICAgICAgPGphdmFjIHNyY2Rpcj0iJHtzcmMuY2xpZW50LmRpcn0iCisgICAgICAgICAgICAgICBkZXN0ZGlyPSIke2NvbXBvbmVudC5jbGFzc2VzLmNsaWVudC5kaXJ9IgorICAgICAgICAgICAgICAgZGVidWc9IiR7amF2YWMuZGVidWd9IgorICAgICAgICAgICAgICAgb3B0aW1pemU9IiR7amF2YWMub3B0aW1pemV9IgorICAgICAgICAgICAgICAgc291cmNlPSIke2phdmFjLnNvdXJjZX0iCisgICAgICAgICAgICAgICBkZXByZWNhdGlvbj0iJHtqYXZhYy5kZXByZWNhdGlvbn0iCisgICAgICAgICAgICAgICBmYWlsb25lcnJvcj0idHJ1ZSIKKyAgICAgICAgICAgICAgIHRhcmdldD0iJHtqYXZhYy50YXJnZXR9IgorCSAgICAgICBpbmNsdWRlYW50cnVudGltZT0iZmFsc2UiPgorICAgICAgICAgICAgPGNsYXNzcGF0aD4KKyAgICAgICAgICAgICAgICA8cGF0aGVsZW1lbnQgbG9jYXRpb249IiR7Y29tcG9uZW50LmNsYXNzZXMuZGlyfSIvPgorICAgICAgICAgICAgICAgIDxwYXRoZWxlbWVudCBsb2NhdGlvbj0iJHthY3RpdmF0aW9uLmphcn0iLz4KKyAgICAgICAgICAgIDwvY2xhc3NwYXRoPgorICAgICAgICAgICAgPGluY2x1ZGUgbmFtZT0iKiIvPgorICAgICAgICA8L2phdmFjPgorCisgICAgICAgIDxta2RpciBkaXI9IiR7Y29tcG9uZW50LmNsYXNzZXMuc2VydmxldC5kaXJ9Ii8+CisgICAgICAgIDxqYXZhYyBzcmNkaXI9IiR7c3JjLnNlcnZsZXQuZGlyfSIKKyAgICAgICAgICAgICAgIGRlc3RkaXI9IiR7Y29tcG9uZW50LmNsYXNzZXMuc2VydmxldC5kaXJ9IgorICAgICAgICAgICAgICAgZGVidWc9IiR7amF2YWMuZGVidWd9IgorICAgICAgICAgICAgICAgb3B0aW1pemU9IiR7amF2YWMub3B0aW1pemV9IgorICAgICAgICAgICAgICAgc291cmNlPSIke2phdmFjLnNvdXJjZX0iCisgICAgICAgICAgICAgICBkZXByZWNhdGlvbj0iJHtqYXZhYy5kZXByZWNhdGlvbn0iCisgICAgICAgICAgICAgICBmYWlsb25lcnJvcj0idHJ1ZSIKKyAgICAgICAgICAgICAgIHRhcmdldD0iJHtqYXZhYy50YXJnZXR9IgorCSAgICAgICBpbmNsdWRlYW50cnVudGltZT0iZmFsc2UiPgorICAgICAgICAgICAgPGNsYXNzcGF0aD4KKyAgICAgICAgICAgICAgICA8cGF0aGVsZW1lbnQgbG9jYXRpb249IiR7Y29tcG9uZW50LmNsYXNzZXMuZGlyfSIvPgorICAgICAgICAgICAgICAgIDxwYXRoZWxlbWVudCBsb2NhdGlvbj0iJHthY3RpdmF0aW9uLmphcn0iLz4KKyAgICAgICAgICAgICAgICA8cGF0aGVsZW1lbnQgbG9jYXRpb249IiR7amF2YWVlLmphcn0iLz4KKyAgICAgICAgICAgIDwvY2xhc3NwYXRoPgorICAgICAgICAgICAgPGluY2x1ZGUgbmFtZT0iKiIvPgorICAgICAgICA8L2phdmFjPgorCisgICAgICAgIDxta2RpciBkaXI9IiR7Y29tcG9uZW50LmNsYXNzZXMubG9nZ2luZy5kaXJ9Ii8+CisgICAgICAgIDxqYXZhYyBzcmNkaXI9IiR7c3JjLmxvZ2dpbmcuZGlyfSIKKyAgICAgICAgICAgICAgIGRlc3RkaXI9IiR7Y29tcG9uZW50LmNsYXNzZXMubG9nZ2luZy5kaXJ9IgorICAgICAgICAgICAgICAgZGVidWc9IiR7amF2YWMuZGVidWd9IgorICAgICAgICAgICAgICAgb3B0aW1pemU9IiR7amF2YWMub3B0aW1pemV9IgorICAgICAgICAgICAgICAgc291cmNlPSIke2phdmFjLnNvdXJjZX0iCisgICAgICAgICAgICAgICBkZXByZWNhdGlvbj0iJHtqYXZhYy5kZXByZWNhdGlvbn0iCisgICAgICAgICAgICAgICBmYWlsb25lcnJvcj0idHJ1ZSIKKyAgICAgICAgICAgICAgIHRhcmdldD0iJHtqYXZhYy50YXJnZXR9IgorCSAgICAgICBpbmNsdWRlYW50cnVudGltZT0iZmFsc2UiPgorICAgICAgICAgICAgPGNsYXNzcGF0aD4KKyAgICAgICAgICAgICAgICA8cGF0aGVsZW1lbnQgbG9jYXRpb249IiR7Y29tcG9uZW50LmNsYXNzZXMuZGlyfSIvPgorICAgICAgICAgICAgICAgIDxwYXRoZWxlbWVudCBsb2NhdGlvbj0iJHtjb21wb25lbnQuY2xhc3Nlcy5kZW1vLmRpcn0iLz4KKyAgICAgICAgICAgICAgICA8cGF0aGVsZW1lbnQgbG9jYXRpb249IiR7YWN0aXZhdGlvbi5qYXJ9Ii8+CisgICAgICAgICAgICA8L2NsYXNzcGF0aD4KKyAgICAgICAgICAgIDxpbmNsdWRlIG5hbWU9IioiLz4KKyAgICAgICAgPC9qYXZhYz4KKworCTwhLS0gWFhYIC0gc3RpbGwgbmVlZCB0byBhZGQgcnVsZXMgdG8gYnVpbGQgd2ViYXBwIC0tPgorCisgICAgPC90YXJnZXQ+CisKKyAgICA8IS0tIGFzc2VtYmxlIC0tPgorICAgIDx0YXJnZXQgbmFtZT0iYXNzZW1ibGUiIGRlcGVuZHM9ImphciIvPgorCisgICAgPHRhcmdldCBuYW1lPSJjbGVhbiIgZGVzY3JpcHRpb249IkNsZWFuIHRoZSBidWlsZCI+CisgICAgICAgIDxkZWxldGUgaW5jbHVkZUVtcHR5RGlycz0idHJ1ZSIgZmFpbG9uZXJyb3I9ImZhbHNlIj4KKyAgICAgICAgICAgIDxmaWxlc2V0IGRpcj0iJHtjb21wb25lbnQuY2xhc3Nlcy5kaXJ9Ii8+CisgICAgICAgICAgICA8ZmlsZXNldCBkaXI9IiR7Y29tcG9uZW50LmNsYXNzZXMuZHNuLmRpcn0iLz4KKyAgICAgICAgICAgIDxmaWxlc2V0IGRpcj0iJHtjb21wb25lbnQuY2xhc3Nlcy5naW1hcC5kaXJ9Ii8+CisgICAgICAgICAgICA8ZmlsZXNldCBkaXI9IiR7Y29tcG9uZW50LmNsYXNzZXMuZGVtby5kaXJ9Ii8+CisgICAgICAgICAgICA8ZmlsZXNldCBkaXI9IiR7Y29tcG9uZW50LmNsYXNzZXMuY2xpZW50LmRpcn0iLz4KKyAgICAgICAgICAgIDxmaWxlc2V0IGRpcj0iJHtjb21wb25lbnQuY2xhc3Nlcy5zZXJ2bGV0LmRpcn0iLz4KKyAgICAgICAgICAgIDxmaWxlc2V0IGRpcj0iJHtjb21wb25lbnQuY2xhc3Nlcy5sb2dnaW5nLmRpcn0iLz4KKyAgICAgICAgPC9kZWxldGU+CisgICAgPC90YXJnZXQ+CisKKyAgICA8dGFyZ2V0IG5hbWU9ImNsb2JiZXIiIGRlc2NyaXB0aW9uPSJDbG9iYmVyIGFsbCBkZXJpdmVkIGZpbGVzIj4KKyAgICAgICAgPGRlbGV0ZSBpbmNsdWRlRW1wdHlEaXJzPSJ0cnVlIiBmYWlsb25lcnJvcj0iZmFsc2UiPgorICAgICAgICAgICAgPGZpbGVzZXQgZGlyPSJ0YXJnZXQiLz4KKyAgICAgICAgPC9kZWxldGU+CisgICAgPC90YXJnZXQ+CisKKyAgICA8IS0tIEphdmFNYWlsIGJ1bmRsZSBidWlsZCB0YXJnZXRzIC0tPgorCisgICAgPHRhcmdldCBuYW1lPSJyZWxlYXNlIiBkZXBlbmRzPSJpbml0LCBqYXJzLCBkZW1vY29tcGlsZSwgZG9jcyI+CisJPCEtLSBYWFggLSBuZWVkIHRvIHJlcGxhY2UgIi4iIHdpdGggIl8iIGluIHJlbGVhc2UudmVyc2lvbiAtLT4KKyAgICAgICAgPHByb3BlcnR5IG5hbWU9InJlbCIgdmFsdWU9ImphdmFtYWlsLSR7cmVsZWFzZS52ZXJzaW9ufSIvPgorICAgICAgICA8cHJvcGVydHkgbmFtZT0iemlwbmFtZSIgdmFsdWU9IiR7cmVsfS56aXAiLz4KKyAgICAgICAgPGRlbGV0ZSBmaWxlPSIke2Jhc2VkaXJ9L3RhcmdldC8ke3ppcG5hbWV9Ii8+CisgICAgICAgIDxlY2hvIG1lc3NhZ2U9IkNyZWF0aW5nIEphdmFNYWlsIGJ1bmRsZSAke2Jhc2VkaXJ9L3RhcmdldC8ke3ppcG5hbWV9Ii8+CisgICAgICAgIDx6aXAgZGVzdGZpbGU9IiR7YmFzZWRpcn0vdGFyZ2V0LyR7emlwbmFtZX0iPgorCSAgICA8emlwZmlsZXNldCBkaXI9IiR7cmVsZWFzZS5kaXJ9IiBwcmVmaXg9IiR7cmVsfSIvPgorICAgICAgICAgICAgPHppcGZpbGVzZXQgZGlyPSIke3NyYy5kZW1vLmRpcn0iIHByZWZpeD0iJHtyZWx9L2RlbW8iCisgICAgICAgICAgICAgICAgZXhjbHVkZXM9IioqL2ludGVybmFsLyoqIi8+CisgICAgICAgICAgICA8emlwZmlsZXNldCBkaXI9IiR7c3JjLmNsaWVudC5kaXJ9IiBwcmVmaXg9IiR7cmVsfS9kZW1vL2NsaWVudCIvPgorICAgICAgICAgICAgPHppcGZpbGVzZXQgZGlyPSIke3NyYy5zZXJ2bGV0LmRpcn0iCisJCXByZWZpeD0iJHtyZWx9L2RlbW8vc2VydmxldCIvPgorICAgICAgICAgICAgPHppcGZpbGVzZXQgZGlyPSJ3ZWJhcHAiIHByZWZpeD0iJHtyZWx9L2RlbW8vd2ViYXBwIgorCQlleGNsdWRlcz0ic3JjLyoqLHBvbS54bWwiLz4KKyAgICAgICAgICAgIDx6aXBmaWxlc2V0IGRpcj0iJHtzcmMud2ViYXBwLmRpcn0iCisJCXByZWZpeD0iJHtyZWx9L2RlbW8vd2ViYXBwL3NyYy9jbGFzc2VzIi8+CisgICAgICAgICAgICA8emlwZmlsZXNldCBkaXI9IiR7ZG9jcm9vdC53ZWJhcHAuZGlyfSIKKwkJcHJlZml4PSIke3JlbH0vZGVtby93ZWJhcHAvc3JjL2RvY3Jvb3QiLz4KKyAgICAgICAgICAgIDx6aXBmaWxlc2V0IGRpcj0iJHtzcmMudGFnbGliLmRpcn0iCisJCXByZWZpeD0iJHtyZWx9L2RlbW8vd2ViYXBwL3NyYy90YWdsaWIiLz4KKyAgICAgICAgICAgIDx6aXBmaWxlc2V0IGRpcj0iJHtyZXNvdXJjZXMudGFnbGliLmRpcn0iCisJCXByZWZpeD0iJHtyZWx9L2RlbW8vd2ViYXBwL3NyYy90YWdsaWIiLz4KKyAgICAgICAgICAgIDx6aXBmaWxlc2V0IGRpcj0iJHtzcmMubG9nZ2luZy5kaXJ9IgorCQlwcmVmaXg9IiR7cmVsfS9kZW1vL2xvZ2dpbmciLz4KKyAgICAgICAgPC96aXA+CisgICAgPC90YXJnZXQ+CisKKyAgICA8IS0tIEJ1aWxkIGFsbCBqYXJzIG5lZWRlZCBmb3IgcmVsZWFzZSAtLT4KKyAgICA8dGFyZ2V0IG5hbWU9ImphcnMiCisJZGVwZW5kcz0iamFyLCBtYWlsYXBpamFyLCBwb3AzamFyLCBpbWFwamFyLCBzbXRwamFyLCBnaW1hcGphciwgZHNuamFyIi8+CisKKyAgICA8IS0tIEFzc2VtYmxlIG1haWwuamFyIC0tPgorICAgIDx0YXJnZXQgbmFtZT0iamFyIiBkZXBlbmRzPSJpbml0LCBjb21waWxlLCBjb29rLW1hbmlmZXN0Ij4KKyAgICAgICAgPG1rZGlyIGRpcj0iJHtyZWxlYXNlLmRpcn0iLz4KKyAgICAgICAgPGphciBqYXJmaWxlPSIke3JlbGVhc2UubWFpbC5qYXJ9IgorCQltYW5pZmVzdD0iJHtjb21wb25lbnQuY2xhc3Nlcy5kaXJ9L21hbmlmZXN0L01BTklGRVNULk1GIj4KKyAgICAgICAgICAgIDxtZXRhaW5mIGRpcj0iJHtyZXNvdXJjZXMubGVnYWwuZGlyfS9NRVRBLUlORiIKKwkJICAgIGluY2x1ZGVzPSJMSUNFTlNFLnR4dCIvPgorICAgICAgICAgICAgPG1ldGFpbmYgZGlyPSIke3Jlc291cmNlcy5kaXJ9L01FVEEtSU5GIgorICAgICAgICAgICAgICAgICAgICBpbmNsdWRlcz0iamF2YW1haWwuY2hhcnNldC5tYXAsamF2YW1haWwuZGVmYXVsdC4qLG1haWxjYXAiLz4KKyAgICAgICAgICAgIDxmaWxlc2V0IGRpcj0iJHtjb21wb25lbnQuY2xhc3Nlcy5kaXJ9Ij4KKyAgICAgICAgICAgICAgICA8aW5jbHVkZSBuYW1lPSJqYXZheC9tYWlsLyoqLyouY2xhc3MiLz4KKyAgICAgICAgICAgICAgICA8aW5jbHVkZSBuYW1lPSJjb20vc3VuL21haWwvKiovKi5jbGFzcyIvPgorICAgICAgICAgICAgPC9maWxlc2V0PgorICAgICAgICA8L2phcj4KKyAgICA8L3RhcmdldD4KKworICAgIDwhLS0gQ3JlYXRlIHppcCBmaWxlIG9mIHNvdXJjZSBjb2RlIHRvIHB1Ymxpc2ggdG8gbWF2ZW4gcmVwbyAtLT4KKyAgICA8dGFyZ2V0IG5hbWU9InNyYyI+CisgICAgICAgIDx6aXAgZmlsZT0idGFyZ2V0L21haWwuc3JjLnppcCI+CisgICAgICAgICAgICA8ZmlsZXNldCBkaXI9IiR7c3JjLmRpcn0iPgorICAgICAgICAgICAgICAgIDxpbmNsdWRlIG5hbWU9ImphdmF4L21haWwvKiovKi5qYXZhIi8+CisgICAgICAgICAgICAgICAgPGluY2x1ZGUgbmFtZT0iY29tL3N1bi9tYWlsLyoqLyouamF2YSIvPgorICAgICAgICAgICAgPC9maWxlc2V0PgorICAgICAgICA8L3ppcD4KKyAgICA8L3RhcmdldD4KKworICAgIDx0YXJnZXQgbmFtZT0iaW1hcGphciIgZGVwZW5kcz0iaW5pdCwgY29tcGlsZSwgY29vay1tYW5pZmVzdCI+CisgICAgICAgIDxta2RpciBkaXI9IiR7cmVsZWFzZS5kaXJ9L2xpYiIvPgorICAgICAgICA8amFyIGphcmZpbGU9IiR7cmVsZWFzZS5pbWFwLmphcn0iCisJCW1hbmlmZXN0PSIke2NvbXBvbmVudC5jbGFzc2VzLmltYXAuZGlyfS9tYW5pZmVzdC9NQU5JRkVTVC5NRiI+CisgICAgICAgICAgICA8bWV0YWluZiBkaXI9IiR7cmVzb3VyY2VzLmxlZ2FsLmRpcn0vTUVUQS1JTkYiCisJCSAgICBpbmNsdWRlcz0iTElDRU5TRS50eHQiLz4KKyAgICAgICAgICAgIDxtZXRhaW5mIGRpcj0iJHtyZXNvdXJjZXMuaW1hcC5kaXJ9L01FVEEtSU5GIgorCQkgICAgaW5jbHVkZXM9ImphdmFtYWlsLnByb3ZpZGVycyIvPgorICAgICAgICAgICAgPGZpbGVzZXQgZGlyPSIke2NvbXBvbmVudC5jbGFzc2VzLmRpcn0iPgorICAgICAgICAgICAgICAgIDxpbmNsdWRlIG5hbWU9ImNvbS9zdW4vbWFpbC9pYXAvKi5jbGFzcyIvPgorICAgICAgICAgICAgICAgIDxpbmNsdWRlIG5hbWU9ImNvbS9zdW4vbWFpbC9pbWFwLyouY2xhc3MiLz4KKyAgICAgICAgICAgICAgICA8aW5jbHVkZSBuYW1lPSJjb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC8qLmNsYXNzIi8+CisgICAgICAgICAgICA8L2ZpbGVzZXQ+CisgICAgICAgIDwvamFyPgorICAgIDwvdGFyZ2V0PgorCisgICAgPHRhcmdldCBuYW1lPSJwb3AzamFyIiBkZXBlbmRzPSJpbml0LCBjb21waWxlLCBjb29rLW1hbmlmZXN0Ij4KKyAgICAgICAgPG1rZGlyIGRpcj0iJHtyZWxlYXNlLmRpcn0vbGliIi8+CisgICAgICAgIDxqYXIgamFyZmlsZT0iJHtyZWxlYXNlLnBvcDMuamFyfSIKKwkJbWFuaWZlc3Q9IiR7Y29tcG9uZW50LmNsYXNzZXMucG9wMy5kaXJ9L21hbmlmZXN0L01BTklGRVNULk1GIj4KKyAgICAgICAgICAgIDxtZXRhaW5mIGRpcj0iJHtyZXNvdXJjZXMubGVnYWwuZGlyfS9NRVRBLUlORiIKKwkJICAgIGluY2x1ZGVzPSJMSUNFTlNFLnR4dCIvPgorICAgICAgICAgICAgPG1ldGFpbmYgZGlyPSIke3Jlc291cmNlcy5wb3AzLmRpcn0vTUVUQS1JTkYiCisJCSAgICBpbmNsdWRlcz0iamF2YW1haWwucHJvdmlkZXJzIi8+CisgICAgICAgICAgICA8ZmlsZXNldCBkaXI9IiR7Y29tcG9uZW50LmNsYXNzZXMuZGlyfSI+CisgICAgICAgICAgICAgICAgPGluY2x1ZGUgbmFtZT0iY29tL3N1bi9tYWlsL3BvcDMvKi5jbGFzcyIvPgorICAgICAgICAgICAgPC9maWxlc2V0PgorICAgICAgICA8L2phcj4KKyAgICAgPC90YXJnZXQ+CisKKyAgICAgPHRhcmdldCBuYW1lPSJzbXRwamFyIiBkZXBlbmRzPSJpbml0LCBjb21waWxlLCBjb29rLW1hbmlmZXN0Ij4KKyAgICAgICAgPG1rZGlyIGRpcj0iJHtyZWxlYXNlLmRpcn0vbGliIi8+CisgICAgICAgIDxqYXIgamFyZmlsZT0iJHtyZWxlYXNlLnNtdHAuamFyfSIKKwkJbWFuaWZlc3Q9IiR7Y29tcG9uZW50LmNsYXNzZXMuc210cC5kaXJ9L21hbmlmZXN0L01BTklGRVNULk1GIj4KKyAgICAgICAgICAgIDxtZXRhaW5mIGRpcj0iJHtyZXNvdXJjZXMubGVnYWwuZGlyfS9NRVRBLUlORiIKKwkJICAgIGluY2x1ZGVzPSJMSUNFTlNFLnR4dCIvPgorICAgICAgICAgICAgPG1ldGFpbmYgZGlyPSIke3Jlc291cmNlcy5zbXRwLmRpcn0vTUVUQS1JTkYiCisJCSAgICBpbmNsdWRlcz0iamF2YW1haWwucHJvdmlkZXJzLGphdmFtYWlsLmFkZHJlc3MubWFwIi8+CisgICAgICAgICAgICA8ZmlsZXNldCBkaXI9IiR7Y29tcG9uZW50LmNsYXNzZXMuZGlyfSI+CisgICAgICAgICAgICAgICAgPGluY2x1ZGUgbmFtZT0iY29tL3N1bi9tYWlsL3NtdHAvKi5jbGFzcyIvPgorICAgICAgICAgICAgPC9maWxlc2V0PgorICAgICAgICA8L2phcj4KKyAgICAgPC90YXJnZXQ+CisKKyAgICAgPHRhcmdldCBuYW1lPSJnaW1hcGphciIgZGVwZW5kcz0iaW5pdCwgZ2ltYXBjb21waWxlLCBjb29rLW1hbmlmZXN0Ij4KKyAgICAgICAgPG1rZGlyIGRpcj0iJHtyZWxlYXNlLmRpcn0vbGliIi8+CisgICAgICAgIDxqYXIgamFyZmlsZT0iJHtyZWxlYXNlLmdpbWFwLmphcn0iCisJCW1hbmlmZXN0PSIke2NvbXBvbmVudC5jbGFzc2VzLmdpbWFwLmRpcn0vbWFuaWZlc3QvTUFOSUZFU1QuTUYiPgorICAgICAgICAgICAgPG1ldGFpbmYgZGlyPSIke3Jlc291cmNlcy5sZWdhbC5kaXJ9L01FVEEtSU5GIgorCQkgICAgaW5jbHVkZXM9IkxJQ0VOU0UudHh0Ii8+CisgICAgICAgICAgICA8bWV0YWluZiBkaXI9IiR7cmVzb3VyY2VzLmdpbWFwLmRpcn0vTUVUQS1JTkYiCisJCSAgICBpbmNsdWRlcz0ibWFpbGNhcCIvPgorICAgICAgICAgICAgPGZpbGVzZXQgZGlyPSIke2NvbXBvbmVudC5jbGFzc2VzLmdpbWFwLmRpcn0iPgorICAgICAgICAgICAgICAgIDxpbmNsdWRlIG5hbWU9ImNvbS9zdW4vbWFpbC9naW1hcC8qLmNsYXNzIi8+CisgICAgICAgICAgICA8L2ZpbGVzZXQ+CisgICAgICAgIDwvamFyPgorICAgICA8L3RhcmdldD4KKworICAgICA8dGFyZ2V0IG5hbWU9ImRzbmphciIgZGVwZW5kcz0iaW5pdCwgZHNuY29tcGlsZSwgY29vay1tYW5pZmVzdCI+CisgICAgICAgIDxta2RpciBkaXI9IiR7cmVsZWFzZS5kaXJ9L2xpYiIvPgorICAgICAgICA8amFyIGphcmZpbGU9IiR7cmVsZWFzZS5kc24uamFyfSIKKwkJbWFuaWZlc3Q9IiR7Y29tcG9uZW50LmNsYXNzZXMuZHNuLmRpcn0vbWFuaWZlc3QvTUFOSUZFU1QuTUYiPgorICAgICAgICAgICAgPG1ldGFpbmYgZGlyPSIke3Jlc291cmNlcy5sZWdhbC5kaXJ9L01FVEEtSU5GIgorCQkgICAgaW5jbHVkZXM9IkxJQ0VOU0UudHh0Ii8+CisgICAgICAgICAgICA8bWV0YWluZiBkaXI9IiR7cmVzb3VyY2VzLmRzbi5kaXJ9L01FVEEtSU5GIgorCQkgICAgaW5jbHVkZXM9Im1haWxjYXAiLz4KKyAgICAgICAgICAgIDxmaWxlc2V0IGRpcj0iJHtjb21wb25lbnQuY2xhc3Nlcy5kc24uZGlyfSI+CisgICAgICAgICAgICAgICAgPGluY2x1ZGUgbmFtZT0iY29tL3N1bi9tYWlsL2Rzbi8qLmNsYXNzIi8+CisgICAgICAgICAgICA8L2ZpbGVzZXQ+CisgICAgICAgIDwvamFyPgorICAgICA8L3RhcmdldD4KKworICAgICA8dGFyZ2V0IG5hbWU9Im1haWxhcGlqYXIiIGRlcGVuZHM9ImluaXQsIGNvbXBpbGUsIGNvb2stbWFuaWZlc3QiPgorICAgICAgICA8bWtkaXIgZGlyPSIke3JlbGVhc2UuZGlyfS9saWIiLz4KKyAgICAgICAgPGphciBqYXJmaWxlPSIke3JlbGVhc2UubWFpbGFwaS5qYXJ9IgorCQltYW5pZmVzdD0iJHtjb21wb25lbnQuY2xhc3Nlcy5kaXJ9L21hbmlmZXN0L01BTklGRVNULk1GIj4KKyAgICAgICAgICAgIDxtZXRhaW5mIGRpcj0iJHtyZXNvdXJjZXMubGVnYWwuZGlyfS9NRVRBLUlORiIKKwkJICAgIGluY2x1ZGVzPSJMSUNFTlNFLnR4dCIvPgorICAgICAgICAgICAgPG1ldGFpbmYgZGlyPSIke3Jlc291cmNlcy5kaXJ9L01FVEEtSU5GIgorCQkgICAgaW5jbHVkZXM9ImphdmFtYWlsLmNoYXJzZXQubWFwLCBtYWlsY2FwIi8+CisgICAgICAgICAgICA8ZmlsZXNldCBkaXI9IiR7Y29tcG9uZW50LmNsYXNzZXMuZGlyfSI+CisgICAgICAgICAgICAgICAgPGluY2x1ZGUgbmFtZT0iamF2YXgvbWFpbC8qKi8qLmNsYXNzIi8+CisgICAgICAgICAgICAgICAgPGluY2x1ZGUgbmFtZT0iY29tL3N1bi9tYWlsL3V0aWwvKi5jbGFzcyIvPgorICAgICAgICAgICAgICAgIDxpbmNsdWRlIG5hbWU9ImNvbS9zdW4vbWFpbC9oYW5kbGVycy8qLmNsYXNzIi8+CisgICAgICAgICAgICA8L2ZpbGVzZXQ+CisgICAgICAgIDwvamFyPgorICAgIDwvdGFyZ2V0PgorCisgICAgPCEtLSBqYXZhZG9jcyAtLT4KKyAgICA8dGFyZ2V0IG5hbWU9ImRvY3MiIGRlcGVuZHM9ImluaXQsIGphciwgamFyIj4KKyAgICAgICAgPGNvcHkgdG9kaXI9IiR7cmVsZWFzZS5kaXJ9Ij4KKyAgICAgICAgICAgIDxmaWxlc2V0IGRpcj0iJHtiYXNlZGlyfS9kb2MvcmVsZWFzZSIgaW5jbHVkZXM9IioudHh0IiAvPgorICAgICAgICA8L2NvcHk+CisgICAgICAgIDxta2RpciBkaXI9IiR7cmVsZWFzZS5kb2NzLmRpcn0iLz4KKyAgICAgICAgPGNvcHkgdG9kaXI9IiR7cmVsZWFzZS5kb2NzLmRpcn0iPgorICAgICAgICAgICAgPGZpbGVzZXQgZGlyPSIke2Jhc2VkaXJ9L2RvYy9zcGVjIiBpbmNsdWRlcz0iKi50eHQiIC8+CisgICAgICAgIDwvY29weT4KKwk8IS0tCisJICAgIFRvIGFsbG93IHVzIHRvIGdlbmVyYXRlIGphdmFkb2NzIHRoYXQgb25seSBpbmNsdWRlIHNvbWUKKwkgICAgY2xhc3NlcyBpbiBjZXJ0YWluIHBhY2thZ2VzLCB3ZSBuZWVkIHRvIGNvcHkgdGhlIHNvdXJjZXMKKwkgICAgdG8gYW5vdGhlciBsb2NhdGlvbiBhbmQgcnVuIGphdmFkb2MgYWdhaW5zdCB0aGF0IHN1YnNldAorCSAgICBvZiB0aGUgc291cmNlcy4KKwktLT4KKyAgICAgICAgPGNvcHkgdG9kaXI9IiR7cmVsZWFzZS5kaXJ9L2phdmFkb2MiPgorCSAgICA8ZmlsZXNldCBkaXI9IiR7c3JjLmRpcn0iPgorCQk8aW5jbHVkZSBuYW1lPSIqKi8qLmh0bWwiLz4KKwkJPGluY2x1ZGUgbmFtZT0iamF2YXgvbWFpbC8qKiIvPgorCSAgICA8L2ZpbGVzZXQ+CisJICAgIDxmaWxlc2V0IGRpcj0iJHtzcmMuZGlyfSIKKwkJaW5jbHVkZXM9IgorCQkgICAgY29tL3N1bi9tYWlsL2ltYXAvSU1BUEZvbGRlci5qYXZhLAorCQkgICAgY29tL3N1bi9tYWlsL2ltYXAvSU1BUE1lc3NhZ2UuamF2YSwKKwkJICAgIGNvbS9zdW4vbWFpbC9pbWFwL0lNQVBTdG9yZS5qYXZhLAorCQkgICAgY29tL3N1bi9tYWlsL2ltYXAvSU1BUFNTTFN0b3JlLmphdmEKKwkJICAgIGNvbS9zdW4vbWFpbC9pbWFwL0FDTC5qYXZhLAorCQkgICAgY29tL3N1bi9tYWlsL2ltYXAvUmlnaHRzLmphdmEsCisJCSAgICBjb20vc3VuL21haWwvaW1hcC9RdW90YS5qYXZhLAorCQkgICAgY29tL3N1bi9tYWlsL2ltYXAvU29ydFRlcm0uamF2YSwKKwkJICAgIGNvbS9zdW4vbWFpbC9wb3AzL1BPUDNTdG9yZS5qYXZhLAorCQkgICAgY29tL3N1bi9tYWlsL3BvcDMvUE9QM1NTTFN0b3JlLmphdmEsCisJCSAgICBjb20vc3VuL21haWwvcG9wMy9QT1AzRm9sZGVyLmphdmEsCisJCSAgICBjb20vc3VuL21haWwvcG9wMy9QT1AzTWVzc2FnZS5qYXZhLAorCQkgICAgY29tL3N1bi9tYWlsL3NtdHAvU01UUE1lc3NhZ2UuamF2YSwKKwkJICAgIGNvbS9zdW4vbWFpbC9zbXRwL1NNVFBBZGRyZXNzRmFpbGVkRXhjZXB0aW9uLmphdmEsCisJCSAgICBjb20vc3VuL21haWwvc210cC9TTVRQQWRkcmVzc1N1Y2NlZWRlZEV4Y2VwdGlvbi5qYXZhLAorCQkgICAgY29tL3N1bi9tYWlsL3NtdHAvU01UUFNlbmRGYWlsZWRFeGNlcHRpb24uamF2YSwKKwkJICAgIGNvbS9zdW4vbWFpbC9zbXRwL1NNVFBTZW5kZXJGYWlsZWRFeGNlcHRpb24uamF2YSwKKwkJICAgIGNvbS9zdW4vbWFpbC9zbXRwL1NNVFBUcmFuc3BvcnQuamF2YSwKKwkJICAgIGNvbS9zdW4vbWFpbC9zbXRwL1NNVFBTU0xUcmFuc3BvcnQuamF2YSwKKwkJICAgIGNvbS9zdW4vbWFpbC91dGlsL01haWxDb25uZWN0RXhjZXB0aW9uLmphdmEsCisJCSAgICBjb20vc3VuL21haWwvdXRpbC9NYWlsU1NMU29ja2V0RmFjdG9yeS5qYXZhLAorCQkgICAgY29tL3N1bi9tYWlsL3V0aWwvUmVhZGFibGVNaW1lLmphdmEsCisJCSAgICBjb20vc3VuL21haWwvdXRpbC9sb2dnaW5nL01haWxIYW5kbGVyLmphdmEKKwkJIi8+CisJICAgIDxmaWxlc2V0IGRpcj0iJHtzcmMuZHNuLmRpcn0iCisJCWluY2x1ZGVzPSIKKwkJICAgIGNvbS9zdW4vbWFpbC9kc24vcGFja2FnZS5odG1sLAorCQkgICAgY29tL3N1bi9tYWlsL2Rzbi9EZWxpdmVyeVN0YXR1cy5qYXZhLAorCQkgICAgY29tL3N1bi9tYWlsL2Rzbi9EaXNwb3NpdGlvbk5vdGlmaWNhdGlvbi5qYXZhLAorCQkgICAgY29tL3N1bi9tYWlsL2Rzbi9NZXNzYWdlSGVhZGVycy5qYXZhLAorCQkgICAgY29tL3N1bi9tYWlsL2Rzbi9NdWx0aXBhcnRSZXBvcnQuamF2YSwKKwkJICAgIGNvbS9zdW4vbWFpbC9kc24vUmVwb3J0LmphdmEKKwkJIi8+CisJICAgIDxmaWxlc2V0IGRpcj0iJHtzcmMuZHNuLmRpcn0iCisJCWluY2x1ZGVzPSIKKwkJICAgIGNvbS9zdW4vbWFpbC9naW1hcC9wYWNrYWdlLmh0bWwsCisJCSAgICBjb20vc3VuL21haWwvZ2ltYXAvR21haWxTdG9yZS5qYXZhLAorCQkgICAgY29tL3N1bi9tYWlsL2dpbWFwL0dtYWlsU1NMU3RvcmUuamF2YSwKKwkJICAgIGNvbS9zdW4vbWFpbC9naW1hcC9HbWFpbEZvbGRlci5qYXZhLAorCQkgICAgY29tL3N1bi9tYWlsL2dpbWFwL0dtYWlsTWVzc2FnZS5qYXZhLAorCQkgICAgY29tL3N1bi9tYWlsL2dpbWFwL0dtYWlsTXNnSWRUZXJtLmphdmEsCisJCSAgICBjb20vc3VuL21haWwvZ2ltYXAvR21haWxUaHJJZFRlcm0uamF2YSwKKwkJICAgIGNvbS9zdW4vbWFpbC9naW1hcC9HbWFpbFJhd1NlYXJjaFRlcm0uamF2YQorCQkiLz4KKyAgICAgICAgPC9jb3B5PgorICAgICAgICA8bWtkaXIgZGlyPSIke3JlbGVhc2UuamF2YWRvY3MuZGlyfSIvPgorICAgICAgICA8amF2YWRvYyBwYWNrYWdlbmFtZXM9ImphdmF4Lm1haWwsIGphdmF4Lm1haWwuaW50ZXJuZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgamF2YXgubWFpbC5zZWFyY2gsIGphdmF4Lm1haWwuZXZlbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgamF2YXgubWFpbC51dGlsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbS5zdW4ubWFpbC5pbWFwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbS5zdW4ubWFpbC5wb3AzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbS5zdW4ubWFpbC5zbXRwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbS5zdW4ubWFpbC5naW1hcCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb20uc3VuLm1haWwudXRpbCwgY29tLnN1bi5tYWlsLnV0aWwubG9nZ2luZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb20uc3VuLm1haWwuZHNuIgorICAgICAgICAgICAgZGVzdGRpcj0iJHtyZWxlYXNlLmphdmFkb2NzLmRpcn0iCisJICAgIHNvdXJjZXBhdGg9IiR7cmVsZWFzZS5kaXJ9L2phdmFkb2MiCisgICAgICAgICAgICBjbGFzc3BhdGg9IiR7YWN0aXZhdGlvbi5qYXJ9OiR7cmVsZWFzZS5tYWlsLmphcn06JHtyZWxlYXNlLmRzbi5qYXJ9OiR7cmVsZWFzZS5naW1hcC5qYXJ9IgorICAgICAgICAgICAgYXV0aG9yPSJmYWxzZSIKKyAgICAgICAgICAgIHZlcnNpb249ImZhbHNlIgorICAgICAgICAgICAgdXNlPSJ0cnVlIgorICAgICAgICAgICAgb3ZlcnZpZXc9IiR7cmVsZWFzZS5kaXJ9L2phdmFkb2Mvb3ZlcnZpZXcuaHRtbCIKKyAgICAgICAgICAgIHdpbmRvd3RpdGxlPSJKYXZhTWFpbCBBUEkgZG9jdW1lbnRhdGlvbiIKKyAgICAgICAgICAgIGRvY3RpdGxlPSJKYXZhTWFpbCBBUEkgZG9jdW1lbnRhdGlvbiI+CisgICAgICAgICAgICA8Z3JvdXAgdGl0bGU9IkphdmFNYWlsIEFQSSBQYWNrYWdlcyIgcGFja2FnZXM9ImphdmF4LioiLz4KKyAgICAgICAgICAgIDxncm91cCB0aXRsZT0iU3VuLXNwZWNpZmljIFBhY2thZ2VzIiBwYWNrYWdlcz0iY29tLnN1bi4qIi8+CisJICAgIDxib3R0b20+Cis8IVtDREFUQVtDb3B5cmlnaHQgJiMxNjk7IDE5OTYtMjAxMywKKyAgICA8YSBocmVmPSJodHRwOi8vd3d3Lm9yYWNsZS5jb20iPk9yYWNsZTwvYT4KKyAgICBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCisgICAgVXNlIGlzIHN1YmplY3QgdG8KKyAgICA8YSBocmVmPSJ7QGRvY1Jvb3R9L2RvYy1maWxlcy9zcGVjbGljZW5zZS5odG1sIiB0YXJnZXQ9Il90b3AiPmxpY2Vuc2UgdGVybXM8CisgICAgL2E+LgorXV0+CisKKwkgICAgPC9ib3R0b20+CisJICAgIDwhLS0gZm9sbG93aW5nIGNhbiByZWFsbHkgc2xvdyBkb3duIGphdmFkb2MgZ2VuZXJhdGlvbgorCSAgICA8bGluayBocmVmPSIke2phdmFzZS51cmx9Ii8+CisJICAgIDxsaW5rIGhyZWY9IiR7amFmLnVybH0iLz4KKwkgICAgLS0+CisgICAgICAgIDwvamF2YWRvYz4KKyAgICA8L3RhcmdldD4KKworICAgIDx0YXJnZXQgbmFtZT0icHVzaC10by1tYXZlbi1wcmVwYXJlIiBkZXBlbmRzPSItcHVzaC10by1tYXZlbi1pbml0LCBqYXIsIHNyYyIKKyAgICAgICAgZGVzY3JpcHRpb249ImNyZWF0ZXMgYW4gaW1hZ2UgZm9yIHRoZSAncHVzaC10by1tYXZlbicgZ29hbCI+CisgICAgICAgIDxkZWxldGUgZGlyPSJ0YXJnZXQvbWF2ZW4tcmVwbyIgLz48IS0tIGNsZWFuIGl0IC0tPgorICAgICAgICA8bWF2ZW4tcmVwb3NpdG9yeS1pbXBvcnRlcgorCQlkZXN0ZGlyPSJ0YXJnZXQvbWF2ZW4tcmVwbyIgdmVyc2lvbj0iJHtyZWxlYXNlLnZlcnNpb259Ij4KKyAgICAgICAgICAgIDxhcnRpZmFjdCBqYXI9InRhcmdldC9yZWxlYXNlL21haWwuamFyIiBwb209Im1haWwucG9tIgorCQkgICAgc3JjemlwPSJ0YXJnZXQvbWFpbC5zcmMuemlwIiAvPgorICAgICAgICA8L21hdmVuLXJlcG9zaXRvcnktaW1wb3J0ZXI+CisgICAgPC90YXJnZXQ+CisKKyAgICA8dGFyZ2V0IG5hbWU9InB1c2gtdG8tbWF2ZW4iIGRlcGVuZHM9InB1c2gtdG8tbWF2ZW4tcHJlcGFyZSIKKyAgICAgICAgZGVzY3JpcHRpb249InB1c2hlcyBqYXJzIHRvIHRoZSBqYXZhLm5ldCBtYXZlbiByZXBvc2l0b3J5Ij4KKyAgICAgICAgPGN2cy1pbXBvcnQgc3JjPSJ0YXJnZXQvbWF2ZW4tcmVwbyIgZGVzdD0iZ2xhc3NmaXNoL3JlcG8iIC8+CisgICAgPC90YXJnZXQ+Cis8L3Byb2plY3Q+CmRpZmYgLS1naXQgYS9jbGllbnQvcG9tLnhtbCBiL2NsaWVudC9wb20ueG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQyYzNkNzgKLS0tIC9kZXYvbnVsbAorKysgYi9jbGllbnQvcG9tLnhtbApAQCAtMCwwICsxLDc0IEBACis8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJpc28tODg1OS0xIj8+Cis8IS0tCisKKyAgICBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKworICAgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICAgIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorCisgICAgVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICAgIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAgICBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAgICB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKworICAgIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorCistLT4KKworPHByb2plY3QgeG1sbnM9Imh0dHA6Ly9tYXZlbi5hcGFjaGUub3JnL1BPTS80LjAuMCIKKwl4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIgorCXhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL21hdmVuLmFwYWNoZS5vcmcvUE9NLzQuMC4wCisJCQkgICAgaHR0cDovL21hdmVuLmFwYWNoZS5vcmcvbWF2ZW4tdjRfMF8wLnhzZCI+CisgICAgPHBhcmVudD4KKwk8Z3JvdXBJZD5jb20uc3VuLm1haWw8L2dyb3VwSWQ+CisJPGFydGlmYWN0SWQ+YWxsPC9hcnRpZmFjdElkPgorCTx2ZXJzaW9uPjEuNi4zPC92ZXJzaW9uPgorICAgIDwvcGFyZW50PgorICAgIDxtb2RlbFZlcnNpb24+NC4wLjA8L21vZGVsVmVyc2lvbj4KKyAgICA8Z3JvdXBJZD5jb20uc3VuLm1haWw8L2dyb3VwSWQ+CisgICAgPGFydGlmYWN0SWQ+Y2xpZW50PC9hcnRpZmFjdElkPgorICAgIDxwYWNrYWdpbmc+amFyPC9wYWNrYWdpbmc+CisgICAgPG5hbWU+SmF2YU1haWwgQVBJIGRlbW8gY2xpZW50PC9uYW1lPgorCisgICAgPGJ1aWxkPgorICAgICAgICA8cGx1Z2lucz4KKwkgICAgPCEtLQorCQlOZWVkIHRvIGRpc2FibGUgdGhlIG1hdmVuLWJ1bmRsZS1wbHVnaW4gYmVjYXVzZSB0aGUKKwkJbmV3IHZlcnNpb24gZG9lc24ndCBsaWtlIGNsYXNzZXMgaW4gdGhlIGRlZmF1bHQgcGFja2FnZS4KKwkgICAgLS0+CisJICAgIDxwbHVnaW4+CisJCTxncm91cElkPm9yZy5hcGFjaGUuZmVsaXg8L2dyb3VwSWQ+CisJCTxhcnRpZmFjdElkPm1hdmVuLWJ1bmRsZS1wbHVnaW48L2FydGlmYWN0SWQ+CisJCTxleGVjdXRpb25zPgorCQkgICAgPGV4ZWN1dGlvbj4KKwkJCTxpZD5vc2dpLW1hbmlmZXN0PC9pZD4KKwkJCTxwaGFzZT5ub25lPC9waGFzZT4KKwkJICAgIDwvZXhlY3V0aW9uPgorCQk8L2V4ZWN1dGlvbnM+CisJICAgIDwvcGx1Z2luPgorCisJICAgIDwhLS0KKwkJQmVjYXVzZSB0aGUgbWF2ZW4tamFyLXBsdWdpbiBkZXBlbmRzIG9uIHRoZSBtYW5pZmVzdCBmaWxlCisJCWNyZWF0ZWQgYnkgdGhlIG1hdmVuLWJ1bmRsZS1wbHVnaW4sIHdlIG5lZWQgdG8gZGlzYWJsZSBpdCB0b28uCisJICAgIC0tPgorCSAgICA8cGx1Z2luPgorCQk8YXJ0aWZhY3RJZD5tYXZlbi1qYXItcGx1Z2luPC9hcnRpZmFjdElkPgorCQk8ZXhlY3V0aW9ucz4KKwkJICAgIDxleGVjdXRpb24+CisJCQk8aWQ+ZGVmYXVsdC1qYXI8L2lkPgorCQkJPHBoYXNlPm5vbmU8L3BoYXNlPgorCQkgICAgPC9leGVjdXRpb24+CisJCTwvZXhlY3V0aW9ucz4KKwkgICAgPC9wbHVnaW4+CisgICAgICAgIDwvcGx1Z2lucz4KKyAgICA8L2J1aWxkPgorCisgICAgPGRlcGVuZGVuY2llcz4KKyAgICAgICAgPGRlcGVuZGVuY3k+CisgICAgICAgICAgICA8Z3JvdXBJZD5jb20uc3VuLm1haWw8L2dyb3VwSWQ+CisgICAgICAgICAgICA8YXJ0aWZhY3RJZD5qYWthcnRhLm1haWw8L2FydGlmYWN0SWQ+CisgICAgICAgIDwvZGVwZW5kZW5jeT4KKyAgICA8L2RlcGVuZGVuY2llcz4KKzwvcHJvamVjdD4KZGlmZiAtLWdpdCBhL2NsaWVudC9zcmMvbWFpbi9qYXZhL0NvbXBvbmVudEZyYW1lLmphdmEgYi9jbGllbnQvc3JjL21haW4vamF2YS9Db21wb25lbnRGcmFtZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM4MmI1NmUKLS0tIC9kZXYvbnVsbAorKysgYi9jbGllbnQvc3JjL21haW4vamF2YS9Db21wb25lbnRGcmFtZS5qYXZhCkBAIC0wLDAgKzEsNTMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorICovCisKK2ltcG9ydCBqYXZhLmF3dC4qOworaW1wb3J0IGphdmEuYXd0LmV2ZW50Lio7CitpbXBvcnQgamF2YXguc3dpbmcuSkZyYW1lOworaW1wb3J0IGphdmF4LnN3aW5nLldpbmRvd0NvbnN0YW50czsKKworCisvKioKKyAqIHRoaXMgRnJhbWUgcHJvdmlkZXMgYSB1dGlsaXR5IGNsYXNzIGZvciBkaXNwbGF5aW5nIGEgc2luZ2xlCisgKiBDb21wb25lbnQgaW4gYSBGcmFtZS4KKyAqCisgKiBAYXV0aG9yCUNocmlzdG9waGVyIENvdHRvbgorICovCisKK3B1YmxpYyBjbGFzcyBDb21wb25lbnRGcmFtZSBleHRlbmRzIEpGcmFtZSB7CisgICAgCisgICAgLyoqCisgICAgICogY3JlYXRlcyB0aGUgZnJhbWUKKyAgICAgKiBAcGFyYW0gd2hhdAl0aGUgY29tcG9uZW50IHRvIGRpc3BsYXkKKyAgICAgKi8KKyAgICBwdWJsaWMgQ29tcG9uZW50RnJhbWUoQ29tcG9uZW50IHdoYXQpIHsKKwl0aGlzKHdoYXQsICJDb21wb25lbnQgRnJhbWUiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBjcmVhdGVzIHRoZSBmcmFtZSB3aXRoIHRoZSBnaXZlbiBuYW1lCisgICAgICogQHBhcmFtIHdoYXQJdGhlIGNvbXBvbmVudCB0byBkaXNwbGF5CisgICAgICogQHBhcmFtIG5hbWUJdGhlIG5hbWUgb2YgdGhlIEZyYW1lCisgICAgICovCisgICAgcHVibGljIENvbXBvbmVudEZyYW1lKENvbXBvbmVudCB3aGF0LCBTdHJpbmcgbmFtZSkgeworCXN1cGVyKG5hbWUpOworCisJLy8gbWFrZSBzdXJlIHRoYXQgd2UgY2xvc2UgYW5kIGRpc3Bvc2Ugb3Vyc2VsdmVzIHdoZW4gbmVlZGVkCisJc2V0RGVmYXVsdENsb3NlT3BlcmF0aW9uKFdpbmRvd0NvbnN0YW50cy5ESVNQT1NFX09OX0NMT1NFKTsKKworCS8vIGRlZmF1bHQgc2l6ZSBvZiB0aGUgZnJhbWUKKwlzZXRTaXplKDcwMCw2MDApOworCisJLy8gd2Ugd2FudCB0byBkaXNwbGF5IGp1c3QgdGhlIGNvbXBvbmVudCBpbiB0aGUgZW50aXJlIGZyYW1lCisJaWYgKHdoYXQgIT0gbnVsbCkgeworCSAgICBnZXRDb250ZW50UGFuZSgpLmFkZCgiQ2VudGVyIiwgd2hhdCk7CisJfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2NsaWVudC9zcmMvbWFpbi9qYXZhL0ZvbGRlck1vZGVsLmphdmEgYi9jbGllbnQvc3JjL21haW4vamF2YS9Gb2xkZXJNb2RlbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU3YTJlYzMKLS0tIC9kZXYvbnVsbAorKysgYi9jbGllbnQvc3JjL21haW4vamF2YS9Gb2xkZXJNb2RlbC5qYXZhCkBAIC0wLDAgKzEsMTM5IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBEaXN0cmlidXRpb24gTGljZW5zZSB2LiAxLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9vcmcvZG9jdW1lbnRzL2VkbC12MTAucGhwLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBCU0QtMy1DbGF1c2UKKyAqLworCitpbXBvcnQgamF2YXgubWFpbC4qOworaW1wb3J0IGphdmEudXRpbC5EYXRlOworaW1wb3J0IGphdmF4LnN3aW5nLnRhYmxlLkFic3RyYWN0VGFibGVNb2RlbDsgCisKKy8qKgorICogTWFwcyB0aGUgbWVzc2FnZXMgaW4gYSBGb2xkZXIgdG8gdGhlIFN3aW5nJ3MgVGFibGUgTW9kZWwKKyAqCisgKiBAYXV0aG9yCUNocmlzdG9waGVyIENvdHRvbgorICogQGF1dGhvcglCaWxsIFNoYW5ub24KKyAqLworCitwdWJsaWMgY2xhc3MgRm9sZGVyTW9kZWwgZXh0ZW5kcyBBYnN0cmFjdFRhYmxlTW9kZWwgeworICAgIAorICAgIEZvbGRlcglmb2xkZXI7CisgICAgTWVzc2FnZVtdCW1lc3NhZ2VzOworCisgICAgU3RyaW5nW10JY29sdW1uTmFtZXMgPSB7ICJEYXRlIiwgIkZyb20iLCAiU3ViamVjdCJ9OyAKKyAgICBDbGFzc1tdCWNvbHVtblR5cGVzID0geyBTdHJpbmcuY2xhc3MsIFN0cmluZy5jbGFzcywgU3RyaW5nLmNsYXNzIH07IAorCisgICAgcHVibGljIHZvaWQgc2V0Rm9sZGVyKEZvbGRlciB3aGF0KSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpZiAod2hhdCAhPSBudWxsKSB7CisKKwkgICAgLy8gb3BlbmVkIGlmIG5lZWRlZAorCSAgICBpZiAoIXdoYXQuaXNPcGVuKCkpIHsKKwkJd2hhdC5vcGVuKEZvbGRlci5SRUFEX1dSSVRFKTsKKwkgICAgfQorICAgIAorCSAgICAvLyBnZXQgdGhlIG1lc3NhZ2VzCisJICAgIG1lc3NhZ2VzID0gd2hhdC5nZXRNZXNzYWdlcygpOworCSAgICBjYWNoZWQgPSBuZXcgU3RyaW5nW21lc3NhZ2VzLmxlbmd0aF1bXTsKKwl9IGVsc2UgeworCSAgICBtZXNzYWdlcyA9IG51bGw7CisJICAgIGNhY2hlZCA9IG51bGw7CisJfQorCS8vIGNsb3NlIHByZXZpb3VzIGZvbGRlciBhbmQgc3dpdGNoIHRvIG5ldyBmb2xkZXIKKwlpZiAoZm9sZGVyICE9IG51bGwpCisJICAgIGZvbGRlci5jbG9zZSh0cnVlKTsKKwlmb2xkZXIgPSB3aGF0OworCWZpcmVUYWJsZURhdGFDaGFuZ2VkKCk7CisgICAgfQorICAgIAorICAgIHB1YmxpYyBNZXNzYWdlIGdldE1lc3NhZ2UoaW50IHdoaWNoKSB7CisJcmV0dXJuIG1lc3NhZ2VzW3doaWNoXTsKKyAgICB9CisKKyAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgIC8vIEltcGxlbWVudGF0aW9uIG9mIHRoZSBUYWJsZU1vZGVsIG1ldGhvZHMKKyAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgICAgcHVibGljIFN0cmluZyBnZXRDb2x1bW5OYW1lKGludCBjb2x1bW4pIHsKKwlyZXR1cm4gY29sdW1uTmFtZXNbY29sdW1uXTsKKyAgICB9CisgICAgCisgICAgcHVibGljIENsYXNzIGdldENvbHVtbkNsYXNzKGludCBjb2x1bW4pIHsKKwlyZXR1cm4gY29sdW1uVHlwZXNbY29sdW1uXTsKKyAgICB9CisgICAgCisKKyAgICBwdWJsaWMgaW50IGdldENvbHVtbkNvdW50KCkgeworCXJldHVybiBjb2x1bW5OYW1lcy5sZW5ndGg7IAorICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0Um93Q291bnQoKSB7CisJaWYgKG1lc3NhZ2VzID09IG51bGwpCisJICAgIHJldHVybiAwOworCQorCXJldHVybiBtZXNzYWdlcy5sZW5ndGg7CisgICAgfQorIAorICAgIHB1YmxpYyBPYmplY3QgZ2V0VmFsdWVBdChpbnQgYVJvdywgaW50IGFDb2x1bW4pIHsKKwlzd2l0Y2goYUNvbHVtbikgeworCWNhc2UgMDoJLy8gZGF0ZQorCWNhc2UgMTogLy8gRnJvbQkJU3RyaW5nW10gd2hhdCA9IGdldENhY2hlZERhdGEoYVJvdyk7CisJY2FzZSAyOiAvLyBTdWJqZWN0CisJICAgIFN0cmluZ1tdIHdoYXQgPSBnZXRDYWNoZWREYXRhKGFSb3cpOworCSAgICBpZiAod2hhdCAhPSBudWxsKSB7CisJCXJldHVybiB3aGF0W2FDb2x1bW5dOworCSAgICB9IGVsc2UgeworCQlyZXR1cm4gIiI7CisJICAgIH0KKwkgICAgCisJZGVmYXVsdDoKKwkgICAgcmV0dXJuICIiOworCX0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgc3RhdGljIFN0cmluZ1tdW10JY2FjaGVkOworICAgIAorICAgIHByb3RlY3RlZCBTdHJpbmdbXSBnZXRDYWNoZWREYXRhKGludCByb3cpIHsKKwlpZiAoY2FjaGVkW3Jvd10gPT0gbnVsbCkgeworCSAgICB0cnl7CisJCU1lc3NhZ2UgbSA9IG1lc3NhZ2VzW3Jvd107CisJICAgIAorCQlTdHJpbmdbXSB0aGVEYXRhID0gbmV3IFN0cmluZ1s0XTsKKwkgICAgCisJCS8vIERhdGUKKwkJRGF0ZSBkYXRlID0gbS5nZXRTZW50RGF0ZSgpOworCQlpZiAoZGF0ZSA9PSBudWxsKSB7CisJCSAgICB0aGVEYXRhWzBdID0gIlVua25vd24iOworCQl9IGVsc2UgeworCQkgICAgdGhlRGF0YVswXSA9IGRhdGUudG9TdHJpbmcoKTsKKwkJfQorCSAgICAKKwkJLy8gRnJvbQorCQlBZGRyZXNzW10gYWRkcyA9IG0uZ2V0RnJvbSgpOworCQlpZiAoYWRkcyAhPSBudWxsICYmIGFkZHMubGVuZ3RoICE9IDApIHsKKwkJICAgIHRoZURhdGFbMV0gPSBhZGRzWzBdLnRvU3RyaW5nKCk7CSAgICAKKwkJfSBlbHNlIHsKKwkJICAgIHRoZURhdGFbMV0gPSAiIjsKKwkJfQorCQkKKwkJLy8gU3ViamVjdAorCQlTdHJpbmcgc3ViamVjdCA9IG0uZ2V0U3ViamVjdCgpOworCQlpZiAoc3ViamVjdCAhPSBudWxsKSB7CisJCSAgICB0aGVEYXRhWzJdID0gc3ViamVjdDsKKwkJfSBlbHNlIHsKKwkJICAgIHRoZURhdGFbMl0gPSAiKE5vIFN1YmplY3QpIjsKKwkJfQorCisJCWNhY2hlZFtyb3ddID0gdGhlRGF0YTsKKwkgICAgfQorCSAgICBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIGUpIHsKKwkJZS5wcmludFN0YWNrVHJhY2UoKTsKKwkgICAgfQorCX0KKwkKKwlyZXR1cm4gY2FjaGVkW3Jvd107CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvY2xpZW50L3NyYy9tYWluL2phdmEvRm9sZGVyVHJlZU5vZGUuamF2YSBiL2NsaWVudC9zcmMvbWFpbi9qYXZhL0ZvbGRlclRyZWVOb2RlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2U2YjkyNQotLS0gL2Rldi9udWxsCisrKyBiL2NsaWVudC9zcmMvbWFpbi9qYXZhL0ZvbGRlclRyZWVOb2RlLmphdmEKQEAgLTAsMCArMSwxMDggQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorICovCisKK2ltcG9ydCBqYXZheC5zd2luZy50cmVlLkRlZmF1bHRNdXRhYmxlVHJlZU5vZGU7CitpbXBvcnQgamF2YXgubWFpbC5TdG9yZTsKK2ltcG9ydCBqYXZheC5tYWlsLkZvbGRlcjsKK2ltcG9ydCBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworLyoqCisgKiBOb2RlIHdoaWNoIHJlcHJlc2VudHMgYSBGb2xkZXIgaW4gdGhlIGphdmF4Lm1haWwgYXBpcy4gCisgKgorICogQGF1dGhvciBDaHJpc3RvcGhlciBDb3R0b24KKyAqLworcHVibGljIGNsYXNzIEZvbGRlclRyZWVOb2RlIGV4dGVuZHMgRGVmYXVsdE11dGFibGVUcmVlTm9kZSB7CisgICAgCisgICAgcHJvdGVjdGVkIEZvbGRlcglmb2xkZXIgPSBudWxsOworICAgIHByb3RlY3RlZCBib29sZWFuCWhhc0xvYWRlZCA9IGZhbHNlOworCisgICAgLyoqCisgICAgICogY3JlYXRlcyBhIHRyZWUgbm9kZSB0aGF0IHBvaW50cyB0byB0aGUgcGFydGljdWxhciBTdG9yZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB3aGF0CXRoZSBzdG9yZSBmb3IgdGhpcyBub2RlCisgICAgICovCisgICAgcHVibGljIEZvbGRlclRyZWVOb2RlKEZvbGRlciB3aGF0KSB7CisJc3VwZXIod2hhdCk7CisJZm9sZGVyID0gd2hhdDsKKyAgICB9CisKKyAgICAKKyAgICAvKioKKyAgICAgKiBhIEZvbGRlciBpcyBhIGxlYWYgaWYgaXQgY2Fubm90IGNvbnRhaW4gc3ViIGZvbGRlcnMKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0xlYWYoKSB7CisJdHJ5IHsKKwkgICAgaWYgKChmb2xkZXIuZ2V0VHlwZSgpICYgRm9sZGVyLkhPTERTX0ZPTERFUlMpID09IDApCisJCXJldHVybiB0cnVlOworCX0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBtZSkgeyB9CisJCisJLy8gb3RoZXJ3aXNlIGl0IGRvZXMgaG9sZCBmb2xkZXJzLCBhbmQgdGhlcmVmb3JlIG5vdAorCS8vIGEgbGVhZgorCXJldHVybiBmYWxzZTsKKyAgICB9CisgICAKKyAgICAvKioKKyAgICAgKiByZXR1cm5zIHRoZSBmb2xkZXIgZm9yIHRoaXMgbm9kZQorICAgICAqLworICAgIHB1YmxpYyBGb2xkZXIgZ2V0Rm9sZGVyKCkgeworCXJldHVybiBmb2xkZXI7CisgICAgfQorICAgIAorCisKKyAgICAvKioKKyAgICAgKiByZXR1cm4gdGhlIG51bWJlciBvZiBjaGlsZHJlbiBmb3IgdGhpcyBmb2xkZXIgbm9kZS4gVGhlIGZpcnN0CisgICAgICogdGltZSB0aGlzIG1ldGhvZCBpcyBjYWxsZWQgd2UgbG9hZCB1cCBhbGwgb2YgdGhlIGZvbGRlcnMKKyAgICAgKiB1bmRlciB0aGUgc3RvcmUncyBkZWZhdWx0Rm9sZGVyCisgICAgICovCisKKyAgICBwdWJsaWMgaW50IGdldENoaWxkQ291bnQoKSB7CisJaWYgKCFoYXNMb2FkZWQpIHsKKwkgICAgbG9hZENoaWxkcmVuKCk7CisJfQorCXJldHVybiBzdXBlci5nZXRDaGlsZENvdW50KCk7CisgICAgfQorICAgIAorICAgIHByb3RlY3RlZCB2b2lkIGxvYWRDaGlsZHJlbigpIHsKKwkvLyBpZiBpdCBpcyBhIGxlYWYsIGp1c3Qgc2F5IHdlIGhhdmUgbG9hZGVkIHRoZW0KKwlpZiAoaXNMZWFmKCkpIHsKKwkgICAgaGFzTG9hZGVkID0gdHJ1ZTsKKwkgICAgcmV0dXJuOworCX0KKworCXRyeSB7CisJICAgIC8vIEZvbGRlcltdIHN1YiA9IGZvbGRlci5saXN0U3Vic2NyaWJlZCgpOworCSAgICBGb2xkZXJbXSBzdWIgPSBmb2xkZXIubGlzdCgpOworCisJICAgIC8vIGFkZCBhIEZvbGRlclRyZWVOb2RlIGZvciBlYWNoIEZvbGRlcgorCSAgICBpbnQgbnVtID0gc3ViLmxlbmd0aDsKKwkgICAgZm9yKGludCBpID0gMDsgaSA8IG51bTsgaSsrKSB7CisJCUZvbGRlclRyZWVOb2RlIG5vZGUgPSBuZXcgRm9sZGVyVHJlZU5vZGUoc3ViW2ldKTsKKwkJLy8gd2UgdXNlZCBpbnNlcnQgaGVyZSwgc2luY2UgYWRkKCkgd291bGQgbWFrZQorCQkvLyBhbm90aGVyIHJlY3Vyc2l2ZSBjYWxsIHRvIGdldENoaWxkQ291bnQoKTsKKwkJaW5zZXJ0KG5vZGUsIGkpOworCSAgICB9CisJICAgIAorCX0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBtZSkgeworCSAgICBtZS5wcmludFN0YWNrVHJhY2UoKTsKKwl9CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBvdmVycmlkZSB0b1N0cmluZygpIHNpbmNlIHdlIG9ubHkgd2FudCB0byBkaXNwbGF5IGEgZm9sZGVyJ3MKKyAgICAgKiBuYW1lLCBhbmQgbm90IHRoZSBmdWxsIHBhdGggb2YgdGhlIGZvbGRlcgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisJcmV0dXJuIGZvbGRlci5nZXROYW1lKCk7CisgICAgfQorICAgIAorfQorCmRpZmYgLS1naXQgYS9jbGllbnQvc3JjL21haW4vamF2YS9Gb2xkZXJWaWV3ZXIuamF2YSBiL2NsaWVudC9zcmMvbWFpbi9qYXZhL0ZvbGRlclZpZXdlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM3NjJhMjYKLS0tIC9kZXYvbnVsbAorKysgYi9jbGllbnQvc3JjL21haW4vamF2YS9Gb2xkZXJWaWV3ZXIuamF2YQpAQCAtMCwwICsxLDgyIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBEaXN0cmlidXRpb24gTGljZW5zZSB2LiAxLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9vcmcvZG9jdW1lbnRzL2VkbC12MTAucGhwLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBCU0QtMy1DbGF1c2UKKyAqLworCitpbXBvcnQgamF2YS5hd3QuKjsKK2ltcG9ydCBqYXZheC5tYWlsLio7CitpbXBvcnQgamF2YXguc3dpbmcuKjsKK2ltcG9ydCBqYXZheC5zd2luZy5ldmVudC4qOworaW1wb3J0IGphdmF4LnN3aW5nLnRhYmxlLio7CisKKy8qKgorICogQGF1dGhvcglDaHJpc3RvcGhlciBDb3R0b24KKyAqIEBhdXRob3IJQmlsbCBTaGFubm9uCisgKi8KKworcHVibGljIGNsYXNzIEZvbGRlclZpZXdlciBleHRlbmRzIEpQYW5lbCB7CisKKyAgICBGb2xkZXJNb2RlbCBtb2RlbCA9IG5ldyBGb2xkZXJNb2RlbCgpOworICAgIEpTY3JvbGxQYW5lIHNjcm9sbHBhbmU7CisgICAgSlRhYmxlIHRhYmxlOworCisgICAgcHVibGljIEZvbGRlclZpZXdlcigpIHsKKwl0aGlzKG51bGwpOworICAgIH0KKworICAgIHB1YmxpYyBGb2xkZXJWaWV3ZXIoRm9sZGVyIHdoYXQpIHsKKwlzdXBlcihuZXcgR3JpZExheW91dCgxLDEpKTsKKworCXRhYmxlID0gbmV3IEpUYWJsZShtb2RlbCk7CisJdGFibGUuc2V0U2hvd0dyaWQoZmFsc2UpOworCisJc2Nyb2xscGFuZSA9IG5ldyBKU2Nyb2xsUGFuZSh0YWJsZSk7CisKKwkvLyBzZXR1cCB0aGUgZm9sZGVyIHdlIHdlcmUgZ2l2ZW4KKwlzZXRGb2xkZXIod2hhdCk7CisJCisJLy8gZmluZCBvdXQgd2hhdCBpcyBwcmVzc2VkCisJdGFibGUuZ2V0U2VsZWN0aW9uTW9kZWwoKS5hZGRMaXN0U2VsZWN0aW9uTGlzdGVuZXIoCisJICAgIG5ldyBGb2xkZXJQcmVzc2VkKCkpOworCXNjcm9sbHBhbmUuc2V0UHJlZmVycmVkU2l6ZShuZXcgRGltZW5zaW9uKDcwMCwgMzAwKSk7CisJYWRkKHNjcm9sbHBhbmUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoYW5nZSB0aGUgY3VycmVudCBGb2xkZXIgZm9yIHRoZSBWaWV3ZXIKKyAgICAgKgorICAgICAqIEBwYXJhbSB3aGF0CXRoZSBmb2xkZXIgdG8gYmUgdmlld2VkCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Rm9sZGVyKEZvbGRlciB3aGF0KSB7CisJdHJ5IHsKKwkgICAgdGFibGUuZ2V0U2VsZWN0aW9uTW9kZWwoKS5jbGVhclNlbGVjdGlvbigpOworCSAgICBpZiAoU2ltcGxlQ2xpZW50Lm12ICE9IG51bGwpCisJCVNpbXBsZUNsaWVudC5tdi5zZXRNZXNzYWdlKG51bGwpOworCSAgICBtb2RlbC5zZXRGb2xkZXIod2hhdCk7CisJICAgIHNjcm9sbHBhbmUuaW52YWxpZGF0ZSgpOworCSAgICBzY3JvbGxwYW5lLnZhbGlkYXRlKCk7CisJfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIG1lKSB7CisJICAgIG1lLnByaW50U3RhY2tUcmFjZSgpOworCX0KKyAgICB9CisKKyAgICBjbGFzcyBGb2xkZXJQcmVzc2VkIGltcGxlbWVudHMgTGlzdFNlbGVjdGlvbkxpc3RlbmVyIHsKKworCXB1YmxpYyB2b2lkIHZhbHVlQ2hhbmdlZChMaXN0U2VsZWN0aW9uRXZlbnQgZSkgeworCSAgICBpZiAobW9kZWwgIT0gbnVsbCAmJiAhZS5nZXRWYWx1ZUlzQWRqdXN0aW5nKCkpIHsKKwkJTGlzdFNlbGVjdGlvbk1vZGVsIGxtID0gKExpc3RTZWxlY3Rpb25Nb2RlbCkgZS5nZXRTb3VyY2UoKTsKKwkJaW50IHdoaWNoID0gbG0uZ2V0TWF4U2VsZWN0aW9uSW5kZXgoKTsKKwkJaWYgKHdoaWNoICE9IC0xKSB7CisJCSAgICAvLyBnZXQgdGhlIG1lc3NhZ2UgYW5kIGRpc3BsYXkgaXQKKwkJICAgIE1lc3NhZ2UgbXNnID0gbW9kZWwuZ2V0TWVzc2FnZSh3aGljaCk7CisJCSAgICBTaW1wbGVDbGllbnQubXYuc2V0TWVzc2FnZShtc2cpOworCQl9CisJICAgIH0KKwl9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvY2xpZW50L3NyYy9tYWluL2phdmEvTWVzc2FnZVZpZXdlci5qYXZhIGIvY2xpZW50L3NyYy9tYWluL2phdmEvTWVzc2FnZVZpZXdlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdiNjQ3NGYKLS0tIC9kZXYvbnVsbAorKysgYi9jbGllbnQvc3JjL21haW4vamF2YS9NZXNzYWdlVmlld2VyLmphdmEKQEAgLTAsMCArMSwyMzQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorICovCisKK2ltcG9ydCBqYXZhLmF3dC4qOworaW1wb3J0IGphdmEuYXd0LmV2ZW50Lio7CitpbXBvcnQgamF2YXgubWFpbC4qOworaW1wb3J0IGphdmF4LmFjdGl2YXRpb24uKjsKK2ltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmF4LnN3aW5nLkpQYW5lbDsKKworLyoqCisgKiBAYXV0aG9yCUNocmlzdG9waGVyIENvdHRvbgorICogQGF1dGhvcglCaWxsIFNoYW5ub24KKyAqLworCitwdWJsaWMgY2xhc3MgTWVzc2FnZVZpZXdlciBleHRlbmRzIEpQYW5lbCBpbXBsZW1lbnRzIENvbW1hbmRPYmplY3QgeworICAgIAorICAgIE1lc3NhZ2UJZGlzcGxheWVkID0gbnVsbDsKKyAgICBEYXRhSGFuZGxlcglkYXRhSGFuZGxlciA9IG51bGw7CisgICAgU3RyaW5nCXZlcmIgPSBudWxsOworICAgIENvbXBvbmVudAltYWluYm9keTsKKyAgICBUZXh0QXJlYQloZWFkZXJzOworCisgICAgcHVibGljIE1lc3NhZ2VWaWV3ZXIoKSB7CisJdGhpcyhudWxsKTsKKyAgICB9CisgICAgCisgICAgcHVibGljIE1lc3NhZ2VWaWV3ZXIoTWVzc2FnZSB3aGF0KSB7CisJLy8gc2V0IG91ciBsYXlvdXQKKwlzdXBlcihuZXcgR3JpZEJhZ0xheW91dCgpKTsKKworCS8vIGFkZCB0aGUgdG9vbGJhcgorCWFkZFRvb2xiYXIoKTsKKworCUdyaWRCYWdDb25zdHJhaW50cyBnYiA9IG5ldyBHcmlkQmFnQ29uc3RyYWludHMoKTsKKwlnYi5ncmlkd2lkdGggPSBHcmlkQmFnQ29uc3RyYWludHMuUkVNQUlOREVSOworCWdiLmZpbGwgPSBHcmlkQmFnQ29uc3RyYWludHMuQk9USDsKKwlnYi53ZWlnaHR4ID0gMS4wOworCWdiLndlaWdodHkgPSAwLjA7CisKKwkvLyBhZGQgdGhlIGhlYWRlcnMKKwloZWFkZXJzID0gbmV3IFRleHRBcmVhKCIiLCA0LCA4MCwgVGV4dEFyZWEuU0NST0xMQkFSU19OT05FKTsKKwloZWFkZXJzLnNldEVkaXRhYmxlKGZhbHNlKTsKKwlhZGQoaGVhZGVycywgZ2IpOworCisJLy8gbm93IGRpc3BsYXkgb3VyIG1lc3NhZ2UKKwlzZXRNZXNzYWdlKHdoYXQpOworICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiBzZXRzIHRoZSBjdXJyZW50IG1lc3NhZ2UgdG8gYmUgZGlzcGxheWVkIGluIHRoZSB2aWV3ZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRNZXNzYWdlKE1lc3NhZ2Ugd2hhdCkgeworCWRpc3BsYXllZCA9IHdoYXQ7CisKKwlpZiAobWFpbmJvZHkgIT0gbnVsbCkKKwkgICAgcmVtb3ZlKG1haW5ib2R5KTsKKworCWlmICh3aGF0ICE9IG51bGwpIHsKKwkgICAgbG9hZEhlYWRlcnMoKTsKKwkgICAgbWFpbmJvZHkgPSBnZXRCb2R5Q29tcG9uZW50KCk7CisJfSBlbHNlIHsKKwkgICAgaGVhZGVycy5zZXRUZXh0KCIiKTsKKwkgICAgVGV4dEFyZWEgZHVtbXkgPSBuZXcgVGV4dEFyZWEoIiIsIDI0LCA4MCwgVGV4dEFyZWEuU0NST0xMQkFSU19OT05FKTsKKwkgICAgZHVtbXkuc2V0RWRpdGFibGUoZmFsc2UpOworCSAgICBtYWluYm9keSA9IGR1bW15OworCX0KKworCS8vIGFkZCB0aGUgbWFpbiBib2R5CisJR3JpZEJhZ0NvbnN0cmFpbnRzIGdiID0gbmV3IEdyaWRCYWdDb25zdHJhaW50cygpOworCWdiLmdyaWR3aWR0aCA9IEdyaWRCYWdDb25zdHJhaW50cy5SRU1BSU5ERVI7CisJZ2IuZmlsbCA9IEdyaWRCYWdDb25zdHJhaW50cy5CT1RIOworCWdiLndlaWdodHggPSAxLjA7CisJZ2Iud2VpZ2h0eSA9IDEuMDsKKwlhZGQobWFpbmJvZHksIGdiKTsKKworCWludmFsaWRhdGUoKTsKKwl2YWxpZGF0ZSgpOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIGFkZFRvb2xiYXIoKSB7CisJR3JpZEJhZ0NvbnN0cmFpbnRzIGdiID0gbmV3IEdyaWRCYWdDb25zdHJhaW50cygpOworCWdiLmdyaWRoZWlnaHQgPSAxOworCWdiLmdyaWR3aWR0aCA9IDE7CisJZ2IuZmlsbCA9IEdyaWRCYWdDb25zdHJhaW50cy5OT05FOworCWdiLmFuY2hvciA9IEdyaWRCYWdDb25zdHJhaW50cy5XRVNUOworCWdiLndlaWdodHggPSAwLjA7CisJZ2Iud2VpZ2h0eSA9IDAuMDsKKwlnYi5pbnNldHMgPSBuZXcgSW5zZXRzKDQsNCw0LDQpOworCisJLy8gc3RydWN0dXJlIGJ1dHRvbgorCWdiLmdyaWR3aWR0aCA9IEdyaWRCYWdDb25zdHJhaW50cy5SRU1BSU5ERVI7IC8vIG9ubHkgZm9yIHRoZSBsYXN0IG9uZQorCUJ1dHRvbiBiID0gbmV3IEJ1dHRvbigiU3RydWN0dXJlIik7CisJYi5hZGRBY3Rpb25MaXN0ZW5lciggbmV3IFN0cnVjdHVyZUFjdGlvbigpKTsKKwlhZGQoYiwgZ2IpOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIGxvYWRIZWFkZXJzKCkgeworCS8vIHNldHVwIHdoYXQgd2Ugd2FudCBpbiBvdXIgdmlld2VyCisJU3RyaW5nQnVmZmVyIHNiID0gbmV3IFN0cmluZ0J1ZmZlcigpOworCisJLy8gZGF0ZQorCXNiLmFwcGVuZCgiRGF0ZTogIik7CisJdHJ5IHsKKwkgICAgRGF0ZSBkdWggPSBkaXNwbGF5ZWQuZ2V0U2VudERhdGUoKTsKKwkgICAgaWYgKGR1aCAhPSBudWxsKSB7CisJCXNiLmFwcGVuZChkdWgudG9TdHJpbmcoKSk7CisJICAgIH0gZWxzZSB7CisJCXNiLmFwcGVuZCgiVW5rbm93biIpOworCSAgICB9CisJICAgIAorCSAgICBzYi5hcHBlbmQoIlxuIik7CisKKwkgICAgLy8gZnJvbQorCSAgICBzYi5hcHBlbmQoIkZyb206ICIpOworCSAgICBBZGRyZXNzW10gYWRkcyA9IGRpc3BsYXllZC5nZXRGcm9tKCk7CisJICAgIGlmIChhZGRzICE9IG51bGwgJiYgYWRkcy5sZW5ndGggPiAwKSB7CisJCXNiLmFwcGVuZChhZGRzWzBdLnRvU3RyaW5nKCkpOworCSAgICB9CisJICAgIHNiLmFwcGVuZCgiXG4iKTsKKworCSAgICAvLyB0bworCSAgICBzYi5hcHBlbmQoIlRvOiAiKTsKKwkgICAgYWRkcyA9IGRpc3BsYXllZC5nZXRSZWNpcGllbnRzKE1lc3NhZ2UuUmVjaXBpZW50VHlwZS5UTyk7CisJICAgIGlmIChhZGRzICE9IG51bGwgJiYgYWRkcy5sZW5ndGggPiAwKSB7CisJCXNiLmFwcGVuZChhZGRzWzBdLnRvU3RyaW5nKCkpOworCSAgICB9CisJICAgIHNiLmFwcGVuZCgiXG4iKTsKKworCSAgICAvLyBzdWJqZWN0CisJICAgIHNiLmFwcGVuZCgiU3ViamVjdDogIik7CisJICAgIHNiLmFwcGVuZChkaXNwbGF5ZWQuZ2V0U3ViamVjdCgpKTsKKwkgICAgCisJICAgIGhlYWRlcnMuc2V0VGV4dChzYi50b1N0cmluZygpKTsKKwl9IGNhdGNoIChNZXNzYWdpbmdFeGNlcHRpb24gbWUpIHsKKwkgICAgaGVhZGVycy5zZXRUZXh0KCIiKTsKKwl9CisgICAgfQorCisgICAgcHJvdGVjdGVkIENvbXBvbmVudCBnZXRCb2R5Q29tcG9uZW50KCkgeworCS8vLS0tLS0tLS0tLS0tCisJLy8gbm93IGdldCBhIGNvbnRlbnQgdmlld2VyIGZvciB0aGUgbWFpbiB0eXBlLi4uCisJLy8tLS0tLS0tLS0tLS0KKwl0cnkgeworCSAgICBEYXRhSGFuZGxlciBkaCA9IGRpc3BsYXllZC5nZXREYXRhSGFuZGxlcigpOworCSAgICBDb21tYW5kSW5mbyBjaSA9IGRoLmdldENvbW1hbmQoInZpZXciKTsKKwkgICAgaWYgKGNpID09IG51bGwpIHsKKwkJdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigidmlldyBjb21tYW5kIGZhaWxlZCBvbjogIiArCisJCQkJCSAgICAgZGlzcGxheWVkLmdldENvbnRlbnRUeXBlKCkpOworCSAgICB9CisKKwkgICAgT2JqZWN0IGJlYW4gPSBkaC5nZXRCZWFuKGNpKTsKKwkgICAgaWYgKGJlYW4gaW5zdGFuY2VvZiBDb21wb25lbnQpIHsKKwkJcmV0dXJuIChDb21wb25lbnQpYmVhbjsKKwkgICAgfSBlbHNlIHsKKwkJdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiYmVhbiBpcyBub3QgYSBjb21wb25lbnQgIiArCisJCQkJCSAgICAgYmVhbi5nZXRDbGFzcygpLnRvU3RyaW5nKCkpOworCSAgICB9CisJfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIG1lKSB7CisJICAgIHJldHVybiBuZXcgTGFiZWwobWUudG9TdHJpbmcoKSk7CisJfQorICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiB0aGUgQ29tbWFuZE9iamVjdCBtZXRob2QgdG8gYWNjZXB0IG91ciBEYXRhSGFuZGxlcgorICAgICAqIEBwYXJhbSBkaAl0aGUgZGF0YWhhbmRsZXIgdXNlZCB0byBnZXQgdGhlIGNvbnRlbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDb21tYW5kQ29udGV4dChTdHJpbmcgdmVyYiwKKwkJCQkgIERhdGFIYW5kbGVyIGRoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCXRoaXMudmVyYiA9IHZlcmI7CisJZGF0YUhhbmRsZXIgPSBkaDsKKworCU9iamVjdCBvID0gZGguZ2V0Q29udGVudCgpOworCWlmIChvIGluc3RhbmNlb2YgTWVzc2FnZSkgeworCSAgICBzZXRNZXNzYWdlKChNZXNzYWdlKW8pOworCX0KKwllbHNlIHsKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCAKKwkJIk1lc3NhZ2VWaWV3ZXIgLSBjb250ZW50IG5vdCBhIE1lc3NhZ2Ugb2JqZWN0LCAiICsgbyk7CisJICAgIGlmIChvICE9IG51bGwpeworCQlTeXN0ZW0ub3V0LnByaW50bG4oby5nZXRDbGFzcygpLnRvU3RyaW5nKCkpOworCSAgICB9CisJfQorICAgIH0KKworCisgICAgY2xhc3MgU3RydWN0dXJlQWN0aW9uIGltcGxlbWVudHMgQWN0aW9uTGlzdGVuZXIgeworCVN0cmluZ0J1ZmZlciBzYjsKKworCXB1YmxpYyB2b2lkIGFjdGlvblBlcmZvcm1lZChBY3Rpb25FdmVudCBlKSB7CisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXG5cbk1lc3NhZ2UgU3RydWN0dXJlIik7CisJICAgIGR1bXBQYXJ0KCIiLCBkaXNwbGF5ZWQpOworCX0KKworCXByb3RlY3RlZCB2b2lkIGR1bXBQYXJ0KFN0cmluZyBwcmVmaXgsIFBhcnQgcCkgeworCSAgICB0cnkgeworCQlTeXN0ZW0ub3V0LnByaW50bG4ocHJlZml4ICsgIi0tLS0tLS0tLS0tLS0tLS0iKTsKKwkJU3lzdGVtLm91dC5wcmludGxuKHByZWZpeCArIAorCQkJCSAgICJDb250ZW50LVR5cGU6ICIgKyBwLmdldENvbnRlbnRUeXBlKCkpOworCQlTeXN0ZW0ub3V0LnByaW50bG4ocHJlZml4ICsgCisJCQkJICAgIkNsYXNzOiAiICsgcC5nZXRDbGFzcygpLnRvU3RyaW5nKCkpOworCQkJICAgIAorCQlPYmplY3QgbyA9IHAuZ2V0Q29udGVudCgpOworCQlpZiAobyA9PSBudWxsKSB7CisJCSAgICBTeXN0ZW0ub3V0LnByaW50bG4ocHJlZml4ICsgIkNvbnRlbnQ6ICBpcyBudWxsIik7CisJCX0gZWxzZSB7CisJCSAgICBTeXN0ZW0ub3V0LnByaW50bG4ocHJlZml4ICsKKwkJCQkgICAgICAgIkNvbnRlbnQ6ICIgKyBvLmdldENsYXNzKCkudG9TdHJpbmcoKSk7CisJCX0KKworCQlpZiAobyBpbnN0YW5jZW9mIE11bHRpcGFydCkgeworCQkgICAgU3RyaW5nIG5ld3ByZWYgPSBwcmVmaXggKyAiXHQiOworCQkgICAgTXVsdGlwYXJ0IG1wID0gKE11bHRpcGFydClvOworCQkgICAgaW50IGNvdW50ID0gbXAuZ2V0Q291bnQoKTsKKwkJICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgeworCQkJZHVtcFBhcnQobmV3cHJlZiwgbXAuZ2V0Qm9keVBhcnQoaSkpOworCQkgICAgfQorCQl9CisJICAgIH0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBlKSB7CisJCWUucHJpbnRTdGFja1RyYWNlKCk7CisJICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZXgpIHsKKwkJU3lzdGVtLm91dC5wcmludGxuKCJDYW5ub3QgZ2V0IGNvbnRlbnQiICsgaW9leC5nZXRNZXNzYWdlKCkpOworCSAgICB9CisJfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2NsaWVudC9zcmMvbWFpbi9qYXZhL011bHRpcGFydFZpZXdlci5qYXZhIGIvY2xpZW50L3NyYy9tYWluL2phdmEvTXVsdGlwYXJ0Vmlld2VyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTkzYjhhOAotLS0gL2Rldi9udWxsCisrKyBiL2NsaWVudC9zcmMvbWFpbi9qYXZhL011bHRpcGFydFZpZXdlci5qYXZhCkBAIC0wLDAgKzEsMTY1IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBEaXN0cmlidXRpb24gTGljZW5zZSB2LiAxLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9vcmcvZG9jdW1lbnRzL2VkbC12MTAucGhwLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBCU0QtMy1DbGF1c2UKKyAqLworCitpbXBvcnQgamF2YS5hd3QuKjsKK2ltcG9ydCBqYXZhLmF3dC5ldmVudC4qOworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZhLmJlYW5zLio7CitpbXBvcnQgamF2YXguYWN0aXZhdGlvbi4qOworaW1wb3J0IGphdmF4Lm1haWwuKjsKK2ltcG9ydCBqYXZheC5zd2luZy5KUGFuZWw7CisKKworLyoqCisgKiBBIFZpZXdlciBCZWFuIGZvciB0aGUgdHlwZSBtdWx0aXBhcnQvbWl4ZWQKKyAqCisgKiBAYXV0aG9yCUNocmlzdG9waGVyIENvdHRvbgorICovCisKK3B1YmxpYyBjbGFzcyBNdWx0aXBhcnRWaWV3ZXIgZXh0ZW5kcyBKUGFuZWwgaW1wbGVtZW50cyBDb21tYW5kT2JqZWN0IHsKKyAgICAKKyAgICBwcm90ZWN0ZWQgRGF0YUhhbmRsZXIJZGggPSBudWxsOworICAgIHByb3RlY3RlZCBTdHJpbmcJCXZlcmIgPSBudWxsOworICAgIAorICAgIHB1YmxpYyBNdWx0aXBhcnRWaWV3ZXIoKSB7CisJc3VwZXIobmV3IEdyaWRCYWdMYXlvdXQoKSk7CisgICAgfQorCisgICAgCisgICAgcHVibGljIHZvaWQgc2V0Q29tbWFuZENvbnRleHQoU3RyaW5nIHZlcmIsIERhdGFIYW5kbGVyIGRoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCXRoaXMudmVyYiA9IHZlcmI7CisJdGhpcy5kaCA9IGRoOworCQorCS8vIGdldCB0aGUgY29udGVudCwgYW5kIGhvcGUgaXQgaXMgYSBNdWx0aXBhcnQgT2JqZWN0CisJT2JqZWN0IGNvbnRlbnQgPSBkaC5nZXRDb250ZW50KCk7CisJaWYgKGNvbnRlbnQgaW5zdGFuY2VvZiBNdWx0aXBhcnQpIHsKKwkgICAgc2V0dXBEaXNwbGF5KChNdWx0aXBhcnQpY29udGVudCk7CisJfSBlbHNlIHsKKwkgICAgc2V0dXBFcnJvckRpc3BsYXkoY29udGVudCk7CisJfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHNldHVwRGlzcGxheShNdWx0aXBhcnQgbXApIHsKKwkvLyB3ZSBkaXNwbGF5IHRoZSBmaXJzdCBib2R5IHBhcnQgaW4gYSBtYWluIGZyYW1lIG9uIHRoZSBsZWZ0LCBhbmQgdGhlbgorCS8vIG9uIHRoZSByaWdodCB3ZSBkaXNwbGF5IHRoZSByZXN0IG9mIHRoZSBwYXJ0cyBhcyBhdHRhY2htZW50cworCisJR3JpZEJhZ0NvbnN0cmFpbnRzIGdjID0gbmV3IEdyaWRCYWdDb25zdHJhaW50cygpOworCWdjLmdyaWRoZWlnaHQgPSBHcmlkQmFnQ29uc3RyYWludHMuUkVNQUlOREVSOworCWdjLmZpbGwgPSBHcmlkQmFnQ29uc3RyYWludHMuQk9USDsKKwlnYy53ZWlnaHR4ID0gMS4wOworCWdjLndlaWdodHkgPSAxLjA7CisKKwkvLyBnZXQgdGhlIGZpcnN0IHBhcnQKKwl0cnkgeworCSAgICBCb2R5UGFydCBicCA9IG1wLmdldEJvZHlQYXJ0KDApOworCSAgICBDb21wb25lbnQgY29tcCA9IGdldENvbXBvbmVudChicCk7CisJICAgIGFkZChjb21wLCBnYyk7CisJICAgIAorCX0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBtZSkgeworCSAgICBhZGQobmV3IExhYmVsKG1lLnRvU3RyaW5nKCkpLCBnYyk7CisJfQorCisJLy8gc2VlIGlmIHRoZXJlIGFyZSBtb3JlIHRoYW4gb25lIHBhcnRzCisJdHJ5IHsKKwkgICAgaW50IGNvdW50ID0gbXAuZ2V0Q291bnQoKTsKKworCSAgICAvLyBzZXR1cCBob3cgdG8gZGlzcGxheSB0aGVtCisJICAgIGdjLmdyaWR3aWR0aCA9IEdyaWRCYWdDb25zdHJhaW50cy5SRU1BSU5ERVI7CisJICAgIGdjLmdyaWRoZWlnaHQgPSAxOworCSAgICBnYy5maWxsID0gR3JpZEJhZ0NvbnN0cmFpbnRzLk5PTkU7CisJICAgIGdjLmFuY2hvciA9IEdyaWRCYWdDb25zdHJhaW50cy5OT1JUSDsKKwkgICAgZ2Mud2VpZ2h0eCA9IDAuMDsKKwkgICAgZ2Mud2VpZ2h0eSA9IDAuMDsKKwkgICAgZ2MuaW5zZXRzID0gbmV3IEluc2V0cyg0LDQsNCw0KTsKKworCSAgICAvLyBmb3IgZWFjaCBvbmUgd2UgY3JlYXRlIGEgYnV0dG9uIHdpdGggdGhlIGNvbnRlbnQgdHlwZQorCSAgICBmb3IoaW50IGkgPSAxOyBpIDwgY291bnQ7IGkrKykgeyAvLyB3ZSBza2lwIHRoZSBmaXJzdCBvbmUgCisJCUJvZHlQYXJ0IGN1cnIgPSBtcC5nZXRCb2R5UGFydChpKTsKKwkJU3RyaW5nIGxhYmVsID0gbnVsbDsKKwkJaWYgKGxhYmVsID09IG51bGwpIGxhYmVsID0gY3Vyci5nZXRGaWxlTmFtZSgpOworCQlpZiAobGFiZWwgPT0gbnVsbCkgbGFiZWwgPSBjdXJyLmdldERlc2NyaXB0aW9uKCk7CisJCWlmIChsYWJlbCA9PSBudWxsKSBsYWJlbCA9IGN1cnIuZ2V0Q29udGVudFR5cGUoKTsKKworCQlCdXR0b24gYnV0ID0gbmV3IEJ1dHRvbihsYWJlbCk7CisJCWJ1dC5hZGRBY3Rpb25MaXN0ZW5lciggbmV3IEF0dGFjaG1lbnRWaWV3ZXIoY3VycikpOworCQlhZGQoYnV0LCBnYyk7CisJICAgIH0KKwkgICAgCisJICAgIAorCX0gY2F0Y2goTWVzc2FnaW5nRXhjZXB0aW9uIG1lMikgeworCSAgICBtZTIucHJpbnRTdGFja1RyYWNlKCk7CisJfQorCisgICAgfQorCisgICAgcHJvdGVjdGVkIENvbXBvbmVudCBnZXRDb21wb25lbnQoQm9keVBhcnQgYnApIHsKKworCXRyeSB7CisJICAgIERhdGFIYW5kbGVyIGRoID0gYnAuZ2V0RGF0YUhhbmRsZXIoKTsKKwkgICAgQ29tbWFuZEluZm8gY2kgPSBkaC5nZXRDb21tYW5kKCJ2aWV3Iik7CisJICAgIGlmIChjaSA9PSBudWxsKSB7CisJCXRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oCisJCSAgICAidmlldyBjb21tYW5kIGZhaWxlZCBvbjogIiArCisJCSAgICBicC5nZXRDb250ZW50VHlwZSgpKTsKKwkgICAgfQorCSAgICAKKwkgICAgT2JqZWN0IGJlYW4gPSBkaC5nZXRCZWFuKGNpKTsKKwkKKwkgICAgaWYgKGJlYW4gaW5zdGFuY2VvZiBDb21wb25lbnQpIHsKKwkJcmV0dXJuIChDb21wb25lbnQpYmVhbjsKKwkgICAgfSBlbHNlIHsKKwkJaWYgKGJlYW4gPT0gbnVsbCkKKwkJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oCisJCQkiYmVhbiBpcyBudWxsLCBjbGFzcyAiICsgY2kuZ2V0Q29tbWFuZENsYXNzKCkgKworCQkJIiAsIGNvbW1hbmQgIiArIGNpLmdldENvbW1hbmROYW1lKCkpOworCQllbHNlCisJCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKAorCQkJImJlYW4gaXMgbm90IGEgYXd0LkNvbXBvbmVudCIgKworCQkJYmVhbi5nZXRDbGFzcygpLnRvU3RyaW5nKCkpOworCSAgICB9CisJfQorCWNhdGNoIChNZXNzYWdpbmdFeGNlcHRpb24gbWUpIHsKKwkgICAgcmV0dXJuIG5ldyBMYWJlbChtZS50b1N0cmluZygpKTsKKwl9CisgICAgfQorICAgIAorCisgICAgCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0dXBFcnJvckRpc3BsYXkoT2JqZWN0IGNvbnRlbnQpIHsKKwlTdHJpbmcgZXJyb3I7CisKKwlpZiAoY29udGVudCA9PSBudWxsKQorCSAgICBlcnJvciA9ICJDb250ZW50IGlzIG51bGwiOworCWVsc2UKKwkgICAgZXJyb3IgPSAiT2JqZWN0IG5vdCBvZiB0eXBlIE11bHRpcGFydCwgY29udGVudCBjbGFzcyA9ICIgKworCSAgICBjb250ZW50LmdldENsYXNzKCkudG9TdHJpbmcoKTsKKwkKKwlTeXN0ZW0ub3V0LnByaW50bG4oZXJyb3IpOworCUxhYmVsIGxhYiA9IG5ldyBMYWJlbChlcnJvcik7CisJYWRkKGxhYik7CisgICAgfQorICAgCisgICAgY2xhc3MgQXR0YWNobWVudFZpZXdlciBpbXBsZW1lbnRzIEFjdGlvbkxpc3RlbmVyIHsKKwkKKwlCb2R5UGFydCBicCA9IG51bGw7CisJCisJcHVibGljIEF0dGFjaG1lbnRWaWV3ZXIoQm9keVBhcnQgcGFydCkgeworCSAgICBicCA9IHBhcnQ7CisJfQorCQorCXB1YmxpYyB2b2lkIGFjdGlvblBlcmZvcm1lZChBY3Rpb25FdmVudCBlKSB7CisJICAgIENvbXBvbmVudEZyYW1lIGYgPSBuZXcgQ29tcG9uZW50RnJhbWUoCisJCWdldENvbXBvbmVudChicCksICJBdHRhY2htZW50Iik7CisJICAgIGYucGFjaygpOworCSAgICBmLnNob3coKTsKKwl9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9jbGllbnQvc3JjL21haW4vamF2YS9SRUFETUUudHh0IGIvY2xpZW50L3NyYy9tYWluL2phdmEvUkVBRE1FLnR4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYjAwOTQzCi0tLSAvZGV2L251bGwKKysrIGIvY2xpZW50L3NyYy9tYWluL2phdmEvUkVBRE1FLnR4dApAQCAtMCwwICsxLDEyNCBAQAorU2ltcGxlQ2xpZW50CistLS0tLS0tLS0tLS0KKworTm90ZXM6Cis9PT09PT0KKworVGhpcyBzaG91bGQgbm90IGJlIHRha2VuIGFzIGEgZGVtbyBvZiBob3cgdG8gdXNlIHRoZSBTd2luZyBBUEksIGJ1dAorcmF0aGVyIGEgdmVyeSBzaW1wbGUgZ3JhcGhpY2FsIG1haWwgY2xpZW50LiBJdCBzaG93cyBob3cgdmlld2VycyBjYW4KK2JlIHVzZWQgdG8gZGlzcGxheSB0aGUgY29udGVudCBmcm9tIG1haWwgbWVzc2FnZXMuICBJdCBhbHNvIChsaWtlIHRoZQorb3RoZXIgZGVtb3MpIHNob3dzIGhvdyB0byByZXRyaWV2ZSBGb2xkZXJzIGZyb20gYSBTdG9yZSwgTWVzc2FnZXMKK2Zyb20gYSBGb2xkZXIsIGFuZCBjb250ZW50IGZyb20gTWVzc2FnZXMuCisKKworVG8gcnVuIHRoZSBkZW1vOgorPT09PT09PT09PT09PT09PQorCisgICAgMS4gIElmIHlvdSdyZSB1c2luZyBKREsgMS4xLngsIGRvd25sb2FkIHRoZSBsYXRlc3QgdmVyc2lvbiBvZiB0aGUgSkZDCisJKFN3aW5nKSBBUElzIGZyb20gaHR0cDovL2phdmEuc3VuLmNvbS9wcm9kdWN0cy9qZmMvZG93bmxvYWQuaHRtbC4KKwlUaGUgU2ltcGxlQ2xpZW50IHVzZXMgYXQgbGVhc3QgdmVyc2lvbiAxLjEgb2YgU3dpbmcuCisKKwlJZiB5b3UncmUgdXNpbmcgSkRLIDEuMiAoSjJTRSAxLjIpIG9yIG5ld2VyLCBTd2luZyBpcyBpbmNsdWRlZAorCWFuZCBubyBzZXBhcmF0ZSBkb3dubG9hZCBpcyBuZWNlc3NhcnkuCisKKwlXZSAqc3Ryb25nbHkqIGVuY291cmFnZSB5b3UgdG8gdXNlIHRoZSBsYXRlc3QgdmVyc2lvbiBvZiBKMlNFLAorCXdoaWNoIHlvdSBjYW4gZG93bmxvYWQgZnJvbSBodHRwOi8vamF2YS5zdW4uY29tL2oyc2UvLgorCisgICAgMi4gIFNldCB5b3VyIENMQVNTUEFUSCB0byBpbmNsdWRlIHRoZSAibWFpbC5qYXIiLCAiYWN0aXZhdGlvbi5qYXIiLAorCWFuZCAoaWYgeW91J3JlIHVzaW5nIEpESyAxLjEueCBhbmQgZG93bmxvYWRlZCBTd2luZyBzZXBhcmF0ZWx5KQorCSJzd2luZ2FsbC5qYXIiLCBhbmQgdGhlIGN1cnJlbnQgZGlyZWN0b3J5LiAgRm9yIGV4YW1wbGU6CisKKwlGb3IgSkRLIDEuMSBvbiBVTklYOgorCisJZXhwb3J0IENMQVNTUEFUSD0vdS9tZS9kb3dubG9hZC9tYWlsLmphcjovdS9tZS9kb3dubG9hZC9hY3RpdmF0aW9uLmphcjovdS9tZS9kb3dubG9hZC9zd2luZ2FsbC5qYXI6LgorCisJRm9yIEpESyAxLjIgYW5kIG5ld2VyIG9uIFVOSVg6CisKKwlleHBvcnQgQ0xBU1NQQVRIPS91L21lL2Rvd25sb2FkL21haWwuamFyOi91L21lL2Rvd25sb2FkL2FjdGl2YXRpb24uamFyOi4KKworICAgIDMuICBHbyB0byB0aGUgZGVtby9jbGllbnQgZGlyZWN0b3J5CisKKyAgICA0LiAgQ29tcGlsZSBhbGwgdGhlIGZpbGVzIHVzaW5nIHlvdXIgSmF2YSBjb21waWxlci4gIEZvciBleGFtcGxlOgorCisJICBqYXZhYyAqLmphdmEKKworICAgIDUuICBSdW4gdGhlIGRlbW8uIEZvciBleGFtcGxlOgorCisJICBqYXZhIFNpbXBsZUNsaWVudCAtTCBpbWFwOi8vdXNlcm5hbWU6cGFzc3dvcmRAaG9zdG5hbWUvCisKKwlOb3RlIHRoYXQgU2ltcGxlQ2xpZW50IGV4cGVjdHMgdG8gcmVhZCB0aGUgInNpbXBsZS5tYWlsY2FwIgorCWZpbGUgZnJvbSB0aGUgY3VycmVudCBkaXJlY3RvcnkuICBUaGUgc2ltcGxlLm1haWxjYXAgZmlsZQorCWNvbnRhaW5zIGNvbmZpZ3VyYXRpb24gaW5mb3JtYXRpb24gYWJvdXQgdmlld2VycyBuZWVkZWQgYnkKKwl0aGUgU2ltcGxlQ2xpZW50IGRlbW8gcHJvZ3JhbS4KKworCisKK092ZXJ2aWV3IG9mIHRoZSBDbGFzc2VzCis9PT09PT09PT09PT09PT09PT09PT09PQorCitNYWluIENsYXNzZXM6CisKKwlTaW1wbGVDbGllbnQgICA9ICAgIGNvbnRhaW5zIG1haW4oKS4KKwkJCSAgICAgVXNlcyB0aGUgcGFyYW1ldGVycyB0byB0aGUgYXBwbGljYXRpb24gdG8KKwkJCSAgICAgbG9jYXRlIHRoZSBjb3JyZWN0IFN0b3JlLiAgZS5nLgorCisJCQkJU2ltcGxlQ2xpZW50IC1MIGltYXA6Ly9jb3R0b246c2VjcmV0QHNub3ctZ29vbi8KKworCQkJICAgICBJdCB3aWxsIGNyZWF0ZSB0aGUgbWFpbiBmcmFtZSBhbmQKKwkJCSAgICAgY3JlYXRlcyBhIHRyZWUuICBUaGUgdHJlZSB1c2VzIHRoZQorCQkJICAgICBTdG9yZVRyZWVOb2RlcyBhbmQgRm9sZGVyVHJlZU5vZGVzLgorCisJU3RvcmVUcmVlTm9kZSAgID0gICAgc3ViY2xhc3Mgb2YgU3dpbmcncyBEZWZhdWx0TXV0YWJsZVRyZWVOb2RlLgorCQkJICAgICBUaGlzIGNsYXNzIHNob3dzIGhvdyB0byBnZXQgRm9sZGVycyBmcm9tCisJCQkgICAgIHRoZSBTdG9yZS4KKworCUZvbGRlclRyZWVOb2RlICA9ICAgIHN1YmNsYXNzIG9mIFN3aW5nJ3MgRGVmYXVsdE11dGFibGVUcmVlTm9kZS4KKwkJCSAgICAgSWYgdGhlIGZvbGRlciBoYXMgbWVzc2FnZXMsIGl0IHdpbGwgY3JlYXRlCisJCQkgICAgIGEgRm9sZGVyVmlld2VyLiAgT3RoZXJ3aXNlIGl0IHdpbGwgYWRkIHRoZQorCQkJICAgICBzdWJmb2xkZXJzIHRvIHRoZSB0cmVlLgorCisJU2ltcGxlQXV0aGVudGljYXRvciA9IHN1YmNsYXNzIG9mIGphdmF4Lm1haWwuQXV0aGVudGljYXRvci4gSWYKKwkJCSAgICAgdGhlIFN0b3JlIGlzIG1pc3NpbmcgdGhlIHVzZXJuYW1lIG9yIHRoZQorCQkJICAgICBwYXNzd29yZCwgdGhpcyBhdXRoZW50aWNhdG9yIHdpbGwgYmUgdXNlZC4KKwkJCSAgICAgSXQgZGlzcGxheXMgYSBkaWFsb2cgcmVxdWVzdGluZyB0aGUKKwkJCSAgICAgaW5mb3JtYXRpb24gZnJvbSB0aGUgdXNlci4KKwkJCQkKKworVmlld2luZyBGb2xkZXJzOgorCisJRm9sZGVyVmlld2VyICAgID0gICAgVXNlcyBhIFN3aW5nIFRhYmxlIHRvIGRpc3BsYXkgYWxsIG9mIHRoZQorCQkJICAgICBNZXNzYWdlIGluIGEgRm9sZGVyLiAgVGhlICJtb2RlbCIgb2YgdGhlCisJCQkgICAgIGRhdGEgZm9yIHRoaXMgVGFibGUgaXMgYSBGb2xkZXJNb2RlbCB3aGljaAorCQkJICAgICBrbm93cyBob3cgdG8gZ2V0IGRpc3BsYXlhYmxlIGluZm9ybWF0aW9uCisJCQkgICAgIGZyb20gYSBNZXNzYWdlLgorCitKQUYgVmlld2VyczoKKworCU1lc3NhZ2VWaWV3ZXIgICA9ICAgIFVzZXMgdGhlIGNvbnRlbnQgb2YgdGhlIERhdGFIYW5kbGVyLiAgVGhlCisJCQkgICAgIGNvbnRlbnQgd2lsbCBiZSBhIGphdmF4Lm1haWwuTWVzc2FnZQorCQkJICAgICBvYmplY3QuICBEaXNwbGF5cyB0aGUgaGVhZGVycyBhbmQgdGhlbgorCQkJICAgICB1c2VzIHRoZSBKQUYgdG8gZmluZCBhbm90aGVyIHZpZXdlciBmb3IKKwkJCSAgICAgdGhlIGNvbnRlbnQgdHlwZSBvZiB0aGUgTWVzc2FnZS4gIChlaXRoZXIKKwkJCSAgICAgbXVsdGlwYXJ0L21peGVkLCBpbWFnZS9naWYsIG9yIHRleHQvcGxhaW4pCisKKwlNdWx0aXBhcnRWaWV3ZXIgPSAgICBVc2VzIHRoZSBjb250ZW50IG9mIHRoZSBEYXRhSGFuZGxlci4gIFRoZQorCQkJICAgICBjb250ZW50IHdpbGwgYmUgYSBqYXZheC5tYWlsLk11bHRpcGFydAorCQkJICAgICBvYmplY3QuICBVc2VzIHRoZSBKQUYgdG8gZmluZCBhbm90aGVyCisJCQkgICAgIHZpZXdlciBmb3IgdGhlIGZpcnN0IEJvZHlQYXJ0J3MgY29udGVudC4KKwkJCSAgICAgQWxzbyBwdXRzIEJ1dHRvbnMgKGFzICJhdHRhY2htZW50cyIpIGZvcgorCQkJICAgICB0aGUgcmVzdCBvZiB0aGUgQm9keVBhcnRzLiAgV2hlbiB0aGUKKwkJCSAgICAgQnV0dG9uIGFyZSBwcmVzc2VkLCBpdCB1c2VzIHRoZSBKQUYgdG8KKwkJCSAgICAgZmluZCBhIHZpZXdlciBmb3IgdGhlIEJvZHlQYXJ0J3MgY29udGVudCwKKwkJCSAgICAgYW5kIGRpc3BsYXlzIGl0IGluIGEgc2VwYXJhdGUgZnJhbWUgKHVzaW5nCisJCQkgICAgIENvbXBvbmVudEZyYW1lKS4KKworCVRleHRWaWV3ZXIgICAgICA9ICAgIFVzZXMgdGhlIGNvbnRlbnQgb2YgdGhlIERhdGFIYW5kbGVyLiAgVGhlCisJCQkgICAgIGNvbnRlbnQgd2lsbCBiZSBlaXRoZXIgYSBqYXZhLmxhbmcuU3RyaW5nCisJCQkgICAgIG9iamVjdCwgb3IgYSBqYXZhLmlvLklucHV0U3RyZWFtIG9iamVjdC4KKwkJCSAgICAgQ3JlYXRlcyBhIFRleHRBcmVhIGFuZCBzZXRzIHRoZSB0ZXh0IHVzaW5nCisJCQkgICAgIHRoZSBTdHJpbmcgb3IgSW5wdXRTdHJlYW0uCisKK1N1cHBvcnQgQ2xhc3NlczoKKworCUNvbXBvbmVudEZyYW1lICA9ICAgIHN1cHBvcnQgY2xhc3Mgd2hpY2ggdGFrZXMgYSBqYXZhLmF3dC5Db21wb25lbnQKKwkJCSAgICAgYW5kIGRpc3BsYXlzIGl0IGluIGEgRnJhbWUuCmRpZmYgLS1naXQgYS9jbGllbnQvc3JjL21haW4vamF2YS9TaW1wbGVBdXRoZW50aWNhdG9yLmphdmEgYi9jbGllbnQvc3JjL21haW4vamF2YS9TaW1wbGVBdXRoZW50aWNhdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTViYWNjNQotLS0gL2Rldi9udWxsCisrKyBiL2NsaWVudC9zcmMvbWFpbi9qYXZhL1NpbXBsZUF1dGhlbnRpY2F0b3IuamF2YQpAQCAtMCwwICsxLDEyNyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgRGlzdHJpYnV0aW9uIExpY2Vuc2Ugdi4gMS4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvb3JnL2RvY3VtZW50cy9lZGwtdjEwLnBocC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQlNELTMtQ2xhdXNlCisgKi8KKworaW1wb3J0IGphdmF4Lm1haWwuKjsKK2ltcG9ydCBqYXZhLm5ldC5JbmV0QWRkcmVzczsKK2ltcG9ydCBqYXZhLmF3dC4qOworaW1wb3J0IGphdmF4LnN3aW5nLio7CisKKy8qKgorICogU2ltcGxlIEF1dGhlbnRpY2F0b3IgZm9yIHJlcXVlc3RpbmcgcGFzc3dvcmQgaW5mb3JtYXRpb24uCisgKgorICogQGF1dGhvcglDaHJpc3RvcGhlciBDb3R0b24KKyAqIEBhdXRob3IJQmlsbCBTaGFubm9uCisgKi8KKworcHVibGljIGNsYXNzIFNpbXBsZUF1dGhlbnRpY2F0b3IgZXh0ZW5kcyBBdXRoZW50aWNhdG9yIHsKKworICAgIEZyYW1lIGZyYW1lOworICAgIFN0cmluZyB1c2VybmFtZTsKKyAgICBTdHJpbmcgcGFzc3dvcmQ7CisKKyAgICBwdWJsaWMgU2ltcGxlQXV0aGVudGljYXRvcihGcmFtZSBmKSB7CisJdGhpcy5mcmFtZSA9IGY7CisgICAgfQorCisgICAgcHJvdGVjdGVkIFBhc3N3b3JkQXV0aGVudGljYXRpb24gZ2V0UGFzc3dvcmRBdXRoZW50aWNhdGlvbigpIHsKKworCS8vIGdpdmVuIGEgcHJvbXB0PworCVN0cmluZyBwcm9tcHQgPSBnZXRSZXF1ZXN0aW5nUHJvbXB0KCk7CisJaWYgKHByb21wdCA9PSBudWxsKQorCSAgICBwcm9tcHQgPSAiUGxlYXNlIGxvZ2luLi4uIjsKKworCS8vIHByb3RvY29sCisJU3RyaW5nIHByb3RvY29sID0gZ2V0UmVxdWVzdGluZ1Byb3RvY29sKCk7CisJaWYgKHByb3RvY29sID09IG51bGwpCisJICAgIHByb3RvY29sID0gIlVua25vd24gcHJvdG9jb2wiOworCisJLy8gZ2V0IHRoZSBob3N0CisJU3RyaW5nIGhvc3QgPSBudWxsOworCUluZXRBZGRyZXNzIGluZXQgPSBnZXRSZXF1ZXN0aW5nU2l0ZSgpOworCWlmIChpbmV0ICE9IG51bGwpCisJICAgIGhvc3QgPSBpbmV0LmdldEhvc3ROYW1lKCk7CisJaWYgKGhvc3QgPT0gbnVsbCkKKwkgICAgaG9zdCA9ICJVbmtub3duIGhvc3QiOworCisJLy8gcG9ydAorCVN0cmluZyBwb3J0ID0gIiI7CisJaW50IHBvcnRudW0gPSBnZXRSZXF1ZXN0aW5nUG9ydCgpOworCWlmIChwb3J0bnVtICE9IC0xKQorCSAgICBwb3J0ID0gIiwgcG9ydCAiICsgcG9ydG51bSArICIgIjsKKworCS8vIEJ1aWxkIHRoZSBpbmZvIHN0cmluZworCVN0cmluZyBpbmZvID0gIkNvbm5lY3RpbmcgdG8gIiArIHByb3RvY29sICsgIiBtYWlsIHNlcnZpY2Ugb24gaG9zdCAiICsKKwkJCQkJCQkJaG9zdCArIHBvcnQ7CisKKwkvL0pQYW5lbCBkID0gbmV3IEpQYW5lbCgpOworCS8vIFhYWCAtIGZvciBzb21lIHJlYXNvbiB1c2luZyBhIEpQYW5lbCBoZXJlIGNhdXNlcyBKT3B0aW9uUGFuZQorCS8vIHRvIGRpc3BsYXkgaW5jb3JyZWN0bHksIHNvIHdlIHdvcmthcm91bmQgdGhlIHByb2JsZW0gdXNpbmcKKwkvLyBhbiBhbm9ueW1vdXMgSkNvbXBvbmVudC4KKwlKQ29tcG9uZW50IGQgPSBuZXcgSkNvbXBvbmVudCgpIHsgfTsKKworCUdyaWRCYWdMYXlvdXQgZ2IgPSBuZXcgR3JpZEJhZ0xheW91dCgpOworCUdyaWRCYWdDb25zdHJhaW50cyBjID0gbmV3IEdyaWRCYWdDb25zdHJhaW50cygpOworCWQuc2V0TGF5b3V0KGdiKTsKKwljLmluc2V0cyA9IG5ldyBJbnNldHMoMiwgMiwgMiwgMik7CisKKwljLmFuY2hvciA9IEdyaWRCYWdDb25zdHJhaW50cy5XRVNUOworCWMuZ3JpZHdpZHRoID0gR3JpZEJhZ0NvbnN0cmFpbnRzLlJFTUFJTkRFUjsKKwljLndlaWdodHggPSAwLjA7CisJZC5hZGQoY29uc3RyYWluKG5ldyBKTGFiZWwoaW5mbyksIGdiLCBjKSk7CisJZC5hZGQoY29uc3RyYWluKG5ldyBKTGFiZWwocHJvbXB0KSwgZ2IsIGMpKTsKKworCWMuZ3JpZHdpZHRoID0gMTsKKwljLmFuY2hvciA9IEdyaWRCYWdDb25zdHJhaW50cy5FQVNUOworCWMuZmlsbCA9IEdyaWRCYWdDb25zdHJhaW50cy5OT05FOworCWMud2VpZ2h0eCA9IDAuMDsKKwlkLmFkZChjb25zdHJhaW4obmV3IEpMYWJlbCgiVXNlcm5hbWU6IiksIGdiLCBjKSk7CisKKwljLmFuY2hvciA9IEdyaWRCYWdDb25zdHJhaW50cy5FQVNUOworCWMuZmlsbCA9IEdyaWRCYWdDb25zdHJhaW50cy5IT1JJWk9OVEFMOworCWMuZ3JpZHdpZHRoID0gR3JpZEJhZ0NvbnN0cmFpbnRzLlJFTUFJTkRFUjsKKwljLndlaWdodHggPSAxLjA7CisJU3RyaW5nIHVzZXIgPSBnZXREZWZhdWx0VXNlck5hbWUoKTsKKwlKVGV4dEZpZWxkIHVzZXJuYW1lID0gbmV3IEpUZXh0RmllbGQodXNlciwgMjApOworCWQuYWRkKGNvbnN0cmFpbih1c2VybmFtZSwgZ2IsIGMpKTsKKworCWMuZ3JpZHdpZHRoID0gMTsKKwljLmZpbGwgPSBHcmlkQmFnQ29uc3RyYWludHMuTk9ORTsKKwljLmFuY2hvciA9IEdyaWRCYWdDb25zdHJhaW50cy5FQVNUOworCWMud2VpZ2h0eCA9IDAuMDsKKwlkLmFkZChjb25zdHJhaW4obmV3IEpMYWJlbCgiUGFzc3dvcmQ6IiksIGdiLCBjKSk7CisKKwljLmFuY2hvciA9IEdyaWRCYWdDb25zdHJhaW50cy5FQVNUOworCWMuZmlsbCA9IEdyaWRCYWdDb25zdHJhaW50cy5IT1JJWk9OVEFMOworCWMuZ3JpZHdpZHRoID0gR3JpZEJhZ0NvbnN0cmFpbnRzLlJFTUFJTkRFUjsKKwljLndlaWdodHggPSAxLjA7CisJSlBhc3N3b3JkRmllbGQgcGFzc3dvcmQgPSBuZXcgSlBhc3N3b3JkRmllbGQoIiIsIDIwKTsKKwlkLmFkZChjb25zdHJhaW4ocGFzc3dvcmQsIGdiLCBjKSk7CisJLy8gWFhYIC0gZm9sbG93aW5nIGRvZXNuJ3Qgd29yaworCWlmICh1c2VyICE9IG51bGwgJiYgdXNlci5sZW5ndGgoKSA+IDApCisJICAgIHBhc3N3b3JkLnJlcXVlc3RGb2N1cygpOworCWVsc2UKKwkgICAgdXNlcm5hbWUucmVxdWVzdEZvY3VzKCk7CisJCisJaW50IHJlc3VsdCA9IEpPcHRpb25QYW5lLnNob3dDb25maXJtRGlhbG9nKGZyYW1lLCBkLCAiTG9naW4iLAorCSAgICBKT3B0aW9uUGFuZS5PS19DQU5DRUxfT1BUSU9OLCBKT3B0aW9uUGFuZS5RVUVTVElPTl9NRVNTQUdFKTsKKwkKKwlpZiAocmVzdWx0ID09IEpPcHRpb25QYW5lLk9LX09QVElPTikKKwkgICAgcmV0dXJuIG5ldyBQYXNzd29yZEF1dGhlbnRpY2F0aW9uKHVzZXJuYW1lLmdldFRleHQoKSwKKwkJCQkJCXBhc3N3b3JkLmdldFRleHQoKSk7CisJZWxzZQorCSAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwcml2YXRlIENvbXBvbmVudCBjb25zdHJhaW4oQ29tcG9uZW50IGNtcCwKKwkJCQlHcmlkQmFnTGF5b3V0IGdiLCBHcmlkQmFnQ29uc3RyYWludHMgYykgeworCWdiLnNldENvbnN0cmFpbnRzKGNtcCwgYyk7CisJcmV0dXJuIChjbXApOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2NsaWVudC9zcmMvbWFpbi9qYXZhL1NpbXBsZUNsaWVudC5qYXZhIGIvY2xpZW50L3NyYy9tYWluL2phdmEvU2ltcGxlQ2xpZW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDQ3YmU1NQotLS0gL2Rldi9udWxsCisrKyBiL2NsaWVudC9zcmMvbWFpbi9qYXZhL1NpbXBsZUNsaWVudC5qYXZhCkBAIC0wLDAgKzEsMTQ4IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBEaXN0cmlidXRpb24gTGljZW5zZSB2LiAxLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9vcmcvZG9jdW1lbnRzL2VkbC12MTAucGhwLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBCU0QtMy1DbGF1c2UKKyAqLworCitpbXBvcnQgamF2YS51dGlsLio7CitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmF4Lm1haWwuKjsKK2ltcG9ydCBqYXZheC5tYWlsLmludGVybmV0Lio7CitpbXBvcnQgamF2YXguYWN0aXZhdGlvbi4qOworaW1wb3J0IGphdmEuYXd0Lio7CitpbXBvcnQgamF2YS5hd3QuZXZlbnQuKjsKK2ltcG9ydCBqYXZheC5zd2luZy4qOworaW1wb3J0IGphdmF4LnN3aW5nLnRhYmxlLio7CitpbXBvcnQgamF2YXguc3dpbmcudHJlZS4qOworaW1wb3J0IGphdmF4LnN3aW5nLmV2ZW50Lio7CisKKworLyoqCisgKiBEZW1vIGFwcCB0aGF0IHNob3dzIGEgdmVyeSBzaW1wbGUgTWFpbCBDbGllbnQKKyAqCisgKiBAYXV0aG9yIENocmlzdG9waGVyIENvdHRvbgorICogQGF1dGhvciBCaWxsIFNoYW5ub24KKyAqLworCitwdWJsaWMgY2xhc3MgU2ltcGxlQ2xpZW50IHsKKworICAgIHN0YXRpYyBWZWN0b3IgdXJsID0gbmV3IFZlY3RvcigpOworICAgIHN0YXRpYyBGb2xkZXJWaWV3ZXIgZnY7CisgICAgc3RhdGljIE1lc3NhZ2VWaWV3ZXIgbXY7CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmcgYXJndltdKSB7CisJYm9vbGVhbiB1c2FnZSA9IGZhbHNlOworCisJZm9yIChpbnQgb3B0aW5kID0gMDsgb3B0aW5kIDwgYXJndi5sZW5ndGg7IG9wdGluZCsrKSB7CisJICAgIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItTCIpKSB7CisJCXVybC5hZGRFbGVtZW50KGFyZ3ZbKytvcHRpbmRdKTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uc3RhcnRzV2l0aCgiLSIpKSB7CisJCXVzYWdlID0gdHJ1ZTsKKwkJYnJlYWs7CisJICAgIH0gZWxzZSB7CisJCXVzYWdlID0gdHJ1ZTsKKwkJYnJlYWs7CisJICAgIH0KKwl9CisKKwlpZiAodXNhZ2UgfHwgdXJsLnNpemUoKSA9PSAwKSB7CisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiVXNhZ2U6IFNpbXBsZUNsaWVudCAtTCB1cmwiKTsKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCIgICB3aGVyZSB1cmwgaXMgcHJvdG9jb2w6Ly91c2VybmFtZTpwYXNzd29yZEBob3N0bmFtZS8iKTsKKwkgICAgU3lzdGVtLmV4aXQoMSk7CisJfQorCisJdHJ5IHsKKwkgICAgLy8gU2V0IHVwIG91ciBNYWlsY2FwIGVudHJpZXMuICBUaGlzIHdpbGwgYWxsb3cgdGhlIEpBRgorCSAgICAvLyB0byBsb2NhdGUgb3VyIHZpZXdlcnMuCisJICAgIEZpbGUgY2FwZmlsZSA9IG5ldyBGaWxlKCJzaW1wbGUubWFpbGNhcCIpOworCSAgICBpZiAoIWNhcGZpbGUuaXNGaWxlKCkpIHsKKwkJU3lzdGVtLm91dC5wcmludGxuKAorCQkgICAgIkNhbm5vdCBsb2NhdGUgdGhlIFwic2ltcGxlLm1haWxjYXBcIiBmaWxlLiIpOworCQlTeXN0ZW0uZXhpdCgxKTsKKwkgICAgfQorCSAgICAKKwkgICAgQ29tbWFuZE1hcC5zZXREZWZhdWx0Q29tbWFuZE1hcCggbmV3IE1haWxjYXBDb21tYW5kTWFwKAorCQluZXcgRmlsZUlucHV0U3RyZWFtKGNhcGZpbGUpKSk7CisJCQorCSAgICBKRnJhbWUgZnJhbWUgPSBuZXcgSkZyYW1lKCJTaW1wbGUgSmF2YU1haWwgQ2xpZW50Iik7CisJICAgIGZyYW1lLmFkZFdpbmRvd0xpc3RlbmVyKG5ldyBXaW5kb3dBZGFwdGVyKCkgeworCQlwdWJsaWMgdm9pZCB3aW5kb3dDbG9zaW5nKFdpbmRvd0V2ZW50IGUpIHtTeXN0ZW0uZXhpdCgwKTt9fSk7CisJICAgIC8vZnJhbWUuc2V0RGVmYXVsdENsb3NlT3BlcmF0aW9uKEpGcmFtZS5ESVNQT1NFX09OX0NMT1NFKTsKKwkJCisJICAgIC8vIEdldCBhIFN0b3JlIG9iamVjdAorCSAgICBTaW1wbGVBdXRoZW50aWNhdG9yIGF1dGggPSBuZXcgU2ltcGxlQXV0aGVudGljYXRvcihmcmFtZSk7CisJICAgIFNlc3Npb24gc2Vzc2lvbiA9IAorCQlTZXNzaW9uLmdldERlZmF1bHRJbnN0YW5jZShTeXN0ZW0uZ2V0UHJvcGVydGllcygpLCBhdXRoKTsKKwkgICAgLy9zZXNzaW9uLnNldERlYnVnKHRydWUpOworCisJICAgIERlZmF1bHRNdXRhYmxlVHJlZU5vZGUgcm9vdCA9IG5ldyBEZWZhdWx0TXV0YWJsZVRyZWVOb2RlKCJSb290Iik7CisKKwkgICAgLy8gY3JlYXRlIGEgbm9kZSBmb3IgZWFjaCBzdG9yZSB3ZSBoYXZlCisJICAgIGZvciAoRW51bWVyYXRpb24gZSA9IHVybC5lbGVtZW50cygpIDsgZS5oYXNNb3JlRWxlbWVudHMoKSA7KSB7CisJCVN0cmluZyB1cmxzdHJpbmcgPSAoU3RyaW5nKSBlLm5leHRFbGVtZW50KCk7CisJCVVSTE5hbWUgdXJsbiA9IG5ldyBVUkxOYW1lKHVybHN0cmluZyk7CisJCVN0b3JlIHN0b3JlID0gc2Vzc2lvbi5nZXRTdG9yZSh1cmxuKTsKKwkJCisJCVN0b3JlVHJlZU5vZGUgc3RvcmVub2RlID0gbmV3IFN0b3JlVHJlZU5vZGUoc3RvcmUpOworCQlyb290LmFkZChzdG9yZW5vZGUpOworCSAgICB9CSAgICAKKworCSAgICBEZWZhdWx0VHJlZU1vZGVsIHRyZWVNb2RlbCA9IG5ldyBEZWZhdWx0VHJlZU1vZGVsKHJvb3QpOworCSAgICBKVHJlZSB0cmVlID0gbmV3IEpUcmVlKHRyZWVNb2RlbCk7CisJICAgIHRyZWUuYWRkVHJlZVNlbGVjdGlvbkxpc3RlbmVyKG5ldyBUcmVlUHJlc3MoKSk7CisKKwkgICAgLyogUHV0IHRoZSBUcmVlIGluIGEgc2Nyb2xsZXIuICovCisJICAgIEpTY3JvbGxQYW5lICAgICAgICBzcCA9IG5ldyBKU2Nyb2xsUGFuZSgpOworCSAgICBzcC5zZXRQcmVmZXJyZWRTaXplKG5ldyBEaW1lbnNpb24oMjUwLCAzMDApKTsKKwkgICAgc3AuZ2V0Vmlld3BvcnQoKS5hZGQodHJlZSk7CisKKwkgICAgLyogQ3JlYXRlIGEgZG91YmxlIGJ1ZmZlcmVkIEpQYW5lbCAqLworCSAgICBKUGFuZWwgc3YgPSBuZXcgSlBhbmVsKG5ldyBCb3JkZXJMYXlvdXQoKSk7CisJICAgIHN2LmFkZCgiQ2VudGVyIiwgc3ApOworCisJICAgIGZ2ID0gbmV3IEZvbGRlclZpZXdlcihudWxsKTsKKworCSAgICBKU3BsaXRQYW5lIGpzcCA9IG5ldyBKU3BsaXRQYW5lKEpTcGxpdFBhbmUuSE9SSVpPTlRBTF9TUExJVCwKKwkJCQlzdiwgZnYpOworCSAgICBqc3Auc2V0T25lVG91Y2hFeHBhbmRhYmxlKHRydWUpOworCSAgICBtdiA9IG5ldyBNZXNzYWdlVmlld2VyKCk7CisJICAgIEpTcGxpdFBhbmUganNwMiA9IG5ldyBKU3BsaXRQYW5lKEpTcGxpdFBhbmUuVkVSVElDQUxfU1BMSVQsCisJCQkJanNwLCBtdik7CisJICAgIGpzcDIuc2V0T25lVG91Y2hFeHBhbmRhYmxlKHRydWUpOworCisJICAgIGZyYW1lLmdldENvbnRlbnRQYW5lKCkuYWRkKGpzcDIpOworCSAgICBmcmFtZS5wYWNrKCk7CisJICAgIGZyYW1lLnNob3coKTsKKworCX0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlNpbXBsZXRDbGllbnQgY2F1Z2h0IGV4Y2VwdGlvbiIpOworCSAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKKwkgICAgU3lzdGVtLmV4aXQoMSk7CisJfQorICAgIH0KKworfQorCitjbGFzcyBUcmVlUHJlc3MgaW1wbGVtZW50cyBUcmVlU2VsZWN0aW9uTGlzdGVuZXIgeworICAgIAorICAgIHB1YmxpYyB2b2lkIHZhbHVlQ2hhbmdlZChUcmVlU2VsZWN0aW9uRXZlbnQgZSkgeworCVRyZWVQYXRoIHBhdGggPSBlLmdldE5ld0xlYWRTZWxlY3Rpb25QYXRoKCk7CisJaWYgKHBhdGggIT0gbnVsbCkgeworCSAgICBPYmplY3QgbyA9IHBhdGguZ2V0TGFzdFBhdGhDb21wb25lbnQoKTsKKwkgICAgaWYgKG8gaW5zdGFuY2VvZiBGb2xkZXJUcmVlTm9kZSkgeworCQlGb2xkZXJUcmVlTm9kZSBub2RlID0gKEZvbGRlclRyZWVOb2RlKW87CisJCUZvbGRlciBmb2xkZXIgPSBub2RlLmdldEZvbGRlcigpOworCisJCXRyeSB7CisJCSAgICBpZiAoKGZvbGRlci5nZXRUeXBlKCkgJiBGb2xkZXIuSE9MRFNfTUVTU0FHRVMpICE9IDApIHsKKwkJCVNpbXBsZUNsaWVudC5mdi5zZXRGb2xkZXIoZm9sZGVyKTsKKwkJICAgIH0KKwkJfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIG1lKSB7IH0KKwkgICAgfQorCX0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9jbGllbnQvc3JjL21haW4vamF2YS9TdG9yZVRyZWVOb2RlLmphdmEgYi9jbGllbnQvc3JjL21haW4vamF2YS9TdG9yZVRyZWVOb2RlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2NhOWE1ZAotLS0gL2Rldi9udWxsCisrKyBiL2NsaWVudC9zcmMvbWFpbi9qYXZhL1N0b3JlVHJlZU5vZGUuamF2YQpAQCAtMCwwICsxLDEwNyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgRGlzdHJpYnV0aW9uIExpY2Vuc2Ugdi4gMS4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvb3JnL2RvY3VtZW50cy9lZGwtdjEwLnBocC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQlNELTMtQ2xhdXNlCisgKi8KKworaW1wb3J0IGphdmF4LnN3aW5nLnRyZWUuRGVmYXVsdE11dGFibGVUcmVlTm9kZTsKK2ltcG9ydCBqYXZheC5tYWlsLio7CisKKy8qKgorICogTm9kZSB3aGljaCByZXByZXNlbnRzIGEgU3RvcmUgaW4gdGhlIGphdmF4Lm1haWwgYXBpcy4gCisgKgorICogQGF1dGhvciBDaHJpc3RvcGhlciBDb3R0b24KKyAqLworcHVibGljIGNsYXNzIFN0b3JlVHJlZU5vZGUgZXh0ZW5kcyBEZWZhdWx0TXV0YWJsZVRyZWVOb2RlIHsKKyAgICAKKyAgICBwcm90ZWN0ZWQgU3RvcmUJc3RvcmUgPSBudWxsOworICAgIHByb3RlY3RlZCBGb2xkZXIJZm9sZGVyID0gbnVsbDsKKyAgICBwcm90ZWN0ZWQgU3RyaW5nCWRpc3BsYXkgPSBudWxsOworCisgICAgLyoqCisgICAgICogY3JlYXRlcyBhIHRyZWUgbm9kZSB0aGF0IHBvaW50cyB0byB0aGUgcGFydGljdWxhciBTdG9yZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB3aGF0CXRoZSBzdG9yZSBmb3IgdGhpcyBub2RlCisgICAgICovCisgICAgcHVibGljIFN0b3JlVHJlZU5vZGUoU3RvcmUgd2hhdCkgeworCXN1cGVyKHdoYXQpOworCXN0b3JlID0gd2hhdDsKKyAgICB9CisKKyAgICAKKyAgICAvKioKKyAgICAgKiBhIFN0b3JlIGlzIG5ldmVyIGEgbGVhZiBub2RlLiAgSXQgY2FuIGFsd2F5cyBjb250YWluIHN0dWZmCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNMZWFmKCkgeworCXJldHVybiBmYWxzZTsKKyAgICB9CisgICAKKworICAgIC8qKgorICAgICAqIHJldHVybiB0aGUgbnVtYmVyIG9mIGNoaWxkcmVuIGZvciB0aGlzIHN0b3JlIG5vZGUuIFRoZSBmaXJzdAorICAgICAqIHRpbWUgdGhpcyBtZXRob2QgaXMgY2FsbGVkIHdlIGxvYWQgdXAgYWxsIG9mIHRoZSBmb2xkZXJzCisgICAgICogdW5kZXIgdGhlIHN0b3JlJ3MgZGVmYXVsdEZvbGRlcgorICAgICAqLworCisgICAgcHVibGljIGludCBnZXRDaGlsZENvdW50KCkgeworCWlmIChmb2xkZXIgPT0gbnVsbCkgeworCSAgICBsb2FkQ2hpbGRyZW4oKTsKKwl9CisJcmV0dXJuIHN1cGVyLmdldENoaWxkQ291bnQoKTsKKyAgICB9CisgICAgCisgICAgcHJvdGVjdGVkIHZvaWQgbG9hZENoaWxkcmVuKCkgeworCXRyeSB7CisJICAgIC8vIGNvbm5lY3QgdG8gdGhlIFN0b3JlIGlmIHdlIG5lZWQgdG8KKwkgICAgaWYgKCFzdG9yZS5pc0Nvbm5lY3RlZCgpKSB7CisJCXN0b3JlLmNvbm5lY3QoKTsKKwkgICAgfQorCisJICAgIC8vIGdldCB0aGUgZGVmYXVsdCBmb2xkZXIsIGFuZCBsaXN0IHRoZQorCSAgICAvLyBzdWJzY3JpYmVkIGZvbGRlcnMgb24gaXQKKwkgICAgZm9sZGVyID0gc3RvcmUuZ2V0RGVmYXVsdEZvbGRlcigpOworCSAgICAvLyBGb2xkZXJbXSBzdWIgPSBmb2xkZXIubGlzdFN1YnNjcmliZWQoKTsKKwkgICAgRm9sZGVyW10gc3ViID0gZm9sZGVyLmxpc3QoKTsKKworCSAgICAvLyBhZGQgYSBGb2xkZXJUcmVlTm9kZSBmb3IgZWFjaCBGb2xkZXIKKwkgICAgaW50IG51bSA9IHN1Yi5sZW5ndGg7CisJICAgIGZvcihpbnQgaSA9IDA7IGkgPCBudW07IGkrKykgeworCQlGb2xkZXJUcmVlTm9kZSBub2RlID0gbmV3IEZvbGRlclRyZWVOb2RlKHN1YltpXSk7CisJCS8vIHdlIHVzZWQgaW5zZXJ0IGhlcmUsIHNpbmNlIGFkZCgpIHdvdWxkIG1ha2UKKwkJLy8gYW5vdGhlciByZWN1cnNpdmUgY2FsbCB0byBnZXRDaGlsZENvdW50KCk7CisJCWluc2VydChub2RlLCBpKTsKKwkgICAgfQorCSAgICAKKwl9IGNhdGNoIChNZXNzYWdpbmdFeGNlcHRpb24gbWUpIHsKKwkgICAgbWUucHJpbnRTdGFja1RyYWNlKCk7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFdlIG92ZXJyaWRlIHRvU3RyaW5nKCkgc28gd2UgY2FuIGRpc3BsYXkgdGhlIHN0b3JlIFVSTE5hbWUKKyAgICAgKiB3aXRob3V0IHRoZSBwYXNzd29yZC4KKyAgICAgKi8KKworICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisJaWYgKGRpc3BsYXkgPT0gbnVsbCkgeworCSAgICBVUkxOYW1lIHVybCA9IHN0b3JlLmdldFVSTE5hbWUoKTsKKwkgICAgaWYgKHVybCA9PSBudWxsKSB7CisJCWRpc3BsYXkgPSBzdG9yZS50b1N0cmluZygpOworCSAgICB9IGVsc2UgeworCQkvLyBkb24ndCBzaG93IHRoZSBwYXNzd29yZAorCQlVUkxOYW1lIHRvbyA9IG5ldyBVUkxOYW1lKCB1cmwuZ2V0UHJvdG9jb2woKSwgdXJsLmdldEhvc3QoKSwgdXJsLmdldFBvcnQoKSwKKwkJCQkJICAgdXJsLmdldEZpbGUoKSwgdXJsLmdldFVzZXJuYW1lKCksIG51bGwpOworCQlkaXNwbGF5ID0gdG9vLnRvU3RyaW5nKCk7CisJICAgIH0KKwl9CisJCisJcmV0dXJuIGRpc3BsYXk7CisgICAgfQorICAgIAorICAgIAorfQorCmRpZmYgLS1naXQgYS9jbGllbnQvc3JjL21haW4vamF2YS9UZXh0Vmlld2VyLmphdmEgYi9jbGllbnQvc3JjL21haW4vamF2YS9UZXh0Vmlld2VyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWM5ZTU4YwotLS0gL2Rldi9udWxsCisrKyBiL2NsaWVudC9zcmMvbWFpbi9qYXZhL1RleHRWaWV3ZXIuamF2YQpAQCAtMCwwICsxLDg3IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBEaXN0cmlidXRpb24gTGljZW5zZSB2LiAxLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9vcmcvZG9jdW1lbnRzL2VkbC12MTAucGhwLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBCU0QtMy1DbGF1c2UKKyAqLworCitpbXBvcnQgamF2YS5hd3QuKjsKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YS5iZWFucy4qOworaW1wb3J0IGphdmF4LmFjdGl2YXRpb24uKjsKK2ltcG9ydCBqYXZheC5zd2luZy5KUGFuZWw7CitpbXBvcnQgamF2YXguc3dpbmcuSlRleHRBcmVhOworaW1wb3J0IGphdmF4LnN3aW5nLkpTY3JvbGxQYW5lOworCisKKy8qKgorICogQSB2ZXJ5IHNpbXBsZSBUZXh0Vmlld2VyIEJlYW4gZm9yIHRoZSBNSU1FVHlwZSAidGV4dC9wbGFpbiIKKyAqCisgKiBAYXV0aG9yCUNocmlzdG9waGVyIENvdHRvbgorICovCisKK3B1YmxpYyBjbGFzcyBUZXh0Vmlld2VyIGV4dGVuZHMgSlBhbmVsIGltcGxlbWVudHMgQ29tbWFuZE9iamVjdCAKK3sKKworICAgIHByaXZhdGUgSlRleHRBcmVhIHRleHRfYXJlYSA9IG51bGw7CisgICAgcHJpdmF0ZSBEYXRhSGFuZGxlciBkaCA9IG51bGw7CisgICAgcHJpdmF0ZSBTdHJpbmcJdmVyYiA9IG51bGw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvcgorICAgICAqLworICAgIHB1YmxpYyBUZXh0Vmlld2VyKCkgeworCXN1cGVyKG5ldyBHcmlkTGF5b3V0KDEsMSkpOworCisJLy8gY3JlYXRlIHRoZSB0ZXh0IGFyZWEKKwl0ZXh0X2FyZWEgPSBuZXcgSlRleHRBcmVhKCk7CisJdGV4dF9hcmVhLnNldEVkaXRhYmxlKGZhbHNlKTsKKwl0ZXh0X2FyZWEuc2V0TGluZVdyYXAodHJ1ZSk7CisKKwkvLyBjcmVhdGUgYSBzY3JvbGwgcGFuZSBmb3IgdGhlIEpUZXh0QXJlYQorCUpTY3JvbGxQYW5lIHNwID0gbmV3IEpTY3JvbGxQYW5lKCk7CisJc3Auc2V0UHJlZmVycmVkU2l6ZShuZXcgRGltZW5zaW9uKDMwMCwgMzAwKSk7CisJc3AuZ2V0Vmlld3BvcnQoKS5hZGQodGV4dF9hcmVhKTsKKwkKKwlhZGQoc3ApOworICAgIH0KKworCisgICAgcHVibGljIHZvaWQgc2V0Q29tbWFuZENvbnRleHQoU3RyaW5nIHZlcmIsIERhdGFIYW5kbGVyIGRoKQorCXRocm93cyBJT0V4Y2VwdGlvbiB7CisKKwl0aGlzLnZlcmIgPSB2ZXJiOworCXRoaXMuZGggPSBkaDsKKwkKKwl0aGlzLnNldElucHV0U3RyZWFtKCBkaC5nZXRJbnB1dFN0cmVhbSgpICk7CisgICAgfQorCisKKyAgLyoqCisgICAqIHNldCB0aGUgZGF0YSBzdHJlYW0sIGNvbXBvbmVudCB0byBhc3N1bWUgaXQgaXMgcmVhZHkgdG8KKyAgICogYmUgcmVhZC4KKyAgICovCisgIHB1YmxpYyB2b2lkIHNldElucHV0U3RyZWFtKElucHV0U3RyZWFtIGlucykgeworICAgICAgCisgICAgICBpbnQgYnl0ZXNfcmVhZCA9IDA7CisgICAgICAvLyBjaGVjayB0aGF0IHdlIGNhbiBhY3R1YWxseSByZWFkCisgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYmFvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgIGJ5dGUgZGF0YVtdID0gbmV3IGJ5dGVbMTAyNF07CisgICAgICAKKyAgICAgIHRyeSB7CisJICB3aGlsZSgoYnl0ZXNfcmVhZCA9IGlucy5yZWFkKGRhdGEpKSA+MCkKKwkJICBiYW9zLndyaXRlKGRhdGEsIDAsIGJ5dGVzX3JlYWQpOworCSAgaW5zLmNsb3NlKCk7CisgICAgICB9IGNhdGNoKEV4Y2VwdGlvbiBlKSB7CisJICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgfQorCisgICAgICAvLyBjb252ZXJ0IHRoZSBidWZmZXIgaW50byBhIHN0cmluZworICAgICAgLy8gcGxhY2UgaW4gdGhlIHRleHQgYXJlYQorICAgICAgdGV4dF9hcmVhLnNldFRleHQoYmFvcy50b1N0cmluZygpKTsKKworICAgIH0KK30KZGlmZiAtLWdpdCBhL2NsaWVudC9zcmMvbWFpbi9qYXZhL3NpbXBsZS5tYWlsY2FwIGIvY2xpZW50L3NyYy9tYWluL2phdmEvc2ltcGxlLm1haWxjYXAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTY1ZTEzYQotLS0gL2Rldi9udWxsCisrKyBiL2NsaWVudC9zcmMvbWFpbi9qYXZhL3NpbXBsZS5tYWlsY2FwCkBAIC0wLDAgKzEsOSBAQAorIworIyBFeGFtcGxlIGNvbW1hbmQgbWFwLCB1c2luZyB0aGUgTWFpbGNhcENvbW1hbmRNYXAuCisjCisjIGZvciBvdXIgdmlld2VycworIworbWVzc2FnZS8qOzsJCXgtamF2YS12aWV3PU1lc3NhZ2VWaWV3ZXIKK3RleHQvcGxhaW47OwkJeC1qYXZhLXZpZXc9VGV4dFZpZXdlcgorbXVsdGlwYXJ0Lyo7OwkJeC1qYXZhLXZpZXc9TXVsdGlwYXJ0Vmlld2VyCisKZGlmZiAtLWdpdCBhL2NvcHlyaWdodC1leGNsdWRlIGIvY29weXJpZ2h0LWV4Y2x1ZGUKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDQwMzA4ZgotLS0gL2Rldi9udWxsCisrKyBiL2NvcHlyaWdodC1leGNsdWRlCkBAIC0wLDAgKzEsMzEgQEAKK2NvcHlyaWdodC1leGNsdWRlCisvTUFOSUZFU1QuTUYKKy9NRVRBLUlORi9zZXJ2aWNlcy8KKy9NRVRBLUlORi9qYXZhbWFpbAorL01FVEEtSU5GL21haWxjYXAKKy9SRUFETUUKK2RvYy9yZWxlYXNlLworZG9jL3NwZWMvCisvTElDRU5TRS50eHQKK0NPTlRSSUJVVElORy5tZAorTElDRU5TRS5tZAorLmhndGFncworLmhnaWdub3JlCitjbGllbnQvc3JjL21haW4vamF2YS9zaW1wbGUubWFpbGNhcAorbWFpbC9zcmMvb2xkdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvZW5jb2RlZGhlYWRlcnMuZGF0YQorbWFpbC9zcmMvb2xkdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvZGVjb2RldGVzdAorbWFpbC5zaWcKK3dlYmFwcC9idWlsZC5iYXQKK3dlYmFwcC93ZWJhcHAuUkVBRE1FLnR4dAorbG9nZ2luZy9zcmMvbWFpbi9qYXZhLworbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL2xvZ2dpbmcvCittYWlsL3NyYy9tYWluL3Jlc291cmNlcy9NRVRBLUlORi9oazItbG9jYXRvci9kZWZhdWx0CittYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3V0aWwvbG9nZ2luZy8KK21haWwvc3JjL3Rlc3QvcmVzb3VyY2VzL2phdmF4L21haWwvaW50ZXJuZXQvcGFyYW1kYXRhCittYWlsL3NyYy90ZXN0L3Jlc291cmNlcy9qYXZheC9tYWlsL2ludGVybmV0L3BhcmFtZGF0YW5vc3RyaWN0CittYWlsL3NyYy90ZXN0L3Jlc291cmNlcy9qYXZheC9tYWlsL2ludGVybmV0L3Rva2VubGlzdAorbWFpbC9zcmMvdGVzdC9yZXNvdXJjZXMvamF2YXgvbWFpbC9pbnRlcm5ldC9hZGRybGlzdAorbWFpbC9zcmMvdGVzdC9yZXNvdXJjZXMvamF2YXgvbWFpbC9pbnRlcm5ldC9NYWlsRGF0ZUZvcm1hdF9vbGQuc2VyCittYWlsL3NyYy90ZXN0L3Jlc291cmNlcy9qYXZheC9tYWlsL2ludGVybmV0L01haWxEYXRlRm9ybWF0X25ldy5zZXIKK21haWwvc3JjL21haW4vamF2YS9kb2MtZmlsZXMvc3BlY2xpY2Vuc2UuaHRtbAorYW5kcm9pZC9hY3RpdmF0aW9uL3NyYy9tYWluL3Jlc291cmNlcy9NRVRBLUlORi9taW1ldHlwZXMuZGVmYXVsdApkaWZmIC0tZ2l0IGEvZGVtby9wb20ueG1sIGIvZGVtby9wb20ueG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMyYmVjZjAKLS0tIC9kZXYvbnVsbAorKysgYi9kZW1vL3BvbS54bWwKQEAgLTAsMCArMSw4MyBAQAorPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PgorPCEtLQorCisgICAgQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisKKyAgICBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAgICB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKworICAgIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAgICBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgICAgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgICAgdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisKKyAgICBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKworLS0+CisKKzxwcm9qZWN0IHhtbG5zPSJodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9QT00vNC4wLjAiCisJeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIKKwl4c2k6c2NoZW1hTG9jYXRpb249Imh0dHA6Ly9tYXZlbi5hcGFjaGUub3JnL1BPTS80LjAuMAorCQkJICAgIGh0dHA6Ly9tYXZlbi5hcGFjaGUub3JnL21hdmVuLXY0XzBfMC54c2QiPgorICAgIDxwYXJlbnQ+CisJPGdyb3VwSWQ+Y29tLnN1bi5tYWlsPC9ncm91cElkPgorCTxhcnRpZmFjdElkPmFsbDwvYXJ0aWZhY3RJZD4KKwk8dmVyc2lvbj4xLjYuMzwvdmVyc2lvbj4KKyAgICA8L3BhcmVudD4KKyAgICA8bW9kZWxWZXJzaW9uPjQuMC4wPC9tb2RlbFZlcnNpb24+CisgICAgPGdyb3VwSWQ+Y29tLnN1bi5tYWlsPC9ncm91cElkPgorICAgIDxhcnRpZmFjdElkPmRlbW88L2FydGlmYWN0SWQ+CisgICAgPHBhY2thZ2luZz5qYXI8L3BhY2thZ2luZz4KKyAgICA8bmFtZT5KYXZhTWFpbCBBUEkgZGVtb3M8L25hbWU+CisKKyAgICA8YnVpbGQ+CisgICAgICAgIDxwbHVnaW5zPgorICAgICAgICAgICAgPHBsdWdpbj4KKyAgICAgICAgICAgICAgICA8YXJ0aWZhY3RJZD5tYXZlbi1jb21waWxlci1wbHVnaW48L2FydGlmYWN0SWQ+CisgICAgICAgICAgICAgICAgPGNvbmZpZ3VyYXRpb24+CisJCSAgICA8ZXhjbHVkZXM+CisJCQk8ZXhjbHVkZT5pbnRlcm5hbC8qKjwvZXhjbHVkZT4KKwkJICAgIDwvZXhjbHVkZXM+CisgICAgICAgICAgICAgICAgPC9jb25maWd1cmF0aW9uPgorCSAgICA8L3BsdWdpbj4KKworCSAgICA8IS0tCisJCU5lZWQgdG8gZGlzYWJsZSB0aGUgbWF2ZW4tYnVuZGxlLXBsdWdpbiBiZWNhdXNlIHRoZQorCQluZXcgdmVyc2lvbiBkb2Vzbid0IGxpa2UgY2xhc3NlcyBpbiB0aGUgZGVmYXVsdCBwYWNrYWdlLgorCSAgICAtLT4KKwkgICAgPHBsdWdpbj4KKwkJPGdyb3VwSWQ+b3JnLmFwYWNoZS5mZWxpeDwvZ3JvdXBJZD4KKwkJPGFydGlmYWN0SWQ+bWF2ZW4tYnVuZGxlLXBsdWdpbjwvYXJ0aWZhY3RJZD4KKwkJPGV4ZWN1dGlvbnM+CisJCSAgICA8ZXhlY3V0aW9uPgorCQkJPGlkPm9zZ2ktbWFuaWZlc3Q8L2lkPgorCQkJPHBoYXNlPm5vbmU8L3BoYXNlPgorCQkgICAgPC9leGVjdXRpb24+CisJCTwvZXhlY3V0aW9ucz4KKwkgICAgPC9wbHVnaW4+CisKKwkgICAgPCEtLQorCQlCZWNhdXNlIHRoZSBtYXZlbi1qYXItcGx1Z2luIGRlcGVuZHMgb24gdGhlIG1hbmlmZXN0IGZpbGUKKwkJY3JlYXRlZCBieSB0aGUgbWF2ZW4tYnVuZGxlLXBsdWdpbiwgd2UgbmVlZCB0byBkaXNhYmxlIGl0IHRvby4KKwkgICAgLS0+CisJICAgIDxwbHVnaW4+CisJCTxhcnRpZmFjdElkPm1hdmVuLWphci1wbHVnaW48L2FydGlmYWN0SWQ+CisJCTxleGVjdXRpb25zPgorCQkgICAgPGV4ZWN1dGlvbj4KKwkJCTxpZD5kZWZhdWx0LWphcjwvaWQ+CisJCQk8cGhhc2U+bm9uZTwvcGhhc2U+CisJCSAgICA8L2V4ZWN1dGlvbj4KKwkJPC9leGVjdXRpb25zPgorCSAgICA8L3BsdWdpbj4KKyAgICAgICAgPC9wbHVnaW5zPgorICAgIDwvYnVpbGQ+CisKKyAgICA8ZGVwZW5kZW5jaWVzPgorICAgICAgICA8ZGVwZW5kZW5jeT4KKyAgICAgICAgICAgIDxncm91cElkPmNvbS5zdW4ubWFpbDwvZ3JvdXBJZD4KKyAgICAgICAgICAgIDxhcnRpZmFjdElkPmpha2FydGEubWFpbDwvYXJ0aWZhY3RJZD4KKyAgICAgICAgPC9kZXBlbmRlbmN5PgorICAgIDwvZGVwZW5kZW5jaWVzPgorPC9wcm9qZWN0PgpkaWZmIC0tZ2l0IGEvZGVtby9zcmMvbWFpbi9qYXZhL0NSTEZPdXRwdXRTdHJlYW0uamF2YSBiL2RlbW8vc3JjL21haW4vamF2YS9DUkxGT3V0cHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDBjYjIzZAotLS0gL2Rldi9udWxsCisrKyBiL2RlbW8vc3JjL21haW4vamF2YS9DUkxGT3V0cHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSw3MiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgRGlzdHJpYnV0aW9uIExpY2Vuc2Ugdi4gMS4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvb3JnL2RvY3VtZW50cy9lZGwtdjEwLnBocC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQlNELTMtQ2xhdXNlCisgKi8KKworaW1wb3J0IGphdmEuaW8uKjsKKworLyoqCisgKiBDb252ZXJ0IGxpbmVzIGludG8gdGhlIGNhbm9uaWNhbCBNSU1FIGZvcm1hdCwgdGhhdCBpcywKKyAqIHRlcm1pbmF0ZSBsaW5lcyB3aXRoIENSTEYuIDxwPgorICoKKyAqIFRoaXMgc3RyZWFtIGNhbiBiZSB1c2VkIHdpdGggdGhlIFBhcnQud3JpdGVUbyBhbmQgTWVzc2FnZS53cml0ZVRvCisgKiBtZXRob2RzIHRvIGdlbmVyYXRlIHRoZSBjYW5vbmljYWwgTUlNRSBmb3JtYXQgb2YgdGhlIGRhdGEgZm9yIHRoZQorICogcHVycG9zZSBvZiAoZS5nLikgc2VuZGluZyBpdCB2aWEgU01UUCBvciBjb21wdXRpbmcgYSBkaWdpdGFsCisgKiBzaWduYXR1cmUuCisgKi8KK3B1YmxpYyBjbGFzcyBDUkxGT3V0cHV0U3RyZWFtIGV4dGVuZHMgRmlsdGVyT3V0cHV0U3RyZWFtIHsKKyAgICBwcm90ZWN0ZWQgaW50IGxhc3RiID0gLTE7CisgICAgcHJvdGVjdGVkIHN0YXRpYyBieXRlW10gbmV3bGluZTsKKyAgICBzdGF0aWMgeworCW5ld2xpbmUgPSBuZXcgYnl0ZVsyXTsKKwluZXdsaW5lWzBdID0gKGJ5dGUpJ1xyJzsKKwluZXdsaW5lWzFdID0gKGJ5dGUpJ1xuJzsKKyAgICB9CisKKyAgICBwdWJsaWMgQ1JMRk91dHB1dFN0cmVhbShPdXRwdXRTdHJlYW0gb3MpIHsKKwlzdXBlcihvcyk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGUoaW50IGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJaWYgKGIgPT0gJ1xyJykgeworCSAgICBvdXQud3JpdGUobmV3bGluZSk7CisJfSBlbHNlIGlmIChiID09ICdcbicpIHsKKwkgICAgaWYgKGxhc3RiICE9ICdccicpCisJCW91dC53cml0ZShuZXdsaW5lKTsKKwl9IGVsc2UgeworCSAgICBvdXQud3JpdGUoYik7CisJfQorCWxhc3RiID0gYjsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShieXRlIGJbXSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwl3cml0ZShiLCAwLCBiLmxlbmd0aCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGUoYnl0ZSBiW10sIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJaW50IHN0YXJ0ID0gb2ZmOworCisJbGVuICs9IG9mZjsKKwlmb3IgKGludCBpID0gc3RhcnQ7IGkgPCBsZW4gOyBpKyspIHsKKwkgICAgaWYgKGJbaV0gPT0gJ1xyJykgeworCQlvdXQud3JpdGUoYiwgc3RhcnQsIGkgLSBzdGFydCk7CisJCW91dC53cml0ZShuZXdsaW5lKTsKKwkJc3RhcnQgPSBpICsgMTsKKwkgICAgfSBlbHNlIGlmIChiW2ldID09ICdcbicpIHsKKwkJaWYgKGxhc3RiICE9ICdccicpIHsKKwkJICAgIG91dC53cml0ZShiLCBzdGFydCwgaSAtIHN0YXJ0KTsKKwkJICAgIG91dC53cml0ZShuZXdsaW5lKTsKKwkJfQorCQlzdGFydCA9IGkgKyAxOworCSAgICB9CisJICAgIGxhc3RiID0gYltpXTsKKwl9CisJaWYgKChsZW4gLSBzdGFydCkgPiAwKQorCSAgICBvdXQud3JpdGUoYiwgc3RhcnQsIGxlbiAtIHN0YXJ0KTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9kZW1vL3NyYy9tYWluL2phdmEvTmV3bGluZU91dHB1dFN0cmVhbS5qYXZhIGIvZGVtby9zcmMvbWFpbi9qYXZhL05ld2xpbmVPdXRwdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNjIwMDI5Ci0tLSAvZGV2L251bGwKKysrIGIvZGVtby9zcmMvbWFpbi9qYXZhL05ld2xpbmVPdXRwdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDYxIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBEaXN0cmlidXRpb24gTGljZW5zZSB2LiAxLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9vcmcvZG9jdW1lbnRzL2VkbC12MTAucGhwLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBCU0QtMy1DbGF1c2UKKyAqLworCitpbXBvcnQgamF2YS5pby4qOworCisvKioKKyAqIENvbnZlcnQgdGhlIHZhcmlvdXMgbmV3bGluZSBjb252ZW50aW9ucyB0byB0aGUgbG9jYWwgcGxhdGZvcm0ncworICogbmV3bGluZSBjb252ZW50aW9uLiA8cD4KKyAqCisgKiBUaGlzIHN0cmVhbSBjYW4gYmUgdXNlZCB3aXRoIHRoZSBNZXNzYWdlLndyaXRlVG8gbWV0aG9kIHRvCisgKiBnZW5lcmF0ZSBhIG1lc3NhZ2UgdGhhdCB1c2VzIHRoZSBsb2NhbCBwbGFmb3JtJ3MgbGluZSB0ZXJtaW5hdG9yCisgKiBmb3IgdGhlIHB1cnBvc2Ugb2YgKGUuZy4pIHNhdmluZyB0aGUgbWVzc2FnZSB0byBhIGxvY2FsIGZpbGUuCisgKi8KK3B1YmxpYyBjbGFzcyBOZXdsaW5lT3V0cHV0U3RyZWFtIGV4dGVuZHMgRmlsdGVyT3V0cHV0U3RyZWFtIHsKKyAgICBwcml2YXRlIGludCBsYXN0YiA9IC0xOworICAgIHByaXZhdGUgc3RhdGljIGJ5dGVbXSBuZXdsaW5lOworCisgICAgcHVibGljIE5ld2xpbmVPdXRwdXRTdHJlYW0oT3V0cHV0U3RyZWFtIG9zKSB7CisJc3VwZXIob3MpOworCWlmIChuZXdsaW5lID09IG51bGwpIHsKKwkgICAgU3RyaW5nIHMgPSBTeXN0ZW0ubGluZVNlcGFyYXRvcigpOworCSAgICBpZiAocyA9PSBudWxsIHx8IHMubGVuZ3RoKCkgPD0gMCkKKwkJcyA9ICJcbiI7CisJICAgIHRyeSB7CisJCW5ld2xpbmUgPSBzLmdldEJ5dGVzKCJpc28tODg1OS0xIik7CS8vIHJlYWxseSB1cy1hc2NpaQorCSAgICB9IGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGV4KSB7CisJCS8vIHNob3VsZCBuZXZlciBoYXBwZW4KKwkJbmV3bGluZSA9IG5ldyBieXRlW10geyAoYnl0ZSknXG4nIH07CisJICAgIH0KKwl9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGUoaW50IGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJaWYgKGIgPT0gJ1xyJykgeworCSAgICBvdXQud3JpdGUobmV3bGluZSk7CisJfSBlbHNlIGlmIChiID09ICdcbicpIHsKKwkgICAgaWYgKGxhc3RiICE9ICdccicpCisJCW91dC53cml0ZShuZXdsaW5lKTsKKwl9IGVsc2UgeworCSAgICBvdXQud3JpdGUoYik7CisJfQorCWxhc3RiID0gYjsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShieXRlIGJbXSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwl3cml0ZShiLCAwLCBiLmxlbmd0aCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGUoYnl0ZSBiW10sIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJZm9yIChpbnQgaSA9IDAgOyBpIDwgbGVuIDsgaSsrKSB7CisJICAgIHdyaXRlKGJbb2ZmICsgaV0pOworCX0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9kZW1vL3NyYy9tYWluL2phdmEvUkVBRE1FLnR4dCBiL2RlbW8vc3JjL21haW4vamF2YS9SRUFETUUudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc4MWQwNjQKLS0tIC9kZXYvbnVsbAorKysgYi9kZW1vL3NyYy9tYWluL2phdmEvUkVBRE1FLnR4dApAQCAtMCwwICsxLDM4NCBAQAorCVJFQURNRSBmb3IgdGhlIGRlbW8gcHJvZ3JhbXMgaW4gdGhpcyBkaXJlY3RvcnkKKwk9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK1RoZXNlIGRlbW8gcHJvZ3JhbXMgaWxsdXN0cmF0ZSBob3cgdG8gdXNlIHRoZSBKYXZhTWFpbCBBUEkgdG8KK3BlcmZvcm0gYSBudW1iZXIgb2YgY29tbW9uIGVtYWlsIGZ1bmN0aW9ucy4gIE5vdGUgdGhlc2UgdGhlc2UKK3Byb2dyYW1zIGFyZSBub3QgaW50ZW5kZWQgdG8gYmUgZXhhbXBsZXMgb2YgZ29vZCB1c2VyIGludGVyZmFjZXMsCitvciBnb29kIGNvbW1hbmQgbGluZSBpbnRlcmZhY2VzLiAgTm8gb25lIGlzIGV4cGVjdGVkIHRvIGFjdHVhbGx5CisqdXNlKiB0aGVzZSBwcm9ncmFtcyBmb3IgYW55dGhpbmcgcmVhbC4gIFJhdGhlciwgdGhlaXIgdmFsdWUgaXMKK2luIHRoZSBzb3VyY2UgY29kZS4gIERvbid0IGxvb2sgYXQgdGhlaXIgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworb3IgdXNlciBpbnRlcmZhY2UgdG8gZmlndXJlIG91dCB3aGF0IEphdmFNYWlsIGNhbiBkbywgbG9vayBhdAordGhlaXIgc291cmNlIGNvZGUuICBXZSBzdHJvbmdseSByZWNvbW1lbmQgdGhhdCB5b3UgcmVhZCB0aGUKK3NvdXJjZSBjb2RlIGFuZCB1bmRlcnN0YW5kIHdoYXQgdGhlc2UgcHJvZ3JhbXMgYXJlIGRvaW5nIGJlZm9yZQorcnVubmluZyB0aGVtLgorCitBbGwgb2YgdGhlc2UgcHJvZ3JhbXMgYXJlIHNpbXBsZSBjb21tYW5kIGxpbmUgdG9vbHMgd2l0aCBhIFVOSVgKK3N0eWxlIGludGVyZmFjZS4gIE9uIFdpbmRvd3MgeW91J2xsIG5lZWQgdG8gcnVuIHRoZW0gaW4gYW4gTVMtRE9TCit3aW5kb3cuICBXZSBhcG9sb2dpemUgaW4gYWR2YW5jZSBmb3IgdGhlIGluY29uc2lzdGVuY3kgaW4gaG93IHRoZXNlCitwcm9ncmFtcyBhY2NlcHQgb3B0aW9ucy4gIFRoZXJlIGFyZSBnZW5lcmFsbHkgdHdvIHN0eWxlcy4gIFRoZSB2ZXJ5CitzaW1wbGUgc3R5bGUgKGUuZy4sIGFzIHVzZWQgYnkgY29waWVyLmphdmEpIHJlcXVpcmVzIGEgZml4ZWQgbnVtYmVyCitvZiBhcmd1bWVudHMgaW4gYSBmaXhlZCBvcmRlci4gIE90aGVycyAoZS5nLiwgZm9sZGVybGlzdC5qYXZhKSB0YWtlCitVTklYLXN0eWxlIG9wdGlvbnMsIG1hbnkgb2Ygd2hpY2ggYXJlIG9wdGlvbmFsLCBhbmQgd2hpY2ggbWF5IGFwcGVhcgoraW4gYW55IG9yZGVyLiAgVGhlIGZvbGxvd2luZyBub3RlcyBzaG91bGQgaGVscCB5b3UgZmlndXJlIGl0IG91dCwKK2J1dCBpZiBpbiBkb3VidCwgcmVhZCB0aGUgc291cmNlIGNvZGUuCisKKworCistIGNvcGllci5qYXZhCisKKwlUaGlzIHByb2dyYW0gY29waWVzIHRoZSBzcGVjaWZpZWQgbWVzc2FnZXMgZnJvbSBvbmUgZm9sZGVyIHRvCisJYW5vdGhlci4gQm90aCBmb2xkZXJzIG11c3QgYmVsb25nIHRvIHRoZSBzYW1lIHN0b3JlLgorCisgIFVzYWdlOgorCWphdmEgY29waWVyIDx1cmxuYW1lPiA8c3JjPiA8ZGVzdD4gPHN0YXJ0PiA8ZW5kPgorCisgIEFyZ3VtZW50cyAoaW4gb3JkZXIpOgorCisgIDx1cmxuYW1lPgk6IFVSTCBvZiB0aGUgU3RvcmUuIFRoZSBVUkwgc2hvdWxkIGluY2x1ZGUKKwkJICB0aGUgcGFzc3dvcmQgYXMgd2VsbCAoaWYgbmVlZGVkKS4KKwkJICBFeGFtcGxlOiAiaW1hcDovL2pvaG46cGFzc3dvcmRAbWFpbHN0b3JlLmNvbSIKKworICA8c3JjPgkJOiBzb3VyY2UgZm9sZGVyCisgIDxkZXN0Pgk6IGRlc3RpbmF0aW9uIGZvbGRlcgorICA8c3RhcnQ+CTogc3RhcnQgbWVzc2FnZSBudW1iZXIKKyAgPGVuZD4JCTogZW5kIG1lc3NhZ2UgbnVtYmVyCisKKworLSBmb2xkZXJsaXN0LmphdmEKKworCVRoaXMgcHJvZ3JhbSBsaXN0cyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgZm9sZGVycyBpbiBhIFN0b3JlLgorCisgICBVc2FnZToKKwlqYXZhIGZvbGRlcmxpc3QgLUwgPHVybD4gLVQgPHByb3RvY29sPiAtSCA8aG9zdD4gLVUgPHVzZXI+IC1QIDxwYXNzd2Q+CisJCSAgIFstUiA8cm9vdD5dIFstcl0gWy12XSBbLURdIDxwYXR0ZXJuPgorCisgICBPcHRpb25zOgorCisgICAtTCA8dXJsPgk6IFVSTCBvZiB0aGUgU3RvcmUuIFRoZSBVUkwgc2hvdWxkIGluY2x1ZGUKKwkJICB0aGUgcGFzc3dvcmQgYXMgd2VsbCAoaWYgbmVlZGVkKS4KKwkJICBFeGFtcGxlOiAiaW1hcDovL2pvaG46cGFzc3dvcmRAbWFpbHN0b3JlLmNvbSIKKyAgIC1UIDxwcm90b2NvbD4gOiBzdG9yZSBwcm90b2NvbCAoRXg6ICJpbWFwIikKKyAgIC1IIDxob3N0Pgk6IGhvc3RuYW1lIG9mIHN0b3JlLgorICAgLVUgPHVzZXI+CTogdXNlcm5hbWUgKGlmIG5lZWRlZCkKKyAgIC1QIDxwYXNzd2Q+CTogcGFzc3dvcmQgKGlmIG5lZWRlZCkKKyAgIC1SIDxyb290Pgk6IHJvb3Qgb2YgdGhlIGZvbGRlciBoaWVyYXJjaHkuIFRoaXMgaXMgb3B0aW9uYWwuIElmCisJCSAgbm90IHByZXNlbnQsIGxpc3Rpbmcgc3RhcnRzIGZyb20gdGhlIGRlZmF1bHQgZm9sZGVyLgorICAgLXIJCTogbGlzdCByZWN1cnNpdmVseSAtIGZvbGRlciBhbmQgYWxsIHN1YmZvbGRlcnMuCisgICAtdgkJOiB2ZXJib3NlIC0gc2hvdyBtb3JlIGluZm8gYWJvdXQgZWFjaCBmb2xkZXIuCisgICAtRAkJOiBUdXJuIG9uIHNlc3Npb24gZGVidWdnaW5nCisgICA8cGF0dGVybj4JOiBmb2xkZXJzIHRoYXQgbWF0Y2ggdGhpcyBwYXR0ZXJuIGFyZSBsaXN0ZWQuIFVzZSAiKiIKKwkJICBhcyB3aWxkY2FyZCB0byBtYXRjaCBldmVyeXRoaW5nLgorCisKKy0gbW9uaXRvci5qYXZhCisKKwlJbGx1c3RyYXRlcyBob3cgdG8gbW9uaXRvciBhIGZvbGRlciBmb3IgaW50ZXJlc3RpbmcgZXZlbnRzLAorCWxpa2UgbmV3IG1haWwgYXJyaXZhbC4KKworICAgVXNhZ2U6CisJamF2YSBtb25pdG9yIDxob3N0PiA8dXNlcj4gPHBhc3N3b3JkPiA8bWJveD4gPGZyZXE+CisKKyAgIEFyZ3VtZW50cyAoaW4gb3JkZXIpOgorCisgICA8aG9zdD4JOiBob3N0bmFtZSBvZiBzdG9yZS4KKyAgIDx1c2VyPgk6IHVzZXJuYW1lIChpZiBuZWVkZWQpCisgICA8cGFzc3dkPgk6IHBhc3N3b3JkIChpZiBuZWVkZWQpCisgICA8bWJveD4JOiBmb2xkZXIgdG8gbW9uaXRvcgorICAgPGZyZXE+CTogZnJlcXVlbmN5IG9mIG1vbml0b3JpbmcKKworCistIG1vdmVyLmphdmEKKworCU1vdmVzIG1lc3NhZ2VzIGJldHdlZW4gZm9sZGVycy4gIFRoZSBmb2xkZXJzIG11c3QgYmVsb25nIHRvIHRoZQorCXNhbWUgc3RvcmUuCisKKyAgIFVzYWdlOgorCWphdmEgbW92ZXIgLVQgPHByb3RvY29sPiAtSCA8aG9zdD4gLVUgPHVzZXI+IC1QIDxwYXNzd2Q+IFstdl0KKwkJLXMgPHNyYz4gLWQgPGRlc3Q+IFsteF0gPHN0YXJ0PiA8ZW5kPgorCisgICBPcHRpb25zOgorCisgICAtVCA8cHJvdG9jb2w+IDogc3RvcmUgcHJvdG9jb2wgKEV4OiAiaW1hcCIpCisgICAtSCA8aG9zdD4JOiBob3N0bmFtZSBvZiBzdG9yZS4KKyAgIC1VIDx1c2VyPgk6IHVzZXJuYW1lIChpZiBuZWVkZWQpCisgICAtUCA8cGFzc3dkPgk6IHBhc3N3b3JkIChpZiBuZWVkZWQpCisgICAtcyA8c3JjPgk6IHNvdXJjZSBmb2xkZXIKKyAgIC1kIDxkZXN0Pgk6IGRlc3RpbmF0aW9uIGZvbGRlcgorICAgLXYJCTogT3B0aW9uYWwgdmVyYm9zZSBvcHRpb24KKyAgIC14CQk6IE9wdGlvbmFsIGV4cHVuZ2Ugb3B0aW9uLCB0byBleHB1bmdlIHRoZSBkZWxldGVkCisJCSAgbWVzc2FnZXMgZnJvbSBzcmMKKworICAgQXJndW1lbnRzIChpbiBvcmRlcik6CisKKyAgIDxzdGFydD4JOiBzdGFydCBtZXNzYWdlIG51bWJlcgorICAgPGVuZD4JOiBlbmQgbWVzc2FnZSBudW1iZXIKKworCistIG1zZ211bHRpc2VuZHNhbXBsZS5qYXZhCisKKwlEZW1vbnN0cmF0ZXMgaG93IHRvIGNvbnN0cnVjdCBhbmQgc2VuZCBhIG11bHRpcGFydCBtZXNzYWdlLgorCisgICBVc2FnZToKKwlqYXZhIG1zZ211bHRpc2VuZHNhbXBsZSA8dG8+IDxmcm9tPiA8c210cGhvc3Q+IHRydWV8ZmFsc2UKKworICAgQXJndW1lbnRzIChpbiBvcmRlcik6CisKKyAgIDx0bz4JCTogUmVjaXBpZW50IGFkZHJlc3MKKyAgIDxmcm9tPgk6IFNlbmRlciBhZGRyZXNzCisgICA8c210cGhvc3Q+CTogbmFtZSBvZiBTTVRQIHNlcnZlcgorICAgdHJ1ZXxmYWxzZQk6ICJ0cnVlIiB0byB0dXJuIG9uIHNlc3Npb24gZGVidWdnaW5nLCAiZmFsc2UiIG90aGVyd2lzZQorCisKKy0gbXNnc2VuZC5qYXZhCisKKwlTZW5kIGEgc2ltcGxlIHRleHQgbWVzc2FnZS4gT3B0aW9uYWxseSBzYXZlcyBhIGNvcHkKKwlvZiB0aGUgb3V0Z29pbmcgbWVzc2FnZSBpbiBhIGZvbGRlciAocmVjb3JkLWZvbGRlcikuCisKKwlNb3N0IHBhcmFtZXRlcnMgdG8gdGhpcyBwcm9ncmFtIGFyZSBvcHRpb25hbC4gV2hlbgorCXRoZSBwcm9ncmFtIGlzIHJ1biwgaXQgaW50ZXJhY3RpdmVseSBhc2tzIGZvcgorCXRoZSAiVG8iIGFuZCAiU3ViamVjdCIgZmllbGRzIGlmIG5vdCBhbHJlYWR5IGF2YWlsYWJsZS4KKwlUaGVuIHRoZSBwcm9ncmFtIGV4cGVjdHMgdGhlIGJvZHkgb2YgdGhlIG1lc3NhZ2UuCisJQWZ0ZXIgeW91IHR5cGUgaW4gdGhlIGJvZHksIGhpdCBDdHJsLUQgb24gVW5peAorCXN5c3RlbXMgb3IgQ3RybC1aIG9uIFdpbmRvd3Mgc3lzdGVtcyB0byBzZW5kCisJdGhlIG1lc3NhZ2UuCisKKyAgIFVzYWdlOgorCWphdmEgbXNnc2VuZCAtTCA8c3RvcmUtdXJsPiAtVCA8cHJvdG9jb2w+IC1IIDxob3N0PiAtVSA8dXNlcj4KKwkJLVAgPHBhc3N3ZD4gLXMgPHN1YmplY3Q+IC1vIDxmcm9tPiAtYyA8Y2M+IC1iIDxiY2M+CisJCS1mIDxyZWNvcmQ+IC1NIDxzbXRwaG9zdD4gWy1kXSA8dG8+CisKKyAgIE9wdGlvbnM6CisKKyAgIC1MIDxzdG9yZS11cmw+IDogVVJMIG9mIHRoZSBzdG9yZSBmb3IgdGhlIHJlY29yZC1mb2xkZXIKKyAgIC1UIDxwcm90b2NvbD4gOiBJZiA8c3RvcmUtdXJsPiBpcyBub3QgcHJlc2VudCwgdGhpcyBpbmRpY2F0ZXMKKwkJICB0aGUgc3RvcmUgcHJvdG9jb2wgZm9yIHRoZSByZWNvcmQtZm9sZGVyLgorICAgLUggPGhvc3Q+CTogSWYgPHN0b3JlLXVybD4gaXMgbm90IHByZXNlbnQsIHRoaXMgaW5kaWNhdGVzCisJCSAgdGhlIGhvc3RuYW1lIGZvciB0aGUgcmVjb3JkLWZvbGRlci4KKyAgIC1VIDx1c2VyPgk6IElmIDxzdG9yZS11cmw+IGlzIG5vdCBwcmVzZW50LCB0aGlzIGluZGljYXRlcworCQkgIHRoZSB1c2VybmFtZSBmb3IgdGhlIHJlY29yZC1mb2xkZXIuCisgICAtUCA8cGFzc3dkPgk6IElmIDxzdG9yZS11cmw+IGlzIG5vdCBwcmVzZW50LCB0aGlzIGluZGljYXRlcworCQkgIHRoZSBwYXNzd29yZCBmb3IgdGhlIHJlY29yZC1mb2xkZXIuCisgICAtZiA8cmVjb3JkPgk6IG5hbWUgb2YgcmVjb3JkLWZvbGRlci4KKyAgIC1NIDxzbXRwaG9zdD4gOiBIb3N0IG5hbWUgb2YgU01UUCBzZXJ2ZXIuICBEZWZhdWx0cyB0byAibG9jYWxob3N0IgorCQkgIHdoaWNoIG9mdGVuIHdvcmtzIG9uIFVOSVggYnV0IHJhcmVseSBvbiBXaW5kb3dzLgorICAgLXMgPHN1YmplY3Q+CTogU3ViamVjdCBvZiBtZXNzYWdlIHRvIGJlIHNlbnQKKyAgIC1vIDxmcm9tPgk6IEZyb20gYWRkcmVzcyBvZiBtZXNzYWdlIHRvIGJlIHNlbnQKKyAgIC1jIDxjYz4JOiBDYyBhZGRyZXNzIG9mIG1lc3NhZ2UgdG8gYmUgc2VudAorICAgLWIgPGJjYz4JOiBCY2MgYWRkcmVzcyBvZiBtZXNzYWdlIHRvIGJlIHNlbnQKKyAgIC1kCQk6IFR1cm4gb24gc2Vzc2lvbiBkZWJ1Z2dpbmcuCisgICAtYSA8ZmlsZT4JOiBJbmNsdWRlIGZpbGUgYXMgYW4gYXR0YWNobWVudCB3aXRoIHRoZSBtZXNzYWdlCisKKyAgIEFyZ3VtZW50OgorCisgICA8dG8+CQk6IFRvIGFkZHJlc3Mgb2YgbWVzc2FnZSB0byBiZSBzZW50CisKKworLSBtc2dzZW5kc2FtcGxlLmphdmEKKworCURlbW9uc3RyYXRlcyBob3cgdG8gY29uc3RydWN0IGFuZCBzZW5kIGEgc2ltcGxlIHRleHQgbWVzc2FnZS4KKworICAgVXNhZ2U6CisJamF2YSBtc2dzZW5kc2FtcGxlIDx0bz4gPGZyb20+IDxzbXRwaG9zdD4gdHJ1ZXxmYWxzZQorCisgICBBcmd1bWVudHMgKGluIG9yZGVyKToKKworICAgPHRvPgkJOiBSZWNpcGllbnQgYWRkcmVzcworICAgPGZyb20+CTogU2VuZGVyIGFkZHJlc3MKKyAgIDxzbXRwaG9zdD4JOiBuYW1lIG9mIFNNVFAgc2VydmVyCisgICB0cnVlfGZhbHNlCTogInRydWUiIHRvIHR1cm4gb24gc2Vzc2lvbiBkZWJ1Z2dpbmcsICJmYWxzZSIgb3RoZXJ3aXNlCisKKworLSBtc2dzaG93LmphdmEKKworCURpc3BsYXlzIG1lc3NhZ2UocykgZnJvbSBhIGZvbGRlciBvciBmcm9tIHN0ZGluLgorCisgICBVc2FnZToKKwlqYXZhIG1zZ3Nob3cgLUwgPHVybD4gLVQgPHByb3RvY29sPiAtSCA8aG9zdD4gLXAgPHBvcnQ+CisJCS1VIDx1c2VyPiAtUCA8cGFzc3dvcmQ+IC1mIDxtYWlsYm94PgorCQlbLURdIFstc10gWy1TXSBbLWFdIFstdl0gW21zZ251bV0KKwlqYXZhIG1zZ3Nob3cgLW0gWy1EXSBbLXNdIFstU10gWy12XQorCisgICBPcHRpb25zOgorCisgICAtTCA8dXJsPgk6IFVSTCBvZiB0aGUgU3RvcmUuIFRoZSBVUkwgc2hvdWxkIGluY2x1ZGUKKwkJICB0aGUgcGFzc3dvcmQgYXMgd2VsbCAoaWYgbmVlZGVkKS4KKwkJICBFeGFtcGxlOiAiaW1hcDovL2pvaG46cGFzc3dvcmRAbWFpbHN0b3JlLmNvbSIKKyAgIC1UIDxwcm90b2NvbD4gOiBJZiA8dXJsPiBpcyBub3QgcHJlc2VudCwgdGhpcyBpbmRpY2F0ZXMKKwkJICB0aGUgc3RvcmUgcHJvdG9jb2wKKyAgIC1IIDxob3N0Pgk6IElmIDx1cmw+IGlzIG5vdCBwcmVzZW50LCB0aGlzIGluZGljYXRlcworCQkgIHRoZSBob3N0bmFtZQorICAgLXAgPHBvcnQ+CTogSWYgPHVybD4gaXMgbm90IHByZXNlbnQsIHRoaXMgaW5kaWNhdGVzCisJCSAgdGhlIHBvcnQgbnVtYmVyICh1c3VhbGx5IG5vdCBuZWVkZWQpCisgICAtVSA8dXNlcj4JOiBJZiA8dXJsPiBpcyBub3QgcHJlc2VudCwgdGhpcyBpbmRpY2F0ZXMKKwkJICB0aGUgdXNlcm5hbWUKKyAgIC1QIDxwYXNzd2Q+CTogSWYgPHVybD4gaXMgbm90IHByZXNlbnQsIHRoaXMgaW5kaWNhdGVzCisJCSAgdGhlIHBhc3N3b3JkCisgICAtZiA8bWFpbGJveD4JOiBGb2xkZXIgdG8gb3BlbgorICAgLW0JCTogUmVhZCBtZXNzYWdlIGZyb20gc3RhbmRhcmQgaW5wdXQKKyAgIC1ECQk6IFR1cm4gb24gc2Vzc2lvbiBkZWJ1Z2dpbmcKKyAgIC1zCQk6IFNob3cgdGhlIHN0cnVjdHVyZSBvZiB0aGUgbWVzc2FnZSwgYnV0IG5vdCB0aGUgY29udGVudHMKKyAgIC1TCQk6IFNhdmUgYXR0YWNobWVudHMgdG8gYXBwcm9wcmlhdGVseSBuYW1lZCBmaWxlcworICAgLWEJCTogU2hvdyBBTEVSVFMgYW5kIE5PVElGSUNBVElPTlMgZnJvbSB0aGUgU3RvcmUKKyAgIC12CQk6IFZlcmJvc2UgbW9kZSAtIHNob3cgdG90YWwgbWVzc2FnZXMgYW5kIG51bWJlciBvZiBuZXcgbWVzc2FnZXMKKworICAgQXJndW1lbnQ6CisKKyAgIDxtc2dudW0+CTogdGhlIG1lc3NhZ2UgdG8gYmUgZGlzcGxheWVkLiBJZiB0aGlzCisgIAkJICBwYXJhbWV0ZXIgaXMgbm90IHByZXNlbnQsIGFsbCBtZXNzYWdlcyBpbiB0aGUKKwkJICBmb2xkZXIgYXJlIGRpc3BsYXllZC4KKworCistIG5hbWVzcGFjZS5qYXZhCisKKwlEaXNwbGF5cyB0aGUgbmFtZXNwYWNlcyBzdXBwb3J0ZWQgYnkgYSBzdG9yZS4KKworICAgVXNhZ2U6CisJamF2YSBuYW1lc3BhY2UgLUwgPHVybD4gLVQgPHByb3RvY29sPiAtSCA8aG9zdD4gLXAgPHBvcnQ+CisJCS1VIDx1c2VyPiAtUCA8cGFzc3dvcmQ+IFstRF0KKworICAgT3B0aW9uczoKKworICAgLUwgPHVybD4JOiBVUkwgb2YgdGhlIFN0b3JlLiBUaGUgVVJMIHNob3VsZCBpbmNsdWRlCisJCSAgdGhlIHBhc3N3b3JkIGFzIHdlbGwgKGlmIG5lZWRlZCkuCisJCSAgRXhhbXBsZTogImltYXA6Ly9qb2huOnBhc3N3b3JkQG1haWxzdG9yZS5jb20iCisgICAtVCA8cHJvdG9jb2w+IDogSWYgPHVybD4gaXMgbm90IHByZXNlbnQsIHRoaXMgaW5kaWNhdGVzCisJCSAgdGhlIHN0b3JlIHByb3RvY29sCisgICAtSCA8aG9zdD4JOiBJZiA8dXJsPiBpcyBub3QgcHJlc2VudCwgdGhpcyBpbmRpY2F0ZXMKKwkJICB0aGUgaG9zdG5hbWUKKyAgIC1wIDxwb3J0Pgk6IElmIDx1cmw+IGlzIG5vdCBwcmVzZW50LCB0aGlzIGluZGljYXRlcworCQkgIHRoZSBwb3J0IG51bWJlciAodXN1YWxseSBub3QgbmVlZGVkKQorICAgLVUgPHVzZXI+CTogSWYgPHVybD4gaXMgbm90IHByZXNlbnQsIHRoaXMgaW5kaWNhdGVzCisJCSAgdGhlIHVzZXJuYW1lCisgICAtUCA8cGFzc3dkPgk6IElmIDx1cmw+IGlzIG5vdCBwcmVzZW50LCB0aGlzIGluZGljYXRlcworCQkgIHRoZSBwYXNzd29yZAorICAgLUQJCTogVHVybiBvbiBzZXNzaW9uIGRlYnVnZ2luZworCisKKy0gcG9wdWxhdGUuamF2YQorCisJQ29waWVzIGFuIGVudGlyZSBmb2xkZXIgaGllcmFyY2h5IGZyb20gb25lIG1lc3NhZ2Ugc3RvcmUgdG8KKwlhbm90aGVyLgorCisgICBVc2FnZToKKwlqYXZhIHBvcHVsYXRlIC1zIDxzcmMtdXJsPiAtZCA8ZGVzdC11cmw+IC1EIC1mCisKKyAgIE9wdGlvbnM6CisKKyAgIC1zIDxzcmMtdXJsPgk6IFVSTCBvZiBzb3VyY2UgZm9sZGVyCisgICAtZCA8ZGVzdC11cmw+IDogVVJMIG9mIGRlc3RpbmF0aW9uIGZvbGRlcgorICAgLUQJCTogVHVybiBvbiBzZXNzaW9uIGRlYnVnZ2luZworICAgLWYJCTogZm9yY2UgdGhlIGNvcHkgdG8gb2NjdXIgZXZlbiBpZiB0aGUgZGVzdGluYXRpb24KKwkJICBmb2xkZXIgYWxyZWFkeSBleGlzdHMKKyAgIC1TCQk6IHNraXAgc3BlY2lhbCBmb2xkZXJzIG5hbWVkICJTQ0NTIiwgIkRyYWZ0cyIsICJUcmFzaCIsIGFuZAorCQkgICJTaGFyZWQgRm9sZGVycyIKKyAgIC1jCQk6IGNsZWFyIG91dCBvbGQgZm9sZGVycyBiZWZvcmUgY29weWluZyBtZXNzYWdlcworICAgLVAJCTogZG9uJ3QgcHJlc2VydmUgZmxhZ3Mgd2hlbiBjb3B5aW5nIG1lc3NhZ2VzCisKKworLSByZWdpc3RyeS5qYXZhCisKKwlEZW1vbnN0cmF0ZXMgaG93IHRvIHF1ZXJ5IHRoZSBKYXZhTWFpbCAicmVnaXN0cnkiIGZvciBwcm92aWRlcnMsCisJc2V0IGRlZmF1bHQgcHJvdmlkZXJzLCBldGMuCisKKyAgIFVzYWdlOgorCWphdmEgcmVnaXN0cnkKKworCistIHNlYXJjaC5qYXZhCisKKwlTZWFyY2ggdGhlIGdpdmVuIGZvbGRlciBmb3IgbWVzc2FnZXMgbWF0Y2hpbmcgdGhlCisJZ2l2ZW4gY3JpdGVyaWEuICBJbGx1c3RyYXRlcyB0aGUgdXNlIG9mIHRoZQorCWphdmF4Lm1haWwuc2VhcmNoIHBhY2thZ2UuCisKKyAgIFVzYWdlOgorCWphdmEgc2VhcmNoIC1MIDx1cmw+IC1UIDxwcm90PiAtSCA8aG9zdD4gLVUgPHVzZXI+IC1QIDxwYXNzd2Q+CisJCS1mIDxmb2xkZXI+IC1zdWJqZWN0IDxzdWJqZWN0PiAtZnJvbSA8ZnJvbT4KKwkJLXRvZGF5IC1vcgorCisgICBPcHRpb25zOgorCisgICAtTCA8dXJsPgk6IFVSTCBvZiB0aGUgc3RvcmUKKyAgIC1UIDxwcm90b2NvbD4gOiBJZiA8dXJsPiBpcyBub3QgcHJlc2VudCwgdGhpcyBpbmRpY2F0ZXMKKwkJICB0aGUgc3RvcmUgcHJvdG9jb2wKKyAgIC1IIDxob3N0Pgk6IElmIDx1cmw+IGlzIG5vdCBwcmVzZW50LCB0aGlzIGluZGljYXRlcworCQkgIHRoZSBob3N0bmFtZQorICAgLVUgPHVzZXI+CTogSWYgPHVybD4gaXMgbm90IHByZXNlbnQsIHRoaXMgaW5kaWNhdGVzCisJCSAgdGhlIHVzZXJuYW1lCisgICAtUCA8cGFzc3dkPgk6IElmIDx1cmw+IGlzIG5vdCBwcmVzZW50LCB0aGlzIGluZGljYXRlcworCQkgIHRoZSBwYXNzd29yZAorICAgLWYgPGZvbGRlcj4JOiBmb2xkZXIgdG8gc2VhcmNoCisKKyAgIC1vcgkJOiBJZiB0aGlzIGZsYWcgaXMgcHJlc2VudCwgdGhlIHNlYXJjaCB3aWxsCisJCSAgcmV0dXJuIG1lc3NhZ2VzIHRoYXQgbWF0Y2ggYW55IG9uZSBvZiB0aGUKKwkJICBiZWxvdyBjcml0ZXJpYS4gRWxzZSB0aGUgc2VhcmNoIHdpbGwgb25seQorCQkgIHJldHVybiBtZXNzYWdlcyB0aGF0IG1hdGNoIGFsbCB0aGUgY3JpdGVyaWEKKworICAgLXN1YmplY3QgPHN1YmplY3Q+CTogc2VhcmNoIGZvciBtZXNzYWdlcyBjb250YWluaW5nIHRoaXMgc3RyaW5nCisJCQkgIGFzIHRoZSBTdWJqZWN0CisgICAtZnJvbSA8ZnJvbT4JCTogc2VhcmNoIGZvciBtZXNzYWdlcyBjb250YWluaW5nIHRoaXMgc3RyaW5nCisJCQkgIGFzIHRoZSBGcm9tIGFkZHJlc3MKKyAgIC10b2RheQkJOiBzZWFyY2ggZm9yIG1lc3NhZ2VzIHJlY2VpdmVkIHRvZGF5CisKKworLSBzZW5kZmlsZS5qYXZhCisKKwlTZW5kIHRoZSBzcGVjaWZpZWQgZmlsZSB0byB0aGUgZ2l2ZW4gYWRkcmVzcy4gIFRoZSBmaWxlCisJaXMgc2VudCBhcyBhbiBhdHRhY2htZW50LiAgQW4gU01UUCBzZXJ2ZXIgbXVzdCBiZSBhdmFpbGFibGUuCisKKyAgIFVzYWdlOgorCWphdmEgc2VuZGZpbGUgPHRvPiA8ZnJvbT4gPHNtdHBob3N0PiA8ZmlsZT4gdHJ1ZXxmYWxzZQorCisgICBBcmd1bWVudHMgKGluIG9yZGVyKToKKworICAgPHRvPgkJOiBSZWNpcGllbnQgYWRkcmVzcworICAgPGZyb20+CTogU2VuZGVyIGFkZHJlc3MKKyAgIDxzbXRwaG9zdD4JOiBuYW1lIG9mIFNNVFAgc2VydmVyCisgICA8ZmlsZT4JOiBuYW1lIG9mIGZpbGUgdG8gYmUgc2VudAorICAgdHJ1ZXxmYWxzZQk6ICJ0cnVlIiB0byB0dXJuIG9uIHNlc3Npb24gZGVidWdnaW5nLCAiZmFsc2UiIG90aGVyd2lzZQorCisKKy0gc2VuZGh0bWwuamF2YQorCisJVGhlIHNlbmRodG1sIHByb2dyYW0gd29ya3MgbGlrZSB0aGUgbXNnc2VuZCBwcm9ncmFtLCB0YWtpbmcKKwl0aGUgc2FtZSBvcHRpb25zIGFuZCBpbnB1dCwgYnV0IHRoZSB0ZXh0IGNvbGxlY3RlZCBmcm9tIHRoZQorCXVzZXIgaXMgc2VudCBhcyB0eXBlICJ0ZXh0L2h0bWwiIGluc3RlYWQgb2YgInRleHQvcGxhaW4iLgorCisJVGhpcyBwcm9ncmFtIGlzIGEgZ29vZCBleGFtcGxlIG9mIGhvdyB0byBzZW5kIGFyYml0cmFyeQorCXN0cmluZyBkYXRhIGFzIGFueSBhcmJpdHJhcnkgTUlNRSB0eXBlLgorCisKKy0gc210cHNlbmQuamF2YQorCisJVGFrZXMgdGhlIHNhbWUgb3B0aW9ucyBhcyB0aGUgbXNnc2VuZCBwcm9ncmFtLCBidXQgaWxsdXN0cmF0ZXMKKwlob3cgdG8gaGFuZGxlIFNNVFAtc3BlY2lmaWMgZXJyb3IgY29kZXMuICBBbHNvIGFjY2VwdHMgdGhlCisJZm9sbG93aW5nIG9wdGlvbnM6CisKKyAgIE9wdGlvbjoKKworICAgLXYJCTogdmVyYm9zZSBvdXRwdXQKKyAgIC1BCQk6IHVzZSBTTVRQIGF1dGhlbnRpY2F0aW9uCisgICAtUwkJOiB1c2UgU1NMCisKKy0gdHJhbnNwb3J0LmphdmEKKworCUlsbHVzdHJhdGVzIGhvdyB0byB1c2UgYW4gZXhwbGljaXQgVHJhbnNwb3J0IG9iamVjdCwgaG93IHRvCisJaGFuZGxlIHRyYW5zcG9ydCBleGNlcHRpb25zLCBhbmQgaG93IHRvIGhhbmRsZSB0cmFuc3BvcnQgZXZlbnRzLgorCisgICBVc2FnZToKKwlqYXZhIHRyYW5zcG9ydCA8dG8+IDxmcm9tPiA8c210cGhvc3Q+IDxmaWxlPiB0cnVlfGZhbHNlCisKKyAgIEFyZ3VtZW50cyAoaW4gb3JkZXIpOgorCisgICA8dG8+CQk6IFJlY2lwaWVudCBhZGRyZXNzCisgICA8ZnJvbT4JOiBTZW5kZXIgYWRkcmVzcworICAgPHNtdHBob3N0Pgk6IG5hbWUgb2YgU01UUCBzZXJ2ZXIKKyAgIDxmaWxlPgk6IG5hbWUgb2YgZmlsZSB0byBiZSBzZW50CisgICB0cnVlfGZhbHNlCTogInRydWUiIHRvIHR1cm4gb24gc2Vzc2lvbiBkZWJ1Z2dpbmcsICJmYWxzZSIgb3RoZXJ3aXNlCisKKworLSB1aWRtc2dzaG93LmphdmEKKworCVRoZSB1aWRtc2dzaG93IHByb2dyYW0gd29ya3MgbGlrZSB0aGUgbXNnc2hvdyBwcm9ncmFtLCB0YWtpbmcKKwl0aGUgc2FtZSBvcHRpb25zLCBleGNlcHQgaW5zdGVhZCBvZiB1c2luZyBtZXNzYWdlIG51bWJlcnMsIGl0CisJdXNlcyBtZXNzYWdlIFVJRCdzLiAgVGhpcyB3aWxsIHR5cGljYWxseSBvbmx5IHdvcmsgd2l0aCBJTUFQCisJbWVzc2FnZSBzdG9yZXMuCmRpZmYgLS1naXQgYS9kZW1vL3NyYy9tYWluL2phdmEvY29waWVyLmphdmEgYi9kZW1vL3NyYy9tYWluL2phdmEvY29waWVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGJjZTNmNwotLS0gL2Rldi9udWxsCisrKyBiL2RlbW8vc3JjL21haW4vamF2YS9jb3BpZXIuamF2YQpAQCAtMCwwICsxLDkwIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk2LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBEaXN0cmlidXRpb24gTGljZW5zZSB2LiAxLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9vcmcvZG9jdW1lbnRzL2VkbC12MTAucGhwLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBCU0QtMy1DbGF1c2UKKyAqLworCisvKioKKyAqCisgKiBAYXV0aG9yCUNocmlzdG9waGVyIENvdHRvbgorICovCisKK2ltcG9ydCBqYXZheC5tYWlsLio7CisKKy8qKgorICogY29waWVyIHdpbGwgY29weSBhIHNwZWNpZmllZCBudW1iZXIgb2YgbWVzc2FnZXMgZnJvbSBvbmUgZm9sZGVyCisgKiB0byBhbm90aGVyIGZvbGRlci4gaXQgZGVtb25zdHJhdGVzIGhvdyB0byB1c2UgdGhlIEphdmFNYWlsIEFQSXMKKyAqIHRvIGNvcHkgbWVzc2FnZXMuPHA+CisgKgorICogVXNhZ2UgZm9yIGNvcGllcjogY29waWVyIDxpPnN0b3JlIHVybG5hbWU8L2k+IAorICogPGk+c3JjIGZvbGRlcjwvaT4gPGk+ZGVzdCBmb2xkZXI8L2k+IDxpPnN0YXJ0IG1zZyAjPC9pPiA8aT5lbmQgbXNnICM8L2k+PHA+CisgKgorICovCisKK3B1YmxpYyBjbGFzcyBjb3BpZXIgeworCisgICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nIGFyZ3ZbXSkgeworCWJvb2xlYW4gZGVidWcgPSBmYWxzZTsJLy8gY2hhbmdlIHRvIGdldCBtb3JlIGVycm9ycworCQorCWlmIChhcmd2Lmxlbmd0aCAhPSA1KSB7CisJICAgIFN5c3RlbS5vdXQucHJpbnRsbiggInVzYWdlOiBjb3BpZXIgPHVybG5hbWU+IDxzcmMgZm9sZGVyPiIgKworCQkJCSI8ZGVzdCBmb2xkZXI+IDxzdGFydCBtc2cgIz4gPGVuZCBtc2cgIz4iKTsKKwkgICAgcmV0dXJuOworCX0KKworCXRyeSB7CisJICAgIFVSTE5hbWUgdXJsID0gbmV3IFVSTE5hbWUoYXJndlswXSk7CisJICAgIFN0cmluZyBzcmMgPSBhcmd2WzFdOwkvLyBzb3VyY2UgZm9sZGVyCisJICAgIFN0cmluZyBkZXN0ID0gYXJndlsyXTsJLy8gZGVzdCBmb2xkZXIKKwkgICAgaW50IHN0YXJ0ID0gSW50ZWdlci5wYXJzZUludChhcmd2WzNdKTsJLy8gY29weSBmcm9tIG1lc3NhZ2UgIworCSAgICBpbnQgZW5kID0gSW50ZWdlci5wYXJzZUludChhcmd2WzRdKTsJLy8gdG8gbWVzc2FnZSAjCisKKwkgICAgLy8gR2V0IHRoZSBkZWZhdWx0IFNlc3Npb24gb2JqZWN0CisKKwkgICAgU2Vzc2lvbiBzZXNzaW9uID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShTeXN0ZW0uZ2V0UHJvcGVydGllcygpLCBudWxsKTsKKwkgICAgLy8gc2Vzc2lvbi5zZXREZWJ1ZyhkZWJ1Zyk7CisKKwkgICAgLy8gR2V0IGEgU3RvcmUgb2JqZWN0IHRoYXQgaW1wbGVtZW50cyB0aGUgcHJvdG9jb2wuCisJICAgIFN0b3JlIHN0b3JlID0gc2Vzc2lvbi5nZXRTdG9yZSh1cmwpOworCSAgICBzdG9yZS5jb25uZWN0KCk7CisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiQ29ubmVjdGVkLi4uIik7CisKKwkgICAgLy8gT3BlbiBTb3VyY2UgRm9sZGVyCisJICAgIEZvbGRlciBmb2xkZXIgPSBzdG9yZS5nZXRGb2xkZXIoc3JjKTsKKwkgICAgZm9sZGVyLm9wZW4oRm9sZGVyLlJFQURfV1JJVEUpOworCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIk9wZW5lZCBzb3VyY2UuLi4iKTsJICAKKworCSAgICBpZiAoZm9sZGVyLmdldE1lc3NhZ2VDb3VudCgpID09IDApIHsKKwkJICBTeXN0ZW0ub3V0LnByaW50bG4oIlNvdXJjZSBmb2xkZXIgaGFzIG5vIG1lc3NhZ2VzIC4uIik7CisJCSAgZm9sZGVyLmNsb3NlKGZhbHNlKTsKKwkJICBzdG9yZS5jbG9zZSgpOworCSAgICB9CisKKwkgICAgLy8gT3BlbiBkZXN0aW5hdGlvbiBmb2xkZXIsIGNyZWF0ZSBpZiBuZWVkZWQgCisJICAgIEZvbGRlciBkZm9sZGVyID0gc3RvcmUuZ2V0Rm9sZGVyKGRlc3QpOworCSAgICBpZiAoIWRmb2xkZXIuZXhpc3RzKCkpIC8vIGNyZWF0ZQorCQlkZm9sZGVyLmNyZWF0ZShGb2xkZXIuSE9MRFNfTUVTU0FHRVMpOworCisJICAgIE1lc3NhZ2VbXSBtc2dzID0gZm9sZGVyLmdldE1lc3NhZ2VzKHN0YXJ0LCBlbmQpOworCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkdvdCBtZXNzYWdlcy4uLiIpOwkgIAorCisJICAgIC8vIENvcHkgbWVzc2FnZXMgaW50byBkZXN0aW5hdGlvbiwgCisJICAgIGZvbGRlci5jb3B5TWVzc2FnZXMobXNncywgZGZvbGRlcik7CisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiQ29waWVkIG1lc3NhZ2VzLi4uIik7CSAgCisKKwkgICAgLy8gQ2xvc2UgdGhlIGZvbGRlciBhbmQgc3RvcmUKKwkgICAgZm9sZGVyLmNsb3NlKGZhbHNlKTsKKwkgICAgc3RvcmUuY2xvc2UoKTsKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJDbG9zZWQgZm9sZGVyIGFuZCBzdG9yZS4uLiIpOworCSAgICAKKwl9IGNhdGNoIChFeGNlcHRpb24gZSkgeworCSAgICBlLnByaW50U3RhY2tUcmFjZSgpOworCX0KKworCVN5c3RlbS5leGl0KDApOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2RlbW8vc3JjL21haW4vamF2YS9mb2xkZXJsaXN0LmphdmEgYi9kZW1vL3NyYy9tYWluL2phdmEvZm9sZGVybGlzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFlMjI4NWYKLS0tIC9kZXYvbnVsbAorKysgYi9kZW1vL3NyYy9tYWluL2phdmEvZm9sZGVybGlzdC5qYXZhCkBAIC0wLDAgKzEsMTY0IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk2LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBEaXN0cmlidXRpb24gTGljZW5zZSB2LiAxLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9vcmcvZG9jdW1lbnRzL2VkbC12MTAucGhwLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBCU0QtMy1DbGF1c2UKKyAqLworCitpbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7CitpbXBvcnQgamF2YXgubWFpbC4qOworCitpbXBvcnQgY29tLnN1bi5tYWlsLmltYXAuKjsKKworLyoqCisgKiBEZW1vIGFwcCB0aGF0IGV4ZXJjaXNlcyB0aGUgTWVzc2FnZSBpbnRlcmZhY2VzLgorICogTGlzdCBpbmZvcm1hdGlvbiBhYm91dCBmb2xkZXJzLgorICoKKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCisKK3B1YmxpYyBjbGFzcyBmb2xkZXJsaXN0IHsKKyAgICBzdGF0aWMgU3RyaW5nIHByb3RvY29sID0gbnVsbDsKKyAgICBzdGF0aWMgU3RyaW5nIGhvc3QgPSBudWxsOworICAgIHN0YXRpYyBTdHJpbmcgdXNlciA9IG51bGw7CisgICAgc3RhdGljIFN0cmluZyBwYXNzd29yZCA9IG51bGw7CisgICAgc3RhdGljIFN0cmluZyB1cmwgPSBudWxsOworICAgIHN0YXRpYyBTdHJpbmcgcm9vdCA9IG51bGw7CisgICAgc3RhdGljIFN0cmluZyBwYXR0ZXJuID0gIiUiOworICAgIHN0YXRpYyBib29sZWFuIHJlY3Vyc2l2ZSA9IGZhbHNlOworICAgIHN0YXRpYyBib29sZWFuIHZlcmJvc2UgPSBmYWxzZTsKKyAgICBzdGF0aWMgYm9vbGVhbiBkZWJ1ZyA9IGZhbHNlOworCisgICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nIGFyZ3ZbXSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJaW50IG9wdGluZDsKKwlmb3IgKG9wdGluZCA9IDA7IG9wdGluZCA8IGFyZ3YubGVuZ3RoOyBvcHRpbmQrKykgeworCSAgICBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLVQiKSkgeworCQlwcm90b2NvbCA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1IIikpIHsKKwkJaG9zdCA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1VIikpIHsKKwkJdXNlciA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1QIikpIHsKKwkJcGFzc3dvcmQgPSBhcmd2Wysrb3B0aW5kXTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItTCIpKSB7CisJCXVybCA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1SIikpIHsKKwkJcm9vdCA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1yIikpIHsKKwkJcmVjdXJzaXZlID0gdHJ1ZTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItdiIpKSB7CisJCXZlcmJvc2UgPSB0cnVlOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1EIikpIHsKKwkJZGVidWcgPSB0cnVlOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi0tIikpIHsKKwkJb3B0aW5kKys7CisJCWJyZWFrOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5zdGFydHNXaXRoKCItIikpIHsKKwkJU3lzdGVtLm91dC5wcmludGxuKAorIlVzYWdlOiBmb2xkZXJsaXN0IFstVCBwcm90b2NvbF0gWy1IIGhvc3RdIFstVSB1c2VyXSBbLVAgcGFzc3dvcmRdIFstTCB1cmxdIik7CisJCVN5c3RlbS5vdXQucHJpbnRsbigKKyJcdFstUiByb290XSBbLXJdIFstdl0gWy1EXSBbcGF0dGVybl0iKTsKKwkJU3lzdGVtLmV4aXQoMSk7CisJICAgIH0gZWxzZSB7CisJCWJyZWFrOworCSAgICB9CisJfQorCWlmIChvcHRpbmQgPCBhcmd2Lmxlbmd0aCkKKwkgICAgcGF0dGVybiA9IGFyZ3Zbb3B0aW5kXTsKKworCS8vIEdldCBhIFByb3BlcnRpZXMgb2JqZWN0CisJUHJvcGVydGllcyBwcm9wcyA9IFN5c3RlbS5nZXRQcm9wZXJ0aWVzKCk7CisKKwkvLyBHZXQgYSBTZXNzaW9uIG9iamVjdAorCVNlc3Npb24gc2Vzc2lvbiA9IFNlc3Npb24uZ2V0SW5zdGFuY2UocHJvcHMsIG51bGwpOworCXNlc3Npb24uc2V0RGVidWcoZGVidWcpOworCisJLy8gR2V0IGEgU3RvcmUgb2JqZWN0CisJU3RvcmUgc3RvcmUgPSBudWxsOworCUZvbGRlciByZiA9IG51bGw7CisJaWYgKHVybCAhPSBudWxsKSB7CisJICAgIFVSTE5hbWUgdXJsbiA9IG5ldyBVUkxOYW1lKHVybCk7CisJICAgIHN0b3JlID0gc2Vzc2lvbi5nZXRTdG9yZSh1cmxuKTsKKwkgICAgc3RvcmUuY29ubmVjdCgpOworCX0gZWxzZSB7CisJICAgIGlmIChwcm90b2NvbCAhPSBudWxsKQorCQlzdG9yZSA9IHNlc3Npb24uZ2V0U3RvcmUocHJvdG9jb2wpOworCSAgICBlbHNlCisJCXN0b3JlID0gc2Vzc2lvbi5nZXRTdG9yZSgpOworCisJICAgIC8vIENvbm5lY3QKKwkgICAgaWYgKGhvc3QgIT0gbnVsbCB8fCB1c2VyICE9IG51bGwgfHwgcGFzc3dvcmQgIT0gbnVsbCkKKwkJc3RvcmUuY29ubmVjdChob3N0LCB1c2VyLCBwYXNzd29yZCk7CisJICAgIGVsc2UKKwkJc3RvcmUuY29ubmVjdCgpOworCX0KKworCS8vIExpc3QgbmFtZXNwYWNlCisJaWYgKHJvb3QgIT0gbnVsbCkKKwkgICAgcmYgPSBzdG9yZS5nZXRGb2xkZXIocm9vdCk7CisJZWxzZQorCSAgICByZiA9IHN0b3JlLmdldERlZmF1bHRGb2xkZXIoKTsKKworCWR1bXBGb2xkZXIocmYsIGZhbHNlLCAiIik7CisJaWYgKChyZi5nZXRUeXBlKCkgJiBGb2xkZXIuSE9MRFNfRk9MREVSUykgIT0gMCkgeworCSAgICBGb2xkZXJbXSBmID0gcmYubGlzdChwYXR0ZXJuKTsKKwkgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmLmxlbmd0aDsgaSsrKQorCQlkdW1wRm9sZGVyKGZbaV0sIHJlY3Vyc2l2ZSwgIiAgICAiKTsKKwl9CisKKwlzdG9yZS5jbG9zZSgpOworICAgIH0KKworICAgIHN0YXRpYyB2b2lkIGR1bXBGb2xkZXIoRm9sZGVyIGZvbGRlciwgYm9vbGVhbiByZWN1cnNlLCBTdHJpbmcgdGFiKQorCQkJCQl0aHJvd3MgRXhjZXB0aW9uIHsKKwlTeXN0ZW0ub3V0LnByaW50bG4odGFiICsgIk5hbWU6ICAgICAgIiArIGZvbGRlci5nZXROYW1lKCkpOworCVN5c3RlbS5vdXQucHJpbnRsbih0YWIgKyAiRnVsbCBOYW1lOiAiICsgZm9sZGVyLmdldEZ1bGxOYW1lKCkpOworCVN5c3RlbS5vdXQucHJpbnRsbih0YWIgKyAiVVJMOiAgICAgICAiICsgZm9sZGVyLmdldFVSTE5hbWUoKSk7CisKKwlpZiAodmVyYm9zZSkgeworCSAgICBpZiAoIWZvbGRlci5pc1N1YnNjcmliZWQoKSkKKwkJU3lzdGVtLm91dC5wcmludGxuKHRhYiArICJOb3QgU3Vic2NyaWJlZCIpOworCisJICAgIGlmICgoZm9sZGVyLmdldFR5cGUoKSAmIEZvbGRlci5IT0xEU19NRVNTQUdFUykgIT0gMCkgeworCQlpZiAoZm9sZGVyLmhhc05ld01lc3NhZ2VzKCkpCisJCSAgICBTeXN0ZW0ub3V0LnByaW50bG4odGFiICsgIkhhcyBOZXcgTWVzc2FnZXMiKTsKKwkJU3lzdGVtLm91dC5wcmludGxuKHRhYiArICJUb3RhbCBNZXNzYWdlczogICIgKworCQkJCQkJZm9sZGVyLmdldE1lc3NhZ2VDb3VudCgpKTsKKwkJU3lzdGVtLm91dC5wcmludGxuKHRhYiArICJOZXcgTWVzc2FnZXM6ICAgICIgKworCQkJCQkJZm9sZGVyLmdldE5ld01lc3NhZ2VDb3VudCgpKTsKKwkJU3lzdGVtLm91dC5wcmludGxuKHRhYiArICJVbnJlYWQgTWVzc2FnZXM6ICIgKworCQkJCQkJZm9sZGVyLmdldFVucmVhZE1lc3NhZ2VDb3VudCgpKTsKKwkgICAgfQorCSAgICBpZiAoKGZvbGRlci5nZXRUeXBlKCkgJiBGb2xkZXIuSE9MRFNfRk9MREVSUykgIT0gMCkKKwkJU3lzdGVtLm91dC5wcmludGxuKHRhYiArICJJcyBEaXJlY3RvcnkiKTsKKworCSAgICAvKgorCSAgICAgKiBEZW1vbnN0cmF0ZSB1c2Ugb2YgSU1BUCBmb2xkZXIgYXR0cmlidXRlcworCSAgICAgKiByZXR1cm5lZCBieSB0aGUgSU1BUCBMSVNUIHJlc3BvbnNlLgorCSAgICAgKi8KKwkgICAgaWYgKGZvbGRlciBpbnN0YW5jZW9mIElNQVBGb2xkZXIpIHsKKwkJSU1BUEZvbGRlciBmID0gKElNQVBGb2xkZXIpZm9sZGVyOworCQlTdHJpbmdbXSBhdHRycyA9IGYuZ2V0QXR0cmlidXRlcygpOworCQlpZiAoYXR0cnMgIT0gbnVsbCAmJiBhdHRycy5sZW5ndGggPiAwKSB7CisJCSAgICBTeXN0ZW0ub3V0LnByaW50bG4odGFiICsgIklNQVAgQXR0cmlidXRlczoiKTsKKwkJICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXR0cnMubGVuZ3RoOyBpKyspCisJCQlTeXN0ZW0ub3V0LnByaW50bG4odGFiICsgIiAgICAiICsgYXR0cnNbaV0pOworCQl9CisJICAgIH0KKwl9CisKKwlTeXN0ZW0ub3V0LnByaW50bG4oKTsKKworCWlmICgoZm9sZGVyLmdldFR5cGUoKSAmIEZvbGRlci5IT0xEU19GT0xERVJTKSAhPSAwKSB7CisJICAgIGlmIChyZWN1cnNlKSB7CisJCUZvbGRlcltdIGYgPSBmb2xkZXIubGlzdCgpOworCQlmb3IgKGludCBpID0gMDsgaSA8IGYubGVuZ3RoOyBpKyspCisJCSAgICBkdW1wRm9sZGVyKGZbaV0sIHJlY3Vyc2UsIHRhYiArICIgICAgIik7CisJICAgIH0KKwl9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvZGVtby9zcmMvbWFpbi9qYXZhL2ludGVybmFsL1R0eUF1dGhlbnRpY2F0b3IuamF2YSBiL2RlbW8vc3JjL21haW4vamF2YS9pbnRlcm5hbC9UdHlBdXRoZW50aWNhdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWFkNWEzMgotLS0gL2Rldi9udWxsCisrKyBiL2RlbW8vc3JjL21haW4vamF2YS9pbnRlcm5hbC9UdHlBdXRoZW50aWNhdG9yLmphdmEKQEAgLTAsMCArMSwxMTIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorICovCisKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YS5uZXQuKjsKK2ltcG9ydCBqYXZheC5tYWlsLio7CitpbXBvcnQgamF2YXgubWFpbC5QYXNzd29yZEF1dGhlbnRpY2F0aW9uOworaW1wb3J0IGphdmF4Lm1haWwuQXV0aGVudGljYXRvcjsKKworLyoqCisgKiBBIHNpbXBsZSBBdXRoZW50aWNhdG9yIHRoYXQgcHJvbXB0cyBmb3IgdGhlIHVzZXIgbmFtZSBhbmQgcGFzc3dvcmQgb24gc3RkaW4uCisgKiBQdXRzIHVwIGEgZGlhbG9nIHNvbWV0aGluZyBsaWtlOgorICogPHA+IDxwcmU+CisgKiBDb25uZWN0aW5nIHRvICZsdDtwcm90b2NvbCZndDsgbWFpbCBzZXJ2aWNlIG9uIGhvc3QgJmx0O2FkZHImZ3Q7LCBwb3J0ICZsdDtwb3J0Jmd0Oy4KKyAqICZsdDtwcm9tcHQmZ3Q7CisgKgorICogVXNlciBOYW1lOiBbZGVmYXVsdFVzZXJOYW1lXQorICogUGFzc3dvcmQ6CisgKiA8L3ByZT4gPHA+CisgKgorICogQGF1dGhvciBCaWxsIFNoYW5ub24KKyAqLworCitwdWJsaWMgY2xhc3MgVHR5QXV0aGVudGljYXRvciBleHRlbmRzIEF1dGhlbnRpY2F0b3IgeworCisgICAgLyoqCisgICAgICogQHJldHVybiBUaGUgUGFzc3dvcmRBdXRoZW50aWNhdGlvbiBjb2xsZWN0ZWQgZnJvbSB0aGUKKyAgICAgKgkJdXNlciwgb3IgbnVsbCBpZiBub25lIGlzIHByb3ZpZGVkLgorICAgICAqLworICAgIHByb3RlY3RlZCBQYXNzd29yZEF1dGhlbnRpY2F0aW9uIGdldFBhc3N3b3JkQXV0aGVudGljYXRpb24oKSB7CisJQnVmZmVyZWRSZWFkZXIgaW4gPSBuZXcgQnVmZmVyZWRSZWFkZXIoCisJCQkJbmV3IElucHV0U3RyZWFtUmVhZGVyKChTeXN0ZW0uaW4pKSk7CisJU3RyaW5nQnVmZmVyIHNiID0gbmV3IFN0cmluZ0J1ZmZlcigpOworCXNiLmFwcGVuZCgiQ29ubmVjdGluZyB0byAiKTsKKwlzYi5hcHBlbmQoZ2V0UmVxdWVzdGluZ1Byb3RvY29sKCkpOworCXNiLmFwcGVuZCgiIG1haWwgc2VydmljZSBvbiBob3N0ICIpOworCXNiLmFwcGVuZChnZXRSZXF1ZXN0aW5nU2l0ZSgpLmdldEhvc3ROYW1lKCkpOworCWludCBwb3J0ID0gZ2V0UmVxdWVzdGluZ1BvcnQoKTsKKwlpZiAocG9ydCA+IDApIHsKKwkgICAgc2IuYXBwZW5kKCIsIHBvcnQgIik7CisJICAgIHNiLmFwcGVuZChwb3J0KTsKKwl9CisJc2IuYXBwZW5kKCIuIik7CisJU3lzdGVtLm91dC5wcmludGxuKHNiLnRvU3RyaW5nKCkpOworCVN0cmluZyBwcm9tcHQgPSBnZXRSZXF1ZXN0aW5nUHJvbXB0KCk7CisJaWYgKHByb21wdCAhPSBudWxsKQorCSAgICBTeXN0ZW0ub3V0LnByaW50bG4ocHJvbXB0KTsKKwlTeXN0ZW0ub3V0LnByaW50bG4oKTsKKwlTdHJpbmcgdXNlck5hbWUgPSBnZXQoaW4sICJVc2VyIE5hbWUiLCBnZXREZWZhdWx0VXNlck5hbWUoKSk7CisJU3RyaW5nIHBhc3N3b3JkID0gZ2V0cHcoIlBhc3N3b3JkIik7CisJaWYgKHVzZXJOYW1lID09IG51bGwpCisJICAgIHJldHVybiBudWxsOworCWVsc2UKKwkgICAgcmV0dXJuIG5ldyBQYXNzd29yZEF1dGhlbnRpY2F0aW9uKHVzZXJOYW1lLCBwYXNzd29yZCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIGdldChCdWZmZXJlZFJlYWRlciBpbiwKKwkJCQlTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKSB7CisJUHJpbnRTdHJlYW0gcCA9IFN5c3RlbS5vdXQ7CisKKwlwLnByaW50KG5hbWUgKyAiOiAiKTsKKwlpZiAodmFsdWUgIT0gbnVsbCkKKwkgICAgcC5wcmludCgiWyIgKyB2YWx1ZSArICJdICIpOworCXAuZmx1c2goKTsKKworCXRyeSB7CisJICAgIFN0cmluZyBzID0gaW4ucmVhZExpbmUoKTsKKwkgICAgaWYgKHMubGVuZ3RoKCkgPT0gMCkKKwkJcmV0dXJuIHZhbHVlOworCSAgICBlbHNlCisJCXJldHVybiBzOworCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKwkgICAgcmV0dXJuIHZhbHVlOworCX0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgZ2V0cHcoU3RyaW5nIG5hbWUpIHsKKwlDb25zb2xlIGNvbnM7CisJY2hhcltdIHBhc3N3ZDsKKwlpZiAoKGNvbnMgPSBTeXN0ZW0uY29uc29sZSgpKSAhPSBudWxsICYmCisJICAgIChwYXNzd2QgPSBjb25zLnJlYWRQYXNzd29yZCgiWyVzXSAiLCBuYW1lKSkgIT0gbnVsbCkKKwkgICAgcmV0dXJuIG5ldyBTdHJpbmcocGFzc3dkKTsKKwlyZXR1cm4gIiI7CisgICAgfQorCisgICAgLy8gbWFpbiBwcm9ncmFtLCBmb3IgZGVidWdnaW5nLgorICAgIC8vIFVzYWdlOiBqYXZhIFR0eUF1dGhlbnRpY2F0b3IgaG9zdCBwb3J0IHByb3RvY29sIHByb21wdCBkZWZhdWx0VXNlcgorICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZyBhcmd2W10pIHRocm93cyBFeGNlcHRpb24geworCVNlc3Npb24gc2VzcyA9IFNlc3Npb24uZ2V0SW5zdGFuY2UoU3lzdGVtLmdldFByb3BlcnRpZXMoKSwKKwkJCQkJbmV3IFR0eUF1dGhlbnRpY2F0b3IoKSk7CisJUGFzc3dvcmRBdXRoZW50aWNhdGlvbiBwdyA9IHNlc3MucmVxdWVzdFBhc3N3b3JkQXV0aGVudGljYXRpb24oCisJCUluZXRBZGRyZXNzLmdldEJ5TmFtZShhcmd2WzBdKSwKKwkJSW50ZWdlci5wYXJzZUludChhcmd2WzFdKSwgYXJndlsyXSwgeihhcmd2WzNdKSwgeihhcmd2WzRdKSk7CisJU3lzdGVtLm91dC5wcmludGxuKCJVc2VyOiAiICsgbihwdy5nZXRVc2VyTmFtZSgpKSk7CisJU3lzdGVtLm91dC5wcmludGxuKCJQYXNzd29yZDogIiArIG4ocHcuZ2V0UGFzc3dvcmQoKSkpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBuKFN0cmluZyBzKSB7CisJcmV0dXJuIHMgPT0gbnVsbCA/ICI8bnVsbD4iIDogczsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgeihTdHJpbmcgcykgeworCXJldHVybiBzLmxlbmd0aCgpID4gMCA/IHMgOiBudWxsOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2RlbW8vc3JjL21haW4vamF2YS9pbnRlcm5hbC9hbnN3ZXIuamF2YSBiL2RlbW8vc3JjL21haW4vamF2YS9pbnRlcm5hbC9hbnN3ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lN2Y4OTYzCi0tLSAvZGV2L251bGwKKysrIGIvZGVtby9zcmMvbWFpbi9qYXZhL2ludGVybmFsL2Fuc3dlci5qYXZhCkBAIC0wLDAgKzEsMzU1IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBEaXN0cmlidXRpb24gTGljZW5zZSB2LiAxLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9vcmcvZG9jdW1lbnRzL2VkbC12MTAucGhwLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBCU0QtMy1DbGF1c2UKKyAqLworCitpbXBvcnQgamF2YS51dGlsLio7CitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmF4Lm1haWwuKjsKK2ltcG9ydCBqYXZheC5tYWlsLnNlYXJjaC4qOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuKjsKKworLyoqCisgKiBQcm9ncmFtIHRvIG1hbmFnZSB0aGUgamF2YW1haWxAU3VuLkNPTSBtYWlsaW5nIGxpc3QgYnkga2VlcGluZyB0cmFjaworICogb2Ygd2hpY2ggbWVzc2FnZXMgaGF2ZSBiZWVuIGFuc3dlcmVkLiAgTWVzc2FnZSB0aGF0IGhhdmUgYmVlbiBhbnN3ZXJlZAorICogaGF2ZSB0aGUgQU5TV0VSRUQgZmxhZyBzZXQuICBNZXNzYWdlcyB0aGF0IGFyZSByZXBsaWVzIHRvIG90aGVyIG1lc3NhZ2VzCisgKiBoYXZlIHRoZSBGTEFHR0VEIGZsYWcgc2V0LiA8cD4KKyAqCisgKiBOb3RlIHRoYXQgdGhpcyBwcm9ncmFtIG9wZXJhdGVzIG9uIHRoZSBsb2cgZmlsZSBkaXJlY3RseSBhbmQgdGh1cyBhbGwKKyAqIGFjY2VzcyB0byB0aGUgbG9nIGZpbGUgdXNpbmcgdGhpcyBwcm9ncmFtIG11c3QgYmUgdGhyb3VnaCB0aGUgc2FtZQorICogSU1BUCBzZXJ2ZXIgc28gdGhhdCB0aGUgZmxhZ3MgYXJlIGhhbmRsZWQgY29uc2lzdGVudGx5LiA8cD4KKyAqCisgKiBXaGVuIHJ1biB3aXRoIG5vIG1lc3NhZ2UgbnVtYmVyIGFyZ3VtZW50cyBpdCB3aWxsIGxpc3QgdGhlIHVuYW5zd2VyZWQKKyAqIG1lc3NhZ2VzLiAgVGhlIC11IGZsYWcgd2lsbCBjYXVzZSBpdCB0byBmaXJzdCB1cGRhdGUgdGhlIG1haWxib3ggdG8KKyAqIGFjY291bnQgZm9yIGFueSByZWNlbnQgcmVwbGllcy4gPHA+CisgKgorICogV2hlbiBydW4gd2l0aCBtZXNzYWdlIG51bWJlciBhcmd1bWVudHMgaXQgd2lsbCBtYXJrIHRob3NlIG1lc3NhZ2VzIGFzCisgKiBhbnN3ZXJlZC4gIFRoaXMgaXMgdXNlZnVsIGZvciBtYXJraW5nIHNwYW0gYW5kIG90aGVyIHJhbmRvbSBtZXNzYWdlcworICogdGhhdCB3aWxsIG5ldmVyIGJlIHJlcGxpZWQgdG8uIDxwPgorICoKKyAqIFRoZSAtYSBmbGFnIHdpbGwgY2F1c2UgaXQgdG8gbWFyayBhbGwgbWVzc2FnZXMgYXMgYW5zd2VyZWQuICBVc2VmdWwgZm9yCisgKiBmbHVzaGluZyB0aGUgZXZlciBhY2N1bXVsYXRpbmcgc3BhbS4gPHA+CisgKgorICogQGF1dGhvciBCaWxsIFNoYW5ub24KKyAqLworCitwdWJsaWMgY2xhc3MgYW5zd2VyIHsKKworICAgIHN0YXRpYyBTdHJpbmcgcHJvdG9jb2wgPSAiaW1hcCI7CisgICAgc3RhdGljIFN0cmluZyBob3N0ID0gImFueWJvZHlzLnNmYmF5IjsKKyAgICBzdGF0aWMgU3RyaW5nIHVzZXIgPSAiamF2YW1haWwiOworICAgIHN0YXRpYyBTdHJpbmcgcGFzc3dvcmQgPSAiMWphdmFtYWlsMSI7CisgICAgc3RhdGljIFN0cmluZyBtYm94ID0KKwkiL25ldC9hbnlib2R5cy5zZmJheS9leHBvcnQ2L2phdmFtYWlsL2xvZ3MvamF2YW1haWwubG9nIjsKKyAgICBzdGF0aWMgU3RyaW5nIHVybCA9IG51bGw7CisgICAgc3RhdGljIGJvb2xlYW4gdmVyYm9zZSA9IGZhbHNlOworICAgIHN0YXRpYyBib29sZWFuIHVwZGF0ZSA9IGZhbHNlOworICAgIHN0YXRpYyBib29sZWFuIG1hcmtBbGwgPSBmYWxzZTsKKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZyBhcmd2W10pIHsKKwlpbnQgb3B0aW5kOworCisJZm9yIChvcHRpbmQgPSAwOyBvcHRpbmQgPCBhcmd2Lmxlbmd0aDsgb3B0aW5kKyspIHsKKwkgICAgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1UIikpIHsKKwkJcHJvdG9jb2wgPSBhcmd2Wysrb3B0aW5kXTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItSCIpKSB7CisJCWhvc3QgPSBhcmd2Wysrb3B0aW5kXTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItVSIpKSB7CisJCXVzZXIgPSBhcmd2Wysrb3B0aW5kXTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItUCIpKSB7CisJCXBhc3N3b3JkID0gYXJndlsrK29wdGluZF07CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLXYiKSkgeworCQl2ZXJib3NlID0gdHJ1ZTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItZiIpKSB7CisJCW1ib3ggPSBhcmd2Wysrb3B0aW5kXTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItTCIpKSB7CisJCXVybCA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi11IikpIHsKKwkJdXBkYXRlID0gdHJ1ZTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItYSIpKSB7CisJCW1hcmtBbGwgPSB0cnVlOworCQl1cGRhdGUgPSB0cnVlOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi0tIikpIHsKKwkJb3B0aW5kKys7CisJCWJyZWFrOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5zdGFydHNXaXRoKCItIikpIHsKKwkJU3lzdGVtLm91dC5wcmludGxuKAorIlVzYWdlOiBhbnN3ZXIgWy1MIHVybF0gWy1UIHByb3RvY29sXSBbLUggaG9zdF0gWy1VIHVzZXJdIFstUCBwYXNzd29yZF1cbiIgKworIlx0Wy1mIG1haWxib3hdIFstdl0gWy11XSBbLWFdIFttc2dubyAuLi5dIik7CisJCVN5c3RlbS5leGl0KDEpOworCSAgICB9IGVsc2UgeworCQlicmVhazsKKwkgICAgfQorCX0KKworICAgICAgICB0cnkgeworCSAgICAvLyBHZXQgYSBQcm9wZXJ0aWVzIG9iamVjdAorCSAgICBQcm9wZXJ0aWVzIHByb3BzID0gU3lzdGVtLmdldFByb3BlcnRpZXMoKTsKKworCSAgICAvLyBHZXQgYSBTZXNzaW9uIG9iamVjdAorCSAgICBTZXNzaW9uIHNlc3Npb24gPSBTZXNzaW9uLmdldERlZmF1bHRJbnN0YW5jZShwcm9wcywKKwkJCQkgICAgbmV3IFR0eUF1dGhlbnRpY2F0b3IoKSk7CisKKwkgICAgLy8gR2V0IGEgU3RvcmUgb2JqZWN0CisJICAgIFN0b3JlIHN0b3JlID0gbnVsbDsKKwkgICAgaWYgKHVybCAhPSBudWxsKSB7CisJCVVSTE5hbWUgdXJsbiA9IG5ldyBVUkxOYW1lKHVybCk7CisJCXN0b3JlID0gc2Vzc2lvbi5nZXRTdG9yZSh1cmxuKTsKKwkJc3RvcmUuY29ubmVjdCgpOworCSAgICB9IGVsc2UgeworCQlpZiAocHJvdG9jb2wgIT0gbnVsbCkJCQorCQkgICAgc3RvcmUgPSBzZXNzaW9uLmdldFN0b3JlKHByb3RvY29sKTsKKwkJZWxzZQorCQkgICAgc3RvcmUgPSBzZXNzaW9uLmdldFN0b3JlKCk7CisKKwkJLy8gQ29ubmVjdAorCQlpZiAoaG9zdCAhPSBudWxsIHx8IHVzZXIgIT0gbnVsbCB8fCBwYXNzd29yZCAhPSBudWxsKQorCQkgICAgc3RvcmUuY29ubmVjdChob3N0LCB1c2VyLCBwYXNzd29yZCk7CisJCWVsc2UKKwkJICAgIHN0b3JlLmNvbm5lY3QoKTsKKwkgICAgfQorCSAgICAKKworCSAgICAvLyBPcGVuIHRoZSBGb2xkZXIKKworCSAgICBGb2xkZXIgZm9sZGVyID0gc3RvcmUuZ2V0RGVmYXVsdEZvbGRlcigpOworCSAgICBpZiAoZm9sZGVyID09IG51bGwpIHsKKwkgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiTm8gZGVmYXVsdCBmb2xkZXIiKTsKKwkgICAgICAgIFN5c3RlbS5leGl0KDEpOworCSAgICB9CisKKwkgICAgZm9sZGVyID0gZm9sZGVyLmdldEZvbGRlcihtYm94KTsKKwkgICAgaWYgKGZvbGRlciA9PSBudWxsKSB7CisJICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkludmFsaWQgZm9sZGVyIik7CisJICAgICAgICBTeXN0ZW0uZXhpdCgxKTsKKwkgICAgfQorCisJICAgIGlmIChvcHRpbmQgPCBhcmd2Lmxlbmd0aCB8fCB1cGRhdGUpCisJCWZvbGRlci5vcGVuKEZvbGRlci5SRUFEX1dSSVRFKTsKKwkgICAgZWxzZQorCQlmb2xkZXIub3BlbihGb2xkZXIuUkVBRF9PTkxZKTsKKwkgICAgaW50IHRvdGFsTWVzc2FnZXMgPSBmb2xkZXIuZ2V0TWVzc2FnZUNvdW50KCk7CisKKwkgICAgaWYgKHRvdGFsTWVzc2FnZXMgPT0gMCkgeworCQlTeXN0ZW0ub3V0LnByaW50bG4oIkVtcHR5IGZvbGRlciIpOworCQlmb2xkZXIuY2xvc2UoZmFsc2UpOworCQlzdG9yZS5jbG9zZSgpOworCQlTeXN0ZW0uZXhpdCgxKTsKKwkgICAgfQorCisJICAgIGlmICh2ZXJib3NlKSB7CisJCWludCBuZXdNZXNzYWdlcyA9IGZvbGRlci5nZXROZXdNZXNzYWdlQ291bnQoKTsKKwkJcHYoIlRvdGFsIG1lc3NhZ2VzID0gIiArIHRvdGFsTWVzc2FnZXMpOworCQlwdigiTmV3IG1lc3NhZ2VzID0gIiArIG5ld01lc3NhZ2VzKTsKKwkJcHYoIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0iKTsKKwkgICAgfQorCisJICAgIGlmIChvcHRpbmQgPj0gYXJndi5sZW5ndGgpIHsKKwkJLy8gZ2V0IGFsbCBtZXNzYWdlcyB0aGF0IGFyZW4ndCBhbnN3ZXJlZCBvciBmbGFnZ2VkCisJCUZsYWdzIGYgPSBuZXcgRmxhZ3MoKTsKKwkJZi5hZGQoRmxhZ3MuRmxhZy5BTlNXRVJFRCk7CisJCWYuYWRkKEZsYWdzLkZsYWcuRkxBR0dFRCk7CisKKwkJLy8gVXNlIGEgc3VpdGFibGUgRmV0Y2hQcm9maWxlCisJCUZldGNoUHJvZmlsZSBmcCA9IG5ldyBGZXRjaFByb2ZpbGUoKTsKKwkJZnAuYWRkKEZldGNoUHJvZmlsZS5JdGVtLkVOVkVMT1BFKTsKKwkJZnAuYWRkKEZldGNoUHJvZmlsZS5JdGVtLkZMQUdTKTsKKworCQlNZXNzYWdlW10gbXNncyA9IGZvbGRlci5zZWFyY2gobmV3IEZsYWdUZXJtKGYsIGZhbHNlKSk7CisJCWZvbGRlci5mZXRjaChtc2dzLCBmcCk7CisKKwkJaWYgKHVwZGF0ZSkgeworCQkgICAgZG9VcGRhdGUobXNncyk7CisJCSAgICAvLyByZS1mZXRjaCBtZXNzYWdlcworCQkgICAgbXNncyA9IGZvbGRlci5zZWFyY2gobmV3IEZsYWdUZXJtKGYsIGZhbHNlKSk7CisJCSAgICBwdigiIik7CisJCSAgICBwdigiIik7CisJCX0KKworCQlTeXN0ZW0ub3V0LnByaW50bG4oIlVuYW5zd2VyZWQgbWVzc2FnZXM6Iik7CisJCWZvciAoaW50IGkgPSAwOyBpIDwgbXNncy5sZW5ndGg7IGkrKykgeworCQkgICAgTWVzc2FnZSBtc2cgPSBtc2dzW2ldOworCQkgICAgU3lzdGVtLm91dC5wcmludGxuKCItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIpOworCQkgICAgU3lzdGVtLm91dC5wcmludGxuKCJNRVNTQUdFICMiICsKKwkJCW1zZy5nZXRNZXNzYWdlTnVtYmVyKCkgKyAiOiIpOworCQkgICAgUXVlc3Rpb24gcSA9IG5ldyBRdWVzdGlvbihtc2cpOworCQkgICAgU3lzdGVtLm91dC5wcmludGxuKHEpOworCQkgICAgaWYgKHEuaXNSZXBseSgpKQorCQkJU3lzdGVtLm91dC5wcmludGxuKAorCQkJICAgICJBIHJlcGx5IHRvIGEgbWVzc2FnZSB3ZSBoYXZlbid0IHNlZW4iKTsKKwkJICAgIGlmIChtYXJrQWxsKSB7CisJCQlpbnQgbXNnbm8gPSBtc2cuZ2V0TWVzc2FnZU51bWJlcigpOworCQkJaWYgKHEuaXNSZXBseSgpKSB7CisJCQkgICAgcHYoIkZsYWdnaW5nIG1lc3NhZ2UgIyIgKyBtc2dubyk7CisJCQkgICAgbXNnLnNldEZsYWcoRmxhZ3MuRmxhZy5GTEFHR0VELCB0cnVlKTsKKwkJCX0gZWxzZSB7CisJCQkgICAgcHYoIkFuc3dlcmluZyBtZXNzYWdlICMiICsgbXNnbm8pOworCQkJICAgIG1zZy5zZXRGbGFnKEZsYWdzLkZsYWcuQU5TV0VSRUQsIHRydWUpOworCQkJfQorCQkgICAgfQorCQl9CisKKwkgICAgfSBlbHNlIHsKKwkJZm9yIChpbnQgaSA9IG9wdGluZDsgaSA8IGFyZ3YubGVuZ3RoOyBpKyspIHsKKwkJICAgIGludCBtc2dubyA9IEludGVnZXIucGFyc2VJbnQoYXJndltpXSk7CisJCSAgICBNZXNzYWdlIG1zZyA9IGZvbGRlci5nZXRNZXNzYWdlKG1zZ25vKTsKKwkJICAgIFF1ZXN0aW9uIHEgPSBuZXcgUXVlc3Rpb24obXNnKTsKKwkJICAgIGlmIChxLmlzUmVwbHkoKSkgeworCQkJcHYoIkZsYWdnaW5nIG1lc3NhZ2UgIyIgKyBtc2dubyk7CisJCQltc2cuc2V0RmxhZyhGbGFncy5GbGFnLkZMQUdHRUQsIHRydWUpOworCQkgICAgfSBlbHNlIHsKKwkJCXB2KCJBbnN3ZXJpbmcgbWVzc2FnZSAjIiArIG1zZ25vKTsKKwkJCW1zZy5zZXRGbGFnKEZsYWdzLkZsYWcuQU5TV0VSRUQsIHRydWUpOworCQkgICAgfQorCQl9CisJICAgIH0KKworCSAgICBmb2xkZXIuY2xvc2UoZmFsc2UpOworCSAgICBzdG9yZS5jbG9zZSgpOworCX0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIk9vcHMsIGdvdCBleGNlcHRpb24hICIgKyBleC5nZXRNZXNzYWdlKCkpOworCSAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKKwkgICAgU3lzdGVtLmV4aXQoMSk7CisJfQorCVN5c3RlbS5leGl0KDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIFVwZGF0ZSB0aGUgbWFpbGJveCB0byBhY2NvdW50IGZvciBhbnkgcmVwbGllcy4KKyAgICAgKi8KKyAgICBzdGF0aWMgdm9pZCBkb1VwZGF0ZShNZXNzYWdlW10gbXNncykgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJLy8gYSBoYXNoIHRhYmxlIG9mIGFsbCB0aGUgdW5hbnN3ZXJlZCBxdWVzdGlvbnMKKwlIYXNodGFibGUgcXQgPSBuZXcgSGFzaHRhYmxlKCk7CisKKwlBZGRyZXNzIGphdmFtYWlsQWRkcmVzcyA9IG5ldyBJbnRlcm5ldEFkZHJlc3MoImphdmFtYWlsQFN1bi5DT00iKTsKKwlTZWFyY2hUZXJtIGphdmFtYWlsID0gbmV3IE9yVGVybSgKKwkJbmV3IFJlY2lwaWVudFRlcm0oTWVzc2FnZS5SZWNpcGllbnRUeXBlLlRPLCBqYXZhbWFpbEFkZHJlc3MpLAorCQluZXcgUmVjaXBpZW50VGVybShNZXNzYWdlLlJlY2lwaWVudFR5cGUuQ0MsIGphdmFtYWlsQWRkcmVzcykpOworCisJZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisJICAgIE1lc3NhZ2UgbXNnID0gbXNnc1tpXTsKKwkgICAgcHYoIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIik7CisJICAgIHB2KCJNRVNTQUdFICMiICsgbXNnLmdldE1lc3NhZ2VOdW1iZXIoKSArICI6Iik7CisJICAgIFF1ZXN0aW9uIHEgPSBuZXcgUXVlc3Rpb24obXNnKTsKKwkgICAgcHYocS50b1N0cmluZygpKTsKKwkgICAgUXVlc3Rpb24gcTA7CisJICAgIGlmICgocTAgPSAoUXVlc3Rpb24pcXQuZ2V0KHEpKSAhPSBudWxsKSB7CisJCXB2KCJGb3VuZCBpbiB0YWJsZSIpOworCQlpZiAocS5pc1JlcGx5KCkpIHsKKwkJICAgIE1lc3NhZ2UgcW0gPSBxMC5nZXRNZXNzYWdlKCk7CisJCSAgICBpZiAoIXFtLmlzU2V0KEZsYWdzLkZsYWcuQU5TV0VSRUQpKSB7CisJCQlwdigiQW5zd2VyZWQ6Iik7CisJCQlwdihxMC50b1N0cmluZygpKTsKKwkJCXFtLnNldEZsYWcoRmxhZ3MuRmxhZy5BTlNXRVJFRCwgdHJ1ZSk7CisJCSAgICB9CisJCSAgICBwdigiaXMgcmVwbHksIGZsYWdnaW5nIGl0Iik7CisJCSAgICBtc2cuc2V0RmxhZyhGbGFncy5GbGFnLkZMQUdHRUQsIHRydWUpOworCQl9IGVsc2UgeworCQkgICAgLy8gYSBzZWNvbmQgY29weSBvZiBhIG1lc3NhZ2UgdGhhdCdzIG5vdCBhIHJlcGx5PworCQkgICAgLy8gc2hvdWxkbid0IGhhcHBlbi4KKwkJfQorCSAgICB9IGVsc2UgeworCQlwdigiTk9UIGZvdW5kIGluIHRhYmxlIik7CisJCWlmIChxLmlzUmVwbHkoKSkgeworCQkgICAgLy8gYSByZXBseSB0byBhIG1lc3NhZ2Ugd2UgaGF2ZW4ndCBzZWVuPworCQkgICAgcHYoImZsYWdnaW5nLCBidXQgbm8gb3JpZ2luYWwgbXNnIik7CisJCSAgICBtc2cuc2V0RmxhZyhGbGFncy5GbGFnLkZMQUdHRUQsIHRydWUpOworCQl9IGVsc2UgeworCQkgICAgLy8gYW4gb3JpZ2luYWwgcXVlc3Rpb24sIHB1dCBpdCBpbiB0aGUgdGFibGUKKwkJICAgIHF0LnB1dChxLCBxKTsKKwkJICAgIC8vIGlmIHRoZSBtZXNzYWdlIGxvb2tzIGxpa2Ugc3BhbSwgZmxhZyBpdAorCQkgICAgaWYgKCFqYXZhbWFpbC5tYXRjaChtc2cpKSB7CisJCQlwdigiU1BBTSEhISIpOworCQkJbXNnLnNldEZsYWcoRmxhZ3MuRmxhZy5GTEFHR0VELCB0cnVlKTsKKwkJICAgIH0KKwkJfQorCSAgICB9CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFByaW50IHZlcmJvc2UuCisgICAgICovCisgICAgc3RhdGljIHZvaWQgcHYoU3RyaW5nIHMpIHsKKwlpZiAodmVyYm9zZSkKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKHMpOworICAgIH0KK30KKworLyoqCisgKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgYSBzaW5nbGUgInF1ZXN0aW9uIiBzZW50IHRvIGphdmFtYWlsQFN1bi5DT00sCisgKiBvciBwb3NzaWJseSBhIHJlcGx5IHRvIHN1Y2ggYSBxdWVzdGlvbi4KKyAqLworY2xhc3MgUXVlc3Rpb24geworICAgIE1lc3NhZ2UJbXNnOworICAgIEFkZHJlc3MJc2VuZGVyOworICAgIEFkZHJlc3NbXQlyZWNpcGllbnRzOworICAgIFN0cmluZwlzdWJqZWN0OworICAgIERhdGUJZGF0ZTsKKyAgICBib29sZWFuCXJlcGx5ID0gZmFsc2U7CisKKyAgICBRdWVzdGlvbihNZXNzYWdlIG1zZykgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJdGhpcy5tc2cgPSBtc2c7CisJc2VuZGVyID0gbXNnLmdldFJlcGx5VG8oKVswXTsgICAgLy8gWFhYIC0gYXNzdW1lIG9ubHkgb25lCisJc3ViamVjdCA9IG1zZy5nZXRTdWJqZWN0KCk7CisJaWYgKHN1YmplY3QgPT0gbnVsbCkKKwkgICAgc3ViamVjdCA9ICIiOworCWVsc2UgaWYgKHN1YmplY3QucmVnaW9uTWF0Y2hlcyh0cnVlLCAwLCAiUmU6ICIsIDAsIDQpKSB7CisJICAgIHN1YmplY3QgPSBzdWJqZWN0LnN1YnN0cmluZyg0KTsKKwkgICAgcmVwbHkgPSB0cnVlOworCSAgICByZWNpcGllbnRzID0gbXNnLmdldFJlY2lwaWVudHMoTWVzc2FnZS5SZWNpcGllbnRUeXBlLlRPKTsKKwl9CisJc3ViamVjdCA9IHN1YmplY3QudHJpbSgpOworCWRhdGUgPSBtc2cuZ2V0U2VudERhdGUoKTsKKwlpZiAoZGF0ZSA9PSBudWxsKQorCSAgICBkYXRlID0gbXNnLmdldFJlY2VpdmVkRGF0ZSgpOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGlzUmVwbHkoKSB7CisJcmV0dXJuIHJlcGx5OworICAgIH0KKworICAgIHB1YmxpYyBNZXNzYWdlIGdldE1lc3NhZ2UoKSB7CisJcmV0dXJuIG1zZzsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworCXJldHVybiBzdWJqZWN0Lmhhc2hDb2RlKCk7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKKwlpZiAoIShvYmogaW5zdGFuY2VvZiBRdWVzdGlvbikpCisJICAgIHJldHVybiBmYWxzZTsKKwlRdWVzdGlvbiBxID0gKFF1ZXN0aW9uKW9iajsKKwlpZiAodGhpcy5yZXBseSA9PSBxLnJlcGx5KQorCSAgICByZXR1cm4gdGhpcy5zZW5kZXIuZXF1YWxzKHEuc2VuZGVyKSAmJgorCQkgICAgdGhpcy5zdWJqZWN0LmVxdWFscyhxLnN1YmplY3QpOworCisJLyoKKwkgKiBBIHJlcGx5IGlzIGVxdWFsIHRvIGEgcXVlc3Rpb24gaWYgdGhlIHNlbmRlciBvZiB0aGUgcXVlc3Rpb24KKwkgKiBpcyBvbmUgb2YgdGhlIHJlY2lwaWVudHMgb2YgdGhlIHJlcGx5LgorCSAqLworCVF1ZXN0aW9uIHFxLCBxcjsKKwlpZiAodGhpcy5yZXBseSkgeworCSAgICBxcSA9IHE7CisJICAgIHFyID0gdGhpczsKKwl9IGVsc2UgeworCSAgICBxcSA9IHRoaXM7CisJICAgIHFyID0gcTsKKwl9CisJZm9yIChpbnQgaSA9IDA7IGkgPCBxci5yZWNpcGllbnRzLmxlbmd0aDsgaSsrKSB7CisJICAgIGlmIChxcS5zZW5kZXIuZXF1YWxzKHFyLnJlY2lwaWVudHNbaV0pKQorCQlyZXR1cm4gdHJ1ZTsKKwl9CisJcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisJcmV0dXJuICJEYXRlOiAiICsgZGF0ZSArICJcbkZyb206ICIgKyBzZW5kZXIgKyAiXG5TdWJqZWN0OiAiICsgc3ViamVjdDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9kZW1vL3NyYy9tYWluL2phdmEvaW50ZXJuYWwvZm9sZGVyc3BsaXQuamF2YSBiL2RlbW8vc3JjL21haW4vamF2YS9pbnRlcm5hbC9mb2xkZXJzcGxpdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM5ZTQ0NDUKLS0tIC9kZXYvbnVsbAorKysgYi9kZW1vL3NyYy9tYWluL2phdmEvaW50ZXJuYWwvZm9sZGVyc3BsaXQuamF2YQpAQCAtMCwwICsxLDE4NyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgRGlzdHJpYnV0aW9uIExpY2Vuc2Ugdi4gMS4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvb3JnL2RvY3VtZW50cy9lZGwtdjEwLnBocC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQlNELTMtQ2xhdXNlCisgKi8KKworaW1wb3J0IGphdmEudXRpbC4qOworaW1wb3J0IGphdmEudGV4dC4qOworaW1wb3J0IGphdmF4Lm1haWwuKjsKKworLyoqCisgKgorICogU3BsaXQgbWFpbCBmb2xkZXJzIGFjY29yZGluZyB0byBkYXRlIG9mIG1lc3NhZ2VzLgorICoKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKi8KKworcHVibGljIGNsYXNzIGZvbGRlcnNwbGl0IHsKKworICAgIHN0YXRpYyBTdHJpbmcgcHJvdG9jb2w7CisgICAgc3RhdGljIFN0cmluZyBob3N0ID0gbnVsbDsKKyAgICBzdGF0aWMgU3RyaW5nIHVzZXIgPSBudWxsOworICAgIHN0YXRpYyBTdHJpbmcgcGFzc3dvcmQgPSBudWxsOworICAgIHN0YXRpYyBTdHJpbmcgZHN0ID0gbnVsbDsKKyAgICBzdGF0aWMgU3RyaW5nIHVybCA9IG51bGw7CisgICAgc3RhdGljIGludCBwb3J0ID0gLTE7CisgICAgc3RhdGljIGJvb2xlYW4gdmVyYm9zZSA9IGZhbHNlOworICAgIHN0YXRpYyBib29sZWFuIGRlYnVnID0gZmFsc2U7CisgICAgc3RhdGljIGJvb2xlYW4gbm9wID0gZmFsc2U7CisgICAgc3RhdGljIFNpbXBsZURhdGVGb3JtYXQgZGYgPSBuZXcgU2ltcGxlRGF0ZUZvcm1hdCgieXl5eS5NTSIpOworCisgICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nIGFyZ3ZbXSkgeworCWludCBvcHRpbmQ7CisKKwlmb3IgKG9wdGluZCA9IDA7IG9wdGluZCA8IGFyZ3YubGVuZ3RoOyBvcHRpbmQrKykgeworCSAgICBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLVQiKSkgeworCQlwcm90b2NvbCA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1IIikpIHsKKwkJaG9zdCA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1VIikpIHsKKwkJdXNlciA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1QIikpIHsKKwkJcGFzc3dvcmQgPSBhcmd2Wysrb3B0aW5kXTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItZCIpKSB7CisJCWRzdCA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi12IikpIHsKKwkJdmVyYm9zZSA9IHRydWU7CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLW4iKSkgeworCQlub3AgPSB0cnVlOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1EIikpIHsKKwkJZGVidWcgPSB0cnVlOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1MIikpIHsKKwkJdXJsID0gYXJndlsrK29wdGluZF07CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLXAiKSkgeworCQlwb3J0ID0gSW50ZWdlci5wYXJzZUludChhcmd2Wysrb3B0aW5kXSk7CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLS0iKSkgeworCQlvcHRpbmQrKzsKKwkJYnJlYWs7CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLnN0YXJ0c1dpdGgoIi0iKSkgeworCQlTeXN0ZW0ub3V0LnByaW50bG4oCisiVXNhZ2U6IGZvbGRlcnNwbGl0IFstTCB1cmxdIFstVCBwcm90b2NvbF0gWy1IIGhvc3RdIFstcCBwb3J0XSBbLVUgdXNlcl0iKTsKKwkJU3lzdGVtLm91dC5wcmludGxuKAorIlx0Wy1QIHBhc3N3b3JkXSBbLXZdIFstRF0gZm9sZGVyIC4uLiIpOworCQlTeXN0ZW0uZXhpdCgxKTsKKwkgICAgfSBlbHNlIHsKKwkJYnJlYWs7CisJICAgIH0KKwl9CisKKyAgICAgICAgdHJ5IHsKKwkgICAgLy8gR2V0IGEgUHJvcGVydGllcyBvYmplY3QKKwkgICAgUHJvcGVydGllcyBwcm9wcyA9IFN5c3RlbS5nZXRQcm9wZXJ0aWVzKCk7CisKKwkgICAgLy8gR2V0IGEgU2Vzc2lvbiBvYmplY3QKKwkgICAgU2Vzc2lvbiBzZXNzaW9uID0gU2Vzc2lvbi5nZXREZWZhdWx0SW5zdGFuY2UocHJvcHMsIG51bGwpOworCSAgICBzZXNzaW9uLnNldERlYnVnKGRlYnVnKTsKKworCSAgICAvLyBHZXQgYSBTdG9yZSBvYmplY3QKKwkgICAgU3RvcmUgc3RvcmUgPSBudWxsOworCSAgICBpZiAodXJsICE9IG51bGwpIHsKKwkJVVJMTmFtZSB1cmxuID0gbmV3IFVSTE5hbWUodXJsKTsKKwkJc3RvcmUgPSBzZXNzaW9uLmdldFN0b3JlKHVybG4pOworCQlzdG9yZS5jb25uZWN0KCk7CisJICAgIH0gZWxzZSB7CisJCWlmIChwcm90b2NvbCAhPSBudWxsKQkJCisJCSAgICBzdG9yZSA9IHNlc3Npb24uZ2V0U3RvcmUocHJvdG9jb2wpOworCQllbHNlCisJCSAgICBzdG9yZSA9IHNlc3Npb24uZ2V0U3RvcmUoKTsKKworCQkvLyBDb25uZWN0CisJCWlmIChob3N0ICE9IG51bGwgfHwgdXNlciAhPSBudWxsIHx8IHBhc3N3b3JkICE9IG51bGwpCisJCSAgICBzdG9yZS5jb25uZWN0KGhvc3QsIHBvcnQsIHVzZXIsIHBhc3N3b3JkKTsKKwkJZWxzZQorCQkgICAgc3RvcmUuY29ubmVjdCgpOworCSAgICB9CisJICAgIAorCisJICAgIC8vIE9wZW4gdGhlIEZvbGRlcgorCisJICAgIEZvbGRlciBkZWZmb2xkZXIgPSBzdG9yZS5nZXREZWZhdWx0Rm9sZGVyKCk7CisJICAgIGlmIChkZWZmb2xkZXIgPT0gbnVsbCkgeworCSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJObyBkZWZhdWx0IGZvbGRlciIpOworCSAgICAgICAgU3lzdGVtLmV4aXQoMSk7CisJICAgIH0KKwkgICAgRm9sZGVyIGRzdGZvbGRlcjsKKwkgICAgaWYgKGRzdCA9PSBudWxsKSB7CisJCWRzdGZvbGRlciA9IGRlZmZvbGRlcjsKKwkgICAgfSBlbHNlIHsKKwkJZHN0Zm9sZGVyID0gZGVmZm9sZGVyLmdldEZvbGRlcihkc3QpOworCQlpZiAoZHN0Zm9sZGVyID09IG51bGwpIHsKKwkJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiTm8gZGVzdGluYXRpb24gZm9sZGVyIik7CisJCSAgICBTeXN0ZW0uZXhpdCgxKTsKKwkJfQorCSAgICB9CisKKwkgICAgRm9sZGVyIG91dGYgPSBudWxsOworCSAgICBmb3IgKDsgb3B0aW5kIDwgYXJndi5sZW5ndGg7IG9wdGluZCsrKSB7CisJCUZvbGRlciBmb2xkZXIgPSBkZWZmb2xkZXIuZ2V0Rm9sZGVyKGFyZ3Zbb3B0aW5kXSk7CisJCWlmIChmb2xkZXIgPT0gbnVsbCkgeworCQkgICAgU3lzdGVtLm91dC5wcmludGxuKCJJbnZhbGlkIGZvbGRlcjogIiArIGFyZ3Zbb3B0aW5kXSk7CisJCSAgICBjb250aW51ZTsKKwkJfQorCQlTeXN0ZW0ub3V0LnByaW50bG4oIkZvbGRlcjogIiArIGZvbGRlci5nZXRGdWxsTmFtZSgpKTsKKworCQlmb2xkZXIub3BlbihGb2xkZXIuUkVBRF9PTkxZKTsKKwkJaW50IHRvdGFsTWVzc2FnZXMgPSBmb2xkZXIuZ2V0TWVzc2FnZUNvdW50KCk7CisKKwkJaWYgKHRvdGFsTWVzc2FnZXMgPT0gMCkgeworCQkgICAgU3lzdGVtLm91dC5wcmludGxuKCJFbXB0eSBmb2xkZXIiKTsKKwkJICAgIGZvbGRlci5jbG9zZShmYWxzZSk7CisJCSAgICBjb250aW51ZTsKKwkJfQorCisJCWlmICh2ZXJib3NlKSB7CisJCSAgICBpbnQgbmV3TWVzc2FnZXMgPSBmb2xkZXIuZ2V0TmV3TWVzc2FnZUNvdW50KCk7CisJCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlRvdGFsIG1lc3NhZ2VzID0gIiArIHRvdGFsTWVzc2FnZXMpOworCQkgICAgU3lzdGVtLm91dC5wcmludGxuKCJOZXcgbWVzc2FnZXMgPSAiICsgbmV3TWVzc2FnZXMpOworCQkgICAgU3lzdGVtLm91dC5wcmludGxuKCItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIik7CisJCX0KKworCQkvLyBBdHRyaWJ1dGVzICYgRmxhZ3MgZm9yIGFsbCBtZXNzYWdlcyAuLgorCQlNZXNzYWdlW10gbXNncyA9IGZvbGRlci5nZXRNZXNzYWdlcygpOworCisJCS8vIFVzZSBhIHN1aXRhYmxlIEZldGNoUHJvZmlsZQorCQlGZXRjaFByb2ZpbGUgZnAgPSBuZXcgRmV0Y2hQcm9maWxlKCk7CisJCWZwLmFkZChGZXRjaFByb2ZpbGUuSXRlbS5FTlZFTE9QRSk7CisJCWZwLmFkZChGZXRjaFByb2ZpbGUuSXRlbS5GTEFHUyk7CisJCWZvbGRlci5mZXRjaChtc2dzLCBmcCk7CisKKwkJZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisJCSAgICBpZiAodmVyYm9zZSkgeworCQkJU3lzdGVtLm91dC5wcmludGxuKCItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIpOworCQkJU3lzdGVtLm91dC5wcmludGxuKCJNRVNTQUdFICMiICsgKGkgKyAxKSArICI6Iik7CisJCSAgICB9CisJCSAgICBEYXRlIGQgPSBtc2dzW2ldLmdldFJlY2VpdmVkRGF0ZSgpOworCQkgICAgaWYgKGQgIT0gbnVsbCkgeworCQkJU3RyaW5nIG4gPSBkZi5mb3JtYXQoZCk7CisJCQlpZiAodmVyYm9zZSkKKwkJCSAgICBTeXN0ZW0ub3V0LnByaW50bG4obik7CisJCQlpZiAob3V0ZiA9PSBudWxsIHx8ICFuLmVxdWFscyhvdXRmLmdldE5hbWUoKSkpIHsKKwkJCSAgICBvdXRmID0gZHN0Zm9sZGVyLmdldEZvbGRlcihuKTsKKwkJCSAgICBpZiAoIW91dGYuZXhpc3RzKCkpIHsKKwkJCQlTeXN0ZW0ub3V0LnByaW50bG4oIkNyZWF0aW5nOiAiICsKKwkJCQkJCSAgICBvdXRmLmdldEZ1bGxOYW1lKCkpOworCQkJCWlmICghbm9wKQorCQkJCSAgICBvdXRmLmNyZWF0ZShGb2xkZXIuSE9MRFNfTUVTU0FHRVMpOworCQkJICAgIH0KKwkJCX0KKwkJICAgIH0KKwkJICAgIGlmICghbm9wKQorCQkJb3V0Zi5hcHBlbmRNZXNzYWdlcyhuZXcgTWVzc2FnZVtdIHsgbXNnc1tpXSB9KTsKKwkJfQorCQlmb2xkZXIuY2xvc2UoZmFsc2UpOworCSAgICB9CisKKwkgICAgc3RvcmUuY2xvc2UoKTsKKwl9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJPb3BzLCBnb3QgZXhjZXB0aW9uISAiICsgZXguZ2V0TWVzc2FnZSgpKTsKKwkgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7CisJfQorCVN5c3RlbS5leGl0KDEpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2RlbW8vc3JjL21haW4vamF2YS9pbnRlcm5hbC9mcG9wdWxhdGUuamF2YSBiL2RlbW8vc3JjL21haW4vamF2YS9pbnRlcm5hbC9mcG9wdWxhdGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MzMzMjEzCi0tLSAvZGV2L251bGwKKysrIGIvZGVtby9zcmMvbWFpbi9qYXZhL2ludGVybmFsL2Zwb3B1bGF0ZS5qYXZhCkBAIC0wLDAgKzEsMjA3IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBEaXN0cmlidXRpb24gTGljZW5zZSB2LiAxLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9vcmcvZG9jdW1lbnRzL2VkbC12MTAucGhwLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBCU0QtMy1DbGF1c2UKKyAqLworCitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmF4Lm1haWwuKjsKK2ltcG9ydCBqYXZheC5tYWlsLmludGVybmV0Lio7CisKKy8qCisgKiBDb3B5IGZvbGRlciBoaWVyYXJjaGllcyBiZXR3ZWVuIGZpbGVzIGFuZCBhIFN0b3JlLiBUaGlzIGlzIGEgdXNlZnVsIAorICogdXRpbGl0eSB0byBwb3B1bGF0ZSBuZXcgKGFuZCBwb3NzaWJseSBlbXB0eSkgbWFpbCBzdG9yZXMuIFNwZWNpZnkKKyAqIHRoZSBzb3VyY2UgYXMgYSBkaXJlY3RvcnkgbmFtZSBhbmQgdGhlIGRlc3RpbmF0aW9uIGZvbGRlcnMgYXMgYSBVUkwuCisgKgkKKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCisKK3B1YmxpYyBjbGFzcyBmcG9wdWxhdGUgeworCisgICAgc3RhdGljIGJvb2xlYW4gZm9yY2UgPSBmYWxzZTsKKyAgICBzdGF0aWMgYm9vbGVhbiBza2lwU0NDUyA9IGZhbHNlOworICAgIHN0YXRpYyBib29sZWFuIGNsZWFyID0gZmFsc2U7CisKKyAgICBzdGF0aWMgU2Vzc2lvbiBzZXNzaW9uOworCisgICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nIGFyZ3ZbXSkgeworICAgIAlTdHJpbmcgc3JjZGlyID0gbnVsbDsKKyAgICAJU3RyaW5nIGRzdFVSTCA9IG51bGw7CisJYm9vbGVhbiBkZWJ1ZyA9IGZhbHNlOworCisJaW50IG9wdGluZDsKKworCWZvciAob3B0aW5kID0gMDsgb3B0aW5kIDwgYXJndi5sZW5ndGg7IG9wdGluZCsrKSB7CisJICAgIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItcyIpKSB7CisJCXNyY2RpciA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1kIikpIHsKKwkJZHN0VVJMID0gYXJndlsrK29wdGluZF07CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLUQiKSkgeworCQlkZWJ1ZyA9IHRydWU7CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLWYiKSkgeworCQlmb3JjZSA9IHRydWU7CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLVMiKSkgeworCQlza2lwU0NDUyA9IHRydWU7CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLWMiKSkgeworCQljbGVhciA9IHRydWU7CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLS0iKSkgeworCQlvcHRpbmQrKzsKKwkJYnJlYWs7CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLnN0YXJ0c1dpdGgoIi0iKSkgeworCQlwcmludFVzYWdlKCk7CisJCVN5c3RlbS5leGl0KDEpOworCSAgICB9IGVsc2UgeworCQlicmVhazsKKwkgICAgfQorCX0KKworCXRyeSB7CisKKwkgICAgaWYgKHNyY2RpciA9PSBudWxsIHx8IGRzdFVSTCA9PSBudWxsKSB7CisJCXByaW50VXNhZ2UoKTsKKwkJU3lzdGVtLmV4aXQoMSk7CisJICAgIH0KKworCSAgICBzZXNzaW9uID0gU2Vzc2lvbi5nZXREZWZhdWx0SW5zdGFuY2UoCisJCQkJU3lzdGVtLmdldFByb3BlcnRpZXMoKSwgbnVsbCk7CisJICAgIHNlc3Npb24uc2V0RGVidWcoZGVidWcpOworCisJICAgIC8vIEdldCBzb3VyY2UgZm9sZGVyCisJICAgIEZpbGUgc3JjRm9sZGVyID0gbmV3IEZpbGUoc3JjZGlyKTsKKwkgICAgaWYgKCFzcmNGb2xkZXIuZXhpc3RzKCkpIHsKKwkJU3lzdGVtLm91dC5wcmludGxuKCJzb3VyY2UgZm9sZGVyIGRvZXMgbm90IGV4aXN0Iik7CisJCVN5c3RlbS5leGl0KDEpOworCSAgICB9CisKKwkgICAgLy8gU2V0IHVwIGRlc3RpbmF0aW9uIGZvbGRlcgorCSAgICBVUkxOYW1lIGRzdFVSTE5hbWUgPSBuZXcgVVJMTmFtZShkc3RVUkwpOworCSAgICBGb2xkZXIgZHN0Rm9sZGVyOworCSAgICAvLyBDaGVjayBpZiB0aGUgZGVzdGluYXRpb24gVVJMIGhhcyBhIGZvbGRlciBzcGVjaWZpZWQuIElmCisJICAgIC8vIG5vdCwgd2UgdXNlIHRoZSBzb3VyY2UgZm9sZGVyIG5hbWUKKwkgICAgaWYgKGRzdFVSTE5hbWUuZ2V0RmlsZSgpID09IG51bGwpIHsKKwkJU3RvcmUgcyA9IHNlc3Npb24uZ2V0U3RvcmUoZHN0VVJMTmFtZSk7CisJCXMuY29ubmVjdCgpOworCQlkc3RGb2xkZXIgPSBzLmdldEZvbGRlcihzcmNGb2xkZXIuZ2V0TmFtZSgpKTsKKwkgICAgfSBlbHNlCisJCWRzdEZvbGRlciA9IHNlc3Npb24uZ2V0Rm9sZGVyKG5ldyBVUkxOYW1lKGRzdFVSTCkpOworCisJICAgIGlmIChjbGVhciAmJiBkc3RGb2xkZXIuZXhpc3RzKCkpIHsKKwkJaWYgKCFkc3RGb2xkZXIuZGVsZXRlKHRydWUpKSB7CisJCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oImNvdWxkbid0IGRlbGV0ZSAiICsKKwkJCQkJCWRzdEZvbGRlci5nZXRGdWxsTmFtZSgpKTsKKwkJICAgIHJldHVybjsKKwkJfQorCSAgICB9CisJICAgIGNvcHkoc3JjRm9sZGVyLCBkc3RGb2xkZXIpOworCisJICAgIC8vIENsb3NlIHRoZSByZXNwZWN0aXZlIHN0b3Jlcy4KKwkgICAgZHN0Rm9sZGVyLmdldFN0b3JlKCkuY2xvc2UoKTsKKworCX0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBtZXgpIHsKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKG1leC5nZXRNZXNzYWdlKCkpOworCSAgICBtZXgucHJpbnRTdGFja1RyYWNlKCk7CisJfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9leCkgeworCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oaW9leC5nZXRNZXNzYWdlKCkpOworCSAgICBpb2V4LnByaW50U3RhY2tUcmFjZSgpOworCX0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGNvcHkoRmlsZSBzcmMsIEZvbGRlciBkc3QpCisJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKwlTeXN0ZW0ub3V0LnByaW50bG4oIlBvcHVsYXRpbmcgIiArIGRzdC5nZXRGdWxsTmFtZSgpKTsKKworCWlmICghZHN0LmV4aXN0cygpKSB7CisJICAgIC8vIENyZWF0ZSBpdC4KKwkgICAgaW50IHR5cGUgPSBob2xkc01lc3NhZ2VzKHNyYykgPworCQkgICAgRm9sZGVyLkhPTERTX01FU1NBR0VTIDogRm9sZGVyLkhPTERTX0ZPTERFUlM7CisJICAgIGlmICghZHN0LmNyZWF0ZSh0eXBlKSkgeworCQlTeXN0ZW0ub3V0LnByaW50bG4oImNvdWxkbid0IGNyZWF0ZSAiICsgZHN0LmdldEZ1bGxOYW1lKCkpOworCQlyZXR1cm47CisJICAgIH0KKworCSAgICAvLyBDb3B5IG92ZXIgYW55IG1lc3NhZ2VzIGZyb20gc3JjIHRvIGRzdAorCSAgICBpZiAoaG9sZHNNZXNzYWdlcyhzcmMpKQorCQljb3B5TWVzc2FnZXMoc3JjLCBkc3QpOworCX0gZWxzZSAgeworCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oZHN0LmdldEZ1bGxOYW1lKCkgKyAiIGFscmVhZHkgZXhpc3RzIik7CisJICAgIC8vIENvcHkgb3ZlciBhbnkgbWVzc2dlcyBmcm9tIHNyYyB0byBkc3QKKwkgICAgaWYgKGZvcmNlICYmIGhvbGRzTWVzc2FnZXMoc3JjKSkKKwkJY29weU1lc3NhZ2VzKHNyYywgZHN0KTsKKwl9CisKKwkvLyBDb3B5IG92ZXIgc3ViZm9sZGVycworCWlmIChob2xkc0ZvbGRlcnMoc3JjKSkgeworCSAgICBTdHJpbmdbXSBzZiA9IHNyYy5saXN0KCk7CisJICAgIGZvciAoaW50ICBpID0gMDsgc2YgIT0gbnVsbCAmJiBpIDwgc2YubGVuZ3RoOyBpKyspIHsKKwkJLy8gc2tpcCBTQ0NTIGRpcmVjdG9yaWVzPworCQlpZiAoc2tpcFNDQ1MgJiYgc2ZbaV0uZXF1YWxzKCJTQ0NTIikpCisJCSAgICBjb250aW51ZTsKKwkJRmlsZSBmID0gbmV3IEZpbGUoc3JjLCBzZltpXSk7CisJCWlmIChmLmlzRGlyZWN0b3J5KCkpCisJCSAgICBjb3B5KGYsIGRzdC5nZXRGb2xkZXIoc2ZbaV0pKTsKKwkgICAgfQorICAgIAl9CisgICAgfQorCisgICAgLyoqCisgICAgICogRG9lcyB0aGlzIGRpcmVjdG9yeSBob2xkIG1lc3NhZ2VzPworICAgICAqIFJldHVybiB0cnVlIGlmIHRoZXJlJ3MgYXQgbGVhc3Qgb25lIG1lc3NhZ2UuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBob2xkc01lc3NhZ2VzKEZpbGUgZikgeworCUZpbGUgbXNnID0gbmV3IEZpbGUoZiwgIjEiKTsKKwlyZXR1cm4gbXNnLmV4aXN0cygpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaG9sZHNGb2xkZXJzKEZpbGUgZikgeworCXJldHVybiAhaG9sZHNNZXNzYWdlcyhmKTsJLy8gWFhYIC0gaGFjayBmb3Igbm93CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29weSBtZXNzYWdlIGZpbGVzIGZyb20gdGhlIHNvdXJjZSBkaXJlY3RvcnkgdG8gdGhlCisgICAgICogZGVzdGluYXRpb24gZm9sZGVyLiAgTWVzc2FnZSBmaWxlcyBtdXN0IGJlIG5hbWVkICIxIiwKKyAgICAgKiAiMiIsIGV0Yy4gIFRoZSBmaXJzdCBtaXNzaW5nIG51bWJlciB0ZXJtaW5hdGVzIHRoZQorICAgICAqIGNvcHkuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBjb3B5TWVzc2FnZXMoRmlsZSBzcmMsIEZvbGRlciBkc3QpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworCVN5c3RlbS5vdXQucHJpbnRsbigiICBDb3B5IGZyb20gIiArIHNyYyArICIgdG8gIiArIGRzdCk7CisJaW50IG1zZ251bSA9IDE7CisJTWVzc2FnZVtdIG1zZ3MgPSBuZXcgTWVzc2FnZVsxXTsKKwlmb3IgKDs7KSB7CisJICAgIEZpbGUgZiA9IG5ldyBGaWxlKHNyYywgU3RyaW5nLnZhbHVlT2YobXNnbnVtKSk7CisJICAgIGlmICghZi5leGlzdHMoKSkJLy8gYnJlYWsgd2hlbiB3ZSBmaW5kIGEgbWVzc2FnZSBtaXNzaW5nCisJCWJyZWFrOworCSAgICBGaWxlSW5wdXRTdHJlYW0gZmlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShmKTsKKwkgICAgQnVmZmVyZWRJbnB1dFN0cmVhbSBpcyA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKGZpcyk7CisJICAgIGlzLm1hcmsoMTAyNCk7CisJICAgIERhdGFJbnB1dFN0cmVhbSBkaXMgPSBuZXcgRGF0YUlucHV0U3RyZWFtKGlzKTsKKwkgICAgU3RyaW5nIGxpbmUgPSBkaXMucmVhZExpbmUoKTsKKwkgICAgLyoKKwkgICAgICogSWYgaXQncyBpbiBVTklYIG1ib3ggZm9ybWF0LCB3ZSBza2lwIHRoZSBmaXJzdCBsaW5lLAorCSAgICAgKiBvdGhlcndpc2Ugd2Ugc3RhcnQgcmVhZGluZyBhdCB0aGUgYmVnaW5uaW5nLgorCSAgICAgKi8KKwkgICAgaWYgKCFsaW5lLnN0YXJ0c1dpdGgoIkZyb20gIikpCisJCWlzLnJlc2V0KCk7CisJICAgIE1pbWVNZXNzYWdlIG1zZyA9IG5ldyBNaW1lTWVzc2FnZShzZXNzaW9uLCBpcyk7CisJICAgIGZpcy5jbG9zZSgpOworCSAgICBtc2dzWzBdID0gbXNnOworCSAgICBkc3QuYXBwZW5kTWVzc2FnZXMobXNncyk7CisJICAgIG1zZ251bSsrOworCX0KKwlTeXN0ZW0ub3V0LnByaW50bG4oIiAgQ29waWVkICIgKyAobXNnbnVtIC0gMSkgKyAiIG1lc3NhZ2VzIik7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBwcmludFVzYWdlKCkgeworCVN5c3RlbS5vdXQucHJpbnRsbigiZnBvcHVsYXRlIFstRF0gWy1mXSBbLVNdIFstY10gIiArCisJCQkgICAiLXMgc291cmNlX2RpciAtZCBkZXN0X3VybCIpOworCVN5c3RlbS5vdXQucHJpbnRsbigiVVJMcyBhcmUgb2YgdGhlIGZvcm06ICIgKworCQkgIAkgICAicHJvdG9jb2w6Ly91c2VybmFtZTpwYXNzd29yZEBob3N0bmFtZS9mb2xkZXJuYW1lIik7CisJU3lzdGVtLm91dC5wcmludGxuKCJUaGUgZGVzdGluYXRpb24gVVJMIGRvZXMgbm90IG5lZWQgYSBmb2xkZXJuYW1lLCIgKworCQkgIAkgICAiIGluIHdoaWNoIGNhc2UsIHRoZSBzb3VyY2UgZm9sZGVybmFtZSBpcyB1c2VkIik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvZGVtby9zcmMvbWFpbi9qYXZhL2ludGVybmFsL21zZ3NwZXJ3ZWVrLmphdmEgYi9kZW1vL3NyYy9tYWluL2phdmEvaW50ZXJuYWwvbXNnc3BlcndlZWsuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MTA1Yjk3Ci0tLSAvZGV2L251bGwKKysrIGIvZGVtby9zcmMvbWFpbi9qYXZhL2ludGVybmFsL21zZ3NwZXJ3ZWVrLmphdmEKQEAgLTAsMCArMSwyNTEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorICovCisKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBqYXZhLnRleHQuKjsKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YXgubWFpbC4qOworaW1wb3J0IGphdmF4Lm1haWwuc2VhcmNoLio7CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC4qOworCisvKioKKyAqIFByb2dyYW0gdGhhdCBnZW5lcmF0ZXMgc3RhdHMgYWJvdXQgbmV3IG1lc3NhZ2VzIHJlY2VpdmVkIHBlciB3ZWVrIAorICogYnkgdGhlIGphdmFtYWlsQFN1bi5DT00gbWFpbGluZyBsaXN0LiBJdCB0cmFja3MgKm5ldyogbWVzc2FnZXMgb25seSwKKyAqIHRoZSBydWxlIGJlaW5nIHRoYXQgdGhlIG1lc3NhZ2UgaGFzIGEgc2luZ2xlIGFkZHJlc3NlZTogCisgKiAiamF2YW1haWxAU3VuLkNPTSIuIEFsc28gc2VhcmNoZXMgZWFjaCBtZXNzYWdlIGJvZHkgZm9yIHRoZSAicG9wMyIgCisgKiBzdHJpbmcgYW5kIGNvdW50cyBpdHMgb2NjdXJyZW5jZS4KKyAqIAorICogTm90ZSB0aGF0IHRoaXMgcHJvZ3JhbSBvcGVyYXRlcyBvbiB0aGUgbG9nIGZpbGUgZGlyZWN0bHkgYW5kIHRodXMgYWxsCisgKiBhY2Nlc3MgdG8gdGhlIGxvZyBmaWxlIHVzaW5nIHRoaXMgcHJvZ3JhbSBtdXN0IGJlIHRocm91Z2ggdGhlIHNhbWUKKyAqIElNQVAgc2VydmVyIHNvIHRoYXQgdGhlIGZsYWdzIGFyZSBoYW5kbGVkIGNvbnNpc3RlbnRseS4KKyAqCisgKiBAYXV0aG9yIE1heCBTcGl2YWsKKyAqLworCitwdWJsaWMgY2xhc3MgbXNnc3BlcndlZWsgeworCisgICAgc3RhdGljIFN0cmluZyBwcm90b2NvbCA9ICJpbWFwIjsKKyAgICBzdGF0aWMgU3RyaW5nIGhvc3QgPSAiYW55Ym9keXMuc2ZiYXkiOworICAgIHN0YXRpYyBTdHJpbmcgdXNlciA9ICJqYXZhbWFpbCI7CisgICAgc3RhdGljIFN0cmluZyBwYXNzd29yZCA9ICIxamF2YW1haWwxIjsKKyAgICBzdGF0aWMgU3RyaW5nIG1ib3ggPQorCSIvbmV0L2FueWJvZHlzLnNmYmF5L2V4cG9ydDYvamF2YW1haWwvbG9ncy9qYXZhbWFpbC5sb2ciOworICAgIHN0YXRpYyBTdHJpbmcgdXJsID0gbnVsbDsKKyAgICBzdGF0aWMgYm9vbGVhbiB2ZXJib3NlID0gZmFsc2U7CisgICAgc3RhdGljIGJvb2xlYW4gZG9Qb3AzID0gZmFsc2U7CisgICAgc3RhdGljIENhbGVuZGFyIGNhbCA9IG51bGw7CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmcgYXJndltdKSB7CisJaW50IG9wdGluZDsKKworCWZvciAob3B0aW5kID0gMDsgb3B0aW5kIDwgYXJndi5sZW5ndGg7IG9wdGluZCsrKSB7CisJICAgIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItVCIpKSB7CisJCXByb3RvY29sID0gYXJndlsrK29wdGluZF07CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLUgiKSkgeworCQlob3N0ID0gYXJndlsrK29wdGluZF07CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLVUiKSkgeworCQl1c2VyID0gYXJndlsrK29wdGluZF07CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLVAiKSkgeworCQlwYXNzd29yZCA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi12IikpIHsKKwkJdmVyYm9zZSA9IHRydWU7CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLWYiKSkgeworCQltYm94ID0gYXJndlsrK29wdGluZF07CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLUwiKSkgeworCQl1cmwgPSBhcmd2Wysrb3B0aW5kXTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItcCIpKSB7CisJCWRvUG9wMyA9IHRydWU7CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLS0iKSkgeworCQlvcHRpbmQrKzsKKwkJYnJlYWs7CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLnN0YXJ0c1dpdGgoIi0iKSkgeworCQlTeXN0ZW0ub3V0LnByaW50bG4oCisiVXNhZ2U6IG1zZ3BlcndlZWsgWy1MIHVybF0gWy1UIHByb3RvY29sXSBbLUggaG9zdF0gWy1VIHVzZXJdIFstUCBwYXNzd29yZF1cbiIrCisiXHRbLWYgbWFpbGJveF0gWy12XSBbLXBdIik7CisJCVN5c3RlbS5leGl0KDEpOworCSAgICB9IGVsc2UgeworCQlicmVhazsKKwkgICAgfQorCX0KKworCVN5c3RlbS5vdXQucHJpbnRsbigibXNnc3BlcndlZWs6IEdlbmVyYXRpbmcgc3RhdHMsIHBsZWFzZSB3YWl0Li4uIik7CisJCisJY2FsID0gQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoKTsKKwkKKyAgICAgICAgdHJ5IHsKKwkgICAgLy8gR2V0IGEgUHJvcGVydGllcyBvYmplY3QKKwkgICAgUHJvcGVydGllcyBwcm9wcyA9IFN5c3RlbS5nZXRQcm9wZXJ0aWVzKCk7CisKKwkgICAgLy8gR2V0IGEgU2Vzc2lvbiBvYmplY3QKKwkgICAgU2Vzc2lvbiBzZXNzaW9uID0gU2Vzc2lvbi5nZXREZWZhdWx0SW5zdGFuY2UocHJvcHMsCisJCQkJICAgIG5ldyBUdHlBdXRoZW50aWNhdG9yKCkpOworCisJICAgIC8vaWYgKHZlcmJvc2UpCisJICAgIC8vc2Vzc2lvbi5zZXREZWJ1Zyh0cnVlKTsKKworCSAgICAvLyBHZXQgYSBTdG9yZSBvYmplY3QKKwkgICAgU3RvcmUgc3RvcmUgPSBudWxsOworCSAgICBpZiAodXJsICE9IG51bGwpIHsKKwkJVVJMTmFtZSB1cmxuID0gbmV3IFVSTE5hbWUodXJsKTsKKwkJc3RvcmUgPSBzZXNzaW9uLmdldFN0b3JlKHVybG4pOworCQlzdG9yZS5jb25uZWN0KCk7CisJICAgIH0gZWxzZSB7CisJCWlmIChwcm90b2NvbCAhPSBudWxsKQkJCisJCSAgICBzdG9yZSA9IHNlc3Npb24uZ2V0U3RvcmUocHJvdG9jb2wpOworCQllbHNlCisJCSAgICBzdG9yZSA9IHNlc3Npb24uZ2V0U3RvcmUoKTsKKworCQkvLyBDb25uZWN0CisJCWlmIChob3N0ICE9IG51bGwgfHwgdXNlciAhPSBudWxsIHx8IHBhc3N3b3JkICE9IG51bGwpCisJCSAgICBzdG9yZS5jb25uZWN0KGhvc3QsIHVzZXIsIHBhc3N3b3JkKTsKKwkJZWxzZQorCQkgICAgc3RvcmUuY29ubmVjdCgpOworCSAgICB9CisJICAgIAorCisJICAgIC8vIE9wZW4gdGhlIEZvbGRlcgorCisJICAgIEZvbGRlciBmb2xkZXIgPSBzdG9yZS5nZXREZWZhdWx0Rm9sZGVyKCk7CisJICAgIGlmIChmb2xkZXIgPT0gbnVsbCkgeworCSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJObyBkZWZhdWx0IGZvbGRlciIpOworCSAgICAgICAgU3lzdGVtLmV4aXQoMSk7CisJICAgIH0KKworCSAgICBmb2xkZXIgPSBmb2xkZXIuZ2V0Rm9sZGVyKG1ib3gpOworCSAgICBpZiAoZm9sZGVyID09IG51bGwpIHsKKwkgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiSW52YWxpZCBmb2xkZXIiKTsKKwkgICAgICAgIFN5c3RlbS5leGl0KDEpOworCSAgICB9CisKKwkgICAgZm9sZGVyLm9wZW4oRm9sZGVyLlJFQURfT05MWSk7CisJICAgIGludCB0b3RhbE1lc3NhZ2VzID0gZm9sZGVyLmdldE1lc3NhZ2VDb3VudCgpOworCisJICAgIGlmICh0b3RhbE1lc3NhZ2VzID09IDApIHsKKwkJU3lzdGVtLm91dC5wcmludGxuKCJFbXB0eSBmb2xkZXIiKTsKKwkJZm9sZGVyLmNsb3NlKGZhbHNlKTsKKwkJc3RvcmUuY2xvc2UoKTsKKwkJU3lzdGVtLmV4aXQoMSk7CisJICAgIH0KKworCSAgICBpZiAodmVyYm9zZSkgeworCQlpbnQgbmV3TWVzc2FnZXMgPSBmb2xkZXIuZ2V0TmV3TWVzc2FnZUNvdW50KCk7CisJCXB2KCJUb3RhbCBtZXNzYWdlcyA9ICIgKyB0b3RhbE1lc3NhZ2VzKTsKKwkJcHYoIk5ldyBtZXNzYWdlcyA9ICIgKyBuZXdNZXNzYWdlcyk7CisJCXB2KCItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIik7CisJICAgIH0KKworCSAgICAvLyBVc2UgYSBzdWl0YWJsZSBGZXRjaFByb2ZpbGUKKwkgICAgRmV0Y2hQcm9maWxlIGZwID0gbmV3IEZldGNoUHJvZmlsZSgpOworCSAgICBmcC5hZGQoRmV0Y2hQcm9maWxlLkl0ZW0uRU5WRUxPUEUpOworCisJICAgIFNlYXJjaFRlcm0gdGVybSA9IG5ldyBSZWNpcGllbnRUZXJtKE1lc3NhZ2UuUmVjaXBpZW50VHlwZS5UTywKKwkJCQkgICAgIG5ldyBJbnRlcm5ldEFkZHJlc3MoImphdmFtYWlsQHN1bi5jb20iKSk7CisJICAgIE1lc3NhZ2VbXSBtc2dzID0gZm9sZGVyLnNlYXJjaCh0ZXJtKTsKKwkgICAgZm9sZGVyLmZldGNoKG1zZ3MsIGZwKTsKKworCSAgICBIYXNodGFibGUgd2tzID0gbmV3IEhhc2h0YWJsZSgpOworCSAgICBpbnQgdG90YWxDb3VudCA9IDA7CisJICAgIEJvZHlUZXJtIHBvcDNTZWFyY2ggPSBuZXcgQm9keVRlcm0oInBvcDMiKTsKKwkgICAgaW50IHBvcDNSZXF1ZXN0cyA9IDA7CisKKwkgICAgLy8gZ28gdGhyb3VnaCBlYWNoIG1zZyBhbmQgY291bnQgaXQgaWYgaXQncyBhbiBpbmNvbWluZyBtc2cKKwkgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisJCS8vIG1ha2Ugc3VyZSB3ZSBvbmx5IGhhdmUgYSBzaW5nbGUgYWRkcmVzc2VlOgorCQkvLyBqYXZhbWFpbEBzdW4uY29tLCB3aGljaCBtZWFucyBpdCdzIGEgbmV3IG1lc3NhZ2UKKwkJLy8gZnJvbSBvdXRzaWRlIG9mIFN1bgorCQlBZGRyZXNzW10gcmVjcz1tc2dzW2ldLmdldFJlY2lwaWVudHMoTWVzc2FnZS5SZWNpcGllbnRUeXBlLlRPKTsKKwkJaWYgKHJlY3MubGVuZ3RoID4gMSkKKwkJICAgIGNvbnRpbnVlOworCisJCS8vIGdldCBtc2dzIGRhdGUKKwkJRGF0ZSBkID0gbXNnc1tpXS5nZXRTZW50RGF0ZSgpOworCQlpZiAoZCA9PSBudWxsKQorCQkgICAgZCA9IG1zZ3NbaV0uZ2V0UmVjZWl2ZWREYXRlKCk7CisJCWNhbC5zZXRUaW1lKGQpOworCisJCS8vIGZpZ3VyZSBvdXQgd2hhdCB3ZWVrIGl0IGlzCisJCWludCB3ZWVrID0gY2FsLmdldChDYWxlbmRhci5XRUVLX09GX1lFQVIpOworCQlpbnQgeXIgPSBjYWwuZ2V0KENhbGVuZGFyLllFQVIpOworCQlTdHJpbmcgd2tJbllyID0gd2VlayArICIgICIgKyB5cjsKKworCQkvLyBpbmNyZW1lbnQgdGhhdCB3ZWVrJ3MgY291bnQKKwkJU3RyaW5nIG51bSA9IChTdHJpbmcpd2tzLmdldCh3a0luWXIpOworCQl0b3RhbENvdW50Kys7CisJCWlmIChudW0gPT0gbnVsbCkKKwkJICAgIHdrcy5wdXQod2tJbllyLCAiMSIpOworCQllbHNlIHsKKwkJICAgIGludCBjb3VudCA9IEludGVnZXIucGFyc2VJbnQobnVtKTsKKwkJICAgIGNvdW50Kys7CisJCSAgICBJbnRlZ2VyIHN0ciA9IG5ldyBJbnRlZ2VyKGNvdW50KTsKKwkJICAgIHdrcy5wdXQod2tJbllyLCBzdHIudG9TdHJpbmcoKSk7CisJCX0KKworCQkvLyBjaGVjayBmb3IgcG9wMyByZXF1ZXN0cworCQlpZiAoZG9Qb3AzICYmIHBvcDNTZWFyY2gubWF0Y2gobXNnc1tpXSkpCisJCSAgICBwb3AzUmVxdWVzdHMrKzsKKwkgICAgfQorCisJICAgIC8vIHByaW50IG91dCB0aGUgc3RhdGlzdGljcworCSAgICBpbnQgc3RhcnRXayA9IDQwOworCSAgICBpbnQgc3RhcnRZciA9IDE5OTc7CisJICAgIENhbGVuZGFyIG5vdyA9IENhbGVuZGFyLmdldEluc3RhbmNlKCk7CisJICAgIG5vdy5zZXRUaW1lKG5ldyBEYXRlKCkpOworCSAgICBjYWwuc2V0KHN0YXJ0WXIsIDEsIDEpOworCSAgICBjYWwuc2V0KENhbGVuZGFyLldFRUtfT0ZfWUVBUiwgc3RhcnRXayk7CisJICAgIGNhbC5zZXQoQ2FsZW5kYXIuREFZX09GX1dFRUssIENhbGVuZGFyLk1PTkRBWSk7CisJICAgIERhdGVGb3JtYXQgZGYgPSBuZXcgU2ltcGxlRGF0ZUZvcm1hdCgiRSBNTU0gZGQgeXl5eSIpOworCSAgICBpbnQgdG90YWxXa3MgPSAwOworCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXG5OdW1iZXIgb2YgbmV3IG1lc3NhZ2VzIGEgd2VlayBzZW50IHRvIGphdmFtYWlsQFN1bi5DT00gYnkgZXh0ZXJuYWwgSmF2YU1haWxcbnVzZXJzLiBUaGlzIGRvZXMgbm90IGluY2x1ZGUgb3VyIGFuc3dlcnMgYW5kIGZvbGxvdy11cCBtYWlsLiIpOworCSAgICBmb3IgKDs7KSB7CisJCWlmIChjYWwuYWZ0ZXIobm93KSkKKwkJICAgIGJyZWFrOworCQllbHNlIHsKKwkJICAgIHRvdGFsV2tzKys7CisJCSAgICBTdHJpbmcgd2tJbllyID0gKGNhbC5nZXQoQ2FsZW5kYXIuV0VFS19PRl9ZRUFSKSkgKworCQkJIiAgIiArIAorCQkJKGNhbC5nZXQoQ2FsZW5kYXIuWUVBUikpOworCQkgICAgT2JqZWN0IG8gPSB3a3MuZ2V0KHdrSW5Zcik7CisJCSAgICBpZiAobyAhPSBudWxsKSB7CisJCQlTdHJpbmcgaSA9IChTdHJpbmcpbzsKKwkJCVN5c3RlbS5vdXQucHJpbnRsbigiICB3ZWVrIG9mICIgKyAKKwkJCQkJICAgZGYuZm9ybWF0KGNhbC5nZXRUaW1lKCkpICsgCisJCQkJCSAgICI6ICIgKyAKKwkJCQkJICAgaSArICIgbWVzc2FnZXMiKTsKKwkJICAgIH0KKwkJICAgIAkJICAgIAorCQkgICAgLy8gaW5jcmVtZW50IHRvIG5leHQgd2VlaworCQkgICAgY2FsLmFkZChDYWxlbmRhci5XRUVLX09GX1lFQVIsIDEpOworCQl9CisJICAgIH0KKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCItLS0tLS0tLS0tLS0tLS0tLS0iKTsKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJUb3RhbCBtZXNzYWdlcyByZWNlaXZlZDogIiArIHRvdGFsQ291bnQpOworCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkF2ZXJhZ2UgbWVzc2FnZXMvd2VlazogICAgIiArIAorCQkJICAgICAgIHRvdGFsQ291bnQvdG90YWxXa3MpOworCSAgICBpZiAoZG9Qb3AzKQorCQlTeXN0ZW0ub3V0LnByaW50bG4oIlRvdGFsIFBPUDMgcmVxdWVzdHM6ICAgICAgIiArIHBvcDNSZXF1ZXN0cyk7CisJICAgIGZvbGRlci5jbG9zZShmYWxzZSk7CisJICAgIHN0b3JlLmNsb3NlKCk7CisJfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiT29wcywgZ290IGV4Y2VwdGlvbiEgIiArIGV4LmdldE1lc3NhZ2UoKSk7CisJICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOworCX0KKwlTeXN0ZW0uZXhpdCgxKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFByaW50IHZlcmJvc2UuCisgICAgICovCisgICAgc3RhdGljIHZvaWQgcHYoU3RyaW5nIHMpIHsKKwlpZiAodmVyYm9zZSkKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKHMpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2RlbW8vc3JjL21haW4vamF2YS9pbnRlcm5hbC90ZXN0aWRsZS5qYXZhIGIvZGVtby9zcmMvbWFpbi9qYXZhL2ludGVybmFsL3Rlc3RpZGxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmQ2NWY5YgotLS0gL2Rldi9udWxsCisrKyBiL2RlbW8vc3JjL21haW4vamF2YS9pbnRlcm5hbC90ZXN0aWRsZS5qYXZhCkBAIC0wLDAgKzEsNDk4IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBEaXN0cmlidXRpb24gTGljZW5zZSB2LiAxLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9vcmcvZG9jdW1lbnRzL2VkbC12MTAucGhwLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBCU0QtMy1DbGF1c2UKKyAqLworCitpbXBvcnQgamF2YS51dGlsLio7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLio7CitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmF4Lm1haWwuKjsKK2ltcG9ydCBqYXZheC5tYWlsLmV2ZW50Lio7CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC4qOworaW1wb3J0IGphdmF4LmFjdGl2YXRpb24uKjsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC5pbWFwLio7CisKKy8qKgorICogVGVzdCBwcm9ncmFtIGZvciBJRExFIHN1cHBvcnQgaW4gSU1BUCBwcm92aWRlci4KKyAqCisgKiBSdW4gc2V2ZXJhbCB0aHJlYWRzIHRoYXQgYWNjZXNzIHRoZSBmb2xkZXIncyBjb25uZWN0aW9uCisgKiB3aGlsZSBhbm90aGVyIHRocmVhZCBydW5zIHRoZSBJRExFIGNvbW1hbmQuICBBIHRpbWVyCisgKiB0aHJlYWQgY2hlY2tzIHRoYXQgZWFjaCB0aHJlYWQgaXMgbWFraW5nIHByb2dyZXNzLCB0bworICogZGV0ZWN0IGRlYWRsb2NrLgorICoKKyAqIFhYWCAtIFNob3VsZCBoYXZlIGFub3RoZXIgdGhyZWFkIGFkZCBtZXNzYWdlcyB0byB0aGUgZm9sZGVyCisgKgkgdG8gdGVzdCB0aGUgbmV3IG1lc3NhZ2Ugbm90aWZpY2F0aW9uIHdvcmtzIHByb3Blcmx5LgorICovCitwdWJsaWMgY2xhc3MgdGVzdGlkbGUgeworCisgICAgcHVibGljIHN0YXRpYyBTdG9yZSBzdG9yZTsKKyAgICBwdWJsaWMgc3RhdGljIEZvbGRlciBmb2xkZXI7CisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIHNob3dTdHJ1Y3R1cmUgPSBmYWxzZTsKKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gc2F2ZUF0dGFjaG1lbnRzID0gZmFsc2U7CisgICAgcHVibGljIHN0YXRpYyBpbnQgYXR0bnVtID0gMDsKKyAgICBwdWJsaWMgc3RhdGljIGludCB0b3RhbFRpbWU7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEF0b21pY0Jvb2xlYW4gc3RvcCA9IG5ldyBBdG9taWNCb29sZWFuKGZhbHNlKTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEF0b21pY0ludGVnZXIgZm9sZGVyUHJvZ3Jlc3MgPSBuZXcgQXRvbWljSW50ZWdlcigpOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQXRvbWljSW50ZWdlciBtc2dQcm9ncmVzcyA9IG5ldyBBdG9taWNJbnRlZ2VyKCk7CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmcgYXJndltdKSB7CisJaWYgKGFyZ3YubGVuZ3RoICE9IDUpIHsKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKAorCQkiVXNhZ2U6IHRlc3RpZGxlIDxob3N0PiA8dXNlcj4gPHBhc3N3b3JkPiA8bWJveD4gPHRpbWU+Iik7CisJICAgIFN5c3RlbS5leGl0KDEpOworCX0KKworICAgICAgICB0cnkgeworCSAgICBQcm9wZXJ0aWVzIHByb3BzID0gU3lzdGVtLmdldFByb3BlcnRpZXMoKTsKKworCSAgICAvLyBHZXQgYSBTZXNzaW9uIG9iamVjdAorCSAgICBTZXNzaW9uIHNlc3Npb24gPSBTZXNzaW9uLmdldEluc3RhbmNlKHByb3BzLCBudWxsKTsKKwkgICAgLy8gc2Vzc2lvbi5zZXREZWJ1Zyh0cnVlKTsKKworCSAgICAvLyBHZXQgYSBTdG9yZSBvYmplY3QKKwkgICAgc3RvcmUgPSBzZXNzaW9uLmdldFN0b3JlKCJpbWFwIik7CisKKwkgICAgc3RvcmUuYWRkU3RvcmVMaXN0ZW5lcihuZXcgU3RvcmVMaXN0ZW5lcigpIHsKKwkJcHVibGljIHZvaWQgbm90aWZpY2F0aW9uKFN0b3JlRXZlbnQgZSkgeworCQkgICAgU3lzdGVtLm91dC5wcmludGxuKCJTdG9yZUV2ZW50OiB0eXBlICIgKworCQkJZS5nZXRNZXNzYWdlVHlwZSgpICsgIiwgbWVzc2FnZSAiICsKKwkJCWUuZ2V0TWVzc2FnZSgpKTsKKwkJfQorCSAgICB9KTsKKworCSAgICAvLyBDb25uZWN0CisJICAgIHN0b3JlLmNvbm5lY3QoYXJndlswXSwgYXJndlsxXSwgYXJndlsyXSk7CisKKwkgICAgLy8gT3BlbiBhIEZvbGRlcgorCSAgICBmb2xkZXIgPSBzdG9yZS5nZXRGb2xkZXIoYXJndlszXSk7CisJICAgIGlmIChmb2xkZXIgPT0gbnVsbCB8fCAhZm9sZGVyLmV4aXN0cygpKSB7CisJCVN5c3RlbS5vdXQucHJpbnRsbigiSW52YWxpZCBmb2xkZXIiKTsKKwkJU3lzdGVtLmV4aXQoMSk7CisJICAgIH0KKworCSAgICBmb2xkZXIub3BlbihGb2xkZXIuUkVBRF9XUklURSk7CisKKwkgICAgLy8gQWRkIG1lc3NhZ2VDb3VudExpc3RlbmVyIHRvIGxpc3RlbiBmb3IgbmV3IG1lc3NhZ2VzCisJICAgIGZvbGRlci5hZGRNZXNzYWdlQ291bnRMaXN0ZW5lcihuZXcgTWVzc2FnZUNvdW50QWRhcHRlcigpIHsKKwkJcHVibGljIHZvaWQgbWVzc2FnZXNBZGRlZChNZXNzYWdlQ291bnRFdmVudCBldikgeworCQkgICAgTWVzc2FnZVtdIG1zZ3MgPSBldi5nZXRNZXNzYWdlcygpOworCQkgICAgU3lzdGVtLm91dC5wcmludGxuKCJHb3QgIiArIG1zZ3MubGVuZ3RoICsgIiBuZXcgbWVzc2FnZXMiKTsKKworCQkgICAgLy8gSnVzdCBkdW1wIG91dCB0aGUgbmV3IG1lc3NhZ2VzCisJCSAgICBmb3IgKGludCBpID0gMDsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspIHsKKwkJCXRyeSB7CisJCQkgICAgU3lzdGVtLm91dC5wcmludGxuKCItLS0tLSIpOworCQkJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiTWVzc2FnZSAiICsKKwkJCQltc2dzW2ldLmdldE1lc3NhZ2VOdW1iZXIoKSArICI6Iik7CisJCQkgICAgbXNnc1tpXS53cml0ZVRvKFN5c3RlbS5vdXQpOworCQkJfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9leCkgeyAKKwkJCSAgICBpb2V4LnByaW50U3RhY2tUcmFjZSgpOwkKKwkJCX0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBtZXgpIHsKKwkJCSAgICBtZXgucHJpbnRTdGFja1RyYWNlKCk7CisJCQl9CisJCSAgICB9CisJCX0KKwkgICAgfSk7CisKKwkgICAgdG90YWxUaW1lID0gSW50ZWdlci5wYXJzZUludChhcmd2WzRdKTsKKworCSAgICBuZXcgVGhyZWFkKCJ0aW1lciIpIHsKKwkJcHVibGljIHZvaWQgcnVuKCkgeworCQkgICAgdGltZXIoKTsKKwkJfQorCSAgICB9LnN0YXJ0KCk7CisKKwkgICAgbmV3IFRocmVhZCgibWVzc2FnZSByZWFkZXIiKSB7CisJCXB1YmxpYyB2b2lkIHJ1bigpIHsKKwkJICAgIHJlYWRNZXNzYWdlcygpOworCQl9CisJICAgIH0uc3RhcnQoKTsKKworCSAgICBuZXcgVGhyZWFkKCJmb2xkZXIgcmVhZGVyIikgeworCQlwdWJsaWMgdm9pZCBydW4oKSB7CisJCSAgICByZWFkRm9sZGVyKCk7CisJCX0KKwkgICAgfS5zdGFydCgpOworCisJICAgIG5ldyBUaHJlYWQoInN0b3JlIGlkbGUiKSB7CisJCXB1YmxpYyB2b2lkIHJ1bigpIHsKKwkJICAgIHN0b3JlSWRsZSgpOworCQl9CisJICAgIH0uc3RhcnQoKTsKKworCisJICAgIC8qCisJICAgICAqIG1ha2Ugc3VyZSB0d28gdGhyZWFkcyBydW5uaW5nIGlkbGUgd29ya3MgcHJvcGVybHkKKwkgICAgbmV3IFRocmVhZCgiaWRsZSIpIHsKKwkJcHVibGljIHZvaWQgcnVuKCkgeworCQkgICAgdHJ5IHsKKwkJCWRvSWRsZSgpOworCQkgICAgfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIG1leCkgeyB9CisJCX0KKwkgICAgfS5zdGFydCgpOworCSAgICAgKi8KKworCSAgICBkb0lkbGUoKTsKKworCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oImNvbm5lY3RlZCAiICsgc3RvcmUuaXNDb25uZWN0ZWQoKSk7CisKKwl9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKwkgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJ1biB0aGUgaWRsZSBjb21tYW5kIHVudGlsIHRvbGQgdG8gc3RvcC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgZG9JZGxlKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJYm9vbGVhbiBzdXBwb3J0c0lkbGUgPSBmYWxzZTsKKwl0cnkgeworCSAgICBpZiAoZm9sZGVyIGluc3RhbmNlb2YgSU1BUEZvbGRlcikgeworCQlJTUFQRm9sZGVyIGYgPSAoSU1BUEZvbGRlcilmb2xkZXI7CisJCWYuaWRsZSgpOworCQlzdXBwb3J0c0lkbGUgPSB0cnVlOworCSAgICB9CisJfSBjYXRjaCAoRm9sZGVyQ2xvc2VkRXhjZXB0aW9uIGZleCkgeworCSAgICB0aHJvdyBmZXg7CisJfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIG1leCkgeworCSAgICBzdXBwb3J0c0lkbGUgPSBmYWxzZTsKKwl9CisJd2hpbGUgKCFzdG9wLmdldCgpKSB7CisJICAgIGlmIChzdXBwb3J0c0lkbGUgJiYgZm9sZGVyIGluc3RhbmNlb2YgSU1BUEZvbGRlcikgeworCQlJTUFQRm9sZGVyIGYgPSAoSU1BUEZvbGRlcilmb2xkZXI7CisJCWYuaWRsZSgpOworCQkvKgorCQlTeXN0ZW0ub3V0LnByaW50bG4oIklETEUgZG9uZSBpbiAiICsKKwkJCQkJVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXROYW1lKCkpOworCQkgKi8KKwkgICAgfSBlbHNlIHsKKwkJdHJ5IHsKKwkJICAgIFRocmVhZC5zbGVlcCgxMDAwKTsgLy8gc2xlZXAgZm9yIDEwMDAgbWlsbGlzZWNvbmRzCisJCX0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGV4KSB7IH0KKworCQkvLyBUaGlzIGlzIHRvIGZvcmNlIHRoZSBJTUFQIHNlcnZlciB0byBzZW5kIHVzCisJCS8vIEVYSVNUUyBub3RpZmljYXRpb25zLiAKKwkJZm9sZGVyLmdldE1lc3NhZ2VDb3VudCgpOworCSAgICB9CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIE1vbml0b3IgcHJvZ3Jlc3Mgb2YgdGhyZWFkcyBhbmQgdGVsbCB0aGVtIHRvIHN0b3AKKyAgICAgKiB3aGVuIHRoZWlyIHRpbWUgaXMgdXAuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHRpbWVyKCkgeworCWxvbmcgdGVuZCA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpICsgdG90YWxUaW1lOworCWludCBmcGNudCA9IGZvbGRlclByb2dyZXNzLmdldCgpOworCWludCBtcGNudCA9IG1zZ1Byb2dyZXNzLmdldCgpOworCXdoaWxlIChTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSA8IHRlbmQpIHsKKwkgICAgdHJ5IHsKKwkJVGhyZWFkLnNsZWVwKDEwMDApOworCSAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBleCkgeyB9CisJICAgIGludCBuZnBjbnQgPSBmb2xkZXJQcm9ncmVzcy5nZXQoKTsKKwkgICAgaW50IG5tcGNudCA9IG1zZ1Byb2dyZXNzLmdldCgpOworCSAgICBpZiAoIShuZnBjbnQgPiBmcGNudCAmJiBubXBjbnQgPiBtcGNudCkpIHsKKwkJU3lzdGVtLm91dC5wcmludGxuKCJUSFJFQUQgU1RVQ0s/Iik7CisJCVN5c3RlbS5vdXQucHJpbnRmKCJmcGNudCAlZCBuZnBjbnQgJWRcbiIsIGZwY250LCBuZnBjbnQpOworCQlTeXN0ZW0ub3V0LnByaW50ZigibXBjbnQgJWQgbm1wY250ICVkXG4iLCBtcGNudCwgbm1wY250KTsKKwkgICAgfQorCSAgICBmcGNudCA9IG5mcGNudDsKKwkgICAgbXBjbnQgPSBubXBjbnQ7CisJfQorCVN5c3RlbS5vdXQucHJpbnRsbigiU1RPUFBJTkciKTsKKwlzdG9wLnNldCh0cnVlKTsKKwl0cnkgeworCSAgICBmb2xkZXIuZ2V0VW5yZWFkTWVzc2FnZUNvdW50KCk7CS8vIGZvcmNlIElETEUgdG8gdGVybWluYXRlCisJfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIG1leCkgeyB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZCBhbGwgdGhlIG1lc3NhZ2VzIGluIHRoZSBmb2xkZXIgYW5kIGFjY2VzcyBhbGwgdGhlaXIgY29udGVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgcmVhZE1lc3NhZ2VzKCkgeworCXRyeSB7CisJICAgIHdoaWxlICghc3RvcC5nZXQoKSkgeworCQlpbnQgY250ID0gZm9sZGVyLmdldE1lc3NhZ2VDb3VudCgpOworCQlmb3IgKGludCBpID0gMTsgaSA8PSBjbnQ7IGkrKykgeworCQkgICAgLy9TeXN0ZW0ub3V0LnByaW50bG4oImR1bXAgIiArIGkpOworCQkgICAgTWVzc2FnZSBtc2cgPSBmb2xkZXIuZ2V0TWVzc2FnZShpKTsKKwkJICAgIGR1bXBFbnZlbG9wZShtc2cpOworCQkgICAgbXNnUHJvZ3Jlc3MuaW5jcmVtZW50QW5kR2V0KCk7CisJCSAgICB0cnkgeworCQkJVGhyZWFkLnNsZWVwKDI1KTsKKwkJICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGV4KSB7IH0KKwkJfQorCSAgICB9CisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigibWVzc2FnZXMgRE9ORSIpOworCX0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oZXgpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtIGZvbGRlciBjb21tYW5kcyB0byBjb21wZXRlIHdpdGggdGhlIG1lc3NhZ2UKKyAgICAgKiBhY2Nlc3MgY29tbWFuZHMuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHJlYWRGb2xkZXIoKSB7CisJdHJ5IHsKKwkgICAgd2hpbGUgKCFzdG9wLmdldCgpKSB7CisJCWludCBjbnQgPSBmb2xkZXIuZ2V0VW5yZWFkTWVzc2FnZUNvdW50KCk7CisJCXN0b3JlLmlzQ29ubmVjdGVkKCk7CS8vIHBva2UgdGhlIHN0b3JlIHRvbworCQlmb2xkZXJQcm9ncmVzcy5pbmNyZW1lbnRBbmRHZXQoKTsKKwkJdHJ5IHsKKwkJICAgIFRocmVhZC5zbGVlcCgxMDApOworCQl9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBleCkgeyB9CisJICAgIH0KKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJmb2xkZXIgRE9ORSIpOworCX0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBtZXgpIHsKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKG1leCk7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJ1biB0aGUgaWRsZSBjb21tYW5kIHVudGlsIHRvbGQgdG8gc3RvcC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc3RvcmVJZGxlKCkgeworCWJvb2xlYW4gc3VwcG9ydHNJZGxlID0gZmFsc2U7CisJdHJ5IHsKKwkgICAgaWYgKHN0b3JlIGluc3RhbmNlb2YgSU1BUFN0b3JlKSB7CisJCUlNQVBTdG9yZSBzID0gKElNQVBTdG9yZSlzdG9yZTsKKwkJcy5pZGxlKCk7CisJCXN1cHBvcnRzSWRsZSA9IHRydWU7CisJICAgIH0KKwl9IGNhdGNoIChNZXNzYWdpbmdFeGNlcHRpb24gbWV4KSB7CisJICAgIHN1cHBvcnRzSWRsZSA9IGZhbHNlOworCX0KKwl0cnkgeworCSAgICB3aGlsZSAoIXN0b3AuZ2V0KCkpIHsKKwkJaWYgKHN1cHBvcnRzSWRsZSAmJiBzdG9yZSBpbnN0YW5jZW9mIElNQVBTdG9yZSkgeworCQkgICAgSU1BUFN0b3JlIHMgPSAoSU1BUFN0b3JlKXN0b3JlOworCQkgICAgcy5pZGxlKCk7CisJCSAgICAvKgorCQkgICAgKi8KKwkJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiSURMRSBkb25lIGluICIgKworCQkJCQkgICAgVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXROYW1lKCkpOworCQkgICAgIC8qCisJCSAgICAgKi8KKwkJfSBlbHNlIHsKKwkJICAgIHRyeSB7CisJCQlUaHJlYWQuc2xlZXAoMTAwMCk7IC8vIHNsZWVwIGZvciAxMDAwIG1pbGxpc2Vjb25kcworCQkgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZXgpIHsgfQorCQl9CisJICAgIH0KKwl9IGNhdGNoIChNZXNzYWdpbmdFeGNlcHRpb24gbWV4KSB7CisJICAgIFN5c3RlbS5vdXQucHJpbnRsbihtZXgpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEdW1wIGNvbnRlbnRzIG9mIG1lc3NhZ2UgcGFydC4KKyAgICAgKiAoQ29waWVkIGZyb20gbXNnc2hvdy5qYXZhKQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBkdW1wUGFydChQYXJ0IHApIHRocm93cyBFeGNlcHRpb24geworCWlmIChwIGluc3RhbmNlb2YgTWVzc2FnZSkKKwkgICAgZHVtcEVudmVsb3BlKChNZXNzYWdlKXApOworCisJLyoqIER1bXAgaW5wdXQgc3RyZWFtIC4uIAorCisJSW5wdXRTdHJlYW0gaXMgPSBwLmdldElucHV0U3RyZWFtKCk7CisJLy8gSWYgImlzIiBpcyBub3QgYWxyZWFkeSBidWZmZXJlZCwgd3JhcCBhIEJ1ZmZlcmVkSW5wdXRTdHJlYW0KKwkvLyBhcm91bmQgaXQuCisJaWYgKCEoaXMgaW5zdGFuY2VvZiBCdWZmZXJlZElucHV0U3RyZWFtKSkKKwkgICAgaXMgPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShpcyk7CisJaW50IGM7CisJd2hpbGUgKChjID0gaXMucmVhZCgpKSAhPSAtMSkKKwkgICAgU3lzdGVtLm91dC53cml0ZShjKTsKKworCSoqLworCisJU3RyaW5nIGN0ID0gcC5nZXRDb250ZW50VHlwZSgpOworCXRyeSB7CisJICAgIHByKCJDT05URU5ULVRZUEU6ICIgKyAobmV3IENvbnRlbnRUeXBlKGN0KSkudG9TdHJpbmcoKSk7CisJfSBjYXRjaCAoUGFyc2VFeGNlcHRpb24gcGV4KSB7CisJICAgIHByKCJCQUQgQ09OVEVOVC1UWVBFOiAiICsgY3QpOworCX0KKwlTdHJpbmcgZmlsZW5hbWUgPSBwLmdldEZpbGVOYW1lKCk7CisJaWYgKGZpbGVuYW1lICE9IG51bGwpCisJICAgIHByKCJGSUxFTkFNRTogIiArIGZpbGVuYW1lKTsKKworCS8qCisJICogVXNpbmcgaXNNaW1lVHlwZSB0byBkZXRlcm1pbmUgdGhlIGNvbnRlbnQgdHlwZSBhdm9pZHMKKwkgKiBmZXRjaGluZyB0aGUgYWN0dWFsIGNvbnRlbnQgZGF0YSB1bnRpbCB3ZSBuZWVkIGl0LgorCSAqLworCWlmIChwLmlzTWltZVR5cGUoInRleHQvcGxhaW4iKSkgeworCSAgICBwcigiVGhpcyBpcyBwbGFpbiB0ZXh0Iik7CisJICAgIHByKCItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0iKTsKKwkgICAgaWYgKCFzaG93U3RydWN0dXJlICYmICFzYXZlQXR0YWNobWVudHMpCisJCVN5c3RlbS5vdXQucHJpbnRsbigoU3RyaW5nKXAuZ2V0Q29udGVudCgpKTsKKwl9IGVsc2UgaWYgKHAuaXNNaW1lVHlwZSgibXVsdGlwYXJ0LyoiKSkgeworCSAgICBwcigiVGhpcyBpcyBhIE11bHRpcGFydCIpOworCSAgICBwcigiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIik7CisJICAgIE11bHRpcGFydCBtcCA9IChNdWx0aXBhcnQpcC5nZXRDb250ZW50KCk7CisJICAgIGxldmVsKys7CisJICAgIGludCBjb3VudCA9IG1wLmdldENvdW50KCk7CisJICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykKKwkJZHVtcFBhcnQobXAuZ2V0Qm9keVBhcnQoaSkpOworCSAgICBsZXZlbC0tOworCX0gZWxzZSBpZiAocC5pc01pbWVUeXBlKCJtZXNzYWdlL3JmYzgyMiIpKSB7CisJICAgIHByKCJUaGlzIGlzIGEgTmVzdGVkIE1lc3NhZ2UiKTsKKwkgICAgcHIoIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIpOworCSAgICBsZXZlbCsrOworCSAgICBkdW1wUGFydCgoUGFydClwLmdldENvbnRlbnQoKSk7CisJICAgIGxldmVsLS07CisJfSBlbHNlIHsKKwkgICAgaWYgKCFzaG93U3RydWN0dXJlICYmICFzYXZlQXR0YWNobWVudHMpIHsKKwkJLyoKKwkJICogSWYgd2UgYWN0dWFsbHkgd2FudCB0byBzZWUgdGhlIGRhdGEsIGFuZCBpdCdzIG5vdCBhCisJCSAqIE1JTUUgdHlwZSB3ZSBrbm93LCBmZXRjaCBpdCBhbmQgY2hlY2sgaXRzIEphdmEgdHlwZS4KKwkJICovCisJCU9iamVjdCBvID0gcC5nZXRDb250ZW50KCk7CisJCWlmIChvIGluc3RhbmNlb2YgU3RyaW5nKSB7CisJCSAgICBwcigiVGhpcyBpcyBhIHN0cmluZyIpOworCQkgICAgcHIoIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIpOworCQkgICAgU3lzdGVtLm91dC5wcmludGxuKChTdHJpbmcpbyk7CisJCX0gZWxzZSBpZiAobyBpbnN0YW5jZW9mIElucHV0U3RyZWFtKSB7CisJCSAgICBwcigiVGhpcyBpcyBqdXN0IGFuIGlucHV0IHN0cmVhbSIpOworCQkgICAgcHIoIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIpOworCQkgICAgSW5wdXRTdHJlYW0gaXMgPSAoSW5wdXRTdHJlYW0pbzsKKwkJICAgIGludCBjOworCQkgICAgd2hpbGUgKChjID0gaXMucmVhZCgpKSAhPSAtMSkKKwkJCVN5c3RlbS5vdXQud3JpdGUoYyk7CisJCX0gZWxzZSB7CisJCSAgICBwcigiVGhpcyBpcyBhbiB1bmtub3duIHR5cGUiKTsKKwkJICAgIHByKCItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0iKTsKKwkJICAgIHByKG8udG9TdHJpbmcoKSk7CisJCX0KKwkgICAgfSBlbHNlIHsKKwkJLy8ganVzdCBhIHNlcGFyYXRvcgorCQlwcigiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIik7CisJICAgIH0KKwl9CisKKwkvKgorCSAqIElmIHdlJ3JlIHNhdmluZyBhdHRhY2htZW50cywgd3JpdGUgb3V0IGFueXRoaW5nIHRoYXQKKwkgKiBsb29rcyBsaWtlIGFuIGF0dGFjaG1lbnQgaW50byBhbiBhcHByb3ByaWF0ZWx5IG5hbWVkCisJICogZmlsZS4gIERvbid0IG92ZXJ3cml0ZSBleGlzdGluZyBmaWxlcyB0byBwcmV2ZW50CisJICogbWlzdGFrZXMuCisJICovCisJaWYgKHNhdmVBdHRhY2htZW50cyAmJiBsZXZlbCAhPSAwICYmICFwLmlzTWltZVR5cGUoIm11bHRpcGFydC8qIikpIHsKKwkgICAgU3RyaW5nIGRpc3AgPSBwLmdldERpc3Bvc2l0aW9uKCk7CisJICAgIC8vIG1hbnkgbWFpbGVycyBkb24ndCBpbmNsdWRlIGEgQ29udGVudC1EaXNwb3NpdGlvbgorCSAgICBpZiAoZGlzcCA9PSBudWxsIHx8IGRpc3AuZXF1YWxzSWdub3JlQ2FzZShQYXJ0LkFUVEFDSE1FTlQpKSB7CisJCWlmIChmaWxlbmFtZSA9PSBudWxsKQorCQkgICAgZmlsZW5hbWUgPSAiQXR0YWNobWVudCIgKyBhdHRudW0rKzsKKwkJcHIoIlNhdmluZyBhdHRhY2htZW50IHRvIGZpbGUgIiArIGZpbGVuYW1lKTsKKwkJdHJ5IHsKKwkJICAgIEZpbGUgZiA9IG5ldyBGaWxlKGZpbGVuYW1lKTsKKwkJICAgIGlmIChmLmV4aXN0cygpKQorCQkJLy8gWFhYIC0gY291bGQgdHJ5IGEgc2VyaWVzIG9mIG5hbWVzCisJCQl0aHJvdyBuZXcgSU9FeGNlcHRpb24oImZpbGUgZXhpc3RzIik7CisJCSAgICAoKE1pbWVCb2R5UGFydClwKS5zYXZlRmlsZShmKTsKKwkJfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKwkJICAgIHByKCJGYWlsZWQgdG8gc2F2ZSBhdHRhY2htZW50OiAiICsgZXgpOworCQl9CisJCXByKCItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0iKTsKKwkgICAgfQorCX0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgZHVtcEVudmVsb3BlKE1lc3NhZ2UgbSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJcHIoIlRoaXMgaXMgdGhlIG1lc3NhZ2UgZW52ZWxvcGUiKTsKKwlwcigiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIik7CisJQWRkcmVzc1tdIGE7CisJLy8gRlJPTSAKKwlpZiAoKGEgPSBtLmdldEZyb20oKSkgIT0gbnVsbCkgeworCSAgICBmb3IgKGludCBqID0gMDsgaiA8IGEubGVuZ3RoOyBqKyspCisJCXByKCJGUk9NOiAiICsgYVtqXS50b1N0cmluZygpKTsKKwl9CisKKwkvLyBUTworCWlmICgoYSA9IG0uZ2V0UmVjaXBpZW50cyhNZXNzYWdlLlJlY2lwaWVudFR5cGUuVE8pKSAhPSBudWxsKSB7CisJICAgIGZvciAoaW50IGogPSAwOyBqIDwgYS5sZW5ndGg7IGorKykgeworCQlwcigiVE86ICIgKyBhW2pdLnRvU3RyaW5nKCkpOworCQlJbnRlcm5ldEFkZHJlc3MgaWEgPSAoSW50ZXJuZXRBZGRyZXNzKWFbal07CisJCWlmIChpYS5pc0dyb3VwKCkpIHsKKwkJICAgIEludGVybmV0QWRkcmVzc1tdIGFhID0gaWEuZ2V0R3JvdXAoZmFsc2UpOworCQkgICAgZm9yIChpbnQgayA9IDA7IGsgPCBhYS5sZW5ndGg7IGsrKykKKwkJCXByKCIgIEdST1VQOiAiICsgYWFba10udG9TdHJpbmcoKSk7CisJCX0KKwkgICAgfQorCX0KKworCS8vIFNVQkpFQ1QKKwlwcigiU1VCSkVDVDogIiArIG0uZ2V0U3ViamVjdCgpKTsKKworCS8vIERBVEUKKwlEYXRlIGQgPSBtLmdldFNlbnREYXRlKCk7CisJcHIoIlNlbmREYXRlOiAiICsKKwkgICAgKGQgIT0gbnVsbCA/IGQudG9TdHJpbmcoKSA6ICJVTktOT1dOIikpOworCisJLy8gRkxBR1MKKwlGbGFncyBmbGFncyA9IG0uZ2V0RmxhZ3MoKTsKKwlTdHJpbmdCdWZmZXIgc2IgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CisJRmxhZ3MuRmxhZ1tdIHNmID0gZmxhZ3MuZ2V0U3lzdGVtRmxhZ3MoKTsgLy8gZ2V0IHRoZSBzeXN0ZW0gZmxhZ3MKKworCWJvb2xlYW4gZmlyc3QgPSB0cnVlOworCWZvciAoaW50IGkgPSAwOyBpIDwgc2YubGVuZ3RoOyBpKyspIHsKKwkgICAgU3RyaW5nIHM7CisJICAgIEZsYWdzLkZsYWcgZiA9IHNmW2ldOworCSAgICBpZiAoZiA9PSBGbGFncy5GbGFnLkFOU1dFUkVEKQorCQlzID0gIlxcQW5zd2VyZWQiOworCSAgICBlbHNlIGlmIChmID09IEZsYWdzLkZsYWcuREVMRVRFRCkKKwkJcyA9ICJcXERlbGV0ZWQiOworCSAgICBlbHNlIGlmIChmID09IEZsYWdzLkZsYWcuRFJBRlQpCisJCXMgPSAiXFxEcmFmdCI7CisJICAgIGVsc2UgaWYgKGYgPT0gRmxhZ3MuRmxhZy5GTEFHR0VEKQorCQlzID0gIlxcRmxhZ2dlZCI7CisJICAgIGVsc2UgaWYgKGYgPT0gRmxhZ3MuRmxhZy5SRUNFTlQpCisJCXMgPSAiXFxSZWNlbnQiOworCSAgICBlbHNlIGlmIChmID09IEZsYWdzLkZsYWcuU0VFTikKKwkJcyA9ICJcXFNlZW4iOworCSAgICBlbHNlCisJCWNvbnRpbnVlOwkvLyBza2lwIGl0CisJICAgIGlmIChmaXJzdCkKKwkJZmlyc3QgPSBmYWxzZTsKKwkgICAgZWxzZQorCQlzYi5hcHBlbmQoJyAnKTsKKwkgICAgc2IuYXBwZW5kKHMpOworCX0KKworCVN0cmluZ1tdIHVmID0gZmxhZ3MuZ2V0VXNlckZsYWdzKCk7IC8vIGdldCB0aGUgdXNlciBmbGFnIHN0cmluZ3MKKwlmb3IgKGludCBpID0gMDsgaSA8IHVmLmxlbmd0aDsgaSsrKSB7CisJICAgIGlmIChmaXJzdCkKKwkJZmlyc3QgPSBmYWxzZTsKKwkgICAgZWxzZQorCQlzYi5hcHBlbmQoJyAnKTsKKwkgICAgc2IuYXBwZW5kKHVmW2ldKTsKKwl9CisJcHIoIkZMQUdTOiAiICsgc2IudG9TdHJpbmcoKSk7CisKKwkvLyBYLU1BSUxFUgorCVN0cmluZ1tdIGhkcnMgPSBtLmdldEhlYWRlcigiWC1NYWlsZXIiKTsKKwlpZiAoaGRycyAhPSBudWxsKQorCSAgICBwcigiWC1NYWlsZXI6ICIgKyBoZHJzWzBdKTsKKwllbHNlCisJICAgIHByKCJYLU1haWxlciBOT1QgYXZhaWxhYmxlIik7CisgICAgfQorCisgICAgc3RhdGljIFN0cmluZyBpbmRlbnRTdHIgPSAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiOworICAgIHN0YXRpYyBpbnQgbGV2ZWwgPSAwOworCisgICAgLyoqCisgICAgICogUHJpbnQgYSwgcG9zc2libHkgaW5kZW50ZWQsIHN0cmluZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgcHIoU3RyaW5nIHMpIHsKKwkvKgorCWlmIChzaG93U3RydWN0dXJlKQorCSAgICBTeXN0ZW0ub3V0LnByaW50KGluZGVudFN0ci5zdWJzdHJpbmcoMCwgbGV2ZWwgKiAyKSk7CisJU3lzdGVtLm91dC5wcmludGxuKHMpOworCSovCisgICAgfQorfQpkaWZmIC0tZ2l0IGEvZGVtby9zcmMvbWFpbi9qYXZhL21vbml0b3IuamF2YSBiL2RlbW8vc3JjL21haW4vamF2YS9tb25pdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODZmYjI5OQotLS0gL2Rldi9udWxsCisrKyBiL2RlbW8vc3JjL21haW4vamF2YS9tb25pdG9yLmphdmEKQEAgLTAsMCArMSwxMDcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTYsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorICovCisKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YXgubWFpbC4qOworaW1wb3J0IGphdmF4Lm1haWwuZXZlbnQuKjsKK2ltcG9ydCBqYXZheC5hY3RpdmF0aW9uLio7CisKK2ltcG9ydCBjb20uc3VuLm1haWwuaW1hcC4qOworCisvKiBNb25pdG9ycyBnaXZlbiBtYWlsYm94IGZvciBuZXcgbWFpbCAqLworCitwdWJsaWMgY2xhc3MgbW9uaXRvciB7CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmcgYXJndltdKSB7CisJaWYgKGFyZ3YubGVuZ3RoICE9IDUpIHsKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKAorCQkiVXNhZ2U6IG1vbml0b3IgPGhvc3Q+IDx1c2VyPiA8cGFzc3dvcmQ+IDxtYm94PiA8ZnJlcT4iKTsKKwkgICAgU3lzdGVtLmV4aXQoMSk7CisJfQorCVN5c3RlbS5vdXQucHJpbnRsbigiXG5UZXN0aW5nIG1vbml0b3JcbiIpOworCisJdHJ5IHsKKwkgICAgUHJvcGVydGllcyBwcm9wcyA9IFN5c3RlbS5nZXRQcm9wZXJ0aWVzKCk7CisKKwkgICAgLy8gR2V0IGEgU2Vzc2lvbiBvYmplY3QKKwkgICAgU2Vzc2lvbiBzZXNzaW9uID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShwcm9wcywgbnVsbCk7CisJICAgIC8vIHNlc3Npb24uc2V0RGVidWcodHJ1ZSk7CisKKwkgICAgLy8gR2V0IGEgU3RvcmUgb2JqZWN0CisJICAgIFN0b3JlIHN0b3JlID0gc2Vzc2lvbi5nZXRTdG9yZSgiaW1hcCIpOworCisJICAgIC8vIENvbm5lY3QKKwkgICAgc3RvcmUuY29ubmVjdChhcmd2WzBdLCBhcmd2WzFdLCBhcmd2WzJdKTsKKworCSAgICAvLyBPcGVuIGEgRm9sZGVyCisJICAgIEZvbGRlciBmb2xkZXIgPSBzdG9yZS5nZXRGb2xkZXIoYXJndlszXSk7CisJICAgIGlmIChmb2xkZXIgPT0gbnVsbCB8fCAhZm9sZGVyLmV4aXN0cygpKSB7CisJCVN5c3RlbS5vdXQucHJpbnRsbigiSW52YWxpZCBmb2xkZXIiKTsKKwkJU3lzdGVtLmV4aXQoMSk7CisJICAgIH0KKworCSAgICBmb2xkZXIub3BlbihGb2xkZXIuUkVBRF9XUklURSk7CisKKwkgICAgLy8gQWRkIG1lc3NhZ2VDb3VudExpc3RlbmVyIHRvIGxpc3RlbiBmb3IgbmV3IG1lc3NhZ2VzCisJICAgIGZvbGRlci5hZGRNZXNzYWdlQ291bnRMaXN0ZW5lcihuZXcgTWVzc2FnZUNvdW50QWRhcHRlcigpIHsKKwkJcHVibGljIHZvaWQgbWVzc2FnZXNBZGRlZChNZXNzYWdlQ291bnRFdmVudCBldikgeworCQkgICAgTWVzc2FnZVtdIG1zZ3MgPSBldi5nZXRNZXNzYWdlcygpOworCQkgICAgU3lzdGVtLm91dC5wcmludGxuKCJHb3QgIiArIG1zZ3MubGVuZ3RoICsgIiBuZXcgbWVzc2FnZXMiKTsKKworCQkgICAgLy8gSnVzdCBkdW1wIG91dCB0aGUgbmV3IG1lc3NhZ2VzCisJCSAgICBmb3IgKGludCBpID0gMDsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspIHsKKwkJCXRyeSB7CisJCQkgICAgU3lzdGVtLm91dC5wcmludGxuKCItLS0tLSIpOworCQkJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiTWVzc2FnZSAiICsKKwkJCQltc2dzW2ldLmdldE1lc3NhZ2VOdW1iZXIoKSArICI6Iik7CisJCQkgICAgbXNnc1tpXS53cml0ZVRvKFN5c3RlbS5vdXQpOworCQkJfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9leCkgeyAKKwkJCSAgICBpb2V4LnByaW50U3RhY2tUcmFjZSgpOwkKKwkJCX0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBtZXgpIHsKKwkJCSAgICBtZXgucHJpbnRTdGFja1RyYWNlKCk7CisJCQl9CisJCSAgICB9CisJCX0KKwkgICAgfSk7CisJCQkKKwkgICAgLy8gQ2hlY2sgbWFpbCBvbmNlIGluICJmcmVxIiBNSUxMSXNlY29uZHMKKwkgICAgaW50IGZyZXEgPSBJbnRlZ2VyLnBhcnNlSW50KGFyZ3ZbNF0pOworCSAgICBib29sZWFuIHN1cHBvcnRzSWRsZSA9IGZhbHNlOworCSAgICB0cnkgeworCQlpZiAoZm9sZGVyIGluc3RhbmNlb2YgSU1BUEZvbGRlcikgeworCQkgICAgSU1BUEZvbGRlciBmID0gKElNQVBGb2xkZXIpZm9sZGVyOworCQkgICAgZi5pZGxlKCk7CisJCSAgICBzdXBwb3J0c0lkbGUgPSB0cnVlOworCQl9CisJICAgIH0gY2F0Y2ggKEZvbGRlckNsb3NlZEV4Y2VwdGlvbiBmZXgpIHsKKwkJdGhyb3cgZmV4OworCSAgICB9IGNhdGNoIChNZXNzYWdpbmdFeGNlcHRpb24gbWV4KSB7CisJCXN1cHBvcnRzSWRsZSA9IGZhbHNlOworCSAgICB9CisJICAgIGZvciAoOzspIHsKKwkJaWYgKHN1cHBvcnRzSWRsZSAmJiBmb2xkZXIgaW5zdGFuY2VvZiBJTUFQRm9sZGVyKSB7CisJCSAgICBJTUFQRm9sZGVyIGYgPSAoSU1BUEZvbGRlcilmb2xkZXI7CisJCSAgICBmLmlkbGUoKTsKKwkJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiSURMRSBkb25lIik7CisJCX0gZWxzZSB7CisJCSAgICBUaHJlYWQuc2xlZXAoZnJlcSk7IC8vIHNsZWVwIGZvciBmcmVxIG1pbGxpc2Vjb25kcworCisJCSAgICAvLyBUaGlzIGlzIHRvIGZvcmNlIHRoZSBJTUFQIHNlcnZlciB0byBzZW5kIHVzCisJCSAgICAvLyBFWElTVFMgbm90aWZpY2F0aW9ucy4gCisJCSAgICBmb2xkZXIuZ2V0TWVzc2FnZUNvdW50KCk7CisJCX0KKwkgICAgfQorCisJfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOworCX0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9kZW1vL3NyYy9tYWluL2phdmEvbW92ZXIuamF2YSBiL2RlbW8vc3JjL21haW4vamF2YS9tb3Zlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFjZjJlMGQKLS0tIC9kZXYvbnVsbAorKysgYi9kZW1vL3NyYy9tYWluL2phdmEvbW92ZXIuamF2YQpAQCAtMCwwICsxLDE1OSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NiwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgRGlzdHJpYnV0aW9uIExpY2Vuc2Ugdi4gMS4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvb3JnL2RvY3VtZW50cy9lZGwtdjEwLnBocC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQlNELTMtQ2xhdXNlCisgKi8KKworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBqYXZheC5tYWlsLio7CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC4qOworCisvKiBNT1ZFIG1lc3NhZ2VzIGJldHdlZW4gbWFpbGJveGVzICovCisKK3B1YmxpYyBjbGFzcyBtb3ZlciB7CisKKyAgICBzdGF0aWMgU3RyaW5nIHByb3RvY29sID0gImltYXAiOworICAgIHN0YXRpYyBTdHJpbmcgaG9zdCA9IG51bGw7CisgICAgc3RhdGljIFN0cmluZyB1c2VyID0gbnVsbDsKKyAgICBzdGF0aWMgU3RyaW5nIHBhc3N3b3JkID0gbnVsbDsKKyAgICBzdGF0aWMgU3RyaW5nIHNyYyA9IG51bGw7CisgICAgc3RhdGljIFN0cmluZyBkZXN0ID0gbnVsbDsKKyAgICBzdGF0aWMgYm9vbGVhbiBleHB1bmdlID0gZmFsc2U7CisgICAgc3RhdGljIFN0cmluZyB1cmwgPSBudWxsOworCisgICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nIGFyZ3ZbXSkgeworCWludCBzdGFydCA9IDE7IGludCBlbmQgPSAtMTsKKwlpbnQgb3B0aW5kOworCisJZm9yIChvcHRpbmQgPSAwOyBvcHRpbmQgPCBhcmd2Lmxlbmd0aDsgb3B0aW5kKyspIHsKKwkgICAgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1UIikpIHsgCSAgICAvLyBwcm90b2NvbAorCQlwcm90b2NvbCA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1IIikpIHsgLy8gaG9zdAorCQlob3N0ID0gYXJndlsrK29wdGluZF07CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLVUiKSkgeyAvLyB1c2VyCisJCXVzZXIgPSBhcmd2Wysrb3B0aW5kXTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItUCIpKSB7IC8vIHBhc3N3b3JkCisJCXBhc3N3b3JkID0gYXJndlsrK29wdGluZF07CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLUwiKSkgeworCQl1cmwgPSBhcmd2Wysrb3B0aW5kXTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItcyIpKSB7IC8vIFNvdXJjZSBtYm94CisJCXNyYyA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1kIikpIHsgLy8gRGVzdGluYXRpb24gbWJveAorCQlkZXN0ID0gYXJndlsrK29wdGluZF07CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLXgiKSkgeyAvLyBFeHB1bmdlID8KKwkJZXhwdW5nZSA9IHRydWU7CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLS0iKSkgeworCQlvcHRpbmQrKzsKKwkJYnJlYWs7CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLnN0YXJ0c1dpdGgoIi0iKSkgeworCQlTeXN0ZW0ub3V0LnByaW50bG4oCisiVXNhZ2U6IG1vdmVyIFstVCBwcm90b2NvbF0gWy1IIGhvc3RdIFstVSB1c2VyXSBbLVAgcGFzc3dvcmRdIFstTCB1cmxdIFstdl0iKTsKKwkJU3lzdGVtLm91dC5wcmludGxuKAorIlx0Wy1zIHNvdXJjZSBtYm94XSBbLWQgZGVzdGluYXRpb24gbWJveF0gWy14XSBbbXNnbnVtMV0gW21zZ251bTJdIik7CisJCVN5c3RlbS5vdXQucHJpbnRsbigKKyJcdCBUaGUgLXggb3B0aW9uID0+IEVYUFVOR0UgZGVsZXRlZCBtZXNzYWdlcyIpOworCQlTeXN0ZW0ub3V0LnByaW50bG4oCisiXHQgbXNnbnVtMSA9PiBzdGFydCBvZiBtZXNzYWdlLXJhbmdlOyBtc2dudW0yID0+IGVuZCBvZiBtZXNzYWdlLXJhbmdlIik7CisJCVN5c3RlbS5leGl0KDEpOworCSAgICB9IGVsc2UgeworCQlicmVhazsKKwkgICAgfQorCX0KKworCWlmIChvcHRpbmQgPCBhcmd2Lmxlbmd0aCkKKwkgICAgc3RhcnQgPSBJbnRlZ2VyLnBhcnNlSW50KGFyZ3Zbb3B0aW5kKytdKTsgLy8gc3RhcnQgbXNnCisKKwlpZiAob3B0aW5kIDwgYXJndi5sZW5ndGgpCisJICAgIGVuZCA9IEludGVnZXIucGFyc2VJbnQoYXJndltvcHRpbmQrK10pOyAgIC8vIGVuZCBtc2cKKworCXRyeSB7CisJICAgIC8vIEdldCBhIFByb3BlcnRpZXMgb2JqZWN0CisJICAgIFByb3BlcnRpZXMgcHJvcHMgPSBTeXN0ZW0uZ2V0UHJvcGVydGllcygpOworCisJICAgIC8vIEdldCBhIFNlc3Npb24gb2JqZWN0CisJICAgIFNlc3Npb24gc2Vzc2lvbiA9IFNlc3Npb24uZ2V0SW5zdGFuY2UocHJvcHMsIG51bGwpOworCisJICAgIC8vIEdldCBhIFN0b3JlIG9iamVjdAorCSAgICBTdG9yZSBzdG9yZSA9IG51bGw7CisJICAgIGlmICh1cmwgIT0gbnVsbCkgeworCQlVUkxOYW1lIHVybG4gPSBuZXcgVVJMTmFtZSh1cmwpOworCQlzdG9yZSA9IHNlc3Npb24uZ2V0U3RvcmUodXJsbik7CisJCXN0b3JlLmNvbm5lY3QoKTsKKwkgICAgfSBlbHNlIHsKKwkJaWYgKHByb3RvY29sICE9IG51bGwpCQkKKwkJICAgIHN0b3JlID0gc2Vzc2lvbi5nZXRTdG9yZShwcm90b2NvbCk7CisJCWVsc2UKKwkJICAgIHN0b3JlID0gc2Vzc2lvbi5nZXRTdG9yZSgpOworCisJCS8vIENvbm5lY3QKKwkJaWYgKGhvc3QgIT0gbnVsbCB8fCB1c2VyICE9IG51bGwgfHwgcGFzc3dvcmQgIT0gbnVsbCkKKwkJICAgIHN0b3JlLmNvbm5lY3QoaG9zdCwgdXNlciwgcGFzc3dvcmQpOworCQllbHNlCisJCSAgICBzdG9yZS5jb25uZWN0KCk7CisJICAgIH0KKwkgICAgCisKKwkgICAgLy8gT3BlbiBzb3VyY2UgRm9sZGVyCisJICAgIEZvbGRlciBmb2xkZXIgPSBzdG9yZS5nZXRGb2xkZXIoc3JjKTsKKwkgICAgaWYgKGZvbGRlciA9PSBudWxsIHx8ICFmb2xkZXIuZXhpc3RzKCkpIHsKKwkJU3lzdGVtLm91dC5wcmludGxuKCJJbnZhbGlkIGZvbGRlcjogIiArIHNyYyk7CisJCVN5c3RlbS5leGl0KDEpOworCSAgICB9CisKKwkgICAgZm9sZGVyLm9wZW4oRm9sZGVyLlJFQURfV1JJVEUpOworCisJICAgIGludCBjb3VudCA9IGZvbGRlci5nZXRNZXNzYWdlQ291bnQoKTsKKwkgICAgaWYgKGNvdW50ID09IDApIHsgLy8gTm8gbWVzc2FnZXMgaW4gdGhlIHNvdXJjZSBmb2xkZXIKKwkJU3lzdGVtLm91dC5wcmludGxuKGZvbGRlci5nZXROYW1lKCkgKyAiIGlzIGVtcHR5Iik7CisJCS8vIENsb3NlIGZvbGRlciwgc3RvcmUgYW5kIHJldHVybgorCQlmb2xkZXIuY2xvc2UoZmFsc2UpOworCQlzdG9yZS5jbG9zZSgpOworCQlyZXR1cm47CisJICAgIH0KKworCSAgICAvLyBPcGVuIGRlc3RpbmF0aW9uIGZvbGRlciwgY3JlYXRlIGlmIHJlcWQKKwkgICAgRm9sZGVyIGRmb2xkZXIgPSBzdG9yZS5nZXRGb2xkZXIoZGVzdCk7CisJICAgIGlmICghZGZvbGRlci5leGlzdHMoKSkKKwkJZGZvbGRlci5jcmVhdGUoRm9sZGVyLkhPTERTX01FU1NBR0VTKTsKKworCSAgICBpZiAoZW5kID09IC0xKQorCQllbmQgPSBjb3VudDsKKworCSAgICAvLyBHZXQgdGhlIG1lc3NhZ2Ugb2JqZWN0cyB0byBjb3B5CisJICAgIE1lc3NhZ2VbXSBtc2dzID0gZm9sZGVyLmdldE1lc3NhZ2VzKHN0YXJ0LCBlbmQpOworCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIk1vdmluZyAiICsgbXNncy5sZW5ndGggKyAiIG1lc3NhZ2VzIik7CisKKwkgICAgaWYgKG1zZ3MubGVuZ3RoICE9IDApIHsKKwkJZm9sZGVyLmNvcHlNZXNzYWdlcyhtc2dzLCBkZm9sZGVyKTsKKwkJZm9sZGVyLnNldEZsYWdzKG1zZ3MsIG5ldyBGbGFncyhGbGFncy5GbGFnLkRFTEVURUQpLCB0cnVlKTsKKworCQkvLyBEdW1wIG91dCB0aGUgRmxhZ3Mgb2YgdGhlIG1vdmVkIG1lc3NhZ2VzLCB0byBpbnN1cmUgdGhhdAorCQkvLyBhbGwgZ290IGRlbGV0ZWQKKwkJZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisJCSAgICBpZiAoIW1zZ3NbaV0uaXNTZXQoRmxhZ3MuRmxhZy5ERUxFVEVEKSkKKwkJCVN5c3RlbS5vdXQucHJpbnRsbigiTWVzc2FnZSAjICIgKyBtc2dzW2ldICsgCisJCQkJCQkiIG5vdCBkZWxldGVkIik7CisJCX0KKwkgICAgfQorCSAgICAKKwkgICAgLy8gQ2xvc2UgZm9sZGVycyBhbmQgc3RvcmUKKwkgICAgZm9sZGVyLmNsb3NlKGV4cHVuZ2UpOworCSAgICBzdG9yZS5jbG9zZSgpOworCisJfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIG1leCkgeworCSAgICBFeGNlcHRpb24gZXggPSBtZXg7CisJICAgIGRvIHsKKwkJU3lzdGVtLm91dC5wcmludGxuKGV4LmdldE1lc3NhZ2UoKSk7CisJCWlmIChleCBpbnN0YW5jZW9mIE1lc3NhZ2luZ0V4Y2VwdGlvbikKKwkJICAgIGV4ID0gKChNZXNzYWdpbmdFeGNlcHRpb24pZXgpLmdldE5leHRFeGNlcHRpb24oKTsKKwkJZWxzZQorCQkgICAgZXggPSBudWxsOworCSAgICB9IHdoaWxlIChleCAhPSBudWxsKTsKKwl9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvZGVtby9zcmMvbWFpbi9qYXZhL21zZ211bHRpc2VuZHNhbXBsZS5qYXZhIGIvZGVtby9zcmMvbWFpbi9qYXZhL21zZ211bHRpc2VuZHNhbXBsZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFiZGUwZGMKLS0tIC9kZXYvbnVsbAorKysgYi9kZW1vL3NyYy9tYWluL2phdmEvbXNnbXVsdGlzZW5kc2FtcGxlLmphdmEKQEAgLTAsMCArMSw4OCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NiwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgRGlzdHJpYnV0aW9uIExpY2Vuc2Ugdi4gMS4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvb3JnL2RvY3VtZW50cy9lZGwtdjEwLnBocC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQlNELTMtQ2xhdXNlCisgKi8KKworaW1wb3J0IGphdmEudXRpbC4qOworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZheC5tYWlsLio7CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC4qOworaW1wb3J0IGphdmF4LmFjdGl2YXRpb24uKjsKKworLyoqCisgKiBtc2dtdWx0aXNlbmRzYW1wbGUgY3JlYXRlcyBhIHNpbXBsZSBtdWx0aXBhcnQvbWl4ZWQgbWVzc2FnZSBhbmQgc2VuZHMgaXQuCisgKiBCb3RoIGJvZHkgcGFydHMgYXJlIHRleHQvcGxhaW4uCisgKiA8cD4KKyAqIHVzYWdlOiA8Y29kZT5qYXZhIG1zZ211bHRpc2VuZHNhbXBsZSA8aT50byBmcm9tIHNtdHAgdHJ1ZXxmYWxzZTwvaT48L2NvZGU+CisgKiB3aGVyZSA8aT50bzwvaT4gYW5kIDxpPmZyb208L2k+IGFyZSB0aGUgZGVzdGluYXRpb24gYW5kCisgKiBvcmlnaW4gZW1haWwgYWRkcmVzc2VzLCByZXNwZWN0aXZlbHksIGFuZCA8aT5zbXRwPC9pPgorICogaXMgdGhlIGhvc3RuYW1lIG9mIHRoZSBtYWNoaW5lIHRoYXQgaGFzIHNtdHAgc2VydmVyCisgKiBydW5uaW5nLiAgVGhlIGxhc3QgcGFyYW1ldGVyIGVpdGhlciB0dXJucyBvbiBvciB0dXJucyBvZmYKKyAqIGRlYnVnZ2luZyBkdXJpbmcgc2VuZGluZy4KKyAqCisgKiBAYXV0aG9yCU1heCBTcGl2YWsKKyAqLworcHVibGljIGNsYXNzIG1zZ211bHRpc2VuZHNhbXBsZSB7CisgICAgc3RhdGljIFN0cmluZyBtc2dUZXh0MSA9ICJUaGlzIGlzIGEgbWVzc2FnZSBib2R5LlxuSGVyZSdzIGxpbmUgdHdvLiI7CisgICAgc3RhdGljIFN0cmluZyBtc2dUZXh0MiA9ICJUaGlzIGlzIHRoZSB0ZXh0IGluIHRoZSBtZXNzYWdlIGF0dGFjaG1lbnQuIjsKKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHsKKwlpZiAoYXJncy5sZW5ndGggIT0gNCkgeworCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oInVzYWdlOiBqYXZhIG1zZ211bHRpc2VuZCA8dG8+IDxmcm9tPiA8c210cD4gdHJ1ZXxmYWxzZSIpOworCSAgICByZXR1cm47CisJfQorCisJU3RyaW5nIHRvID0gYXJnc1swXTsKKwlTdHJpbmcgZnJvbSA9IGFyZ3NbMV07CisJU3RyaW5nIGhvc3QgPSBhcmdzWzJdOworCWJvb2xlYW4gZGVidWcgPSBCb29sZWFuLnZhbHVlT2YoYXJnc1szXSkuYm9vbGVhblZhbHVlKCk7CisKKwkvLyBjcmVhdGUgc29tZSBwcm9wZXJ0aWVzIGFuZCBnZXQgdGhlIGRlZmF1bHQgU2Vzc2lvbgorCVByb3BlcnRpZXMgcHJvcHMgPSBuZXcgUHJvcGVydGllcygpOworCXByb3BzLnB1dCgibWFpbC5zbXRwLmhvc3QiLCBob3N0KTsKKworCVNlc3Npb24gc2Vzc2lvbiA9IFNlc3Npb24uZ2V0SW5zdGFuY2UocHJvcHMsIG51bGwpOworCXNlc3Npb24uc2V0RGVidWcoZGVidWcpOworCQorCXRyeSB7CisJICAgIC8vIGNyZWF0ZSBhIG1lc3NhZ2UKKwkgICAgTWltZU1lc3NhZ2UgbXNnID0gbmV3IE1pbWVNZXNzYWdlKHNlc3Npb24pOworCSAgICBtc2cuc2V0RnJvbShuZXcgSW50ZXJuZXRBZGRyZXNzKGZyb20pKTsKKwkgICAgSW50ZXJuZXRBZGRyZXNzW10gYWRkcmVzcyA9IHtuZXcgSW50ZXJuZXRBZGRyZXNzKHRvKX07CisJICAgIG1zZy5zZXRSZWNpcGllbnRzKE1lc3NhZ2UuUmVjaXBpZW50VHlwZS5UTywgYWRkcmVzcyk7CisJICAgIG1zZy5zZXRTdWJqZWN0KCJKYXZhTWFpbCBBUElzIE11bHRpcGFydCBUZXN0Iik7CisJICAgIG1zZy5zZXRTZW50RGF0ZShuZXcgRGF0ZSgpKTsKKworCSAgICAvLyBjcmVhdGUgYW5kIGZpbGwgdGhlIGZpcnN0IG1lc3NhZ2UgcGFydAorCSAgICBNaW1lQm9keVBhcnQgbWJwMSA9IG5ldyBNaW1lQm9keVBhcnQoKTsKKwkgICAgbWJwMS5zZXRUZXh0KG1zZ1RleHQxKTsKKworCSAgICAvLyBjcmVhdGUgYW5kIGZpbGwgdGhlIHNlY29uZCBtZXNzYWdlIHBhcnQKKwkgICAgTWltZUJvZHlQYXJ0IG1icDIgPSBuZXcgTWltZUJvZHlQYXJ0KCk7CisJICAgIC8vIFVzZSBzZXRUZXh0KHRleHQsIGNoYXJzZXQpLCB0byBzaG93IGl0IG9mZiAhCisJICAgIG1icDIuc2V0VGV4dChtc2dUZXh0MiwgInVzLWFzY2lpIik7CisKKwkgICAgLy8gY3JlYXRlIHRoZSBNdWx0aXBhcnQgYW5kIGl0cyBwYXJ0cyB0byBpdAorCSAgICBNdWx0aXBhcnQgbXAgPSBuZXcgTWltZU11bHRpcGFydCgpOworCSAgICBtcC5hZGRCb2R5UGFydChtYnAxKTsKKwkgICAgbXAuYWRkQm9keVBhcnQobWJwMik7CisKKwkgICAgLy8gYWRkIHRoZSBNdWx0aXBhcnQgdG8gdGhlIG1lc3NhZ2UKKwkgICAgbXNnLnNldENvbnRlbnQobXApOworCSAgICAKKwkgICAgLy8gc2VuZCB0aGUgbWVzc2FnZQorCSAgICBUcmFuc3BvcnQuc2VuZChtc2cpOworCX0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBtZXgpIHsKKwkgICAgbWV4LnByaW50U3RhY2tUcmFjZSgpOworCSAgICBFeGNlcHRpb24gZXggPSBudWxsOworCSAgICBpZiAoKGV4ID0gbWV4LmdldE5leHRFeGNlcHRpb24oKSkgIT0gbnVsbCkgeworCQlleC5wcmludFN0YWNrVHJhY2UoKTsKKwkgICAgfQorCX0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9kZW1vL3NyYy9tYWluL2phdmEvbXNnc2VuZC5qYXZhIGIvZGVtby9zcmMvbWFpbi9qYXZhL21zZ3NlbmQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YTdkZWY5Ci0tLSAvZGV2L251bGwKKysrIGIvZGVtby9zcmMvbWFpbi9qYXZhL21zZ3NlbmQuamF2YQpAQCAtMCwwICsxLDIyNyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgRGlzdHJpYnV0aW9uIExpY2Vuc2Ugdi4gMS4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvb3JnL2RvY3VtZW50cy9lZGwtdjEwLnBocC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQlNELTMtQ2xhdXNlCisgKi8KKworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKK2ltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKKworaW1wb3J0IGphdmF4Lm1haWwuKjsKK2ltcG9ydCBqYXZheC5tYWlsLmludGVybmV0Lio7CisKKy8qKgorICogRGVtbyBhcHAgdGhhdCBzaG93cyBob3cgdG8gY29uc3RydWN0IGFuZCBzZW5kIGFuIFJGQzgyMgorICogKHNpbmdsZXBhcnQpIG1lc3NhZ2UuCisgKgorICogWFhYIC0gYWxsb3cgbW9yZSB0aGFuIG9uZSByZWNpcGllbnQgb24gdGhlIGNvbW1hbmQgbGluZQorICoKKyAqIEBhdXRob3IgTWF4IFNwaXZhaworICogQGF1dGhvciBCaWxsIFNoYW5ub24KKyAqLworCitwdWJsaWMgY2xhc3MgbXNnc2VuZCB7CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmd2KSB7CisJU3RyaW5nICB0bywgc3ViamVjdCA9IG51bGwsIGZyb20gPSBudWxsLCAKKwkJY2MgPSBudWxsLCBiY2MgPSBudWxsLCB1cmwgPSBudWxsOworCVN0cmluZyBtYWlsaG9zdCA9IG51bGw7CisJU3RyaW5nIG1haWxlciA9ICJtc2dzZW5kIjsKKwlTdHJpbmcgZmlsZSA9IG51bGw7CisJU3RyaW5nIHByb3RvY29sID0gbnVsbCwgaG9zdCA9IG51bGwsIHVzZXIgPSBudWxsLCBwYXNzd29yZCA9IG51bGw7CisJU3RyaW5nIHJlY29yZCA9IG51bGw7CS8vIG5hbWUgb2YgZm9sZGVyIGluIHdoaWNoIHRvIHJlY29yZCBtYWlsCisJYm9vbGVhbiBkZWJ1ZyA9IGZhbHNlOworCUJ1ZmZlcmVkUmVhZGVyIGluID0KKwkJCW5ldyBCdWZmZXJlZFJlYWRlcihuZXcgSW5wdXRTdHJlYW1SZWFkZXIoU3lzdGVtLmluKSk7CisJaW50IG9wdGluZDsKKworCS8qCisJICogUHJvY2VzcyBjb21tYW5kIGxpbmUgYXJndW1lbnRzLgorCSAqLworCWZvciAob3B0aW5kID0gMDsgb3B0aW5kIDwgYXJndi5sZW5ndGg7IG9wdGluZCsrKSB7CisJICAgIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItVCIpKSB7CisJCXByb3RvY29sID0gYXJndlsrK29wdGluZF07CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLUgiKSkgeworCQlob3N0ID0gYXJndlsrK29wdGluZF07CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLVUiKSkgeworCQl1c2VyID0gYXJndlsrK29wdGluZF07CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLVAiKSkgeworCQlwYXNzd29yZCA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1NIikpIHsKKwkJbWFpbGhvc3QgPSBhcmd2Wysrb3B0aW5kXTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItZiIpKSB7CisJCXJlY29yZCA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1hIikpIHsKKwkJZmlsZSA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1zIikpIHsKKwkJc3ViamVjdCA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1vIikpIHsgLy8gb3JpZ2luYXRvcgorCQlmcm9tID0gYXJndlsrK29wdGluZF07CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLWMiKSkgeworCQljYyA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1iIikpIHsKKwkJYmNjID0gYXJndlsrK29wdGluZF07CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLUwiKSkgeworCQl1cmwgPSBhcmd2Wysrb3B0aW5kXTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItZCIpKSB7CisJCWRlYnVnID0gdHJ1ZTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItLSIpKSB7CisJCW9wdGluZCsrOworCQlicmVhazsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uc3RhcnRzV2l0aCgiLSIpKSB7CisJCVN5c3RlbS5vdXQucHJpbnRsbigKKyJVc2FnZTogbXNnc2VuZCBbWy1MIHN0b3JlLXVybF0gfCBbLVQgcHJvdF0gWy1IIGhvc3RdIFstVSB1c2VyXSBbLVAgcGFzc3dkXV0iKTsKKwkJU3lzdGVtLm91dC5wcmludGxuKAorIlx0Wy1zIHN1YmplY3RdIFstbyBmcm9tLWFkZHJlc3NdIFstYyBjYy1hZGRyZXNzZXNdIFstYiBiY2MtYWRkcmVzc2VzXSIpOworCQlTeXN0ZW0ub3V0LnByaW50bG4oCisiXHRbLWYgcmVjb3JkLW1haWxib3hdIFstTSB0cmFuc3BvcnQtaG9zdF0gWy1hIGF0dGFjaC1maWxlXSBbLWRdIFthZGRyZXNzXSIpOworCQlTeXN0ZW0uZXhpdCgxKTsKKwkgICAgfSBlbHNlIHsKKwkJYnJlYWs7CisJICAgIH0KKwl9CisKKwl0cnkgeworCSAgICAvKgorCSAgICAgKiBQcm9tcHQgZm9yIFRvIGFuZCBTdWJqZWN0LCBpZiBub3Qgc3BlY2lmaWVkLgorCSAgICAgKi8KKwkgICAgaWYgKG9wdGluZCA8IGFyZ3YubGVuZ3RoKSB7CisJCS8vIFhYWCAtIGNvbmNhdGVuYXRlIGFsbCByZW1haW5pbmcgYXJndW1lbnRzCisJCXRvID0gYXJndltvcHRpbmRdOworCQlTeXN0ZW0ub3V0LnByaW50bG4oIlRvOiAiICsgdG8pOworCSAgICB9IGVsc2UgeworCQlTeXN0ZW0ub3V0LnByaW50KCJUbzogIik7CisJCVN5c3RlbS5vdXQuZmx1c2goKTsKKwkJdG8gPSBpbi5yZWFkTGluZSgpOworCSAgICB9CisJICAgIGlmIChzdWJqZWN0ID09IG51bGwpIHsKKwkJU3lzdGVtLm91dC5wcmludCgiU3ViamVjdDogIik7CisJCVN5c3RlbS5vdXQuZmx1c2goKTsKKwkJc3ViamVjdCA9IGluLnJlYWRMaW5lKCk7CisJICAgIH0gZWxzZSB7CisJCVN5c3RlbS5vdXQucHJpbnRsbigiU3ViamVjdDogIiArIHN1YmplY3QpOworCSAgICB9CisKKwkgICAgLyoKKwkgICAgICogSW5pdGlhbGl6ZSB0aGUgSmF2YU1haWwgU2Vzc2lvbi4KKwkgICAgICovCisJICAgIFByb3BlcnRpZXMgcHJvcHMgPSBTeXN0ZW0uZ2V0UHJvcGVydGllcygpOworCSAgICAvLyBYWFggLSBjb3VsZCB1c2UgU2Vzc2lvbi5nZXRUcmFuc3BvcnQoKSBhbmQgVHJhbnNwb3J0LmNvbm5lY3QoKQorCSAgICAvLyBYWFggLSBhc3N1bWUgd2UncmUgdXNpbmcgU01UUAorCSAgICBpZiAobWFpbGhvc3QgIT0gbnVsbCkKKwkJcHJvcHMucHV0KCJtYWlsLnNtdHAuaG9zdCIsIG1haWxob3N0KTsKKworCSAgICAvLyBHZXQgYSBTZXNzaW9uIG9iamVjdAorCSAgICBTZXNzaW9uIHNlc3Npb24gPSBTZXNzaW9uLmdldEluc3RhbmNlKHByb3BzLCBudWxsKTsKKwkgICAgaWYgKGRlYnVnKQorCQlzZXNzaW9uLnNldERlYnVnKHRydWUpOworCisJICAgIC8qCisJICAgICAqIENvbnN0cnVjdCB0aGUgbWVzc2FnZSBhbmQgc2VuZCBpdC4KKwkgICAgICovCisJICAgIE1lc3NhZ2UgbXNnID0gbmV3IE1pbWVNZXNzYWdlKHNlc3Npb24pOworCSAgICBpZiAoZnJvbSAhPSBudWxsKQorCQltc2cuc2V0RnJvbShuZXcgSW50ZXJuZXRBZGRyZXNzKGZyb20pKTsKKwkgICAgZWxzZQorCQltc2cuc2V0RnJvbSgpOworCisJICAgIG1zZy5zZXRSZWNpcGllbnRzKE1lc3NhZ2UuUmVjaXBpZW50VHlwZS5UTywKKwkJCQkJSW50ZXJuZXRBZGRyZXNzLnBhcnNlKHRvLCBmYWxzZSkpOworCSAgICBpZiAoY2MgIT0gbnVsbCkKKwkJbXNnLnNldFJlY2lwaWVudHMoTWVzc2FnZS5SZWNpcGllbnRUeXBlLkNDLAorCQkJCQlJbnRlcm5ldEFkZHJlc3MucGFyc2UoY2MsIGZhbHNlKSk7CisJICAgIGlmIChiY2MgIT0gbnVsbCkKKwkJbXNnLnNldFJlY2lwaWVudHMoTWVzc2FnZS5SZWNpcGllbnRUeXBlLkJDQywKKwkJCQkJSW50ZXJuZXRBZGRyZXNzLnBhcnNlKGJjYywgZmFsc2UpKTsKKworCSAgICBtc2cuc2V0U3ViamVjdChzdWJqZWN0KTsKKworCSAgICBTdHJpbmcgdGV4dCA9IGNvbGxlY3QoaW4pOworCisJICAgIGlmIChmaWxlICE9IG51bGwpIHsKKwkJLy8gQXR0YWNoIHRoZSBzcGVjaWZpZWQgZmlsZS4KKwkJLy8gV2UgbmVlZCBhIG11bHRpcGFydCBtZXNzYWdlIHRvIGhvbGQgdGhlIGF0dGFjaG1lbnQuCisJCU1pbWVCb2R5UGFydCBtYnAxID0gbmV3IE1pbWVCb2R5UGFydCgpOworCQltYnAxLnNldFRleHQodGV4dCk7CisJCU1pbWVCb2R5UGFydCBtYnAyID0gbmV3IE1pbWVCb2R5UGFydCgpOworCQltYnAyLmF0dGFjaEZpbGUoZmlsZSk7CisJCU1pbWVNdWx0aXBhcnQgbXAgPSBuZXcgTWltZU11bHRpcGFydCgpOworCQltcC5hZGRCb2R5UGFydChtYnAxKTsKKwkJbXAuYWRkQm9keVBhcnQobWJwMik7CisJCW1zZy5zZXRDb250ZW50KG1wKTsKKwkgICAgfSBlbHNlIHsKKwkJLy8gSWYgdGhlIGRlc2lyZWQgY2hhcnNldCBpcyBrbm93biwgeW91IGNhbiB1c2UKKwkJLy8gc2V0VGV4dCh0ZXh0LCBjaGFyc2V0KQorCQltc2cuc2V0VGV4dCh0ZXh0KTsKKwkgICAgfQorCisJICAgIG1zZy5zZXRIZWFkZXIoIlgtTWFpbGVyIiwgbWFpbGVyKTsKKwkgICAgbXNnLnNldFNlbnREYXRlKG5ldyBEYXRlKCkpOworCisJICAgIC8vIHNlbmQgdGhlIHRoaW5nIG9mZgorCSAgICBUcmFuc3BvcnQuc2VuZChtc2cpOworCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXG5NYWlsIHdhcyBzZW50IHN1Y2Nlc3NmdWxseS4iKTsKKworCSAgICAvKgorCSAgICAgKiBTYXZlIGEgY29weSBvZiB0aGUgbWVzc2FnZSwgaWYgcmVxdWVzdGVkLgorCSAgICAgKi8KKwkgICAgaWYgKHJlY29yZCAhPSBudWxsKSB7CisJCS8vIEdldCBhIFN0b3JlIG9iamVjdAorCQlTdG9yZSBzdG9yZSA9IG51bGw7CisJCWlmICh1cmwgIT0gbnVsbCkgeworCQkgICAgVVJMTmFtZSB1cmxuID0gbmV3IFVSTE5hbWUodXJsKTsKKwkJICAgIHN0b3JlID0gc2Vzc2lvbi5nZXRTdG9yZSh1cmxuKTsKKwkJICAgIHN0b3JlLmNvbm5lY3QoKTsKKwkJfSBlbHNlIHsKKwkJICAgIGlmIChwcm90b2NvbCAhPSBudWxsKQkJCisJCQlzdG9yZSA9IHNlc3Npb24uZ2V0U3RvcmUocHJvdG9jb2wpOworCQkgICAgZWxzZQorCQkJc3RvcmUgPSBzZXNzaW9uLmdldFN0b3JlKCk7CisKKwkJICAgIC8vIENvbm5lY3QKKwkJICAgIGlmIChob3N0ICE9IG51bGwgfHwgdXNlciAhPSBudWxsIHx8IHBhc3N3b3JkICE9IG51bGwpCisJCQlzdG9yZS5jb25uZWN0KGhvc3QsIHVzZXIsIHBhc3N3b3JkKTsKKwkJICAgIGVsc2UKKwkJCXN0b3JlLmNvbm5lY3QoKTsKKwkJfQorCisJCS8vIEdldCByZWNvcmQgRm9sZGVyLiAgQ3JlYXRlIGlmIGl0IGRvZXMgbm90IGV4aXN0LgorCQlGb2xkZXIgZm9sZGVyID0gc3RvcmUuZ2V0Rm9sZGVyKHJlY29yZCk7CisJCWlmIChmb2xkZXIgPT0gbnVsbCkgeworCQkgICAgU3lzdGVtLmVyci5wcmludGxuKCJDYW4ndCBnZXQgcmVjb3JkIGZvbGRlci4iKTsKKwkJICAgIFN5c3RlbS5leGl0KDEpOworCQl9CisJCWlmICghZm9sZGVyLmV4aXN0cygpKQorCQkgICAgZm9sZGVyLmNyZWF0ZShGb2xkZXIuSE9MRFNfTUVTU0FHRVMpOworCisJCU1lc3NhZ2VbXSBtc2dzID0gbmV3IE1lc3NhZ2VbMV07CisJCW1zZ3NbMF0gPSBtc2c7CisJCWZvbGRlci5hcHBlbmRNZXNzYWdlcyhtc2dzKTsKKworCQlTeXN0ZW0ub3V0LnByaW50bG4oIk1haWwgd2FzIHJlY29yZGVkIHN1Y2Nlc3NmdWxseS4iKTsKKwkgICAgfQorCisJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKwkgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZCB0aGUgYm9keSBvZiB0aGUgbWVzc2FnZSB1bnRpbCBFT0YuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgY29sbGVjdChCdWZmZXJlZFJlYWRlciBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlTdHJpbmcgbGluZTsKKwlTdHJpbmdCdWZmZXIgc2IgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CisJd2hpbGUgKChsaW5lID0gaW4ucmVhZExpbmUoKSkgIT0gbnVsbCkgeworCSAgICBzYi5hcHBlbmQobGluZSk7CisJICAgIHNiLmFwcGVuZCgiXG4iKTsKKwl9CisJcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvZGVtby9zcmMvbWFpbi9qYXZhL21zZ3NlbmRzYW1wbGUuamF2YSBiL2RlbW8vc3JjL21haW4vamF2YS9tc2dzZW5kc2FtcGxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzgxMGEwMQotLS0gL2Rldi9udWxsCisrKyBiL2RlbW8vc3JjL21haW4vamF2YS9tc2dzZW5kc2FtcGxlLmphdmEKQEAgLTAsMCArMSwxMDYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTYsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorICovCisKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YXgubWFpbC4qOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuKjsKK2ltcG9ydCBqYXZheC5hY3RpdmF0aW9uLio7CisKKy8qKgorICogbXNnc2VuZHNhbXBsZSBjcmVhdGVzIGEgdmVyeSBzaW1wbGUgdGV4dC9wbGFpbiBtZXNzYWdlIGFuZCBzZW5kcyBpdC4KKyAqIDxwPgorICogdXNhZ2U6IDxjb2RlPmphdmEgbXNnc2VuZHNhbXBsZSA8aT50byBmcm9tIHNtdHBob3N0IHRydWV8ZmFsc2U8L2k+PC9jb2RlPgorICogd2hlcmUgPGk+dG88L2k+IGFuZCA8aT5mcm9tPC9pPiBhcmUgdGhlIGRlc3RpbmF0aW9uIGFuZAorICogb3JpZ2luIGVtYWlsIGFkZHJlc3NlcywgcmVzcGVjdGl2ZWx5LCBhbmQgPGk+c210cGhvc3Q8L2k+CisgKiBpcyB0aGUgaG9zdG5hbWUgb2YgdGhlIG1hY2hpbmUgdGhhdCBoYXMgdGhlIHNtdHAgc2VydmVyCisgKiBydW5uaW5nLiBUaGUgbGFzdCBwYXJhbWV0ZXIgZWl0aGVyIHR1cm5zIG9uIG9yIHR1cm5zIG9mZgorICogZGVidWdnaW5nIGR1cmluZyBzZW5kaW5nLgorICoKKyAqIEBhdXRob3IgTWF4IFNwaXZhaworICovCitwdWJsaWMgY2xhc3MgbXNnc2VuZHNhbXBsZSB7CisgICAgc3RhdGljIFN0cmluZyBtc2dUZXh0ID0gIlRoaXMgaXMgYSBtZXNzYWdlIGJvZHkuXG5IZXJlJ3MgdGhlIHNlY29uZCBsaW5lLiI7CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7CisJaWYgKGFyZ3MubGVuZ3RoICE9IDQpIHsKKwkgICAgdXNhZ2UoKTsKKwkgICAgU3lzdGVtLmV4aXQoMSk7CisJfQorCisJU3lzdGVtLm91dC5wcmludGxuKCk7CisJCisJU3RyaW5nIHRvID0gYXJnc1swXTsKKwlTdHJpbmcgZnJvbSA9IGFyZ3NbMV07CisJU3RyaW5nIGhvc3QgPSBhcmdzWzJdOworCWJvb2xlYW4gZGVidWcgPSBCb29sZWFuLnZhbHVlT2YoYXJnc1szXSkuYm9vbGVhblZhbHVlKCk7CisKKwkvLyBjcmVhdGUgc29tZSBwcm9wZXJ0aWVzIGFuZCBnZXQgdGhlIGRlZmF1bHQgU2Vzc2lvbgorCVByb3BlcnRpZXMgcHJvcHMgPSBuZXcgUHJvcGVydGllcygpOworCXByb3BzLnB1dCgibWFpbC5zbXRwLmhvc3QiLCBob3N0KTsKKwlpZiAoZGVidWcpIHByb3BzLnB1dCgibWFpbC5kZWJ1ZyIsIGFyZ3NbM10pOworCisJU2Vzc2lvbiBzZXNzaW9uID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShwcm9wcywgbnVsbCk7CisJc2Vzc2lvbi5zZXREZWJ1ZyhkZWJ1Zyk7CisJCisJdHJ5IHsKKwkgICAgLy8gY3JlYXRlIGEgbWVzc2FnZQorCSAgICBNaW1lTWVzc2FnZSBtc2cgPSBuZXcgTWltZU1lc3NhZ2Uoc2Vzc2lvbik7CisJICAgIG1zZy5zZXRGcm9tKG5ldyBJbnRlcm5ldEFkZHJlc3MoZnJvbSkpOworCSAgICBJbnRlcm5ldEFkZHJlc3NbXSBhZGRyZXNzID0ge25ldyBJbnRlcm5ldEFkZHJlc3ModG8pfTsKKwkgICAgbXNnLnNldFJlY2lwaWVudHMoTWVzc2FnZS5SZWNpcGllbnRUeXBlLlRPLCBhZGRyZXNzKTsKKwkgICAgbXNnLnNldFN1YmplY3QoIkphdmFNYWlsIEFQSXMgVGVzdCIpOworCSAgICBtc2cuc2V0U2VudERhdGUobmV3IERhdGUoKSk7CisJICAgIC8vIElmIHRoZSBkZXNpcmVkIGNoYXJzZXQgaXMga25vd24sIHlvdSBjYW4gdXNlCisJICAgIC8vIHNldFRleHQodGV4dCwgY2hhcnNldCkKKwkgICAgbXNnLnNldFRleHQobXNnVGV4dCk7CisJICAgIAorCSAgICBUcmFuc3BvcnQuc2VuZChtc2cpOworCX0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBtZXgpIHsKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJcbi0tRXhjZXB0aW9uIGhhbmRsaW5nIGluIG1zZ3NlbmRzYW1wbGUuamF2YSIpOworCisJICAgIG1leC5wcmludFN0YWNrVHJhY2UoKTsKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCk7CisJICAgIEV4Y2VwdGlvbiBleCA9IG1leDsKKwkgICAgZG8geworCQlpZiAoZXggaW5zdGFuY2VvZiBTZW5kRmFpbGVkRXhjZXB0aW9uKSB7CisJCSAgICBTZW5kRmFpbGVkRXhjZXB0aW9uIHNmZXggPSAoU2VuZEZhaWxlZEV4Y2VwdGlvbilleDsKKwkJICAgIEFkZHJlc3NbXSBpbnZhbGlkID0gc2ZleC5nZXRJbnZhbGlkQWRkcmVzc2VzKCk7CisJCSAgICBpZiAoaW52YWxpZCAhPSBudWxsKSB7CisJCQlTeXN0ZW0ub3V0LnByaW50bG4oIiAgICAqKiBJbnZhbGlkIEFkZHJlc3NlcyIpOworCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBpbnZhbGlkLmxlbmd0aDsgaSsrKSAKKwkJCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiAgICAgICAgICIgKyBpbnZhbGlkW2ldKTsKKwkJICAgIH0KKwkJICAgIEFkZHJlc3NbXSB2YWxpZFVuc2VudCA9IHNmZXguZ2V0VmFsaWRVbnNlbnRBZGRyZXNzZXMoKTsKKwkJICAgIGlmICh2YWxpZFVuc2VudCAhPSBudWxsKSB7CisJCQlTeXN0ZW0ub3V0LnByaW50bG4oIiAgICAqKiBWYWxpZFVuc2VudCBBZGRyZXNzZXMiKTsKKwkJCWZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWRVbnNlbnQubGVuZ3RoOyBpKyspIAorCQkJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiICAgICAgICAgIit2YWxpZFVuc2VudFtpXSk7CisJCSAgICB9CisJCSAgICBBZGRyZXNzW10gdmFsaWRTZW50ID0gc2ZleC5nZXRWYWxpZFNlbnRBZGRyZXNzZXMoKTsKKwkJICAgIGlmICh2YWxpZFNlbnQgIT0gbnVsbCkgeworCQkJU3lzdGVtLm91dC5wcmludGxuKCIgICAgKiogVmFsaWRTZW50IEFkZHJlc3NlcyIpOworCQkJZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFNlbnQubGVuZ3RoOyBpKyspIAorCQkJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiICAgICAgICAgIit2YWxpZFNlbnRbaV0pOworCQkgICAgfQorCQl9CisJCVN5c3RlbS5vdXQucHJpbnRsbigpOworCQlpZiAoZXggaW5zdGFuY2VvZiBNZXNzYWdpbmdFeGNlcHRpb24pCisJCSAgICBleCA9ICgoTWVzc2FnaW5nRXhjZXB0aW9uKWV4KS5nZXROZXh0RXhjZXB0aW9uKCk7CisJCWVsc2UKKwkJICAgIGV4ID0gbnVsbDsKKwkgICAgfSB3aGlsZSAoZXggIT0gbnVsbCk7CisJfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgdXNhZ2UoKSB7CisJU3lzdGVtLm91dC5wcmludGxuKCJ1c2FnZTogamF2YSBtc2dzZW5kc2FtcGxlIDx0bz4gPGZyb20+IDxzbXRwPiB0cnVlfGZhbHNlIik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvZGVtby9zcmMvbWFpbi9qYXZhL21zZ3Nob3cuamF2YSBiL2RlbW8vc3JjL21haW4vamF2YS9tc2dzaG93LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDdlZDAwMAotLS0gL2Rldi9udWxsCisrKyBiL2RlbW8vc3JjL21haW4vamF2YS9tc2dzaG93LmphdmEKQEAgLTAsMCArMSw0MjQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorICovCisKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YXgubWFpbC4qOworaW1wb3J0IGphdmF4Lm1haWwuZXZlbnQuKjsKK2ltcG9ydCBqYXZheC5tYWlsLmludGVybmV0Lio7CisKKy8qCisgKiBEZW1vIGFwcCB0aGF0IGV4ZXJjaXNlcyB0aGUgTWVzc2FnZSBpbnRlcmZhY2VzLgorICogU2hvdyBpbmZvcm1hdGlvbiBhYm91dCBhbmQgY29udGVudHMgb2YgbWVzc2FnZXMuCisgKgorICogQGF1dGhvciBKb2huIE1hbmkKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKi8KKworcHVibGljIGNsYXNzIG1zZ3Nob3cgeworCisgICAgc3RhdGljIFN0cmluZyBwcm90b2NvbDsKKyAgICBzdGF0aWMgU3RyaW5nIGhvc3QgPSBudWxsOworICAgIHN0YXRpYyBTdHJpbmcgdXNlciA9IG51bGw7CisgICAgc3RhdGljIFN0cmluZyBwYXNzd29yZCA9IG51bGw7CisgICAgc3RhdGljIFN0cmluZyBtYm94ID0gbnVsbDsKKyAgICBzdGF0aWMgU3RyaW5nIHVybCA9IG51bGw7CisgICAgc3RhdGljIGludCBwb3J0ID0gLTE7CisgICAgc3RhdGljIGJvb2xlYW4gdmVyYm9zZSA9IGZhbHNlOworICAgIHN0YXRpYyBib29sZWFuIGRlYnVnID0gZmFsc2U7CisgICAgc3RhdGljIGJvb2xlYW4gc2hvd1N0cnVjdHVyZSA9IGZhbHNlOworICAgIHN0YXRpYyBib29sZWFuIHNob3dNZXNzYWdlID0gZmFsc2U7CisgICAgc3RhdGljIGJvb2xlYW4gc2hvd0FsZXJ0ID0gZmFsc2U7CisgICAgc3RhdGljIGJvb2xlYW4gc2F2ZUF0dGFjaG1lbnRzID0gZmFsc2U7CisgICAgc3RhdGljIGludCBhdHRudW0gPSAxOworCisgICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nIGFyZ3ZbXSkgeworCWludCBvcHRpbmQ7CisJSW5wdXRTdHJlYW0gbXNnU3RyZWFtID0gU3lzdGVtLmluOworCisJZm9yIChvcHRpbmQgPSAwOyBvcHRpbmQgPCBhcmd2Lmxlbmd0aDsgb3B0aW5kKyspIHsKKwkgICAgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1UIikpIHsKKwkJcHJvdG9jb2wgPSBhcmd2Wysrb3B0aW5kXTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItSCIpKSB7CisJCWhvc3QgPSBhcmd2Wysrb3B0aW5kXTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItVSIpKSB7CisJCXVzZXIgPSBhcmd2Wysrb3B0aW5kXTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItUCIpKSB7CisJCXBhc3N3b3JkID0gYXJndlsrK29wdGluZF07CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLXYiKSkgeworCQl2ZXJib3NlID0gdHJ1ZTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItRCIpKSB7CisJCWRlYnVnID0gdHJ1ZTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItZiIpKSB7CisJCW1ib3ggPSBhcmd2Wysrb3B0aW5kXTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItTCIpKSB7CisJCXVybCA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1wIikpIHsKKwkJcG9ydCA9IEludGVnZXIucGFyc2VJbnQoYXJndlsrK29wdGluZF0pOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1zIikpIHsKKwkJc2hvd1N0cnVjdHVyZSA9IHRydWU7CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLVMiKSkgeworCQlzYXZlQXR0YWNobWVudHMgPSB0cnVlOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1tIikpIHsKKwkJc2hvd01lc3NhZ2UgPSB0cnVlOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1hIikpIHsKKwkJc2hvd0FsZXJ0ID0gdHJ1ZTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItLSIpKSB7CisJCW9wdGluZCsrOworCQlicmVhazsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uc3RhcnRzV2l0aCgiLSIpKSB7CisJCVN5c3RlbS5vdXQucHJpbnRsbigKKyJVc2FnZTogbXNnc2hvdyBbLUwgdXJsXSBbLVQgcHJvdG9jb2xdIFstSCBob3N0XSBbLXAgcG9ydF0gWy1VIHVzZXJdIik7CisJCVN5c3RlbS5vdXQucHJpbnRsbigKKyJcdFstUCBwYXNzd29yZF0gWy1mIG1haWxib3hdIFttc2dudW0gLi4uXSBbLXZdIFstRF0gWy1zXSBbLVNdIFstYV0iKTsKKwkJU3lzdGVtLm91dC5wcmludGxuKAorIm9yICAgICBtc2dzaG93IC1tIFstdl0gWy1EXSBbLXNdIFstU10gWy1mIG1zZy1maWxlXSIpOworCQlTeXN0ZW0uZXhpdCgxKTsKKwkgICAgfSBlbHNlIHsKKwkJYnJlYWs7CisJICAgIH0KKwl9CisKKwl0cnkgeworCSAgICAvLyBHZXQgYSBQcm9wZXJ0aWVzIG9iamVjdAorCSAgICBQcm9wZXJ0aWVzIHByb3BzID0gU3lzdGVtLmdldFByb3BlcnRpZXMoKTsKKworCSAgICAvLyBHZXQgYSBTZXNzaW9uIG9iamVjdAorCSAgICBTZXNzaW9uIHNlc3Npb24gPSBTZXNzaW9uLmdldEluc3RhbmNlKHByb3BzLCBudWxsKTsKKwkgICAgc2Vzc2lvbi5zZXREZWJ1ZyhkZWJ1Zyk7CisKKwkgICAgaWYgKHNob3dNZXNzYWdlKSB7CisJCU1pbWVNZXNzYWdlIG1zZzsKKwkJaWYgKG1ib3ggIT0gbnVsbCkKKwkJICAgIG1zZyA9IG5ldyBNaW1lTWVzc2FnZShzZXNzaW9uLAorCQkJbmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0obmV3IEZpbGVJbnB1dFN0cmVhbShtYm94KSkpOworCQllbHNlCisJCSAgICBtc2cgPSBuZXcgTWltZU1lc3NhZ2Uoc2Vzc2lvbiwgbXNnU3RyZWFtKTsKKwkJZHVtcFBhcnQobXNnKTsKKwkJU3lzdGVtLmV4aXQoMCk7CisJICAgIH0KKworCSAgICAvLyBHZXQgYSBTdG9yZSBvYmplY3QKKwkgICAgU3RvcmUgc3RvcmUgPSBudWxsOworCSAgICBpZiAodXJsICE9IG51bGwpIHsKKwkJVVJMTmFtZSB1cmxuID0gbmV3IFVSTE5hbWUodXJsKTsKKwkJc3RvcmUgPSBzZXNzaW9uLmdldFN0b3JlKHVybG4pOworCQlpZiAoc2hvd0FsZXJ0KSB7CisJCSAgICBzdG9yZS5hZGRTdG9yZUxpc3RlbmVyKG5ldyBTdG9yZUxpc3RlbmVyKCkgeworCQkJcHVibGljIHZvaWQgbm90aWZpY2F0aW9uKFN0b3JlRXZlbnQgZSkgeworCQkJICAgIFN0cmluZyBzOworCQkJICAgIGlmIChlLmdldE1lc3NhZ2VUeXBlKCkgPT0gU3RvcmVFdmVudC5BTEVSVCkKKwkJCQlzID0gIkFMRVJUOiAiOworCQkJICAgIGVsc2UKKwkJCQlzID0gIk5PVElDRTogIjsKKwkJCSAgICBTeXN0ZW0ub3V0LnByaW50bG4ocyArIGUuZ2V0TWVzc2FnZSgpKTsKKwkJCX0KKwkJICAgIH0pOworCQl9CisJCXN0b3JlLmNvbm5lY3QoKTsKKwkgICAgfSBlbHNlIHsKKwkJaWYgKHByb3RvY29sICE9IG51bGwpCQkKKwkJICAgIHN0b3JlID0gc2Vzc2lvbi5nZXRTdG9yZShwcm90b2NvbCk7CisJCWVsc2UKKwkJICAgIHN0b3JlID0gc2Vzc2lvbi5nZXRTdG9yZSgpOworCisJCS8vIENvbm5lY3QKKwkJaWYgKGhvc3QgIT0gbnVsbCB8fCB1c2VyICE9IG51bGwgfHwgcGFzc3dvcmQgIT0gbnVsbCkKKwkJICAgIHN0b3JlLmNvbm5lY3QoaG9zdCwgcG9ydCwgdXNlciwgcGFzc3dvcmQpOworCQllbHNlCisJCSAgICBzdG9yZS5jb25uZWN0KCk7CisJICAgIH0KKwkgICAgCisKKwkgICAgLy8gT3BlbiB0aGUgRm9sZGVyCisKKwkgICAgRm9sZGVyIGZvbGRlciA9IHN0b3JlLmdldERlZmF1bHRGb2xkZXIoKTsKKwkgICAgaWYgKGZvbGRlciA9PSBudWxsKSB7CisJCVN5c3RlbS5vdXQucHJpbnRsbigiTm8gZGVmYXVsdCBmb2xkZXIiKTsKKwkJU3lzdGVtLmV4aXQoMSk7CisJICAgIH0KKworCSAgICBpZiAobWJveCA9PSBudWxsKQorCQltYm94ID0gIklOQk9YIjsKKwkgICAgZm9sZGVyID0gZm9sZGVyLmdldEZvbGRlcihtYm94KTsKKwkgICAgaWYgKGZvbGRlciA9PSBudWxsKSB7CisJCVN5c3RlbS5vdXQucHJpbnRsbigiSW52YWxpZCBmb2xkZXIiKTsKKwkJU3lzdGVtLmV4aXQoMSk7CisJICAgIH0KKworCSAgICAvLyB0cnkgdG8gb3BlbiByZWFkL3dyaXRlIGFuZCBpZiB0aGF0IGZhaWxzIHRyeSByZWFkLW9ubHkKKwkgICAgdHJ5IHsKKwkJZm9sZGVyLm9wZW4oRm9sZGVyLlJFQURfV1JJVEUpOworCSAgICB9IGNhdGNoIChNZXNzYWdpbmdFeGNlcHRpb24gZXgpIHsKKwkJZm9sZGVyLm9wZW4oRm9sZGVyLlJFQURfT05MWSk7CisJICAgIH0KKwkgICAgaW50IHRvdGFsTWVzc2FnZXMgPSBmb2xkZXIuZ2V0TWVzc2FnZUNvdW50KCk7CisKKwkgICAgaWYgKHRvdGFsTWVzc2FnZXMgPT0gMCkgeworCQlTeXN0ZW0ub3V0LnByaW50bG4oIkVtcHR5IGZvbGRlciIpOworCQlmb2xkZXIuY2xvc2UoZmFsc2UpOworCQlzdG9yZS5jbG9zZSgpOworCQlTeXN0ZW0uZXhpdCgxKTsKKwkgICAgfQorCisJICAgIGlmICh2ZXJib3NlKSB7CisJCWludCBuZXdNZXNzYWdlcyA9IGZvbGRlci5nZXROZXdNZXNzYWdlQ291bnQoKTsKKwkJU3lzdGVtLm91dC5wcmludGxuKCJUb3RhbCBtZXNzYWdlcyA9ICIgKyB0b3RhbE1lc3NhZ2VzKTsKKwkJU3lzdGVtLm91dC5wcmludGxuKCJOZXcgbWVzc2FnZXMgPSAiICsgbmV3TWVzc2FnZXMpOworCQlTeXN0ZW0ub3V0LnByaW50bG4oIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0iKTsKKwkgICAgfQorCisJICAgIGlmIChvcHRpbmQgPj0gYXJndi5sZW5ndGgpIHsKKwkJLy8gQXR0cmlidXRlcyAmIEZsYWdzIGZvciBhbGwgbWVzc2FnZXMgLi4KKwkJTWVzc2FnZVtdIG1zZ3MgPSBmb2xkZXIuZ2V0TWVzc2FnZXMoKTsKKworCQkvLyBVc2UgYSBzdWl0YWJsZSBGZXRjaFByb2ZpbGUKKwkJRmV0Y2hQcm9maWxlIGZwID0gbmV3IEZldGNoUHJvZmlsZSgpOworCQlmcC5hZGQoRmV0Y2hQcm9maWxlLkl0ZW0uRU5WRUxPUEUpOworCQlmcC5hZGQoRmV0Y2hQcm9maWxlLkl0ZW0uRkxBR1MpOworCQlmcC5hZGQoIlgtTWFpbGVyIik7CisJCWZvbGRlci5mZXRjaChtc2dzLCBmcCk7CisKKwkJZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisJCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIik7CisJCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIk1FU1NBR0UgIyIgKyAoaSArIDEpICsgIjoiKTsKKwkJICAgIGR1bXBFbnZlbG9wZShtc2dzW2ldKTsKKwkJICAgIC8vIGR1bXBQYXJ0KG1zZ3NbaV0pOworCQl9CisJICAgIH0gZWxzZSB7CisJCXdoaWxlIChvcHRpbmQgPCBhcmd2Lmxlbmd0aCkgeworCQkgICAgaW50IG1zZ251bSA9IEludGVnZXIucGFyc2VJbnQoYXJndltvcHRpbmQrK10pOworCQkgICAgU3lzdGVtLm91dC5wcmludGxuKCJHZXR0aW5nIG1lc3NhZ2UgbnVtYmVyOiAiICsgbXNnbnVtKTsKKwkJICAgIE1lc3NhZ2UgbSA9IG51bGw7CisJCSAgICAKKwkJICAgIHRyeSB7CisJCQltID0gZm9sZGVyLmdldE1lc3NhZ2UobXNnbnVtKTsKKwkJCWR1bXBQYXJ0KG0pOworCQkgICAgfSBjYXRjaCAoSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZXgpIHsKKwkJCVN5c3RlbS5vdXQucHJpbnRsbigiTWVzc2FnZSBudW1iZXIgb3V0IG9mIHJhbmdlIik7CisJCSAgICB9CisJCX0KKwkgICAgfQorCisJICAgIGZvbGRlci5jbG9zZShmYWxzZSk7CisJICAgIHN0b3JlLmNsb3NlKCk7CisJfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiT29wcywgZ290IGV4Y2VwdGlvbiEgIiArIGV4LmdldE1lc3NhZ2UoKSk7CisJICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOworCSAgICBTeXN0ZW0uZXhpdCgxKTsKKwl9CisJU3lzdGVtLmV4aXQoMCk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGR1bXBQYXJ0KFBhcnQgcCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJaWYgKHAgaW5zdGFuY2VvZiBNZXNzYWdlKQorCSAgICBkdW1wRW52ZWxvcGUoKE1lc3NhZ2UpcCk7CisKKwkvKiogRHVtcCBpbnB1dCBzdHJlYW0gLi4gCisKKwlJbnB1dFN0cmVhbSBpcyA9IHAuZ2V0SW5wdXRTdHJlYW0oKTsKKwkvLyBJZiAiaXMiIGlzIG5vdCBhbHJlYWR5IGJ1ZmZlcmVkLCB3cmFwIGEgQnVmZmVyZWRJbnB1dFN0cmVhbQorCS8vIGFyb3VuZCBpdC4KKwlpZiAoIShpcyBpbnN0YW5jZW9mIEJ1ZmZlcmVkSW5wdXRTdHJlYW0pKQorCSAgICBpcyA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKGlzKTsKKwlpbnQgYzsKKwl3aGlsZSAoKGMgPSBpcy5yZWFkKCkpICE9IC0xKQorCSAgICBTeXN0ZW0ub3V0LndyaXRlKGMpOworCisJKiovCisKKwlTdHJpbmcgY3QgPSBwLmdldENvbnRlbnRUeXBlKCk7CisJdHJ5IHsKKwkgICAgcHIoIkNPTlRFTlQtVFlQRTogIiArIChuZXcgQ29udGVudFR5cGUoY3QpKS50b1N0cmluZygpKTsKKwl9IGNhdGNoIChQYXJzZUV4Y2VwdGlvbiBwZXgpIHsKKwkgICAgcHIoIkJBRCBDT05URU5ULVRZUEU6ICIgKyBjdCk7CisJfQorCVN0cmluZyBmaWxlbmFtZSA9IHAuZ2V0RmlsZU5hbWUoKTsKKwlpZiAoZmlsZW5hbWUgIT0gbnVsbCkKKwkgICAgcHIoIkZJTEVOQU1FOiAiICsgZmlsZW5hbWUpOworCisJLyoKKwkgKiBVc2luZyBpc01pbWVUeXBlIHRvIGRldGVybWluZSB0aGUgY29udGVudCB0eXBlIGF2b2lkcworCSAqIGZldGNoaW5nIHRoZSBhY3R1YWwgY29udGVudCBkYXRhIHVudGlsIHdlIG5lZWQgaXQuCisJICovCisJaWYgKHAuaXNNaW1lVHlwZSgidGV4dC9wbGFpbiIpKSB7CisJICAgIHByKCJUaGlzIGlzIHBsYWluIHRleHQiKTsKKwkgICAgcHIoIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIpOworCSAgICBpZiAoIXNob3dTdHJ1Y3R1cmUgJiYgIXNhdmVBdHRhY2htZW50cykKKwkJU3lzdGVtLm91dC5wcmludGxuKChTdHJpbmcpcC5nZXRDb250ZW50KCkpOworCX0gZWxzZSBpZiAocC5pc01pbWVUeXBlKCJtdWx0aXBhcnQvKiIpKSB7CisJICAgIHByKCJUaGlzIGlzIGEgTXVsdGlwYXJ0Iik7CisJICAgIHByKCItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0iKTsKKwkgICAgTXVsdGlwYXJ0IG1wID0gKE11bHRpcGFydClwLmdldENvbnRlbnQoKTsKKwkgICAgbGV2ZWwrKzsKKwkgICAgaW50IGNvdW50ID0gbXAuZ2V0Q291bnQoKTsKKwkgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKQorCQlkdW1wUGFydChtcC5nZXRCb2R5UGFydChpKSk7CisJICAgIGxldmVsLS07CisJfSBlbHNlIGlmIChwLmlzTWltZVR5cGUoIm1lc3NhZ2UvcmZjODIyIikpIHsKKwkgICAgcHIoIlRoaXMgaXMgYSBOZXN0ZWQgTWVzc2FnZSIpOworCSAgICBwcigiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIik7CisJICAgIGxldmVsKys7CisJICAgIGR1bXBQYXJ0KChQYXJ0KXAuZ2V0Q29udGVudCgpKTsKKwkgICAgbGV2ZWwtLTsKKwl9IGVsc2UgeworCSAgICBpZiAoIXNob3dTdHJ1Y3R1cmUgJiYgIXNhdmVBdHRhY2htZW50cykgeworCQkvKgorCQkgKiBJZiB3ZSBhY3R1YWxseSB3YW50IHRvIHNlZSB0aGUgZGF0YSwgYW5kIGl0J3Mgbm90IGEKKwkJICogTUlNRSB0eXBlIHdlIGtub3csIGZldGNoIGl0IGFuZCBjaGVjayBpdHMgSmF2YSB0eXBlLgorCQkgKi8KKwkJT2JqZWN0IG8gPSBwLmdldENvbnRlbnQoKTsKKwkJaWYgKG8gaW5zdGFuY2VvZiBTdHJpbmcpIHsKKwkJICAgIHByKCJUaGlzIGlzIGEgc3RyaW5nIik7CisJCSAgICBwcigiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIik7CisJCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oKFN0cmluZylvKTsKKwkJfSBlbHNlIGlmIChvIGluc3RhbmNlb2YgSW5wdXRTdHJlYW0pIHsKKwkJICAgIHByKCJUaGlzIGlzIGp1c3QgYW4gaW5wdXQgc3RyZWFtIik7CisJCSAgICBwcigiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIik7CisJCSAgICBJbnB1dFN0cmVhbSBpcyA9IChJbnB1dFN0cmVhbSlvOworCQkgICAgaW50IGM7CisJCSAgICB3aGlsZSAoKGMgPSBpcy5yZWFkKCkpICE9IC0xKQorCQkJU3lzdGVtLm91dC53cml0ZShjKTsKKwkJfSBlbHNlIHsKKwkJICAgIHByKCJUaGlzIGlzIGFuIHVua25vd24gdHlwZSIpOworCQkgICAgcHIoIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIpOworCQkgICAgcHIoby50b1N0cmluZygpKTsKKwkJfQorCSAgICB9IGVsc2UgeworCQkvLyBqdXN0IGEgc2VwYXJhdG9yCisJCXByKCItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0iKTsKKwkgICAgfQorCX0KKworCS8qCisJICogSWYgd2UncmUgc2F2aW5nIGF0dGFjaG1lbnRzLCB3cml0ZSBvdXQgYW55dGhpbmcgdGhhdAorCSAqIGxvb2tzIGxpa2UgYW4gYXR0YWNobWVudCBpbnRvIGFuIGFwcHJvcHJpYXRlbHkgbmFtZWQKKwkgKiBmaWxlLiAgRG9uJ3Qgb3ZlcndyaXRlIGV4aXN0aW5nIGZpbGVzIHRvIHByZXZlbnQKKwkgKiBtaXN0YWtlcy4KKwkgKi8KKwlpZiAoc2F2ZUF0dGFjaG1lbnRzICYmIGxldmVsICE9IDAgJiYgcCBpbnN0YW5jZW9mIE1pbWVCb2R5UGFydCAmJgorCQkhcC5pc01pbWVUeXBlKCJtdWx0aXBhcnQvKiIpKSB7CisJICAgIFN0cmluZyBkaXNwID0gcC5nZXREaXNwb3NpdGlvbigpOworCSAgICAvLyBtYW55IG1haWxlcnMgZG9uJ3QgaW5jbHVkZSBhIENvbnRlbnQtRGlzcG9zaXRpb24KKwkgICAgaWYgKGRpc3AgPT0gbnVsbCB8fCBkaXNwLmVxdWFsc0lnbm9yZUNhc2UoUGFydC5BVFRBQ0hNRU5UKSkgeworCQlpZiAoZmlsZW5hbWUgPT0gbnVsbCkKKwkJICAgIGZpbGVuYW1lID0gIkF0dGFjaG1lbnQiICsgYXR0bnVtKys7CisJCXByKCJTYXZpbmcgYXR0YWNobWVudCB0byBmaWxlICIgKyBmaWxlbmFtZSk7CisJCXRyeSB7CisJCSAgICBGaWxlIGYgPSBuZXcgRmlsZShmaWxlbmFtZSk7CisJCSAgICBpZiAoZi5leGlzdHMoKSkKKwkJCS8vIFhYWCAtIGNvdWxkIHRyeSBhIHNlcmllcyBvZiBuYW1lcworCQkJdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJmaWxlIGV4aXN0cyIpOworCQkgICAgKChNaW1lQm9keVBhcnQpcCkuc2F2ZUZpbGUoZik7CisJCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisJCSAgICBwcigiRmFpbGVkIHRvIHNhdmUgYXR0YWNobWVudDogIiArIGV4KTsKKwkJfQorCQlwcigiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIik7CisJICAgIH0KKwl9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGR1bXBFbnZlbG9wZShNZXNzYWdlIG0pIHRocm93cyBFeGNlcHRpb24geworCXByKCJUaGlzIGlzIHRoZSBtZXNzYWdlIGVudmVsb3BlIik7CisJcHIoIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIpOworCUFkZHJlc3NbXSBhOworCS8vIEZST00gCisJaWYgKChhID0gbS5nZXRGcm9tKCkpICE9IG51bGwpIHsKKwkgICAgZm9yIChpbnQgaiA9IDA7IGogPCBhLmxlbmd0aDsgaisrKQorCQlwcigiRlJPTTogIiArIGFbal0udG9TdHJpbmcoKSk7CisJfQorCisJLy8gUkVQTFkgVE8KKwlpZiAoKGEgPSBtLmdldFJlcGx5VG8oKSkgIT0gbnVsbCkgeworCSAgICBmb3IgKGludCBqID0gMDsgaiA8IGEubGVuZ3RoOyBqKyspCisJCXByKCJSRVBMWSBUTzogIiArIGFbal0udG9TdHJpbmcoKSk7CisJfQorCisJLy8gVE8KKwlpZiAoKGEgPSBtLmdldFJlY2lwaWVudHMoTWVzc2FnZS5SZWNpcGllbnRUeXBlLlRPKSkgIT0gbnVsbCkgeworCSAgICBmb3IgKGludCBqID0gMDsgaiA8IGEubGVuZ3RoOyBqKyspIHsKKwkJcHIoIlRPOiAiICsgYVtqXS50b1N0cmluZygpKTsKKwkJSW50ZXJuZXRBZGRyZXNzIGlhID0gKEludGVybmV0QWRkcmVzcylhW2pdOworCQlpZiAoaWEuaXNHcm91cCgpKSB7CisJCSAgICBJbnRlcm5ldEFkZHJlc3NbXSBhYSA9IGlhLmdldEdyb3VwKGZhbHNlKTsKKwkJICAgIGZvciAoaW50IGsgPSAwOyBrIDwgYWEubGVuZ3RoOyBrKyspCisJCQlwcigiICBHUk9VUDogIiArIGFhW2tdLnRvU3RyaW5nKCkpOworCQl9CisJICAgIH0KKwl9CisKKwkvLyBTVUJKRUNUCisJcHIoIlNVQkpFQ1Q6ICIgKyBtLmdldFN1YmplY3QoKSk7CisKKwkvLyBEQVRFCisJRGF0ZSBkID0gbS5nZXRTZW50RGF0ZSgpOworCXByKCJTZW5kRGF0ZTogIiArCisJICAgIChkICE9IG51bGwgPyBkLnRvU3RyaW5nKCkgOiAiVU5LTk9XTiIpKTsKKworCS8vIEZMQUdTCisJRmxhZ3MgZmxhZ3MgPSBtLmdldEZsYWdzKCk7CisJU3RyaW5nQnVmZmVyIHNiID0gbmV3IFN0cmluZ0J1ZmZlcigpOworCUZsYWdzLkZsYWdbXSBzZiA9IGZsYWdzLmdldFN5c3RlbUZsYWdzKCk7IC8vIGdldCB0aGUgc3lzdGVtIGZsYWdzCisKKwlib29sZWFuIGZpcnN0ID0gdHJ1ZTsKKwlmb3IgKGludCBpID0gMDsgaSA8IHNmLmxlbmd0aDsgaSsrKSB7CisJICAgIFN0cmluZyBzOworCSAgICBGbGFncy5GbGFnIGYgPSBzZltpXTsKKwkgICAgaWYgKGYgPT0gRmxhZ3MuRmxhZy5BTlNXRVJFRCkKKwkJcyA9ICJcXEFuc3dlcmVkIjsKKwkgICAgZWxzZSBpZiAoZiA9PSBGbGFncy5GbGFnLkRFTEVURUQpCisJCXMgPSAiXFxEZWxldGVkIjsKKwkgICAgZWxzZSBpZiAoZiA9PSBGbGFncy5GbGFnLkRSQUZUKQorCQlzID0gIlxcRHJhZnQiOworCSAgICBlbHNlIGlmIChmID09IEZsYWdzLkZsYWcuRkxBR0dFRCkKKwkJcyA9ICJcXEZsYWdnZWQiOworCSAgICBlbHNlIGlmIChmID09IEZsYWdzLkZsYWcuUkVDRU5UKQorCQlzID0gIlxcUmVjZW50IjsKKwkgICAgZWxzZSBpZiAoZiA9PSBGbGFncy5GbGFnLlNFRU4pCisJCXMgPSAiXFxTZWVuIjsKKwkgICAgZWxzZQorCQljb250aW51ZTsJLy8gc2tpcCBpdAorCSAgICBpZiAoZmlyc3QpCisJCWZpcnN0ID0gZmFsc2U7CisJICAgIGVsc2UKKwkJc2IuYXBwZW5kKCcgJyk7CisJICAgIHNiLmFwcGVuZChzKTsKKwl9CisKKwlTdHJpbmdbXSB1ZiA9IGZsYWdzLmdldFVzZXJGbGFncygpOyAvLyBnZXQgdGhlIHVzZXIgZmxhZyBzdHJpbmdzCisJZm9yIChpbnQgaSA9IDA7IGkgPCB1Zi5sZW5ndGg7IGkrKykgeworCSAgICBpZiAoZmlyc3QpCisJCWZpcnN0ID0gZmFsc2U7CisJICAgIGVsc2UKKwkJc2IuYXBwZW5kKCcgJyk7CisJICAgIHNiLmFwcGVuZCh1ZltpXSk7CisJfQorCXByKCJGTEFHUzogIiArIHNiLnRvU3RyaW5nKCkpOworCisJLy8gWC1NQUlMRVIKKwlTdHJpbmdbXSBoZHJzID0gbS5nZXRIZWFkZXIoIlgtTWFpbGVyIik7CisJaWYgKGhkcnMgIT0gbnVsbCkKKwkgICAgcHIoIlgtTWFpbGVyOiAiICsgaGRyc1swXSk7CisJZWxzZQorCSAgICBwcigiWC1NYWlsZXIgTk9UIGF2YWlsYWJsZSIpOworICAgIH0KKworICAgIHN0YXRpYyBTdHJpbmcgaW5kZW50U3RyID0gIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjsKKyAgICBzdGF0aWMgaW50IGxldmVsID0gMDsKKworICAgIC8qKgorICAgICAqIFByaW50IGEsIHBvc3NpYmx5IGluZGVudGVkLCBzdHJpbmcuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHByKFN0cmluZyBzKSB7CisJaWYgKHNob3dTdHJ1Y3R1cmUpCisJICAgIFN5c3RlbS5vdXQucHJpbnQoaW5kZW50U3RyLnN1YnN0cmluZygwLCBsZXZlbCAqIDIpKTsKKwlTeXN0ZW0ub3V0LnByaW50bG4ocyk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvZGVtby9zcmMvbWFpbi9qYXZhL25hbWVzcGFjZS5qYXZhIGIvZGVtby9zcmMvbWFpbi9qYXZhL25hbWVzcGFjZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBlMzYyNDcKLS0tIC9kZXYvbnVsbAorKysgYi9kZW1vL3NyYy9tYWluL2phdmEvbmFtZXNwYWNlLmphdmEKQEAgLTAsMCArMSwxMzEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorICovCisKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YXgubWFpbC4qOworCisvKgorICogRGVtbyBhcHAgdGhhdCBleGVyY2lzZXMgdGhlIG5hbWVzcGFjZSBpbnRlcmZhY2VzLgorICogU2hvdyB0aGUgbmFtZXNwYWNlcyBzdXBwb3J0ZWQgYnkgYSBzdG9yZS4KKyAqCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCisKK3B1YmxpYyBjbGFzcyBuYW1lc3BhY2UgeworCisgICAgc3RhdGljIFN0cmluZyBwcm90b2NvbDsKKyAgICBzdGF0aWMgU3RyaW5nIGhvc3QgPSBudWxsOworICAgIHN0YXRpYyBTdHJpbmcgdXNlciA9IG51bGw7CisgICAgc3RhdGljIFN0cmluZyBwYXNzd29yZCA9IG51bGw7CisgICAgc3RhdGljIFN0cmluZyB1cmwgPSBudWxsOworICAgIHN0YXRpYyBpbnQgcG9ydCA9IC0xOworICAgIHN0YXRpYyBib29sZWFuIGRlYnVnID0gZmFsc2U7CisgICAgc3RhdGljIFN0cmluZyBzdXNlciA9ICJvdGhlciI7CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmcgYXJndltdKSB7CisJaW50IG1zZ251bSA9IC0xOworCWludCBvcHRpbmQ7CisKKwlmb3IgKG9wdGluZCA9IDA7IG9wdGluZCA8IGFyZ3YubGVuZ3RoOyBvcHRpbmQrKykgeworCSAgICBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLVQiKSkgeworCQlwcm90b2NvbCA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1IIikpIHsKKwkJaG9zdCA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1VIikpIHsKKwkJdXNlciA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1QIikpIHsKKwkJcGFzc3dvcmQgPSBhcmd2Wysrb3B0aW5kXTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItRCIpKSB7CisJCWRlYnVnID0gdHJ1ZTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItTCIpKSB7CisJCXVybCA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1wIikpIHsKKwkJcG9ydCA9IEludGVnZXIucGFyc2VJbnQoYXJndlsrK29wdGluZF0pOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi11IikpIHsKKwkJc3VzZXIgPSBhcmd2Wysrb3B0aW5kXTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItLSIpKSB7CisJCW9wdGluZCsrOworCQlicmVhazsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uc3RhcnRzV2l0aCgiLSIpKSB7CisJCVN5c3RlbS5vdXQucHJpbnRsbigKKyJVc2FnZTogbmFtZXNwYWNlIFstTCB1cmxdIFstVCBwcm90b2NvbF0gWy1IIGhvc3RdIFstcCBwb3J0XSBbLVUgdXNlcl0iKTsKKwkJU3lzdGVtLm91dC5wcmludGxuKAorIlx0Wy1QIHBhc3N3b3JkXSBbLXUgb3RoZXItdXNlcl0gWy1EXSIpOworCQlTeXN0ZW0uZXhpdCgxKTsKKwkgICAgfSBlbHNlIHsKKwkJYnJlYWs7CisJICAgIH0KKwl9CisKKwl0cnkgeworCSAgICAvLyBHZXQgYSBQcm9wZXJ0aWVzIG9iamVjdAorCSAgICBQcm9wZXJ0aWVzIHByb3BzID0gU3lzdGVtLmdldFByb3BlcnRpZXMoKTsKKworCSAgICAvLyBHZXQgYSBTZXNzaW9uIG9iamVjdAorCSAgICBTZXNzaW9uIHNlc3Npb24gPSBTZXNzaW9uLmdldEluc3RhbmNlKHByb3BzLCBudWxsKTsKKwkgICAgc2Vzc2lvbi5zZXREZWJ1ZyhkZWJ1Zyk7CisKKwkgICAgLy8gR2V0IGEgU3RvcmUgb2JqZWN0CisJICAgIFN0b3JlIHN0b3JlID0gbnVsbDsKKwkgICAgaWYgKHVybCAhPSBudWxsKSB7CisJCVVSTE5hbWUgdXJsbiA9IG5ldyBVUkxOYW1lKHVybCk7CisJCXN0b3JlID0gc2Vzc2lvbi5nZXRTdG9yZSh1cmxuKTsKKwkJc3RvcmUuY29ubmVjdCgpOworCSAgICB9IGVsc2UgeworCQlpZiAocHJvdG9jb2wgIT0gbnVsbCkJCQorCQkgICAgc3RvcmUgPSBzZXNzaW9uLmdldFN0b3JlKHByb3RvY29sKTsKKwkJZWxzZQorCQkgICAgc3RvcmUgPSBzZXNzaW9uLmdldFN0b3JlKCk7CisKKwkJLy8gQ29ubmVjdAorCQlpZiAoaG9zdCAhPSBudWxsIHx8IHVzZXIgIT0gbnVsbCB8fCBwYXNzd29yZCAhPSBudWxsKQorCQkgICAgc3RvcmUuY29ubmVjdChob3N0LCBwb3J0LCB1c2VyLCBwYXNzd29yZCk7CisJCWVsc2UKKwkJICAgIHN0b3JlLmNvbm5lY3QoKTsKKwkgICAgfQorCisJICAgIHByaW50Rm9sZGVycygiUGVyc29uYWwiLCBzdG9yZS5nZXRQZXJzb25hbE5hbWVzcGFjZXMoKSk7CisJICAgIHByaW50Rm9sZGVycygiVXNlciBcIiIgKyBzdXNlciArICJcIiIsCisJCQkJc3RvcmUuZ2V0VXNlck5hbWVzcGFjZXMoc3VzZXIpKTsKKwkgICAgcHJpbnRGb2xkZXJzKCJTaGFyZWQiLCBzdG9yZS5nZXRTaGFyZWROYW1lc3BhY2VzKCkpOworCisJICAgIHN0b3JlLmNsb3NlKCk7CisJfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiT29wcywgZ290IGV4Y2VwdGlvbiEgIiArIGV4LmdldE1lc3NhZ2UoKSk7CisJICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOworCX0KKwlTeXN0ZW0uZXhpdCgwKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHByaW50Rm9sZGVycyhTdHJpbmcgbmFtZSwgRm9sZGVyW10gZm9sZGVycykKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlTeXN0ZW0ub3V0LnByaW50bG4obmFtZSArICIgTmFtZXNwYWNlOiIpOworCWlmIChmb2xkZXJzID09IG51bGwgfHwgZm9sZGVycy5sZW5ndGggPT0gMCkgeworCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiAgPG5vbmU+Iik7CisJICAgIHJldHVybjsKKwl9CisJZm9yIChpbnQgaSA9IDA7IGkgPCBmb2xkZXJzLmxlbmd0aDsgaSsrKSB7CisJICAgIFN0cmluZyBmbiA9IGZvbGRlcnNbaV0uZ2V0RnVsbE5hbWUoKTsKKwkgICAgaWYgKGZuLmxlbmd0aCgpID09IDApCisJCWZuID0gIjxkZWZhdWx0IGZvbGRlcj4iOworCSAgICB0cnkgeworCQlTeXN0ZW0ub3V0LnByaW50bG4oIiAgIiArIGZuICsKKwkJCSIsIGRlbGltaXRlciBcIiIgKyBmb2xkZXJzW2ldLmdldFNlcGFyYXRvcigpICsgIlwiIik7CisJCUZvbGRlcltdIGZsID0gZm9sZGVyc1tpXS5saXN0KCk7CisJCWlmIChmbC5sZW5ndGggPiAwKSB7CisJCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiAgU3ViZm9sZGVyczoiKTsKKwkJICAgIGZvciAoaW50IGogPSAwOyBqIDwgZmwubGVuZ3RoOyBqKyspCisJCQlTeXN0ZW0ub3V0LnByaW50bG4oIiAgICAiICsgZmxbal0uZ2V0RnVsbE5hbWUoKSk7CisJCX0KKwkgICAgfSBjYXRjaCAoRm9sZGVyTm90Rm91bmRFeGNlcHRpb24gZXgpIHsgfQorCX0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9kZW1vL3NyYy9tYWluL2phdmEvcG9wdWxhdGUuamF2YSBiL2RlbW8vc3JjL21haW4vamF2YS9wb3B1bGF0ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjcyMWMxNmQKLS0tIC9kZXYvbnVsbAorKysgYi9kZW1vL3NyYy9tYWluL2phdmEvcG9wdWxhdGUuamF2YQpAQCAtMCwwICsxLDIzMSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgRGlzdHJpYnV0aW9uIExpY2Vuc2Ugdi4gMS4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvb3JnL2RvY3VtZW50cy9lZGwtdjEwLnBocC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQlNELTMtQ2xhdXNlCisgKi8KKworaW1wb3J0IGphdmF4Lm1haWwuKjsKK2ltcG9ydCBqYXZheC5tYWlsLmludGVybmV0Lio7CisKKy8qCisgKiBDb3B5IGZvbGRlciBoaWVyYXJjaGllcyBiZXR3ZWVuIGRpZmZlcmVudCBTdG9yZXMuIFRoaXMgaXMgYSB1c2VmdWwgCisgKiB1dGlsaXR5IHRvIHBvcHVsYXRlIG5ldyAoYW5kIHBvc3NpYmx5IGVtcHR5KSBtYWlsIHN0b3Jlcy4gU3BlY2lmeQorICogYm90aCB0aGUgc291cmNlIGFuZCBkZXN0aW5hdGlvbiBmb2xkZXJzIGFzIFVSTHMuCisgKgkKKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCisKK3B1YmxpYyBjbGFzcyBwb3B1bGF0ZSB7CisKKyAgICBzdGF0aWMgYm9vbGVhbiBmb3JjZSA9IGZhbHNlOworICAgIHN0YXRpYyBib29sZWFuIHNraXBTcGVjaWFsID0gZmFsc2U7CisgICAgc3RhdGljIGJvb2xlYW4gY2xlYXIgPSBmYWxzZTsKKyAgICBzdGF0aWMgYm9vbGVhbiBkb250UHJlc2VydmVGbGFncyA9IGZhbHNlOworICAgIHN0YXRpYyBib29sZWFuIHdhcm4gPSBmYWxzZTsKKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZyBhcmd2W10pIHsKKwlTdHJpbmcgc3JjVVJMID0gbnVsbDsKKwlTdHJpbmcgZHN0VVJMID0gbnVsbDsKKwlib29sZWFuIGRlYnVnID0gZmFsc2U7CisKKwlpbnQgb3B0aW5kOworCisJZm9yIChvcHRpbmQgPSAwOyBvcHRpbmQgPCBhcmd2Lmxlbmd0aDsgb3B0aW5kKyspIHsKKwkgICAgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1zIikpIHsKKwkJc3JjVVJMID0gYXJndlsrK29wdGluZF07CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLWQiKSkgeworCQlkc3RVUkwgPSBhcmd2Wysrb3B0aW5kXTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItRCIpKSB7CisJCWRlYnVnID0gdHJ1ZTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItZiIpKSB7CisJCWZvcmNlID0gdHJ1ZTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItUyIpKSB7CisJCXNraXBTcGVjaWFsID0gdHJ1ZTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItYyIpKSB7CisJCWNsZWFyID0gdHJ1ZTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItUCIpKSB7CisJCWRvbnRQcmVzZXJ2ZUZsYWdzID0gdHJ1ZTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItVyIpKSB7CisJCXdhcm4gPSB0cnVlOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi0tIikpIHsKKwkJb3B0aW5kKys7CisJCWJyZWFrOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5zdGFydHNXaXRoKCItIikpIHsKKwkJcHJpbnRVc2FnZSgpOworCQlTeXN0ZW0uZXhpdCgxKTsKKwkgICAgfSBlbHNlIHsKKwkJYnJlYWs7CisJICAgIH0KKwl9CisKKwl0cnkgeworCisJICAgIGlmIChzcmNVUkwgPT0gbnVsbCB8fCBkc3RVUkwgPT0gbnVsbCkgeworCQlwcmludFVzYWdlKCk7CisJCVN5c3RlbS5leGl0KDEpOworCSAgICB9CisKKwkgICAgU2Vzc2lvbiBzZXNzaW9uID0gU2Vzc2lvbi5nZXRJbnN0YW5jZSgKKwkJCQlTeXN0ZW0uZ2V0UHJvcGVydGllcygpLCBudWxsKTsKKwkgICAgc2Vzc2lvbi5zZXREZWJ1ZyhkZWJ1Zyk7CisKKwkgICAgLy8gR2V0IHNvdXJjZSBmb2xkZXIKKwkgICAgVVJMTmFtZSBzcmNVUkxOYW1lID0gbmV3IFVSTE5hbWUoc3JjVVJMKTsKKwkgICAgRm9sZGVyIHNyY0ZvbGRlcjsKKwkgICAgLy8gQ2hlY2sgaWYgdGhlIHNvdXJjZSBVUkwgaGFzIGEgZm9sZGVyIHNwZWNpZmllZC4gSWYKKwkgICAgLy8gbm90LCB3ZSB1c2UgdGhlIGRlZmF1bHQgZm9sZGVyCisJICAgIGlmIChzcmNVUkxOYW1lLmdldEZpbGUoKSA9PSBudWxsKSB7CisJCVN0b3JlIHMgPSBzZXNzaW9uLmdldFN0b3JlKHNyY1VSTE5hbWUpOworCQlzLmNvbm5lY3QoKTsKKwkJc3JjRm9sZGVyID0gcy5nZXREZWZhdWx0Rm9sZGVyKCk7CisJICAgIH0gZWxzZSB7CisJCXNyY0ZvbGRlciA9IHNlc3Npb24uZ2V0Rm9sZGVyKG5ldyBVUkxOYW1lKHNyY1VSTCkpOworCQlpZiAoIXNyY0ZvbGRlci5leGlzdHMoKSkgeworCQkgICAgU3lzdGVtLm91dC5wcmludGxuKCJzb3VyY2UgZm9sZGVyIGRvZXMgbm90IGV4aXN0Iik7CisJCSAgICBzcmNGb2xkZXIuZ2V0U3RvcmUoKS5jbG9zZSgpOworCQkgICAgU3lzdGVtLmV4aXQoMSk7CisJCX0KKwkgICAgfQorCisJICAgIC8vIFNldCB1cCBkZXN0aW5hdGlvbiBmb2xkZXIKKwkgICAgVVJMTmFtZSBkc3RVUkxOYW1lID0gbmV3IFVSTE5hbWUoZHN0VVJMKTsKKwkgICAgRm9sZGVyIGRzdEZvbGRlcjsKKwkgICAgLy8gQ2hlY2sgaWYgdGhlIGRlc3RpbmF0aW9uIFVSTCBoYXMgYSBmb2xkZXIgc3BlY2lmaWVkLiBJZgorCSAgICAvLyBub3QsIHdlIHVzZSB0aGUgc291cmNlIGZvbGRlciBuYW1lCisJICAgIGlmIChkc3RVUkxOYW1lLmdldEZpbGUoKSA9PSBudWxsKSB7CisJCVN0b3JlIHMgPSBzZXNzaW9uLmdldFN0b3JlKGRzdFVSTE5hbWUpOworCQlzLmNvbm5lY3QoKTsKKwkJZHN0Rm9sZGVyID0gcy5nZXRGb2xkZXIoc3JjRm9sZGVyLmdldE5hbWUoKSk7CisJICAgIH0gZWxzZQorCQlkc3RGb2xkZXIgPSBzZXNzaW9uLmdldEZvbGRlcihkc3RVUkxOYW1lKTsKKworCSAgICBpZiAoY2xlYXIgJiYgZHN0Rm9sZGVyLmV4aXN0cygpKSB7CisJCWlmICghZHN0Rm9sZGVyLmRlbGV0ZSh0cnVlKSkgeworCQkgICAgU3lzdGVtLm91dC5wcmludGxuKCJjb3VsZG4ndCBkZWxldGUgIiArCisJCQkJCQlkc3RGb2xkZXIuZ2V0RnVsbE5hbWUoKSk7CisJCSAgICByZXR1cm47CisJCX0KKwkgICAgfQorCSAgICBjb3B5KHNyY0ZvbGRlciwgZHN0Rm9sZGVyKTsKKworCSAgICAvLyBDbG9zZSB0aGUgcmVzcGVjdGl2ZSBzdG9yZXMuCisJICAgIHNyY0ZvbGRlci5nZXRTdG9yZSgpLmNsb3NlKCk7CisJICAgIGRzdEZvbGRlci5nZXRTdG9yZSgpLmNsb3NlKCk7CisKKwl9IGNhdGNoIChNZXNzYWdpbmdFeGNlcHRpb24gbWV4KSB7CisJICAgIFN5c3RlbS5vdXQucHJpbnRsbihtZXguZ2V0TWVzc2FnZSgpKTsKKwkgICAgbWV4LnByaW50U3RhY2tUcmFjZSgpOworCX0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGNvcHkoRm9sZGVyIHNyYywgRm9sZGVyIGRzdCkKKwkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJU3lzdGVtLm91dC5wcmludGxuKCJQb3B1bGF0aW5nICIgKyBkc3QuZ2V0RnVsbE5hbWUoKSk7CisKKwlGb2xkZXIgZGRzdCA9IGRzdDsKKwlGb2xkZXJbXSBzcmNGb2xkZXJzID0gbnVsbDsKKwlpZiAoKHNyYy5nZXRUeXBlKCkgJiBGb2xkZXIuSE9MRFNfRk9MREVSUykgIT0gMCkKKwkgICAgc3JjRm9sZGVycyA9IHNyYy5saXN0KCk7CisJYm9vbGVhbiBzcmNIYXNDaGlsZHJlbiA9IHNyY0ZvbGRlcnMgIT0gbnVsbCAmJiBzcmNGb2xkZXJzLmxlbmd0aCA+IDA7CisKKwlpZiAoIWRzdC5leGlzdHMoKSkgeworCSAgICAvLyBDcmVhdGUgaXQuCisJICAgIGJvb2xlYW4gZHN0SG9sZHNPbmx5Rm9sZGVycyA9IGZhbHNlOworCSAgICBpZiAoIWRzdC5jcmVhdGUoc3JjLmdldFR5cGUoKSkpIHsKKwkJLy8gbWlnaHQgbm90IGJlIGFibGUgdG8gY3JlYXRlIGEgZm9sZGVyIHRoYXQgaG9sZHMgYm90aAorCQlpZiAoIWRzdC5jcmVhdGUoc3JjSGFzQ2hpbGRyZW4gPyBGb2xkZXIuSE9MRFNfRk9MREVSUyA6CisJCQkJCQlGb2xkZXIuSE9MRFNfTUVTU0FHRVMpKSB7CisJCSAgICAvLyBtaWdodCBvbmx5IGJlIGFibGUgdG8gY3JlYXRlIG9uZSB0eXBlIChHbWFpbCkKKwkJICAgIGlmICghZHN0LmNyZWF0ZShGb2xkZXIuSE9MRFNfTUVTU0FHRVMpKSB7CisJCQlTeXN0ZW0ub3V0LnByaW50bG4oImNvdWxkbid0IGNyZWF0ZSAiICsKKwkJCQkJCQkgICAgZHN0LmdldEZ1bGxOYW1lKCkpOworCQkJcmV0dXJuOworCQkgICAgfQorCQl9CisJCWRzdEhvbGRzT25seUZvbGRlcnMgPSBzcmNIYXNDaGlsZHJlbjsKKwkgICAgfQorCisJICAgIC8vIENvcHkgb3ZlciBhbnkgbWVzc2dlcyBmcm9tIHNyYyB0byBkc3QKKwkgICAgaWYgKChzcmMuZ2V0VHlwZSgpICYgRm9sZGVyLkhPTERTX01FU1NBR0VTKSAhPSAwKSB7CisJCXNyYy5vcGVuKEZvbGRlci5SRUFEX09OTFkpOworCQlpZiAoZHN0SG9sZHNPbmx5Rm9sZGVycykgeworCQkgICAgaWYgKHNyYy5nZXRNZXNzYWdlQ291bnQoKSA+IDApIHsKKwkJCVN5c3RlbS5vdXQucHJpbnRsbigiVW5hYmxlIHRvIGNvcHkgbWVzc2FnZXMgZnJvbSAiICsKKwkJCSAgICBzcmMuZ2V0RnVsbE5hbWUoKSArICIgdG8gIiArIGRzdC5nZXRGdWxsTmFtZSgpICsKKwkJCSAgICAiIGJlY2F1c2UgZGVzdGluYXRpb24gaG9sZHMgb25seSBmb2xkZXJzIik7CisJCSAgICB9CisJCX0gZWxzZQorCQkgICAgY29weU1lc3NhZ2VzKHNyYywgZHN0KTsKKwkJc3JjLmNsb3NlKGZhbHNlKTsKKwkgICAgfQorCX0gZWxzZSAgeworCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oZHN0LmdldEZ1bGxOYW1lKCkgKyAiIGFscmVhZHkgZXhpc3RzIik7CisJICAgIC8vIENvcHkgb3ZlciBhbnkgbWVzc2dlcyBmcm9tIHNyYyB0byBkc3QKKwkgICAgaWYgKGZvcmNlICYmIChzcmMuZ2V0VHlwZSgpICYgRm9sZGVyLkhPTERTX01FU1NBR0VTKSAhPSAwKSB7CisJCXNyYy5vcGVuKEZvbGRlci5SRUFEX09OTFkpOworCQljb3B5TWVzc2FnZXMoc3JjLCBkc3QpOworCQlzcmMuY2xvc2UoZmFsc2UpOworCSAgICB9CisJfQorCisJLy8gQ29weSBvdmVyIHN1YmZvbGRlcnMKKwlpZiAoc3JjSGFzQ2hpbGRyZW4pIHsKKwkgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzcmNGb2xkZXJzLmxlbmd0aDsgaSsrKSB7CisJCS8vIHNraXAgc3BlY2lhbCBkaXJlY3Rvcmllcz8KKwkJaWYgKHNraXBTcGVjaWFsKSB7CisJCSAgICBpZiAoc3JjRm9sZGVyc1tpXS5nZXROYW1lKCkuZXF1YWxzKCJTQ0NTIikgfHwKKwkJCXNyY0ZvbGRlcnNbaV0uZ2V0TmFtZSgpLmVxdWFscygiRHJhZnRzIikgfHwKKwkJCXNyY0ZvbGRlcnNbaV0uZ2V0TmFtZSgpLmVxdWFscygiVHJhc2giKSB8fAorCQkJc3JjRm9sZGVyc1tpXS5nZXROYW1lKCkuZXF1YWxzKCJTaGFyZWQgRm9sZGVycyIpKQorCQkJY29udGludWU7CisJCX0KKwkJY29weShzcmNGb2xkZXJzW2ldLCBkc3QuZ2V0Rm9sZGVyKHNyY0ZvbGRlcnNbaV0uZ2V0TmFtZSgpKSk7CisJICAgIH0KKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29weSBtZXNzYWdlIGZyb20gc3JjIHRvIGRzdC4gIElmIGRvbnRQcmVzZXJ2ZUZsYWdzIGlzIHNldAorICAgICAqIHdlIGZpcnN0IGNvcHkgdGhlIG1lc3NhZ2VzIHRvIG1lbW9yeSwgY2xlYXIgYWxsIHRoZSBmbGFncywKKyAgICAgKiBhbmQgdGhlbiBjb3B5IHRvIHRoZSBkZXN0aW5hdGlvbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGNvcHlNZXNzYWdlcyhGb2xkZXIgc3JjLCBGb2xkZXIgZHN0KQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCU1lc3NhZ2VbXSBtc2dzID0gc3JjLmdldE1lc3NhZ2VzKCk7CisJaWYgKGRvbnRQcmVzZXJ2ZUZsYWdzKSB7CisJICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbXNncy5sZW5ndGg7IGkrKykgeworCQlNaW1lTWVzc2FnZSBtID0gbmV3IE1pbWVNZXNzYWdlKChNaW1lTWVzc2FnZSltc2dzW2ldKTsKKwkJbS5zZXRGbGFncyhtLmdldEZsYWdzKCksIGZhbHNlKTsKKwkJbXNnc1tpXSA9IG07CisJICAgIH0KKwl9CisJaWYgKHdhcm4pIHsKKwkgICAgLy8gaGF2ZSB0byBjb3B5IG1lc3NhZ2VzIG9uZSBhdCBhIHRpbWUKKwkgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisJCXRyeSB7CisJCSAgICBzcmMuY29weU1lc3NhZ2VzKG5ldyBNZXNzYWdlW10geyBtc2dzW2ldIH0sIGRzdCk7CisJCX0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBtZXgpIHsKKwkJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiV0FSTklORzogQ29weSBvZiBtZXNzYWdlICIgKyAoaSArIDEpICsKKwkJCSIgZnJvbSAiICsgc3JjLmdldEZ1bGxOYW1lKCkgKworCQkJIiB0byAiICsgZHN0LmdldEZ1bGxOYW1lKCkgKworCQkJIiBmYWlsZWQ6ICIgKyBtZXgudG9TdHJpbmcoKSk7CisJCX0KKwkgICAgfQorCX0gZWxzZQorCSAgICBzcmMuY29weU1lc3NhZ2VzKG1zZ3MsIGRzdCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBwcmludFVzYWdlKCkgeworCVN5c3RlbS5vdXQucHJpbnRsbigicG9wdWxhdGUgWy1EXSBbLWZdIFstU10gWy1jXSAiICsKKwkJCSAgICItcyBzb3VyY2VfdXJsIC1kIGRlc3RfdXJsIik7CisJU3lzdGVtLm91dC5wcmludGxuKCJVUkxzIGFyZSBvZiB0aGUgZm9ybTogIiArCisJCQkgICAicHJvdG9jb2w6Ly91c2VybmFtZTpwYXNzd29yZEBob3N0bmFtZS9mb2xkZXJuYW1lIik7CisJU3lzdGVtLm91dC5wcmludGxuKCJUaGUgZGVzdGluYXRpb24gVVJMIGRvZXMgbm90IG5lZWQgYSBmb2xkZXJuYW1lLCIgKworCQkJICAgIiBpbiB3aGljaCBjYXNlLCB0aGUgc291cmNlIGZvbGRlcm5hbWUgaXMgdXNlZCIpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2RlbW8vc3JjL21haW4vamF2YS9yZWdpc3RyeS5qYXZhIGIvZGVtby9zcmMvbWFpbi9qYXZhL3JlZ2lzdHJ5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTUyOTQ5MAotLS0gL2Rldi9udWxsCisrKyBiL2RlbW8vc3JjL21haW4vamF2YS9yZWdpc3RyeS5qYXZhCkBAIC0wLDAgKzEsMTUxIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBEaXN0cmlidXRpb24gTGljZW5zZSB2LiAxLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9vcmcvZG9jdW1lbnRzL2VkbC12MTAucGhwLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBCU0QtMy1DbGF1c2UKKyAqLworCitpbXBvcnQgamF2YS51dGlsLio7CisKK2ltcG9ydCBqYXZheC5tYWlsLio7CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC4qOworCisvKioKKyAqIFRoaXMgY2xhc3MgZGVtb25zdHJhdGVzIGhvdyB0byBxdWVyeSB0aGUgcmVnaXN0cnkgZm9yIGF2YWlsYWJsZQorICogUHJvdmlkZXJzLCBzZXQgZGVmYXVsdCBwcm92aWRlcnMsIGV0Yy4gU2VlIHNlY3Rpb24gNS4yIGluIHRoZQorICogSmF2YU1haWwgU3BlYyBmb3IgZGV0YWlscyBvbiBob3cgdG8gdXNlIHRoZSByZWdpc3RyeS4KKyAqIAorICogU2VlIHRoZSBjb21tZW50cyBpbmxpbmUgZm9yIHdoYXQncyBoYXBwZW5pbmcuCisgKgorICogQGF1dGhvciBNYXggU3BpdmFrCisgKi8KKworcHVibGljIGNsYXNzIHJlZ2lzdHJ5IHsKKyAgICAvLyBsZXQncyByZW1lbWJlciBhIGZldyBwcm92aWRlcnMKKyAgICBzdGF0aWMgUHJvdmlkZXIgX2FQcm92aWRlciwgX2JQcm92aWRlciwgX3N1blNNVFAsIF9zdW5JTUFQOyAKKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHsKKwlQcm9wZXJ0aWVzIHByb3BzID0gbmV3IFByb3BlcnRpZXMoKTsKKworCS8vIHNldCBzbXRwIGFuZCBpbWFwIHRvIGJlIG91ciBkZWZhdWx0IAorCS8vIHRyYW5zcG9ydCBhbmQgc3RvcmUgcHJvdG9jb2xzLCByZXNwZWN0aXZlbHkKKwlwcm9wcy5wdXQoIm1haWwudHJhbnNwb3J0LnByb3RvY29sIiwgInNtdHAiKTsKKwlwcm9wcy5wdXQoIm1haWwuc3RvcmUucHJvdG9jb2wiLCAiaW1hcCIpOworCisJLy8gCisJcHJvcHMucHV0KCJtYWlsLnNtdHAuY2xhc3MiLCAiY29tLnN1bi5tYWlsLnNtdHAuU01UUFRyYW5zcG9ydCIpOworCXByb3BzLnB1dCgibWFpbC5pbWFwLmNsYXNzIiwgImNvbS5zdW4ubWFpbC5pbWFwLklNQVBTdG9yZSIpOworCQorCVNlc3Npb24gc2Vzc2lvbiA9IFNlc3Npb24uZ2V0SW5zdGFuY2UocHJvcHMsIG51bGwpOworCS8vc2Vzc2lvbi5zZXREZWJ1Zyh0cnVlKTsKKworCS8vIFJldHJpZXZlIGFsbCBjb25maWd1cmVkIHByb3ZpZGVycyBmcm9tIHRoZSBTZXNzaW9uCisJU3lzdGVtLm91dC5wcmludGxuKCJcbi0tLS0tLSBnZXRQcm92aWRlcnMoKS0tLS0tLS0tLS0iKTsKKwlQcm92aWRlcltdIHByb3ZpZGVycyA9IHNlc3Npb24uZ2V0UHJvdmlkZXJzKCk7CisJZm9yIChpbnQgaSA9IDA7IGkgPCBwcm92aWRlcnMubGVuZ3RoOyBpKyspIHsKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCIqKiAiICsgcHJvdmlkZXJzW2ldKTsKKworCSAgICAvLyBsZXQncyByZW1lbWJlciBzb21lIHByb3ZpZGVycyBzbyB0aGF0IHdlIGNhbiB1c2UgdGhlbSBsYXRlcgorCSAgICAvLyAoSSdtIGV4cGxpY2l0bHkgc2hvd2luZyBtdWx0aXBsZSB3YXlzIG9mIHRlc3RpbmcgUHJvdmlkZXJzKQorCSAgICAvLyBCVFcsIG5vIFByb3ZpZGVyICJBQ01FIENvcnAiIHdpbGwgYmUgZm91bmQgaW4gdGhlIGRlZmF1bHQKKwkgICAgLy8gc2V0dXAgYi9jIGl0cyBub3QgaW4gYW55IGphdmFtYWlsLnByb3ZpZGVycyByZXNvdXJjZSBmaWxlcworCSAgICBTdHJpbmcgcyA9IG51bGw7CisJICAgIGlmICgoKHMgPSBwcm92aWRlcnNbaV0uZ2V0VmVuZG9yKCkpICE9IG51bGwpICYmCisJCXMuc3RhcnRzV2l0aCgiQUNNRSBDb3JwIikpIHsKKwkJX2FQcm92aWRlciA9IHByb3ZpZGVyc1tpXTsKKwkgICAgfQorCisJICAgIC8vIHRoaXMgUHJvdmlkZXIgd29uJ3QgYmUgZm91bmQgYnkgZGVmYXVsdCBlaXRoZXIKKwkgICAgaWYgKHByb3ZpZGVyc1tpXS5nZXRDbGFzc05hbWUoKS5lbmRzV2l0aCgiYXBwbGljYXRpb24uc210cCIpKQorCQlfYlByb3ZpZGVyID0gcHJvdmlkZXJzW2ldOworCisJICAgIC8vIHRoaXMgUHJvdmlkZXIgd2lsbCBiZSBmb3VuZCBzaW5jZSBjb20uc3VuLm1haWwuaW1hcC5JTUFQU3RvcmUKKwkgICAgLy8gaXMgY29uZmlndXJlZCBpbiBqYXZhbWFpbC5kZWZhdWx0LnByb3ZpZGVycworCSAgICBpZiAocHJvdmlkZXJzW2ldLmdldENsYXNzTmFtZSgpLmVxdWFscygiY29tLnN1bi5tYWlsLmltYXAuSU1BUFN0b3JlIikpeworCQlfc3VuSU1BUCA9IHByb3ZpZGVyc1tpXTsKKwkgICAgfQorCisJICAgIC8vIHRoaXMgUHJvdmlkZXIgd2lsbCBiZSBmb3VuZCBhcyB3ZWxsIHNpbmNlIHRoZXJlIGlzIGFuCisJICAgIC8vIE9yYWNsZSBTTVRQIHRyYW5zcG9ydCBjb25maWd1cmVkIGJ5IAorCSAgICAvLyBkZWZhdWx0IGluIGphdmFtYWlsLmRlZmF1bHQucHJvdmlkZXJzCisJICAgIGlmICgoKHMgPSBwcm92aWRlcnNbaV0uZ2V0VmVuZG9yKCkpICE9IG51bGwpICYmCisJCXMuc3RhcnRzV2l0aCgiT3JhY2xlIikgJiYgCisJCXByb3ZpZGVyc1tpXS5nZXRUeXBlKCkgPT0gUHJvdmlkZXIuVHlwZS5UUkFOU1BPUlQgJiYKKwkJcHJvdmlkZXJzW2ldLmdldFByb3RvY29sKCkuZXF1YWxzSWdub3JlQ2FzZSgic210cCIpKSB7CisJCV9zdW5TTVRQID0gcHJvdmlkZXJzW2ldOworCSAgICB9CisJfQorCQorCVN5c3RlbS5vdXQucHJpbnRsbigiXG4tLS0tLS0gaW5pdGlhbCBwcm90b2NvbCBkZWZhdWx0cyAtLS0tLS0tIik7CisJdHJ5IHsKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJpbWFwOiAiICsgc2Vzc2lvbi5nZXRQcm92aWRlcigiaW1hcCIpKTsKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJzbXRwOiAiICsgc2Vzc2lvbi5nZXRQcm92aWRlcigic210cCIpKTsKKwkgICAgLy8gdGhlIE5OVFAgcHJvdmlkZXIgd2lsbCBmYWlsIHNpbmNlIHdlIGRvbid0IGhhdmUgb25lIGNvbmZpZ3VyZWQKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJubnRwOiAiICsgc2Vzc2lvbi5nZXRQcm92aWRlcigibm50cCIpKTsKKwl9IGNhdGNoIChOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiBtZXgpIHsgCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiPj4gVGhpcyBleGNlcHRpb24gaXMgT0sgc2luY2UgdGhlcmUgaXMgbm8gTk5UUCBQcm92aWRlciBjb25maWd1cmVkIGJ5IGRlZmF1bHQiKTsKKwkgICAgbWV4LnByaW50U3RhY2tUcmFjZSgpOworCX0KKworCVN5c3RlbS5vdXQucHJpbnRsbigiXG4tLS0tLS0gc2V0IG5ldyBwcm90b2NvbCBkZWZhdWx0cyAtLS0tLS0iKTsKKwkvLyBzZXQgc29tZSBuZXcgZGVmYXVsdHMKKwl0cnkgeworCSAgICAvLyBzaW5jZSBfYVByb3ZpZGVyIGlzbid0IGNvbmZpZ3VyZWQsIHRoaXMgd2lsbCBmYWlsCisJICAgIHNlc3Npb24uc2V0UHJvdmlkZXIoX2FQcm92aWRlcik7ICAvLyB3aWxsIGZhaWwKKwl9IGNhdGNoIChOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiBtZXgpIHsgCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiPj4gRXhjZXB0aW9uIGV4cGVjdGVkOiBfYVByb3ZpZGVyIGlzIG51bGwiKTsKKwkgICAgbWV4LnByaW50U3RhY2tUcmFjZSgpOyAKKwl9CisJdHJ5IHsKKwkgICAgLy8gX3N1bklNQVAgcHJvdmlkZXIgc2hvdWxkJ3ZlIGNvbmZpZ3VyZWQgY29ycmVjdGx5OyBzaG91bGQgd29yaworCSAgICBzZXNzaW9uLnNldFByb3ZpZGVyKF9zdW5JTUFQKTsKKwl9IGNhdGNoIChOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiBtZXgpIHsgbWV4LnByaW50U3RhY2tUcmFjZSgpOyB9CisJdHJ5IHsKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJpbWFwOiAiICsgc2Vzc2lvbi5nZXRQcm92aWRlcigiaW1hcCIpKTsKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJzbXRwOiAiICsgc2Vzc2lvbi5nZXRQcm92aWRlcigic210cCIpKTsKKwl9IGNhdGNoIChOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiBtZXgpIHsgbWV4LnByaW50U3RhY2tUcmFjZSgpOyB9CisKKworCVN5c3RlbS5vdXQucHJpbnRsbigiXG5cbi0tLS0tIGdldCBzb21lIHN0b3JlcyAtLS0tLS0tLS0iKTsKKwkvLyBtdWx0aXBsZSB3YXlzIHRvIHJldHJpZXZlIHN0b3Jlcy4gdGhlc2Ugd2lsbCBwcmludCBvdXQgdGhlCisJLy8gc3RyaW5nICJpbWFwOiIgc2luY2UgaXRzIHRoZSBVUkxOYW1lIGZvciB0aGUgc3RvcmUKKwl0cnkgeworCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oImdldFN0b3JlKCk6ICIgKyBzZXNzaW9uLmdldFN0b3JlKCkpOworCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oImdldFN0b3JlKFByb3ZpZGVyKTogIiArIAorCQkJICAgICAgIHNlc3Npb24uZ2V0U3RvcmUoX3N1bklNQVApKTsKKwl9IGNhdGNoIChOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiBtZXgpIHsKKwkgICAgbWV4LnByaW50U3RhY2tUcmFjZSgpOworCX0KKworCXRyeSB7CisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZ2V0U3RvcmUoaW1hcCk6ICIgKyBzZXNzaW9uLmdldFN0b3JlKCJpbWFwIikpOworCSAgICAvLyBwb3AzIHdpbGwgZmFpbCBzaW5jZSBpdCBkb2Vzbid0IGV4aXN0CisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZ2V0U3RvcmUocG9wMyk6ICIgKyBzZXNzaW9uLmdldFN0b3JlKCJwb3AzIikpOworCX0gY2F0Y2ggKE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIG1leCkgeyAKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCI+PiBFeGNlcHRpb24gZXhwZWN0ZWQ6IG5vIHBvcDMgcHJvdmlkZXIiKTsKKwkgICAgbWV4LnByaW50U3RhY2tUcmFjZSgpOyAKKwl9CisKKworCVN5c3RlbS5vdXQucHJpbnRsbigiXG5cbi0tLS0tIG5vdyBmb3IgdHJhbnNwb3J0cy9hZGRyZXNzZXMgLS0tLS0tLS0tIik7CisJLy8gcmV0cmlldmUgdHJhbnNwb3J0czsgdGhlc2Ugd2lsbCBwcmludCBvdXQgInNtdHA6IiAobGlrZSBzdG9yZXMgZGlkKQorCXRyeSB7CisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZ2V0VHJhbnNwb3J0KCk6ICIgKyBzZXNzaW9uLmdldFRyYW5zcG9ydCgpKTsKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJnZXRUcmFuc3BvcnQoUHJvdmlkZXIpOiAiICsgCisJCQkgICAgICAgc2Vzc2lvbi5nZXRUcmFuc3BvcnQoX3N1blNNVFApKTsKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJnZXRUcmFuc3BvcnQoc210cCk6ICIgKyAKKwkJCSAgICAgICBzZXNzaW9uLmdldFRyYW5zcG9ydCgic210cCIpKTsKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJnZXRUcmFuc3BvcnQoQWRkcmVzcyk6ICIgKyAKKwkJCSAgICAgICBzZXNzaW9uLmdldFRyYW5zcG9ydChuZXcgSW50ZXJuZXRBZGRyZXNzKCJtc3BpdmFrQGFwaWxvbiIpKSk7CisJICAgIC8vIE5ld3Mgd2lsbCBmYWlsIHNpbmNlIHRoZXJlJ3Mgbm8gbmV3cyBwcm92aWRlciBjb25maWd1cmVkCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZ2V0VHJhbnNwb3J0KE5ld3MpOiAiICsgCisJCQkgICAgICAgc2Vzc2lvbi5nZXRUcmFuc3BvcnQobmV3IE5ld3NBZGRyZXNzKCJyZWMuaHVtb3IiKSkpOworCX0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBtZXgpIHsgCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiPj4gRXhjZXB0aW9uIGV4cGVjdGVkOiBubyBuZXdzIHByb3ZpZGVyIGNvbmZpZ3VyZWQiKTsKKwkgICAgbWV4LnByaW50U3RhY2tUcmFjZSgpOyAKKwl9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvZGVtby9zcmMvbWFpbi9qYXZhL3NlYXJjaC5qYXZhIGIvZGVtby9zcmMvbWFpbi9qYXZhL3NlYXJjaC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY5YmJlNDIKLS0tIC9kZXYvbnVsbAorKysgYi9kZW1vL3NyYy9tYWluL2phdmEvc2VhcmNoLmphdmEKQEAgLTAsMCArMSwzMDEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorICovCisKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YXgubWFpbC4qOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuKjsKK2ltcG9ydCBqYXZheC5tYWlsLnNlYXJjaC4qOworaW1wb3J0IGphdmF4LmFjdGl2YXRpb24uKjsKKworLyoKKyAqIFNlYXJjaCB0aGUgZ2l2ZW4gZm9sZGVyIGZvciBtZXNzYWdlcyBtYXRjaGluZyB0aGUgZ2l2ZW4KKyAqIGNyaXRlcmlhLgorICoKKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKi8KKworcHVibGljIGNsYXNzIHNlYXJjaCB7CisKKyAgICBzdGF0aWMgU3RyaW5nIHByb3RvY29sID0gImltYXAiOworICAgIHN0YXRpYyBTdHJpbmcgaG9zdCA9IG51bGw7CisgICAgc3RhdGljIFN0cmluZyB1c2VyID0gbnVsbDsKKyAgICBzdGF0aWMgU3RyaW5nIHBhc3N3b3JkID0gbnVsbDsKKyAgICBzdGF0aWMgU3RyaW5nIG1ib3ggPSAiSU5CT1giOworICAgIHN0YXRpYyBTdHJpbmcgdXJsID0gbnVsbDsKKyAgICBzdGF0aWMgYm9vbGVhbiBkZWJ1ZyA9IGZhbHNlOworCisgICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nIGFyZ3ZbXSkgeworCWludCBvcHRpbmQ7CisKKwlTdHJpbmcgc3ViamVjdCA9IG51bGw7CisJU3RyaW5nIGZyb20gPSBudWxsOworCWJvb2xlYW4gb3IgPSBmYWxzZTsKKwlib29sZWFuIHRvZGF5ID0gZmFsc2U7CisJaW50IHNpemUgPSAtMTsKKworCWZvciAob3B0aW5kID0gMDsgb3B0aW5kIDwgYXJndi5sZW5ndGg7IG9wdGluZCsrKSB7CisJICAgIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItVCIpKSB7CisJCXByb3RvY29sID0gYXJndlsrK29wdGluZF07CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLUgiKSkgeworCQlob3N0ID0gYXJndlsrK29wdGluZF07CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLVUiKSkgeworCQl1c2VyID0gYXJndlsrK29wdGluZF07CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLVAiKSkgeworCQlwYXNzd29yZCA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1vciIpKSB7CisJCW9yID0gdHJ1ZTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItRCIpKSB7CisJCWRlYnVnID0gdHJ1ZTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItZiIpKSB7CisJCW1ib3ggPSBhcmd2Wysrb3B0aW5kXTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItTCIpKSB7CisJCXVybCA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1zdWJqZWN0IikpIHsKKwkJc3ViamVjdCA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1mcm9tIikpIHsKKwkJZnJvbSA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi10b2RheSIpKSB7CisJCXRvZGF5ID0gdHJ1ZTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItc2l6ZSIpKSB7CisJCXNpemUgPSBJbnRlZ2VyLnBhcnNlSW50KGFyZ3ZbKytvcHRpbmRdKTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItLSIpKSB7CisJCW9wdGluZCsrOworCQlicmVhazsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uc3RhcnRzV2l0aCgiLSIpKSB7CisJCVN5c3RlbS5vdXQucHJpbnRsbigKKwkJICJVc2FnZTogc2VhcmNoIFstRF0gWy1MIHVybF0gWy1UIHByb3RvY29sXSBbLUggaG9zdF0gIiArIAorCQkgIlstVSB1c2VyXSBbLVAgcGFzc3dvcmRdIFstZiBtYWlsYm94XSAiICsgCisJCSAiWy1zdWJqZWN0IHN1YmplY3RdIFstZnJvbSBmcm9tXSBbLW9yXSBbLXRvZGF5XSIpOworCQlTeXN0ZW0uZXhpdCgxKTsKKwkgICAgfSBlbHNlIHsKKwkJYnJlYWs7CisJICAgIH0KKwl9CisKKwl0cnkgeworCisJICAgIGlmICgoc3ViamVjdCA9PSBudWxsKSAmJiAoZnJvbSA9PSBudWxsKSAmJiAhdG9kYXkgJiYgc2l6ZSA8IDApIHsKKwkJU3lzdGVtLm91dC5wcmludGxuKAorCQkJICAgICJTcGVjaWZ5IGVpdGhlciAtc3ViamVjdCwgLWZyb20sIC10b2RheSwgb3IgLXNpemUiKTsKKwkJU3lzdGVtLmV4aXQoMSk7CisJICAgIH0KKworCSAgICAvLyBHZXQgYSBQcm9wZXJ0aWVzIG9iamVjdAorCSAgICBQcm9wZXJ0aWVzIHByb3BzID0gU3lzdGVtLmdldFByb3BlcnRpZXMoKTsKKworCSAgICAvLyBHZXQgYSBTZXNzaW9uIG9iamVjdAorCSAgICBTZXNzaW9uIHNlc3Npb24gPSBTZXNzaW9uLmdldEluc3RhbmNlKHByb3BzLCBudWxsKTsKKwkgICAgc2Vzc2lvbi5zZXREZWJ1ZyhkZWJ1Zyk7CisKKwkgICAgLy8gR2V0IGEgU3RvcmUgb2JqZWN0CisJICAgIFN0b3JlIHN0b3JlID0gbnVsbDsKKwkgICAgaWYgKHVybCAhPSBudWxsKSB7CisJCVVSTE5hbWUgdXJsbiA9IG5ldyBVUkxOYW1lKHVybCk7CisJCXN0b3JlID0gc2Vzc2lvbi5nZXRTdG9yZSh1cmxuKTsKKwkJc3RvcmUuY29ubmVjdCgpOworCSAgICB9IGVsc2UgeworCQlpZiAocHJvdG9jb2wgIT0gbnVsbCkJCQorCQkgICAgc3RvcmUgPSBzZXNzaW9uLmdldFN0b3JlKHByb3RvY29sKTsKKwkJZWxzZQorCQkgICAgc3RvcmUgPSBzZXNzaW9uLmdldFN0b3JlKCk7CisKKwkJLy8gQ29ubmVjdAorCQlpZiAoaG9zdCAhPSBudWxsIHx8IHVzZXIgIT0gbnVsbCB8fCBwYXNzd29yZCAhPSBudWxsKQorCQkgICAgc3RvcmUuY29ubmVjdChob3N0LCB1c2VyLCBwYXNzd29yZCk7CisJCWVsc2UKKwkJICAgIHN0b3JlLmNvbm5lY3QoKTsKKwkgICAgfQorCSAgICAKKworCSAgICAvLyBPcGVuIHRoZSBGb2xkZXIKKworCSAgICBGb2xkZXIgZm9sZGVyID0gc3RvcmUuZ2V0RGVmYXVsdEZvbGRlcigpOworCSAgICBpZiAoZm9sZGVyID09IG51bGwpIHsKKwkJU3lzdGVtLm91dC5wcmludGxuKCJDYW50IGZpbmQgZGVmYXVsdCBuYW1lc3BhY2UiKTsKKwkJU3lzdGVtLmV4aXQoMSk7CisJICAgIH0KKworCSAgICBmb2xkZXIgPSBmb2xkZXIuZ2V0Rm9sZGVyKG1ib3gpOworCSAgICBpZiAoZm9sZGVyID09IG51bGwpIHsKKwkJU3lzdGVtLm91dC5wcmludGxuKCJJbnZhbGlkIGZvbGRlciIpOworCQlTeXN0ZW0uZXhpdCgxKTsKKwkgICAgfQorCisJICAgIGZvbGRlci5vcGVuKEZvbGRlci5SRUFEX09OTFkpOworCSAgICBTZWFyY2hUZXJtIHRlcm0gPSBudWxsOworCisJICAgIGlmIChzdWJqZWN0ICE9IG51bGwpCisJCXRlcm0gPSBuZXcgU3ViamVjdFRlcm0oc3ViamVjdCk7CisJICAgIGlmIChmcm9tICE9IG51bGwpIHsKKwkJRnJvbVN0cmluZ1Rlcm0gZnJvbVRlcm0gPSBuZXcgRnJvbVN0cmluZ1Rlcm0oZnJvbSk7CisJCWlmICh0ZXJtICE9IG51bGwpIHsKKwkJICAgIGlmIChvcikKKwkJCXRlcm0gPSBuZXcgT3JUZXJtKHRlcm0sIGZyb21UZXJtKTsKKwkJICAgIGVsc2UKKwkJCXRlcm0gPSBuZXcgQW5kVGVybSh0ZXJtLCBmcm9tVGVybSk7CisJCX0KKwkJZWxzZQorCQkgICAgdGVybSA9IGZyb21UZXJtOworCSAgICB9CisJICAgIGlmICh0b2RheSkgeworCQlDYWxlbmRhciBjID0gQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoKTsKKwkJYy5zZXQoQ2FsZW5kYXIuSE9VUiwgMCk7CisJCWMuc2V0KENhbGVuZGFyLk1JTlVURSwgMCk7CisJCWMuc2V0KENhbGVuZGFyLlNFQ09ORCwgMCk7CisJCWMuc2V0KENhbGVuZGFyLk1JTExJU0VDT05ELCAwKTsKKwkJYy5zZXQoQ2FsZW5kYXIuQU1fUE0sIENhbGVuZGFyLkFNKTsKKwkJUmVjZWl2ZWREYXRlVGVybSBzdGFydERhdGVUZXJtID0gCisJCSBuZXcgUmVjZWl2ZWREYXRlVGVybShDb21wYXJpc29uVGVybS5HRSwgYy5nZXRUaW1lKCkpOworCQljLmFkZChDYWxlbmRhci5EQVRFLCAxKTsJLy8gbmV4dCBkYXkKKwkJUmVjZWl2ZWREYXRlVGVybSBlbmREYXRlVGVybSA9IAorCQkgbmV3IFJlY2VpdmVkRGF0ZVRlcm0oQ29tcGFyaXNvblRlcm0uTFQsIGMuZ2V0VGltZSgpKTsKKwkJU2VhcmNoVGVybSBkYXRlVGVybSA9IG5ldyBBbmRUZXJtKHN0YXJ0RGF0ZVRlcm0sIGVuZERhdGVUZXJtKTsKKwkJaWYgKHRlcm0gIT0gbnVsbCkgeworCQkgICAgaWYgKG9yKQorCQkJdGVybSA9IG5ldyBPclRlcm0odGVybSwgZGF0ZVRlcm0pOworCQkgICAgZWxzZQorCQkJdGVybSA9IG5ldyBBbmRUZXJtKHRlcm0sIGRhdGVUZXJtKTsKKwkJfQorCQllbHNlCisJCSAgICB0ZXJtID0gZGF0ZVRlcm07CisJICAgIH0KKworCSAgICBpZiAoc2l6ZSA+PSAwKSB7CisJCVNpemVUZXJtIHNpemVUZXJtID0gbmV3IFNpemVUZXJtKENvbXBhcmlzb25UZXJtLkdULCBzaXplKTsKKwkJaWYgKHRlcm0gIT0gbnVsbCkgeworCQkgICAgaWYgKG9yKQorCQkJdGVybSA9IG5ldyBPclRlcm0odGVybSwgc2l6ZVRlcm0pOworCQkgICAgZWxzZQorCQkJdGVybSA9IG5ldyBBbmRUZXJtKHRlcm0sIHNpemVUZXJtKTsKKwkJfQorCQllbHNlCisJCSAgICB0ZXJtID0gc2l6ZVRlcm07CisJICAgIH0KKworCSAgICBNZXNzYWdlW10gbXNncyA9IGZvbGRlci5zZWFyY2godGVybSk7CisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRk9VTkQgIiArIG1zZ3MubGVuZ3RoICsgIiBNRVNTQUdFUyIpOworCSAgICBpZiAobXNncy5sZW5ndGggPT0gMCkgLy8gbm8gbWF0Y2gKKwkJU3lzdGVtLmV4aXQoMSk7CisKKwkgICAgLy8gVXNlIGEgc3VpdGFibGUgRmV0Y2hQcm9maWxlCisJICAgIEZldGNoUHJvZmlsZSBmcCA9IG5ldyBGZXRjaFByb2ZpbGUoKTsKKwkgICAgZnAuYWRkKEZldGNoUHJvZmlsZS5JdGVtLkVOVkVMT1BFKTsKKwkgICAgZm9sZGVyLmZldGNoKG1zZ3MsIGZwKTsKKworCSAgICBmb3IgKGludCBpID0gMDsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspIHsKKwkJU3lzdGVtLm91dC5wcmludGxuKCItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIpOworCQlTeXN0ZW0ub3V0LnByaW50bG4oIk1FU1NBR0UgIyIgKyAoaSArIDEpICsgIjoiKTsKKwkJZHVtcFBhcnQobXNnc1tpXSk7CisJICAgIH0KKworCSAgICBmb2xkZXIuY2xvc2UoZmFsc2UpOworCSAgICBzdG9yZS5jbG9zZSgpOworCX0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIk9vcHMsIGdvdCBleGNlcHRpb24hICIgKyBleC5nZXRNZXNzYWdlKCkpOworCSAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKKwl9CisKKwlTeXN0ZW0uZXhpdCgxKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgZHVtcFBhcnQoUGFydCBwKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlpZiAocCBpbnN0YW5jZW9mIE1lc3NhZ2UpIHsKKwkgICAgTWVzc2FnZSBtID0gKE1lc3NhZ2UpcDsKKwkgICAgQWRkcmVzc1tdIGE7CisJICAgIC8vIEZST00gCisJICAgIGlmICgoYSA9IG0uZ2V0RnJvbSgpKSAhPSBudWxsKSB7CisJCWZvciAoaW50IGogPSAwOyBqIDwgYS5sZW5ndGg7IGorKykKKwkJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRlJPTTogIiArIGFbal0udG9TdHJpbmcoKSk7CisJICAgIH0KKworCSAgICAvLyBUTworCSAgICBpZiAoKGEgPSBtLmdldFJlY2lwaWVudHMoTWVzc2FnZS5SZWNpcGllbnRUeXBlLlRPKSkgIT0gbnVsbCkgeworCQlmb3IgKGludCBqID0gMDsgaiA8IGEubGVuZ3RoOyBqKyspCisJCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlRPOiAiICsgYVtqXS50b1N0cmluZygpKTsKKwkgICAgfQorCisJICAgIC8vIFNVQkpFQ1QKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJTVUJKRUNUOiAiICsgbS5nZXRTdWJqZWN0KCkpOworCisJICAgIC8vIERBVEUKKwkgICAgRGF0ZSBkID0gbS5nZXRTZW50RGF0ZSgpOworCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlNlbmREYXRlOiAiICsKKwkJKGQgIT0gbnVsbCA/IGQudG9Mb2NhbGVTdHJpbmcoKSA6ICJVTktOT1dOIikpOworCisJICAgIC8vIEZMQUdTOgorCSAgICBGbGFncyBmbGFncyA9IG0uZ2V0RmxhZ3MoKTsKKwkgICAgU3RyaW5nQnVmZmVyIHNiID0gbmV3IFN0cmluZ0J1ZmZlcigpOworCSAgICBGbGFncy5GbGFnW10gc2YgPSBmbGFncy5nZXRTeXN0ZW1GbGFncygpOyAvLyBnZXQgdGhlIHN5c3RlbSBmbGFncworCisJICAgIGJvb2xlYW4gZmlyc3QgPSB0cnVlOworCSAgICBmb3IgKGludCBpID0gMDsgaSA8IHNmLmxlbmd0aDsgaSsrKSB7CisJCVN0cmluZyBzOworCQlGbGFncy5GbGFnIGYgPSBzZltpXTsKKwkJaWYgKGYgPT0gRmxhZ3MuRmxhZy5BTlNXRVJFRCkKKwkJICAgIHMgPSAiXFxBbnN3ZXJlZCI7CisJCWVsc2UgaWYgKGYgPT0gRmxhZ3MuRmxhZy5ERUxFVEVEKQorCQkgICAgcyA9ICJcXERlbGV0ZWQiOworCQllbHNlIGlmIChmID09IEZsYWdzLkZsYWcuRFJBRlQpCisJCSAgICBzID0gIlxcRHJhZnQiOworCQllbHNlIGlmIChmID09IEZsYWdzLkZsYWcuRkxBR0dFRCkKKwkJICAgIHMgPSAiXFxGbGFnZ2VkIjsKKwkJZWxzZSBpZiAoZiA9PSBGbGFncy5GbGFnLlJFQ0VOVCkKKwkJICAgIHMgPSAiXFxSZWNlbnQiOworCQllbHNlIGlmIChmID09IEZsYWdzLkZsYWcuU0VFTikKKwkJICAgIHMgPSAiXFxTZWVuIjsKKwkJZWxzZQorCQkgICAgY29udGludWU7CS8vIHNraXAgaXQKKwkJaWYgKGZpcnN0KQorCQkgICAgZmlyc3QgPSBmYWxzZTsKKwkJZWxzZQorCQkgICAgc2IuYXBwZW5kKCcgJyk7CisJCXNiLmFwcGVuZChzKTsKKwkgICAgfQorCisJICAgIFN0cmluZ1tdIHVmID0gZmxhZ3MuZ2V0VXNlckZsYWdzKCk7IC8vIGdldCB0aGUgdXNlciBmbGFnIHN0cmluZ3MKKwkgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB1Zi5sZW5ndGg7IGkrKykgeworCQlpZiAoZmlyc3QpCisJCSAgICBmaXJzdCA9IGZhbHNlOworCQllbHNlCisJCSAgICBzYi5hcHBlbmQoJyAnKTsKKwkJc2IuYXBwZW5kKHVmW2ldKTsKKwkgICAgfQorCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkZMQUdTID0gIiArIHNiLnRvU3RyaW5nKCkpOworCX0KKworCVN5c3RlbS5vdXQucHJpbnRsbigiQ09OVEVOVC1UWVBFOiAiICsgcC5nZXRDb250ZW50VHlwZSgpKTsKKworCS8qIER1bXAgaW5wdXQgc3RyZWFtCisJSW5wdXRTdHJlYW0gaXMgPSAoKE1pbWVNZXNzYWdlKW0pLmdldElucHV0U3RyZWFtKCk7CisJaW50IGM7CisJd2hpbGUgKChjID0gaXMucmVhZCgpKSAhPSAtMSkKKwkgICAgU3lzdGVtLm91dC53cml0ZShjKTsKKwkqLworCisJT2JqZWN0IG8gPSBwLmdldENvbnRlbnQoKTsKKwlpZiAobyBpbnN0YW5jZW9mIFN0cmluZykgeworCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlRoaXMgaXMgYSBTdHJpbmciKTsKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKChTdHJpbmcpbyk7CisJfSBlbHNlIGlmIChvIGluc3RhbmNlb2YgTXVsdGlwYXJ0KSB7CisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiVGhpcyBpcyBhIE11bHRpcGFydCIpOworCSAgICBNdWx0aXBhcnQgbXAgPSAoTXVsdGlwYXJ0KW87CisJICAgIGludCBjb3VudCA9IG1wLmdldENvdW50KCk7CisJICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykKKwkJZHVtcFBhcnQobXAuZ2V0Qm9keVBhcnQoaSkpOworCX0gZWxzZSBpZiAobyBpbnN0YW5jZW9mIElucHV0U3RyZWFtKSB7CisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiVGhpcyBpcyBqdXN0IGFuIGlucHV0IHN0cmVhbSIpOworCSAgICBJbnB1dFN0cmVhbSBpcyA9IChJbnB1dFN0cmVhbSlvOworCSAgICBpbnQgYzsKKwkgICAgd2hpbGUgKChjID0gaXMucmVhZCgpKSAhPSAtMSkKKwkJU3lzdGVtLm91dC53cml0ZShjKTsKKwl9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvZGVtby9zcmMvbWFpbi9qYXZhL3NlbmRmaWxlLmphdmEgYi9kZW1vL3NyYy9tYWluL2phdmEvc2VuZGZpbGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZjQ0NTQ0Ci0tLSAvZGV2L251bGwKKysrIGIvZGVtby9zcmMvbWFpbi9qYXZhL3NlbmRmaWxlLmphdmEKQEAgLTAsMCArMSwxMjEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTYsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorICovCisKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YXgubWFpbC4qOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuKjsKK2ltcG9ydCBqYXZheC5hY3RpdmF0aW9uLio7CisKKy8qKgorICogc2VuZGZpbGUgd2lsbCBjcmVhdGUgYSBtdWx0aXBhcnQgbWVzc2FnZSB3aXRoIHRoZSBzZWNvbmQKKyAqIGJsb2NrIG9mIHRoZSBtZXNzYWdlIGJlaW5nIHRoZSBnaXZlbiBmaWxlLjxwPgorICoKKyAqIFRoaXMgZGVtb25zdHJhdGVzIGhvdyB0byB1c2UgdGhlIEZpbGVEYXRhU291cmNlIHRvIHNlbmQKKyAqIGEgZmlsZSB2aWEgbWFpbC48cD4KKyAqCisgKiB1c2FnZTogPGNvZGU+amF2YSBzZW5kZmlsZSA8aT50byBmcm9tIHNtdHAgZmlsZSB0cnVlfGZhbHNlPC9pPjwvY29kZT4KKyAqIHdoZXJlIDxpPnRvPC9pPiBhbmQgPGk+ZnJvbTwvaT4gYXJlIHRoZSBkZXN0aW5hdGlvbiBhbmQKKyAqIG9yaWdpbiBlbWFpbCBhZGRyZXNzZXMsIHJlc3BlY3RpdmVseSwgYW5kIDxpPnNtdHA8L2k+CisgKiBpcyB0aGUgaG9zdG5hbWUgb2YgdGhlIG1hY2hpbmUgdGhhdCBoYXMgc210cCBzZXJ2ZXIKKyAqIHJ1bm5pbmcuICA8aT5maWxlPC9pPiBpcyB0aGUgZmlsZSB0byBzZW5kLiBUaGUgbmV4dCBwYXJhbWV0ZXIKKyAqIGVpdGhlciB0dXJucyBvbiBvciB0dXJucyBvZmYgZGVidWdnaW5nIGR1cmluZyBzZW5kaW5nLgorICoKKyAqIEBhdXRob3IJQ2hyaXN0b3BoZXIgQ290dG9uCisgKi8KK3B1YmxpYyBjbGFzcyBzZW5kZmlsZSB7CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7CisJaWYgKGFyZ3MubGVuZ3RoICE9IDUpIHsKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJ1c2FnZTogamF2YSBzZW5kZmlsZSA8dG8+IDxmcm9tPiA8c210cD4gPGZpbGU+IHRydWV8ZmFsc2UiKTsKKwkgICAgU3lzdGVtLmV4aXQoMSk7CisJfQorCisJU3RyaW5nIHRvID0gYXJnc1swXTsKKwlTdHJpbmcgZnJvbSA9IGFyZ3NbMV07CisJU3RyaW5nIGhvc3QgPSBhcmdzWzJdOworCVN0cmluZyBmaWxlbmFtZSA9IGFyZ3NbM107CisJYm9vbGVhbiBkZWJ1ZyA9IEJvb2xlYW4udmFsdWVPZihhcmdzWzRdKS5ib29sZWFuVmFsdWUoKTsKKwlTdHJpbmcgbXNnVGV4dDEgPSAiU2VuZGluZyBhIGZpbGUuXG4iOworCVN0cmluZyBzdWJqZWN0ID0gIlNlbmRpbmcgYSBmaWxlIjsKKwkKKwkvLyBjcmVhdGUgc29tZSBwcm9wZXJ0aWVzIGFuZCBnZXQgdGhlIGRlZmF1bHQgU2Vzc2lvbgorCVByb3BlcnRpZXMgcHJvcHMgPSBTeXN0ZW0uZ2V0UHJvcGVydGllcygpOworCXByb3BzLnB1dCgibWFpbC5zbXRwLmhvc3QiLCBob3N0KTsKKwkKKwlTZXNzaW9uIHNlc3Npb24gPSBTZXNzaW9uLmdldEluc3RhbmNlKHByb3BzLCBudWxsKTsKKwlzZXNzaW9uLnNldERlYnVnKGRlYnVnKTsKKwkKKwl0cnkgeworCSAgICAvLyBjcmVhdGUgYSBtZXNzYWdlCisJICAgIE1pbWVNZXNzYWdlIG1zZyA9IG5ldyBNaW1lTWVzc2FnZShzZXNzaW9uKTsKKwkgICAgbXNnLnNldEZyb20obmV3IEludGVybmV0QWRkcmVzcyhmcm9tKSk7CisJICAgIEludGVybmV0QWRkcmVzc1tdIGFkZHJlc3MgPSB7bmV3IEludGVybmV0QWRkcmVzcyh0byl9OworCSAgICBtc2cuc2V0UmVjaXBpZW50cyhNZXNzYWdlLlJlY2lwaWVudFR5cGUuVE8sIGFkZHJlc3MpOworCSAgICBtc2cuc2V0U3ViamVjdChzdWJqZWN0KTsKKworCSAgICAvLyBjcmVhdGUgYW5kIGZpbGwgdGhlIGZpcnN0IG1lc3NhZ2UgcGFydAorCSAgICBNaW1lQm9keVBhcnQgbWJwMSA9IG5ldyBNaW1lQm9keVBhcnQoKTsKKwkgICAgbWJwMS5zZXRUZXh0KG1zZ1RleHQxKTsKKworCSAgICAvLyBjcmVhdGUgdGhlIHNlY29uZCBtZXNzYWdlIHBhcnQKKwkgICAgTWltZUJvZHlQYXJ0IG1icDIgPSBuZXcgTWltZUJvZHlQYXJ0KCk7CisKKwkgICAgLy8gYXR0YWNoIHRoZSBmaWxlIHRvIHRoZSBtZXNzYWdlCisJICAgIG1icDIuYXR0YWNoRmlsZShmaWxlbmFtZSk7CisKKwkgICAgLyoKKwkgICAgICogVXNlIHRoZSBmb2xsb3dpbmcgYXBwcm9hY2ggaW5zdGVhZCBvZiB0aGUgYWJvdmUgbGluZSBpZgorCSAgICAgKiB5b3Ugd2FudCB0byBjb250cm9sIHRoZSBNSU1FIHR5cGUgb2YgdGhlIGF0dGFjaGVkIGZpbGUuCisJICAgICAqIE5vcm1hbGx5IHlvdSBzaG91bGQgbmV2ZXIgbmVlZCB0byBkbyB0aGlzLgorCSAgICAgKgorCSAgICBGaWxlRGF0YVNvdXJjZSBmZHMgPSBuZXcgRmlsZURhdGFTb3VyY2UoZmlsZW5hbWUpIHsKKwkJcHVibGljIFN0cmluZyBnZXRDb250ZW50VHlwZSgpIHsKKwkJICAgIHJldHVybiAiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIjsKKwkJfQorCSAgICB9OworCSAgICBtYnAyLnNldERhdGFIYW5kbGVyKG5ldyBEYXRhSGFuZGxlcihmZHMpKTsKKwkgICAgbWJwMi5zZXRGaWxlTmFtZShmZHMuZ2V0TmFtZSgpKTsKKwkgICAgICovCisKKwkgICAgLy8gY3JlYXRlIHRoZSBNdWx0aXBhcnQgYW5kIGFkZCBpdHMgcGFydHMgdG8gaXQKKwkgICAgTXVsdGlwYXJ0IG1wID0gbmV3IE1pbWVNdWx0aXBhcnQoKTsKKwkgICAgbXAuYWRkQm9keVBhcnQobWJwMSk7CisJICAgIG1wLmFkZEJvZHlQYXJ0KG1icDIpOworCisJICAgIC8vIGFkZCB0aGUgTXVsdGlwYXJ0IHRvIHRoZSBtZXNzYWdlCisJICAgIG1zZy5zZXRDb250ZW50KG1wKTsKKworCSAgICAvLyBzZXQgdGhlIERhdGU6IGhlYWRlcgorCSAgICBtc2cuc2V0U2VudERhdGUobmV3IERhdGUoKSk7CisKKwkgICAgLyoKKwkgICAgICogSWYgeW91IHdhbnQgdG8gY29udHJvbCB0aGUgQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZworCSAgICAgKiBvZiB0aGUgYXR0YWNoZWQgZmlsZSwgZG8gdGhlIGZvbGxvd2luZy4gIE5vcm1hbGx5IHlvdQorCSAgICAgKiBzaG91bGQgbmV2ZXIgbmVlZCB0byBkbyB0aGlzLgorCSAgICAgKgorCSAgICBtc2cuc2F2ZUNoYW5nZXMoKTsKKwkgICAgbWJwMi5zZXRIZWFkZXIoIkNvbnRlbnQtVHJhbnNmZXItRW5jb2RpbmciLCAiYmFzZTY0Iik7CisJICAgICAqLworCisJICAgIC8vIHNlbmQgdGhlIG1lc3NhZ2UKKwkgICAgVHJhbnNwb3J0LnNlbmQobXNnKTsKKwkgICAgCisJfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIG1leCkgeworCSAgICBtZXgucHJpbnRTdGFja1RyYWNlKCk7CisJICAgIEV4Y2VwdGlvbiBleCA9IG51bGw7CisJICAgIGlmICgoZXggPSBtZXguZ2V0TmV4dEV4Y2VwdGlvbigpKSAhPSBudWxsKSB7CisJCWV4LnByaW50U3RhY2tUcmFjZSgpOworCSAgICB9CisJfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9leCkgeworCSAgICBpb2V4LnByaW50U3RhY2tUcmFjZSgpOworCX0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9kZW1vL3NyYy9tYWluL2phdmEvc2VuZGh0bWwuamF2YSBiL2RlbW8vc3JjL21haW4vamF2YS9zZW5kaHRtbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVjNjQxMGMKLS0tIC9kZXYvbnVsbAorKysgYi9kZW1vL3NyYy9tYWluL2phdmEvc2VuZGh0bWwuamF2YQpAQCAtMCwwICsxLDIxNiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5OCwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgRGlzdHJpYnV0aW9uIExpY2Vuc2Ugdi4gMS4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvb3JnL2RvY3VtZW50cy9lZGwtdjEwLnBocC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQlNELTMtQ2xhdXNlCisgKi8KKworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKK2ltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKKworaW1wb3J0IGphdmF4Lm1haWwuKjsKK2ltcG9ydCBqYXZheC5hY3RpdmF0aW9uLio7CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC4qOworaW1wb3J0IGphdmF4Lm1haWwudXRpbC4qOworCisvKioKKyAqIERlbW8gYXBwIHRoYXQgc2hvd3MgaG93IHRvIGNvbnN0cnVjdCBhbmQgc2VuZCBhIHNpbmdsZSBwYXJ0IGh0bWwKKyAqIG1lc3NhZ2UuICBOb3RlIHRoYXQgdGhlIHNhbWUgYmFzaWMgdGVjaG5pcXVlIGNhbiBiZSB1c2VkIHRvIHNlbmQKKyAqIGRhdGEgb2YgYW55IHR5cGUuCisgKgorICogQGF1dGhvciBKb2huIE1hbmkKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKiBAYXV0aG9yIE1heCBTcGl2YWsKKyAqLworCitwdWJsaWMgY2xhc3Mgc2VuZGh0bWwgeworCisgICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJndikgeworCW5ldyBzZW5kaHRtbChhcmd2KTsKKyAgICB9CisKKyAgICBwdWJsaWMgc2VuZGh0bWwoU3RyaW5nW10gYXJndikgeworCisJU3RyaW5nICB0bywgc3ViamVjdCA9IG51bGwsIGZyb20gPSBudWxsLCAKKwkJY2MgPSBudWxsLCBiY2MgPSBudWxsLCB1cmwgPSBudWxsOworCVN0cmluZyBtYWlsaG9zdCA9IG51bGw7CisJU3RyaW5nIG1haWxlciA9ICJzZW5kaHRtbCI7CisJU3RyaW5nIHByb3RvY29sID0gbnVsbCwgaG9zdCA9IG51bGwsIHVzZXIgPSBudWxsLCBwYXNzd29yZCA9IG51bGw7CisJU3RyaW5nIHJlY29yZCA9IG51bGw7CS8vIG5hbWUgb2YgZm9sZGVyIGluIHdoaWNoIHRvIHJlY29yZCBtYWlsCisJYm9vbGVhbiBkZWJ1ZyA9IGZhbHNlOworCUJ1ZmZlcmVkUmVhZGVyIGluID0KKwkJCW5ldyBCdWZmZXJlZFJlYWRlcihuZXcgSW5wdXRTdHJlYW1SZWFkZXIoU3lzdGVtLmluKSk7CisJaW50IG9wdGluZDsKKworCWZvciAob3B0aW5kID0gMDsgb3B0aW5kIDwgYXJndi5sZW5ndGg7IG9wdGluZCsrKSB7CisJICAgIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItVCIpKSB7CisJCXByb3RvY29sID0gYXJndlsrK29wdGluZF07CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLUgiKSkgeworCQlob3N0ID0gYXJndlsrK29wdGluZF07CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLVUiKSkgeworCQl1c2VyID0gYXJndlsrK29wdGluZF07CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLVAiKSkgeworCQlwYXNzd29yZCA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1NIikpIHsKKwkJbWFpbGhvc3QgPSBhcmd2Wysrb3B0aW5kXTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItZiIpKSB7CisJCXJlY29yZCA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1zIikpIHsKKwkJc3ViamVjdCA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1vIikpIHsgLy8gb3JpZ2luYXRvcgorCQlmcm9tID0gYXJndlsrK29wdGluZF07CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLWMiKSkgeworCQljYyA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1iIikpIHsKKwkJYmNjID0gYXJndlsrK29wdGluZF07CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLUwiKSkgeworCQl1cmwgPSBhcmd2Wysrb3B0aW5kXTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItZCIpKSB7CisJCWRlYnVnID0gdHJ1ZTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItLSIpKSB7CisJCW9wdGluZCsrOworCQlicmVhazsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uc3RhcnRzV2l0aCgiLSIpKSB7CisJCVN5c3RlbS5vdXQucHJpbnRsbigKKyJVc2FnZTogc2VuZGh0bWwgW1stTCBzdG9yZS11cmxdIHwgWy1UIHByb3RdIFstSCBob3N0XSBbLVUgdXNlcl0gWy1QIHBhc3N3ZF1dIik7CisJCVN5c3RlbS5vdXQucHJpbnRsbigKKyJcdFstcyBzdWJqZWN0XSBbLW8gZnJvbS1hZGRyZXNzXSBbLWMgY2MtYWRkcmVzc2VzXSBbLWIgYmNjLWFkZHJlc3Nlc10iKTsKKwkJU3lzdGVtLm91dC5wcmludGxuKAorIlx0Wy1mIHJlY29yZC1tYWlsYm94XSBbLU0gdHJhbnNwb3J0LWhvc3RdIFstZF0gW2FkZHJlc3NdIik7CisJCVN5c3RlbS5leGl0KDEpOworCSAgICB9IGVsc2UgeworCQlicmVhazsKKwkgICAgfQorCX0KKworCXRyeSB7CisJICAgIGlmIChvcHRpbmQgPCBhcmd2Lmxlbmd0aCkgeworCQkvLyBYWFggLSBjb25jYXRlbmF0ZSBhbGwgcmVtYWluaW5nIGFyZ3VtZW50cworCQl0byA9IGFyZ3Zbb3B0aW5kXTsKKwkJU3lzdGVtLm91dC5wcmludGxuKCJUbzogIiArIHRvKTsKKwkgICAgfSBlbHNlIHsKKwkJU3lzdGVtLm91dC5wcmludCgiVG86ICIpOworCQlTeXN0ZW0ub3V0LmZsdXNoKCk7CisJCXRvID0gaW4ucmVhZExpbmUoKTsKKwkgICAgfQorCSAgICBpZiAoc3ViamVjdCA9PSBudWxsKSB7CisJCVN5c3RlbS5vdXQucHJpbnQoIlN1YmplY3Q6ICIpOworCQlTeXN0ZW0ub3V0LmZsdXNoKCk7CisJCXN1YmplY3QgPSBpbi5yZWFkTGluZSgpOworCSAgICB9IGVsc2UgeworCQlTeXN0ZW0ub3V0LnByaW50bG4oIlN1YmplY3Q6ICIgKyBzdWJqZWN0KTsKKwkgICAgfQorCisJICAgIFByb3BlcnRpZXMgcHJvcHMgPSBTeXN0ZW0uZ2V0UHJvcGVydGllcygpOworCSAgICAvLyBYWFggLSBjb3VsZCB1c2UgU2Vzc2lvbi5nZXRUcmFuc3BvcnQoKSBhbmQgVHJhbnNwb3J0LmNvbm5lY3QoKQorCSAgICAvLyBYWFggLSBhc3N1bWUgd2UncmUgdXNpbmcgU01UUAorCSAgICBpZiAobWFpbGhvc3QgIT0gbnVsbCkKKwkJcHJvcHMucHV0KCJtYWlsLnNtdHAuaG9zdCIsIG1haWxob3N0KTsKKworCSAgICAvLyBHZXQgYSBTZXNzaW9uIG9iamVjdAorCSAgICBTZXNzaW9uIHNlc3Npb24gPSBTZXNzaW9uLmdldEluc3RhbmNlKHByb3BzLCBudWxsKTsKKwkgICAgaWYgKGRlYnVnKQorCQlzZXNzaW9uLnNldERlYnVnKHRydWUpOworCisJICAgIC8vIGNvbnN0cnVjdCB0aGUgbWVzc2FnZQorCSAgICBNZXNzYWdlIG1zZyA9IG5ldyBNaW1lTWVzc2FnZShzZXNzaW9uKTsKKwkgICAgaWYgKGZyb20gIT0gbnVsbCkKKwkJbXNnLnNldEZyb20obmV3IEludGVybmV0QWRkcmVzcyhmcm9tKSk7CisJICAgIGVsc2UKKwkJbXNnLnNldEZyb20oKTsKKworCSAgICBtc2cuc2V0UmVjaXBpZW50cyhNZXNzYWdlLlJlY2lwaWVudFR5cGUuVE8sCisJCQkJCUludGVybmV0QWRkcmVzcy5wYXJzZSh0bywgZmFsc2UpKTsKKwkgICAgaWYgKGNjICE9IG51bGwpCisJCW1zZy5zZXRSZWNpcGllbnRzKE1lc3NhZ2UuUmVjaXBpZW50VHlwZS5DQywKKwkJCQkJSW50ZXJuZXRBZGRyZXNzLnBhcnNlKGNjLCBmYWxzZSkpOworCSAgICBpZiAoYmNjICE9IG51bGwpCisJCW1zZy5zZXRSZWNpcGllbnRzKE1lc3NhZ2UuUmVjaXBpZW50VHlwZS5CQ0MsCisJCQkJCUludGVybmV0QWRkcmVzcy5wYXJzZShiY2MsIGZhbHNlKSk7CisKKwkgICAgbXNnLnNldFN1YmplY3Qoc3ViamVjdCk7CisKKwkgICAgY29sbGVjdChpbiwgbXNnKTsKKworCSAgICBtc2cuc2V0SGVhZGVyKCJYLU1haWxlciIsIG1haWxlcik7CisJICAgIG1zZy5zZXRTZW50RGF0ZShuZXcgRGF0ZSgpKTsKKworCSAgICAvLyBzZW5kIHRoZSB0aGluZyBvZmYKKwkgICAgVHJhbnNwb3J0LnNlbmQobXNnKTsKKworCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlxuTWFpbCB3YXMgc2VudCBzdWNjZXNzZnVsbHkuIik7CisKKwkgICAgLy8gS2VlcCBhIGNvcHksIGlmIHJlcXVlc3RlZC4KKworCSAgICBpZiAocmVjb3JkICE9IG51bGwpIHsKKwkJLy8gR2V0IGEgU3RvcmUgb2JqZWN0CisJCVN0b3JlIHN0b3JlID0gbnVsbDsKKwkJaWYgKHVybCAhPSBudWxsKSB7CisJCSAgICBVUkxOYW1lIHVybG4gPSBuZXcgVVJMTmFtZSh1cmwpOworCQkgICAgc3RvcmUgPSBzZXNzaW9uLmdldFN0b3JlKHVybG4pOworCQkgICAgc3RvcmUuY29ubmVjdCgpOworCQl9IGVsc2UgeworCQkgICAgaWYgKHByb3RvY29sICE9IG51bGwpCQkKKwkJCXN0b3JlID0gc2Vzc2lvbi5nZXRTdG9yZShwcm90b2NvbCk7CisJCSAgICBlbHNlCisJCQlzdG9yZSA9IHNlc3Npb24uZ2V0U3RvcmUoKTsKKworCQkgICAgLy8gQ29ubmVjdAorCQkgICAgaWYgKGhvc3QgIT0gbnVsbCB8fCB1c2VyICE9IG51bGwgfHwgcGFzc3dvcmQgIT0gbnVsbCkKKwkJCXN0b3JlLmNvbm5lY3QoaG9zdCwgdXNlciwgcGFzc3dvcmQpOworCQkgICAgZWxzZQorCQkJc3RvcmUuY29ubmVjdCgpOworCQl9CisKKwkJLy8gR2V0IHJlY29yZCBGb2xkZXIuICBDcmVhdGUgaWYgaXQgZG9lcyBub3QgZXhpc3QuCisJCUZvbGRlciBmb2xkZXIgPSBzdG9yZS5nZXRGb2xkZXIocmVjb3JkKTsKKwkJaWYgKGZvbGRlciA9PSBudWxsKSB7CisJCSAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkNhbid0IGdldCByZWNvcmQgZm9sZGVyLiIpOworCQkgICAgU3lzdGVtLmV4aXQoMSk7CisJCX0KKwkJaWYgKCFmb2xkZXIuZXhpc3RzKCkpCisJCSAgICBmb2xkZXIuY3JlYXRlKEZvbGRlci5IT0xEU19NRVNTQUdFUyk7CisKKwkJTWVzc2FnZVtdIG1zZ3MgPSBuZXcgTWVzc2FnZVsxXTsKKwkJbXNnc1swXSA9IG1zZzsKKwkJZm9sZGVyLmFwcGVuZE1lc3NhZ2VzKG1zZ3MpOworCisJCVN5c3RlbS5vdXQucHJpbnRsbigiTWFpbCB3YXMgcmVjb3JkZWQgc3VjY2Vzc2Z1bGx5LiIpOworCSAgICB9CisKKwl9IGNhdGNoIChFeGNlcHRpb24gZSkgeworCSAgICBlLnByaW50U3RhY2tUcmFjZSgpOworCX0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBjb2xsZWN0KEJ1ZmZlcmVkUmVhZGVyIGluLCBNZXNzYWdlIG1zZykKKwkJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworCVN0cmluZyBsaW5lOworCVN0cmluZyBzdWJqZWN0ID0gbXNnLmdldFN1YmplY3QoKTsKKwlTdHJpbmdCdWZmZXIgc2IgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CisJc2IuYXBwZW5kKCI8SFRNTD5cbiIpOworCXNiLmFwcGVuZCgiPEhFQUQ+XG4iKTsKKwlzYi5hcHBlbmQoIjxUSVRMRT5cbiIpOworCXNiLmFwcGVuZChzdWJqZWN0ICsgIlxuIik7CisJc2IuYXBwZW5kKCI8L1RJVExFPlxuIik7CisJc2IuYXBwZW5kKCI8L0hFQUQ+XG4iKTsKKworCXNiLmFwcGVuZCgiPEJPRFk+XG4iKTsKKwlzYi5hcHBlbmQoIjxIMT4iICsgc3ViamVjdCArICI8L0gxPiIgKyAiXG4iKTsKKworCXdoaWxlICgobGluZSA9IGluLnJlYWRMaW5lKCkpICE9IG51bGwpIHsKKwkgICAgc2IuYXBwZW5kKGxpbmUpOworCSAgICBzYi5hcHBlbmQoIlxuIik7CisJfQorCisJc2IuYXBwZW5kKCI8L0JPRFk+XG4iKTsKKwlzYi5hcHBlbmQoIjwvSFRNTD5cbiIpOworCisJbXNnLnNldERhdGFIYW5kbGVyKG5ldyBEYXRhSGFuZGxlcigKKwkJbmV3IEJ5dGVBcnJheURhdGFTb3VyY2Uoc2IudG9TdHJpbmcoKSwgInRleHQvaHRtbCIpKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvZGVtby9zcmMvbWFpbi9qYXZhL3NtdHBzZW5kLmphdmEgYi9kZW1vL3NyYy9tYWluL2phdmEvc210cHNlbmQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZTI2ZWI1Ci0tLSAvZGV2L251bGwKKysrIGIvZGVtby9zcmMvbWFpbi9qYXZhL3NtdHBzZW5kLmphdmEKQEAgLTAsMCArMSwzNTAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorICovCisKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YS5uZXQuSW5ldEFkZHJlc3M7CitpbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CisKK2ltcG9ydCBqYXZheC5tYWlsLio7CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC4qOworCitpbXBvcnQgY29tLnN1bi5tYWlsLnNtdHAuKjsKKworLyoqCisgKiBEZW1vIGFwcCB0aGF0IHNob3dzIGhvdyB0byBjb25zdHJ1Y3QgYW5kIHNlbmQgYW4gUkZDODIyCisgKiAoc2luZ2xlcGFydCkgbWVzc2FnZS4KKyAqCisgKiBYWFggLSBhbGxvdyBtb3JlIHRoYW4gb25lIHJlY2lwaWVudCBvbiB0aGUgY29tbWFuZCBsaW5lCisgKgorICogVGhpcyBpcyBqdXN0IGEgdmFyaWFudCBvZiBtc2dzZW5kLmphdmEgdGhhdCBkZW1vbnN0cmF0ZXMgdXNlIG9mCisgKiBzb21lIFNNVFAtc3BlY2lmaWMgZmVhdHVyZXMuCisgKgorICogQGF1dGhvciBNYXggU3BpdmFrCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCisKK3B1YmxpYyBjbGFzcyBzbXRwc2VuZCB7CisKKyAgICAvKioKKyAgICAgKiBFeGFtcGxlIG9mIGhvdyB0byBleHRlbmQgdGhlIFNNVFBUcmFuc3BvcnQgY2xhc3MuCisgICAgICogVGhpcyBleGFtcGxlIGlsbHVzdHJhdGVzIGhvdyB0byBpc3N1ZSB0aGUgWEFDVAorICAgICAqIGNvbW1hbmQgYmVmb3JlIHRoZSBTTVRQVHJhbnNwb3J0IGlzc3VlcyB0aGUgREFUQQorICAgICAqIGNvbW1hbmQuCisgICAgICoKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFNNVFBFeHRlbnNpb24gZXh0ZW5kcyBTTVRQVHJhbnNwb3J0IHsKKwlwdWJsaWMgU01UUEV4dGVuc2lvbihTZXNzaW9uIHNlc3Npb24sIFVSTE5hbWUgdXJsKSB7CisJICAgIHN1cGVyKHNlc3Npb24sIHVybCk7CisJICAgIC8vIHRvIGNoZWNrIHRoYXQgd2UncmUgYmVpbmcgdXNlZAorCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlNNVFBFeHRlbnNpb246IGNvbnN0cnVjdGVkIik7CisJfQorCisJcHJvdGVjdGVkIHN5bmNocm9uaXplZCBPdXRwdXRTdHJlYW0gZGF0YSgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCSAgICBpZiAoc3VwcG9ydHNFeHRlbnNpb24oIlhBQ0NPVU5USU5HIikpCisJCWlzc3VlQ29tbWFuZCgiWEFDVCIsIDI1MCk7CisJICAgIHJldHVybiBzdXBlci5kYXRhKCk7CisJfQorICAgIH0KKyAgICAgKi8KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3YpIHsKKwlTdHJpbmcgIHRvLCBzdWJqZWN0ID0gbnVsbCwgZnJvbSA9IG51bGwsIAorCQljYyA9IG51bGwsIGJjYyA9IG51bGwsIHVybCA9IG51bGw7CisJU3RyaW5nIG1haWxob3N0ID0gbnVsbDsKKwlTdHJpbmcgbWFpbGVyID0gInNtdHBzZW5kIjsKKwlTdHJpbmcgZmlsZSA9IG51bGw7CisJU3RyaW5nIHByb3RvY29sID0gbnVsbCwgaG9zdCA9IG51bGwsIHVzZXIgPSBudWxsLCBwYXNzd29yZCA9IG51bGw7CisJU3RyaW5nIHJlY29yZCA9IG51bGw7CS8vIG5hbWUgb2YgZm9sZGVyIGluIHdoaWNoIHRvIHJlY29yZCBtYWlsCisJYm9vbGVhbiBkZWJ1ZyA9IGZhbHNlOworCWJvb2xlYW4gdmVyYm9zZSA9IGZhbHNlOworCWJvb2xlYW4gYXV0aCA9IGZhbHNlOworCVN0cmluZyBwcm90ID0gInNtdHAiOworCUJ1ZmZlcmVkUmVhZGVyIGluID0KKwkJCW5ldyBCdWZmZXJlZFJlYWRlcihuZXcgSW5wdXRTdHJlYW1SZWFkZXIoU3lzdGVtLmluKSk7CisJaW50IG9wdGluZDsKKworCS8qCisJICogUHJvY2VzcyBjb21tYW5kIGxpbmUgYXJndW1lbnRzLgorCSAqLworCWZvciAob3B0aW5kID0gMDsgb3B0aW5kIDwgYXJndi5sZW5ndGg7IG9wdGluZCsrKSB7CisJICAgIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItVCIpKSB7CisJCXByb3RvY29sID0gYXJndlsrK29wdGluZF07CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLUgiKSkgeworCQlob3N0ID0gYXJndlsrK29wdGluZF07CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLVUiKSkgeworCQl1c2VyID0gYXJndlsrK29wdGluZF07CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLVAiKSkgeworCQlwYXNzd29yZCA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1NIikpIHsKKwkJbWFpbGhvc3QgPSBhcmd2Wysrb3B0aW5kXTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItZiIpKSB7CisJCXJlY29yZCA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1hIikpIHsKKwkJZmlsZSA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1zIikpIHsKKwkJc3ViamVjdCA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1vIikpIHsgLy8gb3JpZ2luYXRvcgorCQlmcm9tID0gYXJndlsrK29wdGluZF07CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLWMiKSkgeworCQljYyA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1iIikpIHsKKwkJYmNjID0gYXJndlsrK29wdGluZF07CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLUwiKSkgeworCQl1cmwgPSBhcmd2Wysrb3B0aW5kXTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItZCIpKSB7CisJCWRlYnVnID0gdHJ1ZTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItdiIpKSB7CisJCXZlcmJvc2UgPSB0cnVlOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1BIikpIHsKKwkJYXV0aCA9IHRydWU7CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLVMiKSkgeworCQlwcm90ID0gInNtdHBzIjsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItLSIpKSB7CisJCW9wdGluZCsrOworCQlicmVhazsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uc3RhcnRzV2l0aCgiLSIpKSB7CisJCVN5c3RlbS5vdXQucHJpbnRsbigKKyJVc2FnZTogc210cHNlbmQgW1stTCBzdG9yZS11cmxdIHwgWy1UIHByb3RdIFstSCBob3N0XSBbLVUgdXNlcl0gWy1QIHBhc3N3ZF1dIik7CisJCVN5c3RlbS5vdXQucHJpbnRsbigKKyJcdFstcyBzdWJqZWN0XSBbLW8gZnJvbS1hZGRyZXNzXSBbLWMgY2MtYWRkcmVzc2VzXSBbLWIgYmNjLWFkZHJlc3Nlc10iKTsKKwkJU3lzdGVtLm91dC5wcmludGxuKAorIlx0Wy1mIHJlY29yZC1tYWlsYm94XSBbLU0gdHJhbnNwb3J0LWhvc3RdIFstZF0gWy1hIGF0dGFjaC1maWxlXSIpOworCQlTeXN0ZW0ub3V0LnByaW50bG4oCisiXHRbLXZdIFstQV0gWy1TXSBbYWRkcmVzc10iKTsKKwkJU3lzdGVtLmV4aXQoMSk7CisJICAgIH0gZWxzZSB7CisJCWJyZWFrOworCSAgICB9CisJfQorCisJdHJ5IHsKKwkgICAgLyoKKwkgICAgICogUHJvbXB0IGZvciBUbyBhbmQgU3ViamVjdCwgaWYgbm90IHNwZWNpZmllZC4KKwkgICAgICovCisJICAgIGlmIChvcHRpbmQgPCBhcmd2Lmxlbmd0aCkgeworCQkvLyBYWFggLSBjb25jYXRlbmF0ZSBhbGwgcmVtYWluaW5nIGFyZ3VtZW50cworCQl0byA9IGFyZ3Zbb3B0aW5kXTsKKwkJU3lzdGVtLm91dC5wcmludGxuKCJUbzogIiArIHRvKTsKKwkgICAgfSBlbHNlIHsKKwkJU3lzdGVtLm91dC5wcmludCgiVG86ICIpOworCQlTeXN0ZW0ub3V0LmZsdXNoKCk7CisJCXRvID0gaW4ucmVhZExpbmUoKTsKKwkgICAgfQorCSAgICBpZiAoc3ViamVjdCA9PSBudWxsKSB7CisJCVN5c3RlbS5vdXQucHJpbnQoIlN1YmplY3Q6ICIpOworCQlTeXN0ZW0ub3V0LmZsdXNoKCk7CisJCXN1YmplY3QgPSBpbi5yZWFkTGluZSgpOworCSAgICB9IGVsc2UgeworCQlTeXN0ZW0ub3V0LnByaW50bG4oIlN1YmplY3Q6ICIgKyBzdWJqZWN0KTsKKwkgICAgfQorCisJICAgIC8qCisJICAgICAqIEluaXRpYWxpemUgdGhlIEphdmFNYWlsIFNlc3Npb24uCisJICAgICAqLworCSAgICBQcm9wZXJ0aWVzIHByb3BzID0gU3lzdGVtLmdldFByb3BlcnRpZXMoKTsKKwkgICAgaWYgKG1haWxob3N0ICE9IG51bGwpCisJCXByb3BzLnB1dCgibWFpbC4iICsgcHJvdCArICIuaG9zdCIsIG1haWxob3N0KTsKKwkgICAgaWYgKGF1dGgpCisJCXByb3BzLnB1dCgibWFpbC4iICsgcHJvdCArICIuYXV0aCIsICJ0cnVlIik7CisKKwkgICAgLyoKKwkgICAgICogQ3JlYXRlIGEgUHJvdmlkZXIgcmVwcmVzZW50aW5nIG91ciBleHRlbmRlZCBTTVRQIHRyYW5zcG9ydAorCSAgICAgKiBhbmQgc2V0IHRoZSBwcm9wZXJ0eSB0byB1c2Ugb3VyIHByb3ZpZGVyLgorCSAgICAgKgorCSAgICBQcm92aWRlciBwID0gbmV3IFByb3ZpZGVyKFByb3ZpZGVyLlR5cGUuVFJBTlNQT1JULCBwcm90LAorCQkic210cHNlbmQkU01UUEV4dGVuc2lvbiIsICJKYXZhTWFpbCBkZW1vIiwgIm5vIHZlcnNpb24iKTsKKwkgICAgcHJvcHMucHV0KCJtYWlsLiIgKyBwcm90ICsgIi5jbGFzcyIsICJzbXRwc2VuZCRTTVRQRXh0ZW5zaW9uIik7CisJICAgICAqLworCisJICAgIC8vIEdldCBhIFNlc3Npb24gb2JqZWN0CisJICAgIFNlc3Npb24gc2Vzc2lvbiA9IFNlc3Npb24uZ2V0SW5zdGFuY2UocHJvcHMsIG51bGwpOworCSAgICBpZiAoZGVidWcpCisJCXNlc3Npb24uc2V0RGVidWcodHJ1ZSk7CisKKwkgICAgLyoKKwkgICAgICogUmVnaXN0ZXIgb3VyIGV4dGVuZGVkIFNNVFAgdHJhbnNwb3J0LgorCSAgICAgKgorCSAgICBzZXNzaW9uLmFkZFByb3ZpZGVyKHApOworCSAgICAgKi8KKworCSAgICAvKgorCSAgICAgKiBDb25zdHJ1Y3QgdGhlIG1lc3NhZ2UgYW5kIHNlbmQgaXQuCisJICAgICAqLworCSAgICBNZXNzYWdlIG1zZyA9IG5ldyBNaW1lTWVzc2FnZShzZXNzaW9uKTsKKwkgICAgaWYgKGZyb20gIT0gbnVsbCkKKwkJbXNnLnNldEZyb20obmV3IEludGVybmV0QWRkcmVzcyhmcm9tKSk7CisJICAgIGVsc2UKKwkJbXNnLnNldEZyb20oKTsKKworCSAgICBtc2cuc2V0UmVjaXBpZW50cyhNZXNzYWdlLlJlY2lwaWVudFR5cGUuVE8sCisJCQkJCUludGVybmV0QWRkcmVzcy5wYXJzZSh0bywgZmFsc2UpKTsKKwkgICAgaWYgKGNjICE9IG51bGwpCisJCW1zZy5zZXRSZWNpcGllbnRzKE1lc3NhZ2UuUmVjaXBpZW50VHlwZS5DQywKKwkJCQkJSW50ZXJuZXRBZGRyZXNzLnBhcnNlKGNjLCBmYWxzZSkpOworCSAgICBpZiAoYmNjICE9IG51bGwpCisJCW1zZy5zZXRSZWNpcGllbnRzKE1lc3NhZ2UuUmVjaXBpZW50VHlwZS5CQ0MsCisJCQkJCUludGVybmV0QWRkcmVzcy5wYXJzZShiY2MsIGZhbHNlKSk7CisKKwkgICAgbXNnLnNldFN1YmplY3Qoc3ViamVjdCk7CisKKwkgICAgU3RyaW5nIHRleHQgPSBjb2xsZWN0KGluKTsKKworCSAgICBpZiAoZmlsZSAhPSBudWxsKSB7CisJCS8vIEF0dGFjaCB0aGUgc3BlY2lmaWVkIGZpbGUuCisJCS8vIFdlIG5lZWQgYSBtdWx0aXBhcnQgbWVzc2FnZSB0byBob2xkIHRoZSBhdHRhY2htZW50LgorCQlNaW1lQm9keVBhcnQgbWJwMSA9IG5ldyBNaW1lQm9keVBhcnQoKTsKKwkJbWJwMS5zZXRUZXh0KHRleHQpOworCQlNaW1lQm9keVBhcnQgbWJwMiA9IG5ldyBNaW1lQm9keVBhcnQoKTsKKwkJbWJwMi5hdHRhY2hGaWxlKGZpbGUpOworCQlNaW1lTXVsdGlwYXJ0IG1wID0gbmV3IE1pbWVNdWx0aXBhcnQoKTsKKwkJbXAuYWRkQm9keVBhcnQobWJwMSk7CisJCW1wLmFkZEJvZHlQYXJ0KG1icDIpOworCQltc2cuc2V0Q29udGVudChtcCk7CisJICAgIH0gZWxzZSB7CisJCS8vIElmIHRoZSBkZXNpcmVkIGNoYXJzZXQgaXMga25vd24sIHlvdSBjYW4gdXNlCisJCS8vIHNldFRleHQodGV4dCwgY2hhcnNldCkKKwkJbXNnLnNldFRleHQodGV4dCk7CisJICAgIH0KKworCSAgICBtc2cuc2V0SGVhZGVyKCJYLU1haWxlciIsIG1haWxlcik7CisJICAgIG1zZy5zZXRTZW50RGF0ZShuZXcgRGF0ZSgpKTsKKworCSAgICAvLyBzZW5kIHRoZSB0aGluZyBvZmYKKwkgICAgLyoKKwkgICAgICogVGhlIHNpbXBsZSB3YXkgdG8gc2VuZCBhIG1lc3NhZ2UgaXMgdGhpczoKKwkgICAgICoKKwkgICAgVHJhbnNwb3J0LnNlbmQobXNnKTsKKwkgICAgICoKKwkgICAgICogQnV0IHdlJ3JlIGdvaW5nIHRvIHVzZSBzb21lIFNNVFAtc3BlY2lmaWMgZmVhdHVyZXMgZm9yCisJICAgICAqIGRlbW9uc3RyYXRpb24gcHVycG9zZXMgc28gd2UgbmVlZCB0byBtYW5hZ2UgdGhlIFRyYW5zcG9ydAorCSAgICAgKiBvYmplY3QgZXhwbGljaXRseS4KKwkgICAgICovCisJICAgIFNNVFBUcmFuc3BvcnQgdCA9CisJCShTTVRQVHJhbnNwb3J0KXNlc3Npb24uZ2V0VHJhbnNwb3J0KHByb3QpOworCSAgICB0cnkgeworCQlpZiAoYXV0aCkKKwkJICAgIHQuY29ubmVjdChtYWlsaG9zdCwgdXNlciwgcGFzc3dvcmQpOworCQllbHNlCisJCSAgICB0LmNvbm5lY3QoKTsKKwkJdC5zZW5kTWVzc2FnZShtc2csIG1zZy5nZXRBbGxSZWNpcGllbnRzKCkpOworCSAgICB9IGZpbmFsbHkgeworCQlpZiAodmVyYm9zZSkKKwkJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiUmVzcG9uc2U6ICIgKworCQkJCQkJdC5nZXRMYXN0U2VydmVyUmVzcG9uc2UoKSk7CisJCXQuY2xvc2UoKTsKKwkgICAgfQorCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXG5NYWlsIHdhcyBzZW50IHN1Y2Nlc3NmdWxseS4iKTsKKworCSAgICAvKgorCSAgICAgKiBTYXZlIGEgY29weSBvZiB0aGUgbWVzc2FnZSwgaWYgcmVxdWVzdGVkLgorCSAgICAgKi8KKwkgICAgaWYgKHJlY29yZCAhPSBudWxsKSB7CisJCS8vIEdldCBhIFN0b3JlIG9iamVjdAorCQlTdG9yZSBzdG9yZSA9IG51bGw7CisJCWlmICh1cmwgIT0gbnVsbCkgeworCQkgICAgVVJMTmFtZSB1cmxuID0gbmV3IFVSTE5hbWUodXJsKTsKKwkJICAgIHN0b3JlID0gc2Vzc2lvbi5nZXRTdG9yZSh1cmxuKTsKKwkJICAgIHN0b3JlLmNvbm5lY3QoKTsKKwkJfSBlbHNlIHsKKwkJICAgIGlmIChwcm90b2NvbCAhPSBudWxsKQkJCisJCQlzdG9yZSA9IHNlc3Npb24uZ2V0U3RvcmUocHJvdG9jb2wpOworCQkgICAgZWxzZQorCQkJc3RvcmUgPSBzZXNzaW9uLmdldFN0b3JlKCk7CisKKwkJICAgIC8vIENvbm5lY3QKKwkJICAgIGlmIChob3N0ICE9IG51bGwgfHwgdXNlciAhPSBudWxsIHx8IHBhc3N3b3JkICE9IG51bGwpCisJCQlzdG9yZS5jb25uZWN0KGhvc3QsIHVzZXIsIHBhc3N3b3JkKTsKKwkJICAgIGVsc2UKKwkJCXN0b3JlLmNvbm5lY3QoKTsKKwkJfQorCisJCS8vIEdldCByZWNvcmQgRm9sZGVyLiAgQ3JlYXRlIGlmIGl0IGRvZXMgbm90IGV4aXN0LgorCQlGb2xkZXIgZm9sZGVyID0gc3RvcmUuZ2V0Rm9sZGVyKHJlY29yZCk7CisJCWlmIChmb2xkZXIgPT0gbnVsbCkgeworCQkgICAgU3lzdGVtLmVyci5wcmludGxuKCJDYW4ndCBnZXQgcmVjb3JkIGZvbGRlci4iKTsKKwkJICAgIFN5c3RlbS5leGl0KDEpOworCQl9CisJCWlmICghZm9sZGVyLmV4aXN0cygpKQorCQkgICAgZm9sZGVyLmNyZWF0ZShGb2xkZXIuSE9MRFNfTUVTU0FHRVMpOworCisJCU1lc3NhZ2VbXSBtc2dzID0gbmV3IE1lc3NhZ2VbMV07CisJCW1zZ3NbMF0gPSBtc2c7CisJCWZvbGRlci5hcHBlbmRNZXNzYWdlcyhtc2dzKTsKKworCQlTeXN0ZW0ub3V0LnByaW50bG4oIk1haWwgd2FzIHJlY29yZGVkIHN1Y2Nlc3NmdWxseS4iKTsKKwkgICAgfQorCisJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKwkgICAgLyoKKwkgICAgICogSGFuZGxlIFNNVFAtc3BlY2lmaWMgZXhjZXB0aW9ucy4KKwkgICAgICovCisJICAgIGlmIChlIGluc3RhbmNlb2YgU2VuZEZhaWxlZEV4Y2VwdGlvbikgeworCQlNZXNzYWdpbmdFeGNlcHRpb24gc2ZlID0gKE1lc3NhZ2luZ0V4Y2VwdGlvbillOworCQlpZiAoc2ZlIGluc3RhbmNlb2YgU01UUFNlbmRGYWlsZWRFeGNlcHRpb24pIHsKKwkJICAgIFNNVFBTZW5kRmFpbGVkRXhjZXB0aW9uIHNzZmUgPQorCQkJCSAgICAoU01UUFNlbmRGYWlsZWRFeGNlcHRpb24pc2ZlOworCQkgICAgU3lzdGVtLm91dC5wcmludGxuKCJTTVRQIFNFTkQgRkFJTEVEOiIpOworCQkgICAgaWYgKHZlcmJvc2UpCisJCQlTeXN0ZW0ub3V0LnByaW50bG4oc3NmZS50b1N0cmluZygpKTsKKwkJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiICBDb21tYW5kOiAiICsgc3NmZS5nZXRDb21tYW5kKCkpOworCQkgICAgU3lzdGVtLm91dC5wcmludGxuKCIgIFJldENvZGU6ICIgKyBzc2ZlLmdldFJldHVybkNvZGUoKSk7CisJCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiAgUmVzcG9uc2U6ICIgKyBzc2ZlLmdldE1lc3NhZ2UoKSk7CisJCX0gZWxzZSB7CisJCSAgICBpZiAodmVyYm9zZSkKKwkJCVN5c3RlbS5vdXQucHJpbnRsbigiU2VuZCBmYWlsZWQ6ICIgKyBzZmUudG9TdHJpbmcoKSk7CisJCX0KKwkJRXhjZXB0aW9uIG5lOworCQl3aGlsZSAoKG5lID0gc2ZlLmdldE5leHRFeGNlcHRpb24oKSkgIT0gbnVsbCAmJgorCQkJbmUgaW5zdGFuY2VvZiBNZXNzYWdpbmdFeGNlcHRpb24pIHsKKwkJICAgIHNmZSA9IChNZXNzYWdpbmdFeGNlcHRpb24pbmU7CisJCSAgICBpZiAoc2ZlIGluc3RhbmNlb2YgU01UUEFkZHJlc3NGYWlsZWRFeGNlcHRpb24pIHsKKwkJCVNNVFBBZGRyZXNzRmFpbGVkRXhjZXB0aW9uIHNzZmUgPQorCQkJCQkoU01UUEFkZHJlc3NGYWlsZWRFeGNlcHRpb24pc2ZlOworCQkJU3lzdGVtLm91dC5wcmludGxuKCJBRERSRVNTIEZBSUxFRDoiKTsKKwkJCWlmICh2ZXJib3NlKQorCQkJICAgIFN5c3RlbS5vdXQucHJpbnRsbihzc2ZlLnRvU3RyaW5nKCkpOworCQkJU3lzdGVtLm91dC5wcmludGxuKCIgIEFkZHJlc3M6ICIgKyBzc2ZlLmdldEFkZHJlc3MoKSk7CisJCQlTeXN0ZW0ub3V0LnByaW50bG4oIiAgQ29tbWFuZDogIiArIHNzZmUuZ2V0Q29tbWFuZCgpKTsKKwkJCVN5c3RlbS5vdXQucHJpbnRsbigiICBSZXRDb2RlOiAiICsgc3NmZS5nZXRSZXR1cm5Db2RlKCkpOworCQkJU3lzdGVtLm91dC5wcmludGxuKCIgIFJlc3BvbnNlOiAiICsgc3NmZS5nZXRNZXNzYWdlKCkpOworCQkgICAgfSBlbHNlIGlmIChzZmUgaW5zdGFuY2VvZiBTTVRQQWRkcmVzc1N1Y2NlZWRlZEV4Y2VwdGlvbikgeworCQkJU3lzdGVtLm91dC5wcmludGxuKCJBRERSRVNTIFNVQ0NFRURFRDoiKTsKKwkJCVNNVFBBZGRyZXNzU3VjY2VlZGVkRXhjZXB0aW9uIHNzZmUgPQorCQkJCQkoU01UUEFkZHJlc3NTdWNjZWVkZWRFeGNlcHRpb24pc2ZlOworCQkJaWYgKHZlcmJvc2UpCisJCQkgICAgU3lzdGVtLm91dC5wcmludGxuKHNzZmUudG9TdHJpbmcoKSk7CisJCQlTeXN0ZW0ub3V0LnByaW50bG4oIiAgQWRkcmVzczogIiArIHNzZmUuZ2V0QWRkcmVzcygpKTsKKwkJCVN5c3RlbS5vdXQucHJpbnRsbigiICBDb21tYW5kOiAiICsgc3NmZS5nZXRDb21tYW5kKCkpOworCQkJU3lzdGVtLm91dC5wcmludGxuKCIgIFJldENvZGU6ICIgKyBzc2ZlLmdldFJldHVybkNvZGUoKSk7CisJCQlTeXN0ZW0ub3V0LnByaW50bG4oIiAgUmVzcG9uc2U6ICIgKyBzc2ZlLmdldE1lc3NhZ2UoKSk7CisJCSAgICB9CisJCX0KKwkgICAgfSBlbHNlIHsKKwkJU3lzdGVtLm91dC5wcmludGxuKCJHb3QgRXhjZXB0aW9uOiAiICsgZSk7CisJCWlmICh2ZXJib3NlKQorCQkgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKwkgICAgfQorCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkIHRoZSBib2R5IG9mIHRoZSBtZXNzYWdlIHVudGlsIEVPRi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBjb2xsZWN0KEJ1ZmZlcmVkUmVhZGVyIGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworCVN0cmluZyBsaW5lOworCVN0cmluZ0J1ZmZlciBzYiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKwl3aGlsZSAoKGxpbmUgPSBpbi5yZWFkTGluZSgpKSAhPSBudWxsKSB7CisJICAgIHNiLmFwcGVuZChsaW5lKTsKKwkgICAgc2IuYXBwZW5kKCJcbiIpOworCX0KKwlyZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9kZW1vL3NyYy9tYWluL2phdmEvdHJhbnNwb3J0LmphdmEgYi9kZW1vL3NyYy9tYWluL2phdmEvdHJhbnNwb3J0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjNjZmJkNwotLS0gL2Rldi9udWxsCisrKyBiL2RlbW8vc3JjL21haW4vamF2YS90cmFuc3BvcnQuamF2YQpAQCAtMCwwICsxLDIxMiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgRGlzdHJpYnV0aW9uIExpY2Vuc2Ugdi4gMS4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvb3JnL2RvY3VtZW50cy9lZGwtdjEwLnBocC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQlNELTMtQ2xhdXNlCisgKi8KKworaW1wb3J0IGphdmEudXRpbC4qOworaW1wb3J0IGphdmF4Lm1haWwuKjsKK2ltcG9ydCBqYXZheC5tYWlsLmludGVybmV0Lio7CitpbXBvcnQgamF2YXgubWFpbC5ldmVudC4qOworaW1wb3J0IGphdmF4LmFjdGl2YXRpb24uKjsKKworLyoqCisgKiB0cmFuc3BvcnQgaXMgYSBzaW1wbGUgcHJvZ3JhbSB0aGF0IGNyZWF0ZXMgYSBtZXNzYWdlLCBleHBsaWNpdGx5CisgKiByZXRyaWV2ZXMgYSBUcmFuc3BvcnQgZnJvbSB0aGUgc2Vzc2lvbiBiYXNlZCBvbiB0aGUgdHlwZSBvZiB0aGUKKyAqIGFkZHJlc3MgKGl0J3MgSW50ZXJuZXRBZGRyZXNzLCBzbyBTTVRQIHdpbGwgYmUgdXNlZCkgYW5kIHNlbmRzIAorICogdGhlIG1lc3NhZ2UuCisgKgorICogdXNhZ2U6IDxjb2RlPmphdmEgdHJhbnNwb3J0IDxpPiJ0b2FkZHIxWywgdG9hZGRyMl0qIiAgZnJvbSBzbXRwaG9zdCAKKyAqIHRydWV8ZmFsc2U8L2k+PC9jb2RlPjxicj4KKyAqIHdoZXJlIDxpPnRvPC9pPiBhbmQgPGk+ZnJvbTwvaT4gYXJlIHRoZSBkZXN0aW5hdGlvbiBhbmQKKyAqIG9yaWdpbiBlbWFpbCBhZGRyZXNzZXMsIHJlc3BlY3RpdmVseSwgYW5kIDxpPnNtdHBob3N0PC9pPgorICogaXMgdGhlIGhvc3RuYW1lIG9mIHRoZSBtYWNoaW5lIHRoYXQgaGFzIHRoZSBzbXRwIHNlcnZlcgorICogcnVubmluZy4gVGhlIDxpPnRvPC9pPiBhZGRyZXNzZXMgY2FuIGJlIGVpdGhlciBhIHNpbmdsZSBlbWFpbAorICogYWRkcmVzcyBvciBhIGNvbW1hLXNlcGFyYXRlZCBsaXN0IG9mIGVtYWlsIGFkZHJlc3NlcyBpbgorICogcXVvdGVzLCBpLmUuICJqb2VAbWFjaGluZSwgamFuZSwgbWF4QHNlcnZlci5jb20iCisgKiBUaGUgbGFzdCBwYXJhbWV0ZXIgZWl0aGVyIHR1cm5zIG9uIG9yIHR1cm5zIG9mZgorICogZGVidWdnaW5nIGR1cmluZyBzZW5kaW5nLgorICoKKyAqIEBhdXRob3IgTWF4IFNwaXZhaworICovCitwdWJsaWMgY2xhc3MgdHJhbnNwb3J0IGltcGxlbWVudHMgQ29ubmVjdGlvbkxpc3RlbmVyLCBUcmFuc3BvcnRMaXN0ZW5lciB7CisgICAgc3RhdGljIFN0cmluZyBtc2dUZXh0ID0gIlRoaXMgaXMgYSBtZXNzYWdlIGJvZHkuXG5IZXJlJ3MgdGhlIHNlY29uZCBsaW5lLiI7CisgICAgc3RhdGljIFN0cmluZyBtc2dUZXh0MiA9ICJcblRoaXMgd2FzIHNlbnQgYnkgdHJhbnNwb3J0LmphdmEgZGVtbyBwcm9ncmFtLiI7CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7CisJUHJvcGVydGllcyBwcm9wcyA9IFN5c3RlbS5nZXRQcm9wZXJ0aWVzKCk7CisJLy8gcGFyc2UgdGhlIGFyZ3VtZW50cworCUludGVybmV0QWRkcmVzc1tdIGFkZHJzID0gbnVsbDsKKwlJbnRlcm5ldEFkZHJlc3MgZnJvbTsKKwlib29sZWFuIGRlYnVnID0gZmFsc2U7CisJaWYgKGFyZ3MubGVuZ3RoICE9IDQpIHsKKwkgICAgdXNhZ2UoKTsKKwkgICAgcmV0dXJuOworCX0gZWxzZSB7CisJICAgIHByb3BzLnB1dCgibWFpbC5zbXRwLmhvc3QiLCBhcmdzWzJdKTsKKwkgICAgaWYgKGFyZ3NbM10uZXF1YWxzKCJ0cnVlIikpIHsKKwkJZGVidWcgPSB0cnVlOworCSAgICB9IGVsc2UgaWYgKGFyZ3NbM10uZXF1YWxzKCJmYWxzZSIpKSB7CisJCWRlYnVnID0gZmFsc2U7CisJICAgIH0gZWxzZSB7CisJCXVzYWdlKCk7CisJCXJldHVybjsKKwkgICAgfQorCisJICAgIC8vIHBhcnNlIHRoZSBkZXN0aW5hdGlvbiBhZGRyZXNzZXMKKwkgICAgdHJ5IHsKKwkJYWRkcnMgPSBJbnRlcm5ldEFkZHJlc3MucGFyc2UoYXJnc1swXSwgZmFsc2UpOworCQlmcm9tID0gbmV3IEludGVybmV0QWRkcmVzcyhhcmdzWzFdKTsKKwkgICAgfSBjYXRjaCAoQWRkcmVzc0V4Y2VwdGlvbiBhZXgpIHsKKwkJU3lzdGVtLm91dC5wcmludGxuKCJJbnZhbGlkIEFkZHJlc3MiKTsKKwkJYWV4LnByaW50U3RhY2tUcmFjZSgpOworCQlyZXR1cm47CisJICAgIH0KKwl9CisJLy8gY3JlYXRlIHNvbWUgcHJvcGVydGllcyBhbmQgZ2V0IGEgU2Vzc2lvbgorCVNlc3Npb24gc2Vzc2lvbiA9IFNlc3Npb24uZ2V0SW5zdGFuY2UocHJvcHMsIG51bGwpOworCXNlc3Npb24uc2V0RGVidWcoZGVidWcpOworCisJdHJhbnNwb3J0IHQgPSBuZXcgdHJhbnNwb3J0KCk7CisJdC5nbyhzZXNzaW9uLCBhZGRycywgZnJvbSk7CisgICAgfQorCisgICAgcHVibGljIHRyYW5zcG9ydCgpIHt9CisKKyAgICBwdWJsaWMgdm9pZCBnbyhTZXNzaW9uIHNlc3Npb24sIEludGVybmV0QWRkcmVzc1tdIHRvQWRkciwKKwkJCQlJbnRlcm5ldEFkZHJlc3MgZnJvbSkgeworCVRyYW5zcG9ydCB0cmFucyA9IG51bGw7CisKKwl0cnkgeworCSAgICAvLyBjcmVhdGUgYSBtZXNzYWdlCisJICAgIE1lc3NhZ2UgbXNnID0gbmV3IE1pbWVNZXNzYWdlKHNlc3Npb24pOworCSAgICBtc2cuc2V0RnJvbShmcm9tKTsKKwkgICAgbXNnLnNldFJlY2lwaWVudHMoTWVzc2FnZS5SZWNpcGllbnRUeXBlLlRPLCB0b0FkZHIpOworCSAgICBtc2cuc2V0U3ViamVjdCgiSmF2YU1haWwgQVBJcyB0cmFuc3BvcnQuamF2YSBUZXN0Iik7CisJICAgIG1zZy5zZXRTZW50RGF0ZShuZXcgRGF0ZSgpKTsgIC8vIERhdGU6IGhlYWRlcgorCSAgICBtc2cuc2V0Q29udGVudChtc2dUZXh0K21zZ1RleHQyLCAidGV4dC9wbGFpbiIpOworCSAgICBtc2cuc2F2ZUNoYW5nZXMoKTsKKworCSAgICAvLyBnZXQgdGhlIHNtdHAgdHJhbnNwb3J0IGZvciB0aGUgYWRkcmVzcworCSAgICB0cmFucyA9IHNlc3Npb24uZ2V0VHJhbnNwb3J0KHRvQWRkclswXSk7CisKKwkgICAgLy8gcmVnaXN0ZXIgb3Vyc2VsdmVzIGFzIGxpc3RlbmVyIGZvciBDb25uZWN0aW9uRXZlbnRzIAorCSAgICAvLyBhbmQgVHJhbnNwb3J0RXZlbnRzCisJICAgIHRyYW5zLmFkZENvbm5lY3Rpb25MaXN0ZW5lcih0aGlzKTsKKwkgICAgdHJhbnMuYWRkVHJhbnNwb3J0TGlzdGVuZXIodGhpcyk7CisKKwkgICAgLy8gY29ubmVjdCB0aGUgdHJhbnNwb3J0CisJICAgIHRyYW5zLmNvbm5lY3QoKTsKKworCSAgICAvLyBzZW5kIHRoZSBtZXNzYWdlCisJICAgIHRyYW5zLnNlbmRNZXNzYWdlKG1zZywgdG9BZGRyKTsKKworCSAgICAvLyBnaXZlIHRoZSBFdmVudFF1ZXVlIGVub3VnaCB0aW1lIHRvIGZpcmUgaXRzIGV2ZW50cworCSAgICB0cnkge1RocmVhZC5zbGVlcCg1KTt9Y2F0Y2goSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkge30KKworCX0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBtZXgpIHsKKwkgICAgLy8gZ2l2ZSB0aGUgRXZlbnRRdWV1ZSBlbm91Z2ggdGltZSB0byBmaXJlIGl0cyBldmVudHMKKwkgICAgdHJ5IHtUaHJlYWQuc2xlZXAoNSk7fWNhdGNoKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHt9CisKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJTZW5kaW5nIGZhaWxlZCB3aXRoIGV4Y2VwdGlvbjoiKTsKKwkgICAgbWV4LnByaW50U3RhY2tUcmFjZSgpOworCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oKTsKKwkgICAgRXhjZXB0aW9uIGV4ID0gbWV4OworCSAgICBkbyB7CisJCWlmIChleCBpbnN0YW5jZW9mIFNlbmRGYWlsZWRFeGNlcHRpb24pIHsKKwkJICAgIFNlbmRGYWlsZWRFeGNlcHRpb24gc2ZleCA9IChTZW5kRmFpbGVkRXhjZXB0aW9uKWV4OworCQkgICAgQWRkcmVzc1tdIGludmFsaWQgPSBzZmV4LmdldEludmFsaWRBZGRyZXNzZXMoKTsKKwkJICAgIGlmIChpbnZhbGlkICE9IG51bGwpIHsKKwkJCVN5c3RlbS5vdXQucHJpbnRsbigiICAgICoqIEludmFsaWQgQWRkcmVzc2VzIik7CisJCQlmb3IgKGludCBpID0gMDsgaSA8IGludmFsaWQubGVuZ3RoOyBpKyspIAorCQkJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiICAgICAgICAgIiArIGludmFsaWRbaV0pOworCQkgICAgfQorCQkgICAgQWRkcmVzc1tdIHZhbGlkVW5zZW50ID0gc2ZleC5nZXRWYWxpZFVuc2VudEFkZHJlc3NlcygpOworCQkgICAgaWYgKHZhbGlkVW5zZW50ICE9IG51bGwpIHsKKwkJCVN5c3RlbS5vdXQucHJpbnRsbigiICAgICoqIFZhbGlkVW5zZW50IEFkZHJlc3NlcyIpOworCQkJZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZFVuc2VudC5sZW5ndGg7IGkrKykgCisJCQkgICAgU3lzdGVtLm91dC5wcmludGxuKCIgICAgICAgICAiK3ZhbGlkVW5zZW50W2ldKTsKKwkJICAgIH0KKwkJICAgIEFkZHJlc3NbXSB2YWxpZFNlbnQgPSBzZmV4LmdldFZhbGlkU2VudEFkZHJlc3NlcygpOworCQkgICAgaWYgKHZhbGlkU2VudCAhPSBudWxsKSB7CisJCQlTeXN0ZW0ub3V0LnByaW50bG4oIiAgICAqKiBWYWxpZFNlbnQgQWRkcmVzc2VzIik7CisJCQlmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkU2VudC5sZW5ndGg7IGkrKykgCisJCQkgICAgU3lzdGVtLm91dC5wcmludGxuKCIgICAgICAgICAiK3ZhbGlkU2VudFtpXSk7CisJCSAgICB9CisJCX0KKwkJU3lzdGVtLm91dC5wcmludGxuKCk7CisJCWlmIChleCBpbnN0YW5jZW9mIE1lc3NhZ2luZ0V4Y2VwdGlvbikKKwkJICAgIGV4ID0gKChNZXNzYWdpbmdFeGNlcHRpb24pZXgpLmdldE5leHRFeGNlcHRpb24oKTsKKwkJZWxzZQorCQkgICAgZXggPSBudWxsOworCSAgICB9IHdoaWxlIChleCAhPSBudWxsKTsKKwl9IGZpbmFsbHkgeworCSAgICB0cnkgeworCQkvLyBjbG9zZSB0aGUgdHJhbnNwb3J0CisJCWlmICh0cmFucyAhPSBudWxsKQorCQkgICAgdHJhbnMuY2xvc2UoKTsKKwkgICAgfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIG1leCkgeyAvKiBpZ25vcmUgKi8gfQorCX0KKyAgICB9CisKKyAgICAvLyBpbXBsZW1lbnQgQ29ubmVjdGlvbkxpc3RlbmVyIGludGVyZmFjZQorICAgIHB1YmxpYyB2b2lkIG9wZW5lZChDb25uZWN0aW9uRXZlbnQgZSkgeworCVN5c3RlbS5vdXQucHJpbnRsbigiPj4+IENvbm5lY3Rpb25MaXN0ZW5lci5vcGVuZWQoKSIpOworICAgIH0KKyAgICBwdWJsaWMgdm9pZCBkaXNjb25uZWN0ZWQoQ29ubmVjdGlvbkV2ZW50IGUpIHt9CisgICAgcHVibGljIHZvaWQgY2xvc2VkKENvbm5lY3Rpb25FdmVudCBlKSB7CisJU3lzdGVtLm91dC5wcmludGxuKCI+Pj4gQ29ubmVjdGlvbkxpc3RlbmVyLmNsb3NlZCgpIik7CisgICAgfQorCisgICAgLy8gaW1wbGVtZW50IFRyYW5zcG9ydExpc3RlbmVyIGludGVyZmFjZQorICAgIHB1YmxpYyB2b2lkIG1lc3NhZ2VEZWxpdmVyZWQoVHJhbnNwb3J0RXZlbnQgZSkgeworCVN5c3RlbS5vdXQucHJpbnRsbigiPj4+IFRyYW5zcG9ydExpc3RlbmVyLm1lc3NhZ2VEZWxpdmVyZWQoKS4iKTsKKwlTeXN0ZW0ub3V0LnByaW50bG4oIiBWYWxpZCBBZGRyZXNzZXM6Iik7CisJQWRkcmVzc1tdIHZhbGlkID0gZS5nZXRWYWxpZFNlbnRBZGRyZXNzZXMoKTsKKwlpZiAodmFsaWQgIT0gbnVsbCkgeworCSAgICBmb3IgKGludCBpID0gMDsgaSA8IHZhbGlkLmxlbmd0aDsgaSsrKSAKKwkJU3lzdGVtLm91dC5wcmludGxuKCIgICAgIiArIHZhbGlkW2ldKTsKKwl9CisgICAgfQorICAgIHB1YmxpYyB2b2lkIG1lc3NhZ2VOb3REZWxpdmVyZWQoVHJhbnNwb3J0RXZlbnQgZSkgeworCVN5c3RlbS5vdXQucHJpbnRsbigiPj4+IFRyYW5zcG9ydExpc3RlbmVyLm1lc3NhZ2VOb3REZWxpdmVyZWQoKS4iKTsKKwlTeXN0ZW0ub3V0LnByaW50bG4oIiBJbnZhbGlkIEFkZHJlc3NlczoiKTsKKwlBZGRyZXNzW10gaW52YWxpZCA9IGUuZ2V0SW52YWxpZEFkZHJlc3NlcygpOworCWlmIChpbnZhbGlkICE9IG51bGwpIHsKKwkgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnZhbGlkLmxlbmd0aDsgaSsrKSAKKwkJU3lzdGVtLm91dC5wcmludGxuKCIgICAgIiArIGludmFsaWRbaV0pOworCX0KKyAgICB9CisgICAgcHVibGljIHZvaWQgbWVzc2FnZVBhcnRpYWxseURlbGl2ZXJlZChUcmFuc3BvcnRFdmVudCBlKSB7CisJU3lzdGVtLm91dC5wcmludGxuKCI+Pj4gVHJhbnNwb3J0TGlzdGVuZXIubWVzc2FnZVBhcnRpYWxseURlbGl2ZXJlZCgpLiIpOworCVN5c3RlbS5vdXQucHJpbnRsbigiIFZhbGlkIEFkZHJlc3NlczoiKTsKKwlBZGRyZXNzW10gdmFsaWQgPSBlLmdldFZhbGlkU2VudEFkZHJlc3NlcygpOworCWlmICh2YWxpZCAhPSBudWxsKSB7CisJICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsaWQubGVuZ3RoOyBpKyspIAorCQlTeXN0ZW0ub3V0LnByaW50bG4oIiAgICAiICsgdmFsaWRbaV0pOworCX0KKwlTeXN0ZW0ub3V0LnByaW50bG4oIiBWYWxpZCBVbnNlbnQgQWRkcmVzc2VzOiIpOworCUFkZHJlc3NbXSB1bnNlbnQgPSBlLmdldFZhbGlkVW5zZW50QWRkcmVzc2VzKCk7CisJaWYgKHVuc2VudCAhPSBudWxsKSB7CisJICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdW5zZW50Lmxlbmd0aDsgaSsrKSAKKwkJU3lzdGVtLm91dC5wcmludGxuKCIgICAgIiArIHVuc2VudFtpXSk7CisJfQorCVN5c3RlbS5vdXQucHJpbnRsbigiIEludmFsaWQgQWRkcmVzc2VzOiIpOworCUFkZHJlc3NbXSBpbnZhbGlkID0gZS5nZXRJbnZhbGlkQWRkcmVzc2VzKCk7CisJaWYgKGludmFsaWQgIT0gbnVsbCkgeworCSAgICBmb3IgKGludCBpID0gMDsgaSA8IGludmFsaWQubGVuZ3RoOyBpKyspIAorCQlTeXN0ZW0ub3V0LnByaW50bG4oIiAgICAiICsgaW52YWxpZFtpXSk7CisJfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgdXNhZ2UoKSB7CisJU3lzdGVtLm91dC5wcmludGxuKAorICAgICJ1c2FnZTogamF2YSB0cmFuc3BvcnQgXCI8dG8xPlssIDx0bzI+XSpcIiA8ZnJvbT4gPHNtdHA+IHRydWV8ZmFsc2UiKTsKKwlTeXN0ZW0ub3V0LnByaW50bG4oCisgICAgImV4YW1wbGU6IGphdmEgdHJhbnNwb3J0IFwiam9lQG1hY2hpbmUsIGphbmVcIiBzZW5kZXJhZGRyIHNtdHBob3N0IGZhbHNlIik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvZGVtby9zcmMvbWFpbi9qYXZhL3VpZG1zZ3Nob3cuamF2YSBiL2RlbW8vc3JjL21haW4vamF2YS91aWRtc2dzaG93LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzFlNGQxNAotLS0gL2Rldi9udWxsCisrKyBiL2RlbW8vc3JjL21haW4vamF2YS91aWRtc2dzaG93LmphdmEKQEAgLTAsMCArMSwyODcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorICovCisKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YXgubWFpbC4qOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuKjsKK2ltcG9ydCBqYXZheC5hY3RpdmF0aW9uLio7CisKKy8qCisgKiBEZW1vIGFwcCB0aGF0IGV4ZXJjaXNlcyB0aGUgTWVzc2FnZSBpbnRlcmZhY2VzLgorICogQWNjZXNzIG1lc3NhZ2UgZ2l2ZW4gaXRzIFVJRC4KKyAqIFNob3cgaW5mb3JtYXRpb24gYWJvdXQgYW5kIGNvbnRlbnRzIG9mIG1lc3NhZ2VzLgorICoKKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCisKK3B1YmxpYyBjbGFzcyB1aWRtc2dzaG93IHsKKworICAgIHN0YXRpYyBTdHJpbmcgcHJvdG9jb2w7CisgICAgc3RhdGljIFN0cmluZyBob3N0ID0gbnVsbDsKKyAgICBzdGF0aWMgU3RyaW5nIHVzZXIgPSBudWxsOworICAgIHN0YXRpYyBTdHJpbmcgcGFzc3dvcmQgPSBudWxsOworICAgIHN0YXRpYyBTdHJpbmcgbWJveCA9ICJJTkJPWCI7CisgICAgc3RhdGljIFN0cmluZyB1cmwgPSBudWxsOworICAgIHN0YXRpYyBib29sZWFuIHZlcmJvc2UgPSBmYWxzZTsKKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZyBhcmd2W10pIHsKKwlsb25nIHVpZCA9IC0xOworCWludCBvcHRpbmQ7CisKKwlmb3IgKG9wdGluZCA9IDA7IG9wdGluZCA8IGFyZ3YubGVuZ3RoOyBvcHRpbmQrKykgeworCSAgICBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLVQiKSkgeworCQlwcm90b2NvbCA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1IIikpIHsKKwkJaG9zdCA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1VIikpIHsKKwkJdXNlciA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1QIikpIHsKKwkJcGFzc3dvcmQgPSBhcmd2Wysrb3B0aW5kXTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItdiIpKSB7CisJCXZlcmJvc2UgPSB0cnVlOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1mIikpIHsKKwkJbWJveCA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1MIikpIHsKKwkJdXJsID0gYXJndlsrK29wdGluZF07CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLS0iKSkgeworCQlvcHRpbmQrKzsKKwkJYnJlYWs7CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLnN0YXJ0c1dpdGgoIi0iKSkgeworCQlTeXN0ZW0ub3V0LnByaW50bG4oIlVzYWdlOiB1aWRtc2dzaG93IFstTCB1cmxdIFstVCBwcm90b2NvbF0gWy1IIGhvc3RdIFstVSB1c2VyXSBbLVAgcGFzc3dvcmRdIFstZiBtYWlsYm94XSBbdWlkXSBbLXZdIik7CisJCVN5c3RlbS5leGl0KDEpOworCSAgICB9IGVsc2UgeworCQlicmVhazsKKwkgICAgfQorCX0KKworCXRyeSB7CisJICAgIGlmIChvcHRpbmQgPCBhcmd2Lmxlbmd0aCkKKwkJIHVpZCA9IExvbmcucGFyc2VMb25nKGFyZ3Zbb3B0aW5kXSk7CisKKwkgICAgLy8gR2V0IGEgUHJvcGVydGllcyBvYmplY3QKKwkgICAgUHJvcGVydGllcyBwcm9wcyA9IFN5c3RlbS5nZXRQcm9wZXJ0aWVzKCk7CisKKwkgICAgLy8gR2V0IGEgU2Vzc2lvbiBvYmplY3QKKwkgICAgU2Vzc2lvbiBzZXNzaW9uID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShwcm9wcywgbnVsbCk7CisJICAgIC8vIHNlc3Npb24uc2V0RGVidWcodHJ1ZSk7CisKKwkgICAgLy8gR2V0IGEgU3RvcmUgb2JqZWN0CisJICAgIFN0b3JlIHN0b3JlID0gbnVsbDsKKwkgICAgaWYgKHVybCAhPSBudWxsKSB7CisJCVVSTE5hbWUgdXJsbiA9IG5ldyBVUkxOYW1lKHVybCk7CisJCXN0b3JlID0gc2Vzc2lvbi5nZXRTdG9yZSh1cmxuKTsKKwkJc3RvcmUuY29ubmVjdCgpOworCSAgICB9IGVsc2UgeworCQlpZiAocHJvdG9jb2wgIT0gbnVsbCkJCQorCQkgICAgc3RvcmUgPSBzZXNzaW9uLmdldFN0b3JlKHByb3RvY29sKTsKKwkJZWxzZQorCQkgICAgc3RvcmUgPSBzZXNzaW9uLmdldFN0b3JlKCk7CisKKwkJLy8gQ29ubmVjdAorCQlpZiAoaG9zdCAhPSBudWxsIHx8IHVzZXIgIT0gbnVsbCB8fCBwYXNzd29yZCAhPSBudWxsKQorCQkgICAgc3RvcmUuY29ubmVjdChob3N0LCB1c2VyLCBwYXNzd29yZCk7CisJCWVsc2UKKwkJICAgIHN0b3JlLmNvbm5lY3QoKTsKKwkgICAgfQorCSAgICAKKworCSAgICAvLyBPcGVuIHRoZSBGb2xkZXIKKworCSAgICBGb2xkZXIgZm9sZGVyID0gc3RvcmUuZ2V0RGVmYXVsdEZvbGRlcigpOworCSAgICBpZiAoZm9sZGVyID09IG51bGwpIHsKKwkJU3lzdGVtLm91dC5wcmludGxuKCJObyBkZWZhdWx0IGZvbGRlciIpOworCQlTeXN0ZW0uZXhpdCgxKTsKKwkgICAgfQorCisJICAgIGZvbGRlciA9IGZvbGRlci5nZXRGb2xkZXIobWJveCk7CisJICAgIGlmICghZm9sZGVyLmV4aXN0cygpKSB7CisJCVN5c3RlbS5vdXQucHJpbnRsbihtYm94ICsgIiAgZG9lcyBub3QgZXhpc3QiKTsKKwkJU3lzdGVtLmV4aXQoMSk7CisJICAgIH0KKworCSAgICBpZiAoIShmb2xkZXIgaW5zdGFuY2VvZiBVSURGb2xkZXIpKSB7CisJCVN5c3RlbS5vdXQucHJpbnRsbigKKwkJICAgICJUaGlzIFByb3ZpZGVyIG9yIHRoaXMgZm9sZGVyIGRvZXMgbm90IHN1cHBvcnQgVUlEcyIpOworCQlTeXN0ZW0uZXhpdCgxKTsKKwkgICAgfQorCisJICAgIFVJREZvbGRlciB1Zm9sZGVyID0gKFVJREZvbGRlcilmb2xkZXI7CisKKwkgICAgZm9sZGVyLm9wZW4oRm9sZGVyLlJFQURfV1JJVEUpOworCSAgICBpbnQgdG90YWxNZXNzYWdlcyA9IGZvbGRlci5nZXRNZXNzYWdlQ291bnQoKTsKKworCSAgICBpZiAodG90YWxNZXNzYWdlcyA9PSAwKSB7CisJCVN5c3RlbS5vdXQucHJpbnRsbigiRW1wdHkgZm9sZGVyIik7CisJCWZvbGRlci5jbG9zZShmYWxzZSk7CisJCXN0b3JlLmNsb3NlKCk7CisJCVN5c3RlbS5leGl0KDEpOworCSAgICB9CisKKwkgICAgaWYgKHZlcmJvc2UpIHsKKwkJaW50IG5ld01lc3NhZ2VzID0gZm9sZGVyLmdldE5ld01lc3NhZ2VDb3VudCgpOworCQlTeXN0ZW0ub3V0LnByaW50bG4oIlRvdGFsIG1lc3NhZ2VzID0gIiArIHRvdGFsTWVzc2FnZXMpOworCQlTeXN0ZW0ub3V0LnByaW50bG4oIk5ldyBtZXNzYWdlcyA9ICIgKyBuZXdNZXNzYWdlcyk7CisJCVN5c3RlbS5vdXQucHJpbnRsbigiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIpOworCSAgICB9CisKKwkgICAgaWYgKHVpZCA9PSAtMSkgeworCQkvLyBBdHRyaWJ1dGVzICYgRmxhZ3MgZm9yIEFMTCBtZXNzYWdlcyAuLgorCQlNZXNzYWdlW10gbXNncyA9IAorCQkJdWZvbGRlci5nZXRNZXNzYWdlc0J5VUlEKDEsIFVJREZvbGRlci5MQVNUVUlEKTsKKworCQkvLyBVc2UgYSBzdWl0YWJsZSBGZXRjaFByb2ZpbGUKKwkJRmV0Y2hQcm9maWxlIGZwID0gbmV3IEZldGNoUHJvZmlsZSgpOworCQlmcC5hZGQoRmV0Y2hQcm9maWxlLkl0ZW0uRU5WRUxPUEUpOworCQlmcC5hZGQoRmV0Y2hQcm9maWxlLkl0ZW0uRkxBR1MpOworCQlmcC5hZGQoIlgtTWFpbGVyIik7CisJCWZvbGRlci5mZXRjaChtc2dzLCBmcCk7CisKKwkJZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisJCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIik7CisJCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIk1FU1NBR0UgVUlEICMiICsgCisJCQkJCXVmb2xkZXIuZ2V0VUlEKG1zZ3NbaV0pICsgIjoiKTsKKwkJICAgIGR1bXBFbnZlbG9wZShtc2dzW2ldKTsKKwkJICAgIC8vIGR1bXBQYXJ0KG1zZ3NbaV0pOworCQl9CisJICAgIH0gZWxzZSB7CisJCVN5c3RlbS5vdXQucHJpbnRsbigiR2V0dGluZyBtZXNzYWdlIFVJRDogIiArIHVpZCk7CisJCU1lc3NhZ2UgbSA9IHVmb2xkZXIuZ2V0TWVzc2FnZUJ5VUlEKHVpZCk7CisJCWlmIChtICE9IG51bGwpCisJCSAgICBkdW1wUGFydChtKTsKKwkJZWxzZQorCQkgICAgU3lzdGVtLm91dC5wcmludGxuKAorCQkJIlRoaXMgTWVzc2FnZSBkb2VzIG5vdCBleGlzdCBvbiB0aGlzIGZvbGRlciIpOworCSAgICB9CisKKwkgICAgZm9sZGVyLmNsb3NlKGZhbHNlKTsKKwkgICAgc3RvcmUuY2xvc2UoKTsKKwl9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJPb3BzLCBnb3QgZXhjZXB0aW9uISAiICsgZXguZ2V0TWVzc2FnZSgpKTsKKwkgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7CisJfQorCVN5c3RlbS5leGl0KDEpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBkdW1wUGFydChQYXJ0IHApIHRocm93cyBFeGNlcHRpb24geworCWlmIChwIGluc3RhbmNlb2YgTWVzc2FnZSkKKwkgICAgZHVtcEVudmVsb3BlKChNZXNzYWdlKXApOworCisJLyogRHVtcCBpbnB1dCBzdHJlYW0KKwlJbnB1dFN0cmVhbSBpcyA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKHAuZ2V0SW5wdXRTdHJlYW0oKSk7CisJaW50IGM7CisJd2hpbGUgKChjID0gaXMucmVhZCgpKSAhPSAtMSkKKwkgICAgU3lzdGVtLm91dC53cml0ZShjKTsKKwkqLworCisJU3lzdGVtLm91dC5wcmludGxuKCJDT05URU5ULVRZUEU6ICIgKyBwLmdldENvbnRlbnRUeXBlKCkpOworCisJT2JqZWN0IG8gPSBwLmdldENvbnRlbnQoKTsKKwlpZiAobyBpbnN0YW5jZW9mIFN0cmluZykgeworCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlRoaXMgaXMgYSBTdHJpbmciKTsKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0iKTsKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKChTdHJpbmcpbyk7CisJfSBlbHNlIGlmIChvIGluc3RhbmNlb2YgTXVsdGlwYXJ0KSB7CisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiVGhpcyBpcyBhIE11bHRpcGFydCIpOworCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIpOworCSAgICBNdWx0aXBhcnQgbXAgPSAoTXVsdGlwYXJ0KW87CisJICAgIGludCBjb3VudCA9IG1wLmdldENvdW50KCk7CisJICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykKKwkJZHVtcFBhcnQobXAuZ2V0Qm9keVBhcnQoaSkpOworCX0gZWxzZSBpZiAobyBpbnN0YW5jZW9mIE1lc3NhZ2UpIHsKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJUaGlzIGlzIGEgTmVzdGVkIE1lc3NhZ2UiKTsKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0iKTsKKwkgICAgZHVtcFBhcnQoKFBhcnQpbyk7CisJfSBlbHNlIGlmIChvIGluc3RhbmNlb2YgSW5wdXRTdHJlYW0pIHsKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJUaGlzIGlzIGp1c3QgYW4gaW5wdXQgc3RyZWFtIik7CisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIik7CisJICAgIElucHV0U3RyZWFtIGlzID0gKElucHV0U3RyZWFtKW87CisJICAgIGludCBjOworCSAgICB3aGlsZSAoKGMgPSBpcy5yZWFkKCkpICE9IC0xKQorCQlTeXN0ZW0ub3V0LndyaXRlKGMpOworCX0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgZHVtcEVudmVsb3BlKE1lc3NhZ2UgbSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJU3lzdGVtLm91dC5wcmludGxuKCJUaGlzIGlzIHRoZSBtZXNzYWdlIGVudmVsb3BlIik7CisJU3lzdGVtLm91dC5wcmludGxuKCItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0iKTsKKwlBZGRyZXNzW10gYTsKKwkvLyBGUk9NIAorCWlmICgoYSA9IG0uZ2V0RnJvbSgpKSAhPSBudWxsKSB7CisJICAgIGZvciAoaW50IGogPSAwOyBqIDwgYS5sZW5ndGg7IGorKykKKwkJU3lzdGVtLm91dC5wcmludGxuKCJGUk9NOiAiICsgYVtqXS50b1N0cmluZygpKTsKKwl9CisKKwkvLyBUTworCWlmICgoYSA9IG0uZ2V0UmVjaXBpZW50cyhNZXNzYWdlLlJlY2lwaWVudFR5cGUuVE8pKSAhPSBudWxsKSB7CisJICAgIGZvciAoaW50IGogPSAwOyBqIDwgYS5sZW5ndGg7IGorKykKKwkJU3lzdGVtLm91dC5wcmludGxuKCJUTzogIiArIGFbal0udG9TdHJpbmcoKSk7CisJfQorCisJLy8gU1VCSkVDVAorCVN5c3RlbS5vdXQucHJpbnRsbigiU1VCSkVDVDogIiArIG0uZ2V0U3ViamVjdCgpKTsKKworCS8vIERBVEUKKwlEYXRlIGQgPSBtLmdldFNlbnREYXRlKCk7CisJU3lzdGVtLm91dC5wcmludGxuKCJTZW5kRGF0ZTogIiArCisJICAgIChkICE9IG51bGwgPyBkLnRvU3RyaW5nKCkgOiAiVU5LTk9XTiIpKTsKKworCS8vIFNJWkUKKwlTeXN0ZW0ub3V0LnByaW50bG4oIlNpemU6ICIgKyBtLmdldFNpemUoKSk7CisKKwkvLyBGTEFHUzoKKwlGbGFncyBmbGFncyA9IG0uZ2V0RmxhZ3MoKTsKKwlTdHJpbmdCdWZmZXIgc2IgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CisJRmxhZ3MuRmxhZ1tdIHNmID0gZmxhZ3MuZ2V0U3lzdGVtRmxhZ3MoKTsgLy8gZ2V0IHRoZSBzeXN0ZW0gZmxhZ3MKKworCWJvb2xlYW4gZmlyc3QgPSB0cnVlOworCWZvciAoaW50IGkgPSAwOyBpIDwgc2YubGVuZ3RoOyBpKyspIHsKKwkgICAgU3RyaW5nIHM7CisJICAgIEZsYWdzLkZsYWcgZiA9IHNmW2ldOworCSAgICBpZiAoZiA9PSBGbGFncy5GbGFnLkFOU1dFUkVEKQorCQlzID0gIlxcQW5zd2VyZWQiOworCSAgICBlbHNlIGlmIChmID09IEZsYWdzLkZsYWcuREVMRVRFRCkKKwkJcyA9ICJcXERlbGV0ZWQiOworCSAgICBlbHNlIGlmIChmID09IEZsYWdzLkZsYWcuRFJBRlQpCisJCXMgPSAiXFxEcmFmdCI7CisJICAgIGVsc2UgaWYgKGYgPT0gRmxhZ3MuRmxhZy5GTEFHR0VEKQorCQlzID0gIlxcRmxhZ2dlZCI7CisJICAgIGVsc2UgaWYgKGYgPT0gRmxhZ3MuRmxhZy5SRUNFTlQpCisJCXMgPSAiXFxSZWNlbnQiOworCSAgICBlbHNlIGlmIChmID09IEZsYWdzLkZsYWcuU0VFTikKKwkJcyA9ICJcXFNlZW4iOworCSAgICBlbHNlCisJCWNvbnRpbnVlOwkvLyBza2lwIGl0CisJICAgIGlmIChmaXJzdCkKKwkJZmlyc3QgPSBmYWxzZTsKKwkgICAgZWxzZQorCQlzYi5hcHBlbmQoJyAnKTsKKwkgICAgc2IuYXBwZW5kKHMpOworCX0KKworCVN0cmluZ1tdIHVmID0gZmxhZ3MuZ2V0VXNlckZsYWdzKCk7IC8vIGdldCB0aGUgdXNlciBmbGFnIHN0cmluZ3MKKwlmb3IgKGludCBpID0gMDsgaSA8IHVmLmxlbmd0aDsgaSsrKSB7CisJICAgIGlmIChmaXJzdCkKKwkJZmlyc3QgPSBmYWxzZTsKKwkgICAgZWxzZQorCQlzYi5hcHBlbmQoJyAnKTsKKwkgICAgc2IuYXBwZW5kKHVmW2ldKTsKKwl9CisJU3lzdGVtLm91dC5wcmludGxuKCJGTEFHUyA9ICIgKyBzYi50b1N0cmluZygpKTsKKworCS8vIFgtTUFJTEVSCisJU3RyaW5nW10gaGRycyA9IG0uZ2V0SGVhZGVyKCJYLU1haWxlciIpOworCWlmIChoZHJzICE9IG51bGwpCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiWC1NYWlsZXI6ICIgKyBoZHJzWzBdKTsKKwllbHNlCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiWC1NYWlsZXIgTk9UIGF2YWlsYWJsZSIpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2RvYy9yZWxlYXNlL0FwYWNoZUpTZXJ2Lmh0bWwgYi9kb2MvcmVsZWFzZS9BcGFjaGVKU2Vydi5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ3Yzg1ZDIKLS0tIC9kZXYvbnVsbAorKysgYi9kb2MvcmVsZWFzZS9BcGFjaGVKU2Vydi5odG1sCkBAIC0wLDAgKzEsOTggQEAKKzwhZG9jdHlwZSBodG1sIHB1YmxpYyAiLS8vdzNjLy9kdGQgaHRtbCA0LjAgdHJhbnNpdGlvbmFsLy9lbiI+Cis8aHRtbD4KKzxoZWFkPgorPCEtLQorCisgICAgQ29weXJpZ2h0IChjKSAyMDEwLCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisKKyAgICBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAgICB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKworICAgIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAgICBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgICAgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgICAgdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisKKyAgICBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKworLS0+CisKKyAgIDxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PWlzby04ODU5LTEiPgorICAgPG1ldGEgbmFtZT0iQXV0aG9yIiBjb250ZW50PSJKYXZhU29mdHdhcmUiPgorICAgPG1ldGEgbmFtZT0iR0VORVJBVE9SIiBjb250ZW50PSJNb3ppbGxhLzQuNjEgW2VuXSAoV2luTlQ7IFUpIFtOZXRzY2FwZV0iPgorICAgPHRpdGxlPkFwYWNoZUpTZXJ2PC90aXRsZT4KKzwvaGVhZD4KKzxib2R5PgorSWYgeW91IGRvbid0IGFscmVhZHkgaGF2ZSBBcGFjaGUgd2ViIHNlcnZlciBhbmQgQXBhY2hlIEpTZXJ2Cittb2R1bGUgaW5zdGFsbGVkIGFuZCBydW5uaW5nLAorPGJyPnlvdSdsbCBuZWVkIHRvIGRvd25sb2FkIHRoZW0gZnJvbSB0aGUmbmJzcDsgPGEgaHJlZj0iaHR0cDovL3d3dy5hcGFjaGUub3JnIj5BcGFjaGUKK1NvZnR3YXJlIEZvdW5kYXRpb248L2E+Jm5ic3A7IGFuZCBpbnN0YWxsIHRoZW0uIFdlCis8YnI+d2VyZSBhYmxlIHRvIGZpbmQgYmluYXJ5IHZlcnNpb25zIG9mIEFwYWNoZSB3ZWIgc2VydmVyIGZvciBib3RoIHRoZQorU29sYXJpcyBhbmQgV2luZG93cyBOVAorPGJyPm9wZXJhdGluZyBzeXN0ZW1zLCBhbmQgQXBhY2hlIEpTZXJ2IDEuMS4yIGZvciBXaW5kb3dzIE5ULiBIb3dldmVyLAorZm9yIFNvbGFyaXMsCis8YnI+QXBhY2hlIEpTZXJ2IG5lZWRlZCB0byBiZSBidWlsdCBmcm9tIHRoZSBzb3VyY2UuCis8cD4ob24gU29sYXJpcykKKzxibG9ja3F1b3RlPkFwYWNoZSBXZWIgU2VydmVyIDEuMy45ICg8YSBocmVmPSJodHRwOi8vaHR0cGQuYXBhY2hlLm9yZy9kaXN0L2JpbmFyaWVzLyI+YmluYXJ5PC9hPikKKzxicj5BcGFjaGUgSlNlcnYgMS4xLjIgKGJ1aWx0IGZyb20gPGEgaHJlZj0iaHR0cDovL2phdmEuYXBhY2hlLm9yZy8iPnNvdXJjZTwvYT4pPC9ibG9ja3F1b3RlPgorKG9uIE5UKQorPGJsb2NrcXVvdGU+QXBhY2hlIFdlYiBTZXJ2ZXImbmJzcDsgMS4zLjE0ICg8YSBocmVmPSJodHRwOi8vaHR0cGQuYXBhY2hlLm9yZy9kaXN0L2JpbmFyaWVzLyI+YmluYXJ5PC9hPikKKzxicj5BcGFjaGUgSlNlcnYgMS4xLjIgKDxhIGhyZWY9Imh0dHA6Ly9qYXZhLmFwYWNoZS5vcmcvIj5iaW5hcnk8L2E+KTwvYmxvY2txdW90ZT4KK1RvIHJ1biB0aGUgSmF2YU1haWxTZXJ2bGV0LCB5b3UgbXVzdCBhZGQgdGhlIEphdmFNYWlsIGFuZCBKYXZhQmVhbnMgQWN0aXZhdGlvbgorRnJhbWV3b3JrCis8YnI+amFyIGZpbGVzIHRvIHRoZSB3ZWIgc2VydmVyJ3Mgc3lzdGVtIGNsYXNzcGF0aC4gQXBhY2hlIEpTZXJ2IGFsc28gcmVxdWlyZXMKK3RoYXQgdGhlCis8YnI+SmF2YSBTZXJ2bGV0IERldmVsb3BtZW50IEtpdCZuYnNwOyAyLjAgKDxhIGhyZWY9Imh0dHA6Ly9qYXZhLnN1bi5jb20vcHJvZHVjdHMvc2VydmxldC9hcmNoaXZlLmh0bWwiPkpTREsyLjA8L2E+KQoraXMgaW5zdGFsbGVkIGFuZCBhbHNvIGFkZGVkIHRvIHRoZSB3ZWIgc2VydmVyJ3MKKzxicj5zeXN0ZW0gY2xhc3NwYXRoLiBKU0RLMi4wIGlzIGEgcmVmZXJlbmNlIGltcGxlbWVudGF0aW9uIG9mIHRoZSBTZXJ2bGV0CitBUEkgU3BlY2lmaWNhdGlvbiBWZXJzaW9uIDIuMC4KKzxwPldoZW4gcnVubmluZyBBcGFjaGUgSlNlcnYgaW4gYXV0b21hdGljIG1vZGUsIGFkZCB3cmFwcGVyLmNsYXNzcGF0aCBwcm9wZXJ0aWVzCitmb3IgZWFjaAorPGJyPm9mIHRoZXNlIGphciBmaWxlcyB0byB0aGUgc2VydmxldCBlbmdpbmUncyBwcm9wZXRpZXMgZmlsZS4gVGhlIGRlZmF1bHQKK2VuZ2luZSBwcm9wZXJ0aWVzIGZpbGUgaXMKKzxicj5qc2Vydi5wcm9wZXJ0aWVzIGFuZCBpcyB1c3VhbGx5IGZvdW5kIGluIEFwYWNoZSBKU2VydidzICdjb25mJyBkaXJlY3RvcnkuCitXcmFwcGVyIHByb3BlcnRpZXMKKzxicj5hcmUgdXNlZCB0byBhdXRvbWF0aWNhbGx5IHN0YXJ0IHRoZSBzZXJ2bGV0IGVuZ2luZS4KKzxwPihvbiBTb2xhcmlzKQorPGJsb2NrcXVvdGU+d3JhcHBlci5jbGFzc3BhdGg9L2ZpbGVzL2phdmEvbGliL0pTREsyLjAvbGliL2pzZGsuamFyCis8YnI+d3JhcHBlci5jbGFzc3BhdGg9L2ZpbGVzL2phdmEvbGliL2phdmFtYWlsLTEuMi9tYWlsLmphcgorPGJyPndyYXBwZXIuY2xhc3NwYXRoPS9maWxlcy9qYXZhL2xpYi9qYWYtMS4wLjEvYWN0aXZhdGlvbi5qYXI8L2Jsb2NrcXVvdGU+Cisob24gTlQpCis8YmxvY2txdW90ZT53cmFwcGVyLmNsYXNzcGF0aD1kOlxqYXZhXGxpYlxqc2RrMi4wXGxpYlxqc2RrLmphcgorPGJyPndyYXBwZXIuY2xhc3NwYXRoPWQ6XGphdmFcbGliXGphdmFtYWlsLTEuMlxtYWlsLmphcgorPGJyPndyYXBwZXIuY2xhc3NwYXRoPWQ6XGphdmFcbGliXGphZi0xLjAuMVxhY3RpdmF0aW9uLmphcjwvYmxvY2txdW90ZT4KK1doZW4gcnVubmluZyBBcGFjaGUgSlNlcnYgaW4gbWFudWFsIG1vZGUsIGFkZCB0aGVzZSBqYXIgZmlsZXMgdG8gdGhlIENMQVNTUEFUSAorPGJyPmVudmlyb25tZW50IHZhcmlhYmxlICh0aGlzIGlzIGRvY3VtZW50ZWQgaW4gdGhlIEphdmFNYWlsIFJFQURNRSBmaWxlCithbmQgYWRkaXRpb25hbAorPGJyPldpbmRvd3MgTlQgaW5mb3JtYXRpb24gaXMgcHJvdmlkZWQgPGEgaHJlZj0iY2xhc3NwYXRoLU5ULmh0bWwiPmhlcmU8L2E+KS4KKzxwPk9uY2UgdGhpcyBpcyBkb25lLCByZXN0YXJ0IHRoZSB3ZWIgc2VydmVyLgorPGJyPiZuYnNwOworPHA+QWRkaXRpb25hbCBOb3RlcworPGJsb2NrcXVvdGU+T25lIHRoaW5nIHRvIHdhdGNoIG91dCBmb3IgaXMgaG93IHRoZSB3ZWIgc2VydmVyIGlzIHJlZmVyZW5jZWQKK3doZW4gdXNpbmcgdGhlCis8YnI+SmF2YU1haWxTZXJ2bGV0IG9uIHRoaXMgd2ViIHNlcnZlci4mbmJzcDsgSXQgaXMgaW1wb3J0YW50IHRvIHVzZSB0aGUKK2NvbmZpZ3VyZWQgc2VydmVyCis8YnI+bmFtZSAoaS5lLiB0aGUgbmFtZSBhc3NpZ25lZCB3aXRoIHRoZSBTZXJ2ZXJOYW1lIGRpcmVjdGl2ZSkgaW4gdGhlCitVUkwuIElmIHRoZQorPGJyPmNvbmZpZ3VyZWQgc2VydmVyIG5hbWUgaW5jbHVkZXMgYSBkb21haW4sIGl0IG11c3QgYmUgcmVmZXJlbmNlZCBpbmNsdWRpbmcKK3RoZQorPGJyPmRvbWFpbiwgZXZlbiBpZiB0aGUgSmF2YU1haWwuaHRtbCBwYWdlIGNhbiBiZSBhY2Nlc3NlZCB3aXRob3V0IGl0LgorPHA+Rm9yIGV4YW1wbGUsIEFwYWNoZSBpcyBjb25maWd1cmVkIHdpdGggdGhlIFNlcnZlck5hbWUgc2V0IHRvICdzaGFkeWdyb3ZlJy4KK0lmIHRoZSBKYXZhTWFpbCBkZW1vIGlzIHJlZmVyZW5jZWQgYnk6Cis8cD4mbmJzcDsmbmJzcDsmbmJzcDsgaHR0cDovL3NoYWR5Z3JvdmUuZWFzdC9leGFtcGxlL0phdmFNYWlsLmh0bWwKKzxwPmFuZCB0aGUgaW5pdGFpbCByZWZlcmVuY2UgdG8gdGhlIEphdmFNYWlsU2VydmxldCBiZWluZzoKKzxwPiZuYnNwOyZuYnNwOyZuYnNwOyBodHRwOi8vc2hhZHlncm92ZS5lYXN0L2V4YW1wbGUvSmF2YU1haWxTZXJ2bGV0Cis8cD50aGUgdXNlciBpcyBzdWNjZXNzZnVsbHkgbG9nZ2VkIGluLiBIb3dldmVyLCB3aGVuIGFuIGF0dGVtcHQgaXMgbWFkZQordG8gYWNjZXNzIHRoZSBJTkJPWCwgdGhlIHVzZXIgaXMgaW5zdHJ1Y3RlZCB0byBsb2dpbiBiZWNhdXNlIHRoZXJlIGlzIG5vCitjdXJyZW50IHNlc3Npb24uIFdoZW4gdGhpcyBvY2N1cnMsIG5vdGUgdGhhdCB0aGUgVVJMIHJlZmVyZW5jaW5nIHRoZSBKYXZhTWFpbFNlcnZsZXQKK25vIGxvbmdlciBjb250YWlucyB0aGUgZG9tYWluIG9yaWdpbmFsbHkgdXNlZCBidXQgdGhlIGNvbmZpZ3VyZWQgU2VydmVyTmFtZS4KKzxwPiZuYnNwOyZuYnNwOyZuYnNwOyBodHRwOi8vc2hhZHlncm92ZS9leGFtcGxlL0phdmFNYWlsU2VydmxldAorPGJyPiZuYnNwOworPHA+QWxzbyBub3RlIHRoYXQgQXBhY2hlIEpTZXJ2IGRvZXMgbm90IHVzZSBhIFNlY3VyaXR5TWFuYWdlciBvciBlbmZvcmNlCithbnkgSmF2YQorPGJyPnNlY3VyaXR5IHBvbGljeS48L2Jsb2NrcXVvdGU+CisKKzwvYm9keT4KKzwvaHRtbD4KZGlmZiAtLWdpdCBhL2RvYy9yZWxlYXNlL0NIQU5HRVMudHh0IGIvZG9jL3JlbGVhc2UvQ0hBTkdFUy50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTY1MTQxZgotLS0gL2Rldi9udWxsCisrKyBiL2RvYy9yZWxlYXNlL0NIQU5HRVMudHh0CkBAIC0wLDAgKzEsODA0IEBACitZb3UgY2FuIGZpbmQgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBlYWNoIGJ1ZyBudW1iZXIgYnkgdmlzaXRpbmcgdGhlCitJc3N1ZSBUcmFja2VyIGFuZCBsb29raW5nIHVwIGVhY2ggYnVnIHlvdSdyZSBpbnRlcmVzdGVkIGluLgorCitCdWcgSURzIHRoYXQgc3RhcnQgd2l0aCAiRSIgY2FuIGJlIGZvdW5kIGluIHRoZSBHaXRIdWIgSXNzdWUgVHJhY2tlcgorZm9yIHRoZSBFY2xpcHNlIEVFNEogSmF2YU1haWwgcHJvamVjdCAoYWZ0ZXIgcmVtb3ZpbmcgdGhlICJFIik6CisKKwlodHRwczovL2dpdGh1Yi5jb20vZWNsaXBzZS1lZTRqL2phdmFtYWlsL2lzc3Vlcy88YnVnLW51bWJlcj4KKworQnVnIElEcyB0aGF0IHN0YXJ0IHdpdGggIkdIIiBjYW4gYmUgZm91bmQgaW4gdGhlIEdpdEh1YiBJc3N1ZSBUcmFja2VyCisoYWZ0ZXIgcmVtb3ZpbmcgdGhlICJHSCIpOgorCisJaHR0cHM6Ly9naXRodWIuY29tL2phdmFlZS9qYXZhbWFpbC9pc3N1ZXMvPGJ1Zy1udW1iZXI+CisKK0J1ZyBJRHMgdGhhdCBzdGFydCB3aXRoICJHIiBjYW4gYmUgZm91bmQgaW4gdGhlIEdsYXNzRmlzaCBJc3N1ZSBUcmFja2VyCisoYWZ0ZXIgcmVtb3ZpbmcgdGhlICJHIik6CisKKwlodHRwczovL2dpdGh1Yi5jb20vamF2YWVlL2dsYXNzZmlzaC9pc3N1ZXMvPGJ1Zy1udW1iZXI+CisKK1NldmVuIGRpZ2l0IGJ1ZyBudW1iZXJzIGFyZSBmcm9tIHRoZSBvbGQgU3VuIGJ1ZyBkYXRhYmFzZSwgd2hpY2ggaXMgbm8KK2xvbmdlciBhdmFpbGFibGUuCisKKworCQkgIENIQU5HRVMgSU4gVEhFIDEuNi4zIFJFTEVBU0UKKwkJICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCitUaGUgZm9sbG93aW5nIGJ1Z3MgaGF2ZSBiZWVuIGZpeGVkIGluIHRoZSAxLjYuMyByZWxlYXNlLgorCitFICAzNDgJQ2hhbmdlIE1hdmVuIGNvb3JkaW5hdGVzIHRvIG1hdGNoIEVFNEogYW5kIEpha2FydGEgRUUgY29udmVudGlvbnMKKworCisJCSAgQ0hBTkdFUyBJTiBUSEUgMS42LjIgUkVMRUFTRQorCQkgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK1RoZSBmb2xsb3dpbmcgYnVncyBoYXZlIGJlZW4gZml4ZWQgaW4gdGhlIDEuNi4yIHJlbGVhc2UuCisKK0dIICAzMDYJSW5maW5pdGUgbG9vcCBwYXJzaW5nIGludmFsaWQgSUQgcmVzcG9uc2UKK0dIICAzMDcJU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB3aGVuICoucHJveHkuaG9zdCBjb250YWlucyBhIGNvbG9uCitHSCAgMzA5CU11bHRpcGFydCBDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nIHRyYWlsaW5nIHNwYWNlCitHSCAgMzEwCUFuZHJvaWQgYXBwIGZhaWxzIHRvIGJ1aWxkIHdpdGggSmF2YU1haWwgMS42LjEKK0dIICAzMTQJSW50ZXJuZXRBZGRyZXNzIGZhaWxzIHRvIGRldGVjdCBpbGxlZ2FsIHNxdWFyZSBicmFja2V0cyBpbiBsb2NhbCBwYXJ0CitHSCAgMzE1CWVtcHR5IENvbnRlbnQtVHJhbnNmZXItRW5jb2RpbmcgaGVhZGVyIGNhdXNlcyBJT0V4Y2VwdGlvbgorR0ggIDMxNglzdGFydHRscy5lbmFibGUgZG9jdW1lbnRhdGlvbiBzaG91bGQgcmVmZXJlbmNlIHN0YXJ0dGxzLnJlcXVpcmVkIHByb3AKK0dIICAzMTcJdXNlIFN5c3RlbS5saW5lU2VwYXJhdG9yKCkgaW5zdGVhZCBvZiBTeXN0ZW0uZ2V0UHJvcGVydHkoLi4uKQorR0ggIDMyMQlVUkxOYW1lLmdldFVSTCgpIHJldHVybnMgaW5jb3JyZWN0IHVybC4KK0dIICAzMjIJRG90cyBpbiBsb2NhbCBwYXJ0IG9mIGVtYWlscyBub3QgaGFuZGxlZCBwcm9wZXJseQorR0ggIDMyMwlTdXBwb3J0IGxvYWRpbmcgcHJvdG9jb2wgcHJvdmlkZXJzIHVzaW5nIFNlcnZpY2VMb2FkZXIKK0dIICAzMjYJQXBwbHkgcmVsYXhlZCBDb250ZW50LURpc3Bvc2l0aW9uIHBhcnNpbmcgdG8gQ29udGVudC1EaXNwb3NpdGlvbiBwYXJhbXMKK0dIICAzMzAJQXR0YWNobWVudCBmaWxlbmFtZSBpcyBpZ25vcmVkCitHSCAgMzMyCWh0dHAgcHJveHkgc3VwcG9ydCBzaG91bGQgc3VwcG9ydCBhdXRoZW50aWNhdGluZyB0byB0aGUgcHJveHkgc2VydmVyCitHSCAgMzMzCXNlYXJjaCB3aXRoIFVuaWNvZGUgY2hhciB0aHJvd3MgQmFkQ29tbWFuZEV4Y2VwdGlvbiB3aXRoIFVURjg9QUxMT1cKK0dIICAzMzQJZ2ltYXAgc2V0IGxhYmVscyBlcnJvciB3aXRoIHNvbWUgbm9uIGVuZ2xpc2ggY2hhcmFjdGVycworCisKKwkJICBDSEFOR0VTIElOIFRIRSAxLjYuMSBSRUxFQVNFCisJCSAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorVGhlIGZvbGxvd2luZyBidWdzIGhhdmUgYmVlbiBmaXhlZCBpbiB0aGUgMS42LjEgcmVsZWFzZS4KKworR0ggIDI2MglTb21lIElNQVAgc2VydmVycyBzZW5kIEVYUFVOR0UgcmVzcG9uc2VzIGZvciB1bmtub3duIG1lc3NhZ2VzCitHSCAgMjc4CUJPRFlTVFJVQ1RVUkUgUGFyc2VyIGZhaWxzIG9uIHNwZWNpZmljIElNQVAgU2VydmVyIHJlc3BvbnNlIAorR0ggIDI4MwljbGVhbiB1cCBjb25uZWN0aW9ucyB3aGVuIGNsb3NpbmcgSU1BUFN0b3JlCitHSCAgMjg3CUFsbG93IHJlbGF4ZWQgQ29udGVudC1EaXNwb3NpdGlvbiBwYXJzaW5nCitHSCAgMjg5CXVzZSBhIGRpZmZlcmVudCBJTUFQIHRhZyBwcmVmaXggZm9yIGVhY2ggY29ubmVjdGlvbgorR0ggIDI5MQlkZWZpbmUgSkRLIDkgbW9kdWxlIG5hbWUgZm9yIEphdmFNYWlsCitHSCAgMjk2CUhUVFAgcHJveHkgc3VwcG9ydCBuZWVkcyB0byB1c2UgSFRUUC8xLjEKKworCisJCSAgQ0hBTkdFUyBJTiBUSEUgMS42LjAgUkVMRUFTRQorCQkgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK1RoZSBmb2xsb3dpbmcgYnVncyBoYXZlIGJlZW4gZml4ZWQgaW4gdGhlIDEuNi4wIHJlbGVhc2UuCisKK0dIICAgNzUJTWltZU11bHRpcGFydCBzaG91bGQgdGhyb3cgUGFyc2VFeGNlcHRpb24gZm9yIHBhcnNpbmcgZXJyb3JzCitHSCAgIDc3CU1pbWVNZXNzYWdlLnVwZGF0ZUhlYWRlcnMgc2hvdWxkIHNldCB0aGUgRGF0ZSBoZWFkZXIgaWYgbm90IGFscmVhZHkgc2V0CitHSCAgIDkzCVN1cHBvcnQgYWRkcmVzc2luZyBpMThuIHZpYSBSRkMgNjUzMC82NTMxLzY1MzIKK0dIICAxMDQJVGhlIFVJREZvbGRlciBpbnRlcmZhY2Ugc2hvdWxkIGhhdmUgYSBnZXR0ZXIgZm9yIFVJRE5FWFQKK0dIICAxMzUJTWFpbEhhbmRsZXIgc2hvdWxkIGNob29zZSBhIGJldHRlciBkZWZhdWx0IHN1YmplY3QgZm9ybWF0dGVyLgorR0ggIDE1OQlTdG9yZSwgVHJhbnNwb3J0LCBhbmQgRm9sZGVyIHNob3VsZCBpbXBsZW1lbnQgQXV0b0Nsb3NlYWJsZQorR0ggIDE3NAlNYWlsRGF0ZUZvcm1hdCBjaGFuZ2VzIGZvciB2ZXJzaW9uIDEuNgorR0ggIDE4MwlGaXggamF2YWMgd2FybmluZ3MKK0dIICAyMDkJZmFpbHMgdG8gcGFyc2Ugc29tZSBmZXRjaCByZXNwb25zZSB0aGF0IGhhcyBzcGFjZSBiZWZvcmUgZmluYWwgJyknCitHSCAgMjE0CUlNQVAgZG9lc24ndCBoYW5kbGUgaWxsZWdhbCBDQVBBQklMSVRZIHJlc3BvbnNlIGFmdGVyIExPR0lOL0FVVEhFTlRJQ0FURQorR0ggIDIyNglNYWlsU2Vzc2lvbkRlZmluaXRpb24gc2hvdWxkIHVzZSB0aGUgUmVwZWF0YWJsZSBhbm5vdGF0aW9uIGZvciBKYXZhIEVFIDgKK0dIICAyMjcJSWRsZU1hbmFnZXIgZmFpbHMgb24gQW5kcm9pZAorR0ggIDIyOAlUZXN0IGZhaWxzOiBqYXZheC5tYWlsLmludGVybmV0LkdldExvY2FsQWRkcmVzc1Rlc3QKK0dIICAyMjkJVGVzdHMgZmFpbDogY29tLnN1bi5tYWlsLnV0aWwuV3JpdGVUaW1lb3V0U29ja2V0VGVzdAorR0ggIDIzMAlNYm94Rm9sZGVyLmV4cHVuZ2UgY2FuIGNvcnJ1cHQgbWFpbGJveCBmaWxlCitHSCAgMjMxCUNvbXBhY3RGb3JtYXR0ZXIgc2hvdWxkIGhhbmRsZSBvdmVycmlkZGVuIFRocm93YWJsZS50b1N0cmluZyBtZXRob2RzCitHSCAgMjMyCVVwZGF0ZSBwdWJsaWMgQVBJIHRvIHVzZSBnZW5lcmljcworR0ggIDIzMwlNYWxmb3JtZWQgSU1BUCBGRVRDSCByZXNwb25zZSB0aHJvd3MgdGhlIHdyb25nIGV4Y2VwdGlvbgorR0ggIDIzNAlSRkM4MjIuU0laRSA+IDJHQiBpc24ndCBoYW5kbGVkCitHSCAgMjM3CVByb3RvY29sI2NvbW1hbmQgbWV0aG9kIGNhbGwgcmVhZFJlc3BvbnNlIGFmdGVyIElPRXhjZXB0aW9uIGlzIHRocm93bgorR0ggIDIzOAlQb3NzaWJsZSBOUEUgaW4gU3RhdHVzLjxpbml0PiBsaW5lIDk2CitHSCAgMjM5CU1haWxIYW5kbGVyIHNob3VsZCBzdXBwb3J0ICdsb2dpbicgdmVyaWZ5IHR5cGUuCitHSCAgMjQwCU1haWxIYW5kbGVyIHN1cHBvcnQgZm9yIG5vbi1tdWx0aXBhcnQgbWVzc2FnZXMKK0dIICAyNDEJdXNlIG9mIFlvdW5nZXJUZXJtL09sZGVyVGVybSBvbiBzZXJ2ZXIgd2l0aG91dCBXSVRISU4gc3VwcG9ydCBmYWlscworR0ggIDI0NAlUaGUgVUlERm9sZGVyIGludGVyZmFjZSBzaG91bGQgaGF2ZSBhIE1BWFVJRCBjb25zdGFudAorR0ggIDI0NQlqYXZhLmlvLklPRXhjZXB0aW9uOiBObyBjb250ZW50IHdoZW4gcmVhZGluZyBtc2cgd2l0aCBlbXB0eSBhdHRhY2htZW50CitHSCAgMjQ3CWxvb2sgZm9yIHJlc291cmNlIGZpbGVzIGluIDxqYXZhLmhvbWU+L2NvbmYgb24gSkRLIDEuOQorR0ggIDI0OAlNaW1lVXRpbGl0eSBzaG91bGQgdHJlYXQgR0IyMzEyIGFzIG9uZSBvZiB0aGUgc3VwZXJzZXRzIEdCSyBvciBHQjE4MDMwCitHSCAgMjQ5CUZsYWdzIGNvbnZlbmllbmNlIG1ldGhvZHMKK0dIICAyNTAJU01UUCBzdXBwb3J0IGZvciB0aGUgQ0hVTktJTkcgZXh0ZW5zaW9uIG9mIFJGQyAzMDMwCitHSCAgMjUxCU1pbWVVdGlsaXR5LnVuZm9sZCBzcXVhc2hlcyBtdWx0aXBsZSBzcGFjZXMKK0dIICAyNTIJSmF2YU1haWwgUExBSU4gYXV0aGVudGljYXRpb24gc2hvdWxkIGltcGxlbWVudCBSRkMgNDYxNgorR0ggIDI1MwlTdXBwb3J0IGNvbm5lY3RpbmcgdGhyb3VnaCB3ZWIgcHJveHkgc2VydmVycworR0ggIDI1NglzdXBwb3J0IFVJRFBMVVMgVUlETk9UU1RJQ0tZIHJlc3BvbnNlIGNvZGUKK0dIICAyNTcJU0FTTCBhdXRoZW50aWNhdGlvbiBzaG91bGQgYWx3YXlzIGFsbG93IFVURi04IHVzZXJuYW1lIGFuZCBwYXNzd29yZAorR0ggIDI1OAlhbmRyb2lkLWFjdGl2YXRpb24gTUFOSUZFU1QgaGFzIGVtcHR5IEJ1bmRsZS1TeW1ib2xpY05hbWUKKworCisJCSAgQ0hBTkdFUyBJTiBUSEUgMS41LjYgUkVMRUFTRQorCQkgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK1RoZSBmb2xsb3dpbmcgYnVncyBoYXZlIGJlZW4gZml4ZWQgaW4gdGhlIDEuNS42IHJlbGVhc2UuCisKK0dIICAxOTkJU3VwcG9ydCBMb2dSZWNvcmQuc2V0TWlsbGlzIGJlaW5nIGRlcHJlY2F0ZWQgaW4gSkRLIDkKK0dIICAyMDAJTG9nZ2luZyBzaG91bGQgc3VwcG9ydCBMb2dSZWNvcmQuZ2V0SW5zdGFudAorR0ggIDIwMglDcmVhdGUgY29tbW9uIHN1cGVyIGNsYXNzIGZvciBsb2dnaW5nIHRlc3RzCitHSCAgMjA1CU5QRSBieSBBUE9QIGRldGVjdGlvbiB3aGVuIG5vIGdyZWV0aW5nIGJhbm5lcgorR0ggIDIwNglNYWtlIElNQVBQcm90b2NvbC5oYW5kbGVMb2dpblJlc3VsdCBwcm90ZWN0ZWQKK0dIICAyMDcJSW50ZXJuZXRBZGRyZXNzLnBhcnNlIGZhaWxzIGZvciB2YWxpZCBkb21haW4gbGl0ZXJhbCBhZGRyZXNzCitHSCAgMjEwCXVuc29saWNpdGVkIEZFVENIIHJlc3BvbnNlICptdXN0KiBpbnZhbGlkYXRlIFgtR00tTEFCRUxTIGluIGNhY2hlCitHSCAgMjExCU1pbWVCb2R5UGFydC5pc01pbWVUeXBlIHJldHVybnMgZmFsc2UgaWYgdHlwZSBoZWFkZXIgY2FuJ3QgYmUgcGFyc2VkCitHSCAgMjEzCU5QRSBpbiBUb21jYXQgQ2xhc3NMb2FkZXIgY2F1c2VzIFNlc3Npb24uZ2V0SW5zdGFuY2UgdG8gZmFpbAorR0ggIDIxNQlEZWFkbG9jayBpbiBJTUFQRm9sZGVyLmRvUHJvdG9jb2xDb21tYW5kKCkKK0dIICAyMTYJSW50ZXJuZXRBZGRyZXNzLmdldExvY2FsQWRkcmVzcyBzaG91bGQgdXNlCisJSW5ldEFkZHJlc3MuZ2V0Q2Fub25pY2FsSG9zdE5hbWUKK0dIICAyMTcJU3RvcmUgZmluYWxpemVycyBzaG91bGQgbm90IHRhbGsgdG8gc2VydmVyCitHSCAgMjE5CU1haWxIYW5kbGVyIHZlcmlmeSBzaG91bGQgbG9hZCBhZGRpdGlvbmFsIGNvbnRlbnQgaGFuZGxlcnMKK0dIICAyMjAJTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgU0FTTCBpcyBlbmFibGVkIG9uIEFuZHJvaWQKK0dIICAyMjEJd3JpdGUgdGltZW91dHMgZG9uJ3Qgd29yayB3aXRoIFNTTCBvbiBBbmRyb2lkCitHSCAgMjIyCUphdmFNYWlsIGFsbG93cyBpbmplY3Rpb24gb2YgdW53YW50ZWQgaGVhZGVycworR0ggIDIyMwlNZXNzYWdlLnNldFJlY2lwaWVudCh0eXBlLCBudWxsKSBzaG91bGQgcmVtb3ZlIHJlY2lwaWVudHMKKworCisJCSAgQ0hBTkdFUyBJTiBUSEUgMS41LjUgUkVMRUFTRQorCQkgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK1RoZSBmb2xsb3dpbmcgYnVncyBoYXZlIGJlZW4gZml4ZWQgaW4gdGhlIDEuNS41IHJlbGVhc2UuCisKK0dIICAxNjgJYWRkIHN1cHBvcnQgZm9yIHNldHRpbmcgR01haWwgbGFiZWxzIG9uIG1lc3NhZ2VzCitHSCAgMTY5CUFkZCBzcGFtIGZpbHRlciBmb3IgdXNlIHdpdGggTWFpbEhhbmRsZXIuCitHSCAgMTcwCUFkZHJlc3MgTWFpbERhdGVGb3JtYXQgaXNzdWVzCitHSCAgMTcyCVR5cG8gaW4gIm1haWwuc3RtcC5zZW5kcGFydGlhbCIKK0dIICAxNzMJbWFpbC5taW1lLmVuY29kZWZpbGVuYW1lIHByb3BlcnR5IHNob3VsZCBvdmVycmlkZSBSRkMgMjIzMSBlbmNvZGluZworR0ggIDE3NglJTUFQIHNob3VsZCBzdXBwb3J0IGEgbWFpbC5pbWFwLmF1dGgubWVjaGFuaXNtcyBwcm9wZXJ0eSBsaWtlIFNNVFAKK0dIICAxNzcJc2V0dGluZyBtYWlsLjxwcm90b2NvbD4uYXV0aC5tZWNoYW5pc21zIHNob3VsZCBvdmVycmlkZQorCW1haWwuPHByb3RvY29sPi5hdXRoLjxtZWNoYW5pc20+LmRpc2FibGUKK0dIICAxNzgJYWRkIHN1cHBvcnQgZm9yIE9BdXRoIDIuMCB3aXRob3V0IFNBU0wKK0dIICAxNzkJY2FwYWJpbGl0eSgpIGNvbW1hbmQgZG9lc24ndCBwcm9wZXJseSB0cmFuc2Zvcm0gZXJyb3JzCitHSCAgMTgwCU1haWxIYW5kbGVyIG5lZWRzIGJldHRlciBzdXBwb3J0IGZvciBzdGF0ZWZ1bCBmaWx0ZXJzLgorR0ggIDE4MQlhZGQgc3VwcG9ydCBmb3IgSU1BUCBsb2dpbiByZWZlcnJhbHMgKFJGQyAyMjIxKQorR0ggIDE4Mgl3aGl0ZXNwYWNlIGxpbmUgYXQgYmVnaW5uaW5nIGNvbmZ1c2VzIEludGVybmV0SGVhZGVycworR0ggIDE4NAlFbGltaW5hdGUgbGVnYWN5IGNsYXNzZXMKK0dIICAxODUJSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiByZWFkaW5nIElNQVAgbGl0ZXJhbCB3aGVuIGNvbm5lY3Rpb24gZmFpbHMKK0dIICAxODYJSWRsZU1hbmFnZXIgZGllcyB3aXRoIENhbmNlbGxlZEtleUV4Y2VwdGlvbgorR0ggIDE4NwlJZGxlTWFuYWdlciBjYW4gZGVhZGxvY2sgd2hlbiBub3QgYnVzeQorR0ggIDE4OAlJTUFQIEZvbGRlciBtZXRob2RzIHRocm93IHJ1bnRpbWUgZXhjZXB0aW9ucyB3aGVuIGNvbm5lY3Rpb24gZHJvcHMKK0dIICAxODkJSW50ZXJuZXRBZGRyZXNzIGRvZXNuJ3QgZGV0ZWN0IHNvbWUgaWxsZWdhbCBuZXdsaW5lcworR0ggIDE5MAlTdGF0dXMgY2xhc3MgZG9lc24ndCBkZWNvZGUgbWFpbGJveCBuYW1lCitHSCAgMTkxCWFkZCBzdXBwb3J0IGZvciBJTUFQIENPTVBSRVNTIGV4dGVuc2lvbiAoUkZDIDQ5NzgpCitHSCAgMTk0CUVtcHR5IEdtYWlsIFgtR00tTEFCRUxTIGxpc3QgaXMgbWlzcGFyc2VkCitHSCAgMTk1CUlNQVBNZXNzYWdlLmdldFJlY2VpdmVkRGF0ZSBzaG91bGQgY2hlY2sgaWYgcmVjZWl2ZWREYXRlIGlzIHByZXNlbnQKKwliZWZvcmUgbG9hZGluZyBlbnZlbG9wZQorR0ggIDE5NglDb2xsZWN0b3JGb3JtYXR0ZXIgZGVzY2VuZGluZyBvcmRlciBkYXRhIHJhY2UKK0dIICAxOTgJb2ZmLWJ5LTEgZXJyb3IgaW4gUmVzcG9uc2UucmVhZFN0cmluZ0xpc3QgY2F1c2VzIGVhcmx5IHRlcm1pbmF0aW9uIG9mCisJcGFyc2luZyBGRVRDSCByZXNwb25zZQorR0ggIDIwMQlJTlRFUk5BTERBVEUgRmV0Y2hQcm9maWxlIEl0ZW0KK0dIICAyMDMJRXhjaGFuZ2UgcmV0dXJucyBOSUwgaW5zdGVhZCBvZiAiIiBmb3IgZW1wdHkgcGFyYW1ldGVyLCBjYXVzaW5nIE5QRQorCisKKwkJICBDSEFOR0VTIElOIFRIRSAxLjUuNCBSRUxFQVNFCisJCSAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorVGhlIGZvbGxvd2luZyBidWdzIGhhdmUgYmVlbiBmaXhlZCBpbiB0aGUgMS41LjQgcmVsZWFzZS4KKworR0ggIDE0OQlJbmNsdWRlIGVsYXBzZWQgdGltZSwgdGhyZWFkIGlkLCBhbmQgc2VxdWVuY2UgZm9yIGxvZ2dpbmcgZm9ybWF0dGVycy4KK0dIICAxNTMJTWFpbEhhbmRsZXJUZXN0IGRvZXMgbm90IGNoZWNrIGZpZWxkIGlzIHN0YXRpYyBvciBmaW5hbAorR0ggIDE1NwlJZGxlTWFuYWdlciBjYW4gZGVhZGxvY2sgd2l0aCBmcmVxdWVudCBub3RpZmljYXRpb25zCitHSCAgMTU4CUlkbGVNYW5hZ2VyIGNhbiBkZWFkbG9jayB3aGVuIGNvbm5lY3Rpb24gZmFpbHMKK0dIICAxNjAJSU1BUCBwcm92aWRlciBzaG91bGQgc3VwcG9ydCB0aGUgTU9WRSBleHRlbnNpb24gKFJGQyA2ODUxKQorR0ggIDE2MglNT0RTRVEgc2hvdWxkIGJlIHN0b3JlZCBpbiBJTUFQTWVzc2FnZSBpZiBDT05EU1RPUkUgaXMgZW5hYmxlZAorR0ggIDE2MwlTcGFjZSBjaGFyYWN0ZXIgbG9zdCBmcm9tIGVuZCBvZiBxdW90ZWQtcHJpbnRhYmxlIGJvZHkgcGFydHMKK0dIICAxNjQJR21haWxNZXNzYWdlIGV4dGVuc2lvbnMgYXJlIG5vdCBjYWNoZWQgYWZ0ZXIgaW1wbGljaXQgRkVUQ0gKK0dIICAxNjUJSU1BUCBtZXNzYWdlIHNldHMgc2hvdWxkIGJlIHNvcnRlZCBpbiBjYXNlcyB3aGVyZSBvcmRlciBkb2Vzbid0IG1hdHRlcgorR0ggIDE2NglJRCBjb21tYW5kIHNob3VsZG4ndCBlc2NhcGUgTklMIHZhbHVlCitHSCAgMTY3CU1ha2UgSU1BUFByb3RvY29sIGNsYXNzIGV4dGVuZGFibGUKKworCisJCSAgQ0hBTkdFUyBJTiBUSEUgMS41LjMgUkVMRUFTRQorCQkgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK1RoZSBmb2xsb3dpbmcgYnVncyBoYXZlIGJlZW4gZml4ZWQgaW4gdGhlIDEuNS4zIHJlbGVhc2UuCisKK0dIICAxMjIJTWFrZSBjb25zdHJ1Y3RvciBvZiBQT1AzRm9sZGVyIHByb3RlY3RlZCB0byBhbGxvdyBzdWJjbGFzc2luZworR0ggIDEyMwljYWxsaW5nIElkbGVNYW5hZ2VyLndhdGNoIHR3aWNlIG9uIHNhbWUgZm9sZGVyIGZhaWxzCitHSCAgMTI0CU5QRSBpbiBJTUFQRm9sZGVyLmNvcHlVSURNZXNzYWdlcyB3aGVuIENPUFlVSUQgbm90IHJldHVybmVkCitHSCAgMTI3CU1lc3NhZ2UtSWQgbGVha3MgY3VycmVudCB1c2VyL2hvc3RuYW1lIG9mIHRoZSBKYXZhIHByb2Nlc3MgKHNlY3VyaXR5KQorR0ggIDEyOAlJTUFQIGlkbGUgYnJlYWtzIGludGVycnVwdCBmbGFnCitHSCAgMTI5CURhdGUgc2VhcmNoIHRlcm1zIHJlc3VsdCBpbiB3cm9uZyBncmVhdGVyLXRoYW4gU0VBUkNIIGNvbW1hbmRzIGZvciBJTUFQCitHSCAgMTMxCWFkZHJlc3Mgc2ltaWxhciB0byAoeCk8eT4oeikgd2lsbCB0aHJvdyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCitHSCAgMTMyCVVwZGF0ZSBsb2dnaW5nIGRlbW9zIHRvIHVzZSB0aGUgbmV3IDEuNS4yIGZlYXR1cmVzCitHSCAgMTMzCVVzZSBjbGFzc2xvYWRlciBlcmdvbm9taWNzIGluIHRoZSBNYWlsSGFuZGxlcgorR0ggIDEzNwlBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaW4gSU1BUEZvbGRlci5jb3B5VUlETWVzc2FnZXMKK0dIICAxMzgJYXR0YWNobWVudCBmaWxlbmFtZXMgYXJlbid0IGJlaW5nIGVuY29kZWQgYnkgZGVmYXVsdAorR0ggIDEzOQlJbmNsdWRlIGphdmFkb2MgZXhhbXBsZSBmb3JtYXRzIGZvciBsb2dnaW5nLgorR0ggIDE0MQlTaGFyZWRGaWxlSW5wdXRTdHJlYW0gaGFzIHByb2JsZW1zIHdpdGggMkdCKyBmaWxlcworR0ggIDE0MwlNaW1lQm9keVBhcnQgd2l0aCBjb3BpZWQgRGF0YUhhbmRsZXIgZG9lc24ndCBhbHdheXMgc2V0IGVuY29kaW5nCitHSCAgMTQ0CXNraXAgdW51c2FibGUgU3RvcmUgYW5kIFRyYW5zcG9ydCBjbGFzc2VzCitHSCAgMTQ1CWxvbmcgcGFyYW1ldGVyIHZhbHVlcyBzaG91bGQgYmUgc3BsaXQgdXNpbmcgUkZDIDIyMzEKK0dIICAxNDYJamF2YXgubWFpbC5BdXRoZW50aWNhdG9yIHRocmVhZCBzYWZldHkKK0dIICAxNDgJTW9kaWZ5IE1haWxIYW5kbGVyIHRvIHN1cHBvcnQgR29vZ2xlIEFwcCBFbmdpbmUuCitHSCAgMTUwCUVYUFVOR0UgcmVzcG9uc2UgZHVyaW5nIFVJRCBGRVRDSCBicmVha3MgVUlELT5zZXFudW0gbWFwcGluZworR0ggIDE1MQlBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gY2F1c2VkIGJ5IG91dC1vZi1yYW5nZSBJTUFQIHJlc3BvbnNlcworR0ggIDE1NAl3cml0ZSB0aW1lb3V0cyBkb24ndCB3b3JrIHdpdGggYSBjdXN0b20gU1NMIHNvY2tldCBmYWN0b3J5CitHSCAgMTU1CVNNVFAgU0FTTCBESUdFU1QtTUQ1IGZhaWxzIG9uIHBvc3RmaXggc2luY2UgdGhlIGxhc3QgcmVwbHkgc2VudCBpcyAiKiIKKworCisJCSAgQ0hBTkdFUyBJTiBUSEUgMS41LjIgUkVMRUFTRQorCQkgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK1RoZSBmb2xsb3dpbmcgYnVncyBoYXZlIGJlZW4gZml4ZWQgaW4gdGhlIDEuNS4yIHJlbGVhc2UuCisKK0dIICAgNTcJYWxsb3cgSU1BUCBzZWFyY2ggdG8gdGhyb3cgU2VhcmNoRXhjZXB0aW9uIHdoZW4gc2VhcmNoIGlzIHRvbyBjb21wbGV4CitHSCAgIDg4CU51bGxQb2ludGVyRXhjZXB0aW9uIGF0IElNQVBGb2xkZXIjZ2V0TWVzc2FnZXNCeVVJRCBpZiBtc2cgbm90IGZvdW5kCitHSCAgIDg5CWFkZCBvcHRpb24gdG8gdXNlIGNhbm9uaWNhbCBob3N0IG5hbWUgZm9yIFNBU0wKK0dIICAgOTAJSU1BUCBhc3RyaW5nIHBhcnNpbmcgaW5jb3JyZWN0CitHSCAgIDkxCVNNVFAgU0FTTCBzdXBwb3J0IGRvZXNuJ3QgaGFuZGxlIGF1dGhlbnRpY2F0aW9uIGZhaWx1cmUgcHJvcGVybHkKK0dIICAgOTIJU0FTTCBhdXRoZW50aWNhdGlvbiBmYWlsdXJlcyBzaG91bGQgbm90IHRyeSBvdGhlciBtZXRob2RzCitHSCAgIDk0CWFkZCBPQXV0aDIgc3VwcG9ydCB0byBKYXZhTWFpbAorR0ggICA5NQlJTUFQIGZhaWx1cmVzIGR1cmluZyBjbG9zZSBjYW4gbGVhdmUgY29ubmVjdGlvbiB1bnVzYWJsZQorR0ggICA5NgluZWVkIHdheSB0byBtb25pdG9yIElNQVAgcmVzcG9uc2VzCitHSCAgIDk3CU1pbWVVdGlsaXR5LmVuY29kZVRleHQoKSBkb2VzIG5vdCB3b3JrIHdpdGggVW5pY29kZSBzdXJyb2dhdGUgcGFpcnMKK0dIICAxMDUJSU1BUCBhbGVydHMgYW5kIG5vdGlmaWNhdGlvbnMgYXJlIG5vdCBzZW50IGR1cmluZyBhdXRoZW50aWNhdGlvbgorR0ggIDEwNglhZGQgYWJpbGl0eSB0byBmZXRjaCBhbmQgY2FjaGUgZW50aXJlIElNQVAgbWVzc2FnZQorR0ggIDEwNwlhZGQgYWJpbGl0eSB0byByZXR1cm4gc2VydmVyLXNwZWNpZmljIFNUQVRVUyByZXNwb25zZXMKK0dIICAxMDgJYWRkIGFiaWxpdHkgdG8gc2V0ICJwZWVrIiBmbGFnIGZvciBhbGwgSU1BUCBtZXNzYWdlcworR0ggIDEwOQlhZGQgYWJpbGl0eSB0byBzcGVjaWZ5IHNjb3BlIG9mIGV2ZW50IHF1ZXVlCitHSCAgMTEwCWFkZCBhYmlsaXR5IHRvIHNwZWNpZnkgYW4gRXhlY3V0b3IgdG8gcHJvY2VzcyBldmVudHMKK0dIICAxMTMJaGFuZGxlIG11bHRpcGxlIElNQVAgQk9EWSBlbGVtZW50cyBpbiBhIHNpbmdsZSBGRVRDSCByZXNwb25zZQorR0ggIDExNQlhZGQgbW9yZSBlZmZpY2llbnQgd2F5IHRvIG1vbml0b3IgbXVsdGlwbGUgZm9sZGVycyBmb3IgbmV3IG1lc3NhZ2VzCitHSCAgMTE2CUluY2x1ZGUgYSBzdWJqZWN0IGZvcm1hdHRlciBmb3IgdGhlIGxvZ2dpbmcgcGFja2FnZQorR0ggIDExOAlCcm9rZW4gZXF1YWxzIGluIFVSTE5hbWUsIE5ld3NBZGRyZXNzCitHSCAgMTE5CU51bGxQb2ludGVyRXhjZXB0aW9uIGluIENvbnRlbnRUeXBlLm1hdGNoCitHSCAgMTIwCWhhc2hDb2RlIG9mIHR3byBlcXVhbHMgaW5zdGFuY2VzIGRvZXMgbm90IG1hdGNoIGZvciBNb2RpZmllZFNpbmNlVGVybSwKKwlZb3VuZ2VyVGVybSwgT2xkZXJUZXJtCitHSCAgMTIxCU51bGxQb2ludGVyRXhjZXB0aW9uIGluIEludGVybmV0QWRkcmVzcworCisKKwkJICBDSEFOR0VTIElOIFRIRSAxLjUuMSBSRUxFQVNFCisJCSAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorVGhlIGZvbGxvd2luZyBidWdzIGhhdmUgYmVlbiBmaXhlZCBpbiB0aGUgMS41LjEgcmVsZWFzZS4KKworR0ggICA2NglXcm9uZyAic291cmNlIiB2ZXJzaW9uIGluIGJ1aWxkLnByb3BlcnRpZXMKK0dIICAgNjcJSU1BUCBwcm92aWRlciBzaG91bGQgc3VwcG9ydCB0aGUgUVJFU1lOQyBleHRlbnNpb24gKFJGQyA1MTYyKQorR0ggICA2OAlJTUFQIHByb3ZpZGVyIHNob3VsZCBzdXBwb3J0IHRoZSBXSVRISU4gc2VhcmNoIGV4dGVuc2lvbiAoUkZDIDUwMzIpCitHSCAgIDY5CUphdmFNYWlsIGRvZXMgbm90IGhhbmRsZSB3cml0ZSB0aW1lb3V0cworR0ggICA3MAltZXRob2QgZmlsbCgpIGlzbid0IHN5bmNocm9uaXplZCBjb3JyZWN0bHkgaW4gU2hhcmVkRmlsZUlucHV0U3RyZWFtCitHSCAgIDcxCU51bGxQb2ludGVyRXhjZXB0aW9uIGluIE1pbWVVdGlsaXR5I3F1b3RlKCkKK0dIICAgNzIJc3VwcG9ydCBSRkMgMjM1OSBDT1BZVUlEIHJlc3BvbnNlIGNvZGUKK0dIICAgNzMJRW1wdHkgRlJPTSBGaWVsZCBjYXVzZXMgRXhjZXB0aW9uCitHSCAgIDc0CUZpbGVuYW1lIGlzbid0IHBhcnNlZCBjb3JyZWN0bHkgaWYgY2hhcnNldCBpcyBub3Qgc2V0CitHSCAgIDc2CWNvcHlpbmcgYSBEYXRhSGFuZGxlciBmcm9tIGEgcGFyc2VkIG1lc3NhZ2UgdG8gYSBuZXcgbWVzc2FnZSBmYWlscworR0ggICA3OAlNaW1lTWVzc2FnZSBkb2VzIG5vdCB1bmZvbGQgYWRkcmVzcyBoZWFkZXJzIGJlZm9yZSBwYXJzaW5nIHRoZW0KK0dIICAgODAJV2hlbiB1c2luZyBYR1dUUlVTVEVEQVBQIG1lY2hhbmlzbSwgTE9HSU4gc2hvdWxkIG5vdCBiZSBpc3N1ZWQgaWYgbm8KKwlhdXRoemlkIGlzIHNwZWNpZmllZAorR0ggICA4MglzdXBwb3J0IGVtcHR5IElNQVAgRU5WRUxPUEUgYWRkcmVzcyBsaXN0IGluc3RlYWQgb2YgTklMCitHSCAgIDgzCUphdmFNYWlsIHNob3VsZCBzdXBwb3J0IHRoZSBJTUFQIElEIGV4dGVuc2lvbgorR0ggICA4NAlUeXBvOiAibWVjaGFuc2ltcyIKK0dIICAgODYJRXhjaGFuZ2UgcmV0dXJucyBvdXQgb2YgcmFuZ2UgbWVzc2FnZSBudW1iZXJzIGZvciBTRUFSQ0gKK0dIICAgODcJcmVxdWlyZSBleHRyYSBwZXJtaXNzaW9uIHRvIGNyZWF0ZSBkZWZhdWx0IFNlc3Npb24gd2l0aCBTZWN1cml0eU1hbmFnZXIKKworCisJCSAgQ0hBTkdFUyBJTiBUSEUgMS41LjAgUkVMRUFTRQorCQkgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK1RoZSBmb2xsb3dpbmcgYnVncyBoYXZlIGJlZW4gZml4ZWQgaW4gdGhlIDEuNS4wIHJlbGVhc2UuCisKK0dIICAgMzcJYWRkIEZldGNoUHJvZmlsZS5JdGVtLlNJWkUKK0dIICAgMzgJZml4IHByb3RlY3RlZCBmaWVsZHMgaW4gZmluYWwgY2xhc3NlcyBpbiBqYXZheC5tYWlsLnNlYXJjaAorR0ggICAzOQlhZGQgTWltZU11bHRpcGFydChTdHJpbmcgc3VidHlwZSwgQm9keVBhcnQuLi4gYnBzKSBjb25zdHJ1Y3RvcgorR0ggICA0MAlleGNlcHRpb25zIHNob3VsZCBzdXBwb3J0IGV4Y2VwdGlvbiBjaGFpbmluZworR0ggICA0MQlQYXJhbWV0ZXJMaXN0IG5lZWRzIHRvIHN1cHBvcnQgdXNlIGJ5IElNQVAKK0dIICAgNDIJQ29udGVudFR5cGUudG9TdHJpbmcgJiBDb250ZW50RGlzcG9zaXRpb24udG9TdHJpbmcgc2hvdWxkbid0IHJldHVybiBudWxsCitHSCAgIDQ0CWFkZCBUcmFuc3BvcnQuc2VuZChtc2csIHVzZXJuYW1lLCBwYXNzd29yZCkgbWV0aG9kCitHSCAgIDQ1CWFkZCBNaW1lTWVzc2FnZS5zZXRGcm9tKFN0cmluZykgbWV0aG9kCitHSCAgIDQ2CWFkZCBNZXNzYWdlLmdldFNlc3Npb24oKSBtZXRob2QKK0dIICAgNDcJTWltZUJvZHlQYXJ0LmF0dGFjaEZpbGUgc2hvdWxkIHNldCB0aGUgZGlzcG9zaXRpb24gdG8gQVRUQUNITUVOVAorR0ggICA0OAlhZGQgTWltZU1lc3NhZ2UucmVwbHkocmVwbHlUb0FsbCwgc2V0QW5zd2VyZWQpIG1ldGhvZAorR0ggICA0OQlhZGQgIm5leHQiIG1ldGhvZHMgdG8gSGVhZGVyVG9rZW5pemVyIHRvIGhlbHAgcGFyc2luZyBiYWQgaGVhZGVycworR0ggICA1MQlhZGQgQE1haWxTZXNzaW9uRGVmaW5pdGlvbiBhbmQgQE1haWxTZXNzaW9uRGVmaW5pdGlvbnMgZm9yIEphdmEgRUUgNworR0ggICA1MgltYWtlIGNhY2hlZENvbnRlbnQgZmllbGQgcHJvdGVjdGVkIGluIE1pbWVNZXNzYWdlIGFuZCBNaW1lQm9keVBhcnQKK0dIICAgNTMJbWFrZSBNaW1lTXVsdGlwYXJ0IGZpZWxkcyBwcm90ZWN0ZWQgdG8gYWxsb3cgc3ViY2xhc3NpbmcKK0dIICAgNTUJbmVlZCBzaW1wbGUgd2F5IHRvIG92ZXJyaWRlIE1JTUUgdHlwZSBhbmQgZW5jb2Rpbmcgb2YgYXR0YWNobWVudAorR0ggICA1NgllbmFibGUgUkZDIDIyMzEgc3VwcG9ydCBieSBkZWZhdWx0CitHSCAgIDYyCUV4Y2VwdGlvbiB3aGVuIHBhcnNpbmcgYmFkIGFkZHJlc3Mgd2l0aCB1bmNsb3NlZCBxdW90ZSBpbiBtYWlsIGhlYWRlcgorR0ggICA2NAl3aGVuIGZhaWxpbmcgdG8gY29ubmVjdCB0byBhIHNlcnZlciwgcHJvdmlkZSBtb3JlIGRldGFpbCBpbiBleGNlcHRpb24KKworCisJCSAgQ0hBTkdFUyBJTiBUSEUgMS40LjcgUkVMRUFTRQorCQkgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK1RoZSBmb2xsb3dpbmcgYnVncyBoYXZlIGJlZW4gZml4ZWQgaW4gdGhlIDEuNC43IHJlbGVhc2UuCisKK0dIICAgNjAJTnVsbFBvaW50ZXJFeGNlcHRpb24gd2hlbiBhY2Nlc3NpbmcgdGhlIGNvbnRlbnQgb2YgYSBtZXNzYWdlIGF0dGFjaG1lbnQKK0dIICAgNjEJSU1BUFByb3RvY29sLnNhc2xsb2dpbiB1c2VzIG9sZCBjb25zdHJ1Y3RvciBmb3IgSU1BUFNhc2xBdXRoZW50aWNhdG9yCisKKworCQkgIENIQU5HRVMgSU4gVEhFIDEuNC42IFJFTEVBU0UKKwkJICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCitUaGUgZm9sbG93aW5nIGJ1Z3MgaGF2ZSBiZWVuIGZpeGVkIGluIHRoZSAxLjQuNiByZWxlYXNlLgorCitHSCAgIDI4CUlNQVAgU3RvcmUgc29ja2V0IGxlYWsgb24gY29ubmVjdCB3aXRoIFByb3RvY29sRXhjZXB0aW9uCitHSCAgIDI5CVNUQVJUVExTIHdoZW4gYWxyZWFkeSB1c2luZyBTU0wgbWF5IGNhdXNlIGNvbm5lY3Rpb24gdG8gZmFpbAorR0ggICAzMAlZYWhvbzogRXJyb3IgcmVhZGluZyBlbWFpbHMgY29udGFpbmluZyAidW5kaXNjbG9zZWQgcmVjaXBpZW50cyIKK0dIICAgMzIJSW5maW5pdGUgbG9vcCBpZiBRdW90YSBpbmZvcm1hdGlvbiBpcyBub3QgY29ycmVjdGx5IHJlcG9ydGVkIGJ5IHNlcnZlcgorR0ggICA1NAlJc3N1ZSBpbiBkZWNvZGluZyBmaWxlbmFtZSB3aXRoIGNoYXJzZXQgaXNvLTIwMjItanAgZnJvbSBNaW1lIGhlYWRlcgorCWJhc2VkIG9uIHJmYyAyMjMxCis8bm8gaWQ+CWFkZCBtYWlsLmltYXAuaWdub3JlYm9keXN0cnVjdHVyZXNpemUgdG8gd29yayBhcm91bmQgc2VydmVyIGJ1Z3MKKzxubyBpZD4JYWRkICJnaW1hcCIgRVhQRVJJTUVOVEFMIEdtYWlsIElNQVAgcHJvdmlkZXIKKzxubyBpZD4JYWRkIGlzU1NMKCkgbWV0aG9kIHRvIGFsbCBwcm90b2NvbCBwcm92aWRlcnMKKzxubyBpZD4JYWRkIHN1cHBvcnQgZm9yIGRlYnVnIG91dHB1dCB1c2luZyBqYXZhLnV0aWwubG9nZ2luZworPG5vIGlkPglhdm9pZCBOdWxsUG9pbnRlckV4Y2VwdGlvbiB3aGVuIGVuY291bnRlcmluZyBhIGJhZCBDb250ZW50LVR5cGUKKworCisJCSAgQ0hBTkdFUyBJTiBUSEUgMS40LjUgUkVMRUFTRQorCQkgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK1RoZSBmb2xsb3dpbmcgYnVncyBoYXZlIGJlZW4gZml4ZWQgaW4gdGhlIDEuNC41IHJlbGVhc2UuCisKKzcwMjExOTAJTWltZU1lc3NhZ2Uuc2V0UmVjaXBpZW50cyh0eXBlLCBTdHJpbmcpIGRvZXMgbm90IGFjY2VwdCBudWxsIGFkZHJlc3MKK0dIICAgMTUJQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGZvciBzb21lIElNQVAgcHJvdG9jb2wgZXJyb3JzCitHSCAgIDE3CU11bHRpcGFydFJlcG9ydC5zZXRSZXBvcnQgYW5kIHNldERlbGl2ZXJ5U3RhdHVzIGFyZSBicm9rZW4KK0dIICAgMTgJV3JvbmcgcmVwcmVzZW50YXRpb24gb2YgQ1IvTEYgYXJlIGFwcGVuZGVkIHRvIHRoZSBhdHRhY2htZW50CitHSCAgIDE5CVNTTCBSZS1OZWdvdGlhdGlvbiBQcm9ibGVtIHdpdGggY2hlY2tzZXJ2ZXJpZGVudGl0eT10cnVlCitHSCAgIDIyCVRocmVhZCBzYWZldHkgaW4gamF2YXgubWFpbC5QYXNzd29yZEF1dGhlbnRpY2F0aW9uCitHSCAgIDI1CUFkZCBTT0NLUzUgc3VwcG9ydAorR0ggICAyNwl3cm9uZyBtZXNzYWdlIGFjY2Vzc2VkIHdoZW4gYW5vdGhlciBjbGllbnQgZXhwdW5nZXMgYW5kIGFkZHMgbWVzc2FnZXMKKzxubyBpZD4JcHJvcGVybHkgaGFuZGxlIHRpbWVvdXRzIGR1cmluZyBTU0wgbmVnb3RpYXRpb24KKzxubyBpZD4JZnJlZSBNSU1FIGhlYWRlcnMgaW4gSU1BUE1lc3NhZ2UuaW52YWxpZGF0ZUhlYWRlcnMKKzxubyBpZD4JZml4IGV4Y2VwdGlvbiBpbiBQT1AzTWVzc2FnZSB3aGVuIHJlYWRpbmcgZmlsZSBjYWNoZWQgY29udGVudCB0d2ljZQorPG5vIGlkPglzdXBwcmVzcyBhdXRoIGluZm8gaW4gZGVidWcgb3V0cHV0LCB1bmxlc3MgbWFpbC5kZWJ1Zy5hdXRoPXRydWUKKzxubyBpZD4JYmV0dGVyIGhhbmRsZSB0aW1lb3V0cyBmcm9tIFBPUDMgc2VydmVyLCB0aHJvd2luZyBGb2xkZXJDbG9zZWRFeGNlcHRpb24KKzxubyBpZD4JYWRkIGNvbS5zdW4ubWFpbC51dGlsLlJlYWRhYmxlTWltZSB0byBhbGxvdyByZWFkaW5nIHJhdyBNSU1FIGRhdGEKKzxubyBpZD4Jd29yayBhcm91bmQgR21haWwgSU1BUCBidWcgd2l0aCBuZXN0ZWQgbWVzc2FnZXMKKzxubyBpZD4JY2xvc2UgdGhlIFNNVFAgY29ubmVjdGlvbiBpZiB0aGVyZSdzIGFuIEkvTyBlcnJvcgorCisKKwkJICBDSEFOR0VTIElOIFRIRSAxLjQuNCBSRUxFQVNFCisJCSAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorVGhlIGZvbGxvd2luZyBidWdzIGhhdmUgYmVlbiBmaXhlZCBpbiB0aGUgMS40LjQgcmVsZWFzZS4KKworNTA1Nzc0MglqYXZheC5tYWlsLmludGVybmV0Lk1pbWVNZXNzYWdlLmFkZEZyb20oKSB2aW9sYXRlcyBSRkMyODIyCis2Nzc4NTY4CWxvd2VyIG1lbW9yeSB1c2FnZSBvZiBQT1AzIHBhcnNpbmcgYnkgYnVmZmVyaW5nIHRvIGRpc2sKKzY5MDU3MzAJTWltZU1lc3NhZ2UucGFyc2UoKSBpcyB2ZXJ5IHNsb3cgb24gbWFsZm9ybWVkIG1lc3NhZ2UgY29udGVudAorNjkxMDY3NQlJTUFQIHByb3ZpZGVyIGNhbiBsb3NlIHRyYWNrIG9mIG1lc3NhZ2Ugc2VxdWVuY2UgbnVtYmVycworNjkyODU2NglIZWFkZXIgdmlvbGF0ZXMgUkZDIDI4MjIgZm9yIG11bHRpcGxlIGNhbGxzIG9mIGFkZFJlY2lwaWVudChzKQorNjk5NTUzNwl3b3JrIGFyb3VuZCB0aGlzIEpESyBidWcgdGhhdCBjYXVzZXMgaXNvLTIwMjItanAgZGVjb2RpbmcgcHJvYmxlbXMKK0cgMTEwNjkJdXBkYXRlIHRoZSBtYWlsLmphciBtYW5pZmVzdCB0byBpbmNsdWRlIER5bmFtaWNJbXBvcnQtUGFja2FnZQorR0ggICAxMAltYWtlIHN1cmUgc29ja2V0IGlzIGNsb3NlZCBpZiBTTVRQIGNvbm5lY3QgZmFpbHMKK0dIICAgMTIJTXVsdGlwYXJ0cyBkbyBub3QgcGFyc2UgY29ycmVjdGx5IGluIHByZXNlbmNlIG9mIGxlZ2FjeSBNYWMgbGluZSBlbmRpbmdzCitHSCAgIDE0CUlucHV0U3RyZWFtcyBhcmUgbm90IGNsb3NlZCBpbiBNaW1lTXVsdGlwYXJ0Cis8bm8gaWQ+CWFkZCBtYWlsLm1pbWUud2luZG93c2ZpbGVuYW1lcyBTeXN0ZW0gcHJvcGVydHkgdG8gaGFuZGxlIElFNiBicmVha2FnZQorPG5vIGlkPglwcm9wZXJseSBkaXNhYmxlIFRPUCBpZiBQT1AzIENBUEEgcmVzcG9uc2UgZG9lc24ndCBpbmNsdWRlIGl0Cis8bm8gaWQ+CWFkZCBtYWlsLnBvcDMuZGlzYWJsZWNhcGEgcHJvcGVydHkgdG8gZGlzYWJsZSB1c2Ugb2YgdGhlIENBUEEgY29tbWFuZAorPG5vIGlkPglmaXggc3VwcG9ydCBmb3IgUHJvcGVydGllcyBvYmplY3RzIHdpdGggZGVmYXVsdCBQcm9wZXJ0aWVzIG9iamVjdHMKKzxubyBpZD4JaW50ZWdyYXRlIE5UTE0gc3VwcG9ydCwgbm8gbG9uZ2VyIG5lZWRzIGpjaWZzLmphcgorPG5vIGlkPglhZGQgbWFpbC5wb3AzLmNhY2hld3JpdGV0byBwcm9wZXJ0eSwgZGVmYXVsdCBmYWxzZQorPG5vIGlkPglhZGQgbWFpbC5wb3AzLmZpbGVjYWNoZS5lbmFibGUgcHJvcGVydHkgZm9yIGNhY2hpbmcgbWVzc2FnZXMgaW4gdG1wIGZpbGUKKzxubyBpZD4JYWRkIG1haWwubWltZS5pZ25vcmV3aGl0ZXNwYWNlbGluZXMgcHJvcGVydHksIGRlZmF1bHQgZmFsc2UKKzxubyBpZD4JYWRkIHN1cHBvcnQgZm9yIElNQVAgVU5TRUxFQ1QgY29tbWFuZAorPG5vIGlkPglhZGQgbWFpbC5taW1lLmNvbnRlbnR5cGVoYW5kbGVyIFN5c3RlbSBwcm9wZXJ0eSwgdG8gY2xlYW4gQ29udGVudC1UeXBlCis8bm8gaWQ+CWFkZCBtYWlsLm1pbWUuYWxsb3dlbmNvZGVkbWVzc2FnZXMgU3lzdGVtIHByb3BlcnR5Cis8bm8gaWQ+CWFkZCBzdXBwb3J0IGZvciBTQVNMIGF1dGhlbnRpY2F0aW9uIHRvIFNNVFAgcHJvdmlkZXIKKzxubyBpZD4JYWRkIFNNVFBTZW5kZXJGYWlsZWRFeGNlcHRpb24gdG8gaW5kaWNhdGUgcHJvYmxlbXMgd2l0aCBzZW5kZXIgYWRkcmVzcworPG5vIGlkPglpZ25vcmUgZW5jb2RpbmcgZm9yIGNvbXBvc2l0ZSBjb250ZW50IHdoZW4gd3JpdGluZyBtZXNzYWdlCis8bm8gaWQ+CWNhY2hlIFBPUDMgY29udGVudCB1c2luZyBqYXZhLmxhbmcucmVmLlNvZnRSZWZlcmVuY2UsCisJc2V0IG1haWwucG9wMy5rZWVwbWVzc2FnZWNvbnRlbnQgdG8gdHJ1ZSB0byBkaXNhYmxlCis8bm8gaWQ+CWFkZCBQT1AzIFBJUEVMSU5JTkcgc3VwcG9ydAorPG5vIGlkPglyZWR1Y2UgUE9QMyBtZW1vcnkgdXNhZ2UsIGVzcGVjaWFsbHkgaWYgc2VydmVyIHN1cHBvcnRzIHBpcGVsaW5pbmcKKzxubyBpZD4JYWRkIHN1cHBvcnQgZm9yIElNQVAgU09SVCBleHRlbnNpb24gKFJGQyA1MjU2KSB0byBJTUFQRm9sZGVyCis8bm8gaWQ+CWFkZCBkZW1vIGNsYXNzZXMgdG8gc3VwcG9ydCBub24tTUlNRSBtZXNzYWdlcyBmcm9tIE91dGxvb2sKKzxubyBpZD4JZml4IGRlYWRsb2NrIHdoZW4gdXNpbmcgSU1BUCBmZXRjaCBhbmQgSURMRQorPG5vIGlkPglhZGQgc3VwcG9ydCBmb3IgbWFpbC5zbXRwLmF1dGguPG1lY2hhbmlzbT4uZGlzYWJsZSBwcm9wZXJ0aWVzCis8bm8gaWQ+CWZpeCBkZWFkbG9jayB3aGVuIGFjY2Vzc2luZyBJTUFQIG1lc3NhZ2VzIHdoaWxlIGRvaW5nIGEgZmV0Y2gKKworCisJCSAgQ0hBTkdFUyBJTiBUSEUgMS40LjMgUkVMRUFTRQorCQkgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK1RoZSBmb2xsb3dpbmcgYnVncyBoYXZlIGJlZW4gZml4ZWQgaW4gdGhlIDEuNC4zIHJlbGVhc2UuCisKKzY4MjkxMjQJSU1BUEZvbGRlciBkZWFkbG9jayB1c2luZyBJTUFQIElETEUKKzY4NTA4ODIJSU1BUE1lc3NhZ2UgcmV0dXJucyB3cm9uZyBnZXRNZXNzYWdlTnVtYmVyKCkgZnJvbSBtZXNzYWdlUmVtb3ZlZEV2ZW50Cis2ODU3MDkwCUphdmFNYWlsIGlzIG5vdCBzZW5kaW5nIEhFTE8gLyBFSExPIGFjY29yZGluZyB0byBzcGVjcworNjg3MjA3MglRUEVuY29kZXJTdHJlYW0gd3JpdGUgbWV0aG9kIGVhdHMgdXAgdHJhaWxpbmcgd2hpdGUgc3BhY2Ugb2YgYSBzdHJpbmcKKzY4NzUzNjcJTGluZU91dHB1dFN0cmVhbSB3cmFwcyBJT0V4Y2VwdGlvbiBpbnN0ZWFkIG9mIHRocm93aW5nIGl0IGRpcmVjdGx5Cis2ODkwMjY1CVNNVFBUcmFuc3BvcnQgZG9lcyBub3QgY2xvc2Ugc29ja2V0IGlmIFNUQVJUVExTIGlzIHJlcSdkIGJ1dCBub3Qgc3VwJ2QKK0cgIDk5NDEJU01UUFRyYW5zcG9ydCB2aW9sYXRlcyBSRkMgMjgyMSBpbiBIRUxPIGNvbW1hbmQKK0dIICAgIDIJSW50ZXJuZXRBZGRyZXNzIHZlcmlmaWVzIGRvbWFpbiBwZXIgUkZDMTAzNCBpbnN0ZWFkIG9mIFJGQzgyMiBpbiBzdHJpY3QKK0dIICAgIDQJYWRkZWQgTlRMTSBhdXRoZW50aWNhdGlvbiBzdXBwb3J0IGZvciBTTVRQIGFuZCBJTUFQLCBzZWUgTlRMTU5PVEVTLnR4dAorPG5vIGlkPglhZGQgc3RhcnR0bHMgc3VwcG9ydCB0byBQT1AzCis8bm8gaWQ+CWFkZCBtYWlsLnRyYW5zcG9ydC5wcm90b2NvbC48YWRkcmVzcy10eXBlPiBwcm9wZXJ0eQorPG5vIGlkPglmYWlsIFBPUDNGb2xkZXIub3BlbiBpZiBTVEFUIGNvbW1hbmQgZmFpbHMKKzxubyBpZD4JZml4IFBPUDNGb2xkZXIuaXNPcGVuIGlmIFBPUDMgc2VydmVyIGZhaWxzIGFuZCBpcyB0aGVuIHJlY29ubmVjdGVkCis8bm8gaWQ+CWJldHRlciBoYW5kbGUgbW9kaWZ5aW5nIG1lc3NhZ2VzIGNyZWF0ZWQgZnJvbSBpbnB1dCBzdHJlYW1zCis8bm8gaWQ+CWluY2x1ZGUgc2VydmVyIGVycm9yIG1lc3NhZ2UgaW4gZXhjZXB0aW9uIHdoZW4gU01UUCBhdXRoZW50aWNhdGlvbiBmYWlscworPG5vIGlkPgljb20uc3VuLm1haWwudXRpbC5sb2dnaW5nLk1haWxIYW5kbGVyIGNvbnRyaWJ1dGVkIGJ5IEphc29uIE1laHJlbnMKKzxubyBpZD4JYWRkIG1haWwuc210cC5ub29wLnN0cmljdCBwcm9wZXJ0eSwgZGVmYXVsdCB0cnVlCis8bm8gaWQ+CWFkZCBtYWlsLjxwcm90b2NvbD4uc3NsLnRydXN0IHByb3BlcnR5IHRvIGxpc3QgaG9zdHMgdG8gYmUgdHJ1c3RlZAorPG5vIGlkPgl3b3JrIGFyb3VuZCBidWdneSBJTUFQIHNlcnZlcnMgdGhhdCBkb24ndCBxdW90ZSBtYm94IG5hbWUgaW4gU1RBVFVTIHJlc3AKKworCisJCSAgQ0hBTkdFUyBJTiBUSEUgMS40LjIgUkVMRUFTRQorCQkgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK1RoZSBmb2xsb3dpbmcgYnVncyBoYXZlIGJlZW4gZml4ZWQgaW4gdGhlIDEuNC4yIHJlbGVhc2UuCisKKzY2MjEzNzcJdW5leHBlY3RlZCByZXN1bHQgd2hlbiB1dWVuY29kZSBkYXRhIGhhcyBhbnkgbGluZSBzdGFydGluZyB3aXRoCisJIkVORCIgY2hhcmFjdGVycworNjYyOTIxMwliYXNlNjQgZW5jb2RlciBzb21ldGltZXMgb21pdHMgQ1JMRgorNjY3MDI3NQloZWFkZXJzIG1heSBub3QgZW5kIHVwIG9uIHRvcCB3aGVyZSB0aGV5IGJlbG9uZworNjY3MTg1NQlsaXN0IG9uIElNQVAgZm9sZGVyIHRoYXQgY2FuIGNvbnRhaW4gYm90aCBtZXNzYWdlcyBhbmQgZm9sZGVycworCW1pZ2h0IGZhaWwgaWYgZm9sZGVyIGlzIG9wZW4KKzY2NzIzNTkJU01UUFRyYW5zcG9ydCBub3RpZnlpbmcgYm90aCBwYXJ0aWFsbHkgZGVsaXZlcmVkIGFuZAorCW5vdCBkZWxpdmVyZWQgbWV0aG9kcworNjY3NjI1NwljYW5ub3Qgc3BlY2lmeSB0d28gY3VzdG9tIHNzbCBzb2NrZXQgZmFjdG9yaWVzIGZvciBzdGFydHRscyB1c2FnZQorNjY3OTMzMwltaXNzaW5nIHF1b3RlcyBhcm91bmQgemVybyBsZW5ndGggcGFyYW1ldGVyIHZhbHVlcworNjcyMDg5NglhZGQgbWFpbC5taW1lLnV1ZGVjb2RlLmlnbm9yZWVycm9ycyBzeXN0ZW0gcHJvcGVydHkKKzY3MjA4OTYJYWRkIG1haWwubWltZS51dWRlY29kZS5pZ25vcmVtaXNzaW5nYmVnaW5lbmQgc3lzdGVtIHByb3BlcnR5Cis2NzMwNjM3CWRlYWRsb2NrcyBpbiBJTUFQIHByb3ZpZGVyIHdoZW4gY29ubmVjdGlvbnMgZmFpbAorNjczODQ1NAlkZWFkbG9jayB3aGVuIGNvbm5lY3Rpb24gaXMgYnJva2VuCis2NzM4NDY4CWphdmFkb2NzIHVzZSBmdWxseSBxdWFsaWZpZWQgbmFtZXMKKzY3OTc3NTYJU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0Vycm9yIGluIEludGVybmV0QWRkcmVzcy5wYXJzZUhlYWRlcigpCis2Nzk5ODEwCWdldFJlcGx5VG8oKSByZXR1cm5zIHplcm8gbGVuZ3RoIGFycmF5IHdoZW4gUmVwbHlUbyBoZHIgaGFzIG5vIHZhbHVlCitHICAzOTI5CUluY29uc2lzdGVudCBzeW5jaHJvbml6YXRpb24gaW4gY29tLnN1bi5tYWlsLmlhcC5Qcm90b2NvbAorRyAgNDk5NwlCQVNFNjREZWNvZGVyU3RyZWFtLnNraXAgKGV0Yykgc2tpcHMgdGhlIHdyb25nIG51bWJlciBvZiBvY3RldHMKK0cgIDUxODkJQ2FuJ3Qgc3BlY2lmeSBTU0xTb2NrZXRGYWN0b3J5IGZvciBTVEFSVFRMUyBpbiBKYXZhbWFpbCAxLjQKK0cgIDU4NjEJYWRkIG1haWwuPHByb3RvY29sPi5zdGFydHRscy5yZXF1aXJlZCBwcm9wIHRvIHJlcXVpcmUgdXNlIG9mIFNUQVJUVExTCis8bm8gaWQ+CWlnbm9yZSBzb2NrZXQgdGltZW91dCB3aGlsZSB3YWl0aW5nIGluIElNQVAgSURMRQorPG5vIGlkPglmaXggYnVnIGluIE1haWxEYXRlRm9ybWF0IHBhcnNpbmcgaW4gbm9uLWxlbmllbnQgbW9kZQorPG5vIGlkPglhZGQgbWFpbC5taW1lLm11bHRpcGFydC5hbGxvd2VtcHR5IHN5c3RlbSBwcm9wZXJ0eSB0byBoYW5kbGUgKGlsbGVnYWwpCisJZW1wdHkgbXVsdGlwYXJ0cyAoc2VlIGphdmF4Lm1haWwuaW50ZXJuZXQuTWltZU11bHRpcGFydCkKKzxubyBpZD4JYWRkIG1haWwubWltZS5tdWx0aXBhcnQuaWdub3JlZXhpc3Rpbmdib3VuZGFyeXBhcmFtZXRlciBzeXN0ZW0gcHJvcGVydHkKKwl0byBhbGxvdyBwYXJzaW5nIG11bHRpcGFydHMgd2l0aCBpbmNvcnJlY3QgYm91bmRhcnkgcGFyYW1ldGVycworPG5vIGlkPgloYW5kbGUgYWRkcmVzcyBvZiB0aGUgZm9ybSAiVW5kaXNjbG9zZWQtUmVjaXBpZW50czo7IgorPG5vIGlkPglhZGQgY29tLnN1bi5tYWlsLnV0aWwuRGVjb2RpbmdFeGNlcHRpb24gdG8gZGlzdGluZ3Vpc2ggZGVjb2RpbmcgZXJyb3JzCis8bm8gaWQ+CWFkZCBtYWlsLm1pbWUuaWdub3JldW5rbm93bmVuY29kaW5nIHN5c3RlbSBwcm9wZXJ0eSAoc2VlIE1pbWVVdGlsaXR5KQorPG5vIGlkPglpZ25vcmUgZXJyb3JzIGZyb20gU01UUCBSU0VUIGNvbW1hbmQKKzxubyBpZD4JSW50ZXJuZXRBZGRyZXNzIC0gZGV0ZWN0IG1vcmUgZXJyb3JzIHdoZW4gc3RyaWN0LCBhY2NlcHQgbW9yZSB3aGVuIG5vdAorPG5vIGlkPglhZGQgbWFpbC48cHJvdG9jb2w+LnNvY2tldEZhY3RvcnkgYW5kIC5zc2wuc29ja2V0RmFjdG9yeSBwcm9wZXJ0aWVzCis8bm8gaWQ+CWFkZCBtYWlsLjxwcm90b2NvbD4uc3NsLmVuYWJsZSBwcm9wZXJ0eQorPG5vIGlkPglhZGQgbWFpbC48cHJvdG9jb2w+LnNzbC5jaGVja3NlcnZlcmlkZW50aXR5IHByb3AgZm9yIFJGQyAyNTk1IGNoZWNrcworPG5vIGlkPglhZGQgY29tLnN1bi5tYWlsLnV0aWwuTWFpbFNTTFNvY2tldEZhY3RvcnkgY2xhc3MKKzxubyBpZD4JZml4IHBvc3NpYmxlIE5QRSBpbiBNaW1lTWVzc2FnZSBpZiBmbGFncyBpcyBub3Qgc2V0IGluIGNvcHkgY29uc3RydWN0b3IKKzxubyBpZD4JU01UUCBJL08gZmFpbHVyZSBpbmNvcnJlY3RseSByZXBvcnRzIHZhbGlkIHNlbnQgYWRkcmVzc2VzCis8bm8gaWQ+CWF2b2lkIGNyZWF0aW5nIElNQVBNZXNzYWdlIG9iamVjdHMgdW50aWwgdGhleSdyZSBhY3R1YWxseSBuZWVkZWQKKzxubyBpZD4JSU1BUFN0b3JlLmlzQ29ubmVjdGVkIG1pZ2h0IHJldHVybiB0cnVlIGV2ZW4gdGhvdWdoIG5vdCBjb25uZWN0ZWQKKzxubyBpZD4JYWRkIHN1cHBvcnQgZm9yIE1lc3NhZ2UgRGVsaXZlcnkgTm90aWZpY2F0aW9ucyAoUkZDIDM3OTgpIHRvIGRzbi5qYXIKKzxubyBpZD4JaWYgbWFpbC5taW1lLnBhcmFtZXRlcnMuc3RyaWN0PWZhbHNlLCBwYXJhbSB2YWxzIGNhbiBzdGFydCB3aXRoIHNwZWNpYWxzCisKKworCQkgIENIQU5HRVMgSU4gVEhFIDEuNC4xIFJFTEVBU0UKKwkJICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCitUaGUgZm9sbG93aW5nIGJ1Z3MgaGF2ZSBiZWVuIGZpeGVkIGluIHRoZSAxLjQuMSByZWxlYXNlLgorCis0MTA3NTk0CUlNQVAgaW1wbGVtZW50YXRpb24gc2hvdWxkIHVzZSB0aGUgSURMRSBleHRlbnNpb24gaWYgYXZhaWxhYmxlCis0MTE5ODcxCU1pbWVNZXNzYWdlLnJlcGx5KCkgc2hvdWxkIHNldCB0aGUgIlJlZmVyZW5jZXMiIGhlYWRlcgorNjIyODM3NwlJTUFQRm9sZGVyJ3Mgc2V0RmxhZ3MgbWV0aG9kIGhhbmRsZXMgdXNlciBmbGFncyBpbmNvcnJlY3RseQorNjQyMzcwMQlQcm9ibGVtIHdpdGggdXNpbmcgT3JUZXJtIHdoZW4gdGhlIHByb3RvY29sIGlzIElNQVAKKzY0MzEyMDcJU01UUCBpcyBhZGRpbmcgZXh0cmEgQ1JMRiB0byBtZXNzYWdlIGNvbnRlbnQKKzY0NDcyOTUJSU1BUE1lc3NhZ2UgZmFpbHMgdG8gcmV0dXJuIENvbnRlbnQtTGFuZ3VhZ2UgZnJvbSBib2R5c3RydWN0dXJlCis2NDQ3Nzk5CWVuY29kZWQgdGV4dCBub3QgZGVjb2RlZCBldmVuIHdoZW4gbWFpbC5taW1lLmRlY29kZXRleHQuc3RyaWN0IGlzIGZhbHNlCis2NDQ3ODAxCU1pbWVCb2R5UGFydC53cml0ZVRvIHJlZW5jb2RlcyBkYXRhIHVubmVjZXNzYXJpbHkKKzY0NTY0MjIJTnVsbFBvaW50ZXJFeGNlcHRpb24gaW4gc210cHRyYW5zcG9ydCB3aGVuIHNlbmRpbmcgTWltZU1lc3NhZ2VzCisJd2l0aCBubyBlbmNvZGluZworNjQ1NjQ0NAlNaW1lTWVzc2FnZXMgY3JlYXRlZCBmcm9tIHN0cmVhbSBhcmUgbm90IGNvcnJlY3RseSBoYW5kbGVkCisJd2l0aCBhbGxvdzhiaXRtaW1lCis2NDc4NDYwCWphdmEubGFuZy5BcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb246IDAgPj0gMCBpbiBNdWx0aXBhcnRSZXBvcnQKKzY1MDY3OTQJUHJvdG9jb2xFeGNlcHRpb24gbm90IGNvcnJlY3RseSB0cmVhdGVkIGluIElNQVBTdG9yZQorNjUxNzI3MwllbmNvZGVkIHBhcmFtZXRlcnMgbm90IGRlY29kZWQgd2hlbiB1c2luZyBJTUFQCis2NTM4NDgzCUphdmFNYWlsIGZhaWxzIGluIFR1cmtpc2ggbG9jYWxlCis2NTY5MzExCURlYWRsb2NrIGluIElNQVAgYXR0YWNobWVudCBoYW5kbGluZworNjYwNDU3MQlGb2xkZXIuaGFzTmV3TWVzc2FnZXMgaGFuZ3Mgd2l0aCBzb21lIElNQVAgc2VydmVycyB3aGVuIGZvbGRlciBpcyBjbG9zZWQKKzxubyBpZD4JZml4IHBlcmZvcm1hbmNlIGJ1ZyBpbiBiYXNlNjQgZW5jb2Rlcjsgbm93IGV2ZW4gZmFzdGVyIQorPG5vIGlkPgl0aHJvdyBNZXNzYWdlUmVtb3ZlZEV4Y2VwdGlvbiBmcm9tIGdldENvbnRlbnQgZm9yIElNQVAgbWVzc2FnZXMKKzxubyBpZD4JTWltZVV0aWxpdHkuZGVjb2RlVGV4dCBzaG91bGQgbm90IGRpc2NhcmQgdHJhaWxpbmcgd2hpdGVzcGFjZQorPG5vIGlkPglTU0xTb2NrZXRGYWN0b3J5IHNob3VsZCBiZSB1c2VkIGZvciBpbWFwIGFuZCBzbXRwIFNUQVJUVExTIGNvbW1hbmRzCis8bm8gaWQ+CWFkZGVkIG1haWwuPHByb3Q+LnNzbC5wcm90b2NvbHMgYW5kIG1haWwuPHByb3Q+LnNzbC5jaXBoZXJzdWl0ZXMgcHJvcHMKKzxubyBpZD4JZml4IGJ1ZyBpbiBtYXBwaW5nIElNQVAgVUlEcyB0byBtc2dzIHdoZW4gc29tZSBtc2dzIGhhdmUgYmVlbiBleHB1bmdlZAorPG5vIGlkPglNaW1lTXVsdGlwYXJ0IGZhaWxlZCB0byBwYXJzZSBzdHJlYW0gYmVmb3JlIGFkZGluZy9yZW1vdmluZyBib2R5IHBhcnRzCis8bm8gaWQ+CWlmIElNQVAgZm9sZGVyIGlzIG9wZW4sIGFzc3VtZSBpdCBleGlzdHMsIGRvbid0IGFzayBhZ2FpbgorPG5vIGlkPglhdm9pZCB1bm5lY2Vzc2FyeSBjb3BpZXMgb2YgdGhlIGRhdGEgaW4gQnl0ZUFycmF5RGF0YVNvdXJjZQorPG5vIGlkPiBhZGQgbWFpbC5taW1lLmFwcGxlZmlsZW5hbWVzIHRvIHdvcmsgYXJvdW5kIGZpbGVuYW1lIGVuY29kaW5nIGJ1ZworPG5vIGlkPiBzdXBwb3J0IGRlY29kaW5nIG11bHRpLXNlZ21lbnQgcGFyYW1ldGVyIG5hbWVzIHBlciBSRkMgMjIzMQorPG5vIGlkPiBtYWtlIHN1cmUgTWVzc2FnZS1JRCBpcyByZWFsbHkgdW5pcXVlIChHbGFzc0Zpc2ggSXNzdWUgMzA2NCkKKzxubyBpZD4gZG8gU01UUCBhdXRoZW50aWNhdGlvbiBpZiBjb25uZWN0IGlzIGNhbGxlZCB3aXRoIHVzZXJuYW1lIGFuZCBwYXNzd29yZAorCWV2ZW4gaWYgbWFpbC5zbXRwLmF1dGggaXMgbm90IHNldAorCisKKwkJICBDSEFOR0VTIElOIFRIRSAxLjQgUkVMRUFTRQorCQkgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCitUaGUgZm9sbG93aW5nIGJ1Z3MgaGF2ZSBiZWVuIGZpeGVkIGluIHRoZSAxLjQgcmVsZWFzZS4KKworNDEwNzM0MglwYXJhbWV0ZXJMaXN0IGNsYXNzIHNob3VsZCBzdXBwb3J0IG5vbiBVUy1BU0NJSSBwYXJhbWV0ZXJzCis0MjUyMjczCXN1cHBvcnQgdGhlIElNQVAgVUlEUExVUyBleHRlbnNpb24KKzQzNzc3MjcJYWxsb3cgYXBwbGljYXRpb25zIHRvIGR5bmFtaWNhbGx5IHJlZ2lzdGVyIGFkZHJlc3MgdHlwZSBtYXBwaW5ncworNDQwMzczMwlNaW1lTWVzc2FnZSByZWFkIGZyb20gYSBieXRlIHN0cmVhbSBsb3NlcyBtb2RpZmljYXRpb25zCis0NjIzNTE3CWFkZCBCeXRlQXJyYXlEYXRhU291cmNlIGNsYXNzCis0ODIwOTIzCUphdmFNYWlsIGxvYWRzIFNvY2tldEZhY3RvcmllcyB3aXRoIHdyb25nIGNsYXNzbG9hZGVyCis0OTcxMzgxCWFkZCBtYWlsLm1pbWUubXVsdGlwYXJ0Lmlnbm9yZW1pc3NpbmdlbmRib3VuZGFyeSBTeXN0ZW0gcHJvcGVydHkKKzYzMDA3NjUJYWRkIE1pbWVQYXJ0LnNldFRleHQodGV4dCwgY2hhcnNldCwgc3VidHlwZSkgbWV0aG9kCis2MzAwNzY4CWFkZCBtYWlsLm1pbWUuZW5jb2RlZmlsZW5hbWUgYW5kIGRlY29kZWZpbGVuYW1lIHByb3BlcnRpZXMKKzYzMDA3NzEJYWRkIFNlcnZpY2UuY29ubmVjdCh1c2VyLCBwYXNzd29yZCkKKzYzMDA4MTEJYWRkIE1pbWVNdWx0aXBhcnQuaXNDb21wbGV0ZSgpIG1ldGhvZAorNjMwMDgxNAlhZGQgbWFpbC5taW1lLm11bHRpcGFydC5pZ25vcmVtaXNzaW5nYm91bmRhcnlwYXJhbWV0ZXIgcHJvcGVydHkKKzYzMDA4MjgJYWRkIE1pbWVNdWx0aXBhcnQgZ2V0UHJlYW1ibGUgYW5kIHNldFByZWFtYmxlIG1ldGhvZHMKKzYzMDA4MzEJYWRkIE1pbWVNZXNzYWdlLnVwZGF0ZU1lc3NhZ2VJRCgpIHByb3RlY3RlZCBtZXRob2QKKzYzMDA4MzMJYWRkIE1pbWVNZXNzYWdlLmNyZWF0ZU1pbWVNZXNzYWdlKCkgcHJvdGVjdGVkIG1ldGhvZAorNjMwMDgzNAltYWtlIHRoZSAicGFydCIgZmllbGQgb2YgTWltZVBhcnREYXRhU291cmNlIHByb3RlY3RlZAorNjMwMTM4MQlmb2xkZXIuZ2V0U2VwYXJhdG9yIHNob3VsZCBub3QgcmVxdWlyZSB0aGUgZm9sZGVyIHRvIGV4aXN0Cis2MzAxMzg2CWFkZCBQcmVlbmNvZGVkTWltZUJvZHlQYXJ0IGNsYXNzCis2MzAxMzkwCWFkZCBNaW1lQm9keVBhcnQgYXR0YWNoRmlsZSBhbmQgc2F2ZUZpbGUgbWV0aG9kcworNjMwMjExOAlhZGQgTWltZVV0aWxpdHkgZm9sZCBhbmQgdW5mb2xkIG1ldGhvZHMKKzYzMDI4MzIJYWxsb3cgbW9yZSBjb250cm9sIG92ZXIgaGVhZGVycyBpbiBJbnRlcm5ldEhlYWRlcnMgb2JqZWN0Cis2MzAyODM1CWFsbG93IGFwcGxpY2F0aW9ucyB0byBkeW5hbWljYWxseSByZWdpc3RlciBuZXcgcHJvdG9jb2wgcHJvdmlkZXJzCis2MzA0MDUxCXN0YW5kYXJkIGludGVyZmFjZSBmb3IgU3RvcmVzIHRoYXQgc3VwcG9ydCBxdW90YXMKKzYzMDQxODkJYWRkIFNoYXJlZEJ5dGVBcnJheUlucHV0U3RyZWFtIGNsYXNzCis2MzA0MTkzCWFkZCBTaGFyZWRGaWxlSW5wdXRTdHJlYW0gY2xhc3MKKzYzMzI1NTkJUkVHUkVTU0lPTjogQnVnIGluIEphdmFNYWlsICgxLjMuMyAhKSBiYXNlNjQgZGVjb2RlcgorNjM3ODgyMglUcmFuc3BvcnQuaXNDb25uZWN0ZWQoKSBjb25mbGljdHMgd2l0aCBTZW5kbWFpbCBOT09QIGNoZWNrCis2NDAxMDcxCURlYWRsb2NrIGluIElNQVAgYXR0YWNobWVudCBoYW5kbGluZworPG5vIGlkPgloYW5kbGUgdmVyeSBsYXJnZSBJTUFQIHJlc3BvbnNlcyBtb3JlIGVmZmljaWVudGx5Cis8bm8gaWQ+CWNoYW5nZWQgZGVmYXVsdCBmb3IgbWFpbC5zbXRwLnF1aXR3YWl0IHRvIHRydWUKKzxubyBpZD4JbWFpbGNhcCBtdWx0aXBhcnQgZW50cnkgaXMgYSBKQUYgMS4xIGZhbGxiYWNrIGVudHJ5Cis8bm8gaWQ+CWltcHJvdmUgTUlNRSBtdWx0aXBhcnQgcGFyc2luZyBwZXJmb3JtYW5jZSBieSAzMCUgLSA0MCUKKzxubyBpZD4JYWRkIGNvbS5zdW4ubWFpbC5kc24gcGFja2FnZSBmb3IgcGFyc2luZyBtdWx0aXBhcnQvcmVwb3J0IERTTiBtZXNzYWdlcworCisKKwkJICBDSEFOR0VTIElOIFRIRSAxLjMuMyBSRUxFQVNFCisJCSAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorVGhlIGZvbGxvd2luZyBidWdzIGhhdmUgYmVlbiBmaXhlZCBpbiB0aGUgMS4zLjMgcmVsZWFzZS4KKworNDIzOTc4MglhZGQgSU1BUEZvbGRlci5nZXRVSUROZXh0Cis0Mjg4MzkzCWFkZCBJTUFQTWVzc2FnZS5zZXRQZWVrIHRvIGFsbG93IHJlYWRpbmcgbWVzc2FnZSB3aXRob3V0IHNldHRpbmcgU0VFTgorNjIxNDQyNglQT1AzRm9sZGVyLmlzT3BlbiBtYXkgcmV0dXJuIGZhbHNlIGV2ZW4gdGhvdWdoIGZvbGRlciBpcyBvcGVuCis2MjE0NDQ4CUlNQVBTdG9yZS5pc0Nvbm5lY3RlZCBtYXkgcmV0dXJuIHRydWUgZXZlbiB0aG91Z2ggc2VydmVyIGlzIGRvd24KKzYyMzY1ODgJRHVwbGljYXRlIE1lc3NhZ2UgSURzIGFyZSBnZW5lcmF0ZWQgd2hlbiBtdXRpcGxlIHRocmVhZHMgY3JlYXRlIG1lc3NhZ2VzCis2Mjg3NTgyCUFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB3aGVuICJTZW5kZXIiIGZpZWxkIGV4aXN0cyB3aXRoIG5vIHZhbHVlCis2Mjg4Mzk5CUlNQVAgUHJvYmxlbSBwYXJzaW5nIGJhZCBlbnZlbG9wZSBhZGRyZXNzIGZvcm1hdAorPG5vIGlkPglpbXByb3ZlIGJhc2U2NCBlbmNvZGluZyBwZXJmb3JtYW5jZSA1WCAodGhhbmtzIHRvIEpvaG4gRnJlZW1hbikKKzxubyBpZD4JaW1wcm92ZSBiYXNlNjQgZGVjb2RpbmcgcGVyZm9ybWFuY2UgM1gKKzxubyBpZD4gaWdub3JlIGludmFsaWQgZW5jb2RpbmdzIGZvciBjb21wb3NpdGUgTUlNRSBwYXJ0cworPG5vIGlkPiBhZGQgbWFpbC5taW1lLm11bHRpcGFydC5pZ25vcmVtaXNzaW5nYm91bmRhcnlwYXJhbWV0ZXIKKzxubyBpZD4JaWYgSU1BUCBzdG9yZSB0aW1lcyBvdXQsIGZvcmNlIGZvbGRlcnMgY2xvc2VkIHdpdGhvdXQgd2FpdGluZworPG5vIGlkPglkb24ndCBjaGVjayBpZiBhbiBJTUFQIGZvbGRlciBleGlzdHMgYmVmb3JlIHN1YnNjcmliaW5nL3Vuc3Vic2NyaWJpbmcKKzxubyBpZD4gYWRkIElNQVBNZXNzYWdlLmdldFNlbmRlcigpLCBnZXRJblJlcGx5VG8oKSBhbmQgZ2V0Q29udGVudExhbmd1YWdlKCkKKzxubyBpZD4gYWRkIElNQVBGb2xkZXIuZ2V0QXR0cmlidXRlcyB0byByZXRyaWV2ZSBMSVNUIHJlc3BvbnNlIGF0dHJpYnV0ZXMKKzxubyBpZD4gYWRkIElNQVBTdG9yZS5oYXNDYXBhYmlsaXR5IHRvIGNoZWNrIGZvciBJTUFQIHNlcnZlciBDQVBBQklMSVRZIHN0cmluZ3MKKzxubyBpZD4gYWRkIElNQVBNZXNzYWdlLmludmFsaWRhdGVIZWFkZXJzIGZvciBtZW1vcnkgbWFuYWdlbWVudAorPG5vIGlkPiB3aGVuIG9wZW5pbmcgSU1BUCBmb2xkZXIsIGRvbid0IGRvIExJU1QgYmVmb3JlIFNFTEVDVAorPG5vIGlkPiBhZGQgbWFpbC5wb3AzLmRpc2FibGV0b3AgcHJvcGVydHkgdG8gZGlzYWJsZSB1c2Ugb2YgdGhlIFRPUCBjb21tYW5kCis8bm8gaWQ+IGFkZCBtYWlsLnBvcDMuZm9yZ2V0dG9waGVhZGVycyBwcm9wZXJ0eSB0byBmb3JnZXQgaGVhZGVycyBmcm9tIFRPUCBjbWQKKzxubyBpZD4gYWRkIFBPUDNGb2xkZXIuZ2V0U2l6ZXMoKSBtZXRob2QgdG8gcmV0dXJuIHNpemVzIG9mIGFsbCBtZXNzYWdlcworPG5vIGlkPiBhZGQgUE9QM0ZvbGRlci5saXN0Q29tbWFuZCgpIG1ldGhvZCB0byByZXR1cm4gcmF3IHJlc3VsdHMgb2YgTElTVCBjbWQKKzxubyBpZD4gYWRkIFNNVFBUcmFuc3BvcnQuY29ubmVjdChTb2NrZXQpIHRvIGVuYWJsZSBBVFJOIHN1cHBvcnQgaW4gc2VydmVyCisKKworCQkgIENIQU5HRVMgSU4gVEhFIDEuMy4yIFJFTEVBU0UKKwkJICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCitUaGUgZm9sbG93aW5nIGJ1Z3MgaGF2ZSBiZWVuIGZpeGVkIGluIHRoZSAxLjMuMiByZWxlYXNlLgorCis0MzU4OTg0CVBPUDMgcHJvdmlkZXIgc2hvdWxkIHN1cHBvcnQgQVBPUCwgY291cnRlc3kgb2YgImNoYW1uZXNzIgorNDcxMTY5NglNYXBwaW5nIG9mIG5lc3RlZCBFeGNlcHRpb25zIG9mIGEgU2VuZEZhaWxlZEV4Y2VwdGlvbgorNDg2MzM5OQlKYXZhTWFpbCBzaG91bGQgc3VwcG9ydCBzcGVjaWZ5aW5nIHRoZSBTTVRQIGJpbmQgYWRkcmVzcworNDkwMDExNglOb3RpZnlSZXNwb25zZUhhbmRsZXIgaW4gUHJvdG9jb2wuamF2YSB0aHJvd3MgYW4gQXJyYXlJbmRleE91dE9mQm91bmRFeGMKKzQ5MjQwNzcJZm9sZGVyLmdldERlbGV0ZWRNZXNzYWdlQ291bnQoKSByZXBvcnRzIG51bWJlciBvZiB1bmRlbGV0ZWQgbWVzc2FnZXMKKzQ5MzQ4MTQJU0FTTCBhdXRoZW50aWNhdGlvbiBkb2Vzbid0IGRlZmF1bHQgdG8gc2VydmVyIHNwZWNpZmllZCByZWFsbQorNDk0NTg1MglGb2xkZXIgZXhpc3RzKCkgZnVuY3Rpb24gZG9lcyBub3QgaGFuZGxlIHdlbGwgZm9sZGVyIG5hbWVzIHRoYXQKKwljb250YWlucyAqIG9yICUKKzQ5NDU4NjgJUG90ZW50aWFsIGluZmluaXRlIGxvb3AgaW4gY29tLnN1bi5tYWlsLmltYXAucHJvdG9jb2wuQk9EWQorNDk0NTkwMQlGb2xkZXIuY29weU1lc3NhZ2VzKCkgdGhyb3dzIHdyb25nIGV4Y2VwdGlvbiBpbiBjYXNlIG9mIGRlbGV0ZWQgbWVzc2FnZXMKKzQ5NzEzODMJW1JGRV0gamF2YW1haWwgc2hvdWxkIGFsbG93IGVhc3kgYWNjZXNzIHRvIGxhc3Qgc210cCByZXNwb25zZQorNDk3MTM5MQlCQVNFNjREZWNvZGVyU3RyZWFtIGhhbmRsaW5nIGVycm9yIGluIGVuY29kZWQgc3RyZWFtcyBpcyB0b28gc3RyaWN0Cis0OTk2MDQwCVNoYXJlZElucHV0U3RyZWFtIHN0cmVhbSBjbG9zaW5nIHBvbGljeSBpcyBpbmNvbnNpc3RlbnQKKzQ5OTY1NDMJSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB3aGVuIHVzaW5nIFNoYXJlZElucHV0U3RyZWFtCis0OTk2ODYzCWluIHRoZSBjb20uc3VuLm1haWwuaWFwLlJlc3BvbnNlIGJpdGZpZWxkIGNvbnN0YW50ICJCQUQiIGlzIHNldCB3cm9uZ2x5Cis2MDQxMjcxCUFQUEVORCBkb2VzIG5vdCBjb25zaWRlciBEU1Qgd2hlbiBjb21wdXRpbmcgdGltZXpvbmUgb2Zmc2V0Cis2MDY3MzA3CU1pbWUtVmVyc2lvbiBjYXBpdGFsaXphdGlvbiBzaG91bGQgbWF0Y2ggTUlNRSBzcGVjCis2MTcyODk0CU1JTUUgbWVzc2FnZXMgd2l0aCBtaXNzaW5nIGVuZCBib3VuZGFyeSBhcmUgbm90IHJlcG9ydGVkIGFzIGFuIGVycm9yCisJKGFkZGVkIG1haWwubWltZS5tdWx0aXBhcnQuaWdub3JlbWlzc2luZ2VuZGJvdW5kYXJ5IFN5c3RlbSBwcm9wZXJ0eSkKKzxubyBpZD4JYWNjb21tb2RhdGUgc29tZSBSRkMzNTAxIElNQVAgcHJvdG9jb2wgY2hhbmdlcworPG5vIGlkPglzdXBwb3J0IFJGQzgyMiBncm91cCBsaXN0cyB3aGVuIHBhcnNpbmcgSU1BUCBhZGRyZXNzIGxpc3RzCis8bm8gaWQ+CWRvbid0IHJlYWQgcGFzdCBlbmQgb2YgSU1BUCBwYXJ0LCBmb3IgYnVnZ3kgc2VydmVycyB0aGF0IGRvbid0IGhhbmRsZSBpdAorPG5vIGlkPglmaXggSU1BUCBOQU1FU1BBQ0Ugc3VwcG9ydAorPG5vIGlkPglhbGxvdyBkaWZmZXJlbnQgU01UUFRyYW5zcG9ydCBvYmplY3RzIHRvIGhhdmUgZGlmZmVyZW50IGxvY2FsaG9zdCBuYW1lcworPG5vIGlkPgltYWtlIHN1cmUgc2VydmVyIGlzIHJlYWxseSBhbGl2ZSBpbiBQT1AzRm9sZGVyLmlzT3BlbigpCis8bm8gaWQ+CXN1cHBvcnQgUkZDMjU1NCBBVVRIPSBzdWJtaXR0ZXIgdmlhIG1haWwuc210cC5zdWJtaXR0ZXIgYW5kCisJU01UUE1lc3NhZ2Uuc2V0U3VibWl0dGVyCis8bm8gaWQ+CWFkZGVkIFNNVFBTZW5kRmFpbGVkRXhjZXB0aW9uLCBTTVRQQWRkcmVzc0ZhaWxlZEV4Y2VwdGlvbiwgYW5kCisJU01UUEFkZHJlc3NTdWNjZWVkZWRFeGNlcHRpb24KKzxubyBpZD4JbWFpbC5zbXRwLnJlcG9ydHN1Y2Nlc3MgY2F1c2VzIGFuIGV4Y2VwdGlvbiB0byBiZSB0aHJvd24gZXZlbiBvbgorCXN1Y2Nlc3NmdWwgc2VuZHMsIGFsbG93aW5nIGFjY2VzcyB0byB0aGUgcmV0dXJuIGNvZGVzIGZvciBlYWNoIGFkZHJlc3MKKzxubyBpZD4JZml4IElNQVAgaXNTdWJzY3JpYmVkIGluIGNhc2Ugd2hlcmUgTFNVQiByZXR1cm5zIGEgXE5vc2VsZWN0IGZvbGRlcgorPG5vIGlkPglwYXJzZSBpbnZhbGlkIG1lc3NhZ2VzIHdpdGggbm9uLUFTQ0lJIGNoYXJhY3RlcnMgaW4gYm91bmRhcnkgc3RyaW5nCis8bm8gaWQ+CWFkZCBJTUFQIEFVVEg9UExBSU4gc3VwcG9ydCwgY291cnRlc3kgb2YgU2FuZHkgTWNBcnRodXIKKzxubyBpZD4JYWRkIFNTTCBzdXBwb3J0IHRvIGFsbCBwcm90b2NvbHMsIHNlZSBTU0xOT1RFUy50eHQgZm9yIGRldGFpbHMKKzxubyBpZD4JYWRkIFNUQVJUVExTIHN1cHBvcnQgdG8gSU1BUCBhbmQgU01UUCBwcm90b2NvbHMsIHNlZSBTU0xOT1RFUy50eHQKKzxubyBpZD4JaGFuZGxlIElNQVAgZW1haWwgYWRkcmVzc2VzIGNvbXBvc2VkIG9mIGVtcHR5IHN0cmluZ3MKKzxubyBpZD4JYWRkIFNBU0wgc3VwcG9ydCB0byBJTUFQIHByb3ZpZGVyCis8bm8gaWQ+CXJlbmFtZSBtYWlsLnN0bXAuc2FzbHJlYWxtIHRvIG1haWwuc210cC5zYXNsLnJlYWxtCisKKworCQkgIENIQU5HRVMgSU4gVEhFIDEuMy4xIEZDUyBSRUxFQVNFCisJCSAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK1RoZSBmb2xsb3dpbmcgYnVncyBoYXZlIGJlZW4gZml4ZWQgaW4gdGhlIDEuMy4xIHJlbGVhc2UuCisKKzQ0MTY0MTcJSU1BUCBhbGVydHMgYW5kIG5vdGlmaWNhdGlvbnMgYXJlIG5vdCBzZW50IGluIGFsbCBjYXNlcyAtIG1vcmUgZml4ZXMKKzQ3MDI0MTAJaGVhZGVyIGZvcm1hdHRpbmcgaW5jb3JyZWN0IGZvciBsb25nIG11bHRpYnl0ZQorNDcwNzEwNglBdXRoZW50aWNhdGlvbkZhaWxlZEV4Y2VwdGlvbiBub3QgdGhyb3duIGluIHNvbWUgY2FzZXMgd2l0aCBQT1AzCis0NzA4NjU1CUlNQVBOZXN0ZWRNZXNzYWdlLmdldENvbnRlbnQgd2l0aG91dCBwYXJ0aWFsZmV0Y2gKKzQ3MDk4NDgJbWVzc2FnZV9yZmM4MjIgRGF0YUNvbnRlbnRIYW5kbGVyIGNhbiBjYXVzZSBOUEUKKzQ3MTE2MDYJdXVkZWNvZGVyIGZhaWxzIHdoZW4gcmVhZGluZyBtb3JlIHRoYW4gYSBieXRlIGF0IGEgdGltZQorNDcyNjQ0NwlJbnRlcm5ldEhlYWRlcnMuZ2V0SGVhZGVyKCkgZG9jLiBkb2Vzbid0IGRvY3VtZW50IG51bGwgcG9pbnRlciByZXR1cm4KKzQ3MjY2MjkJSmF2YSBNYWlsIHZlcnkgc2xvdyB3aXRoIGxhcmdlIGF0dGFjaG1lbnQKKzQ3NDE4MTIJSU1BUEZvbGRlciBjYW4gZGVhZGxvY2sKKzQ3NTA1MTQJUkVHUkVTU0lPTjogTWltZUJvZHlQYXJ0LmdldENvbnRlbnQgZmFpbHMgb24gaW1hZ2UvZ2lmIGlmIG5vIFgxMSBwcmVzZW50Cis0NzUwNTE5CXVzaW5nIFNTTCwgU29ja2V0RmV0Y2hlci5nZXRTb2NrZXQwKCkgdGhyb3dzIGluY29ycmVjdCBFeGNlcHRpb24KKzQ3NjI2NDMJSmF2YU1haWwgZG9lcyBub3Qgc3VwcG9ydCBzZWFyY2ggaW4gYWxsIG1lc3NhZ2UncyBwYXJ0cy4KKzQ3ODAyNTUJTWVzc2FnZSBzdWJqZWN0IG5vdCBlbmNvZGVkIGFjY29yZGluZyB0byAnbWFpbC5taW1lLmNoYXJzZXQnIHByb3BlcnR5Cis0Nzg3ODE0CWFjY2Vzc2liaWxpdHkgNTA4IG5vbi1jb21wbGlhbmNlOiAgYXBpL2phdmF4L21haWwvU2Vzc2lvbi5odG1sCis0NzkwNzAwCUphdmFNYWlsIFN0b3JlLmNvbm5lY3QoKSB0aHJvd3Mgd3JvbmcgZXhjZXB0aW9uIHdoZW4gYWxyZWFkeSBjb25uZWN0ZWQKKzQ4MjAwMjUJSU1BUFN0b3JlLmdldFBlcnNvbmFsTmFtZXNwYWNlcyB0aHJvd3MgYSBQcm90b2NvbEV4Y2VwdGlvbgorNDg3NDc4NwlJbnRlcm5ldEFkZHJlc3MudG9Vbmljb2RlU3RyaW5nIHRocm93cyBOUEUsIHBlcnNvbmFsIG5vdCBpbml0aWFsaXplZAorNDg4MjU1NAlMaW5lIGJyZWFrcyBpbiBzdWJqZWN0IHRleHQgYnJlYWsgbWVzc2FnZSBmb3JtYXQKKzxubyBpZD4JZG9uJ3QgY2xvc2UgY29ubmVjdGlvbiBpZiBvcGVuIGZhaWxzLCBwdXQgaXQgYmFjayBpbiB0aGUgcG9vbAorPG5vIGlkPglkb24ndCBhbHdheXMgZmV0Y2ggZW50aXJlIGVudmVsb3BlIGluIElNQVBNZXNzYWdlLmdldFNpemUKKzxubyBpZD4JZml4ZWQgZGVtbyB3ZWJhcHAgdG8gd29yayB3aXRoIHNlcnZsZXQgMi4zIGFuZCBuZXdlcgorPG5vIGlkPglhZGQgRElHRVNULU1ENSBzdXBwb3J0IHRvIFNNVFAgcHJvdmlkZXIsIGNvdXJ0ZXN5IG9mIERlYW4gR2lic29uCis8bm8gaWQ+CWFkZGVkIG1haWwuc210cC5xdWl0d2FpdCBwcm9wZXJ0eSB0byB3YWl0IGZvciByZXNwb25zZSB0byBRVUlUCis8bm8gaWQ+CWFkZGVkIG1haWwuaW1hcC5hdXRoLmxvZ2luLmRpc2FibGUgcHJvcCB0byBkaXNhYmxlIEFVVEhFTlRJQ0FURSBMT0dJTgorCisKKwkJICBDSEFOR0VTIElOIFRIRSAxLjMgRkNTIFJFTEVBU0UKKwkJICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK1RoZSBmb2xsb3dpbmcgYnVncyBoYXZlIGJlZW4gZml4ZWQgaW4gdGhlIDEuMyByZWxlYXNlLgorCis0MTEyMDAyCUlNQVAgcHJvdmlkZXIgaGFuZ3MgaWYgQVBQRU5EIGlzIHByb2hpYml0ZWQKKzQyMDEyMDMJSTE4TjogSW5jb3JyZWN0bHkgZW5jb2RlZCBNSU1FIGhlYWRlciBjYW4ndCBiZSBkZWNvZGVkCisJKHNldCB0aGUgKlN5c3RlbSogcHJvcGVydHkgIm1haWwubWltZS5kZWNvZGV0ZXh0LnN0cmljdCIgdG8gImZhbHNlIikKKzQ0MTM0OTgJSW50ZXJuZXRIZWFkZXJzIHNob3VsZCBhZGQgUmVjZWl2ZWQgaGVhZGVycyBpbiBmcm9udAorNDQxNjQxNwlJTUFQIGFsZXJ0cyBhbmQgbm90aWZpY2F0aW9ucyBhcmUgbm90IHNlbnQgaW4gYWxsIGNhc2VzCis0NDgzMTI1CU11bHRpLWxpbmUgbWFpbCBoZWFkZXIgcHJvY2Vzc2luZyBpcyBzbG93Cis0NDgzMTU4CW51bGwgcG9pbnRlciBleGNlcHRpb24gZm9yIE1lc3NhZ2VDb250ZXh0LmdldE1lc3NhZ2UoKQorNDQ4MzIwNglQbGVhc2UgYWRkIGEgcHVibGljIFBPUDMgVE9QIG1ldGhvZCBpbiB0aGUgbmV4dCByZWxlYXNlIG9mIHRoZSBQT1AzIGFwaQorNDQ4NDA5OAlJTUFQIFBSRUFVVEggZG9lcyBub3Qgd29yaworNDUxNjk3Mwlkb1ByaXZpbGVnZWQgYmxvY2tzIG5lZWRlZCBmb3IgamF2YW1haWwKKzQ1MTc2ODMJbmV3IEZsYWdzKCJGT08iKS5jb250YWlucygiRk9PIikgZmFpbHMKKzQ1MTc2ODYJd2FudCBKYXZhTWFpbC1zcGVjaWZpYyBkZWJ1ZyBvdXRwdXQgc3RyZWFtCis0NjM4NzQzCUphdmFNYWlsIGRvZXMgbm90IHByb3Blcmx5IHBhcnNlIGRhdGVzIGNvbnRhaW5pbmcgZm9sZGluZyB3aGl0ZSBzcGFjZQorNDYzODc0MQlKYXZhTWFpbCBkb2VzIG5vdCBoYW5kbGUgaW4tc3BlYyBJbnRlcm5ldCBncm91cCBhZGRyZXNzZXMgcHJvcGVybHkKKzQ2NTA5NDAJSW50ZXJuZXRBZGRyZXNzIHBhcnNpbmcgc2hvdWxkIGJlIG1vcmUgdG9sZXJhbnQgb2YgYmFkIGFkZHJlc3NlcworNDY1MDk0OQl3cm9uZyBlbmNvZGluZyBjaG9zZW4gZm9yIG5vbi10ZXh0IGRhdGEgaW4gcmFyZSBjYXNlcworNDY1MDk1MglzaG91bGQgYmUgYWJsZSB0byBleHRyYWN0IGdyb3VwIGFkZHJlc3MgbWVtYmVycworNDY3MjMwOAlJbnRlcm5ldEFkZHJlc3MudG9TdHJpbmcgKCkgdGhyb3dzIGEgTnVsbFBvaW50ZXJFeGNlcHRpb24gYWZ0ZXIgY3JlYXRpb24KKzQ2Nzk1MTYJIk5PIiBSZXNwb25zZSBmcm9tIElNQVAgc2VydmVyIGNhdXNlcyBOUEUgZnJvbSBnZXRTdWJqZWN0KCkKKzQ2ODQwNDAJQ2FsbGluZyBGb2xkZXIuZmV0Y2ggdHdpY2UgbWF5IGNhdXNlIHRvIGhlYWRlciBkdXBsaWNhdGlvbgorPG5vIGlkPgltYWtlIHV1ZGVjb2RlciBtb3JlIHRvbGVyYW50IG9mIGluY29ycmVjdCBpbnB1dAorPG5vIGlkPglpbXByb3ZlIHBlcmZvcm1hbmNlIG9mIFNNVFAgZm9yIHNtYWxsIG1lc3NhZ2VzCis8bm8gaWQ+CWhhbmRsZSBjb25uZWN0aW9uIGZhaWx1cmUgZHVyaW5nIG9wZW4gb2YgUE9QMyBmb2xkZXIKKzxubyBpZD4JZW5zdXJlIEFTQ0lJLCBub3QgRUJDRElDIG91dHB1dCBmb3IgUE9QMyBwcm90b2NvbCBvbiBJQk0gbWFpbmZyYW1lcworPG5vIGlkPglhZGQgUE9QM01lc3NhZ2UuaW52YWxpZGF0ZSBtZXRob2QgdG8gaW52YWxpZGF0ZSBjYWNoZWQgbWVzc2FnZSBkYXRhCis8bm8gaWQ+CWZpeCB0aHJlYWQgc2FmZXR5IGJ1ZyBpbiBkYXRlIGZvcm1hdHRpbmcgd2hlbiBhcHBlbmRpbmcgdG8gSU1BUCBmb2xkZXJzCis8bm8gaWQ+CWZpeCBwYXJzaW5nIGJ1ZyBpbiBRVU9UQSBzdXBwb3J0Cis8bm8gaWQ+CWFkZCBtYWlsLmltYXAuYWxsb3dyZWFkb25seXNlbGVjdCBwcm9wZXJ0eSB0byBzdXBwb3J0IHNoYXJlZCBtYWlsYm94ZXMKKzxubyBpZD4JdXNlIHRocmVhZCdzIGNvbnRleHQgY2xhc3MgbG9hZGVyIGZvciBsb2FkaW5nIGNsYXNzZXMKKzxubyBpZD4JYWRkIElNQVBGb2xkZXIuRmV0Y2hQcm9maWxlSXRlbS5IRUFERVIgYW5kIFNJWkUKKzxubyBpZD4JZG9uJ3QgdHJ5IHRvIGxvZ291dCBzdG9yZSBjb25uZWN0aW9uIHR3aWNlCis8bm8gaWQ+CUlNQVBGb2xkZXIuY2xvc2UoZmFsc2UpIHJlYWQtb25seSBmb2xkZXIgZG9lc24ndCBuZWVkIHRvIEVYQU1JTkUgZmlyc3QKKzxubyBpZD4JYWRkIHN1cHBvcnQgZm9yIGdyb3VwIGFkZHJlc3NlcyB0byBTTVRQIHRyYW5zcG9ydAorPG5vIGlkPgl1c2UgYnVpbHRpbiBkZWZhdWx0cyB0byBhbGxvdyBKYXZhTWFpbCB0byB3b3JrIGluIG5ldHNjYXBlIDQKKzxubyBpZD4JdG9sZXJhdGUgdHJhaWxpbmcgc2VtaWNvbG9uIGluIENvbnRlbnQtVHlwZSBoZWFkZXIgKHJlcXVpcmVzIEpBRiAxLjAuMikKKzxubyBpZD4JYWRkIHgtdXVlIGFzIGFub3RoZXIgc3lub255bSBmb3IgdXVlbmNvZGUgQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZworPG5vIGlkPglzZXQgZGVmYXVsdCBjaGFyc2V0IGZvciB0ZXh0IHBhcnRzCis8bm8gaWQ+CXByb3Blcmx5IGVzY2FwZSBDUkxGIGluIE1pbWVVdGlsaXR5LnF1b3RlCis8bm8gaWQ+CWZpeCBOUEUgaW4gTWVzc2FnaW5nRXhjZXB0aW9uLmdldE1lc3NhZ2UKKworCisJCSAgQ0hBTkdFUyBJTiBUSEUgMS4yIEZDUyBSRUxFQVNFCisJCSAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCitUaGUgZm9sbG93aW5nIGJ1Z3MgaGF2ZSBiZWVuIGZpeGVkIGluIHRoZSAxLjIgcmVsZWFzZS4KKworNDEwNzc1MgluZWVkIE1pbWVNZXNzYWdlKE1pbWVNZXNzYWdlIG1zZykgY29uc3RydWN0b3IgdG8gYWxsb3cgY29weWluZyBtZXNzYWdlCis0MTEyMDY1CU5lZWQgQVBJIHRvIGxpc3QgYW5kIHNldC9yZW1vdmUgQUNMcyBvbiBmb2xkZXJzIChJTUFQLXNwZWNpZmljKQorNDExOTY4MQlNaW1lTWVzc2FnZSBzaG91bGQgYWxsb3cgY3JlYXRpb24gb2YgbGlnaHQtd2VpZ2h0IG1lc3NhZ2VzCis0MTI0MDIyIFR3byBjb25uZWN0aW9ucyByZXF1aXJlZCB0byBJTUFQIHNlcnZlciB0byBvcGVuIGEgZm9sZGVyCis0MTI0ODQwCUEgbWVjaGFuaXNtIHRvIGdldCB0aGUgcmF3ICh1bmVuY29kZWQpIGRhdGEgZnJvbSBhIE1pbWVQYXJ0IGlzIG5lZWRlZAorNDEyNjAxMwlqYXZheC5tYWlsLnNlYXJjaCB0ZXJtcyBzaG91bGQgYmUgc2VyaWFsaXphYmxlCis0MTI5NzQzCU1pbWVNZXNzYWdlLnBhcnNlKCkgYW5kIE1pbWVNZXNzYWdlLm1vZGlmaWVkIHNob3VsZCBiZSBwcm90ZWN0ZWQKKzQxMzIwMjkJU01UUCBTdWJtaXQgaXMgbGltaXRlZCB0byA3Yml0OyBkb2VzIG5vdCB1c2UgRVNNVFAvOEJJVE1JTUUKKzQxNDA1NzkgTWltZVV0aWxpdHkuZW5jb2RlKCkgZG9lcyBub3QgYWxsb3cgZm9yIGZpbGVuYW1lIHdoZW4gdXNpbmcgVVVFbmNvZGUKKzQxNjMzNjAgTmVlZCBhIHN1aXRhYmxlIE1lc3NhZ2luZ0V4Y2VwdGlvbiBzdWJjbGFzcyB0byBpbmRpY2F0ZSByZWFkLW9ubHkgZm9sZGVyCis0MTgxMTQ0CUludGVybmV0QWRkcmVzcyBzaG91bGQgYmUgQ2xvbmVhYmxlCis0MjMwNTUzCUF1dGhlbnRpY2F0aW9uRmFpbGVkRXhjZXB0aW9uIHNob3VsZCBpbmNsdWRlIGVycm9yIG1lc3NhZ2UgZnJvbSBzZXJ2ZXIKKzQyNTkyMTEgZXhjZXB0aW9uIGNvbnN0cnVjdG9ycyBpbmNvbnNpc3RlbnQKKzQyNjYzOTAgTWFpbERhdGVGb3JtYXQgY2xhc3Mgc2hvdWxkIGJlIHBhcnQgb2YgdGhlIHB1YmxpYyBBUEkKKzQyODE3MjkgQWRkcmVzc1N0cmluZ1Rlcm0ubWF0Y2ggYnVnCis0MzE5ODk1CVBPUDMgcHJvdmlkZXIgZG9lc24ndCBlbmZvcmNlIHJlYWQtb25seSBtb2RlCis0MzE5OTU3CUFtYmlndW91cyBkb2N1bWVudGF0aW9uIGluIEphdmFtYWlsIDEuMS4zIGVhcmx5IGFjY2VzcyBlZGl0aW9uCis0MzI4ODI0IHN0cmluZyBiYXNlZCBtZXRob2RzIHRvIGFkZCByZWNpcGllbnRzCis0MzI4ODI2IGdldERlZmF1bHRJbnN0YW5jZSBtZXRob2Qgd2l0aCBubyBBdXRoZW50aWNhdG9yCis0MzMwNTgwCU1pbWVNdWx0aXBhcnQuZ2V0Qm9keVBhcnQoU3RyaW5nIENJRCkgdGhyb3dzIGV4Y2VwdGlvbgorNDMzMzY5NAlOdWxsUG9pbnRlckV4Y2VwdGlvbiBpbiB2ZXJzaW9uIDEuMS4xIG9mIHRoZSBQT1AzIFByb3ZpZGVyCis0MzM2NDM1CXF1b3RlZCByaWdodCBhbmdsZSBicmFja2V0IG5vdCBoYW5kbGVkIGluIEludGVybmV0QWRkcmVzcworNDMzOTIwMwl3cml0ZVRvIHNob3VsZCBhdXRvbWF0aWNhbGx5IGNhbGwgc2F2ZUNoYW5nZXMKKzQzNDA2NDgJTWltZVV0aWxpdHkuZ2V0RW5jb2RpbmcoRGF0YUhhbmRsZXIpIG1ldGhvZCBzaG91bGQgYmUgcHVibGljCis0MzY0ODI3CVN1cHBvcnQgSU1BUCBOQU1FU1BBQ0UgZXh0ZW5zaW9uCis0MzY2MzczCUNvbnRlbnREaXNwb3NpdGlvbiBjbGFzcyBzaG91bGQgYmUgcHVibGljCis0MzcxODYyCWltcHJvdmUgcGVyZm9ybWFuY2Ugb2YgTWltZU1lc3NhZ2UKKzQzNzI3MDAgUGFyYW1ldGVyTGlzdC50b1N0cmluZyBtZXRob2Qgc2hvdWxkIGFsbG93IGZvciByZXR1cm5pbmcgZm9sZGVkIHJlc3VsdHMKKzxubyBpZD4JbW9zdCBjb250cm9sIGNoYXJhY3RlcnMgbXVzdCBiZSBlbmNvZGVkLCBub3Qgc2VudCBhcyAiN2JpdCIKKzxubyBpZD4JYXBwZW5kaW5nIHZlcnkgbGFyZ2UgbWVzc2FnZSB0byBJTUFQIGZvbGRlciB1c2VzIHRvbyBtdWNoIG1lbW9yeQorPG5vIGlkPgljaGFuZ2VkIG11bHRpcGFydCBib3VuZGFyeSBnZW5lcmF0aW9uIHRvIG5vdCBpbmNsdWRlIGVtYWlsIGFkZHJlc3MKKzxubyBpZD4Jc3VwcG9ydCBJTUFQIExJVEVSQUwrIGV4dGVuc2lvbiAoUkZDIDIwODgpCis8bm8gaWQ+CWFsbG93IFNNVFAgbXVsdGlsaW5lIHJlcG9uc2VzIHdpdGggbm8gdGV4dCAoZS5nLiwgIjI1MC0iKQorPG5vIGlkPglmaXggbWFueSBwb3RlbnRpYWwgbG9ja2luZyBidWdzIGluIElNQVAgcHJvdmlkZXIKKzxubyBpZD4JYWRkIG1haWwuc210cC5zZW5kcGFydGlhbCBwcm9wZXJ0eSB0byBzZW5kIG1zZyB3aXRoIHNvbWUgYmFkIGFkZHJlc3NlcworPG5vIGlkPglhZGQgbWFpbC5wb3AzLnJzZXRiZWZvcmVxdWl0IHByb3BlcnR5IChzZWUgTk9URVNULnR4dCkKKzxubyBpZD4JdGhyb3cgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGluc3RlYWQgb2YgTWVzc2FnaW5nRXhjZXB0aW9uIHdoZW4gZm9sZGVyCisJaXMgbm90IG9wZW4gKG9yIGNsb3NlZCwgYXMgYXBwcm9wcmlhdGUpCis8bm8gaWQ+CWFkZGVkIHN1cHBvcnQgZm9yIElNQVAgUVVPVEEgZXh0ZW5zaW9uCis8bm8gaWQ+CWFkZGVkIHN1cHBvcnQgZm9yIElNQVAgUFJFQVVUSCBncmVldGluZyByZXNwb25zZQorPG5vIGlkPglhZGRlZCBEYXRhQ29udGVudEhhbmRsZXIgZm9yIHRleHQveG1sIGRhdGEKKzxubyBpZD4JYWRkZWQgU01UUE1lc3NhZ2UgY2xhc3MgdG8gc3BlY2lmeSBTTVRQIG9wdGlvbnMgb24gYSBwZXItbWVzc2FnZSBiYXNpcworPG5vIGlkPglhZGRlZCBqYXZhZG9jcyBmb3IgU3VuIHByb3RvY29sIHByb3ZpZGVycworPG5vIGlkPgltYWlsLnBvcDMubWVzc2FnZS5jbGFzcyBwcm9wZXJ0eSBhbGxvd3MgUE9QM01lc3NhZ2UgY2xhc3MgdG8gYmUgcmVwbGFjZWQKKzxubyBpZD4JbWFpbC57c210cCxpbWFwLHBvcDN9LmNvbm5lY3Rpb250aW1lb3V0IHByb3BlcnR5IGZvciBjb25uZWN0aW9uIHRpbWVvdXRzCisKKworCisJCSAgQ0hBTkdFUyBJTiBUSEUgMS4xLjMgRkNTIFJFTEVBU0UKKwkJICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorVGhlIGZvbGxvd2luZyBidWdzIGhhdmUgYmVlbiBmaXhlZCBpbiB0aGUgMS4xLjMgcmVsZWFzZS4KKworNDI0ODc1NQlQcm9ibGVtIGxvYWRpbmcgYSBjdXN0b20gcHJvdmlkZXIKKzQyNDkwNDYJZG9uJ3QgcHV0IHNwYWNlIGFmdGVyIFNNVFAgRlJPTTogYW5kIFRPOgorNDI0OTA1OAlJTUFQIGFwcGVuZE1lc3NhZ2VzKCkgc2hvdWxkIGluY2x1ZGUgdGhlIG1lc3NhZ2UgRmxhZ3MgYXMgd2VsbC4KKzQyNjMxODUJSmF2YU1haWwgYW5kIEpBRiBjYW4ndCBmaW5kIHByb3BlcnRpZXMgd2hlbiB1c2VkIGFzIHN0ZCBleHQKKzQyNzE3MTQJREVCVUcgbWVzc2FnZSBhbHdheXMgcHJpbnRlZCB3aGVuIHByb3ZpZGVycyBsb2FkZWQgZnJvbSA8amF2YS5ob21lPi9saWIKKzQyNzYwODAJZ2V0RW5jb2RpbmcgbWV0aG9kIGRvZXNuJ3QgcGFyc2UgTUlNRSBoZWFkZXIKKzQyNzk2MDMJUkZDODIyIGFuZCBNSU1FIHNwZWNpYWxzIGRvZXMgbm90IGluY2x1ZGUgcGVyaW9kICIuIgorNDI5Mjc5Mwl1c2luZyBNZXNzYWdlLnJlcGx5KHRydWUpIHR3aWNlIG9uIHRoZSBzYW1lIElNQVAgbWVzc2FnZSBjYXVzZXMgTlBFCis0MjkzNjA1CWphdmF4Lm1haWwuTWltZU11bHRpcGFydCBib3VuZGFyeSBzdHJpbmcgY29udGFpbnMgaW52YWxpZCBjaGFyYWN0ZXJzCis0Mjk2NzExCUphdmFNYWlsIElNQVAgcHJvdmlkZXIgZG9lc24ndCBzZXQgU0VFTiBvbiBtZXNzYWdlcyB3aXRoIDAgbGVuZ3RoIGJvZHkKKzQzMDU2ODcJSmF2YU1haWwgc3BlYWtpbmcgU01UUCBmYWlscyB0byBxdW90ZSBkb3RzIGluIHNvbWUgY2FzZXMKKzxubyBpZD4JYWRkIHN1cHBvcnQgZm9yIFNNVFAgQXV0aGVudGljYXRpb24sIHNlZSBOT1RFUy50eHQKKzxubyBpZD4JYWRkIHN1cHBvcnQgZm9yIFNNVFAgRGVsaXZlcnkgU3RhdHVzIE5vdGlmaWNhdGlvbiwgc2VlIE5PVEVTLnR4dAorPG5vIGlkPglTTVRQIHJldHVybiBhZGRyZXNzIGlzIG5vdyBzZXQgaW4gbWFpbC5zbXRwLmZyb20KKzxubyBpZD4JZml4IGJ1ZyBpbiBJbnRlcm5ldEFkZHJlc3Mgd2hlbiBwYXJzaW5nIGBgPHhAZm9vLmNvbT4gKE1yLiBYKScnCis8bm8gaWQ+CWltcHJvdmUgamF2YWRvY3MgaW4gbWFueSBwbGFjZXMgYmFzZWQgb24gcXVlc3Rpb25zIHRvIGphdmFtYWlsQHN1bi5jb20KKzxubyBpZD4JYXZvaWQgSkRLIDEuMiBidWcgNDIwODk2MCBpbiBTaW1wbGVUaW1lWm9uZS5nZXRPZmZzZXQKKzxubyBpZD4JY2Fub25pY2FsaXplIHRoZSBVUkxOYW1lIGJlZm9yZSBmZXRjaGluZyBzYXZlZCBQYXNzd29yZEF1dGhlbnRpY2F0aW9uCis8bm8gaWQ+CWNvbnZlcnQgU2ltcGxlQ2xpZW50IHRvIHN3aW5nIDEuMSBwYWNrYWdlIG5hbWVzIChqYXZheC5zd2luZy4qKQorPG5vIGlkPglmb2xkZXIuZ2V0VVJMTmFtZSgpIHNob3VsZCByZXR1cm4gbmF0aXZlIHNlcGFyYXRvciwgbm90IC8sIHBlciBSRkMgMjE5MgorPG5vIGlkPgl1c2UgSkRLIDEuMiBDbGFzc0xvYWRlci5nZXRSZXNvdXJjZXMoKSBtZXRob2QgKGlmIGF2YWlsYWJsZSkgdG8gZmluZCBhbGwKKwlNRVRBLUlORi9qYXZhbWFpbC5wcm92aWRlcnMgYW5kIE1FVEEtSU5GL2phdmFtYWlsLmFkZHJlc3MubWFwIGZpbGVzIGluCisJdGhlIENMQVNTUEFUSCwgdG8gYmV0dGVyIHN1cHBvcnQgcHJvdG9jb2wgcHJvdmlkZXIgamFyIGZpbGVzCis8bm8gaWQ+CWVuY29kZS9kZWNvZGUgdXNlcm5hbWUgYW5kIHBhc3N3b3JkIGZpZWxkcyBvZiBVUkxOYW1lIHRvIGFsbG93IChlLmcuKQorCXVzZXJuYW1lcyB3aXRoICJAIgorPG5vIGlkPglhZGRlZCBEYXRhQ29udGVudEhhbmRsZXIgZm9yIHRleHQvaHRtbCwgdG8gc2ltcGxpZnkgY3JlYXRpb24gb2YgSFRNTAorCW1lc3NhZ2VzIGFuZCBib2R5IHBhcnRzCis8bm8gaWQ+CXJlbW92ZSBlc2NhcGVzIGZyb20gcGVyc29uYWwgbmFtZSB3aGVuIHBhcnNpbmcgaW4gSW50ZXJuZXRBZGRyZXNzCis8bm8gaWQ+CWNhY2hlIHJlc3VsdHMgb2YgSU1BUCBTVEFUVVMgY29tbWFuZCBmb3IgMSBzZWNvbmQsIHRvIGltcHJvdmUKKwlwZXJmb3JtYW5jZSBvZiBiYWNrLXRvLWJhY2sgY2FsbHMgdG8gZ2V0TWVzc2FnZUNvdW50LAorCWdldE5ld01lc3NhZ2VDb3VudCwgZ2V0VW5yZWFkTWVzc2FnZUNvdW50Cis8bm8gaWQ+CWZpeCBJbnRlcm5ldEhlYWRlcnMgRW51bWVyYXRpb24gdG8gd29yayBldmVuIGlmIGhhc01vcmVFbGVtZW50cyBpc24ndAorCWNhbGxlZAorPG5vIGlkPglzdXBwb3J0IG1haWwuc210cC50aW1lb3V0IHByb3BlcnR5CisKKworCisJCSAgQ0hBTkdFUyBJTiBUSEUgMS4xLjIgRkNTIFJFTEVBU0UKKwkJICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorVGhlIGZvbGxvd2luZyBidWdzIGhhdmUgYmVlbiBmaXhlZCBpbiB0aGUgMS4xLjIgcmVsZWFzZS4KKworPG5vIGlkPiBGaXhlZCBidWcgd2hlcmUgSU1BUCBzZXJ2ZXIgY29ubmVjdGlvbiBoYW5ncyBhcm91bmQgZXZlbiB0aG91Z2gKKwl0aGUgY29ubmVjdCgpIG1ldGhvZCBmYWlsZWQuCis0MTk5NTk1CWZvcmNlIHF1b3RlZC1wcmludGFibGUgZW5jb2Rpbmcgb2YgbG9uZyB0ZXh0IGxpbmVzCis8bm8gaWQ+CWZpeCBidWcgaW4gU01UUCBvdXRwdXQgdGhhdCBzb21ldGltZXMgZHVwbGljYXRlZCAiLiIKKzxubyBpZD4JY2xvc2UgU01UUCB0cmFuc3BvcnQgb24gSS9PIGVycm9yCis0MjMwNTQxCWRvbid0IHNlbmQgU01UUCBOT09QIHVubmVjZXNzYXJpbHkKKzQyMTY2NjYgSU1BUCBwcm92aWRlciBJTlRFUk5BTERBVEUgZm9ybWF0dGVyIGVycm9yLCBjYXVzaW5nIAorCXByb2JsZW1zIGR1cmluZyBhcHBlbmRNZXNzYWdlcygpCis0MjI3ODg4IElNQVAgcHJvdmlkZXIgZG9lcyBub3QgaG9ub3IgdGhlIFVJRCBpdGVtIGluIGl0cyBGZXRjaFByb2ZpbGUKKworCisJCSAgQ0hBTkdFUyBJTiBUSEUgMS4xLjEgRkNTIFJFTEVBU0UKKwkJICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorVGhlIGZvbGxvd2luZyBidWdzIGhhdmUgYmVlbiBmaXhlZCBpbiB0aGUgMS4xLjEgcmVsZWFzZS4KKworNDE4MTE0MyBwZXJzb25hbCBjYW4ndCBiZSBudWxsIGluIGNvbnN0cnVjdG9yCis0MTM0MjczIG1vcmUgY2FyZWZ1bCAmIHBpY2t5IGFkZHJlc3MgcGFyc2luZyBpbiBJbnRlcm5ldEFkZHJlc3MgcGFyc2VyCis0MTgzNzAwIFNNVFBUcmFuc3BvcnQgZmFpbHMgdG8gY2xvc2Ugc29ja2V0IHVuZGVyIGNlcnRhaW4gc2l0dWF0aW9ucy4KKzxubyBpZD4gSU1BUCBwcm92aWRlciByZXRhaW5zIGFwcGVuZGVkIG1lc3NhZ2UncyBpbnRlcm5hbCBkYXRlIGR1cmluZworCUZvbGRlci5hcHBlbmRNZXNzYWdlcyhNZXNzYWdlW10gbSk7Cis8bm8gaWQ+IE1vcmUgZWZmaWNpZW50IHNlcnZlci1zaWRlIHNlYXJjaCBmb3IgTWVzc2FnZUlEVGVybSBpbiB0aGUKKwlJTUFQIHByb3ZpZGVyCis8bm8gaWQ+IEZpeCBSRkMyMDQ3IGRlY29kaW5nIGJ1ZyBpbiBJbnRlcm5ldEFkZHJlc3MuZ2V0UGVyc29uYWwoKQorPG5vIGlkPiBCZSBtb3JlIHRvbGVyYW50IG9mIGlsbGVnYWxseSBmb3JtYXR0ZWQgZGF0ZXMgaW4gZGF0ZSBwYXJzaW5nLgorPG5vIGlkPiBpZ25vcmUgZW1wdHkgbGluZXMgaW4gbG9hZE1hcHBpbmdzCis8bm8gaWQ+IGZvcmdvdCB0byB1c2UgamF2YUNoYXJzZXQoKSBpbiBNaW1lVXRpbGl0eS5kZWNvZGVXb3JkKCkKKzxubyBpZD4gQWxsb3cgYWRkcmVzc2VzIHdpdGhvdXQgaG9zdG5hbWVzIGluIEludGVybmV0QWRkcmVzcyBwYXJzZXIKKzxubyBpZD4gdW5yZWNvZ25pemVkIGNoYXJzZXRzIGNhbiBjYXVzZSBJbGxlZ2FsQXJndW1lbnQgcnVudGltZQorCWV4Y2VwdGlvbiB3aGVuIGludm9raW5nIGdldENvbnRlbnQoKS4KKzxubyBpZD4gQXV0aGVudGljYXRpb24gZmFpbHVyZSB3aGVuIGNvbm5lY3RpbmcgdG8gU3VuIElNQVAgc2VydmVyLgorPG5vIGlkPglSZXNldCBTTVRQIGNvbm5lY3Rpb24gYWZ0ZXIgaW52YWxpZCBhZGRyZXNzIHRvIGFsbG93IGZ1dHVyZQorCXNlbmRzIHRvIHN1Y2NlZWQKKzxubyBpZD4JQW55IHJlc3BvbnNlIHRvIGFuIFNNVFAgTk9PUCBjb21tYW5kIG1lYW5zIHdlJ3JlIHN0aWxsIGNvbm5lY3RlZApkaWZmIC0tZ2l0IGEvZG9jL3JlbGVhc2UvQ09NUEFULnR4dCBiL2RvYy9yZWxlYXNlL0NPTVBBVC50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDVhN2VjMgotLS0gL2Rldi9udWxsCisrKyBiL2RvYy9yZWxlYXNlL0NPTVBBVC50eHQKQEAgLTAsMCArMSwzNzcgQEAKKwkJCUNPTVBBVElCSUxJVFkgTk9URVMKKwkJCT09PT09PT09PT09PT09PT09PT0KKworCQkgICAgSmF2YU1haWwoVE0pIEFQSSAke21haWwudmVyc2lvbn0gcmVsZWFzZQorCQkgICAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK1RoZSBKYXZhTWFpbCAxLjYgc3BlY2lmaWNhdGlvbiBpcyBmdWxseSBjb21wYXRpYmxlIHdpdGggdGhlIEphdmFNYWlsCisxLjUgc3BlY2lmaWNhdGlvbiwgd2l0aCB0aGUgZXhjZXB0aW9ucyBsaXN0ZWQgYmVsb3cuCisKK0luIGFkZGl0aW9uLCBjaGFuZ2VzIGluIHRoZSBpbXBsZW1lbnRhdGlvbiBtYXkgaW1wYWN0CithcHBsaWNhdGlvbnMgdGhhdCBkZXBlbmQgb24gYmVoYXZpb3IgYmV5b25kIHdoYXQgaXMgZGVmaW5lZCBieSB0aGUKK0phdmFNYWlsIHNwZWNpZmljYXRpb24sIG9yIHRoYXQgdXNlIGZlYXR1cmVzIHNwZWNpZmljIHRvIHRoZSByZWZlcmVuY2UKK2ltcGxlbWVudGF0aW9uLiAgVGhpcyBub3RlIHN1bW1hcml6ZXMgcG90ZW50aWFsIGNvbXBhdGliaWxpdHkgaXNzdWVzCit3aXRoIHRoaXMgcmVsZWFzZSBvZiB0aGUgSmF2YU1haWwgQVBJLgorCisKKy0tIEphdmFNYWlsIDEuNi4zIC0tCisKKy0gTWF2ZW4gY29vcmRpbmF0ZXMgZm9yIEphdmFNYWlsIGNoYW5nZWQuCisKKwlKYXZhTWFpbCBoYXMgbW92ZWQgdG8gdGhlIEVjbGlwc2UgRm91bmRhdGlvbiBhcyBwYXJ0IG9mIHRoZSBFRTRKCisJcHJvamVjdCwgYW5kIHdpbGwgYmUgaW5jbHVkZWQgaW4gdGhlIEpha2FydGEgRUUgc3BlY2lmaWNhdGlvbi4KKwlUaGUgTWF2ZW4gY29vcmRpbmF0ZXMgZm9yIEphdmFNYWlsIGFyZSBub3c6CisKKwktIGNvbS5zdW4ubWFpbDpqYWthcnRhLm1haWwJLSBjb21wbGV0ZSBKYXZhTWFpbCBqYXIgZmlsZQorCS0gamFrYXJ0YS5tYWlsOmpha2FydGEubWFpbC1hcGkJLSBBUEkgamFyIGZpbGUgZm9yIGNvbXBpbGluZyBvbmx5CisKKwlXaGVuIHVwZGF0aW5nIGRlcGVuZGVuY2llcyB0byB1c2UgSmF2YU1haWwgMS42LjMgb3IgbmV3ZXIsIHRoZQorCWFydGlmYWN0SWQgd2lsbCBuZWVkIHRvIGJlIGNoYW5nZWQgYXMgYWJvdmUuICBUaGUgQVBJcyBhcmUKKwlvdGhlcndpc2UgY29tcGF0aWJsZS4KKworLSBKYXZhIG1vZHVsZSBzeXN0ZW0gbmFtZSBjaGFuZ2VkLgorCisJRXhwZXJpbWVudGFsIHN1cHBvcnQgZm9yIHRoZSBKYXZhIHBsYXRmb3JtIG1vZHVsZSBzeXN0ZW0gd2FzCisJYWRkZWQgaW4gdGhlIHByZXZpb3VzIHJlbGVhc2UgdXNpbmcgdGhlIG5hbWUgImphdmEubWFpbCIgZm9yIHRoZQorCUFQSSBtb2R1bGUgKG1haWxhcGkuamFyKS4gIEluIHRoaXMgcmVsZWFzZSB0aGUgbmFtZSBvZiB0aGF0CisJbW9kdWxlIGlzIGNoYW5nZWQgdG8gImpha2FydGEubWFpbCIuCisKKworLS0gSmF2YU1haWwgMS42LjIgLS0KKworLSBQcm90b2NvbCBwcm92aWRlcnMgbm93IGxvYWRlZCB1c2luZyB0aGUgamF2YS51dGlsLlNlcnZpY2VMb2FkZXIgbWVjaGFuaXNtLgorCisJQWxsIHRoZSBwcm90b2NvbCBwcm92aWRlcnMgaW5jbHVkZWQgd2l0aCBKYXZhTWFpbCwgYXMgd2VsbCBhcworCXRoaXJkIHBhcnR5IHByb3ZpZGVycywgY2FuIHVzZSB0aGUgU2VydmljZSBMb2FkZXIgbWVjaGFuaXNtIHRvCisJY29uZmlndXJlIHRoZSBwcm92aWRlciwgaW5zdGVhZCBvZiB1c2luZyB0aGUKKwlNRVRBLUlORi9qYXZhbWFpbC5kZWZhdWx0LnByb3ZpZGVycyBvciBNRVRBLUlORi9qYXZhbWFpbC5wcm92aWRlcnMKKwlmaWxlLiAgVGhlc2UgSmF2YU1haWwgcHJvdmlkZXIgY29uZmlndXJhdGlvbiBmaWxlcyBhcmUgb25seSByZWFkCisJaWYgdGhlIFNlcnZpY2VMb2FkZXIgZmFpbHMgdG8gZmluZCBhIHByb3ZpZGVyIHRoYXQgc3VwcG9ydHMgdGhlCisJcmVxdWVzdGVkIHByb3RvY29sLiAgVGhpcyBtYXkgaGF2ZSB0aGUgZWZmZWN0IG9mIGNoYW5naW5nIHRoZSBvcmRlcgorCWluIHdoaWNoIHByb3ZpZGVycyBhcmUgbG9hZGVkLCB3aGljaCBzaG91bGQgb25seSBiZSBhbiBpc3N1ZSBpZgorCW11bHRpcGxlIHByb3ZpZGVycyBzdXBwb3J0IHRoZSBzYW1lIHByb3RvY29sIG5hbWUuCisKKworLS0gSmF2YU1haWwgMS42LjEgLS0KKworLSBjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nIG5vIGxvbmdlciBpbmNsdWRlZCBpbiBtYWlsYXBpLmphci4KKworCUlmIHlvdSdyZSB1c2luZyBtYWlsYXBpLmphciBhbmQgZGVwZW5kIG9uIHRoZSBjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nCisJY2xhc3NlcywgeW91J2xsIG5lZWQgdG8gaW5jbHVkZSB0aGUgbG9nZ2luZy1tYWlsaGFuZGxlci5qYXIgZmlsZSBpbgorCXlvdXIgYXBwbGljYXRpb24gY2xhc3MgcGF0aC4KKworCisKKy0tIEphdmFNYWlsIDEuNiAtLQorCistIFB1YmxpYyBBUEkgdXBkYXRlZCB0byB1c2UgZ2VuZXJpY3MKKworCU1ldGhvZHMgaW4gdGhlIGZvbGxvd2luZyBjbGFzc2VzIGhhdmUgYmVlbiB1cGRhdGVkIHRvIHVzZSBnZW5lcmljcy4KKwlUaGlzIGNoYW5nZSBzaG91bGQgYmUgYmluYXJ5IGNvbXBhdGlibGUgYnV0IG1heSByZXF1aXJlIHNvdXJjZQorCWNvZGUgY2hhbmdlcyBpbiBhcHBsaWNhdGlvbnMuCisKKwkJamF2YXgubWFpbC5NdWx0aXBhcnQKKwkJamF2YXgubWFpbC5QYXJ0CisJCWphdmF4Lm1haWwuU2VydmljZQorCQlqYXZheC5tYWlsLmludGVybmV0LkludGVybmV0SGVhZGVycworCQlqYXZheC5tYWlsLmludGVybmV0Lk1pbWVCb2R5UGFydAorCQlqYXZheC5tYWlsLmludGVybmV0Lk1pbWVNZXNzYWdlCisJCWphdmF4Lm1haWwuaW50ZXJuZXQuTWltZVBhcnQKKwkJamF2YXgubWFpbC5pbnRlcm5ldC5QYXJhbWV0ZXJMaXN0CisKKy0gSkRLIDEuNyBvciBuZXdlciByZXF1aXJlZAorCisJVGhlIEphdmFNYWlsIHJlZmVyZW5jZSBpbXBsZW1lbnRhdGlvbiBub3cgcmVxdWlyZXMgSkRLIDEuNworCW9yIG5ld2VyLiAgSXQgaXMgZXhwZWN0ZWQgdGhhdCB0aGUgbGFyZ2UgbWFqb3JpdHkgb2YgdXNlcnMKKwlhcmUgYWxyZWFkeSB1c2luZyBKREsgMS43IG9yIG5ld2VyLgorCistIE1haWxEYXRlRm9ybWF0IGNoYW5nZXMKKworCVRoZSBmb2xsb3dpbmcgY2hhbmdlcyB0byBNYWlsRGF0ZUZvcm1hdCBtYXkgaW1wYWN0IGFwcGxpY2F0aW9uczoKKworCSogcGFyc2UoU3RyaW5nKSBub3cgdGhyb3dzIGEgUGFyc2VFeGNlcHRpb24gb24gaW52YWxpZCBpbnB1dCBpbnN0ZWFkCisJICBvZiByZXR1cm5pbmcgbnVsbCwgdG8gY29uZm9ybSB0byB0aGUgRGF0ZUZvcm1hdCBjb250cmFjdAorCSogdGhlIGZvbGxvd2luZyBtZXRob2RzIG5vdyB0aHJvdyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgorCSAgdG8gcHJldmVudCB0YW1wZXJpbmcgd2l0aCBNYWlsRGF0ZUZvcm1hdCdzIGludGVybmFsczoKKworCQlnZXQyRGlnaXRZZWFyU3RhcnQKKwkJYXBwbHlMb2NhbGl6ZWRQYXR0ZXJuCisJCWFwcGx5UGF0dGVybgorCQlzZXQyRGlnaXRZZWFyU3RhcnQKKwkJc2V0RGF0ZUZvcm1hdFN5bWJvbHMKKworLSBtZXRob2QgYWRkZWQgdG8gVUlERm9sZGVyIGludGVyZmFjZQorCisJVGhlIFVJREZvbGRlciBpbnRlcmZhY2UgaGFzIGEgbmV3IGdldFVJRE5leHQoKSBtZXRob2QuICBBbnkKKwljbGFzc2VzIGltcGxlbWVudGluZyB0aGUgVUlERm9sZGVyIGludGVyZmFjZSB3aWxsIG5lZWQgdG8gYWRkCisJdGhpcyBtZXRob2QuICBUaGUgSU1BUEZvbGRlciBjbGFzcyBpbXBsZW1lbnRzIHRoZSBVSURGb2xkZXIKKwlpbnRlcmZhY2UgYW5kIGhhcyBwcm92aWRlZCB0aGlzIG1ldGhvZCBmb3Igc29tZSB0aW1lLgorCistIFlvdW5nZXJUZXJtLCBPbGRlclRlcm0sIGFuZCBNb2RpZmllZFNpbmNlVGVybSBmYWxsIGJhY2sgdG8gbG9jYWwgc2VhcmNoaW5nCisKKwlJbiBnZW5lcmFsLCBTZWFyY2hUZXJtcyB0aGF0IGFyZSBub3QgdW5kZXJzdG9vZCBieSB0aGUgSU1BUAorCXByb3ZpZGVyIG9yIG5vdCBzdXBwb3J0ZWQgYnkgdGhlIElNQVAgc2VydmVyIGZhbGwgYmFjayB0byBkb2luZworCWxvY2FsIHNlYXJjaGluZy4gIFRoZSBJTUFQLXNwZWNpZmljIFlvdW5nZXJUZXJtLCBPbGRlclRlcm0sIGFuZAorCU1vZGlmaWVkU2luY2VUZXJtIHdlcmUgaW5zdGVhZCB0aHJvd2luZyBhbiBleGNlcHRpb24gaWYgdGhlIHNlcnZlcgorCWRpZG4ndCBzdXBwb3J0IHRoZSBleHRlbnNpb24gdGhhdCB0aGUgc2VhcmNoIHRlcm0gZGVwZW5kZWQgb24uCisJVGhpcyBoYXMgYmVlbiBmaXhlZCB0byBmYWxsIGJhY2sgdG8gZG9pbmcgdGhlIHNlYXJjaCBsb2NhbGx5LgorCVRoaXMgYmVoYXZpb3IgY2FuIGJlIGNoYW5nZWQgYnkgc2V0dGluZyB0aGUgcHJvcGVydHkKKwkibWFpbC5pbWFwLnRocm93c2VhcmNoZXhjZXB0aW9uIiB0byAidHJ1ZSIgdG8gY2F1c2UgYW4gZXhjZXB0aW9uCisJdG8gYmUgdGhyb3duIGlmIHRoZSBzZXJ2ZXIgY2FuJ3QgcGVyZm9ybSB0aGUgc2VhcmNoLgorCisKKworLS0gSmF2YU1haWwgMS41LjYgLS0KKworLSBmaW5hbGl6ZXJzIGNsb3NlIHNvY2tldHMgYWJydXB0bHkKKworCUl0J3MgaW1wb3J0YW50IGZvciBmaW5hbGl6ZXJzIHRvIGNsb3NlIGFuIG9wZW4gc29ja2V0CisJY29ubmVjdGlvbiB0byBwcmV2ZW50IGZpbGUgZGVzY3JpcHRvciBsZWFrcy4gIFByZXZpb3VzbHkgdGhlCisJZmluYWxpemVycyBmb3IgdGhlIElNQVAgYW5kIFBPUDMgcHJvdmlkZXJzIHdvdWxkIHRyeSB0byBjbG9zZQorCXRoZSBjb25uZWN0aW9uIGNsZWFubHksIHdoaWNoIGNvdWxkIHJlc3VsdCBpbiBhIHRpbWVvdXQgd2FpdGluZworCWZvciB0aGUgc2VydmVyLiAgVGhleSBub3cgY2xvc2UgdGhlIGNvbm5lY3Rpb24gd2l0aG91dAorCXBlcmZvcm1pbmcgYW55IHNvY2tldCBJL08sIHdoaWNoIG1heSByZXN1bHQgaW4gYW4gdW5jbGVhbgorCXNodXRkb3duIHdoZW4gc2VlbiBmcm9tIHRoZSBzZXJ2ZXIuICBBcHBsaWNhdGlvbnMgc2hvdWxkIGFsd2F5cworCWNsb3NlIFN0b3JlcyBhbmQgRm9sZGVycyB3aGVuIGRvbmUgd2l0aCB0aGVtIHRvIGF2b2lkIHRoZSBuZWVkCisJZm9yIHRoZSBmaW5hbGl6ZXIgdG8gZG8gdGhpcyBjbGVhbnVwLiAgVGhlIFNlc3Npb24gcHJvcGVydHkKKwkibWFpbC48cHJvdG9jb2w+LmZpbmFsaXplY2xlYW5jbG9zZSIgY2FuIGJlIHNldCB0byAidHJ1ZSIgdG8KKwlmb3JjZSB0aGUgY29ubmVjdGlvbiB0byBiZSBjbG9zZWQgY2xlYW5seSBpbiB0aGUgZmluYWxpemVyLgorCistIEludGVybmV0QWRkcmVzcy5nZXRMb2NhbEFkZHJlc3MgdXNlcyBjYW5vbmljYWwgaG9zdCBuYW1lCisKKwlUaGUgSW50ZXJuZXRBZGRyZXNzLmdldExvY2FsQWRkcmVzcyBtZXRob2Qgbm93IHVzZXMgdGhlCisJamF2YS5uZXQuSW5ldEFkZHJlc3MuZ2V0Q2Fub25pY2FsSG9zdE5hbWUgbWV0aG9kIGlmIG5laXRoZXIgdGhlCisJIm1haWwuZnJvbSIgbm9yICJtYWlsLmhvc3QiIHByb3BlcnRpZXMgaGF2ZSBiZWVuIHNldC4gIFRoZSBTeXN0ZW0KKwlwcm9wZXJ0eSAibWFpbC5taW1lLmFkZHJlc3MudXNlY2Fub25pY2FsaG9zdG5hbWUiIGNhbiBiZSBzZXQgdG8KKwkiZmFsc2UiIHRvIHJldmVydCB0byB0aGUgcHJldmlvdXMgYmVoYXZpb3IuCisKKy0gU01UUFRyYW5zcG9ydC5zYXNsbG9naW4gbm8gbG9uZ2VyIHB1YmxpYworCisJVGhlIFNNVFBUcmFuc3BvcnQuc2FzbGxvZ2luIG1ldGhvZCBzaG91bGQgbmV2ZXIgaGF2ZSBiZWVuCisJZGVjbGFyZWQgcHVibGljLiAgSXQncyB1c2VkIGludGVybmFsbHkgd2hlbiBTQVNMIGF1dGhlbnRpY2F0aW9uCisJaXMgcmVxdWVzdGVkOyBhcHBsaWNhdGlvbnMgc2hvdWxkIG5vdCB1c2UgdGhlIG1ldGhvZCBkaXJlY3RseS4KKworCisKKy0tIEphdmFNYWlsIDEuNS40IC0tCisKKy0gSWRsZW1hbmFnZXIud2F0Y2ggbm8gbG9uZ2VyIHRocm93cyBJT0V4Y2VwdGlvbgorCisJVGhlIElkbGVNYW5hZ2VyLndhdGNoIG1ldGhvZCB3YXMgZGVjbGFyZWQgdG8gdGhyb3cgSU9FeGNlcHRpb24sCisJYnV0IG5ldmVyIGFjdHVhbGx5IHRocmV3IGl0LiAgVGhlIGRlY2xhcmFjdGlvbiBoYXMgYmVlbiBjaGFuZ2VkLAorCXdoaWNoIHdpbGwgY2F1c2UgYSBzb3VyY2UgaW5jb21wYXRpYmlsaXR5IGZvciBjb2RlIGV4cGVjdGluZyB0bworCWNhdGNoIElPRXhjZXB0aW9uIHdoZW4gY2FsbGluZyB0aGUgd2F0Y2ggbWV0aG9kLgorCisKKworLS0gSmF2YU1haWwgMS41LjMgLS0KKworLSBEYXRlIHNlYXJjaCB0ZXJtcyByZXN1bHQgaW4gd3JvbmcgZ3JlYXRlci10aGFuIFNFQVJDSCBjb21tYW5kcyBmb3IgSU1BUAorCisJVGhlIElNQVAgU2VudERhdGVUZXJtIGFuZCBSZWNlaXZlZERhdGVUZXJtIGdyZWF0ZXItdGhhbiBjb21wYXJpc29uCisJd2FzIGFjdHVhbGx5IGRvaW5nIGEgZ3JlYXRlci10aGFuLW9yLWVxdWFsLXRvIGNvbXBhcmlzb24uICBUaGlzCisJaGFzIGJlZW4gZml4ZWQgaW4gdGhlIDEuNS4zIHJlbGVhc2UsIGJ1dCBwcm9ncmFtcyB0aGF0IGFjY2lkZW50YWxseQorCXJlbGllZCBvbiB0aGUgb2xkIGJlaGF2aW9yIG1heSBnZXQgZGlmZmVyZW50IHJlc3VsdHMuCisKKy0gQXV0aGVudGljYXRvciBpcyBub3cgc3luY2hyb25pemVkCisKKwlUaGUgY2FsbCB0byB0aGUgQXV0aGVudGljYXRvcidzIGdldFBhc3N3b3JkQXV0aGVudGljYXRpb24gbWV0aG9kCisJaXMgbm93IHN5bmNocm9uaXplZCBzbyB0aGF0IHRoZSBzdGF0ZSBzdG9yZWQgaW4gdGhlIEF1dGhlbnRpY2F0b3IKKwlpcyBzYWZlIGlmIG11bHRpcGxlIHRocmVhZHMgdHJ5IHRvIHVzZSB0aGUgQXV0aGVudGljYXRvcgorCXNpbXVsdGFuZW91c2x5LiAgSWYgdGhlIGFwcGxpY2F0aW9uJ3MgZ2V0UGFzc3dvcmRBdXRoZW50aWNhdGlvbgorCW1ldGhvZCBibG9ja3MsIGl0IHdpbGwgcHJldmVudCBvdGhlciB0aHJlYWRzIGluIHRoZSBzYW1lCisJU2Vzc2lvbiBmcm9tIHVzaW5nIHRoZSBBdXRoZW50aWNhdG9yLgorCisKKworLS0gSmF2YU1haWwgMS41IC0tCisKKy0gUkZDIDIyMzEgcGFyYW1ldGVyIGVuY29kaW5nL2RlY29kaW5nIGVuYWJsZWQgYnkgZGVmYXVsdAorCisJVGhlIFN5c3RlbSBwcm9wZXJ0aWVzICJtYWlsLm1pbWUuZGVjb2RlcGFyYW1ldGVycyIgYW5kCisJIm1haWwubWltZS5lbmNvZGVwYXJhbWV0ZXJzIiBub3cgZGVmYXVsdCB0byB0cnVlIGluc3RlYWQgb2YgZmFsc2UuCisJTm93IHRoYXQgbW9zdCBtYWlsZXJzIHN1cHBvcnQgUkZDIDIyMzEsIHRoaXMgaXMgZXhwZWN0ZWQgdG8KKwlpbmNyZWFzZSBpbnRlcm9wZXJhYmlsaXR5LCBhbHRob3VnaCBpbiByYXJlIGNhc2VzLCBhbmQgZXNwZWNpYWxseQorCXdoZW4gZGVhbGluZyB3aXRoIG9sZGVyIG1haWxlcnMsIHRoaXMgbWF5IGNhdXNlIHByb2JsZW1zLgorCVBhcmFtZXRlcnMgbWF5IGFwcGVhciBlbmNvZGVkLCBhbmQgd2l0aCBhIGRpZmZlcmVudCBuYW1lLAorCXRoYW4gd2hhdCB0aGUgcmVjZWl2ZXIgaXMgZXhwZWN0aW5nLgorCistIENvbnRlbnRUeXBlLnRvU3RyaW5nIGFuZCBDb250ZW50RGlzcG9zaXRpb24udG9TdHJpbmcgbmV2ZXIgcmV0dXJuIG51bGwKKworCVRoZXNlIG1ldGhvZHMgd2VyZSBwcmV2aW91c2x5IGRvY3VtZW50ZWQgdG8gcmV0dXJuIG51bGwgaW4KKwllcnJvciBjYXNlcyB3aGVuIHRoZSBmaWVsZHMgb2YgdGhlIGNsYXNzIHdlcmUgbm90IHZhbGlkLgorCVRoZXNlIG1ldGhvZHMgbm93IHJldHVybiBhbiBlbXB0eSBzdHJpbmcgaW4gdGhlc2UgY2FzZXMsIHRvCisJYmUgY29uc2lzdGVudCB3aXRoIHRoZSBnZW5lcmFsIGNvbnRyYWN0IG9mIE9iamVjdC50b1N0cmluZy4KKworLSBhZGRpdGlvbmFsIGNsYXNzZXMsIG1ldGhvZHMsIGFuZCBmaWVsZHMKKworCUphdmFNYWlsIDEuNSBhZGRzIGNsYXNzZXMgdG8gZXhpc3RpbmcgcGFja2FnZXMsIG1ldGhvZHMgdG8KKwlleGlzdGluZyBjbGFzc2VzLCBhbmQgZmllbGRzIHRvIGV4aXN0aW5nIGNsYXNzZXMuICBBbGwgb2YKKwl0aGVzZSBjaGFuZ2VzIGhhdmUgdGhlIHBvdGVudGlhbCB0byBicmVhayBzb3VyY2UgY29tcGF0aWJpbGl0eQorCWZvciBhcHBsaWNhdGlvbnMgdXNpbmcgdGhlIEphdmFNYWlsIEFQSS4KKworLSBKREsgMS41IG9yIG5ld2VyIHJlcXVpcmVkCisKKwlUaGUgSmF2YU1haWwgcmVmZXJlbmNlIGltcGxlbWVudGF0aW9uIG5vdyByZXF1aXJlcyBKREsgMS41CisJb3IgbmV3ZXIuICBJdCBpcyBleHBlY3RlZCB0aGF0IHRoZSBsYXJnZSBtYWpvcml0eSBvZiB1c2VycworCWFyZSBhbHJlYWR5IHVzaW5nIEpESyAxLjYgb3IgbmV3ZXIuCisKKy0gcHJvdGVjdGVkIGZpZWxkcyBpbiBmaW5hbCBjbGFzc2VzIGluIGphdmF4Lm1haWwuc2VhcmNoIG1hZGUgcHJpdmF0ZQorCisJU29tZSBvZiB0aGUgZmluYWwgY2xhc3NlcyBpbiB0aGUgamF2YXgubWFpbC5zZWFyY2ggcGFja2FnZQorCWNvbnRhaW5lZCBwcm90ZWN0ZWQgZmllbGRzLiAgU2luY2UgdGhlc2UgY2xhc3NlcyB3ZXJlIGZpbmFsCisJYW5kIGNvdWxkbid0IGJlIHN1YmNsYXNzZWQsIHRoZSAicHJvdGVjdGVkIiBhY2Nlc3MgcXVhbGlmaWVyCisJaGFkIG5vIGVmZmVjdC4gIFRoZXNlIGZpZWxkcyBhcmUgbm93IHByaXZhdGUuICBJdCdzIGhhcmQgdG8KKwlpbWFnaW5lIGhvdyB0aGlzIGNoYW5nZSBjb3VsZCBpbXBhY3QgYW55IGFwcGxpY2F0aW9ucyBvdGhlcgorCXRoYW4gcGVyaGFwcyB0aG9zZSB1c2luZyByZWZsZWN0aW9uIHRvIGFjY2VzcyB0aGVzZSBjbGFzc2VzLgorCistIE1haWxIYW5kbGVyIGRlZmF1bHQgYXR0YWNobWVudCBmaWx0ZXJzCisKKwlUaGUgZGVmYXVsdCB1c2VkIGZvciBhdHRhY2htZW50IGZpbHRlcnMgaGFzIGNoYW5nZWQgZnJvbSBhbGxvdworCWFsbCBsb2cgcmVjb3JkcyAobnVsbCkgdG8gaW5zdGVhZCB1c2UgYm9keSBmaWx0ZXIgYXNzaWduZWQgdG8KKwlnZXRGaWx0ZXIoKS4gIFRoaXMgaXMgYSBzYWZlciBjaG9pY2UgYXMgaXQgbWFpbnRhaW5zIGFueQorCWV4aXN0aW5nIGZpbHRlciBydWxlcyB3aGVuIGF0dGFjaG1lbnRzIGFyZSBhZGRlZC4KKworLSBNYWlsSGFuZGxlciBkZWZhdWx0ICdUTycgYWRkcmVzcyByZWNpcGllbnQKKworCUlmIHRoZSAnVE8nIGFkZHJlc3Mga2V5IGlzIG5vdCBzcGVjaWZpZWQgdGhlbiB0aGUgbG9jYWwgYWRkcmVzcworCWlzIHVzZWQuICBUaGUgcHJldmlvdXMgYmVoYXZpb3Igd2FzIHRvIG9taXQgdGhlICdUTycgYWRkcmVzcworCWhlYWRlci4gIFRoaXMgY2FuIGJyZWFrIGNvbmZpZ3VyYXRpb25zIHRoYXQgYXJlIG9ubHkgc2VuZGluZyB0bworCWEgc2V0IG9mICdDQycgb3IgJ0JDQycgYWRkcmVzc2VzLiAgVG8gcmV2ZXJ0IHRoaXMgYmVoYXZpb3IKKwlzaW1wbHkgc3BlY2lmeSBhICdUTycgYWRkcmVzcyBrZXkgd2l0aCBhbiBlbXB0eSBhZGRyZXNzIHZhbHVlLgorCistIE1haWxIYW5kbGVyIGludGVybiBvZiBlcnJvciBtYW5hZ2VyLCBmaWx0ZXJzLCBhbmQgZm9ybWF0dGVycy4KKworCVdoZW4gTWFpbEhhbmRsZXIgaXMgY3JlYXRlZCwgdGhlIGVycm9yIG1hbmFnZXIsIGZpbHRlcnMsIGFuZAorCWZvcm1hdHRlcnMgYXJlIGNoZWNrZWQgZm9yIGVxdWFsaXR5LiAgV2hlbiBlcXVhbCBvYmplY3RzIGFyZQorCWZvdW5kIHRoZXkgYXJlIHJlcGxhY2VkIHdpdGggYSBzaW5nbGUgcmVwcmVzZW50YXRpb24uICBUaGlzCisJYWxsb3dzIG9iamVjdHMgb2YgdGhlIHNhbWUgdHlwZSB0byBzaGFyZSBzdGF0ZSBmb3IgaW1wcm92aW5nCisJcGVyZm9ybWFuY2UsIGFkZGluZyBmdW5jdGlvbmFsaXR5LCBldGMuICBUbyByZXZlcnQgdG8gdGhlCisJcHJldmlvdXMgYmVoYXZpb3IgdGhlIGVycm9yIG1hbmFnZXIsIGZpbHRlcnMsIGFuZCBmb3JtYXR0ZXJzCisJbXVzdCByZXRhaW4gb3IgYmUgd3JhcHBlZCB3aXRoIG9iamVjdHMgdGhhdCByZXRhaW4gdGhlIGlkZW50aXR5CisJZXF1YWxzIGFuZCBoYXNoIGNvZGUgdG8gcHJldmVudCBpbnRlcm5pbmcuCisKKworCistLSBKYXZhTWFpbCAxLjQuNCAtLQorCistIGF1dGhvcml6YXRpb24gSUQgbWF5IGJlIG51bGwKKworCVRoZSBJTUFQIGFuZCBTTVRQIHByb3ZpZGVycyBzdXBwb3J0IGEKKwkibWFpbC48cHJvdG9jb2w+LnNhc2wuYXV0aG9yaXphdGlvbmlkIiBwcm9wZXJ0eSB0aGF0IGFsbG93cyB5b3UKKwl0byBzcGVjaWZ5IGFuIGF1dGhvcml6YXRpb24gSUQgc2VwYXJhdGVseSBmcm9tIHRoZSBhdXRoZW50aWNhdGlvbgorCUlEIHRoYXQncyBzcGVjaWZpZWQgYXMgdGhlIHVzZXIgbmFtZSBpbiBwcm9wZXJ0aWVzIG9yIGluIHRoZSBjb25uZWN0CisJbWV0aG9kLiAgVGhlIFBMQUlOIGF1dGhlbnRpY2F0aW9uIG1ldGhvZCwgYW5kIHNvbWUgU0FTTCBhdXRoZW50aWNhdGlvbgorCW1ldGhvZHMgc3VwcG9ydCB1c2Ugb2YgdGhlIHNlcGFyYXRlIGF1dGhvcml6YXRpb24gSUQuICBJbiBwcmV2aW91cworCXJlbGVhc2VzLCBpZiB0aGUgYXV0aG9yaXphdGlvbiBJRCB3YXMgbm90IHNwZWNpZmllZCwgaXQgZGVmYXVsdGVkCisJdG8gdGhlIGF1dGhlbnRpY2F0aW9uIElEICh1c2VyIG5hbWUpLiAgVGhpcyBjYW4gY2F1c2UgcHJvYmxlbXMgaWYKKwl0aGUgc2VydmVyIGRvZXNuJ3QgYWxsb3cgYW4gYXV0aG9yaXphdGlvbiBJRCBldmVuIHRob3VnaCB0aGUgU0FTTAorCW1ldGhvZCBhbGxvd3Mgc3BlY2lmeWluZyBvbmUuICBJbiB0aGlzIHJlbGVhc2UsIGlmIG5vIGF1dGhvcml6YXRpb24KKwlJRCBpcyBzcGVjaWZpZWQsIG51bGwgaXMgcGFzc2VkIHRvIHRoZSBTQVNMIG1ldGhvZC4gIElmIHRoaXMgY2F1c2VzCisJcHJvYmxlbXMgZm9yIGEgU0FTTCBtZXRob2QgaW1wbGVtZW50YXRpb24gb3IgYSBzZXJ2ZXIsIHRoZQorCSJtYWlsLjxwcm90b2NvbD4uc2FzbC5hdXRob3JpemF0aW9uaWQiIHByb3BlcnR5IHNob3VsZCBiZSBzZXQgdG8KKwl0aGUgdXNlciBuYW1lIHVzZWQgZm9yIGF1dGhlbnRpY2F0aW9uLgorCisKKworLS0gSmF2YU1haWwgMS40LjMgLS0KKworLSBTTVRQVHJhbnNwb3J0LmlzQ29ubmVjdGVkIGJlaGF2aW9yIGNoYW5nZWQKKworCVRoZSBTTVRQVHJhbnNwb3J0LmlzQ29ubmVjdGVkIG1ldGhvZCB1c2VzIHRoZSBTTVRQIE5PT1AgY29tbWFuZAorCXRvIGRldGVybWluZSBpZiB0aGUgc2VydmVyIGlzIHN0aWxsIGFsaXZlLiAgQmVjYXVzZSBtYW55IG9sZGVyCisJc2VydmVycyB3ZXJlIGJyb2tlbiBpbiB2YXJpb3VzIHdheXMsIGFueSByZXNwb25zZSAob3RoZXIgdGhhbgorCXRoZSA0MjEgImNvbm5lY3Rpb24gdGltZWQgb3V0IiByZXNwb25zZSkgd2FzIGNvbnNpZGVyZWQgYQorCXN1Y2Nlc3NmdWwgcmVzcG9uc2UgYW5kIHRoZSBzZXJ2ZXIgd2FzIGNvbnNpZGVyZWQgdG8gYmUgc3RpbGwKKwlhbGl2ZS4gIFVuZm9ydHVuYXRlbHksIE1pY3Jvc29mdCBFeGNoYW5nZSBoYXMgYSBidWcgdGhhdCBjYXVzZXMKKwlpdCB0byByZXR1cm4gYSByZXNwb25zZSBjb2RlIG9mIDQ1MSB3aGVuIGl0IHRpbWVzIG91dCBhIGNvbm5lY3Rpb24KKwlpbnN0ZWFkIG9mIHRoZSBleHBlY3RlZCA0MjEgcmVzcG9uc2UgY29kZS4gIFNNVFBUcmFuc3BvcnQuaXNDb25uZWN0ZWQKKwlub3cgY29uc2lkZXJzIG9ubHkgYSAyNTAgcmVzcG9uc2UgY29kZSB0byBpbmRpY2F0ZSBzdWNjZXNzLCBwZXIKKwl0aGUgU01UUCBzcGVjLiAgVGhlIG9sZCBiZWhhdmlvciBjYW4gYmUgcmVzdG9yZWQgYnkgc2V0dGluZyB0aGUKKwluZXcgbWFpbC5zbXRwLm5vb3Auc3RyaWN0IHByb3BlcnR5IHRvIGZhbHNlLgorCisKKworLS0gSmF2YU1haWwgMS40LjIgLS0KKworLSBtYWlsLnNtdHAucXVpdHdhaXQgZGVmYXVsdCBjaGFuZ2VkCisKKwlJbiBwcmV2aW91cyByZWxlYXNlcywgSmF2YU1haWwgd291bGQgZHJvcCB0aGUgU01UUCBjb25uZWN0aW9uCisJdG8gdGhlIHNlcnZlciBpbW1lZGlhdGVseSBhZnRlciBzZW5kaW5nIHRoZSBRVUlUIGNvbW1hbmQuCisJVGhpcyB2aW9sYXRlcyB0aGUgU01UUCBzcGVjLiAgVGhlIHByb3BlcnR5ICJtYWlsLnN0bXAucXVpdHdhaXQiCisJY29udHJvbHMgdGhpcyBiZWhhdmlvci4gIEluIHRoaXMgcmVsZWFzZSB0aGUgZGVmYXVsdCBiZWhhdmlvcgorCShpZiB0aGUgcHJvcGVydHkgaXNuJ3Qgc3BlY2lmaWVkKSBoYXMgY2hhbmdlZCBzbyB0aGF0IEphdmFNYWlsCisJd2lsbCB3YWl0IGZvciB0aGUgcmVzcG9uc2UgZnJvbSB0aGUgc2VydmVyIGJlZm9yZSBkcm9wcGluZyB0aGUKKwljb25uZWN0aW9uLiAgSW4gc29tZSBjYXNlcywgd2l0aCBzb21lIHNlcnZlcnMsIHRoaXMgYWRkaXRpb25hbAorCXdhaXQgdGltZSBtYXkgYmUgbm90aWNlYWJsZS4KKworCistIE1lc3NhZ2luZ0V4Y2VwdGlvbi5nZXRNZXNzYWdlIG91dHB1dCBjaGFuZ2VkCisKKwlUaGUgTWVzc2FnaW5nRXhjZXB0aW9uIGNsYXNzLCB3aGljaCBpcyB0aGUgYmFzZSBjbGFzcyBmb3IgYWxsCisJSmF2YU1haWwgZXhjZXB0aW9ucywgaGFzIGJlZW4gcmV0cm9maXR0ZWQgdG8gc3VwcG9ydCB0aGUKKwlleGNlcHRpb24gY2hhaW5pbmcgZmVhdHVyZSBhZGRlZCB0byB0aGUgamF2YS5sYW5nLlRocm93YWJsZQorCWNsYXNzIGluIEoyU0UgMS40LiAgVGhlIHZpc2libGUgaW1wYWN0IG9mIHRoaXMgY2hhbmdlIGlzIHRoYXQKKwl0aGUgU3RyaW5nIHJldHVybmVkIGJ5IHRoZSBnZXRNZXNzYWdlIG1ldGhvZCB3aWxsIG9ubHkgcmV0dXJuCisJdGhlIGltbWVkaWF0ZSBtZXNzYWdlIGZvciB0aGUgdG9wIGxldmVsIGV4Y2VwdGlvbiwgaW5zdGVhZCBvZgorCWluY2x1ZGluZyBtZXNzYWdlcyBmb3IgYWxsIG5lc3RlZCBleGNlcHRpb25zLgorCisKKy0gY29ubmVjdGlvbiB0aW1lb3V0cyBubyBsb25nZXIgdXNlIGEgdGhyZWFkCisKKwlUbyBzdXBwb3J0IGNvbm5lY3Rpb24gdGltZW91dHMgaW4gb2xkZXIgdmVyc2lvbnMgb2YgdGhlIEpESywKKwlpdCB3YXMgbmVjZXNzYXJ5IGZvciBKYXZhTWFpbCB0byBjcmVhdGUgYSB0aHJlYWQgdG8gbWFrZSB0aGUKKwljb25uZWN0aW9uLCBzbyB0aGF0IGl0IGNvdWxkIGludGVycnVwdCBhbmQgYWJhbmRvbiB0aGF0CisJdGhyZWFkIGlmIHRoZSBjb25uZWN0aW9uIHRpbWVvdXQgZXhwaXJlZC4gIEoyU0UgMS40IGFkZGVkCisJdGhlIGFiaWxpdHkgdG8gc3BlY2lmeSB0aGUgY29ubmVjdGlvbiB0aW1lb3V0IGRpcmVjdGx5LCBzbworCUphdmFNYWlsIG5vIGxvbmdlciB1c2VzIGFuIGFkZGl0aW9uYWwgdGhyZWFkIGZvciB0aGlzIHB1cnBvc2UuCisKKworLSBCeXRlQXJyYXlEYXRhU291cmNlIG5vdyBwYXJ0IG9mIGphdmF4Lm1haWwudXRpbAorCisJVGhlIEJ5dGVBcnJheURhdGFTb3VyY2UgY2xhc3MsIHdoaWNoIHdhcyBwcmV2aW91c2x5IGluY2x1ZGVkCisJaW4gc291cmNlIGZvcm0gaW4gdGhlIGRlbW8gZGlyZWN0b3J5LCBpcyBub3cgYSBzdGFuZGFyZCBwYXJ0CisJb2YgdGhlIEphdmFNYWlsIEFQSSBpbiB0aGUgbmV3IGphdmF4Lm1haWwudXRpbCBwYWNrYWdlLgorCUFwcGxpY2F0aW9ucyB0aGF0IGFyZSBtb2RpZmllZCB0byBtYWtlIHVzZSBvZiBjbGFzc2VzIGluIHRoZQorCW5ldyBwYWNrYWdlLCBhbmQgdGhhdCBhbHNvIGluY2x1ZGVkIGEgY29weSBvZiB0aGUgZGVtbyB2ZXJzaW9uCisJb2YgQnl0ZUFycmF5RGF0YVNvdXJjZSwgc2hvdWxkIGJlIGNhcmVmdWwgdG8gYXZvaWQgcG90ZW50aWFsCisJbmFtZSBjb25mbGljdHMgYmV0d2VlbiB0aGVzZSB0d28gY2xhc3Nlcy4KKworCistIG1haWwuU1NMU29ja2V0RmFjdG9yeS5jbGFzcyBwcm9wZXJ0eSBubyBsb25nZXIgc3VwcG9ydGVkCisKKwlUaGUgSmF2YU1haWwgaW1wbGVtZW50YXRpb24gcHJldmlvdXNseSB1c2VkIHRoaXMgdW5kb2N1bWVudGVkCisJcHJvcGVydHkgdG8gbG9jYXRlIHRoZSBTU0xTb2NrZXRGYWN0b3J5IGZyb20gd2hpY2ggaXQgd291bGQKKwljcmVhdGUgU1NMU29ja2V0cyB3aGVuIG1ha2luZyBhbiBTU0wgb3IgVExTIGNvbm5lY3Rpb24uICBUaGlzCisJcHJvcGVydHkgaXMgbm8gbG9uZ2VyIHVzZWQuICBUaGUgc3RhbmRhcmQKKwlqYXZheC5uZXQuc3NsLlNTTFNvY2tldEZhY3RvcnkgaXMgdXNlZCBpbnN0ZWFkLCB3aGljaCBzdXBwb3J0cworCWEgc3RhbmRhcmQgd2F5IG9mIG92ZXJyaWRpbmcgdGhlIGNob2ljZSBvZiBkZWZhdWx0IFNTTFNvY2tldEZhY3RvcnkuCisJU2VlIHRoZSBTU0xTb2NrZXRGYWN0b3J5IGphdmFkb2NzIGZvciBkZXRhaWxzLiAgTW9zdCBhcHBsaWNhdGlvbnMKKwlzaG91bGQgbmV2ZXIgbmVlZCB0byBvdmVycmlkZSB0aGUgZGVmYXVsdCBTU0xTb2NrZXRGYWN0b3J5LgorCisKKy0gUXVvdGEgY2xhc3MgbW92ZWQgZnJvbSBjb20uc3VuLm1haWwuaW1hcCB0byBqYXZheC5tYWlsCisKKwlUaGUgbmV3IFF1b3RhIEFQSXMgaW4gSmF2YU1haWwgYXJlIHRha2VuIGRpcmVjdGx5IGZyb20gdGhlIG9sZAorCUlNQVAtc3BlY2lmaWMgY2xhc3NlcyBpbiB0aGUgY29tLnN1bi5tYWlsLmltYXAgcGFja2FnZS4gIElmIHlvdSd2ZQorCWJlZW4gdXNpbmcgdGhlc2UgY2xhc3NlcywgeW91J2xsIG5lZWQgdG8gdXBkYXRlIHlvdXIgYXBwbGljYXRpb24KKwl0byB1c2UgdGhlIG5ldyBjbGFzc2VzIGluIHRoZSBqYXZheC5tYWlsIHBhY2thZ2UuCisKKworLSBnZXRQcm90b2NvbCBtZXRob2QgcmVtb3ZlZCBmcm9tIGNvbS5zdW4ubWFpbC5pbWFwLklNQVBGb2xkZXIKKworCVRoZSBnZXRQcm90b2NvbCBtZXRob2QgcmV0dXJucyBhbiBpbnN0YW5jZSBvZiBJTUFQUHJvdG9jb2wuCisJVGhpcyB3YXMgb3JpZ2luYWxseSBpbnRlbmRlZCB0byBhbGxvdyBhcHBsaWNhdGlvbnMgdG8KKwlleHBlcmltZW50IHdpdGggZXh0ZW5kaW5nIHRoZSBJTUFQIHByb3RvY29sIHN1cHBvcnQgdG8gdXNlIElNQVAKKwljb21tYW5kcyBub3QgZGlyZWN0bHkgaW1wbGVtZW50ZWQgYnkgdGhlIElNQVAgcHJvdG9jb2wKKwlwcm92aWRlci4gIFVuZm9ydHVuYXRlbHksIHRvIHNhZmVseSB1c2UgdGhlIElNQVBQcm90b2NvbAorCW9iamVjdCwgeW91IG5lZWQgdG8gb2JleSB0aGUgbG9ja2luZyByZXF1aXJlbWVudHMgb2YgdGhlCisJSU1BUEZvbGRlciBvYmplY3QsIGFuZCB0aGVyZSdzIG5vIHdheSB0byBkbyB0aGF0IGZyb20gb3V0c2lkZQorCXRoZSBJTUFQRm9sZGVyIG9iamVjdC4gIFRoZSBkb0NvbW1hbmQgbWV0aG9kIHdhcyBhZGRlZCB0bworCUlNQVBGb2xkZXIgdG8gcmVzb2x2ZSB0aGlzIHByb2JsZW0uICBOb3csIHdpdGggdGhlIGludHJvZHVjdGlvbgorCW9mIElETEUgc3VwcG9ydCB0byB0aGUgSU1BUCBwcm90b2NvbCBwcm92aWRlciwgaXQncyBjcml0aWNhbCB0bworCW9iZXkgdGhlIGxvY2tpbmcgcmVxdWlyZW1lbnRzLiAgVG8gcHJldmVudCBtaXN0YWtlcywgdGhlIG9sZCwKKwl1bnNhZmUsIGdldFByb3RvY29sIG1ldGhvZCBoYXMgYmVlbiByZW1vdmVkLiAgQXBwbGljYXRpb25zCisJc2hvdWxkIHVzZSB0aGUgZG9Db21tYW5kIG1ldGhvZCBmb3Igc2ltcGxlIElNQVAgZXh0ZW5zaW9ucy4KKwlVc2Ugb2YgbW9yZSBjb21wbGV4IElNQVAgZXh0ZW5zaW9ucyBtYXkgcmVxdWlyZSBtb2RpZmljYXRpb24KKwlvZiB0aGUgSU1BUCBwcm90b2NvbCBwcm92aWRlci4KZGlmZiAtLWdpdCBhL2RvYy9yZWxlYXNlL0lzc3VlTWFwLnR4dCBiL2RvYy9yZWxlYXNlL0lzc3VlTWFwLnR4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NjA2MjdkCi0tLSAvZGV2L251bGwKKysrIGIvZG9jL3JlbGVhc2UvSXNzdWVNYXAudHh0CkBAIC0wLDAgKzEsMjYxIEBACisjCisjIFRoaXMgZmlsZSBpcyB0aGUgbWFwcGluZyBmcm9tIG9sZCBqYXZhLm5ldCBpc3N1ZSBudW1iZXJzIHRvCisjIG5ldyBnaXRodWIgaXNzdWUgbnVtYmVycy4gIENvbW1pdCBtZXNzYWdlcyBmcm9tIGJlZm9yZSB0aGUgbWlncmF0aW9uCisjIHRvIGdpdGh1YiB3aWxsIHJlZmVyZW5jZSB0aGVzZSBvbGRlciBpc3N1ZSBudW1iZXJzLgorIworMTg5IDEKKzIwMiAyCis5NjUgMworMTIwNyA0CisxMzQzIDUKKzEzNDUgNgorMjcyOCA3CisyOTg2IDgKKzMxNTUgOQorMzQ0MiAxMAorMzQ0NCAxMQorMzUzOSAxMgorMzU2NSAxMworMzU2NiAxNAorMzgxNSAxNQorMzk4MyAxNgorNDAwMiAxNworNDA2NSAxOAorNDI5NiAxOQorNDM1NSAyMAorNDQ0OCAyMQorNDUxMSAyMgorNDU3OSAyMworNDU4MSAyNAorNDU4MyAyNQorNDc0MyAyNgorNDc1MyAyNworNDkwNiAyOAorNTA4NiAyOQorNTA5MCAzMAorNTIxOCAzMQorNTIzMyAzMgorNTI1NyAzMworNTI4NSAzNAorNTMwMCAzNQorNTY4MSAzNgorNTY4MiAzNworNTY4MyAzOAorNTY4NCAzOQorNTY4NSA0MAorNTY4NiA0MQorNTY4NyA0MgorNTY4OCA0MworNTY4OSA0NAorNTY5MCA0NQorNTY5MSA0NgorNTY5MiA0NworNTY5MyA0OAorNTY5NCA0OQorNTcxMyA1MAorNTc0MyA1MQorNTc2OSA1MgorNTc3MCA1MworNTgxNiA1NAorNTgxOCA1NQorNTgxOSA1NgorNTgyMCA1NworNTgyMSA1OAorNTgyMiA1OQorNTgyOSA2MAorNTgzMCA2MQorNTg0NyA2MgorNTg1MyA2MworNTg2MSA2NAorNTg5NiA2NQorNTkwMSA2NgorNTkyNCA2NworNTkyNSA2OAorNTkzMyA2OQorNTkzNCA3MAorNTk3OCA3MQorNTk4NyA3MgorNTk4OSA3MworNjAwNCA3NAorNjA2OSA3NQorNjA3MiA3NgorNjA3NCA3NworNjEwMiA3OAorNjEwNCA3OQorNjEwOCA4MAorNjEyMSA4MQorNjEyNSA4MgorNjEzNyA4MworNjE0MSA4NAorNjE0MyA4NQorNjE2MCA4NgorNjE2MSA4NworNjE4MSA4OAorNjIwMSA4OQorNjIwMyA5MAorNjIwNyA5MQorNjIwOCA5MgorNjIxNiA5MworNjIzOCA5NAorNjI2MCA5NQorNjI2MSA5NgorNjI3NCA5NworNjI3NSA5OAorNjI3NiA5OQorNjI3NyAxMDAKKzYyNzggMTAxCis2Mjc5IDEwMgorNjI4MCAxMDMKKzYyODEgMTA0Cis2MjgzIDEwNQorNjMyNCAxMDYKKzYzMjUgMTA3Cis2MzI2IDEwOAorNjMyNyAxMDkKKzYzMjggMTEwCis2MzI5IDExMQorNjMzMCAxMTIKKzYzMzYgMTEzCis2MzQ4IDExNAorNjM1MiAxMTUKKzYzNTMgMTE2Cis2MzYxIDExNworNjM2NSAxMTgKKzYzNjYgMTE5Cis2MzY3IDEyMAorNjM2OCAxMjEKKzYzNzkgMTIyCis2NDA3IDEyMworNjQzMCAxMjQKKzY0NTIgMTI1Cis2NDY3IDEyNgorNjQ5NiAxMjcKKzY0OTggMTI4Cis2NTI2IDEyOQorNjUyOCAxMzAKKzY1MzUgMTMxCis2NTUxIDEzMgorNjU1MiAxMzMKKzY1NjUgMTM0Cis2NTY4IDEzNQorNjU3MiAxMzYKKzY1ODUgMTM3Cis2NjM4IDEzOAorNjY0NCAxMzkKKzY2NTAgMTQwCis2NjU3IDE0MQorNjY2MiAxNDIKKzY2NjcgMTQzCis2NjY4IDE0NAorNjY4NyAxNDUKKzY3MDMgMTQ2Cis2NzEyIDE0NworNjcxOCAxNDgKKzY3MTkgMTQ5Cis2NzU1IDE1MAorNjc2MiAxNTEKKzY3NjUgMTUyCis2NzY3IDE1MworNjc3MiAxNTQKKzY3NzggMTU1Cis2Nzg3IDE1NgorNjgwNCAxNTcKKzY4MTcgMTU4Cis2ODIzIDE1OQorNjgyNCAxNjAKKzY4MjcgMTYxCis2ODQwIDE2MgorNjg0NCAxNjMKKzY4NTAgMTY0Cis2ODUyIDE2NQorNjg2MCAxNjYKKzY4NjMgMTY3Cis2ODg2IDE2OAorNjkwNSAxNjkKKzY5MDcgMTcwCis2OTEzIDE3MQorNjkzOCAxNzIKKzY5NDMgMTczCis2OTQ5IDE3NAorNjk1NCAxNzUKKzY5NjQgMTc2Cis2OTY1IDE3NworNjk2NiAxNzgKKzY5NzMgMTc5Cis2OTg5IDE4MAorNjk5NyAxODEKKzcwMDkgMTgyCis3MDEwIDE4MworNzAxMSAxODQKKzcwMTQgMTg1Cis3MDE5IDE4NgorNzAyNiAxODcKKzcwMjcgMTg4Cis3MDI4IDE4OQorNzAzMCAxOTAKKzcwMzUgMTkxCis3MDQyIDE5MgorNzA1MSAxOTMKKzcwNTIgMTk0Cis3MDc1IDE5NQorNzA4MyAxOTYKKzcwODggMTk3Cis3MDkwIDE5OAorNzA5MSAxOTkKKzcwOTIgMjAwCis3MDk0IDIwMQorNzA5NyAyMDIKKzcxMDQgMjAzCis3MTE4IDIwNAorNzE0MCAyMDUKKzcxNTAgMjA2Cis3MTUxIDIwNworNzE1NiAyMDgKKzcxODIgMjA5Cis3MjM4IDIxMAorNzMzMiAyMTEKKzczNTUgMjEyCis3MzU2IDIxMworNzM3MSAyMTQKKzczNzggMjE1Cis3NDcxIDIxNgorNzQ3MiAyMTcKKzc0ODMgMjE4Cis3NTA2IDIxOQorNzUxMiAyMjAKKzc1MTMgMjIxCis3NTI5IDIyMgorNzUzNiAyMjMKKzgzODcgMjI0Cis4Mzg5IDIyNQorODM5OCAyMjYKKzgzOTkgMjI3Cis4NDAzIDIyOAorODQwNCAyMjkKKzg0MDUgMjMwCis4NDA4IDIzMQorODQxNSAyMzIKKzg0MjAgMjMzCis4NDIyIDIzNAorODQyOCAyMzUKKzg0MzUgMjM2Cis4NDg2IDIzNworODQ4NyAyMzgKKzg0OTIgMjM5Cis4NTQwIDI0MAorODU1MCAyNDEKKzg1NTggMjQyCis4NTYyIDI0MworODU2OCAyNDQKKzg1ODMgMjQ1Cis4NjIxIDI0NgorODc0OCAyNDcKKzg4MTAgMjQ4Cis4ODIyIDI0OQorODgzMyAyNTAKKzg4NDYgMjUxCis5MTY5IDI1MgorOTQxOCAyNTMKKzEwOTA5IDI1NAorMTEwNTcgMjU1CisxOTU2MyAyNTYKZGlmZiAtLWdpdCBhL2RvYy9yZWxlYXNlL0phdmFXZWJTZXJ2ZXIuaHRtbCBiL2RvYy9yZWxlYXNlL0phdmFXZWJTZXJ2ZXIuaHRtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45YzM0YmIwCi0tLSAvZGV2L251bGwKKysrIGIvZG9jL3JlbGVhc2UvSmF2YVdlYlNlcnZlci5odG1sCkBAIC0wLDAgKzEsNTggQEAKKzwhZG9jdHlwZSBodG1sIHB1YmxpYyAiLS8vdzNjLy9kdGQgaHRtbCA0LjAgdHJhbnNpdGlvbmFsLy9lbiI+Cis8aHRtbD4KKzxoZWFkPgorPCEtLQorCisgICAgQ29weXJpZ2h0IChjKSAyMDEwLCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisKKyAgICBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAgICB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKworICAgIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAgICBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgICAgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgICAgdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisKKyAgICBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKworLS0+CisKKyAgIDxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PWlzby04ODU5LTEiPgorICAgPG1ldGEgbmFtZT0iQXV0aG9yIiBjb250ZW50PSJKYXZhU29mdHdhcmUiPgorICAgPG1ldGEgbmFtZT0iR0VORVJBVE9SIiBjb250ZW50PSJNb3ppbGxhLzQuNjEgW2VuXSAoV2luTlQ7IFUpIFtOZXRzY2FwZV0iPgorICAgPHRpdGxlPkphdmFXZWJTZXJ2ZXI8L3RpdGxlPgorPC9oZWFkPgorPGJvZHk+CitJZiB5b3UgZG9uJ3QgYWxyZWFkeSBoYXZlIEphdmEgV2ViIFNlcnZlciBpbnN0YWxsZWQgYW5kIHJ1bm5pbmcsCit5b3UnbGwgbmVlZCB0byBkb3dubG9hZCBpdAorPGJyPmZyb20gdGhlJm5ic3A7IDxhIGhyZWY9Imh0dHA6Ly93d3cuc3VuLmNvbS9zb2Z0d2FyZS9qd2Vic2VydmVyL2luZGV4Lmh0bWwiPkphdmEKK1dlYiBTZXJ2ZXI8L2E+Jm5ic3A7IHByb2R1Y3QgcGFnZSBhbmQgaW5zdGFsbCBpdC4gV2UgdGVzdGVkIHRoZSBKYXZhTWFpbFNlcnZsZXQKK3dpdGgKKzxicj50aGVzZSBjb25maWd1cmF0aW9ucy4KKzxwPihvbiBTb2xhcmlzKQorPGJsb2NrcXVvdGU+SmF2YVdlYlNlcnZlciAyLjAgKGJpbmFyeSk8L2Jsb2NrcXVvdGU+Cisob24gTlQpCis8YmxvY2txdW90ZT5KYXZhV2ViU2VydmVyIDIuMCAoYmluYXJ5KTwvYmxvY2txdW90ZT4KK1RvIHJ1biB0aGUgSmF2YU1haWxTZXJ2bGV0LCB5b3UgbXVzdCBhZGQgdGhlIEphdmFNYWlsIGFuZCBKYXZhQmVhbnMgQWN0aXZhdGlvbgorRnJhbWV3b3JrCis8YnI+amFyIGZpbGVzIHRvIHRoZSBDTEFTU1BBVEggZW52aXJvbm1lbnQgdmFyaWFibGUgKHRoaXMgaXMgZG9jdW1lbnRlZAoraW4gdGhlIEphdmFNYWlsIFJFQURNRSBmaWxlCis8YnI+YW5kIGFkZGl0aW9uYWwgV2luZG93cyBOVCBpbmZvcm1hdGlvbiBpcyBwcm92aWRlZCA8YSBocmVmPSJjbGFzc3BhdGgtTlQuaHRtbCI+aGVyZTwvYT4pLgorPHA+T25jZSB0aGlzIGlzIGRvbmUsIHJlc3RhcnQgdGhlIHdlYiBzZXJ2ZXIuCis8YnI+Jm5ic3A7Cis8cD5BZGRpdGlvbmFsIE5vdGVzCis8YmxvY2txdW90ZT5JZiB5b3UgcnVuIEphdmFXZWJTZXJ2ZXIgMi4wIHdpdGggdGhlIEphdmEgUnVudGltZSBFbnZpcm9ubWVudAorKEpSRSkgc3VwcGxpZWQgd2l0aAorPGJyPkphdmFXZWJTZXJ2ZXIsIG5vIGFkZGl0aW9uYWwgc2VjdXJpdHkgcG9saWN5IGlzIG5lY2Vzc2FyeS4gVGhlIHNlY3VyaXR5Citwb2xpY3kgZmlsZQorPGJyPihpLmUuIGpzZXJ2LnBvbGljeSkgc3VwcGxpZWQgd2l0aCB0aGUgSlJFIGNvbnRhaW5zIHRoZSBuZWNlc3NhcnkgcGVybWlzc2lvbnMKK2ZvciBsb2NhbCBzZXJ2bGV0cy48L2Jsb2NrcXVvdGU+CisKKzxibG9ja3F1b3RlPklmIHlvdSBydW4gSmF2YVdlYlNlcnZlciAyLjAgd2l0aCBhbm90aGVyIEpSRSAod2l0aCBhbiBpbnN0YWxsZWQKK0pESyBmb3IgZXhhbXBsZSksIHlvdQorPGJyPm11c3QgYWRkIHRoZSBuZWNlc3NheSBzZWN1cml0eSBwb2xpY3kgZm9yIHJ1bm5pbmcgdW5kZXIgYSBTZWN1cml0eU1hbmFnZXIuPC9ibG9ja3F1b3RlPgorCis8L2JvZHk+Cis8L2h0bWw+CmRpZmYgLS1naXQgYS9kb2MvcmVsZWFzZS9OT1RFUy50eHQgYi9kb2MvcmVsZWFzZS9OT1RFUy50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjM3YTJkZAotLS0gL2Rldi9udWxsCisrKyBiL2RvYy9yZWxlYXNlL05PVEVTLnR4dApAQCAtMCwwICsxLDIwNiBAQAorCQkJICAgICBOT1RFUworCQkJICAgICA9PT09PQorCisJCSAgICBKYXZhTWFpbChUTSkgQVBJICR7bWFpbC52ZXJzaW9ufSByZWxlYXNlCisJCSAgICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworV2VsY29tZSB0byB0aGUgJHttYWlsLnZlcnNpb259IHJlbGVhc2Ugb2YgdGhlIEphdmFNYWlsIEFQSSBpbXBsZW1lbnRhdGlvbi4gCisKK1BsZWFzZSByZWZlciB0byBDSEFOR0VTLnR4dCBmb3IgYSBsaXN0IG9mIHRoZSBjaGFuZ2VzIHNpbmNlIHRoZSAKK3ByZXZpb3VzIHJlbGVhc2UuCisKK1BsZWFzZSBzZWUgdGhlIEZBUSBhdCBodHRwczovL2VjbGlwc2UtZWU0ai5naXRodWIuaW8vamF2YW1haWwvRkFRCisKK1Byb3RvY29sIFByb3ZpZGVycworLS0tLS0tLS0tLS0tLS0tLS0tCisKK1RoZSBKYXZhTWFpbCBBUEkgamFyIGZpbGUgImpha2FydGEubWFpbC5qYXIiIGluY2x1ZGVzIHRoZSBmdWxsIEphdmFNYWlsCitBUEkgaW1wbGVtZW50YXRpb24gYW5kIHRoZSBTdW4gcHJvdG9jb2wgcHJvdmlkZXJzIC0gSU1BUCwgU01UUCwgYW5kCitQT1AzLiAgVGhlIHNpbXBsZXN0IHdheSB0byB1c2UgdGhlIEphdmFNYWlsIEFQSSBpcyB0byBqdXN0IHVzZSB0aGUKK2pha2FydGEubWFpbC5qYXIgZmlsZSBhbmQgaWdub3JlIHRoZSBvdGhlciBqYXIgZmlsZXMgaW4gdGhpcyBwYWNrYWdlLgorCitJbiBzb21lIGNhc2VzIGl0IG1heSBiZSBkZXNpcmFibGUgdG8gbWluaW1pemUgdGhlIHNpemUgb2YgdGhlIEphdmFNYWlsCitBUEkgY29kZSB1c2VkIGJ5IGFuIGFwcGxpY2F0aW9uIChlLmcuLCBpbiBhIG1pY3Jvc2VydmljZSkuCitJbiB0aGlzIGNhc2UgeW91IG1pZ2h0IHdhbnQgdG8gaW5jbHVkZSB0aGUgIm1haWxhcGkuamFyIiBmaWxlLCB3aGljaAoraW5jbHVkZXMgKm5vKiBwcm90b2NvbCBwcm92aWRlcnMsIGFsb25nIHdpdGgganVzdCB0aGUgamFyIGZpbGUgZm9yIHRoZQorcHJvdG9jb2wgcHJvdmlkZXIgeW91IG5lZWQuICBGb3IgZXhhbXBsZSwgYSBtaWNyb3NlcnZpY2UgdGhhdCBvbmx5IG5lZWRzCit0byBzZW5kIG1haWwgY291bGQgdXNlIHRoZSAibWFpbGFwaS5qYXIiIGZpbGUgYW5kIHRoZSAic210cC5qYXIiIGZpbGUuCisKK0FuIGltcG9ydGFudCBub3RlIHdoZW4gdXNpbmcgdGhlIHNlcGFyYXRlIHByb3RvY29sIHByb3ZpZGVyIGphciBmaWxlczoKKworLSAgWW91IGNhbid0IG1peCBhbmQgbWF0Y2ggdGhlIFN1biBwcm90b2NvbCBwcm92aWRlcnMgYmV0d2VlbiBkaWZmZXJlbnQKKyAgIHJlbGVhc2VzIG9mIHRoZSBKYXZhTWFpbCBBUEkuICBUaGUgU3VuIHByb3RvY29sIHByb3ZpZGVycyBkZXBlbmQgb24KKyAgIGltcGxlbWVudGF0aW9uLXNwZWNpZmljIHV0aWxpdHkgQVBJcyB3aXRoaW4gdGhlIG1haWxhcGkuamFyIGZpbGUuCisgICAoVGhpcmQgcGFydHkgcHJvdG9jb2wgcHJvdmlkZXJzIHRoYXQgZG9uJ3QgZGVwZW5kIG9uIHRoZXNlIEFQSXMKKyAgIHNob3VsZCB3b3JrIGZpbmUuKQorCisKK05PVEU6IFRoZSBTdW4gcHJvdG9jb2wgcHJvdmlkZXIgZG9jdW1lbnRhdGlvbiBpcyBpbmNsdWRlZCBpbiB0aGUgamF2YWRvY3MKKyAgICAgIGZvciB0aGUgSmF2YU1haWwgQVBJLiAgVGhpcyBkb2N1bWVudGF0aW9uIGRlc2NyaWJlcyBob3cgdG8KKyAgICAgIHVzZSBmZWF0dXJlcyBvZiB0aGUgU3VuIHByb3RvY29sIHByb3ZpZGVycyB0byBkaXJlY3RseSBhY2Nlc3MKKyAgICAgIHNvbWUgZmVhdHVyZXMgb2YgdGhlIFNNVFAsIElNQVAsIGFuZCBQT1AzIHByb3RvY29scyB0aGF0IGFyZQorICAgICAgbm90IG90aGVyd2lzZSBzdXBwb3J0ZWQgYnkgdGhlIHN0YW5kYXJkIEphdmFNYWlsIEFQSS4KKworCitHbWFpbCBJTUFQIFByb3ZpZGVyCistLS0tLS0tLS0tLS0tLS0tLS0tCisKK1RoaXMgcmVsZWFzZSBpbmNsdWRlcyBhbiBFWFBFUklNRU5UQUwgR21haWwgSU1BUCBwcm92aWRlci4KK05vcm1hbCB1c2Ugb2YgR21haWwgaXMgaGFuZGxlZCBieSB0aGUgc3RhbmRhcmQgImltYXAiIHByb3RvY29sCitwcm92aWRlciwgYnV0IHRoZSBuZXcgImdpbWFwIiBwcm90b2NvbCBwcm92aWRlciBzdXBwb3J0cyBhZGRpdGlvbmFsCitHbWFpbC1zcGVjaWZpYyBub24tc3RhbmRhcmQgZmVhdHVyZXMuICBTZWUgdGhlIGphdmFkb2NzIGZvciB0aGUKK2NvbS5zdW4ubWFpbC5naW1hcCBwYWNrYWdlIGZvciBkZXRhaWxzLiAgTm90ZSB0aGF0IHRoZSBnaW1hcC5qYXIgZmlsZQorbmVlZHMgdG8gYmUgYWRkZWQgdG8geW91ciBDTEFTU1BBVEggdG8gdXNlIHRoaXMgbmV3IHByb3ZpZGVyLgorCisKK1NBU0wgU3VwcG9ydAorLS0tLS0tLS0tLS0tCisKK09uIHN5c3RlbXMgdGhhdCBzdXBwb3J0IHRoZSBKYXZhIFNBU0wgQVBJIChqYXZheC5zZWN1cml0eS5zYXNsLCBKU1ItMjgpLAorc3VjaCBhcyBKMlNFIDUuMCBhbmQgbGF0ZXIsIHRoZSBJTUFQIHByb3ZpZGVyIGNhbiB1c2UgdGhlIFNBU0wgQVBJIHRvCitmaW5kIGFuIGFwcHJvcHJpYXRlIGF1dGhlbnRpY2F0aW9uIG1lY2hhbmlzbS4gIFRoZSBTQVNMIEFQSSBhbHNvIGFsbG93cworeW91IHRvIHBsdWcgaW4gc3VwcG9ydCBmb3IgY3VzdG9tIGF1dGhlbnRpY2F0aW9uIG1lY2hhbmlzbXMuICBTZWUgVGhlCitKYXZhIFNBU0wgQVBJIFByb2dyYW1taW5nIGFuZCBEZXBsb3ltZW50IEd1aWRlIGF0CitodHRwczovL2RvY3Mub3JhY2xlLmNvbS9qYXZhc2UvOC9kb2NzL3RlY2hub3Rlcy9ndWlkZXMvc2VjdXJpdHkvc2FzbC9zYXNsLXJlZmd1aWRlLmh0bWwKK2ZvciBkZXRhaWxzIG9uIGRldmVsb3BpbmcgY3VzdG9tIFNBU0wgbWVjaGFuaXNtcy4gIFNlZSB0aGUgamF2YWRvY3MgZm9yCit0aGUgY29tLnN1bi5tYWlsLmltYXAgcGFja2FnZSBmb3IgdGhlIHByb3BlcnRpZXMgcmVxdWlyZWQgdG8gZW5hYmxlIGFuZAorY29uZmlndXJlIFNBU0wgc3VwcG9ydC4KKworCitEU04gU3VwcG9ydAorLS0tLS0tLS0tLS0KKworVGhpcyByZWxlYXNlIG9mIEphdmFNYWlsIGluY2x1ZGVzIEVYUEVSSU1FTlRBTCBzdXBwb3J0IGZvciBjcmVhdGluZworYW5kIHBhcnNpbmcgRGVsaXZlcnkgU3RhdHVzIE5vdGlmaWNhdGlvbnMsIGFzIGRlZmluZWQgYnkgUkZDIDM0NjIKK2FuZCBSRkMgMzQ2NC4gIFRvIG1ha2UgdXNlIG9mIHRoaXMgc3VwcG9ydCB5b3UgbmVlZCB0byBpbmNsdWRlIGRzbi5qYXIKK2luIHlvdXIgQ0xBU1NQQVRIIGFsb25nIHdpdGggamFrYXJ0YS5tYWlsLmphci4gIFNlZSB0aGUgamF2YWRvY3MgZm9yIHRoZQorY29tLnN1bi5tYWlsLmRzbiBwYWNrYWdlIGZvciBtb3JlIGRldGFpbHMuCisKK1RoZSBEU04gcGFja2FnZSBhbHNvIHByb3ZpZGVzIHN1cHBvcnQgZm9yIGNyZWF0aW5nIGFuZCBwYXJzaW5nIE1lc3NhZ2UKK0Rpc3Bvc2l0aW9uIE5vdGlmaWNhdGlvbnMsIGFzIGRlZmluZWQgYnkgUkZDIDM3OTguCisKK1RoZSBBUElzIHVuaXF1ZSB0byB0aGlzIHBhY2thZ2Ugc2hvdWxkIGJlIGNvbnNpZGVyZWQgRVhQRVJJTUVOVEFMLgorVGhleSBtYXkgYmUgY2hhbmdlZCBpbiB0aGUgZnV0dXJlIGluIHdheXMgdGhhdCBhcmUgaW5jb21wYXRpYmxlIHdpdGgKK2FwcGxpY2F0aW9ucyB1c2luZyB0aGUgY3VycmVudCBBUElzLgorCisKK05UTE0gU3VwcG9ydAorLS0tLS0tLS0tLS0tCisKK1RoaXMgcmVsZWFzZSBvZiBKYXZhTWFpbCBpbmNsdWRlcyBFWFBFUklNRU5UQUwgc3VwcG9ydCBmb3IgdGhlCitNaWNyb3NvZnQgTlRMTSBhdXRoZW50aWNhdGlvbiBtZWNoYW5pc20gdXNlZCBieSBFeGNoYW5nZS4gIFNlZSB0aGUKK2ZpbGUgTlRMTU5PVEVTLnR4dCBmb3IgZGV0YWlscy4KKworCitPU0dpIFN1cHBvcnQKKy0tLS0tLS0tLS0tLQorCitUaGUgSmF2YU1haWwgamFyIGZpbGVzIGFyZSBub3cgT1NHaSBidW5kbGVzLiAgUGxlYXNlIGxldCB1cyBrbm93CitvZiBhbnkgcHJvYmxlbXMgdXNpbmcgSmF2YU1haWwgd2l0aCBPU0dpLgorCisKK0hvdyB0byBzdWJtaXQgYnVnIHJlcG9ydHMKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworSWYgeW91J3ZlIGZvdW5kIGEgYnVnLCBvciBpZiB5b3UganVzdCBuZWVkIGhlbHAgZmlndXJpbmcgb3V0IGhvdyB0byB1c2UKK3RoZSBKYXZhTWFpbCBBUEksIHBsZWFzZSB0cnkgdG8gaW5jbHVkZSB0aGUgZm9sbG93aW5nIGluZm9ybWF0aW9uIGluCit5b3VyIG1lc3NhZ2UgdG8gdXM6CisKKyAgICAtIGEgcHJvZ3JhbSBvciBjb2RlIHNuaXBwZXQgdGhhdCBzaG93cyB0aGUgcHJvYmxlbQorICAgIC0gdGhlIHBsYXRmb3JtIHlvdSBhcmUgdXNpbmcKKyAgICAtIHRoZSBtYWlsIHNlcnZlciAodmVuZG9yIG5hbWUsIHZlcnNpb24gbnVtYmVyKSB5b3UgYXJlIHVzaW5nCisgICAgLSB5b3VyIGVudmlyb25tZW50IHZhcmlhYmxlIHNldHRpbmdzCisgICAgLSBhIHN0YWNrIHRyYWNlLCBpZiBhcHByb3ByaWF0ZQorICAgIC0gYSBwcm90b2NvbCB0cmFjZSwgYWZ0ZXIgdHVybmluZyBvbiBzZXNzaW9uIGRlYnVnZ2luZywgaWYgYXBwcm9wcmlhdGUKKworTW9zdCBvZiB0aGUgcHJvYmxlbXMgcmVwb3J0ZWQgdG8gdXMgZmFpbCB0byBpbmNsdWRlIGVub3VnaCBvZiB0aGUgYWJvdmUKK2luZm9ybWF0aW9uIHRvIGFsbG93IHVzIHRvIGRpYWdub3NlIHlvdXIgcHJvYmxlbS4gIEl0IHdpbGwgc2F2ZSB5b3UgYW5kCit1cyB0aW1lIGlmIHlvdSBpbmNsdWRlIHRoaXMgaW5mb3JtYXRpb24gaW4geW91ciBmaXJzdCBtZXNzYWdlIHRvIHVzLgorCitCeSBmYXIgdGhlIG1vc3QgY29tbW9uIHByb2JsZW1zIHdlIHNlZSBhcmU6CisKK1lvdXIgcHJvYmxlbToJU29tZXRoaW5nIGRvZXNuJ3Qgd29yayByaWdodCB3aGVuIHRhbGtpbmcgdG8gbXkgbWFpbCBzZXJ2ZXIuCitPdXIgcmVzcG9uc2U6CVR1cm4gb24gc2Vzc2lvbiBkZWJ1Z2dpbmcgYW5kIHNlbmQgdXMgdGhlIHByb3RvY29sIHRyYWNlLgorCQlTZWUgdGhlIGRlbW8gcHJvZ3JhbSBkb2N1bWVudGF0aW9uIGZvciBob3cgdG8gdHVybiBvbgorCQlzZXNzaW9uIGRlYnVnZ2luZyBmb3IgdGhlIGRlbW8gcHJvZ3JhbXMuICBJbiB5b3VyIG93bgorCQlwcm9ncmFtLCBjYWxsICJzZXNzaW9uLnNldERlYnVnKHRydWUpOyIuCisKK1lvdXIgcHJvYmxlbToJamF2YXgubWFpbCBvciBqYXZheC5hY3RpdmF0aW9uIGNsYXNzZXMgbm90IGZvdW5kIHdoZW4gY29tcGlsaW5nLgorT3VyIHJlc3BvbnNlOglZb3UgZGlkbid0IHNldCBDTEFTU1BBVEggY29ycmVjdGx5IHRvIGZpbmQgamFrYXJ0YS5tYWlsLmphciBhbmQKKwkJamFrYXJ0YS5hY3RpdmF0aW9uLmphci4gIFNlZSBSRUFETUUudHh0LgorCitZb3VyIHByb2JsZW06CU5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIC0gTm8gc3VjaCBwcm92aWRlciBmb3IgcmZjODIyLgorT3VyIHJlc3BvbnNlOglZb3UgdW5qYXInZWQgamFrYXJ0YS5tYWlsLmphci4gIERvbid0LgorCitZb3VyIHByb2JsZW06CUhvdyBkbyBJIGNyZWF0ZSBhIG1lc3NhZ2Ugd2l0aCBhbiBhdHRhY2htZW50PworT3VyIHJlc3BvbnNlOglDcmVhdGUgYSBtZXNzYWdlIHdpdGggYSBNaW1lTXVsdGlwYXJ0IGNvbnRlbnQuICBTZWUgdGhlCisJCXNlbmRmaWxlLmh0bWwgYW5kIG1zZ211bHRpc2VuZHNhbXBsZS5qYXZhIGRlbW8gcHJvZ3JhbXMuCisKK1BsZWFzZSBjaGVjayB0aGUgRkFRIGF0IGh0dHBzOi8vZWNsaXBzZS1lZTRqLmdpdGh1Yi5pby9qYXZhbWFpbC9GQVEKK2JlZm9yZSBzdWJtaXR0aW5nIGJ1ZyByZXBvcnRzLgorCitTZW5kIHlvdXIgYnVnIHJlcG9ydHMgdG86CisKKwlqYXZhbWFpbF93d0BvcmFjbGUuY29tCisKKworCisKK1NlcnZlcnMgdGVzdGVkIHdpdGg6CistLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIFRoZSBJTUFQIGltcGxlbWVudGF0aW9uIHdvcmtzIHdpdGggSU1BUDQgYW5kIElNQVA0cmV2MSBzZXJ2ZXJzLgorICBUaGUgY3VycmVudCByZWxlYXNlIGhhcyBiZWVuIHRlc3RlZCB3aXRoOgorCU9yYWNsZSBCZWVoaXZlCisJT3JhY2xlIENvbW11bmljYXRpb25zIE1lc3NhZ2luZyBTZXJ2ZXIgOC4wCisJVVcgSU1BUDQgc2VydmVyIHZlcnNpb24gMjAwMy4zMzkKKwlDeXJ1cyBJTUFQNCBzZXJ2ZXIgdmVyc2lvbiAxLjYuMTkKKwlNaWNyb3NvZnQgRXhjaGFuZ2UgMjAxMAorCU1pY3Jvc29mdCBFeGNoYW5nZSAyMDEzCisJTWljcm9zb2Z0IEV4Y2hhbmdlIDIwMTYKKworICBQcmV2aW91cyByZWxlYXNlcyBoYXZlIGJlZW4gdGVzdGVkIHdpdGg6CisJU3VuIEphdmEgU3lzdGVtIE1lc3NhZ2luZyBTZXJ2ZXIgdmVyc2lvbiA1LjIKKwlTdW4gSmF2YSBTeXN0ZW0gTWVzc2FnaW5nIFNlcnZlciB2ZXJzaW9uIDYuMworCVN1biBKYXZhIFN5c3RlbSBNZXNzYWdpbmcgU2VydmVyIHZlcnNpb24gNy4wCisJU3VuIEludGVybmV0IE1haWwgU2VydmVyIHZlcnNpb24gMi4wLCAzLjIsIGFuZCA0LjAKKwlOZXRzY2FwZSBNZXNzYWdpbmcgU2VydmVyIHZlcnNpb24gMy4wMSBhbmQgNC4xCisJTWljcm9zb2Z0IE1DSVMgTWFpbCBTZXJ2ZXIKKwlMb3R1cyBOb3RlcworCVNvZnR3YXJlLmNvbSBJTUFQIHNlcnZlcgorCVF1YWxjb21tIFdvcmxkbWFpbAorCisgIFRoZSBjdXJyZW50IHJlbGVhc2Ugb2YgdGhlIFNNVFAgaW1wbGVtZW50YXRpb24gaGFzIGJlZW4gdGVzdGVkIHdpdGg6CisJU2VuZG1haWwgdmVyc2lvbiA4LjEzLjgKKwlPcmFjbGUgQmVlaGl2ZQorCU9yYWNsZSBDb21tdW5pY2F0aW9ucyBNZXNzYWdpbmcgU2VydmVyIDguMAorCU1pY3Jvc29mdCBFeGNoYW5nZSAyMDEwCisJTWljcm9zb2Z0IEV4Y2hhbmdlIDIwMTMKKwlNaWNyb3NvZnQgRXhjaGFuZ2UgMjAxNgorCisgIFByZXZpb3VzIHJlbGVhc2VzIGhhdmUgYmVlbiB0ZXN0ZWQgd2l0aDoKKwlTZW5kbWFpbCB2ZXJzaW9uIDguNiBhbmQgOC45LjEKKwlTdW4gSmF2YSBTeXN0ZW0gTWVzc2FnaW5nIFNlcnZlciB2ZXJzaW9uIDUuMgorCVN1biBKYXZhIFN5c3RlbSBNZXNzYWdpbmcgU2VydmVyIHZlcnNpb24gNi4zCisJU3VuIEphdmEgU3lzdGVtIE1lc3NhZ2luZyBTZXJ2ZXIgdmVyc2lvbiA3LjAKKwlTdW4gSW50ZXJuZXQgTWFpbCBTZXJ2ZXIgdmVyc2lvbiAzLjIgYW5kIDQuMAorCU5ldHNjYXBlIE1lc3NhZ2luZyBTZXJ2ZXIgdmVyc2lvbiAzLjAxIGFuZCA0LjEKKwlNaWNyb3NvZnQgRXhjaGFuZ2UKKwlNaWNyb3NvZnQgTUNJUyBNYWlsIFNlcnZlcgorCVF1YWxjb21tIFdvcmxkbWFpbAorCitIb3cgdG8gZ2l2ZSBmZWVkYmFjaworLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworUGxlYXNlIHNlbmQgeW91ciBmZWVkYmFjayB0byB0aGlzIGVtYWlsLWFkZHJlc3M6CisKKwlqYXZhbWFpbF93d0BvcmFjbGUuY29tCisKK0NoZWNrIG91dCBvdXIgd2Vic2l0ZSBhdCBodHRwczovL2VjbGlwc2UtZWU0ai5naXRodWIuaW8vamF2YW1haWwvLgorCitZb3UgY2FuIGFsc28gZmluZCBoZWxwIG9uIFN0YWNrT3ZlcmZsb3c6CisKKwlodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy90YWdnZWQvamF2YW1haWwKKworCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KZGlmZiAtLWdpdCBhL2RvYy9yZWxlYXNlL05UTE1OT1RFUy50eHQgYi9kb2MvcmVsZWFzZS9OVExNTk9URVMudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg3ZmNlNzIKLS0tIC9kZXYvbnVsbAorKysgYi9kb2MvcmVsZWFzZS9OVExNTk9URVMudHh0CkBAIC0wLDAgKzEsMjggQEAKKwlOb3RlcyBmb3IgdXNlIG9mIE5UTE0gYXV0aGVudGljYXRpb24gc3VwcG9ydCB3aXRoIEphdmFNYWlsCisJLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitUaGFua3MgdG8gdGhlIGVmZm9ydHMgb2YgTHVpcyBTZXJyYWxoZWlybywgSmF2YU1haWwgbm93IHN1cG9ydHMgdGhlIHVzZQorb2YgTWljcm9zb2Z0J3MgcHJvcHJpZXRhcnkgTlRMTSBhdXRoZW50aWNhdGlvbiBtZWNoYW5pc20uICBUaGlzIHN1cHBvcnQKK3dpdGhpbiBKYXZhTWFpbCBpcyBub3cgZGVyaXZlZCBmcm9tIHRoZSBOVExNIHN1cHBvcnQgaW4gdGhlIEpESyBhbmQKK2luY2x1ZGVkIGRpcmVjdGx5IGluIEphdmFNYWlsLCB3aXRoIG5vIGV4dGVybmFsIGRlcGVuZGVuY2llcy4KKworVGhpcyByZWxlYXNlIG9mIEphdmFNYWlsIHdhcyB0ZXN0ZWQgd2l0aCBNaWNyb3NvZnQgRXhjaGFuZ2UgNS41IGFuZCAyMDA3LgorCitUaGUgU01UUCBhbmQgSU1BUCBwcm92aWRlcnMgc3VwcG9ydCB0aGUgdXNlIG9mIE5UTE0gYXV0aGVudGljYXRpb24uCitUaGUgZm9sbG93aW5nIHByb3BlcnRpZXMgY2FuIGJlIHVzZWQgdG8gY29uZmlndXJlIHRoZSBOVExNIHN1cHBvcnQ6CisKK21haWwuPHByb3RvY29sPi5hdXRoLm50bG0uZG9tYWluCisJVGhlIE5UTE0gYXV0aGVudGljYXRpb24gZG9tYWluLgorCittYWlsLjxwcm90b2NvbD4uYXV0aC5udGxtLmZsYWdzCisJTlRMTSBwcm90b2NvbC1zcGVjaWZpYyBmbGFncy4gIChub3QgY3VycmVudGx5IHVzZWQpCisJU2VlIGh0dHA6Ly9jdXJsLmhheHguc2UvcmZjL250bG0uaHRtbCN0aGVOdGxtRmxhZ3MgZm9yIGRldGFpbHMuCisKKworTk9URToJVGhpcyBjYXBhYmlsaXR5IGlzIHZlcnkgbmV3IGFuZCBoYXMgTk9UIGJlZW4gdGhvcm91Z2hseSB0ZXN0ZWQuCisJUGxlYXNlIHNlbmQgYW55IGZlZWRiYWNrIG9yIGJ1ZyByZXBvcnRzIHRvIHVzIGF0IGphdmFtYWlsX3d3QG9yYWNsZS5jb20uCisKK1dBUk5JTkc6IFRoaXMgc3VwcG9ydCwgYW5kIHRoZSBBUElzIGFuZCBwcm9wZXJ0aWVzIHVzZWQgdG8gY29udHJvbCBpdCwKK3Nob3VsZCBiZSBjb25zaWRlcmVkIEVYUEVSSU1FTlRBTC4gIFRoZXkgbWF5IGJlIGNoYW5nZWQgaW4gdGhlIGZ1dHVyZQoraW4gd2F5cyB0aGF0IGFyZSBpbmNvbXBhdGlibGUgd2l0aCBhcHBsaWNhdGlvbnMgdXNpbmcgdGhlIGN1cnJlbnQgQVBJcworYW5kIHByb3BlcnRpZXMuCmRpZmYgLS1naXQgYS9kb2MvcmVsZWFzZS9SRUFETUUudHh0IGIvZG9jL3JlbGVhc2UvUkVBRE1FLnR4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZjIwNjk3Ci0tLSAvZGV2L251bGwKKysrIGIvZG9jL3JlbGVhc2UvUkVBRE1FLnR4dApAQCAtMCwwICsxLDE3NSBAQAorCQkJUkVBRE1FCisJCQk9PT09PT0KKworCSAgICBKYXZhTWFpbChUTSkgQVBJICR7bWFpbC52ZXJzaW9ufSByZWxlYXNlCisJICAgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitXZWxjb21lIHRvIHRoZSBKYXZhTWFpbCBBUEkgJHttYWlsLnZlcnNpb259IHJlbGVhc2UhICBUaGlzIHJlbGVhc2UgaW5jbHVkZXMKK3ZlcnNpb25zIG9mIHRoZSBKYXZhTWFpbCBBUEkgaW1wbGVtZW50YXRpb24sIElNQVAsIFNNVFAsIGFuZCBQT1AzCitzZXJ2aWNlIHByb3ZpZGVycywgc29tZSBleGFtcGxlcywgYW5kIGRvY3VtZW50YXRpb24gZm9yIHRoZSBKYXZhTWFpbAorQVBJLgorCitQbGVhc2Ugc2VlIHRoZSBGQVEgYXQgaHR0cHM6Ly9lY2xpcHNlLWVlNGouZ2l0aHViLmlvL2phdmFtYWlsL0ZBUQorCitKREsgVmVyc2lvbiBub3RlcworLS0tLS0tLS0tLS0tLS0tLS0KKworVGhlIEphdmFNYWlsIEFQSSBzdXBwb3J0cyBKREsgMS43IG9yIGhpZ2hlci4gIE5vdGUgdGhhdCB3ZSBoYXZlCitjdXJyZW50bHkgdGVzdGVkIHRoaXMgaW1wbGVtZW50YXRpb24gd2l0aCBKREsgMS43IGFuZCAxLjguCisKK1doaWxlIEphdmFNYWlsIHdpbGwgd29yayB3aXRoIEpBRiAxLjAuMiwgd2UgcmVjb21tZW5kIHRoZSB1c2Ugb2YgSkFGIDEuMQorb3IgbmV3ZXIuICBKQUYgMS4yLjEgaXMgY3VycmVudGx5IHRoZSBuZXdlc3QgdmVyc2lvbi4gIE5vdGUgdGhhdCBKQUYgMS4xCitpcyBpbmNsdWRlZCBpbiBKREsgMS42IGFuZCBKQUYgMS4xLjEgaXMgaW5jbHVkZWQgaW4gSkRLIDEuNi4wXzEwIGFuZAorbGF0ZXIuICBKQUYgMS4yLjAgaXMgaW5jbHVkZWQgYnV0IGhpZGRlbiBpbiBKREsgOSBhbmQgaGFzIGJlZW4gcmVtb3ZlZAorZnJvbSBKREsgMTEuICBKQUYgMS4yLjEgaXMgYXZhaWxhYmxlIHNlcGFyYXRlbHkgKHNlZSBiZWxvdykuCisKKworUHJvdG9jb2xzIHN1cHBvcnRlZAorLS0tLS0tLS0tLS0tLS0tLS0tLQorCitUaGlzIHJlbGVhc2Ugc3VwcG9ydHMgdGhlIGZvbGxvd2luZyBJbnRlcm5ldCBzdGFuZGFyZCBtYWlsIHByb3RvY29sczoKKworICAgIElNQVAgLSBhIG1lc3NhZ2UgU3RvcmUgcHJvdG9jb2wsIGZvciByZWFkaW5nIG1lc3NhZ2VzIGZyb20gYSBzZXJ2ZXIKKyAgICBQT1AzIC0gYSBtZXNzYWdlIFN0b3JlIHByb3RvY29sLCBmb3IgcmVhZGluZyBtZXNzYWdlcyBmcm9tIGEgc2VydmVyCisgICAgU01UUCAtIGEgbWVzc2FnZSBUcmFuc3BvcnQgcHJvdG9jb2wsIGZvciBzZW5kaW5nIG1lc3NhZ2VzIHRvIGEgc2VydmVyCisKK1RoZSBmb2xsb3dpbmcgdGFibGUgbGlzdHMgdGhlIG5hbWVzIG9mIHRoZSBzdXBwb3J0ZWQgcHJvdG9jb2xzIChhcyB1c2VkCitpbiB0aGUgSmF2YU1haWwgQVBJKSBhbmQgdGhlaXIgY2FwYWJpbGl0aWVzOgorCisJUHJvdG9jb2wJU3RvcmUgb3IJVXNlcwlTdXBwb3J0cworCU5hbWUJCVRyYW5zcG9ydD8JU1NMPwlTVEFSVFRMUz8KKwktLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisJaW1hcAkJU3RvcmUJCU5vCVllcworCWltYXBzCQlTdG9yZQkJWWVzCU4vQQorCWdpbWFwCQlTdG9yZQkJWWVzCU4vQQorCXBvcDMJCVN0b3JlCQlObwlZZXMKKwlwb3AzcwkJU3RvcmUJCVllcwlOL0EKKwlzbXRwCQlUcmFuc3BvcnQJTm8JWWVzCisJc210cHMJCVRyYW5zcG9ydAlZZXMJTi9BCisKK1NlZSBvdXIgd2ViIHBhZ2UgYXQgaHR0cHM6Ly9lY2xpcHNlLWVlNGouZ2l0aHViLmlvL2phdmFtYWlsLworZm9yIHRoZSBsYXRlc3QgaW5mb3JtYXRpb24gb24gdGhpcmQgcGFydHkgcHJvdG9jb2wgcHJvdmlkZXJzLgorCisKK0Rvd25sb2FkCistLS0tLS0tLQorCitTZWUgdGhlIEphdmFNYWlsIHByb2plY3QgcGFnZSB0byBkb3dubG9hZCB0aGlzIHJlbGVhc2UuCisKKwlodHRwczovL2VjbGlwc2UtZWU0ai5naXRodWIuaW8vamF2YW1haWwvCisKKworUmVxdWlyZW1lbnRzCistLS0tLS0tLS0tLS0KKworTm90ZSB0aGF0IHRoZSBKYXZhTWFpbCBBUEkgcmVxdWlyZXMgdGhlIEphdmFCZWFucyhUTSkgQWN0aXZhdGlvbgorRnJhbWV3b3JrIHBhY2thZ2UgdG8gYmUgaW5zdGFsbGVkIGFzIHdlbGwgaWYgeW91J3JlIHVzaW5nIG9yIEpESyAxMSBvciBsYXRlci4KKworRG93bmxvYWQgdGhlIGxhdGVzdCB2ZXJzaW9uIG9mIHRoZSBKYXZhQmVhbnMgQWN0aXZhdGlvbiBGcmFtZXdvcmsgZnJvbQorCisJaHR0cHM6Ly9naXRodWIuY29tL2VjbGlwc2UtZWU0ai9qYWYvcmVsZWFzZXMKKworYW5kIGluc3RhbGwgaXQgaW4gYSBzdWl0YWJsZSBsb2NhdGlvbi4KKworCitJbnN0YWxsYXRpb24KKy0tLS0tLS0tLS0tLQorCisgIFVOSVgvTGludXgKKyAgLS0tLS0tLS0tLQorCisgIDEuIERvd25sb2FkIHRoZSBqYWthcnRhLm1haWwuamFyIGZpbGUgZnJvbSB0aGUgSmF2YU1haWwgcHJvamVjdCB3ZWJzaXRlLgorICAgICBodHRwczovL2dpdGh1Yi5jb20vZWNsaXBzZS1lZTRqL2phdmFtYWlsL3JlbGVhc2VzCisKKyAgMi4gU2V0IHlvdXIgQ0xBU1NQQVRIIHRvIGluY2x1ZGUgdGhlICJqYWthcnRhLm1haWwuamFyIiBmaWxlIG9idGFpbmVkIGZyb20KKyAgICAgdGhlIGRvd25sb2FkLCBhcyB3ZWxsIGFzIHRoZSBjdXJyZW50IGRpcmVjdG9yeS4KKworICAgICBBc3N1bWluZyB5b3UgaGF2ZSBkb3dubG9hZGVkIGpha2FydGEubWFpbC5qYXIgdG8gdGhlIC91L21lL2Rvd25sb2FkLworICAgICBkaXJlY3RvcnksIHRoZSBmb2xsb3dpbmcgd291bGQgd29yazoKKworICAgICAgZXhwb3J0IENMQVNTUEFUSD0kQ0xBU1NQQVRIOi91L21lL2Rvd25sb2FkL2pha2FydGEubWFpbC5qYXI6LgorCisgICAgKERvbid0IGZvcmdldCB0aGUgdHJhaWxpbmcgIi4iIGZvciB0aGUgY3VycmVudCBkaXJlY3RvcnkuKQorICAgIEFsc28sIGlmIHlvdSdyZSB1c2luZyBKREsgMS41LCBpbmNsdWRlIHRoZSAiYWN0aXZhdGlvbi5qYXIiIGZpbGUgdGhhdCB5b3UKKyAgICBvYnRhaW5lZCBmcm9tIGRvd25sb2FkaW5nIHRoZSBKYXZhQmVhbnMgQWN0aXZhdGlvbiBGcmFtZXdvcmsuICBGb3IgZXhhbXBsZToKKworICAgICAgZXhwb3J0IENMQVNTUEFUSD0kQ0xBU1NQQVRIOi91L21lL2Rvd25sb2FkL2FjdGl2YXRpb24vYWN0aXZhdGlvbi5qYXIKKworICAzLiBEb3dubG9hZCB0aGUgamF2YW1haWwtc2FtcGxlcy56aXAgZmlsZSBmcm9tIHRoZSBwcm9qZWN0IHdlYnNpdGUuCisgICAgIGh0dHBzOi8vZ2l0aHViLmNvbS9lY2xpcHNlLWVlNGovamF2YW1haWwvcmVsZWFzZXMKKworICA0LiBDb21waWxlIGFueSBzYW1wbGUgcHJvZ3JhbSB1c2luZyB5b3VyIEphdmEgY29tcGlsZXIuIEZvciBleGFtcGxlOgorCisgICAgICBqYXZhYyBtc2dzaG93LmphdmEKKworICA1LiBSdW4gdGhlIHNhbXBsZSBwcm9ncmFtLiAgVGhlICctJyBvcHRpb24gbGlzdHMgdGhlIHJlcXVpcmVkIGFuZCBvcHRpb25hbAorICAgICBjb21tYW5kLWxpbmUgb3B0aW9ucyB0byBzdWNjZXNzZnVsbHkgcnVuIGFueSBzYW1wbGUuICBGb3IgZXhhbXBsZToKKworICAgICAgamF2YSBtc2dzaG93IC0KKworICAgIGxpc3RzIHRoZSBhdmFpbGFibGUgb3B0aW9ucy4gIEFuZAorCisgICAgICBqYXZhIG1zZ3Nob3cgLVQgaW1hcCAtSCA8bWFpbHNlcnZlcj4gLVUgPHVzZXJuYW1lPiAtUCA8cGFzc3dkPiAtZiBJTkJPWCA1CisKKyAgICB1c2VzIHRoZSBJTUFQIHByb3RvY29sIHRvIGRpc3BsYXkgbWVzc2FnZSBudW1iZXIgNSBmcm9tIHlvdXIgSU5CT1guCisKKyAgKEFkZGl0aW9uYWwgaW5zdHJ1Y3Rpb25zIG9uIGhvdyB0byBydW4gdGhlIHNpbXBsZSBtYWlsIHJlYWRlciBzYW1wbGUKKyAgYW5kIHNlcnZsZXQgc2FtcGxlIGFyZSBwcm92aWRlZCBpbiBjbGllbnQvUkVBRE1FLnR4dCBhbmQgc2VydmxldC9SRUFETUUudHh0LAorICByZXNwZWN0aXZlbHkuKQorCisKKyAgV2luZG93cworICAtLS0tLS0tCisKKyAgMS4gRG93bmxvYWQgdGhlIGpha2FydGEubWFpbC5qYXIgZmlsZSBmcm9tIHRoZSBKYXZhTWFpbCBwcm9qZWN0IHdlYnNpdGUuCisgICAgIGh0dHBzOi8vZ2l0aHViLmNvbS9lY2xpcHNlLWVlNGovamF2YW1haWwvcmVsZWFzZXMKKworICAyLiBTZXQgeW91ciBDTEFTU1BBVEggdG8gaW5jbHVkZSB0aGUgImpha2FydGEubWFpbC5qYXIiIGZpbGUgb2J0YWluZWQgZnJvbQorICAgICB0aGUgZG93bmxvYWQsIGFzIHdlbGwgYXMgdGhlIGN1cnJlbnQgZGlyZWN0b3J5LgorCisgICAgIEFzc3VtaW5nIHlvdSBoYXZlIGRvd25sb2FkZWQgamFrYXJ0YS5tYWlsLmphciB0byB0aGUgL3UvbWUvZG93bmxvYWQvCisgICAgIGRpcmVjdG9yeSwgdGhlIGZvbGxvd2luZyB3b3VsZCB3b3JrOgorCisgICAgICBzZXQgQ0xBU1NQQVRIPSVDTEFTU1BBVEglO2M6XGRvd25sb2FkXGpha2FydGEubWFpbC5qYXI7LgorCisgICAgKERvbid0IGZvcmdldCB0aGUgdHJhaWxpbmcgIi4iIGZvciB0aGUgY3VycmVudCBkaXJlY3RvcnkuKQorICAgIEFsc28sIGlmIHlvdSdyZSB1c2luZyBKREsgMS41LCBpbmNsdWRlIHRoZSAiYWN0aXZhdGlvbi5qYXIiIGZpbGUgdGhhdCB5b3UKKyAgICBvYnRhaW5lZCBmcm9tIGRvd25sb2FkaW5nIHRoZSBKYXZhQmVhbnMgQWN0aXZhdGlvbiBGcmFtZXdvcmsuICBGb3IgZXhhbXBsZToKKworICAgICAgc2V0IENMQVNTUEFUSD0lQ0xBU1NQQVRIJTtjOlxkb3dubG9hZFxhY3RpdmF0aW9uXGFjdGl2YXRpb24uamFyCisKKyAgMy4gRG93bmxvYWQgdGhlIGphdmFtYWlsLXNhbXBsZXMuemlwIGZpbGUgZnJvbSB0aGUgcHJvamVjdCB3ZWJzaXRlLgorICAgICBodHRwczovL2dpdGh1Yi5jb20vZWNsaXBzZS1lZTRqL2phdmFtYWlsL3JlbGVhc2VzCisKKyAgNC4gQ29tcGlsZSBhbnkgc2FtcGxlIHByb2dyYW0gdXNpbmcgeW91ciBKYXZhIGNvbXBpbGVyLiBGb3IgZXhhbXBsZToKKworICAgICAgamF2YWMgbXNnc2hvdy5qYXZhCisKKyAgNS4gUnVuIHRoZSBzYW1wbGUgcHJvZ3JhbS4gIFRoZSAnLScgb3B0aW9uIGxpc3RzIHRoZSByZXF1aXJlZCBhbmQgb3B0aW9uYWwKKyAgICAgY29tbWFuZC1saW5lIG9wdGlvbnMgdG8gc3VjY2Vzc2Z1bGx5IHJ1biBhbnkgc2FtcGxlLiAgRm9yIGV4YW1wbGU6CisKKyAgICAgIGphdmEgbXNnc2hvdyAtCisKKyAgICBsaXN0cyB0aGUgYXZhaWxhYmxlIG9wdGlvbnMuICBBbmQKKworICAgICAgamF2YSBtc2dzaG93IC1UIGltYXAgLUggPG1haWxzZXJ2ZXI+IC1VIDx1c2VybmFtZT4gLVAgPHBhc3N3ZD4gLWYgSU5CT1ggNQorCisgICAgdXNlcyB0aGUgSU1BUCBwcm90b2NvbCB0byBkaXNwbGF5IG1lc3NhZ2UgbnVtYmVyIDUgZnJvbSB5b3VyIElOQk9YLgorCisgIChBZGRpdGlvbmFsIGluc3RydWN0aW9ucyBvbiBob3cgdG8gcnVuIHRoZSBzaW1wbGUgbWFpbCByZWFkZXIgc2FtcGxlCisgIGFuZCBzZXJ2bGV0IHNhbXBsZSBhcmUgcHJvdmlkZWQgaW4gY2xpZW50L1JFQURNRS50eHQgYW5kIHNlcnZsZXQvUkVBRE1FLnR4dCwKKyAgcmVzcGVjdGl2ZWx5LikKKworCitQcm9ibGVtcz8KKy0tLS0tLS0tLQorCitUaGUgSmF2YU1haWwgRkFRIGF0IGh0dHBzOi8vZWNsaXBzZS1lZTRqLmdpdGh1Yi5pby9qYXZhbWFpbC9GQVEKK2luY2x1ZGVzIGluZm9ybWF0aW9uIG9uIHByb3RvY29scyBzdXBwb3J0ZWQsIGluc3RhbGxhdGlvbiBwcm9ibGVtcywKK2RlYnVnZ2luZyB0aXBzLCBldGMuCisKK1NlZSB0aGUgTk9URVMudHh0IGZpbGUgZm9yIGluZm9ybWF0aW9uIG9uIGhvdyB0byByZXBvcnQgYnVncy4KKworRW5qb3khCisKK1RoZSBKYXZhTWFpbCBBUEkgVGVhbQpkaWZmIC0tZ2l0IGEvZG9jL3JlbGVhc2UvU1NMTk9URVMudHh0IGIvZG9jL3JlbGVhc2UvU1NMTk9URVMudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkzZTJlYWMKLS0tIC9kZXYvbnVsbAorKysgYi9kb2MvcmVsZWFzZS9TU0xOT1RFUy50eHQKQEAgLTAsMCArMSwzMTEgQEAKKwkJTm90ZXMgZm9yIHVzZSBvZiBTU0wgd2l0aCBKYXZhTWFpbAorCQktLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0phdmFNYWlsIG5vdyBzdXBwb3J0cyBhY2Nlc3NpbmcgbWFpbCBzZXJ2ZXJzIG92ZXIgY29ubmVjdGlvbnMgc2VjdXJlZAordXNpbmcgU1NMIG9yIFRMUy4gIFRvIHNpbXBsaWZ5IHN1Y2ggYWNjZXNzLCB0aGVyZSBhcmUgdHdvIGFsdGVybmF0aXZlCithcHByb2FjaGVzIHRvIGVuYWJsZSB1c2Ugb2YgU1NMLgorCitGaXJzdCwgYW5kIHBlcmhhcHMgdGhlIHNpbXBsZXN0LCBpcyB0byBzZXQgYSBwcm9wZXJ0eSB0byBlbmFibGUgdXNlCitvZiBTU0wuICBGb3IgZXhhbXBsZSwgdG8gZW5hYmxlIHVzZSBvZiBTU0wgZm9yIFNNVFAgY29ubmVjdGlvbnMsIHNldAordGhlIHByb3BlcnR5ICJtYWlsLnNtdHAuc3NsLmVuYWJsZSIgdG8gInRydWUiLgorCitBbHRlcm5hdGl2ZWx5LCB5b3UgY2FuIGNvbmZpZ3VyZSBKYXZhTWFpbCB0byB1c2Ugb25lIG9mIHRoZSBTU0wtZW5hYmxlZAorcHJvdG9jb2wgbmFtZXMuICBJbiBhZGRpdGlvbiB0byB0aGUgbm9uLVNTTCBKYXZhTWFpbCBwcm90b2NvbHMgImltYXAiLAorInBvcDMiLCBhbmQgInNtdHAiLCB0aGUgcHJvdG9jb2xzICJpbWFwcyIsICJwb3AzcyIsIGFuZCAic210cHMiIGNhbgorYmUgdXNlZCB0byBjb25uZWN0IHRvIHRoZSBjb3JyZXNwb25kaW5nIHNlcnZpY2VzIHVzaW5nIGFuIFNTTAorY29ubmVjdGlvbi4KKworSW4gYWRkaXRpb24sIHRoZSAiaW1hcCIgYW5kICJzbXRwIiBwcm90b2NvbHMgc3VwcG9ydCB1c2Ugb2YgdGhlCitTVEFSVFRMUyBjb21tYW5kIChzZWUgUkZDIDI0ODcgYW5kIFJGQyAzNTAxKSB0byBzd2l0Y2ggdGhlIGNvbm5lY3Rpb24KK3RvIGJlIHNlY3VyZWQgYnkgVExTLgorCitVc2Ugb2YgdGhlIFNUQVJUVExTIGNvbW1hbmQgaXMgcHJlZmVycmVkIGluIGNhc2VzIHdoZXJlIHRoZSBzZXJ2ZXIKK3N1cHBvcnRzIGJvdGggU1NMIGFuZCBub24tU1NMIGNvbm5lY3Rpb25zLgorCitUaGlzIFNTTC9UTFMgc3VwcG9ydCBpbiBKYXZhTWFpbCB3b3JrcyBvbmx5IHdoZW4gSmF2YU1haWwgaXMgdXNlZCBvbgorYSB2ZXJzaW9uIG9mIEoyU0UgdGhhdCBpbmNsdWRlcyBTU0wgc3VwcG9ydC4gIFdlIGhhdmUgdGVzdGVkIHRoaXMKK3N1cHBvcnQgb24gSjJTRSAxLjQgYW5kIG5ld2VyLCB3aGljaCBpbmNsdWRlIFNTTCBzdXBwb3J0LiAgVGhlCitTU0wgc3VwcG9ydCBpcyBwcm92aWRlZCBieSB0aGUgSlNTRSBwYWNrYWdlLCB3aGljaCBpcyBhbHNvIGF2YWlsYWJsZQorZm9yIGVhcmxpZXIgdmVyc2lvbnMgb2YgSjJTRS4gIFdlIGhhdmUgbm90IHRlc3RlZCBzdWNoIGNvbmZpZ3VyYXRpb25zLgorCistLSBTVEFSVFRMUyBzdXBwb3J0CisKK1RoZSBTVEFSVFRMUyBzdXBwb3J0IGlzIGF2YWlsYWJsZSBpbiB0aGUgc3RhbmRhcmQgImltYXAiIGFuZCAic210cCIKK3Byb3RvY29scywgYnV0IG11c3QgYmUgZW5hYmxlZCBieSBzZXR0aW5nIHRoZSBhcHByb3ByaWF0ZSBwcm9wZXJ0eSwKK21haWwuaW1hcC5zdGFydHRscy5lbmFibGUgb3IgbWFpbC5zbXRwLnN0YXJ0dGxzLmVuYWJsZSwgdG8gInRydWUiLgorV2hlbiBzZXQsIGlmIHRoZSBzZXJ2ZXIgc3VwcG9ydHMgdGhlIFNUQVJUVExTIGNvbW1hbmQsIGl0IHdpbGwgYmUKK3VzZWQgYWZ0ZXIgbWFraW5nIHRoZSBjb25uZWN0aW9uIGFuZCBiZWZvcmUgc2VuZGluZyBhbnkgbG9naW4KK2luZm9ybWF0aW9uLgorCisKKy0tIFNlY3VyZSBwcm90b2NvbHMKKworV2hlbiB1c2luZyB0aGUgbmV3IHByb3RvY29sIG5hbWVzLCBjb25maWd1cmF0aW9uIHByb3BlcnRpZXMgbXVzdCBhbHNvIHVzZQordGhlc2UgcHJvdG9jb2wgbmFtZXMuICBGb3IgaW5zdGFuY2UsIHNldCB0aGUgcHJvcGVydHkgIm1haWwuc210cHMuaG9zdCIKK3RvIHNwZWNpZnkgdGhlIGhvc3QgbmFtZSBvZiB0aGUgbWFjaGluZSB0byBjb25uZWN0IHRvIHdoZW4gdXNpbmcgdGhlCisic210cHMiIHByb3RvY29sIGZvciBTTVRQIG92ZXIgU1NMLiAgU2ltaWxhcmx5LCB0byBzZXQgdGhlIElNQVAgcHJvdG9jb2wKK3RpbWVvdXQgd2hlbiB1c2luZyB0aGUgImltYXBzIiBwcm90b2NvbCBmb3IgSU1BUCBvdmVyIFNTTCwgc2V0IHRoZSBwcm9wZXJ0eQorIm1haWwuaW1hcHMudGltZW91dCIuICBTZWUgdGhlIHBhY2thZ2UgZG9jdW1lbnRhdGlvbiBmb3IgdGhlIGRpZmZlcmVudAorcHJvdG9jb2wgcGFja2FnZXMgZm9yIHRoZSBsaXN0IG9mIGF2YWlsYWJsZSBwcm9wZXJ0aWVzLCB3aGljaCBhcmUKK2Fsd2F5cyBzZXQgdXNpbmcgcHJvcGVydHkgbmFtZXMgb2YgdGhlIGZvcm0gbWFpbC48cHJvdG9jb2w+Ljxwcm9wZXJ0eT4uCisKK1RoZSBUcmFuc3BvcnQuc2VuZCBtZXRob2Qgd2lsbCB1c2UgdGhlIGRlZmF1bHQgdHJhbnNwb3J0IHByb3RvY29sLAord2hpY2ggcmVtYWlucyAic210cCIuICBUbyBlbmFibGUgU01UUCBjb25uZWN0aW9ucyBvdmVyIFNTTCwgc2V0IHRoZQorIm1haWwuc210cC5zc2wuZW5hYmxlIiBwcm9wZXJ0eSB0byAidHJ1ZSIuICBUaGlzIGlzIHVzdWFsbHkgdGhlIGVhc2llc3QKK2FwcHJvYWNoLgorCitBbHRlcm5hdGl2ZWx5LCB0byBjaGFuZ2UgdGhlIGRlZmF1bHQgdHJhbnNwb3J0IHByb3RvY29sIAorcmV0dXJuZWQgYnkgdGhlIFNlc3Npb24uZ2V0VHJhbnNwb3J0KCkgbWV0aG9kIHRvIFNNVFAgb3ZlciBTU0wsIHNldAordGhlIHByb3BlcnR5ICJtYWlsLnRyYW5zcG9ydC5wcm90b2NvbCIgdG8gInNtdHBzIi4gIFRvIGNoYW5nZSB0aGUKK3RyYW5zcG9ydCB1c2VkIGZvciBpbnRlcm5ldCBhZGRyZXNzZXMgKGFzIHJldHVybmVkIGJ5IHRoZQorU2Vzc2lvbi5nZXRUcmFuc3BvcnQoQWRkcmVzcykgbWV0aG9kLCBhbmQgdXNlZCBieSB0aGUgVHJhbnNwb3J0LnNlbmQKK21ldGhvZCksIHVzZQorCisJc2Vzc2lvbi5zZXRQcm90b2NvbEZvckFkZHJlc3MoInJmYzgyMiIsICJzbXRwcyIpOworCisKKy0tIFRydXN0ZWQgQ2VydGlmaWNhdGVzCisKK1RvIGVzdGFibGlzaCBhbiBTU0wvVExTIGNvbm5lY3Rpb24sIHRoZSBKYXZhTWFpbCBjbGllbnQgbXVzdCBiZSBhYmxlCit0byB2ZXJpZnkgdGhhdCB0aGUgc2VjdXJpdHkgY2VydGlmaWNhdGUgcHJlc2VudGVkIGJ5IHRoZSBzZXJ2ZXIKK2l0IGlzIGNvbm5lY3RpbmcgdG8gaXMgInRydXN0ZWQiIGJ5IHRoZSBjbGllbnQuICBUcnVzdGVkIGNlcnRpZmljYXRlcworYXJlIG1haW50YWluZWQgaW4gYSBKYXZhIGtleXN0b3JlIGZpbGUgb24gdGhlIGNsaWVudC4gIFRoZSBKMlNFCitTREsgImtleXRvb2wiIGNvbW1hbmQgaXMgdXNlZCB0byBtYWludGFpbiB0aGUga2V5c3RvcmUgZmlsZS4KKworVGhlcmUgYXJlIHR3byBjb21tb24gYXBwcm9hY2hlcyBmb3IgdmVyaWZ5aW5nIHNlcnZlciBjZXJ0aWZpY2F0ZXMuCitUaGUgZmlyc3QgYXBwcm9hY2ggaXMgcHJvYmFibHkgbW9zdCBjb21tb24gZm9yIHNlcnZlcnMgYWNjZXNzaWJsZSB0bworcGFydG5lcnMgb3V0c2lkZSBhIGNvbXBhbnkuICBUaGUgc2Vjb25kIGFwcHJvYWNoIGlzIHByb2JhYmx5IG1vc3QKK2NvbW1vbiBmb3Igc2VydmVycyB1c2VkIHdpdGhpbiBhIGNvbXBhbnkuCisKKzEuIFNlcnZlciBjZXJ0aWZpY2F0ZXMgbWF5IGJlIHNpZ25lZCBiZSBhIHdlbGwga25vd24gcHVibGljCisgICBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkuICBUaGUgZGVmYXVsdCBKYXZhIGtleXN0b3JlIGZpbGUgY29udGFpbnMKKyAgIHRoZSBwdWJsaWMga2V5cyBvZiB3ZWxsIGtub3duIENlcnRpZmljYXRlIEF1dGhvcml0aWVzIGFuZCBjYW4KKyAgIHZlcmlmeSB0aGUgc2VydmVyJ3MgY2VydGlmaWNhdGUgYnkgZm9sbG93aW5nIHRoZSBjaGFpbiBvZgorICAgY2VydGlmaWNhdGVzIHNpZ25pbmcgdGhlIHNlcnZlcidzIGNlcnRpZmljYXRlIGJhY2sgdG8gb25lIG9mCisgICB0aGVzZSB3ZWxsIGtub3duIENBIGNlcnRpZmljYXRlcy4KKworICAgSW4gdGhpcyBjYXNlIHRoZSBjbGllbnQgZG9lc24ndCBuZWVkIHRvIG1hbmFnZSBjZXJ0aWZpY2F0ZXMKKyAgIGV4cGxpY2l0bHkgYnV0IGNhbiBqdXN0IHVzZSB0aGUgZGVmYXVsdCBrZXlzdG9yZSBmaWxlLgorCisyLiBTZXJ2ZXIgY2VydGlmaWNhdGVzIG1heSBiZSAic2VsZi1zaWduZWQiLiAgSW4gdGhpcyBjYXNlIHRoZXJlIGlzCisgICBubyBjaGFpbiBvZiBzaWduYXR1cmVzIHRvIHVzZSBpbiB2ZXJpZnlpbmcgdGhlIHNlcnZlcidzIGNlcnRpZmljYXRlLgorICAgSW5zdGVhZCwgdGhlIGNsaWVudCB3aWxsIG5lZWQgdGhlIHNlcnZlcidzIGNlcnRpZmljYXRlIGluIHRoZQorICAgY2xpZW50J3Mga2V5c3RvcmUgZmlsZS4gIFRoZSBzZXJ2ZXIncyBjZXJ0aWZpY2F0ZSBpcyBpbXBvcnRlZCBpbnRvCisgICB0aGUga2V5c3RvcmUgZmlsZSBvbmNlLCB1c2luZyB0aGUga2V5dG9vbCBjb21tYW5kLCBhbmQgYWZ0ZXIgdGhhdAorICAgaXMgdXNlZCB0byB2ZXJpZnkgY29ubmVjdGlvbnMgdG8gdGhlIHNlcnZlci4gIEEgc2luZ2xlIGtleXN0b3JlIGZpbGUKKyAgIG1heSBjb250YWluIGNlcnRpZmljYXRlcyBvZiBtYW55IHNlcnZlcnMuCisKKyAgIEluIHRoaXMgY2FzZSB0aGUgY2xpZW50IHdpbGwgbmVlZCB0byBzZXQgdGhlIGFwcHJvcHJpYXRlIFN5c3RlbQorICAgcHJvcGVydGllcyB0byBwb2ludCB0byB0aGUgY2xpZW50J3Mga2V5c3RvcmUgZmlsZSBjb250YWluaW5nIHRoZQorICAgdHJ1c3RlZCBjZXJ0aWZpY2F0ZS4gIFRoZXNlIHByb3BlcnRpZXMgY2FuIGJlIHNldCB3aGVuIGludm9raW5nCisgICB0aGUgImphdmEiIGNvbW1hbmQsIG9yIGNhbiBiZSBzZXQgcHJvZ3JhbW1hdGljYWxseS4gIEZvciBleGFtcGxlLAorCisJamF2YSAtRGphdmF4Lm5ldC5zc2wudHJ1c3RTdG9yZT0kSE9NRS8ua2V5c3RvcmUgLi4uCisKKyAgIFNlZSB0aGUgSlNTRSBSZWZlcmVuY2UgR3VpZGUgZm9yIGRldGFpbHM6CisgICBodHRwOi8vZG93bmxvYWQub3JhY2xlLmNvbS9qYXZhc2UvNi9kb2NzL3RlY2hub3Rlcy9ndWlkZXMvc2VjdXJpdHkvanNzZS9KU1NFUmVmR3VpZGUuaHRtbCNDdXN0b21pemluZ1N0b3JlcworCisKKy0tIFNlcnZlciBJZGVudGl0eSBDaGVjaworCitSRkMgMjU5NSBzcGVjaWZpZXMgYWRkaXRpb24gY2hlY2tzIHRoYXQgbXVzdCBiZSBwZXJmb3JtZWQgb24gdGhlCitzZXJ2ZXIncyBjZXJ0aWZpY2F0ZSB0byBlbnN1cmUgdGhhdCB0aGUgc2VydmVyIHlvdSBjb25uZWN0ZWQgdG8gaXMKK3RoZSBzZXJ2ZXIgeW91IGludGVuZGVkIHRvIGNvbm5lY3QgdG8uICBUaGlzIHJlZHVjZXMgdGhlIHJpc2sgb2YKKyJtYW4gaW4gdGhlIG1pZGRsZSIgYXR0YWNrcy4gIEZvciBjb21wYXRpYmlsaXR5IHdpdGggZWFybGllciByZWxlYXNlcworb2YgSmF2YU1haWwsIHRoZXNlIGFkZGl0aW9uYWwgY2hlY2tzIGFyZSBkaXNhYmxlZCBieSBkZWZhdWx0LiAgV2UKK3N0cm9uZ2x5IHJlY29tbWVuZCB0aGF0IHlvdSBlbmFibGUgdGhlc2UgY2hlY2tzIHdoZW4gdXNpbmcgU1NMLiAgVG8KK2VuYWJsZSB0aGVzZSBjaGVja3MsIHNldCB0aGUgIm1haWwuPHByb3RvY29sPi5zc2wuY2hlY2tzZXJ2ZXJpZGVudGl0eSIKK3Byb3BlcnR5IHRvICJ0cnVlIi4KKworCistLSBTb2NrZXQgRmFjdG9yaWVzCisKK0luIGVhcmxpZXIgcmVsZWFzZXMgaXQgd2FzIG5lY2Vzc2FyeSB0byBleHBsaWNpdGx5IHNldCBhIHNvY2tldAorZmFjdG9yeSBwcm9wZXJ0eSB0byBlbmFibGUgdXNlIG9mIFNTTC4gIEluIGFsbW9zdCBhbGwgY2FzZXMsIHRoaXMKK2lzIG5vIGxvbmdlciBuZWNlc3NhcnkuICBTU0wgc3VwcG9ydCBpcyBidWlsdCBpbi4gIEhvd2V2ZXIsIHRoZXJlCitpcyBvbmUgY2FzZSB3aGVyZSBhIHNwZWNpYWwgc29ja2V0IGZhY3RvcnkgbWF5IGJlIG5lZWRlZC4KKworSmF2YU1haWwgbm93IGluY2x1ZGVzIGEgc3BlY2lhbCBTU0wgc29ja2V0IGZhY3RvcnkgdGhhdCBjYW4gc2ltcGxpZnkKK2RlYWxpbmcgd2l0aCBzZXJ2ZXJzIHdpdGggc2VsZi1zaWduZWQgY2VydGlmaWNhdGVzLiAgV2hpbGUgdGhlCityZWNvbW1lbmRlZCBhcHByb2FjaCBpcyB0byBpbmNsdWRlIHRoZSBjZXJ0aWZpY2F0ZSBpbiB5b3VyIGtleXN0b3JlCithcyBkZXNjcmliZWQgYWJvdmUsIHRoZSBmb2xsb3dpbmcgYXBwcm9hY2ggbWF5IGJlIHNpbXBsZXIgaW4gc29tZSBjYXNlcy4KKworVGhlIGNsYXNzIGNvbS5zdW4ubWFpbC51dGlsLk1haWxTU0xTb2NrZXRGYWN0b3J5IGNhbiBiZSB1c2VkIGFzIGEKK3NpbXBsZSBzb2NrZXQgZmFjdG9yeSB0aGF0IGFsbG93cyB0cnVzdGluZyBhbGwgaG9zdHMgb3IgYSBzcGVjaWZpYyBzZXQKK29mIGhvc3RzLiAgRm9yIGV4YW1wbGU6CisKKwlNYWlsU1NMU29ja2V0RmFjdG9yeSBzZiA9IG5ldyBNYWlsU1NMU29ja2V0RmFjdG9yeSgpOworCXNmLnNldFRydXN0QWxsSG9zdHModHJ1ZSk7CisJLy8gb3IKKwkvLyBzZi5zZXRUcnVzdGVkSG9zdHMobmV3IFN0cmluZ1tdIHsgIm15LXNlcnZlciIgfSk7CisJcHJvcHMucHV0KCJtYWlsLnNtdHAuc3NsLmVuYWJsZSIsICJ0cnVlIik7CisJLy8gYWxzbyB1c2UgZm9sbG93aW5nIGZvciBhZGRpdGlvbmFsIHNhZmV0eQorCS8vcHJvcHMucHV0KCJtYWlsLnNtdHAuc3NsLmNoZWNrc2VydmVyaWRlbnRpdHkiLCAidHJ1ZSIpOworCXByb3BzLnB1dCgibWFpbC5zbXRwLnNzbC5zb2NrZXRGYWN0b3J5Iiwgc2YpOworCitVc2Ugb2YgTWFpbFNTTFNvY2tldEZhY3RvcnkgYXZvaWRzIHRoZSBuZWVkIHRvIGFkZCB0aGUgY2VydGlmaWNhdGUgdG8KK3lvdXIga2V5c3RvcmUgYXMgZGVzY3JpYmVkIGFib3ZlLCBvciBjb25maWd1cmUgeW91ciBvd24gVHJ1c3RNYW5hZ2VyCithcyBkZXNjcmliZWQgYmVsb3cuCisKKworLS0gRGVidWdnaW5nCisKK0RlYnVnZ2luZyBwcm9ibGVtcyB3aXRoIGNlcnRpZmljYXRlcyBhbmQga2V5c3RvcmVzIGNhbiBiZSBkaWZmaWN1bHQuCitUaGUgSlNTRSBSZWZlcmVuY2UgR3VpZGUgY29udGFpbnMgaW5mb3JtYXRpb24gb24gZGVidWdnaW5nIHV0aWxpdGllcwordGhhdCBjYW4gaGVscC4gIFNlZToKK2h0dHA6Ly9kb3dubG9hZC5vcmFjbGUuY29tL2phdmFzZS82L2RvY3MvdGVjaG5vdGVzL2d1aWRlcy9zZWN1cml0eS9qc3NlL0pTU0VSZWZHdWlkZS5odG1sI0RlYnVnCisKK1RoZXJlIGFyZSBzb21lIGRlYnVnZ2luZyBvcHRpb25zIGluIHRoZSBKREsgdGhhdCBjYW4gaGVscCwgZGVwZW5kaW5nCitvbiB0aGUgc29ydHMgb2YgcHJvYmxlbXMgeW91J3JlIGhhdmluZy4gIFNldHRpbmcgdGhlIGZvbGxvd2luZyBzeXN0ZW0KK3Byb3BlcnRpZXMgd2lsbCBwcm9kdWNlIGFkZGl0aW9uYWwgZGVidWdnaW5nIG91dHB1dDoKKworCWphdmEuc2VjdXJpdHkuZGVidWc9Y2VydHBhdGgKKwlqYXZheC5uZXQuZGVidWc9dHJ1c3RtYW5hZ2VyIAorCitTZXQgdGhlc2Ugb24gdGhlIGNvbW1hbmQgbGluZSB3aGVuIHlvdSBydW4geW91ciBwcm9ncmFtIHVzaW5nLCBmb3IgZXhhbXBsZToKKworCWphdmEgLURqYXZhLnNlY3VyaXR5LmRlYnVnPWNlcnRwYXRoIC1EamF2YXgubmV0LmRlYnVnPXRydXN0bWFuYWdlciAuLi4KKworCistLSBrZXl0b29sIFVzYWdlCisKK0dpdmVuIGEgY2VydGlmaWNhdGUgZm9yIHRoZSBzZXJ2ZXIgYXMgdXNlZCBpbiBjYXNlICMyIGFib3ZlLCB5b3UgY2FuCitpbXBvcnQgdGhpcyBjZXJ0aWZpY2F0ZSBpbnRvIHlvdXIgSmF2YSBrZXlzdG9yZSBmaWxlIHVzaW5nIGEgY29tbWFuZAorc3VjaCBhczoKKworCWtleXRvb2wgLWltcG9ydCAtYWxpYXMgaW1hcC1zZXJ2ZXIgLWZpbGUgaW1hcC5jZXIKKworVGhlIGtleXRvb2wgY29tbWFuZCBjYW4gYWxzbyBiZSB1c2VkIHRvIGdlbmVyYXRlIGEgc2VsZi1zaWduZWQgY2VydGlmaWNhdGUKK3RoYXQgY2FuIGJlIHVzZWQgYnkgeW91ciBtYWlsIHNlcnZlciwgaWYgeW91J3JlIHNldHRpbmcgdXAgeW91ciBvd24gc2VydmVyLgorT3RoZXIgdXRpbGl0aWVzLCBzdWNoIGFzIHRob3NlIGluY2x1ZGVkIHdpdGggdGhlIE9wZW5TU0wgcGFja2FnZSwgY2FuIGFsc28KK2JlIHVzZWQgdG8gZ2VuZXJhdGUgc3VjaCBjZXJ0aWZpY2F0ZXMsIGFuZCB0aGV5IGNhbiBiZSBpbXBvcnRlZCBpbnRvIHRoZQorSmF2YSBrZXlzdG9yZSB1c2luZyBrZXl0b29sLgorCitGb3IgbW9yZSBpbmZvcm1hdGlvbiBvbiB1c2luZyB0aGUga2V5dG9vbCBjb21tYW5kLCBzZWUgdGhlIGtleXRvb2wKK3JlZmVyZW5jZSBwYWdlcyBhdDoKK2h0dHA6Ly9kb3dubG9hZC5vcmFjbGUuY29tL2phdmFzZS82L2RvY3MvdGVjaG5vdGVzL2d1aWRlcy9zZWN1cml0eS9pbmRleC5odG1sCisKKworLS0gQ29uZmlndXJpbmcgWW91ciBPd24gVHJ1c3QgTWFuYWdlcgorCitXaGVuIHVzaW5nIFNTTC9UTFMsIGl0J3MgaW1wb3J0YW50IHRvIGVuc3VyZSB0aGF0IHRoZSBzZXJ2ZXIgeW91IGNvbm5lY3QKK3RvIGlzIGFjdHVhbGx5IHRoZSBzZXJ2ZXIgeW91IGV4cGVjdGVkIHRvIGNvbm5lY3QgdG8sIHRvIHByZXZlbnQgIm1hbiBpbgordGhlIG1pZGRsZSIgYXR0YWNrcyBvbiB5b3VyIGNvbW11bmljYXRpb24uICBUaGUgcmVjb21tZW5kZWQgdGVjaG5pcXVlIGlzCit0byBjb25maWd1cmUgdGhlIEphdmEga2V5c3RvcmUgdXNpbmcgb25lIG9mIHRoZSBtZXRob2RzIGRlc2NyaWJlZCBhYm92ZS4KK0lmLCBmb3Igc29tZSByZWFzb24sIHRoYXQgYXBwcm9hY2ggaXMgbm90IHdvcmthYmxlLCBpdCdzIGFsc28gcG9zc2libGUKK3RvIGNvbmZpZ3VyZSB0aGUgU1NML1RMUyBpbXBsZW1lbnRhdGlvbiB0byB1c2UgeW91ciBvd24gVHJ1c3RNYW5hZ2VyCitjbGFzcyB0byBldmFsdWF0ZSB3aGV0aGVyIHRvIHRydXN0IHRoZSBzZXJ2ZXIgeW91J3ZlIGNvbm5lY3RlZCB0by4KKworVGhlIGZvbGxvd2luZyAiZHVtbXkiIGNsYXNzZXMgaWxsdXN0cmF0ZSB0aGUgZnJhbWV3b3JrIG5lY2Vzc2FyeSB0byBjcmVhdGUKK3lvdXIgb3duIFRydXN0TWFuYWdlciBpbXBsZW1lbnRhdGlvbi4KKworRmlyc3QsIGEgcmVwbGFjZW1lbnQgZm9yIHRoZSBzdGFuZGFyZCBTU0xTb2NrZXRGYWN0b3J5IGlzIG5lZWRlZCwgdG8gYWxsb3cKK3lvdSB0byBzcGVjaWZ5IHdoaWNoIFRydXN0TWFuYWdlciB0byB1c2U6CisKKz09PiBEdW1teVNTTFNvY2tldEZhY3RvcnkuamF2YSA8PT0KKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuSW5ldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuU29ja2V0OworCitpbXBvcnQgamF2YXgubmV0LlNvY2tldEZhY3Rvcnk7CitpbXBvcnQgamF2YXgubmV0LnNzbC4qOworCisKKy8qKgorICogRHVtbXlTU0xTb2NrZXRGYWN0b3J5CisgKi8KK3B1YmxpYyBjbGFzcyBEdW1teVNTTFNvY2tldEZhY3RvcnkgZXh0ZW5kcyBTU0xTb2NrZXRGYWN0b3J5IHsKKyAgICBwcml2YXRlIFNTTFNvY2tldEZhY3RvcnkgZmFjdG9yeTsKKworICAgIHB1YmxpYyBEdW1teVNTTFNvY2tldEZhY3RvcnkoKSB7CisJdHJ5IHsKKwkgICAgU1NMQ29udGV4dCBzc2xjb250ZXh0ID0gU1NMQ29udGV4dC5nZXRJbnN0YW5jZSgiVExTIik7CisJICAgIHNzbGNvbnRleHQuaW5pdChudWxsLAorCQkJCSBuZXcgVHJ1c3RNYW5hZ2VyW10geyBuZXcgRHVtbXlUcnVzdE1hbmFnZXIoKX0sCisJCQkJIG51bGwpOworCSAgICBmYWN0b3J5ID0gKFNTTFNvY2tldEZhY3Rvcnkpc3NsY29udGV4dC5nZXRTb2NrZXRGYWN0b3J5KCk7CisJfSBjYXRjaChFeGNlcHRpb24gZXgpIHsKKwkgICAgLy8gaWdub3JlCisJfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU29ja2V0RmFjdG9yeSBnZXREZWZhdWx0KCkgeworCXJldHVybiBuZXcgRHVtbXlTU0xTb2NrZXRGYWN0b3J5KCk7CisgICAgfQorCisgICAgcHVibGljIFNvY2tldCBjcmVhdGVTb2NrZXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCXJldHVybiBmYWN0b3J5LmNyZWF0ZVNvY2tldCgpOworICAgIH0KKworICAgIHB1YmxpYyBTb2NrZXQgY3JlYXRlU29ja2V0KFNvY2tldCBzb2NrZXQsIFN0cmluZyBzLCBpbnQgaSwgYm9vbGVhbiBmbGFnKQorCQkJCXRocm93cyBJT0V4Y2VwdGlvbiB7CisJcmV0dXJuIGZhY3RvcnkuY3JlYXRlU29ja2V0KHNvY2tldCwgcywgaSwgZmxhZyk7CisgICAgfQorCisgICAgcHVibGljIFNvY2tldCBjcmVhdGVTb2NrZXQoSW5ldEFkZHJlc3MgaW5hZGRyLCBpbnQgaSwKKwkJCQlJbmV0QWRkcmVzcyBpbmFkZHIxLCBpbnQgaikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlyZXR1cm4gZmFjdG9yeS5jcmVhdGVTb2NrZXQoaW5hZGRyLCBpLCBpbmFkZHIxLCBqKTsKKyAgICB9CisKKyAgICBwdWJsaWMgU29ja2V0IGNyZWF0ZVNvY2tldChJbmV0QWRkcmVzcyBpbmFkZHIsIGludCBpKQorCQkJCXRocm93cyBJT0V4Y2VwdGlvbiB7CisJcmV0dXJuIGZhY3RvcnkuY3JlYXRlU29ja2V0KGluYWRkciwgaSk7CisgICAgfQorCisgICAgcHVibGljIFNvY2tldCBjcmVhdGVTb2NrZXQoU3RyaW5nIHMsIGludCBpLCBJbmV0QWRkcmVzcyBpbmFkZHIsIGludCBqKQorCQkJCXRocm93cyBJT0V4Y2VwdGlvbiB7CisJcmV0dXJuIGZhY3RvcnkuY3JlYXRlU29ja2V0KHMsIGksIGluYWRkciwgaik7CisgICAgfQorCisgICAgcHVibGljIFNvY2tldCBjcmVhdGVTb2NrZXQoU3RyaW5nIHMsIGludCBpKSB0aHJvd3MgSU9FeGNlcHRpb24geworCXJldHVybiBmYWN0b3J5LmNyZWF0ZVNvY2tldChzLCBpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nW10gZ2V0RGVmYXVsdENpcGhlclN1aXRlcygpIHsKKwlyZXR1cm4gZmFjdG9yeS5nZXREZWZhdWx0Q2lwaGVyU3VpdGVzKCk7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZ1tdIGdldFN1cHBvcnRlZENpcGhlclN1aXRlcygpIHsKKwlyZXR1cm4gZmFjdG9yeS5nZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoKTsKKyAgICB9Cit9CisKKworTmV4dCB5b3UgbmVlZCB0aGUgYWN0dWFsIGltcGxlbWVudGF0aW9uIG9mIHRoZSBUcnVzdE1hbmFnZXIuICBUaGlzIGR1bW15Cit0cnVzdCBtYW5hZ2VyIHRydXN0cyBhbnl0aGluZy4gIFRISVMgSVMgTk9UIFNFQ1VSRSEhIQorCis9PT4gRHVtbXlUcnVzdE1hbmFnZXIuamF2YSA8PT0KKworaW1wb3J0IGphdmF4Lm5ldC5zc2wuWDUwOVRydXN0TWFuYWdlcjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlOworCisKKy8qKgorICogRHVtbXlUcnVzdE1hbmFnZXIgLSBOT1QgU0VDVVJFCisgKi8KK3B1YmxpYyBjbGFzcyBEdW1teVRydXN0TWFuYWdlciBpbXBsZW1lbnRzIFg1MDlUcnVzdE1hbmFnZXIgeworCisgICAgcHVibGljIHZvaWQgY2hlY2tDbGllbnRUcnVzdGVkKFg1MDlDZXJ0aWZpY2F0ZVtdIGNlcnQsIFN0cmluZyBhdXRoVHlwZSkgeworCS8vIGV2ZXJ5dGhpbmcgaXMgdHJ1c3RlZAorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGNoZWNrU2VydmVyVHJ1c3RlZChYNTA5Q2VydGlmaWNhdGVbXSBjZXJ0LCBTdHJpbmcgYXV0aFR5cGUpIHsKKwkvLyBldmVyeXRoaW5nIGlzIHRydXN0ZWQKKyAgICB9CisKKyAgICBwdWJsaWMgWDUwOUNlcnRpZmljYXRlW10gZ2V0QWNjZXB0ZWRJc3N1ZXJzKCkgeworCXJldHVybiBuZXcgWDUwOUNlcnRpZmljYXRlWzBdOworICAgIH0KK30KKworRmluYWxseSwgeW91IG5lZWQgdG8gY29uZmlndXJlIEphdmFNYWlsIHRvIHVzZSB5b3VyIFNTTFNvY2tldEZhY3RvcnkuCitTZXQgdGhlIGFwcHJvcHJpYXRlIHByb3RvY29sLXNwZWNpZmljIHByb3BlcnR5LCBlLmcuLAorCisgICAgcHJvcHMuc2V0UHJvcGVydHkoIm1haWwuaW1hcC5zc2wuZW5hYmxlIiwgInRydWUiKTsKKyAgICBwcm9wcy5zZXRQcm9wZXJ0eSgibWFpbC5pbWFwLnNzbC5zb2NrZXRGYWN0b3J5LmNsYXNzIiwKKwkJCQkJIkR1bW15U1NMU29ja2V0RmFjdG9yeSIpOworICAgIHByb3BzLnNldFByb3BlcnR5KCJtYWlsLmltYXAuc3NsLnNvY2tldEZhY3RvcnkuZmFsbGJhY2siLCAiZmFsc2UiKTsKKyAgICBTZXNzaW9uIHNlc3Npb24gPSBTZXNzaW9uLmdldEluc3RhbmNlKHByb3BzLCBudWxsKTsKKworU2ltaWxhciBwcm9wZXJ0aWVzIHdvdWxkIG5lZWQgdG8gYmUgc2V0IHRvIHVzZSBvdGhlciBwcm90b2NvbHMuCmRpZmYgLS1naXQgYS9kb2MvcmVsZWFzZS9Ub21jYXQuaHRtbCBiL2RvYy9yZWxlYXNlL1RvbWNhdC5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgwNzc4NzUKLS0tIC9kZXYvbnVsbAorKysgYi9kb2MvcmVsZWFzZS9Ub21jYXQuaHRtbApAQCAtMCwwICsxLDQzIEBACis8IWRvY3R5cGUgaHRtbCBwdWJsaWMgIi0vL3czYy8vZHRkIGh0bWwgNC4wIHRyYW5zaXRpb25hbC8vZW4iPgorPGh0bWw+Cis8aGVhZD4KKzwhLS0KKworICAgIENvcHlyaWdodCAoYykgMjAxMCwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorCisgICAgVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgICAgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisKKyAgICBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgICAgTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICAgIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICAgIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorCisgICAgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisKKy0tPgorCisgICA8bWV0YSBodHRwLWVxdWl2PSJDb250ZW50LVR5cGUiIGNvbnRlbnQ9InRleHQvaHRtbDsgY2hhcnNldD1pc28tODg1OS0xIj4KKyAgIDxtZXRhIG5hbWU9IkF1dGhvciIgY29udGVudD0iSmF2YVNvZnR3YXJlIj4KKyAgIDx0aXRsZT5Ub21jYXQ8L3RpdGxlPgorPC9oZWFkPgorPGJvZHk+CitUb21jYXQgaXMgYSBjb21wbGV0ZSB3ZWIgc2VydmVyIHdyaXR0ZW4gaW4gSmF2YSB0aGF0IHByb3ZpZGVzCitzdXBwb3J0IGZvciB0aGUgU2VydmxldCBhbmQgSlNQIHNwZWNpZmljYXRpb25zLgorVG9tY2F0IGlzIGRldmVsb3BlZCBhcyBhIHBhcnQgb2YgdGhlIEFwYWNoZQorPGEgaHJlZj0iaHR0cDovL2pha2FydGEuYXBhY2hlLm9yZyI+SmFrYXJ0YSBQcm9qZWN0PC9hPi4KK0JvdGggYmluYXJpZXMgYW5kIHNvdXJjZSBhcmUgYXZhaWxhYmxlIGZyb20gdGhlIEpha2FydGEgd2ViIHNpdGUuCis8cD4KK1RvIHJ1biB0aGUgSmF2YU1haWxTZXJ2bGV0LCB5b3UgbXVzdCBhZGQgdGhlIEphdmFNYWlsIGFuZCBKYXZhQmVhbnMKK0FjdGl2YXRpb24gRnJhbWV3b3JrIGphciBmaWxlcyB0byB0aGUgPGNvZGU+bGliPC9jb2RlPiBkaXJlY3RvcnkKK3VuZGVyIHRoZSBkaXJlY3RvcnkgaW4gd2hpY2ggeW91IGluc3RhbGxlZCBUb21jYXQuICBUaGlzIHdpbGwKK2NhdXNlIFRvbWNhdCB0byBpbmNsdWRlIHRoZXNlIGphciBmaWxlcyBpbiBpdHMgY2xhc3NwYXRoIGF1dG9tYXRpY2FsbHkuCisoU29tZSBwYWNrYWdlcyBvZiBUb21jYXQgdmVyc2lvbiA0IGluY2x1ZGUgSmF2YU1haWwgc3VwcG9ydC4pCitEZXBlbmRpbmcgb24gdGhlIHZlcnNpb24gb2YgVG9tY2F0IHVzZWQsIHRoZSA8Y29kZT5tYWlsLmphcjwvY29kZT4KK2FuZCA8Y29kZT5hY3RpdmF0aW9uLmphcjwvY29kZT4gZmlsZXMgc2hvdWxkIGJlIGNvcGllZCB0byB0aGUKKzxjb2RlPmxpYjwvY29kZT4gZGlyZWN0b3J5IG9yIHRvIGFuIGFwcHJvcHJpYXRlIHN1YmRpcmVjdG9yeSBvZiB0aGUKKzxjb2RlPmxpYjwvY29kZT4gZGlyZWN0b3J5LgorPC9ib2R5PgorPC9odG1sPgpkaWZmIC0tZ2l0IGEvZG9jL3JlbGVhc2UvY2xhc3NwYXRoLU5ULmh0bWwgYi9kb2MvcmVsZWFzZS9jbGFzc3BhdGgtTlQuaHRtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMDA1N2FlCi0tLSAvZGV2L251bGwKKysrIGIvZG9jL3JlbGVhc2UvY2xhc3NwYXRoLU5ULmh0bWwKQEAgLTAsMCArMSw2NCBAQAorPCFkb2N0eXBlIGh0bWwgcHVibGljICItLy93M2MvL2R0ZCBodG1sIDQuMCB0cmFuc2l0aW9uYWwvL2VuIj4KKzxodG1sPgorPGhlYWQ+Cis8IS0tCisKKyAgICBDb3B5cmlnaHQgKGMpIDIwMTAsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKworICAgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICAgIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorCisgICAgVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICAgIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAgICBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAgICB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKworICAgIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorCistLT4KKworICAgPG1ldGEgaHR0cC1lcXVpdj0iQ29udGVudC1UeXBlIiBjb250ZW50PSJ0ZXh0L2h0bWw7IGNoYXJzZXQ9aXNvLTg4NTktMSI+CisgICA8bWV0YSBuYW1lPSJBdXRob3IiIGNvbnRlbnQ9IkphdmFTb2Z0d2FyZSI+CisgICA8bWV0YSBuYW1lPSJHRU5FUkFUT1IiIGNvbnRlbnQ9Ik1vemlsbGEvNC42MSBbZW5dIChXaW5OVDsgVSkgW05ldHNjYXBlXSI+CisgICA8dGl0bGU+TlQgQ2xhc3NwYXRoPC90aXRsZT4KKzwvaGVhZD4KKzxib2R5PgorRW52aXJvbm1lbnQgdmFyaWFibGVzIGFyZSBhZG1pbmlzdGVyZWQgb24gV2luZG93cyBOVCBmcm9tIHRoZQorPGI+U3lzdGVtCitQcm9wZXJ0aWVzPC9iPiBDb250cm9sIFBhbmVsIHNldHRpbmdzIChTdGFydC0+U2V0dGluZ3MtPkNvbnRyb2wgUGFuZWw7CitpdCdzIHRoZSA8Yj5TeXN0ZW08L2I+IGljb24gaW4gdGhlIENvbnRyb2wgUGFuZWwpLiBUaGUgPGI+RW52aXJvbm1lbnQ8L2I+Cit0YWIgY29udGFpbnMgYWxsIG9mIHRoZSBTeXN0ZW0gYW5kIFVzZXIgVmFyaWFibGVzLgorPHA+U3lzdGVtIFZhcmlhYmxlcyBleGlzdCBmb3IgYWxsIHVzZXJzIHdoaWxlIFVzZXIgVmFyaWFibGVzIG9ubHkgZXhpc3QKK2ZvciB0aGUgY3VycmVudCB1c2VyLiBPbmx5IHVzZXJzIHdpdGggQWRtaW5pc3RyYXRvciBwcml2aWxlZ2VzIGFyZSBhYmxlCit0byBkZWZpbmUgU3lzdGVtIFZhcmlhYmxlcy4gRm9yIHRoaXMgZXhhbXBsZSwgZW52aXJvbm1lbnQgdmFyaWFibGVzIHdpbGwKK2JlIGRlZmluZWQgYXMgVXNlciBWYXJpYWJsZXMuCis8cD5JZiB0aGlzIGlzIHRoZSBmaXJzdCB0aW1lIHRoZSBDTEFTU1BBVEggZW52aXJvbm1lbnQgdmFyaWFibGUgaXMgYmVpbmcKK2RlZmluZWQsIHNlbGVjdCB0aGUgZmlyc3QgVXNlciBWYXJpYWJsZXMgZW50cnkgKGl0cyBuYW1lL3ZhbHVlIHBhaXIgd2lsbAorc2hvdyB1cCBiZWxvdyB0aGUgVXNlciBWYXJpYWJsZXMgbGlzdCkuIEVudGVyICdDTEFTU1BBVEgnIGluIHRoZSAnVmFyaWFibGU6JwordGV4dCBlZGl0IGZpZWxkLgorPHA+SWYgdGhlIENMQVNTUEFUSCBlbnZpcm9ubWVudCB2YXJpYWJsZSBoYXMgYWxyZWFkeSBiZWVuIHByZXZpb3VzbHkgZGVmaW5lZCwKK3NpbXBseSBzZWxlY3QgaXQgZnJvbSB0aGUgVXNlciBWYXJpYWJsZXMgbGlzdC4KKzxwPlRoZXJlIGFyZSBhIGNvdXBsZSBvZiB3YXlzIG9mIGFkZGluZyBzb21ldGhpbmcgdG8gYW4gZW52aXJvbm1lbnQgdmFyaWFibGUuCitJdCBjYW4gYmUgYWRkZWQgZGlyZWN0bHksIG9yIHRocm91Z2ggdGhlIHVzZSBvZiBhIHNlcGFyYXRlbHkgZGVmaW5lZCBlbnZpcm9ubWVudAordmFyaWFibGUuCis8cD5XaGVuIHRoZSBKYXZhTWFpbCBhbmQgSmF2YSBBY3RpdmF0aW9uIEZyYW1ld29yayAoSkFGKSBqYXIgZmlsZXMgYXJlCithZGRlZCBkaXJlY3RseSB0byB0aGUgQ0xBU1NQQVRILCB0aGUgVmFsdWUgZmllbGQgc2hvdWxkIGNvbnRhaW4gKGZvciBleGFtcGxlKQorIi47RDpcSmF2YVxqYXZhbWFpbC0xLjJcbWFpbC5qYXI7RDpcSmF2YVxqYWYtMS4wLjFcYWN0aXZhdGlvbi5qYXIiLgorPHA+PGltZyBTUkM9ImltYWdlcy9kaXJlY3QtY2xhc3NwYXRoLmpwZyIgaGVpZ2h0PTQ2NiB3aWR0aD00MTA+Cis8YnI+Jm5ic3A7Cis8cD5XaGVuIHRoZSBKYXZhTWFpbCBhbmQgSmF2YSBBY3RpdmF0aW9uIEZyYW1ld29yayAoSkFGKSBqYXIgZmlsZXMgYXJlCithZGRlZCB0byB0aGUgQ0xBU1NQQVRIIHVzaW5nIHNlcGFyYXRlIGVudmlyb25tZW50IHZhcmlhYmxlcywgdGhlIFZhbHVlCitmaWVsZCBzaG91bGQgY29udGFpbiAoZm9yIGV4YW1wbGUpICIuOyVKQVZBTUFJTF9KQVIlOyVKQUZfSkFSJSIKKzxicj4mbmJzcDsKKzxwPjxpbWcgU1JDPSJpbWFnZXMvaW5kaXJlY3QtY2xhc3NwYXRoLmpwZyIgaGVpZ2h0PTQ2NiB3aWR0aD00MTA+Cis8YnI+Jm5ic3A7Cis8cD5PbmNlIHlvdSBoYXZlIGZpbmlzaGVkIHVwZGF0aW5nIHRoZSBWYWx1ZSBmaWVsZCwgeW91IG11c3QgcHJlc3MgdGhlCitTZXQgYnV0dG9uLiBUaGVuIHByZXNzIE9LLiBJdCBpcyBub3QgbmVjZXNzYXJ5IHRvIHJlYm9vdCBvciBsb2cgb3V0LCBob3dldmVyCit0aGVzZSBuZXcgc2V0dGluZ3Mgd2lsbCBvbmx5IGJlIHByZXNlbnQgaW4gbmV3IENvbW1hbmQgUHJvbXB0IHdpbmRvd3MuCitBbnkgZXhpc3Rpbmcgd2luZG93cyBtdXN0IGJlIGNsb3NlZCBhbmQgcmVvcGVuZWQgZm9yIHRoZSBuZXcgc2V0dGluZ3MgdG8KK3Rha2UgZWZmZWN0LiBBbnkgcnVubmluZyBKYXZhIGFwcGxpY2F0aW9ucyB3aGljaCBpbmhlcml0IHRoZSBzeXN0ZW0gQ0xBU1NQQVRICithbHNvIG5lZWQgdG8gYmUgcmVzdGFydGVkLgorPC9ib2R5PgorPC9odG1sPgpkaWZmIC0tZ2l0IGEvZG9jL3JlbGVhc2UvaVBsYW5ldC5odG1sIGIvZG9jL3JlbGVhc2UvaVBsYW5ldC5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM0MjA4NjMKLS0tIC9kZXYvbnVsbAorKysgYi9kb2MvcmVsZWFzZS9pUGxhbmV0Lmh0bWwKQEAgLTAsMCArMSw1MCBAQAorPCFkb2N0eXBlIGh0bWwgcHVibGljICItLy93M2MvL2R0ZCBodG1sIDQuMCB0cmFuc2l0aW9uYWwvL2VuIj4KKzxodG1sPgorPGhlYWQ+Cis8IS0tCisKKyAgICBDb3B5cmlnaHQgKGMpIDIwMTAsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKworICAgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICAgIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorCisgICAgVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICAgIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAgICBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAgICB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKworICAgIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorCistLT4KKworICAgPG1ldGEgaHR0cC1lcXVpdj0iQ29udGVudC1UeXBlIiBjb250ZW50PSJ0ZXh0L2h0bWw7IGNoYXJzZXQ9aXNvLTg4NTktMSI+CisgICA8bWV0YSBuYW1lPSJBdXRob3IiIGNvbnRlbnQ9IkphdmFTb2Z0d2FyZSI+CisgICA8bWV0YSBuYW1lPSJHRU5FUkFUT1IiIGNvbnRlbnQ9Ik1vemlsbGEvNC42MSBbZW5dIChXaW5OVDsgVSkgW05ldHNjYXBlXSI+CisgICA8dGl0bGU+aVBsYW50ZXQ8L3RpdGxlPgorPC9oZWFkPgorPGJvZHk+CitJZiB5b3UgZG9uJ3QgYWxyZWFkeSBoYXZlIGlQbGFuZXQgV2ViIFNlcnZlciBpbnN0YWxsZWQgYW5kIHJ1bm5pbmcsCit5b3UnbGwgbmVlZCB0byBkb3dubG9hZCBpdAorPGJyPmZyb20gdGhlIDxhIGhyZWY9Imh0dHA6Ly93d3cuaXBsYW5ldC5jb20vcHJvZHVjdHMvaW5mcmFzdHJ1Y3R1cmUvd2ViX3NlcnZlcnMvaXdzL2luZGV4Lmh0bWwiPmlQbGFuZXQKK1dlYiBTZXJ2ZXI8L2E+Jm5ic3A7IHByb2R1Y3QgcGFnZSBhbmQgaW5zdGFsbCBpdC4gV2UgdGVzdGVkIHRoZSBKYXZhTWFpbFNlcnZsZXQKK3dpdGgKKzxicj50aGVzZSBjb25maWd1cmF0aW9ucy4KKzxwPihvbiBTb2xhcmlzKQorPGJsb2NrcXVvdGU+Jm5ic3A7aVBsYW5ldCBXZWIgU2VydmVyIDQuMSAoYmluYXJ5KTwvYmxvY2txdW90ZT4KKyhvbiBOVCkKKzxibG9ja3F1b3RlPiZuYnNwO2lQbGFuZXQgV2ViIFNlcnZlciA0LjEgKGJpbmFyeSk8L2Jsb2NrcXVvdGU+CitUbyBydW4gdGhlIEphdmFNYWlsU2VydmxldCwgeW91IG11c3QgYWRkIHRoZSBKYXZhTWFpbCBhbmQgSmF2YUJlYW5zIEFjdGl2YXRpb24KK0ZyYW1ld29yaworPGJyPmphciBmaWxlcyB0byB0aGUgQ0xBU1NQQVRIIGVudmlyb25tZW50IHZhcmlhYmxlICh0aGlzIGlzIGRvY3VtZW50ZWQKK2luIHRoZSBKYXZhTWFpbCBSRUFETUUgZmlsZQorPGJyPmFuZCBhZGRpdGlvbmFsIFdpbmRvd3MgTlQgaW5mb3JtYXRpb24gaXMgcHJvdmlkZWQgPGEgaHJlZj0iY2xhc3NwYXRoLU5ULmh0bWwiPmhlcmU8L2E+KS4KKzxwPk9uY2UgdGhpcyBpcyBkb25lLCByZXN0YXJ0IHRoZSB3ZWIgc2VydmVyLgorPGJyPiZuYnNwOworPHA+QWRkaXRpb25hbCBOb3RlcworPGJsb2NrcXVvdGU+aVBsYW5ldCBXZWIgU2VydmVyIDQuMSBkb2VzIG5vdCB1c2UgYSBTZWN1cml0eU1hbmFnZXIgb3IgZW5mb3JjZQorYW55IEphdmEgc2VjdXJpdHkgcG9saWN5LjwvYmxvY2txdW90ZT4KKworPC9ib2R5PgorPC9odG1sPgpkaWZmIC0tZ2l0IGEvZG9jL3JlbGVhc2UvaW1hZ2VzL2RpcmVjdC1jbGFzc3BhdGguanBnIGIvZG9jL3JlbGVhc2UvaW1hZ2VzL2RpcmVjdC1jbGFzc3BhdGguanBnCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY3OGRmMDQKLS0tIC9kZXYvbnVsbAorKysgYi9kb2MvcmVsZWFzZS9pbWFnZXMvZGlyZWN0LWNsYXNzcGF0aC5qcGcKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvZG9jL3JlbGVhc2UvaW1hZ2VzL2luZGlyZWN0LWNsYXNzcGF0aC5qcGcgYi9kb2MvcmVsZWFzZS9pbWFnZXMvaW5kaXJlY3QtY2xhc3NwYXRoLmpwZwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ODgxM2FjCi0tLSAvZGV2L251bGwKKysrIGIvZG9jL3JlbGVhc2UvaW1hZ2VzL2luZGlyZWN0LWNsYXNzcGF0aC5qcGcKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvZG9jL3NwZWMvSmF2YU1haWwtMS4xLWNoYW5nZXMudHh0IGIvZG9jL3NwZWMvSmF2YU1haWwtMS4xLWNoYW5nZXMudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAyOGRiZWMKLS0tIC9kZXYvbnVsbAorKysgYi9kb2Mvc3BlYy9KYXZhTWFpbC0xLjEtY2hhbmdlcy50eHQKQEAgLTAsMCArMSw2NTYgQEAKKwkJCisJCUphdmFNYWlsIDEuMQorCQk9PT09PT09PT09PT0KKworRm9sbG93aW5nIGlzIGEgZGVzY3JpcHRpb24gb2YgdGhlIG5ldyBBUElzIHRoYXQgYXJlIGJlaW5nCitpbnRyb2R1Y2VkIGluIEphdmFNYWlsIDEuMQorCitQbGVhc2Ugc2VuZCBjb21tZW50cyBhbmQgZmVlZGJhY2sgdG8gamF2YW1haWxAc3VuLmNvbQorCisoMSkgTWVzc2FnZUNvbnRleHQKKz09PT09PT09PT09PT09PT09PQorCitJbiBzb21lIGNhc2VzIGl0IGlzIGRlc2lyYWJsZSBmb3IgdGhlIG9iamVjdCByZXByZXNlbnRpbmcgdGhlIGNvbnRlbnQKK29mIGEgQm9keVBhcnQgdG8ga25vdyBzb21ldGhpbmcgYWJvdXQgdGhlICJjb250ZXh0IiBpbiB3aGljaCBpdCBpcworb3BlcmF0aW5nLCBlLmcuLCB3aGF0IG90aGVyIGRhdGEgaXMgY29udGFpbmVkIGluIHRoZSBzYW1lIE11bHRpcGFydAorb2JqZWN0LCB3aG8gc2VudCB0aGUgbWVzc2FnZSBjb250YWluaW5nIHRoZSBkYXRhLCBldGMuICBUaGlzIGFsbG93cworZm9yIG1vcmUgaW50ZXJlc3RpbmcgY29udGVudCB0eXBlcyB0aGF0IGtub3cgbW9yZSBhYm91dCB0aGUgbWVzc2FnZQorY29udGFpbmluZyB0aGVtIGFuZCB0aGUgbWFpbCBzeXN0ZW0gaW4gZ2VuZXJhbC4KKworU29tZSB1c2VzIG9mIG11bHRpcGFydC9yZWxhdGVkIG1pZ2h0IHJlcXVpcmUgdGhlc2UgY2FwYWJpbGl0aWVzLgorRm9yIGluc3RhbmNlLCB0aGUgaGFuZGxlciBmb3IgYSB0ZXh0L2h0bWwgYm9keSBwYXJ0IGNvbnRhaW5lZCBpbiBhCittdWx0aXBhcnQvcmVsYXRlZCBvYmplY3QgbWlnaHQgbmVlZCB0byBrbm93IGFib3V0IHRoZSBjb250YWluaW5nCitvYmplY3QgaW4gb3JkZXIgdG8gZmluZCB0aGUgcmVsYXRlZCBpbWFnZSBkYXRhIG5lZWRlZCB0byBkaXNwbGF5IHRoZQorSFRNTCBkb2N1bWVudC4KKworVGhlcmUgaXMgb25lIHBhcnRpY3VsYXIgY2FzZSBpbiB0aGUgY3VycmVudCBpbXBsZW1lbnRhdGlvbiB3aGVyZQordGhpcyBuZWVkIGFyaXNlcy4gIChUaGlzIGlzIGEgYnVnIGluIHRoZSBjdXJyZW50IHJlbGVhc2UuKSAgV2hlbgorY29uc3RydWN0aW5nIGEgTWltZU1lc3NhZ2Ugb2JqZWN0IGZvciBhIG5lc3RlZCBtZXNzYWdlIGNvbnRhaW5lZAoraW4gYW5vdGhlciBtZXNzYWdlLCB0aGUgRGF0YUNvbnRlbnRIYW5kbGVyIG5lZWRzIHRoZSBTZXNzaW9uCitvYmplY3QgaW4gb3JkZXIgdG8gY29uc3RydWN0IHRoZSBuZXcgTWltZU1lc3NhZ2Ugb2JqZWN0LgorCitUbyBzb2x2ZSB0aGVzZSBwcm9ibGVtcyB3ZSBpbnRyb2R1Y2UgYSBuZXcgY2xhc3MsIGEgbmV3IGludGVyZmFjZSwKK2FuZCBhIG51bWJlciBvZiBuZXcgbWV0aG9kcy4KKworVGhlIE1lc3NhZ2VDb250ZXh0IGNsYXNzIHByb3ZpZGVzIHRoZSBiYXNpYyBpbmZvcm1hdGlvbiBhYm91dCB0aGUKKyJjb250ZXh0IiBpbiB3aGljaCBhIGNvbnRlbnQgb2JqZWN0IGlzIG9wZXJhdGluZzoKKworLyoqCisgKiBUaGUgY29udGV4dCBpbiB3aGljaCBhIHBpZWNlIG9mIE1lc3NhZ2UgY29udGVudCBpcyBjb250YWluZWQuICBBCisgKiA8Y29kZT5NZXNzYWdlQ29udGV4dDwvY29kZT4gb2JqZWN0IGlzIHJldHVybmVkIGJ5IHRoZQorICogPGNvZGU+Z2V0TWVzc2FnZUNvbnRleHQ8L2NvZGU+IG1ldGhvZCBvZiB0aGUKKyAqIDxjb2RlPk1lc3NhZ2VBd2FyZTwvY29kZT4gaW50ZXJmYWNlLiAgPGNvZGU+TWVzc2FnZUF3YXJlPC9jb2RlPiBpcworICogdHlwaWNhbGx5IGltcGxlbWVudGVkIGJ5IDxjb2RlPkRhdGFTb3VyY2VzPC9jb2RlPiB0byBhbGxvdyBhCisgKiA8Y29kZT5EYXRhQ29udGVudEhhbmRsZXI8L2NvZGU+IHRvIHBhc3Mgb24gaW5mb3JtYXRpb24gYWJvdXQgdGhlCisgKiBjb250ZXh0IGluIHdoaWNoIGEgZGF0YSBjb250ZW50IG9iamVjdCBpcyBvcGVyYXRpbmcuCisgKgorICogQHNlZSBqYXZheC5tYWlsLk1lc3NhZ2VBd2FyZQorICogQHNlZSBqYXZheC5hY3RpdmF0aW9uLkRhdGFTb3VyY2UKKyAqIEBzZWUgamF2YXguYWN0aXZhdGlvbi5EYXRhQ29udGVudEhhbmRsZXIKKyAqLworcHVibGljIGNsYXNzIE1lc3NhZ2VDb250ZXh0IHsKKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIE1lc3NhZ2VDb250ZXh0IG9iamVjdCBkZXNjcmliaW5nIHRoZSBjb250ZXh0IG9mIHRoZSAKKyAgICAgKiBnaXZlbiBQYXJ0LgorICAgICAqLworICAgIHB1YmxpYyBNZXNzYWdlQ29udGV4dChQYXJ0IHBhcnQpCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIFBhcnQgdGhhdCBjb250YWlucyB0aGUgY29udGVudC4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIGNvbnRhaW5pbmcgUGFydCwgb3IgbnVsbCBpZiBub3Qga25vd24KKyAgICAgKi8KKyAgICBwdWJsaWMgUGFydCBnZXRQYXJ0KCkKKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgTWVzc2FnZSB0aGF0IGNvbnRhaW5zIHRoZSBjb250ZW50LgorICAgICAqIEZvbGxvd3MgdGhlIHBhcmVudCBjaGFpbiB1cCB0aHJvdWdoIGNvbnRhaW5pbmcgTXVsdGlwYXJ0CisgICAgICogb2JqZWN0cyB1bnRpbCBpdCBjb21lcyB0byBhIE1lc3NhZ2Ugb2JqZWN0LCBvciBudWxsLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgY29udGFpbmluZyBNZXNzYWdlLCBvciBudWxsIGlmIG5vdCBrbm93bgorICAgICAqLworICAgIHB1YmxpYyBNZXNzYWdlIGdldE1lc3NhZ2UoKQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBTZXNzaW9uIHdlJ3JlIG9wZXJhdGluZyBpbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIFNlc3Npb24sIG9yIG51bGwgaWYgbm90IGtub3duCisgICAgICovCisgICAgcHVibGljIFNlc3Npb24gZ2V0U2Vzc2lvbigpCit9CisKKworQSBNZXNzYWdlQ29udGV4dCBvYmplY3QgY2FuIGJlIG9idGFpbmVkIGJ5IGEgRGF0YUNvbnRlbnRIYW5kbGVyIGZyb20gYQorRGF0YVNvdXJjZSB0aGF0IGFsc28gaW1wbGVtZW50cyB0aGUgTWVzc2FnZUF3YXJlIGludGVyZmFjZToKKworLyoqCisgKiBBbiBpbnRlcmZhY2Ugb3B0aW9uYWxseSBpbXBsZW1lbnRlZCBieSA8Y29kZT5EYXRhU291cmNlczwvY29kZT4gdG8KKyAqIHN1cHBseSBpbmZvcm1hdGlvbiB0byBhIDxjb2RlPkRhdGFDb250ZW50SGFuZGxlcjwvY29kZT4gYWJvdXQgdGhlCisgKiBtZXNzYWdlIGNvbnRleHQgaW4gd2hpY2ggdGhlIGRhdGEgY29udGVudCBvYmplY3QgaXMgb3BlcmF0aW5nLgorICoKKyAqIEBzZWUgamF2YXgubWFpbC5NZXNzYWdlQ29udGV4dAorICogQHNlZSBqYXZheC5hY3RpdmF0aW9uLkRhdGFTb3VyY2UKKyAqIEBzZWUgamF2YXguYWN0aXZhdGlvbi5EYXRhQ29udGVudEhhbmRsZXIKKyAqLworcHVibGljIGludGVyZmFjZSBNZXNzYWdlQXdhcmUgeworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgbWVzc2FnZSBjb250ZXh0LgorICAgICAqLworICAgIHB1YmxpYyBNZXNzYWdlQ29udGV4dCBnZXRNZXNzYWdlQ29udGV4dCgpOworfQorCisKK1RoaXMgbmV3IGludGVyZmFjZSBhbmQgY2xhc3MgcHJvdmlkZXMgdGhlIGJhc2ljIGluZm9ybWF0aW9uIG5lZWRlZCBieQordGhlIERhdGFDb250ZW50SGFuZGxlciB0byB1c2UgaW4gY29uc3RydWN0aW5nIG1vcmUgImludGVyZXN0aW5nIiBvYmplY3RzCityZXByZXNlbnRpbmcgYSBwYXJ0aWN1bGFyIHR5cGUgb2YgZGF0YS4KKworVG8gYWxsb3cgbmF2aWdhdGlvbiB1cCB0aGUgY2hhaW4gb2YgY29tcG9uZW50cyBjb250YWluZWQgaW4gYSBNZXNzYWdlLAord2UgYWRkIHRoZSBmb2xsb3dpbmcgbWV0aG9kcy4KKworRmlyc3QsIG9uIEJvZHlQYXJ0IHdlIGFkZDoKKworICAgIC8qKgorICAgICAqIFRoZSA8Y29kZT5NdWx0aXBhcnQ8L2NvZGU+IG9iamVjdCBjb250YWluaW5nIHRoaXMgCisgICAgICogPGNvZGU+Qm9keVBhcnQ8L2NvZGU+LCBpZiBrbm93bi4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgTXVsdGlwYXJ0IHBhcmVudDsKKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgY29udGFpbmluZyA8Y29kZT5NdWx0aXBhcnQ8L2NvZGU+IG9iamVjdCwKKyAgICAgKiBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBub3Qga25vd24uCisgICAgICovCisgICAgcHVibGljIE11bHRpcGFydCBnZXRQYXJlbnQoKQorCisKK09uIE11bHRpcGFydCB3ZSBhZGQ6CisKKyAgICAvKioKKyAgICAgKiBUaGUgPGNvZGU+UGFydDwvY29kZT4gY29udGFpbmluZyB0aGlzIDxjb2RlPk11bHRpcGFydDwvY29kZT4sCisgICAgICogaWYga25vd24uCisgICAgICovCisgICAgcHJvdGVjdGVkIFBhcnQgcGFyZW50OworCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSA8Y29kZT5QYXJ0PC9jb2RlPiB0aGF0IGNvbnRhaW5zIHRoaXMKKyAgICAgKiAoY29kPGNvZGU+TXVsdGlwYXJ0PC9jIG9iamVjdCwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgbm90IGtub3duLgorICAgICAqLworICAgIHB1YmxpYyBQYXJ0IGdldFBhcmVudCgpCisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHBhcmVudCBvZiB0aGlzIDxjb2RlPk11bHRpcGFydDwvY29kZT4gdG8gYmUgdGhlIHNwZWNpZmllZAorICAgICAqIDxjb2RlPlBhcnQ8L2NvZGU+LiAgTm9ybWFsbHkgY2FsbGVkIGJ5IHRoZSA8Y29kZT5NZXNzYWdlPC9jb2RlPgorICAgICAqIG9yIDxjb2RlPkJvZHlQYXJ0PC9jb2RlPiA8Y29kZT5zZXRDb250ZW50KE11bHRpcGFydCk8L2NvZGU+CisgICAgICogbWV0aG9kLiA8cD4KKyAgICAgKgorICAgICAqIDxjb2RlPnBhcmVudDwvY29kZT4gbWF5IGJlIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZQorICAgICAqIDxjb2RlPk11bHRpcGFydDwvY29kZT4gaXMgYmVpbmcgcmVtb3ZlZCBmcm9tIGl0cyBjb250YWluaW5nCisgICAgICogPGNvZGU+UGFydDwvY29kZT4uCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UGFyZW50KFBhcnQgcGFyZW50KQorCisKK1RvIGVuYWJsZSB0aGlzIG5ldyBmdW5jdGlvbmFsaXR5IHdlIGNoYW5nZSB0aGUgaW1wbGVtZW50YXRpb25zIG9mCitNaW1lQm9keVBhcnQsIE1pbWVNZXNzYWdlLCBhbmQgTWltZU11bHRpcGFydCB0byBtYWludGFpbiB0aGUgInBhcmVudCIKK2xpbmtzIHdoZXJlIHBvc3NpYmxlLiAgV2UgYWxzbyBjaGFuZ2UgTWltZVBhcnREYXRhU291cmNlIHRvIGltcGxlbWVudAordGhlIE1lc3NhZ2VBd2FyZSBpbnRlcmZhY2UuCisKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworKDIpIE1lc3NhZ2VJRAorPT09PT09PT09PT09PQorVGhlIE1pbWVNZXNzYWdlIGNsYXNzIHJlcXVpcmVzIGEgZ2V0TWVzc2FnZUlEKCkgbWV0aG9kLgorCitUaGUgY2xpZW50IGNhbiBub3cgZmV0Y2ggaXQgYXMgYSBoZWFkZXIsIGJ1dCBzaW5jZSB0aGlzIGlzIGEgInN0YW5kYXJkIgorUkZDODIyIGhlYWRlciwgd2Ugd2FudCB0byBwcm92aWRlIGFuIGVhc2llciBhY2Nlc3MgbWV0aG9kLiAKKworQW4gYWRkZWQgYmVuZWZpdCBpcyB0aGF0IHByb3RvY29scyBsaWtlIElNQVAsIHdoaWNoIHByb3ZpZGUgdGhpcyBpbmZvCithcyBwYXJ0IG9mIHRoZSBFTlZFTE9QRSBzdHJ1Y3R1cmUsIGNhbiBpbXBsZW1lbnQgdGhpcyBtZXRob2QgbXVjaCBtb3JlCitlZmZpY2llbnRseS4KKworIC8qKgorICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIHRoZSAiTWVzc2FnZS1JRCIgaGVhZGVyIGZpZWxkLiBSZXR1cm5zCisgICogbnVsbCBpZiB0aGlzIGZpZWxkIGlzIHVuYXZhaWxhYmxlIG9yIGl0cyB2YWx1ZSBpcyBhYnNlbnQuIDxwPgorICAqCisgICogVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gcHJvdmlkZWQgaGVyZSB1c2VzIHRoZQorICAqIDxjb2RlPmdldEhlYWRlcigpPC9jb2RlPiBtZXRob2QgdG8gcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUKKyAgKiAiTWVzc2FnZS1JRCIgZmllbGQuCisgICoKKyAgKiBAcmV0dXJuIAlNZXNzYWdlLUlECisgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24sIGlmIHRoZSByZXRyaWV2YWwgb2YgdGhpcyBmaWVsZAorICAqCQljYXVzZXMgYW55IGV4Y2VwdGlvbi4KKyAgKiBAc2VlCWphdmF4Lm1haWwuc2VhcmNoLk1lc3NhZ2VJRFRlcm0KKyAgKi8KKyAgcHVibGljIFN0cmluZyBnZXRNZXNzYWdlSUQoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uOworCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKygzKSBVSURGb2xkZXIKKz09PT09PT09PT09PT0KKworVGhlIGZvbGxvd2luZyBtZXRob2RzIGluIHRoZSBVSURGb2xkZXIgaW50ZXJmYWNlIGhhdmUgY2VydGFpbiBwcm9ibGVtcy4KKworV2UgYXJlIHByb3Bvc2luZyBjaGFuZ2VzIHRoYXQgd2lsbCBmaXggdGhlc2UgcHJvYmxlbXMuIFRoZXNlIGFyZQorYmluYXJ5IGluY29tcGF0aWJsZSBjaGFuZ2VzLCBidXQgd2UgdGhpbmsgdGhlc2UgY2hhbmdlcyBhcmUgbmVjZXNzYXJ5IGZvcgordGhpcyBpbnRlcmZhY2UgdG8gd29yayBpbiBhIHVzZWZ1bCBtYW5uZXIuIFdlIGFyZSBhbHNvIG5vdCBhd2FyZSBvZgorYW55b25lIHRoYXQgaGFzIHNoaXBwZWQgYSBTdG9yZSBQcm92aWRlciB0aGF0IGltcGxlbWVudHMgdGhpcyBpbnRlcmZhY2UsCitzbyB3ZSBhcmUgaG9waW5nIHRoYXQgdGhlIGVmZmVjdCBvZiB0aGlzIGNoYW5nZSBpcyBtaW5pbWFsIChub24tZXhpc3RlbnQpLgorCisoMSkgTWVzc2FnZSBnZXRNZXNzYWdlQnlVSUQobG9uZyB1aWQpCisKK0Rlc2NyaXB0aW9uOgorCUdldCB0aGUgTWVzc2FnZSBjb3JyZXNwb25kaW5nIHRvIHRoZSBnaXZlbiBVSUQuIElmIG5vIHN1Y2gKK21lc3NhZ2UgZXhpc3RzLCB0aGUgamF2YS51dGlsLk5vU3VjaEVsZW1lbnRFeGNlcHRpb24gaXMgdGhyb3duLgorCitQcm9ibGVtOgorCUEgZGlzY29ubmVjdGVkIGNsaWVudCBjYW4gaGF2ZSBhIHN0YXNoIG9mIFVJRHMgZnJvbSBhCitwcmV2aW91cyBzZXNzaW9uLiBTb21lIG9mIHRoZXNlIFVJRHMgbWF5IGhhdmUgYmVlbiBleHB1bmdlZCBmcm9tIHRoZQorc2VydmVyLCBidXQgdGhlIGRpc2Nvbm5lY3RlZCBjbGllbnQgZG9lcyBub3Qga25vdyB0aGlzLiBJdCBpcyBxdWl0ZQorcmVhc29uYWJsZSAoYW5kIGV4cGVjdGVkKSBmb3IgYSBkaXNjb25uZWN0ZWQgY2xpZW50IHRvIHVzZSB0aGlzCittZXRob2Qgd2hlbiByZWNvbm5lY3RpbmcgLSB0byBjaGVjayB3aGV0aGVyIGEgVUlEIGlzIHZhbGlkIG9yIG5vdCBhdAordGhlIHNlcnZlci4KKwlTaW5jZSBmYWlsdXJlIGlzIGFuIGV4cGVjdGVkIHJlc3VsdCBoZXJlLCB1c2luZyBhCitSdW5UaW1lRXhjZXB0aW9uIHRvIGluZGljYXRlIGl0LCBzZWVtcyB3cm9uZyBhbmQgY291bnRlci1pbnR1aXRpdmUgZm9yCit0aGUgY2xpZW50LgorCitTb2x1dGlvbjoKKwlPdXIgc29sdXRpb24gaXMgdG8gYWxsb3cgdGhpcyBtZXRob2QgdG8gcmV0dXJuIG51bGwgdG8gaW5kaWNhdGUKK3RoYXQgdGhlIHJlcXVlc3RlZCBVSUQgaXMgbm90IHZhbGlkIGFueW1vcmUuIFRodXMsIHRoaXMgbWV0aG9kIHdpbGwgbm8KK2xvbmdlciB0aHJvdyB0aGUgamF2YS51dGlsLk5vU3VjaEVsZW1lbnRFeGNlcHRpb24uCisKKygyKSAgTWVzc2FnZVtdIGdldE1lc3NhZ2VzQnlVSUQobG9uZyBzdGFydCwgbG9uZyBlbmQpCisKK0Rlc2NyaXB0aW9uOgorCUdldCB0aGUgTWVzc2FnZXMgY29ycmVzcG9uZGluZyB0byB0aGUgZ2l2ZW4gVUlEIHJhbmdlLiBJZiBhbnkKK1VJRCBpcyBpbnZhbGlkLCB0aGUgamF2YS51dGlsLk5vU3VjaEVsZW1lbnRFeGNlcHRpb24gaXMgdGhyb3duLgorCitQcm9ibGVtOgorCVNpbWlsYXIsIGJ1dCB3b3JzZSB0aGFuICgxKS4gV2UgdGhpbmsgdGhhdCBkaXNjb25uZWN0ZWQgY2xpZW50cworKG9yIGNsaWVudHMgdGhhdCBwcmVmZXIgdG8gdXNlIFVJRHMpIG1heSBpc3N1ZSAKKwlnZXRNZXNzYWdlc0J5VUlEKDEsIExBU1RVSUQpIAordG8gZ2V0IGFsbCB0aGUgTWVzc2FnZXMgYXQgdGhlIHNlcnZlciwgZXNwZWNpYWxseSB3aGVuIHRoZSBjbGllbnQgZG9lcworbm90IGtub3cgdGhlIGV4YWN0IFVJRHMgZm9yIHRoaXMgZm9sZGVyLiBJbiB0aGlzIGNhc2UsIHdlIGNlcnRhaW5seQorZG8gbm90IHdhbnQgdGhpcyBtZXRob2QgdG8gZmFpbCBpZiBzb21lIGlkIGluIHRoZSBnaXZlbiByYW5nZSBpcyAKK25vdCBhIHZhbGlkIFVJRDsgcmF0aGVyIHdlIHdhbnQgaXQgdG8gcmV0dXJuIGFsbCBhdmFpbGFibGUgTWVzc2FnZXMgZnJvbQordGhlIHNlcnZlci4KKworU29sdXRpb246CisJT3VyIHNvbHV0aW9uIGlzIHRvIHJlbW92ZSB0aGUgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiBleGNlcHRpb24KK2FuZCBhbGxvdyB0aGlzIG1ldGhvZCB0byByZXR1cm4gTWVzc2FnZSBvYmplY3RzIGluIHRoZSBnaXZlbiByYW5nZS4KKworKDMpIE1lc3NhZ2VbXSBnZXRNZXNzYWdlc0J5VUlEKGxvbmdbXSB1aWRzKQorCitEZXNjcmlwdGlvbjoKKwlHZXQgdGhlIE1lc3NhZ2VzIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGdpdmVuIFVJRCByYW5nZS4gSWYgYW55CitVSUQgaXMgaW52YWxpZCwgdGhlIGphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uIGlzIHRocm93bi4KKworUHJvYmxlbToKKwlJZGVudGljYWwgdG8gKDEpLgorCUEgZGlzY29ubmVjdGVkIGNsaWVudCBjYW4gaGF2ZSBhIHN0YXNoIG9mIFVJRHMgZnJvbSBhCitwcmV2aW91cyBzZXNzaW9uLiBTb21lIG9mIHRoZXNlIFVJRHMgbWF5IGhhdmUgYmVlbiBleHB1bmdlZCBmcm9tIHRoZQorc2VydmVyLCBidXQgdGhlIGRpc2Nvbm5lY3RlZCBjbGllbnQgZG9lcyBub3Qga25vdyB0aGlzLiBJdCBpcyBxdWl0ZQorcmVhc29uYWJsZSAoYW5kIGV4cGVjdGVkKSBmb3IgYSBkaXNjb25uZWN0ZWQgY2xpZW50IHRvIHVzZSB0aGlzCittZXRob2Qgd2hlbiByZWNvbm5lY3RpbmcgLSB0byBjaGVjayB3aGV0aGVyIGEgc2V0IG9mIFVJRHMgYXJlIHZhbGlkCitvciBub3QgYXQgdGhlIHNlcnZlci4KKwlTaW5jZSBmYWlsdXJlIGNhbiBiZSBhbiBleHBlY3RlZCByZXN1bHQsIHVzaW5nIGEKK1J1blRpbWVFeGNlcHRpb24gdG8gaW5kaWNhdGUgaXQsIHNlZW1zIHdyb25nIGFuZCBjb3VudGVyLWludHVpdGl2ZSBmb3IKK3RoZSBjbGllbnQuCisKK1NvbHV0aW9uOgorCU91ciBzb2x1dGlvbiBpcyB0byBhbGxvdyB0aGlzIG1ldGhvZCB0byByZXR1cm4gbnVsbCBlbnRyaWVzCit0byBpbmRpY2F0ZSB0aGF0IGEgcmVxdWVzdGVkIFVJRCBpcyBub3QgdmFsaWQgYW55bW9yZS4gVGh1cywgdGhlCittZXNzYWdlIGFycmF5IHJldHVybmVkIGJ5IHRoaXMgbWV0aG9kIGNhbiBoYXZlIG51bGwgZW50cmllcyBmb3IgdGhlCitpbnZhbGlkIFVJRHM7IGFuZCB0aGlzIG1ldGhvZCB3aWxsIG5vIGxvbmdlciB0aHJvdyB0aGUgCitqYXZhLnV0aWwuTm9TdWNoRWxlbWVudEV4Y2VwdGlvbi4KKwlOb3RlIHRoYXQgdGhlIHNpemUgb2YgdGhlIHJldHVybmVkIE1lc3NhZ2UgYXJyYXkgaXMgdGhlIHNhbWUKK2FzIHRoZSBzaXplIG9mIHRoZSByZXF1ZXN0IGFycmF5IG9mIFVJRHMsIGFuZCB0aGF0IGVhY2ggZW50cnkgaW4gdGhlCitNZXNzYWdlIGFycmF5IGNvcnJlc3BvbmRzIHRvIHRoZSBzYW1lIGluZGV4IGVudHJ5IGluIHRoZSBVSUQgYXJyYXkuCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKyg0KSBJbnRlcm5ldEFkZHJlc3MKKz09PT09PT09PT09PT09PT09PT0KKworVGhlIEludGVybmV0QWRkcmVzcyBjbGFzcyBuZWVkcyB0aGUgZm9sbG93aW5nIHByb3RlY3RlZCBmaWVsZCB0bworcHJvcGVybHkgc3VwcG9ydCBlbmNvZGluZyBvZiB0aGUgInBlcnNvbmFsIG5hbWUiLgorCisJcHJvdGVjdGVkIFN0cmluZyBlbmNvZGVkUGVyc29uYWw7IC8vIHRoZSBlbmNvZGVkIHBlcnNvbmFsIG5hbWUKKworTm8gb3RoZXIgQVBJIGNoYW5nZXMgYXJlIGFzc29jaWF0ZWQgd2l0aCB0aGlzLiAKKworVGhpcyBpcyBhIGJpbmFyeSBjb21wYXRpYmxlIGNoYW5nZSB0byBKYXZhTWFpbCAxLjAuIEhvd2V2ZXIsIHRoZXJlIGlzCithIHBvdGVudGlhbCBwcm9ibGVtIGZvciBhbnkgZXhpc3RpbmcgSW50ZXJuZXRBZGRyZXNzIHN1YmNsYXNzZXMsIHdoaWNoCitjYW4gY2F1c2UgdGhlbSB0byBicmVhay4gVGhpcyB0eXBpY2FsbHkgd2lsbCBhZmZlY3Qgb25seSBwcm92aWRlcnMsCitub3QgY2xpZW50cy4KKworRGV0YWlsczoKKy0tLS0tLS0KKworVGhlIEludGVybmV0QWRkcmVzcyBpbXBsZW1lbnRhdGlvbiB3aWxsIHVzZSB0aGlzIGZpZWxkIHRvIHN0b3JlIHRoZQorZW5jb2RlZCBwZXJzb25hbCBuYW1lLiAKKworCVRoZSBnZXRQZXJzb25hbCgpIG1ldGhvZCB3aWxsIHJldHVybiB0aGUgcHJvdGVjdGVkCisncGVyc29uYWwnIGZpZWxkOyBpZiB0aGlzIGZpZWxkIGlzIG51bGwsIGl0IHdpbGwgY2hlY2sgdGhlICdlbmNvZGVkUGVyc29uYWwnCitmaWVsZCBhbmQgZGVjb2RlIGl0cyB2YWx1ZSBhbmQgcmV0dXJuIGl0LgorCVRoZSB0b1N0cmluZygpIG1ldGhvZCB3aWxsIHVzZSB0aGUgcHJvdGVjdGVkICdlbmNvZGVkUGVyc29uYWwnCitmaWVsZCB0byBjcmVhdGUgdGhlIFJGQzIwNDcgY29tcGxpYW50IGFkZHJlc3Mgc3RyaW5nLiBJZiB0aGlzIGZpZWxkIGlzCitudWxsLCBpdCB3aWxsIGNoZWNrIHRoZSAncGVyc29uYWwnIGZpZWxkLCBlbmNvZGUgdGhhdCBpZiBuZWNlc3NhcnkgYW5kCit1c2UgaXQuCisKK1RoaXMgaW1wbGllcyB0aGF0LCBpZiBhbiBJbnRlcm5ldEFkZHJlc3Mgc3ViY2xhc3MgY2hhbmdlcyBlaXRoZXIgCit0aGUgJ3BlcnNvbmFsJyBvciAnZW5jb2RlZFBlcnNvbmFsJyBmaWVsZHMsICBpdCBzaG91bGQgc2V0IHRoZSBvdGhlcgordG8gbnVsbCB0byBmb3JjZSBpdHMgcmVjb21wdXRhdGlvbi4gVW5mb3J0dW5hdGVseSwgdGhpcyBhbHNvIGltcGxpZXMKK3RoYXQgZXhpc3Rpbmcgc3ViY2xhc3NlcyBvZiBJbnRlcm5ldEFkZHJlc3MgdGhhdCBkaXJlY3RseSBzZXQgdGhlCisncGVyc29uYWwnIGZpZWxkIGNhbiBicmVhayBpbiBjZXJ0YWluIHNpdHVhdGlvbnMuCisJV2UgZmVlbCB0aGF0IHRoZSByaXNrIG9mIHRoaXMgaGFwcGVuaW5nIGlzIG1pbmltYWwsIHNpbmNlIHdlCitkb24ndCBleHBlY3QgdGhhdCBvdXIgdXNlcnMgaGF2ZSBzdWJjbGFzc2VkIEludGVybmV0QWRkcmVzcy4gQWxzbywgdGhpcworaXMgbmVjZXNzYXJ5IHRvIHByb3Blcmx5IHN1cHBvcnQgZW5jb2RlZCBwZXJzb25hbCBuYW1lcywgc28gd2UgZmVlbCB0aGF0Cit0aGlzIGhhcyB0byBiZSBkb25lLgorPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisoNSkgTWltZUNoYXJzZXQKKz09PT09PT09PT09PT09PT0KKworQSB1dGlsaXR5IG1ldGhvZCB0byBjb252ZXJ0IGphdmEgY2hhcnNldHMgaW50byBNSU1FIGNoYXJzZXRzIGlzCituZWVkZWQuCisKK1RoZSBKREsgc3VwcG9ydHMgYSB2YXJpZXR5IG9mIGNoYXJzZXRzLiBUaGUgSkRLIGhhcyBuYW1lcyBmb3IgdGhlc2UKK2NoYXJzZXRzLCB1bmZvcnR1bmF0ZWx5IHRoZXkgZG9udCBhbHdheXMgbWF0Y2ggdG8gdGhlaXIgTUlNRSBvciBJQU5BCitlcXVpdmFsZW50cy4gCisKK0l0IGlzIG5lY2Vzc2FyeSBpbiBzb21lIGNhc2VzLCAoZXNwZWNpYWxseSBmb3IgcHJvdmlkZXJzKSB0byBtYXAgdGhlCitKREsgY2hhcnNldCBuYW1lcyBpbnRvIHRoZWlyIE1JTUUgb3IgSUFOQSBlcXVpdmFsZW50cy4gVGhpcyBtZXRob2QgZG9lcwordGhhdC4KKworVGhlIEFQSToKKy0tLS0tLS0KKworVGhpcyBpcyBhIG5ldyBzdGF0aWMgbWV0aG9kIHRvIHRoZSBqYXZheC5tYWlsLmludGVybmV0Lk1pbWVVdGlsaXR5IGNsYXNzCisKKwkvKioKKwkgKiBDb252ZXJ0IGEgamF2YSBjaGFyc2V0IGludG8gaXRzIE1JTUUgY2hhcnNldCBuYW1lLiA8cD4KKwkgKgorCSAqIE5vdGUgdGhhdCBhIGZ1dHVyZSB2ZXJzaW9uIG9mIEpESyAocG9zdCAxLjIpIG1pZ2h0IHByb3ZpZGUKKwkgKiB0aGlzIGZ1bmN0aW9uYWxpdHksIGluIHdoaWNoIGNhc2UsIHdlIG1pZ2h0IGRlcHJlY2F0ZSB0aGlzCisJICogbWV0aG9kIHRoZW4uCisJICoKKwkgKiBAcGFyYW0gICBjaGFyc2V0ICAgIHRoZSBKREsgY2hhcnNldAorCSAqIEByZXR1cm4JdGhlIE1JTUUvSUFOQSBlcXVpdmFsZW50LiBJZiBhIG1hcHBpbmcKKwkgKgkJaXMgbm90IHBvc3NpYmxlLCB0aGUgcGFzc2VkIGluIGNoYXJzZXQgaXRzZWxmCisJICoJCWlzIHJldHVybmVkLgorCSAqLwkJCQorCXB1YmxpYyBzdGF0aWMgU3RyaW5nIG1pbWVDaGFyc2V0KFN0cmluZyBjaGFyc2V0KTsKKworPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworKDYpIGdldERlZmF1bHRKYXZhQ2hhcnNldCgpCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK1RoaXMgbWV0aG9kIHJldHVybnMgdGhlIGRlZmF1bHQgY2hhcnNldCBmb3IgdGhlIHBsYXRmb3JtJ3MgbG9jYWxlLCBhcworYSBKYXZhIGNoYXJzZXQuIFRoaXMgaXMgYSBuZXcgc3RhdGljIG1ldGhvZCB0byB0aGUgTWltZVV0aWxpdHkgY2xhc3MuCisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGRlZmF1bHQgY2hhcnNldCBmb3IgdGhpcyBsb2NhbGUuIDxwPgorICAgICAqCisgICAgICogQHJldHVybiAgdGhlIGRlZmF1bHQgY2hhcnNldCBvZiB0aGUgcGxhdGZvcm0ncyBsb2NhbGUsCisgICAgICogICAgICAgICAgYXMgYSBKYXZhIGNoYXJzZXQuIChOT1QgYSBNSU1FIGNoYXJzZXQpCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0RGVmYXVsdEphdmFDaGFyc2V0KCkKKworPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworKDcpIE1ldGhvZCB0byBwcmludCBvdXQgdGhlIG5lc3RlZCBFeGNlcHRpb25zCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworVGhlIE1lc3NhZ2luZ0V4Y2VwdGlvbiBjbGFzcyBjdXJyZW50bHkgYWxsb3dzIG5lc3RlZCBleGNlcHRpb25zLiBJdAord291bGQgYmUgbmljZSB0byBoYXZlIG9uZSBzaW5nbGUgbWV0aG9kIHRvIGR1bXAgb3V0IGFsbCB0aGUgCituZXN0ZWQgZXhjZXB0aW9ucycgbWVzc2FnZXMgaW50byBTeXN0ZW0ub3V0CisKK1Byb3Bvc2FsCistLS0tLS0tLQorCitPdmVycmlkZSB0aGUgZ2V0TWVzc2FnZSgpIG1ldGhvZCBmcm9tIHRoZSBzdXBlcmNsYXNzIChUaHJvd2FibGUpLCB0bworYXBwZW5kIHRoZSBtZXNzYWdlcyBmcm9tIGFsbCBuZXN0ZWQgRXhjZXB0aW9ucy4gVGhpcyBpcyBzaW1pbGFyIHRvCitqYXZhLnJtaS5SZW1vdGVFeGNlcHRpb24uCisKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisoOCkgTmV3IFNlYXJjaFRlcm1zCis9PT09PT09PT09PT09PT09PT09PQorCitUaGUgY3VycmVudCBhZGRyZXNzIHJlbGF0ZWQgc2VhcmNoIHRlcm1zIC0gQWRkcmVzc1Rlcm0sIEZyb21UZXJtIGFuZAorUmVjaXBpZW50VGVybSBhcmUgbGltaXRlZCBpbiB0aGF0IHRoZXkgb3BlcmF0ZSBvbiBBZGRyZXNzIG9iamVjdHMsIG5vdAorU3RyaW5ncy4gVGhlc2UgdGVybXMgdXNlIHRoZSBlcXVhbHMoKSBtZXRob2QgdG8gY29tcGFyZSB0aGUgYWRkcmVzc2VzIC0KK3doaWNoIGlzIG5vdCB1c2VmdWwgZm9yIHRoZSBjb21tb24gY2FzZSBvZiBzdWJzdHJpbmcgY29tcGFyaXNvbnMuCisKK0hlbmNlIHdlIGludHJvZHVjZSB0aHJlZSBuZXcgU2VhcmNoVGVybXM6CisKK3B1YmxpYyBBZGRyZXNzU3RyaW5nVGVybSBleHRlbmRzIFN0cmluZ1Rlcm0geworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yLgorICAgICAqIEBwYXJhbSBwYXR0ZXJuCXRoZSBhZGRyZXNzIHBhdHRlcm4gdG8gYmUgY29tcGFyZWQKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQWRkcmVzc1N0cmluZ1Rlcm0oU3RyaW5nIHBhdHRlcm4pOworCisgICAgLyoqCisgICAgICogQ2hlY2sgd2hldGhlciB0aGUgYWRkcmVzcyBwYXR0ZXJuIHNwZWNpZmllZCBpbiB0aGUgCisgICAgICogY29uc3RydWN0b3IgaXMgYSBzdWJzdHJpbmcgb2YgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiAKKyAgICAgKiB0aGUgZ2l2ZW4gQWRkcmVzcyBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0JYWRkcmVzcwl0aGUgYWRkcmVzcyB0byBtYXRjaCBhZ2FpbnN0CisgICAgICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gbWF0Y2goQWRkcmVzcyBhZGRyZXNzKTsKK30KKworcHVibGljIEZyb21TdHJpbmdUZXJtIGV4dGVuZHMgQWRkcmVzc1N0cmluZ1Rlcm0geworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yLgorICAgICAqIEBwYXJhbQlhZGRyZXNzCXRoZSBhZGRyZXNzIHRvIGJlIGNvbXBhcmVkLgorICAgICAqLworICAgIHB1YmxpYyBGcm9tU3RyaW5nVGVybShTdHJpbmcgc3RyaW5nKTsKKworICAgIC8qKgorICAgICAqIENoZWNrIHdoZXRoZXIgdGhlIGFkZHJlc3Mgc3BlY2lmaWVkIGluIHRoZSBjb25zdHJ1Y3RvciBpcworICAgICAqIGEgc3Vic3RyaW5nIG9mIHRoZSAiRnJvbSIgYXR0cmlidXRlIG9mIHRoaXMgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbQltc2cgdGhlIGFkZHJlc3MgY29tcGFyaXNvbiBpcyBhcHBsaWVkIHRvIHRoaXMgTWVzc2FnZQorICAgICAqLworICAgICBwdWJsaWMgYm9vbGVhbiBtYXRjaChNZXNzYWdlIG1zZyk7Cit9CisKK3B1YmxpYyBSZWNpcGllbnRTdHJpbmdUZXJtIGV4dGVuZHMgQWRkcmVzc1N0cmluZ1Rlcm0geworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdHlwZSAgICAgIHRoZSByZWNpcGllbnQgdHlwZQorICAgICAqIEBwYXJhbSBhZGRyZXNzCXRoZSBhZGRyZXNzIHRvIGJlIGNvbXBhcmVkLgorICAgICAqLworICAgIHB1YmxpYyBSZWNpcGllbnRTdHJpbmdUZXJtKE1lc3NhZ2UuUmVjaXBpZW50VHlwZSB0eXBlLCBTdHJpbmcgYWRkcmVzcyk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIHR5cGUgb2YgcmVjaXBpZW50IHRvIG1hdGNoIHdpdGguCisgICAgICovCisgICAgcHVibGljIE1lc3NhZ2UuUmVjaXBpZW50VHlwZSBnZXRSZWNpcGllbnRUeXBlKCk7CisKKyAgICAvKioKKyAgICAgKiBDaGVjayB3aGV0aGVyIHRoZSBhZGRyZXNzIHNwZWNpZmllZCBpbiB0aGUgY29uc3RydWN0b3IgaXMKKyAgICAgKiBhIHN1YnN0cmluZyBvZiB0aGUgZ2l2ZW4gUmVjaXBpZW50IGF0dHJpYnV0ZSBvZiB0aGlzIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0JbXNnIHRoZSBhZGRyZXNzIGNvbXBhcmlzb24gaXMgYXBwbGllZCB0byB0aGlzIE1lc3NhZ2UKKyAgICAgKi8KKyAgICAgcHVibGljIGJvb2xlYW4gbWF0Y2goTWVzc2FnZSBtc2cpOworfQorCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworKDkpIEludGVybmV0QWRkcmVzcy50b1N0cmluZyhBZGRyZXNzW10gYWRkcmVzc2VzLCBpbnQgdXNlZCkKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK0FzIHBlciBSRkMyMDQ3IChNSU1FKSwgdGhlIGxlbmd0aCBvZiBhIGhlYWRlciBmaWVsZCB0aGF0IGNvbnRhaW5zCitlbmNvZGVkLXdvcmRzIGlzIGxpbWl0ZWQgdG8gNzYgY2hhcmFjdGVycy4KKworVGhlcmUgYXJlIHR3byBtZXRob2RzIGluIHRoZSBJbnRlcm5ldEFkZHJlc3MgY2xhc3MgdGhhdCBnZW5lcmF0ZQorUkZDODIyIHN0eWxlIGFkZHJlc3Mgc3RyaW5nczoKKworIC0gVGhlIHRvU3RyaW5nKCkgbWV0aG9kIG9uIEludGVybmV0QWRkcmVzcywgd2hpY2ggZ2VuZXJhdGVzCisgdGhlIHN0cmluZyBmb3Igb25lIEludGVybmV0QWRkcmVzcyBvYmplY3QKKyAtIFRoZSB0b1N0cmluZygpIHN0YXRpYyBtZXRob2QsIHdoaWNoIGdlbmVyYXRlcyBhIGNvbW1hIHNlcGFyYXRlZAorIHN0cmluZyBmb3IgdGhlIGdpdmVuIGFycmF5IG9mIEludGVybmV0QWRkcmVzcyBvYmplY3RzLgorCitCb3RoIHRoZXNlIG1ldGhvZHMgY3VycmVudGx5IGRvIG5vdCBob25vciB0aGUgNzYgY2hhcmFjdGVyIGxpbWl0LgorQWN0dWFsbHksIHRoZSBmb3JtZXIgZG9lcyB0byBhbiBleHRlbnQsIHNpbmNlIHRoZSBlbmNvZGVkV29yZAorZ2VuZXJhdG9yIChpLmUgdGhlIE1pbWVVdGlsaXR5LmVuY29kZVdvcmQoKSBtZXRob2QpIGRvZXMgYnJlYWsKK2VuY29kZWQgd29yZHMgaW50byBtdWx0aXBsZXMsIGlmIHRoZXkgc3RyZXRjaCBiZXlvbmQgNzYgY2hhcmFjdGVycy4KKworU29sdXRpb24KKy0tLS0tLS0tCisKK0ZvciB0aGUgMS4xIHJlbGVhc2UsIHdlIGFyZSBwbGFubmluZyB0byBmaXggdGhlIHRoZSB0b1N0cmluZygpCitzdGF0aWMgbWV0aG9kIGFzIGZvbGxvd3M6CisKK0FkZCBhIG5ldyBzdGF0aWMgbWV0aG9kIAorCXN0YXRpYyBTdHJpbmcgdG9TdHJpbmcoQWRkcmVzc1tdIGFkZHJlc3MsIGludCB1c2VkKQorCitUaGlzIG1ldGhvZCB0YWtlcyBhbiBhcnJheSBvZiBBZGRyZXNzIG9iamVjdHMgYW5kIGFuIGludGVnZXIgcmVwcmVzZW50aW5nCit0aGUgbnVtYmVyIG9mICJ1c2VkIiBjaGFyYWN0ZXIgcG9zaXRpb25zIGZvciB0aGUgZmlyc3QgbGluZSBvZiB0aGlzCitmaWVsZC4gVGhlIHR5cGljYWwgdXNlIG9mIHRoaXMgbWV0aG9kIGlzIHdoZW4gc2V0dGluZyBSRkM4MjIgaGVhZGVycywKK2xpa2UgdGhlICJGcm9tIiBoZWFkZXIuICd1c2VkJyBjYW4gYmUgc2V0IHRvIHNpemVvZigiRnJvbTogIikgaW4KK3RoaXMgY2FzZS4KKworV2hlbiBnZW5lcmF0aW5nIHRoZSBzdHJpbmcsIHRoaXMgbWV0aG9kIHN0YXJ0cyBhIG5ldyBsaW5lIGlmIHRoZQorYWRkaXRpb24gb2YgdGhlIG5leHQgYWRkcmVzcy50b1N0cmluZygpIGNhdXNlcyB0aGUgY3VycmVudCBsaW5lJ3MgCitsaW5lLWxlbmd0aCB0byBnbyBvdmVyIDc2LgorCitOb3RlIHRoYXQgdGhpcyBhbGdvcml0aG0gZG9lcyBub3Qgd29yayByaWdodCBpZiB0aGUgbGVuZ3RoIG9mIGEgc2luZ2xlCitJbnRlcm5ldEFkZHJlc3MgaXMgaXRzZWxmIG1vcmUgdGhhbiA3NiBjaGFyYWN0ZXJzLiBBbHNvLCBpdCBkb2VzIG5vdAorb3B0aW1hbGx5IGJyZWFrIGFuIGFkZHJlc3MgZmllbGQsIHNvIHRoYXQgdGhlIG1heGltdW0gY2hhcmFjdGVycyBhcmUKK2FjY29tbW9kYXRlZCBpbiBhIHNpbmdsZSBsaW5lLgorCitTbywgZXNzZW50aWFsbHksIHRoaXMgaXMgYW4gaW5pdGlhbCBhdHRlbXB0IHRvIHNvbHZlIHRoaXMgcHJvYmxlbS4gV2UKK3dpbGwgYWRkIG1vcmUgQVBJcyBpbiB0aGUgbmV4dCB2ZXJzaW9uIHRvIGZ1cnRoZXIgcmVmaW5lIHRoaXMuCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworKDEwKSBGb2xkZXIuZ2V0TW9kZSgpCis9PT09PT09PT09PT09PT09PT09PT0KKworSXQgaXMgY3VycmVudGx5IG5vdCBwb3NzaWJsZSB0byB0ZWxsIHdoZXRoZXIgYSBmb2xkZXIgaXMgb3BlbiBSRUFEX09OTFkKK29yIFJFQURfV1JJVEUgd2l0aG91dCBhdHRlbXB0aW5nIHRvIHdyaXRlIGl0IGFuZCBjYXRjaGluZyB0aGUgZXhjZXB0aW9uLgorCitXZSBwcm9wb3NlIHRvIGFkZCBhIHByb3RlY3RlZCBmaWVsZCB0byBGb2xkZXIgdG8gc3RvcmUgdGhlIG9wZW4gbW9kZSBhbmQKK2EgbmV3IG1ldGhvZCB0byBGb2xkZXIgdG8gcmV0dXJuIHRoZSBvcGVuIG1vZGUuICBCZWNhdXNlIGV4aXN0aW5nIAorc3ViY2xhc3NlcyB3aWxsIG5vdCB1c2UgdGhpcyBuZXcgZmllbGQsIHdlIGNhbid0IGd1YXJhbnRlZSB0aGF0IHRoZSAKK21ldGhvZCB3aWxsIGFsd2F5cyByZXR1cm4gdGhlIGNvcnJlY3QgdmFsdWUgKGFsdGhvdWdoIGFsbCBGb2xkZXIgc3ViY2xhc3NlcworaW4gdGhlIEphdmFNYWlsIHBhY2thZ2Ugd2lsbCBiZSB1cGRhdGVkIHRvIHJldHVybiB0aGUgY29ycmVjdCB2YWx1ZSkuCisKKyAgICAvKioKKyAgICAgKiBUaGUgb3BlbiBtb2RlICg8Y29kZT5Gb2xkZXIuUkVBRF9PTkxZPC9jb2RlPiwKKyAgICAgKiA8Y29kZT5Gb2xkZXIuUkVBRF9XUklURTwvY29kZT4sIG9yIC0xIGlmIG5vdCBrbm93bikuCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBtb2RlID0gLTE7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIG9wZW4gbW9kZSBvZiB0aGlzIGZvbGRlci4gIFJldHVybnMKKyAgICAgKiA8Y29kZT5Gb2xkZXIuUkVBRF9PTkxZPC9jb2RlPiwgPGNvZGU+Rm9sZGVyLlJFQURfV1JJVEU8L2NvZGU+LAorICAgICAqIG9yIC0xIGlmIHRoZSBvcGVuIG1vZGUgaXMgbm90IGtub3duICh1c3VhbGx5IG9ubHkgYmVjYXVzZSBhbiBvbGRlcgorICAgICAqIDxjb2RlPkZvbGRlcjwvY29kZT4gcHJvdmlkZXIgaGFzIG5vdCBiZWVuIHVwZGF0ZWQgdG8gdXNlIHRoaXMgbmV3CisgICAgICogbWV0aG9kKS4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgZm9sZGVyIGlzIG5vdCBvcGVuZWQKKyAgICAgKiBAcmV0dXJuCSAgICAgICAgdGhlIG9wZW4gbW9kZSBvZiB0aGlzIGZvbGRlcgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0TW9kZSgpIHsKKwlpZiAoIWlzT3BlbigpKQorCSAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJGb2xkZXIgbm90IG9wZW4iKTsKKwlyZXR1cm4gbW9kZTsKKyAgICB9CisKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKygxMSkgRm9sZGVyLmdldFVSTE5hbWUoKQorPT09PT09PT09PT09PT09PT09PT09PT09CisKK1RoZSBVUkxOYW1lIHN1cHBvcnQgaW4gdGhlIEphdmFNYWlsIDEuMCBBUEkncyBpcyBpbmNvbXBsZXRlIGFuZAoraW5hZGVxdWF0ZWx5IHNwZWNpZmllZC4gIFdoaWxlIHlvdSBjYW4gZ2V0IGEgRm9sZGVyIGZyb20gYSBTZXNzaW9uCitnaXZlbiBhIFVSTE5hbWUgZm9yIHRoZSBmb2xkZXIsIHlvdSBjYW4ndCBmaW5kIG91dCB0aGUgVVJMTmFtZQorZm9yIGEgZ2l2ZW4gRm9sZGVyIG9iamVjdC4gIFdlIHByb3Bvc2UgYWRkaW5nIHRoZSBmb2xsb3dpbmcgbWV0aG9kCit0byBGb2xkZXI6CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYSBVUkxOYW1lIHJlcHJlc2VudGluZyB0aGlzIGZvbGRlci4gIFRoZSByZXR1cm5lZCBVUkxOYW1lCisgICAgICogZG9lcyA8ZW0+bm90PC9lbT4gaW5jbHVkZSB0aGUgcGFzc3dvcmQgdXNlZCB0byBhY2Nlc3MgdGhlIHN0b3JlLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgVVJMTmFtZSByZXByZXNlbnRpbmcgdGhpcyBmb2xkZXIKKyAgICAgKiBAc2VlCVVSTE5hbWUKKyAgICAgKi8KKyAgICBwdWJsaWMgVVJMTmFtZSBnZXRVUkxOYW1lKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbgorCitQcmV2aW91c2x5IGl0IHdhcyBub3Qgc3BlY2lmaWVkIHdoZXRoZXIgdGhlIFVSTE5hbWUgcmV0dXJuZWQgZnJvbQordGhlIFN0b3JlLmdldFVSTE5hbWUgbWV0aG9kIHdvdWxkIGluY2x1ZGUgdGhlIHBhc3N3b3JkIGZpZWxkIG9yCitub3QsIGJ1dCBzb21ldGltZXMgaXQgZGlkLiAgV2UgcHJvcG9zZSB0byB0aWdoZW4gdGhlIHNwZWNpZmljYXRpb24KK2FuZCBmaXggdGhlIGltcGxlbWVudGF0aW9uIHNvIHRoYXQgdGhlIHBhc3N3b3JkIGZpZWxkIGlzIG5vdCByZXR1cm5lZDoKKworICAgIC8qKgorICAgICAqIFJldHVybiBhIFVSTE5hbWUgcmVwcmVzZW50aW5nIHRoaXMgc3RvcmUuICBUaGUgcmV0dXJuZWQgVVJMTmFtZQorICAgICAqIGRvZXMgPGVtPm5vdDwvZW0+IGluY2x1ZGUgdGhlIHBhc3N3b3JkIGZpZWxkLiAgPHA+CisgICAgICoKKyAgICAgKiBTdWJjbGFzc2VzIHNob3VsZCBvbmx5IG92ZXJyaWRlIHRoaXMgbWV0aG9kIGlmIHRoZWlyCisgICAgICogVVJMTmFtZSBkb2VzIG5vdCBmb2xsb3cgdGhlIHN0YW5kYXJkIGZvcm1hdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIFVSTE5hbWUgcmVwcmVzZW50aW5nIHRoaXMgc3RvcmUKKyAgICAgKiBAc2VlCVVSTE5hbWUKKyAgICAgKi8KKyAgICBwdWJsaWMgVVJMTmFtZSBnZXRVUkxOYW1lKCkKKworU2ltaWxhcmx5IGZvciBUcmFuc3BvcnQuCisKK1ByZXZpb3VzbHkgaXQgd2FzIHVuc3BlY2lmaWVkIGhvdyB0aGUgU3RvcmUgYW5kIFRyYW5zcG9ydCBjb25uZWN0CittZXRob2RzIGludGVyYWN0ZWQgd2l0aCB0aGUgdXJsIGZpZWxkLiAgSW4gc29tZSBjYXNlcyBpdCB3b3VsZCBiZQordXBkYXRlZCBhbmQgaW4gb3RoZXIgY2FzZXMgaXQgd291bGQgbm90LiAgV2UgcHJvcG9zZSB0byB0aWdoZW4gdGhlCitzcGVjaWZpY2F0aW9uIGFzIGZvbGxvd3M6CisKKyAgICAvKioKKyAgICAgKiBDb25uZWN0IHRvIHRoZSBzcGVjaWZpZWQgYWRkcmVzcy4gVGhpcyBtZXRob2QgcHJvdmlkZXMgYSBzaW1wbGUKKyAgICAgKiBhdXRoZW50aWNhdGlvbiBzY2hlbWUgdGhhdCByZXF1aXJlcyBhIHVzZXJuYW1lIGFuZCBwYXNzd29yZC4gPHA+CisgICAgICoKKyAgICAgKiBJZiB0aGUgY29ubmVjdGlvbiBpcyBzdWNjZXNzZnVsLCBhbiAib3BlbiIgQ29ubmVjdGlvbkV2ZW50IGlzCisgICAgICogZGVsaXZlcmVkIHRvIGFueSBDb25uZWN0aW9uTGlzdGVuZXJzIG9uIHRoaXMgU3RvcmUuIDxwPgorICAgICAqCisgICAgICogSXQgaXMgYW4gZXJyb3IgdG8gY29ubmVjdCB0byBhbiBhbHJlYWR5IGNvbm5lY3RlZCBTdG9yZS4gPHA+CisgICAgICoKKyAgICAgKiBUaGUgaW1wbGVtZW50YXRpb24gaW4gdGhlIFN0b3JlIGNsYXNzIHdpbGwgY29sbGVjdCBkZWZhdWx0cworICAgICAqIGZvciB0aGUgaG9zdCwgdXNlciwgYW5kIHBhc3N3b3JkIGZyb20gdGhlIHNlc3Npb24sIHByb21wdGluZyB0aGUKKyAgICAgKiB1c2VyIGlmIG5lY2Vzc2FyeSwgYW5kIHdpbGwgdGhlbiBjYWxsIHRoZSBwcm90b2NvbENvbm5lY3QgbWV0aG9kLAorICAgICAqIHdoaWNoIHRoZSBzdWJjbGFzcyBtdXN0IG92ZXJyaWRlLiAgVGhlIHN1YmNsYXNzIHNob3VsZCBhbHNvCisgICAgICogaW1wbGVtZW50IHRoZSA8Y29kZT5nZXRVUkxOYW1lPC9jb2RlPiBtZXRob2QsIG9yIHVzZSB0aGUgCisgICAgICogaW1wbGVtZW50YXRpb24gaW4gdGhpcyBjbGFzcy4gPHA+CisgICAgICoKKyAgICAgKiBPbiBhIHN1Y2Nlc3NmdWwgY29ubmVjdGlvbiwgdGhlIDxjb2RlPnNldFVSTE5hbWU8L2NvZGU+IG1ldGhvZCBpcworICAgICAqIGNhbGxlZCB3aXRoIGEgVVJMTmFtZSB0aGF0IGluY2x1ZGVzIHRoZSBpbmZvcm1hdGlvbiB1c2VkIHRvIG1ha2UKKyAgICAgKiB0aGUgY29ubmVjdGlvbiwgaW5jbHVkaW5nIHRoZSBwYXNzd29yZC4gPHA+CisgICAgICoKKyAgICAgKiBJZiB0aGUgcGFzc3dvcmQgcGFzc2VkIGluIGlzIG51bGwgYW5kIHRoaXMgaXMgdGhlIGZpcnN0IHN1Y2Nlc3NmdWwKKyAgICAgKiBjb25uZWN0aW9uIHRvIHRoaXMgc3RvcmUsIHRoZSB1c2VyIG5hbWUgYW5kIHRoZSBwYXNzd29yZAorICAgICAqIGNvbGxlY3RlZCBmcm9tIHRoZSB1c2VyIHdpbGwgYmUgc2F2ZWQgYXMgZGVmYXVsdHMgZm9yIHN1YnNlcXVlbnQKKyAgICAgKiBjb25uZWN0aW9uIGF0dGVtcHRzIHRvIHRoaXMgc2FtZSBzdG9yZS4gIElmIHRoZSBwYXNzd29yZCBwYXNzZWQKKyAgICAgKiBpbiBpcyBub3QgbnVsbCwgaXQgaXMgbm90IHNhdmVkLCBvbiB0aGUgYXNzdW1wdGlvbiB0aGF0IHRoZSAKKyAgICAgKiBhcHBsaWNhdGlvbiBpcyBtYW5hZ2luZyBwYXNzd29yZHMgZXhwbGljaXRseS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBob3N0IAl0aGUgaG9zdCB0byBjb25uZWN0IHRvCisgICAgICogQHBhcmFtIHVzZXIJdGhlIHVzZXIgbmFtZQorICAgICAqIEBwYXJhbSBwYXNzd29yZAl0aGlzIHVzZXIncyBwYXNzd29yZAorICAgICAqIEBleGNlcHRpb24gQXV0aGVudGljYXRpb25GYWlsZWRFeGNlcHRpb24JZm9yIGF1dGhlbnRpY2F0aW9uIGZhaWx1cmVzCisgICAgICogQGV4Y2VwdGlvbiBNZXNzYWdpbmdFeGNlcHRpb24JCWZvciBvdGhlciBmYWlsdXJlcworICAgICAqIEBleGNlcHRpb24gSWxsZWdhbFN0YXRlRXhjZXB0aW9uCWlmIHRoZSBzdG9yZSBpcyBhbHJlYWR5IGNvbm5lY3RlZAorICAgICAqIEBzZWUgamF2YXgubWFpbC5ldmVudC5Db25uZWN0aW9uRXZlbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjb25uZWN0KFN0cmluZyBob3N0LCBTdHJpbmcgdXNlciwgU3RyaW5nIHBhc3N3b3JkKQorCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbgorCitBbmQgYWRkIHRoaXMgbWV0aG9kIHRvIFN0b3JlIGFuZCBUcmFuc3BvcnQ6CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIFVSTE5hbWUgcmVwcmVzZW50aW5nIHRoaXMgc3RvcmUuCisgICAgICogTm9ybWFsbHkgdXNlZCB0byB1cGRhdGUgdGhlIDxjb2RlPnVybDwvY29kZT4gZmllbGQKKyAgICAgKiBhZnRlciBhIHN0b3JlIGhhcyBzdWNjZXNzZnVsbHkgY29ubmVjdGVkLiA8cD4KKyAgICAgKgorICAgICAqIFN1YmNsYXNzZXMgc2hvdWxkIG9ubHkgb3ZlcnJpZGUgdGhpcyBtZXRob2QgaWYgdGhlaXIKKyAgICAgKiBVUkxOYW1lIGRvZXMgbm90IGZvbGxvdyB0aGUgc3RhbmRhcmQgZm9ybWF0LiA8cD4KKyAgICAgKgorICAgICAqIFRoZSBpbXBsZW1lbnRhdGlvbiBpbiB0aGUgU3RvcmUgY2xhc3Mgc2ltcGx5IHNldHMgdGhlCisgICAgICogPGNvZGU+dXJsPC9jb2RlPiBmaWVsZC4KKyAgICAgKgorICAgICAqIEBzZWUgVVJMTmFtZQorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHNldFVSTE5hbWUoVVJMTmFtZSB1cmwpCisKK0FuZCBmaW5hbGx5LCB0byBzaW1wbGlmeSB0aGUgaW1wbGVtZW50YXRpb24gb2YgU3RvcmUgYW5kIFRyYW5zcG9ydCwKK2FuZCBtYWtlIHRoZSBjb21tb24gZGVzaWduIHBhdHRlcm5zIGJldHdlZW4gdGhlbSBtb3JlIGNsZWFyLCB3ZSdyZQorY29uc2lkZXJpbmcgaW50cm9kdWNpbmcgYSBuZXcgU2VydmljZSBjbGFzcyBhcyBhIHN1cGVyY2xhc3Mgb2YKK1N0b3JlIGFuZCBUcmFuc3BvcnQsIGFuZCBtb3ZpbmcgYWxsIGNvbW1vbiBtZXRob2RzICh0aGUgdmFyaW91cworY29ubm5lY3QgbWV0aG9kcywgVVJMTmFtZSBtZXRob2RzLCBhbmQgc29tZSBsaXN0ZW5lciBtZXRob2RzKSB0bwordGhlIHN1cGVyY2xhc3MuICBOb3RlIHRoYXQgdGhpcyBpcyBhIGJpbmFyeSBjb21wYXRpYmxlIGNoYW5nZS4KKworPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKzEyKSBOZXcgU2VydmljZSBjbGFzcworPT09PT09PT09PT09PT09PT09PT09PQorCitUbyBlbXBoYXNpemUgdGhlIGNvbW1vbmFsaXR5IGluIGJlaGF2aW9yIGJldHdlZW4gdGhlIFN0b3JlIGFuZAorVHJhbnNwb3J0IGNsYXNzZXMsIGFuZCB0byBzaW1wbGlmeSBtYWludGVuYW5jZSBvZiB0aGVzZSBjbGFzc2VzLCB3ZQorcHJvcG9zZSBtb3ZpbmcgbWFueSBvZiB0aGUgY29tbW9uIG1ldGhvZHMgdG8gYSBuZXcgc3VwZXJjbGFzcyBjYWxsZWQKK2phdmF4Lm1haWwuU2VydmljZS4gIFN0b3JlIGFuZCBUcmFuc3BvcnQgd291bGQgdGhlbiBleHRlbmQgU2VydmljZS4KK1RoZXNlIGV4aXN0aW5nIG1ldGhvZHMgY3VycmVudGx5IGhhdmUgaWRlbnRpY2FsIGltcGxlbWVudGF0aW9ucyBpbiB0aGUKK1N0b3JlIGFuZCBUcmFuc3BvcnQgY2xhc3NlcyBzbyBtb3ZpbmcgdGhlbSB0byBhIGNvbW1vbiBzdXBlcmNsYXNzIHdpbGwKK25vdCBjaGFuZ2UgdGhlIGJlaGF2aW9yIG9mIGVpdGhlciBTdG9yZSBvciBUcmFuc3BvcnQuCisKK1RoZSBTZXJ2aWNlIGNsYXNzIHdpbGwgY29udGFpbiBhbGwgdGhlIG1ldGhvZHMgYW5kIGZpZWxkcyBoYXZpbmcgdG8gZG8KK3dpdGggY29ubmVjdGluZywgY29ubmVjdGlvbiBsaXN0ZW5lcnMsIGFuZCBuYW1pbmcgdmlhIFVSTE5hbWVzLiAgVGhlCitTdG9yZSBjbGFzcyByZXRhaW5zIHRoZSBtZXRob2RzIGZvciBnZXR0aW5nIEZvbGRlcnMgYW5kIG1hbmFnaW5nIFN0b3JlCithbmQgRm9sZGVyIGxpc3RlbmVycy4gIFRoZSBUcmFuc3BvcnQgY2xhc3MgcmV0YWlucyB0aGUgbWV0aG9kcyBmb3IKK3NlbmRpbmcgbWVzc2FnZXMgYW5kIG1hbmFnaW5nIFRyYW5zcG9ydCBsaXN0ZW5lcnMuCisKK05vdGUgdGhhdCB0aGlzIGlzIGEgYmluYXJ5IGNvbXBhdGlibGUgY2hhbmdlIGJvdGggZm9yIGV4aXN0aW5nIHVzZXJzIG9mCit0aGUgU3RvcmUgYW5kIFRyYW5zcG9ydCBjbGFzc2VzLCBhcyB3ZWxsIGFzIGZvciBleGlzdGluZyBzdWJjbGFzc2VzIG9mCit0aGVzZSBjbGFzc2VzLgorCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CmRpZmYgLS1naXQgYS9kb2Mvc3BlYy9KYXZhTWFpbC0xLjItY2hhbmdlcy50eHQgYi9kb2Mvc3BlYy9KYXZhTWFpbC0xLjItY2hhbmdlcy50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGM2NGYwOAotLS0gL2Rldi9udWxsCisrKyBiL2RvYy9zcGVjL0phdmFNYWlsLTEuMi1jaGFuZ2VzLnR4dApAQCAtMCwwICsxLDEwMjIgQEAKKworCQlKYXZhTWFpbCAxLjIKKwkJPT09PT09PT09PT09CisKK0ZvbGxvd2luZyBpcyBhIGRlc2NyaXB0aW9uIG9mIHRoZSBuZXcgQVBJcyB0aGF0IGFyZSBiZWluZworaW50cm9kdWNlZCBpbiBKYXZhTWFpbCAxLjIuICBUaGUgbnVtYmVycyBpbiBwYXJlbnRoZXNlcworYXJlIGJ1ZyBudW1iZXJzOyB5b3UgY2FuIGZpbmQgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUKK2J1ZyByZXBvcnRzIGF0OgorCisgICAgaHR0cDovL2RldmVsb3Blci5qYXZhLnN1bi5jb20vZGV2ZWxvcGVyL2J1Z1BhcmFkZS9pbmRleC5odG1sCisKK1BsZWFzZSBzZW5kIGNvbW1lbnRzIGFuZCBmZWVkYmFjayB0byBqYXZhbWFpbEBzdW4uY29tLgorCisKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworMS4gTmV3IHByb3RlY3RlZCBmaWVsZCBhbmQgbWV0aG9kcyAoNDEyOTc0MykKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK1RvIHNpbXBsaWZ5IGNyZWF0aW5nIHN1YmNsYXNzZXMgb2YgTWltZU1lc3NhZ2UsIHRoZSBmb2xsb3dpbmcKK2ZpZWxkIGFuZCBtZXRob2QgdGhhdCB3ZXJlIHByZXZpb3VzbHkgcHJpdmF0ZSBhcmUgbm93IHByb3RlY3RlZDoKKworICAgIC8qKgorICAgICAqIEEgZmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIG1lc3NhZ2UgaGFzIGJlZW4gbW9kaWZpZWQuCisgICAgICogSWYgdGhlIG1lc3NhZ2UgaGFzIG5vdCBiZWVuIG1vZGlmaWVkLCBhbnkgZGF0YSBpbiB0aGUKKyAgICAgKiA8Y29kZT5jb250ZW50PC9jb2RlPiBhcnJheSBpcyBhc3N1bWVkIHRvIGJlIHZhbGlkIGFuZCBpcyB1c2VkCisgICAgICogZGlyZWN0bHkgaW4gdGhlIDxjb2RlPndyaXRlVG88L2NvZGU+IG1ldGhvZC4gIFRoaXMgZmxhZyBpcworICAgICAqIHNldCB0byB0cnVlIHdoZW4gYW4gZW1wdHkgbWVzc2FnZSBpcyBjcmVhdGVkIG9yIHdoZW4gdGhlCisgICAgICogPGNvZGU+c2F2ZUNoYW5nZXM8L2NvZGU+IG1ldGhvZCBpcyBjYWxsZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gbW9kaWZpZWQgPSBmYWxzZTsKKworICAgIC8qKgorICAgICAqIFBhcnNlIHRoZSBJbnB1dFN0cmVhbSBzZXR0aW5nIHRoZSA8Y29kZT5oZWFkZXJzPC9jb2RlPiBhbmQKKyAgICAgKiA8Y29kZT5jb250ZW50PC9jb2RlPiBmaWVsZHMgYXBwcm9wcmlhdGVseS4gIEFsc28gcmVzZXRzIHRoZQorICAgICAqIDxjb2RlPm1vZGlmaWVkPC9jb2RlPiBmbGFnLiA8cD4KKyAgICAgKgorICAgICAqIFRoaXMgbWV0aG9kIGlzIGludGVuZGVkIGZvciB1c2UgYnkgc3ViY2xhc3NlcyB0aGF0IG5lZWQgdG8KKyAgICAgKiBjb250cm9sIHdoZW4gdGhlIElucHV0U3RyZWFtIGlzIHBhcnNlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpcyAgICAgICAgVGhlIG1lc3NhZ2UgaW5wdXQgc3RyZWFtCisgICAgICogQGV4Y2VwdGlvbiAgICAgICBNZXNzYWdpbmdFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBwYXJzZShJbnB1dFN0cmVhbSBpcykgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbgorCisKK1RoZSBqYXZhZG9jcyBmb3IgdGhlIGZvbGxvd2luZyBleHN0aW5nIG1ldGhvZHMgaGF2ZSBiZWVuIHVwZGF0ZWQgdG8KK2Rlc2NyaWJlIHRoZSB1c2Ugb2YgdGhlIG1vZGlmaWVkIGZsYWc6CisKKyAgICAvKioKKyAgICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiBBbiBlbXB0eSBtZXNzYWdlIG9iamVjdCBpcyBjcmVhdGVkLgorICAgICAqIFRoZSA8Y29kZT5oZWFkZXJzPC9jb2RlPiBmaWVsZCBpcyBzZXQgdG8gYW4gZW1wdHkgSW50ZXJuZXRIZWFkZXJzCisgICAgICogb2JqZWN0LiBUaGUgPGNvZGU+ZmxhZ3M8L2NvZGU+IGZpZWxkIGlzIHNldCB0byBhbiBlbXB0eSBGbGFncworICAgICAqIG9iamVjdC4gVGhlIDxjb2RlPm1vZGlmaWVkPC9jb2RlPiBmbGFnIGlzIHNldCB0byB0cnVlLgorICAgICAqLworICAgIHB1YmxpYyBNaW1lTWVzc2FnZShTZXNzaW9uIHNlc3Npb24pCisKKyAgICAvKioKKyAgICAgKiBPdXRwdXQgdGhlIG1lc3NhZ2UgYXMgYW4gUkZDIDgyMiBmb3JtYXQgc3RyZWFtLCB3aXRob3V0CisgICAgICogc3BlY2lmaWVkIGhlYWRlcnMuICBJZiB0aGUgPGNvZGU+bW9kaWZpZWQ8L2NvZGU+IGZsYWcgaXMgbm90CisgICAgICogc2V0IGFuZCB0aGUgPGNvZGU+Y29udGVudDwvY29kZT4gYXJyYXkgaXMgbm90IG51bGwsIHRoZQorICAgICAqIDxjb2RlPmNvbnRlbnQ8L2NvZGU+IGFycmF5IGlzIHdyaXR0ZW4gZGlyZWN0bHksIGFmdGVyCisgICAgICogd3JpdGluZyB0aGUgYXBwcm9wcmlhdGUgbWVzc2FnZSBoZWFkZXJzLgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbiBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorICAgICAqIEBleGNlcHRpb24gSU9FeGNlcHRpb24gICBpZiBhbiBlcnJvciBvY2N1cnMgd3JpdGluZyB0byB0aGUgc3RyZWFtCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIG9yIGlmIGFuIGVycm9yIGlzIGdlbmVyYXRlZCBieSB0aGUKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgamF2YXguYWN0aXZhdGlvbiBsYXllci4KKyAgICAgKiBAc2VlIGphdmF4LmFjdGl2YXRpb24uRGF0YUhhbmRsZXIjd3JpdGVUbworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oT3V0cHV0U3RyZWFtIG9zLCBTdHJpbmdbXSBpZ25vcmVMaXN0KQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIE1lc3NhZ2luZ0V4Y2VwdGlvbgorCisgICAgLyoqCisgICAgICogVXBkYXRlcyB0aGUgYXBwcm9wcmlhdGUgaGVhZGVyIGZpZWxkcyBvZiB0aGlzIG1lc3NhZ2UgdG8gYmUKKyAgICAgKiBjb25zaXN0ZW50IHdpdGggdGhlIG1lc3NhZ2UncyBjb250ZW50cy4gSWYgdGhpcyBtZXNzYWdlIGlzCisgICAgICogY29udGFpbmVkIGluIGEgRm9sZGVyLCBhbnkgY2hhbmdlcyBtYWRlIHRvIHRoaXMgbWVzc2FnZSBhcmUKKyAgICAgKiBjb21taXR0ZWQgdG8gdGhlIGNvbnRhaW5pbmcgZm9sZGVyLiA8cD4KKyAgICAgKgorICAgICAqIElmIGFueSBwYXJ0IG9mIGEgbWVzc2FnZSdzIGhlYWRlcnMgb3IgY29udGVudHMgYXJlIGNoYW5nZWQsCisgICAgICogPGNvZGU+c2F2ZUNoYW5nZXM8L2NvZGU+IG11c3QgYmUgY2FsbGVkIHRvIGVuc3VyZSB0aGF0IHRob3NlCisgICAgICogY2hhbmdlcyBhcmUgcGVybWFuZW50LiBPdGhlcndpc2UsIGFueSBzdWNoIG1vZGlmaWNhdGlvbnMgbWF5IG9yCisgICAgICogbWF5IG5vdCBiZSBzYXZlZCwgZGVwZW5kaW5nIG9uIHRoZSBmb2xkZXIgaW1wbGVtZW50YXRpb24uIDxwPgorICAgICAqCisgICAgICogTWVzc2FnZXMgb2J0YWluZWQgZnJvbSBmb2xkZXJzIG9wZW5lZCBSRUFEX09OTFkgc2hvdWxkIG5vdCBiZQorICAgICAqIG1vZGlmaWVkIGFuZCBzYXZlQ2hhbmdlcyBzaG91bGQgbm90IGJlIGNhbGxlZCBvbiBzdWNoIG1lc3NhZ2VzLiA8cD4KKyAgICAgKgorICAgICAqIFRoaXMgbWV0aG9kIHNldHMgdGhlIDxjb2RlPm1vZGlmaWVkPC9jb2RlPiBmbGFnIHRvIHRydWUgYW5kIHRoZW4KKyAgICAgKiBjYWxscyB0aGUgPGNvZGU+dXBkYXRlSGVhZGVyczxjb2RlPiBtZXRob2QuCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIElsbGVnYWxXcml0ZUV4Y2VwdGlvbiBpZiB0aGUgdW5kZXJseWluZworICAgICAqICAgICAgICAgICAgICAgICAgaW1wbGVtZW50YXRpb24gZG9lcyBub3Qgc3VwcG9ydCBtb2RpZmljYXRpb24KKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIG1lc3NhZ2UgaXMKKyAgICAgKiAgICAgICAgICAgICAgICAgIG9idGFpbmVkIGZyb20gYSBSRUFEX09OTFkgZm9sZGVyLgorICAgICAqIEBleGNlcHRpb24gICAgICAgTWVzc2FnaW5nRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2F2ZUNoYW5nZXMoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uCisKK1RoZSBmb2xsb3dpbmcgbWV0aG9kIGlzIGFkZGVkIHRvIE1pbWVNZXNzYWdlOgorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGFuZCByZXR1cm4gYW4gSW50ZXJuZXRIZWFkZXJzIG9iamVjdCB0aGF0IGxvYWRzIHRoZQorICAgICAqIGhlYWRlcnMgZnJvbSB0aGUgZ2l2ZW4gSW5wdXRTdHJlYW0uICBTdWJjbGFzc2VzIGNhbiBvdmVycmlkZQorICAgICAqIHRoaXMgbWV0aG9kIHRvIHJldHVybiBhIHN1YmNsYXNzIG9mIEludGVybmV0SGVhZGVycywgaWYKKyAgICAgKiBuZWNlc3NhcnkuICBUaGlzIGltcGxlbWVudGF0aW9uIHNpbXBseSBjb25zdHJ1Y3RzIGFuZCByZXR1cm5zIAorICAgICAqIGFuIEludGVybmV0SGVhZGVycyBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gICBpcyAgICAgIHRoZSBJbnB1dFN0cmVhbSB0byByZWFkIHRoZSBoZWFkZXJzIGZyb20KKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIE1lc3NhZ2luZ0V4Y2VwdGlvbgorICAgICAqLworICAgIHByb3RlY3RlZCBJbnRlcm5ldEhlYWRlcnMgY3JlYXRlSW50ZXJuZXRIZWFkZXJzKElucHV0U3RyZWFtIGlzKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uCisKK0xpa2V3aXNlLCB0byBzaW1wbGlmeSBjcmVhdGluZyBzdWJjbGFzc2VzIG9mIE1pbWVNdWx0aXBhcnQsIHRoZSBwYXJzZQorbWV0aG9kIGlzIG1hZGUgcHJvdGVjdGVkOgorCisgICAgLyoqCisgICAgICogUGFyc2UgdGhlIElucHV0U3RyZWFtIGZyb20gb3VyIERhdGFTb3VyY2UsIGNvbnN0cnVjdGluZyB0aGUKKyAgICAgKiBhcHByb3ByaWF0ZSBNaW1lQm9keVBhcnRzLiAgVGhlIDxjb2RlPnBhcnNlZDwvY29kZT4gZmxhZyBpcworICAgICAqIHNldCB0byB0cnVlLCBhbmQgaWYgdHJ1ZSBvbiBlbnRyeSBub3RoaW5nIGlzIGRvbmUuICBUaGlzCisgICAgICogbWV0aG9kIGlzIGNhbGxlZCBieSBhbGwgb3RoZXIgbWV0aG9kcyB0aGF0IG5lZWQgZGF0YSBmb3IKKyAgICAgKiB0aGUgYm9keSBwYXJ0cywgdG8gbWFrZSBzdXJlIHRoZSBkYXRhIGhhcyBiZWVuIHBhcnNlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3luY2hyb25pemVkIHZvaWQgcGFyc2UoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uCisKK2FuZCB0aGUgZm9sbG93aW5nIHByb3RlY3RlZCBtZXRob2RzIGFyZSBhZGRlZDoKKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhbmQgcmV0dXJuIGFuIEludGVybmV0SGVhZGVycyBvYmplY3QgdGhhdCBsb2FkcyB0aGUKKyAgICAgKiBoZWFkZXJzIGZyb20gdGhlIGdpdmVuIElucHV0U3RyZWFtLiAgU3ViY2xhc3NlcyBjYW4gb3ZlcnJpZGUKKyAgICAgKiB0aGlzIG1ldGhvZCB0byByZXR1cm4gYSBzdWJjbGFzcyBvZiBJbnRlcm5ldEhlYWRlcnMsIGlmCisgICAgICogbmVjZXNzYXJ5LiAgVGhpcyBpbXBsZW1lbnRhdGlvbiBzaW1wbHkgY29uc3RydWN0cyBhbmQgcmV0dXJucworICAgICAqIGFuIEludGVybmV0SGVhZGVycyBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gICBpcyAgICAgIHRoZSBJbnB1dFN0cmVhbSB0byByZWFkIHRoZSBoZWFkZXJzIGZyb20KKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIE1lc3NhZ2luZ0V4Y2VwdGlvbgorICAgICAqLworICAgIHByb3RlY3RlZCBJbnRlcm5ldEhlYWRlcnMgY3JlYXRlSW50ZXJuZXRIZWFkZXJzKElucHV0U3RyZWFtIGlzKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uCisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYW5kIHJldHVybiBhIE1pbWVCb2R5UGFydCBvYmplY3QgdG8gcmVwcmVzZW50IGEKKyAgICAgKiBib2R5IHBhcnQgcGFyc2VkIGZyb20gdGhlIElucHV0U3RyZWFtLiAgU3ViY2xhc3NlcyBjYW4gb3ZlcnJpZGUKKyAgICAgKiB0aGlzIG1ldGhvZCB0byByZXR1cm4gYSBzdWJjbGFzcyBvZiBNaW1lQm9keVBhcnQsIGlmCisgICAgICogbmVjZXNzYXJ5LiAgVGhpcyBpbXBsZW1lbnRhdGlvbiBzaW1wbHkgY29uc3RydWN0cyBhbmQgcmV0dXJucworICAgICAqIGEgTWltZUJvZHlQYXJ0IG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSAgIGhlYWRlcnMgICAgICAgICB0aGUgaGVhZGVycyBmb3IgdGhlIGJvZHkgcGFydAorICAgICAqIEBwYXJhbSAgIGNvbnRlbnQgICAgICAgICB0aGUgY29udGVudCBvZnRoZSBib2R5IHBhcnQKKyAgICAgKiBAZXhjZXB0aW9uICAgICAgICAgICAgICAgTWVzc2FnaW5nRXhjZXB0aW9uCisgICAgICovCisgICAgcHJvdGVjdGVkIE1pbWVCb2R5UGFydCBjcmVhdGVNaW1lQm9keVBhcnQoSW50ZXJuZXRIZWFkZXJzIGhlYWRlcnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVbXSBjb250ZW50KSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uCisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYW5kIHJldHVybiBhIE1pbWVCb2R5UGFydCBvYmplY3QgdG8gcmVwcmVzZW50IGEKKyAgICAgKiBib2R5IHBhcnQgcGFyc2VkIGZyb20gdGhlIElucHV0U3RyZWFtLiAgU3ViY2xhc3NlcyBjYW4gb3ZlcnJpZGUKKyAgICAgKiB0aGlzIG1ldGhvZCB0byByZXR1cm4gYSBzdWJjbGFzcyBvZiBNaW1lQm9keVBhcnQsIGlmCisgICAgICogbmVjZXNzYXJ5LiAgVGhpcyBpbXBsZW1lbnRhdGlvbiBzaW1wbHkgY29uc3RydWN0cyBhbmQgcmV0dXJucworICAgICAqIGEgTWltZUJvZHlQYXJ0IG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbQlpcwkJSW5wdXRTdHJlYW0gY29udGFpbmluZyB0aGUgYm9keSBwYXJ0CisgICAgICogQGV4Y2VwdGlvbiAgCQlNZXNzYWdpbmdFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgTWltZUJvZHlQYXJ0IGNyZWF0ZU1pbWVCb2R5UGFydChJbnB1dFN0cmVhbSBpcykKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uCisKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworMi4gTWltZU1lc3NhZ2UgYW5kIE1pbWVCb2R5UGFydCBnZXRSYXdJbnB1dFN0cmVhbSBtZXRob2QgKDQxMjQ4NDApCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworSW4gc29tZSBjYXNlcyBpdCBpcyBkZXNpcmFibGUgdG8gZ2V0IHRoZSBkYXRhIGZvciBhIGJvZHkgcGFydAorYmVmb3JlIEphdmFNYWlsIGF0dGVtcHRzIHRvIGRlY29kZSBpdC4gIFRoaXMgaXMgcGFydGljdWxhcmx5IGltcG9ydGFudAoraWYgdGhlIENvbnRlbnQtVHJhbnNmZXItRW5jb2RpbmcgaGVhZGVyIGlzIGluY29ycmVjdC4gIChGb3IgZXhhbXBsZSwKK3NvbWUgbWFpbCBzb2Z0d2FyZSBpcyBrbm93biB0byB1c2UgIjctYml0IiBpbnN0ZWFkIG9mIHRoZSBNSU1FCitkZWZpbmVkICI3Yml0Ii4pICBBY2Nlc3MgdG8gdGhpcyBkYXRhIGlzIGN1cnJlbnRseSBwcm92aWRlZAordGhyb3VnaCB0aGUgcHJvdGVjdGVkIGdldENvbnRlbnRTdHJlYW0gbWV0aG9kLiAgU2luY2Ugc2ltcGx5CittYWtpbmcgdGhpcyBtZXRob2QgcHVibGljIGhhcyB0aGUgcG90ZW50aWFsIHRvIGNhdXNlIGEgc291cmNlCitpbmNvbXBhdGliaWxpdHkgZm9yIGFueSBzdWJjbGFzc2VzIHRoYXQgZGVjbGFyZSB0aGlzIG1ldGhvZCBhcworcHJvdGVjdGVkLCB3ZSBpbnN0ZWFkIGFkZCBhIG5ldyBwdWJsaWMgbWV0aG9kIHRoYXQgY2FsbHMgdGhpcworcHJvdGVjdGVkIG1ldGhvZDoKKworICAgIC8qKgorICAgICAqIFJldHVybiBhbiBJbnB1dFN0cmVhbSB0byB0aGUgcmF3IGRhdGEgd2l0aCBhbnkgQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZworICAgICAqIGludGFjdC4gIFRoaXMgbWV0aG9kIGlzIHVzZWZ1bCBpZiB0aGUgIkNvbnRlbnQtVHJhbnNmZXItRW5jb2RpbmciCisgICAgICogaGVhZGVyIGlzIGluY29ycmVjdCBvciBjb3JydXB0LCB3aGljaCB3b3VsZCBwcmV2ZW50IHRoZQorICAgICAqIDxjb2RlPmdldElucHV0U3RyZWFtPC9jb2RlPiBtZXRob2Qgb3IgPGNvZGU+Z2V0Q29udGVudDwvY29kZT4gbWV0aG9kCisgICAgICogZnJvbSByZXR1cm5pbmcgdGhlIGNvcnJlY3QgZGF0YS4gIEluIHN1Y2ggYSBjYXNlIHRoZSBhcHBsaWNhdGlvbiBtYXkKKyAgICAgKiB1c2UgdGhpcyBtZXRob2QgYW5kIGF0dGVtcHQgdG8gZGVjb2RlIHRoZSByYXcgZGF0YSBpdHNlbGYuIDxwPgorICAgICAqCisgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiBzaW1wbHkgY2FsbHMgdGhlIDxjb2RlPmdldENvbnRlbnRTdHJlYW08L2NvZGU+CisgICAgICogbWV0aG9kLgorICAgICAqCisgICAgICogQHNlZSAjZ2V0SW5wdXRTdHJlYW0KKyAgICAgKiBAc2VlICNnZXRDb250ZW50U3RyZWFtCisgICAgICovCisgICAgcHVibGljIElucHV0U3RyZWFtIGdldFJhd0lucHV0U3RyZWFtKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbgorCisKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworMy4gUmVhZE9ubHlGb2xkZXJFeGNlcHRpb24gKDQxNjMzNjApCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworQSBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uIHN1YmNsYXNzIHRvIGluZGljYXRlIGEgcmVhZC1vbmx5IGZvbGRlcgoraXMgbmVlZGVkLgorCitDdXJyZW50bHksIGlmIGEgY2xpZW50IGF0dGVtcHRzIHRvIG9wZW4gYSBmb2xkZXIgaW4gcmVhZC13cml0ZSBtb2RlCithbmQgdGhlIGZvbGRlciBpcyByZWFkLW9ubHksIGEgTWVzc2FnaW5nRXhjZXB0aW9uIGlzIHRocm93bi4gVGhpcworZXhjZXB0aW9uIHR5cGUgZG9lcyBub3QgaW5kaWNhdGUgdGhhdCB0aGUgYW5vbWFseSB3YXMgY2F1c2VkIGR1ZSB0bwordGhlIGxhY2sgb2Ygd3JpdGUtcGVybWlzc2lvbnMuCisKKy8qKgorICogVGhpcyBleGNlcHRpb24gaXMgdGhyb3duIHdoZW4gYW4gYXR0ZW1wdCBpcyBtYWRlIHRvIG9wZW4gYSBmb2xkZXIKKyAqIHdpdGggcmVhZC13cml0ZSBhY2Nlc3Mgd2hlbiB0aGUgZm9sZGVyIGlzIG1hcmtlZCByZWFkLW9ubHkuIDxwPgorICovCisKK3B1YmxpYyBjbGFzcyBSZWFkT25seUZvbGRlckV4Y2VwdGlvbiBleHRlbmRzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAgKiBAcGFyYW0gZm9sZGVyICAgIHRoZSBGb2xkZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgUmVhZE9ubHlGb2xkZXJFeGNlcHRpb24oRm9sZGVyIGZvbGRlcikKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yLgorICAgICAqIEBwYXJhbSBmb2xkZXIgICAgdGhlIEZvbGRlcgorICAgICAqIEBwYXJhbSBtZXNzYWdlICAgdGhlIGRldGFpbGVkIGVycm9yIG1lc3NhZ2UKKyAgICAgKi8KKyAgICBwdWJsaWMgUmVhZE9ubHlGb2xkZXJFeGNlcHRpb24oRm9sZGVyIGZvbGRlciwgU3RyaW5nIG1lc3NhZ2UpCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBGb2xkZXIgb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyBGb2xkZXIgZ2V0Rm9sZGVyKCkKK30gCisKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworNC4gSW50ZXJuZXRBZGRyZXNzIGltcGxlbWVudHMgQ2xvbmVhYmxlICg0MTgxMTQ0KQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitUbyBzaW1wbGlmeSBjb3B5aW5nIG9mIEludGVybmV0QWRkcmVzcyBvYmplY3RzLCB0aGUgSW50ZXJuZXRBZGRyZXNzCitjbGFzcyB3aWxsIGltcGxlbWVudCB0aGUgQ2xvbmVhYmxlIGludGVyZmFjZSBhbmQgd2lsbCBwcm92aWRlIGEKK3B1YmxpYyBjbG9uZSBtZXRob2QuCisKK3B1YmxpYyBjbGFzcyBJbnRlcm5ldEFkZHJlc3MgZXh0ZW5kcyBBZGRyZXNzIGltcGxlbWVudHMgQ2xvbmVhYmxlIHsKKworICAgIC8qKgorICAgICAqIFJldHVybiBhIGNvcHkgb2YgdGhpcyBJbnRlcm5ldEFkZHJlc3Mgb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKQorfQorCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKzUuIE1pbWVNZXNzYWdlIGNvcHkgY29uc3RydWN0b3IgKDQxMDc3NTIpCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitXaGVuIGZvcndhcmRpbmcgb3Igc2F2aW5nIGEgbWVzc2FnZSByZXRyaWV2ZWQgZnJvbSBhIFN0b3JlLCBpdCBpcworc29tZXRpbWVzIGRlc2lyYWJsZSB0byBiZSBhYmxlIHRvIG1vZGlmeSB0aGUgbWVzc2FnZSBmaXJzdC4gIFNpbmNlCittb3N0IFN0b3JlcyBkbyBub3QgYWxsb3cgdGhlaXIgTWVzc2FnZSBvYmplY3RzIHRvIGJlIG1vZGlmaWVkLCB0aGUKK21lc3NhZ2UgbXVzdCBmaXJzdCBiZSBjb3BpZWQuICBUbyBzaW1wbGlmeSBjb3B5aW5nIGEgTWltZU1lc3NhZ2UsCit3ZSBpbnRyb2R1Y2UgYSBjb3B5IGNvbnN0cnVjdG9yIHRoYXQgYWxsb3dzIGEgbmV3IE1pbWVNZXNzYWdlIHRvCitiZSBjcmVhdGVkIGFuZCBpbml0aWFsaXplZCB3aXRoIGEgY29weSBvZiBhbm90aGVyIE1pbWVNZXNzYWdlLgorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBNaW1lTWVzc2FnZSB3aXRoIGNvbnRlbnQgaW5pdGlhbGl6ZWQgZm9ybSB0aGUKKyAgICAgKiA8Y29kZT5zb3VyY2U8L2NvZGU+IE1pbWVNZXNzYWdlLiAgVGhlIG5ldyBtZXNzYWdlIGlzIGluZGVwZW5kZW50CisgICAgICogb2YgdGhlIG9yaWdpbmFsLiA8cD4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gICBzb3VyY2UgIHRoZSBtZXNzYWdlIHRvIGNvcHkgY29udGVudCBmcm9tCisgICAgICogQGV4Y2VwdGlvbiAgICAgICBNZXNzYWdpbmdFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgTWltZU1lc3NhZ2UoTWltZU1lc3NhZ2Ugc291cmNlKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uCisKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworNi4gQXV0aGVudGljYXRpb25GYWlsZWRFeGNlcHRpb24gaW5jbHVkZXMgc2VydmVyIG1lc3NhZ2UgKDQyMzA1NTMpCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworV2hlbiBhdXRoZW50aWNhdGlvbiB3aXRoIGEgc2VydmVyIGZhaWxzLCB0aGUgc2VydmVyIG9mdGVuIHN1cHBsaWVzCitzb21lIGluZm9ybWF0aW9uIGluIGl0cyBwcm90b2NvbCBtZXNzYWdlIHRoYXQgaW5kaWNhdGVzIHRoZSByZWFzb24KK2ZvciB0aGUgZmFpbHVyZS4gIFRvIGFsbG93IGEgc2VydmljZSBwcm92aWRlciB0byByZXR1cm4gdGhpcyBpbmZvcm1hdGlvbgordG8gdGhlIHVzZXIsIHdlIG5vdyBhbGxvdyB0aGUgU2VydmljZS5wcm90b2NvbENvbm5lY3QoKSBtZXRob2QgdG8KK3Rocm93IGFuIEF1dGhlbnRpY2F0aW9uRmFpbGVkRXhjZXB0aW9uIGluIHRoaXMgY2FzZS4gIFRoZSBleGNlcHRpb24KK21heSBjb250YWluIGEgc3RyaW5nIG1lc3NhZ2UgdGhhdCBpbmNsdWRlcyB0aGUgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorZnJvbSB0aGUgc2VydmVyLgorCisgICAgLyoqCisgICAgICogVGhlIHNlcnZpY2UgaW1wbGVtZW50YXRpb24gc2hvdWxkIG92ZXJyaWRlIHRoaXMgbWV0aG9kIHRvCisgICAgICogcGVyZm9ybSB0aGUgYWN0dWFsIHByb3RvY29sLXNwZWNpZmljIGNvbm5lY3Rpb24gYXR0ZW1wdC4KKyAgICAgKiBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgPGNvZGU+Y29ubmVjdDwvY29kZT4gbWV0aG9kCisgICAgICogY2FsbHMgdGhpcyBtZXRob2QgYXMgbmVlZGVkLiA8cD4KKyAgICAgKgorICAgICAqIFRoZSA8Y29kZT5wcm90b2NvbENvbm5lY3Q8L2NvZGU+IG1ldGhvZCBzaG91bGQgcmV0dXJuCisgICAgICogPGNvZGU+ZmFsc2U8L2NvZGU+IGlmIGEgdXNlciBuYW1lIG9yIHBhc3N3b3JkIGlzIHJlcXVpcmVkCisgICAgICogZm9yIGF1dGhlbnRpY2F0aW9uIGJ1dCB0aGUgY29ycmVzcG9uZGluZyBwYXJhbWV0ZXIgaXMgbnVsbDsKKyAgICAgKiB0aGUgPGNvZGU+Y29ubmVjdDwvY29kZT4gbWV0aG9kIHdpbGwgcHJvbXB0IHRoZSB1c2VyIHdoZW4KKyAgICAgKiBuZWVkZWQgdG8gc3VwcGx5IG1pc3NpbmcgaW5mb3JtYXRpb24uICBUaGlzIG1ldGhvZCBtYXkKKyAgICAgKiBhbHNvIHJldHVybiA8Y29kZT5mYWxzZTwvY29kZT4gaWYgYXV0aGVudGljYXRpb24gZmFpbHMgZm9yCisgICAgICogdGhlIHN1cHBsaWVkIHVzZXIgbmFtZSBvciBwYXNzd29yZC4gIEFsdGVybmF0aXZlbHksIHRoaXMgbWV0aG9kCisgICAgICogbWF5IHRocm93IGFuIEF1dGhlbnRpY2F0aW9uRmFpbGVkRXhjZXB0aW9uIHdoZW4gYXV0aGVudGljYXRpb24KKyAgICAgKiBmYWlscy4gIFRoaXMgZXhjZXB0aW9uIG1heSBpbmNsdWRlIGEgU3RyaW5nIG1lc3NhZ2Ugd2l0aCBtb3JlCisgICAgICogZGV0YWlsIGFib3V0IHRoZSBmYWlsdXJlLiA8cD4KKyAgICAgKgorICAgICAqIFRoZSA8Y29kZT5wcm90b2NvbENvbm5lY3Q8L2NvZGU+IG1ldGhvZCBzaG91bGQgdGhyb3cgYW4KKyAgICAgKiBleGNlcHRpb24gdG8gcmVwb3J0IGZhaWx1cmVzIG5vdCByZWxhdGVkIHRvIGF1dGhlbnRpY2F0aW9uLAorICAgICAqIHN1Y2ggYXMgYW4gaW52YWxpZCBob3N0IG5hbWUgb3IgcG9ydCBudW1iZXIsIGxvc3Mgb2YgYQorICAgICAqIGNvbm5lY3Rpb24gZHVyaW5nIHRoZSBhdXRoZW50aWNhdGlvbiBwcm9jZXNzLCB1bmF2YWlsYWJpbGl0eQorICAgICAqIG9mIHRoZSBzZXJ2ZXIsIGV0Yy4KKyAgICAgKgorICAgICAqIEBwYXJhbSAgIGhvc3QgICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgaG9zdCB0byBjb25uZWN0IHRvCisgICAgICogQHBhcmFtICAgcG9ydCAgICAgICAgICAgIHRoZSBwb3J0IHRvIHVzZSAoLTEgbWVhbnMgdXNlIGRlZmF1bHQgcG9ydCkKKyAgICAgKiBAcGFyYW0gICB1c2VyICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHVzZXIgdG8gbG9naW4gYXMKKyAgICAgKiBAcGFyYW0gICBwYXNzd29yZCAgICAgICAgdGhlIHVzZXIncyBwYXNzd29yZAorICAgICAqIEByZXR1cm4gIHRydWUgaWYgY29ubmVjdGlvbiBzdWNjZXNzZnVsLCBmYWxzZSBpZiBhdXRoZW50aWNhdGlvbiBmYWlsZWQKKyAgICAgKiBAZXhjZXB0aW9uIEF1dGhlbnRpY2F0aW9uRmFpbGVkRXhjZXB0aW9uIGZvciBhdXRoZW50aWNhdGlvbiBmYWlsdXJlcworICAgICAqIEBleGNlcHRpb24gTWVzc2FnaW5nRXhjZXB0aW9uICAgIGZvciBub24tYXV0aGVudGljYXRpb24gZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBwcm90b2NvbENvbm5lY3QoU3RyaW5nIGhvc3QsIGludCBwb3J0LCBTdHJpbmcgdXNlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHBhc3N3b3JkKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uCisKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworNy4gU3VwcG9ydCBFU01UUCA4QklUTUlNRSBleHRlbnNpb24gKDQxMzIwMjkpCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworSmF2YU1haWwgY2hvb3NlcyB0aGUgZW5jb2RpbmcgZm9yIGJvZHkgcGFydHMgd2hlbiB0aGUgTWVzc2FnZS5zYXZlQ2hhbmdlcygpCittZXRob2QgaXMgY2FsbGVkLiAgQXQgdGhlIHRpbWUgdGhpcyBtZXRob2QgaXMgY2FsbGVkLCBKYXZhTWFpbCBoYXMgbm8KK2luZm9ybWF0aW9uIGFib3V0IHRoZSBUcmFuc3BvcnQgdGhhdCBtaWdodCBiZSB1c2VkIHRvIHNlbmQgdGhlIG1lc3NhZ2UuCitUaHVzLCBjb21tdW5pY2F0aW5nIHRoZSBUcmFuc3BvcnQncyBjYXBhYmlsaXRpZXMgdG8gdGhlIHBhcnQgb2YgSmF2YU1haWwKK3RoYXQgY2hvb3NlcyBib2R5IHBhcnQgZW5jb2RpbmdzIGlzIHByb2JsZW1hdGljLgorCitUbyBwcm92aWRlIHNvbWUgbWluaW1hbCBzdXBwb3J0IGZvciB0aGUgOEJJVE1JTUUgZXh0ZW5zaW9uLCB0aGUgU01UUAorcHJvdG9jb2wgcHJvdmlkZXIgaXMgZXh0ZW5kZWQgaW4gdGhlIGZvbGxvd2luZyB3YXkuICBOb3RlIHRoYXQgdGhpcworY2FwYWJpbGl0eSBpcyBwYXJ0IG9mIFN1bidzIFNNVFAgcHJvdG9jb2wgcHJvdmlkZXIsIGFuZCBpcyAqbm90KiBhCitwYXJ0IG9mIHRoZSBKYXZhTWFpbCBBUEkgc3BlYy4gIFdlIGluY2x1ZGUgaXQgaGVyZSBmb3IgY29udmVuaWVuY2Ugb25seS4KKworSWYgdGhlIHByb3BlcnR5ICJtYWlsLnNtdHAuYWxsb3c4Yml0bWltZSIgaXMgc2V0IHRvICJ0cnVlIiwgYW5kIHRoZQorU01UUCBzZXJ2ZXIgc3VwcG9ydHMgdGhlIDhCSVRNSU1FIGV4dGVuc2lvbiwgdGhlIFNNVFAgVHJhbnNwb3J0IHdpbGwKK3RyYXZlcnNlIHRoZSBtZXNzYWdlIGFuZCBhZGp1c3QgdGhlIENvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmcgb2YgdGV4dAorYm9keSBwYXJ0cyBmcm9tICJxdW90ZWQtcHJpbnRhYmxlIiBvciAiYmFzZTY0IiB0byAiOGJpdCIgYXMgYXBwcm9wcmlhdGUuCisKK05vdGUgdGhhdCBpZiB0aGUgc2FtZSBtZXNzYWdlIGlzIHN1YnNlcXVlbnRseSBzZW50IG92ZXIgYSBUcmFuc3BvcnQKK29yIHRvIGEgc2VydmVyIHRoYXQgZG9lcyBub3Qgc3VwcG9ydCA4Yml0IE1JTUUsIHRoZSBtZXNzYWdlIHdpbGwgKm5vdCoKK2JlIGNvbnZlcnRlZCBiYWNrIHRvIGEgbm9uLThiaXQgZW5jb2RpbmcuICBOb3JtYWxseSB0aGlzIHdpbGwgbm90IGJlIGEKK3Byb2JsZW0uICBOb3RlIGFsc28gdGhhdCBhIG1lc3NhZ2UgdXNpbmcgIjhiaXQiIGVuY29kaW5nIGNhbiBiZSBzYWZlbHkKK2FwcGVuZGVkIHRvIGFuIElNQVAgZm9sZGVyLgorCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKzguIE1ha2UgTWFpbERhdGVGb3JtYXQgY2xhc3MgcHVibGljICg0MjY2MzkwKQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0l0IHdvdWxkIGJlIHVzZWZ1bCB0byBoYXZlIHRoZSBNYWlsRGF0ZUZvcm1hdCBjbGFzcyBhdmFpbGFibGUgYXMgcGFydAorb2YgdGhlIGphdmF4Lm1haWwuaW50ZXJuZXQgcGFja2FnZSB0byBhbGxvdyBwYXJzaW5nIGFuZCBmb3JtYXR0aW5nCitkYXRlcyBpbiBvdGhlciBNSU1FIGhlYWRlcnMuCisKKy8qKgorICogRm9ybWF0cyBhbmQgcGFyc2VzIGRhdGUgc3BlY2lmaWNhdGlvbiBiYXNlZCBvbiB0aGUKKyAqIGRyYWZ0LWlldGYtZHJ1bXMtbXNnLWZtdC0wOCBkYXRlZCBKYW51YXJ5IDI2LCAyMDAwLiBUaGlzIGlzIGEgZm9sbG93dXAKKyAqIHNwZWMgdG8gUkZDODIyLjxwPgorICoKKyAqIFRoaXMgY2xhc3MgZG9lcyBub3QgdGFrZSBwYXR0ZXJuIHN0cmluZ3MuIEl0IGFsd2F5cyBmb3JtYXRzIHRoZQorICogZGF0ZSBiYXNlZCBvbiB0aGUgc3BlY2lmaWNhdGlvbiBiZWxvdy48cD4KKyAqCisgKiAzLjMgRGF0ZSBhbmQgVGltZSBTcGVjaWZpY2F0aW9uPHA+CisgKgorICogRGF0ZSBhbmQgdGltZSBvY2N1ciBpbiBzZXZlcmFsIGhlYWRlciBmaWVsZHMgb2YgYSBtZXNzYWdlLiBUaGlzIHNlY3Rpb24KKyAqIHNwZWNpZmllcyB0aGUgc3ludGF4IGZvciBhIGZ1bGwgZGF0ZSBhbmQgdGltZSBzcGVjaWZpY2F0aW9uLiBUaG91Z2ggZm9sZGluZworICogd2hpdGVzcGFjZSBpcyBwZXJtaXR0ZWQgdGhyb3VnaG91dCB0aGUgZGF0ZS10aW1lIHNwZWNpZmljYXRpb24sIGl0IGlzCisgKiByZWNvbW1lbmRlZCB0aGF0IG9ubHkgYSBzaW5nbGUgc3BhY2UgYmUgdXNlZCB3aGVyZSBGV1MgaXMgcmVxdWlyZWQgYW5kIG5vCisgKiBzcGFjZSBiZSB1c2VkIHdoZXJlIEZXUyBpcyBvcHRpb25hbCBpbiB0aGUgZGF0ZS10aW1lIHNwZWNpZmljYXRpb247IHNvbWUKKyAqIG9sZGVyIGltcGxlbWVudGF0aW9ucyBtYXkgbm90IGludGVycHJldCBvdGhlciBvY2N1cnJlbmNlcyBvZiBmb2xkaW5nCisgKiB3aGl0ZXNwYWNlIGNvcnJlY3RseS48cD4KKyAqCisgKiBkYXRlLXRpbWUgPSBbIGRheS1vZi13ZWVrICIsIiBdIGRhdGUgRldTIHRpbWUgW0NGV1NdPHA+CisgKgorICogZGF5LW9mLXdlZWsgPSAoW0ZXU10gZGF5LW5hbWUpIC8gb2JzLWRheS1vZi13ZWVrPHA+CisgKgorICogZGF5LW5hbWUgPSAiTW9uIiAvICJUdWUiIC8gIldlZCIgLyAiVGh1IiAvICJGcmkiIC8gIlNhdCIgLyAiU3VuIjxwPgorICoKKyAqIGRhdGUgPSBkYXkgbW9udGggeWVhcjxwPgorICoKKyAqIHllYXIgPSA0KkRJR0lUIC8gb2JzLXllYXI8cD4KKyAqCisgKiBtb250aCA9IChGV1MgbW9udGgtbmFtZSBGV1MpIC8gb2JzLW1vbnRoPHA+CisgKgorICo8cHJlPm1vbnRoLW5hbWUgPSAiSmFuIiAvICJGZWIiIC8gIk1hciIgLyAiQXByIiAvCisgKiAgICAgICAgICAgICAiTWF5IiAvICJKdW4iIC8gIkp1bCIgLyAiQXVnIiAvCisgKiAgICAgICAgICAgICAiU2VwIiAvICJPY3QiIC8gIk5vdiIgLyAiRGVjIgorICogPC9wcmU+PHA+CisgKiBkYXkgPSAoW0ZXU10gMSoyRElHSVQpIC8gb2JzLWRheTxwPgorICoKKyAqIHRpbWUgPSB0aW1lLW9mLWRheSBGV1Mgem9uZTxwPgorICoKKyAqIHRpbWUtb2YtZGF5ID0gaG91ciAiOiIgbWludXRlIFsgIjoiIHNlY29uZCBdPHA+CisgKgorICogaG91ciA9IDJESUdJVCAvIG9icy1ob3VyPHA+CisgKgorICogbWludXRlID0gMkRJR0lUIC8gb2JzLW1pbnV0ZTxwPgorICoKKyAqIHNlY29uZCA9IDJESUdJVCAvIG9icy1zZWNvbmQ8cD4KKyAqCisgKiB6b25lID0gKCggIisiIC8gIi0iICkgNERJR0lUKSAvIG9icy16b25lPHA+CisgKgorICoKKyAqIFRoZSBkYXkgaXMgdGhlIG51bWVyaWMgZGF5IG9mIHRoZSBtb250aC4gVGhlIHllYXIgaXMgYW55IG51bWVyaWMgeWVhciBpbgorICogdGhlIGNvbW1vbiBlcmEuPHA+CisgKgorICogVGhlIHRpbWUtb2YtZGF5IHNwZWNpZmllcyB0aGUgbnVtYmVyIG9mIGhvdXJzLCBtaW51dGVzLCBhbmQgb3B0aW9uYWxseQorICogc2Vjb25kcyBzaW5jZSBtaWRuaWdodCBvZiB0aGUgZGF0ZSBpbmRpY2F0ZWQuPHA+CisgKgorICogVGhlIGRhdGUgYW5kIHRpbWUtb2YtZGF5IFNIT1VMRCBleHByZXNzIGxvY2FsIHRpbWUuPHA+CisgKgorICogVGhlIHpvbmUgc3BlY2lmaWVzIHRoZSBvZmZzZXQgZnJvbSBDb29yZGluYXRlZCBVbml2ZXJzYWwgVGltZSAoVVRDLAorICogZm9ybWVybHkgcmVmZXJyZWQgdG8gYXMgIkdyZWVud2ljaCBNZWFuIFRpbWUiKSB0aGF0IHRoZSBkYXRlIGFuZAorICogdGltZS1vZi1kYXkgcmVwcmVzZW50LiBUaGUgIisiIG9yICItIiBpbmRpY2F0ZXMgd2hldGhlciB0aGUgdGltZS1vZi1kYXkgaXMKKyAqIGFoZWFkIG9mIG9yIGJlaGluZCBVbml2ZXJzYWwgVGltZS4gVGhlIGZpcnN0IHR3byBkaWdpdHMgaW5kaWNhdGUgdGhlIG51bWJlcgorICogb2YgaG91cnMgZGlmZmVyZW5jZSBmcm9tIFVuaXZlcnNhbCBUaW1lLCBhbmQgdGhlIGxhc3QgdHdvIGRpZ2l0cyBpbmRpY2F0ZQorICogdGhlIG51bWJlciBvZiBtaW51dGVzIGRpZmZlcmVuY2UgZnJvbSBVbml2ZXJzYWwgVGltZS4gKEhlbmNlLCAraGhtbSBtZWFucworICogKyhoaCAqIDYwICsgbW0pIG1pbnV0ZXMsIGFuZCAtaGhtbSBtZWFucyAtKGhoICogNjAgKyBtbSkgbWludXRlcykuIFRoZSBmb3JtCisgKiAiKzAwMDAiIFNIT1VMRCBiZSB1c2VkIHRvIGluZGljYXRlIGEgdGltZSB6b25lIGF0IFVuaXZlcnNhbCBUaW1lLiBUaG91Z2gKKyAqICItMDAwMCIgYWxzbyBpbmRpY2F0ZXMgVW5pdmVyc2FsIFRpbWUsIGl0IGlzIHVzZWQgdG8gaW5kaWNhdGUgdGhhdCB0aGUgdGltZQorICogd2FzIGdlbmVyYXRlZCBvbiBhIHN5c3RlbSB0aGF0IG1heSBiZSBpbiBhIGxvY2FsIHRpbWUgem9uZSBvdGhlciB0aGFuCisgKiBVbml2ZXJzYWwgVGltZS48cD4KKyAqCisgKiBBIGRhdGUtdGltZSBzcGVjaWZpY2F0aW9uIE1VU1QgYmUgc2VtYW50aWNhbGx5IHZhbGlkLiBUaGF0IGlzLCB0aGUKKyAqIGRheS1vZi10aGUgd2VlayAoaWYgaW5jbHVkZWQpIE1VU1QgYmUgdGhlIGRheSBpbXBsaWVkIGJ5IHRoZSBkYXRlLCB0aGUKKyAqIG51bWVyaWMgZGF5LW9mLW1vbnRoIE1VU1QgYmUgYmV0d2VlbiAxIGFuZCB0aGUgbnVtYmVyIG9mIGRheXMgYWxsb3dlZCBmb3IKKyAqIHRoZSBzcGVjaWZpZWQgbW9udGggKGluIHRoZSBzcGVjaWZpZWQgeWVhciksIHRoZSB0aW1lLW9mLWRheSBNVVNUIGJlIGluIHRoZQorICogcmFuZ2UgMDA6MDA6MDAgdGhyb3VnaCAyMzo1OTo2MCAodGhlIG51bWJlciBvZiBzZWNvbmRzIGFsbG93aW5nIGZvciBhIGxlYXAKKyAqIHNlY29uZDsgc2VlIFtTVEQtMTJdKSwgYW5kIHRoZSB6b25lIE1VU1QgYmUgd2l0aGluIHRoZSByYW5nZSAtOTk1OSB0aHJvdWdoCisgKiArOTk1OS48cD4KKyAqCisgKi8KK3B1YmxpYyBjbGFzcyBNYWlsRGF0ZUZvcm1hdCBleHRlbmRzIFNpbXBsZURhdGVGb3JtYXQgeworIAorICAgIHB1YmxpYyBNYWlsRGF0ZUZvcm1hdCgpCisgICAgCisgICAgLyoqCisgICAgICogRm9ybWF0cyB0aGUgZ2l2ZW4gZGF0ZSBpbiB0aGUgZm9ybWF0IHNwZWNpZmllZCBieQorICAgICAqIGRyYWZ0LWlldGYtZHJ1bXMtbXNnLWZtdC0wOCBpbiB0aGUgY3VycmVudCBUaW1lWm9uZQorICAgICAqCisgICAgICogQHBhcmFtCWRhdGUJCXRoZSBEYXRlIG9iamVjdAorICAgICAqIEBwYXJhbQlkYXRlU3RyQnVmCXRoZSBmb3JtYXR0ZWQgc3RyaW5nCisgICAgICogQHBhcmFtCWZpZWxkUG9zaXRpb24JdGhlIGN1cnJlbnQgZmllbGQgcG9zaXRpb24KKyAgICAgKiBAcmV0dXJucwlTdHJpbmdCdWZmZXIJdGhlIGZvcm1hdHRlZCBTdHJpbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nQnVmZmVyIGZvcm1hdChEYXRlIGRhdGUsIFN0cmluZ0J1ZmZlciBkYXRlU3RyQnVmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkUG9zaXRpb24gZmllbGRQb3NpdGlvbikKKworICAgIC8qKgorICAgICAqIFBhcnNlcyB0aGUgZ2l2ZW4gZGF0ZSBpbiB0aGUgZm9ybWF0IHNwZWNpZmllZCBieQorICAgICAqIGRyYWZ0LWlldGYtZHJ1bXMtbXNnLWZtdC0wOCBpbiB0aGUgY3VycmVudCBUaW1lWm9uZQorICAgICAqCisgICAgICogQHBhcmFtCXRleHQJdGhlIGZvcm1hdHRlZCBkYXRlIHRvIGJlIHBhcnNlZAorICAgICAqIEBwYXJhbQlwb3MJdGhlIGN1cnJlbnQgcGFyc2UgcG9zaXRpb24KKyAgICAgKiBAcmV0dXJucwlEYXRlCXRoZSBwYXJzZWQgZGF0ZSBpbiBhIERhdGUgb2JqZWN0CisgICAgICovCisgICAgcHVibGljIERhdGUgcGFyc2UoU3RyaW5nIHRleHQsIFBhcnNlUG9zaXRpb24gcG9zKQorfQorCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKzkuIFN0cmluZy1iYXNlZCBNaW1lTWVzc2FnZSBzZXRSZWNpcGllbnRzIGFuZCBhZGRSZWNpcGllbnRzIG1ldGhvZHMgKDQzMjg4MjQpCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorVGhlIGZvbGxvd2luZyBjb252ZW5pZW5jZSBtZXRob2RzIHdpbGwgYmUgYWRkZWQgdG8gTWltZU1lc3NhZ2UuIFRoZXkgdGFrZSBhCitTdHJpbmcgZm9yIHNldHRpbmcvYWRkaW5nIGEgcmVjaXBpZW50IChpbnN0ZWFkIG9mIGphdmF4Lm1haWwuQWRkcmVzcyBvYmplY3RzKS4KKworICAgIC8qKiAgCisgICAgICogU2V0IHRoZSBzcGVjaWZpZWQgcmVjaXBpZW50IHR5cGUgdG8gdGhlIGdpdmVuIGFkZHJlc3Nlcy4KKyAgICAgKiBJZiB0aGUgYWRkcmVzcyBwYXJhbWV0ZXIgaXMgPGNvZGU+bnVsbDwvY29kZT4sIHRoZSBjb3JyZXNwb25kaW5nCisgICAgICogcmVjaXBpZW50IGZpZWxkIGlzIHJlbW92ZWQuCisgICAgICogICAKKyAgICAgKiBAcGFyYW0gdHlwZSAgICAgIFJlY2lwaWVudCB0eXBlCisgICAgICogQHBhcmFtIGFkZHJlc3NlcyBBZGRyZXNzZXMKKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIElsbGVnYWxXcml0ZUV4Y2VwdGlvbiBpZiB0aGUgdW5kZXJseWluZworICAgICAqICAgICAgICAgICAgICAgICAgaW1wbGVtZW50YXRpb24gZG9lcyBub3Qgc3VwcG9ydCBtb2RpZmljYXRpb24KKyAgICAgKiAgICAgICAgICAgICAgICAgIG9mIGV4aXN0aW5nIHZhbHVlcworICAgICAqIEBleGNlcHRpb24gICAgICAgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgbWVzc2FnZSBpcworICAgICAqICAgICAgICAgICAgICAgICAgb2J0YWluZWQgZnJvbSBhIFJFQURfT05MWSBmb2xkZXIuCisgICAgICogQGV4Y2VwdGlvbiAgICAgICBNZXNzYWdpbmdFeGNlcHRpb24KKyAgICAgKiBAc2VlICAgICAgICAgICAgICNnZXRSZWNpcGllbnRzCisgICAgICovICAKKyAgICBwdWJsaWMgdm9pZCBzZXRSZWNpcGllbnRzKE1lc3NhZ2UuUmVjaXBpZW50VHlwZSB0eXBlLCBTdHJpbmcgYWRkcmVzc2VzKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uCisKKyAgICAvKioKKyAgICAgKiBBZGQgdGhlIGdpdmVuIGFkZHJlc3NlcyB0byB0aGUgc3BlY2lmaWVkIHJlY2lwaWVudCB0eXBlLgorICAgICAqICAgCisgICAgICogQHBhcmFtIHR5cGUgICAgICBSZWNpcGllbnQgdHlwZQorICAgICAqIEBwYXJhbSBhZGRyZXNzZXMgQWRkcmVzc2VzCisgICAgICogQGV4Y2VwdGlvbiAgICAgICBJbGxlZ2FsV3JpdGVFeGNlcHRpb24gaWYgdGhlIHVuZGVybHlpbmcKKyAgICAgKiAgICAgICAgICAgICAgICAgIGltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uCisgICAgICogICAgICAgICAgICAgICAgICBvZiBleGlzdGluZyB2YWx1ZXMuCisgICAgICogQGV4Y2VwdGlvbiAgICAgICBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBtZXNzYWdlIGlzCisgICAgICogICAgICAgICAgICAgICAgICBvYnRhaW5lZCBmcm9tIGEgUkVBRF9PTkxZIGZvbGRlci4KKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIE1lc3NhZ2luZ0V4Y2VwdGlvbgorICAgICAqLyAgCisgICAgcHVibGljIHZvaWQgYWRkUmVjaXBpZW50cyhNZXNzYWdlLlJlY2lwaWVudFR5cGUgdHlwZSwgU3RyaW5nIGFkZHJlc3NlcykKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbgorCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKzEwLiBBZGQgU2Vzc2lvbi5nZXREZWZhdWx0SW5zdGFuY2UoUHJvcGVydGllcyBwcm9wcykgYW5kCisgICAgICAgIFNlc3Npb24uZ2V0SW5zdGFuY2UoUHJvcGVydGllcyBwcm9wcykgbWV0aG9kcyAoNDMyODgyNikKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitUaGVzZSBhcmUgY29udmVuaWVuY2UgbWV0aG9kcyBmb3IgcmV0cmlldmluZyB0aGUgZGVmYXVsdCBTZXNzaW9uIG9yIGEgbmV3CitTZXNzaW9uIG9iamVjdCB3aGljaCBkb2VzIG5vdCByZXF1aXJlIGFuIEF1dGhlbnRpY2F0b3IgcGFyYW1ldGVyCisoaXQgaXMgYXNzdW1lZCB0byBiZSBudWxsKS4KKyAKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGRlZmF1bHQgU2Vzc2lvbiBvYmplY3QuIElmIGEgZGVmYXVsdCBoYXMgbm90IHlldCBiZWVuCisgICAgICogc2V0dXAsIGEgbmV3IFNlc3Npb24gb2JqZWN0IGlzIGNyZWF0ZWQgYW5kIGluc3RhbGxlZCBhcyB0aGUKKyAgICAgKiBkZWZhdWx0LjxwPgorICAgICAqCisgICAgICogTm90ZSB0aGF0IGEgZGVmYXVsdCBzZXNzaW9uIGNyZWF0ZWQgd2l0aCBubyBBdXRoZW50aWNhdG9yIGlzCisgICAgICogYXZhaWxhYmxlIHRvIGFsbCBjb2RlIGV4ZWN1dGluZyBpbiB0aGUgc2FtZSBKYXZhIHZpcnR1YWwKKyAgICAgKiBtYWNoaW5lLCBhbmQgdGhlIHNlc3Npb24gY2FuIGNvbnRhaW4gc2VjdXJpdHkgc2Vuc2l0aXZlCisgICAgICogaW5mb3JtYXRpb24gc3VjaCBhcyB1c2VyIG5hbWVzIGFuZCBwYXNzd29yZHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gICBwcm9wcyAgIFByb3BlcnRpZXMgb2JqZWN0LiBVc2VkIG9ubHkgaWYgYSBuZXcgU2Vzc2lvbgorICAgICAqICAgICAgICAgICAgICAgICAgb2JqZWN0IGlzIGNyZWF0ZWQuPGJyPgorICAgICAqICAgICAgICAgICAgICAgICAgSXQgaXMgZXhwZWN0ZWQgdGhhdCB0aGUgY2xpZW50IHN1cHBsaWVzIHZhbHVlcworICAgICAqICAgICAgICAgICAgICAgICAgZm9yIHRoZSBwcm9wZXJ0aWVzIGxpc3RlZCBpbiBBcHBlbmRpeCBBIG9mIHRoZQorICAgICAqICAgICAgICAgICAgICAgICAgSmF2YU1haWwgc3BlYyAocGFydGljdWxhcmx5ICBtYWlsLnN0b3JlLnByb3RvY29sLAorICAgICAqICAgICAgICAgICAgICAgICAgbWFpbC50cmFuc3BvcnQucHJvdG9jb2wsIG1haWwuaG9zdCwgbWFpbC51c2VyLAorICAgICAqICAgICAgICAgICAgICAgICAgYW5kIG1haWwuZnJvbSkgYXMgdGhlIGRlZmF1bHRzIGFyZSB1bmxpa2VseSB0bworICAgICAqICAgICAgICAgICAgICAgICAgd29yayBpbiBhbGwgY2FzZXMuCisgICAgICogQHJldHVybiAgICAgICAgICB0aGUgZGVmYXVsdCBTZXNzaW9uIG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU2Vzc2lvbiBnZXREZWZhdWx0SW5zdGFuY2UoUHJvcGVydGllcyBwcm9wcykKKworICAgIC8qKiAgCisgICAgICogR2V0IGEgbmV3IFNlc3Npb24gb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtICAgcHJvcHMgICBQcm9wZXJ0aWVzIG9iamVjdCB0aGF0IGhvbGQgcmVsZXZhbnQgcHJvcGVydGllcy48YnI+CisgICAgICogICAgICAgICAgICAgICAgICBJdCBpcyBleHBlY3RlZCB0aGF0IHRoZSBjbGllbnQgc3VwcGxpZXMgdmFsdWVzCisgICAgICogICAgICAgICAgICAgICAgICBmb3IgdGhlIHByb3BlcnRpZXMgbGlzdGVkIGluIEFwcGVuZGl4IEEgb2YgdGhlCisgICAgICogICAgICAgICAgICAgICAgICBKYXZhTWFpbCBzcGVjIChwYXJ0aWN1bGFybHkgIG1haWwuc3RvcmUucHJvdG9jb2wsCisgICAgICogICAgICAgICAgICAgICAgICBtYWlsLnRyYW5zcG9ydC5wcm90b2NvbCwgbWFpbC5ob3N0LCBtYWlsLnVzZXIsCisgICAgICogICAgICAgICAgICAgICAgICBhbmQgbWFpbC5mcm9tKSBhcyB0aGUgZGVmYXVsdHMgYXJlIHVubGlrZWx5IHRvCisgICAgICogICAgICAgICAgICAgICAgICB3b3JrIGluIGFsbCBjYXNlcy4KKyAgICAgKiBAcmV0dXJuICAgICAgICAgIGEgbmV3IFNlc3Npb24gb2JqZWN0CisgICAgICogQHNlZSAgICAgamF2YXgubWFpbC5BdXRoZW50aWNhdG9yCisgICAgICovICAKKyAgICBwdWJsaWMgc3RhdGljIFNlc3Npb24gZ2V0SW5zdGFuY2UoUHJvcGVydGllcyBwcm9wcykKKworPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisxMS4gQWxsb3cgZm9yIHByb3ZpZGluZyBhIGZpbGVuYW1lIHdoZW4gdXNpbmcgTWltZVV0aWxpdHkuZW5jb2RlKCkgKDQxNDA1NzkpCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK1RoZSBVVUVuY29kZSBlbmNvZGVyIHJlcXVpcmVzIHRoZSBmaWxlbmFtZSB0byBiZSBpbnNlcnRlZCBpbnRvIHRoZSBlbmNvZGVkCitzdHJlYW0uIFRoZSBwdWJsaWMgYWNjZXNzIHBvaW50IHRvIHRoZSBlbmNvZGVyIGlzIHRocnUgdGhlIE1pbWVVdGlsaXR5LmVuY29kZSgpCittZXRob2QsIHdoaWNoIGRvZXMgbm90IGhhdmUgYW55IHBhcmFtZXRlciB0aGF0IGNhbiBwcm92aWRlIHRoZSBmaWxlbmFtZS4KK0hlbmNlIHRoZSB1dWVuY29kZWQgc3RyZWFtIGFsd2F5cyBoYXMgImVuY29kZS5idWYiIGFzIGZpbGVuYW1lLiBUaGlzIG5ldworbWV0aG9kIGFsbG93cyB0aGUgc2V0dGluZyBvZiB0aGUgZmlsZW5hbWUuCisKKyAgICAvKioKKyAgICAgKiBXcmFwIGFuIGVuY29kZXIgYXJvdW5kIHRoZSBnaXZlbiBvdXRwdXQgc3RyZWFtLgorICAgICAqIEFsbCB0aGUgZW5jb2RpbmdzIGRlZmluZWQgaW4gUkZDIDIwNDUgYXJlIHN1cHBvcnRlZCBoZXJlLgorICAgICAqIFRoZXkgaW5jbHVkZSAiYmFzZTY0IiwgInF1b3RlZC1wcmludGFibGUiLCAiN2JpdCIsICI4Yml0IiBhbmQKKyAgICAgKiAiYmluYXJ5Ii4gSW4gYWRkaXRpb24sICJ1dWVuY29kZSIgaXMgYWxzbyBzdXBwb3J0ZWQuCisgICAgICogVGhlIDxjb2RlPmZpbGVuYW1lPC9jb2RlPiBwYXJhbWV0ZXIgaXMgdXNlZCB3aXRoIHRoZSAidXVlbmNvZGUiCisgICAgICogZW5jb2RpbmcgYW5kIGlzIGluY2x1ZGVkIGluIHRoZSBlbmNvZGVkIG91dHB1dC4KKyAgICAgKgorICAgICAqIEBwYXJhbSAgIG9zICAgICAgICAgICAgICBvdXRwdXQgc3RyZWFtCisgICAgICogQHBhcmFtICAgZW5jb2RpbmcgICAgICAgIHRoZSBlbmNvZGluZyBvZiB0aGUgc3RyZWFtLgorICAgICAqIEBwYXJhbSAgIGZpbGVuYW1lCW5hbWUgZm9yIHRoZSBmaWxlIGJlaW5nIGVuY29kZWQKKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIE1lc3NhZ2luZ0V4Y2VwdGlvbgorICAgICAqIEByZXR1cm4gICAgICAgICAgICAgICAgICBvdXRwdXQgc3RyZWFtIHRoYXQgYXBwbGllcyB0aGUKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2lmaWVkIGVuY29kaW5nLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgT3V0cHV0U3RyZWFtIGVuY29kZShPdXRwdXRTdHJlYW0gb3MsIFN0cmluZyBlbmNvZGluZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGZpbGVuYW1lKQorICAgICAgICAgICAgICAgIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24KKyAgCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKzEyLiBOZXcgZXhjZXB0aW9uIGNvbnN0cnVjdG9ycyAoNDI1OTIxMSkKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworVGhlIEZvbGRlck5vdEZvdW5kRXhjZXB0aW9uIGNvbnN0cnVjdG9ycyBhcmUgbm90IGNvbnNpc3RhbnQgd2l0aCBvdGhlcgorZXhjZXB0aW9ucyBkZWZpbmVkIGluIHRoZSBBUEkuIE5ldyBjb25zdHJ1Y3RvcnMgYXJlIG5lZWRlZCB0byBlbGltaW5hdGUKK3RoZXNlIGluY29uc2lzdGVuY2llcy4KKyAKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgTWVzc2FnaW5nRXhjZXB0aW9uIHdpdGggdGhlIHNwZWNpZmllZCBmb2xkZXIKKyAgICAgKiBAcGFyYW0gZm9sZGVyICAgIHRoZSBGb2xkZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgRm9sZGVyTm90Rm91bmRFeGNlcHRpb24oRm9sZGVyIGZvbGRlcikKKyAKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgTWVzc2FnaW5nRXhjZXB0aW9uIHdpdGggdGhlIHNwZWNpZmllZCBkZXRhaWwgbWVzc2FnZQorICAgICAqIGFuZCB0aGUgc3BlY2lmaWVkIGZvbGRlci4KKyAgICAgKiBAcGFyYW0gZm9sZGVyICAgIHRoZSBGb2xkZXIKKyAgICAgKiBAcGFyYW0gcyAgICAgICAgIHRoZSBkZXRhaWwgbWVzc2FnZQorICAgICAqLworICAgIHB1YmxpYyBGb2xkZXJOb3RGb3VuZEV4Y2VwdGlvbihGb2xkZXIgZm9sZGVyLCBTdHJpbmcgcykKKworPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisxMy4gSW50ZXJuZXRBZGRyZXNzLnRvVW5pY29kZVN0cmluZygpIG1ldGhvZCAgKDQyODE3MjkpCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK1Byb2JsZW06IEFkZHJlc3NTdHJpbmdUZXJtLm1hdGNoIGRvZXMgbm90IHJldHVybiB0aGUgY29ycmVjdCByZXN1bHRzCitpbiBzb21lIHNpdHVhdGlvbnMuCisKK0FkZHJlc3NTdHJpbmdUZXJtIHdhbnRzIHRvIGRvIHRoZSBtYXRjaCBhZ2FpbnN0IHRoZSBmb3JtYXR0ZWQgYWRkcmVzcworc3RyaW5nIGluIFVuaWNvZGUsIG5vdCB0aGUgQVNDSUkgdmVyc2lvbiB0aGF0IG1pZ2h0IGluY2x1ZGUgY2hhcnNldAorZW5jb2RpbmcgaW5mb3JtYXRpb24uICBUbyBkbyB0aGlzIGl0IGF0dGVtcHRzIHRvIGZvcm1hdCB0aGUgYWRkcmVzcworaXRzZWxmLCBidXQgaXQncyBub3Qgc21hcnQgZW5vdWdoIHRvIGtub3cgYWxsIHRoZSBydWxlcyBhYm91dAorZm9ybWF0dGluZyBhbiBhZGRyZXNzIChlLmcuLCB3aGVuIHRvIHF1b3RlIHRoZSBwZXJzb25hbCBuYW1lKSBzbyBpdAorZG9lcyB0aGlzIGZvcm1hdHRpbmcgZGlmZmVyZW50bHkgdGhhbiBJbnRlcm5ldEFkZHJlc3MudG9TdHJpbmcgZG9lcy4KK1doZW4gdGhlIGFkZHJlc3MgY29udGFpbnMgb25seSBBU0NJSSBjaGFyYWN0ZXJzLCB0aGUgZm9ybWF0dGluZyBzaG91bGQKK2JlIGlkZW50aWNhbC4KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBwcm9wZXJseSBmb3JtYXR0ZWQgYWRkcmVzcyAoUkZDIDgyMiBzeW50YXgpIG9mCisgICAgICogVW5pY29kZSBjaGFyYWN0ZXJzLgorICAgICAqICAgCisgICAgICogQHJldHVybiAgICAgICAgICBVbmljb2RlIGFkZHJlc3Mgc3RyaW5nCisgICAgICovICAKKyAgICBwdWJsaWMgU3RyaW5nIHRvVW5pY29kZVN0cmluZygpCisgICAgCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKzE0LiBDYWxsIHNhdmVDaGFuZ2VzIGF1dG9tYXRpY2FsbHkgb24gbmV3bHkgY29uc3RydWN0ZWQgbWVzc2FnZSAoNDMzOTIwMykKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworT25lIG9mIHRoZSBtb3N0IGNvbW1vbiBlcnJvcnMgd2hlbiBjb25zdHJ1Y3RpbmcgbmV3IG1lc3NhZ2VzIGlzIGZvcmdldHRpbmcKK3RvIGNhbGwgdGhlIHNhdmVDaGFuZ2VzKCkgbWV0aG9kIGJlZm9yZSB3cml0aW5nIG91dCB0aGUgbWVzc2FnZSBvciBjYWxsaW5nCit0aGUgVHJhbnNwb3J0LnNlbmRNZXNzYWdlKCkgbWV0aG9kLiAgVG8gc29sdmUgdGhpcyBwcm9ibGVtIHdlIGFkZCBhIGZsYWcKK3RvIE1pbWVNZXNzYWdlIGFuZCBjaGFuZ2UgdGhlIHdyaXRlVG8oKSBtZXRob2QgYWNjb3JkaW5nbHk6CisKKyAgICAvKioKKyAgICAgKiBEb2VzIHRoZSA8Y29kZT5zYXZlQ2hhbmdlczwvY29kZT4gbWV0aG9kIG5lZWQgdG8gYmUgY2FsbGVkIG9uCisgICAgICogdGhpcyBtZXNzYWdlPyAgVGhpcyBmbGFnIGlzIHNldCB0byBmYWxzZSBieSB0aGUgcHVibGljIGNvbnN0cnVjdG9yCisgICAgICogYW5kIHNldCB0byB0cnVlIGJ5IHRoZSA8Y29kZT5zYXZlQ2hhbmdlczwvY29kZT4gbWV0aG9kLiAgVGhlCisgICAgICogPGNvZGU+d3JpdGVUbzwvY29kZT4gbWV0aG9kIGNoZWNrcyB0aGlzIGZsYWcgYW5kIGNhbGxzIHRoZQorICAgICAqIDxjb2RlPnNhdmVDaGFuZ2VzPC9jb2RlPiBtZXRob2QgYXMgbmVjZXNzYXJ5LiAgVGhpcyBhdm9pZHMgdGhlCisgICAgICogY29tbW9uIG1pc3Rha2Ugb2YgZm9yZ2V0dGluZyB0byBjYWxsIHRoZSA8Y29kZT5zYXZlQ2hhbmdlczwvY29kZT4KKyAgICAgKiBtZXRob2Qgb24gYSBuZXdseSBjb25zdHJ1Y3RlZCBtZXNzYWdlLgorICAgICAqLworICAgIHByb3RlY3RlZCBib29sZWFuIHNhdmVkID0gZmFsc2U7CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIHRoZSBhcHByb3ByaWF0ZSBoZWFkZXIgZmllbGRzIG9mIHRoaXMgbWVzc2FnZSB0byBiZQorICAgICAqIGNvbnNpc3RlbnQgd2l0aCB0aGUgbWVzc2FnZSdzIGNvbnRlbnRzLiBJZiB0aGlzIG1lc3NhZ2UgaXMKKyAgICAgKiBjb250YWluZWQgaW4gYSBGb2xkZXIsIGFueSBjaGFuZ2VzIG1hZGUgdG8gdGhpcyBtZXNzYWdlIGFyZQorICAgICAqIGNvbW1pdHRlZCB0byB0aGUgY29udGFpbmluZyBmb2xkZXIuIDxwPgorICAgICAqCisgICAgICogSWYgYW55IHBhcnQgb2YgYSBtZXNzYWdlJ3MgaGVhZGVycyBvciBjb250ZW50cyBhcmUgY2hhbmdlZCwKKyAgICAgKiA8Y29kZT5zYXZlQ2hhbmdlczwvY29kZT4gbXVzdCBiZSBjYWxsZWQgdG8gZW5zdXJlIHRoYXQgdGhvc2UKKyAgICAgKiBjaGFuZ2VzIGFyZSBwZXJtYW5lbnQuIE90aGVyd2lzZSwgYW55IHN1Y2ggbW9kaWZpY2F0aW9ucyBtYXkgb3IKKyAgICAgKiBtYXkgbm90IGJlIHNhdmVkLCBkZXBlbmRpbmcgb24gdGhlIGZvbGRlciBpbXBsZW1lbnRhdGlvbi4gPHA+CisgICAgICoKKyAgICAgKiBNZXNzYWdlcyBvYnRhaW5lZCBmcm9tIGZvbGRlcnMgb3BlbmVkIFJFQURfT05MWSBzaG91bGQgbm90IGJlCisgICAgICogbW9kaWZpZWQgYW5kIHNhdmVDaGFuZ2VzIHNob3VsZCBub3QgYmUgY2FsbGVkIG9uIHN1Y2ggbWVzc2FnZXMuIDxwPgorICAgICAqCisgICAgICogVGhpcyBtZXRob2Qgc2V0cyB0aGUgPGNvZGU+bW9kaWZpZWQ8L2NvZGU+IGZsYWcgdG8gdHJ1ZSwgdGhlCisgICAgICogPGNvZGU+c2F2ZTwvY29kZT4gZmxhZyB0byB0cnVlLCBhbmQgdGhlbiBjYWxscyB0aGUKKyAgICAgKiA8Y29kZT51cGRhdGVIZWFkZXJzPGNvZGU+IG1ldGhvZC4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24gICAgICAgSWxsZWdhbFdyaXRlRXhjZXB0aW9uIGlmIHRoZSB1bmRlcmx5aW5nCisgICAgICogICAgICAgICAgICAgICAgICBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IG1vZGlmaWNhdGlvbgorICAgICAqIEBleGNlcHRpb24gICAgICAgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgbWVzc2FnZSBpcworICAgICAqICAgICAgICAgICAgICAgICAgb2J0YWluZWQgZnJvbSBhIFJFQURfT05MWSBmb2xkZXIuCisgICAgICogQGV4Y2VwdGlvbiAgICAgICBNZXNzYWdpbmdFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzYXZlQ2hhbmdlcygpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24KKworICAgIC8qKgorICAgICAqIE91dHB1dCB0aGUgbWVzc2FnZSBhcyBhbiBSRkMgODIyIGZvcm1hdCBzdHJlYW0sIHdpdGhvdXQKKyAgICAgKiBzcGVjaWZpZWQgaGVhZGVycy4gIElmIHRoZSA8Y29kZT5zYXZlZDwvY29kZT4gZmxhZyBpcyBub3Qgc2V0LAorICAgICAqIHRoZSA8Y29kZT5zYXZlQ2hhbmdlczwvY29kZT4gbWV0aG9kIGlzIGNhbGxlZC4KKyAgICAgKiBJZiB0aGUgPGNvZGU+bW9kaWZpZWQ8L2NvZGU+IGZsYWcgaXMgbm90CisgICAgICogc2V0IGFuZCB0aGUgPGNvZGU+Y29udGVudDwvY29kZT4gYXJyYXkgaXMgbm90IG51bGwsIHRoZQorICAgICAqIDxjb2RlPmNvbnRlbnQ8L2NvZGU+IGFycmF5IGlzIHdyaXR0ZW4gZGlyZWN0bHksIGFmdGVyCisgICAgICogd3JpdGluZyB0aGUgYXBwcm9wcmlhdGUgbWVzc2FnZSBoZWFkZXJzLgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbiBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorICAgICAqIEBleGNlcHRpb24gSU9FeGNlcHRpb24gICBpZiBhbiBlcnJvciBvY2N1cnMgd3JpdGluZyB0byB0aGUgc3RyZWFtCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIG9yIGlmIGFuIGVycm9yIGlzIGdlbmVyYXRlZCBieSB0aGUKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgamF2YXguYWN0aXZhdGlvbiBsYXllci4KKyAgICAgKiBAc2VlIGphdmF4LmFjdGl2YXRpb24uRGF0YUhhbmRsZXIjd3JpdGVUbworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oT3V0cHV0U3RyZWFtIG9zLCBTdHJpbmdbXSBpZ25vcmVMaXN0KQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIE1lc3NhZ2luZ0V4Y2VwdGlvbgorCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKzE1LiBOZXcgTWltZVV0aWxpdHkuZ2V0RW5jb2RpbmcoRGF0YUhhbmRsZXIpIG1ldGhvZCAoNDM0MDY0OCkKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworVG8gaW1wcm92ZSB0aGUgcGVyZm9ybWFuY2Ugb2YgSmF2YU1haWwsIHdlIHByZXZpb3VzbHkgYWRkZWQgYSAocGFja2FnZQorcHJpdmF0ZSkgZ2V0RW5jb2RpbmcoKSBtZXRob2QgdG8gTWltZVV0aWxpdHkuICBUaGlzIG1ldGhvZCBpcyBub3cgcHVibGljOgorCisgICAgLyoqCisgICAgICogU2FtZSBhcyA8Y29kZT5nZXRFbmNvZGluZyhEYXRhU291cmNlKTwvY29kZT4gZXhjZXB0IHRoYXQgaW5zdGVhZAorICAgICAqIG9mIHJlYWRpbmcgdGhlIGRhdGEgZnJvbSBhbiA8Y29kZT5JbnB1dFN0cmVhbTwvY29kZT4gaXQgdXNlcyB0aGUKKyAgICAgKiA8Y29kZT53cml0ZVRvPC9jb2RlPiBtZXRob2QgdG8gZXhhbWluZSB0aGUgZGF0YS4gIFRoaXMgaXMgbW9yZQorICAgICAqIGVmZmljaWVudCBpbiB0aGUgY29tbW9uIGNhc2Ugb2YgYSA8Y29kZT5EYXRhSGFuZGxlcjwvY29kZT4KKyAgICAgKiBjcmVhdGVkIHdpdGggYW4gb2JqZWN0IGFuZCBhIE1JTUUgdHlwZSAoZm9yIGV4YW1wbGUsIGEKKyAgICAgKiAidGV4dC9wbGFpbiIgU3RyaW5nKSBiZWNhdXNlIGFsbCB0aGUgSS9PIGlzIGRvbmUgaW4gdGhpcworICAgICAqIHRocmVhZC4gIEluIHRoZSBjYXNlIHJlcXVpcmluZyBhbiA8Y29kZT5JbnB1dFN0cmVhbTwvY29kZT4gdGhlCisgICAgICogPGNvZGU+RGF0YUhhbmRsZXI8L2NvZGU+IHVzZXMgYSB0aHJlYWQsIGEgcGFpciBvZiBwaXBlIHN0cmVhbXMsCisgICAgICogYW5kIHRoZSA8Y29kZT53cml0ZVRvPC9jb2RlPiBtZXRob2QgdG8gcHJvZHVjZSB0aGUgZGF0YS4gPHA+CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0RW5jb2RpbmcoRGF0YUhhbmRsZXIgZGgpCisKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworMTYuIE5ldyBUcmFuc3BvcnRFdmVudC5nZXRNZXNzYWdlKCkgIG1ldGhvZCAoNDMzMTY3NCkKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK1RoZSBUcmFuc3BvcnRFdmVudCBjbGFzcyBzYXZlcyB0aGUgbWVzc2FnZSB0aGF0IGNhdXNlZCB0aGUgZXJyb3IsCitidXQgcHJvdmlkZXMgbm8gZ2V0TWVzc2FnZSBtZXRob2QgZm9yIHRoZSBsaXN0ZW5lciB0byByZXRyaWV2ZSB0aGUKK01lc3NhZ2Ugb2JqZWN0LiBUaGUgZm9sbG93aW5nIG1ldGhvZCB3aWxsIGJlIGFkZGVkOgorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBNZXNzYWdlIG9iamVjdCBhc3NvY2lhdGVkIHdpdGggdGhpcyBUcmFuc3BvcnQgRXZlbnQuCisgICAgICogICAKKyAgICAgKiBAcmV0dXJuICAgICAgICAgIHRoZSBNZXNzYWdlIG9iamVjdCAKKyAgICAgKi8KKyAgICBwdWJsaWMgTWVzc2FnZSBnZXRNZXNzYWdlKCkKKworCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKzE3LiBqYXZheC5tYWlsLnNlYXJjaCB0ZXJtcyBzaG91bGQgYmUgc2VyaWFsaXphYmxlICg0MTI2MDEzKQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK1RoZSBqYXZheC5tYWlsLnNlYXJjaCBwYWNrYWdlIGFsbG93cyB5b3UgdG8gcHJvZ3JhbW1hdGljYWxseSBjb25zdHJ1Y3QKK2Egc2VhcmNoIHRlcm0uICBJdCB3b3VsZCBiZSBjb252ZW5pZW50IGlmIHRob3NlIHRlcm1zIGNvdWxkIGJlIHNhdmVkCitpbiBwZXJzaXN0ZW50IHN0b3JhZ2UgYW5kIHJlc3RvcmVkIGluIGEgbGF0ZXIgc2Vzc2lvbi4gIFVzaW5nCitzZXJpYWxpemF0aW9uIHRvIHN0b3JlIHRoZXNlIGV4cHJlc3Npb25zIGlzIHRoZSBzaW1wbGVzdCBhcHByb2FjaC4KKworTWFueSBvZiB0aGUgc2VhcmNoIHRlcm1zIHJlZmVyZW5jZSBvdGhlciBvYmplY3RzIHRoYXQgbXVzdCBhbHNvIGJlCitzZXJpYWxpemFibGUuICBUaGUgbW9zdCBwcm9ibGVtYXRpYyBzdWNoIG9iamVjdHMgYXJlIG9mIHRoZSBjbGFzcworTWVzc2FnZS5SZWNpcGllbnRUeXBlLiAgVGhpcyBjbGFzcyB1c2VzIHRoZSBqYXZhICJ0eXBlLXNhZmUgZW51bSIKK2lkaW9tLCB3aGljaCBpbnZvbHZlcyBhIG51bWJlciBvZiBzdGF0aWMgZmluYWwgaW5zdGFuY2VzIG9mIHRoZSBjbGFzcy4KK0FwcGxpY2F0aW9ucyBhcmUgYWxsb3dlZCB0byB0ZXN0IGZvciBlcXVpdmFsZW5jZSB3aXRoIHRoZXNlICJjb25zdGFudHMiCitieSB1c2luZyB0aGUgIj09IiBlcXVhbGl0eSBvcGVyYXRvci4gIFRodXMsIGl0J3MgY3JpdGljYWwgdGhhdCBvbmx5IGEKK3NpbmdsZSBpbnN0YW5jZSBvZiBlYWNoIGNvbnN0YW50IGV4aXN0IGluIHRoZSBKYXZhIHZpcnR1YWwgbWFjaGluZS4KK1RvIGVuc3VyZSB0aGF0IHRoaXMgY29uc3RyYWludCBpcyBtZXQgd2hlbiBkZXNlcmlhbGl6aW5nIGFuIG9iamVjdAorb2YgdGhpcyBjbGFzcywgd2UgbXVzdCB0YWtlIGFkdmFudGFnZSBvZiB0aGUgSkRLIDEuMiByZWFkUmVwbGFjZSgpCittZXRob2QuICBTaW5jZSB0aGlzIG1ldGhvZCBpcyBub3QgYXZhaWxhYmxlIG9uIEpESyAxLjEsIG9iamVjdHMgb2YKK3RoaXMgY2xhc3MsIGFuZCB0aHVzIHNlYXJjaCB0ZXJtcyB0aGF0IHJlZmVyZW5jZSB0aGVtLCBjYW4gbm90IGJlCitjb3JyZWN0bHkgZGVzZXJpYWxpemVkIG9uIEpESyAxLjEuICBUaGlzIGlzIGEgbGltaXRhdGlvbiBvZiB0aGlzCituZXcgY2FwYWJpbGl0eS4KKworVG8gcHJvdmlkZSB0aGlzIHN1cHBvcnQsIHRoZSBmb2xsb3dpbmcgY2xhc3NlcyBhbmQgYWxsIHRoZWlyIHN1YmNsYXNzZXMKK25vdyBpbXBsZW1lbnQgdGhlIFNlcmlhbGl6YWJsZSBpbnRlcmZhY2U6CisKKyAgICBqYXZheC5tYWlsLnNlYXJjaC5TZWFyY2hUZXJtCisgICAgamF2YXgubWFpbC5BZGRyZXNzCisgICAgamF2YXgubWFpbC5GbGFncworICAgIGphdmF4Lm1haWwuTWVzc2FnZS5SZWNpcGllbnRUeXBlCisKK0luIGFkZGl0aW9uLCB0byBhbGxvdyBjb21wYXJpc29uIGJldHdlZW4gc2VhcmNoIHRlcm1zLCB0aGUgZXF1YWxzCithbmQgaGFzaENvZGUgbWV0aG9kcyBvbiBTZWFyY2hUZXJtIChhbmQgYWxsIHN1YmNsYXNzZXMpIG5vdyBpbXBsZW1lbnQKKyJ2YWx1ZSIgZXF1aXZhbGVuY2UgcmF0aGVyIHRoYW4gaWRlbnRpdHkgZXF1aXZhbGVuY2UuCisKKworPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisxOC4gU3VwcG9ydCBJTUFQIE5BTUVTUEFDRSBleHRlbnNpb24gKDQzNjQ4MjcpCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworV2UgcHJvcG9zZSB0aGUgZm9sbG93aW5nIG5ldyBBUElzIHRvIGJlIGFkZGVkIHRvIGphdmF4Lm1haWwuU3RvcmUgdG8KK3Byb3ZpZGUgbmFtZXNwYWNlIGluZm9ybWF0aW9uLiAgSWYgdGhlIElNQVAgc2VydmVyIHN1cHBvcnRzIHRoZQorTkFNRVNQQUNFIGV4dGVuc2lvbiwgaXQgd2lsbCBiZSB1c2VkIHRvIHJldHVybiB0aGlzIGluZm9ybWF0aW9uLgorCisgICAgLyoqCisgICAgICogUmV0dXJuIGEgc2V0IG9mIGZvbGRlcnMgcmVwcmVzZW50aW5nIHRoZSA8aT5wZXJzb25hbDwvaT4gbmFtZXNwYWNlcworICAgICAqIGZvciB0aGUgY3VycmVudCB1c2VyLiAgQSBwZXJzb25hbCBuYW1lc3BhY2UgaXMgYSBzZXQgb2YgbmFtZXMgdGhhdAorICAgICAqIGlzIGNvbnNpZGVyZWQgd2l0aGluIHRoZSBwZXJzb25hbCBzY29wZSBvZiB0aGUgYXV0aGVudGljYXRlZCB1c2VyLgorICAgICAqIFR5cGljYWxseSwgb25seSB0aGUgYXV0aGVudGljYXRlZCB1c2VyIGhhcyBhY2Nlc3MgdG8gbWFpbCBmb2xkZXJzCisgICAgICogaW4gdGhlaXIgcGVyc29uYWwgbmFtZXNwYWNlLiAgSWYgYW4gSU5CT1ggZXhpc3RzIGZvciBhIHVzZXIsIGl0CisgICAgICogbXVzdCBhcHBlYXIgd2l0aGluIHRoZSB1c2VyJ3MgcGVyc29uYWwgbmFtZXNwYWNlLiAgSW4gdGhlCisgICAgICogdHlwaWNhbCBjYXNlLCB0aGVyZSBzaG91bGQgYmUgb25seSBvbmUgcGVyc29uYWwgbmFtZXNwYWNlIGZvciBlYWNoCisgICAgICogdXNlciBpbiBlYWNoIFN0b3JlLiA8cD4KKyAgICAgKgorICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gcmV0dXJucyBhbiBhcnJheSB3aXRoIGEgc2luZ2xlIGVudHJ5IGNvbnRhaW5pbmcKKyAgICAgKiB0aGUgcmV0dXJuIHZhbHVlIG9mIHRoZSA8Y29kZT5nZXREZWZhdWx0Rm9sZGVyPC9jb2RlPiBtZXRob2QuCisgICAgICogU3ViY2xhc3NlcyBzaG91bGQgb3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8gcmV0dXJuIGFwcHJvcHJpYXRlIGluZm9ybWF0aW9uLgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbiAJSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgU3RvcmUgaXMgbm90IGNvbm5lY3RlZC4KKyAgICAgKiBAcmV0dXJuCQlhcnJheSBvZiBGb2xkZXIgb2JqZWN0cworICAgICAqLworICAgIHB1YmxpYyBGb2xkZXJbXSBnZXRQZXJzb25hbE5hbWVzcGFjZXMoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYSBzZXQgb2YgZm9sZGVycyByZXByZXNlbnRpbmcgdGhlIG5hbWVzcGFjZXMgZm9yCisgICAgICogPGNvZGU+dXNlcjwvY29kZT4uICBUaGUgbmFtZXNwYWNlcyByZXR1cm5lZCByZXByZXNlbnQgdGhlCisgICAgICogcGVyc29uYWwgbmFtZXNwYWNlcyBmb3IgdGhlIHVzZXIuICBUbyBhY2Nlc3MgbWFpbCBmb2xkZXJzIGluIHRoZQorICAgICAqIG90aGVyIHVzZXIncyBuYW1lc3BhY2UsIHRoZSBjdXJyZW50bHkgYXV0aGVudGljYXRlZCB1c2VyIG11c3QgYmUKKyAgICAgKiBleHBsaWNpdGx5IGdyYW50ZWQgYWNjZXNzIHJpZ2h0cy4gIEZvciBleGFtcGxlLCBpdCBpcyBjb21tb24gZm9yCisgICAgICogYSBtYW5hZ2VyIHRvIGdyYW50IHRvIHRoZWlyIHNlY3JldGFyeSBhY2Nlc3MgcmlnaHRzIHRvIHRoZWlyCisgICAgICogbWFpbCBmb2xkZXJzLiA8cD4KKyAgICAgKgorICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gcmV0dXJucyBhbiBlbXB0eSBhcnJheS4gIFN1YmNsYXNzZXMgc2hvdWxkCisgICAgICogb3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8gcmV0dXJuIGFwcHJvcHJpYXRlIGluZm9ybWF0aW9uLgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbiAJSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgU3RvcmUgaXMgbm90IGNvbm5lY3RlZC4KKyAgICAgKiBAcmV0dXJuCQlhcnJheSBvZiBGb2xkZXIgb2JqZWN0cworICAgICAqLworICAgIHB1YmxpYyBGb2xkZXJbXSBnZXRVc2VyTmFtZXNwYWNlcyhTdHJpbmcgdXNlcikgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbgorCisgICAgLyoqCisgICAgICogUmV0dXJuIGEgc2V0IG9mIGZvbGRlcnMgcmVwcmVzZW50aW5nIHRoZSA8aT5zaGFyZWQ8L2k+IG5hbWVzcGFjZXMuCisgICAgICogQSBzaGFyZWQgbmFtZXNwYWNlIGlzIGEgbmFtZXNwYWNlIHRoYXQgY29uc2lzdHMgb2YgbWFpbCBmb2xkZXJzCisgICAgICogdGhhdCBhcmUgaW50ZW5kZWQgdG8gYmUgc2hhcmVkIGFtb25nc3QgdXNlcnMgYW5kIGRvIG5vdCBleGlzdAorICAgICAqIHdpdGhpbiBhIHVzZXIncyBwZXJzb25hbCBuYW1lc3BhY2UuIDxwPgorICAgICAqCisgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiByZXR1cm5zIGFuIGVtcHR5IGFycmF5LiAgU3ViY2xhc3NlcyBzaG91bGQKKyAgICAgKiBvdmVycmlkZSB0aGlzIG1ldGhvZCB0byByZXR1cm4gYXBwcm9wcmlhdGUgaW5mb3JtYXRpb24uCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uIAlJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBTdG9yZSBpcyBub3QgY29ubmVjdGVkLgorICAgICAqIEByZXR1cm4JCWFycmF5IG9mIEZvbGRlciBvYmplY3RzCisgICAgICovCisgICAgcHVibGljIEZvbGRlcltdIGdldFNoYXJlZE5hbWVzcGFjZXMoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uCisKKworPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisxOS4gTWFrZSBDb250ZW50RGlzcG9zaXRpb24gY2xhc3MgcHVibGljICg0MzY2MzczKQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworVGhlIGphdmF4Lm1haWwuaW50ZXJuZXQuQ29udGVudERpc3Bvc2l0aW9uIGNsYXNzIGlzIHBhY2thZ2UgcHJpdmF0ZQorYW5kIHNob3VsZCBiZSBtYWRlIHB1YmxpYy4gIFRoZSBBUEkgaXM6CisKKy8qKgorICogVGhpcyBjbGFzcyByZXByZXNlbnRzIGEgTUlNRSBDb250ZW50RGlzcG9zaXRpb24gdmFsdWUuIEl0IHByb3ZpZGVzCisgKiBtZXRob2RzIHRvIHBhcnNlIGEgQ29udGVudERpc3Bvc2l0aW9uIHN0cmluZyBpbnRvIGluZGl2aWR1YWwgY29tcG9uZW50cworICogYW5kIHRvIGdlbmVyYXRlIGEgTUlNRSBzdHlsZSBDb250ZW50RGlzcG9zaXRpb24gc3RyaW5nLgorICovCisKK3B1YmxpYyBjbGFzcyBDb250ZW50RGlzcG9zaXRpb24KKworICAgIC8qKgorICAgICAqIE5vLWFyZyBDb25zdHJ1Y3Rvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29udGVudERpc3Bvc2l0aW9uKCkKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yLgorICAgICAqCisgICAgICogQHBhcmFtCWRpc3Bvc2l0aW9uCWRpc3Bvc2l0aW9uCisgICAgICogQHBhcmFtCWxpc3QJUGFyYW1ldGVyTGlzdAorICAgICAqLworICAgIHB1YmxpYyBDb250ZW50RGlzcG9zaXRpb24oU3RyaW5nIGRpc3Bvc2l0aW9uLCBQYXJhbWV0ZXJMaXN0IGxpc3QpCisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvciB0aGF0IHRha2VzIGEgQ29udGVudERpc3Bvc2l0aW9uIHN0cmluZy4gVGhlIFN0cmluZworICAgICAqIGlzIHBhcnNlZCBpbnRvIGl0cyBjb25zdGl0dWVudHM6IGRpc3Bvc3Rpb24gYW5kIHBhcmFtZXRlcnMuIAorICAgICAqIEEgUGFyc2VFeGNlcHRpb24gaXMgdGhyb3duIGlmIHRoZSBwYXJzZSBmYWlscy4gCisgICAgICoKKyAgICAgKiBAcGFyYW0Jcwl0aGUgQ29udGVudERpc3Bvc2l0aW9uIHN0cmluZy4KKyAgICAgKiBAZXhjZXB0aW9uCVBhcnNlRXhjZXB0aW9uIGlmIHRoZSBwYXJzZSBmYWlscy4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29udGVudERpc3Bvc2l0aW9uKFN0cmluZyBzKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgZGlzcG9zaXRpb24gdmFsdWUuCisgICAgICogQHJldHVybiB0aGUgZGlzcG9zaXRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldERpc3Bvc2l0aW9uKCkKKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciB2YWx1ZS4gUmV0dXJucyA8Y29kZT5udWxsPC9jb2RlPgorICAgICAqIGlmIHRoaXMgcGFyYW1ldGVyIGlzIGFic2VudC4KKyAgICAgKiBAcmV0dXJuCXBhcmFtZXRlciB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UGFyYW1ldGVyKFN0cmluZyBuYW1lKQorCisgICAgLyoqCisgICAgICogUmV0dXJuIGEgUGFyYW1ldGVyTGlzdCBvYmplY3QgdGhhdCBob2xkcyBhbGwgdGhlIGF2YWlsYWJsZSAKKyAgICAgKiBwYXJhbWV0ZXJzLiBSZXR1cm5zIG51bGwgaWYgbm8gcGFyYW1ldGVycyBhcmUgYXZhaWxhYmxlLgorICAgICAqCisgICAgICogQHJldHVybglQYXJhbWV0ZXJMaXN0CisgICAgICovCisgICAgcHVibGljIFBhcmFtZXRlckxpc3QgZ2V0UGFyYW1ldGVyTGlzdCgpCisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHByaW1hcnkgdHlwZS4gT3ZlcnJpZGVzIGV4aXN0aW5nIHByaW1hcnkgdHlwZS4KKyAgICAgKiBAcGFyYW0JcHJpbWFyeVR5cGUJcHJpbWFyeSB0eXBlCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RGlzcG9zaXRpb24oU3RyaW5nIGRpc3Bvc2l0aW9uKQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyLiBJZiB0aGlzIHBhcmFtZXRlciBhbHJlYWR5IGV4aXN0cywKKyAgICAgKiBpdCBpcyByZXBsYWNlZCBieSB0aGlzIG5ldyB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbQluYW1lCXBhcmFtZXRlciBuYW1lCisgICAgICogQHBhcmFtCXZhbHVlCXBhcmFtZXRlciB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFBhcmFtZXRlcihTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKQorCisgICAgLyoqCisgICAgICogU2V0IGEgbmV3IFBhcmFtZXRlckxpc3QuCisgICAgICogQHBhcmFtCWxpc3QJUGFyYW1ldGVyTGlzdAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFBhcmFtZXRlckxpc3QoUGFyYW1ldGVyTGlzdCBsaXN0KQorCisgICAgLyoqCisgICAgICogUmV0cmlldmUgYSBSRkMyMDQ1IHN0eWxlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZgorICAgICAqIHRoaXMgQ29udGVudERpc3Bvc2l0aW9uLiBSZXR1cm5zIDxjb2RlPm51bGw8L2NvZGU+IGlmCisgICAgICogdGhlIGNvbnZlcnNpb24gZmFpbGVkLgorICAgICAqCisgICAgICogQHJldHVybglSRkMyMDQ1IHN0eWxlIHN0cmluZworICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKQorfQorCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKzIwLiBJbXByb3ZlIHBlcmZvcm1hbmNlIG9mIE1pbWVNZXNzYWdlICg0MzcxODYyKQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworVG8gYWxsb3cgdXMgdG8gaW1wcm92ZSB0aGUgcGVyZm9ybWFuY2Ugb2YgdGhlIE1pbWVNZXNzYWdlIGFuZCBNaW1lTXVsdGlwYXJ0CitjbGFzc2VzIHdoZW4gcGFyc2luZyBkYXRhIGZyb20gYW4gSW5wdXRTdHJlYW0sIHdlIGludHJvZHVjZSBhIG5ldworaW50ZXJmYWNlIHRoYXQgYWxsb3dzIHRoZSBkYXRhIGluIHRoZSBJbnB1dFN0cmVhbSB0byBiZSBzaGFyZWQgaW5zdGVhZAorb2YgY29waWVkLCBhbmQgd2UgdXNlIHRoaXMgbmV3IGludGVyZmFjZSBpbiBrZXkgcGFydHMgb2YgdGhlIGltcGxlbWVudGF0aW9uLgorCitUaGUgZm9sbG93aW5nIGZpZWxkIGlzIGFkZGVkIHRvIE1pbWVNZXNzYWdlOgorCisgICAgLyoqCisgICAgICogSWYgdGhlIGRhdGEgZm9yIHRoaXMgbWVzc2FnZSB3YXMgc3VwcGxpZWQgYnkgYW4KKyAgICAgKiBJbnB1dFN0cmVhbSB0aGF0IGltcGxlbWVudHMgdGhlIFNoYXJlZElucHV0U3RyZWFtIGludGVyZmFjZSwKKyAgICAgKiA8Y29kZT5jb250ZW50U3RyZWFtPC9jb2RlPiBpcyBhbm90aGVyIHN1Y2ggc3RyZWFtIHJlcHJlc2VudGluZworICAgICAqIHRoZSBjb250ZW50IG9mIHRoaXMgbWVzc2FnZS4gIEluIHRoaXMgY2FzZSwgPGNvZGU+Y29udGVudDwvY29kZT4KKyAgICAgKiB3aWxsIGJlIG51bGwuCisgICAgICovCisgICAgcHJvdGVjdGVkIElucHV0U3RyZWFtIGNvbnRlbnRTdHJlYW07CisKK1RoZSBmb2xsb3dpbmcgZmllbGQgaXMgYWRkZWQgdG8gTWltZUJvZHlQYXJ0OgorCisgICAgLyoqCisgICAgICogSWYgdGhlIGRhdGEgZm9yIHRoaXMgYm9keSBwYXJ0IHdhcyBzdXBwbGllZCBieSBhbgorICAgICAqIElucHV0U3RyZWFtIHRoYXQgaW1wbGVtZW50cyB0aGUgU2hhcmVkSW5wdXRTdHJlYW0gaW50ZXJmYWNlLAorICAgICAqIDxjb2RlPmNvbnRlbnRTdHJlYW08L2NvZGU+IGlzIGFub3RoZXIgc3VjaCBzdHJlYW0gcmVwcmVzZW50aW5nCisgICAgICogdGhlIGNvbnRlbnQgb2YgdGhpcyBib2R5IHBhcnQuICBJbiB0aGlzIGNhc2UsIDxjb2RlPmNvbnRlbnQ8L2NvZGU+CisgICAgICogd2lsbCBiZSBudWxsLgorICAgICAqLworICAgIHByb3RlY3RlZCBJbnB1dFN0cmVhbSBjb250ZW50U3RyZWFtOworCitUaGUgZm9sbG93aW5nIGludGVyZmFjZSBpcyBhZGRlZDoKKworcGFja2FnZSBqYXZheC5tYWlsLmludGVybmV0OworCisvKioKKyAqIEFuIElucHV0U3RyZWFtIHRoYXQgaXMgYmFja2VkIGJ5IGRhdGEgdGhhdCBjYW4gYmUgc2hhcmVkIGJ5IG11bHRpcGxlCisgKiByZWFkZXJzIG1heSBpbXBsZW1lbnQgdGhpcyBpbnRlcmZhY2UuICBUaGlzIGFsbG93cyB1c2VycyBvZiBzdWNoIGFuCisgKiBJbnB1dFN0cmVhbSB0byBkZXRlcm1pbmUgdGhlIGN1cnJlbnQgcG9zaXRpb25pbiB0aGUgSW5wdXRTdHJlYW0sIGFuZAorICogdG8gY3JlYXRlIG5ldyBJbnB1dFN0cmVhbXMgcmVwcmVzZW50aW5nIGEgc3Vic2V0IG9mIHRoZSBkYXRhIGluIHRoZQorICogb3JpZ2luYWwgSW5wdXRTdHJlYW0uICBUaGUgbmV3IElucHV0U3RyZWFtIHdpbGwgYWNjZXNzIHRoZSBzYW1lCisgKiB1bmRlcmx5aW5nIGRhdGEgYXMgdGhlIG9yaWdpbmFsLCB3aXRob3V0IGNvcHlpbmcgdGhlIGRhdGEuCisgKi8KKworcHVibGljIGludGVyZmFjZSBTaGFyZWRJbnB1dFN0cmVhbSB7CisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBJbnB1dFN0cmVhbSwgYXMgYW4KKyAgICAgKiBvZmZzZXQgZnJvbSB0aGUgYmVnaW5uaW5nIG9mIHRoZSBJbnB1dFN0cmVhbS4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIGN1cnJlbnQgcG9zaXRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXRQb3NpdGlvbigpOworCisgICAgLyoqCisgICAgICogUmV0dXJuIGEgbmV3IElucHV0U3RyZWFtIHJlcHJlc2VudGluZyBhIHN1YnNldCBvZiB0aGUgZGF0YQorICAgICAqIGZyb20gdGhpcyBJbnB1dFN0cmVhbSwgc3RhcnRpbmcgYXQgPGNvZGU+c3RhcnQ8L2NvZGU+IChpbmNsdXNpdmUpCisgICAgICogdXAgdG8gPGNvZGU+ZW5kPC9jb2RlPiAoZXhjbHVzaXZlKS4gIDxjb2RlPnN0YXJ0PC9jb2RlPiBtdXN0IGJlCisgICAgICogbm9uLW5lZ2F0aXZlLiAgSWYgPGNvZGU+ZW5kPC9jb2RlPiBpcyAtMSwgdGhlIG5ldyBzdHJlYW0gZW5kcworICAgICAqIGF0IHRoZSBzYW1lIHBsYWNlIGFzIHRoaXMgc3RyZWFtLiAgVGhlIHJldHVybmVkIElucHV0U3RyZWFtCisgICAgICogd2lsbCBhbHNvIGltcGxlbWVudCB0aGUgU2hhcmVkSW5wdXRTdHJlYW0gaW50ZXJmYWNlLgorICAgICAqCisgICAgICogQHBhcmFtCXN0YXJ0CXRoZSBzdGFydGluZyBwb3NpdGlvbgorICAgICAqIEBwYXJhbQllbmQJdGhlIGVuZGluZyBwb3NpdGlvbiArIDEKKyAgICAgKiBAcmV0dXJuCQl0aGUgbmV3IHN0cmVhbQorICAgICAqLworICAgIHB1YmxpYyBJbnB1dFN0cmVhbSBuZXdTdHJlYW0obG9uZyBzdGFydCwgbG9uZyBlbmQpOworfQorCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKzIxLiBOZXcgUGFyYW1ldGVyTGlzdC50b1N0cmluZyhpbnQgdXNlZCkgbWV0aG9kLgorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworVGhlIFBhcmFtZXRlckxpc3QudG9TdHJpbmcoKSBtZXRob2QgcmV0dXJucyBpdHMgcmVzdWx0cyAidW5mb2xkZWQiLiBJdAord291bGQgYmUgdXNlZnVsIHRvIGhhdmUgdGhlIHJlc3VsdHMgImZvbGRlZCIgaW4gY2VydGFpbiBzaXR1YXRpb25zLiBBCituZXcgbWV0aG9kIHdpbGwgYmUgYWRkZWQgdG8gdGhlIFBhcmFtdGVyTGlzdCBjbGFzcyB3aGljaCB3aWxsIHJldHVybgorImZvbGRlZCIgcmVzdWx0cy4gRm9sZGluZyBpcyBkZWZpbmVkIGJ5IFJGQyA4MjIgYXMgdGhlIHByb2Nlc3Mgb2Ygc3BsaXR0aW5nCithIGhlYWRlciBmaWVsZCBpbnRvIG11bHRpcGxlIGxpbmVzLiAiVGhlIGdlbmVyYWwgcnVsZSBpcyB0aGF0IHdoZXJldmVyIHRoZXJlCittYXkgYmUgbGluZWFyLXdoaXRlLXNwYWNlIChOT1Qgc2ltcGx5IExXU1AtY2hhcnMpLCBhIENSTEYgaW1tZWRpYXRlbHkKK2ZvbGxvd2VkIGJ5IEFUIExFQVNUIG9uZSBMV1NQLWNoYXIgbWF5IGluc3RlYWQgYmUgaW5zZXJ0ZWQuIiBVbmZvbGRpbmcgaXMgCit0aGUgcHJvY2VzcyBvZiByZXR1cm5pbmcgdG8gYSBzaW5nbGUgbGluZSByZXByZXNlbnRhdGlvbi4gIlVuZm9sZGluZyBpcyAKK2FjY29tcGxpc2hlZCAgYnkgcmVnYXJkaW5nIENSTEYgaW1tZWRpYXRlbHkgZm9sbG93ZWQgYnkgYSBMV1NQLWNoYXIgYXMKK2VxdWl2YWxlbnQgdG8gdGhlIExXU1AtY2hhci4iCisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0IHRoaXMgUGFyYW1ldGVyTGlzdCBpbnRvIGEgTUlNRSBTdHJpbmcuIElmIHRoaXMgaXMKKyAgICAgKiBhbiBlbXB0eSBsaXN0LCBhbiBlbXB0eSBzdHJpbmcgaXMgcmV0dXJuZWQuCisgICAgICogICAKKyAgICAgKiBUaGUgJ3VzZWQnIHBhcmFtZXRlciBzcGVjaWZpZXMgdGhlIG51bWJlciBvZiBjaGFyYWN0ZXIgcG9zaXRpb25zCisgICAgICogYWxyZWFkeSB0YWtlbiB1cCBpbiB0aGUgZmllbGQgaW50byB3aGljaCB0aGUgcmVzdWx0aW5nIGFkZHJlc3MKKyAgICAgKiBzZXF1ZW5jZSBzdHJpbmcgaXMgdG8gYmUgaW5zZXJ0ZWQuIEl0J3MgdXNlZCB0byBkZXRlcm1pbmUgd2hlcmUKKyAgICAgKiB0byAiZm9sZCIgdGhlIHJlc3VsdGluZyBwYXJhbWV0ZXIgbGlzdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1c2VkICAgICAgbnVtYmVyIG9mIGNoYXJhY3RlciBwb3NpdGlvbnMgYWxyZWFkeSB1c2VkLCBpbgorICAgICAqICAgICAgICAgICAgICAgICAgdGhlIGZpZWxkIGludG8gd2hpY2ggdGhlIHBhcmFtZXRlciBsaXN0IGlzIHRvCisgICAgICogICAgICAgICAgICAgICAgICBiZSBpbnNlcnRlZC4KKyAgICAgKiBAcmV0dXJuICAgICAgICAgIFN0cmluZworICAgICAqLyAgCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZyhpbnQgdXNlZCkKZGlmZiAtLWdpdCBhL2RvYy9zcGVjL0phdmFNYWlsLTEuMy1jaGFuZ2VzLnR4dCBiL2RvYy9zcGVjL0phdmFNYWlsLTEuMy1jaGFuZ2VzLnR4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43OGNiOTUyCi0tLSAvZGV2L251bGwKKysrIGIvZG9jL3NwZWMvSmF2YU1haWwtMS4zLWNoYW5nZXMudHh0CkBAIC0wLDAgKzEsMzAzIEBACisKKwkJSmF2YU1haWwgMS4zCisJCT09PT09PT09PT09PQorCisJCShVcGRhdGVkIEFwcmlsIDEsIDIwMDIpCisKK0ZvbGxvd2luZyBpcyBhIGRlc2NyaXB0aW9uIG9mIHRoZSBuZXcgQVBJcyB0aGF0IGFyZSBiZWluZworaW50cm9kdWNlZCBpbiBKYXZhTWFpbCAxLjMuICBUaGUgbnVtYmVycyBpbiBwYXJlbnRoZXNlcworYXJlIGJ1ZyBudW1iZXJzOyB5b3UgY2FuIGZpbmQgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUKK2J1ZyByZXBvcnRzIGF0OgorCisgICAgaHR0cDovL2RldmVsb3Blci5qYXZhLnN1bi5jb20vZGV2ZWxvcGVyL2J1Z1BhcmFkZS9pbmRleC5odG1sCisKK1BsZWFzZSBzZW5kIGNvbW1lbnRzIGFuZCBmZWVkYmFjayB0byBqYXZhbWFpbEBzdW4uY29tLgorCitNYW55IG9mIHRoZXNlIGNoYW5nZXMgZXhwYW5kIEphdmFNYWlsJ3MgY29uZm9ybWFuY2Ugd2l0aCBJbnRlcm5ldAorc3RhbmRhcmRzLCBvciBtYWtlIEphdmFNYWlsIG1vcmUgdG9sZXJhbnQgb2YgbWVzc2FnZXMgdGhhdCBkb24ndAorcXVpdGUgY29uZm9ybSB0byB0aGUgc3RhbmRhcmRzLiAgIkJlIGxpYmVyYWwgaW4gd2hhdCB5b3UgcmVjZWl2ZQorYW5kIGNvbnNlcnZhdGl2ZSBpbiB3aGF0IHlvdSBzZW5kLiIKKworCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKzEuIEFkZCBzZXRTZW5kZXIgYW5kIGdldFNlbmRlciBtZXRob2RzIHRvIE1pbWVNZXNzYWdlICg0NDA1MTE1KQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK1RoZXNlIGNvbnZlbmllbmNlIG1ldGhvZHMgc3VwcG9ydCBzZXR0aW5nIGFuZCByZWFkaW5nIHRoZSBSRkMgODIyCitTZW5kZXIgaGVhZGVyLgorCisgICAgLyoqIAorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIHRoZSBSRkMgODIyICJTZW5kZXIiIGhlYWRlciBmaWVsZC4KKyAgICAgKiBJZiB0aGUgIlNlbmRlciIgaGVhZGVyIGZpZWxkIGlzIGFic2VudCwgPGNvZGU+bnVsbDwvY29kZT4KKyAgICAgKiBpcyByZXR1cm5lZC48cD4KKyAgICAgKgorICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gdXNlcyB0aGUgPGNvZGU+Z2V0SGVhZGVyPC9jb2RlPiBtZXRob2QKKyAgICAgKiB0byBvYnRhaW4gdGhlIHJlcXVpc2l0ZSBoZWFkZXIgZmllbGQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCQlBZGRyZXNzIG9iamVjdAorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uCisgICAgICogQHNlZQkJI2hlYWRlcnMKKyAgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuMworICAgICAqLworICAgIHB1YmxpYyBBZGRyZXNzIGdldFNlbmRlcigpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgUkZDIDgyMiAiU2VuZGVyIiBoZWFkZXIgZmllbGQuIEFueSBleGlzdGluZyB2YWx1ZXMgYXJlIAorICAgICAqIHJlcGxhY2VkIHdpdGggdGhlIGdpdmVuIGFkZHJlc3MuIElmIGFkZHJlc3MgaXMgPGNvZGU+bnVsbDwvY29kZT4sCisgICAgICogdGhpcyBoZWFkZXIgaXMgcmVtb3ZlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhZGRyZXNzCXRoZSBzZW5kZXIgb2YgdGhpcyBtZXNzYWdlCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsV3JpdGVFeGNlcHRpb24gaWYgdGhlIHVuZGVybHlpbmcKKyAgICAgKgkJCWltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uCisgICAgICoJCQlvZiBleGlzdGluZyB2YWx1ZXMKKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIG1lc3NhZ2UgaXMKKyAgICAgKgkJCW9idGFpbmVkIGZyb20gYSBSRUFEX09OTFkgZm9sZGVyLgorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uCisgICAgICogQHNpbmNlCQlKYXZhTWFpbCAxLjMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRTZW5kZXIoQWRkcmVzcyBhZGRyZXNzKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uCisKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworMi4gQWRkIHNldENvbnRlbnRJRCBtZXRob2QgdG8gTWltZUJvZHlQYXJ0ICg0Mzc3NzIwKQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitUaGlzIGNvbnZlbmllbmNlIG1ldGhvZCBzdXBwb3J0cyBzZXR0aW5nIHRoZSBDb250ZW50LUlEIGhlYWRlci4KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgIkNvbnRlbnQtSUQiIGhlYWRlciBmaWVsZCBvZiB0aGlzIGJvZHkgcGFydC4KKyAgICAgKiBJZiB0aGUgPGNvZGU+Y2lkPC9jb2RlPiBwYXJhbWV0ZXIgaXMgbnVsbCwgYW55IGV4aXN0aW5nIAorICAgICAqICJDb250ZW50LUlEIiBpcyByZW1vdmVkLgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsV3JpdGVFeGNlcHRpb24gaWYgdGhlIHVuZGVybHlpbmcKKyAgICAgKgkJCWltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBib2R5IHBhcnQgaXMKKyAgICAgKgkJCW9idGFpbmVkIGZyb20gYSBSRUFEX09OTFkgZm9sZGVyLgorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uCisgICAgICogQHNpbmNlCQlKYXZhTWFpbCAxLjMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDb250ZW50SUQoU3RyaW5nIGNpZCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbgorCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKzMuIEFkZCBtYWlsLm1pbWUuY2hhcnNldCBwcm9wZXJ0eSAoNDM3NzczMSkKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworVGhlICJtYWlsLm1pbWUuY2hhcnNldCIgU3lzdGVtIHByb3BlcnR5IChOT1RFOiAqbm90KiBTZXNzaW9uIHByb3BlcnR5KQorbmFtZXMgdGhlIGRlZmF1bHQgY2hhcnNldCB0byBiZSB1c2VkIGJ5IEphdmFNYWlsLiAgSWYgbm90IHNldCwgdGhlCitzdGFuZGFyZCBKMlNFICJmaWxlLmVuY29kaW5nIiBTeXN0ZW0gcHJvcGVydHkgaXMgdXNlZC4gIFRoaXMgYWxsb3dzCithcHBsaWNhdGlvbnMgdG8gc3BlY2lmeSBhIGRlZmF1bHQgY2hhcmFjdGVyIHNldCBmb3Igc2VuZGluZyBtZXNzYWdlcwordGhhdCdzIGRpZmZlcmVudCB0aGFuIHRoZSBjaGFyYWN0ZXIgc2V0IHVzZWQgZm9yIGZpbGVzIHN0b3JlZCBvbiB0aGUKK3N5c3RlbS4gIFRoaXMgaXMgY29tbW9uIG9uIEphcGFuZXNlIHN5c3RlbXMuCisKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworNC4gQWRkIGdldERlbGV0ZWRNZXNhZ2VDb3VudCBtZXRob2QgdG8gRm9sZGVyICg0Mzg4NzMwKQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitUaGlzIGNvbnZlbmllbmNlIG1ldGhvZCB3b3VsZCByZXR1cm4gYSBjb3VudCBvZiB0aGUgbnVtYmVyIG9mIGRlbGV0ZWQKK21lc3NhZ2VzIGluIGEgZm9sZGVyLgorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBudW1iZXIgb2YgZGVsZXRlZCBtZXNzYWdlcyBpbiB0aGlzIEZvbGRlci4gPHA+CisgICAgICoKKyAgICAgKiBUaGlzIG1ldGhvZCBjYW4gYmUgaW52b2tlZCBvbiBhIGNsb3NlZCBmb2xkZXIuIEhvd2V2ZXIsIG5vdGUKKyAgICAgKiB0aGF0IGZvciBzb21lIGZvbGRlciBpbXBsZW1lbnRhdGlvbnMsIGdldHRpbmcgdGhlIGRlbGV0ZWQgbWVzc2FnZQorICAgICAqIGNvdW50IGNhbiBiZSBhbiBleHBlbnNpdmUgb3BlcmF0aW9uIGludm9sdmluZyBhY3R1YWxseSBvcGVuaW5nIAorICAgICAqIHRoZSBmb2xkZXIuIEluIHN1Y2ggY2FzZXMsIGEgcHJvdmlkZXIgY2FuIGNob29zZSBub3QgdG8gc3VwcG9ydCAKKyAgICAgKiB0aGlzIGZ1bmN0aW9uYWxpdHkgaW4gdGhlIGNsb3NlZCBzdGF0ZSwgaW4gd2hpY2ggY2FzZSB0aGlzIG1ldGhvZAorICAgICAqIG11c3QgcmV0dXJuIC0xLiA8cD4KKyAgICAgKgorICAgICAqIENsaWVudHMgaW52b2tpbmcgdGhpcyBtZXRob2Qgb24gYSBjbG9zZWQgZm9sZGVyIG11c3QgYmUgYXdhcmUKKyAgICAgKiB0aGF0IHRoaXMgaXMgYSBwb3RlbnRpYWxseSBleHBlbnNpdmUgb3BlcmF0aW9uLiBDbGllbnRzIG11c3QKKyAgICAgKiBhbHNvIGJlIHByZXBhcmVkIHRvIGhhbmRsZSBhIHJldHVybiB2YWx1ZSBvZiAtMSBpbiB0aGlzIGNhc2UuIDxwPgorICAgICAqCisgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiByZXR1cm5zIC0xIGlmIHRoaXMgZm9sZGVyIGlzIGNsb3NlZC4gRWxzZQorICAgICAqIHRoaXMgaW1wbGVtZW50YXRpb24gZ2V0cyBlYWNoIE1lc3NhZ2UgaW4gdGhlIGZvbGRlciB1c2luZworICAgICAqIDxjb2RlPmdldE1lc3NhZ2UoaW50KTwvY29kZT4gYW5kIGNoZWNrcyB3aGV0aGVyIGl0cworICAgICAqIDxjb2RlPkRFTEVURUQ8L2NvZGU+IGZsYWcgaXMgc2V0LiBUaGUgdG90YWwgbnVtYmVyIG9mIG1lc3NhZ2VzCisgICAgICogdGhhdCBoYXZlIHRoaXMgZmxhZyBzZXQgaXMgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIAkJbnVtYmVyIG9mIGRlbGV0ZWQgbWVzc2FnZXMuIC0xIG1heSBiZSByZXR1cm5lZAorICAgICAqCQkJYnkgY2VydGFpbiBpbXBsZW1lbnRhdGlvbnMgaWYgdGhpcyBtZXRob2QgaXMKKyAgICAgKgkJCWludm9rZWQgb24gYSBjbG9zZWQgZm9sZGVyLgorICAgICAqIEBleGNlcHRpb24JRm9sZGVyTm90Rm91bmRFeGNlcHRpb24gaWYgdGhpcyBmb2xkZXIgZG9lcyAKKyAgICAgKgkJCW5vdCBleGlzdC4KKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIE1lc3NhZ2luZ0V4Y2VwdGlvbgorICAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS4zCisgICAgICovCisgICAgcHVibGljIGludCBnZXREZWxldGVkTWVzc2FnZUNvdW50KCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbgorCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKzUuIFN1cHBvcnQgcGFyc2luZyAiaWxsZWdhbCIgSW50ZXJuZXQgYWRkcmVzc2VzICg0NjUwOTQwKQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK1RoZSBwYXJzZSBtZXRob2Qgb24gdGhlIEludGVybmV0QWRkcmVzcyBjbGFzcyB0YWtlcyBhIGZsYWcgdGhhdCB0ZWxscword2hldGhlciBvciBub3QgdG8gc3RyaWN0bHkgZW5mb3JjZSB0aGUgUkZDODIyIHN5bnRheCBydWxlcy4gIEN1cnJlbnRseSwKK3doZW4gdGhlIGZsYWcgaXMgZmFsc2UgbW9zdCBydWxlcyBhcmUgc3RpbGwgY2hlY2tlZCB3aGlsZSBhIGZldyBhcmUgbm90LgorVG8gYmV0dGVyIHN1cHBvcnQgdGhlIHJhbmdlIG9mICJpbnZhbGlkIiBhZGRyZXNzZXMgc2VlbiBpbiByZWFsIG1lc3NhZ2VzLAorYW5kIGluIGNvbWJpbmF0aW9uIHdpdGggdGhlIGZvbGxvd2luZyB0d28gY2hhbmdlcywgdGhlIHBhcnNlSGVhZGVyCittZXRob2Qgd291bGQgZW5mb3JjZSBmZXdlciBzeW50YXggcnVsZXMgd2hlbiB0aGUgc3RyaWN0IGZsYWcgaXMgZmFsc2UKK2FuZCB3b3VsZCBlbmZvcmNlIG1vcmUgcnVsZXMgd2hlbiB0aGUgc3RyaWN0IGZsYWcgaXMgdHJ1ZS4gIElmIHRoZQorc3RyaWN0IGZsYWcgaXMgZmFsc2UgYW5kIHRoZSBwYXJzZSBpcyBzdWNjZXNzZnVsIGluIHNlcGFyYXRpbmcgb3V0IGFuCitlbWFpbCBhZGRyZXNzIG9yIGFkZHJlc3NlcywgdGhlIHN5bnRheCBvZiB0aGUgYWRkcmVzc2VzIHRoZW1zZWx2ZXMKK3dvdWxkIG5vdCBiZSBjaGVja2VkLiAgKEludHJvZHVjaW5nIGEgbmV3IG1ldGhvZCBwcmVzZXJ2ZXMKK2NvbXBhdGliaWxpdHkgd2l0aCB1c2VycyBvZiB0aGUgZXhpc3RpbmcgcGFyc2UgbWV0aG9kLikKKworICAgIC8qKgorICAgICAqIFBhcnNlIHRoZSBnaXZlbiBzZXF1ZW5jZSBvZiBhZGRyZXNzZXMgaW50byBJbnRlcm5ldEFkZHJlc3MKKyAgICAgKiBvYmplY3RzLiAgSWYgPGNvZGU+c3RyaWN0PC9jb2RlPiBpcyBmYWxzZSwgdGhlIGZ1bGwgc3ludGF4IHJ1bGVzIGZvcgorICAgICAqIGluZGl2aWR1YWwgYWRkcmVzc2VzIGFyZSBub3QgZW5mb3JjZWQuICBJZiA8Y29kZT5zdHJpY3Q8L2NvZGU+IGlzCisgICAgICogdHJ1ZSwgbWFueSAoYnV0IG5vdCBhbGwpIG9mIHRoZSBSRkM4MjIgc3ludGF4IHJ1bGVzIGFyZSBlbmZvcmNlZC4KKyAgICAgKgorICAgICAqIE5vbi1zdHJpY3QgcGFyc2luZyBpcyB0eXBpY2FsbHkgdXNlZCB3aGVuIHBhcnNpbmcgYSBsaXN0IG9mCisgICAgICogbWFpbCBhZGRyZXNzZXMgZW50ZXJlZCBieSBhIGh1bWFuLiAgU3RyaWN0IHBhcnNpbmcgaXMgdHlwaWNhbGx5CisgICAgICogdXNlZCB3aGVuIHBhcnNpbmcgYWRkcmVzcyBoZWFkZXJzIGluIG1haWwgbWVzc2FnZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0JYWRkcmVzc2xpc3QJY29tbWEgc2VwYXJhdGVkIGFkZHJlc3Mgc3RyaW5ncworICAgICAqIEBwYXJhbQlzdHJpY3QJCWVuZm9yY2UgUkZDODIyIHN5bnRheAorICAgICAqIEByZXR1cm4JCQlhcnJheSBvZiBJbnRlcm5ldEFkZHJlc3Mgb2JqZWN0cworICAgICAqIEBleGNlcHRpb24JQWRkcmVzc0V4Y2VwdGlvbiBpZiB0aGUgcGFyc2UgZmFpbGVkCisgICAgICogQHNpbmNlCQlKYXZhTWFpbCAxLjMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEludGVybmV0QWRkcmVzc1tdIHBhcnNlSGVhZGVyKFN0cmluZyBzLCBib29sZWFuIHN0cmljdCkKKwkJCQkJICAgIHRocm93cyBBZGRyZXNzRXhjZXB0aW9uCisKKworVG8gYWxsb3cgYXBwbGljYXRpb25zIHRvIGNoZWNrIHRoZSBzeW50YXggb2YgYWRkcmVzc2VzIHRoYXQgbWlnaHQndmUKK2JlZW4gcGFyc2VkIHdpdGggdGhlIHN0cmljdCBmbGFnIHNldCB0byBmYWxzZSwgd2UgYWRkIGEgdmFsaWRhdGUKK21ldGhvZC4KKworICAgIC8qKgorICAgICAqIFZhbGlkYXRlIHRoYXQgdGhpcyBhZGRyZXNzIGNvbmZvcm1zIHRvIHRoZSBzeW50YXggcnVsZXMKKyAgICAgKiBvZiBSRkMgODIyLiAgVGhlIGN1cnJlbnQgaW1wbGVtZW50YXRpb24gY2hlY2tzIG1hbnksIG5vdAorICAgICAqIGFsbCwgc3ludGF4IHJ1bGVzLiAgTm90ZSB0aGF0LCBldmVuIHRob3VnaCB0aGUgc3ludGF4IG9mCisgICAgICogdGhlIGFkZHJlc3MgbWF5IGJlIGNvcnJlY3QsIHRoZXJlJ3Mgbm8gZ3VhcmFudGVlIHRoYXQgYQorICAgICAqIG1haWxib3ggb2YgdGhhdCBuYW1lIGV4aXN0cy4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24JQWRkcmVzc0V4Y2VwdGlvbiBpZiB0aGUgYWRkcmVzcworICAgICAqCQkJaXNuJ3QgdmFsaWQuCisgICAgICogQHNpbmNlCQlKYXZhTWFpbCAxLjMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB2YWxpZGF0ZSgpIHRocm93cyBBZGRyZXNzRXhjZXB0aW9uCisKKworVG8gY29udHJvbCB0aGUgc3RyaWN0IGZsYWcgd2hlbiBjb25zdHJ1Y3RpbmcgYSBzaW5nbGUgSW50ZXJuZXRBZGRyZXNzCitvYmplY3Qgd2UgYWRkIGEgbmV3IGNvbnN0cnVjdG9yLgorCisgICAgLyoqCisgICAgICogUGFyc2UgdGhlIGdpdmVuIHN0cmluZyBhbmQgY3JlYXRlIGFuIEludGVybmV0QWRkcmVzcy4KKyAgICAgKiBJZiA8Y29kZT5zdHJpY3Q8L2NvZGU+IGlzIGZhbHNlLCB0aGUgZGV0YWlsZWQgc3ludGF4IG9mIHRoZQorICAgICAqIGFkZHJlc3MgaXNuJ3QgY2hlY2tlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbQlhZGRyZXNzCQl0aGUgYWRkcmVzcyBpbiBSRkM4MjIgZm9ybWF0CisgICAgICogQHBhcmFtCXN0cmljdAkJZW5mb3JjZSBSRkM4MjIgc3ludGF4CisgICAgICogQGV4Y2VwdGlvbgkJQWRkcmVzc0V4Y2VwdGlvbiBpZiB0aGUgcGFyc2UgZmFpbGVkCisgICAgICogQHNpbmNlCQkJSmF2YU1haWwgMS4zCisgICAgICovCisgICAgcHVibGljIEludGVybmV0QWRkcmVzcyhTdHJpbmcgYWRkcmVzcywgYm9vbGVhbiBzdHJpY3QpCisJCQkJCQl0aHJvd3MgQWRkcmVzc0V4Y2VwdGlvbgorCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKzYuIEFkZCBtYWlsLm1pbWUuYWRkcmVzcy5zdHJpY3QgcHJvcGVydHkgKDQ2NTA5NDApCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitUaGUgTWltZU1lc3NhZ2UgY2xhc3Mgd2lsbCB1c2UgdGhlIG5ldyBwYXJzZUhlYWRlciBtZXRob2QgaW50cm9kdWNlZAorYWJvdmUgdG8gcGFyc2UgaGVhZGVycyBpbiBtZXNzYWdlcy4gIFRoZSAibWFpbC5taW1lLmFkZHJlc3Muc3RyaWN0IgorU2Vzc2lvbiBwcm9wZXJ0eSB3aWxsIGNvbnRyb2wgdGhlIHN0cmljdCBmbGFnIHBhc3NlZCB0byB0aGUgcGFyc2VIZWFkZXIKK21ldGhvZC4gIFRoZSBkZWZhdWx0IGlzIHRydWUuCisKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworNy4gQWRkIG1haWwubWltZS5kZWNvZGV0ZXh0LnN0cmljdCBwcm9wZXJ0eSAoNDIwMTIwMykKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK1JGQyAyMDQ3IHJlcXVpcmVzIHRoYXQgZW5jb2RlZCB0ZXh0IHN0YXJ0IGF0IHRoZSBiZWdpbm5pbmcgb2YgYQord2hpdGVzcGFjZSBzZXBhcmF0ZWQgd29yZC4gIFNvbWUgbWFpbGVycywgZXNwZWNpYWxseSBKYXBhbmVzZSBtYWlsZXJzLAoraW1wcm9wZXJseSBlbmNvZGUgdGV4dCBhbmQgaW5jbHVkZWQgZW5jb2RlZCB0ZXh0IGluIHRoZSBtaWRkbGUgb2Ygd29yZHMuCitUaGUgIm1haWwubWltZS5kZWNvZGV0ZXh0LnN0cmljdCIgU3lzdGVtIHByb3BlcnR5IChOT1RFOiAqbm90KiBTZXNzaW9uCitwcm9wZXJ0eSkgY29udHJvbHMgd2hldGhlciBKYXZhTWFpbCB3aWxsIGF0dGVtcHQgdG8gZGVjb2RlIHN1Y2gKK2luY29ycmVjdGx5IGVuY29kZWQgdGV4dC4gIFRoZSBkZWZhdWx0IGlzIHRydWUuCisKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworOC4gQWRkIG1haWwubWltZS5lbmNvZGVlb2wuc3RyaWN0IHByb3BlcnR5ICg0NjUwOTQ5KQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitXaGVuIGNob29zaW5nIGFuIGVuY29kaW5nIGZvciB0aGUgZGF0YSBvZiBhIG1lc3NhZ2UsIEphdmFNYWlsIGFzc3VtZXMKK3RoYXQgYW55IG9mIENSLCBMRiwgb3IgQ1JMRiBhcmUgdmFsaWQgbGluZSB0ZXJtaW5hdG9ycyBpbiBtZXNzYWdlCitwYXJ0cyB0aGF0IGNvbnRhaW4gb25seSBwcmludGFibGUgQVNDSUkgY2hhcmFjdGVycywgZXZlbiBpZiB0aGUgcGFydCBpcworbm90IGEgTUlNRSB0ZXh0IHR5cGUuICBJdCdzIGNvbW1vbiwgZXNwZWNpYWxseSBvbiBVTklYIHN5c3RlbXMsIGZvcgorZGF0YSBvZiBNSU1FIHR5cGUgYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIChmb3IgZXhhbXBsZSkgdG8gcmVhbGx5IGJlCit0ZXh0dWFsIGRhdGEgdGhhdCBzaG91bGQgYmUgdHJhbnNtaXR0ZWQgd2l0aCB0aGUgZW5jb2RpbmcgcnVsZXMgZm9yCitNSU1FIHRleHQuICBJbiByYXJlIGNhc2VzLCBzdWNoIHB1cmUgQVNDSUkgdGV4dCBtYXkgaW4gZmFjdCBiZSBiaW5hcnkKK2RhdGEgaW4gd2hpY2ggdGhlIENSIGFuZCBMRiBjaGFyYWN0ZXJzIG11c3QgYmUgcHJlc2VydmVkIGV4YWN0bHkuICBUaGUKKyJtYWlsLm1pbWUuZW5jb2RlZW9sLnN0cmljdCIgU3lzdGVtIHByb3BlcnR5IChOT1RFOiAqbm90KiBTZXNzaW9uCitwcm9wZXJ0eSkgY29udHJvbHMgd2hldGhlciBKYXZhTWFpbCB3aWxsIGNvbnNpZGVyIGEgbG9uZSBDUiBvciBMRiBpbiBhCitib2R5IHBhcnQgdGhhdCdzIG5vdCBhIE1JTUUgdGV4dCB0eXBlIHRvIGluZGljYXRlIHRoYXQgdGhlIGJvZHkgcGFydAorbmVlZHMgdG8gYmUgZW5jb2RlZC4KKworPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCis5LiBBZGQgaXNHcm91cCBhbmQgZ2V0R3JvdXAgbWV0aG9kcyB0byBJbnRlcm5ldEFkZHJlc3MgKDQ2NTA5NTIpCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK1RvIGJldHRlciBzdXBwb3J0IFJGQzgyMiBncm91cCBhZGRyZXNzZXMsIHRoZSBmb2xsb3dpbmcgbWV0aG9kcword291bGQgYmUgYWRkZWQuCisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGlzIGFkZHJlc3MgaXMgYW4gUkZDIDgyMiBncm91cCBhZGRyZXNzLgorICAgICAqIE5vdGUgdGhhdCBhIGdyb3VwIGFkZHJlc3MgaXMgZGlmZmVyZW50IHRoYW4gdGhlIG1haWxpbmcKKyAgICAgKiBsaXN0IGFkZHJlc3NlcyBzdXBwb3J0ZWQgYnkgbW9zdCBtYWlsIHNlcnZlcnMuICBHcm91cCBhZGRyZXNzZXMKKyAgICAgKiBhcmUgcmFyZWx5IHVzZWQ7IHNlZSBSRkMgODIyIGZvciBkZXRhaWxzLgorICAgICAqCisgICAgICogQHJldHVybgkJdHJ1ZSBpZiB0aGlzIGFkZHJlc3MgcmVwcmVzZW50cyBhIGdyb3VwCisgICAgICogQHNpbmNlCQlKYXZhTWFpbCAxLjMKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0dyb3VwKCkKKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgbWVtYmVycyBvZiBhIGdyb3VwIGFkZHJlc3MuICBBIGdyb3VwIG1heSBoYXZlIHplcm8sCisgICAgICogb25lLCBvciBtb3JlIG1lbWJlcnMuICBJZiB0aGlzIGFkZHJlc3MgaXMgbm90IGEgZ3JvdXAsIG51bGwKKyAgICAgKiBpcyByZXR1cm5lZC4gIFRoZSA8Y29kZT5zdHJpY3Q8L2NvZGU+IHBhcmFtZXRlciBjb250cm9scyB3aGV0aGVyCisgICAgICogdGhlIGdyb3VwIGxpc3QgaXMgcGFyc2VkIHVzaW5nIHN0cmljdCBSRkMgODIyIHJ1bGVzIG9yIG5vdC4KKyAgICAgKiBUaGUgcGFyc2luZyBpcyBkb25lIHVzaW5nIHRoZSA8Y29kZT5wYXJzZUhlYWRlcjwvY29kZT4gbWV0aG9kLgorICAgICAqCisgICAgICogQHJldHVybgkJYXJyYXkgb2YgSW50ZXJuZXRBZGRyZXNzIG9iamVjdHMsIG9yIG51bGwKKyAgICAgKiBAZXhjZXB0aW9uCUFkZHJlc3NFeGNlcHRpb24gaWYgdGhlIGdyb3VwIGxpc3QgY2FuJ3QgYmUgcGFyc2VkCisgICAgICogQHNpbmNlCQlKYXZhTWFpbCAxLjMKKyAgICAgKi8KKyAgICBwdWJsaWMgSW50ZXJuZXRBZGRyZXNzW10gZ2V0R3JvdXAoYm9vbGVhbiBzdHJpY3QpIHRocm93cyBBZGRyZXNzRXhjZXB0aW9uCisKKworPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisxMC4gU3VwcG9ydCBwZXItc2Vzc2lvbiBkZWJ1ZyBvdXRwdXQgc3RyZWFtICg0NTE3Njg2KQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworVG8gYWxsb3cgdGhlIGRlYnVnZ2luZyBvdXRwdXQgZm9yIGEgc2Vzc2lvbiB0byBiZSByZWRpcmVjdGVkLCB3ZSBhZGQKK3RoZSBmb2xsb3dpbmcgbWV0aG9kcyB0byBTZXNzaW9uLgorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBzdHJlYW0gdG8gYmUgdXNlZCBmb3IgZGVidWdnaW5nIG91dHB1dCBmb3IgdGhpcyBzZXNzaW9uLgorICAgICAqIElmIDxjb2RlPm91dDwvY29kZT4gaXMgbnVsbCwgPGNvZGU+U3lzdGVtLm91dDwvY29kZT4gd2lsbCBiZSB1c2VkLgorICAgICAqIE5vdGUgdGhhdCBkZWJ1Z2dpbmcgb3V0cHV0IHRoYXQgb2NjdXJzIGJlZm9yZSBhbnkgc2Vzc2lvbiBpcyBjcmVhdGVkLAorICAgICAqIGFzIGEgcmVzdWx0IG9mIHNldHRpbmcgdGhlIDxjb2RlPm1haWwuZGVidWc8L2NvZGU+IHN5c3RlbSBwcm9wZXJ0eSwKKyAgICAgKiB3aWxsIGFsd2F5cyBiZSBzZW50IHRvIDxjb2RlPlN5c3RlbS5vdXQ8L2NvZGU+LgorICAgICAqCisgICAgICogQHBhcmFtCW91dAl0aGUgUHJpbnRTdHJlYW0gdG8gdXNlIGZvciBkZWJ1Z2dpbmcgb3V0cHV0CisgICAgICogQHNpbmNlCQlKYXZhTWFpbCAxLjMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXREZWJ1Z091dChQcmludFN0cmVhbSBvdXQpCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzdHJlYW0gdG8gYmUgdXNlZCBmb3IgZGVidWdnaW5nIG91dHB1dC4gIElmIG5vIHN0cmVhbQorICAgICAqIGhhcyBiZWVuIHNldCwgPGNvZGU+U3lzdGVtLm91dDwvY29kZT4gaXMgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCQl0aGUgUHJpbnRTdHJlYW0gdG8gdXNlIGZvciBkZWJ1Z2dpbmcgb3V0cHV0CisgICAgICogQHNpbmNlCQlKYXZhTWFpbCAxLjMKKyAgICAgKi8KKyAgICBwdWJsaWMgUHJpbnRTdHJlYW0gZ2V0RGVidWdPdXQoKQpkaWZmIC0tZ2l0IGEvZG9jL3NwZWMvSmF2YU1haWwtMS40LWNoYW5nZXMudHh0IGIvZG9jL3NwZWMvSmF2YU1haWwtMS40LWNoYW5nZXMudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQwMzA5OTYKLS0tIC9kZXYvbnVsbAorKysgYi9kb2Mvc3BlYy9KYXZhTWFpbC0xLjQtY2hhbmdlcy50eHQKQEAgLTAsMCArMSwxMDYxIEBACisKKwkJSmF2YU1haWwgMS40CisJCT09PT09PT09PT09PQorCisJCShVcGRhdGVkIEF1Z3VzdCAxNSwgMjAwNSkKKworRm9sbG93aW5nIGlzIGEgZGVzY3JpcHRpb24gb2YgdGhlIG5ldyBBUElzIHRoYXQgYXJlIGJlaW5nCitpbnRyb2R1Y2VkIGluIEphdmFNYWlsIDEuNC4gIFRoZSBudW1iZXJzIGluIHBhcmVudGhlc2VzCithcmUgYnVnIG51bWJlcnM7IHlvdSBjYW4gZmluZCBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHRoZQorYnVnIHJlcG9ydHMgYXQ6CisKKyAgICBodHRwOi8vYnVncy5zdW4uY29tL2J1Z2RhdGFiYXNlL2luZGV4LmpzcAorCitQbGVhc2Ugc2VuZCBjb21tZW50cyBhbmQgZmVlZGJhY2sgdG8gamF2YW1haWxAc3VuLmNvbS4KKworTWFueSBvZiB0aGVzZSBjaGFuZ2VzIGV4cGFuZCBKYXZhTWFpbCdzIGNvbmZvcm1hbmNlIHdpdGggSW50ZXJuZXQKK3N0YW5kYXJkcywgb3IgbWFrZSBKYXZhTWFpbCBtb3JlIHRvbGVyYW50IG9mIG1lc3NhZ2VzIHRoYXQgZG9uJ3QKK3F1aXRlIGNvbmZvcm0gdG8gdGhlIHN0YW5kYXJkcy4gICJCZSBsaWJlcmFsIGluIHdoYXQgeW91IHJlY2VpdmUKK2FuZCBjb25zZXJ2YXRpdmUgaW4gd2hhdCB5b3Ugc2VuZC4iCisKK0phdmFNYWlsIDEuNCB3aWxsIGFsc28gcmVxdWlyZSBhdCBsZWFzdCBKMlNFIDEuNC4gIFRoaXMgYWxsb3dzCitKYXZhTWFpbCB0byB0YWtlIGFkdmFudGFnZSBvZiBmZWF0dXJlcyBvZiBtb3JlIG1vZGVybiBKMlNFIHJlbGVhc2VzLgorCisKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworMS4gQWRkIE1pbWVQYXJ0LnNldFRleHQodGV4dCwgY2hhcnNldCwgc3VidHlwZSkgbWV0aG9kICg2MzAwNzY1KQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitUaGUgc2V0VGV4dCBtZXRob2QgaXMgYSBjb252ZW5pZW5jZSBtZXRob2QgdXNlZCB0byBzZXQgdGhlIGNvbnRlbnQKK2ZvciBhIHRleHQvcGxhaW4gcGFydC4gIFdpdGggdGhlIGluY3JlYXNlZCB1c2Ugb2YgSFRNTCBhbmQgWE1MIGluCittYWlsIG1lc3NhZ2VzLCBpdCB3b3VsZCBiZSB1c2VmdWwgdG8gaGF2ZSBhIGNvbnZlbmllbmNlIG1ldGhvZCB0bworc2V0IGNvbnRlbnQgb2YgdGhvc2UgdHlwZXMgYXMgd2VsbC4gIFRvIHN1cHBvcnQgdGhpcyB1c2FnZSB3ZSBhZGQKK2EgbmV3IG1ldGhvZCB0byB0aGUgTWltZVBhcnQgaW50ZXJmYWNlOgorCisgICAgLyoqCisgICAgICogQ29udmVuaWVuY2UgbWV0aG9kIHRoYXQgc2V0cyB0aGUgZ2l2ZW4gU3RyaW5nIGFzIHRoaXMgcGFydCdzCisgICAgICogY29udGVudCwgd2l0aCBhIHByaW1hcnkgTUlNRSB0eXBlIG9mICJ0ZXh0IiBhbmQgdGhlIHNwZWNpZmllZAorICAgICAqIE1JTUUgc3VidHlwZS4gIFRoZSBnaXZlbiBVbmljb2RlIHN0cmluZyB3aWxsIGJlIGNoYXJzZXQtZW5jb2RlZAorICAgICAqIHVzaW5nIHRoZSBzcGVjaWZpZWQgY2hhcnNldC4gVGhlIGNoYXJzZXQgaXMgYWxzbyB1c2VkIHRvIHNldAorICAgICAqIHRoZSAiY2hhcnNldCIgcGFyYW1ldGVyLgorICAgICAqCisgICAgICogQHBhcmFtCXRleHQJdGhlIHRleHQgY29udGVudCB0byBzZXQKKyAgICAgKiBAcGFyYW0JY2hhcnNldAl0aGUgY2hhcnNldCB0byB1c2UgZm9yIHRoZSB0ZXh0CisgICAgICogQHBhcmFtCXN1YnR5cGUJdGhlIE1JTUUgc3VidHlwZSB0byB1c2UgKGUuZy4sICJodG1sIikKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbglpZiBhbiBlcnJvciBvY2N1cnMKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS40CisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0VGV4dChTdHJpbmcgdGV4dCwgU3RyaW5nIGNoYXJzZXQsIFN0cmluZyBzdWJ0eXBlKQorICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworVGhlIE1pbWVNZXNzYWdlIGFuZCBNaW1lQm9keVBhcnQgY2xhc3Nlcywgd2hpY2ggaW1wbGVtZW50IHRoZQorTWltZVBhcnQgaW50ZXJmYWNlLCB3aWxsIGJlIHVwZGF0ZWQgdG8gcHJvdmlkZSBpbXBsZW1lbnRhdGlvbnMKK29mIHRoZSBuZXcgbWV0aG9kLgorCisKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworMi4gQWRkIG1haWwubWltZS5lbmNvZGVmaWxlbmFtZSBhbmQgZGVjb2RlZmlsZW5hbWUgcHJvcGVydGllcyAoNjMwMDc2OCkKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0FjY29yZGluZyB0byB0aGUgTUlNRSBzcGVjIChSRkMgMjA0NyksIGZpbGVuYW1lcyBpbmNsdWRlZCBpbiB0aGUKK2ZpbGVuYW1lIHBhcmFtZXRlciBvZiB0aGUgQ29udGVudC1EaXNwb3NpdGlvbiBoZWFkZXIgbWF5IG5vdAoraW5jbHVkZSBNSU1FICJlbmNvZGVkLXdvcmRzIiwgYW5kIHRodXMgbWF5IGNvbnRhaW4gb25seSBVUy1BU0NJSQorY2hhcmFjdGVycy4gIEhvd2V2ZXIsIG1hbnkgbWFpbGVycyB2aW9sYXRlIHRoaXMgc3BlYyByZXF1aXJlbWVudAorYW5kIHVzZSBzdGFuZGFyZCBNSU1FIGVuY29kaW5nIHRlY2huaXF1ZXMgdG8gc3RvcmUgbm9uLUFTQ0lJCitmaWxlbmFtZXMgaW4gdGhpcyBmaWxlbmFtZSBwYXJhbWV0ZXIuCisKK0lmIHRoZSBtYWlsLm1pbWUuZW5jb2RlZmlsZW5hbWUgU3lzdGVtIHByb3BlcnR5IGlzIHNldCB0byAidHJ1ZSIuCit0aGUgTWltZU1lc3NhZ2UgYW5kIE1pbWVCb2R5UGFydCBzZXRGaWxlTmFtZSBtZXRob2RzIHdpbGwgdXNlIHRoZQorTWltZVV0aWxpdHkuZW5jb2RlVGV4dCBtZXRob2QgdG8gZW5jb2RlIHRoZSBmaWxlbmFtZS4KKworSWYgdGhlIG1haWwubWltZS5kZWNvZGVmaWxlbmFtZSBTeXN0ZW0gcHJvcGVydHkgaXMgc2V0IHRvICJ0cnVlIi4KK3RoZSBNaW1lTWVzc2FnZSBhbmQgTWltZUJvZHlQYXJ0IGdldEZpbGVOYW1lIG1ldGhvZHMgd2lsbCB1c2UgdGhlCitNaW1lVXRpbGl0eS5kZWNvZGVUZXh0IG1ldGhvZCB0byBkZWNvZGUgdGhlIGZpbGVuYW1lLgorCitCb3RoIG9mIHRoZXNlIHByb3BlcnRpZXMgZGVmYXVsdCB0byAiZmFsc2UiLgorCitUaGUgZm9sbG93aW5nIHRleHQgaXMgYWRkZWQgdG8gdGhlIE1pbWVNZXNzYWdlIGFuZCBNaW1lQm9keVBhcnQKK3NldEZpbGVOYW1lIG1ldGhvZHM6CisKKyAgICAgKiBJZiB0aGUgPGNvZGU+bWFpbC5taW1lLmVuY29kZWZpbGVuYW1lPC9jb2RlPiBTeXN0ZW0gcHJvcGVydHkKKyAgICAgKiBpcyBzZXQgdG8gdHJ1ZSwgdGhlIHtAbGluayBNaW1lVXRpbGl0eSNlbmNvZGVUZXh0CisgICAgICogTWltZVV0aWxpdHkuZW5jb2RlVGV4dCBtZXRob2Qgd2lsbCBiZSB1c2VkIHRvIGVuY29kZSB0aGUKKyAgICAgKiBmaWxlbmFtZS4gIFdoaWxlIHN1Y2ggZW5jb2RpbmcgaXMgbm90IHN1cHBvcnRlZCBieSB0aGUgTUlNRQorICAgICAqIHNwZWMsIG1hbnkgbWFpbGVycyB1c2UgdGhpcyB0ZWNobmlxdWUgdG8gc3VwcG9ydCBub24tQVNDSUkKKyAgICAgKiBjaGFyYWN0ZXJzIGluIGZpbGVuYW1lcy4gIFRoZSBkZWZhdWx0IHZhbHVlIG9mIHRoaXMgcHJvcGVydHkKKyAgICAgKiBpcyBmYWxzZS4KKworVGhlIGZvbGxvd2luZyB0ZXh0IGlzIGFkZGVkIHRvIHRoZSBNaW1lTWVzc2FnZSBhbmQgTWltZUJvZHlQYXJ0CitnZXRGaWxlTmFtZSBtZXRob2RzOgorCisgICAgICogSWYgdGhlIDxjb2RlPm1haWwubWltZS5lbmNvZGVmaWxlbmFtZTwvY29kZT4gU3lzdGVtIHByb3BlcnR5CisgICAgICogaXMgc2V0IHRvIHRydWUsIHRoZSB7QGxpbmsgTWltZVV0aWxpdHkjZGVjb2RlVGV4dAorICAgICAqIE1pbWVVdGlsaXR5LmRlY29kZVRleHQgbWV0aG9kIHdpbGwgYmUgdXNlZCB0byBkZWNvZGUgdGhlCisgICAgICogZmlsZW5hbWUuICBXaGlsZSBzdWNoIGVuY29kaW5nIGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhlIE1JTUUKKyAgICAgKiBzcGVjLCBtYW55IG1haWxlcnMgdXNlIHRoaXMgdGVjaG5pcXVlIHRvIHN1cHBvcnQgbm9uLUFTQ0lJCisgICAgICogY2hhcmFjdGVycyBpbiBmaWxlbmFtZXMuICBUaGUgZGVmYXVsdCB2YWx1ZSBvZiB0aGlzIHByb3BlcnR5CisgICAgICogaXMgZmFsc2UuCisKKworPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCiszLiBBZGQgU2VydmljZS5jb25uZWN0KHVzZXIsIHBhc3N3b3JkKSAoNjMwMDc3MSkKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitUaGlzIGNvbnZlbmllbmNlIG1ldGhvZCB1c2VzIHRoZSBob3N0IGFscmVhZHkga25vd24gdG8gdGhlIFNlcnZpY2UKKyhUcmFuc3BvcnQgb3IgU3RvcmUpLiAgRXF1aXZhbGVudCB0byBjb25uZWN0KG51bGwsIHVzZXIsIHBhc3N3b3JkKS4KKworICAgIC8qKgorICAgICAqIENvbm5lY3QgdG8gdGhlIGN1cnJlbnQgaG9zdCB1c2luZyB0aGUgc3BlY2lmaWVkIHVzZXJuYW1lCisgICAgICogYW5kIHBhc3N3b3JkLiAgVGhpcyBtZXRob2QgaXMgZXF1aXZhbGVudCB0byBjYWxsaW5nIHRoZQorICAgICAqIDxjb2RlPmNvbm5lY3QoaG9zdCwgdXNlciwgcGFzc3dvcmQpPC9jb2RlPiBtZXRob2Qgd2l0aCBudWxsCisgICAgICogZm9yIHRoZSBob3N0IG5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdXNlciAgICAgIHRoZSB1c2VyIG5hbWUKKyAgICAgKiBAcGFyYW0gcGFzc3dvcmQgIHRoaXMgdXNlcidzIHBhc3N3b3JkCisgICAgICogQGV4Y2VwdGlvbiBBdXRoZW50aWNhdGlvbkZhaWxlZEV4Y2VwdGlvbiBmb3IgYXV0aGVudGljYXRpb24gZmFpbHVyZXMKKyAgICAgKiBAZXhjZXB0aW9uIE1lc3NhZ2luZ0V4Y2VwdGlvbiAgICAgICAgICAgIGZvciBvdGhlciBmYWlsdXJlcworICAgICAqIEBleGNlcHRpb24gSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoZSBzZXJ2aWNlIGlzIGFscmVhZHkgY29ubmVjdGVkCisgICAgICogQHNlZSBqYXZheC5tYWlsLmV2ZW50LkNvbm5lY3Rpb25FdmVudAorICAgICAqIEBzZWUgamF2YXgubWFpbC5TZXNzaW9uI3NldFBhc3N3b3JkQXV0aGVudGljYXRpb24KKyAgICAgKiBAc2VlICNjb25uZWN0KGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcpCisgICAgICogQHNpbmNlCQlKYXZhTWFpbCAxLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjb25uZWN0KFN0cmluZyB1c2VyLCBTdHJpbmcgcGFzc3dvcmQpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24KKworCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKzQuIEFkZCBtYWlsLm1pbWUubXVsdGlwYXJ0Lmlnbm9yZW1pc3NpbmdlbmRib3VuZGFyeSBTeXN0ZW0gcHJvcGVydHkgKDQ5NzEzODEpCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitUaGUgY3VycmVudCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgTWltZU11bHRpcGFydCBjbGFzcyB3aWxsCitpZ25vcmUgYSBtaXNzaW5nIGVuZCBib3VuZGFyeSBsaW5lOyBpZiBFT0YgaXMgcmVhY2hlZCB3aGVuCitwYXJzaW5nIHRoZSBjb250ZW50IGJlZm9yZSBzZWVpbmcgYW4gZW5kIGJvdW5kYXJ5IGxpbmUsIHRoZQorbGFzdCBwYXJ0IG9mIHRoZSBtdWx0aXBhcnQgaXMgdGVybWluYXRlZCBhbmQgbm8gZXJyb3IgaXMKK3JldHVybmVkLgorCitTb21lIHVzZXJzIGhhdmUgcmVxdWVzdGVkIGEgd2F5IHRvIGZvcmNlIHRoZSBtdWx0aXBhcnQKK3BhcnNpbmcgdG8gbW9yZSBzdHJpY3RseSBlbmZvcmNlIHRoZSBNSU1FIHNwZWNpZmljYXRpb24uCitUbyBzdXBwb3J0IHRoaXMgd2Ugd2UgaW50cm9kdWNlIGEgbmV3IFN5c3RlbSBwcm9wZXJ0eToKKworICAgIG1haWwubWltZS5tdWx0aXBhcnQuaWdub3JlbWlzc2luZ2VuZGJvdW5kYXJ5CisKK0lmIHRoaXMgcHJvcGVydHkgaXMgc2V0IHRvICJmYWxzZSIgTWltZU11bHRpcGFydCB3aWxsIHRocm93IGEKK01lc3NhZ2luZ0V4Y2VwdGlvbiB3aGVuIHBhcnNpbmcgYSBtdWx0aXBhcnQgdGhhdCBkb2VzIG5vdAoraW5jbHVkZSB0aGUgcHJvcGVyIGVuZCBib3VuZGFyeSBsaW5lLgorCitUaGlzIHByb3BlcnR5IGlzIGFscmVhZHkgc3VwcG9ydGVkIGFzIHBhcnQgb2YgdGhlIEphdmFNYWlsCitpbXBsZW1lbnRhdGlvbi4gIFRoaXMgY2hhbmdlIG1ha2VzIHRoZSBwcm9wZXJ0eSBhIHBhcnQgb2YgdGhlCitzdGFuZGFyZCBBUEkuCisKKyAqIFRoZSA8Y29kZT5tYWlsLm1pbWUubXVsdGlwYXJ0Lmlnbm9yZW1pc3NpbmdlbmRib3VuZGFyeTwvY29kZT4KKyAqIFN5c3RlbSBwcm9wZXJ0eSBtYXkgYmUgc2V0IHRvIDxjb2RlPmZhbHNlPC9jb2RlPiB0byBjYXVzZSBhCisgKiA8Y29kZT5NZXNzYWdpbmdFeGNlcHRpb248L2NvZGU+IHRvIGJlIHRocm93biBpZiB0aGUgbXVsdGlwYXJ0CisgKiBkYXRhIGRvZXMgbm90IGVuZCB3aXRoIHRoZSByZXF1aXJlZCBlbmQgYm91bmRhcnkgbGluZS4gIElmIHRoaXMKKyAqIHByb3BlcnR5IGlzIHNldCB0byA8Y29kZT50cnVlPC9jb2RlPiBvciBub3Qgc2V0LCBtaXNzaW5nIGVuZAorICogYm91bmRhcmllcyBhcmUgbm90IGNvbnNpZGVyZWQgYW4gZXJyb3IgYW5kIHRoZSBmaW5hbCBib2R5IHBhcnQKKyAqIGVuZHMgYXQgdGhlIGVuZCBvZiB0aGUgZGF0YS4gPHA+CisKKworPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCis1LiBBZGQgTWltZU11bHRpcGFydC5pc0NvbXBsZXRlKCkgbWV0aG9kICg2MzAwODExKQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworQXMgZGVzY3JpYmVkIGFib3ZlLCBwYXJzaW5nIG9mIGEgTUlNRSBtdWx0aXBhcnQgbWF5IHRlcm1pbmF0ZQord2l0aG91dCBhbiBlcnJvciwgZXZlbiB0aG91Z2ggbm8gZmluYWwgYm91bmRhcnkgbGluZSB3YXMgc2Vlbi4KK1RoaXMgbWV0aG9kIHdpbGwgcmV0dXJuIHRydWUgaWYgdGhlIGZpbmFsIGJvdW5kYXJ5IGxpbmUgd2FzCitzZWVuLiAgVGhpcyB3aWxsIGFsbG93IGFwcGxpY2F0aW9ucyB0byBzdWNjZXNzZnVsbHkgcGFyc2UKK21hbC1mb3JtZWQgbWVzc2FnZXMsIHdoaWxlIGFsc28gYmVpbmcgYWJsZSB0byB0ZWxsIHRoYXQgdGhleQord2VyZSBtYWwtZm9ybWVkLgorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRydWUgaWYgdGhlIGZpbmFsIGJvdW5kYXJ5IGxpbmUgZm9yIHRoaXMKKyAgICAgKiBtdWx0aXBhcnQgd2FzIHNlZW4uICBXaGVuIHBhcnNpbmcgbXVsdGlwYXJ0IGNvbnRlbnQsCisgICAgICogdGhpcyBjbGFzcyB3aWxsIChieSBkZWZhdWx0KSB0ZXJtaW5hdGUgcGFyc2luZyB3aXRoCisgICAgICogbm8gZXJyb3IgaWYgdGhlIGVuZCBvZiBpbnB1dCBpcyByZWFjaGVkIGJlZm9yZSBzZWVpbmcKKyAgICAgKiB0aGUgZmluYWwgbXVsdGlwYXJ0IGJvdW5kYXJ5IGxpbmUuICBJbiBzdWNoIGEgY2FzZSwKKyAgICAgKiB0aGlzIG1ldGhvZCB3aWxsIHJldHVybiBmYWxzZS4gIChJZiB0aGUgU3lzdGVtIHByb3BlcnR5CisgICAgICogIm1haWwubWltZS5tdWx0aXBhcnQuaWdub3JlbWlzc2luZ2VuZGJvdW5kYXJ5IiBpcyBzZXQgdG8KKyAgICAgKiBmYWxzZSwgcGFyc2luZyBzdWNoIGEgbWVzc2FnZSB3aWxsIGluc3RlYWQgdGhyb3cgYQorICAgICAqIE1lc3NhZ2luZ0V4Y2VwdGlvbi4pCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRydWUgaWYgdGhlIGZpbmFsIGJvdW5kYXJ5IGxpbmUgd2FzIHNlZW4KKyAgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuNAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzQ29tcGxldGUoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uCisKKworPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCis2LiBBZGQgbWFpbC5taW1lLm11bHRpcGFydC5pZ25vcmVtaXNzaW5nYm91bmRhcnlwYXJhbWV0ZXIgcHJvcGVydHkgKDYzMDA4MTQpCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK1RoZSBmb2xsb3dpbmcgcHJvcGVydHkgaXMgYWxyZWFkeSBzdXBwb3J0ZWQgYXMgcGFydCBvZiB0aGUgSmF2YU1haWwKK2ltcGxlbWVudGF0aW9uLiAgVGhpcyBjaGFuZ2UgbWFrZXMgdGhlIHByb3BlcnR5IGEgcGFydCBvZiB0aGUKK3N0YW5kYXJkIEFQSS4KKworICogVGhlIDxjb2RlPm1haWwubWltZS5tdWx0aXBhcnQuaWdub3JlbWlzc2luZ2JvdW5kYXJ5cGFyYW1ldGVyPC9jb2RlPgorICogU3lzdGVtIHByb3BlcnR5IG1heSBiZSBzZXQgdG8gPGNvZGU+ZmFsc2U8L2NvZGU+IHRvIGNhdXNlIGEKKyAqIDxjb2RlPk1lc3NhZ2luZ0V4Y2VwdGlvbjwvY29kZT4gdG8gYmUgdGhyb3duIGlmIHRoZSBDb250ZW50LVR5cGUKKyAqIG9mIHRoZSBNaW1lTXVsdGlwYXJ0IGRvZXMgbm90IGluY2x1ZGUgYSA8Y29kZT5ib3VuZGFyeTwvY29kZT4gcGFyYW1ldGVyLgorICogSWYgdGhpcyBwcm9wZXJ0eSBpcyBzZXQgdG8gPGNvZGU+dHJ1ZTwvY29kZT4gb3Igbm90IHNldCwgdGhlIG11bHRpcGFydAorICogcGFyc2luZyBjb2RlIHdpbGwgbG9vayBmb3IgYSBsaW5lIHRoYXQgbG9va3MgbGlrZSBhIGJvdW5hcnkgbGluZSBhbmQKKyAqIHVzZSB0aGF0IGFzIHRoZSBib3VuZGFyeSBzZXBhcmF0aW5nIHRoZSBwYXJ0cy4KKworCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKzcuIEFkZCBNaW1lTXVsdGlwYXJ0IGdldFByZWFtYmxlIGFuZCBzZXRQcmVhbWJsZSBtZXRob2RzICg2MzAwODI4KQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0luIGEgTUlNRSBtdWx0aXBhcnQgbWVzc2FnZSwgaXQncyBwb3NzaWJsZSB0byBpbmNsdWRlIHRleHQgYmV0d2VlbgordGhlIGhlYWRlcnMgYW5kIHRoZSBmaXJzdCBib3VuZGFyeSBsaW5lLiAgVGhpcyB0ZXh0IGlzIGNhbGxlZCB0aGUKK3ByZWFtYmxlLiAgSXQgbWF5IGluY2x1ZGUgaW5zdHJ1Y3Rpb25zIGZvciB1c2VycyBvZiBub24tTUlNRQorY29tcGxpYW50IHNvZnR3YXJlLiAgVGhlIGdldFByZWFtYmxlIG1ldGhvZCBhbGxvd3MgYWNjZXNzIHRvIHRoaXMKK3RleHQgd2hlbiBhdmFpbGFibGUuICAoTm90ZSB0aGF0IElNQVAgc2VydmVycyBwcm92aWRlIG5vIGNvbnZlbmllbnQKK2FjY2VzcyB0byB0aGlzIHRleHQuKSAgVGhlIHNldFByZWFtYmxlIG1ldGhvZCBhbGxvd3MgYW4gYXBwbGljYXRpb24KK3RvIHNldCB0aGUgcHJlYW1ibGUgZm9yIGEgbWVzc2FnZSBiZWluZyBjb25zdHJ1Y3RlZC4KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgcHJlYW1ibGUgdGV4dCwgaWYgYW55LCB0aGF0IGFwcGVhcnMgYmVmb3JlIHRoZQorICAgICAqIGZpcnN0IGJvZHkgcGFydCBvZiB0aGlzIG11bHRpcGFydC4gIFNvbWUgcHJvdG9jb2xzLAorICAgICAqIHN1Y2ggYXMgSU1BUCwgd2lsbCBub3QgYWxsb3cgYWNjZXNzIHRvIHRoZSBwcmVhbWJsZSB0ZXh0LgorICAgICAqCisgICAgICogQHJldHVybgkJdGhlIHByZWFtYmxlIHRleHQsIG9yIG51bGwgaWYgbm8gcHJlYW1ibGUKKyAgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuNAorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UHJlYW1ibGUoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uCisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHByZWFtYmxlIHRleHQgdG8gYmUgaW5jbHVkZWQgYmVmb3JlIHRoZSBmaXJzdAorICAgICAqIGJvZHkgcGFydC4gIEFwcGxpY2F0aW9ucyBzaG91bGQgZ2VuZXJhbGx5IG5vdCBpbmNsdWRlCisgICAgICogYW55IHByZWFtYmxlIHRleHQuICBJbiBzb21lIGNhc2VzIGl0IG1heSBiZSBoZWxwZnVsIHRvCisgICAgICogaW5jbHVkZSBwcmVhbWJsZSB0ZXh0IHdpdGggaW5zdHJ1Y3Rpb25zIGZvciB1c2VycyBvZgorICAgICAqIHByZS1NSU1FIHNvZnR3YXJlLgorICAgICAqCisgICAgICogQHBhcmFtCXByZWFtYmxlCXRoZSBwcmVhbWJsZSB0ZXh0CisgICAgICogQHNpbmNlCQlKYXZhTWFpbCAxLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRQcmVhbWJsZShTdHJpbmcgcHJlYW1ibGUpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24KKworCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKzguIEFkZCBNaW1lTWVzc2FnZS51cGRhdGVNZXNzYWdlSUQoKSBwcm90ZWN0ZWQgbWV0aG9kICg2MzAwODMxKQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK1NvbWUgYXBwbGljYXRpb25zIHdhbnQgbW9yZSBjb250cm9sIG92ZXIgdGhlIGRhdGEgdGhhdCdzIHVzZWQKK3RvIGNyZWF0ZSB0aGUgTWVzc2FnZS1JRCBmb3IgYSBtZXNzYWdlLiAgVGhpcyBtZXRob2QgYWxsb3dzCithbiBhcHBsaWNhdGlvbiB0byBwcm92aWRlIGEgc2ltcGxlIHN1YmNsYXNzIG9mIE1pbWVNZXNzYWdlCit0aGF0IG92ZXJyaWRlcyB0aGUgTWVzc2FnZS1JRCBhbGdvcml0aG0uCisKKyAgICAvKioKKyAgICAgKiBVcGRhdGUgdGhlIE1lc3NhZ2UtSUQgaGVhZGVyLiAgVGhpcyBtZXRob2QgaXMgY2FsbGVkCisgICAgICogYnkgdGhlIDxjb2RlPnVwZGF0ZUhlYWRlcnM8L2NvZGU+IGFuZCBhbGxvd3MgYSBzdWJjbGFzcworICAgICAqIHRvIG92ZXJyaWRlIG9ubHkgdGhlIGFsZ29yaXRobSBmb3IgY2hvb3NpbmcgYSBNZXNzYWdlLUlELgorICAgICAqCisgICAgICogQHNpbmNlCQlKYXZhTWFpbCAxLjQKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCB1cGRhdGVNZXNzYWdlSUQoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uCisKKworPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCis5LiBBZGQgTWltZU1lc3NhZ2UuY3JlYXRlTWltZU1lc3NhZ2UoKSBwcm90ZWN0ZWQgbWV0aG9kICg2MzAwODMzKQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworVGhlIE1pbWVNZXNzYWdlLnJlcGx5IG1ldGhvZCBjcmVhdGVzIGFuZCByZXR1cm5zIGEgbmV3IE1pbWVNZXNzYWdlLgorU3ViY2xhc3NlcyBvZiBNaW1lTWVzc2FnZSBtYXkgbmVlZCB0aGUgcmVwbHkgbWV0aG9kIHRvIGNyZWF0ZSBhIG5ldworbWVzc2FnZSBvZiB0aGUgYXBwcm9wcmlhdGUgc3ViY2xhc3MuICBUaGlzIG1ldGhvZCBhbGxvd3Mgc3ViY2xhc3NlcwordG8gY29udHJvbCB0aGUgY2xhc3MgY3JlYXRlZCBpbiB0aGlzIGNhc2UuCisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYW5kIHJldHVybiBhIE1pbWVNZXNzYWdlIG9iamVjdC4gIFRoZSByZXBseSBtZXRob2QKKyAgICAgKiB1c2VzIHRoaXMgbWV0aG9kIHRvIGNyZWF0ZSB0aGUgTWltZU1lc3NhZ2Ugb2JqZWN0IHRoYXQgaXQKKyAgICAgKiB3aWxsIHJldHVybi4gIFN1YmNsYXNzZXMgY2FuIG92ZXJyaWRlIHRoaXMgbWV0aG9kIHRvIHJldHVybgorICAgICAqIGEgc3ViY2xhc3Mgb2YgTWltZU1lc3NhZ2UuICBUaGlzIGltcGxlbWVudGF0aW9uIHNpbXBseSBjb25zdHJ1Y3RzCisgICAgICogYW5kIHJldHVybnMgYSBNaW1lTWVzc2FnZSBvYmplY3QgdXNpbmcgdGhlIHN1cHBsaWVkIFNlc3Npb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0Jc2Vzc2lvbgl0aGUgU2Vzc2lvbiB0byB1c2UgZm9yIHRoZSBuZXcgbWVzc2FnZQorICAgICAqIEByZXR1cm4JCXRoZSBuZXcgTWltZU1lc3NhZ2Ugb2JqZWN0CisgICAgICogQHNpbmNlCQlKYXZhTWFpbCAxLjQKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgTWltZU1lc3NhZ2UgY3JlYXRlTWltZU1lc3NhZ2UoU2Vzc2lvbiBzZXNzaW9uKQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24KKworCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKzEwLiBNYWtlIHRoZSAicGFydCIgZmllbGQgb2YgTWltZVBhcnREYXRhU291cmNlIHByb3RlY3RlZCAoNjMwMDgzNCkKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworU3ViY2xhc3NlcyBvZiBNaW1lUGFydERhdGFTb3VyY2UgbWF5IG5lZWQgYWNjZXNzIHRvIHRoZSAicGFydCIKK2ZpZWxkIGluIG9yZGVyIHRvIGltcGxlbWVudCB0aGUgZ2V0SW5wdXRTdHJlYW0gbWV0aG9kLiAgVGhlCitwYXJ0IGZpZWxkIGlzIGN1cnJlbnRseSBwcml2YXRlLCB0aGlzIGNoYW5nZSB3aWxsIG1ha2UgaXQgcHJvdGVjdGVkLgorCisJLyoqCisJICogVGhlIE1pbWVQYXJ0IHRoYXQgcHJvdmlkZXMgdGhlIGRhdGEgZm9yIHRoaXMgRGF0YVNvdXJjZS4KKwkgKgorCSAqIEBzaW5jZQlKYXZhTWFpbCAxLjQKKwkgKi8KKwlwcm90ZWN0ZWQgTWltZVBhcnQgcGFydDsKKworCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKzExLiBGb2xkZXIuZ2V0U2VwYXJhdG9yIHNob3VsZCBub3QgcmVxdWlyZSB0aGUgZm9sZGVyIHRvIGV4aXN0ICg2MzAxMzgxKQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0lNQVAgZm9sZGVycyBhcmUgYWJsZSB0byBkZXRlcm1pbmUgdGhlIHNlcGFyYXRvciBjaGFyYWN0ZXIgd2l0aG91dAora25vd2luZyB3aGV0aGVyIHRoZSBmb2xkZXIgZXhpc3RzLiAgQ2hlY2tpbmcgd2hldGhlciB0aGUgZm9sZGVyCitleGlzdHMgaW4gb3JkZXIgdG8gdGhyb3cgRm9sZGVyTm90Rm91bmRFeGNlcHRpb24gaW50cm9kdWNlcyBhZGRpdGlvbmFsCitvdmVyaGVhZC4gIEJlY2F1c2Ugb3RoZXIgbWV0aG9kcyBvZnRlbiBuZWVkIHRvIGtub3cgdGhlIHNlcGFyYXRvcgorY2hhcmFjdGVyLCB0aGlzIG92ZXJoZWFkIGNhbiBiZSBub3RpY2FibGUuICBUaGUgc3BlY2lmaWNhdGlvbiBvZiB0aGlzCittZXRob2QgaXMgY2hhbmdlZCBhcyBmb2xsb3dzOgorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBkZWxpbWl0ZXIgY2hhcmFjdGVyIHRoYXQgc2VwYXJhdGVzIHRoaXMgRm9sZGVyJ3MgcGF0aG5hbWUKKyAgICAgKiBmcm9tIHRoZSBuYW1lcyBvZiBpbW1lZGlhdGUgc3ViZm9sZGVycy4gVGhpcyBtZXRob2QgY2FuIGJlIGludm9rZWQgCisgICAgICogb24gYSBjbG9zZWQgRm9sZGVyLgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbiAJRm9sZGVyTm90Rm91bmRFeGNlcHRpb24gaWYgdGhlIGltcGxlbWVudGF0aW9uCisgICAgICoJCQlyZXF1aXJlcyB0aGUgZm9sZGVyIHRvIGV4aXN0LCBidXQgaXQgZG9lcyBub3QKKyAgICAgKiBAcmV0dXJuICAgICAgICAgIEhpZXJhcmNoeSBzZXBhcmF0b3IgY2hhcmFjdGVyCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGNoYXIgZ2V0U2VwYXJhdG9yKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKzEyLiBBZGQgUHJlZW5jb2RlZE1pbWVCb2R5UGFydCBjbGFzcyAoNjMwMTM4NikKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworSW4gc29tZSBjYXNlcyBhbiBhcHBsaWNhdGlvbiB3aWxsIGhhdmUgZGF0YSB0aGF0IGhhcyBhbHJlYWR5CitiZWVuIGVuY29kZWQgdXNpbmcgKGZvciBleGFtcGxlKSBiYXNlNjQgZW5jb2RpbmcuICBUaGVyZSBzaG91bGQKK2JlIGFuIGVhc3kgd2F5IHRvIGF0dGFjaCBzdWNoIGRhdGEgdG8gYSBtZXNzYWdlIHdpdGhvdXQgdGhlIG5lZWQKK3RvIGRlY29kZSBpdCBhbmQgcmVlbmNvZGUgaXQuICBUaGlzIGNsYXNzIHByb3ZpZGVzIHN1Y2ggc3VwcG9ydC4KKworLyoqCisgKiBBIE1pbWVCb2R5UGFydCB0aGF0IGhhbmRsZXMgZGF0YSB0aGF0IGhhcyBhbHJlYWR5IGJlZW4gZW5jb2RlZC4KKyAqIFRoaXMgY2xhc3MgaXMgdXNlZnVsIHdoZW4gY29uc3RydWN0aW5nIGEgbWVzc2FnZSBhbmQgYXR0YWNoaW5nCisgKiBkYXRhIHRoYXQgaGFzIGFscmVhZHkgYmVlbiBlbmNvZGVkIChmb3IgZXhhbXBsZSwgdXNpbmcgYmFzZTY0CisgKiBlbmNvZGluZykuICBUaGUgZGF0YSBtYXkgaGF2ZSBiZWVuIGVuY29kZWQgYnkgdGhlIGFwcGxpY2F0aW9uLAorICogb3IgbWF5IGhhdmUgYmVlbiBzdG9yZWQgaW4gYSBmaWxlIG9yIGRhdGFiYXNlIGluIGVuY29kZWQgZm9ybS4KKyAqIFRoZSBlbmNvZGluZyBpcyBzdXBwbGllZCB3aGVuIHRoaXMgb2JqZWN0IGlzIGNyZWF0ZWQuICBUaGUgZGF0YQorICogaXMgYXR0YWNoZWQgdG8gdGhpcyBvYmplY3QgaW4gdGhlIHVzdWFsIGZhc2hpb24sIGJ5IHVzaW5nIHRoZQorICogPGNvZGU+c2V0VGV4dDwvY29kZT4sIDxjb2RlPnNldENvbnRlbnQ8L2NvZGU+LCBvcgorICogPGNvZGU+c2V0RGF0YUhhbmRsZXI8L2NvZGU+IG1ldGhvZHMuCisgKgorICogQHNpbmNlCUphdmFNYWlsIDEuNAorICovCisKK3B1YmxpYyBjbGFzcyBQcmVlbmNvZGVkTWltZUJvZHlQYXJ0IGV4dGVuZHMgTWltZUJvZHlQYXJ0IHsKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBQcmVlbmNvZGVkTWltZUJvZHlQYXJ0IHRoYXQgYXNzdW1lcyB0aGUgZGF0YSBpcworICAgICAqIGVuY29kZWQgdXNpbmcgdGhlIHNwZWNpZmllZCBlbmNvZGluZy4gIFRoZSBlbmNvZGluZyBtdXN0CisgICAgICogYmUgYSBNSU1FIHN1cHBvcnRlZCBDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nLgorICAgICAqLworICAgIHB1YmxpYyBQcmVlbmNvZGVkTWltZUJvZHlQYXJ0KFN0cmluZyBlbmNvZGluZykKK30KKworCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKzEzLiBBZGQgTWltZUJvZHlQYXJ0IGF0dGFjaEZpbGUgYW5kIHNhdmVGaWxlIG1ldGhvZHMgKDYzMDEzOTApCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitJdCdzIHZlcnkgY29tbW9uIGZvciBhcHBsaWNhdGlvbnMgdG8gY3JlYXRlIG1lc3NhZ2VzIHdpdGggZmlsZXMKK2FzIGF0dGFjaG1lbnRzLCBhbmQgdG8gcmVjZWl2ZSBhdHRhY2htZW50cyBhbmQgc2F2ZSB0aGVtIGluIGZpbGVzLgorVG8gc2ltcGxpZnkgdGhpcyB1c2FibGUsIHdlIGFkZCBzZXZlcmFsIGNvbnZlbmllbmNlIG1ldGhvZHMgdG8gdGhlCitNaW1lQm9keVBhcnQgY2xhc3M6CisKKyAgICAvKioKKyAgICAgKiBVc2UgdGhlIHNwZWNpZmllZCBmaWxlIHRvIHByb3ZpZGUgdGhlIGRhdGEgZm9yIHRoaXMgcGFydC4KKyAgICAgKiBUaGUgc2ltcGxlIGZpbGUgbmFtZSBpcyB1c2VkIGFzIHRoZSBmaWxlIG5hbWUgZm9yIHRoaXMKKyAgICAgKiBwYXJ0IGFuZCB0aGUgZGF0YSBpbiB0aGUgZmlsZSBpcyB1c2VkIGFzIHRoZSBkYXRhIGZvciB0aGlzCisgICAgICogcGFydC4gIFRoZSBlbmNvZGluZyB3aWxsIGJlIGNob3NlbiBhcHByb3ByaWF0ZWx5IGZvciB0aGUKKyAgICAgKiBmaWxlIGRhdGEuCisgICAgICoKKyAgICAgKiBAcGFyYW0JCWZpbGUJCXRoZSBGaWxlIG9iamVjdCB0byBhdHRhY2gKKyAgICAgKiBAZXhjZXB0aW9uCUlPRXhjZXB0aW9uCWVycm9ycyByZWxhdGVkIHRvIGFjY2Vzc2luZyB0aGUgZmlsZQorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uCW1lc3NhZ2UgcmVsYXRlZCBlcnJvcnMKKyAgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuNAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGF0dGFjaEZpbGUoRmlsZSBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24sIE1lc3NhZ2luZ0V4Y2VwdGlvbgorCisgICAgLyoqCisgICAgICogVXNlIHRoZSBzcGVjaWZpZWQgZmlsZSB0byBwcm92aWRlIHRoZSBkYXRhIGZvciB0aGlzIHBhcnQuCisgICAgICogVGhlIHNpbXBsZSBmaWxlIG5hbWUgaXMgdXNlZCBhcyB0aGUgZmlsZSBuYW1lIGZvciB0aGlzCisgICAgICogcGFydCBhbmQgdGhlIGRhdGEgaW4gdGhlIGZpbGUgaXMgdXNlZCBhcyB0aGUgZGF0YSBmb3IgdGhpcworICAgICAqIHBhcnQuICBUaGUgZW5jb2Rpbmcgd2lsbCBiZSBjaG9zZW4gYXBwcm9wcmlhdGVseSBmb3IgdGhlCisgICAgICogZmlsZSBkYXRhLgorICAgICAqCisgICAgICogQHBhcmFtCQlmaWxlCQl0aGUgbmFtZSBvZiB0aGUgZmlsZSB0byBhdHRhY2gKKyAgICAgKiBAZXhjZXB0aW9uCUlPRXhjZXB0aW9uCWVycm9ycyByZWxhdGVkIHRvIGFjY2Vzc2luZyB0aGUgZmlsZQorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uCW1lc3NhZ2UgcmVsYXRlZCBlcnJvcnMKKyAgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuNAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGF0dGFjaEZpbGUoU3RyaW5nIGZpbGUpIHRocm93cyBJT0V4Y2VwdGlvbiwgTWVzc2FnaW5nRXhjZXB0aW9uCisKKyAgICAvKioKKyAgICAgKiBTYXZlIHRoZSBjb250ZW50cyBvZiB0aGlzIHBhcnQgaW4gdGhlIHNwZWNpZmllZCBmaWxlLiAgVGhlIGNvbnRlbnQKKyAgICAgKiBpcyBkZWNvZGVkIGFuZCBzYXZlZCwgd2l0aG91dCBhbnkgb2YgdGhlIE1JTUUgaGVhZGVycy4KKyAgICAgKgorICAgICAqIEBwYXJhbQkJZmlsZQkJdGhlIEZpbGUgb2JqZWN0IHRvIHdyaXRlIHRvCisgICAgICogQGV4Y2VwdGlvbglJT0V4Y2VwdGlvbgllcnJvcnMgcmVsYXRlZCB0byBhY2Nlc3NpbmcgdGhlIGZpbGUKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbgltZXNzYWdlIHJlbGF0ZWQgZXJyb3JzCisgICAgICogQHNpbmNlCQlKYXZhTWFpbCAxLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzYXZlRmlsZShGaWxlIGZpbGUpIHRocm93cyBJT0V4Y2VwdGlvbiwgTWVzc2FnaW5nRXhjZXB0aW9uCisKKyAgICAvKioKKyAgICAgKiBTYXZlIHRoZSBjb250ZW50cyBvZiB0aGlzIHBhcnQgaW4gdGhlIHNwZWNpZmllZCBmaWxlLiAgVGhlIGNvbnRlbnQKKyAgICAgKiBpcyBkZWNvZGVkIGFuZCBzYXZlZCwgd2l0aG91dCBhbnkgb2YgdGhlIE1JTUUgaGVhZGVycy4KKyAgICAgKgorICAgICAqIEBwYXJhbQkJZmlsZQkJdGhlIG5hbWUgb2YgdGhlIGZpbGUgdG8gd3JpdGUgdG8KKyAgICAgKiBAZXhjZXB0aW9uCUlPRXhjZXB0aW9uCWVycm9ycyByZWxhdGVkIHRvIGFjY2Vzc2luZyB0aGUgZmlsZQorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uCW1lc3NhZ2UgcmVsYXRlZCBlcnJvcnMKKyAgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuNAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNhdmVGaWxlKFN0cmluZyBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24sIE1lc3NhZ2luZ0V4Y2VwdGlvbgorCisKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworMTQuIEFkZCBNaW1lVXRpbGl0eSBmb2xkIGFuZCB1bmZvbGQgbWV0aG9kcyAoNjMwMjExOCkKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK1doZW4gZGVhbGluZyB3aXRoIGxvbmcgaGVhZGVyIGxpbmVzLCBpdCdzIG9mdGVuIG5lY2Vzc2FyeSB0byBmb2xkCit0aGUgbGluZXMgdG8gYXZvaWQgZXhjZWVkaW5nIGxpbmUgbGVuZ3RoIGxpbWl0YXRpb25zLiAgV2hlbiByZXRyaWV2aW5nCit0aGUgZGF0YSBmcm9tIHN1Y2ggaGVhZGVycywgdGhlIGZvbGRpbmcgbmVlZHMgdG8gYmUgdW5kb25lLiAgVGhlIEphdmFNYWlsCitpbXBsZW1lbnRhdGlvbiBpbmNsdWRlcyBwcml2YXRlIGZvbGQgYW5kIHVuZm9sZCBtZXRob2RzIGZvciB0aGlzIHB1cnBvc2UuCitUaGVzZSBtZXRob2RzIHNob3VsZCBiZSBtYWRlIHB1YmxpYy4KKworICAgIC8qKgorICAgICAqIEZvbGQgYSBzdHJpbmcgYXQgbGluZWFyIHdoaXRlc3BhY2Ugc28gdGhhdCBlYWNoIGxpbmUgaXMgbm8gbG9uZ2VyCisgICAgICogdGhhbiA3NiBjaGFyYWN0ZXJzLCBpZiBwb3NzaWJsZS4gIElmIHRoZXJlIGFyZSBtb3JlIHRoYW4gNzYKKyAgICAgKiBub24td2hpdGVzcGFjZSBjaGFyYWN0ZXJzIGNvbnNlY3V0aXZlbHksIHRoZSBzdHJpbmcgaXMgZm9sZGVkIGF0CisgICAgICogdGhlIGZpcnN0IHdoaXRlc3BhY2UgYWZ0ZXIgdGhhdCBzZXF1ZW5jZS4gIFRoZSBwYXJhbWV0ZXIKKyAgICAgKiA8Y29kZT51c2VkPC9jb2RlPiBpbmRpY2F0ZXMgaG93IG1hbnkgY2hhcmFjdGVycyBoYXZlIGJlZW4gdXNlZCBpbgorICAgICAqIHRoZSBjdXJyZW50IGxpbmU7IGl0IGlzIHVzdWFsbHkgdGhlIGxlbmd0aCBvZiB0aGUgaGVhZGVyIG5hbWUuIDxwPgorICAgICAqCisgICAgICogTm90ZSB0aGF0IGxpbmUgYnJlYWtzIGluIHRoZSBzdHJpbmcgYXJlbid0IGVzY2FwZWQ7IHRoZXkgcHJvYmFibHkKKyAgICAgKiBzaG91bGQgYmUuCisgICAgICoKKyAgICAgKiBAcGFyYW0JdXNlZAljaGFyYWN0ZXJzIHVzZWQgaW4gbGluZSBzbyBmYXIKKyAgICAgKiBAcGFyYW0Jcwl0aGUgc3RyaW5nIHRvIGZvbGQKKyAgICAgKiBAcmV0dXJuCQl0aGUgZm9sZGVkIHN0cmluZworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGZvbGQoaW50IHVzZWQsIFN0cmluZyBzKQorCisgICAgLyoqCisgICAgICogVW5mb2xkIGEgZm9sZGVkIGhlYWRlci4gIEFueSBsaW5lIGJyZWFrcyB0aGF0IGFyZW4ndCBlc2NhcGVkIGFuZAorICAgICAqIGFyZSBmb2xsb3dlZCBieSB3aGl0ZXNwYWNlIGFyZSByZW1vdmVkLgorICAgICAqCisgICAgICogQHBhcmFtCXMJdGhlIHN0cmluZyB0byB1bmZvbGQKKyAgICAgKiBAcmV0dXJuCQl0aGUgdW5mb2xkZWQgc3RyaW5nCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdW5mb2xkKFN0cmluZyBzKQorCisKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworMTUuIEFsbG93IG1vcmUgY29udHJvbCBvdmVyIGhlYWRlcnMgaW4gSW50ZXJuZXRIZWFkZXJzIG9iamVjdCAoNjMwMjgzMikKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK1NvbWUgYXBwbGljYXRpb25zLCBzdWNoIGFzIG1haWwgc2VydmVyIGFwcGxpY2F0aW9ucywgbmVlZCBtb3JlIGNvbnRyb2wKK292ZXIgdGhlIG9yZGVyIG9mIGhlYWRlcnMgaW4gdGhlIEludGVybmV0SGVhZGVycyBjbGFzcy4gIFRvIHN1cHBvcnQKK3N1Y2ggdXNhZ2UsIHdlIGFsbG93IHN1Y2ggYXBwbGljYXRpb25zIHRvIHN1YmNsYXNzIEludGVybmV0SGVhZGVycworYW5kIGFjY2VzcyB0aGUgTGlzdCBvZiBoZWFkZXJzIGRpcmVjdGx5LiAgSW50ZXJuZXRIZWFkZXJzIGV4cG9zZXMgYQorcHJvdGVjdGVkIGZpZWxkOgorCisgICAgcHJvdGVjdGVkIExpc3QgaGVhZGVyczsKKworVGhlIGVsZW1lbnRzIG9mIHRoZSBsaXN0IGFyZSBvYmplY3RzIG9mIGEgbmV3IHByb3RlY3RlZCBmaW5hbCBjbGFzcworSW50ZXJuZXRIZWFkZXJzLkludGVybmV0SGVhZGVyIHRoYXQgZXh0ZW5kcyB0aGUgamF2YXgubWFpbC5IZWFkZXIgY2xhc3MuCitUbyBhbGxvdyB0aGUgSW50ZXJuZXRIZWFkZXIgY2xhc3MgdG8gbWFrZSB1c2Ugb2YgdGhlIEhlYWRlciBjbGFzcywgd2UKK21ha2UgdGhlIGZvbGxvd2luZyBmaWVsZHMgb2YgSGVhZGVyIHByb3RlY3RlZDoKKworICAgIC8qKgorICAgICAqIFRoZSBuYW1lIG9mIHRoZSBoZWFkZXIuCisgICAgICoKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS40CisgICAgICovCisgICAgcHJvdGVjdGVkIFN0cmluZyBuYW1lOworCisgICAgLyoqCisgICAgICogVGhlIHZhbHVlIG9mIHRoZSBoZWFkZXIuCisgICAgICoKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS40CisgICAgICovCisgICAgcHJvdGVjdGVkIFN0cmluZyB2YWx1ZTsKKworCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKzE2LiBBbGxvdyBhcHBsaWNhdGlvbnMgdG8gZHluYW1pY2FsbHkgcmVnaXN0ZXIgbmV3IHByb3RvY29sIHByb3ZpZGVycyAoNjMwMjgzNSkKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK1NvbWUgYXBwbGljYXRpb25zIHdvdWxkIGxpa2UgdG8gcmVnaXN0ZXIgbmV3IHByb3RvY29sIHByb3ZpZGVycyBhdCBydW50aW1lCityYXRoZXIgdGhhbiBkZXBlbmRpbmcgb24gdGhlIEphdmFNYWlsIGNvbmZpZ3VyYXRpb24gZmlsZXMgYW5kIHJlc291cmNlcy4KK1RvIHN1cHBvcnQgc3VjaCB1c2FnZSB3ZSBtYWtlIHRoZSBjb25zdHJ1Y3RvciBmb3IgdGhlIFByb3ZpZGVyIGNsYXNzCitwdWJsaWM6CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBuZXcgcHJvdmlkZXIgb2YgdGhlIHNwZWNpZmllZCB0eXBlIGZvciB0aGUgc3BlY2lmaWVkCisgICAgICogcHJvdG9jb2wuICBUaGUgc3BlY2lmaWVkIGNsYXNzIGltcGxlbWVudHMgdGhlIHByb3ZpZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIHR5cGUgICAgICBUeXBlLlNUT1JFIG9yIFR5cGUuVFJBTlNQT1JUCisgICAgICogQHBhcmFtIHByb3RvY29sICB2YWxpZCBwcm90b2NvbCBmb3IgdGhlIHR5cGUKKyAgICAgKiBAcGFyYW0gY2xhc3NuYW1lIGNsYXNzIG5hbWUgdGhhdCBpbXBsZW1lbnRzIHRoaXMgcHJvdG9jb2wKKyAgICAgKiBAcGFyYW0gdmVuZG9yICAgIG9wdGlvbmFsIHN0cmluZyBpZGVudGlmeWluZyB0aGUgdmVuZG9yIChtYXkgYmUgbnVsbCkKKyAgICAgKiBAcGFyYW0gdmVyc2lvbiAgIG9wdGlvbmFsIGltcGxlbWVudGF0aW9uIHZlcnNpb24gc3RyaW5nIChtYXkgYmUgbnVsbCkKKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS40CisgICAgICovCisgICAgcHVibGljIFByb3ZpZGVyKFR5cGUgdHlwZSwgU3RyaW5nIHByb3RvY29sLCBTdHJpbmcgY2xhc3NuYW1lLCAKKwkgICAgIFN0cmluZyB2ZW5kb3IsIFN0cmluZyB2ZXJzaW9uKQorCitXZSBhbHNvIGFkZCBhIG5ldyBtZXRob2QgdG8gU2Vzc2lvbiB0byBhbGxvdyByZWdpc3RlcmluZyBzdWNoIFByb3ZpZGVyczoKKworICAgIC8qKgorICAgICAqIEFkZCBhIHByb3ZpZGVyIHRvIHRoZSBzZXNzaW9uLgorICAgICAqCisgICAgICogQHBhcmFtCXByb3ZpZGVyCXRoZSBwcm92aWRlciB0byBhZGQKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS40CisgICAgICovCisgICAgcHVibGljIHZvaWQgYWRkUHJvdmlkZXIoUHJvdmlkZXIgcHJvdmlkZXIpCisKKworPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisxNy4gQWxsb3cgYXBwbGljYXRpb25zIHRvIGR5bmFtaWNhbGx5IHJlZ2lzdGVyIGFkZHJlc3MgdHlwZSBtYXBwaW5ncyAoNDM3NzcyNykKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitBbG9uZyB3aXRoIHRoZSBhYm92ZSBpdGVtLCBzb21lIGFwcGxpY2F0aW9ucyB3aWxsIHdhbnQgdG8gZHluYW1pY2FsbHkKK2NvbnRyb2wgdGhlIG1hcHBpbmcgZnJvbSBhZGRyZXNzIHR5cGUgdG8gcHJvdG9jb2wuICBUaGlzIGNvdWxkIGFsc28KK2JlIHVzZWQgdG8gY2hhbmdlIHRoZSBkZWZhdWx0IGludGVybmV0IHByb3RvY29sIGZyb20gInNtdHAiIHRvICJzbXRwcyIuCitXZSBhZGQgdGhlIGZvbGxvd2luZyBtZXRob2QgdG8gU2Vzc2lvbjoKKworICAgIC8qKgorICAgICAqIFNldCB0aGUgZGVmYXVsdCB0cmFuc3BvcnQgcHJvdG9jb2wgdG8gdXNlIGZvciBhZGRyZXNzZXMgb2YKKyAgICAgKiB0aGUgc3BlY2lmaWVkIHR5cGUuICBOb3JtYWxseSB0aGUgZGVmYXVsdCBpcyBzZXQgYnkgdGhlCisgICAgICogPGNvZGU+amF2YW1haWwuZGVmYXVsdC5hZGRyZXNzLm1hcDwvY29kZT4gb3IKKyAgICAgKiA8Y29kZT5qYXZhbWFpbC5hZGRyZXNzLm1hcDwvY29kZT4gZmlsZXMgb3IgcmVzb3VyY2VzLgorICAgICAqCisgICAgICogQHBhcmFtCWFkZHJlc3N0eXBlCXR5cGUgb2YgYWRkcmVzcworICAgICAqIEBwYXJhbQlwcm90b2NvbAluYW1lIG9mIHByb3RvY29sCisgICAgICogQHNlZSAjZ2V0VHJhbnNwb3J0KEFkZHJlc3MpCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFByb3RvY29sRm9yQWRkcmVzcyhTdHJpbmcgYWRkcmVzc3R5cGUsIFN0cmluZyBwcm90b2NvbCkKKworCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKzE4LiBQYXJhbWV0ZXJMaXN0IGNsYXNzIHNob3VsZCBzdXBwb3J0IG5vbiBVUy1BU0NJSSBwYXJhbWV0ZXJzICg0MTA3MzQyKQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK1JGQyAyMjMxIGRlc2NyaWJlcyBhIG1ldGhvZCBmb3IgZW5jb2Rpbmcgbm9uLUFTQ0lJIHBhcmFtZXRlcnMgaW4gTUlNRQoraGVhZGVycy4gIFdlIGludHJvZHVjZSB0aGUgZm9sbG93aW5nIFN5c3RlbSBwcm9wZXJ0aWVzIHRvIGNvbnRyb2wKK2VuY29kaW5nIGFuZCBkZWNvZGluZyBzdWNoIHBhcmFtZXRlcnMuCisKK0lmIHRoZSBtYWlsLm1pbWUuZW5jb2RlcGFyYW1ldGVycyBTeXN0ZW0gcHJvcGVydHkgaXMgc2V0IHRvICJ0cnVlIi4KK25vbi1BU0NJSSBwYXJhbWV0ZXJzIHdpbGwgYmUgZW5jb2RlZCBwZXIgUkZDIDIyMzEuCisKK0lmIHRoZSBtYWlsLm1pbWUuZGVjb2RlcGFyYW1ldGVycyBTeXN0ZW0gcHJvcGVydHkgaXMgc2V0IHRvICJ0cnVlIi4KK3BhcmFtZXRlcnMgZW5jb2RlZCBwZXIgUkZDIDIyMzEgd2lsbCBiZSBkZWNvZGVkLgorCitCb3RoIG9mIHRoZXNlIHByb3BlcnRpZXMgZGVmYXVsdCB0byAiZmFsc2UiLgorCitOb3RlIHRoYXQgUkZDIDIyMzEgYWxzbyBkZXNjcmliZXMgYSB0ZWNobmlxdWUgZm9yIHNwbGl0dGluZyBsb25nCitwYXJhbWV0ZXIgdmFsdWVzIGFjcm9zcyBtdWx0aXBsZSBwYXJhbWV0ZXJzLiAgV2UgZG8gbm90IHBsYW4gdG8KK3N1cHBvcnQgc3VjaCBwYXJhbWV0ZXIgY29udGludWF0aW9ucy4KKworVG8gYWxsb3cgc3BlY2lmeWluZyB0aGUgY2hhcnNldCB0byB1c2UgZm9yIGEgcGFyYW1ldGVyLCB3ZSBhZGQKK3RoZSBmb2xsb3dpbmcgbWV0aG9kIHRvIFBhcmFtZXRlckxpc3Q6CisKKyAgICAvKioKKyAgICAgKiBTZXQgYSBwYXJhbWV0ZXIuIElmIHRoaXMgcGFyYW1ldGVyIGFscmVhZHkgZXhpc3RzLCBpdCBpcworICAgICAqIHJlcGxhY2VkIGJ5IHRoaXMgbmV3IHZhbHVlLiAgSWYgdGhlCisgICAgICogPGNvZGU+bWFpbC5taW1lLmVuY29kZXBhcmFtZXRlcnM8L2NvZGU+IFN5c3RlbSBwcm9wZXJ0eQorICAgICAqIGlzIHRydWUsIGFuZCB0aGUgcGFyYW1ldGVyIHZhbHVlIGlzIG5vbi1BU0NJSSwgaXQgd2lsbCBiZQorICAgICAqIGVuY29kZWQgd2l0aCB0aGUgc3BlY2lmaWVkIGNoYXJzZXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0JbmFtZSAJbmFtZSBvZiB0aGUgcGFyYW1ldGVyLgorICAgICAqIEBwYXJhbQl2YWx1ZQl2YWx1ZSBvZiB0aGUgcGFyYW1ldGVyLgorICAgICAqIEBwYXJhbQljaGFyc2V0CWNoYXJzZXQgb2YgdGhlIHBhcmFtZXRlciB2YWx1ZS4KKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS40CisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0KFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsdWUsIFN0cmluZyBjaGFyc2V0KQorCisKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworMTkuIFN0YW5kYXJkIGludGVyZmFjZSBmb3IgU3RvcmVzIHRoYXQgc3VwcG9ydCBxdW90YXMgKDYzMDQwNTEpCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworU29tZSBJTUFQIHN0b3JlcyBzdXBwb3J0IHF1b3Rhcy4gIFRvIGFsbG93IGFwcGxpY2F0aW9ucyB0byBtYWtlCit1c2Ugb2YgcXVvdGEgc3VwcG9ydCB3aXRob3V0IGRlcGVuZGluZyBvbiBJTUFQLXNwZWNpZmljIEFQSXMsCit3ZSBwcm92aWRlIGEgUXVvdGFBd2FyZVN0b3JlIGludGVyZmFjZSB0aGF0IFN0b3Jlcywgc3VjaCBhcyB0aGUKK0lNQVAgU3RvcmUsIGNhbiBpbXBsZW1lbnQuICBXZSBhbHNvIHByb3ZpZGUgYSBRdW90YSBjbGFzcyB0bworcmVwcmVzZW50IGEgc2V0IG9mIHF1b3RhcyBmb3IgYSBxdW90YSByb290LgorCitwYWNrYWdlIGphdmF4Lm1haWw7CisKKy8qKgorICogQW4gaW50ZXJyZmFjZSBpbXBsZW1lbnRlZCBieSBTdG9yZXMgdGhhdCBzdXBwb3J0IHF1b3Rhcy4KKyAqIFRoZSB7QGxpbmsgI2dldFF1b3RhIGdldFF1b3RhfSBhbmQge0BsaW5rICNzZXRRdW90YSBzZXRRdW90YX0gbWV0aG9kcworICogc3VwcG9ydCB0aGUgcXVvdGEgbW9kZWwgZGVmaW5lZCBieSB0aGUgSU1BUCBRVU9UQSBleHRlbnNpb24uCisgKiBSZWZlciB0byA8QSBIUkVGPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMDg3LnR4dCI+UkZDIDIwODc8L0E+CisgKiBmb3IgbW9yZSBpbmZvcm1hdGlvbi4gPHA+CisgKgorICogQHNpbmNlIEphdmFNYWlsIDEuNAorICovCitwdWJsaWMgaW50ZXJmYWNlIFF1b3RhQXdhcmVTdG9yZSB7CisgICAgLyoqCisgICAgICogR2V0IHRoZSBxdW90YXMgZm9yIHRoZSBuYW1lZCBxdW90YSByb290LgorICAgICAqIFF1b3RhcyBhcmUgY29udHJvbGxlZCBvbiB0aGUgYmFzaXMgb2YgYSBxdW90YSByb290LCBub3QKKyAgICAgKiAobmVjZXNzYXJpbHkpIGEgZm9sZGVyLiAgVGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGZvbGRlcnMKKyAgICAgKiBhbmQgcXVvdGEgcm9vdHMgZGVwZW5kcyBvbiB0aGUgc2VydmVyLiAgU29tZSBzZXJ2ZXJzCisgICAgICogbWlnaHQgaW1wbGVtZW50IGEgc2luZ2xlIHF1b3RhIHJvb3QgZm9yIGFsbCBmb2xkZXJzIG93bmVkIGJ5CisgICAgICogYSB1c2VyLiAgT3RoZXIgc2VydmVycyBtaWdodCBpbXBsZW1lbnQgYSBzZXBhcmF0ZSBxdW90YSByb290CisgICAgICogZm9yIGVhY2ggZm9sZGVyLiAgQSBzaW5nbGUgZm9sZGVyIGNhbiBldmVuIGhhdmUgbXVsdGlwbGUKKyAgICAgKiBxdW90YSByb290cywgcGVyaGFwcyBjb250cm9sbGluZyBxdW90YXMgZm9yIGRpZmZlcmVudAorICAgICAqIHJlc291cmNlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbQlyb290CXRoZSBuYW1lIG9mIHRoZSBxdW90YSByb290CisgICAgICogQHJldHVybgkJYXJyYXkgb2YgUXVvdGEgb2JqZWN0cworICAgICAqIEBleGNlcHRpb24gTWVzc2FnaW5nRXhjZXB0aW9uCWlmIHRoZSBzZXJ2ZXIgZG9lc24ndCBzdXBwb3J0IHRoZQorICAgICAqCQkJCQlRVU9UQSBleHRlbnNpb24KKyAgICAgKi8KKyAgICBRdW90YVtdIGdldFF1b3RhKFN0cmluZyByb290KSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0IHRoZSBxdW90YXMgZm9yIHRoZSBxdW90YSByb290IHNwZWNpZmllZCBpbiB0aGUgcXVvdGEgYXJndW1lbnQuCisgICAgICogVHlwaWNhbGx5IHRoaXMgd2lsbCBiZSBvbmUgb2YgdGhlIHF1b3RhIHJvb3RzIG9idGFpbmVkIGZyb20gdGhlCisgICAgICogPGNvZGU+Z2V0UXVvdGE8L2NvZGU+IG1ldGhvZCwgYnV0IGl0IG5lZWQgbm90IGJlLgorICAgICAqCisgICAgICogQHBhcmFtCXF1b3RhCXRoZSBxdW90YSB0byBzZXQKKyAgICAgKiBAZXhjZXB0aW9uIE1lc3NhZ2luZ0V4Y2VwdGlvbglpZiB0aGUgc2VydmVyIGRvZXNuJ3Qgc3VwcG9ydCB0aGUKKyAgICAgKgkJCQkJUVVPVEEgZXh0ZW5zaW9uCisgICAgICovCisgICAgdm9pZCBzZXRRdW90YShRdW90YSBxdW90YSkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbjsKK30KKworcGFja2FnZSBqYXZheC5tYWlsOworCisvKioKKyAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhIHNldCBvZiBxdW90YXMgZm9yIGEgZ2l2ZW4gcXVvdGEgcm9vdC4KKyAqIEVhY2ggcXVvdGEgcm9vdCBoYXMgYSBzZXQgb2YgcmVzb3VyY2VzLCByZXByZXNlbnRlZCBieSB0aGUKKyAqIDxjb2RlPlF1b3RhLlJlc291cmNlPC9jb2RlPiBjbGFzcy4gIEVhY2ggcmVzb3VyY2UgaGFzIGEgbmFtZQorICogKGZvciBleGFtcGxlLCAiU1RPUkFHRSIpLCBhIGN1cnJlbnQgdXNhZ2UsIGFuZCBhIHVzYWdlIGxpbWl0LgorICogU2VlIFJGQyAyMDg3LgorICoKKyAqIEBzaW5jZSBKYXZhTWFpbCAxLjQKKyAqLworCitwdWJsaWMgY2xhc3MgUXVvdGEgeworCisgICAgLyoqCisgICAgICogQW4gaW5kaXZpZHVhbCByZXNvdXJjZSBpbiBhIHF1b3RhIHJvb3QuCisgICAgICoKKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS40CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBSZXNvdXJjZSB7CisJLyoqIFRoZSBuYW1lIG9mIHRoZSByZXNvdXJjZS4gKi8KKwlwdWJsaWMgU3RyaW5nIG5hbWU7CisJLyoqIFRoZSBjdXJyZW50IHVzYWdlIG9mIHRoZSByZXNvdXJjZS4gKi8KKwlwdWJsaWMgbG9uZyB1c2FnZTsKKwkvKiogVGhlIHVzYWdlIGxpbWl0IGZvciB0aGUgcmVzb3VyY2UuICovCisJcHVibGljIGxvbmcgbGltaXQ7CisKKwkvKioKKwkgKiBDb25zdHJ1Y3QgYSBSZXNvdXJjZSBvYmplY3Qgd2l0aCB0aGUgZ2l2ZW4gbmFtZSwKKwkgKiB1c2FnZSwgYW5kIGxpbWl0LgorCSAqCisJICogQHBhcmFtCW5hbWUJdGhlIHJlc291cmNlIG5hbWUKKwkgKiBAcGFyYW0JdXNhZ2UJdGhlIGN1cnJlbnQgdXNhZ2Ugb2YgdGhlIHJlc291cmNlCisJICogQHBhcmFtCWxpbWl0CXRoZSB1c2FnZSBsaW1pdCBmb3IgdGhlIHJlc291cmNlCisJICovCisJcHVibGljIFJlc291cmNlKFN0cmluZyBuYW1lLCBsb25nIHVzYWdlLCBsb25nIGxpbWl0KQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBuYW1lIG9mIHRoZSBxdW90YSByb290LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgcXVvdGFSb290OworCisgICAgLyoqCisgICAgICogVGhlIHNldCBvZiByZXNvdXJjZXMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgcXVvdGEgcm9vdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUXVvdGEuUmVzb3VyY2VbXSByZXNvdXJjZXM7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBRdW90YSBvYmplY3QgZm9yIHRoZSBuYW1lZCBxdW90YXJvb3Qgd2l0aCBubyBhc3NvY2lhdGVkCisgICAgICogcmVzb3VyY2VzLgorICAgICAqCisgICAgICogQHBhcmFtCXF1b3RhUm9vdAl0aGUgbmFtZSBvZiB0aGUgcXVvdGEgcm9vdAorICAgICAqLworICAgIHB1YmxpYyBRdW90YShTdHJpbmcgcXVvdGFSb290KQorCisgICAgLyoqCisgICAgICogU2V0IGEgcmVzb3VyY2UgbGltaXQgZm9yIHRoaXMgcXVvdGEgcm9vdC4KKyAgICAgKgorICAgICAqIEBwYXJhbQluYW1lCXRoZSBuYW1lIG9mIHRoZSByZXNvdXJjZQorICAgICAqIEBwYXJhbQlsaW1pdAl0aGUgcmVzb3VyY2UgbGltaXQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRSZXNvdXJjZUxpbWl0KFN0cmluZyBuYW1lLCBsb25nIGxpbWl0KQorfQorCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKzIwLiBBZGQgQnl0ZUFycmF5RGF0YVNvdXJjZSBjbGFzcyAoNDYyMzUxNykKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworVGhlIEJ5dGVBcnJheURhdGFTb3VyY2UgaGFzIGJlZW4gaW5jbHVkZWQgaW4gdGhlIEphdmFNYWlsIGRlbW8KK3NvdXJjZSBjb2RlIGZvciBxdWl0ZSBzb21lIHRpbWUuICBRdWl0ZSBhIGZldyBhcHBsaWNhdGlvbnMgbmVlZAorYSBjbGFzcyBvZiB0aGlzIHNvcnQuICBJdCdzIHRpbWUgdG8gYWRkIGl0IGFzIGEgc3RhbmRhcmQgQVBJLgorVG8gYXZvaWQgY29uZmxpY3Rpbmcgd2l0aCBhcHBsaWNhdGlvbnMgdGhhdCBoYXZlIHVzZWQgdGhlIGRlbW8KK3ZlcnNpb24sIHdlICBwdXQgdGhpcyB2ZXJzaW9uIGluIGEgbmV3IGphdmF4Lm1haWwudXRpbCBwYWNrYWdlLgorCitwYWNrYWdlIGphdmF4Lm1haWwudXRpbDsKKworLyoqCisgKiBBIERhdGFTb3VyY2UgYmFja2VkIGJ5IGEgYnl0ZSBhcnJheS4gIFRoZSBieXRlIGFycmF5IG1heSBiZQorICogcGFzc2VkIGluIGRpcmVjdGx5LCBvciBtYXkgYmUgaW5pdGlhbGl6ZWQgZnJvbSBhbiBJbnB1dFN0cmVhbQorICogb3IgYSBTdHJpbmcuCisgKgorICogQHNpbmNlIEphdmFNYWlsIDEuNAorICovCitwdWJsaWMgY2xhc3MgQnl0ZUFycmF5RGF0YVNvdXJjZSBpbXBsZW1lbnRzIERhdGFTb3VyY2UgeworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIEJ5dGVBcnJheURhdGFTb3VyY2Ugd2l0aCBkYXRhIGZyb20gdGhlCisgICAgICogc3BlY2lmaWVkIGJ5dGUgYXJyYXkgYW5kIHdpdGggdGhlIHNwZWNpZmllZCBNSU1FIHR5cGUuCisgICAgICovCisgICAgcHVibGljIEJ5dGVBcnJheURhdGFTb3VyY2UoYnl0ZVtdIGRhdGEsIFN0cmluZyB0eXBlKQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgQnl0ZUFycmF5RGF0YVNvdXJjZSB3aXRoIGRhdGEgZnJvbSB0aGUKKyAgICAgKiBzcGVjaWZpZWQgSW5wdXRTdHJlYW0gYW5kIHdpdGggdGhlIHNwZWNpZmllZCBNSU1FIHR5cGUuCisgICAgICogVGhlIElucHV0U3RyZWFtIGlzIHJlYWQgY29tcGxldGVseSBhbmQgdGhlIGRhdGEgaXMKKyAgICAgKiBzdG9yZWQgaW4gYSBieXRlIGFycmF5LgorICAgICAqLworICAgIHB1YmxpYyBCeXRlQXJyYXlEYXRhU291cmNlKElucHV0U3RyZWFtIGlzLCBTdHJpbmcgdHlwZSkgdGhyb3dzIElPRXhjZXB0aW9uCisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBCeXRlQXJyYXlEYXRhU291cmNlIHdpdGggZGF0YSBmcm9tIHRoZQorICAgICAqIHNwZWNpZmllZCBTdHJpbmcgYW5kIHdpdGggdGhlIHNwZWNpZmllZCBNSU1FIHR5cGUuCisgICAgICogVGhlIE1JTUUgdHlwZSBzaG91bGQgaW5jbHVkZSBhIDxjb2RlPmNoYXJzZXQ8L2NvZGU+CisgICAgICogcGFyYW1ldGVyIHNwZWNpZnlpbmcgdGhlIGNoYXJzZXQgdG8gYmUgdXNlZCBmb3IgdGhlCisgICAgICogc3RyaW5nLiAgSWYgdGhlIHBhcmFtZXRlciBpcyBub3QgaW5jbHVkZWQsIHRoZQorICAgICAqIGRlZmF1bHQgY2hhcnNldCBpcyB1c2VkLgorICAgICAqLworICAgIHB1YmxpYyBCeXRlQXJyYXlEYXRhU291cmNlKFN0cmluZyBkYXRhLCBTdHJpbmcgdHlwZSkgdGhyb3dzIElPRXhjZXB0aW9uCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYW4gSW5wdXRTdHJlYW0gZm9yIHRoZSBkYXRhLgorICAgICAqIE5vdGUgdGhhdCBhIG5ldyBzdHJlYW0gaXMgcmV0dXJuZWQgZWFjaCB0aW1lCisgICAgICogdGhpcyBtZXRob2QgaXMgY2FsbGVkLgorICAgICAqLworICAgIHB1YmxpYyBJbnB1dFN0cmVhbSBnZXRJbnB1dFN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbgorCisgICAgLyoqCisgICAgICogUmV0dXJuIGFuIE91dHB1dFN0cmVhbSBmb3IgdGhlIGRhdGEuCisgICAgICogV3JpdGluZyB0aGUgZGF0YSBpcyBub3Qgc3VwcG9ydGVkOyBhbiA8Y29kZT5JT0V4Y2VwdGlvbjwvY29kZT4KKyAgICAgKiBpcyBhbHdheXMgdGhyb3duLgorICAgICAqLworICAgIHB1YmxpYyBPdXRwdXRTdHJlYW0gZ2V0T3V0cHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uCisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIE1JTUUgY29udGVudCB0eXBlIG9mIHRoZSBkYXRhLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q29udGVudFR5cGUoKQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBuYW1lIG9mIHRoZSBkYXRhLgorICAgICAqIEJ5IGRlZmF1bHQsIGFuIGVtcHR5IHN0cmluZyAoIiIpIGlzIHJldHVybmVkLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpCisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIG5hbWUgb2YgdGhlIGRhdGEuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TmFtZShTdHJpbmcgbmFtZSkKK30KKworCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKzIxLiBBZGQgU2hhcmVkQnl0ZUFycmF5SW5wdXRTdHJlYW0gY2xhc3MgKDYzMDQxODkpCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitUaGUgU2hhcmVkSW5wdXRTdHJlYW0gaW50ZXJmYWNlIGFsbG93cyB0aGUgSmF2YU1haWwgaW1wbGVtZW50YXRpb24gdG8KK2VmZmljaWVudGx5IHByb2Nlc3MgZGF0YSB3aGVuIHBhcnNpbmcgbWVzc2FnZXMsIHdpdGhvdXQgbmVlZGluZyB0bworbWFrZSBtYW55IGNvcGllcyBvZiB0aGUgZGF0YS4gIFRoaXMgY2xhc3MgaXMgYW4gaW1wbGVtZW50YXRpb24gb2YgdGhlCitTaGFyZWRJbnB1dFN0cmVhbSBpbnRlcmZhY2UgdGhhdCB1c2VzIGEgYnl0ZSBhcnJheSBhcyB0aGUgYmFja2luZyBzdG9yZS4KKworcGFja2FnZSBqYXZheC5tYWlsLnV0aWw7CisKKy8qKgorICogQSBCeXRlQXJyYXlJbnB1dFN0cmVhbSB0aGF0IGltcGxlbWVudHMgdGhlIFNoYXJlZElucHV0U3RyZWFtIGludGVyZmFjZSwKKyAqIGFsbG93aW5nIHRoZSB1bmRlcmx5aW5nIGJ5dGUgYXJyYXkgdG8gYmUgc2hhcmVkIGJldHdlZW4gbXVsdGlwbGUgcmVhZGVycy4KKyAqCisgKiBAc2luY2UgSmF2YU1haWwgMS40CisgKi8KK3B1YmxpYyBjbGFzcyBTaGFyZWRCeXRlQXJyYXlJbnB1dFN0cmVhbSBleHRlbmRzIEJ5dGVBcnJheUlucHV0U3RyZWFtCisJCQkJaW1wbGVtZW50cyBTaGFyZWRJbnB1dFN0cmVhbSB7CisgICAgLyoqCisgICAgICogUG9zaXRpb24gd2l0aGluIHNoYXJlZCBidWZmZXIgdGhhdCB0aGlzIHN0cmVhbSBzdGFydHMgYXQuCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBzdGFydDsKKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIFNoYXJlZEJ5dGVBcnJheUlucHV0U3RyZWFtIHJlcHJlc2VudGluZyB0aGUgZW50aXJlCisgICAgICogYnl0ZSBhcnJheS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2hhcmVkQnl0ZUFycmF5SW5wdXRTdHJlYW0oYnl0ZVtdIGJ1ZikKKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIFNoYXJlZEJ5dGVBcnJheUlucHV0U3RyZWFtIHJlcHJlc2VudGluZyB0aGUgcGFydAorICAgICAqIG9mIHRoZSBieXRlIGFycmF5IGZyb20gPGNvZGU+b2Zmc2V0PC9jb2RlPiBmb3IgPGNvZGU+bGVuZ3RoPC9jb2RlPgorICAgICAqIGJ5dGVzLgorICAgICAqLworICAgIHB1YmxpYyBTaGFyZWRCeXRlQXJyYXlJbnB1dFN0cmVhbShieXRlW10gYnVmLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBJbnB1dFN0cmVhbSwgYXMgYW4KKyAgICAgKiBvZmZzZXQgZnJvbSB0aGUgYmVnaW5uaW5nIG9mIHRoZSBJbnB1dFN0cmVhbS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gIHRoZSBjdXJyZW50IHBvc2l0aW9uCisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0UG9zaXRpb24oKQorCisgICAgLyoqCisgICAgICogUmV0dXJuIGEgbmV3IElucHV0U3RyZWFtIHJlcHJlc2VudGluZyBhIHN1YnNldCBvZiB0aGUgZGF0YQorICAgICAqIGZyb20gdGhpcyBJbnB1dFN0cmVhbSwgc3RhcnRpbmcgYXQgPGNvZGU+c3RhcnQ8L2NvZGU+IChpbmNsdXNpdmUpCisgICAgICogdXAgdG8gPGNvZGU+ZW5kPC9jb2RlPiAoZXhjbHVzaXZlKS4gIDxjb2RlPnN0YXJ0PC9jb2RlPiBtdXN0IGJlCisgICAgICogbm9uLW5lZ2F0aXZlLiAgSWYgPGNvZGU+ZW5kPC9jb2RlPiBpcyAtMSwgdGhlIG5ldyBzdHJlYW0gZW5kcworICAgICAqIGF0IHRoZSBzYW1lIHBsYWNlIGFzIHRoaXMgc3RyZWFtLiAgVGhlIHJldHVybmVkIElucHV0U3RyZWFtCisgICAgICogd2lsbCBhbHNvIGltcGxlbWVudCB0aGUgU2hhcmVkSW5wdXRTdHJlYW0gaW50ZXJmYWNlLgorICAgICAqCisgICAgICogQHBhcmFtCXN0YXJ0CXRoZSBzdGFydGluZyBwb3NpdGlvbgorICAgICAqIEBwYXJhbQllbmQJdGhlIGVuZGluZyBwb3NpdGlvbiArIDEKKyAgICAgKiBAcmV0dXJuCQl0aGUgbmV3IHN0cmVhbQorICAgICAqLworICAgIHB1YmxpYyBJbnB1dFN0cmVhbSBuZXdTdHJlYW0obG9uZyBzdGFydCwgbG9uZyBlbmQpCit9CisKKworPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisyMi4gQWRkIFNoYXJlZEZpbGVJbnB1dFN0cmVhbSBjbGFzcyAoNjMwNDE5MykKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitGaW5hbGx5LCBTaGFyZWRGaWxlSW5wdXRTdHJlYW0gaXMgYW4gaW1wbGVtZW50YXRpb24gb2YgdGhlCitTaGFyZWRJbnB1dFN0cmVhbSBpbnRlcmZhY2UgdGhhdCB1c2VzIGEgZmlsZSBhcyB0aGUgYmFja2luZyBzdG9yZS4KKworcGFja2FnZSBqYXZheC5tYWlsLnV0aWw7CisKKy8qKgorICogQSA8Y29kZT5TaGFyZWRGaWxlSW5wdXRTdHJlYW08L2NvZGU+IGlzIGEKKyAqIDxjb2RlPkJ1ZmZlcmVkSW5wdXRTdHJlYW08L2NvZGU+IHRoYXQgYnVmZmVycworICogZGF0YSBmcm9tIHRoZSBmaWxlIGFuZCBzdXBwb3J0cyB0aGUgPGNvZGU+bWFyazwvY29kZT4KKyAqIGFuZCA8Y29kZT5yZXNldDwvY29kZT4gbWV0aG9kcy4gIEl0IGFsc28gc3VwcG9ydHMgdGhlCisgKiA8Y29kZT5uZXdTdHJlYW08L2NvZGU+IG1ldGhvZCB0aGF0IGFsbG93cyB5b3UgdG8gY3JlYXRlCisgKiBvdGhlciBzdHJlYW1zIHRoYXQgcmVwcmVzZW50IHN1YnNldHMgb2YgdGhlIGZpbGUuCisgKiBBIDxjb2RlPlJhbmRvbUFjY2Vzc0ZpbGU8L2NvZGU+IG9iamVjdCBpcyB1c2VkIHRvCisgKiBhY2Nlc3MgdGhlIGZpbGUgZGF0YS4KKyAqCisgKiBAc2luY2UgICBKYXZhTWFpbCAxLjQKKyAqLworcHVibGljIGNsYXNzIFNoYXJlZEZpbGVJbnB1dFN0cmVhbSBleHRlbmRzIEJ1ZmZlcmVkSW5wdXRTdHJlYW0KKwkJCQlpbXBsZW1lbnRzIFNoYXJlZElucHV0U3RyZWFtIHsKKworICAgIC8qKgorICAgICAqIFRoZSBmaWxlIGNvbnRhaW5pbmcgdGhlIGRhdGEuCisgICAgICogU2hhcmVkIGJ5IGFsbCByZWxhdGVkIFNoYXJlZEZpbGVJbnB1dFN0cmVhbSBpbnN0YW5jZXMuCisgICAgICovCisgICAgcHJvdGVjdGVkIFJhbmRvbUFjY2Vzc0ZpbGUgaW47CisKKyAgICAvKioKKyAgICAgKiBUaGUgbm9ybWFsIHNpemUgb2YgdGhlIHJlYWQgYnVmZmVyLgorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgYnVmc2l6ZTsKKworICAgIC8qKgorICAgICAqIFRoZSBmaWxlIG9mZnNldCB0aGF0IGNvcnJlc3BvbmRzIHRvIHRoZSBmaXJzdCBieXRlIGluCisgICAgICogdGhlIHJlYWQgYnVmZmVyLgorICAgICAqLworICAgIHByb3RlY3RlZCBsb25nIGJ1ZnBvczsKKworICAgIC8qKgorICAgICAqIFRoZSBmaWxlIG9mZnNldCBvZiB0aGUgc3RhcnQgb2YgZGF0YSBpbiB0aGlzIHN1YnNldCBvZiB0aGUgZmlsZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgbG9uZyBzdGFydCA9IDA7CisKKyAgICAvKioKKyAgICAgKiBUaGUgYW1vdW50IG9mIGRhdGEgaW4gdGhpcyBzdWJzZXQgb2YgdGhlIGZpbGUuCisgICAgICovCisgICAgcHJvdGVjdGVkIGxvbmcgZGF0YWxlbjsKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSA8Y29kZT5TaGFyZWRGaWxlSW5wdXRTdHJlYW08L2NvZGU+CisgICAgICogZm9yIHRoZSBmaWxlLgorICAgICAqCisgICAgICogQHBhcmFtICAgZmlsZSAgIHRoZSBmaWxlCisgICAgICovCisgICAgcHVibGljIFNoYXJlZEZpbGVJbnB1dFN0cmVhbShGaWxlIGZpbGUpIHRocm93cyBJT0V4Y2VwdGlvbgorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIDxjb2RlPlNoYXJlZEZpbGVJbnB1dFN0cmVhbTwvY29kZT4KKyAgICAgKiBmb3IgdGhlIG5hbWVkIGZpbGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gICBmaWxlICAgdGhlIGZpbGUKKyAgICAgKi8KKyAgICBwdWJsaWMgU2hhcmVkRmlsZUlucHV0U3RyZWFtKFN0cmluZyBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSA8Y29kZT5TaGFyZWRGaWxlSW5wdXRTdHJlYW08L2NvZGU+CisgICAgICogd2l0aCB0aGUgc3BlY2lmaWVkIGJ1ZmZlciBzaXplLgorICAgICAqCisgICAgICogQHBhcmFtICAgZmlsZQl0aGUgZmlsZQorICAgICAqIEBwYXJhbSAgIHNpemUgICB0aGUgYnVmZmVyIHNpemUuCisgICAgICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgc2l6ZSA8PSAwLgorICAgICAqLworICAgIHB1YmxpYyBTaGFyZWRGaWxlSW5wdXRTdHJlYW0oRmlsZSBmaWxlLCBpbnQgc2l6ZSkgdGhyb3dzIElPRXhjZXB0aW9uCisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgPGNvZGU+U2hhcmVkRmlsZUlucHV0U3RyZWFtPC9jb2RlPgorICAgICAqIHdpdGggdGhlIHNwZWNpZmllZCBidWZmZXIgc2l6ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSAgIGZpbGUJdGhlIGZpbGUKKyAgICAgKiBAcGFyYW0gICBzaXplICAgdGhlIGJ1ZmZlciBzaXplLgorICAgICAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHNpemUgPD0gMC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU2hhcmVkRmlsZUlucHV0U3RyZWFtKFN0cmluZyBmaWxlLCBpbnQgc2l6ZSkgdGhyb3dzIElPRXhjZXB0aW9uCisKKyAgICAvKioKKyAgICAgKiBTZWUgdGhlIGdlbmVyYWwgY29udHJhY3Qgb2YgdGhlIDxjb2RlPnJlYWQ8L2NvZGU+CisgICAgICogbWV0aG9kIG9mIDxjb2RlPklucHV0U3RyZWFtPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gICAgIHRoZSBuZXh0IGJ5dGUgb2YgZGF0YSwgb3IgPGNvZGU+LTE8L2NvZGU+IGlmIHRoZSBlbmQgb2YgdGhlCisgICAgICogICAgICAgICAgICAgc3RyZWFtIGlzIHJlYWNoZWQuCisgICAgICogQGV4Y2VwdGlvbiAgSU9FeGNlcHRpb24gIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIGludCByZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uCisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBieXRlcyBmcm9tIHRoaXMgc3RyZWFtIGludG8gdGhlIHNwZWNpZmllZCBieXRlIGFycmF5LAorICAgICAqIHN0YXJ0aW5nIGF0IHRoZSBnaXZlbiBvZmZzZXQuCisgICAgICoKKyAgICAgKiA8cD4gVGhpcyBtZXRob2QgaW1wbGVtZW50cyB0aGUgZ2VuZXJhbCBjb250cmFjdCBvZiB0aGUgY29ycmVzcG9uZGluZworICAgICAqIDxjb2RlPntAbGluayBqYXZhLmlvLklucHV0U3RyZWFtI3JlYWQoYnl0ZVtdLCBpbnQsIGludCkgcmVhZH08L2NvZGU+CisgICAgICogbWV0aG9kIG9mIHRoZSA8Y29kZT57QGxpbmsgamF2YS5pby5JbnB1dFN0cmVhbX08L2NvZGU+IGNsYXNzLgorICAgICAqCisgICAgICogQHBhcmFtICAgICAgYiAgICAgZGVzdGluYXRpb24gYnVmZmVyLgorICAgICAqIEBwYXJhbSAgICAgIG9mZiAgIG9mZnNldCBhdCB3aGljaCB0byBzdGFydCBzdG9yaW5nIGJ5dGVzLgorICAgICAqIEBwYXJhbSAgICAgIGxlbiAgIG1heGltdW0gbnVtYmVyIG9mIGJ5dGVzIHRvIHJlYWQuCisgICAgICogQHJldHVybiAgICAgdGhlIG51bWJlciBvZiBieXRlcyByZWFkLCBvciA8Y29kZT4tMTwvY29kZT4gaWYgdGhlIGVuZCBvZgorICAgICAqICAgICAgICAgICAgIHRoZSBzdHJlYW0gaGFzIGJlZW4gcmVhY2hlZC4KKyAgICAgKiBAZXhjZXB0aW9uICBJT0V4Y2VwdGlvbiAgaWYgYW4gSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHJlYWQoYnl0ZSBiW10sIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbgorCisgICAgLyoqCisgICAgICogU2VlIHRoZSBnZW5lcmFsIGNvbnRyYWN0IG9mIHRoZSA8Y29kZT5za2lwPC9jb2RlPgorICAgICAqIG1ldGhvZCBvZiA8Y29kZT5JbnB1dFN0cmVhbTwvY29kZT4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gICAgICBuICAgdGhlIG51bWJlciBvZiBieXRlcyB0byBiZSBza2lwcGVkLgorICAgICAqIEByZXR1cm4gICAgIHRoZSBhY3R1YWwgbnVtYmVyIG9mIGJ5dGVzIHNraXBwZWQuCisgICAgICogQGV4Y2VwdGlvbiAgSU9FeGNlcHRpb24gIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIGxvbmcgc2tpcChsb25nIG4pIHRocm93cyBJT0V4Y2VwdGlvbgorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRoYXQgY2FuIGJlIHJlYWQgZnJvbSB0aGlzIGlucHV0IAorICAgICAqIHN0cmVhbSB3aXRob3V0IGJsb2NraW5nLiAKKyAgICAgKgorICAgICAqIEByZXR1cm4gICAgIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCBjYW4gYmUgcmVhZCBmcm9tIHRoaXMgaW5wdXQKKyAgICAgKiAgICAgICAgICAgICBzdHJlYW0gd2l0aG91dCBibG9ja2luZy4KKyAgICAgKiBAZXhjZXB0aW9uICBJT0V4Y2VwdGlvbiAgaWYgYW4gSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGF2YWlsYWJsZSgpIHRocm93cyBJT0V4Y2VwdGlvbgorCisgICAgLyoqIAorICAgICAqIFNlZSB0aGUgZ2VuZXJhbCBjb250cmFjdCBvZiB0aGUgPGNvZGU+bWFyazwvY29kZT4KKyAgICAgKiBtZXRob2Qgb2YgPGNvZGU+SW5wdXRTdHJlYW08L2NvZGU+LgorICAgICAqCisgICAgICogQHBhcmFtICAgcmVhZGxpbWl0ICAgdGhlIG1heGltdW0gbGltaXQgb2YgYnl0ZXMgdGhhdCBjYW4gYmUgcmVhZCBiZWZvcmUKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICB0aGUgbWFyayBwb3NpdGlvbiBiZWNvbWVzIGludmFsaWQuCisgICAgICogQHNlZSAgICAgI3Jlc2V0KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBtYXJrKGludCByZWFkbGltaXQpCisKKyAgICAvKioKKyAgICAgKiBTZWUgdGhlIGdlbmVyYWwgY29udHJhY3Qgb2YgdGhlIDxjb2RlPnJlc2V0PC9jb2RlPgorICAgICAqIG1ldGhvZCBvZiA8Y29kZT5JbnB1dFN0cmVhbTwvY29kZT4uCisgICAgICogPHA+CisgICAgICogSWYgPGNvZGU+bWFya3BvczwvY29kZT4gaXMgPGNvZGU+LTE8L2NvZGU+CisgICAgICogKG5vIG1hcmsgaGFzIGJlZW4gc2V0IG9yIHRoZSBtYXJrIGhhcyBiZWVuCisgICAgICogaW52YWxpZGF0ZWQpLCBhbiA8Y29kZT5JT0V4Y2VwdGlvbjwvY29kZT4KKyAgICAgKiBpcyB0aHJvd24uIE90aGVyd2lzZSwgPGNvZGU+cG9zPC9jb2RlPiBpcworICAgICAqIHNldCBlcXVhbCB0byA8Y29kZT5tYXJrcG9zPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24gIElPRXhjZXB0aW9uICBpZiB0aGlzIHN0cmVhbSBoYXMgbm90IGJlZW4gbWFya2VkIG9yCisgICAgICogICAgICAgICAgICAgICBpZiB0aGUgbWFyayBoYXMgYmVlbiBpbnZhbGlkYXRlZC4KKyAgICAgKiBAc2VlICAgICAgICAjbWFyayhpbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVzZXQoKSB0aHJvd3MgSU9FeGNlcHRpb24KKworICAgIC8qKgorICAgICAqIFRlc3RzIGlmIHRoaXMgaW5wdXQgc3RyZWFtIHN1cHBvcnRzIHRoZSA8Y29kZT5tYXJrPC9jb2RlPiAKKyAgICAgKiBhbmQgPGNvZGU+cmVzZXQ8L2NvZGU+IG1ldGhvZHMuIFRoZSA8Y29kZT5tYXJrU3VwcG9ydGVkPC9jb2RlPiAKKyAgICAgKiBtZXRob2Qgb2YgPGNvZGU+U2hhcmVkRmlsZUlucHV0U3RyZWFtPC9jb2RlPiByZXR1cm5zIAorICAgICAqIDxjb2RlPnRydWU8L2NvZGU+LiAKKyAgICAgKgorICAgICAqIEByZXR1cm4gIGEgPGNvZGU+Ym9vbGVhbjwvY29kZT4gaW5kaWNhdGluZyBpZiB0aGlzIHN0cmVhbSB0eXBlIHN1cHBvcnRzCisgICAgICogICAgICAgICAgdGhlIDxjb2RlPm1hcms8L2NvZGU+IGFuZCA8Y29kZT5yZXNldDwvY29kZT4gbWV0aG9kcy4KKyAgICAgKiBAc2VlICAgICBqYXZhLmlvLklucHV0U3RyZWFtI21hcmsoaW50KQorICAgICAqIEBzZWUgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0jcmVzZXQoKQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIG1hcmtTdXBwb3J0ZWQoKQorCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoaXMgaW5wdXQgc3RyZWFtIGFuZCByZWxlYXNlcyBhbnkgc3lzdGVtIHJlc291cmNlcyAKKyAgICAgKiBhc3NvY2lhdGVkIHdpdGggdGhlIHN0cmVhbS4gCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uICBJT0V4Y2VwdGlvbiAgaWYgYW4gSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbgorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBJbnB1dFN0cmVhbSwgYXMgYW4KKyAgICAgKiBvZmZzZXQgZnJvbSB0aGUgYmVnaW5uaW5nIG9mIHRoZSBJbnB1dFN0cmVhbS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gIHRoZSBjdXJyZW50IHBvc2l0aW9uCisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0UG9zaXRpb24oKQorCisgICAgLyoqCisgICAgICogUmV0dXJuIGEgbmV3IElucHV0U3RyZWFtIHJlcHJlc2VudGluZyBhIHN1YnNldCBvZiB0aGUgZGF0YQorICAgICAqIGZyb20gdGhpcyBJbnB1dFN0cmVhbSwgc3RhcnRpbmcgYXQgPGNvZGU+c3RhcnQ8L2NvZGU+IChpbmNsdXNpdmUpCisgICAgICogdXAgdG8gPGNvZGU+ZW5kPC9jb2RlPiAoZXhjbHVzaXZlKS4gIDxjb2RlPnN0YXJ0PC9jb2RlPiBtdXN0IGJlCisgICAgICogbm9uLW5lZ2F0aXZlLiAgSWYgPGNvZGU+ZW5kPC9jb2RlPiBpcyAtMSwgdGhlIG5ldyBzdHJlYW0gZW5kcworICAgICAqIGF0IHRoZSBzYW1lIHBsYWNlIGFzIHRoaXMgc3RyZWFtLiAgVGhlIHJldHVybmVkIElucHV0U3RyZWFtCisgICAgICogd2lsbCBhbHNvIGltcGxlbWVudCB0aGUgU2hhcmVkSW5wdXRTdHJlYW0gaW50ZXJmYWNlLgorICAgICAqCisgICAgICogQHBhcmFtCXN0YXJ0CXRoZSBzdGFydGluZyBwb3NpdGlvbgorICAgICAqIEBwYXJhbQllbmQJdGhlIGVuZGluZyBwb3NpdGlvbiArIDEKKyAgICAgKiBAcmV0dXJuCQl0aGUgbmV3IHN0cmVhbQorICAgICAqLworICAgIHB1YmxpYyBJbnB1dFN0cmVhbSBuZXdTdHJlYW0obG9uZyBzdGFydCwgbG9uZyBlbmQpCisKKyAgICAvKioKKyAgICAgKiBGb3JjZSB0aGlzIHN0cmVhbSB0byBjbG9zZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBmaW5hbGl6ZSgpIHRocm93cyBUaHJvd2FibGUKK30KZGlmZiAtLWdpdCBhL2RvYy9zcGVjL0phdmFNYWlsLTEuNS1jaGFuZ2VzLnR4dCBiL2RvYy9zcGVjL0phdmFNYWlsLTEuNS1jaGFuZ2VzLnR4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42NTU0MDBkCi0tLSAvZGV2L251bGwKKysrIGIvZG9jL3NwZWMvSmF2YU1haWwtMS41LWNoYW5nZXMudHh0CkBAIC0wLDAgKzEsODIzIEBACisKKwkJSmF2YU1haWwgMS41CisJCT09PT09PT09PT09PQorCisJCShVcGRhdGVkIEZlYnJ1YXJ5IDcsIDIwMTMpCisKK0ZvbGxvd2luZyBpcyBhIGRlc2NyaXB0aW9uIG9mIHRoZSBjaGFuZ2VzIHRvIHRoZSBKYXZhTWFpbAorQVBJIGludHJvZHVjZWQgaW4gSmF2YU1haWwgMS41LiAgVGhlIG51bWJlcnMgaW4gcGFyZW50aGVzZXMKK2FyZSBidWcgbnVtYmVyczsgeW91IGNhbiBmaW5kIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgdGhlCitidWcgcmVwb3J0cyBhdDoKKworICAgIGh0dHBzOi8vZ2l0aHViLmNvbS9qYXZhZWUvamF2YW1haWwvaXNzdWVzLzxidWcgbnVtYmVyPgorCitQbGVhc2Ugc2VuZCBjb21tZW50cyBhbmQgZmVlZGJhY2sgdG8gamF2YW1haWxfd3dAb3JhY2xlLmNvbS4KKworSmF2YU1haWwgMS41IHdpbGwgYWxzbyByZXF1aXJlIGF0IGxlYXN0IEoyU0UgNS4wLiAgVGhpcyBhbGxvd3MKK0phdmFNYWlsIHRvIHRha2UgYWR2YW50YWdlIG9mIGZlYXR1cmVzIG9mIG1vcmUgbW9kZXJuIEphdmEgU0UgcmVsZWFzZXMuCisKKworPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisxLiBBZGQgRmV0Y2hQcm9maWxlLkl0ZW0uU0laRSAoMzcpCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK1RoZSBGZXRjaFByb2ZpbGUuSXRlbS5TSVpFIGl0ZW0gYWxsb3dzIHByZWZldGNoaW5nIHRoZSBzaXplIG9mCithIG1lc3NhZ2UuICBQcmV2aW91c2x5IHRoaXMgd2FzIGFuIElNQVAtc3BlY2lmaWMgZmV0Y2ggaXRlbS4KKworCS8qKgorCSAqIFNJWkUgaXMgYSBmZXRjaCBwcm9maWxlIGl0ZW0gdGhhdCBjYW4gYmUgaW5jbHVkZWQgaW4gYQorCSAqIDxjb2RlPkZldGNoUHJvZmlsZTwvY29kZT4gZHVyaW5nIGEgZmV0Y2ggcmVxdWVzdCB0byBhIEZvbGRlci4KKwkgKiBUaGlzIGl0ZW0gaW5kaWNhdGVzIHRoYXQgdGhlIHNpemVzIG9mIHRoZSBtZXNzYWdlcyBpbiB0aGUgc3BlY2lmaWVkIAorCSAqIHJhbmdlIHNob3VsZCBiZSBwcmVmZXRjaGVkLiA8cD4KKwkgKgorCSAqIEBzaW5jZQlKYXZhTWFpbCAxLjUKKwkgKi8KKwlwdWJsaWMgc3RhdGljIGZpbmFsIEl0ZW0gU0laRTsKKworCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKzIuIEZpeCBwcm90ZWN0ZWQgZmllbGRzIGluIGZpbmFsIGNsYXNzZXMgaW4gamF2YXgubWFpbC5zZWFyY2ggKDM4KQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK1NldmVyYWwgZmluYWwgY2xhc3NlcyBpbiB0aGUgamF2YXgubWFpbC5zZWFyY2ggcGFja2FnZSBjb250YWluCitwcm90ZWN0ZWQgZmllbGRzLiAgU2luY2UgdGhlIGNsYXNzZXMgYXJlIGZpbmFsLCB0aGV5IGNhbid0IGJlCitzdWJjbGFzc2VkLCBhbmQgdGhlIHByb3RlY3RlZCBmaWVsZHMgY2FuIG5vdCBiZSBhY2Nlc3NlZC4gIFRoaXMKK2NoYW5nZSBjbGVhbnMgdXAgdGhlc2UgZmllbGRzIGJ5IG1ha2luZyB0aGVtIHByaXZhdGUuICBUaGUgZm9sbG93aW5nCitmaWVsZHMgYXJlIGNoYW5nZWQ6CisKK2phdmF4Lm1haWwuc2VhcmNoLkFuZFRlcm06CisgICAgcHJpdmF0ZSBTZWFyY2hUZXJtW10gdGVybXM7CisKK2phdmF4Lm1haWwuc2VhcmNoLkZsYWdUZXJtOgorICAgIHByaXZhdGUgYm9vbGVhbiBzZXQ7CisgICAgcHJpdmF0ZSBGbGFncyBmbGFnczsKKworamF2YXgubWFpbC5zZWFyY2guSGVhZGVyVGVybToKKyAgICBwcml2YXRlIFN0cmluZyBoZWFkZXJOYW1lOworCitqYXZheC5tYWlsLnNlYXJjaC5Ob3RUZXJtOgorICAgIHByaXZhdGUgU2VhcmNoVGVybSB0ZXJtOworCitqYXZheC5tYWlsLnNlYXJjaC5PclRlcm06CisgICAgcHJpdmF0ZSBTZWFyY2hUZXJtW10gdGVybXM7CisKK2phdmF4Lm1haWwuc2VhcmNoLlJlY2lwaWVudFRlcm06CisgICAgcHJpdmF0ZSBNZXNzYWdlLlJlY2lwaWVudFR5cGUgdHlwZTsKKworCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKzMuIEFkZCBNaW1lTXVsdGlwYXJ0KFN0cmluZyBzdWJ0eXBlLCBCb2R5UGFydC4uLiBicHMpIGNvbnN0cnVjdG9yICgzOSkKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworVGhlc2UgY29udmVuaWVuY2UgY29uc3RydWN0b3JzIGNyZWF0ZSBhIE1pbWVNdWx0aXBhcnQgb2JqZWN0IGdpdmVuIGFuCithcnJheSBvciB2YXJhcmdzIGxpc3Qgb2YgQm9keVBhcnRzLgorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGEgTWltZU11bHRpcGFydCBvYmplY3Qgb2YgdGhlIGRlZmF1bHQgIm1peGVkIiBzdWJ0eXBlLAorICAgICAqIGFuZCB3aXRoIHRoZSBnaXZlbiBib2R5IHBhcnRzLiAgTW9yZSBib2R5IHBhcnRzIG1heSBiZSBhZGRlZCBsYXRlci4KKyAgICAgKgorICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgTWltZU11bHRpcGFydChCb2R5UGFydC4uLiBwYXJ0cykgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbgorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGEgTWltZU11bHRpcGFydCBvYmplY3Qgb2YgdGhlIGdpdmVuIHN1YnR5cGUKKyAgICAgKiBhbmQgd2l0aCB0aGUgZ2l2ZW4gYm9keSBwYXJ0cy4gIE1vcmUgYm9keSBwYXJ0cyBtYXkgYmUgYWRkZWQgbGF0ZXIuCisgICAgICoKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS41CisgICAgICovCisgICAgcHVibGljIE1pbWVNdWx0aXBhcnQoU3RyaW5nIHN1YnR5cGUsIEJvZHlQYXJ0Li4uIHBhcnRzKQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24KKworCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKzQuIEV4Y2VwdGlvbnMgc2hvdWxkIHN1cHBvcnQgZXhjZXB0aW9uIGNoYWluaW5nICg0MCkKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24gd2FzIGRlc2lnbmVkIGJlZm9yZSBleGNlcHRpb24gY2hhaW5naW5nCit3YXMgYWRkZWQgdG8gSmF2YSBTRSwgYnV0IGl0IGRvZXMgc3VwcG9ydCBhIHNpbWlsYXIgY29uY2VwdCBpdHNlbGYsCithbmQgdGhhdCBzdXBwb3J0IHNob3VsZCBiZSBtYWRlIGF2YWlsYWJsZSB0byBhbGwgc3ViY2xhc3Nlcy4KKworamF2YXgubWFpbC5BdXRoZW50aWNhdGlvbkZhaWxlZEV4Y2VwdGlvbjoKKyAgIC8qKgorICAgICogQ29uc3RydWN0cyBhbiBBdXRoZW50aWNhdGlvbkZhaWxlZEV4Y2VwdGlvbiB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAqIGRldGFpbCBtZXNzYWdlIGFuZCBlbWJlZGRlZCBleGNlcHRpb24uICBUaGUgZXhjZXB0aW9uIGlzIGNoYWluZWQKKyAgICAqIHRvIHRoaXMgZXhjZXB0aW9uLgorICAgICoKKyAgICAqIEBwYXJhbSBtZXNzYWdlCVRoZSBkZXRhaWxlZCBlcnJvciBtZXNzYWdlCisgICAgKiBAcGFyYW0gZQkJVGhlIGVtYmVkZGVkIGV4Y2VwdGlvbgorICAgICogQHNpbmNlCQlKYXZhTWFpbCAxLjUKKyAgICAqLworICAgcHVibGljIEF1dGhlbnRpY2F0aW9uRmFpbGVkRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlLCBFeGNlcHRpb24gZSkKKworamF2YXgubWFpbC5Gb2xkZXJDbG9zZWRFeGNlcHRpb246CisgICAvKioKKyAgICAqIENvbnN0cnVjdHMgYSBGb2xkZXJDbG9zZWRFeGNlcHRpb24gd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgKiBkZXRhaWwgbWVzc2FnZSBhbmQgZW1iZWRkZWQgZXhjZXB0aW9uLiAgVGhlIGV4Y2VwdGlvbiBpcyBjaGFpbmVkCisgICAgKiB0byB0aGlzIGV4Y2VwdGlvbi4KKyAgICAqCisgICAgKiBAcGFyYW0gZm9sZGVyIAlUaGUgRm9sZGVyCisgICAgKiBAcGFyYW0gbWVzc2FnZQlUaGUgZGV0YWlsZWQgZXJyb3IgbWVzc2FnZQorICAgICogQHBhcmFtIGUJCVRoZSBlbWJlZGRlZCBleGNlcHRpb24KKyAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS41CisgICAgKi8KKyAgIHB1YmxpYyBGb2xkZXJDbG9zZWRFeGNlcHRpb24oRm9sZGVyIGZvbGRlciwgU3RyaW5nIG1lc3NhZ2UsIEV4Y2VwdGlvbiBlKQorCitqYXZheC5tYWlsLkZvbGRlck5vdEZvdW5kRXhjZXB0aW9uOgorICAgLyoqCisgICAgKiBDb25zdHJ1Y3RzIGEgRm9sZGVyTm90Rm91bmRFeGNlcHRpb24gd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgKiBkZXRhaWwgbWVzc2FnZSBhbmQgZW1iZWRkZWQgZXhjZXB0aW9uLiAgVGhlIGV4Y2VwdGlvbiBpcyBjaGFpbmVkCisgICAgKiB0byB0aGlzIGV4Y2VwdGlvbi4KKyAgICAqCisgICAgKiBAcGFyYW0gZm9sZGVyCVRoZSBGb2xkZXIKKyAgICAqIEBwYXJhbSBzCQlUaGUgZGV0YWlsZWQgZXJyb3IgbWVzc2FnZQorICAgICogQHBhcmFtIGUJCVRoZSBlbWJlZGRlZCBleGNlcHRpb24KKyAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS41CisgICAgKi8KKyAgIHB1YmxpYyBGb2xkZXJOb3RGb3VuZEV4Y2VwdGlvbihGb2xkZXIgZm9sZGVyLCBTdHJpbmcgcywgRXhjZXB0aW9uIGUpCisKK2phdmF4Lm1haWwuSWxsZWdhbFdyaXRlRXhjZXB0aW9uOgorICAgLyoqCisgICAgKiBDb25zdHJ1Y3RzIGFuIElsbGVnYWxXcml0ZUV4Y2VwdGlvbiB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAqIGRldGFpbCBtZXNzYWdlIGFuZCBlbWJlZGRlZCBleGNlcHRpb24uICBUaGUgZXhjZXB0aW9uIGlzIGNoYWluZWQKKyAgICAqIHRvIHRoaXMgZXhjZXB0aW9uLgorICAgICoKKyAgICAqIEBwYXJhbSBzCQlUaGUgZGV0YWlsZWQgZXJyb3IgbWVzc2FnZQorICAgICogQHBhcmFtIGUJCVRoZSBlbWJlZGRlZCBleGNlcHRpb24KKyAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS41CisgICAgKi8KKyAgIHB1YmxpYyBJbGxlZ2FsV3JpdGVFeGNlcHRpb24oU3RyaW5nIHMsIEV4Y2VwdGlvbiBlKQorCitqYXZheC5tYWlsLk1lc3NhZ2VSZW1vdmVkRXhjZXB0aW9uOgorICAgLyoqCisgICAgKiBDb25zdHJ1Y3RzIGEgTWVzc2FnZVJlbW92ZWRFeGNlcHRpb24gd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgKiBkZXRhaWwgbWVzc2FnZSBhbmQgZW1iZWRkZWQgZXhjZXB0aW9uLiAgVGhlIGV4Y2VwdGlvbiBpcyBjaGFpbmVkCisgICAgKiB0byB0aGlzIGV4Y2VwdGlvbi4KKyAgICAqCisgICAgKiBAcGFyYW0gcwkJVGhlIGRldGFpbGVkIGVycm9yIG1lc3NhZ2UKKyAgICAqIEBwYXJhbSBlCQlUaGUgZW1iZWRkZWQgZXhjZXB0aW9uCisgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuNQorICAgICovCisgICBwdWJsaWMgTWVzc2FnZVJlbW92ZWRFeGNlcHRpb24oU3RyaW5nIHMsIEV4Y2VwdGlvbiBlKQorCitqYXZheC5tYWlsLk1ldGhvZE5vdFN1cHBvcnRlZEV4Y2VwdGlvbjoKKyAgIC8qKgorICAgICogQ29uc3RydWN0cyBhIE1ldGhvZE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAqIGRldGFpbCBtZXNzYWdlIGFuZCBlbWJlZGRlZCBleGNlcHRpb24uICBUaGUgZXhjZXB0aW9uIGlzIGNoYWluZWQKKyAgICAqIHRvIHRoaXMgZXhjZXB0aW9uLgorICAgICoKKyAgICAqIEBwYXJhbSBzCQlUaGUgZGV0YWlsZWQgZXJyb3IgbWVzc2FnZQorICAgICogQHBhcmFtIGUJCVRoZSBlbWJlZGRlZCBleGNlcHRpb24KKyAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS41CisgICAgKi8KKyAgIHB1YmxpYyBNZXRob2ROb3RTdXBwb3J0ZWRFeGNlcHRpb24oU3RyaW5nIHMsIEV4Y2VwdGlvbiBlKQorCitqYXZheC5tYWlsLk5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uOgorICAgLyoqCisgICAgKiBDb25zdHJ1Y3RzIGEgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgKiBkZXRhaWwgbWVzc2FnZSBhbmQgZW1iZWRkZWQgZXhjZXB0aW9uLiAgVGhlIGV4Y2VwdGlvbiBpcyBjaGFpbmVkCisgICAgKiB0byB0aGlzIGV4Y2VwdGlvbi4KKyAgICAqCisgICAgKiBAcGFyYW0gbWVzc2FnZQlUaGUgZGV0YWlsZWQgZXJyb3IgbWVzc2FnZQorICAgICogQHBhcmFtIGUJCVRoZSBlbWJlZGRlZCBleGNlcHRpb24KKyAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS41CisgICAgKi8KKyAgIHB1YmxpYyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSwgRXhjZXB0aW9uIGUpCisKK2phdmF4Lm1haWwuUmVhZE9ubHlGb2xkZXJFeGNlcHRpb246CisgICAvKioKKyAgICAqIENvbnN0cnVjdHMgYSBSZWFkT25seUZvbGRlckV4Y2VwdGlvbiB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAqIGRldGFpbCBtZXNzYWdlIGFuZCBlbWJlZGRlZCBleGNlcHRpb24uICBUaGUgZXhjZXB0aW9uIGlzIGNoYWluZWQKKyAgICAqIHRvIHRoaXMgZXhjZXB0aW9uLgorICAgICoKKyAgICAqIEBwYXJhbSBmb2xkZXIgCVRoZSBGb2xkZXIKKyAgICAqIEBwYXJhbSBtZXNzYWdlCVRoZSBkZXRhaWxlZCBlcnJvciBtZXNzYWdlCisgICAgKiBAcGFyYW0gZQkJVGhlIGVtYmVkZGVkIGV4Y2VwdGlvbgorICAgICogQHNpbmNlCQlKYXZhTWFpbCAxLjUKKyAgICAqLworICAgcHVibGljIFJlYWRPbmx5Rm9sZGVyRXhjZXB0aW9uKEZvbGRlciBmb2xkZXIsIFN0cmluZyBtZXNzYWdlLCBFeGNlcHRpb24gZSkKKworamF2YXgubWFpbC5TdG9yZUNsb3NlZEV4Y2VwdGlvbjoKKyAgIC8qKgorICAgICogQ29uc3RydWN0cyBhIFN0b3JlQ2xvc2VkRXhjZXB0aW9uIHdpdGggdGhlIHNwZWNpZmllZAorICAgICogZGV0YWlsIG1lc3NhZ2UgYW5kIGVtYmVkZGVkIGV4Y2VwdGlvbi4gIFRoZSBleGNlcHRpb24gaXMgY2hhaW5lZAorICAgICogdG8gdGhpcyBleGNlcHRpb24uCisgICAgKgorICAgICogQHBhcmFtIHN0b3JlCVRoZSBkZWFkIFN0b3JlIG9iamVjdAorICAgICogQHBhcmFtIG1lc3NhZ2UJVGhlIGRldGFpbGVkIGVycm9yIG1lc3NhZ2UKKyAgICAqIEBwYXJhbSBlCQlUaGUgZW1iZWRkZWQgZXhjZXB0aW9uCisgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuNQorICAgICovCisgICBwdWJsaWMgU3RvcmVDbG9zZWRFeGNlcHRpb24oU3RvcmUgc3RvcmUsIFN0cmluZyBtZXNzYWdlLCBFeGNlcHRpb24gZSkKKworCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKzUuIFBhcmFtZXRlckxpc3QgbmVlZHMgdG8gc3VwcG9ydCB1c2UgYnkgSU1BUCAoNDEpCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitUaGUgSU1BUCBwcm92aWRlciBoYXMgc3BlY2lhbCBuZWVkcyB3aGVuIHByb2Nlc3NpbmcgbXVsdGktc2VnbWVudAorcGFyYW1ldGVycyBkZWZpbmVkIGJ5IFJGQyAyMjMxLiAgVGhpcyBuZXcgbWV0aG9kIHN1cHBvcnRzIHN1Y2ggdXNlCitieSB0aGUgSU1BUCBwcm92aWRlci4KKworICAgLyoqCisgICAgKiBOb3JtYWwgdXNlcnMgb2YgdGhpcyBjbGFzcyB3aWxsIHVzZSBzaW1wbGUgcGFyYW1ldGVyIG5hbWVzLgorICAgICogSW4gc29tZSBjYXNlcywgZm9yIGV4YW1wbGUsIHdoZW4gcHJvY2Vzc2luZyBJTUFQIHByb3RvY29sCisgICAgKiBtZXNzYWdlcywgaW5kaXZpZHVhbCBzZWdtZW50cyBvZiBhIG11bHRpLXNlZ21lbnQgbmFtZQorICAgICogKHNwZWNpZmllZCBieSBSRkMgMjIzMSkgd2lsbCBiZSBlbmNvdW50ZXJlZCBhbmQgcGFzc2VkIHRvCisgICAgKiB0aGUge0BsaW5rICNzZXR9IG1ldGhvZC4gIEFmdGVyIGFsbCB0aGVzZSBzZWdtZW50cyBhcmUgYWRkZWQKKyAgICAqIHRvIHRoaXMgUGFyYW1ldGVyTGlzdCwgdGhleSBuZWVkIHRvIGJlIGNvbWJpbmVkIHRvIHJlcHJlc2VudAorICAgICogdGhlIGxvZ2ljYWwgcGFyYW1ldGVyIG5hbWUgYW5kIHZhbHVlLiAgVGhpcyBtZXRob2Qgd2lsbCBjb21iaW5lCisgICAgKiBhbGwgc2VnbWVudHMgb2YgbXVsdGktc2VnbWVudCBuYW1lcy4gPHA+CisgICAgKgorICAgICogTm9ybWFsIHVzZXJzIHNob3VsZCBuZXZlciBuZWVkIHRvIGNhbGwgdGhpcyBtZXRob2QuCisgICAgKgorICAgICogQHNpbmNlCUphdmFNYWlsIDEuNQorICAgICovIAorICAgcHVibGljIHZvaWQgY29tYmluZVNlZ21lbnRzKCkKKworCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKzYuIENvbnRlbnRUeXBlIGFuZCBDb250ZW50RGlzcG9zaXRpb24gdG9TdHJpbmcgc2hvdWxkIG5ldmVyIHJldHVybiBudWxsICg0MikKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworVGhlIGdlbmVyYWwgY29udHJhY3Qgb2YgT2JqZWN0LnRvU3RyaW5nIGlzIHRoYXQgaXQgbmV2ZXIgcmV0dXJucyBudWxsLgorVGhlIHRvU3RyaW5nIG1ldGhvZHMgb2YgQ29udGVudFR5cGUgYW5kIENvbnRlbnREaXNwb3NpdGlvbiB3ZXJlIGRlZmluZWQKK3RvIHJldHVybiBudWxsIGluIGNlcnRhaW4gZXJyb3IgY2FzZXMuICBHaXZlbiB0aGUgZ2VuZXJhbCB0b1N0cmluZyBjb250cmFjdAoraXQgc2VlbXMgdW5saWtlbHkgdGhhdCBhbnlvbmUgZXZlciBkZXBlbmRlZCBvbiB0aGVzZSBzcGVjaWFsIGNhc2VzLCBhbmQKK2l0IHdvdWxkIGJlIG1vcmUgdXNlZnVsIGZvciB0aGVzZSBjbGFzc2VzIHRvIG9iZXkgdGhlIGdlbmVyYWwgY29udHJhY3QuCitUaGVzZSBtZXRob2RzIGhhdmUgYmVlbiBjaGFuZ2VkIHRvIHJldHVybiBhbiBlbXB0eSBzdHJpbmcgaW4gdGhlc2UgZXJyb3IKK2Nhc2VzLgorCitqYXZheC5tYWlsLmludGVybmV0LkNvbnRlbnRUeXBlOgorICAgIC8qKgorICAgICAqIFJldHJpZXZlIGEgUkZDMjA0NSBzdHlsZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YKKyAgICAgKiB0aGlzIENvbnRlbnQtVHlwZS4gUmV0dXJucyBhbiBlbXB0eSBzdHJpbmcgaWYKKyAgICAgKiB0aGUgY29udmVyc2lvbiBmYWlsZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCVJGQzIwNDUgc3R5bGUgc3RyaW5nCisgICAgICovCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpCisKK2phdmF4Lm1haWwuaW50ZXJuZXQuQ29udGVudERpc3Bvc2l0aW9uOgorICAgIC8qKgorICAgICAqIFJldHJpZXZlIGEgUkZDMjA0NSBzdHlsZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YKKyAgICAgKiB0aGlzIENvbnRlbnREaXNwb3NpdGlvbi4gUmV0dXJucyBhbiBlbXB0eSBzdHJpbmcgaWYKKyAgICAgKiB0aGUgY29udmVyc2lvbiBmYWlsZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCVJGQzIwNDUgc3R5bGUgc3RyaW5nCisgICAgICogQHNpbmNlCQlKYXZhTWFpbCAxLjIKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkKKworCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKzcuIEFkZCBUcmFuc3BvcnQuc2VuZChtc2csIHVzZXJuYW1lLCBwYXNzd29yZCkgbWV0aG9kICg0NCkKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworSXQncyBub3cgdmVyeSBjb21tb24gdGhhdCBlbWFpbCBzZXJ2ZXJzIHJlcXVpcmUgYXV0aGVudGljYXRpb24gYmVmb3JlCitzZW5kaW5nIGEgbWVzc2FnZSwgc28gd2UgYWRkIHRoZXNlIG5ldyBjb252ZW5pZW5jZSBtZXRob2RzLgorCisgICAgLyoqCisgICAgICogU2VuZCBhIG1lc3NhZ2UuICBUaGUgbWVzc2FnZSB3aWxsIGJlIHNlbnQgdG8gYWxsIHJlY2lwaWVudAorICAgICAqIGFkZHJlc3NlcyBzcGVjaWZpZWQgaW4gdGhlIG1lc3NhZ2UgKGFzIHJldHVybmVkIGZyb20gdGhlCisgICAgICogPGNvZGU+TWVzc2FnZTwvY29kZT4gbWV0aG9kIDxjb2RlPmdldEFsbFJlY2lwaWVudHM8L2NvZGU+KS4KKyAgICAgKiBUaGUgPGNvZGU+c2VuZDwvY29kZT4gbWV0aG9kIGNhbGxzIHRoZSA8Y29kZT5zYXZlQ2hhbmdlczwvY29kZT4KKyAgICAgKiBtZXRob2Qgb24gdGhlIG1lc3NhZ2UgYmVmb3JlIHNlbmRpbmcgaXQuIDxwPgorICAgICAqCisgICAgICogVXNlIHRoZSBzcGVjaWZpZWQgdXNlciBuYW1lIGFuZCBwYXNzd29yZCB0byBhdXRoZW50aWNhdGUgdG8KKyAgICAgKiB0aGUgbWFpbCBzZXJ2ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0JbXNnCXRoZSBtZXNzYWdlIHRvIHNlbmQKKyAgICAgKiBAcGFyYW0JdXNlcgl0aGUgdXNlciBuYW1lCisgICAgICogQHBhcmFtCXBhc3N3b3JkIHRoaXMgdXNlcidzIHBhc3N3b3JkCisgICAgICogQGV4Y2VwdGlvbglTZW5kRmFpbGVkRXhjZXB0aW9uIGlmIHRoZSBtZXNzYWdlIGNvdWxkIG5vdAorICAgICAqCQkJYmUgc2VudCB0byBzb21lIG9yIGFueSBvZiB0aGUgcmVjaXBpZW50cy4KKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbgorICAgICAqIEBzZWUJCU1lc3NhZ2Ujc2F2ZUNoYW5nZXMKKyAgICAgKiBAc2VlICAgICAgICAgICAgICNzZW5kKE1lc3NhZ2UpCisgICAgICogQHNlZQkJamF2YXgubWFpbC5TZW5kRmFpbGVkRXhjZXB0aW9uCisgICAgICogQHNpbmNlCQlKYXZhTWFpbCAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2VuZChNZXNzYWdlIG1zZywKKwkJU3RyaW5nIHVzZXIsIFN0cmluZyBwYXNzd29yZCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbgorCisgICAgLyoqCisgICAgICogU2VuZCB0aGUgbWVzc2FnZSB0byB0aGUgc3BlY2lmaWVkIGFkZHJlc3NlcywgaWdub3JpbmcgYW55CisgICAgICogcmVjaXBpZW50cyBzcGVjaWZpZWQgaW4gdGhlIG1lc3NhZ2UgaXRzZWxmLiBUaGUKKyAgICAgKiA8Y29kZT5zZW5kPC9jb2RlPiBtZXRob2QgY2FsbHMgdGhlIDxjb2RlPnNhdmVDaGFuZ2VzPC9jb2RlPgorICAgICAqIG1ldGhvZCBvbiB0aGUgbWVzc2FnZSBiZWZvcmUgc2VuZGluZyBpdC4gPHA+CisgICAgICoKKyAgICAgKiBVc2UgdGhlIHNwZWNpZmllZCB1c2VyIG5hbWUgYW5kIHBhc3N3b3JkIHRvIGF1dGhlbnRpY2F0ZSB0bworICAgICAqIHRoZSBtYWlsIHNlcnZlci4KKyAgICAgKgorICAgICAqIEBwYXJhbQltc2cJdGhlIG1lc3NhZ2UgdG8gc2VuZAorICAgICAqIEBwYXJhbQlhZGRyZXNzZXMgdGhlIGFkZHJlc3NlcyB0byB3aGljaCB0byBzZW5kIHRoZSBtZXNzYWdlCisgICAgICogQHBhcmFtCXVzZXIJdGhlIHVzZXIgbmFtZQorICAgICAqIEBwYXJhbQlwYXNzd29yZCB0aGlzIHVzZXIncyBwYXNzd29yZAorICAgICAqIEBleGNlcHRpb24JU2VuZEZhaWxlZEV4Y2VwdGlvbiBpZiB0aGUgbWVzc2FnZSBjb3VsZCBub3QKKyAgICAgKgkJCWJlIHNlbnQgdG8gc29tZSBvciBhbnkgb2YgdGhlIHJlY2lwaWVudHMuCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24KKyAgICAgKiBAc2VlCQlNZXNzYWdlI3NhdmVDaGFuZ2VzCisgICAgICogQHNlZSAgICAgICAgICAgICAjc2VuZChNZXNzYWdlKQorICAgICAqIEBzZWUJCWphdmF4Lm1haWwuU2VuZEZhaWxlZEV4Y2VwdGlvbgorICAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHNlbmQoTWVzc2FnZSBtc2csIEFkZHJlc3NbXSBhZGRyZXNzZXMsCisJCVN0cmluZyB1c2VyLCBTdHJpbmcgcGFzc3dvcmQpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24KKworCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKzguIEFkZCBNaW1lTWVzc2FnZS5zZXRGcm9tKFN0cmluZykgbWV0aG9kICg0NSkKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworVGhpcyBuZXcgY29udmVuaWVuY2UgbWV0aG9kIGFsbG93cyB0aGUgRnJvbSBoZWFkZXIgdG8gYmUgc2V0IHVzaW5nIGEgU3RyaW5nLgorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBSRkMgODIyICJGcm9tIiBoZWFkZXIgZmllbGQuIEFueSBleGlzdGluZyB2YWx1ZXMgYXJlIAorICAgICAqIHJlcGxhY2VkIHdpdGggdGhlIGdpdmVuIGFkZHJlc3Nlcy4gSWYgYWRkcmVzcyBpcyA8Y29kZT5udWxsPC9jb2RlPiwKKyAgICAgKiB0aGlzIGhlYWRlciBpcyByZW1vdmVkLgorICAgICAqCisgICAgICogQHBhcmFtIGFkZHJlc3MJdGhlIHNlbmRlcihzKSBvZiB0aGlzIG1lc3NhZ2UKKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxXcml0ZUV4Y2VwdGlvbiBpZiB0aGUgdW5kZXJseWluZworICAgICAqCQkJaW1wbGVtZW50YXRpb24gZG9lcyBub3Qgc3VwcG9ydCBtb2RpZmljYXRpb24KKyAgICAgKgkJCW9mIGV4aXN0aW5nIHZhbHVlcworICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgbWVzc2FnZSBpcworICAgICAqCQkJb2J0YWluZWQgZnJvbSBhIFJFQURfT05MWSBmb2xkZXIuCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24KKyAgICAgKiBAc2luY2UJCUp2YU1haWwgMS41CisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RnJvbShTdHJpbmcgYWRkcmVzcykgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbgorCisKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworOS4gQWRkIE1lc3NhZ2UuZ2V0U2Vzc3Npb24oKSBtZXRob2QgKDQ2KQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitBbG93IGFjY2VzcyB0byB0aGUgU2Vzc2lvbiB1c2VkIHdoZW4gdGhlIE1lc3NhZ2Ugd2FzIGNyZWF0ZWQuCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIFNlc3Npb24gdXNlZCB3aGVuIHRoaXMgbWVzc2FnZSB3YXMgY3JlYXRlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4JCXRoZSBtZXNzYWdlJ3MgU2Vzc2lvbgorICAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS41CisgICAgICovCisgICAgcHVibGljIFNlc3Npb24gZ2V0U2Vzc2lvbigpCisKKworPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisxMC4gTWltZUJvZHlQYXJ0LmF0dGFjaEZpbGUgc2hvdWxkIHNldCB0aGUgZGlzcG9zaXRpb24gdG8gQVRUQUNITUVOVCAoNDcpCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0FuIG92ZXJzaWdodCB3aGVuIHRoZXNlIG1ldGhvZHMgd2VyZSBvcmlnaW5hbGx5IGFkZGVkLiAgQ2xlYXJseSBhdHRhY2htZW50cworc2hvdWxkIHNldCB0aGUgZGlzcG9zaXRpb24gdG8gQVRUQUNITUVOVC4KKworICAgIC8qKgorICAgICAqIFVzZSB0aGUgc3BlY2lmaWVkIGZpbGUgdG8gcHJvdmlkZSB0aGUgZGF0YSBmb3IgdGhpcyBwYXJ0LgorICAgICAqIFRoZSBzaW1wbGUgZmlsZSBuYW1lIGlzIHVzZWQgYXMgdGhlIGZpbGUgbmFtZSBmb3IgdGhpcworICAgICAqIHBhcnQgYW5kIHRoZSBkYXRhIGluIHRoZSBmaWxlIGlzIHVzZWQgYXMgdGhlIGRhdGEgZm9yIHRoaXMKKyAgICAgKiBwYXJ0LiAgVGhlIGVuY29kaW5nIHdpbGwgYmUgY2hvc2VuIGFwcHJvcHJpYXRlbHkgZm9yIHRoZQorICAgICAqIGZpbGUgZGF0YS4gIFRoZSBkaXNwb3NpdGlvbiBvZiB0aGlzIHBhcnQgaXMgc2V0IHRvCisgICAgICoge0BsaW5rIFBhcnQjQVRUQUNITUVOVCBQYXJ0LkFUVEFDSE1FTlR9LgorICAgICAqCisgICAgICogQHBhcmFtCQlmaWxlCQl0aGUgRmlsZSBvYmplY3QgdG8gYXR0YWNoCisgICAgICogQGV4Y2VwdGlvbglJT0V4Y2VwdGlvbgllcnJvcnMgcmVsYXRlZCB0byBhY2Nlc3NpbmcgdGhlIGZpbGUKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbgltZXNzYWdlIHJlbGF0ZWQgZXJyb3JzCisgICAgICogQHNpbmNlCQlKYXZhTWFpbCAxLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhdHRhY2hGaWxlKEZpbGUgZmlsZSkgdGhyb3dzIElPRXhjZXB0aW9uLCBNZXNzYWdpbmdFeGNlcHRpb24KKworICAgIC8qKgorICAgICAqIFVzZSB0aGUgc3BlY2lmaWVkIGZpbGUgdG8gcHJvdmlkZSB0aGUgZGF0YSBmb3IgdGhpcyBwYXJ0LgorICAgICAqIFRoZSBzaW1wbGUgZmlsZSBuYW1lIGlzIHVzZWQgYXMgdGhlIGZpbGUgbmFtZSBmb3IgdGhpcworICAgICAqIHBhcnQgYW5kIHRoZSBkYXRhIGluIHRoZSBmaWxlIGlzIHVzZWQgYXMgdGhlIGRhdGEgZm9yIHRoaXMKKyAgICAgKiBwYXJ0LiAgVGhlIGVuY29kaW5nIHdpbGwgYmUgY2hvc2VuIGFwcHJvcHJpYXRlbHkgZm9yIHRoZQorICAgICAqIGZpbGUgZGF0YS4KKyAgICAgKgorICAgICAqIEBwYXJhbQkJZmlsZQkJdGhlIG5hbWUgb2YgdGhlIGZpbGUgdG8gYXR0YWNoCisgICAgICogQGV4Y2VwdGlvbglJT0V4Y2VwdGlvbgllcnJvcnMgcmVsYXRlZCB0byBhY2Nlc3NpbmcgdGhlIGZpbGUKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbgltZXNzYWdlIHJlbGF0ZWQgZXJyb3JzCisgICAgICogQHNpbmNlCQlKYXZhTWFpbCAxLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhdHRhY2hGaWxlKFN0cmluZyBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24sIE1lc3NhZ2luZ0V4Y2VwdGlvbgorCisKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworMTEuIEFkZCBNaW1lTWVzc2FnZS5yZXBseShyZXBseVRvQWxsLCBzZXRBbnN3ZXJlZCkgbWV0aG9kICg0OCkKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0FkZCBhIG1ldGhvZCB0byBjb250cm9sIHdoZXRoZXIgdGhlIEFOU1dFUkVEIGZsYWcgaXMgc2V0IGluIHRoZSBvcmlnaW5hbAorbWVzc2FnZSB3aGVuIGNyZWF0aW5nIGEgcmVwbHkgbWVzc2FnZS4KKworICAgIC8qKgorICAgICAqIEdldCBhIG5ldyBNZXNzYWdlIHN1aXRhYmxlIGZvciBhIHJlcGx5IHRvIHRoaXMgbWVzc2FnZS4KKyAgICAgKiBUaGUgbmV3IE1lc3NhZ2Ugd2lsbCBoYXZlIGl0cyBhdHRyaWJ1dGVzIGFuZCBoZWFkZXJzIAorICAgICAqIHNldCB1cCBhcHByb3ByaWF0ZWx5LiAgTm90ZSB0aGF0IHRoaXMgbmV3IG1lc3NhZ2Ugb2JqZWN0CisgICAgICogd2lsbCBiZSBlbXB0eSwgaS5lLiwgaXQgd2lsbCA8c3Ryb25nPm5vdDwvc3Ryb25nPiBoYXZlIGEgImNvbnRlbnQiLgorICAgICAqIFRoZXNlIHdpbGwgaGF2ZSB0byBiZSBzdWl0YWJseSBmaWxsZWQgaW4gYnkgdGhlIGNsaWVudC4gPHA+CisgICAgICoKKyAgICAgKiBJZiA8Y29kZT5yZXBseVRvQWxsPC9jb2RlPiBpcyBzZXQsIHRoZSBuZXcgTWVzc2FnZSB3aWxsIGJlIGFkZHJlc3NlZAorICAgICAqIHRvIGFsbCByZWNpcGllbnRzIG9mIHRoaXMgbWVzc2FnZS4gIE90aGVyd2lzZSwgdGhlIHJlcGx5IHdpbGwgYmUKKyAgICAgKiBhZGRyZXNzZWQgdG8gb25seSB0aGUgc2VuZGVyIG9mIHRoaXMgbWVzc2FnZSAodXNpbmcgdGhlIHZhbHVlCisgICAgICogb2YgdGhlIDxjb2RlPmdldFJlcGx5VG88L2NvZGU+IG1ldGhvZCkuICA8cD4KKyAgICAgKgorICAgICAqIElmIDxjb2RlPnNldEFuc3dlcmVkPC9jb2RlPiBpcyBzZXQsIHRoZQorICAgICAqIHtAbGluayBqYXZheC5tYWlsLkZsYWdzLkZsYWcjQU5TV0VSRUQgQU5TV0VSRUR9IGZsYWcgaXMgc2V0CisgICAgICogaW4gdGhpcyBtZXNzYWdlLiA8cD4KKyAgICAgKgorICAgICAqIFRoZSAiU3ViamVjdCIgZmllbGQgaXMgZmlsbGVkIGluIHdpdGggdGhlIG9yaWdpbmFsIHN1YmplY3QKKyAgICAgKiBwcmVmaXhlZCB3aXRoICJSZToiICh1bmxlc3MgaXQgYWxyZWFkeSBzdGFydHMgd2l0aCAiUmU6IikuCisgICAgICogVGhlICJJbi1SZXBseS1UbyIgaGVhZGVyIGlzIHNldCBpbiB0aGUgbmV3IG1lc3NhZ2UgaWYgdGhpcworICAgICAqIG1lc3NhZ2UgaGFzIGEgIk1lc3NhZ2UtSWQiIGhlYWRlci4KKyAgICAgKgorICAgICAqIFRoZSBjdXJyZW50IGltcGxlbWVudGF0aW9uIGFsc28gc2V0cyB0aGUgIlJlZmVyZW5jZXMiIGhlYWRlcgorICAgICAqIGluIHRoZSBuZXcgbWVzc2FnZSB0byBpbmNsdWRlIHRoZSBjb250ZW50cyBvZiB0aGUgIlJlZmVyZW5jZXMiCisgICAgICogaGVhZGVyIChvciwgaWYgbWlzc2luZywgdGhlICJJbi1SZXBseS1UbyIgaGVhZGVyKSBpbiB0aGlzIG1lc3NhZ2UsCisgICAgICogcGx1cyB0aGUgY29udGVudHMgb2YgdGhlICJNZXNzYWdlLUlkIiBoZWFkZXIgb2YgdGhpcyBtZXNzYWdlLAorICAgICAqIGFzIGRlc2NyaWJlZCBpbiBSRkMgMjgyMi4KKyAgICAgKgorICAgICAqIEBwYXJhbQlyZXBseVRvQWxsCXJlcGx5IHNob3VsZCBiZSBzZW50IHRvIGFsbCByZWNpcGllbnRzCisgICAgICoJCQkJb2YgdGhpcyBtZXNzYWdlCisgICAgICogQHBhcmFtCXNldEFuc3dlcmVkCXNldCB0aGUgQU5TV0VSRUQgZmxhZyBpbiB0aGlzIG1lc3NhZ2U/CisgICAgICogQHJldHVybgkJdGhlIHJlcGx5IE1lc3NhZ2UKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbgorICAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS41CisgICAgICovCisgICAgcHVibGljIE1lc3NhZ2UgcmVwbHkoYm9vbGVhbiByZXBseVRvQWxsLCBib29sZWFuIHNldEFuc3dlcmVkKQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24KKworCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKzEyLiBBZGQgYWRkaXRpb25hbCAibmV4dCIgbWV0aG9kcyB0byBIZWFkZXJUb2tlbml6ZXIgKDQ5KQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK1RoZXNlIGFkZGl0aW9uYWwgIm5leHQiIG1ldGhvZHMgbWFrZSBpdCBlYXNpZXIgdG8gcGFyc2UgaGVhZGVycyB0aGF0IGRvbid0CitvYmV5IHRoZSBNSU1FIHN5bnRheCByZXF1aXJlbWVudHMuCisKKyAgICAvKioKKyAgICAgKiBQYXJzZXMgdGhlIG5leHQgdG9rZW4gZnJvbSB0aGlzIFN0cmluZy4KKyAgICAgKiBJZiBlbmRPZkF0b20gaXMgbm90IE5VTCwgdGhlIHRva2VuIGV4dGVuZHMgdW50aWwgdGhlCisgICAgICogZW5kT2ZBdG9tIGNoYXJhY3RlciBpcyBzZWVuLCBvciB0byB0aGUgZW5kIG9mIHRoZSBoZWFkZXIuCisgICAgICogVGhpcyBtZXRob2QgaXMgdXNlZnVsIHdoZW4gcGFyc2luZyBoZWFkZXJzIHRoYXQgZG9uJ3QKKyAgICAgKiBvYmV5IHRoZSBNSU1FIHNwZWNpZmljYXRpb24sIGUuZy4sIGJ5IGZhaWxpbmcgdG8gcXVvdGUKKyAgICAgKiBwYXJhbWV0ZXIgdmFsdWVzIHRoYXQgY29udGFpbiBzcGFjZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0JZW5kT2ZBdG9tCWlmIG5vdCBOVUwsIGNoYXJhY3RlciBtYXJraW5nIGVuZCBvZiB0b2tlbgorICAgICAqIEByZXR1cm4JCXRoZSBuZXh0IFRva2VuCisgICAgICogQGV4Y2VwdGlvbglQYXJzZUV4Y2VwdGlvbiBpZiB0aGUgcGFyc2UgZmFpbHMKKyAgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuNQorICAgICAqLworICAgIHB1YmxpYyBUb2tlbiBuZXh0KGNoYXIgZW5kT2ZBdG9tKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24KKworICAgIC8qKgorICAgICAqIFBhcnNlcyB0aGUgbmV4dCB0b2tlbiBmcm9tIHRoaXMgU3RyaW5nLgorICAgICAqIGVuZE9mQXRvbSBpcyBoYW5kbGVkIGFzIGFib3ZlLiAgSWYga2VlcEVzY2FwZXMgaXMgdHJ1ZSwKKyAgICAgKiBhbnkgYmFja3NsYXNoIGVzY2FwZXMgYXJlIHByZXNlcnZlZCBpbiB0aGUgcmV0dXJuZWQgc3RyaW5nLgorICAgICAqIFRoaXMgbWV0aG9kIGlzIHVzZWZ1bCB3aGVuIHBhcnNpbmcgaGVhZGVycyB0aGF0IGRvbid0CisgICAgICogb2JleSB0aGUgTUlNRSBzcGVjaWZpY2F0aW9uLCBlLmcuLCBieSBmYWlsaW5nIHRvIGVzY2FwZQorICAgICAqIGJhY2tzbGFzaGVzIGluIHRoZSBmaWxlbmFtZSBwYXJhbWV0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0JZW5kT2ZBdG9tCWlmIG5vdCBOVUwsIGNoYXJhY3RlciBtYXJraW5nIGVuZCBvZiB0b2tlbgorICAgICAqIEBwYXJhbQlrZWVwRXNjYXBlcwlrZWVwIGFsbCBiYWNrc2xhc2hlcyBpbiByZXR1cm5lZCBzdHJpbmc/CisgICAgICogQHJldHVybgkJdGhlIG5leHQgVG9rZW4KKyAgICAgKiBAZXhjZXB0aW9uCVBhcnNlRXhjZXB0aW9uIGlmIHRoZSBwYXJzZSBmYWlscworICAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS41CisgICAgICovCisgICAgcHVibGljIFRva2VuIG5leHQoY2hhciBlbmRPZkF0b20sIGJvb2xlYW4ga2VlcEVzY2FwZXMpCisJCQkJdGhyb3dzIFBhcnNlRXhjZXB0aW9uCisKKworPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisxMy4gQWRkIEBNYWlsU2Vzc2lvbkRlZmluaXRpb24gYW5kIEBNYWlsU2Vzc2lvbkRlZmluaXRpb25zIGZvciBKYXZhIEVFIDcgKDUxKQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworVGhlc2UgbmV3IGFubm90YXRpb25zIHN1cHBvcnQgY29uZmlndXJpbmcgSmF2YU1haWwgU2Vzc2lvbiByZXNvdXJjZXMgaW4KK0phdmEgRUUgNyBhcHBsaWNhdGlvbiBzZXJ2ZXJzLgorCitqYXZheC5tYWlsLk1haWxTZXNzaW9uRGVmaW5pdGlvbjoKKworLyoqCisgKiBBbm5vdGF0aW9uIHVzZWQgYnkgSmF2YSBFRSBhcHBsaWNhdGlvbnMgdG8gZGVmaW5lIGEgPGNvZGU+TWFpbFNlc3Npb248L2NvZGU+CisgKiB0byBiZSByZWdpc3RlcmVkIHdpdGggSk5ESS4gIFRoZSA8Y29kZT5NYWlsU2Vzc2lvbjwvY29kZT4gbWF5IGJlIGNvbmZpZ3VyZWQKKyAqIGJ5IHNldHRpbmcgdGhlIGFubm90YXRpb24gZWxlbWVudHMgZm9yIGNvbW1vbmx5IHVzZWQgPGNvZGU+U2Vzc2lvbjwvY29kZT4KKyAqIHByb3BlcnRpZXMuICBBZGRpdGlvbmFsIHN0YW5kYXJkIGFuZCB2ZW5kb3Itc3BlY2lmaWMgcHJvcGVydGllcyBtYXkgYmUKKyAqIHNwZWNpZmllZCB1c2luZyB0aGUgPGNvZGU+cHJvcGVydGllczwvY29kZT4gZWxlbWVudC4KKyAqIDxwLz4KKyAqIFRoZSBzZXNzaW9uIHdpbGwgYmUgcmVnaXN0ZXJlZCB1bmRlciB0aGUgbmFtZSBzcGVjaWZpZWQgaW4gdGhlCisgKiA8Y29kZT5uYW1lPC9jb2RlPiBlbGVtZW50LiAgSXQgbWF5IGJlIGRlZmluZWQgdG8gYmUgaW4gYW55IHZhbGlkCisgKiA8Y29kZT5KYXZhIEVFPC9jb2RlPiBuYW1lc3BhY2UsIGFuZCB3aWxsIGRldGVybWluZSB0aGUgYWNjZXNzaWJpbGl0eSBvZgorICogdGhlIHNlc3Npb24gZnJvbSBvdGhlciBjb21wb25lbnRzLgorICoKKyAqIEBzaW5jZSBKYXZhTWFpbCAxLjUKKyAqLworQFRhcmdldCh7RWxlbWVudFR5cGUuVFlQRX0pCitAUmV0ZW50aW9uKFJldGVudGlvblBvbGljeS5SVU5USU1FKQorcHVibGljIEBpbnRlcmZhY2UgTWFpbFNlc3Npb25EZWZpbml0aW9uIHsKKworICAgIC8qKgorICAgICAqIERlc2NyaXB0aW9uIG9mIHRoaXMgbWFpbCBzZXNzaW9uLgorICAgICAqLworICAgIFN0cmluZyBkZXNjcmlwdGlvbigpIGRlZmF1bHQgIiI7CisKKyAgICAvKioKKyAgICAgKiBKTkRJIG5hbWUgYnkgd2hpY2ggdGhlIG1haWwgc2Vzc2lvbiB3aWxsIGJlIHJlZ2lzdGVyZWQuCisgICAgICovCisgICAgU3RyaW5nIG5hbWUoKTsKKworICAgIC8qKgorICAgICAqIFN0b3JlIHByb3RvY29sIG5hbWUuCisgICAgICovCisgICAgU3RyaW5nIHN0b3JlUHJvdG9jb2woKSBkZWZhdWx0ICIiOworCisgICAgLyoqCisgICAgICogVHJhbnNwb3J0IHByb3RvY29sIG5hbWUuCisgICAgICovCisgICAgU3RyaW5nIHRyYW5zcG9ydFByb3RvY29sKCkgZGVmYXVsdCAiIjsKKworICAgIC8qKgorICAgICAqIEhvc3QgbmFtZSBmb3IgdGhlIG1haWwgc2VydmVyLgorICAgICAqLworICAgIFN0cmluZyBob3N0KCkgZGVmYXVsdCAiIjsKKworICAgIC8qKgorICAgICAqIFVzZXIgbmFtZSB0byB1c2UgZm9yIGF1dGhlbnRpY2F0aW9uLgorICAgICAqLworICAgIFN0cmluZyB1c2VyKCkgZGVmYXVsdCAiIjsKKworICAgIC8qKgorICAgICAqIFBhc3N3b3JkIHRvIHVzZSBmb3IgYXV0aGVudGljYXRpb24uCisgICAgICovCisgICAgU3RyaW5nIHBhc3N3b3JkKCkgZGVmYXVsdCAiIjsKKworICAgIC8qKgorICAgICAqIEZyb20gYWRkcmVzcyBmb3IgdGhlIHVzZXIuCisgICAgICovCisgICAgU3RyaW5nIGZyb20oKSBkZWZhdWx0ICIiOworCisgICAgLyoqCisgICAgICogUHJvcGVydGllcyB0byBpbmNsdWRlIGluIHRoZSBTZXNzaW9uLgorICAgICAqIFByb3BlcnRpZXMgYXJlIHNwZWNpZmllZCB1c2luZyB0aGUgZm9ybWF0OgorICAgICAqIDxpPnByb3BlcnR5TmFtZT1wcm9wZXJ0eVZhbHVlPC9pPiB3aXRoIG9uZSBwcm9wZXJ0eSBwZXIgYXJyYXkgZWxlbWVudC4KKyAgICAgKi8KKyAgICBTdHJpbmdbXSBwcm9wZXJ0aWVzKCkgZGVmYXVsdCB7fTsKK30KKworCitqYXZheC5tYWlsLk1haWxTZXNzaW9uRGVmaW5pdGlvbnM6CisKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5UYXJnZXQ7CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uOworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLkVsZW1lbnRUeXBlOworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlJldGVudGlvblBvbGljeTsKKworLyoqCisgKiBEZWNsYXJlcyBvbmUgb3IgbW9yZSA8Y29kZT5NYWlsU2Vzc2lvbkRlZmluaXRpb248L2NvZGU+IGFubm90YXRpb25zLgorICoKKyAqIEBzZWUgTWFpbFNlc3Npb25EZWZpbml0aW9uCisgKiBAc2luY2UgSmF2YU1haWwgMS41CisgKi8KK0BUYXJnZXQoe0VsZW1lbnRUeXBlLlRZUEV9KQorQFJldGVudGlvbihSZXRlbnRpb25Qb2xpY3kuUlVOVElNRSkKK3B1YmxpYyBAaW50ZXJmYWNlIE1haWxTZXNzaW9uRGVmaW5pdGlvbnMgeworICAgIE1haWxTZXNzaW9uRGVmaW5pdGlvbltdIHZhbHVlKCk7Cit9CisKKworPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisxNC4gTWFrZSBjYWNoZWRDb250ZW50IGZpZWxkIHByb3RlY3RlZCBpbiBNaW1lTWVzc2FnZSBhbmQgTWltZUJvZHlQYXJ0ICg1MikKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitFeHBvc2luZyB0aGlzIHByZXZpb3VzbHkgcHJpdmF0ZSBmaWVsZCBtYWtlcyBpdCBlYXNpZXIgdG8gc3ViY2xhc3MgdGhlc2UKK2NsYXNzZXMuCisKKyAgICAvKioKKyAgICAgKiBJZiBvdXIgY29udGVudCBpcyBhIE11bHRpcGFydCBvciBNZXNzYWdlIG9iamVjdCwgd2Ugc2F2ZSBpdAorICAgICAqIHRoZSBmaXJzdCB0aW1lIGl0J3MgY3JlYXRlZCBieSBwYXJzaW5nIGEgc3RyZWFtIHNvIHRoYXQgY2hhbmdlcworICAgICAqIHRvIHRoZSBjb250YWluZWQgb2JqZWN0cyB3aWxsIG5vdCBiZSBsb3N0LiA8cD4KKyAgICAgKgorICAgICAqIElmIHRoaXMgZmllbGQgaXMgbm90IG51bGwsIGl0J3MgcmV0dXJuIGJ5IHRoZSB7QGxpbmsgI2dldENvbnRlbnR9CisgICAgICogbWV0aG9kLiAgVGhlIHtAbGluayAjZ2V0Q29udGVudH0gbWV0aG9kIHNldHMgdGhpcyBmaWVsZCBpZiBpdAorICAgICAqIHdvdWxkIHJldHVybiBhIE11bHRpcGFydCBvciBNaW1lTWVzc2FnZSBvYmplY3QuICBUaGlzIGZpZWxkIGlzCisgICAgICogaXMgY2xlYXJlZCBieSB0aGUge0BsaW5rICNzZXREYXRhSGFuZGxlcn0gbWV0aG9kLgorICAgICAqCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNQorICAgICAqLworICAgIHByb3RlY3RlZCBPYmplY3QgY2FjaGVkQ29udGVudDsKKworCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKzE1LiBNYWtlIE1pbWVNdWx0aXBhcnQgZmllbGRzIHByb3RlY3RlZCB0byBhbGxvdyBzdWJjbGFzc2luZyAoNTMpCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitNb3N0IG9mIHRoZXNlIGZpZWxkcyBjb250cm9sIGhvdyB0aGUgTWltZU11bHRpcGFydCBjbGFzcyBwYXJzZXMgbWVzc2FnZXMKK3RoYXQgZG9uJ3QgY29uZm9ybSB0byB0aGUgTUlNRSBzcGVjLiAgVGhlIG5ldyBpbml0aWFsaXplUHJvcGVydGllcyBtZXRob2QKK2luaXRpYWxpemVzIHRoZXNlIGZpZWxkcyBiYXNlZCBvbiBTeXN0ZW0gcHJvcGVydGllcy4gIEV4cG9zaW5nIHRoZXNlCitwcmV2aW91c2x5IHByaXZhdGUgZmllbGRzIG1ha2VzIGl0IGVhc2llciB0byBzdWJjbGFzcyBNaW1lTXVsdGlwYXJ0LgorCisgICAgLyoqCisgICAgICogSGF2ZSB3ZSBzZWVuIHRoZSBmaW5hbCBib3VuYXJ5IGxpbmU/CisgICAgICoKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS41CisgICAgICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gY29tcGxldGUgPSB0cnVlOworCisgICAgLyoqCisgICAgICogVGhlIE1JTUUgbXVsdGlwYXJ0IHByZWFtYmxlIHRleHQsIHRoZSB0ZXh0IHRoYXQKKyAgICAgKiBvY2N1cnMgYmVmb3JlIHRoZSBmaXJzdCBib3VuZGFyeSBsaW5lLgorICAgICAqCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNQorICAgICAqLworICAgIHByb3RlY3RlZCBTdHJpbmcgcHJlYW1ibGUgPSBudWxsOworCisgICAgLyoqCisgICAgICogRmxhZyBjb3JyZXNwb25kaW5nIHRvIHRoZSAibWFpbC5taW1lLm11bHRpcGFydC5pZ25vcmVtaXNzaW5nZW5kYm91bmRhcnkiCisgICAgICogcHJvcGVydHksIHNldCBpbiB0aGUge0BsaW5rICNpbml0aWFsaXplUHJvcGVydGllc30gbWV0aG9kIGNhbGxlZCBmcm9tCisgICAgICogY29uc3RydWN0b3JzIGFuZCB0aGUgcGFyc2UgbWV0aG9kLgorICAgICAqCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNQorICAgICAqLworICAgIHByb3RlY3RlZCBib29sZWFuIGlnbm9yZU1pc3NpbmdFbmRCb3VuZGFyeSA9IHRydWU7CisKKyAgICAvKioKKyAgICAgKiBGbGFnIGNvcnJlc3BvbmRpbmcgdG8gdGhlCisgICAgICogIm1haWwubWltZS5tdWx0aXBhcnQuaWdub3JlbWlzc2luZ2JvdW5kYXJ5cGFyYW1ldGVyIgorICAgICAqIHByb3BlcnR5LCBzZXQgaW4gdGhlIHtAbGluayAjaW5pdGlhbGl6ZVByb3BlcnRpZXN9IG1ldGhvZCBjYWxsZWQgZnJvbQorICAgICAqIGNvbnN0cnVjdG9ycyBhbmQgdGhlIHBhcnNlIG1ldGhvZC4KKyAgICAgKgorICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjUKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpZ25vcmVNaXNzaW5nQm91bmRhcnlQYXJhbWV0ZXIgPSB0cnVlOworCisgICAgLyoqCisgICAgICogRmxhZyBjb3JyZXNwb25kaW5nIHRvIHRoZQorICAgICAqICJtYWlsLm1pbWUubXVsdGlwYXJ0Lmlnbm9yZWV4aXN0aW5nYm91bmRhcnlwYXJhbWV0ZXIiCisgICAgICogcHJvcGVydHksIHNldCBpbiB0aGUge0BsaW5rICNpbml0aWFsaXplUHJvcGVydGllc30gbWV0aG9kIGNhbGxlZCBmcm9tCisgICAgICogY29uc3RydWN0b3JzIGFuZCB0aGUgcGFyc2UgbWV0aG9kLgorICAgICAqCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNQorICAgICAqLworICAgIHByb3RlY3RlZCBib29sZWFuIGlnbm9yZUV4aXN0aW5nQm91bmRhcnlQYXJhbWV0ZXIgPSBmYWxzZTsKKworICAgIC8qKgorICAgICAqIEZsYWcgY29ycmVzcG9uZGluZyB0byB0aGUgIm1haWwubWltZS5tdWx0aXBhcnQuYWxsb3dlbXB0eSIKKyAgICAgKiBwcm9wZXJ0eSwgc2V0IGluIHRoZSB7QGxpbmsgI2luaXRpYWxpemVQcm9wZXJ0aWVzfSBtZXRob2QgY2FsbGVkIGZyb20KKyAgICAgKiBjb25zdHJ1Y3RvcnMgYW5kIHRoZSBwYXJzZSBtZXRob2QuCisgICAgICoKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS41CisgICAgICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gYWxsb3dFbXB0eSA9IGZhbHNlOworCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZSBmbGFncyB0aGF0IGNvbnRyb2wgcGFyc2luZyBiZWhhdmlvciwKKyAgICAgKiBiYXNlZCBvbiBTeXN0ZW0gcHJvcGVydGllcyBkZXNjcmliZWQgYWJvdmUgaW4KKyAgICAgKiB0aGUgY2xhc3MgZG9jdW1lbnRhdGlvbi4KKyAgICAgKgorICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjUKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBpbml0aWFsaXplUHJvcGVydGllcygpCisKK1RoZSBmb2xsb3dpbmcgYWRkaXRpb25hbCBTeXN0ZW0gcHJvcGVydGllcyBhcmUgZGVmaW5lZCBjb3JyZXNwb25kaW5nIHRvCit0aGUgbGFzdCB0d28gZmllbGRzIGFib3ZlOgorCittYWlsLm1pbWUubXVsdGlwYXJ0Lmlnbm9yZWV4aXN0aW5nYm91bmRhcnlwYXJhbWV0ZXI6CisKKyAgTm9ybWFsbHkgdGhlIGJvdW5kYXJ5IHBhcmFtZXRlciBpbiB0aGUgQ29udGVudC1UeXBlIGhlYWRlciBvZiBhIG11bHRpcGFydAorICBib2R5IHBhcnQgaXMgdXNlZCB0byBzcGVjaWZ5IHRoZSBzZXBhcmF0b3IgYmV0d2VlbiBwYXJ0cyBvZiB0aGUgbXVsdGlwYXJ0CisgIGJvZHkuICBUaGlzIFN5c3RlbSBwcm9wZXJ0eSBtYXkgYmUgc2V0IHRvIDxjb2RlPiJ0cnVlIjwvY29kZT4gdG8gY2F1c2UKKyAgdGhlIHBhcnNlciB0byBsb29rIGZvciBhIGxpbmUgaW4gdGhlIG11bHRpcGFydCBib2R5IHRoYXQgbG9va3MgbGlrZSBhCisgIGJvdW5kYXJ5IGxpbmUgYW5kIHVzZSB0aGF0IHZhbHVlIGFzIHRoZSBzZXBhcmF0b3IgYmV0d2VlbiBzdWJzZXF1ZW50IHBhcnRzLgorICBUaGlzIG1heSBiZSB1c2VmdWwgaW4gY2FzZXMgd2hlcmUgYSBicm9rZW4gYW50aS12aXJ1cyBwcm9kdWN0IGhhcyByZXdyaXR0ZW4KKyAgdGhlIG1lc3NhZ2UgaW5jb3JyZWN0bHkgc3VjaCB0aGF0IHRoZSBib3VuZGFyeSBwYXJhbWV0ZXIgYW5kIHRoZSBhY3R1YWwKKyAgYm91bmRhcnkgdmFsdWUgbm8gbG9uZ2VyIG1hdGNoLgorICBUaGUgZGVmYXVsdCB2YWx1ZSBvZiB0aGlzIHByb3BlcnR5IGlzIGZhbHNlLgorCittYWlsLm1pbWUubXVsdGlwYXJ0LmFsbG93ZW1wdHk6CisKKyAgTm9ybWFsbHksIHdoZW4gd3JpdGluZyBvdXQgYSBNaW1lTXVsdGlwYXJ0IHRoYXQgY29udGFpbnMgbm8gYm9keQorICBwYXJ0cywgb3Igd2hlbiB0cnlpbmcgdG8gcGFyc2UgYSBtdWx0aXBhcnQgbWVzc2FnZSB3aXRoIG5vIGJvZHkgcGFydHMsCisgIGEgPGNvZGU+TWVzc2FnaW5nRXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24uICBUaGUgTUlNRSBzcGVjIGRvZXMgbm90IGFsbG93CisgIG11bHRpcGFydCBjb250ZW50IHdpdGggbm8gYm9keSBwYXJ0cy4gIFRoaXMKKyAgU3lzdGVtIHByb3BlcnR5IG1heSBiZSBzZXQgdG8gPGNvZGU+InRydWUiPC9jb2RlPiB0byBvdmVycmlkZSB0aGlzIGJlaGF2aW9yLgorICBXaGVuIHdyaXRpbmcgb3V0IHN1Y2ggYSBNaW1lTXVsdGlwYXJ0LCBhIHNpbmdsZSBlbXB0eSBwYXJ0IHdpbGwgYmUKKyAgaW5jbHVkZWQuICBXaGVuIHJlYWRpbmcgc3VjaCBhIG11bHRpcGFydCwgYSBNaW1lTXVsdGlwYXJ0IHdpbGwgYmUgY3JlYXRlZAorICB3aXRoIG5vIGJvZHkgcGFydHMuCisgIFRoZSBkZWZhdWx0IHZhbHVlIG9mIHRoaXMgcHJvcGVydHkgaXMgZmFsc2UuCisKKworPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisxNi4gTmVlZCBzaW1wbGUgd2F5IHRvIG92ZXJyaWRlIE1JTUUgdHlwZSBhbmQgZW5jb2Rpbmcgb2YgYXR0YWNobWVudCAoNTUpCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0ZpcnN0LCB3ZSBkZWZpbmUgYW4gaW50ZXJmYWNlIHRoYXQgYWxsb3dzIGEgRGF0YVNvdXJjZSB0byBzcGVjaWZ5IHRoZQorQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZyB0byB1c2U6CisKK3BhY2thZ2UgamF2YXgubWFpbDsKKworLyoqCisgKiBBIHtAbGluayBqYXZheC5hY3RpdmF0aW9uLkRhdGFTb3VyY2UgRGF0YVNvdXJjZX0gdGhhdCBhbHNvIGltcGxlbWVudHMKKyAqIDxjb2RlPkVuY29kaW5nQXdhcmU8L2NvZGU+IG1heSBzcGVjaWZ5IHRoZSBDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nCisgKiB0byB1c2UgZm9yIGl0cyBkYXRhLiAgVmFsaWQgQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZyB2YWx1ZXMgc3BlY2lmaWVkCisgKiBieSBSRkMgMjA0NSBhcmUgIjdiaXQiLCAiOGJpdCIsICJxdW90ZWQtcHJpbnRhYmxlIiwgImJhc2U2NCIsIGFuZCAiYmluYXJ5Ii4KKyAqIDxwPgorICogRm9yIGV4YW1wbGUsIGEge0BsaW5rIGphdmF4LmFjdGl2YXRpb24uRmlsZURhdGFTb3VyY2UgRmlsZURhdGFTb3VyY2V9CisgKiBjb3VsZCBiZSBjcmVhdGVkIHRoYXQgZm9yY2VzIGFsbCBmaWxlcyB0byBiZSBiYXNlNjQgZW5jb2RlZDogPHA+CisgKiA8YmxvY2txdW90ZT48cHJlPgorICogIHB1YmxpYyBjbGFzcyBCYXNlNjRGaWxlRGF0YVNvdXJjZSBleHRlbmRzIEZpbGVEYXRhU291cmNlCisgKgkJCQkJaW1wbGVtZW50cyBFbmNvZGluZ0F3YXJlIHsKKyAqCXB1YmxpYyBCYXNlNjRGaWxlRGF0YVNvdXJjZShGaWxlIGZpbGUpIHsKKyAqCSAgICBzdXBlcihmaWxlKTsKKyAqCX0KKyAqCisgKgkvLyBpbXBsZW1lbnRzIEVuY29kaW5nQXdhcmUuZ2V0RW5jb2RpbmcoKQorICoJcHVibGljIFN0cmluZyBnZXRFbmNvZGluZygpIHsKKyAqCSAgICByZXR1cm4gImJhc2U2NCI7CisgKgl9CisgKiAgfQorICogPC9wcmU+PC9ibG9ja3F1b3RlPjxwPgorICoKKyAqIEBzaW5jZQlKYXZhTWFpbCAxLjUKKyAqIEBhdXRob3IJQmlsbCBTaGFubm9uCisgKi8KKworcHVibGljIGludGVyZmFjZSBFbmNvZGluZ0F3YXJlIHsKKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgTUlNRSBDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nIHRvIHVzZSBmb3IgdGhpcyBkYXRhLAorICAgICAqIG9yIG51bGwgdG8gaW5kaWNhdGUgdGhhdCBhbiBhcHByb3ByaWF0ZSB2YWx1ZSBzaG91bGQgYmUgY2hvc2VuCisgICAgICogYnkgdGhlIGNhbGxlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4JCXRoZSBDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nIHZhbHVlLCBvciBudWxsCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRFbmNvZGluZygpOworfQorCitUaGVuIHdlIGFkZCBuZXcgbWV0aG9kcyB0byBNaW1lQm9keVBhcnQ6CisKKyAgICAvKioKKyAgICAgKiBVc2UgdGhlIHNwZWNpZmllZCBmaWxlIHdpdGggdGhlIHNwZWNpZmllZCBDb250ZW50LVR5cGUgYW5kCisgICAgICogQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZyB0byBwcm92aWRlIHRoZSBkYXRhIGZvciB0aGlzIHBhcnQuCisgICAgICogSWYgY29udGVudFR5cGUgb3IgZW5jb2RpbmcgYXJlIG51bGwsIGFwcHJvcHJpYXRlIHZhbHVlcyB3aWxsCisgICAgICogYmUgY2hvc2VuLgorICAgICAqIFRoZSBzaW1wbGUgZmlsZSBuYW1lIGlzIHVzZWQgYXMgdGhlIGZpbGUgbmFtZSBmb3IgdGhpcworICAgICAqIHBhcnQgYW5kIHRoZSBkYXRhIGluIHRoZSBmaWxlIGlzIHVzZWQgYXMgdGhlIGRhdGEgZm9yIHRoaXMKKyAgICAgKiBwYXJ0LiAgVGhlIGRpc3Bvc2l0aW9uIG9mIHRoaXMgcGFydCBpcyBzZXQgdG8KKyAgICAgKiB7QGxpbmsgUGFydCNBVFRBQ0hNRU5UIFBhcnQuQVRUQUNITUVOVH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0JCWZpbGUJCXRoZSBGaWxlIG9iamVjdCB0byBhdHRhY2gKKyAgICAgKiBAcGFyYW0JCWNvbnRlbnRUeXBlCXRoZSBDb250ZW50LVR5cGUsIG9yIG51bGwKKyAgICAgKiBAcGFyYW0JCWVuY29kaW5nCXRoZSBDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nLCBvciBudWxsCisgICAgICogQGV4Y2VwdGlvbglJT0V4Y2VwdGlvbgllcnJvcnMgcmVsYXRlZCB0byBhY2Nlc3NpbmcgdGhlIGZpbGUKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbgltZXNzYWdlIHJlbGF0ZWQgZXJyb3JzCisgICAgICogQHNpbmNlCQlKYXZhTWFpbCAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhdHRhY2hGaWxlKEZpbGUgZmlsZSwgU3RyaW5nIGNvbnRlbnRUeXBlLCBTdHJpbmcgZW5jb2RpbmcpCisJCQkJdGhyb3dzIElPRXhjZXB0aW9uLCBNZXNzYWdpbmdFeGNlcHRpb24KKworICAgIC8qKgorICAgICAqIFVzZSB0aGUgc3BlY2lmaWVkIGZpbGUgd2l0aCB0aGUgc3BlY2lmaWVkIENvbnRlbnQtVHlwZSBhbmQKKyAgICAgKiBDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nIHRvIHByb3ZpZGUgdGhlIGRhdGEgZm9yIHRoaXMgcGFydC4KKyAgICAgKiBJZiBjb250ZW50VHlwZSBvciBlbmNvZGluZyBhcmUgbnVsbCwgYXBwcm9wcmlhdGUgdmFsdWVzIHdpbGwKKyAgICAgKiBiZSBjaG9zZW4uCisgICAgICogVGhlIHNpbXBsZSBmaWxlIG5hbWUgaXMgdXNlZCBhcyB0aGUgZmlsZSBuYW1lIGZvciB0aGlzCisgICAgICogcGFydCBhbmQgdGhlIGRhdGEgaW4gdGhlIGZpbGUgaXMgdXNlZCBhcyB0aGUgZGF0YSBmb3IgdGhpcworICAgICAqIHBhcnQuICBUaGUgZGlzcG9zaXRpb24gb2YgdGhpcyBwYXJ0IGlzIHNldCB0bworICAgICAqIHtAbGluayBQYXJ0I0FUVEFDSE1FTlQgUGFydC5BVFRBQ0hNRU5UfS4KKyAgICAgKgorICAgICAqIEBwYXJhbQkJZmlsZQkJdGhlIG5hbWUgb2YgdGhlIGZpbGUKKyAgICAgKiBAcGFyYW0JCWNvbnRlbnRUeXBlCXRoZSBDb250ZW50LVR5cGUsIG9yIG51bGwKKyAgICAgKiBAcGFyYW0JCWVuY29kaW5nCXRoZSBDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nLCBvciBudWxsCisgICAgICogQGV4Y2VwdGlvbglJT0V4Y2VwdGlvbgllcnJvcnMgcmVsYXRlZCB0byBhY2Nlc3NpbmcgdGhlIGZpbGUKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbgltZXNzYWdlIHJlbGF0ZWQgZXJyb3JzCisgICAgICogQHNpbmNlCQlKYXZhTWFpbCAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhdHRhY2hGaWxlKFN0cmluZyBmaWxlLCBTdHJpbmcgY29udGVudFR5cGUsIFN0cmluZyBlbmNvZGluZykKKwkJCQl0aHJvd3MgSU9FeGNlcHRpb24sIE1lc3NhZ2luZ0V4Y2VwdGlvbgorCisKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworMTcuIEVuYWJsZSBSRkMgMjIzMSBzdXBwb3J0IGJ5IGRlZmF1bHQgKDU2KQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitSRkMgMjIzMSBzdXBwb3J0IGZvciBlbmNvZGVkIHBhcmFtZXRlciB2YWx1ZXMgaXMgbm93IHdpZGVseSBpbXBsZW1lbnRlZCwKK2l0J3MgdGltZSB0byBjaGFuZ2UgdGhlIGRlZmF1bHQgdG8gc3VwcG9ydCB0aGlzIHN0YW5kYXJkLiAgR2l2ZW4gdGhlCit3YXkgUkZDIDIyMzEgaXMgZGVmaW5lZCwgaXQncyBleHRyZW1lbHkgdW5saWtlbHkgdGhhdCB0aGlzIHdvdWxkIGNhdXNlCitjb21wYXRpYmlsaXR5IHByb2JsZW1zIHdpdGggZXhpc3RpbmcgYXBwbGljYXRpb25zLgorCitUaGUgU3lzdGVtIHByb3BlcnRpZXMgbWFpbC5taW1lLmRlY29kZXBhcmFtZXRlcnMgYW5kIG1haWwubWltZS5lbmNvZGVwYXJhbWV0ZXJzCitub3cgZGVmYXVsdCB0byB0cnVlIGluc3RlYWQgb2YgZmFsc2UuCmRpZmYgLS1naXQgYS9kb2Mvc3BlYy9KYXZhTWFpbC0xLjYtY2hhbmdlcy50eHQgYi9kb2Mvc3BlYy9KYXZhTWFpbC0xLjYtY2hhbmdlcy50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTY5MDZiNgotLS0gL2Rldi9udWxsCisrKyBiL2RvYy9zcGVjL0phdmFNYWlsLTEuNi1jaGFuZ2VzLnR4dApAQCAtMCwwICsxLDY3NyBAQAorCisJCUphdmFNYWlsIDEuNgorCQk9PT09PT09PT09PT0KKworCQkoVXBkYXRlZCBKdWx5IDE3LCAyMDE3KQorCitGb2xsb3dpbmcgaXMgYSBkZXNjcmlwdGlvbiBvZiB0aGUgY2hhbmdlcyB0byB0aGUgSmF2YU1haWwKK0FQSSBpbnRyb2R1Y2VkIGluIEphdmFNYWlsIDEuNi4gIFRoZSBudW1iZXJzIGluIHBhcmVudGhlc2VzCithcmUgYnVnIG51bWJlcnM7IHlvdSBjYW4gZmluZCBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHRoZQorYnVnIHJlcG9ydHMgYXQ6CisKKyAgICBodHRwczovL2dpdGh1Yi5jb20vamF2YWVlL2phdmFtYWlsL2lzc3Vlcy88YnVnIG51bWJlcj4KKworUGxlYXNlIHNlbmQgY29tbWVudHMgYW5kIGZlZWRiYWNrIHRvIGphdmFtYWlsX3d3QG9yYWNsZS5jb20uCisKK0phdmFNYWlsIDEuNiB3aWxsIGFsc28gcmVxdWlyZSBhdCBsZWFzdCBKYXZhIFNFIDcuCisKKworPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisxLiBNYWlsU2Vzc2lvbkRlZmluaXRpb24gc2hvdWxkIHVzZSBSZXBlYXRhYmxlIGFubm90YXRpb24gZm9yIEphdmEgRUUgOCAoMjI2KQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworVGhlIE1haWxTZXNzaW9uRGVmaW5pdGlvbiBhbm5vdGF0aW9uIG5vdyBpbmNsdWRlcyB0aGUgUmVwZWF0YWJsZSBhbm5vdGF0aW9uOgorCisJQFRhcmdldCh7RWxlbWVudFR5cGUuVFlQRX0pCisJQFJldGVudGlvbihSZXRlbnRpb25Qb2xpY3kuUlVOVElNRSkKKwlAUmVwZWF0YWJsZShNYWlsU2Vzc2lvbkRlZmluaXRpb25zLmNsYXNzKQorCXB1YmxpYyBAaW50ZXJmYWNlIE1haWxTZXNzaW9uRGVmaW5pdGlvbiB7CisJICAgIC4uLgorCX0KKworVGhlIFJlcGVhdGFibGUgYW5ub3RhdGlvbiBpcyBub3Qga25vd24gdG8gSmF2YSBTRSA3IGFuZCB3aWxsIGJlIGlnbm9yZWQKKyhhcyBleHBlY3RlZCkgd2hlbiBKYXZhTWFpbCAxLjYgaXMgdXNlZCBvbiBKYXZhIFNFIDcuCisKKworPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisyLiBNaW1lTWVzc2FnZS51cGRhdGVIZWFkZXJzIHNob3VsZCBzZXQgRGF0ZSBoZWFkZXIgaWYgbm90IGFscmVhZHkgc2V0ICg3NykKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitSRkMgMjgyMiByZXF1aXJlcyBhIERhdGUgaGVhZGVyLiAgVGhlIE1pbWVNZXNzYWdlLnVwZGF0ZUhlYWRlcnMgbWV0aG9kCitub3cgc2V0cyB0aGUgRGF0ZSBoZWFkZXIgaWYgaXQncyBub3QgYWxyZWFkeSBzZXQ6CisKKwkvKioKKwkgKiBDYWxsZWQgYnkgdGhlIDxjb2RlPnNhdmVDaGFuZ2VzPC9jb2RlPiBtZXRob2QgdG8gYWN0dWFsbHkKKwkgKiB1cGRhdGUgdGhlIE1JTUUgaGVhZGVycy4gIFRoZSBpbXBsZW1lbnRhdGlvbiBoZXJlIHNldHMgdGhlCisJICogPGNvZGU+Q29udGVudC1UcmFuc2Zlci1FbmNvZGluZzwvY29kZT4gaGVhZGVyIChpZiBuZWVkZWQKKwkgKiBhbmQgbm90IGFscmVhZHkgc2V0KSwgdGhlIDxjb2RlPkRhdGU8L2NvZGU+IGhlYWRlciAoaWYKKwkgKiBub3QgYWxyZWFkeSBzZXQpLCB0aGUgPGNvZGU+TUlNRS1WZXJzaW9uPC9jb2RlPiBoZWFkZXIKKwkgKiBhbmQgdGhlIDxjb2RlPk1lc3NhZ2UtSUQ8L2NvZGU+IGhlYWRlci4gQWxzbywgaWYgdGhlIGNvbnRlbnQKKwkgKiBvZiB0aGlzIG1lc3NhZ2UgaXMgYSA8Y29kZT5NaW1lTXVsdGlwYXJ0PC9jb2RlPiwgaXRzCisJICogPGNvZGU+dXBkYXRlSGVhZGVyczwvY29kZT4gbWV0aG9kIGlzIGNhbGxlZC4gPHA+CisJICoKKwkgKiBJZiB0aGUge0BsaW5rICNjYWNoZWRDb250ZW50fSBmaWVsZCBpcyBub3QgbnVsbCAodGhhdCBpcywKKwkgKiBpdCByZWZlcmVuY2VzIGEgTXVsdGlwYXJ0IG9yIE1lc3NhZ2Ugb2JqZWN0KSwgdGhlbgorCSAqIHRoYXQgb2JqZWN0IGlzIHVzZWQgdG8gc2V0IGEgbmV3IERhdGFIYW5kbGVyLCBhbnkKKwkgKiBzdHJlYW0gZGF0YSB1c2VkIHRvIGNyZWF0ZSB0aGlzIG9iamVjdCBpcyBkaXNjYXJkZWQsCisJICogYW5kIHRoZSB7QGxpbmsgI2NhY2hlZENvbnRlbnR9IGZpZWxkIGlzIGNsZWFyZWQuCisJICoKKwkgKiBAZXhjZXB0aW9uICAgICAgIElsbGVnYWxXcml0ZUV4Y2VwdGlvbiBpZiB0aGUgdW5kZXJseWluZworCSAqICAgICAgICAgICAgICAgICAgaW1wbGVtZW50YXRpb24gZG9lcyBub3Qgc3VwcG9ydCBtb2RpZmljYXRpb24KKwkgKiBAZXhjZXB0aW9uICAgICAgIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIG1lc3NhZ2UgaXMKKwkgKiAgICAgICAgICAgICAgICAgIG9idGFpbmVkIGZyb20gYSBSRUFEX09OTFkgZm9sZGVyLgorCSAqIEBleGNlcHRpb24gICAgICAgTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBvdGhlciBmYWlsdXJlcworCSAqLworCXByb3RlY3RlZCBzeW5jaHJvbml6ZWQgdm9pZCB1cGRhdGVIZWFkZXJzKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJICAgIC4uLgorCX0KKworCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKzMuIFVwZGF0ZSBwdWJsaWMgQVBJIHRvIHVzZSBnZW5lcmljcyAoMjMyKQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK01ldGhvZHMgb24gdGhlIGZvbGxvd2luZyBBUElzIGhhdmUgYmVlbiB1cGRhdGVkIHRvIHVzZSBnZW5lcmljcword2hlbiBhcHByb3ByaWF0ZToKKworCWphdmF4Lm1haWwuTXVsdGlwYXJ0CisJamF2YXgubWFpbC5QYXJ0CisJamF2YXgubWFpbC5TZXJ2aWNlCisJamF2YXgubWFpbC5pbnRlcm5ldC5JbnRlcm5ldEhlYWRlcnMKKwlqYXZheC5tYWlsLmludGVybmV0Lk1pbWVCb2R5UGFydAorCWphdmF4Lm1haWwuaW50ZXJuZXQuTWltZU1lc3NhZ2UKKwlqYXZheC5tYWlsLmludGVybmV0Lk1pbWVQYXJ0CisJamF2YXgubWFpbC5pbnRlcm5ldC5QYXJhbWV0ZXJMaXN0CisKK0RldGFpbHMgZm9sbG93OgorCitkaWZmIC1yIDFmNmIyYzE3ZTI5MSBtYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9NdWx0aXBhcnQuamF2YQorLSBhL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL011bHRpcGFydC5qYXZhCisrKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9NdWx0aXBhcnQuamF2YQorQEAgLTcyLDIgKzcyLDEgQEAKKy0gICAgQFN1cHByZXNzV2FybmluZ3MoInJhd3R5cGVzIikKKy0gICAgcHJvdGVjdGVkIFZlY3RvciBwYXJ0cyA9IG5ldyBWZWN0b3IoKTsgLy8gSG9sZHMgQm9keVBhcnRzCisrICAgIHByb3RlY3RlZCBWZWN0b3I8Qm9keVBhcnQ+IHBhcnRzID0gbmV3IFZlY3Rvcjw+KCk7IC8vIEhvbGRzIEJvZHlQYXJ0cworZGlmZiAtciAxZjZiMmMxN2UyOTEgbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvUGFydC5qYXZhCistIGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvUGFydC5qYXZhCisrKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9QYXJ0LmphdmEKK0BAIC00NTIsMiArNDUyLDEgQEAKKy0gICAgQFN1cHByZXNzV2FybmluZ3MoInJhd3R5cGVzIikKKy0gICAgcHVibGljIEVudW1lcmF0aW9uIGdldEFsbEhlYWRlcnMoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uOworKyAgICBwdWJsaWMgRW51bWVyYXRpb248SGVhZGVyPiBnZXRBbGxIZWFkZXJzKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbjsKK0BAIC00NjMsMiArNDYyLDEgQEAKKy0gICAgQFN1cHByZXNzV2FybmluZ3MoInJhd3R5cGVzIikKKy0gICAgcHVibGljIEVudW1lcmF0aW9uIGdldE1hdGNoaW5nSGVhZGVycyhTdHJpbmdbXSBoZWFkZXJfbmFtZXMpCisrICAgIHB1YmxpYyBFbnVtZXJhdGlvbjxIZWFkZXI+IGdldE1hdGNoaW5nSGVhZGVycyhTdHJpbmdbXSBoZWFkZXJfbmFtZXMpCitAQCAtNDc1LDIgKzQ3MywxIEBACistICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJyYXd0eXBlcyIpCistICAgIHB1YmxpYyBFbnVtZXJhdGlvbiBnZXROb25NYXRjaGluZ0hlYWRlcnMoU3RyaW5nW10gaGVhZGVyX25hbWVzKSAKKysgICAgcHVibGljIEVudW1lcmF0aW9uPEhlYWRlcj4gZ2V0Tm9uTWF0Y2hpbmdIZWFkZXJzKFN0cmluZ1tdIGhlYWRlcl9uYW1lcykgCitkaWZmIC1yIDFmNmIyYzE3ZTI5MSBtYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9TZXJ2aWNlLmphdmEKKy0gYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9TZXJ2aWNlLmphdmEKKysrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL1NlcnZpY2UuamF2YQorQEAgLTY0MCwyICs2NDAsMiBAQAorLSAgICBAU3VwcHJlc3NXYXJuaW5ncygicmF3dHlwZXMiKQorLSAgICBwcm90ZWN0ZWQgdm9pZCBxdWV1ZUV2ZW50KE1haWxFdmVudCBldmVudCwgVmVjdG9yIHZlY3RvcikgeworKyAgICBwcm90ZWN0ZWQgdm9pZCBxdWV1ZUV2ZW50KE1haWxFdmVudCBldmVudCwKKysJICAgIFZlY3Rvcjw/IGV4dGVuZHMgRXZlbnRMaXN0ZW5lcj4gdmVjdG9yKSB7CitkaWZmIC1yIDFmNmIyYzE3ZTI5MSBtYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9JbnRlcm5ldEhlYWRlcnMuamF2YQorLSBhL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2ludGVybmV0L0ludGVybmV0SGVhZGVycy5qYXZhCisrKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9JbnRlcm5ldEhlYWRlcnMuamF2YQorQEAgLTMwMCwyICszMDAsMSBAQAorLSAgICBAU3VwcHJlc3NXYXJuaW5ncygicmF3dHlwZXMiKQorLSAgICBwcm90ZWN0ZWQgTGlzdCBoZWFkZXJzOworKyAgICBwcm90ZWN0ZWQgTGlzdDxJbnRlcm5ldEhlYWRlcj4gaGVhZGVyczsKK0BAIC01ODksMiArNTg1LDEgQEAKKy0gICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyIsICJ1bmNoZWNrZWQifSkKKy0gICAgcHVibGljIEVudW1lcmF0aW9uIGdldEFsbEhlYWRlcnMoKSB7CisrICAgIHB1YmxpYyBFbnVtZXJhdGlvbjxIZWFkZXI+IGdldEFsbEhlYWRlcnMoKSB7CitAQCAtNjAwLDIgKzU5NSwxIEBACistICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMiLCAidW5jaGVja2VkIn0pCistICAgIHB1YmxpYyBFbnVtZXJhdGlvbiBnZXRNYXRjaGluZ0hlYWRlcnMoU3RyaW5nW10gbmFtZXMpIHsKKysgICAgcHVibGljIEVudW1lcmF0aW9uPEhlYWRlcj4gZ2V0TWF0Y2hpbmdIZWFkZXJzKFN0cmluZ1tdIG5hbWVzKSB7CitAQCAtNjExLDIgKzYwNSwxIEBACistICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMiLCAidW5jaGVja2VkIn0pCistICAgIHB1YmxpYyBFbnVtZXJhdGlvbiBnZXROb25NYXRjaGluZ0hlYWRlcnMoU3RyaW5nW10gbmFtZXMpIHsKKysgICAgcHVibGljIEVudW1lcmF0aW9uPEhlYWRlcj4gZ2V0Tm9uTWF0Y2hpbmdIZWFkZXJzKFN0cmluZ1tdIG5hbWVzKSB7CitAQCAtNjQ5LDIgKzY0MCwxIEBACistICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJyYXd0eXBlcyIpCistICAgIHB1YmxpYyBFbnVtZXJhdGlvbiBnZXRBbGxIZWFkZXJMaW5lcygpIHsgCisrICAgIHB1YmxpYyBFbnVtZXJhdGlvbjxTdHJpbmc+IGdldEFsbEhlYWRlckxpbmVzKCkgeyAKK0BAIC02NjAsMiArNjUwLDEgQEAKKy0gICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyIsICJ1bmNoZWNrZWQifSkKKy0gICAgcHVibGljIEVudW1lcmF0aW9uIGdldE1hdGNoaW5nSGVhZGVyTGluZXMoU3RyaW5nW10gbmFtZXMpIHsKKysgICAgcHVibGljIEVudW1lcmF0aW9uPFN0cmluZz4gZ2V0TWF0Y2hpbmdIZWFkZXJMaW5lcyhTdHJpbmdbXSBuYW1lcykgeworQEAgLTY3MSwyICs2NjAsMSBAQAorLSAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIiwgInVuY2hlY2tlZCJ9KQorLSAgICBwdWJsaWMgRW51bWVyYXRpb24gZ2V0Tm9uTWF0Y2hpbmdIZWFkZXJMaW5lcyhTdHJpbmdbXSBuYW1lcykgeworKyAgICBwdWJsaWMgRW51bWVyYXRpb248U3RyaW5nPiBnZXROb25NYXRjaGluZ0hlYWRlckxpbmVzKFN0cmluZ1tdIG5hbWVzKSB7CitkaWZmIC1yIDFmNmIyYzE3ZTI5MSBtYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9NaW1lQm9keVBhcnQuamF2YQorLSBhL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2ludGVybmV0L01pbWVCb2R5UGFydC5qYXZhCisrKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9NaW1lQm9keVBhcnQuamF2YQorQEAgLTEwMzYsMiArMTAzNiwxIEBACistICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJyYXd0eXBlcyIpCistICAgIHB1YmxpYyBFbnVtZXJhdGlvbiBnZXRBbGxIZWFkZXJzKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisrICAgIHB1YmxpYyBFbnVtZXJhdGlvbjxIZWFkZXI+IGdldEFsbEhlYWRlcnMoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKK0BAIC0xMDQ1LDIgKzEwNDQsMSBAQAorLSAgICBAU3VwcHJlc3NXYXJuaW5ncygicmF3dHlwZXMiKQorLSAgICBwdWJsaWMgRW51bWVyYXRpb24gZ2V0TWF0Y2hpbmdIZWFkZXJzKFN0cmluZ1tdIG5hbWVzKQorKyAgICBwdWJsaWMgRW51bWVyYXRpb248SGVhZGVyPiBnZXRNYXRjaGluZ0hlYWRlcnMoU3RyaW5nW10gbmFtZXMpCitAQCAtMTA1NSwyICsxMDUzLDEgQEAKKy0gICAgQFN1cHByZXNzV2FybmluZ3MoInJhd3R5cGVzIikKKy0gICAgcHVibGljIEVudW1lcmF0aW9uIGdldE5vbk1hdGNoaW5nSGVhZGVycyhTdHJpbmdbXSBuYW1lcykKKysgICAgcHVibGljIEVudW1lcmF0aW9uPEhlYWRlcj4gZ2V0Tm9uTWF0Y2hpbmdIZWFkZXJzKFN0cmluZ1tdIG5hbWVzKQorQEAgLTEwNzMsMiArMTA3MCwxIEBACistICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJyYXd0eXBlcyIpCistICAgIHB1YmxpYyBFbnVtZXJhdGlvbiBnZXRBbGxIZWFkZXJMaW5lcygpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworKyAgICBwdWJsaWMgRW51bWVyYXRpb248U3RyaW5nPiBnZXRBbGxIZWFkZXJMaW5lcygpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworQEAgLTEwODMsMiArMTA3OSwxIEBACistICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJyYXd0eXBlcyIpCistICAgIHB1YmxpYyBFbnVtZXJhdGlvbiBnZXRNYXRjaGluZ0hlYWRlckxpbmVzKFN0cmluZ1tdIG5hbWVzKQorKyAgICBwdWJsaWMgRW51bWVyYXRpb248U3RyaW5nPiBnZXRNYXRjaGluZ0hlYWRlckxpbmVzKFN0cmluZ1tdIG5hbWVzKQorQEAgLTEwOTQsMiArMTA4OSwxIEBACistICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJyYXd0eXBlcyIpCistICAgIHB1YmxpYyBFbnVtZXJhdGlvbiBnZXROb25NYXRjaGluZ0hlYWRlckxpbmVzKFN0cmluZ1tdIG5hbWVzKSAgCisrICAgIHB1YmxpYyBFbnVtZXJhdGlvbjxTdHJpbmc+IGdldE5vbk1hdGNoaW5nSGVhZGVyTGluZXMoU3RyaW5nW10gbmFtZXMpICAKK2RpZmYgLXIgMWY2YjJjMTdlMjkxIG1haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2ludGVybmV0L01pbWVNZXNzYWdlLmphdmEKKy0gYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9NaW1lTWVzc2FnZS5qYXZhCisrKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9NaW1lTWVzc2FnZS5qYXZhCitAQCAtMTk5MiwyICsxOTkxLDEgQEAKKy0gICAgQFN1cHByZXNzV2FybmluZ3MoInJhd3R5cGVzIikKKy0gICAgcHVibGljIEVudW1lcmF0aW9uIGdldEFsbEhlYWRlcnMoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKysgICAgcHVibGljIEVudW1lcmF0aW9uPEhlYWRlcj4gZ2V0QWxsSGVhZGVycygpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworQEAgLTIwMDQsMiArMjAwMiwxIEBACistICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJyYXd0eXBlcyIpCistICAgIHB1YmxpYyBFbnVtZXJhdGlvbiBnZXRNYXRjaGluZ0hlYWRlcnMoU3RyaW5nW10gbmFtZXMpCisrICAgIHB1YmxpYyBFbnVtZXJhdGlvbjxIZWFkZXI+IGdldE1hdGNoaW5nSGVhZGVycyhTdHJpbmdbXSBuYW1lcykKK0BAIC0yMDE3LDIgKzIwMTQsMSBAQAorLSAgICBAU3VwcHJlc3NXYXJuaW5ncygicmF3dHlwZXMiKQorLSAgICBwdWJsaWMgRW51bWVyYXRpb24gZ2V0Tm9uTWF0Y2hpbmdIZWFkZXJzKFN0cmluZ1tdIG5hbWVzKQorKyAgICBwdWJsaWMgRW51bWVyYXRpb248SGVhZGVyPiBnZXROb25NYXRjaGluZ0hlYWRlcnMoU3RyaW5nW10gbmFtZXMpCitAQCAtMjA0MywyICsyMDM5LDEgQEAKKy0gICAgQFN1cHByZXNzV2FybmluZ3MoInJhd3R5cGVzIikKKy0gICAgcHVibGljIEVudW1lcmF0aW9uIGdldEFsbEhlYWRlckxpbmVzKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisrICAgIHB1YmxpYyBFbnVtZXJhdGlvbjxTdHJpbmc+IGdldEFsbEhlYWRlckxpbmVzKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CitAQCAtMjA1NSwyICsyMDUwLDEgQEAKKy0gICAgQFN1cHByZXNzV2FybmluZ3MoInJhd3R5cGVzIikKKy0gICAgcHVibGljIEVudW1lcmF0aW9uIGdldE1hdGNoaW5nSGVhZGVyTGluZXMoU3RyaW5nW10gbmFtZXMpCisrICAgIHB1YmxpYyBFbnVtZXJhdGlvbjxTdHJpbmc+IGdldE1hdGNoaW5nSGVhZGVyTGluZXMoU3RyaW5nW10gbmFtZXMpCitAQCAtMjA2OCwyICsyMDYyLDEgQEAKKy0gICAgQFN1cHByZXNzV2FybmluZ3MoInJhd3R5cGVzIikKKy0gICAgcHVibGljIEVudW1lcmF0aW9uIGdldE5vbk1hdGNoaW5nSGVhZGVyTGluZXMoU3RyaW5nW10gbmFtZXMpCisrICAgIHB1YmxpYyBFbnVtZXJhdGlvbjxTdHJpbmc+IGdldE5vbk1hdGNoaW5nSGVhZGVyTGluZXMoU3RyaW5nW10gbmFtZXMpCitkaWZmIC1yIDFmNmIyYzE3ZTI5MSBtYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9NaW1lUGFydC5qYXZhCistIGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvTWltZVBhcnQuamF2YQorKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvTWltZVBhcnQuamF2YQorQEAgLTExMSwyICsxMTEsMSBAQAorLSAgICBAU3VwcHJlc3NXYXJuaW5ncygicmF3dHlwZXMiKQorLSAgICBwdWJsaWMgRW51bWVyYXRpb24gZ2V0QWxsSGVhZGVyTGluZXMoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uOworKyAgICBwdWJsaWMgRW51bWVyYXRpb248U3RyaW5nPiBnZXRBbGxIZWFkZXJMaW5lcygpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb247CitAQCAtMTIzLDIgKzEyMiwxIEBACistICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJyYXd0eXBlcyIpCistICAgIHB1YmxpYyBFbnVtZXJhdGlvbiBnZXRNYXRjaGluZ0hlYWRlckxpbmVzKFN0cmluZ1tdIG5hbWVzKQorKyAgICBwdWJsaWMgRW51bWVyYXRpb248U3RyaW5nPiBnZXRNYXRjaGluZ0hlYWRlckxpbmVzKFN0cmluZ1tdIG5hbWVzKQorQEAgLTEzNiwyICsxMzQsMSBAQAorLSAgICBAU3VwcHJlc3NXYXJuaW5ncygicmF3dHlwZXMiKQorLSAgICBwdWJsaWMgRW51bWVyYXRpb24gZ2V0Tm9uTWF0Y2hpbmdIZWFkZXJMaW5lcyhTdHJpbmdbXSBuYW1lcykKKysgICAgcHVibGljIEVudW1lcmF0aW9uPFN0cmluZz4gZ2V0Tm9uTWF0Y2hpbmdIZWFkZXJMaW5lcyhTdHJpbmdbXSBuYW1lcykKK2RpZmYgLXIgMWY2YjJjMTdlMjkxIG1haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2ludGVybmV0L1BhcmFtZXRlckxpc3QuamF2YQorLSBhL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2ludGVybmV0L1BhcmFtZXRlckxpc3QuamF2YQorKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvUGFyYW1ldGVyTGlzdC5qYXZhCitAQCAtNjI3LDIgKzYyNywxIEBACistICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJyYXd0eXBlcyIpCistICAgIHB1YmxpYyBFbnVtZXJhdGlvbiBnZXROYW1lcygpIHsKKysgICAgcHVibGljIEVudW1lcmF0aW9uPFN0cmluZz4gZ2V0TmFtZXMoKSB7CisKKworPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCis0LiBNYWlsRGF0ZUZvcm1hdCBjaGFuZ2VzIGZvciB2ZXJzaW9uIDEuNiAoMTc0KQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworVGhlIHBhcnNlKFN0cmluZykgbWV0aG9kIGN1cnJlbnRseSByZXR1cm5zIG51bGwgZm9yIGludmFsaWQgZGF0ZXMsCit3aGljaCB2aW9sYXRlcyB0aGUgY29udHJhY3Qgb2YgRGF0ZUZvcm1hdC4gIEl0IHNob3VsZCB0aHJvdyBQYXJzZUV4Y2VwdGlvbi4KKworU29tZSBtZXRob2RzIG9mIE1haWxEYXRlRm9ybWF0IHRocm93IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uLgorVGhlIGZvbGxvd2luZyBtZXRob2RzIHNob3VsZCBhbHNvIGRvIHNvOgorCisJLyoqCisJICogVGhpcyBtZXRob2QgYWx3YXlzIHRocm93cyBhbiBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBhbmQKKwkgKiBzaG91bGQgbm90IGJlIHVzZWQgYmVjYXVzZSBSRkMgMjgyMiBtYW5kYXRlcyBhIHNwZWNpZmljIHBhdHRlcm4uCisJICoKKwkgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGlmIHRoaXMgbWV0aG9kIGlzIGludm9rZWQKKwkgKiBAc2luY2UgSmF2YU1haWwgMS42CisJICovCisJQE92ZXJyaWRlCisJcHVibGljIHZvaWQgYXBwbHlMb2NhbGl6ZWRQYXR0ZXJuKFN0cmluZyBwYXR0ZXJuKSB7CisJICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTWV0aG9kICIKKwkJICAgICsgImFwcGx5TG9jYWxpemVkUGF0dGVybigpIHNob3VsZG4ndCBiZSBjYWxsZWQiKTsKKwl9CisKKwkvKioKKwkgKiBUaGlzIG1ldGhvZCBhbHdheXMgdGhyb3dzIGFuIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGFuZAorCSAqIHNob3VsZCBub3QgYmUgdXNlZCBiZWNhdXNlIFJGQyAyODIyIG1hbmRhdGVzIGEgc3BlY2lmaWMgcGF0dGVybi4KKwkgKgorCSAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gaWYgdGhpcyBtZXRob2QgaXMgaW52b2tlZAorCSAqIEBzaW5jZSBKYXZhTWFpbCAxLjYKKwkgKi8KKwlAT3ZlcnJpZGUKKwlwdWJsaWMgdm9pZCBhcHBseVBhdHRlcm4oU3RyaW5nIHBhdHRlcm4pIHsKKwkgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJNZXRob2QgIgorCQkgICAgKyAiYXBwbHlQYXR0ZXJuKCkgc2hvdWxkbid0IGJlIGNhbGxlZCIpOworCX0KKworCS8qKgorCSAqIFRoaXMgbWV0aG9kIGFsd2F5cyB0aHJvd3MgYW4gVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gYW5kCisJICogc2hvdWxkIG5vdCBiZSB1c2VkIGJlY2F1c2UgUkZDIDI4MjIgbWFuZGF0ZXMgYW5vdGhlciBzdHJhdGVneQorCSAqIGZvciBpbnRlcnByZXRpbmcgMi1kaWdpdHMgeWVhcnMuCisJICoKKwkgKiBAcmV0dXJuIHRoZSBzdGFydCBvZiB0aGUgMTAwLXllYXIgcGVyaW9kIGludG8gd2hpY2ggdHdvIGRpZ2l0CisJICogeWVhcnMgYXJlIHBhcnNlZAorCSAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gaWYgdGhpcyBtZXRob2QgaXMgaW52b2tlZAorCSAqIEBzaW5jZSBKYXZhTWFpbCAxLjYKKwkgKi8KKwlAT3ZlcnJpZGUKKwlwdWJsaWMgRGF0ZSBnZXQyRGlnaXRZZWFyU3RhcnQoKSB7CisJICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTWV0aG9kICIKKwkJICAgICsgImdldDJEaWdpdFllYXJTdGFydCgpIHNob3VsZG4ndCBiZSBjYWxsZWQiKTsKKwl9CisKKwkvKioKKwkgKiBUaGlzIG1ldGhvZCBhbHdheXMgdGhyb3dzIGFuIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGFuZAorCSAqIHNob3VsZCBub3QgYmUgdXNlZCBiZWNhdXNlIFJGQyAyODIyIG1hbmRhdGVzIGFub3RoZXIgc3RyYXRlZ3kKKwkgKiBmb3IgaW50ZXJwcmV0aW5nIDItZGlnaXRzIHllYXJzLgorCSAqCisJICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBpZiB0aGlzIG1ldGhvZCBpcyBpbnZva2VkCisJICogQHNpbmNlIEphdmFNYWlsIDEuNgorCSAqLworCUBPdmVycmlkZQorCXB1YmxpYyB2b2lkIHNldDJEaWdpdFllYXJTdGFydChEYXRlIHN0YXJ0RGF0ZSkgeworCSAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk1ldGhvZCAiCisJCSAgICArICJzZXQyRGlnaXRZZWFyU3RhcnQoKSBzaG91bGRuJ3QgYmUgY2FsbGVkIik7CisJfQorCisJLyoqCisJICogVGhpcyBtZXRob2QgYWx3YXlzIHRocm93cyBhbiBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBhbmQKKwkgKiBzaG91bGQgbm90IGJlIHVzZWQgYmVjYXVzZSBSRkMgMjgyMiBtYW5kYXRlcyBzcGVjaWZpYyBkYXRlCisJICogZm9ybWF0IHN5bWJvbHMuCisJICoKKwkgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGlmIHRoaXMgbWV0aG9kIGlzIGludm9rZWQKKwkgKiBAc2luY2UgSmF2YU1haWwgMS42CisJICovCisJQE92ZXJyaWRlCisJcHVibGljIHZvaWQgc2V0RGF0ZUZvcm1hdFN5bWJvbHMoRGF0ZUZvcm1hdFN5bWJvbHMgbmV3Rm9ybWF0U3ltYm9scykgeworCSAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk1ldGhvZCAiCisJCSAgICArICJzZXREYXRlRm9ybWF0U3ltYm9scygpIHNob3VsZG4ndCBiZSBjYWxsZWQiKTsKKwl9CisKK01haWxEYXRlRm9ybWF0IHNob3VsZCBpbmNsdWRlIGEgcHJvcGVyIGNsb25lIG1ldGhvZDoKKworCS8qKgorCSAqIE92ZXJyaWRlcyBDbG9uZWFibGUuCisJICoKKwkgKiBAcmV0dXJuIGEgY2xvbmUgb2YgdGhpcyBpbnN0YW5jZQorCSAqIEBzaW5jZSBKYXZhTWFpbCAxLjYKKwkgKi8KKwlAT3ZlcnJpZGUKKwlwdWJsaWMgTWFpbERhdGVGb3JtYXQgY2xvbmUoKSB7CisJICAgIHJldHVybiAoTWFpbERhdGVGb3JtYXQpIHN1cGVyLmNsb25lKCk7CisJfQorCisKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworNS4gU3RvcmUsIFRyYW5zcG9ydCwgYW5kIEZvbGRlciBzaG91bGQgaW1wbGVtZW50IEF1dG9DbG9zZWFibGUgKDE1OSkKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK1RvIGVuYWJsZSB1c2UgaW4gYSB0cnktd2l0aC1yZXNvdXJjZXMgYmxvY2ssIHRoZSBTdG9yZSwgVHJhbnNwb3J0LAorYW5kIEZvbGRlciBjbGFzc2VzIHNob3VsZCBpbXBsZW1lbnQgdGhlIGphdmEubGFuZy5BdXRvQ2xvc2VhYmxlIGludGVyZmFjZS4KK1N0b3JlIGFuZCBUcmFuc3BvcnQgYXJlIHN1YmNsYXNzZXMgb2YgU2VydmljZSwgd2hpY2ggYWxyZWFkeSBoYXMgdGhlCityZXF1aXJlZCBjbG9zZSgpIG1ldGhvZCwgc28gaGF2aW5nIFNlcnZpY2UgaW1wbGVtZW50IEF1dG9DbG9zZWFibGUgaXMKK3N1ZmZpY2llbnQuICBUaGUgRm9sZGVyIGNsYXNzIGluY2x1ZGVzIGEgY2xvc2UgbWV0aG9kIHdpdGggYSByZXF1aXJlZAorImV4cHVuZ2UiIHBhcmFtZXRlciBzbyB3ZSBhZGQgYSBuZXcgY2xvc2UoKSBtZXRob2Qgd2l0aCBubyBwYXJhbWV0ZXIKK3RoYXQgYmVoYXZlcyB0aGUgc2FtZSBhcyBjbG9zZSh0cnVlKSwgYW5kIGhhdmUgRm9sZGVyIGltcGxlbWVudCBBdXRvQ2xvc2VhYmxlLgorCisJcHVibGljIGFic3RyYWN0IGNsYXNzIFNlcnZpY2UgaW1wbGVtZW50cyBBdXRvQ2xvc2VhYmxlIHsKKwkgICAgLi4uCisJfQorCisJcHVibGljIGFic3RyYWN0IGNsYXNzIEZvbGRlciBpbXBsZW1lbnRzIEF1dG9DbG9zZWFibGUgeworCSAgICAuLi4KKyAKKwkgICAgLyoqCisJICAgICAqIENsb3NlIHRoaXMgRm9sZGVyIGFuZCBleHB1bmdlIGRlbGV0ZWQgbWVzc2FnZXMuIDxwPgorCSAgICAgKgorCSAgICAgKiBBIENMT1NFRCBDb25uZWN0aW9uRXZlbnQgaXMgZGVsaXZlcmVkIHRvIGFueSBDb25uZWN0aW9uTGlzdGVuZXJzCisJICAgICAqIHJlZ2lzdGVyZWQgb24gdGhpcyBGb2xkZXIuIE5vdGUgdGhhdCB0aGUgZm9sZGVyIGlzIGNsb3NlZCBldmVuCisJICAgICAqIGlmIHRoaXMgbWV0aG9kIHRlcm1pbmF0ZXMgYWJub3JtYWxseSBieSB0aHJvd2luZyBhCisJICAgICAqIE1lc3NhZ2luZ0V4Y2VwdGlvbi4gPHA+CisJICAgICAqCisJICAgICAqIFRoaXMgbWV0aG9kIHN1cHBvcnRzIHRoZSB7QGxpbmsgamF2YS5sYW5nLkF1dG9DbG9zZWFibGUgQXV0b0Nsb3NlYWJsZX0KKwkgICAgICogaW50ZXJmYWNlLiA8cD4KKwkgICAgICoKKwkgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiBjYWxscyA8Y29kZT5jbG9zZSh0cnVlKTwvY29kZT4uCisJICAgICAqCisJICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgZm9sZGVyIGlzIG5vdCBvcGVuZWQKKwkgICAgICogQGV4Y2VwdGlvbiAgICAgICBNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisJICAgICAqIEBzZWUgCQlqYXZheC5tYWlsLmV2ZW50LkNvbm5lY3Rpb25FdmVudAorCSAgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuNgorCSAgICAgKi8KKwkgICAgQE92ZXJyaWRlCisJICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJCWNsb3NlKHRydWUpOworCSAgICB9CisJfQorCisKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworNi4gVGhlIFVJREZvbGRlciBpbnRlcmZhY2Ugc2hvdWxkIGhhdmUgYSBnZXR0ZXIgZm9yIFVJRE5FWFQgKDEwNCkKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK1RoZSBVSURGb2xkZXIgaW50ZXJmYWNlIG1vZGVscyB0aGUgVUlEIHN1cHBvcnQgaW4gdGhlIElNQVAgcHJvdG9jb2wuCitBZnRlciBVSURGb2xkZXIgd2FzIG9yaWdpbmFsbHkgY3JlYXRlZCwgdGhlIElNQVAgcHJvdG9jb2wgYWRkZWQKK3N1cHBvcnQgZm9yIGdldHRpbmcgdGhlIHZhbHVlIG9mIHRoZSBuZXh0IFVJRCB0aGF0IHdpbGwgYmUgYXNzaWduZWQuCitUaGUgSU1BUCBwcm92aWRlciBpbiBKYXZhTWFpbCBoYXMgc3VwcG9ydGVkIHRoaXMgZm9yIHF1aXRlIHNvbWUgdGltZTsKK2l0IHNob3VsZCBiZSBhZGRlZCB0byB0aGUgVUlERm9sZGVyIGludGVyZmFjZToKKworCS8qKgorCSAqIFJldHVybnMgdGhlIHByZWRpY3RlZCBVSUQgdGhhdCB3aWxsIGJlIGFzc2lnbmVkIHRvIHRoZQorCSAqIG5leHQgbWVzc2FnZSB0aGF0IGlzIGFwcGVuZGVkIHRvIHRoaXMgZm9sZGVyLgorCSAqIE1lc3NhZ2VzIG1pZ2h0IGJlIGFwcGVuZGVkIHRvIHRoZSBmb2xkZXIgYWZ0ZXIgdGhpcyB2YWx1ZQorCSAqIGlzIHJldHJpZXZlZCwgY2F1c2luZyB0aGlzIHZhbHVlIHRvIGJlIG91dCBvZiBkYXRlLgorCSAqIFRoaXMgdmFsdWUgbWlnaHQgb25seSBiZSB1cGRhdGVkIHdoZW4gYSBmb2xkZXIgaXMgZmlyc3Qgb3BlbmVkLgorCSAqIE5vdGUgdGhhdCBtZXNzYWdlcyBtYXkgaGF2ZSBiZWVuIGFwcGVuZGVkIHRvIHRoZSBmb2xkZXIKKwkgKiB3aGlsZSBpdCB3YXMgb3BlbiBhbmQgdGh1cyB0aGlzIHZhbHVlIG1heSBiZSBvdXQgb2YKKwkgKiBkYXRlLiA8cD4KKwkgKgorCSAqIElmIHRoZSB2YWx1ZSBpcyB1bmtub3duLCAtMSBpcyByZXR1cm5lZC4gIDxwPgorCSAqCisJICogQHJldHVybiAgdGhlIFVJRE5FWFQgdmFsdWUsIG9yIC0xIGlmIHVua25vd24KKwkgKiBAZXhjZXB0aW9uICAgICAgIE1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKwkgKiBAc2luY2UgICBKYXZhTWFpbCAxLjYKKwkgKi8KKwlwdWJsaWMgbG9uZyBnZXRVSUROZXh0KCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworSWRlYWxseSB0aGlzIG5ldyBtZXRob2QgYWRkZWQgdG8gdGhlIGludGVyZmFjZSB3b3VsZCBpbmNsdWRlIGEgZGVmYXVsdAoraW1wbGVtZW50YXRpb24gdG8gcHJvdmlkZSBjb21wYXRpYmlsaXR5IHdpdGggZXhpc3RpbmcgY2xhc3NlcyB0aGF0CitpbXBsZW1lbnQgdGhpcyBtZXRob2QuICBIb3dldmVyLCBzaW5jZSB0aGUgSmF2YU1haWwgMS42IHJlZmVyZW5jZQoraW1wbGVtZW50YXRpb24gdGFyZ2V0cyBKYXZhIFNFIDcsIHRoaXMgaXMgbm90IHBvc3NpYmxlLiAgSXQncyB2ZXJ5CitsaWtlbHkgdGhhdCB0aGUgb25seSBjbGFzcyBpbXBsZW1lbnRpbmcgdGhpcyBpbnRlcmZhY2UgaXMgdGhlIElNQVBGb2xkZXIKK2NsYXNzIGluIHRoZSBKYXZhTWFpbCByZWZlcmVuY2UgaW1wbGVtZW50YXRpb24sIHRodXMgdGhpcyBpbmNvbXBhdGliaWxpdHkKK2lzIGV4dHJlbWVseSB1bmxpa2VseSB0byBjYXVzZSBhIHByb2JsZW0gaW4gcHJhY3RpY2UuCisKKworPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCis3LiBUaGUgVUlERm9sZGVyIGludGVyZmFjZSBzaG91bGQgaGF2ZSBhIE1BWFVJRCBjb25zdGFudCAoMjQ0KQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworQW4gSU1BUCBVSUQgaXMgYSAzMi1iaXQgdW5zaWduZWQgaW50ZWdlciBhbmQgaXMgcmVwcmVzZW50ZWQgYXMgYSBKYXZhIGxvbmcuCitBIG5ldyBjb25zdGFudCBpbmRpY2F0ZXMgdGhlIG1heGltdW0gdmFsdWUgb2YgYSBVSUQ6CisKKwkvKioKKwkgKiBUaGUgbGFyZ2VzdCB2YWx1ZSBwb3NzaWJsZSBmb3IgYSBVSUQsIGEgMzItYml0IHVuc2lnbmVkIGludGVnZXIuCisJICogVGhpcyBjYW4gYmUgdXNlZCB0byBmZXRjaCBhbGwgbmV3IG1lc3NhZ2VzIGJ5IGtlZXBpbmcgdHJhY2sgb2YgdGhlCisJICogbGFzdCBVSUQgdGhhdCB3YXMgc2VlbiBhbmQgdXNpbmc6CisJICogPGJsb2NrcXVvdGU+PHByZT4KKwkgKgorCSAqIAlGb2xkZXIgZiA9IHN0b3JlLmdldEZvbGRlcigid2hhdGV2ZXIiKTsKKwkgKglVSURGb2xkZXIgdWYgPSAoVUlERm9sZGVyKWY7CisJICoJTWVzc2FnZVtdIG5ld01zZ3MgPQorCSAqCQl1Zi5nZXRNZXNzYWdlc0J5VUlEKGxhc3RTZWVuVUlEICsgMSwgVUlERm9sZGVyLk1BWFVJRCk7CisJICoKKwkgKiA8L3ByZT48L2Jsb2NrcXVvdGU+PHA+CisJICoKKwkgKiBAc2luY2UgSmF2YU1haWwgMS42CisJICovCisJcHVibGljIHN0YXRpYyBmaW5hbCBsb25nIE1BWFVJRCA9IDB4ZmZmZmZmZmZMOworCisKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworOC4gTWltZU11bHRpcGFydCBzaG91bGQgdGhyb3cgUGFyc2VFeGNlcHRpb24gZm9yIHBhcnNpbmcgZXJyb3JzICg3NSkKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK1BhcnNlRXhjZXB0aW9uIGluZGljYXRlcyBhbiBlcnJvciBwYXJzaW5nIE1JTUUgbWVzc2FnZXMuICBJbiBhZGRpdGlvbgordG8gYXBwbHlpbmcgdG8gTUlNRSBoZWFkZXJzLCBpdCBzZWVtcyByZWFzb25hYmxlIHRvIGV4cGFuZCBpdCB0byBjb3ZlcgorbXVsdGlwYXJ0IG1lc3NhZ2UgcGFyc2luZy4gIFNpbmNlIFBhcnNlRXhjZXB0aW9uIGlzIGEgc3ViY2xhc3Mgb2YKK01lc3NhZ2luZ0V4Y2VwdGlvbiwgaXQgbWVyZWx5IHJlcG9ydHMgbW9yZSBwcmVjaXNlbHkgdGhlIGNhdXNlIG9mIHRoZQorZXJyb3IuCisKK1RoZSBkZXNjcmlwdGlvbiBvZiBQYXJzZUV4Y2VwdGlvbiBpcyBjaGFuZ2VkIHRvOgorCisJICAqIFRoZSBleGNlcHRpb24gdGhyb3duIGR1ZSB0byBhbiBlcnJvciBpbiBwYXJzaW5nIFJGQzgyMiAKKwkgICogb3IgTUlNRSBoZWFkZXJzLCBpbmNsdWRpbmcgbXVsdGlwYXJ0IGJvZGllcy4KKworTWltZU11bHRpcGFydCBkb2N1bWVudHMgdGhhdCBQYXJzZUV4Y2VwdGlvbiBjYW4gYmUgdGhyb3duIGZyb20gYW4KK2V4aXN0aW5nIGNvbnN0cnVjdG9yIGFuZCBtZXRob2Q6CisKKwkvKioKKwkgKiBDb25zdHJ1Y3RzIGEgTWltZU11bHRpcGFydCBvYmplY3QgYW5kIGl0cyBib2R5cGFydHMgZnJvbSB0aGUgCisJICogZ2l2ZW4gRGF0YVNvdXJjZS4gPHA+CisJICoKKwkgKiBUaGlzIGNvbnN0cnVjdG9yIGhhbmRsZXMgYXMgYSBzcGVjaWFsIGNhc2UgdGhlIHNpdHVhdGlvbiB3aGVyZSB0aGUKKwkgKiBnaXZlbiBEYXRhU291cmNlIGlzIGEgTXVsdGlwYXJ0RGF0YVNvdXJjZSBvYmplY3QuICBJbiB0aGlzIGNhc2UsIHRoaXMKKwkgKiBtZXRob2QganVzdCBpbnZva2VzIHRoZSBzdXBlcmNsYXNzIChpLmUuLCBNdWx0aXBhcnQpIGNvbnN0cnVjdG9yCisJICogdGhhdCB0YWtlcyBhIE11bHRpcGFydERhdGFTb3VyY2Ugb2JqZWN0LiA8cD4KKwkgKgorCSAqIE90aGVyd2lzZSwgdGhlIERhdGFTb3VyY2UgaXMgYXNzdW1lZCB0byBwcm92aWRlIGEgTUlNRSBtdWx0aXBhcnQgCisJICogYnl0ZSBzdHJlYW0uICBUaGUgPGNvZGU+cGFyc2VkPC9jb2RlPiBmbGFnIGlzIHNldCB0byBmYWxzZS4gIFdoZW4KKwkgKiB0aGUgZGF0YSBmb3IgdGhlIGJvZHkgcGFydHMgYXJlIG5lZWRlZCwgdGhlIHBhcnNlciBleHRyYWN0cyB0aGUKKwkgKiAiYm91bmRhcnkiIHBhcmFtZXRlciBmcm9tIHRoZSBjb250ZW50IHR5cGUgb2YgdGhpcyBEYXRhU291cmNlLAorCSAqIHNraXBzIHRoZSAncHJlYW1ibGUnIGFuZCByZWFkcyBieXRlcyB0aWxsIHRoZSB0ZXJtaW5hdGluZworCSAqIGJvdW5kYXJ5IGFuZCBjcmVhdGVzIE1pbWVCb2R5UGFydHMgZm9yIGVhY2ggcGFydCBvZiB0aGUgc3RyZWFtLgorCSAqCisJICogQHBhcmFtCWRzCURhdGFTb3VyY2UsIGNhbiBiZSBhIE11bHRpcGFydERhdGFTb3VyY2UKKwkgKiBAZXhjZXB0aW9uCVBhcnNlRXhjZXB0aW9uIGZvciBmYWlsdXJlcyBwYXJzaW5nIHRoZSBtZXNzYWdlCisJICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisJICovCisJcHVibGljIE1pbWVNdWx0aXBhcnQoRGF0YVNvdXJjZSBkcykgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbgorCisJLi4uCisKKwkvKioKKwkgKiBQYXJzZSB0aGUgSW5wdXRTdHJlYW0gZnJvbSBvdXIgRGF0YVNvdXJjZSwgY29uc3RydWN0aW5nIHRoZQorCSAqIGFwcHJvcHJpYXRlIE1pbWVCb2R5UGFydHMuICBUaGUgPGNvZGU+cGFyc2VkPC9jb2RlPiBmbGFnIGlzCisJICogc2V0IHRvIHRydWUsIGFuZCBpZiB0cnVlIG9uIGVudHJ5IG5vdGhpbmcgaXMgZG9uZS4gIFRoaXMKKwkgKiBtZXRob2QgaXMgY2FsbGVkIGJ5IGFsbCBvdGhlciBtZXRob2RzIHRoYXQgbmVlZCBkYXRhIGZvcgorCSAqIHRoZSBib2R5IHBhcnRzLCB0byBtYWtlIHN1cmUgdGhlIGRhdGEgaGFzIGJlZW4gcGFyc2VkLgorCSAqIFRoZSB7QGxpbmsgI2luaXRpYWxpemVQcm9wZXJ0aWVzfSBtZXRob2QgaXMgY2FsbGVkIGJlZm9yZQorCSAqIHBhcnNpbmcgdGhlIGRhdGEuCisJICoKKwkgKiBAZXhjZXB0aW9uCVBhcnNlRXhjZXB0aW9uIGZvciBmYWlsdXJlcyBwYXJzaW5nIHRoZSBtZXNzYWdlCisJICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisJICogQHNpbmNlCUphdmFNYWlsIDEuMgorCSAqLworCXByb3RlY3RlZCBzeW5jaHJvbml6ZWQgdm9pZCBwYXJzZSgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24KKworCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKzkuIFN1cHBvcnQgYWRkcmVzc2luZyBpMThuIHZpYSBSRkMgNjUzMC82NTMxLzY1MzIgKDkzKQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK1RvIGVuYWJsZSBzdXBwb3J0IGZvciBVVEYtOCBlbWFpbCBhZGRyZXNzZXMsIHRoZSBmb2xsb3dpbmcgbWV0aG9kcworYXJlIGFkZGVkIHRvIEludGVybmV0QWRkcmVzczoKKworCS8qKgorCSAqIENvbnZlcnQgdGhlIGdpdmVuIGFycmF5IG9mIEludGVybmV0QWRkcmVzcyBvYmplY3RzIGludG8KKwkgKiBhIGNvbW1hIHNlcGFyYXRlZCBzZXF1ZW5jZSBvZiBhZGRyZXNzIHN0cmluZ3MuIFRoZQorCSAqIHJlc3VsdGluZyBzdHJpbmcgY29udGFpbnMgVW5pY29kZSBjaGFyYWN0ZXJzLiA8cD4KKwkgKgorCSAqIEBwYXJhbSBhZGRyZXNzZXMJYXJyYXkgb2YgSW50ZXJuZXRBZGRyZXNzIG9iamVjdHMKKwkgKiBAZXhjZXB0aW9uIAlDbGFzc0Nhc3RFeGNlcHRpb24gaWYgYW55IGFkZHJlc3Mgb2JqZWN0IGluIHRoZSAKKwkgKgkJCWdpdmVuIGFycmF5IGlzIG5vdCBhbiBJbnRlcm5ldEFkZHJlc3Mgb2JqZWN0LgorCSAqCQkJTm90ZSB0aGF0IHRoaXMgaXMgYSBSdW50aW1lRXhjZXB0aW9uLgorCSAqIEByZXR1cm4JCWNvbW1hIHNlcGFyYXRlZCBzdHJpbmcgb2YgYWRkcmVzc2VzCisJICogQHNpbmNlCQlKYXZhTWFpbCAxLjYKKwkgKi8KKwlwdWJsaWMgc3RhdGljIFN0cmluZyB0b1VuaWNvZGVTdHJpbmcoQWRkcmVzc1tdIGFkZHJlc3NlcykKKworCS8qKgorCSAqIENvbnZlcnQgdGhlIGdpdmVuIGFycmF5IG9mIEludGVybmV0QWRkcmVzcyBvYmplY3RzIGludG8KKwkgKiBhIGNvbW1hIHNlcGFyYXRlZCBzZXF1ZW5jZSBvZiBhZGRyZXNzIHN0cmluZ3MuIFRoZQorCSAqIHJlc3VsdGluZyBzdHJpbmcgY29udGFpbnMgVW5pY29kZSBjaGFyYWN0ZXJzLiA8cD4KKwkgKgorCSAqIFRoZSAndXNlZCcgcGFyYW1ldGVyIHNwZWNpZmllcyB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlciBwb3NpdGlvbnMKKwkgKiBhbHJlYWR5IHRha2VuIHVwIGluIHRoZSBmaWVsZCBpbnRvIHdoaWNoIHRoZSByZXN1bHRpbmcgYWRkcmVzcyAKKwkgKiBzZXF1ZW5jZSBzdHJpbmcgaXMgdG8gYmUgaW5zZXJ0ZWQuIEl0IGlzIHVzZWQgdG8gZGV0ZXJtaW5lIHRoZSAKKwkgKiBsaW5lLWJyZWFrIHBvc2l0aW9ucyBpbiB0aGUgcmVzdWx0aW5nIGFkZHJlc3Mgc2VxdWVuY2Ugc3RyaW5nLgorCSAqCisJICogQHBhcmFtIGFkZHJlc3NlcwlhcnJheSBvZiBJbnRlcm5ldEFkZHJlc3Mgb2JqZWN0cworCSAqIEBwYXJhbSB1c2VkCW51bWJlciBvZiBjaGFyYWN0ZXIgcG9zaXRpb25zIGFscmVhZHkgdXNlZCwgaW4KKwkgKgkJCXRoZSBmaWVsZCBpbnRvIHdoaWNoIHRoZSBhZGRyZXNzIHN0cmluZyBpcyB0bworCSAqCQkJYmUgaW5zZXJ0ZWQuCisJICogQGV4Y2VwdGlvbiAJQ2xhc3NDYXN0RXhjZXB0aW9uIGlmIGFueSBhZGRyZXNzIG9iamVjdCBpbiB0aGUgCisJICoJCQlnaXZlbiBhcnJheSBpcyBub3QgYW4gSW50ZXJuZXRBZGRyZXNzIG9iamVjdC4KKwkgKgkJCU5vdGUgdGhhdCB0aGlzIGlzIGEgUnVudGltZUV4Y2VwdGlvbi4KKwkgKiBAcmV0dXJuCQljb21tYSBzZXBhcmF0ZWQgc3RyaW5nIG9mIGFkZHJlc3NlcworCSAqIEBzaW5jZQkJSmF2YU1haWwgMS42CisJICovCisJcHVibGljIHN0YXRpYyBTdHJpbmcgdG9Vbmljb2RlU3RyaW5nKEFkZHJlc3NbXSBhZGRyZXNzZXMsIGludCB1c2VkKQorCisKK1RoZSBmb2xsb3dpbmcgY29uc3RydWN0b3IgYW5kIG1ldGhvZCBhcmUgYWRkZWQgdG8gSW50ZXJuZXRIZWFkZXJzOgorCisJLyoqCisJICogUmVhZCBhbmQgcGFyc2UgdGhlIGdpdmVuIFJGQzgyMiBtZXNzYWdlIHN0cmVhbSB0aWxsIHRoZSAKKwkgKiBibGFuayBsaW5lIHNlcGFyYXRpbmcgdGhlIGhlYWRlciBmcm9tIHRoZSBib2R5LiBUaGUgaW5wdXQgCisJICogc3RyZWFtIGlzIGxlZnQgcG9zaXRpb25lZCBhdCB0aGUgc3RhcnQgb2YgdGhlIGJvZHkuIFRoZSAKKwkgKiBoZWFkZXIgbGluZXMgYXJlIHN0b3JlZCBpbnRlcm5hbGx5LiA8cD4KKwkgKgorCSAqIEZvciBlZmZpY2llbmN5LCB3cmFwIGEgQnVmZmVyZWRJbnB1dFN0cmVhbSBhcm91bmQgdGhlIGFjdHVhbAorCSAqIGlucHV0IHN0cmVhbSBhbmQgcGFzcyBpdCBhcyB0aGUgcGFyYW1ldGVyLiA8cD4KKwkgKgorCSAqIE5vIHBsYWNlaG9sZGVyIGVudHJpZXMgYXJlIGluc2VydGVkOyB0aGUgb3JpZ2luYWwgb3JkZXIgb2YKKwkgKiB0aGUgaGVhZGVycyBpcyBwcmVzZXJ2ZWQuCisJICoKKwkgKiBAcGFyYW0JaXMgCVJGQzgyMiBpbnB1dCBzdHJlYW0KKwkgKiBAcGFyYW0JYWxsb3d1dGY4IAlpZiBVVEYtOCBlbmNvZGVkIGhlYWRlcnMgYXJlIGFsbG93ZWQKKwkgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgYW55IEkvTyBlcnJvciByZWFkaW5nIHRoZSBzdHJlYW0KKwkgKiBAc2luY2UJCUphdmFNYWlsIDEuNgorCSAqLworCXB1YmxpYyBJbnRlcm5ldEhlYWRlcnMoSW5wdXRTdHJlYW0gaXMsIGJvb2xlYW4gYWxsb3d1dGY4KQorCQkJCSAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uCisKKworCS8qKgorCSAqIFJlYWQgYW5kIHBhcnNlIHRoZSBnaXZlbiBSRkM4MjIgbWVzc2FnZSBzdHJlYW0gdGlsbCB0aGUKKwkgKiBibGFuayBsaW5lIHNlcGFyYXRpbmcgdGhlIGhlYWRlciBmcm9tIHRoZSBib2R5LiBTdG9yZSB0aGUKKwkgKiBoZWFkZXIgbGluZXMgaW5zaWRlIHRoaXMgSW50ZXJuZXRIZWFkZXJzIG9iamVjdC4gVGhlIG9yZGVyCisJICogb2YgaGVhZGVyIGxpbmVzIGlzIHByZXNlcnZlZC4gPHA+CisJICoKKwkgKiBOb3RlIHRoYXQgdGhlIGhlYWRlciBsaW5lcyBhcmUgYWRkZWQgaW50byB0aGlzIEludGVybmV0SGVhZGVycworCSAqIG9iamVjdCwgc28gYW55IGV4aXN0aW5nIGhlYWRlcnMgaW4gdGhpcyBvYmplY3Qgd2lsbCBub3QgYmUKKwkgKiBhZmZlY3RlZC4gIEhlYWRlcnMgYXJlIGFkZGVkIHRvIHRoZSBlbmQgb2YgdGhlIGV4aXN0aW5nIGxpc3QKKwkgKiBvZiBoZWFkZXJzLCBpbiBvcmRlci4KKwkgKgorCSAqIEBwYXJhbQlpcyAJUkZDODIyIGlucHV0IHN0cmVhbQorCSAqIEBwYXJhbQlhbGxvd3V0ZjggCWlmIFVURi04IGVuY29kZWQgaGVhZGVycyBhcmUgYWxsb3dlZAorCSAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBhbnkgSS9PIGVycm9yIHJlYWRpbmcgdGhlIHN0cmVhbQorCSAqIEBzaW5jZQkJSmF2YU1haWwgMS42CisJICovCisJcHVibGljIHZvaWQgbG9hZChJbnB1dFN0cmVhbSBpcywgYm9vbGVhbiBhbGxvd3V0ZjgpCisJCQkJICAgIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24KKworVGhlIGZvbGxvd2luZyBTZXNzaW9uIHByb3BlcnR5IGNhbiBiZSBzZXQgdG8gZW5hYmxlIGltcGxpY2l0IHVzZSBvZgordGhlc2UgbmV3IG1ldGhvZHM6CisKK21haWwubWltZS5hbGxvd3V0Zjg6CisKKyAgSWYgc2V0IHRvICJ0cnVlIiwgVVRGLTggc3RyaW5ncyBhcmUgYWxsb3dlZCBpbiBtZXNzYWdlIGhlYWRlcnMsCisgIGUuZy4sIGluIGFkZHJlc3Nlcy4gIFRoaXMgc2hvdWxkIG9ubHkgYmUgc2V0IGlmIHRoZSBtYWlsIHNlcnZlciBhbHNvCisgIHN1cHBvcnRzIFVURi04LgorCisKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworMTAuIExvb2sgZm9yIHJlc291cmNlIGZpbGVzIGluIDxqYXZhLmhvbWU+L2NvbmYgb24gSkRLIDEuOSAoMjQ3KQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitKREsgMS45IGFkZHMgYSBuZXcgPGphdmEuaG9tZT4vY29uZiBkaXJlY3RvcnkgdG8gaG9sZCBjb25maWd1cmF0aW9uCitmaWxlcyB0aGF0IHdlcmUgcHJldmlvdXNseSBzdG9yZWQgaW4gPGphdmEuaG9tZT4vbGliLiAgV2hlbiB1c2luZworSmF2YU1haWwgb24gSkRLIDEuOSwgaXQgc2hvdWxkIGxvb2sgZm9yIGl0cyAob3B0aW9uYWwpIGNvbmZpZ3VyYXRpb24KK2ZpbGVzIGluIHRoZSA8amF2YS5ob21lPi9jb25mIGRpcmVjdG9yeS4KKworVGhlIHNwZWNpZmljYXRpb24gb2YgdGhlIFNlc3Npb24gY2xhc3MgaXMgY2hhbmdlZCBhcyBmb2xsb3dzOgorCisJLyoqCisJICogVGhlIFNlc3Npb24gY2xhc3MgcmVwcmVzZW50cyBhIG1haWwgc2Vzc2lvbiBhbmQgaXMgbm90IHN1YmNsYXNzZWQuCisJICogSXQgY29sbGVjdHMgdG9nZXRoZXIgcHJvcGVydGllcyBhbmQgZGVmYXVsdHMgdXNlZCBieSB0aGUgbWFpbCBBUEkncy4KKwkgKiBBIHNpbmdsZSBkZWZhdWx0IHNlc3Npb24gY2FuIGJlIHNoYXJlZCBieSBtdWx0aXBsZSBhcHBsaWNhdGlvbnMgb24KKwkgKiB0aGUgZGVza3RvcC4gIFVuc2hhcmVkIHNlc3Npb25zIGNhbiBhbHNvIGJlIGNyZWF0ZWQuIDxwPgorCSAqCisJICogVGhlIFNlc3Npb24gY2xhc3MgcHJvdmlkZXMgYWNjZXNzIHRvIHRoZSBwcm90b2NvbCBwcm92aWRlcnMgdGhhdAorCSAqIGltcGxlbWVudCB0aGUgPGNvZGU+U3RvcmU8L2NvZGU+LCA8Y29kZT5UcmFuc3BvcnQ8L2NvZGU+LCBhbmQgcmVsYXRlZAorCSAqIGNsYXNzZXMuICBUaGUgcHJvdG9jb2wgcHJvdmlkZXJzIGFyZSBjb25maWd1cmVkIHVzaW5nIHRoZSBmb2xsb3dpbmcKKwkgKiBmaWxlczoKKwkgKiA8dWw+CisJICogIDxsaT4gPGNvZGU+amF2YW1haWwucHJvdmlkZXJzPC9jb2RlPiBhbmQKKwkgKiAgICAgIDxjb2RlPmphdmFtYWlsLmRlZmF1bHQucHJvdmlkZXJzPC9jb2RlPiA8L2xpPgorCSAqICA8bGk+IDxjb2RlPmphdmFtYWlsLmFkZHJlc3MubWFwPC9jb2RlPiBhbmQKKwkgKiAgICAgIDxjb2RlPmphdmFtYWlsLmRlZmF1bHQuYWRkcmVzcy5tYXA8L2NvZGU+IDwvbGk+CisJICogPC91bD4KKwkgKiA8cD4KKwkgKiBFYWNoIDxjb2RlPmphdmFtYWlsLjwvY29kZT48aT5YPC9pPiByZXNvdXJjZSBmaWxlIGlzIHNlYXJjaGVkIGZvcgorCSAqIHVzaW5nIHRocmVlIG1ldGhvZHMgaW4gdGhlIGZvbGxvd2luZyBvcmRlcjoKKwkgKiA8b2w+CisJICogIDxsaT4gPGNvZGU+PGk+amF2YS5ob21lPC9pPi88aT5jb25mPC9pPi9qYXZhbWFpbC48L2NvZGU+PGk+WDwvaT4gPC9saT4KKwkgKiAgPGxpPiA8Y29kZT5NRVRBLUlORi9qYXZhbWFpbC48L2NvZGU+PGk+WDwvaT4gPC9saT4KKwkgKiAgPGxpPiA8Y29kZT5NRVRBLUlORi9qYXZhbWFpbC5kZWZhdWx0LjwvY29kZT48aT5YPC9pPiA8L2xpPgorCSAqIDwvb2w+CisJICogPHA+CisJICogKFdoZXJlIDxpPmphdmEuaG9tZTwvaT4gaXMgdGhlIHZhbHVlIG9mIHRoZSAiamF2YS5ob21lIiBTeXN0ZW0KKwkgKiBwcm9wZXJ0eSBhbmQgPGk+Y29uZjwvaT4gaXMgdGhlIGRpcmVjdG9yeSBuYW1lZCAiY29uZiIgaWYgaXQgZXhpc3RzLAorCSAqIG90aGVyd2lzZSB0aGUgZGlyZWN0b3J5IG5hbWVkICJsaWIiOyB0aGUgImNvbmYiIGRpcmVjdG9yeSB3YXMKKwkgKiBpbnRyb2R1Y2VkIGluIEpESyAxLjkuKQorCSAqIDxwPgorCSAqIFRoZSBmaXJzdCBtZXRob2QgYWxsb3dzIHRoZSB1c2VyIHRvIGluY2x1ZGUgdGhlaXIgb3duIHZlcnNpb24gb2YgdGhlCisJICogcmVzb3VyY2UgZmlsZSBieSBwbGFjaW5nIGl0IGluIHRoZSA8aT5jb25mPC9pPiBkaXJlY3Rvcnkgd2hlcmUgdGhlCisJICogPGNvZGU+amF2YS5ob21lPC9jb2RlPiBwcm9wZXJ0eSBwb2ludHMuICBUaGUgc2Vjb25kIG1ldGhvZCBhbGxvd3MgYW4KKwkgKiBhcHBsaWNhdGlvbiB0aGF0IHVzZXMgdGhlIEphdmFNYWlsIEFQSXMgdG8gaW5jbHVkZSB0aGVpciBvd24gcmVzb3VyY2UKKwkgKiBmaWxlcyBpbiB0aGVpciBhcHBsaWNhdGlvbidzIG9yIGphciBmaWxlJ3MgPGNvZGU+TUVUQS1JTkY8L2NvZGU+CisJICogZGlyZWN0b3J5LiAgVGhlIDxjb2RlPmphdmFtYWlsLmRlZmF1bHQuPC9jb2RlPjxpPlg8L2k+IGRlZmF1bHQgZmlsZXMKKwkgKiBhcmUgcGFydCBvZiB0aGUgSmF2YU1haWwgPGNvZGU+bWFpbC5qYXI8L2NvZGU+IGZpbGUgYW5kIHNob3VsZCBub3QgYmUKKwkgKiBzdXBwbGllZCBieSB1c2Vycy4gPHA+CisKKworPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisxMS4gRmxhZ3MgY29udmVuaWVuY2UgbWV0aG9kcyAoMjQ5KQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworV2hlbiBjb3B5aW5nIG1lc3NhZ2VzIGZyb20gb25lIHNlcnZlciB0byBhbm90aGVyLCBpdCdzIHNvbWV0aW1lcyBuZWNlc3NhcnkKK3RvIGFkanVzdCB0aGUgbWVzc2FnZSBmbGFncyBiYXNlZCBvbiB0aGUgY2FwYWJpbGl0aWVzIG9mIHRoZSB0YXJnZXQgc2VydmVyLgorSXQgd291bGQgYmUgY29udmVuaWVudCBpZiB0aGUgRmxhZ3MgY2xhc3MgaGFkIG1ldGhvZHMgdG8gY2xlYXIgYW55IGZsYWdzCitub3Qgc3VwcG9ydGVkIGJ5IHRoZSB0YXJnZXQgc2VydmVyLCB0byBjbGVhciBhbGwgdXNlciBmbGFncywgYW5kIHRvIGNsZWFyCithbGwgc3lzdGVtIGZsYWdzLgorCisJLyoqCisJICogUmVtb3ZlIGFueSBmbGFncyA8c3Ryb25nPm5vdDwvc3Ryb25nPiBpbiB0aGUgZ2l2ZW4gRmxhZ3Mgb2JqZWN0LgorCSAqIFVzZWZ1bCBmb3IgY2xlYXJpbmcgZmxhZ3Mgbm90IHN1cHBvcnRlZCBieSBhIHNlcnZlci4gIElmIHRoZQorCSAqIGdpdmVuIEZsYWdzIG9iamVjdCBpbmNsdWRlcyB0aGUgRmxhZ3MuRmxhZy5VU0VSIGZsYWcsIGFsbCB1c2VyCisJICogZmxhZ3MgaW4gdGhpcyBGbGFncyBvYmplY3QgYXJlIHJldGFpbmVkLgorCSAqCisJICogQHBhcmFtCWYJdGhlIGZsYWdzIHRvIGtlZXAKKwkgKiBAcmV0dXJuCQl0cnVlIGlmIHRoaXMgRmxhZ3Mgb2JqZWN0IGNoYW5nZWQKKwkgKiBAc2luY2UJCUphdmFNYWlsIDEuNgorCSAqLworCXB1YmxpYyBib29sZWFuIHJldGFpbkFsbChGbGFncyBmKQorCisJLyoqCisJICogQ2xlYXIgYWxsIG9mIHRoZSBzeXN0ZW0gZmxhZ3MuCisJICoKKwkgKiBAc2luY2UJSmF2YU1haWwgMS42CisJICovCisJcHVibGljIHZvaWQgY2xlYXJTeXN0ZW1GbGFncygpCisKKwkvKioKKwkgKiBDbGVhciBhbGwgb2YgdGhlIHVzZXIgZmxhZ3MuCisJICoKKwkgKiBAc2luY2UJSmF2YU1haWwgMS42CisJICovCisJcHVibGljIHZvaWQgY2xlYXJVc2VyRmxhZ3MoKQpkaWZmIC0tZ2l0IGEvZHNuL3BvbS54bWwgYi9kc24vcG9tLnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNjE5NTJjCi0tLSAvZGV2L251bGwKKysrIGIvZHNuL3BvbS54bWwKQEAgLTAsMCArMSw5OCBAQAorPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PgorPCEtLQorCisgICAgQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisKKyAgICBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAgICB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKworICAgIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAgICBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgICAgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgICAgdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisKKyAgICBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKworLS0+CisKKzxwcm9qZWN0IHhtbG5zPSJodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9QT00vNC4wLjAiCisJeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIKKwl4c2k6c2NoZW1hTG9jYXRpb249Imh0dHA6Ly9tYXZlbi5hcGFjaGUub3JnL1BPTS80LjAuMAorCQkJICAgIGh0dHA6Ly9tYXZlbi5hcGFjaGUub3JnL21hdmVuLXY0XzBfMC54c2QiPgorICAgIDxwYXJlbnQ+CisJPGdyb3VwSWQ+Y29tLnN1bi5tYWlsPC9ncm91cElkPgorCTxhcnRpZmFjdElkPmFsbDwvYXJ0aWZhY3RJZD4KKwk8dmVyc2lvbj4xLjYuMzwvdmVyc2lvbj4KKyAgICA8L3BhcmVudD4KKyAgICA8bW9kZWxWZXJzaW9uPjQuMC4wPC9tb2RlbFZlcnNpb24+CisgICAgPGdyb3VwSWQ+Y29tLnN1bi5tYWlsPC9ncm91cElkPgorICAgIDxhcnRpZmFjdElkPmRzbjwvYXJ0aWZhY3RJZD4KKyAgICA8cGFja2FnaW5nPmphcjwvcGFja2FnaW5nPgorICAgIDxuYW1lPkphdmFNYWlsIEFQSSBkc24gc3VwcG9ydDwvbmFtZT4KKworICAgIDxwcm9wZXJ0aWVzPgorCTxtYWlsLnBhY2thZ2VzLmV4cG9ydD4KKwkgICAgY29tLnN1bi5tYWlsLmRzbjsgdmVyc2lvbj0ke21haWwub3NnaXZlcnNpb259CisJPC9tYWlsLnBhY2thZ2VzLmV4cG9ydD4KKyAgICA8L3Byb3BlcnRpZXM+CisKKyAgICA8YnVpbGQ+CisJPHBsdWdpbnM+CisJICAgIDwhLS0KKwkJQ29uZmlndXJlIFNwb3RCdWdzIHRvIHJ1biB3aXRoICJtdm4gZmluZGJ1Z3M6ZmluZGJ1Z3MiCisJCWFuZCBnZW5lcmF0ZSBYTUwgb3V0cHV0IHRoYXQgY2FuIGJlIHVzZWQgYnkgdGhlIEh1ZHNvbgorCQlGaW5kQnVncyBwbHVnaW4uCisJICAgIC0tPgorCSAgICA8cGx1Z2luPgorCQk8Z3JvdXBJZD5jb20uZ2l0aHViLnNwb3RidWdzPC9ncm91cElkPgorCQk8YXJ0aWZhY3RJZD5zcG90YnVncy1tYXZlbi1wbHVnaW48L2FydGlmYWN0SWQ+CisJCTxjb25maWd1cmF0aW9uPgorCQkgICAgPHNraXA+ZmFsc2U8L3NraXA+CisJCSAgICA8dGhyZXNob2xkPiR7ZmluZGJ1Z3MudGhyZXNob2xkfTwvdGhyZXNob2xkPgorCQkgICAgPCEtLQorCQkgICAgPGV4Y2x1ZGVGaWx0ZXJGaWxlPgorCQkJJHtwcm9qZWN0LmJhc2VkaXJ9L2V4Y2x1ZGUueG1sCisJCSAgICA8L2V4Y2x1ZGVGaWx0ZXJGaWxlPgorCQkgICAgLS0+CisJCSAgICA8ZmluZGJ1Z3NYbWxXaXRoTWVzc2FnZXM+dHJ1ZTwvZmluZGJ1Z3NYbWxXaXRoTWVzc2FnZXM+CisJCTwvY29uZmlndXJhdGlvbj4KKwkgICAgPC9wbHVnaW4+CisJPC9wbHVnaW5zPgorICAgIDwvYnVpbGQ+CisKKyAgICA8ZGVwZW5kZW5jaWVzPgorICAgICAgICA8ZGVwZW5kZW5jeT4KKyAgICAgICAgICAgIDxncm91cElkPmNvbS5zdW4ubWFpbDwvZ3JvdXBJZD4KKyAgICAgICAgICAgIDxhcnRpZmFjdElkPmpha2FydGEubWFpbDwvYXJ0aWZhY3RJZD4KKyAgICAgICAgPC9kZXBlbmRlbmN5PgorCTxkZXBlbmRlbmN5PgorCSAgICA8Z3JvdXBJZD5qdW5pdDwvZ3JvdXBJZD4KKwkgICAgPGFydGlmYWN0SWQ+anVuaXQ8L2FydGlmYWN0SWQ+CisJICAgIDx2ZXJzaW9uPjQuMTI8L3ZlcnNpb24+CisJICAgIDxzY29wZT50ZXN0PC9zY29wZT4KKwkgICAgPG9wdGlvbmFsPnRydWU8L29wdGlvbmFsPgorCTwvZGVwZW5kZW5jeT4KKyAgICA8L2RlcGVuZGVuY2llcz4KKworICAgIDxyZXBvcnRpbmc+CisJPHBsdWdpbnM+CisJICAgIDwhLS0KKwkJQ29uZmlndXJlIFNwb3RCdWdzIHRvIHJ1biB3aXRoICJtdm4gc2l0ZSIgYW5kCisJCWdlbmVyYXRlIGh0bWwgb3V0cHV0IHRoYXQgY2FuIGJlIHZpZXdlZCBkaXJlY3RseS4KKwkgICAgLS0+CisJICAgIDxwbHVnaW4+CisJCTxncm91cElkPm9yZy5jb2RlaGF1cy5tb2pvPC9ncm91cElkPgorCQk8YXJ0aWZhY3RJZD5maW5kYnVncy1tYXZlbi1wbHVnaW48L2FydGlmYWN0SWQ+CisJCTxjb25maWd1cmF0aW9uPgorCQkgICAgPHNraXA+ZmFsc2U8L3NraXA+CisJCSAgICA8dGhyZXNob2xkPiR7ZmluZGJ1Z3MudGhyZXNob2xkfTwvdGhyZXNob2xkPgorCQkgICAgPCEtLQorCQkgICAgPGV4Y2x1ZGVGaWx0ZXJGaWxlPmV4Y2x1ZGUueG1sPC9leGNsdWRlRmlsdGVyRmlsZT4KKwkJICAgIC0tPgorCQk8L2NvbmZpZ3VyYXRpb24+CisJICAgIDwvcGx1Z2luPgorCTwvcGx1Z2lucz4KKyAgICA8L3JlcG9ydGluZz4KKzwvcHJvamVjdD4KZGlmZiAtLWdpdCBhL2Rzbi9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9kc24vRGVsaXZlcnlTdGF0dXMuamF2YSBiL2Rzbi9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9kc24vRGVsaXZlcnlTdGF0dXMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMjBlNmViCi0tLSAvZGV2L251bGwKKysrIGIvZHNuL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2Rzbi9EZWxpdmVyeVN0YXR1cy5qYXZhCkBAIC0wLDAgKzEsMTg4IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5kc247CisKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YS51dGlsLio7CitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTGV2ZWw7CisKK2ltcG9ydCBqYXZheC5hY3RpdmF0aW9uLio7CitpbXBvcnQgamF2YXgubWFpbC4qOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuKjsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLkxpbmVPdXRwdXRTdHJlYW07CS8vIFhYWAoraW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLlByb3BVdGlsOworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLk1haWxMb2dnZXI7CisKKy8qKgorICogQSBtZXNzYWdlL2RlbGl2ZXJ5LXN0YXR1cyBtZXNzYWdlIGNvbnRlbnQsIGFzIGRlZmluZWQgaW4KKyAqIDxBIEhSRUY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzM0NjQudHh0IiBUQVJHRVQ9Il90b3AiPlJGQyAzNDY0PC9BPi4KKyAqCisgKiBAc2luY2UJSmF2YU1haWwgMS40CisgKi8KK3B1YmxpYyBjbGFzcyBEZWxpdmVyeVN0YXR1cyBleHRlbmRzIFJlcG9ydCB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBNYWlsTG9nZ2VyIGxvZ2dlciA9IG5ldyBNYWlsTG9nZ2VyKAorCURlbGl2ZXJ5U3RhdHVzLmNsYXNzLAorCSJERUJVRyBEU04iLAorCVByb3BVdGlsLmdldEJvb2xlYW5TeXN0ZW1Qcm9wZXJ0eSgibWFpbC5kc24uZGVidWciLCBmYWxzZSksCisJU3lzdGVtLm91dCk7CisKKyAgICAvKioKKyAgICAgKiBUaGUgRFNOIGZpZWxkcyBmb3IgdGhlIG1lc3NhZ2UuCisgICAgICovCisgICAgcHJvdGVjdGVkIEludGVybmV0SGVhZGVycyBtZXNzYWdlRFNOOworCisgICAgLyoqCisgICAgICogVGhlIERTTiBmaWVsZHMgZm9yIGVhY2ggcmVjaXBpZW50LgorICAgICAqLworICAgIHByb3RlY3RlZCBJbnRlcm5ldEhlYWRlcnNbXSByZWNpcGllbnREU047CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYSBkZWxpdmVyeSBzdGF0dXMgbm90aWZpY2F0aW9uIHdpdGggbm8gY29udGVudC4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBEZWxpdmVyeVN0YXR1cygpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXN1cGVyKCJkZWxpdmVyeS1zdGF0dXMiKTsKKwltZXNzYWdlRFNOID0gbmV3IEludGVybmV0SGVhZGVycygpOworCXJlY2lwaWVudERTTiA9IG5ldyBJbnRlcm5ldEhlYWRlcnNbMF07CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGEgZGVsaXZlcnkgc3RhdHVzIG5vdGlmaWNhdGlvbiBieSBwYXJzaW5nIHRoZQorICAgICAqIHN1cHBsaWVkIGlucHV0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbQlpcwl0aGUgaW5wdXQgc3RyZWFtCisgICAgICogQGV4Y2VwdGlvbglJT0V4Y2VwdGlvbiBmb3IgSS9PIGVycm9ycyByZWFkaW5nIHRoZSBzdHJlYW0KKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgRGVsaXZlcnlTdGF0dXMoSW5wdXRTdHJlYW0gaXMpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworCXN1cGVyKCJkZWxpdmVyeS1zdGF0dXMiKTsKKwltZXNzYWdlRFNOID0gbmV3IEludGVybmV0SGVhZGVycyhpcyk7CisJbG9nZ2VyLmZpbmUoImdvdCBtZXNzYWdlRFNOIik7CisJVmVjdG9yPEludGVybmV0SGVhZGVycz4gdiA9IG5ldyBWZWN0b3I8PigpOworCXRyeSB7CisJICAgIHdoaWxlIChpcy5hdmFpbGFibGUoKSA+IDApIHsKKwkJSW50ZXJuZXRIZWFkZXJzIGggPSBuZXcgSW50ZXJuZXRIZWFkZXJzKGlzKTsKKwkJbG9nZ2VyLmZpbmUoImdvdCByZWNpcGllbnREU04iKTsKKwkJdi5hZGRFbGVtZW50KGgpOworCSAgICB9CisJfSBjYXRjaCAoRU9GRXhjZXB0aW9uIGV4KSB7CisJICAgIGxvZ2dlci5sb2coTGV2ZWwuRklORSwgImdvdCBFT0ZFeGNlcHRpb24iLCBleCk7CisJfQorCWlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FKSkKKwkgICAgbG9nZ2VyLmZpbmUoInJlY2lwaWVudERTTiBzaXplICIgKyB2LnNpemUoKSk7CisJcmVjaXBpZW50RFNOID0gbmV3IEludGVybmV0SGVhZGVyc1t2LnNpemUoKV07CisJdi5jb3B5SW50byhyZWNpcGllbnREU04pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiBhbGwgdGhlIHBlci1tZXNzYWdlIGZpZWxkcyBpbiB0aGUgZGVsaXZlcnkgc3RhdHVzIG5vdGlmaWNhdGlvbi4KKyAgICAgKiBUaGUgZmllbGRzIGFyZSBkZWZpbmVkIGFzOgorICAgICAqCisgICAgICogPHByZT4KKyAgICAgKiAgICBwZXItbWVzc2FnZS1maWVsZHMgPQorICAgICAqICAgICAgICAgIFsgb3JpZ2luYWwtZW52ZWxvcGUtaWQtZmllbGQgQ1JMRiBdCisgICAgICogICAgICAgICAgcmVwb3J0aW5nLW10YS1maWVsZCBDUkxGCisgICAgICogICAgICAgICAgWyBkc24tZ2F0ZXdheS1maWVsZCBDUkxGIF0KKyAgICAgKiAgICAgICAgICBbIHJlY2VpdmVkLWZyb20tbXRhLWZpZWxkIENSTEYgXQorICAgICAqICAgICAgICAgIFsgYXJyaXZhbC1kYXRlLWZpZWxkIENSTEYgXQorICAgICAqICAgICAgICAgICooIGV4dGVuc2lvbi1maWVsZCBDUkxGICkKKyAgICAgKiA8L3ByZT4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIHBlci1tZXNzYWdlIERTTiBmaWVsZHMKKyAgICAgKi8KKyAgICAvLyBYWFggLSBjb3VsZCBwYXJzZSBlYWNoIG9mIHRoZXNlIGZpZWxkcworICAgIHB1YmxpYyBJbnRlcm5ldEhlYWRlcnMgZ2V0TWVzc2FnZURTTigpIHsKKwlyZXR1cm4gbWVzc2FnZURTTjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHBlci1tZXNzYWdlIGZpZWxkcyBpbiB0aGUgZGVsaXZlcnkgc3RhdHVzIG5vdGlmaWNhdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbQltZXNzYWdlRFNOCXRoZSBwZXItbWVzc2FnZSBEU04gZmllbGRzCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TWVzc2FnZURTTihJbnRlcm5ldEhlYWRlcnMgbWVzc2FnZURTTikgeworCXRoaXMubWVzc2FnZURTTiA9IG1lc3NhZ2VEU047CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBudW1iZXIgb2YgcmVjaXBpZW50cyBmb3Igd2hpY2ggd2UgaGF2ZQorICAgICAqIHBlci1yZWNpcGllbnQgZGVsaXZlcnkgc3RhdHVzIG5vdGlmaWNhdGlvbiBpbmZvcm1hdGlvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIG51bWJlciBvZiByZWNpcGllbnRzCisgICAgICovCisgICAgcHVibGljIGludCBnZXRSZWNpcGllbnREU05Db3VudCgpIHsKKwlyZXR1cm4gcmVjaXBpZW50RFNOLmxlbmd0aDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIGRlbGl2ZXJ5IHN0YXR1cyBub3RpZmljYXRpb24gaW5mb3JtYXRpb24gZm9yCisgICAgICogdGhlIHNwZWNpZmllZCByZWNpcGllbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jbgl0aGUgcmVjaXBpZW50IG51bWJlcgorICAgICAqIEByZXR1cm4JdGhlIERTTiBmaWVsZHMgZm9yIHRoZSByZWNpcGllbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgSW50ZXJuZXRIZWFkZXJzIGdldFJlY2lwaWVudERTTihpbnQgbikgeworCXJldHVybiByZWNpcGllbnREU05bbl07CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkIGRlbGl2ZXIgc3RhdHVzIG5vdGlmaWNhdGlvbiBpbmZvcm1hdGlvbiBmb3IgYW5vdGhlcgorICAgICAqIHJlY2lwaWVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbQloCXRoZSBEU04gZmllbGRzIGZvciB0aGUgcmVjaXBpZW50CisgICAgICovCisgICAgcHVibGljIHZvaWQgYWRkUmVjaXBpZW50RFNOKEludGVybmV0SGVhZGVycyBoKSB7CisJSW50ZXJuZXRIZWFkZXJzW10gcmggPSBuZXcgSW50ZXJuZXRIZWFkZXJzW3JlY2lwaWVudERTTi5sZW5ndGggKyAxXTsKKwlTeXN0ZW0uYXJyYXljb3B5KHJlY2lwaWVudERTTiwgMCwgcmgsIDAsIHJlY2lwaWVudERTTi5sZW5ndGgpOworCXJlY2lwaWVudERTTiA9IHJoOworCXJlY2lwaWVudERTTltyZWNpcGllbnREU04ubGVuZ3RoIC0gMV0gPSBoOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oT3V0cHV0U3RyZWFtIG9zKSB0aHJvd3MgSU9FeGNlcHRpb24geworCS8vIHNlZSBpZiB3ZSBhbHJlYWR5IGhhdmUgYSBMT1MKKwlMaW5lT3V0cHV0U3RyZWFtIGxvcyA9IG51bGw7CisJaWYgKG9zIGluc3RhbmNlb2YgTGluZU91dHB1dFN0cmVhbSkgeworCSAgICBsb3MgPSAoTGluZU91dHB1dFN0cmVhbSkgb3M7CisJfSBlbHNlIHsKKwkgICAgbG9zID0gbmV3IExpbmVPdXRwdXRTdHJlYW0ob3MpOworCX0KKworCXdyaXRlSW50ZXJuZXRIZWFkZXJzKG1lc3NhZ2VEU04sIGxvcyk7CisJbG9zLndyaXRlbG4oKTsKKwlmb3IgKGludCBpID0gMDsgaSA8IHJlY2lwaWVudERTTi5sZW5ndGg7IGkrKykgeworCSAgICB3cml0ZUludGVybmV0SGVhZGVycyhyZWNpcGllbnREU05baV0sIGxvcyk7CisJICAgIGxvcy53cml0ZWxuKCk7CisJfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgd3JpdGVJbnRlcm5ldEhlYWRlcnMoSW50ZXJuZXRIZWFkZXJzIGgsCisJCQkJTGluZU91dHB1dFN0cmVhbSBsb3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJRW51bWVyYXRpb24gZSA9IGguZ2V0QWxsSGVhZGVyTGluZXMoKTsKKwl3aGlsZSAoZS5oYXNNb3JlRWxlbWVudHMoKSkKKwkgICAgbG9zLndyaXRlbG4oKFN0cmluZyllLm5leHRFbGVtZW50KCkpOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisJcmV0dXJuICJEZWxpdmVyeVN0YXR1czogUmVwb3J0aW5nLU1UQT0iICsKKwkgICAgbWVzc2FnZURTTi5nZXRIZWFkZXIoIlJlcG9ydGluZy1NVEEiLCBudWxsKSArICIsICNSZWNpcGllbnRzPSIgKworCSAgICByZWNpcGllbnREU04ubGVuZ3RoOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2Rzbi9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9kc24vRGlzcG9zaXRpb25Ob3RpZmljYXRpb24uamF2YSBiL2Rzbi9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9kc24vRGlzcG9zaXRpb25Ob3RpZmljYXRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zMGY2ZTlkCi0tLSAvZGV2L251bGwKKysrIGIvZHNuL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2Rzbi9EaXNwb3NpdGlvbk5vdGlmaWNhdGlvbi5qYXZhCkBAIC0wLDAgKzEsMTMzIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5kc247CisKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YS51dGlsLio7CisKK2ltcG9ydCBqYXZheC5tYWlsLio7CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC4qOworCitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuTGluZU91dHB1dFN0cmVhbTsJLy8gWFhYCitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuUHJvcFV0aWw7CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuTWFpbExvZ2dlcjsKKworLyoqCisgKiBBIG1lc3NhZ2UvZGlzcG9zaXRpb24tbm90aWZpY2F0aW9uIG1lc3NhZ2UgY29udGVudCwgYXMgZGVmaW5lZCBpbgorICogPEEgSFJFRj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzc5OC50eHQiIFRBUkdFVD0iX3RvcCI+UkZDIDM3OTg8L0E+LgorICoKKyAqIEBzaW5jZQlKYXZhTWFpbCAxLjQuMgorICovCitwdWJsaWMgY2xhc3MgRGlzcG9zaXRpb25Ob3RpZmljYXRpb24gZXh0ZW5kcyBSZXBvcnQgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgTWFpbExvZ2dlciBsb2dnZXIgPSBuZXcgTWFpbExvZ2dlcigKKwlEZWxpdmVyeVN0YXR1cy5jbGFzcywKKwkiREVCVUcgRFNOIiwKKwlQcm9wVXRpbC5nZXRCb29sZWFuU3lzdGVtUHJvcGVydHkoIm1haWwuZHNuLmRlYnVnIiwgZmFsc2UpLAorCVN5c3RlbS5vdXQpOworCisgICAgLyoqCisgICAgICogVGhlIGRpc3Bvc2l0aW9uIG5vdGlmaWNhdGlvbiBjb250ZW50IGZpZWxkcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgSW50ZXJuZXRIZWFkZXJzIG5vdGlmaWNhdGlvbnM7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYSBkaXNwb3NpdGlvbiBub3RpZmljYXRpb24gd2l0aCBubyBjb250ZW50LgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIERpc3Bvc2l0aW9uTm90aWZpY2F0aW9uKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJc3VwZXIoImRpc3Bvc2l0aW9uLW5vdGlmaWNhdGlvbiIpOworCW5vdGlmaWNhdGlvbnMgPSBuZXcgSW50ZXJuZXRIZWFkZXJzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGEgZGlzcG9zaXRpb24gbm90aWZpY2F0aW9uIGJ5IHBhcnNpbmcgdGhlCisgICAgICogc3VwcGxpZWQgaW5wdXQgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtCWlzCXRoZSBpbnB1dCBzdHJlYW0KKyAgICAgKiBAZXhjZXB0aW9uCUlPRXhjZXB0aW9uIGZvciBJL08gZXJyb3JzIHJlYWRpbmcgdGhlIHN0cmVhbQorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBvdGhlciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBEaXNwb3NpdGlvbk5vdGlmaWNhdGlvbihJbnB1dFN0cmVhbSBpcykKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisJc3VwZXIoImRpc3Bvc2l0aW9uLW5vdGlmaWNhdGlvbiIpOworCW5vdGlmaWNhdGlvbnMgPSBuZXcgSW50ZXJuZXRIZWFkZXJzKGlzKTsKKwlsb2dnZXIuZmluZSgiZ290IE1ETiBub3RpZmljYXRpb24gY29udGVudCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiBhbGwgdGhlIGRpc3Bvc2l0aW9uIG5vdGlmaWNhdGlvbiBmaWVsZHMgaW4gdGhlCisgICAgICogZGlzcG9zaXRpb24gbm90aWZpY2F0aW9uLgorICAgICAqIFRoZSBmaWVsZHMgYXJlIGRlZmluZWQgYXM6CisgICAgICoKKyAgICAgKiA8cHJlPgorICAgICAqICAgIGRpc3Bvc2l0aW9uLW5vdGlmaWNhdGlvbi1jb250ZW50ID0KKyAgICAgKgkJWyByZXBvcnRpbmctdWEtZmllbGQgQ1JMRiBdCisgICAgICoJCVsgbWRuLWdhdGV3YXktZmllbGQgQ1JMRiBdCisgICAgICoJCVsgb3JpZ2luYWwtcmVjaXBpZW50LWZpZWxkIENSTEYgXQorICAgICAqCQlmaW5hbC1yZWNpcGllbnQtZmllbGQgQ1JMRgorICAgICAqCQlbIG9yaWdpbmFsLW1lc3NhZ2UtaWQtZmllbGQgQ1JMRiBdCisgICAgICoJCWRpc3Bvc2l0aW9uLWZpZWxkIENSTEYKKyAgICAgKgkJKiggZmFpbHVyZS1maWVsZCBDUkxGICkKKyAgICAgKgkJKiggZXJyb3ItZmllbGQgQ1JMRiApCisgICAgICoJCSooIHdhcm5pbmctZmllbGQgQ1JMRiApCisgICAgICoJCSooIGV4dGVuc2lvbi1maWVsZCBDUkxGICkKKyAgICAgKiA8L3ByZT4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIERTTiBmaWVsZHMKKyAgICAgKi8KKyAgICAvLyBYWFggLSBjb3VsZCBwYXJzZSBlYWNoIG9mIHRoZXNlIGZpZWxkcworICAgIHB1YmxpYyBJbnRlcm5ldEhlYWRlcnMgZ2V0Tm90aWZpY2F0aW9ucygpIHsKKwlyZXR1cm4gbm90aWZpY2F0aW9uczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIGRpc3Bvc2l0aW9uIG5vdGlmaWNhdGlvbiBmaWVsZHMgaW4gdGhlCisgICAgICogZGlzcG9zaXRpb24gbm90aWZpY2F0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtCW5vdGlmaWNhdGlvbnMJdGhlIERTTiBmaWVsZHMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXROb3RpZmljYXRpb25zKEludGVybmV0SGVhZGVycyBub3RpZmljYXRpb25zKSB7CisJdGhpcy5ub3RpZmljYXRpb25zID0gbm90aWZpY2F0aW9uczsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKE91dHB1dFN0cmVhbSBvcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkvLyBzZWUgaWYgd2UgYWxyZWFkeSBoYXZlIGEgTE9TCisJTGluZU91dHB1dFN0cmVhbSBsb3MgPSBudWxsOworCWlmIChvcyBpbnN0YW5jZW9mIExpbmVPdXRwdXRTdHJlYW0pIHsKKwkgICAgbG9zID0gKExpbmVPdXRwdXRTdHJlYW0pIG9zOworCX0gZWxzZSB7CisJICAgIGxvcyA9IG5ldyBMaW5lT3V0cHV0U3RyZWFtKG9zKTsKKwl9CisKKwl3cml0ZUludGVybmV0SGVhZGVycyhub3RpZmljYXRpb25zLCBsb3MpOworCWxvcy53cml0ZWxuKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCB3cml0ZUludGVybmV0SGVhZGVycyhJbnRlcm5ldEhlYWRlcnMgaCwKKwkJCQlMaW5lT3V0cHV0U3RyZWFtIGxvcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlFbnVtZXJhdGlvbiBlID0gaC5nZXRBbGxIZWFkZXJMaW5lcygpOworCXdoaWxlIChlLmhhc01vcmVFbGVtZW50cygpKQorCSAgICBsb3Mud3JpdGVsbigoU3RyaW5nKWUubmV4dEVsZW1lbnQoKSk7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKwlyZXR1cm4gIkRpc3Bvc2l0aW9uTm90aWZpY2F0aW9uOiBSZXBvcnRpbmctVUE9IiArCisJICAgIG5vdGlmaWNhdGlvbnMuZ2V0SGVhZGVyKCJSZXBvcnRpbmctVUEiLCBudWxsKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9kc24vc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvZHNuL01lc3NhZ2VIZWFkZXJzLmphdmEgYi9kc24vc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvZHNuL01lc3NhZ2VIZWFkZXJzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWFjZGVhMAotLS0gL2Rldi9udWxsCisrKyBiL2Rzbi9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9kc24vTWVzc2FnZUhlYWRlcnMuamF2YQpAQCAtMCwwICsxLDkxIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5kc247CisKK2ltcG9ydCBqYXZhLmlvLio7CisKK2ltcG9ydCBqYXZheC5hY3RpdmF0aW9uLio7CitpbXBvcnQgamF2YXgubWFpbC4qOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuKjsKKworLyoqCisgKiBBIHNwZWNpYWwgTWltZU1lc3NhZ2Ugb2JqZWN0IHRoYXQgY29udGFpbnMgb25seSBtZXNzYWdlIGhlYWRlcnMsCisgKiBubyBjb250ZW50LiAgVXNlZCB0byByZXByZXNlbnQgdGhlIE1JTUUgdHlwZSB0ZXh0L3JmYzgyMi1oZWFkZXJzLgorICoKKyAqIEBzaW5jZQlKYXZhTWFpbCAxLjQKKyAqLworcHVibGljIGNsYXNzIE1lc3NhZ2VIZWFkZXJzIGV4dGVuZHMgTWltZU1lc3NhZ2UgeworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGEgTWVzc2FnZUhlYWRlcnMgb2JqZWN0LgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIE1lc3NhZ2VIZWFkZXJzKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJc3VwZXIoKFNlc3Npb24pbnVsbCk7CisJY29udGVudCA9IG5ldyBieXRlWzBdOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBNZXNzYWdlSGVhZGVycyBvYmplY3QgZnJvbSB0aGUgZ2l2ZW4gSW5wdXRTdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0JaXMJSW5wdXRTdHJlYW0KKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgTWVzc2FnZUhlYWRlcnMoSW5wdXRTdHJlYW0gaXMpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXN1cGVyKG51bGwsIGlzKTsKKwljb250ZW50ID0gbmV3IGJ5dGVbMF07CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIE1lc3NhZ2VIZWFkZXJzIG9iamVjdCB1c2luZyB0aGUgZ2l2ZW4gSW50ZXJuZXRIZWFkZXJzLgorICAgICAqCisgICAgICogQHBhcmFtCWhlYWRlcnMJSW50ZXJuZXRIZWFkZXJzIHRvIHVzZQorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBNZXNzYWdlSGVhZGVycyhJbnRlcm5ldEhlYWRlcnMgaGVhZGVycykgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJc3VwZXIoKFNlc3Npb24pbnVsbCk7CisJdGhpcy5oZWFkZXJzID0gaGVhZGVyczsKKwljb250ZW50ID0gbmV3IGJ5dGVbMF07CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBzaXplIG9mIHRoaXMgbWVzc2FnZS4KKyAgICAgKiBBbHdheXMgcmV0dXJucyB6ZXJvLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0U2l6ZSgpIHsKKwlyZXR1cm4gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgSW5wdXRTdHJlYW0gZ2V0SW5wdXRTdHJlYW0oKSB7CisJcmV0dXJuIG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShjb250ZW50KTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgSW5wdXRTdHJlYW0gZ2V0Q29udGVudFN0cmVhbSgpIHsKKwlyZXR1cm4gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGNvbnRlbnQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENhbid0IHNldCBhbnkgY29udGVudCBmb3IgYSBNZXNzYWdlSGVhZGVycyBvYmplY3QuCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbglhbHdheXMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXREYXRhSGFuZGxlcihEYXRhSGFuZGxlciBkaCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiQ2FuJ3Qgc2V0IGNvbnRlbnQgZm9yIE1lc3NhZ2VIZWFkZXJzIik7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9kc24vc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvZHNuL011bHRpcGFydFJlcG9ydC5qYXZhIGIvZHNuL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2Rzbi9NdWx0aXBhcnRSZXBvcnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZTE5ZWZlCi0tLSAvZGV2L251bGwKKysrIGIvZHNuL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2Rzbi9NdWx0aXBhcnRSZXBvcnQuamF2YQpAQCAtMCwwICsxLDQzMCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuZHNuOworCitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7CisKK2ltcG9ydCBqYXZheC5hY3RpdmF0aW9uLio7CitpbXBvcnQgamF2YXgubWFpbC4qOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuKjsKKworLyoqCisgKiBBIG11bHRpcGFydC9yZXBvcnQgbWVzc2FnZSBjb250ZW50LCBhcyBkZWZpbmVkIGluCisgKiA8QSBIUkVGPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMzNDYyLnR4dCIgVEFSR0VUPSJfdG9wIj5SRkMgMzQ2MjwvQT4uCisgKiBBIG11bHRpcGFydC9yZXBvcnQgY29udGVudCBpcyBhIGNvbnRhaW5lciBmb3IgbWFpbCByZXBvcnRzCisgKiBvZiBhbnkga2luZCwgYW5kIGlzIG1vc3Qgb2Z0ZW4gdXNlZCB0byByZXR1cm4gYSBkZWxpdmVyeQorICogc3RhdHVzIHJlcG9ydCBvciBhIGRpc3Bvc2l0aW9uIG5vdGlmaWNhdGlvbiByZXBvcnQuIDxwPgorICoKKyAqIEEgTXVsdGlwYXJ0UmVwb3J0IG9iamVjdCBpcyBhIHNwZWNpYWwgdHlwZSBvZiBNaW1lTXVsdGlwYXJ0CisgKiBvYmplY3Qgd2l0aCBhIHJlc3RyaWN0ZWQgc2V0IG9mIGJvZHkgcGFydHMuICBBIE11bHRpcGFydFJlcG9ydAorICogb2JqZWN0IGNvbnRhaW5zOgorICogPHVsPgorICogPGxpPltSZXF1aXJlZF0gQSBodW1hbiByZWFkYWJsZSB0ZXh0IG1lc3NhZ2UgZGVzY3JpYmluZyB0aGUKKyAqIHJlYXNvbiB0aGUgcmVwb3J0IHdhcyBnZW5lcmF0ZWQuPC9saT4KKyAqIDxsaT5bUmVxdWlyZWRdIEEge0BsaW5rIFJlcG9ydH0gb2JqZWN0IGNvbnRhaW5pbmcgdGhlCisgKiBkZXRhaWxzIGZvciB3aHkgdGhlIHJlcG9ydCB3YXMgZ2VuZXJhdGVkLjwvbGk+CisgKiA8bGk+W09wdGlvbmFsXSBBIHJldHVybmVkIGNvcHkgb2YgdGhlIGVudGlyZSBtZXNzYWdlLCBvciBqdXN0CisgKiBpdHMgaGVhZGVycywgd2hpY2ggY2F1c2VkIHRoZSBnZW5lcmF0aW9uIG9mIHRoaXMgcmVwb3J0LgorICogPC91bD4KKyAqIE1hbnkgb2YgdGhlIG5vcm1hbCBNaW1lTXVsdGlwYXJ0IG9wZXJhdGlvbnMgYXJlIHJlc3RyaWN0ZWQgdG8KKyAqIGVuc3VyZSB0aGF0IHRoZSBNdWx0aXBhcnRSZXBvcnQgb2JqZWN0IGFsd2F5cyBmb2xsb3dzIHRoaXMKKyAqIHN0cnVjdHVyZS4KKyAqCisgKiBAc2luY2UJSmF2YU1haWwgMS40CisgKi8KK3B1YmxpYyBjbGFzcyBNdWx0aXBhcnRSZXBvcnQgZXh0ZW5kcyBNaW1lTXVsdGlwYXJ0IHsKKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBjb25zdHJ1Y3RlZDsgLy8gdHJ1ZSB3aGVuIGRvbmUgd2l0aCBjb25zdHJ1Y3RvcgorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGEgbXVsdGlwYXJ0L3JlcG9ydCBvYmplY3Qgd2l0aCBubyBjb250ZW50LgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIE11bHRpcGFydFJlcG9ydCgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXN1cGVyKCJyZXBvcnQiKTsKKwkvLyBhbHdheXMgYXQgbGVhc3QgdHdvIGJvZHkgcGFydHMKKwlNaW1lQm9keVBhcnQgbWJwID0gbmV3IE1pbWVCb2R5UGFydCgpOworCXNldEJvZHlQYXJ0KG1icCwgMCk7CisJbWJwID0gbmV3IE1pbWVCb2R5UGFydCgpOworCXNldEJvZHlQYXJ0KG1icCwgMSk7CisJY29uc3RydWN0ZWQgPSB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCBhIG11bHRpcGFydC9yZXBvcnQgb2JqZWN0IHdpdGggdGhlIHNwZWNpZmllZCBwbGFpbgorICAgICAqIHRleHQgYW5kIHJlcG9ydCB0eXBlIChEZWxpdmVyeVN0YXR1cyBvciBEaXNwb3NpdGlvbk5vdGlmaWNhdGlvbikKKyAgICAgKiB0byBiZSByZXR1cm5lZCB0byB0aGUgdXNlci4KKyAgICAgKgorICAgICAqIEBwYXJhbQl0ZXh0CXRoZSBwbGFpbiB0ZXh0CisgICAgICogQHBhcmFtCXJlcG9ydAl0aGUgUmVwb3J0IG9iamVjdAorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBNdWx0aXBhcnRSZXBvcnQoU3RyaW5nIHRleHQsIFJlcG9ydCByZXBvcnQpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJc3VwZXIoInJlcG9ydCIpOworCUNvbnRlbnRUeXBlIGN0ID0gbmV3IENvbnRlbnRUeXBlKGNvbnRlbnRUeXBlKTsKKwlTdHJpbmcgcmVwb3J0VHlwZSA9IHJlcG9ydC5nZXRUeXBlKCk7CisJY3Quc2V0UGFyYW1ldGVyKCJyZXBvcnQtdHlwZSIsIHJlcG9ydFR5cGUpOworCWNvbnRlbnRUeXBlID0gY3QudG9TdHJpbmcoKTsKKwlNaW1lQm9keVBhcnQgbWJwID0gbmV3IE1pbWVCb2R5UGFydCgpOworCW1icC5zZXRUZXh0KHRleHQpOworCXNldEJvZHlQYXJ0KG1icCwgMCk7CisJbWJwID0gbmV3IE1pbWVCb2R5UGFydCgpOworCWN0ID0gbmV3IENvbnRlbnRUeXBlKCJtZXNzYWdlIiwgcmVwb3J0VHlwZSwgbnVsbCk7CisJbWJwLnNldENvbnRlbnQocmVwb3J0LCBjdC50b1N0cmluZygpKTsKKwlzZXRCb2R5UGFydChtYnAsIDEpOworCWNvbnN0cnVjdGVkID0gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYSBtdWx0aXBhcnQvcmVwb3J0IG9iamVjdCB3aXRoIHRoZSBzcGVjaWZpZWQgcGxhaW4KKyAgICAgKiB0ZXh0LCByZXBvcnQsIGFuZCBvcmlnaW5hbCBtZXNzYWdlIHRvIGJlIHJldHVybmVkIHRvIHRoZSB1c2VyLgorICAgICAqCisgICAgICogQHBhcmFtCXRleHQJdGhlIHBsYWluIHRleHQKKyAgICAgKiBAcGFyYW0JcmVwb3J0CXRoZSBSZXBvcnQgb2JqZWN0CisgICAgICogQHBhcmFtCW1zZwl0aGUgbWVzc2FnZSB0aGlzIHJlcG9ydCBpcyBhYm91dAorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBNdWx0aXBhcnRSZXBvcnQoU3RyaW5nIHRleHQsIFJlcG9ydCByZXBvcnQsIE1pbWVNZXNzYWdlIG1zZykKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwl0aGlzKHRleHQsIHJlcG9ydCk7CisJaWYgKG1zZyAhPSBudWxsKSB7CisJICAgIE1pbWVCb2R5UGFydCBtYnAgPSBuZXcgTWltZUJvZHlQYXJ0KCk7CisJICAgIG1icC5zZXRDb250ZW50KG1zZywgIm1lc3NhZ2UvcmZjODIyIik7CisJICAgIHNldEJvZHlQYXJ0KG1icCwgMik7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCBhIG11bHRpcGFydC9yZXBvcnQgb2JqZWN0IHdpdGggdGhlIHNwZWNpZmllZCBwbGFpbgorICAgICAqIHRleHQsIHJlcG9ydCwgYW5kIGhlYWRlcnMgZnJvbSB0aGUgb3JpZ2luYWwgbWVzc2FnZQorICAgICAqIHRvIGJlIHJldHVybmVkIHRvIHRoZSB1c2VyLgorICAgICAqCisgICAgICogQHBhcmFtCXRleHQJdGhlIHBsYWluIHRleHQKKyAgICAgKiBAcGFyYW0JcmVwb3J0CXRoZSBSZXBvcnQgb2JqZWN0CisgICAgICogQHBhcmFtCWhkcgl0aGUgaGVhZGVycyBvZiB0aGUgbWVzc2FnZSB0aGlzIHJlcG9ydCBpcyBhYm91dAorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBNdWx0aXBhcnRSZXBvcnQoU3RyaW5nIHRleHQsIFJlcG9ydCByZXBvcnQsIEludGVybmV0SGVhZGVycyBoZHIpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJdGhpcyh0ZXh0LCByZXBvcnQpOworCWlmIChoZHIgIT0gbnVsbCkgeworCSAgICBNaW1lQm9keVBhcnQgbWJwID0gbmV3IE1pbWVCb2R5UGFydCgpOworCSAgICBtYnAuc2V0Q29udGVudChuZXcgTWVzc2FnZUhlYWRlcnMoaGRyKSwgInRleHQvcmZjODIyLWhlYWRlcnMiKTsKKwkgICAgc2V0Qm9keVBhcnQobWJwLCAyKTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIE11bHRpcGFydFJlcG9ydCBvYmplY3QgYW5kIGl0cyBib2R5cGFydHMgZnJvbSB0aGUgCisgICAgICogZ2l2ZW4gRGF0YVNvdXJjZS4gPHA+CisgICAgICoKKyAgICAgKiBAcGFyYW0JZHMJRGF0YVNvdXJjZSwgY2FuIGJlIGEgTXVsdGlwYXJ0RGF0YVNvdXJjZQorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBNdWx0aXBhcnRSZXBvcnQoRGF0YVNvdXJjZSBkcykgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJc3VwZXIoZHMpOworCXBhcnNlKCk7CisJY29uc3RydWN0ZWQgPSB0cnVlOworCS8qCisJICogQ2FuJ3QgZmFpbCB0byBjb25zdHJ1Y3Qgb2JqZWN0IGJlY2F1c2Ugc29tZSBwcm9ncmFtcyBqdXN0CisJICogd2FudCB0byB0cmVhdCB0aGlzIGFzIGEgTXVsdGlwYXJ0IGFuZCBleGFtaW5lIHRoZSBwYXJ0cy4KKwkgKgorCWlmIChnZXRDb3VudCgpIDwgMiB8fCBnZXRDb3VudCgpID4gMykJLy8gWFhYIGFsbG93IGV4dHJhIHBhcnRzCisJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oCisJCSJXcm9uZyBudW1iZXIgb2YgcGFydHMgaW4gbXVsdGlwYXJ0L3JlcG9ydDogIiArIGdldENvdW50KCkpOworCSAqLworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgcGxhaW4gdGV4dCB0byBiZSBwcmVzZW50ZWQgdG8gdGhlIHVzZXIsIGlmIHRoZXJlIGlzIGFueS4KKyAgICAgKiBSYXJlbHksIHRoZSBtZXNzYWdlIG1heSBjb250YWluIG9ubHkgSFRNTCB0ZXh0LCBvciBubyB0ZXh0IGF0CisgICAgICogYWxsLiAgSWYgdGhlIHRleHQgYm9keSBwYXJ0IG9mIHRoaXMgbXVsdGlwYXJ0L3JlcG9ydCBvYmplY3QgaXMKKyAgICAgKiBvZiB0eXBlIHRleHQvcGxhaW4sIG9yIGlmIGl0IGlzIG9mIHR5cGUgbXVsdGlwYXJ0L2FsdGVybmF0aXZlCisgICAgICogYW5kIGNvbnRhaW5zIGEgdGV4dC9wbGFpbiBwYXJ0LCB0aGUgdGV4dCBmcm9tIHRoYXQgcGFydCBpcworICAgICAqIHJldHVybmVkLiAgT3RoZXJ3aXNlLCBudWxsIGlzIHJldHVybiBhbmQgdGhlIHtAbGluayAjZ2V0VGV4dEJvZHlQYXJ0CisgICAgICogZ2V0VGV4dEJvZHlQYXJ0fSBtZXRob2QgbWF5IGJlIHVzZWQgdG8gZXh0cmFjdCB0aGUgZGF0YS4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIHRleHQKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIFN0cmluZyBnZXRUZXh0KCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJdHJ5IHsKKwkgICAgQm9keVBhcnQgYnAgPSBnZXRCb2R5UGFydCgwKTsKKwkgICAgaWYgKGJwLmlzTWltZVR5cGUoInRleHQvcGxhaW4iKSkKKwkJcmV0dXJuIChTdHJpbmcpYnAuZ2V0Q29udGVudCgpOworCSAgICBpZiAoYnAuaXNNaW1lVHlwZSgibXVsdGlwYXJ0L2FsdGVybmF0aXZlIikpIHsKKwkJTXVsdGlwYXJ0IG1wID0gKE11bHRpcGFydClicC5nZXRDb250ZW50KCk7CisJCWZvciAoaW50IGkgPSAwOyBpIDwgbXAuZ2V0Q291bnQoKTsgaSsrKSB7CisJCSAgICBicCA9IG1wLmdldEJvZHlQYXJ0KGkpOworCQkgICAgaWYgKGJwLmlzTWltZVR5cGUoInRleHQvcGxhaW4iKSkKKwkJCXJldHVybiAoU3RyaW5nKWJwLmdldENvbnRlbnQoKTsKKwkJfQorCSAgICB9CisJfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiRXhjZXB0aW9uIGdldHRpbmcgdGV4dCBjb250ZW50IiwgZXgpOworCX0KKwlyZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIG1lc3NhZ2UgdG8gYmUgcHJlc2VudGVkIHRvIHRoZSB1c2VyIGFzIGp1c3QgYSB0ZXh0L3BsYWluCisgICAgICogcGFydCBjb250YWluaW5nIHRoZSBzcGVjaWZpZWQgdGV4dC4KKyAgICAgKgorICAgICAqIEBwYXJhbQl0ZXh0CXRoZSB0ZXh0CisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHNldFRleHQoU3RyaW5nIHRleHQpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCU1pbWVCb2R5UGFydCBtYnAgPSBuZXcgTWltZUJvZHlQYXJ0KCk7CisJbWJwLnNldFRleHQodGV4dCk7CisJc2V0Qm9keVBhcnQobWJwLCAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIGJvZHkgcGFydCBjb250YWluaW5nIHRoZSBtZXNzYWdlIHRvIGJlIHByZXNlbnRlZCB0bworICAgICAqIHRoZSB1c2VyLCB1c3VhbGx5IGp1c3QgYSB0ZXh0L3BsYWluIHBhcnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBib2R5IHBhcnQgY29udGFpbmluZyB0aGUgdGV4dAorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgTWltZUJvZHlQYXJ0IGdldFRleHRCb2R5UGFydCgpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJcmV0dXJuIChNaW1lQm9keVBhcnQpZ2V0Qm9keVBhcnQoMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBib2R5IHBhcnQgY29udGFpbmluZyB0aGUgdGV4dCB0byBiZSBwcmVzZW50ZWQgdG8gdGhlCisgICAgICogdXNlci4gIFVzdWFsbHkgdGhpcyBhIHRleHQvcGxhaW4gcGFydCwgYnV0IGl0IG1pZ2h0IGFsc28gYmUKKyAgICAgKiBhIHRleHQvaHRtbCBwYXJ0IG9yIGEgbXVsdGlwYXJ0L2FsdGVybmF0aXZlIHBhcnQgY29udGFpbmluZworICAgICAqIHRleHQvcGxhaW4gYW5kIHRleHQvaHRtbCBwYXJ0cy4gIEFueSB0eXBlIGlzIGFsbG93ZWQgaGVyZQorICAgICAqIGJ1dCB0aGVzZSB0eXBlcyBhcmUgbW9zdCBjb21tb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0JbWJwCXRoZSBib2R5IHBhcnQgY29udGFpbmluZyB0aGUgdGV4dAorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXRUZXh0Qm9keVBhcnQoTWltZUJvZHlQYXJ0IG1icCkKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlzZXRCb2R5UGFydChtYnAsIDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgcmVwb3J0IGFzc29jaWF0ZWQgd2l0aCB0aGlzIG11bHRpcGFydC9yZXBvcnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBSZXBvcnQgb2JqZWN0CisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNC4yCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBSZXBvcnQgZ2V0UmVwb3J0KCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKGdldENvdW50KCkgPCAyKQorCSAgICByZXR1cm4gbnVsbDsKKwlCb2R5UGFydCBicCA9IGdldEJvZHlQYXJ0KDEpOworCXRyeSB7CisJICAgIE9iamVjdCBjb250ZW50ID0gYnAuZ2V0Q29udGVudCgpOworCSAgICBpZiAoIShjb250ZW50IGluc3RhbmNlb2YgUmVwb3J0KSkKKwkJcmV0dXJuIG51bGw7CisJICAgIHJldHVybiAoUmVwb3J0KWNvbnRlbnQ7CisJfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiSU9FeGNlcHRpb24gZ2V0dGluZyBSZXBvcnQiLCBleCk7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgcmVwb3J0IGFzc29jaWF0ZWQgd2l0aCB0aGlzIG11bHRpcGFydC9yZXBvcnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0JcmVwb3J0CXRoZSBSZXBvcnQgb2JqZWN0CisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNC4yCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHNldFJlcG9ydChSZXBvcnQgcmVwb3J0KQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCU1pbWVCb2R5UGFydCBtYnAgPSBuZXcgTWltZUJvZHlQYXJ0KCk7CisJQ29udGVudFR5cGUgY3QgPSBuZXcgQ29udGVudFR5cGUoY29udGVudFR5cGUpOworCVN0cmluZyByZXBvcnRUeXBlID0gcmVwb3J0LmdldFR5cGUoKTsKKwljdC5zZXRQYXJhbWV0ZXIoInJlcG9ydC10eXBlIiwgcmVwb3J0VHlwZSk7CisJY29udGVudFR5cGUgPSBjdC50b1N0cmluZygpOworCWN0ID0gbmV3IENvbnRlbnRUeXBlKCJtZXNzYWdlIiwgcmVwb3J0VHlwZSwgbnVsbCk7CisJbWJwLnNldENvbnRlbnQocmVwb3J0LCBjdC50b1N0cmluZygpKTsKKwlzZXRCb2R5UGFydChtYnAsIDEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgZGVsaXZlcnkgc3RhdHVzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIG11bHRpcGFydC9yZXBvcnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBkZWxpdmVyeSBzdGF0dXMKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKiBAZGVwcmVjYXRlZAl1c2UgZ2V0UmVwb3J0IGluc3RlYWQKKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgRGVsaXZlcnlTdGF0dXMgZ2V0RGVsaXZlcnlTdGF0dXMoKQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWlmIChnZXRDb3VudCgpIDwgMikKKwkgICAgcmV0dXJuIG51bGw7CisJQm9keVBhcnQgYnAgPSBnZXRCb2R5UGFydCgxKTsKKwlpZiAoIWJwLmlzTWltZVR5cGUoIm1lc3NhZ2UvZGVsaXZlcnktc3RhdHVzIikpCisJICAgIHJldHVybiBudWxsOworCXRyeSB7CisJICAgIHJldHVybiAoRGVsaXZlcnlTdGF0dXMpYnAuZ2V0Q29udGVudCgpOworCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oIklPRXhjZXB0aW9uIGdldHRpbmcgRGVsaXZlcnlTdGF0dXMiLAorCQkJCQlleCk7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgZGVsaXZlcnkgc3RhdHVzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIG11bHRpcGFydC9yZXBvcnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jc3RhdHVzIHRoZSBkZWxpdmVyIHN0YXR1cworICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqIEBkZXByZWNhdGVkCXVzZSBzZXRSZXBvcnQgaW5zdGVhZAorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXREZWxpdmVyeVN0YXR1cyhEZWxpdmVyeVN0YXR1cyBzdGF0dXMpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJTWltZUJvZHlQYXJ0IG1icCA9IG5ldyBNaW1lQm9keVBhcnQoKTsKKwltYnAuc2V0Q29udGVudChzdGF0dXMsICJtZXNzYWdlL2RlbGl2ZXJ5LXN0YXR1cyIpOworCXNldEJvZHlQYXJ0KG1icCwgMSk7CisJQ29udGVudFR5cGUgY3QgPSBuZXcgQ29udGVudFR5cGUoY29udGVudFR5cGUpOworCWN0LnNldFBhcmFtZXRlcigicmVwb3J0LXR5cGUiLCAiZGVsaXZlcnktc3RhdHVzIik7CisJY29udGVudFR5cGUgPSBjdC50b1N0cmluZygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgb3JpZ2luYWwgbWVzc2FnZSB0aGF0IGlzIGJlaW5nIHJldHVybmVkIGFsb25nIHdpdGggdGhpcworICAgICAqIG11bHRpcGFydC9yZXBvcnQuICBJZiBubyBvcmlnaW5hbCBtZXNzYWdlIGlzIGluY2x1ZGVkLCBudWxsIGlzCisgICAgICogcmV0dXJuZWQuICBJbiBzb21lIGNhc2VzIG9ubHkgdGhlIGhlYWRlcnMgb2YgdGhlIG9yaWdpbmFsCisgICAgICogbWVzc2FnZSB3aWxsIGJlIHJldHVybmVkIGFzIGFuIG9iamVjdCBvZiB0eXBlIE1lc3NhZ2VIZWFkZXJzLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgcmV0dXJuZWQgbWVzc2FnZQorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgTWltZU1lc3NhZ2UgZ2V0UmV0dXJuZWRNZXNzYWdlKCkKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpZiAoZ2V0Q291bnQoKSA8IDMpCisJICAgIHJldHVybiBudWxsOworCUJvZHlQYXJ0IGJwID0gZ2V0Qm9keVBhcnQoMik7CisJaWYgKCFicC5pc01pbWVUeXBlKCJtZXNzYWdlL3JmYzgyMiIpICYmCisJCSFicC5pc01pbWVUeXBlKCJ0ZXh0L3JmYzgyMi1oZWFkZXJzIikpCisJICAgIHJldHVybiBudWxsOworCXRyeSB7CisJICAgIHJldHVybiAoTWltZU1lc3NhZ2UpYnAuZ2V0Q29udGVudCgpOworCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oIklPRXhjZXB0aW9uIGdldHRpbmcgUmV0dXJuZWRNZXNzYWdlIiwKKwkJCQkJZXgpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIG9yaWdpbmFsIG1lc3NhZ2UgdG8gYmUgcmV0dXJuZWQgYXMgcGFydCBvZiB0aGUKKyAgICAgKiBtdWx0aXBhcnQvcmVwb3J0LiAgSWYgbXNnIGlzIG51bGwsIGFueSBwcmV2aW91c2x5IHNldAorICAgICAqIHJldHVybmVkIG1lc3NhZ2Ugb3IgaGVhZGVycyBpcyByZW1vdmVkLgorICAgICAqCisgICAgICogQHBhcmFtCW1zZwl0aGUgcmV0dXJuZWQgbWVzc2FnZQorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXRSZXR1cm5lZE1lc3NhZ2UoTWltZU1lc3NhZ2UgbXNnKQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWlmIChtc2cgPT0gbnVsbCkgeworCSAgICBzdXBlci5yZW1vdmVCb2R5UGFydCgyKTsKKwkgICAgcmV0dXJuOworCX0KKwlNaW1lQm9keVBhcnQgbWJwID0gbmV3IE1pbWVCb2R5UGFydCgpOworCWlmIChtc2cgaW5zdGFuY2VvZiBNZXNzYWdlSGVhZGVycykKKwkgICAgbWJwLnNldENvbnRlbnQobXNnLCAidGV4dC9yZmM4MjItaGVhZGVycyIpOworCWVsc2UKKwkgICAgbWJwLnNldENvbnRlbnQobXNnLCAibWVzc2FnZS9yZmM4MjIiKTsKKwlzZXRCb2R5UGFydChtYnAsIDIpOworICAgIH0KKworICAgIHByaXZhdGUgc3luY2hyb25pemVkIHZvaWQgc2V0Qm9keVBhcnQoQm9keVBhcnQgcGFydCwgaW50IGluZGV4KSAKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpZiAocGFydHMgPT0gbnVsbCkJLy8gWFhYIC0gY2FuIG5ldmVyIGhhcHBlbj8KKwkgICAgcGFydHMgPSBuZXcgVmVjdG9yPEJvZHlQYXJ0PigpOworCisJaWYgKGluZGV4IDwgcGFydHMuc2l6ZSgpKQorCSAgICBzdXBlci5yZW1vdmVCb2R5UGFydChpbmRleCk7CisJc3VwZXIuYWRkQm9keVBhcnQocGFydCwgaW5kZXgpOworICAgIH0KKworCisgICAgLy8gT3ZlcnJpZGUgTXVsdGlwYXJ0IG1ldGhvZHMgdG8gcHJlc2VydmUgaW50ZWdyaXR5IG9mIG11bHRpcGFydC9yZXBvcnQuCisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHN1YnR5cGUuICBUaHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtCXN1YnR5cGUJCVN1YnR5cGUKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbglhbHdheXM7IGNhbid0IGNoYW5nZSBzdWJ0eXBlCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHNldFN1YlR5cGUoU3RyaW5nIHN1YnR5cGUpIAorCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiQ2FuJ3QgY2hhbmdlIHN1YnR5cGUgb2YgTXVsdGlwYXJ0UmVwb3J0Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlIHRoZSBzcGVjaWZpZWQgcGFydCBmcm9tIHRoZSBtdWx0aXBhcnQgbWVzc2FnZS4KKyAgICAgKiBOb3QgYWxsb3dlZCBvbiBhIG11bHRpcGFydC9yZXBvcnQgb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtICAgcGFydAlUaGUgcGFydCB0byByZW1vdmUKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBhbHdheXMKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiByZW1vdmVCb2R5UGFydChCb2R5UGFydCBwYXJ0KSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwl0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKAorCSAgICAiQ2FuJ3QgcmVtb3ZlIGJvZHkgcGFydHMgZnJvbSBtdWx0aXBhcnQvcmVwb3J0Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlIHRoZSBwYXJ0IGF0IHNwZWNpZmllZCBsb2NhdGlvbiAoc3RhcnRpbmcgZnJvbSAwKS4KKyAgICAgKiBOb3QgYWxsb3dlZCBvbiBhIG11bHRpcGFydC9yZXBvcnQgb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtICAgaW5kZXgJSW5kZXggb2YgdGhlIHBhcnQgdG8gcmVtb3ZlCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24JYWx3YXlzCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVtb3ZlQm9keVBhcnQoaW50IGluZGV4KSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwl0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKAorCSAgICAiQ2FuJ3QgcmVtb3ZlIGJvZHkgcGFydHMgZnJvbSBtdWx0aXBhcnQvcmVwb3J0Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkcyBhIFBhcnQgdG8gdGhlIG11bHRpcGFydC4KKyAgICAgKiBOb3QgYWxsb3dlZCBvbiBhIG11bHRpcGFydC9yZXBvcnQgb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtICBwYXJ0ICBUaGUgUGFydCB0byBiZSBhcHBlbmRlZAorICAgICAqIEBleGNlcHRpb24gICAgICAgTWVzc2FnaW5nRXhjZXB0aW9uCWFsd2F5cworICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBhZGRCb2R5UGFydChCb2R5UGFydCBwYXJ0KSAKKwkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJLy8gT25jZSBjb25zdHJ1Y3RvciBpcyBkb25lLCBkb24ndCBhbGxvdyB0aGlzIGFueW1vcmUuCisJaWYgKCFjb25zdHJ1Y3RlZCkKKwkgICAgc3VwZXIuYWRkQm9keVBhcnQocGFydCk7CisJZWxzZQorCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKAorCQkiQ2FuJ3QgYWRkIGJvZHkgcGFydHMgdG8gbXVsdGlwYXJ0L3JlcG9ydCAxIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkcyBhIEJvZHlQYXJ0IGF0IHBvc2l0aW9uIDxjb2RlPmluZGV4PC9jb2RlPi4KKyAgICAgKiBOb3QgYWxsb3dlZCBvbiBhIG11bHRpcGFydC9yZXBvcnQgb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtICBwYXJ0ICBUaGUgQm9keVBhcnQgdG8gYmUgaW5zZXJ0ZWQKKyAgICAgKiBAcGFyYW0gIGluZGV4IExvY2F0aW9uIHdoZXJlIHRvIGluc2VydCB0aGUgcGFydAorICAgICAqIEBleGNlcHRpb24gICAgICAgTWVzc2FnaW5nRXhjZXB0aW9uCWFsd2F5cworICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBhZGRCb2R5UGFydChCb2R5UGFydCBwYXJ0LCBpbnQgaW5kZXgpIAorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oCisJICAgICJDYW4ndCBhZGQgYm9keSBwYXJ0cyB0byBtdWx0aXBhcnQvcmVwb3J0IDIiKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9kc24vc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvZHNuL1JlcG9ydC5qYXZhIGIvZHNuL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2Rzbi9SZXBvcnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iMTAzZDU2Ci0tLSAvZGV2L251bGwKKysrIGIvZHNuL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2Rzbi9SZXBvcnQuamF2YQpAQCAtMCwwICsxLDQ4IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5kc247CisKKy8qKgorICogQW4gYWJzdHJhY3QgcmVwb3J0IHR5cGUsIHRvIGJlIGluY2x1ZGVkIGluIGEgTXVsdGlwYXJ0UmVwb3J0LgorICogU3ViY2xhc3NlcyBkZWZpbmUgc3BlY2lmaWMgcmVwb3J0IHR5cGVzLCBzdWNoIGFzIHtAbGluayBEZWxpdmVyeVN0YXR1c30KKyAqIGFuZCB7QGxpbmsgRGlzcG9zaXRpb25Ob3RpZmljYXRpb259LgorICoKKyAqIEBzaW5jZQlKYXZhTWFpbCAxLjQuMgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgUmVwb3J0IHsKKyAgICBwcm90ZWN0ZWQgU3RyaW5nIHR5cGU7CS8vIHRoZSBNSU1FIHN1YnR5cGUgb2YgdGhlIHJlcG9ydAorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGEgcmVwb3J0IG9mIHRoZSBpbmRpY2F0ZWQgTUlNRSBzdWJ0eXBlLgorICAgICAqIFRoZSBwcmltYXJ5IE1JTUUgdHlwZSBpcyBhbHdheXMgIm1lc3NhZ2UiLgorICAgICAqCisgICAgICogQHBhcmFtCXR5cGUJdGhlIE1JTUUgc3VidHlwZQorICAgICAqLworICAgIHByb3RlY3RlZCBSZXBvcnQoU3RyaW5nIHR5cGUpIHsKKwl0aGlzLnR5cGUgPSB0eXBlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgTUlNRSBzdWJ0eXBlIG9mIHRoZSByZXBvcnQuCisgICAgICogVGhlIHByaW1hcnkgTUlNRSB0eXBlIGlzIGFsd2F5cyAibWVzc2FnZSIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBNSU1FIHN1YnR5cGUKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFR5cGUoKSB7CisJcmV0dXJuIHR5cGU7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvZHNuL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2Rzbi9tZXNzYWdlX2RlbGl2ZXJ5c3RhdHVzLmphdmEgYi9kc24vc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvZHNuL21lc3NhZ2VfZGVsaXZlcnlzdGF0dXMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hNTlhYzhhCi0tLSAvZGV2L251bGwKKysrIGIvZHNuL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2Rzbi9tZXNzYWdlX2RlbGl2ZXJ5c3RhdHVzLmphdmEKQEAgLTAsMCArMSwxMDYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmRzbjsKKworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKK2ltcG9ydCBqYXZhLmF3dC5kYXRhdHJhbnNmZXIuRGF0YUZsYXZvcjsKK2ltcG9ydCBqYXZheC5hY3RpdmF0aW9uLio7CitpbXBvcnQgamF2YXgubWFpbC4qOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuKjsKKworCisvKioKKyAqIERhdGFDb250ZW50SGFuZGxlciBmb3IgbWVzc2FnZS9kZWxpdmVyeS1zdGF0dXMgTUlNRSB0eXBlLgorICogQXBwbGljYXRpb25zIHNob3VsZCBub3QgdXNlIHRoaXMgY2xhc3MgZGlyZWN0bHksIGl0J3MgdXNlZCBpbmRpcmVjdGx5CisgKiB0aHJvdWdoIHRoZSBKYXZhQmVhbnMgQWN0aXZhdGlvbiBGcmFtZXdvcmsuCisgKgorICogQHNpbmNlCUphdmFNYWlsIDEuNAorICovCitwdWJsaWMgY2xhc3MgbWVzc2FnZV9kZWxpdmVyeXN0YXR1cyBpbXBsZW1lbnRzIERhdGFDb250ZW50SGFuZGxlciB7CisKKyAgICBBY3RpdmF0aW9uRGF0YUZsYXZvciBvdXJEYXRhRmxhdm9yID0gbmV3IEFjdGl2YXRpb25EYXRhRmxhdm9yKAorCURlbGl2ZXJ5U3RhdHVzLmNsYXNzLAorCSJtZXNzYWdlL2RlbGl2ZXJ5LXN0YXR1cyIsIAorCSJEZWxpdmVyeSBTdGF0dXMiKTsKKworICAgIC8qKgorICAgICAqIHJldHVybiB0aGUgRGF0YUZsYXZvcnMgZm9yIHRoaXMgPGNvZGU+RGF0YUNvbnRlbnRIYW5kbGVyPC9jb2RlPgorICAgICAqIEByZXR1cm4gVGhlIERhdGFGbGF2b3JzLgorICAgICAqLworICAgIHB1YmxpYyBEYXRhRmxhdm9yW10gZ2V0VHJhbnNmZXJEYXRhRmxhdm9ycygpIHsKKwlyZXR1cm4gbmV3IERhdGFGbGF2b3JbXSB7IG91ckRhdGFGbGF2b3IgfTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiByZXR1cm4gdGhlIFRyYW5zZmVyIERhdGEgb2YgdHlwZSBEYXRhRmxhdm9yIGZyb20gSW5wdXRTdHJlYW0KKyAgICAgKiBAcGFyYW0gZGYgVGhlIERhdGFGbGF2b3IuCisgICAgICogQHBhcmFtIGRzIFRoZSBEYXRhU291cmNlIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGRhdGEuCisgICAgICogQHJldHVybiBhIE1lc3NhZ2Ugb2JqZWN0CisgICAgICovCisgICAgcHVibGljIE9iamVjdCBnZXRUcmFuc2ZlckRhdGEoRGF0YUZsYXZvciBkZiwgRGF0YVNvdXJjZSBkcykKKwkJCQl0aHJvd3MgSU9FeGNlcHRpb24geworCS8vIG1ha2Ugc3VyZSB3ZSBjYW4gaGFuZGxlIHRoaXMgRGF0YUZsYXZvcgorCWlmIChvdXJEYXRhRmxhdm9yLmVxdWFscyhkZikpCisJICAgIHJldHVybiBnZXRDb250ZW50KGRzKTsKKwllbHNlCisJICAgIHJldHVybiBudWxsOworICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIGNvbnRlbnQuCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBnZXRDb250ZW50KERhdGFTb3VyY2UgZHMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJLy8gY3JlYXRlIGEgbmV3IERlbGl2ZXJ5U3RhdHVzCisJdHJ5IHsKKwkgICAgLyoKKwkgICAgU2Vzc2lvbiBzZXNzaW9uOworCSAgICBpZiAoZHMgaW5zdGFuY2VvZiBNZXNzYWdlQXdhcmUpIHsKKwkJamF2YXgubWFpbC5NZXNzYWdlQ29udGV4dCBtYyA9CisJCQkoKE1lc3NhZ2VBd2FyZSlkcykuZ2V0TWVzc2FnZUNvbnRleHQoKTsKKwkJc2Vzc2lvbiA9IG1jLmdldFNlc3Npb24oKTsKKwkgICAgfSBlbHNlIHsKKwkJLy8gSG9wZWZ1bGx5IGEgcmFyZSBjYXNlLiAgQWxzbyBob3BlZnVsbHkgdGhlIGFwcGxpY2F0aW9uCisJCS8vIGhhcyBjcmVhdGVkIGEgZGVmYXVsdCBTZXNzaW9uIHRoYXQgY2FuIGp1c3QgYmUgcmV0dXJuZWQKKwkJLy8gaGVyZS4gIElmIG5vdCwgdGhlIG9uZSB3ZSBjcmVhdGUgaGVyZSBpcyBiZXR0ZXIgdGhhbgorCQkvLyBub3RoaW5nLCBidXQgb3ZlcmFsbCBub3QgYSByZWFsbHkgZ29vZCBhbnN3ZXIuCisJCXNlc3Npb24gPSBTZXNzaW9uLmdldERlZmF1bHRJbnN0YW5jZShuZXcgUHJvcGVydGllcygpLCBudWxsKTsKKwkgICAgfQorCSAgICByZXR1cm4gbmV3IERlbGl2ZXJ5U3RhdHVzKHNlc3Npb24sIGRzLmdldElucHV0U3RyZWFtKCkpOworCSAgICAqLworCSAgICByZXR1cm4gbmV3IERlbGl2ZXJ5U3RhdHVzKGRzLmdldElucHV0U3RyZWFtKCkpOworCX0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBtZSkgeworCSAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkV4Y2VwdGlvbiBjcmVhdGluZyBEZWxpdmVyeVN0YXR1cyBpbiAiICsKKwkJICAgICJtZXNzYWdlL2RlbGl2ZXJ5LXN0YXR1cyBEYXRhQ29udGVudEhhbmRsZXI6ICIgKworCQkgICAgbWUudG9TdHJpbmcoKSk7CisJfQorICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKE9iamVjdCBvYmosIFN0cmluZyBtaW1lVHlwZSwgT3V0cHV0U3RyZWFtIG9zKSAKKwkJCXRocm93cyBJT0V4Y2VwdGlvbiB7CisJLy8gaWYgdGhlIG9iamVjdCBpcyBhIERlbGl2ZXJ5U3RhdHVzLCB3ZSBrbm93IGhvdyB0byB3cml0ZSB0aGF0IG91dAorCWlmIChvYmogaW5zdGFuY2VvZiBEZWxpdmVyeVN0YXR1cykgeworCSAgICBEZWxpdmVyeVN0YXR1cyBkcyA9IChEZWxpdmVyeVN0YXR1cylvYmo7CisJICAgIGRzLndyaXRlVG8ob3MpOworCSAgICAKKwl9IGVsc2UgeworCSAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oInVuc3VwcG9ydGVkIG9iamVjdCIpOworCX0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9kc24vc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvZHNuL21lc3NhZ2VfZGlzcG9zaXRpb25ub3RpZmljYXRpb24uamF2YSBiL2Rzbi9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9kc24vbWVzc2FnZV9kaXNwb3NpdGlvbm5vdGlmaWNhdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZlYmE4MDIKLS0tIC9kZXYvbnVsbAorKysgYi9kc24vc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvZHNuL21lc3NhZ2VfZGlzcG9zaXRpb25ub3RpZmljYXRpb24uamF2YQpAQCAtMCwwICsxLDEwNiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuZHNuOworCitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOworaW1wb3J0IGphdmEuYXd0LmRhdGF0cmFuc2Zlci5EYXRhRmxhdm9yOworaW1wb3J0IGphdmF4LmFjdGl2YXRpb24uKjsKK2ltcG9ydCBqYXZheC5tYWlsLio7CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC4qOworCisKKy8qKgorICogRGF0YUNvbnRlbnRIYW5kbGVyIGZvciBtZXNzYWdlL2Rpc3Bvc2l0aW9uLW5vdGlmaWNhdGlvbiBNSU1FIHR5cGUuCisgKiBBcHBsaWNhdGlvbnMgc2hvdWxkIG5vdCB1c2UgdGhpcyBjbGFzcyBkaXJlY3RseSwgaXQncyB1c2VkIGluZGlyZWN0bHkKKyAqIHRocm91Z2ggdGhlIEphdmFCZWFucyBBY3RpdmF0aW9uIEZyYW1ld29yay4KKyAqCisgKiBAc2luY2UJSmF2YU1haWwgMS40LjIKKyAqLworcHVibGljIGNsYXNzIG1lc3NhZ2VfZGlzcG9zaXRpb25ub3RpZmljYXRpb24gaW1wbGVtZW50cyBEYXRhQ29udGVudEhhbmRsZXIgeworCisgICAgQWN0aXZhdGlvbkRhdGFGbGF2b3Igb3VyRGF0YUZsYXZvciA9IG5ldyBBY3RpdmF0aW9uRGF0YUZsYXZvcigKKwlEaXNwb3NpdGlvbk5vdGlmaWNhdGlvbi5jbGFzcywKKwkibWVzc2FnZS9kaXNwb3NpdGlvbi1ub3RpZmljYXRpb24iLCAKKwkiRGlzcG9zaXRpb24gTm90aWZpY2F0aW9uIik7CisKKyAgICAvKioKKyAgICAgKiByZXR1cm4gdGhlIERhdGFGbGF2b3JzIGZvciB0aGlzIDxjb2RlPkRhdGFDb250ZW50SGFuZGxlcjwvY29kZT4KKyAgICAgKiBAcmV0dXJuIFRoZSBEYXRhRmxhdm9ycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgRGF0YUZsYXZvcltdIGdldFRyYW5zZmVyRGF0YUZsYXZvcnMoKSB7CisJcmV0dXJuIG5ldyBEYXRhRmxhdm9yW10geyBvdXJEYXRhRmxhdm9yIH07CisgICAgfQorCisgICAgLyoqCisgICAgICogcmV0dXJuIHRoZSBUcmFuc2ZlciBEYXRhIG9mIHR5cGUgRGF0YUZsYXZvciBmcm9tIElucHV0U3RyZWFtCisgICAgICogQHBhcmFtIGRmIFRoZSBEYXRhRmxhdm9yLgorICAgICAqIEBwYXJhbSBkcyBUaGUgRGF0YVNvdXJjZSBjb3JyZXNwb25kaW5nIHRvIHRoZSBkYXRhLgorICAgICAqIEByZXR1cm4gYSBNZXNzYWdlIG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZ2V0VHJhbnNmZXJEYXRhKERhdGFGbGF2b3IgZGYsIERhdGFTb3VyY2UgZHMpCisJCQkJdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkvLyBtYWtlIHN1cmUgd2UgY2FuIGhhbmRsZSB0aGlzIERhdGFGbGF2b3IKKwlpZiAob3VyRGF0YUZsYXZvci5lcXVhbHMoZGYpKQorCSAgICByZXR1cm4gZ2V0Q29udGVudChkcyk7CisJZWxzZQorCSAgICByZXR1cm4gbnVsbDsKKyAgICB9CisgICAgCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBjb250ZW50LgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZ2V0Q29udGVudChEYXRhU291cmNlIGRzKSB0aHJvd3MgSU9FeGNlcHRpb24geworCS8vIGNyZWF0ZSBhIG5ldyBEaXNwb3NpdGlvbk5vdGlmaWNhdGlvbgorCXRyeSB7CisJICAgIC8qCisJICAgIFNlc3Npb24gc2Vzc2lvbjsKKwkgICAgaWYgKGRzIGluc3RhbmNlb2YgTWVzc2FnZUF3YXJlKSB7CisJCWphdmF4Lm1haWwuTWVzc2FnZUNvbnRleHQgbWMgPQorCQkJKChNZXNzYWdlQXdhcmUpZHMpLmdldE1lc3NhZ2VDb250ZXh0KCk7CisJCXNlc3Npb24gPSBtYy5nZXRTZXNzaW9uKCk7CisJICAgIH0gZWxzZSB7CisJCS8vIEhvcGVmdWxseSBhIHJhcmUgY2FzZS4gIEFsc28gaG9wZWZ1bGx5IHRoZSBhcHBsaWNhdGlvbgorCQkvLyBoYXMgY3JlYXRlZCBhIGRlZmF1bHQgU2Vzc2lvbiB0aGF0IGNhbiBqdXN0IGJlIHJldHVybmVkCisJCS8vIGhlcmUuICBJZiBub3QsIHRoZSBvbmUgd2UgY3JlYXRlIGhlcmUgaXMgYmV0dGVyIHRoYW4KKwkJLy8gbm90aGluZywgYnV0IG92ZXJhbGwgbm90IGEgcmVhbGx5IGdvb2QgYW5zd2VyLgorCQlzZXNzaW9uID0gU2Vzc2lvbi5nZXREZWZhdWx0SW5zdGFuY2UobmV3IFByb3BlcnRpZXMoKSwgbnVsbCk7CisJICAgIH0KKwkgICAgcmV0dXJuIG5ldyBEaXNwb3NpdGlvbk5vdGlmaWNhdGlvbihzZXNzaW9uLCBkcy5nZXRJbnB1dFN0cmVhbSgpKTsKKwkgICAgKi8KKwkgICAgcmV0dXJuIG5ldyBEaXNwb3NpdGlvbk5vdGlmaWNhdGlvbihkcy5nZXRJbnB1dFN0cmVhbSgpKTsKKwl9IGNhdGNoIChNZXNzYWdpbmdFeGNlcHRpb24gbWUpIHsKKwkgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKAorCQkgICAgIkV4Y2VwdGlvbiBjcmVhdGluZyBEaXNwb3NpdGlvbk5vdGlmaWNhdGlvbiBpbiAiICsKKwkJICAgICJtZXNzYWdlL2Rpc3Bvc2l0aW9uLW5vdGlmaWNhdGlvbiBEYXRhQ29udGVudEhhbmRsZXI6ICIgKworCQkgICAgbWUudG9TdHJpbmcoKSk7CisJfQorICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKE9iamVjdCBvYmosIFN0cmluZyBtaW1lVHlwZSwgT3V0cHV0U3RyZWFtIG9zKSAKKwkJCXRocm93cyBJT0V4Y2VwdGlvbiB7CisJLy8gaWYgaXQncyBhIERpc3Bvc2l0aW9uTm90aWZpY2F0aW9uLCB3ZSBrbm93IGhvdyB0byB3cml0ZSB0aGF0IG91dAorCWlmIChvYmogaW5zdGFuY2VvZiBEaXNwb3NpdGlvbk5vdGlmaWNhdGlvbikgeworCSAgICBEaXNwb3NpdGlvbk5vdGlmaWNhdGlvbiBkbiA9IChEaXNwb3NpdGlvbk5vdGlmaWNhdGlvbilvYmo7CisJICAgIGRuLndyaXRlVG8ob3MpOworCX0gZWxzZSB7CisJICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigidW5zdXBwb3J0ZWQgb2JqZWN0Iik7CisJfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2Rzbi9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9kc24vbXVsdGlwYXJ0X3JlcG9ydC5qYXZhIGIvZHNuL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2Rzbi9tdWx0aXBhcnRfcmVwb3J0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGZiY2NmYQotLS0gL2Rldi9udWxsCisrKyBiL2Rzbi9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9kc24vbXVsdGlwYXJ0X3JlcG9ydC5qYXZhCkBAIC0wLDAgKzEsOTIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmRzbjsKKworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZhLmF3dC5kYXRhdHJhbnNmZXIuRGF0YUZsYXZvcjsKK2ltcG9ydCBqYXZheC5hY3RpdmF0aW9uLio7CitpbXBvcnQgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC4qOworCisKKy8qKgorICogRGF0YUNvbnRlbnRIYW5kbGVyIGZvciBtdWx0aXBhcnQvcmVwb3J0IE1JTUUgdHlwZS4KKyAqIEFwcGxpY2F0aW9ucyBzaG91bGQgbm90IHVzZSB0aGlzIGNsYXNzIGRpcmVjdGx5LCBpdCdzIHVzZWQgaW5kaXJlY3RseQorICogdGhyb3VnaCB0aGUgSmF2YUJlYW5zIEFjdGl2YXRpb24gRnJhbWV3b3JrLgorICoKKyAqIEBzaW5jZQlKYXZhTWFpbCAxLjQKKyAqLworcHVibGljIGNsYXNzIG11bHRpcGFydF9yZXBvcnQgaW1wbGVtZW50cyBEYXRhQ29udGVudEhhbmRsZXIgeworICAgIHByaXZhdGUgQWN0aXZhdGlvbkRhdGFGbGF2b3IgbXlERiA9IG5ldyBBY3RpdmF0aW9uRGF0YUZsYXZvcigKKwkgICAgTXVsdGlwYXJ0UmVwb3J0LmNsYXNzLAorCSAgICAibXVsdGlwYXJ0L3JlcG9ydCIsIAorCSAgICAiTXVsdGlwYXJ0IFJlcG9ydCIpOworCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBEYXRhRmxhdm9ycyBmb3IgdGhpcyA8Y29kZT5EYXRhQ29udGVudEhhbmRsZXI8L2NvZGU+LgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgRGF0YUZsYXZvcnMKKyAgICAgKi8KKyAgICBwdWJsaWMgRGF0YUZsYXZvcltdIGdldFRyYW5zZmVyRGF0YUZsYXZvcnMoKSB7IC8vIHRocm93cyBFeGNlcHRpb247CisJcmV0dXJuIG5ldyBEYXRhRmxhdm9yW10geyBteURGIH07CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBUcmFuc2ZlciBEYXRhIG9mIHR5cGUgRGF0YUZsYXZvciBmcm9tIElucHV0U3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtIGRmIFRoZSBEYXRhRmxhdm9yCisgICAgICogQHBhcmFtIGRzIFRoZSBEYXRhU291cmNlIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGRhdGEKKyAgICAgKiBAcmV0dXJuIFN0cmluZyBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IGdldFRyYW5zZmVyRGF0YShEYXRhRmxhdm9yIGRmLCBEYXRhU291cmNlIGRzKQorCQkJCXRocm93cyBJT0V4Y2VwdGlvbiB7CisJLy8gdXNlIG15REYuZXF1YWxzIHRvIGJlIHN1cmUgdG8gZ2V0IEFjdGl2YXRpb25EYXRhRmxhdm9yLmVxdWFscywKKwkvLyB3aGljaCBwcm9wZXJseSBpZ25vcmVzIENvbnRlbnQtVHlwZSBwYXJhbWV0ZXJzIGluIGNvbXBhcmlzb24KKwlpZiAobXlERi5lcXVhbHMoZGYpKQorCSAgICByZXR1cm4gZ2V0Q29udGVudChkcyk7CisJZWxzZQorCSAgICByZXR1cm4gbnVsbDsKKyAgICB9CisgICAgCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBjb250ZW50LgorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZ2V0Q29udGVudChEYXRhU291cmNlIGRzKSB0aHJvd3MgSU9FeGNlcHRpb24geworCXRyeSB7CisJICAgIHJldHVybiBuZXcgTXVsdGlwYXJ0UmVwb3J0KGRzKTsgCisJfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIGUpIHsKKwkgICAgSU9FeGNlcHRpb24gaW9leCA9CisJCW5ldyBJT0V4Y2VwdGlvbigiRXhjZXB0aW9uIHdoaWxlIGNvbnN0cnVjdGluZyBNdWx0aXBhcnRSZXBvcnQiKTsKKwkgICAgaW9leC5pbml0Q2F1c2UoZSk7CisJICAgIHRocm93IGlvZXg7CisJfQorICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiBXcml0ZSB0aGUgb2JqZWN0IHRvIHRoZSBvdXRwdXQgc3RyZWFtLCB1c2luZyB0aGUgc3BlY2lmaWMgTUlNRSB0eXBlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oT2JqZWN0IG9iaiwgU3RyaW5nIG1pbWVUeXBlLCBPdXRwdXRTdHJlYW0gb3MpIAorCQkJdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlpZiAob2JqIGluc3RhbmNlb2YgTXVsdGlwYXJ0UmVwb3J0KSB7CisJICAgIHRyeSB7CisJCSgoTXVsdGlwYXJ0UmVwb3J0KW9iaikud3JpdGVUbyhvcyk7CisJICAgIH0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBlKSB7CisJCXRocm93IG5ldyBJT0V4Y2VwdGlvbihlLnRvU3RyaW5nKCkpOworCSAgICB9CisJfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2Rzbi9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9kc24vcGFja2FnZS5odG1sIGIvZHNuL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2Rzbi9wYWNrYWdlLmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGY5NjgwMgotLS0gL2Rldi9udWxsCisrKyBiL2Rzbi9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9kc24vcGFja2FnZS5odG1sCkBAIC0wLDAgKzEsODMgQEAKKzwhRE9DVFlQRSBodG1sIFBVQkxJQyAiLS8vVzNDLy9EVEQgSFRNTCA0LjAxIFRyYW5zaXRpb25hbC8vRU4iPgorPEhUTUw+Cis8SEVBRD4KKzxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PXV0Zi04Ij4KKzwhLS0KKworICAgIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorCisgICAgVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgICAgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisKKyAgICBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgICAgTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICAgIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICAgIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorCisgICAgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisKKy0tPgorCis8VElUTEU+Y29tLnN1bi5tYWlsLmRzbiBwYWNrYWdlPC9USVRMRT4KKzwvSEVBRD4KKzxCT0RZIEJHQ09MT1I9IndoaXRlIj4KKworPFA+CitTdXBwb3J0IGZvciBjcmVhdGluZyBhbmQgcGFyc2luZyBEZWxpdmVyeSBTdGF0dXMgTm90aWZpY2F0aW9ucy4KK1JlZmVyIHRvIDxBIEhSRUY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzM0NjIudHh0IiBUQVJHRVQ9Il90b3AiPgorUkZDIDM0NjI8L0E+CithbmQgPEEgSFJFRj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzQ2NC50eHQiIFRBUkdFVD0iX3RvcCI+UkZDIDM0NjQ8L0E+Citmb3IgbW9yZSBpbmZvcm1hdGlvbi4KKzwvUD4KKzxQPgorQSBEZWxpdmVyeSBTdGF0dXMgTm90aWZpY2F0aW9uIGlzIGEgTUlNRSBtZXNzYWdlIHdpdGggYSBDb250ZW50LVR5cGUKK29mIDxjb2RlPm11bHRpcGFydC9yZXBvcnQ8L2NvZGU+LgorQSB7QGxpbmsgY29tLnN1bi5tYWlsLmRzbi5NdWx0aXBhcnRSZXBvcnQgTXVsdGlwYXJ0UmVwb3J0fSBvYmplY3QKK3JlcHJlc2VudHMgdGhlIGNvbnRlbnQgb2Ygc3VjaCBhIG1lc3NhZ2UuCitUaGUgTXVsdGlwYXJ0UmVwb3J0IG9iamVjdCBjb250YWlucyBzZXZlcmFsIHBhcnRzIHRoYXQgcmVwcmVzZW50IHRoZQoraW5mb3JtYXRpb24gaW4gYSBkZWxpdmVyeSBzdGF0dXMgbm90aWZpY2F0aW9uLgorVGhlIGZpcnN0IHBhcnQgaXMgdXN1YWxseSBhIDxjb2RlPnRleHQvcGxhaW48L2NvZGU+IHBhcnQgdGhhdAorZGVzY3JpYmVzIHRoZSByZWFzb24gZm9yIHRoZSBub3RpZmljYXRpb24uCitUaGUgc2Vjb25kIHBhcnQgaXMgYSA8Y29kZT5tZXNzYWdlL2RlbGl2ZXJ5LXN0YXR1czwvY29kZT4gcGFydCwKK3doaWNoIGlzIHJlcHJlc2VudGVkIGJ5IGEKK3tAbGluayBjb20uc3VuLm1haWwuZHNuLkRlbGl2ZXJ5U3RhdHVzIERlbGl2ZXJ5U3RhdHVzfSBvYmplY3QsIGFuZCBjb250YWlucworZGV0YWlscyBhYm91dCB0aGUgbm90aWZpY2F0aW9uLgorVGhlIHRoaXJkIHBhcnQgaXMgZWl0aGVyIGFuIGVudGlyZSBjb3B5IG9mIHRoZSBvcmlnaW5hbCBtZXNzYWdlCit0aGF0IGlzIHJldHVybmVkLCByZXByZXNlbnRlZCBieSBhCit7QGxpbmsgamF2YXgubWFpbC5pbnRlcm5ldC5NaW1lTWVzc2FnZSBNaW1lTWVzc2FnZX0gb2JqZWN0LCBvcgoranVzdCB0aGUgaGVhZGVycyBvZiB0aGUgb3JpZ2luYWwgbWVzc2FnZSwgcmVwcmVzZW50ZWQgYnkgYQore0BsaW5rIGNvbS5zdW4ubWFpbC5kc24uTWVzc2FnZUhlYWRlcnMgTWVzc2FnZUhlYWRlcnN9IG9iamVjdC4KKzwvUD4KKzxQPgorVG8gdXNlIHRoZSBjbGFzc2VzIGluIHRoaXMgcGFja2FnZSwgaW5jbHVkZSA8Y29kZT5kc24uamFyPC9jb2RlPgoraW4geW91ciBjbGFzcyBwYXRoLgorPC9QPgorPFA+CitDbGFzc2VzIGluIHRoaXMgcGFja2FnZSBsb2cgZGVidWdnaW5nIGluZm9ybWF0aW9uIHVzaW5nCit7QGxpbmsgamF2YS51dGlsLmxvZ2dpbmd9IGFzIGRlc2NyaWJlZCBpbiB0aGUgZm9sbG93aW5nIHRhYmxlOgorPC9QPgorPFRBQkxFIEJPUkRFUiBTVU1NQVJZPSJjb20uc3VuLm1haWwuZHNuIExvZ2dlcnMiPgorPFRSPgorPFRIPkxvZ2dlciBOYW1lPC9USD4KKzxUSD5Mb2dnaW5nIExldmVsPC9USD4KKzxUSD5QdXJwb3NlPC9USD4KKzwvVFI+CisKKzxUUj4KKzxURD5jb20uc3VuLm1haWwuZHNuPC9URD4KKzxURD5GSU5FUjwvVEQ+Cis8VEQ+R2VuZXJhbCBkZWJ1Z2dpbmcgb3V0cHV0PC9URD4KKzwvVFI+Cis8L1RBQkxFPgorCis8UD4KKzxzdHJvbmc+V0FSTklORzo8L3N0cm9uZz4gVGhlIEFQSXMgdW5pcXVlIHRvIHRoaXMgcGFja2FnZSBzaG91bGQgYmUKK2NvbnNpZGVyZWQgPHN0cm9uZz5FWFBFUklNRU5UQUw8L3N0cm9uZz4uICBUaGV5IG1heSBiZSBjaGFuZ2VkIGluIHRoZQorZnV0dXJlIGluIHdheXMgdGhhdCBhcmUgaW5jb21wYXRpYmxlIHdpdGggYXBwbGljYXRpb25zIHVzaW5nIHRoZQorY3VycmVudCBBUElzLgorPC9QPgorCis8L0JPRFk+Cis8L0hUTUw+CmRpZmYgLS1naXQgYS9kc24vc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvZHNuL3RleHRfcmZjODIyaGVhZGVycy5qYXZhIGIvZHNuL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2Rzbi90ZXh0X3JmYzgyMmhlYWRlcnMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNjA3ODJmCi0tLSAvZGV2L251bGwKKysrIGIvZHNuL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2Rzbi90ZXh0X3JmYzgyMmhlYWRlcnMuamF2YQpAQCAtMCwwICsxLDE4NSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuZHNuOworCitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmEuYXd0LmRhdGF0cmFuc2Zlci5EYXRhRmxhdm9yOworaW1wb3J0IGphdmF4LmFjdGl2YXRpb24uKjsKK2ltcG9ydCBqYXZheC5tYWlsLio7CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC4qOworCisvKioKKyAqIERhdGFDb250ZW50SGFuZGxlciBmb3IgdGV4dC9yZmM4MjItaGVhZGVycyBNSU1FIHR5cGUuCisgKiBBcHBsaWNhdGlvbnMgc2hvdWxkIG5vdCB1c2UgdGhpcyBjbGFzcyBkaXJlY3RseSwgaXQncyB1c2VkIGluZGlyZWN0bHkKKyAqIHRocm91Z2ggdGhlIEphdmFCZWFucyBBY3RpdmF0aW9uIEZyYW1ld29yay4KKyAqCisgKiBAc2luY2UJSmF2YU1haWwgMS40CisgKgorICovCitwdWJsaWMgY2xhc3MgdGV4dF9yZmM4MjJoZWFkZXJzIGltcGxlbWVudHMgRGF0YUNvbnRlbnRIYW5kbGVyIHsKKyAgICBwcml2YXRlIHN0YXRpYyBBY3RpdmF0aW9uRGF0YUZsYXZvciBteURGID0gbmV3IEFjdGl2YXRpb25EYXRhRmxhdm9yKAorCU1lc3NhZ2VIZWFkZXJzLmNsYXNzLAorCSJ0ZXh0L3JmYzgyMi1oZWFkZXJzIiwKKwkiUkZDODIyIGhlYWRlcnMiKTsKKyAgICBwcml2YXRlIHN0YXRpYyBBY3RpdmF0aW9uRGF0YUZsYXZvciBteURGcyA9IG5ldyBBY3RpdmF0aW9uRGF0YUZsYXZvcigKKwlqYXZhLmxhbmcuU3RyaW5nLmNsYXNzLAorCSJ0ZXh0L3JmYzgyMi1oZWFkZXJzIiwKKwkiUkZDODIyIGhlYWRlcnMiKTsKKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgRGF0YUZsYXZvcnMgZm9yIHRoaXMgPGNvZGU+RGF0YUNvbnRlbnRIYW5kbGVyPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVGhlIERhdGFGbGF2b3JzCisgICAgICovCisgICAgcHVibGljIERhdGFGbGF2b3JbXSBnZXRUcmFuc2ZlckRhdGFGbGF2b3JzKCkgeworCXJldHVybiBuZXcgRGF0YUZsYXZvcltdIHsgbXlERiwgbXlERnMgfTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIFRyYW5zZmVyIERhdGEgb2YgdHlwZSBEYXRhRmxhdm9yIGZyb20gSW5wdXRTdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGYgVGhlIERhdGFGbGF2b3IKKyAgICAgKiBAcGFyYW0gZHMgVGhlIERhdGFTb3VyY2UgY29ycmVzcG9uZGluZyB0byB0aGUgZGF0YQorICAgICAqIEByZXR1cm4gU3RyaW5nIG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZ2V0VHJhbnNmZXJEYXRhKERhdGFGbGF2b3IgZGYsIERhdGFTb3VyY2UgZHMpIAorCQkJdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkvLyB1c2UgbXlERi5lcXVhbHMgdG8gYmUgc3VyZSB0byBnZXQgQWN0aXZhdGlvbkRhdGFGbGF2b3IuZXF1YWxzLAorCS8vIHdoaWNoIHByb3Blcmx5IGlnbm9yZXMgQ29udGVudC1UeXBlIHBhcmFtZXRlcnMgaW4gY29tcGFyaXNvbgorCWlmIChteURGLmVxdWFscyhkZikpCisJICAgIHJldHVybiBnZXRDb250ZW50KGRzKTsKKwllbHNlIGlmIChteURGcy5lcXVhbHMoZGYpKQorCSAgICByZXR1cm4gZ2V0U3RyaW5nQ29udGVudChkcyk7CisJZWxzZQorCSAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGdldENvbnRlbnQoRGF0YVNvdXJjZSBkcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwl0cnkgeworCSAgICByZXR1cm4gbmV3IE1lc3NhZ2VIZWFkZXJzKGRzLmdldElucHV0U3RyZWFtKCkpOworCX0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBtZXgpIHsKKy8vU3lzdGVtLm91dC5wcmludGxuKCJFeGNlcHRpb24gY3JlYXRpbmcgTWVzc2FnZUhlYWRlcnM6ICIgKyBtZXgpOworCSAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkV4Y2VwdGlvbiBjcmVhdGluZyBNZXNzYWdlSGVhZGVyczogIiArIG1leCk7CisJfQorICAgIH0KKworICAgIHByaXZhdGUgT2JqZWN0IGdldFN0cmluZ0NvbnRlbnQoRGF0YVNvdXJjZSBkcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlTdHJpbmcgZW5jID0gbnVsbDsKKwlJbnB1dFN0cmVhbVJlYWRlciBpcyA9IG51bGw7CisJCisJdHJ5IHsKKwkgICAgZW5jID0gZ2V0Q2hhcnNldChkcy5nZXRDb250ZW50VHlwZSgpKTsKKwkgICAgaXMgPSBuZXcgSW5wdXRTdHJlYW1SZWFkZXIoZHMuZ2V0SW5wdXRTdHJlYW0oKSwgZW5jKTsKKwl9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWV4KSB7CisJICAgIC8qCisJICAgICAqIEFuIHVua25vd24gY2hhcnNldCBvZiB0aGUgZm9ybSBJU08tWFhYLVhYWCB3aWxsIGNhdXNlCisJICAgICAqIHRoZSBKREsgdG8gdGhyb3cgYW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLiAgVGhlCisJICAgICAqIEpESyB3aWxsIGF0dGVtcHQgdG8gY3JlYXRlIGEgY2xhc3NuYW1lIHVzaW5nIHRoaXMgc3RyaW5nLAorCSAgICAgKiBidXQgdmFsaWQgY2xhc3NuYW1lcyBtdXN0IG5vdCBjb250YWluIHRoZSBjaGFyYWN0ZXIgJy0nLAorCSAgICAgKiBhbmQgdGhpcyByZXN1bHRzIGluIGFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwgcmF0aGVyIHRoYW4KKwkgICAgICogdGhlIGV4cGVjdGVkIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24uICBZaWtlcy4KKwkgICAgICovCisJICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uKGVuYyk7CisJfQorCisJdHJ5IHsKKwkgICAgaW50IHBvcyA9IDA7CisJICAgIGludCBjb3VudDsKKwkgICAgY2hhciBidWZbXSA9IG5ldyBjaGFyWzEwMjRdOworCisJICAgIHdoaWxlICgoY291bnQgPSBpcy5yZWFkKGJ1ZiwgcG9zLCBidWYubGVuZ3RoIC0gcG9zKSkgIT0gLTEpIHsKKwkJcG9zICs9IGNvdW50OworCQlpZiAocG9zID49IGJ1Zi5sZW5ndGgpIHsKKwkJICAgIGludCBzaXplID0gYnVmLmxlbmd0aDsKKwkJICAgIGlmIChzaXplIDwgMjU2KjEwMjQpCisJCQlzaXplICs9IHNpemU7CisJCSAgICBlbHNlCisJCQlzaXplICs9IDI1NioxMDI0OworCQkgICAgY2hhciB0YnVmW10gPSBuZXcgY2hhcltzaXplXTsKKwkJICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmLCAwLCB0YnVmLCAwLCBwb3MpOworCQkgICAgYnVmID0gdGJ1ZjsKKwkJfQorCSAgICB9CisJICAgIHJldHVybiBuZXcgU3RyaW5nKGJ1ZiwgMCwgcG9zKTsKKwl9IGZpbmFsbHkgeworCSAgICB0cnkgeworCQlpcy5jbG9zZSgpOworCSAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworCQkvLyBpZ25vcmUgaXQKKwkgICAgfQorCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZSB0aGUgb2JqZWN0IHRvIHRoZSBvdXRwdXQgc3RyZWFtLCB1c2luZyB0aGUgc3BlY2lmaWVkIE1JTUUgdHlwZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKE9iamVjdCBvYmosIFN0cmluZyB0eXBlLCBPdXRwdXRTdHJlYW0gb3MpIAorCQkJdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlpZiAob2JqIGluc3RhbmNlb2YgTWVzc2FnZUhlYWRlcnMpIHsKKwkgICAgTWVzc2FnZUhlYWRlcnMgbWggPSAoTWVzc2FnZUhlYWRlcnMpb2JqOworCSAgICB0cnkgeworCQltaC53cml0ZVRvKG9zKTsKKwkgICAgfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIG1leCkgeworCQlFeGNlcHRpb24gZXggPSBtZXguZ2V0TmV4dEV4Y2VwdGlvbigpOworCQlpZiAoZXggaW5zdGFuY2VvZiBJT0V4Y2VwdGlvbikKKwkJICAgIHRocm93IChJT0V4Y2VwdGlvbilleDsKKwkJZWxzZQorCQkgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJFeGNlcHRpb24gd3JpdGluZyBoZWFkZXJzOiAiICsgbWV4KTsKKwkgICAgfQorCSAgICByZXR1cm47CisJfQorCWlmICghKG9iaiBpbnN0YW5jZW9mIFN0cmluZykpCisJICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiXCIiICsgbXlERnMuZ2V0TWltZVR5cGUoKSArCisJCSJcIiBEYXRhQ29udGVudEhhbmRsZXIgcmVxdWlyZXMgU3RyaW5nIG9iamVjdCwgIiArCisJCSJ3YXMgZ2l2ZW4gb2JqZWN0IG9mIHR5cGUgIiArIG9iai5nZXRDbGFzcygpLnRvU3RyaW5nKCkpOworCisJU3RyaW5nIGVuYyA9IG51bGw7CisJT3V0cHV0U3RyZWFtV3JpdGVyIG9zdyA9IG51bGw7CisKKwl0cnkgeworCSAgICBlbmMgPSBnZXRDaGFyc2V0KHR5cGUpOworCSAgICBvc3cgPSBuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKG9zLCBlbmMpOworCX0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZXgpIHsKKwkgICAgLyoKKwkgICAgICogQW4gdW5rbm93biBjaGFyc2V0IG9mIHRoZSBmb3JtIElTTy1YWFgtWFhYIHdpbGwgY2F1c2UKKwkgICAgICogdGhlIEpESyB0byB0aHJvdyBhbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uICBUaGUKKwkgICAgICogSkRLIHdpbGwgYXR0ZW1wdCB0byBjcmVhdGUgYSBjbGFzc25hbWUgdXNpbmcgdGhpcyBzdHJpbmcsCisJICAgICAqIGJ1dCB2YWxpZCBjbGFzc25hbWVzIG11c3Qgbm90IGNvbnRhaW4gdGhlIGNoYXJhY3RlciAnLScsCisJICAgICAqIGFuZCB0aGlzIHJlc3VsdHMgaW4gYW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCByYXRoZXIgdGhhbgorCSAgICAgKiB0aGUgZXhwZWN0ZWQgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbi4gIFlpa2VzLgorCSAgICAgKi8KKwkgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24oZW5jKTsKKwl9CisKKwlTdHJpbmcgcyA9IChTdHJpbmcpb2JqOworCW9zdy53cml0ZShzLCAwLCBzLmxlbmd0aCgpKTsKKwlvc3cuZmx1c2goKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFN0cmluZyBnZXRDaGFyc2V0KFN0cmluZyB0eXBlKSB7CisJdHJ5IHsKKwkgICAgQ29udGVudFR5cGUgY3QgPSBuZXcgQ29udGVudFR5cGUodHlwZSk7CisJICAgIFN0cmluZyBjaGFyc2V0ID0gY3QuZ2V0UGFyYW1ldGVyKCJjaGFyc2V0Iik7CisJICAgIGlmIChjaGFyc2V0ID09IG51bGwpCisJCS8vIElmIHRoZSBjaGFyc2V0IHBhcmFtZXRlciBpcyBhYnNlbnQsIHVzZSBVUy1BU0NJSS4KKwkJY2hhcnNldCA9ICJ1cy1hc2NpaSI7CisJICAgIHJldHVybiBNaW1lVXRpbGl0eS5qYXZhQ2hhcnNldChjaGFyc2V0KTsKKwl9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKwkgICAgcmV0dXJuIG51bGw7CisJfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2Rzbi9zcmMvbWFpbi9yZXNvdXJjZXMvTUVUQS1JTkYvTUFOSUZFU1QuTUYgYi9kc24vc3JjL21haW4vcmVzb3VyY2VzL01FVEEtSU5GL01BTklGRVNULk1GCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMyNDE3N2IKLS0tIC9kZXYvbnVsbAorKysgYi9kc24vc3JjL21haW4vcmVzb3VyY2VzL01FVEEtSU5GL01BTklGRVNULk1GCkBAIC0wLDAgKzEsOSBAQAorTWFuaWZlc3QtVmVyc2lvbjogMS4wCitFeHRlbnNpb24tTmFtZTogY29tLnN1bi5tYWlsLmRzbgorU3BlY2lmaWNhdGlvbi1UaXRsZTogY29tLnN1bi5tYWlsLmRzbgorU3BlY2lmaWNhdGlvbi1WZXJzaW9uOiAke21haWwuc3BlYy52ZXJzaW9ufQorU3BlY2lmaWNhdGlvbi1WZW5kb3I6ICR7cHJvamVjdC5vcmdhbml6YXRpb24ubmFtZX0KK0ltcGxlbWVudGF0aW9uLVRpdGxlOiBjb20uc3VuLm1haWwuZHNuCitJbXBsZW1lbnRhdGlvbi1WZXJzaW9uOiAke21haWwudmVyc2lvbn0KK0ltcGxlbWVudGF0aW9uLVZlbmRvcjogJHtwcm9qZWN0Lm9yZ2FuaXphdGlvbi5uYW1lfQorSW1wbGVtZW50YXRpb24tVmVuZG9yLUlkOiBjb20uc3VuCmRpZmYgLS1naXQgYS9kc24vc3JjL21haW4vcmVzb3VyY2VzL01FVEEtSU5GL21haWxjYXAgYi9kc24vc3JjL21haW4vcmVzb3VyY2VzL01FVEEtSU5GL21haWxjYXAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDQyZGU3YwotLS0gL2Rldi9udWxsCisrKyBiL2Rzbi9zcmMvbWFpbi9yZXNvdXJjZXMvTUVUQS1JTkYvbWFpbGNhcApAQCAtMCwwICsxLDggQEAKKyMKKyMKKyMgSmF2YU1haWwgY29udGVudC1oYW5kbGVyczoKKyMKK211bHRpcGFydC9yZXBvcnQ7Owl4LWphdmEtY29udGVudC1oYW5kbGVyPWNvbS5zdW4ubWFpbC5kc24ubXVsdGlwYXJ0X3JlcG9ydAorbWVzc2FnZS9kZWxpdmVyeS1zdGF0dXM7OyB4LWphdmEtY29udGVudC1oYW5kbGVyPWNvbS5zdW4ubWFpbC5kc24ubWVzc2FnZV9kZWxpdmVyeXN0YXR1cworbWVzc2FnZS9kaXNwb3NpdGlvbi1ub3RpZmljYXRpb247OyB4LWphdmEtY29udGVudC1oYW5kbGVyPWNvbS5zdW4ubWFpbC5kc24ubWVzc2FnZV9kaXNwb3NpdGlvbm5vdGlmaWNhdGlvbgordGV4dC9yZmM4MjItaGVhZGVyczs7CXgtamF2YS1jb250ZW50LWhhbmRsZXI9Y29tLnN1bi5tYWlsLmRzbi50ZXh0X3JmYzgyMmhlYWRlcnMKZGlmZiAtLWdpdCBhL2Rzbi9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9kc24vTXVsdGlwYXJ0UmVwb3J0VGVzdC5qYXZhIGIvZHNuL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL2Rzbi9NdWx0aXBhcnRSZXBvcnRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2VkYWZlNgotLS0gL2Rldi9udWxsCisrKyBiL2Rzbi9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9kc24vTXVsdGlwYXJ0UmVwb3J0VGVzdC5qYXZhCkBAIC0wLDAgKzEsNTggQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMTAsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmRzbjsKKworaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOworCitpbXBvcnQgamF2YXgubWFpbC5TZXNzaW9uOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuTWltZU1lc3NhZ2U7CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC5JbnRlcm5ldEhlYWRlcnM7CisKK2ltcG9ydCBvcmcuanVuaXQuKjsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUcnVlOworCisvKioKKyAqLworcHVibGljIGNsYXNzIE11bHRpcGFydFJlcG9ydFRlc3QgeworIAorICAgIHByaXZhdGUgc3RhdGljIFNlc3Npb24gc2Vzc2lvbiA9IFNlc3Npb24uZ2V0SW5zdGFuY2UobmV3IFByb3BlcnRpZXMoKSk7CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RXcm9uZ0luZGV4QnVnKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJTWltZU1lc3NhZ2UgbXNnID0gbmV3IE1pbWVNZXNzYWdlKHNlc3Npb24pOworCisJLy8gY3JlYXRlIHRoZSBNdWx0aXBhcnQgYW5kIGl0cyBwYXJ0cyB0byBpdAorCU11bHRpcGFydFJlcG9ydCBtcCA9IG5ldyBNdWx0aXBhcnRSZXBvcnQoKTsKKwltcC5zZXRUZXh0KCJ0ZXN0IE11bHRpcGFydCBSZXBvcnRcbiIpOworCisJRGVsaXZlcnlTdGF0dXMgZHMgPSBuZXcgRGVsaXZlcnlTdGF0dXMoKTsKKwlJbnRlcm5ldEhlYWRlcnMgbWRzbiA9IG5ldyBJbnRlcm5ldEhlYWRlcnMoKTsKKwltZHNuLnNldEhlYWRlcigiUmVwb3J0aW5nLU1UQSIsICJ0ZXN0Iik7CisJZHMuc2V0TWVzc2FnZURTTihtZHNuKTsKKwlJbnRlcm5ldEhlYWRlcnMgcmRzbiA9IG5ldyBJbnRlcm5ldEhlYWRlcnMoKTsKKwlyZHNuLnNldEhlYWRlcigiRmluYWwtUmVjaXBpZW50IiwgImpvZSIpOworCXJkc24uc2V0SGVhZGVyKCJBY3Rpb24iLCAibm9uZSIpOworCXJkc24uc2V0SGVhZGVyKCJTdGF0dXMiLCAibm9uZSIpOworCWRzLmFkZFJlY2lwaWVudERTTihyZHNuKTsKKwltcC5zZXRSZXBvcnQoZHMpOworCW1zZy5zZXRDb250ZW50KG1wKTsKKwltc2cuc2F2ZUNoYW5nZXMoKTsKKwltc2cud3JpdGVUbyhuZXcgTnVsbE91dHB1dFN0cmVhbSgpKTsKKwkvLyBhbnl0aGluZyBvdGhlciB0aGFuIGFuIGV4Y2VwdGlvbiBpcyBzdWNjZXNzCisJYXNzZXJ0VHJ1ZSgiTXVsdGlwYXJ0UmVwb3J0IGNvbnN0cnVjdGVkIiwgdHJ1ZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvZHNuL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL2Rzbi9OdWxsT3V0cHV0U3RyZWFtLmphdmEgYi9kc24vc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvZHNuL051bGxPdXRwdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xYjJhN2E3Ci0tLSAvZGV2L251bGwKKysrIGIvZHNuL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL2Rzbi9OdWxsT3V0cHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwzNCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwOSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuZHNuOworCitpbXBvcnQgamF2YS5pby4qOworCisvKioKKyAqIEFuIE91dHB1dFN0cmVhbSB0aGF0IHRocm93cyBhd2F5IGFsbCBkYXRhIHdyaXR0ZW4gdG8gaXQuCisgKi8KK3B1YmxpYyBjbGFzcyBOdWxsT3V0cHV0U3RyZWFtIGV4dGVuZHMgT3V0cHV0U3RyZWFtIHsKKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKGludCBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKGJ5dGVbXSBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIH0KK30KZGlmZiAtLWdpdCBhL2dpbWFwL2V4Y2x1ZGUueG1sIGIvZ2ltYXAvZXhjbHVkZS54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTk1ZTNhOAotLS0gL2Rldi9udWxsCisrKyBiL2dpbWFwL2V4Y2x1ZGUueG1sCkBAIC0wLDAgKzEsNDQgQEAKKzw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04Ij8+Cis8IS0tCisKKyAgICBDb3B5cmlnaHQgKGMpIDIwMTMsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKworICAgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICAgIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorCisgICAgVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICAgIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAgICBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAgICB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKworICAgIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorCistLT4KKworPCEtLSBGaW5kQnVncyBleGNsdWRlIGxpc3QgZm9yIEphdmFNYWlsIGdpbWFwIHByb3ZpZGVyIC0tPgorCis8RmluZEJ1Z3NGaWx0ZXI+CisgICAgPCEtLQorCVRoZXNlIHJldHVybmVkIGFycmF5cyBhcmUgbmV2ZXIgZXhwb3NlZCB0byBhcHBsaWNhdGlvbnMgc28gaXQncworCXNhZmUgdGhhdCBpdCBkb2Vzbid0IHJldHVybiBhIGNvcHkuCisgICAgLS0+CisgICAgPE1hdGNoPgorCTxDbGFzcyBuYW1lPSJjb20uc3VuLm1haWwuZ2ltYXAucHJvdG9jb2wuR21haWxQcm90b2NvbCIvPgorCTxNZXRob2QgbmFtZT0iZ2V0RmV0Y2hJdGVtcyIvPgorCTxCdWcgcGF0dGVybj0iRUlfRVhQT1NFX1JFUCIvPgorICAgIDwvTWF0Y2g+CisKKyAgICA8IS0tCisJVGhlIHNldExhYmVscyBtZXRob2QgbmVlZHMgdG8gYmUgc3luY2hyb25pemVkIGJlY2F1c2Ugb2YgaXRzCisJdXNlIG9mIHRoZSBwcm90b2NvbCBvYmplY3QuICBUaGUgZ2V0TGFiZWxzIG1ldGhvZCBkZXBlbmRzIG9uCisJdGhlIGdldEl0ZW0gbWV0aG9kIHRvIGRvIHRoZSBzeW5jaHJvbml6YXRpb24uCisgICAgLS0+CisgICAgPE1hdGNoPgorCTxDbGFzcyBuYW1lPSJjb20uc3VuLm1haWwuZ2ltYXAuR21haWxNZXNzYWdlIi8+CisJPE1ldGhvZCBuYW1lPSJnZXRMYWJlbHMiLz4KKwk8QnVnIHBhdHRlcm49IlVHX1NZTkNfU0VUX1VOU1lOQ19HRVQiLz4KKyAgICA8L01hdGNoPgorCis8L0ZpbmRCdWdzRmlsdGVyPgpkaWZmIC0tZ2l0IGEvZ2ltYXAvcG9tLnhtbCBiL2dpbWFwL3BvbS54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTNmMjVlYgotLS0gL2Rldi9udWxsCisrKyBiL2dpbWFwL3BvbS54bWwKQEAgLTAsMCArMSw5MCBAQAorPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PgorPCEtLQorCisgICAgQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisKKyAgICBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAgICB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKworICAgIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAgICBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgICAgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgICAgdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisKKyAgICBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKworLS0+CisKKzxwcm9qZWN0IHhtbG5zPSJodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9QT00vNC4wLjAiCisJeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIKKwl4c2k6c2NoZW1hTG9jYXRpb249Imh0dHA6Ly9tYXZlbi5hcGFjaGUub3JnL1BPTS80LjAuMAorCQkJICAgIGh0dHA6Ly9tYXZlbi5hcGFjaGUub3JnL21hdmVuLXY0XzBfMC54c2QiPgorICAgIDxwYXJlbnQ+CisJPGdyb3VwSWQ+Y29tLnN1bi5tYWlsPC9ncm91cElkPgorCTxhcnRpZmFjdElkPmFsbDwvYXJ0aWZhY3RJZD4KKwk8dmVyc2lvbj4xLjYuMzwvdmVyc2lvbj4KKyAgICA8L3BhcmVudD4KKyAgICA8bW9kZWxWZXJzaW9uPjQuMC4wPC9tb2RlbFZlcnNpb24+CisgICAgPGdyb3VwSWQ+Y29tLnN1bi5tYWlsPC9ncm91cElkPgorICAgIDxhcnRpZmFjdElkPmdpbWFwPC9hcnRpZmFjdElkPgorICAgIDxwYWNrYWdpbmc+amFyPC9wYWNrYWdpbmc+CisgICAgPG5hbWU+SmF2YU1haWwgQVBJIEdtYWlsIElNQVAgcHJvdmlkZXI8L25hbWU+CisKKyAgICA8cHJvcGVydGllcz4KKwk8bWFpbC5wYWNrYWdlcy5leHBvcnQ+CisJICAgIGNvbS5zdW4ubWFpbC5naW1hcDsgdmVyc2lvbj0ke21haWwub3NnaXZlcnNpb259CisJPC9tYWlsLnBhY2thZ2VzLmV4cG9ydD4KKwk8ZmluZGJ1Z3MuZXhjbHVkZT4KKwkgICAgJHtwcm9qZWN0LmJhc2VkaXJ9L2V4Y2x1ZGUueG1sCisJPC9maW5kYnVncy5leGNsdWRlPgorICAgIDwvcHJvcGVydGllcz4KKworICAgIDxidWlsZD4KKwk8cGx1Z2lucz4KKwkgICAgPCEtLQorCQlDb25maWd1cmUgU3BvdEJ1Z3MgdG8gcnVuIHdpdGggIm12biBzcG90YnVnczpzcG90YnVncyIKKwkJYW5kIGdlbmVyYXRlIFhNTCBvdXRwdXQgdGhhdCBjYW4gYmUgdXNlZCBieSB0aGUgSHVkc29uCisJCUZpbmRCdWdzIHBsdWdpbi4KKwkgICAgLS0+CisJICAgIDxwbHVnaW4+CisJCTxncm91cElkPmNvbS5naXRodWIuc3BvdGJ1Z3M8L2dyb3VwSWQ+CisJCTxhcnRpZmFjdElkPnNwb3RidWdzLW1hdmVuLXBsdWdpbjwvYXJ0aWZhY3RJZD4KKwkJPGNvbmZpZ3VyYXRpb24+CisJCSAgICA8c2tpcD5mYWxzZTwvc2tpcD4KKwkJICAgIDx0aHJlc2hvbGQ+JHtmaW5kYnVncy50aHJlc2hvbGR9PC90aHJlc2hvbGQ+CisJCSAgICA8ZXhjbHVkZUZpbHRlckZpbGU+JHtmaW5kYnVncy5leGNsdWRlfTwvZXhjbHVkZUZpbHRlckZpbGU+CisJCSAgICA8ZmluZGJ1Z3NYbWxXaXRoTWVzc2FnZXM+dHJ1ZTwvZmluZGJ1Z3NYbWxXaXRoTWVzc2FnZXM+CisJCTwvY29uZmlndXJhdGlvbj4KKwkgICAgPC9wbHVnaW4+CisJPC9wbHVnaW5zPgorICAgIDwvYnVpbGQ+CisKKyAgICA8ZGVwZW5kZW5jaWVzPgorICAgICAgICA8ZGVwZW5kZW5jeT4KKyAgICAgICAgICAgIDxncm91cElkPmNvbS5zdW4ubWFpbDwvZ3JvdXBJZD4KKyAgICAgICAgICAgIDxhcnRpZmFjdElkPmpha2FydGEubWFpbDwvYXJ0aWZhY3RJZD4KKyAgICAgICAgPC9kZXBlbmRlbmN5PgorICAgIDwvZGVwZW5kZW5jaWVzPgorCisgICAgPHJlcG9ydGluZz4KKwk8cGx1Z2lucz4KKwkgICAgPCEtLQorCQlDb25maWd1cmUgU3BvdEJ1Z3MgdG8gcnVuIHdpdGggIm12biBzaXRlIiBhbmQKKwkJZ2VuZXJhdGUgaHRtbCBvdXRwdXQgdGhhdCBjYW4gYmUgdmlld2VkIGRpcmVjdGx5LgorCSAgICAtLT4KKwkgICAgPHBsdWdpbj4KKwkJPGdyb3VwSWQ+b3JnLmNvZGVoYXVzLm1vam88L2dyb3VwSWQ+CisJCTxhcnRpZmFjdElkPmZpbmRidWdzLW1hdmVuLXBsdWdpbjwvYXJ0aWZhY3RJZD4KKwkJPGNvbmZpZ3VyYXRpb24+CisJCSAgICA8c2tpcD5mYWxzZTwvc2tpcD4KKwkJICAgIDx0aHJlc2hvbGQ+JHtmaW5kYnVncy50aHJlc2hvbGR9PC90aHJlc2hvbGQ+CisJCSAgICA8IS0tCisJCSAgICA8ZXhjbHVkZUZpbHRlckZpbGU+ZXhjbHVkZS54bWw8L2V4Y2x1ZGVGaWx0ZXJGaWxlPgorCQkgICAgLS0+CisJCTwvY29uZmlndXJhdGlvbj4KKwkgICAgPC9wbHVnaW4+CisJPC9wbHVnaW5zPgorICAgIDwvcmVwb3J0aW5nPgorPC9wcm9qZWN0PgpkaWZmIC0tZ2l0IGEvZ2ltYXAvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvZ2ltYXAvR21haWxGb2xkZXIuamF2YSBiL2dpbWFwL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2dpbWFwL0dtYWlsRm9sZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2RiZGUwMAotLS0gL2Rldi9udWxsCisrKyBiL2dpbWFwL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2dpbWFwL0dtYWlsRm9sZGVyLmphdmEKQEAgLTAsMCArMSwyMTAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmdpbWFwOworCitpbXBvcnQgamF2YS5pby4qOworCitpbXBvcnQgamF2YXgubWFpbC4qOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuKjsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC5pYXAuKjsKK2ltcG9ydCBjb20uc3VuLm1haWwuaW1hcC4qOworaW1wb3J0IGNvbS5zdW4ubWFpbC5pbWFwLnByb3RvY29sLio7CitpbXBvcnQgY29tLnN1bi5tYWlsLmdpbWFwLnByb3RvY29sLio7CisKKy8qKgorICogQSBHbWFpbCBmb2xkZXIuICBEZWZpbmVzIG5ldyBGZXRjaFByb2ZpbGUgaXRlbXMgYW5kCisgKiB1c2VzIEdtYWlsTWVzc2FnZSB0byBzdG9yZSBhZGRpdGlvbmFsIEdtYWlsIG1lc3NhZ2UgYXR0cmlidXRlcy4KKyAqCisgKiBAc2luY2UgSmF2YU1haWwgMS40LjYKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKi8KKworcHVibGljIGNsYXNzIEdtYWlsRm9sZGVyIGV4dGVuZHMgSU1BUEZvbGRlciB7CisgICAgLyoqCisgICAgICogQSBmZXRjaCBwcm9maWxlIGl0ZW0gZm9yIGZldGNoaW5nIGhlYWRlcnMuCisgICAgICogVGhpcyBpbm5lciBjbGFzcyBleHRlbmRzIHRoZSA8Y29kZT5GZXRjaFByb2ZpbGUuSXRlbTwvY29kZT4KKyAgICAgKiBjbGFzcyB0byBhZGQgbmV3IEZldGNoUHJvZmlsZSBpdGVtIHR5cGVzLCBzcGVjaWZpYyB0byBHbWFpbC4KKyAgICAgKgorICAgICAqIEBzZWUgRmV0Y2hQcm9maWxlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBGZXRjaFByb2ZpbGVJdGVtIGV4dGVuZHMgRmV0Y2hQcm9maWxlLkl0ZW0geworCXByb3RlY3RlZCBGZXRjaFByb2ZpbGVJdGVtKFN0cmluZyBuYW1lKSB7CisJICAgIHN1cGVyKG5hbWUpOworCX0KKworCS8qKgorCSAqIE1TR0lEIGlzIGEgZmV0Y2ggcHJvZmlsZSBpdGVtIHRoYXQgY2FuIGJlIGluY2x1ZGVkIGluIGEKKwkgKiA8Y29kZT5GZXRjaFByb2ZpbGU8L2NvZGU+IGR1cmluZyBhIGZldGNoIHJlcXVlc3QgdG8gYSBGb2xkZXIuCisJICogVGhpcyBpdGVtIGluZGljYXRlcyB0aGF0IHRoZSBHbWFpbCB1bmlxdWUgbWVzc2FnZSBJRCBmb3IgbWVzc2FnZXMKKwkgKiBpbiB0aGUgc3BlY2lmaWVkIHJhbmdlIGFyZSBkZXNpcmVkIHRvIGJlIHByZWZldGNoZWQuIDxwPgorCSAqIAorCSAqIEFuIGV4YW1wbGUgb2YgaG93IGEgY2xpZW50IHVzZXMgdGhpcyBpcyBiZWxvdzoKKwkgKiA8YmxvY2txdW90ZT48cHJlPgorCSAqCisJICogCUZldGNoUHJvZmlsZSBmcCA9IG5ldyBGZXRjaFByb2ZpbGUoKTsKKwkgKglmcC5hZGQoR21haWxGb2xkZXIuRmV0Y2hQcm9maWxlSXRlbS5NU0dJRCk7CisJICoJZm9sZGVyLmZldGNoKG1zZ3MsIGZwKTsKKwkgKgorCSAqIDwvcHJlPjwvYmxvY2txdW90ZT4KKwkgKi8gCisJcHVibGljIHN0YXRpYyBmaW5hbCBGZXRjaFByb2ZpbGVJdGVtIE1TR0lEID0gCisJCW5ldyBGZXRjaFByb2ZpbGVJdGVtKCJYLUdNLU1TR0lEIik7CisKKwkvKioKKwkgKiBUSFJJRCBpcyBhIGZldGNoIHByb2ZpbGUgaXRlbSB0aGF0IGNhbiBiZSBpbmNsdWRlZCBpbiBhCisJICogPGNvZGU+RmV0Y2hQcm9maWxlPC9jb2RlPiBkdXJpbmcgYSBmZXRjaCByZXF1ZXN0IHRvIGEgRm9sZGVyLgorCSAqIFRoaXMgaXRlbSBpbmRpY2F0ZXMgdGhhdCB0aGUgR21haWwgdW5pcXVlIHRocmVhZCBJRCBmb3IgbWVzc2FnZXMKKwkgKiBpbiB0aGUgc3BlY2lmaWVkIHJhbmdlIGFyZSBkZXNpcmVkIHRvIGJlIHByZWZldGNoZWQuIDxwPgorCSAqIAorCSAqIEFuIGV4YW1wbGUgb2YgaG93IGEgY2xpZW50IHVzZXMgdGhpcyBpcyBiZWxvdzoKKwkgKiA8YmxvY2txdW90ZT48cHJlPgorCSAqCisJICogCUZldGNoUHJvZmlsZSBmcCA9IG5ldyBGZXRjaFByb2ZpbGUoKTsKKwkgKglmcC5hZGQoR21haWxGb2xkZXIuRmV0Y2hQcm9maWxlSXRlbS5USFJJRCk7CisJICoJZm9sZGVyLmZldGNoKG1zZ3MsIGZwKTsKKwkgKgorCSAqIDwvcHJlPjwvYmxvY2txdW90ZT4KKwkgKi8gCisJcHVibGljIHN0YXRpYyBmaW5hbCBGZXRjaFByb2ZpbGVJdGVtIFRIUklEID0gCisJCW5ldyBGZXRjaFByb2ZpbGVJdGVtKCJYLUdNLVRIUklEIik7CisKKwkvKioKKwkgKiBMQUJFTFMgaXMgYSBmZXRjaCBwcm9maWxlIGl0ZW0gdGhhdCBjYW4gYmUgaW5jbHVkZWQgaW4gYQorCSAqIDxjb2RlPkZldGNoUHJvZmlsZTwvY29kZT4gZHVyaW5nIGEgZmV0Y2ggcmVxdWVzdCB0byBhIEZvbGRlci4KKwkgKiBUaGlzIGl0ZW0gaW5kaWNhdGVzIHRoYXQgdGhlIEdtYWlsIGxhYmVscyBmb3IgbWVzc2FnZXMKKwkgKiBpbiB0aGUgc3BlY2lmaWVkIHJhbmdlIGFyZSBkZXNpcmVkIHRvIGJlIHByZWZldGNoZWQuIDxwPgorCSAqIAorCSAqIEFuIGV4YW1wbGUgb2YgaG93IGEgY2xpZW50IHVzZXMgdGhpcyBpcyBiZWxvdzoKKwkgKiA8YmxvY2txdW90ZT48cHJlPgorCSAqCisJICogCUZldGNoUHJvZmlsZSBmcCA9IG5ldyBGZXRjaFByb2ZpbGUoKTsKKwkgKglmcC5hZGQoR21haWxGb2xkZXIuRmV0Y2hQcm9maWxlSXRlbS5MQUJFTFMpOworCSAqCWZvbGRlci5mZXRjaChtc2dzLCBmcCk7CisJICoKKwkgKiA8L3ByZT48L2Jsb2NrcXVvdGU+CisJICovIAorCXB1YmxpYyBzdGF0aWMgZmluYWwgRmV0Y2hQcm9maWxlSXRlbSBMQUJFTFMgPSAKKwkJbmV3IEZldGNoUHJvZmlsZUl0ZW0oIlgtR00tTEFCRUxTIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBzcGVjaWZpZWQgbGFiZWxzIGZvciB0aGUgZ2l2ZW4gYXJyYXkgb2YgbWVzc2FnZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0JbXNncwl0aGUgbWVzc2FnZXMKKyAgICAgKiBAcGFyYW0JbGFiZWxzCXRoZSBsYWJlbHMgdG8gYWRkIG9yIHJlbW92ZQorICAgICAqIEBwYXJhbQlzZXQJdHJ1ZSB0byBhZGQsIGZhbHNlIHRvIHJlbW92ZQorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uCWZvciBmYWlsdXJlcworICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjUuNQorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXRMYWJlbHMoTWVzc2FnZVtdIG1zZ3MsCisJCQkJU3RyaW5nW10gbGFiZWxzLCBib29sZWFuIHNldCkKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwljaGVja09wZW5lZCgpOworCisJaWYgKG1zZ3MubGVuZ3RoID09IDApIC8vIGJvdW5kYXJ5IGNvbmRpdGlvbgorCSAgICByZXR1cm47CisKKwlzeW5jaHJvbml6ZWQobWVzc2FnZUNhY2hlTG9jaykgeworCSAgICB0cnkgeworCQlJTUFQUHJvdG9jb2wgaXAgPSBnZXRQcm90b2NvbCgpOworCQlhc3NlcnQgaXAgaW5zdGFuY2VvZiBHbWFpbFByb3RvY29sOworCQlHbWFpbFByb3RvY29sIHAgPSAoR21haWxQcm90b2NvbClpcDsKKwkJTWVzc2FnZVNldFtdIG1zID0gVXRpbGl0eS50b01lc3NhZ2VTZXRTb3J0ZWQobXNncywgbnVsbCk7CisJCWlmIChtcyA9PSBudWxsKQorCQkgICAgdGhyb3cgbmV3IE1lc3NhZ2VSZW1vdmVkRXhjZXB0aW9uKAorCQkJCQkiTWVzc2FnZXMgaGF2ZSBiZWVuIHJlbW92ZWQiKTsKKwkJcC5zdG9yZUxhYmVscyhtcywgbGFiZWxzLCBzZXQpOworCSAgICB9IGNhdGNoIChDb25uZWN0aW9uRXhjZXB0aW9uIGNleCkgeworCQl0aHJvdyBuZXcgRm9sZGVyQ2xvc2VkRXhjZXB0aW9uKHRoaXMsIGNleC5nZXRNZXNzYWdlKCkpOworCSAgICB9IGNhdGNoIChQcm90b2NvbEV4Y2VwdGlvbiBwZXgpIHsKKwkJdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbihwZXguZ2V0TWVzc2FnZSgpLCBwZXgpOworCSAgICB9CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgc3BlY2lmaWVkIGxhYmVscyBmb3IgdGhlIGdpdmVuIHJhbmdlIG9mIG1lc3NhZ2UgbnVtYmVycy4KKyAgICAgKgorICAgICAqIEBwYXJhbQlzdGFydAlmaXJzdCBtZXNzYWdlIG51bWJlcgorICAgICAqIEBwYXJhbQllbmQJbGFzdCBtZXNzYWdlIG51bWJlcgorICAgICAqIEBwYXJhbQlsYWJlbHMJdGhlIGxhYmVscyB0byBhZGQgb3IgcmVtb3ZlCisgICAgICogQHBhcmFtCXNldAl0cnVlIHRvIGFkZCwgZmFsc2UgdG8gcmVtb3ZlCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24JZm9yIGZhaWx1cmVzCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNS41CisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHNldExhYmVscyhpbnQgc3RhcnQsIGludCBlbmQsCisJCQkJU3RyaW5nW10gbGFiZWxzLCBib29sZWFuIHNldCkKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwljaGVja09wZW5lZCgpOworCU1lc3NhZ2VbXSBtc2dzID0gbmV3IE1lc3NhZ2VbZW5kIC0gc3RhcnQgKyAxXTsKKwlpbnQgaSA9IDA7CisJZm9yIChpbnQgbiA9IHN0YXJ0OyBuIDw9IGVuZDsgbisrKQorCSAgICBtc2dzW2krK10gPSBnZXRNZXNzYWdlKG4pOworCXNldExhYmVscyhtc2dzLCBsYWJlbHMsIHNldCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBzcGVjaWZpZWQgbGFiZWxzIGZvciB0aGUgZ2l2ZW4gYXJyYXkgb2YgbWVzc2FnZSBudW1iZXJzLgorICAgICAqCisgICAgICogQHBhcmFtCW1zZ251bXMJdGhlIG1lc3NhZ2UgbnVtYmVycworICAgICAqIEBwYXJhbQlsYWJlbHMJdGhlIGxhYmVscyB0byBhZGQgb3IgcmVtb3ZlCisgICAgICogQHBhcmFtCXNldAl0cnVlIHRvIGFkZCwgZmFsc2UgdG8gcmVtb3ZlCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24JZm9yIGZhaWx1cmVzCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNS41CisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHNldExhYmVscyhpbnRbXSBtc2dudW1zLAorCQkJCVN0cmluZ1tdIGxhYmVscywgYm9vbGVhbiBzZXQpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJY2hlY2tPcGVuZWQoKTsKKwlNZXNzYWdlW10gbXNncyA9IG5ldyBNZXNzYWdlW21zZ251bXMubGVuZ3RoXTsKKwlmb3IgKGludCBpID0gMDsgaSA8IG1zZ251bXMubGVuZ3RoOyBpKyspCisJICAgIG1zZ3NbaV0gPSBnZXRNZXNzYWdlKG1zZ251bXNbaV0pOworCXNldExhYmVscyhtc2dzLCBsYWJlbHMsIHNldCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IgdXNlZCB0byBjcmVhdGUgYSBwb3NzaWJseSBub24tZXhpc3RlbnQgZm9sZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGZ1bGxOYW1lCWZ1bGxuYW1lIG9mIHRoaXMgZm9sZGVyCisgICAgICogQHBhcmFtIHNlcGFyYXRvciB0aGUgZGVmYXVsdCBzZXBhcmF0b3IgY2hhcmFjdGVyIGZvciB0aGlzIAorICAgICAqCQkJZm9sZGVyJ3MgbmFtZXNwYWNlCisgICAgICogQHBhcmFtIHN0b3JlCXRoZSBTdG9yZQorICAgICAqIEBwYXJhbSBpc05hbWVzcGFjZSBkb2VzIHRoaXMgbmFtZSByZXByZXNlbnQgYSBuYW1lc3BhY2U/CisgICAgICovCisgICAgcHJvdGVjdGVkIEdtYWlsRm9sZGVyKFN0cmluZyBmdWxsTmFtZSwgY2hhciBzZXBhcmF0b3IsIElNQVBTdG9yZSBzdG9yZSwKKwkJCQlCb29sZWFuIGlzTmFtZXNwYWNlKSB7CisJc3VwZXIoZnVsbE5hbWUsIHNlcGFyYXRvciwgc3RvcmUsIGlzTmFtZXNwYWNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvciB1c2VkIHRvIGNyZWF0ZSBhbiBleGlzdGluZyBmb2xkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0JbGkJdGhlIExpc3RJbmZvIGZvciB0aGlzIGZvbGRlcgorICAgICAqIEBwYXJhbQlzdG9yZQl0aGUgc3RvcmUgY29udGFpbmluZyB0aGlzIGZvbGRlcgorICAgICAqLworICAgIHByb3RlY3RlZCBHbWFpbEZvbGRlcihMaXN0SW5mbyBsaSwgSU1BUFN0b3JlIHN0b3JlKSB7CisJc3VwZXIobGksIHN0b3JlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBuZXcgSU1BUE1lc3NhZ2Ugb2JqZWN0IHRvIHJlcHJlc2VudCB0aGUgZ2l2ZW4gbWVzc2FnZSBudW1iZXIuCisgICAgICovCisgICAgcHJvdGVjdGVkIElNQVBNZXNzYWdlIG5ld0lNQVBNZXNzYWdlKGludCBtc2dudW0pIHsKKwlyZXR1cm4gbmV3IEdtYWlsTWVzc2FnZSh0aGlzLCBtc2dudW0pOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2dpbWFwL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2dpbWFwL0dtYWlsTWVzc2FnZS5qYXZhIGIvZ2ltYXAvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvZ2ltYXAvR21haWxNZXNzYWdlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTJlMWE3YQotLS0gL2Rldi9udWxsCisrKyBiL2dpbWFwL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2dpbWFwL0dtYWlsTWVzc2FnZS5qYXZhCkBAIC0wLDAgKzEsMTM5IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5naW1hcDsKKworaW1wb3J0IGphdmEuaW8uKjsKKworaW1wb3J0IGphdmF4Lm1haWwuKjsKK2ltcG9ydCBqYXZheC5tYWlsLmludGVybmV0Lio7CisKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC4qOworaW1wb3J0IGNvbS5zdW4ubWFpbC5pYXAuKjsKK2ltcG9ydCBjb20uc3VuLm1haWwuaW1hcC4qOworaW1wb3J0IGNvbS5zdW4ubWFpbC5pbWFwLnByb3RvY29sLio7CitpbXBvcnQgY29tLnN1bi5tYWlsLmdpbWFwLnByb3RvY29sLio7CisKKy8qKgorICogQSBHbWFpbCBtZXNzYWdlLiAgQWRkcyBtZXRob2RzIHRvIGFjY2VzcyBHbWFpbC1zcGVjaWZpYyBwZXItbWVzc2FnZSBkYXRhLgorICoKKyAqIEBzaW5jZSBKYXZhTWFpbCAxLjQuNgorICogQGF1dGhvciBCaWxsIFNoYW5ub24KKyAqLworCitwdWJsaWMgY2xhc3MgR21haWxNZXNzYWdlIGV4dGVuZHMgSU1BUE1lc3NhZ2UgeworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yLgorICAgICAqCisgICAgICogQHBhcmFtCWZvbGRlcgl0aGUgY29udGFpbmluZyBmb2xkZXIKKyAgICAgKiBAcGFyYW0JbXNnbnVtCXRoZSBtZXNzYWdlIHNlcXVlbmNlIG51bWJlcgorICAgICAqLworICAgIHByb3RlY3RlZCBHbWFpbE1lc3NhZ2UoSU1BUEZvbGRlciBmb2xkZXIsIGludCBtc2dudW0pIHsKKwlzdXBlcihmb2xkZXIsIG1zZ251bSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IsIGZvciB1c2UgYnkgSU1BUE5lc3RlZE1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jc2Vzc2lvbgl0aGUgU2Vzc2lvbgorICAgICAqLworICAgIHByb3RlY3RlZCBHbWFpbE1lc3NhZ2UoU2Vzc2lvbiBzZXNzaW9uKSB7CisJc3VwZXIoc2Vzc2lvbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBHbWFpbCB1bmlxdWUgbWVzc2FnZSBJRC4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIG1lc3NhZ2UgSUQKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXRNc2dJZCgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCUxvbmcgbXNnaWQgPSAoTG9uZylnZXRJdGVtKEdtYWlsUHJvdG9jb2wuTVNHSURfSVRFTSk7CisJaWYgKG1zZ2lkICE9IG51bGwpCisJICAgIHJldHVybiBtc2dpZC5sb25nVmFsdWUoKTsKKwllbHNlCisJICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIEdtYWlsIHVuaXF1ZSB0aHJlYWQgSUQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSB0aHJlYWQgSUQKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXRUaHJJZCgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCUxvbmcgdGhyaWQgPSAoTG9uZylnZXRJdGVtKEdtYWlsUHJvdG9jb2wuVEhSSURfSVRFTSk7CisJaWYgKHRocmlkICE9IG51bGwpCisJICAgIHJldHVybiB0aHJpZC5sb25nVmFsdWUoKTsKKwllbHNlCisJICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIEdtYWlsIGxhYmVscyBhc3NvY2lhdGVkIHdpdGggdGhpcyBtZXNzYWdlLgorICAgICAqCisgICAgICogQHJldHVybglhcnJheSBvZiBsYWJlbHMsIG9yIGVtcHR5IGFycmF5IGlmIG5vbmUKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nW10gZ2V0TGFiZWxzKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJU3RyaW5nW10gbGFiZWxzID0gKFN0cmluZ1tdKWdldEl0ZW0oR21haWxQcm90b2NvbC5MQUJFTFNfSVRFTSk7CisJaWYgKGxhYmVscyAhPSBudWxsKQorCSAgICByZXR1cm4gKFN0cmluZ1tdKShsYWJlbHMuY2xvbmUoKSk7CisJZWxzZQorCSAgICByZXR1cm4gbmV3IFN0cmluZ1swXTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQvVW5zZXQgdGhlIGdpdmVuIGxhYmVscyBvbiB0aGlzIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0JbGFiZWxzCXRoZSBsYWJlbHMgdG8gYWRkIG9yIHJlbW92ZQorICAgICAqIEBwYXJhbQlzZXQJdHJ1ZSB0byBhZGQgbGFiZWxzLCBmYWxzZSB0byByZW1vdmUKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS41LjUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgc2V0TGFiZWxzKFN0cmluZ1tdIGxhYmVscywgYm9vbGVhbiBzZXQpCisJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gQWNxdWlyZSBNZXNzYWdlQ2FjaGVMb2NrLCB0byBmcmVlemUgc2VxbnVtLgorICAgICAgICBzeW5jaHJvbml6ZWQoZ2V0TWVzc2FnZUNhY2hlTG9jaygpKSB7CisJICAgIHRyeSB7CisJCUlNQVBQcm90b2NvbCBpcCA9IGdldFByb3RvY29sKCk7CisJCWFzc2VydCBpcCBpbnN0YW5jZW9mIEdtYWlsUHJvdG9jb2w7CisJCUdtYWlsUHJvdG9jb2wgcCA9IChHbWFpbFByb3RvY29sKWlwOworCQljaGVja0V4cHVuZ2VkKCk7IC8vIEluc3VyZSB0aGF0IHRoaXMgbWVzc2FnZSBpcyBub3QgZXhwdW5nZWQKKwkJcC5zdG9yZUxhYmVscyhnZXRTZXF1ZW5jZU51bWJlcigpLCBsYWJlbHMsIHNldCk7CisJICAgIH0gY2F0Y2ggKENvbm5lY3Rpb25FeGNlcHRpb24gY2V4KSB7CisJCXRocm93IG5ldyBGb2xkZXJDbG9zZWRFeGNlcHRpb24oZm9sZGVyLCBjZXguZ2V0TWVzc2FnZSgpKTsKKwkgICAgfSBjYXRjaCAoUHJvdG9jb2xFeGNlcHRpb24gcGV4KSB7CisJCXRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24ocGV4LmdldE1lc3NhZ2UoKSwgcGV4KTsKKwkgICAgfQorCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbGVhciBhbnkgY2FjaGVkIGxhYmVscyBmb3IgdGhpcyBtZXNzYWdlLgorICAgICAqIFRoZSBHbWFpbCBsYWJlbHMgZm9yIGEgbWVzc2dlIHdpbGwgYmUgY2FjaGVkIHdoZW4gZmlyc3QgYWNjZXNzZWQKKyAgICAgKiB1c2luZyBlaXRoZXIgdGhlIGZldGNoIG1ldGhvZCBvciB0aGUgZ2V0TGFiZWxzIG1ldGhvZC4gIEdtYWlsIHByb3ZpZGVzCisgICAgICogbm8gbm90aWZpY2F0aW9uIHdoZW4gdGhlIGxhYmVscyBoYXZlIGJlZW4gY2hhbmdlZCBieSBhbm90aGVyIGFwcGxpY2F0aW9uCisgICAgICogc28gYXBwbGljYXRpb25zIG1heSBuZWVkIHRvIGNsZWFyIHRoZSBjYWNoZSBpZiBhY2Nlc3NpbmcgdGhlIGxhYmVscyBmb3IKKyAgICAgKiBhIG1lc3NhZ2UgbW9yZSB0aGFuIG9uY2Ugd2hpbGUgdGhlIEZvbGRlciBpcyBvcGVuLgorICAgICAqCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNS42CisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGNsZWFyQ2FjaGVkTGFiZWxzKCkgeworCWlmIChpdGVtcyAhPSBudWxsKQorCSAgICBpdGVtcy5yZW1vdmUoR21haWxQcm90b2NvbC5MQUJFTFNfSVRFTS5nZXROYW1lKCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2dpbWFwL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2dpbWFwL0dtYWlsTXNnSWRUZXJtLmphdmEgYi9naW1hcC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9naW1hcC9HbWFpbE1zZ0lkVGVybS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjliM2E2MGQKLS0tIC9kZXYvbnVsbAorKysgYi9naW1hcC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9naW1hcC9HbWFpbE1zZ0lkVGVybS5qYXZhCkBAIC0wLDAgKzEsNzQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmdpbWFwOworCitpbXBvcnQgamF2YXgubWFpbC5NZXNzYWdlOworaW1wb3J0IGphdmF4Lm1haWwuc2VhcmNoLlN0cmluZ1Rlcm07CisKKy8qKgorICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIHNlYXJjaGluZyBmb3IgdGhlIEdtYWlsIG1lc3NhZ2UgSUQuCisgKgorICogQHNpbmNlIEphdmFNYWlsIDEuNC42CisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCisKK3B1YmxpYyBmaW5hbCBjbGFzcyBHbWFpbE1zZ0lkVGVybSBleHRlbmRzIExvbmdUZXJtIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC03MDkwOTA5NDAxMDcxNjI2ODY2TDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZ0lkICB0aGUgbWVzc2FnZSBJRAorICAgICAqLworICAgIHB1YmxpYyBHbWFpbE1zZ0lkVGVybShsb25nIG1zZ0lkKSB7CisJc3VwZXIobXNnSWQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBtYXRjaCBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbXNnCXRoZSBNZXNzYWdlIG51bWJlciBpcyBtYXRjaGVkIHdpdGggdGhpcyBNZXNzYWdlCisgICAgICogQHJldHVybgkJdHJ1ZSBpZiB0aGUgbWF0Y2ggc3VjY2VlZHMsIG90aGVyd2lzZSBmYWxzZQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIG1hdGNoKE1lc3NhZ2UgbXNnKSB7CisJbG9uZyBtc2dJZDsKKworCXRyeSB7CisJICAgIGlmIChtc2cgaW5zdGFuY2VvZiBHbWFpbE1lc3NhZ2UpCisJCW1zZ0lkID0gKChHbWFpbE1lc3NhZ2UpbXNnKS5nZXRNc2dJZCgpOworCSAgICBlbHNlCisJCXJldHVybiBmYWxzZTsKKwl9IGNhdGNoIChFeGNlcHRpb24gZSkgeworCSAgICByZXR1cm4gZmFsc2U7CisJfQorCisJcmV0dXJuIHN1cGVyLm1hdGNoKG1zZ0lkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFcXVhbGl0eSBjb21wYXJpc29uLgorICAgICAqCisgICAgICogQHBhcmFtCW9iagl0aGUgb2JqZWN0IHRvIGNvbXBhcmUgd2l0aAorICAgICAqIEByZXR1cm4JCXRydWUgaWYgZXF1YWwKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgeworCWlmICghKG9iaiBpbnN0YW5jZW9mIEdtYWlsTXNnSWRUZXJtKSkKKwkgICAgcmV0dXJuIGZhbHNlOworCXJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9naW1hcC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9naW1hcC9HbWFpbFByb3ZpZGVyLmphdmEgYi9naW1hcC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9naW1hcC9HbWFpbFByb3ZpZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGE1NjI2MwotLS0gL2Rldi9udWxsCisrKyBiL2dpbWFwL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2dpbWFwL0dtYWlsUHJvdmlkZXIuamF2YQpAQCAtMCwwICsxLDI5IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5naW1hcDsKKworaW1wb3J0IGphdmF4Lm1haWwuUHJvdmlkZXI7CisKKy8qKgorICogVGhlIEdtYWlsIElNQVAgcHJvdG9jb2wgcHJvdmlkZXIuCisgKi8KK3B1YmxpYyBjbGFzcyBHbWFpbFByb3ZpZGVyIGV4dGVuZHMgUHJvdmlkZXIgeworICAgIHB1YmxpYyBHbWFpbFByb3ZpZGVyKCkgeworCXN1cGVyKFByb3ZpZGVyLlR5cGUuU1RPUkUsICJnaW1hcCIsIEdtYWlsU3RvcmUuY2xhc3MuZ2V0TmFtZSgpLAorCSAgICAiT3JhY2xlIiwgbnVsbCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvZ2ltYXAvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvZ2ltYXAvR21haWxSYXdTZWFyY2hUZXJtLmphdmEgYi9naW1hcC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9naW1hcC9HbWFpbFJhd1NlYXJjaFRlcm0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42NjI2NDY3Ci0tLSAvZGV2L251bGwKKysrIGIvZ2ltYXAvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvZ2ltYXAvR21haWxSYXdTZWFyY2hUZXJtLmphdmEKQEAgLTAsMCArMSw2MiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuZ2ltYXA7CisKK2ltcG9ydCBqYXZheC5tYWlsLk1lc3NhZ2U7CitpbXBvcnQgamF2YXgubWFpbC5zZWFyY2guU3RyaW5nVGVybTsKKworLyoqCisgKiBUaGlzIGNsYXNzIGltcGxlbWVudHMgc2VhcmNoaW5nIHVzaW5nIHRoZSBHbWFpbCBYLUdNLVJBVyBleHRlbnNpb24uCisgKgorICogQHNpbmNlIEphdmFNYWlsIDEuNC42CisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCisKK3B1YmxpYyBmaW5hbCBjbGFzcyBHbWFpbFJhd1NlYXJjaFRlcm0gZXh0ZW5kcyBTdHJpbmdUZXJtIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDYyODQ3MzAxNDA0MjQyNDI2NjJMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGF0dGVybiAgdGhlIHBhdHRlcm4gdG8gc2VhcmNoIGZvcgorICAgICAqLworICAgIHB1YmxpYyBHbWFpbFJhd1NlYXJjaFRlcm0oU3RyaW5nIHBhdHRlcm4pIHsKKwkvLyBOb3RlOiBjb21wYXJpc29uIGlzIGNhc2UtaW5zZW5zaXRpdmUKKwlzdXBlcihwYXR0ZXJuKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgbWF0Y2ggbWV0aG9kLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZwl0aGUgcGF0dGVybiBtYXRjaCBpcyBhcHBsaWVkIHRvIHRoaXMgTWVzc2FnZSdzIAorICAgICAqCQkJc3ViamVjdCBoZWFkZXIKKyAgICAgKiBAZXhjZXB0aW9uCVJ1bnRpbWVFeGNlcHRpb24JdGhpcyBjYW4ndCBiZSBzdXBwb3J0ZWQgbG9jYWxseQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIG1hdGNoKE1lc3NhZ2UgbXNnKSB7CisJdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkdtYWlsUmF3U2VhcmNoVGVybSBub3Qgc3VwcG9ydGVkIGxvY2FsbHkiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFcXVhbGl0eSBjb21wYXJpc29uLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CisJaWYgKCEob2JqIGluc3RhbmNlb2YgR21haWxSYXdTZWFyY2hUZXJtKSkKKwkgICAgcmV0dXJuIGZhbHNlOworCXJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9naW1hcC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9naW1hcC9HbWFpbFNTTFByb3ZpZGVyLmphdmEgYi9naW1hcC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9naW1hcC9HbWFpbFNTTFByb3ZpZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWQ4NjUyMwotLS0gL2Rldi9udWxsCisrKyBiL2dpbWFwL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2dpbWFwL0dtYWlsU1NMUHJvdmlkZXIuamF2YQpAQCAtMCwwICsxLDI5IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5naW1hcDsKKworaW1wb3J0IGphdmF4Lm1haWwuUHJvdmlkZXI7CisKKy8qKgorICogVGhlIEdtYWlsIElNQVAgcHJvdG9jb2wgcHJvdmlkZXIuCisgKi8KK3B1YmxpYyBjbGFzcyBHbWFpbFNTTFByb3ZpZGVyIGV4dGVuZHMgUHJvdmlkZXIgeworICAgIHB1YmxpYyBHbWFpbFNTTFByb3ZpZGVyKCkgeworCXN1cGVyKFByb3ZpZGVyLlR5cGUuU1RPUkUsICJnaW1hcHMiLCBHbWFpbFNTTFN0b3JlLmNsYXNzLmdldE5hbWUoKSwKKwkgICAgIk9yYWNsZSIsIG51bGwpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2dpbWFwL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2dpbWFwL0dtYWlsU1NMU3RvcmUuamF2YSBiL2dpbWFwL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2dpbWFwL0dtYWlsU1NMU3RvcmUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZjg1NWY0Ci0tLSAvZGV2L251bGwKKysrIGIvZ2ltYXAvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvZ2ltYXAvR21haWxTU0xTdG9yZS5qYXZhCkBAIC0wLDAgKzEsNDEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmdpbWFwOworCitpbXBvcnQgamF2YXgubWFpbC4qOworCisvKioKKyAqIFN1cHBvcnQgImdpbWFwcyIgcHJvdG9jb2wgbmFtZS4KKyAqIFVubmVjZXNzYXJ5LCBzaW5jZSBHbWFpbCBhbHdheXMgdXNlcyBTU0wsIGJ1dCBzb21lb25lIG1pZ2h0CisgKiBleHBlY3QgdGhpcyBuYW1lIHRvIHdvcmsuCisgKgorICogQHNpbmNlIEphdmFNYWlsIDEuNC42CisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCisKK3B1YmxpYyBjbGFzcyBHbWFpbFNTTFN0b3JlIGV4dGVuZHMgR21haWxTdG9yZSB7CisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IgdGhhdCB0YWtlcyBhIFNlc3Npb24gb2JqZWN0IGFuZCBhIFVSTE5hbWUgdGhhdAorICAgICAqIHJlcHJlc2VudHMgYSBzcGVjaWZpYyBJTUFQIHNlcnZlci4KKyAgICAgKgorICAgICAqIEBwYXJhbQlzZXNzaW9uCXRoZSBTZXNzaW9uCisgICAgICogQHBhcmFtCXVybAl0aGUgVVJMTmFtZSBvZiB0aGlzIHN0b3JlCisgICAgICovCisgICAgcHVibGljIEdtYWlsU1NMU3RvcmUoU2Vzc2lvbiBzZXNzaW9uLCBVUkxOYW1lIHVybCkgeworCXN1cGVyKHNlc3Npb24sIHVybCwgImdpbWFwcyIsIHRydWUpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2dpbWFwL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2dpbWFwL0dtYWlsU3RvcmUuamF2YSBiL2dpbWFwL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2dpbWFwL0dtYWlsU3RvcmUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mYjY1MWFmCi0tLSAvZGV2L251bGwKKysrIGIvZ2ltYXAvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvZ2ltYXAvR21haWxTdG9yZS5qYXZhCkBAIC0wLDAgKzEsOTQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmdpbWFwOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworaW1wb3J0IGphdmF4Lm1haWwuKjsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC5pYXAuUHJvdG9jb2xFeGNlcHRpb247CitpbXBvcnQgY29tLnN1bi5tYWlsLmltYXAuSU1BUFN0b3JlOworaW1wb3J0IGNvbS5zdW4ubWFpbC5pbWFwLklNQVBGb2xkZXI7CitpbXBvcnQgY29tLnN1bi5tYWlsLmltYXAucHJvdG9jb2wuSU1BUFByb3RvY29sOworaW1wb3J0IGNvbS5zdW4ubWFpbC5pbWFwLnByb3RvY29sLkxpc3RJbmZvOworaW1wb3J0IGNvbS5zdW4ubWFpbC5naW1hcC5wcm90b2NvbC5HbWFpbFByb3RvY29sOworCisvKioKKyAqIEEgR21haWwgU3RvcmUuICBEZWZhdWx0cyB0byBpbWFwLmdtYWlsLmNvbSB3aXRoIFNTTC4KKyAqIFVzZXMgYSBHbWFpbFByb3RvY29sIGFuZCBHbWFpbCBGb2xkZXIgdG8gc3VwcG9ydCBHbWFpbCBleHRlbnNpb25zLgorICoKKyAqIEBzaW5jZSBKYXZhTWFpbCAxLjQuNgorICogQGF1dGhvciBCaWxsIFNoYW5ub24KKyAqLworCitwdWJsaWMgY2xhc3MgR21haWxTdG9yZSBleHRlbmRzIElNQVBTdG9yZSB7CisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IgdGhhdCB0YWtlcyBhIFNlc3Npb24gb2JqZWN0IGFuZCBhIFVSTE5hbWUgdGhhdAorICAgICAqIHJlcHJlc2VudHMgYSBzcGVjaWZpYyBJTUFQIHNlcnZlci4KKyAgICAgKgorICAgICAqIEBwYXJhbQlzZXNzaW9uCXRoZSBTZXNzaW9uCisgICAgICogQHBhcmFtCXVybAl0aGUgVVJMTmFtZSBvZiB0aGlzIHN0b3JlCisgICAgICovCisgICAgcHVibGljIEdtYWlsU3RvcmUoU2Vzc2lvbiBzZXNzaW9uLCBVUkxOYW1lIHVybCkgeworCXRoaXMoc2Vzc2lvbiwgdXJsLCAiZ2ltYXAiLCB0cnVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvciB1c2VkIGJ5IEdtYWlsU1NMU3RvcmUgc3ViY2xhc3MuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jc2Vzc2lvbgl0aGUgU2Vzc2lvbgorICAgICAqIEBwYXJhbQl1cmwJdGhlIFVSTE5hbWUgb2YgdGhpcyBzdG9yZQorICAgICAqIEBwYXJhbQluYW1lCXRoZSBwcm90b2NvbCBuYW1lCisgICAgICogQHBhcmFtCWlzU1NMCXVzZSBTU0wgdG8gY29ubmVjdD8KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgR21haWxTdG9yZShTZXNzaW9uIHNlc3Npb24sIFVSTE5hbWUgdXJsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZSwgYm9vbGVhbiBpc1NTTCkgeworCXN1cGVyKHNlc3Npb24sIHVybCwgbmFtZSwgdHJ1ZSk7CS8vIEdtYWlsIHJlcXVpcmVzIFNTTAorICAgIH0KKworICAgIHByb3RlY3RlZCBib29sZWFuIHByb3RvY29sQ29ubmVjdChTdHJpbmcgaG9zdCwgaW50IHBwb3J0LAorCQkJCVN0cmluZyB1c2VyLCBTdHJpbmcgcGFzc3dvcmQpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKGhvc3QgPT0gbnVsbCkKKwkgICAgaG9zdCA9ICJpbWFwLmdtYWlsLmNvbSI7CQkvLyBkZWZhdWx0IHRvIEdtYWlsIGhvc3QKKwlyZXR1cm4gc3VwZXIucHJvdG9jb2xDb25uZWN0KGhvc3QsIHBwb3J0LCB1c2VyLCBwYXNzd29yZCk7CisgICAgfQorCisgICAgcHJvdGVjdGVkIElNQVBQcm90b2NvbCBuZXdJTUFQUHJvdG9jb2woU3RyaW5nIGhvc3QsIGludCBwb3J0KQorCQkJCXRocm93cyBJT0V4Y2VwdGlvbiwgUHJvdG9jb2xFeGNlcHRpb24geworCXJldHVybiBuZXcgR21haWxQcm90b2NvbChuYW1lLCBob3N0LCBwb3J0LCAKKwkJCQkJICAgIHNlc3Npb24uZ2V0UHJvcGVydGllcygpLAorCQkJCQkgICAgaXNTU0wsCisJCQkJCSAgICBsb2dnZXIKKwkJCQkJICAgKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYW4gSU1BUEZvbGRlciBvYmplY3QuCisgICAgICovCisgICAgcHJvdGVjdGVkIElNQVBGb2xkZXIgbmV3SU1BUEZvbGRlcihTdHJpbmcgZnVsbE5hbWUsIGNoYXIgc2VwYXJhdG9yLAorCQkJCUJvb2xlYW4gaXNOYW1lc3BhY2UpIHsKKwlyZXR1cm4gbmV3IEdtYWlsRm9sZGVyKGZ1bGxOYW1lLCBzZXBhcmF0b3IsIHRoaXMsIGlzTmFtZXNwYWNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYW4gSU1BUEZvbGRlciBvYmplY3QuCisgICAgICovCisgICAgcHJvdGVjdGVkIElNQVBGb2xkZXIgbmV3SU1BUEZvbGRlcihMaXN0SW5mbyBsaSkgeworCXJldHVybiBuZXcgR21haWxGb2xkZXIobGksIHRoaXMpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2dpbWFwL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2dpbWFwL0dtYWlsVGhySWRUZXJtLmphdmEgYi9naW1hcC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9naW1hcC9HbWFpbFRocklkVGVybS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkxMDFkNzMKLS0tIC9kZXYvbnVsbAorKysgYi9naW1hcC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9naW1hcC9HbWFpbFRocklkVGVybS5qYXZhCkBAIC0wLDAgKzEsNzQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmdpbWFwOworCitpbXBvcnQgamF2YXgubWFpbC5NZXNzYWdlOworaW1wb3J0IGphdmF4Lm1haWwuc2VhcmNoLlN0cmluZ1Rlcm07CisKKy8qKgorICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIHNlYXJjaGluZyBmb3IgdGhlIEdtYWlsIHRocmVhZCBJRC4KKyAqCisgKiBAc2luY2UgSmF2YU1haWwgMS40LjYKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKi8KKworcHVibGljIGZpbmFsIGNsYXNzIEdtYWlsVGhySWRUZXJtIGV4dGVuZHMgTG9uZ1Rlcm0geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTQ1NDkyNjg1MDIxODM3Mzk3NDRMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGhySWQgIHRoZSB0aHJlYWQgSUQKKyAgICAgKi8KKyAgICBwdWJsaWMgR21haWxUaHJJZFRlcm0obG9uZyB0aHJJZCkgeworCXN1cGVyKHRocklkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgbWF0Y2ggbWV0aG9kLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZwl0aGUgTWVzc2FnZSBudW1iZXIgaXMgbWF0Y2hlZCB3aXRoIHRoaXMgTWVzc2FnZQorICAgICAqIEByZXR1cm4JCXRydWUgaWYgdGhlIG1hdGNoIHN1Y2NlZWRzLCBvdGhlcndpc2UgZmFsc2UKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBtYXRjaChNZXNzYWdlIG1zZykgeworCWxvbmcgdGhySWQ7CisKKwl0cnkgeworCSAgICBpZiAobXNnIGluc3RhbmNlb2YgR21haWxNZXNzYWdlKQorCQl0aHJJZCA9ICgoR21haWxNZXNzYWdlKW1zZykuZ2V0VGhySWQoKTsKKwkgICAgZWxzZQorCQlyZXR1cm4gZmFsc2U7CisJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKwkgICAgcmV0dXJuIGZhbHNlOworCX0KKworCXJldHVybiBzdXBlci5tYXRjaCh0aHJJZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXF1YWxpdHkgY29tcGFyaXNvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbQlvYmoJdGhlIG9iamVjdCB0byBjb21wYXJlIHdpdGgKKyAgICAgKiBAcmV0dXJuCQl0cnVlIGlmIGVxdWFsCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKKwlpZiAoIShvYmogaW5zdGFuY2VvZiBHbWFpbFRocklkVGVybSkpCisJICAgIHJldHVybiBmYWxzZTsKKwlyZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvZ2ltYXAvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvZ2ltYXAvTG9uZ1Rlcm0uamF2YSBiL2dpbWFwL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2dpbWFwL0xvbmdUZXJtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmVjMTg5ZAotLS0gL2Rldi9udWxsCisrKyBiL2dpbWFwL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2dpbWFwL0xvbmdUZXJtLmphdmEKQEAgLTAsMCArMSw3MSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuZ2ltYXA7CisKK2ltcG9ydCBqYXZheC5tYWlsLnNlYXJjaC5TZWFyY2hUZXJtOworCisvKioKKyAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyBhIGxvbmcgaW50ZWdlciBzZWFyY2ggdGVybS4KKyAqCisgKiBAc2luY2UgSmF2YU1haWwgMS40LjYKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKi8KKworYWJzdHJhY3QgY2xhc3MgTG9uZ1Rlcm0gZXh0ZW5kcyBTZWFyY2hUZXJtIHsKKyAgICAvKioKKyAgICAgKiBUaGUgbnVtYmVyLgorICAgICAqCisgICAgICogQHNlcmlhbAorICAgICAqLworICAgIHByb3RlY3RlZCBsb25nIG51bWJlcjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDUyODUxNDcxOTMyNDYxMjgwNDNMOworCisgICAgcHJvdGVjdGVkIExvbmdUZXJtKGxvbmcgbnVtYmVyKSB7CisJdGhpcy5udW1iZXIgPSBudW1iZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBudW1iZXIgdG8gY29tcGFyZSB3aXRoLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgbnVtYmVyCisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0TnVtYmVyKCkgeworCXJldHVybiBudW1iZXI7CisgICAgfQorCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gbWF0Y2gobG9uZyBpKSB7CisJcmV0dXJuIGkgPT0gbnVtYmVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVxdWFsaXR5IGNvbXBhcmlzb24uCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKKwlpZiAoIShvYmogaW5zdGFuY2VvZiBMb25nVGVybSkpCisJICAgIHJldHVybiBmYWxzZTsKKwlMb25nVGVybSB0ID0gKExvbmdUZXJtKW9iajsKKwlyZXR1cm4gdC5udW1iZXIgPT0gdGhpcy5udW1iZXIgJiYgc3VwZXIuZXF1YWxzKG9iaik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcHV0ZSBhIGhhc2hDb2RlIGZvciB0aGlzIG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworCXJldHVybiAoaW50KW51bWJlciArIHN1cGVyLmhhc2hDb2RlKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvZ2ltYXAvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvZ2ltYXAvcGFja2FnZS5odG1sIGIvZ2ltYXAvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvZ2ltYXAvcGFja2FnZS5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkxNjEzNzIKLS0tIC9kZXYvbnVsbAorKysgYi9naW1hcC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9naW1hcC9wYWNrYWdlLmh0bWwKQEAgLTAsMCArMSwxMDUgQEAKKzwhRE9DVFlQRSBodG1sIFBVQkxJQyAiLS8vVzNDLy9EVEQgSFRNTCA0LjAxIFRyYW5zaXRpb25hbC8vRU4iPgorPEhUTUw+Cis8SEVBRD4KKzxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PXV0Zi04Ij4KKzwhLS0KKworICAgIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorCisgICAgVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgICAgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisKKyAgICBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgICAgTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICAgIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICAgIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorCisgICAgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisKKy0tPgorCis8VElUTEU+Y29tLnN1bi5tYWlsLmdpbWFwIHBhY2thZ2U8L1RJVExFPgorPC9IRUFEPgorPEJPRFkgQkdDT0xPUj0id2hpdGUiPgorCis8UD4KK0FuIEVYUEVSSU1FTlRBTCBJTUFQIHByb3RvY29sIHByb3ZpZGVyIHRoYXQgc3VwcG9ydHMgdGhlCis8QSBIUkVGPSJodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9nb29nbGUtYXBwcy9nbWFpbC9pbWFwX2V4dGVuc2lvbnMiCitUQVJHRVQ9Il90b3AiPgorR21haWwtc3BlY2lmaWMgSU1BUCBwcm90b2NvbCBleHRlbnNpb25zCis8L0E+LgorVGhpcyBwcm92aWRlciBzdXBwb3J0cyBhbGwgdGhlIGZlYXR1cmVzIG9mIHRoZSBJTUFQIHByb3ZpZGVyLCBwbHVzCithZGRpdGlvbmFsIEdtYWlsLXNwZWNpZmljIGZlYXR1cmVzLgorVGhpcyBwcm92aWRlciBjYW4gYmUgdXNlZCBieSBpbmNsdWRpbmcgZ2ltYXAuamFyIGluIHlvdXIgQ0xBU1NQQVRICithbG9uZyB3aXRoIG1haWwuamFyLCBhbmQgYnkgdXNpbmcgdGhlICJnaW1hcCIgcHJvdG9jb2wgaW5zdGVhZCBvZgordGhlICJpbWFwIiBwcm90b2NvbC4KK1JlbWVtYmVyIHRoYXQgdGhpcyBtZWFucyB0aGF0IGFsbCBwcm9wZXJ0aWVzIHNob3VsZCBiZSBuYW1lZCAibWFpbC5naW1hcC4qIiwKK2J1dCB0aGF0IG90aGVyd2lzZSB0aGlzIHByb3ZpZGVyIHN1cHBvcnRzIGFsbCB0aGUgc2FtZSBwcm9wZXJ0aWVzIGFzIHRoZQorSU1BUCBwcm90b2NvbCBwcm92aWRlci4KK1RoZSBHbWFpbCBJTUFQIHByb3ZpZGVyIGRlZmF1bHRzIHRvIHVzaW5nIFNTTCB0byBjb25uZWN0IHRvICJpbWFwLmdtYWlsLmNvbSIuCis8L1A+Cis8UD4KK0luIGdlbmVyYWwsIGFwcGxpY2F0aW9ucyBzaG91bGQgbm90IG5lZWQgdG8gdXNlIHRoZSBjbGFzc2VzIGluIHRoaXMKK3BhY2thZ2UgZGlyZWN0bHkuICBJbnN0ZWFkLCB0aGV5IHNob3VsZCB1c2UgdGhlIEFQSXMgZGVmaW5lZCBieSB0aGUKKzxjb2RlPmphdmF4Lm1haWw8L2NvZGU+IHBhY2thZ2UgKGFuZCBzdWJwYWNrYWdlcykuICBBcHBsaWNhdGlvbnMgc2hvdWxkCituZXZlciBjb25zdHJ1Y3QgaW5zdGFuY2VzIG9mIDxjb2RlPkdtYWlsU3RvcmU8L2NvZGU+IG9yCis8Y29kZT5HbWFpbEZvbGRlcjwvY29kZT4gZGlyZWN0bHkuICBJbnN0ZWFkLCB0aGV5IHNob3VsZCB1c2UgdGhlCis8Y29kZT5TZXNzaW9uPC9jb2RlPiBtZXRob2QgPGNvZGU+Z2V0U3RvcmU8L2NvZGU+IHRvIGFjcXVpcmUgYW4KK2FwcHJvcHJpYXRlIDxjb2RlPlN0b3JlPC9jb2RlPiBvYmplY3QsIGFuZCBmcm9tIHRoYXQgYWNxdWlyZQorPGNvZGU+Rm9sZGVyPC9jb2RlPiBvYmplY3RzLgorPC9QPgorPFA+CitNZXNzYWdlIG9iamVjdHMgcmV0dXJuZWQgYnkgdGhpcyBwcm92aWRlciBtYXkgYmUgY2FzdCB0byBHbWFpbE1lc3NhZ2UKK3RvIGFjY2VzcyBHbWFpbC1zcGVjaWZpYyBkYXRhLCBlLmcuLCB1c2luZyB0aGUgbWV0aG9kcyBHbWFpbE1lc3NhZ2UuZ2V0TXNnSWQoKSwKK0dtYWlsTWVzc2FnZS5nZXRUaHJJZCgpLCBhbmQgR21haWxNZXNzYWdlLmdldExhYmVscygpLgorRm9yIGV4YW1wbGU6Cis8L1A+Cis8UFJFPgorICAgIEdtYWlsTWVzc2FnZSBnbXNnID0gKEdtYWlsTWVzc2FnZSltc2c7CisgICAgU3lzdGVtLm91dC5wcmludGxuKCJHbWFpbCBtZXNzYWdlIElEIGlzICIgKyBnbXNnLmdldE1zZ0lkKCkpOworICAgIFN0cmluZ1tdIGxhYmVscyA9IGdtc2cuZ2V0TGFiZWxzKCk7CisgICAgZm9yIChTdHJpbmcgcyA6IGxhYmVscykKKwlTeXN0ZW0ub3V0LnByaW50bG4oIkdtYWlsIG1lc3NhZ2UgbGFiZWw6ICIgKyBzKTsKKzwvUFJFPgorPFA+CitHbWFpbC1zcGVjaWZpYyBkYXRhIG1heSBiZSBwcmVmZXRjaGVkIHVzaW5nIHRoZSBHbWFpbEZvbGRlci5GZXRjaFByb2ZpbGVJdGVtcworTVNHSUQsIFRIUklELCBhbmQgTEFCRUxTLgorRm9yIGV4YW1wbGU6Cis8L1A+Cis8UFJFPgorICAgIEZldGNoUHJvZmlsZSBmcCA9IG5ldyBGZXRjaFByb2ZpbGUoKTsKKyAgICBmcC5hZGQoR21haWxGb2xkZXIuRmV0Y2hQcm9maWxlSXRlbS5NU0dJRCk7CisgICAgZm9sZGVyLmZldGNoKGZwKTsKKzwvUFJFPgorPFA+CitZb3UgY2FuIHNlYXJjaCB1c2luZyBHbWFpbC1zcGVjaWZpYyBkYXRhIHVzaW5nIHRoZSBHbWFpbE1zZ0lkVGVybSwKK0dtYWlsVGhySWRUZXJtLCBhbmQgR21haWxSYXdTZWFyY2hUZXJtIHNlYXJjaCB0ZXJtcy4KK0ZvciBleGFtcGxlOgorPC9QPgorPFBSRT4KKyAgICAvLyBmaW5kIHRoZSBtZXNzYWdlIHdpdGggdGhpcyBHbWFpbCB1bmlxdWUgbWVzc2FnZSBJRAorICAgIGxvbmcgbXNnaWQgPSAuLi47CisgICAgTWVzc2FnZVtdIG1zZ3MgPSBmb2xkZXIuc2VhcmNoKG5ldyBHbWFpbE1zZ0lkVGVybShtc2dpZCkpOworPC9QUkU+Cis8UD4KK1lvdSBjYW4gYWNjZXNzIHRoZSBHbWFpbCBleHRlbmRlZCBhdHRyaWJ1dGVzIChyZXR1cm5lZCBieSBYTElTVCkgZm9yIGEKK2ZvbGRlciB1c2luZyB0aGUgSU1BUEZvbGRlci5nZXRBdHRyaWJ1dGVzKCkgbWV0aG9kLgorRm9yIGV4YW1wbGU6Cis8L1A+Cis8UFJFPgorICAgIElNQVBGb2xkZXIgaWZvbGRlciA9IChJTUFQRm9sZGVyKWZvbGRlcjsKKyAgICBTdHJpbmdbXSBhdHRycyA9IGlmb2xkZXIuZ2V0QXR0cmlidXRlcygpOworICAgIGZvciAoU3RyaW5nIHMgOiBhdHRycykKKwlTeXN0ZW0ub3V0LnByaW50bG4oIkZvbGRlciBhdHRyaWJ1dGU6ICIgKyBzKTsKKzwvUFJFPgorPFA+Cis8c3Ryb25nPldBUk5JTkc6PC9zdHJvbmc+IFRoZSBBUElzIHVuaXF1ZSB0byB0aGlzIHBhY2thZ2Ugc2hvdWxkIGJlCitjb25zaWRlcmVkIDxzdHJvbmc+RVhQRVJJTUVOVEFMPC9zdHJvbmc+LiAgVGhleSBtYXkgYmUgY2hhbmdlZCBpbiB0aGUKK2Z1dHVyZSBpbiB3YXlzIHRoYXQgYXJlIGluY29tcGF0aWJsZSB3aXRoIGFwcGxpY2F0aW9ucyB1c2luZyB0aGUKK2N1cnJlbnQgQVBJcy4KKzwvUD4KKworPC9CT0RZPgorPC9IVE1MPgpkaWZmIC0tZ2l0IGEvZ2ltYXAvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvZ2ltYXAvcHJvdG9jb2wvR21haWxQcm90b2NvbC5qYXZhIGIvZ2ltYXAvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvZ2ltYXAvcHJvdG9jb2wvR21haWxQcm90b2NvbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMzZTNmYjEKLS0tIC9kZXYvbnVsbAorKysgYi9naW1hcC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9naW1hcC9wcm90b2NvbC9HbWFpbFByb3RvY29sLmphdmEKQEAgLTAsMCArMSwxOTAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmdpbWFwLnByb3RvY29sOworCitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmEudXRpbC4qOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuU3RhbmRhcmRDaGFyc2V0czsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC5pYXAuKjsKK2ltcG9ydCBjb20uc3VuLm1haWwuaW1hcC5wcm90b2NvbC4qOworaW1wb3J0IGNvbS5zdW4ubWFpbC5naW1hcC5HbWFpbEZvbGRlci5GZXRjaFByb2ZpbGVJdGVtOworCitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuTWFpbExvZ2dlcjsKKworLyoqCisgKiBFeHRlbmQgSU1BUCBzdXBwb3J0IHRvIGhhbmRsZSBHbWFpbC1zcGVjaWZpYyBwcm90b2NvbCBleHRlbnNpb25zLgorICoKKyAqIEBzaW5jZSBKYXZhTWFpbCAxLjQuNgorICogQGF1dGhvciBCaWxsIFNoYW5ub24KKyAqLworCitwdWJsaWMgY2xhc3MgR21haWxQcm90b2NvbCBleHRlbmRzIElNQVBQcm90b2NvbCB7CisgICAgCisgICAgLyoKKyAgICAgKiBEZWZpbmUgdGhlIEdtYWlsLXNwZWNpZmljIEZFVENIIGl0ZW1zLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmV0Y2hJdGVtIE1TR0lEX0lURU0gPQorCW5ldyBGZXRjaEl0ZW0oIlgtR00tTVNHSUQiLCBGZXRjaFByb2ZpbGVJdGVtLk1TR0lEKSB7CisJICAgIHB1YmxpYyBPYmplY3QgcGFyc2VJdGVtKEZldGNoUmVzcG9uc2UgcikgeworCQlyZXR1cm4gTG9uZy52YWx1ZU9mKHIucmVhZExvbmcoKSk7CisJICAgIH0KKwl9OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmV0Y2hJdGVtIFRIUklEX0lURU0gPQorCW5ldyBGZXRjaEl0ZW0oIlgtR00tVEhSSUQiLCBGZXRjaFByb2ZpbGVJdGVtLlRIUklEKSB7CisJICAgIHB1YmxpYyBPYmplY3QgcGFyc2VJdGVtKEZldGNoUmVzcG9uc2UgcikgeworCQlyZXR1cm4gTG9uZy52YWx1ZU9mKHIucmVhZExvbmcoKSk7CisJICAgIH0KKwl9OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRmV0Y2hJdGVtIExBQkVMU19JVEVNID0KKwluZXcgRmV0Y2hJdGVtKCJYLUdNLUxBQkVMUyIsIEZldGNoUHJvZmlsZUl0ZW0uTEFCRUxTKSB7CisJICAgIHB1YmxpYyBPYmplY3QgcGFyc2VJdGVtKEZldGNoUmVzcG9uc2UgcikgeworCQlyZXR1cm4gci5yZWFkQXRvbVN0cmluZ0xpc3QoKTsKKwkgICAgfQorCX07CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBGZXRjaEl0ZW1bXSBteUZldGNoSXRlbXMgPSB7CisJTVNHSURfSVRFTSwKKwlUSFJJRF9JVEVNLAorCUxBQkVMU19JVEVNCisgICAgfTsKKworICAgIHByaXZhdGUgRmV0Y2hJdGVtW10gZmV0Y2hJdGVtcyA9IG51bGw7CisKKyAgICAvKioKKyAgICAgKiBDb25uZWN0IHRvIEdtYWlsLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUJdGhlIHByb3RvY29sIG5hbWUKKyAgICAgKiBAcGFyYW0gaG9zdAlob3N0IHRvIGNvbm5lY3QgdG8KKyAgICAgKiBAcGFyYW0gcG9ydAlwb3J0bnVtYmVyIHRvIGNvbm5lY3QgdG8KKyAgICAgKiBAcGFyYW0gcHJvcHMJUHJvcGVydGllcyBvYmplY3QgdXNlZCBieSB0aGlzIHByb3RvY29sCisgICAgICogQHBhcmFtIGlzU1NMCXVzZSBTU0w/CisgICAgICogQHBhcmFtIGxvZ2dlcglmb3IgbG9nIG1lc3NhZ2VzCisgICAgICogQGV4Y2VwdGlvbglJT0V4Y2VwdGlvbglmb3IgSS9PIGVycm9ycworICAgICAqIEBleGNlcHRpb24JUHJvdG9jb2xFeGNlcHRpb24JZm9yIHByb3RvY29sIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIEdtYWlsUHJvdG9jb2woU3RyaW5nIG5hbWUsIFN0cmluZyBob3N0LCBpbnQgcG9ydCwgCisJCQlQcm9wZXJ0aWVzIHByb3BzLCBib29sZWFuIGlzU1NMLCBNYWlsTG9nZ2VyIGxvZ2dlcikKKwkJCXRocm93cyBJT0V4Y2VwdGlvbiwgUHJvdG9jb2xFeGNlcHRpb24geworCXN1cGVyKG5hbWUsIGhvc3QsIHBvcnQsIHByb3BzLCBpc1NTTCwgbG9nZ2VyKTsKKworCS8vIGNoZWNrIHRvIHNlZSBpZiB0aGlzIGlzIHJlYWxseSBHbWFpbAorCWlmICghaGFzQ2FwYWJpbGl0eSgiWC1HTS1FWFQtMSIpKSB7CisJICAgIGxvZ2dlci5maW5lKCJXQVJOSU5HISBOb3QgY29ubmVjdGVkIHRvIEdtYWlsISIpOworCSAgICAvLyBYWFggLSBjb3VsZCBjYWxsICJkaXNjb25uZWN0KCkiIGhlcmUgYW5kIG1ha2UgdGhpcyBhIGZhdGFsIGVycm9yCisJfSBlbHNlIHsKKwkgICAgbG9nZ2VyLmZpbmUoImNvbm5lY3RlZCB0byBHbWFpbCIpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIGFkZGl0aW9uYWwgZmV0Y2ggaXRlbXMgc3VwcG9ydGVkIGJ5IHRoZSBHbWFpbCBwcm90b2NvbC4KKyAgICAgKiBDb21iaW5lcyBvdXIgZmV0Y2ggaXRlbXMgd2l0aCB0aG9zZSBzdXBwb3J0ZWQgYnkgdGhlIHN1cGVyY2xhc3MuCisgICAgICovCisgICAgcHVibGljIEZldGNoSXRlbVtdIGdldEZldGNoSXRlbXMoKSB7CisJaWYgKGZldGNoSXRlbXMgIT0gbnVsbCkKKwkgICAgcmV0dXJuIGZldGNoSXRlbXM7CisJRmV0Y2hJdGVtW10gc2ZpID0gc3VwZXIuZ2V0RmV0Y2hJdGVtcygpOworCWlmIChzZmkgPT0gbnVsbCB8fCBzZmkubGVuZ3RoID09IDApCisJICAgIGZldGNoSXRlbXMgPSBteUZldGNoSXRlbXM7CisJZWxzZSB7CisJICAgIGZldGNoSXRlbXMgPSBuZXcgRmV0Y2hJdGVtW3NmaS5sZW5ndGggKyBteUZldGNoSXRlbXMubGVuZ3RoXTsKKwkgICAgU3lzdGVtLmFycmF5Y29weShzZmksIDAsIGZldGNoSXRlbXMsIDAsIHNmaS5sZW5ndGgpOworCSAgICBTeXN0ZW0uYXJyYXljb3B5KG15RmV0Y2hJdGVtcywgMCwgZmV0Y2hJdGVtcywgc2ZpLmxlbmd0aCwKKwkJCQkJCQlteUZldGNoSXRlbXMubGVuZ3RoKTsKKwl9CisJcmV0dXJuIGZldGNoSXRlbXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBzcGVjaWZpZWQgbGFiZWxzIG9uIHRoaXMgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbQltc2dzZXRzCXRoZSBtZXNzYWdlIHNldHMKKyAgICAgKiBAcGFyYW0JbGFiZWxzCXRoZSBsYWJlbHMKKyAgICAgKiBAcGFyYW0Jc2V0CXRydWUgdG8gc2V0LCBmYWxzZSB0byBjbGVhcgorICAgICAqIEBleGNlcHRpb24JUHJvdG9jb2xFeGNlcHRpb24JZm9yIHByb3RvY29sIGZhaWx1cmVzCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNS41CisgICAgICovCisgICAgcHVibGljIHZvaWQgc3RvcmVMYWJlbHMoTWVzc2FnZVNldFtdIG1zZ3NldHMsIFN0cmluZ1tdIGxhYmVscywgYm9vbGVhbiBzZXQpCisJCQl0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCXN0b3JlTGFiZWxzKE1lc3NhZ2VTZXQudG9TdHJpbmcobXNnc2V0cyksIGxhYmVscywgc2V0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHNwZWNpZmllZCBsYWJlbHMgb24gdGhpcyBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtCXN0YXJ0CXRoZSBmaXJzdCBtZXNzYWdlIG51bWJlcgorICAgICAqIEBwYXJhbQllbmQJdGhlIGxhc3QgbWVzc2FnZSBudW1iZXIKKyAgICAgKiBAcGFyYW0JbGFiZWxzCXRoZSBsYWJlbHMKKyAgICAgKiBAcGFyYW0Jc2V0CXRydWUgdG8gc2V0LCBmYWxzZSB0byBjbGVhcgorICAgICAqIEBleGNlcHRpb24JUHJvdG9jb2xFeGNlcHRpb24JZm9yIHByb3RvY29sIGZhaWx1cmVzCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNS41CisgICAgICovCisgICAgcHVibGljIHZvaWQgc3RvcmVMYWJlbHMoaW50IHN0YXJ0LCBpbnQgZW5kLCBTdHJpbmdbXSBsYWJlbHMsIGJvb2xlYW4gc2V0KQorCQkJdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKwlzdG9yZUxhYmVscyhTdHJpbmcudmFsdWVPZihzdGFydCkgKyAiOiIgKyBTdHJpbmcudmFsdWVPZihlbmQpLAorCQkgICBsYWJlbHMsIHNldCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBzcGVjaWZpZWQgbGFiZWxzIG9uIHRoaXMgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbQltc2cJdGhlIG1lc3NhZ2UgbnVtYmVyCisgICAgICogQHBhcmFtCWxhYmVscwl0aGUgbGFiZWxzCisgICAgICogQHBhcmFtCXNldAl0cnVlIHRvIHNldCwgZmFsc2UgdG8gY2xlYXIKKyAgICAgKiBAZXhjZXB0aW9uCVByb3RvY29sRXhjZXB0aW9uCWZvciBwcm90b2NvbCBmYWlsdXJlcworICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjUuNQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHN0b3JlTGFiZWxzKGludCBtc2csIFN0cmluZ1tdIGxhYmVscywgYm9vbGVhbiBzZXQpCisJCQl0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geyAKKwlzdG9yZUxhYmVscyhTdHJpbmcudmFsdWVPZihtc2cpLCBsYWJlbHMsIHNldCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHN0b3JlTGFiZWxzKFN0cmluZyBtc2dzZXQsIFN0cmluZ1tdIGxhYmVscywgYm9vbGVhbiBzZXQpCisJCQl0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCVJlc3BvbnNlW10gcjsKKwlpZiAoc2V0KQorCSAgICByID0gY29tbWFuZCgiU1RPUkUgIiArIG1zZ3NldCArICIgK1gtR00tTEFCRUxTIiwKKwkJCSBjcmVhdGVMYWJlbExpc3QobGFiZWxzKSk7CisJZWxzZQorCSAgICByID0gY29tbWFuZCgiU1RPUkUgIiArIG1zZ3NldCArICIgLVgtR00tTEFCRUxTIiwKKwkJCWNyZWF0ZUxhYmVsTGlzdChsYWJlbHMpKTsKKwkKKwkvLyBEaXNwYXRjaCB1bnRhZ2dlZCByZXNwb25zZXMKKwlub3RpZnlSZXNwb25zZUhhbmRsZXJzKHIpOworCWhhbmRsZVJlc3VsdChyW3IubGVuZ3RoLTFdKTsKKyAgICB9CisKKyAgICAvLyBYWFggLSBhc3N1bWUgR21haWwgYWx3YXlzIHN1cHBvcnRzIFVURi04CisgICAgcHJpdmF0ZSBBcmd1bWVudCBjcmVhdGVMYWJlbExpc3QoU3RyaW5nW10gbGFiZWxzKSB7CisJQXJndW1lbnQgYXJncyA9IG5ldyBBcmd1bWVudCgpOwkKKwlBcmd1bWVudCBpdGVtQXJncyA9IG5ldyBBcmd1bWVudCgpOworCWZvciAoaW50IGkgPSAwLCBsZW4gPSBsYWJlbHMubGVuZ3RoOyBpIDwgbGVuOyBpKyspCisJICAgIGl0ZW1BcmdzLndyaXRlU3RyaW5nKGxhYmVsc1tpXSwgU3RhbmRhcmRDaGFyc2V0cy5VVEZfOCk7CisJYXJncy53cml0ZUFyZ3VtZW50KGl0ZW1BcmdzKTsKKwlyZXR1cm4gYXJnczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYSBHbWFpbFNlYXJjaFNlcXVlbmNlLgorICAgICAqLworICAgIHByb3RlY3RlZCBTZWFyY2hTZXF1ZW5jZSBnZXRTZWFyY2hTZXF1ZW5jZSgpIHsKKwlpZiAoc2VhcmNoU2VxdWVuY2UgPT0gbnVsbCkKKwkgICAgc2VhcmNoU2VxdWVuY2UgPSBuZXcgR21haWxTZWFyY2hTZXF1ZW5jZSh0aGlzKTsKKwlyZXR1cm4gc2VhcmNoU2VxdWVuY2U7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvZ2ltYXAvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvZ2ltYXAvcHJvdG9jb2wvR21haWxTZWFyY2hTZXF1ZW5jZS5qYXZhIGIvZ2ltYXAvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvZ2ltYXAvcHJvdG9jb2wvR21haWxTZWFyY2hTZXF1ZW5jZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg2ODk3MjYKLS0tIC9kZXYvbnVsbAorKysgYi9naW1hcC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9naW1hcC9wcm90b2NvbC9HbWFpbFNlYXJjaFNlcXVlbmNlLmphdmEKQEAgLTAsMCArMSw3NiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuZ2ltYXAucHJvdG9jb2w7CisKK2ltcG9ydCBqYXZhLmlvLio7CisKK2ltcG9ydCBqYXZheC5tYWlsLio7CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC4qOworaW1wb3J0IGphdmF4Lm1haWwuc2VhcmNoLio7CisKK2ltcG9ydCBjb20uc3VuLm1haWwuaWFwLio7CitpbXBvcnQgY29tLnN1bi5tYWlsLmltYXAucHJvdG9jb2wuKjsKK2ltcG9ydCBjb20uc3VuLm1haWwuZ2ltYXAuKjsKKworLyoqCisgKiBTdXBwb3J0IEdtYWlsLXNwZWNpZmljIHNlYXJjaCBleHRlbnNpb25zLgorICoKKyAqIEBzaW5jZSBKYXZhTWFpbCAxLjQuNgorICogQGF1dGhvciBCaWxsIFNoYW5ub24KKyAqLworCitwdWJsaWMgY2xhc3MgR21haWxTZWFyY2hTZXF1ZW5jZSBleHRlbmRzIFNlYXJjaFNlcXVlbmNlIHsKKyAgICBwdWJsaWMgR21haWxTZWFyY2hTZXF1ZW5jZShJTUFQUHJvdG9jb2wgcCkgeworCXN1cGVyKHApOworICAgIH0KKworICAgIHB1YmxpYyBBcmd1bWVudCBnZW5lcmF0ZVNlcXVlbmNlKFNlYXJjaFRlcm0gdGVybSwgU3RyaW5nIGNoYXJzZXQpCisJCQkJdGhyb3dzIFNlYXJjaEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworCWlmICh0ZXJtIGluc3RhbmNlb2YgR21haWxNc2dJZFRlcm0pCisJICAgIHJldHVybiBnbWFpbE1zZ2lkU2VhcmNoKChHbWFpbE1zZ0lkVGVybSl0ZXJtKTsKKwllbHNlIGlmICh0ZXJtIGluc3RhbmNlb2YgR21haWxUaHJJZFRlcm0pCisJICAgIHJldHVybiBnbWFpbFRocmlkU2VhcmNoKChHbWFpbFRocklkVGVybSl0ZXJtKTsKKwllbHNlIGlmICh0ZXJtIGluc3RhbmNlb2YgR21haWxSYXdTZWFyY2hUZXJtKQorCSAgICByZXR1cm4gZ21haWxSYXdTZWFyY2goKEdtYWlsUmF3U2VhcmNoVGVybSl0ZXJtLCBjaGFyc2V0KTsKKwllbHNlCisJICAgIHJldHVybiBzdXBlci5nZW5lcmF0ZVNlcXVlbmNlKHRlcm0sIGNoYXJzZXQpOworICAgIH0KKworICAgIHByb3RlY3RlZCBBcmd1bWVudCBnbWFpbE1zZ2lkU2VhcmNoKEdtYWlsTXNnSWRUZXJtIHRlcm0pCisJCQkJdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlBcmd1bWVudCByZXN1bHQgPSBuZXcgQXJndW1lbnQoKTsKKwlyZXN1bHQud3JpdGVBdG9tKCJYLUdNLU1TR0lEIik7CisJcmVzdWx0LndyaXRlTnVtYmVyKHRlcm0uZ2V0TnVtYmVyKCkpOworCXJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHJvdGVjdGVkIEFyZ3VtZW50IGdtYWlsVGhyaWRTZWFyY2goR21haWxUaHJJZFRlcm0gdGVybSkKKwkJCQl0aHJvd3MgSU9FeGNlcHRpb24geworCUFyZ3VtZW50IHJlc3VsdCA9IG5ldyBBcmd1bWVudCgpOworCXJlc3VsdC53cml0ZUF0b20oIlgtR00tVEhSSUQiKTsKKwlyZXN1bHQud3JpdGVOdW1iZXIodGVybS5nZXROdW1iZXIoKSk7CisJcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgQXJndW1lbnQgZ21haWxSYXdTZWFyY2goR21haWxSYXdTZWFyY2hUZXJtIHRlcm0sIFN0cmluZyBjaGFyc2V0KQorCQkJCXRocm93cyBJT0V4Y2VwdGlvbiB7CisJQXJndW1lbnQgcmVzdWx0ID0gbmV3IEFyZ3VtZW50KCk7CisJcmVzdWx0LndyaXRlQXRvbSgiWC1HTS1SQVciKTsKKwlyZXN1bHQud3JpdGVTdHJpbmcodGVybS5nZXRQYXR0ZXJuKCksIGNoYXJzZXQpOworCXJldHVybiByZXN1bHQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvZ2ltYXAvc3JjL21haW4vamF2YS9tb2R1bGUtaW5mby5qYXZhIGIvZ2ltYXAvc3JjL21haW4vamF2YS9tb2R1bGUtaW5mby5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNkYTI0NmUKLS0tIC9kZXYvbnVsbAorKysgYi9naW1hcC9zcmMvbWFpbi9qYXZhL21vZHVsZS1pbmZvLmphdmEKQEAgLTAsMCArMSwyNyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworbW9kdWxlIGNvbS5zdW4ubWFpbC5naW1hcCB7CisgICAgZXhwb3J0cyBjb20uc3VuLm1haWwuZ2ltYXA7CisgICAgZXhwb3J0cyBjb20uc3VuLm1haWwuZ2ltYXAucHJvdG9jb2w7CisgICAgcHJvdmlkZXMgamF2YXgubWFpbC5Qcm92aWRlciB3aXRoCisJY29tLnN1bi5tYWlsLmdpbWFwLkdtYWlsUHJvdmlkZXIsIGNvbS5zdW4ubWFpbC5naW1hcC5HbWFpbFNTTFByb3ZpZGVyOworCisgICAgcmVxdWlyZXMgamFrYXJ0YS5tYWlsOworICAgIHJlcXVpcmVzIGphdmEubG9nZ2luZzsKKyAgICByZXF1aXJlcyBqYXZhLnNlY3VyaXR5LnNhc2w7CisgICAgcmVxdWlyZXMgY29tLnN1bi5tYWlsLmltYXA7Cit9CmRpZmYgLS1naXQgYS9naW1hcC9zcmMvbWFpbi9yZXNvdXJjZXMvTUVUQS1JTkYvTUFOSUZFU1QuTUYgYi9naW1hcC9zcmMvbWFpbi9yZXNvdXJjZXMvTUVUQS1JTkYvTUFOSUZFU1QuTUYKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmNjZjM0MgotLS0gL2Rldi9udWxsCisrKyBiL2dpbWFwL3NyYy9tYWluL3Jlc291cmNlcy9NRVRBLUlORi9NQU5JRkVTVC5NRgpAQCAtMCwwICsxLDkgQEAKK01hbmlmZXN0LVZlcnNpb246IDEuMAorRXh0ZW5zaW9uLU5hbWU6IGNvbS5zdW4ubWFpbC5naW1hcAorU3BlY2lmaWNhdGlvbi1UaXRsZTogY29tLnN1bi5tYWlsLmdpbWFwCitTcGVjaWZpY2F0aW9uLVZlcnNpb246ICR7bWFpbC5zcGVjLnZlcnNpb259CitTcGVjaWZpY2F0aW9uLVZlbmRvcjogJHtwcm9qZWN0Lm9yZ2FuaXphdGlvbi5uYW1lfQorSW1wbGVtZW50YXRpb24tVGl0bGU6IGNvbS5zdW4ubWFpbC5naW1hcAorSW1wbGVtZW50YXRpb24tVmVyc2lvbjogJHttYWlsLnZlcnNpb259CitJbXBsZW1lbnRhdGlvbi1WZW5kb3I6ICR7cHJvamVjdC5vcmdhbml6YXRpb24ubmFtZX0KK0ltcGxlbWVudGF0aW9uLVZlbmRvci1JZDogY29tLnN1bgpkaWZmIC0tZ2l0IGEvZ2ltYXAvc3JjL21haW4vcmVzb3VyY2VzL01FVEEtSU5GL2phdmFtYWlsLnByb3ZpZGVycyBiL2dpbWFwL3NyYy9tYWluL3Jlc291cmNlcy9NRVRBLUlORi9qYXZhbWFpbC5wcm92aWRlcnMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTlkMzg5MAotLS0gL2Rldi9udWxsCisrKyBiL2dpbWFwL3NyYy9tYWluL3Jlc291cmNlcy9NRVRBLUlORi9qYXZhbWFpbC5wcm92aWRlcnMKQEAgLTAsMCArMSwyIEBACitwcm90b2NvbD1naW1hcDsgdHlwZT1zdG9yZTsgY2xhc3M9Y29tLnN1bi5tYWlsLmdpbWFwLkdtYWlsU3RvcmU7IHZlbmRvcj1PcmFjbGU7Citwcm90b2NvbD1naW1hcHM7IHR5cGU9c3RvcmU7IGNsYXNzPWNvbS5zdW4ubWFpbC5naW1hcC5HbWFpbFNTTFN0b3JlOyB2ZW5kb3I9T3JhY2xlOwpkaWZmIC0tZ2l0IGEvZ2ltYXAvc3JjL21haW4vcmVzb3VyY2VzL01FVEEtSU5GL3NlcnZpY2VzL2phdmF4Lm1haWwuUHJvdmlkZXIgYi9naW1hcC9zcmMvbWFpbi9yZXNvdXJjZXMvTUVUQS1JTkYvc2VydmljZXMvamF2YXgubWFpbC5Qcm92aWRlcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZjQ5YTE0Ci0tLSAvZGV2L251bGwKKysrIGIvZ2ltYXAvc3JjL21haW4vcmVzb3VyY2VzL01FVEEtSU5GL3NlcnZpY2VzL2phdmF4Lm1haWwuUHJvdmlkZXIKQEAgLTAsMCArMSwyIEBACitjb20uc3VuLm1haWwuZ2ltYXAuR21haWxQcm92aWRlcgorY29tLnN1bi5tYWlsLmdpbWFwLkdtYWlsU1NMUHJvdmlkZXIKZGlmZiAtLWdpdCBhL2ltYXAvcG9tLnhtbCBiL2ltYXAvcG9tLnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNDU1OTBmCi0tLSAvZGV2L251bGwKKysrIGIvaW1hcC9wb20ueG1sCkBAIC0wLDAgKzEsNDQgQEAKKzw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9Imlzby04ODU5LTEiPz4KKzwhLS0KKworICAgIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorCisgICAgVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgICAgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisKKyAgICBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgICAgTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICAgIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICAgIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorCisgICAgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisKKy0tPgorCis8cHJvamVjdCB4bWxucz0iaHR0cDovL21hdmVuLmFwYWNoZS5vcmcvUE9NLzQuMC4wIgorCXhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiCisJeHNpOnNjaGVtYUxvY2F0aW9uPSJodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9QT00vNC4wLjAKKwkJCSAgICBodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9tYXZlbi12NF8wXzAueHNkIj4KKyAgICA8cGFyZW50PgorCTxncm91cElkPmNvbS5zdW4ubWFpbDwvZ3JvdXBJZD4KKwk8YXJ0aWZhY3RJZD5wYXJlbnQtZGlzdHJpYjwvYXJ0aWZhY3RJZD4KKwk8dmVyc2lvbj4xLjYuMzwvdmVyc2lvbj4KKwk8cmVsYXRpdmVQYXRoPi4uL3BhcmVudC1kaXN0cmliL3BvbS54bWw8L3JlbGF0aXZlUGF0aD4KKyAgICA8L3BhcmVudD4KKyAgICA8bW9kZWxWZXJzaW9uPjQuMC4wPC9tb2RlbFZlcnNpb24+CisgICAgPGdyb3VwSWQ+Y29tLnN1bi5tYWlsPC9ncm91cElkPgorICAgIDxhcnRpZmFjdElkPmltYXA8L2FydGlmYWN0SWQ+CisgICAgPHBhY2thZ2luZz5qYXI8L3BhY2thZ2luZz4KKyAgICA8bmFtZT5KYXZhTWFpbCBBUEkgaW1hcCBwcm92aWRlcjwvbmFtZT4KKworICAgIDxwcm9wZXJ0aWVzPgorCTxtYWlsLmV4dHJhQ2xhc3Nlcz5jb20vc3VuL21haWwvaWFwLyoqPC9tYWlsLmV4dHJhQ2xhc3Nlcz4KKwk8bWFpbC5wYWNrYWdlcy5leHBvcnQ+CisJICAgIGNvbS5zdW4ubWFpbC5pbWFwOyB2ZXJzaW9uPSR7bWFpbC5vc2dpdmVyc2lvbn0sCisJICAgIGNvbS5zdW4ubWFpbC5pbWFwLnByb3RvY29sOyB2ZXJzaW9uPSR7bWFpbC5vc2dpdmVyc2lvbn0sCisJICAgIGNvbS5zdW4ubWFpbC5pYXA7IHZlcnNpb249JHttYWlsLm9zZ2l2ZXJzaW9ufQorCTwvbWFpbC5wYWNrYWdlcy5leHBvcnQ+CisgICAgPC9wcm9wZXJ0aWVzPgorPC9wcm9qZWN0PgpkaWZmIC0tZ2l0IGEvaW1hcC9zcmMvbWFpbi9qYXZhL21vZHVsZS1pbmZvLmphdmEgYi9pbWFwL3NyYy9tYWluL2phdmEvbW9kdWxlLWluZm8uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zN2EzYzM0Ci0tLSAvZGV2L251bGwKKysrIGIvaW1hcC9zcmMvbWFpbi9qYXZhL21vZHVsZS1pbmZvLmphdmEKQEAgLTAsMCArMSwyNyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworbW9kdWxlIGNvbS5zdW4ubWFpbC5pbWFwIHsKKyAgICBleHBvcnRzIGNvbS5zdW4ubWFpbC5pYXA7CisgICAgZXhwb3J0cyBjb20uc3VuLm1haWwuaW1hcDsKKyAgICBleHBvcnRzIGNvbS5zdW4ubWFpbC5pbWFwLnByb3RvY29sOworICAgIHByb3ZpZGVzIGphdmF4Lm1haWwuUHJvdmlkZXIgd2l0aAorCWNvbS5zdW4ubWFpbC5pbWFwLklNQVBQcm92aWRlciwgY29tLnN1bi5tYWlsLmltYXAuSU1BUFNTTFByb3ZpZGVyOworCisgICAgcmVxdWlyZXMgamFrYXJ0YS5tYWlsOworICAgIHJlcXVpcmVzIGphdmEubG9nZ2luZzsKKyAgICByZXF1aXJlcyBqYXZhLnNlY3VyaXR5LnNhc2w7Cit9CmRpZmYgLS1naXQgYS9pbWFwL3NyYy9tYWluL3Jlc291cmNlcy9NRVRBLUlORi9NQU5JRkVTVC5NRiBiL2ltYXAvc3JjL21haW4vcmVzb3VyY2VzL01FVEEtSU5GL01BTklGRVNULk1GCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY0ZjgxNTYKLS0tIC9kZXYvbnVsbAorKysgYi9pbWFwL3NyYy9tYWluL3Jlc291cmNlcy9NRVRBLUlORi9NQU5JRkVTVC5NRgpAQCAtMCwwICsxLDkgQEAKK01hbmlmZXN0LVZlcnNpb246IDEuMAorRXh0ZW5zaW9uLU5hbWU6IGNvbS5zdW4ubWFpbC5pbWFwCitTcGVjaWZpY2F0aW9uLVRpdGxlOiBjb20uc3VuLm1haWwuaW1hcAorU3BlY2lmaWNhdGlvbi1WZXJzaW9uOiAke21haWwuc3BlYy52ZXJzaW9ufQorU3BlY2lmaWNhdGlvbi1WZW5kb3I6ICR7cHJvamVjdC5vcmdhbml6YXRpb24ubmFtZX0KK0ltcGxlbWVudGF0aW9uLVRpdGxlOiBjb20uc3VuLm1haWwuaW1hcAorSW1wbGVtZW50YXRpb24tVmVyc2lvbjogJHttYWlsLnZlcnNpb259CitJbXBsZW1lbnRhdGlvbi1WZW5kb3I6ICR7cHJvamVjdC5vcmdhbml6YXRpb24ubmFtZX0KK0ltcGxlbWVudGF0aW9uLVZlbmRvci1JZDogY29tLnN1bgpkaWZmIC0tZ2l0IGEvaW1hcC9zcmMvbWFpbi9yZXNvdXJjZXMvTUVUQS1JTkYvamF2YW1haWwucHJvdmlkZXJzIGIvaW1hcC9zcmMvbWFpbi9yZXNvdXJjZXMvTUVUQS1JTkYvamF2YW1haWwucHJvdmlkZXJzCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMwNWRmYTUKLS0tIC9kZXYvbnVsbAorKysgYi9pbWFwL3NyYy9tYWluL3Jlc291cmNlcy9NRVRBLUlORi9qYXZhbWFpbC5wcm92aWRlcnMKQEAgLTAsMCArMSwzIEBACisjIEphdmFNYWlsIElNQVAgcHJvdmlkZXIgT3JhY2xlCitwcm90b2NvbD1pbWFwOyB0eXBlPXN0b3JlOyBjbGFzcz1jb20uc3VuLm1haWwuaW1hcC5JTUFQU3RvcmU7IHZlbmRvcj1PcmFjbGU7Citwcm90b2NvbD1pbWFwczsgdHlwZT1zdG9yZTsgY2xhc3M9Y29tLnN1bi5tYWlsLmltYXAuSU1BUFNTTFN0b3JlOyB2ZW5kb3I9T3JhY2xlOwpkaWZmIC0tZ2l0IGEvaW1hcC9zcmMvbWFpbi9yZXNvdXJjZXMvTUVUQS1JTkYvc2VydmljZXMvamF2YXgubWFpbC5Qcm92aWRlciBiL2ltYXAvc3JjL21haW4vcmVzb3VyY2VzL01FVEEtSU5GL3NlcnZpY2VzL2phdmF4Lm1haWwuUHJvdmlkZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTMyZTk5MgotLS0gL2Rldi9udWxsCisrKyBiL2ltYXAvc3JjL21haW4vcmVzb3VyY2VzL01FVEEtSU5GL3NlcnZpY2VzL2phdmF4Lm1haWwuUHJvdmlkZXIKQEAgLTAsMCArMSwyIEBACitjb20uc3VuLm1haWwuaW1hcC5JTUFQUHJvdmlkZXIKK2NvbS5zdW4ubWFpbC5pbWFwLklNQVBTU0xQcm92aWRlcgpkaWZmIC0tZ2l0IGEvamF2YWRvYy9wb20ueG1sIGIvamF2YWRvYy9wb20ueG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhhZWFlZDMKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhZG9jL3BvbS54bWwKQEAgLTAsMCArMSwyMDUgQEAKKzw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9Imlzby04ODU5LTEiPz4KKzwhLS0KKworICAgIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorCisgICAgVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgICAgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisKKyAgICBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgICAgTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICAgIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICAgIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorCisgICAgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisKKy0tPgorCis8cHJvamVjdCB4bWxucz0iaHR0cDovL21hdmVuLmFwYWNoZS5vcmcvUE9NLzQuMC4wIgorCXhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiCisJeHNpOnNjaGVtYUxvY2F0aW9uPSJodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9QT00vNC4wLjAKKwkJCSAgICBodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9tYXZlbi12NF8wXzAueHNkIj4KKyAgICA8cGFyZW50PgorCTxncm91cElkPmNvbS5zdW4ubWFpbDwvZ3JvdXBJZD4KKwk8YXJ0aWZhY3RJZD5hbGw8L2FydGlmYWN0SWQ+CisJPHZlcnNpb24+MS42LjM8L3ZlcnNpb24+CisgICAgPC9wYXJlbnQ+CisgICAgPG1vZGVsVmVyc2lvbj40LjAuMDwvbW9kZWxWZXJzaW9uPgorICAgIDxncm91cElkPmNvbS5zdW4ubWFpbDwvZ3JvdXBJZD4KKyAgICA8YXJ0aWZhY3RJZD5qYXZhZG9jPC9hcnRpZmFjdElkPgorICAgIDxwYWNrYWdpbmc+cG9tPC9wYWNrYWdpbmc+CisgICAgPHZlcnNpb24+MS42LjM8L3ZlcnNpb24+CisgICAgPG5hbWU+SmF2YU1haWwgQVBJIGphdmFkb2NzPC9uYW1lPgorICAgIDxkZXNjcmlwdGlvbj4ke3Byb2plY3QubmFtZX08L2Rlc2NyaXB0aW9uPgorCisgICAgPGJ1aWxkPgorICAgICAgICA8cGx1Z2lucz4KKwkgICAgPCEtLQorCQlUbyBhbGxvdyB1cyB0byBnZW5lcmF0ZSBqYXZhZG9jcyB0aGF0IG9ubHkgaW5jbHVkZSBzb21lCisJCWNsYXNzZXMgaW4gY2VydGFpbiBwYWNrYWdlcywgd2UgbmVlZCB0byBjb3B5IHRoZSBzb3VyY2VzCisJCXRvIGFub3RoZXIgbG9jYXRpb24gYW5kIHJ1biBqYXZhZG9jIGFnYWluc3QgdGhhdCBzdWJzZXQKKwkJb2YgdGhlIHNvdXJjZXMuICBUaGlzIGFudCB0YXNrIGRvZXMgdGhlIGNvcHkuCisJICAgIC0tPgorCSAgICA8cGx1Z2luPgorICAgICAgICAgICAgICAgIDxhcnRpZmFjdElkPm1hdmVuLWFudHJ1bi1wbHVnaW48L2FydGlmYWN0SWQ+CisJCTxpbmhlcml0ZWQ+ZmFsc2U8L2luaGVyaXRlZD4KKyAgICAgICAgICAgICAgICA8ZXhlY3V0aW9ucz4KKwkJICAgIDxleGVjdXRpb24+CisJCQk8cGhhc2U+cGFja2FnZTwvcGhhc2U+CisJCQk8Y29uZmlndXJhdGlvbj4KKwkJCSAgICA8dGFza3M+CisKKwkJCQk8Y29weSB0b2Rpcj0idGFyZ2V0L2phdmFkb2MiPgorCQkJCSAgICA8ZmlsZXNldCBkaXI9Ii4uL21haWwvc3JjL21haW4vamF2YSI+CisJCQkJCTxpbmNsdWRlIG5hbWU9IioqLyouaHRtbCIvPgorCQkJCQk8aW5jbHVkZSBuYW1lPSJqYXZheC9tYWlsLyoqIi8+CisJCQkJICAgIDwvZmlsZXNldD4KKwkJCQkgICAgPGZpbGVzZXQgZGlyPSIuLi9tYWlsL3NyYy9tYWluL2phdmEiCisJCQkJCWluY2x1ZGVzPSIKKwkJCWNvbS9zdW4vbWFpbC9pbWFwL3BhY2thZ2UuaHRtbCwKKwkJCWNvbS9zdW4vbWFpbC9pbWFwL0lNQVBGb2xkZXIuamF2YSwKKwkJCWNvbS9zdW4vbWFpbC9pbWFwL0lNQVBNZXNzYWdlLmphdmEsCisJCQljb20vc3VuL21haWwvaW1hcC9JTUFQU3RvcmUuamF2YSwKKwkJCWNvbS9zdW4vbWFpbC9pbWFwL0lNQVBTU0xTdG9yZS5qYXZhCisJCQljb20vc3VuL21haWwvaW1hcC9BQ0wuamF2YSwKKwkJCWNvbS9zdW4vbWFpbC9pbWFwL1JpZ2h0cy5qYXZhLAorCQkJY29tL3N1bi9tYWlsL2ltYXAvUXVvdGEuamF2YSwKKwkJCWNvbS9zdW4vbWFpbC9pbWFwL1NvcnRUZXJtLmphdmEsCisJCQljb20vc3VuL21haWwvaW1hcC9SZXN5bmNEYXRhLmphdmEsCisJCQljb20vc3VuL21haWwvaW1hcC9PbGRlclRlcm0uamF2YSwKKwkJCWNvbS9zdW4vbWFpbC9pbWFwL1lvdW5nZXJUZXJtLmphdmEsCisJCQljb20vc3VuL21haWwvaW1hcC9NZXNzYWdlVmFuaXNoZWRFdmVudC5qYXZhLAorCQkJY29tL3N1bi9tYWlsL2ltYXAvTW9kaWZpZWRTaW5jZVRlcm0uamF2YSwKKwkJCWNvbS9zdW4vbWFpbC9pbWFwL0lkbGVNYW5hZ2VyLmphdmEsCisJCQljb20vc3VuL21haWwvaW1hcC9SZWZlcnJhbEV4Y2VwdGlvbi5qYXZhLAorCQkJY29tL3N1bi9tYWlsL3BvcDMvUE9QM1N0b3JlLmphdmEsCisJCQljb20vc3VuL21haWwvcG9wMy9QT1AzU1NMU3RvcmUuamF2YSwKKwkJCWNvbS9zdW4vbWFpbC9wb3AzL1BPUDNGb2xkZXIuamF2YSwKKwkJCWNvbS9zdW4vbWFpbC9wb3AzL1BPUDNNZXNzYWdlLmphdmEsCisJCQljb20vc3VuL21haWwvc210cC9TTVRQTWVzc2FnZS5qYXZhLAorCQkJY29tL3N1bi9tYWlsL3NtdHAvU01UUEFkZHJlc3NGYWlsZWRFeGNlcHRpb24uamF2YSwKKwkJCWNvbS9zdW4vbWFpbC9zbXRwL1NNVFBBZGRyZXNzU3VjY2VlZGVkRXhjZXB0aW9uLmphdmEsCisJCQljb20vc3VuL21haWwvc210cC9TTVRQU2VuZEZhaWxlZEV4Y2VwdGlvbi5qYXZhLAorCQkJY29tL3N1bi9tYWlsL3NtdHAvU01UUFNlbmRlckZhaWxlZEV4Y2VwdGlvbi5qYXZhLAorCQkJY29tL3N1bi9tYWlsL3NtdHAvU01UUFRyYW5zcG9ydC5qYXZhLAorCQkJY29tL3N1bi9tYWlsL3NtdHAvU01UUFNTTFRyYW5zcG9ydC5qYXZhLAorCQkJY29tL3N1bi9tYWlsL3V0aWwvTWFpbENvbm5lY3RFeGNlcHRpb24uamF2YSwKKwkJCWNvbS9zdW4vbWFpbC91dGlsL01haWxTU0xTb2NrZXRGYWN0b3J5LmphdmEsCisJCQljb20vc3VuL21haWwvdXRpbC9SZWFkYWJsZU1pbWUuamF2YSwKKwkJCWNvbS9zdW4vbWFpbC91dGlsL2xvZ2dpbmcvKi5qYXZhCisJCQkJCSIvPgorCQkJCSAgICA8ZmlsZXNldCBkaXI9Ii4uL2Rzbi9zcmMvbWFpbi9qYXZhIgorCQkJCQlpbmNsdWRlcz0iCisJCQljb20vc3VuL21haWwvZHNuL3BhY2thZ2UuaHRtbCwKKwkJCWNvbS9zdW4vbWFpbC9kc24vRGVsaXZlcnlTdGF0dXMuamF2YSwKKwkJCWNvbS9zdW4vbWFpbC9kc24vRGlzcG9zaXRpb25Ob3RpZmljYXRpb24uamF2YSwKKwkJCWNvbS9zdW4vbWFpbC9kc24vTWVzc2FnZUhlYWRlcnMuamF2YSwKKwkJCWNvbS9zdW4vbWFpbC9kc24vTXVsdGlwYXJ0UmVwb3J0LmphdmEsCisJCQljb20vc3VuL21haWwvZHNuL1JlcG9ydC5qYXZhCisJCQkJCSIvPgorCQkJCSAgICA8ZmlsZXNldCBkaXI9Ii4uL2dpbWFwL3NyYy9tYWluL2phdmEiCisJCQkJCWluY2x1ZGVzPSIKKwkJCWNvbS9zdW4vbWFpbC9naW1hcC9wYWNrYWdlLmh0bWwsCisJCQljb20vc3VuL21haWwvZ2ltYXAvKi5qYXZhCisJCQkJCSIvPgorCQkJCTwvY29weT4KKworCQkJICAgIDwvdGFza3M+CisJCQk8L2NvbmZpZ3VyYXRpb24+CisJCQk8Z29hbHM+CisJCQkgICAgPGdvYWw+cnVuPC9nb2FsPgorCQkJPC9nb2Fscz4KKwkJICAgIDwvZXhlY3V0aW9uPgorICAgICAgICAgICAgICAgIDwvZXhlY3V0aW9ucz4KKyAgICAgICAgICAgIDwvcGx1Z2luPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAorCisJICAgIDxwbHVnaW4+CisJCTxhcnRpZmFjdElkPm1hdmVuLWphdmFkb2MtcGx1Z2luPC9hcnRpZmFjdElkPgorCQk8aW5oZXJpdGVkPmZhbHNlPC9pbmhlcml0ZWQ+CisgICAgICAgICAgICAgICAgPGV4ZWN1dGlvbnM+CisJCSAgICA8ZXhlY3V0aW9uPgorCQkJPHBoYXNlPnBhY2thZ2U8L3BoYXNlPgorCQkJPGdvYWxzPgorCQkJICAgIDxnb2FsPmphdmFkb2M8L2dvYWw+CisJCQk8L2dvYWxzPgorCQkJPGNvbmZpZ3VyYXRpb24+CisJCQkgICAgPGFkZGl0aW9uYWxKT3B0aW9uPi1KLVhteDI1Nm08L2FkZGl0aW9uYWxKT3B0aW9uPgorCQkJICAgIDxhdXRob3I+ZmFsc2U8L2F1dGhvcj4KKwkJCSAgICA8ZGVzY3JpcHRpb24+CisJCQkJSmF2YU1haWwgQVBJIGRvY3VtZW50YXRpb24KKwkJCSAgICA8L2Rlc2NyaXB0aW9uPgorCQkJICAgIDxkb2N0aXRsZT4KKwkJCQlKYXZhTWFpbCBBUEkgZG9jdW1lbnRhdGlvbgorCQkJICAgIDwvZG9jdGl0bGU+CisJCQkgICAgPHdpbmRvd3RpdGxlPgorCQkJCUphdmFNYWlsIEFQSSBkb2N1bWVudGF0aW9uCisJCQkgICAgPC93aW5kb3d0aXRsZT4KKwkJCSAgICA8c3BsaXRpbmRleD50cnVlPC9zcGxpdGluZGV4PgorCQkJICAgIDx1c2U+dHJ1ZTwvdXNlPgorCQkJICAgIDxub3RpbWVzdGFtcD50cnVlPC9ub3RpbWVzdGFtcD4KKwkJCSAgICA8c2VyaWFsd2Fybj50cnVlPC9zZXJpYWx3YXJuPgorCQkJICAgIDxxdWlldD50cnVlPC9xdWlldD4KKwkJCSAgICA8b3ZlcnZpZXc+CisJCQkJJHtiYXNlZGlyfS90YXJnZXQvamF2YWRvYy9vdmVydmlldy5odG1sCisJCQkgICAgPC9vdmVydmlldz4KKwkJCSAgICA8Ym90dG9tPgorPCFbQ0RBVEFbQ29weXJpZ2h0ICYjMTY5OyAxOTk2LTIwMTgsCisgICAgPGEgaHJlZj0iaHR0cDovL3d3dy5vcmFjbGUuY29tIj5PcmFjbGU8L2E+CisgICAgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgUmlnaHRzIFJlc2VydmVkLgorICAgIFVzZSBpcyBzdWJqZWN0IHRvCisgICAgPGEgaHJlZj0ie0Bkb2NSb290fS9kb2MtZmlsZXMvc3BlY2xpY2Vuc2UuaHRtbCIgdGFyZ2V0PSJfdG9wIj5saWNlbnNlIHRlcm1zPC9hPi4KK11dPgorCQkJICAgIDwvYm90dG9tPgorCQkJICAgIDxncm91cHM+CisJCQkJPGdyb3VwPgorCQkJCSAgICA8dGl0bGU+SmF2YU1haWwgQVBJIFBhY2thZ2VzPC90aXRsZT4KKwkJCQkgICAgPHBhY2thZ2VzPmphdmF4Lio8L3BhY2thZ2VzPgorCQkJCTwvZ3JvdXA+CisJCQkJPGdyb3VwPgorCQkJCSAgICA8dGl0bGU+Ukktc3BlY2lmaWMgUGFja2FnZXM8L3RpdGxlPgorCQkJCSAgICA8cGFja2FnZXM+Y29tLnN1bi4qPC9wYWNrYWdlcz4KKwkJCQk8L2dyb3VwPgorCQkJICAgIDwvZ3JvdXBzPgorCQkJICAgIDxzdWJwYWNrYWdlcz4KK2phdmF4OmNvbS5zdW4ubWFpbC5pbWFwOmNvbS5zdW4ubWFpbC5wb3AzOmNvbS5zdW4ubWFpbC5zbXRwOmNvbS5zdW4ubWFpbC5kc246Y29tLnN1bi5tYWlsLnV0aWw6Y29tLnN1bi5tYWlsLmdpbWFwCisJCQkgICAgPC9zdWJwYWNrYWdlcz4KKwkJCSAgICA8ZXhjbHVkZVBhY2thZ2VOYW1lcz4KKwkJCQljb20uc3VuLm1haWwuaW1hcC5wcm90b2NvbDpjb20uc3VuLm1haWwuZ2ltYXAucHJvdG9jb2wKKwkJCSAgICA8L2V4Y2x1ZGVQYWNrYWdlTmFtZXM+CisJCQkgICAgPHNvdXJjZXBhdGg+JHtiYXNlZGlyfS90YXJnZXQvamF2YWRvYzwvc291cmNlcGF0aD4KKwkJCSAgICA8IS0tCisJCQkJTGlua3MgdG8gSmF2YSBTRSBqYXZhZG9jcy4KKworCQkJCVhYWCAtIGxpbmtzIG5lZWQgdG8gaW5jbHVkZSBhIHRyYWlsaW5nICIvLiIKKwkJCQkgICAgICBiZWNhdXNlIE1hdmVuIHN0cmlwcyBvZmYgYSB0cmFpbGluZyAiLyIKKwkJCQkgICAgICBiZWZvcmUgcGFzc2luZyB0aGUgb3B0aW9uIHRvIHRoZSBqYXZhZG9jCisJCQkJICAgICAgY29tbWFuZCwgd2hpY2ggdGhlbiBzdHJpcHMgb2ZmIHRoZSBsYXN0CisJCQkJICAgICAgbmFtZSBpZiBpdCBkb2Vzbid0IGVuZCB3aXRoICIvIi4KKwkJCSAgICAtLT4KKwkJCSAgICA8bGlua3M+CisJCQkJPGxpbms+aHR0cDovL2RvY3Mub3JhY2xlLmNvbS9qYXZhc2UvNy9kb2NzL2FwaS8uPC9saW5rPgorCQkJICAgIDwvbGlua3M+CisJCQk8L2NvbmZpZ3VyYXRpb24+CisJCSAgICA8L2V4ZWN1dGlvbj4KKyAgICAgICAgICAgICAgICA8L2V4ZWN1dGlvbnM+CisJICAgIDwvcGx1Z2luPgorCTwvcGx1Z2lucz4KKyAgICA8L2J1aWxkPgorCisgICAgPGRlcGVuZGVuY2llcz4KKyAgICAgICAgPGRlcGVuZGVuY3k+CisgICAgICAgICAgICA8Z3JvdXBJZD5jb20uc3VuLm1haWw8L2dyb3VwSWQ+CisgICAgICAgICAgICA8YXJ0aWZhY3RJZD5qYWthcnRhLm1haWw8L2FydGlmYWN0SWQ+CisgICAgICAgIDwvZGVwZW5kZW5jeT4KKyAgICAgICAgPGRlcGVuZGVuY3k+CisgICAgICAgICAgICA8Z3JvdXBJZD5jb20uc3VuLm1haWw8L2dyb3VwSWQ+CisgICAgICAgICAgICA8YXJ0aWZhY3RJZD5kc248L2FydGlmYWN0SWQ+CisgICAgICAgIDwvZGVwZW5kZW5jeT4KKyAgICAgICAgPGRlcGVuZGVuY3k+CisgICAgICAgICAgICA8Z3JvdXBJZD5jb20uc3VuLm1haWw8L2dyb3VwSWQ+CisgICAgICAgICAgICA8YXJ0aWZhY3RJZD5naW1hcDwvYXJ0aWZhY3RJZD4KKyAgICAgICAgPC9kZXBlbmRlbmN5PgorICAgIDwvZGVwZW5kZW5jaWVzPgorPC9wcm9qZWN0PgpkaWZmIC0tZ2l0IGEvbG9nZ2luZy9wb20ueG1sIGIvbG9nZ2luZy9wb20ueG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU0NzFiOGEKLS0tIC9kZXYvbnVsbAorKysgYi9sb2dnaW5nL3BvbS54bWwKQEAgLTAsMCArMSw3NCBAQAorPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PgorPCEtLQorCisgICAgQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisKKyAgICBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAgICB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKworICAgIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAgICBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgICAgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgICAgdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisKKyAgICBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKworLS0+CisKKzxwcm9qZWN0IHhtbG5zPSJodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9QT00vNC4wLjAiCisJeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIKKwl4c2k6c2NoZW1hTG9jYXRpb249Imh0dHA6Ly9tYXZlbi5hcGFjaGUub3JnL1BPTS80LjAuMAorCQkJICAgIGh0dHA6Ly9tYXZlbi5hcGFjaGUub3JnL21hdmVuLXY0XzBfMC54c2QiPgorICAgIDxwYXJlbnQ+CisJPGdyb3VwSWQ+Y29tLnN1bi5tYWlsPC9ncm91cElkPgorCTxhcnRpZmFjdElkPmFsbDwvYXJ0aWZhY3RJZD4KKwk8dmVyc2lvbj4xLjYuMzwvdmVyc2lvbj4KKyAgICA8L3BhcmVudD4KKyAgICA8bW9kZWxWZXJzaW9uPjQuMC4wPC9tb2RlbFZlcnNpb24+CisgICAgPGdyb3VwSWQ+Y29tLnN1bi5tYWlsPC9ncm91cElkPgorICAgIDxhcnRpZmFjdElkPmxvZ2dpbmc8L2FydGlmYWN0SWQ+CisgICAgPHBhY2thZ2luZz5qYXI8L3BhY2thZ2luZz4KKyAgICA8bmFtZT5KYXZhTWFpbCBBUEkgbG9nZ2luZyBkZW1vPC9uYW1lPgorCisgICAgPGJ1aWxkPgorICAgICAgICA8cGx1Z2lucz4KKwkgICAgPCEtLQorCQlOZWVkIHRvIGRpc2FibGUgdGhlIG1hdmVuLWJ1bmRsZS1wbHVnaW4gYmVjYXVzZSB0aGUKKwkJbmV3IHZlcnNpb24gZG9lc24ndCBsaWtlIGNsYXNzZXMgaW4gdGhlIGRlZmF1bHQgcGFja2FnZS4KKwkgICAgLS0+CisJICAgIDxwbHVnaW4+CisJCTxncm91cElkPm9yZy5hcGFjaGUuZmVsaXg8L2dyb3VwSWQ+CisJCTxhcnRpZmFjdElkPm1hdmVuLWJ1bmRsZS1wbHVnaW48L2FydGlmYWN0SWQ+CisJCTxleGVjdXRpb25zPgorCQkgICAgPGV4ZWN1dGlvbj4KKwkJCTxpZD5vc2dpLW1hbmlmZXN0PC9pZD4KKwkJCTxwaGFzZT5ub25lPC9waGFzZT4KKwkJICAgIDwvZXhlY3V0aW9uPgorCQk8L2V4ZWN1dGlvbnM+CisJICAgIDwvcGx1Z2luPgorCisJICAgIDwhLS0KKwkJQmVjYXVzZSB0aGUgbWF2ZW4tamFyLXBsdWdpbiBkZXBlbmRzIG9uIHRoZSBtYW5pZmVzdCBmaWxlCisJCWNyZWF0ZWQgYnkgdGhlIG1hdmVuLWJ1bmRsZS1wbHVnaW4sIHdlIG5lZWQgdG8gZGlzYWJsZSBpdCB0b28uCisJICAgIC0tPgorCSAgICA8cGx1Z2luPgorCQk8YXJ0aWZhY3RJZD5tYXZlbi1qYXItcGx1Z2luPC9hcnRpZmFjdElkPgorCQk8ZXhlY3V0aW9ucz4KKwkJICAgIDxleGVjdXRpb24+CisJCQk8aWQ+ZGVmYXVsdC1qYXI8L2lkPgorCQkJPHBoYXNlPm5vbmU8L3BoYXNlPgorCQkgICAgPC9leGVjdXRpb24+CisJCTwvZXhlY3V0aW9ucz4KKwkgICAgPC9wbHVnaW4+CisgICAgICAgIDwvcGx1Z2lucz4KKyAgICA8L2J1aWxkPgorCisgICAgPGRlcGVuZGVuY2llcz4KKyAgICAgICAgPGRlcGVuZGVuY3k+CisgICAgICAgICAgICA8Z3JvdXBJZD5jb20uc3VuLm1haWw8L2dyb3VwSWQ+CisgICAgICAgICAgICA8YXJ0aWZhY3RJZD5qYWthcnRhLm1haWw8L2FydGlmYWN0SWQ+CisgICAgICAgIDwvZGVwZW5kZW5jeT4KKyAgICA8L2RlcGVuZGVuY2llcz4KKzwvcHJvamVjdD4KZGlmZiAtLWdpdCBhL2xvZ2dpbmcvc3JjL21haW4vamF2YS9GaWxlRXJyb3JNYW5hZ2VyLmphdmEgYi9sb2dnaW5nL3NyYy9tYWluL2phdmEvRmlsZUVycm9yTWFuYWdlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU5MWEyNDYKLS0tIC9kZXYvbnVsbAorKysgYi9sb2dnaW5nL3NyYy9tYWluL2phdmEvRmlsZUVycm9yTWFuYWdlci5qYXZhCkBAIC0wLDAgKzEsMzA4IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDA5LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKiBDb3B5cmlnaHQgKGMpIDIwMDksIDIwMTggSmFzb24gTWVocmVucy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorICovCisKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CitpbXBvcnQgamF2YS5zZWN1cml0eS5BY2Nlc3NDb250cm9sbGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmlsZWdlZEFjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwubG9nZ2luZy5FcnJvck1hbmFnZXI7CitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTGV2ZWw7CitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTG9nTWFuYWdlcjsKKworLyoqCisgKiBBbiBlcnJvciBtYW5hZ2VyIHVzZWQgdG8gc3RvcmUgbWltZSBtZXNzYWdlcyBmcm9tIHRoZSA8dHQ+TWFpbEhhbmRsZXI8L3R0PgorICogdG8gdGhlIGZpbGUgc3lzdGVtIHdoZW4gdGhlIGVtYWlsIHNlcnZlciBpcyB1bmF2YWlsYWJsZSBvciB1bnJlYWNoYWJsZS4gVGhlCisgKiBjb2RlIHRvIG1hbnVhbGx5IHNldHVwIHRoaXMgZXJyb3IgbWFuYWdlciBjYW4gYmUgYXMgc2ltcGxlIGFzIHRoZSBmb2xsb3dpbmc6CisgKiA8cHJlPgorICogICAgICBGaWxlIGRpciA9IG5ldyBGaWxlKCJwYXRoIHRvIGRpciIpOworICogICAgICBGaWxlRXJyb3JNYW5hZ2VyIGVtID0gbmV3IEZpbGVFcnJvck1hbmFnZXIoZGlyKTsKKyAqIDwvcHJlPgorICoKKyAqIDxwPgorICogPGI+Q29uZmlndXJhdGlvbjo8L2I+CisgKiBUaGUgY29kZSB0byBzZXR1cCB0aGlzIGVycm9yIG1hbmFnZXIgdmlhIHRoZSBsb2dnaW5nIHByb3BlcnRpZXMgY2FuIGJlIGFzCisgKiBzaW1wbGUgYXMgdGhlIGZvbGxvd2luZzoKKyAqIDxwcmU+CisgKiAgICAgICNEZWZhdWx0IEZpbGVFcnJvck1hbmFnZXIgc2V0dGluZ3MuCisgKiAgICAgIEZpbGVFcnJvck1hbmFnZXIucGF0dGVybiA9IHBhdGggdG8gZGlyZWN0b3J5CisgKiA8L3ByZT4KKyAqCisgKiBJZiBwcm9wZXJ0aWVzIGFyZSBub3QgZGVmaW5lZCwgb3IgY29udGFpbiBpbnZhbGlkIHZhbHVlcywgdGhlbiB0aGUgc3BlY2lmaWVkCisgKiBkZWZhdWx0IHZhbHVlcyBhcmUgdXNlZC4KKyAqIDx1bD4KKyAqIDxsaT5GaWxlRXJyb3JNYW5hZ2VyLnBhdHRlcm4gdGhlIGFic29sdXRlIGZpbGUgcGF0aCB0byB0aGUgZGlyZWN0b3J5IHdoaWNoCisgKiB3aWxsIHN0b3JlIGFueSBmYWlsZWQgZW1haWwgbWVzc2FnZXMuIChkZWZhdWx0cyB0byB0aGUgdmFsdWUgb2YgdGhlIHN5c3RlbQorICogcHJvcGVydHkgPHR0PmphdmEuaW8udG1wZGlyPC90dD4pCisgKiA8L3VsPgorICoKKyAqIEBhdXRob3IgSmFzb24gTWVocmVucworICovCitwdWJsaWMgY2xhc3MgRmlsZUVycm9yTWFuYWdlciBleHRlbmRzIEVycm9yTWFuYWdlciB7CisKKyAgICAvKioKKyAgICAgKiBTdG9yZXMgdGhlIExvZ01hbmFnZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTG9nTWFuYWdlciBtYW5hZ2VyID0gTG9nTWFuYWdlci5nZXRMb2dNYW5hZ2VyKCk7CisgICAgLyoqCisgICAgICogVXNlZCB0byByZXBvcnQgZXJyb3JzIHRoYXQgdGhpcyBlcnJvciBtYW5hZ2VyIGZhaWxzIHRvIHJlcG9ydC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIEVycm9yTWFuYWdlciBuZXh0ID0gbmV3IEVycm9yTWFuYWdlcigpOworICAgIC8qKgorICAgICAqIERpcmVjdG9yeSBvZiB0aGUgZW1haWwgc3RvcmUuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBGaWxlIGVtYWlsU3RvcmU7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IGVycm9yIG1hbmFnZXIuIEZpbGVzIGFyZSBzdG9yZWQgaW4gdGhlIHVzZXJzIHRlbXAKKyAgICAgKiBkaXJlY3RvcnkuCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uIFNlY3VyaXR5RXhjZXB0aW9uIGlmIHVuYWJsZSB0byBhY2Nlc3Mgc3lzdGVtIHByb3BlcnRpZXMgb3IgaWYKKyAgICAgKiBhIHNlY3VyaXR5IG1hbmFnZXIgaXMgcHJlc2VudCBhbmQgdW5hYmxlIHRvIHJlYWQgb3Igd3JpdGUgdG8gdXNlcnMgdGVtcAorICAgICAqIGRpcmVjdG9yeS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRmlsZUVycm9yTWFuYWdlcigpIHsKKyAgICAgICAgdGhpcy5lbWFpbFN0b3JlID0gZ2V0RW1haWxTdG9yZSgpOworICAgICAgICBpbml0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBlcnJvciBtYW5hZ2VyLgorICAgICAqCisgICAgICogQHBhcmFtIGRpciBhIGRpcmVjdG9yeSB0byBzdG9yZSB0aGUgZW1haWwgZmlsZXMuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8dHQ+ZGlyPC90dD4gaXMgPHR0Pm51bGw8L3R0PgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIDx0dD5kaXI8L3R0PiBpcyBhCisgICAgICogPHR0PmphdmEuaW8uRmlsZTwvdHQ+IHN1YmNsYXNzLCBub3QgYSBkaXJlY3RvcnksIG9yIGlzIG5vdCBhbiBhYnNvbHV0ZQorICAgICAqIHBhdGguCisgICAgICogQHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbiBpZiBhIHNlY3VyaXR5IG1hbmFnZXIgaXMgcHJlc2VudCBhbmQgdW5hYmxlIHRvCisgICAgICogcmVhZCBvciB3cml0ZSB0byBhIGdpdmVuIGRpcmVjdG9yeS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRmlsZUVycm9yTWFuYWdlcihGaWxlIGRpcikgeworICAgICAgICB0aGlzLmVtYWlsU3RvcmUgPSBkaXI7CisgICAgICAgIGluaXQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJZiB0aGUgbWVzc2FnZSBwYXJhbWV0ZXIgaXMgYSByYXcgZW1haWwsIGFuZCBwYXNzZXMgdGhlIHN0b3JlIHRlcm0sIHRoZW4KKyAgICAgKiB0aGlzIG1ldGhvZCB3aWxsIHN0b3JlIHRoZSBlbWFpbCB0byB0aGUgZmlsZSBzeXN0ZW0uIElmIHRoZSBtZXNzYWdlCisgICAgICogcGFyYW1ldGVyIGlzIG5vdCBhIHJhdyBlbWFpbCB0aGVuIHRoZSBtZXNzYWdlIGlzIGZvcndhcmRlZCB0byB0aGUgc3VwZXIKKyAgICAgKiBjbGFzcy4gSWYgYW4gZW1haWwgaXMgd3JpdHRlbiB0byB0aGUgZmlsZSBzeXN0ZW0gd2l0aG91dCBlcnJvciwgdGhlbiB0aGUKKyAgICAgKiBvcmlnaW5hbCByZXBvcnRlZCBlcnJvciBpcyBpZ25vcmVkLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZyBTdHJpbmcgcmF3IGVtYWlsIG9yIHBsYWluIGVycm9yIG1lc3NhZ2UuCisgICAgICogQHBhcmFtIGV4IEV4Y2VwdGlvbiB0aGF0IG9jY3VycmVkIGluIHRoZSBtYWlsIGhhbmRsZXIuCisgICAgICogQHBhcmFtIGNvZGUgaW50IGVycm9yIG1hbmFnZXIgY29kZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBlcnJvcihTdHJpbmcgbXNnLCBFeGNlcHRpb24gZXgsIGludCBjb2RlKSB7CisgICAgICAgIGlmIChpc1Jhd0VtYWlsKG1zZykpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc3RvcmVFbWFpbChtc2cpOworICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgSU9FeGNlcHRpb24gfCBSdW50aW1lRXhjZXB0aW9uIElPRSkgeworICAgICAgICAgICAgICAgIG5leHQuZXJyb3IobXNnLCBleCwgY29kZSk7CisgICAgICAgICAgICAgICAgc3VwZXIuZXJyb3IoZW1haWxTdG9yZS50b1N0cmluZygpLCBJT0UsIEVycm9yTWFuYWdlci5HRU5FUklDX0ZBSUxVUkUpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgbmV4dC5lcnJvcihtc2csIGV4LCBjb2RlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIHRoZSBpbml0aWFsaXphdGlvbiBmb3IgdGhpcyBvYmplY3QuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGluaXQoKSB7CisgICAgICAgIGlmIChuZXh0ID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbihFcnJvck1hbmFnZXIuY2xhc3MuZ2V0TmFtZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIEZpbGUgZGlyID0gdGhpcy5lbWFpbFN0b3JlOworICAgICAgICBpZiAoZGlyLmdldENsYXNzKCkgIT0gRmlsZS5jbGFzcykgeyAvL0ZvciBzZWN1cml0eSByZWFzb25zLgorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihkaXIuZ2V0Q2xhc3MoKS5nZXROYW1lKCkpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKCFkaXIuaXNEaXJlY3RvcnkoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmlsZSBtdXN0IGJlIGEgZGlyZWN0b3J5LiIpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKCFkaXIuY2FuV3JpdGUoKSkgeyAvL0NhbiB0aHJvdyB1bmRlciBhIHNlY3VyaXR5IG1hbmFnZXIuCisgICAgICAgICAgICBzdXBlci5lcnJvcihkaXIuZ2V0QWJzb2x1dGVQYXRoKCksCisgICAgICAgICAgICAgICAgICAgIG5ldyBTZWN1cml0eUV4Y2VwdGlvbigid3JpdGUiKSwgRXJyb3JNYW5hZ2VyLk9QRU5fRkFJTFVSRSk7CisgICAgICAgIH0KKworICAgICAgICAvL0ZvciBub3csIG9ubHkgYWJzb2x1dGUgcGF0aHMgYXJlIGFsbG93ZWQuCisgICAgICAgIGlmICghZGlyLmlzQWJzb2x1dGUoKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiT25seSBhYnNvbHV0ZSBwYXRocyBhcmUgYWxsb3dlZC4iKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICghZGlyLmNhblJlYWQoKSkgeyAvL0NhbiB0aHJvdyB1bmRlciBhIHNlY3VyaXR5IG1hbmFnZXIuCisgICAgICAgICAgICBzdXBlci5lcnJvcihkaXIuZ2V0QWJzb2x1dGVQYXRoKCksCisgICAgICAgICAgICAgICAgICAgIG5ldyBTZWN1cml0eUV4Y2VwdGlvbigicmVhZCIpLCBFcnJvck1hbmFnZXIuT1BFTl9GQUlMVVJFKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBjb21tb24gdGVtcCBmaWxlIHByZWZpeC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIGZpbGUgcHJlZml4LgorICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nIHByZWZpeE5hbWUoKSB7CisgICAgICAgIHJldHVybiAiRmlsZUVycm9yTWFuYWdlciI7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIGNvbW1vbiB0ZW1wIGZpbGUgc3VmZml4LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZmlsZSBzdWZmaXguCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgc3VmZml4TmFtZSgpIHsKKyAgICAgICAgcmV0dXJuICIuZW1sIjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIGlmIHRoZSBnaXZlbiBtZXNzYWdlIGlzIGEgTUlNRSBtZXNzYWdlIG9yIGp1c3QgZnJlZSB0ZXh0LgorICAgICAqCisgICAgICogQHBhcmFtIG1zZyB0aGUgbWVzc2FnZSB0byBleGFtaW5lLgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBNSU1FIG1lc3NhZ2Ugb3RoZXJ3aXNlIGZhbHNlLgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBpc1Jhd0VtYWlsKFN0cmluZyBtc2cpIHsKKyAgICAgICAgaWYgKG1zZyAhPSBudWxsICYmIG1zZy5sZW5ndGgoKSA+IDApIHsKKyAgICAgICAgICAgIHJldHVybiAhbXNnLnN0YXJ0c1dpdGgoTGV2ZWwuU0VWRVJFLmdldE5hbWUoKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFN0b3JlcyB0aGUgZ2l2ZW4gc3RyaW5nIGluIGEgZmlsZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlbWFpbCB0aGUgbWVzc2FnZSB0byBzdG9yZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHRoZXJlIGlzIGEgcHJvYmxlbS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgc3RvcmVFbWFpbChTdHJpbmcgZW1haWwpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEZpbGUgdG1wID0gbnVsbDsKKyAgICAgICAgRmlsZU91dHB1dFN0cmVhbSBvdXQgPSBudWxsOworICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICB0bXAgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKHByZWZpeE5hbWUoKSwgc3VmZml4TmFtZSgpLCBlbWFpbFN0b3JlKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgb3V0ID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0odG1wKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBGTkZFKSB7CisgICAgICAgICAgICAgICAgaWYgKCF0bXAuZXhpc3RzKCkpIHsgLy9yZXRyeSBpZiBmaWxlIGlzIGxvY2tlZAorICAgICAgICAgICAgICAgICAgICB0aHJvdyBGTkZFOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRyeSAoUHJpbnRTdHJlYW0gcHMgPSBuZXcgUHJpbnRTdHJlYW0od3JhcChvdXQpLCBmYWxzZSwgIlVURi04IikpIHsKKyAgICAgICAgICAgIHBzLnByaW50KGVtYWlsKTsKKyAgICAgICAgICAgIHBzLmZsdXNoKCk7CisgICAgICAgICAgICB0bXAgPSBudWxsOyAvL0Rvbid0IGRlbGV0ZSAndG1wJyBpZiBhbGwgYnl0ZXMgd2VyZSB3cml0dGVuLgorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgY2xvc2Uob3V0KTsKKyAgICAgICAgICAgIGRlbGV0ZSh0bXApOyAvL09ubHkgZGVsZXRlcyBpZiBub3QgbnVsbC4KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIE51bGwgc2FmZSBjbG9zZSBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3V0IGNsb3NlcyB0aGUgZ2l2ZW4gc3RyZWFtLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBjbG9zZShPdXRwdXRTdHJlYW0gb3V0KSB7CisgICAgICAgIGlmIChvdXQgIT0gbnVsbCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIElPRSkgeworICAgICAgICAgICAgICAgIHN1cGVyLmVycm9yKG91dC50b1N0cmluZygpLCBJT0UsIEVycm9yTWFuYWdlci5DTE9TRV9GQUlMVVJFKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIE51bGwgc2FmZSBkZWxldGUgbWV0aG9kLgorICAgICAqCisgICAgICogQHBhcmFtIHRtcCB0aGUgZmlsZSB0byBkZWxldGUuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGRlbGV0ZShGaWxlIHRtcCkgeworICAgICAgICBpZiAodG1wICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaWYgKCF0bXAuZGVsZXRlKCkgJiYgdG1wLmV4aXN0cygpKSB7CisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRtcC5kZWxldGVPbkV4aXQoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGZpbmFsIExpbmthZ2VFcnJvciBzaHV0ZG93bikgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKHNodXRkb3duKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgUnVudGltZUV4Y2VwdGlvbiBzaHV0ZG93bikgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0bXAuZGVsZXRlKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXBlci5lcnJvcih0bXAuZ2V0QWJzb2x1dGVQYXRoKCksIHNodXRkb3duLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXJyb3JNYW5hZ2VyLkNMT1NFX0ZBSUxVUkUpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gU0UpIHsKKyAgICAgICAgICAgICAgICBzdXBlci5lcnJvcih0bXAudG9TdHJpbmcoKSwgU0UsIEVycm9yTWFuYWdlci5DTE9TRV9GQUlMVVJFKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGxvY2F0aW9uIG9mIHRoZSBlbWFpbCBzdG9yZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIEZpbGUgbG9jYXRpb24uCisgICAgICovCisgICAgcHJpdmF0ZSBGaWxlIGdldEVtYWlsU3RvcmUoKSB7CisgICAgICAgIFN0cmluZyBkaXIgPSBtYW5hZ2VyLmdldFByb3BlcnR5KAorICAgICAgICAgICAgICAgIGdldENsYXNzKCkuZ2V0TmFtZSgpLmNvbmNhdCgiLnBhdHRlcm4iKSk7CisgICAgICAgIGlmIChkaXIgPT0gbnVsbCkgeworICAgICAgICAgICAgZGlyID0gQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb248U3RyaW5nPigpIHsKKworICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgcnVuKCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gU3lzdGVtLmdldFByb3BlcnR5KCJqYXZhLmlvLnRtcGRpciIsICIuIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBGaWxlKGRpcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JhcHMgdGhlIGdpdmVuIHN0cmVhbSBhcyBhIE5ld0xpbmVPdXRwdXRTdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3V0IHRoZSBzdHJlYW0gdG8gd3JhcC4KKyAgICAgKiBAcmV0dXJuIHRoZSBvcmlnaW5hbCBvciB3cmFwcGVkIG91dHB1dCBzdHJlYW0uCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoIlVzZVNwZWNpZmljQ2F0Y2giKQorICAgIHByaXZhdGUgT3V0cHV0U3RyZWFtIHdyYXAoT3V0cHV0U3RyZWFtIG91dCkgeworICAgICAgICBhc3NlcnQgb3V0ICE9IG51bGw7CisgICAgICAgIENsYXNzPD8+IGs7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrID0gQ2xhc3MuZm9yTmFtZSgiTmV3bGluZU91dHB1dFN0cmVhbSIpOworICAgICAgICAgICAgaWYgKE91dHB1dFN0cmVhbS5jbGFzcy5pc0Fzc2lnbmFibGVGcm9tKGspKSB7CisgICAgICAgICAgICAgICAgQ29uc3RydWN0b3I8Pz4gYyA9IGsuZ2V0Q29uc3RydWN0b3IoT3V0cHV0U3RyZWFtLmNsYXNzKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gKE91dHB1dFN0cmVhbSkgYy5uZXdJbnN0YW5jZShvdXQpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBzdXBlci5lcnJvcigiVW5hYmxlIHRvIHN3aXRjaCBuZXdsaW5lcyIsCisgICAgICAgICAgICAgICAgICAgICAgICBuZXcgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbihrLmdldE5hbWUoKSksCisgICAgICAgICAgICAgICAgICAgICAgICBFcnJvck1hbmFnZXIuR0VORVJJQ19GQUlMVVJFKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiByZSkgeworICAgICAgICAgICAgc3VwZXIuZXJyb3IoIlVuYWJsZSB0byBzd2l0Y2ggbmV3bGluZXMiLAorICAgICAgICAgICAgICAgICAgICByZSwgRXJyb3JNYW5hZ2VyLkdFTkVSSUNfRkFJTFVSRSk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgc3VwZXIuZXJyb3IoIlVuYWJsZSB0byBzd2l0Y2ggbmV3bGluZXMiLAorICAgICAgICAgICAgICAgICAgICBleCwgRXJyb3JNYW5hZ2VyLkdFTkVSSUNfRkFJTFVSRSk7CisgICAgICAgIH0gY2F0Y2ggKExpbmthZ2VFcnJvciBsZSkgeworICAgICAgICAgICAgc3VwZXIuZXJyb3IoIlVuYWJsZSB0byBzd2l0Y2ggbmV3bGluZXMiLAorICAgICAgICAgICAgICAgICAgICBuZXcgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbigiIiwgbGUpLAorICAgICAgICAgICAgICAgICAgICBFcnJvck1hbmFnZXIuR0VORVJJQ19GQUlMVVJFKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gb3V0OworICAgIH0KK30KZGlmZiAtLWdpdCBhL2xvZ2dpbmcvc3JjL21haW4vamF2YS9NYWlsSGFuZGxlckRlbW8uamF2YSBiL2xvZ2dpbmcvc3JjL21haW4vamF2YS9NYWlsSGFuZGxlckRlbW8uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMmM5MThmCi0tLSAvZGV2L251bGwKKysrIGIvbG9nZ2luZy9zcmMvbWFpbi9qYXZhL01haWxIYW5kbGVyRGVtby5qYXZhCkBAIC0wLDAgKzEsNjQ3IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDA5LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKiBDb3B5cmlnaHQgKGMpIDIwMDksIDIwMTggSmFzb24gTWVocmVucy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorICovCisKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nLkNvbGxlY3RvckZvcm1hdHRlcjsKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nLkR1cmF0aW9uRmlsdGVyOworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLmxvZ2dpbmcuTWFpbEhhbmRsZXI7CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwubG9nZ2luZy5TZXZlcml0eUNvbXBhcmF0b3I7CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5QcmludFN0cmVhbTsKK2ltcG9ydCBqYXZhLmxhbmcubWFuYWdlbWVudC5NYW5hZ2VtZW50RmFjdG9yeTsKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBqYXZhLnV0aWwubG9nZ2luZy4qOworaW1wb3J0IGphdmF4LmFjdGl2YXRpb24uRGF0YUhhbmRsZXI7CitpbXBvcnQgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YXgubWFpbC5TZXNzaW9uOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuSW50ZXJuZXRBZGRyZXNzOworCisvKioKKyAqIERlbW8gZm9yIHRoZSBkaWZmZXJlbnQgY29uZmlndXJhdGlvbnMgZm9yIHRoZSBNYWlsSGFuZGxlci4gSWYgdGhlIGxvZ2dpbmcKKyAqIHByb3BlcnRpZXMgZmlsZSBvciBjbGFzcyBpcyBub3Qgc3BlY2lmaWVkIHRoZW4gdGhpcyBkZW1vIHdpbGwgYXBwbHkgc29tZQorICogZGVmYXVsdCBzZXR0aW5ncyB0byBzdG9yZSBlbWFpbHMgaW4gdGhlIHVzZXIncyB0ZW1wIGRpcmVjdG9yeS4KKyAqCisgKiBAYXV0aG9yIEphc29uIE1laHJlbnMKKyAqLworcHVibGljIGNsYXNzIE1haWxIYW5kbGVyRGVtbyB7CisKKyAgICAvKioKKyAgICAgKiBUaGlzIGNsYXNzIG5hbWUuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIENMQVNTX05BTUUgPSBNYWlsSGFuZGxlckRlbW8uY2xhc3MuZ2V0TmFtZSgpOworICAgIC8qKgorICAgICAqIFRoZSBsb2dnZXIgZm9yIHRoaXMgY2xhc3MgbmFtZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBMb2dnZXIgTE9HR0VSID0gTG9nZ2VyLmdldExvZ2dlcihDTEFTU19OQU1FKTsKKworICAgIC8qKgorICAgICAqIFJ1bnMgdGhlIGRlbW8uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYXJncyB0aGUgY29tbWFuZCBsaW5lIGFyZ3VtZW50cworICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgdGhlcmUgaXMgYSBwcm9ibGVtLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIExpc3Q8U3RyaW5nPiBsID0gQXJyYXlzLmFzTGlzdChhcmdzKTsKKyAgICAgICAgaWYgKGwuY29udGFpbnMoIi8/IikgfHwgbC5jb250YWlucygiLT8iKSB8fCBsLmNvbnRhaW5zKCItaGVscCIpKSB7CisgICAgICAgICAgICBMT0dHRVIuaW5mbygiVXNhZ2U6IGphdmEgTWFpbEhhbmRsZXJEZW1vICIKKyAgICAgICAgICAgICAgICAgICAgKyAiW1stYWxsXSB8IFstYm9keV0gfCBbLWN1c3RvbV0gfCBbLWRlYnVnXSB8IFstbG93XSAiCisgICAgICAgICAgICAgICAgICAgICsgInwgWy1zaW1wbGVdIHwgWy1wdXNobGV2ZWxdIHwgWy1wdXNoZmlsdGVyXSAiCisgICAgICAgICAgICAgICAgICAgICsgInwgWy1wdXNobm9ybWFsXSB8IFstcHVzaG9ubHldXSAiCisgICAgICAgICAgICAgICAgICAgICsgIlxuXG4iCisgICAgICAgICAgICAgICAgICAgICsgIi1hbGxcdFx0OiBFeGVjdXRlIGFsbCBkZW1vcy5cbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiLWJvZHlcdFx0OiBBbiBlbWFpbCB3aXRoIGFsbCByZWNvcmRzIGFuZCBvbmx5IGEgYm9keS5cbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiLWN1c3RvbVx0XHQ6IEFuIGVtYWlsIHdpdGggYXR0YWNobWVudHMgYW5kIGR5bmFtaWMgbmFtZXMuXG4iCisgICAgICAgICAgICAgICAgICAgICsgIi1kZWJ1Z1x0XHQ6IE91dHB1dCBiYXNpYyBkZWJ1ZyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgSlZNICIKKyAgICAgICAgICAgICAgICAgICAgKyAiYW5kIGxvZyBjb25maWd1cmF0aW9uLlxuIgorICAgICAgICAgICAgICAgICAgICArICItbG93XHRcdDogR2VuZXJhdGVzIG11bHRpcGxlIGVtYWlscyBkdWUgdG8gbG93IGNhcGFjaXR5LiIKKyAgICAgICAgICAgICAgICAgICAgKyAiXG4iCisgICAgICAgICAgICAgICAgICAgICsgIi1zaW1wbGVcdFx0OiBBbiBlbWFpbCB3aXRoIGFsbCByZWNvcmRzIHdpdGggYm9keSBhbmQgIgorICAgICAgICAgICAgICAgICAgICArICJhbiBhdHRhY2htZW50LlxuIgorICAgICAgICAgICAgICAgICAgICArICItcHVzaGxldmVsXHQ6IEdlbmVyYXRlcyBoaWdoIHByaW9yaXR5IGVtYWlscyB3aGVuIHRoZSIKKyAgICAgICAgICAgICAgICAgICAgKyAiIHB1c2ggbGV2ZWwgaXMgdHJpZ2dlcmVkIGFuZCBub3JtYWwgcHJpb3JpdHkgd2hlbiAiCisgICAgICAgICAgICAgICAgICAgICsgImZsdXNoZWQuXG4iCisgICAgICAgICAgICAgICAgICAgICsgIi1wdXNoRmlsdGVyXHQ6IEdlbmVyYXRlcyBoaWdoIHByaW9yaXR5IGVtYWlscyB3aGVuIHRoZSAiCisgICAgICAgICAgICAgICAgICAgICsgInB1c2ggbGV2ZWwgYW5kIHRoZSBwdXNoIGZpbHRlciBpcyB0cmlnZ2VyZWQgYW5kIG5vcm1hbCAiCisgICAgICAgICAgICAgICAgICAgICsgInByaW9yaXR5IGVtYWlscyB3aGVuIGZsdXNoZWQuXG4iCisgICAgICAgICAgICAgICAgICAgICsgIi1wdXNobm9ybWFsXHQ6IEdlbmVyYXRlcyBtdWx0aXBsZSBlbWFpbHMgd2hlbiB0aGUgIgorICAgICAgICAgICAgICAgICAgICArICJNZW1vcnlIYW5kbGVyIHB1c2ggbGV2ZWwgaXMgdHJpZ2dlcmVkLiAgQWxsIGdlbmVyYXRlZCAiCisgICAgICAgICAgICAgICAgICAgICsgImVtYWlsIGFyZSBzZW50IGFzIG5vcm1hbCBwcmlvcml0eS5cbiIKKyAgICAgICAgICAgICAgICAgICAgKyAiLXB1c2hvbmx5XHQ6IEdlbmVyYXRlcyBtdWx0aXBsZSBlbWFpbHMgd2hlbiB0aGUgIgorICAgICAgICAgICAgICAgICAgICArICJNZW1vcnlIYW5kbGVyIHB1c2ggbGV2ZWwgaXMgdHJpZ2dlcmVkLiAgR2VuZXJhdGVzIGhpZ2ggIgorICAgICAgICAgICAgICAgICAgICArICJwcmlvcml0eSBlbWFpbHMgd2hlbiB0aGUgcHVzaCBsZXZlbCBpcyB0cmlnZ2VyZWQgYW5kICIKKyAgICAgICAgICAgICAgICAgICAgKyAibm9ybWFsIHByaW9yaXR5IHdoZW4gZmx1c2hlZC5cbiIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZmluYWwgYm9vbGVhbiBkZWJ1ZyA9IGluaXQobCk7IC8vbWF5IGNyZWF0ZSBsb2cgbWVzc2FnZXMuCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIExPR0dFUi5sb2coTGV2ZWwuRklORVNULCAiVGhpcyBpcyB0aGUgZmluZXN0IHBhcnQgb2YgdGhlIGRlbW8uIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oIkZha2UgSmF2YU1haWwgaXNzdWUuIikpOworICAgICAgICAgICAgICAgIExPR0dFUi5sb2coTGV2ZWwuRklORVIsICJUaGlzIGlzIHRoZSBmaW5lciBwYXJ0IG9mIHRoZSBkZW1vLiIsCisgICAgICAgICAgICAgICAgICAgICAgICBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIkZha2UgYnVnLiIpKTsKKyAgICAgICAgICAgICAgICBMT0dHRVIubG9nKExldmVsLkZJTkUsICJUaGlzIGlzIHRoZSBmaW5lIHBhcnQgb2YgdGhlIGRlbW8uIik7CisgICAgICAgICAgICAgICAgTE9HR0VSLmxvZyhMZXZlbC5DT05GSUcsICJMb2dnaW5nIGNvbmZpZyBmaWxlIGlzIHswfS4iLAorICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Q29uZmlnTG9jYXRpb24oKSk7CisgICAgICAgICAgICAgICAgTE9HR0VSLmxvZyhMZXZlbC5JTkZPLCAiWW91ciB0ZW1wIGRpcmVjdG9yeSBpcyB7MH0sICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgInBsZWFzZSB3YWl0Li4uIiwgZ2V0VGVtcERpcigpKTsKKworICAgICAgICAgICAgICAgIHRyeSB7IC8vV2FzdGUgc29tZSB0aW1lIGZvciB0aGUgY3VzdG9tIGZvcm1hdHRlci4KKyAgICAgICAgICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDNMICogMTAwMEwpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgICAgIFRocmVhZC5jdXJyZW50VGhyZWFkKCkuaW50ZXJydXB0KCk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgTE9HR0VSLmxvZyhMZXZlbC5XQVJOSU5HLCAiVGhpcyBpcyBhIHdhcm5pbmcuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBGaWxlTm90Rm91bmRFeGNlcHRpb24oIkZha2UgZmlsZSBjaG9vc2VyIGlzc3VlLiIpKTsKKyAgICAgICAgICAgICAgICBMT0dHRVIubG9nKExldmVsLlNFVkVSRSwgIlRoZSBlbmQgb2YgdGhlIGRlbW8uIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBJT0V4Y2VwdGlvbigiRmFrZSBhY2Nlc3MgZGVuaWVkIGlzc3VlLiIpKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgY2xvc2VIYW5kbGVycygpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvL0ZvcmNlIHBhcnNlIGVycm9ycy4gIFRoaXMgZG9lcyBoYXZlIHNpZGUgZWZmZWN0cy4KKyAgICAgICAgICAgIGlmIChkZWJ1ZyAmJiBnZXRDb25maWdMb2NhdGlvbigpICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBMb2dNYW5hZ2VyLmdldExvZ01hbmFnZXIoKS5yZWFkQ29uZmlndXJhdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVXNlZCBkZWJ1ZyBwcm9ibGVtcyB3aXRoIHRoZSBsb2dnaW5nLnByb3BlcnRpZXMuIFRoZSBzeXN0ZW0gcHJvcGVydHkKKyAgICAgKiBqYXZhLnNlY3VyaXR5LmRlYnVnPWFjY2VzcyxzdGFjayBjYW4gYmUgdXNlZCB0byB0cmFjZSBhY2Nlc3MgdG8gdGhlCisgICAgICogTG9nTWFuYWdlciByZXNldC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwcmVmaXggYSBzdHJpbmcgdG8gcHJlZml4IHRoZSBvdXRwdXQuCisgICAgICogQHBhcmFtIGVyciBhbnkgUHJpbnRTdHJlYW0gb3IgbnVsbCBmb3IgU3lzdGVtLm91dC4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiVXNlT2ZTeXN0ZW1PdXRPclN5c3RlbUVyciIpCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBjaGVja0NvbmZpZyhTdHJpbmcgcHJlZml4LCBQcmludFN0cmVhbSBlcnIpIHsKKyAgICAgICAgaWYgKHByZWZpeCA9PSBudWxsIHx8IHByZWZpeC50cmltKCkubGVuZ3RoKCkgPT0gMCkgeworICAgICAgICAgICAgcHJlZml4ID0gIkRFQlVHIjsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChlcnIgPT0gbnVsbCkgeworICAgICAgICAgICAgZXJyID0gU3lzdGVtLm91dDsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlcnIucHJpbnRsbihwcmVmaXggKyAiOiBqYXZhLnZlcnNpb249IgorICAgICAgICAgICAgICAgICAgICArIFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS52ZXJzaW9uIikpOworICAgICAgICAgICAgZXJyLnByaW50bG4ocHJlZml4ICsgIjogTE9HR0VSPSIgKyBMT0dHRVIuZ2V0TGV2ZWwoKSk7CisgICAgICAgICAgICBlcnIucHJpbnRsbihwcmVmaXggKyAiOiBKVk0gaWQgIgorICAgICAgICAgICAgICAgICAgICArIE1hbmFnZW1lbnRGYWN0b3J5LmdldFJ1bnRpbWVNWEJlYW4oKS5nZXROYW1lKCkpOworICAgICAgICAgICAgZXJyLnByaW50bG4ocHJlZml4ICsgIjogamF2YS5zZWN1cml0eS5kZWJ1Zz0iCisgICAgICAgICAgICAgICAgICAgICsgU3lzdGVtLmdldFByb3BlcnR5KCJqYXZhLnNlY3VyaXR5LmRlYnVnIikpOworICAgICAgICAgICAgU2VjdXJpdHlNYW5hZ2VyIHNtID0gU3lzdGVtLmdldFNlY3VyaXR5TWFuYWdlcigpOworICAgICAgICAgICAgaWYgKHNtICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBlcnIucHJpbnRsbihwcmVmaXggKyAiOiBTZWN1cml0eU1hbmFnZXIuY2xhc3M9IgorICAgICAgICAgICAgICAgICAgICAgICAgKyBzbS5nZXRDbGFzcygpLmdldE5hbWUoKSk7CisgICAgICAgICAgICAgICAgZXJyLnByaW50bG4ocHJlZml4ICsgIjogU2VjdXJpdHlNYW5hZ2VyIGNsYXNzTG9hZGVyPSIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgdG9TdHJpbmcoc20uZ2V0Q2xhc3MoKS5nZXRDbGFzc0xvYWRlcigpKSk7CisgICAgICAgICAgICAgICAgZXJyLnByaW50bG4ocHJlZml4ICsgIjogU2VjdXJpdHlNYW5hZ2VyLnRvU3RyaW5nPSIgKyBzbSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGVyci5wcmludGxuKHByZWZpeCArICI6IFNlY3VyaXR5TWFuYWdlci5jbGFzcz1udWxsIik7CisgICAgICAgICAgICAgICAgZXJyLnByaW50bG4ocHJlZml4ICsgIjogU2VjdXJpdHlNYW5hZ2VyLnRvU3RyaW5nPW51bGwiKTsKKyAgICAgICAgICAgICAgICBlcnIucHJpbnRsbihwcmVmaXggKyAiOiBTZWN1cml0eU1hbmFnZXIgY2xhc3NMb2FkZXI9bnVsbCIpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBTdHJpbmcgcG9saWN5ID0gU3lzdGVtLmdldFByb3BlcnR5KCJqYXZhLnNlY3VyaXR5LnBvbGljeSIpOworICAgICAgICAgICAgaWYgKHBvbGljeSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgRmlsZSBmID0gbmV3IEZpbGUocG9saWN5KTsKKyAgICAgICAgICAgICAgICBlcnIucHJpbnRsbihwcmVmaXggKyAiOiBBYnNvbHV0ZVBhdGg9IiArIGYuZ2V0QWJzb2x1dGVQYXRoKCkpOworICAgICAgICAgICAgICAgIGVyci5wcmludGxuKHByZWZpeCArICI6IENhbm9uaWNhbFBhdGg9IiArIGYuZ2V0Q2Fub25pY2FsUGF0aCgpKTsKKyAgICAgICAgICAgICAgICBlcnIucHJpbnRsbihwcmVmaXggKyAiOiBsZW5ndGg9IiArIGYubGVuZ3RoKCkpOworICAgICAgICAgICAgICAgIGVyci5wcmludGxuKHByZWZpeCArICI6IGNhblJlYWQ9IiArIGYuY2FuUmVhZCgpKTsKKyAgICAgICAgICAgICAgICBlcnIucHJpbnRsbihwcmVmaXggKyAiOiBsYXN0TW9kaWZpZWQ9IgorICAgICAgICAgICAgICAgICAgICAgICAgKyBuZXcgamF2YS51dGlsLkRhdGUoZi5sYXN0TW9kaWZpZWQoKSkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBMb2dNYW5hZ2VyIG1hbmFnZXIgPSBMb2dNYW5hZ2VyLmdldExvZ01hbmFnZXIoKTsKKyAgICAgICAgICAgIFN0cmluZyBrZXkgPSAiamF2YS51dGlsLmxvZ2dpbmcuY29uZmlnLmZpbGUiOworICAgICAgICAgICAgU3RyaW5nIGNmZyA9IFN5c3RlbS5nZXRQcm9wZXJ0eShrZXkpOworICAgICAgICAgICAgaWYgKGNmZyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgZXJyLnByaW50bG4ocHJlZml4ICsgIjogIiArIGNmZyk7CisgICAgICAgICAgICAgICAgRmlsZSBmID0gbmV3IEZpbGUoY2ZnKTsKKyAgICAgICAgICAgICAgICBlcnIucHJpbnRsbihwcmVmaXggKyAiOiBBYnNvbHV0ZVBhdGg9IiArIGYuZ2V0QWJzb2x1dGVQYXRoKCkpOworICAgICAgICAgICAgICAgIGVyci5wcmludGxuKHByZWZpeCArICI6IENhbm9uaWNhbFBhdGg9IiArIGYuZ2V0Q2Fub25pY2FsUGF0aCgpKTsKKyAgICAgICAgICAgICAgICBlcnIucHJpbnRsbihwcmVmaXggKyAiOiBsZW5ndGg9IiArIGYubGVuZ3RoKCkpOworICAgICAgICAgICAgICAgIGVyci5wcmludGxuKHByZWZpeCArICI6IGNhblJlYWQ9IiArIGYuY2FuUmVhZCgpKTsKKyAgICAgICAgICAgICAgICBlcnIucHJpbnRsbihwcmVmaXggKyAiOiBsYXN0TW9kaWZpZWQ9IgorICAgICAgICAgICAgICAgICAgICAgICAgKyBuZXcgamF2YS51dGlsLkRhdGUoZi5sYXN0TW9kaWZpZWQoKSkpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBlcnIucHJpbnRsbihwcmVmaXggKyAiOiAiICsga2V5CisgICAgICAgICAgICAgICAgICAgICAgICArICIgaXMgbm90IHNldCBhcyBhIHN5c3RlbSBwcm9wZXJ0eS4iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVyci5wcmludGxuKHByZWZpeCArICI6IExvZ01hbmFnZXIuY2xhc3M9IgorICAgICAgICAgICAgICAgICAgICArIG1hbmFnZXIuZ2V0Q2xhc3MoKS5nZXROYW1lKCkpOworICAgICAgICAgICAgZXJyLnByaW50bG4ocHJlZml4ICsgIjogTG9nTWFuYWdlciBjbGFzc0xvYWRlcj0iCisgICAgICAgICAgICAgICAgICAgICsgdG9TdHJpbmcobWFuYWdlci5nZXRDbGFzcygpLmdldENsYXNzTG9hZGVyKCkpKTsKKyAgICAgICAgICAgIGVyci5wcmludGxuKHByZWZpeCArICI6IExvZ01hbmFnZXIudG9TdHJpbmc9IiArIG1hbmFnZXIpOworICAgICAgICAgICAgZXJyLnByaW50bG4ocHJlZml4ICsgIjogTWFpbEhhbmRsZXIgY2xhc3NMb2FkZXI9IgorICAgICAgICAgICAgICAgICAgICArIHRvU3RyaW5nKE1haWxIYW5kbGVyLmNsYXNzLmdldENsYXNzTG9hZGVyKCkpKTsKKyAgICAgICAgICAgIGVyci5wcmludGxuKHByZWZpeCArICI6IENvbnRleHQgQ2xhc3NMb2FkZXI9IgorICAgICAgICAgICAgICAgICAgICArIHRvU3RyaW5nKFRocmVhZC5jdXJyZW50VGhyZWFkKCkuZ2V0Q29udGV4dENsYXNzTG9hZGVyKCkpKTsKKyAgICAgICAgICAgIGVyci5wcmludGxuKHByZWZpeCArICI6IFNlc3Npb24gQ2xhc3NMb2FkZXI9IgorICAgICAgICAgICAgICAgICAgICArIHRvU3RyaW5nKFNlc3Npb24uY2xhc3MuZ2V0Q2xhc3NMb2FkZXIoKSkpOworICAgICAgICAgICAgZXJyLnByaW50bG4ocHJlZml4ICsgIjogRGF0YUhhbmRsZXIgQ2xhc3NMb2FkZXI9IgorICAgICAgICAgICAgICAgICAgICArIHRvU3RyaW5nKERhdGFIYW5kbGVyLmNsYXNzLmdldENsYXNzTG9hZGVyKCkpKTsKKworICAgICAgICAgICAgZmluYWwgU3RyaW5nIHAgPSBNYWlsSGFuZGxlci5jbGFzcy5nZXROYW1lKCk7CisgICAgICAgICAgICBrZXkgPSBwLmNvbmNhdCgiLm1haWwudG8iKTsKKyAgICAgICAgICAgIFN0cmluZyB0byA9IG1hbmFnZXIuZ2V0UHJvcGVydHkoa2V5KTsKKyAgICAgICAgICAgIGVyci5wcmludGxuKHByZWZpeCArICI6IFRPPSIgKyB0byk7CisgICAgICAgICAgICBpZiAodG8gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGVyci5wcmludGxuKHByZWZpeCArICI6IFRPPSIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgQXJyYXlzLnRvU3RyaW5nKEludGVybmV0QWRkcmVzcy5wYXJzZSh0bywgdHJ1ZSkpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAga2V5ID0gcC5jb25jYXQoIi5tYWlsLmZyb20iKTsKKyAgICAgICAgICAgIFN0cmluZyBmcm9tID0gbWFuYWdlci5nZXRQcm9wZXJ0eShrZXkpOworICAgICAgICAgICAgaWYgKGZyb20gPT0gbnVsbCB8fCBmcm9tLmxlbmd0aCgpID09IDApIHsKKyAgICAgICAgICAgICAgICBTZXNzaW9uIHNlc3Npb24gPSBTZXNzaW9uLmdldEluc3RhbmNlKG5ldyBQcm9wZXJ0aWVzKCkpOworICAgICAgICAgICAgICAgIEludGVybmV0QWRkcmVzcyBsb2NhbCA9IEludGVybmV0QWRkcmVzcy5nZXRMb2NhbEFkZHJlc3Moc2Vzc2lvbik7CisgICAgICAgICAgICAgICAgZXJyLnByaW50bG4ocHJlZml4ICsgIjogRlJPTT0iICsgbG9jYWwpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBlcnIucHJpbnRsbihwcmVmaXggKyAiOiBGUk9NPSIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgQXJyYXlzLmFzTGlzdChJbnRlcm5ldEFkZHJlc3MucGFyc2UoZnJvbSwgZmFsc2UpKSk7CisgICAgICAgICAgICAgICAgZXJyLnByaW50bG4ocHJlZml4ICsgIjogRlJPTT0iCisgICAgICAgICAgICAgICAgICAgICAgICArIEFycmF5cy5hc0xpc3QoSW50ZXJuZXRBZGRyZXNzLnBhcnNlKGZyb20sIHRydWUpKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAobWFuYWdlcikgeworICAgICAgICAgICAgICAgIGZpbmFsIEVudW1lcmF0aW9uPFN0cmluZz4gZSA9IG1hbmFnZXIuZ2V0TG9nZ2VyTmFtZXMoKTsKKyAgICAgICAgICAgICAgICB3aGlsZSAoZS5oYXNNb3JlRWxlbWVudHMoKSkgeworICAgICAgICAgICAgICAgICAgICBmaW5hbCBMb2dnZXIgbCA9IG1hbmFnZXIuZ2V0TG9nZ2VyKGUubmV4dEVsZW1lbnQoKSk7CisgICAgICAgICAgICAgICAgICAgIGlmIChsICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEhhbmRsZXJbXSBoYW5kbGVycyA9IGwuZ2V0SGFuZGxlcnMoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChoYW5kbGVycy5sZW5ndGggPiAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyLnByaW50bG4ocHJlZml4ICsgIjogIiArIGwuZ2V0Q2xhc3MoKS5nZXROYW1lKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiwgIiArIGwuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKEhhbmRsZXIgaCA6IGhhbmRsZXJzKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVyci5wcmludGxuKHByZWZpeCArICI6XHQiICsgdG9TdHJpbmcocHJlZml4LCBlcnIsIGgpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSBlcnJvcikgeworICAgICAgICAgICAgZXJyLnByaW50KHByZWZpeCArICI6ICIpOworICAgICAgICAgICAgZXJyb3IucHJpbnRTdGFja1RyYWNlKGVycik7CisgICAgICAgIH0KKyAgICAgICAgZXJyLmZsdXNoKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgY2xhc3MgbG9hZGVyIGxpc3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY2wgdGhlIGNsYXNzIGxvYWRlciBvciBudWxsLgorICAgICAqIEByZXR1cm4gdGhlIGNsYXNzIGxvYWRlciBsaXN0LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyB0b1N0cmluZyhDbGFzc0xvYWRlciBjbCkgeworICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIGJ1Zi5hcHBlbmQoY2wpOworICAgICAgICB3aGlsZSAoY2wgIT0gbnVsbCkgeworICAgICAgICAgICAgY2wgPSBjbC5nZXRQYXJlbnQoKTsKKyAgICAgICAgICAgIGJ1Zi5hcHBlbmQoIjwtIikuYXBwZW5kKGNsKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhIGZvcm1hdHRpbmcgc3RyaW5nIGRlc2NyaWJpbmcgdGhlIGdpdmVuIGhhbmRsZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcHJlZml4IHRoZSBvdXRwdXQgcHJlZml4LgorICAgICAqIEBwYXJhbSBlcnIgdGhlIGVycm9yIHN0cmVhbS4KKyAgICAgKiBAcGFyYW0gaCB0aGUgaGFuZGxlci4KKyAgICAgKiBAcmV0dXJuIHRoZSBmb3JtYXR0ZWQgc3RyaW5nLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyB0b1N0cmluZyhTdHJpbmcgcHJlZml4LCBQcmludFN0cmVhbSBlcnIsIEhhbmRsZXIgaCkgeworICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICAgIGJ1Zi5hcHBlbmQoaC5nZXRDbGFzcygpLmdldE5hbWUoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAoaCBpbnN0YW5jZW9mIE1haWxIYW5kbGVyKSB7CisgICAgICAgICAgICAgICAgTWFpbEhhbmRsZXIgbWggPSAoTWFpbEhhbmRsZXIpIGg7CisgICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgiLCAiKS5hcHBlbmQobWguZ2V0U3ViamVjdCgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gZXJyb3IpIHsKKyAgICAgICAgICAgIGVyci5wcmludChwcmVmaXggKyAiOiAiKTsKKyAgICAgICAgICAgIGVycm9yLnByaW50U3RhY2tUcmFjZShlcnIpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJ1Zi5hcHBlbmQoIiwgIikuYXBwZW5kKGguZ2V0Rm9ybWF0dGVyKCkpOworICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBlcnJvcikgeworICAgICAgICAgICAgZXJyLnByaW50KHByZWZpeCArICI6ICIpOworICAgICAgICAgICAgZXJyb3IucHJpbnRTdGFja1RyYWNlKGVycik7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKGggaW5zdGFuY2VvZiBNYWlsSGFuZGxlcikgeworICAgICAgICAgICAgICAgIE1haWxIYW5kbGVyIG1oID0gKE1haWxIYW5kbGVyKSBoOworICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoIiwgIikuYXBwZW5kKEFycmF5cy50b1N0cmluZygKKyAgICAgICAgICAgICAgICAgICAgICAgIG1oLmdldEF0dGFjaG1lbnRGb3JtYXR0ZXJzKCkpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gZXJyb3IpIHsKKyAgICAgICAgICAgIGVyci5wcmludChwcmVmaXggKyAiOiAiKTsKKyAgICAgICAgICAgIGVycm9yLnByaW50U3RhY2tUcmFjZShlcnIpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJ1Zi5hcHBlbmQoIiwgIikuYXBwZW5kKGguZ2V0TGV2ZWwoKSk7CisgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGVycm9yKSB7CisgICAgICAgICAgICBlcnIucHJpbnQocHJlZml4ICsgIjogIik7CisgICAgICAgICAgICBlcnJvci5wcmludFN0YWNrVHJhY2UoZXJyKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBidWYuYXBwZW5kKCIsICIpLmFwcGVuZChoLmdldEZpbHRlcigpKTsKKyAgICAgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gZXJyb3IpIHsKKyAgICAgICAgICAgIGVyci5wcmludChwcmVmaXggKyAiOiAiKTsKKyAgICAgICAgICAgIGVycm9yLnByaW50U3RhY2tUcmFjZShlcnIpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJ1Zi5hcHBlbmQoIiwgIikuYXBwZW5kKGguZ2V0RXJyb3JNYW5hZ2VyKCkpOworICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBlcnJvcikgeworICAgICAgICAgICAgZXJyLnByaW50KHByZWZpeCArICI6ICIpOworICAgICAgICAgICAgZXJyb3IucHJpbnRTdGFja1RyYWNlKGVycik7CisgICAgICAgIH0KKworICAgICAgICBidWYuYXBwZW5kKCIsICIpLmFwcGVuZCh0b1N0cmluZyhoLmdldENsYXNzKCkuZ2V0Q2xhc3NMb2FkZXIoKSkpOworICAgICAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXhhbXBsZSBmb3IgYm9keSBvbmx5IG1lc3NhZ2VzLiBPbiBjbG9zZSB0aGUgcmVtYWluaW5nIG1lc3NhZ2VzIGFyZSBzZW50LiAgICAgIDxjb2RlPgorICAgICAqICMjbG9nZ2luZy5wcm9wZXJ0aWVzCisgICAgICogTWFpbEhhbmRsZXJEZW1vLmhhbmRsZXJzPWNvbS5zdW4ubWFpbC51dGlsLmxvZ2dpbmcuTWFpbEhhbmRsZXIKKyAgICAgKiBjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nLk1haWxIYW5kbGVyLnN1YmplY3Q9Qm9keSBvbmx5IGRlbW8KKyAgICAgKiAjIworICAgICAqIDwvY29kZT4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGluaXRCb2R5T25seSgpIHsKKyAgICAgICAgTWFpbEhhbmRsZXIgaCA9IG5ldyBNYWlsSGFuZGxlcigpOworICAgICAgICBoLnNldFN1YmplY3QoIkJvZHkgb25seSBkZW1vIik7CisgICAgICAgIExPR0dFUi5hZGRIYW5kbGVyKGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEV4YW1wbGUgc2hvd2luZyB0aGF0IHdoZW4gdGhlIG1haWwgaGFuZGxlciByZWFjaGVzIGNhcGFjaXR5IGl0IHdpbGwKKyAgICAgKiBmb3JtYXQgYW5kIHNlbmQgdGhlIGN1cnJlbnQgcmVjb3Jkcy4gQ2FwYWNpdHkgaXMgdXNlZCB0byByb3VnaGx5IGxpbWl0CisgICAgICogdGhlIHNpemUgb2YgYW4gb3V0Z29pbmcgbWVzc2FnZS4gT24gY2xvc2UgYW55IHJlbWFpbmluZyBtZXNzYWdlcyBhcmUKKyAgICAgKiBzZW50LiAgICAgIDxjb2RlPgorICAgICAqICMjbG9nZ2luZy5wcm9wZXJ0aWVzCisgICAgICogTWFpbEhhbmRsZXJEZW1vLmhhbmRsZXJzPWNvbS5zdW4ubWFpbC51dGlsLmxvZ2dpbmcuTWFpbEhhbmRsZXIKKyAgICAgKiBjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nLk1haWxIYW5kbGVyLnN1YmplY3Q9TG93IGNhcGFjaXR5IGRlbW8KKyAgICAgKiBjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nLk1haWxIYW5kbGVyLmNhcGFjaXR5PTUKKyAgICAgKiAjIworICAgICAqIDwvY29kZT4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGluaXRMb3dDYXBhY2l0eSgpIHsKKyAgICAgICAgTWFpbEhhbmRsZXIgaCA9IG5ldyBNYWlsSGFuZGxlcig1KTsKKyAgICAgICAgaC5zZXRTdWJqZWN0KCJMb3cgY2FwYWNpdHkgZGVtbyIpOworICAgICAgICBMT0dHRVIuYWRkSGFuZGxlcihoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFeGFtcGxlIGZvciBib2R5IG9ubHkgbWVzc2FnZXMuIE9uIGNsb3NlIGFueSByZW1haW5pbmcgbWVzc2FnZXMgYXJlIHNlbnQuICAgICAgPGNvZGU+CisgICAgICogIyNsb2dnaW5nLnByb3BlcnRpZXMKKyAgICAgKiBNYWlsSGFuZGxlckRlbW8uaGFuZGxlcnM9Y29tLnN1bi5tYWlsLnV0aWwubG9nZ2luZy5NYWlsSGFuZGxlcgorICAgICAqIGNvbS5zdW4ubWFpbC51dGlsLmxvZ2dpbmcuTWFpbEhhbmRsZXIuc3ViamVjdD1Cb2R5IGFuZCBhdHRhY2htZW50IGRlbW8KKyAgICAgKiBjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nLk1haWxIYW5kbGVyLmF0dGFjaG1lbnQuZm9ybWF0dGVycz1qYXZhLnV0aWwubG9nZ2luZy5YTUxGb3JtYXR0ZXIKKyAgICAgKiBjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nLk1haWxIYW5kbGVyLmF0dGFjaG1lbnQubmFtZXM9ZGF0YS54bWwKKyAgICAgKiAjIworICAgICAqIDwvY29kZT4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGluaXRTaW1wbGVBdHRhY2htZW50KCkgeworICAgICAgICBNYWlsSGFuZGxlciBoID0gbmV3IE1haWxIYW5kbGVyKCk7CisgICAgICAgIGguc2V0U3ViamVjdCgiQm9keSBhbmQgYXR0YWNobWVudCBkZW1vIik7CisgICAgICAgIGguc2V0QXR0YWNobWVudEZvcm1hdHRlcnMobmV3IFhNTEZvcm1hdHRlcigpKTsKKyAgICAgICAgaC5zZXRBdHRhY2htZW50TmFtZXMoImRhdGEueG1sIik7CisgICAgICAgIExPR0dFUi5hZGRIYW5kbGVyKGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEV4YW1wbGUgc2V0dXAgZm9yIHByaW9yaXR5IG1lc3NhZ2VzIGJ5IGxldmVsLiBJZiB0aGUgcHVzaCBsZXZlbCBpcworICAgICAqIHRyaWdnZXJlZCB0aGUgbWVzc2FnZSBpcyBoaWdoIHByaW9yaXR5LiBPdGhlcndpc2UsIG9uIGNsb3NlIGFueSByZW1haW5pbmcKKyAgICAgKiBtZXNzYWdlcyBhcmUgc2VudC4gICAgICA8Y29kZT4KKyAgICAgKiAjI2xvZ2dpbmcucHJvcGVydGllcworICAgICAqIE1haWxIYW5kbGVyRGVtby5oYW5kbGVycz1jb20uc3VuLm1haWwudXRpbC5sb2dnaW5nLk1haWxIYW5kbGVyCisgICAgICogY29tLnN1bi5tYWlsLnV0aWwubG9nZ2luZy5NYWlsSGFuZGxlci5zdWJqZWN0PVB1c2ggbGV2ZWwgZGVtbworICAgICAqIGNvbS5zdW4ubWFpbC51dGlsLmxvZ2dpbmcuTWFpbEhhbmRsZXIucHVzaExldmVsPVdBUk5JTkcKKyAgICAgKiAjIworICAgICAqIDwvY29kZT4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGluaXRXaXRoUHVzaExldmVsKCkgeworICAgICAgICBNYWlsSGFuZGxlciBoID0gbmV3IE1haWxIYW5kbGVyKCk7CisgICAgICAgIGguc2V0U3ViamVjdCgiUHVzaCBsZXZlbCBkZW1vIik7CisgICAgICAgIGguc2V0UHVzaExldmVsKExldmVsLldBUk5JTkcpOworICAgICAgICBMT0dHRVIuYWRkSGFuZGxlcihoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFeGFtcGxlIGZvciBwcmlvcml0eSBtZXNzYWdlcyBieSBnZW5lcmF0aW9uIHJhdGUuIElmIHRoZSBwdXNoIGZpbHRlciBpcworICAgICAqIHRyaWdnZXJlZCB0aGUgbWVzc2FnZSBpcyBoaWdoIHByaW9yaXR5LiBPdGhlcndpc2UsIG9uIGNsb3NlIGFueSByZW1haW5pbmcKKyAgICAgKiBtZXNzYWdlcyBhcmUgc2VudC4gSWYgdGhlIGNhcGFjaXR5IGlzIHNldCB0byB0aGUgICAgICA8Y29kZT4KKyAgICAgKiAjI2xvZ2dpbmcucHJvcGVydGllcworICAgICAqIE1haWxIYW5kbGVyRGVtby5oYW5kbGVycz1jb20uc3VuLm1haWwudXRpbC5sb2dnaW5nLk1haWxIYW5kbGVyCisgICAgICogY29tLnN1bi5tYWlsLnV0aWwubG9nZ2luZy5NYWlsSGFuZGxlci5zdWJqZWN0PVB1c2ggZmlsdGVyIGRlbW8KKyAgICAgKiBjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nLk1haWxIYW5kbGVyLnB1c2hMZXZlbD1BTEwKKyAgICAgKiBjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nLk1haWxIYW5kbGVyLnB1c2hGaWx0ZXI9Y29tLnN1bi5tYWlsLnV0aWwubG9nZ2luZy5EdXJhdGlvbkZpbHRlcgorICAgICAqIGNvbS5zdW4ubWFpbC51dGlsLmxvZ2dpbmcuRHVyYXRpb25GaWx0ZXIucmVjb3Jkcz0yCisgICAgICogY29tLnN1bi5tYWlsLnV0aWwubG9nZ2luZy5EdXJhdGlvbkZpbHRlci5kdXJhdGlvbj0xICogNjAgKiAxMDAwCisgICAgICogIyMKKyAgICAgKiA8L2NvZGU+CisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBpbml0V2l0aFB1c2hGaWx0ZXIoKSB7CisgICAgICAgIE1haWxIYW5kbGVyIGggPSBuZXcgTWFpbEhhbmRsZXIoKTsKKyAgICAgICAgaC5zZXRTdWJqZWN0KCJQdXNoIGZpbHRlciBkZW1vIik7CisgICAgICAgIGguc2V0UHVzaExldmVsKExldmVsLkFMTCk7CisgICAgICAgIGguc2V0UHVzaEZpbHRlcihuZXcgRHVyYXRpb25GaWx0ZXIoMiwgMUwgKiA2MEwgKiAxMDAwTCkpOworICAgICAgICBMT0dHRVIuYWRkSGFuZGxlcihoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFeGFtcGxlIGZvciBjaXJjdWxhciBidWZmZXIgYmVoYXZpb3IuIFRoZSBsZXZlbCwgcHVzaCBsZXZlbCwgYW5kIGNhcGFjaXR5CisgICAgICogYXJlIHNldCB0aGUgc2FtZSBzbyB0aGF0IHRoZSBtZW1vcnkgaGFuZGxlciBwdXNoIHJlc3VsdHMgaW4gYSBtYWlsCisgICAgICogaGFuZGxlciBwdXNoLiBBbGwgbWVzc2FnZXMgYXJlIGhpZ2ggcHJpb3JpdHkuIE9uIGNsb3NlIGFueSByZW1haW5pbmcKKyAgICAgKiByZWNvcmRzIGFyZSBkaXNjYXJkZWQgYmVjYXVzZSB0aGV5IG5ldmVyIHJlYWNoIHRoZSBtYWlsIGhhbmRsZXIuICAgICAgPGNvZGU+CisgICAgICogIyNsb2dnaW5nLnByb3BlcnRpZXMKKyAgICAgKiBNYWlsSGFuZGxlckRlbW8uaGFuZGxlcnM9amF2YS51dGlsLmxvZ2dpbmcuTWVtb3J5SGFuZGxlcgorICAgICAqIGphdmEudXRpbC5sb2dnaW5nLk1lbW9yeUhhbmRsZXIudGFyZ2V0PWNvbS5zdW4ubWFpbC51dGlsLmxvZ2dpbmcuTWFpbEhhbmRsZXIKKyAgICAgKiBjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nLk1haWxIYW5kbGVyLmxldmVsPUFMTAorICAgICAqIGphdmEudXRpbC5sb2dnaW5nLk1lbW9yeUhhbmRsZXIubGV2ZWw9QUxMCisgICAgICogamF2YS51dGlsLmxvZ2dpbmcuTWVtb3J5SGFuZGxlci5wdXNoPVdBUk5JTkcKKyAgICAgKiBjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nLk1haWxIYW5kbGVyLnN1YmplY3Q9UHVzaCBvbmx5IGRlbW8KKyAgICAgKiBjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nLk1haWxIYW5kbGVyLnB1c2hMZXZlbD1XQVJOSU5HCisgICAgICogIyMKKyAgICAgKiA8L2NvZGU+CisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBpbml0UHVzaE9ubHkoKSB7CisgICAgICAgIGZpbmFsIGludCBjYXBhY2l0eSA9IDM7CisgICAgICAgIGZpbmFsIExldmVsIHB1c2hMZXZlbCA9IExldmVsLldBUk5JTkc7CisgICAgICAgIGZpbmFsIE1haWxIYW5kbGVyIGggPSBuZXcgTWFpbEhhbmRsZXIoY2FwYWNpdHkpOworICAgICAgICBoLnNldFB1c2hMZXZlbChwdXNoTGV2ZWwpOworICAgICAgICBoLnNldFN1YmplY3QoIlB1c2ggb25seSBkZW1vIik7CisgICAgICAgIE1lbW9yeUhhbmRsZXIgbSA9IG5ldyBNZW1vcnlIYW5kbGVyKGgsIGNhcGFjaXR5LCBwdXNoTGV2ZWwpOworICAgICAgICBoLnNldExldmVsKG0uZ2V0TGV2ZWwoKSk7CisgICAgICAgIExPR0dFUi5hZGRIYW5kbGVyKG0pOworICAgICAgICBwdXNoT25seUhhbmRsZXIgPSBoOworICAgIH0KKworICAgIC8qKgorICAgICAqIEhvbGRzIG9uIHRvIHRoZSBwdXNoIG9ubHkgaGFuZGxlci4gT25seSBkZWNsYXJlZCBoZXJlIHRvIGFwcGx5IGZhbGxiYWNrCisgICAgICogc2V0dGluZ3MuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgSGFuZGxlciBwdXNoT25seUhhbmRsZXI7CisKKyAgICAvKioKKyAgICAgKiBFeGFtcGxlIGZvciBjaXJjdWxhciBidWZmZXIgYmVoYXZpb3IgYXMgbm9ybWFsIHByaW9yaXR5LiBUaGUgcHVzaCBsZXZlbCwKKyAgICAgKiBhbmQgY2FwYWNpdHkgYXJlIHNldCB0aGUgc2FtZSBzbyB0aGF0IHRoZSBtZW1vcnkgaGFuZGxlciBwdXNoIHJlc3VsdHMgaW4KKyAgICAgKiBhIG1haWwgaGFuZGxlciBwdXNoLiBBbGwgbWVzc2FnZXMgYXJlIG5vcm1hbCBwcmlvcml0eS4gT24gY2xvc2UgYW55CisgICAgICogcmVtYWluaW5nIHJlY29yZHMgYXJlIGRpc2NhcmRlZCBiZWNhdXNlIHRoZXkgbmV2ZXIgcmVhY2ggdGhlIG1haWwKKyAgICAgKiBoYW5kbGVyLiBVc2UgdGhlIExvZ01hbmFnZXIgY29uZmlnIG9wdGlvbiBvciBleHRlbmQgdGhlIE1lbW9yeUhhbmRsZXIgdG8KKyAgICAgKiBlbXVsYXRlIHRoaXMgYmVoYXZpb3IgdmlhIHRoZSBsb2dnaW5nLnByb3BlcnRpZXMuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBpbml0UHVzaE5vcm1hbCgpIHsKKyAgICAgICAgZmluYWwgaW50IGNhcGFjaXR5ID0gMzsKKyAgICAgICAgZmluYWwgTWFpbEhhbmRsZXIgaCA9IG5ldyBNYWlsSGFuZGxlcihjYXBhY2l0eSk7CisgICAgICAgIGguc2V0U3ViamVjdCgiUHVzaCBub3JtYWwgZGVtbyIpOworICAgICAgICBNZW1vcnlIYW5kbGVyIG0gPSBuZXcgTWVtb3J5SGFuZGxlcihoLCBjYXBhY2l0eSwgTGV2ZWwuV0FSTklORykgeworCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHB1c2goKSB7CisgICAgICAgICAgICAgICAgc3VwZXIucHVzaCgpOyAgLy9wdXNoIHRvIHRhcmdldC4KKyAgICAgICAgICAgICAgICBzdXBlci5mbHVzaCgpOyAvL21ha2UgdGhlIHRhcmdldCBzZW5kIHRoZSBlbWFpbC4KKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICAgICAgTE9HR0VSLmFkZEhhbmRsZXIobSk7CisgICAgICAgIHB1c2hOb3JtYWxIYW5kbGVyID0gaDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBIb2xkcyBvbiB0byB0aGUgcHVzaCBub3JtYWwgaGFuZGxlci4gT25seSBkZWNsYXJlZCBoZXJlIHRvIGFwcGx5IGZhbGxiYWNrCisgICAgICogc2V0dGluZ3MuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgSGFuZGxlciBwdXNoTm9ybWFsSGFuZGxlcjsKKworICAgIC8qKgorICAgICAqIEV4YW1wbGUgZm9yIHZhcmlvdXMga2luZHMgb2YgY3VzdG9tIHNvcnRpbmcsIGZvcm1hdHRpbmcsIGFuZCBmaWx0ZXJpbmcKKyAgICAgKiBmb3IgbXVsdGlwbGUgYXR0YWNobWVudCBtZXNzYWdlcy4gVGhlIHN1YmplY3Qgd2lsbCBjb250YWluIHRoZSBtb3N0CisgICAgICogc2V2ZXJlIHJlY29yZCBhbmQgYSBjb3VudCBvZiByZW1haW5pbmcgcmVjb3Jkcy4gVGhlIGxvZyByZWNvcmRzIGFyZQorICAgICAqIG9yZGVyZWQgZnJvbSBtb3N0IHNldmVyZSB0byBsZWFzdCBzZXZlcmUuIFRoZSBib2R5IHVzZXMgYSBjdXN0b20KKyAgICAgKiBmb3JtYXR0ZXIgdGhhdCBpbmNsdWRlcyBhIHN1bW1hcnkgYnkgZGF0ZSBhbmQgdGltZS4gVGhlIGF0dGFjaG1lbnQgdXNlCisgICAgICogWE1MIGFuZCBwbGFpbiB0ZXh0IGZvcm1hdHMuIEVhY2ggYXR0YWNobWVudCBoYXMgYSBkaWZmZXJlbnQgc2V0IG9mCisgICAgICogZmlsdGVyaW5nLiBUaGUgYXR0YWNobWVudCBuYW1lcyBhcmUgZ2VuZXJhdGVkIGZyb20gZWl0aGVyIGEgZml4ZWQgbmFtZSBvcgorICAgICAqIGFyZSBidWlsdCB1c2luZyB0aGUgbnVtYmVyIGFuZCB0eXBlIG9mIHRoZSByZWNvcmRzIGZvcm1hdHRlZC4gT24gY2xvc2UKKyAgICAgKiBhbnkgcmVtYWluaW5nIG1lc3NhZ2VzIGFyZSBzZW50LiBVc2UgdGhlIExvZ01hbmFnZXIgY29uZmlnIG9wdGlvbiBvcgorICAgICAqIGV4dGVuZCB0aGUgTWVtb3J5SGFuZGxlciB0byBlbXVsYXRlIHRoaXMgYmVoYXZpb3IgdmlhIHRoZQorICAgICAqIGxvZ2dpbmcucHJvcGVydGllcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGluaXRDdXN0b21BdHRhY2htZW50cygpIHsKKyAgICAgICAgTWFpbEhhbmRsZXIgaCA9IG5ldyBNYWlsSGFuZGxlcigpOworCisgICAgICAgIC8vU29ydCByZWNvcmRzIGJ5IHNldmVyaXR5IGtlZXBpbmcgdGhlIHNldmVyZSBtZXNzYWdlcyBhdCB0aGUgdG9wLgorICAgICAgICBoLnNldENvbXBhcmF0b3IoQ29sbGVjdGlvbnMucmV2ZXJzZU9yZGVyKG5ldyBTZXZlcml0eUNvbXBhcmF0b3IoKSkpOworCisgICAgICAgIC8vVXNlIHN1YmplY3QgdG8gcHJvdmlkZSBhIGhpbnQgYXMgdG8gd2hhdCBpcyBpbiB0aGUgZW1haWwuCisgICAgICAgIGguc2V0U3ViamVjdChuZXcgQ29sbGVjdG9yRm9ybWF0dGVyKCkpOworCisgICAgICAgIC8vTWFrZSB0aGUgYm9keSBnaXZlIGEgc2ltcGxlIHN1bW1hcnkgb2Ygd2hhdCBoYXBwZW5lZC4KKyAgICAgICAgaC5zZXRGb3JtYXR0ZXIobmV3IFN1bW1hcnlGb3JtYXR0ZXIoKSk7CisKKyAgICAgICAgLy9DcmVhdGUgMyBhdHRhY2htZW50cy4KKyAgICAgICAgaC5zZXRBdHRhY2htZW50Rm9ybWF0dGVycyhuZXcgWE1MRm9ybWF0dGVyKCksCisgICAgICAgICAgICAgICAgbmV3IFhNTEZvcm1hdHRlcigpLCBuZXcgU2ltcGxlRm9ybWF0dGVyKCkpOworCisgICAgICAgIC8vRmlsdGVyIGVhY2ggYXR0YWNobWVudCBkaWZmZXJlbnRseS4KKyAgICAgICAgaC5zZXRBdHRhY2htZW50RmlsdGVycyhudWxsLAorICAgICAgICAgICAgICAgIG5ldyBEdXJhdGlvbkZpbHRlcigzTCwgMTAwMEwpLAorICAgICAgICAgICAgICAgIG5ldyBEdXJhdGlvbkZpbHRlcigxTCwgMTVMICogNjBMICogMTAwMEwpKTsKKworICAgICAgICAvL0NyZWF0aW5nIHRoZSBhdHRhY2htZW50IG5hbWUgZm9ybWF0dGVycy4KKyAgICAgICAgaC5zZXRBdHRhY2htZW50TmFtZXMobmV3IENvbGxlY3RvckZvcm1hdHRlcigiYWxsLnhtbCIpLAorICAgICAgICAgICAgICAgIG5ldyBDb2xsZWN0b3JGb3JtYXR0ZXIoInszfSByZWNvcmRzIGFuZCB7NX0gZXJyb3JzLnhtbCIpLAorICAgICAgICAgICAgICAgIG5ldyBDb2xsZWN0b3JGb3JtYXR0ZXIoIns1LGNob2ljZSwwI25vIGVycm9yc3wxIzEgZXJyb3J8MTwiCisgICAgICAgICAgICAgICAgICAgICAgICArICJ7NSxudW1iZXIsaW50ZWdlcn0gZXJyb3JzfS50eHQiKSk7CisKKyAgICAgICAgTE9HR0VSLmFkZEhhbmRsZXIoaCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB1cCB0aGUgZGVtb3MgdGhhdCB3aWxsIHJ1bi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsIHRoZSBsaXN0IG9mIGFyZ3VtZW50cy4KKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgZGVidWcgaXMgb24uCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpbml0KExpc3Q8U3RyaW5nPiBsKSB7CisgICAgICAgIGwgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4obCk7CisgICAgICAgIFNlc3Npb24gc2Vzc2lvbiA9IFNlc3Npb24uZ2V0SW5zdGFuY2UoU3lzdGVtLmdldFByb3BlcnRpZXMoKSk7CisgICAgICAgIGJvb2xlYW4gYWxsID0gbC5yZW1vdmUoIi1hbGwiKSB8fCBsLmlzRW1wdHkoKTsKKyAgICAgICAgaWYgKGwucmVtb3ZlKCItYm9keSIpIHx8IGFsbCkgeworICAgICAgICAgICAgaW5pdEJvZHlPbmx5KCk7CisgICAgICAgIH0KKworICAgICAgICBpZiAobC5yZW1vdmUoIi1jdXN0b20iKSB8fCBhbGwpIHsKKyAgICAgICAgICAgIGluaXRDdXN0b21BdHRhY2htZW50cygpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGwucmVtb3ZlKCItbG93IikgfHwgYWxsKSB7CisgICAgICAgICAgICBpbml0TG93Q2FwYWNpdHkoKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChsLnJlbW92ZSgiLXB1c2hmaWx0ZXIiKSB8fCBhbGwpIHsKKyAgICAgICAgICAgIGluaXRXaXRoUHVzaEZpbHRlcigpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGwucmVtb3ZlKCItcHVzaGxldmVsIikgfHwgYWxsKSB7CisgICAgICAgICAgICBpbml0V2l0aFB1c2hMZXZlbCgpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGwucmVtb3ZlKCItcHVzaG5vcm1hbCIpIHx8IGFsbCkgeworICAgICAgICAgICAgaW5pdFB1c2hOb3JtYWwoKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChsLnJlbW92ZSgiLXB1c2hvbmx5IikgfHwgYWxsKSB7CisgICAgICAgICAgICBpbml0UHVzaE9ubHkoKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChsLnJlbW92ZSgiLXNpbXBsZSIpIHx8IGFsbCkgeworICAgICAgICAgICAgaW5pdFNpbXBsZUF0dGFjaG1lbnQoKTsKKyAgICAgICAgfQorCisgICAgICAgIGJvb2xlYW4gZmFsbGJhY2sgPSBhcHBseUZhbGxiYWNrU2V0dGluZ3MoKTsKKyAgICAgICAgYm9vbGVhbiBkZWJ1ZyA9IGwucmVtb3ZlKCItZGVidWciKSB8fCBzZXNzaW9uLmdldERlYnVnKCk7CisgICAgICAgIGlmIChkZWJ1ZykgeworICAgICAgICAgICAgY2hlY2tDb25maWcoQ0xBU1NfTkFNRSwgc2Vzc2lvbi5nZXREZWJ1Z091dCgpKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICghbC5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIExPR0dFUi5sb2coTGV2ZWwuU0VWRVJFLCAiVW5rbm93biBjb21tYW5kczogezB9IiwgbCk7CisgICAgICAgIH0KKworICAgICAgICBpZiAoZmFsbGJhY2spIHsKKyAgICAgICAgICAgIExPR0dFUi5pbmZvKCJDaGVjayB5b3VyIHVzZXIgdGVtcCBkaXIgZm9yIG91dHB1dC4iKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZGVidWc7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2UgYW5kIHJlbW92ZSBhbGwgaGFuZGxlcnMgYWRkZWQgdG8gdGhlIGNsYXNzIGxvZ2dlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGNsb3NlSGFuZGxlcnMoKSB7CisgICAgICAgIEhhbmRsZXJbXSBoYW5kbGVycyA9IExPR0dFUi5nZXRIYW5kbGVycygpOworICAgICAgICBmb3IgKEhhbmRsZXIgaCA6IGhhbmRsZXJzKSB7CisgICAgICAgICAgICBoLmNsb3NlKCk7CisgICAgICAgICAgICBMT0dHRVIucmVtb3ZlSGFuZGxlcihoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEFwcGx5IHNvbWUgZmFsbGJhY2sgc2V0dGluZ3MgaWYgbm8gY29uZmlndXJhdGlvbiBmaWxlIHdhcyBzcGVjaWZpZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgZmFsbGJhY2sgc2V0dGluZ3Mgd2VyZSBhcHBsaWVkLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gYXBwbHlGYWxsYmFja1NldHRpbmdzKCkgeworICAgICAgICBpZiAoZ2V0Q29uZmlnTG9jYXRpb24oKSA9PSBudWxsKSB7CisgICAgICAgICAgICBMT0dHRVIuc2V0TGV2ZWwoTGV2ZWwuQUxMKTsKKyAgICAgICAgICAgIEhhbmRsZXJbXSBoYW5kbGVycyA9IExPR0dFUi5nZXRIYW5kbGVycygpOworICAgICAgICAgICAgZm9yIChIYW5kbGVyIGggOiBoYW5kbGVycykgeworICAgICAgICAgICAgICAgIGZhbGxiYWNrU2V0dGluZ3MoaCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmYWxsYmFja1NldHRpbmdzKHB1c2hPbmx5SGFuZGxlcik7CisgICAgICAgICAgICBmYWxsYmFja1NldHRpbmdzKHB1c2hOb3JtYWxIYW5kbGVyKTsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21tb24gZmFsbGJhY2sgc2V0dGluZ3MgZm9yIGEgc2luZ2xlIGhhbmRsZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaCB0aGUgaGFuZGxlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGZhbGxiYWNrU2V0dGluZ3MoSGFuZGxlciBoKSB7CisgICAgICAgIGlmIChoICE9IG51bGwpIHsKKyAgICAgICAgICAgIGguc2V0RXJyb3JNYW5hZ2VyKG5ldyBGaWxlRXJyb3JNYW5hZ2VyKCkpOworICAgICAgICAgICAgaC5zZXRMZXZlbChMZXZlbC5BTEwpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgc3lzdGVtIHRlbXAgZGlyZWN0b3J5LgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgc3lzdGVtIHRlbXAgZGlyZWN0b3J5LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBnZXRUZW1wRGlyKCkgeworICAgICAgICByZXR1cm4gU3lzdGVtLmdldFByb3BlcnR5KCJqYXZhLmlvLnRtcGRpciIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGNvbmZpZ3VyYXRpb24gZmlsZSBvciBjbGFzcyBuYW1lLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgZmlsZSBuYW1lIG9yIGNsYXNzIG5hbWUuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGdldENvbmZpZ0xvY2F0aW9uKCkgeworICAgICAgICBTdHJpbmcgZmlsZSA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS51dGlsLmxvZ2dpbmcuY29uZmlnLmZpbGUiKTsKKyAgICAgICAgaWYgKGZpbGUgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS51dGlsLmxvZ2dpbmcuY29uZmlnLmNsYXNzIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZpbGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogTm8gb2JqZWN0cyBhcmUgYWxsb3dlZC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gYWx3YXlzLgorICAgICAqLworICAgIHByaXZhdGUgTWFpbEhhbmRsZXJEZW1vKCkgdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbigpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2xvZ2dpbmcvc3JjL21haW4vamF2YS9SRUFETUUudHh0IGIvbG9nZ2luZy9zcmMvbWFpbi9qYXZhL1JFQURNRS50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzZiN2FkZAotLS0gL2Rldi9udWxsCisrKyBiL2xvZ2dpbmcvc3JjL21haW4vamF2YS9SRUFETUUudHh0CkBAIC0wLDAgKzEsMTAzIEBACitMb2dnaW5nIERlbW8KKy0tLS0tLS0tLS0tLQorCitOb3RlczoKKz09PT09PQorCitUaGlzIHNob3VsZCBub3QgYmUgdGFrZW4gYXMgYSBkZW1vIG9mIGhvdyB0byB1c2UgdGhlIGxvZ2dpbmcgQVBJLCBidXQKK3JhdGhlciBob3cgdG8gdXNlIHRoZSBmZWF0dXJlcyBvZiB0aGUgTWFpbEhhbmRsZXIuCisKK1RvIHJ1biB0aGUgZGVtbzoKKz09PT09PT09PT09PT09PT0KKworICAgIDEuICBUaGUgZGVtbyByZXF1aXJlcyBKYXZhIHZlcnNpb24gMS41IG9yIG5ld2VyLgorCVdlICpzdHJvbmdseSogZW5jb3VyYWdlIHlvdSB0byB1c2UgdGhlIGxhdGVzdCB2ZXJzaW9uIG9mIEoyU0UsCisJd2hpY2ggeW91IGNhbiBkb3dubG9hZCBmcm9tCisgICAgICAgIGh0dHA6Ly93d3cub3JhY2xlLmNvbS90ZWNobmV0d29yay9qYXZhL2phdmFzZS9kb3dubG9hZHMuCisKKyAgICAyLiAgU2V0IHlvdXIgQ0xBU1NQQVRIIHRvIGluY2x1ZGUgdGhlICJtYWlsLmphciIgYW5kICJhY3RpdmF0aW9uLmphciIuCisKKwlGb3IgSkRLIDEuMSBvbiBVTklYOgorCisJZXhwb3J0IENMQVNTUEFUSD0vdS9tZS9kb3dubG9hZC9tYWlsLmphcjovdS9tZS9kb3dubG9hZC9hY3RpdmF0aW9uLmphci4KKworCUZvciBKREsgMS4yIGFuZCBuZXdlciBvbiBVTklYOgorCisJZXhwb3J0IENMQVNTUEFUSD0vdS9tZS9kb3dubG9hZC9tYWlsLmphcjovdS9tZS9kb3dubG9hZC9hY3RpdmF0aW9uLmphcjouCisKKyAgICAzLiAgR28gdG8gdGhlIGRlbW8vbG9nZ2luZyBkaXJlY3RvcnkKKworICAgIDQuICBDb21waWxlIGFsbCB0aGUgZmlsZXMgdXNpbmcgeW91ciBKYXZhIGNvbXBpbGVyLiAgRm9yIGV4YW1wbGU6CisKKwkgIGphdmFjICouamF2YQorCisgICAgNS4gIE5vdCByZXF1aXJlZCBidXQsIHlvdSBzaG91bGQgZWRpdCB0aGUgbWFpbGRlbW8ucHJvcGVydGllcyBhbmQgY2hhbmdlIHRoZQorICAgICAgICBtYWlsLnRvIGFkZHJlc3MgYW5kIG1haWwuaG9zdCB0byB5b3VyIG1haWwgc2VydmVyIGlwIG9yIGhvc3QgbmFtZS4KKworICAgIDYuICBSdW4gdGhlIGRlbW8uIEZvciBleGFtcGxlOgorCisJICBqYXZhIC1EbWFpbC5kZWJ1Zz1mYWxzZSAtRGphdmEudXRpbC5sb2dnaW5nLmNvbmZpZy5maWxlPS91L21lL2Rvd25sb2FkL2phdmFtYWlsL2RlbW8vbWFpbGRlbW8ucHJvcGVydGllcyBNYWlsSGFuZGxlckRlbW8KKworCisKK092ZXJ2aWV3IG9mIHRoZSBDbGFzc2VzCis9PT09PT09PT09PT09PT09PT09PT09PQorCitNYWluIENsYXNzZXM6CisKKwlNYWlsSGFuZGxlckRlbW8gICAgICAgPSBUaGUgbWFpbiBtZXRob2QgY3JlYXRlcyBsb2cgbWVzc2FnZXMKKwkJCQlmb3IgdGhlIE1haWxIYW5kZXIgdG8gY2FwdHVyZS4gIFRoZQorCQkJCWluaXRYWFggbWV0aG9kcyBkZXNjcmliZSBzb21lIG9mIHRoZQorCQkJCWNvbW1vbiBzZXR1cCBjb2RlIGZvciBkaWZmZXJlbnQgdHlwZXMKKwkJCQlvZiBlbWFpbCBtZXNzYWdlcy4KKworICAgICAgICAgICAgICAgICAgICAgICBVc2FnZTogamF2YSBNYWlsSGFuZGxlckRlbW8gW1stYWxsXSB8IFstYm9keV0gfCBbLWRlYnVnXQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFstbG93XSB8IFstc2ltcGxlXSB8IFstcHVzaGxldmVsXQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFstcHVzaGZpbHRlcl0gfCBbLXB1c2hub3JtYWxdfCBbLXB1c2hvbmx5XV0KKworICAgICAgICAgICAgICAgICAgICAgICAgT3B0aW9uczoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAtYWxsICAgIDogRXhlY3V0ZSBhbGwgZGVtb3MuCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLWJvZHkgICA6IEFuIGVtYWlsIHdpdGggYWxsIHJlY29yZHMgYW5kIG9ubHkgYSBib2R5LgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC1jdXN0b20gOiBBbiBlbWFpbCB3aXRoIGF0dGFjaG1lbnRzIGFuZCBkeW5hbWljIG5hbWVzLgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC1kZWJ1ZyAgOiBPdXRwdXQgYmFzaWMgZGVidWcgaW5mb3JtYXRpb24gYWJvdXQgdGhlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSlZNIGFuZCBsb2cgY29uZmlndXJhdGlvbi4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAtbG93ICAgIDogR2VuZXJhdGVzIG11bHRpcGxlIGVtYWlscyBkdWUgdG8gbG93CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FwYWNpdHkuCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLXNpbXBsZSA6IEFuIGVtYWlsIHdpdGggYWxsIHJlY29yZHMgd2l0aCBib2R5IGFuZCBhbgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dGFjaG1lbnQuCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLXB1c2hsZXZlbAk6IEdlbmVyYXRlcyBoaWdoIHByaW9yaXR5IGVtYWlscyB3aGVuCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBwdXNoIGxldmVsIGlzIHRyaWdnZXJlZCBhbmQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9ybWFsIHByaW9yaXR5IHdoZW4gZmx1c2hlZC4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAtcHVzaEZpbHRlcgk6IEdlbmVyYXRlcyBoaWdoIHByaW9yaXR5IGVtYWlscyB3aGVuCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBwdXNoIGxldmVsIGFuZCB0aGUgcHVzaCBmaWx0ZXIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXMgdHJpZ2dlcmVkIGFuZCBub3JtYWwgcHJpb3JpdHkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW1haWxzIHdoZW4gZmx1c2hlZC4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAtcHVzaG5vcm1hbAk6IEdlbmVyYXRlcyBtdWx0aXBsZSBlbWFpbHMgd2hlbiB0aGUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVtb3J5SGFuZGxlciBwdXNoIGxldmVsIGlzCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyaWdnZXJlZC4gIEFsbCBnZW5lcmF0ZWQgZW1haWwgYXJlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbnQgYXMgbm9ybWFsIHByaW9yaXR5LgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC1wdXNob25seQk6IEdlbmVyYXRlcyBtdWx0aXBsZSBlbWFpbHMgd2hlbiB0aGUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVtb3J5SGFuZGxlciBwdXNoIGxldmVsIGlzCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyaWdnZXJlZC4gIEdlbmVyYXRlcyBoaWdoIHByaW9yaXR5CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVtYWlscyB3aGVuIHRoZSBwdXNoIGxldmVsIGlzCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyaWdnZXJlZCBhbmQgbm9ybWFsIHByaW9yaXR5IHdoZW4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmx1c2hlZC4KKworCisJRmlsZUVycm9yTWFuYWdlciAgICAgID0gVXNlZCB0byBzdG9yZSBlbWFpbCBtZXNzYWdlcyB0byB0aGUKKwkJCQlsb2NhbCBmaWxlIHN5c3RlbSB3aGVuIG1haWwgdHJhbnNwb3J0CisJCQkJZmFpbHMuICBUaGlzIGlzIGluc3RhbGxlZCBhcyBhCisJCQkJZmFsbGJhY2sgaW4gY2FzZSB0aGUgbG9nZ2luZyBjb25maWcgaXMKKwkJCQlub3Qgc3BlY2lmaWVkLgorCisJU3VtbWFyeUZvcm1hdHRlciAgICAgID0gQW4gZXhhbXBsZSBjb21wYWN0IGZvcm1hdHRlciB3aXRoIHN1bW1hcnkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIHVzZSB3aXRoIHRoZSBib2R5IG9mIGFuIGVtYWlsIG1lc3NhZ2UuCisKK1N1cHBvcnQgZmlsZXM6CisKKwltYWlsZGVtby5wcm9wZXJ0aWVzICAgPSBBIHNhbXBsZSBMb2dNYW5hZ2VyIHByb3BlcnRpZXMgZmlsZSBmb3IKKwkJCQl0aGUgTWFpbEhhbmRsZXJEZW1vLgorCisJbWFpbGRlbW8ucG9saWN5ICAgICAgID0gQSBzYW1wbGUgc2VjdXJpdHkgcG9saWN5IGZpbGUgdG8gdXNlIHdpdGgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIE1haWxIYW5kbGVyRGVtby4gIFRoaXMgY2FuIGJlIHVzZWQgdG8KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5hYmxlIHNlY3VyaXR5IHRyYWNpbmcuCmRpZmYgLS1naXQgYS9sb2dnaW5nL3NyYy9tYWluL2phdmEvU3VtbWFyeUZvcm1hdHRlci5qYXZhIGIvbG9nZ2luZy9zcmMvbWFpbi9qYXZhL1N1bW1hcnlGb3JtYXR0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iODIxMzY0Ci0tLSAvZGV2L251bGwKKysrIGIvbG9nZ2luZy9zcmMvbWFpbi9qYXZhL1N1bW1hcnlGb3JtYXR0ZXIuamF2YQpAQCAtMCwwICsxLDgwIEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDA5LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKiBDb3B5cmlnaHQgKGMpIDIwMDksIDIwMTggSmFzb24gTWVocmVucy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorICovCisKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nLkNvbGxlY3RvckZvcm1hdHRlcjsKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nLkNvbXBhY3RGb3JtYXR0ZXI7CitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuRm9ybWF0dGVyOworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkhhbmRsZXI7CitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTG9nUmVjb3JkOworCisvKioKKyAqIEEgY29tcGFjdCBmb3JtYXR0ZXIgdXNlZCB0byBzdW1tYXJpemUgYW4gZXJyb3IgcmVwb3J0LgorICoKKyAqIEBhdXRob3IgSmFzb24gTWVocmVucworICovCitwdWJsaWMgZmluYWwgY2xhc3MgU3VtbWFyeUZvcm1hdHRlciBleHRlbmRzIEZvcm1hdHRlciB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbGluZSBmb3JtYXR0ZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBDb21wYWN0Rm9ybWF0dGVyIGZvcm1hdDsKKyAgICAvKioKKyAgICAgKiBUaGUgZm9vdGVyIGZvcm1hdHRlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIENvbGxlY3RvckZvcm1hdHRlciBmb290ZXI7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIHRoZSBmb3JtYXR0ZXIuCisgICAgICovCisgICAgcHVibGljIFN1bW1hcnlGb3JtYXR0ZXIoKSB7CisgICAgICAgIGZvcm1hdCA9IG5ldyBDb21wYWN0Rm9ybWF0dGVyKCJbJTQkc11cdCU1JHMgJTYkcyVuIik7CisgICAgICAgIGZvb3RlciA9IG5ldyBDb2xsZWN0b3JGb3JtYXR0ZXIoIlxuVGhlc2UgezN9IG1lc3NhZ2VzIG9jY3VycmVkIGJldHdlZW4gIgorICAgICAgICAgICAgICAgICsgIns3LHRpbWUsRUVFLCBNTU0gZGQgSEg6bW06c3M6UyBaWlogeXl5eX0gYW5kICIKKyAgICAgICAgICAgICAgICArICJ7OCx0aW1lLEVFRSwgTU1NIGRkIEhIOm1tOnNzOlMgWlpaIHl5eXl9XG4iLCBmb3JtYXQsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGhlYWRlciBpbmZvcm1hdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBoIHRoZSBoYW5kbGVyIG9yIG51bGwuCisgICAgICogQHJldHVybiB0aGUgaGVhZGVyLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0SGVhZChIYW5kbGVyIGgpIHsKKyAgICAgICAgZm9vdGVyLmdldEhlYWQoaCk7CisgICAgICAgIHJldHVybiBmb3JtYXQuZ2V0SGVhZChoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGb3JtYXRzIHRoZSBnaXZlbiByZWNvcmQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVjb3JkIHRoZSBsb2cgcmVjb3JkLgorICAgICAqIEByZXR1cm4gdGhlIGZvcm1hdHRlZCByZWNvcmQuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiByZWNvcmQgaXMgbnVsbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGZvcm1hdChMb2dSZWNvcmQgcmVjb3JkKSB7CisgICAgICAgIFN0cmluZyBkYXRhID0gZm9ybWF0LmZvcm1hdChyZWNvcmQpOworICAgICAgICBmb290ZXIuZm9ybWF0KHJlY29yZCk7IC8vVHJhY2sgcmVjb3JkIHRpbWVzIGZvciBmb290ZXIuCisgICAgICAgIHJldHVybiBkYXRhOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYW5kIHJlc2V0cyB0aGUgZm9vdGVyIGluZm9ybWF0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIGggdGhlIGhhbmRsZXIgb3IgbnVsbC4KKyAgICAgKiBAcmV0dXJuIHRoZSBmb290ZXIuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXRUYWlsKEhhbmRsZXIgaCkgeworICAgICAgICBmb3JtYXQuZ2V0VGFpbChoKTsKKyAgICAgICAgcmV0dXJuIGZvb3Rlci5nZXRUYWlsKGgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL2xvZ2dpbmcvc3JjL21haW4vamF2YS9tYWlsZGVtby5wb2xpY3kgYi9sb2dnaW5nL3NyYy9tYWluL2phdmEvbWFpbGRlbW8ucG9saWN5Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ3ZDc5ODAKLS0tIC9kZXYvbnVsbAorKysgYi9sb2dnaW5nL3NyYy9tYWluL2phdmEvbWFpbGRlbW8ucG9saWN5CkBAIC0wLDAgKzEsMTkgQEAKKy8qDQorICogQ29weXJpZ2h0IChjKSAyMDE0LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQorICogQ29weXJpZ2h0IChjKSAyMDE0LCAyMDE4IEphc29uIE1laHJlbnMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuDQorICoNCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUNCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBEaXN0cmlidXRpb24gTGljZW5zZSB2LiAxLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdA0KKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvb3JnL2RvY3VtZW50cy9lZGwtdjEwLnBocC4NCisgKg0KKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBCU0QtMy1DbGF1c2UNCisgKi8NCitncmFudCB7DQorICBwZXJtaXNzaW9uIGphdmEudXRpbC5sb2dnaW5nLkxvZ2dpbmdQZXJtaXNzaW9uICJjb250cm9sIjsNCisgIHBlcm1pc3Npb24gamF2YS51dGlsLlByb3BlcnR5UGVybWlzc2lvbiAiKiIsICJyZWFkLCB3cml0ZSI7DQorICBwZXJtaXNzaW9uIGphdmEubmV0LlNvY2tldFBlcm1pc3Npb24gIioiLCAicmVzb2x2ZSwgY29ubmVjdCI7DQorICBwZXJtaXNzaW9uIGphdmEubGFuZy5SdW50aW1lUGVybWlzc2lvbiAiYWNjZXNzQ2xhc3NJblBhY2thZ2Uuc3VuLnV0aWwubG9nZ2luZy5yZXNvdXJjZXMiOw0KKyAgcGVybWlzc2lvbiBqYXZhLmlvLkZpbGVQZXJtaXNzaW9uICI8PEFMTCBGSUxFUz4+IiwgInJlYWQsIHdyaXRlIjsNCisgIHBlcm1pc3Npb24gamF2YS5sYW5nLlJ1bnRpbWVQZXJtaXNzaW9uICJnZXRDbGFzc0xvYWRlciI7DQorfTsNCisNCmRpZmYgLS1naXQgYS9sb2dnaW5nL3NyYy9tYWluL2phdmEvbWFpbGRlbW8ucHJvcGVydGllcyBiL2xvZ2dpbmcvc3JjL21haW4vamF2YS9tYWlsZGVtby5wcm9wZXJ0aWVzCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMxNGEwNWEKLS0tIC9kZXYvbnVsbAorKysgYi9sb2dnaW5nL3NyYy9tYWluL2phdmEvbWFpbGRlbW8ucHJvcGVydGllcwpAQCAtMCwwICsxLDUxIEBACisjDQorIyBDb3B5cmlnaHQgKGMpIDIwMDksIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCisjIENvcHlyaWdodCAoYykgMjAwOSwgMjAxOCBKYXNvbiBNZWhyZW5zLiBBbGwgUmlnaHRzIFJlc2VydmVkLg0KKyMNCisjIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQ0KKyMgdGVybXMgb2YgdGhlIEVjbGlwc2UgRGlzdHJpYnV0aW9uIExpY2Vuc2Ugdi4gMS4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQNCisjIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvb3JnL2RvY3VtZW50cy9lZGwtdjEwLnBocC4NCisjDQorIyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQlNELTMtQ2xhdXNlDQorDQorDQorDQorDQorIyBUaGlzIGNhbiBiZSB1c2VkIGJ5IHNldHRpbmcgdGhlIHN5c3RlbSBwcm9wZXJ0eQ0KKyMgLURqYXZhLnV0aWwubG9nZ2luZy5jb25maWcuZmlsZT1wYXRoIHRvIHRoaXMgZmlsZQ0KKw0KKyMgVGFrZW4gZnJvbSB0aGUgSkRLIGRlZmF1bHRzLg0KK2hhbmRsZXJzPSBqYXZhLnV0aWwubG9nZ2luZy5Db25zb2xlSGFuZGxlcg0KKy5sZXZlbD0gSU5GTw0KK2phdmEudXRpbC5sb2dnaW5nLkNvbnNvbGVIYW5kbGVyLmxldmVsID0gSU5GTw0KK2phdmEudXRpbC5sb2dnaW5nLkNvbnNvbGVIYW5kbGVyLmZvcm1hdHRlciA9IGphdmEudXRpbC5sb2dnaW5nLlNpbXBsZUZvcm1hdHRlcg0KKw0KKw0KKyMgU2V0IHRoZSBtYWlsIGhhbmRsZXIgZGVtbyBsb2dnZXIgbGV2ZWwNCitNYWlsSGFuZGxlckRlbW8ubGV2ZWwgPSBBTEwNCisNCisjIENvbmZpZ3VyZSB0aGUgTWFpbEhhbmRsZXIuDQorY29tLnN1bi5tYWlsLnV0aWwubG9nZ2luZy5NYWlsSGFuZGxlci5sZXZlbCA9IEFMTA0KK2NvbS5zdW4ubWFpbC51dGlsLmxvZ2dpbmcuTWFpbEhhbmRsZXIubWFpbC5ob3N0ID0gbXktbWFpbC1zZXJ2ZXINCitjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nLk1haWxIYW5kbGVyLm1haWwuZnJvbSA9IG1lQGV4YW1wbGUuY29tDQorY29tLnN1bi5tYWlsLnV0aWwubG9nZ2luZy5NYWlsSGFuZGxlci5tYWlsLnRvID0gbWVAZXhhbXBsZS5jb20NCitjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nLk1haWxIYW5kbGVyLnZlcmlmeSA9IGxvY2FsDQorDQorIyBBZGQgYXR0YWNobWVudHMgaWYgbmVlZGVkLg0KKyNjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nLk1haWxIYW5kbGVyLmF0dGFjaG1lbnQuZm9ybWF0dGVycyA9IGphdmEudXRpbC5sb2dnaW5nLlNpbXBsZUZvcm1hdHRlciwgamF2YS51dGlsLmxvZ2dpbmcuWE1MRm9ybWF0dGVyDQorDQorIyBObyBmaWx0ZXJzLg0KKyNjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nLk1haWxIYW5kbGVyLmF0dGFjaG1lbnQuZmlsdGVycyA9IG51bGwsIG51bGwNCisNCisjIEZvcm1hdHRlciBjbGFzcyBuYW1lIG9yIHN0cmluZ3MuDQorI2NvbS5zdW4ubWFpbC51dGlsLmxvZ2dpbmcuTWFpbEhhbmRsZXIuYXR0YWNobWVudC5uYW1lcyA9IHNpbXBsZS50eHQsIGVycm9yLnhtbA0KKw0KKw0KKyMgU3RvcmUgbWVzc2FnZXMgb24gZXJyb3IgYnkgaW5zdGFsbGluZyB0aGUgRmlsZUVycm9yTWFuYWdlciAoZGVtbyBjb2RlKS4NCitjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nLk1haWxIYW5kbGVyLmVycm9yTWFuYWdlciA9IEZpbGVFcnJvck1hbmFnZXINCisNCisjIENvbmZpZ3VyZSB0aGUgRmlsZUVycm9yTWFuYWdlciBmb3IgZGVtbyAobm90IHJlcXVpcmVkKS4NCisjIEZpbGVFcnJvck1hbmFnZXIucGF0dGVybiA9IHBhdGgtdG8tZGlyDQorDQorIyBEZWJ1ZyBtYWlsIHRyYW5zcG9ydCBpc3N1ZXMuDQorbWFpbC5kZWJ1ZyA9IGZhbHNlDQpkaWZmIC0tZ2l0IGEvbWFpbC5zaWcgYi9tYWlsLnNpZwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mZGRkYjMzCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC5zaWcKQEAgLTAsMCArMSwxNDUxIEBACisjU2lnbmF0dXJlIGZpbGUgdjQuMworI1ZlcnNpb24gCisKK0NMU1MgcHVibGljIGFic3RyYWN0IGphdmF4Lm1haWwuQWRkcmVzcworY29ucyBwdWJsaWMgPGluaXQ+KCkKK2ludGYgamF2YS5pby5TZXJpYWxpemFibGUKK21ldGggcHVibGljIGFic3RyYWN0IGJvb2xlYW4gZXF1YWxzKGphdmEubGFuZy5PYmplY3QpCittZXRoIHB1YmxpYyBhYnN0cmFjdCBqYXZhLmxhbmcuU3RyaW5nIGdldFR5cGUoKQorbWV0aCBwdWJsaWMgYWJzdHJhY3QgamF2YS5sYW5nLlN0cmluZyB0b1N0cmluZygpCitzdXByIGphdmEubGFuZy5PYmplY3QKK2hmZHMgc2VyaWFsVmVyc2lvblVJRAorCitDTFNTIHB1YmxpYyBqYXZheC5tYWlsLkF1dGhlbnRpY2F0aW9uRmFpbGVkRXhjZXB0aW9uCitjb25zIHB1YmxpYyA8aW5pdD4oKQorY29ucyBwdWJsaWMgPGluaXQ+KGphdmEubGFuZy5TdHJpbmcpCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YS5sYW5nLlN0cmluZyxqYXZhLmxhbmcuRXhjZXB0aW9uKQorc3VwciBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgoraGZkcyBzZXJpYWxWZXJzaW9uVUlECisKK0NMU1MgcHVibGljIGFic3RyYWN0IGphdmF4Lm1haWwuQXV0aGVudGljYXRvcgorY29ucyBwdWJsaWMgPGluaXQ+KCkKK21ldGggcHJvdGVjdGVkIGZpbmFsIGludCBnZXRSZXF1ZXN0aW5nUG9ydCgpCittZXRoIHByb3RlY3RlZCBmaW5hbCBqYXZhLmxhbmcuU3RyaW5nIGdldERlZmF1bHRVc2VyTmFtZSgpCittZXRoIHByb3RlY3RlZCBmaW5hbCBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcXVlc3RpbmdQcm9tcHQoKQorbWV0aCBwcm90ZWN0ZWQgZmluYWwgamF2YS5sYW5nLlN0cmluZyBnZXRSZXF1ZXN0aW5nUHJvdG9jb2woKQorbWV0aCBwcm90ZWN0ZWQgZmluYWwgamF2YS5uZXQuSW5ldEFkZHJlc3MgZ2V0UmVxdWVzdGluZ1NpdGUoKQorbWV0aCBwcm90ZWN0ZWQgamF2YXgubWFpbC5QYXNzd29yZEF1dGhlbnRpY2F0aW9uIGdldFBhc3N3b3JkQXV0aGVudGljYXRpb24oKQorc3VwciBqYXZhLmxhbmcuT2JqZWN0CitoZmRzIHJlcXVlc3RpbmdQb3J0LHJlcXVlc3RpbmdQcm9tcHQscmVxdWVzdGluZ1Byb3RvY29sLHJlcXVlc3RpbmdTaXRlLHJlcXVlc3RpbmdVc2VyTmFtZQorCitDTFNTIHB1YmxpYyBhYnN0cmFjdCBqYXZheC5tYWlsLkJvZHlQYXJ0Citjb25zIHB1YmxpYyA8aW5pdD4oKQorZmxkIHByb3RlY3RlZCBqYXZheC5tYWlsLk11bHRpcGFydCBwYXJlbnQKK2ludGYgamF2YXgubWFpbC5QYXJ0CittZXRoIHB1YmxpYyBqYXZheC5tYWlsLk11bHRpcGFydCBnZXRQYXJlbnQoKQorc3VwciBqYXZhLmxhbmcuT2JqZWN0CisKK0NMU1MgcHVibGljIGFic3RyYWN0IGludGVyZmFjZSBqYXZheC5tYWlsLkVuY29kaW5nQXdhcmUKK21ldGggcHVibGljIGFic3RyYWN0IGphdmEubGFuZy5TdHJpbmcgZ2V0RW5jb2RpbmcoKQorCitDTFNTIHB1YmxpYyBqYXZheC5tYWlsLkZldGNoUHJvZmlsZQorY29ucyBwdWJsaWMgPGluaXQ+KCkKK2lubnIgcHVibGljIHN0YXRpYyBJdGVtCittZXRoIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKGphdmEubGFuZy5TdHJpbmcpCittZXRoIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKGphdmF4Lm1haWwuRmV0Y2hQcm9maWxlJEl0ZW0pCittZXRoIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nW10gZ2V0SGVhZGVyTmFtZXMoKQorbWV0aCBwdWJsaWMgamF2YXgubWFpbC5GZXRjaFByb2ZpbGUkSXRlbVtdIGdldEl0ZW1zKCkKK21ldGggcHVibGljIHZvaWQgYWRkKGphdmEubGFuZy5TdHJpbmcpCittZXRoIHB1YmxpYyB2b2lkIGFkZChqYXZheC5tYWlsLkZldGNoUHJvZmlsZSRJdGVtKQorc3VwciBqYXZhLmxhbmcuT2JqZWN0CitoZmRzIGhlYWRlcnMsc3BlY2lhbHMKKworQ0xTUyBwdWJsaWMgc3RhdGljIGphdmF4Lm1haWwuRmV0Y2hQcm9maWxlJEl0ZW0KKyBvdXRlciBqYXZheC5tYWlsLkZldGNoUHJvZmlsZQorY29ucyBwcm90ZWN0ZWQgPGluaXQ+KGphdmEubGFuZy5TdHJpbmcpCitmbGQgcHVibGljIGZpbmFsIHN0YXRpYyBqYXZheC5tYWlsLkZldGNoUHJvZmlsZSRJdGVtIENPTlRFTlRfSU5GTworZmxkIHB1YmxpYyBmaW5hbCBzdGF0aWMgamF2YXgubWFpbC5GZXRjaFByb2ZpbGUkSXRlbSBFTlZFTE9QRQorZmxkIHB1YmxpYyBmaW5hbCBzdGF0aWMgamF2YXgubWFpbC5GZXRjaFByb2ZpbGUkSXRlbSBGTEFHUworZmxkIHB1YmxpYyBmaW5hbCBzdGF0aWMgamF2YXgubWFpbC5GZXRjaFByb2ZpbGUkSXRlbSBTSVpFCittZXRoIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIHRvU3RyaW5nKCkKK3N1cHIgamF2YS5sYW5nLk9iamVjdAoraGZkcyBuYW1lCisKK0NMU1MgcHVibGljIGphdmF4Lm1haWwuRmxhZ3MKK2NvbnMgcHVibGljIDxpbml0PigpCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YS5sYW5nLlN0cmluZykKK2NvbnMgcHVibGljIDxpbml0PihqYXZheC5tYWlsLkZsYWdzJEZsYWcpCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YXgubWFpbC5GbGFncykKK2lubnIgcHVibGljIGZpbmFsIHN0YXRpYyBGbGFnCitpbnRmIGphdmEuaW8uU2VyaWFsaXphYmxlCitpbnRmIGphdmEubGFuZy5DbG9uZWFibGUKK21ldGggcHVibGljIGJvb2xlYW4gY29udGFpbnMoamF2YS5sYW5nLlN0cmluZykKK21ldGggcHVibGljIGJvb2xlYW4gY29udGFpbnMoamF2YXgubWFpbC5GbGFncyRGbGFnKQorbWV0aCBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhqYXZheC5tYWlsLkZsYWdzKQorbWV0aCBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoamF2YS5sYW5nLk9iamVjdCkKK21ldGggcHVibGljIGJvb2xlYW4gcmV0YWluQWxsKGphdmF4Lm1haWwuRmxhZ3MpCittZXRoIHB1YmxpYyBpbnQgaGFzaENvZGUoKQorbWV0aCBwdWJsaWMgamF2YS5sYW5nLk9iamVjdCBjbG9uZSgpCittZXRoIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIHRvU3RyaW5nKCkKK21ldGggcHVibGljIGphdmEubGFuZy5TdHJpbmdbXSBnZXRVc2VyRmxhZ3MoKQorbWV0aCBwdWJsaWMgamF2YXgubWFpbC5GbGFncyRGbGFnW10gZ2V0U3lzdGVtRmxhZ3MoKQorbWV0aCBwdWJsaWMgdm9pZCBhZGQoamF2YS5sYW5nLlN0cmluZykKK21ldGggcHVibGljIHZvaWQgYWRkKGphdmF4Lm1haWwuRmxhZ3MkRmxhZykKK21ldGggcHVibGljIHZvaWQgYWRkKGphdmF4Lm1haWwuRmxhZ3MpCittZXRoIHB1YmxpYyB2b2lkIGNsZWFyU3lzdGVtRmxhZ3MoKQorbWV0aCBwdWJsaWMgdm9pZCBjbGVhclVzZXJGbGFncygpCittZXRoIHB1YmxpYyB2b2lkIHJlbW92ZShqYXZhLmxhbmcuU3RyaW5nKQorbWV0aCBwdWJsaWMgdm9pZCByZW1vdmUoamF2YXgubWFpbC5GbGFncyRGbGFnKQorbWV0aCBwdWJsaWMgdm9pZCByZW1vdmUoamF2YXgubWFpbC5GbGFncykKK3N1cHIgamF2YS5sYW5nLk9iamVjdAoraGZkcyBBTlNXRVJFRF9CSVQsREVMRVRFRF9CSVQsRFJBRlRfQklULEZMQUdHRURfQklULFJFQ0VOVF9CSVQsU0VFTl9CSVQsVVNFUl9CSVQsc2VyaWFsVmVyc2lvblVJRCxzeXN0ZW1fZmxhZ3MsdXNlcl9mbGFncworCitDTFNTIHB1YmxpYyBmaW5hbCBzdGF0aWMgamF2YXgubWFpbC5GbGFncyRGbGFnCisgb3V0ZXIgamF2YXgubWFpbC5GbGFncworZmxkIHB1YmxpYyBmaW5hbCBzdGF0aWMgamF2YXgubWFpbC5GbGFncyRGbGFnIEFOU1dFUkVECitmbGQgcHVibGljIGZpbmFsIHN0YXRpYyBqYXZheC5tYWlsLkZsYWdzJEZsYWcgREVMRVRFRAorZmxkIHB1YmxpYyBmaW5hbCBzdGF0aWMgamF2YXgubWFpbC5GbGFncyRGbGFnIERSQUZUCitmbGQgcHVibGljIGZpbmFsIHN0YXRpYyBqYXZheC5tYWlsLkZsYWdzJEZsYWcgRkxBR0dFRAorZmxkIHB1YmxpYyBmaW5hbCBzdGF0aWMgamF2YXgubWFpbC5GbGFncyRGbGFnIFJFQ0VOVAorZmxkIHB1YmxpYyBmaW5hbCBzdGF0aWMgamF2YXgubWFpbC5GbGFncyRGbGFnIFNFRU4KK2ZsZCBwdWJsaWMgZmluYWwgc3RhdGljIGphdmF4Lm1haWwuRmxhZ3MkRmxhZyBVU0VSCitzdXByIGphdmEubGFuZy5PYmplY3QKK2hmZHMgYml0CisKK0NMU1MgcHVibGljIGFic3RyYWN0IGphdmF4Lm1haWwuRm9sZGVyCitjb25zIHByb3RlY3RlZCA8aW5pdD4oamF2YXgubWFpbC5TdG9yZSkKK2ZsZCBwcm90ZWN0ZWQgaW50IG1vZGUKK2ZsZCBwcm90ZWN0ZWQgamF2YXgubWFpbC5TdG9yZSBzdG9yZQorZmxkIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IEhPTERTX0ZPTERFUlMgPSAyCitmbGQgcHVibGljIGZpbmFsIHN0YXRpYyBpbnQgSE9MRFNfTUVTU0FHRVMgPSAxCitmbGQgcHVibGljIGZpbmFsIHN0YXRpYyBpbnQgUkVBRF9PTkxZID0gMQorZmxkIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IFJFQURfV1JJVEUgPSAyCitpbnRmIGphdmEubGFuZy5BdXRvQ2xvc2VhYmxlCittZXRoIHByb3RlY3RlZCB2b2lkIGZpbmFsaXplKCkgdGhyb3dzIGphdmEubGFuZy5UaHJvd2FibGUKK21ldGggcHJvdGVjdGVkIHZvaWQgbm90aWZ5Q29ubmVjdGlvbkxpc3RlbmVycyhpbnQpCittZXRoIHByb3RlY3RlZCB2b2lkIG5vdGlmeUZvbGRlckxpc3RlbmVycyhpbnQpCittZXRoIHByb3RlY3RlZCB2b2lkIG5vdGlmeUZvbGRlclJlbmFtZWRMaXN0ZW5lcnMoamF2YXgubWFpbC5Gb2xkZXIpCittZXRoIHByb3RlY3RlZCB2b2lkIG5vdGlmeU1lc3NhZ2VBZGRlZExpc3RlbmVycyhqYXZheC5tYWlsLk1lc3NhZ2VbXSkKK21ldGggcHJvdGVjdGVkIHZvaWQgbm90aWZ5TWVzc2FnZUNoYW5nZWRMaXN0ZW5lcnMoaW50LGphdmF4Lm1haWwuTWVzc2FnZSkKK21ldGggcHJvdGVjdGVkIHZvaWQgbm90aWZ5TWVzc2FnZVJlbW92ZWRMaXN0ZW5lcnMoYm9vbGVhbixqYXZheC5tYWlsLk1lc3NhZ2VbXSkKK21ldGggcHVibGljIGFic3RyYWN0IGJvb2xlYW4gY3JlYXRlKGludCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGRlbGV0ZShib29sZWFuKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGFic3RyYWN0IGJvb2xlYW4gZXhpc3RzKCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGhhc05ld01lc3NhZ2VzKCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGlzT3BlbigpCittZXRoIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIHJlbmFtZVRvKGphdmF4Lm1haWwuRm9sZGVyKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGFic3RyYWN0IGNoYXIgZ2V0U2VwYXJhdG9yKCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBhYnN0cmFjdCBpbnQgZ2V0TWVzc2FnZUNvdW50KCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBhYnN0cmFjdCBpbnQgZ2V0VHlwZSgpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgYWJzdHJhY3QgamF2YS5sYW5nLlN0cmluZyBnZXRGdWxsTmFtZSgpCittZXRoIHB1YmxpYyBhYnN0cmFjdCBqYXZhLmxhbmcuU3RyaW5nIGdldE5hbWUoKQorbWV0aCBwdWJsaWMgYWJzdHJhY3QgamF2YXgubWFpbC5GbGFncyBnZXRQZXJtYW5lbnRGbGFncygpCittZXRoIHB1YmxpYyBhYnN0cmFjdCBqYXZheC5tYWlsLkZvbGRlciBnZXRGb2xkZXIoamF2YS5sYW5nLlN0cmluZykgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBhYnN0cmFjdCBqYXZheC5tYWlsLkZvbGRlciBnZXRQYXJlbnQoKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGFic3RyYWN0IGphdmF4Lm1haWwuRm9sZGVyW10gbGlzdChqYXZhLmxhbmcuU3RyaW5nKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGFic3RyYWN0IGphdmF4Lm1haWwuTWVzc2FnZSBnZXRNZXNzYWdlKGludCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBhYnN0cmFjdCBqYXZheC5tYWlsLk1lc3NhZ2VbXSBleHB1bmdlKCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGFwcGVuZE1lc3NhZ2VzKGphdmF4Lm1haWwuTWVzc2FnZVtdKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGFic3RyYWN0IHZvaWQgY2xvc2UoYm9vbGVhbikgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBhYnN0cmFjdCB2b2lkIG9wZW4oaW50KSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGJvb2xlYW4gaXNTdWJzY3JpYmVkKCkKK21ldGggcHVibGljIGludCBnZXREZWxldGVkTWVzc2FnZUNvdW50KCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBpbnQgZ2V0TW9kZSgpCittZXRoIHB1YmxpYyBpbnQgZ2V0TmV3TWVzc2FnZUNvdW50KCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBpbnQgZ2V0VW5yZWFkTWVzc2FnZUNvdW50KCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIHRvU3RyaW5nKCkKK21ldGggcHVibGljIGphdmF4Lm1haWwuRm9sZGVyW10gbGlzdCgpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgamF2YXgubWFpbC5Gb2xkZXJbXSBsaXN0U3Vic2NyaWJlZCgpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgamF2YXgubWFpbC5Gb2xkZXJbXSBsaXN0U3Vic2NyaWJlZChqYXZhLmxhbmcuU3RyaW5nKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGphdmF4Lm1haWwuTWVzc2FnZVtdIGdldE1lc3NhZ2VzKCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBqYXZheC5tYWlsLk1lc3NhZ2VbXSBnZXRNZXNzYWdlcyhpbnQsaW50KSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGphdmF4Lm1haWwuTWVzc2FnZVtdIGdldE1lc3NhZ2VzKGludFtdKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGphdmF4Lm1haWwuTWVzc2FnZVtdIHNlYXJjaChqYXZheC5tYWlsLnNlYXJjaC5TZWFyY2hUZXJtKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGphdmF4Lm1haWwuTWVzc2FnZVtdIHNlYXJjaChqYXZheC5tYWlsLnNlYXJjaC5TZWFyY2hUZXJtLGphdmF4Lm1haWwuTWVzc2FnZVtdKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGphdmF4Lm1haWwuU3RvcmUgZ2V0U3RvcmUoKQorbWV0aCBwdWJsaWMgamF2YXgubWFpbC5VUkxOYW1lIGdldFVSTE5hbWUoKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIHZvaWQgYWRkQ29ubmVjdGlvbkxpc3RlbmVyKGphdmF4Lm1haWwuZXZlbnQuQ29ubmVjdGlvbkxpc3RlbmVyKQorbWV0aCBwdWJsaWMgdm9pZCBhZGRGb2xkZXJMaXN0ZW5lcihqYXZheC5tYWlsLmV2ZW50LkZvbGRlckxpc3RlbmVyKQorbWV0aCBwdWJsaWMgdm9pZCBhZGRNZXNzYWdlQ2hhbmdlZExpc3RlbmVyKGphdmF4Lm1haWwuZXZlbnQuTWVzc2FnZUNoYW5nZWRMaXN0ZW5lcikKK21ldGggcHVibGljIHZvaWQgYWRkTWVzc2FnZUNvdW50TGlzdGVuZXIoamF2YXgubWFpbC5ldmVudC5NZXNzYWdlQ291bnRMaXN0ZW5lcikKK21ldGggcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIHZvaWQgY29weU1lc3NhZ2VzKGphdmF4Lm1haWwuTWVzc2FnZVtdLGphdmF4Lm1haWwuRm9sZGVyKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIHZvaWQgZmV0Y2goamF2YXgubWFpbC5NZXNzYWdlW10samF2YXgubWFpbC5GZXRjaFByb2ZpbGUpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgdm9pZCByZW1vdmVDb25uZWN0aW9uTGlzdGVuZXIoamF2YXgubWFpbC5ldmVudC5Db25uZWN0aW9uTGlzdGVuZXIpCittZXRoIHB1YmxpYyB2b2lkIHJlbW92ZUZvbGRlckxpc3RlbmVyKGphdmF4Lm1haWwuZXZlbnQuRm9sZGVyTGlzdGVuZXIpCittZXRoIHB1YmxpYyB2b2lkIHJlbW92ZU1lc3NhZ2VDaGFuZ2VkTGlzdGVuZXIoamF2YXgubWFpbC5ldmVudC5NZXNzYWdlQ2hhbmdlZExpc3RlbmVyKQorbWV0aCBwdWJsaWMgdm9pZCByZW1vdmVNZXNzYWdlQ291bnRMaXN0ZW5lcihqYXZheC5tYWlsLmV2ZW50Lk1lc3NhZ2VDb3VudExpc3RlbmVyKQorbWV0aCBwdWJsaWMgdm9pZCBzZXRGbGFncyhpbnQsaW50LGphdmF4Lm1haWwuRmxhZ3MsYm9vbGVhbikgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyB2b2lkIHNldEZsYWdzKGludFtdLGphdmF4Lm1haWwuRmxhZ3MsYm9vbGVhbikgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyB2b2lkIHNldEZsYWdzKGphdmF4Lm1haWwuTWVzc2FnZVtdLGphdmF4Lm1haWwuRmxhZ3MsYm9vbGVhbikgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyB2b2lkIHNldFN1YnNjcmliZWQoYm9vbGVhbikgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCitzdXByIGphdmEubGFuZy5PYmplY3QKK2hmZHMgY29ubmVjdGlvbkxpc3RlbmVycyxmb2xkZXJMaXN0ZW5lcnMsbWVzc2FnZUNoYW5nZWRMaXN0ZW5lcnMsbWVzc2FnZUNvdW50TGlzdGVuZXJzLHEKKworQ0xTUyBwdWJsaWMgamF2YXgubWFpbC5Gb2xkZXJDbG9zZWRFeGNlcHRpb24KK2NvbnMgcHVibGljIDxpbml0PihqYXZheC5tYWlsLkZvbGRlcikKK2NvbnMgcHVibGljIDxpbml0PihqYXZheC5tYWlsLkZvbGRlcixqYXZhLmxhbmcuU3RyaW5nKQorY29ucyBwdWJsaWMgPGluaXQ+KGphdmF4Lm1haWwuRm9sZGVyLGphdmEubGFuZy5TdHJpbmcsamF2YS5sYW5nLkV4Y2VwdGlvbikKK21ldGggcHVibGljIGphdmF4Lm1haWwuRm9sZGVyIGdldEZvbGRlcigpCitzdXByIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCitoZmRzIGZvbGRlcixzZXJpYWxWZXJzaW9uVUlECisKK0NMU1MgcHVibGljIGphdmF4Lm1haWwuRm9sZGVyTm90Rm91bmRFeGNlcHRpb24KK2NvbnMgcHVibGljIDxpbml0PigpCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YS5sYW5nLlN0cmluZyxqYXZheC5tYWlsLkZvbGRlcikKK2NvbnMgcHVibGljIDxpbml0PihqYXZheC5tYWlsLkZvbGRlcikKK2NvbnMgcHVibGljIDxpbml0PihqYXZheC5tYWlsLkZvbGRlcixqYXZhLmxhbmcuU3RyaW5nKQorY29ucyBwdWJsaWMgPGluaXQ+KGphdmF4Lm1haWwuRm9sZGVyLGphdmEubGFuZy5TdHJpbmcsamF2YS5sYW5nLkV4Y2VwdGlvbikKK21ldGggcHVibGljIGphdmF4Lm1haWwuRm9sZGVyIGdldEZvbGRlcigpCitzdXByIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCitoZmRzIGZvbGRlcixzZXJpYWxWZXJzaW9uVUlECisKK0NMU1MgcHVibGljIGphdmF4Lm1haWwuSGVhZGVyCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YS5sYW5nLlN0cmluZyxqYXZhLmxhbmcuU3RyaW5nKQorZmxkIHByb3RlY3RlZCBqYXZhLmxhbmcuU3RyaW5nIG5hbWUKK2ZsZCBwcm90ZWN0ZWQgamF2YS5sYW5nLlN0cmluZyB2YWx1ZQorbWV0aCBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXROYW1lKCkKK21ldGggcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0VmFsdWUoKQorc3VwciBqYXZhLmxhbmcuT2JqZWN0CisKK0NMU1MgcHVibGljIGphdmF4Lm1haWwuSWxsZWdhbFdyaXRlRXhjZXB0aW9uCitjb25zIHB1YmxpYyA8aW5pdD4oKQorY29ucyBwdWJsaWMgPGluaXQ+KGphdmEubGFuZy5TdHJpbmcpCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YS5sYW5nLlN0cmluZyxqYXZhLmxhbmcuRXhjZXB0aW9uKQorc3VwciBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgoraGZkcyBzZXJpYWxWZXJzaW9uVUlECisKK0NMU1MgcHVibGljIGFic3RyYWN0IGludGVyZmFjZSAhYW5ub3RhdGlvbiBqYXZheC5tYWlsLk1haWxTZXNzaW9uRGVmaW5pdGlvbgorIGFubm8gMCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXBlYXRhYmxlKGphdmEubGFuZy5DbGFzczw/IGV4dGVuZHMgamF2YS5sYW5nLmFubm90YXRpb24uQW5ub3RhdGlvbj4gdmFsdWU9Y2xhc3MgamF2YXgubWFpbC5NYWlsU2Vzc2lvbkRlZmluaXRpb25zKQorIGFubm8gMCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXRlbnRpb24oamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uUG9saWN5IHZhbHVlPVJVTlRJTUUpCisgYW5ubyAwIGphdmEubGFuZy5hbm5vdGF0aW9uLlRhcmdldChqYXZhLmxhbmcuYW5ub3RhdGlvbi5FbGVtZW50VHlwZVtdIHZhbHVlPVtUWVBFXSkKK2ludGYgamF2YS5sYW5nLmFubm90YXRpb24uQW5ub3RhdGlvbgorbWV0aCBwdWJsaWMgYWJzdHJhY3QgIWhhc2RlZmF1bHQgamF2YS5sYW5nLlN0cmluZyBkZXNjcmlwdGlvbigpIHZhbHVlPSAiIgorbWV0aCBwdWJsaWMgYWJzdHJhY3QgIWhhc2RlZmF1bHQgamF2YS5sYW5nLlN0cmluZyBmcm9tKCkgdmFsdWU9ICIiCittZXRoIHB1YmxpYyBhYnN0cmFjdCAhaGFzZGVmYXVsdCBqYXZhLmxhbmcuU3RyaW5nIGhvc3QoKSB2YWx1ZT0gIiIKK21ldGggcHVibGljIGFic3RyYWN0ICFoYXNkZWZhdWx0IGphdmEubGFuZy5TdHJpbmcgcGFzc3dvcmQoKSB2YWx1ZT0gIiIKK21ldGggcHVibGljIGFic3RyYWN0ICFoYXNkZWZhdWx0IGphdmEubGFuZy5TdHJpbmcgc3RvcmVQcm90b2NvbCgpIHZhbHVlPSAiIgorbWV0aCBwdWJsaWMgYWJzdHJhY3QgIWhhc2RlZmF1bHQgamF2YS5sYW5nLlN0cmluZyB0cmFuc3BvcnRQcm90b2NvbCgpIHZhbHVlPSAiIgorbWV0aCBwdWJsaWMgYWJzdHJhY3QgIWhhc2RlZmF1bHQgamF2YS5sYW5nLlN0cmluZyB1c2VyKCkgdmFsdWU9ICIiCittZXRoIHB1YmxpYyBhYnN0cmFjdCAhaGFzZGVmYXVsdCBqYXZhLmxhbmcuU3RyaW5nW10gcHJvcGVydGllcygpIHZhbHVlPSBbXQorbWV0aCBwdWJsaWMgYWJzdHJhY3QgamF2YS5sYW5nLlN0cmluZyBuYW1lKCkKKworQ0xTUyBwdWJsaWMgYWJzdHJhY3QgaW50ZXJmYWNlICFhbm5vdGF0aW9uIGphdmF4Lm1haWwuTWFpbFNlc3Npb25EZWZpbml0aW9ucworIGFubm8gMCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXRlbnRpb24oamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uUG9saWN5IHZhbHVlPVJVTlRJTUUpCisgYW5ubyAwIGphdmEubGFuZy5hbm5vdGF0aW9uLlRhcmdldChqYXZhLmxhbmcuYW5ub3RhdGlvbi5FbGVtZW50VHlwZVtdIHZhbHVlPVtUWVBFXSkKK2ludGYgamF2YS5sYW5nLmFubm90YXRpb24uQW5ub3RhdGlvbgorbWV0aCBwdWJsaWMgYWJzdHJhY3QgamF2YXgubWFpbC5NYWlsU2Vzc2lvbkRlZmluaXRpb25bXSB2YWx1ZSgpCisKK0NMU1MgcHVibGljIGFic3RyYWN0IGphdmF4Lm1haWwuTWVzc2FnZQorY29ucyBwcm90ZWN0ZWQgPGluaXQ+KCkKK2NvbnMgcHJvdGVjdGVkIDxpbml0PihqYXZheC5tYWlsLkZvbGRlcixpbnQpCitjb25zIHByb3RlY3RlZCA8aW5pdD4oamF2YXgubWFpbC5TZXNzaW9uKQorZmxkIHByb3RlY3RlZCBib29sZWFuIGV4cHVuZ2VkCitmbGQgcHJvdGVjdGVkIGludCBtc2dudW0KK2ZsZCBwcm90ZWN0ZWQgamF2YXgubWFpbC5Gb2xkZXIgZm9sZGVyCitmbGQgcHJvdGVjdGVkIGphdmF4Lm1haWwuU2Vzc2lvbiBzZXNzaW9uCitpbm5yIHB1YmxpYyBzdGF0aWMgUmVjaXBpZW50VHlwZQoraW50ZiBqYXZheC5tYWlsLlBhcnQKK21ldGggcHJvdGVjdGVkIHZvaWQgc2V0RXhwdW5nZWQoYm9vbGVhbikKK21ldGggcHJvdGVjdGVkIHZvaWQgc2V0TWVzc2FnZU51bWJlcihpbnQpCittZXRoIHB1YmxpYyBhYnN0cmFjdCBqYXZhLmxhbmcuU3RyaW5nIGdldFN1YmplY3QoKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGFic3RyYWN0IGphdmEudXRpbC5EYXRlIGdldFJlY2VpdmVkRGF0ZSgpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgYWJzdHJhY3QgamF2YS51dGlsLkRhdGUgZ2V0U2VudERhdGUoKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGFic3RyYWN0IGphdmF4Lm1haWwuQWRkcmVzc1tdIGdldEZyb20oKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGFic3RyYWN0IGphdmF4Lm1haWwuQWRkcmVzc1tdIGdldFJlY2lwaWVudHMoamF2YXgubWFpbC5NZXNzYWdlJFJlY2lwaWVudFR5cGUpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgYWJzdHJhY3QgamF2YXgubWFpbC5GbGFncyBnZXRGbGFncygpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgYWJzdHJhY3QgamF2YXgubWFpbC5NZXNzYWdlIHJlcGx5KGJvb2xlYW4pIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBhZGRGcm9tKGphdmF4Lm1haWwuQWRkcmVzc1tdKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGFic3RyYWN0IHZvaWQgYWRkUmVjaXBpZW50cyhqYXZheC5tYWlsLk1lc3NhZ2UkUmVjaXBpZW50VHlwZSxqYXZheC5tYWlsLkFkZHJlc3NbXSkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNhdmVDaGFuZ2VzKCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldEZsYWdzKGphdmF4Lm1haWwuRmxhZ3MsYm9vbGVhbikgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldEZyb20oKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGFic3RyYWN0IHZvaWQgc2V0RnJvbShqYXZheC5tYWlsLkFkZHJlc3MpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRSZWNpcGllbnRzKGphdmF4Lm1haWwuTWVzc2FnZSRSZWNpcGllbnRUeXBlLGphdmF4Lm1haWwuQWRkcmVzc1tdKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGFic3RyYWN0IHZvaWQgc2V0U2VudERhdGUoamF2YS51dGlsLkRhdGUpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRTdWJqZWN0KGphdmEubGFuZy5TdHJpbmcpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgYm9vbGVhbiBpc0V4cHVuZ2VkKCkKK21ldGggcHVibGljIGJvb2xlYW4gaXNTZXQoamF2YXgubWFpbC5GbGFncyRGbGFnKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGJvb2xlYW4gbWF0Y2goamF2YXgubWFpbC5zZWFyY2guU2VhcmNoVGVybSkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBpbnQgZ2V0TWVzc2FnZU51bWJlcigpCittZXRoIHB1YmxpYyBqYXZheC5tYWlsLkFkZHJlc3NbXSBnZXRBbGxSZWNpcGllbnRzKCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBqYXZheC5tYWlsLkFkZHJlc3NbXSBnZXRSZXBseVRvKCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBqYXZheC5tYWlsLkZvbGRlciBnZXRGb2xkZXIoKQorbWV0aCBwdWJsaWMgamF2YXgubWFpbC5TZXNzaW9uIGdldFNlc3Npb24oKQorbWV0aCBwdWJsaWMgdm9pZCBhZGRSZWNpcGllbnQoamF2YXgubWFpbC5NZXNzYWdlJFJlY2lwaWVudFR5cGUsamF2YXgubWFpbC5BZGRyZXNzKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIHZvaWQgc2V0RmxhZyhqYXZheC5tYWlsLkZsYWdzJEZsYWcsYm9vbGVhbikgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyB2b2lkIHNldFJlY2lwaWVudChqYXZheC5tYWlsLk1lc3NhZ2UkUmVjaXBpZW50VHlwZSxqYXZheC5tYWlsLkFkZHJlc3MpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgdm9pZCBzZXRSZXBseVRvKGphdmF4Lm1haWwuQWRkcmVzc1tdKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK3N1cHIgamF2YS5sYW5nLk9iamVjdAorCitDTFNTIHB1YmxpYyBzdGF0aWMgamF2YXgubWFpbC5NZXNzYWdlJFJlY2lwaWVudFR5cGUKKyBvdXRlciBqYXZheC5tYWlsLk1lc3NhZ2UKK2NvbnMgcHJvdGVjdGVkIDxpbml0PihqYXZhLmxhbmcuU3RyaW5nKQorZmxkIHByb3RlY3RlZCBqYXZhLmxhbmcuU3RyaW5nIHR5cGUKK2ZsZCBwdWJsaWMgZmluYWwgc3RhdGljIGphdmF4Lm1haWwuTWVzc2FnZSRSZWNpcGllbnRUeXBlIEJDQworZmxkIHB1YmxpYyBmaW5hbCBzdGF0aWMgamF2YXgubWFpbC5NZXNzYWdlJFJlY2lwaWVudFR5cGUgQ0MKK2ZsZCBwdWJsaWMgZmluYWwgc3RhdGljIGphdmF4Lm1haWwuTWVzc2FnZSRSZWNpcGllbnRUeXBlIFRPCitpbnRmIGphdmEuaW8uU2VyaWFsaXphYmxlCittZXRoIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IHJlYWRSZXNvbHZlKCkgdGhyb3dzIGphdmEuaW8uT2JqZWN0U3RyZWFtRXhjZXB0aW9uCittZXRoIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIHRvU3RyaW5nKCkKK3N1cHIgamF2YS5sYW5nLk9iamVjdAoraGZkcyBzZXJpYWxWZXJzaW9uVUlECisKK0NMU1MgcHVibGljIGFic3RyYWN0IGludGVyZmFjZSBqYXZheC5tYWlsLk1lc3NhZ2VBd2FyZQorbWV0aCBwdWJsaWMgYWJzdHJhY3QgamF2YXgubWFpbC5NZXNzYWdlQ29udGV4dCBnZXRNZXNzYWdlQ29udGV4dCgpCisKK0NMU1MgcHVibGljIGphdmF4Lm1haWwuTWVzc2FnZUNvbnRleHQKK2NvbnMgcHVibGljIDxpbml0PihqYXZheC5tYWlsLlBhcnQpCittZXRoIHB1YmxpYyBqYXZheC5tYWlsLk1lc3NhZ2UgZ2V0TWVzc2FnZSgpCittZXRoIHB1YmxpYyBqYXZheC5tYWlsLlBhcnQgZ2V0UGFydCgpCittZXRoIHB1YmxpYyBqYXZheC5tYWlsLlNlc3Npb24gZ2V0U2Vzc2lvbigpCitzdXByIGphdmEubGFuZy5PYmplY3QKK2hmZHMgcGFydAorCitDTFNTIHB1YmxpYyBqYXZheC5tYWlsLk1lc3NhZ2VSZW1vdmVkRXhjZXB0aW9uCitjb25zIHB1YmxpYyA8aW5pdD4oKQorY29ucyBwdWJsaWMgPGluaXQ+KGphdmEubGFuZy5TdHJpbmcpCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YS5sYW5nLlN0cmluZyxqYXZhLmxhbmcuRXhjZXB0aW9uKQorc3VwciBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgoraGZkcyBzZXJpYWxWZXJzaW9uVUlECisKK0NMU1MgcHVibGljIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCitjb25zIHB1YmxpYyA8aW5pdD4oKQorY29ucyBwdWJsaWMgPGluaXQ+KGphdmEubGFuZy5TdHJpbmcpCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YS5sYW5nLlN0cmluZyxqYXZhLmxhbmcuRXhjZXB0aW9uKQorbWV0aCBwdWJsaWMgYm9vbGVhbiBzZXROZXh0RXhjZXB0aW9uKGphdmEubGFuZy5FeGNlcHRpb24pCittZXRoIHB1YmxpYyBqYXZhLmxhbmcuRXhjZXB0aW9uIGdldE5leHRFeGNlcHRpb24oKQorbWV0aCBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyB0b1N0cmluZygpCittZXRoIHB1YmxpYyBqYXZhLmxhbmcuVGhyb3dhYmxlIGdldENhdXNlKCkKK3N1cHIgamF2YS5sYW5nLkV4Y2VwdGlvbgoraGZkcyBuZXh0LHNlcmlhbFZlcnNpb25VSUQKKworQ0xTUyBwdWJsaWMgamF2YXgubWFpbC5NZXRob2ROb3RTdXBwb3J0ZWRFeGNlcHRpb24KK2NvbnMgcHVibGljIDxpbml0PigpCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YS5sYW5nLlN0cmluZykKK2NvbnMgcHVibGljIDxpbml0PihqYXZhLmxhbmcuU3RyaW5nLGphdmEubGFuZy5FeGNlcHRpb24pCitzdXByIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCitoZmRzIHNlcmlhbFZlcnNpb25VSUQKKworQ0xTUyBwdWJsaWMgYWJzdHJhY3QgamF2YXgubWFpbC5NdWx0aXBhcnQKK2NvbnMgcHJvdGVjdGVkIDxpbml0PigpCitmbGQgcHJvdGVjdGVkIGphdmEubGFuZy5TdHJpbmcgY29udGVudFR5cGUKK2ZsZCBwcm90ZWN0ZWQgamF2YS51dGlsLlZlY3RvcjxqYXZheC5tYWlsLkJvZHlQYXJ0PiBwYXJ0cworZmxkIHByb3RlY3RlZCBqYXZheC5tYWlsLlBhcnQgcGFyZW50CittZXRoIHByb3RlY3RlZCB2b2lkIHNldE11bHRpcGFydERhdGFTb3VyY2UoamF2YXgubWFpbC5NdWx0aXBhcnREYXRhU291cmNlKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGFic3RyYWN0IHZvaWQgd3JpdGVUbyhqYXZhLmlvLk91dHB1dFN0cmVhbSkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24samF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGJvb2xlYW4gcmVtb3ZlQm9keVBhcnQoamF2YXgubWFpbC5Cb2R5UGFydCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBpbnQgZ2V0Q291bnQoKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0Q29udGVudFR5cGUoKQorbWV0aCBwdWJsaWMgamF2YXgubWFpbC5Cb2R5UGFydCBnZXRCb2R5UGFydChpbnQpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgamF2YXgubWFpbC5QYXJ0IGdldFBhcmVudCgpCittZXRoIHB1YmxpYyB2b2lkIGFkZEJvZHlQYXJ0KGphdmF4Lm1haWwuQm9keVBhcnQpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgdm9pZCBhZGRCb2R5UGFydChqYXZheC5tYWlsLkJvZHlQYXJ0LGludCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyB2b2lkIHJlbW92ZUJvZHlQYXJ0KGludCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyB2b2lkIHNldFBhcmVudChqYXZheC5tYWlsLlBhcnQpCitzdXByIGphdmEubGFuZy5PYmplY3QKKworQ0xTUyBwdWJsaWMgYWJzdHJhY3QgaW50ZXJmYWNlIGphdmF4Lm1haWwuTXVsdGlwYXJ0RGF0YVNvdXJjZQoraW50ZiBqYXZheC5hY3RpdmF0aW9uLkRhdGFTb3VyY2UKK21ldGggcHVibGljIGFic3RyYWN0IGludCBnZXRDb3VudCgpCittZXRoIHB1YmxpYyBhYnN0cmFjdCBqYXZheC5tYWlsLkJvZHlQYXJ0IGdldEJvZHlQYXJ0KGludCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCisKK0NMU1MgcHVibGljIGphdmF4Lm1haWwuTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24KK2NvbnMgcHVibGljIDxpbml0PigpCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YS5sYW5nLlN0cmluZykKK2NvbnMgcHVibGljIDxpbml0PihqYXZhLmxhbmcuU3RyaW5nLGphdmEubGFuZy5FeGNlcHRpb24pCitzdXByIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCitoZmRzIHNlcmlhbFZlcnNpb25VSUQKKworQ0xTUyBwdWJsaWMgYWJzdHJhY3QgaW50ZXJmYWNlIGphdmF4Lm1haWwuUGFydAorZmxkIHB1YmxpYyBmaW5hbCBzdGF0aWMgamF2YS5sYW5nLlN0cmluZyBBVFRBQ0hNRU5UID0gImF0dGFjaG1lbnQiCitmbGQgcHVibGljIGZpbmFsIHN0YXRpYyBqYXZhLmxhbmcuU3RyaW5nIElOTElORSA9ICJpbmxpbmUiCittZXRoIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGlzTWltZVR5cGUoamF2YS5sYW5nLlN0cmluZykgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBhYnN0cmFjdCBpbnQgZ2V0TGluZUNvdW50KCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBhYnN0cmFjdCBpbnQgZ2V0U2l6ZSgpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgYWJzdHJhY3QgamF2YS5pby5JbnB1dFN0cmVhbSBnZXRJbnB1dFN0cmVhbSgpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uLGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBhYnN0cmFjdCBqYXZhLmxhbmcuT2JqZWN0IGdldENvbnRlbnQoKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbixqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgYWJzdHJhY3QgamF2YS5sYW5nLlN0cmluZyBnZXRDb250ZW50VHlwZSgpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgYWJzdHJhY3QgamF2YS5sYW5nLlN0cmluZyBnZXREZXNjcmlwdGlvbigpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgYWJzdHJhY3QgamF2YS5sYW5nLlN0cmluZyBnZXREaXNwb3NpdGlvbigpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgYWJzdHJhY3QgamF2YS5sYW5nLlN0cmluZyBnZXRGaWxlTmFtZSgpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgYWJzdHJhY3QgamF2YS5sYW5nLlN0cmluZ1tdIGdldEhlYWRlcihqYXZhLmxhbmcuU3RyaW5nKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGFic3RyYWN0IGphdmEudXRpbC5FbnVtZXJhdGlvbjxqYXZheC5tYWlsLkhlYWRlcj4gZ2V0QWxsSGVhZGVycygpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgYWJzdHJhY3QgamF2YS51dGlsLkVudW1lcmF0aW9uPGphdmF4Lm1haWwuSGVhZGVyPiBnZXRNYXRjaGluZ0hlYWRlcnMoamF2YS5sYW5nLlN0cmluZ1tdKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGFic3RyYWN0IGphdmEudXRpbC5FbnVtZXJhdGlvbjxqYXZheC5tYWlsLkhlYWRlcj4gZ2V0Tm9uTWF0Y2hpbmdIZWFkZXJzKGphdmEubGFuZy5TdHJpbmdbXSkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBhYnN0cmFjdCBqYXZheC5hY3RpdmF0aW9uLkRhdGFIYW5kbGVyIGdldERhdGFIYW5kbGVyKCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGFkZEhlYWRlcihqYXZhLmxhbmcuU3RyaW5nLGphdmEubGFuZy5TdHJpbmcpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgYWJzdHJhY3Qgdm9pZCByZW1vdmVIZWFkZXIoamF2YS5sYW5nLlN0cmluZykgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldENvbnRlbnQoamF2YS5sYW5nLk9iamVjdCxqYXZhLmxhbmcuU3RyaW5nKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGFic3RyYWN0IHZvaWQgc2V0Q29udGVudChqYXZheC5tYWlsLk11bHRpcGFydCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldERhdGFIYW5kbGVyKGphdmF4LmFjdGl2YXRpb24uRGF0YUhhbmRsZXIpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXREZXNjcmlwdGlvbihqYXZhLmxhbmcuU3RyaW5nKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGFic3RyYWN0IHZvaWQgc2V0RGlzcG9zaXRpb24oamF2YS5sYW5nLlN0cmluZykgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldEZpbGVOYW1lKGphdmEubGFuZy5TdHJpbmcpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRIZWFkZXIoamF2YS5sYW5nLlN0cmluZyxqYXZhLmxhbmcuU3RyaW5nKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGFic3RyYWN0IHZvaWQgc2V0VGV4dChqYXZhLmxhbmcuU3RyaW5nKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGFic3RyYWN0IHZvaWQgd3JpdGVUbyhqYXZhLmlvLk91dHB1dFN0cmVhbSkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24samF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KKworQ0xTUyBwdWJsaWMgZmluYWwgamF2YXgubWFpbC5QYXNzd29yZEF1dGhlbnRpY2F0aW9uCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YS5sYW5nLlN0cmluZyxqYXZhLmxhbmcuU3RyaW5nKQorbWV0aCBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRQYXNzd29yZCgpCittZXRoIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFVzZXJOYW1lKCkKK3N1cHIgamF2YS5sYW5nLk9iamVjdAoraGZkcyBwYXNzd29yZCx1c2VyTmFtZQorCitDTFNTIHB1YmxpYyBqYXZheC5tYWlsLlByb3ZpZGVyCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YXgubWFpbC5Qcm92aWRlciRUeXBlLGphdmEubGFuZy5TdHJpbmcsamF2YS5sYW5nLlN0cmluZyxqYXZhLmxhbmcuU3RyaW5nLGphdmEubGFuZy5TdHJpbmcpCitpbm5yIHB1YmxpYyBzdGF0aWMgVHlwZQorbWV0aCBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRDbGFzc05hbWUoKQorbWV0aCBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRQcm90b2NvbCgpCittZXRoIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFZlbmRvcigpCittZXRoIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFZlcnNpb24oKQorbWV0aCBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyB0b1N0cmluZygpCittZXRoIHB1YmxpYyBqYXZheC5tYWlsLlByb3ZpZGVyJFR5cGUgZ2V0VHlwZSgpCitzdXByIGphdmEubGFuZy5PYmplY3QKK2hmZHMgY2xhc3NOYW1lLHByb3RvY29sLHR5cGUsdmVuZG9yLHZlcnNpb24KKworQ0xTUyBwdWJsaWMgc3RhdGljIGphdmF4Lm1haWwuUHJvdmlkZXIkVHlwZQorIG91dGVyIGphdmF4Lm1haWwuUHJvdmlkZXIKK2ZsZCBwdWJsaWMgZmluYWwgc3RhdGljIGphdmF4Lm1haWwuUHJvdmlkZXIkVHlwZSBTVE9SRQorZmxkIHB1YmxpYyBmaW5hbCBzdGF0aWMgamF2YXgubWFpbC5Qcm92aWRlciRUeXBlIFRSQU5TUE9SVAorbWV0aCBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyB0b1N0cmluZygpCitzdXByIGphdmEubGFuZy5PYmplY3QKK2hmZHMgdHlwZQorCitDTFNTIHB1YmxpYyBqYXZheC5tYWlsLlF1b3RhCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YS5sYW5nLlN0cmluZykKK2ZsZCBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBxdW90YVJvb3QKK2ZsZCBwdWJsaWMgamF2YXgubWFpbC5RdW90YSRSZXNvdXJjZVtdIHJlc291cmNlcworaW5uciBwdWJsaWMgc3RhdGljIFJlc291cmNlCittZXRoIHB1YmxpYyB2b2lkIHNldFJlc291cmNlTGltaXQoamF2YS5sYW5nLlN0cmluZyxsb25nKQorc3VwciBqYXZhLmxhbmcuT2JqZWN0CisKK0NMU1MgcHVibGljIHN0YXRpYyBqYXZheC5tYWlsLlF1b3RhJFJlc291cmNlCisgb3V0ZXIgamF2YXgubWFpbC5RdW90YQorY29ucyBwdWJsaWMgPGluaXQ+KGphdmEubGFuZy5TdHJpbmcsbG9uZyxsb25nKQorZmxkIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIG5hbWUKK2ZsZCBwdWJsaWMgbG9uZyBsaW1pdAorZmxkIHB1YmxpYyBsb25nIHVzYWdlCitzdXByIGphdmEubGFuZy5PYmplY3QKKworQ0xTUyBwdWJsaWMgYWJzdHJhY3QgaW50ZXJmYWNlIGphdmF4Lm1haWwuUXVvdGFBd2FyZVN0b3JlCittZXRoIHB1YmxpYyBhYnN0cmFjdCBqYXZheC5tYWlsLlF1b3RhW10gZ2V0UXVvdGEoamF2YS5sYW5nLlN0cmluZykgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldFF1b3RhKGphdmF4Lm1haWwuUXVvdGEpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorCitDTFNTIHB1YmxpYyBqYXZheC5tYWlsLlJlYWRPbmx5Rm9sZGVyRXhjZXB0aW9uCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YXgubWFpbC5Gb2xkZXIpCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YXgubWFpbC5Gb2xkZXIsamF2YS5sYW5nLlN0cmluZykKK2NvbnMgcHVibGljIDxpbml0PihqYXZheC5tYWlsLkZvbGRlcixqYXZhLmxhbmcuU3RyaW5nLGphdmEubGFuZy5FeGNlcHRpb24pCittZXRoIHB1YmxpYyBqYXZheC5tYWlsLkZvbGRlciBnZXRGb2xkZXIoKQorc3VwciBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgoraGZkcyBmb2xkZXIsc2VyaWFsVmVyc2lvblVJRAorCitDTFNTIHB1YmxpYyBqYXZheC5tYWlsLlNlbmRGYWlsZWRFeGNlcHRpb24KK2NvbnMgcHVibGljIDxpbml0PigpCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YS5sYW5nLlN0cmluZykKK2NvbnMgcHVibGljIDxpbml0PihqYXZhLmxhbmcuU3RyaW5nLGphdmEubGFuZy5FeGNlcHRpb24pCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YS5sYW5nLlN0cmluZyxqYXZhLmxhbmcuRXhjZXB0aW9uLGphdmF4Lm1haWwuQWRkcmVzc1tdLGphdmF4Lm1haWwuQWRkcmVzc1tdLGphdmF4Lm1haWwuQWRkcmVzc1tdKQorZmxkIHByb3RlY3RlZCBqYXZheC5tYWlsLkFkZHJlc3NbXSBpbnZhbGlkCitmbGQgcHJvdGVjdGVkIGphdmF4Lm1haWwuQWRkcmVzc1tdIHZhbGlkU2VudAorZmxkIHByb3RlY3RlZCBqYXZheC5tYWlsLkFkZHJlc3NbXSB2YWxpZFVuc2VudAorbWV0aCBwdWJsaWMgamF2YXgubWFpbC5BZGRyZXNzW10gZ2V0SW52YWxpZEFkZHJlc3NlcygpCittZXRoIHB1YmxpYyBqYXZheC5tYWlsLkFkZHJlc3NbXSBnZXRWYWxpZFNlbnRBZGRyZXNzZXMoKQorbWV0aCBwdWJsaWMgamF2YXgubWFpbC5BZGRyZXNzW10gZ2V0VmFsaWRVbnNlbnRBZGRyZXNzZXMoKQorc3VwciBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgoraGZkcyBzZXJpYWxWZXJzaW9uVUlECisKK0NMU1MgcHVibGljIGFic3RyYWN0IGphdmF4Lm1haWwuU2VydmljZQorY29ucyBwcm90ZWN0ZWQgPGluaXQ+KGphdmF4Lm1haWwuU2Vzc2lvbixqYXZheC5tYWlsLlVSTE5hbWUpCitmbGQgcHJvdGVjdGVkIGJvb2xlYW4gZGVidWcKK2ZsZCBwcm90ZWN0ZWQgamF2YXgubWFpbC5TZXNzaW9uIHNlc3Npb24KK2ZsZCBwcm90ZWN0ZWQgdm9sYXRpbGUgamF2YXgubWFpbC5VUkxOYW1lIHVybAoraW50ZiBqYXZhLmxhbmcuQXV0b0Nsb3NlYWJsZQorbWV0aCBwcm90ZWN0ZWQgYm9vbGVhbiBwcm90b2NvbENvbm5lY3QoamF2YS5sYW5nLlN0cmluZyxpbnQsamF2YS5sYW5nLlN0cmluZyxqYXZhLmxhbmcuU3RyaW5nKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHJvdGVjdGVkIHZvaWQgZmluYWxpemUoKSB0aHJvd3MgamF2YS5sYW5nLlRocm93YWJsZQorbWV0aCBwcm90ZWN0ZWQgdm9pZCBub3RpZnlDb25uZWN0aW9uTGlzdGVuZXJzKGludCkKK21ldGggcHJvdGVjdGVkIHZvaWQgcXVldWVFdmVudChqYXZheC5tYWlsLmV2ZW50Lk1haWxFdmVudCxqYXZhLnV0aWwuVmVjdG9yPD8gZXh0ZW5kcyBqYXZhLnV0aWwuRXZlbnRMaXN0ZW5lcj4pCittZXRoIHByb3RlY3RlZCB2b2lkIHNldENvbm5lY3RlZChib29sZWFuKQorbWV0aCBwcm90ZWN0ZWQgdm9pZCBzZXRVUkxOYW1lKGphdmF4Lm1haWwuVVJMTmFtZSkKK21ldGggcHVibGljIGJvb2xlYW4gaXNDb25uZWN0ZWQoKQorbWV0aCBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyB0b1N0cmluZygpCittZXRoIHB1YmxpYyBqYXZheC5tYWlsLlVSTE5hbWUgZ2V0VVJMTmFtZSgpCittZXRoIHB1YmxpYyB2b2lkIGFkZENvbm5lY3Rpb25MaXN0ZW5lcihqYXZheC5tYWlsLmV2ZW50LkNvbm5lY3Rpb25MaXN0ZW5lcikKK21ldGggcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIHZvaWQgY29ubmVjdCgpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgdm9pZCBjb25uZWN0KGphdmEubGFuZy5TdHJpbmcsaW50LGphdmEubGFuZy5TdHJpbmcsamF2YS5sYW5nLlN0cmluZykgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyB2b2lkIGNvbm5lY3QoamF2YS5sYW5nLlN0cmluZyxqYXZhLmxhbmcuU3RyaW5nKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIHZvaWQgY29ubmVjdChqYXZhLmxhbmcuU3RyaW5nLGphdmEubGFuZy5TdHJpbmcsamF2YS5sYW5nLlN0cmluZykgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyB2b2lkIHJlbW92ZUNvbm5lY3Rpb25MaXN0ZW5lcihqYXZheC5tYWlsLmV2ZW50LkNvbm5lY3Rpb25MaXN0ZW5lcikKK3N1cHIgamF2YS5sYW5nLk9iamVjdAoraGZkcyBjb25uZWN0ZWQsY29ubmVjdGlvbkxpc3RlbmVycyxxCisKK0NMU1MgcHVibGljIGZpbmFsIGphdmF4Lm1haWwuU2Vzc2lvbgorbWV0aCBwdWJsaWMgYm9vbGVhbiBnZXREZWJ1ZygpCittZXRoIHB1YmxpYyBqYXZhLmlvLlByaW50U3RyZWFtIGdldERlYnVnT3V0KCkKK21ldGggcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UHJvcGVydHkoamF2YS5sYW5nLlN0cmluZykKK21ldGggcHVibGljIGphdmEudXRpbC5Qcm9wZXJ0aWVzIGdldFByb3BlcnRpZXMoKQorbWV0aCBwdWJsaWMgamF2YXgubWFpbC5Gb2xkZXIgZ2V0Rm9sZGVyKGphdmF4Lm1haWwuVVJMTmFtZSkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBqYXZheC5tYWlsLlBhc3N3b3JkQXV0aGVudGljYXRpb24gZ2V0UGFzc3dvcmRBdXRoZW50aWNhdGlvbihqYXZheC5tYWlsLlVSTE5hbWUpCittZXRoIHB1YmxpYyBqYXZheC5tYWlsLlBhc3N3b3JkQXV0aGVudGljYXRpb24gcmVxdWVzdFBhc3N3b3JkQXV0aGVudGljYXRpb24oamF2YS5uZXQuSW5ldEFkZHJlc3MsaW50LGphdmEubGFuZy5TdHJpbmcsamF2YS5sYW5nLlN0cmluZyxqYXZhLmxhbmcuU3RyaW5nKQorbWV0aCBwdWJsaWMgamF2YXgubWFpbC5Qcm92aWRlciBnZXRQcm92aWRlcihqYXZhLmxhbmcuU3RyaW5nKSB0aHJvd3MgamF2YXgubWFpbC5Ob1N1Y2hQcm92aWRlckV4Y2VwdGlvbgorbWV0aCBwdWJsaWMgamF2YXgubWFpbC5Qcm92aWRlcltdIGdldFByb3ZpZGVycygpCittZXRoIHB1YmxpYyBqYXZheC5tYWlsLlN0b3JlIGdldFN0b3JlKCkgdGhyb3dzIGphdmF4Lm1haWwuTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24KK21ldGggcHVibGljIGphdmF4Lm1haWwuU3RvcmUgZ2V0U3RvcmUoamF2YS5sYW5nLlN0cmluZykgdGhyb3dzIGphdmF4Lm1haWwuTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24KK21ldGggcHVibGljIGphdmF4Lm1haWwuU3RvcmUgZ2V0U3RvcmUoamF2YXgubWFpbC5Qcm92aWRlcikgdGhyb3dzIGphdmF4Lm1haWwuTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24KK21ldGggcHVibGljIGphdmF4Lm1haWwuU3RvcmUgZ2V0U3RvcmUoamF2YXgubWFpbC5VUkxOYW1lKSB0aHJvd3MgamF2YXgubWFpbC5Ob1N1Y2hQcm92aWRlckV4Y2VwdGlvbgorbWV0aCBwdWJsaWMgamF2YXgubWFpbC5UcmFuc3BvcnQgZ2V0VHJhbnNwb3J0KCkgdGhyb3dzIGphdmF4Lm1haWwuTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24KK21ldGggcHVibGljIGphdmF4Lm1haWwuVHJhbnNwb3J0IGdldFRyYW5zcG9ydChqYXZhLmxhbmcuU3RyaW5nKSB0aHJvd3MgamF2YXgubWFpbC5Ob1N1Y2hQcm92aWRlckV4Y2VwdGlvbgorbWV0aCBwdWJsaWMgamF2YXgubWFpbC5UcmFuc3BvcnQgZ2V0VHJhbnNwb3J0KGphdmF4Lm1haWwuQWRkcmVzcykgdGhyb3dzIGphdmF4Lm1haWwuTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24KK21ldGggcHVibGljIGphdmF4Lm1haWwuVHJhbnNwb3J0IGdldFRyYW5zcG9ydChqYXZheC5tYWlsLlByb3ZpZGVyKSB0aHJvd3MgamF2YXgubWFpbC5Ob1N1Y2hQcm92aWRlckV4Y2VwdGlvbgorbWV0aCBwdWJsaWMgamF2YXgubWFpbC5UcmFuc3BvcnQgZ2V0VHJhbnNwb3J0KGphdmF4Lm1haWwuVVJMTmFtZSkgdGhyb3dzIGphdmF4Lm1haWwuTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24KK21ldGggcHVibGljIHN0YXRpYyBqYXZheC5tYWlsLlNlc3Npb24gZ2V0RGVmYXVsdEluc3RhbmNlKGphdmEudXRpbC5Qcm9wZXJ0aWVzKQorbWV0aCBwdWJsaWMgc3RhdGljIGphdmF4Lm1haWwuU2Vzc2lvbiBnZXREZWZhdWx0SW5zdGFuY2UoamF2YS51dGlsLlByb3BlcnRpZXMsamF2YXgubWFpbC5BdXRoZW50aWNhdG9yKQorbWV0aCBwdWJsaWMgc3RhdGljIGphdmF4Lm1haWwuU2Vzc2lvbiBnZXRJbnN0YW5jZShqYXZhLnV0aWwuUHJvcGVydGllcykKK21ldGggcHVibGljIHN0YXRpYyBqYXZheC5tYWlsLlNlc3Npb24gZ2V0SW5zdGFuY2UoamF2YS51dGlsLlByb3BlcnRpZXMsamF2YXgubWFpbC5BdXRoZW50aWNhdG9yKQorbWV0aCBwdWJsaWMgdm9pZCBhZGRQcm92aWRlcihqYXZheC5tYWlsLlByb3ZpZGVyKQorbWV0aCBwdWJsaWMgdm9pZCBzZXREZWJ1Zyhib29sZWFuKQorbWV0aCBwdWJsaWMgdm9pZCBzZXREZWJ1Z091dChqYXZhLmlvLlByaW50U3RyZWFtKQorbWV0aCBwdWJsaWMgdm9pZCBzZXRQYXNzd29yZEF1dGhlbnRpY2F0aW9uKGphdmF4Lm1haWwuVVJMTmFtZSxqYXZheC5tYWlsLlBhc3N3b3JkQXV0aGVudGljYXRpb24pCittZXRoIHB1YmxpYyB2b2lkIHNldFByb3RvY29sRm9yQWRkcmVzcyhqYXZhLmxhbmcuU3RyaW5nLGphdmEubGFuZy5TdHJpbmcpCittZXRoIHB1YmxpYyB2b2lkIHNldFByb3ZpZGVyKGphdmF4Lm1haWwuUHJvdmlkZXIpIHRocm93cyBqYXZheC5tYWlsLk5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uCitzdXByIGphdmEubGFuZy5PYmplY3QKK2hmZHMgYWRkcmVzc01hcCxhdXRoVGFibGUsYXV0aGVudGljYXRvcixjb25mRGlyLGRlYnVnLGRlZmF1bHRTZXNzaW9uLGxvZ2dlcixvdXQscHJvcHMscHJvdmlkZXJzLHByb3ZpZGVyc0J5Q2xhc3NOYW1lLHByb3ZpZGVyc0J5UHJvdG9jb2wscQorCitDTFNTIHB1YmxpYyBhYnN0cmFjdCBqYXZheC5tYWlsLlN0b3JlCitjb25zIHByb3RlY3RlZCA8aW5pdD4oamF2YXgubWFpbC5TZXNzaW9uLGphdmF4Lm1haWwuVVJMTmFtZSkKK21ldGggcHJvdGVjdGVkIHZvaWQgbm90aWZ5Rm9sZGVyTGlzdGVuZXJzKGludCxqYXZheC5tYWlsLkZvbGRlcikKK21ldGggcHJvdGVjdGVkIHZvaWQgbm90aWZ5Rm9sZGVyUmVuYW1lZExpc3RlbmVycyhqYXZheC5tYWlsLkZvbGRlcixqYXZheC5tYWlsLkZvbGRlcikKK21ldGggcHJvdGVjdGVkIHZvaWQgbm90aWZ5U3RvcmVMaXN0ZW5lcnMoaW50LGphdmEubGFuZy5TdHJpbmcpCittZXRoIHB1YmxpYyBhYnN0cmFjdCBqYXZheC5tYWlsLkZvbGRlciBnZXREZWZhdWx0Rm9sZGVyKCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBhYnN0cmFjdCBqYXZheC5tYWlsLkZvbGRlciBnZXRGb2xkZXIoamF2YS5sYW5nLlN0cmluZykgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBhYnN0cmFjdCBqYXZheC5tYWlsLkZvbGRlciBnZXRGb2xkZXIoamF2YXgubWFpbC5VUkxOYW1lKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGphdmF4Lm1haWwuRm9sZGVyW10gZ2V0UGVyc29uYWxOYW1lc3BhY2VzKCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBqYXZheC5tYWlsLkZvbGRlcltdIGdldFNoYXJlZE5hbWVzcGFjZXMoKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGphdmF4Lm1haWwuRm9sZGVyW10gZ2V0VXNlck5hbWVzcGFjZXMoamF2YS5sYW5nLlN0cmluZykgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyB2b2lkIGFkZEZvbGRlckxpc3RlbmVyKGphdmF4Lm1haWwuZXZlbnQuRm9sZGVyTGlzdGVuZXIpCittZXRoIHB1YmxpYyB2b2lkIGFkZFN0b3JlTGlzdGVuZXIoamF2YXgubWFpbC5ldmVudC5TdG9yZUxpc3RlbmVyKQorbWV0aCBwdWJsaWMgdm9pZCByZW1vdmVGb2xkZXJMaXN0ZW5lcihqYXZheC5tYWlsLmV2ZW50LkZvbGRlckxpc3RlbmVyKQorbWV0aCBwdWJsaWMgdm9pZCByZW1vdmVTdG9yZUxpc3RlbmVyKGphdmF4Lm1haWwuZXZlbnQuU3RvcmVMaXN0ZW5lcikKK3N1cHIgamF2YXgubWFpbC5TZXJ2aWNlCitoZmRzIGZvbGRlckxpc3RlbmVycyxzdG9yZUxpc3RlbmVycworCitDTFNTIHB1YmxpYyBqYXZheC5tYWlsLlN0b3JlQ2xvc2VkRXhjZXB0aW9uCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YXgubWFpbC5TdG9yZSkKK2NvbnMgcHVibGljIDxpbml0PihqYXZheC5tYWlsLlN0b3JlLGphdmEubGFuZy5TdHJpbmcpCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YXgubWFpbC5TdG9yZSxqYXZhLmxhbmcuU3RyaW5nLGphdmEubGFuZy5FeGNlcHRpb24pCittZXRoIHB1YmxpYyBqYXZheC5tYWlsLlN0b3JlIGdldFN0b3JlKCkKK3N1cHIgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK2hmZHMgc2VyaWFsVmVyc2lvblVJRCxzdG9yZQorCitDTFNTIHB1YmxpYyBhYnN0cmFjdCBqYXZheC5tYWlsLlRyYW5zcG9ydAorY29ucyBwdWJsaWMgPGluaXQ+KGphdmF4Lm1haWwuU2Vzc2lvbixqYXZheC5tYWlsLlVSTE5hbWUpCittZXRoIHByb3RlY3RlZCB2b2lkIG5vdGlmeVRyYW5zcG9ydExpc3RlbmVycyhpbnQsamF2YXgubWFpbC5BZGRyZXNzW10samF2YXgubWFpbC5BZGRyZXNzW10samF2YXgubWFpbC5BZGRyZXNzW10samF2YXgubWFpbC5NZXNzYWdlKQorbWV0aCBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZW5kTWVzc2FnZShqYXZheC5tYWlsLk1lc3NhZ2UsamF2YXgubWFpbC5BZGRyZXNzW10pIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgc3RhdGljIHZvaWQgc2VuZChqYXZheC5tYWlsLk1lc3NhZ2UpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgc3RhdGljIHZvaWQgc2VuZChqYXZheC5tYWlsLk1lc3NhZ2UsamF2YS5sYW5nLlN0cmluZyxqYXZhLmxhbmcuU3RyaW5nKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIHN0YXRpYyB2b2lkIHNlbmQoamF2YXgubWFpbC5NZXNzYWdlLGphdmF4Lm1haWwuQWRkcmVzc1tdKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIHN0YXRpYyB2b2lkIHNlbmQoamF2YXgubWFpbC5NZXNzYWdlLGphdmF4Lm1haWwuQWRkcmVzc1tdLGphdmEubGFuZy5TdHJpbmcsamF2YS5sYW5nLlN0cmluZykgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyB2b2lkIGFkZFRyYW5zcG9ydExpc3RlbmVyKGphdmF4Lm1haWwuZXZlbnQuVHJhbnNwb3J0TGlzdGVuZXIpCittZXRoIHB1YmxpYyB2b2lkIHJlbW92ZVRyYW5zcG9ydExpc3RlbmVyKGphdmF4Lm1haWwuZXZlbnQuVHJhbnNwb3J0TGlzdGVuZXIpCitzdXByIGphdmF4Lm1haWwuU2VydmljZQoraGZkcyB0cmFuc3BvcnRMaXN0ZW5lcnMKKworQ0xTUyBwdWJsaWMgYWJzdHJhY3QgaW50ZXJmYWNlIGphdmF4Lm1haWwuVUlERm9sZGVyCitmbGQgcHVibGljIGZpbmFsIHN0YXRpYyBsb25nIExBU1RVSUQgPSAtMQorZmxkIHB1YmxpYyBmaW5hbCBzdGF0aWMgbG9uZyBNQVhVSUQgPSA0Mjk0OTY3Mjk1Citpbm5yIHB1YmxpYyBzdGF0aWMgRmV0Y2hQcm9maWxlSXRlbQorbWV0aCBwdWJsaWMgYWJzdHJhY3QgamF2YXgubWFpbC5NZXNzYWdlIGdldE1lc3NhZ2VCeVVJRChsb25nKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGFic3RyYWN0IGphdmF4Lm1haWwuTWVzc2FnZVtdIGdldE1lc3NhZ2VzQnlVSUQobG9uZyxsb25nKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGFic3RyYWN0IGphdmF4Lm1haWwuTWVzc2FnZVtdIGdldE1lc3NhZ2VzQnlVSUQobG9uZ1tdKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGFic3RyYWN0IGxvbmcgZ2V0VUlEKGphdmF4Lm1haWwuTWVzc2FnZSkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBhYnN0cmFjdCBsb25nIGdldFVJRE5leHQoKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGFic3RyYWN0IGxvbmcgZ2V0VUlEVmFsaWRpdHkoKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KKworQ0xTUyBwdWJsaWMgc3RhdGljIGphdmF4Lm1haWwuVUlERm9sZGVyJEZldGNoUHJvZmlsZUl0ZW0KKyBvdXRlciBqYXZheC5tYWlsLlVJREZvbGRlcgorY29ucyBwcm90ZWN0ZWQgPGluaXQ+KGphdmEubGFuZy5TdHJpbmcpCitmbGQgcHVibGljIGZpbmFsIHN0YXRpYyBqYXZheC5tYWlsLlVJREZvbGRlciRGZXRjaFByb2ZpbGVJdGVtIFVJRAorc3VwciBqYXZheC5tYWlsLkZldGNoUHJvZmlsZSRJdGVtCisKK0NMU1MgcHVibGljIGphdmF4Lm1haWwuVVJMTmFtZQorY29ucyBwdWJsaWMgPGluaXQ+KGphdmEubGFuZy5TdHJpbmcpCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YS5sYW5nLlN0cmluZyxqYXZhLmxhbmcuU3RyaW5nLGludCxqYXZhLmxhbmcuU3RyaW5nLGphdmEubGFuZy5TdHJpbmcsamF2YS5sYW5nLlN0cmluZykKK2NvbnMgcHVibGljIDxpbml0PihqYXZhLm5ldC5VUkwpCitmbGQgcHJvdGVjdGVkIGphdmEubGFuZy5TdHJpbmcgZnVsbFVSTAorbWV0aCBwcm90ZWN0ZWQgdm9pZCBwYXJzZVN0cmluZyhqYXZhLmxhbmcuU3RyaW5nKQorbWV0aCBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoamF2YS5sYW5nLk9iamVjdCkKK21ldGggcHVibGljIGludCBnZXRQb3J0KCkKK21ldGggcHVibGljIGludCBoYXNoQ29kZSgpCittZXRoIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpbGUoKQorbWV0aCBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRIb3N0KCkKK21ldGggcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UGFzc3dvcmQoKQorbWV0aCBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRQcm90b2NvbCgpCittZXRoIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlZigpCittZXRoIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFVzZXJuYW1lKCkKK21ldGggcHVibGljIGphdmEubGFuZy5TdHJpbmcgdG9TdHJpbmcoKQorbWV0aCBwdWJsaWMgamF2YS5uZXQuVVJMIGdldFVSTCgpIHRocm93cyBqYXZhLm5ldC5NYWxmb3JtZWRVUkxFeGNlcHRpb24KK3N1cHIgamF2YS5sYW5nLk9iamVjdAoraGZkcyBjYXNlRGlmZixkb0VuY29kZSxkb250TmVlZEVuY29kaW5nLGZpbGUsaGFzaENvZGUsaG9zdCxob3N0QWRkcmVzcyxob3N0QWRkcmVzc0tub3duLHBhc3N3b3JkLHBvcnQscHJvdG9jb2wscmVmLHVzZXJuYW1lCisKK0NMU1MgcHVibGljIGFic3RyYWN0IGphdmF4Lm1haWwuZXZlbnQuQ29ubmVjdGlvbkFkYXB0ZXIKK2NvbnMgcHVibGljIDxpbml0PigpCitpbnRmIGphdmF4Lm1haWwuZXZlbnQuQ29ubmVjdGlvbkxpc3RlbmVyCittZXRoIHB1YmxpYyB2b2lkIGNsb3NlZChqYXZheC5tYWlsLmV2ZW50LkNvbm5lY3Rpb25FdmVudCkKK21ldGggcHVibGljIHZvaWQgZGlzY29ubmVjdGVkKGphdmF4Lm1haWwuZXZlbnQuQ29ubmVjdGlvbkV2ZW50KQorbWV0aCBwdWJsaWMgdm9pZCBvcGVuZWQoamF2YXgubWFpbC5ldmVudC5Db25uZWN0aW9uRXZlbnQpCitzdXByIGphdmEubGFuZy5PYmplY3QKKworQ0xTUyBwdWJsaWMgamF2YXgubWFpbC5ldmVudC5Db25uZWN0aW9uRXZlbnQKK2NvbnMgcHVibGljIDxpbml0PihqYXZhLmxhbmcuT2JqZWN0LGludCkKK2ZsZCBwcm90ZWN0ZWQgaW50IHR5cGUKK2ZsZCBwdWJsaWMgZmluYWwgc3RhdGljIGludCBDTE9TRUQgPSAzCitmbGQgcHVibGljIGZpbmFsIHN0YXRpYyBpbnQgRElTQ09OTkVDVEVEID0gMgorZmxkIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IE9QRU5FRCA9IDEKK21ldGggcHVibGljIGludCBnZXRUeXBlKCkKK21ldGggcHVibGljIHZvaWQgZGlzcGF0Y2goamF2YS5sYW5nLk9iamVjdCkKK3N1cHIgamF2YXgubWFpbC5ldmVudC5NYWlsRXZlbnQKK2hmZHMgc2VyaWFsVmVyc2lvblVJRAorCitDTFNTIHB1YmxpYyBhYnN0cmFjdCBpbnRlcmZhY2UgamF2YXgubWFpbC5ldmVudC5Db25uZWN0aW9uTGlzdGVuZXIKK2ludGYgamF2YS51dGlsLkV2ZW50TGlzdGVuZXIKK21ldGggcHVibGljIGFic3RyYWN0IHZvaWQgY2xvc2VkKGphdmF4Lm1haWwuZXZlbnQuQ29ubmVjdGlvbkV2ZW50KQorbWV0aCBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBkaXNjb25uZWN0ZWQoamF2YXgubWFpbC5ldmVudC5Db25uZWN0aW9uRXZlbnQpCittZXRoIHB1YmxpYyBhYnN0cmFjdCB2b2lkIG9wZW5lZChqYXZheC5tYWlsLmV2ZW50LkNvbm5lY3Rpb25FdmVudCkKKworQ0xTUyBwdWJsaWMgYWJzdHJhY3QgamF2YXgubWFpbC5ldmVudC5Gb2xkZXJBZGFwdGVyCitjb25zIHB1YmxpYyA8aW5pdD4oKQoraW50ZiBqYXZheC5tYWlsLmV2ZW50LkZvbGRlckxpc3RlbmVyCittZXRoIHB1YmxpYyB2b2lkIGZvbGRlckNyZWF0ZWQoamF2YXgubWFpbC5ldmVudC5Gb2xkZXJFdmVudCkKK21ldGggcHVibGljIHZvaWQgZm9sZGVyRGVsZXRlZChqYXZheC5tYWlsLmV2ZW50LkZvbGRlckV2ZW50KQorbWV0aCBwdWJsaWMgdm9pZCBmb2xkZXJSZW5hbWVkKGphdmF4Lm1haWwuZXZlbnQuRm9sZGVyRXZlbnQpCitzdXByIGphdmEubGFuZy5PYmplY3QKKworQ0xTUyBwdWJsaWMgamF2YXgubWFpbC5ldmVudC5Gb2xkZXJFdmVudAorY29ucyBwdWJsaWMgPGluaXQ+KGphdmEubGFuZy5PYmplY3QsamF2YXgubWFpbC5Gb2xkZXIsaW50KQorY29ucyBwdWJsaWMgPGluaXQ+KGphdmEubGFuZy5PYmplY3QsamF2YXgubWFpbC5Gb2xkZXIsamF2YXgubWFpbC5Gb2xkZXIsaW50KQorZmxkIHByb3RlY3RlZCBpbnQgdHlwZQorZmxkIHByb3RlY3RlZCBqYXZheC5tYWlsLkZvbGRlciBmb2xkZXIKK2ZsZCBwcm90ZWN0ZWQgamF2YXgubWFpbC5Gb2xkZXIgbmV3Rm9sZGVyCitmbGQgcHVibGljIGZpbmFsIHN0YXRpYyBpbnQgQ1JFQVRFRCA9IDEKK2ZsZCBwdWJsaWMgZmluYWwgc3RhdGljIGludCBERUxFVEVEID0gMgorZmxkIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IFJFTkFNRUQgPSAzCittZXRoIHB1YmxpYyBpbnQgZ2V0VHlwZSgpCittZXRoIHB1YmxpYyBqYXZheC5tYWlsLkZvbGRlciBnZXRGb2xkZXIoKQorbWV0aCBwdWJsaWMgamF2YXgubWFpbC5Gb2xkZXIgZ2V0TmV3Rm9sZGVyKCkKK21ldGggcHVibGljIHZvaWQgZGlzcGF0Y2goamF2YS5sYW5nLk9iamVjdCkKK3N1cHIgamF2YXgubWFpbC5ldmVudC5NYWlsRXZlbnQKK2hmZHMgc2VyaWFsVmVyc2lvblVJRAorCitDTFNTIHB1YmxpYyBhYnN0cmFjdCBpbnRlcmZhY2UgamF2YXgubWFpbC5ldmVudC5Gb2xkZXJMaXN0ZW5lcgoraW50ZiBqYXZhLnV0aWwuRXZlbnRMaXN0ZW5lcgorbWV0aCBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBmb2xkZXJDcmVhdGVkKGphdmF4Lm1haWwuZXZlbnQuRm9sZGVyRXZlbnQpCittZXRoIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGZvbGRlckRlbGV0ZWQoamF2YXgubWFpbC5ldmVudC5Gb2xkZXJFdmVudCkKK21ldGggcHVibGljIGFic3RyYWN0IHZvaWQgZm9sZGVyUmVuYW1lZChqYXZheC5tYWlsLmV2ZW50LkZvbGRlckV2ZW50KQorCitDTFNTIHB1YmxpYyBhYnN0cmFjdCBqYXZheC5tYWlsLmV2ZW50Lk1haWxFdmVudAorY29ucyBwdWJsaWMgPGluaXQ+KGphdmEubGFuZy5PYmplY3QpCittZXRoIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGRpc3BhdGNoKGphdmEubGFuZy5PYmplY3QpCitzdXByIGphdmEudXRpbC5FdmVudE9iamVjdAoraGZkcyBzZXJpYWxWZXJzaW9uVUlECisKK0NMU1MgcHVibGljIGphdmF4Lm1haWwuZXZlbnQuTWVzc2FnZUNoYW5nZWRFdmVudAorY29ucyBwdWJsaWMgPGluaXQ+KGphdmEubGFuZy5PYmplY3QsaW50LGphdmF4Lm1haWwuTWVzc2FnZSkKK2ZsZCBwcm90ZWN0ZWQgaW50IHR5cGUKK2ZsZCBwcm90ZWN0ZWQgamF2YXgubWFpbC5NZXNzYWdlIG1zZworZmxkIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IEVOVkVMT1BFX0NIQU5HRUQgPSAyCitmbGQgcHVibGljIGZpbmFsIHN0YXRpYyBpbnQgRkxBR1NfQ0hBTkdFRCA9IDEKK21ldGggcHVibGljIGludCBnZXRNZXNzYWdlQ2hhbmdlVHlwZSgpCittZXRoIHB1YmxpYyBqYXZheC5tYWlsLk1lc3NhZ2UgZ2V0TWVzc2FnZSgpCittZXRoIHB1YmxpYyB2b2lkIGRpc3BhdGNoKGphdmEubGFuZy5PYmplY3QpCitzdXByIGphdmF4Lm1haWwuZXZlbnQuTWFpbEV2ZW50CitoZmRzIHNlcmlhbFZlcnNpb25VSUQKKworQ0xTUyBwdWJsaWMgYWJzdHJhY3QgaW50ZXJmYWNlIGphdmF4Lm1haWwuZXZlbnQuTWVzc2FnZUNoYW5nZWRMaXN0ZW5lcgoraW50ZiBqYXZhLnV0aWwuRXZlbnRMaXN0ZW5lcgorbWV0aCBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBtZXNzYWdlQ2hhbmdlZChqYXZheC5tYWlsLmV2ZW50Lk1lc3NhZ2VDaGFuZ2VkRXZlbnQpCisKK0NMU1MgcHVibGljIGFic3RyYWN0IGphdmF4Lm1haWwuZXZlbnQuTWVzc2FnZUNvdW50QWRhcHRlcgorY29ucyBwdWJsaWMgPGluaXQ+KCkKK2ludGYgamF2YXgubWFpbC5ldmVudC5NZXNzYWdlQ291bnRMaXN0ZW5lcgorbWV0aCBwdWJsaWMgdm9pZCBtZXNzYWdlc0FkZGVkKGphdmF4Lm1haWwuZXZlbnQuTWVzc2FnZUNvdW50RXZlbnQpCittZXRoIHB1YmxpYyB2b2lkIG1lc3NhZ2VzUmVtb3ZlZChqYXZheC5tYWlsLmV2ZW50Lk1lc3NhZ2VDb3VudEV2ZW50KQorc3VwciBqYXZhLmxhbmcuT2JqZWN0CisKK0NMU1MgcHVibGljIGphdmF4Lm1haWwuZXZlbnQuTWVzc2FnZUNvdW50RXZlbnQKK2NvbnMgcHVibGljIDxpbml0PihqYXZheC5tYWlsLkZvbGRlcixpbnQsYm9vbGVhbixqYXZheC5tYWlsLk1lc3NhZ2VbXSkKK2ZsZCBwcm90ZWN0ZWQgYm9vbGVhbiByZW1vdmVkCitmbGQgcHJvdGVjdGVkIGludCB0eXBlCitmbGQgcHJvdGVjdGVkIGphdmF4Lm1haWwuTWVzc2FnZVtdIG1zZ3MKK2ZsZCBwdWJsaWMgZmluYWwgc3RhdGljIGludCBBRERFRCA9IDEKK2ZsZCBwdWJsaWMgZmluYWwgc3RhdGljIGludCBSRU1PVkVEID0gMgorbWV0aCBwdWJsaWMgYm9vbGVhbiBpc1JlbW92ZWQoKQorbWV0aCBwdWJsaWMgaW50IGdldFR5cGUoKQorbWV0aCBwdWJsaWMgamF2YXgubWFpbC5NZXNzYWdlW10gZ2V0TWVzc2FnZXMoKQorbWV0aCBwdWJsaWMgdm9pZCBkaXNwYXRjaChqYXZhLmxhbmcuT2JqZWN0KQorc3VwciBqYXZheC5tYWlsLmV2ZW50Lk1haWxFdmVudAoraGZkcyBzZXJpYWxWZXJzaW9uVUlECisKK0NMU1MgcHVibGljIGFic3RyYWN0IGludGVyZmFjZSBqYXZheC5tYWlsLmV2ZW50Lk1lc3NhZ2VDb3VudExpc3RlbmVyCitpbnRmIGphdmEudXRpbC5FdmVudExpc3RlbmVyCittZXRoIHB1YmxpYyBhYnN0cmFjdCB2b2lkIG1lc3NhZ2VzQWRkZWQoamF2YXgubWFpbC5ldmVudC5NZXNzYWdlQ291bnRFdmVudCkKK21ldGggcHVibGljIGFic3RyYWN0IHZvaWQgbWVzc2FnZXNSZW1vdmVkKGphdmF4Lm1haWwuZXZlbnQuTWVzc2FnZUNvdW50RXZlbnQpCisKK0NMU1MgcHVibGljIGphdmF4Lm1haWwuZXZlbnQuU3RvcmVFdmVudAorY29ucyBwdWJsaWMgPGluaXQ+KGphdmF4Lm1haWwuU3RvcmUsaW50LGphdmEubGFuZy5TdHJpbmcpCitmbGQgcHJvdGVjdGVkIGludCB0eXBlCitmbGQgcHJvdGVjdGVkIGphdmEubGFuZy5TdHJpbmcgbWVzc2FnZQorZmxkIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IEFMRVJUID0gMQorZmxkIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IE5PVElDRSA9IDIKK21ldGggcHVibGljIGludCBnZXRNZXNzYWdlVHlwZSgpCittZXRoIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE1lc3NhZ2UoKQorbWV0aCBwdWJsaWMgdm9pZCBkaXNwYXRjaChqYXZhLmxhbmcuT2JqZWN0KQorc3VwciBqYXZheC5tYWlsLmV2ZW50Lk1haWxFdmVudAoraGZkcyBzZXJpYWxWZXJzaW9uVUlECisKK0NMU1MgcHVibGljIGFic3RyYWN0IGludGVyZmFjZSBqYXZheC5tYWlsLmV2ZW50LlN0b3JlTGlzdGVuZXIKK2ludGYgamF2YS51dGlsLkV2ZW50TGlzdGVuZXIKK21ldGggcHVibGljIGFic3RyYWN0IHZvaWQgbm90aWZpY2F0aW9uKGphdmF4Lm1haWwuZXZlbnQuU3RvcmVFdmVudCkKKworQ0xTUyBwdWJsaWMgYWJzdHJhY3QgamF2YXgubWFpbC5ldmVudC5UcmFuc3BvcnRBZGFwdGVyCitjb25zIHB1YmxpYyA8aW5pdD4oKQoraW50ZiBqYXZheC5tYWlsLmV2ZW50LlRyYW5zcG9ydExpc3RlbmVyCittZXRoIHB1YmxpYyB2b2lkIG1lc3NhZ2VEZWxpdmVyZWQoamF2YXgubWFpbC5ldmVudC5UcmFuc3BvcnRFdmVudCkKK21ldGggcHVibGljIHZvaWQgbWVzc2FnZU5vdERlbGl2ZXJlZChqYXZheC5tYWlsLmV2ZW50LlRyYW5zcG9ydEV2ZW50KQorbWV0aCBwdWJsaWMgdm9pZCBtZXNzYWdlUGFydGlhbGx5RGVsaXZlcmVkKGphdmF4Lm1haWwuZXZlbnQuVHJhbnNwb3J0RXZlbnQpCitzdXByIGphdmEubGFuZy5PYmplY3QKKworQ0xTUyBwdWJsaWMgamF2YXgubWFpbC5ldmVudC5UcmFuc3BvcnRFdmVudAorY29ucyBwdWJsaWMgPGluaXQ+KGphdmF4Lm1haWwuVHJhbnNwb3J0LGludCxqYXZheC5tYWlsLkFkZHJlc3NbXSxqYXZheC5tYWlsLkFkZHJlc3NbXSxqYXZheC5tYWlsLkFkZHJlc3NbXSxqYXZheC5tYWlsLk1lc3NhZ2UpCitmbGQgcHJvdGVjdGVkIGludCB0eXBlCitmbGQgcHJvdGVjdGVkIGphdmF4Lm1haWwuQWRkcmVzc1tdIGludmFsaWQKK2ZsZCBwcm90ZWN0ZWQgamF2YXgubWFpbC5BZGRyZXNzW10gdmFsaWRTZW50CitmbGQgcHJvdGVjdGVkIGphdmF4Lm1haWwuQWRkcmVzc1tdIHZhbGlkVW5zZW50CitmbGQgcHJvdGVjdGVkIGphdmF4Lm1haWwuTWVzc2FnZSBtc2cKK2ZsZCBwdWJsaWMgZmluYWwgc3RhdGljIGludCBNRVNTQUdFX0RFTElWRVJFRCA9IDEKK2ZsZCBwdWJsaWMgZmluYWwgc3RhdGljIGludCBNRVNTQUdFX05PVF9ERUxJVkVSRUQgPSAyCitmbGQgcHVibGljIGZpbmFsIHN0YXRpYyBpbnQgTUVTU0FHRV9QQVJUSUFMTFlfREVMSVZFUkVEID0gMworbWV0aCBwdWJsaWMgaW50IGdldFR5cGUoKQorbWV0aCBwdWJsaWMgamF2YXgubWFpbC5BZGRyZXNzW10gZ2V0SW52YWxpZEFkZHJlc3NlcygpCittZXRoIHB1YmxpYyBqYXZheC5tYWlsLkFkZHJlc3NbXSBnZXRWYWxpZFNlbnRBZGRyZXNzZXMoKQorbWV0aCBwdWJsaWMgamF2YXgubWFpbC5BZGRyZXNzW10gZ2V0VmFsaWRVbnNlbnRBZGRyZXNzZXMoKQorbWV0aCBwdWJsaWMgamF2YXgubWFpbC5NZXNzYWdlIGdldE1lc3NhZ2UoKQorbWV0aCBwdWJsaWMgdm9pZCBkaXNwYXRjaChqYXZhLmxhbmcuT2JqZWN0KQorc3VwciBqYXZheC5tYWlsLmV2ZW50Lk1haWxFdmVudAoraGZkcyBzZXJpYWxWZXJzaW9uVUlECisKK0NMU1MgcHVibGljIGFic3RyYWN0IGludGVyZmFjZSBqYXZheC5tYWlsLmV2ZW50LlRyYW5zcG9ydExpc3RlbmVyCitpbnRmIGphdmEudXRpbC5FdmVudExpc3RlbmVyCittZXRoIHB1YmxpYyBhYnN0cmFjdCB2b2lkIG1lc3NhZ2VEZWxpdmVyZWQoamF2YXgubWFpbC5ldmVudC5UcmFuc3BvcnRFdmVudCkKK21ldGggcHVibGljIGFic3RyYWN0IHZvaWQgbWVzc2FnZU5vdERlbGl2ZXJlZChqYXZheC5tYWlsLmV2ZW50LlRyYW5zcG9ydEV2ZW50KQorbWV0aCBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBtZXNzYWdlUGFydGlhbGx5RGVsaXZlcmVkKGphdmF4Lm1haWwuZXZlbnQuVHJhbnNwb3J0RXZlbnQpCisKK0NMU1MgcHVibGljIGphdmF4Lm1haWwuaW50ZXJuZXQuQWRkcmVzc0V4Y2VwdGlvbgorY29ucyBwdWJsaWMgPGluaXQ+KCkKK2NvbnMgcHVibGljIDxpbml0PihqYXZhLmxhbmcuU3RyaW5nKQorY29ucyBwdWJsaWMgPGluaXQ+KGphdmEubGFuZy5TdHJpbmcsamF2YS5sYW5nLlN0cmluZykKK2NvbnMgcHVibGljIDxpbml0PihqYXZhLmxhbmcuU3RyaW5nLGphdmEubGFuZy5TdHJpbmcsaW50KQorZmxkIHByb3RlY3RlZCBpbnQgcG9zCitmbGQgcHJvdGVjdGVkIGphdmEubGFuZy5TdHJpbmcgcmVmCittZXRoIHB1YmxpYyBpbnQgZ2V0UG9zKCkKK21ldGggcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVmKCkKK21ldGggcHVibGljIGphdmEubGFuZy5TdHJpbmcgdG9TdHJpbmcoKQorc3VwciBqYXZheC5tYWlsLmludGVybmV0LlBhcnNlRXhjZXB0aW9uCitoZmRzIHNlcmlhbFZlcnNpb25VSUQKKworQ0xTUyBwdWJsaWMgamF2YXgubWFpbC5pbnRlcm5ldC5Db250ZW50RGlzcG9zaXRpb24KK2NvbnMgcHVibGljIDxpbml0PigpCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YS5sYW5nLlN0cmluZykgdGhyb3dzIGphdmF4Lm1haWwuaW50ZXJuZXQuUGFyc2VFeGNlcHRpb24KK2NvbnMgcHVibGljIDxpbml0PihqYXZhLmxhbmcuU3RyaW5nLGphdmF4Lm1haWwuaW50ZXJuZXQuUGFyYW1ldGVyTGlzdCkKK21ldGggcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RGlzcG9zaXRpb24oKQorbWV0aCBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRQYXJhbWV0ZXIoamF2YS5sYW5nLlN0cmluZykKK21ldGggcHVibGljIGphdmEubGFuZy5TdHJpbmcgdG9TdHJpbmcoKQorbWV0aCBwdWJsaWMgamF2YXgubWFpbC5pbnRlcm5ldC5QYXJhbWV0ZXJMaXN0IGdldFBhcmFtZXRlckxpc3QoKQorbWV0aCBwdWJsaWMgdm9pZCBzZXREaXNwb3NpdGlvbihqYXZhLmxhbmcuU3RyaW5nKQorbWV0aCBwdWJsaWMgdm9pZCBzZXRQYXJhbWV0ZXIoamF2YS5sYW5nLlN0cmluZyxqYXZhLmxhbmcuU3RyaW5nKQorbWV0aCBwdWJsaWMgdm9pZCBzZXRQYXJhbWV0ZXJMaXN0KGphdmF4Lm1haWwuaW50ZXJuZXQuUGFyYW1ldGVyTGlzdCkKK3N1cHIgamF2YS5sYW5nLk9iamVjdAoraGZkcyBkaXNwb3NpdGlvbixsaXN0CisKK0NMU1MgcHVibGljIGphdmF4Lm1haWwuaW50ZXJuZXQuQ29udGVudFR5cGUKK2NvbnMgcHVibGljIDxpbml0PigpCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YS5sYW5nLlN0cmluZykgdGhyb3dzIGphdmF4Lm1haWwuaW50ZXJuZXQuUGFyc2VFeGNlcHRpb24KK2NvbnMgcHVibGljIDxpbml0PihqYXZhLmxhbmcuU3RyaW5nLGphdmEubGFuZy5TdHJpbmcsamF2YXgubWFpbC5pbnRlcm5ldC5QYXJhbWV0ZXJMaXN0KQorbWV0aCBwdWJsaWMgYm9vbGVhbiBtYXRjaChqYXZhLmxhbmcuU3RyaW5nKQorbWV0aCBwdWJsaWMgYm9vbGVhbiBtYXRjaChqYXZheC5tYWlsLmludGVybmV0LkNvbnRlbnRUeXBlKQorbWV0aCBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRCYXNlVHlwZSgpCittZXRoIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFBhcmFtZXRlcihqYXZhLmxhbmcuU3RyaW5nKQorbWV0aCBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRQcmltYXJ5VHlwZSgpCittZXRoIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFN1YlR5cGUoKQorbWV0aCBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyB0b1N0cmluZygpCittZXRoIHB1YmxpYyBqYXZheC5tYWlsLmludGVybmV0LlBhcmFtZXRlckxpc3QgZ2V0UGFyYW1ldGVyTGlzdCgpCittZXRoIHB1YmxpYyB2b2lkIHNldFBhcmFtZXRlcihqYXZhLmxhbmcuU3RyaW5nLGphdmEubGFuZy5TdHJpbmcpCittZXRoIHB1YmxpYyB2b2lkIHNldFBhcmFtZXRlckxpc3QoamF2YXgubWFpbC5pbnRlcm5ldC5QYXJhbWV0ZXJMaXN0KQorbWV0aCBwdWJsaWMgdm9pZCBzZXRQcmltYXJ5VHlwZShqYXZhLmxhbmcuU3RyaW5nKQorbWV0aCBwdWJsaWMgdm9pZCBzZXRTdWJUeXBlKGphdmEubGFuZy5TdHJpbmcpCitzdXByIGphdmEubGFuZy5PYmplY3QKK2hmZHMgbGlzdCxwcmltYXJ5VHlwZSxzdWJUeXBlCisKK0NMU1MgcHVibGljIGphdmF4Lm1haWwuaW50ZXJuZXQuSGVhZGVyVG9rZW5pemVyCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YS5sYW5nLlN0cmluZykKK2NvbnMgcHVibGljIDxpbml0PihqYXZhLmxhbmcuU3RyaW5nLGphdmEubGFuZy5TdHJpbmcpCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YS5sYW5nLlN0cmluZyxqYXZhLmxhbmcuU3RyaW5nLGJvb2xlYW4pCitmbGQgcHVibGljIGZpbmFsIHN0YXRpYyBqYXZhLmxhbmcuU3RyaW5nIE1JTUUgPSAiKCk8PkAsOzpcdTAwNWNcdTAwMjJcdTAwMDkgW10vPz0iCitmbGQgcHVibGljIGZpbmFsIHN0YXRpYyBqYXZhLmxhbmcuU3RyaW5nIFJGQzgyMiA9ICIoKTw+QCw7Olx1MDA1Y1x1MDAyMlx1MDAwOSAuW10iCitpbm5yIHB1YmxpYyBzdGF0aWMgVG9rZW4KK21ldGggcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVtYWluZGVyKCkKK21ldGggcHVibGljIGphdmF4Lm1haWwuaW50ZXJuZXQuSGVhZGVyVG9rZW5pemVyJFRva2VuIG5leHQoKSB0aHJvd3MgamF2YXgubWFpbC5pbnRlcm5ldC5QYXJzZUV4Y2VwdGlvbgorbWV0aCBwdWJsaWMgamF2YXgubWFpbC5pbnRlcm5ldC5IZWFkZXJUb2tlbml6ZXIkVG9rZW4gbmV4dChjaGFyKSB0aHJvd3MgamF2YXgubWFpbC5pbnRlcm5ldC5QYXJzZUV4Y2VwdGlvbgorbWV0aCBwdWJsaWMgamF2YXgubWFpbC5pbnRlcm5ldC5IZWFkZXJUb2tlbml6ZXIkVG9rZW4gbmV4dChjaGFyLGJvb2xlYW4pIHRocm93cyBqYXZheC5tYWlsLmludGVybmV0LlBhcnNlRXhjZXB0aW9uCittZXRoIHB1YmxpYyBqYXZheC5tYWlsLmludGVybmV0LkhlYWRlclRva2VuaXplciRUb2tlbiBwZWVrKCkgdGhyb3dzIGphdmF4Lm1haWwuaW50ZXJuZXQuUGFyc2VFeGNlcHRpb24KK3N1cHIgamF2YS5sYW5nLk9iamVjdAoraGZkcyBFT0ZUb2tlbixjdXJyZW50UG9zLGRlbGltaXRlcnMsbWF4UG9zLG5leHRQb3MscGVla1Bvcyxza2lwQ29tbWVudHMsc3RyaW5nCisKK0NMU1MgcHVibGljIHN0YXRpYyBqYXZheC5tYWlsLmludGVybmV0LkhlYWRlclRva2VuaXplciRUb2tlbgorIG91dGVyIGphdmF4Lm1haWwuaW50ZXJuZXQuSGVhZGVyVG9rZW5pemVyCitjb25zIHB1YmxpYyA8aW5pdD4oaW50LGphdmEubGFuZy5TdHJpbmcpCitmbGQgcHVibGljIGZpbmFsIHN0YXRpYyBpbnQgQVRPTSA9IC0xCitmbGQgcHVibGljIGZpbmFsIHN0YXRpYyBpbnQgQ09NTUVOVCA9IC0zCitmbGQgcHVibGljIGZpbmFsIHN0YXRpYyBpbnQgRU9GID0gLTQKK2ZsZCBwdWJsaWMgZmluYWwgc3RhdGljIGludCBRVU9URURTVFJJTkcgPSAtMgorbWV0aCBwdWJsaWMgaW50IGdldFR5cGUoKQorbWV0aCBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRWYWx1ZSgpCitzdXByIGphdmEubGFuZy5PYmplY3QKK2hmZHMgdHlwZSx2YWx1ZQorCitDTFNTIHB1YmxpYyBqYXZheC5tYWlsLmludGVybmV0LkludGVybmV0QWRkcmVzcworY29ucyBwdWJsaWMgPGluaXQ+KCkKK2NvbnMgcHVibGljIDxpbml0PihqYXZhLmxhbmcuU3RyaW5nKSB0aHJvd3MgamF2YXgubWFpbC5pbnRlcm5ldC5BZGRyZXNzRXhjZXB0aW9uCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YS5sYW5nLlN0cmluZyxib29sZWFuKSB0aHJvd3MgamF2YXgubWFpbC5pbnRlcm5ldC5BZGRyZXNzRXhjZXB0aW9uCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YS5sYW5nLlN0cmluZyxqYXZhLmxhbmcuU3RyaW5nKSB0aHJvd3MgamF2YS5pby5VbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YS5sYW5nLlN0cmluZyxqYXZhLmxhbmcuU3RyaW5nLGphdmEubGFuZy5TdHJpbmcpIHRocm93cyBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24KK2ZsZCBwcm90ZWN0ZWQgamF2YS5sYW5nLlN0cmluZyBhZGRyZXNzCitmbGQgcHJvdGVjdGVkIGphdmEubGFuZy5TdHJpbmcgZW5jb2RlZFBlcnNvbmFsCitmbGQgcHJvdGVjdGVkIGphdmEubGFuZy5TdHJpbmcgcGVyc29uYWwKK2ludGYgamF2YS5sYW5nLkNsb25lYWJsZQorbWV0aCBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoamF2YS5sYW5nLk9iamVjdCkKK21ldGggcHVibGljIGJvb2xlYW4gaXNHcm91cCgpCittZXRoIHB1YmxpYyBpbnQgaGFzaENvZGUoKQorbWV0aCBwdWJsaWMgamF2YS5sYW5nLk9iamVjdCBjbG9uZSgpCittZXRoIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEFkZHJlc3MoKQorbWV0aCBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRQZXJzb25hbCgpCittZXRoIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFR5cGUoKQorbWV0aCBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyB0b1N0cmluZygpCittZXRoIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIHRvVW5pY29kZVN0cmluZygpCittZXRoIHB1YmxpYyBqYXZheC5tYWlsLmludGVybmV0LkludGVybmV0QWRkcmVzc1tdIGdldEdyb3VwKGJvb2xlYW4pIHRocm93cyBqYXZheC5tYWlsLmludGVybmV0LkFkZHJlc3NFeGNlcHRpb24KK21ldGggcHVibGljIHN0YXRpYyBqYXZhLmxhbmcuU3RyaW5nIHRvU3RyaW5nKGphdmF4Lm1haWwuQWRkcmVzc1tdKQorbWV0aCBwdWJsaWMgc3RhdGljIGphdmEubGFuZy5TdHJpbmcgdG9TdHJpbmcoamF2YXgubWFpbC5BZGRyZXNzW10saW50KQorbWV0aCBwdWJsaWMgc3RhdGljIGphdmEubGFuZy5TdHJpbmcgdG9Vbmljb2RlU3RyaW5nKGphdmF4Lm1haWwuQWRkcmVzc1tdKQorbWV0aCBwdWJsaWMgc3RhdGljIGphdmEubGFuZy5TdHJpbmcgdG9Vbmljb2RlU3RyaW5nKGphdmF4Lm1haWwuQWRkcmVzc1tdLGludCkKK21ldGggcHVibGljIHN0YXRpYyBqYXZheC5tYWlsLmludGVybmV0LkludGVybmV0QWRkcmVzcyBnZXRMb2NhbEFkZHJlc3MoamF2YXgubWFpbC5TZXNzaW9uKQorbWV0aCBwdWJsaWMgc3RhdGljIGphdmF4Lm1haWwuaW50ZXJuZXQuSW50ZXJuZXRBZGRyZXNzW10gcGFyc2UoamF2YS5sYW5nLlN0cmluZykgdGhyb3dzIGphdmF4Lm1haWwuaW50ZXJuZXQuQWRkcmVzc0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgc3RhdGljIGphdmF4Lm1haWwuaW50ZXJuZXQuSW50ZXJuZXRBZGRyZXNzW10gcGFyc2UoamF2YS5sYW5nLlN0cmluZyxib29sZWFuKSB0aHJvd3MgamF2YXgubWFpbC5pbnRlcm5ldC5BZGRyZXNzRXhjZXB0aW9uCittZXRoIHB1YmxpYyBzdGF0aWMgamF2YXgubWFpbC5pbnRlcm5ldC5JbnRlcm5ldEFkZHJlc3NbXSBwYXJzZUhlYWRlcihqYXZhLmxhbmcuU3RyaW5nLGJvb2xlYW4pIHRocm93cyBqYXZheC5tYWlsLmludGVybmV0LkFkZHJlc3NFeGNlcHRpb24KK21ldGggcHVibGljIHZvaWQgc2V0QWRkcmVzcyhqYXZhLmxhbmcuU3RyaW5nKQorbWV0aCBwdWJsaWMgdm9pZCBzZXRQZXJzb25hbChqYXZhLmxhbmcuU3RyaW5nKSB0aHJvd3MgamF2YS5pby5VbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyB2b2lkIHNldFBlcnNvbmFsKGphdmEubGFuZy5TdHJpbmcsamF2YS5sYW5nLlN0cmluZykgdGhyb3dzIGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgdm9pZCB2YWxpZGF0ZSgpIHRocm93cyBqYXZheC5tYWlsLmludGVybmV0LkFkZHJlc3NFeGNlcHRpb24KK3N1cHIgamF2YXgubWFpbC5BZGRyZXNzCitoZmRzIGFsbG93VXRmOCxpZ25vcmVCb2d1c0dyb3VwTmFtZSxyZmM4MjJwaHJhc2Usc2VyaWFsVmVyc2lvblVJRCxzcGVjaWFsc05vRG90LHNwZWNpYWxzTm9Eb3ROb0F0LHVzZUNhbm9uaWNhbEhvc3ROYW1lCisKK0NMU1MgcHVibGljIGphdmF4Lm1haWwuaW50ZXJuZXQuSW50ZXJuZXRIZWFkZXJzCitjb25zIHB1YmxpYyA8aW5pdD4oKQorY29ucyBwdWJsaWMgPGluaXQ+KGphdmEuaW8uSW5wdXRTdHJlYW0pIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorY29ucyBwdWJsaWMgPGluaXQ+KGphdmEuaW8uSW5wdXRTdHJlYW0sYm9vbGVhbikgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCitmbGQgcHJvdGVjdGVkIGphdmEudXRpbC5MaXN0PGphdmF4Lm1haWwuaW50ZXJuZXQuSW50ZXJuZXRIZWFkZXJzJEludGVybmV0SGVhZGVyPiBoZWFkZXJzCitpbm5yIHByb3RlY3RlZCBmaW5hbCBzdGF0aWMgSW50ZXJuZXRIZWFkZXIKK21ldGggcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0SGVhZGVyKGphdmEubGFuZy5TdHJpbmcsamF2YS5sYW5nLlN0cmluZykKK21ldGggcHVibGljIGphdmEubGFuZy5TdHJpbmdbXSBnZXRIZWFkZXIoamF2YS5sYW5nLlN0cmluZykKK21ldGggcHVibGljIGphdmEudXRpbC5FbnVtZXJhdGlvbjxqYXZhLmxhbmcuU3RyaW5nPiBnZXRBbGxIZWFkZXJMaW5lcygpCittZXRoIHB1YmxpYyBqYXZhLnV0aWwuRW51bWVyYXRpb248amF2YS5sYW5nLlN0cmluZz4gZ2V0TWF0Y2hpbmdIZWFkZXJMaW5lcyhqYXZhLmxhbmcuU3RyaW5nW10pCittZXRoIHB1YmxpYyBqYXZhLnV0aWwuRW51bWVyYXRpb248amF2YS5sYW5nLlN0cmluZz4gZ2V0Tm9uTWF0Y2hpbmdIZWFkZXJMaW5lcyhqYXZhLmxhbmcuU3RyaW5nW10pCittZXRoIHB1YmxpYyBqYXZhLnV0aWwuRW51bWVyYXRpb248amF2YXgubWFpbC5IZWFkZXI+IGdldEFsbEhlYWRlcnMoKQorbWV0aCBwdWJsaWMgamF2YS51dGlsLkVudW1lcmF0aW9uPGphdmF4Lm1haWwuSGVhZGVyPiBnZXRNYXRjaGluZ0hlYWRlcnMoamF2YS5sYW5nLlN0cmluZ1tdKQorbWV0aCBwdWJsaWMgamF2YS51dGlsLkVudW1lcmF0aW9uPGphdmF4Lm1haWwuSGVhZGVyPiBnZXROb25NYXRjaGluZ0hlYWRlcnMoamF2YS5sYW5nLlN0cmluZ1tdKQorbWV0aCBwdWJsaWMgdm9pZCBhZGRIZWFkZXIoamF2YS5sYW5nLlN0cmluZyxqYXZhLmxhbmcuU3RyaW5nKQorbWV0aCBwdWJsaWMgdm9pZCBhZGRIZWFkZXJMaW5lKGphdmEubGFuZy5TdHJpbmcpCittZXRoIHB1YmxpYyB2b2lkIGxvYWQoamF2YS5pby5JbnB1dFN0cmVhbSkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyB2b2lkIGxvYWQoamF2YS5pby5JbnB1dFN0cmVhbSxib29sZWFuKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIHZvaWQgcmVtb3ZlSGVhZGVyKGphdmEubGFuZy5TdHJpbmcpCittZXRoIHB1YmxpYyB2b2lkIHNldEhlYWRlcihqYXZhLmxhbmcuU3RyaW5nLGphdmEubGFuZy5TdHJpbmcpCitzdXByIGphdmEubGFuZy5PYmplY3QKK2hmZHMgaWdub3JlV2hpdGVzcGFjZUxpbmVzCitoY2xzIE1hdGNoRW51bSxNYXRjaEhlYWRlckVudW0sTWF0Y2hTdHJpbmdFbnVtCisKK0NMU1MgcHJvdGVjdGVkIGZpbmFsIHN0YXRpYyBqYXZheC5tYWlsLmludGVybmV0LkludGVybmV0SGVhZGVycyRJbnRlcm5ldEhlYWRlcgorIG91dGVyIGphdmF4Lm1haWwuaW50ZXJuZXQuSW50ZXJuZXRIZWFkZXJzCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YS5sYW5nLlN0cmluZykKK2NvbnMgcHVibGljIDxpbml0PihqYXZhLmxhbmcuU3RyaW5nLGphdmEubGFuZy5TdHJpbmcpCittZXRoIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFZhbHVlKCkKK3N1cHIgamF2YXgubWFpbC5IZWFkZXIKK2hmZHMgbGluZQorCitDTFNTIHB1YmxpYyBqYXZheC5tYWlsLmludGVybmV0Lk1haWxEYXRlRm9ybWF0Citjb25zIHB1YmxpYyA8aW5pdD4oKQorbWV0aCBwdWJsaWMgamF2YS5sYW5nLlN0cmluZ0J1ZmZlciBmb3JtYXQoamF2YS51dGlsLkRhdGUsamF2YS5sYW5nLlN0cmluZ0J1ZmZlcixqYXZhLnRleHQuRmllbGRQb3NpdGlvbikKK21ldGggcHVibGljIGphdmEudXRpbC5EYXRlIGdldDJEaWdpdFllYXJTdGFydCgpCittZXRoIHB1YmxpYyBqYXZhLnV0aWwuRGF0ZSBwYXJzZShqYXZhLmxhbmcuU3RyaW5nLGphdmEudGV4dC5QYXJzZVBvc2l0aW9uKQorbWV0aCBwdWJsaWMgamF2YXgubWFpbC5pbnRlcm5ldC5NYWlsRGF0ZUZvcm1hdCBjbG9uZSgpCittZXRoIHB1YmxpYyB2b2lkIGFwcGx5TG9jYWxpemVkUGF0dGVybihqYXZhLmxhbmcuU3RyaW5nKQorbWV0aCBwdWJsaWMgdm9pZCBhcHBseVBhdHRlcm4oamF2YS5sYW5nLlN0cmluZykKK21ldGggcHVibGljIHZvaWQgc2V0MkRpZ2l0WWVhclN0YXJ0KGphdmEudXRpbC5EYXRlKQorbWV0aCBwdWJsaWMgdm9pZCBzZXRDYWxlbmRhcihqYXZhLnV0aWwuQ2FsZW5kYXIpCittZXRoIHB1YmxpYyB2b2lkIHNldERhdGVGb3JtYXRTeW1ib2xzKGphdmEudGV4dC5EYXRlRm9ybWF0U3ltYm9scykKK21ldGggcHVibGljIHZvaWQgc2V0TnVtYmVyRm9ybWF0KGphdmEudGV4dC5OdW1iZXJGb3JtYXQpCitzdXByIGphdmEudGV4dC5TaW1wbGVEYXRlRm9ybWF0CitoZmRzIExFQVBfU0VDT05ELExPR0dFUixQQVRURVJOLFVOS05PV05fREFZX05BTUUsVVRDLHNlcmlhbFZlcnNpb25VSUQKK2hjbHMgQWJzdHJhY3REYXRlUGFyc2VyLFJmYzI4MjJMZW5pZW50UGFyc2VyLFJmYzI4MjJTdHJpY3RQYXJzZXIKKworQ0xTUyBwdWJsaWMgamF2YXgubWFpbC5pbnRlcm5ldC5NaW1lQm9keVBhcnQKK2NvbnMgcHVibGljIDxpbml0PigpCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YS5pby5JbnB1dFN0cmVhbSkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YXgubWFpbC5pbnRlcm5ldC5JbnRlcm5ldEhlYWRlcnMsYnl0ZVtdKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK2ZsZCBwcm90ZWN0ZWQgYnl0ZVtdIGNvbnRlbnQKK2ZsZCBwcm90ZWN0ZWQgamF2YS5pby5JbnB1dFN0cmVhbSBjb250ZW50U3RyZWFtCitmbGQgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgY2FjaGVkQ29udGVudAorZmxkIHByb3RlY3RlZCBqYXZheC5hY3RpdmF0aW9uLkRhdGFIYW5kbGVyIGRoCitmbGQgcHJvdGVjdGVkIGphdmF4Lm1haWwuaW50ZXJuZXQuSW50ZXJuZXRIZWFkZXJzIGhlYWRlcnMKK2ludGYgamF2YXgubWFpbC5pbnRlcm5ldC5NaW1lUGFydAorbWV0aCBwcm90ZWN0ZWQgamF2YS5pby5JbnB1dFN0cmVhbSBnZXRDb250ZW50U3RyZWFtKCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHByb3RlY3RlZCB2b2lkIHVwZGF0ZUhlYWRlcnMoKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGJvb2xlYW4gaXNNaW1lVHlwZShqYXZhLmxhbmcuU3RyaW5nKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGludCBnZXRMaW5lQ291bnQoKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGludCBnZXRTaXplKCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBqYXZhLmlvLklucHV0U3RyZWFtIGdldElucHV0U3RyZWFtKCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24samF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGphdmEuaW8uSW5wdXRTdHJlYW0gZ2V0UmF3SW5wdXRTdHJlYW0oKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGphdmEubGFuZy5PYmplY3QgZ2V0Q29udGVudCgpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uLGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldENvbnRlbnRJRCgpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRDb250ZW50TUQ1KCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldENvbnRlbnRUeXBlKCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldERlc2NyaXB0aW9uKCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldERpc3Bvc2l0aW9uKCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEVuY29kaW5nKCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpbGVOYW1lKCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEhlYWRlcihqYXZhLmxhbmcuU3RyaW5nLGphdmEubGFuZy5TdHJpbmcpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgamF2YS5sYW5nLlN0cmluZ1tdIGdldENvbnRlbnRMYW5ndWFnZSgpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgamF2YS5sYW5nLlN0cmluZ1tdIGdldEhlYWRlcihqYXZhLmxhbmcuU3RyaW5nKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGphdmEudXRpbC5FbnVtZXJhdGlvbjxqYXZhLmxhbmcuU3RyaW5nPiBnZXRBbGxIZWFkZXJMaW5lcygpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgamF2YS51dGlsLkVudW1lcmF0aW9uPGphdmEubGFuZy5TdHJpbmc+IGdldE1hdGNoaW5nSGVhZGVyTGluZXMoamF2YS5sYW5nLlN0cmluZ1tdKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGphdmEudXRpbC5FbnVtZXJhdGlvbjxqYXZhLmxhbmcuU3RyaW5nPiBnZXROb25NYXRjaGluZ0hlYWRlckxpbmVzKGphdmEubGFuZy5TdHJpbmdbXSkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBqYXZhLnV0aWwuRW51bWVyYXRpb248amF2YXgubWFpbC5IZWFkZXI+IGdldEFsbEhlYWRlcnMoKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGphdmEudXRpbC5FbnVtZXJhdGlvbjxqYXZheC5tYWlsLkhlYWRlcj4gZ2V0TWF0Y2hpbmdIZWFkZXJzKGphdmEubGFuZy5TdHJpbmdbXSkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBqYXZhLnV0aWwuRW51bWVyYXRpb248amF2YXgubWFpbC5IZWFkZXI+IGdldE5vbk1hdGNoaW5nSGVhZGVycyhqYXZhLmxhbmcuU3RyaW5nW10pIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgamF2YXguYWN0aXZhdGlvbi5EYXRhSGFuZGxlciBnZXREYXRhSGFuZGxlcigpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgdm9pZCBhZGRIZWFkZXIoamF2YS5sYW5nLlN0cmluZyxqYXZhLmxhbmcuU3RyaW5nKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIHZvaWQgYWRkSGVhZGVyTGluZShqYXZhLmxhbmcuU3RyaW5nKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIHZvaWQgYXR0YWNoRmlsZShqYXZhLmlvLkZpbGUpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uLGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyB2b2lkIGF0dGFjaEZpbGUoamF2YS5pby5GaWxlLGphdmEubGFuZy5TdHJpbmcsamF2YS5sYW5nLlN0cmluZykgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24samF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIHZvaWQgYXR0YWNoRmlsZShqYXZhLmxhbmcuU3RyaW5nKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbixqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgdm9pZCBhdHRhY2hGaWxlKGphdmEubGFuZy5TdHJpbmcsamF2YS5sYW5nLlN0cmluZyxqYXZhLmxhbmcuU3RyaW5nKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbixqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgdm9pZCByZW1vdmVIZWFkZXIoamF2YS5sYW5nLlN0cmluZykgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyB2b2lkIHNhdmVGaWxlKGphdmEuaW8uRmlsZSkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24samF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIHZvaWQgc2F2ZUZpbGUoamF2YS5sYW5nLlN0cmluZykgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24samF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIHZvaWQgc2V0Q29udGVudChqYXZhLmxhbmcuT2JqZWN0LGphdmEubGFuZy5TdHJpbmcpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgdm9pZCBzZXRDb250ZW50KGphdmF4Lm1haWwuTXVsdGlwYXJ0KSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIHZvaWQgc2V0Q29udGVudElEKGphdmEubGFuZy5TdHJpbmcpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgdm9pZCBzZXRDb250ZW50TGFuZ3VhZ2UoamF2YS5sYW5nLlN0cmluZ1tdKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIHZvaWQgc2V0Q29udGVudE1ENShqYXZhLmxhbmcuU3RyaW5nKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIHZvaWQgc2V0RGF0YUhhbmRsZXIoamF2YXguYWN0aXZhdGlvbi5EYXRhSGFuZGxlcikgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyB2b2lkIHNldERlc2NyaXB0aW9uKGphdmEubGFuZy5TdHJpbmcpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgdm9pZCBzZXREZXNjcmlwdGlvbihqYXZhLmxhbmcuU3RyaW5nLGphdmEubGFuZy5TdHJpbmcpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgdm9pZCBzZXREaXNwb3NpdGlvbihqYXZhLmxhbmcuU3RyaW5nKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIHZvaWQgc2V0RmlsZU5hbWUoamF2YS5sYW5nLlN0cmluZykgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyB2b2lkIHNldEhlYWRlcihqYXZhLmxhbmcuU3RyaW5nLGphdmEubGFuZy5TdHJpbmcpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgdm9pZCBzZXRUZXh0KGphdmEubGFuZy5TdHJpbmcpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgdm9pZCBzZXRUZXh0KGphdmEubGFuZy5TdHJpbmcsamF2YS5sYW5nLlN0cmluZykgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyB2b2lkIHNldFRleHQoamF2YS5sYW5nLlN0cmluZyxqYXZhLmxhbmcuU3RyaW5nLGphdmEubGFuZy5TdHJpbmcpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgdm9pZCB3cml0ZVRvKGphdmEuaW8uT3V0cHV0U3RyZWFtKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbixqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorc3VwciBqYXZheC5tYWlsLkJvZHlQYXJ0CitoZmRzIGFsbG93dXRmOCxjYWNoZU11bHRpcGFydCxkZWNvZGVGaWxlTmFtZSxlbmNvZGVGaWxlTmFtZSxpZ25vcmVNdWx0aXBhcnRFbmNvZGluZyxzZXRDb250ZW50VHlwZUZpbGVOYW1lLHNldERlZmF1bHRUZXh0Q2hhcnNldAoraGNscyBFbmNvZGVkRmlsZURhdGFTb3VyY2UsTWltZVBhcnREYXRhSGFuZGxlcgorCitDTFNTIHB1YmxpYyBqYXZheC5tYWlsLmludGVybmV0Lk1pbWVNZXNzYWdlCitjb25zIHByb3RlY3RlZCA8aW5pdD4oamF2YXgubWFpbC5Gb2xkZXIsaW50KQorY29ucyBwcm90ZWN0ZWQgPGluaXQ+KGphdmF4Lm1haWwuRm9sZGVyLGphdmEuaW8uSW5wdXRTdHJlYW0saW50KSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK2NvbnMgcHJvdGVjdGVkIDxpbml0PihqYXZheC5tYWlsLkZvbGRlcixqYXZheC5tYWlsLmludGVybmV0LkludGVybmV0SGVhZGVycyxieXRlW10saW50KSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK2NvbnMgcHVibGljIDxpbml0PihqYXZheC5tYWlsLlNlc3Npb24pCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YXgubWFpbC5TZXNzaW9uLGphdmEuaW8uSW5wdXRTdHJlYW0pIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorY29ucyBwdWJsaWMgPGluaXQ+KGphdmF4Lm1haWwuaW50ZXJuZXQuTWltZU1lc3NhZ2UpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorZmxkIHByb3RlY3RlZCBib29sZWFuIG1vZGlmaWVkCitmbGQgcHJvdGVjdGVkIGJvb2xlYW4gc2F2ZWQKK2ZsZCBwcm90ZWN0ZWQgYnl0ZVtdIGNvbnRlbnQKK2ZsZCBwcm90ZWN0ZWQgamF2YS5pby5JbnB1dFN0cmVhbSBjb250ZW50U3RyZWFtCitmbGQgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgY2FjaGVkQ29udGVudAorZmxkIHByb3RlY3RlZCBqYXZheC5hY3RpdmF0aW9uLkRhdGFIYW5kbGVyIGRoCitmbGQgcHJvdGVjdGVkIGphdmF4Lm1haWwuRmxhZ3MgZmxhZ3MKK2ZsZCBwcm90ZWN0ZWQgamF2YXgubWFpbC5pbnRlcm5ldC5JbnRlcm5ldEhlYWRlcnMgaGVhZGVycworaW5uciBwdWJsaWMgc3RhdGljIFJlY2lwaWVudFR5cGUKK2ludGYgamF2YXgubWFpbC5pbnRlcm5ldC5NaW1lUGFydAorbWV0aCBwcm90ZWN0ZWQgamF2YS5pby5JbnB1dFN0cmVhbSBnZXRDb250ZW50U3RyZWFtKCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHByb3RlY3RlZCBqYXZheC5tYWlsLmludGVybmV0LkludGVybmV0SGVhZGVycyBjcmVhdGVJbnRlcm5ldEhlYWRlcnMoamF2YS5pby5JbnB1dFN0cmVhbSkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHByb3RlY3RlZCBqYXZheC5tYWlsLmludGVybmV0Lk1pbWVNZXNzYWdlIGNyZWF0ZU1pbWVNZXNzYWdlKGphdmF4Lm1haWwuU2Vzc2lvbikgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHByb3RlY3RlZCB2b2lkIHBhcnNlKGphdmEuaW8uSW5wdXRTdHJlYW0pIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwcm90ZWN0ZWQgdm9pZCB1cGRhdGVIZWFkZXJzKCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHByb3RlY3RlZCB2b2lkIHVwZGF0ZU1lc3NhZ2VJRCgpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgYm9vbGVhbiBpc01pbWVUeXBlKGphdmEubGFuZy5TdHJpbmcpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgYm9vbGVhbiBpc1NldChqYXZheC5tYWlsLkZsYWdzJEZsYWcpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgaW50IGdldExpbmVDb3VudCgpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgaW50IGdldFNpemUoKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGphdmEuaW8uSW5wdXRTdHJlYW0gZ2V0SW5wdXRTdHJlYW0oKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbixqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgamF2YS5pby5JbnB1dFN0cmVhbSBnZXRSYXdJbnB1dFN0cmVhbSgpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgamF2YS5sYW5nLk9iamVjdCBnZXRDb250ZW50KCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24samF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0Q29udGVudElEKCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldENvbnRlbnRNRDUoKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0Q29udGVudFR5cGUoKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RGVzY3JpcHRpb24oKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RGlzcG9zaXRpb24oKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RW5jb2RpbmcoKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmlsZU5hbWUoKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0SGVhZGVyKGphdmEubGFuZy5TdHJpbmcsamF2YS5sYW5nLlN0cmluZykgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE1lc3NhZ2VJRCgpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTdWJqZWN0KCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nW10gZ2V0Q29udGVudExhbmd1YWdlKCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nW10gZ2V0SGVhZGVyKGphdmEubGFuZy5TdHJpbmcpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgamF2YS51dGlsLkRhdGUgZ2V0UmVjZWl2ZWREYXRlKCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBqYXZhLnV0aWwuRGF0ZSBnZXRTZW50RGF0ZSgpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgamF2YS51dGlsLkVudW1lcmF0aW9uPGphdmEubGFuZy5TdHJpbmc+IGdldEFsbEhlYWRlckxpbmVzKCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBqYXZhLnV0aWwuRW51bWVyYXRpb248amF2YS5sYW5nLlN0cmluZz4gZ2V0TWF0Y2hpbmdIZWFkZXJMaW5lcyhqYXZhLmxhbmcuU3RyaW5nW10pIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgamF2YS51dGlsLkVudW1lcmF0aW9uPGphdmEubGFuZy5TdHJpbmc+IGdldE5vbk1hdGNoaW5nSGVhZGVyTGluZXMoamF2YS5sYW5nLlN0cmluZ1tdKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGphdmEudXRpbC5FbnVtZXJhdGlvbjxqYXZheC5tYWlsLkhlYWRlcj4gZ2V0QWxsSGVhZGVycygpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgamF2YS51dGlsLkVudW1lcmF0aW9uPGphdmF4Lm1haWwuSGVhZGVyPiBnZXRNYXRjaGluZ0hlYWRlcnMoamF2YS5sYW5nLlN0cmluZ1tdKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGphdmEudXRpbC5FbnVtZXJhdGlvbjxqYXZheC5tYWlsLkhlYWRlcj4gZ2V0Tm9uTWF0Y2hpbmdIZWFkZXJzKGphdmEubGFuZy5TdHJpbmdbXSkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBqYXZheC5hY3RpdmF0aW9uLkRhdGFIYW5kbGVyIGdldERhdGFIYW5kbGVyKCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBqYXZheC5tYWlsLkFkZHJlc3MgZ2V0U2VuZGVyKCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBqYXZheC5tYWlsLkFkZHJlc3NbXSBnZXRBbGxSZWNpcGllbnRzKCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBqYXZheC5tYWlsLkFkZHJlc3NbXSBnZXRGcm9tKCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBqYXZheC5tYWlsLkFkZHJlc3NbXSBnZXRSZWNpcGllbnRzKGphdmF4Lm1haWwuTWVzc2FnZSRSZWNpcGllbnRUeXBlKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGphdmF4Lm1haWwuQWRkcmVzc1tdIGdldFJlcGx5VG8oKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGphdmF4Lm1haWwuRmxhZ3MgZ2V0RmxhZ3MoKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGphdmF4Lm1haWwuTWVzc2FnZSByZXBseShib29sZWFuKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGphdmF4Lm1haWwuTWVzc2FnZSByZXBseShib29sZWFuLGJvb2xlYW4pIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgdm9pZCBhZGRGcm9tKGphdmF4Lm1haWwuQWRkcmVzc1tdKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIHZvaWQgYWRkSGVhZGVyKGphdmEubGFuZy5TdHJpbmcsamF2YS5sYW5nLlN0cmluZykgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyB2b2lkIGFkZEhlYWRlckxpbmUoamF2YS5sYW5nLlN0cmluZykgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyB2b2lkIGFkZFJlY2lwaWVudHMoamF2YXgubWFpbC5NZXNzYWdlJFJlY2lwaWVudFR5cGUsamF2YS5sYW5nLlN0cmluZykgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyB2b2lkIGFkZFJlY2lwaWVudHMoamF2YXgubWFpbC5NZXNzYWdlJFJlY2lwaWVudFR5cGUsamF2YXgubWFpbC5BZGRyZXNzW10pIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgdm9pZCByZW1vdmVIZWFkZXIoamF2YS5sYW5nLlN0cmluZykgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyB2b2lkIHNhdmVDaGFuZ2VzKCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyB2b2lkIHNldENvbnRlbnQoamF2YS5sYW5nLk9iamVjdCxqYXZhLmxhbmcuU3RyaW5nKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIHZvaWQgc2V0Q29udGVudChqYXZheC5tYWlsLk11bHRpcGFydCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyB2b2lkIHNldENvbnRlbnRJRChqYXZhLmxhbmcuU3RyaW5nKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIHZvaWQgc2V0Q29udGVudExhbmd1YWdlKGphdmEubGFuZy5TdHJpbmdbXSkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyB2b2lkIHNldENvbnRlbnRNRDUoamF2YS5sYW5nLlN0cmluZykgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyB2b2lkIHNldERhdGFIYW5kbGVyKGphdmF4LmFjdGl2YXRpb24uRGF0YUhhbmRsZXIpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgdm9pZCBzZXREZXNjcmlwdGlvbihqYXZhLmxhbmcuU3RyaW5nKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIHZvaWQgc2V0RGVzY3JpcHRpb24oamF2YS5sYW5nLlN0cmluZyxqYXZhLmxhbmcuU3RyaW5nKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIHZvaWQgc2V0RGlzcG9zaXRpb24oamF2YS5sYW5nLlN0cmluZykgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyB2b2lkIHNldEZpbGVOYW1lKGphdmEubGFuZy5TdHJpbmcpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgdm9pZCBzZXRGbGFncyhqYXZheC5tYWlsLkZsYWdzLGJvb2xlYW4pIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgdm9pZCBzZXRGcm9tKCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyB2b2lkIHNldEZyb20oamF2YS5sYW5nLlN0cmluZykgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyB2b2lkIHNldEZyb20oamF2YXgubWFpbC5BZGRyZXNzKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIHZvaWQgc2V0SGVhZGVyKGphdmEubGFuZy5TdHJpbmcsamF2YS5sYW5nLlN0cmluZykgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyB2b2lkIHNldFJlY2lwaWVudHMoamF2YXgubWFpbC5NZXNzYWdlJFJlY2lwaWVudFR5cGUsamF2YS5sYW5nLlN0cmluZykgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyB2b2lkIHNldFJlY2lwaWVudHMoamF2YXgubWFpbC5NZXNzYWdlJFJlY2lwaWVudFR5cGUsamF2YXgubWFpbC5BZGRyZXNzW10pIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgdm9pZCBzZXRSZXBseVRvKGphdmF4Lm1haWwuQWRkcmVzc1tdKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIHZvaWQgc2V0U2VuZGVyKGphdmF4Lm1haWwuQWRkcmVzcykgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyB2b2lkIHNldFNlbnREYXRlKGphdmEudXRpbC5EYXRlKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIHZvaWQgc2V0U3ViamVjdChqYXZhLmxhbmcuU3RyaW5nKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIHZvaWQgc2V0U3ViamVjdChqYXZhLmxhbmcuU3RyaW5nLGphdmEubGFuZy5TdHJpbmcpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgdm9pZCBzZXRUZXh0KGphdmEubGFuZy5TdHJpbmcpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgdm9pZCBzZXRUZXh0KGphdmEubGFuZy5TdHJpbmcsamF2YS5sYW5nLlN0cmluZykgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyB2b2lkIHNldFRleHQoamF2YS5sYW5nLlN0cmluZyxqYXZhLmxhbmcuU3RyaW5nLGphdmEubGFuZy5TdHJpbmcpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgdm9pZCB3cml0ZVRvKGphdmEuaW8uT3V0cHV0U3RyZWFtKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbixqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgdm9pZCB3cml0ZVRvKGphdmEuaW8uT3V0cHV0U3RyZWFtLGphdmEubGFuZy5TdHJpbmdbXSkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24samF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK3N1cHIgamF2YXgubWFpbC5NZXNzYWdlCitoZmRzIGFsbG93dXRmOCxhbnN3ZXJlZEZsYWcsbWFpbERhdGVGb3JtYXQsc3RyaWN0CisKK0NMU1MgcHVibGljIHN0YXRpYyBqYXZheC5tYWlsLmludGVybmV0Lk1pbWVNZXNzYWdlJFJlY2lwaWVudFR5cGUKKyBvdXRlciBqYXZheC5tYWlsLmludGVybmV0Lk1pbWVNZXNzYWdlCitjb25zIHByb3RlY3RlZCA8aW5pdD4oamF2YS5sYW5nLlN0cmluZykKK2ZsZCBwdWJsaWMgZmluYWwgc3RhdGljIGphdmF4Lm1haWwuaW50ZXJuZXQuTWltZU1lc3NhZ2UkUmVjaXBpZW50VHlwZSBORVdTR1JPVVBTCittZXRoIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IHJlYWRSZXNvbHZlKCkgdGhyb3dzIGphdmEuaW8uT2JqZWN0U3RyZWFtRXhjZXB0aW9uCitzdXByIGphdmF4Lm1haWwuTWVzc2FnZSRSZWNpcGllbnRUeXBlCitoZmRzIHNlcmlhbFZlcnNpb25VSUQKKworQ0xTUyBwdWJsaWMgamF2YXgubWFpbC5pbnRlcm5ldC5NaW1lTXVsdGlwYXJ0Citjb25zIHB1YmxpYyAhdmFyYXJncyA8aW5pdD4oamF2YS5sYW5nLlN0cmluZyxqYXZheC5tYWlsLkJvZHlQYXJ0W10pIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorY29ucyBwdWJsaWMgIXZhcmFyZ3MgPGluaXQ+KGphdmF4Lm1haWwuQm9keVBhcnRbXSkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCitjb25zIHB1YmxpYyA8aW5pdD4oKQorY29ucyBwdWJsaWMgPGluaXQ+KGphdmEubGFuZy5TdHJpbmcpCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YXguYWN0aXZhdGlvbi5EYXRhU291cmNlKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK2ZsZCBwcm90ZWN0ZWQgYm9vbGVhbiBhbGxvd0VtcHR5CitmbGQgcHJvdGVjdGVkIGJvb2xlYW4gY29tcGxldGUKK2ZsZCBwcm90ZWN0ZWQgYm9vbGVhbiBpZ25vcmVFeGlzdGluZ0JvdW5kYXJ5UGFyYW1ldGVyCitmbGQgcHJvdGVjdGVkIGJvb2xlYW4gaWdub3JlTWlzc2luZ0JvdW5kYXJ5UGFyYW1ldGVyCitmbGQgcHJvdGVjdGVkIGJvb2xlYW4gaWdub3JlTWlzc2luZ0VuZEJvdW5kYXJ5CitmbGQgcHJvdGVjdGVkIGJvb2xlYW4gcGFyc2VkCitmbGQgcHJvdGVjdGVkIGphdmEubGFuZy5TdHJpbmcgcHJlYW1ibGUKK2ZsZCBwcm90ZWN0ZWQgamF2YXguYWN0aXZhdGlvbi5EYXRhU291cmNlIGRzCittZXRoIHByb3RlY3RlZCBqYXZheC5tYWlsLmludGVybmV0LkludGVybmV0SGVhZGVycyBjcmVhdGVJbnRlcm5ldEhlYWRlcnMoamF2YS5pby5JbnB1dFN0cmVhbSkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHByb3RlY3RlZCBqYXZheC5tYWlsLmludGVybmV0Lk1pbWVCb2R5UGFydCBjcmVhdGVNaW1lQm9keVBhcnQoamF2YS5pby5JbnB1dFN0cmVhbSkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHByb3RlY3RlZCBqYXZheC5tYWlsLmludGVybmV0Lk1pbWVCb2R5UGFydCBjcmVhdGVNaW1lQm9keVBhcnQoamF2YXgubWFpbC5pbnRlcm5ldC5JbnRlcm5ldEhlYWRlcnMsYnl0ZVtdKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHJvdGVjdGVkIHZvaWQgaW5pdGlhbGl6ZVByb3BlcnRpZXMoKQorbWV0aCBwcm90ZWN0ZWQgdm9pZCBwYXJzZSgpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwcm90ZWN0ZWQgdm9pZCB1cGRhdGVIZWFkZXJzKCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBib29sZWFuIGlzQ29tcGxldGUoKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGJvb2xlYW4gcmVtb3ZlQm9keVBhcnQoamF2YXgubWFpbC5Cb2R5UGFydCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBpbnQgZ2V0Q291bnQoKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UHJlYW1ibGUoKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGphdmF4Lm1haWwuQm9keVBhcnQgZ2V0Qm9keVBhcnQoaW50KSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGphdmF4Lm1haWwuQm9keVBhcnQgZ2V0Qm9keVBhcnQoamF2YS5sYW5nLlN0cmluZykgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyB2b2lkIGFkZEJvZHlQYXJ0KGphdmF4Lm1haWwuQm9keVBhcnQpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgdm9pZCBhZGRCb2R5UGFydChqYXZheC5tYWlsLkJvZHlQYXJ0LGludCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyB2b2lkIHJlbW92ZUJvZHlQYXJ0KGludCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyB2b2lkIHNldFByZWFtYmxlKGphdmEubGFuZy5TdHJpbmcpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgdm9pZCBzZXRTdWJUeXBlKGphdmEubGFuZy5TdHJpbmcpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgdm9pZCB3cml0ZVRvKGphdmEuaW8uT3V0cHV0U3RyZWFtKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbixqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorc3VwciBqYXZheC5tYWlsLk11bHRpcGFydAorCitDTFNTIHB1YmxpYyBhYnN0cmFjdCBpbnRlcmZhY2UgamF2YXgubWFpbC5pbnRlcm5ldC5NaW1lUGFydAoraW50ZiBqYXZheC5tYWlsLlBhcnQKK21ldGggcHVibGljIGFic3RyYWN0IGphdmEubGFuZy5TdHJpbmcgZ2V0Q29udGVudElEKCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBhYnN0cmFjdCBqYXZhLmxhbmcuU3RyaW5nIGdldENvbnRlbnRNRDUoKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGFic3RyYWN0IGphdmEubGFuZy5TdHJpbmcgZ2V0RW5jb2RpbmcoKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGFic3RyYWN0IGphdmEubGFuZy5TdHJpbmcgZ2V0SGVhZGVyKGphdmEubGFuZy5TdHJpbmcsamF2YS5sYW5nLlN0cmluZykgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBhYnN0cmFjdCBqYXZhLmxhbmcuU3RyaW5nW10gZ2V0Q29udGVudExhbmd1YWdlKCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBhYnN0cmFjdCBqYXZhLnV0aWwuRW51bWVyYXRpb248amF2YS5sYW5nLlN0cmluZz4gZ2V0QWxsSGVhZGVyTGluZXMoKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGFic3RyYWN0IGphdmEudXRpbC5FbnVtZXJhdGlvbjxqYXZhLmxhbmcuU3RyaW5nPiBnZXRNYXRjaGluZ0hlYWRlckxpbmVzKGphdmEubGFuZy5TdHJpbmdbXSkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBhYnN0cmFjdCBqYXZhLnV0aWwuRW51bWVyYXRpb248amF2YS5sYW5nLlN0cmluZz4gZ2V0Tm9uTWF0Y2hpbmdIZWFkZXJMaW5lcyhqYXZhLmxhbmcuU3RyaW5nW10pIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBhZGRIZWFkZXJMaW5lKGphdmEubGFuZy5TdHJpbmcpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRDb250ZW50TGFuZ3VhZ2UoamF2YS5sYW5nLlN0cmluZ1tdKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGFic3RyYWN0IHZvaWQgc2V0Q29udGVudE1ENShqYXZhLmxhbmcuU3RyaW5nKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGFic3RyYWN0IHZvaWQgc2V0VGV4dChqYXZhLmxhbmcuU3RyaW5nKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK21ldGggcHVibGljIGFic3RyYWN0IHZvaWQgc2V0VGV4dChqYXZhLmxhbmcuU3RyaW5nLGphdmEubGFuZy5TdHJpbmcpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRUZXh0KGphdmEubGFuZy5TdHJpbmcsamF2YS5sYW5nLlN0cmluZyxqYXZhLmxhbmcuU3RyaW5nKSB0aHJvd3MgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KKworQ0xTUyBwdWJsaWMgamF2YXgubWFpbC5pbnRlcm5ldC5NaW1lUGFydERhdGFTb3VyY2UKK2NvbnMgcHVibGljIDxpbml0PihqYXZheC5tYWlsLmludGVybmV0Lk1pbWVQYXJ0KQorZmxkIHByb3RlY3RlZCBqYXZheC5tYWlsLmludGVybmV0Lk1pbWVQYXJ0IHBhcnQKK2ludGYgamF2YXguYWN0aXZhdGlvbi5EYXRhU291cmNlCitpbnRmIGphdmF4Lm1haWwuTWVzc2FnZUF3YXJlCittZXRoIHB1YmxpYyBqYXZhLmlvLklucHV0U3RyZWFtIGdldElucHV0U3RyZWFtKCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24KK21ldGggcHVibGljIGphdmEuaW8uT3V0cHV0U3RyZWFtIGdldE91dHB1dFN0cmVhbSgpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uCittZXRoIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldENvbnRlbnRUeXBlKCkKK21ldGggcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TmFtZSgpCittZXRoIHB1YmxpYyBqYXZheC5tYWlsLk1lc3NhZ2VDb250ZXh0IGdldE1lc3NhZ2VDb250ZXh0KCkKK3N1cHIgamF2YS5sYW5nLk9iamVjdAoraGZkcyBjb250ZXh0CisKK0NMU1MgcHVibGljIGphdmF4Lm1haWwuaW50ZXJuZXQuTWltZVV0aWxpdHkKK2ZsZCBwdWJsaWMgZmluYWwgc3RhdGljIGludCBBTEwgPSAtMQorbWV0aCBwdWJsaWMgc3RhdGljIGphdmEuaW8uSW5wdXRTdHJlYW0gZGVjb2RlKGphdmEuaW8uSW5wdXRTdHJlYW0samF2YS5sYW5nLlN0cmluZykgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBzdGF0aWMgamF2YS5pby5PdXRwdXRTdHJlYW0gZW5jb2RlKGphdmEuaW8uT3V0cHV0U3RyZWFtLGphdmEubGFuZy5TdHJpbmcpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgc3RhdGljIGphdmEuaW8uT3V0cHV0U3RyZWFtIGVuY29kZShqYXZhLmlvLk91dHB1dFN0cmVhbSxqYXZhLmxhbmcuU3RyaW5nLGphdmEubGFuZy5TdHJpbmcpIHRocm93cyBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgc3RhdGljIGphdmEubGFuZy5TdHJpbmcgZGVjb2RlVGV4dChqYXZhLmxhbmcuU3RyaW5nKSB0aHJvd3MgamF2YS5pby5VbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBzdGF0aWMgamF2YS5sYW5nLlN0cmluZyBkZWNvZGVXb3JkKGphdmEubGFuZy5TdHJpbmcpIHRocm93cyBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24samF2YXgubWFpbC5pbnRlcm5ldC5QYXJzZUV4Y2VwdGlvbgorbWV0aCBwdWJsaWMgc3RhdGljIGphdmEubGFuZy5TdHJpbmcgZW5jb2RlVGV4dChqYXZhLmxhbmcuU3RyaW5nKSB0aHJvd3MgamF2YS5pby5VbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBzdGF0aWMgamF2YS5sYW5nLlN0cmluZyBlbmNvZGVUZXh0KGphdmEubGFuZy5TdHJpbmcsamF2YS5sYW5nLlN0cmluZyxqYXZhLmxhbmcuU3RyaW5nKSB0aHJvd3MgamF2YS5pby5VbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBzdGF0aWMgamF2YS5sYW5nLlN0cmluZyBlbmNvZGVXb3JkKGphdmEubGFuZy5TdHJpbmcpIHRocm93cyBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24KK21ldGggcHVibGljIHN0YXRpYyBqYXZhLmxhbmcuU3RyaW5nIGVuY29kZVdvcmQoamF2YS5sYW5nLlN0cmluZyxqYXZhLmxhbmcuU3RyaW5nLGphdmEubGFuZy5TdHJpbmcpIHRocm93cyBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24KK21ldGggcHVibGljIHN0YXRpYyBqYXZhLmxhbmcuU3RyaW5nIGZvbGQoaW50LGphdmEubGFuZy5TdHJpbmcpCittZXRoIHB1YmxpYyBzdGF0aWMgamF2YS5sYW5nLlN0cmluZyBnZXREZWZhdWx0SmF2YUNoYXJzZXQoKQorbWV0aCBwdWJsaWMgc3RhdGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RW5jb2RpbmcoamF2YXguYWN0aXZhdGlvbi5EYXRhSGFuZGxlcikKK21ldGggcHVibGljIHN0YXRpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEVuY29kaW5nKGphdmF4LmFjdGl2YXRpb24uRGF0YVNvdXJjZSkKK21ldGggcHVibGljIHN0YXRpYyBqYXZhLmxhbmcuU3RyaW5nIGphdmFDaGFyc2V0KGphdmEubGFuZy5TdHJpbmcpCittZXRoIHB1YmxpYyBzdGF0aWMgamF2YS5sYW5nLlN0cmluZyBtaW1lQ2hhcnNldChqYXZhLmxhbmcuU3RyaW5nKQorbWV0aCBwdWJsaWMgc3RhdGljIGphdmEubGFuZy5TdHJpbmcgcXVvdGUoamF2YS5sYW5nLlN0cmluZyxqYXZhLmxhbmcuU3RyaW5nKQorbWV0aCBwdWJsaWMgc3RhdGljIGphdmEubGFuZy5TdHJpbmcgdW5mb2xkKGphdmEubGFuZy5TdHJpbmcpCitzdXByIGphdmEubGFuZy5PYmplY3QKK2hmZHMgQUxMX0FTQ0lJLE1PU1RMWV9BU0NJSSxNT1NUTFlfTk9OQVNDSUksYWxsb3dVdGY4LGRlY29kZVN0cmljdCxkZWZhdWx0SmF2YUNoYXJzZXQsZGVmYXVsdE1JTUVDaGFyc2V0LGVuY29kZUVvbFN0cmljdCxmb2xkRW5jb2RlZFdvcmRzLGZvbGRUZXh0LGlnbm9yZVVua25vd25FbmNvZGluZyxqYXZhMm1pbWUsbWltZTJqYXZhLG5vbkFzY2lpQ2hhcnNldE1hcAorCitDTFNTIHB1YmxpYyBqYXZheC5tYWlsLmludGVybmV0Lk5ld3NBZGRyZXNzCitjb25zIHB1YmxpYyA8aW5pdD4oKQorY29ucyBwdWJsaWMgPGluaXQ+KGphdmEubGFuZy5TdHJpbmcpCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YS5sYW5nLlN0cmluZyxqYXZhLmxhbmcuU3RyaW5nKQorZmxkIHByb3RlY3RlZCBqYXZhLmxhbmcuU3RyaW5nIGhvc3QKK2ZsZCBwcm90ZWN0ZWQgamF2YS5sYW5nLlN0cmluZyBuZXdzZ3JvdXAKK21ldGggcHVibGljIGJvb2xlYW4gZXF1YWxzKGphdmEubGFuZy5PYmplY3QpCittZXRoIHB1YmxpYyBpbnQgaGFzaENvZGUoKQorbWV0aCBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRIb3N0KCkKK21ldGggcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TmV3c2dyb3VwKCkKK21ldGggcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0VHlwZSgpCittZXRoIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIHRvU3RyaW5nKCkKK21ldGggcHVibGljIHN0YXRpYyBqYXZhLmxhbmcuU3RyaW5nIHRvU3RyaW5nKGphdmF4Lm1haWwuQWRkcmVzc1tdKQorbWV0aCBwdWJsaWMgc3RhdGljIGphdmF4Lm1haWwuaW50ZXJuZXQuTmV3c0FkZHJlc3NbXSBwYXJzZShqYXZhLmxhbmcuU3RyaW5nKSB0aHJvd3MgamF2YXgubWFpbC5pbnRlcm5ldC5BZGRyZXNzRXhjZXB0aW9uCittZXRoIHB1YmxpYyB2b2lkIHNldEhvc3QoamF2YS5sYW5nLlN0cmluZykKK21ldGggcHVibGljIHZvaWQgc2V0TmV3c2dyb3VwKGphdmEubGFuZy5TdHJpbmcpCitzdXByIGphdmF4Lm1haWwuQWRkcmVzcworaGZkcyBzZXJpYWxWZXJzaW9uVUlECisKK0NMU1MgcHVibGljIGphdmF4Lm1haWwuaW50ZXJuZXQuUGFyYW1ldGVyTGlzdAorY29ucyBwdWJsaWMgPGluaXQ+KCkKK2NvbnMgcHVibGljIDxpbml0PihqYXZhLmxhbmcuU3RyaW5nKSB0aHJvd3MgamF2YXgubWFpbC5pbnRlcm5ldC5QYXJzZUV4Y2VwdGlvbgorbWV0aCBwdWJsaWMgaW50IHNpemUoKQorbWV0aCBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXQoamF2YS5sYW5nLlN0cmluZykKK21ldGggcHVibGljIGphdmEubGFuZy5TdHJpbmcgdG9TdHJpbmcoKQorbWV0aCBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyB0b1N0cmluZyhpbnQpCittZXRoIHB1YmxpYyBqYXZhLnV0aWwuRW51bWVyYXRpb248amF2YS5sYW5nLlN0cmluZz4gZ2V0TmFtZXMoKQorbWV0aCBwdWJsaWMgdm9pZCBjb21iaW5lU2VnbWVudHMoKQorbWV0aCBwdWJsaWMgdm9pZCByZW1vdmUoamF2YS5sYW5nLlN0cmluZykKK21ldGggcHVibGljIHZvaWQgc2V0KGphdmEubGFuZy5TdHJpbmcsamF2YS5sYW5nLlN0cmluZykKK21ldGggcHVibGljIHZvaWQgc2V0KGphdmEubGFuZy5TdHJpbmcsamF2YS5sYW5nLlN0cmluZyxqYXZhLmxhbmcuU3RyaW5nKQorc3VwciBqYXZhLmxhbmcuT2JqZWN0CitoZmRzIGFwcGxlaGFjayxkZWNvZGVQYXJhbWV0ZXJzLGRlY29kZVBhcmFtZXRlcnNTdHJpY3QsZW5jb2RlUGFyYW1ldGVycyxoZXgsbGFzdE5hbWUsbGlzdCxtdWx0aXNlZ21lbnROYW1lcyxwYXJhbWV0ZXJzU3RyaWN0LHNsaXN0LHNwbGl0TG9uZ1BhcmFtZXRlcnMsd2luZG93c2hhY2sKK2hjbHMgTGl0ZXJhbFZhbHVlLE11bHRpVmFsdWUsUGFyYW1FbnVtLFRvU3RyaW5nQnVmZmVyLFZhbHVlCisKK0NMU1MgcHVibGljIGphdmF4Lm1haWwuaW50ZXJuZXQuUGFyc2VFeGNlcHRpb24KK2NvbnMgcHVibGljIDxpbml0PigpCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YS5sYW5nLlN0cmluZykKK3N1cHIgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24KK2hmZHMgc2VyaWFsVmVyc2lvblVJRAorCitDTFNTIHB1YmxpYyBqYXZheC5tYWlsLmludGVybmV0LlByZWVuY29kZWRNaW1lQm9keVBhcnQKK2NvbnMgcHVibGljIDxpbml0PihqYXZhLmxhbmcuU3RyaW5nKQorbWV0aCBwcm90ZWN0ZWQgdm9pZCB1cGRhdGVIZWFkZXJzKCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEVuY29kaW5nKCkgdGhyb3dzIGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCittZXRoIHB1YmxpYyB2b2lkIHdyaXRlVG8oamF2YS5pby5PdXRwdXRTdHJlYW0pIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uLGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uCitzdXByIGphdmF4Lm1haWwuaW50ZXJuZXQuTWltZUJvZHlQYXJ0CitoZmRzIGVuY29kaW5nCisKK0NMU1MgcHVibGljIGFic3RyYWN0IGludGVyZmFjZSBqYXZheC5tYWlsLmludGVybmV0LlNoYXJlZElucHV0U3RyZWFtCittZXRoIHB1YmxpYyBhYnN0cmFjdCBqYXZhLmlvLklucHV0U3RyZWFtIG5ld1N0cmVhbShsb25nLGxvbmcpCittZXRoIHB1YmxpYyBhYnN0cmFjdCBsb25nIGdldFBvc2l0aW9uKCkKKworQ0xTUyBwdWJsaWMgYWJzdHJhY3QgamF2YXgubWFpbC5zZWFyY2guQWRkcmVzc1N0cmluZ1Rlcm0KK2NvbnMgcHJvdGVjdGVkIDxpbml0PihqYXZhLmxhbmcuU3RyaW5nKQorbWV0aCBwcm90ZWN0ZWQgYm9vbGVhbiBtYXRjaChqYXZheC5tYWlsLkFkZHJlc3MpCittZXRoIHB1YmxpYyBib29sZWFuIGVxdWFscyhqYXZhLmxhbmcuT2JqZWN0KQorc3VwciBqYXZheC5tYWlsLnNlYXJjaC5TdHJpbmdUZXJtCitoZmRzIHNlcmlhbFZlcnNpb25VSUQKKworQ0xTUyBwdWJsaWMgYWJzdHJhY3QgamF2YXgubWFpbC5zZWFyY2guQWRkcmVzc1Rlcm0KK2NvbnMgcHJvdGVjdGVkIDxpbml0PihqYXZheC5tYWlsLkFkZHJlc3MpCitmbGQgcHJvdGVjdGVkIGphdmF4Lm1haWwuQWRkcmVzcyBhZGRyZXNzCittZXRoIHByb3RlY3RlZCBib29sZWFuIG1hdGNoKGphdmF4Lm1haWwuQWRkcmVzcykKK21ldGggcHVibGljIGJvb2xlYW4gZXF1YWxzKGphdmEubGFuZy5PYmplY3QpCittZXRoIHB1YmxpYyBpbnQgaGFzaENvZGUoKQorbWV0aCBwdWJsaWMgamF2YXgubWFpbC5BZGRyZXNzIGdldEFkZHJlc3MoKQorc3VwciBqYXZheC5tYWlsLnNlYXJjaC5TZWFyY2hUZXJtCitoZmRzIHNlcmlhbFZlcnNpb25VSUQKKworQ0xTUyBwdWJsaWMgZmluYWwgamF2YXgubWFpbC5zZWFyY2guQW5kVGVybQorY29ucyBwdWJsaWMgPGluaXQ+KGphdmF4Lm1haWwuc2VhcmNoLlNlYXJjaFRlcm0samF2YXgubWFpbC5zZWFyY2guU2VhcmNoVGVybSkKK2NvbnMgcHVibGljIDxpbml0PihqYXZheC5tYWlsLnNlYXJjaC5TZWFyY2hUZXJtW10pCittZXRoIHB1YmxpYyBib29sZWFuIGVxdWFscyhqYXZhLmxhbmcuT2JqZWN0KQorbWV0aCBwdWJsaWMgYm9vbGVhbiBtYXRjaChqYXZheC5tYWlsLk1lc3NhZ2UpCittZXRoIHB1YmxpYyBpbnQgaGFzaENvZGUoKQorbWV0aCBwdWJsaWMgamF2YXgubWFpbC5zZWFyY2guU2VhcmNoVGVybVtdIGdldFRlcm1zKCkKK3N1cHIgamF2YXgubWFpbC5zZWFyY2guU2VhcmNoVGVybQoraGZkcyBzZXJpYWxWZXJzaW9uVUlELHRlcm1zCisKK0NMU1MgcHVibGljIGZpbmFsIGphdmF4Lm1haWwuc2VhcmNoLkJvZHlUZXJtCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YS5sYW5nLlN0cmluZykKK21ldGggcHVibGljIGJvb2xlYW4gZXF1YWxzKGphdmEubGFuZy5PYmplY3QpCittZXRoIHB1YmxpYyBib29sZWFuIG1hdGNoKGphdmF4Lm1haWwuTWVzc2FnZSkKK3N1cHIgamF2YXgubWFpbC5zZWFyY2guU3RyaW5nVGVybQoraGZkcyBzZXJpYWxWZXJzaW9uVUlECisKK0NMU1MgcHVibGljIGFic3RyYWN0IGphdmF4Lm1haWwuc2VhcmNoLkNvbXBhcmlzb25UZXJtCitjb25zIHB1YmxpYyA8aW5pdD4oKQorZmxkIHByb3RlY3RlZCBpbnQgY29tcGFyaXNvbgorZmxkIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IEVRID0gMworZmxkIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IEdFID0gNgorZmxkIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IEdUID0gNQorZmxkIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IExFID0gMQorZmxkIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IExUID0gMgorZmxkIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IE5FID0gNAorbWV0aCBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoamF2YS5sYW5nLk9iamVjdCkKK21ldGggcHVibGljIGludCBoYXNoQ29kZSgpCitzdXByIGphdmF4Lm1haWwuc2VhcmNoLlNlYXJjaFRlcm0KK2hmZHMgc2VyaWFsVmVyc2lvblVJRAorCitDTFNTIHB1YmxpYyBhYnN0cmFjdCBqYXZheC5tYWlsLnNlYXJjaC5EYXRlVGVybQorY29ucyBwcm90ZWN0ZWQgPGluaXQ+KGludCxqYXZhLnV0aWwuRGF0ZSkKK2ZsZCBwcm90ZWN0ZWQgamF2YS51dGlsLkRhdGUgZGF0ZQorbWV0aCBwcm90ZWN0ZWQgYm9vbGVhbiBtYXRjaChqYXZhLnV0aWwuRGF0ZSkKK21ldGggcHVibGljIGJvb2xlYW4gZXF1YWxzKGphdmEubGFuZy5PYmplY3QpCittZXRoIHB1YmxpYyBpbnQgZ2V0Q29tcGFyaXNvbigpCittZXRoIHB1YmxpYyBpbnQgaGFzaENvZGUoKQorbWV0aCBwdWJsaWMgamF2YS51dGlsLkRhdGUgZ2V0RGF0ZSgpCitzdXByIGphdmF4Lm1haWwuc2VhcmNoLkNvbXBhcmlzb25UZXJtCitoZmRzIHNlcmlhbFZlcnNpb25VSUQKKworQ0xTUyBwdWJsaWMgZmluYWwgamF2YXgubWFpbC5zZWFyY2guRmxhZ1Rlcm0KK2NvbnMgcHVibGljIDxpbml0PihqYXZheC5tYWlsLkZsYWdzLGJvb2xlYW4pCittZXRoIHB1YmxpYyBib29sZWFuIGVxdWFscyhqYXZhLmxhbmcuT2JqZWN0KQorbWV0aCBwdWJsaWMgYm9vbGVhbiBnZXRUZXN0U2V0KCkKK21ldGggcHVibGljIGJvb2xlYW4gbWF0Y2goamF2YXgubWFpbC5NZXNzYWdlKQorbWV0aCBwdWJsaWMgaW50IGhhc2hDb2RlKCkKK21ldGggcHVibGljIGphdmF4Lm1haWwuRmxhZ3MgZ2V0RmxhZ3MoKQorc3VwciBqYXZheC5tYWlsLnNlYXJjaC5TZWFyY2hUZXJtCitoZmRzIGZsYWdzLHNlcmlhbFZlcnNpb25VSUQsc2V0CisKK0NMU1MgcHVibGljIGZpbmFsIGphdmF4Lm1haWwuc2VhcmNoLkZyb21TdHJpbmdUZXJtCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YS5sYW5nLlN0cmluZykKK21ldGggcHVibGljIGJvb2xlYW4gZXF1YWxzKGphdmEubGFuZy5PYmplY3QpCittZXRoIHB1YmxpYyBib29sZWFuIG1hdGNoKGphdmF4Lm1haWwuTWVzc2FnZSkKK3N1cHIgamF2YXgubWFpbC5zZWFyY2guQWRkcmVzc1N0cmluZ1Rlcm0KK2hmZHMgc2VyaWFsVmVyc2lvblVJRAorCitDTFNTIHB1YmxpYyBmaW5hbCBqYXZheC5tYWlsLnNlYXJjaC5Gcm9tVGVybQorY29ucyBwdWJsaWMgPGluaXQ+KGphdmF4Lm1haWwuQWRkcmVzcykKK21ldGggcHVibGljIGJvb2xlYW4gZXF1YWxzKGphdmEubGFuZy5PYmplY3QpCittZXRoIHB1YmxpYyBib29sZWFuIG1hdGNoKGphdmF4Lm1haWwuTWVzc2FnZSkKK3N1cHIgamF2YXgubWFpbC5zZWFyY2guQWRkcmVzc1Rlcm0KK2hmZHMgc2VyaWFsVmVyc2lvblVJRAorCitDTFNTIHB1YmxpYyBmaW5hbCBqYXZheC5tYWlsLnNlYXJjaC5IZWFkZXJUZXJtCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YS5sYW5nLlN0cmluZyxqYXZhLmxhbmcuU3RyaW5nKQorbWV0aCBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoamF2YS5sYW5nLk9iamVjdCkKK21ldGggcHVibGljIGJvb2xlYW4gbWF0Y2goamF2YXgubWFpbC5NZXNzYWdlKQorbWV0aCBwdWJsaWMgaW50IGhhc2hDb2RlKCkKK21ldGggcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0SGVhZGVyTmFtZSgpCitzdXByIGphdmF4Lm1haWwuc2VhcmNoLlN0cmluZ1Rlcm0KK2hmZHMgaGVhZGVyTmFtZSxzZXJpYWxWZXJzaW9uVUlECisKK0NMU1MgcHVibGljIGFic3RyYWN0IGphdmF4Lm1haWwuc2VhcmNoLkludGVnZXJDb21wYXJpc29uVGVybQorY29ucyBwcm90ZWN0ZWQgPGluaXQ+KGludCxpbnQpCitmbGQgcHJvdGVjdGVkIGludCBudW1iZXIKK21ldGggcHJvdGVjdGVkIGJvb2xlYW4gbWF0Y2goaW50KQorbWV0aCBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoamF2YS5sYW5nLk9iamVjdCkKK21ldGggcHVibGljIGludCBnZXRDb21wYXJpc29uKCkKK21ldGggcHVibGljIGludCBnZXROdW1iZXIoKQorbWV0aCBwdWJsaWMgaW50IGhhc2hDb2RlKCkKK3N1cHIgamF2YXgubWFpbC5zZWFyY2guQ29tcGFyaXNvblRlcm0KK2hmZHMgc2VyaWFsVmVyc2lvblVJRAorCitDTFNTIHB1YmxpYyBmaW5hbCBqYXZheC5tYWlsLnNlYXJjaC5NZXNzYWdlSURUZXJtCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YS5sYW5nLlN0cmluZykKK21ldGggcHVibGljIGJvb2xlYW4gZXF1YWxzKGphdmEubGFuZy5PYmplY3QpCittZXRoIHB1YmxpYyBib29sZWFuIG1hdGNoKGphdmF4Lm1haWwuTWVzc2FnZSkKK3N1cHIgamF2YXgubWFpbC5zZWFyY2guU3RyaW5nVGVybQoraGZkcyBzZXJpYWxWZXJzaW9uVUlECisKK0NMU1MgcHVibGljIGZpbmFsIGphdmF4Lm1haWwuc2VhcmNoLk1lc3NhZ2VOdW1iZXJUZXJtCitjb25zIHB1YmxpYyA8aW5pdD4oaW50KQorbWV0aCBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoamF2YS5sYW5nLk9iamVjdCkKK21ldGggcHVibGljIGJvb2xlYW4gbWF0Y2goamF2YXgubWFpbC5NZXNzYWdlKQorc3VwciBqYXZheC5tYWlsLnNlYXJjaC5JbnRlZ2VyQ29tcGFyaXNvblRlcm0KK2hmZHMgc2VyaWFsVmVyc2lvblVJRAorCitDTFNTIHB1YmxpYyBmaW5hbCBqYXZheC5tYWlsLnNlYXJjaC5Ob3RUZXJtCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YXgubWFpbC5zZWFyY2guU2VhcmNoVGVybSkKK21ldGggcHVibGljIGJvb2xlYW4gZXF1YWxzKGphdmEubGFuZy5PYmplY3QpCittZXRoIHB1YmxpYyBib29sZWFuIG1hdGNoKGphdmF4Lm1haWwuTWVzc2FnZSkKK21ldGggcHVibGljIGludCBoYXNoQ29kZSgpCittZXRoIHB1YmxpYyBqYXZheC5tYWlsLnNlYXJjaC5TZWFyY2hUZXJtIGdldFRlcm0oKQorc3VwciBqYXZheC5tYWlsLnNlYXJjaC5TZWFyY2hUZXJtCitoZmRzIHNlcmlhbFZlcnNpb25VSUQsdGVybQorCitDTFNTIHB1YmxpYyBmaW5hbCBqYXZheC5tYWlsLnNlYXJjaC5PclRlcm0KK2NvbnMgcHVibGljIDxpbml0PihqYXZheC5tYWlsLnNlYXJjaC5TZWFyY2hUZXJtLGphdmF4Lm1haWwuc2VhcmNoLlNlYXJjaFRlcm0pCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YXgubWFpbC5zZWFyY2guU2VhcmNoVGVybVtdKQorbWV0aCBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoamF2YS5sYW5nLk9iamVjdCkKK21ldGggcHVibGljIGJvb2xlYW4gbWF0Y2goamF2YXgubWFpbC5NZXNzYWdlKQorbWV0aCBwdWJsaWMgaW50IGhhc2hDb2RlKCkKK21ldGggcHVibGljIGphdmF4Lm1haWwuc2VhcmNoLlNlYXJjaFRlcm1bXSBnZXRUZXJtcygpCitzdXByIGphdmF4Lm1haWwuc2VhcmNoLlNlYXJjaFRlcm0KK2hmZHMgc2VyaWFsVmVyc2lvblVJRCx0ZXJtcworCitDTFNTIHB1YmxpYyBmaW5hbCBqYXZheC5tYWlsLnNlYXJjaC5SZWNlaXZlZERhdGVUZXJtCitjb25zIHB1YmxpYyA8aW5pdD4oaW50LGphdmEudXRpbC5EYXRlKQorbWV0aCBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoamF2YS5sYW5nLk9iamVjdCkKK21ldGggcHVibGljIGJvb2xlYW4gbWF0Y2goamF2YXgubWFpbC5NZXNzYWdlKQorc3VwciBqYXZheC5tYWlsLnNlYXJjaC5EYXRlVGVybQoraGZkcyBzZXJpYWxWZXJzaW9uVUlECisKK0NMU1MgcHVibGljIGZpbmFsIGphdmF4Lm1haWwuc2VhcmNoLlJlY2lwaWVudFN0cmluZ1Rlcm0KK2NvbnMgcHVibGljIDxpbml0PihqYXZheC5tYWlsLk1lc3NhZ2UkUmVjaXBpZW50VHlwZSxqYXZhLmxhbmcuU3RyaW5nKQorbWV0aCBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoamF2YS5sYW5nLk9iamVjdCkKK21ldGggcHVibGljIGJvb2xlYW4gbWF0Y2goamF2YXgubWFpbC5NZXNzYWdlKQorbWV0aCBwdWJsaWMgaW50IGhhc2hDb2RlKCkKK21ldGggcHVibGljIGphdmF4Lm1haWwuTWVzc2FnZSRSZWNpcGllbnRUeXBlIGdldFJlY2lwaWVudFR5cGUoKQorc3VwciBqYXZheC5tYWlsLnNlYXJjaC5BZGRyZXNzU3RyaW5nVGVybQoraGZkcyBzZXJpYWxWZXJzaW9uVUlELHR5cGUKKworQ0xTUyBwdWJsaWMgZmluYWwgamF2YXgubWFpbC5zZWFyY2guUmVjaXBpZW50VGVybQorY29ucyBwdWJsaWMgPGluaXQ+KGphdmF4Lm1haWwuTWVzc2FnZSRSZWNpcGllbnRUeXBlLGphdmF4Lm1haWwuQWRkcmVzcykKK21ldGggcHVibGljIGJvb2xlYW4gZXF1YWxzKGphdmEubGFuZy5PYmplY3QpCittZXRoIHB1YmxpYyBib29sZWFuIG1hdGNoKGphdmF4Lm1haWwuTWVzc2FnZSkKK21ldGggcHVibGljIGludCBoYXNoQ29kZSgpCittZXRoIHB1YmxpYyBqYXZheC5tYWlsLk1lc3NhZ2UkUmVjaXBpZW50VHlwZSBnZXRSZWNpcGllbnRUeXBlKCkKK3N1cHIgamF2YXgubWFpbC5zZWFyY2guQWRkcmVzc1Rlcm0KK2hmZHMgc2VyaWFsVmVyc2lvblVJRCx0eXBlCisKK0NMU1MgcHVibGljIGphdmF4Lm1haWwuc2VhcmNoLlNlYXJjaEV4Y2VwdGlvbgorY29ucyBwdWJsaWMgPGluaXQ+KCkKK2NvbnMgcHVibGljIDxpbml0PihqYXZhLmxhbmcuU3RyaW5nKQorc3VwciBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbgoraGZkcyBzZXJpYWxWZXJzaW9uVUlECisKK0NMU1MgcHVibGljIGFic3RyYWN0IGphdmF4Lm1haWwuc2VhcmNoLlNlYXJjaFRlcm0KK2NvbnMgcHVibGljIDxpbml0PigpCitpbnRmIGphdmEuaW8uU2VyaWFsaXphYmxlCittZXRoIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIG1hdGNoKGphdmF4Lm1haWwuTWVzc2FnZSkKK3N1cHIgamF2YS5sYW5nLk9iamVjdAoraGZkcyBzZXJpYWxWZXJzaW9uVUlECisKK0NMU1MgcHVibGljIGZpbmFsIGphdmF4Lm1haWwuc2VhcmNoLlNlbnREYXRlVGVybQorY29ucyBwdWJsaWMgPGluaXQ+KGludCxqYXZhLnV0aWwuRGF0ZSkKK21ldGggcHVibGljIGJvb2xlYW4gZXF1YWxzKGphdmEubGFuZy5PYmplY3QpCittZXRoIHB1YmxpYyBib29sZWFuIG1hdGNoKGphdmF4Lm1haWwuTWVzc2FnZSkKK3N1cHIgamF2YXgubWFpbC5zZWFyY2guRGF0ZVRlcm0KK2hmZHMgc2VyaWFsVmVyc2lvblVJRAorCitDTFNTIHB1YmxpYyBmaW5hbCBqYXZheC5tYWlsLnNlYXJjaC5TaXplVGVybQorY29ucyBwdWJsaWMgPGluaXQ+KGludCxpbnQpCittZXRoIHB1YmxpYyBib29sZWFuIGVxdWFscyhqYXZhLmxhbmcuT2JqZWN0KQorbWV0aCBwdWJsaWMgYm9vbGVhbiBtYXRjaChqYXZheC5tYWlsLk1lc3NhZ2UpCitzdXByIGphdmF4Lm1haWwuc2VhcmNoLkludGVnZXJDb21wYXJpc29uVGVybQoraGZkcyBzZXJpYWxWZXJzaW9uVUlECisKK0NMU1MgcHVibGljIGFic3RyYWN0IGphdmF4Lm1haWwuc2VhcmNoLlN0cmluZ1Rlcm0KK2NvbnMgcHJvdGVjdGVkIDxpbml0PihqYXZhLmxhbmcuU3RyaW5nKQorY29ucyBwcm90ZWN0ZWQgPGluaXQ+KGphdmEubGFuZy5TdHJpbmcsYm9vbGVhbikKK2ZsZCBwcm90ZWN0ZWQgYm9vbGVhbiBpZ25vcmVDYXNlCitmbGQgcHJvdGVjdGVkIGphdmEubGFuZy5TdHJpbmcgcGF0dGVybgorbWV0aCBwcm90ZWN0ZWQgYm9vbGVhbiBtYXRjaChqYXZhLmxhbmcuU3RyaW5nKQorbWV0aCBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoamF2YS5sYW5nLk9iamVjdCkKK21ldGggcHVibGljIGJvb2xlYW4gZ2V0SWdub3JlQ2FzZSgpCittZXRoIHB1YmxpYyBpbnQgaGFzaENvZGUoKQorbWV0aCBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRQYXR0ZXJuKCkKK3N1cHIgamF2YXgubWFpbC5zZWFyY2guU2VhcmNoVGVybQoraGZkcyBzZXJpYWxWZXJzaW9uVUlECisKK0NMU1MgcHVibGljIGZpbmFsIGphdmF4Lm1haWwuc2VhcmNoLlN1YmplY3RUZXJtCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YS5sYW5nLlN0cmluZykKK21ldGggcHVibGljIGJvb2xlYW4gZXF1YWxzKGphdmEubGFuZy5PYmplY3QpCittZXRoIHB1YmxpYyBib29sZWFuIG1hdGNoKGphdmF4Lm1haWwuTWVzc2FnZSkKK3N1cHIgamF2YXgubWFpbC5zZWFyY2guU3RyaW5nVGVybQoraGZkcyBzZXJpYWxWZXJzaW9uVUlECisKK0NMU1MgcHVibGljIGphdmF4Lm1haWwudXRpbC5CeXRlQXJyYXlEYXRhU291cmNlCitjb25zIHB1YmxpYyA8aW5pdD4oYnl0ZVtdLGphdmEubGFuZy5TdHJpbmcpCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YS5pby5JbnB1dFN0cmVhbSxqYXZhLmxhbmcuU3RyaW5nKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbgorY29ucyBwdWJsaWMgPGluaXQ+KGphdmEubGFuZy5TdHJpbmcsamF2YS5sYW5nLlN0cmluZykgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24KK2ludGYgamF2YXguYWN0aXZhdGlvbi5EYXRhU291cmNlCittZXRoIHB1YmxpYyBqYXZhLmlvLklucHV0U3RyZWFtIGdldElucHV0U3RyZWFtKCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24KK21ldGggcHVibGljIGphdmEuaW8uT3V0cHV0U3RyZWFtIGdldE91dHB1dFN0cmVhbSgpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uCittZXRoIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldENvbnRlbnRUeXBlKCkKK21ldGggcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TmFtZSgpCittZXRoIHB1YmxpYyB2b2lkIHNldE5hbWUoamF2YS5sYW5nLlN0cmluZykKK3N1cHIgamF2YS5sYW5nLk9iamVjdAoraGZkcyBkYXRhLGxlbixuYW1lLHR5cGUKK2hjbHMgRFNCeXRlQXJyYXlPdXRwdXRTdHJlYW0KKworQ0xTUyBwdWJsaWMgamF2YXgubWFpbC51dGlsLlNoYXJlZEJ5dGVBcnJheUlucHV0U3RyZWFtCitjb25zIHB1YmxpYyA8aW5pdD4oYnl0ZVtdKQorY29ucyBwdWJsaWMgPGluaXQ+KGJ5dGVbXSxpbnQsaW50KQorZmxkIHByb3RlY3RlZCBpbnQgc3RhcnQKK2ludGYgamF2YXgubWFpbC5pbnRlcm5ldC5TaGFyZWRJbnB1dFN0cmVhbQorbWV0aCBwdWJsaWMgamF2YS5pby5JbnB1dFN0cmVhbSBuZXdTdHJlYW0obG9uZyxsb25nKQorbWV0aCBwdWJsaWMgbG9uZyBnZXRQb3NpdGlvbigpCitzdXByIGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW0KKworQ0xTUyBwdWJsaWMgamF2YXgubWFpbC51dGlsLlNoYXJlZEZpbGVJbnB1dFN0cmVhbQorY29ucyBwdWJsaWMgPGluaXQ+KGphdmEuaW8uRmlsZSkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24KK2NvbnMgcHVibGljIDxpbml0PihqYXZhLmlvLkZpbGUsaW50KSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbgorY29ucyBwdWJsaWMgPGluaXQ+KGphdmEubGFuZy5TdHJpbmcpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uCitjb25zIHB1YmxpYyA8aW5pdD4oamF2YS5sYW5nLlN0cmluZyxpbnQpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uCitmbGQgcHJvdGVjdGVkIGludCBidWZzaXplCitmbGQgcHJvdGVjdGVkIGphdmEuaW8uUmFuZG9tQWNjZXNzRmlsZSBpbgorZmxkIHByb3RlY3RlZCBsb25nIGJ1ZnBvcworZmxkIHByb3RlY3RlZCBsb25nIGRhdGFsZW4KK2ZsZCBwcm90ZWN0ZWQgbG9uZyBzdGFydAoraW50ZiBqYXZheC5tYWlsLmludGVybmV0LlNoYXJlZElucHV0U3RyZWFtCittZXRoIHByb3RlY3RlZCB2b2lkIGZpbmFsaXplKCkgdGhyb3dzIGphdmEubGFuZy5UaHJvd2FibGUKK21ldGggcHVibGljIGJvb2xlYW4gbWFya1N1cHBvcnRlZCgpCittZXRoIHB1YmxpYyBpbnQgYXZhaWxhYmxlKCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24KK21ldGggcHVibGljIGludCByZWFkKCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24KK21ldGggcHVibGljIGludCByZWFkKGJ5dGVbXSxpbnQsaW50KSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgamF2YS5pby5JbnB1dFN0cmVhbSBuZXdTdHJlYW0obG9uZyxsb25nKQorbWV0aCBwdWJsaWMgbG9uZyBnZXRQb3NpdGlvbigpCittZXRoIHB1YmxpYyBsb25nIHNraXAobG9uZykgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24KK21ldGggcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbgorbWV0aCBwdWJsaWMgdm9pZCBtYXJrKGludCkKK21ldGggcHVibGljIHZvaWQgcmVzZXQoKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbgorc3VwciBqYXZhLmlvLkJ1ZmZlcmVkSW5wdXRTdHJlYW0KK2hmZHMgZGVmYXVsdEJ1ZmZlclNpemUsbWFzdGVyLHNmCitoY2xzIFNoYXJlZEZpbGUKKwpkaWZmIC0tZ2l0IGEvbWFpbC9leGNsdWRlLnhtbCBiL21haWwvZXhjbHVkZS54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjVmYTQ1YwotLS0gL2Rldi9udWxsCisrKyBiL21haWwvZXhjbHVkZS54bWwKQEAgLTAsMCArMSw3MjcgQEAKKzw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04Ij8+Cis8IS0tCisKKyAgICBDb3B5cmlnaHQgKGMpIDIwMTAsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKworICAgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICAgIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorCisgICAgVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICAgIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAgICBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAgICB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKworICAgIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorCistLT4KKworPCEtLSBGaW5kQnVncyBleGNsdWRlIGxpc3QgZm9yIEphdmFNYWlsIC0tPgorCis8RmluZEJ1Z3NGaWx0ZXI+CisgICAgPCEtLQorCUZpbmRCdWdzICpyZWFsbHkqIHdhbnRzIHVzIHRvIHVzZSB6ZXJvIGxlbmd0aCBhcnJheXMgaW5zdGVhZAorCW9mIG51bGwuICBVbmZvcnR1bmF0ZWx5LCB0aGVyZSdzIGEgYnVuY2ggb2YgcGxhY2VzIHdlIGNhbid0CisJZG8gdGhpcyBmb3IgdmFyaW91cyByZWFzb25zOgorCSAgLSBUaGUgQVBJIHNwZWNpZmllcyBudWxsIGFuZCB3ZSBjYW4ndCBtYWtlIGFuIGluY29tcGF0aWJsZSBjaGFuZ2UuCisJICAtIFdlIHVzZSBudWxsIHRvIGluZGljYXRlIG5vIGhlYWRlciBhbmQgYW4gZW1wdHkgYXJyYXkgdG8gaW5kaWNhdGUKKwkgICAgdGhlIGhlYWRlciBleGlzdHMgYnV0IGhhcyBubyBlbnRyaWVzLgorCSAgLSBXZSB1c2UgbnVsbCB0byBpbmRpY2F0ZSBOSUwgaW4gdGhlIHByb3RvY29sIGFuZCBhbiBlbXB0eSBhcnJheQorCSAgICB0byBpbmRpY2F0ZSBhbiBlbXB0eSBsaXN0ICIoKSIgaW4gdGhlIHByb3RvY29sLgorCVRoaXMgZXJyb3Igb2NjdXJzIG9mdGVuIGVub3VnaCB0aGF0IHdlIGp1c3QgaWdub3JlIGl0IGV2ZXJ5d2hlcmUuCisgICAgLS0+CisgICAgPE1hdGNoPgorCTxCdWcgcGF0dGVybj0iUFpMQV9QUkVGRVJfWkVST19MRU5HVEhfQVJSQVlTIi8+CisgICAgPC9NYXRjaD4KKyAgICA8IS0tCisJVGhlcmUgYXJlIGEgYnVuY2ggb2YgcGxhY2VzIHdoZXJlIEZpbmRCdWdzIGNvbXBsYWlucyBhYm91dAorCWV4cG9zaW5nIGludGVybmFsIHJlcHJlc2VudGF0aW9ucy4gIFdlIGV4Y2x1ZGUgY2FzZXMgd2hlcmUKKwl0aGlzIG9ubHkgaGFwcGVucyBpbiBpbnRlcm5hbCBjbGFzc2VzIHRoYXQgYXJlIG5ldmVyIHZpc2libGUKKwl0aHJvdWdoIHRoZSBwdWJsaWMgSmF2YU1haWwgQVBJLCBvciBjYXNlcyB3aGVyZSB0aGUgdXNlcgorCXBhc3NlcyBpbiBhbiBvYmplY3QgKHVzdWFsbHkgYW4gYXJyYXkpIGFuZCBjYW4gb25seSBodXJ0CisJdGhlbXNlbHZlcyBieSBtb2RpZnlpbmcgdGhlIGFycmF5IHdoaWxlIGEgbWV0aG9kIGlzIGluIHByb2dyZXNzLAorCW9yIHdoZXJlIHRoZSBpbXBsZW1lbnRhdGlvbiBpcyBwYXNzaW5nIHRoZSBkYXRhIGJhY2sgdG8gdGhlIHVzZXIKKwkoZS5nLiwgaW4gYW4gRXhjZXB0aW9uKSBhbmQgbmV2ZXIgdXNlcyBpdCBhZ2Fpbi4KKyAgICAtLT4KKyAgICA8TWF0Y2g+CisJPE9yPgorCSAgICA8Q2xhc3MgbmFtZT0iamF2YXgubWFpbC5TZW5kRmFpbGVkRXhjZXB0aW9uIi8+CisJICAgIDxDbGFzcyBuYW1lPSJqYXZheC5tYWlsLmV2ZW50Lk1lc3NhZ2VDb3VudEV2ZW50Ii8+CisJICAgIDxDbGFzcyBuYW1lPSJqYXZheC5tYWlsLmV2ZW50LlRyYW5zcG9ydEV2ZW50Ii8+CisJICAgIDxDbGFzcyBuYW1lPSJjb20uc3VuLm1haWwuaWFwLkJ5dGVBcnJheSIvPgorCSAgICA8Q2xhc3MgbmFtZT0iY29tLnN1bi5tYWlsLmltYXAuTWVzc2FnZVZhbmlzaGVkRXZlbnQiLz4KKwkgICAgPENsYXNzIG5hbWU9ImNvbS5zdW4ubWFpbC5pbWFwLnByb3RvY29sLkZldGNoUmVzcG9uc2UiLz4KKwk8L09yPgorCTxPcj4KKwkgICAgPEJ1ZyBwYXR0ZXJuPSJFSV9FWFBPU0VfUkVQIi8+CisJICAgIDxCdWcgcGF0dGVybj0iRUlfRVhQT1NFX1JFUDIiLz4KKwk8L09yPgorICAgIDwvTWF0Y2g+CisgICAgPE1hdGNoPgorCTxDbGFzcyBuYW1lPSJjb20uc3VuLm1haWwuc210cC5TTVRQVHJhbnNwb3J0Ii8+CisJPE1ldGhvZCBuYW1lPSJzZW5kTWVzc2FnZSIvPgorCTwhLS0gcGFzc2VkIGluIEFkZHJlc3MgYXJyYXkgLS0+CisJPEJ1ZyBwYXR0ZXJuPSJFSV9FWFBPU0VfUkVQMiIvPgorICAgIDwvTWF0Y2g+CisgICAgPE1hdGNoPgorCTxDbGFzcyBuYW1lPSJqYXZheC5tYWlsLmludGVybmV0Lk1pbWVCb2R5UGFydCIvPgorCTxNZXRob2QgbmFtZT0iJmx0O2luaXQmZ3Q7Ii8+IDwhLS0gbWF0Y2ggY29uc3RydWN0b3IgLS0+CisJPCEtLSBwYXNzZWQgaW4gYnl0ZSBhcnJheSAtLT4KKwk8QnVnIHBhdHRlcm49IkVJX0VYUE9TRV9SRVAyIi8+CisgICAgPC9NYXRjaD4KKyAgICA8TWF0Y2g+CisJPENsYXNzIG5hbWU9ImphdmF4Lm1haWwudXRpbC5CeXRlQXJyYXlEYXRhU291cmNlIi8+CisJPE1ldGhvZCBuYW1lPSImbHQ7aW5pdCZndDsiLz4gPCEtLSBtYXRjaCBjb25zdHJ1Y3RvciAtLT4KKwk8IS0tIHBhc3NlZCBpbiBieXRlIGFycmF5IC0tPgorCTxCdWcgcGF0dGVybj0iRUlfRVhQT1NFX1JFUDIiLz4KKyAgICA8L01hdGNoPgorICAgIDxNYXRjaD4KKwk8Q2xhc3MgbmFtZT0iY29tLnN1bi5tYWlsLnV0aWwuTWFpbFNTTFNvY2tldEZhY3RvcnkiLz4KKwk8TWV0aG9kIG5hbWU9InNldFRydXN0TWFuYWdlcnMiLz4KKwk8IS0tIHBhc3NlZCBpbiBUcnVzdE1hbmFnZXIgYXJyYXkgLS0+CisJPEJ1ZyBwYXR0ZXJuPSJFSV9FWFBPU0VfUkVQMiIvPgorICAgIDwvTWF0Y2g+CisgICAgPE1hdGNoPgorCTxDbGFzcyBuYW1lPSJjb20uc3VuLm1haWwudXRpbC5NYWlsU1NMU29ja2V0RmFjdG9yeSIvPgorCTxNZXRob2QgbmFtZT0iZ2V0VHJ1c3RNYW5hZ2VycyIvPgorCTwhLS0gcmV0dXJuZWQgVHJ1c3RNYW5hZ2VyIGFycmF5IC0tPgorCTxCdWcgcGF0dGVybj0iRUlfRVhQT1NFX1JFUCIvPgorICAgIDwvTWF0Y2g+CisgICAgPE1hdGNoPgorCTxDbGFzcyBuYW1lPSJjb20uc3VuLm1haWwuaW1hcC5wcm90b2NvbC5JTlRFUk5BTERBVEUiLz4KKwk8TWV0aG9kIG5hbWU9ImdldERhdGUiLz4KKwk8IS0tCisJICAgIFJldHVybmVkIERhdGUgb2JqZWN0OyBpdCdzIG9ubHkgZXZlciBzdG9yZWQgaW4KKwkgICAgSU1BUE1lc3NhZ2UucmVjZWl2ZWREYXRlIGFuZCBpcyBhbHdheXMgdXNlZCB0bworCSAgICBjb25zdHJ1Y3QgYSBuZXcgRGF0ZSBvYmplY3QgYmVmb3JlIHJldHVybmluZyB0bworCSAgICB1c2Vycy4KKwktLT4KKwk8QnVnIHBhdHRlcm49IkVJX0VYUE9TRV9SRVAiLz4KKyAgICA8L01hdGNoPgorICAgIDxNYXRjaD4KKwk8Q2xhc3MgbmFtZT0iY29tLnN1bi5tYWlsLmltYXAuQ29weVVJRCIvPgorCTxNZXRob2QgbmFtZT0iJmx0O2luaXQmZ3Q7Ii8+IDwhLS0gbWF0Y2ggY29uc3RydWN0b3IgLS0+CisJPEJ1ZyBwYXR0ZXJuPSJFSV9FWFBPU0VfUkVQMiIvPgorICAgIDwvTWF0Y2g+CisKKyAgICA8IS0tCisJQSBmZXcgcGxhY2VzIHdoZXJlIGl0IGNvbXBsYWlucyBhYm91dCB3YWl0IG5vdCBiZWluZyBpbiBhIGxvb3AuCisJVGhpcyBwdXJwb3NlbHkgZG9lc24ndCBsb29wIHNvIHRoYXQgdGhlIGFwcGxpY2F0aW9uCisJY2FsbGluZyBpZGxlIGNhbiBjaGVjayB3aGV0aGVyIHRoZSBpZGxlIHNob3VsZCBjb250aW51ZS4KKyAgICAtLT4KKyAgICA8TWF0Y2g+CisJPCEtLSBhbiBhbm9ueW1vdXMgaW5uZXIgY2xhc3Mgb2YgdGhlIGlkbGUgbWV0aG9kIC0tPgorCTxDbGFzcyBuYW1lPSJ+Y29tXC5zdW5cLm1haWxcLmltYXBcLklNQVBGb2xkZXIuKiIvPgorCTxNZXRob2QgbmFtZT0iZG9Db21tYW5kIi8+CisJPEJ1ZyBwYXR0ZXJuPSJXQV9OT1RfSU5fTE9PUCIvPgorICAgIDwvTWF0Y2g+CisgICAgPE1hdGNoPgorCTxDbGFzcyBuYW1lPSJjb20uc3VuLm1haWwuaW1hcC5JTUFQU3RvcmUiLz4KKwk8TWV0aG9kIG5hbWU9ImlkbGUiLz4KKwk8QnVnIHBhdHRlcm49IldBX05PVF9JTl9MT09QIi8+CisgICAgPC9NYXRjaD4KKworICAgIDwhLS0KKwlBIGZldyBwbGFjZXMgd2hlcmUgd2UgY2F0Y2ggRXhjZXB0aW9uIGV2ZW4gdGhvdWdoIGl0J3Mgbm90CisJZXhwbGljaXRseSB0aHJvd24uICBXZSBuZWVkIHRvIG1ha2Ugc3VyZSB0aGF0IGlmIGFueXRoaW5nCisJZ29lcyB3cm9uZyB3ZSBjbGVhbiB0aGluZ3MgdXAuICBQZXJoYXBzIHRoZXNlIHNob3VsZCBiZQorCWNvbnZlcnRlZCB0byBhIGZpbmFsbHkgYmxvY2sgYW5kIGEgYm9vbGVhbiAic3VjY2VzcyIgZmxhZz8KKwlNb3N0IG9mIHRoZXNlIGFyZSByZWxhdGVkIHRvIHJlZmxlY3Rpb24gb3IgQ2xhc3NMb2FkZXIKKwlvcGVyYXRpb25zLCB3aGljaCBjYW4gZmFpbCBmb3IgYWxsIHNvcnRzIG9mIHVuZXhwZWN0ZWQgcmVhc29ucy4KKwlTb21lIG9mIHRoZXNlIGNvdWxkIGJlIGNvbnZlcnRlZCB0byB1c2UgbXVsdGktY2F0Y2ggd2l0aCBKREsgMS43LgorICAgIC0tPgorICAgIDxNYXRjaD4KKwk8Q2xhc3MgbmFtZT0iY29tLnN1bi5tYWlsLmltYXAuSU1BUFN0b3JlIi8+CisJPE9yPgorCSAgICA8TWV0aG9kIG5hbWU9IiZsdDtpbml0Jmd0OyIvPiA8IS0tIG1hdGNoIGNvbnN0cnVjdG9yIC0tPgorCSAgICA8TWV0aG9kIG5hbWU9ImdldFByb3RvY29sIi8+CisJICAgIDxNZXRob2QgbmFtZT0iZ2V0U3RvcmVQcm90b2NvbCIvPgorCSAgICA8TWV0aG9kIG5hbWU9Im5ld0lNQVBGb2xkZXIiLz4KKwk8L09yPgorCTxCdWcgcGF0dGVybj0iUkVDX0NBVENIX0VYQ0VQVElPTiIvPgorICAgIDwvTWF0Y2g+CisgICAgPE1hdGNoPgorCTxDbGFzcyBuYW1lPSJjb20uc3VuLm1haWwuaW1hcC5wcm90b2NvbC5JTUFQUHJvdG9jb2wiLz4KKwk8T3I+CisJICAgIDxNZXRob2QgbmFtZT0iYXV0aGxvZ2luIi8+CisJICAgIDxNZXRob2QgbmFtZT0iYXV0aG50bG0iLz4KKwkgICAgPE1ldGhvZCBuYW1lPSJhdXRocGxhaW4iLz4KKwkgICAgPE1ldGhvZCBuYW1lPSJhdXRob2F1dGgyIi8+CisJICAgIDxNZXRob2QgbmFtZT0ic2FzbGxvZ2luIi8+CisJPC9Pcj4KKwk8QnVnIHBhdHRlcm49IlJFQ19DQVRDSF9FWENFUFRJT04iLz4KKyAgICA8L01hdGNoPgorICAgIDxNYXRjaD4KKwk8Q2xhc3MgbmFtZT0iY29tLnN1bi5tYWlsLmltYXAucHJvdG9jb2wuSU1BUFNhc2xBdXRoZW50aWNhdG9yIi8+CisJPE1ldGhvZCBuYW1lPSJhdXRoZW50aWNhdGUiLz4KKwk8QnVnIHBhdHRlcm49IlJFQ19DQVRDSF9FWENFUFRJT04iLz4KKyAgICA8L01hdGNoPgorICAgIDxNYXRjaD4KKwk8Q2xhc3MgbmFtZT0iY29tLnN1bi5tYWlsLnBvcDMuUE9QM1N0b3JlIi8+CisJPE1ldGhvZCBuYW1lPSImbHQ7aW5pdCZndDsiLz4gPCEtLSBtYXRjaCBjb25zdHJ1Y3RvciAtLT4KKwk8QnVnIHBhdHRlcm49IlJFQ19DQVRDSF9FWENFUFRJT04iLz4KKyAgICA8L01hdGNoPgorICAgIDxNYXRjaD4KKwk8Q2xhc3MgbmFtZT0iY29tLnN1bi5tYWlsLnNtdHAuU01UUFRyYW5zcG9ydCIvPgorCTxPcj4KKwkgICAgPE1ldGhvZCBuYW1lPSJpc0Nvbm5lY3RlZCIvPgorCSAgICA8TWV0aG9kIG5hbWU9InNhc2xsb2dpbiIvPgorCTwvT3I+CisJPEJ1ZyBwYXR0ZXJuPSJSRUNfQ0FUQ0hfRVhDRVBUSU9OIi8+CisgICAgPC9NYXRjaD4KKyAgICA8TWF0Y2g+CisJPENsYXNzIG5hbWU9ImNvbS5zdW4ubWFpbC5wb3AzLlBPUDNGb2xkZXIiLz4KKwk8TWV0aG9kIG5hbWU9ImNyZWF0ZU1lc3NhZ2UiLz4KKwk8T3I+CisJICAgIDxCdWcgcGF0dGVybj0iUkVDX0NBVENIX0VYQ0VQVElPTiIvPgorCSAgICA8QnVnIHBhdHRlcm49IkRFX01JR0hUX0lHTk9SRSIvPgorCTwvT3I+CisgICAgPC9NYXRjaD4KKyAgICA8TWF0Y2g+CisJPENsYXNzIG5hbWU9ImNvbS5zdW4ubWFpbC51dGlsLlNvY2tldEZldGNoZXIiLz4KKwk8T3I+CisJICAgIDxNZXRob2QgbmFtZT0iZ2V0U29ja2V0Ii8+CisJICAgIDxNZXRob2QgbmFtZT0ic3RhcnRUTFMiLz4KKwkgICAgPE1ldGhvZCBuYW1lPSJtYXRjaENlcnQiLz4KKwk8L09yPgorCTxCdWcgcGF0dGVybj0iUkVDX0NBVENIX0VYQ0VQVElPTiIvPgorICAgIDwvTWF0Y2g+CisgICAgPE1hdGNoPgorCTxDbGFzcyBuYW1lPSJjb20uc3VuLm1haWwudXRpbC5NaW1lVXRpbCIvPgorCTxNZXRob2QgbmFtZT0iY2xlYW5Db250ZW50VHlwZSIvPgorCTxCdWcgcGF0dGVybj0iUkVDX0NBVENIX0VYQ0VQVElPTiIvPgorICAgIDwvTWF0Y2g+CisgICAgPE1hdGNoPgorCTxDbGFzcyBuYW1lPSJqYXZheC5tYWlsLlNlc3Npb24iLz4KKwk8T3I+CisJICAgIDxNZXRob2QgbmFtZT0iZ2V0U2VydmljZSIvPgorCSAgICA8TWV0aG9kIG5hbWU9ImxvYWRBbGxSZXNvdXJjZXMiLz4KKwk8L09yPgorCTxCdWcgcGF0dGVybj0iUkVDX0NBVENIX0VYQ0VQVElPTiIvPgorICAgIDwvTWF0Y2g+CisgICAgPE1hdGNoPgorCTxDbGFzcyBuYW1lPSJqYXZheC5tYWlsLmludGVybmV0Lk1pbWVVdGlsaXR5Ii8+CisJPE9yPgorCSAgICA8TWV0aG9kIG5hbWU9IiZsdDtjbGluaXQmZ3Q7Ii8+IDwhLS0gbWF0Y2ggc3RhdGljIGluaXRpYWxpemVyIC0tPgorCSAgICA8TWV0aG9kIG5hbWU9ImdldEVuY29kaW5nIi8+CisJPC9Pcj4KKwk8QnVnIHBhdHRlcm49IlJFQ19DQVRDSF9FWENFUFRJT04iLz4KKyAgICA8L01hdGNoPgorICAgIDxNYXRjaD4KKwk8Q2xhc3MgbmFtZT0iY29tLnN1bi5tYWlsLmltYXAuSU1BUEZvbGRlciIvPgorCTxNZXRob2QgbmFtZT0iaGFuZGxlSWRsZSIvPgorCTxCdWcgcGF0dGVybj0iREVfTUlHSFRfSUdOT1JFIi8+CisgICAgPC9NYXRjaD4KKworICAgIDwhLS0KKwlGaW5kQnVncyBjb21wbGFpbnMgYWJvdXQgYSBwb3NzaWJsZSBkb3VibGUgY2hlY2sgb2YgaGVhZGVyc0xvYWRlZCwKKwlidXQgaXQgc2VlbXMgdG8gYmUganVzdCB3cm9uZzsgSSBkb24ndCBzZWUgaXQuCisgICAgLS0+CisgICAgPE1hdGNoPgorCTxDbGFzcyBuYW1lPSJjb20uc3VuLm1haWwuaW1hcC5JTUFQTWVzc2FnZSIvPgorCTxNZXRob2QgbmFtZT0ibG9hZEhlYWRlcnMiLz4KKwk8QnVnIHBhdHRlcm49IkRDX0RPVUJMRUNIRUNLIi8+CisgICAgPC9NYXRjaD4KKworICAgIDwhLS0KKwlUaGVzZSBJTUFQLXNwZWNpZmljIHN1YmNsYXNzZXMgb2Ygc3RhbmRhcmQgY2xhc3NlcyBkb24ndCBvdmVycmlkZQorCWVxdWFscyBiZWNhdXNlIGFsbCB0aGV5IGFkZCBhcmUgY29uc3RydWN0b3JzIGFuZCBvcHRpbWl6ZWQgYWNjZXNzCisJbWV0aG9kczsgZXZlcnl0aGluZyBlbHNlLCBpbmNsdWRpbmcgdGhlIHdheSB0byB0ZXN0IGZvciBlcXVhbGl0eSwKKwlpcyB0aGUgc2FtZS4KKyAgICAtLT4KKyAgICA8TWF0Y2g+CisJPENsYXNzIG5hbWU9ImNvbS5zdW4ubWFpbC5pbWFwLnByb3RvY29sLkZMQUdTIi8+CisJPEJ1ZyBwYXR0ZXJuPSJFUV9ET0VTTlRfT1ZFUlJJREVfRVFVQUxTIi8+CisgICAgPC9NYXRjaD4KKyAgICA8TWF0Y2g+CisJPENsYXNzIG5hbWU9ImNvbS5zdW4ubWFpbC5pbWFwLnByb3RvY29sLklNQVBBZGRyZXNzIi8+CisJPCEtLSBkZWZpbmVkIGluIEVOVkVMT1BFLmphdmEgLS0+CisJPEJ1ZyBwYXR0ZXJuPSJFUV9ET0VTTlRfT1ZFUlJJREVfRVFVQUxTIi8+CisgICAgPC9NYXRjaD4KKworICAgIDwhLS0KKwlGaW5kQnVncyBjb21wbGFpbnMgb2YgYW4gdW5pdGlhbGl6ZWQgcmVhZCBvZiB0aGUgImNhcGFiaWxpdGllcyIKKwlmaWVsZC4gIFNpbmNlIHRoZSBzdXBlcmNsYXNzIG1pZ2h0IGluaXRpYWxpemUgdGhlIGZpZWxkICh2aWEgYQorCWNhbGwgaW50byB0aGUgb3ZlcnJpZGRlbiBwcm9jZXNzR3JlZXRpbmcgbWV0aG9kKSwgYW55IGluaXRpYWxpemF0aW9uCisJZG9uZSBpbiB0aGUgSU1BUFByb3RvY29sIGNsYXNzIHdpbGwgdW5kbyBhbnkgaW5pdGlhbGl6YXRpb24gZG9uZQorCWFzIGEgc2lkZSBlZmZlY3Qgb2YgY2FsbGluZyB0aGUgc3VwZXJjbGFzcyBjb25zdHJ1Y3Rvci4gIFRodXMsIHdlCisJbmVlZCB0byBkZXBlbmQgb24gdGhlIGZpZWxkIGJlaW5nIGluaXRpYWxpemVkIHRvIHRoZSBkZWZhdWx0IHZhbHVlLgorICAgIC0tPgorICAgIDxNYXRjaD4KKwk8Q2xhc3MgbmFtZT0iY29tLnN1bi5tYWlsLmltYXAucHJvdG9jb2wuSU1BUFByb3RvY29sIi8+CisJPE1ldGhvZCBuYW1lPSImbHQ7aW5pdCZndDsiLz4gPCEtLSBtYXRjaCBjb25zdHJ1Y3RvciAtLT4KKwk8QnVnIHBhdHRlcm49IlVSX1VOSU5JVF9SRUFEIi8+CisgICAgPC9NYXRjaD4KKworICAgIDwhLS0KKwlUaGlzIHVzZSBvZiBzdHJpbmcgY29uY2F0ZW5hdGlvbiBvbmx5IG9jY3VycyB3aGVuIGNyZWF0aW5nIGEKKwlzdHJpbmcgZm9yIGFuIGVycm9yIG1lc3NhZ2UgaW4gYW4gZXhjZXB0aW9uLiAgVGhlIHNpbXBsZXIgY29kZQorCWlzIGJldHRlciBoZXJlOyBwZXJmb3JtYW5jZSBpcyBub3QgYW4gaXNzdWUuCisgICAgLS0+CisgICAgPE1hdGNoPgorCTxDbGFzcyBuYW1lPSJjb20uc3VuLm1haWwudXRpbC5CQVNFNjREZWNvZGVyU3RyZWFtIi8+CisJPE1ldGhvZCBuYW1lPSJyZWNlbnRDaGFycyIvPgorCTxCdWcgcGF0dGVybj0iU0JTQ19VU0VfU1RSSU5HQlVGRkVSX0NPTkNBVEVOQVRJT04iLz4KKyAgICA8L01hdGNoPgorCisgICAgPCEtLQorCVllcywgdGhlICJuZXh0IiBlbGVtZW50IGluIG15IGxpbmtlZCBsaXN0IGlzbid0IGV2ZXIgYWN0dWFsbHkKKwl1c2VkLCBidXQgaXQgZmVlbHMgd2VpcmQgdG8gb25seSBoYXZlIGEgInByZXYiIGVsZW1lbnQuCisgICAgLS0+CisgICAgPE1hdGNoPgorCTxDbGFzcyBuYW1lPSJqYXZheC5tYWlsLkV2ZW50UXVldWUkUXVldWVFbGVtZW50Ii8+CisJPEZpZWxkIG5hbWU9Im5leHQiLz4KKwk8QnVnIHBhdHRlcm49IlVSRl9VTlJFQURfRklFTEQiLz4KKyAgICA8L01hdGNoPgorCisgICAgPCEtLQorCVN0dXBpZCBTZXJpYWxpemFibGUgRXZlbnRPYmplY3QgY2xhc3MgY2F1c2VzIEZpbmRCdWdzIHRvIGNvbXBsYWluCisJYWJvdXQgdHJhbnNpZW50IGZpZWxkcyBpbiBzdWJjbGFzc2VzLiAgSSBkb24ndCBrbm93IHdoeSBpdCdzCisJY29tcGxhaW5pbmcgYWJvdXQgdGhlc2UgZmllbGRzIGJ1dCBub3Qgb3RoZXJzLCBidXQgc2luY2UgSSBkb24ndAorCXJlYWxseSBleHBlY3QgYW55b25lIHRvIHNlcmlhbGl6ZSB0aGVzZSBldmVudHMgSSdtIGp1c3QgaWdub3JpbmcKKwl0aGlzIGNvbXBsYWludC4gIERpdHRvIEV4Y2VwdGlvbiBmaWVsZHMuCisgICAgLS0+CisgICAgPE1hdGNoPgorCTxDbGFzcyBuYW1lPSJqYXZheC5tYWlsLmV2ZW50LlRyYW5zcG9ydEV2ZW50Ii8+CisJPE9yPgorCSAgICA8RmllbGQgbmFtZT0iaW52YWxpZCIvPgorCSAgICA8RmllbGQgbmFtZT0idmFsaWRTZW50Ii8+CisJICAgIDxGaWVsZCBuYW1lPSJ2YWxpZFVuc2VudCIvPgorCTwvT3I+CisJPEJ1ZyBwYXR0ZXJuPSJTRV9UUkFOU0lFTlRfRklFTERfTk9UX1JFU1RPUkVEIi8+CisgICAgPC9NYXRjaD4KKyAgICA8TWF0Y2g+CisJPENsYXNzIG5hbWU9ImphdmF4Lm1haWwuZXZlbnQuRm9sZGVyRXZlbnQiLz4KKwk8T3I+CisJICAgIDxGaWVsZCBuYW1lPSJmb2xkZXIiLz4KKwkgICAgPEZpZWxkIG5hbWU9Im5ld0ZvbGRlciIvPgorCTwvT3I+CisJPEJ1ZyBwYXR0ZXJuPSJTRV9UUkFOU0lFTlRfRklFTERfTk9UX1JFU1RPUkVEIi8+CisgICAgPC9NYXRjaD4KKyAgICA8TWF0Y2g+CisJPENsYXNzIG5hbWU9ImphdmF4Lm1haWwuZXZlbnQuTWVzc2FnZUNoYW5nZWRFdmVudCIvPgorCTxGaWVsZCBuYW1lPSJtc2ciLz4KKwk8QnVnIHBhdHRlcm49IlNFX1RSQU5TSUVOVF9GSUVMRF9OT1RfUkVTVE9SRUQiLz4KKyAgICA8L01hdGNoPgorICAgIDxNYXRjaD4KKwk8Q2xhc3MgbmFtZT0iamF2YXgubWFpbC5ldmVudC5NZXNzYWdlQ291bnRFdmVudCIvPgorCTxGaWVsZCBuYW1lPSJtc2dzIi8+CisJPEJ1ZyBwYXR0ZXJuPSJTRV9UUkFOU0lFTlRfRklFTERfTk9UX1JFU1RPUkVEIi8+CisgICAgPC9NYXRjaD4KKyAgICA8TWF0Y2g+CisJPENsYXNzIG5hbWU9ImphdmF4Lm1haWwuZXZlbnQuVHJhbnNwb3J0RXZlbnQiLz4KKwk8RmllbGQgbmFtZT0ibXNnIi8+CisJPEJ1ZyBwYXR0ZXJuPSJTRV9UUkFOU0lFTlRfRklFTERfTk9UX1JFU1RPUkVEIi8+CisgICAgPC9NYXRjaD4KKyAgICA8TWF0Y2g+CisJPENsYXNzIG5hbWU9ImphdmF4Lm1haWwuU2VuZEZhaWxlZEV4Y2VwdGlvbiIvPgorCTxPcj4KKwkgICAgPEZpZWxkIG5hbWU9ImludmFsaWQiLz4KKwkgICAgPEZpZWxkIG5hbWU9InZhbGlkU2VudCIvPgorCSAgICA8RmllbGQgbmFtZT0idmFsaWRVbnNlbnQiLz4KKwk8L09yPgorCTxCdWcgcGF0dGVybj0iU0VfVFJBTlNJRU5UX0ZJRUxEX05PVF9SRVNUT1JFRCIvPgorICAgIDwvTWF0Y2g+CisKKyAgICA8IS0tCisJVGhlc2Ugc3RyaW5nIGNvbXBhcmlzb25zIGFyZSBqdXN0IG9wdGltaXphdGlvbnMuCisgICAgLS0+CisgICAgPE1hdGNoPgorCTxPcj4KKwkgICAgPENsYXNzIG5hbWU9ImphdmF4Lm1haWwuVVJMTmFtZSIvPgorCSAgICA8Q2xhc3MgbmFtZT0iamF2YXgubWFpbC5pbnRlcm5ldC5JbnRlcm5ldEFkZHJlc3MiLz4KKwk8L09yPgorCTxNZXRob2QgbmFtZT0iZXF1YWxzIi8+CisJPEJ1ZyBwYXR0ZXJuPSJFU19DT01QQVJJTkdfU1RSSU5HU19XSVRIX0VRIi8+CisgICAgPC9NYXRjaD4KKworICAgIDwhLS0KKwlUaGlzIHN0cmluZyBjb21wYXJpc29uIHVzaW5nID09IGlzIHRvIGRldGVybWluZSB3aGV0aGVyIHRoZQorCVN0cmluZyBvYmplY3QgaXMgYSBkaWZmZXJlbnQgU3RyaW5nIG9iamVjdC4KKyAgICAtLT4KKyAgICA8TWF0Y2g+CisJPENsYXNzIG5hbWU9ImphdmF4Lm1haWwuaW50ZXJuZXQuTWltZVV0aWxpdHkiLz4KKwk8TWV0aG9kIG5hbWU9ImRlY29kZVRleHQiLz4KKwk8QnVnIHBhdHRlcm49IkVTX0NPTVBBUklOR19TVFJJTkdTX1dJVEhfRVEiLz4KKyAgICA8L01hdGNoPgorCisgICAgPCEtLQorCVRoaXMgc3RyaW5nIGNvbXBhcmlzb24gdXNpbmcgPT0gaXMgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdGhlCisJU3RyaW5nIG9iamVjdCBpcyB0aGUgb3JpZ2luYWwgZGVmYXVsdCBTdHJpbmcgb2JqZWN0LgorICAgIC0tPgorICAgIDxNYXRjaD4KKwk8Q2xhc3MgbmFtZT0iY29tLnN1bi5tYWlsLnNtdHAuU01UUFRyYW5zcG9ydCIvPgorCTxNZXRob2QgbmFtZT0iYXV0aGVudGljYXRlIi8+CisJPEJ1ZyBwYXR0ZXJuPSJFU19DT01QQVJJTkdfU1RSSU5HU19XSVRIX0VRIi8+CisgICAgPC9NYXRjaD4KKworICAgIDwhLS0KKwlCeXRlQXJyYXlJbnB1dFN0cmVhbS5hdmFpbGFibGUgZ3VhcmFudGVlcyB0byByZXR1cm4gdGhlIGZ1bGwgbnVtYmVyCisJb2YgYnl0ZXMgbGVmdCBpbiB0aGUgYnVmZmVyLCBhbmQgQnl0ZUFycmF5SW5wdXRTdHJlYW0ucmVhZCBndWFyYW50ZWVzCisJdG8gcmVhZCBhbGwgdGhlIGJ5dGVzLCBzbyB3ZSBkb24ndCByZWFsbHkgbmVlZCB0byBjaGVjayB0aGUgcmV0dXJuCisJdmFsdWUuICBJZ25vcmUgdGhpcyBjb21wbGFpbnQuCisgICAgLS0+CisgICAgPE1hdGNoPgorCTxDbGFzcyBuYW1lPSJjb20uc3VuLm1haWwudXRpbC5BU0NJSVV0aWxpdHkiLz4KKwk8TWV0aG9kIG5hbWU9ImdldEJ5dGVzIi8+CisJPEJ1ZyBwYXR0ZXJuPSJETFNfREVBRF9MT0NBTF9TVE9SRSIvPgorICAgIDwvTWF0Y2g+CisKKyAgICA8IS0tCisJV2UgZXh0cmFjdCB0aGUgImxhbmciIGZpZWxkIG9mIGFuIGVuY29kZWQgc3RyaW5nIGJ1dCB3ZSBkb24ndAorCWN1cnJlbnRseSBkbyBhbnl0aGluZyB3aXRoIGl0LiAgSWdub3JlIHRoaXMgY29tcGxhaW50LgorICAgIC0tPgorICAgIDxNYXRjaD4KKwk8Q2xhc3MgbmFtZT0iamF2YXgubWFpbC5pbnRlcm5ldC5QYXJhbWV0ZXJMaXN0Ii8+CisJPE1ldGhvZCBuYW1lPSJkZWNvZGVWYWx1ZSIvPgorCTxCdWcgcGF0dGVybj0iRExTX0RFQURfTE9DQUxfU1RPUkUiLz4KKyAgICA8L01hdGNoPgorCisgICAgPCEtLQorCVRoZSBjYWxsIFBhcmFtZXRlckxpc3Quc2V0KG51bGwsICJET05FIikgaXMgYSBrbHVkZ2UgdXNlZCBieSB0aGUKKwlJTUFQIHByb3ZpZGVyIHRvIGluZGljYXRlIHRoYXQgaXQncyBkb25lIHNldHRpbmcgcGFyYW1ldGVycy4KKwlJbiBvdGhlciBjYXNlcyB3ZSAqd2FudCogYSBudWxsIG5hbWUgdG8gY2F1c2UgYSBOdWxsUG9pbnRlckV4Y2VwdGlvbi4KKyAgICAtLT4KKyAgICA8TWF0Y2g+CisJPENsYXNzIG5hbWU9ImphdmF4Lm1haWwuaW50ZXJuZXQuUGFyYW1ldGVyTGlzdCIvPgorCTxNZXRob2QgbmFtZT0ic2V0Ii8+CisJPEJ1ZyBwYXR0ZXJuPSJOUF9OVUxMX09OX1NPTUVfUEFUSCIvPgorICAgIDwvTWF0Y2g+CisKKyAgICA8IS0tCisJV2UgcHVycG9zZWx5IGRvbid0IGNsb3NlIHRoZXNlIHN0cmVhbXMsIHdoaWNoIGFyZSBqdXN0IHdyYXBwZXJzCisJYXJvdW5kIHRoZSBvcmlnaW5hbCBzdHJlYW0gdGhhdCBuZWVkcyB0byByZW1haW4gb3Blbi4KKyAgICAtLT4KKyAgICA8TWF0Y2g+CisJPENsYXNzIG5hbWU9ImphdmF4Lm1haWwuaW50ZXJuZXQuTWltZU11bHRpcGFydCIvPgorCTxPcj4KKwkgICAgPE1ldGhvZCBuYW1lPSJwYXJzZSIvPgorCSAgICA8TWV0aG9kIG5hbWU9InBhcnNlYm0iLz4KKwk8L09yPgorCTxCdWcgcGF0dGVybj0iT1NfT1BFTl9TVFJFQU0iLz4KKyAgICA8L01hdGNoPgorCisgICAgPCEtLQorCVdoZW4gZGVsZXRpbmcgdGhlIHRlbXAgZmlsZSBmYWlscywgdGhlcmUncyByZWFsbHkgbm90aGluZyB0byBiZSBkb25lLgorICAgIC0tPgorICAgIDxNYXRjaD4KKwk8Q2xhc3MgbmFtZT0iY29tLnN1bi5tYWlsLnBvcDMuVGVtcEZpbGUiLz4KKwk8TWV0aG9kIG5hbWU9ImNsb3NlIi8+CisJPEJ1ZyBwYXR0ZXJuPSJSVl9SRVRVUk5fVkFMVUVfSUdOT1JFRF9CQURfUFJBQ1RJQ0UiLz4KKyAgICA8L01hdGNoPgorCisgICAgPCEtLQorCUluIElNQVBGb2xkZXIuY2xvc2UsIEkgYmVsaWV2ZSB0aGUgcHJvdG9jb2wgZmllbGQgY2FuIGJlIHNldCB0byBudWxsCisJYXMgYSByZXN1bHQgb2YgYSBwcm90b2NvbCBlcnJvciB0aGF0IGludm9rZXMgYSBjYWxsYmFjayB0aGF0IGNhbGxzCisJY2xlYW51cCwgdGh1cyBJIGRvbid0IGJlbGlldmUgdGhlc2UgbnVsbCBjaGVja3MgYXJlIHJlZHVuZGFudC4KKyAgICAtLT4KKyAgICA8TWF0Y2g+CisJPENsYXNzIG5hbWU9ImNvbS5zdW4ubWFpbC5pbWFwLklNQVBGb2xkZXIiLz4KKwk8TWV0aG9kIG5hbWU9ImNsb3NlIi8+CisJPEJ1ZyBwYXR0ZXJuPSJSQ05fUkVEVU5EQU5UX05VTExDSEVDS19XT1VMRF9IQVZFX0JFRU5fQV9OUEUiLz4KKyAgICA8L01hdGNoPgorCisgICAgPCEtLQorCUNhbid0IGZpeCB0aGVzZSBlcnJvcnMgaW4gdG9TdHJpbmcgdW50aWwgSmF2YU1haWwgMS41IGJlY2F1c2UKKwlpdCdzIHBhcnQgb2YgdGhlIHNwZWMuICBTaWdoLgorICAgIC0tPgorICAgIDxNYXRjaD4KKwk8T3I+CisJICAgIDxDbGFzcyBuYW1lPSJqYXZheC5tYWlsLmludGVybmV0LkNvbnRlbnREaXNwb3NpdGlvbiIvPgorCSAgICA8Q2xhc3MgbmFtZT0iamF2YXgubWFpbC5pbnRlcm5ldC5Db250ZW50VHlwZSIvPgorCTwvT3I+CisJPE1ldGhvZCBuYW1lPSJ0b1N0cmluZyIvPgorCTxCdWcgcGF0dGVybj0iTlBfVE9TVFJJTkdfQ09VTERfUkVUVVJOX05VTEwiLz4KKyAgICA8L01hdGNoPgorCisgICAgPCEtLQorCUlNQVBGb2xkZXIudWlkVGFibGUgaXMgb25seSBldmVyIG1hbmlwdWxhdGVkIHdoZW4gdGhlCisJbWVzc2FnZUNhY2hlTG9jayBpcyBoZWxkLCBidXQgRmluZEJ1Z3MgY2FuJ3QgZmlndXJlIHRoYXQgb3V0LgorICAgIC0tPgorICAgIDxNYXRjaD4KKwk8Q2xhc3MgbmFtZT0iY29tLnN1bi5tYWlsLmltYXAuSU1BUEZvbGRlciIvPgorCTxGaWVsZCBuYW1lPSJ1aWRUYWJsZSIvPgorCTxCdWcgcGF0dGVybj0iSVMyX0lOQ09OU0lTVEVOVF9TWU5DIi8+CisgICAgPC9NYXRjaD4KKworICAgIDwhLS0KKwlJTUFQRm9sZGVyLmRvRXhwdW5nZU5vdGlmaWNhdGlvbiBpcyBvbmx5IGV2ZXIgbWFuaXB1bGF0ZWQgd2hlbiB0aGUKKwltZXNzYWdlQ2FjaGVMb2NrIGlzIGhlbGQsIGJ1dCBGaW5kQnVncyBjYW4ndCBmaWd1cmUgdGhhdCBvdXQuCisgICAgLS0+CisgICAgPE1hdGNoPgorCTxDbGFzcyBuYW1lPSJjb20uc3VuLm1haWwuaW1hcC5JTUFQRm9sZGVyIi8+CisJPEZpZWxkIG5hbWU9ImRvRXhwdW5nZU5vdGlmaWNhdGlvbiIvPgorCTxCdWcgcGF0dGVybj0iSVMyX0lOQ09OU0lTVEVOVF9TWU5DIi8+CisgICAgPC9NYXRjaD4KKworICAgIDwhLS0KKwlUaGUgc3RhdGljIG1haWxEYXRlRm9ybWF0IGZpZWxkIGlzIG9ubHkgdXNlZCB0byBhY2Nlc3MgdGhlIHBhcnNlCisJbWV0aG9kLCB3aGljaCBpcyBrbm93biB0byBiZSB0aHJlYWQgc2FmZSwgc28gd2UgY2FuIGlnbm9yZSB0aGlzIGVycm9yLgorICAgIC0tPgorICAgIDxNYXRjaD4KKwk8Q2xhc3MgbmFtZT0iY29tLnN1bi5tYWlsLmltYXAucHJvdG9jb2wuSU5URVJOQUxEQVRFIi8+CisJPEJ1ZyBwYXR0ZXJuPSJTVENBTF9JTlZPS0VfT05fU1RBVElDX0RBVEVfRk9STUFUX0lOU1RBTkNFIi8+CisgICAgPC9NYXRjaD4KKworICAgIDwhLS0KKwlUaGVzZSBlcnJvcnMgYXJlIGluIGNvZGUgaW1wb3J0ZWQgZnJvbSB0aGUgSkRLLCB3aGVyZSBpdCBzZWVtcworCXRvIGJlIHB1cnBvc2VseSB1c2luZyB0aGUgcGxhdGZvcm0gZGVmYXVsdCBlbmNvZGluZy4gIEl0J3Mgc2FmZXIKKwl0byBqdXN0IGxlYXZlIHRoaXMgYWxvbmUgYW5kIGlnbm9yZSB0aGUgZXJyb3JzLgorICAgIC0tPgorICAgIDxNYXRjaD4KKwk8Q2xhc3MgbmFtZT0iamF2YXgubWFpbC5VUkxOYW1lIi8+CisJPEJ1ZyBwYXR0ZXJuPSJETV9ERUZBVUxUX0VOQ09ESU5HIi8+CisgICAgPC9NYXRjaD4KKworICAgIDwhLS0KKwlXZSdyZSBwdXJwb3NlbHkgdXNpbmcgdGhlIHBsYXRmb3JtIGRlZmF1bHQgZW5jb2RpbmcgYmVjYXVzZQorCXdlJ3JlIHRyeWluZyB0byBkaXNjb3ZlciB3aGF0IHRoZSBwbGF0Zm9ybSBkZWZhdWx0IGVuY29kaW5nICppcyohCisgICAgLS0+CisgICAgPE1hdGNoPgorCTxDbGFzcyBuYW1lPSJqYXZheC5tYWlsLmludGVybmV0Lk1pbWVVdGlsaXR5Ii8+CisJPE1ldGhvZCBuYW1lPSJnZXREZWZhdWx0SmF2YUNoYXJzZXQiLz4KKwk8QnVnIHBhdHRlcm49IkRNX0RFRkFVTFRfRU5DT0RJTkciLz4KKyAgICA8L01hdGNoPgorCisgICAgPCEtLQorCVdlJ3JlIHB1cnBvc2VseSB1c2luZyB0aGUgcGxhdGZvcm0gZGVmYXVsdCBlbmNvZGluZyB3aGVuIGEKKwljaGFyc2V0IGhhc24ndCBiZWVuIHNwZWNpZmllZC4KKyAgICAtLT4KKyAgICA8TWF0Y2g+CisJPENsYXNzIG5hbWU9ImphdmF4Lm1haWwuaW50ZXJuZXQuUGFyYW1ldGVyTGlzdCIvPgorCTxNZXRob2QgbmFtZT0iY29tYmluZU11bHRpc2VnbWVudE5hbWVzIi8+CisJPEJ1ZyBwYXR0ZXJuPSJETV9ERUZBVUxUX0VOQ09ESU5HIi8+CisgICAgPC9NYXRjaD4KKworICAgIDwhLS0KKwlXZSdyZSBwdXJwb3NlbHkgdXNpbmcgdGhlIHBsYXRmb3JtIGRlZmF1bHQgZW5jb2RpbmcgYmVjYXVzZQorCXdlJ3JlIGNvbnZlcnRpbmcgYnl0ZXMgdGhhdCB3ZXJlIHdyaXR0ZW4gdXNpbmcgdGhlIHBsYXRmb3JtCisJZGVmYXVsdCBlbmNvZGluZyBiYWNrIHRvIGEgU3RyaW5nLgorICAgIC0tPgorICAgIDxNYXRjaD4KKwk8Q2xhc3MgbmFtZT0iY29tLnN1bi5tYWlsLnV0aWwuTG9nT3V0cHV0U3RyZWFtIi8+CisJPE1ldGhvZCBuYW1lPSJsb2dCdWYiLz4KKwk8QnVnIHBhdHRlcm49IkRNX0RFRkFVTFRfRU5DT0RJTkciLz4KKyAgICA8L01hdGNoPgorCisgICAgPCEtLQorCU1pbWVCb2R5UGFydC5oZWFkZXJzIGlzIHNldCBpbiB0aGUgY29uc3RydWN0b3IuICBJTUFQQm9keVBhcnQgaGFzCisJcGVyaGFwcyBwYXJhbm9pZCBkZWZlbnNpdmUgY29kZSB0byBzZXQgaXQgaWYgaXQncyBub3Qgc2V0LiAgVGhhdAorCWNvZGUgaXMgcHJvdGVjdGVkIGJ5IHRoZSBvYmplY3QgbG9jaywgYnV0IGFsbCBvZiB0aGUgcmVhZHMgb2YgdGhlCisJZmllbGQgYXJlIG5vdCwgdGh1cyBGaW5kQnVncyBjb21wbGFpbnMuICBGb3Igbm93IEkgdGhpbmsgaXQncworCWJldHRlciB0byBsZWF2ZSB0aGUgZGVmZW5zaXZlIGNvZGUgaW4gYW5kIGlnbm9yZSB0aGlzIGVycm9yLgorICAgIC0tPgorICAgIDxNYXRjaD4KKwk8Q2xhc3MgbmFtZT0iamF2YXgubWFpbC5pbnRlcm5ldC5NaW1lQm9keVBhcnQiLz4KKwk8RmllbGQgbmFtZT0iaGVhZGVycyIvPgorCTxCdWcgcGF0dGVybj0iSVMyX0lOQ09OU0lTVEVOVF9TWU5DIi8+CisgICAgPC9NYXRjaD4KKworICAgIDwhLS0KKwlSZWZhY3RvcmluZyB0aGVzZSBhbm9ueW1vdXMgaW5uZXIgY2xhc3NlcyB0byBiZSBzdGF0aWMgY2xhc3NlcworCW1ha2VzIHRoZSBjb2RlIGxlc3MgcmVhZGFibGUuICBUb28gYmFkIHRoZXJlJ3Mgbm8gd2F5IGZvciBhbgorCWFub255bW91cyBpbm5lciBjbGFzcyB0byBiZSBzdGF0aWMuCisJWFhYIC0gdGhlc2UgY2xhc3MgbmFtZXMgYXJlbid0IGdvaW5nIHRvIGJlIHN0YWJsZSBhcyB0aGUgY29kZSBjaGFuZ2VzCisgICAgLS0+CisgICAgPE1hdGNoPgorCTxPcj4KKwkgICAgPENsYXNzIG5hbWU9ImNvbS5zdW4ubWFpbC5pbWFwLkRlZmF1bHRGb2xkZXIkMSIvPgorCSAgICA8Q2xhc3MgbmFtZT0iY29tLnN1bi5tYWlsLmltYXAuRGVmYXVsdEZvbGRlciQyIi8+CisJICAgIDxDbGFzcyBuYW1lPSJjb20uc3VuLm1haWwuaW1hcC5JTUFQRm9sZGVyJDEiLz4KKwkgICAgPENsYXNzIG5hbWU9ImNvbS5zdW4ubWFpbC5pbWFwLklNQVBGb2xkZXIkNCIvPgorCSAgICA8Q2xhc3MgbmFtZT0iY29tLnN1bi5tYWlsLmltYXAuSU1BUEZvbGRlciQ3Ii8+CisJICAgIDxDbGFzcyBuYW1lPSJjb20uc3VuLm1haWwuaW1hcC5JTUFQRm9sZGVyJDEzIi8+CisJICAgIDxDbGFzcyBuYW1lPSJjb20uc3VuLm1haWwuaW1hcC5JTUFQRm9sZGVyJDIwIi8+CisJICAgIDxDbGFzcyBuYW1lPSJjb20uc3VuLm1haWwuaW1hcC5JZGxlTWFuYWdlciQyIi8+CisJPC9Pcj4KKwk8QnVnIHBhdHRlcm49IlNJQ19JTk5FUl9TSE9VTERfQkVfU1RBVElDX0FOT04iLz4KKyAgICA8L01hdGNoPgorCisgICAgPCEtLQorCVNwb3RCdWdzIGRvZXNuJ3QgcmVjb2duaXplIHRoZSBhbm9ueW1vdXMgaW5uZXIgY2xhc3NlcyBhYm92ZS4KKwlodHRwczovL2dpdGh1Yi5jb20vc3BvdGJ1Z3MvZGlzY3Vzcy9pc3N1ZXMvMjIKKwlUaGlzIHJlZ3VsYXIgZXhwcmVzc2lvbiB2ZXJzaW9uIGhhcyB0aGUgc2FtZSBlZmZlY3QsIGFuZAorCWF2b2lkcyB0aGUgcG90ZW50aWFsIGlzc3VlIHdpdGggdGhlIGNsYXNzIG5hbWVzIGNoYW5naW5nLgorICAgIC0tPgorICAgIDxNYXRjaD4KKwk8T3I+CisJICAgIDxDbGFzcyBuYW1lPSJ+Y29tXC5zdW5cLm1haWxcLmltYXBcLkRlZmF1bHRGb2xkZXIuKiIvPgorCSAgICA8Q2xhc3MgbmFtZT0ifmNvbVwuc3VuXC5tYWlsXC5pbWFwXC5JTUFQRm9sZGVyLioiLz4KKwkgICAgPENsYXNzIG5hbWU9In5jb21cLnN1blwubWFpbFwuaW1hcFwuSWRsZU1hbmFnZXIuKiIvPgorCTwvT3I+CisJPEJ1ZyBwYXR0ZXJuPSJTSUNfSU5ORVJfU0hPVUxEX0JFX1NUQVRJQ19BTk9OIi8+CisgICAgPC9NYXRjaD4KKworICAgIDwhLS0KKwlFdmVuIHRob3VnaCBvbmx5IHRoaXMgYXJyYXkgcmVmZXJlbmNlIGlzIHZvbGF0aWxlLCB0aGUgYXJyYXkgaXMKKwl1c2VkIGluIHN1Y2ggYSB3YXkgdGhhdCBpdCdzIHNhZmUuICBUaGUgYXJheSBlbGVtZW50cyBhcmUgY3JlYXRlZAorCWFuZCBpbml0aWFsaXplZCBiZWZvcmUgdGhlIGFycmF5IGlzIGFzc2lnbmVkIHRvIHRoaXMgYXJyYXkKKwlyZWZlcmVuY2UsIGFuZCBhZnRlciBiZWluZyBhc3NpZ25lZCBuZWl0aGVyIHRoZSBhcnJheSBub3IgdGhlCisJYXJyYXkgZWxlbWVudHMgYXJlIGNoYW5nZWQuCisgICAgLS0+CisgICAgPE1hdGNoPgorCTxDbGFzcyBuYW1lPSJjb20uc3VuLm1haWwuaW1hcC5JTUFQRm9sZGVyIi8+CisJPEZpZWxkIG5hbWU9ImF0dHJpYnV0ZXMiLz4KKwk8QnVnIHBhdHRlcm49IlZPX1ZPTEFUSUxFX1JFRkVSRU5DRV9UT19BUlJBWSIvPgorICAgIDwvTWF0Y2g+CisKKyAgICA8IS0tCisJVGhpcyBjb2RlIGlzIGVhc2llciB0byB1bmRlcnN0YW5kIHdpdGggZW1wdHkgImlmIiBjbGF1c2VzOworCXRoZSAibWF0Y2giIG1ldGhvZCBpcyBiZWluZyBjYWxsZWQgZm9yIGl0cyBzaWRlIGVmZmVjdHMuCisgICAgLS0+CisgICAgPE1hdGNoPgorCTxDbGFzcyBuYW1lPSJjb20uc3VuLm1haWwuaW1hcC5wcm90b2NvbC5GZXRjaFJlc3BvbnNlIi8+CisJPE1ldGhvZCBuYW1lPSJwYXJzZUl0ZW0iLz4KKwk8QnVnIHBhdHRlcm49IlVDRl9VU0VMRVNTX0NPTlRST0xfRkxPVyIvPgorICAgIDwvTWF0Y2g+CisKKyAgICA8IS0tCisJRXZlbiB0aG91Z2ggdGhlc2UgZmllbGRzIGFyZSB1bnJlYWQgZm9yIG5vdywgd2UnbGwga2VlcCB0aGVtCisJc2luY2UgdGhleSByZXByZXNlbnQgZGF0YSBpbiB0aGUgcHJvdG9jb2wgbWVzc2FnZSBiZWluZyBwYXJzZWQuCisgICAgLS0+CisgICAgPE1hdGNoPgorCTxPcj4KKwkgICAgPENsYXNzIG5hbWU9ImNvbS5zdW4ubWFpbC5pbWFwLnByb3RvY29sLkVOVkVMT1BFIi8+CisJICAgIDxDbGFzcyBuYW1lPSJjb20uc3VuLm1haWwuaW1hcC5wcm90b2NvbC5JTlRFUk5BTERBVEUiLz4KKwkgICAgPENsYXNzIG5hbWU9ImNvbS5zdW4ubWFpbC5pbWFwLnByb3RvY29sLlJGQzgyMlNJWkUiLz4KKwk8L09yPgorCTxGaWVsZCBuYW1lPSJtc2dubyIvPgorCTxCdWcgcGF0dGVybj0iVVJGX1VOUkVBRF9QVUJMSUNfT1JfUFJPVEVDVEVEX0ZJRUxEIi8+CisgICAgPC9NYXRjaD4KKyAgICA8TWF0Y2g+CisJPENsYXNzIG5hbWU9ImNvbS5zdW4ubWFpbC5pbWFwLnByb3RvY29sLk1haWxib3hJbmZvIi8+CisJPEZpZWxkIG5hbWU9ImZpcnN0Ii8+CisJPEJ1ZyBwYXR0ZXJuPSJVUkZfVU5SRUFEX1BVQkxJQ19PUl9QUk9URUNURURfRklFTEQiLz4KKyAgICA8L01hdGNoPgorICAgIDwhLS0KKwlUaGVzZSB1bnJlYWQgZmllbGRzIGFyZSBwYXJ0IG9mIHRoZSBwdWJsaWMgQVBJLgorICAgIC0tPgorICAgIDxNYXRjaD4KKwk8Q2xhc3MgbmFtZT0iamF2YXgubWFpbC5TZXJ2aWNlIi8+CisJPEZpZWxkIG5hbWU9ImRlYnVnIi8+CisJPEJ1ZyBwYXR0ZXJuPSJVUkZfVU5SRUFEX1BVQkxJQ19PUl9QUk9URUNURURfRklFTEQiLz4KKyAgICA8L01hdGNoPgorICAgIDxNYXRjaD4KKwk8Q2xhc3MgbmFtZT0iamF2YXgubWFpbC5RdW90YSRSZXNvdXJjZSIvPgorCTxGaWVsZCBuYW1lPSJ1c2FnZSIvPgorCTxCdWcgcGF0dGVybj0iVVJGX1VOUkVBRF9QVUJMSUNfT1JfUFJPVEVDVEVEX0ZJRUxEIi8+CisgICAgPC9NYXRjaD4KKworICAgIDwhLS0KKwlXZSB1c2UgYSBzdGF0aWMgTWFpbERhdGVGb3JtYXQgaW5zdGFuY2UsIHdoaWNoIHVzZXMgYSBzdGF0aWMKKwlHcmVnb3JpYW5DYWxlbmRhciBpbnN0YW5jZS4gIFRoZSBNYWlsRGF0ZUZvcm1hdC5wYXJzZSBtZXRob2QKKwl1c2VzIG9ubHkgbG9jYWwgZGF0YSBleGNlcHQgZm9yIHRoZSBHcmVnb3JpYW5DYWxlbmRhciBpbnN0YW5jZSwKKwl3aGljaCBpcyBpbnZva2VkIHRocm91Z2ggYSBzdGF0aWMgc3luY2hyb25pemVkIG1ldGhvZC4KKyAgICAtLT4KKyAgICA8TWF0Y2g+CisJPENsYXNzIG5hbWU9ImNvbS5zdW4ubWFpbC5pbWFwLnByb3RvY29sLkVOVkVMT1BFIi8+CisJPEJ1ZyBwYXR0ZXJuPSJTVENBTF9JTlZPS0VfT05fU1RBVElDX0RBVEVfRk9STUFUX0lOU1RBTkNFIi8+CisgICAgPC9NYXRjaD4KKworICAgIDwhLS0KKwlBIHNwZWNpYWwgU3RyaW5nIGluc3RhbmNlIGlzIHVzZWQgdG8gaW5kaWNhdGUgdGhhdCB0aGUgUE9QMworCVVJRCBpcyB1bmtub3duLiAgVGhlIHVpZCBmaWVsZCBpcyBpbml0aWFsaXplZCB0byB0aGlzIFN0cmluZworCWluc3RhbmNlLCB3aGljaCB3ZSB0aGVuIGNvbXBhcmUgd2l0aCBsYXRlciB0byBzZWUgaWYgdGhlIHVpZAorCWhhcyBiZWVuIHNldC4KKyAgICAtLT4KKyAgICA8TWF0Y2g+CisJPENsYXNzIG5hbWU9ImNvbS5zdW4ubWFpbC5wb3AzLlBPUDNGb2xkZXIiLz4KKwk8TWV0aG9kIG5hbWU9ImdldFVJRCIvPgorCTxCdWcgcGF0dGVybj0iRVNfQ09NUEFSSU5HX1NUUklOR1NfV0lUSF9FUSIvPgorICAgIDwvTWF0Y2g+CisgICAgPCEtLQorCUFzIGFib3ZlLCBhIHNwZWNpYWwgU3RyaW5nIGluc3RhbmNlIGlzIHVzZWQgdG8gaW5kaWNhdGUgd2hldGhlcgorCWNlcnRhaW4gZmllbGRzIGhhdmUgYmVlbiBzZXQuCisgICAgLS0+CisgICAgPE1hdGNoPgorCTxDbGFzcyBuYW1lPSJjb20uc3VuLm1haWwuc210cC5TTVRQVHJhbnNwb3J0Ii8+CisJPE9yPgorCSAgICA8TWV0aG9kIG5hbWU9ImdldEF1dGhvcml6YXRpb25JZCIvPgorCSAgICA8TWV0aG9kIG5hbWU9ImdldE5UTE1Eb21haW4iLz4KKwkgICAgPE1ldGhvZCBuYW1lPSJnZXRTQVNMUmVhbG0iLz4KKwk8L09yPgorCTxCdWcgcGF0dGVybj0iRVNfQ09NUEFSSU5HX1NUUklOR1NfV0lUSF9FUSIvPgorICAgIDwvTWF0Y2g+CisKKyAgICA8IS0tCisJSSBrbm93IEV4Y2VwdGlvbi50b1N0cmluZyBpcyBuZXZlciBzdXBwb3NlZCB0byByZXR1cm4gbnVsbCwKKwlidXQgdGhpcyBleHRyYSBjaGVjayBpcyBjaGVhcCBpbnN1cmFuY2UuCisgICAgLS0+CisgICAgPE1hdGNoPgorCTxDbGFzcyBuYW1lPSJqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbiIvPgorCTxNZXRob2QgbmFtZT0idG9TdHJpbmciLz4KKwk8QnVnIHBhdHRlcm49IlJDTl9SRURVTkRBTlRfTlVMTENIRUNLX09GX05PTk5VTExfVkFMVUUiLz4KKyAgICA8L01hdGNoPgorICAgIDwhLS0KKwlJIGtub3cgQ2xhc3NMb2FkZXIuZ2V0UmVzb3VyY2VzIGlzIG5ldmVyIHN1cHBvc2VkIHRvIHJldHVybiBudWxsLAorCWJ1dCB0aGlzIGV4dHJhIGNoZWNrIGlzIGNoZWFwIGluc3VyYW5jZS4KKyAgICAtLT4KKyAgICA8TWF0Y2g+CisJPENsYXNzIG5hbWU9In5qYXZheFwubWFpbFwuU2Vzc2lvblwkLioiLz4KKwk8TWV0aG9kIG5hbWU9InJ1biIvPgorCTxCdWcgcGF0dGVybj0iUkNOX1JFRFVOREFOVF9OVUxMQ0hFQ0tfT0ZfTk9OTlVMTF9WQUxVRSIvPgorICAgIDwvTWF0Y2g+CisKKyAgICA8IS0tCisJVGhlc2UgbmFtZXMgbWF5IGJlIGNvbmZ1c2luZywgYnV0IHdlJ3JlIHN0dWNrIHdpdGggdGhlbS4KKyAgICAtLT4KKyAgICA8TWF0Y2g+CisJPENsYXNzIG5hbWU9ImphdmF4Lm1haWwuUGFzc3dvcmRBdXRoZW50aWNhdGlvbiIvPgorCTxNZXRob2QgbmFtZT0iZ2V0VXNlck5hbWUiLz4KKwk8QnVnIHBhdHRlcm49Ik5NX0NPTkZVU0lORyIvPgorICAgIDwvTWF0Y2g+CisKKyAgICA8IS0tCisJVGhpcyB0cml2aWFsIGlubmVyIGNsYXNzIGV4dGVuZHMgQXJyYXlMaXN0LCBidXQgaXMgbmV2ZXIgc2VyaWFsaXplZCwKKwlzbyBpdCBkb2Vzbid0IHJlYWxseSBuZWVkIGEgc2VyaWFsVmVyc2lvblVJRC4KKyAgICAtLT4KKyAgICA8TWF0Y2g+CisJPENsYXNzIG5hbWU9ImphdmF4Lm1haWwuaW50ZXJuZXQuUGFyYW1ldGVyTGlzdCRNdWx0aVZhbHVlIi8+CisJPEJ1ZyBwYXR0ZXJuPSJTRV9OT19TRVJJQUxWRVJTSU9OSUQiLz4KKyAgICA8L01hdGNoPgorCisgICAgPCEtLQorCVRoZXNlIGFycmF5IHJlZmVyZW5jZXMgYXJlIGRlY2xhcmVkIHZvbGF0aWxlIGJlY2F1c2UgdGhleSdyZQorCXRyZWF0ZWQgYXMgY29weS1vbi13cml0ZS4KKyAgICAtLT4KKyAgICA8TWF0Y2g+CisJPENsYXNzIG5hbWU9ImNvbS5zdW4ubWFpbC51dGlsLmxvZ2dpbmcuTG9nTWFuYWdlclByb3BlcnRpZXMiLz4KKwk8RmllbGQgbmFtZT0iUkVGTEVDVF9OQU1FUyIvPgorCTxCdWcgcGF0dGVybj0iVk9fVk9MQVRJTEVfUkVGRVJFTkNFX1RPX0FSUkFZIi8+CisgICAgPC9NYXRjaD4KKyAgICA8TWF0Y2g+CisJPENsYXNzIG5hbWU9ImNvbS5zdW4ubWFpbC51dGlsLmxvZ2dpbmcuTWFpbEhhbmRsZXIiLz4KKwk8RmllbGQgbmFtZT0iYXR0YWNobWVudEZpbHRlcnMiLz4KKwk8QnVnIHBhdHRlcm49IlZPX1ZPTEFUSUxFX1JFRkVSRU5DRV9UT19BUlJBWSIvPgorICAgIDwvTWF0Y2g+CisKKyAgICA8IS0tCisJVGhlIEF1dGhlbnRpY2F0b3IgZmllbGRzIGFyZSBvbmx5IGFjY2Vzc2libGUgYnkgc3ViY2xhc3NlcywKKwl3aGljaCBhcmUgb25seSBjYWxsZWQgdGhyb3VnaCB0aGUgb25lIHN5bmNocm9uaXplZCBwdWJsaWMKKwltZXRob2QsIGFzc3VtaW5nIHRoZSBzdWJjbGFzcyBkb2Vzbid0IGRvIHNvbWV0aGluZyBjcmF6eSBhbmQKKwlleHBvc2UgdGhlbSBpdHNlbGYuCisgICAgLS0+CisgICAgPE1hdGNoPgorCTxDbGFzcyBuYW1lPSJqYXZheC5tYWlsLkF1dGhlbnRpY2F0b3IiLz4KKwk8QnVnIHBhdHRlcm49IklTMl9JTkNPTlNJU1RFTlRfU1lOQyIvPgorICAgIDwvTWF0Y2g+CisKKyAgICA8IS0tCisJSWdub3JlIGZhaWx1cmVzIHRvIGNsb3NlIGNvbm5lY3Rpb24uCisgICAgLS0+CisgICAgPE1hdGNoPgorCTxDbGFzcyBuYW1lPSJjb20uc3VuLm1haWwuc210cC5TTVRQVHJhbnNwb3J0Ii8+CisJPE1ldGhvZCBuYW1lPSJwcm90b2NvbENvbm5lY3QiLz4KKwk8QnVnIHBhdHRlcm49IkRFX01JR0hUX0lHTk9SRSIvPgorICAgIDwvTWF0Y2g+CisKKyAgICA8IS0tCisJVGhpcyBpbm5lciBjbGFzcyBkb2Vzbid0IG5lZWQgInRoaXMiLCBidXQgaXQgY3JlYXRlcyBhbm90aGVyCisJaW5uZXIgY2xhc3MgdGhhdCAqZG9lcyogbmVlZCAidGhpcyIuCisgICAgLS0+CisgICAgPE1hdGNoPgorCTxDbGFzcyBuYW1lPSJjb20uc3VuLm1haWwuc210cC5TTVRQVHJhbnNwb3J0JEJEQVRPdXRwdXRTdHJlYW0iLz4KKwk8QnVnIHBhdHRlcm49IlNJQ19JTk5FUl9TSE9VTERfQkVfU1RBVElDX05FRURTX1RISVMiLz4KKyAgICA8L01hdGNoPgorPC9GaW5kQnVnc0ZpbHRlcj4KZGlmZiAtLWdpdCBhL21haWwvcG9tLnhtbCBiL21haWwvcG9tLnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMDIwZWQwCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9wb20ueG1sCkBAIC0wLDAgKzEsMjE0IEBACis8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJpc28tODg1OS0xIj8+Cis8IS0tCisKKyAgICBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKworICAgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICAgIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorCisgICAgVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICAgIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAgICBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAgICB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKworICAgIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorCistLT4KKworPHByb2plY3QgeG1sbnM9Imh0dHA6Ly9tYXZlbi5hcGFjaGUub3JnL1BPTS80LjAuMCIKKwl4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIgorCXhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL21hdmVuLmFwYWNoZS5vcmcvUE9NLzQuMC4wCisJCQkgICAgaHR0cDovL21hdmVuLmFwYWNoZS5vcmcvbWF2ZW4tdjRfMF8wLnhzZCI+CisgICAgPHBhcmVudD4KKwk8Z3JvdXBJZD5jb20uc3VuLm1haWw8L2dyb3VwSWQ+CisJPGFydGlmYWN0SWQ+YWxsPC9hcnRpZmFjdElkPgorCTx2ZXJzaW9uPjEuNi4zPC92ZXJzaW9uPgorICAgIDwvcGFyZW50PgorICAgIDxtb2RlbFZlcnNpb24+NC4wLjA8L21vZGVsVmVyc2lvbj4KKyAgICA8Z3JvdXBJZD5jb20uc3VuLm1haWw8L2dyb3VwSWQ+CisgICAgPGFydGlmYWN0SWQ+amFrYXJ0YS5tYWlsPC9hcnRpZmFjdElkPgorICAgIDxwYWNrYWdpbmc+amFyPC9wYWNrYWdpbmc+CisgICAgPG5hbWU+SmF2YU1haWwgQVBJPC9uYW1lPgorCisgICAgPHByb3BlcnRpZXM+CisJPG1haWwuZXh0ZW5zaW9uTmFtZT4KKwkgICAgamFrYXJ0YS5tYWlsCisJPC9tYWlsLmV4dGVuc2lvbk5hbWU+CisJPG1haWwubW9kdWxlTmFtZT4KKwkgICAgamFrYXJ0YS5tYWlsCisJPC9tYWlsLm1vZHVsZU5hbWU+CisJPG1haWwuc3BlY2lmaWNhdGlvblRpdGxlPgorCSAgICBKYXZhTWFpbChUTSkgQVBJIERlc2lnbiBTcGVjaWZpY2F0aW9uCisJPC9tYWlsLnNwZWNpZmljYXRpb25UaXRsZT4KKwk8bWFpbC5pbXBsZW1lbnRhdGlvblRpdGxlPgorCSAgICBqYXZheC5tYWlsCisJPC9tYWlsLmltcGxlbWVudGF0aW9uVGl0bGU+CisJPG1haWwucGFja2FnZXMuZXhwb3J0PgorCSAgICBqYXZheC5tYWlsLio7IHZlcnNpb249JHttYWlsLnNwZWMudmVyc2lvbn0sCisJICAgIGNvbS5zdW4ubWFpbC5pbWFwOyB2ZXJzaW9uPSR7bWFpbC5vc2dpdmVyc2lvbn0sCisJICAgIGNvbS5zdW4ubWFpbC5pbWFwLnByb3RvY29sOyB2ZXJzaW9uPSR7bWFpbC5vc2dpdmVyc2lvbn0sCisJICAgIGNvbS5zdW4ubWFpbC5pYXA7IHZlcnNpb249JHttYWlsLm9zZ2l2ZXJzaW9ufSwKKwkgICAgY29tLnN1bi5tYWlsLnBvcDM7IHZlcnNpb249JHttYWlsLm9zZ2l2ZXJzaW9ufSwKKwkgICAgY29tLnN1bi5tYWlsLnNtdHA7IHZlcnNpb249JHttYWlsLm9zZ2l2ZXJzaW9ufSwKKwkgICAgY29tLnN1bi5tYWlsLnV0aWw7IHZlcnNpb249JHttYWlsLm9zZ2l2ZXJzaW9ufSwKKwkgICAgY29tLnN1bi5tYWlsLnV0aWwubG9nZ2luZzsgdmVyc2lvbj0ke21haWwub3NnaXZlcnNpb259LAorCSAgICBjb20uc3VuLm1haWwuaGFuZGxlcnM7IHZlcnNpb249JHttYWlsLm9zZ2l2ZXJzaW9ufQorCTwvbWFpbC5wYWNrYWdlcy5leHBvcnQ+CisJPG1haWwucHJvYmVGaWxlPgorCSAgICBNRVRBLUlORi9nZnByb2JlLXByb3ZpZGVyLnhtbAorCTwvbWFpbC5wcm9iZUZpbGU+CisJPGZpbmRidWdzLnNraXA+CisJICAgIGZhbHNlCisJPC9maW5kYnVncy5za2lwPgorCTxmaW5kYnVncy5leGNsdWRlPgorCSAgICAke3Byb2plY3QuYmFzZWRpcn0vZXhjbHVkZS54bWwKKwk8L2ZpbmRidWdzLmV4Y2x1ZGU+CisgICAgPC9wcm9wZXJ0aWVzPgorCisgICAgPHByb2ZpbGVzPgorCTwhLS0KKwkgICAgQSBzcGVjaWFsIHByb2ZpbGUgZm9yIGNvbXBpbGluZyB3aXRoIHRoZSByZWFsIEpESyAxLjcgY29tcGlsZXIuCisJICAgIEV4Y2x1ZGUgTWFpbFNlc3Npb25EZWZpbml0aW9uIGFuZCBNYWlsU2Vzc2lvbkRlZmluaXRpb25zIHNpbmNlCisJICAgIHRoZSBmb3JtZXIgcmVxdWlyZXMgSkRLIDEuOCBhbmQgdGhlIGxhdHRlciBkZXBlbmRzIG9uIHRoZSBmb3JtZXIuCisJLS0+CisJPHByb2ZpbGU+CisJICAgIDxpZD4xLjc8L2lkPgorCSAgICA8YnVpbGQ+CisJCTxwbHVnaW5zPgorCQkgICAgPHBsdWdpbj4KKwkJCTxhcnRpZmFjdElkPm1hdmVuLWNvbXBpbGVyLXBsdWdpbjwvYXJ0aWZhY3RJZD4KKwkJCTxleGVjdXRpb25zPgorCQkJICAgIDxleGVjdXRpb24+CisJCQkJPGlkPmRlZmF1bHQtY29tcGlsZTwvaWQ+CisJCQkJPGNvbmZpZ3VyYXRpb24+CisJCQkJICAgIDxleGNsdWRlcz4KKwkJCQkJPGV4Y2x1ZGU+CisJCQkJCSAgamF2YXgvbWFpbC9NYWlsU2Vzc2lvbkRlZmluaXRpb24uamF2YQorCQkJCQk8L2V4Y2x1ZGU+CisJCQkJCTxleGNsdWRlPgorCQkJCQkgIGphdmF4L21haWwvTWFpbFNlc3Npb25EZWZpbml0aW9ucy5qYXZhCisJCQkJCTwvZXhjbHVkZT4KKwkJCQkJPGV4Y2x1ZGU+CisJCQkJCSAgbW9kdWxlLWluZm8uamF2YQorCQkJCQk8L2V4Y2x1ZGU+CisJCQkJICAgIDwvZXhjbHVkZXM+CisJCQkJPC9jb25maWd1cmF0aW9uPgorCQkJICAgIDwvZXhlY3V0aW9uPgorCQkJPC9leGVjdXRpb25zPgorCQkgICAgPC9wbHVnaW4+CisJCTwvcGx1Z2lucz4KKwkgICAgPC9idWlsZD4KKwk8L3Byb2ZpbGU+CisKKwk8IS0tCisJICAgIEEgc3BlY2lhbCBwcm9maWxlIHVzZWQgd2hlbiBjb21waWxpbmcgd2l0aCB0aGUgcmVhbCBKREsgOSBjb21waWxlci4KKwkgICAgT3ZlcnJpZGUgdGhlIHJlbGVhc2Ugc2V0dGluZyBmcm9tIHRoZSBwYXJlbnQncyAiOSIgcHJvZmlsZSBzbworCSAgICB0aGF0IHdlIHByb2R1Y2UgSkRLIDEuNyBjb21wYXRpYmxlIGNsYXNzIGZpbGVzLgorCS0tPgorCTxwcm9maWxlPgorCSAgICA8aWQ+OTwvaWQ+CisJICAgIDxhY3RpdmF0aW9uPgorCQk8amRrPjk8L2pkaz4KKwkgICAgPC9hY3RpdmF0aW9uPgorCSAgICA8YnVpbGQ+CisJCTxwbHVnaW5zPgorCQkgICAgPHBsdWdpbj4KKwkJCTxhcnRpZmFjdElkPm1hdmVuLWNvbXBpbGVyLXBsdWdpbjwvYXJ0aWZhY3RJZD4KKwkJCTxleGVjdXRpb25zPgorCQkJICAgIDxleGVjdXRpb24+CisJCQkJPGlkPmRlZmF1bHQtY29tcGlsZTwvaWQ+CisJCQkJPGNvbmZpZ3VyYXRpb24+CisJCQkJICAgIDxyZWxlYXNlIGNvbWJpbmUuc2VsZj0ib3ZlcnJpZGUiPjwvcmVsZWFzZT4KKwkJCQk8L2NvbmZpZ3VyYXRpb24+CisJCQkgICAgPC9leGVjdXRpb24+CisJCQk8L2V4ZWN1dGlvbnM+CisJCSAgICA8L3BsdWdpbj4KKwkJPC9wbHVnaW5zPgorCSAgICA8L2J1aWxkPgorCTwvcHJvZmlsZT4KKyAgICA8L3Byb2ZpbGVzPgorCisgICAgPGJ1aWxkPgorCTxyZXNvdXJjZXM+CisJICAgIDxyZXNvdXJjZT4KKwkJPGRpcmVjdG9yeT5zcmMvbWFpbi9yZXNvdXJjZXM8L2RpcmVjdG9yeT4KKwkJPGZpbHRlcmluZz50cnVlPC9maWx0ZXJpbmc+CisJICAgIDwvcmVzb3VyY2U+CisJPC9yZXNvdXJjZXM+CisJPHBsdWdpbnM+CisJICAgIDwhLS0KKwkJQ29uZmlndXJlIGNvbXBpbGVyIHBsdWdpbiB0byBwcmludCBsaW50IHdhcm5pbmdzLgorCQlOZWVkIHRvIGV4Y2x1ZGUgb3B0aW9ucyB3YXJuaW5nIGJlY2F1c2UgYm9vdHN0cmFwCisJCWNsYXNzcGF0aCBpc24ndCBzZXQgKG9uIHB1cnBvc2UpLgorCQlOZWVkIHRvIGV4Y2x1ZGUgcGF0aCB3YXJuaW5ncyBiZWNhdXNlIE1hdmVuIGluY2x1ZGVzCisJCXNvdXJjZSBkaXJlY3RvcmllcyB0aGF0IGRvbid0IGV4aXN0IChlLmcuLCBnZW5lcmF0ZWQtc291cmNlcykuCisJICAgIC0tPgorCSAgICA8cGx1Z2luPgorCQk8YXJ0aWZhY3RJZD5tYXZlbi1jb21waWxlci1wbHVnaW48L2FydGlmYWN0SWQ+CisJCTxjb25maWd1cmF0aW9uPgorCQkgICAgPHNvdXJjZT4xLjc8L3NvdXJjZT4KKwkJICAgIDx0YXJnZXQ+MS43PC90YXJnZXQ+CisJCSAgICA8Y29tcGlsZXJBcmdzPgorCQkJPGFyZz4tWGxpbnQ8L2FyZz4KKwkJCTxhcmc+LVhsaW50Oi1vcHRpb25zPC9hcmc+CisJCQk8YXJnPi1YbGludDotcGF0aDwvYXJnPgorCQkJPGFyZz4tV2Vycm9yPC9hcmc+CisJCSAgICA8L2NvbXBpbGVyQXJncz4KKwkJICAgIDxzaG93RGVwcmVjYXRpb24+dHJ1ZTwvc2hvd0RlcHJlY2F0aW9uPgorCQkgICAgPHNob3dXYXJuaW5ncz50cnVlPC9zaG93V2FybmluZ3M+CisJCSAgICA8ZXhjbHVkZXM+CisJCQk8ZXhjbHVkZT4KKwkJCSAgbW9kdWxlLWluZm8uamF2YQorCQkJPC9leGNsdWRlPgorCQkgICAgPC9leGNsdWRlcz4KKwkJPC9jb25maWd1cmF0aW9uPgorCSAgICA8L3BsdWdpbj4KKworCSAgICA8IS0tCisJCUNvbmZpZ3VyZSB0ZXN0IHBsdWdpbiB0byBmaW5kICpUZXN0U3VpdGUgY2xhc3Nlcy4KKwkgICAgLS0+CisJICAgIDxwbHVnaW4+CisJCTxncm91cElkPm9yZy5hcGFjaGUubWF2ZW4ucGx1Z2luczwvZ3JvdXBJZD4KKwkJPGFydGlmYWN0SWQ+bWF2ZW4tc3VyZWZpcmUtcGx1Z2luPC9hcnRpZmFjdElkPgorCQk8Y29uZmlndXJhdGlvbj4KKwkJICAgIDxpbmNsdWRlcz4KKwkJCTxpbmNsdWRlPioqLypUZXN0LmphdmE8L2luY2x1ZGU+CisJCQk8aW5jbHVkZT4qKi8qVGVzdFN1aXRlLmphdmE8L2luY2x1ZGU+CisJCSAgICA8L2luY2x1ZGVzPgorCQk8L2NvbmZpZ3VyYXRpb24+CisJICAgIDwvcGx1Z2luPgorCisJICAgIDwhLS0KKwkJQWRkIHRoZSBBdXRvbWF0aWMtTW9kdWxlLU5hbWUgbWFuaWZlc3QgaGVhZGVyIGZvciBKREsgOS4KKwkgICAgLS0+CisJICAgIDxwbHVnaW4+CisJCTxhcnRpZmFjdElkPm1hdmVuLWphci1wbHVnaW48L2FydGlmYWN0SWQ+CisJCTxjb25maWd1cmF0aW9uPgorCQkgICAgPGFyY2hpdmU+CisJCQk8bWFuaWZlc3RFbnRyaWVzPgorCQkJICAgIDxBdXRvbWF0aWMtTW9kdWxlLU5hbWU+CisJCQkJJHttYWlsLm1vZHVsZU5hbWV9CisJCQkgICAgPC9BdXRvbWF0aWMtTW9kdWxlLU5hbWU+CisJCQk8L21hbmlmZXN0RW50cmllcz4KKwkJICAgIDwvYXJjaGl2ZT4KKwkJPC9jb25maWd1cmF0aW9uPgorCSAgICA8L3BsdWdpbj4KKwk8L3BsdWdpbnM+CisgICAgPC9idWlsZD4KKworICAgIDxkZXBlbmRlbmNpZXM+CisJPGRlcGVuZGVuY3k+CisJICAgIDxncm91cElkPmNvbS5zdW4uYWN0aXZhdGlvbjwvZ3JvdXBJZD4KKwkgICAgPGFydGlmYWN0SWQ+amFrYXJ0YS5hY3RpdmF0aW9uPC9hcnRpZmFjdElkPgorCTwvZGVwZW5kZW5jeT4KKwk8ZGVwZW5kZW5jeT4KKwkgICAgPGdyb3VwSWQ+anVuaXQ8L2dyb3VwSWQ+CisJICAgIDxhcnRpZmFjdElkPmp1bml0PC9hcnRpZmFjdElkPgorCSAgICA8dmVyc2lvbj40LjEyPC92ZXJzaW9uPgorCSAgICA8c2NvcGU+dGVzdDwvc2NvcGU+CisJICAgIDxvcHRpb25hbD50cnVlPC9vcHRpb25hbD4KKwk8L2RlcGVuZGVuY3k+CisgICAgPC9kZXBlbmRlbmNpZXM+Cis8L3Byb2plY3Q+CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2F1dGgvTUQ0LmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2F1dGgvTUQ0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGI5OGI5MAotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvYXV0aC9NRDQuamF2YQpAQCAtMCwwICsxLDI3NiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworLyoKKyAqIENvcGllZCBmcm9tIE9wZW5KREsgd2l0aCBwZXJtaXNzaW9uLgorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmF1dGg7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lio7CisKKy8vaW1wb3J0IHN0YXRpYyBzdW4uc2VjdXJpdHkucHJvdmlkZXIuQnl0ZUFycmF5QWNjZXNzLio7CisKKy8qKgorICogVGhlIE1ENCBjbGFzcyBpcyB1c2VkIHRvIGNvbXB1dGUgYW4gTUQ0IG1lc3NhZ2UgZGlnZXN0IG92ZXIgYSBnaXZlbgorICogYnVmZmVyIG9mIGJ5dGVzLiBJdCBpcyBhbiBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgUlNBIERhdGEgU2VjdXJpdHkgSW5jCisgKiBNRDQgYWxnb3JpdGhpbSBhcyBkZXNjcmliZWQgaW4gaW50ZXJuZXQgUkZDIDEzMjAuCisgKgorICogQGF1dGhvciAgICAgIEFuZHJlYXMgU3RlcmJlbnoKKyAqIEBhdXRob3IgICAgICBCaWxsIFNoYW5ub24gKGFkYXB0ZWQgZm9yIEphdmFNYWlsKQorICovCitwdWJsaWMgZmluYWwgY2xhc3MgTUQ0IHsKKworICAgIC8vIHN0YXRlIG9mIHRoaXMgb2JqZWN0CisgICAgcHJpdmF0ZSBmaW5hbCBpbnRbXSBzdGF0ZTsKKyAgICAvLyB0ZW1wb3JhcnkgYnVmZmVyLCB1c2VkIGJ5IGltcGxDb21wcmVzcygpCisgICAgcHJpdmF0ZSBmaW5hbCBpbnRbXSB4OworCisgICAgLy8gc2l6ZSBvZiB0aGUgaW5wdXQgdG8gdGhlIGNvbXByZXNzaW9uIGZ1bmN0aW9uIGluIGJ5dGVzCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IGJsb2NrU2l6ZSA9IDY0OworCisgICAgLy8gYnVmZmVyIHRvIHN0b3JlIHBhcnRpYWwgYmxvY2tzLCBibG9ja1NpemUgYnl0ZXMgbGFyZ2UKKyAgICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVtibG9ja1NpemVdOworICAgIC8vIG9mZnNldCBpbnRvIGJ1ZmZlcgorICAgIHByaXZhdGUgaW50IGJ1Zk9mczsKKworICAgIC8vIG51bWJlciBvZiBieXRlcyBwcm9jZXNzZWQgc28gZmFyLgorICAgIC8vIGFsc28gdXNlZCBhcyBhIGZsYWcgdG8gaW5kaWNhdGUgcmVzZXQgc3RhdHVzCisgICAgLy8gLTE6IG5lZWQgdG8gY2FsbCBlbmdpbmVSZXNldCgpIGJlZm9yZSBuZXh0IGNhbGwgdG8gdXBkYXRlKCkKKyAgICAvLyAgMDogaXMgYWxyZWFkeSByZXNldAorICAgIHByaXZhdGUgbG9uZyBieXRlc1Byb2Nlc3NlZDsKKworICAgIC8vIHJvdGF0aW9uIGNvbnN0YW50cworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTMTEgPSAzOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTMTIgPSA3OworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTMTMgPSAxMTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUzE0ID0gMTk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFMyMSA9IDM7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFMyMiA9IDU7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFMyMyA9IDk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFMyNCA9IDEzOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTMzEgPSAzOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTMzIgPSA5OworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTMzMgPSAxMTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUzM0ID0gMTU7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gcGFkZGluZzsKKworICAgIHN0YXRpYyB7CisgICAgICAgIHBhZGRpbmcgPSBuZXcgYnl0ZVsxMzZdOworICAgICAgICBwYWRkaW5nWzBdID0gKGJ5dGUpMHg4MDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTdGFuZGFyZCBjb25zdHJ1Y3RvciwgY3JlYXRlcyBhIG5ldyBNRDQgaW5zdGFuY2UuCisgICAgICovCisgICAgcHVibGljIE1ENCgpIHsKKyAgICAgICAgc3RhdGUgPSBuZXcgaW50WzRdOworICAgICAgICB4ID0gbmV3IGludFsxNl07CisgICAgICAgIGltcGxSZXNldCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXB1dGUgYW5kIHJldHVybiB0aGUgbWVzc2FnZSBkaWdlc3Qgb2YgdGhlIGlucHV0IGJ5dGUgYXJyYXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0JaW4JdGhlIGlucHV0IGJ5dGUgYXJyYXkKKyAgICAgKiBAcmV0dXJuCXRoZSBtZXNzYWdlIGRpZ2VzdCBieXRlIGFycmF5CisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBkaWdlc3QoYnl0ZVtdIGluKSB7CisJaW1wbFJlc2V0KCk7CisJZW5naW5lVXBkYXRlKGluLCAwLCBpbi5sZW5ndGgpOworCWJ5dGVbXSBvdXQgPSBuZXcgYnl0ZVsxNl07CisJaW1wbERpZ2VzdChvdXQsIDApOworCXJldHVybiBvdXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVzZXQgdGhlIHN0YXRlIG9mIHRoaXMgb2JqZWN0LgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBpbXBsUmVzZXQoKSB7CisgICAgICAgIC8vIExvYWQgbWFnaWMgaW5pdGlhbGl6YXRpb24gY29uc3RhbnRzLgorICAgICAgICBzdGF0ZVswXSA9IDB4Njc0NTIzMDE7CisgICAgICAgIHN0YXRlWzFdID0gMHhlZmNkYWI4OTsKKyAgICAgICAgc3RhdGVbMl0gPSAweDk4YmFkY2ZlOworICAgICAgICBzdGF0ZVszXSA9IDB4MTAzMjU0NzY7CisgICAgICAgIGJ1Zk9mcyA9IDA7CisgICAgICAgIGJ5dGVzUHJvY2Vzc2VkID0gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtIHRoZSBmaW5hbCBjb21wdXRhdGlvbnMsIGFueSBidWZmZXJlZCBieXRlcyBhcmUgYWRkZWQKKyAgICAgKiB0byB0aGUgZGlnZXN0LCB0aGUgY291bnQgaXMgYWRkZWQgdG8gdGhlIGRpZ2VzdCwgYW5kIHRoZSByZXN1bHRpbmcKKyAgICAgKiBkaWdlc3QgaXMgc3RvcmVkLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBpbXBsRGlnZXN0KGJ5dGVbXSBvdXQsIGludCBvZnMpIHsKKyAgICAgICAgbG9uZyBiaXRzUHJvY2Vzc2VkID0gYnl0ZXNQcm9jZXNzZWQgPDwgMzsKKworICAgICAgICBpbnQgaW5kZXggPSAoaW50KWJ5dGVzUHJvY2Vzc2VkICYgMHgzZjsKKyAgICAgICAgaW50IHBhZExlbiA9IChpbmRleCA8IDU2KSA/ICg1NiAtIGluZGV4KSA6ICgxMjAgLSBpbmRleCk7CisgICAgICAgIGVuZ2luZVVwZGF0ZShwYWRkaW5nLCAwLCBwYWRMZW4pOworCisgICAgICAgIC8vaTJiTGl0dGxlNCgoaW50KWJpdHNQcm9jZXNzZWQsIGJ1ZmZlciwgNTYpOworICAgICAgICAvL2kyYkxpdHRsZTQoKGludCkoYml0c1Byb2Nlc3NlZCA+Pj4gMzIpLCBidWZmZXIsIDYwKTsKKwlidWZmZXJbNTZdID0gKGJ5dGUpYml0c1Byb2Nlc3NlZDsKKwlidWZmZXJbNTddID0gKGJ5dGUpKGJpdHNQcm9jZXNzZWQ+PjgpOworCWJ1ZmZlcls1OF0gPSAoYnl0ZSkoYml0c1Byb2Nlc3NlZD4+MTYpOworCWJ1ZmZlcls1OV0gPSAoYnl0ZSkoYml0c1Byb2Nlc3NlZD4+MjQpOworCWJ1ZmZlcls2MF0gPSAoYnl0ZSkoYml0c1Byb2Nlc3NlZD4+MzIpOworCWJ1ZmZlcls2MV0gPSAoYnl0ZSkoYml0c1Byb2Nlc3NlZD4+NDApOworCWJ1ZmZlcls2Ml0gPSAoYnl0ZSkoYml0c1Byb2Nlc3NlZD4+NDgpOworCWJ1ZmZlcls2M10gPSAoYnl0ZSkoYml0c1Byb2Nlc3NlZD4+NTYpOworICAgICAgICBpbXBsQ29tcHJlc3MoYnVmZmVyLCAwKTsKKworICAgICAgICAvL2kyYkxpdHRsZShzdGF0ZSwgMCwgb3V0LCBvZnMsIDE2KTsKKwlmb3IgKGludCBpID0gMDsgaSA8IHN0YXRlLmxlbmd0aDsgaSsrKSB7CisJICAgIGludCB4ID0gc3RhdGVbaV07CisJICAgIG91dFtvZnMrK10gPSAoYnl0ZSl4OworCSAgICBvdXRbb2ZzKytdID0gKGJ5dGUpKHg+PjgpOworCSAgICBvdXRbb2ZzKytdID0gKGJ5dGUpKHg+PjE2KTsKKwkgICAgb3V0W29mcysrXSA9IChieXRlKSh4Pj4yNCk7CisJfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBlbmdpbmVVcGRhdGUoYnl0ZVtdIGIsIGludCBvZnMsIGludCBsZW4pIHsKKyAgICAgICAgaWYgKGxlbiA9PSAwKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgaWYgKChvZnMgPCAwKSB8fCAobGVuIDwgMCkgfHwgKG9mcyA+IGIubGVuZ3RoIC0gbGVuKSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGlmIChieXRlc1Byb2Nlc3NlZCA8IDApIHsKKyAgICAgICAgICAgIGltcGxSZXNldCgpOworICAgICAgICB9CisgICAgICAgIGJ5dGVzUHJvY2Vzc2VkICs9IGxlbjsKKyAgICAgICAgLy8gaWYgYnVmZmVyIGlzIG5vdCBlbXB0eSwgd2UgbmVlZCB0byBmaWxsIGl0IGJlZm9yZSBwcm9jZWVkaW5nCisgICAgICAgIGlmIChidWZPZnMgIT0gMCkgeworICAgICAgICAgICAgaW50IG4gPSBNYXRoLm1pbihsZW4sIGJsb2NrU2l6ZSAtIGJ1Zk9mcyk7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGIsIG9mcywgYnVmZmVyLCBidWZPZnMsIG4pOworICAgICAgICAgICAgYnVmT2ZzICs9IG47CisgICAgICAgICAgICBvZnMgKz0gbjsKKyAgICAgICAgICAgIGxlbiAtPSBuOworICAgICAgICAgICAgaWYgKGJ1Zk9mcyA+PSBibG9ja1NpemUpIHsKKyAgICAgICAgICAgICAgICAvLyBjb21wcmVzcyBjb21wbGV0ZWQgYmxvY2sgbm93CisgICAgICAgICAgICAgICAgaW1wbENvbXByZXNzKGJ1ZmZlciwgMCk7CisgICAgICAgICAgICAgICAgYnVmT2ZzID0gMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAvLyBjb21wcmVzcyBjb21wbGV0ZSBibG9ja3MKKyAgICAgICAgd2hpbGUgKGxlbiA+PSBibG9ja1NpemUpIHsKKyAgICAgICAgICAgIGltcGxDb21wcmVzcyhiLCBvZnMpOworICAgICAgICAgICAgbGVuIC09IGJsb2NrU2l6ZTsKKyAgICAgICAgICAgIG9mcyArPSBibG9ja1NpemU7CisgICAgICAgIH0KKyAgICAgICAgLy8gY29weSByZW1haW5kZXIgdG8gYnVmZmVyCisgICAgICAgIGlmIChsZW4gPiAwKSB7CisgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGIsIG9mcywgYnVmZmVyLCAwLCBsZW4pOworICAgICAgICAgICAgYnVmT2ZzID0gbGVuOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IEZGKGludCBhLCBpbnQgYiwgaW50IGMsIGludCBkLCBpbnQgeCwgaW50IHMpIHsKKyAgICAgICAgYSArPSAoKGIgJiBjKSB8ICgofmIpICYgZCkpICsgeDsKKyAgICAgICAgcmV0dXJuICgoYSA8PCBzKSB8IChhID4+PiAoMzIgLSBzKSkpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGludCBHRyhpbnQgYSwgaW50IGIsIGludCBjLCBpbnQgZCwgaW50IHgsIGludCBzKSB7CisgICAgICAgIGEgKz0gKChiICYgYykgfCAoYiAmIGQpIHwgKGMgJiBkKSkgKyB4ICsgMHg1YTgyNzk5OTsKKyAgICAgICAgcmV0dXJuICgoYSA8PCBzKSB8IChhID4+PiAoMzIgLSBzKSkpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGludCBISChpbnQgYSwgaW50IGIsIGludCBjLCBpbnQgZCwgaW50IHgsIGludCBzKSB7CisgICAgICAgIGEgKz0gKChiIF4gYykgXiBkKSArIHggKyAweDZlZDllYmExOworICAgICAgICByZXR1cm4gKChhIDw8IHMpIHwgKGEgPj4+ICgzMiAtIHMpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBpcyB3aGVyZSB0aGUgZnVuY3Rpb25zIGNvbWUgdG9nZXRoZXIgYXMgdGhlIGdlbmVyaWMgTUQ0CisgICAgICogdHJhbnNmb3JtYXRpb24gb3BlcmF0aW9uLiBJdCBjb25zdW1lcyA2NAorICAgICAqIGJ5dGVzIGZyb20gdGhlIGJ1ZmZlciwgYmVnaW5uaW5nIGF0IHRoZSBzcGVjaWZpZWQgb2Zmc2V0LgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBpbXBsQ29tcHJlc3MoYnl0ZVtdIGJ1ZiwgaW50IG9mcykgeworICAgICAgICAvL2IyaUxpdHRsZTY0KGJ1Ziwgb2ZzLCB4KTsKKwlmb3IgKGludCB4ZnMgPSAwOyB4ZnMgPCB4Lmxlbmd0aDsgeGZzKyspIHsKKwkgICAgeFt4ZnNdID0gKGJ1ZltvZnNdICYgMHhmZikgfCAoKGJ1ZltvZnMrMV0gJiAweGZmKSA8PCA4KSB8CisJCSgoYnVmW29mcysyXSAmIDB4ZmYpIDw8IDE2KSB8ICgoYnVmW29mcyszXSAmIDB4ZmYpIDw8IDI0KTsKKwkgICAgb2ZzICs9IDQ7CisJfQorCisgICAgICAgIGludCBhID0gc3RhdGVbMF07CisgICAgICAgIGludCBiID0gc3RhdGVbMV07CisgICAgICAgIGludCBjID0gc3RhdGVbMl07CisgICAgICAgIGludCBkID0gc3RhdGVbM107CisKKyAgICAgICAgLyogUm91bmQgMSAqLworICAgICAgICBhID0gRkYgKGEsIGIsIGMsIGQsIHhbIDBdLCBTMTEpOyAvKiAxICovCisgICAgICAgIGQgPSBGRiAoZCwgYSwgYiwgYywgeFsgMV0sIFMxMik7IC8qIDIgKi8KKyAgICAgICAgYyA9IEZGIChjLCBkLCBhLCBiLCB4WyAyXSwgUzEzKTsgLyogMyAqLworICAgICAgICBiID0gRkYgKGIsIGMsIGQsIGEsIHhbIDNdLCBTMTQpOyAvKiA0ICovCisgICAgICAgIGEgPSBGRiAoYSwgYiwgYywgZCwgeFsgNF0sIFMxMSk7IC8qIDUgKi8KKyAgICAgICAgZCA9IEZGIChkLCBhLCBiLCBjLCB4WyA1XSwgUzEyKTsgLyogNiAqLworICAgICAgICBjID0gRkYgKGMsIGQsIGEsIGIsIHhbIDZdLCBTMTMpOyAvKiA3ICovCisgICAgICAgIGIgPSBGRiAoYiwgYywgZCwgYSwgeFsgN10sIFMxNCk7IC8qIDggKi8KKyAgICAgICAgYSA9IEZGIChhLCBiLCBjLCBkLCB4WyA4XSwgUzExKTsgLyogOSAqLworICAgICAgICBkID0gRkYgKGQsIGEsIGIsIGMsIHhbIDldLCBTMTIpOyAvKiAxMCAqLworICAgICAgICBjID0gRkYgKGMsIGQsIGEsIGIsIHhbMTBdLCBTMTMpOyAvKiAxMSAqLworICAgICAgICBiID0gRkYgKGIsIGMsIGQsIGEsIHhbMTFdLCBTMTQpOyAvKiAxMiAqLworICAgICAgICBhID0gRkYgKGEsIGIsIGMsIGQsIHhbMTJdLCBTMTEpOyAvKiAxMyAqLworICAgICAgICBkID0gRkYgKGQsIGEsIGIsIGMsIHhbMTNdLCBTMTIpOyAvKiAxNCAqLworICAgICAgICBjID0gRkYgKGMsIGQsIGEsIGIsIHhbMTRdLCBTMTMpOyAvKiAxNSAqLworICAgICAgICBiID0gRkYgKGIsIGMsIGQsIGEsIHhbMTVdLCBTMTQpOyAvKiAxNiAqLworCisgICAgICAgIC8qIFJvdW5kIDIgKi8KKyAgICAgICAgYSA9IEdHIChhLCBiLCBjLCBkLCB4WyAwXSwgUzIxKTsgLyogMTcgKi8KKyAgICAgICAgZCA9IEdHIChkLCBhLCBiLCBjLCB4WyA0XSwgUzIyKTsgLyogMTggKi8KKyAgICAgICAgYyA9IEdHIChjLCBkLCBhLCBiLCB4WyA4XSwgUzIzKTsgLyogMTkgKi8KKyAgICAgICAgYiA9IEdHIChiLCBjLCBkLCBhLCB4WzEyXSwgUzI0KTsgLyogMjAgKi8KKyAgICAgICAgYSA9IEdHIChhLCBiLCBjLCBkLCB4WyAxXSwgUzIxKTsgLyogMjEgKi8KKyAgICAgICAgZCA9IEdHIChkLCBhLCBiLCBjLCB4WyA1XSwgUzIyKTsgLyogMjIgKi8KKyAgICAgICAgYyA9IEdHIChjLCBkLCBhLCBiLCB4WyA5XSwgUzIzKTsgLyogMjMgKi8KKyAgICAgICAgYiA9IEdHIChiLCBjLCBkLCBhLCB4WzEzXSwgUzI0KTsgLyogMjQgKi8KKyAgICAgICAgYSA9IEdHIChhLCBiLCBjLCBkLCB4WyAyXSwgUzIxKTsgLyogMjUgKi8KKyAgICAgICAgZCA9IEdHIChkLCBhLCBiLCBjLCB4WyA2XSwgUzIyKTsgLyogMjYgKi8KKyAgICAgICAgYyA9IEdHIChjLCBkLCBhLCBiLCB4WzEwXSwgUzIzKTsgLyogMjcgKi8KKyAgICAgICAgYiA9IEdHIChiLCBjLCBkLCBhLCB4WzE0XSwgUzI0KTsgLyogMjggKi8KKyAgICAgICAgYSA9IEdHIChhLCBiLCBjLCBkLCB4WyAzXSwgUzIxKTsgLyogMjkgKi8KKyAgICAgICAgZCA9IEdHIChkLCBhLCBiLCBjLCB4WyA3XSwgUzIyKTsgLyogMzAgKi8KKyAgICAgICAgYyA9IEdHIChjLCBkLCBhLCBiLCB4WzExXSwgUzIzKTsgLyogMzEgKi8KKyAgICAgICAgYiA9IEdHIChiLCBjLCBkLCBhLCB4WzE1XSwgUzI0KTsgLyogMzIgKi8KKworICAgICAgICAvKiBSb3VuZCAzICovCisgICAgICAgIGEgPSBISCAoYSwgYiwgYywgZCwgeFsgMF0sIFMzMSk7IC8qIDMzICovCisgICAgICAgIGQgPSBISCAoZCwgYSwgYiwgYywgeFsgOF0sIFMzMik7IC8qIDM0ICovCisgICAgICAgIGMgPSBISCAoYywgZCwgYSwgYiwgeFsgNF0sIFMzMyk7IC8qIDM1ICovCisgICAgICAgIGIgPSBISCAoYiwgYywgZCwgYSwgeFsxMl0sIFMzNCk7IC8qIDM2ICovCisgICAgICAgIGEgPSBISCAoYSwgYiwgYywgZCwgeFsgMl0sIFMzMSk7IC8qIDM3ICovCisgICAgICAgIGQgPSBISCAoZCwgYSwgYiwgYywgeFsxMF0sIFMzMik7IC8qIDM4ICovCisgICAgICAgIGMgPSBISCAoYywgZCwgYSwgYiwgeFsgNl0sIFMzMyk7IC8qIDM5ICovCisgICAgICAgIGIgPSBISCAoYiwgYywgZCwgYSwgeFsxNF0sIFMzNCk7IC8qIDQwICovCisgICAgICAgIGEgPSBISCAoYSwgYiwgYywgZCwgeFsgMV0sIFMzMSk7IC8qIDQxICovCisgICAgICAgIGQgPSBISCAoZCwgYSwgYiwgYywgeFsgOV0sIFMzMik7IC8qIDQyICovCisgICAgICAgIGMgPSBISCAoYywgZCwgYSwgYiwgeFsgNV0sIFMzMyk7IC8qIDQzICovCisgICAgICAgIGIgPSBISCAoYiwgYywgZCwgYSwgeFsxM10sIFMzNCk7IC8qIDQ0ICovCisgICAgICAgIGEgPSBISCAoYSwgYiwgYywgZCwgeFsgM10sIFMzMSk7IC8qIDQ1ICovCisgICAgICAgIGQgPSBISCAoZCwgYSwgYiwgYywgeFsxMV0sIFMzMik7IC8qIDQ2ICovCisgICAgICAgIGMgPSBISCAoYywgZCwgYSwgYiwgeFsgN10sIFMzMyk7IC8qIDQ3ICovCisgICAgICAgIGIgPSBISCAoYiwgYywgZCwgYSwgeFsxNV0sIFMzNCk7IC8qIDQ4ICovCisKKyAgICAgICAgc3RhdGVbMF0gKz0gYTsKKyAgICAgICAgc3RhdGVbMV0gKz0gYjsKKyAgICAgICAgc3RhdGVbMl0gKz0gYzsKKyAgICAgICAgc3RhdGVbM10gKz0gZDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2F1dGgvTnRsbS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9hdXRoL050bG0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NmEwNWE0Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9hdXRoL050bG0uamF2YQpAQCAtMCwwICsxLDM0MyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworLyoKKyAqIENvcGllZCBmcm9tIE9wZW5KREsgd2l0aCBwZXJtaXNzaW9uLgorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmF1dGg7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLlByaW50U3RyZWFtOworaW1wb3J0IGphdmEuc2VjdXJpdHkuR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTGV2ZWw7CitpbXBvcnQgamF2YXguY3J5cHRvLkNpcGhlcjsKK2ltcG9ydCBqYXZheC5jcnlwdG8uTm9TdWNoUGFkZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5jcnlwdG8uU2VjcmV0S2V5OworaW1wb3J0IGphdmF4LmNyeXB0by5TZWNyZXRLZXlGYWN0b3J5OworaW1wb3J0IGphdmF4LmNyeXB0by5zcGVjLkRFU0tleVNwZWM7CisKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5CQVNFNjREZWNvZGVyU3RyZWFtOworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLkJBU0U2NEVuY29kZXJTdHJlYW07CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuTWFpbExvZ2dlcjsKKworCisvKioKKyAqIE5UTE1BdXRoZW50aWNhdGlvbjoKKyAqCisgKiBAYXV0aG9yIE1pY2hhZWwgTWNNYWhvbgorICogQGF1dGhvciBCaWxsIFNoYW5ub24gKGFkYXB0ZWQgZm9yIEphdmFNYWlsKQorICovCitwdWJsaWMgY2xhc3MgTnRsbSB7CisKKyAgICBwcml2YXRlIGJ5dGVbXSB0eXBlMTsKKyAgICBwcml2YXRlIGJ5dGVbXSB0eXBlMzsKKworICAgIHByaXZhdGUgU2VjcmV0S2V5RmFjdG9yeSBmYWM7CisgICAgcHJpdmF0ZSBDaXBoZXIgY2lwaGVyOworICAgIHByaXZhdGUgTUQ0IG1kNDsKKyAgICBwcml2YXRlIFN0cmluZyBob3N0bmFtZTsKKyAgICBwcml2YXRlIFN0cmluZyBudGRvbWFpbjsKKyAgICBwcml2YXRlIFN0cmluZyB1c2VybmFtZTsKKyAgICBwcml2YXRlIFN0cmluZyBwYXNzd29yZDsKKworICAgIHByaXZhdGUgTWFpbExvZ2dlciBsb2dnZXI7CisKKyAgICBwcml2YXRlIHZvaWQgaW5pdDAoKSB7CisgICAgICAgIHR5cGUxID0gbmV3IGJ5dGVbMjU2XTsKKyAgICAgICAgdHlwZTMgPSBuZXcgYnl0ZVsyNTZdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG5ldyBieXRlW10geydOJywnVCcsJ0wnLCdNJywnUycsJ1MnLCdQJywwLDF9LCAwLAorCQkJICAgIHR5cGUxLCAwLCA5KTsKKyAgICAgICAgdHlwZTFbMTJdID0gKGJ5dGUpIDM7CisgICAgICAgIHR5cGUxWzEzXSA9IChieXRlKSAweGIyOworICAgICAgICB0eXBlMVsyOF0gPSAoYnl0ZSkgMHgyMDsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShuZXcgYnl0ZVtdIHsnTicsJ1QnLCdMJywnTScsJ1MnLCdTJywnUCcsMCwzfSwgMCwKKwkJCSAgICB0eXBlMywgMCwgOSk7CisgICAgICAgIHR5cGUzWzEyXSA9IChieXRlKSAweDE4OworICAgICAgICB0eXBlM1sxNF0gPSAoYnl0ZSkgMHgxODsKKyAgICAgICAgdHlwZTNbMjBdID0gKGJ5dGUpIDB4MTg7CisgICAgICAgIHR5cGUzWzIyXSA9IChieXRlKSAweDE4OworICAgICAgICB0eXBlM1szMl0gPSAoYnl0ZSkgMHg0MDsKKyAgICAgICAgdHlwZTNbNjBdID0gKGJ5dGUpIDE7CisgICAgICAgIHR5cGUzWzYxXSA9IChieXRlKSAweDgyOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmYWMgPSBTZWNyZXRLZXlGYWN0b3J5LmdldEluc3RhbmNlKCJERVMiKTsKKyAgICAgICAgICAgIGNpcGhlciA9IENpcGhlci5nZXRJbnN0YW5jZSgiREVTL0VDQi9Ob1BhZGRpbmciKTsKKyAgICAgICAgICAgIG1kNCA9IG5ldyBNRDQoKTsKKyAgICAgICAgfSBjYXRjaCAoTm9TdWNoUGFkZGluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnQgZmFsc2U7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnQgZmFsc2U7CisgICAgICAgIH0KKyAgICB9OworCisgICAgLyoqCisgICAgICogQ3JlYXRlIGFuIE5UTE0gYXV0aGVudGljYXRvci4KKyAgICAgKiBVc2VybmFtZSBtYXkgYmUgc3BlY2lmaWVkIGFzIGRvbWFpblxcdXNlcm5hbWUgaW4gdGhlIEF1dGhlbnRpY2F0b3IuCisgICAgICogSWYgdGhpcyBub3RhdGlvbiBpcyBub3QgdXNlZCwgdGhlbiB0aGUgZG9tYWluIHdpbGwgYmUgdGFrZW4KKyAgICAgKiBmcm9tIHRoZSBudGRvbWFpbiBwYXJhbWV0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0JbnRkb21haW4JdGhlIE5UIGRvbWFpbgorICAgICAqIEBwYXJhbQlob3N0bmFtZQl0aGUgaG9zdCBuYW1lCisgICAgICogQHBhcmFtCXVzZXJuYW1lCXRoZSB1c2VyIG5hbWUKKyAgICAgKiBAcGFyYW0JcGFzc3dvcmQJdGhlIHBhc3N3b3JkCisgICAgICogQHBhcmFtCWxvZ2dlcgkJdGhlIE1haWxMb2dnZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgTnRsbShTdHJpbmcgbnRkb21haW4sIFN0cmluZyBob3N0bmFtZSwgU3RyaW5nIHVzZXJuYW1lLAorCQkJCVN0cmluZyBwYXNzd29yZCwgTWFpbExvZ2dlciBsb2dnZXIpIHsKKwlpbnQgaSA9IGhvc3RuYW1lLmluZGV4T2YoJy4nKTsKKwlpZiAoaSAhPSAtMSkgeworCSAgICBob3N0bmFtZSA9IGhvc3RuYW1lLnN1YnN0cmluZygwLCBpKTsKKwl9CisgICAgICAgIGkgPSB1c2VybmFtZS5pbmRleE9mKCdcXCcpOworICAgICAgICBpZiAoaSAhPSAtMSkgeworICAgICAgICAgICAgbnRkb21haW4gPSB1c2VybmFtZS5zdWJzdHJpbmcoMCwgaSkudG9VcHBlckNhc2UoTG9jYWxlLkVOR0xJU0gpOworICAgICAgICAgICAgdXNlcm5hbWUgPSB1c2VybmFtZS5zdWJzdHJpbmcoaSsxKTsKKyAgICAgICAgfSBlbHNlIGlmIChudGRvbWFpbiA9PSBudWxsKSB7CisJICAgIG50ZG9tYWluID0gIiI7CisJfQorCXRoaXMubnRkb21haW4gPSBudGRvbWFpbjsKKwl0aGlzLmhvc3RuYW1lID0gaG9zdG5hbWU7CisJdGhpcy51c2VybmFtZSA9IHVzZXJuYW1lOworCXRoaXMucGFzc3dvcmQgPSBwYXNzd29yZDsKKwl0aGlzLmxvZ2dlciA9IGxvZ2dlci5nZXRMb2dnZXIodGhpcy5nZXRDbGFzcygpLCAiREVCVUcgTlRMTSIpOworICAgICAgICBpbml0MCgpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBjb3B5Ynl0ZXMoYnl0ZVtdIGRlc3QsIGludCBkZXN0cG9zLCBTdHJpbmcgc3JjLCBTdHJpbmcgZW5jKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBieXRlW10geCA9IHNyYy5nZXRCeXRlcyhlbmMpOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weSh4LCAwLCBkZXN0LCBkZXN0cG9zLCB4Lmxlbmd0aCk7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgYXNzZXJ0IGZhbHNlOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZW5lcmF0ZVR5cGUxTXNnKGludCBmbGFncykgeworCS8vIFhYWCAtIHNob3VsZCBzZXQgImZsYWdzIiBpbiBnZW5lcmF0ZWQgbWVzc2FnZQorICAgICAgICBpbnQgZGxlbiA9IG50ZG9tYWluLmxlbmd0aCgpOworICAgICAgICB0eXBlMVsxNl09IChieXRlKSAoZGxlbiAlIDI1Nik7CisgICAgICAgIHR5cGUxWzE3XT0gKGJ5dGUpIChkbGVuIC8gMjU2KTsKKyAgICAgICAgdHlwZTFbMThdID0gdHlwZTFbMTZdOworICAgICAgICB0eXBlMVsxOV0gPSB0eXBlMVsxN107CisJaWYgKGRsZW4gPT0gMCkKKwkgICAgdHlwZTFbMTNdICY9IH4weDEwOworCisgICAgICAgIGludCBobGVuID0gaG9zdG5hbWUubGVuZ3RoKCk7CisgICAgICAgIHR5cGUxWzI0XT0gKGJ5dGUpIChobGVuICUgMjU2KTsKKyAgICAgICAgdHlwZTFbMjVdPSAoYnl0ZSkgKGhsZW4gLyAyNTYpOworICAgICAgICB0eXBlMVsyNl0gPSB0eXBlMVsyNF07CisgICAgICAgIHR5cGUxWzI3XSA9IHR5cGUxWzI1XTsKKworICAgICAgICBjb3B5Ynl0ZXModHlwZTEsIDMyLCBob3N0bmFtZSwgImlzby04ODU5LTEiKTsKKyAgICAgICAgY29weWJ5dGVzKHR5cGUxLCBobGVuKzMyLCBudGRvbWFpbiwgImlzby04ODU5LTEiKTsKKyAgICAgICAgdHlwZTFbMjBdID0gKGJ5dGUpICgoaGxlbiszMikgJSAyNTYpOworICAgICAgICB0eXBlMVsyMV0gPSAoYnl0ZSkgKChobGVuKzMyKSAvIDI1Nik7CisKKyAgICAgICAgYnl0ZVtdIG1zZyA9IG5ldyBieXRlWzMyICsgaGxlbiArIGRsZW5dOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHR5cGUxLCAwLCBtc2csIDAsIDMyICsgaGxlbiArIGRsZW4pOworCWlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FKSkKKwkgICAgbG9nZ2VyLmZpbmUoInR5cGUgMSBtZXNzYWdlOiAiICsgdG9IZXgobXNnKSk7CisKKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IG51bGw7CisJdHJ5IHsKKwkgICAgcmVzdWx0ID0gbmV3IFN0cmluZyhCQVNFNjRFbmNvZGVyU3RyZWFtLmVuY29kZShtc2cpLCAiaXNvLTg4NTktMSIpOworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGFzc2VydCBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlcnQgYSA3IGJ5dGUgYXJyYXkgdG8gYW4gOCBieXRlIGFycmF5IChmb3IgYSBkZXMga2V5IHdpdGggcGFyaXR5KS4KKyAgICAgKiBJbnB1dCBzdGFydHMgYXQgb2Zmc2V0IG9mZi4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJ5dGVbXSBtYWtlRGVzS2V5KGJ5dGVbXSBpbnB1dCwgaW50IG9mZikgeworICAgICAgICBpbnRbXSBpbiA9IG5ldyBpbnRbaW5wdXQubGVuZ3RoXTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbi5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgaW5baV0gPSBpbnB1dFtpXSA8IDAgPyBpbnB1dFtpXSArIDI1NjogaW5wdXRbaV07CisgICAgICAgIH0KKyAgICAgICAgYnl0ZVtdIG91dCA9IG5ldyBieXRlWzhdOworICAgICAgICBvdXRbMF0gPSAoYnl0ZSlpbltvZmYrMF07CisgICAgICAgIG91dFsxXSA9IChieXRlKSgoKGluW29mZiswXSA8PCA3KSAmIDB4RkYpIHwgKGluW29mZisxXSA+PiAxKSk7CisgICAgICAgIG91dFsyXSA9IChieXRlKSgoKGluW29mZisxXSA8PCA2KSAmIDB4RkYpIHwgKGluW29mZisyXSA+PiAyKSk7CisgICAgICAgIG91dFszXSA9IChieXRlKSgoKGluW29mZisyXSA8PCA1KSAmIDB4RkYpIHwgKGluW29mZiszXSA+PiAzKSk7CisgICAgICAgIG91dFs0XSA9IChieXRlKSgoKGluW29mZiszXSA8PCA0KSAmIDB4RkYpIHwgKGluW29mZis0XSA+PiA0KSk7CisgICAgICAgIG91dFs1XSA9IChieXRlKSgoKGluW29mZis0XSA8PCAzKSAmIDB4RkYpIHwgKGluW29mZis1XSA+PiA1KSk7CisgICAgICAgIG91dFs2XSA9IChieXRlKSgoKGluW29mZis1XSA8PCAyKSAmIDB4RkYpIHwgKGluW29mZis2XSA+PiA2KSk7CisgICAgICAgIG91dFs3XSA9IChieXRlKSgoaW5bb2ZmKzZdIDw8IDEpICYgMHhGRik7CisgICAgICAgIHJldHVybiBvdXQ7CisgICAgfQorCisgICAgcHJpdmF0ZSBieXRlW10gY2FsY0xNSGFzaCgpIHRocm93cyBHZW5lcmFsU2VjdXJpdHlFeGNlcHRpb24geworICAgICAgICBieXRlW10gbWFnaWMgPSB7MHg0YiwgMHg0NywgMHg1MywgMHgyMSwgMHg0MCwgMHgyMywgMHgyNCwgMHgyNX07CisgICAgICAgIGJ5dGVbXSBwd2IgPSBudWxsOworCXRyeSB7CisJICAgIHB3YiA9IHBhc3N3b3JkLnRvVXBwZXJDYXNlKExvY2FsZS5FTkdMSVNIKS5nZXRCeXRlcygiaXNvLTg4NTktMSIpOworCX0gY2F0Y2ggKFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gZXgpIHsKKwkgICAgLy8gc2hvdWxkIG5ldmVyIGhhcHBlbgorCSAgICBhc3NlcnQgZmFsc2U7CisJfQorICAgICAgICBieXRlW10gcHdiMSA9IG5ldyBieXRlWzE0XTsKKyAgICAgICAgaW50IGxlbiA9IHBhc3N3b3JkLmxlbmd0aCgpOworICAgICAgICBpZiAobGVuID4gMTQpCisgICAgICAgICAgICBsZW4gPSAxNDsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShwd2IsIDAsIHB3YjEsIDAsIGxlbik7IC8qIFplcm8gcGFkZGVkICovCisKKyAgICAgICAgREVTS2V5U3BlYyBka3MxID0gbmV3IERFU0tleVNwZWMobWFrZURlc0tleShwd2IxLCAwKSk7CisgICAgICAgIERFU0tleVNwZWMgZGtzMiA9IG5ldyBERVNLZXlTcGVjKG1ha2VEZXNLZXkocHdiMSwgNykpOworCisgICAgICAgIFNlY3JldEtleSBrZXkxID0gZmFjLmdlbmVyYXRlU2VjcmV0KGRrczEpOworICAgICAgICBTZWNyZXRLZXkga2V5MiA9IGZhYy5nZW5lcmF0ZVNlY3JldChka3MyKTsKKyAgICAgICAgY2lwaGVyLmluaXQoQ2lwaGVyLkVOQ1JZUFRfTU9ERSwga2V5MSk7CisgICAgICAgIGJ5dGVbXSBvdXQxID0gY2lwaGVyLmRvRmluYWwobWFnaWMsIDAsIDgpOworICAgICAgICBjaXBoZXIuaW5pdChDaXBoZXIuRU5DUllQVF9NT0RFLCBrZXkyKTsKKyAgICAgICAgYnl0ZVtdIG91dDIgPSBjaXBoZXIuZG9GaW5hbChtYWdpYywgMCwgOCk7CisKKyAgICAgICAgYnl0ZVtdIHJlc3VsdCA9IG5ldyBieXRlIFsyMV07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkob3V0MSwgMCwgcmVzdWx0LCAwLCA4KTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShvdXQyLCAwLCByZXN1bHQsIDgsIDgpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHByaXZhdGUgYnl0ZVtdIGNhbGNOVEhhc2goKSB0aHJvd3MgR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uIHsKKyAgICAgICAgYnl0ZVtdIHB3ID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHB3ID0gcGFzc3dvcmQuZ2V0Qnl0ZXMoIlVuaWNvZGVMaXR0bGVVbm1hcmtlZCIpOworICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGFzc2VydCBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBieXRlW10gb3V0ID0gbWQ0LmRpZ2VzdChwdyk7CisgICAgICAgIGJ5dGVbXSByZXN1bHQgPSBuZXcgYnl0ZVsyMV07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkob3V0LCAwLCByZXN1bHQsIDAsIDE2KTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKgorICAgICAqIEtleSBpcyBhIDIxIGJ5dGUgYXJyYXkuICBTcGxpdCBpdCBpbnRvIDMgNyBieXRlIGNodW5rcywKKyAgICAgKiBjb252ZXJ0IGVhY2ggdG8gOCBieXRlIERFUyBrZXlzLCBlbmNyeXB0IHRoZSB0ZXh0IGFyZyB3aXRoCisgICAgICogZWFjaCBrZXkgYW5kIHJldHVybiB0aGUgdGhyZWUgcmVzdWx0cyBpbiBhIHNlcXVlbnRpYWwgW10uCisgICAgICovCisgICAgcHJpdmF0ZSBieXRlW10gY2FsY1Jlc3BvbnNlKGJ5dGVbXSBrZXksIGJ5dGVbXSB0ZXh0KQorCQkJCXRocm93cyBHZW5lcmFsU2VjdXJpdHlFeGNlcHRpb24geworICAgICAgICBhc3NlcnQga2V5Lmxlbmd0aCA9PSAyMTsKKyAgICAgICAgREVTS2V5U3BlYyBka3MxID0gbmV3IERFU0tleVNwZWMobWFrZURlc0tleShrZXksIDApKTsKKyAgICAgICAgREVTS2V5U3BlYyBka3MyID0gbmV3IERFU0tleVNwZWMobWFrZURlc0tleShrZXksIDcpKTsKKyAgICAgICAgREVTS2V5U3BlYyBka3MzID0gbmV3IERFU0tleVNwZWMobWFrZURlc0tleShrZXksIDE0KSk7CisgICAgICAgIFNlY3JldEtleSBrZXkxID0gZmFjLmdlbmVyYXRlU2VjcmV0KGRrczEpOworICAgICAgICBTZWNyZXRLZXkga2V5MiA9IGZhYy5nZW5lcmF0ZVNlY3JldChka3MyKTsKKyAgICAgICAgU2VjcmV0S2V5IGtleTMgPSBmYWMuZ2VuZXJhdGVTZWNyZXQoZGtzMyk7CisgICAgICAgIGNpcGhlci5pbml0KENpcGhlci5FTkNSWVBUX01PREUsIGtleTEpOworICAgICAgICBieXRlW10gb3V0MSA9IGNpcGhlci5kb0ZpbmFsKHRleHQsIDAsIDgpOworICAgICAgICBjaXBoZXIuaW5pdChDaXBoZXIuRU5DUllQVF9NT0RFLCBrZXkyKTsKKyAgICAgICAgYnl0ZVtdIG91dDIgPSBjaXBoZXIuZG9GaW5hbCh0ZXh0LCAwLCA4KTsKKyAgICAgICAgY2lwaGVyLmluaXQoQ2lwaGVyLkVOQ1JZUFRfTU9ERSwga2V5Myk7CisgICAgICAgIGJ5dGVbXSBvdXQzID0gY2lwaGVyLmRvRmluYWwodGV4dCwgMCwgOCk7CisgICAgICAgIGJ5dGVbXSByZXN1bHQgPSBuZXcgYnl0ZVsyNF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkob3V0MSwgMCwgcmVzdWx0LCAwLCA4KTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShvdXQyLCAwLCByZXN1bHQsIDgsIDgpOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG91dDMsIDAsIHJlc3VsdCwgMTYsIDgpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2VuZXJhdGVUeXBlM01zZyhTdHJpbmcgY2hhbGxlbmdlKSB7CisJdHJ5IHsKKyAgICAgICAgLyogRmlyc3QgZGVjb2RlIHRoZSB0eXBlMiBtZXNzYWdlIHRvIGdldCB0aGUgc2VydmVyIG5vbmNlICovCisgICAgICAgIC8qIG5vbmNlIGlzIGxvY2F0ZWQgYXQgdHlwZTJbMjRdIGZvciA4IGJ5dGVzICovCisKKyAgICAgICAgYnl0ZVtdIHR5cGUyID0gbnVsbDsKKwl0cnkgeworCSAgICB0eXBlMiA9IEJBU0U2NERlY29kZXJTdHJlYW0uZGVjb2RlKGNoYWxsZW5nZS5nZXRCeXRlcygidXMtYXNjaWkiKSk7CisJfSBjYXRjaCAoVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBleCkgeworCSAgICAvLyBzaG91bGQgbmV2ZXIgaGFwcGVuCisJICAgIGFzc2VydCBmYWxzZTsKKwl9CisgICAgICAgIGJ5dGVbXSBub25jZSA9IG5ldyBieXRlWzhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHR5cGUyLCAyNCwgbm9uY2UsIDAsIDgpOworCisgICAgICAgIGludCB1bGVuID0gdXNlcm5hbWUubGVuZ3RoKCkqMjsKKyAgICAgICAgdHlwZTNbMzZdID0gdHlwZTNbMzhdID0gKGJ5dGUpICh1bGVuICUgMjU2KTsKKyAgICAgICAgdHlwZTNbMzddID0gdHlwZTNbMzldID0gKGJ5dGUpICh1bGVuIC8gMjU2KTsKKyAgICAgICAgaW50IGRsZW4gPSBudGRvbWFpbi5sZW5ndGgoKSoyOworICAgICAgICB0eXBlM1syOF0gPSB0eXBlM1szMF0gPSAoYnl0ZSkgKGRsZW4gJSAyNTYpOworICAgICAgICB0eXBlM1syOV0gPSB0eXBlM1szMV0gPSAoYnl0ZSkgKGRsZW4gLyAyNTYpOworICAgICAgICBpbnQgaGxlbiA9IGhvc3RuYW1lLmxlbmd0aCgpKjI7CisgICAgICAgIHR5cGUzWzQ0XSA9IHR5cGUzWzQ2XSA9IChieXRlKSAoaGxlbiAlIDI1Nik7CisgICAgICAgIHR5cGUzWzQ1XSA9IHR5cGUzWzQ3XSA9IChieXRlKSAoaGxlbiAvIDI1Nik7CisKKyAgICAgICAgaW50IGwgPSA2NDsKKyAgICAgICAgY29weWJ5dGVzKHR5cGUzLCBsLCBudGRvbWFpbiwgIlVuaWNvZGVMaXR0bGVVbm1hcmtlZCIpOworICAgICAgICB0eXBlM1szMl0gPSAoYnl0ZSkgKGwgJSAyNTYpOworICAgICAgICB0eXBlM1szM10gPSAoYnl0ZSkgKGwgLyAyNTYpOworICAgICAgICBsICs9IGRsZW47CisgICAgICAgIGNvcHlieXRlcyh0eXBlMywgbCwgdXNlcm5hbWUsICJVbmljb2RlTGl0dGxlVW5tYXJrZWQiKTsKKyAgICAgICAgdHlwZTNbNDBdID0gKGJ5dGUpIChsICUgMjU2KTsKKyAgICAgICAgdHlwZTNbNDFdID0gKGJ5dGUpIChsIC8gMjU2KTsKKyAgICAgICAgbCArPSB1bGVuOworICAgICAgICBjb3B5Ynl0ZXModHlwZTMsIGwsIGhvc3RuYW1lLCAiVW5pY29kZUxpdHRsZVVubWFya2VkIik7CisgICAgICAgIHR5cGUzWzQ4XSA9IChieXRlKSAobCAlIDI1Nik7CisgICAgICAgIHR5cGUzWzQ5XSA9IChieXRlKSAobCAvIDI1Nik7CisgICAgICAgIGwgKz0gaGxlbjsKKworICAgICAgICBieXRlW10gbG1oYXNoID0gY2FsY0xNSGFzaCgpOworICAgICAgICBieXRlW10gbG1yZXNwb25zZSA9IGNhbGNSZXNwb25zZShsbWhhc2gsIG5vbmNlKTsKKyAgICAgICAgYnl0ZVtdIG50aGFzaCA9IGNhbGNOVEhhc2goKTsKKyAgICAgICAgYnl0ZVtdIG50cmVzcG9uc2UgPSBjYWxjUmVzcG9uc2UobnRoYXNoLCBub25jZSk7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobG1yZXNwb25zZSwgMCwgdHlwZTMsIGwsIDI0KTsKKyAgICAgICAgdHlwZTNbMTZdID0gKGJ5dGUpIChsICUgMjU2KTsKKyAgICAgICAgdHlwZTNbMTddID0gKGJ5dGUpIChsIC8gMjU2KTsKKyAgICAgICAgbCArPSAyNDsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShudHJlc3BvbnNlLCAwLCB0eXBlMywgbCwgMjQpOworICAgICAgICB0eXBlM1syNF0gPSAoYnl0ZSkgKGwgJSAyNTYpOworICAgICAgICB0eXBlM1syNV0gPSAoYnl0ZSkgKGwgLyAyNTYpOworICAgICAgICBsICs9IDI0OworICAgICAgICB0eXBlM1s1Nl0gPSAoYnl0ZSkgKGwgJSAyNTYpOworICAgICAgICB0eXBlM1s1N10gPSAoYnl0ZSkgKGwgLyAyNTYpOworCisgICAgICAgIGJ5dGVbXSBtc2cgPSBuZXcgYnl0ZVtsXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weSh0eXBlMywgMCwgbXNnLCAwLCBsKTsKKwlpZiAobG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuRklORSkpCisJICAgIGxvZ2dlci5maW5lKCJ0eXBlIDMgbWVzc2FnZTogIiArIHRvSGV4KG1zZykpOworCisgICAgICAgIFN0cmluZyByZXN1bHQgPSBudWxsOworCXRyeSB7CisJICAgIHJlc3VsdCA9IG5ldyBTdHJpbmcoQkFTRTY0RW5jb2RlclN0cmVhbS5lbmNvZGUobXNnKSwgImlzby04ODU5LTEiKTsKKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnQgZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKworCX0gY2F0Y2ggKEdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbiBleCkgeworCSAgICAvLyBzaG91bGQgbmV2ZXIgaGFwcGVuCisJICAgIGxvZ2dlci5sb2coTGV2ZWwuRklORSwgIkdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbiIsIGV4KTsKKwkgICAgcmV0dXJuICIiOwkvLyB3aWxsIGZhaWwgbGF0ZXIKKwl9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgY2hhcltdIGhleCA9CisJeyAnMCcsJzEnLCcyJywnMycsJzQnLCc1JywnNicsJzcnLCc4JywnOScsJ0EnLCdCJywnQycsJ0QnLCdFJywnRicgfTsKKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyB0b0hleChieXRlW10gYikgeworCVN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcihiLmxlbmd0aCAqIDMpOworCWZvciAoaW50IGkgPSAwOyBpIDwgYi5sZW5ndGg7IGkrKykKKwkgICAgc2IuYXBwZW5kKGhleFsoYltpXT4+NCkmMHhGXSkuYXBwZW5kKGhleFtiW2ldJjB4Rl0pLmFwcGVuZCgnICcpOworCXJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvYXV0aC9PQXV0aDJTYXNsQ2xpZW50LmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2F1dGgvT0F1dGgyU2FzbENsaWVudC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJlYzk1ZDQKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2F1dGgvT0F1dGgyU2FzbENsaWVudC5qYXZhCkBAIC0wLDAgKzEsMTIwIEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDE0LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5hdXRoOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJpdHk7CitpbXBvcnQgamF2YXguc2VjdXJpdHkuc2FzbC4qOworaW1wb3J0IGphdmF4LnNlY3VyaXR5LmF1dGguY2FsbGJhY2suKjsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLkFTQ0lJVXRpbGl0eTsKKworLyoqCisgKiBKYXZhTWFpbCBTQVNMIGNsaWVudCBmb3IgT0FVVEgyLgorICoKKyAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjNjc0OSI+CisgKglSRkMgNjc0OSAtIE9BdXRoIDIuMCBBdXRob3JpemF0aW9uIEZyYW1ld29yazwvYT4KKyAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjNjc1MCI+CisgKglSRkMgNjc1MCAtIE9BdXRoIDIuMCBBdXRob3JpemF0aW9uIEZyYW1ld29yazogQmVhcmVyIFRva2VuIFVzYWdlPC9hPgorICogQGF1dGhvciBCaWxsIFNoYW5ub24KKyAqLworcHVibGljIGNsYXNzIE9BdXRoMlNhc2xDbGllbnQgaW1wbGVtZW50cyBTYXNsQ2xpZW50IHsKKyAgICBwcml2YXRlIENhbGxiYWNrSGFuZGxlciBjYmg7CisgICAgLy9wcml2YXRlIE1hcDxTdHJpbmcsPz4gcHJvcHM7CS8vIFhYWCAtIG5vdCBjdXJyZW50bHkgdXNlZAorICAgIHByaXZhdGUgYm9vbGVhbiBjb21wbGV0ZSA9IGZhbHNlOworCisgICAgcHVibGljIE9BdXRoMlNhc2xDbGllbnQoTWFwPFN0cmluZyw/PiBwcm9wcywgQ2FsbGJhY2tIYW5kbGVyIGNiaCkgeworCS8vdGhpcy5wcm9wcyA9IHByb3BzOworCXRoaXMuY2JoID0gY2JoOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWVjaGFuaXNtTmFtZSgpIHsKKwlyZXR1cm4gIlhPQVVUSDIiOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGhhc0luaXRpYWxSZXNwb25zZSgpIHsKKwlyZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYnl0ZVtdIGV2YWx1YXRlQ2hhbGxlbmdlKGJ5dGVbXSBjaGFsbGVuZ2UpIHRocm93cyBTYXNsRXhjZXB0aW9uIHsKKwlpZiAoY29tcGxldGUpCisJICAgIHJldHVybiBuZXcgYnl0ZVswXTsKKworCU5hbWVDYWxsYmFjayBuY2IgPSBuZXcgTmFtZUNhbGxiYWNrKCJVc2VyIG5hbWU6Iik7CisJUGFzc3dvcmRDYWxsYmFjayBwY2IgPSBuZXcgUGFzc3dvcmRDYWxsYmFjaygiT0F1dGggdG9rZW46IiwgZmFsc2UpOworCXRyeSB7CisJICAgIGNiaC5oYW5kbGUobmV3IENhbGxiYWNrW10geyBuY2IsIHBjYiB9KTsKKwl9IGNhdGNoIChVbnN1cHBvcnRlZENhbGxiYWNrRXhjZXB0aW9uIGV4KSB7CisJICAgIHRocm93IG5ldyBTYXNsRXhjZXB0aW9uKCJVbnN1cHBvcnRlZCBjYWxsYmFjayIsIGV4KTsKKwl9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworCSAgICB0aHJvdyBuZXcgU2FzbEV4Y2VwdGlvbigiQ2FsbGJhY2sgaGFuZGxlciBmYWlsZWQiLCBleCk7CisJfQorCisJLyoKKwkgKiBUaGUgT0F1dGggdG9rZW4gaXNuJ3QgcmVhbGx5IGEgcGFzc3dvcmQsIGFuZCBKYXZhTWFpbCBkb2Vzbid0CisJICogdXNlIGNoYXJbXSBmb3IgcGFzc3dvcmRzLCBzbyB3ZSBkb24ndCB3b3JyeSBhYm91dCBzdG9yaW5nIHRoZQorCSAqIHRva2VuIGluIHN0cmluZ3MuCisJICovCisJU3RyaW5nIHVzZXIgPSBuY2IuZ2V0TmFtZSgpOworCVN0cmluZyB0b2tlbiA9IG5ldyBTdHJpbmcocGNiLmdldFBhc3N3b3JkKCkpOworCXBjYi5jbGVhclBhc3N3b3JkKCk7CisJU3RyaW5nIHJlc3AgPSAidXNlcj0iICsgdXNlciArICJcMDAxYXV0aD1CZWFyZXIgIiArIHRva2VuICsgIlwwMDFcMDAxIjsKKwlieXRlW10gcmVzcG9uc2U7CisJdHJ5IHsKKwkgICAgcmVzcG9uc2UgPSByZXNwLmdldEJ5dGVzKCJ1dGYtOCIpOworCX0gY2F0Y2ggKFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gZXgpIHsKKwkgICAgLy8gZmFsbCBiYWNrIHRvIEFTQ0lJCisJICAgIHJlc3BvbnNlID0gQVNDSUlVdGlsaXR5LmdldEJ5dGVzKHJlc3ApOworCX0KKwljb21wbGV0ZSA9IHRydWU7CisJcmV0dXJuIHJlc3BvbnNlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGlzQ29tcGxldGUoKSB7CisJcmV0dXJuIGNvbXBsZXRlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBieXRlW10gdW53cmFwKGJ5dGVbXSBpbmNvbWluZywgaW50IG9mZnNldCwgaW50IGxlbikKKwkJCQl0aHJvd3MgU2FzbEV4Y2VwdGlvbiB7CisJdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiT0FVVEgyIHVud3JhcCBub3Qgc3VwcG9ydGVkIik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJ5dGVbXSB3cmFwKGJ5dGVbXSBvdXRnb2luZywgaW50IG9mZnNldCwgaW50IGxlbikKKwkJCQl0aHJvd3MgU2FzbEV4Y2VwdGlvbiB7CisJdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiT0FVVEgyIHdyYXAgbm90IHN1cHBvcnRlZCIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgZ2V0TmVnb3RpYXRlZFByb3BlcnR5KFN0cmluZyBwcm9wTmFtZSkgeworCWlmICghY29tcGxldGUpCisJICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIk9BVVRIMiBnZXROZWdvdGlhdGVkUHJvcGVydHkiKTsKKwlyZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBkaXNwb3NlKCkgdGhyb3dzIFNhc2xFeGNlcHRpb24geworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvYXV0aC9PQXV0aDJTYXNsQ2xpZW50RmFjdG9yeS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9hdXRoL09BdXRoMlNhc2xDbGllbnRGYWN0b3J5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODQ1MDM5MQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvYXV0aC9PQXV0aDJTYXNsQ2xpZW50RmFjdG9yeS5qYXZhCkBAIC0wLDAgKzEsNzMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMTQsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmF1dGg7CisKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlByb3ZpZGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJpdHk7CitpbXBvcnQgamF2YXguc2VjdXJpdHkuc2FzbC4qOworaW1wb3J0IGphdmF4LnNlY3VyaXR5LmF1dGguY2FsbGJhY2suKjsKKworLyoqCisgKiBKYXZhTWFpbCBTQVNMIGNsaWVudCBmYWN0b3J5IGZvciBPQVVUSDIuCisgKgorICogQGF1dGhvciBCaWxsIFNoYW5ub24KKyAqLworcHVibGljIGNsYXNzIE9BdXRoMlNhc2xDbGllbnRGYWN0b3J5IGltcGxlbWVudHMgU2FzbENsaWVudEZhY3RvcnkgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFBST1ZJREVSX05BTUUgPSAiSmF2YU1haWwtT0F1dGgyIjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTUVDSEFOSVNNX05BTUUgPSAiU2FzbENsaWVudEZhY3RvcnkuWE9BVVRIMiI7CisKKyAgICBzdGF0aWMgY2xhc3MgT0F1dGgyUHJvdmlkZXIgZXh0ZW5kcyBQcm92aWRlciB7CisJcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTUzNzE3OTU1NTE1NjIyODcwNTlMOworCisJcHVibGljIE9BdXRoMlByb3ZpZGVyKCkgeworCSAgICBzdXBlcihQUk9WSURFUl9OQU1FLCAxLjAsICJYT0FVVEgyIFNBU0wgTWVjaGFuaXNtIik7CisJICAgIHB1dChNRUNIQU5JU01fTkFNRSwgT0F1dGgyU2FzbENsaWVudEZhY3RvcnkuY2xhc3MuZ2V0TmFtZSgpKTsKKwl9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNhc2xDbGllbnQgY3JlYXRlU2FzbENsaWVudChTdHJpbmdbXSBtZWNoYW5pc21zLAorCQkJCVN0cmluZyBhdXRob3JpemF0aW9uSWQsIFN0cmluZyBwcm90b2NvbCwKKwkJCQlTdHJpbmcgc2VydmVyTmFtZSwgTWFwPFN0cmluZyw/PiBwcm9wcywKKwkJCQlDYWxsYmFja0hhbmRsZXIgY2JoKSB0aHJvd3MgU2FzbEV4Y2VwdGlvbiB7CisJZm9yIChTdHJpbmcgbSA6IG1lY2hhbmlzbXMpIHsKKwkgICAgaWYgKG0uZXF1YWxzKCJYT0FVVEgyIikpCisJCXJldHVybiBuZXcgT0F1dGgyU2FzbENsaWVudChwcm9wcywgY2JoKTsKKwl9CisJcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZ1tdIGdldE1lY2hhbmlzbU5hbWVzKE1hcDxTdHJpbmcsPz4gcHJvcHMpIHsKKwlyZXR1cm4gbmV3IFN0cmluZ1tdIHsgIlhPQVVUSDIiIH07CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZSB0aGlzIE9BVVRIMiBwcm92aWRlciwgYnV0IG9ubHkgaWYgdGhlcmUgaXNuJ3Qgb25lIGFscmVhZHkuCisgICAgICogSWYgd2UncmUgbm90IGFsbG93ZWQgdG8gYWRkIHRoaXMgcHJvdmlkZXIsIGp1c3QgZ2l2ZSB1cCBzaWxlbnRseS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgaW5pdCgpIHsKKwl0cnkgeworCSAgICBpZiAoU2VjdXJpdHkuZ2V0UHJvdmlkZXIoUFJPVklERVJfTkFNRSkgPT0gbnVsbCkKKwkJU2VjdXJpdHkuYWRkUHJvdmlkZXIobmV3IE9BdXRoMlByb3ZpZGVyKCkpOworCX0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGV4KSB7CisJICAgIC8vIG9oIHdlbGwuLi4KKwl9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9hdXRoL3BhY2thZ2UuaHRtbCBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvYXV0aC9wYWNrYWdlLmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDc2ZjJlZQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvYXV0aC9wYWNrYWdlLmh0bWwKQEAgLTAsMCArMSwzMyBAQAorPCFET0NUWVBFIGh0bWwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMDEgVHJhbnNpdGlvbmFsLy9FTiI+Cis8SFRNTD4KKzxIRUFEPgorPG1ldGEgaHR0cC1lcXVpdj0iQ29udGVudC1UeXBlIiBjb250ZW50PSJ0ZXh0L2h0bWw7IGNoYXJzZXQ9dXRmLTgiPgorPCEtLQorCisgICAgQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisKKyAgICBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAgICB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKworICAgIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAgICBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgICAgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgICAgdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisKKyAgICBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKworLS0+CisKKzxUSVRMRT5jb20uc3VuLm1haWwuYXV0aCBwYWNrYWdlPC9USVRMRT4KKzwvSEVBRD4KKzxCT0RZIEJHQ09MT1I9IndoaXRlIj4KKworPFA+CitUaGlzIHBhY2thZ2UgaW5jbHVkZXMgaW50ZXJuYWwgYXV0aGVudGljYXRpb24gc3VwcG9ydCBjbGFzc2VzIGFuZAorPHN0cm9uZz5TSE9VTEQgTk9UIEJFIFVTRUQgRElSRUNUTFkgQlkgQVBQTElDQVRJT05TPC9zdHJvbmc+LgorPC9QPgorCis8L0JPRFk+Cis8L0hUTUw+CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2hhbmRsZXJzL2hhbmRsZXJfYmFzZS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9oYW5kbGVycy9oYW5kbGVyX2Jhc2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YjRlZGFlCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9oYW5kbGVycy9oYW5kbGVyX2Jhc2UuamF2YQpAQCAtMCwwICsxLDg1IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5oYW5kbGVyczsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5hd3QuZGF0YXRyYW5zZmVyLkRhdGFGbGF2b3I7CitpbXBvcnQgamF2YXguYWN0aXZhdGlvbi4qOworCisvKioKKyAqIEJhc2UgY2xhc3MgZm9yIG90aGVyIERhdGFDb250ZW50SGFuZGxlcnMuCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBoYW5kbGVyX2Jhc2UgaW1wbGVtZW50cyBEYXRhQ29udGVudEhhbmRsZXIgeworCisgICAgLyoqCisgICAgICogUmV0dXJuIGFuIGFycmF5IG9mIEFjdGl2YXRpb25EYXRhRmxhdm9ycyB0aGF0IHdlIHN1cHBvcnQuCisgICAgICogVXN1YWxseSB0aGVyZSB3aWxsIGJlIG9ubHkgb25lLgorICAgICAqCisgICAgICogQHJldHVybglhcnJheSBvZiBBY3RpdmF0aW9uRGF0YUZsYXZvcnMgdGhhdCB3ZSBzdXBwb3J0CisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IEFjdGl2YXRpb25EYXRhRmxhdm9yW10gZ2V0RGF0YUZsYXZvcnMoKTsKKworICAgIC8qKgorICAgICAqIEdpdmVuIHRoZSBmbGF2b3IgdGhhdCBtYXRjaGVkLCByZXR1cm4gdGhlIGFwcHJvcHJpYXRlIHR5cGUgb2Ygb2JqZWN0LgorICAgICAqIFVzdWFsbHkgdGhlcmUncyBvbmx5IG9uZSBmbGF2b3Igc28ganVzdCBjYWxsIGdldENvbnRlbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0JYUZsYXZvcgl0aGUgQWN0aXZhdGlvbkRhdGFGbGF2b3IKKyAgICAgKiBAcGFyYW0JZHMJRGF0YVNvdXJjZSBjb250YWluaW5nIHRoZSBkYXRhCisgICAgICogQHJldHVybgl0aGUgb2JqZWN0CisgICAgICogQGV4Y2VwdGlvbglJT0V4Y2VwdGlvbglmb3IgZXJyb3JzIHJlYWRpbmcgdGhlIGRhdGEKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgT2JqZWN0IGdldERhdGEoQWN0aXZhdGlvbkRhdGFGbGF2b3IgYUZsYXZvciwgRGF0YVNvdXJjZSBkcykKKwkJCQl0aHJvd3MgSU9FeGNlcHRpb24geworCXJldHVybiBnZXRDb250ZW50KGRzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIERhdGFGbGF2b3JzIGZvciB0aGlzIDxjb2RlPkRhdGFDb250ZW50SGFuZGxlcjwvY29kZT4uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIFRoZSBEYXRhRmxhdm9ycworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBEYXRhRmxhdm9yW10gZ2V0VHJhbnNmZXJEYXRhRmxhdm9ycygpIHsKKwlBY3RpdmF0aW9uRGF0YUZsYXZvcltdIGFkZiA9IGdldERhdGFGbGF2b3JzKCk7CisJaWYgKGFkZi5sZW5ndGggPT0gMSkJLy8gdGhlIGNvbW1vbiBjYXNlCisJICAgIHJldHVybiBuZXcgRGF0YUZsYXZvcltdIHsgYWRmWzBdIH07CisJRGF0YUZsYXZvcltdIGRmID0gbmV3IERhdGFGbGF2b3JbYWRmLmxlbmd0aF07CisJU3lzdGVtLmFycmF5Y29weShhZGYsIDAsIGRmLCAwLCBhZGYubGVuZ3RoKTsKKwlyZXR1cm4gZGY7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBUcmFuc2ZlciBEYXRhIG9mIHR5cGUgRGF0YUZsYXZvciBmcm9tIElucHV0U3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtCWRmCVRoZSBEYXRhRmxhdm9yCisgICAgICogQHBhcmFtCWRzCVRoZSBEYXRhU291cmNlIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGRhdGEKKyAgICAgKiBAcmV0dXJuCXRoZSBvYmplY3QKKyAgICAgKiBAZXhjZXB0aW9uCUlPRXhjZXB0aW9uCWZvciBlcnJvcnMgcmVhZGluZyB0aGUgZGF0YQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgZ2V0VHJhbnNmZXJEYXRhKERhdGFGbGF2b3IgZGYsIERhdGFTb3VyY2UgZHMpIAorCQkJdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlBY3RpdmF0aW9uRGF0YUZsYXZvcltdIGFkZiA9IGdldERhdGFGbGF2b3JzKCk7CisJZm9yIChpbnQgaSA9IDA7IGkgPCBhZGYubGVuZ3RoOyBpKyspIHsKKwkgICAgLy8gdXNlIEFjdGl2YXRpb25EYXRhRmxhdm9yLmVxdWFscywgd2hpY2ggcHJvcGVybHkKKwkgICAgLy8gaWdub3JlcyBDb250ZW50LVR5cGUgcGFyYW1ldGVycyBpbiBjb21wYXJpc29uCisJICAgIGlmIChhZGZbaV0uZXF1YWxzKGRmKSkKKwkJcmV0dXJuIGdldERhdGEoYWRmW2ldLCBkcyk7CisJfQorCXJldHVybiBudWxsOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaGFuZGxlcnMvaW1hZ2VfZ2lmLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2hhbmRsZXJzL2ltYWdlX2dpZi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBjNzVjOGIKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2hhbmRsZXJzL2ltYWdlX2dpZi5qYXZhCkBAIC0wLDAgKzEsNzQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmhhbmRsZXJzOworCitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmEuYXd0Lio7CitpbXBvcnQgamF2YXguYWN0aXZhdGlvbi4qOworCisvKioKKyAqIERhdGFDb250ZW50SGFuZGxlciBmb3IgaW1hZ2UvZ2lmLgorICovCitwdWJsaWMgY2xhc3MgaW1hZ2VfZ2lmIGV4dGVuZHMgaGFuZGxlcl9iYXNlIHsKKyAgICBwcml2YXRlIHN0YXRpYyBBY3RpdmF0aW9uRGF0YUZsYXZvcltdIG15REYgPSB7CisJbmV3IEFjdGl2YXRpb25EYXRhRmxhdm9yKEltYWdlLmNsYXNzLCAiaW1hZ2UvZ2lmIiwgIkdJRiBJbWFnZSIpCisgICAgfTsKKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBBY3RpdmF0aW9uRGF0YUZsYXZvcltdIGdldERhdGFGbGF2b3JzKCkgeworCXJldHVybiBteURGOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgZ2V0Q29udGVudChEYXRhU291cmNlIGRzKSB0aHJvd3MgSU9FeGNlcHRpb24geworCUlucHV0U3RyZWFtIGlzID0gZHMuZ2V0SW5wdXRTdHJlYW0oKTsKKwlpbnQgcG9zID0gMDsKKwlpbnQgY291bnQ7CisJYnl0ZSBidWZbXSA9IG5ldyBieXRlWzEwMjRdOworCisJd2hpbGUgKChjb3VudCA9IGlzLnJlYWQoYnVmLCBwb3MsIGJ1Zi5sZW5ndGggLSBwb3MpKSAhPSAtMSkgeworCSAgICBwb3MgKz0gY291bnQ7CisJICAgIGlmIChwb3MgPj0gYnVmLmxlbmd0aCkgeworCQlpbnQgc2l6ZSA9IGJ1Zi5sZW5ndGg7CisJCWlmIChzaXplIDwgMjU2KjEwMjQpCisJCSAgICBzaXplICs9IHNpemU7CisJCWVsc2UKKwkJICAgIHNpemUgKz0gMjU2KjEwMjQ7CisJCWJ5dGUgdGJ1ZltdID0gbmV3IGJ5dGVbc2l6ZV07CisJCVN5c3RlbS5hcnJheWNvcHkoYnVmLCAwLCB0YnVmLCAwLCBwb3MpOworCQlidWYgPSB0YnVmOworCSAgICB9CisJfQorCVRvb2xraXQgdGsgPSBUb29sa2l0LmdldERlZmF1bHRUb29sa2l0KCk7CisJcmV0dXJuIHRrLmNyZWF0ZUltYWdlKGJ1ZiwgMCwgcG9zKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZSB0aGUgb2JqZWN0IHRvIHRoZSBvdXRwdXQgc3RyZWFtLCB1c2luZyB0aGUgc3BlY2lmaWVkIE1JTUUgdHlwZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKE9iamVjdCBvYmosIFN0cmluZyB0eXBlLCBPdXRwdXRTdHJlYW0gb3MpCisJCQl0aHJvd3MgSU9FeGNlcHRpb24geworCWlmICghKG9iaiBpbnN0YW5jZW9mIEltYWdlKSkKKwkgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJcIiIgKyBnZXREYXRhRmxhdm9ycygpWzBdLmdldE1pbWVUeXBlKCkgKworCQkiXCIgRGF0YUNvbnRlbnRIYW5kbGVyIHJlcXVpcmVzIEltYWdlIG9iamVjdCwgIiArCisJCSJ3YXMgZ2l2ZW4gb2JqZWN0IG9mIHR5cGUgIiArIG9iai5nZXRDbGFzcygpLnRvU3RyaW5nKCkpOworCisJdGhyb3cgbmV3IElPRXhjZXB0aW9uKGdldERhdGFGbGF2b3JzKClbMF0uZ2V0TWltZVR5cGUoKSArCisJCQkJIiBlbmNvZGluZyBub3Qgc3VwcG9ydGVkIik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9oYW5kbGVycy9pbWFnZV9qcGVnLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2hhbmRsZXJzL2ltYWdlX2pwZWcuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNDlkMTI5Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9oYW5kbGVycy9pbWFnZV9qcGVnLmphdmEKQEAgLTAsMCArMSwzNCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuaGFuZGxlcnM7CisKK2ltcG9ydCBqYXZhLmF3dC5JbWFnZTsKK2ltcG9ydCBqYXZheC5hY3RpdmF0aW9uLkFjdGl2YXRpb25EYXRhRmxhdm9yOworCisvKioKKyAqIERhdGFDb250ZW50SGFuZGxlciBmb3IgaW1hZ2UvanBlZy4KKyAqLworcHVibGljIGNsYXNzIGltYWdlX2pwZWcgZXh0ZW5kcyBpbWFnZV9naWYgeworICAgIHByaXZhdGUgc3RhdGljIEFjdGl2YXRpb25EYXRhRmxhdm9yW10gbXlERiA9IHsKKwluZXcgQWN0aXZhdGlvbkRhdGFGbGF2b3IoSW1hZ2UuY2xhc3MsICJpbWFnZS9qcGVnIiwgIkpQRUcgSW1hZ2UiKQorICAgIH07CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgQWN0aXZhdGlvbkRhdGFGbGF2b3JbXSBnZXREYXRhRmxhdm9ycygpIHsKKwlyZXR1cm4gbXlERjsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2hhbmRsZXJzL21lc3NhZ2VfcmZjODIyLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2hhbmRsZXJzL21lc3NhZ2VfcmZjODIyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDdiNGM4MQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaGFuZGxlcnMvbWVzc2FnZV9yZmM4MjIuamF2YQpAQCAtMCwwICsxLDkwIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5oYW5kbGVyczsKKworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKK2ltcG9ydCBqYXZheC5hY3RpdmF0aW9uLio7CitpbXBvcnQgamF2YXgubWFpbC4qOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuKjsKKworCisvKioKKyAqIEBhdXRob3IJQ2hyaXN0b3BoZXIgQ290dG9uCisgKi8KKworCitwdWJsaWMgY2xhc3MgbWVzc2FnZV9yZmM4MjIgZXh0ZW5kcyBoYW5kbGVyX2Jhc2UgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgQWN0aXZhdGlvbkRhdGFGbGF2b3JbXSBvdXJEYXRhRmxhdm9yID0geworCW5ldyBBY3RpdmF0aW9uRGF0YUZsYXZvcihNZXNzYWdlLmNsYXNzLCAibWVzc2FnZS9yZmM4MjIiLCAiTWVzc2FnZSIpCisgICAgfTsKKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBBY3RpdmF0aW9uRGF0YUZsYXZvcltdIGdldERhdGFGbGF2b3JzKCkgeworCXJldHVybiBvdXJEYXRhRmxhdm9yOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgY29udGVudC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgT2JqZWN0IGdldENvbnRlbnQoRGF0YVNvdXJjZSBkcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkvLyBjcmVhdGUgYSBuZXcgTWltZU1lc3NhZ2UKKwl0cnkgeworCSAgICBTZXNzaW9uIHNlc3Npb247CisJICAgIGlmIChkcyBpbnN0YW5jZW9mIE1lc3NhZ2VBd2FyZSkgeworCQlNZXNzYWdlQ29udGV4dCBtYyA9ICgoTWVzc2FnZUF3YXJlKWRzKS5nZXRNZXNzYWdlQ29udGV4dCgpOworCQlzZXNzaW9uID0gbWMuZ2V0U2Vzc2lvbigpOworCSAgICB9IGVsc2UgeworCQkvLyBIb3BlZnVsbHkgYSByYXJlIGNhc2UuICBBbHNvIGhvcGVmdWxseSB0aGUgYXBwbGljYXRpb24KKwkJLy8gaGFzIGNyZWF0ZWQgYSBkZWZhdWx0IFNlc3Npb24gdGhhdCBjYW4ganVzdCBiZSByZXR1cm5lZAorCQkvLyBoZXJlLiAgSWYgbm90LCB0aGUgb25lIHdlIGNyZWF0ZSBoZXJlIGlzIGJldHRlciB0aGFuCisJCS8vIG5vdGhpbmcsIGJ1dCBvdmVyYWxsIG5vdCBhIHJlYWxseSBnb29kIGFuc3dlci4KKwkJc2Vzc2lvbiA9IFNlc3Npb24uZ2V0RGVmYXVsdEluc3RhbmNlKG5ldyBQcm9wZXJ0aWVzKCksIG51bGwpOworCSAgICB9CisJICAgIHJldHVybiBuZXcgTWltZU1lc3NhZ2Uoc2Vzc2lvbiwgZHMuZ2V0SW5wdXRTdHJlYW0oKSk7CisJfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIG1lKSB7CisJICAgIElPRXhjZXB0aW9uIGlvZXggPQorCQluZXcgSU9FeGNlcHRpb24oIkV4Y2VwdGlvbiBjcmVhdGluZyBNaW1lTWVzc2FnZSBpbiAiICsKKwkJICAgICJtZXNzYWdlL3JmYzgyMiBEYXRhQ29udGVudEhhbmRsZXIiKTsKKwkgICAgaW9leC5pbml0Q2F1c2UobWUpOworCSAgICB0aHJvdyBpb2V4OworCX0KKyAgICB9CisgICAgCisgICAgLyoqCisgICAgICogV3JpdGUgdGhlIG9iamVjdCBhcyBhIGJ5dGUgc3RyZWFtLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oT2JqZWN0IG9iaiwgU3RyaW5nIG1pbWVUeXBlLCBPdXRwdXRTdHJlYW0gb3MpIAorCQkJdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkvLyBpZiB0aGUgb2JqZWN0IGlzIGEgbWVzc2FnZSwgd2Uga25vdyBob3cgdG8gd3JpdGUgdGhhdCBvdXQKKwlpZiAob2JqIGluc3RhbmNlb2YgTWVzc2FnZSkgeworCSAgICBNZXNzYWdlIG0gPSAoTWVzc2FnZSlvYmo7CisJICAgIHRyeSB7CisJCW0ud3JpdGVUbyhvcyk7CisJICAgIH0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBtZSkgeworCQlJT0V4Y2VwdGlvbiBpb2V4ID0gbmV3IElPRXhjZXB0aW9uKCJFeGNlcHRpb24gd3JpdGluZyBtZXNzYWdlIik7CisJCWlvZXguaW5pdENhdXNlKG1lKTsKKwkJdGhyb3cgaW9leDsKKwkgICAgfQorCX0gZWxzZSB7CisJICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigidW5zdXBwb3J0ZWQgb2JqZWN0Iik7CisJfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaGFuZGxlcnMvbXVsdGlwYXJ0X21peGVkLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2hhbmRsZXJzL211bHRpcGFydF9taXhlZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJlMmJkMmUKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2hhbmRsZXJzL211bHRpcGFydF9taXhlZC5qYXZhCkBAIC0wLDAgKzEsNjkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmhhbmRsZXJzOworCitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmF4LmFjdGl2YXRpb24uKjsKK2ltcG9ydCBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5tYWlsLk11bHRpcGFydDsKK2ltcG9ydCBqYXZheC5tYWlsLmludGVybmV0Lk1pbWVNdWx0aXBhcnQ7CisKKworcHVibGljIGNsYXNzIG11bHRpcGFydF9taXhlZCBleHRlbmRzIGhhbmRsZXJfYmFzZSB7CisgICAgcHJpdmF0ZSBzdGF0aWMgQWN0aXZhdGlvbkRhdGFGbGF2b3JbXSBteURGID0geworCW5ldyBBY3RpdmF0aW9uRGF0YUZsYXZvcihNdWx0aXBhcnQuY2xhc3MsCisJCQkJICAgICJtdWx0aXBhcnQvbWl4ZWQiLCAiTXVsdGlwYXJ0IikKKyAgICB9OworCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIEFjdGl2YXRpb25EYXRhRmxhdm9yW10gZ2V0RGF0YUZsYXZvcnMoKSB7CisJcmV0dXJuIG15REY7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBjb250ZW50LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgZ2V0Q29udGVudChEYXRhU291cmNlIGRzKSB0aHJvd3MgSU9FeGNlcHRpb24geworCXRyeSB7CisJICAgIHJldHVybiBuZXcgTWltZU11bHRpcGFydChkcyk7IAorCX0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBlKSB7CisJICAgIElPRXhjZXB0aW9uIGlvZXggPQorCQluZXcgSU9FeGNlcHRpb24oIkV4Y2VwdGlvbiB3aGlsZSBjb25zdHJ1Y3RpbmcgTWltZU11bHRpcGFydCIpOworCSAgICBpb2V4LmluaXRDYXVzZShlKTsKKwkgICAgdGhyb3cgaW9leDsKKwl9CisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIFdyaXRlIHRoZSBvYmplY3QgdG8gdGhlIG91dHB1dCBzdHJlYW0sIHVzaW5nIHRoZSBzcGVjaWZpYyBNSU1FIHR5cGUuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGVUbyhPYmplY3Qgb2JqLCBTdHJpbmcgbWltZVR5cGUsIE91dHB1dFN0cmVhbSBvcykgCisJCQl0aHJvd3MgSU9FeGNlcHRpb24geworCWlmIChvYmogaW5zdGFuY2VvZiBNdWx0aXBhcnQpIHsKKwkgICAgdHJ5IHsKKwkJKChNdWx0aXBhcnQpb2JqKS53cml0ZVRvKG9zKTsKKwkgICAgfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIGUpIHsKKwkJSU9FeGNlcHRpb24gaW9leCA9CisJCSAgICBuZXcgSU9FeGNlcHRpb24oIkV4Y2VwdGlvbiB3cml0aW5nIE11bHRpcGFydCIpOworCQlpb2V4LmluaXRDYXVzZShlKTsKKwkJdGhyb3cgaW9leDsKKwkgICAgfQorCX0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2hhbmRsZXJzL3BhY2thZ2UuaHRtbCBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaGFuZGxlcnMvcGFja2FnZS5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBhYWZhMjEKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2hhbmRsZXJzL3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDMzIEBACis8IURPQ1RZUEUgaHRtbCBQVUJMSUMgIi0vL1czQy8vRFREIEhUTUwgNC4wMSBUcmFuc2l0aW9uYWwvL0VOIj4KKzxIVE1MPgorPEhFQUQ+Cis8bWV0YSBodHRwLWVxdWl2PSJDb250ZW50LVR5cGUiIGNvbnRlbnQ9InRleHQvaHRtbDsgY2hhcnNldD11dGYtOCI+Cis8IS0tCisKKyAgICBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKworICAgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICAgIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorCisgICAgVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICAgIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAgICBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAgICB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKworICAgIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorCistLT4KKworPFRJVExFPmNvbS5zdW4ubWFpbC5oYW5kbGVycyBwYWNrYWdlPC9USVRMRT4KKzwvSEVBRD4KKzxCT0RZIEJHQ09MT1I9IndoaXRlIj4KKworPFA+CitUaGlzIHBhY2thZ2UgaW5jbHVkZXMgaW50ZXJuYWwgZGF0YSBoYW5kbGVyIHN1cHBvcnQgY2xhc3NlcyBhbmQKKzxzdHJvbmc+U0hPVUxEIE5PVCBCRSBVU0VEIERJUkVDVExZIEJZIEFQUExJQ0FUSU9OUzwvc3Ryb25nPi4KKzwvUD4KKworPC9CT0RZPgorPC9IVE1MPgpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9oYW5kbGVycy90ZXh0X2h0bWwuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaGFuZGxlcnMvdGV4dF9odG1sLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjRlZjA1OAotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaGFuZGxlcnMvdGV4dF9odG1sLmphdmEKQEAgLTAsMCArMSwzNCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuaGFuZGxlcnM7CisKK2ltcG9ydCBqYXZheC5hY3RpdmF0aW9uLkFjdGl2YXRpb25EYXRhRmxhdm9yOworCisvKioKKyAqIERhdGFDb250ZW50SGFuZGxlciBmb3IgdGV4dC9odG1sLgorICoKKyAqLworcHVibGljIGNsYXNzIHRleHRfaHRtbCBleHRlbmRzIHRleHRfcGxhaW4geworICAgIHByaXZhdGUgc3RhdGljIEFjdGl2YXRpb25EYXRhRmxhdm9yW10gbXlERiA9IHsKKwluZXcgQWN0aXZhdGlvbkRhdGFGbGF2b3IoU3RyaW5nLmNsYXNzLCAidGV4dC9odG1sIiwgIkhUTUwgU3RyaW5nIikKKyAgICB9OworCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIEFjdGl2YXRpb25EYXRhRmxhdm9yW10gZ2V0RGF0YUZsYXZvcnMoKSB7CisJcmV0dXJuIG15REY7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9oYW5kbGVycy90ZXh0X3BsYWluLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2hhbmRsZXJzL3RleHRfcGxhaW4uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kYTBiZWFiCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9oYW5kbGVycy90ZXh0X3BsYWluLmphdmEKQEAgLTAsMCArMSwxNTMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmhhbmRsZXJzOworCitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmF4LmFjdGl2YXRpb24uKjsKK2ltcG9ydCBqYXZheC5tYWlsLmludGVybmV0LkNvbnRlbnRUeXBlOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuTWltZVV0aWxpdHk7CisKKy8qKgorICogRGF0YUNvbnRlbnRIYW5kbGVyIGZvciB0ZXh0L3BsYWluLgorICoKKyAqLworcHVibGljIGNsYXNzIHRleHRfcGxhaW4gZXh0ZW5kcyBoYW5kbGVyX2Jhc2UgeworICAgIHByaXZhdGUgc3RhdGljIEFjdGl2YXRpb25EYXRhRmxhdm9yW10gbXlERiA9IHsKKwluZXcgQWN0aXZhdGlvbkRhdGFGbGF2b3IoU3RyaW5nLmNsYXNzLCAidGV4dC9wbGFpbiIsICJUZXh0IFN0cmluZyIpCisgICAgfTsKKworICAgIC8qKgorICAgICAqIEFuIE91cHV0U3RyZWFtIHdyYXBwZXIgdGhhdCBkb2Vzbid0IGNsb3NlIHRoZSB1bmRlcmx5aW5nIHN0cmVhbS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBOb0Nsb3NlT3V0cHV0U3RyZWFtIGV4dGVuZHMgRmlsdGVyT3V0cHV0U3RyZWFtIHsKKwlwdWJsaWMgTm9DbG9zZU91dHB1dFN0cmVhbShPdXRwdXRTdHJlYW0gb3MpIHsKKwkgICAgc3VwZXIob3MpOworCX0KKworCUBPdmVycmlkZQorCXB1YmxpYyB2b2lkIGNsb3NlKCkgeworCSAgICAvLyBkbyBub3RoaW5nCisJfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBBY3RpdmF0aW9uRGF0YUZsYXZvcltdIGdldERhdGFGbGF2b3JzKCkgeworCXJldHVybiBteURGOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgZ2V0Q29udGVudChEYXRhU291cmNlIGRzKSB0aHJvd3MgSU9FeGNlcHRpb24geworCVN0cmluZyBlbmMgPSBudWxsOworCUlucHV0U3RyZWFtUmVhZGVyIGlzID0gbnVsbDsKKwkKKwl0cnkgeworCSAgICBlbmMgPSBnZXRDaGFyc2V0KGRzLmdldENvbnRlbnRUeXBlKCkpOworCSAgICBpcyA9IG5ldyBJbnB1dFN0cmVhbVJlYWRlcihkcy5nZXRJbnB1dFN0cmVhbSgpLCBlbmMpOworCX0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZXgpIHsKKwkgICAgLyoKKwkgICAgICogQW4gdW5rbm93biBjaGFyc2V0IG9mIHRoZSBmb3JtIElTTy1YWFgtWFhYIHdpbGwgY2F1c2UKKwkgICAgICogdGhlIEpESyB0byB0aHJvdyBhbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uICBUaGUKKwkgICAgICogSkRLIHdpbGwgYXR0ZW1wdCB0byBjcmVhdGUgYSBjbGFzc25hbWUgdXNpbmcgdGhpcyBzdHJpbmcsCisJICAgICAqIGJ1dCB2YWxpZCBjbGFzc25hbWVzIG11c3Qgbm90IGNvbnRhaW4gdGhlIGNoYXJhY3RlciAnLScsCisJICAgICAqIGFuZCB0aGlzIHJlc3VsdHMgaW4gYW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCByYXRoZXIgdGhhbgorCSAgICAgKiB0aGUgZXhwZWN0ZWQgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbi4gIFlpa2VzLgorCSAgICAgKi8KKwkgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24oZW5jKTsKKwl9CisKKwl0cnkgeworCSAgICBpbnQgcG9zID0gMDsKKwkgICAgaW50IGNvdW50OworCSAgICBjaGFyIGJ1ZltdID0gbmV3IGNoYXJbMTAyNF07CisKKwkgICAgd2hpbGUgKChjb3VudCA9IGlzLnJlYWQoYnVmLCBwb3MsIGJ1Zi5sZW5ndGggLSBwb3MpKSAhPSAtMSkgeworCQlwb3MgKz0gY291bnQ7CisJCWlmIChwb3MgPj0gYnVmLmxlbmd0aCkgeworCQkgICAgaW50IHNpemUgPSBidWYubGVuZ3RoOworCQkgICAgaWYgKHNpemUgPCAyNTYqMTAyNCkKKwkJCXNpemUgKz0gc2l6ZTsKKwkJICAgIGVsc2UKKwkJCXNpemUgKz0gMjU2KjEwMjQ7CisJCSAgICBjaGFyIHRidWZbXSA9IG5ldyBjaGFyW3NpemVdOworCQkgICAgU3lzdGVtLmFycmF5Y29weShidWYsIDAsIHRidWYsIDAsIHBvcyk7CisJCSAgICBidWYgPSB0YnVmOworCQl9CisJICAgIH0KKwkgICAgcmV0dXJuIG5ldyBTdHJpbmcoYnVmLCAwLCBwb3MpOworCX0gZmluYWxseSB7CisJICAgIHRyeSB7CisJCWlzLmNsb3NlKCk7CisJICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisJCS8vIGlnbm9yZSBpdAorCSAgICB9CisJfQorICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiBXcml0ZSB0aGUgb2JqZWN0IHRvIHRoZSBvdXRwdXQgc3RyZWFtLCB1c2luZyB0aGUgc3BlY2lmaWVkIE1JTUUgdHlwZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKE9iamVjdCBvYmosIFN0cmluZyB0eXBlLCBPdXRwdXRTdHJlYW0gb3MpIAorCQkJdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlpZiAoIShvYmogaW5zdGFuY2VvZiBTdHJpbmcpKQorCSAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlwiIiArIGdldERhdGFGbGF2b3JzKClbMF0uZ2V0TWltZVR5cGUoKSArCisJCSJcIiBEYXRhQ29udGVudEhhbmRsZXIgcmVxdWlyZXMgU3RyaW5nIG9iamVjdCwgIiArCisJCSJ3YXMgZ2l2ZW4gb2JqZWN0IG9mIHR5cGUgIiArIG9iai5nZXRDbGFzcygpLnRvU3RyaW5nKCkpOworCisJU3RyaW5nIGVuYyA9IG51bGw7CisJT3V0cHV0U3RyZWFtV3JpdGVyIG9zdyA9IG51bGw7CisKKwl0cnkgeworCSAgICBlbmMgPSBnZXRDaGFyc2V0KHR5cGUpOworCSAgICBvc3cgPSBuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKG5ldyBOb0Nsb3NlT3V0cHV0U3RyZWFtKG9zKSwgZW5jKTsKKwl9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWV4KSB7CisJICAgIC8qCisJICAgICAqIEFuIHVua25vd24gY2hhcnNldCBvZiB0aGUgZm9ybSBJU08tWFhYLVhYWCB3aWxsIGNhdXNlCisJICAgICAqIHRoZSBKREsgdG8gdGhyb3cgYW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLiAgVGhlCisJICAgICAqIEpESyB3aWxsIGF0dGVtcHQgdG8gY3JlYXRlIGEgY2xhc3NuYW1lIHVzaW5nIHRoaXMgc3RyaW5nLAorCSAgICAgKiBidXQgdmFsaWQgY2xhc3NuYW1lcyBtdXN0IG5vdCBjb250YWluIHRoZSBjaGFyYWN0ZXIgJy0nLAorCSAgICAgKiBhbmQgdGhpcyByZXN1bHRzIGluIGFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwgcmF0aGVyIHRoYW4KKwkgICAgICogdGhlIGV4cGVjdGVkIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24uICBZaWtlcy4KKwkgICAgICovCisJICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uKGVuYyk7CisJfQorCisJU3RyaW5nIHMgPSAoU3RyaW5nKW9iajsKKwlvc3cud3JpdGUocywgMCwgcy5sZW5ndGgoKSk7CisJLyoKKwkgKiBIYXZlIHRvIGNhbGwgb3N3LmNsb3NlKCkgaW5zdGVhZCBvZiBvc3cuZmx1c2goKSBiZWNhdXNlCisJICogc29tZSBjaGFyc2V0IGNvbnZlcnRzLCBzdWNoIGFzIHRoZSBpc28tMjAyMi1qcCBjb252ZXJ0ZXIsCisJICogZG9uJ3Qgb3V0cHV0IHRoZSAic2hpZnQgb3V0IiBzZXF1ZW5jZSB1bmxlc3MgdGhleSdyZSBjbG9zZWQuCisJICogVGhlIE5vQ2xvc2VPdXRwdXRTdHJlYW0gd3JhcHBlciBwcmV2ZW50cyB0aGUgdW5kZXJseWluZworCSAqIHN0cmVhbSBmcm9tIGJlaW5nIGNsb3NlZC4KKwkgKi8KKwlvc3cuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFN0cmluZyBnZXRDaGFyc2V0KFN0cmluZyB0eXBlKSB7CisJdHJ5IHsKKwkgICAgQ29udGVudFR5cGUgY3QgPSBuZXcgQ29udGVudFR5cGUodHlwZSk7CisJICAgIFN0cmluZyBjaGFyc2V0ID0gY3QuZ2V0UGFyYW1ldGVyKCJjaGFyc2V0Iik7CisJICAgIGlmIChjaGFyc2V0ID09IG51bGwpCisJCS8vIElmIHRoZSBjaGFyc2V0IHBhcmFtZXRlciBpcyBhYnNlbnQsIHVzZSBVUy1BU0NJSS4KKwkJY2hhcnNldCA9ICJ1cy1hc2NpaSI7CisJICAgIHJldHVybiBNaW1lVXRpbGl0eS5qYXZhQ2hhcnNldChjaGFyc2V0KTsKKwl9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKwkgICAgcmV0dXJuIG51bGw7CisJfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaGFuZGxlcnMvdGV4dF94bWwuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaGFuZGxlcnMvdGV4dF94bWwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZjAzMDE3Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9oYW5kbGVycy90ZXh0X3htbC5qYXZhCkBAIC0wLDAgKzEsMTIxIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5oYW5kbGVyczsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CisKK2ltcG9ydCBqYXZheC5hY3RpdmF0aW9uLkFjdGl2YXRpb25EYXRhRmxhdm9yOworaW1wb3J0IGphdmF4LmFjdGl2YXRpb24uRGF0YVNvdXJjZTsKK2ltcG9ydCBqYXZheC5tYWlsLmludGVybmV0LkNvbnRlbnRUeXBlOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuUGFyc2VFeGNlcHRpb247CitpbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5Tb3VyY2U7CitpbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lcjsKK2ltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRmFjdG9yeTsKK2ltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLlRyYW5zZm9ybWVyRXhjZXB0aW9uOworaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLlN0cmVhbVJlc3VsdDsKK2ltcG9ydCBqYXZheC54bWwudHJhbnNmb3JtLnN0cmVhbS5TdHJlYW1Tb3VyY2U7CisKKy8qKgorICogRGF0YUNvbnRlbnRIYW5kbGVyIGZvciB0ZXh0L3htbC4KKyAqCisgKiBAYXV0aG9yIEFuaWwgVmlqZW5kcmFuCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCitwdWJsaWMgY2xhc3MgdGV4dF94bWwgZXh0ZW5kcyB0ZXh0X3BsYWluIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEFjdGl2YXRpb25EYXRhRmxhdm9yW10gZmxhdm9ycyA9IHsKKwluZXcgQWN0aXZhdGlvbkRhdGFGbGF2b3IoU3RyaW5nLmNsYXNzLCAidGV4dC94bWwiLCAiWE1MIFN0cmluZyIpLAorCW5ldyBBY3RpdmF0aW9uRGF0YUZsYXZvcihTdHJpbmcuY2xhc3MsICJhcHBsaWNhdGlvbi94bWwiLCAiWE1MIFN0cmluZyIpLAorCW5ldyBBY3RpdmF0aW9uRGF0YUZsYXZvcihTdHJlYW1Tb3VyY2UuY2xhc3MsICJ0ZXh0L3htbCIsICJYTUwiKSwKKwluZXcgQWN0aXZhdGlvbkRhdGFGbGF2b3IoU3RyZWFtU291cmNlLmNsYXNzLCAiYXBwbGljYXRpb24veG1sIiwgIlhNTCIpCisgICAgfTsKKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBBY3RpdmF0aW9uRGF0YUZsYXZvcltdIGdldERhdGFGbGF2b3JzKCkgeworCXJldHVybiBmbGF2b3JzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBPYmplY3QgZ2V0RGF0YShBY3RpdmF0aW9uRGF0YUZsYXZvciBhRmxhdm9yLCBEYXRhU291cmNlIGRzKQorCQkJCXRocm93cyBJT0V4Y2VwdGlvbiB7CisJaWYgKGFGbGF2b3IuZ2V0UmVwcmVzZW50YXRpb25DbGFzcygpID09IFN0cmluZy5jbGFzcykKKwkgICAgcmV0dXJuIHN1cGVyLmdldENvbnRlbnQoZHMpOworCWVsc2UgaWYgKGFGbGF2b3IuZ2V0UmVwcmVzZW50YXRpb25DbGFzcygpID09IFN0cmVhbVNvdXJjZS5jbGFzcykKKwkgICAgcmV0dXJuIG5ldyBTdHJlYW1Tb3VyY2UoZHMuZ2V0SW5wdXRTdHJlYW0oKSk7CisJZWxzZQorCSAgICByZXR1cm4gbnVsbDsgICAgICAgIC8vIFhYWCAtIHNob3VsZCBuZXZlciBoYXBwZW4KKyAgICB9CisKKyAgICAvKioKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKE9iamVjdCBvYmosIFN0cmluZyBtaW1lVHlwZSwgT3V0cHV0U3RyZWFtIG9zKQorCQkJCSAgICB0aHJvd3MgSU9FeGNlcHRpb24geworCWlmICghaXNYbWxUeXBlKG1pbWVUeXBlKSkKKwkgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKAorCQkiSW52YWxpZCBjb250ZW50IHR5cGUgXCIiICsgbWltZVR5cGUgKyAiXCIgZm9yIHRleHQveG1sIERDSCIpOworCWlmIChvYmogaW5zdGFuY2VvZiBTdHJpbmcpIHsKKwkgICAgc3VwZXIud3JpdGVUbyhvYmosIG1pbWVUeXBlLCBvcyk7CisJICAgIHJldHVybjsKKwl9CisJaWYgKCEob2JqIGluc3RhbmNlb2YgRGF0YVNvdXJjZSB8fCBvYmogaW5zdGFuY2VvZiBTb3VyY2UpKSB7CisJICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkludmFsaWQgT2JqZWN0IHR5cGUgPSAiK29iai5nZXRDbGFzcygpKworCQkiLiBYbWxEQ0ggY2FuIG9ubHkgY29udmVydCBEYXRhU291cmNlIG9yIFNvdXJjZSB0byBYTUwuIik7CisJfQorCisJdHJ5IHsKKwkgICAgVHJhbnNmb3JtZXIgdHJhbnNmb3JtZXIgPQorCQlUcmFuc2Zvcm1lckZhY3RvcnkubmV3SW5zdGFuY2UoKS5uZXdUcmFuc2Zvcm1lcigpOworCSAgICBTdHJlYW1SZXN1bHQgcmVzdWx0ID0gbmV3IFN0cmVhbVJlc3VsdChvcyk7CisJICAgIGlmIChvYmogaW5zdGFuY2VvZiBEYXRhU291cmNlKSB7CisJCS8vIFN0cmVhbWluZyB0cmFuc2Zvcm0gYXBwbGllcyBvbmx5IHRvCisJCS8vIGphdmF4LnhtbC50cmFuc2Zvcm0uU3RyZWFtU291cmNlCisJCXRyYW5zZm9ybWVyLnRyYW5zZm9ybSgKKwkJICAgIG5ldyBTdHJlYW1Tb3VyY2UoKChEYXRhU291cmNlKW9iaikuZ2V0SW5wdXRTdHJlYW0oKSksCisJCSAgICByZXN1bHQpOworCSAgICB9IGVsc2UgeworCQl0cmFuc2Zvcm1lci50cmFuc2Zvcm0oKFNvdXJjZSlvYmosIHJlc3VsdCk7CisJICAgIH0KKwl9IGNhdGNoIChUcmFuc2Zvcm1lckV4Y2VwdGlvbiBleCkgeworCSAgICBJT0V4Y2VwdGlvbiBpb2V4ID0gbmV3IElPRXhjZXB0aW9uKAorCQkiVW5hYmxlIHRvIHJ1biB0aGUgSkFYUCB0cmFuc2Zvcm1lciBvbiBhIHN0cmVhbSAiCisJCSAgICArIGV4LmdldE1lc3NhZ2UoKSk7CisJICAgIGlvZXguaW5pdENhdXNlKGV4KTsKKwkgICAgdGhyb3cgaW9leDsKKwl9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGV4KSB7CisJICAgIElPRXhjZXB0aW9uIGlvZXggPSBuZXcgSU9FeGNlcHRpb24oCisJCSJVbmFibGUgdG8gcnVuIHRoZSBKQVhQIHRyYW5zZm9ybWVyIG9uIGEgc3RyZWFtICIKKwkJICAgICsgZXguZ2V0TWVzc2FnZSgpKTsKKwkgICAgaW9leC5pbml0Q2F1c2UoZXgpOworCSAgICB0aHJvdyBpb2V4OworCX0KKyAgICB9CisKKyAgICBwcml2YXRlIGJvb2xlYW4gaXNYbWxUeXBlKFN0cmluZyB0eXBlKSB7CisJdHJ5IHsKKwkgICAgQ29udGVudFR5cGUgY3QgPSBuZXcgQ29udGVudFR5cGUodHlwZSk7CisJICAgIHJldHVybiBjdC5nZXRTdWJUeXBlKCkuZXF1YWxzKCJ4bWwiKSAmJgorCQkgICAgKGN0LmdldFByaW1hcnlUeXBlKCkuZXF1YWxzKCJ0ZXh0IikgfHwKKwkJICAgIGN0LmdldFByaW1hcnlUeXBlKCkuZXF1YWxzKCJhcHBsaWNhdGlvbiIpKTsKKwl9IGNhdGNoIChQYXJzZUV4Y2VwdGlvbiBleCkgeworCSAgICByZXR1cm4gZmFsc2U7CisJfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBleCkgeworCSAgICByZXR1cm4gZmFsc2U7CisJfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaWFwL0FyZ3VtZW50LmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2lhcC9Bcmd1bWVudC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY3N2M2M2QKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2lhcC9Bcmd1bWVudC5qYXZhCkBAIC0wLDAgKzEsNDMxIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5pYXA7CisKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXQ7CisKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5BU0NJSVV0aWxpdHk7CisKKy8qKgorICogQGF1dGhvciAgSm9obiBNYW5pCisgKiBAYXV0aG9yICBCaWxsIFNoYW5ub24KKyAqLworCitwdWJsaWMgY2xhc3MgQXJndW1lbnQgeworICAgIHByb3RlY3RlZCBMaXN0PE9iamVjdD4gaXRlbXM7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvcgorICAgICAqLworICAgIHB1YmxpYyBBcmd1bWVudCgpIHsKKwlpdGVtcyA9IG5ldyBBcnJheUxpc3Q8PigxKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBcHBlbmQgdGhlIGdpdmVuIEFyZ3VtZW50IHRvIHRoaXMgQXJndW1lbnQuIEFsbCBpdGVtcworICAgICAqIGZyb20gdGhlIHNvdXJjZSBhcmd1bWVudCBhcmUgY29waWVkIGludG8gdGhpcyBkZXN0aW5hdGlvbgorICAgICAqIGFyZ3VtZW50LgorICAgICAqCisgICAgICogQHBhcmFtCWFyZwl0aGUgQXJndW1lbnQgdG8gYXBwZW5kCisgICAgICogQHJldHVybgkJdGhpcworICAgICAqLworICAgIHB1YmxpYyBBcmd1bWVudCBhcHBlbmQoQXJndW1lbnQgYXJnKSB7CisJaXRlbXMuYWRkQWxsKGFyZy5pdGVtcyk7CisJcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGUgb3V0IGdpdmVuIHN0cmluZyBhcyBhbiBBU1RSSU5HLCBkZXBlbmRpbmcgb24gdGhlIHR5cGUKKyAgICAgKiBvZiB0aGUgY2hhcmFjdGVycyBpbnNpZGUgdGhlIHN0cmluZy4gVGhlIHN0cmluZyBzaG91bGQKKyAgICAgKiBjb250YWluIG9ubHkgQVNDSUkgY2hhcmFjdGVycy4gPHA+CisgICAgICoKKyAgICAgKiBYWFg6IEhtbSAuLiB0aGlzIHNob3VsZCByZWFsbHkgYmUgY2FsbGVkIHdyaXRlQVNDSUkoKQorICAgICAqCisgICAgICogQHBhcmFtCXMJU3RyaW5nIHRvIHdyaXRlIG91dAorICAgICAqIEByZXR1cm4JCXRoaXMKKyAgICAgKi8KKyAgICBwdWJsaWMgQXJndW1lbnQgd3JpdGVTdHJpbmcoU3RyaW5nIHMpIHsKKwlpdGVtcy5hZGQobmV3IEFTdHJpbmcoQVNDSUlVdGlsaXR5LmdldEJ5dGVzKHMpKSk7CisJcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydCB0aGUgZ2l2ZW4gc3RyaW5nIGludG8gYnl0ZXMgaW4gdGhlIHNwZWNpZmllZAorICAgICAqIGNoYXJzZXQsIGFuZCB3cml0ZSB0aGUgYnl0ZXMgb3V0IGFzIGFuIEFTVFJJTkcKKyAgICAgKgorICAgICAqIEBwYXJhbQlzCVN0cmluZyB0byB3cml0ZSBvdXQKKyAgICAgKiBAcGFyYW0JY2hhcnNldAl0aGUgY2hhcnNldAorICAgICAqIEByZXR1cm4JCXRoaXMKKyAgICAgKiBAZXhjZXB0aW9uCVVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24JZm9yIGJhZCBjaGFyc2V0CisgICAgICovCisgICAgcHVibGljIEFyZ3VtZW50IHdyaXRlU3RyaW5nKFN0cmluZyBzLCBTdHJpbmcgY2hhcnNldCkKKwkJdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24geworCWlmIChjaGFyc2V0ID09IG51bGwpIC8vIGNvbnZlbmllbmNlCisJICAgIHdyaXRlU3RyaW5nKHMpOworCWVsc2UKKwkgICAgaXRlbXMuYWRkKG5ldyBBU3RyaW5nKHMuZ2V0Qnl0ZXMoY2hhcnNldCkpKTsKKwlyZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0IHRoZSBnaXZlbiBzdHJpbmcgaW50byBieXRlcyBpbiB0aGUgc3BlY2lmaWVkCisgICAgICogY2hhcnNldCwgYW5kIHdyaXRlIHRoZSBieXRlcyBvdXQgYXMgYW4gQVNUUklORworICAgICAqCisgICAgICogQHBhcmFtCXMJU3RyaW5nIHRvIHdyaXRlIG91dAorICAgICAqIEBwYXJhbQljaGFyc2V0CXRoZSBjaGFyc2V0CisgICAgICogQHJldHVybgkJdGhpcworICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjYuMAorICAgICAqLworICAgIHB1YmxpYyBBcmd1bWVudCB3cml0ZVN0cmluZyhTdHJpbmcgcywgQ2hhcnNldCBjaGFyc2V0KSB7CisJaWYgKGNoYXJzZXQgPT0gbnVsbCkgLy8gY29udmVuaWVuY2UKKwkgICAgd3JpdGVTdHJpbmcocyk7CisJZWxzZQorCSAgICBpdGVtcy5hZGQobmV3IEFTdHJpbmcocy5nZXRCeXRlcyhjaGFyc2V0KSkpOworCXJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlIG91dCBnaXZlbiBzdHJpbmcgYXMgYW4gTlNUUklORywgZGVwZW5kaW5nIG9uIHRoZSB0eXBlCisgICAgICogb2YgdGhlIGNoYXJhY3RlcnMgaW5zaWRlIHRoZSBzdHJpbmcuIFRoZSBzdHJpbmcgc2hvdWxkCisgICAgICogY29udGFpbiBvbmx5IEFTQ0lJIGNoYXJhY3RlcnMuIDxwPgorICAgICAqCisgICAgICogQHBhcmFtCXMJU3RyaW5nIHRvIHdyaXRlIG91dAorICAgICAqIEByZXR1cm4JCXRoaXMKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS41LjEKKyAgICAgKi8KKyAgICBwdWJsaWMgQXJndW1lbnQgd3JpdGVOU3RyaW5nKFN0cmluZyBzKSB7CisJaWYgKHMgPT0gbnVsbCkKKwkgICAgaXRlbXMuYWRkKG5ldyBOU3RyaW5nKG51bGwpKTsKKwllbHNlCisJICAgIGl0ZW1zLmFkZChuZXcgTlN0cmluZyhBU0NJSVV0aWxpdHkuZ2V0Qnl0ZXMocykpKTsKKwlyZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0IHRoZSBnaXZlbiBzdHJpbmcgaW50byBieXRlcyBpbiB0aGUgc3BlY2lmaWVkCisgICAgICogY2hhcnNldCwgYW5kIHdyaXRlIHRoZSBieXRlcyBvdXQgYXMgYW4gTlNUUklORworICAgICAqCisgICAgICogQHBhcmFtCXMJU3RyaW5nIHRvIHdyaXRlIG91dAorICAgICAqIEBwYXJhbQljaGFyc2V0CXRoZSBjaGFyc2V0CisgICAgICogQHJldHVybgkJdGhpcworICAgICAqIEBleGNlcHRpb24JVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbglmb3IgYmFkIGNoYXJzZXQKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS41LjEKKyAgICAgKi8KKyAgICBwdWJsaWMgQXJndW1lbnQgd3JpdGVOU3RyaW5nKFN0cmluZyBzLCBTdHJpbmcgY2hhcnNldCkKKwkJdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24geworCWlmIChzID09IG51bGwpCisJICAgIGl0ZW1zLmFkZChuZXcgTlN0cmluZyhudWxsKSk7CisJZWxzZSBpZiAoY2hhcnNldCA9PSBudWxsKSAvLyBjb252ZW5pZW5jZQorCSAgICB3cml0ZVN0cmluZyhzKTsKKwllbHNlCisJICAgIGl0ZW1zLmFkZChuZXcgTlN0cmluZyhzLmdldEJ5dGVzKGNoYXJzZXQpKSk7CisJcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydCB0aGUgZ2l2ZW4gc3RyaW5nIGludG8gYnl0ZXMgaW4gdGhlIHNwZWNpZmllZAorICAgICAqIGNoYXJzZXQsIGFuZCB3cml0ZSB0aGUgYnl0ZXMgb3V0IGFzIGFuIE5TVFJJTkcKKyAgICAgKgorICAgICAqIEBwYXJhbQlzCVN0cmluZyB0byB3cml0ZSBvdXQKKyAgICAgKiBAcGFyYW0JY2hhcnNldAl0aGUgY2hhcnNldAorICAgICAqIEByZXR1cm4JCXRoaXMKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS42LjAKKyAgICAgKi8KKyAgICBwdWJsaWMgQXJndW1lbnQgd3JpdGVOU3RyaW5nKFN0cmluZyBzLCBDaGFyc2V0IGNoYXJzZXQpIHsKKwlpZiAocyA9PSBudWxsKQorCSAgICBpdGVtcy5hZGQobmV3IE5TdHJpbmcobnVsbCkpOworCWVsc2UgaWYgKGNoYXJzZXQgPT0gbnVsbCkgLy8gY29udmVuaWVuY2UKKwkgICAgd3JpdGVTdHJpbmcocyk7CisJZWxzZQorCSAgICBpdGVtcy5hZGQobmV3IE5TdHJpbmcocy5nZXRCeXRlcyhjaGFyc2V0KSkpOworCXJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlIG91dCBnaXZlbiBieXRlW10gYXMgYSBMaXRlcmFsLgorICAgICAqIEBwYXJhbSBiICBieXRlW10gdG8gd3JpdGUgb3V0CisgICAgICogQHJldHVybgl0aGlzCisgICAgICovCisgICAgcHVibGljIEFyZ3VtZW50IHdyaXRlQnl0ZXMoYnl0ZVtdIGIpICB7CisJaXRlbXMuYWRkKGIpOworCXJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlIG91dCBnaXZlbiBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYXMgYSBMaXRlcmFsLgorICAgICAqIEBwYXJhbSBiICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gdG8gYmUgd3JpdHRlbiBvdXQuCisgICAgICogQHJldHVybgl0aGlzCisgICAgICovCisgICAgcHVibGljIEFyZ3VtZW50IHdyaXRlQnl0ZXMoQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGIpICB7CisJaXRlbXMuYWRkKGIpOworCXJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlIG91dCBnaXZlbiBkYXRhIGFzIGEgbGl0ZXJhbC4KKyAgICAgKiBAcGFyYW0gYiAgTGl0ZXJhbCByZXByZXNlbnRpbmcgZGF0YSB0byBiZSB3cml0dGVuIG91dC4KKyAgICAgKiBAcmV0dXJuCXRoaXMKKyAgICAgKi8KKyAgICBwdWJsaWMgQXJndW1lbnQgd3JpdGVCeXRlcyhMaXRlcmFsIGIpICB7CisJaXRlbXMuYWRkKGIpOworCXJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlIG91dCBnaXZlbiBzdHJpbmcgYXMgYW4gQXRvbS4gTm90ZSB0aGF0IGFuIEF0b20gY2FuIGNvbnRhaW4gb25seQorICAgICAqIGNlcnRhaW4gVVMtQVNDSUkgY2hhcmFjdGVycy4gIE5vIHZhbGlkYXRpb24gaXMgZG9uZSBvbiB0aGUgY2hhcmFjdGVycyAKKyAgICAgKiBpbiB0aGUgc3RyaW5nLgorICAgICAqIEBwYXJhbSBzICBTdHJpbmcKKyAgICAgKiBAcmV0dXJuCXRoaXMKKyAgICAgKi8KKyAgICBwdWJsaWMgQXJndW1lbnQgd3JpdGVBdG9tKFN0cmluZyBzKSB7CisJaXRlbXMuYWRkKG5ldyBBdG9tKHMpKTsKKwlyZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZSBvdXQgbnVtYmVyLgorICAgICAqIEBwYXJhbSBpIG51bWJlcgorICAgICAqIEByZXR1cm4JdGhpcworICAgICAqLworICAgIHB1YmxpYyBBcmd1bWVudCB3cml0ZU51bWJlcihpbnQgaSkgeworCWl0ZW1zLmFkZChJbnRlZ2VyLnZhbHVlT2YoaSkpOworCXJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlIG91dCBudW1iZXIuCisgICAgICogQHBhcmFtIGkgbnVtYmVyCisgICAgICogQHJldHVybgl0aGlzCisgICAgICovCisgICAgcHVibGljIEFyZ3VtZW50IHdyaXRlTnVtYmVyKGxvbmcgaSkgeworCWl0ZW1zLmFkZChMb25nLnZhbHVlT2YoaSkpOworCXJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlIG91dCBhcyBwYXJlbnRoZXNpc2VkIGxpc3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0JYwl0aGUgQXJndW1lbnQKKyAgICAgKiBAcmV0dXJuCXRoaXMKKyAgICAgKi8KKyAgICBwdWJsaWMgQXJndW1lbnQgd3JpdGVBcmd1bWVudChBcmd1bWVudCBjKSB7CisJaXRlbXMuYWRkKGMpOworCXJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qCisgICAgICogV3JpdGUgb3V0IGFsbCB0aGUgYnVmZmVyZWQgaXRlbXMgaW50byB0aGUgb3V0cHV0IHN0cmVhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB3cml0ZShQcm90b2NvbCBwcm90b2NvbCkgCisJCXRocm93cyBJT0V4Y2VwdGlvbiwgUHJvdG9jb2xFeGNlcHRpb24geworCWludCBzaXplID0gaXRlbXMgIT0gbnVsbCA/IGl0ZW1zLnNpemUoKSA6IDA7CisJRGF0YU91dHB1dFN0cmVhbSBvcyA9IChEYXRhT3V0cHV0U3RyZWFtKXByb3RvY29sLmdldE91dHB1dFN0cmVhbSgpOworCisJZm9yIChpbnQgaT0wOyBpIDwgc2l6ZTsgaSsrKSB7CisJICAgIGlmIChpID4gMCkJLy8gd3JpdGUgZGVsaW1pdGVyIGlmIG5vdCB0aGUgZmlyc3QgaXRlbQorCQlvcy53cml0ZSgnICcpOworCisJICAgIE9iamVjdCBvID0gaXRlbXMuZ2V0KGkpOworCSAgICBpZiAobyBpbnN0YW5jZW9mIEF0b20pIHsKKwkJb3Mud3JpdGVCeXRlcygoKEF0b20pbykuc3RyaW5nKTsKKwkgICAgfSBlbHNlIGlmIChvIGluc3RhbmNlb2YgTnVtYmVyKSB7CisJCW9zLndyaXRlQnl0ZXMoKChOdW1iZXIpbykudG9TdHJpbmcoKSk7CisJICAgIH0gZWxzZSBpZiAobyBpbnN0YW5jZW9mIEFTdHJpbmcpIHsKKwkJYXN0cmluZygoKEFTdHJpbmcpbykuYnl0ZXMsIHByb3RvY29sKTsKKwkgICAgfSBlbHNlIGlmIChvIGluc3RhbmNlb2YgTlN0cmluZykgeworCQluc3RyaW5nKCgoTlN0cmluZylvKS5ieXRlcywgcHJvdG9jb2wpOworCSAgICB9IGVsc2UgaWYgKG8gaW5zdGFuY2VvZiBieXRlW10pIHsKKwkJbGl0ZXJhbCgoYnl0ZVtdKW8sIHByb3RvY29sKTsKKwkgICAgfSBlbHNlIGlmIChvIGluc3RhbmNlb2YgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKSB7CisJCWxpdGVyYWwoKEJ5dGVBcnJheU91dHB1dFN0cmVhbSlvLCBwcm90b2NvbCk7CisJICAgIH0gZWxzZSBpZiAobyBpbnN0YW5jZW9mIExpdGVyYWwpIHsKKwkJbGl0ZXJhbCgoTGl0ZXJhbClvLCBwcm90b2NvbCk7CisJICAgIH0gZWxzZSBpZiAobyBpbnN0YW5jZW9mIEFyZ3VtZW50KSB7CisJCW9zLndyaXRlKCcoJyk7IC8vIG9wZW4gcGFyYW5zCisJCSgoQXJndW1lbnQpbykud3JpdGUocHJvdG9jb2wpOworCQlvcy53cml0ZSgnKScpOyAvLyBjbG9zZSBwYXJhbnMKKwkgICAgfQorCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZSBvdXQgZ2l2ZW4gU3RyaW5nIGFzIGVpdGhlciBhbiBBdG9tLCBRdW90ZWRTdHJpbmcgb3IgTGl0ZXJhbAorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBhc3RyaW5nKGJ5dGVbXSBieXRlcywgUHJvdG9jb2wgcHJvdG9jb2wpIAorCQkJdGhyb3dzIElPRXhjZXB0aW9uLCBQcm90b2NvbEV4Y2VwdGlvbiB7CisJbmFzdHJpbmcoYnl0ZXMsIHByb3RvY29sLCBmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGUgb3V0IGdpdmVuIFN0cmluZyBhcyBlaXRoZXIgTklMLCBRdW90ZWRTdHJpbmcsIG9yIExpdGVyYWwuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIG5zdHJpbmcoYnl0ZVtdIGJ5dGVzLCBQcm90b2NvbCBwcm90b2NvbCkgCisJCQl0aHJvd3MgSU9FeGNlcHRpb24sIFByb3RvY29sRXhjZXB0aW9uIHsKKwlpZiAoYnl0ZXMgPT0gbnVsbCkgeworCSAgICBEYXRhT3V0cHV0U3RyZWFtIG9zID0gKERhdGFPdXRwdXRTdHJlYW0pcHJvdG9jb2wuZ2V0T3V0cHV0U3RyZWFtKCk7CisJICAgIG9zLndyaXRlQnl0ZXMoIk5JTCIpOworCX0gZWxzZQorCSAgICBuYXN0cmluZyhieXRlcywgcHJvdG9jb2wsIHRydWUpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBuYXN0cmluZyhieXRlW10gYnl0ZXMsIFByb3RvY29sIHByb3RvY29sLCBib29sZWFuIGRvUXVvdGUpIAorCQkJdGhyb3dzIElPRXhjZXB0aW9uLCBQcm90b2NvbEV4Y2VwdGlvbiB7CisJRGF0YU91dHB1dFN0cmVhbSBvcyA9IChEYXRhT3V0cHV0U3RyZWFtKXByb3RvY29sLmdldE91dHB1dFN0cmVhbSgpOworCWludCBsZW4gPSBieXRlcy5sZW5ndGg7CisKKwkvLyBJZiBsZW5ndGggaXMgZ3JlYXRlciB0aGFuIDEwMjQgYnl0ZXMsIHNlbmQgYXMgbGl0ZXJhbAorCWlmIChsZW4gPiAxMDI0KSB7CisJICAgIGxpdGVyYWwoYnl0ZXMsIHByb3RvY29sKTsKKwkgICAgcmV0dXJuOworCX0KKworICAgICAgICAvLyBpZiAwIGxlbmd0aCwgc2VuZCBhcyBxdW90ZWQtc3RyaW5nCisgICAgICAgIGJvb2xlYW4gcXVvdGUgPSBsZW4gPT0gMCA/IHRydWUgOiBkb1F1b3RlOworCWJvb2xlYW4gZXNjYXBlID0gZmFsc2U7CisJYm9vbGVhbiB1dGY4ID0gcHJvdG9jb2wuc3VwcG9ydHNVdGY4KCk7CisKKwlieXRlIGI7CisJZm9yIChpbnQgaSA9IDA7IGkgPCBsZW47IGkrKykgeworCSAgICBiID0gYnl0ZXNbaV07CisJICAgIGlmIChiID09ICdcMCcgfHwgYiA9PSAnXHInIHx8IGIgPT0gJ1xuJyB8fAorCQkgICAgKCF1dGY4ICYmICgoYiAmIDB4ZmYpID4gMDE3NykpKSB7CisJCS8vIE5VTCwgQ1Igb3IgTEYgbWVhbnMgdGhlIGJ5dGVzIG5lZWQgdG8gYmUgc2VudCBhcyBsaXRlcmFscworCQlsaXRlcmFsKGJ5dGVzLCBwcm90b2NvbCk7CisJCXJldHVybjsKKwkgICAgfQorCSAgICBpZiAoYiA9PSAnKicgfHwgYiA9PSAnJScgfHwgYiA9PSAnKCcgfHwgYiA9PSAnKScgfHwgYiA9PSAneycgfHwKKwkJICAgIGIgPT0gJyInIHx8IGIgPT0gJ1xcJyB8fAorCQkgICAgKChiICYgMHhmZikgPD0gJyAnKSB8fCAoKGIgJiAweGZmKSA+IDAxNzcpKSB7CisJCXF1b3RlID0gdHJ1ZTsKKwkJaWYgKGIgPT0gJyInIHx8IGIgPT0gJ1xcJykgLy8gbmVlZCB0byBlc2NhcGUgdGhlc2UgY2hhcmFjdGVycworCQkgICAgZXNjYXBlID0gdHJ1ZTsKKwkgICAgfQorCX0KKworCS8qCisJICogTWFrZSBzdXJlIHRoZSAoY2FzZS1pbmRlcGVuZGVudCkgc3RyaW5nICJOSUwiIGlzIGFsd2F5cyBxdW90ZWQsCisJICogc28gYXMgbm90IHRvIGJlIGNvbmZ1c2VkIHdpdGggYSByZWFsIE5JTCAoaGFuZGxlZCBhYm92ZSBpbiBuc3RyaW5nKS4KKwkgKiBUaGlzIGlzIG1vcmUgdGhhbiBpcyBuZWNlc3NhcnksIGJ1dCBpdCdzIHJhcmUgdG8gYmVnaW4gd2l0aCBhbmQKKwkgKiB0aGlzIG1ha2VzIGl0IHNhZmVyIHRoYW4gZG9pbmcgdGhlIHRlc3QgaW4gbnN0cmluZyBhYm92ZSBpbiBjYXNlCisJICogc29tZSBjb2RlIGNhbGxzIHdyaXRlU3RyaW5nIHdoZW4gaXQgc2hvdWxkIGNhbGwgd3JpdGVOU3RyaW5nLgorCSAqLworCWlmICghcXVvdGUgJiYgYnl0ZXMubGVuZ3RoID09IDMgJiYKKwkJKGJ5dGVzWzBdID09ICdOJyB8fCBieXRlc1swXSA9PSAnbicpICYmCisJCShieXRlc1sxXSA9PSAnSScgfHwgYnl0ZXNbMV0gPT0gJ2knKSAmJgorCQkoYnl0ZXNbMl0gPT0gJ0wnIHx8IGJ5dGVzWzJdID09ICdsJykpCisJICAgIHF1b3RlID0gdHJ1ZTsKKworCWlmIChxdW90ZSkgLy8gc3RhcnQgcXVvdGUKKwkgICAgb3Mud3JpdGUoJyInKTsKKworICAgICAgICBpZiAoZXNjYXBlKSB7CisgICAgICAgICAgICAvLyBhbHJlYWR5IHF1b3RlZAorICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW47IGkrKykgeworICAgICAgICAgICAgICAgIGIgPSBieXRlc1tpXTsKKyAgICAgICAgICAgICAgICBpZiAoYiA9PSAnIicgfHwgYiA9PSAnXFwnKQorICAgICAgICAgICAgICAgICAgICBvcy53cml0ZSgnXFwnKTsKKyAgICAgICAgICAgICAgICBvcy53cml0ZShiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIAorICAgICAgICAgICAgb3Mud3JpdGUoYnl0ZXMpOworIAorCisJaWYgKHF1b3RlKSAvLyBlbmQgcXVvdGUKKwkgICAgb3Mud3JpdGUoJyInKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZSBvdXQgZ2l2ZW4gYnl0ZVtdIGFzIGEgbGl0ZXJhbAorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBsaXRlcmFsKGJ5dGVbXSBiLCBQcm90b2NvbCBwcm90b2NvbCkgCisJCQl0aHJvd3MgSU9FeGNlcHRpb24sIFByb3RvY29sRXhjZXB0aW9uIHsKKwlzdGFydExpdGVyYWwocHJvdG9jb2wsIGIubGVuZ3RoKS53cml0ZShiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZSBvdXQgZ2l2ZW4gQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGFzIGEgbGl0ZXJhbC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgbGl0ZXJhbChCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYiwgUHJvdG9jb2wgcHJvdG9jb2wpIAorCQkJdGhyb3dzIElPRXhjZXB0aW9uLCBQcm90b2NvbEV4Y2VwdGlvbiB7CisJYi53cml0ZVRvKHN0YXJ0TGl0ZXJhbChwcm90b2NvbCwgYi5zaXplKCkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZSBvdXQgZ2l2ZW4gTGl0ZXJhbCBhcyBhIGxpdGVyYWwuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGxpdGVyYWwoTGl0ZXJhbCBiLCBQcm90b2NvbCBwcm90b2NvbCkgCisJCQl0aHJvd3MgSU9FeGNlcHRpb24sIFByb3RvY29sRXhjZXB0aW9uIHsKKwliLndyaXRlVG8oc3RhcnRMaXRlcmFsKHByb3RvY29sLCBiLnNpemUoKSkpOworICAgIH0KKworICAgIHByaXZhdGUgT3V0cHV0U3RyZWFtIHN0YXJ0TGl0ZXJhbChQcm90b2NvbCBwcm90b2NvbCwgaW50IHNpemUpIAorCQkJdGhyb3dzIElPRXhjZXB0aW9uLCBQcm90b2NvbEV4Y2VwdGlvbiB7CisJRGF0YU91dHB1dFN0cmVhbSBvcyA9IChEYXRhT3V0cHV0U3RyZWFtKXByb3RvY29sLmdldE91dHB1dFN0cmVhbSgpOworCWJvb2xlYW4gbm9uU3luYyA9IHByb3RvY29sLnN1cHBvcnRzTm9uU3luY0xpdGVyYWxzKCk7CisKKwlvcy53cml0ZSgneycpOworCW9zLndyaXRlQnl0ZXMoSW50ZWdlci50b1N0cmluZyhzaXplKSk7CisJaWYgKG5vblN5bmMpIC8vIHNlcnZlciBzdXBwb3J0cyBub24tc3luYyBsaXRlcmFscworCSAgICBvcy53cml0ZUJ5dGVzKCIrfVxyXG4iKTsKKwllbHNlCisJICAgIG9zLndyaXRlQnl0ZXMoIn1cclxuIik7CisJb3MuZmx1c2goKTsKKworCS8vIElmIHdlIGFyZSB1c2luZyBzeW5jaHJvbml6ZWQgbGl0ZXJhbHMsIHdhaXQgZm9yIHRoZSBzZXJ2ZXIncworCS8vIGNvbnRpbnVhdGlvbiBzaWduYWwKKwlpZiAoIW5vblN5bmMpIHsKKwkgICAgZm9yICg7IDspIHsKKwkJUmVzcG9uc2UgciA9IHByb3RvY29sLnJlYWRSZXNwb25zZSgpOworCQlpZiAoci5pc0NvbnRpbnVhdGlvbigpKQorCQkgICAgYnJlYWs7CisJCWlmIChyLmlzVGFnZ2VkKCkpCisJCSAgICB0aHJvdyBuZXcgTGl0ZXJhbEV4Y2VwdGlvbihyKTsKKwkJLy8gWFhYIC0gdGhyb3cgYXdheSB1bnRhZ2dlZCByZXNwb25zZXM7CisJCS8vCSB2aW9sYXRlcyBJTUFQIHNwZWMsIGhvcGUgbm8gc2VydmVycyBkbyB0aGlzCisJICAgIH0KKwl9CisJcmV0dXJuIG9zOworICAgIH0KK30KKworY2xhc3MgQXRvbSB7CisgICAgU3RyaW5nIHN0cmluZzsKKworICAgIEF0b20oU3RyaW5nIHMpIHsKKwlzdHJpbmcgPSBzOworICAgIH0KK30KKworY2xhc3MgQVN0cmluZyB7CisgICAgYnl0ZVtdIGJ5dGVzOworCisgICAgQVN0cmluZyhieXRlW10gYikgeworCWJ5dGVzID0gYjsKKyAgICB9Cit9CisKK2NsYXNzIE5TdHJpbmcgeworICAgIGJ5dGVbXSBieXRlczsKKworICAgIE5TdHJpbmcoYnl0ZVtdIGIpIHsKKwlieXRlcyA9IGI7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pYXAvQmFkQ29tbWFuZEV4Y2VwdGlvbi5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pYXAvQmFkQ29tbWFuZEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRhMWIzM2IKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2lhcC9CYWRDb21tYW5kRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0OSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuaWFwOworCisvKioKKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKi8KKworcHVibGljIGNsYXNzIEJhZENvbW1hbmRFeGNlcHRpb24gZXh0ZW5kcyBQcm90b2NvbEV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA1NzY5NzIyNTM5Mzk3MjM3NTE1TDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYW4gQmFkQ29tbWFuZEV4Y2VwdGlvbiB3aXRoIG5vIGRldGFpbCBtZXNzYWdlLgorICAgICAqLworICAgIHB1YmxpYyBCYWRDb21tYW5kRXhjZXB0aW9uKCkgeworCXN1cGVyKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhbiBCYWRDb21tYW5kRXhjZXB0aW9uIHdpdGggdGhlIHNwZWNpZmllZCBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKiBAcGFyYW0gcwkJdGhlIGRldGFpbCBtZXNzYWdlCisgICAgICovCisgICAgcHVibGljIEJhZENvbW1hbmRFeGNlcHRpb24oU3RyaW5nIHMpIHsKKwlzdXBlcihzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGFuIEJhZENvbW1hbmRFeGNlcHRpb24gd2l0aCB0aGUgc3BlY2lmaWVkIFJlc3BvbnNlLgorICAgICAqIEBwYXJhbSByCQl0aGUgUmVzcG9uc2UKKyAgICAgKi8KKyAgICBwdWJsaWMgQmFkQ29tbWFuZEV4Y2VwdGlvbihSZXNwb25zZSByKSB7CisJc3VwZXIocik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pYXAvQnl0ZUFycmF5LmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2lhcC9CeXRlQXJyYXkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMDUxMTBiCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pYXAvQnl0ZUFycmF5LmphdmEKQEAgLTAsMCArMSwxMjUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmlhcDsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CisKKy8qKgorICogQSBzaW1wbGUgd3JhcHBlciBhcm91bmQgYSBieXRlIGFycmF5LCB3aXRoIGEgc3RhcnQgcG9zaXRpb24gYW5kCisgKiBjb3VudCBvZiBieXRlcy4KKyAqCisgKiBAYXV0aG9yICBKb2huIE1hbmkKKyAqLworCitwdWJsaWMgY2xhc3MgQnl0ZUFycmF5IHsKKyAgICBwcml2YXRlIGJ5dGVbXSBieXRlczsgLy8gdGhlIGJ5dGUgYXJyYXkKKyAgICBwcml2YXRlIGludCBzdGFydDsJICAvLyBzdGFydCBwb3NpdGlvbgorICAgIHByaXZhdGUgaW50IGNvdW50OwkgIC8vIGNvdW50IG9mIGJ5dGVzCisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvcgorICAgICAqCisgICAgICogQHBhcmFtCWIJdGhlIGJ5dGUgYXJyYXkgdG8gd3JhcAorICAgICAqIEBwYXJhbQlzdGFydAlzdGFydCBwb3NpdGlvbiBpbiBieXRlIGFycmF5CisgICAgICogQHBhcmFtCWNvdW50CW51bWJlciBvZiBieXRlcyBpbiBieXRlIGFycmF5CisgICAgICovCisgICAgcHVibGljIEJ5dGVBcnJheShieXRlW10gYiwgaW50IHN0YXJ0LCBpbnQgY291bnQpIHsKKwlieXRlcyA9IGI7CisJdGhpcy5zdGFydCA9IHN0YXJ0OworCXRoaXMuY291bnQgPSBjb3VudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvciB0aGF0IGNyZWF0ZXMgYSBieXRlIGFycmF5IG9mIHRoZSBzcGVjaWZpZWQgc2l6ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbQlzaXplCXRoZSBzaXplIG9mIHRoZSBCeXRlQXJyYXkKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS40LjEKKyAgICAgKi8KKyAgICBwdWJsaWMgQnl0ZUFycmF5KGludCBzaXplKSB7CisJdGhpcyhuZXcgYnl0ZVtzaXplXSwgMCwgc2l6ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgaW50ZXJuYWwgYnl0ZSBhcnJheS4gTm90ZSB0aGF0IHRoaXMgaXMgYSBsaXZlCisgICAgICogcmVmZXJlbmNlIHRvIHRoZSBhY3R1YWwgZGF0YSwgbm90IGEgY29weS4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIHdyYXBwZWQgYnl0ZSBhcnJheQorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ2V0Qnl0ZXMoKSB7CisJcmV0dXJuIGJ5dGVzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBuZXcgYnl0ZSBhcnJheSB0aGF0IGlzIGEgY29weSBvZiB0aGUgZGF0YS4KKyAgICAgKgorICAgICAqIEByZXR1cm4JYSBuZXcgYnl0ZSBhcnJheSB3aXRoIHRoZSBieXRlcyBmcm9tIHN0YXJ0IGZvciBjb3VudAorICAgICAqLworICAgIHB1YmxpYyBieXRlW10gZ2V0TmV3Qnl0ZXMoKSB7CisJYnl0ZVtdIGIgPSBuZXcgYnl0ZVtjb3VudF07CisJU3lzdGVtLmFycmF5Y29weShieXRlcywgc3RhcnQsIGIsIDAsIGNvdW50KTsKKwlyZXR1cm4gYjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzdGFydCBwb3NpdGlvbgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgc3RhcnQgcG9zaXRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFN0YXJ0KCkgeworCXJldHVybiBzdGFydDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjb3VudCBvZiBieXRlcworICAgICAqCisgICAgICogQHJldHVybgl0aGUgbnVtYmVyIG9mIGJ5dGVzCisgICAgICovCisgICAgcHVibGljIGludCBnZXRDb3VudCgpIHsKKwlyZXR1cm4gY291bnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBjb3VudCBvZiBieXRlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbQljb3VudAl0aGUgbnVtYmVyIG9mIGJ5dGVzCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNC4xCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q291bnQoaW50IGNvdW50KSB7CisJdGhpcy5jb3VudCA9IGNvdW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBCeXRlQXJyYXlJbnB1dFN0cmVhbS4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIEJ5dGVBcnJheUlucHV0U3RyZWFtCisgICAgICovCisgICAgcHVibGljIEJ5dGVBcnJheUlucHV0U3RyZWFtIHRvQnl0ZUFycmF5SW5wdXRTdHJlYW0oKSB7CisJcmV0dXJuIG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShieXRlcywgc3RhcnQsIGNvdW50KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHcm93IHRoZSBieXRlIGFycmF5IGJ5IGluY3IgYnl0ZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0JaW5jcglob3cgbXVjaCB0byBncm93CisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNC4xCisgICAgICovCisgICAgcHVibGljIHZvaWQgZ3JvdyhpbnQgaW5jcikgeworCWJ5dGVbXSBuYnVmID0gbmV3IGJ5dGVbYnl0ZXMubGVuZ3RoICsgaW5jcl07CisJU3lzdGVtLmFycmF5Y29weShieXRlcywgMCwgbmJ1ZiwgMCwgYnl0ZXMubGVuZ3RoKTsKKwlieXRlcyA9IG5idWY7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pYXAvQ29tbWFuZEZhaWxlZEV4Y2VwdGlvbi5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pYXAvQ29tbWFuZEZhaWxlZEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhjMTQxZTcKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2lhcC9Db21tYW5kRmFpbGVkRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0OSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuaWFwOworCisvKioKKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKi8KKworcHVibGljIGNsYXNzIENvbW1hbmRGYWlsZWRFeGNlcHRpb24gZXh0ZW5kcyBQcm90b2NvbEV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA3OTM5MzI4MDc4ODA0NDM2MzFMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhbiBDb21tYW5kRmFpbGVkRXhjZXB0aW9uIHdpdGggbm8gZGV0YWlsIG1lc3NhZ2UuCisgICAgICovCisgICAgcHVibGljIENvbW1hbmRGYWlsZWRFeGNlcHRpb24oKSB7CisJc3VwZXIoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGFuIENvbW1hbmRGYWlsZWRFeGNlcHRpb24gd2l0aCB0aGUgc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlLgorICAgICAqIEBwYXJhbSBzCQl0aGUgZGV0YWlsIG1lc3NhZ2UKKyAgICAgKi8KKyAgICBwdWJsaWMgQ29tbWFuZEZhaWxlZEV4Y2VwdGlvbihTdHJpbmcgcykgeworCXN1cGVyKHMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYW4gQ29tbWFuZEZhaWxlZEV4Y2VwdGlvbiB3aXRoIHRoZSBzcGVjaWZpZWQgUmVzcG9uc2UuCisgICAgICogQHBhcmFtIHIJCXRoZSBSZXNwb25zZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29tbWFuZEZhaWxlZEV4Y2VwdGlvbihSZXNwb25zZSByKSB7CisJc3VwZXIocik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pYXAvQ29ubmVjdGlvbkV4Y2VwdGlvbi5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pYXAvQ29ubmVjdGlvbkV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjEyZGQ0OTYKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2lhcC9Db25uZWN0aW9uRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw1OCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuaWFwOworCisvKioKKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKi8KKworcHVibGljIGNsYXNzIENvbm5lY3Rpb25FeGNlcHRpb24gZXh0ZW5kcyBQcm90b2NvbEV4Y2VwdGlvbiB7CisgICAgcHJpdmF0ZSB0cmFuc2llbnQgUHJvdG9jb2wgcDsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDU3NDk3Mzk2MDQyNTc0NjQ3MjdMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhbiBDb25uZWN0aW9uRXhjZXB0aW9uIHdpdGggbm8gZGV0YWlsIG1lc3NhZ2UuCisgICAgICovCisgICAgcHVibGljIENvbm5lY3Rpb25FeGNlcHRpb24oKSB7CisJc3VwZXIoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGFuIENvbm5lY3Rpb25FeGNlcHRpb24gd2l0aCB0aGUgc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIHMJCXRoZSBkZXRhaWwgbWVzc2FnZQorICAgICAqLworICAgIHB1YmxpYyBDb25uZWN0aW9uRXhjZXB0aW9uKFN0cmluZyBzKSB7CisJc3VwZXIocyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhbiBDb25uZWN0aW9uRXhjZXB0aW9uIHdpdGggdGhlIHNwZWNpZmllZCBSZXNwb25zZS4KKyAgICAgKgorICAgICAqIEBwYXJhbQlwCXRoZSBQcm90b2NvbCBvYmplY3QKKyAgICAgKiBAcGFyYW0Jcgl0aGUgUmVzcG9uc2UKKyAgICAgKi8KKyAgICBwdWJsaWMgQ29ubmVjdGlvbkV4Y2VwdGlvbihQcm90b2NvbCBwLCBSZXNwb25zZSByKSB7CisJc3VwZXIocik7CisJdGhpcy5wID0gcDsKKyAgICB9CisKKyAgICBwdWJsaWMgUHJvdG9jb2wgZ2V0UHJvdG9jb2woKSB7CisJcmV0dXJuIHA7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pYXAvTGl0ZXJhbC5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pYXAvTGl0ZXJhbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE0YzU5MmIKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2lhcC9MaXRlcmFsLmphdmEKQEAgLTAsMCArMSw0MyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuaWFwOworCitpbXBvcnQgamF2YS5pby4qOworCisvKioKKyAqIEFuIGludGVyZmFjZSBmb3Igb2JqZWN0cyB0aGF0IHByb3ZpZGUgZGF0YSBkeW5hbWljYWxseSBmb3IgdXNlIGluCisgKiBhIGxpdGVyYWwgcHJvdG9jb2wgZWxlbWVudC4KKyAqCisgKiBAYXV0aG9yICBCaWxsIFNoYW5ub24KKyAqLworCitwdWJsaWMgaW50ZXJmYWNlIExpdGVyYWwgeworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgc2l6ZSBvZiB0aGUgZGF0YS4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIHNpemUgb2YgdGhlIGRhdGEKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHNpemUoKTsKKworICAgIC8qKgorICAgICAqIFdyaXRlIHRoZSBkYXRhIHRvIHRoZSBPdXRwdXRTdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0Jb3MJdGhlIG91dHB1dCBzdHJlYW0KKyAgICAgKiBAZXhjZXB0aW9uCUlPRXhjZXB0aW9uCWZvciBJL08gZXJyb3JzCisgICAgICovCisgICAgcHVibGljIHZvaWQgd3JpdGVUbyhPdXRwdXRTdHJlYW0gb3MpIHRocm93cyBJT0V4Y2VwdGlvbjsKK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaWFwL0xpdGVyYWxFeGNlcHRpb24uamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaWFwL0xpdGVyYWxFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42NjA3NDdmCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pYXAvTGl0ZXJhbEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsMzYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmlhcDsKKworLyoqCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCisKK3B1YmxpYyBjbGFzcyBMaXRlcmFsRXhjZXB0aW9uIGV4dGVuZHMgUHJvdG9jb2xFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTY5MTkxNzk4MjgzMzk2MDk5MTNMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIExpdGVyYWxFeGNlcHRpb24gd2l0aCB0aGUgc3BlY2lmaWVkIFJlc3BvbnNlIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbQlyCXRoZSByZXNwb25zZSBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgTGl0ZXJhbEV4Y2VwdGlvbihSZXNwb25zZSByKSB7CisJc3VwZXIoci50b1N0cmluZygpKTsKKwlyZXNwb25zZSA9IHI7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pYXAvUGFyc2luZ0V4Y2VwdGlvbi5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pYXAvUGFyc2luZ0V4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmExZTcxNjgKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2lhcC9QYXJzaW5nRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0OSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuaWFwOworCisvKioKKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKi8KKworcHVibGljIGNsYXNzIFBhcnNpbmdFeGNlcHRpb24gZXh0ZW5kcyBQcm90b2NvbEV4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA3NzU2MTE5ODQwMTQyNzI0ODM5TDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYW4gUGFyc2luZ0V4Y2VwdGlvbiB3aXRoIG5vIGRldGFpbCBtZXNzYWdlLgorICAgICAqLworICAgIHB1YmxpYyBQYXJzaW5nRXhjZXB0aW9uKCkgeworCXN1cGVyKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhbiBQYXJzaW5nRXhjZXB0aW9uIHdpdGggdGhlIHNwZWNpZmllZCBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKiBAcGFyYW0gcwkJdGhlIGRldGFpbCBtZXNzYWdlCisgICAgICovCisgICAgcHVibGljIFBhcnNpbmdFeGNlcHRpb24oU3RyaW5nIHMpIHsKKwlzdXBlcihzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGFuIFBhcnNpbmdFeGNlcHRpb24gd2l0aCB0aGUgc3BlY2lmaWVkIFJlc3BvbnNlLgorICAgICAqIEBwYXJhbSByCQl0aGUgUmVzcG9uc2UKKyAgICAgKi8KKyAgICBwdWJsaWMgUGFyc2luZ0V4Y2VwdGlvbihSZXNwb25zZSByKSB7CisJc3VwZXIocik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pYXAvUHJvdG9jb2wuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaWFwL1Byb3RvY29sLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTMzOTUzMgotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaWFwL1Byb3RvY29sLmphdmEKQEAgLTAsMCArMSw2NzEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmlhcDsKKworaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5Tb2NrZXRDaGFubmVsOworaW1wb3J0IGphdmEubmV0Lio7CitpbXBvcnQgamF2YXgubmV0LnNzbC5TU0xTb2NrZXQ7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5Db3B5T25Xcml0ZUFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5hdG9taWMuQXRvbWljSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnV0aWwubG9nZ2luZy5MZXZlbDsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLkRlZmxhdGVyOworaW1wb3J0IGphdmEudXRpbC56aXAuRGVmbGF0ZXJPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLnppcC5JbmZsYXRlcjsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLkluZmxhdGVySW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuRmllbGQ7CisKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5Qcm9wVXRpbDsKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5NYWlsTG9nZ2VyOworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLlNvY2tldEZldGNoZXI7CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuVHJhY2VJbnB1dFN0cmVhbTsKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5UcmFjZU91dHB1dFN0cmVhbTsKKworLyoqCisgKiBHZW5lcmFsIHByb3RvY29sIGhhbmRsaW5nIGNvZGUgZm9yIElNQVAtbGlrZSBwcm90b2NvbHMuIDxwPgorICoKKyAqIFRoZSBQcm90b2NvbCBvYmplY3QgaXMgbXVsdGl0aHJlYWQgc2FmZS4KKyAqCisgKiBAYXV0aG9yICBKb2huIE1hbmkKKyAqIEBhdXRob3IgIE1heCBTcGl2YWsKKyAqIEBhdXRob3IgIEJpbGwgU2hhbm5vbgorICovCisKK3B1YmxpYyBjbGFzcyBQcm90b2NvbCB7CisgICAgcHJvdGVjdGVkIFN0cmluZyBob3N0OworICAgIHByaXZhdGUgU29ja2V0IHNvY2tldDsKKyAgICAvLyBpbiBjYXNlIHdlIHR1cm4gb24gVExTLCB3ZSdsbCBuZWVkIHRoZXNlIGxhdGVyCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gcXVvdGU7CisgICAgcHJvdGVjdGVkIE1haWxMb2dnZXIgbG9nZ2VyOworICAgIHByb3RlY3RlZCBNYWlsTG9nZ2VyIHRyYWNlTG9nZ2VyOworICAgIHByb3RlY3RlZCBQcm9wZXJ0aWVzIHByb3BzOworICAgIHByb3RlY3RlZCBTdHJpbmcgcHJlZml4OworCisgICAgcHJpdmF0ZSBUcmFjZUlucHV0U3RyZWFtIHRyYWNlSW5wdXQ7CS8vIHRoZSBUcmFjZXIKKyAgICBwcml2YXRlIHZvbGF0aWxlIFJlc3BvbnNlSW5wdXRTdHJlYW0gaW5wdXQ7CisKKyAgICBwcml2YXRlIFRyYWNlT3V0cHV0U3RyZWFtIHRyYWNlT3V0cHV0OwkvLyB0aGUgVHJhY2VyCisgICAgcHJpdmF0ZSB2b2xhdGlsZSBEYXRhT3V0cHV0U3RyZWFtIG91dHB1dDsKKworICAgIHByaXZhdGUgaW50IHRhZ0NvdW50ZXIgPSAwOworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIHRhZ1ByZWZpeDsKKworICAgIHByaXZhdGUgU3RyaW5nIGxvY2FsSG9zdE5hbWU7CisKKyAgICBwcml2YXRlIGZpbmFsIExpc3Q8UmVzcG9uc2VIYW5kbGVyPiBoYW5kbGVycworCSAgICA9IG5ldyBDb3B5T25Xcml0ZUFycmF5TGlzdDw+KCk7CisKKyAgICBwcml2YXRlIHZvbGF0aWxlIGxvbmcgdGltZXN0YW1wOworCisgICAgLy8gcGFja2FnZSBwcml2YXRlLCB0byBhbGxvdyB0ZXN0aW5nCisgICAgc3RhdGljIGZpbmFsIEF0b21pY0ludGVnZXIgdGFnTnVtID0gbmV3IEF0b21pY0ludGVnZXIoKTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBDUkxGID0geyAoYnl0ZSknXHInLCAoYnl0ZSknXG4nfTsKKyAKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3Rvci4gPHA+CisgICAgICogCisgICAgICogT3BlbnMgYSBjb25uZWN0aW9uIHRvIHRoZSBnaXZlbiBob3N0IGF0IGdpdmVuIHBvcnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaG9zdAlob3N0IHRvIGNvbm5lY3QgdG8KKyAgICAgKiBAcGFyYW0gcG9ydAlwb3J0bnVtYmVyIHRvIGNvbm5lY3QgdG8KKyAgICAgKiBAcGFyYW0gcHJvcHMgICAgIFByb3BlcnRpZXMgb2JqZWN0IHVzZWQgYnkgdGhpcyBwcm90b2NvbAorICAgICAqIEBwYXJhbSBwcmVmaXggCVByZWZpeCB0byBwcmVwZW5kIHRvIHByb3BlcnR5IGtleXMKKyAgICAgKiBAcGFyYW0gaXNTU0wgCXVzZSBTU0w/CisgICAgICogQHBhcmFtIGxvZ2dlciAJbG9nIG1lc3NhZ2VzIGhlcmUKKyAgICAgKiBAZXhjZXB0aW9uCUlPRXhjZXB0aW9uCWZvciBJL08gZXJyb3JzCisgICAgICogQGV4Y2VwdGlvbglQcm90b2NvbEV4Y2VwdGlvbglmb3IgcHJvdG9jb2wgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgUHJvdG9jb2woU3RyaW5nIGhvc3QsIGludCBwb3J0LCAKKwkJICAgIFByb3BlcnRpZXMgcHJvcHMsIFN0cmluZyBwcmVmaXgsCisJCSAgICBib29sZWFuIGlzU1NMLCBNYWlsTG9nZ2VyIGxvZ2dlcikKKwkJICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgUHJvdG9jb2xFeGNlcHRpb24geworCWJvb2xlYW4gY29ubmVjdGVkID0gZmFsc2U7CQkvLyBkaWQgY29uc3RydWN0b3Igc3VjY2VlZD8KKwl0YWdQcmVmaXggPSBjb21wdXRlUHJlZml4KHByb3BzLCBwcmVmaXgpOworCXRyeSB7CisJICAgIHRoaXMuaG9zdCA9IGhvc3Q7CisJICAgIHRoaXMucHJvcHMgPSBwcm9wczsKKwkgICAgdGhpcy5wcmVmaXggPSBwcmVmaXg7CisJICAgIHRoaXMubG9nZ2VyID0gbG9nZ2VyOworCSAgICB0cmFjZUxvZ2dlciA9IGxvZ2dlci5nZXRTdWJMb2dnZXIoInByb3RvY29sIiwgbnVsbCk7CisKKwkgICAgc29ja2V0ID0gU29ja2V0RmV0Y2hlci5nZXRTb2NrZXQoaG9zdCwgcG9ydCwgcHJvcHMsIHByZWZpeCwgaXNTU0wpOworCSAgICBxdW90ZSA9IFByb3BVdGlsLmdldEJvb2xlYW5Qcm9wZXJ0eShwcm9wcywKKwkJCQkJIm1haWwuZGVidWcucXVvdGUiLCBmYWxzZSk7CisKKwkgICAgaW5pdFN0cmVhbXMoKTsKKworCSAgICAvLyBSZWFkIHNlcnZlciBncmVldGluZworCSAgICBwcm9jZXNzR3JlZXRpbmcocmVhZFJlc3BvbnNlKCkpOworCisJICAgIHRpbWVzdGFtcCA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworIAorCSAgICBjb25uZWN0ZWQgPSB0cnVlOwkvLyBtdXN0IGJlIGxhc3Qgc3RhdGVtZW50IGluIGNvbnN0cnVjdG9yCisJfSBmaW5hbGx5IHsKKwkgICAgLyoKKwkgICAgICogSWYgd2UgZ2V0IGhlcmUgYmVjYXVzZSBhbiBleGNlcHRpb24gd2FzIHRocm93biwgd2UgbmVlZAorCSAgICAgKiB0byBkaXNjb25uZWN0IHRvIGF2b2lkIGxlYXZpbmcgYSBjb25uZWN0ZWQgc29ja2V0IHRoYXQKKwkgICAgICogbm8gb25lIHdpbGwgYmUgYWJsZSB0byB1c2UgYmVjYXVzZSB0aGlzIG9iamVjdCB3YXMgbmV2ZXIKKwkgICAgICogY29tcGxldGVseSBjb25zdHJ1Y3RlZC4KKwkgICAgICovCisJICAgIGlmICghY29ubmVjdGVkKQorCQlkaXNjb25uZWN0KCk7CisJfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBpbml0U3RyZWFtcygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJdHJhY2VJbnB1dCA9IG5ldyBUcmFjZUlucHV0U3RyZWFtKHNvY2tldC5nZXRJbnB1dFN0cmVhbSgpLCB0cmFjZUxvZ2dlcik7CisJdHJhY2VJbnB1dC5zZXRRdW90ZShxdW90ZSk7CisJaW5wdXQgPSBuZXcgUmVzcG9uc2VJbnB1dFN0cmVhbSh0cmFjZUlucHV0KTsKKworCXRyYWNlT3V0cHV0ID0KKwkgICAgbmV3IFRyYWNlT3V0cHV0U3RyZWFtKHNvY2tldC5nZXRPdXRwdXRTdHJlYW0oKSwgdHJhY2VMb2dnZXIpOworCXRyYWNlT3V0cHV0LnNldFF1b3RlKHF1b3RlKTsKKwlvdXRwdXQgPSBuZXcgRGF0YU91dHB1dFN0cmVhbShuZXcgQnVmZmVyZWRPdXRwdXRTdHJlYW0odHJhY2VPdXRwdXQpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wdXRlIHRoZSB0YWcgcHJlZml4IHRvIGJlIHVzZWQgZm9yIHRoaXMgY29ubmVjdGlvbi4KKyAgICAgKiBTdGFydCB3aXRoICJBIiAtICJaIiwgdGhlbiAiQUEiIC0gIlpaIiwgYW5kIGZpbmFsbHkgIkFBQSIgLSAiWlpaIi4KKyAgICAgKiBXcmFwIGFyb3VuZCBhZnRlciB0aGF0LgorICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nIGNvbXB1dGVQcmVmaXgoUHJvcGVydGllcyBwcm9wcywgU3RyaW5nIHByZWZpeCkgeworCS8vIFhYWCAtIGluIGNhc2Ugc29tZW9uZSBkZXBlbmRzIG9uIHRoZSB0YWcgcHJlZml4CisJaWYgKFByb3BVdGlsLmdldEJvb2xlYW5Qcm9wZXJ0eShwcm9wcywKKwkJCQkgICAgcHJlZml4ICsgIi5yZXVzZXRhZ3ByZWZpeCIsIGZhbHNlKSkKKwkgICAgcmV0dXJuICJBIjsKKwkvLyB0YWcgcHJlZml4LCB3cmFwIGFyb3VuZCBhZnRlciB0aHJlZSBsZXR0ZXJzCisJaW50IG4gPSB0YWdOdW0uZ2V0QW5kSW5jcmVtZW50KCkgJSAoMjYqMjYqMjYgKyAyNioyNiArIDI2KTsKKwlTdHJpbmcgdGFnUHJlZml4OworCWlmIChuIDwgMjYpCisJICAgIHRhZ1ByZWZpeCA9IG5ldyBTdHJpbmcobmV3IGNoYXJbXSB7IChjaGFyKSgnQScgKyBuKSB9KTsKKwllbHNlIGlmIChuIDwgKDI2KjI2ICsgMjYpKSB7CisJICAgIG4gLT0gMjY7CisJICAgIHRhZ1ByZWZpeCA9IG5ldyBTdHJpbmcobmV3IGNoYXJbXSB7CisJCQkgICAgKGNoYXIpKCdBJyArIG4vMjYpLCAoY2hhcikoJ0EnICsgbiUyNikgfSk7CisJfSBlbHNlIHsKKwkgICAgbiAtPSAoMjYqMjYgKyAyNik7CisJICAgIHRhZ1ByZWZpeCA9IG5ldyBTdHJpbmcobmV3IGNoYXJbXSB7CisJCShjaGFyKSgnQScgKyBuLygyNioyNikpLAorCQkoY2hhcikoJ0EnICsgKG4lKDI2KjI2KSkvMjYpLAorCQkoY2hhcikoJ0EnICsgbiUyNikgfSk7CisJfQorCXJldHVybiB0YWdQcmVmaXg7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IgZm9yIGRlYnVnZ2luZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbgl0aGUgSW5wdXRTdHJlYW0gdG8gcmVhZCBmcm9tCisgICAgICogQHBhcmFtIG91dAl0aGUgUHJpbnRTdHJlYW0gdG8gd3JpdGUgdG8KKyAgICAgKiBAcGFyYW0gcHJvcHMgICAgIFByb3BlcnRpZXMgb2JqZWN0IHVzZWQgYnkgdGhpcyBwcm90b2NvbAorICAgICAqIEBwYXJhbSBkZWJ1Zwl0cnVlIHRvIGVuYWJsZSBkZWJ1Z2dpbmcgb3V0cHV0CisgICAgICogQGV4Y2VwdGlvbglJT0V4Y2VwdGlvbglmb3IgSS9PIGVycm9ycworICAgICAqLworICAgIHB1YmxpYyBQcm90b2NvbChJbnB1dFN0cmVhbSBpbiwgUHJpbnRTdHJlYW0gb3V0LCBQcm9wZXJ0aWVzIHByb3BzLAorCQkJCWJvb2xlYW4gZGVidWcpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJdGhpcy5ob3N0ID0gImxvY2FsaG9zdCI7CisJdGhpcy5wcm9wcyA9IHByb3BzOworCXRoaXMucXVvdGUgPSBmYWxzZTsKKwl0YWdQcmVmaXggPSBjb21wdXRlUHJlZml4KHByb3BzLCAibWFpbC5pbWFwIik7CisJbG9nZ2VyID0gbmV3IE1haWxMb2dnZXIodGhpcy5nZXRDbGFzcygpLCAiREVCVUciLCBkZWJ1ZywgU3lzdGVtLm91dCk7CisJdHJhY2VMb2dnZXIgPSBsb2dnZXIuZ2V0U3ViTG9nZ2VyKCJwcm90b2NvbCIsIG51bGwpOworCisJLy8gWFhYIC0gaW5saW5lZCBpbml0U3RyZWFtcywgd29uJ3QgYWxsb3cgbGF0ZXIgc3RhcnRUTFMKKwl0cmFjZUlucHV0ID0gbmV3IFRyYWNlSW5wdXRTdHJlYW0oaW4sIHRyYWNlTG9nZ2VyKTsKKwl0cmFjZUlucHV0LnNldFF1b3RlKHF1b3RlKTsKKwlpbnB1dCA9IG5ldyBSZXNwb25zZUlucHV0U3RyZWFtKHRyYWNlSW5wdXQpOworCisJdHJhY2VPdXRwdXQgPSBuZXcgVHJhY2VPdXRwdXRTdHJlYW0ob3V0LCB0cmFjZUxvZ2dlcik7CisJdHJhY2VPdXRwdXQuc2V0UXVvdGUocXVvdGUpOworCW91dHB1dCA9IG5ldyBEYXRhT3V0cHV0U3RyZWFtKG5ldyBCdWZmZXJlZE91dHB1dFN0cmVhbSh0cmFjZU91dHB1dCkpOworCisgICAgICAgIHRpbWVzdGFtcCA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHRpbWVzdGFtcC4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIHRpbWVzdGFtcAorICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldFRpbWVzdGFtcCgpIHsKKyAgICAgICAgcmV0dXJuIHRpbWVzdGFtcDsKKyAgICB9CisgCisgICAgLyoqCisgICAgICogQWRkcyBhIHJlc3BvbnNlIGhhbmRsZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0JaAl0aGUgcmVzcG9uc2UgaGFuZGxlcgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFkZFJlc3BvbnNlSGFuZGxlcihSZXNwb25zZUhhbmRsZXIgaCkgeworCWhhbmRsZXJzLmFkZChoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmVkIHRoZSBzcGVjaWZpZWQgcmVzcG9uc2UgaGFuZGxlci4KKyAgICAgKgorICAgICAqIEBwYXJhbQloCXRoZSByZXNwb25zZSBoYW5kbGVyCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVtb3ZlUmVzcG9uc2VIYW5kbGVyKFJlc3BvbnNlSGFuZGxlciBoKSB7CisJaGFuZGxlcnMucmVtb3ZlKGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIE5vdGlmeSByZXNwb25zZSBoYW5kbGVycworICAgICAqCisgICAgICogQHBhcmFtCXJlc3BvbnNlcwl0aGUgcmVzcG9uc2VzCisgICAgICovCisgICAgcHVibGljIHZvaWQgbm90aWZ5UmVzcG9uc2VIYW5kbGVycyhSZXNwb25zZVtdIHJlc3BvbnNlcykgeworCWlmIChoYW5kbGVycy5pc0VtcHR5KCkpIHsKKwkgICAgcmV0dXJuOworCX0KKworCWZvciAoUmVzcG9uc2UgciA6IHJlc3BvbnNlcykgeworCSAgICBpZiAociAhPSBudWxsKSB7CisJCWZvciAoUmVzcG9uc2VIYW5kbGVyIHJoIDogaGFuZGxlcnMpIHsKKwkJICAgIGlmIChyaCAhPSBudWxsKSB7CisJCQlyaC5oYW5kbGVSZXNwb25zZShyKTsKKwkJICAgIH0KKwkJfQorCSAgICB9CisJfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHByb2Nlc3NHcmVldGluZyhSZXNwb25zZSByKSB0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCWlmIChyLmlzQllFKCkpCisJICAgIHRocm93IG5ldyBDb25uZWN0aW9uRXhjZXB0aW9uKHRoaXMsIHIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgUHJvdG9jb2wncyBJbnB1dFN0cmVhbS4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIGlucHV0IHN0cmVhbQorICAgICAqLworICAgIHByb3RlY3RlZCBSZXNwb25zZUlucHV0U3RyZWFtIGdldElucHV0U3RyZWFtKCkgeworCXJldHVybiBpbnB1dDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIFByb3RvY29sJ3MgT3V0cHV0U3RyZWFtCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBvdXRwdXQgc3RyZWFtCisgICAgICovCisgICAgcHJvdGVjdGVkIE91dHB1dFN0cmVhbSBnZXRPdXRwdXRTdHJlYW0oKSB7CisJcmV0dXJuIG91dHB1dDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhpcyBQcm90b2NvbCBzdXBwb3J0cyBub24tc3luY2hyb25pemluZyBsaXRlcmFscworICAgICAqIERlZmF1bHQgaXMgZmFsc2UuIFN1YmNsYXNzZXMgc2hvdWxkIG92ZXJyaWRlIHRoaXMgaWYgcmVxdWlyZWQKKyAgICAgKgorICAgICAqIEByZXR1cm4JdHJ1ZSBpZiB0aGUgc2VydmVyIHN1cHBvcnRzIG5vbi1zeW5jaHJvbml6aW5nIGxpdGVyYWxzCisgICAgICovCisgICAgcHJvdGVjdGVkIHN5bmNocm9uaXplZCBib29sZWFuIHN1cHBvcnRzTm9uU3luY0xpdGVyYWxzKCkgeworCXJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgUmVzcG9uc2UgcmVhZFJlc3BvbnNlKCkgCisJCXRocm93cyBJT0V4Y2VwdGlvbiwgUHJvdG9jb2xFeGNlcHRpb24geworCXJldHVybiBuZXcgUmVzcG9uc2UodGhpcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSXMgYW5vdGhlciByZXNwb25zZSBhdmFpbGFibGUgaW4gb3VyIGJ1ZmZlcj8KKyAgICAgKgorICAgICAqIEByZXR1cm4JdHJ1ZSBpZiBhbm90aGVyIHJlc3BvbnNlIGlzIGluIHRoZSBidWZmZXIKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS41LjQKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNSZXNwb25zZSgpIHsKKwkvKgorCSAqIFhYWCAtIFJlYWxseSBzaG91bGQgcGVlayBhaGVhZCBpbiB0aGUgYnVmZmVyIHRvIHNlZQorCSAqIGlmIHRoZXJlJ3MgYSAqY29tcGxldGUqIHJlc3BvbnNlIGF2YWlsYWJsZSwgYnV0IGlmIHRoZXJlCisJICogaXNuJ3Qgd2hvJ3MgZ29pbmcgdG8gcmVhZCBtb3JlIGRhdGEgaW50byB0aGUgYnVmZmVyIAorCSAqIHVudGlsIHRoZXJlIGlzPworCSAqLworCXRyeSB7CisJICAgIHJldHVybiBpbnB1dC5hdmFpbGFibGUoKSA+IDA7CisJfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKwl9CisJcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiBhIGJ1ZmZlciB0byBiZSB1c2VkIHRvIHJlYWQgYSByZXNwb25zZS4KKyAgICAgKiBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiByZXR1cm5zIG51bGwsIHdoaWNoIGNhdXNlcworICAgICAqIGEgbmV3IGJ1ZmZlciB0byBiZSBhbGxvY2F0ZWQgZm9yIGV2ZXJ5IHJlc3BvbnNlLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgYnVmZmVyIHRvIHVzZQorICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjQuMQorICAgICAqLworICAgIHByb3RlY3RlZCBCeXRlQXJyYXkgZ2V0UmVzcG9uc2VCdWZmZXIoKSB7CisJcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyB3cml0ZUNvbW1hbmQoU3RyaW5nIGNvbW1hbmQsIEFyZ3VtZW50IGFyZ3MpIAorCQl0aHJvd3MgSU9FeGNlcHRpb24sIFByb3RvY29sRXhjZXB0aW9uIHsKKwkvLyBhc3NlcnQgVGhyZWFkLmhvbGRzTG9jayh0aGlzKTsKKwkvLyBjYW4ndCBhc3NlcnQgYmVjYXVzZSBpdCdzIGNhbGxlZCBmcm9tIGNvbnN0cnVjdG9yCisJU3RyaW5nIHRhZyA9IHRhZ1ByZWZpeCArIEludGVnZXIudG9TdHJpbmcodGFnQ291bnRlcisrKTsgLy8gdW5pcXVlIHRhZworCisJb3V0cHV0LndyaXRlQnl0ZXModGFnICsgIiAiICsgY29tbWFuZCk7CisgICAgCisJaWYgKGFyZ3MgIT0gbnVsbCkgeworCSAgICBvdXRwdXQud3JpdGUoJyAnKTsKKwkgICAgYXJncy53cml0ZSh0aGlzKTsKKwl9CisKKwlvdXRwdXQud3JpdGUoQ1JMRik7CisJb3V0cHV0LmZsdXNoKCk7CisJcmV0dXJuIHRhZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZW5kIGEgY29tbWFuZCB0byB0aGUgc2VydmVyLiBDb2xsZWN0IGFsbCByZXNwb25zZXMgdW50aWwgZWl0aGVyCisgICAgICogdGhlIGNvcnJlc3BvbmRpbmcgY29tbWFuZCBjb21wbGV0aW9uIHJlc3BvbnNlIG9yIGEgQllFIHJlc3BvbnNlIAorICAgICAqIChpbmRpY2F0aW5nIHNlcnZlciBmYWlsdXJlKS4gIFJldHVybiBhbGwgdGhlIGNvbGxlY3RlZCByZXNwb25zZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0JY29tbWFuZAl0aGUgY29tbWFuZAorICAgICAqIEBwYXJhbQlhcmdzCXRoZSBhcmd1bWVudHMKKyAgICAgKiBAcmV0dXJuCQlhcnJheSBvZiBSZXNwb25zZSBvYmplY3RzIHJldHVybmVkIGJ5IHRoZSBzZXJ2ZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIFJlc3BvbnNlW10gY29tbWFuZChTdHJpbmcgY29tbWFuZCwgQXJndW1lbnQgYXJncykgeworCWNvbW1hbmRTdGFydChjb21tYW5kKTsKKwlMaXN0PFJlc3BvbnNlPiB2ID0gbmV3IEFycmF5TGlzdDw+KCk7CisJYm9vbGVhbiBkb25lID0gZmFsc2U7CisJU3RyaW5nIHRhZyA9IG51bGw7CisKKwkvLyB3cml0ZSB0aGUgY29tbWFuZAorCXRyeSB7CisJICAgIHRhZyA9IHdyaXRlQ29tbWFuZChjb21tYW5kLCBhcmdzKTsKKwl9IGNhdGNoIChMaXRlcmFsRXhjZXB0aW9uIGxleCkgeworCSAgICB2LmFkZChsZXguZ2V0UmVzcG9uc2UoKSk7CisJICAgIGRvbmUgPSB0cnVlOworCX0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCSAgICAvLyBDb252ZXJ0IHRoaXMgaW50byBhIEJZRSByZXNwb25zZQorCSAgICB2LmFkZChSZXNwb25zZS5ieWVSZXNwb25zZShleCkpOworCSAgICBkb25lID0gdHJ1ZTsKKwl9CisKKwlSZXNwb25zZSBieWVSZXNwID0gbnVsbDsKKwl3aGlsZSAoIWRvbmUpIHsKKwkgICAgUmVzcG9uc2UgciA9IG51bGw7CisJICAgIHRyeSB7CisJCXIgPSByZWFkUmVzcG9uc2UoKTsKKwkgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9leCkgeworCQlpZiAoYnllUmVzcCA9PSBudWxsKQkvLyBjb252ZXJ0IHRoaXMgaW50byBhIEJZRSByZXNwb25zZQorCQkgICAgYnllUmVzcCA9IFJlc3BvbnNlLmJ5ZVJlc3BvbnNlKGlvZXgpOworCQkvLyBlbHNlLCBjb25uZWN0aW9uIGNsb3NlZCBhZnRlciBCWUUgd2FzIHNlbnQKKwkJYnJlYWs7CisJICAgIH0gY2F0Y2ggKFByb3RvY29sRXhjZXB0aW9uIHBleCkgeworCQlsb2dnZXIubG9nKExldmVsLkZJTkUsICJpZ25vcmluZyBiYWQgcmVzcG9uc2UiLCBwZXgpOworCQljb250aW51ZTsgLy8gc2tpcCB0aGlzIHJlc3BvbnNlCisJICAgIH0KKworCSAgICBpZiAoci5pc0JZRSgpKSB7CisJCWJ5ZVJlc3AgPSByOworCQljb250aW51ZTsKKwkgICAgfQorCisJICAgIHYuYWRkKHIpOworCisJICAgIC8vIElmIHRoaXMgaXMgYSBtYXRjaGluZyBjb21tYW5kIGNvbXBsZXRpb24gcmVzcG9uc2UsIHdlIGFyZSBkb25lCisJICAgIGlmIChyLmlzVGFnZ2VkKCkgJiYgci5nZXRUYWcoKS5lcXVhbHModGFnKSkKKwkJZG9uZSA9IHRydWU7CisJfQorCisJaWYgKGJ5ZVJlc3AgIT0gbnVsbCkKKwkJdi5hZGQoYnllUmVzcCk7CS8vIG11c3QgYmUgbGFzdAorCVJlc3BvbnNlW10gcmVzcG9uc2VzID0gbmV3IFJlc3BvbnNlW3Yuc2l6ZSgpXTsKKwl2LnRvQXJyYXkocmVzcG9uc2VzKTsKKyAgICAgICAgdGltZXN0YW1wID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisJY29tbWFuZEVuZCgpOworCXJldHVybiByZXNwb25zZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVuaWVuY2Ugcm91dGluZSB0byBoYW5kbGUgT0ssIE5PLCBCQUQgYW5kIEJZRSByZXNwb25zZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0JcmVzcG9uc2UJdGhlIHJlc3BvbnNlCisgICAgICogQGV4Y2VwdGlvbglQcm90b2NvbEV4Y2VwdGlvbglmb3IgcHJvdG9jb2wgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBoYW5kbGVSZXN1bHQoUmVzcG9uc2UgcmVzcG9uc2UpIHRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJaWYgKHJlc3BvbnNlLmlzT0soKSkKKwkgICAgcmV0dXJuOworCWVsc2UgaWYgKHJlc3BvbnNlLmlzTk8oKSkKKwkgICAgdGhyb3cgbmV3IENvbW1hbmRGYWlsZWRFeGNlcHRpb24ocmVzcG9uc2UpOworCWVsc2UgaWYgKHJlc3BvbnNlLmlzQkFEKCkpCisJICAgIHRocm93IG5ldyBCYWRDb21tYW5kRXhjZXB0aW9uKHJlc3BvbnNlKTsKKwllbHNlIGlmIChyZXNwb25zZS5pc0JZRSgpKSB7CisJICAgIGRpc2Nvbm5lY3QoKTsKKwkgICAgdGhyb3cgbmV3IENvbm5lY3Rpb25FeGNlcHRpb24odGhpcywgcmVzcG9uc2UpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZW5pZW5jZSByb3V0aW5lIHRvIGhhbmRsZSBzaW1wbGUgSUFQIGNvbW1hbmRzCisgICAgICogdGhhdCBkbyBub3QgaGF2ZSByZXNwb25zZXMgc3BlY2lmaWMgdG8gdGhhdCBjb21tYW5kLgorICAgICAqCisgICAgICogQHBhcmFtCWNtZAl0aGUgY29tbWFuZAorICAgICAqIEBwYXJhbQlhcmdzCXRoZSBhcmd1bWVudHMKKyAgICAgKiBAZXhjZXB0aW9uCVByb3RvY29sRXhjZXB0aW9uCWZvciBwcm90b2NvbCBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNpbXBsZUNvbW1hbmQoU3RyaW5nIGNtZCwgQXJndW1lbnQgYXJncykKKwkJCXRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJLy8gSXNzdWUgY29tbWFuZAorCVJlc3BvbnNlW10gciA9IGNvbW1hbmQoY21kLCBhcmdzKTsKKworCS8vIGRpc3BhdGNoIHVudGFnZ2VkIHJlc3BvbnNlcworCW5vdGlmeVJlc3BvbnNlSGFuZGxlcnMocik7CisKKwkvLyBIYW5kbGUgcmVzdWx0IG9mIHRoaXMgY29tbWFuZAorCWhhbmRsZVJlc3VsdChyW3IubGVuZ3RoLTFdKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTdGFydCBUTFMgb24gdGhlIGN1cnJlbnQgY29ubmVjdGlvbi4KKyAgICAgKiA8Y29kZT5jbWQ8L2NvZGU+IGlzIHRoZSBjb21tYW5kIHRvIGlzc3VlIHRvIHN0YXJ0IFRMUyBuZWdvdGlhdGlvbi4KKyAgICAgKiBJZiB0aGUgY29tbWFuZCBzdWNjZWVkcywgd2UgYmVnaW4gVExTIG5lZ290aWF0aW9uLgorICAgICAqIElmIHRoZSBzb2NrZXQgaXMgYWxyZWFkeSBhbiBTU0xTb2NrZXQgdGhpcyBpcyBhIG5vcCBhbmQgdGhlIGNvbW1hbmQKKyAgICAgKiBpcyBub3QgaXNzdWVkLgorICAgICAqCisgICAgICogQHBhcmFtCWNtZAl0aGUgY29tbWFuZCB0byBpc3N1ZQorICAgICAqIEBleGNlcHRpb24JSU9FeGNlcHRpb24JZm9yIEkvTyBlcnJvcnMKKyAgICAgKiBAZXhjZXB0aW9uCVByb3RvY29sRXhjZXB0aW9uCWZvciBwcm90b2NvbCBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzdGFydFRMUyhTdHJpbmcgY21kKQorCQkJCXRocm93cyBJT0V4Y2VwdGlvbiwgUHJvdG9jb2xFeGNlcHRpb24geworCWlmIChzb2NrZXQgaW5zdGFuY2VvZiBTU0xTb2NrZXQpCisJICAgIHJldHVybjsJLy8gbm90aGluZyB0byBkbworCXNpbXBsZUNvbW1hbmQoY21kLCBudWxsKTsKKwlzb2NrZXQgPSBTb2NrZXRGZXRjaGVyLnN0YXJ0VExTKHNvY2tldCwgaG9zdCwgcHJvcHMsIHByZWZpeCk7CisJaW5pdFN0cmVhbXMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTdGFydCBjb21wcmVzc2lvbiBvbiB0aGUgY3VycmVudCBjb25uZWN0aW9uLgorICAgICAqIDxjb2RlPmNtZDwvY29kZT4gaXMgdGhlIGNvbW1hbmQgdG8gaXNzdWUgdG8gc3RhcnQgY29tcHJlc3Npb24uCisgICAgICogSWYgdGhlIGNvbW1hbmQgc3VjY2VlZHMsIHdlIGJlZ2luIGNvbXByZXNzaW9uLgorICAgICAqCisgICAgICogQHBhcmFtCWNtZAl0aGUgY29tbWFuZCB0byBpc3N1ZQorICAgICAqIEBleGNlcHRpb24JSU9FeGNlcHRpb24JZm9yIEkvTyBlcnJvcnMKKyAgICAgKiBAZXhjZXB0aW9uCVByb3RvY29sRXhjZXB0aW9uCWZvciBwcm90b2NvbCBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzdGFydENvbXByZXNzaW9uKFN0cmluZyBjbWQpCisJCQkJdGhyb3dzIElPRXhjZXB0aW9uLCBQcm90b2NvbEV4Y2VwdGlvbiB7CisJLy8gWFhYIC0gY2hlY2sgd2hldGhlciBjb21wcmVzc2lvbiBpcyBhbHJlYWR5IGVuYWJsZWQ/CisJc2ltcGxlQ29tbWFuZChjbWQsIG51bGwpOworCisJLy8gbmVlZCB0byBjcmVhdGUgb3VyIG93biBJbmZsYXRlciBhbmQgRGVmbGF0ZXIgaW4gb3JkZXIgdG8gc2V0IG5vd3JhcAorCUluZmxhdGVyIGluZiA9IG5ldyBJbmZsYXRlcih0cnVlKTsKKwl0cmFjZUlucHV0ID0gbmV3IFRyYWNlSW5wdXRTdHJlYW0obmV3IEluZmxhdGVySW5wdXRTdHJlYW0oCisJCQkgICAgc29ja2V0LmdldElucHV0U3RyZWFtKCksIGluZiksIHRyYWNlTG9nZ2VyKTsKKwl0cmFjZUlucHV0LnNldFF1b3RlKHF1b3RlKTsKKwlpbnB1dCA9IG5ldyBSZXNwb25zZUlucHV0U3RyZWFtKHRyYWNlSW5wdXQpOworCisJLy8gY29uZmlndXJlIHRoZSBEZWZsYXRlcgorCWludCBsZXZlbCA9IFByb3BVdGlsLmdldEludFByb3BlcnR5KHByb3BzLCBwcmVmaXggKyAiLmNvbXByZXNzLmxldmVsIiwKKwkJCQkJCURlZmxhdGVyLkRFRkFVTFRfQ09NUFJFU1NJT04pOworCWludCBzdHJhdGVneSA9IFByb3BVdGlsLmdldEludFByb3BlcnR5KHByb3BzLAorCQkJCQkJcHJlZml4ICsgIi5jb21wcmVzcy5zdHJhdGVneSIsCisJCQkJCQlEZWZsYXRlci5ERUZBVUxUX1NUUkFURUdZKTsKKwlpZiAobG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuRklORSkpCisJICAgIGxvZ2dlci5sb2coTGV2ZWwuRklORSwKKwkJIkNyZWF0aW5nIERlZmxhdGVyIHdpdGggY29tcHJlc3Npb24gbGV2ZWwgezB9IGFuZCBzdHJhdGVneSB7MX0iLAorCQluZXcgT2JqZWN0W10geyBsZXZlbCwgc3RyYXRlZ3kgfSk7CisJRGVmbGF0ZXIgZGVmID0gbmV3IERlZmxhdGVyKERlZmxhdGVyLkRFRkFVTFRfQ09NUFJFU1NJT04sIHRydWUpOworCXRyeSB7CisJICAgIGRlZi5zZXRMZXZlbChsZXZlbCk7CisJfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4KSB7CisJICAgIGxvZ2dlci5sb2coTGV2ZWwuRklORSwgIklnbm9yaW5nIGJhZCBjb21wcmVzc2lvbiBsZXZlbCIsIGV4KTsKKwl9CisJdHJ5IHsKKwkgICAgZGVmLnNldFN0cmF0ZWd5KHN0cmF0ZWd5KTsKKwl9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXgpIHsKKwkgICAgbG9nZ2VyLmxvZyhMZXZlbC5GSU5FLCAiSWdub3JpbmcgYmFkIGNvbXByZXNzaW9uIHN0cmF0ZWd5IiwgZXgpOworCX0KKwl0cmFjZU91dHB1dCA9IG5ldyBUcmFjZU91dHB1dFN0cmVhbShuZXcgRGVmbGF0ZXJPdXRwdXRTdHJlYW0oCisJCQkgICAgc29ja2V0LmdldE91dHB1dFN0cmVhbSgpLCBkZWYsIHRydWUpLCB0cmFjZUxvZ2dlcik7CisJdHJhY2VPdXRwdXQuc2V0UXVvdGUocXVvdGUpOworCW91dHB1dCA9IG5ldyBEYXRhT3V0cHV0U3RyZWFtKG5ldyBCdWZmZXJlZE91dHB1dFN0cmVhbSh0cmFjZU91dHB1dCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIElzIHRoaXMgY29ubmVjdGlvbiB1c2luZyBhbiBTU0wgc29ja2V0PworICAgICAqCisgICAgICogQHJldHVybgl0cnVlIGlmIHVzaW5nIFNTTAorICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjQuNgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzU1NMKCkgeworCXJldHVybiBzb2NrZXQgaW5zdGFuY2VvZiBTU0xTb2NrZXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBhZGRyZXNzIHRoZSBzb2NrZXQgY29ubmVjdGVkIHRvLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgSW5ldEFkZHJlc3MgdGhlIHNvY2tldCBpcyBjb25uZWN0ZWQgdG8KKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS41LjIKKyAgICAgKi8KKyAgICBwdWJsaWMgSW5ldEFkZHJlc3MgZ2V0SW5ldEFkZHJlc3MoKSB7CisJcmV0dXJuIHNvY2tldC5nZXRJbmV0QWRkcmVzcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgU29ja2V0Q2hhbm5lbCBhc3NvY2lhdGVkIHdpdGggdGhpcyBjb25uZWN0aW9uLCBpZiBhbnkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBTb2NrZXRDaGFubmVsCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNS4yCisgICAgICovCisgICAgcHVibGljIFNvY2tldENoYW5uZWwgZ2V0Q2hhbm5lbCgpIHsKKwlTb2NrZXRDaGFubmVsIHJldCA9IHNvY2tldC5nZXRDaGFubmVsKCk7CisJaWYgKHJldCAhPSBudWxsKQorCSAgICByZXR1cm4gcmV0OworCisJLy8gWFhYIC0gQW5kcm9pZCBpcyBicm9rZW4gYW5kIFNTTCB3cmFwcGVkIHNvY2tldHMgZG9uJ3QgZGVsZWdhdGUKKwkvLyB0aGUgZ2V0Q2hhbm5lbCBtZXRob2QgdG8gdGhlIHdyYXBwZWQgU29ja2V0CisJaWYgKHNvY2tldCBpbnN0YW5jZW9mIFNTTFNvY2tldCkgeworCSAgICB0cnkgeworCQlGaWVsZCBmID0gc29ja2V0LmdldENsYXNzKCkuZ2V0RGVjbGFyZWRGaWVsZCgic29ja2V0Iik7CisJCWYuc2V0QWNjZXNzaWJsZSh0cnVlKTsKKwkJU29ja2V0IHMgPSAoU29ja2V0KWYuZ2V0KHNvY2tldCk7CisJCXJldCA9IHMuZ2V0Q2hhbm5lbCgpOworCSAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKwkJLy8gaWdub3JlIGFueXRoaW5nIHRoYXQgbWlnaHQgZ28gd3JvbmcKKwkgICAgfQorCX0KKwlyZXR1cm4gcmV0OworICAgIH0KKworICAgIC8qKgorICAgICAqIERvZXMgdGhlIHNlcnZlciBzdXBwb3J0IFVURi04PworICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gcmV0dXJucyBmYWxzZS4KKyAgICAgKiBTdWJjbGFzc2VzIHNob3VsZCBvdmVycmlkZSBhcyBhcHByb3ByaWF0ZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdHJ1ZSBpZiB0aGUgc2VydmVyIHN1cHBvcnRzIFVURi04CisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNi4wCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gc3VwcG9ydHNVdGY4KCkgeworCXJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEaXNjb25uZWN0LgorICAgICAqLworICAgIHByb3RlY3RlZCBzeW5jaHJvbml6ZWQgdm9pZCBkaXNjb25uZWN0KCkgeworCWlmIChzb2NrZXQgIT0gbnVsbCkgeworCSAgICB0cnkgeworCQlzb2NrZXQuY2xvc2UoKTsKKwkgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworCQkvLyBpZ25vcmUgaXQKKwkgICAgfQorCSAgICBzb2NrZXQgPSBudWxsOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIG5hbWUgb2YgdGhlIGxvY2FsIGhvc3QuCisgICAgICogVGhlIHByb3BlcnR5ICZsdDtwcmVmaXgmZ3Q7LmxvY2FsaG9zdCBvdmVycmlkZXMKKyAgICAgKiAmbHQ7cHJlZml4Jmd0Oy5sb2NhbGFkZHJlc3MsCisgICAgICogd2hpY2ggb3ZlcnJpZGVzIHdoYXQgSW5ldEFkZHJlc3Mgd291bGQgdGVsbCB1cy4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIG5hbWUgb2YgdGhlIGxvY2FsIGhvc3QKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3luY2hyb25pemVkIFN0cmluZyBnZXRMb2NhbEhvc3QoKSB7CisJLy8gZ2V0IG91ciBob3N0bmFtZSBhbmQgY2FjaGUgaXQgZm9yIGZ1dHVyZSB1c2UKKwlpZiAobG9jYWxIb3N0TmFtZSA9PSBudWxsIHx8IGxvY2FsSG9zdE5hbWUubGVuZ3RoKCkgPD0gMCkKKwkgICAgbG9jYWxIb3N0TmFtZSA9CisJCSAgICBwcm9wcy5nZXRQcm9wZXJ0eShwcmVmaXggKyAiLmxvY2FsaG9zdCIpOworCWlmIChsb2NhbEhvc3ROYW1lID09IG51bGwgfHwgbG9jYWxIb3N0TmFtZS5sZW5ndGgoKSA8PSAwKQorCSAgICBsb2NhbEhvc3ROYW1lID0KKwkJICAgIHByb3BzLmdldFByb3BlcnR5KHByZWZpeCArICIubG9jYWxhZGRyZXNzIik7CisJdHJ5IHsKKwkgICAgaWYgKGxvY2FsSG9zdE5hbWUgPT0gbnVsbCB8fCBsb2NhbEhvc3ROYW1lLmxlbmd0aCgpIDw9IDApIHsKKwkJSW5ldEFkZHJlc3MgbG9jYWxIb3N0ID0gSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCk7CisJCWxvY2FsSG9zdE5hbWUgPSBsb2NhbEhvc3QuZ2V0Q2Fub25pY2FsSG9zdE5hbWUoKTsKKwkJLy8gaWYgd2UgY2FuJ3QgZ2V0IG91ciBuYW1lLCB1c2UgbG9jYWwgYWRkcmVzcyBsaXRlcmFsCisJCWlmIChsb2NhbEhvc3ROYW1lID09IG51bGwpCisJCSAgICAvLyBYWFggLSBub3QgY29ycmVjdCBmb3IgSVB2NgorCQkgICAgbG9jYWxIb3N0TmFtZSA9ICJbIiArIGxvY2FsSG9zdC5nZXRIb3N0QWRkcmVzcygpICsgIl0iOworCSAgICB9CisJfSBjYXRjaCAoVW5rbm93bkhvc3RFeGNlcHRpb24gdWhleCkgeworCX0KKworCS8vIGxhc3QgY2hhbmNlLCB0cnkgdG8gZ2V0IG91ciBhZGRyZXNzIGZyb20gb3VyIHNvY2tldAorCWlmIChsb2NhbEhvc3ROYW1lID09IG51bGwgfHwgbG9jYWxIb3N0TmFtZS5sZW5ndGgoKSA8PSAwKSB7CisJICAgIGlmIChzb2NrZXQgIT0gbnVsbCAmJiBzb2NrZXQuaXNCb3VuZCgpKSB7CisJCUluZXRBZGRyZXNzIGxvY2FsSG9zdCA9IHNvY2tldC5nZXRMb2NhbEFkZHJlc3MoKTsKKwkJbG9jYWxIb3N0TmFtZSA9IGxvY2FsSG9zdC5nZXRDYW5vbmljYWxIb3N0TmFtZSgpOworCQkvLyBpZiB3ZSBjYW4ndCBnZXQgb3VyIG5hbWUsIHVzZSBsb2NhbCBhZGRyZXNzIGxpdGVyYWwKKwkJaWYgKGxvY2FsSG9zdE5hbWUgPT0gbnVsbCkKKwkJICAgIC8vIFhYWCAtIG5vdCBjb3JyZWN0IGZvciBJUHY2CisJCSAgICBsb2NhbEhvc3ROYW1lID0gIlsiICsgbG9jYWxIb3N0LmdldEhvc3RBZGRyZXNzKCkgKyAiXSI7CisJICAgIH0KKwl9CisJcmV0dXJuIGxvY2FsSG9zdE5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogSXMgcHJvdG9jb2wgdHJhY2luZyBlbmFibGVkPworICAgICAqCisgICAgICogQHJldHVybgl0cnVlIGlmIHByb3RvY29sIHRyYWNpbmcgaXMgZW5hYmxlZAorICAgICAqLworICAgIHByb3RlY3RlZCBib29sZWFuIGlzVHJhY2luZygpIHsKKwlyZXR1cm4gdHJhY2VMb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FU1QpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlbXBvcmFyaWx5IHR1cm4gb2ZmIHByb3RvY29sIHRyYWNpbmcsIGUuZy4sIHRvIHByZXZlbnQKKyAgICAgKiB0cmFjaW5nIHRoZSBhdXRoZW50aWNhdGlvbiBzZXF1ZW5jZSwgaW5jbHVkaW5nIHRoZSBwYXNzd29yZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzdXNwZW5kVHJhY2luZygpIHsKKwlpZiAodHJhY2VMb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FU1QpKSB7CisJICAgIHRyYWNlSW5wdXQuc2V0VHJhY2UoZmFsc2UpOworCSAgICB0cmFjZU91dHB1dC5zZXRUcmFjZShmYWxzZSk7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlc3VtZSBwcm90b2NvbCB0cmFjaW5nLCBpZiBpdCB3YXMgZW5hYmxlZCB0byBiZWdpbiB3aXRoLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHJlc3VtZVRyYWNpbmcoKSB7CisJaWYgKHRyYWNlTG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuRklORVNUKSkgeworCSAgICB0cmFjZUlucHV0LnNldFRyYWNlKHRydWUpOworCSAgICB0cmFjZU91dHB1dC5zZXRUcmFjZSh0cnVlKTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogRmluYWxpemVyLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIGZpbmFsaXplKCkgdGhyb3dzIFRocm93YWJsZSB7CisJdHJ5IHsKKwkgICAgZGlzY29ubmVjdCgpOworCX0gZmluYWxseSB7CisJICAgIHN1cGVyLmZpbmFsaXplKCk7CisJfQorICAgIH0KKworICAgIC8qCisgICAgICogUHJvYmUgcG9pbnRzIGZvciBHbGFzc0Zpc2ggbW9uaXRvcmluZy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgY29tbWFuZFN0YXJ0KFN0cmluZyBjb21tYW5kKSB7IH0KKyAgICBwcml2YXRlIHZvaWQgY29tbWFuZEVuZCgpIHsgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pYXAvUHJvdG9jb2xFeGNlcHRpb24uamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaWFwL1Byb3RvY29sRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjRkOWUzYQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaWFwL1Byb3RvY29sRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw3MyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuaWFwOworCisvKioKKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKi8KKworcHVibGljIGNsYXNzIFByb3RvY29sRXhjZXB0aW9uIGV4dGVuZHMgRXhjZXB0aW9uIHsKKyAgICBwcm90ZWN0ZWQgdHJhbnNpZW50IFJlc3BvbnNlIHJlc3BvbnNlID0gbnVsbDsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC00MzYwNTAwODA3OTcxNzk3NDM5TDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBQcm90b2NvbEV4Y2VwdGlvbiB3aXRoIG5vIGRldGFpbCBtZXNzYWdlLgorICAgICAqLworICAgIHB1YmxpYyBQcm90b2NvbEV4Y2VwdGlvbigpIHsKKwlzdXBlcigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBQcm90b2NvbEV4Y2VwdGlvbiB3aXRoIHRoZSBzcGVjaWZpZWQgZGV0YWlsIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWVzc2FnZQkJdGhlIGRldGFpbCBtZXNzYWdlCisgICAgICovCisgICAgcHVibGljIFByb3RvY29sRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlKSB7CisJc3VwZXIobWVzc2FnZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIFByb3RvY29sRXhjZXB0aW9uIHdpdGggdGhlIHNwZWNpZmllZCBkZXRhaWwgbWVzc2FnZQorICAgICAqIGFuZCBjYXVzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtZXNzYWdlCQl0aGUgZGV0YWlsIG1lc3NhZ2UKKyAgICAgKiBAcGFyYW0gY2F1c2UJCXRoZSBjYXVzZQorICAgICAqLworICAgIHB1YmxpYyBQcm90b2NvbEV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSwgVGhyb3dhYmxlIGNhdXNlKSB7CisJc3VwZXIobWVzc2FnZSwgY2F1c2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBQcm90b2NvbEV4Y2VwdGlvbiB3aXRoIHRoZSBzcGVjaWZpZWQgUmVzcG9uc2Ugb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtCXIJdGhlIFJlc3BvbnNlCisgICAgICovCisgICAgcHVibGljIFByb3RvY29sRXhjZXB0aW9uKFJlc3BvbnNlIHIpIHsKKwlzdXBlcihyLnRvU3RyaW5nKCkpOworCXJlc3BvbnNlID0gcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIG9mZmVuZGluZyBSZXNwb25zZSBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBSZXNwb25zZSBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgUmVzcG9uc2UgZ2V0UmVzcG9uc2UoKSB7CisJcmV0dXJuIHJlc3BvbnNlOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaWFwL1Jlc3BvbnNlLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2lhcC9SZXNwb25zZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNiZWM5ZTQKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2lhcC9SZXNwb25zZS5qYXZhCkBAIC0wLDAgKzEsNjAwIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5pYXA7CisKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YS51dGlsLio7CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5TdGFuZGFyZENoYXJzZXRzOworCitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuQVNDSUlVdGlsaXR5OworCisvKioKKyAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhIHJlc3BvbnNlIG9idGFpbmVkIGZyb20gdGhlIGlucHV0IHN0cmVhbQorICogb2YgYW4gSU1BUCBzZXJ2ZXIuCisgKgorICogQGF1dGhvciBKb2huIE1hbmkKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKi8KKworcHVibGljIGNsYXNzIFJlc3BvbnNlIHsKKyAgICBwcm90ZWN0ZWQgaW50IGluZGV4OyAgLy8gaW50ZXJuYWwgaW5kZXggKHVwZGF0ZWQgZHVyaW5nIHRoZSBwYXJzZSkKKyAgICBwcm90ZWN0ZWQgaW50IHBpbmRleDsgLy8gaW5kZXggYWZ0ZXIgcGFyc2UsIGZvciByZXNldAorICAgIHByb3RlY3RlZCBpbnQgc2l6ZTsgICAvLyBudW1iZXIgb2YgdmFsaWQgYnl0ZXMgaW4gb3VyIGJ1ZmZlcgorICAgIHByb3RlY3RlZCBieXRlW10gYnVmZmVyID0gbnVsbDsKKyAgICBwcm90ZWN0ZWQgaW50IHR5cGUgPSAwOworICAgIHByb3RlY3RlZCBTdHJpbmcgdGFnID0gbnVsbDsKKyAgICAvKiogQHNpbmNlIEphdmFNYWlsIDEuNS40ICovCisgICAgcHJvdGVjdGVkIEV4Y2VwdGlvbiBleDsKKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiB1dGY4OworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IGluY3JlbWVudCA9IDEwMDsKKworICAgIC8vIFRoZSBmaXJzdCBhbmQgc2Vjb25kIGJpdHMgaW5kaWNhdGUgd2hldGhlciB0aGlzIHJlc3BvbnNlCisgICAgLy8gaXMgYSBDb250aW51YXRpb24sIFRhZ2dlZCBvciBVbnRhZ2dlZAorICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IFRBR19NQVNLIAkgPSAweDAzOworICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IENPTlRJTlVBVElPTiA9IDB4MDE7CisgICAgcHVibGljIGZpbmFsIHN0YXRpYyBpbnQgVEFHR0VEIAkgPSAweDAyOworICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IFVOVEFHR0VEIAkgPSAweDAzOworCisgICAgLy8gVGhlIHRoaXJkLCBmb3VydGggYW5kIGZpZnRoIGJpdHMgaW5kaWNhdGUgd2hldGhlciB0aGlzIHJlc3BvbnNlCisgICAgLy8gaXMgYW4gT0ssIE5PLCBCQUQgb3IgQllFIHJlc3BvbnNlCisgICAgcHVibGljIGZpbmFsIHN0YXRpYyBpbnQgVFlQRV9NQVNLIAkgPSAweDFDOworICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IE9LIAkgCSA9IDB4MDQ7CisgICAgcHVibGljIGZpbmFsIHN0YXRpYyBpbnQgTk8gCSAJID0gMHgwODsKKyAgICBwdWJsaWMgZmluYWwgc3RhdGljIGludCBCQUQJIAkgPSAweDBDOworICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IEJZRQkgCSA9IDB4MTA7CisKKyAgICAvLyBUaGUgc2l4dGggYml0IGluZGljYXRlcyB3aGV0aGVyIGEgQllFIHJlc3BvbnNlIGlzIHN5bnRoZXRpYyBvciByZWFsCisgICAgcHVibGljIGZpbmFsIHN0YXRpYyBpbnQgU1lOVEhFVElDIAkgPSAweDIwOworCisgICAgLyoqCisgICAgICogQW4gQVRPTSBpcyBhbnkgQ0hBUiBkZWxpbWl0ZWQgYnk6CisgICAgICogU1BBQ0UgfCBDVEwgfCAnKCcgfCAnKScgfCAneycgfCAnJScgfCAnKicgfCAnIicgfCAnXCcgfCAnXScKKyAgICAgKiAoQ1RMIGlzIGhhbmRsZWQgaW4gcmVhZERlbGltU3RyaW5nLikKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgQVRPTV9DSEFSX0RFTElNID0gIiAoKXslKlwiXFxdIjsKKworICAgIC8qKgorICAgICAqIEFuIEFTVFJJTkdfQ0hBUiBpcyBhbnkgQ0hBUiBkZWxpbWl0ZWQgYnk6CisgICAgICogU1BBQ0UgfCBDVEwgfCAnKCcgfCAnKScgfCAneycgfCAnJScgfCAnKicgfCAnIicgfCAnXCcKKyAgICAgKiAoQ1RMIGlzIGhhbmRsZWQgaW4gcmVhZERlbGltU3RyaW5nLikKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgQVNUUklOR19DSEFSX0RFTElNID0gIiAoKXslKlwiXFwiOworCisgICAgcHVibGljIFJlc3BvbnNlKFN0cmluZyBzKSB7CisJdGhpcyhzLCB0cnVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvciBmb3IgdGVzdGluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbQlzCXRoZSByZXNwb25zZSBzdHJpbmcKKyAgICAgKiBAcGFyYW0Jc3VwcG9ydHNVdGY4CWFsbG93IFVURi04IGluIHJlc3BvbnNlPworICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjYuMAorICAgICAqLworICAgIHB1YmxpYyBSZXNwb25zZShTdHJpbmcgcywgYm9vbGVhbiBzdXBwb3J0c1V0ZjgpIHsKKwlpZiAoc3VwcG9ydHNVdGY4KQorCSAgICBidWZmZXIgPSBzLmdldEJ5dGVzKFN0YW5kYXJkQ2hhcnNldHMuVVRGXzgpOworCWVsc2UKKwkgICAgYnVmZmVyID0gcy5nZXRCeXRlcyhTdGFuZGFyZENoYXJzZXRzLlVTX0FTQ0lJKTsKKwlzaXplID0gYnVmZmVyLmxlbmd0aDsKKwl1dGY4ID0gc3VwcG9ydHNVdGY4OworCXBhcnNlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZCBhIG5ldyBSZXNwb25zZSBmcm9tIHRoZSBnaXZlbiBQcm90b2NvbAorICAgICAqCisgICAgICogQHBhcmFtCXAJdGhlIFByb3RvY29sIG9iamVjdAorICAgICAqIEBleGNlcHRpb24JSU9FeGNlcHRpb24JZm9yIEkvTyBlcnJvcnMKKyAgICAgKiBAZXhjZXB0aW9uCVByb3RvY29sRXhjZXB0aW9uCWZvciBwcm90b2NvbCBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBSZXNwb25zZShQcm90b2NvbCBwKSB0aHJvd3MgSU9FeGNlcHRpb24sIFByb3RvY29sRXhjZXB0aW9uIHsKKwkvLyByZWFkIG9uZSByZXNwb25zZSBpbnRvICdidWZmZXInCisJQnl0ZUFycmF5IGJhID0gcC5nZXRSZXNwb25zZUJ1ZmZlcigpOworCUJ5dGVBcnJheSByZXNwb25zZSA9IHAuZ2V0SW5wdXRTdHJlYW0oKS5yZWFkUmVzcG9uc2UoYmEpOworCWJ1ZmZlciA9IHJlc3BvbnNlLmdldEJ5dGVzKCk7CisJc2l6ZSA9IHJlc3BvbnNlLmdldENvdW50KCkgLSAyOyAvLyBTa2lwIHRoZSB0ZXJtaW5hdGluZyBDUkxGCisJdXRmOCA9IHAuc3VwcG9ydHNVdGY4KCk7CisKKwlwYXJzZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvcHkgY29uc3RydWN0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jcgl0aGUgUmVzcG9uc2UgdG8gY29weQorICAgICAqLworICAgIHB1YmxpYyBSZXNwb25zZShSZXNwb25zZSByKSB7CisJaW5kZXggPSByLmluZGV4OworCXBpbmRleCA9IHIucGluZGV4OworCXNpemUgPSByLnNpemU7CisJYnVmZmVyID0gci5idWZmZXI7CisJdHlwZSA9IHIudHlwZTsKKwl0YWcgPSByLnRhZzsKKwlleCA9IHIuZXg7CisJdXRmOCA9IHIudXRmODsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYSBSZXNwb25zZSBvYmplY3QgdGhhdCBsb29rcyBsaWtlIGEgQllFIHByb3RvY29sIHJlc3BvbnNlLgorICAgICAqIEluY2x1ZGUgdGhlIGRldGFpbHMgb2YgdGhlIGV4Y2VwdGlvbiBpbiB0aGUgcmVzcG9uc2Ugc3RyaW5nLgorICAgICAqCisgICAgICogQHBhcmFtCWV4CXRoZSBleGNlcHRpb24KKyAgICAgKiBAcmV0dXJuCQl0aGUgc3ludGhldGljIFJlc3BvbnNlIG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgUmVzcG9uc2UgYnllUmVzcG9uc2UoRXhjZXB0aW9uIGV4KSB7CisJU3RyaW5nIGVyciA9ICIqIEJZRSBKYXZhTWFpbCBFeGNlcHRpb246ICIgKyBleC50b1N0cmluZygpOworCWVyciA9IGVyci5yZXBsYWNlKCdccicsICcgJykucmVwbGFjZSgnXG4nLCAnICcpOworCVJlc3BvbnNlIHIgPSBuZXcgUmVzcG9uc2UoZXJyKTsKKwlyLnR5cGUgfD0gU1lOVEhFVElDOworCXIuZXggPSBleDsKKwlyZXR1cm4gcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEb2VzIHRoZSBzZXJ2ZXIgc3VwcG9ydCBVVEYtOD8KKyAgICAgKgorICAgICAqIEByZXR1cm4JCXRydWUgaWYgdGhlIHNlcnZlciBzdXBwb3J0cyBVVEYtOAorICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjYuMAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHN1cHBvcnRzVXRmOCgpIHsKKwlyZXR1cm4gdXRmODsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgcGFyc2UoKSB7CisJaW5kZXggPSAwOyAvLyBwb3NpdGlvbiBpbnRlcm5hbCBpbmRleCBhdCBzdGFydAorCisJaWYgKHNpemUgPT0gMCkJLy8gZW1wdHkgbGluZQorCSAgICByZXR1cm47CisJaWYgKGJ1ZmZlcltpbmRleF0gPT0gJysnKSB7IC8vIENvbnRpbnVhdGlvbiBzdGF0ZW1lbnQKKwkgICAgdHlwZSB8PSBDT05USU5VQVRJT047CisJICAgIGluZGV4ICs9IDE7IC8vIFBvc2l0aW9uIGJleW9uZCB0aGUgJysnCisJICAgIHJldHVybjsJLy8gcmV0dXJuCisJfSBlbHNlIGlmIChidWZmZXJbaW5kZXhdID09ICcqJykgeyAvLyBVbnRhZ2dlZCBzdGF0ZW1lbnQKKwkgICAgdHlwZSB8PSBVTlRBR0dFRDsKKwkgICAgaW5kZXggKz0gMTsgLy8gUG9zaXRpb24gYmV5b25kIHRoZSAnKicKKwl9IGVsc2UgeyAgLy8gVGFnZ2VkIHN0YXRlbWVudAorCSAgICB0eXBlIHw9IFRBR0dFRDsKKwkgICAgdGFnID0gcmVhZEF0b20oKTsJLy8gcmVhZCB0aGUgVEFHLCBpbmRleCBwb3NpdGlvbmVkIGJleW9uZCB0YWcKKwkgICAgaWYgKHRhZyA9PSBudWxsKQorCQl0YWcgPSAiIjsJLy8gYXZvaWQgcG9zc2libGUgTlBFCisJfQorCisJaW50IG1hcmsgPSBpbmRleDsgLy8gbWFyaworCVN0cmluZyBzID0gcmVhZEF0b20oKTsJLy8gdXBkYXRlcyBpbmRleAorCWlmIChzID09IG51bGwpCisJICAgIHMgPSAiIjsJCS8vIGF2b2lkIHBvc3NpYmxlIE5QRQorCWlmIChzLmVxdWFsc0lnbm9yZUNhc2UoIk9LIikpCisJICAgIHR5cGUgfD0gT0s7CisJZWxzZSBpZiAocy5lcXVhbHNJZ25vcmVDYXNlKCJOTyIpKQorCSAgICB0eXBlIHw9IE5POworCWVsc2UgaWYgKHMuZXF1YWxzSWdub3JlQ2FzZSgiQkFEIikpCisJICAgIHR5cGUgfD0gQkFEOworCWVsc2UgaWYgKHMuZXF1YWxzSWdub3JlQ2FzZSgiQllFIikpCisJICAgIHR5cGUgfD0gQllFOworCWVsc2UKKwkgICAgaW5kZXggPSBtYXJrOyAvLyByZXNldAorCisJcGluZGV4ID0gaW5kZXg7CisJcmV0dXJuOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNraXBTcGFjZXMoKSB7CisJd2hpbGUgKGluZGV4IDwgc2l6ZSAmJiBidWZmZXJbaW5kZXhdID09ICcgJykKKwkgICAgaW5kZXgrKzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTa2lwIHBhc3QgYW55IHNwYWNlcy4gIElmIHRoZSBuZXh0IG5vbi1zcGFjZSBjaGFyYWN0ZXIgaXMgYywKKyAgICAgKiBjb25zdW1lIGl0IGFuZCByZXR1cm4gdHJ1ZS4gIE90aGVyd2lzZSBzdG9wIGF0IHRoYXQgcG9pbnQKKyAgICAgKiBhbmQgcmV0dXJuIGZhbHNlLgorICAgICAqCisgICAgICogQHBhcmFtCWMJdGhlIGNoYXJhY3RlciB0byBsb29rIGZvcgorICAgICAqIEByZXR1cm4JCXRydWUgaWYgdGhlIGNoYXJhY3RlciBpcyBmb3VuZAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzTmV4dE5vblNwYWNlKGNoYXIgYykgeworCXNraXBTcGFjZXMoKTsKKwlpZiAoaW5kZXggPCBzaXplICYmIGJ1ZmZlcltpbmRleF0gPT0gKGJ5dGUpYykgeworCSAgICBpbmRleCsrOworCSAgICByZXR1cm4gdHJ1ZTsKKwl9CisJcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNraXAgdG8gdGhlIG5leHQgc3BhY2UsIGZvciB1c2UgaW4gZXJyb3IgcmVjb3Zlcnkgd2hpbGUgcGFyc2luZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBza2lwVG9rZW4oKSB7CisJd2hpbGUgKGluZGV4IDwgc2l6ZSAmJiBidWZmZXJbaW5kZXhdICE9ICcgJykKKwkgICAgaW5kZXgrKzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBza2lwKGludCBjb3VudCkgeworCWluZGV4ICs9IGNvdW50OworICAgIH0KKworICAgIHB1YmxpYyBieXRlIHBlZWtCeXRlKCkgeworCWlmIChpbmRleCA8IHNpemUpCisJICAgIHJldHVybiBidWZmZXJbaW5kZXhdOworCWVsc2UKKwkgICAgcmV0dXJuIDA7CQkvLyBYWFggLSBob3cgZWxzZSB0byBzaWduYWwgZXJyb3I/CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBuZXh0IGJ5dGUgZnJvbSB0aGlzIFN0YXRlbWVudC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIG5leHQgYnl0ZQorICAgICAqLworICAgIHB1YmxpYyBieXRlIHJlYWRCeXRlKCkgeworCWlmIChpbmRleCA8IHNpemUpCisJICAgIHJldHVybiBidWZmZXJbaW5kZXgrK107CisJZWxzZQorCSAgICByZXR1cm4gMDsJCS8vIFhYWCAtIGhvdyBlbHNlIHRvIHNpZ25hbCBlcnJvcj8KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFeHRyYWN0IGFuIEFUT00sIHN0YXJ0aW5nIGF0IHRoZSBjdXJyZW50IHBvc2l0aW9uLiBVcGRhdGVzCisgICAgICogdGhlIGludGVybmFsIGluZGV4IHRvIGJleW9uZCB0aGUgQXRvbS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYW4gQXRvbQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgcmVhZEF0b20oKSB7CisJcmV0dXJuIHJlYWREZWxpbVN0cmluZyhBVE9NX0NIQVJfREVMSU0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIEV4dHJhY3QgYSBzdHJpbmcgc3RvcHBpbmcgYXQgY29udHJvbCBjaGFyYWN0ZXJzIG9yIGFueQorICAgICAqIGNoYXJhY3RlciBpbiBkZWxpbS4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyByZWFkRGVsaW1TdHJpbmcoU3RyaW5nIGRlbGltKSB7CisJc2tpcFNwYWNlcygpOworCisJaWYgKGluZGV4ID49IHNpemUpIC8vIGFscmVhZHkgYXQgZW5kIG9mIHJlc3BvbnNlCisJICAgIHJldHVybiBudWxsOworCisJaW50IGI7CisJaW50IHN0YXJ0ID0gaW5kZXg7CisJd2hpbGUgKGluZGV4IDwgc2l6ZSAmJiAoKGIgPSAoKChpbnQpYnVmZmVyW2luZGV4XSkmMHhmZikpID49ICcgJykgJiYKKwkgICAgICAgZGVsaW0uaW5kZXhPZigoY2hhciliKSA8IDAgJiYgYiAhPSAweDdmKQorCSAgICBpbmRleCsrOworCisJcmV0dXJuIHRvU3RyaW5nKGJ1ZmZlciwgc3RhcnQsIGluZGV4KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkIGEgc3RyaW5nIGFzIGFuIGFyYml0cmFyeSBzZXF1ZW5jZSBvZiBjaGFyYWN0ZXJzLAorICAgICAqIHN0b3BwaW5nIGF0IHRoZSBkZWxpbWl0ZXIgIFVzZWQgdG8gcmVhZCBwYXJ0IG9mIGEKKyAgICAgKiByZXNwb25zZSBjb2RlIGluc2lkZSBbXS4KKyAgICAgKgorICAgICAqIEBwYXJhbQlkZWxpbQl0aGUgZGVsaW1pdGVyIGNoYXJhY3RlcgorICAgICAqIEByZXR1cm4JCXRoZSBzdHJpbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIHJlYWRTdHJpbmcoY2hhciBkZWxpbSkgeworCXNraXBTcGFjZXMoKTsKKworCWlmIChpbmRleCA+PSBzaXplKSAvLyBhbHJlYWR5IGF0IGVuZCBvZiByZXNwb25zZQorCSAgICByZXR1cm4gbnVsbDsKKworCWludCBzdGFydCA9IGluZGV4OworCXdoaWxlIChpbmRleCA8IHNpemUgJiYgYnVmZmVyW2luZGV4XSAhPSBkZWxpbSkKKwkgICAgaW5kZXgrKzsKKworCXJldHVybiB0b1N0cmluZyhidWZmZXIsIHN0YXJ0LCBpbmRleCk7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZ1tdIHJlYWRTdHJpbmdMaXN0KCkgeworCXJldHVybiByZWFkU3RyaW5nTGlzdChmYWxzZSk7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZ1tdIHJlYWRBdG9tU3RyaW5nTGlzdCgpIHsKKwlyZXR1cm4gcmVhZFN0cmluZ0xpc3QodHJ1ZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBTdHJpbmdbXSByZWFkU3RyaW5nTGlzdChib29sZWFuIGF0b20pIHsKKwlza2lwU3BhY2VzKCk7CisKKwlpZiAoYnVmZmVyW2luZGV4XSAhPSAnKCcpIHsgLy8gbm90IHdoYXQgd2UgZXhwZWN0ZWQKKwkgICAgcmV0dXJuIG51bGw7CisJfQorCWluZGV4Kys7IC8vIHNraXAgJygnCisKKwkvLyB0byBoYW5kbGUgYnVnZ3kgSU1BUCBzZXJ2ZXJzLCB3ZSB0b2xlcmF0ZSBtdWx0aXBsZSBzcGFjZXMgYXMKKwkvLyB3ZWxsIGFzIHNwYWNlcyBhZnRlciB0aGUgbGVmdCBwYXJlbiBvciBiZWZvcmUgdGhlIHJpZ2h0IHBhcmVuCisJTGlzdDxTdHJpbmc+IHJlc3VsdCA9IG5ldyBBcnJheUxpc3Q8PigpOworCXdoaWxlICghaXNOZXh0Tm9uU3BhY2UoJyknKSkgeworCSAgICBTdHJpbmcgcyA9IGF0b20gPyByZWFkQXRvbVN0cmluZygpIDogcmVhZFN0cmluZygpOworCSAgICBpZiAocyA9PSBudWxsKQkvLyBub3QgdGhlIGV4cGVjdGVkIHN0cmluZyBvciBhdG9tCisJCWJyZWFrOworCSAgICByZXN1bHQuYWRkKHMpOworCX0KKworCXJldHVybiByZXN1bHQudG9BcnJheShuZXcgU3RyaW5nW3Jlc3VsdC5zaXplKCldKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFeHRyYWN0IGFuIGludGVnZXIsIHN0YXJ0aW5nIGF0IHRoZSBjdXJyZW50IHBvc2l0aW9uLiBVcGRhdGVzIHRoZQorICAgICAqIGludGVybmFsIGluZGV4IHRvIGJleW9uZCB0aGUgbnVtYmVyLiBSZXR1cm5zIC0xIGlmICBhIG51bWJlciB3YXMgCisgICAgICogbm90IGZvdW5kLgorICAgICAqCisgICAgICogQHJldHVybiAgYSBudW1iZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHJlYWROdW1iZXIoKSB7CisJLy8gU2tpcCBsZWFkaW5nIHNwYWNlcworCXNraXBTcGFjZXMoKTsKKworICAgICAgICBpbnQgc3RhcnQgPSBpbmRleDsKKyAgICAgICAgd2hpbGUgKGluZGV4IDwgc2l6ZSAmJiBDaGFyYWN0ZXIuaXNEaWdpdCgoY2hhcilidWZmZXJbaW5kZXhdKSkKKyAgICAgICAgICAgIGluZGV4Kys7CisKKyAgICAgICAgaWYgKGluZGV4ID4gc3RhcnQpIHsKKwkgICAgdHJ5IHsKKwkJcmV0dXJuIEFTQ0lJVXRpbGl0eS5wYXJzZUludChidWZmZXIsIHN0YXJ0LCBpbmRleCk7CisJICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBuZXgpIHsgfQorCX0KKworCXJldHVybiAtMTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFeHRyYWN0IGEgbG9uZyBudW1iZXIsIHN0YXJ0aW5nIGF0IHRoZSBjdXJyZW50IHBvc2l0aW9uLiBVcGRhdGVzIHRoZQorICAgICAqIGludGVybmFsIGluZGV4IHRvIGJleW9uZCB0aGUgbnVtYmVyLiBSZXR1cm5zIC0xIGlmIGEgbG9uZyBudW1iZXIKKyAgICAgKiB3YXMgbm90IGZvdW5kLgorICAgICAqCisgICAgICogQHJldHVybiAgYSBsb25nCisgICAgICovCisgICAgcHVibGljIGxvbmcgcmVhZExvbmcoKSB7CisJLy8gU2tpcCBsZWFkaW5nIHNwYWNlcworCXNraXBTcGFjZXMoKTsKKworICAgICAgICBpbnQgc3RhcnQgPSBpbmRleDsKKyAgICAgICAgd2hpbGUgKGluZGV4IDwgc2l6ZSAmJiBDaGFyYWN0ZXIuaXNEaWdpdCgoY2hhcilidWZmZXJbaW5kZXhdKSkKKyAgICAgICAgICAgIGluZGV4Kys7CisKKyAgICAgICAgaWYgKGluZGV4ID4gc3RhcnQpIHsKKwkgICAgdHJ5IHsKKwkJcmV0dXJuIEFTQ0lJVXRpbGl0eS5wYXJzZUxvbmcoYnVmZmVyLCBzdGFydCwgaW5kZXgpOworCSAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gbmV4KSB7IH0KKwl9CisKKwlyZXR1cm4gLTE7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXh0cmFjdCBhIE5TVFJJTkcsIHN0YXJ0aW5nIGF0IHRoZSBjdXJyZW50IHBvc2l0aW9uLiBSZXR1cm4gaXQgYXMKKyAgICAgKiBhIFN0cmluZy4gVGhlIHNlcXVlbmNlICdOSUwnIGlzIHJldHVybmVkIGFzIG51bGwKKyAgICAgKgorICAgICAqIE5TVFJJTkcgOj0gUXVvdGVkU3RyaW5nIHwgTGl0ZXJhbCB8ICJOSUwiCisgICAgICoKKyAgICAgKiBAcmV0dXJuICBhIFN0cmluZworICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgcmVhZFN0cmluZygpIHsKKwlyZXR1cm4gKFN0cmluZylwYXJzZVN0cmluZyhmYWxzZSwgdHJ1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXh0cmFjdCBhIE5TVFJJTkcsIHN0YXJ0aW5nIGF0IHRoZSBjdXJyZW50IHBvc2l0aW9uLiBSZXR1cm4gaXQgYXMKKyAgICAgKiBhIEJ5dGVBcnJheUlucHV0U3RyZWFtLiBUaGUgc2VxdWVuY2UgJ05JTCcgaXMgcmV0dXJuZWQgYXMgbnVsbAorICAgICAqCisgICAgICogTlNUUklORyA6PSBRdW90ZWRTdHJpbmcgfCBMaXRlcmFsIHwgIk5JTCIKKyAgICAgKgorICAgICAqIEByZXR1cm4gIGEgQnl0ZUFycmF5SW5wdXRTdHJlYW0KKyAgICAgKi8KKyAgICBwdWJsaWMgQnl0ZUFycmF5SW5wdXRTdHJlYW0gcmVhZEJ5dGVzKCkgeworCUJ5dGVBcnJheSBiYSA9IHJlYWRCeXRlQXJyYXkoKTsKKwlpZiAoYmEgIT0gbnVsbCkKKwkgICAgcmV0dXJuIGJhLnRvQnl0ZUFycmF5SW5wdXRTdHJlYW0oKTsKKwllbHNlCisJICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEV4dHJhY3QgYSBOU1RSSU5HLCBzdGFydGluZyBhdCB0aGUgY3VycmVudCBwb3NpdGlvbi4gUmV0dXJuIGl0IGFzCisgICAgICogYSBCeXRlQXJyYXkuIFRoZSBzZXF1ZW5jZSAnTklMJyBpcyByZXR1cm5lZCBhcyBudWxsCisgICAgICoKKyAgICAgKiBOU1RSSU5HIDo9IFF1b3RlZFN0cmluZyB8IExpdGVyYWwgfCAiTklMIgorICAgICAqCisgICAgICogQHJldHVybiAgYSBCeXRlQXJyYXkKKyAgICAgKi8KKyAgICBwdWJsaWMgQnl0ZUFycmF5IHJlYWRCeXRlQXJyYXkoKSB7CisJLyoKKwkgKiBTcGVjaWFsIGNhc2UsIHJldHVybiB0aGUgZGF0YSBhZnRlciB0aGUgY29udGludWF0aW9uIHVuaW50ZXJwcmV0ZWQuCisJICogSXQncyB1c3VhbGx5IGEgY2hhbGxlbmdlIGZvciBhbiBBVVRIRU5USUNBVEUgY29tbWFuZC4KKwkgKi8KKwlpZiAoaXNDb250aW51YXRpb24oKSkgeworCSAgICBza2lwU3BhY2VzKCk7CisJICAgIHJldHVybiBuZXcgQnl0ZUFycmF5KGJ1ZmZlciwgaW5kZXgsIHNpemUgLSBpbmRleCk7CisJfQorCXJldHVybiAoQnl0ZUFycmF5KXBhcnNlU3RyaW5nKGZhbHNlLCBmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXh0cmFjdCBhbiBBU1RSSU5HLCBzdGFydGluZyBhdCB0aGUgY3VycmVudCBwb3NpdGlvbgorICAgICAqIGFuZCByZXR1cm4gYXMgYSBTdHJpbmcuIEFuIEFTVFJJTkcgY2FuIGJlIGEgUXVvdGVkU3RyaW5nLCBhCisgICAgICogTGl0ZXJhbCBvciBhbiBBdG9tIChwbHVzICddJykuCisgICAgICoKKyAgICAgKiBBbnkgZXJyb3JzIGluIHBhcnNpbmcgcmV0dXJucyBudWxsCisgICAgICoKKyAgICAgKiBBU1RSSU5HIDo9IFF1b3RlZFN0cmluZyB8IExpdGVyYWwgfCAxKkFTVFJJTkdfQ0hBUgorICAgICAqCisgICAgICogQHJldHVybiBhIFN0cmluZworICAgICAqLyAKKyAgICBwdWJsaWMgU3RyaW5nIHJlYWRBdG9tU3RyaW5nKCkgeworCXJldHVybiAoU3RyaW5nKXBhcnNlU3RyaW5nKHRydWUsIHRydWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdlbmVyaWMgcGFyc2luZyByb3V0aW5lIHRoYXQgY2FuIHBhcnNlIG91dCBhIFF1b3RlZC1TdHJpbmcsCisgICAgICogTGl0ZXJhbCBvciBBdG9tIGFuZCByZXR1cm4gdGhlIHBhcnNlZCB0b2tlbiBhcyBhIFN0cmluZworICAgICAqIG9yIGEgQnl0ZUFycmF5LiBFcnJvcnMgb3IgTklMIGRhdGEgd2lsbCByZXR1cm4gbnVsbC4KKyAgICAgKi8KKyAgICBwcml2YXRlIE9iamVjdCBwYXJzZVN0cmluZyhib29sZWFuIHBhcnNlQXRvbXMsIGJvb2xlYW4gcmV0dXJuU3RyaW5nKSB7CisJYnl0ZSBiOworCisJLy8gU2tpcCBsZWFkaW5nIHNwYWNlcworCXNraXBTcGFjZXMoKTsKKwkKKwliID0gYnVmZmVyW2luZGV4XTsKKwlpZiAoYiA9PSAnIicpIHsgLy8gUXVvdGVkU3RyaW5nCisJICAgIGluZGV4Kys7IC8vIHNraXAgdGhlIHF1b3RlCisJICAgIGludCBzdGFydCA9IGluZGV4OworCSAgICBpbnQgY29weXRvID0gaW5kZXg7CisKKwkgICAgd2hpbGUgKGluZGV4IDwgc2l6ZSAmJiAoYiA9IGJ1ZmZlcltpbmRleF0pICE9ICciJykgeworCQlpZiAoYiA9PSAnXFwnKSAvLyBza2lwIGVzY2FwZWQgYnl0ZQorCQkgICAgaW5kZXgrKzsKKwkJaWYgKGluZGV4ICE9IGNvcHl0bykgeyAvLyBvbmx5IGNvcHkgaWYgd2UgbmVlZCB0bworCQkgICAgLy8gQmV3YXJlOiB0aGlzIGlzIGEgZGVzdHJ1Y3RpdmUgY29weS4gSSdtIAorCQkgICAgLy8gcHJldHR5IHN1cmUgdGhpcyBpcyBPSywgYnV0IC4uLiA7PgorCQkgICAgYnVmZmVyW2NvcHl0b10gPSBidWZmZXJbaW5kZXhdOworCQl9CisJCWNvcHl0bysrOworCQlpbmRleCsrOworCSAgICB9CisJICAgIGlmIChpbmRleCA+PSBzaXplKSB7CisJCS8vIGRpZG4ndCBmaW5kIHRlcm1pbmF0aW5nIHF1b3RlLCBzb21ldGhpbmcgaXMgc2VyaW91c2x5IHdyb25nCisJCS8vdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigKKwkJLy8JCSAgICAiaW5kZXggPSAiICsgaW5kZXggKyAiLCBzaXplID0gIiArIHNpemUpOworCQlyZXR1cm4gbnVsbDsKKwkgICAgfSBlbHNlCisJCWluZGV4Kys7IC8vIHNraXAgcGFzdCB0aGUgdGVybWluYXRpbmcgcXVvdGUKKworCSAgICBpZiAocmV0dXJuU3RyaW5nKSAKKwkJcmV0dXJuIHRvU3RyaW5nKGJ1ZmZlciwgc3RhcnQsIGNvcHl0byk7CisJICAgIGVsc2UKKwkJcmV0dXJuIG5ldyBCeXRlQXJyYXkoYnVmZmVyLCBzdGFydCwgY29weXRvLXN0YXJ0KTsKKwl9IGVsc2UgaWYgKGIgPT0gJ3snKSB7IC8vIExpdGVyYWwKKwkgICAgaW50IHN0YXJ0ID0gKytpbmRleDsgLy8gbm90ZSB0aGUgc3RhcnQgcG9zaXRpb24KKworCSAgICB3aGlsZSAoYnVmZmVyW2luZGV4XSAhPSAnfScpCisJCWluZGV4Kys7CisKKwkgICAgaW50IGNvdW50ID0gMDsKKwkgICAgdHJ5IHsKKwkJY291bnQgPSBBU0NJSVV0aWxpdHkucGFyc2VJbnQoYnVmZmVyLCBzdGFydCwgaW5kZXgpOworCSAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gbmV4KSB7IAorCSAgIAkvLyB0aHJvdyBuZXcgUGFyc2luZ0V4Y2VwdGlvbigpOworCQlyZXR1cm4gbnVsbDsKKwkgICAgfQorCisJICAgIHN0YXJ0ID0gaW5kZXggKyAzOyAvLyBza2lwICJ9XHJcbiIKKwkgICAgaW5kZXggPSBzdGFydCArIGNvdW50OyAvLyBwb3NpdGlvbiBpbmRleCB0byBiZXlvbmQgdGhlIGxpdGVyYWwKKworCSAgICBpZiAocmV0dXJuU3RyaW5nKSAvLyByZXR1cm4gYXMgU3RyaW5nCisJCXJldHVybiB0b1N0cmluZyhidWZmZXIsIHN0YXJ0LCBzdGFydCArIGNvdW50KTsKKwkgICAgZWxzZQorCSAgICAJcmV0dXJuIG5ldyBCeXRlQXJyYXkoYnVmZmVyLCBzdGFydCwgY291bnQpOworCX0gZWxzZSBpZiAocGFyc2VBdG9tcykgeyAvLyBwYXJzZSBhcyBBU1RSSU5HLUNIQVJzCisJICAgIGludCBzdGFydCA9IGluZGV4OwkvLyB0cmFjayB0aGlzLCBzbyB0aGF0IHdlIGNhbiB1c2UgdG8KKwkJCQkvLyBjcmVhdGluZyBCeXRlQXJyYXlJbnB1dFN0cmVhbSBiZWxvdy4KKwkgICAgU3RyaW5nIHMgPSByZWFkRGVsaW1TdHJpbmcoQVNUUklOR19DSEFSX0RFTElNKTsKKwkgICAgaWYgKHJldHVyblN0cmluZykKKwkJcmV0dXJuIHM7CisJICAgIGVsc2UgIC8vICp2ZXJ5KiB1bmxpa2VseQorCQlyZXR1cm4gbmV3IEJ5dGVBcnJheShidWZmZXIsIHN0YXJ0LCBpbmRleCk7CisJfSBlbHNlIGlmIChiID09ICdOJyB8fCBiID09ICduJykgeyAvLyB0aGUgb25seSB2YWxpZCB2YWx1ZSBpcyAnTklMJworCSAgICBpbmRleCArPSAzOyAvLyBza2lwIHBhc3QgTklMCisJICAgIHJldHVybiBudWxsOworCX0KKwlyZXR1cm4gbnVsbDsgLy8gRXJyb3IKKyAgICB9CisKKyAgICBwcml2YXRlIFN0cmluZyB0b1N0cmluZyhieXRlW10gYnVmZmVyLCBpbnQgc3RhcnQsIGludCBlbmQpIHsKKwlyZXR1cm4gdXRmOCA/CisJCW5ldyBTdHJpbmcoYnVmZmVyLCBzdGFydCwgZW5kIC0gc3RhcnQsIFN0YW5kYXJkQ2hhcnNldHMuVVRGXzgpIDoKKwkJQVNDSUlVdGlsaXR5LnRvU3RyaW5nKGJ1ZmZlciwgc3RhcnQsIGVuZCk7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRUeXBlKCkgeworCXJldHVybiB0eXBlOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGlzQ29udGludWF0aW9uKCkgeworCXJldHVybiAoKHR5cGUgJiBUQUdfTUFTSykgPT0gQ09OVElOVUFUSU9OKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1RhZ2dlZCgpIHsKKwlyZXR1cm4gKCh0eXBlICYgVEFHX01BU0spID09IFRBR0dFRCk7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaXNVblRhZ2dlZCgpIHsKKwlyZXR1cm4gKCh0eXBlICYgVEFHX01BU0spID09IFVOVEFHR0VEKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpc09LKCkgeworCXJldHVybiAoKHR5cGUgJiBUWVBFX01BU0spID09IE9LKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpc05PKCkgeworCXJldHVybiAoKHR5cGUgJiBUWVBFX01BU0spID09IE5PKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0JBRCgpIHsKKwlyZXR1cm4gKCh0eXBlICYgVFlQRV9NQVNLKSA9PSBCQUQpOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGlzQllFKCkgeworCXJldHVybiAoKHR5cGUgJiBUWVBFX01BU0spID09IEJZRSk7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaXNTeW50aGV0aWMoKSB7CisJcmV0dXJuICgodHlwZSAmIFNZTlRIRVRJQykgPT0gU1lOVEhFVElDKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIHRhZywgaWYgdGhpcyBpcyBhIHRhZ2dlZCBzdGF0ZW1lbnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRhZyBvZiB0aGlzIHRhZ2dlZCBzdGF0ZW1lbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFRhZygpIHsKKwlyZXR1cm4gdGFnOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgcmVzdCBvZiB0aGUgcmVzcG9uc2UgYXMgYSBzdHJpbmcsIHVzdWFsbHkgdXNlZCB0bworICAgICAqIHJldHVybiB0aGUgYXJiaXRyYXJ5IG1lc3NhZ2UgdGV4dCBhZnRlciBhIE5PIHJlc3BvbnNlLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgcmVzdCBvZiB0aGUgcmVzcG9uc2UKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFJlc3QoKSB7CisJc2tpcFNwYWNlcygpOworCXJldHVybiB0b1N0cmluZyhidWZmZXIsIGluZGV4LCBzaXplKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIGV4Y2VwdGlvbiBmb3IgYSBzeW50aGV0aWMgQllFIHJlc3BvbnNlLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgZXhjZXB0aW9uCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNS40CisgICAgICovCisgICAgcHVibGljIEV4Y2VwdGlvbiBnZXRFeGNlcHRpb24oKSB7CisJcmV0dXJuIGV4OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlc2V0IHBvaW50ZXIgdG8gYmVnaW5uaW5nIG9mIHJlc3BvbnNlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlc2V0KCkgeworCWluZGV4ID0gcGluZGV4OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisJcmV0dXJuIHRvU3RyaW5nKGJ1ZmZlciwgMCwgc2l6ZSk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2lhcC9SZXNwb25zZUhhbmRsZXIuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaWFwL1Jlc3BvbnNlSGFuZGxlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdkNWE2MWMKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2lhcC9SZXNwb25zZUhhbmRsZXIuamF2YQpAQCAtMCwwICsxLDI3IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5pYXA7CisKKy8qKgorICogVGhpcyBjbGFzcyAKKyAqCisgKiBAYXV0aG9yICBKb2huIE1hbmkKKyAqLworCitwdWJsaWMgaW50ZXJmYWNlIFJlc3BvbnNlSGFuZGxlciB7IAorICAgIHB1YmxpYyB2b2lkIGhhbmRsZVJlc3BvbnNlKFJlc3BvbnNlIHIpOworfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pYXAvUmVzcG9uc2VJbnB1dFN0cmVhbS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pYXAvUmVzcG9uc2VJbnB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjllMDViMTgKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2lhcC9SZXNwb25zZUlucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwxNTggQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmlhcDsKKworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBjb20uc3VuLm1haWwuaWFwLkJ5dGVBcnJheTsKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5BU0NJSVV0aWxpdHk7CisKKy8qKgorICoKKyAqIElucHV0c3RyZWFtIHRoYXQgaXMgdXNlZCB0byByZWFkIGEgUmVzcG9uc2UuCisgKgorICogQGF1dGhvciAgQXJ1biBLcmlzaG5hbgorICogQGF1dGhvciAgQmlsbCBTaGFubm9uCisgKi8KKworcHVibGljIGNsYXNzIFJlc3BvbnNlSW5wdXRTdHJlYW0geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IG1pbkluY3JlbWVudCA9IDI1NjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgbWF4SW5jcmVtZW50ID0gMjU2ICogMTAyNDsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgaW5jcmVtZW50U2xvcCA9IDE2OworCisgICAgLy8gd2hlcmUgd2UgcmVhZCBmcm9tCisgICAgcHJpdmF0ZSBCdWZmZXJlZElucHV0U3RyZWFtIGJpbjsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yLgorICAgICAqCisgICAgICogQHBhcmFtCWluCXRoZSBJbnB1dFN0cmVhbSB0byB3cmFwCisgICAgICovCisgICAgcHVibGljIFJlc3BvbnNlSW5wdXRTdHJlYW0oSW5wdXRTdHJlYW0gaW4pIHsKKwliaW4gPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShpbiwgMiAqIDEwMjQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWQgYSBSZXNwb25zZSBmcm9tIHRoZSBJbnB1dFN0cmVhbS4KKyAgICAgKgorICAgICAqIEByZXR1cm4JCUJ5dGVBcnJheSB0aGF0IGNvbnRhaW5zIHRoZSBSZXNwb25zZQorICAgICAqIEBleGNlcHRpb24JSU9FeGNlcHRpb24JZm9yIEkvTyBlcnJvcnMKKyAgICAgKi8KKyAgICBwdWJsaWMgQnl0ZUFycmF5IHJlYWRSZXNwb25zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJcmV0dXJuIHJlYWRSZXNwb25zZShudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkIGEgUmVzcG9uc2UgZnJvbSB0aGUgSW5wdXRTdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0JYmEJdGhlIEJ5dGVBcnJheSBpbiB3aGljaCB0byBzdG9yZSB0aGUgcmVzcG9uc2UsIG9yIG51bGwKKyAgICAgKiBAcmV0dXJuCQlCeXRlQXJyYXkgdGhhdCBjb250YWlucyB0aGUgUmVzcG9uc2UKKyAgICAgKiBAZXhjZXB0aW9uCUlPRXhjZXB0aW9uCWZvciBJL08gZXJyb3JzCisgICAgICovCisgICAgcHVibGljIEJ5dGVBcnJheSByZWFkUmVzcG9uc2UoQnl0ZUFycmF5IGJhKSB0aHJvd3MgSU9FeGNlcHRpb24geworCWlmIChiYSA9PSBudWxsKQorCSAgICBiYSA9IG5ldyBCeXRlQXJyYXkobmV3IGJ5dGVbMTI4XSwgMCwgMTI4KTsKKworCWJ5dGVbXSBidWZmZXIgPSBiYS5nZXRCeXRlcygpOworCWludCBpZHggPSAwOworCWZvciAoOzspIHsJLy8gcmVhZCB1bnRpbCBDUkxGIHdpdGggbm8gcHJlY2VlZGluZyBsaXRlcmFsCisJICAgIC8vIFhYWCAtIGIgbmVlZHMgdG8gYmUgYW4gaW50LCB0byBoYW5kbGUgYnl0ZXMgd2l0aCB2YWx1ZSAweGZmCisJICAgIGludCBiID0gMDsKKwkgICAgYm9vbGVhbiBnb3RDUkxGPWZhbHNlOworCisJICAgIC8vIFJlYWQgYSBDUkxGIHRlcm1pbmF0ZWQgbGluZSBmcm9tIHRoZSBJbnB1dFN0cmVhbQorCSAgICB3aGlsZSAoIWdvdENSTEYgJiYKKwkJICAgKChiID0gIGJpbi5yZWFkKCkpICE9IC0xKSkgeworCQlpZiAoYiA9PSAnXG4nKSB7CisJCSAgICBpZiAoKGlkeCA+IDApICYmIGJ1ZmZlcltpZHgtMV0gPT0gJ1xyJykKKwkJCWdvdENSTEYgPSB0cnVlOworCQl9CisJCWlmIChpZHggPj0gYnVmZmVyLmxlbmd0aCkgeworCQkgICAgaW50IGluY3IgPSBidWZmZXIubGVuZ3RoOworCQkgICAgaWYgKGluY3IgPiBtYXhJbmNyZW1lbnQpCisJCQlpbmNyID0gbWF4SW5jcmVtZW50OworCQkgICAgYmEuZ3JvdyhpbmNyKTsKKwkJICAgIGJ1ZmZlciA9IGJhLmdldEJ5dGVzKCk7CisJCX0KKwkJYnVmZmVyW2lkeCsrXSA9IChieXRlKWI7CisJICAgIH0KKworCSAgICBpZiAoYiA9PSAtMSkKKwkJdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJDb25uZWN0aW9uIGRyb3BwZWQgYnkgc2VydmVyPyIpOworCisJICAgIC8vIE5vdyBsZXRzIGNoZWNrIGZvciBsaXRlcmFscyA6IHs8ZGlnaXRzPn1DUkxGCisJICAgIC8vIE5vdGU6IGluZGV4IG5lZWRzIHRvID49IDUgZm9yIHRoZSBhYm92ZSBzZXF1ZW5jZSB0byBvY2N1cgorCSAgICBpZiAoaWR4IDwgNSB8fCBidWZmZXJbaWR4LTNdICE9ICd9JykKKwkJYnJlYWs7CisKKwkgICAgaW50IGk7CisJICAgIC8vIGxvb2sgZm9yIGxlZnQgY3VybHkKKwkgICAgZm9yIChpID0gaWR4IC0gNDsgaSA+PSAwOyBpLS0pCisJCWlmIChidWZmZXJbaV0gPT0gJ3snKQorCQkgICAgYnJlYWs7CisKKwkgICAgaWYgKGkgPCAwKSAvLyBOb3BlLCBub3QgYSBsaXRlcmFsID8KKwkJYnJlYWs7CisKKwkgICAgaW50IGNvdW50ID0gMDsKKwkgICAgLy8gT0ssIGhhbmRsZSB0aGUgbGl0ZXJhbCAuLgorCSAgICB0cnkgeworCQljb3VudCA9IEFTQ0lJVXRpbGl0eS5wYXJzZUludChidWZmZXIsIGkrMSwgaWR4LTMpOworCSAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgeworCQlicmVhazsKKwkgICAgfQorCisJICAgIC8vIE5vdyByZWFkICdjb3VudCcgYnl0ZXMuIChOb3RlOiBjb3VudCBjb3VsZCBiZSAwKQorCSAgICBpZiAoY291bnQgPiAwKSB7CisJCWludCBhdmFpbCA9IGJ1ZmZlci5sZW5ndGggLSBpZHg7IC8vIGF2YWlsYWJsZSBzcGFjZSBpbiBidWZmZXIKKwkJaWYgKGNvdW50ICsgaW5jcmVtZW50U2xvcCA+IGF2YWlsKSB7CisJCSAgICAvLyBuZWVkIGNvdW50LWF2YWlsIG1vcmUgYnl0ZXMKKwkJICAgIGJhLmdyb3cobWluSW5jcmVtZW50ID4gY291bnQgKyBpbmNyZW1lbnRTbG9wIC0gYXZhaWwgPyAKKwkJCSAgICBtaW5JbmNyZW1lbnQgOiBjb3VudCArIGluY3JlbWVudFNsb3AgLSBhdmFpbCk7CisJCSAgICBidWZmZXIgPSBiYS5nZXRCeXRlcygpOworCQl9CisKKwkJLyoKKwkJICogcmVhZCgpIG1pZ2h0IG5vdCByZXR1cm4gYWxsIHRoZSBieXRlcyBpbiBvbmUgc2hvdCwKKwkJICogc28gY2FsbCByZXBlYXRlZGx5IHRpbGwgd2UgYXJlIGRvbmUKKwkJICovCisJCWludCBhY3R1YWw7CisJCXdoaWxlIChjb3VudCA+IDApIHsKKwkJICAgIGFjdHVhbCA9IGJpbi5yZWFkKGJ1ZmZlciwgaWR4LCBjb3VudCk7CisJCSAgICBpZiAoYWN0dWFsID09IC0xKQorCQkJdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJDb25uZWN0aW9uIGRyb3BwZWQgYnkgc2VydmVyPyIpOworCQkgICAgY291bnQgLT0gYWN0dWFsOworCQkgICAgaWR4ICs9IGFjdHVhbDsKKwkJfQorCSAgICB9CisJICAgIC8vIGJhY2sgdG8gdG9wIG9mIGxvb3AgdG8gcmVhZCB1bnRpbCBDUkxGCisJfQorCWJhLnNldENvdW50KGlkeCk7CisJcmV0dXJuIGJhOworICAgIH0KKworICAgIC8qKgorICAgICAqIEhvdyBtdWNoIGJ1ZmZlcmVkIGRhdGEgZG8gd2UgaGF2ZT8KKyAgICAgKgorICAgICAqIEByZXR1cm4JbnVtYmVyIG9mIGJ5dGVzIGF2YWlsYWJsZQorICAgICAqIEBleGNlcHRpb24JSU9FeGNlcHRpb24JaWYgdGhlIHN0cmVhbSBoYXMgYmVlbiBjbG9zZWQKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS41LjQKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGF2YWlsYWJsZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJcmV0dXJuIGJpbi5hdmFpbGFibGUoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2lhcC9wYWNrYWdlLmh0bWwgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2lhcC9wYWNrYWdlLmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjYwN2UzMwotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaWFwL3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDMzIEBACis8IURPQ1RZUEUgaHRtbCBQVUJMSUMgIi0vL1czQy8vRFREIEhUTUwgNC4wMSBUcmFuc2l0aW9uYWwvL0VOIj4KKzxIVE1MPgorPEhFQUQ+Cis8bWV0YSBodHRwLWVxdWl2PSJDb250ZW50LVR5cGUiIGNvbnRlbnQ9InRleHQvaHRtbDsgY2hhcnNldD11dGYtOCI+Cis8IS0tCisKKyAgICBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKworICAgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICAgIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorCisgICAgVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICAgIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAgICBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAgICB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKworICAgIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorCistLT4KKworPFRJVExFPmNvbS5zdW4ubWFpbC5pYXAgcGFja2FnZTwvVElUTEU+Cis8L0hFQUQ+Cis8Qk9EWSBCR0NPTE9SPSJ3aGl0ZSI+CisKKzxQPgorVGhpcyBwYWNrYWdlIGluY2x1ZGVzIGludGVybmFsIElNQVAgc3VwcG9ydCBjbGFzc2VzIGFuZAorPHN0cm9uZz5TSE9VTEQgTk9UIEJFIFVTRUQgRElSRUNUTFkgQlkgQVBQTElDQVRJT05TPC9zdHJvbmc+LgorPC9QPgorCis8L0JPRFk+Cis8L0hUTUw+CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvQUNMLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvQUNMLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWU5OWM5NQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9BQ0wuamF2YQpAQCAtMCwwICsxLDk0IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5pbWFwOworCitpbXBvcnQgamF2YS51dGlsLio7CisKKy8qKgorICogQW4gYWNjZXNzIGNvbnRyb2wgbGlzdCBlbnRyeSBmb3IgYSBwYXJ0aWN1bGFyIGF1dGhlbnRpY2F0aW9uIGlkZW50aWZpZXIKKyAqICh1c2VyIG9yIGdyb3VwKS4gIEFzc29jaWF0ZXMgYSBzZXQgb2YgUmlnaHRzIHdpdGggdGhlIGlkZW50aWZpZXIuCisgKiBTZWUgUkZDIDIwODYuCisgKiA8cD4KKyAqCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCisKK3B1YmxpYyBjbGFzcyBBQ0wgaW1wbGVtZW50cyBDbG9uZWFibGUgeworCisgICAgcHJpdmF0ZSBTdHJpbmcgbmFtZTsKKyAgICBwcml2YXRlIFJpZ2h0cyByaWdodHM7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYW4gQUNMIGVudHJ5IGZvciB0aGUgZ2l2ZW4gaWRlbnRpZmllciBhbmQgd2l0aCBubyByaWdodHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0JbmFtZQl0aGUgaWRlbnRpZmllciBuYW1lCisgICAgICovCisgICAgcHVibGljIEFDTChTdHJpbmcgbmFtZSkgeworCXRoaXMubmFtZSA9IG5hbWU7CisJdGhpcy5yaWdodHMgPSBuZXcgUmlnaHRzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGFuIEFDTCBlbnRyeSBmb3IgdGhlIGdpdmVuIGlkZW50aWZpZXIgd2l0aCB0aGUgZ2l2ZW4gcmlnaHRzLgorICAgICAqCisgICAgICogQHBhcmFtCW5hbWUJdGhlIGlkZW50aWZpZXIgbmFtZQorICAgICAqIEBwYXJhbQlyaWdodHMJdGhlIHJpZ2h0cworICAgICAqLworICAgIHB1YmxpYyBBQ0woU3RyaW5nIG5hbWUsIFJpZ2h0cyByaWdodHMpIHsKKwl0aGlzLm5hbWUgPSBuYW1lOworCXRoaXMucmlnaHRzID0gcmlnaHRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgaWRlbnRpZmllciBuYW1lIGZvciB0aGlzIEFDTCBlbnRyeS4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIGlkZW50aWZpZXIgbmFtZQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKKwlyZXR1cm4gbmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHJpZ2h0cyBhc3NvY2lhdGVkIHdpdGggdGhpcyBBQ0wgZW50cnkuCisgICAgICoKKyAgICAgKiBAcGFyYW0JcmlnaHRzCXRoZSByaWdodHMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRSaWdodHMoUmlnaHRzIHJpZ2h0cykgeworCXRoaXMucmlnaHRzID0gcmlnaHRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgcmlnaHRzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIEFDTCBlbnRyeS4KKyAgICAgKiBSZXR1cm5zIHRoZSBhY3R1YWwgUmlnaHRzIG9iamVjdCByZWZlcmVuY2VkIGJ5IHRoaXMgQUNMOworICAgICAqIG1vZGlmaWNhdGlvbnMgdG8gdGhlIFJpZ2h0cyBvYmplY3Qgd2lsbCBlZmZlY3QgdGhpcyBBQ0wuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSByaWdodHMKKyAgICAgKi8KKyAgICBwdWJsaWMgUmlnaHRzIGdldFJpZ2h0cygpIHsKKwlyZXR1cm4gcmlnaHRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIENsb25lIHRoaXMgQUNMIGVudHJ5LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgY2xvbmUoKSB0aHJvd3MgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24geworCUFDTCBhY2wgPSAoQUNMKXN1cGVyLmNsb25lKCk7CisJYWNsLnJpZ2h0cyA9IChSaWdodHMpdGhpcy5yaWdodHMuY2xvbmUoKTsKKwlyZXR1cm4gYWNsOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9BcHBlbmRVSUQuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9BcHBlbmRVSUQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NmM3N2ZlCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0FwcGVuZFVJRC5qYXZhCkBAIC0wLDAgKzEsMzcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmltYXA7CisKK2ltcG9ydCBjb20uc3VuLm1haWwuaWFwLio7CisKKy8qKgorICogSW5mb3JtYXRpb24gZnJvbSB0aGUgQVBQRU5EVUlEIHJlc3BvbnNlIGNvZGUKKyAqIGRlZmluZWQgYnkgdGhlIFVJRFBMVVMgZXh0ZW5zaW9uIC0KKyAqIDxBIEhSRUY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzQzMTUudHh0Ij5SRkMgNDMxNTwvQT4uCisgKgorICogQGF1dGhvciAgQmlsbCBTaGFubm9uCisgKi8KKworcHVibGljIGNsYXNzIEFwcGVuZFVJRCB7IAorICAgIHB1YmxpYyBsb25nIHVpZHZhbGlkaXR5ID0gLTE7CisgICAgcHVibGljIGxvbmcgdWlkID0gLTE7CisKKyAgICBwdWJsaWMgQXBwZW5kVUlEKGxvbmcgdWlkdmFsaWRpdHksIGxvbmcgdWlkKSB7CisJdGhpcy51aWR2YWxpZGl0eSA9IHVpZHZhbGlkaXR5OworCXRoaXMudWlkID0gdWlkOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9Db3B5VUlELmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvQ29weVVJRC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM2NDhmYzUKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvQ29weVVJRC5qYXZhCkBAIC0wLDAgKzEsMzkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmltYXA7CisKK2ltcG9ydCBjb20uc3VuLm1haWwuaW1hcC5wcm90b2NvbC5VSURTZXQ7CisKKy8qKgorICogSW5mb3JtYXRpb24gZnJvbSB0aGUgQ09QWVVJRCByZXNwb25zZSBjb2RlCisgKiBkZWZpbmVkIGJ5IHRoZSBVSURQTFVTIGV4dGVuc2lvbiAtCisgKiA8QSBIUkVGPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmM0MzE1LnR4dCI+UkZDIDQzMTU8L0E+LgorICoKKyAqIEBhdXRob3IgIEJpbGwgU2hhbm5vbgorICovCisKK3B1YmxpYyBjbGFzcyBDb3B5VUlEIHsgCisgICAgcHVibGljIGxvbmcgdWlkdmFsaWRpdHkgPSAtMTsKKyAgICBwdWJsaWMgVUlEU2V0W10gc3JjOworICAgIHB1YmxpYyBVSURTZXRbXSBkc3Q7CisKKyAgICBwdWJsaWMgQ29weVVJRChsb25nIHVpZHZhbGlkaXR5LCBVSURTZXRbXSBzcmMsIFVJRFNldFtdIGRzdCkgeworCXRoaXMudWlkdmFsaWRpdHkgPSB1aWR2YWxpZGl0eTsKKwl0aGlzLnNyYyA9IHNyYzsKKwl0aGlzLmRzdCA9IGRzdDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvRGVmYXVsdEZvbGRlci5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0RlZmF1bHRGb2xkZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ZGFiMDRmCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0RlZmF1bHRGb2xkZXIuamF2YQpAQCAtMCwwICsxLDEyNyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuaW1hcDsKKworaW1wb3J0IGphdmF4Lm1haWwuRm9sZGVyOworaW1wb3J0IGphdmF4Lm1haWwuTWVzc2FnZTsKK2ltcG9ydCBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5tYWlsLk1ldGhvZE5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKK2ltcG9ydCBjb20uc3VuLm1haWwuaWFwLlByb3RvY29sRXhjZXB0aW9uOworaW1wb3J0IGNvbS5zdW4ubWFpbC5pbWFwLnByb3RvY29sLklNQVBQcm90b2NvbDsKK2ltcG9ydCBjb20uc3VuLm1haWwuaW1hcC5wcm90b2NvbC5MaXN0SW5mbzsKKworLyoqCisgKiBUaGUgZGVmYXVsdCBJTUFQIGZvbGRlciAocm9vdCBvZiB0aGUgbmFtaW5nIGhpZXJhcmNoeSkuCisgKgorICogQGF1dGhvciAgSm9obiBNYW5pCisgKi8KKworcHVibGljIGNsYXNzIERlZmF1bHRGb2xkZXIgZXh0ZW5kcyBJTUFQRm9sZGVyIHsKKyAgICAKKyAgICBwcm90ZWN0ZWQgRGVmYXVsdEZvbGRlcihJTUFQU3RvcmUgc3RvcmUpIHsKKwlzdXBlcigiIiwgVU5LTk9XTl9TRVBBUkFUT1IsIHN0b3JlLCBudWxsKTsKKwlleGlzdHMgPSB0cnVlOyAvLyBvZiBjb3Vyc2UKKwl0eXBlID0gSE9MRFNfRk9MREVSUzsgLy8gb2J2aW91c2x5CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBTdHJpbmcgZ2V0TmFtZSgpIHsKKwlyZXR1cm4gZnVsbE5hbWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEZvbGRlciBnZXRQYXJlbnQoKSB7CisJcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBGb2xkZXJbXSBsaXN0KGZpbmFsIFN0cmluZyBwYXR0ZXJuKQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCUxpc3RJbmZvW10gbGkgPSBudWxsOworCisJbGkgPSAoTGlzdEluZm9bXSlkb0NvbW1hbmQobmV3IFByb3RvY29sQ29tbWFuZCgpIHsKKwkgICAgQE92ZXJyaWRlCisJICAgIHB1YmxpYyBPYmplY3QgZG9Db21tYW5kKElNQVBQcm90b2NvbCBwKSB0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCQlyZXR1cm4gcC5saXN0KCIiLCBwYXR0ZXJuKTsKKwkgICAgfQorCX0pOworCisJaWYgKGxpID09IG51bGwpCisJICAgIHJldHVybiBuZXcgRm9sZGVyWzBdOworCisJSU1BUEZvbGRlcltdIGZvbGRlcnMgPSBuZXcgSU1BUEZvbGRlcltsaS5sZW5ndGhdOworCWZvciAoaW50IGkgPSAwOyBpIDwgZm9sZGVycy5sZW5ndGg7IGkrKykKKwkgICAgZm9sZGVyc1tpXSA9ICgoSU1BUFN0b3JlKXN0b3JlKS5uZXdJTUFQRm9sZGVyKGxpW2ldKTsKKwlyZXR1cm4gZm9sZGVyczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIEZvbGRlcltdIGxpc3RTdWJzY3JpYmVkKGZpbmFsIFN0cmluZyBwYXR0ZXJuKQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCUxpc3RJbmZvW10gbGkgPSBudWxsOworCisJbGkgPSAoTGlzdEluZm9bXSlkb0NvbW1hbmQobmV3IFByb3RvY29sQ29tbWFuZCgpIHsKKwkgICAgQE92ZXJyaWRlCisJICAgIHB1YmxpYyBPYmplY3QgZG9Db21tYW5kKElNQVBQcm90b2NvbCBwKSB0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCQlyZXR1cm4gcC5sc3ViKCIiLCBwYXR0ZXJuKTsKKwkgICAgfQorCX0pOworCisJaWYgKGxpID09IG51bGwpCisJICAgIHJldHVybiBuZXcgRm9sZGVyWzBdOworCisJSU1BUEZvbGRlcltdIGZvbGRlcnMgPSBuZXcgSU1BUEZvbGRlcltsaS5sZW5ndGhdOworCWZvciAoaW50IGkgPSAwOyBpIDwgZm9sZGVycy5sZW5ndGg7IGkrKykKKwkgICAgZm9sZGVyc1tpXSA9ICgoSU1BUFN0b3JlKXN0b3JlKS5uZXdJTUFQRm9sZGVyKGxpW2ldKTsKKwlyZXR1cm4gZm9sZGVyczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXdNZXNzYWdlcygpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCS8vIE5vdCBhcHBsaWNhYmxlIG9uIERlZmF1bHRGb2xkZXIKKwlyZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEZvbGRlciBnZXRGb2xkZXIoU3RyaW5nIG5hbWUpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXJldHVybiAoKElNQVBTdG9yZSlzdG9yZSkubmV3SU1BUEZvbGRlcihuYW1lLCBVTktOT1dOX1NFUEFSQVRPUik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZGVsZXRlKGJvb2xlYW4gcmVjdXJzZSkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7ICAKKwkvLyBOb3QgYXBwbGljYWJsZSBvbiBEZWZhdWx0Rm9sZGVyCisJdGhyb3cgbmV3IE1ldGhvZE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigiQ2Fubm90IGRlbGV0ZSBEZWZhdWx0IEZvbGRlciIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIHJlbmFtZVRvKEZvbGRlciBmKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwkvLyBOb3QgYXBwbGljYWJsZSBvbiBEZWZhdWx0Rm9sZGVyCisJdGhyb3cgbmV3IE1ldGhvZE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigiQ2Fubm90IHJlbmFtZSBEZWZhdWx0IEZvbGRlciIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGFwcGVuZE1lc3NhZ2VzKE1lc3NhZ2VbXSBtc2dzKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwkvLyBOb3QgYXBwbGljYWJsZSBvbiBEZWZhdWx0Rm9sZGVyCisJdGhyb3cgbmV3IE1ldGhvZE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigiQ2Fubm90IGFwcGVuZCB0byBEZWZhdWx0IEZvbGRlciIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBNZXNzYWdlW10gZXhwdW5nZSgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCS8vIE5vdCBhcHBsaWNhYmxlIG9uIERlZmF1bHRGb2xkZXIKKwl0aHJvdyBuZXcgTWV0aG9kTm90U3VwcG9ydGVkRXhjZXB0aW9uKCJDYW5ub3QgZXhwdW5nZSBEZWZhdWx0IEZvbGRlciIpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9JTUFQQm9keVBhcnQuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9JTUFQQm9keVBhcnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xODFiYjk0Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0lNQVBCb2R5UGFydC5qYXZhCkBAIC0wLDAgKzEsNDU0IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5pbWFwOworCitpbXBvcnQgamF2YS5pby4qOworCitpbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOworaW1wb3J0IGphdmF4Lm1haWwuKjsKK2ltcG9ydCBqYXZheC5tYWlsLmludGVybmV0Lio7CitpbXBvcnQgamF2YXguYWN0aXZhdGlvbi4qOworCitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuUHJvcFV0aWw7CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuUmVhZGFibGVNaW1lOworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLkxpbmVPdXRwdXRTdHJlYW07CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuU2hhcmVkQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGNvbS5zdW4ubWFpbC5pYXAuKjsKK2ltcG9ydCBjb20uc3VuLm1haWwuaW1hcC5wcm90b2NvbC4qOworCisvKioKKyAqIEFuIElNQVAgYm9keSBwYXJ0LgorICoKKyAqIEBhdXRob3IgIEpvaG4gTWFuaQorICogQGF1dGhvciAgQmlsbCBTaGFubm9uCisgKi8KKworcHVibGljIGNsYXNzIElNQVBCb2R5UGFydCBleHRlbmRzIE1pbWVCb2R5UGFydCBpbXBsZW1lbnRzIFJlYWRhYmxlTWltZSB7CisgICAgcHJpdmF0ZSBJTUFQTWVzc2FnZSBtZXNzYWdlOworICAgIHByaXZhdGUgQk9EWVNUUlVDVFVSRSBiczsKKyAgICBwcml2YXRlIFN0cmluZyBzZWN0aW9uSWQ7CisKKyAgICAvLyBwcm9jZXNzZWQgdmFsdWVzIC4uCisgICAgcHJpdmF0ZSBTdHJpbmcgdHlwZTsKKyAgICBwcml2YXRlIFN0cmluZyBkZXNjcmlwdGlvbjsKKworICAgIHByaXZhdGUgYm9vbGVhbiBoZWFkZXJzTG9hZGVkID0gZmFsc2U7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIGRlY29kZUZpbGVOYW1lID0KKwlQcm9wVXRpbC5nZXRCb29sZWFuU3lzdGVtUHJvcGVydHkoIm1haWwubWltZS5kZWNvZGVmaWxlbmFtZSIsIGZhbHNlKTsKKworICAgIHByb3RlY3RlZCBJTUFQQm9keVBhcnQoQk9EWVNUUlVDVFVSRSBicywgU3RyaW5nIHNpZCwgSU1BUE1lc3NhZ2UgbWVzc2FnZSkgeworCXN1cGVyKCk7CisJdGhpcy5icyA9IGJzOworCXRoaXMuc2VjdGlvbklkID0gc2lkOworCXRoaXMubWVzc2FnZSA9IG1lc3NhZ2U7CisJLy8gZ2VuZXJhdGUgY29udGVudC10eXBlCisJQ29udGVudFR5cGUgY3QgPSBuZXcgQ29udGVudFR5cGUoYnMudHlwZSwgYnMuc3VidHlwZSwgYnMuY1BhcmFtcyk7CisJdHlwZSA9IGN0LnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyogT3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8gbWFrZSBpdCBhIG5vLW9wLCByYXRoZXIgdGhhbiB0aHJvdworICAgICAqIGFuIElsbGVnYWxXcml0ZUV4Y2VwdGlvbi4gVGhpcyB3aWxsIHBlcm1pdCBJTUFQQm9keVBhcnRzIHRvCisgICAgICogYmUgaW5zZXJ0ZWQgaW4gbmV3bHkgY3JhZnRlZCBNaW1lTWVzc2FnZXMsIGVzcGVjaWFsbHkgd2hlbgorICAgICAqIGZvcndhcmRpbmcgb3IgcmVwbHlpbmcgdG8gbWVzc2FnZXMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgdXBkYXRlSGVhZGVycygpIHsKKwlyZXR1cm47CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRTaXplKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJcmV0dXJuIGJzLnNpemU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRMaW5lQ291bnQoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gYnMubGluZXM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXRDb250ZW50VHlwZSgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXJldHVybiB0eXBlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0RGlzcG9zaXRpb24oKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gYnMuZGlzcG9zaXRpb247CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0RGlzcG9zaXRpb24oU3RyaW5nIGRpc3Bvc2l0aW9uKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwl0aHJvdyBuZXcgSWxsZWdhbFdyaXRlRXhjZXB0aW9uKCJJTUFQQm9keVBhcnQgaXMgcmVhZC1vbmx5Iik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXRFbmNvZGluZygpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXJldHVybiBicy5lbmNvZGluZzsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldENvbnRlbnRJRCgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXJldHVybiBicy5pZDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldENvbnRlbnRNRDUoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gYnMubWQ1OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldENvbnRlbnRNRDUoU3RyaW5nIG1kNSkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJdGhyb3cgbmV3IElsbGVnYWxXcml0ZUV4Y2VwdGlvbigiSU1BUEJvZHlQYXJ0IGlzIHJlYWQtb25seSIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0RGVzY3JpcHRpb24oKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpZiAoZGVzY3JpcHRpb24gIT0gbnVsbCkgLy8gY2FjaGVkIHZhbHVlID8KKwkgICAgcmV0dXJuIGRlc2NyaXB0aW9uOworCisJaWYgKGJzLmRlc2NyaXB0aW9uID09IG51bGwpCisJICAgIHJldHVybiBudWxsOworCQorCXRyeSB7CisJICAgIGRlc2NyaXB0aW9uID0gTWltZVV0aWxpdHkuZGVjb2RlVGV4dChicy5kZXNjcmlwdGlvbik7CisJfSBjYXRjaCAoVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBleCkgeworCSAgICBkZXNjcmlwdGlvbiA9IGJzLmRlc2NyaXB0aW9uOworCX0KKworCXJldHVybiBkZXNjcmlwdGlvbjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXREZXNjcmlwdGlvbihTdHJpbmcgZGVzY3JpcHRpb24sIFN0cmluZyBjaGFyc2V0KQorCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJdGhyb3cgbmV3IElsbGVnYWxXcml0ZUV4Y2VwdGlvbigiSU1BUEJvZHlQYXJ0IGlzIHJlYWQtb25seSIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0RmlsZU5hbWUoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlTdHJpbmcgZmlsZW5hbWUgPSBudWxsOworCWlmIChicy5kUGFyYW1zICE9IG51bGwpCisJICAgIGZpbGVuYW1lID0gYnMuZFBhcmFtcy5nZXQoImZpbGVuYW1lIik7CisJaWYgKChmaWxlbmFtZSA9PSBudWxsIHx8IGZpbGVuYW1lLmlzRW1wdHkoKSkgJiYgYnMuY1BhcmFtcyAhPSBudWxsKQorCSAgICBmaWxlbmFtZSA9IGJzLmNQYXJhbXMuZ2V0KCJuYW1lIik7CisJaWYgKGRlY29kZUZpbGVOYW1lICYmIGZpbGVuYW1lICE9IG51bGwpIHsKKwkgICAgdHJ5IHsKKwkJZmlsZW5hbWUgPSBNaW1lVXRpbGl0eS5kZWNvZGVUZXh0KGZpbGVuYW1lKTsKKwkgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBleCkgeworCQl0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKCJDYW4ndCBkZWNvZGUgZmlsZW5hbWUiLCBleCk7CisJICAgIH0KKwl9CisJcmV0dXJuIGZpbGVuYW1lOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldEZpbGVOYW1lKFN0cmluZyBmaWxlbmFtZSkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJdGhyb3cgbmV3IElsbGVnYWxXcml0ZUV4Y2VwdGlvbigiSU1BUEJvZHlQYXJ0IGlzIHJlYWQtb25seSIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBJbnB1dFN0cmVhbSBnZXRDb250ZW50U3RyZWFtKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJSW5wdXRTdHJlYW0gaXMgPSBudWxsOworCWJvb2xlYW4gcGsgPSBtZXNzYWdlLmdldFBlZWsoKTsJLy8gYWNxdWlyZSBvdXRzaWRlIG9mIG1lc3NhZ2UgY2FjaGUgbG9jaworCisgICAgICAgIC8vIEFjcXVpcmUgTWVzc2FnZUNhY2hlTG9jaywgdG8gZnJlZXplIHNlcW51bS4KKyAgICAgICAgc3luY2hyb25pemVkKG1lc3NhZ2UuZ2V0TWVzc2FnZUNhY2hlTG9jaygpKSB7CisJICAgIHRyeSB7CisJCUlNQVBQcm90b2NvbCBwID0gbWVzc2FnZS5nZXRQcm90b2NvbCgpOworCisJCS8vIENoZWNrIHdoZXRoZXIgdGhpcyBtZXNzYWdlIGlzIGV4cHVuZ2VkCisJCW1lc3NhZ2UuY2hlY2tFeHB1bmdlZCgpOworCisJCWlmIChwLmlzUkVWMSgpICYmIChtZXNzYWdlLmdldEZldGNoQmxvY2tTaXplKCkgIT0gLTEpKQorCQkgICAgcmV0dXJuIG5ldyBJTUFQSW5wdXRTdHJlYW0obWVzc2FnZSwgc2VjdGlvbklkLAorCQkJbWVzc2FnZS5pZ25vcmVCb2R5U3RydWN0dXJlU2l6ZSgpID8gLTEgOiBicy5zaXplLCBwayk7CisKKwkJLy8gRWxzZSwgdmFuaWxhIElNQVA0LCBubyBwYXJ0aWFsIGZldGNoIAorCisJCWludCBzZXFudW0gPSBtZXNzYWdlLmdldFNlcXVlbmNlTnVtYmVyKCk7CisJCUJPRFkgYjsKKwkJaWYgKHBrKQorCQkgICAgYiA9IHAucGVla0JvZHkoc2VxbnVtLCBzZWN0aW9uSWQpOworCQllbHNlCisJCSAgICBiID0gcC5mZXRjaEJvZHkoc2VxbnVtLCBzZWN0aW9uSWQpOworCQlpZiAoYiAhPSBudWxsKQorCQkgICAgaXMgPSBiLmdldEJ5dGVBcnJheUlucHV0U3RyZWFtKCk7CisJICAgIH0gY2F0Y2ggKENvbm5lY3Rpb25FeGNlcHRpb24gY2V4KSB7CisJCXRocm93IG5ldyBGb2xkZXJDbG9zZWRFeGNlcHRpb24oCisJCQltZXNzYWdlLmdldEZvbGRlcigpLCBjZXguZ2V0TWVzc2FnZSgpKTsKKwkgICAgfSBjYXRjaCAoUHJvdG9jb2xFeGNlcHRpb24gcGV4KSB7IAorCQl0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKHBleC5nZXRNZXNzYWdlKCksIHBleCk7CisJICAgIH0KKwl9CisKKwlpZiAoaXMgPT0gbnVsbCkgeworCSAgICBtZXNzYWdlLmZvcmNlQ2hlY2tFeHB1bmdlZCgpOyAvLyBtYXkgdGhyb3cgTWVzc2FnZVJlbW92ZWRFeGNlcHRpb24KKwkgICAgLy8gbm9wZSwgdGhlIHNlcnZlciBkb2Vzbid0IHRoaW5rIGl0J3MgZXhwdW5nZWQuCisJICAgIC8vIGNhbid0IHRlbGwgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgc2VydmVyIHJldHVybmluZyBOSUwKKwkgICAgLy8gYW5kIHNvbWUgb3RoZXIgZXJyb3IgdGhhdCBjYXVzZWQgbnVsbCB0byBiZSByZXR1cm5lZCBhYm92ZSwKKwkgICAgLy8gc28gd2UnbGwganVzdCBhc3N1bWUgaXQgd2FzIGVtcHR5IGNvbnRlbnQuCisJICAgIGlzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKG5ldyBieXRlWzBdKTsKKwl9CisJcmV0dXJuIGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgTUlNRSBmb3JtYXQgc3RyZWFtIG9mIGhlYWRlcnMgZm9yIHRoaXMgYm9keSBwYXJ0LgorICAgICAqLworICAgIHByaXZhdGUgSW5wdXRTdHJlYW0gZ2V0SGVhZGVyU3RyZWFtKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKCFtZXNzYWdlLmlzUkVWMSgpKQorCSAgICBsb2FkSGVhZGVycygpOwkvLyB3aWxsIGJlIG5lZWRlZCBiZWxvdworCisJLy8gQWNxdWlyZSBNZXNzYWdlQ2FjaGVMb2NrLCB0byBmcmVlemUgc2VxbnVtLgorCXN5bmNocm9uaXplZChtZXNzYWdlLmdldE1lc3NhZ2VDYWNoZUxvY2soKSkgeworCSAgICB0cnkgeworCQlJTUFQUHJvdG9jb2wgcCA9IG1lc3NhZ2UuZ2V0UHJvdG9jb2woKTsKKworCQkvLyBDaGVjayB3aGV0aGVyIHRoaXMgbWVzc2FnZSBnb3QgZXhwdW5nZWQKKwkJbWVzc2FnZS5jaGVja0V4cHVuZ2VkKCk7CisKKwkJaWYgKHAuaXNSRVYxKCkpIHsKKwkJICAgIGludCBzZXFudW0gPSBtZXNzYWdlLmdldFNlcXVlbmNlTnVtYmVyKCk7CisJCSAgICBCT0RZIGIgPSBwLnBlZWtCb2R5KHNlcW51bSwgc2VjdGlvbklkICsgIi5NSU1FIik7CisKKwkJICAgIGlmIChiID09IG51bGwpCisJCQl0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKCJGYWlsZWQgdG8gZmV0Y2ggaGVhZGVycyIpOworCisJCSAgICBCeXRlQXJyYXlJbnB1dFN0cmVhbSBiaXMgPSBiLmdldEJ5dGVBcnJheUlucHV0U3RyZWFtKCk7CisJCSAgICBpZiAoYmlzID09IG51bGwpCisJCQl0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKCJGYWlsZWQgdG8gZmV0Y2ggaGVhZGVycyIpOworCQkgICAgcmV0dXJuIGJpczsKKworCQl9IGVsc2UgeworCQkgICAgLy8gQ2FuJ3QgcmVhZCBpdCBmcm9tIHNlcnZlciwgaGF2ZSB0byBmYWtlIGl0CisJCSAgICBTaGFyZWRCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zID0KKwkJCW5ldyBTaGFyZWRCeXRlQXJyYXlPdXRwdXRTdHJlYW0oMCk7CisJCSAgICBMaW5lT3V0cHV0U3RyZWFtIGxvcyA9IG5ldyBMaW5lT3V0cHV0U3RyZWFtKGJvcyk7CisKKwkJICAgIHRyeSB7CisJCQkvLyBXcml0ZSBvdXQgdGhlIGhlYWRlcgorCQkJRW51bWVyYXRpb248U3RyaW5nPiBoZHJMaW5lcworCQkJCT0gc3VwZXIuZ2V0QWxsSGVhZGVyTGluZXMoKTsKKwkJCXdoaWxlIChoZHJMaW5lcy5oYXNNb3JlRWxlbWVudHMoKSkKKwkJCSAgICBsb3Mud3JpdGVsbihoZHJMaW5lcy5uZXh0RWxlbWVudCgpKTsKKworCQkJLy8gVGhlIENSTEYgc2VwYXJhdG9yIGJldHdlZW4gaGVhZGVyIGFuZCBjb250ZW50CisJCQlsb3Mud3JpdGVsbigpOworCQkgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9leCkgeworCQkJLy8gc2hvdWxkIG5ldmVyIGhhcHBlbgorCQkgICAgfSBmaW5hbGx5IHsKKwkJCXRyeSB7CisJCQkgICAgbG9zLmNsb3NlKCk7CisJCQl9IGNhdGNoIChJT0V4Y2VwdGlvbiBjZXgpIHsgfQorCQkgICAgfQorCQkgICAgcmV0dXJuIGJvcy50b1N0cmVhbSgpOworCQl9CisJICAgIH0gY2F0Y2ggKENvbm5lY3Rpb25FeGNlcHRpb24gY2V4KSB7CisJCXRocm93IG5ldyBGb2xkZXJDbG9zZWRFeGNlcHRpb24oCisJCQkgICAgbWVzc2FnZS5nZXRGb2xkZXIoKSwgY2V4LmdldE1lc3NhZ2UoKSk7CisJICAgIH0gY2F0Y2ggKFByb3RvY29sRXhjZXB0aW9uIHBleCkgeworCQl0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKHBleC5nZXRNZXNzYWdlKCksIHBleCk7CisJICAgIH0KKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBNSU1FIGZvcm1hdCBzdHJlYW0gY29ycmVzcG9uZGluZyB0byB0aGlzIG1lc3NhZ2UgcGFydC4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIE1JTUUgZm9ybWF0IHN0cmVhbQorICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjQuNQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBJbnB1dFN0cmVhbSBnZXRNaW1lU3RyZWFtKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJLyoKKwkgKiBUaGUgSU1BUCBwcm90b2NvbCBkb2Vzbid0IHN1cHBvcnQgcmV0dXJuaW5nIHRoZSBlbnRpcmUKKwkgKiBwYXJ0IGNvbnRlbnQgaW4gb25lIG9wZXJhdGlvbiBzbyB3ZSBoYXZlIHRvIGZha2UgaXQgYnkKKwkgKiBjb25jYXRlbmF0aW5nIHRoZSBoZWFkZXIgc3RyZWFtIGFuZCB0aGUgY29udGVudCBzdHJlYW0uCisJICovCisJcmV0dXJuIG5ldyBTZXF1ZW5jZUlucHV0U3RyZWFtKGdldEhlYWRlclN0cmVhbSgpLCBnZXRDb250ZW50U3RyZWFtKCkpOworICAgIH0KKwkgICAgCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBEYXRhSGFuZGxlciBnZXREYXRhSGFuZGxlcigpIAorCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpZiAoZGggPT0gbnVsbCkgeworCSAgIGlmIChicy5pc011bHRpKCkpCisJCWRoID0gbmV3IERhdGFIYW5kbGVyKAorCQkJbmV3IElNQVBNdWx0aXBhcnREYXRhU291cmNlKAorCQkJCXRoaXMsIGJzLmJvZGllcywgc2VjdGlvbklkLCBtZXNzYWdlKQorCQkgICAgICk7CisJICAgIGVsc2UgaWYgKGJzLmlzTmVzdGVkKCkgJiYgbWVzc2FnZS5pc1JFVjEoKSAmJiBicy5lbnZlbG9wZSAhPSBudWxsKQorCQlkaCA9IG5ldyBEYXRhSGFuZGxlcigKKwkJCW5ldyBJTUFQTmVzdGVkTWVzc2FnZShtZXNzYWdlLCAKKwkJCQkJICAgICAgYnMuYm9kaWVzWzBdLAorCQkJCQkgICAgICBicy5lbnZlbG9wZSwKKwkJCQkJICAgICAgc2VjdGlvbklkKSwKKwkJCXR5cGUKKwkJICAgICApOworCX0KKworCXJldHVybiBzdXBlci5nZXREYXRhSGFuZGxlcigpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldERhdGFIYW5kbGVyKERhdGFIYW5kbGVyIGNvbnRlbnQpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXRocm93IG5ldyBJbGxlZ2FsV3JpdGVFeGNlcHRpb24oIklNQVBCb2R5UGFydCBpcyByZWFkLW9ubHkiKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRDb250ZW50KE9iamVjdCBvLCBTdHJpbmcgdHlwZSkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJdGhyb3cgbmV3IElsbGVnYWxXcml0ZUV4Y2VwdGlvbigiSU1BUEJvZHlQYXJ0IGlzIHJlYWQtb25seSIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldENvbnRlbnQoTXVsdGlwYXJ0IG1wKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwl0aHJvdyBuZXcgSWxsZWdhbFdyaXRlRXhjZXB0aW9uKCJJTUFQQm9keVBhcnQgaXMgcmVhZC1vbmx5Iik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZ1tdIGdldEhlYWRlcihTdHJpbmcgbmFtZSkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJbG9hZEhlYWRlcnMoKTsKKwlyZXR1cm4gc3VwZXIuZ2V0SGVhZGVyKG5hbWUpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldEhlYWRlcihTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKQorCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwl0aHJvdyBuZXcgSWxsZWdhbFdyaXRlRXhjZXB0aW9uKCJJTUFQQm9keVBhcnQgaXMgcmVhZC1vbmx5Iik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgYWRkSGVhZGVyKFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsdWUpCisJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXRocm93IG5ldyBJbGxlZ2FsV3JpdGVFeGNlcHRpb24oIklNQVBCb2R5UGFydCBpcyByZWFkLW9ubHkiKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCByZW1vdmVIZWFkZXIoU3RyaW5nIG5hbWUpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXRocm93IG5ldyBJbGxlZ2FsV3JpdGVFeGNlcHRpb24oIklNQVBCb2R5UGFydCBpcyByZWFkLW9ubHkiKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRW51bWVyYXRpb248SGVhZGVyPiBnZXRBbGxIZWFkZXJzKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJbG9hZEhlYWRlcnMoKTsKKwlyZXR1cm4gc3VwZXIuZ2V0QWxsSGVhZGVycygpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBFbnVtZXJhdGlvbjxIZWFkZXI+IGdldE1hdGNoaW5nSGVhZGVycyhTdHJpbmdbXSBuYW1lcykKKwkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJbG9hZEhlYWRlcnMoKTsKKwlyZXR1cm4gc3VwZXIuZ2V0TWF0Y2hpbmdIZWFkZXJzKG5hbWVzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRW51bWVyYXRpb248SGVhZGVyPiBnZXROb25NYXRjaGluZ0hlYWRlcnMoU3RyaW5nW10gbmFtZXMpCisJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWxvYWRIZWFkZXJzKCk7CisJcmV0dXJuIHN1cGVyLmdldE5vbk1hdGNoaW5nSGVhZGVycyhuYW1lcyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgYWRkSGVhZGVyTGluZShTdHJpbmcgbGluZSkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJdGhyb3cgbmV3IElsbGVnYWxXcml0ZUV4Y2VwdGlvbigiSU1BUEJvZHlQYXJ0IGlzIHJlYWQtb25seSIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBFbnVtZXJhdGlvbjxTdHJpbmc+IGdldEFsbEhlYWRlckxpbmVzKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJbG9hZEhlYWRlcnMoKTsKKwlyZXR1cm4gc3VwZXIuZ2V0QWxsSGVhZGVyTGluZXMoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRW51bWVyYXRpb248U3RyaW5nPiBnZXRNYXRjaGluZ0hlYWRlckxpbmVzKFN0cmluZ1tdIG5hbWVzKQorCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlsb2FkSGVhZGVycygpOworCXJldHVybiBzdXBlci5nZXRNYXRjaGluZ0hlYWRlckxpbmVzKG5hbWVzKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRW51bWVyYXRpb248U3RyaW5nPiBnZXROb25NYXRjaGluZ0hlYWRlckxpbmVzKFN0cmluZ1tdIG5hbWVzKQorCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlsb2FkSGVhZGVycygpOworCXJldHVybiBzdXBlci5nZXROb25NYXRjaGluZ0hlYWRlckxpbmVzKG5hbWVzKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN5bmNocm9uaXplZCB2b2lkIGxvYWRIZWFkZXJzKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKGhlYWRlcnNMb2FkZWQpCisJICAgIHJldHVybjsKKworCS8vICJoZWFkZXJzIiBzaG91bGQgbmV2ZXIgYmUgbnVsbCBzaW5jZSBpdCdzIHNldCBpbiB0aGUgY29uc3RydWN0b3IuCisJLy8gSWYgc29tZXRoaW5nIGRpZCBnbyB3cm9uZyB0aGlzIHdpbGwgZml4IGl0LCBidXQgaXMgYW4gdW5zeW5jaHJvbml6ZWQKKwkvLyBhc3NpZ25tZW50IG9mICJoZWFkZXJzIi4KKwlpZiAoaGVhZGVycyA9PSBudWxsKQorCSAgICBoZWFkZXJzID0gbmV3IEludGVybmV0SGVhZGVycygpOworCisJLy8gbG9hZCBoZWFkZXJzCisKKwkvLyBBY3F1aXJlIE1lc3NhZ2VDYWNoZUxvY2ssIHRvIGZyZWV6ZSBzZXFudW0uCisJc3luY2hyb25pemVkKG1lc3NhZ2UuZ2V0TWVzc2FnZUNhY2hlTG9jaygpKSB7CisJICAgIHRyeSB7CisJCUlNQVBQcm90b2NvbCBwID0gbWVzc2FnZS5nZXRQcm90b2NvbCgpOworCisJCS8vIENoZWNrIHdoZXRoZXIgdGhpcyBtZXNzYWdlIGdvdCBleHB1bmdlZAorCQltZXNzYWdlLmNoZWNrRXhwdW5nZWQoKTsKKworCQlpZiAocC5pc1JFVjEoKSkgeworCQkgICAgaW50IHNlcW51bSA9IG1lc3NhZ2UuZ2V0U2VxdWVuY2VOdW1iZXIoKTsKKwkJICAgIEJPRFkgYiA9IHAucGVla0JvZHkoc2VxbnVtLCBzZWN0aW9uSWQgKyAiLk1JTUUiKTsKKworCQkgICAgaWYgKGIgPT0gbnVsbCkKKwkJCXRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oIkZhaWxlZCB0byBmZXRjaCBoZWFkZXJzIik7CisKKwkJICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGJpcyA9IGIuZ2V0Qnl0ZUFycmF5SW5wdXRTdHJlYW0oKTsKKwkJICAgIGlmIChiaXMgPT0gbnVsbCkKKwkJCXRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oIkZhaWxlZCB0byBmZXRjaCBoZWFkZXJzIik7CisKKwkJICAgIGhlYWRlcnMubG9hZChiaXMpOworCisJCX0gZWxzZSB7CisKKwkJICAgIC8vIFJGQyAxNzMwIGRvZXMgbm90IHByb3ZpZGUgZm9yIGZldGNoaW5nIEJvZHlQYXJ0IGhlYWRlcnMKKwkJICAgIC8vIFNvLCBqdXN0IGR1bXAgdGhlIFJGQzE3MzAgQk9EWVNUUlVDVFVSRSBpbnRvIHRoZQorCQkgICAgLy8gaGVhZGVyU3RvcmUKKwkJICAgIAorCQkgICAgLy8gQ29udGVudC1UeXBlCisJCSAgICBoZWFkZXJzLmFkZEhlYWRlcigiQ29udGVudC1UeXBlIiwgdHlwZSk7CisJCSAgICAvLyBDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nCisJCSAgICBoZWFkZXJzLmFkZEhlYWRlcigiQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZyIsIGJzLmVuY29kaW5nKTsKKwkJICAgIC8vIENvbnRlbnQtRGVzY3JpcHRpb24KKwkJICAgIGlmIChicy5kZXNjcmlwdGlvbiAhPSBudWxsKQorCQkJaGVhZGVycy5hZGRIZWFkZXIoIkNvbnRlbnQtRGVzY3JpcHRpb24iLAorCQkJCQkJCSAgICBicy5kZXNjcmlwdGlvbik7CisJCSAgICAvLyBDb250ZW50LUlECisJCSAgICBpZiAoYnMuaWQgIT0gbnVsbCkKKwkJCWhlYWRlcnMuYWRkSGVhZGVyKCJDb250ZW50LUlEIiwgYnMuaWQpOworCQkgICAgLy8gQ29udGVudC1NRDUKKwkJICAgIGlmIChicy5tZDUgIT0gbnVsbCkKKwkJCWhlYWRlcnMuYWRkSGVhZGVyKCJDb250ZW50LU1ENSIsIGJzLm1kNSk7CisJCX0KKwkgICAgfSBjYXRjaCAoQ29ubmVjdGlvbkV4Y2VwdGlvbiBjZXgpIHsKKwkJdGhyb3cgbmV3IEZvbGRlckNsb3NlZEV4Y2VwdGlvbigKKwkJCSAgICBtZXNzYWdlLmdldEZvbGRlcigpLCBjZXguZ2V0TWVzc2FnZSgpKTsKKwkgICAgfSBjYXRjaCAoUHJvdG9jb2xFeGNlcHRpb24gcGV4KSB7CisJCXRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24ocGV4LmdldE1lc3NhZ2UoKSwgcGV4KTsKKwkgICAgfQorCX0KKwloZWFkZXJzTG9hZGVkID0gdHJ1ZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvSU1BUEZvbGRlci5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0lNQVBGb2xkZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NGYyZjU2Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0lNQVBGb2xkZXIuamF2YQpAQCAtMCwwICsxLDQxNTMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmltYXA7CisKK2ltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOworaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTGV2ZWw7CitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmEubmV0LlNvY2tldFRpbWVvdXRFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuU29ja2V0Q2hhbm5lbDsKKworaW1wb3J0IGphdmF4Lm1haWwuKjsKK2ltcG9ydCBqYXZheC5tYWlsLmV2ZW50Lio7CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC4qOworaW1wb3J0IGphdmF4Lm1haWwuc2VhcmNoLio7CisKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5Qcm9wVXRpbDsKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5NYWlsTG9nZ2VyOworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLkNSTEZPdXRwdXRTdHJlYW07CitpbXBvcnQgY29tLnN1bi5tYWlsLmlhcC4qOworaW1wb3J0IGNvbS5zdW4ubWFpbC5pbWFwLnByb3RvY29sLio7CisKKy8qKgorICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIGFuIElNQVAgZm9sZGVyLiA8cD4KKyAqCisgKiBBIGNsb3NlZCBJTUFQRm9sZGVyIG9iamVjdCBzaGFyZXMgYSBwcm90b2NvbCBjb25uZWN0aW9uIHdpdGggaXRzIElNQVBTdG9yZQorICogb2JqZWN0LiBXaGVuIHRoZSBmb2xkZXIgaXMgb3BlbmVkLCBpdCBnZXRzIGl0cyBvd24gcHJvdG9jb2wgY29ubmVjdGlvbi4gPHA+CisgKgorICogQXBwbGljYXRpb25zIHRoYXQgbmVlZCB0byBtYWtlIHVzZSBvZiBJTUFQLXNwZWNpZmljIGZlYXR1cmVzIG1heSBjYXN0CisgKiBhIDxjb2RlPkZvbGRlcjwvY29kZT4gb2JqZWN0IHRvIGFuIDxjb2RlPklNQVBGb2xkZXI8L2NvZGU+IG9iamVjdCBhbmQKKyAqIHVzZSB0aGUgbWV0aG9kcyBvbiB0aGlzIGNsYXNzLiA8cD4KKyAqCisgKiBUaGUge0BsaW5rICNnZXRRdW90YSBnZXRRdW90YX0gYW5kCisgKiB7QGxpbmsgI3NldFF1b3RhIHNldFF1b3RhfSBtZXRob2RzIHN1cHBvcnQgdGhlIElNQVAgUVVPVEEgZXh0ZW5zaW9uLgorICogUmVmZXIgdG8gPEEgSFJFRj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjA4Ny50eHQiPlJGQyAyMDg3PC9BPgorICogZm9yIG1vcmUgaW5mb3JtYXRpb24uIDxwPgorICoKKyAqIFRoZSB7QGxpbmsgI2dldEFDTCBnZXRBQ0x9LCB7QGxpbmsgI2FkZEFDTCBhZGRBQ0x9LAorICoge0BsaW5rICNyZW1vdmVBQ0wgcmVtb3ZlQUNMfSwge0BsaW5rICNhZGRSaWdodHMgYWRkUmlnaHRzfSwKKyAqIHtAbGluayAjcmVtb3ZlUmlnaHRzIHJlbW92ZVJpZ2h0c30sIHtAbGluayAjbGlzdFJpZ2h0cyBsaXN0UmlnaHRzfSwgYW5kCisgKiB7QGxpbmsgI215UmlnaHRzIG15UmlnaHRzfSBtZXRob2RzIHN1cHBvcnQgdGhlIElNQVAgQUNMIGV4dGVuc2lvbi4KKyAqIFJlZmVyIHRvIDxBIEhSRUY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIwODYudHh0Ij5SRkMgMjA4NjwvQT4KKyAqIGZvciBtb3JlIGluZm9ybWF0aW9uLiA8cD4KKyAqCisgKiBUaGUge0BsaW5rICNnZXRTb3J0ZWRNZXNzYWdlcyBnZXRTb3J0ZWRNZXNzYWdlc30KKyAqIG1ldGhvZHMgc3VwcG9ydCB0aGUgSU1BUCBTT1JUIGV4dGVuc2lvbi4KKyAqIFJlZmVyIHRvIDxBIEhSRUY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzUyNTYudHh0Ij5SRkMgNTI1NjwvQT4KKyAqIGZvciBtb3JlIGluZm9ybWF0aW9uLiA8cD4KKyAqCisgKiBUaGUge0BsaW5rICNvcGVuKGludCxjb20uc3VuLm1haWwuaW1hcC5SZXN5bmNEYXRhKSBvcGVuKGludCxSZXN5bmNEYXRhKX0KKyAqIG1ldGhvZCBhbmQge0BsaW5rIGNvbS5zdW4ubWFpbC5pbWFwLlJlc3luY0RhdGEgUmVzeW5jRGF0YX0gY2xhc3Mgc3VwcG9ydHMKKyAqIHRoZSBJTUFQIENPTkRTVE9SRSBhbmQgUVJFU1lOQyBleHRlbnNpb25zLgorICogUmVmZXIgdG8gPEEgSFJFRj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjNDU1MS50eHQiPlJGQyA0NTUxPC9BPgorICogYW5kIDxBIEhSRUY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzUxNjIudHh0Ij5SRkMgNTE2MjwvQT4KKyAqIGZvciBtb3JlIGluZm9ybWF0aW9uLiA8cD4KKyAqCisgKiBUaGUge0BsaW5rICNkb0NvbW1hbmQgZG9Db21tYW5kfSBtZXRob2QgYW5kCisgKiB7QGxpbmsgSU1BUEZvbGRlci5Qcm90b2NvbENvbW1hbmQgSU1BUEZvbGRlci5Qcm90b2NvbENvbW1hbmR9CisgKiBpbnRlcmZhY2Ugc3VwcG9ydCB1c2Ugb2YgYXJiaXRyYXJ5IElNQVAgcHJvdG9jb2wgY29tbWFuZHMuIDxwPgorICoKKyAqIFNlZSB0aGUgPGEgaHJlZj0icGFja2FnZS1zdW1tYXJ5Lmh0bWwiPmNvbS5zdW4ubWFpbC5pbWFwPC9hPiBwYWNrYWdlCisgKiBkb2N1bWVudGF0aW9uIGZvciBmdXJ0aGVyIGluZm9ybWF0aW9uIG9uIHRoZSBJTUFQIHByb3RvY29sIHByb3ZpZGVyLiA8cD4KKyAqCisgKiA8c3Ryb25nPldBUk5JTkc6PC9zdHJvbmc+IFRoZSBBUElzIHVuaXF1ZSB0byB0aGlzIGNsYXNzIHNob3VsZCBiZQorICogY29uc2lkZXJlZCA8c3Ryb25nPkVYUEVSSU1FTlRBTDwvc3Ryb25nPi4gIFRoZXkgbWF5IGJlIGNoYW5nZWQgaW4gdGhlCisgKiBmdXR1cmUgaW4gd2F5cyB0aGF0IGFyZSBpbmNvbXBhdGlibGUgd2l0aCBhcHBsaWNhdGlvbnMgdXNpbmcgdGhlCisgKiBjdXJyZW50IEFQSXMuCisgKgorICogQGF1dGhvciAgSm9obiBNYW5pCisgKiBAYXV0aG9yICBCaWxsIFNoYW5ub24KKyAqIEBhdXRob3IgIEppbSBHbGVubm9uCisgKi8KKworLyoKKyAqIFRoZSBmb2xkZXIgb2JqZWN0IGl0c2VsZiBzZXJ2ZXMgYXMgYSBsb2NrIGZvciB0aGUgZm9sZGVyJ3Mgc3RhdGUKKyAqIEVYQ0VQVCBmb3IgdGhlIG1lc3NhZ2UgY2FjaGUgKHNlZSBiZWxvdyksIHR5cGljYWxseSBieSB1c2luZworICogc3luY2hyb25pemVkIG1ldGhvZHMuICBXaGVuIGNoZWNraW5nIHRoYXQgYSBmb2xkZXIgaXMgb3BlbiBvcgorICogY2xvc2VkLCB0aGUgZm9sZGVyJ3MgbG9jayBtdXN0IGJlIGhlbGQuICBJdCdzIGltcG9ydGFudCB0aGF0IHRoZQorICogZm9sZGVyJ3MgbG9jayBpcyBhY3F1aXJlZCBiZWZvcmUgdGhlIG1lc3NhZ2VDYWNoZUxvY2sgKHNlZSBiZWxvdykuCisgKiBUaHVzLCB0aGUgbG9ja2luZyBoaWVyYXJjaHkgaXMgdGhhdCB0aGUgZm9sZGVyIGxvY2ssIHdoaWxlIG9wdGlvbmFsLAorICogbXVzdCBiZSBhY3F1aXJlZCBiZWZvcmUgdGhlIG1lc3NhZ2VDYWNoZUxvY2ssIGlmIGl0J3MgYWNxdWlyZWQgYXQKKyAqIGFsbC4gIEJlIGVzcGVjaWFsbHkgY2FyZWZ1bCBvZiBjYWxsYmFja3MgdGhhdCBvY2N1ciB3aGlsZSBob2xkaW5nCisgKiB0aGUgbWVzc2FnZUNhY2hlTG9jayBpbnRvIChlLmcuKSBzdXBlcmNsYXNzIEZvbGRlciBtZXRob2RzIHRoYXQgYXJlCisgKiBzeW5jaHJvbml6ZWQuICBOb3RlIHRoYXQgbWV0aG9kcyBpbiBJTUFQTWVzc2FnZSB3aWxsIGFjcXVpcmUgdGhlCisgKiBtZXNzYWdlQ2FjaGVMb2NrIHdpdGhvdXQgYWNxdWlyaW5nIHRoZSBmb2xkZXIgbG9jay4gPHA+CisgKgorICogV2hlbiBhIGZvbGRlciBpcyBvcGVuZWQsIGl0IGNyZWF0ZXMgYSBtZXNzYWdlQ2FjaGUgKGEgVmVjdG9yKSBvZiAKKyAqIGVtcHR5IElNQVBNZXNzYWdlIG9iamVjdHMuIEVhY2ggTWVzc2FnZSBoYXMgYSBtZXNzYWdlTnVtYmVyIC0gd2hpY2gKKyAqIGlzIGl0cyBpbmRleCBpbnRvIHRoZSBtZXNzYWdlQ2FjaGUsIGFuZCBhIHNlcXVlbmNlTnVtYmVyIC0gd2hpY2ggaXMKKyAqIGl0cyBJTUFQIHNlcXVlbmNlLW51bWJlci4gQWxsIG9wZXJhdGlvbnMgb24gYSBNZXNzYWdlIHdoaWNoIGludm9sdmUKKyAqIGNvbW11bmljYXRpb24gd2l0aCB0aGUgc2VydmVyLCB1c2UgdGhlIG1lc3NhZ2UncyBzZXF1ZW5jZU51bWJlci4gPHA+CisgKgorICogVGhlIG1vc3QgaW1wb3J0YW50IHRoaW5nIHRvIG5vdGUgaGVyZSBpcyB0aGF0IHRoZSBzZXJ2ZXIgY2FuIHNlbmQKKyAqIHVuc29saWNpdGVkIEVYUFVOR0Ugbm90aWZpY2F0aW9ucyBhcyBwYXJ0IG9mIHRoZSByZXNwb25zZXMgZm9yICJtb3N0IgorICogY29tbWFuZHMuIFJlZmVyIFJGQyAzNTAxLCBzZWN0aW9ucyA1LjMgJiA1LjUgZm9yIGdvcnkgZGV0YWlscy4gQWxzbywgCisgKiB0aGUgc2VydmVyIHNlbmRzIHRoZXNlICBub3RpZmljYXRpb25zIEFGVEVSIHRoZSBtZXNzYWdlIGhhcyBiZWVuIAorICogZXhwdW5nZWQuIEFuZCBvbmNlIGEgbWVzc2FnZSBpcyBleHB1bmdlZCwgdGhlIHNlcXVlbmNlLW51bWJlcnMgb2YgCisgKiB0aG9zZSBtZXNzYWdlcyBhZnRlciB0aGUgZXhwdW5nZWQgb25lIGFyZSByZW51bWJlcmVkLiBUaGlzIGVzc2VudGlhbGx5CisgKiBtZWFucyB0aGF0IHRoZSBtYXBwaW5nIGJldHdlZW4gKmFueSogTWVzc2FnZSBhbmQgaXRzIHNlcXVlbmNlLW51bWJlciAKKyAqIGNhbiBjaGFuZ2UgaW4gdGhlIHBlcmlvZCB3aGVuIGEgSU1BUCBjb21tYW5kIGlzIGlzc3VlZCBhbmQgaXRzIHJlc3BvbnNlcworICogYXJlIHByb2Nlc3NlZC4gSGVuY2Ugd2UgaW1wb3NlIGEgc3RyaWN0IGxvY2tpbmcgbW9kZWwgYXMgZm9sbG93czogPHA+CisgKgorICogV2UgZGVmaW5lIG9uZSBtdXRleCBwZXIgZm9sZGVyIC0gdGhpcyBpcyBqdXN0IGEgSmF2YSBPYmplY3QgKG5hbWVkIAorICogbWVzc2FnZUNhY2hlTG9jaykuIEFueSB0aW1lIGEgY29tbWFuZCBpcyB0byBiZSBpc3N1ZWQgdG8gdGhlIElNQVAKKyAqIHNlcnZlciAoaS5lLiwgYW55dGltZSB0aGUgY29ycmVzcG9uZGluZyBJTUFQUHJvdG9jb2wgbWV0aG9kIGlzCisgKiBpbnZva2VkKSwgZm9sbG93IHRoZSBiZWxvdyBzdHlsZToKKyAqCQkKKyAqCXN5bmNocm9uaXplZCAobWVzc2FnZUNhY2hlTG9jaykgeyAvLyBBQ1FVSVJFIExPQ0sKKyAqCSAgICBpc3N1ZSBjb21tYW5kICgpCisgKgkgICAgCisgKgkgICAgLy8gVGhlIHJlc3BvbnNlIHByb2Nlc3NpbmcgaXMgdHlwaWNhbGx5IGRvbmUgd2l0aGluCisgKgkgICAgLy8gdGhlIGhhbmRsZVJlc3BvbnNlKCkgY2FsbGJhY2suIEEgZmV3IGNvbW1hbmRzIChGZXRjaCwKKyAqCSAgICAvLyBFeHB1bmdlKSByZXR1cm4gKmFsbCogcmVzcG9uc2VzIGFuZCBoZW5jZSB0aGVpcgorICoJICAgIC8vIHByb2Nlc3NpbmcgaXMgZG9uZSBoZXJlIGl0c2VsZi4gTm93LCBhcyBwYXJ0IG9mIHRoZQorICoJICAgIC8vIHByb2Nlc3NpbmcgdW5zb2xpY2l0ZWQgRVhQVU5HRSByZXNwb25zZXMsIHdlIHJlbnVtYmVyCisgKgkgICAgLy8gdGhlIG5lY2Vzc2FyeSBzZXF1ZW5jZS1udW1iZXJzLiBUaHVzIHRoZSByZW51bWJlcmluZworICoJICAgIC8vIGhhcHBlbnMgd2l0aGluIHRoaXMgY3JpdGljYWwtcmVnaW9uLCBzdXJyb3VuZGVkIGJ5CisgKgkgICAgLy8gbG9ja3MuCisgKgkgICAgcHJvY2VzcyByZXNwb25zZXMgKCkKKyAqCX0gLy8gUkVMRUFTRSBMT0NLCisgKgorICogVGhpcyB0ZWNobmlxdWUgaXMgdXNlZCBib3RoIGJ5IG1ldGhvZHMgaW4gSU1BUEZvbGRlciBhbmQgYnkgbWV0aG9kcworICogaW4gSU1BUE1lc3NhZ2UgYW5kIG90aGVyIGNsYXNzZXMgdGhhdCBvcGVyYXRlIG9uIGRhdGEgaW4gdGhlIGZvbGRlci4KKyAqIE5vdGUgdGhhdCBob2xkaW5nIHRoZSBtZXNzYWdlQ2FjaGVMb2NrIGhhcyB0aGUgc2lkZSBlZmZlY3Qgb2YKKyAqIHByZXZlbnRpbmcgdGhlIGZvbGRlciBmcm9tIGJlaW5nIGNsb3NlZCwgYW5kIHRodXMgZW5zdXJpbmcgdGhhdCB0aGUKKyAqIGZvbGRlcidzIHByb3RvY29sIG9iamVjdCBpcyBzdGlsbCB2YWxpZC4gIFRoZSBwcm90b2NvbCBvYmplY3Qgc2hvdWxkCisgKiBvbmx5IGJlIGFjY2Vzc2VkIHdoaWxlIGhvbGRpbmcgdGhlIG1lc3NhZ2VDYWNoZUxvY2sgKGV4Y2VwdCBmb3IgY2FsbHMKKyAqIHRvIElNQVBQcm90b2NvbC5pc1JFVjEoKSwgd2hpY2ggZG9uJ3QgbmVlZCB0byBiZSBwcm90ZWN0ZWQgYmVjYXVzZSBpdAorICogZG9lc24ndCBhY2Nlc3MgdGhlIHNlcnZlcikuCisgKgkgICAgCisgKiBOb3RlIHRoYXQgaW50ZXJhY3Rpb25zIHdpdGggdGhlIFN0b3JlJ3MgcHJvdG9jb2wgY29ubmVjdGlvbiBkbworICogbm90IGhhdmUgdG8gYmUgcHJvdGVjdGVkIGFzIGFib3ZlLCBzaW5jZSB0aGUgU3RvcmUncyBwcm90b2NvbCBpcworICogbmV2ZXIgaW4gYSAibWVhbmluZ2Z1bCIgU0VMRUNULWVkIHN0YXRlLgorICovCisKK3B1YmxpYyBjbGFzcyBJTUFQRm9sZGVyIGV4dGVuZHMgRm9sZGVyIGltcGxlbWVudHMgVUlERm9sZGVyLCBSZXNwb25zZUhhbmRsZXIgeworICAgIAorICAgIHByb3RlY3RlZCB2b2xhdGlsZSBTdHJpbmcgZnVsbE5hbWU7CS8vIGZ1bGwgbmFtZQorICAgIHByb3RlY3RlZCBTdHJpbmcgbmFtZTsJCS8vIG5hbWUKKyAgICBwcm90ZWN0ZWQgaW50IHR5cGU7CQkJLy8gZm9sZGVyIHR5cGUuIAorICAgIHByb3RlY3RlZCBjaGFyIHNlcGFyYXRvcjsJCS8vIHNlcGFyYXRvcgorICAgIHByb3RlY3RlZCBGbGFncyBhdmFpbGFibGVGbGFnczsgCS8vIGF2YWlsYWJsZSBmbGFncworICAgIHByb3RlY3RlZCBGbGFncyBwZXJtYW5lbnRGbGFnczsgCS8vIHBlcm1hbmVudCBmbGFncworICAgIHByb3RlY3RlZCB2b2xhdGlsZSBib29sZWFuIGV4aXN0czsJLy8gd2hldGhlciB0aGlzIGZvbGRlciByZWFsbHkgZXhpc3RzID8KKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpc05hbWVzcGFjZSA9IGZhbHNlOyAvLyBmb2xkZXIgaXMgYSBuYW1lc3BhY2UgbmFtZQorICAgIHByb3RlY3RlZCB2b2xhdGlsZSBTdHJpbmdbXSBhdHRyaWJ1dGVzOy8vIG5hbWUgYXR0cmlidXRlcyBmcm9tIExJU1QgcmVzcG9uc2UKKworICAgIHByb3RlY3RlZCB2b2xhdGlsZSBJTUFQUHJvdG9jb2wgcHJvdG9jb2w7IC8vIHRoaXMgZm9sZGVyJ3MgcHJvdG9jb2wgb2JqZWN0CisgICAgcHJvdGVjdGVkIE1lc3NhZ2VDYWNoZSBtZXNzYWdlQ2FjaGU7Ly8gbWVzc2FnZSBjYWNoZQorICAgIC8vIGFjY2Vzc29yIGxvY2sgZm9yIG1lc3NhZ2UgY2FjaGUKKyAgICBwcm90ZWN0ZWQgZmluYWwgT2JqZWN0IG1lc3NhZ2VDYWNoZUxvY2sgPSBuZXcgT2JqZWN0KCk7CisKKyAgICBwcm90ZWN0ZWQgSGFzaHRhYmxlPExvbmcsIElNQVBNZXNzYWdlPiB1aWRUYWJsZTsgLy8gVUlELT5NZXNzYWdlIGhhc2h0YWJsZQorCisgICAgLyogQW4gSU1BUCBkZWxpbWl0ZXIgaXMgYSA3Yml0IFVTLUFTQ0lJIGNoYXJhY3Rlci4gKGV4Y2VwdCBOVUwpLgorICAgICAqIFdlIHVzZSAnXHVmZmZmJyAoYSBub24gN2JpdCBjaGFyYWN0ZXIpIHRvIGluZGljYXRlIHRoYXQgd2UgaGF2ZW50CisgICAgICogeWV0IGRldGVybWluZWQgd2hhdCB0aGUgc2VwYXJhdG9yIGNoYXJhY3RlciBpcy4KKyAgICAgKiBXZSB1c2UgJ1x1MDAwMCcgKE5VTCkgdG8gaW5kaWNhdGUgdGhhdCBubyBzZXBhcmF0b3IgY2hhcmFjdGVyCisgICAgICogZXhpc3RzLCBpLmUuLCBhIGZsYXQgaGllcmFyY2h5CisgICAgICovCisgICAgc3RhdGljIGZpbmFsIHByb3RlY3RlZCBjaGFyIFVOS05PV05fU0VQQVJBVE9SID0gJ1x1ZmZmZic7CisKKyAgICBwcml2YXRlIHZvbGF0aWxlIGJvb2xlYW4gb3BlbmVkID0gZmFsc2U7IAkvLyBpcyB0aGlzIGZvbGRlciBvcGVuZWQgPworCisgICAgLyogVGhpcyBmaWVsZCB0cmFja3MgdGhlIHN0YXRlIG9mIHRoaXMgZm9sZGVyLiBJZiB0aGUgZm9sZGVyIGlzIGNsb3NlZAorICAgICAqIGR1ZSB0byBleHRlcm5hbCBjYXVzZXMgKGkuZSwgbm90IHRocnUgdGhlIGNsb3NlKCkgbWV0aG9kKSwgdGhlbgorICAgICAqIHRoaXMgZmllbGQgd2lsbCByZW1haW4gZmFsc2UuIElmIHRoZSBmb2xkZXIgaXMgY2xvc2VkIHRocnUgdGhlCisgICAgICogY2xvc2UoKSBtZXRob2QsIHRoZW4gdGhpcyBmaWVsZCBpcyBzZXQgdG8gdHJ1ZS4KKyAgICAgKgorICAgICAqIElmIHJlYWxseUNsb3NlZCBpcyBmYWxzZSwgdGhlbiBhIEZvbGRlckNsb3NlZEV4Y2VwdGlvbiBpcworICAgICAqIGdlbmVyYXRlZCB3aGVuIGEgbWV0aG9kIGlzIGludm9rZWQgb24gYW55IE1lc3NhZ2luZyBvYmplY3QKKyAgICAgKiBvd25lZCBieSB0aGlzIGZvbGRlci4gSWYgcmVhbGx5Q2xvc2VkIGlzIHRydWUsIHRoZW4gdGhlCisgICAgICogSWxsZWdhbFN0YXRlRXhjZXB0aW9uIHJ1bnRpbWUgZXhjZXB0aW9uIGlzIHRocm93bi4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gcmVhbGx5Q2xvc2VkID0gdHJ1ZTsKKworICAgIC8qCisgICAgICogVGhlIGlkbGVTdGF0ZSBmaWVsZCBzdXBwb3J0cyB0aGUgSURMRSBjb21tYW5kLgorICAgICAqIE5vcm1hbGx5IHdoZW4gZXhlY3V0aW5nIGFuIElNQVAgY29tbWFuZCB3ZSBob2xkIHRoZQorICAgICAqIG1lc3NhZ2VDYWNoZUxvY2sgYW5kIG9mdGVuIHRoZSBmb2xkZXIgbG9jayAoc2VlIGFib3ZlKS4KKyAgICAgKiBXaGlsZSBleGVjdXRpbmcgdGhlIElETEUgY29tbWFuZCB3ZSBjYW4ndCBob2xkIGVpdGhlcgorICAgICAqIG9mIHRoZXNlIGxvY2tzIG9yIGl0IHdvdWxkIHByZXZlbnQgb3RoZXIgdGhyZWFkcyBmcm9tCisgICAgICogZW50ZXJpbmcgRm9sZGVyIG1ldGhvZHMgZXZlbiBmYXIgZW5vdWdoIHRvIGNoZWNrIHdoZXRoZXIKKyAgICAgKiBhbiBJRExFIGNvbW1hbmQgaXMgaW4gcHJvZ3Jlc3MuICBXZSBuZWVkIHRvIGNoZWNrIGJlZm9yZQorICAgICAqIGlzc3VpbmcgYW5vdGhlciBjb21tYW5kIHNvIHRoYXQgd2UgY2FuIGFib3J0IHRoZSBJRExFCisgICAgICogY29tbWFuZC4KKyAgICAgKgorICAgICAqIFRoZSBpZGxlU3RhdGUgZmllbGQgaXMgcHJvdGVjdGVkIGJ5IHRoZSBtZXNzYWdlQ2FjaGVMb2NrLgorICAgICAqIFRoZSBSVU5OSU5HIHN0YXRlIGlzIHRoZSBub3JtYWwgc3RhdGUgYW5kIG1lYW5zIG5vIElETEUKKyAgICAgKiBjb21tYW5kIGlzIGluIHByb2dyZXNzLiAgVGhlIElETEUgc3RhdGUgbWVhbnMgd2UndmUgaXNzdWVkCisgICAgICogYW4gSURMRSBjb21tYW5kIGFuZCBhcmUgcmVhZGluZyByZXNwb25zZXMuICBUaGUgQUJPUlRJTkcKKyAgICAgKiBzdGF0ZSBtZWFucyB3ZSd2ZSBzZW50IHRoZSBET05FIGNvbnRpbnVhdGlvbiBjb21tYW5kIGFuZAorICAgICAqIGFyZSB3YWl0aW5nIGZvciB0aGUgdGhyZWFkIHJ1bm5pbmcgdGhlIElETEUgY29tbWFuZCB0bworICAgICAqIGJyZWFrIG91dCBvZiBpdHMgcmVhZCBsb29wLgorICAgICAqCisgICAgICogV2hlbiBhbiBJRExFIGNvbW1hbmQgaXMgaW4gcHJvZ3Jlc3MsIHRoZSB0aHJlYWQgY2FsbGluZworICAgICAqIHRoZSBpZGxlIG1ldGhvZCB3aWxsIGJlIHJlYWRpbmcgZnJvbSB0aGUgSU1BUCBjb25uZWN0aW9uCisgICAgICogd2hpbGUgaG9sZGluZyBuZWl0aGVyIHRoZSBmb2xkZXIgbG9jayBub3IgdGhlIG1lc3NhZ2VDYWNoZUxvY2suCisgICAgICogSXQncyBvYnZpb3VzbHkgY3JpdGljYWwgdGhhdCBubyBvdGhlciB0aHJlYWQgdHJ5IHRvIHNlbmQgYQorICAgICAqIGNvbW1hbmQgb3IgcmVhZCBmcm9tIHRoZSBjb25uZWN0aW9uIHdoaWxlIGluIHRoaXMgc3RhdGUuCisgICAgICogSG93ZXZlciwgb3RoZXIgdGhyZWFkcyBjYW4gc2VuZCB0aGUgRE9ORSBjb250aW51YXRpb24KKyAgICAgKiBjb21tYW5kIHRoYXQgd2lsbCBjYXVzZSB0aGUgc2VydmVyIHRvIGJyZWFrIG91dCBvZiB0aGUgSURMRQorICAgICAqIGxvb3AgYW5kIHNlbmQgdGhlIGVuZGluZyB0YWcgcmVzcG9uc2UgdG8gdGhlIElETEUgY29tbWFuZC4KKyAgICAgKiBUaGUgdGhyZWFkIGluIHRoZSBpZGxlIG1ldGhvZCB0aGF0J3MgcmVhZGluZyB0aGUgcmVzcG9uc2VzCisgICAgICogZnJvbSB0aGUgSURMRSBjb21tYW5kIHdpbGwgc2VlIHRoaXMgZW5kaW5nIHJlc3BvbnNlIGFuZAorICAgICAqIGNvbXBsZXRlIHRoZSBpZGxlIG1ldGhvZCwgc2V0dGluZyB0aGUgaWRsZVN0YXRlIGZpZWxkIGJhY2sKKyAgICAgKiB0byBSVU5OSU5HLCBhbmQgbm90aWZ5aW5nIGFueSB0aHJlYWRzIHdhaXRpbmcgdG8gdXNlIHRoZQorICAgICAqIGNvbm5lY3Rpb24uCisgICAgICoKKyAgICAgKiBBbGwgdXNlcyBvZiB0aGUgSU1BUCBjb25uZWN0aW9uIChJTUFQUHJvdG9jb2wgb2JqZWN0KSBtdXN0CisgICAgICogYmUgZG9uZSB3aGlsZSBob2xkaW5nIHRoZSBtZXNzYWdlQ2FjaGVMb2NrIGFuZCBtdXN0IGJlCisgICAgICogcHJlY2VlZGVkIGJ5IGEgY2hlY2sgdG8gbWFrZSBzdXJlIGFuIElETEUgY29tbWFuZCBpcyBub3QKKyAgICAgKiBydW5uaW5nLCBhbmQgYWJvcnQgdGhlIElETEUgY29tbWFuZCBpZiBuZWNlc3NhcnkuICBXaGlsZQorICAgICAqIHdhaXRpbmcgZm9yIHRoZSBJRExFIGNvbW1hbmQgdG8gY29tcGxldGUsIHRoZXNlIG90aGVyIHRocmVhZHMKKyAgICAgKiB3aWxsIGdpdmUgdXAgdGhlIG1lc3NhZ2VDYWNoZUxvY2ssIGJ1dCBtaWdodCBzdGlsbCBiZSBob2xkaW5nCisgICAgICogdGhlIGZvbGRlciBsb2NrLiAgVGhpcyBjaGVjayBpcyBkb25lIGJ5IHRoZSBnZXRQcm90b2NvbCgpCisgICAgICogbWV0aG9kLCByZXN1bHRpbmcgaW4gYSB0eXBpY2FsIHVzYWdlIHBhdHRlcm4gb2Y6CisgICAgICoKKyAgICAgKgkgICAgc3luY2hyb25pemVkIChtZXNzYWdlQ2FjaGVMb2NrKSB7CisgICAgICoJCUlNQVBQcm90b2NvbCBwID0gZ2V0UHJvdG9jb2woKTsJLy8gbWF5IGJsb2NrIHdhaXRpbmcgZm9yIElETEUKKyAgICAgKgkJLy8gLi4uIHVzZSBwcm90b2NvbAorICAgICAqCSAgICB9CisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFJVTk5JTkcgPSAwOwkvLyBub3QgZG9pbmcgSURMRSBjb21tYW5kCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IElETEUgPSAxOwkJLy8gSURMRSBjb21tYW5kIGluIGVmZmVjdAorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBBQk9SVElORyA9IDI7CS8vIElETEUgY29tbWFuZCBhYm9ydGluZworICAgIHByaXZhdGUgaW50IGlkbGVTdGF0ZSA9IFJVTk5JTkc7CisgICAgcHJpdmF0ZSBJZGxlTWFuYWdlciBpZGxlTWFuYWdlcjsKKworICAgIHByaXZhdGUgdm9sYXRpbGUgaW50IHRvdGFsID0gLTE7CS8vIHRvdGFsIG51bWJlciBvZiBtZXNzYWdlcyBpbiB0aGUKKwkJCQkJLy8gbWVzc2FnZSBjYWNoZQorICAgIHByaXZhdGUgdm9sYXRpbGUgaW50IHJlY2VudCA9IC0xOwkvLyBudW1iZXIgb2YgcmVjZW50IG1lc3NhZ2VzCisgICAgcHJpdmF0ZSBpbnQgcmVhbFRvdGFsID0gLTE7CQkvLyB0b3RhbCBudW1iZXIgb2YgbWVzc2FnZXMgb24KKyAgICAJCQkJCS8vIHRoZSBzZXJ2ZXIKKyAgICBwcml2YXRlIGxvbmcgdWlkdmFsaWRpdHkgPSAtMTsJLy8gVUlEVmFsaWRpdHkKKyAgICBwcml2YXRlIGxvbmcgdWlkbmV4dCA9IC0xOwkJLy8gVUlETmV4dAorICAgIHByaXZhdGUgYm9vbGVhbiB1aWROb3RTdGlja3kgPSBmYWxzZTsJLy8gUkZDIDQzMTUKKyAgICBwcml2YXRlIHZvbGF0aWxlIGxvbmcgaGlnaGVzdG1vZHNlcSA9IC0xOwkvLyBSRkMgNDU1MSAtIENPTkRTVE9SRQorICAgIHByaXZhdGUgYm9vbGVhbiBkb0V4cHVuZ2VOb3RpZmljYXRpb24gPSB0cnVlOyAvLyB1c2VkIGluIGV4cHVuZ2UgaGFuZGxlcgorCisgICAgcHJpdmF0ZSBTdGF0dXMgY2FjaGVkU3RhdHVzID0gbnVsbDsKKyAgICBwcml2YXRlIGxvbmcgY2FjaGVkU3RhdHVzVGltZSA9IDA7CisKKyAgICBwcml2YXRlIGJvb2xlYW4gaGFzTWVzc2FnZUNvdW50TGlzdGVuZXIgPSBmYWxzZTsJLy8gb3B0aW1pemUgbm90aWZpY2F0aW9uCisKKyAgICBwcm90ZWN0ZWQgTWFpbExvZ2dlciBsb2dnZXI7CisgICAgcHJpdmF0ZSBNYWlsTG9nZ2VyIGNvbm5lY3Rpb25Qb29sTG9nZ2VyOworCisgICAgLyoqCisgICAgICogQSBmZXRjaCBwcm9maWxlIGl0ZW0gZm9yIGZldGNoaW5nIGhlYWRlcnMuCisgICAgICogVGhpcyBpbm5lciBjbGFzcyBleHRlbmRzIHRoZSA8Y29kZT5GZXRjaFByb2ZpbGUuSXRlbTwvY29kZT4KKyAgICAgKiBjbGFzcyB0byBhZGQgbmV3IEZldGNoUHJvZmlsZSBpdGVtIHR5cGVzLCBzcGVjaWZpYyB0byBJTUFQRm9sZGVycy4KKyAgICAgKgorICAgICAqIEBzZWUgRmV0Y2hQcm9maWxlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBGZXRjaFByb2ZpbGVJdGVtIGV4dGVuZHMgRmV0Y2hQcm9maWxlLkl0ZW0geworCXByb3RlY3RlZCBGZXRjaFByb2ZpbGVJdGVtKFN0cmluZyBuYW1lKSB7CisJICAgIHN1cGVyKG5hbWUpOworCX0KKworCS8qKgorCSAqIEhFQURFUlMgaXMgYSBmZXRjaCBwcm9maWxlIGl0ZW0gdGhhdCBjYW4gYmUgaW5jbHVkZWQgaW4gYQorCSAqIDxjb2RlPkZldGNoUHJvZmlsZTwvY29kZT4gZHVyaW5nIGEgZmV0Y2ggcmVxdWVzdCB0byBhIEZvbGRlci4KKwkgKiBUaGlzIGl0ZW0gaW5kaWNhdGVzIHRoYXQgdGhlIGhlYWRlcnMgZm9yIG1lc3NhZ2VzIGluIHRoZSBzcGVjaWZpZWQgCisJICogcmFuZ2UgYXJlIGRlc2lyZWQgdG8gYmUgcHJlZmV0Y2hlZC4gPHA+CisJICogCisJICogQW4gZXhhbXBsZSBvZiBob3cgYSBjbGllbnQgdXNlcyB0aGlzIGlzIGJlbG93OgorCSAqIDxibG9ja3F1b3RlPjxwcmU+CisJICoKKwkgKiAJRmV0Y2hQcm9maWxlIGZwID0gbmV3IEZldGNoUHJvZmlsZSgpOworCSAqCWZwLmFkZChJTUFQRm9sZGVyLkZldGNoUHJvZmlsZUl0ZW0uSEVBREVSUyk7CisJICoJZm9sZGVyLmZldGNoKG1zZ3MsIGZwKTsKKwkgKgorCSAqIDwvcHJlPjwvYmxvY2txdW90ZT4KKwkgKi8gCisJcHVibGljIHN0YXRpYyBmaW5hbCBGZXRjaFByb2ZpbGVJdGVtIEhFQURFUlMgPSAKKwkJbmV3IEZldGNoUHJvZmlsZUl0ZW0oIkhFQURFUlMiKTsKKworCS8qKgorCSAqIFNJWkUgaXMgYSBmZXRjaCBwcm9maWxlIGl0ZW0gdGhhdCBjYW4gYmUgaW5jbHVkZWQgaW4gYQorCSAqIDxjb2RlPkZldGNoUHJvZmlsZTwvY29kZT4gZHVyaW5nIGEgZmV0Y2ggcmVxdWVzdCB0byBhIEZvbGRlci4KKwkgKiBUaGlzIGl0ZW0gaW5kaWNhdGVzIHRoYXQgdGhlIHNpemVzIG9mIHRoZSBtZXNzYWdlcyBpbiB0aGUgc3BlY2lmaWVkIAorCSAqIHJhbmdlIGFyZSBkZXNpcmVkIHRvIGJlIHByZWZldGNoZWQuIDxwPgorCSAqCisJICogU0laRSB3YXMgbW92ZWQgdG8gRmV0Y2hQcm9maWxlLkl0ZW0gaW4gSmF2YU1haWwgMS41LgorCSAqCisJICogQGRlcHJlY2F0ZWQKKwkgKi8KKwlARGVwcmVjYXRlZAorCXB1YmxpYyBzdGF0aWMgZmluYWwgRmV0Y2hQcm9maWxlSXRlbSBTSVpFID0gCisJCW5ldyBGZXRjaFByb2ZpbGVJdGVtKCJTSVpFIik7CisKKwkvKioKKwkgKiBNRVNTQUdFIGlzIGEgZmV0Y2ggcHJvZmlsZSBpdGVtIHRoYXQgY2FuIGJlIGluY2x1ZGVkIGluIGEKKwkgKiA8Y29kZT5GZXRjaFByb2ZpbGU8L2NvZGU+IGR1cmluZyBhIGZldGNoIHJlcXVlc3QgdG8gYSBGb2xkZXIuCisJICogVGhpcyBpdGVtIGluZGljYXRlcyB0aGF0IHRoZSBlbnRpcmUgbWVzc2FnZXMgKGhlYWRlcnMgYW5kIGJvZHksCisJICogaW5jbHVkaW5nIGFsbCAiYXR0YWNobWVudHMiKSBpbiB0aGUgc3BlY2lmaWVkIAorCSAqIHJhbmdlIGFyZSBkZXNpcmVkIHRvIGJlIHByZWZldGNoZWQuICBOb3RlIHRoYXQgdGhlIGVudGlyZSBtZXNzYWdlCisJICogY29udGVudCBpcyBjYWNoZWQgaW4gbWVtb3J5IHdoaWxlIHRoZSBGb2xkZXIgaXMgb3Blbi4gIFRoZSBjYWNoZWQKKwkgKiBtZXNzYWdlIHdpbGwgYmUgcGFyc2VkIGxvY2FsbHkgdG8gcmV0dXJuIGhlYWRlciBpbmZvcm1hdGlvbiBhbmQKKwkgKiBtZXNzYWdlIGNvbnRlbnQuIDxwPgorCSAqIAorCSAqIEFuIGV4YW1wbGUgb2YgaG93IGEgY2xpZW50IHVzZXMgdGhpcyBpcyBiZWxvdzoKKwkgKiA8YmxvY2txdW90ZT48cHJlPgorCSAqCisJICogCUZldGNoUHJvZmlsZSBmcCA9IG5ldyBGZXRjaFByb2ZpbGUoKTsKKwkgKglmcC5hZGQoSU1BUEZvbGRlci5GZXRjaFByb2ZpbGVJdGVtLk1FU1NBR0UpOworCSAqCWZvbGRlci5mZXRjaChtc2dzLCBmcCk7CisJICoKKwkgKiA8L3ByZT48L2Jsb2NrcXVvdGU+CisJICoKKwkgKiBAc2luY2UJSmF2YU1haWwgMS41LjIKKwkgKi8gCisJcHVibGljIHN0YXRpYyBmaW5hbCBGZXRjaFByb2ZpbGVJdGVtIE1FU1NBR0UgPSAKKwkJbmV3IEZldGNoUHJvZmlsZUl0ZW0oIk1FU1NBR0UiKTsKKworCS8qKgorCSAqIElOVEVSTkFMREFURSBpcyBhIGZldGNoIHByb2ZpbGUgaXRlbSB0aGF0IGNhbiBiZSBpbmNsdWRlZCBpbiBhCisJICogPGNvZGU+RmV0Y2hQcm9maWxlPC9jb2RlPiBkdXJpbmcgYSBmZXRjaCByZXF1ZXN0IHRvIGEgRm9sZGVyLgorCSAqIFRoaXMgaXRlbSBpbmRpY2F0ZXMgdGhhdCB0aGUgSU1BUCBJTlRFUk5BTERBVEUgdmFsdWVzCisJICogKHJlY2VpdmVkIGRhdGUpIG9mIHRoZSBtZXNzYWdlcyBpbiB0aGUgc3BlY2lmaWVkIAorCSAqIHJhbmdlIGFyZSBkZXNpcmVkIHRvIGJlIHByZWZldGNoZWQuICA8cD4KKwkgKiAKKwkgKiBBbiBleGFtcGxlIG9mIGhvdyBhIGNsaWVudCB1c2VzIHRoaXMgaXMgYmVsb3c6CisJICogPGJsb2NrcXVvdGU+PHByZT4KKwkgKgorCSAqIAlGZXRjaFByb2ZpbGUgZnAgPSBuZXcgRmV0Y2hQcm9maWxlKCk7CisJICoJZnAuYWRkKElNQVBGb2xkZXIuRmV0Y2hQcm9maWxlSXRlbS5JTlRFUk5BTERBVEUpOworCSAqCWZvbGRlci5mZXRjaChtc2dzLCBmcCk7CisJICoKKwkgKiA8L3ByZT48L2Jsb2NrcXVvdGU+CisJICoKKwkgKiBAc2luY2UJSmF2YU1haWwgMS41LjUKKwkgKi8gCisJcHVibGljIHN0YXRpYyBmaW5hbCBGZXRjaFByb2ZpbGVJdGVtIElOVEVSTkFMREFURSA9IAorCQluZXcgRmV0Y2hQcm9maWxlSXRlbSgiSU5URVJOQUxEQVRFIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IgdXNlZCB0byBjcmVhdGUgYSBwb3NzaWJseSBub24tZXhpc3RlbnQgZm9sZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGZ1bGxOYW1lCWZ1bGxuYW1lIG9mIHRoaXMgZm9sZGVyCisgICAgICogQHBhcmFtIHNlcGFyYXRvciB0aGUgZGVmYXVsdCBzZXBhcmF0b3IgY2hhcmFjdGVyIGZvciB0aGlzIAorICAgICAqCQkJZm9sZGVyJ3MgbmFtZXNwYWNlCisgICAgICogQHBhcmFtIHN0b3JlCXRoZSBTdG9yZQorICAgICAqIEBwYXJhbSBpc05hbWVzcGFjZSBpZiB0aGlzIGZvbGRlciByZXByZXNlbnRzIGEgbmFtZXNwYWNlCisgICAgICovCisgICAgcHJvdGVjdGVkIElNQVBGb2xkZXIoU3RyaW5nIGZ1bGxOYW1lLCBjaGFyIHNlcGFyYXRvciwgSU1BUFN0b3JlIHN0b3JlLAorCQkJCUJvb2xlYW4gaXNOYW1lc3BhY2UpIHsKKwlzdXBlcihzdG9yZSk7CisJaWYgKGZ1bGxOYW1lID09IG51bGwpCisJICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiRm9sZGVyIG5hbWUgaXMgbnVsbCIpOworCXRoaXMuZnVsbE5hbWUgPSBmdWxsTmFtZTsKKwl0aGlzLnNlcGFyYXRvciA9IHNlcGFyYXRvcjsKKwlsb2dnZXIgPSBuZXcgTWFpbExvZ2dlcih0aGlzLmdldENsYXNzKCksICJERUJVRyBJTUFQIiwKKwkgICAgc3RvcmUuZ2V0U2Vzc2lvbigpLmdldERlYnVnKCksIHN0b3JlLmdldFNlc3Npb24oKS5nZXREZWJ1Z091dCgpKTsKKwljb25uZWN0aW9uUG9vbExvZ2dlciA9IHN0b3JlLmdldENvbm5lY3Rpb25Qb29sTG9nZ2VyKCk7CisKKwkvKgorCSAqIFdvcmsgYXJvdW5kIGFwcGFyZW50IGJ1ZyBpbiBFeGNoYW5nZS4gIEV4Y2hhbmdlCisJICogd2lsbCByZXR1cm4gYSBuYW1lIG9mICJQdWJsaWMgRm9sZGVycy8iIGZyb20KKwkgKiBMSVNUICIlIi4KKwkgKgorCSAqIElmIG5hbWUgaGFzIG9uZSBzZXBhcmF0b3IsIGFuZCBpdCdzIGF0IHRoZSBlbmQsCisJICogYXNzdW1lIHRoaXMgaXMgYSBuYW1lc3BhY2UgbmFtZSBhbmQgdHJlYXQgaXQKKwkgKiBhY2NvcmRpbmdseS4gIFVzdWFsbHkgdGhpcyB3aWxsIGhhcHBlbiBhcyBhIHJlc3VsdAorCSAqIG9mIHRoZSBsaXN0IG1ldGhvZCwgYnV0IHRoaXMgYWxzbyBhbGxvd3MgZ2V0Rm9sZGVyCisJICogdG8gd29yayB3aXRoIG5hbWVzcGFjZSBuYW1lcy4KKwkgKi8KKwl0aGlzLmlzTmFtZXNwYWNlID0gZmFsc2U7CisJaWYgKHNlcGFyYXRvciAhPSBVTktOT1dOX1NFUEFSQVRPUiAmJiBzZXBhcmF0b3IgIT0gJ1wwJykgeworCSAgICBpbnQgaSA9IHRoaXMuZnVsbE5hbWUuaW5kZXhPZihzZXBhcmF0b3IpOworCSAgICBpZiAoaSA+IDAgJiYgaSA9PSB0aGlzLmZ1bGxOYW1lLmxlbmd0aCgpIC0gMSkgeworCQl0aGlzLmZ1bGxOYW1lID0gdGhpcy5mdWxsTmFtZS5zdWJzdHJpbmcoMCwgaSk7CisJCXRoaXMuaXNOYW1lc3BhY2UgPSB0cnVlOworCSAgICB9CisJfQorCisJLy8gaWYgd2Ugd2VyZSBnaXZlbiBhIHZhbHVlLCBvdmVycmlkZSBkZWZhdWx0IGNob3NlbiBhYm92ZQorCWlmIChpc05hbWVzcGFjZSAhPSBudWxsKQorCSAgICB0aGlzLmlzTmFtZXNwYWNlID0gaXNOYW1lc3BhY2UuYm9vbGVhblZhbHVlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IgdXNlZCB0byBjcmVhdGUgYW4gZXhpc3RpbmcgZm9sZGVyLgorICAgICAqCisgICAgICogQHBhcmFtCWxpCXRoZSBMaXN0SW5mbyBmb3IgdGhpcyBmb2xkZXIKKyAgICAgKiBAcGFyYW0Jc3RvcmUJdGhlIHN0b3JlIGNvbnRhaW5pbmcgdGhpcyBmb2xkZXIKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgSU1BUEZvbGRlcihMaXN0SW5mbyBsaSwgSU1BUFN0b3JlIHN0b3JlKSB7CisJdGhpcyhsaS5uYW1lLCBsaS5zZXBhcmF0b3IsIHN0b3JlLCBudWxsKTsKKworCWlmIChsaS5oYXNJbmZlcmlvcnMpCisJICAgIHR5cGUgfD0gSE9MRFNfRk9MREVSUzsKKwlpZiAobGkuY2FuT3BlbikKKwkgICAgdHlwZSB8PSBIT0xEU19NRVNTQUdFUzsKKwlleGlzdHMgPSB0cnVlOworCWF0dHJpYnV0ZXMgPSBsaS5hdHRyczsKKyAgICB9CisJCisgICAgLyoKKyAgICAgKiBFbnN1cmUgdGhhdCB0aGlzIGZvbGRlciBleGlzdHMuIElmICdleGlzdHMnIGhhcyBiZWVuIHNldCB0byB0cnVlLAorICAgICAqIHdlIGRvbid0IGF0dGVtcHQgdG8gdmFsaWRhdGUgaXQgd2l0aCB0aGUgc2VydmVyIGFnYWluLiBOb3RlIHRoYXQKKyAgICAgKiB0aGlzIGNhbiByZXN1bHQgaW4gYSBwb3NzaWJsZSBsb3NzIG9mIHN5bmMgd2l0aCB0aGUgc2VydmVyLgorICAgICAqIEFTU0VSVDogTXVzdCBiZSBjYWxsZWQgd2l0aCB0aGlzIGZvbGRlcidzIHN5bmNocm9uaXphdGlvbiBsb2NrIGhlbGQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgY2hlY2tFeGlzdHMoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwkvLyBJZiB0aGUgYm9vbGVhbiBmaWVsZCAnZXhpc3RzJyBpcyBmYWxzZSwgY2hlY2sgd2l0aCB0aGUKKwkvLyBzZXJ2ZXIgYnkgaW52b2tpbmcgZXhpc3RzKCkgLi4KKwlpZiAoIWV4aXN0cyAmJiAhZXhpc3RzKCkpCisJICAgIHRocm93IG5ldyBGb2xkZXJOb3RGb3VuZEV4Y2VwdGlvbigKKwkJdGhpcywgZnVsbE5hbWUgKyAiIG5vdCBmb3VuZCIpOworICAgIH0KKworICAgIC8qCisgICAgICogRW5zdXJlIHRoZSBmb2xkZXIgaXMgY2xvc2VkLgorICAgICAqIEFTU0VSVDogTXVzdCBiZSBjYWxsZWQgd2l0aCB0aGlzIGZvbGRlcidzIHN5bmNocm9uaXphdGlvbiBsb2NrIGhlbGQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgY2hlY2tDbG9zZWQoKSB7CisJaWYgKG9wZW5lZCkKKwkgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigKKwkJIlRoaXMgb3BlcmF0aW9uIGlzIG5vdCBhbGxvd2VkIG9uIGFuIG9wZW4gZm9sZGVyIgorCQkpOworICAgIH0KKworICAgIC8qCisgICAgICogRW5zdXJlIHRoZSBmb2xkZXIgaXMgb3Blbi4KKyAgICAgKiBBU1NFUlQ6IE11c3QgYmUgY2FsbGVkIHdpdGggdGhpcyBmb2xkZXIncyBzeW5jaHJvbml6YXRpb24gbG9jayBoZWxkLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGNoZWNrT3BlbmVkKCkgdGhyb3dzIEZvbGRlckNsb3NlZEV4Y2VwdGlvbiB7CisJYXNzZXJ0IFRocmVhZC5ob2xkc0xvY2sodGhpcyk7CisJaWYgKCFvcGVuZWQpIHsKKwkgICAgaWYgKHJlYWxseUNsb3NlZCkKKwkJdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigKKwkJICAgICJUaGlzIG9wZXJhdGlvbiBpcyBub3QgYWxsb3dlZCBvbiBhIGNsb3NlZCBmb2xkZXIiCisJICAgIAkpOworCSAgICBlbHNlIC8vIEZvbGRlciB3YXMgY2xvc2VkICJpbXBsaWNpdGx5IgorCQl0aHJvdyBuZXcgRm9sZGVyQ2xvc2VkRXhjZXB0aW9uKHRoaXMsIAorCQkgICAgIkxvc3QgZm9sZGVyIGNvbm5lY3Rpb24gdG8gc2VydmVyIgorCQkpOworCX0KKyAgICB9CisKKyAgICAvKgorICAgICAqIENoZWNrIHRoYXQgdGhlIGdpdmVuIG1lc3NhZ2UgbnVtYmVyIGlzIHdpdGhpbiB0aGUgcmFuZ2UKKyAgICAgKiBvZiBtZXNzYWdlcyBwcmVzZW50IGluIHRoaXMgZm9sZGVyLiBJZiB0aGUgbWVzc2FnZQorICAgICAqIG51bWJlciBpcyBvdXQgb2YgcmFuZ2UsIHdlIHBpbmcgdGhlIHNlcnZlciB0byBvYnRhaW4gYW55CisgICAgICogcGVuZGluZyBuZXcgbWVzc2FnZSBub3RpZmljYXRpb25zIGZyb20gdGhlIHNlcnZlci4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBjaGVja1JhbmdlKGludCBtc2dubykgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKG1zZ25vIDwgMSkgLy8gbWVzc2FnZS1udW1iZXJzIHN0YXJ0IGF0IDEKKwkgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oIm1lc3NhZ2UgbnVtYmVyIDwgMSIpOworCisJaWYgKG1zZ25vIDw9IHRvdGFsKQorCSAgICByZXR1cm47CisKKwkvLyBPdXQgb2YgcmFuZ2UsIGxldCdzIHBpbmcgdGhlIHNlcnZlciBhbmQgc2VlIGlmCisJLy8gdGhlIHNlcnZlciBoYXMgbW9yZSBtZXNzYWdlcyBmb3IgdXMuCisKKwlzeW5jaHJvbml6ZWQobWVzc2FnZUNhY2hlTG9jaykgeyAvLyBBY3F1aXJlIGxvY2sKKwkgICAgdHJ5IHsKKwkJa2VlcENvbm5lY3Rpb25BbGl2ZShmYWxzZSk7CisJICAgIH0gY2F0Y2ggKENvbm5lY3Rpb25FeGNlcHRpb24gY2V4KSB7CisJCS8vIE9vcHMsIGxvc3QgY29ubmVjdGlvbgorCQl0aHJvdyBuZXcgRm9sZGVyQ2xvc2VkRXhjZXB0aW9uKHRoaXMsIGNleC5nZXRNZXNzYWdlKCkpOworCSAgICB9IGNhdGNoIChQcm90b2NvbEV4Y2VwdGlvbiBwZXgpIHsgCisJCXRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24ocGV4LmdldE1lc3NhZ2UoKSwgcGV4KTsKKwkgICAgfQorCX0gLy8gUmVsZWFzZSBsb2NrCisKKwlpZiAobXNnbm8gPiB0b3RhbCkgLy8gU3RpbGwgb3V0IG9mIHJhbmdlID8gVGhyb3cgdXAgLi4uCisJICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKG1zZ25vICsgIiA+ICIgKyB0b3RhbCk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBDaGVjayB3aGV0aGVyIHRoZSBnaXZlbiBmbGFncyBhcmUgc3VwcG9ydGVkIGJ5IHRoaXMgc2VydmVyLAorICAgICAqIGFuZCBhbHNvIHZlcmlmeSB0aGF0IHRoZSBmb2xkZXIgYWxsb3dzIHNldHRpbmcgZmxhZ3MuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrRmxhZ3MoRmxhZ3MgZmxhZ3MpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWFzc2VydCBUaHJlYWQuaG9sZHNMb2NrKHRoaXMpOworCWlmIChtb2RlICE9IFJFQURfV1JJVEUpCisJICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oCisJCSJDYW5ub3QgY2hhbmdlIGZsYWdzIG9uIFJFQURfT05MWSBmb2xkZXI6ICIgKyBmdWxsTmFtZQorCQkpOworCS8qCisJaWYgKCFhdmFpbGFibGVGbGFncy5jb250YWlucyhmbGFncykpCisJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oCisJCSJUaGVzZSBmbGFncyBhcmUgbm90IHN1cHBvcnRlZCBieSB0aGlzIGltcGxlbWVudGF0aW9uIgorCQkpOworCSovCisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBuYW1lIG9mIHRoaXMgZm9sZGVyLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgU3RyaW5nIGdldE5hbWUoKSB7CisJLyogUmV0dXJuIHRoZSBsYXN0IGNvbXBvbmVudCBvZiB0aGlzIEZvbGRlcidzIGZ1bGwgbmFtZS4KKwkgKiBGb2xkZXIgY29tcG9uZW50cyBhcmUgZGVsaW1pdGVkIGJ5IHRoZSBzZXBhcmF0b3IgY2hhcmFjdGVyLgorCSAqLworCWlmIChuYW1lID09IG51bGwpIHsKKwkgICAgdHJ5IHsKKwkJbmFtZSA9IAlmdWxsTmFtZS5zdWJzdHJpbmcoCisJCQkgICAgZnVsbE5hbWUubGFzdEluZGV4T2YoZ2V0U2VwYXJhdG9yKCkpICsgMQorCQkJKTsKKwkgICAgfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIG1leCkgeyB9CisJfQorCXJldHVybiBuYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgZnVsbG5hbWUgb2YgdGhpcyBmb2xkZXIuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXRGdWxsTmFtZSgpIHsKKwlyZXR1cm4gZnVsbE5hbWU7CQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGlzIGZvbGRlcidzIHBhcmVudC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIEZvbGRlciBnZXRQYXJlbnQoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwljaGFyIGMgPSBnZXRTZXBhcmF0b3IoKTsKKwlpbnQgaW5kZXg7CisJaWYgKChpbmRleCA9IGZ1bGxOYW1lLmxhc3RJbmRleE9mKGMpKSAhPSAtMSkKKwkgICAgcmV0dXJuICgoSU1BUFN0b3JlKXN0b3JlKS5uZXdJTUFQRm9sZGVyKAorCQkJICAgIGZ1bGxOYW1lLnN1YnN0cmluZygwLCBpbmRleCksIGMpOworCWVsc2UKKwkgICAgcmV0dXJuIG5ldyBEZWZhdWx0Rm9sZGVyKChJTUFQU3RvcmUpc3RvcmUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrIHdoZXRoZXIgdGhpcyBmb2xkZXIgcmVhbGx5IGV4aXN0cyBvbiB0aGUgc2VydmVyLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgYm9vbGVhbiBleGlzdHMoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwkvLyBDaGVjayB3aGV0aGVyIHRoaXMgZm9sZGVyIGV4aXN0cyAuLgorCUxpc3RJbmZvW10gbGkgPSBudWxsOworCWZpbmFsIFN0cmluZyBsbmFtZTsKKwlpZiAoaXNOYW1lc3BhY2UgJiYgc2VwYXJhdG9yICE9ICdcMCcpCisJICAgIGxuYW1lID0gZnVsbE5hbWUgKyBzZXBhcmF0b3I7CisJZWxzZQorCSAgICBsbmFtZSA9IGZ1bGxOYW1lOworCisJbGkgPSAoTGlzdEluZm9bXSlkb0NvbW1hbmQobmV3IFByb3RvY29sQ29tbWFuZCgpIHsKKwkgICAgQE92ZXJyaWRlCisJICAgIHB1YmxpYyBPYmplY3QgZG9Db21tYW5kKElNQVBQcm90b2NvbCBwKSB0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCQlyZXR1cm4gcC5saXN0KCIiLCBsbmFtZSk7CisJICAgIH0KKwl9KTsKKworCWlmIChsaSAhPSBudWxsKSB7CisJICAgIGludCBpID0gZmluZE5hbWUobGksIGxuYW1lKTsKKwkgICAgZnVsbE5hbWUgPSBsaVtpXS5uYW1lOworCSAgICBzZXBhcmF0b3IgPSBsaVtpXS5zZXBhcmF0b3I7CisJICAgIGludCBsZW4gPSBmdWxsTmFtZS5sZW5ndGgoKTsKKwkgICAgaWYgKHNlcGFyYXRvciAhPSAnXDAnICYmIGxlbiA+IDAgJiYKKwkJICAgIGZ1bGxOYW1lLmNoYXJBdChsZW4gLSAxKSA9PSBzZXBhcmF0b3IpIHsKKwkJZnVsbE5hbWUgPSBmdWxsTmFtZS5zdWJzdHJpbmcoMCwgbGVuIC0gMSk7CisJICAgIH0KKwkgICAgdHlwZSA9IDA7CisJICAgIGlmIChsaVtpXS5oYXNJbmZlcmlvcnMpCisJCXR5cGUgfD0gSE9MRFNfRk9MREVSUzsKKwkgICAgaWYgKGxpW2ldLmNhbk9wZW4pCisJCXR5cGUgfD0gSE9MRFNfTUVTU0FHRVM7CisJICAgIGV4aXN0cyA9IHRydWU7CisJICAgIGF0dHJpYnV0ZXMgPSBsaVtpXS5hdHRyczsKKwl9IGVsc2UgeworCSAgICBleGlzdHMgPSBvcGVuZWQ7CisJICAgIGF0dHJpYnV0ZXMgPSBudWxsOworCX0KKworCXJldHVybiBleGlzdHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogV2hpY2ggZW50cnkgaW4gPGNvZGU+bGk8L2NvZGU+IG1hdGNoZXMgPGNvZGU+bG5hbWU8L2NvZGU+PworICAgICAqIElmIHRoZSBuYW1lIGNvbnRhaW5zIHdpbGRjYXJkcywgbW9yZSB0aGFuIG9uZSBlbnRyeSBtYXkgYmUKKyAgICAgKiByZXR1cm5lZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBmaW5kTmFtZShMaXN0SW5mb1tdIGxpLCBTdHJpbmcgbG5hbWUpIHsKKwlpbnQgaTsKKwkvLyBpZiB0aGUgbmFtZSBjb250YWlucyBhIHdpbGRjYXJkLCB0aGVyZSBtaWdodCBiZSBtb3JlIHRoYW4gb25lCisJZm9yIChpID0gMDsgaSA8IGxpLmxlbmd0aDsgaSsrKSB7CisJICAgIGlmIChsaVtpXS5uYW1lLmVxdWFscyhsbmFtZSkpCisJCWJyZWFrOworCX0KKwlpZiAoaSA+PSBsaS5sZW5ndGgpIHsJLy8gbm90aGluZyBtYXRjaGVkIGV4YWN0bHkKKwkgICAgLy8gWFhYIC0gcG9zc2libHkgc2hvdWxkIGZhaWw/ICBCdXQgd2hhdCBpZiBzZXJ2ZXIKKwkgICAgLy8gaXMgY2FzZSBpbnNlbnNpdGl2ZSBhbmQgcmV0dXJucyB0aGUgcHJlZmVycmVkCisJICAgIC8vIGNhc2Ugb2YgdGhlIG5hbWUgaGVyZT8KKwkgICAgaSA9IDA7CQkvLyB1c2UgZmlyc3Qgb25lCisJfQorCXJldHVybiBpOworICAgIH0KKworICAgIC8qKgorICAgICAqIExpc3QgYWxsIHN1YmZvbGRlcnMgbWF0Y2hpbmcgdGhlIHNwZWNpZmllZCBwYXR0ZXJuLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBGb2xkZXJbXSBsaXN0KFN0cmluZyBwYXR0ZXJuKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gZG9MaXN0KHBhdHRlcm4sIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMaXN0IGFsbCBzdWJzY3JpYmVkIHN1YmZvbGRlcnMgbWF0Y2hpbmcgdGhlIHNwZWNpZmllZCBwYXR0ZXJuLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBGb2xkZXJbXSBsaXN0U3Vic2NyaWJlZChTdHJpbmcgcGF0dGVybikgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJcmV0dXJuIGRvTGlzdChwYXR0ZXJuLCB0cnVlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN5bmNocm9uaXplZCBGb2xkZXJbXSBkb0xpc3QoZmluYWwgU3RyaW5nIHBhdHRlcm4sCisJCWZpbmFsIGJvb2xlYW4gc3Vic2NyaWJlZCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJY2hlY2tFeGlzdHMoKTsgLy8gaW5zdXJlIHRoYXQgdGhpcyBmb2xkZXIgZG9lcyBleGlzdC4KKwkKKwkvLyBXaHkgd2FzdGUgYSByb3VuZHRyaXAgdG8gdGhlIHNlcnZlcj8KKwlpZiAoYXR0cmlidXRlcyAhPSBudWxsICYmICFpc0RpcmVjdG9yeSgpKQorCSAgICByZXR1cm4gbmV3IEZvbGRlclswXTsKKworCWZpbmFsIGNoYXIgYyA9IGdldFNlcGFyYXRvcigpOworCisJTGlzdEluZm9bXSBsaSA9IChMaXN0SW5mb1tdKWRvQ29tbWFuZElnbm9yZUZhaWx1cmUoCisJICAgIG5ldyBQcm90b2NvbENvbW1hbmQoKSB7CisJCUBPdmVycmlkZQorCQlwdWJsaWMgT2JqZWN0IGRvQ29tbWFuZChJTUFQUHJvdG9jb2wgcCkKKwkJCXRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJCSAgICBpZiAoc3Vic2NyaWJlZCkKKwkJCXJldHVybiBwLmxzdWIoIiIsIGZ1bGxOYW1lICsgYyArIHBhdHRlcm4pOworCQkgICAgZWxzZSAKKwkJCXJldHVybiBwLmxpc3QoIiIsIGZ1bGxOYW1lICsgYyArIHBhdHRlcm4pOworCQl9CisJICAgIH0pOworCisJaWYgKGxpID09IG51bGwpCisJICAgIHJldHVybiBuZXcgRm9sZGVyWzBdOworCisJLyoKKwkgKiBUaGUgVVcgYmFzZWQgSU1BUDQgc2VydmVycyAoZS5nLiBTSU1TMi4wKSBpbmNsdWRlCisJICogY3VycmVudCBmb2xkZXIgKHRlcm1pbmF0ZWQgd2l0aCB0aGUgc2VwYXJhdG9yKSwgd2hlbgorCSAqIHRoZSBMSVNUIHBhdHRlcm4gaXMgJyUnIG9yICcqJy4gaS5lLCA8TElTVCAiIiBtYWlsLyU+IAorCSAqIHJldHVybnMgIm1haWwvIiBhcyB0aGUgZmlyc3QgTElTVCByZXNwb25zZS4KKwkgKgorCSAqIERvZXNuJ3QgbWFrZSBzZW5zZSB0byBpbmNsdWRlIHRoZSBjdXJyZW50IGZvbGRlciBpbiB0aGlzCisJICogY2FzZSwgc28gd2UgZmlsdGVyIGl0IG91dC4gTm90ZSB0aGF0IEknbSBhc3N1bWluZyB0aGF0CisJICogdGhlIG9mZmVuZGluZyByZXNwb25zZSBpcyB0aGUgKmZpcnN0KiBvbmUsIG15IGV4cGVyaW1lbnRzCisJICogd2l0aCB0aGUgVVcgJiBTSU1TMi4wIHNlcnZlcnMgaW5kaWNhdGUgdGhhdCAuLiAKKwkgKi8KKwlpbnQgc3RhcnQgPSAwOworCS8vIENoZWNrIHRoZSBmaXJzdCBMSVNUIHJlc3BvbnNlLgorCWlmIChsaS5sZW5ndGggPiAwICYmIGxpWzBdLm5hbWUuZXF1YWxzKGZ1bGxOYW1lICsgYykpIAorCSAgICBzdGFydCA9IDE7IC8vIHN0YXJ0IGZyb20gaW5kZXggPSAxCisKKwlJTUFQRm9sZGVyW10gZm9sZGVycyA9IG5ldyBJTUFQRm9sZGVyW2xpLmxlbmd0aCAtIHN0YXJ0XTsKKwlJTUFQU3RvcmUgc3QgPSAoSU1BUFN0b3JlKXN0b3JlOworCWZvciAoaW50IGkgPSBzdGFydDsgaSA8IGxpLmxlbmd0aDsgaSsrKQorCSAgICBmb2xkZXJzW2ktc3RhcnRdID0gc3QubmV3SU1BUEZvbGRlcihsaVtpXSk7CisJcmV0dXJuIGZvbGRlcnM7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBzZXBhcmF0b3IgY2hhcmFjdGVyLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgY2hhciBnZXRTZXBhcmF0b3IoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpZiAoc2VwYXJhdG9yID09IFVOS05PV05fU0VQQVJBVE9SKSB7CisJICAgIExpc3RJbmZvW10gbGkgPSBudWxsOworCisJICAgIGxpID0gKExpc3RJbmZvW10pZG9Db21tYW5kKG5ldyBQcm90b2NvbENvbW1hbmQoKSB7CisJCUBPdmVycmlkZQorCQlwdWJsaWMgT2JqZWN0IGRvQ29tbWFuZChJTUFQUHJvdG9jb2wgcCkKKwkJCXRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJCSAgICAvLyBSRVYxIGFsbG93cyB0aGUgZm9sbG93aW5nIExJU1QgZm9ybWF0IHRvIG9idGFpbgorCQkgICAgLy8gdGhlIGhpZXJhcmNoeSBkZWxpbWl0ZXIgb2Ygbm9uLWV4aXN0ZW50IGZvbGRlcnMKKwkJICAgIGlmIChwLmlzUkVWMSgpKSAvLyBJTUFQNHJldjEKKwkJICAgICAgICByZXR1cm4gcC5saXN0KGZ1bGxOYW1lLCAiIik7CisJCSAgICBlbHNlIC8vIElNQVA0LCBub3RlIHRoYXQgdGhpcyBmb2xkZXIgbXVzdCBleGlzdCBmb3IgdGhpcworCQkgICAgICAgIC8vIHRvIHdvcmsgOigKKwkJICAgICAgICByZXR1cm4gcC5saXN0KCIiLCBmdWxsTmFtZSk7CisJCX0KKwkgICAgfSk7CisKKwkgICAgaWYgKGxpICE9IG51bGwpIAorCQlzZXBhcmF0b3IgPSBsaVswXS5zZXBhcmF0b3I7CisJICAgIGVsc2UKKwkJc2VwYXJhdG9yID0gJy8nOyAvLyBwdW50ICEKKwl9CisJcmV0dXJuIHNlcGFyYXRvcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIHR5cGUgb2YgdGhpcyBmb2xkZXIuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBpbnQgZ2V0VHlwZSgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWlmIChvcGVuZWQpIHsKKwkgICAgLy8gbmV2ZXIgdGhyb3cgRm9sZGVyTm90Rm91bmRFeGNlcHRpb24gaWYgZm9sZGVyIGlzIG9wZW4KKwkgICAgaWYgKGF0dHJpYnV0ZXMgPT0gbnVsbCkKKwkJZXhpc3RzKCk7CS8vIHRyeSB0byBmZXRjaCBhdHRyaWJ1dGVzCisJfSBlbHNlIHsKKwkgICAgY2hlY2tFeGlzdHMoKTsKKwl9CisJcmV0dXJuIHR5cGU7CisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIENoZWNrIHdoZXRoZXIgdGhpcyBmb2xkZXIgaXMgc3Vic2NyaWJlZC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGJvb2xlYW4gaXNTdWJzY3JpYmVkKCkgeworCUxpc3RJbmZvW10gbGkgPSBudWxsOworCWZpbmFsIFN0cmluZyBsbmFtZTsKKwlpZiAoaXNOYW1lc3BhY2UgJiYgc2VwYXJhdG9yICE9ICdcMCcpCisJICAgIGxuYW1lID0gZnVsbE5hbWUgKyBzZXBhcmF0b3I7CisJZWxzZQorCSAgICBsbmFtZSA9IGZ1bGxOYW1lOworCisJdHJ5IHsKKwkgICAgbGkgPSAoTGlzdEluZm9bXSlkb1Byb3RvY29sQ29tbWFuZChuZXcgUHJvdG9jb2xDb21tYW5kKCkgeworCQlAT3ZlcnJpZGUKKwkJcHVibGljIE9iamVjdCBkb0NvbW1hbmQoSU1BUFByb3RvY29sIHApCisJCQl0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCQkgICAgcmV0dXJuIHAubHN1YigiIiwgbG5hbWUpOworCQl9CisJICAgIH0pOworCX0gY2F0Y2ggKFByb3RvY29sRXhjZXB0aW9uIHBleCkgeworICAgICAgICB9CisKKwlpZiAobGkgIT0gbnVsbCkgeworCSAgICBpbnQgaSA9IGZpbmROYW1lKGxpLCBsbmFtZSk7CisJICAgIHJldHVybiBsaVtpXS5jYW5PcGVuOworCX0gZWxzZQorCSAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogU3Vic2NyaWJlL1Vuc3Vic2NyaWJlIHRoaXMgZm9sZGVyLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXRTdWJzY3JpYmVkKGZpbmFsIGJvb2xlYW4gc3Vic2NyaWJlKSAKKwkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWRvQ29tbWFuZElnbm9yZUZhaWx1cmUobmV3IFByb3RvY29sQ29tbWFuZCgpIHsKKwkgICAgQE92ZXJyaWRlCisJICAgIHB1YmxpYyBPYmplY3QgZG9Db21tYW5kKElNQVBQcm90b2NvbCBwKSB0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCQlpZiAoc3Vic2NyaWJlKQorCQkgICAgcC5zdWJzY3JpYmUoZnVsbE5hbWUpOworCQllbHNlCisJCSAgICBwLnVuc3Vic2NyaWJlKGZ1bGxOYW1lKTsKKwkJcmV0dXJuIG51bGw7CisJICAgIH0KKwl9KTsKKyAgICB9CisJCisgICAgLyoqCisgICAgICogQ3JlYXRlIHRoaXMgZm9sZGVyLCB3aXRoIHRoZSBzcGVjaWZpZWQgdHlwZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGJvb2xlYW4gY3JlYXRlKGZpbmFsIGludCB0eXBlKQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCisJY2hhciBjID0gMDsKKwlpZiAoKHR5cGUgJiBIT0xEU19NRVNTQUdFUykgPT0gMCkJLy8gb25seSBob2xkcyBmb2xkZXJzCisJICAgIGMgPSBnZXRTZXBhcmF0b3IoKTsKKwlmaW5hbCBjaGFyIHNlcCA9IGM7CisJT2JqZWN0IHJldCA9IGRvQ29tbWFuZElnbm9yZUZhaWx1cmUobmV3IFByb3RvY29sQ29tbWFuZCgpIHsKKwkgICAgQE92ZXJyaWRlCisJCXB1YmxpYyBPYmplY3QgZG9Db21tYW5kKElNQVBQcm90b2NvbCBwKQorCQkJdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKwkJICAgIGlmICgodHlwZSAmIEhPTERTX01FU1NBR0VTKSA9PSAwKQkvLyBvbmx5IGhvbGRzIGZvbGRlcnMKKwkJCXAuY3JlYXRlKGZ1bGxOYW1lICsgc2VwKTsKKwkJICAgIGVsc2UgeworCQkJcC5jcmVhdGUoZnVsbE5hbWUpOworCisJCQkvLyBDZXJ0YWluIElNQVAgc2VydmVycyBkbyBub3QgYWxsb3cgY3JlYXRpb24gb2YgZm9sZGVycworCQkJLy8gdGhhdCBjYW4gY29udGFpbiBtZXNzYWdlcyAqYW5kKiBzdWJmb2xkZXJzLiBTbywgaWYgd2UKKwkJCS8vIHdlcmUgYXNrZWQgdG8gY3JlYXRlIHN1Y2ggYSBmb2xkZXIsIHdlIHNob3VsZCB2ZXJpZnkKKwkJCS8vIHRoYXQgd2UgY291bGQgaW5kZWVkIGRvIHNvLgorCQkJaWYgKCh0eXBlICYgSE9MRFNfRk9MREVSUykgIT0gMCkgeworCQkJICAgIC8vIHdlIHdhbnQgdG8gaG9sZCBzdWJmb2xkZXJzIGFuZCBtZXNzYWdlcy4gQ2hlY2sKKwkJCSAgICAvLyB3aGV0aGVyIHdlIGNvdWxkIGNyZWF0ZSBzdWNoIGEgZm9sZGVyLgorCQkJICAgIExpc3RJbmZvW10gbGkgPSBwLmxpc3QoIiIsIGZ1bGxOYW1lKTsKKwkJCSAgICBpZiAobGkgIT0gbnVsbCAmJiAhbGlbMF0uaGFzSW5mZXJpb3JzKSB7CisJCQkJLy8gSG1tIC4udGhlIG5ldyBmb2xkZXIgCisJCQkJLy8gZG9lc24ndCBzdXBwb3J0IEluZmVyaW9ycyA/IEZhaWwKKwkJCQlwLmRlbGV0ZShmdWxsTmFtZSk7CisJCQkJdGhyb3cgbmV3IFByb3RvY29sRXhjZXB0aW9uKCJVbnN1cHBvcnRlZCB0eXBlIik7CisJCQkgICAgfQorCQkJfQorCQkgICAgfQorCQkgICAgcmV0dXJuIEJvb2xlYW4uVFJVRTsKKwkJfQorCSAgICB9KTsKKworCWlmIChyZXQgPT0gbnVsbCkKKwkgICAgcmV0dXJuIGZhbHNlOyAvLyBDUkVBVEUgZmFpbHVyZSwgbWF5YmUgdGhpcyAKKwkJCSAgLy8gZm9sZGVyIGFscmVhZHkgZXhpc3RzID8KKworCS8vIGV4aXN0cyA9IHRydWU7CisJLy8gdGhpcy50eXBlID0gdHlwZTsKKwlib29sZWFuIHJldGIgPSBleGlzdHMoKTsJLy8gc2V0IGV4aXN0cywgdHlwZSwgYW5kIGF0dHJpYnV0ZXMKKwlpZiAocmV0YikJCS8vIE5vdGlmeSBsaXN0ZW5lcnMgb24gc2VsZiBhbmQgb3VyIFN0b3JlCisJICAgIG5vdGlmeUZvbGRlckxpc3RlbmVycyhGb2xkZXJFdmVudC5DUkVBVEVEKTsKKwlyZXR1cm4gcmV0YjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVjayB3aGV0aGVyIHRoaXMgZm9sZGVyIGhhcyBuZXcgbWVzc2FnZXMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIGhhc05ld01lc3NhZ2VzKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJc3luY2hyb25pemVkIChtZXNzYWdlQ2FjaGVMb2NrKSB7CisJICAgIGlmIChvcGVuZWQpIHsgLy8gSWYgd2UgYXJlIG9wZW4sIHdlIGFscmVhZHkgaGF2ZSB0aGlzIGluZm9ybWF0aW9uCisJCS8vIEZvbGRlciBpcyBvcGVuLCBtYWtlIHN1cmUgaW5mb3JtYXRpb24gaXMgdXAgdG8gZGF0ZQorCQkvLyB0aWNrbGUgdGhlIGZvbGRlciBhbmQgc3RvcmUgY29ubmVjdGlvbnMuCisJCXRyeSB7CisJCSAgICBrZWVwQ29ubmVjdGlvbkFsaXZlKHRydWUpOworCQl9IGNhdGNoIChDb25uZWN0aW9uRXhjZXB0aW9uIGNleCkgeworCQkgICAgdGhyb3cgbmV3IEZvbGRlckNsb3NlZEV4Y2VwdGlvbih0aGlzLCBjZXguZ2V0TWVzc2FnZSgpKTsKKwkJfSBjYXRjaCAoUHJvdG9jb2xFeGNlcHRpb24gcGV4KSB7CisJCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKHBleC5nZXRNZXNzYWdlKCksIHBleCk7CisJCX0KKwkJcmV0dXJuIHJlY2VudCA+IDAgPyB0cnVlIDogZmFsc2U7CisJICAgIH0KKwl9CisKKwkvLyBGaXJzdCwgdGhlIGNoZWFwIHdheSAtIHVzZSBMSVNUIGFuZCBsb29rIGZvciB0aGUgXE1hcmtlZAorCS8vIG9yIFxVbm1hcmtlZCB0YWcKKworCUxpc3RJbmZvW10gbGkgPSBudWxsOworCWZpbmFsIFN0cmluZyBsbmFtZTsKKwlpZiAoaXNOYW1lc3BhY2UgJiYgc2VwYXJhdG9yICE9ICdcMCcpCisJICAgIGxuYW1lID0gZnVsbE5hbWUgKyBzZXBhcmF0b3I7CisJZWxzZQorCSAgICBsbmFtZSA9IGZ1bGxOYW1lOworCWxpID0gKExpc3RJbmZvW10pZG9Db21tYW5kSWdub3JlRmFpbHVyZShuZXcgUHJvdG9jb2xDb21tYW5kKCkgeworCSAgICBAT3ZlcnJpZGUKKwkgICAgcHVibGljIE9iamVjdCBkb0NvbW1hbmQoSU1BUFByb3RvY29sIHApIHRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJCXJldHVybiBwLmxpc3QoIiIsIGxuYW1lKTsKKwkgICAgfQorCX0pOworCisJLy8gaWYgZm9sZGVyIGRvZXNuJ3QgZXhpc3QsIHRocm93IGV4Y2VwdGlvbgorCWlmIChsaSA9PSBudWxsKQorCSAgICB0aHJvdyBuZXcgRm9sZGVyTm90Rm91bmRFeGNlcHRpb24odGhpcywgZnVsbE5hbWUgKyAiIG5vdCBmb3VuZCIpOworCisJaW50IGkgPSBmaW5kTmFtZShsaSwgbG5hbWUpOworCWlmIChsaVtpXS5jaGFuZ2VTdGF0ZSA9PSBMaXN0SW5mby5DSEFOR0VEKQorCSAgICByZXR1cm4gdHJ1ZTsKKwllbHNlIGlmIChsaVtpXS5jaGFuZ2VTdGF0ZSA9PSBMaXN0SW5mby5VTkNIQU5HRUQpCisJICAgIHJldHVybiBmYWxzZTsKKworCS8vIExJU1QgZGlkbid0IHdvcmsuIFRyeSB0aGUgaGFyZCB3YXksIHVzaW5nIFNUQVRVUworCXRyeSB7CisJICAgIFN0YXR1cyBzdGF0dXMgPSBnZXRTdGF0dXMoKTsKKwkgICAgaWYgKHN0YXR1cy5yZWNlbnQgPiAwKQorCQlyZXR1cm4gdHJ1ZTsKKwkgICAgZWxzZQorCQlyZXR1cm4gZmFsc2U7CisJfSBjYXRjaCAoQmFkQ29tbWFuZEV4Y2VwdGlvbiBiZXgpIHsKKwkgICAgLy8gUHJvYmFibHkgZG9lc24ndCBzdXBwb3J0IFNUQVRVUywgdG91Z2ggbHVjay4KKwkgICAgcmV0dXJuIGZhbHNlOworCX0gY2F0Y2ggKENvbm5lY3Rpb25FeGNlcHRpb24gY2V4KSB7CisJICAgIHRocm93IG5ldyBTdG9yZUNsb3NlZEV4Y2VwdGlvbihzdG9yZSwgY2V4LmdldE1lc3NhZ2UoKSk7CisJfSBjYXRjaCAoUHJvdG9jb2xFeGNlcHRpb24gcGV4KSB7CisJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24ocGV4LmdldE1lc3NhZ2UoKSwgcGV4KTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBuYW1lZCBzdWJmb2xkZXIuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBGb2xkZXIgZ2V0Rm9sZGVyKFN0cmluZyBuYW1lKQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCS8vIElmIHdlIGtub3cgdGhhdCB0aGlzIGZvbGRlciBpcyAqbm90KiBhIGRpcmVjdG9yeSwgZG9uJ3QKKwkvLyBzZW5kIHRoZSByZXF1ZXN0IHRvIHRoZSBzZXJ2ZXIgYXQgYWxsIC4uLgorCWlmIChhdHRyaWJ1dGVzICE9IG51bGwgJiYgIWlzRGlyZWN0b3J5KCkpCisJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oIkNhbm5vdCBjb250YWluIHN1YmZvbGRlcnMiKTsKKworCWNoYXIgYyA9IGdldFNlcGFyYXRvcigpOworCXJldHVybiAoKElNQVBTdG9yZSlzdG9yZSkubmV3SU1BUEZvbGRlcihmdWxsTmFtZSArIGMgKyBuYW1lLCBjKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZWxldGUgdGhpcyBmb2xkZXIuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIGRlbGV0ZShib29sZWFuIHJlY3Vyc2UpIAorCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7ICAKKwljaGVja0Nsb3NlZCgpOyAvLyBpbnN1cmUgdGhhdCB0aGlzIGZvbGRlciBpcyBjbG9zZWQuCisKKwlpZiAocmVjdXJzZSkgeworCSAgICAvLyBEZWxldGUgYWxsIHN1YmZvbGRlcnMuCisJICAgIEZvbGRlcltdIGYgPSBsaXN0KCk7CisJICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZi5sZW5ndGg7IGkrKykKKwkJZltpXS5kZWxldGUocmVjdXJzZSk7IC8vIGlnbm9yZSBpbnRlcm1lZGlhdGUgZmFpbHVyZXMKKwl9CisKKwkvLyBBdHRlbXB0IHRvIGRlbGV0ZSB0aGlzIGZvbGRlcgorCisJT2JqZWN0IHJldCA9IGRvQ29tbWFuZElnbm9yZUZhaWx1cmUobmV3IFByb3RvY29sQ29tbWFuZCgpIHsKKwkgICAgQE92ZXJyaWRlCisJICAgIHB1YmxpYyBPYmplY3QgZG9Db21tYW5kKElNQVBQcm90b2NvbCBwKSB0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCQlwLmRlbGV0ZShmdWxsTmFtZSk7CisJCXJldHVybiBCb29sZWFuLlRSVUU7CisJICAgIH0KKwl9KTsKKworCWlmIChyZXQgPT0gbnVsbCkKKwkgICAgLy8gTm9uLWV4aXN0ZW50IGZvbGRlci9ObyBwZXJtaXNzaW9uID8/CisJICAgIHJldHVybiBmYWxzZTsKKworCS8vIERFTEVURSBzdWNjZWVkZWQuCisJZXhpc3RzID0gZmFsc2U7CisJYXR0cmlidXRlcyA9IG51bGw7CisKKwkvLyBOb3RpZnkgbGlzdGVuZXJzIG9uIHNlbGYgYW5kIG91ciBTdG9yZQorCW5vdGlmeUZvbGRlckxpc3RlbmVycyhGb2xkZXJFdmVudC5ERUxFVEVEKTsKKwlyZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW5hbWUgdGhpcyBmb2xkZXIuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIHJlbmFtZVRvKGZpbmFsIEZvbGRlciBmKQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWNoZWNrQ2xvc2VkKCk7IC8vIGluc3VyZSB0aGF0IHdlIGFyZSBjbG9zZWQuCisJY2hlY2tFeGlzdHMoKTsKKwlpZiAoZi5nZXRTdG9yZSgpICE9IHN0b3JlKQorCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKCJDYW4ndCByZW5hbWUgYWNyb3NzIFN0b3JlcyIpOworCisKKwlPYmplY3QgcmV0ID0gZG9Db21tYW5kSWdub3JlRmFpbHVyZShuZXcgUHJvdG9jb2xDb21tYW5kKCkgeworCSAgICBAT3ZlcnJpZGUKKwkgICAgcHVibGljIE9iamVjdCBkb0NvbW1hbmQoSU1BUFByb3RvY29sIHApIHRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJCXAucmVuYW1lKGZ1bGxOYW1lLCBmLmdldEZ1bGxOYW1lKCkpOworCQlyZXR1cm4gQm9vbGVhbi5UUlVFOworCSAgICB9CisJfSk7CisKKwlpZiAocmV0ID09IG51bGwpCisJICAgIHJldHVybiBmYWxzZTsKKworCWV4aXN0cyA9IGZhbHNlOworCWF0dHJpYnV0ZXMgPSBudWxsOworCW5vdGlmeUZvbGRlclJlbmFtZWRMaXN0ZW5lcnMoZik7CisJcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogT3BlbiB0aGlzIGZvbGRlciBpbiB0aGUgZ2l2ZW4gbW9kZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgb3BlbihpbnQgbW9kZSkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJb3Blbihtb2RlLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBPcGVuIHRoaXMgZm9sZGVyIGluIHRoZSBnaXZlbiBtb2RlLCB3aXRoIHRoZSBnaXZlbgorICAgICAqIHJlc3luY2hyb25pemF0aW9uIGRhdGEuCisgICAgICoKKyAgICAgKiBAcGFyYW0JbW9kZQl0aGUgb3BlbiBtb2RlIChGb2xkZXIuUkVBRF9XUklURSBvciBGb2xkZXIuUkVBRF9PTkxZKQorICAgICAqIEBwYXJhbQlyZAl0aGUgUmVzeW5jRGF0YSBpbnN0YW5jZQorICAgICAqIEByZXR1cm4JCWEgTGlzdCBvZiBNYWlsRXZlbnQgaW5zdGFuY2VzLCBvciBudWxsIGlmIG5vbmUKKyAgICAgKiBAZXhjZXB0aW9uIE1lc3NhZ2luZ0V4Y2VwdGlvbglpZiB0aGUgb3BlbiBmYWlscworICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjUuMQorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgTGlzdDxNYWlsRXZlbnQ+IG9wZW4oaW50IG1vZGUsIFJlc3luY0RhdGEgcmQpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJY2hlY2tDbG9zZWQoKTsgLy8gaW5zdXJlIHRoYXQgd2UgYXJlIG5vdCBhbHJlYWR5IG9wZW4KKwkKKwlNYWlsYm94SW5mbyBtaSA9IG51bGw7CisJLy8gUmVxdWVzdCBzdG9yZSBmb3Igb3VyIG93biBwcm90b2NvbCBjb25uZWN0aW9uLgorCXByb3RvY29sID0gKChJTUFQU3RvcmUpc3RvcmUpLmdldFByb3RvY29sKHRoaXMpOworCisJTGlzdDxNYWlsRXZlbnQ+IG9wZW5FdmVudHMgPSBudWxsOworCXN5bmNocm9uaXplZChtZXNzYWdlQ2FjaGVMb2NrKSB7IC8vIEFjcXVpcmUgbWVzc2FnZUNhY2hlTG9jaworCisJICAgIC8qCisJICAgICAqIEFkZCByZXNwb25zZSBoYW5kbGVyIHJpZ2h0IGF3YXkgc28gd2UgZ2V0IGFueSBhbGVydHMgb3IKKwkgICAgICogbm90aWZpY2F0aW9ucyB0aGF0IG9jY3VyIGR1cmluZyB0aGUgU0VMRUNUIG9yIEVYQU1JTkUuCisJICAgICAqIEhhdmUgdG8gYmUgc3VyZSB0byByZW1vdmUgaXQgaWYgd2UgZmFpbCB0byBvcGVuIHRoZQorCSAgICAgKiBmb2xkZXIuCisJICAgICAqLworCSAgICBwcm90b2NvbC5hZGRSZXNwb25zZUhhbmRsZXIodGhpcyk7CisKKwkgICAgdHJ5IHsKKwkJLyoKKwkJICogRW5hYmxlIFFSRVNZTkMgb3IgQ09ORFNUT1JFIGlmIG5lZWRlZCBhbmQgbm90IGVuYWJsZWQuCisJCSAqIFFSRVNZTkMgaW1wbGllcyBDT05EU1RPUkUsIGJ1dCBzZXJ2ZXJzIHRoYXQgc3VwcG9ydAorCQkgKiBRUkVTWU5DIGFyZSBub3QgcmVxdWlyZWQgdG8gc3VwcG9ydCBqdXN0IENPTkRTVE9SRQorCQkgKiBwZXIgUkZDIDUxNjIuCisJCSAqLworCQlpZiAocmQgIT0gbnVsbCkgeworCQkgICAgaWYgKHJkID09IFJlc3luY0RhdGEuQ09ORFNUT1JFKSB7CisJCQlpZiAoIXByb3RvY29sLmlzRW5hYmxlZCgiQ09ORFNUT1JFIikgJiYKKwkJCSAgICAhcHJvdG9jb2wuaXNFbmFibGVkKCJRUkVTWU5DIikpIHsKKwkJCSAgICBpZiAocHJvdG9jb2wuaGFzQ2FwYWJpbGl0eSgiQ09ORFNUT1JFIikpCisJCQkJcHJvdG9jb2wuZW5hYmxlKCJDT05EU1RPUkUiKTsKKwkJCSAgICBlbHNlCisJCQkJcHJvdG9jb2wuZW5hYmxlKCJRUkVTWU5DIik7CisJCQl9CisJCSAgICB9IGVsc2UgeworCQkJaWYgKCFwcm90b2NvbC5pc0VuYWJsZWQoIlFSRVNZTkMiKSkKKwkJCSAgICBwcm90b2NvbC5lbmFibGUoIlFSRVNZTkMiKTsKKwkJICAgIH0KKwkJfQorCisJCWlmIChtb2RlID09IFJFQURfT05MWSkKKwkJICAgIG1pID0gcHJvdG9jb2wuZXhhbWluZShmdWxsTmFtZSwgcmQpOworCQllbHNlCisJCSAgICBtaSA9IHByb3RvY29sLnNlbGVjdChmdWxsTmFtZSwgcmQpOworCSAgICB9IGNhdGNoIChDb21tYW5kRmFpbGVkRXhjZXB0aW9uIGNleCkgeworCQkvKgorCQkgKiBIYW5kbGUgU0VMRUNUIG9yIEVYQU1JTkUgZmFpbHVyZS4KKwkJICogVHJ5IHRvIGZpZ3VyZSBvdXQgd2h5IHRoZSBvcGVyYXRpb24gZmFpbGVkIHNvIHdlIGNhbgorCQkgKiByZXBvcnQgYSBtb3JlIHJlYXNvbmFibGUgZXhjZXB0aW9uLgorCQkgKgorCQkgKiBXaWxsIHVzZSBvdXIgZXhpc3RpbmcgcHJvdG9jb2wgb2JqZWN0LgorCQkgKi8KKwkJdHJ5IHsKKwkJICAgIGNoZWNrRXhpc3RzKCk7IC8vIHRocm93IGV4Y2VwdGlvbiBpZiBmb2xkZXIgZG9lc24ndCBleGlzdAorCisJCSAgICBpZiAoKHR5cGUgJiBIT0xEU19NRVNTQUdFUykgPT0gMCkKKwkJCXRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oCisJCQkgICAgImZvbGRlciBjYW5ub3QgY29udGFpbiBtZXNzYWdlcyIpOworCQkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbihjZXguZ2V0TWVzc2FnZSgpLCBjZXgpOworCisJCX0gZmluYWxseSB7CisJCSAgICAvLyBmb2xkZXIgbm90IG9wZW4sIGRvbid0IGtlZXAgdGhpcyBpbmZvcm1hdGlvbgorCQkgICAgZXhpc3RzID0gZmFsc2U7CisJCSAgICBhdHRyaWJ1dGVzID0gbnVsbDsKKwkJICAgIHR5cGUgPSAwOworCQkgICAgLy8gY29ubmVjdGlvbiBzdGlsbCBnb29kLCByZXR1cm4gaXQKKwkJICAgIHJlbGVhc2VQcm90b2NvbCh0cnVlKTsKKwkJfQorCQkvLyBOT1RSRUFDSEVECisJICAgIH0gY2F0Y2ggKFByb3RvY29sRXhjZXB0aW9uIHBleCkgeworCQkvLyBnb3QgYSBCQUQgb3IgYSBCWUU7IGNvbm5lY3Rpb24gbWF5IGJlIGJhZCwgY2xvc2UgaXQKKwkJdHJ5IHsKKwkJICAgIHRocm93IGxvZ291dEFuZFRocm93KHBleC5nZXRNZXNzYWdlKCksIHBleCk7CisJCX0gZmluYWxseSB7CisJCSAgICByZWxlYXNlUHJvdG9jb2woZmFsc2UpOworCQl9CisJICAgIH0KKworCSAgICBpZiAobWkubW9kZSAhPSBtb2RlKSB7CisJCWlmIChtb2RlID09IFJFQURfV1JJVEUgJiYgbWkubW9kZSA9PSBSRUFEX09OTFkgJiYKKwkJCSgoSU1BUFN0b3JlKXN0b3JlKS5hbGxvd1JlYWRPbmx5U2VsZWN0KCkpIHsKKwkJICAgIDsJCS8vIGFsbCBvaywgYWxsb3cgaXQKKwkJfSBlbHNlIHsJLy8gb3RoZXJ3aXNlLCBpdCdzIGFuIGVycm9yCisJCSAgICBSZWFkT25seUZvbGRlckV4Y2VwdGlvbiBpZmUgPSBuZXcgUmVhZE9ubHlGb2xkZXJFeGNlcHRpb24oCisJCQkgICAgdGhpcywgIkNhbm5vdCBvcGVuIGluIGRlc2lyZWQgbW9kZSIpOworCQkgICAgdGhyb3cgY2xlYW51cEFuZFRocm93KGlmZSk7CisJCX0KKyAgICAgICAgICAgIH0KKwkKKwkgICAgLy8gSW5pdGlhbGl6ZSBzdHVmZi4KKwkgICAgb3BlbmVkID0gdHJ1ZTsKKwkgICAgcmVhbGx5Q2xvc2VkID0gZmFsc2U7CisJICAgIHRoaXMubW9kZSA9IG1pLm1vZGU7CisJICAgIGF2YWlsYWJsZUZsYWdzID0gbWkuYXZhaWxhYmxlRmxhZ3M7CisJICAgIHBlcm1hbmVudEZsYWdzID0gbWkucGVybWFuZW50RmxhZ3M7CisJICAgIHRvdGFsID0gcmVhbFRvdGFsID0gbWkudG90YWw7CisJICAgIHJlY2VudCA9IG1pLnJlY2VudDsKKwkgICAgdWlkdmFsaWRpdHkgPSBtaS51aWR2YWxpZGl0eTsKKwkgICAgdWlkbmV4dCA9IG1pLnVpZG5leHQ7CisJICAgIHVpZE5vdFN0aWNreSA9IG1pLnVpZE5vdFN0aWNreTsKKwkgICAgaGlnaGVzdG1vZHNlcSA9IG1pLmhpZ2hlc3Rtb2RzZXE7CisKKwkgICAgLy8gQ3JlYXRlIHRoZSBtZXNzYWdlIGNhY2hlIG9mIGFwcHJvcHJpYXRlIHNpemUKKwkgICAgbWVzc2FnZUNhY2hlID0gbmV3IE1lc3NhZ2VDYWNoZSh0aGlzLCAoSU1BUFN0b3JlKXN0b3JlLCB0b3RhbCk7CisKKwkgICAgLy8gcHJvY2VzcyBzYXZlZCByZXNwb25zZXMgYW5kIHJldHVybiBjb3JyZXNwb25kaW5nIGV2ZW50cworCSAgICBpZiAobWkucmVzcG9uc2VzICE9IG51bGwpIHsKKwkJb3BlbkV2ZW50cyA9IG5ldyBBcnJheUxpc3Q8PigpOworCQlmb3IgKElNQVBSZXNwb25zZSBpciA6IG1pLnJlc3BvbnNlcykgeworCQkgICAgaWYgKGlyLmtleUVxdWFscygiVkFOSVNIRUQiKSkgeworCQkJLy8gIlZBTklTSEVEIiBTUCBbIihFQVJMSUVSKSJdIFNQIGtub3duLXVpZHMKKwkJCVN0cmluZ1tdIHMgPSBpci5yZWFkQXRvbVN0cmluZ0xpc3QoKTsKKwkJCS8vIGNoZWNrIHRoYXQgaXQgcmVhbGx5IGlzICJFQVJMSUVSIgorCQkJaWYgKHMgPT0gbnVsbCB8fCBzLmxlbmd0aCAhPSAxIHx8CisJCQkJCSAgICAhc1swXS5lcXVhbHNJZ25vcmVDYXNlKCJFQVJMSUVSIikpCisJCQkgICAgY29udGludWU7CS8vIGl0J3Mgbm90LCB3aGF0IHRvIGRvIHdpdGggaXQgaGVyZT8KKwkJCVN0cmluZyB1aWRzID0gaXIucmVhZEF0b20oKTsKKwkJCVVJRFNldFtdIHVpZHNldCA9IFVJRFNldC5wYXJzZVVJRFNldHModWlkcyk7CisJCQlsb25nW10gbHVpZCA9IFVJRFNldC50b0FycmF5KHVpZHNldCwgdWlkbmV4dCk7CisJCQlpZiAobHVpZCAhPSBudWxsICYmIGx1aWQubGVuZ3RoID4gMCkKKwkJCSAgICBvcGVuRXZlbnRzLmFkZCgKKwkJCQluZXcgTWVzc2FnZVZhbmlzaGVkRXZlbnQodGhpcywgbHVpZCkpOworCQkgICAgfSBlbHNlIGlmIChpci5rZXlFcXVhbHMoIkZFVENIIikpIHsKKwkJCWFzc2VydCBpciBpbnN0YW5jZW9mIEZldGNoUmVzcG9uc2UgOgorCQkJCSIhaXIgaW5zdGFuY2VvZiBGZXRjaFJlc3BvbnNlIjsKKwkJCU1lc3NhZ2UgbXNnID0gcHJvY2Vzc0ZldGNoUmVzcG9uc2UoKEZldGNoUmVzcG9uc2UpaXIpOworCQkJaWYgKG1zZyAhPSBudWxsKQorCQkJICAgIG9wZW5FdmVudHMuYWRkKG5ldyBNZXNzYWdlQ2hhbmdlZEV2ZW50KHRoaXMsCisJCQkJICAgIE1lc3NhZ2VDaGFuZ2VkRXZlbnQuRkxBR1NfQ0hBTkdFRCwgbXNnKSk7CisJCSAgICB9CisJCX0KKwkgICAgfQorCX0gLy8gUmVsZWFzZSBsb2NrCisKKwlleGlzdHMgPSB0cnVlOwkJLy8gaWYgd2Ugb3BlbmVkIGl0LCBpdCBtdXN0IGV4aXN0CisJYXR0cmlidXRlcyA9IG51bGw7CS8vIGJ1dCB3ZSBkb24ndCB5ZXQga25vdyBpdHMgYXR0cmlidXRlcworCXR5cGUgPSBIT0xEU19NRVNTQUdFUzsJLy8gbGFja2luZyBtb3JlIGluZm8sIHdlIGtub3cgYXQgbGVhc3QgdGhpcyBtdWNoCisKKwkvLyBub3RpZnkgbGlzdGVuZXJzCisJbm90aWZ5Q29ubmVjdGlvbkxpc3RlbmVycyhDb25uZWN0aW9uRXZlbnQuT1BFTkVEKTsKKworCXJldHVybiBvcGVuRXZlbnRzOworICAgIH0KKworICAgIHByaXZhdGUgTWVzc2FnaW5nRXhjZXB0aW9uIGNsZWFudXBBbmRUaHJvdyhNZXNzYWdpbmdFeGNlcHRpb24gaWZlKSB7CisJdHJ5IHsKKwkgICAgdHJ5IHsKKwkJLy8gY2xvc2UgbWFpbGJveCBhbmQgcmV0dXJuIGNvbm5lY3Rpb24KKwkJcHJvdG9jb2wuY2xvc2UoKTsKKwkJcmVsZWFzZVByb3RvY29sKHRydWUpOworCSAgICB9IGNhdGNoIChQcm90b2NvbEV4Y2VwdGlvbiBwZXgpIHsKKwkJLy8gc29tZXRoaW5nIHdlbnQgd3JvbmcsIGNsb3NlIGNvbm5lY3Rpb24KKwkJdHJ5IHsKKwkJICAgIGFkZFN1cHByZXNzZWQoaWZlLCBsb2dvdXRBbmRUaHJvdyhwZXguZ2V0TWVzc2FnZSgpLCBwZXgpKTsKKwkJfSBmaW5hbGx5IHsKKwkJICAgIHJlbGVhc2VQcm90b2NvbChmYWxzZSk7CisJCX0KKwkgICAgfQorCX0gY2F0Y2ggKFRocm93YWJsZSB0aHIpIHsKKwkgICAgYWRkU3VwcHJlc3NlZChpZmUsIHRocik7CisJfQorCXJldHVybiBpZmU7CisgICAgfQorCisgICAgcHJpdmF0ZSBNZXNzYWdpbmdFeGNlcHRpb24gbG9nb3V0QW5kVGhyb3coU3RyaW5nIHdoeSwgUHJvdG9jb2xFeGNlcHRpb24gdCkgeworCU1lc3NhZ2luZ0V4Y2VwdGlvbiBpZmUgPSBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKHdoeSwgdCk7CisJdHJ5IHsKKwkgICAgcHJvdG9jb2wubG9nb3V0KCk7CisJfSBjYXRjaCAoVGhyb3dhYmxlIHRocikgeworCSAgICBhZGRTdXBwcmVzc2VkKGlmZSwgdGhyKTsKKwl9CisJcmV0dXJuIGlmZTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYWRkU3VwcHJlc3NlZChUaHJvd2FibGUgaWZlLCBUaHJvd2FibGUgdGhyKSB7CisJaWYgKGlzUmVjb3ZlcmFibGUodGhyKSkgeworCSAgICBpZmUuYWRkU3VwcHJlc3NlZCh0aHIpOworCX0gZWxzZSB7CisJICAgIHRoci5hZGRTdXBwcmVzc2VkKGlmZSk7CisJICAgIGlmICh0aHIgaW5zdGFuY2VvZiBFcnJvcikgeworCQl0aHJvdyAoRXJyb3IpIHRocjsKKwkgICAgfQorCSAgICBpZiAodGhyIGluc3RhbmNlb2YgUnVudGltZUV4Y2VwdGlvbikgeworCQl0aHJvdyAoUnVudGltZUV4Y2VwdGlvbikgdGhyOworCSAgICB9CisJICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbiIsIHRocik7CisJfQorICAgIH0KKworICAgIHByaXZhdGUgYm9vbGVhbiBpc1JlY292ZXJhYmxlKFRocm93YWJsZSB0KSB7CisJcmV0dXJuICh0IGluc3RhbmNlb2YgRXhjZXB0aW9uKSB8fCAodCBpbnN0YW5jZW9mIExpbmthZ2VFcnJvcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJlZmV0Y2ggYXR0cmlidXRlcywgYmFzZWQgb24gdGhlIGdpdmVuIEZldGNoUHJvZmlsZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgZmV0Y2goTWVzc2FnZVtdIG1zZ3MsIEZldGNoUHJvZmlsZSBmcCkKKwkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCS8vIGNhY2hlIHRoaXMgaW5mb3JtYXRpb24gaW4gY2FzZSBjb25uZWN0aW9uIGlzIGNsb3NlZCBhbmQKKwkvLyBwcm90b2NvbCBpcyBzZXQgdG8gbnVsbAorCWJvb2xlYW4gaXNSZXYxOworCUZldGNoSXRlbVtdIGZpdGVtczsKKyAgICAgICAgc3luY2hyb25pemVkIChtZXNzYWdlQ2FjaGVMb2NrKSB7CisJICAgIGNoZWNrT3BlbmVkKCk7CisJICAgIGlzUmV2MSA9IHByb3RvY29sLmlzUkVWMSgpOworCSAgICBmaXRlbXMgPSBwcm90b2NvbC5nZXRGZXRjaEl0ZW1zKCk7CisJfQorCisJU3RyaW5nQnVpbGRlciBjb21tYW5kID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKwlib29sZWFuIGZpcnN0ID0gdHJ1ZTsKKwlib29sZWFuIGFsbEhlYWRlcnMgPSBmYWxzZTsKKworCWlmIChmcC5jb250YWlucyhGZXRjaFByb2ZpbGUuSXRlbS5FTlZFTE9QRSkpIHsKKwkgICAgY29tbWFuZC5hcHBlbmQoZ2V0RW52ZWxvcGVDb21tYW5kKCkpOworCSAgICBmaXJzdCA9IGZhbHNlOworCX0KKwlpZiAoZnAuY29udGFpbnMoRmV0Y2hQcm9maWxlLkl0ZW0uRkxBR1MpKSB7CisJICAgIGNvbW1hbmQuYXBwZW5kKGZpcnN0ID8gIkZMQUdTIiA6ICIgRkxBR1MiKTsKKwkgICAgZmlyc3QgPSBmYWxzZTsKKwl9CisJaWYgKGZwLmNvbnRhaW5zKEZldGNoUHJvZmlsZS5JdGVtLkNPTlRFTlRfSU5GTykpIHsKKwkgICAgY29tbWFuZC5hcHBlbmQoZmlyc3QgPyAiQk9EWVNUUlVDVFVSRSIgOiAiIEJPRFlTVFJVQ1RVUkUiKTsKKwkgICAgZmlyc3QgPSBmYWxzZTsKKwl9CisJaWYgKGZwLmNvbnRhaW5zKFVJREZvbGRlci5GZXRjaFByb2ZpbGVJdGVtLlVJRCkpIHsKKwkgICAgY29tbWFuZC5hcHBlbmQoZmlyc3QgPyAiVUlEIiA6ICIgVUlEIik7CisJICAgIGZpcnN0ID0gZmFsc2U7CisJfQorCWlmIChmcC5jb250YWlucyhJTUFQRm9sZGVyLkZldGNoUHJvZmlsZUl0ZW0uSEVBREVSUykpIHsKKwkgICAgYWxsSGVhZGVycyA9IHRydWU7CisJICAgIGlmIChpc1JldjEpCisJCWNvbW1hbmQuYXBwZW5kKGZpcnN0ID8KKwkJCSAgICAiQk9EWS5QRUVLW0hFQURFUl0iIDogIiBCT0RZLlBFRUtbSEVBREVSXSIpOworCSAgICBlbHNlCisJCWNvbW1hbmQuYXBwZW5kKGZpcnN0ID8gIlJGQzgyMi5IRUFERVIiIDogIiBSRkM4MjIuSEVBREVSIik7CisJICAgIGZpcnN0ID0gZmFsc2U7CisJfQorCWlmIChmcC5jb250YWlucyhJTUFQRm9sZGVyLkZldGNoUHJvZmlsZUl0ZW0uTUVTU0FHRSkpIHsKKwkgICAgYWxsSGVhZGVycyA9IHRydWU7CisJICAgIGlmIChpc1JldjEpCisJCWNvbW1hbmQuYXBwZW5kKGZpcnN0ID8gIkJPRFkuUEVFS1tdIiA6ICIgQk9EWS5QRUVLW10iKTsKKwkgICAgZWxzZQorCQljb21tYW5kLmFwcGVuZChmaXJzdCA/ICJSRkM4MjIiIDogIiBSRkM4MjIiKTsKKwkgICAgZmlyc3QgPSBmYWxzZTsKKwl9CisJaWYgKGZwLmNvbnRhaW5zKEZldGNoUHJvZmlsZS5JdGVtLlNJWkUpIHx8CisJCWZwLmNvbnRhaW5zKElNQVBGb2xkZXIuRmV0Y2hQcm9maWxlSXRlbS5TSVpFKSkgeworCSAgICBjb21tYW5kLmFwcGVuZChmaXJzdCA/ICJSRkM4MjIuU0laRSIgOiAiIFJGQzgyMi5TSVpFIik7CisJICAgIGZpcnN0ID0gZmFsc2U7CisJfQorCWlmIChmcC5jb250YWlucyhJTUFQRm9sZGVyLkZldGNoUHJvZmlsZUl0ZW0uSU5URVJOQUxEQVRFKSkgeworCSAgICBjb21tYW5kLmFwcGVuZChmaXJzdCA/ICJJTlRFUk5BTERBVEUiIDogIiBJTlRFUk5BTERBVEUiKTsKKwkgICAgZmlyc3QgPSBmYWxzZTsKKwl9CisKKwkvLyBpZiB3ZSdyZSBub3QgZmV0Y2hpbmcgYWxsIGhlYWRlcnMsIGZldGNoIGluZGl2aWR1YWwgaGVhZGVycworCVN0cmluZ1tdIGhkcnMgPSBudWxsOworCWlmICghYWxsSGVhZGVycykgeworCSAgICBoZHJzID0gZnAuZ2V0SGVhZGVyTmFtZXMoKTsKKwkgICAgaWYgKGhkcnMubGVuZ3RoID4gMCkgeworCQlpZiAoIWZpcnN0KQorCQkgICAgY29tbWFuZC5hcHBlbmQoIiAiKTsKKwkJY29tbWFuZC5hcHBlbmQoY3JlYXRlSGVhZGVyQ29tbWFuZChoZHJzLCBpc1JldjEpKTsKKwkgICAgfQorCX0KKworCS8qCisJICogQWRkIGFueSBhZGRpdGlvbmFsIGV4dGVuc2lvbiBmZXRjaCBpdGVtcy4KKwkgKi8KKwlmb3IgKGludCBpID0gMDsgaSA8IGZpdGVtcy5sZW5ndGg7IGkrKykgeworCSAgICBpZiAoZnAuY29udGFpbnMoZml0ZW1zW2ldLmdldEZldGNoUHJvZmlsZUl0ZW0oKSkpIHsKKwkJaWYgKGNvbW1hbmQubGVuZ3RoKCkgIT0gMCkKKwkJICAgIGNvbW1hbmQuYXBwZW5kKCIgIik7CisJCWNvbW1hbmQuYXBwZW5kKGZpdGVtc1tpXS5nZXROYW1lKCkpOworCSAgICB9CisJfQorCisJVXRpbGl0eS5Db25kaXRpb24gY29uZGl0aW9uID0KKwkgICAgbmV3IElNQVBNZXNzYWdlLkZldGNoUHJvZmlsZUNvbmRpdGlvbihmcCwgZml0ZW1zKTsKKworICAgICAgICAvLyBBY3F1aXJlIHRoZSBGb2xkZXIncyBNZXNzYWdlQ2FjaGVMb2NrLgorICAgICAgICBzeW5jaHJvbml6ZWQgKG1lc3NhZ2VDYWNoZUxvY2spIHsKKworCSAgICAvLyBjaGVjayBhZ2FpbiB0byBtYWtlIHN1cmUgZm9sZGVyIGlzIHN0aWxsIG9wZW4KKwkgICAgY2hlY2tPcGVuZWQoKTsKKworCSAgICAvLyBBcHBseSB0aGUgdGVzdCwgYW5kIGdldCB0aGUgc2VxdWVuY2UtbnVtYmVyIHNldCBmb3IKKwkgICAgLy8gdGhlIG1lc3NhZ2VzIHRoYXQgbmVlZCB0byBiZSBwcmVmZXRjaGVkLgorCSAgICBNZXNzYWdlU2V0W10gbXNnc2V0cyA9IFV0aWxpdHkudG9NZXNzYWdlU2V0U29ydGVkKG1zZ3MsIGNvbmRpdGlvbik7CisKKwkgICAgaWYgKG1zZ3NldHMgPT0gbnVsbCkKKwkJLy8gV2UgYWxyZWFkeSBoYXZlIHdoYXQgd2UgbmVlZC4KKwkJcmV0dXJuOworCisJICAgIFJlc3BvbnNlW10gciA9IG51bGw7CisJICAgIC8vIHRvIGNvbGxlY3Qgbm9uLUZFVENIIHJlc3BvbnNlcyAmIHVuc29saWNpdGVkIEZFVENIIEZMQUcgcmVzcG9uc2VzIAorCSAgICBMaXN0PFJlc3BvbnNlPiB2ID0gbmV3IEFycmF5TGlzdDw+KCk7CisJICAgIHRyeSB7CisJCXIgPSBnZXRQcm90b2NvbCgpLmZldGNoKG1zZ3NldHMsIGNvbW1hbmQudG9TdHJpbmcoKSk7CisJICAgIH0gY2F0Y2ggKENvbm5lY3Rpb25FeGNlcHRpb24gY2V4KSB7CisJCXRocm93IG5ldyBGb2xkZXJDbG9zZWRFeGNlcHRpb24odGhpcywgY2V4LmdldE1lc3NhZ2UoKSk7CisJICAgIH0gY2F0Y2ggKENvbW1hbmRGYWlsZWRFeGNlcHRpb24gY2Z4KSB7CisJCS8vIElnbm9yZSB0aGVzZSwgYXMgcGVyIFJGQyAyMTgwCisJICAgIH0gY2F0Y2ggKFByb3RvY29sRXhjZXB0aW9uIHBleCkgeyAKKwkJdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbihwZXguZ2V0TWVzc2FnZSgpLCBwZXgpOworCSAgICB9CisKKwkgICAgaWYgKHIgPT0gbnVsbCkKKwkJcmV0dXJuOworCSAgIAorCSAgICBmb3IgKGludCBpID0gMDsgaSA8IHIubGVuZ3RoOyBpKyspIHsKKwkJaWYgKHJbaV0gPT0gbnVsbCkKKwkJICAgIGNvbnRpbnVlOworCQlpZiAoIShyW2ldIGluc3RhbmNlb2YgRmV0Y2hSZXNwb25zZSkpIHsKKwkJICAgIHYuYWRkKHJbaV0pOyAvLyBVbnNvbGljaXRlZCBOb24tRkVUQ0ggcmVzcG9uc2UKKwkJICAgIGNvbnRpbnVlOworCQl9CisKKwkJLy8gR290IGEgRmV0Y2hSZXNwb25zZS4KKwkJRmV0Y2hSZXNwb25zZSBmID0gKEZldGNoUmVzcG9uc2UpcltpXTsKKwkJLy8gR2V0IHRoZSBjb3JyZXNwb25kaW5nIG1lc3NhZ2UuCisJCUlNQVBNZXNzYWdlIG1zZyA9IGdldE1lc3NhZ2VCeVNlcU51bWJlcihmLmdldE51bWJlcigpKTsKKworCQlpbnQgY291bnQgPSBmLmdldEl0ZW1Db3VudCgpOworCQlib29sZWFuIHVuc29saWNpdGVkRmxhZ3MgPSBmYWxzZTsKKworCQlmb3IgKGludCBqID0gMDsgaiA8IGNvdW50OyBqKyspIHsKKwkJICAgIEl0ZW0gaXRlbSA9IGYuZ2V0SXRlbShqKTsKKwkJICAgIC8vIENoZWNrIGZvciB0aGUgRkxBR1MgaXRlbQorCQkgICAgaWYgKGl0ZW0gaW5zdGFuY2VvZiBGbGFncyAmJgorCQkJICAgICghZnAuY29udGFpbnMoRmV0Y2hQcm9maWxlLkl0ZW0uRkxBR1MpIHx8CisJCQkJbXNnID09IG51bGwpKSB7CisJCQkvLyBPaywgVW5zb2xpY2l0ZWQgRkxBR1MgdXBkYXRlLgorCQkJdW5zb2xpY2l0ZWRGbGFncyA9IHRydWU7CisJCSAgICB9IGVsc2UgaWYgKG1zZyAhPSBudWxsKQorCQkJbXNnLmhhbmRsZUZldGNoSXRlbShpdGVtLCBoZHJzLCBhbGxIZWFkZXJzKTsKKwkJfQorCQlpZiAobXNnICE9IG51bGwpCisJCSAgICBtc2cuaGFuZGxlRXh0ZW5zaW9uRmV0Y2hJdGVtcyhmLmdldEV4dGVuc2lvbkl0ZW1zKCkpOworCisJCS8vIElmIHRoaXMgcmVzcG9uc2UgY29udGFpbnMgYW55IHVuc29saWNpdGVkIEZMQUdTCisJCS8vIGFkZCBpdCB0byB0aGUgdW5zb2xpY2l0ZWQgcmVzcG9uc2UgdmVjdG9yCisJCWlmICh1bnNvbGljaXRlZEZsYWdzKQorCQkgICAgdi5hZGQoZik7CisJICAgIH0KKworCSAgICAvLyBEaXNwYXRjaCBhbnkgdW5zb2xpY2l0ZWQgcmVzcG9uc2VzCisJICAgIGlmICghdi5pc0VtcHR5KCkpIHsKKwkJUmVzcG9uc2VbXSByZXNwb25zZXMgPSBuZXcgUmVzcG9uc2Vbdi5zaXplKCldOworCQl2LnRvQXJyYXkocmVzcG9uc2VzKTsKKwkJaGFuZGxlUmVzcG9uc2VzKHJlc3BvbnNlcyk7CisJICAgIH0KKworCX0gLy8gUmVsZWFzZSBtZXNzYWdlQ2FjaGVMb2NrCisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBJTUFQIEZFVENIIGl0ZW1zIHRvIHJlcXVlc3QgaW4gb3JkZXIgdG8gbG9hZAorICAgICAqIGFsbCB0aGUgImVudmVsb3BlIiBkYXRhLiAgU3ViY2xhc3NlcyBjYW4gb3ZlcnJpZGUgdGhpcworICAgICAqIG1ldGhvZCB0byBmZXRjaCBtb3JlIGRhdGEgd2hlbiBGZXRjaFByb2ZpbGUuSXRlbS5FTlZFTE9QRQorICAgICAqIGlzIHJlcXVlc3RlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIElNQVAgRkVUQ0ggaXRlbXMgdG8gcmVxdWVzdAorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjQuNgorICAgICAqLworICAgIHByb3RlY3RlZCBTdHJpbmcgZ2V0RW52ZWxvcGVDb21tYW5kKCkgeworCXJldHVybiBJTUFQTWVzc2FnZS5FbnZlbG9wZUNtZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBuZXcgSU1BUE1lc3NhZ2Ugb2JqZWN0IHRvIHJlcHJlc2VudCB0aGUgZ2l2ZW4gbWVzc2FnZSBudW1iZXIuCisgICAgICogU3ViY2xhc3NlcyBvZiBJTUFQRm9sZGVyIG1heSBvdmVycmlkZSB0aGlzIG1ldGhvZCB0byBjcmVhdGUgYQorICAgICAqIHN1YmNsYXNzIG9mIElNQVBNZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtCW1zZ251bQl0aGUgbWVzc2FnZSBzZXF1ZW5jZSBudW1iZXIKKyAgICAgKiBAcmV0dXJuCXRoZSBuZXcgSU1BUE1lc3NhZ2Ugb2JqZWN0CisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNC42CisgICAgICovCisgICAgcHJvdGVjdGVkIElNQVBNZXNzYWdlIG5ld0lNQVBNZXNzYWdlKGludCBtc2dudW0pIHsKKwlyZXR1cm4gbmV3IElNQVBNZXNzYWdlKHRoaXMsIG1zZ251bSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIHRoZSBhcHByb3ByaWF0ZSBJTUFQIEZFVENIIGNvbW1hbmQgaXRlbXMgdG8gZmV0Y2ggdGhlCisgICAgICogcmVxdWVzdGVkIGhlYWRlcnMuCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgY3JlYXRlSGVhZGVyQ29tbWFuZChTdHJpbmdbXSBoZHJzLCBib29sZWFuIGlzUmV2MSkgeworCVN0cmluZ0J1aWxkZXIgc2I7CisKKwlpZiAoaXNSZXYxKQorCSAgICBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCJCT0RZLlBFRUtbSEVBREVSLkZJRUxEUyAoIik7CisJZWxzZQorCSAgICBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCJSRkM4MjIuSEVBREVSLkxJTkVTICgiKTsKKworCWZvciAoaW50IGkgPSAwOyBpIDwgaGRycy5sZW5ndGg7IGkrKykgeworCSAgICBpZiAoaSA+IDApCisJCXNiLmFwcGVuZCgiICIpOworCSAgICBzYi5hcHBlbmQoaGRyc1tpXSk7CisJfQorCisJaWYgKGlzUmV2MSkKKwkgICAgc2IuYXBwZW5kKCIpXSIpOworCWVsc2UKKwkgICAgc2IuYXBwZW5kKCIpIik7CisJCisJcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBzcGVjaWZpZWQgZmxhZ3MgZm9yIHRoZSBnaXZlbiBhcnJheSBvZiBtZXNzYWdlcy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgc2V0RmxhZ3MoTWVzc2FnZVtdIG1zZ3MsIEZsYWdzIGZsYWcsIGJvb2xlYW4gdmFsdWUpCisJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwljaGVja09wZW5lZCgpOworCWNoZWNrRmxhZ3MoZmxhZyk7IC8vIHZhbGlkYXRlIGZsYWdzCisKKwlpZiAobXNncy5sZW5ndGggPT0gMCkgLy8gYm91bmRhcnkgY29uZGl0aW9uCisJICAgIHJldHVybjsKKworCXN5bmNocm9uaXplZChtZXNzYWdlQ2FjaGVMb2NrKSB7CisJICAgIHRyeSB7CisJCUlNQVBQcm90b2NvbCBwID0gZ2V0UHJvdG9jb2woKTsKKwkJTWVzc2FnZVNldFtdIG1zID0gVXRpbGl0eS50b01lc3NhZ2VTZXRTb3J0ZWQobXNncywgbnVsbCk7CisJCWlmIChtcyA9PSBudWxsKQorCQkgICAgdGhyb3cgbmV3IE1lc3NhZ2VSZW1vdmVkRXhjZXB0aW9uKAorCQkJCQkiTWVzc2FnZXMgaGF2ZSBiZWVuIHJlbW92ZWQiKTsKKwkJcC5zdG9yZUZsYWdzKG1zLCBmbGFnLCB2YWx1ZSk7CisJICAgIH0gY2F0Y2ggKENvbm5lY3Rpb25FeGNlcHRpb24gY2V4KSB7CisJCXRocm93IG5ldyBGb2xkZXJDbG9zZWRFeGNlcHRpb24odGhpcywgY2V4LmdldE1lc3NhZ2UoKSk7CisJICAgIH0gY2F0Y2ggKFByb3RvY29sRXhjZXB0aW9uIHBleCkgeworCQl0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKHBleC5nZXRNZXNzYWdlKCksIHBleCk7CisJICAgIH0KKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBzcGVjaWZpZWQgZmxhZ3MgZm9yIHRoZSBnaXZlbiByYW5nZSBvZiBtZXNzYWdlIG51bWJlcnMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHNldEZsYWdzKGludCBzdGFydCwgaW50IGVuZCwKKwkJCUZsYWdzIGZsYWcsIGJvb2xlYW4gdmFsdWUpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWNoZWNrT3BlbmVkKCk7CisJTWVzc2FnZVtdIG1zZ3MgPSBuZXcgTWVzc2FnZVtlbmQgLSBzdGFydCArIDFdOworCWludCBpID0gMDsKKwlmb3IgKGludCBuID0gc3RhcnQ7IG4gPD0gZW5kOyBuKyspCisJICAgIG1zZ3NbaSsrXSA9IGdldE1lc3NhZ2Uobik7CisJc2V0RmxhZ3MobXNncywgZmxhZywgdmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgc3BlY2lmaWVkIGZsYWdzIGZvciB0aGUgZ2l2ZW4gYXJyYXkgb2YgbWVzc2FnZSBudW1iZXJzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXRGbGFncyhpbnRbXSBtc2dudW1zLCBGbGFncyBmbGFnLCBib29sZWFuIHZhbHVlKQorCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJY2hlY2tPcGVuZWQoKTsKKwlNZXNzYWdlW10gbXNncyA9IG5ldyBNZXNzYWdlW21zZ251bXMubGVuZ3RoXTsKKwlmb3IgKGludCBpID0gMDsgaSA8IG1zZ251bXMubGVuZ3RoOyBpKyspCisJICAgIG1zZ3NbaV0gPSBnZXRNZXNzYWdlKG1zZ251bXNbaV0pOworCXNldEZsYWdzKG1zZ3MsIGZsYWcsIHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9zZSB0aGlzIGZvbGRlci4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgY2xvc2UoYm9vbGVhbiBleHB1bmdlKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwljbG9zZShleHB1bmdlLCBmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2UgdGhpcyBmb2xkZXIgd2l0aG91dCB3YWl0aW5nIGZvciB0aGUgc2VydmVyLgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGZvcmNlQ2xvc2UoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwljbG9zZShmYWxzZSwgdHJ1ZSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBDb21tb24gY2xvc2UgbWV0aG9kLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBjbG9zZShib29sZWFuIGV4cHVuZ2UsIGJvb2xlYW4gZm9yY2UpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJYXNzZXJ0IFRocmVhZC5ob2xkc0xvY2sodGhpcyk7CisJc3luY2hyb25pemVkKG1lc3NhZ2VDYWNoZUxvY2spIHsKKwkgICAgLyoKKwkgICAgICogSWYgd2UgYWxyZWFkeSBrbm93IHdlJ3JlIGNsb3NlZCwgdGhpcyBpcyBpbGxlZ2FsLgorCSAgICAgKiBDYW4ndCB1c2UgY2hlY2tPcGVuZWQoKSBiZWNhdXNlIGlmIHdlIHdlcmUgZm9yY2libHkKKwkgICAgICogY2xvc2VkIGFzeW5jaHJvbm91c2x5IHdlIGp1c3Qgd2FudCB0byBjb21wbGV0ZSB0aGUKKwkgICAgICogY2xvc2luZyBoZXJlLgorCSAgICAgKi8KKwkgICAgaWYgKCFvcGVuZWQgJiYgcmVhbGx5Q2xvc2VkKQorCQl0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKAorCQkgICAgIlRoaXMgb3BlcmF0aW9uIGlzIG5vdCBhbGxvd2VkIG9uIGEgY2xvc2VkIGZvbGRlciIKKwkJKTsKKworCSAgICByZWFsbHlDbG9zZWQgPSB0cnVlOyAvLyBPaywgbGV0cyByZXNldAorCisJICAgIC8vIE1heWJlIHRoaXMgZm9sZGVyIGlzIGFscmVhZHkgY2xvc2VkLCBvciBtYXliZSBhbm90aGVyCisJICAgIC8vIHRocmVhZCB3aGljaCBoYWQgdGhlIG1lc3NhZ2VDYWNoZUxvY2sgZWFybGllciwgZm91bmQKKwkgICAgLy8gdGhhdCBvdXIgc2VydmVyIGNvbm5lY3Rpb24gaXMgZGVhZCBhbmQgY2xlYW5lZCB1cAorCSAgICAvLyBldmVyeXRoaW5nIC4uCisJICAgIGlmICghb3BlbmVkKQorCQlyZXR1cm47CisKKwkgICAgYm9vbGVhbiByZXVzZVByb3RvY29sID0gdHJ1ZTsKKwkgICAgdHJ5IHsKKwkJd2FpdElmSWRsZSgpOworCQlpZiAoZm9yY2UpIHsKKwkJICAgIGxvZ2dlci5sb2coTGV2ZWwuRklORSwgImZvcmNpbmcgZm9sZGVyIHswfSB0byBjbG9zZSIsCisJCQkJCQkJCSAgICBmdWxsTmFtZSk7CisJCSAgICBpZiAocHJvdG9jb2wgIT0gbnVsbCkKKwkJCXByb3RvY29sLmRpc2Nvbm5lY3QoKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCgoSU1BUFN0b3JlKXN0b3JlKS5pc0Nvbm5lY3Rpb25Qb29sRnVsbCgpKSB7CisJCSAgICAvLyBJZiB0aGUgY29ubmVjdGlvbiBwb29sIGlzIGZ1bGwsIGxvZ291dCB0aGUgY29ubmVjdGlvbgorCQkgICAgbG9nZ2VyLmZpbmUoCisJCQkicG9vbCBpcyBmdWxsLCBub3QgYWRkaW5nIGFuIEF1dGhlbnRpY2F0ZWQgY29ubmVjdGlvbiIpOworCisJCSAgICAvLyBJZiB0aGUgZXhwdW5nZSBmbGFnIGlzIHNldCwgY2xvc2UgdGhlIGZvbGRlciBmaXJzdC4KKwkJICAgIGlmIChleHB1bmdlICYmIHByb3RvY29sICE9IG51bGwpCisJCQlwcm90b2NvbC5jbG9zZSgpOworCisJCSAgICBpZiAocHJvdG9jb2wgIT0gbnVsbCkKKwkJCXByb3RvY29sLmxvZ291dCgpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisJCSAgICAvLyBJZiB0aGUgZXhwdW5nZSBmbGFnIGlzIHNldCBvciB3ZSdyZSBvcGVuIHJlYWQtb25seSB3ZQorCQkgICAgLy8gY2FuIGp1c3QgY2xvc2UgdGhlIGZvbGRlciwgb3RoZXJ3aXNlIG9wZW4gaXQgcmVhZC1vbmx5CisJCSAgICAvLyBiZWZvcmUgY2xvc2luZywgb3IgdW5zZWxlY3QgaXQgaWYgc3VwcG9ydGVkLgorICAgICAgICAgICAgICAgICAgICBpZiAoIWV4cHVuZ2UgJiYgbW9kZSA9PSBSRUFEX1dSSVRFKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0cnkgeworCQkJICAgIGlmIChwcm90b2NvbCAhPSBudWxsICYmCisJCQkJICAgIHByb3RvY29sLmhhc0NhcGFiaWxpdHkoIlVOU0VMRUNUIikpCisJCQkJcHJvdG9jb2wudW5zZWxlY3QoKTsKKwkJCSAgICBlbHNlIHsKKwkJCQkvLyBVbnNlbGVjdCBpc24ndCBzdXBwb3J0ZWQgc28gd2UgbmVlZCB0bworCQkJCS8vIHNlbGVjdCBhIGZvbGRlciB0byBjYXVzZSB0aGlzIG9uZSB0byBiZQorCQkJCS8vIGRlc2VsZWN0ZWQgd2l0aG91dCBleHB1bmdpbmcgbWVzc2FnZXMuCisJCQkJLy8gV2UgdHJ5IHRvIGRvIHRoYXQgYnkgcmVvcGVuaW5nIHRoZSBjdXJyZW50CisJCQkJLy8gZm9sZGVyIHJlYWQtb25seS4gIElmIHRoZSBjdXJyZW50IGZvbGRlcgorCQkJCS8vIHdhcyByZW5hbWVkIG91dCBmcm9tIHVuZGVyIHVzLCB0aGUgRVhBTUlORQorCQkJCS8vIG1pZ2h0IGZhaWwsIGJ1dCB0aGF0J3Mgb2sgYmVjYXVzZSBpdCBzdGlsbAorCQkJCS8vIGxlYXZlcyB1cyB3aXRoIHRoZSBmb2xkZXIgZGVzZWxlY3RlZC4KKwkJCQlpZiAocHJvdG9jb2wgIT0gbnVsbCkgeworCQkJCSAgICBib29sZWFuIHNlbGVjdGVkID0gdHJ1ZTsKKwkJCQkgICAgdHJ5IHsKKwkJCQkJcHJvdG9jb2wuZXhhbWluZShmdWxsTmFtZSk7CisJCQkJCS8vIHN1Y2Nlc3MsIGZvbGRlciBzdGlsbCBzZWxlY3RlZAorCQkJCSAgICB9IGNhdGNoIChDb21tYW5kRmFpbGVkRXhjZXB0aW9uIGV4KSB7CisJCQkJCS8vIEVYQU1JTkUgZmFpbGVkLCBmb2xkZXIgaXMgbm8KKwkJCQkJLy8gbG9uZ2VyIHNlbGVjdGVkCisJCQkJCXNlbGVjdGVkID0gZmFsc2U7CisJCQkJICAgIH0KKwkJCQkgICAgaWYgKHNlbGVjdGVkICYmIHByb3RvY29sICE9IG51bGwpCisJCQkJCXByb3RvY29sLmNsb3NlKCk7CisJCQkJfQorCQkJICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFByb3RvY29sRXhjZXB0aW9uIHBleDIpIHsKKwkJCSAgICByZXVzZVByb3RvY29sID0gZmFsc2U7CS8vIHNvbWV0aGluZyB3ZW50IHdyb25nCisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisJCQlpZiAocHJvdG9jb2wgIT0gbnVsbCkKKwkJCSAgICBwcm90b2NvbC5jbG9zZSgpOworCQkgICAgfQorICAgICAgICAgICAgICAgIH0KKwkgICAgfSBjYXRjaCAoUHJvdG9jb2xFeGNlcHRpb24gcGV4KSB7CisJCXRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24ocGV4LmdldE1lc3NhZ2UoKSwgcGV4KTsKKwkgICAgfSBmaW5hbGx5IHsKKwkJLy8gY2xlYW51cCBpZiB3ZSBoYXZlbid0IGFscmVhZHkKKwkJaWYgKG9wZW5lZCkKKwkJICAgIGNsZWFudXAocmV1c2VQcm90b2NvbCk7CisJICAgIH0KKwl9CisgICAgfQorCisgICAgLy8gTk9URTogdGhpcyBtZXRob2QgY2FuIGN1cnJlbnRseSBiZSBpbnZva2VkIGZyb20gY2xvc2UoKSBvcgorICAgIC8vIGZyb20gaGFuZGxlUmVzcG9uc2VzKCkuIEJvdGggaW52b2NhdGlvbnMgYXJlIGNvbmRpdGlvbmFsLAorICAgIC8vIGJhc2VkIG9uIHRoZSAib3BlbmVkIiBmbGFnLCBzbyB3ZSBhcmUgc3VyZSB0aGF0IG11bHRpcGxlCisgICAgLy8gQ29ubmVjdGlvbi5DTE9TRUQgZXZlbnRzIGFyZSBub3QgZ2VuZXJhdGVkLiBBbHNvIGJvdGgKKyAgICAvLyBpbnZvY2F0aW9ucyBhcmUgZnJvbSB3aXRoaW4gbWVzc2FnZUNhY2hlTG9jay1lZCBhcmVhcy4KKyAgICBwcml2YXRlIHZvaWQgY2xlYW51cChib29sZWFuIHJldHVyblRvUG9vbCkgeworCWFzc2VydCBUaHJlYWQuaG9sZHNMb2NrKG1lc3NhZ2VDYWNoZUxvY2spOworICAgICAgICByZWxlYXNlUHJvdG9jb2wocmV0dXJuVG9Qb29sKTsKKwltZXNzYWdlQ2FjaGUgPSBudWxsOworCXVpZFRhYmxlID0gbnVsbDsKKwlleGlzdHMgPSBmYWxzZTsgLy8gdG8gZm9yY2UgYSByZWNoZWNrIGluIGV4aXN0cygpLgorCWF0dHJpYnV0ZXMgPSBudWxsOworICAgICAgICBvcGVuZWQgPSBmYWxzZTsKKwlpZGxlU3RhdGUgPSBSVU5OSU5HOwkvLyBqdXN0IGluIGNhc2UKKwltZXNzYWdlQ2FjaGVMb2NrLm5vdGlmeUFsbCgpOwkvLyB3YWtlIHVwIGFueW9uZSB3YWl0aW5nCisJbm90aWZ5Q29ubmVjdGlvbkxpc3RlbmVycyhDb25uZWN0aW9uRXZlbnQuQ0xPU0VEKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVjayB3aGV0aGVyIHRoaXMgY29ubmVjdGlvbiBpcyByZWFsbHkgb3Blbi4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGJvb2xlYW4gaXNPcGVuKCkgeworCXN5bmNocm9uaXplZChtZXNzYWdlQ2FjaGVMb2NrKSB7CisJICAgIC8vIFByb2JlIHRoZSBjb25uZWN0aW9uIHRvIG1ha2Ugc3VyZSBpdHMgcmVhbGx5IG9wZW4uCisJICAgIGlmIChvcGVuZWQpIHsKKwkJdHJ5IHsKKwkJICAgIGtlZXBDb25uZWN0aW9uQWxpdmUoZmFsc2UpOworCQl9IGNhdGNoIChQcm90b2NvbEV4Y2VwdGlvbiBwZXgpIHsgfQorCSAgICB9CisJfQorCisJcmV0dXJuIG9wZW5lZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIHBlcm1hbmVudCBmbGFncyBzdXBwb3J0ZWQgYnkgdGhlIHNlcnZlci4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIEZsYWdzIGdldFBlcm1hbmVudEZsYWdzKCkgeworCWlmIChwZXJtYW5lbnRGbGFncyA9PSBudWxsKQorCSAgICByZXR1cm4gbnVsbDsKKwlyZXR1cm4gKEZsYWdzKShwZXJtYW5lbnRGbGFncy5jbG9uZSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIHRvdGFsIG1lc3NhZ2UgY291bnQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBpbnQgZ2V0TWVzc2FnZUNvdW50KCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJc3luY2hyb25pemVkIChtZXNzYWdlQ2FjaGVMb2NrKSB7CisJICAgIGlmIChvcGVuZWQpIHsKKwkJLy8gRm9sZGVyIGlzIG9wZW4sIHdlIGtub3cgd2hhdCB0aGUgdG90YWwgbWVzc2FnZSBjb3VudCBpcyAuLgorCQkvLyB0aWNrbGUgdGhlIGZvbGRlciBhbmQgc3RvcmUgY29ubmVjdGlvbnMuCisJCXRyeSB7CisJCSAgICBrZWVwQ29ubmVjdGlvbkFsaXZlKHRydWUpOworCQkgICAgcmV0dXJuIHRvdGFsOworCQl9IGNhdGNoIChDb25uZWN0aW9uRXhjZXB0aW9uIGNleCkgeworCQkgICAgdGhyb3cgbmV3IEZvbGRlckNsb3NlZEV4Y2VwdGlvbih0aGlzLCBjZXguZ2V0TWVzc2FnZSgpKTsKKwkJfSBjYXRjaCAoUHJvdG9jb2xFeGNlcHRpb24gcGV4KSB7CisJCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKHBleC5nZXRNZXNzYWdlKCksIHBleCk7CisJCX0KKwkgICAgfQorCX0KKworCS8vIElmIHRoaXMgZm9sZGVyIGlzIG5vdCB5ZXQgb3Blbiwgd2UgdXNlIFNUQVRVUyB0bworCS8vIGdldCB0aGUgdG90YWwgbWVzc2FnZSBjb3VudAorCWNoZWNrRXhpc3RzKCk7CisJdHJ5IHsKKwkgICAgU3RhdHVzIHN0YXR1cyA9IGdldFN0YXR1cygpOworCSAgICByZXR1cm4gc3RhdHVzLnRvdGFsOworCX0gY2F0Y2ggKEJhZENvbW1hbmRFeGNlcHRpb24gYmV4KSB7CisJICAgIC8vIGRvZXNuJ3Qgc3VwcG9ydCBTVEFUVVMsIHByb2JhYmx5IHZhbmlsbGEgSU1BUDQgLi4KKwkgICAgLy8gbGV0cyB0cnkgRVhBTUlORQorCSAgICBJTUFQUHJvdG9jb2wgcCA9IG51bGw7CisKKwkgICAgdHJ5IHsKKwkJcCA9IGdldFN0b3JlUHJvdG9jb2woKTsJLy8gWFhYCisJCU1haWxib3hJbmZvIG1pbmZvID0gcC5leGFtaW5lKGZ1bGxOYW1lKTsKKwkJcC5jbG9zZSgpOworCQlyZXR1cm4gbWluZm8udG90YWw7CisJICAgIH0gY2F0Y2ggKFByb3RvY29sRXhjZXB0aW9uIHBleCkgeworCQkvLyBHaXZlIHVwLgorCQl0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKHBleC5nZXRNZXNzYWdlKCksIHBleCk7CisJICAgIH0gZmluYWxseSB7CisJCXJlbGVhc2VTdG9yZVByb3RvY29sKHApOworCSAgICB9CisJfSBjYXRjaCAoQ29ubmVjdGlvbkV4Y2VwdGlvbiBjZXgpIHsKKwkgICAgdGhyb3cgbmV3IFN0b3JlQ2xvc2VkRXhjZXB0aW9uKHN0b3JlLCBjZXguZ2V0TWVzc2FnZSgpKTsKKwl9IGNhdGNoIChQcm90b2NvbEV4Y2VwdGlvbiBwZXgpIHsKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbihwZXguZ2V0TWVzc2FnZSgpLCBwZXgpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIG5ldyBtZXNzYWdlIGNvdW50LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IGdldE5ld01lc3NhZ2VDb3VudCgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXN5bmNocm9uaXplZCAobWVzc2FnZUNhY2hlTG9jaykgeworCSAgICBpZiAob3BlbmVkKSB7CisJCS8vIEZvbGRlciBpcyBvcGVuLCB3ZSBrbm93IHdoYXQgdGhlIG5ldyBtZXNzYWdlIGNvdW50IGlzIC4uCisJCS8vIHRpY2tsZSB0aGUgZm9sZGVyIGFuZCBzdG9yZSBjb25uZWN0aW9ucy4KKwkJdHJ5IHsKKwkJICAgIGtlZXBDb25uZWN0aW9uQWxpdmUodHJ1ZSk7CisJCSAgICByZXR1cm4gcmVjZW50OworCQl9IGNhdGNoIChDb25uZWN0aW9uRXhjZXB0aW9uIGNleCkgeworCQkgICAgdGhyb3cgbmV3IEZvbGRlckNsb3NlZEV4Y2VwdGlvbih0aGlzLCBjZXguZ2V0TWVzc2FnZSgpKTsKKwkJfSBjYXRjaCAoUHJvdG9jb2xFeGNlcHRpb24gcGV4KSB7CisJCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKHBleC5nZXRNZXNzYWdlKCksIHBleCk7CisJCX0KKwkgICAgfQorCX0KKworCS8vIElmIHRoaXMgZm9sZGVyIGlzIG5vdCB5ZXQgb3Blbiwgd2UgdXNlIFNUQVRVUyB0bworCS8vIGdldCB0aGUgbmV3IG1lc3NhZ2UgY291bnQKKwljaGVja0V4aXN0cygpOworCXRyeSB7CisJICAgIFN0YXR1cyBzdGF0dXMgPSBnZXRTdGF0dXMoKTsKKwkgICAgcmV0dXJuIHN0YXR1cy5yZWNlbnQ7CisJfSBjYXRjaCAoQmFkQ29tbWFuZEV4Y2VwdGlvbiBiZXgpIHsKKwkgICAgLy8gZG9lc24ndCBzdXBwb3J0IFNUQVRVUywgcHJvYmFibHkgdmFuaWxsYSBJTUFQNCAuLgorCSAgICAvLyBsZXRzIHRyeSBFWEFNSU5FCisJICAgIElNQVBQcm90b2NvbCBwID0gbnVsbDsKKworCSAgICB0cnkgeworCQlwID0gZ2V0U3RvcmVQcm90b2NvbCgpOwkvLyBYWFgKKwkJTWFpbGJveEluZm8gbWluZm8gPSBwLmV4YW1pbmUoZnVsbE5hbWUpOworCQlwLmNsb3NlKCk7CisJCXJldHVybiBtaW5mby5yZWNlbnQ7CisJICAgIH0gY2F0Y2ggKFByb3RvY29sRXhjZXB0aW9uIHBleCkgeworCQkvLyBHaXZlIHVwLgorCQl0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKHBleC5nZXRNZXNzYWdlKCksIHBleCk7CisJICAgIH0gZmluYWxseSB7CisJCXJlbGVhc2VTdG9yZVByb3RvY29sKHApOworCSAgICB9CisJfSBjYXRjaCAoQ29ubmVjdGlvbkV4Y2VwdGlvbiBjZXgpIHsKKwkgICAgdGhyb3cgbmV3IFN0b3JlQ2xvc2VkRXhjZXB0aW9uKHN0b3JlLCBjZXguZ2V0TWVzc2FnZSgpKTsKKwl9IGNhdGNoIChQcm90b2NvbEV4Y2VwdGlvbiBwZXgpIHsKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbihwZXguZ2V0TWVzc2FnZSgpLCBwZXgpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIHVucmVhZCBtZXNzYWdlIGNvdW50LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IGdldFVucmVhZE1lc3NhZ2VDb3VudCgpCisJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpZiAoIW9wZW5lZCkgeworCSAgICBjaGVja0V4aXN0cygpOworCSAgICAvLyBJZiB0aGlzIGZvbGRlciBpcyBub3QgeWV0IG9wZW4sIHdlIHVzZSBTVEFUVVMgdG8KKwkgICAgLy8gZ2V0IHRoZSB1bnNlZW4gbWVzc2FnZSBjb3VudAorCSAgICB0cnkgeworCQlTdGF0dXMgc3RhdHVzID0gZ2V0U3RhdHVzKCk7CisJCXJldHVybiBzdGF0dXMudW5zZWVuOworCSAgICB9IGNhdGNoIChCYWRDb21tYW5kRXhjZXB0aW9uIGJleCkgeworCQkvLyBkb2Vzbid0IHN1cHBvcnQgU1RBVFVTLCBwcm9iYWJseSB2YW5pbGxhIElNQVA0IC4uCisJCS8vIENvdWxkIEVYQU1JTkUsIFNFQVJDSCBmb3IgVU5SRUFEIG1lc3NhZ2VzIGFuZAorCQkvLyByZXR1cm4gdGhlIGNvdW50IC4uIGJhaCwgbm90IHdvcnRoIGl0LgorCQlyZXR1cm4gLTE7CisJICAgIH0gY2F0Y2ggKENvbm5lY3Rpb25FeGNlcHRpb24gY2V4KSB7CisJCXRocm93IG5ldyBTdG9yZUNsb3NlZEV4Y2VwdGlvbihzdG9yZSwgY2V4LmdldE1lc3NhZ2UoKSk7CisJICAgIH0gY2F0Y2ggKFByb3RvY29sRXhjZXB0aW9uIHBleCkgeworCQl0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKHBleC5nZXRNZXNzYWdlKCksIHBleCk7CisJICAgIH0KKwl9CisKKwkvLyBpZiBvcGVuZWQsIGlzc3VlIHNlcnZlci1zaWRlIHNlYXJjaCBmb3IgbWVzc2FnZXMgdGhhdCBkbworCS8vICpub3QqIGhhdmUgdGhlIFNFRU4gZmxhZy4KKwlGbGFncyBmID0gbmV3IEZsYWdzKCk7CisJZi5hZGQoRmxhZ3MuRmxhZy5TRUVOKTsKKwl0cnkgeworCSAgICBzeW5jaHJvbml6ZWQobWVzc2FnZUNhY2hlTG9jaykgeworCQlpbnRbXSBtYXRjaGVzID0gZ2V0UHJvdG9jb2woKS5zZWFyY2gobmV3IEZsYWdUZXJtKGYsIGZhbHNlKSk7CisJCXJldHVybiBtYXRjaGVzLmxlbmd0aDsgLy8gTk9URTogJ21hdGNoZXMnIGlzIG5ldmVyIG51bGwKKwkgICAgfQorCX0gY2F0Y2ggKENvbm5lY3Rpb25FeGNlcHRpb24gY2V4KSB7CisJICAgIHRocm93IG5ldyBGb2xkZXJDbG9zZWRFeGNlcHRpb24odGhpcywgY2V4LmdldE1lc3NhZ2UoKSk7CisJfSBjYXRjaCAoUHJvdG9jb2xFeGNlcHRpb24gcGV4KSB7CisJICAgIC8vIFNob3VsZG4ndCBoYXBwZW4KKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbihwZXguZ2V0TWVzc2FnZSgpLCBwZXgpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGRlbGV0ZWQgbWVzc2FnZSBjb3VudC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCBnZXREZWxldGVkTWVzc2FnZUNvdW50KCkKKwkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWlmICghb3BlbmVkKSB7CisJICAgIGNoZWNrRXhpc3RzKCk7CisJICAgIC8vIG5vIHdheSB0byBkbyB0aGlzIG9uIGNsb3NlZCBmb2xkZXJzCisJICAgIHJldHVybiAtMTsKKwl9CisKKwkvLyBpZiBvcGVuZWQsIGlzc3VlIHNlcnZlci1zaWRlIHNlYXJjaCBmb3IgbWVzc2FnZXMgdGhhdCBkbworCS8vIGhhdmUgdGhlIERFTEVURUQgZmxhZy4KKwlGbGFncyBmID0gbmV3IEZsYWdzKCk7CisJZi5hZGQoRmxhZ3MuRmxhZy5ERUxFVEVEKTsKKwl0cnkgeworCSAgICBzeW5jaHJvbml6ZWQobWVzc2FnZUNhY2hlTG9jaykgeworCQlpbnRbXSBtYXRjaGVzID0gZ2V0UHJvdG9jb2woKS5zZWFyY2gobmV3IEZsYWdUZXJtKGYsIHRydWUpKTsKKwkJcmV0dXJuIG1hdGNoZXMubGVuZ3RoOyAvLyBOT1RFOiAnbWF0Y2hlcycgaXMgbmV2ZXIgbnVsbAorCSAgICB9CisJfSBjYXRjaCAoQ29ubmVjdGlvbkV4Y2VwdGlvbiBjZXgpIHsKKwkgICAgdGhyb3cgbmV3IEZvbGRlckNsb3NlZEV4Y2VwdGlvbih0aGlzLCBjZXguZ2V0TWVzc2FnZSgpKTsKKwl9IGNhdGNoIChQcm90b2NvbEV4Y2VwdGlvbiBwZXgpIHsKKwkgICAgLy8gU2hvdWxkbid0IGhhcHBlbgorCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKHBleC5nZXRNZXNzYWdlKCksIHBleCk7CisJfQorICAgIH0KKworICAgIC8qCisgICAgICogR2V0IHJlc3VsdHMgb2YgU1RBVFVTIGNvbW1hbmQgZm9yIHRoaXMgZm9sZGVyLCBjaGVja2luZyBjYWNoZSBmaXJzdC4KKyAgICAgKiBBU1NFUlQ6IE11c3QgYmUgY2FsbGVkIHdpdGggdGhpcyBmb2xkZXIncyBzeW5jaHJvbml6YXRpb24gbG9jayBoZWxkLgorICAgICAqIEFTU0VSVDogVGhlIGZvbGRlciBtdXN0IGJlIGNsb3NlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0YXR1cyBnZXRTdGF0dXMoKSB0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCWludCBzdGF0dXNDYWNoZVRpbWVvdXQgPSAoKElNQVBTdG9yZSlzdG9yZSkuZ2V0U3RhdHVzQ2FjaGVUaW1lb3V0KCk7CisKKwkvLyBpZiBhbGxvd2VkIHRvIGNhY2hlIGFuZCBvdXIgY2FjaGUgaXMgc3RpbGwgdmFsaWQsIHJldHVybiBpdAorCWlmIChzdGF0dXNDYWNoZVRpbWVvdXQgPiAwICYmIGNhY2hlZFN0YXR1cyAhPSBudWxsICYmCisJICAgIFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpIC0gY2FjaGVkU3RhdHVzVGltZSA8IHN0YXR1c0NhY2hlVGltZW91dCkKKwkgICAgcmV0dXJuIGNhY2hlZFN0YXR1czsKKworICAgICAgICBJTUFQUHJvdG9jb2wgcCA9IG51bGw7CisKKwl0cnkgeworCSAgICBwID0gZ2V0U3RvcmVQcm90b2NvbCgpOwkvLyBYWFgKKwkgICAgU3RhdHVzIHMgPSBwLnN0YXR1cyhmdWxsTmFtZSwgbnVsbCk7IAorCSAgICAvLyBpZiBhbGxvd2VkIHRvIGNhY2hlLCBkbyBzbworCSAgICBpZiAoc3RhdHVzQ2FjaGVUaW1lb3V0ID4gMCkgeworCQljYWNoZWRTdGF0dXMgPSBzOworCQljYWNoZWRTdGF0dXNUaW1lID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisJICAgIH0KKwkgICAgcmV0dXJuIHM7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICByZWxlYXNlU3RvcmVQcm90b2NvbChwKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgc3BlY2lmaWVkIG1lc3NhZ2UuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBNZXNzYWdlIGdldE1lc3NhZ2UoaW50IG1zZ251bSkgCisJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWNoZWNrT3BlbmVkKCk7CisJY2hlY2tSYW5nZShtc2dudW0pOworCisJcmV0dXJuIG1lc3NhZ2VDYWNoZS5nZXRNZXNzYWdlKG1zZ251bSk7CisgICAgfQorCisgICAgLyoqCisgICAgICoge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgTWVzc2FnZVtdIGdldE1lc3NhZ2VzKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJLyoKKwkgKiBOZWVkIHRvIG92ZXJyaWRlIEZvbGRlciBtZXRob2QgdG8gdGhyb3cgRm9sZGVyQ2xvc2VkRXhjZXB0aW9uCisJICogaW5zdGVhZCBvZiBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgbm90IHJlYWxseSBjbG9zZWQuCisJICovCisJY2hlY2tPcGVuZWQoKTsKKwlpbnQgdG90YWwgPSBnZXRNZXNzYWdlQ291bnQoKTsKKwlNZXNzYWdlW10gbXNncyA9IG5ldyBNZXNzYWdlW3RvdGFsXTsKKwlmb3IgKGludCBpID0gMTsgaSA8PSB0b3RhbDsgaSsrKQorCSAgICBtc2dzW2kgLSAxXSA9IG1lc3NhZ2VDYWNoZS5nZXRNZXNzYWdlKGkpOworCXJldHVybiBtc2dzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFwcGVuZCB0aGUgZ2l2ZW4gbWVzc2FnZXMgaW50byB0aGlzIGZvbGRlci4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgYXBwZW5kTWVzc2FnZXMoTWVzc2FnZVtdIG1zZ3MpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJY2hlY2tFeGlzdHMoKTsgLy8gdmVyaWZ5IHRoYXQgc2VsZiBleGlzdHMKKworCS8vIFhYWCAtIGhhdmUgdG8gdmVyaWZ5IHRoYXQgbWVzc2FnZXMgYXJlIGluIGEgZGlmZmVyZW50CisJLy8gc3RvcmUgKGlmIGFueSkgdGhhbiB0YXJnZXQgZm9sZGVyLCBvdGhlcndpc2UgY291bGQKKwkvLyBkZWFkbG9jayB0cnlpbmcgdG8gZmV0Y2ggbWVzc2FnZXMgb24gdGhlIHNhbWUgY29ubmVjdGlvbgorCS8vIHdlJ3JlIHVzaW5nIGZvciB0aGUgYXBwZW5kLgorCisJaW50IG1heHNpemUgPSAoKElNQVBTdG9yZSlzdG9yZSkuZ2V0QXBwZW5kQnVmZmVyU2l6ZSgpOworCisJZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisJICAgIGZpbmFsIE1lc3NhZ2UgbSA9IG1zZ3NbaV07CisJICAgIERhdGUgZCA9IG0uZ2V0UmVjZWl2ZWREYXRlKCk7IC8vIHJldGFpbiBkYXRlcworCSAgICBpZiAoZCA9PSBudWxsKQorCQlkID0gbS5nZXRTZW50RGF0ZSgpOworCSAgICBmaW5hbCBEYXRlIGRkID0gZDsKKwkgICAgZmluYWwgRmxhZ3MgZiA9IG0uZ2V0RmxhZ3MoKTsKKworCSAgICBmaW5hbCBNZXNzYWdlTGl0ZXJhbCBtb3M7CisJICAgIHRyeSB7CisJCS8vIGlmIHdlIGtub3cgdGhlIG1lc3NhZ2UgaXMgdG9vIGJpZywgZG9uJ3QgYnVmZmVyIGFueSBvZiBpdAorCQltb3MgPSBuZXcgTWVzc2FnZUxpdGVyYWwobSwKKwkJCQltLmdldFNpemUoKSA+IG1heHNpemUgPyAwIDogbWF4c2l6ZSk7CisJICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisJCXRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oCisJCQkJIklPRXhjZXB0aW9uIHdoaWxlIGFwcGVuZGluZyBtZXNzYWdlcyIsIGV4KTsKKwkgICAgfSBjYXRjaCAoTWVzc2FnZVJlbW92ZWRFeGNlcHRpb24gbXJleCkgeworCQljb250aW51ZTsgLy8ganVzdCBza2lwIHRoaXMgZXhwdW5nZWQgbWVzc2FnZQorCSAgICB9CisKKwkgICAgZG9Db21tYW5kKG5ldyBQcm90b2NvbENvbW1hbmQoKSB7CisJCUBPdmVycmlkZQorCQlwdWJsaWMgT2JqZWN0IGRvQ29tbWFuZChJTUFQUHJvdG9jb2wgcCkKKwkJCXRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJCSAgICBwLmFwcGVuZChmdWxsTmFtZSwgZiwgZGQsIG1vcyk7CisJCSAgICByZXR1cm4gbnVsbDsKKwkJfQorCSAgICB9KTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogQXBwZW5kIHRoZSBnaXZlbiBtZXNzYWdlcyBpbnRvIHRoaXMgZm9sZGVyLgorICAgICAqIFJldHVybiBhcnJheSBvZiBBcHBlbmRVSUQgb2JqZWN0cyBjb250YWluaW5nCisgICAgICogVUlEcyBvZiB0aGVzZSBtZXNzYWdlcyBpbiB0aGUgZGVzdGluYXRpb24gZm9sZGVyLgorICAgICAqIEVhY2ggZWxlbWVudCBvZiB0aGUgcmV0dXJuZWQgYXJyYXkgY29ycmVzcG9uZHMgdG8KKyAgICAgKiBhbiBlbGVtZW50IG9mIHRoZSA8Y29kZT5tc2dzPC9jb2RlPiBhcnJheS4gIEEgbnVsbAorICAgICAqIGVsZW1lbnQgbWVhbnMgdGhlIHNlcnZlciBkaWRuJ3QgcmV0dXJuIFVJRCBpbmZvcm1hdGlvbgorICAgICAqIGZvciB0aGUgYXBwZW5kZWQgbWVzc2FnZS4gIDxwPgorICAgICAqCisgICAgICogRGVwZW5kcyBvbiB0aGUgQVBQRU5EVUlEIHJlc3BvbnNlIGNvZGUgZGVmaW5lZCBieSB0aGUKKyAgICAgKiBVSURQTFVTIGV4dGVuc2lvbiAtCisgICAgICogPEEgSFJFRj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjNDMxNS50eHQiPlJGQyA0MzE1PC9BPi4KKyAgICAgKgorICAgICAqIEBwYXJhbQltc2dzCXRoZSBtZXNzYWdlcyB0byBhcHBlbmQKKyAgICAgKiBAcmV0dXJuCQlhcnJheSBvZiBBcHBlbmRVSUQgb2JqZWN0cworICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIEFwcGVuZFVJRFtdIGFwcGVuZFVJRE1lc3NhZ2VzKE1lc3NhZ2VbXSBtc2dzKQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWNoZWNrRXhpc3RzKCk7IC8vIHZlcmlmeSB0aGF0IHNlbGYgZXhpc3RzCisKKwkvLyBYWFggLSBoYXZlIHRvIHZlcmlmeSB0aGF0IG1lc3NhZ2VzIGFyZSBpbiBhIGRpZmZlcmVudAorCS8vIHN0b3JlIChpZiBhbnkpIHRoYW4gdGFyZ2V0IGZvbGRlciwgb3RoZXJ3aXNlIGNvdWxkCisJLy8gZGVhZGxvY2sgdHJ5aW5nIHRvIGZldGNoIG1lc3NhZ2VzIG9uIHRoZSBzYW1lIGNvbm5lY3Rpb24KKwkvLyB3ZSdyZSB1c2luZyBmb3IgdGhlIGFwcGVuZC4KKworCWludCBtYXhzaXplID0gKChJTUFQU3RvcmUpc3RvcmUpLmdldEFwcGVuZEJ1ZmZlclNpemUoKTsKKworCUFwcGVuZFVJRFtdIHVpZHMgPSBuZXcgQXBwZW5kVUlEW21zZ3MubGVuZ3RoXTsKKwlmb3IgKGludCBpID0gMDsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspIHsKKwkgICAgZmluYWwgTWVzc2FnZSBtID0gbXNnc1tpXTsKKwkgICAgZmluYWwgTWVzc2FnZUxpdGVyYWwgbW9zOworCisJICAgIHRyeSB7CisJCS8vIGlmIHdlIGtub3cgdGhlIG1lc3NhZ2UgaXMgdG9vIGJpZywgZG9uJ3QgYnVmZmVyIGFueSBvZiBpdAorCQltb3MgPSBuZXcgTWVzc2FnZUxpdGVyYWwobSwKKwkJCQltLmdldFNpemUoKSA+IG1heHNpemUgPyAwIDogbWF4c2l6ZSk7CisJICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisJCXRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oCisJCQkJIklPRXhjZXB0aW9uIHdoaWxlIGFwcGVuZGluZyBtZXNzYWdlcyIsIGV4KTsKKwkgICAgfSBjYXRjaCAoTWVzc2FnZVJlbW92ZWRFeGNlcHRpb24gbXJleCkgeworCQljb250aW51ZTsgLy8ganVzdCBza2lwIHRoaXMgZXhwdW5nZWQgbWVzc2FnZQorCSAgICB9CisKKwkgICAgRGF0ZSBkID0gbS5nZXRSZWNlaXZlZERhdGUoKTsgLy8gcmV0YWluIGRhdGVzCisJICAgIGlmIChkID09IG51bGwpCisJCWQgPSBtLmdldFNlbnREYXRlKCk7CisJICAgIGZpbmFsIERhdGUgZGQgPSBkOworCSAgICBmaW5hbCBGbGFncyBmID0gbS5nZXRGbGFncygpOworCSAgICBBcHBlbmRVSUQgYXVpZCA9IChBcHBlbmRVSUQpZG9Db21tYW5kKG5ldyBQcm90b2NvbENvbW1hbmQoKSB7CisJCUBPdmVycmlkZQorCQlwdWJsaWMgT2JqZWN0IGRvQ29tbWFuZChJTUFQUHJvdG9jb2wgcCkKKwkJCXRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJCSAgICByZXR1cm4gcC5hcHBlbmR1aWQoZnVsbE5hbWUsIGYsIGRkLCBtb3MpOworCQl9CisJICAgIH0pOworCSAgICB1aWRzW2ldID0gYXVpZDsKKwl9CisJcmV0dXJuIHVpZHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXBwZW5kIHRoZSBnaXZlbiBtZXNzYWdlcyBpbnRvIHRoaXMgZm9sZGVyLgorICAgICAqIFJldHVybiBhcnJheSBvZiBNZXNzYWdlIG9iamVjdHMgcmVwcmVzZW50aW5nCisgICAgICogdGhlIG1lc3NhZ2VzIGluIHRoZSBkZXN0aW5hdGlvbiBmb2xkZXIuICBOb3RlCisgICAgICogdGhhdCB0aGUgZm9sZGVyIG11c3QgYmUgb3Blbi4KKyAgICAgKiBFYWNoIGVsZW1lbnQgb2YgdGhlIHJldHVybmVkIGFycmF5IGNvcnJlc3BvbmRzIHRvCisgICAgICogYW4gZWxlbWVudCBvZiB0aGUgPGNvZGU+bXNnczwvY29kZT4gYXJyYXkuICBBIG51bGwKKyAgICAgKiBlbGVtZW50IG1lYW5zIHRoZSBzZXJ2ZXIgZGlkbid0IHJldHVybiBVSUQgaW5mb3JtYXRpb24KKyAgICAgKiBmb3IgdGhlIGFwcGVuZGVkIG1lc3NhZ2UuIDxwPgorICAgICAqCisgICAgICogRGVwZW5kcyBvbiB0aGUgQVBQRU5EVUlEIHJlc3BvbnNlIGNvZGUgZGVmaW5lZCBieSB0aGUKKyAgICAgKiBVSURQTFVTIGV4dGVuc2lvbiAtCisgICAgICogPEEgSFJFRj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjNDMxNS50eHQiPlJGQyA0MzE1PC9BPi4KKyAgICAgKgorICAgICAqIEBwYXJhbQltc2dzCXRoZSBtZXNzYWdlcyB0byBhZGQKKyAgICAgKiBAcmV0dXJuCQl0aGUgbWVzc2FnZXMgaW4gdGhpcyBmb2xkZXIKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS40CisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBNZXNzYWdlW10gYWRkTWVzc2FnZXMoTWVzc2FnZVtdIG1zZ3MpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJY2hlY2tPcGVuZWQoKTsKKwlNZXNzYWdlW10gcm1zZ3MgPSBuZXcgTWltZU1lc3NhZ2VbbXNncy5sZW5ndGhdOworCUFwcGVuZFVJRFtdIHVpZHMgPSBhcHBlbmRVSURNZXNzYWdlcyhtc2dzKTsKKwlmb3IgKGludCBpID0gMDsgaSA8IHVpZHMubGVuZ3RoOyBpKyspIHsKKwkgICAgQXBwZW5kVUlEIGF1aWQgPSB1aWRzW2ldOworCSAgICBpZiAoYXVpZCAhPSBudWxsKSB7CisJCWlmIChhdWlkLnVpZHZhbGlkaXR5ID09IHVpZHZhbGlkaXR5KSB7CisJCSAgICB0cnkgeworCQkJcm1zZ3NbaV0gPSBnZXRNZXNzYWdlQnlVSUQoYXVpZC51aWQpOworCQkgICAgfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIG1leCkgeworCQkJLy8gaWdub3JlIGVycm9ycyBhdCB0aGlzIHN0YWdlCisJCSAgICB9CisJCX0KKwkgICAgfQorCX0KKwlyZXR1cm4gcm1zZ3M7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29weSB0aGUgc3BlY2lmaWVkIG1lc3NhZ2VzIGZyb20gdGhpcyBmb2xkZXIsIHRvIHRoZQorICAgICAqIHNwZWNpZmllZCBkZXN0aW5hdGlvbi4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgY29weU1lc3NhZ2VzKE1lc3NhZ2VbXSBtc2dzLCBGb2xkZXIgZm9sZGVyKQorCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJY29weW1vdmVNZXNzYWdlcyhtc2dzLCBmb2xkZXIsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb3B5IHRoZSBzcGVjaWZpZWQgbWVzc2FnZXMgZnJvbSB0aGlzIGZvbGRlciwgdG8gdGhlCisgICAgICogc3BlY2lmaWVkIGRlc3RpbmF0aW9uLgorICAgICAqIFJldHVybiBhcnJheSBvZiBBcHBlbmRVSUQgb2JqZWN0cyBjb250YWluaW5nCisgICAgICogVUlEcyBvZiB0aGVzZSBtZXNzYWdlcyBpbiB0aGUgZGVzdGluYXRpb24gZm9sZGVyLgorICAgICAqIEVhY2ggZWxlbWVudCBvZiB0aGUgcmV0dXJuZWQgYXJyYXkgY29ycmVzcG9uZHMgdG8KKyAgICAgKiBhbiBlbGVtZW50IG9mIHRoZSA8Y29kZT5tc2dzPC9jb2RlPiBhcnJheS4gIEEgbnVsbAorICAgICAqIGVsZW1lbnQgbWVhbnMgdGhlIHNlcnZlciBkaWRuJ3QgcmV0dXJuIFVJRCBpbmZvcm1hdGlvbgorICAgICAqIGZvciB0aGUgY29waWVkIG1lc3NhZ2UuICA8cD4KKyAgICAgKgorICAgICAqIERlcGVuZHMgb24gdGhlIENPUFlVSUQgcmVzcG9uc2UgY29kZSBkZWZpbmVkIGJ5IHRoZQorICAgICAqIFVJRFBMVVMgZXh0ZW5zaW9uIC0KKyAgICAgKiA8QSBIUkVGPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmM0MzE1LnR4dCI+UkZDIDQzMTU8L0E+LgorICAgICAqCisgICAgICogQHBhcmFtCW1zZ3MJdGhlIG1lc3NhZ2VzIHRvIGNvcHkKKyAgICAgKiBAcGFyYW0JZm9sZGVyCXRoZSBmb2xkZXIgdG8gY29weSB0aGUgbWVzc2FnZXMgdG8KKyAgICAgKiBAcmV0dXJuCQlhcnJheSBvZiBBcHBlbmRVSUQgb2JqZWN0cworICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjUuMQorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgQXBwZW5kVUlEW10gY29weVVJRE1lc3NhZ2VzKE1lc3NhZ2VbXSBtc2dzLAorCQkJRm9sZGVyIGZvbGRlcikgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJcmV0dXJuIGNvcHltb3ZlVUlETWVzc2FnZXMobXNncywgZm9sZGVyLCBmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTW92ZSB0aGUgc3BlY2lmaWVkIG1lc3NhZ2VzIGZyb20gdGhpcyBmb2xkZXIsIHRvIHRoZQorICAgICAqIHNwZWNpZmllZCBkZXN0aW5hdGlvbi4KKyAgICAgKgorICAgICAqIERlcGVuZHMgb24gdGhlIE1PVkUgZXh0ZW5zaW9uCisgICAgICogKDxBIEhSRUY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzY4NTEudHh0Ij5SRkMgNjg1MTwvQT4pLgorICAgICAqCisgICAgICogQHBhcmFtCW1zZ3MJdGhlIG1lc3NhZ2VzIHRvIG1vdmUKKyAgICAgKiBAcGFyYW0JZm9sZGVyCXRoZSBmb2xkZXIgdG8gbW92ZSB0aGUgbWVzc2FnZXMgdG8KKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKgorICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjUuNAorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBtb3ZlTWVzc2FnZXMoTWVzc2FnZVtdIG1zZ3MsIEZvbGRlciBmb2xkZXIpCisJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwljb3B5bW92ZU1lc3NhZ2VzKG1zZ3MsIGZvbGRlciwgdHJ1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTW92ZSB0aGUgc3BlY2lmaWVkIG1lc3NhZ2VzIGZyb20gdGhpcyBmb2xkZXIsIHRvIHRoZQorICAgICAqIHNwZWNpZmllZCBkZXN0aW5hdGlvbi4KKyAgICAgKiBSZXR1cm4gYXJyYXkgb2YgQXBwZW5kVUlEIG9iamVjdHMgY29udGFpbmluZworICAgICAqIFVJRHMgb2YgdGhlc2UgbWVzc2FnZXMgaW4gdGhlIGRlc3RpbmF0aW9uIGZvbGRlci4KKyAgICAgKiBFYWNoIGVsZW1lbnQgb2YgdGhlIHJldHVybmVkIGFycmF5IGNvcnJlc3BvbmRzIHRvCisgICAgICogYW4gZWxlbWVudCBvZiB0aGUgPGNvZGU+bXNnczwvY29kZT4gYXJyYXkuICBBIG51bGwKKyAgICAgKiBlbGVtZW50IG1lYW5zIHRoZSBzZXJ2ZXIgZGlkbid0IHJldHVybiBVSUQgaW5mb3JtYXRpb24KKyAgICAgKiBmb3IgdGhlIG1vdmVkIG1lc3NhZ2UuICA8cD4KKyAgICAgKgorICAgICAqIERlcGVuZHMgb24gdGhlIE1PVkUgZXh0ZW5zaW9uCisgICAgICogKDxBIEhSRUY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzY4NTEudHh0Ij5SRkMgNjg1MTwvQT4pCisgICAgICogYW5kIHRoZSBDT1BZVUlEIHJlc3BvbnNlIGNvZGUgZGVmaW5lZCBieSB0aGUKKyAgICAgKiBVSURQTFVTIGV4dGVuc2lvbgorICAgICAqICg8QSBIUkVGPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmM0MzE1LnR4dCI+UkZDIDQzMTU8L0E+KS4KKyAgICAgKgorICAgICAqIEBwYXJhbQltc2dzCXRoZSBtZXNzYWdlcyB0byBtb3ZlCisgICAgICogQHBhcmFtCWZvbGRlcgl0aGUgZm9sZGVyIHRvIG1vdmUgdGhlIG1lc3NhZ2VzIHRvCisgICAgICogQHJldHVybgkJYXJyYXkgb2YgQXBwZW5kVUlEIG9iamVjdHMKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS41LjQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIEFwcGVuZFVJRFtdIG1vdmVVSURNZXNzYWdlcyhNZXNzYWdlW10gbXNncywKKwkJCUZvbGRlciBmb2xkZXIpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXJldHVybiBjb3B5bW92ZVVJRE1lc3NhZ2VzKG1zZ3MsIGZvbGRlciwgdHJ1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29weSBvciBtb3ZlIHRoZSBzcGVjaWZpZWQgbWVzc2FnZXMgZnJvbSB0aGlzIGZvbGRlciwgdG8gdGhlCisgICAgICogc3BlY2lmaWVkIGRlc3RpbmF0aW9uLgorICAgICAqCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNS40CisgICAgICovCisgICAgcHJpdmF0ZSBzeW5jaHJvbml6ZWQgdm9pZCBjb3B5bW92ZU1lc3NhZ2VzKE1lc3NhZ2VbXSBtc2dzLCBGb2xkZXIgZm9sZGVyLAorCQkJYm9vbGVhbiBtb3ZlKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwljaGVja09wZW5lZCgpOworCisJaWYgKG1zZ3MubGVuZ3RoID09IDApIC8vIGJvdW5kYXJ5IGNvbmRpdGlvbgorCSAgICByZXR1cm47CisKKwkvLyBJZiB0aGUgZGVzdGluYXRpb24gYmVsb25ncyB0byBvdXIgc2FtZSBzdG9yZSwgb3B0aW1pemUKKwlpZiAoZm9sZGVyLmdldFN0b3JlKCkgPT0gc3RvcmUpIHsKKwkgICAgc3luY2hyb25pemVkKG1lc3NhZ2VDYWNoZUxvY2spIHsKKwkJdHJ5IHsKKwkJICAgIElNQVBQcm90b2NvbCBwID0gZ2V0UHJvdG9jb2woKTsKKwkJICAgIE1lc3NhZ2VTZXRbXSBtcyA9IFV0aWxpdHkudG9NZXNzYWdlU2V0KG1zZ3MsIG51bGwpOworCQkgICAgaWYgKG1zID09IG51bGwpCisJCQl0aHJvdyBuZXcgTWVzc2FnZVJlbW92ZWRFeGNlcHRpb24oCisJCQkJCSJNZXNzYWdlcyBoYXZlIGJlZW4gcmVtb3ZlZCIpOworCQkgICAgaWYgKG1vdmUpCisJCQlwLm1vdmUobXMsIGZvbGRlci5nZXRGdWxsTmFtZSgpKTsKKwkJICAgIGVsc2UKKwkJCXAuY29weShtcywgZm9sZGVyLmdldEZ1bGxOYW1lKCkpOworCQl9IGNhdGNoIChDb21tYW5kRmFpbGVkRXhjZXB0aW9uIGNmeCkgeworCQkgICAgaWYgKGNmeC5nZXRNZXNzYWdlKCkuaW5kZXhPZigiVFJZQ1JFQVRFIikgIT0gLTEpCisJCQl0aHJvdyBuZXcgRm9sZGVyTm90Rm91bmRFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9sZGVyLAorCQkJICAgIGZvbGRlci5nZXRGdWxsTmFtZSgpICsgIiBkb2VzIG5vdCBleGlzdCIKKwkJCSAgICk7CisJCSAgICBlbHNlIAorCQkJdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbihjZnguZ2V0TWVzc2FnZSgpLCBjZngpOworCQl9IGNhdGNoIChDb25uZWN0aW9uRXhjZXB0aW9uIGNleCkgeworCQkgICAgdGhyb3cgbmV3IEZvbGRlckNsb3NlZEV4Y2VwdGlvbih0aGlzLCBjZXguZ2V0TWVzc2FnZSgpKTsKKwkJfSBjYXRjaCAoUHJvdG9jb2xFeGNlcHRpb24gcGV4KSB7CisJCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKHBleC5nZXRNZXNzYWdlKCksIHBleCk7CisJICAgIAl9CisJICAgIH0KKwl9IGVsc2UgLy8gZGVzdGluYXRpb24gaXMgYSBkaWZmZXJlbnQgc3RvcmUuCisJICAgIGlmIChtb3ZlKQorCQl0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKAorCQkJCQkiTW92ZSBiZXR3ZWVuIHN0b3JlcyBub3Qgc3VwcG9ydGVkIik7CisJICAgIGVsc2UKKwkJc3VwZXIuY29weU1lc3NhZ2VzKG1zZ3MsIGZvbGRlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29weSBvciBtb3ZlIHRoZSBzcGVjaWZpZWQgbWVzc2FnZXMgZnJvbSB0aGlzIGZvbGRlciwgdG8gdGhlCisgICAgICogc3BlY2lmaWVkIGRlc3RpbmF0aW9uLgorICAgICAqIFJldHVybiBhcnJheSBvZiBBcHBlbmRVSUQgb2JqZWN0cyBjb250YWluaW5nCisgICAgICogVUlEcyBvZiB0aGVzZSBtZXNzYWdlcyBpbiB0aGUgZGVzdGluYXRpb24gZm9sZGVyLgorICAgICAqIEVhY2ggZWxlbWVudCBvZiB0aGUgcmV0dXJuZWQgYXJyYXkgY29ycmVzcG9uZHMgdG8KKyAgICAgKiBhbiBlbGVtZW50IG9mIHRoZSA8Y29kZT5tc2dzPC9jb2RlPiBhcnJheS4gIEEgbnVsbAorICAgICAqIGVsZW1lbnQgbWVhbnMgdGhlIHNlcnZlciBkaWRuJ3QgcmV0dXJuIFVJRCBpbmZvcm1hdGlvbgorICAgICAqIGZvciB0aGUgY29waWVkIG1lc3NhZ2UuICA8cD4KKyAgICAgKgorICAgICAqIERlcGVuZHMgb24gdGhlIENPUFlVSUQgcmVzcG9uc2UgY29kZSBkZWZpbmVkIGJ5IHRoZQorICAgICAqIFVJRFBMVVMgZXh0ZW5zaW9uIC0KKyAgICAgKiA8QSBIUkVGPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmM0MzE1LnR4dCI+UkZDIDQzMTU8L0E+LgorICAgICAqIE1vdmUgZGVwZW5kcyBvbiB0aGUgTU9WRSBleHRlbnNpb24gLQorICAgICAqIDxBIEhSRUY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzY4NTEudHh0Ij5SRkMgNjg1MTwvQT4uCisgICAgICoKKyAgICAgKiBAcGFyYW0JbXNncwl0aGUgbWVzc2FnZXMgdG8gY29weQorICAgICAqIEBwYXJhbQlmb2xkZXIJdGhlIGZvbGRlciB0byBjb3B5IHRoZSBtZXNzYWdlcyB0bworICAgICAqIEBwYXJhbQltb3ZlCW1vdmUgaW5zdGVhZCBvZiBjb3B5PworICAgICAqIEByZXR1cm4JCWFycmF5IG9mIEFwcGVuZFVJRCBvYmplY3RzCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNS40CisgICAgICovCisgICAgcHJpdmF0ZSBzeW5jaHJvbml6ZWQgQXBwZW5kVUlEW10gY29weW1vdmVVSURNZXNzYWdlcyhNZXNzYWdlW10gbXNncywKKwkJCUZvbGRlciBmb2xkZXIsIGJvb2xlYW4gbW92ZSkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJY2hlY2tPcGVuZWQoKTsKKworCWlmIChtc2dzLmxlbmd0aCA9PSAwKSAvLyBib3VuZGFyeSBjb25kaXRpb24KKwkgICAgcmV0dXJuIG51bGw7CisKKwkvLyB0aGUgZGVzdGluYXRpb24gbXVzdCBiZWxvbmcgdG8gb3VyIHNhbWUgc3RvcmUKKwlpZiAoZm9sZGVyLmdldFN0b3JlKCkgIT0gc3RvcmUpIC8vIGRlc3RpbmF0aW9uIGlzIGEgZGlmZmVyZW50IHN0b3JlLgorCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKAorCQkJbW92ZSA/CisJCQkiY2FuJ3QgbW92ZVVJRE1lc3NhZ2VzIHRvIGEgZGlmZmVyZW50IHN0b3JlIiA6CisJCQkiY2FuJ3QgY29weVVJRE1lc3NhZ2VzIHRvIGEgZGlmZmVyZW50IHN0b3JlIik7CisKKwkvLyBjYWxsIGZldGNoIHRvIG1ha2Ugc3VyZSB3ZSBoYXZlIGFsbCB0aGUgVUlEcworCS8vIG5lY2Vzc2FyeSB0byBpbnRlcnByZXQgdGhlIENPUFlVSUQgcmVzcG9uc2UKKwlGZXRjaFByb2ZpbGUgZnAgPSBuZXcgRmV0Y2hQcm9maWxlKCk7CisJZnAuYWRkKFVJREZvbGRlci5GZXRjaFByb2ZpbGVJdGVtLlVJRCk7CisJZmV0Y2gobXNncywgZnApOworCS8vIFhYWCAtIGNvdWxkIHBpcGVsaW5lIHRoZSBGRVRDSCB3aXRoIHRoZSBDT1BZL01PVkUgYmVsb3cKKworCXN5bmNocm9uaXplZCAobWVzc2FnZUNhY2hlTG9jaykgeworCSAgICB0cnkgeworCQlJTUFQUHJvdG9jb2wgcCA9IGdldFByb3RvY29sKCk7CisJCS8vIFhYWCAtIG1lc3NhZ2VzIGhhdmUgdG8gYmUgZnJvbSB0aGlzIEZvbGRlciwgd2hvIGNoZWNrcz8KKwkJTWVzc2FnZVNldFtdIG1zID0gVXRpbGl0eS50b01lc3NhZ2VTZXQobXNncywgbnVsbCk7CisJCWlmIChtcyA9PSBudWxsKQorCQkgICAgdGhyb3cgbmV3IE1lc3NhZ2VSZW1vdmVkRXhjZXB0aW9uKAorCQkJCSAgICAiTWVzc2FnZXMgaGF2ZSBiZWVuIHJlbW92ZWQiKTsKKwkJQ29weVVJRCBjdWlkOworCQlpZiAobW92ZSkKKwkJICAgIGN1aWQgPSBwLm1vdmV1aWQobXMsIGZvbGRlci5nZXRGdWxsTmFtZSgpKTsKKwkJZWxzZQorCQkgICAgY3VpZCA9IHAuY29weXVpZChtcywgZm9sZGVyLmdldEZ1bGxOYW1lKCkpOworCisJCS8qCisJCSAqIENvcnJlbGF0ZSBzb3VyY2UgVUlEcyB3aXRoIGRlc3RpbmF0aW9uIFVJRHMuCisJCSAqIFRoaXMgd29uJ3QgYmUgdGltZSBvciBzcGFjZSBlZmZpY2llbnQgaWYgdGhlcmUncworCQkgKiBhIGxvdCBvZiBtZXNzYWdlcy4KKwkJICoKKwkJICogSW4gb3JkZXIgdG8gbWFrZSBzZW5zZSBvZiB0aGUgcmV0dXJuZWQgVUlEcywgd2UgbmVlZAorCQkgKiB0aGUgVUlEcyBmb3IgZXZlcnkgb25lIG9mIHRoZSBvcmlnaW5hbCBtZXNzYWdlcy4KKwkJICogV2UgZmV0Y2ggdGhlbSBhYm92ZSwgdG8gbWFrZSBzdXJlIHdlIGhhdmUgdGhlbS4KKwkJICogVGhpcyBpcyBjcml0aWNhbCBmb3IgTU9WRSBzaW5jZSBhZnRlciB0aGUgTU9WRSB0aGUKKwkJICogbWVzc2FnZXMgYXJlIGdvbmUvZXhwdW5nZWQuCisJCSAqCisJCSAqIEFzc3VtZSB0aGUgY29tbW9uIGNhc2UgaXMgdGhhdCB0aGUgbWVzc2FnZXMgYXJlCisJCSAqIGluIG9yZGVyIGJ5IFVJRC4gIE1hcCB0aGUgcmV0dXJuZWQgc291cmNlCisJCSAqIFVJRHMgdG8gdGhlaXIgY29ycmVzcG9uZGluZyBNZXNzYWdlIG9iamVjdHMuCisJCSAqIFN0ZXAgdGhyb3VnaCB0aGUgbXNncyBhcnJheSBsb29raW5nIGZvciB0aGUKKwkJICogTWVzc2FnZSBvYmplY3QgaW4gdGhlIHJldHVybmVkIHNvdXJjZSBtZXNzYWdlCisJCSAqIGxpc3QuICBNb3N0IGNvbW1vbmx5IHRoZSBzb3VyY2UgbWVzc2FnZSAoVUlEKQorCQkgKiBmb3IgdGhlIE50aCBvcmlnaW5hbCBtZXNzYWdlIHdpbGwgYmUgaW4gdGhlIE50aAorCQkgKiBwb3NpdGlvbiBpbiB0aGUgcmV0dXJuZWQgc291cmNlIG1lc3NhZ2UgKFVJRCkKKwkJICogbGlzdC4gIFRodXMsIHRoZSBkZXN0aW5hdGlvbiBVSUQgaXMgaW4gdGhlIE50aAorCQkgKiBwb3NpdGlvbiBpbiB0aGUgcmV0dXJuZWQgZGVzdGluYXRpb24gVUlEIGxpc3QuCisJCSAqIEJ1dCBpZiB0aGUgc291cmNlIG1lc3NhZ2UgaXNuJ3Qgd2hlcmUgZXhwZWN0ZWQsCisJCSAqIHdlIGhhdmUgdG8gc2VhcmNoIHRoZSBlbnRpcmUgc291cmNlIG1lc3NhZ2UKKwkJICogbGlzdCwgc3RhcnRpbmcgZnJvbSB3aGVyZSB3ZSBleHBlY3QgaXQgYW5kCisJCSAqIHdyYXBwaW5nIGFyb3VuZCB1bnRpbCB3ZSd2ZSBzZWFyY2hlZCBpdCBhbGwuCisJCSAqIChHbWFpbCB3aWxsIG9mdGVuIHJldHVybiB0aGUgbGlzdHMgaW4gYW4gdW5leHBlY3RlZCBvcmRlci4pCisJCSAqCisJCSAqIEEgcG9zc2libGUgb3B0aW1pemF0aW9uOgorCQkgKiBJZiB0aGUgbnVtYmVyIG9mIFVJRHMgcmV0dXJuZWQgaXMgdGhlIHNhbWUgYXMgdGhlCisJCSAqIG51bWJlciBvZiBtZXNzYWdlcyBiZWluZyBjb3BpZWQvbW92ZWQsIHdlIGNvdWxkCisJCSAqIHNvcnQgdGhlIHNvdXJjZSBtZXNzYWdlcyBieSBtZXNzYWdlIG51bWJlciwgc29ydAorCQkgKiB0aGUgc291cmNlIGFuZCBkZXN0aW5hdGlvbiBwYXJhbGxlbCBhcnJheXMgYnkgc291cmNlCisJCSAqIFVJRCwgYW5kIHRoZSByZXN1bHRpbmcgbWVzc2FnZSBhbmQgZGVzdGluYXRpb24gVUlECisJCSAqIGFycmF5cyB3aWxsIGNvcnJlc3BvbmQuCisJCSAqCisJCSAqIElmIHRoZSByZXR1cm5lZCBVSUQgYXJyYXkgc2l6ZSBpcyBkaWZmZXJlbnQsIHNvbWUKKwkJICogbWVzc2FnZSB3YXMgZXhwdW5nZWQgd2hpbGUgd2Ugd2VyZSB0cnlpbmcgdG8gY29weS9tb3ZlIGl0LgorCQkgKiBUaGlzIHNob3VsZCBiZSByYXJlIGJ1dCB3b3VsZCBtZWFuIGZhbGxpbmcgYmFjayB0byB0aGUKKwkJICogZ2VuZXJhbCBhbGdvcml0aG0uCisJCSAqLworCQlsb25nW10gc3JjdWlkcyA9IFVJRFNldC50b0FycmF5KGN1aWQuc3JjKTsKKwkJbG9uZ1tdIGRzdHVpZHMgPSBVSURTZXQudG9BcnJheShjdWlkLmRzdCk7CisJCS8vIG1hcCBzb3VyY2UgVUlEcyB0byBNZXNzYWdlIG9iamVjdHMKKwkJLy8gWFhYIC0gY291bGQgaW5saW5lL29wdGltaXplIHRoaXMKKwkJTWVzc2FnZVtdIHNyY21zZ3MgPSBnZXRNZXNzYWdlc0J5VUlEKHNyY3VpZHMpOworCQlBcHBlbmRVSURbXSByZXN1bHQgPSBuZXcgQXBwZW5kVUlEW21zZ3MubGVuZ3RoXTsKKwkJZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisJCSAgICBpbnQgaiA9IGk7CisJCSAgICBkbyB7CisJCQlpZiAobXNnc1tpXSA9PSBzcmNtc2dzW2pdKSB7CisJCQkgICAgcmVzdWx0W2ldID0gbmV3IEFwcGVuZFVJRCgKKwkJCQkJICAgIGN1aWQudWlkdmFsaWRpdHksIGRzdHVpZHNbal0pOworCQkJICAgIGJyZWFrOworCQkJfQorCQkJaisrOworCQkJaWYgKGogPj0gc3JjbXNncy5sZW5ndGgpCisJCQkgICAgaiA9IDA7CisJCSAgICB9IHdoaWxlIChqICE9IGkpOworCQl9CisJCXJldHVybiByZXN1bHQ7CisJICAgIH0gY2F0Y2ggKENvbW1hbmRGYWlsZWRFeGNlcHRpb24gY2Z4KSB7CisJCWlmIChjZnguZ2V0TWVzc2FnZSgpLmluZGV4T2YoIlRSWUNSRUFURSIpICE9IC0xKQorCQkgICAgdGhyb3cgbmV3IEZvbGRlck5vdEZvdW5kRXhjZXB0aW9uKAorCQkJZm9sZGVyLAorCQkJZm9sZGVyLmdldEZ1bGxOYW1lKCkgKyAiIGRvZXMgbm90IGV4aXN0IgorCQkgICAgICAgKTsKKwkJZWxzZSAKKwkJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oY2Z4LmdldE1lc3NhZ2UoKSwgY2Z4KTsKKwkgICAgfSBjYXRjaCAoQ29ubmVjdGlvbkV4Y2VwdGlvbiBjZXgpIHsKKwkJdGhyb3cgbmV3IEZvbGRlckNsb3NlZEV4Y2VwdGlvbih0aGlzLCBjZXguZ2V0TWVzc2FnZSgpKTsKKwkgICAgfSBjYXRjaCAoUHJvdG9jb2xFeGNlcHRpb24gcGV4KSB7CisJCXRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24ocGV4LmdldE1lc3NhZ2UoKSwgcGV4KTsKKwkgICAgfQorCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFeHB1bmdlIGFsbCBtZXNzYWdlcyBtYXJrZWQgYXMgREVMRVRFRC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIE1lc3NhZ2VbXSBleHB1bmdlKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJcmV0dXJuIGV4cHVuZ2UobnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXhwdW5nZSB0aGUgaW5kaWNhdGVkIG1lc3NhZ2VzLCB3aGljaCBtdXN0IGhhdmUgYmVlbiBtYXJrZWQgYXMgREVMRVRFRC4KKyAgICAgKgorICAgICAqIERlcGVuZHMgb24gdGhlIFVJRFBMVVMgZXh0ZW5zaW9uIC0KKyAgICAgKiA8QSBIUkVGPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmM0MzE1LnR4dCI+UkZDIDQzMTU8L0E+LgorICAgICAqCisgICAgICogQHBhcmFtCW1zZ3MJdGhlIG1lc3NhZ2VzIHRvIGV4cHVuZ2UKKyAgICAgKiBAcmV0dXJuCQl0aGUgZXhwdW5nZWQgbWVzc2FnZXMKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIE1lc3NhZ2VbXSBleHB1bmdlKE1lc3NhZ2VbXSBtc2dzKQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWNoZWNrT3BlbmVkKCk7CisKKwlpZiAobXNncyAhPSBudWxsKSB7CisJICAgIC8vIGNhbGwgZmV0Y2ggdG8gbWFrZSBzdXJlIHdlIGhhdmUgYWxsIHRoZSBVSURzCisJICAgIEZldGNoUHJvZmlsZSBmcCA9IG5ldyBGZXRjaFByb2ZpbGUoKTsKKwkgICAgZnAuYWRkKFVJREZvbGRlci5GZXRjaFByb2ZpbGVJdGVtLlVJRCk7CisJICAgIGZldGNoKG1zZ3MsIGZwKTsKKwl9CisKKwlJTUFQTWVzc2FnZVtdIHJtc2dzOworCXN5bmNocm9uaXplZChtZXNzYWdlQ2FjaGVMb2NrKSB7CisJICAgIGRvRXhwdW5nZU5vdGlmaWNhdGlvbiA9IGZhbHNlOyAvLyBXZSBkbyB0aGlzIG91cnNlbHZlcyBsYXRlcgorCSAgICB0cnkgeworCQlJTUFQUHJvdG9jb2wgcCA9IGdldFByb3RvY29sKCk7CisJCWlmIChtc2dzICE9IG51bGwpCisJCSAgICBwLnVpZGV4cHVuZ2UoVXRpbGl0eS50b1VJRFNldChtc2dzKSk7CisJCWVsc2UKKwkJICAgIHAuZXhwdW5nZSgpOworCSAgICB9IGNhdGNoIChDb21tYW5kRmFpbGVkRXhjZXB0aW9uIGNmeCkgeworCQkvLyBleHB1bmdlIG5vdCBhbGxvd2VkLCBwZXJoYXBzIGR1ZSB0byBhIHBlcm1pc3Npb24gcHJvYmxlbT8KKwkJaWYgKG1vZGUgIT0gUkVBRF9XUklURSkKKwkJICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oCisJCQkiQ2Fubm90IGV4cHVuZ2UgUkVBRF9PTkxZIGZvbGRlcjogIiArIGZ1bGxOYW1lKTsKKwkJZWxzZQorCQkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbihjZnguZ2V0TWVzc2FnZSgpLCBjZngpOworCSAgICB9IGNhdGNoIChDb25uZWN0aW9uRXhjZXB0aW9uIGNleCkgeworCQl0aHJvdyBuZXcgRm9sZGVyQ2xvc2VkRXhjZXB0aW9uKHRoaXMsIGNleC5nZXRNZXNzYWdlKCkpOworCSAgICB9IGNhdGNoIChQcm90b2NvbEV4Y2VwdGlvbiBwZXgpIHsKKwkJLy8gQmFkIGJhZCBzZXJ2ZXIgLi4KKwkJdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbihwZXguZ2V0TWVzc2FnZSgpLCBwZXgpOworCSAgICB9IGZpbmFsbHkgeworCQlkb0V4cHVuZ2VOb3RpZmljYXRpb24gPSB0cnVlOworCSAgICB9CisKKwkgICAgLy8gQ2xlYW51cCBleHB1bmdlZCBtZXNzYWdlcyBhbmQgc3luYyBtZXNzYWdlQ2FjaGUgd2l0aCByZWFsaXR5LgorCSAgICBpZiAobXNncyAhPSBudWxsKQorCQlybXNncyA9IG1lc3NhZ2VDYWNoZS5yZW1vdmVFeHB1bmdlZE1lc3NhZ2VzKG1zZ3MpOworCSAgICBlbHNlCisJCXJtc2dzID0gbWVzc2FnZUNhY2hlLnJlbW92ZUV4cHVuZ2VkTWVzc2FnZXMoKTsKKwkgICAgaWYgKHVpZFRhYmxlICE9IG51bGwpIHsKKwkJZm9yIChpbnQgaSA9IDA7IGkgPCBybXNncy5sZW5ndGg7IGkrKykgeworCQkgICAgSU1BUE1lc3NhZ2UgbSA9IHJtc2dzW2ldOworCQkgICAgLyogcmVtb3ZlIHRoaXMgbWVzc2FnZSBmcm9tIHRoZSBVSURUYWJsZSAqLworCQkgICAgbG9uZyB1aWQgPSBtLmdldFVJRCgpOworCQkgICAgaWYgKHVpZCAhPSAtMSkKKwkJCXVpZFRhYmxlLnJlbW92ZShMb25nLnZhbHVlT2YodWlkKSk7CisJCX0KKwkgICAgfQorCisJICAgIC8vIFVwZGF0ZSAndG90YWwnCisJICAgIHRvdGFsID0gbWVzc2FnZUNhY2hlLnNpemUoKTsKKwl9CisKKwkvLyBOb3RpZnkgbGlzdGVuZXJzLiBUaGlzIHRpbWUgaXRzIGZvciByZWFsLCBndXlzLgorCWlmIChybXNncy5sZW5ndGggPiAwKQorCSAgICBub3RpZnlNZXNzYWdlUmVtb3ZlZExpc3RlbmVycyh0cnVlLCBybXNncyk7CisJcmV0dXJuIHJtc2dzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNlYXJjaCB3aG9sZSBmb2xkZXIgZm9yIG1lc3NhZ2VzIG1hdGNoaW5nIHRoZSBnaXZlbiB0ZXJtLgorICAgICAqIElmIHRoZSBwcm9wZXJ0eSA8Y29kZT5tYWlsLmltYXAudGhyb3dzZWFyY2hleGNlcHRpb248L2NvZGU+IGlzIHRydWUsCisgICAgICogYW5kIHRoZSBzZWFyY2ggdGVybSBpcyB0b28gY29tcGxleCBmb3IgdGhlIElNQVAgcHJvdG9jb2wsCisgICAgICogU2VhcmNoRXhjZXB0aW9uIGlzIHRocm93bi4gIE90aGVyd2lzZSwgaWYgdGhlIHNlYXJjaCB0ZXJtIGlzIHRvbworICAgICAqIGNvbXBsZXgsIDxjb2RlPnN1cGVyLnNlYXJjaDwvY29kZT4gaXMgY2FsbGVkIHRvIGRvIHRoZSBzZWFyY2ggb24KKyAgICAgKiB0aGUgY2xpZW50LgorICAgICAqCisgICAgICogQHBhcmFtCXRlcm0JdGhlIHNlYXJjaCB0ZXJtCisgICAgICogQHJldHVybgkJdGhlIG1lc3NhZ2VzIHRoYXQgbWF0Y2gKKyAgICAgKiBAZXhjZXB0aW9uCVNlYXJjaEV4Y2VwdGlvbiBpZiBtYWlsLmltYXAudGhyb3dzZWFyY2hleGNlcHRpb24gaXMKKyAgICAgKgkJCXRydWUgYW5kIHRoZSBzZWFyY2ggaXMgdG9vIGNvbXBsZXggZm9yIHRoZSBJTUFQIHByb3RvY29sCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBNZXNzYWdlW10gc2VhcmNoKFNlYXJjaFRlcm0gdGVybSkKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwljaGVja09wZW5lZCgpOworCisJdHJ5IHsKKwkgICAgTWVzc2FnZVtdIG1hdGNoTXNncyA9IG51bGw7CisKKwkgICAgc3luY2hyb25pemVkKG1lc3NhZ2VDYWNoZUxvY2spIHsKKwkJaW50W10gbWF0Y2hlcyA9IGdldFByb3RvY29sKCkuc2VhcmNoKHRlcm0pOworCQlpZiAobWF0Y2hlcyAhPSBudWxsKQorCQkgICAgbWF0Y2hNc2dzID0gZ2V0TWVzc2FnZXNCeVNlcU51bWJlcnMobWF0Y2hlcyk7CisJICAgIH0KKwkgICAgcmV0dXJuIG1hdGNoTXNnczsKKworCX0gY2F0Y2ggKENvbW1hbmRGYWlsZWRFeGNlcHRpb24gY2Z4KSB7CisJICAgIC8vIHVuc3VwcG9ydGVkIGNoYXJzZXQgb3Igc2VhcmNoIGNyaXRlcmlvbgorCSAgICByZXR1cm4gc3VwZXIuc2VhcmNoKHRlcm0pOworCX0gY2F0Y2ggKFNlYXJjaEV4Y2VwdGlvbiBzZXgpIHsKKwkgICAgLy8gdG9vIGNvbXBsZXggZm9yIElNQVAKKwkgICAgaWYgKCgoSU1BUFN0b3JlKXN0b3JlKS50aHJvd1NlYXJjaEV4Y2VwdGlvbigpKQorCQl0aHJvdyBzZXg7CisJICAgIHJldHVybiBzdXBlci5zZWFyY2godGVybSk7CisJfSBjYXRjaCAoQ29ubmVjdGlvbkV4Y2VwdGlvbiBjZXgpIHsKKwkgICAgdGhyb3cgbmV3IEZvbGRlckNsb3NlZEV4Y2VwdGlvbih0aGlzLCBjZXguZ2V0TWVzc2FnZSgpKTsKKwl9IGNhdGNoIChQcm90b2NvbEV4Y2VwdGlvbiBwZXgpIHsKKwkgICAgLy8gYnVnIGluIG91ciBJTUFQIGxheWVyID8KKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbihwZXguZ2V0TWVzc2FnZSgpLCBwZXgpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZWFyY2ggdGhlIGZvbGRlciBmb3IgbWVzc2FnZXMgbWF0Y2hpbmcgdGhlIGdpdmVuIHRlcm0uIFJldHVybnMKKyAgICAgKiBhcnJheSBvZiBtYXRjaGluZyBtZXNzYWdlcy4gUmV0dXJucyBhbiBlbXB0eSBhcnJheSBpZiBubyBtYXRjaGluZworICAgICAqIG1lc3NhZ2VzIGFyZSBmb3VuZC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIE1lc3NhZ2VbXSBzZWFyY2goU2VhcmNoVGVybSB0ZXJtLCBNZXNzYWdlW10gbXNncykgCisJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwljaGVja09wZW5lZCgpOworCisJaWYgKG1zZ3MubGVuZ3RoID09IDApCisJICAgIC8vIG5lZWQgdG8gcmV0dXJuIGFuIGVtcHR5IGFycmF5IChub3QgbnVsbCEpCisJICAgIHJldHVybiBtc2dzOworCisJdHJ5IHsKKwkgICAgTWVzc2FnZVtdIG1hdGNoTXNncyA9IG51bGw7CisKKwkgICAgc3luY2hyb25pemVkKG1lc3NhZ2VDYWNoZUxvY2spIHsKKwkJSU1BUFByb3RvY29sIHAgPSBnZXRQcm90b2NvbCgpOworCQlNZXNzYWdlU2V0W10gbXMgPSBVdGlsaXR5LnRvTWVzc2FnZVNldFNvcnRlZChtc2dzLCBudWxsKTsKKwkJaWYgKG1zID09IG51bGwpCisJCSAgICB0aHJvdyBuZXcgTWVzc2FnZVJlbW92ZWRFeGNlcHRpb24oCisJCQkJCSJNZXNzYWdlcyBoYXZlIGJlZW4gcmVtb3ZlZCIpOworCQlpbnRbXSBtYXRjaGVzID0gcC5zZWFyY2gobXMsIHRlcm0pOworCQlpZiAobWF0Y2hlcyAhPSBudWxsKQorCQkgICAgbWF0Y2hNc2dzID0gZ2V0TWVzc2FnZXNCeVNlcU51bWJlcnMobWF0Y2hlcyk7CisJICAgIH0KKwkgICAgcmV0dXJuIG1hdGNoTXNnczsKKworCX0gY2F0Y2ggKENvbW1hbmRGYWlsZWRFeGNlcHRpb24gY2Z4KSB7CisJICAgIC8vIHVuc3VwcG9ydGVkIGNoYXJzZXQgb3Igc2VhcmNoIGNyaXRlcmlvbgorCSAgICByZXR1cm4gc3VwZXIuc2VhcmNoKHRlcm0sIG1zZ3MpOworCX0gY2F0Y2ggKFNlYXJjaEV4Y2VwdGlvbiBzZXgpIHsKKwkgICAgLy8gdG9vIGNvbXBsZXggZm9yIElNQVAKKwkgICAgcmV0dXJuIHN1cGVyLnNlYXJjaCh0ZXJtLCBtc2dzKTsKKwl9IGNhdGNoIChDb25uZWN0aW9uRXhjZXB0aW9uIGNleCkgeworCSAgICB0aHJvdyBuZXcgRm9sZGVyQ2xvc2VkRXhjZXB0aW9uKHRoaXMsIGNleC5nZXRNZXNzYWdlKCkpOworCX0gY2F0Y2ggKFByb3RvY29sRXhjZXB0aW9uIHBleCkgeworCSAgICAvLyBidWcgaW4gb3VyIElNQVAgbGF5ZXIgPworCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKHBleC5nZXRNZXNzYWdlKCksIHBleCk7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNvcnQgdGhlIG1lc3NhZ2VzIGluIHRoZSBmb2xkZXIgYWNjb3JkaW5nIHRvIHRoZSBzb3J0IGNyaXRlcmlhLgorICAgICAqIFRoZSBtZXNzYWdlcyBhcmUgcmV0dXJuZWQgaW4gdGhlIHNvcnRlZCBvcmRlciwgYnV0IHRoZSBvcmRlciBvZgorICAgICAqIHRoZSBtZXNzYWdlcyBpbiB0aGUgZm9sZGVyIGlzIG5vdCBjaGFuZ2VkLiA8cD4KKyAgICAgKgorICAgICAqIERlcGVuZHMgb24gdGhlIFNPUlQgZXh0ZW5zaW9uIC0KKyAgICAgKiA8QSBIUkVGPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmM1MjU2LnR4dCI+UkZDIDUyNTY8L0E+LgorICAgICAqCisgICAgICogQHBhcmFtCXRlcm0JdGhlIFNvcnRUZXJtcworICAgICAqIEByZXR1cm4JCXRoZSBtZXNzYWdlcyBpbiBzb3J0ZWQgb3JkZXIKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS40LjQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIE1lc3NhZ2VbXSBnZXRTb3J0ZWRNZXNzYWdlcyhTb3J0VGVybVtdIHRlcm0pCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJcmV0dXJuIGdldFNvcnRlZE1lc3NhZ2VzKHRlcm0sIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNvcnQgdGhlIG1lc3NhZ2VzIGluIHRoZSBmb2xkZXIgYWNjb3JkaW5nIHRvIHRoZSBzb3J0IGNyaXRlcmlhLgorICAgICAqIFRoZSBtZXNzYWdlcyBhcmUgcmV0dXJuZWQgaW4gdGhlIHNvcnRlZCBvcmRlciwgYnV0IHRoZSBvcmRlciBvZgorICAgICAqIHRoZSBtZXNzYWdlcyBpbiB0aGUgZm9sZGVyIGlzIG5vdCBjaGFuZ2VkLiAgT25seSBtZXNzYWdlcyBtYXRjaGluZworICAgICAqIHRoZSBzZWFyY2ggY3JpdGVyaWEgYXJlIGNvbnNpZGVyZWQuIDxwPgorICAgICAqCisgICAgICogRGVwZW5kcyBvbiB0aGUgU09SVCBleHRlbnNpb24gLQorICAgICAqIDxBIEhSRUY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzUyNTYudHh0Ij5SRkMgNTI1NjwvQT4uCisgICAgICoKKyAgICAgKiBAcGFyYW0JdGVybQl0aGUgU29ydFRlcm1zCisgICAgICogQHBhcmFtCXN0ZXJtCXRoZSBTZWFyY2hUZXJtCisgICAgICogQHJldHVybgkJdGhlIG1lc3NhZ2VzIGluIHNvcnRlZCBvcmRlcgorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjQuNAorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgTWVzc2FnZVtdIGdldFNvcnRlZE1lc3NhZ2VzKFNvcnRUZXJtW10gdGVybSwKKwkJCQlTZWFyY2hUZXJtIHN0ZXJtKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwljaGVja09wZW5lZCgpOworCisJdHJ5IHsKKwkgICAgTWVzc2FnZVtdIG1hdGNoTXNncyA9IG51bGw7CisKKwkgICAgc3luY2hyb25pemVkKG1lc3NhZ2VDYWNoZUxvY2spIHsKKwkJaW50W10gbWF0Y2hlcyA9IGdldFByb3RvY29sKCkuc29ydCh0ZXJtLCBzdGVybSk7CisJCWlmIChtYXRjaGVzICE9IG51bGwpCisJCSAgICBtYXRjaE1zZ3MgPSBnZXRNZXNzYWdlc0J5U2VxTnVtYmVycyhtYXRjaGVzKTsKKwkgICAgfQorCSAgICByZXR1cm4gbWF0Y2hNc2dzOworCisJfSBjYXRjaCAoQ29tbWFuZEZhaWxlZEV4Y2VwdGlvbiBjZngpIHsKKwkgICAgLy8gdW5zdXBwb3J0ZWQgY2hhcnNldCBvciBzZWFyY2ggY3JpdGVyaW9uCisJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oY2Z4LmdldE1lc3NhZ2UoKSwgY2Z4KTsKKwl9IGNhdGNoIChTZWFyY2hFeGNlcHRpb24gc2V4KSB7CisJICAgIC8vIHRvbyBjb21wbGV4IGZvciBJTUFQCisJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oc2V4LmdldE1lc3NhZ2UoKSwgc2V4KTsKKwl9IGNhdGNoIChDb25uZWN0aW9uRXhjZXB0aW9uIGNleCkgeworCSAgICB0aHJvdyBuZXcgRm9sZGVyQ2xvc2VkRXhjZXB0aW9uKHRoaXMsIGNleC5nZXRNZXNzYWdlKCkpOworCX0gY2F0Y2ggKFByb3RvY29sRXhjZXB0aW9uIHBleCkgeworCSAgICAvLyBidWcgaW4gb3VyIElNQVAgbGF5ZXIgPworCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKHBleC5nZXRNZXNzYWdlKCksIHBleCk7CisJfQorICAgIH0KKworICAgIC8qCisgICAgICogT3ZlcnJpZGUgRm9sZGVyIG1ldGhvZCB0byBrZWVwIHRyYWNrIG9mIHdoZXRoZXIgd2UgaGF2ZSBhbnkKKyAgICAgKiBtZXNzYWdlIGNvdW50IGxpc3RlbmVycy4gIE5vcm1hbGx5IHdlIHdvbid0IGhhdmUgYW55LCBzbyB3ZQorICAgICAqIGNhbiBhdm9pZCBjcmVhdGluZyBtZXNzYWdlIG9iamVjdHMgdG8gcGFzcyB0byB0aGUgbm90aWZ5CisgICAgICogbWV0aG9kLiAgSXQncyB0b28gaGFyZCB0byBrZWVwIHRyYWNrIG9mIHdoZW4gYWxsIGxpc3RlbmVycworICAgICAqIGFyZSByZW1vdmVkLCBhbmQgdGhhdCdzIGEgcmFyZSBjYXNlLCBzbyB3ZSBkb24ndCB0cnkuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGFkZE1lc3NhZ2VDb3VudExpc3RlbmVyKE1lc3NhZ2VDb3VudExpc3RlbmVyIGwpIHsgCisJc3VwZXIuYWRkTWVzc2FnZUNvdW50TGlzdGVuZXIobCk7CisJaGFzTWVzc2FnZUNvdW50TGlzdGVuZXIgPSB0cnVlOworICAgIH0KKworICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorICAgICAqCQlVSURGb2xkZXIgaW50ZXJmYWNlIG1ldGhvZHMKKyAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIFVJRFZhbGlkaXR5IGZvciB0aGlzIGZvbGRlci4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGxvbmcgZ2V0VUlEVmFsaWRpdHkoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpZiAob3BlbmVkKSAvLyB3ZSBhbHJlYWR5IGhhdmUgdGhpcyBpbmZvcm1hdGlvbgorCSAgICByZXR1cm4gdWlkdmFsaWRpdHk7CisKKyAgICAgICAgSU1BUFByb3RvY29sIHAgPSBudWxsOworICAgICAgICBTdGF0dXMgc3RhdHVzID0gbnVsbDsKKworCXRyeSB7CisJICAgIHAgPSBnZXRTdG9yZVByb3RvY29sKCk7CS8vIFhYWAorCSAgICBTdHJpbmdbXSBpdGVtID0geyAiVUlEVkFMSURJVFkiIH07CisJICAgIHN0YXR1cyA9IHAuc3RhdHVzKGZ1bGxOYW1lLCBpdGVtKTsKKwl9IGNhdGNoIChCYWRDb21tYW5kRXhjZXB0aW9uIGJleCkgeworCSAgICAvLyBQcm9iYWJseSBhIFJGQzE3MzAgc2VydmVyCisJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oIkNhbm5vdCBvYnRhaW4gVUlEVmFsaWRpdHkiLCBiZXgpOworCX0gY2F0Y2ggKENvbm5lY3Rpb25FeGNlcHRpb24gY2V4KSB7CisgICAgICAgICAgICAvLyBPb3BzLCB0aGUgc3RvcmUgb3IgZm9sZGVyIGRpZWQgb24gdXMuCisgICAgICAgICAgICB0aHJvd0Nsb3NlZEV4Y2VwdGlvbihjZXgpOworCX0gY2F0Y2ggKFByb3RvY29sRXhjZXB0aW9uIHBleCkgeworCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKHBleC5nZXRNZXNzYWdlKCksIHBleCk7CisJfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHJlbGVhc2VTdG9yZVByb3RvY29sKHApOworICAgICAgICB9CisKKwlpZiAoc3RhdHVzID09IG51bGwpCisJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oIkNhbm5vdCBvYnRhaW4gVUlEVmFsaWRpdHkiKTsKKwlyZXR1cm4gc3RhdHVzLnVpZHZhbGlkaXR5OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHByZWRpY3RlZCBVSUQgdGhhdCB3aWxsIGJlIGFzc2lnbmVkIHRvIHRoZQorICAgICAqIG5leHQgbWVzc2FnZSB0aGF0IGlzIGFwcGVuZGVkIHRvIHRoaXMgZm9sZGVyLgorICAgICAqIElmIHRoZSBmb2xkZXIgaXMgY2xvc2VkLCB0aGUgU1RBVFVTIGNvbW1hbmQgaXMgdXNlZCB0bworICAgICAqIHJldHJpZXZlIHRoaXMgdmFsdWUuICBJZiB0aGUgZm9sZGVyIGlzIG9wZW4sIHRoZSB2YWx1ZQorICAgICAqIHJldHVybmVkIGZyb20gdGhlIFNFTEVDVCBvciBFWEFNSU5FIGNvbW1hbmQgaXMgcmV0dXJuZWQuCisgICAgICogTm90ZSB0aGF0IG1lc3NhZ2VzIG1heSBoYXZlIGJlZW4gYXBwZW5kZWQgdG8gdGhlIGZvbGRlcgorICAgICAqIHdoaWxlIGl0IHdhcyBvcGVuIGFuZCB0aHVzIHRoaXMgdmFsdWUgbWF5IGJlIG91dCBvZgorICAgICAqIGRhdGUuIDxwPgorICAgICAqCisgICAgICogU2VydmVycyBpbXBsZW1lbnRpbmcgUkZDMjA2MCBsaWtlbHkgd29uJ3QgcmV0dXJuIHRoaXMgdmFsdWUKKyAgICAgKiB3aGVuIGEgZm9sZGVyIGlzIG9wZW5lZC4gIFNlcnZlcnMgaW1wbGVtZW50aW5nIFJGQzM1MDEKKyAgICAgKiBzaG91bGQgcmV0dXJuIHRoaXMgdmFsdWUgd2hlbiBhIGZvbGRlciBpcyBvcGVuZWQuIDxwPgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgVUlETkVYVCB2YWx1ZSwgb3IgLTEgaWYgdW5rbm93bgorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjMuMworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgbG9uZyBnZXRVSUROZXh0KCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKG9wZW5lZCkgLy8gd2UgYWxyZWFkeSBoYXZlIHRoaXMgaW5mb3JtYXRpb24KKwkgICAgcmV0dXJuIHVpZG5leHQ7CisKKyAgICAgICAgSU1BUFByb3RvY29sIHAgPSBudWxsOworICAgICAgICBTdGF0dXMgc3RhdHVzID0gbnVsbDsKKworCXRyeSB7CisJICAgIHAgPSBnZXRTdG9yZVByb3RvY29sKCk7CS8vIFhYWAorCSAgICBTdHJpbmdbXSBpdGVtID0geyAiVUlETkVYVCIgfTsKKwkgICAgc3RhdHVzID0gcC5zdGF0dXMoZnVsbE5hbWUsIGl0ZW0pOworCX0gY2F0Y2ggKEJhZENvbW1hbmRFeGNlcHRpb24gYmV4KSB7CisJICAgIC8vIFByb2JhYmx5IGEgUkZDMTczMCBzZXJ2ZXIKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiQ2Fubm90IG9idGFpbiBVSUROZXh0IiwgYmV4KTsKKwl9IGNhdGNoIChDb25uZWN0aW9uRXhjZXB0aW9uIGNleCkgeworICAgICAgICAgICAgLy8gT29wcywgdGhlIHN0b3JlIG9yIGZvbGRlciBkaWVkIG9uIHVzLgorICAgICAgICAgICAgdGhyb3dDbG9zZWRFeGNlcHRpb24oY2V4KTsKKwl9IGNhdGNoIChQcm90b2NvbEV4Y2VwdGlvbiBwZXgpIHsKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbihwZXguZ2V0TWVzc2FnZSgpLCBwZXgpOworCX0gZmluYWxseSB7CisgICAgICAgICAgICByZWxlYXNlU3RvcmVQcm90b2NvbChwKTsKKyAgICAgICAgfQorCisJaWYgKHN0YXR1cyA9PSBudWxsKQorCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKCJDYW5ub3Qgb2J0YWluIFVJRE5leHQiKTsKKwlyZXR1cm4gc3RhdHVzLnVpZG5leHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBNZXNzYWdlIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGdpdmVuIFVJRC4KKyAgICAgKiBJZiBubyBzdWNoIG1lc3NhZ2UgZXhpc3RzLCA8Y29kZT4gbnVsbCA8L2NvZGU+IGlzIHJldHVybmVkLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgTWVzc2FnZSBnZXRNZXNzYWdlQnlVSUQobG9uZyB1aWQpIAorCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJY2hlY2tPcGVuZWQoKTsgLy8gaW5zdXJlIGZvbGRlciBpcyBvcGVuCisKKwlJTUFQTWVzc2FnZSBtID0gbnVsbDsKKworCXRyeSB7CisJICAgIHN5bmNocm9uaXplZChtZXNzYWdlQ2FjaGVMb2NrKSB7CisJCUxvbmcgbCA9IExvbmcudmFsdWVPZih1aWQpOworCisJCWlmICh1aWRUYWJsZSAhPSBudWxsKSB7CisJCSAgICAvLyBDaGVjayBpbiB1aWRUYWJsZQorCQkgICAgbSA9IHVpZFRhYmxlLmdldChsKTsKKwkJICAgIGlmIChtICE9IG51bGwpIC8vIGZvdW5kIGl0CisJCQlyZXR1cm4gbTsKKwkJfSBlbHNlCisJCSAgICB1aWRUYWJsZSA9IG5ldyBIYXNodGFibGU8PigpOworCisJCS8vIENoZWNrIHdpdGggdGhlIHNlcnZlcgorCQkvLyBJc3N1ZSBVSUQgRkVUQ0ggY29tbWFuZAorCQlnZXRQcm90b2NvbCgpLmZldGNoU2VxdWVuY2VOdW1iZXIodWlkKTsKKworCQlpZiAodWlkVGFibGUgIT0gbnVsbCkgeworCQkgICAgLy8gQ2hlY2sgaW4gdWlkVGFibGUKKwkJICAgIG0gPSB1aWRUYWJsZS5nZXQobCk7CisJCSAgICBpZiAobSAhPSBudWxsKSAvLyBmb3VuZCBpdAorCQkJcmV0dXJuIG07CisJCX0KKwkgICAgfQorCX0gY2F0Y2goQ29ubmVjdGlvbkV4Y2VwdGlvbiBjZXgpIHsKKwkgICAgdGhyb3cgbmV3IEZvbGRlckNsb3NlZEV4Y2VwdGlvbih0aGlzLCBjZXguZ2V0TWVzc2FnZSgpKTsKKwl9IGNhdGNoIChQcm90b2NvbEV4Y2VwdGlvbiBwZXgpIHsKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbihwZXguZ2V0TWVzc2FnZSgpLCBwZXgpOworCX0KKworCXJldHVybiBtOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgTWVzc2FnZXMgc3BlY2lmaWVkIGJ5IHRoZSBnaXZlbiByYW5nZS4gPHA+CisgICAgICogUmV0dXJucyBNZXNzYWdlIG9iamVjdHMgZm9yIGFsbCB2YWxpZCBtZXNzYWdlcyBpbiB0aGlzIHJhbmdlLgorICAgICAqIFJldHVybnMgYW4gZW1wdHkgYXJyYXkgaWYgbm8gbWVzc2FnZXMgYXJlIGZvdW5kLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgTWVzc2FnZVtdIGdldE1lc3NhZ2VzQnlVSUQobG9uZyBzdGFydCwgbG9uZyBlbmQpIAorCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJY2hlY2tPcGVuZWQoKTsgLy8gaW5zdXJlIHRoYXQgZm9sZGVyIGlzIG9wZW4KKworCU1lc3NhZ2VbXSBtc2dzOyAvLyBhcnJheSBvZiBtZXNzYWdlcyB0byBiZSByZXR1cm5lZAorCisJdHJ5IHsKKwkgICAgc3luY2hyb25pemVkKG1lc3NhZ2VDYWNoZUxvY2spIHsKKwkJaWYgKHVpZFRhYmxlID09IG51bGwpCisJCSAgICB1aWRUYWJsZSA9IG5ldyBIYXNodGFibGU8PigpOworCisJCS8vIElzc3VlIFVJRCBGRVRDSCBmb3IgZ2l2ZW4gcmFuZ2UKKwkJbG9uZ1tdIHVhID0gZ2V0UHJvdG9jb2woKS5mZXRjaFNlcXVlbmNlTnVtYmVycyhzdGFydCwgZW5kKTsKKworCQlMaXN0PE1lc3NhZ2U+IG1hID0gbmV3IEFycmF5TGlzdDw+KCk7CisJCS8vIE5PVEU6IEJlbG93IG11c3QgYmUgd2l0aGluIG1lc3NhZ2VDYWNoZUxvY2sgcmVnaW9uCisJCWZvciAoaW50IGkgPSAwOyBpIDwgdWEubGVuZ3RoOyBpKyspIHsKKwkJICAgIE1lc3NhZ2UgbSA9IHVpZFRhYmxlLmdldChMb25nLnZhbHVlT2YodWFbaV0pKTsKKwkJICAgIGlmIChtICE9IG51bGwpIC8vIGZvdW5kIGl0CisJCQltYS5hZGQobSk7CisJCX0KKwkJbXNncyA9IG1hLnRvQXJyYXkobmV3IE1lc3NhZ2VbbWEuc2l6ZSgpXSk7CisJICAgIH0KKwl9IGNhdGNoKENvbm5lY3Rpb25FeGNlcHRpb24gY2V4KSB7CisJICAgIHRocm93IG5ldyBGb2xkZXJDbG9zZWRFeGNlcHRpb24odGhpcywgY2V4LmdldE1lc3NhZ2UoKSk7CisJfSBjYXRjaCAoUHJvdG9jb2xFeGNlcHRpb24gcGV4KSB7CisJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24ocGV4LmdldE1lc3NhZ2UoKSwgcGV4KTsKKwl9CisKKwlyZXR1cm4gbXNnczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIE1lc3NhZ2VzIHNwZWNpZmllZCBieSB0aGUgZ2l2ZW4gYXJyYXkuIDxwPgorICAgICAqCisgICAgICogPGNvZGU+dWlkcy5sZW5ndGgoKTwvY29kZT4gZWxlbWVudHMgYXJlIHJldHVybmVkLgorICAgICAqIElmIGFueSBVSUQgaW4gdGhlIGFycmF5IGlzIGludmFsaWQsIGEgPGNvZGU+bnVsbDwvY29kZT4gZW50cnkKKyAgICAgKiBpcyByZXR1cm5lZCBmb3IgdGhhdCBlbGVtZW50LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgTWVzc2FnZVtdIGdldE1lc3NhZ2VzQnlVSUQobG9uZ1tdIHVpZHMpCisJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwljaGVja09wZW5lZCgpOyAvLyBpbnN1cmUgdGhhdCBmb2xkZXIgaXMgb3BlbgorCisJdHJ5IHsKKwkgICAgc3luY2hyb25pemVkKG1lc3NhZ2VDYWNoZUxvY2spIHsKKwkJbG9uZ1tdIHVuYXZhaWxVaWRzID0gdWlkczsKKwkJaWYgKHVpZFRhYmxlICE9IG51bGwpIHsKKwkJICAgIC8vIHRvIGNvbGxlY3QgdW5hdmFpbGFibGUgVUlEcworCQkgICAgTGlzdDxMb25nPiB2ID0gbmV3IEFycmF5TGlzdDw+KCk7CisJCSAgICBmb3IgKGxvbmcgdWlkIDogdWlkcykgeworCQkJaWYgKCF1aWRUYWJsZS5jb250YWluc0tleSh1aWQpKSB7CisJCQkgICAgLy8gVGhpcyBVSUQgaGFzIG5vdCBiZWVuIGxvYWRlZCB5ZXQuCisJCQkgICAgdi5hZGQodWlkKTsKKwkJCX0KKwkJICAgIH0KKworCQkgICAgaW50IHZzaXplID0gdi5zaXplKCk7CisJCSAgICB1bmF2YWlsVWlkcyA9IG5ldyBsb25nW3ZzaXplXTsKKwkJICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdnNpemU7IGkrKykgeworCQkJdW5hdmFpbFVpZHNbaV0gPSB2LmdldChpKTsKKwkJICAgIH0KKwkJfSBlbHNlCisJCSAgICB1aWRUYWJsZSA9IG5ldyBIYXNodGFibGU8PigpOworCisJCWlmICh1bmF2YWlsVWlkcy5sZW5ndGggPiAwKSB7CisJCSAgICAvLyBJc3N1ZSBVSUQgRkVUQ0ggcmVxdWVzdCBmb3IgZ2l2ZW4gdWlkcworCQkgICAgZ2V0UHJvdG9jb2woKS5mZXRjaFNlcXVlbmNlTnVtYmVycyh1bmF2YWlsVWlkcyk7CisJCX0KKworCQkvLyBSZXR1cm4gYXJyYXkgb2Ygc2l6ZSA9IHVpZHMubGVuZ3RoCisJCU1lc3NhZ2VbXSBtc2dzID0gbmV3IE1lc3NhZ2VbdWlkcy5sZW5ndGhdOworCQlmb3IgKGludCBpID0gMDsgaSA8IHVpZHMubGVuZ3RoOyBpKyspCisJCSAgICBtc2dzW2ldID0gKE1lc3NhZ2UpdWlkVGFibGUuZ2V0KExvbmcudmFsdWVPZih1aWRzW2ldKSk7CisJCXJldHVybiBtc2dzOworCSAgICB9CisJfSBjYXRjaChDb25uZWN0aW9uRXhjZXB0aW9uIGNleCkgeworCSAgICB0aHJvdyBuZXcgRm9sZGVyQ2xvc2VkRXhjZXB0aW9uKHRoaXMsIGNleC5nZXRNZXNzYWdlKCkpOworCX0gY2F0Y2ggKFByb3RvY29sRXhjZXB0aW9uIHBleCkgeworCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKHBleC5nZXRNZXNzYWdlKCksIHBleCk7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgVUlEIGZvciB0aGUgc3BlY2lmaWVkIG1lc3NhZ2UuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBsb25nIGdldFVJRChNZXNzYWdlIG1lc3NhZ2UpIAorCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKG1lc3NhZ2UuZ2V0Rm9sZGVyKCkgIT0gdGhpcykKKwkgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oCisJCSJNZXNzYWdlIGRvZXMgbm90IGJlbG9uZyB0byB0aGlzIGZvbGRlciIpOworCisJY2hlY2tPcGVuZWQoKTsgLy8gaW5zdXJlIHRoYXQgZm9sZGVyIGlzIG9wZW4KKworCWlmICghKG1lc3NhZ2UgaW5zdGFuY2VvZiBJTUFQTWVzc2FnZSkpCisJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oIm1lc3NhZ2UgaXMgbm90IGFuIElNQVBNZXNzYWdlIik7CisJSU1BUE1lc3NhZ2UgbSA9IChJTUFQTWVzc2FnZSltZXNzYWdlOworCS8vIElmIHRoZSBtZXNzYWdlIGFscmVhZHkga25vd3MgaXRzIFVJRCwgZ3JlYXQgLi4KKwlsb25nIHVpZDsKKwlpZiAoKHVpZCA9IG0uZ2V0VUlEKCkpICE9IC0xKQorCSAgICByZXR1cm4gdWlkOworCisJc3luY2hyb25pemVkKG1lc3NhZ2VDYWNoZUxvY2spIHsgLy8gQWNxdWlyZSBMb2NrCisJICAgIHRyeSB7CisJCUlNQVBQcm90b2NvbCBwID0gZ2V0UHJvdG9jb2woKTsKKwkJbS5jaGVja0V4cHVuZ2VkKCk7IC8vIGluc3VyZSB0aGF0IG1lc3NhZ2UgaXMgbm90IGV4cHVuZ2VkCisJCVVJRCB1ID0gcC5mZXRjaFVJRChtLmdldFNlcXVlbmNlTnVtYmVyKCkpOworCisJCWlmICh1ICE9IG51bGwpIHsKKwkJICAgIHVpZCA9IHUudWlkOworCQkgICAgbS5zZXRVSUQodWlkKTsgLy8gc2V0IG1lc3NhZ2UncyBVSUQKKworCQkgICAgLy8gaW5zZXJ0IHRoaXMgbWVzc2FnZSBpbnRvIHVpZFRhYmxlCisJCSAgICBpZiAodWlkVGFibGUgPT0gbnVsbCkKKwkJCXVpZFRhYmxlID0gbmV3IEhhc2h0YWJsZTw+KCk7CisJCSAgICB1aWRUYWJsZS5wdXQoTG9uZy52YWx1ZU9mKHVpZCksIG0pOworCQl9CisJICAgIH0gY2F0Y2ggKENvbm5lY3Rpb25FeGNlcHRpb24gY2V4KSB7CisJCXRocm93IG5ldyBGb2xkZXJDbG9zZWRFeGNlcHRpb24odGhpcywgY2V4LmdldE1lc3NhZ2UoKSk7CisJICAgIH0gY2F0Y2ggKFByb3RvY29sRXhjZXB0aW9uIHBleCkgeworCQl0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKHBleC5nZXRNZXNzYWdlKCksIHBleCk7CisJICAgIH0KKwl9CisKKwlyZXR1cm4gdWlkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNlcnZlcnMgdGhhdCBzdXBwb3J0IHRoZSBVSURQTFVTIGV4dGVuc2lvbgorICAgICAqICg8QSBIUkVGPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmM0MzE1LnR4dCI+UkZDIDQzMTU8L0E+KQorICAgICAqIG1heSBpbmRpY2F0ZSB0aGF0IHRoaXMgZm9sZGVyIGRvZXMgbm90IHN1cHBvcnQgcGVyc2lzdGVudCBVSURzOworICAgICAqIHRoYXQgaXMsIFVJRFZBTElESVRZIHdpbGwgYmUgZGlmZmVyZW50IGVhY2ggdGltZSB0aGUgZm9sZGVyIGlzCisgICAgICogb3BlbmVkLiAgT25seSB2YWxpZCB3aGVuIHRoZSBmb2xkZXIgaXMgb3Blbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdHJ1ZSBpZiBVSURzIGFyZSBub3Qgc3RpY2t5CisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24JaWYgdGhlIGZvbGRlciBpc24ndCBvcGVuCisgICAgICogQHNlZSAiUkZDIDQzMTUiCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNi4wCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIGdldFVJRE5vdFN0aWNreSgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWNoZWNrT3BlbmVkKCk7CisJcmV0dXJuIHVpZE5vdFN0aWNreTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgb3IgY3JlYXRlIE1lc3NhZ2Ugb2JqZWN0cyBmb3IgdGhlIFVJRHMuCisgICAgICovCisgICAgcHJpdmF0ZSBNZXNzYWdlW10gY3JlYXRlTWVzc2FnZXNGb3JVSURzKGxvbmdbXSB1aWRzKSB7CisJSU1BUE1lc3NhZ2VbXSBtc2dzID0gbmV3IElNQVBNZXNzYWdlW3VpZHMubGVuZ3RoXTsKKwlmb3IgKGludCBpID0gMDsgaSA8IHVpZHMubGVuZ3RoOyBpKyspIHsKKwkgICAgSU1BUE1lc3NhZ2UgbSA9IG51bGw7CisJICAgIGlmICh1aWRUYWJsZSAhPSBudWxsKQorCQltID0gdWlkVGFibGUuZ2V0KExvbmcudmFsdWVPZih1aWRzW2ldKSk7CisJICAgIGlmIChtID09IG51bGwpIHsKKwkJLy8gZmFrZSBpdCwgd2UgZG9uJ3Qga25vdyB3aGF0IG1lc3NhZ2UgdGhpcyByZWFsbHkgaXMKKwkJbSA9IG5ld0lNQVBNZXNzYWdlKC0xKTsJLy8gbm8gc2VxdWVuY2UgbnVtYmVyCisJCW0uc2V0VUlEKHVpZHNbaV0pOworCQltLnNldEV4cHVuZ2VkKHRydWUpOworCSAgICB9CisJICAgIG1zZ3NbaSsrXSA9IG07CisJfQorCXJldHVybiBtc2dzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIEhJR0hFU1RNT0RTRVEgZm9yIHRoaXMgZm9sZGVyLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgSElHSEVTVE1PRFNFUSB2YWx1ZQorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqIEBzZWUgIlJGQyA0NTUxIgorICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjUuMQorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgbG9uZyBnZXRIaWdoZXN0TW9kU2VxKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKG9wZW5lZCkgLy8gd2UgYWxyZWFkeSBoYXZlIHRoaXMgaW5mb3JtYXRpb24KKwkgICAgcmV0dXJuIGhpZ2hlc3Rtb2RzZXE7CisKKyAgICAgICAgSU1BUFByb3RvY29sIHAgPSBudWxsOworICAgICAgICBTdGF0dXMgc3RhdHVzID0gbnVsbDsKKworCXRyeSB7CisJICAgIHAgPSBnZXRTdG9yZVByb3RvY29sKCk7CS8vIFhYWAorCSAgICBpZiAoIXAuaGFzQ2FwYWJpbGl0eSgiQ09ORFNUT1JFIikpCisJCXRocm93IG5ldyBCYWRDb21tYW5kRXhjZXB0aW9uKCJDT05EU1RPUkUgbm90IHN1cHBvcnRlZCIpOworCSAgICBTdHJpbmdbXSBpdGVtID0geyAiSElHSEVTVE1PRFNFUSIgfTsKKwkgICAgc3RhdHVzID0gcC5zdGF0dXMoZnVsbE5hbWUsIGl0ZW0pOworCX0gY2F0Y2ggKEJhZENvbW1hbmRFeGNlcHRpb24gYmV4KSB7CisJICAgIC8vIFByb2JhYmx5IGEgUkZDMTczMCBzZXJ2ZXIKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiQ2Fubm90IG9idGFpbiBISUdIRVNUTU9EU0VRIiwgYmV4KTsKKwl9IGNhdGNoIChDb25uZWN0aW9uRXhjZXB0aW9uIGNleCkgeworICAgICAgICAgICAgLy8gT29wcywgdGhlIHN0b3JlIG9yIGZvbGRlciBkaWVkIG9uIHVzLgorICAgICAgICAgICAgdGhyb3dDbG9zZWRFeGNlcHRpb24oY2V4KTsKKwl9IGNhdGNoIChQcm90b2NvbEV4Y2VwdGlvbiBwZXgpIHsKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbihwZXguZ2V0TWVzc2FnZSgpLCBwZXgpOworCX0gZmluYWxseSB7CisgICAgICAgICAgICByZWxlYXNlU3RvcmVQcm90b2NvbChwKTsKKyAgICAgICAgfQorCisJaWYgKHN0YXR1cyA9PSBudWxsKQorCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKCJDYW5ub3Qgb2J0YWluIEhJR0hFU1RNT0RTRVEiKTsKKwlyZXR1cm4gc3RhdHVzLmhpZ2hlc3Rtb2RzZXE7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBtZXNzYWdlcyB0aGF0IGhhdmUgYmVlbiBjaGFuZ2VkIHNpbmNlIHRoZSBnaXZlbiBNT0RTRVEgdmFsdWUuCisgICAgICogQWxzbywgcHJlZmV0Y2ggdGhlIGZsYWdzIGZvciB0aGUgbWVzc2FnZXMuIDxwPgorICAgICAqCisgICAgICogVGhlIHNlcnZlciBtdXN0IHN1cHBvcnQgdGhlIENPTkRTVE9SRSBleHRlbnNpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0Jc3RhcnQJdGhlIGZpcnN0IG1lc3NhZ2UgbnVtYmVyCisgICAgICogQHBhcmFtCWVuZAl0aGUgbGFzdCBtZXNzYWdlIG51bWJlcgorICAgICAqIEBwYXJhbQltb2RzZXEJdGhlIE1PRFNFUSB2YWx1ZQorICAgICAqIEByZXR1cm4JdGhlIGNoYW5nZWQgbWVzc2FnZXMKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKiBAc2VlICJSRkMgNDU1MSIKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS41LjEKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIE1lc3NhZ2VbXSBnZXRNZXNzYWdlc0J5VUlEQ2hhbmdlZFNpbmNlKAorCQkJCWxvbmcgc3RhcnQsIGxvbmcgZW5kLCBsb25nIG1vZHNlcSkKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwljaGVja09wZW5lZCgpOyAvLyBpbnN1cmUgdGhhdCBmb2xkZXIgaXMgb3BlbgorCisJdHJ5IHsKKwkgICAgc3luY2hyb25pemVkIChtZXNzYWdlQ2FjaGVMb2NrKSB7CisJCUlNQVBQcm90b2NvbCBwID0gZ2V0UHJvdG9jb2woKTsKKwkJaWYgKCFwLmhhc0NhcGFiaWxpdHkoIkNPTkRTVE9SRSIpKQorCQkgICAgdGhyb3cgbmV3IEJhZENvbW1hbmRFeGNlcHRpb24oIkNPTkRTVE9SRSBub3Qgc3VwcG9ydGVkIik7CisKKwkJLy8gSXNzdWUgRkVUQ0ggZm9yIGdpdmVuIHJhbmdlCisJCWludFtdIG51bXMgPSBwLnVpZGZldGNoQ2hhbmdlZFNpbmNlKHN0YXJ0LCBlbmQsIG1vZHNlcSk7CisJCXJldHVybiBnZXRNZXNzYWdlc0J5U2VxTnVtYmVycyhudW1zKTsKKwkgICAgfQorCX0gY2F0Y2goQ29ubmVjdGlvbkV4Y2VwdGlvbiBjZXgpIHsKKwkgICAgdGhyb3cgbmV3IEZvbGRlckNsb3NlZEV4Y2VwdGlvbih0aGlzLCBjZXguZ2V0TWVzc2FnZSgpKTsKKwl9IGNhdGNoIChQcm90b2NvbEV4Y2VwdGlvbiBwZXgpIHsKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbihwZXguZ2V0TWVzc2FnZSgpLCBwZXgpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIHF1b3RhcyBmb3IgdGhlIHF1b3Rhcm9vdCBhc3NvY2lhdGVkIHdpdGggdGhpcworICAgICAqIGZvbGRlci4gIE5vdGUgdGhhdCBtYW55IGZvbGRlcnMgbWF5IGhhdmUgdGhlIHNhbWUgcXVvdGFyb290LgorICAgICAqIFF1b3RhcyBhcmUgY29udHJvbGxlZCBvbiB0aGUgYmFzaXMgb2YgYSBxdW90YXJvb3QsIG5vdAorICAgICAqIChuZWNlc3NhcmlseSkgYSBmb2xkZXIuICBUaGUgcmVsYXRpb25zaGlwIGJldHdlZW4gZm9sZGVycworICAgICAqIGFuZCBxdW90YXJvb3RzIGRlcGVuZHMgb24gdGhlIElNQVAgc2VydmVyLiAgU29tZSBzZXJ2ZXJzCisgICAgICogbWlnaHQgaW1wbGVtZW50IGEgc2luZ2xlIHF1b3Rhcm9vdCBmb3IgYWxsIGZvbGRlcnMgb3duZWQgYnkKKyAgICAgKiBhIHVzZXIuICBPdGhlciBzZXJ2ZXJzIG1pZ2h0IGltcGxlbWVudCBhIHNlcGFyYXRlIHF1b3Rhcm9vdAorICAgICAqIGZvciBlYWNoIGZvbGRlci4gIEEgc2luZ2xlIGZvbGRlciBjYW4gZXZlbiBoYXZlIG11bHRpcGxlCisgICAgICogcXVvdGFyb290cywgcGVyaGFwcyBjb250cm9sbGluZyBxdW90YXMgZm9yIGRpZmZlcmVudAorICAgICAqIHJlc291cmNlcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4JYXJyYXkgb2YgUXVvdGEgb2JqZWN0cyBmb3IgdGhlIHF1b3Rhcm9vdHMgYXNzb2NpYXRlZCB3aXRoCisgICAgICoJCXRoaXMgZm9sZGVyCisgICAgICogQGV4Y2VwdGlvbiBNZXNzYWdpbmdFeGNlcHRpb24JaWYgdGhlIHNlcnZlciBkb2Vzbid0IHN1cHBvcnQgdGhlCisgICAgICoJCQkJCVFVT1RBIGV4dGVuc2lvbgorICAgICAqLworICAgIHB1YmxpYyBRdW90YVtdIGdldFF1b3RhKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJcmV0dXJuIChRdW90YVtdKWRvT3B0aW9uYWxDb21tYW5kKCJRVU9UQSBub3Qgc3VwcG9ydGVkIiwKKwkgICAgbmV3IFByb3RvY29sQ29tbWFuZCgpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyBPYmplY3QgZG9Db21tYW5kKElNQVBQcm90b2NvbCBwKQorCQkJdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKwkJICAgIHJldHVybiBwLmdldFF1b3RhUm9vdChmdWxsTmFtZSk7CisJCX0KKwkgICAgfSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBxdW90YXMgZm9yIHRoZSBxdW90YXJvb3Qgc3BlY2lmaWVkIGluIHRoZSBxdW90YSBhcmd1bWVudC4KKyAgICAgKiBUeXBpY2FsbHkgdGhpcyB3aWxsIGJlIG9uZSBvZiB0aGUgcXVvdGFyb290cyBhc3NvY2lhdGVkIHdpdGggdGhpcworICAgICAqIGZvbGRlciwgYXMgb2J0YWluZWQgZnJvbSB0aGUgPGNvZGU+Z2V0UXVvdGE8L2NvZGU+IG1ldGhvZCwgYnV0IGl0CisgICAgICogbmVlZCBub3QgYmUuCisgICAgICoKKyAgICAgKiBAcGFyYW0JcXVvdGEJdGhlIHF1b3RhIHRvIHNldAorICAgICAqIEBleGNlcHRpb24gTWVzc2FnaW5nRXhjZXB0aW9uCWlmIHRoZSBzZXJ2ZXIgZG9lc24ndCBzdXBwb3J0IHRoZQorICAgICAqCQkJCQlRVU9UQSBleHRlbnNpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRRdW90YShmaW5hbCBRdW90YSBxdW90YSkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJZG9PcHRpb25hbENvbW1hbmQoIlFVT1RBIG5vdCBzdXBwb3J0ZWQiLAorCSAgICBuZXcgUHJvdG9jb2xDb21tYW5kKCkgeworCQlAT3ZlcnJpZGUKKwkJcHVibGljIE9iamVjdCBkb0NvbW1hbmQoSU1BUFByb3RvY29sIHApCisJCQl0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCQkgICAgcC5zZXRRdW90YShxdW90YSk7CisJCSAgICByZXR1cm4gbnVsbDsKKwkJfQorCSAgICB9KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGFjY2VzcyBjb250cm9sIGxpc3QgZW50cmllcyBmb3IgdGhpcyBmb2xkZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCWFycmF5IG9mIGFjY2VzcyBjb250cm9sIGxpc3QgZW50cmllcworICAgICAqIEBleGNlcHRpb24gTWVzc2FnaW5nRXhjZXB0aW9uCWlmIHRoZSBzZXJ2ZXIgZG9lc24ndCBzdXBwb3J0IHRoZQorICAgICAqCQkJCQlBQ0wgZXh0ZW5zaW9uCisgICAgICovCisgICAgcHVibGljIEFDTFtdIGdldEFDTCgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXJldHVybiAoQUNMW10pZG9PcHRpb25hbENvbW1hbmQoIkFDTCBub3Qgc3VwcG9ydGVkIiwKKwkgICAgbmV3IFByb3RvY29sQ29tbWFuZCgpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyBPYmplY3QgZG9Db21tYW5kKElNQVBQcm90b2NvbCBwKQorCQkJdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKwkJICAgIHJldHVybiBwLmdldEFDTChmdWxsTmFtZSk7CisJCX0KKwkgICAgfSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkIGFuIGFjY2VzcyBjb250cm9sIGxpc3QgZW50cnkgdG8gdGhlIGFjY2VzcyBjb250cm9sIGxpc3QKKyAgICAgKiBmb3IgdGhpcyBmb2xkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0JYWNsCXRoZSBhY2Nlc3MgY29udHJvbCBsaXN0IGVudHJ5IHRvIGFkZAorICAgICAqIEBleGNlcHRpb24gTWVzc2FnaW5nRXhjZXB0aW9uCWlmIHRoZSBzZXJ2ZXIgZG9lc24ndCBzdXBwb3J0IHRoZQorICAgICAqCQkJCQlBQ0wgZXh0ZW5zaW9uCisgICAgICovCisgICAgcHVibGljIHZvaWQgYWRkQUNMKEFDTCBhY2wpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXNldEFDTChhY2wsICdcMCcpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZSBhbnkgYWNjZXNzIGNvbnRyb2wgbGlzdCBlbnRyeSBmb3IgdGhlIGdpdmVuIGlkZW50aWZpZXIKKyAgICAgKiBmcm9tIHRoZSBhY2Nlc3MgY29udHJvbCBsaXN0IGZvciB0aGlzIGZvbGRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbQluYW1lCXRoZSBpZGVudGlmaWVyIGZvciB3aGljaCB0byByZW1vdmUgYWxsIEFDTCBlbnRyaWVzCisgICAgICogQGV4Y2VwdGlvbiBNZXNzYWdpbmdFeGNlcHRpb24JaWYgdGhlIHNlcnZlciBkb2Vzbid0IHN1cHBvcnQgdGhlCisgICAgICoJCQkJCUFDTCBleHRlbnNpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZW1vdmVBQ0woZmluYWwgU3RyaW5nIG5hbWUpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWRvT3B0aW9uYWxDb21tYW5kKCJBQ0wgbm90IHN1cHBvcnRlZCIsCisJICAgIG5ldyBQcm90b2NvbENvbW1hbmQoKSB7CisJCUBPdmVycmlkZQorCQlwdWJsaWMgT2JqZWN0IGRvQ29tbWFuZChJTUFQUHJvdG9jb2wgcCkKKwkJCXRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJCSAgICBwLmRlbGV0ZUFDTChmdWxsTmFtZSwgbmFtZSk7CisJCSAgICByZXR1cm4gbnVsbDsKKwkJfQorCSAgICB9KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGQgdGhlIHJpZ2h0cyBzcGVjaWZpZWQgaW4gdGhlIEFDTCB0byB0aGUgZW50cnkgZm9yIHRoZQorICAgICAqIGlkZW50aWZpZXIgc3BlY2lmaWVkIGluIHRoZSBBQ0wuICBJZiBhbiBlbnRyeSBmb3IgdGhlIGlkZW50aWZpZXIKKyAgICAgKiBkb2Vzbid0IGFscmVhZHkgZXhpc3QsIGFkZCBvbmUuCisgICAgICoKKyAgICAgKiBAcGFyYW0JYWNsCXRoZSBpZGVudGlmZXIgYW5kIHJpZ2h0cyB0byBhZGQKKyAgICAgKiBAZXhjZXB0aW9uIE1lc3NhZ2luZ0V4Y2VwdGlvbglpZiB0aGUgc2VydmVyIGRvZXNuJ3Qgc3VwcG9ydCB0aGUKKyAgICAgKgkJCQkJQUNMIGV4dGVuc2lvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFkZFJpZ2h0cyhBQ0wgYWNsKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlzZXRBQ0woYWNsLCAnKycpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZSB0aGUgcmlnaHRzIHNwZWNpZmllZCBpbiB0aGUgQUNMIGZyb20gdGhlIGVudHJ5IGZvciB0aGUKKyAgICAgKiBpZGVudGlmaWVyIHNwZWNpZmllZCBpbiB0aGUgQUNMLgorICAgICAqCisgICAgICogQHBhcmFtCWFjbAl0aGUgaWRlbnRpZmVyIGFuZCByaWdodHMgdG8gcmVtb3ZlCisgICAgICogQGV4Y2VwdGlvbiBNZXNzYWdpbmdFeGNlcHRpb24JaWYgdGhlIHNlcnZlciBkb2Vzbid0IHN1cHBvcnQgdGhlCisgICAgICoJCQkJCUFDTCBleHRlbnNpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZW1vdmVSaWdodHMoQUNMIGFjbCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJc2V0QUNMKGFjbCwgJy0nKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgYWxsIHRoZSByaWdodHMgdGhhdCBtYXkgYmUgYWxsb3dlZCB0byB0aGUgZ2l2ZW4gaWRlbnRpZmllci4KKyAgICAgKiBSaWdodHMgYXJlIGdyb3VwZWQgcGVyIFJGQyAyMDg2IGFuZCBlYWNoIGdyb3VwIGlzIHJldHVybmVkIGFzIGFuCisgICAgICogZWxlbWVudCBvZiB0aGUgYXJyYXkuICBUaGUgZmlyc3QgZWxlbWVudCBvZiB0aGUgYXJyYXkgaXMgdGhlIHNldAorICAgICAqIG9mIHJpZ2h0cyB0aGF0IGFyZSBhbHdheXMgZ3JhbnRlZCB0byB0aGUgaWRlbnRpZmllci4gIExhdGVyCisgICAgICogZWxlbWVudHMgYXJlIHJpZ2h0cyB0aGF0IG1heSBiZSBvcHRpb25hbGx5IGdyYW50ZWQgdG8gdGhlCisgICAgICogaWRlbnRpZmllci4gPHA+CisgICAgICoKKyAgICAgKiBOb3RlIHRoYXQgdGhpcyBtZXRob2QgbGlzdHMgdGhlIHJpZ2h0cyB0aGF0IGl0IGlzIHBvc3NpYmxlIHRvCisgICAgICogYXNzaWduIHRvIHRoZSBnaXZlbiBpZGVudGlmaWVyLCA8ZW0+bm90PC9lbT4gdGhlIHJpZ2h0cyB0aGF0IGFyZQorICAgICAqIGFjdHVhbGx5IGdyYW50ZWQgdG8gdGhlIGdpdmVuIGlkZW50aWZpZXIuICBGb3IgdGhlIGxhdHRlciwgc2VlCisgICAgICogdGhlIDxjb2RlPmdldEFDTDwvY29kZT4gbWV0aG9kLgorICAgICAqCisgICAgICogQHBhcmFtCW5hbWUJdGhlIGlkZW50aWZpZXIgdG8gbGlzdCByaWdodHMgZm9yCisgICAgICogQHJldHVybgkJYXJyYXkgb2YgUmlnaHRzIG9iamVjdHMgcmVwcmVzZW50aW5nIHBvc3NpYmxlCisgICAgICoJCQlyaWdodHMgZm9yIHRoZSBpZGVudGlmaWVyCisgICAgICogQGV4Y2VwdGlvbiBNZXNzYWdpbmdFeGNlcHRpb24JaWYgdGhlIHNlcnZlciBkb2Vzbid0IHN1cHBvcnQgdGhlCisgICAgICoJCQkJCUFDTCBleHRlbnNpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgUmlnaHRzW10gbGlzdFJpZ2h0cyhmaW5hbCBTdHJpbmcgbmFtZSkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJcmV0dXJuIChSaWdodHNbXSlkb09wdGlvbmFsQ29tbWFuZCgiQUNMIG5vdCBzdXBwb3J0ZWQiLAorCSAgICBuZXcgUHJvdG9jb2xDb21tYW5kKCkgeworCQlAT3ZlcnJpZGUKKwkJcHVibGljIE9iamVjdCBkb0NvbW1hbmQoSU1BUFByb3RvY29sIHApCisJCQl0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCQkgICAgcmV0dXJuIHAubGlzdFJpZ2h0cyhmdWxsTmFtZSwgbmFtZSk7CisJCX0KKwkgICAgfSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSByaWdodHMgYWxsb3dlZCB0byB0aGUgY3VycmVudGx5IGF1dGhlbnRpY2F0ZWQgdXNlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIHJpZ2h0cyBncmFudGVkIHRvIHRoZSBjdXJyZW50IHVzZXIKKyAgICAgKiBAZXhjZXB0aW9uIE1lc3NhZ2luZ0V4Y2VwdGlvbglpZiB0aGUgc2VydmVyIGRvZXNuJ3Qgc3VwcG9ydCB0aGUKKyAgICAgKgkJCQkJQUNMIGV4dGVuc2lvbgorICAgICAqLworICAgIHB1YmxpYyBSaWdodHMgbXlSaWdodHMoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gKFJpZ2h0cylkb09wdGlvbmFsQ29tbWFuZCgiQUNMIG5vdCBzdXBwb3J0ZWQiLAorCSAgICBuZXcgUHJvdG9jb2xDb21tYW5kKCkgeworCQlAT3ZlcnJpZGUKKwkJcHVibGljIE9iamVjdCBkb0NvbW1hbmQoSU1BUFByb3RvY29sIHApCisJCQl0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCQkgICAgcmV0dXJuIHAubXlSaWdodHMoZnVsbE5hbWUpOworCQl9CisJICAgIH0pOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBzZXRBQ0woZmluYWwgQUNMIGFjbCwgZmluYWwgY2hhciBtb2QpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJZG9PcHRpb25hbENvbW1hbmQoIkFDTCBub3Qgc3VwcG9ydGVkIiwKKwkgICAgbmV3IFByb3RvY29sQ29tbWFuZCgpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyBPYmplY3QgZG9Db21tYW5kKElNQVBQcm90b2NvbCBwKQorCQkJdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKwkJICAgIHAuc2V0QUNMKGZ1bGxOYW1lLCBtb2QsIGFjbCk7CisJCSAgICByZXR1cm4gbnVsbDsKKwkJfQorCSAgICB9KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGF0dHJpYnV0ZXMgdGhhdCB0aGUgSU1BUCBzZXJ2ZXIgcmV0dXJucyB3aXRoIHRoZQorICAgICAqIExJU1QgcmVzcG9uc2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCWFycmF5IG9mIGF0dHJpYnV0ZXMgZm9yIHRoaXMgZm9sZGVyCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuMy4zCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBTdHJpbmdbXSBnZXRBdHRyaWJ1dGVzKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJY2hlY2tFeGlzdHMoKTsKKwlpZiAoYXR0cmlidXRlcyA9PSBudWxsKQorCSAgICBleGlzdHMoKTsJCS8vIGRvIGEgTElTVCB0byBzZXQgdGhlIGF0dHJpYnV0ZXMKKwlyZXR1cm4gYXR0cmlidXRlcyA9PSBudWxsID8gbmV3IFN0cmluZ1swXSA6IGF0dHJpYnV0ZXMuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVc2UgdGhlIElNQVAgSURMRSBjb21tYW5kIChzZWUKKyAgICAgKiA8QSBIUkVGPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMTc3LnR4dCI+UkZDIDIxNzc8L0E+KSwKKyAgICAgKiBpZiBzdXBwb3J0ZWQgYnkgdGhlIHNlcnZlciwgdG8gZW50ZXIgaWRsZSBtb2RlIHNvIHRoYXQgdGhlIHNlcnZlcgorICAgICAqIGNhbiBzZW5kIHVuc29saWNpdGVkIG5vdGlmaWNhdGlvbnMgb2YgbmV3IG1lc3NhZ2VzIGFycml2aW5nLCBldGMuCisgICAgICogd2l0aG91dCB0aGUgbmVlZCBmb3IgdGhlIGNsaWVudCB0byBjb25zdGFudGx5IHBvbGwgdGhlIHNlcnZlci4KKyAgICAgKiBVc2UgYW4gYXBwcm9wcmlhdGUgbGlzdGVuZXIgdG8gYmUgbm90aWZpZWQgb2YgbmV3IG1lc3NhZ2VzIG9yCisgICAgICogb3RoZXIgZXZlbnRzLiAgV2hlbiBhbm90aGVyIHRocmVhZCAoZS5nLiwgdGhlIGxpc3RlbmVyIHRocmVhZCkKKyAgICAgKiBuZWVkcyB0byBpc3N1ZSBhbiBJTUFQIGNvbWFuZCBmb3IgdGhpcyBmb2xkZXIsIHRoZSBpZGxlIG1vZGUgd2lsbAorICAgICAqIGJlIHRlcm1pbmF0ZWQgYW5kIHRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuLiAgVHlwaWNhbGx5IHRoZSBjYWxsZXIKKyAgICAgKiB3aWxsIGludm9rZSB0aGlzIG1ldGhvZCBpbiBhIGxvb3AuIDxwPgorICAgICAqCisgICAgICogVGhlIG1haWwuaW1hcC5taW5pZGxldGltZSBwcm9wZXJ0eSBlbmZvcmNlcyBhIG1pbmltdW0gZGVsYXkKKyAgICAgKiBiZWZvcmUgcmV0dXJuaW5nIGZyb20gdGhpcyBtZXRob2QsIHRvIGVuc3VyZSB0aGF0IG90aGVyIHRocmVhZHMKKyAgICAgKiBoYXZlIGEgY2hhbmNlIHRvIGlzc3VlIGNvbW1hbmRzIGJlZm9yZSB0aGUgY2FsbGVyIGludm9rZXMgdGhpcworICAgICAqIG1ldGhvZCBhZ2Fpbi4gIFRoZSBkZWZhdWx0IGRlbGF5IGlzIDEwIG1pbGxpc2Vjb25kcy4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24gTWVzc2FnaW5nRXhjZXB0aW9uCWlmIHRoZSBzZXJ2ZXIgZG9lc24ndCBzdXBwb3J0IHRoZQorICAgICAqCQkJCQlJRExFIGV4dGVuc2lvbgorICAgICAqIEBleGNlcHRpb24gSWxsZWdhbFN0YXRlRXhjZXB0aW9uCWlmIHRoZSBmb2xkZXIgaXNuJ3Qgb3BlbgorICAgICAqCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNC4xCisgICAgICovCisgICAgcHVibGljIHZvaWQgaWRsZSgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWlkbGUoZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIExpa2Uge0BsaW5rICNpZGxlfSwgYnV0IGlmIDxjb2RlPm9uY2U8L2NvZGU+IGlzIHRydWUsIGFib3J0IHRoZQorICAgICAqIElETEUgY29tbWFuZCBhZnRlciB0aGUgZmlyc3Qgbm90aWZpY2F0aW9uLCB0byBhbGxvdyB0aGUgY2FsbGVyCisgICAgICogdG8gcHJvY2VzcyBhbnkgbm90aWZpY2F0aW9uIHN5bmNocm9ub3VzbHkuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jb25jZQlvbmx5IGRvIG9uZSBub3RpZmljYXRpb24/CisgICAgICogQGV4Y2VwdGlvbiBNZXNzYWdpbmdFeGNlcHRpb24JaWYgdGhlIHNlcnZlciBkb2Vzbid0IHN1cHBvcnQgdGhlCisgICAgICoJCQkJCUlETEUgZXh0ZW5zaW9uCisgICAgICogQGV4Y2VwdGlvbiBJbGxlZ2FsU3RhdGVFeGNlcHRpb24JaWYgdGhlIGZvbGRlciBpc24ndCBvcGVuCisgICAgICoKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS40LjMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBpZGxlKGJvb2xlYW4gb25jZSkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJc3luY2hyb25pemVkICh0aGlzKSB7CisJICAgIC8qCisJICAgICAqIFdlIGNhbid0IHN1cHBvcnQgdGhlIGlkbGUgbWV0aG9kIGlmIHdlJ3JlIHVzaW5nIFNvY2tldENoYW5uZWxzCisJICAgICAqIGJlY2F1c2UgU29ja2V0Q2hhbm5lbHMgZG9uJ3QgYWxsb3cgc2ltdWx0YW5lb3VzIHJlYWQgYW5kIHdyaXRlLgorCSAgICAgKiBJZiB3ZSdyZSBibG9ja2VkIGluIGEgcmVhZCB3YWl0aW5nIGZvciBJRExFIHJlc3BvbnNlcywgd2UgY2FuJ3QKKwkgICAgICogc2VuZCB0aGUgRE9ORSBtZXNzYWdlIHRvIGFib3J0IHRoZSBJRExFLiAgU2lnaC4KKwkgICAgICogWFhYIC0gV2UgY291bGQgZG8gc2VsZWN0IGhlcmUgdG9vLCBsaWtlIElkbGVNYW5hZ2VyLCBpbnN0ZWFkCisJICAgICAqIG9mIGJsb2NraW5nIGluIHJlYWQsIGJ1dCB0aGF0J3MgbW9yZSBjb21wbGljYXRlZC4KKwkgICAgICovCisJICAgIGlmIChwcm90b2NvbCAhPSBudWxsICYmIHByb3RvY29sLmdldENoYW5uZWwoKSAhPSBudWxsKQorCQl0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKAorCQkJICAgICJpZGxlIG1ldGhvZCBub3Qgc3VwcG9ydGVkIHdpdGggU29ja2V0Q2hhbm5lbHMiKTsKKwl9CisJaWYgKCFzdGFydElkbGUobnVsbCkpCisJICAgIHJldHVybjsKKworCS8qCisJICogV2UgZ2F2ZSB1cCB0aGUgZm9sZGVyIGxvY2sgc28gdGhhdCBvdGhlciB0aHJlYWRzCisJICogY2FuIGdldCBpbnRvIHRoZSBmb2xkZXIgZmFyIGVub3VnaCB0byBzZWUgdGhhdCB3ZSdyZQorCSAqIGluIElETEUgYW5kIGFib3J0IHRoZSBJRExFLgorCSAqCisJICogTm93IHdlIHJlYWQgcmVzcG9uc2VzIGZyb20gdGhlIElETEUgY29tbWFuZCwgZXNwZWNpYWxseQorCSAqIGluY2x1ZGluZyB1bnNvbGljaXRlZCBub3RpZmljYXRpb25zIGZyb20gdGhlIHNlcnZlci4KKwkgKiBXZSBkb24ndCBob2xkIHRoZSBtZXNzYWdlQ2FjaGVMb2NrIHdoaWxlIHJlYWRpbmcgYmVjYXVzZQorCSAqIGl0IHByb3RlY3RzIHRoZSBpZGxlU3RhdGUgYW5kIG90aGVyIHRocmVhZHMgbmVlZCB0byBiZQorCSAqIGFibGUgdG8gZXhhbWluZSB0aGUgc3RhdGUuCisJICoKKwkgKiBUaGUgbWVzc2FnZUNhY2hlTG9jayBpcyBoZWxkIGluIGhhbmRsZUlkbGUgd2hpbGUgcHJvY2Vzc2luZworCSAqIHRoZSByZXNwb25zZXMgc28gdGhhdCB3ZSBjYW4gdXBkYXRlIHRoZSBudW1iZXIgb2YgbWVzc2FnZXMKKwkgKiBpbiB0aGUgZm9sZGVyIChmb3IgZXhhbXBsZSkuCisJICovCisJZm9yICg7OykgeworCSAgICBpZiAoIWhhbmRsZUlkbGUob25jZSkpCisJCWJyZWFrOworCX0KKworCS8qCisJICogRW5mb3JjZSBhIG1pbmltdW0gZGVsYXkgdG8gZ2l2ZSB0aW1lIHRvIHRocmVhZHMKKwkgKiBwcm9jZXNzaW5nIHRoZSByZXNwb25zZXMgdGhhdCBjYW1lIGluIHdoaWxlIHdlCisJICogd2VyZSBpZGxlLgorCSAqLworCWludCBtaW5pZGxlID0gKChJTUFQU3RvcmUpc3RvcmUpLmdldE1pbklkbGVUaW1lKCk7CisJaWYgKG1pbmlkbGUgPiAwKSB7CisJICAgIHRyeSB7CisJCVRocmVhZC5zbGVlcChtaW5pZGxlKTsKKwkgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZXgpIHsKKwkJLy8gcmVzdG9yZSB0aGUgaW50ZXJydXB0ZWQgc3RhdGUsIHdoaWNoIGNhbGxlcnMgbWlnaHQgZGVwZW5kIG9uCisJCVRocmVhZC5jdXJyZW50VGhyZWFkKCkuaW50ZXJydXB0KCk7CisJICAgIH0KKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogU3RhcnQgdGhlIElETEUgY29tbWFuZCBhbmQgcHV0IHRoaXMgZm9sZGVyIGludG8gdGhlIElETEUgc3RhdGUuCisgICAgICogSURMRSBwcm9jZXNzaW5nIGlzIGRvbmUgbGF0ZXIgaW4gaGFuZGxlSWRsZSgpLCBlLmcuLCBjYWxsZWQgZnJvbQorICAgICAqIHRoZSBJZGxlTWFuYWdlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdHJ1ZSBpZiBJRExFIHN0YXJ0ZWQsIGZhbHNlIG90aGVyd2lzZQorICAgICAqIEBleGNlcHRpb24gTWVzc2FnaW5nRXhjZXB0aW9uCWlmIHRoZSBzZXJ2ZXIgZG9lc24ndCBzdXBwb3J0IHRoZQorICAgICAqCQkJCQlJRExFIGV4dGVuc2lvbgorICAgICAqIEBleGNlcHRpb24gSWxsZWdhbFN0YXRlRXhjZXB0aW9uCWlmIHRoZSBmb2xkZXIgaXNuJ3Qgb3BlbgorICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjUuMgorICAgICAqLworICAgIGJvb2xlYW4gc3RhcnRJZGxlKGZpbmFsIElkbGVNYW5hZ2VyIGltKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwkvLyBBU1NFUlQ6IE11c3QgTk9UIGJlIGNhbGxlZCB3aXRoIHRoaXMgZm9sZGVyJ3MKKwkvLyBzeW5jaHJvbml6YXRpb24gbG9jayBoZWxkLgorCWFzc2VydCAhVGhyZWFkLmhvbGRzTG9jayh0aGlzKTsKKwlzeW5jaHJvbml6ZWQodGhpcykgeworCSAgICBjaGVja09wZW5lZCgpOworCSAgICBpZiAoaW0gIT0gbnVsbCAmJiBpZGxlTWFuYWdlciAhPSBudWxsICYmIGltICE9IGlkbGVNYW5hZ2VyKQorCQl0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKAorCQkgICAgIkZvbGRlciBhbHJlYWR5IGJlaW5nIHdhdGNoZWQgYnkgYW5vdGhlciBJZGxlTWFuYWdlciIpOworCSAgICBCb29sZWFuIHN0YXJ0ZWQgPSAoQm9vbGVhbilkb09wdGlvbmFsQ29tbWFuZCgiSURMRSBub3Qgc3VwcG9ydGVkIiwKKwkJbmV3IFByb3RvY29sQ29tbWFuZCgpIHsKKwkJICAgIEBPdmVycmlkZQorCQkgICAgcHVibGljIE9iamVjdCBkb0NvbW1hbmQoSU1BUFByb3RvY29sIHApCisJCQkgICAgdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKwkJCS8vIGlmIHRoZSBJZGxlTWFuYWdlciBpcyBhbHJlYWR5IHdhdGNoaW5nIHRoaXMgZm9sZGVyLAorCQkJLy8gdGhlcmUncyBub3RoaW5nIHRvIGRvIGhlcmUKKwkJCWlmIChpZGxlU3RhdGUgPT0gSURMRSAmJgorCQkJCWltICE9IG51bGwgJiYgaW0gPT0gaWRsZU1hbmFnZXIpCisJCQkgICAgcmV0dXJuIEJvb2xlYW4uVFJVRTsJLy8gYWxyZWFkeSB3YXRjaGluZyBpdAorCQkJaWYgKGlkbGVTdGF0ZSA9PSBSVU5OSU5HKSB7CisJCQkgICAgcC5pZGxlU3RhcnQoKTsKKwkJCSAgICBsb2dnZXIuZmluZXN0KCJzdGFydElkbGU6IHNldCB0byBJRExFIik7CisJCQkgICAgaWRsZVN0YXRlID0gSURMRTsKKwkJCSAgICBpZGxlTWFuYWdlciA9IGltOworCQkJICAgIHJldHVybiBCb29sZWFuLlRSVUU7CisJCQl9IGVsc2UgeworCQkJICAgIC8vIHNvbWUgb3RoZXIgdGhyZWFkIG11c3QgYmUgcnVubmluZyB0aGUgSURMRQorCQkJICAgIC8vIGNvbW1hbmQsIHdlJ2xsIGp1c3Qgd2FpdCBmb3IgaXQgdG8gZmluaXNoCisJCQkgICAgLy8gd2l0aG91dCBhYm9ydGluZyBpdCBvdXJzZWx2ZXMKKwkJCSAgICB0cnkgeworCQkJCS8vIGdpdmUgdXAgbG9jayBhbmQgd2FpdCB0byBiZSBub3QgaWRsZQorCQkJCW1lc3NhZ2VDYWNoZUxvY2sud2FpdCgpOworCQkJICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGV4KSB7CisJCQkJLy8gcmVzdG9yZSB0aGUgaW50ZXJydXB0ZWQgc3RhdGUsIHdoaWNoIGNhbGxlcnMKKwkJCQkvLyBtaWdodCBkZXBlbmQgb24KKwkJCQlUaHJlYWQuY3VycmVudFRocmVhZCgpLmludGVycnVwdCgpOworCQkJICAgIH0KKwkJCSAgICByZXR1cm4gQm9vbGVhbi5GQUxTRTsKKwkJCX0KKwkJICAgIH0KKwkJfSk7CisJICAgIGxvZ2dlci5sb2coTGV2ZWwuRklORVNULCAic3RhcnRJZGxlOiByZXR1cm4gezB9Iiwgc3RhcnRlZCk7CisJICAgIHJldHVybiBzdGFydGVkLmJvb2xlYW5WYWx1ZSgpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkIGEgcmVzcG9uc2UgZnJvbSB0aGUgc2VydmVyIHdoaWxlIHdlJ3JlIGluIHRoZSBJRExFIHN0YXRlLgorICAgICAqIFdlIGhvbGQgdGhlIG1lc3NhZ2VDYWNoZUxvY2sgd2hpbGUgcHJvY2Vzc2luZyB0aGUKKyAgICAgKiByZXNwb25zZXMgc28gdGhhdCB3ZSBjYW4gdXBkYXRlIHRoZSBudW1iZXIgb2YgbWVzc2FnZXMKKyAgICAgKiBpbiB0aGUgZm9sZGVyIChmb3IgZXhhbXBsZSkuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jb25jZQlvbmx5IGRvIG9uZSBub3RpZmljYXRpb24/CisgICAgICogQHJldHVybgl0cnVlIGlmIHdlIHNob3VsZCBsb29rIGZvciBtb3JlIElETEUgcmVzcG9uc2VzLAorICAgICAqCQlmYWxzZSBpZiBJRExFIGlzIGRvbmUKKyAgICAgKiBAZXhjZXB0aW9uIE1lc3NhZ2luZ0V4Y2VwdGlvbglmb3IgZXJyb3JzCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNS4yCisgICAgICovCisgICAgYm9vbGVhbiBoYW5kbGVJZGxlKGJvb2xlYW4gb25jZSkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJUmVzcG9uc2UgciA9IG51bGw7CisJZG8geworCSAgICByID0gcHJvdG9jb2wucmVhZElkbGVSZXNwb25zZSgpOworCSAgICB0cnkgeworCQlzeW5jaHJvbml6ZWQgKG1lc3NhZ2VDYWNoZUxvY2spIHsKKwkJICAgIGlmIChyLmlzQllFKCkgJiYgci5pc1N5bnRoZXRpYygpICYmIGlkbGVTdGF0ZSA9PSBJRExFKSB7CisJCQkvKgorCQkJICogSWYgaXQgd2FzIGEgdGltZW91dCBhbmQgbm8gYnl0ZXMgd2VyZSB0cmFuc2ZlcnJlZAorCQkJICogd2UgaWdub3JlIGl0IGFuZCBnbyBiYWNrIGFuZCByZWFkIGFnYWluLgorCQkJICogSWYgdGhlIEkvTyB3YXMgb3RoZXJ3aXNlIGludGVycnVwdGVkLCBhbmQgbm8KKwkJCSAqIGJ5dGVzIHdlcmUgdHJhbnNmZXJyZWQsIHdlIHRha2UgaXQgYXMgYSByZXF1ZXN0CisJCQkgKiB0byBhYm9ydCB0aGUgSURMRS4KKwkJCSAqLworCQkJRXhjZXB0aW9uIGV4ID0gci5nZXRFeGNlcHRpb24oKTsKKwkJCWlmIChleCBpbnN0YW5jZW9mIEludGVycnVwdGVkSU9FeGNlcHRpb24gJiYKKwkJCSAgICAoKEludGVycnVwdGVkSU9FeGNlcHRpb24pZXgpLgorCQkJCSAgICBieXRlc1RyYW5zZmVycmVkID09IDApIHsKKwkJCSAgICBpZiAoZXggaW5zdGFuY2VvZiBTb2NrZXRUaW1lb3V0RXhjZXB0aW9uKSB7CisJCQkJbG9nZ2VyLmZpbmVzdCgKKwkJCQkgICAgImhhbmRsZUlkbGU6IGlnbm9yaW5nIHNvY2tldCB0aW1lb3V0Iik7CisJCQkJciA9IG51bGw7CS8vIHJlcGVhdCBkby93aGlsZSBsb29wCisJCQkgICAgfSBlbHNlIHsKKwkJCQlsb2dnZXIuZmluZXN0KCJoYW5kbGVJZGxlOiBpbnRlcnJ1cHRpbmcgSURMRSIpOworCQkJCUlkbGVNYW5hZ2VyIGltID0gaWRsZU1hbmFnZXI7CisJCQkJaWYgKGltICE9IG51bGwpIHsKKwkJCQkgICAgbG9nZ2VyLmZpbmVzdCgKKwkJCQkgICAgImhhbmRsZUlkbGU6IHJlcXVlc3QgSWRsZU1hbmFnZXIgdG8gYWJvcnQiKTsKKwkJCQkgICAgaW0ucmVxdWVzdEFib3J0KHRoaXMpOworCQkJCX0gZWxzZSB7CisJCQkJICAgIGxvZ2dlci5maW5lc3QoImhhbmRsZUlkbGU6IGFib3J0IElETEUiKTsKKwkJCQkgICAgcHJvdG9jb2wuaWRsZUFib3J0KCk7CisJCQkJICAgIGlkbGVTdGF0ZSA9IEFCT1JUSU5HOworCQkJCX0KKwkJCQkvLyBub3JtYWxseSB3aWxsIGV4aXQgdGhlIGRvL3doaWxlIGxvb3AKKwkJCSAgICB9CisJCQkgICAgY29udGludWU7CisJCQl9CisJCSAgICB9CisJCSAgICBib29sZWFuIGRvbmUgPSB0cnVlOworCQkgICAgdHJ5IHsKKwkJCWlmIChwcm90b2NvbCA9PSBudWxsIHx8CisJCQkJIXByb3RvY29sLnByb2Nlc3NJZGxlUmVzcG9uc2UocikpCisJCQkgICAgcmV0dXJuIGZhbHNlOwkvLyBkb25lCisJCQlkb25lID0gZmFsc2U7CisJCSAgICB9IGZpbmFsbHkgeworCQkJaWYgKGRvbmUpIHsKKwkJCSAgICBsb2dnZXIuZmluZXN0KCJoYW5kbGVJZGxlOiBzZXQgdG8gUlVOTklORyIpOworCQkJICAgIGlkbGVTdGF0ZSA9IFJVTk5JTkc7CisJCQkgICAgaWRsZU1hbmFnZXIgPSBudWxsOworCQkJICAgIG1lc3NhZ2VDYWNoZUxvY2subm90aWZ5QWxsKCk7CisJCQl9CisJCSAgICB9CisJCSAgICBpZiAob25jZSkgeworCQkJaWYgKGlkbGVTdGF0ZSA9PSBJRExFKSB7CisJCQkgICAgdHJ5IHsKKwkJCQlwcm90b2NvbC5pZGxlQWJvcnQoKTsKKwkJCSAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKwkJCQkvLyBpZ25vcmUgYW55IGZhaWx1cmVzLCBzdGlsbCBoYXZlIHRvIGFib3J0LgorCQkJCS8vIGNvbm5lY3Rpb24gZmFpbHVyZXMgd2lsbCBiZSBkZXRlY3RlZCBhYm92ZQorCQkJCS8vIGluIHRoZSBjYWxsIHRvIHJlYWRJZGxlUmVzcG9uc2UuCisJCQkgICAgfQorCQkJICAgIGlkbGVTdGF0ZSA9IEFCT1JUSU5HOworCQkJfQorCQkgICAgfQorCQl9CisJICAgIH0gY2F0Y2ggKENvbm5lY3Rpb25FeGNlcHRpb24gY2V4KSB7CisJCS8vIE9vcHMsIHRoZSBmb2xkZXIgZGllZCBvbiB1cy4KKwkJdGhyb3cgbmV3IEZvbGRlckNsb3NlZEV4Y2VwdGlvbih0aGlzLCBjZXguZ2V0TWVzc2FnZSgpKTsKKwkgICAgfSBjYXRjaCAoUHJvdG9jb2xFeGNlcHRpb24gcGV4KSB7CisJCXRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24ocGV4LmdldE1lc3NhZ2UoKSwgcGV4KTsKKwkgICAgfQorCS8vIGtlZXAgcHJvY2Vzc2luZyByZXNwb25zZXMgYWxyZWFkeSBpbiBvdXIgYnVmZmVyCisJfSB3aGlsZSAociA9PSBudWxsIHx8IHByb3RvY29sLmhhc1Jlc3BvbnNlKCkpOworCXJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qCisgICAgICogSWYgYW4gSURMRSBjb21tYW5kIGlzIGluIHByb2dyZXNzLCBhYm9ydCBpdCBpZiBuZWNlc3NhcnksCisgICAgICogYW5kIHdhaXQgdW50aWwgaXQgY29tcGxldGVzLgorICAgICAqIEFTU0VSVDogTXVzdCBiZSBjYWxsZWQgd2l0aCB0aGUgbWVzc2FnZSBjYWNoZSBsb2NrIGhlbGQuCisgICAgICovCisgICAgdm9pZCB3YWl0SWZJZGxlKCkgdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKwlhc3NlcnQgVGhyZWFkLmhvbGRzTG9jayhtZXNzYWdlQ2FjaGVMb2NrKTsKKwl3aGlsZSAoaWRsZVN0YXRlICE9IFJVTk5JTkcpIHsKKwkgICAgaWYgKGlkbGVTdGF0ZSA9PSBJRExFKSB7CisJCUlkbGVNYW5hZ2VyIGltID0gaWRsZU1hbmFnZXI7CisJCWlmIChpbSAhPSBudWxsKSB7CisJCSAgICBsb2dnZXIuZmluZXN0KCJ3YWl0SWZJZGxlOiByZXF1ZXN0IElkbGVNYW5hZ2VyIHRvIGFib3J0Iik7CisJCSAgICBpbS5yZXF1ZXN0QWJvcnQodGhpcyk7CisJCX0gZWxzZSB7CisJCSAgICBsb2dnZXIuZmluZXN0KCJ3YWl0SWZJZGxlOiBhYm9ydCBJRExFIik7CisJCSAgICBwcm90b2NvbC5pZGxlQWJvcnQoKTsKKwkJICAgIGlkbGVTdGF0ZSA9IEFCT1JUSU5HOworCQl9CisJICAgIH0gZWxzZQorCQlsb2dnZXIubG9nKExldmVsLkZJTkVTVCwgIndhaXRJZklkbGU6IGlkbGVTdGF0ZSB7MH0iLCBpZGxlU3RhdGUpOworCSAgICB0cnkgeworCQkvLyBnaXZlIHVwIGxvY2sgYW5kIHdhaXQgdG8gYmUgbm90IGlkbGUKKwkJaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkVTVCkpCisJCSAgICBsb2dnZXIuZmluZXN0KCJ3YWl0SWZJZGxlOiB3YWl0IHRvIGJlIG5vdCBpZGxlOiAiICsKKwkJCQkgICAgVGhyZWFkLmN1cnJlbnRUaHJlYWQoKSk7CisJCW1lc3NhZ2VDYWNoZUxvY2sud2FpdCgpOworCQlpZiAobG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuRklORVNUKSkKKwkJICAgIGxvZ2dlci5maW5lc3QoIndhaXRJZklkbGU6IHdhaXQgZG9uZSwgaWRsZVN0YXRlICIgKworCQkJCSAgICBpZGxlU3RhdGUgKyAiOiAiICsgVGhyZWFkLmN1cnJlbnRUaHJlYWQoKSk7CisJICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGV4KSB7CisJCS8vIHJlc3RvcmUgdGhlIGludGVycnVwdGVkIHN0YXRlLCB3aGljaCBjYWxsZXJzIG1pZ2h0IGRlcGVuZCBvbgorCQlUaHJlYWQuY3VycmVudFRocmVhZCgpLmludGVycnVwdCgpOworCQkvLyBJZiBzb21lb25lIGlzIHRyeWluZyB0byBpbnRlcnJ1cHQgdXMgd2UgY2FuJ3Qga2VlcCBnb2luZworCQkvLyBhcm91bmQgdGhlIGxvb3Agd2FpdGluZyBmb3IgSURMRSB0byBjb21wbGV0ZSwgYnV0IHdlIGNhbid0CisJCS8vIGp1c3QgcmV0dXJuIGJlY2F1c2UgY2FsbGVycyBleHBlY3QgdGhlIGlkbGVTdGF0ZSB0byBiZQorCQkvLyBSVU5OSU5HIHdoZW4gd2UgcmV0dXJuLiAgVGhyb3dpbmcgdGhpcyBleGNlcHRpb24gc2VlbXMKKwkJLy8gbGlrZSB0aGUgYmVzdCBjaG9pY2UuCisJCXRocm93IG5ldyBQcm90b2NvbEV4Y2VwdGlvbigiSW50ZXJydXB0ZWQgd2FpdElmSWRsZSIsIGV4KTsKKwkgICAgfQorCX0KKyAgICB9CisKKyAgICAvKgorICAgICAqIFNlbmQgdGhlIERPTkUgY29tbWFuZCB0aGF0IGFib3J0cyB0aGUgSURMRTsgdXNlZCBieSBJZGxlTWFuYWdlci4KKyAgICAgKi8KKyAgICB2b2lkIGlkbGVBYm9ydCgpIHsKKwlzeW5jaHJvbml6ZWQgKG1lc3NhZ2VDYWNoZUxvY2spIHsKKwkgICAgaWYgKGlkbGVTdGF0ZSA9PSBJRExFICYmIHByb3RvY29sICE9IG51bGwpIHsKKwkJcHJvdG9jb2wuaWRsZUFib3J0KCk7CisJCWlkbGVTdGF0ZSA9IEFCT1JUSU5HOworCSAgICB9CisJfQorICAgIH0KKworICAgIC8qCisgICAgICogU2VuZCB0aGUgRE9ORSBjb21tYW5kIHRoYXQgYWJvcnRzIHRoZSBJRExFIGFuZCB3YWl0IGZvciB0aGUgcmVzcG9uc2U7CisgICAgICogdXNlZCBieSBJZGxlTWFuYWdlci4KKyAgICAgKi8KKyAgICB2b2lkIGlkbGVBYm9ydFdhaXQoKSB7CisJc3luY2hyb25pemVkIChtZXNzYWdlQ2FjaGVMb2NrKSB7CisJICAgIGlmIChpZGxlU3RhdGUgPT0gSURMRSAmJiBwcm90b2NvbCAhPSBudWxsKSB7CisJCXByb3RvY29sLmlkbGVBYm9ydCgpOworCQlpZGxlU3RhdGUgPSBBQk9SVElORzsKKworCQkvLyByZWFkIHJlc3BvbnNlcyB1bnRpbCBPSyBvciBjb25uZWN0aW9uIGZhaWx1cmUKKwkJdHJ5IHsKKwkJICAgIGZvciAoOzspIHsKKwkJCWlmICghaGFuZGxlSWRsZShmYWxzZSkpCisJCQkgICAgYnJlYWs7CisJCSAgICB9CisJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCQkgICAgLy8gYXNzdW1lIGl0J3MgYSBjb25uZWN0aW9uIGZhaWx1cmU7IG5vdGhpbmcgbW9yZSB0byBkbworCQkgICAgbG9nZ2VyLmxvZyhMZXZlbC5GSU5FU1QsICJFeGNlcHRpb24gaW4gaWRsZUFib3J0V2FpdCIsIGV4KTsKKwkJfQorCQlsb2dnZXIuZmluZXN0KCJJRExFIGFib3J0ZWQiKTsKKwkgICAgfQorCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIFNvY2tldENoYW5uZWwgZm9yIHRoaXMgY29ubmVjdGlvbiwgaWYgYW55LCBmb3IgdXNlCisgICAgICogaW4gSWRsZU1hbmFnZXIuCisgICAgICovCisgICAgU29ja2V0Q2hhbm5lbCBnZXRDaGFubmVsKCkgeworCXJldHVybiBwcm90b2NvbCAhPSBudWxsID8gcHJvdG9jb2wuZ2V0Q2hhbm5lbCgpIDogbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZW5kIHRoZSBJTUFQIElEIGNvbW1hbmQgKGlmIHN1cHBvcnRlZCBieSB0aGUgc2VydmVyKSBhbmQgcmV0dXJuCisgICAgICogdGhlIHJlc3VsdCBmcm9tIHRoZSBzZXJ2ZXIuICBUaGUgSUQgY29tbWFuZCBpZGVudGZpZXMgdGhlIGNsaWVudAorICAgICAqIHRvIHRoZSBzZXJ2ZXIgYW5kIHJldHVybnMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHNlcnZlciB0byB0aGUgY2xpZW50LgorICAgICAqIFNlZSA8QSBIUkVGPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyOTcxLnR4dCI+UkZDIDI5NzE8L0E+LgorICAgICAqIFRoZSByZXR1cm5lZCBNYXAgaXMgdW5tb2RpZmlhYmxlLgorICAgICAqCisgICAgICogQHBhcmFtCWNsaWVudFBhcmFtcwlhIE1hcCBvZiBrZXlzIGFuZCB2YWx1ZXMgaWRlbnRpZnlpbmcgdGhlIGNsaWVudAorICAgICAqIEByZXR1cm4JCQlhIE1hcCBvZiBrZXlzIGFuZCB2YWx1ZXMgaWRlbnRpZnlpbmcgdGhlIHNlcnZlcgorICAgICAqIEBleGNlcHRpb24gTWVzc2FnaW5nRXhjZXB0aW9uCWlmIHRoZSBzZXJ2ZXIgZG9lc24ndCBzdXBwb3J0IHRoZQorICAgICAqCQkJCQlJRCBleHRlbnNpb24KKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS41LjEKKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgTWFwPFN0cmluZywgU3RyaW5nPiBpZChmaW5hbCBNYXA8U3RyaW5nLCBTdHJpbmc+IGNsaWVudFBhcmFtcykKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwljaGVja09wZW5lZCgpOworCXJldHVybiAoTWFwPFN0cmluZyxTdHJpbmc+KWRvT3B0aW9uYWxDb21tYW5kKCJJRCBub3Qgc3VwcG9ydGVkIiwKKwkgICAgbmV3IFByb3RvY29sQ29tbWFuZCgpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyBPYmplY3QgZG9Db21tYW5kKElNQVBQcm90b2NvbCBwKQorCQkJdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKwkJICAgIHJldHVybiBwLmlkKGNsaWVudFBhcmFtcyk7CisJCX0KKwkgICAgfSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVXNlIHRoZSBJTUFQIFNUQVRVUyBjb21tYW5kIHRvIGdldCB0aGUgaW5kaWNhdGVkIGl0ZW0uCisgICAgICogVGhlIFNUQVRVUyBpdGVtIG1heSBiZSBhIHN0YW5kYXJkIGl0ZW0gc3VjaCBhcyAiUkVDRU5UIiBvciAiVU5TRUVOIiwKKyAgICAgKiBvciBtYXkgYmUgYSBzZXJ2ZXItc3BlY2lmaWMgaXRlbS4KKyAgICAgKiBUaGUgZm9sZGVyIG11c3QgYmUgY2xvc2VkLiAgSWYgdGhlIGl0ZW0gaXMgbm90IGZvdW5kLCBvciB0aGUKKyAgICAgKiBmb2xkZXIgaXMgb3BlbiwgLTEgaXMgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0JaXRlbQl0aGUgU1RBVFVTIGl0ZW0gdG8gZmV0Y2gKKyAgICAgKiBAcmV0dXJuCQl0aGUgdmFsdWUgb2YgdGhlIFNUQVRVUyBpdGVtLCBvciAtMQorICAgICAqIEBleGNlcHRpb24gTWVzc2FnaW5nRXhjZXB0aW9uCWZvciBlcnJvcnMKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS41LjIKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGxvbmcgZ2V0U3RhdHVzSXRlbShTdHJpbmcgaXRlbSkKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpZiAoIW9wZW5lZCkgeworCSAgICBjaGVja0V4aXN0cygpOworCisJICAgIElNQVBQcm90b2NvbCBwID0gbnVsbDsKKwkgICAgU3RhdHVzIHN0YXR1cyA9IG51bGw7CisJICAgIHRyeSB7CisJCXAgPSBnZXRTdG9yZVByb3RvY29sKCk7CS8vIFhYWAorCQlTdHJpbmdbXSBpdGVtcyA9IHsgaXRlbSB9OworCQlzdGF0dXMgPSBwLnN0YXR1cyhmdWxsTmFtZSwgaXRlbXMpOworCQlyZXR1cm4gc3RhdHVzICE9IG51bGwgPyBzdGF0dXMuZ2V0SXRlbShpdGVtKSA6IC0xOworCSAgICB9IGNhdGNoIChCYWRDb21tYW5kRXhjZXB0aW9uIGJleCkgeworCQkvLyBkb2Vzbid0IHN1cHBvcnQgU1RBVFVTLCBwcm9iYWJseSB2YW5pbGxhIElNQVA0IC4uCisJCS8vIENvdWxkIEVYQU1JTkUsIFNFQVJDSCBmb3IgVU5SRUFEIG1lc3NhZ2VzIGFuZAorCQkvLyByZXR1cm4gdGhlIGNvdW50IC4uIGJhaCwgbm90IHdvcnRoIGl0LgorCQlyZXR1cm4gLTE7CisJICAgIH0gY2F0Y2ggKENvbm5lY3Rpb25FeGNlcHRpb24gY2V4KSB7CisJCXRocm93IG5ldyBTdG9yZUNsb3NlZEV4Y2VwdGlvbihzdG9yZSwgY2V4LmdldE1lc3NhZ2UoKSk7CisJICAgIH0gY2F0Y2ggKFByb3RvY29sRXhjZXB0aW9uIHBleCkgeworCQl0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKHBleC5nZXRNZXNzYWdlKCksIHBleCk7CisJICAgIH0gZmluYWxseSB7CisJCXJlbGVhc2VTdG9yZVByb3RvY29sKHApOworCSAgICB9CisJfQorCXJldHVybiAtMTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgcmVzcG9uc2UgaGFuZGxlci4gVGhpcyBpcyB0aGUgY2FsbGJhY2sgcm91dGluZSB0aGF0IGlzIAorICAgICAqIGludm9rZWQgYnkgdGhlIHByb3RvY29sIGxheWVyLgorICAgICAqLworICAgIC8qCisgICAgICogQVNTRVJUOiBUaGlzIG1ldGhvZCBtdXN0IGJlIGNhbGxlZCBvbmx5IHdoZW4gaG9sZGluZyB0aGUKKyAgICAgKiBtZXNzYWdlQ2FjaGVMb2NrLgorICAgICAqIEFTU0VSVDogVGhpcyBtZXRob2QgbXVzdCAqbm90KiBpbnZva2UgYW55IG90aGVyIG1ldGhvZCB0aGF0CisgICAgICogbWlnaHQgZ3JhYiB0aGUgJ2ZvbGRlcicgbG9jayBvciAnbWVzc2FnZScgbG9jayAoaS5lLiwgYW55IAorICAgICAqIHN5bmNocm9uaXplZCBtZXRob2RzIG9uIElNQVBGb2xkZXIgb3IgSU1BUE1lc3NhZ2UpCisgICAgICogc2luY2UgdGhhdCB3aWxsIHJlc3VsdCBpbiB2aW9sYXRpbmcgdGhlIGxvY2tpbmcgaGllcmFyY2h5LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGhhbmRsZVJlc3BvbnNlKFJlc3BvbnNlIHIpIHsKKwlhc3NlcnQgVGhyZWFkLmhvbGRzTG9jayhtZXNzYWdlQ2FjaGVMb2NrKTsKKworCS8qCisJICogRmlyc3QsIGRlbGVnYXRlIHBvc3NpYmxlIEFMRVJUIG9yIG5vdGlmaWNhdGlvbiB0byB0aGUgU3RvcmUuCisJICovCisJaWYgKHIuaXNPSygpIHx8IHIuaXNOTygpIHx8IHIuaXNCQUQoKSB8fCByLmlzQllFKCkpCisJICAgICgoSU1BUFN0b3JlKXN0b3JlKS5oYW5kbGVSZXNwb25zZUNvZGUocik7CisKKwkvKgorCSAqIE5vdyBjaGVjayB3aGV0aGVyIHRoaXMgaXMgYSBCWUUgb3IgT0sgcmVzcG9uc2UgYW5kCisJICogaGFuZGxlIGFwcHJvcHJpYXRlbHkuCisJICovCisJaWYgKHIuaXNCWUUoKSkgeworCSAgICBpZiAob3BlbmVkKQkJLy8gWFhYIC0gYWNjZXNzZWQgd2l0aG91dCBob2xkaW5nIGZvbGRlciBsb2NrCisJCWNsZWFudXAoZmFsc2UpOyAKKwkgICAgcmV0dXJuOworCX0gZWxzZSBpZiAoci5pc09LKCkpIHsKKwkgICAgLy8gSElHSEVTVE1PRFNFUSBjYW4gYmUgdXBkYXRlZCBvbiBhbnkgT0sgcmVzcG9uc2UKKwkgICAgci5za2lwU3BhY2VzKCk7CisJICAgIGlmIChyLnJlYWRCeXRlKCkgPT0gJ1snKSB7CisJCVN0cmluZyBzID0gci5yZWFkQXRvbSgpOworCQlpZiAocy5lcXVhbHNJZ25vcmVDYXNlKCJISUdIRVNUTU9EU0VRIikpCisJCSAgICBoaWdoZXN0bW9kc2VxID0gci5yZWFkTG9uZygpOworCSAgICB9CisJICAgIHIucmVzZXQoKTsKKwkgICAgcmV0dXJuOworCX0gZWxzZSBpZiAoIXIuaXNVblRhZ2dlZCgpKSB7CisJICAgIHJldHVybjsJLy8gbWlnaHQgYmUgYSBjb250aW51YXRpb24gZm9yIElETEUKKwl9CisKKwkvKiBOb3cgY2hlY2sgd2hldGhlciB0aGlzIGlzIGFuIElNQVAgc3BlY2lmaWMgcmVzcG9uc2UgKi8KKwlpZiAoIShyIGluc3RhbmNlb2YgSU1BUFJlc3BvbnNlKSkgeworCSAgICAvLyBQcm9iYWJseSBhIGJ1ZyBpbiBvdXIgY29kZSAhCisJICAgIC8vIFhYWCAtIHNob3VsZCBiZSBhbiBhc3NlcnQKKwkgICAgbG9nZ2VyLmZpbmUoIlVORVhQRUNURUQgUkVTUE9OU0UgOiAiICsgci50b1N0cmluZygpKTsKKwkgICAgcmV0dXJuOworCX0KKworCUlNQVBSZXNwb25zZSBpciA9IChJTUFQUmVzcG9uc2UpcjsKKworCWlmIChpci5rZXlFcXVhbHMoIkVYSVNUUyIpKSB7IC8vIEVYSVNUUworCSAgICBpbnQgZXhpc3RzID0gaXIuZ2V0TnVtYmVyKCk7CisJICAgIGlmIChleGlzdHMgPD0gcmVhbFRvdGFsKSAKKwkJLy8gQ291bGQgYmUgdGhlIEVYSVNUUyBmb2xsb3dpbmcgRVhQVU5HRSwgaWdub3JlICdlbQorCQlyZXR1cm47CisJCisJICAgIGludCBjb3VudCA9IGV4aXN0cyAtIHJlYWxUb3RhbDsgLy8gbnVtYmVyIG9mIG5ldyBtZXNzYWdlcworCSAgICBNZXNzYWdlW10gbXNncyA9IG5ldyBNZXNzYWdlW2NvdW50XTsKKworCSAgICAvLyBBZGQgJ2NvdW50JyBuZXcgSU1BUE1lc3NhZ2Ugb2JqZWN0cyBpbnRvIHRoZSBtZXNzYWdlQ2FjaGUKKwkgICAgbWVzc2FnZUNhY2hlLmFkZE1lc3NhZ2VzKGNvdW50LCByZWFsVG90YWwgKyAxKTsKKwkgICAgaW50IG9sZHRvdGFsID0gdG90YWw7CS8vIHVzZWQgaW4gbG9vcCBiZWxvdworCSAgICByZWFsVG90YWwgKz0gY291bnQ7CisJICAgIHRvdGFsICs9IGNvdW50OworCisJICAgIC8vIGF2b2lkIGluc3RhbnRpYXRpbmcgTWVzc2FnZSBvYmplY3RzIGlmIG5vIGxpc3RlbmVycy4KKwkgICAgaWYgKGhhc01lc3NhZ2VDb3VudExpc3RlbmVyKSB7CisJCWZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykKKwkJICAgIG1zZ3NbaV0gPSBtZXNzYWdlQ2FjaGUuZ2V0TWVzc2FnZSgrK29sZHRvdGFsKTsKKworCQkvLyBOb3RpZnkgbGlzdGVuZXJzLgorCQlub3RpZnlNZXNzYWdlQWRkZWRMaXN0ZW5lcnMobXNncyk7CisJICAgIH0KKworCX0gZWxzZSBpZiAoaXIua2V5RXF1YWxzKCJFWFBVTkdFIikpIHsKKwkgICAgLy8gRVhQVU5HRSByZXNwb25zZS4KKworCSAgICBpbnQgc2VxbnVtID0gaXIuZ2V0TnVtYmVyKCk7CisJICAgIGlmIChzZXFudW0gPiByZWFsVG90YWwpIHsKKwkJLy8gQSBtZXNzYWdlIHdhcyBleHB1bmdlZCB0aGF0IHdlIG5ldmVyIGtuZXcgYWJvdXQuCisJCS8vIEV4Y2hhbmdlIHdpbGwgZG8gdGhpcy4gIEp1c3QgaWdub3JlIHRoZSBub3RpZmljYXRpb24uCisJCS8vIChBbHRlcm5hdGl2ZWx5LCB3ZSBjb3VsZCBzaW11bGF0ZSBhbiBFWElTVFMgZm9yIHRoZQorCQkvLyBleHB1bmdlZCBtZXNzYWdlIGJlZm9yZSBleHB1bmdpbmcgaXQuKQorCQlyZXR1cm47CisJICAgIH0KKwkgICAgTWVzc2FnZVtdIG1zZ3MgPSBudWxsOworCSAgICBpZiAoZG9FeHB1bmdlTm90aWZpY2F0aW9uICYmIGhhc01lc3NhZ2VDb3VudExpc3RlbmVyKSB7CisJCS8vIHNhdmUgdGhlIE1lc3NhZ2Ugb2JqZWN0IGZpcnN0OyBjYW4ndCBsb29rIGl0CisJCS8vIHVwIGFmdGVyIGl0J3MgZXhwdW5nZWQKKwkJbXNncyA9IG5ldyBNZXNzYWdlW10geyBnZXRNZXNzYWdlQnlTZXFOdW1iZXIoc2VxbnVtKSB9OworCQlpZiAobXNnc1swXSA9PSBudWxsKQkvLyBYWFggLSBzaG91bGQgbmV2ZXIgaGFwcGVuCisJCSAgICBtc2dzID0gbnVsbDsKKwkgICAgfQorCisJICAgIG1lc3NhZ2VDYWNoZS5leHB1bmdlTWVzc2FnZShzZXFudW0pOworCisJICAgIC8vIGRlY3JlbWVudCAncmVhbFRvdGFsJzsgYnV0IGxlYXZlICd0b3RhbCcgdW5jaGFuZ2VkCisJICAgIHJlYWxUb3RhbC0tOworCisJICAgIGlmIChtc2dzICE9IG51bGwpCS8vIERvIHRoZSBub3RpZmljYXRpb24gaGVyZS4KKwkJbm90aWZ5TWVzc2FnZVJlbW92ZWRMaXN0ZW5lcnMoZmFsc2UsIG1zZ3MpOworCisJfSBlbHNlIGlmIChpci5rZXlFcXVhbHMoIlZBTklTSEVEIikpIHsKKwkgICAgLy8gYWZ0ZXIgdGhlIGZvbGRlciBpcyBvcGVuZWQgd2l0aCBRUkVTWU5DLCBhIFZBTklTSEVEIHJlc3BvbnNlCisJICAgIC8vIHdpdGhvdXQgdGhlIChFQVJMSUVSKSB0YWcgaXMgdXNlZCBpbnN0ZWFkIG9mIHRoZSBFWFBVTkdFCisJICAgIC8vIHJlc3BvbnNlCisKKwkgICAgLy8gIlZBTklTSEVEIiBTUCBbIihFQVJMSUVSKSJdIFNQIGtub3duLXVpZHMKKwkgICAgU3RyaW5nW10gcyA9IGlyLnJlYWRBdG9tU3RyaW5nTGlzdCgpOworCSAgICBpZiAocyA9PSBudWxsKSB7CS8vIG5vIChFQVJMSUVSKQorCQlTdHJpbmcgdWlkcyA9IGlyLnJlYWRBdG9tKCk7CisJCVVJRFNldFtdIHVpZHNldCA9IFVJRFNldC5wYXJzZVVJRFNldHModWlkcyk7CisJCS8vIGFzc3VtZSBubyBkdXBsaWNhdGVzIGFuZCBubyBVSURzIG91dCBvZiByYW5nZQorCQlyZWFsVG90YWwgLT0gVUlEU2V0LnNpemUodWlkc2V0KTsKKwkJbG9uZ1tdIGx1aWQgPSBVSURTZXQudG9BcnJheSh1aWRzZXQpOworCQlNZXNzYWdlW10gbXNncyA9IGNyZWF0ZU1lc3NhZ2VzRm9yVUlEcyhsdWlkKTsKKwkJZm9yIChNZXNzYWdlIG0gOiBtc2dzKSB7CisJCSAgICBpZiAobS5nZXRNZXNzYWdlTnVtYmVyKCkgPiAwKQorCQkJbWVzc2FnZUNhY2hlLmV4cHVuZ2VNZXNzYWdlKG0uZ2V0TWVzc2FnZU51bWJlcigpKTsKKwkJfQorCQlpZiAoZG9FeHB1bmdlTm90aWZpY2F0aW9uICYmIGhhc01lc3NhZ2VDb3VudExpc3RlbmVyKSB7CisJCSAgICBub3RpZnlNZXNzYWdlUmVtb3ZlZExpc3RlbmVycyh0cnVlLCBtc2dzKTsKKwkJfQorCSAgICB9IC8vIGVsc2UgaWYgKEVBUkxJRVIpLCBpZ25vcmUKKworCX0gZWxzZSBpZiAoaXIua2V5RXF1YWxzKCJGRVRDSCIpKSB7CisJICAgIGFzc2VydCBpciBpbnN0YW5jZW9mIEZldGNoUmVzcG9uc2UgOiAiIWlyIGluc3RhbmNlb2YgRmV0Y2hSZXNwb25zZSI7CisJICAgIE1lc3NhZ2UgbXNnID0gcHJvY2Vzc0ZldGNoUmVzcG9uc2UoKEZldGNoUmVzcG9uc2UpaXIpOworCSAgICBpZiAobXNnICE9IG51bGwpCisJCW5vdGlmeU1lc3NhZ2VDaGFuZ2VkTGlzdGVuZXJzKAorCQkJTWVzc2FnZUNoYW5nZWRFdmVudC5GTEFHU19DSEFOR0VELCBtc2cpOworCisJfSBlbHNlIGlmIChpci5rZXlFcXVhbHMoIlJFQ0VOVCIpKSB7CisJICAgIC8vIHVwZGF0ZSAncmVjZW50JworCSAgICByZWNlbnQgPSBpci5nZXROdW1iZXIoKTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJvY2VzcyBhIEZFVENIIHJlc3BvbnNlLgorICAgICAqIFRoZSBvbmx5IHVuc29saWNpdGVkIEZFVENIIHJlc3BvbnNlIHRoYXQgbWFrZXMgc2Vuc2UKKyAgICAgKiB0byBtZSAoZm9yIG5vdykgaXMgRkxBR1MgdXBkYXRlcywgd2hpY2ggbWlnaHQgaW5jbHVkZQorICAgICAqIFVJRCBhbmQgTU9EU0VRIGluZm9ybWF0aW9uLiAgSWdub3JlIGFueSBvdGhlciBqdW5rLgorICAgICAqLworICAgIHByaXZhdGUgTWVzc2FnZSBwcm9jZXNzRmV0Y2hSZXNwb25zZShGZXRjaFJlc3BvbnNlIGZyKSB7CisJSU1BUE1lc3NhZ2UgbXNnID0gZ2V0TWVzc2FnZUJ5U2VxTnVtYmVyKGZyLmdldE51bWJlcigpKTsKKwlpZiAobXNnICE9IG51bGwpIHsJLy8gc2hvdWxkIGFsd2F5cyBiZSB0cnVlCisJICAgIGJvb2xlYW4gbm90aWZ5ID0gZmFsc2U7CisKKwkgICAgVUlEIHVpZCA9IGZyLmdldEl0ZW0oVUlELmNsYXNzKTsKKwkgICAgaWYgKHVpZCAhPSBudWxsICYmIG1zZy5nZXRVSUQoKSAhPSB1aWQudWlkKSB7CisJCW1zZy5zZXRVSUQodWlkLnVpZCk7CisJCWlmICh1aWRUYWJsZSA9PSBudWxsKQorCQkgICAgdWlkVGFibGUgPSBuZXcgSGFzaHRhYmxlPD4oKTsKKwkJdWlkVGFibGUucHV0KExvbmcudmFsdWVPZih1aWQudWlkKSwgbXNnKTsKKwkJbm90aWZ5ID0gdHJ1ZTsKKwkgICAgfQorCisJICAgIE1PRFNFUSBtb2RzZXEgPSBmci5nZXRJdGVtKE1PRFNFUS5jbGFzcyk7CisJICAgIGlmIChtb2RzZXEgIT0gbnVsbCAmJiBtc2cuX2dldE1vZFNlcSgpICE9IG1vZHNlcS5tb2RzZXEpIHsKKwkJbXNnLnNldE1vZFNlcShtb2RzZXEubW9kc2VxKTsKKwkJLyoKKwkJICogWFhYIC0gc2hvdWxkIHdlIHVwZGF0ZSB0aGUgZm9sZGVyJ3MgSElHSEVTVE1PRFNFUSBvciBub3Q/CisJCSAqCisJCWlmIChtb2RzZXEubW9kc2VxID4gaGlnaGVzdG1vZHNlcSkKKwkJICAgIGhpZ2hlc3Rtb2RzZXEgPSBtb2RzZXEubW9kc2VxOworCQkgKi8KKwkJbm90aWZ5ID0gdHJ1ZTsKKwkgICAgfQorCisJICAgIC8vIEdldCBGTEFHUyByZXNwb25zZSwgaWYgcHJlc2VudAorCSAgICBGTEFHUyBmbGFncyA9IGZyLmdldEl0ZW0oRkxBR1MuY2xhc3MpOworCSAgICBpZiAoZmxhZ3MgIT0gbnVsbCkgeworCQltc2cuX3NldEZsYWdzKGZsYWdzKTsJLy8gYXNzdW1lIGZsYWdzIGNoYW5nZWQKKwkJbm90aWZ5ID0gdHJ1ZTsKKwkgICAgfQorCisJICAgIC8vIGhhbmRsZSBhbnkgZXh0ZW5zaW9uIGl0ZW1zIHRoYXQgbWlnaHQndmUgY2hhbmdlZAorCSAgICAvLyBYWFggLSBubyBub3RpZmljYXRpb25zIGFzc29jaWF0ZWQgd2l0aCBleHRlbnNpb24gaXRlbXMKKwkgICAgbXNnLmhhbmRsZUV4dGVuc2lvbkZldGNoSXRlbXMoZnIuZ2V0RXh0ZW5zaW9uSXRlbXMoKSk7CisKKwkgICAgaWYgKCFub3RpZnkpCisJCW1zZyA9IG51bGw7CisJfQorCXJldHVybiBtc2c7CisgICAgfQorCisgICAgLyoqCisgICAgICogSGFuZGxlIHRoZSBnaXZlbiBhcnJheSBvZiBSZXNwb25zZXMuCisgICAgICoKKyAgICAgKiBBU1NFUlQ6IFRoaXMgbWV0aG9kIG11c3QgYmUgY2FsbGVkIG9ubHkgd2hlbiBob2xkaW5nIHRoZQorICAgICAqIAltZXNzYWdlQ2FjaGVMb2NrCisgICAgICovCisgICAgdm9pZCBoYW5kbGVSZXNwb25zZXMoUmVzcG9uc2VbXSByKSB7CisJZm9yIChpbnQgaSA9IDA7IGkgPCByLmxlbmd0aDsgaSsrKSB7CisJICAgIGlmIChyW2ldICE9IG51bGwpCisJCWhhbmRsZVJlc3BvbnNlKHJbaV0pOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhpcyBmb2xkZXIncyBTdG9yZSdzIHByb3RvY29sIGNvbm5lY3Rpb24uCisgICAgICoKKyAgICAgKiBXaGVuIGFjcXVpcmluZyBhIHN0b3JlIHByb3RvY29sIG9iamVjdCwgaXQgaXMgaW1wb3J0YW50IHRvCisgICAgICogdXNlIHRoZSBmb2xsb3dpbmcgc3RlcHM6CisgICAgICoKKyAgICAgKiA8YmxvY2txdW90ZT48cHJlPgorICAgICAqICAgICBJTUFQUHJvdG9jb2wgcCA9IG51bGw7CisgICAgICogICAgIHRyeSB7CisgICAgICogICAgICAgICBwID0gZ2V0U3RvcmVQcm90b2NvbCgpOworICAgICAqICAgICAgICAgLy8gcGVyZm9ybSB0aGUgY29tbWFuZAorICAgICAqICAgICB9IGNhdGNoIChXaGF0ZXZlckV4Y2VwdGlvbiBleCkgeworICAgICAqICAgICAgICAgLy8gaGFuZGxlIGl0CisgICAgICogICAgIH0gZmluYWxseSB7CisgICAgICogICAgICAgICByZWxlYXNlU3RvcmVQcm90b2NvbChwKTsKKyAgICAgKiAgICAgfQorICAgICAqIDwvcHJlPjwvYmxvY2txdW90ZT4KKyAgICAgKgorICAgICAqIEFTU0VSVDogTXVzdCBiZSBjYWxsZWQgd2l0aCB0aGlzIGZvbGRlcidzIHN5bmNocm9uaXphdGlvbiBsb2NrIGhlbGQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBJTUFQUHJvdG9jb2wgZm9yIHRoZSBTdG9yZSdzIGNvbm5lY3Rpb24KKyAgICAgKiBAZXhjZXB0aW9uCVByb3RvY29sRXhjZXB0aW9uIGZvciBwcm90b2NvbCBlcnJvcnMKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3luY2hyb25pemVkIElNQVBQcm90b2NvbCBnZXRTdG9yZVByb3RvY29sKCkgCisgICAgICAgICAgICB0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCWNvbm5lY3Rpb25Qb29sTG9nZ2VyLmZpbmUoImdldFN0b3JlUHJvdG9jb2woKSBib3Jyb3dpbmcgYSBjb25uZWN0aW9uIik7CisJcmV0dXJuICgoSU1BUFN0b3JlKXN0b3JlKS5nZXRGb2xkZXJTdG9yZVByb3RvY29sKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhyb3cgdGhlIGFwcHJvcHJpYXRlICdjbG9zZWQnIGV4Y2VwdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbQljZXgJdGhlIENvbm5lY3Rpb25FeGNlcHRpb24KKyAgICAgKiBAZXhjZXB0aW9uCUZvbGRlckNsb3NlZEV4Y2VwdGlvbiBpZiB0aGUgZm9sZGVyIGlzIGNsb3NlZAorICAgICAqIEBleGNlcHRpb24JU3RvcmVDbG9zZWRFeGNlcHRpb24gaWYgdGhlIHN0b3JlIGlzIGNsb3NlZAorICAgICAqLworICAgIHByb3RlY3RlZCBzeW5jaHJvbml6ZWQgdm9pZCB0aHJvd0Nsb3NlZEV4Y2VwdGlvbihDb25uZWN0aW9uRXhjZXB0aW9uIGNleCkgCisgICAgICAgICAgICB0aHJvd3MgRm9sZGVyQ2xvc2VkRXhjZXB0aW9uLCBTdG9yZUNsb3NlZEV4Y2VwdGlvbiB7CisJLy8gSWYgaXQncyB0aGUgZm9sZGVyJ3MgcHJvdG9jb2wgb2JqZWN0LCB0aHJvdyBhIEZvbGRlckNsb3NlZEV4Y2VwdGlvbjsKKwkvLyBvdGhlcndpc2UsIHRocm93IGEgU3RvcmVDbG9zZWRFeGNlcHRpb24uCisJLy8gSWYgYSBjb21tYW5kIGhhcyBmYWlsZWQgYmVjYXVzZSB0aGUgY29ubmVjdGlvbiBpcyBjbG9zZWQsCisJLy8gdGhlIGZvbGRlciB3aWxsIGhhdmUgYWxyZWFkeSBiZWVuIGZvcmNlZCBjbG9zZWQgYnkgdGhlCisJLy8gdGltZSB3ZSBnZXQgaGVyZSBhbmQgb3VyIHByb3RvY29sIG9iamVjdCB3aWxsIGhhdmUgYmVlbgorCS8vIHJlbGVhc2VkLCBzbyBpZiB3ZSBubyBsb25nZXIgaGF2ZSBhIHByb3RvY29sIG9iamVjdCB3ZSBiYXNlCisJLy8gdGhpcyBkZWNpc2lvbiBvbiB3aGV0aGVyIHdlICp0aGluayogdGhlIGZvbGRlciBpcyBvcGVuLgorCWlmICgocHJvdG9jb2wgIT0gbnVsbCAmJiBjZXguZ2V0UHJvdG9jb2woKSA9PSBwcm90b2NvbCkgfHwKKwkJKHByb3RvY29sID09IG51bGwgJiYgIXJlYWxseUNsb3NlZCkpCisgICAgICAgICAgICB0aHJvdyBuZXcgRm9sZGVyQ2xvc2VkRXhjZXB0aW9uKHRoaXMsIGNleC5nZXRNZXNzYWdlKCkpOworICAgICAgICBlbHNlCisgICAgICAgICAgICB0aHJvdyBuZXcgU3RvcmVDbG9zZWRFeGNlcHRpb24oc3RvcmUsIGNleC5nZXRNZXNzYWdlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgSU1BUFByb3RvY29sIG9iamVjdCBmb3IgdGhpcyBmb2xkZXIuIDxwPgorICAgICAqCisgICAgICogVGhpcyBtZXRob2Qgd2lsbCBibG9jayBpZiBuZWNlc3NhcnkgdG8gd2FpdCBmb3IgYW4gSURMRQorICAgICAqIGNvbW1hbmQgdG8gZmluaXNoLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgSU1BUFByb3RvY29sIG9iamVjdCB1c2VkIHdoZW4gdGhlIGZvbGRlciBpcyBvcGVuCisgICAgICogQGV4Y2VwdGlvbglQcm90b2NvbEV4Y2VwdGlvbiBmb3IgcHJvdG9jb2wgZXJyb3JzCisgICAgICovCisgICAgcHJvdGVjdGVkIElNQVBQcm90b2NvbCBnZXRQcm90b2NvbCgpIHRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJYXNzZXJ0IFRocmVhZC5ob2xkc0xvY2sobWVzc2FnZUNhY2hlTG9jayk7CisJd2FpdElmSWRsZSgpOworCS8vIGlmIHdlIG5vIGxvbmdlciBoYXZlIGEgcHJvdG9jb2wgb2JqZWN0IGFmdGVyIHdhaXRpbmcsIGl0IHByb2JhYmx5CisJLy8gbWVhbnMgdGhlIGNvbm5lY3Rpb24gaGFzIGJlZW4gY2xvc2VkIGR1ZSB0byBhIGNvbW11bm5pY2F0aW9uIGVycm9yLAorCS8vIG9yIHBvc3NpYmx5IGJlY2F1c2UgdGhlIGZvbGRlciBoYXMgYmVlbiBjbG9zZWQKKwlpZiAocHJvdG9jb2wgPT0gbnVsbCkKKwkgICAgdGhyb3cgbmV3IENvbm5lY3Rpb25FeGNlcHRpb24oIkNvbm5lY3Rpb24gY2xvc2VkIik7CisgICAgICAgIHJldHVybiBwcm90b2NvbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBIHNpbXBsZSBpbnRlcmZhY2UgZm9yIHVzZXItZGVmaW5lZCBJTUFQIHByb3RvY29sIGNvbW1hbmRzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50ZXJmYWNlIFByb3RvY29sQ29tbWFuZCB7CisJLyoqCisJICogRXhlY3V0ZSB0aGUgdXNlci1kZWZpbmVkIGNvbW1hbmQgdXNpbmcgdGhlIHN1cHBsaWVkIElNQVBQcm90b2NvbAorCSAqIG9iamVjdC4KKwkgKgorCSAqIEBwYXJhbQlwcm90b2NvbAl0aGUgSU1BUFByb3RvY29sIGZvciB0aGUgY29ubmVjdGlvbgorCSAqIEByZXR1cm4JCQl0aGUgcmVzdWx0cyBvZiB0aGUgY29tbWFuZAorCSAqIEBleGNlcHRpb24JUHJvdG9jb2xFeGNlcHRpb24gZm9yIHByb3RvY29sIGVycm9ycworCSAqLworCXB1YmxpYyBPYmplY3QgZG9Db21tYW5kKElNQVBQcm90b2NvbCBwcm90b2NvbCkgdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIEV4ZWN1dGUgYSB1c2VyLXN1cHBsaWVkIElNQVAgY29tbWFuZC4gIFRoZSBjb21tYW5kIGlzIGV4ZWN1dGVkCisgICAgICogaW4gdGhlIGFwcHJvcHJpYXRlIGNvbnRleHQgd2l0aCB0aGUgbmVjZXNzYXJ5IGxvY2tzIGhlbGQgYW5kCisgICAgICogdXNpbmcgdGhlIGFwcHJvcHJpYXRlIDxjb2RlPklNQVBQcm90b2NvbDwvY29kZT4gb2JqZWN0LiA8cD4KKyAgICAgKgorICAgICAqIFRoaXMgbWV0aG9kIHJldHVybnMgd2hhdGV2ZXIgdGhlIDxjb2RlPlByb3RvY29sQ29tbWFuZDwvY29kZT4KKyAgICAgKiBvYmplY3QncyA8Y29kZT5kb0NvbW1hbmQ8L2NvZGU+IG1ldGhvZCByZXR1cm5zLiAgSWYgdGhlCisgICAgICogPGNvZGU+ZG9Db21tYW5kPC9jb2RlPiBtZXRob2QgdGhyb3dzIGEgPGNvZGU+Q29ubmVjdGlvbkV4Y2VwdGlvbjwvY29kZT4KKyAgICAgKiBpdCBpcyB0cmFuc2xhdGVkIGludG8gYSA8Y29kZT5TdG9yZUNsb3NlZEV4Y2VwdGlvbjwvY29kZT4gb3IKKyAgICAgKiA8Y29kZT5Gb2xkZXJDbG9zZWRFeGNlcHRpb248L2NvZGU+IGFzIGFwcHJvcHJpYXRlLiAgSWYgdGhlCisgICAgICogPGNvZGU+ZG9Db21tYW5kPC9jb2RlPiBtZXRob2QgdGhyb3dzIGEgPGNvZGU+UHJvdG9jb2xFeGNlcHRpb248L2NvZGU+CisgICAgICogaXQgaXMgdHJhbnNsYXRlZCBpbnRvIGEgPGNvZGU+TWVzc2FnaW5nRXhjZXB0aW9uPC9jb2RlPi4gPHA+CisgICAgICoKKyAgICAgKiBUaGUgZm9sbG93aW5nIGV4YW1wbGUgc2hvd3MgaG93IHRvIGV4ZWN1dGUgdGhlIElNQVAgTk9PUCBjb21tYW5kLgorICAgICAqIEV4ZWN1dGluZyBtb3JlIGNvbXBsZXggSU1BUCBjb21tYW5kcyByZXF1aXJlcyBpbnRpbWF0ZSBrbm93bGVkZ2UKKyAgICAgKiBvZiB0aGUgPGNvZGU+Y29tLnN1bi5tYWlsLmlhcDwvY29kZT4gYW5kCisgICAgICogPGNvZGU+Y29tLnN1bi5tYWlsLmltYXAucHJvdG9jb2w8L2NvZGU+IHBhY2thZ2VzLCBiZXN0IGFjcXVpcmVkIGJ5CisgICAgICogcmVhZGluZyB0aGUgc291cmNlIGNvZGUuCisgICAgICoKKyAgICAgKiA8YmxvY2txdW90ZT48cHJlPgorICAgICAqIGltcG9ydCBjb20uc3VuLm1haWwuaWFwLio7CisgICAgICogaW1wb3J0IGNvbS5zdW4ubWFpbC5pbWFwLio7CisgICAgICogaW1wb3J0IGNvbS5zdW4ubWFpbC5pbWFwLnByb3RvY29sLio7CisgICAgICoKKyAgICAgKiAuLi4KKyAgICAgKgorICAgICAqIElNQVBGb2xkZXIgZiA9IChJTUFQRm9sZGVyKWZvbGRlcjsKKyAgICAgKiBPYmplY3QgdmFsID0gZi5kb0NvbW1hbmQobmV3IElNQVBGb2xkZXIuUHJvdG9jb2xDb21tYW5kKCkgeworICAgICAqCXB1YmxpYyBPYmplY3QgZG9Db21tYW5kKElNQVBQcm90b2NvbCBwKQorICAgICAqCQkJdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKyAgICAgKgkgICAgcC5zaW1wbGVDb21tYW5kKCJOT09QIiwgbnVsbCk7CisgICAgICoJICAgIHJldHVybiBudWxsOworICAgICAqCX0KKyAgICAgKiB9KTsKKyAgICAgKiA8L3ByZT48L2Jsb2NrcXVvdGU+CisgICAgICogPHA+CisgICAgICoKKyAgICAgKiBIZXJlJ3MgYSBtb3JlIGNvbXBsZXggZXhhbXBsZSBzaG93aW5nIGhvdyB0byB1c2UgdGhlIHByb3Bvc2VkCisgICAgICogSU1BUCBTT1JUIGV4dGVuc2lvbjoKKyAgICAgKgorICAgICAqIDxibG9ja3F1b3RlPjxwcmU+CisgICAgICogaW1wb3J0IGNvbS5zdW4ubWFpbC5pYXAuKjsKKyAgICAgKiBpbXBvcnQgY29tLnN1bi5tYWlsLmltYXAuKjsKKyAgICAgKiBpbXBvcnQgY29tLnN1bi5tYWlsLmltYXAucHJvdG9jb2wuKjsKKyAgICAgKgorICAgICAqIC4uLgorICAgICAqCisgICAgICogSU1BUEZvbGRlciBmID0gKElNQVBGb2xkZXIpZm9sZGVyOworICAgICAqIE9iamVjdCB2YWwgPSBmLmRvQ29tbWFuZChuZXcgSU1BUEZvbGRlci5Qcm90b2NvbENvbW1hbmQoKSB7CisgICAgICoJcHVibGljIE9iamVjdCBkb0NvbW1hbmQoSU1BUFByb3RvY29sIHApCisgICAgICoJCQl0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworICAgICAqCSAgICAvLyBJc3N1ZSBjb21tYW5kCisgICAgICoJICAgIEFyZ3VtZW50IGFyZ3MgPSBuZXcgQXJndW1lbnQoKTsKKyAgICAgKgkgICAgQXJndW1lbnQgbGlzdCA9IG5ldyBBcmd1bWVudCgpOworICAgICAqCSAgICBsaXN0LndyaXRlU3RyaW5nKCJTVUJKRUNUIik7CisgICAgICoJICAgIGFyZ3Mud3JpdGVBcmd1bWVudChsaXN0KTsKKyAgICAgKgkgICAgYXJncy53cml0ZVN0cmluZygiVVRGLTgiKTsKKyAgICAgKgkgICAgYXJncy53cml0ZVN0cmluZygiQUxMIik7CisgICAgICoJICAgIFJlc3BvbnNlW10gciA9IHAuY29tbWFuZCgiU09SVCIsIGFyZ3MpOworICAgICAqCSAgICBSZXNwb25zZSByZXNwb25zZSA9IHJbci5sZW5ndGgtMV07CisgICAgICoKKyAgICAgKgkgICAgLy8gR3JhYiByZXNwb25zZQorICAgICAqCSAgICBWZWN0b3IgdiA9IG5ldyBWZWN0b3IoKTsKKyAgICAgKgkgICAgaWYgKHJlc3BvbnNlLmlzT0soKSkgeyAvLyBjb21tYW5kIHN1Y2Nlc2Z1bCAKKyAgICAgKgkJZm9yIChpbnQgaSA9IDAsIGxlbiA9IHIubGVuZ3RoOyBpICZsdDsgbGVuOyBpKyspIHsKKyAgICAgKgkJICAgIGlmICghKHJbaV0gaW5zdGFuY2VvZiBJTUFQUmVzcG9uc2UpKQorICAgICAqCQkJY29udGludWU7CisgICAgICoKKyAgICAgKgkJICAgIElNQVBSZXNwb25zZSBpciA9IChJTUFQUmVzcG9uc2UpcltpXTsKKyAgICAgKgkJICAgIGlmIChpci5rZXlFcXVhbHMoIlNPUlQiKSkgeworICAgICAqCQkJU3RyaW5nIG51bTsKKyAgICAgKgkJCXdoaWxlICgobnVtID0gaXIucmVhZEF0b21TdHJpbmcoKSkgIT0gbnVsbCkKKyAgICAgKgkJCSAgICBTeXN0ZW0ub3V0LnByaW50bG4obnVtKTsKKyAgICAgKgkJCXJbaV0gPSBudWxsOworICAgICAqCQkgICAgfQorICAgICAqCQl9CisgICAgICoJICAgIH0KKyAgICAgKgorICAgICAqCSAgICAvLyBkaXNwYXRjaCByZW1haW5pbmcgdW50YWdnZWQgcmVzcG9uc2VzCisgICAgICoJICAgIHAubm90aWZ5UmVzcG9uc2VIYW5kbGVycyhyKTsKKyAgICAgKgkgICAgcC5oYW5kbGVSZXN1bHQocmVzcG9uc2UpOworICAgICAqCisgICAgICoJICAgIHJldHVybiBudWxsOworICAgICAqCX0KKyAgICAgKiB9KTsKKyAgICAgKiA8L3ByZT48L2Jsb2NrcXVvdGU+CisgICAgICoKKyAgICAgKiBAcGFyYW0JY21kCXRoZSBwcm90b2NvbCBjb21tYW5kCisgICAgICogQHJldHVybgkJdGhlIHJlc3VsdCBvZiB0aGUgY29tbWFuZAorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZG9Db21tYW5kKFByb3RvY29sQ29tbWFuZCBjbWQpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXRyeSB7CisJICAgIHJldHVybiBkb1Byb3RvY29sQ29tbWFuZChjbWQpOworCX0gY2F0Y2ggKENvbm5lY3Rpb25FeGNlcHRpb24gY2V4KSB7CisgICAgICAgICAgICAvLyBPb3BzLCB0aGUgc3RvcmUgb3IgZm9sZGVyIGRpZWQgb24gdXMuCisgICAgICAgICAgICB0aHJvd0Nsb3NlZEV4Y2VwdGlvbihjZXgpOworCX0gY2F0Y2ggKFByb3RvY29sRXhjZXB0aW9uIHBleCkgeworCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKHBleC5nZXRNZXNzYWdlKCksIHBleCk7CisJfQorCXJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZG9PcHRpb25hbENvbW1hbmQoU3RyaW5nIGVyciwgUHJvdG9jb2xDb21tYW5kIGNtZCkKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwl0cnkgeworCSAgICByZXR1cm4gZG9Qcm90b2NvbENvbW1hbmQoY21kKTsKKwl9IGNhdGNoIChCYWRDb21tYW5kRXhjZXB0aW9uIGJleCkgeworCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKGVyciwgYmV4KTsKKwl9IGNhdGNoIChDb25uZWN0aW9uRXhjZXB0aW9uIGNleCkgeworICAgICAgICAgICAgLy8gT29wcywgdGhlIHN0b3JlIG9yIGZvbGRlciBkaWVkIG9uIHVzLgorICAgICAgICAgICAgdGhyb3dDbG9zZWRFeGNlcHRpb24oY2V4KTsKKwl9IGNhdGNoIChQcm90b2NvbEV4Y2VwdGlvbiBwZXgpIHsKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbihwZXguZ2V0TWVzc2FnZSgpLCBwZXgpOworCX0KKwlyZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGRvQ29tbWFuZElnbm9yZUZhaWx1cmUoUHJvdG9jb2xDb21tYW5kIGNtZCkKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwl0cnkgeworCSAgICByZXR1cm4gZG9Qcm90b2NvbENvbW1hbmQoY21kKTsKKwl9IGNhdGNoIChDb21tYW5kRmFpbGVkRXhjZXB0aW9uIGNmeCkgeworCSAgICByZXR1cm4gbnVsbDsKKwl9IGNhdGNoIChDb25uZWN0aW9uRXhjZXB0aW9uIGNleCkgeworICAgICAgICAgICAgLy8gT29wcywgdGhlIHN0b3JlIG9yIGZvbGRlciBkaWVkIG9uIHVzLgorICAgICAgICAgICAgdGhyb3dDbG9zZWRFeGNlcHRpb24oY2V4KTsKKwl9IGNhdGNoIChQcm90b2NvbEV4Y2VwdGlvbiBwZXgpIHsKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbihwZXguZ2V0TWVzc2FnZSgpLCBwZXgpOworCX0KKwlyZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgc3luY2hyb25pemVkIE9iamVjdCBkb1Byb3RvY29sQ29tbWFuZChQcm90b2NvbENvbW1hbmQgY21kKQorCQkJCXRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJLyoKKwkgKiBDaGVjayB3aGV0aGVyIHdlIGhhdmUgYSBwcm90b2NvbCBvYmplY3QsIG5vdCB3aGV0aGVyIHdlJ3JlCisJICogb3BlbmVkLCB0byBhbGxvdyB1c2Ugb2YgdGhlIGV4c3RpbmcgcHJvdG9jb2wgb2JqZWN0IGluIHRoZQorCSAqIG9wZW4gbWV0aG9kIGJlZm9yZSB0aGUgc3RhdGUgaXMgY2hhbmdlZCB0byAib3BlbmVkIi4KKwkgKi8KKwlpZiAocHJvdG9jb2wgIT0gbnVsbCkgeworCSAgICBzeW5jaHJvbml6ZWQgKG1lc3NhZ2VDYWNoZUxvY2spIHsKKwkJcmV0dXJuIGNtZC5kb0NvbW1hbmQoZ2V0UHJvdG9jb2woKSk7CisJICAgIH0KKwl9CisKKwkvLyBvbmx5IGdldCBoZXJlIGlmIHVzaW5nIHN0b3JlJ3MgY29ubmVjdGlvbgorCUlNQVBQcm90b2NvbCBwID0gbnVsbDsKKworCXRyeSB7CisgICAgICAgICAgICBwID0gZ2V0U3RvcmVQcm90b2NvbCgpOworCSAgICByZXR1cm4gY21kLmRvQ29tbWFuZChwKTsKKwl9IGZpbmFsbHkgeworCSAgICByZWxlYXNlU3RvcmVQcm90b2NvbChwKTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVsZWFzZSB0aGUgc3RvcmUgcHJvdG9jb2wgb2JqZWN0LiAgSWYgd2UgYm9ycm93ZWQgYSBwcm90b2NvbAorICAgICAqIG9iamVjdCBmcm9tIHRoZSBjb25uZWN0aW9uIHBvb2wsIGdpdmUgaXQgYmFjay4gIElmIHdlIHVzZWQgb3VyCisgICAgICogb3duIHByb3RvY29sIG9iamVjdCwgbm90aGluZyB0byBkby4KKyAgICAgKgorICAgICAqIEFTU0VSVDogTXVzdCBiZSBjYWxsZWQgd2l0aCB0aGlzIGZvbGRlcidzIHN5bmNocm9uaXphdGlvbiBsb2NrIGhlbGQuCisgICAgICoKKyAgICAgKiBAcGFyYW0JcAl0aGUgSU1BUFByb3RvY29sIG9iamVjdAorICAgICAqLworICAgIHByb3RlY3RlZCBzeW5jaHJvbml6ZWQgdm9pZCByZWxlYXNlU3RvcmVQcm90b2NvbChJTUFQUHJvdG9jb2wgcCkgeworICAgICAgICBpZiAocCAhPSBwcm90b2NvbCkKKyAgICAgICAgICAgICgoSU1BUFN0b3JlKXN0b3JlKS5yZWxlYXNlRm9sZGVyU3RvcmVQcm90b2NvbChwKTsKKwllbHNlIHsKKwkgICAgLy8gWFhYIC0gc2hvdWxkIG5ldmVyIGhhcHBlbgorCSAgICBsb2dnZXIuZmluZSgicmVsZWFzaW5nIG91ciBwcm90b2NvbCBhcyBzdG9yZSBwcm90b2NvbD8iKTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVsZWFzZSB0aGUgcHJvdG9jb2wgb2JqZWN0LgorICAgICAqCisgICAgICogQVNTRVJUOiBUaGlzIG1ldGhvZCBtdXN0IGJlIGNhbGxlZCBvbmx5IHdoZW4gaG9sZGluZyB0aGUKKyAgICAgKiAgbWVzc2FnZUNhY2hlTG9jaworICAgICAqCisgICAgICogQHBhcmFtCXJldHVyblRvUG9vbAlyZXR1cm4gdGhlIHByb3RvY29sIG9iamVjdCB0byB0aGUgcG9vbD8KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCByZWxlYXNlUHJvdG9jb2woYm9vbGVhbiByZXR1cm5Ub1Bvb2wpIHsKKyAgICAgICAgaWYgKHByb3RvY29sICE9IG51bGwpIHsKKyAgICAgICAgICAgIHByb3RvY29sLnJlbW92ZVJlc3BvbnNlSGFuZGxlcih0aGlzKTsKKworICAgICAgICAgICAgaWYgKHJldHVyblRvUG9vbCkKKyAgICAgICAgICAgICAgICAoKElNQVBTdG9yZSlzdG9yZSkucmVsZWFzZVByb3RvY29sKHRoaXMsIHByb3RvY29sKTsKKyAgICAgICAgICAgIGVsc2UgeworCQlwcm90b2NvbC5kaXNjb25uZWN0KCk7CS8vIG1ha2Ugc3VyZSBpdCdzIGRpc2Nvbm5lY3RlZAorICAgICAgICAgICAgICAgICgoSU1BUFN0b3JlKXN0b3JlKS5yZWxlYXNlUHJvdG9jb2wodGhpcywgbnVsbCk7CisJICAgIH0KKwkgICAgcHJvdG9jb2wgPSBudWxsOworICAgICAgICB9CisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIElzc3VlIGEgbm9vcCBjb21tYW5kIGZvciB0aGUgY29ubmVjdGlvbiBpZiB0aGUgY29ubmVjdGlvbiBoYXMgbm90IGJlZW4KKyAgICAgKiB1c2VkIGluIG1vcmUgdGhhbiBhIHNlY29uZC4gSWYgPGNvZGU+a2VlcFN0b3JlQWxpdmU8L2NvZGU+IGlzIHRydWUsCisgICAgICogYWxzbyBpc3N1ZSBhIG5vb3Agb3ZlciB0aGUgc3RvcmUncyBjb25uZWN0aW9uLgorICAgICAqCisgICAgICogQVNTRVJUOiBUaGlzIG1ldGhvZCBtdXN0IGJlIGNhbGxlZCBvbmx5IHdoZW4gaG9sZGluZyB0aGUKKyAgICAgKiAgbWVzc2FnZUNhY2hlTG9jaworICAgICAqCisgICAgICogQHBhcmFtCWtlZXBTdG9yZUFsaXZlCWtlZXAgdGhlIFN0b3JlIGFsaXZlIHRvbz8KKyAgICAgKiBAZXhjZXB0aW9uCVByb3RvY29sRXhjZXB0aW9uIGZvciBwcm90b2NvbCBlcnJvcnMKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBrZWVwQ29ubmVjdGlvbkFsaXZlKGJvb2xlYW4ga2VlcFN0b3JlQWxpdmUpIAorICAgICAgICAgICAgICAgICAgICB0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCisJYXNzZXJ0IFRocmVhZC5ob2xkc0xvY2sobWVzc2FnZUNhY2hlTG9jayk7CisJaWYgKHByb3RvY29sID09IG51bGwpCS8vIGluIGNhc2UgY29ubmVjdGlvbiB3YXMgY2xvc2VkCisJICAgIHJldHVybjsKKyAgICAgICAgaWYgKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpIC0gcHJvdG9jb2wuZ2V0VGltZXN0YW1wKCkgPiAxMDAwKSB7CisJICAgIHdhaXRJZklkbGUoKTsKKwkgICAgaWYgKHByb3RvY29sICE9IG51bGwpCisJCXByb3RvY29sLm5vb3AoKTsgCisJfQorCisgICAgICAgIGlmIChrZWVwU3RvcmVBbGl2ZSAmJiAoKElNQVBTdG9yZSlzdG9yZSkuaGFzU2VwYXJhdGVTdG9yZUNvbm5lY3Rpb24oKSkgeworICAgICAgICAgICAgSU1BUFByb3RvY29sIHAgPSBudWxsOworCSAgICB0cnkgeworCQlwID0gKChJTUFQU3RvcmUpc3RvcmUpLmdldEZvbGRlclN0b3JlUHJvdG9jb2woKTsKKwkJaWYgKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpIC0gcC5nZXRUaW1lc3RhbXAoKSA+IDEwMDApCisJCSAgICBwLm5vb3AoKTsKKwkgICAgfSBmaW5hbGx5IHsKKwkJKChJTUFQU3RvcmUpc3RvcmUpLnJlbGVhc2VGb2xkZXJTdG9yZVByb3RvY29sKHApOworCSAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIG1lc3NhZ2Ugb2JqZWN0IGZvciB0aGUgZ2l2ZW4gc2VxdWVuY2UgbnVtYmVyLiBJZgorICAgICAqIG5vbmUgZm91bmQsIG51bGwgaXMgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBBU1NFUlQ6IFRoaXMgbWV0aG9kIG11c3QgYmUgY2FsbGVkIG9ubHkgd2hlbiBob2xkaW5nIHRoZQorICAgICAqICBtZXNzYWdlQ2FjaGVMb2NrCisgICAgICoKKyAgICAgKiBAcGFyYW0Jc2VxbnVtCXRoZSBtZXNzYWdlIHNlcXVlbmNlIG51bWJlcgorICAgICAqIEByZXR1cm4JdGhlIElNQVBNZXNzYWdlIG9iamVjdAorICAgICAqLworICAgIHByb3RlY3RlZCBJTUFQTWVzc2FnZSBnZXRNZXNzYWdlQnlTZXFOdW1iZXIoaW50IHNlcW51bSkgeworCWlmIChzZXFudW0gPiBtZXNzYWdlQ2FjaGUuc2l6ZSgpKSB7CisJICAgIC8vIE1pY3Jvc29mdCBFeGNoYW5nZSB3aWxsIHNvbWV0aW1lcyByZXR1cm4gbWVzc2FnZQorCSAgICAvLyBudW1iZXJzIHRoYXQgaXQgaGFzIG5vdCB5ZXQgbm90aWZpZWQgdGhlIGNsaWVudAorCSAgICAvLyBhYm91dCB2aWEgRVhJU1RTOyBpZ25vcmUgdGhvc2UgbWVzc2FnZXMgaGVyZS4KKwkgICAgLy8gR29EYWRkeSBJTUFQIGRvZXMgdGhpcyB0b28uCisJICAgIGlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FKSkKKwkJbG9nZ2VyLmZpbmUoImlnbm9yaW5nIG1lc3NhZ2UgbnVtYmVyICIgKworCQkgICAgc2VxbnVtICsgIiBvdXRzaWRlIHJhbmdlICIgKyBtZXNzYWdlQ2FjaGUuc2l6ZSgpKTsKKwkgICAgcmV0dXJuIG51bGw7CisJfQorCXJldHVybiBtZXNzYWdlQ2FjaGUuZ2V0TWVzc2FnZUJ5U2VxbnVtKHNlcW51bSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBtZXNzYWdlIG9iamVjdHMgZm9yIHRoZSBnaXZlbiBzZXF1ZW5jZSBudW1iZXJzLgorICAgICAqCisgICAgICogQVNTRVJUOiBUaGlzIG1ldGhvZCBtdXN0IGJlIGNhbGxlZCBvbmx5IHdoZW4gaG9sZGluZyB0aGUKKyAgICAgKiAgbWVzc2FnZUNhY2hlTG9jaworICAgICAqCisgICAgICogQHBhcmFtCXNlcW51bXMJdGhlIGFycmF5IG9mIG1lc3NhZ2Ugc2VxdWVuY2UgbnVtYmVycworICAgICAqIEByZXR1cm4JdGhlIElNQVBNZXNzYWdlIG9iamVjdHMKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS41LjMKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgSU1BUE1lc3NhZ2VbXSBnZXRNZXNzYWdlc0J5U2VxTnVtYmVycyhpbnRbXSBzZXFudW1zKSB7CisJSU1BUE1lc3NhZ2VbXSBtc2dzID0gbmV3IElNQVBNZXNzYWdlW3NlcW51bXMubGVuZ3RoXTsKKwlpbnQgbnVsbHMgPSAwOworCS8vIE1hcCBzZXEtbnVtYmVycyBpbnRvIGFjdHVhbCBNZXNzYWdlcy4KKwlmb3IgKGludCBpID0gMDsgaSA8IHNlcW51bXMubGVuZ3RoOyBpKyspIHsKKwkgICAgbXNnc1tpXSA9IGdldE1lc3NhZ2VCeVNlcU51bWJlcihzZXFudW1zW2ldKTsKKwkgICAgaWYgKG1zZ3NbaV0gPT0gbnVsbCkKKwkJbnVsbHMrKzsKKwl9CisJaWYgKG51bGxzID4gMCkgewkvLyBjb21wcmVzcyB0aGUgYXJyYXkgdG8gcmVtb3ZlIHRoZSBudWxscworCSAgICBJTUFQTWVzc2FnZVtdIG5tc2dzID0gbmV3IElNQVBNZXNzYWdlW3NlcW51bXMubGVuZ3RoIC0gbnVsbHNdOworCSAgICBmb3IgKGludCBpID0gMCwgaiA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisJCWlmIChtc2dzW2ldICE9IG51bGwpCisJCSAgICBubXNnc1tqKytdID0gbXNnc1tpXTsKKwkgICAgfQorCSAgICBtc2dzID0gbm1zZ3M7CisJfQorCXJldHVybiBtc2dzOworICAgIH0KKworICAgIHByaXZhdGUgYm9vbGVhbiBpc0RpcmVjdG9yeSgpIHsKKwlyZXR1cm4gKCh0eXBlICYgSE9MRFNfRk9MREVSUykgIT0gMCk7CisgICAgfQorfQorCisvKioKKyAqIEFuIG9iamVjdCB0aGF0IGhvbGRzIGEgTWVzc2FnZSBvYmplY3QKKyAqIGFuZCByZXBvcnRzIGl0cyBzaXplIGFuZCB3cml0ZXMgaXQgdG8gYW5vdGhlciBPdXRwdXRTdHJlYW0KKyAqIG9uIGRlbWFuZC4gIFVzZWQgYnkgYXBwZW5kTWVzc2FnZXMgdG8gYXZvaWQgdGhlIG5lZWQgdG8KKyAqIGJ1ZmZlciB0aGUgZW50aXJlIG1lc3NhZ2UgaW4gbWVtb3J5IGluIGEgc2luZ2xlIGJ5dGUgYXJyYXkKKyAqIGJlZm9yZSBzZW5kaW5nIGl0IHRvIHRoZSBzZXJ2ZXIuCisgKi8KK2NsYXNzIE1lc3NhZ2VMaXRlcmFsIGltcGxlbWVudHMgTGl0ZXJhbCB7CisgICAgcHJpdmF0ZSBNZXNzYWdlIG1zZzsKKyAgICBwcml2YXRlIGludCBtc2dTaXplID0gLTE7CisgICAgcHJpdmF0ZSBieXRlW10gYnVmOwkJLy8gdGhlIGJ1ZmZlcmVkIG1lc3NhZ2UsIGlmIG5vdCBudWxsCisKKyAgICBwdWJsaWMgTWVzc2FnZUxpdGVyYWwoTWVzc2FnZSBtc2csIGludCBtYXhzaXplKQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKwl0aGlzLm1zZyA9IG1zZzsKKwkvLyBjb21wdXRlIHRoZSBzaXplIGhlcmUgc28gZXhjZXB0aW9ucyBjYW4gYmUgcmV0dXJuZWQgaW1tZWRpYXRlbHkKKwlMZW5ndGhDb3VudGVyIGxjID0gbmV3IExlbmd0aENvdW50ZXIobWF4c2l6ZSk7CisJT3V0cHV0U3RyZWFtIG9zID0gbmV3IENSTEZPdXRwdXRTdHJlYW0obGMpOworCW1zZy53cml0ZVRvKG9zKTsKKwlvcy5mbHVzaCgpOworCW1zZ1NpemUgPSBsYy5nZXRTaXplKCk7CisJYnVmID0gbGMuZ2V0Qnl0ZXMoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHNpemUoKSB7CisJcmV0dXJuIG1zZ1NpemU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGVUbyhPdXRwdXRTdHJlYW0gb3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJLy8gdGhlIG1lc3NhZ2Ugc2hvdWxkIG5vdCBjaGFuZ2UgYmV0d2VlbiB0aGUgY29uc3RydWN0b3IgYW5kIHRoaXMgY2FsbAorCXRyeSB7CisJICAgIGlmIChidWYgIT0gbnVsbCkKKwkJb3Mud3JpdGUoYnVmLCAwLCBtc2dTaXplKTsKKwkgICAgZWxzZSB7CisJCW9zID0gbmV3IENSTEZPdXRwdXRTdHJlYW0ob3MpOworCQltc2cud3JpdGVUbyhvcyk7CisJICAgIH0KKwl9IGNhdGNoIChNZXNzYWdpbmdFeGNlcHRpb24gbWV4KSB7CisJICAgIC8vIGV4Y2VwdGlvbnMgaGVyZSBhcmUgYmFkLCAic2hvdWxkIiBuZXZlciBoYXBwZW4KKwkgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJNZXNzYWdpbmdFeGNlcHRpb24gd2hpbGUgYXBwZW5kaW5nIG1lc3NhZ2U6ICIKKwkJCQkgICAgKyBtZXgpOworCX0KKyAgICB9Cit9CisKKy8qKgorICogQ291bnQgdGhlIG51bWJlciBvZiBieXRlcyB3cml0dGVuIHRvIHRoZSBzdHJlYW0uCisgKiBBbHNvLCBzYXZlIGEgY29weSBvZiBzbWFsbCBtZXNzYWdlcyB0byBhdm9pZCBoYXZpbmcgdG8gcHJvY2VzcworICogdGhlIGRhdGEgYWdhaW4uCisgKi8KK2NsYXNzIExlbmd0aENvdW50ZXIgZXh0ZW5kcyBPdXRwdXRTdHJlYW0geworICAgIHByaXZhdGUgaW50IHNpemUgPSAwOworICAgIHByaXZhdGUgYnl0ZVtdIGJ1ZjsKKyAgICBwcml2YXRlIGludCBtYXhzaXplOworCisgICAgcHVibGljIExlbmd0aENvdW50ZXIoaW50IG1heHNpemUpIHsKKwlidWYgPSBuZXcgYnl0ZVs4MTkyXTsKKwl0aGlzLm1heHNpemUgPSBtYXhzaXplOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGludCBiKSB7CisJaW50IG5ld3NpemUgPSBzaXplICsgMTsKKwlpZiAoYnVmICE9IG51bGwpIHsKKwkgICAgaWYgKG5ld3NpemUgPiBtYXhzaXplICYmIG1heHNpemUgPj0gMCkgeworCQlidWYgPSBudWxsOworCSAgICB9IGVsc2UgaWYgKG5ld3NpemUgPiBidWYubGVuZ3RoKSB7CisJCWJ5dGUgbmV3YnVmW10gPSBuZXcgYnl0ZVtNYXRoLm1heChidWYubGVuZ3RoIDw8IDEsIG5ld3NpemUpXTsKKwkJU3lzdGVtLmFycmF5Y29weShidWYsIDAsIG5ld2J1ZiwgMCwgc2l6ZSk7CisJCWJ1ZiA9IG5ld2J1ZjsKKwkJYnVmW3NpemVdID0gKGJ5dGUpYjsKKwkgICAgfSBlbHNlIHsKKwkJYnVmW3NpemVdID0gKGJ5dGUpYjsKKwkgICAgfQorCX0KKwlzaXplID0gbmV3c2l6ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShieXRlIGJbXSwgaW50IG9mZiwgaW50IGxlbikgeworCWlmICgob2ZmIDwgMCkgfHwgKG9mZiA+IGIubGVuZ3RoKSB8fCAobGVuIDwgMCkgfHwKKyAgICAgICAgICAgICgob2ZmICsgbGVuKSA+IGIubGVuZ3RoKSB8fCAoKG9mZiArIGxlbikgPCAwKSkgeworCSAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigpOworCX0gZWxzZSBpZiAobGVuID09IDApIHsKKwkgICAgcmV0dXJuOworCX0KKyAgICAgICAgaW50IG5ld3NpemUgPSBzaXplICsgbGVuOworCWlmIChidWYgIT0gbnVsbCkgeworCSAgICBpZiAobmV3c2l6ZSA+IG1heHNpemUgJiYgbWF4c2l6ZSA+PSAwKSB7CisJCWJ1ZiA9IG51bGw7CisJICAgIH0gZWxzZSBpZiAobmV3c2l6ZSA+IGJ1Zi5sZW5ndGgpIHsKKwkJYnl0ZSBuZXdidWZbXSA9IG5ldyBieXRlW01hdGgubWF4KGJ1Zi5sZW5ndGggPDwgMSwgbmV3c2l6ZSldOworCQlTeXN0ZW0uYXJyYXljb3B5KGJ1ZiwgMCwgbmV3YnVmLCAwLCBzaXplKTsKKwkJYnVmID0gbmV3YnVmOworCQlTeXN0ZW0uYXJyYXljb3B5KGIsIG9mZiwgYnVmLCBzaXplLCBsZW4pOworCSAgICB9IGVsc2UgeworCQlTeXN0ZW0uYXJyYXljb3B5KGIsIG9mZiwgYnVmLCBzaXplLCBsZW4pOworCSAgICB9CisJfQorICAgICAgICBzaXplID0gbmV3c2l6ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShieXRlW10gYikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwl3cml0ZShiLCAwLCBiLmxlbmd0aCk7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRTaXplKCkgeworCXJldHVybiBzaXplOworICAgIH0KKworICAgIHB1YmxpYyBieXRlW10gZ2V0Qnl0ZXMoKSB7CisJcmV0dXJuIGJ1ZjsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvSU1BUElucHV0U3RyZWFtLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvSU1BUElucHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzFjOTkzZAotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9JTUFQSW5wdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDI1OSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuaW1hcDsKKworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZheC5tYWlsLio7CitpbXBvcnQgY29tLnN1bi5tYWlsLmltYXAucHJvdG9jb2wuKjsKK2ltcG9ydCBjb20uc3VuLm1haWwuaWFwLio7CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuRm9sZGVyQ2xvc2VkSU9FeGNlcHRpb247CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuTWVzc2FnZVJlbW92ZWRJT0V4Y2VwdGlvbjsKKworLyoqCisgKiBUaGlzIGNsYXNzIGltcGxlbWVudHMgYW4gSU1BUCBkYXRhIHN0cmVhbS4KKyAqCisgKiBAYXV0aG9yICBKb2huIE1hbmkKKyAqLworCitwdWJsaWMgY2xhc3MgSU1BUElucHV0U3RyZWFtIGV4dGVuZHMgSW5wdXRTdHJlYW0geworICAgIHByaXZhdGUgSU1BUE1lc3NhZ2UgbXNnOyAvLyB0aGlzIG1lc3NhZ2UKKyAgICBwcml2YXRlIFN0cmluZyBzZWN0aW9uOyAgLy8gc2VjdGlvbi1pZAorICAgIHByaXZhdGUgaW50IHBvczsJICAvLyB0cmFjayB0aGUgcG9zaXRpb24gd2l0aGluIHRoZSBJTUFQIGRhdGFzdHJlYW0KKyAgICBwcml2YXRlIGludCBibGtzaXplOyAgLy8gbnVtYmVyIG9mIGJ5dGVzIHRvIHJlYWQgaW4gZWFjaCBGRVRDSCByZXF1ZXN0CisgICAgcHJpdmF0ZSBpbnQgbWF4OwkgIC8vIHRoZSB0b3RhbCBudW1iZXIgb2YgYnl0ZXMgaW4gdGhpcyBzZWN0aW9uLgorCQkJICAvLyAgLTEgaW5kaWNhdGVzIHVua25vd24KKyAgICBwcml2YXRlIGJ5dGVbXSBidWY7ICAgLy8gdGhlIGJ1ZmZlciBvYnRhaW5lZCBmcm9tIGZldGNoQk9EWSgpCisgICAgcHJpdmF0ZSBpbnQgYnVmY291bnQ7IC8vIFRoZSBpbmRleCBvbmUgZ3JlYXRlciB0aGFuIHRoZSBpbmRleCBvZiB0aGUKKwkJCSAgLy8gbGFzdCB2YWxpZCBieXRlIGluICdidWYnCisgICAgcHJpdmF0ZSBpbnQgYnVmcG9zOyAgIC8vIFRoZSBjdXJyZW50IHBvc2l0aW9uIHdpdGhpbiAnYnVmJworICAgIHByaXZhdGUgYm9vbGVhbiBsYXN0QnVmZmVyOyAvLyBpcyB0aGlzIHRoZSBsYXN0IGJ1ZmZlciBvZiBkYXRhPworICAgIHByaXZhdGUgYm9vbGVhbiBwZWVrOyAvLyBwZWVrIGluc3RlYWQgb2YgZmV0Y2g/CisgICAgcHJpdmF0ZSBCeXRlQXJyYXkgcmVhZGJ1ZjsgLy8gcmV1c2UgZm9yIGVhY2ggcmVhZAorCisgICAgLy8gQWxsb2NhdGUgdGhpcyBtdWNoIGV4dHJhIHNwYWNlIGluIHRoZSByZWFkIGJ1ZmZlciB0byBhbGxvdworICAgIC8vIHNwYWNlIGZvciB0aGUgRkVUQ0ggcmVzcG9uc2Ugb3ZlcmhlYWQKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgc2xvcCA9IDY0OworCisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYW4gSU1BUElucHV0U3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtCW1zZwl0aGUgSU1BUE1lc3NhZ2UgdGhlIGRhdGEgd2lsbCBjb21lIGZyb20KKyAgICAgKiBAcGFyYW0Jc2VjdGlvbgl0aGUgSU1BUCBzZWN0aW9uL3BhcnQgaWRlbnRpZmllciBmb3IgdGhlIGRhdGEKKyAgICAgKiBAcGFyYW0JbWF4CXRoZSBudW1iZXIgb2YgYnl0ZXMgaW4gdGhpcyBzZWN0aW9uCisgICAgICogQHBhcmFtCXBlZWsJcGVlayBpbnN0ZWFkIG9mIGZldGNoPworICAgICAqLworICAgIHB1YmxpYyBJTUFQSW5wdXRTdHJlYW0oSU1BUE1lc3NhZ2UgbXNnLCBTdHJpbmcgc2VjdGlvbiwgaW50IG1heCwKKwkJCQlib29sZWFuIHBlZWspIHsKKwl0aGlzLm1zZyA9IG1zZzsKKwl0aGlzLnNlY3Rpb24gPSBzZWN0aW9uOworCXRoaXMubWF4ID0gbWF4OworCXRoaXMucGVlayA9IHBlZWs7CisJcG9zID0gMDsKKwlibGtzaXplID0gbXNnLmdldEZldGNoQmxvY2tTaXplKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRG8gYSBOT09QIHRvIGZvcmNlIGFueSB1bnRhZ2dlZCBFWFBVTkdFIHJlc3BvbnNlcworICAgICAqIGFuZCB0aGVuIGNoZWNrIGlmIHRoaXMgbWVzc2FnZSBpcyBleHB1bmdlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgZm9yY2VDaGVja0V4cHVuZ2VkKCkKKwkJICAgIHRocm93cyBNZXNzYWdlUmVtb3ZlZElPRXhjZXB0aW9uLCBGb2xkZXJDbG9zZWRJT0V4Y2VwdGlvbiB7CisJc3luY2hyb25pemVkIChtc2cuZ2V0TWVzc2FnZUNhY2hlTG9jaygpKSB7CisJICAgIHRyeSB7CisJCW1zZy5nZXRQcm90b2NvbCgpLm5vb3AoKTsKKwkgICAgfSBjYXRjaCAoQ29ubmVjdGlvbkV4Y2VwdGlvbiBjZXgpIHsKKwkJdGhyb3cgbmV3IEZvbGRlckNsb3NlZElPRXhjZXB0aW9uKG1zZy5nZXRGb2xkZXIoKSwKKwkJCQkJCWNleC5nZXRNZXNzYWdlKCkpOworCSAgICB9IGNhdGNoIChGb2xkZXJDbG9zZWRFeGNlcHRpb24gZmV4KSB7CisJCXRocm93IG5ldyBGb2xkZXJDbG9zZWRJT0V4Y2VwdGlvbihmZXguZ2V0Rm9sZGVyKCksCisJCQkJCQlmZXguZ2V0TWVzc2FnZSgpKTsKKwkgICAgfSBjYXRjaCAoUHJvdG9jb2xFeGNlcHRpb24gcGV4KSB7CisJCS8vIGlnbm9yZSBpdAorCSAgICB9CisJfQorCWlmIChtc2cuaXNFeHB1bmdlZCgpKQorCSAgICB0aHJvdyBuZXcgTWVzc2FnZVJlbW92ZWRJT0V4Y2VwdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZldGNoIG1vcmUgZGF0YSBmcm9tIHRoZSBzZXJ2ZXIuIFRoaXMgbWV0aG9kIGFzc3VtZXMgdGhhdCBhbGwKKyAgICAgKiBkYXRhIGhhcyBhbHJlYWR5IGJlZW4gcmVhZCBpbiwgaGVuY2UgYnVmcG9zID4gYnVmY291bnQuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGZpbGwoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCS8qCisJICogSWYgd2UndmUgcmVhZCB0aGUgbGFzdCBidWZmZXIsIHRoZXJlJ3Mgbm8gbW9yZSB0byByZWFkLgorCSAqIElmIHdlIGtub3cgdGhlIHRvdGFsIG51bWJlciBvZiBieXRlcyBhdmFpbGFibGUgZnJvbSB0aGlzCisJICogc2VjdGlvbiwgbGV0J3MgY2hlY2sgaWYgd2UgaGF2ZSBjb25zdW1lZCB0aGF0IG1hbnkgYnl0ZXMuCisJICovCisJaWYgKGxhc3RCdWZmZXIgfHwgbWF4ICE9IC0xICYmIHBvcyA+PSBtYXgpIHsKKwkgICAgaWYgKHBvcyA9PSAwKQorCQljaGVja1NlZW4oKTsKKwkgICAgcmVhZGJ1ZiA9IG51bGw7CS8vIFhYWCAtIHJldHVybiB0byBwb29sPworCSAgICByZXR1cm47IC8vIHRoZSBjYWxsZXIgb2YgZmlsbCgpIHdpbGwgcmV0dXJuIC0xLgorCX0KKworCUJPRFkgYiA9IG51bGw7CisJaWYgKHJlYWRidWYgPT0gbnVsbCkKKwkgICAgcmVhZGJ1ZiA9IG5ldyBCeXRlQXJyYXkoYmxrc2l6ZSArIHNsb3ApOworCisJQnl0ZUFycmF5IGJhOworCWludCBjbnQ7CisJLy8gQWNxdWlyZSBNZXNzYWdlQ2FjaGVMb2NrLCB0byBmcmVlemUgc2VxbnVtLgorCXN5bmNocm9uaXplZCAobXNnLmdldE1lc3NhZ2VDYWNoZUxvY2soKSkgeworCSAgICB0cnkgeworCQlJTUFQUHJvdG9jb2wgcCA9IG1zZy5nZXRQcm90b2NvbCgpOworCisJCS8vIENoZWNrIHdoZXRoZXIgdGhpcyBtZXNzYWdlIGlzIGV4cHVuZ2VkCisJCWlmIChtc2cuaXNFeHB1bmdlZCgpKQorCQkgICAgdGhyb3cgbmV3IE1lc3NhZ2VSZW1vdmVkSU9FeGNlcHRpb24oCisJCQkJIk5vIGNvbnRlbnQgZm9yIGV4cHVuZ2VkIG1lc3NhZ2UiKTsKKworCQlpbnQgc2VxbnVtID0gbXNnLmdldFNlcXVlbmNlTnVtYmVyKCk7CisJCWNudCA9IGJsa3NpemU7CisJCWlmIChtYXggIT0gLTEgJiYgcG9zICsgYmxrc2l6ZSA+IG1heCkKKwkJICAgIGNudCA9IG1heCAtIHBvczsKKwkJaWYgKHBlZWspCisJCSAgICBiID0gcC5wZWVrQm9keShzZXFudW0sIHNlY3Rpb24sIHBvcywgY250LCByZWFkYnVmKTsKKwkJZWxzZQorCQkgICAgYiA9IHAuZmV0Y2hCb2R5KHNlcW51bSwgc2VjdGlvbiwgcG9zLCBjbnQsIHJlYWRidWYpOworCSAgICB9IGNhdGNoIChQcm90b2NvbEV4Y2VwdGlvbiBwZXgpIHsKKwkJZm9yY2VDaGVja0V4cHVuZ2VkKCk7CisJCXRocm93IG5ldyBJT0V4Y2VwdGlvbihwZXguZ2V0TWVzc2FnZSgpKTsKKwkgICAgfSBjYXRjaCAoRm9sZGVyQ2xvc2VkRXhjZXB0aW9uIGZleCkgeworCQl0aHJvdyBuZXcgRm9sZGVyQ2xvc2VkSU9FeGNlcHRpb24oZmV4LmdldEZvbGRlcigpLAorCQkJCQkJZmV4LmdldE1lc3NhZ2UoKSk7CisJICAgIH0KKworCSAgICBpZiAoYiA9PSBudWxsIHx8ICgoYmEgPSBiLmdldEJ5dGVBcnJheSgpKSA9PSBudWxsKSkgeworCQlmb3JjZUNoZWNrRXhwdW5nZWQoKTsKKwkJLy8gbm9wZSwgdGhlIHNlcnZlciBkb2Vzbid0IHRoaW5rIGl0J3MgZXhwdW5nZWQuCisJCS8vIGNhbid0IHRlbGwgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgc2VydmVyIHJldHVybmluZyBOSUwKKwkJLy8gYW5kIHNvbWUgb3RoZXIgZXJyb3IgdGhhdCBjYXVzZWQgbnVsbCB0byBiZSByZXR1cm5lZCBhYm92ZSwKKwkJLy8gc28gd2UnbGwganVzdCBhc3N1bWUgaXQgd2FzIGVtcHR5IGNvbnRlbnQuCisJCWJhID0gbmV3IEJ5dGVBcnJheSgwKTsKKwkgICAgfQorCX0KKworCS8vIG1ha2Ugc3VyZSB0aGUgU0VFTiBmbGFnIGlzIHNldCBhZnRlciByZWFkaW5nIHRoZSBmaXJzdCBjaHVuaworCWlmIChwb3MgPT0gMCkKKwkgICAgY2hlY2tTZWVuKCk7CisKKwkvLyBzZXR1cCBuZXcgdmFsdWVzIC4uCisJYnVmID0gYmEuZ2V0Qnl0ZXMoKTsKKwlidWZwb3MgPSBiYS5nZXRTdGFydCgpOworCWludCBuID0gYmEuZ2V0Q291bnQoKTsgICAgLy8gd2lsbCBiZSB6ZXJvLCBpZiBhbGwgZGF0YSBoYXMgYmVlbgorCQkJCSAgLy8gY29uc3VtZWQgZnJvbSB0aGUgc2VydmVyLgorCS8vIGlmIHdlIGdvdCBsZXNzIHRoYW4gd2UgYXNrZWQgZm9yLCB0aGlzIGlzIHRoZSBsYXN0IGJ1ZmZlciBvZiBkYXRhCisJbGFzdEJ1ZmZlciA9IG4gPCBjbnQ7CisJYnVmY291bnQgPSBidWZwb3MgKyBuOworCXBvcyArPSBuOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIHRoZSBuZXh0IGJ5dGUgb2YgZGF0YSBmcm9tIHRoaXMgYnVmZmVyZWQgaW5wdXQgc3RyZWFtLgorICAgICAqIElmIG5vIGJ5dGUgaXMgYXZhaWxhYmxlLCB0aGUgdmFsdWUgPGNvZGU+LTE8L2NvZGU+IGlzIHJldHVybmVkLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCWlmIChidWZwb3MgPj0gYnVmY291bnQpIHsKKwkgICAgZmlsbCgpOworCSAgICBpZiAoYnVmcG9zID49IGJ1ZmNvdW50KQorCQlyZXR1cm4gLTE7CS8vIEVPRgorCX0KKwlyZXR1cm4gYnVmW2J1ZnBvcysrXSAmIDB4ZmY7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgdXAgdG8gPGNvZGU+bGVuPC9jb2RlPiBieXRlcyBvZiBkYXRhIGZyb20gdGhpcworICAgICAqIGlucHV0IHN0cmVhbSBpbnRvIHRoZSBnaXZlbiBidWZmZXIuIDxwPgorICAgICAqCisgICAgICogUmV0dXJucyB0aGUgdG90YWwgbnVtYmVyIG9mIGJ5dGVzIHJlYWQgaW50byB0aGUgYnVmZmVyLAorICAgICAqIG9yIDxjb2RlPi0xPC9jb2RlPiBpZiB0aGVyZSBpcyBubyBtb3JlIGRhdGEuIDxwPgorICAgICAqCisgICAgICogTm90ZSB0aGF0IHRoaXMgbWV0aG9kIG1pbWljcyB0aGUgIndlaXJkICEiIHNlbWFudGljcyBvZgorICAgICAqIEJ1ZmZlcmVkSW5wdXRTdHJlYW0gaW4gdGhhdCB0aGUgbnVtYmVyIG9mIGJ5dGVzIGFjdHVhbGx5CisgICAgICogcmV0dXJuZWQgbWF5IGJlIGxlc3MgdGhhdCB0aGUgcmVxdWVzdGVkIHZhbHVlLiBTbyBjYWxsZXJzCisgICAgICogb2YgdGhpcyByb3V0aW5lIHNob3VsZCBiZSBhd2FyZSBvZiB0aGlzIGFuZCBtdXN0IGNoZWNrCisgICAgICogdGhlIHJldHVybiB2YWx1ZSB0byBpbnN1cmUgdGhhdCB0aGV5IGhhdmUgb2J0YWluZWQgdGhlCisgICAgICogcmVxdWlzaXRlIG51bWJlciBvZiBieXRlcy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCByZWFkKGJ5dGUgYltdLCBpbnQgb2ZmLCBpbnQgbGVuKSAKKwkJdGhyb3dzIElPRXhjZXB0aW9uIHsKKworCWludCBhdmFpbCA9IGJ1ZmNvdW50IC0gYnVmcG9zOworCWlmIChhdmFpbCA8PSAwKSB7CisJICAgIGZpbGwoKTsKKwkgICAgYXZhaWwgPSBidWZjb3VudCAtIGJ1ZnBvczsKKwkgICAgaWYgKGF2YWlsIDw9IDApCisJCXJldHVybiAtMTsgLy8gRU9GCisJfQorCWludCBjbnQgPSAoYXZhaWwgPCBsZW4pID8gYXZhaWwgOiBsZW47CisJU3lzdGVtLmFycmF5Y29weShidWYsIGJ1ZnBvcywgYiwgb2ZmLCBjbnQpOworCWJ1ZnBvcyArPSBjbnQ7CisJcmV0dXJuIGNudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyB1cCB0byA8Y29kZT5iLmxlbmd0aDwvY29kZT4gYnl0ZXMgb2YgZGF0YSBmcm9tIHRoaXMgaW5wdXQKKyAgICAgKiBzdHJlYW0gaW50byBhbiBhcnJheSBvZiBieXRlcy4gPHA+CisgICAgICoKKyAgICAgKiBSZXR1cm5zIHRoZSB0b3RhbCBudW1iZXIgb2YgYnl0ZXMgcmVhZCBpbnRvIHRoZSBidWZmZXIsIG9yCisgICAgICogPGNvZGU+LTE8L2NvZGU+IGlzIHRoZXJlIGlzIG5vIG1vcmUgZGF0YS4gPHA+CisgICAgICoKKyAgICAgKiBOb3RlIHRoYXQgdGhpcyBtZXRob2QgbWltaWNzIHRoZSAid2VpcmQgISIgc2VtYW50aWNzIG9mCisgICAgICogQnVmZmVyZWRJbnB1dFN0cmVhbSBpbiB0aGF0IHRoZSBudW1iZXIgb2YgYnl0ZXMgYWN0dWFsbHkKKyAgICAgKiByZXR1cm5lZCBtYXkgYmUgbGVzcyB0aGF0IHRoZSByZXF1ZXN0ZWQgdmFsdWUuIFNvIGNhbGxlcnMKKyAgICAgKiBvZiB0aGlzIHJvdXRpbmUgc2hvdWxkIGJlIGF3YXJlIG9mIHRoaXMgYW5kIG11c3QgY2hlY2sKKyAgICAgKiB0aGUgcmV0dXJuIHZhbHVlIHRvIGluc3VyZSB0aGF0IHRoZXkgaGF2ZSBvYnRhaW5lZCB0aGUKKyAgICAgKiByZXF1aXNpdGUgbnVtYmVyIG9mIGJ5dGVzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZChieXRlIGJbXSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlyZXR1cm4gcmVhZChiLCAwLCBiLmxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRoYXQgY2FuIGJlIHJlYWQgZnJvbSB0aGlzIGlucHV0CisgICAgICogc3RyZWFtIHdpdGhvdXQgYmxvY2tpbmcuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBpbnQgYXZhaWxhYmxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlyZXR1cm4gKGJ1ZmNvdW50IC0gYnVmcG9zKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBOb3JtYWxseSB0aGUgU0VFTiBmbGFnIHdpbGwgaGF2ZSBiZWVuIHNldCBieSBub3csIGJ1dCBpZiBub3QsCisgICAgICogZm9yY2UgaXQgdG8gYmUgc2V0IChhcyBsb25nIGFzIHRoZSBmb2xkZXIgaXNuJ3Qgb3BlbiByZWFkLW9ubHkKKyAgICAgKiBhbmQgd2UncmUgbm90IHBlZWtpbmcpLgorICAgICAqIEFuZCBvZiBjb3Vyc2UsIGlmIHRoZXJlJ3Mgbm8gZm9sZGVyIChlLmcuLCBhIG5lc3RlZCBtZXNzYWdlKQorICAgICAqIGRvbid0IGRvIGFueXRoaW5nLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBjaGVja1NlZW4oKSB7CisJaWYgKHBlZWspCS8vIGlmIHdlJ3JlIHBlZWtpbmcsIGRvbid0IHNldCB0aGUgU0VFTiBmbGFnCisJICAgIHJldHVybjsKKwl0cnkgeworCSAgICBGb2xkZXIgZiA9IG1zZy5nZXRGb2xkZXIoKTsKKwkgICAgaWYgKGYgIT0gbnVsbCAmJiBmLmdldE1vZGUoKSAhPSBGb2xkZXIuUkVBRF9PTkxZICYmCisJCSAgICAhbXNnLmlzU2V0KEZsYWdzLkZsYWcuU0VFTikpCisJCW1zZy5zZXRGbGFnKEZsYWdzLkZsYWcuU0VFTiwgdHJ1ZSk7CisJfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIGV4KSB7CisJICAgIC8vIGlnbm9yZSBpdAorCX0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvSU1BUE1lc3NhZ2UuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9JTUFQTWVzc2FnZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ1MzQ3OWQKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvSU1BUE1lc3NhZ2UuamF2YQpAQCAtMCwwICsxLDE3MDAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmltYXA7CisKK2ltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YS51dGlsLio7CisKK2ltcG9ydCBqYXZheC5tYWlsLio7CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC4qOworaW1wb3J0IGphdmF4LmFjdGl2YXRpb24uKjsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLlJlYWRhYmxlTWltZTsKK2ltcG9ydCBjb20uc3VuLm1haWwuaWFwLio7CitpbXBvcnQgY29tLnN1bi5tYWlsLmltYXAucHJvdG9jb2wuKjsKKworLyoqCisgKiBUaGlzIGNsYXNzIGltcGxlbWVudHMgYW4gSU1BUE1lc3NhZ2Ugb2JqZWN0LiA8cD4KKyAqCisgKiBBbiBJTUFQTWVzc2FnZSBvYmplY3Qgc3RhcnRzIG91dCBhcyBhIGxpZ2h0LXdlaWdodCBvYmplY3QuIEl0IGdldHMKKyAqIGZpbGxlZC1pbiBpbmNyZW1lbnRhbGx5IHdoZW4gYSByZXF1ZXN0IGlzIG1hZGUgZm9yIHNvbWUgaXRlbS4gT3IKKyAqIHdoZW4gYSBwcmVmZXRjaCBpcyBkb25lIHVzaW5nIHRoZSBGZXRjaFByb2ZpbGUuIDxwPgorICoKKyAqIEFuIElNQVBNZXNzYWdlIGhhcyBhIG1lc3NhZ2VOdW1iZXIgYW5kIGEgc2VxdWVuY2VOdW1iZXIuIFRoZSAKKyAqIG1lc3NhZ2VOdW1iZXIgaXMgaXRzIGluZGV4IGludG8gaXRzIGNvbnRhaW5pbmcgZm9sZGVyJ3MgbWVzc2FnZUNhY2hlLgorICogVGhlIHNlcXVlbmNlTnVtYmVyIGlzIGl0cyBJTUFQIHNlcXVlbmNlLW51bWJlci4KKyAqCisgKiBAYXV0aG9yICBKb2huIE1hbmkKKyAqIEBhdXRob3IgIEJpbGwgU2hhbm5vbgorICovCisvKgorICogVGhlIGxvY2sgaGllcmFyY2h5IGlzIHRoYXQgdGhlIGxvY2sgb24gdGhlIElNQVBNZXNzYWdlIG9iamVjdCwgaWYKKyAqIGl0J3MgYWNxdWlyZWQgYXQgYWxsLCBtdXN0IGJlIGFjcXVpcmVkIGJlZm9yZSB0aGUgbWVzc2FnZSBjYWNoZSBsb2NrLgorICogVGhlIElNQVBNZXNzYWdlIGxvY2sgcHJvdGVjdHMgdGhlIG1lc3NhZ2UgZmxhZ3MsIHNvcnQgb2YuCisgKgorICogWFhYIC0gSSdtIG5vdCBjb252aW5jZWQgdGhhdCBhbGwgZmllbGRzIG9mIElNQVBNZXNzYWdlIGFyZSBwcm9wZXJseQorICogcHJvdGVjdGVkIGJ5IGxvY2tzLgorICovCisKK3B1YmxpYyBjbGFzcyBJTUFQTWVzc2FnZSBleHRlbmRzIE1pbWVNZXNzYWdlIGltcGxlbWVudHMgUmVhZGFibGVNaW1lIHsKKyAgICBwcm90ZWN0ZWQgQk9EWVNUUlVDVFVSRSBiczsJCS8vIEJPRFlTVFJVQ1RVUkUKKyAgICBwcm90ZWN0ZWQgRU5WRUxPUEUgZW52ZWxvcGU7CS8vIEVOVkVMT1BFCisKKyAgICAvKioKKyAgICAgKiBBIG1hcCBvZiB0aGUgZXh0ZW5zaW9uIEZFVENIIGl0ZW1zLiAgSW4gYWRkaXRpb24gdG8gc2F2aW5nIHRoZQorICAgICAqIGRhdGEgaW4gdGhpcyBtYXAsIGFuIGVudHJ5IGluIHRoaXMgbWFwIGluZGljYXRlcyB0aGF0IHdlICpoYXZlKgorICAgICAqIHRoZSBkYXRhLCBhbmQgc28gaXQgZG9lc24ndCBuZWVkIHRvIGJlIGZldGNoZWQgYWdhaW4uICBUaGUgbWFwCisgICAgICogaXMgY3JlYXRlZCBvbmx5IHdoZW4gbmVlZGVkLCB0byBhdm9pZCBzaWduaWZpY2FudGx5IGluY3JlYXNpbmcKKyAgICAgKiB0aGUgZWZmZWN0aXZlIHNpemUgb2YgYW4gSU1BUE1lc3NhZ2Ugb2JqZWN0LgorICAgICAqCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNC42CisgICAgICovCisgICAgcHJvdGVjdGVkIE1hcDxTdHJpbmcsIE9iamVjdD4gaXRlbXM7CQkvLyBNYXA8U3RyaW5nLE9iamVjdD4KKworICAgIHByaXZhdGUgRGF0ZSByZWNlaXZlZERhdGU7CQkvLyBJTlRFUk5BTERBVEUKKyAgICBwcml2YXRlIGxvbmcgc2l6ZSA9IC0xOwkJLy8gUkZDODIyLlNJWkUKKworICAgIHByaXZhdGUgQm9vbGVhbiBwZWVrOwkJLy8gdXNlIEJPRFkuUEVFSyB3aGVuIGZldGNoaW5nIGNvbnRlbnQ/CisKKyAgICAvLyB0aGlzIG1lc3NhZ2UncyBJTUFQIFVJRAorICAgIHByaXZhdGUgdm9sYXRpbGUgbG9uZyB1aWQgPSAtMTsKKworICAgIC8vIHRoaXMgbWVzc2FnZSdzIElNQVAgTU9EU0VRIC0gUkZDIDQ1NTEgQ09ORFNUT1JFCisgICAgcHJpdmF0ZSB2b2xhdGlsZSBsb25nIG1vZHNlcSA9IC0xOworCisgICAgLy8gdGhpcyBtZXNzYWdlJ3MgSU1BUCBzZWN0aW9uSWQgKG51bGwgZm9yIHRvcGxldmVsIG1lc3NhZ2UsIAorICAgIC8vIAlub24tbnVsbCBmb3IgYSBuZXN0ZWQgbWVzc2FnZSkKKyAgICBwcm90ZWN0ZWQgU3RyaW5nIHNlY3Rpb25JZDsKKworICAgIC8vIHByb2Nlc3NlZCB2YWx1ZXMKKyAgICBwcml2YXRlIFN0cmluZyB0eXBlOwkJLy8gQ29udGVudC1UeXBlICh3aXRoIHBhcmFtcykKKyAgICBwcml2YXRlIFN0cmluZyBzdWJqZWN0OwkJLy8gZGVjb2RlZCAoVW5pY29kZSkgc3ViamVjdAorICAgIHByaXZhdGUgU3RyaW5nIGRlc2NyaXB0aW9uOwkJLy8gZGVjb2RlZCAoVW5pY29kZSkgZGVzYworCisgICAgLy8gSW5kaWNhdGVzIHRoYXQgd2UndmUgbG9hZGVkICphbGwqIGhlYWRlcnMgZm9yIHRoaXMgbWVzc2FnZQorICAgIHByaXZhdGUgdm9sYXRpbGUgYm9vbGVhbiBoZWFkZXJzTG9hZGVkID0gZmFsc2U7CisKKyAgICAvLyBJbmRpY2F0ZXMgdGhhdCB3ZSd2ZSBjYWNoZWQgdGhlIGJvZHkgb2YgdGhpcyBtZXNzYWdlCisgICAgcHJpdmF0ZSB2b2xhdGlsZSBib29sZWFuIGJvZHlMb2FkZWQgPSBmYWxzZTsKKworICAgIC8qIEhhc2h0YWJsZSBvZiBuYW1lcyBvZiBoZWFkZXJzIHdlJ3ZlIGxvYWRlZCBmcm9tIHRoZSBzZXJ2ZXIuCisgICAgICogVXNlZCBpbiBpc0hlYWRlckxvYWRlZCgpIGFuZCBnZXRIZWFkZXJMb2FkZWQoKSB0byBrZWVwIHRyYWNrCisgICAgICogb2YgdGhvc2UgaGVhZGVycyB3ZSd2ZSBhdHRlbXB0ZWQgdG8gbG9hZCBmcm9tIHRoZSBzZXJ2ZXIuIFdlCisgICAgICogbmVlZCB0aGlzIHRhYmxlIG9mIG5hbWVzIHRvIGF2b2lkIG11bHRpcGxlIGF0dGVtcHRzIGF0IGxvYWRpbmcKKyAgICAgKiBoZWFkZXJzIHRoYXQgZG9uJ3QgZXhpc3QgZm9yIGEgcGFydGljdWxhciBtZXNzYWdlLgorICAgICAqCisgICAgICogQ291bGQgdGhpcyBzb21laG93IGJlIGluY2x1ZGVkIGluIHRoZSBJbnRlcm5ldEhlYWRlcnMgb2JqZWN0ID8/CisgICAgICovCisgICAgcHJpdmF0ZSBIYXNodGFibGU8U3RyaW5nLCBTdHJpbmc+IGxvYWRlZEhlYWRlcnMKKwkgICAgPSBuZXcgSGFzaHRhYmxlPD4oMSk7CisKKyAgICAvLyBUaGlzIGlzIG91ciBFbnZlbG9wZQorICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgRW52ZWxvcGVDbWQgPSAiRU5WRUxPUEUgSU5URVJOQUxEQVRFIFJGQzgyMi5TSVpFIjsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yLgorICAgICAqCisgICAgICogQHBhcmFtCWZvbGRlcgl0aGUgZm9sZGVyIGNvbnRhaW5pbmcgdGhpcyBtZXNzYWdlCisgICAgICogQHBhcmFtCW1zZ251bQl0aGUgbWVzc2FnZSBzZXF1ZW5jZSBudW1iZXIKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgSU1BUE1lc3NhZ2UoSU1BUEZvbGRlciBmb2xkZXIsIGludCBtc2dudW0pIHsKKwlzdXBlcihmb2xkZXIsIG1zZ251bSk7CisJZmxhZ3MgPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yLCBmb3IgdXNlIGJ5IElNQVBOZXN0ZWRNZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtCXNlc3Npb24JdGhlIFNlc3Npb24KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgSU1BUE1lc3NhZ2UoU2Vzc2lvbiBzZXNzaW9uKSB7CisJc3VwZXIoc2Vzc2lvbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoaXMgbWVzc2FnZSdzIGZvbGRlcidzIHByb3RvY29sIGNvbm5lY3Rpb24uCisgICAgICogVGhyb3dzIEZvbGRlckNsb3NlZEV4Y2VwdGlvbiwgaWYgdGhlIHByb3RvY29sIGNvbm5lY3Rpb24KKyAgICAgKiBpcyBub3QgYXZhaWxhYmxlLgorICAgICAqCisgICAgICogQVNTRVJUOiBNdXN0IGhvbGQgdGhlIG1lc3NhZ2VDYWNoZUxvY2suCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBJTUFQUHJvdG9jb2wgb2JqZWN0IGZvciB0aGUgY29udGFpbmluZyBmb2xkZXIKKyAgICAgKiBAZXhjZXB0aW9uCVByb3RvY29sRXhjZXB0aW9uIGZvciBwcm90b2NvbCBlcnJvcnMKKyAgICAgKiBAZXhjZXB0aW9uCUZvbGRlckNsb3NlZEV4Y2VwdGlvbiBpZiB0aGUgZm9sZGVyIGlzIGNsb3NlZAorICAgICAqLworICAgIHByb3RlY3RlZCBJTUFQUHJvdG9jb2wgZ2V0UHJvdG9jb2woKQorCQkJICAgIHRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiwgRm9sZGVyQ2xvc2VkRXhjZXB0aW9uIHsKKwkoKElNQVBGb2xkZXIpZm9sZGVyKS53YWl0SWZJZGxlKCk7CisJSU1BUFByb3RvY29sIHAgPSAoKElNQVBGb2xkZXIpZm9sZGVyKS5wcm90b2NvbDsKKwlpZiAocCA9PSBudWxsKQorCSAgICB0aHJvdyBuZXcgRm9sZGVyQ2xvc2VkRXhjZXB0aW9uKGZvbGRlcik7CisJZWxzZQorCSAgICByZXR1cm4gcDsKKyAgICB9CisKKyAgICAvKgorICAgICAqIElzIHRoaXMgYW4gSU1BUDQgUkVWMSBzZXJ2ZXI/CisgICAgICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gaXNSRVYxKCkgdGhyb3dzIEZvbGRlckNsb3NlZEV4Y2VwdGlvbiB7CisJLy8gYWNjZXNzIHRoZSBmb2xkZXIncyBwcm90b2NvbCBvYmplY3Qgd2l0aG91dCB3YWl0aW5nCisJLy8gZm9yIElETEUgdG8gY29tcGxldGUKKwlJTUFQUHJvdG9jb2wgcCA9ICgoSU1BUEZvbGRlcilmb2xkZXIpLnByb3RvY29sOworCWlmIChwID09IG51bGwpCisJICAgIHRocm93IG5ldyBGb2xkZXJDbG9zZWRFeGNlcHRpb24oZm9sZGVyKTsKKwllbHNlCisJICAgIHJldHVybiBwLmlzUkVWMSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgbWVzc2FnZUNhY2hlTG9jaywgYXNzb2NpYXRlZCB3aXRoIHRoaXMgTWVzc2FnZSdzCisgICAgICogRm9sZGVyLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgbWVzc2FnZSBjYWNoZSBsb2NrIG9iamVjdAorICAgICAqLworICAgIHByb3RlY3RlZCBPYmplY3QgZ2V0TWVzc2FnZUNhY2hlTG9jaygpIHsKKwlyZXR1cm4gKChJTUFQRm9sZGVyKWZvbGRlcikubWVzc2FnZUNhY2hlTG9jazsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhpcyBtZXNzYWdlJ3MgSU1BUCBzZXF1ZW5jZSBudW1iZXIuCisgICAgICoKKyAgICAgKiBBU1NFUlQ6IFRoaXMgbWV0aG9kIG11c3QgYmUgY2FsbGVkIG9ubHkgd2hlbiBob2xkaW5nIHRoZQorICAgICAqIAltZXNzYWdlQ2FjaGVMb2NrLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgbWVzc2FnZSBzZXF1ZW5jZSBudW1iZXIKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IGdldFNlcXVlbmNlTnVtYmVyKCkgeworCXJldHVybiAoKElNQVBGb2xkZXIpZm9sZGVyKS5tZXNzYWdlQ2FjaGUuc2VxbnVtT2YoZ2V0TWVzc2FnZU51bWJlcigpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcmFwcGVyIGFyb3VuZCB0aGUgcHJvdGVjdGVkIG1ldGhvZCBNZXNzYWdlLnNldE1lc3NhZ2VOdW1iZXIoKSB0byAKKyAgICAgKiBtYWtlIHRoYXQgbWV0aG9kIGFjY2Vzc2libGUgdG8gSU1BUEZvbGRlci4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRNZXNzYWdlTnVtYmVyKGludCBtc2dudW0pIHsKKwlzdXBlci5zZXRNZXNzYWdlTnVtYmVyKG1zZ251bSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBVSUQgZm9yIHRoaXMgbWVzc2FnZS4KKyAgICAgKiBSZXR1cm5zIC0xIGlmIG5vdCBrbm93bjsgdXNlIFVJREZvbGRlci5nZXRVSUQoKSBpbiB0aGlzIGNhc2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBVSUQKKyAgICAgKiBAc2VlCWphdmF4Lm1haWwuVUlERm9sZGVyI2dldFVJRAorICAgICAqLworICAgIHByb3RlY3RlZCBsb25nIGdldFVJRCgpIHsKKwlyZXR1cm4gdWlkOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVJRChsb25nIHVpZCkgeworCXRoaXMudWlkID0gdWlkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgbW9kaWZpY2F0aW9uIHNlcXVlbmNlIG51bWJlciAoTU9EU0VRKSBmb3IgdGhpcyBtZXNzYWdlLgorICAgICAqIFJldHVybnMgLTEgaWYgbm90IGtub3duLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgbW9kaWZpY2F0aW9uIHNlcXVlbmNlIG51bWJlcgorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqIEBzZWUJIlJGQyA0NTUxIgorICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjUuMQorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgbG9uZyBnZXRNb2RTZXEoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpZiAobW9kc2VxICE9IC0xKQorCSAgICByZXR1cm4gbW9kc2VxOworCisJc3luY2hyb25pemVkIChnZXRNZXNzYWdlQ2FjaGVMb2NrKCkpIHsgLy8gQWNxdWlyZSBMb2NrCisJICAgIHRyeSB7CisJCUlNQVBQcm90b2NvbCBwID0gZ2V0UHJvdG9jb2woKTsKKwkJY2hlY2tFeHB1bmdlZCgpOyAvLyBpbnN1cmUgdGhhdCBtZXNzYWdlIGlzIG5vdCBleHB1bmdlZAorCQlNT0RTRVEgbXMgPSBwLmZldGNoTU9EU0VRKGdldFNlcXVlbmNlTnVtYmVyKCkpOworCisJCWlmIChtcyAhPSBudWxsKQorCQkgICAgbW9kc2VxID0gbXMubW9kc2VxOworCSAgICB9IGNhdGNoIChDb25uZWN0aW9uRXhjZXB0aW9uIGNleCkgeworCQl0aHJvdyBuZXcgRm9sZGVyQ2xvc2VkRXhjZXB0aW9uKGZvbGRlciwgY2V4LmdldE1lc3NhZ2UoKSk7CisJICAgIH0gY2F0Y2ggKFByb3RvY29sRXhjZXB0aW9uIHBleCkgeworCQl0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKHBleC5nZXRNZXNzYWdlKCksIHBleCk7CisJICAgIH0KKwl9CisJcmV0dXJuIG1vZHNlcTsKKyAgICB9CisKKyAgICBsb25nIF9nZXRNb2RTZXEoKSB7CisJcmV0dXJuIG1vZHNlcTsKKyAgICB9CisKKyAgICB2b2lkIHNldE1vZFNlcShsb25nIG1vZHNlcSkgeworCXRoaXMubW9kc2VxID0gbW9kc2VxOworICAgIH0KKworICAgIC8vIGV4cG9zZSB0byBNZXNzYWdlQ2FjaGUKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRFeHB1bmdlZChib29sZWFuIHNldCkgeworCXN1cGVyLnNldEV4cHVuZ2VkKHNldCk7CisgICAgfQorCisgICAgLy8gQ29udmVuaWVuY2Ugcm91dGluZQorICAgIHByb3RlY3RlZCB2b2lkIGNoZWNrRXhwdW5nZWQoKSB0aHJvd3MgTWVzc2FnZVJlbW92ZWRFeGNlcHRpb24geworCWlmIChleHB1bmdlZCkKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2VSZW1vdmVkRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRG8gYSBOT09QIHRvIGZvcmNlIGFueSB1bnRhZ2dlZCBFWFBVTkdFIHJlc3BvbnNlcworICAgICAqIGFuZCB0aGVuIGNoZWNrIGlmIHRoaXMgbWVzc2FnZSBpcyBleHB1bmdlZC4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24JTWVzc2FnZVJlbW92ZWRFeGNlcHRpb24gaWYgdGhlIG1lc3NhZ2UgaGFzIGJlZW4gcmVtb3ZlZAorICAgICAqIEBleGNlcHRpb24JRm9sZGVyQ2xvc2VkRXhjZXB0aW9uIGlmIHRoZSBmb2xkZXIgaGFzIGJlZW4gY2xvc2VkCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgZm9yY2VDaGVja0V4cHVuZ2VkKCkKKwkJCXRocm93cyBNZXNzYWdlUmVtb3ZlZEV4Y2VwdGlvbiwgRm9sZGVyQ2xvc2VkRXhjZXB0aW9uIHsKKwlzeW5jaHJvbml6ZWQgKGdldE1lc3NhZ2VDYWNoZUxvY2soKSkgeworCSAgICB0cnkgeworCQlnZXRQcm90b2NvbCgpLm5vb3AoKTsKKwkgICAgfSBjYXRjaCAoQ29ubmVjdGlvbkV4Y2VwdGlvbiBjZXgpIHsKKwkJdGhyb3cgbmV3IEZvbGRlckNsb3NlZEV4Y2VwdGlvbihmb2xkZXIsIGNleC5nZXRNZXNzYWdlKCkpOworCSAgICB9IGNhdGNoIChQcm90b2NvbEV4Y2VwdGlvbiBwZXgpIHsKKwkJLy8gaWdub3JlIGl0CisJICAgIH0KKwl9CisJaWYgKGV4cHVuZ2VkKQorCSAgICB0aHJvdyBuZXcgTWVzc2FnZVJlbW92ZWRFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICAvLyBSZXR1cm4gdGhlIGJsb2NrIHNpemUgZm9yIEZFVENIIHJlcXVlc3RzCisgICAgLy8gTVVTVCBiZSBvdmVycmlkZGVuIGJ5IElNQVBOZXN0ZWRNZXNzYWdlCisgICAgcHJvdGVjdGVkIGludCBnZXRGZXRjaEJsb2NrU2l6ZSgpIHsKKwlyZXR1cm4gKChJTUFQU3RvcmUpZm9sZGVyLmdldFN0b3JlKCkpLmdldEZldGNoQmxvY2tTaXplKCk7CisgICAgfQorCisgICAgLy8gU2hvdWxkIHdlIGlnbm9yZSB0aGUgc2l6ZSBpbiB0aGUgQk9EWVNUUlVDVFVSRT8KKyAgICAvLyBNVVNUIGJlIG92ZXJyaWRkZW4gYnkgSU1BUE5lc3RlZE1lc3NhZ2UKKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpZ25vcmVCb2R5U3RydWN0dXJlU2l6ZSgpIHsKKwlyZXR1cm4gKChJTUFQU3RvcmUpZm9sZGVyLmdldFN0b3JlKCkpLmlnbm9yZUJvZHlTdHJ1Y3R1cmVTaXplKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSAiRnJvbSIgYXR0cmlidXRlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBBZGRyZXNzW10gZ2V0RnJvbSgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWNoZWNrRXhwdW5nZWQoKTsKKwlpZiAoYm9keUxvYWRlZCkKKwkgICAgcmV0dXJuIHN1cGVyLmdldEZyb20oKTsKKwlsb2FkRW52ZWxvcGUoKTsKKwlJbnRlcm5ldEFkZHJlc3NbXSBhID0gZW52ZWxvcGUuZnJvbTsKKwkvKgorCSAqIFBlciBSRkMgMjgyMiwgdGhlIEZyb20gaGVhZGVyIGlzIHJlcXVpcmVkLCBhbmQgdGh1cyB0aGUgSU1BUAorCSAqIHNwZWMgYWxzbyByZXF1aXJlcyB0aGF0IGl0IGJlIHByZXNlbnQsIGJ1dCB3ZSBrbm93IHRoYXQgaW4KKwkgKiBwcmFjdGljZSBpdCBpcyBvZnRlbiBtaXNzaW5nLiAgU29tZSBzZXJ2ZXJzIGZpbGwgaW4gdGhlCisJICogRnJvbSBmaWVsZCB3aXRoIHRoZSBTZW5kZXIgZmllbGQgaW4gdGhpcyBjYXNlLCBidXQgYXQgbGVhc3QKKwkgKiBFeGNoYW5nZSAyMDA3IGRvZXMgbm90LiAgVXNlIHRoZSBzYW1lIGZhbGxiYWNrIHN0cmF0ZWd5IHVzZWQKKwkgKiBieSBNaW1lTWVzc2FnZS4KKwkgKi8KKwlpZiAoYSA9PSBudWxsIHx8IGEubGVuZ3RoID09IDApCisJICAgIGEgPSBlbnZlbG9wZS5zZW5kZXI7CisJcmV0dXJuIGFhY2xvbmUoYSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0RnJvbShBZGRyZXNzIGFkZHJlc3MpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXRocm93IG5ldyBJbGxlZ2FsV3JpdGVFeGNlcHRpb24oIklNQVBNZXNzYWdlIGlzIHJlYWQtb25seSIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGFkZEZyb20oQWRkcmVzc1tdIGFkZHJlc3NlcykgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJdGhyb3cgbmV3IElsbGVnYWxXcml0ZUV4Y2VwdGlvbigiSU1BUE1lc3NhZ2UgaXMgcmVhZC1vbmx5Iik7CisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIEdldCB0aGUgIlNlbmRlciIgYXR0cmlidXRlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBBZGRyZXNzIGdldFNlbmRlcigpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWNoZWNrRXhwdW5nZWQoKTsKKwlpZiAoYm9keUxvYWRlZCkKKwkgICAgcmV0dXJuIHN1cGVyLmdldFNlbmRlcigpOworCWxvYWRFbnZlbG9wZSgpOworCWlmIChlbnZlbG9wZS5zZW5kZXIgIT0gbnVsbCAmJiBlbnZlbG9wZS5zZW5kZXIubGVuZ3RoID4gMCkKKwkJcmV0dXJuIChlbnZlbG9wZS5zZW5kZXIpWzBdOwkvLyB0aGVyZSBjYW4gYmUgb25seSBvbmUgc2VuZGVyCisJZWxzZSAKKwkJcmV0dXJuIG51bGw7CisgICAgfQorCQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0U2VuZGVyKEFkZHJlc3MgYWRkcmVzcykgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJdGhyb3cgbmV3IElsbGVnYWxXcml0ZUV4Y2VwdGlvbigiSU1BUE1lc3NhZ2UgaXMgcmVhZC1vbmx5Iik7CisgICAgfSAgICAKKworICAgIC8qKgorICAgICAqIEdldCB0aGUgZGVzaXJlZCBSZWNpcGllbnQgdHlwZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQWRkcmVzc1tdIGdldFJlY2lwaWVudHMoTWVzc2FnZS5SZWNpcGllbnRUeXBlIHR5cGUpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJY2hlY2tFeHB1bmdlZCgpOworCWlmIChib2R5TG9hZGVkKQorCSAgICByZXR1cm4gc3VwZXIuZ2V0UmVjaXBpZW50cyh0eXBlKTsKKwlsb2FkRW52ZWxvcGUoKTsKKworCWlmICh0eXBlID09IE1lc3NhZ2UuUmVjaXBpZW50VHlwZS5UTykKKwkgICAgcmV0dXJuIGFhY2xvbmUoZW52ZWxvcGUudG8pOworCWVsc2UgaWYgKHR5cGUgPT0gTWVzc2FnZS5SZWNpcGllbnRUeXBlLkNDKQorCSAgICByZXR1cm4gYWFjbG9uZShlbnZlbG9wZS5jYyk7CisJZWxzZSBpZiAodHlwZSA9PSBNZXNzYWdlLlJlY2lwaWVudFR5cGUuQkNDKQorCSAgICByZXR1cm4gYWFjbG9uZShlbnZlbG9wZS5iY2MpOworCWVsc2UKKwkgICAgcmV0dXJuIHN1cGVyLmdldFJlY2lwaWVudHModHlwZSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0UmVjaXBpZW50cyhNZXNzYWdlLlJlY2lwaWVudFR5cGUgdHlwZSwgQWRkcmVzc1tdIGFkZHJlc3NlcykKKwkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXRocm93IG5ldyBJbGxlZ2FsV3JpdGVFeGNlcHRpb24oIklNQVBNZXNzYWdlIGlzIHJlYWQtb25seSIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGFkZFJlY2lwaWVudHMoTWVzc2FnZS5SZWNpcGllbnRUeXBlIHR5cGUsIEFkZHJlc3NbXSBhZGRyZXNzZXMpCisJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwl0aHJvdyBuZXcgSWxsZWdhbFdyaXRlRXhjZXB0aW9uKCJJTUFQTWVzc2FnZSBpcyByZWFkLW9ubHkiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIFJlcGx5VG8gYWRkcmVzc2VzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBBZGRyZXNzW10gZ2V0UmVwbHlUbygpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWNoZWNrRXhwdW5nZWQoKTsKKwlpZiAoYm9keUxvYWRlZCkKKwkgICAgcmV0dXJuIHN1cGVyLmdldFJlcGx5VG8oKTsKKwlsb2FkRW52ZWxvcGUoKTsKKwkvKgorCSAqIFRoZSBJTUFQIHNwZWMgcmVxdWlyZXMgdGhhdCB0aGUgUmVwbHktVG8gZmllbGQgbmV2ZXIgYmUKKwkgKiBudWxsLCBidXQgYXQgbGVhc3QgRXhjaGFuZ2UgMjAwNyBmYWlscyB0byBmaWxsIGl0IGluIGluCisJICogc29tZSBjYXNlcy4gIFVzZSB0aGUgc2FtZSBmYWxsYmFjayBzdHJhdGVneSB1c2VkIGJ5CisJICogTWltZU1lc3NhZ2UuCisJICovCisJaWYgKGVudmVsb3BlLnJlcGx5VG8gPT0gbnVsbCB8fCBlbnZlbG9wZS5yZXBseVRvLmxlbmd0aCA9PSAwKQorCSAgICByZXR1cm4gZ2V0RnJvbSgpOworCXJldHVybiBhYWNsb25lKGVudmVsb3BlLnJlcGx5VG8pOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFJlcGx5VG8oQWRkcmVzc1tdIGFkZHJlc3NlcykgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJdGhyb3cgbmV3IElsbGVnYWxXcml0ZUV4Y2VwdGlvbigiSU1BUE1lc3NhZ2UgaXMgcmVhZC1vbmx5Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBkZWNvZGVkIHN1YmplY3QuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXRTdWJqZWN0KCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJY2hlY2tFeHB1bmdlZCgpOworCWlmIChib2R5TG9hZGVkKQorCSAgICByZXR1cm4gc3VwZXIuZ2V0U3ViamVjdCgpOworCisJaWYgKHN1YmplY3QgIT0gbnVsbCkgLy8gYWxyZWFkeSBjYWNoZWQgPworCSAgICByZXR1cm4gc3ViamVjdDsKKworCWxvYWRFbnZlbG9wZSgpOworCWlmIChlbnZlbG9wZS5zdWJqZWN0ID09IG51bGwpIC8vIG5vIHN1YmplY3QKKwkgICAgcmV0dXJuIG51bGw7CisKKwkvLyBDYWNoZSBhbmQgcmV0dXJuIHRoZSBkZWNvZGVkIHZhbHVlLgorCXRyeSB7CisJICAgIC8vIFRoZSBzZXJ2ZXIgKnNob3VsZCogdW5mb2xkIHRoZSB2YWx1ZSwgYnV0IGp1c3QgaW4gY2FzZSBpdAorCSAgICAvLyBkb2Vzbid0IHdlIHVuZm9sZCBpdCBoZXJlLgorCSAgICBzdWJqZWN0ID0KKwkJTWltZVV0aWxpdHkuZGVjb2RlVGV4dChNaW1lVXRpbGl0eS51bmZvbGQoZW52ZWxvcGUuc3ViamVjdCkpOworCX0gY2F0Y2ggKFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gZXgpIHsKKwkgICAgc3ViamVjdCA9IGVudmVsb3BlLnN1YmplY3Q7CisJfQorCisJcmV0dXJuIHN1YmplY3Q7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0U3ViamVjdChTdHJpbmcgc3ViamVjdCwgU3RyaW5nIGNoYXJzZXQpIAorCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwl0aHJvdyBuZXcgSWxsZWdhbFdyaXRlRXhjZXB0aW9uKCJJTUFQTWVzc2FnZSBpcyByZWFkLW9ubHkiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIFNlbnREYXRlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBEYXRlIGdldFNlbnREYXRlKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJY2hlY2tFeHB1bmdlZCgpOworCWlmIChib2R5TG9hZGVkKQorCSAgICByZXR1cm4gc3VwZXIuZ2V0U2VudERhdGUoKTsKKwlsb2FkRW52ZWxvcGUoKTsKKwlpZiAoZW52ZWxvcGUuZGF0ZSA9PSBudWxsKQorCSAgICByZXR1cm4gbnVsbDsKKwllbHNlCisJICAgIHJldHVybiBuZXcgRGF0ZShlbnZlbG9wZS5kYXRlLmdldFRpbWUoKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0U2VudERhdGUoRGF0ZSBkKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwl0aHJvdyBuZXcgSWxsZWdhbFdyaXRlRXhjZXB0aW9uKCJJTUFQTWVzc2FnZSBpcyByZWFkLW9ubHkiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIHJlY2VpdmVkIGRhdGUgKElOVEVSTkFMREFURSkuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIERhdGUgZ2V0UmVjZWl2ZWREYXRlKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJY2hlY2tFeHB1bmdlZCgpOworCWlmIChyZWNlaXZlZERhdGUgPT0gbnVsbCkKKwkgICAgbG9hZEVudmVsb3BlKCk7IC8vIGhhdmUgdG8gZ28gdG8gdGhlIHNlcnZlciBmb3IgdGhpcworCWlmIChyZWNlaXZlZERhdGUgPT0gbnVsbCkKKwkgICAgcmV0dXJuIG51bGw7CisJZWxzZQorCSAgICByZXR1cm4gbmV3IERhdGUocmVjZWl2ZWREYXRlLmdldFRpbWUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBtZXNzYWdlIHNpemUuIDxwPgorICAgICAqCisgICAgICogTm90ZSB0aGF0IHRoaXMgcmV0dXJucyBSRkM4MjIuU0laRS4gIFRoYXQgaXMsIGl0J3MgdGhlCisgICAgICogc2l6ZSBvZiB0aGUgd2hvbGUgbWVzc2FnZSwgaGVhZGVyIGFuZCBib2R5IGluY2x1ZGVkLgorICAgICAqIE5vdGUgYWxzbyB0aGF0IGlmIHRoZSBzaXplIG9mIHRoZSBtZXNzYWdlIGlzIGdyZWF0ZXIgdGhhbgorICAgICAqIEludGVnZXIuTUFYX1ZBTFVFICgyR0IpLCB0aGlzIG1ldGhvZCByZXR1cm5zIEludGVnZXIuTUFYX1ZBTFVFLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0U2l6ZSgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWNoZWNrRXhwdW5nZWQoKTsKKwkvLyBpZiBib2R5TG9hZGVkLCBzaXplIGlzIGFscmVhZHkgc2V0CisJaWYgKHNpemUgPT0gLTEpCisJICAgIGxvYWRFbnZlbG9wZSgpOwkvLyBYWFggLSBjb3VsZCBqdXN0IGZldGNoIHRoZSBzaXplCisJaWYgKHNpemUgPiBJbnRlZ2VyLk1BWF9WQUxVRSkKKwkgICAgcmV0dXJuIEludGVnZXIuTUFYX1ZBTFVFOwkvLyB0aGUgYmVzdCB3ZSBjYW4gZG8uLi4KKwllbHNlCisJICAgIHJldHVybiAoaW50KXNpemU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBtZXNzYWdlIHNpemUgYXMgYSBsb25nLiA8cD4KKyAgICAgKgorICAgICAqIFN1aXRhYmxlIGZvciBtZXNzYWdlcyB0aGF0IG1pZ2h0IGJlIGxhcmdlciB0aGFuIDJHQi4KKyAgICAgKiBAcmV0dXJuCXRoZSBtZXNzYWdlIHNpemUgYXMgYSBsb25nIGludGVnZXIKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS42CisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0U2l6ZUxvbmcoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwljaGVja0V4cHVuZ2VkKCk7CisJLy8gaWYgYm9keUxvYWRlZCwgc2l6ZSBpcyBhbHJlYWR5IHNldAorCWlmIChzaXplID09IC0xKQorCSAgICBsb2FkRW52ZWxvcGUoKTsJLy8gWFhYIC0gY291bGQganVzdCBmZXRjaCB0aGUgc2l6ZQorCXJldHVybiBzaXplOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgdG90YWwgbnVtYmVyIG9mIGxpbmVzLiA8cD4KKyAgICAgKgorICAgICAqIFJldHVybnMgdGhlICJib2R5X2ZsZF9saW5lcyIgZmllbGQgZnJvbSB0aGUKKyAgICAgKiBCT0RZU1RSVUNUVVJFLiBOb3RlIHRoYXQgdGhpcyBmaWVsZCBpcyBhdmFpbGFibGUKKyAgICAgKiBvbmx5IGZvciB0ZXh0L3BsYWluIGFuZCBtZXNzYWdlL3JmYzgyMiB0eXBlcworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0TGluZUNvdW50KCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJY2hlY2tFeHB1bmdlZCgpOworCS8vIFhYWCAtIHN1cGVyY2xhc3MgZG9lc24ndCBpbXBsZW1lbnQgdGhpcworCWxvYWRCT0RZU1RSVUNUVVJFKCk7CisJcmV0dXJuIGJzLmxpbmVzOworICAgIH0KKworICAgIC8qKiAKKyAgICAgKiBHZXQgdGhlIGNvbnRlbnQgbGFuZ3VhZ2UuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZ1tdIGdldENvbnRlbnRMYW5ndWFnZSgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworICAgIAljaGVja0V4cHVuZ2VkKCk7CisJaWYgKGJvZHlMb2FkZWQpCisJICAgIHJldHVybiBzdXBlci5nZXRDb250ZW50TGFuZ3VhZ2UoKTsKKyAgICAJbG9hZEJPRFlTVFJVQ1RVUkUoKTsKKyAgICAJaWYgKGJzLmxhbmd1YWdlICE9IG51bGwpCisJICAgIHJldHVybiBicy5sYW5ndWFnZS5jbG9uZSgpOworICAgIAllbHNlCisJICAgIHJldHVybiBudWxsOworICAgIH0KKyAKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRDb250ZW50TGFuZ3VhZ2UoU3RyaW5nW10gbGFuZ3VhZ2VzKQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworICAgIAl0aHJvdyBuZXcgSWxsZWdhbFdyaXRlRXhjZXB0aW9uKCJJTUFQTWVzc2FnZSBpcyByZWFkLW9ubHkiKTsKKyAgICB9CisgCisgICAgLyoqCisgICAgICogR2V0IHRoZSBJbi1SZXBseS1UbyBoZWFkZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBJbi1SZXBseS1UbyBoZWFkZXIKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS4zLjMKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEluUmVwbHlUbygpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworICAgIAljaGVja0V4cHVuZ2VkKCk7CisJaWYgKGJvZHlMb2FkZWQpCisJICAgIHJldHVybiBzdXBlci5nZXRIZWFkZXIoIkluLVJlcGx5LVRvIiwgIiAiKTsKKyAgICAJbG9hZEVudmVsb3BlKCk7CisgICAgCXJldHVybiBlbnZlbG9wZS5pblJlcGx5VG87CisgICAgfQorIAorICAgIC8qKgorICAgICAqIEdldCB0aGUgQ29udGVudC1UeXBlLgorICAgICAqCisgICAgICogR2VuZXJhdGUgdGhpcyBoZWFkZXIgZnJvbSB0aGUgQk9EWVNUUlVDVFVSRS4gQXBwZW5kIHBhcmFtZXRlcnMKKyAgICAgKiBhcyB3ZWxsLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgU3RyaW5nIGdldENvbnRlbnRUeXBlKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJY2hlY2tFeHB1bmdlZCgpOworCWlmIChib2R5TG9hZGVkKQorCSAgICByZXR1cm4gc3VwZXIuZ2V0Q29udGVudFR5cGUoKTsKKworCS8vIElmIHdlIGhhdmVuJ3QgY2FjaGVkIHRoZSB0eXBlIHlldCAuLgorCWlmICh0eXBlID09IG51bGwpIHsKKwkgICAgbG9hZEJPRFlTVFJVQ1RVUkUoKTsKKwkgICAgLy8gZ2VuZXJhdGUgY29udGVudC10eXBlIGZyb20gQk9EWVNUUlVDVFVSRQorCSAgICBDb250ZW50VHlwZSBjdCA9IG5ldyBDb250ZW50VHlwZShicy50eXBlLCBicy5zdWJ0eXBlLCBicy5jUGFyYW1zKTsKKwkgICAgdHlwZSA9IGN0LnRvU3RyaW5nKCk7CisJfQorCXJldHVybiB0eXBlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgQ29udGVudC1EaXNwb3NpdGlvbi4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldERpc3Bvc2l0aW9uKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJY2hlY2tFeHB1bmdlZCgpOworCWlmIChib2R5TG9hZGVkKQorCSAgICByZXR1cm4gc3VwZXIuZ2V0RGlzcG9zaXRpb24oKTsKKwlsb2FkQk9EWVNUUlVDVFVSRSgpOworCXJldHVybiBicy5kaXNwb3NpdGlvbjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXREaXNwb3NpdGlvbihTdHJpbmcgZGlzcG9zaXRpb24pIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXRocm93IG5ldyBJbGxlZ2FsV3JpdGVFeGNlcHRpb24oIklNQVBNZXNzYWdlIGlzIHJlYWQtb25seSIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldEVuY29kaW5nKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJY2hlY2tFeHB1bmdlZCgpOworCWlmIChib2R5TG9hZGVkKQorCSAgICByZXR1cm4gc3VwZXIuZ2V0RW5jb2RpbmcoKTsKKwlsb2FkQk9EWVNUUlVDVFVSRSgpOworCXJldHVybiBicy5lbmNvZGluZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIENvbnRlbnQtSUQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXRDb250ZW50SUQoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwljaGVja0V4cHVuZ2VkKCk7CisJaWYgKGJvZHlMb2FkZWQpCisJICAgIHJldHVybiBzdXBlci5nZXRDb250ZW50SUQoKTsKKwlsb2FkQk9EWVNUUlVDVFVSRSgpOworCXJldHVybiBicy5pZDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRDb250ZW50SUQoU3RyaW5nIGNpZCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJdGhyb3cgbmV3IElsbGVnYWxXcml0ZUV4Y2VwdGlvbigiSU1BUE1lc3NhZ2UgaXMgcmVhZC1vbmx5Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBDb250ZW50LU1ENS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldENvbnRlbnRNRDUoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwljaGVja0V4cHVuZ2VkKCk7CisJaWYgKGJvZHlMb2FkZWQpCisJICAgIHJldHVybiBzdXBlci5nZXRDb250ZW50TUQ1KCk7CisJbG9hZEJPRFlTVFJVQ1RVUkUoKTsKKwlyZXR1cm4gYnMubWQ1OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldENvbnRlbnRNRDUoU3RyaW5nIG1kNSkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJdGhyb3cgbmV3IElsbGVnYWxXcml0ZUV4Y2VwdGlvbigiSU1BUE1lc3NhZ2UgaXMgcmVhZC1vbmx5Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBkZWNvZGVkIENvbnRlbnQtRGVzY3JpcHRpb24uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXREZXNjcmlwdGlvbigpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWNoZWNrRXhwdW5nZWQoKTsKKwlpZiAoYm9keUxvYWRlZCkKKwkgICAgcmV0dXJuIHN1cGVyLmdldERlc2NyaXB0aW9uKCk7CisKKwlpZiAoZGVzY3JpcHRpb24gIT0gbnVsbCkgLy8gY2FjaGVkIHZhbHVlID8KKwkgICAgcmV0dXJuIGRlc2NyaXB0aW9uOworCQorCWxvYWRCT0RZU1RSVUNUVVJFKCk7CisJaWYgKGJzLmRlc2NyaXB0aW9uID09IG51bGwpCisJICAgIHJldHVybiBudWxsOworCQorCXRyeSB7CisJICAgIGRlc2NyaXB0aW9uID0gTWltZVV0aWxpdHkuZGVjb2RlVGV4dChicy5kZXNjcmlwdGlvbik7CisJfSBjYXRjaCAoVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBleCkgeworCSAgICBkZXNjcmlwdGlvbiA9IGJzLmRlc2NyaXB0aW9uOworCX0KKworCXJldHVybiBkZXNjcmlwdGlvbjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXREZXNjcmlwdGlvbihTdHJpbmcgZGVzY3JpcHRpb24sIFN0cmluZyBjaGFyc2V0KSAKKwkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXRocm93IG5ldyBJbGxlZ2FsV3JpdGVFeGNlcHRpb24oIklNQVBNZXNzYWdlIGlzIHJlYWQtb25seSIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgTWVzc2FnZS1JRC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldE1lc3NhZ2VJRCgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWNoZWNrRXhwdW5nZWQoKTsKKwlpZiAoYm9keUxvYWRlZCkKKwkgICAgcmV0dXJuIHN1cGVyLmdldE1lc3NhZ2VJRCgpOworCWxvYWRFbnZlbG9wZSgpOworCXJldHVybiBlbnZlbG9wZS5tZXNzYWdlSWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSAiZmlsZW5hbWUiIERpc3Bvc2l0aW9uIHBhcmFtZXRlci4gKE9ubHkgYXZhaWxhYmxlIGluCisgICAgICogSU1BUDRyZXYxKS4gSWYgdGhhdHMgbm90IGF2YWlsYWJsZSwgZ2V0IHRoZSAibmFtZSIgQ29udGVudFR5cGUKKyAgICAgKiBwYXJhbWV0ZXIuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXRGaWxlTmFtZSgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWNoZWNrRXhwdW5nZWQoKTsKKwlpZiAoYm9keUxvYWRlZCkKKwkgICAgcmV0dXJuIHN1cGVyLmdldEZpbGVOYW1lKCk7CisKKwlTdHJpbmcgZmlsZW5hbWUgPSBudWxsOworCWxvYWRCT0RZU1RSVUNUVVJFKCk7CisKKwlpZiAoYnMuZFBhcmFtcyAhPSBudWxsKQorCSAgICBmaWxlbmFtZSA9IGJzLmRQYXJhbXMuZ2V0KCJmaWxlbmFtZSIpOworCWlmIChmaWxlbmFtZSA9PSBudWxsICYmIGJzLmNQYXJhbXMgIT0gbnVsbCkKKwkgICAgZmlsZW5hbWUgPSBicy5jUGFyYW1zLmdldCgibmFtZSIpOworCXJldHVybiBmaWxlbmFtZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRGaWxlTmFtZShTdHJpbmcgZmlsZW5hbWUpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXRocm93IG5ldyBJbGxlZ2FsV3JpdGVFeGNlcHRpb24oIklNQVBNZXNzYWdlIGlzIHJlYWQtb25seSIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCBhbGwgdGhlIGJ5dGVzIGZvciB0aGlzIG1lc3NhZ2UuIE92ZXJyaWRlcyBnZXRDb250ZW50U3RyZWFtKCkKKyAgICAgKiBpbiBNaW1lTWVzc2FnZS4gVGhpcyBtZXRob2QgaXMgdWx0aW1hdGVseSB1c2VkIGJ5IHRoZSBEYXRhSGFuZGxlcgorICAgICAqIHRvIG9idGFpbiB0aGUgaW5wdXQgc3RyZWFtIGZvciB0aGlzIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAc2VlIGphdmF4Lm1haWwuaW50ZXJuZXQuTWltZU1lc3NhZ2UjZ2V0Q29udGVudFN0cmVhbQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBJbnB1dFN0cmVhbSBnZXRDb250ZW50U3RyZWFtKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKGJvZHlMb2FkZWQpCisJICAgIHJldHVybiBzdXBlci5nZXRDb250ZW50U3RyZWFtKCk7CisJSW5wdXRTdHJlYW0gaXMgPSBudWxsOworCWJvb2xlYW4gcGsgPSBnZXRQZWVrKCk7CS8vIGdldCBiZWZvcmUgYWNxdWlyaW5nIG1lc3NhZ2UgY2FjaGUgbG9jaworCisgICAgICAgIC8vIEFjcXVpcmUgTWVzc2FnZUNhY2hlTG9jaywgdG8gZnJlZXplIHNlcW51bS4KKyAgICAgICAgc3luY2hyb25pemVkKGdldE1lc3NhZ2VDYWNoZUxvY2soKSkgeworCSAgICB0cnkgeworCQlJTUFQUHJvdG9jb2wgcCA9IGdldFByb3RvY29sKCk7CisKKwkJLy8gVGhpcyBtZXNzYWdlIGNvdWxkIGJlIGV4cHVuZ2VkIHdoZW4gd2Ugd2VyZSB3YWl0aW5nCisJCS8vIHRvIGFjcXVpcmUgdGhlIGxvY2sgLi4uCisJCWNoZWNrRXhwdW5nZWQoKTsKKworCQlpZiAocC5pc1JFVjEoKSAmJiAoZ2V0RmV0Y2hCbG9ja1NpemUoKSAhPSAtMSkpIC8vIElNQVA0cmV2MQorCQkgICAgcmV0dXJuIG5ldyBJTUFQSW5wdXRTdHJlYW0odGhpcywgdG9TZWN0aW9uKCJURVhUIiksCisJCQkJICAgIGJzICE9IG51bGwgJiYgIWlnbm9yZUJvZHlTdHJ1Y3R1cmVTaXplKCkgPworCQkJCQlicy5zaXplIDogLTEsIHBrKTsKKworCQlpZiAocC5pc1JFVjEoKSkgeworCQkgICAgQk9EWSBiOworCQkgICAgaWYgKHBrKQorCQkJYiA9IHAucGVla0JvZHkoZ2V0U2VxdWVuY2VOdW1iZXIoKSwgdG9TZWN0aW9uKCJURVhUIikpOworCQkgICAgZWxzZQorCQkJYiA9IHAuZmV0Y2hCb2R5KGdldFNlcXVlbmNlTnVtYmVyKCksIHRvU2VjdGlvbigiVEVYVCIpKTsKKwkJICAgIGlmIChiICE9IG51bGwpCisJCQlpcyA9IGIuZ2V0Qnl0ZUFycmF5SW5wdXRTdHJlYW0oKTsKKwkJfSBlbHNlIHsKKwkJICAgIFJGQzgyMkRBVEEgcmQgPSBwLmZldGNoUkZDODIyKGdldFNlcXVlbmNlTnVtYmVyKCksICJURVhUIik7CisJCSAgICBpZiAocmQgIT0gbnVsbCkKKwkJCWlzID0gcmQuZ2V0Qnl0ZUFycmF5SW5wdXRTdHJlYW0oKTsKKwkJfQorCSAgICB9IGNhdGNoIChDb25uZWN0aW9uRXhjZXB0aW9uIGNleCkgeworCQl0aHJvdyBuZXcgRm9sZGVyQ2xvc2VkRXhjZXB0aW9uKGZvbGRlciwgY2V4LmdldE1lc3NhZ2UoKSk7CisJICAgIH0gY2F0Y2ggKFByb3RvY29sRXhjZXB0aW9uIHBleCkgeworCQlmb3JjZUNoZWNrRXhwdW5nZWQoKTsKKwkJdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbihwZXguZ2V0TWVzc2FnZSgpLCBwZXgpOworCSAgICB9CisJfQorCisJaWYgKGlzID09IG51bGwpIHsKKwkgICAgZm9yY2VDaGVja0V4cHVuZ2VkKCk7CS8vIG1heSB0aHJvdyBNZXNzYWdlUmVtb3ZlZEV4Y2VwdGlvbgorCSAgICAvLyBub3BlLCB0aGUgc2VydmVyIGRvZXNuJ3QgdGhpbmsgaXQncyBleHB1bmdlZC4KKwkgICAgLy8gY2FuJ3QgdGVsbCB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBzZXJ2ZXIgcmV0dXJuaW5nIE5JTAorCSAgICAvLyBhbmQgc29tZSBvdGhlciBlcnJvciB0aGF0IGNhdXNlZCBudWxsIHRvIGJlIHJldHVybmVkIGFib3ZlLAorCSAgICAvLyBzbyB3ZSdsbCBqdXN0IGFzc3VtZSBpdCB3YXMgZW1wdHkgY29udGVudC4KKwkgICAgaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0obmV3IGJ5dGVbMF0pOworCX0KKwlyZXR1cm4gaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBEYXRhSGFuZGxlciBvYmplY3QgZm9yIHRoaXMgbWVzc2FnZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIERhdGFIYW5kbGVyIGdldERhdGFIYW5kbGVyKCkKKwkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJY2hlY2tFeHB1bmdlZCgpOworCisJaWYgKGRoID09IG51bGwgJiYgIWJvZHlMb2FkZWQpIHsKKwkgICAgbG9hZEJPRFlTVFJVQ1RVUkUoKTsKKwkgICAgaWYgKHR5cGUgPT0gbnVsbCkgeyAvLyB0eXBlIG5vdCB5ZXQgY29tcHV0ZWQKKwkJLy8gZ2VuZXJhdGUgY29udGVudC10eXBlIGZyb20gQk9EWVNUUlVDVFVSRQorCQlDb250ZW50VHlwZSBjdCA9IG5ldyBDb250ZW50VHlwZShicy50eXBlLCBicy5zdWJ0eXBlLAorCQkJCQkJIGJzLmNQYXJhbXMpOworCQl0eXBlID0gY3QudG9TdHJpbmcoKTsKKwkgICAgfQorCisJICAgIC8qIFNwZWNpYWwtY2FzZSBNdWx0aXBhcnQgYW5kIE5lc3RlZCBjb250ZW50LiBBbGwgb3RoZXIKKwkgICAgICogY2FzZXMgYXJlIGhhbmRsZWQgYnkgdGhlIHN1cGVyY2xhc3MuCisJICAgICAqLworCSAgICBpZiAoYnMuaXNNdWx0aSgpKQorCQlkaCA9IG5ldyBEYXRhSGFuZGxlcigKKwkJCW5ldyBJTUFQTXVsdGlwYXJ0RGF0YVNvdXJjZSh0aGlzLCBicy5ib2RpZXMsIAorCQkJCQkJICAgIHNlY3Rpb25JZCwgdGhpcykKKwkJICAgICApOworCSAgICBlbHNlIGlmIChicy5pc05lc3RlZCgpICYmIGlzUkVWMSgpICYmIGJzLmVudmVsb3BlICE9IG51bGwpCisJCS8qIE5lc3RlZCBtZXNzYWdlcyBhcmUgaGFuZGxlZCBzcGVjaWFsbHkgb25seSBmb3IKKwkJICogSU1BUDRyZXYxLiBJTUFQNCBkb2Vzbid0IHByb3ZpZGUgZW5vdWdoIHN1cHBvcnQgdG8gCisJCSAqIEZFVENIIHRoZSBjb21wb25lbnRzIG9mIG5lc3RlZCBtZXNzYWdlcworCQkgKi8KKwkJZGggPSBuZXcgRGF0YUhhbmRsZXIoCisJCQkgICAgbmV3IElNQVBOZXN0ZWRNZXNzYWdlKHRoaXMsIAorCQkJCWJzLmJvZGllc1swXSwgCisJCQkJYnMuZW52ZWxvcGUsCisJCQkJc2VjdGlvbklkID09IG51bGwgPyAiMSIgOiBzZWN0aW9uSWQgKyAiLjEiKSwKKwkJCSAgICB0eXBlCisJCSAgICAgKTsKKwl9CisKKwlyZXR1cm4gc3VwZXIuZ2V0RGF0YUhhbmRsZXIoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXREYXRhSGFuZGxlcihEYXRhSGFuZGxlciBjb250ZW50KSAKKwkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXRocm93IG5ldyBJbGxlZ2FsV3JpdGVFeGNlcHRpb24oIklNQVBNZXNzYWdlIGlzIHJlYWQtb25seSIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgTUlNRSBmb3JtYXQgc3RyZWFtIGNvcnJlc3BvbmRpbmcgdG8gdGhpcyBtZXNzYWdlLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgTUlNRSBmb3JtYXQgc3RyZWFtCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNC41CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIElucHV0U3RyZWFtIGdldE1pbWVTdHJlYW0oKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwkvLyBYWFggLSBuZWVkIGFuICJpZiAoYm9keUxvYWRlZCkiIHZlcnNpb24KKwlJbnB1dFN0cmVhbSBpcyA9IG51bGw7CisJYm9vbGVhbiBwayA9IGdldFBlZWsoKTsJLy8gZ2V0IGJlZm9yZSBhY3F1aXJpbmcgbWVzc2FnZSBjYWNoZSBsb2NrCisKKyAgICAgICAgLy8gQWNxdWlyZSBNZXNzYWdlQ2FjaGVMb2NrLCB0byBmcmVlemUgc2VxbnVtLgorICAgICAgICBzeW5jaHJvbml6ZWQoZ2V0TWVzc2FnZUNhY2hlTG9jaygpKSB7CisJICAgIHRyeSB7CisJCUlNQVBQcm90b2NvbCBwID0gZ2V0UHJvdG9jb2woKTsKKworCQljaGVja0V4cHVuZ2VkKCk7IC8vIGluc3VyZSB0aGlzIG1lc3NhZ2UgaXMgbm90IGV4cHVuZ2VkCisKKwkJaWYgKHAuaXNSRVYxKCkgJiYgKGdldEZldGNoQmxvY2tTaXplKCkgIT0gLTEpKSAvLyBJTUFQNHJldjEKKwkJICAgIHJldHVybiBuZXcgSU1BUElucHV0U3RyZWFtKHRoaXMsIHNlY3Rpb25JZCwgLTEsIHBrKTsKKworCQlpZiAocC5pc1JFVjEoKSkgeworCQkgICAgQk9EWSBiOworCQkgICAgaWYgKHBrKQorCQkJYiA9IHAucGVla0JvZHkoZ2V0U2VxdWVuY2VOdW1iZXIoKSwgc2VjdGlvbklkKTsKKwkJICAgIGVsc2UKKwkJCWIgPSBwLmZldGNoQm9keShnZXRTZXF1ZW5jZU51bWJlcigpLCBzZWN0aW9uSWQpOworCQkgICAgaWYgKGIgIT0gbnVsbCkKKwkJCWlzID0gYi5nZXRCeXRlQXJyYXlJbnB1dFN0cmVhbSgpOworCQl9IGVsc2UgeworCQkgICAgUkZDODIyREFUQSByZCA9IHAuZmV0Y2hSRkM4MjIoZ2V0U2VxdWVuY2VOdW1iZXIoKSwgbnVsbCk7CisJCSAgICBpZiAocmQgIT0gbnVsbCkKKwkJCWlzID0gcmQuZ2V0Qnl0ZUFycmF5SW5wdXRTdHJlYW0oKTsKKwkJfQorCSAgICB9IGNhdGNoIChDb25uZWN0aW9uRXhjZXB0aW9uIGNleCkgeworCQl0aHJvdyBuZXcgRm9sZGVyQ2xvc2VkRXhjZXB0aW9uKGZvbGRlciwgY2V4LmdldE1lc3NhZ2UoKSk7CisJICAgIH0gY2F0Y2ggKFByb3RvY29sRXhjZXB0aW9uIHBleCkgeworCQlmb3JjZUNoZWNrRXhwdW5nZWQoKTsKKwkJdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbihwZXguZ2V0TWVzc2FnZSgpLCBwZXgpOworCSAgICB9CisJfQorCisJaWYgKGlzID09IG51bGwpIHsKKwkgICAgZm9yY2VDaGVja0V4cHVuZ2VkKCk7CS8vIG1heSB0aHJvdyBNZXNzYWdlUmVtb3ZlZEV4Y2VwdGlvbgorCSAgICAvLyBub3BlLCB0aGUgc2VydmVyIGRvZXNuJ3QgdGhpbmsgaXQncyBleHB1bmdlZC4KKwkgICAgLy8gY2FuJ3QgdGVsbCB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBzZXJ2ZXIgcmV0dXJuaW5nIE5JTAorCSAgICAvLyBhbmQgc29tZSBvdGhlciBlcnJvciB0aGF0IGNhdXNlZCBudWxsIHRvIGJlIHJldHVybmVkIGFib3ZlLAorCSAgICAvLyBzbyB3ZSdsbCBqdXN0IGFzc3VtZSBpdCB3YXMgZW1wdHkgY29udGVudC4KKwkgICAgaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0obmV3IGJ5dGVbMF0pOworCX0KKwlyZXR1cm4gaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGUgb3V0IHRoZSBieXRlcyBpbnRvIHRoZSBnaXZlbiBPdXRwdXRTdHJlYW0uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGVUbyhPdXRwdXRTdHJlYW0gb3MpCisJCQkJdGhyb3dzIElPRXhjZXB0aW9uLCBNZXNzYWdpbmdFeGNlcHRpb24geworCWlmIChib2R5TG9hZGVkKSB7CisJICAgIHN1cGVyLndyaXRlVG8ob3MpOworCSAgICByZXR1cm47CisJfQorCUlucHV0U3RyZWFtIGlzID0gZ2V0TWltZVN0cmVhbSgpOworCXRyeSB7CisJICAgIC8vIHdyaXRlIG91dCB0aGUgYnl0ZXMKKwkgICAgYnl0ZVtdIGJ5dGVzID0gbmV3IGJ5dGVbMTYqMTAyNF07CisJICAgIGludCBjb3VudDsKKwkgICAgd2hpbGUgKChjb3VudCA9IGlzLnJlYWQoYnl0ZXMpKSAhPSAtMSkKKwkJb3Mud3JpdGUoYnl0ZXMsIDAsIGNvdW50KTsKKwl9IGZpbmFsbHkgeworCSAgICBpcy5jbG9zZSgpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIG5hbWVkIGhlYWRlci4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nW10gZ2V0SGVhZGVyKFN0cmluZyBuYW1lKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwljaGVja0V4cHVuZ2VkKCk7CisKKwlpZiAoaXNIZWFkZXJMb2FkZWQobmFtZSkpIC8vIGFscmVhZHkgbG9hZGVkID8KKwkgICAgcmV0dXJuIGhlYWRlcnMuZ2V0SGVhZGVyKG5hbWUpOworCisJLy8gTG9hZCB0aGlzIHBhcnRpY3VsYXIgaGVhZGVyCisJSW5wdXRTdHJlYW0gaXMgPSBudWxsOworCisgICAgICAgIC8vIEFjcXVpcmUgTWVzc2FnZUNhY2hlTG9jaywgdG8gZnJlZXplIHNlcW51bS4KKyAgICAgICAgc3luY2hyb25pemVkKGdldE1lc3NhZ2VDYWNoZUxvY2soKSkgeworCSAgICB0cnkgeworCQlJTUFQUHJvdG9jb2wgcCA9IGdldFByb3RvY29sKCk7CisKKwkJLy8gVGhpcyBtZXNzYWdlIGNvdWxkIGJlIGV4cHVuZ2VkIHdoZW4gd2Ugd2VyZSB3YWl0aW5nCisJCS8vIHRvIGFjcXVpcmUgdGhlIGxvY2sgLi4uCisJCWNoZWNrRXhwdW5nZWQoKTsKKworCQlpZiAocC5pc1JFVjEoKSkgeworCQkgICAgQk9EWSBiID0gcC5wZWVrQm9keShnZXRTZXF1ZW5jZU51bWJlcigpLCAKKwkJCQl0b1NlY3Rpb24oIkhFQURFUi5GSUVMRFMgKCIgKyBuYW1lICsgIikiKQorCQkJICAgICApOworCQkgICAgaWYgKGIgIT0gbnVsbCkKKwkJCWlzID0gYi5nZXRCeXRlQXJyYXlJbnB1dFN0cmVhbSgpOworCQl9IGVsc2UgeworCQkgICAgUkZDODIyREFUQSByZCA9IHAuZmV0Y2hSRkM4MjIoZ2V0U2VxdWVuY2VOdW1iZXIoKSwgCisJCQkJCSJIRUFERVIuTElORVMgKCIgKyBuYW1lICsgIikiKTsKKwkJICAgIGlmIChyZCAhPSBudWxsKQorCQkJaXMgPSByZC5nZXRCeXRlQXJyYXlJbnB1dFN0cmVhbSgpOworCQl9CisJICAgIH0gY2F0Y2ggKENvbm5lY3Rpb25FeGNlcHRpb24gY2V4KSB7CisJCXRocm93IG5ldyBGb2xkZXJDbG9zZWRFeGNlcHRpb24oZm9sZGVyLCBjZXguZ2V0TWVzc2FnZSgpKTsKKwkgICAgfSBjYXRjaCAoUHJvdG9jb2xFeGNlcHRpb24gcGV4KSB7CisJCWZvcmNlQ2hlY2tFeHB1bmdlZCgpOworCQl0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKHBleC5nZXRNZXNzYWdlKCksIHBleCk7CisJICAgIH0KKwl9CisKKwkvLyBpZiB3ZSBnZXQgdGhpcyBmYXIgd2l0aG91dCAiaXMiIGJlaW5nIHNldCwgc29tZXRoaW5nIGhhcyBnb25lCisJLy8gd3Jvbmc7IHByZXZlbnQgYSBsYXRlciBOdWxsUG9pbnRlckV4Y2VwdGlvbiBhbmQgcmV0dXJuIG51bGwgaGVyZQorCWlmIChpcyA9PSBudWxsKQorCSAgICByZXR1cm4gbnVsbDsKKworCWlmIChoZWFkZXJzID09IG51bGwpCisJICAgIGhlYWRlcnMgPSBuZXcgSW50ZXJuZXRIZWFkZXJzKCk7CisJaGVhZGVycy5sb2FkKGlzKTsgLy8gbG9hZCB0aGlzIGhlYWRlciBpbnRvIHRoZSBIZWFkZXJzIG9iamVjdC4KKwlzZXRIZWFkZXJMb2FkZWQobmFtZSk7IC8vIE1hcmsgdGhpcyBoZWFkZXIgYXMgbG9hZGVkCisKKwlyZXR1cm4gaGVhZGVycy5nZXRIZWFkZXIobmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBuYW1lZCBoZWFkZXIuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXRIZWFkZXIoU3RyaW5nIG5hbWUsIFN0cmluZyBkZWxpbWl0ZXIpCisJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwljaGVja0V4cHVuZ2VkKCk7CisKKwkvLyBmb3JjZSB0aGUgaGVhZGVyIHRvIGJlIGxvYWRlZCBieSBpbnZva2luZyBnZXRIZWFkZXIobmFtZSkKKwlpZiAoZ2V0SGVhZGVyKG5hbWUpID09IG51bGwpCisJICAgIHJldHVybiBudWxsOworCXJldHVybiBoZWFkZXJzLmdldEhlYWRlcihuYW1lLCBkZWxpbWl0ZXIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldEhlYWRlcihTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKQorCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJdGhyb3cgbmV3IElsbGVnYWxXcml0ZUV4Y2VwdGlvbigiSU1BUE1lc3NhZ2UgaXMgcmVhZC1vbmx5Iik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgYWRkSGVhZGVyKFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsdWUpCisJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwl0aHJvdyBuZXcgSWxsZWdhbFdyaXRlRXhjZXB0aW9uKCJJTUFQTWVzc2FnZSBpcyByZWFkLW9ubHkiKTsKKyAgICB9CisJICAgIAorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHJlbW92ZUhlYWRlcihTdHJpbmcgbmFtZSkKKwkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXRocm93IG5ldyBJbGxlZ2FsV3JpdGVFeGNlcHRpb24oIklNQVBNZXNzYWdlIGlzIHJlYWQtb25seSIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCBhbGwgaGVhZGVycy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRW51bWVyYXRpb248SGVhZGVyPiBnZXRBbGxIZWFkZXJzKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJY2hlY2tFeHB1bmdlZCgpOworCWxvYWRIZWFkZXJzKCk7CisJcmV0dXJuIHN1cGVyLmdldEFsbEhlYWRlcnMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgbWF0Y2hpbmcgaGVhZGVycy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRW51bWVyYXRpb248SGVhZGVyPiBnZXRNYXRjaGluZ0hlYWRlcnMoU3RyaW5nW10gbmFtZXMpCisJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwljaGVja0V4cHVuZ2VkKCk7CisJbG9hZEhlYWRlcnMoKTsKKwlyZXR1cm4gc3VwZXIuZ2V0TWF0Y2hpbmdIZWFkZXJzKG5hbWVzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgbm9uLW1hdGNoaW5nIGhlYWRlcnMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEVudW1lcmF0aW9uPEhlYWRlcj4gZ2V0Tm9uTWF0Y2hpbmdIZWFkZXJzKFN0cmluZ1tdIG5hbWVzKQorCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJY2hlY2tFeHB1bmdlZCgpOworCWxvYWRIZWFkZXJzKCk7CisJcmV0dXJuIHN1cGVyLmdldE5vbk1hdGNoaW5nSGVhZGVycyhuYW1lcyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgYWRkSGVhZGVyTGluZShTdHJpbmcgbGluZSkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJdGhyb3cgbmV3IElsbGVnYWxXcml0ZUV4Y2VwdGlvbigiSU1BUE1lc3NhZ2UgaXMgcmVhZC1vbmx5Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IGFsbCBoZWFkZXItbGluZXMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEVudW1lcmF0aW9uPFN0cmluZz4gZ2V0QWxsSGVhZGVyTGluZXMoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwljaGVja0V4cHVuZ2VkKCk7CisJbG9hZEhlYWRlcnMoKTsKKwlyZXR1cm4gc3VwZXIuZ2V0QWxsSGVhZGVyTGluZXMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgYWxsIG1hdGNoaW5nIGhlYWRlci1saW5lcy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRW51bWVyYXRpb248U3RyaW5nPiBnZXRNYXRjaGluZ0hlYWRlckxpbmVzKFN0cmluZ1tdIG5hbWVzKQorCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJY2hlY2tFeHB1bmdlZCgpOworCWxvYWRIZWFkZXJzKCk7CisJcmV0dXJuIHN1cGVyLmdldE1hdGNoaW5nSGVhZGVyTGluZXMobmFtZXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCBhbGwgbm9uLW1hdGNoaW5nIGhlYWRlcmxpbmVzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBFbnVtZXJhdGlvbjxTdHJpbmc+IGdldE5vbk1hdGNoaW5nSGVhZGVyTGluZXMoU3RyaW5nW10gbmFtZXMpCisJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwljaGVja0V4cHVuZ2VkKCk7CisJbG9hZEhlYWRlcnMoKTsKKwlyZXR1cm4gc3VwZXIuZ2V0Tm9uTWF0Y2hpbmdIZWFkZXJMaW5lcyhuYW1lcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBGbGFncyBmb3IgdGhpcyBtZXNzYWdlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgRmxhZ3MgZ2V0RmxhZ3MoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwljaGVja0V4cHVuZ2VkKCk7CisJbG9hZEZsYWdzKCk7CisJcmV0dXJuIHN1cGVyLmdldEZsYWdzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBpZiB0aGUgZ2l2ZW4gRmxhZ3MgYXJlIHNldCBpbiB0aGlzIG1lc3NhZ2UuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIGlzU2V0KEZsYWdzLkZsYWcgZmxhZykKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwljaGVja0V4cHVuZ2VkKCk7CisJbG9hZEZsYWdzKCk7CisJcmV0dXJuIHN1cGVyLmlzU2V0KGZsYWcpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldC9VbnNldCB0aGUgZ2l2ZW4gZmxhZ3MgaW4gdGhpcyBtZXNzYWdlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXRGbGFncyhGbGFncyBmbGFnLCBib29sZWFuIHNldCkKKwkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworICAgICAgICAvLyBBY3F1aXJlIE1lc3NhZ2VDYWNoZUxvY2ssIHRvIGZyZWV6ZSBzZXFudW0uCisgICAgICAgIHN5bmNocm9uaXplZChnZXRNZXNzYWdlQ2FjaGVMb2NrKCkpIHsKKwkgICAgdHJ5IHsKKwkJSU1BUFByb3RvY29sIHAgPSBnZXRQcm90b2NvbCgpOworCQljaGVja0V4cHVuZ2VkKCk7IC8vIEluc3VyZSB0aGF0IHRoaXMgbWVzc2FnZSBpcyBub3QgZXhwdW5nZWQKKwkJcC5zdG9yZUZsYWdzKGdldFNlcXVlbmNlTnVtYmVyKCksIGZsYWcsIHNldCk7CisJICAgIH0gY2F0Y2ggKENvbm5lY3Rpb25FeGNlcHRpb24gY2V4KSB7CisJCXRocm93IG5ldyBGb2xkZXJDbG9zZWRFeGNlcHRpb24oZm9sZGVyLCBjZXguZ2V0TWVzc2FnZSgpKTsKKwkgICAgfSBjYXRjaCAoUHJvdG9jb2xFeGNlcHRpb24gcGV4KSB7CisJCXRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24ocGV4LmdldE1lc3NhZ2UoKSwgcGV4KTsKKwkgICAgfQorCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgd2hldGhlciBvciBub3QgdG8gdXNlIHRoZSBQRUVLIHZhcmlhbnQgb2YgRkVUQ0ggd2hlbgorICAgICAqIGZldGNoaW5nIG1lc3NhZ2UgY29udGVudC4gIFRoaXMgb3ZlcnJpZGVzIHRoZSBkZWZhdWx0CisgICAgICogdmFsdWUgZnJvbSB0aGUgIm1haWwuaW1hcC5wZWVrIiBwcm9wZXJ0eS4KKyAgICAgKgorICAgICAqIEBwYXJhbQlwZWVrCXRoZSBwZWVrIGZsYWcKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS4zLjMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgc2V0UGVlayhib29sZWFuIHBlZWspIHsKKwl0aGlzLnBlZWsgPSBCb29sZWFuLnZhbHVlT2YocGVlayk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHdoZXRoZXIgb3Igbm90IHRvIHVzZSB0aGUgUEVFSyB2YXJpYW50IG9mIEZFVENIIHdoZW4KKyAgICAgKiBmZXRjaGluZyBtZXNzYWdlIGNvbnRlbnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBwZWVrIGZsYWcKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS4zLjMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGJvb2xlYW4gZ2V0UGVlaygpIHsKKwlpZiAocGVlayA9PSBudWxsKQorCSAgICByZXR1cm4gKChJTUFQU3RvcmUpZm9sZGVyLmdldFN0b3JlKCkpLmdldFBlZWsoKTsKKwllbHNlCisJICAgIHJldHVybiBwZWVrLmJvb2xlYW5WYWx1ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEludmFsaWRhdGUgY2FjaGVkIGhlYWRlciBhbmQgZW52ZWxvcGUgaW5mb3JtYXRpb24gZm9yIHRoaXMKKyAgICAgKiBtZXNzYWdlLiAgU3Vic2VxdWVudCBhY2Nlc3NlcyBvZiB0aGlzIGluZm9ybWF0aW9uIHdpbGwKKyAgICAgKiBjYXVzZSBpdCB0byBiZSBmZXRjaGVkIGZyb20gdGhlIHNlcnZlci4KKyAgICAgKgorICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjMuMworICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBpbnZhbGlkYXRlSGVhZGVycygpIHsKKwloZWFkZXJzTG9hZGVkID0gZmFsc2U7CisJbG9hZGVkSGVhZGVycy5jbGVhcigpOworCWhlYWRlcnMgPSBudWxsOworCWVudmVsb3BlID0gbnVsbDsKKwlicyA9IG51bGw7CisJcmVjZWl2ZWREYXRlID0gbnVsbDsKKwlzaXplID0gLTE7CisJdHlwZSA9IG51bGw7CisJc3ViamVjdCA9IG51bGw7CisJZGVzY3JpcHRpb24gPSBudWxsOworCWZsYWdzID0gbnVsbDsKKwljb250ZW50ID0gbnVsbDsKKwljb250ZW50U3RyZWFtID0gbnVsbDsKKwlib2R5TG9hZGVkID0gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIHRoZSB0ZXN0IHRvIGJlIGRvbmUgb24gZWFjaAorICAgICAqIG1lc3NhZ2UgaW4gdGhlIGZvbGRlci4gVGhlIHRlc3QgaXMgdG8gY2hlY2sgd2hldGhlciB0aGUKKyAgICAgKiBtZXNzYWdlIGhhcyBhbHJlYWR5IGNhY2hlZCBhbGwgdGhlIGl0ZW1zIHJlcXVlc3RlZCBpbiB0aGUKKyAgICAgKiBGZXRjaFByb2ZpbGUuIElmIGFueSBpdGVtIGlzIG1pc3NpbmcsIHRoZSB0ZXN0IHN1Y2NlZWRzIGFuZAorICAgICAqIGJyZWFrcyBvdXQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBGZXRjaFByb2ZpbGVDb25kaXRpb24gaW1wbGVtZW50cyBVdGlsaXR5LkNvbmRpdGlvbiB7CisJcHJpdmF0ZSBib29sZWFuIG5lZWRFbnZlbG9wZSA9IGZhbHNlOworCXByaXZhdGUgYm9vbGVhbiBuZWVkRmxhZ3MgPSBmYWxzZTsKKwlwcml2YXRlIGJvb2xlYW4gbmVlZEJvZHlTdHJ1Y3R1cmUgPSBmYWxzZTsKKwlwcml2YXRlIGJvb2xlYW4gbmVlZFVJRCA9IGZhbHNlOworCXByaXZhdGUgYm9vbGVhbiBuZWVkSGVhZGVycyA9IGZhbHNlOworCXByaXZhdGUgYm9vbGVhbiBuZWVkU2l6ZSA9IGZhbHNlOworCXByaXZhdGUgYm9vbGVhbiBuZWVkTWVzc2FnZSA9IGZhbHNlOworCXByaXZhdGUgYm9vbGVhbiBuZWVkUkRhdGUgPSBmYWxzZTsKKwlwcml2YXRlIFN0cmluZ1tdIGhkcnMgPSBudWxsOworCXByaXZhdGUgU2V0PEZldGNoSXRlbT4gbmVlZCA9IG5ldyBIYXNoU2V0PD4oKTsKKworCS8qKgorCSAqIENyZWF0ZSBhIEZldGNoUHJvZmlsZUNvbmRpdGlvbiB0byBkZXRlcm1pbmUgaWYgd2UgbmVlZCB0byBmZXRjaAorCSAqIGFueSBvZiB0aGUgaW5mb3JtYXRpb24gc3BlY2lmaWVkIGluIHRoZSBGZXRjaFByb2ZpbGUuCisJICoKKwkgKiBAcGFyYW0JZnAJdGhlIEZldGNoUHJvZmlsZQorCSAqIEBwYXJhbQlmaXRlbXMJdGhlIEZFVENIIGl0ZW1zCisJICovCisJQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikJLy8gZm9yIEZldGNoUHJvZmlsZS5JdGVtLlNJWkUKKwlwdWJsaWMgRmV0Y2hQcm9maWxlQ29uZGl0aW9uKEZldGNoUHJvZmlsZSBmcCwgRmV0Y2hJdGVtW10gZml0ZW1zKSB7CisJICAgIGlmIChmcC5jb250YWlucyhGZXRjaFByb2ZpbGUuSXRlbS5FTlZFTE9QRSkpCisJCW5lZWRFbnZlbG9wZSA9IHRydWU7CisJICAgIGlmIChmcC5jb250YWlucyhGZXRjaFByb2ZpbGUuSXRlbS5GTEFHUykpCisJCW5lZWRGbGFncyA9IHRydWU7CisJICAgIGlmIChmcC5jb250YWlucyhGZXRjaFByb2ZpbGUuSXRlbS5DT05URU5UX0lORk8pKQorCQluZWVkQm9keVN0cnVjdHVyZSA9IHRydWU7CisJICAgIGlmIChmcC5jb250YWlucyhGZXRjaFByb2ZpbGUuSXRlbS5TSVpFKSkKKwkJbmVlZFNpemUgPSB0cnVlOworCSAgICBpZiAoZnAuY29udGFpbnMoVUlERm9sZGVyLkZldGNoUHJvZmlsZUl0ZW0uVUlEKSkKKwkJbmVlZFVJRCA9IHRydWU7CisJICAgIGlmIChmcC5jb250YWlucyhJTUFQRm9sZGVyLkZldGNoUHJvZmlsZUl0ZW0uSEVBREVSUykpCisJCW5lZWRIZWFkZXJzID0gdHJ1ZTsKKwkgICAgaWYgKGZwLmNvbnRhaW5zKElNQVBGb2xkZXIuRmV0Y2hQcm9maWxlSXRlbS5TSVpFKSkKKwkJbmVlZFNpemUgPSB0cnVlOworCSAgICBpZiAoZnAuY29udGFpbnMoSU1BUEZvbGRlci5GZXRjaFByb2ZpbGVJdGVtLk1FU1NBR0UpKQorCQluZWVkTWVzc2FnZSA9IHRydWU7CisJICAgIGlmIChmcC5jb250YWlucyhJTUFQRm9sZGVyLkZldGNoUHJvZmlsZUl0ZW0uSU5URVJOQUxEQVRFKSkKKwkJbmVlZFJEYXRlID0gdHJ1ZTsKKwkgICAgaGRycyA9IGZwLmdldEhlYWRlck5hbWVzKCk7CisJICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZml0ZW1zLmxlbmd0aDsgaSsrKSB7CisJCWlmIChmcC5jb250YWlucyhmaXRlbXNbaV0uZ2V0RmV0Y2hQcm9maWxlSXRlbSgpKSkKKwkJICAgIG5lZWQuYWRkKGZpdGVtc1tpXSk7CisJICAgIH0KKwl9CisKKwkvKioKKwkgKiBSZXR1cm4gdHJ1ZSBpZiB3ZSBORUVEIHRvIGZldGNoIHRoZSByZXF1ZXN0ZWQgaW5mb3JtYXRpb24KKwkgKiBmb3IgdGhlIHNwZWNpZmllZCBtZXNzYWdlLgorCSAqLworCUBPdmVycmlkZQorCXB1YmxpYyBib29sZWFuIHRlc3QoSU1BUE1lc3NhZ2UgbSkgeworCSAgICBpZiAobmVlZEVudmVsb3BlICYmIG0uX2dldEVudmVsb3BlKCkgPT0gbnVsbCAmJiAhbS5ib2R5TG9hZGVkKQorCQlyZXR1cm4gdHJ1ZTsgLy8gbm8gZW52ZWxvcGUKKwkgICAgaWYgKG5lZWRGbGFncyAmJiBtLl9nZXRGbGFncygpID09IG51bGwpCisJCXJldHVybiB0cnVlOyAvLyBubyBmbGFncworCSAgICBpZiAobmVlZEJvZHlTdHJ1Y3R1cmUgJiYgbS5fZ2V0Qm9keVN0cnVjdHVyZSgpID09IG51bGwgJiYKKwkJCQkJCQkJIW0uYm9keUxvYWRlZCkKKwkJcmV0dXJuIHRydWU7IC8vIG5vIEJPRFlTVFJVQ1RVUkUKKwkgICAgaWYgKG5lZWRVSUQgJiYgbS5nZXRVSUQoKSA9PSAtMSkJLy8gbm8gVUlECisJCXJldHVybiB0cnVlOworCSAgICBpZiAobmVlZEhlYWRlcnMgJiYgIW0uYXJlSGVhZGVyc0xvYWRlZCgpKSAvLyBubyBoZWFkZXJzCisJCXJldHVybiB0cnVlOworCSAgICBpZiAobmVlZFNpemUgJiYgbS5zaXplID09IC0xICYmICFtLmJvZHlMb2FkZWQpIC8vIG5vIHNpemUKKwkJcmV0dXJuIHRydWU7CisJICAgIGlmIChuZWVkTWVzc2FnZSAmJiAhbS5ib2R5TG9hZGVkKQkJLy8gbm8gbWVzc2FnZSBib2R5CisJCXJldHVybiB0cnVlOworCSAgICBpZiAobmVlZFJEYXRlICYmIG0ucmVjZWl2ZWREYXRlID09IG51bGwpCS8vIG5vIHJlY2VpdmVkIGRhdGUKKwkJcmV0dXJuIHRydWU7CisKKwkgICAgLy8gSXMgdGhlIGRlc2lyZWQgaGVhZGVyIHByZXNlbnQgPworCSAgICBmb3IgKGludCBpID0gMDsgaSA8IGhkcnMubGVuZ3RoOyBpKyspIHsKKwkJaWYgKCFtLmlzSGVhZGVyTG9hZGVkKGhkcnNbaV0pKQorCQkgICAgcmV0dXJuIHRydWU7IC8vIE5vcGUsIHJldHVybgorCSAgICB9CisJICAgIEl0ZXJhdG9yPEZldGNoSXRlbT4gaXQgPSBuZWVkLml0ZXJhdG9yKCk7CisJICAgIHdoaWxlIChpdC5oYXNOZXh0KCkpIHsKKwkJRmV0Y2hJdGVtIGZpdGVtID0gaXQubmV4dCgpOworCQlpZiAobS5pdGVtcyA9PSBudWxsIHx8IG0uaXRlbXMuZ2V0KGZpdGVtLmdldE5hbWUoKSkgPT0gbnVsbCkKKwkJICAgIHJldHVybiB0cnVlOworCSAgICB9CisKKwkgICAgcmV0dXJuIGZhbHNlOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBcHBseSB0aGUgZGF0YSBpbiB0aGUgRkVUQ0ggaXRlbSB0byB0aGlzIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBBU1NFUlQ6IE11c3QgaG9sZCB0aGUgbWVzc2FnZUNhY2hlTG9jay4KKyAgICAgKgorICAgICAqIEBwYXJhbQlpdGVtCXRoZSBmZXRjaCBpdGVtCisgICAgICogQHBhcmFtCWhkcnMJdGhlIGhlYWRlcnMgd2UncmUgYXNraW5nIGZvcgorICAgICAqIEBwYXJhbQlhbGxIZWFkZXJzIGxvYWQgYWxsIGhlYWRlcnM/CisgICAgICogQHJldHVybgkJZGlkIHdlIGhhbmRsZSB0aGlzIGZldGNoIGl0ZW0/CisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNC42CisgICAgICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gaGFuZGxlRmV0Y2hJdGVtKEl0ZW0gaXRlbSwKKwkJCQlTdHJpbmdbXSBoZHJzLCBib29sZWFuIGFsbEhlYWRlcnMpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJLy8gQ2hlY2sgZm9yIHRoZSBGTEFHUyBpdGVtCisJaWYgKGl0ZW0gaW5zdGFuY2VvZiBGbGFncykKKwkgICAgZmxhZ3MgPSAoRmxhZ3MpaXRlbTsKKwkvLyBDaGVjayBmb3IgRU5WRUxPUEUgaXRlbXMKKwllbHNlIGlmIChpdGVtIGluc3RhbmNlb2YgRU5WRUxPUEUpCisJICAgIGVudmVsb3BlID0gKEVOVkVMT1BFKWl0ZW07CisJZWxzZSBpZiAoaXRlbSBpbnN0YW5jZW9mIElOVEVSTkFMREFURSkKKwkgICAgcmVjZWl2ZWREYXRlID0gKChJTlRFUk5BTERBVEUpaXRlbSkuZ2V0RGF0ZSgpOworCWVsc2UgaWYgKGl0ZW0gaW5zdGFuY2VvZiBSRkM4MjJTSVpFKQorCSAgICBzaXplID0gKChSRkM4MjJTSVpFKWl0ZW0pLnNpemU7CisJZWxzZSBpZiAoaXRlbSBpbnN0YW5jZW9mIE1PRFNFUSkKKwkgICAgbW9kc2VxID0gKChNT0RTRVEpaXRlbSkubW9kc2VxOworCisJLy8gQ2hlY2sgZm9yIHRoZSBCT0RZU1RSVUNUVVJFIGl0ZW0KKwllbHNlIGlmIChpdGVtIGluc3RhbmNlb2YgQk9EWVNUUlVDVFVSRSkKKwkgICAgYnMgPSAoQk9EWVNUUlVDVFVSRSlpdGVtOworCS8vIENoZWNrIGZvciB0aGUgVUlEIGl0ZW0KKwllbHNlIGlmIChpdGVtIGluc3RhbmNlb2YgVUlEKSB7CisJICAgIFVJRCB1ID0gKFVJRClpdGVtOworCSAgICB1aWQgPSB1LnVpZDsgLy8gc2V0IHVpZAorCSAgICAvLyBhZGQgZW50cnkgaW50byB1aWQgdGFibGUKKwkgICAgaWYgKCgoSU1BUEZvbGRlcilmb2xkZXIpLnVpZFRhYmxlID09IG51bGwpCisJCSgoSU1BUEZvbGRlcikgZm9sZGVyKS51aWRUYWJsZQorCQkJPSBuZXcgSGFzaHRhYmxlPD4oKTsKKwkgICAgKChJTUFQRm9sZGVyKWZvbGRlcikudWlkVGFibGUucHV0KExvbmcudmFsdWVPZih1LnVpZCksIHRoaXMpOworCX0KKworCS8vIENoZWNrIGZvciBoZWFkZXIgaXRlbXMKKwllbHNlIGlmIChpdGVtIGluc3RhbmNlb2YgUkZDODIyREFUQSB8fAorCQkgaXRlbSBpbnN0YW5jZW9mIEJPRFkpIHsKKwkgICAgSW5wdXRTdHJlYW0gaGVhZGVyU3RyZWFtOworCSAgICBib29sZWFuIGlzSGVhZGVyOworCSAgICBpZiAoaXRlbSBpbnN0YW5jZW9mIFJGQzgyMkRBVEEpIHsgLy8gSU1BUDQKKwkJaGVhZGVyU3RyZWFtID0gCisJCSAgICAoKFJGQzgyMkRBVEEpaXRlbSkuZ2V0Qnl0ZUFycmF5SW5wdXRTdHJlYW0oKTsKKwkJaXNIZWFkZXIgPSAoKFJGQzgyMkRBVEEpaXRlbSkuaXNIZWFkZXIoKTsKKwkgICAgfSBlbHNlIHsJLy8gSU1BUDRyZXYxCisJCWhlYWRlclN0cmVhbSA9IAorCQkgICAgKChCT0RZKWl0ZW0pLmdldEJ5dGVBcnJheUlucHV0U3RyZWFtKCk7CisJCWlzSGVhZGVyID0gKChCT0RZKWl0ZW0pLmlzSGVhZGVyKCk7CisJICAgIH0KKworCSAgICBpZiAoIWlzSGVhZGVyKSB7CisJCS8vIGxvYWQgdGhlIGVudGlyZSBtZXNzYWdlIGJ5IHVzaW5nIHRoZSBzdXBlcmNsYXNzCisJCS8vIE1pbWVNZXNzYWdlLnBhcnNlIG1ldGhvZAorCQkvLyBmaXJzdCwgc2F2ZSB0aGUgc2l6ZSBvZiB0aGUgbWVzc2FnZQorCQl0cnkgeworCQkgICAgc2l6ZSA9IGhlYWRlclN0cmVhbS5hdmFpbGFibGUoKTsKKwkJfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKwkJICAgIC8vIHNob3VsZCBuZXZlciBvY2N1cgorCQl9CisJCXBhcnNlKGhlYWRlclN0cmVhbSk7CisJCWJvZHlMb2FkZWQgPSB0cnVlOworCQlzZXRIZWFkZXJzTG9hZGVkKHRydWUpOworCSAgICB9IGVsc2UgeworCQkvLyBMb2FkIHRoZSBvYnRhaW5lZCBoZWFkZXJzLgorCQlJbnRlcm5ldEhlYWRlcnMgaCA9IG5ldyBJbnRlcm5ldEhlYWRlcnMoKTsKKwkJLy8gU29tZSBJTUFQIHNlcnZlcnMgKGUuZy4sIGdteC5uZXQpIHJldHVybiBOSUwgCisJCS8vIGluc3RlYWQgb2YgYSBzdHJpbmcganVzdCBjb250YWluaW5nIGEgQ1IvTEYKKwkJLy8gd2hlbiB0aGUgaGVhZGVyIGxpc3QgaXMgZW1wdHkuCisJCWlmIChoZWFkZXJTdHJlYW0gIT0gbnVsbCkKKwkJICAgIGgubG9hZChoZWFkZXJTdHJlYW0pOworCQlpZiAoaGVhZGVycyA9PSBudWxsIHx8IGFsbEhlYWRlcnMpCisJCSAgICBoZWFkZXJzID0gaDsKKwkJZWxzZSB7CisJCSAgICAvKgorCQkgICAgICogVGhpcyBpcyByZWFsbHkgcGFpbmZ1bC4gIEEgc2Vjb25kIGZldGNoCisJCSAgICAgKiBvZiB0aGUgc2FtZSBoZWFkZXJzICh3aGljaCBtaWdodCBvY2N1ciBiZWNhdXNlCisJCSAgICAgKiBhIG5ldyBoZWFkZXIgd2FzIGFkZGVkIHRvIHRoZSBzZXQgcmVxdWVzdGVkKQorCQkgICAgICogd2lsbCByZXR1cm4gaGVhZGVycyB3ZSBhbHJlYWR5IGtub3cgYWJvdXQuCisJCSAgICAgKiBJbiB0aGlzIGNhc2UsIG9ubHkgbG9hZCB0aGUgaGVhZGVycyB3ZSBoYXZlbid0CisJCSAgICAgKiBzZWVuIGJlZm9yZSB0byBhdm9pZCBhZGRpbmcgZHVwbGljYXRlcyBvZgorCQkgICAgICogaGVhZGVycyB3ZSBhbHJlYWR5IGhhdmUuCisJCSAgICAgKgorCQkgICAgICogWFhYIC0gVGhlcmUncyBhIHJhY2UgY29uZGl0aW9uIGhlcmUgaWYgYW5vdGhlcgorCQkgICAgICogdGhyZWFkIGlzIHJlYWRpbmcgaGVhZGVycyBpbiB0aGUgc2FtZSBtZXNzYWdlCisJCSAgICAgKiBvYmplY3QsIGJlY2F1c2UgSW50ZXJuZXRIZWFkZXJzIGlzIG5vdCB0aHJlYWQKKwkJICAgICAqIHNhZmUuCisJCSAgICAgKi8KKwkJICAgIEVudW1lcmF0aW9uPEhlYWRlcj4gZSA9IGguZ2V0QWxsSGVhZGVycygpOworCQkgICAgd2hpbGUgKGUuaGFzTW9yZUVsZW1lbnRzKCkpIHsKKwkJCUhlYWRlciBoZSA9IGUubmV4dEVsZW1lbnQoKTsKKwkJCWlmICghaXNIZWFkZXJMb2FkZWQoaGUuZ2V0TmFtZSgpKSkKKwkJCSAgICBoZWFkZXJzLmFkZEhlYWRlcigKKwkJCQkJaGUuZ2V0TmFtZSgpLCBoZS5nZXRWYWx1ZSgpKTsKKwkJICAgIH0KKwkJfQorCisJCS8vIGlmIHdlIGFza2VkIGZvciBhbGwgaGVhZGVycywgYXNzdW1lIHdlIGdvdCB0aGVtCisJCWlmIChhbGxIZWFkZXJzKQorCQkgICAgc2V0SGVhZGVyc0xvYWRlZCh0cnVlKTsKKwkJZWxzZSB7CisJCSAgICAvLyBNYXJrIGFsbCBoZWFkZXJzIHdlIGFza2VkIGZvciBhcyAnbG9hZGVkJworCQkgICAgZm9yIChpbnQgayA9IDA7IGsgPCBoZHJzLmxlbmd0aDsgaysrKQorCQkJc2V0SGVhZGVyTG9hZGVkKGhkcnNba10pOworCQl9CisJICAgIH0KKwl9IGVsc2UKKwkgICAgcmV0dXJuIGZhbHNlOwkvLyBub3QgaGFuZGxlZAorCXJldHVybiB0cnVlOwkJLy8gc29tZXRoaW5nIGFib3ZlIGhhbmRsZWQgaXQKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBcHBseSB0aGUgZGF0YSBpbiB0aGUgZXh0ZW5zaW9uIEZFVENIIGl0ZW1zIHRvIHRoaXMgbWVzc2FnZS4KKyAgICAgKiBUaGlzIG1ldGhvZCBhZGRzIGFsbCB0aGUgaXRlbXMgdG8gdGhlIGl0ZW1zIG1hcC4KKyAgICAgKiBTdWJjbGFzc2VzIG1heSBvdmVycmlkZSB0aGlzIG1ldGhvZCB0byBjYWxsIHN1cGVyIGFuZCB0aGVuCisgICAgICogYWxzbyBjb3B5IHRoZSBkYXRhIHRvIGEgbW9yZSBjb252ZW5pZW50IGZvcm0uCisgICAgICoKKyAgICAgKiBBU1NFUlQ6IE11c3QgaG9sZCB0aGUgbWVzc2FnZUNhY2hlTG9jay4KKyAgICAgKgorICAgICAqIEBwYXJhbQlleHRlbnNpb25JdGVtcwl0aGUgTWFwIHRvIGFkZCBmZXRjaCBpdGVtcyB0bworICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjQuNgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGhhbmRsZUV4dGVuc2lvbkZldGNoSXRlbXMoCisJICAgIE1hcDxTdHJpbmcsIE9iamVjdD4gZXh0ZW5zaW9uSXRlbXMpIHsKKwlpZiAoZXh0ZW5zaW9uSXRlbXMgPT0gbnVsbCB8fCBleHRlbnNpb25JdGVtcy5pc0VtcHR5KCkpCisJICAgIHJldHVybjsKKwlpZiAoaXRlbXMgPT0gbnVsbCkKKwkgICAgaXRlbXMgPSBuZXcgSGFzaE1hcDw+KCk7CisJaXRlbXMucHV0QWxsKGV4dGVuc2lvbkl0ZW1zKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGZXRjaCBhbiBpbmRpdmlkdWFsIGl0ZW0gZm9yIHRoZSBjdXJyZW50IG1lc3NhZ2UuCisgICAgICogTm90ZSB0aGF0IGhhbmRsZUV4dGVuc2lvbkZldGNoSXRlbXMgd2lsbCBoYXZlIGJlZW4gY2FsbGVkCisgICAgICogdG8gc3RvcmUgdGhpcyBpdGVtIGluIHRoZSBtZXNzYWdlIGJlZm9yZSB0aGlzIG1ldGhvZAorICAgICAqIHJldHVybnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0JZml0ZW0JdGhlIEZldGNoSXRlbQorICAgICAqIEByZXR1cm4JCXRoZSBkYXRhIGFzc29jaWF0ZWQgd2l0aCB0aGUgRmV0Y2hJdGVtCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNC42CisgICAgICovCisgICAgcHJvdGVjdGVkIE9iamVjdCBmZXRjaEl0ZW0oRmV0Y2hJdGVtIGZpdGVtKQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCisJLy8gQWNxdWlyZSBNZXNzYWdlQ2FjaGVMb2NrLCB0byBmcmVlemUgc2VxbnVtLgorCXN5bmNocm9uaXplZChnZXRNZXNzYWdlQ2FjaGVMb2NrKCkpIHsKKwkgICAgT2JqZWN0IHJvYmogPSBudWxsOworCisJICAgIHRyeSB7CisJCUlNQVBQcm90b2NvbCBwID0gZ2V0UHJvdG9jb2woKTsKKworCQljaGVja0V4cHVuZ2VkKCk7IC8vIEluc3VyZSB0aGF0IHRoaXMgbWVzc2FnZSBpcyBub3QgZXhwdW5nZWQKKworCQlpbnQgc2VxbnVtID0gZ2V0U2VxdWVuY2VOdW1iZXIoKTsKKwkJUmVzcG9uc2VbXSByID0gcC5mZXRjaChzZXFudW0sIGZpdGVtLmdldE5hbWUoKSk7CisKKwkJZm9yIChpbnQgaSA9IDA7IGkgPCByLmxlbmd0aDsgaSsrKSB7CisJCSAgICAvLyBJZiB0aGlzIHJlc3BvbnNlIGlzIE5PVCBhIEZldGNoUmVzcG9uc2Ugb3IgaWYgaXQgZG9lcworCQkgICAgLy8gbm90IG1hdGNoIG91ciBzZXFudW0sIHNraXAuCisJCSAgICBpZiAocltpXSA9PSBudWxsIHx8CisJCQkhKHJbaV0gaW5zdGFuY2VvZiBGZXRjaFJlc3BvbnNlKSB8fAorCQkJKChGZXRjaFJlc3BvbnNlKXJbaV0pLmdldE51bWJlcigpICE9IHNlcW51bSkKKwkJCWNvbnRpbnVlOworCisJCSAgICBGZXRjaFJlc3BvbnNlIGYgPSAoRmV0Y2hSZXNwb25zZSlyW2ldOworCQkgICAgaGFuZGxlRXh0ZW5zaW9uRmV0Y2hJdGVtcyhmLmdldEV4dGVuc2lvbkl0ZW1zKCkpOworCQkgICAgaWYgKGl0ZW1zICE9IG51bGwpIHsKKwkJCU9iamVjdCBvID0gaXRlbXMuZ2V0KGZpdGVtLmdldE5hbWUoKSk7CisJCQlpZiAobyAhPSBudWxsKQorCQkJICAgIHJvYmogPSBvOworCQkgICAgfQorCQl9CisKKwkJLy8gKChJTUFQRm9sZGVyKWZvbGRlcikuaGFuZGxlUmVzcG9uc2VzKHIpOworCQlwLm5vdGlmeVJlc3BvbnNlSGFuZGxlcnMocik7CisJCXAuaGFuZGxlUmVzdWx0KHJbci5sZW5ndGggLSAxXSk7CisJICAgIH0gY2F0Y2ggKENvbm5lY3Rpb25FeGNlcHRpb24gY2V4KSB7CisJCXRocm93IG5ldyBGb2xkZXJDbG9zZWRFeGNlcHRpb24oZm9sZGVyLCBjZXguZ2V0TWVzc2FnZSgpKTsKKwkgICAgfSBjYXRjaCAoUHJvdG9jb2xFeGNlcHRpb24gcGV4KSB7CisJCWZvcmNlQ2hlY2tFeHB1bmdlZCgpOworCQl0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKHBleC5nZXRNZXNzYWdlKCksIHBleCk7CisJICAgIH0KKwkgICAgcmV0dXJuIHJvYmo7CisKKwl9IC8vIFJlbGVhc2UgTWVzc2FnZUNhY2hlTG9jaworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgZGF0YSBhc3NvY2lhdGVkIHdpdGggdGhlIEZldGNoSXRlbS4KKyAgICAgKiBJZiB0aGUgZGF0YSBoYXNuJ3QgYmVlbiBmZXRjaGVkLCBjYWxsIHRoZSBmZXRjaEl0ZW0KKyAgICAgKiBtZXRob2QgdG8gZmV0Y2ggaXQuICBSZXR1cm5zIG51bGwgaWYgdGhlcmUgaXMgbm8KKyAgICAgKiBkYXRhIGZvciB0aGUgRmV0Y2hJdGVtLgorICAgICAqCisgICAgICogQHBhcmFtCWZpdGVtCXRoZSBGZXRjaEl0ZW0KKyAgICAgKiBAcmV0dXJuCQl0aGUgZGF0YSBhc3NvY2lhdGVkIHdpdGggdGhlIEZldGNoSXRlbQorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjQuNgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgT2JqZWN0IGdldEl0ZW0oRmV0Y2hJdGVtIGZpdGVtKQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCU9iamVjdCBpdGVtID0gaXRlbXMgPT0gbnVsbCA/IG51bGwgOiBpdGVtcy5nZXQoZml0ZW0uZ2V0TmFtZSgpKTsKKwlpZiAoaXRlbSA9PSBudWxsKQorCSAgICBpdGVtID0gZmV0Y2hJdGVtKGZpdGVtKTsKKwlyZXR1cm4gaXRlbTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIExvYWQgdGhlIEVudmVsb3BlIGZvciB0aGlzIG1lc3NhZ2UuCisgICAgICovCisgICAgcHJpdmF0ZSBzeW5jaHJvbml6ZWQgdm9pZCBsb2FkRW52ZWxvcGUoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpZiAoZW52ZWxvcGUgIT0gbnVsbCkgLy8gYWxyZWFkeSBsb2FkZWQKKwkgICAgcmV0dXJuOworCisJUmVzcG9uc2VbXSByID0gbnVsbDsKKworCS8vIEFjcXVpcmUgTWVzc2FnZUNhY2hlTG9jaywgdG8gZnJlZXplIHNlcW51bS4KKwlzeW5jaHJvbml6ZWQoZ2V0TWVzc2FnZUNhY2hlTG9jaygpKSB7CisJICAgIHRyeSB7CisJCUlNQVBQcm90b2NvbCBwID0gZ2V0UHJvdG9jb2woKTsKKworCQljaGVja0V4cHVuZ2VkKCk7IC8vIEluc3VyZSB0aGF0IHRoaXMgbWVzc2FnZSBpcyBub3QgZXhwdW5nZWQKKworCQlpbnQgc2VxbnVtID0gZ2V0U2VxdWVuY2VOdW1iZXIoKTsKKwkJciA9IHAuZmV0Y2goc2VxbnVtLCBFbnZlbG9wZUNtZCk7CisKKwkJZm9yIChpbnQgaSA9IDA7IGkgPCByLmxlbmd0aDsgaSsrKSB7CisJCSAgICAvLyBJZiB0aGlzIHJlc3BvbnNlIGlzIE5PVCBhIEZldGNoUmVzcG9uc2Ugb3IgaWYgaXQgZG9lcworCQkgICAgLy8gbm90IG1hdGNoIG91ciBzZXFudW0sIHNraXAuCisJCSAgICBpZiAocltpXSA9PSBudWxsIHx8CisJCQkhKHJbaV0gaW5zdGFuY2VvZiBGZXRjaFJlc3BvbnNlKSB8fAorCQkJKChGZXRjaFJlc3BvbnNlKXJbaV0pLmdldE51bWJlcigpICE9IHNlcW51bSkKKwkJCWNvbnRpbnVlOworCisJCSAgICBGZXRjaFJlc3BvbnNlIGYgPSAoRmV0Y2hSZXNwb25zZSlyW2ldOworCQkgICAgCisJCSAgICAvLyBMb29rIGZvciB0aGUgRW52ZWxvcGUgaXRlbXMuCisJCSAgICBpbnQgY291bnQgPSBmLmdldEl0ZW1Db3VudCgpOworCQkgICAgZm9yIChpbnQgaiA9IDA7IGogPCBjb3VudDsgaisrKSB7CisJCQlJdGVtIGl0ZW0gPSBmLmdldEl0ZW0oaik7CisJCQkKKwkJCWlmIChpdGVtIGluc3RhbmNlb2YgRU5WRUxPUEUpCisJCQkgICAgZW52ZWxvcGUgPSAoRU5WRUxPUEUpaXRlbTsKKwkJCWVsc2UgaWYgKGl0ZW0gaW5zdGFuY2VvZiBJTlRFUk5BTERBVEUpCisJCQkgICAgcmVjZWl2ZWREYXRlID0gKChJTlRFUk5BTERBVEUpaXRlbSkuZ2V0RGF0ZSgpOworCQkJZWxzZSBpZiAoaXRlbSBpbnN0YW5jZW9mIFJGQzgyMlNJWkUpCisJCQkgICAgc2l6ZSA9ICgoUkZDODIyU0laRSlpdGVtKS5zaXplOworCQkgICAgfQorCQl9CisKKwkJLy8gKChJTUFQRm9sZGVyKWZvbGRlcikuaGFuZGxlUmVzcG9uc2VzKHIpOworCQlwLm5vdGlmeVJlc3BvbnNlSGFuZGxlcnMocik7CisJCXAuaGFuZGxlUmVzdWx0KHJbci5sZW5ndGggLSAxXSk7CisJICAgIH0gY2F0Y2ggKENvbm5lY3Rpb25FeGNlcHRpb24gY2V4KSB7CisJCXRocm93IG5ldyBGb2xkZXJDbG9zZWRFeGNlcHRpb24oZm9sZGVyLCBjZXguZ2V0TWVzc2FnZSgpKTsKKwkgICAgfSBjYXRjaCAoUHJvdG9jb2xFeGNlcHRpb24gcGV4KSB7CisJCWZvcmNlQ2hlY2tFeHB1bmdlZCgpOworCQl0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKHBleC5nZXRNZXNzYWdlKCksIHBleCk7CisJICAgIH0KKworCX0gLy8gUmVsZWFzZSBNZXNzYWdlQ2FjaGVMb2NrCisKKwlpZiAoZW52ZWxvcGUgPT0gbnVsbCkKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiRmFpbGVkIHRvIGxvYWQgSU1BUCBlbnZlbG9wZSIpOworICAgIH0KKworICAgIC8qCisgICAgICogTG9hZCB0aGUgQk9EWVNUUlVDVFVSRQorICAgICAqLworICAgIHByaXZhdGUgc3luY2hyb25pemVkIHZvaWQgbG9hZEJPRFlTVFJVQ1RVUkUoKSAKKwkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKGJzICE9IG51bGwpIC8vIGFscmVhZHkgbG9hZGVkCisJICAgIHJldHVybjsKKworCS8vIEFjcXVpcmUgTWVzc2FnZUNhY2hlTG9jaywgdG8gZnJlZXplIHNlcW51bS4KKwlzeW5jaHJvbml6ZWQoZ2V0TWVzc2FnZUNhY2hlTG9jaygpKSB7CisJICAgIHRyeSB7CisJCUlNQVBQcm90b2NvbCBwID0gZ2V0UHJvdG9jb2woKTsKKworCQkvLyBUaGlzIG1lc3NhZ2UgY291bGQgYmUgZXhwdW5nZWQgd2hlbiB3ZSB3ZXJlIHdhaXRpbmcgCisJCS8vIHRvIGFjcXVpcmUgdGhlIGxvY2sgLi4uCisJCWNoZWNrRXhwdW5nZWQoKTsKKworCQlicyA9IHAuZmV0Y2hCb2R5U3RydWN0dXJlKGdldFNlcXVlbmNlTnVtYmVyKCkpOworCSAgICB9IGNhdGNoIChDb25uZWN0aW9uRXhjZXB0aW9uIGNleCkgeworCQl0aHJvdyBuZXcgRm9sZGVyQ2xvc2VkRXhjZXB0aW9uKGZvbGRlciwgY2V4LmdldE1lc3NhZ2UoKSk7CisJICAgIH0gY2F0Y2ggKFByb3RvY29sRXhjZXB0aW9uIHBleCkgeworCQlmb3JjZUNoZWNrRXhwdW5nZWQoKTsKKwkJdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbihwZXguZ2V0TWVzc2FnZSgpLCBwZXgpOworCSAgICB9CisJICAgIGlmIChicyA9PSBudWxsKSB7CisJCS8vIGlmIHRoZSBGRVRDSCBpcyBzdWNjZXNzZnVsLCB3ZSBzaG91bGQgYWx3YXlzIGdldCBhCisJCS8vIEJPRFlTVFJVQ1RVUkUsIGJ1dCBzb21lIHNlcnZlcnMgZmFpbCB0byByZXR1cm4gaXQKKwkJLy8gaWYgdGhlIG1lc3NhZ2UgaGFzIGJlZW4gZXhwdW5nZWQKKwkJZm9yY2VDaGVja0V4cHVuZ2VkKCk7CisJCXRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oIlVuYWJsZSB0byBsb2FkIEJPRFlTVFJVQ1RVUkUiKTsKKwkgICAgfQorCX0KKyAgICB9CisKKyAgICAvKgorICAgICAqIExvYWQgYWxsIGhlYWRlcnMuCisgICAgICovCisgICAgcHJpdmF0ZSBzeW5jaHJvbml6ZWQgdm9pZCBsb2FkSGVhZGVycygpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWlmIChoZWFkZXJzTG9hZGVkKQorCSAgICByZXR1cm47CisKKwlJbnB1dFN0cmVhbSBpcyA9IG51bGw7CisKKwkvLyBBY3F1aXJlIE1lc3NhZ2VDYWNoZUxvY2ssIHRvIGZyZWV6ZSBzZXFudW0uCisJc3luY2hyb25pemVkIChnZXRNZXNzYWdlQ2FjaGVMb2NrKCkpIHsKKwkgICAgdHJ5IHsKKwkJSU1BUFByb3RvY29sIHAgPSBnZXRQcm90b2NvbCgpOworCisJCS8vIFRoaXMgbWVzc2FnZSBjb3VsZCBiZSBleHB1bmdlZCB3aGVuIHdlIHdlcmUgd2FpdGluZyAKKwkJLy8gdG8gYWNxdWlyZSB0aGUgbG9jayAuLi4KKwkJY2hlY2tFeHB1bmdlZCgpOworCisJCWlmIChwLmlzUkVWMSgpKSB7CisJCSAgICBCT0RZIGIgPSBwLnBlZWtCb2R5KGdldFNlcXVlbmNlTnVtYmVyKCksIAorCQkJCQkgdG9TZWN0aW9uKCJIRUFERVIiKSk7CisJCSAgICBpZiAoYiAhPSBudWxsKQorCQkJaXMgPSBiLmdldEJ5dGVBcnJheUlucHV0U3RyZWFtKCk7CisJCX0gZWxzZSB7CisJCSAgICBSRkM4MjJEQVRBIHJkID0gcC5mZXRjaFJGQzgyMihnZXRTZXF1ZW5jZU51bWJlcigpLCAKKwkJCQkJCSAgIkhFQURFUiIpOworCQkgICAgaWYgKHJkICE9IG51bGwpCisJCQlpcyA9IHJkLmdldEJ5dGVBcnJheUlucHV0U3RyZWFtKCk7CisJCX0KKwkgICAgfSBjYXRjaCAoQ29ubmVjdGlvbkV4Y2VwdGlvbiBjZXgpIHsKKwkJdGhyb3cgbmV3IEZvbGRlckNsb3NlZEV4Y2VwdGlvbihmb2xkZXIsIGNleC5nZXRNZXNzYWdlKCkpOworCSAgICB9IGNhdGNoIChQcm90b2NvbEV4Y2VwdGlvbiBwZXgpIHsKKwkJZm9yY2VDaGVja0V4cHVuZ2VkKCk7CisJCXRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24ocGV4LmdldE1lc3NhZ2UoKSwgcGV4KTsKKwkgICAgfQorCX0gLy8gUmVsZWFzZSBNZXNzYWdlQ2FjaGVMb2NrCisKKwlpZiAoaXMgPT0gbnVsbCkKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiQ2Fubm90IGxvYWQgaGVhZGVyIik7CisJaGVhZGVycyA9IG5ldyBJbnRlcm5ldEhlYWRlcnMoaXMpOworCWhlYWRlcnNMb2FkZWQgPSB0cnVlOworICAgIH0KKworICAgIC8qCisgICAgICogTG9hZCB0aGlzIG1lc3NhZ2UncyBGbGFncworICAgICAqLworICAgIHByaXZhdGUgc3luY2hyb25pemVkIHZvaWQgbG9hZEZsYWdzKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKGZsYWdzICE9IG51bGwpCisJICAgIHJldHVybjsKKwkKKwkvLyBBY3F1aXJlIE1lc3NhZ2VDYWNoZUxvY2ssIHRvIGZyZWV6ZSBzZXFudW0uCisJc3luY2hyb25pemVkKGdldE1lc3NhZ2VDYWNoZUxvY2soKSkgeworCSAgICB0cnkgeworCQlJTUFQUHJvdG9jb2wgcCA9IGdldFByb3RvY29sKCk7CisKKwkJLy8gVGhpcyBtZXNzYWdlIGNvdWxkIGJlIGV4cHVuZ2VkIHdoZW4gd2Ugd2VyZSB3YWl0aW5nIAorCQkvLyB0byBhY3F1aXJlIHRoZSBsb2NrIC4uLgorCQljaGVja0V4cHVuZ2VkKCk7CisKKwkJZmxhZ3MgPSBwLmZldGNoRmxhZ3MoZ2V0U2VxdWVuY2VOdW1iZXIoKSk7CisJCS8vIG1ha2Ugc3VyZSBmbGFncyBpcyBhbHdheXMgc2V0LCBldmVuIGlmIHNlcnZlciBpcyBicm9rZW4KKwkJaWYgKGZsYWdzID09IG51bGwpCisJCSAgICBmbGFncyA9IG5ldyBGbGFncygpOworCSAgICB9IGNhdGNoIChDb25uZWN0aW9uRXhjZXB0aW9uIGNleCkgeworCQl0aHJvdyBuZXcgRm9sZGVyQ2xvc2VkRXhjZXB0aW9uKGZvbGRlciwgY2V4LmdldE1lc3NhZ2UoKSk7CisJICAgIH0gY2F0Y2ggKFByb3RvY29sRXhjZXB0aW9uIHBleCkgeworCQlmb3JjZUNoZWNrRXhwdW5nZWQoKTsKKwkJdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbihwZXguZ2V0TWVzc2FnZSgpLCBwZXgpOworCSAgICB9CisJfSAvLyBSZWxlYXNlIE1lc3NhZ2VDYWNoZUxvY2sKKyAgICB9CisKKyAgICAvKgorICAgICAqIEFyZSBhbGwgaGVhZGVycyBsb2FkZWQ/CisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGFyZUhlYWRlcnNMb2FkZWQoKSB7CisJcmV0dXJuIGhlYWRlcnNMb2FkZWQ7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBTZXQgd2hldGhlciBhbGwgaGVhZGVycyBhcmUgbG9hZGVkLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBzZXRIZWFkZXJzTG9hZGVkKGJvb2xlYW4gbG9hZGVkKSB7CisJaGVhZGVyc0xvYWRlZCA9IGxvYWRlZDsKKyAgICB9CisKKyAgICAvKiAKKyAgICAgKiBDaGVjayBpZiB0aGUgZ2l2ZW4gaGVhZGVyIHdhcyBldmVyIGxvYWRlZCBmcm9tIHRoZSBzZXJ2ZXIKKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gaXNIZWFkZXJMb2FkZWQoU3RyaW5nIG5hbWUpIHsKKwlpZiAoaGVhZGVyc0xvYWRlZCkgLy8gQWxsIGhlYWRlcnMgZm9yIHRoaXMgbWVzc2FnZSBoYXZlIGJlZW4gbG9hZGVkCisJICAgIHJldHVybiB0cnVlOworCQorCXJldHVybiBsb2FkZWRIZWFkZXJzLmNvbnRhaW5zS2V5KG5hbWUudG9VcHBlckNhc2UoTG9jYWxlLkVOR0xJU0gpKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIE1hcmsgdGhhdCB0aGUgZ2l2ZW4gaGVhZGVycyBoYXZlIGJlZW4gbG9hZGVkIGZyb20gdGhlIHNlcnZlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgc2V0SGVhZGVyTG9hZGVkKFN0cmluZyBuYW1lKSB7CisJbG9hZGVkSGVhZGVycy5wdXQobmFtZS50b1VwcGVyQ2FzZShMb2NhbGUuRU5HTElTSCksIG5hbWUpOworICAgIH0KKworICAgIC8qCisgICAgICogQ29udmVydCB0aGUgZ2l2ZW4gRkVUQ0ggaXRlbSBpZGVudGlmaWVyIHRvIHRoZSBhcHByb3JpYXRlIAorICAgICAqIHNlY3Rpb24tc3RyaW5nIGZvciB0aGlzIG1lc3NhZ2UuCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgdG9TZWN0aW9uKFN0cmluZyB3aGF0KSB7CisJaWYgKHNlY3Rpb25JZCA9PSBudWxsKQorCSAgICByZXR1cm4gd2hhdDsKKwllbHNlCisJICAgIHJldHVybiBzZWN0aW9uSWQgKyAiLiIgKyB3aGF0OworICAgIH0KKworICAgIC8qCisgICAgICogQ2xvbmUgYW4gYXJyYXkgb2YgSW50ZXJuZXRBZGRyZXNzZXMuCisgICAgICovCisgICAgcHJpdmF0ZSBJbnRlcm5ldEFkZHJlc3NbXSBhYWNsb25lKEludGVybmV0QWRkcmVzc1tdIGFhKSB7CisJaWYgKGFhID09IG51bGwpCisJICAgIHJldHVybiBudWxsOworCWVsc2UKKwkgICAgcmV0dXJuIGFhLmNsb25lKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBGbGFncyBfZ2V0RmxhZ3MoKSB7CisJcmV0dXJuIGZsYWdzOworICAgIH0KKworICAgIHByaXZhdGUgRU5WRUxPUEUgX2dldEVudmVsb3BlKCkgeworCXJldHVybiBlbnZlbG9wZTsKKyAgICB9CisKKyAgICBwcml2YXRlIEJPRFlTVFJVQ1RVUkUgX2dldEJvZHlTdHJ1Y3R1cmUoKSB7CisJcmV0dXJuIGJzOworICAgIH0KKworICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorICAgICAqIGFjY2Vzc29yIHJvdXRpbmVzIHRvIG1ha2UgYXZhaWxhYmxlIGNlcnRhaW4gcHJpdmF0ZS9wcm90ZWN0ZWQKKyAgICAgKiBmaWVsZHMgdG8gb3RoZXIgY2xhc3NlcyBpbiB0aGlzIHBhY2thZ2UuCisgICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisgICAgLyoKKyAgICAgKiBDYWxsZWQgYnkgSU1BUEZvbGRlci4KKyAgICAgKiBNdXN0IG5vdCBiZSBzeW5jaHJvbml6ZWQuCisgICAgICovCisgICAgdm9pZCBfc2V0RmxhZ3MoRmxhZ3MgZmxhZ3MpIHsKKwl0aGlzLmZsYWdzID0gZmxhZ3M7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBDYWxsZWQgYnkgSU1BUE5lc3RlZE1lc3NhZ2UuCisgICAgICovCisgICAgU2Vzc2lvbiBfZ2V0U2Vzc2lvbigpIHsKKwlyZXR1cm4gc2Vzc2lvbjsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvSU1BUE11bHRpcGFydERhdGFTb3VyY2UuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9JTUFQTXVsdGlwYXJ0RGF0YVNvdXJjZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM1NWVmMDIKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvSU1BUE11bHRpcGFydERhdGFTb3VyY2UuamF2YQpAQCAtMCwwICsxLDYxIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5pbWFwOworCisKK2ltcG9ydCBqYXZheC5tYWlsLio7CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC4qOworCitpbXBvcnQgY29tLnN1bi5tYWlsLmltYXAucHJvdG9jb2wuKjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCisvKioKKyAqIFRoaXMgY2xhc3MgCisgKgorICogQGF1dGhvciAgSm9obiBNYW5pCisgKi8KKworcHVibGljIGNsYXNzIElNQVBNdWx0aXBhcnREYXRhU291cmNlIGV4dGVuZHMgTWltZVBhcnREYXRhU291cmNlCisJCQkJICAgICBpbXBsZW1lbnRzIE11bHRpcGFydERhdGFTb3VyY2UgeworICAgIHByaXZhdGUgTGlzdDxJTUFQQm9keVBhcnQ+IHBhcnRzOworCisgICAgcHJvdGVjdGVkIElNQVBNdWx0aXBhcnREYXRhU291cmNlKE1pbWVQYXJ0IHBhcnQsIEJPRFlTVFJVQ1RVUkVbXSBicywgCisJCQkJICAgICAgU3RyaW5nIHNlY3Rpb25JZCwgSU1BUE1lc3NhZ2UgbXNnKSB7CisJc3VwZXIocGFydCk7CisKKwlwYXJ0cyA9IG5ldyBBcnJheUxpc3Q8Pihicy5sZW5ndGgpOworCWZvciAoaW50IGkgPSAwOyBpIDwgYnMubGVuZ3RoOyBpKyspCisJICAgIHBhcnRzLmFkZCgKKwkJbmV3IElNQVBCb2R5UGFydChic1tpXSwgCisJCQkJIHNlY3Rpb25JZCA9PSBudWxsID8gCisJCQkJICAgSW50ZWdlci50b1N0cmluZyhpKzEpIDogCisJCQkJICAgc2VjdGlvbklkICsgIi4iICsgSW50ZWdlci50b1N0cmluZyhpKzEpLAorCQkJCSBtc2cpCisJICAgICk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRDb3VudCgpIHsKKwlyZXR1cm4gcGFydHMuc2l6ZSgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBCb2R5UGFydCBnZXRCb2R5UGFydChpbnQgaW5kZXgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXJldHVybiBwYXJ0cy5nZXQoaW5kZXgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9JTUFQTmVzdGVkTWVzc2FnZS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0lNQVBOZXN0ZWRNZXNzYWdlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTJjZDRlNAotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9JTUFQTmVzdGVkTWVzc2FnZS5qYXZhCkBAIC0wLDAgKzEsMTM3IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5pbWFwOworCitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmF4Lm1haWwuKjsKK2ltcG9ydCBjb20uc3VuLm1haWwuaW1hcC5wcm90b2NvbC4qOworaW1wb3J0IGNvbS5zdW4ubWFpbC5pYXAuUHJvdG9jb2xFeGNlcHRpb247CisKKy8qKgorICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIGEgbmVzdGVkIElNQVAgbWVzc2FnZQorICoKKyAqIEBhdXRob3IgIEpvaG4gTWFuaQorICovCisKK3B1YmxpYyBjbGFzcyBJTUFQTmVzdGVkTWVzc2FnZSBleHRlbmRzIElNQVBNZXNzYWdlIHsKKyAgICBwcml2YXRlIElNQVBNZXNzYWdlIG1zZzsgLy8gdGhlIGVuY2xvc3VyZSBvZiB0aGlzIG5lc3RlZCBtZXNzYWdlCisKKyAgICAvKioKKyAgICAgKiBQYWNrYWdlIHByaXZhdGUgY29uc3RydWN0b3IuIDxwPgorICAgICAqCisgICAgICogTm90ZSB0aGF0IG5lc3RlZCBtZXNzYWdlcyBoYXZlIG5vIGNvbnRhaW5pbmcgZm9sZGVyLCBub3IgCisgICAgICogYSBtZXNzYWdlIG51bWJlci4KKyAgICAgKi8KKyAgICBJTUFQTmVzdGVkTWVzc2FnZShJTUFQTWVzc2FnZSBtLCBCT0RZU1RSVUNUVVJFIGIsIEVOVkVMT1BFIGUsIFN0cmluZyBzaWQpIHsKKwlzdXBlcihtLl9nZXRTZXNzaW9uKCkpOworCW1zZyA9IG07CisJYnMgPSBiOworCWVudmVsb3BlID0gZTsKKwlzZWN0aW9uSWQgPSBzaWQ7CisJc2V0UGVlayhtLmdldFBlZWsoKSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBHZXQgdGhlIGVuY2xvc2luZyBtZXNzYWdlJ3MgUHJvdG9jb2wgb2JqZWN0LiBPdmVycmlkZXMKKyAgICAgKiBJTUFQTWVzc2FnZS5nZXRQcm90b2NvbCgpLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBJTUFQUHJvdG9jb2wgZ2V0UHJvdG9jb2woKQorCQkJdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uLCBGb2xkZXJDbG9zZWRFeGNlcHRpb24geworCXJldHVybiBtc2cuZ2V0UHJvdG9jb2woKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIElzIHRoaXMgYW4gSU1BUDQgUkVWMSBzZXJ2ZXI/CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gaXNSRVYxKCkgdGhyb3dzIEZvbGRlckNsb3NlZEV4Y2VwdGlvbiB7CisJcmV0dXJuIG1zZy5pc1JFVjEoKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIEdldCB0aGUgZW5jbG9zaW5nIG1lc3NhZ2UncyBtZXNzYWdlQ2FjaGVMb2NrLiBPdmVycmlkZXMKKyAgICAgKiBJTUFQTWVzc2FnZS5nZXRNZXNzYWdlQ2FjaGVMb2NrKCkuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIE9iamVjdCBnZXRNZXNzYWdlQ2FjaGVMb2NrKCkgeworCXJldHVybiBtc2cuZ2V0TWVzc2FnZUNhY2hlTG9jaygpOworICAgIH0KKworICAgIC8qCisgICAgICogR2V0IHRoZSBlbmNsb3NpbmcgbWVzc2FnZSdzIHNlcXVlbmNlIG51bWJlci4gT3ZlcnJpZGVzCisgICAgICogSU1BUE1lc3NhZ2UuZ2V0U2VxdWVuY2VOdW1iZXIoKS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgaW50IGdldFNlcXVlbmNlTnVtYmVyKCkgeworCXJldHVybiBtc2cuZ2V0U2VxdWVuY2VOdW1iZXIoKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIENoZWNrIHdoZXRoZXIgdGhlIGVuY2xvc2luZyBtZXNzYWdlIGlzIGV4cHVuZ2VkLiBPdmVycmlkZXMgCisgICAgICogSU1BUE1lc3NhZ2UuY2hlY2tFeHB1bmdlZCgpLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIGNoZWNrRXhwdW5nZWQoKSB0aHJvd3MgTWVzc2FnZVJlbW92ZWRFeGNlcHRpb24geworCW1zZy5jaGVja0V4cHVuZ2VkKCk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBDaGVjayB3aGV0aGVyIHRoZSBlbmNsb3NpbmcgbWVzc2FnZSBpcyBleHB1bmdlZC4gT3ZlcnJpZGVzCisgICAgICogTWVzc2FnZS5pc0V4cHVuZ2VkKCkuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaXNFeHB1bmdlZCgpIHsKKwlyZXR1cm4gbXNnLmlzRXhwdW5nZWQoKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIEdldCB0aGUgZW5jbG9zaW5nIG1lc3NhZ2UncyBmZXRjaEJsb2NrU2l6ZS4gCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGludCBnZXRGZXRjaEJsb2NrU2l6ZSgpIHsKKwlyZXR1cm4gbXNnLmdldEZldGNoQmxvY2tTaXplKCk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBHZXQgdGhlIGVuY2xvc2luZyBtZXNzYWdlJ3MgaWdub3JlQm9keVN0cnVjdHVyZVNpemUuIAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBib29sZWFuIGlnbm9yZUJvZHlTdHJ1Y3R1cmVTaXplKCkgeworCXJldHVybiBtc2cuaWdub3JlQm9keVN0cnVjdHVyZVNpemUoKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIElNQVBNZXNzYWdlIHVzZXMgUkZDODIyLlNJWkUuIFdlIHVzZSB0aGUgInNpemUiIGZpZWxkIGZyb20KKyAgICAgKiBvdXIgQk9EWVNUUlVDVFVSRS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldFNpemUoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gYnMuc2l6ZTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIERpc2FsbG93IHNldHRpbmcgZmxhZ3Mgb24gbmVzdGVkIG1lc3NhZ2VzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHNldEZsYWdzKEZsYWdzIGZsYWcsIGJvb2xlYW4gc2V0KSAKKwkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCS8vIENhbm5vdCBzZXQgRkxBR1Mgb24gYSBuZXN0ZWQgSU1BUCBtZXNzYWdlCQorCXRocm93IG5ldyBNZXRob2ROb3RTdXBwb3J0ZWRFeGNlcHRpb24oCisJCSJDYW5ub3Qgc2V0IGZsYWdzIG9uIHRoaXMgbmVzdGVkIG1lc3NhZ2UiKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvSU1BUFByb3ZpZGVyLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvSU1BUFByb3ZpZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTYwNDUwMQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9JTUFQUHJvdmlkZXIuamF2YQpAQCAtMCwwICsxLDI5IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5pbWFwOworCitpbXBvcnQgamF2YXgubWFpbC5Qcm92aWRlcjsKKworLyoqCisgKiBUaGUgSU1BUCBwcm90b2NvbCBwcm92aWRlci4KKyAqLworcHVibGljIGNsYXNzIElNQVBQcm92aWRlciBleHRlbmRzIFByb3ZpZGVyIHsKKyAgICBwdWJsaWMgSU1BUFByb3ZpZGVyKCkgeworCXN1cGVyKFByb3ZpZGVyLlR5cGUuU1RPUkUsICJpbWFwIiwgSU1BUFN0b3JlLmNsYXNzLmdldE5hbWUoKSwKKwkgICAgIk9yYWNsZSIsIG51bGwpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9JTUFQU1NMUHJvdmlkZXIuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9JTUFQU1NMUHJvdmlkZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MWZlNjg2Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0lNQVBTU0xQcm92aWRlci5qYXZhCkBAIC0wLDAgKzEsMjkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmltYXA7CisKK2ltcG9ydCBqYXZheC5tYWlsLlByb3ZpZGVyOworCisvKioKKyAqIFRoZSBJTUFQIFNTTCBwcm90b2NvbCBwcm92aWRlci4KKyAqLworcHVibGljIGNsYXNzIElNQVBTU0xQcm92aWRlciBleHRlbmRzIFByb3ZpZGVyIHsKKyAgICBwdWJsaWMgSU1BUFNTTFByb3ZpZGVyKCkgeworCXN1cGVyKFByb3ZpZGVyLlR5cGUuU1RPUkUsICJpbWFwcyIsIElNQVBTU0xTdG9yZS5jbGFzcy5nZXROYW1lKCksCisJICAgICJPcmFjbGUiLCBudWxsKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvSU1BUFNTTFN0b3JlLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvSU1BUFNTTFN0b3JlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDg4YjRlYwotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9JTUFQU1NMU3RvcmUuamF2YQpAQCAtMCwwICsxLDM3IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5pbWFwOworCitpbXBvcnQgamF2YXgubWFpbC4qOworCisvKioKKyAqIFRoaXMgY2xhc3MgcHJvdmlkZXMgYWNjZXNzIHRvIGFuIElNQVAgbWVzc2FnZSBzdG9yZSBvdmVyIFNTTC4KKyAqLworCitwdWJsaWMgY2xhc3MgSU1BUFNTTFN0b3JlIGV4dGVuZHMgSU1BUFN0b3JlIHsKKyAgICAKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvciB0aGF0IHRha2VzIGEgU2Vzc2lvbiBvYmplY3QgYW5kIGEgVVJMTmFtZSB0aGF0CisgICAgICogcmVwcmVzZW50cyBhIHNwZWNpZmljIElNQVAgc2VydmVyLgorICAgICAqCisgICAgICogQHBhcmFtCXNlc3Npb24JdGhlIFNlc3Npb24KKyAgICAgKiBAcGFyYW0JdXJsCXRoZSBVUkxOYW1lIG9mIHRoaXMgc3RvcmUKKyAgICAgKi8KKyAgICBwdWJsaWMgSU1BUFNTTFN0b3JlKFNlc3Npb24gc2Vzc2lvbiwgVVJMTmFtZSB1cmwpIHsKKwlzdXBlcihzZXNzaW9uLCB1cmwsICJpbWFwcyIsIHRydWUpOyAvLyBjYWxsIHN1cGVyIGNvbnN0cnVjdG9yCisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0lNQVBTdG9yZS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0lNQVBTdG9yZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE2YjUxODIKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvSU1BUFN0b3JlLmphdmEKQEAgLTAsMCArMSwyMjEwIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5pbWFwOworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuKjsKK2ltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOworaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LkluZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LlVua25vd25Ib3N0RXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTGV2ZWw7CisKK2ltcG9ydCBqYXZheC5tYWlsLio7CitpbXBvcnQgamF2YXgubWFpbC5ldmVudC4qOworCitpbXBvcnQgY29tLnN1bi5tYWlsLmlhcC4qOworaW1wb3J0IGNvbS5zdW4ubWFpbC5pbWFwLnByb3RvY29sLio7CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuUHJvcFV0aWw7CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuTWFpbExvZ2dlcjsKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5Tb2NrZXRDb25uZWN0RXhjZXB0aW9uOworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLk1haWxDb25uZWN0RXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKKy8qKgorICogVGhpcyBjbGFzcyBwcm92aWRlcyBhY2Nlc3MgdG8gYW4gSU1BUCBtZXNzYWdlIHN0b3JlLiA8cD4KKyAqCisgKiBBcHBsaWNhdGlvbnMgdGhhdCBuZWVkIHRvIG1ha2UgdXNlIG9mIElNQVAtc3BlY2lmaWMgZmVhdHVyZXMgbWF5IGNhc3QKKyAqIGEgPGNvZGU+U3RvcmU8L2NvZGU+IG9iamVjdCB0byBhbiA8Y29kZT5JTUFQU3RvcmU8L2NvZGU+IG9iamVjdCBhbmQKKyAqIHVzZSB0aGUgbWV0aG9kcyBvbiB0aGlzIGNsYXNzLiBUaGUge0BsaW5rICNnZXRRdW90YSBnZXRRdW90YX0gYW5kCisgKiB7QGxpbmsgI3NldFF1b3RhIHNldFF1b3RhfSBtZXRob2RzIHN1cHBvcnQgdGhlIElNQVAgUVVPVEEgZXh0ZW5zaW9uLgorICogUmVmZXIgdG8gPEEgSFJFRj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjA4Ny50eHQiPlJGQyAyMDg3PC9BPgorICogZm9yIG1vcmUgaW5mb3JtYXRpb24uIDxwPgorICoKKyAqIFRoZSB7QGxpbmsgI2lkIGlkfSBtZXRob2Qgc3VwcG9ydHMgdGhlIElNQVAgSUQgZXh0ZW5zaW9uOworICogc2VlIDxBIEhSRUY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzI5NzEudHh0Ij5SRkMgMjk3MTwvQT4uCisgKiBUaGUgZmllbGRzIElEX05BTUUsIElEX1ZFUlNJT04sIGV0Yy4gcmVwcmVzZW50IHRoZSBzdWdnZXN0ZWQgZmllbGQgbmFtZXMKKyAqIGluIFJGQyAyOTcxIHNlY3Rpb24gMy4zIGFuZCBtYXkgYmUgdXNlZCBhcyBrZXlzIGluIHRoZSBNYXAgY29udGFpbmluZworICogY2xpZW50IHZhbHVlcyBvciBzZXJ2ZXIgdmFsdWVzLiA8cD4KKyAqCisgKiBTZWUgdGhlIDxhIGhyZWY9InBhY2thZ2Utc3VtbWFyeS5odG1sIj5jb20uc3VuLm1haWwuaW1hcDwvYT4gcGFja2FnZQorICogZG9jdW1lbnRhdGlvbiBmb3IgZnVydGhlciBpbmZvcm1hdGlvbiBvbiB0aGUgSU1BUCBwcm90b2NvbCBwcm92aWRlci4gPHA+CisgKgorICogPHN0cm9uZz5XQVJOSU5HOjwvc3Ryb25nPiBUaGUgQVBJcyB1bmlxdWUgdG8gdGhpcyBjbGFzcyBzaG91bGQgYmUKKyAqIGNvbnNpZGVyZWQgPHN0cm9uZz5FWFBFUklNRU5UQUw8L3N0cm9uZz4uICBUaGV5IG1heSBiZSBjaGFuZ2VkIGluIHRoZQorICogZnV0dXJlIGluIHdheXMgdGhhdCBhcmUgaW5jb21wYXRpYmxlIHdpdGggYXBwbGljYXRpb25zIHVzaW5nIHRoZQorICogY3VycmVudCBBUElzLgorICoKKyAqIEBhdXRob3IgIEpvaG4gTWFuaQorICogQGF1dGhvciAgQmlsbCBTaGFubm9uCisgKiBAYXV0aG9yICBKaW0gR2xlbm5vbgorICovCisvKgorICogVGhpcyBwYWNrYWdlIGlzIGltcGxlbWVudGVkIG92ZXIgdGhlICJpbWFwLnByb3RvY29sIiBwYWNrYWdlLCB3aGljaAorICogaW1wbGVtZW50cyB0aGUgcHJvdG9jb2wtbGV2ZWwgY29tbWFuZHMuIDxwPgorICoKKyAqIEEgY29ubmVjdGVkIElNQVBTdG9yZSBtYWludGFpbnMgYSBwb29sIG9mIElNQVAgcHJvdG9jb2wgb2JqZWN0cyBmb3IKKyAqIHVzZSBpbiBjb21tdW5pY2F0aW5nIHdpdGggdGhlIElNQVAgc2VydmVyLiBUaGUgSU1BUFN0b3JlIHdpbGwgY3JlYXRlCisgKiB0aGUgaW5pdGlhbCBBVVRIRU5USUNBVEVEIGNvbm5lY3Rpb24gYW5kIHNlZWQgdGhlIHBvb2wgd2l0aCB0aGlzCisgKiBjb25uZWN0aW9uLiBBcyBmb2xkZXJzIGFyZSBvcGVuZWQgYW5kIG5ldyBJTUFQIHByb3RvY29sIG9iamVjdHMgYXJlCisgKiBuZWVkZWQsIHRoZSBJTUFQU3RvcmUgd2lsbCBwcm92aWRlIHRoZW0gZnJvbSB0aGUgY29ubmVjdGlvbiBwb29sLAorICogb3IgY3JlYXRlIHRoZW0gaWYgbm9uZSBhcmUgYXZhaWxhYmxlLiBXaGVuIGEgZm9sZGVyIGlzIGNsb3NlZCwKKyAqIGl0cyBJTUFQIHByb3RvY29sIG9iamVjdCBpcyByZXR1cm5lZCB0byB0aGUgY29ubmVjdGlvbiBwb29sIGlmIHRoZQorICogcG9vbCBpcyBub3Qgb3ZlciBjYXBhY2l0eS4gVGhlIHBvb2wgc2l6ZSBjYW4gYmUgY29uZmlndXJlZCBieSBzZXR0aW5nCisgKiB0aGUgbWFpbC5pbWFwLmNvbm5lY3Rpb25wb29sc2l6ZSBwcm9wZXJ0eS4gPHA+CisgKgorICogTm90ZSB0aGF0IGFsbCBjb25uZWN0aW9ucyBpbiB0aGUgY29ubmVjdGlvbiBwb29sIGhhdmUgdGhlaXIgcmVzcG9uc2UKKyAqIGhhbmRsZXIgc2V0IHRvIGJlIHRoZSBTdG9yZS4gIFdoZW4gdGhlIGNvbm5lY3Rpb24gaXMgcmVtb3ZlZCBmcm9tIHRoZQorICogcG9vbCBmb3IgdXNlIGJ5IGEgZm9sZGVyLCB0aGUgcmVzcG9uc2UgaGFuZGxlciBpcyByZW1vdmVkIGFuZCB0aGVuIHNldAorICogdG8gZWl0aGVyIHRoZSBGb2xkZXIgb3IgdG8gdGhlIHNwZWNpYWwgbm9uU3RvcmVSZXNwb25zZUhhbmRsZXIsIGRlcGVuZGluZworICogb24gaG93IHRoZSBjb25uZWN0aW9uIGlzIGJlaW5nIHVzZWQuICBUaGlzIGlzIHByb2JhYmx5IGV4Y2Vzc2l2ZS4KKyAqIEJldHRlciB3b3VsZCBiZSBmb3IgdGhlIFByb3RvY29sIG9iamVjdCB0byBzdXBwb3J0IG9ubHkgYSBzaW5nbGUKKyAqIHJlc3BvbnNlIGhhbmRsZXIsIHdoaWNoIHdvdWxkIGJlIHNldCBiZWZvcmUgdGhlIGNvbm5lY3Rpb24gaXMgdXNlZAorICogYW5kIGNsZWFyZWQgd2hlbiB0aGUgY29ubmVjdGlvbiBpcyBpbiB0aGUgcG9vbCBhbmQgY2FuJ3QgYmUgdXNlZC4gPHA+CisgKgorICogQSBtZWNoYW5pc20gaXMgcHJvdmlkZWQgZm9yIHRpbWluZyBvdXQgaWRsZSBjb25uZWN0aW9uIHBvb2wgSU1BUAorICogcHJvdG9jb2wgb2JqZWN0cy4gVGltZWQgb3V0IGNvbm5lY3Rpb25zIGFyZSBjbG9zZWQgYW5kIHJlbW92ZWQgKHBydW5lZCkKKyAqIGZyb20gdGhlIGNvbm5lY3Rpb24gcG9vbC4gVGhlIHRpbWUgb3V0IGludGVydmFsIGNhbiBiZSBjb25maWd1cmVkIHZpYQorICogdGhlIG1haWwuaW1hcC5jb25uZWN0aW9ucG9vbHRpbWVvdXQgcHJvcGVydHkuIDxwPgorICoKKyAqIFRoZSBjb25uZWN0ZWQgSU1BUFN0b3JlIG9iamVjdCBtYXkgb3IgbWF5IG5vdCBtYWludGFpbiBhIHNlcGFyYXRlIElNQVAKKyAqIHByb3RvY29sIG9iamVjdCB0aGF0IHByb3ZpZGVzIHRoZSBzdG9yZSBhIGRlZGljYXRlZCBjb25uZWN0aW9uIHRvIHRoZQorICogSU1BUCBzZXJ2ZXIuIFRoaXMgaXMgcHJvdmlkZWQgbWFpbmx5IGZvciBjb21wYXRpYmlsaXR5IHdpdGggcHJldmlvdXMKKyAqIGltcGxlbWVudGF0aW9ucyBvZiBKYXZhTWFpbCBhbmQgaXMgZGV0ZXJtaW5lZCBieSB0aGUgdmFsdWUgb2YgdGhlIAorICogbWFpbC5pbWFwLnNlcGFyYXRlc3RvcmVjb25uZWN0aW9uIHByb3BlcnR5LiA8cD4KKyAqCisgKiBBbiBJTUFQU3RvcmUgb2JqZWN0IHByb3ZpZGVzIGNsb3NlZCBJTUFQRm9sZGVyIG9iamVjdHMgdGhydSBpdHMgbGlzdCgpCisgKiBhbmQgbGlzdFN1YnNjcmliZWQoKSBtZXRob2RzLiBBIGNsb3NlZCBJTUFQRm9sZGVyIG9iamVjdCBhY3F1aXJlcyBhbgorICogSU1BUCBwcm90b2NvbCBvYmplY3QgZnJvbSB0aGUgc3RvcmUgdG8gY29tbXVuaWNhdGUgd2l0aCB0aGUgc2VydmVyLiBXaGVuCisgKiB0aGUgZm9sZGVyIGlzIG9wZW5lZCwgaXQgZ2V0cyBpdHMgb3duIHByb3RvY29sIG9iamVjdCBhbmQgdGh1cyBpdHMgb3duLAorICogc2VwYXJhdGUgY29ubmVjdGlvbiB0byB0aGUgc2VydmVyLiBUaGUgc3RvcmUgbWFpbnRhaW5zIHJlZmVyZW5jZXMgdG8KKyAqIGFsbCAnb3BlbicgZm9sZGVycy4gV2hlbiBhIGZvbGRlciBpcy9nZXRzIGNsb3NlZCwgdGhlIHN0b3JlIHJlbW92ZXMKKyAqIGl0IGZyb20gaXRzIGxpc3QuIFdoZW4gdGhlIHN0b3JlIGlzL2dldHMgY2xvc2VkLCBpdCBjbG9zZXMgYWxsIG9wZW4gCisgKiBmb2xkZXJzIGluIGl0cyBsaXN0LCB0aHVzIGNsZWFuaW5nIHVwIGFsbCBvcGVuIGNvbm5lY3Rpb25zIHRvIHRoZQorICogc2VydmVyLiA8cD4KKyAqCisgKiBBIG11dGV4IGlzIHVzZWQgdG8gY29udHJvbCBhY2Nlc3MgdG8gdGhlIGNvbm5lY3Rpb24gcG9vbCByZXNvdXJjZXMuCisgKiBBbnkgdGltZSBhbnkgb2YgdGhlc2UgcmVzb3VyY2VzIG5lZWQgdG8gYmUgYWNjZXNzZWQsIHRoZSBmb2xsb3dpbmcKKyAqIGNvbnZlbnRpb24gc2hvdWxkIGJlIGZvbGxvd2VkOgorICoKKyAqICAgICBzeW5jaHJvbml6ZWQgKHBvb2wpIHsgLy8gQUNRVUlSRSBMT0NLCisgKiAgICAgICAgIC8vIGFjY2VzcyBjb25uZWN0aW9uIHBvb2wgcmVzb3VyY2VzCisgKiAgICAgfSAvLyBSRUxFQVNFIExPQ0sgPHA+CisgKgorICogVGhlIGxvY2tpbmcgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIHN0b3JlIGFuZCBmb2xkZXJzIGlzIHRoYXQgdGhlCisgKiBzdG9yZSBsb2NrIG11c3QgYmUgYWNxdWlyZWQgYmVmb3JlIGEgZm9sZGVyIGxvY2suIFRoaXMgaXMgY3VycmVudGx5IG9ubHkKKyAqIGFwcGxpY2FibGUgaW4gdGhlIHN0b3JlJ3MgY2xlYW51cCBtZXRob2QuIEl0J3MgaW1wb3J0YW50IHRoYXQgdGhlCisgKiBjb25uZWN0aW9uIHBvb2wgbG9jayBpcyBub3QgaGVsZCB3aGVuIGNhbGxpbmcgaW50byBmb2xkZXIgb2JqZWN0cy4KKyAqIFRoZSBsb2NraW5nIGhpZXJhcmNoeSBpcyB0aGF0IGEgZm9sZGVyIGxvY2sgbXVzdCBiZSBhY3F1aXJlZCBiZWZvcmUKKyAqIGFueSBjb25uZWN0aW9uIHBvb2wgb3BlcmF0aW9ucyBhcmUgcGVyZm9ybWVkLiAgWW91IG5ldmVyIG5lZWQgdG8gaG9sZAorICogYWxsIHRocmVlIGxvY2tzLCBidXQgaWYgeW91IGhvbGQgbW9yZSB0aGFuIG9uZSB0aGlzIGlzIHRoZSBvcmRlciB5b3UKKyAqIGhhdmUgdG8gYWNxdWlyZSB0aGVtIGluLiA8cD4KKyAqCisgKiBUaGF0IGlzOiBTdG9yZSA+IEZvbGRlciwgRm9sZGVyID4gcG9vbCwgU3RvcmUgPiBwb29sIDxwPgorICoKKyAqIFRoZSBJTUFQU3RvcmUgaW1wbGVtZW50cyB0aGUgUmVzcG9uc2VIYW5kbGVyIGludGVyZmFjZSBhbmQgbGlzdGVucyB0bworICogQllFIG9yIHVudGFnZ2VkIE9LLW5vdGlmaWNhdGlvbiBldmVudHMgZnJvbSB0aGUgc2VydmVyIGFzIGEgcmVzdWx0IG9mCisgKiBTdG9yZSBvcGVyYXRpb25zLiAgSU1BUEZvbGRlciBmb3J3YXJkcyBub3RpZmljYXRpb25zIHRoYXQgcmVzdWx0IGZyb20KKyAqIEZvbGRlciBvcGVyYXRpb25zIHVzaW5nIHRoZSBzdG9yZSBjb25uZWN0aW9uOyB0aGUgSU1BUFN0b3JlIFJlc3BvbnNlSGFuZGxlcgorICogaXMgbm90IHVzZWQgZGlyZWN0bHkgaW4gdGhpcyBjYXNlLiA8cD4KKyAqLworCitwdWJsaWMgY2xhc3MgSU1BUFN0b3JlIGV4dGVuZHMgU3RvcmUgCisJICAgICBpbXBsZW1lbnRzIFF1b3RhQXdhcmVTdG9yZSwgUmVzcG9uc2VIYW5kbGVyIHsKKyAgICAKKyAgICAvKioKKyAgICAgKiBBIHNwZWNpYWwgZXZlbnQgdHlwZSBmb3IgYSBTdG9yZUV2ZW50IHRvIGluZGljYXRlIGFuIElNQVAKKyAgICAgKiByZXNwb25zZSwgaWYgdGhlIG1haWwuaW1hcC5lbmFibGVpbWFwZXZlbnRzIHByb3BlcnR5IGlzIHNldC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVNQT05TRSA9IDEwMDA7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJRF9OQU1FID0gIm5hbWUiOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElEX1ZFUlNJT04gPSAidmVyc2lvbiI7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSURfT1MgPSAib3MiOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElEX09TX1ZFUlNJT04gPSAib3MtdmVyc2lvbiI7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSURfVkVORE9SID0gInZlbmRvciI7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSURfU1VQUE9SVF9VUkwgPSAic3VwcG9ydC11cmwiOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElEX0FERFJFU1MgPSAiYWRkcmVzcyI7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSURfREFURSA9ICJkYXRlIjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJRF9DT01NQU5EID0gImNvbW1hbmQiOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElEX0FSR1VNRU5UUyA9ICJhcmd1bWVudHMiOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElEX0VOVklST05NRU5UID0gImVudmlyb25tZW50IjsKKworICAgIHByb3RlY3RlZCBmaW5hbCBTdHJpbmcgbmFtZTsJLy8gbmFtZSBvZiB0aGlzIHByb3RvY29sCisgICAgcHJvdGVjdGVkIGZpbmFsIGludCBkZWZhdWx0UG9ydDsJLy8gZGVmYXVsdCBJTUFQIHBvcnQKKyAgICBwcm90ZWN0ZWQgZmluYWwgYm9vbGVhbiBpc1NTTDsJLy8gdXNlIFNTTD8KKworICAgIHByaXZhdGUgZmluYWwgaW50IGJsa3NpemU7CQkvLyBCbG9jayBzaXplIGZvciBkYXRhIHJlcXVlc3RlZAorCQkJCQkvLyBpbiBGRVRDSCByZXF1ZXN0cy4gRGVmYXVsdHMgdG8KKwkJCQkJLy8gMTZLCisKKyAgICBwcml2YXRlIGJvb2xlYW4gaWdub3JlU2l6ZTsJCS8vIGlnbm9yZSB0aGUgc2l6ZSBpbiBCT0RZU1RSVUNUVVJFPworCisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgc3RhdHVzQ2FjaGVUaW1lb3V0OwkvLyBjYWNoZSBTdGF0dXMgZm9yIDEgc2Vjb25kCisKKyAgICBwcml2YXRlIGZpbmFsIGludCBhcHBlbmRCdWZmZXJTaXplOwkvLyBtYXggc2l6ZSBvZiBtc2cgYnVmZmVyZWQgZm9yIGFwcGVuZAorCisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgbWluSWRsZVRpbWU7CS8vIG1pbmltdW0gaWRsZSB0aW1lCisKKyAgICBwcml2YXRlIHZvbGF0aWxlIGludCBwb3J0ID0gLTE7CS8vIHBvcnQgdG8gdXNlCisKKyAgICAvLyBBdXRoIGluZm8KKyAgICBwcm90ZWN0ZWQgU3RyaW5nIGhvc3Q7CisgICAgcHJvdGVjdGVkIFN0cmluZyB1c2VyOworICAgIHByb3RlY3RlZCBTdHJpbmcgcGFzc3dvcmQ7CisgICAgcHJvdGVjdGVkIFN0cmluZyBwcm94eUF1dGhVc2VyOworICAgIHByb3RlY3RlZCBTdHJpbmcgYXV0aG9yaXphdGlvbklEOworICAgIHByb3RlY3RlZCBTdHJpbmcgc2FzbFJlYWxtOworCisgICAgcHJpdmF0ZSBOYW1lc3BhY2VzIG5hbWVzcGFjZXM7CisKKyAgICBwcml2YXRlIGJvb2xlYW4gZW5hYmxlU3RhcnRUTFMgPSBmYWxzZTsJLy8gZW5hYmxlIFNUQVJUVExTCisgICAgcHJpdmF0ZSBib29sZWFuIHJlcXVpcmVTdGFydFRMUyA9IGZhbHNlOwkvLyByZXF1aXJlIFNUQVJUVExTCisgICAgcHJpdmF0ZSBib29sZWFuIHVzaW5nU1NMID0gZmFsc2U7CQkvLyB1c2luZyBTU0w/CisgICAgcHJpdmF0ZSBib29sZWFuIGVuYWJsZVNBU0wgPSBmYWxzZTsJCS8vIGVuYWJsZSBTQVNMIGF1dGhlbnRpY2F0aW9uCisgICAgcHJpdmF0ZSBTdHJpbmdbXSBzYXNsTWVjaGFuaXNtczsKKyAgICBwcml2YXRlIGJvb2xlYW4gZm9yY2VQYXNzd29yZFJlZnJlc2ggPSBmYWxzZTsKKyAgICAvLyBlbmFibGUgbm90aWZpY2F0aW9uIG9mIElNQVAgcmVzcG9uc2VzCisgICAgcHJpdmF0ZSBib29sZWFuIGVuYWJsZVJlc3BvbnNlRXZlbnRzID0gZmFsc2U7CisgICAgLy8gZW5hYmxlIG5vdGlmaWNhdGlvbiBvZiBJTUFQIHJlc3BvbnNlcyBkdXJpbmcgSURMRQorICAgIHByaXZhdGUgYm9vbGVhbiBlbmFibGVJbWFwRXZlbnRzID0gZmFsc2U7CisgICAgcHJpdmF0ZSBTdHJpbmcgZ3VpZDsJCQkvLyBmb3IgWWFob28hIE1haWwgSU1BUAorICAgIHByaXZhdGUgYm9vbGVhbiB0aHJvd1NlYXJjaEV4Y2VwdGlvbiA9IGZhbHNlOworICAgIHByaXZhdGUgYm9vbGVhbiBwZWVrID0gZmFsc2U7CisgICAgcHJpdmF0ZSBib29sZWFuIGNsb3NlRm9sZGVyc09uU3RvcmVGYWlsdXJlID0gdHJ1ZTsKKyAgICBwcml2YXRlIGJvb2xlYW4gZW5hYmxlQ29tcHJlc3MgPSBmYWxzZTsJLy8gZW5hYmxlIENPTVBSRVNTPURFRkxBVEUKKyAgICBwcml2YXRlIGJvb2xlYW4gZmluYWxpemVDbGVhbkNsb3NlID0gZmFsc2U7CisKKyAgICAvKgorICAgICAqIFRoaXMgZmllbGQgaXMgc2V0IGluIHRoZSBTdG9yZSdzIHJlc3BvbnNlIGhhbmRsZXIgaWYgd2Ugc2VlCisgICAgICogYSBCWUUgcmVzcG9uc2UuICBUaGUgcmVsZWFzZVN0b3JlIG1ldGhvZCBjaGVja3MgdGhpcyBmaWVsZAorICAgICAqIGFuZCBpZiBzZXQgaXQgY2xlYW5zIHVwIHRoZSBTdG9yZS4gIEZpZWxkIGlzIHZvbGF0aWxlIGJlY2F1c2UKKyAgICAgKiB0aGVyZSdzIG5vIGxvY2sgd2UgY29uc2lzdGVudGx5IGhvbGQgd2hpbGUgbWFuaXB1bGF0aW5nIGl0LgorICAgICAqCisgICAgICogQmVjYXVzZSB2b2xhdGlsZSBkb2Vzbid0IHJlYWxseSB3b3JrIGJlZm9yZSBKREsgMS41LAorICAgICAqIHVzZSBhIGxvY2sgdG8gcHJvdGVjdCB0aGVzZSB0d28gZmllbGRzLgorICAgICAqLworICAgIHByaXZhdGUgdm9sYXRpbGUgYm9vbGVhbiBjb25uZWN0aW9uRmFpbGVkID0gZmFsc2U7CisgICAgcHJpdmF0ZSB2b2xhdGlsZSBib29sZWFuIGZvcmNlQ2xvc2UgPSBmYWxzZTsKKyAgICBwcml2YXRlIGZpbmFsIE9iamVjdCBjb25uZWN0aW9uRmFpbGVkTG9jayA9IG5ldyBPYmplY3QoKTsKKworICAgIHByaXZhdGUgYm9vbGVhbiBkZWJ1Z3VzZXJuYW1lOwkvLyBpbmNsdWRlIHVzZXJuYW1lIGluIGRlYnVnIG91dHB1dD8KKyAgICBwcml2YXRlIGJvb2xlYW4gZGVidWdwYXNzd29yZDsJLy8gaW5jbHVkZSBwYXNzd29yZCBpbiBkZWJ1ZyBvdXRwdXQ/CisgICAgcHJvdGVjdGVkIE1haWxMb2dnZXIgbG9nZ2VyOwkvLyBmb3IgZGVidWcgb3V0cHV0CisKKyAgICBwcml2YXRlIGJvb2xlYW4gbWVzc2FnZUNhY2hlRGVidWc7CisKKyAgICAvLyBjb25zdHJ1Y3RvcnMgZm9yIElNQVBGb2xkZXIgY2xhc3MgcHJvdmlkZWQgYnkgdXNlcgorICAgIHByaXZhdGUgdm9sYXRpbGUgQ29uc3RydWN0b3I8Pz4gZm9sZGVyQ29uc3RydWN0b3IgPSBudWxsOworICAgIHByaXZhdGUgdm9sYXRpbGUgQ29uc3RydWN0b3I8Pz4gZm9sZGVyQ29uc3RydWN0b3JMSSA9IG51bGw7CisKKyAgICAvLyBDb25uZWN0aW9uIHBvb2wgaW5mbworCisgICAgc3RhdGljIGNsYXNzIENvbm5lY3Rpb25Qb29sIHsKKworICAgICAgICAvLyBjb250YWluZXIgZm9yIHRoZSBwb29sJ3MgSU1BUCBwcm90b2NvbCBvYmplY3RzCisgICAgICAgIHByaXZhdGUgVmVjdG9yPElNQVBQcm90b2NvbD4gYXV0aGVudGljYXRlZENvbm5lY3Rpb25zCisJCT0gbmV3IFZlY3Rvcjw+KCk7CisKKyAgICAgICAgLy8gdmVjdG9yZSBvZiBvcGVuIGZvbGRlcnMKKyAgICAgICAgcHJpdmF0ZSBWZWN0b3I8SU1BUEZvbGRlcj4gZm9sZGVyczsKKworICAgICAgICAvLyBpcyB0aGUgc3RvcmUgY29ubmVjdGlvbiBiZWluZyB1c2VkPworICAgICAgICBwcml2YXRlIGJvb2xlYW4gc3RvcmVDb25uZWN0aW9uSW5Vc2UgPSBmYWxzZTsgCisKKyAgICAgICAgLy8gdGhlIGxhc3QgdGltZSAoaW4gbWlsbGlzKSB0aGUgcG9vbCB3YXMgY2hlY2tlZCBmb3IgdGltZWQgb3V0CisgICAgICAgIC8vIGNvbm5lY3Rpb25zCisgICAgICAgIHByaXZhdGUgbG9uZyBsYXN0VGltZVBydW5lZDsKKworICAgICAgICAvLyBmbGFnIHRvIGluZGljYXRlIHdoZXRoZXIgdGhlcmUgaXMgYSBkZWRpY2F0ZWQgY29ubmVjdGlvbiBmb3IKKyAgICAgICAgLy8gc3RvcmUgY29tbWFuZHMKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIHNlcGFyYXRlU3RvcmVDb25uZWN0aW9uOworCisgICAgICAgIC8vIGNsaWVudCB0aW1lb3V0IGludGVydmFsCisgICAgICAgIHByaXZhdGUgZmluYWwgbG9uZyBjbGllbnRUaW1lb3V0SW50ZXJ2YWw7CisKKyAgICAgICAgLy8gc2VydmVyIHRpbWVvdXQgaW50ZXJ2YWwKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBsb25nIHNlcnZlclRpbWVvdXRJbnRlcnZhbDsKKworICAgICAgICAvLyBzaXplIG9mIHRoZSBjb25uZWN0aW9uIHBvb2wKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgcG9vbFNpemU7CisKKyAgICAgICAgLy8gaW50ZXJ2YWwgZm9yIGNoZWNraW5nIGZvciB0aW1lZCBvdXQgY29ubmVjdGlvbnMKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBsb25nIHBydW5pbmdJbnRlcnZhbDsKKyAgICAKKyAgICAgICAgLy8gY29ubmVjdGlvbiBwb29sIGxvZ2dlcgorICAgICAgICBwcml2YXRlIGZpbmFsIE1haWxMb2dnZXIgbG9nZ2VyOworCisJLyoKKwkgKiBUaGUgaWRsZVN0YXRlIGZpZWxkIHN1cHBvcnRzIHRoZSBJRExFIGNvbW1hbmQuCisJICogTm9ybWFsbHkgd2hlbiBleGVjdXRpbmcgYW4gSU1BUCBjb21tYW5kIHdlIGhvbGQgdGhlCisJICogc3RvcmUncyBsb2NrLgorCSAqIFdoaWxlIGV4ZWN1dGluZyB0aGUgSURMRSBjb21tYW5kIHdlIGNhbid0IGhvbGQgdGhlCisJICogbG9jayBvciBpdCB3b3VsZCBwcmV2ZW50IG90aGVyIHRocmVhZHMgZnJvbQorCSAqIGVudGVyaW5nIFN0b3JlIG1ldGhvZHMgZXZlbiBmYXIgZW5vdWdoIHRvIGNoZWNrIHdoZXRoZXIKKwkgKiBhbiBJRExFIGNvbW1hbmQgaXMgaW4gcHJvZ3Jlc3MuICBXZSBuZWVkIHRvIGNoZWNrIGJlZm9yZQorCSAqIGlzc3VpbmcgYW5vdGhlciBjb21tYW5kIHNvIHRoYXQgd2UgY2FuIGFib3J0IHRoZSBJRExFCisJICogY29tbWFuZC4KKwkgKgorCSAqIFRoZSBpZGxlU3RhdGUgZmllbGQgaXMgcHJvdGVjdGVkIGJ5IHRoZSBzdG9yZSdzIGxvY2suCisJICogVGhlIFJVTk5JTkcgc3RhdGUgaXMgdGhlIG5vcm1hbCBzdGF0ZSBhbmQgbWVhbnMgbm8gSURMRQorCSAqIGNvbW1hbmQgaXMgaW4gcHJvZ3Jlc3MuICBUaGUgSURMRSBzdGF0ZSBtZWFucyB3ZSd2ZSBpc3N1ZWQKKwkgKiBhbiBJRExFIGNvbW1hbmQgYW5kIGFyZSByZWFkaW5nIHJlc3BvbnNlcy4gIFRoZSBBQk9SVElORworCSAqIHN0YXRlIG1lYW5zIHdlJ3ZlIHNlbnQgdGhlIERPTkUgY29udGludWF0aW9uIGNvbW1hbmQgYW5kCisJICogYXJlIHdhaXRpbmcgZm9yIHRoZSB0aHJlYWQgcnVubmluZyB0aGUgSURMRSBjb21tYW5kIHRvCisJICogYnJlYWsgb3V0IG9mIGl0cyByZWFkIGxvb3AuCisJICoKKwkgKiBXaGVuIGFuIElETEUgY29tbWFuZCBpcyBpbiBwcm9ncmVzcywgdGhlIHRocmVhZCBjYWxsaW5nCisJICogdGhlIGlkbGUgbWV0aG9kIHdpbGwgYmUgcmVhZGluZyBmcm9tIHRoZSBJTUFQIGNvbm5lY3Rpb24KKwkgKiB3aGlsZSBub3QgaG9sZGluZyB0aGUgc3RvcmUncyBsb2NrLgorCSAqIEl0J3Mgb2J2aW91c2x5IGNyaXRpY2FsIHRoYXQgbm8gb3RoZXIgdGhyZWFkIHRyeSB0byBzZW5kIGEKKwkgKiBjb21tYW5kIG9yIHJlYWQgZnJvbSB0aGUgY29ubmVjdGlvbiB3aGlsZSBpbiB0aGlzIHN0YXRlLgorCSAqIEhvd2V2ZXIsIG90aGVyIHRocmVhZHMgY2FuIHNlbmQgdGhlIERPTkUgY29udGludWF0aW9uCisJICogY29tbWFuZCB0aGF0IHdpbGwgY2F1c2UgdGhlIHNlcnZlciB0byBicmVhayBvdXQgb2YgdGhlIElETEUKKwkgKiBsb29wIGFuZCBzZW5kIHRoZSBlbmRpbmcgdGFnIHJlc3BvbnNlIHRvIHRoZSBJRExFIGNvbW1hbmQuCisJICogVGhlIHRocmVhZCBpbiB0aGUgaWRsZSBtZXRob2QgdGhhdCdzIHJlYWRpbmcgdGhlIHJlc3BvbnNlcworCSAqIGZyb20gdGhlIElETEUgY29tbWFuZCB3aWxsIHNlZSB0aGlzIGVuZGluZyByZXNwb25zZSBhbmQKKwkgKiBjb21wbGV0ZSB0aGUgaWRsZSBtZXRob2QsIHNldHRpbmcgdGhlIGlkbGVTdGF0ZSBmaWVsZCBiYWNrCisJICogdG8gUlVOTklORywgYW5kIG5vdGlmeWluZyBhbnkgdGhyZWFkcyB3YWl0aW5nIHRvIHVzZSB0aGUKKwkgKiBjb25uZWN0aW9uLgorCSAqCisJICogQWxsIHVzZXMgb2YgdGhlIElNQVAgY29ubmVjdGlvbiAoSU1BUFByb3RvY29sIG9iamVjdCkgbXVzdAorCSAqIGJlIHByZWNlZWRlZCBieSBhIGNoZWNrIHRvIG1ha2Ugc3VyZSBhbiBJRExFIGNvbW1hbmQgaXMgbm90CisJICogcnVubmluZywgYW5kIGFib3J0IHRoZSBJRExFIGNvbW1hbmQgaWYgbmVjZXNzYXJ5LiAgVGhpcyBjaGVjaworCSAqIGlzIG1hZGUgd2hpbGUgaG9sZGluZyB0aGUgY29ubmVjdGlvbiBwb29sIGxvY2suICBXaGlsZQorCSAqIHdhaXRpbmcgZm9yIHRoZSBJRExFIGNvbW1hbmQgdG8gY29tcGxldGUsIHRoZXNlIG90aGVyIHRocmVhZHMKKwkgKiB3aWxsIGdpdmUgdXAgdGhlIGNvbm5lY3Rpb24gcG9vbCBsb2NrLiAgVGhpcyBjaGVjayBpcyBkb25lIGJ5CisJICogdGhlIGdldFN0b3JlUHJvdG9jb2woKSBtZXRob2QuCisJICovCisJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFJVTk5JTkcgPSAwOwkvLyBub3QgZG9pbmcgSURMRSBjb21tYW5kCisJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IElETEUgPSAxOwkvLyBJRExFIGNvbW1hbmQgaW4gZWZmZWN0CisJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEFCT1JUSU5HID0gMjsJLy8gSURMRSBjb21tYW5kIGFib3J0aW5nCisJcHJpdmF0ZSBpbnQgaWRsZVN0YXRlID0gUlVOTklORzsKKwlwcml2YXRlIElNQVBQcm90b2NvbCBpZGxlUHJvdG9jb2w7CS8vIHByb3RvY29sIG9iamVjdCB3aGVuIElETEUKKworCUNvbm5lY3Rpb25Qb29sKFN0cmluZyBuYW1lLCBNYWlsTG9nZ2VyIHBsb2dnZXIsIFNlc3Npb24gc2Vzc2lvbikgeworCSAgICBsYXN0VGltZVBydW5lZCA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworCSAgICBQcm9wZXJ0aWVzIHByb3BzID0gc2Vzc2lvbi5nZXRQcm9wZXJ0aWVzKCk7CisKKwkgICAgYm9vbGVhbiBkZWJ1ZyA9IFByb3BVdGlsLmdldEJvb2xlYW5Qcm9wZXJ0eShwcm9wcywKKwkJIm1haWwuIiArIG5hbWUgKyAiLmNvbm5lY3Rpb25wb29sLmRlYnVnIiwgZmFsc2UpOworCSAgICBsb2dnZXIgPSBwbG9nZ2VyLmdldFN1YkxvZ2dlcigiY29ubmVjdGlvbnBvb2wiLAorCQkJCQkgICAgIkRFQlVHIElNQVAgQ1AiLCBkZWJ1Zyk7CisKKwkgICAgLy8gY2hlY2sgaWYgdGhlIGRlZmF1bHQgY29ubmVjdGlvbiBwb29sIHNpemUgaXMgb3ZlcnJpZGRlbgorCSAgICBpbnQgc2l6ZSA9IFByb3BVdGlsLmdldEludFByb3BlcnR5KHByb3BzLAorCQkibWFpbC4iICsgbmFtZSArICIuY29ubmVjdGlvbnBvb2xzaXplIiwgLTEpOworCSAgICBpZiAoc2l6ZSA+IDApIHsKKwkJcG9vbFNpemUgPSBzaXplOworCQlpZiAobG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuQ09ORklHKSkKKwkJICAgIGxvZ2dlci5jb25maWcoIm1haWwuaW1hcC5jb25uZWN0aW9ucG9vbHNpemU6ICIgKyBwb29sU2l6ZSk7CisJICAgIH0gZWxzZQorCQlwb29sU2l6ZSA9IDE7CisKKwkgICAgLy8gY2hlY2sgaWYgdGhlIGRlZmF1bHQgY2xpZW50LXNpZGUgdGltZW91dCB2YWx1ZSBpcyBvdmVycmlkZGVuCisJICAgIGludCBjb25uZWN0aW9uUG9vbFRpbWVvdXQgPSBQcm9wVXRpbC5nZXRJbnRQcm9wZXJ0eShwcm9wcywKKwkJIm1haWwuIiArIG5hbWUgKyAiLmNvbm5lY3Rpb25wb29sdGltZW91dCIsIC0xKTsKKwkgICAgaWYgKGNvbm5lY3Rpb25Qb29sVGltZW91dCA+IDApIHsKKwkJY2xpZW50VGltZW91dEludGVydmFsID0gY29ubmVjdGlvblBvb2xUaW1lb3V0OworCQlpZiAobG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuQ09ORklHKSkKKwkJICAgIGxvZ2dlci5jb25maWcoIm1haWwuaW1hcC5jb25uZWN0aW9ucG9vbHRpbWVvdXQ6ICIgKworCQkJY2xpZW50VGltZW91dEludGVydmFsKTsKKwkgICAgfSBlbHNlIAorCQljbGllbnRUaW1lb3V0SW50ZXJ2YWwgPSA0NSAqIDEwMDA7CS8vIDQ1IHNlY29uZHMKKworCSAgICAvLyBjaGVjayBpZiB0aGUgZGVmYXVsdCBzZXJ2ZXItc2lkZSB0aW1lb3V0IHZhbHVlIGlzIG92ZXJyaWRkZW4KKwkgICAgaW50IHNlcnZlclRpbWVvdXQgPSBQcm9wVXRpbC5nZXRJbnRQcm9wZXJ0eShwcm9wcywKKwkJIm1haWwuIiArIG5hbWUgKyAiLnNlcnZlcnRpbWVvdXQiLCAtMSk7CisJICAgIGlmIChzZXJ2ZXJUaW1lb3V0ID4gMCkgeworCQlzZXJ2ZXJUaW1lb3V0SW50ZXJ2YWwgPSBzZXJ2ZXJUaW1lb3V0OworCQlpZiAobG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuQ09ORklHKSkKKwkJICAgIGxvZ2dlci5jb25maWcoIm1haWwuaW1hcC5zZXJ2ZXJ0aW1lb3V0OiAiICsKKwkJCXNlcnZlclRpbWVvdXRJbnRlcnZhbCk7CisJICAgIH0gIGVsc2UKKwkJc2VydmVyVGltZW91dEludGVydmFsID0gMzAgKiA2MCAqIDEwMDA7CS8vIDMwIG1pbnV0ZXMKKworCSAgICAvLyBjaGVjayBpZiB0aGUgZGVmYXVsdCBzZXJ2ZXItc2lkZSB0aW1lb3V0IHZhbHVlIGlzIG92ZXJyaWRkZW4KKwkgICAgaW50IHBydW5pbmcgPSBQcm9wVXRpbC5nZXRJbnRQcm9wZXJ0eShwcm9wcywKKwkJIm1haWwuIiArIG5hbWUgKyAiLnBydW5pbmdpbnRlcnZhbCIsIC0xKTsKKwkgICAgaWYgKHBydW5pbmcgPiAwKSB7CisJCXBydW5pbmdJbnRlcnZhbCA9IHBydW5pbmc7CisJCWlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5DT05GSUcpKQorCQkgICAgbG9nZ2VyLmNvbmZpZygibWFpbC5pbWFwLnBydW5pbmdpbnRlcnZhbDogIiArCisJCQlwcnVuaW5nSW50ZXJ2YWwpOworCSAgICB9ICBlbHNlCisJCXBydW5pbmdJbnRlcnZhbCA9IDYwICogMTAwMDsJCS8vIDEgbWludXRlCisgICAgIAorCSAgICAvLyBjaGVjayB0byBzZWUgaWYgd2Ugc2hvdWxkIHVzZSBhIHNlcGFyYXRlIChpLmUuIGRlZGljYXRlZCkKKwkgICAgLy8gc3RvcmUgY29ubmVjdGlvbgorCSAgICBzZXBhcmF0ZVN0b3JlQ29ubmVjdGlvbiA9CisJCVByb3BVdGlsLmdldEJvb2xlYW5Qcm9wZXJ0eShwcm9wcywKKwkJICAgICJtYWlsLiIgKyBuYW1lICsgIi5zZXBhcmF0ZXN0b3JlY29ubmVjdGlvbiIsIGZhbHNlKTsKKwkgICAgaWYgKHNlcGFyYXRlU3RvcmVDb25uZWN0aW9uKQorCQlsb2dnZXIuY29uZmlnKCJkZWRpY2F0ZSBhIHN0b3JlIGNvbm5lY3Rpb24iKTsKKworCX0KKyAgICB9CisgCisgICAgcHJpdmF0ZSBmaW5hbCBDb25uZWN0aW9uUG9vbCBwb29sOworCisgICAgLyoqCisgICAgICogQSBzcGVjaWFsIHJlc3BvbnNlIGhhbmRsZXIgZm9yIGNvbm5lY3Rpb25zIHRoYXQgYXJlIGJlaW5nIHVzZWQKKyAgICAgKiB0byBwZXJmb3JtIG9wZXJhdGlvbnMgb24gYmVoYWxmIG9mIGFuIG9iamVjdCBvdGhlciB0aGFuIHRoZSBTdG9yZS4KKyAgICAgKiBJdCBET0VTTidUIGNhdXNlIHRoZSBTdG9yZSB0byBiZSBjbGVhbmVkIHVwIGlmIGEgQllFIGlzIHNlZW4uCisgICAgICogVGhlIEJZRSBtYXkgYmUgcmVhbCBvciBzeW50aGV0aWMgYW5kIGluIGVpdGhlciBjYXNlIGp1c3QgaW5kaWNhdGVzCisgICAgICogdGhhdCB0aGUgY29ubmVjdGlvbiBpcyBkZWFkLgorICAgICAqLworICAgIHByaXZhdGUgUmVzcG9uc2VIYW5kbGVyIG5vblN0b3JlUmVzcG9uc2VIYW5kbGVyID0gbmV3IFJlc3BvbnNlSGFuZGxlcigpIHsKKwlAT3ZlcnJpZGUKKwlwdWJsaWMgdm9pZCBoYW5kbGVSZXNwb25zZShSZXNwb25zZSByKSB7CisJICAgIC8vIEFueSBvZiB0aGVzZSByZXNwb25zZXMgbWF5IGhhdmUgYSByZXNwb25zZSBjb2RlLgorCSAgICBpZiAoci5pc09LKCkgfHwgci5pc05PKCkgfHwgci5pc0JBRCgpIHx8IHIuaXNCWUUoKSkKKwkJaGFuZGxlUmVzcG9uc2VDb2RlKHIpOworCSAgICBpZiAoci5pc0JZRSgpKQorCQlsb2dnZXIuZmluZSgiSU1BUFN0b3JlIG5vbi1zdG9yZSBjb25uZWN0aW9uIGRlYWQiKTsKKwl9CisgICAgfTsKKyAKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvciB0aGF0IHRha2VzIGEgU2Vzc2lvbiBvYmplY3QgYW5kIGEgVVJMTmFtZSB0aGF0CisgICAgICogcmVwcmVzZW50cyBhIHNwZWNpZmljIElNQVAgc2VydmVyLgorICAgICAqCisgICAgICogQHBhcmFtCXNlc3Npb24JdGhlIFNlc3Npb24KKyAgICAgKiBAcGFyYW0JdXJsCXRoZSBVUkxOYW1lIG9mIHRoaXMgc3RvcmUKKyAgICAgKi8KKyAgICBwdWJsaWMgSU1BUFN0b3JlKFNlc3Npb24gc2Vzc2lvbiwgVVJMTmFtZSB1cmwpIHsKKwl0aGlzKHNlc3Npb24sIHVybCwgImltYXAiLCBmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IgdXNlZCBieSB0aGlzIGNsYXNzIGFuZCBieSBJTUFQU1NMU3RvcmUgc3ViY2xhc3MuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jc2Vzc2lvbgl0aGUgU2Vzc2lvbgorICAgICAqIEBwYXJhbQl1cmwJdGhlIFVSTE5hbWUgb2YgdGhpcyBzdG9yZQorICAgICAqIEBwYXJhbQluYW1lCXRoZSBwcm90b2NvbCBuYW1lIGZvciB0aGlzIHN0b3JlCisgICAgICogQHBhcmFtCWlzU1NMCXVzZSBTU0w/CisgICAgICovCisgICAgcHJvdGVjdGVkIElNQVBTdG9yZShTZXNzaW9uIHNlc3Npb24sIFVSTE5hbWUgdXJsLAorCQkJCVN0cmluZyBuYW1lLCBib29sZWFuIGlzU1NMKSB7CisJc3VwZXIoc2Vzc2lvbiwgdXJsKTsgLy8gY2FsbCBzdXBlciBjb25zdHJ1Y3RvcgorCVByb3BlcnRpZXMgcHJvcHMgPSBzZXNzaW9uLmdldFByb3BlcnRpZXMoKTsKKworCWlmICh1cmwgIT0gbnVsbCkKKwkgICAgbmFtZSA9IHVybC5nZXRQcm90b2NvbCgpOworCXRoaXMubmFtZSA9IG5hbWU7CisJaWYgKCFpc1NTTCkKKwkgICAgaXNTU0wgPSBQcm9wVXRpbC5nZXRCb29sZWFuUHJvcGVydHkocHJvcHMsCisJCQkJIm1haWwuIiArIG5hbWUgKyAiLnNzbC5lbmFibGUiLCBmYWxzZSk7CisJaWYgKGlzU1NMKQorCSAgICB0aGlzLmRlZmF1bHRQb3J0ID0gOTkzOworCWVsc2UKKwkgICAgdGhpcy5kZWZhdWx0UG9ydCA9IDE0MzsKKwl0aGlzLmlzU1NMID0gaXNTU0w7CisKKyAgICAgICAgZGVidWcgPSBzZXNzaW9uLmdldERlYnVnKCk7CisJZGVidWd1c2VybmFtZSA9IFByb3BVdGlsLmdldEJvb2xlYW5Qcm9wZXJ0eShwcm9wcywKKwkJCSJtYWlsLmRlYnVnLmF1dGgudXNlcm5hbWUiLCB0cnVlKTsKKwlkZWJ1Z3Bhc3N3b3JkID0gUHJvcFV0aWwuZ2V0Qm9vbGVhblByb3BlcnR5KHByb3BzLAorCQkJIm1haWwuZGVidWcuYXV0aC5wYXNzd29yZCIsIGZhbHNlKTsKKwlsb2dnZXIgPSBuZXcgTWFpbExvZ2dlcih0aGlzLmdldENsYXNzKCksCisJCQkiREVCVUcgIiArIG5hbWUudG9VcHBlckNhc2UoTG9jYWxlLkVOR0xJU0gpLAorCQkJc2Vzc2lvbi5nZXREZWJ1ZygpLCBzZXNzaW9uLmdldERlYnVnT3V0KCkpOworCisJYm9vbGVhbiBwYXJ0aWFsRmV0Y2ggPSBQcm9wVXRpbC5nZXRCb29sZWFuUHJvcGVydHkocHJvcHMsCisJICAgICJtYWlsLiIgKyBuYW1lICsgIi5wYXJ0aWFsZmV0Y2giLCB0cnVlKTsKKwlpZiAoIXBhcnRpYWxGZXRjaCkgeworCSAgICBibGtzaXplID0gLTE7CisJICAgIGxvZ2dlci5jb25maWcoIm1haWwuaW1hcC5wYXJ0aWFsZmV0Y2g6IGZhbHNlIik7CisJfSBlbHNlIHsKKwkgICAgYmxrc2l6ZSA9IFByb3BVdGlsLmdldEludFByb3BlcnR5KHByb3BzLAorCQkibWFpbC4iICsgbmFtZSArIi5mZXRjaHNpemUiLCAxMDI0ICogMTYpOworCSAgICBpZiAobG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuQ09ORklHKSkKKwkJbG9nZ2VyLmNvbmZpZygibWFpbC5pbWFwLmZldGNoc2l6ZTogIiArIGJsa3NpemUpOworCX0KKworCWlnbm9yZVNpemUgPSBQcm9wVXRpbC5nZXRCb29sZWFuUHJvcGVydHkocHJvcHMsCisJICAgICJtYWlsLiIgKyBuYW1lICsiLmlnbm9yZWJvZHlzdHJ1Y3R1cmVzaXplIiwgZmFsc2UpOworCWlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5DT05GSUcpKQorCSAgICBsb2dnZXIuY29uZmlnKCJtYWlsLmltYXAuaWdub3JlYm9keXN0cnVjdHVyZXNpemU6ICIgKyBpZ25vcmVTaXplKTsKKworCXN0YXR1c0NhY2hlVGltZW91dCA9IFByb3BVdGlsLmdldEludFByb3BlcnR5KHByb3BzLAorCSAgICAibWFpbC4iICsgbmFtZSArICIuc3RhdHVzY2FjaGV0aW1lb3V0IiwgMTAwMCk7CisJaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkNPTkZJRykpCisJICAgIGxvZ2dlci5jb25maWcoIm1haWwuaW1hcC5zdGF0dXNjYWNoZXRpbWVvdXQ6ICIgKworCQkJCQkJc3RhdHVzQ2FjaGVUaW1lb3V0KTsKKworCWFwcGVuZEJ1ZmZlclNpemUgPSBQcm9wVXRpbC5nZXRJbnRQcm9wZXJ0eShwcm9wcywKKwkgICAgIm1haWwuIiArIG5hbWUgKyAiLmFwcGVuZGJ1ZmZlcnNpemUiLCAtMSk7CisJaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkNPTkZJRykpCisJICAgIGxvZ2dlci5jb25maWcoIm1haWwuaW1hcC5hcHBlbmRidWZmZXJzaXplOiAiICsgYXBwZW5kQnVmZmVyU2l6ZSk7CisKKwltaW5JZGxlVGltZSA9IFByb3BVdGlsLmdldEludFByb3BlcnR5KHByb3BzLAorCSAgICAibWFpbC4iICsgbmFtZSArICIubWluaWRsZXRpbWUiLCAxMCk7CisJaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkNPTkZJRykpCisJICAgIGxvZ2dlci5jb25maWcoIm1haWwuaW1hcC5taW5pZGxldGltZTogIiArIG1pbklkbGVUaW1lKTsKKworCS8vIGNoZWNrIGlmIHdlIHNob3VsZCBkbyBhIFBST1hZQVVUSCBsb2dpbgorCVN0cmluZyBzID0gc2Vzc2lvbi5nZXRQcm9wZXJ0eSgibWFpbC4iICsgbmFtZSArICIucHJveHlhdXRoLnVzZXIiKTsKKwlpZiAocyAhPSBudWxsKSB7CisJICAgIHByb3h5QXV0aFVzZXIgPSBzOworCSAgICBpZiAobG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuQ09ORklHKSkKKwkJbG9nZ2VyLmNvbmZpZygibWFpbC5pbWFwLnByb3h5YXV0aC51c2VyOiAiICsgcHJveHlBdXRoVXNlcik7CisJfQorCisJLy8gY2hlY2sgaWYgU1RBUlRUTFMgaXMgZW5hYmxlZAorCWVuYWJsZVN0YXJ0VExTID0gUHJvcFV0aWwuZ2V0Qm9vbGVhblByb3BlcnR5KHByb3BzLAorCSAgICAibWFpbC4iICsgbmFtZSArICIuc3RhcnR0bHMuZW5hYmxlIiwgZmFsc2UpOworCWlmIChlbmFibGVTdGFydFRMUykKKwkgICAgbG9nZ2VyLmNvbmZpZygiZW5hYmxlIFNUQVJUVExTIik7CisKKwkvLyBjaGVjayBpZiBTVEFSVFRMUyBpcyByZXF1aXJlZAorCXJlcXVpcmVTdGFydFRMUyA9IFByb3BVdGlsLmdldEJvb2xlYW5Qcm9wZXJ0eShwcm9wcywKKwkgICAgIm1haWwuIiArIG5hbWUgKyAiLnN0YXJ0dGxzLnJlcXVpcmVkIiwgZmFsc2UpOworCWlmIChyZXF1aXJlU3RhcnRUTFMpCisJICAgIGxvZ2dlci5jb25maWcoInJlcXVpcmUgU1RBUlRUTFMiKTsKKworCS8vIGNoZWNrIGlmIFNBU0wgaXMgZW5hYmxlZAorCWVuYWJsZVNBU0wgPSBQcm9wVXRpbC5nZXRCb29sZWFuUHJvcGVydHkocHJvcHMsCisJICAgICJtYWlsLiIgKyBuYW1lICsgIi5zYXNsLmVuYWJsZSIsIGZhbHNlKTsKKwlpZiAoZW5hYmxlU0FTTCkKKwkgICAgbG9nZ2VyLmNvbmZpZygiZW5hYmxlIFNBU0wiKTsKKworCS8vIGNoZWNrIGlmIFNBU0wgbWVjaGFuaXNtcyBhcmUgc3BlY2lmaWVkCisJaWYgKGVuYWJsZVNBU0wpIHsKKwkgICAgcyA9IHNlc3Npb24uZ2V0UHJvcGVydHkoIm1haWwuIiArIG5hbWUgKyAiLnNhc2wubWVjaGFuaXNtcyIpOworCSAgICBpZiAocyAhPSBudWxsICYmIHMubGVuZ3RoKCkgPiAwKSB7CisJCWlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5DT05GSUcpKQorCQkgICAgbG9nZ2VyLmNvbmZpZygiU0FTTCBtZWNoYW5pc21zIGFsbG93ZWQ6ICIgKyBzKTsKKwkJTGlzdDxTdHJpbmc+IHYgPSBuZXcgQXJyYXlMaXN0PD4oNSk7CisJCVN0cmluZ1Rva2VuaXplciBzdCA9IG5ldyBTdHJpbmdUb2tlbml6ZXIocywgIiAsIik7CisJCXdoaWxlIChzdC5oYXNNb3JlVG9rZW5zKCkpIHsKKwkJICAgIFN0cmluZyBtID0gc3QubmV4dFRva2VuKCk7CisJCSAgICBpZiAobS5sZW5ndGgoKSA+IDApCisJCQl2LmFkZChtKTsKKwkJfQorCQlzYXNsTWVjaGFuaXNtcyA9IG5ldyBTdHJpbmdbdi5zaXplKCldOworCQl2LnRvQXJyYXkoc2FzbE1lY2hhbmlzbXMpOworCSAgICB9CisJfQorCisJLy8gY2hlY2sgaWYgYW4gYXV0aG9yaXphdGlvbiBJRCBoYXMgYmVlbiBzcGVjaWZpZWQKKwlzID0gc2Vzc2lvbi5nZXRQcm9wZXJ0eSgibWFpbC4iICsgbmFtZSArICIuc2FzbC5hdXRob3JpemF0aW9uaWQiKTsKKwlpZiAocyAhPSBudWxsKSB7CisJICAgIGF1dGhvcml6YXRpb25JRCA9IHM7CisJICAgIGxvZ2dlci5sb2coTGV2ZWwuQ09ORklHLCAibWFpbC5pbWFwLnNhc2wuYXV0aG9yaXphdGlvbmlkOiB7MH0iLAorCQkJCQkJYXV0aG9yaXphdGlvbklEKTsKKwl9CisKKwkvLyBjaGVjayBpZiBhIFNBU0wgcmVhbG0gaGFzIGJlZW4gc3BlY2lmaWVkCisJcyA9IHNlc3Npb24uZ2V0UHJvcGVydHkoIm1haWwuIiArIG5hbWUgKyAiLnNhc2wucmVhbG0iKTsKKwlpZiAocyAhPSBudWxsKSB7CisJICAgIHNhc2xSZWFsbSA9IHM7CisJICAgIGxvZ2dlci5sb2coTGV2ZWwuQ09ORklHLCAibWFpbC5pbWFwLnNhc2wucmVhbG06IHswfSIsIHNhc2xSZWFsbSk7CisJfQorCisJLy8gY2hlY2sgaWYgZm9yY2VQYXNzd29yZFJlZnJlc2ggaXMgZW5hYmxlZAorCWZvcmNlUGFzc3dvcmRSZWZyZXNoID0gUHJvcFV0aWwuZ2V0Qm9vbGVhblByb3BlcnR5KHByb3BzLAorCSAgICAibWFpbC4iICsgbmFtZSArICIuZm9yY2VwYXNzd29yZHJlZnJlc2giLCBmYWxzZSk7CisJaWYgKGZvcmNlUGFzc3dvcmRSZWZyZXNoKQorCSAgICBsb2dnZXIuY29uZmlnKCJlbmFibGUgZm9yY2VQYXNzd29yZFJlZnJlc2giKTsKKworCS8vIGNoZWNrIGlmIGVuYWJsZWltYXBldmVudHMgaXMgZW5hYmxlZAorCWVuYWJsZVJlc3BvbnNlRXZlbnRzID0gUHJvcFV0aWwuZ2V0Qm9vbGVhblByb3BlcnR5KHByb3BzLAorCSAgICAibWFpbC4iICsgbmFtZSArICIuZW5hYmxlcmVzcG9uc2VldmVudHMiLCBmYWxzZSk7CisJaWYgKGVuYWJsZVJlc3BvbnNlRXZlbnRzKQorCSAgICBsb2dnZXIuY29uZmlnKCJlbmFibGUgSU1BUCByZXNwb25zZSBldmVudHMiKTsKKworCS8vIGNoZWNrIGlmIGVuYWJsZXJlc3BvbnNlZXZlbnRzIGlzIGVuYWJsZWQKKwllbmFibGVJbWFwRXZlbnRzID0gUHJvcFV0aWwuZ2V0Qm9vbGVhblByb3BlcnR5KHByb3BzLAorCSAgICAibWFpbC4iICsgbmFtZSArICIuZW5hYmxlaW1hcGV2ZW50cyIsIGZhbHNlKTsKKwlpZiAoZW5hYmxlSW1hcEV2ZW50cykKKwkgICAgbG9nZ2VyLmNvbmZpZygiZW5hYmxlIElNQVAgSURMRSBldmVudHMiKTsKKworCS8vIGNoZWNrIGlmIG1lc3NhZ2UgY2FjaGUgZGVidWdnaW5nIHNldAorCW1lc3NhZ2VDYWNoZURlYnVnID0gUHJvcFV0aWwuZ2V0Qm9vbGVhblByb3BlcnR5KHByb3BzLAorCSAgICAibWFpbC4iICsgbmFtZSArICIubWVzc2FnZWNhY2hlLmRlYnVnIiwgZmFsc2UpOworCisJZ3VpZCA9IHNlc3Npb24uZ2V0UHJvcGVydHkoIm1haWwuIiArIG5hbWUgKyAiLnlhaG9vLmd1aWQiKTsKKwlpZiAoZ3VpZCAhPSBudWxsKQorCSAgICBsb2dnZXIubG9nKExldmVsLkNPTkZJRywgIm1haWwuaW1hcC55YWhvby5ndWlkOiB7MH0iLCBndWlkKTsKKworCS8vIGNoZWNrIGlmIHRocm93c2VhcmNoZXhjZXB0aW9uIGlzIGVuYWJsZWQKKwl0aHJvd1NlYXJjaEV4Y2VwdGlvbiA9IFByb3BVdGlsLmdldEJvb2xlYW5Qcm9wZXJ0eShwcm9wcywKKwkgICAgIm1haWwuIiArIG5hbWUgKyAiLnRocm93c2VhcmNoZXhjZXB0aW9uIiwgZmFsc2UpOworCWlmICh0aHJvd1NlYXJjaEV4Y2VwdGlvbikKKwkgICAgbG9nZ2VyLmNvbmZpZygidGhyb3cgU2VhcmNoRXhjZXB0aW9uIik7CisKKwkvLyBjaGVjayBpZiBwZWVrIGlzIHNldAorCXBlZWsgPSBQcm9wVXRpbC5nZXRCb29sZWFuUHJvcGVydHkocHJvcHMsCisJICAgICJtYWlsLiIgKyBuYW1lICsgIi5wZWVrIiwgZmFsc2UpOworCWlmIChwZWVrKQorCSAgICBsb2dnZXIuY29uZmlnKCJwZWVrIik7CisKKwkvLyBjaGVjayBpZiBjbG9zZUZvbGRlcnNPblN0b3JlRmFpbHVyZSBpcyBzZXQKKwljbG9zZUZvbGRlcnNPblN0b3JlRmFpbHVyZSA9IFByb3BVdGlsLmdldEJvb2xlYW5Qcm9wZXJ0eShwcm9wcywKKwkgICAgIm1haWwuIiArIG5hbWUgKyAiLmNsb3NlZm9sZGVyc29uc3RvcmVmYWlsdXJlIiwgdHJ1ZSk7CisJaWYgKGNsb3NlRm9sZGVyc09uU3RvcmVGYWlsdXJlKQorCSAgICBsb2dnZXIuY29uZmlnKCJjbG9zZUZvbGRlcnNPblN0b3JlRmFpbHVyZSIpOworCisJLy8gY2hlY2sgaWYgQ09NUFJFU1MgaXMgZW5hYmxlZAorCWVuYWJsZUNvbXByZXNzID0gUHJvcFV0aWwuZ2V0Qm9vbGVhblByb3BlcnR5KHByb3BzLAorCSAgICAibWFpbC4iICsgbmFtZSArICIuY29tcHJlc3MuZW5hYmxlIiwgZmFsc2UpOworCWlmIChlbmFibGVDb21wcmVzcykKKwkgICAgbG9nZ2VyLmNvbmZpZygiZW5hYmxlIENPTVBSRVNTIik7CisKKwkvLyBjaGVjayBpZiBmaW5hbGl6ZUNsZWFuQ2xvc2UgaXMgZW5hYmxlZAorCWZpbmFsaXplQ2xlYW5DbG9zZSA9IFByb3BVdGlsLmdldEJvb2xlYW5Qcm9wZXJ0eShwcm9wcywKKwkgICAgIm1haWwuIiArIG5hbWUgKyAiLmZpbmFsaXplY2xlYW5jbG9zZSIsIGZhbHNlKTsKKwlpZiAoZmluYWxpemVDbGVhbkNsb3NlKQorCSAgICBsb2dnZXIuY29uZmlnKCJjbG9zZSBjb25uZWN0aW9uIGNsZWFubHkgaW4gZmluYWxpemUiKTsKKworCXMgPSBzZXNzaW9uLmdldFByb3BlcnR5KCJtYWlsLiIgKyBuYW1lICsgIi5mb2xkZXIuY2xhc3MiKTsKKwlpZiAocyAhPSBudWxsKSB7CisJICAgIGxvZ2dlci5sb2coTGV2ZWwuQ09ORklHLCAiSU1BUDogZm9sZGVyIGNsYXNzOiB7MH0iLCBzKTsKKwkgICAgdHJ5IHsKKwkJQ2xhc3NMb2FkZXIgY2wgPSB0aGlzLmdldENsYXNzKCkuZ2V0Q2xhc3NMb2FkZXIoKTsKKworCQkvLyBub3cgbG9hZCB0aGUgY2xhc3MKKwkJQ2xhc3M8Pz4gZm9sZGVyQ2xhc3MgPSBudWxsOworCQl0cnkgeworCQkgICAgLy8gRmlyc3QgdHJ5IHRoZSAiYXBwbGljYXRpb24ncyIgY2xhc3MgbG9hZGVyLgorCQkgICAgLy8gVGhpcyBzaG91bGQgZXZlbnR1YWxseSBiZSByZXBsYWNlZCBieQorCQkgICAgLy8gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXRDb250ZXh0Q2xhc3NMb2FkZXIoKS4KKwkJICAgIGZvbGRlckNsYXNzID0gQ2xhc3MuZm9yTmFtZShzLCBmYWxzZSwgY2wpOworCQl9IGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGV4MSkgeworCQkgICAgLy8gVGhhdCBkaWRuJ3Qgd29yaywgbm93IHRyeSB0aGUgInN5c3RlbSIgY2xhc3MgbG9hZGVyLgorCQkgICAgLy8gKE5lZWQgYm90aCBvZiB0aGVzZSBiZWNhdXNlIEpESyAxLjEgY2xhc3MgbG9hZGVycworCQkgICAgLy8gbWF5IG5vdCBkZWxlZ2F0ZSB0byB0aGVpciBwYXJlbnQgY2xhc3MgbG9hZGVyLikKKwkJICAgIGZvbGRlckNsYXNzID0gQ2xhc3MuZm9yTmFtZShzKTsKKwkJfQorCisJCUNsYXNzPD8+W10gYyA9IHsgU3RyaW5nLmNsYXNzLCBjaGFyLmNsYXNzLCBJTUFQU3RvcmUuY2xhc3MsCisJCQkJQm9vbGVhbi5jbGFzcyB9OworCQlmb2xkZXJDb25zdHJ1Y3RvciA9IGZvbGRlckNsYXNzLmdldENvbnN0cnVjdG9yKGMpOworCQlDbGFzczw/PltdIGMyID0geyBMaXN0SW5mby5jbGFzcywgSU1BUFN0b3JlLmNsYXNzIH07CisJCWZvbGRlckNvbnN0cnVjdG9yTEkgPSBmb2xkZXJDbGFzcy5nZXRDb25zdHJ1Y3RvcihjMik7CisJICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCQlsb2dnZXIubG9nKExldmVsLkNPTkZJRywKKwkJCSJJTUFQOiBmYWlsZWQgdG8gbG9hZCBmb2xkZXIgY2xhc3MiLCBleCk7CisJICAgIH0KKwl9CisKKwlwb29sID0gbmV3IENvbm5lY3Rpb25Qb29sKG5hbWUsIGxvZ2dlciwgc2Vzc2lvbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW1wbGVtZW50YXRpb24gb2YgcHJvdG9jb2xDb25uZWN0KCkuICBXaWxsIGNyZWF0ZSBhIGNvbm5lY3Rpb24KKyAgICAgKiB0byB0aGUgc2VydmVyIGFuZCBhdXRoZW50aWNhdGUgdGhlIHVzZXIgdXNpbmcgdGhlIG1lY2hhbmlzbXMKKyAgICAgKiBzcGVjaWZpZWQgYnkgdmFyaW91cyBwcm9wZXJ0aWVzLiA8cD4KKyAgICAgKgorICAgICAqIFRoZSA8Y29kZT5ob3N0PC9jb2RlPiwgPGNvZGU+dXNlcjwvY29kZT4sIGFuZCA8Y29kZT5wYXNzd29yZDwvY29kZT4KKyAgICAgKiBwYXJhbWV0ZXJzIG11c3QgYWxsIGJlIG5vbi1udWxsLiAgSWYgdGhlIGF1dGhlbnRpY2F0aW9uIG1lY2hhbmlzbQorICAgICAqIGJlaW5nIHVzZWQgZG9lcyBub3QgcmVxdWlyZSBhIHBhc3N3b3JkLCBhbiBlbXB0eSBzdHJpbmcgb3Igb3RoZXIKKyAgICAgKiBzdWl0YWJsZSBkdW1teSBwYXNzd29yZCBzaG91bGQgYmUgdXNlZC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgc3luY2hyb25pemVkIGJvb2xlYW4gCisgICAgcHJvdG9jb2xDb25uZWN0KFN0cmluZyBob3N0LCBpbnQgcHBvcnQsIFN0cmluZyB1c2VyLCBTdHJpbmcgcGFzc3dvcmQpCisJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworICAgICAgICAKKyAgICAgICAgSU1BUFByb3RvY29sIHByb3RvY29sID0gbnVsbDsKKworCS8vIGNoZWNrIGZvciBub24tbnVsbCB2YWx1ZXMgb2YgaG9zdCwgcGFzc3dvcmQsIHVzZXIKKwlpZiAoaG9zdCA9PSBudWxsIHx8IHBhc3N3b3JkID09IG51bGwgfHwgdXNlciA9PSBudWxsKSB7CisJICAgIGlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FKSkKKwkJbG9nZ2VyLmZpbmUoInByb3RvY29sQ29ubmVjdCByZXR1cm5pbmcgZmFsc2UiICsKKwkJCQkiLCBob3N0PSIgKyBob3N0ICsKKwkJCQkiLCB1c2VyPSIgKyB0cmFjZVVzZXIodXNlcikgKworCQkJCSIsIHBhc3N3b3JkPSIgKyB0cmFjZVBhc3N3b3JkKHBhc3N3b3JkKSk7CisJICAgIHJldHVybiBmYWxzZTsKKwl9CisKKwkvLyBzZXQgdGhlIHBvcnQgY29ycmVjdGx5CisJaWYgKHBwb3J0ICE9IC0xKSB7CisJICAgIHBvcnQgPSBwcG9ydDsKKwl9IGVsc2UgeworCSAgICBwb3J0ID0gUHJvcFV0aWwuZ2V0SW50UHJvcGVydHkoc2Vzc2lvbi5nZXRQcm9wZXJ0aWVzKCksCisJCQkJCSJtYWlsLiIgKyBuYW1lICsgIi5wb3J0IiwgcG9ydCk7CisJfSAKKwkKKwkvLyB1c2UgdGhlIGRlZmF1bHQgaWYgbmVlZGVkCisJaWYgKHBvcnQgPT0gLTEpIHsKKwkgICAgcG9ydCA9IGRlZmF1bHRQb3J0OworCX0KKwkKKwl0cnkgeworICAgICAgICAgICAgYm9vbGVhbiBwb29sRW1wdHk7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKHBvb2wpIHsKKyAgICAgICAgICAgICAgICBwb29sRW1wdHkgPSBwb29sLmF1dGhlbnRpY2F0ZWRDb25uZWN0aW9ucy5pc0VtcHR5KCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChwb29sRW1wdHkpIHsKKwkJaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkUpKQorCQkgICAgbG9nZ2VyLmZpbmUoInRyeWluZyB0byBjb25uZWN0IHRvIGhvc3QgXCIiICsgaG9zdCArCisJCQkJIlwiLCBwb3J0ICIgKyBwb3J0ICsgIiwgaXNTU0wgIiArIGlzU1NMKTsKKyAgICAgICAgICAgICAgICBwcm90b2NvbCA9IG5ld0lNQVBQcm90b2NvbChob3N0LCBwb3J0KTsKKwkJaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkUpKQorCQkgICAgbG9nZ2VyLmZpbmUoInByb3RvY29sQ29ubmVjdCBsb2dpbiIgKworCQkJCSIsIGhvc3Q9IiArIGhvc3QgKworCQkJCSIsIHVzZXI9IiArIHRyYWNlVXNlcih1c2VyKSArCisJCQkJIiwgcGFzc3dvcmQ9IiArIHRyYWNlUGFzc3dvcmQocGFzc3dvcmQpKTsKKwkJcHJvdG9jb2wuYWRkUmVzcG9uc2VIYW5kbGVyKG5vblN0b3JlUmVzcG9uc2VIYW5kbGVyKTsKKwkgICAgICAgIGxvZ2luKHByb3RvY29sLCB1c2VyLCBwYXNzd29yZCk7CisJCXByb3RvY29sLnJlbW92ZVJlc3BvbnNlSGFuZGxlcihub25TdG9yZVJlc3BvbnNlSGFuZGxlcik7CisJICAgICAgICBwcm90b2NvbC5hZGRSZXNwb25zZUhhbmRsZXIodGhpcyk7CisKKwkJdXNpbmdTU0wgPSBwcm90b2NvbC5pc1NTTCgpOwkvLyBpbiBjYXNlIGFueW9uZSBhc2tzCisKKwkgICAgICAgIHRoaXMuaG9zdCA9IGhvc3Q7CisJICAgICAgICB0aGlzLnVzZXIgPSB1c2VyOworCSAgICAgICAgdGhpcy5wYXNzd29yZCA9IHBhc3N3b3JkOworCisgICAgICAgICAgICAgICAgc3luY2hyb25pemVkIChwb29sKSB7CisgICAgICAgICAgICAgICAgICAgIHBvb2wuYXV0aGVudGljYXRlZENvbm5lY3Rpb25zLmFkZEVsZW1lbnQocHJvdG9jb2wpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKwl9IGNhdGNoIChJTUFQUmVmZXJyYWxFeGNlcHRpb24gZXgpIHsKKwkgICAgLy8gbG9naW4gZmFpbHVyZSBkdWUgdG8gSU1BUCBSRUZFUlJBTCwgY2xvc2UgY29ubmVjdGlvbiB0byBzZXJ2ZXIKKwkgICAgaWYgKHByb3RvY29sICE9IG51bGwpCisJCXByb3RvY29sLmRpc2Nvbm5lY3QoKTsKKwkgICAgcHJvdG9jb2wgPSBudWxsOworCSAgICB0aHJvdyBuZXcgUmVmZXJyYWxFeGNlcHRpb24oZXguZ2V0VXJsKCksIGV4LmdldE1lc3NhZ2UoKSk7CisJfSBjYXRjaCAoQ29tbWFuZEZhaWxlZEV4Y2VwdGlvbiBjZXgpIHsKKwkgICAgLy8gbG9naW4gZmFpbHVyZSwgY2xvc2UgY29ubmVjdGlvbiB0byBzZXJ2ZXIKKwkgICAgaWYgKHByb3RvY29sICE9IG51bGwpCisJCXByb3RvY29sLmRpc2Nvbm5lY3QoKTsKKwkgICAgcHJvdG9jb2wgPSBudWxsOworCSAgICBSZXNwb25zZSByID0gY2V4LmdldFJlc3BvbnNlKCk7CisJICAgIHRocm93IG5ldyBBdXRoZW50aWNhdGlvbkZhaWxlZEV4Y2VwdGlvbigKKwkJCQkgICAgciAhPSBudWxsID8gci5nZXRSZXN0KCkgOiBjZXguZ2V0TWVzc2FnZSgpKTsKKwl9IGNhdGNoIChQcm90b2NvbEV4Y2VwdGlvbiBwZXgpIHsgLy8gYW55IG90aGVyIGV4Y2VwdGlvbgorCSAgICAvLyBmYWlsdXJlIGluIGxvZ2luIGNvbW1hbmQsIGNsb3NlIGNvbm5lY3Rpb24gdG8gc2VydmVyCisJICAgIGlmIChwcm90b2NvbCAhPSBudWxsKQorCQlwcm90b2NvbC5kaXNjb25uZWN0KCk7CisJICAgIHByb3RvY29sID0gbnVsbDsKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbihwZXguZ2V0TWVzc2FnZSgpLCBwZXgpOworCX0gY2F0Y2ggKFNvY2tldENvbm5lY3RFeGNlcHRpb24gc2NleCkgeworCSAgICB0aHJvdyBuZXcgTWFpbENvbm5lY3RFeGNlcHRpb24oc2NleCk7CisJfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9leCkgeworCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKGlvZXguZ2V0TWVzc2FnZSgpLCBpb2V4KTsKKwl9IAorCisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhbiBJTUFQUHJvdG9jb2wgb2JqZWN0IGNvbm5lY3RlZCB0byB0aGUgaG9zdCBhbmQgcG9ydC4KKyAgICAgKiBTdWJjbGFzc2VzIG9mIElNQVBTdG9yZSBtYXkgb3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8gcmV0dXJuIGEKKyAgICAgKiBzdWJjbGFzcyBvZiBJTUFQUHJvdG9jb2wgdGhhdCBzdXBwb3J0cyBwcm9kdWN0LXNwZWNpZmljIGV4dGVuc2lvbnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0JaG9zdAl0aGUgaG9zdCBuYW1lCisgICAgICogQHBhcmFtCXBvcnQJdGhlIHBvcnQgbnVtYmVyCisgICAgICogQHJldHVybgkJdGhlIG5ldyBJTUFQUHJvdG9jb2wgb2JqZWN0CisgICAgICogQGV4Y2VwdGlvbglJT0V4Y2VwdGlvbiBmb3IgSS9PIGVycm9ycworICAgICAqIEBleGNlcHRpb24JUHJvdG9jb2xFeGNlcHRpb24gZm9yIHByb3RvY29sIGVycm9ycworICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjQuNgorICAgICAqLworICAgIHByb3RlY3RlZCBJTUFQUHJvdG9jb2wgbmV3SU1BUFByb3RvY29sKFN0cmluZyBob3N0LCBpbnQgcG9ydCkKKwkJCQl0aHJvd3MgSU9FeGNlcHRpb24sIFByb3RvY29sRXhjZXB0aW9uIHsKKwlyZXR1cm4gbmV3IElNQVBQcm90b2NvbChuYW1lLCBob3N0LCBwb3J0LCAKKwkJCQkJICAgIHNlc3Npb24uZ2V0UHJvcGVydGllcygpLAorCQkJCQkgICAgaXNTU0wsCisJCQkJCSAgICBsb2dnZXIKKwkJCQkJICAgKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgbG9naW4oSU1BUFByb3RvY29sIHAsIFN0cmluZyB1LCBTdHJpbmcgcHcpIAorCQl0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCS8vIHR1cm4gb24gVExTIGlmIGl0J3MgYmVlbiBlbmFibGVkIG9yIHJlcXVpcmVkIGFuZCBpcyBzdXBwb3J0ZWQKKwkvLyBhbmQgd2UncmUgbm90IGFscmVhZHkgdXNpbmcgU1NMCisJaWYgKChlbmFibGVTdGFydFRMUyB8fCByZXF1aXJlU3RhcnRUTFMpICYmICFwLmlzU1NMKCkpIHsKKwkgICAgaWYgKHAuaGFzQ2FwYWJpbGl0eSgiU1RBUlRUTFMiKSkgeworCQlwLnN0YXJ0VExTKCk7CisJCS8vIGlmIHN0YXJ0VExTIHN1Y2NlZWRzLCByZWZyZXNoIGNhcGFiaWxpdGllcworCQlwLmNhcGFiaWxpdHkoKTsKKwkgICAgfSBlbHNlIGlmIChyZXF1aXJlU3RhcnRUTFMpIHsKKwkJbG9nZ2VyLmZpbmUoIlNUQVJUVExTIHJlcXVpcmVkIGJ1dCBub3Qgc3VwcG9ydGVkIGJ5IHNlcnZlciIpOworCQl0aHJvdyBuZXcgUHJvdG9jb2xFeGNlcHRpb24oCisJCSAgICAiU1RBUlRUTFMgcmVxdWlyZWQgYnV0IG5vdCBzdXBwb3J0ZWQgYnkgc2VydmVyIik7CisJICAgIH0KKwl9CisJaWYgKHAuaXNBdXRoZW50aWNhdGVkKCkpCisJICAgIHJldHVybjsJCS8vIG5vIG5lZWQgdG8gbG9naW4KKworCS8vIGFsbG93IHN1YmNsYXNzZXMgdG8gaXNzdWUgY29tbWFuZHMgYmVmb3JlIGxvZ2luCisJcHJlTG9naW4ocCk7CisKKwkvLyBpc3N1ZSBzcGVjaWFsIElEIGNvbW1hbmQgdG8gWWFob28hIE1haWwgSU1BUCBzZXJ2ZXIKKwkvLyBodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1lhaG9vJTIxX01haWwjRnJlZV9JTUFQX2FuZF9TTVRQc19hY2Nlc3MKKwlpZiAoZ3VpZCAhPSBudWxsKSB7CisJICAgIE1hcDxTdHJpbmcsU3RyaW5nPiBnbWFwID0gbmV3IEhhc2hNYXA8PigpOworCSAgICBnbWFwLnB1dCgiR1VJRCIsIGd1aWQpOworCSAgICBwLmlkKGdtYXApOworCX0KKworCS8qCisJICogUHV0IGEgc3BlY2lhbCAibWFya2VyIiBpbiB0aGUgY2FwYWJpbGl0aWVzIGxpc3Qgc28gd2UgY2FuCisJICogZGV0ZWN0IGlmIHRoZSBzZXJ2ZXIgcmVmcmVzaGVkIHRoZSBjYXBhYmlsaXRpZXMgaW4gdGhlIE9LCisJICogcmVzcG9uc2UuCisJICovCisJcC5nZXRDYXBhYmlsaXRpZXMoKS5wdXQoIl9fUFJFTE9HSU5fXyIsICIiKTsKKwlTdHJpbmcgYXV0aHppZDsKKwlpZiAoYXV0aG9yaXphdGlvbklEICE9IG51bGwpCisJICAgIGF1dGh6aWQgPSBhdXRob3JpemF0aW9uSUQ7CisJZWxzZSBpZiAocHJveHlBdXRoVXNlciAhPSBudWxsKQorCSAgICBhdXRoemlkID0gcHJveHlBdXRoVXNlcjsKKwllbHNlCisJICAgIGF1dGh6aWQgPSBudWxsOworCisJaWYgKGVuYWJsZVNBU0wpIHsKKwkgICAgdHJ5IHsKKwkJcC5zYXNsbG9naW4oc2FzbE1lY2hhbmlzbXMsIHNhc2xSZWFsbSwgYXV0aHppZCwgdSwgcHcpOworCQlpZiAoIXAuaXNBdXRoZW50aWNhdGVkKCkpCisJCSAgICB0aHJvdyBuZXcgQ29tbWFuZEZhaWxlZEV4Y2VwdGlvbigKKwkJCQkJCSJTQVNMIGF1dGhlbnRpY2F0aW9uIGZhaWxlZCIpOworCSAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBleCkgeworCQkvLyBjb250aW51ZSB0byB0cnkgb3RoZXIgYXV0aGVudGljYXRpb24gbWV0aG9kcyBiZWxvdworCSAgICB9CisJfQorCisJaWYgKCFwLmlzQXV0aGVudGljYXRlZCgpKQorCSAgICBhdXRoZW50aWNhdGUocCwgYXV0aHppZCwgdSwgcHcpOworCisJaWYgKHByb3h5QXV0aFVzZXIgIT0gbnVsbCkKKwkgICAgcC5wcm94eWF1dGgocHJveHlBdXRoVXNlcik7CisKKwkvKgorCSAqIElmIG1hcmtlciBpcyBzdGlsbCB0aGVyZSwgY2FwYWJpbGl0aWVzIGhhdmVuJ3QgYmVlbiByZWZyZXNoZWQsCisJICogcmVmcmVzaCB0aGVtIG5vdy4KKwkgKi8KKwlpZiAocC5oYXNDYXBhYmlsaXR5KCJfX1BSRUxPR0lOX18iKSkgeworCSAgICB0cnkgeworCQlwLmNhcGFiaWxpdHkoKTsKKwkgICAgfSBjYXRjaCAoQ29ubmVjdGlvbkV4Y2VwdGlvbiBjZXgpIHsKKwkJdGhyb3cgY2V4OwkvLyByZXRocm93IGNvbm5lY3Rpb24gZmFpbHVyZXMKKwkJLy8gWFhYIC0gYXNzdW1lIGNvbm5lY3Rpb24gaGFzIGJlZW4gY2xvc2VkCisJICAgIH0gY2F0Y2ggKFByb3RvY29sRXhjZXB0aW9uIHBleCkgeworCQkvLyBpZ25vcmUgb3RoZXIgZXhjZXB0aW9ucyB0aGF0ICJzaG91bGQgbmV2ZXIgaGFwcGVuIgorCSAgICB9CisJfQorCisJaWYgKGVuYWJsZUNvbXByZXNzKSB7CisJICAgIGlmIChwLmhhc0NhcGFiaWxpdHkoIkNPTVBSRVNTPURFRkxBVEUiKSkgeworCQlwLmNvbXByZXNzKCk7CisJICAgIH0KKwl9CisKKwkvLyBpZiBzZXJ2ZXIgc3VwcG9ydHMgVVRGLTgsIGVuYWJsZSBpdCBmb3IgY2xpZW50IHVzZQorCS8vIG5vdGUgdGhhdCB0aGlzIGlzIHNhZmUgdG8gZW5hYmxlIGV2ZW4gaWYgbWFpbC5taW1lLmFsbG93dXRmOD1mYWxzZQorCWlmIChwLmhhc0NhcGFiaWxpdHkoIlVURjg9QUNDRVBUIikgfHwgcC5oYXNDYXBhYmlsaXR5KCJVVEY4PU9OTFkiKSkKKwkgICAgcC5lbmFibGUoIlVURjg9QUNDRVBUIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXV0aGVudGljYXRlIHVzaW5nIG9uZSBvZiB0aGUgbm9uLVNBU0wgbWVjaGFuaXNtcy4KKyAgICAgKgorICAgICAqIEBwYXJhbQlwCXRoZSBJTUFQUHJvdG9jb2wgb2JqZWN0CisgICAgICogQHBhcmFtCWF1dGh6aWQJdGhlIGF1dGhvcml6YXRpb24gSUQKKyAgICAgKiBAcGFyYW0JdXNlcgl0aGUgdXNlciBuYW1lCisgICAgICogQHBhcmFtCXBhc3N3b3JkIHRoZSBwYXNzd29yZAorICAgICAqIEBleGNlcHRpb24JUHJvdG9jb2xFeGNlcHRpb24Jb24gZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgYXV0aGVudGljYXRlKElNQVBQcm90b2NvbCBwLCBTdHJpbmcgYXV0aHppZCwKKwkJCQlTdHJpbmcgdXNlciwgU3RyaW5nIHBhc3N3b3JkKQorCQkJCXRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJLy8gdGhpcyBsaXN0IG11c3QgbWF0Y2ggdGhlICJpZiIgc3RhdGVtZW50cyBiZWxvdworCVN0cmluZyBkZWZhdWx0QXV0aGVudGljYXRpb25NZWNoYW5pc21zID0gIlBMQUlOIExPR0lOIE5UTE0gWE9BVVRIMiI7CisKKwkvLyBzZXR0aW5nIG1haWwuaW1hcC5hdXRoLm1lY2hhbmlzbXMgY29udHJvbHMgd2hpY2ggbWVjaGFuaXNtcyB3aWxsCisJLy8gYmUgdXNlZCwgYW5kIGluIHdoYXQgb3JkZXIgdGhleSdsbCBiZSBjb25zaWRlcmVkLiAgb25seSB0aGUgZmlyc3QKKwkvLyBtYXRjaCBpcyB1c2VkLgorCVN0cmluZyBtZWNocyA9IHNlc3Npb24uZ2V0UHJvcGVydHkoIm1haWwuIiArIG5hbWUgKyAiLmF1dGgubWVjaGFuaXNtcyIpOworCisJaWYgKG1lY2hzID09IG51bGwpCisJICAgIG1lY2hzID0gZGVmYXVsdEF1dGhlbnRpY2F0aW9uTWVjaGFuaXNtczsKKworCS8qCisJICogTG9vcCB0aHJvdWdoIHRoZSBsaXN0IG9mIG1lY2hhbmlzbXMgc3VwcGxpZWQgYnkgdGhlIHVzZXIKKwkgKiAob3IgZGVmYXVsdGVkKSBhbmQgdHJ5IGVhY2ggaW4gdHVybi4gIElmIHRoZSBzZXJ2ZXIgc3VwcG9ydHMKKwkgKiB0aGUgbWVjaGFuaXNtIGFuZCB3ZSBoYXZlIGFuIGF1dGhlbnRpY2F0b3IgZm9yIHRoZSBtZWNoYW5pc20sCisJICogYW5kIGl0IGhhc24ndCBiZWVuIGRpc2FibGVkLCB1c2UgaXQuCisJICovCisJU3RyaW5nVG9rZW5pemVyIHN0ID0gbmV3IFN0cmluZ1Rva2VuaXplcihtZWNocyk7CisJd2hpbGUgKHN0Lmhhc01vcmVUb2tlbnMoKSkgeworCSAgICBTdHJpbmcgbSA9IHN0Lm5leHRUb2tlbigpOworCSAgICBtID0gbS50b1VwcGVyQ2FzZShMb2NhbGUuRU5HTElTSCk7CisKKwkgICAgLyoKKwkgICAgICogSWYgdXNpbmcgdGhlIGRlZmF1bHQgbWVjaGFuaXNtcywgY2hlY2sgaWYgdGhpcyBvbmUgaXMgZGlzYWJsZWQuCisJICAgICAqLworCSAgICBpZiAobWVjaHMgPT0gZGVmYXVsdEF1dGhlbnRpY2F0aW9uTWVjaGFuaXNtcykgeworCQlTdHJpbmcgZHByb3AgPSAibWFpbC4iICsgbmFtZSArICIuYXV0aC4iICsKKwkJCQkgICAgbS50b0xvd2VyQ2FzZShMb2NhbGUuRU5HTElTSCkgKyAiLmRpc2FibGUiOworCQlib29sZWFuIGRpc2FibGVkID0gUHJvcFV0aWwuZ2V0Qm9vbGVhblByb3BlcnR5KAorCQkJCQlzZXNzaW9uLmdldFByb3BlcnRpZXMoKSwKKwkJCQkJZHByb3AsIG0uZXF1YWxzKCJYT0FVVEgyIikpOworCQlpZiAoZGlzYWJsZWQpIHsKKwkJICAgIGlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FKSkKKwkJCWxvZ2dlci5maW5lKCJtZWNoYW5pc20gIiArIG0gKworCQkJCQkiIGRpc2FibGVkIGJ5IHByb3BlcnR5OiAiICsgZHByb3ApOworCQkgICAgY29udGludWU7CisJCX0KKwkgICAgfQorCisJICAgIGlmICghKHAuaGFzQ2FwYWJpbGl0eSgiQVVUSD0iICsgbSkgfHwKKwkJICAgIChtLmVxdWFscygiTE9HSU4iKSAmJiBwLmhhc0NhcGFiaWxpdHkoIkFVVEgtTE9HSU4iKSkpKSB7CisJCWxvZ2dlci5sb2coTGV2ZWwuRklORSwgIm1lY2hhbmlzbSB7MH0gbm90IHN1cHBvcnRlZCBieSBzZXJ2ZXIiLAorCQkJCQltKTsKKwkJY29udGludWU7CisJICAgIH0KKworCSAgICBpZiAobS5lcXVhbHMoIlBMQUlOIikpCisJCXAuYXV0aHBsYWluKGF1dGh6aWQsIHVzZXIsIHBhc3N3b3JkKTsKKwkgICAgZWxzZSBpZiAobS5lcXVhbHMoIkxPR0lOIikpCisJCXAuYXV0aGxvZ2luKHVzZXIsIHBhc3N3b3JkKTsKKwkgICAgZWxzZSBpZiAobS5lcXVhbHMoIk5UTE0iKSkKKwkJcC5hdXRobnRsbShhdXRoemlkLCB1c2VyLCBwYXNzd29yZCk7CisJICAgIGVsc2UgaWYgKG0uZXF1YWxzKCJYT0FVVEgyIikpCisJCXAuYXV0aG9hdXRoMih1c2VyLCBwYXNzd29yZCk7CisJICAgIGVsc2UgeworCQlsb2dnZXIubG9nKExldmVsLkZJTkUsICJubyBhdXRoZW50aWNhdG9yIGZvciBtZWNoYW5pc20gezB9IiwgbSk7CisJCWNvbnRpbnVlOworCSAgICB9CisJICAgIHJldHVybjsKKwl9CisKKwlpZiAoIXAuaGFzQ2FwYWJpbGl0eSgiTE9HSU5ESVNBQkxFRCIpKSB7CisJICAgIHAubG9naW4odXNlciwgcGFzc3dvcmQpOworCSAgICByZXR1cm47CisJfQorCisJdGhyb3cgbmV3IFByb3RvY29sRXhjZXB0aW9uKCJObyBsb2dpbiBtZXRob2RzIHN1cHBvcnRlZCEiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYWZ0ZXIgdGhlIGNvbm5lY3Rpb24gaXMgbWFkZSBhbmQKKyAgICAgKiBUTFMgaXMgc3RhcnRlZCAoaWYgbmVlZGVkKSwgYnV0IGJlZm9yZSBhbnkgYXV0aGVudGljYXRpb24KKyAgICAgKiBpcyBhdHRlbXB0ZWQuICBTdWJjbGFzc2VzIGNhbiBvdmVycmlkZSB0aGlzIG1ldGhvZCB0bworICAgICAqIGlzc3VlIGNvbW1hbmRzIHRoYXQgYXJlIG5lZWRlZCBpbiB0aGUgIm5vdCBhdXRoZW50aWNhdGVkIgorICAgICAqIHN0YXRlLiAgTm90ZSB0aGF0IGlmIHRoZSBjb25uZWN0aW9uIGlzIHByZS1hdXRoZW50aWNhdGVkLAorICAgICAqIHRoaXMgbWV0aG9kIHdvbid0IGJlIGNhbGxlZC4gPHA+CisgICAgICoKKyAgICAgKiBUaGUgaW1wbGVtZW50YXRpb24gb2YgdGhpcyBtZXRob2QgaW4gdGhpcyBjbGFzcyBkb2VzIG5vdGhpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0JcAl0aGUgSU1BUFByb3RvY29sIGNvbm5lY3Rpb24KKyAgICAgKiBAZXhjZXB0aW9uCVByb3RvY29sRXhjZXB0aW9uIGZvciBwcm90b2NvbCBlcnJvcnMKKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS40LjQKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBwcmVMb2dpbihJTUFQUHJvdG9jb2wgcCkgdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEb2VzIHRoaXMgSU1BUFN0b3JlIHVzZSBTU0wgd2hlbiBjb25uZWN0aW5nIHRvIHRoZSBzZXJ2ZXI/CisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRydWUgaWYgdXNpbmcgU1NMCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNC42CisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIGlzU1NMKCkgeworICAgICAgICByZXR1cm4gdXNpbmdTU0w7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSB1c2VyIG5hbWUgdGhhdCB3aWxsIGJlIHVzZWQgZm9yIHN1YnNlcXVlbnQgY29ubmVjdGlvbnMKKyAgICAgKiBhZnRlciB0aGlzIFN0b3JlIGlzIGZpcnN0IGNvbm5lY3RlZCAoZm9yIGV4YW1wbGUsIHdoZW4gY3JlYXRpbmcKKyAgICAgKiBhIGNvbm5lY3Rpb24gdG8gb3BlbiBhIEZvbGRlcikuICBUaGlzIHZhbHVlIGlzIG92ZXJyaWRkZW4KKyAgICAgKiBieSBhbnkgY2FsbCB0byB0aGUgU3RvcmUncyBjb25uZWN0IG1ldGhvZC4gPHA+CisgICAgICoKKyAgICAgKiBTb21lIElNQVAgc2VydmVycyBtYXkgcHJvdmlkZSBhbiBhdXRoZW50aWNhdGlvbiBJRCB0aGF0IGNhbgorICAgICAqIGJlIHVzZWQgZm9yIG1vcmUgZWZmaWNpZW50IGF1dGhlbnRpY2F0aW9uIGZvciBmdXR1cmUgY29ubmVjdGlvbnMuCisgICAgICogVGhpcyBhdXRoZW50aWNhdGlvbiBJRCBpcyBwcm92aWRlZCBpbiBhIHNlcnZlci1zcGVjaWZpYyBtYW5uZXIKKyAgICAgKiBub3QgZGVzY3JpYmVkIGhlcmUuIDxwPgorICAgICAqCisgICAgICogTW9zdCBhcHBsaWNhdGlvbnMgd2lsbCBuZXZlciBuZWVkIHRvIHVzZSB0aGlzIG1ldGhvZC4KKyAgICAgKgorICAgICAqIEBwYXJhbQl1c2VyCXRoZSB1c2VyIG5hbWUgZm9yIHRoZSBzdG9yZQorICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjMuMworICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXRVc2VybmFtZShTdHJpbmcgdXNlcikgeworCXRoaXMudXNlciA9IHVzZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBwYXNzd29yZCB0aGF0IHdpbGwgYmUgdXNlZCBmb3Igc3Vic2VxdWVudCBjb25uZWN0aW9ucworICAgICAqIGFmdGVyIHRoaXMgU3RvcmUgaXMgZmlyc3QgY29ubmVjdGVkIChmb3IgZXhhbXBsZSwgd2hlbiBjcmVhdGluZworICAgICAqIGEgY29ubmVjdGlvbiB0byBvcGVuIGEgRm9sZGVyKS4gIFRoaXMgdmFsdWUgaXMgb3ZlcnJpZGRlbgorICAgICAqIGJ5IGFueSBjYWxsIHRvIHRoZSBTdG9yZSdzIGNvbm5lY3QgbWV0aG9kLiA8cD4KKyAgICAgKgorICAgICAqIE1vc3QgYXBwbGljYXRpb25zIHdpbGwgbmV2ZXIgbmVlZCB0byB1c2UgdGhpcyBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcGFyYW0JcGFzc3dvcmQJdGhlIHBhc3N3b3JkIGZvciB0aGUgc3RvcmUKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS4zLjMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgc2V0UGFzc3dvcmQoU3RyaW5nIHBhc3N3b3JkKSB7CisJdGhpcy5wYXNzd29yZCA9IHBhc3N3b3JkOworICAgIH0KKworICAgIC8qCisgICAgICogR2V0IGEgbmV3IGF1dGhlbnRpY2F0ZWQgcHJvdG9jb2wgb2JqZWN0IGZvciB0aGlzIEZvbGRlci4KKyAgICAgKiBBbHNvIHN0b3JlIGEgcmVmZXJlbmNlIHRvIHRoaXMgZm9sZGVyIGluIG91ciBsaXN0IG9mCisgICAgICogb3BlbiBmb2xkZXJzLgorICAgICAqLworICAgIElNQVBQcm90b2NvbCBnZXRQcm90b2NvbChJTUFQRm9sZGVyIGZvbGRlcikgCisJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCUlNQVBQcm90b2NvbCBwID0gbnVsbDsKKworCS8vIGtlZXAgbG9va2luZyBmb3IgYSBjb25uZWN0aW9uIHVudGlsIHdlIGdldCBhIGdvb2Qgb25lCisJd2hpbGUgKHAgPT0gbnVsbCkgeworIAorICAgICAgICAvLyBOZXcgYXV0aGVudGljYXRlZCBwcm90b2NvbCBvYmplY3RzIGFyZSBlaXRoZXIgYWNxdWlyZWQKKyAgICAgICAgLy8gZnJvbSB0aGUgY29ubmVjdGlvbiBwb29sLCBvciBjcmVhdGVkIHdoZW4gdGhlIHBvb2wgaXMKKyAgICAgICAgLy8gZW1wdHkgb3Igbm8gY29ubmVjdGlvbnMgYXJlIGF2YWlsYWJsZS4gTm9uZSBhcmUgYXZhaWxhYmxlCisgICAgICAgIC8vIGlmIHRoZSBjdXJyZW50IHBvb2wgc2l6ZSBpcyBvbmUgYW5kIHRoZSBzZXBhcmF0ZSBzdG9yZQorICAgICAgICAvLyBwcm9wZXJ0eSBpcyBzZXQgb3IgdGhlIGNvbm5lY3Rpb24gaXMgaW4gdXNlLgorCisgICAgICAgIHN5bmNocm9uaXplZCAocG9vbCkgeworCisgICAgICAgICAgICAvLyBJZiB0aGVyZSdzIG5vbmUgYXZhaWxhYmxlIGluIHRoZSBwb29sLAorICAgICAgICAgICAgLy8gY3JlYXRlIGEgbmV3IG9uZS4KKyAgICAgICAgICAgIGlmIChwb29sLmF1dGhlbnRpY2F0ZWRDb25uZWN0aW9ucy5pc0VtcHR5KCkgfHwKKyAgICAgICAgICAgICAgICAocG9vbC5hdXRoZW50aWNhdGVkQ29ubmVjdGlvbnMuc2l6ZSgpID09IDEgJiYKKyAgICAgICAgICAgICAgICAocG9vbC5zZXBhcmF0ZVN0b3JlQ29ubmVjdGlvbiB8fCBwb29sLnN0b3JlQ29ubmVjdGlvbkluVXNlKSkpIHsKKworCQlsb2dnZXIuZmluZSgibm8gY29ubmVjdGlvbnMgaW4gdGhlIHBvb2wsIGNyZWF0aW5nIGEgbmV3IG9uZSIpOworICAgICAgICAgICAgICAgIHRyeSB7CisJCSAgICBpZiAoZm9yY2VQYXNzd29yZFJlZnJlc2gpCisJCQlyZWZyZXNoUGFzc3dvcmQoKTsKKyAgICAgICAgICAgICAgICAgICAgLy8gVXNlIGNhY2hlZCBob3N0LCBwb3J0IGFuZCB0aW1lb3V0IHZhbHVlcy4KKyAgICAgICAgICAgICAgICAgICAgcCA9IG5ld0lNQVBQcm90b2NvbChob3N0LCBwb3J0KTsKKwkJICAgIHAuYWRkUmVzcG9uc2VIYW5kbGVyKG5vblN0b3JlUmVzcG9uc2VIYW5kbGVyKTsKKyAgICAgICAgICAgICAgICAgICAgLy8gVXNlIGNhY2hlZCBhdXRoIGluZm8KKyAgICAgICAgICAgICAgICAgICAgbG9naW4ocCwgdXNlciwgcGFzc3dvcmQpOworCQkgICAgcC5yZW1vdmVSZXNwb25zZUhhbmRsZXIobm9uU3RvcmVSZXNwb25zZUhhbmRsZXIpOworICAgICAgICAgICAgICAgIH0gY2F0Y2goRXhjZXB0aW9uIGV4MSkgeworICAgICAgICAgICAgICAgICAgICBpZiAocCAhPSBudWxsKQorICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBwLmRpc2Nvbm5lY3QoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleDIpIHsgfQorICAgICAgICAgICAgICAgICAgICBwID0gbnVsbDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgIGlmIChwID09IG51bGwpCisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oImNvbm5lY3Rpb24gZmFpbHVyZSIpOworICAgICAgICAgICAgfSBlbHNlIHsKKwkJaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkUpKQorICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZmluZSgiY29ubmVjdGlvbiBhdmFpbGFibGUgLS0gc2l6ZTogIiArCisgICAgICAgICAgICAgICAgICAgICAgICBwb29sLmF1dGhlbnRpY2F0ZWRDb25uZWN0aW9ucy5zaXplKCkpOworCisgICAgICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSBhdmFpbGFibGUgY29ubmVjdGlvbiBmcm9tIHRoZSBBdXRoZW50aWNhdGVkIHF1ZXVlCisgICAgICAgICAgICAgICAgcCA9IHBvb2wuYXV0aGVudGljYXRlZENvbm5lY3Rpb25zLmxhc3RFbGVtZW50KCk7CisgICAgICAgICAgICAgICAgcG9vbC5hdXRoZW50aWNhdGVkQ29ubmVjdGlvbnMucmVtb3ZlRWxlbWVudChwKTsKKworCQkvLyBjaGVjayBpZiB0aGUgY29ubmVjdGlvbiBpcyBzdGlsbCBsaXZlCisJCWxvbmcgbGFzdFVzZWQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSAtIHAuZ2V0VGltZXN0YW1wKCk7CisJCWlmIChsYXN0VXNlZCA+IHBvb2wuc2VydmVyVGltZW91dEludGVydmFsKSB7CisJCSAgICB0cnkgeworCQkJLyoKKwkJCSAqIFN3YXAgaW4gYSBzcGVjaWFsIHJlc3BvbnNlIGhhbmRsZXIgdGhhdCB3aWxsIGhhbmRsZQorCQkJICogYWxlcnRzLCBidXQgd29uJ3QgY2F1c2UgdGhlIHN0b3JlIHRvIGJlIGNsb3NlZCBhbmQKKwkJCSAqIGNsZWFuZWQgdXAgaWYgdGhlIGNvbm5lY3Rpb24gaXMgZGVhZC4KKwkJCSAqLworCQkJcC5yZW1vdmVSZXNwb25zZUhhbmRsZXIodGhpcyk7CisJCQlwLmFkZFJlc3BvbnNlSGFuZGxlcihub25TdG9yZVJlc3BvbnNlSGFuZGxlcik7CisJCQlwLm5vb3AoKTsKKwkJCXAucmVtb3ZlUmVzcG9uc2VIYW5kbGVyKG5vblN0b3JlUmVzcG9uc2VIYW5kbGVyKTsKKwkJCXAuYWRkUmVzcG9uc2VIYW5kbGVyKHRoaXMpOworCQkgICAgfSBjYXRjaCAoUHJvdG9jb2xFeGNlcHRpb24gcGV4KSB7CisJCQl0cnkgeworCQkJICAgIHAucmVtb3ZlUmVzcG9uc2VIYW5kbGVyKG5vblN0b3JlUmVzcG9uc2VIYW5kbGVyKTsKKwkJCSAgICBwLmRpc2Nvbm5lY3QoKTsKKwkJCX0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gaWdub3JlZCkgeworCQkJICAgIC8vIGRvbid0IGxldCBhbnkgZXhjZXB0aW9uIHN0b3AgdXMKKwkJCX0KKwkJCXAgPSBudWxsOworCQkJY29udGludWU7ICAgLy8gdHJ5IGFnYWluLCBmcm9tIHRoZSB0b3AKKwkJICAgIH0KKwkJfQorCisJCS8vIGlmIHByb3h5QXV0aFVzZXIgaGFzIGNoYW5nZWQsIHN3aXRjaCB0byBuZXcgdXNlcgorCQlpZiAocHJveHlBdXRoVXNlciAhPSBudWxsICYmCisJCQkhcHJveHlBdXRoVXNlci5lcXVhbHMocC5nZXRQcm94eUF1dGhVc2VyKCkpICYmCisJCQlwLmhhc0NhcGFiaWxpdHkoIlgtVU5BVVRIRU5USUNBVEUiKSkgeworCQkgICAgdHJ5IHsKKwkJCS8qCisJCQkgKiBTd2FwIGluIGEgc3BlY2lhbCByZXNwb25zZSBoYW5kbGVyIHRoYXQgd2lsbCBoYW5kbGUKKwkJCSAqIGFsZXJ0cywgYnV0IHdvbid0IGNhdXNlIHRoZSBzdG9yZSB0byBiZSBjbG9zZWQgYW5kCisJCQkgKiBjbGVhbmVkIHVwIGlmIHRoZSBjb25uZWN0aW9uIGlzIGRlYWQuCisJCQkgKi8KKwkJCXAucmVtb3ZlUmVzcG9uc2VIYW5kbGVyKHRoaXMpOworCQkJcC5hZGRSZXNwb25zZUhhbmRsZXIobm9uU3RvcmVSZXNwb25zZUhhbmRsZXIpOworCQkJcC51bmF1dGhlbnRpY2F0ZSgpOworCQkJbG9naW4ocCwgdXNlciwgcGFzc3dvcmQpOworCQkJcC5yZW1vdmVSZXNwb25zZUhhbmRsZXIobm9uU3RvcmVSZXNwb25zZUhhbmRsZXIpOworCQkJcC5hZGRSZXNwb25zZUhhbmRsZXIodGhpcyk7CisJCSAgICB9IGNhdGNoIChQcm90b2NvbEV4Y2VwdGlvbiBwZXgpIHsKKwkJCXRyeSB7CisJCQkgICAgcC5yZW1vdmVSZXNwb25zZUhhbmRsZXIobm9uU3RvcmVSZXNwb25zZUhhbmRsZXIpOworCQkJICAgIHAuZGlzY29ubmVjdCgpOworCQkJfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBpZ25vcmVkKSB7CisJCQkgICAgLy8gZG9uJ3QgbGV0IGFueSBleGNlcHRpb24gc3RvcCB1cworCQkJfQorCQkJcCA9IG51bGw7CisJCQljb250aW51ZTsgICAvLyB0cnkgYWdhaW4sIGZyb20gdGhlIHRvcAorCQkgICAgfQorCQl9CisKKyAgICAgICAgICAgICAgICAvLyByZW1vdmUgdGhlIHN0b3JlIGFzIGEgcmVzcG9uc2UgaGFuZGxlci4KKyAgICAgICAgICAgICAgICBwLnJlbW92ZVJlc3BvbnNlSGFuZGxlcih0aGlzKTsKKwkgICAgfQorCisgICAgICAgICAgICAvLyBjaGVjayBpZiB3ZSBuZWVkIHRvIGxvb2sgZm9yIGNsaWVudC1zaWRlIHRpbWVvdXRzCisgICAgICAgICAgICB0aW1lb3V0Q29ubmVjdGlvbnMoKTsKKworCSAgICAvLyBBZGQgZm9sZGVyIHRvIGZvbGRlci1saXN0CisJICAgIGlmIChmb2xkZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGlmIChwb29sLmZvbGRlcnMgPT0gbnVsbCkKKyAgICAgICAgICAgICAgICAgICAgcG9vbC5mb2xkZXJzID0gbmV3IFZlY3Rvcjw+KCk7CisJCXBvb2wuZm9sZGVycy5hZGRFbGVtZW50KGZvbGRlcik7CisJICAgIH0KKyAgICAgICAgfQorCisJfQorCQorCXJldHVybiBwOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGlzIFN0b3JlJ3MgcHJvdG9jb2wgY29ubmVjdGlvbi4KKyAgICAgKgorICAgICAqIFdoZW4gYWNxdWlyaW5nIGEgc3RvcmUgcHJvdG9jb2wgb2JqZWN0LCBpdCBpcyBpbXBvcnRhbnQgdG8KKyAgICAgKiB1c2UgdGhlIGZvbGxvd2luZyBzdGVwczoKKyAgICAgKgorICAgICAqICAgICBJTUFQUHJvdG9jb2wgcCA9IG51bGw7CisgICAgICogICAgIHRyeSB7CisgICAgICogICAgICAgICBwID0gZ2V0U3RvcmVQcm90b2NvbCgpOworICAgICAqICAgICAgICAgLy8gcGVyZm9ybSB0aGUgY29tbWFuZAorICAgICAqICAgICB9IGNhdGNoIChDb25uZWN0aW9uRXhjZXB0aW9uIGNleCkgeworICAgICAqICAgICAgICAgdGhyb3cgbmV3IFN0b3JlQ2xvc2VkRXhjZXB0aW9uKHRoaXMsIGNleC5nZXRNZXNzYWdlKCkpOworICAgICAqICAgICB9IGNhdGNoIChXaGF0ZXZlckV4Y2VwdGlvbiBleCkgeworICAgICAqICAgICAgICAgLy8gaGFuZGxlIGl0CisgICAgICogICAgIH0gZmluYWxseSB7CisgICAgICogICAgICAgICByZWxlYXNlU3RvcmVQcm90b2NvbChwKTsKKyAgICAgKiAgICAgfQorICAgICAqLworICAgIHByaXZhdGUgSU1BUFByb3RvY29sIGdldFN0b3JlUHJvdG9jb2woKSB0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworICAgICAgICBJTUFQUHJvdG9jb2wgcCA9IG51bGw7CisKKwl3aGlsZSAocCA9PSBudWxsKSB7CisgICAgICAgIHN5bmNocm9uaXplZCAocG9vbCkgeworCSAgICB3YWl0SWZJZGxlKCk7CisKKyAgICAgICAgICAgIC8vIElmIHRoZXJlJ3Mgbm8gYXV0aGVudGljYXRlZCBjb25uZWN0aW9ucyBhdmFpbGFibGUgY3JlYXRlIGEgCisgICAgICAgICAgICAvLyBuZXcgb25lIGFuZCBwbGFjZSBpdCBpbiB0aGUgYXV0aGVudGljYXRlZCBxdWV1ZS4KKyAgICAgICAgICAgIGlmIChwb29sLmF1dGhlbnRpY2F0ZWRDb25uZWN0aW9ucy5pc0VtcHR5KCkpIHsKKwkJcG9vbC5sb2dnZXIuZmluZSgiZ2V0U3RvcmVQcm90b2NvbCgpIC0gbm8gY29ubmVjdGlvbnMgIiArCisgICAgICAgICAgICAgICAgICAgICAgICAiaW4gdGhlIHBvb2wsIGNyZWF0aW5nIGEgbmV3IG9uZSIpOworICAgICAgICAgICAgICAgIHRyeSB7CisJCSAgICBpZiAoZm9yY2VQYXNzd29yZFJlZnJlc2gpCisJCQlyZWZyZXNoUGFzc3dvcmQoKTsKKyAgICAgICAgICAgICAgICAgICAgLy8gVXNlIGNhY2hlZCBob3N0LCBwb3J0IGFuZCB0aW1lb3V0IHZhbHVlcy4KKyAgICAgICAgICAgICAgICAgICAgcCA9IG5ld0lNQVBQcm90b2NvbChob3N0LCBwb3J0KTsKKyAgICAgICAgICAgICAgICAgICAgLy8gVXNlIGNhY2hlZCBhdXRoIGluZm8KKyAgICAgICAgICAgICAgICAgICAgbG9naW4ocCwgdXNlciwgcGFzc3dvcmQpOworICAgICAgICAgICAgICAgIH0gY2F0Y2goRXhjZXB0aW9uIGV4MSkgeworICAgICAgICAgICAgICAgICAgICBpZiAocCAhPSBudWxsKQorICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBwLmxvZ291dCgpOworICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4MikgeyB9CisgICAgICAgICAgICAgICAgICAgIHAgPSBudWxsOworICAgICAgICAgICAgICAgIH0KKyAKKyAgICAgICAgICAgICAgICBpZiAocCA9PSBudWxsKQorICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ29ubmVjdGlvbkV4Y2VwdGlvbigKKwkJCQkiZmFpbGVkIHRvIGNyZWF0ZSBuZXcgc3RvcmUgY29ubmVjdGlvbiIpOworICAgICAgICAgICAgIAorCSAgICAgICAgcC5hZGRSZXNwb25zZUhhbmRsZXIodGhpcyk7CisgICAgICAgICAgICAgICAgcG9vbC5hdXRoZW50aWNhdGVkQ29ubmVjdGlvbnMuYWRkRWxlbWVudChwKTsKKyAKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgLy8gQWx3YXlzIHVzZSB0aGUgZmlyc3QgZWxlbWVudCBpbiB0aGUgQXV0aGVudGljYXRlZCBxdWV1ZS4KKwkJaWYgKHBvb2wubG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuRklORSkpCisgICAgICAgICAgICAgICAgICAgIHBvb2wubG9nZ2VyLmZpbmUoImdldFN0b3JlUHJvdG9jb2woKSAtICIgKworICAgICAgICAgICAgICAgICAgICAgICAgImNvbm5lY3Rpb24gYXZhaWxhYmxlIC0tIHNpemU6ICIgKworICAgICAgICAgICAgICAgICAgICAgICAgcG9vbC5hdXRoZW50aWNhdGVkQ29ubmVjdGlvbnMuc2l6ZSgpKTsKKyAgICAgICAgICAgICAgICBwID0gcG9vbC5hdXRoZW50aWNhdGVkQ29ubmVjdGlvbnMuZmlyc3RFbGVtZW50KCk7CisKKwkJLy8gaWYgcHJveHlBdXRoVXNlciBoYXMgY2hhbmdlZCwgc3dpdGNoIHRvIG5ldyB1c2VyCisJCWlmIChwcm94eUF1dGhVc2VyICE9IG51bGwgJiYKKwkJCSFwcm94eUF1dGhVc2VyLmVxdWFscyhwLmdldFByb3h5QXV0aFVzZXIoKSkgJiYKKwkJCXAuaGFzQ2FwYWJpbGl0eSgiWC1VTkFVVEhFTlRJQ0FURSIpKSB7CisJCSAgICBwLnVuYXV0aGVudGljYXRlKCk7CisJCSAgICBsb2dpbihwLCB1c2VyLCBwYXNzd29yZCk7CisJCX0KKyAgICAgICAgICAgIH0KKyAKKwkgICAgaWYgKHBvb2wuc3RvcmVDb25uZWN0aW9uSW5Vc2UpIHsKKwkJdHJ5IHsKKwkJICAgIC8vIHNvbWVvbmUgZWxzZSBpcyB1c2luZyB0aGUgY29ubmVjdGlvbiwgZ2l2ZSB1cAorCQkgICAgLy8gYW5kIHdhaXQgdW50aWwgdGhleSdyZSBkb25lCisJCSAgICBwID0gbnVsbDsKKwkJICAgIHBvb2wud2FpdCgpOworCQl9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBleCkgeworCQkgICAgLy8gcmVzdG9yZSB0aGUgaW50ZXJydXB0ZWQgc3RhdGUsIHdoaWNoIGNhbGxlcnMgbWlnaHQKKwkJICAgIC8vIGRlcGVuZCBvbgorCQkgICAgVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5pbnRlcnJ1cHQoKTsKKwkJICAgIC8vIGRvbid0IGtlZXAgbG9va2luZyBmb3IgYSBjb25uZWN0aW9uIGlmIHdlJ3ZlIGJlZW4KKwkJICAgIC8vIGludGVycnVwdGVkCisJCSAgICB0aHJvdyBuZXcgUHJvdG9jb2xFeGNlcHRpb24oCisJCQkJICAgICJJbnRlcnJ1cHRlZCBnZXRTdG9yZVByb3RvY29sIiwgZXgpOworCQl9CisJICAgIH0gZWxzZSB7CisJCXBvb2wuc3RvcmVDb25uZWN0aW9uSW5Vc2UgPSB0cnVlOworCisJCXBvb2wubG9nZ2VyLmZpbmUoImdldFN0b3JlUHJvdG9jb2woKSAtLSBzdG9yZUNvbm5lY3Rpb25JblVzZSIpOworCSAgICB9CisgCisgICAgICAgICAgICB0aW1lb3V0Q29ubmVjdGlvbnMoKTsKKyAgICAgICAgfQorCX0KKwlyZXR1cm4gcDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgYSBzdG9yZSBwcm90b2NvbCBvYmplY3QgZm9yIHVzZSBieSBhIGZvbGRlci4KKyAgICAgKi8KKyAgICBJTUFQUHJvdG9jb2wgZ2V0Rm9sZGVyU3RvcmVQcm90b2NvbCgpIHRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJSU1BUFByb3RvY29sIHAgPSBnZXRTdG9yZVByb3RvY29sKCk7CisJcC5yZW1vdmVSZXNwb25zZUhhbmRsZXIodGhpcyk7CisJcC5hZGRSZXNwb25zZUhhbmRsZXIobm9uU3RvcmVSZXNwb25zZUhhbmRsZXIpOworCXJldHVybiBwOworICAgIH0KKworICAgIC8qCisgICAgICogU29tZSBhdXRoZW50aWNhdGlvbiBzeXN0ZW1zIHVzZSBvbmUgdGltZSBwYXNzd29yZHMKKyAgICAgKiBvciB0b2tlbnMsIHNvIGVhY2ggYXV0aGVudGljYXRpb24gcmVxdWVzdCByZXF1aXJlcworICAgICAqIGEgbmV3IHBhc3N3b3JkLiAgVGhpcyAia2x1ZGdlIiBhbGxvd3MgYSBjYWxsYmFjaworICAgICAqIHRvIGFwcGxpY2F0aW9uIGNvZGUgdG8gZ2V0IGEgbmV3IHBhc3N3b3JkLgorICAgICAqCisgICAgICogWFhYIC0gcmVtb3ZlIHRoaXMgd2hlbiBTQVNMIHN1cHBvcnQgaXMgYWRkZWQKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmVmcmVzaFBhc3N3b3JkKCkgeworCWlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FKSkKKwkgICAgbG9nZ2VyLmZpbmUoInJlZnJlc2ggcGFzc3dvcmQsIHVzZXI6ICIgKyB0cmFjZVVzZXIodXNlcikpOworCUluZXRBZGRyZXNzIGFkZHI7CisJdHJ5IHsKKwkgICAgYWRkciA9IEluZXRBZGRyZXNzLmdldEJ5TmFtZShob3N0KTsKKwl9IGNhdGNoIChVbmtub3duSG9zdEV4Y2VwdGlvbiBlKSB7CisJICAgIGFkZHIgPSBudWxsOworCX0KKwlQYXNzd29yZEF1dGhlbnRpY2F0aW9uIHBhID0KKwkgICAgc2Vzc2lvbi5yZXF1ZXN0UGFzc3dvcmRBdXRoZW50aWNhdGlvbihhZGRyLCBwb3J0LAorCQkJCQluYW1lLCBudWxsLCB1c2VyKTsKKwlpZiAocGEgIT0gbnVsbCkgeworCSAgICB1c2VyID0gcGEuZ2V0VXNlck5hbWUoKTsKKwkgICAgcGFzc3dvcmQgPSBwYS5nZXRQYXNzd29yZCgpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJZiBhIFNFTEVDVCBzdWNjZWVkcywgYnV0IGluZGljYXRlcyB0aGF0IHRoZSBmb2xkZXIgaXMKKyAgICAgKiBSRUFELU9OTFksIGFuZCB0aGUgdXNlciBhc2tlZCB0byBvcGVuIHRoZSBmb2xkZXIgUkVBRF9XUklURSwKKyAgICAgKiBkbyB3ZSBhbGxvdyB0aGUgb3BlbiB0byBzdWNjZWVkPworICAgICAqLworICAgIGJvb2xlYW4gYWxsb3dSZWFkT25seVNlbGVjdCgpIHsKKwlyZXR1cm4gUHJvcFV0aWwuZ2V0Qm9vbGVhblByb3BlcnR5KHNlc3Npb24uZ2V0UHJvcGVydGllcygpLAorCSAgICAibWFpbC4iICsgbmFtZSArICIuYWxsb3dyZWFkb25seXNlbGVjdCIsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXBvcnQgd2hldGhlciB0aGUgc2VwYXJhdGVTdG9yZUNvbm5lY3Rpb24gaXMgc2V0LgorICAgICAqLworICAgIGJvb2xlYW4gaGFzU2VwYXJhdGVTdG9yZUNvbm5lY3Rpb24oKSB7CisgICAgICAgIHJldHVybiBwb29sLnNlcGFyYXRlU3RvcmVDb25uZWN0aW9uOworICAgIH0KKworICAgIC8qKiAKKyAgICAgKiBSZXR1cm4gdGhlIGNvbm5lY3Rpb24gcG9vbCBsb2dnZXIuCisgICAgICovIAorICAgIE1haWxMb2dnZXIgZ2V0Q29ubmVjdGlvblBvb2xMb2dnZXIoKSB7CisgICAgICAgIHJldHVybiBwb29sLmxvZ2dlcjsgCisgICAgfSAKKyAKKyAgICAvKiogCisgICAgICogUmVwb3J0IHdoZXRoZXIgbWVzc2FnZSBjYWNoZSBkZWJ1Z2dpbmcgaXMgZW5hYmxlZC4gCisgICAgICovIAorICAgIGJvb2xlYW4gZ2V0TWVzc2FnZUNhY2hlRGVidWcoKSB7CisgICAgICAgIHJldHVybiBtZXNzYWdlQ2FjaGVEZWJ1ZzsgCisgICAgfSAKKyAKKyAgICAvKioKKyAgICAgKiBSZXBvcnQgd2hldGhlciB0aGUgY29ubmVjdGlvbiBwb29sIGlzIGZ1bGwuCisgICAgICovCisgICAgYm9vbGVhbiBpc0Nvbm5lY3Rpb25Qb29sRnVsbCgpIHsKKworICAgICAgICBzeW5jaHJvbml6ZWQgKHBvb2wpIHsKKwkgICAgaWYgKHBvb2wubG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuRklORSkpCisgICAgICAgICAgICAgICAgcG9vbC5sb2dnZXIuZmluZSgiY29ubmVjdGlvbiBwb29sIGN1cnJlbnQgc2l6ZTogIiArCisgICAgICAgICAgICAgICAgICAgIHBvb2wuYXV0aGVudGljYXRlZENvbm5lY3Rpb25zLnNpemUoKSArIAorICAgICAgICAgICAgICAgICAgICAiICAgcG9vbCBzaXplOiAiICsgcG9vbC5wb29sU2l6ZSk7CisKKyAgICAgICAgICAgIHJldHVybiAocG9vbC5hdXRoZW50aWNhdGVkQ29ubmVjdGlvbnMuc2l6ZSgpID49IHBvb2wucG9vbFNpemUpOworCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWxlYXNlIHRoZSBwcm90b2NvbCBvYmplY3QgYmFjayB0byB0aGUgY29ubmVjdGlvbiBwb29sLgorICAgICAqLworICAgIHZvaWQgcmVsZWFzZVByb3RvY29sKElNQVBGb2xkZXIgZm9sZGVyLCBJTUFQUHJvdG9jb2wgcHJvdG9jb2wpIHsKKworICAgICAgICBzeW5jaHJvbml6ZWQgKHBvb2wpIHsKKyAgICAgICAgICAgIGlmIChwcm90b2NvbCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgLy8gSWYgdGhlIHBvb2wgaXMgbm90IGZ1bGwsIGFkZCB0aGUgc3RvcmUgYXMgYSByZXNwb25zZSBoYW5kbGVyCisgICAgICAgICAgICAgICAgLy8gYW5kIHJldHVybiB0aGUgcHJvdG9jb2wgb2JqZWN0IHRvIHRoZSBjb25uZWN0aW9uIHBvb2wuCisgICAgICAgICAgICAgICAgaWYgKCFpc0Nvbm5lY3Rpb25Qb29sRnVsbCgpKSB7CisgICAgICAgICAgICAgICAgICAgIHByb3RvY29sLmFkZFJlc3BvbnNlSGFuZGxlcih0aGlzKTsKKyAgICAgICAgICAgICAgICAgICAgcG9vbC5hdXRoZW50aWNhdGVkQ29ubmVjdGlvbnMuYWRkRWxlbWVudChwcm90b2NvbCk7CisKKwkJICAgIGlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FKSkKKyAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5maW5lKAorCQkJICAgICJhZGRlZCBhbiBBdXRoZW50aWNhdGVkIGNvbm5lY3Rpb24gLS0gc2l6ZTogIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9vbC5hdXRoZW50aWNhdGVkQ29ubmVjdGlvbnMuc2l6ZSgpKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworCQkgICAgbG9nZ2VyLmZpbmUoCisJCQkicG9vbCBpcyBmdWxsLCBub3QgYWRkaW5nIGFuIEF1dGhlbnRpY2F0ZWQgY29ubmVjdGlvbiIpOworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgcHJvdG9jb2wubG9nb3V0KCk7CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFByb3RvY29sRXhjZXB0aW9uIHBleCkge307CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAocG9vbC5mb2xkZXJzICE9IG51bGwpCisgICAgICAgICAgICAgICAgcG9vbC5mb2xkZXJzLnJlbW92ZUVsZW1lbnQoZm9sZGVyKTsKKworICAgICAgICAgICAgdGltZW91dENvbm5lY3Rpb25zKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWxlYXNlIHRoZSBzdG9yZSBjb25uZWN0aW9uLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZWxlYXNlU3RvcmVQcm90b2NvbChJTUFQUHJvdG9jb2wgcHJvdG9jb2wpIHsKKworCS8vIHdpbGwgYmUgY2FsbGVkIGZyb20gaWRsZSgpIHdpdGhvdXQgdGhlIFN0b3JlIGxvY2sgaGVsZCwKKwkvLyBidXQgY2xlYW51cCBpcyBzeW5jaHJvbml6ZWQgYW5kIHdpbGwgYWNxdWlyZSB0aGUgU3RvcmUgbG9jaworCisJaWYgKHByb3RvY29sID09IG51bGwpIHsKKwkgICAgY2xlYW51cCgpOwkJLy8gZmFpbGVkIHRvIGV2ZXIgZ2V0IHRoZSBjb25uZWN0aW9uCisJICAgIHJldHVybjsJCS8vIG5vdGhpbmcgdG8gcmVsZWFzZQorCX0KKworCS8qCisJICogUmVhZCBvdXQgdGhlIGZsYWcgdGhhdCBzYXlzIHdoZXRoZXIgdGhpcyBjb25uZWN0aW9uIGZhaWxlZAorCSAqIGJlZm9yZSByZWxlYXNpbmcgdGhlIHByb3RvY29sIG9iamVjdCBmb3Igb3RoZXJzIHRvIHVzZS4KKwkgKi8KKwlib29sZWFuIGZhaWxlZDsKKwlzeW5jaHJvbml6ZWQgKGNvbm5lY3Rpb25GYWlsZWRMb2NrKSB7CisJICAgIGZhaWxlZCA9IGNvbm5lY3Rpb25GYWlsZWQ7CisJICAgIGNvbm5lY3Rpb25GYWlsZWQgPSBmYWxzZTsJLy8gcmVzZXQgZm9yIG5leHQgdXNlCisJfQorCisJLy8gbm93IGZyZWUgdGhlIHN0b3JlIGNvbm5lY3Rpb24KKyAgICAgICAgc3luY2hyb25pemVkIChwb29sKSB7CisJICAgIHBvb2wuc3RvcmVDb25uZWN0aW9uSW5Vc2UgPSBmYWxzZTsKKwkgICAgcG9vbC5ub3RpZnlBbGwoKTsJLy8gaW4gY2FzZSBhbnlvbmUgd2FpdGluZworCisJICAgIHBvb2wubG9nZ2VyLmZpbmUoInJlbGVhc2VTdG9yZVByb3RvY29sKCkiKTsKKworICAgICAgICAgICAgdGltZW91dENvbm5lY3Rpb25zKCk7CisgICAgICAgIH0KKworCS8qCisJICogSWYgdGhlIGNvbm5lY3Rpb24gZGllZCB3aGlsZSB3ZSB3ZXJlIHVzaW5nIGl0LCBjbGVhbiB1cC4KKwkgKiBJdCdzIGNyaXRpY2FsIHRoYXQgdGhlIHN0b3JlIGNvbm5lY3Rpb24gYmUgZnJlZWQgYW5kIHRoZQorCSAqIGNvbm5lY3Rpb24gcG9vbCBub3QgYmUgbG9ja2VkIHdoaWxlIHdlIGRvIHRoaXMuCisJICovCisJYXNzZXJ0ICFUaHJlYWQuaG9sZHNMb2NrKHBvb2wpOworCWlmIChmYWlsZWQpCisJICAgIGNsZWFudXAoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWxlYXNlIGEgc3RvcmUgcHJvdG9jb2wgb2JqZWN0IHRoYXQgd2FzIGJlaW5nIHVzZWQgYnkgYSBmb2xkZXIuCisgICAgICovCisgICAgdm9pZCByZWxlYXNlRm9sZGVyU3RvcmVQcm90b2NvbChJTUFQUHJvdG9jb2wgcHJvdG9jb2wpIHsKKwlpZiAocHJvdG9jb2wgPT0gbnVsbCkKKwkgICAgcmV0dXJuOwkJLy8gc2hvdWxkIG5ldmVyIGhhcHBlbgorCXByb3RvY29sLnJlbW92ZVJlc3BvbnNlSGFuZGxlcihub25TdG9yZVJlc3BvbnNlSGFuZGxlcik7CisJcHJvdG9jb2wuYWRkUmVzcG9uc2VIYW5kbGVyKHRoaXMpOworICAgICAgICBzeW5jaHJvbml6ZWQgKHBvb2wpIHsKKwkgICAgcG9vbC5zdG9yZUNvbm5lY3Rpb25JblVzZSA9IGZhbHNlOworCSAgICBwb29sLm5vdGlmeUFsbCgpOwkvLyBpbiBjYXNlIGFueW9uZSB3YWl0aW5nCisKKwkgICAgcG9vbC5sb2dnZXIuZmluZSgicmVsZWFzZUZvbGRlclN0b3JlUHJvdG9jb2woKSIpOworCisgICAgICAgICAgICB0aW1lb3V0Q29ubmVjdGlvbnMoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEVtcHR5IHRoZSBjb25uZWN0aW9uIHBvb2wuCisgICAgICovIAorICAgIHByaXZhdGUgdm9pZCBlbXB0eUNvbm5lY3Rpb25Qb29sKGJvb2xlYW4gZm9yY2UpIHsKKworICAgICAgICBzeW5jaHJvbml6ZWQgKHBvb2wpIHsKKyAgICAgICAgICAgIGZvciAoaW50IGluZGV4ID0gcG9vbC5hdXRoZW50aWNhdGVkQ29ubmVjdGlvbnMuc2l6ZSgpIC0gMTsKKwkJICAgIGluZGV4ID49IDA7IC0taW5kZXgpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworCQkgICAgSU1BUFByb3RvY29sIHAgPQorCQkJcG9vbC5hdXRoZW50aWNhdGVkQ29ubmVjdGlvbnMuZWxlbWVudEF0KGluZGV4KTsKKwkJICAgIHAucmVtb3ZlUmVzcG9uc2VIYW5kbGVyKHRoaXMpOworCQkgICAgaWYgKGZvcmNlKQorCQkJcC5kaXNjb25uZWN0KCk7CisJCSAgICBlbHNlCisJCQlwLmxvZ291dCgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFByb3RvY29sRXhjZXB0aW9uIHBleCkge307CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHBvb2wuYXV0aGVudGljYXRlZENvbm5lY3Rpb25zLnJlbW92ZUFsbEVsZW1lbnRzKCk7CisgICAgICAgIH0KKyAgICAgICAgCisJcG9vbC5sb2dnZXIuZmluZSgicmVtb3ZlZCBhbGwgYXV0aGVudGljYXRlZCBjb25uZWN0aW9ucyBmcm9tIHBvb2wiKTsKKyAgICB9CisKKyAgICAvKiogIAorICAgICAqIENoZWNrIHRvIHNlZSBpZiBpdCdzIHRpbWUgdG8gc2hyaW5rIHRoZSBjb25uZWN0aW9uIHBvb2wuCisgICAgICovICAKKyAgICBwcml2YXRlIHZvaWQgdGltZW91dENvbm5lY3Rpb25zKCkgeworCisgICAgICAgIHN5bmNocm9uaXplZCAocG9vbCkgeworCisgICAgICAgICAgICAvLyBJZiB3ZSd2ZSBleGNlZWRlZCB0aGUgcHJ1bmluZyBpbnRlcnZhbCwgbG9vayBmb3Igc3RhbGUKKyAgICAgICAgICAgIC8vIGNvbm5lY3Rpb25zIHRvIGxvZ291dC4KKyAgICAgICAgICAgIGlmIChTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSAtIHBvb2wubGFzdFRpbWVQcnVuZWQgPiAKKyAgICAgICAgICAgICAgICBwb29sLnBydW5pbmdJbnRlcnZhbCAmJiAKKyAgICAgICAgICAgICAgICBwb29sLmF1dGhlbnRpY2F0ZWRDb25uZWN0aW9ucy5zaXplKCkgPiAxKSB7CisKKwkJaWYgKHBvb2wubG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuRklORSkpIHsKKyAgICAgICAgICAgICAgICAgICAgcG9vbC5sb2dnZXIuZmluZSgiY2hlY2tpbmcgZm9yIGNvbm5lY3Rpb25zIHRvIHBydW5lOiAiICsKKyAgICAgICAgICAgICAgICAgICAgICAgIChTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSAtIHBvb2wubGFzdFRpbWVQcnVuZWQpKTsKKyAgICAgICAgICAgICAgICAgICAgcG9vbC5sb2dnZXIuZmluZSgiY2xpZW50VGltZW91dEludGVydmFsOiAiICsKKyAgICAgICAgICAgICAgICAgICAgICAgIHBvb2wuY2xpZW50VGltZW91dEludGVydmFsKTsKKyAgICAgICAgICAgICAgICB9ICAgCisgCisgICAgICAgICAgICAgICAgSU1BUFByb3RvY29sIHA7CisgCisgICAgICAgICAgICAgICAgLy8gQ2hlY2sgdGhlIHRpbWVzdGFtcCBvZiB0aGUgcHJvdG9jb2wgb2JqZWN0cyBpbiB0aGUgcG9vbCBhbmQKKyAgICAgICAgICAgICAgICAvLyBsb2dvdXQgaWYgdGhlIGludGVydmFsIGV4Y2VlZHMgdGhlIGNsaWVudCB0aW1lb3V0IHZhbHVlCisgICAgICAgICAgICAgICAgLy8gKGxlYXZlIHRoZSBmaXJzdCBjb25uZWN0aW9uKS4KKyAgICAgICAgICAgICAgICBmb3IgKGludCBpbmRleCA9IHBvb2wuYXV0aGVudGljYXRlZENvbm5lY3Rpb25zLnNpemUoKSAtIDE7IAorICAgICAgICAgICAgICAgICAgICAgaW5kZXggPiAwOyBpbmRleC0tKSB7CisgICAgICAgICAgICAgICAgICAgIHAgPSBwb29sLmF1dGhlbnRpY2F0ZWRDb25uZWN0aW9ucy4KKyAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRBdChpbmRleCk7CisJCSAgICBpZiAocG9vbC5sb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FKSkKKyAgICAgICAgICAgICAgICAgICAgICAgIHBvb2wubG9nZ2VyLmZpbmUoInByb3RvY29sIGxhc3QgdXNlZDogIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpIC0gcC5nZXRUaW1lc3RhbXAoKSkpOworICAgICAgICAgICAgICAgICAgICBpZiAoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSBwLmdldFRpbWVzdGFtcCgpID4KKyAgICAgICAgICAgICAgICAgICAgICAgIHBvb2wuY2xpZW50VGltZW91dEludGVydmFsKSB7CisgCisJCQlwb29sLmxvZ2dlci5maW5lKAorCQkJICAgICJhdXRoZW50aWNhdGVkIGNvbm5lY3Rpb24gdGltZWQgb3V0LCAiICsKKwkJCSAgICAibG9nZ2luZyBvdXQgdGhlIGNvbm5lY3Rpb24iKTsKKyAKKyAgICAgICAgICAgICAgICAgICAgICAgIHAucmVtb3ZlUmVzcG9uc2VIYW5kbGVyKHRoaXMpOworICAgICAgICAgICAgICAgICAgICAgICAgcG9vbC5hdXRoZW50aWNhdGVkQ29ubmVjdGlvbnMucmVtb3ZlRWxlbWVudEF0KGluZGV4KTsKKworICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBwLmxvZ291dCgpOworICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoUHJvdG9jb2xFeGNlcHRpb24gcGV4KSB7fQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHBvb2wubGFzdFRpbWVQcnVuZWQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgYmxvY2sgc2l6ZSB0byB1c2UgZm9yIGZldGNoIHJlcXVlc3RzIG9uIHRoaXMgU3RvcmUuCisgICAgICovCisgICAgaW50IGdldEZldGNoQmxvY2tTaXplKCkgeworCXJldHVybiBibGtzaXplOworICAgIH0KKworICAgIC8qKgorICAgICAqIElnbm9yZSB0aGUgc2l6ZSByZXBvcnRlZCBpbiB0aGUgQk9EWVNUUlVDVFVSRSB3aGVuIGZldGNoaW5nIGRhdGE/CisgICAgICovCisgICAgYm9vbGVhbiBpZ25vcmVCb2R5U3RydWN0dXJlU2l6ZSgpIHsKKwlyZXR1cm4gaWdub3JlU2l6ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgYSByZWZlcmVuY2UgdG8gdGhlIHNlc3Npb24uCisgICAgICovCisgICAgU2Vzc2lvbiBnZXRTZXNzaW9uKCkgeworICAgICAgICByZXR1cm4gc2Vzc2lvbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgdG8gY2FjaGUgU1RBVFVTIHJlc3BvbnNlLgorICAgICAqLworICAgIGludCBnZXRTdGF0dXNDYWNoZVRpbWVvdXQoKSB7CisJcmV0dXJuIHN0YXR1c0NhY2hlVGltZW91dDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIG1heGltdW0gc2l6ZSBvZiBhIG1lc3NhZ2UgdG8gYnVmZmVyIGZvciBhcHBlbmQuCisgICAgICovCisgICAgaW50IGdldEFwcGVuZEJ1ZmZlclNpemUoKSB7CisJcmV0dXJuIGFwcGVuZEJ1ZmZlclNpemU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBtaW5pbXVtIGFtb3VudCBvZiB0aW1lIHRvIGRlbGF5IHdoZW4gcmV0dXJuaW5nIGZyb20gaWRsZS4KKyAgICAgKi8KKyAgICBpbnQgZ2V0TWluSWRsZVRpbWUoKSB7CisJcmV0dXJuIG1pbklkbGVUaW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRocm93IGEgU2VhcmNoRXhjZXB0aW9uIGlmIHRoZSBzZWFyY2ggZXhwcmVzc2lvbiBpcyB0b28gY29tcGxleD8KKyAgICAgKi8KKyAgICBib29sZWFuIHRocm93U2VhcmNoRXhjZXB0aW9uKCkgeworCXJldHVybiB0aHJvd1NlYXJjaEV4Y2VwdGlvbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGRlZmF1bHQgInBlZWsiIHZhbHVlLgorICAgICAqLworICAgIGJvb2xlYW4gZ2V0UGVlaygpIHsKKwlyZXR1cm4gcGVlazsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIGNhcGFiaWxpdHkgc3RyaW5nIGlzIGluIHRoZSBsaXN0CisgICAgICogb2YgY2FwYWJpbGl0aWVzIHRoZSBzZXJ2ZXIgYW5ub3VuY2VkLgorICAgICAqCisgICAgICogQHBhcmFtCWNhcGFiaWxpdHkJdGhlIGNhcGFiaWxpdHkgc3RyaW5nCisgICAgICogQHJldHVybgkJCXRydWUgaWYgdGhlIHNlcnZlciBzdXBwb3J0cyB0aGlzIGNhcGFiaWxpdHkKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS4zLjMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGJvb2xlYW4gaGFzQ2FwYWJpbGl0eShTdHJpbmcgY2FwYWJpbGl0eSkKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgSU1BUFByb3RvY29sIHAgPSBudWxsOworCXRyeSB7CisJICAgIHAgPSBnZXRTdG9yZVByb3RvY29sKCk7CisgICAgICAgICAgICByZXR1cm4gcC5oYXNDYXBhYmlsaXR5KGNhcGFiaWxpdHkpOworCX0gY2F0Y2ggKFByb3RvY29sRXhjZXB0aW9uIHBleCkgeworCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKHBleC5nZXRNZXNzYWdlKCksIHBleCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICByZWxlYXNlU3RvcmVQcm90b2NvbChwKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgdXNlciBuYW1lIHRvIGJlIHVzZWQgd2l0aCB0aGUgUFJPWFlBVVRIIGNvbW1hbmQuCisgICAgICogVGhlIFBST1hZQVVUSCB1c2VyIG5hbWUgY2FuIGFsc28gYmUgc2V0IHVzaW5nIHRoZQorICAgICAqIDxjb2RlPm1haWwuaW1hcC5wcm94eWF1dGgudXNlcjwvY29kZT4gcHJvcGVydHkgd2hlbiB0aGlzCisgICAgICogU3RvcmUgaXMgY3JlYXRlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbQl1c2VyCXRoZSB1c2VyIG5hbWUgdG8gc2V0CisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNS4xCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UHJveHlBdXRoVXNlcihTdHJpbmcgdXNlcikgeworCXByb3h5QXV0aFVzZXIgPSB1c2VyOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgdXNlciBuYW1lIHRvIGJlIHVzZWQgd2l0aCB0aGUgUFJPWFlBVVRIIGNvbW1hbmQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSB1c2VyIG5hbWUKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS41LjEKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFByb3h5QXV0aFVzZXIoKSB7CisJcmV0dXJuIHByb3h5QXV0aFVzZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2sgd2hldGhlciB0aGlzIHN0b3JlIGlzIGNvbm5lY3RlZC4gT3ZlcnJpZGUgc3VwZXJjbGFzcworICAgICAqIG1ldGhvZCwgdG8gYWN0dWFsbHkgcGluZyBvdXIgc2VydmVyIGNvbm5lY3Rpb24uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIGlzQ29ubmVjdGVkKCkgeworCWlmICghc3VwZXIuaXNDb25uZWN0ZWQoKSkgeworCSAgICAvLyBpZiB3ZSBoYXZlbid0IGJlZW4gY29ubmVjdGVkIGF0IGFsbCwgZG9uJ3QgYm90aGVyIHdpdGgKKwkgICAgLy8gdGhlIE5PT1AuCisJICAgIHJldHVybiBmYWxzZTsKKwl9CisKKwkvKgorCSAqIFRoZSBiZWxvdyBub29wKCkgcmVxdWVzdCBjYW46CisJICogKDEpIHN1Y2NlZWQgLSBpbiB3aGljaCBjYXNlIGFsbCBpcyBmaW5lLgorCSAqCisJICogKDIpIGZhaWwgYmVjYXVzZSB0aGUgc2VydmVyIHJldHVybnMgTk8gb3IgQkFELCBpbiB3aGljaAorCSAqIAljYXNlIHdlIGlnbm9yZSBpdCBzaW5jZSB3ZSBjYW4ndCByZWFsbHkgZG8gYW55dGhpbmcuCisJICogKDIpIGZhaWwgYmVjYXVzZSBhIEJZRSByZXNwb25zZSBpcyBvYnRhaW5lZCBmcm9tIHRoZSAKKwkgKglzZXJ2ZXIKKwkgKiAoMykgZmFpbCBiZWNhdXNlIHRoZSBzb2NrZXQud3JpdGUoKSB0byB0aGUgc2VydmVyIGZhaWxzLAorCSAqCWluIHdoaWNoIGNhc2UgdGhlIGlhcC5wcm90b2NvbCgpIGNvZGUgY29udmVydHMgdGhlCisJICoJSU9FeGNlcHRpb24gaW50byBhIEJZRSByZXNwb25zZS4KKwkgKgorCSAqIFRodXMsIG91ciBCWUUgaGFuZGxlciB3aWxsIHRha2UgY2FyZSBvZiBjbG9zaW5nIHRoZSBTdG9yZQorCSAqIGluIGNhc2Ugb3VyIGNvbm5lY3Rpb24gaXMgcmVhbGx5IGdvbmUuCisJICovCisgICAKKyAgICAgICAgSU1BUFByb3RvY29sIHAgPSBudWxsOworCXRyeSB7CisJICAgIHAgPSBnZXRTdG9yZVByb3RvY29sKCk7CisgICAgICAgICAgICBwLm5vb3AoKTsKKwl9IGNhdGNoIChQcm90b2NvbEV4Y2VwdGlvbiBwZXgpIHsKKwkgICAgLy8gd2lsbCByZXR1cm4gZmFsc2UgYmVsb3cKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHJlbGVhc2VTdG9yZVByb3RvY29sKHApOworICAgICAgICB9CisKKworCXJldHVybiBzdXBlci5pc0Nvbm5lY3RlZCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENsb3NlIHRoaXMgU3RvcmUuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGNsb3NlKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJY2xlYW51cCgpOworCS8vIGRvIHRoZXNlIGFnYWluIGluIGNhc2UgY2xlYW51cCByZXR1cm5lZCBlYXJseQorCS8vIGJlY2F1c2Ugd2Ugd2VyZSBhbHJlYWR5IGNsb3NlZCBkdWUgdG8gYSBmYWlsdXJlCisJY2xvc2VBbGxGb2xkZXJzKGZhbHNlKTsKKwllbXB0eUNvbm5lY3Rpb25Qb29sKGZhbHNlKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBmaW5hbGl6ZSgpIHRocm93cyBUaHJvd2FibGUgeworCWlmICghZmluYWxpemVDbGVhbkNsb3NlKSB7CisJICAgIC8vIHdoZW4gZmluYWxpemluZywgY2xvc2UgY29ubmVjdGlvbnMgYWJydXB0bHkKKwkgICAgc3luY2hyb25pemVkIChjb25uZWN0aW9uRmFpbGVkTG9jaykgeworCQljb25uZWN0aW9uRmFpbGVkID0gdHJ1ZTsKKwkJZm9yY2VDbG9zZSA9IHRydWU7CisJICAgIH0KKwkgICAgY2xvc2VGb2xkZXJzT25TdG9yZUZhaWx1cmUgPSB0cnVlOwkvLyBtYWtlIHN1cmUgZm9sZGVycyBnZXQgY2xvc2VkCisJfQorCXRyeSB7CisJICAgIGNsb3NlKCk7CisJfSBmaW5hbGx5IHsKKwkgICAgc3VwZXIuZmluYWxpemUoKTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xlYW51cCBiZWZvcmUgZHlpbmcuCisgICAgICovCisgICAgcHJpdmF0ZSBzeW5jaHJvbml6ZWQgdm9pZCBjbGVhbnVwKCkgeworCS8vIGlmIHdlJ3JlIG5vdCBjb25uZWN0ZWQsIHNvbWVvbmUgYmVhdCB1cyB0byBpdAorCWlmICghc3VwZXIuaXNDb25uZWN0ZWQoKSkgeworCSAgICBsb2dnZXIuZmluZSgiSU1BUFN0b3JlIGNsZWFudXAsIG5vdCBjb25uZWN0ZWQiKTsKKwkgICAgcmV0dXJuOworCX0KKworCS8qCisJICogSWYgZm9yY2VDbG9zZSBpcyB0cnVlLCBzb21lIHRocmVhZCByYW4gaW50byBhbiBlcnJvciB0aGF0IHN1Z2dlc3RzCisJICogdGhlIHNlcnZlciBtaWdodCBiZSBkZWFkLCBzbyB3ZSBmb3JjZSB0aGUgZm9sZGVycyB0byBjbG9zZQorCSAqIGFicnVwdGx5IHdpdGhvdXQgd2FpdGluZyBmb3IgdGhlIHNlcnZlci4gIFVzZWQgd2hlbgorCSAqIHRoZSBzdG9yZSBjb25uZWN0aW9uIHRpbWVzIG91dCwgZm9yIGV4YW1wbGUuCisJICovCisJYm9vbGVhbiBmb3JjZTsKKwlzeW5jaHJvbml6ZWQgKGNvbm5lY3Rpb25GYWlsZWRMb2NrKSB7CisJICAgIGZvcmNlID0gZm9yY2VDbG9zZTsKKwkgICAgZm9yY2VDbG9zZSA9IGZhbHNlOworCSAgICBjb25uZWN0aW9uRmFpbGVkID0gZmFsc2U7CisJfQorCWlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FKSkKKwkgICAgbG9nZ2VyLmZpbmUoIklNQVBTdG9yZSBjbGVhbnVwLCBmb3JjZSAiICsgZm9yY2UpOworCisJaWYgKCFmb3JjZSB8fCBjbG9zZUZvbGRlcnNPblN0b3JlRmFpbHVyZSkgeworCSAgICBjbG9zZUFsbEZvbGRlcnMoZm9yY2UpOworCX0KKworCWVtcHR5Q29ubmVjdGlvblBvb2woZm9yY2UpOworCisJLy8gdG8gc2V0IHRoZSBzdGF0ZSBhbmQgc2VuZCB0aGUgY2xvc2VkIGNvbm5lY3Rpb24gZXZlbnQKKwl0cnkgeworCSAgICBzdXBlci5jbG9zZSgpOworCX0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBtZXgpIHsKKwkgICAgLy8gaWdub3JlIGl0CisJfQorCWxvZ2dlci5maW5lKCJJTUFQU3RvcmUgY2xlYW51cCBkb25lIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2UgYWxsIG9wZW4gRm9sZGVycy4gIElmIGZvcmNlIGlzIHRydWUsIGNsb3NlIHRoZW0gZm9yY2libHkuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGNsb3NlQWxsRm9sZGVycyhib29sZWFuIGZvcmNlKSB7CisgICAgICAgIExpc3Q8SU1BUEZvbGRlcj4gZm9sZGVyc0NvcHkgPSBudWxsOworICAgICAgICBib29sZWFuIGRvbmUgPSB0cnVlOworCisJLy8gVG8gYXZvaWQgdmlvbGF0aW5nIHRoZSBsb2NraW5nIGhpZXJhcmNoeSwgdGhlcmUncyBubyBsb2NrIHdlCisJLy8gY2FuIGhvbGQgdGhhdCBwcmV2ZW50cyBhbm90aGVyIHRocmVhZCBmcm9tIHRyeWluZyB0byBvcGVuIGEKKwkvLyBmb2xkZXIgYXQgdGhlIHNhbWUgdGltZSB3ZSdyZSB0cnlpbmcgdG8gY2xvc2UgYWxsIHRoZSBmb2xkZXJzLgorCS8vIFRodXMsIHRoZXJlJ3MgYW4gaW5oZXJlbnQgcmFjZSBjb25kaXRpb24gaGVyZS4gIFdlIGNsb3NlIGFsbAorCS8vIHRoZSBmb2xkZXJzIHdlIGtub3cgYWJvdXQgYW5kIHRoZW4gY2hlY2sgd2hldGhlciBhbnkgbmV3IGZvbGRlcnMKKwkvLyBoYXZlIGJlZW4gb3BlbmVkIGluIHRoZSBtZWFuIHRpbWUuICBXZSBrZWVwIHRyeWluZyB1bnRpbCB3ZSdyZQorCS8vIHN1Y2Nlc3NmdWwgaW4gY2xvc2luZyBhbGwgdGhlIGZvbGRlcnMuCisJZm9yICg7OykgeworCSAgICAvLyBNYWtlIGEgY29weSBvZiB0aGUgZm9sZGVycyBsaXN0IHNvIHdlIGRvIG5vdCB2aW9sYXRlIHRoZQorCSAgICAvLyBmb2xkZXItY29ubmVjdGlvbiBwb29sIGxvY2tpbmcgaGllcmFyY2h5LgorCSAgICBzeW5jaHJvbml6ZWQgKHBvb2wpIHsKKwkJaWYgKHBvb2wuZm9sZGVycyAhPSBudWxsKSB7CisJCSAgICBkb25lID0gZmFsc2U7CisJCSAgICBmb2xkZXJzQ29weSA9IHBvb2wuZm9sZGVyczsKKwkJICAgIHBvb2wuZm9sZGVycyA9IG51bGw7CisJCX0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOworICAgICAgICAgICAgICAgIH0KKwkgICAgfQorCSAgICBpZiAoZG9uZSkKKwkJYnJlYWs7CisKKwkgICAgLy8gQ2xvc2UgYW5kIHJlbW92ZSBhbnkgb3BlbiBmb2xkZXJzIHVuZGVyIHRoaXMgU3RvcmUuCisJICAgIGZvciAoaW50IGkgPSAwLCBmc2l6ZSA9IGZvbGRlcnNDb3B5LnNpemUoKTsgaSA8IGZzaXplOyBpKyspIHsKKwkJSU1BUEZvbGRlciBmID0gZm9sZGVyc0NvcHkuZ2V0KGkpOworCisJCXRyeSB7CisJCSAgICBpZiAoZm9yY2UpIHsKKwkJCWxvZ2dlci5maW5lKCJmb3JjZSBmb2xkZXIgdG8gY2xvc2UiKTsKKwkJCS8vIERvbid0IHdhbnQgdG8gd2FpdCBmb3IgZm9sZGVyIGNvbm5lY3Rpb24gdG8gdGltZW91dAorCQkJLy8gKGlmLCBmb3IgZXhhbXBsZSwgdGhlIHNlcnZlciBpcyBkb3duKSBzbyB3ZSBjbG9zZQorCQkJLy8gZm9sZGVycyBhYnJ1cHRseS4KKwkJCWYuZm9yY2VDbG9zZSgpOworCQkgICAgfSBlbHNlIHsKKwkJCWxvZ2dlci5maW5lKCJjbG9zZSBmb2xkZXIiKTsKKwkJCWYuY2xvc2UoZmFsc2UpOworCQkgICAgfQorCQl9IGNhdGNoIChNZXNzYWdpbmdFeGNlcHRpb24gbWV4KSB7CisJCSAgICAvLyBXaG8gY2FyZXMgPyEgSWdub3JlICdlbS4KKwkJfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGV4KSB7CisJCSAgICAvLyBEaXR0bworCQl9CisJICAgIH0KKworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGRlZmF1bHQgZm9sZGVyLCByZXByZXNlbnRpbmcgdGhlIHJvb3Qgb2YgdGhpcyB1c2VyJ3MgCisgICAgICogbmFtZXNwYWNlLiBSZXR1cm5zIGEgY2xvc2VkIERlZmF1bHRGb2xkZXIgb2JqZWN0LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgRm9sZGVyIGdldERlZmF1bHRGb2xkZXIoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwljaGVja0Nvbm5lY3RlZCgpOworCXJldHVybiBuZXcgRGVmYXVsdEZvbGRlcih0aGlzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgbmFtZWQgZm9sZGVyLiBSZXR1cm5zIGEgbmV3LCBjbG9zZWQgSU1BUEZvbGRlci4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIEZvbGRlciBnZXRGb2xkZXIoU3RyaW5nIG5hbWUpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJY2hlY2tDb25uZWN0ZWQoKTsKKwlyZXR1cm4gbmV3SU1BUEZvbGRlcihuYW1lLCBJTUFQRm9sZGVyLlVOS05PV05fU0VQQVJBVE9SKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgbmFtZWQgZm9sZGVyLiBSZXR1cm5zIGEgbmV3LCBjbG9zZWQgSU1BUEZvbGRlci4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIEZvbGRlciBnZXRGb2xkZXIoVVJMTmFtZSB1cmwpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJY2hlY2tDb25uZWN0ZWQoKTsKKwlyZXR1cm4gbmV3SU1BUEZvbGRlcih1cmwuZ2V0RmlsZSgpLCBJTUFQRm9sZGVyLlVOS05PV05fU0VQQVJBVE9SKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYW4gSU1BUEZvbGRlciBvYmplY3QuICBJZiB1c2VyIHN1cHBsaWVkIHRoZWlyIG93biBjbGFzcywKKyAgICAgKiB1c2UgaXQuICBPdGhlcndpc2UsIGNhbGwgdGhlIGNvbnN0cnVjdG9yLgorICAgICAqCisgICAgICogQHBhcmFtCWZ1bGxOYW1lIHRoZSBmdWxsIG5hbWUgb2YgdGhlIGZvbGRlcgorICAgICAqIEBwYXJhbQlzZXBhcmF0b3IgdGhlIHNlcGFyYXRvciBjaGFyYWN0ZXIgZm9yIHRoZSBmb2xkZXIgaGllcmFyY2h5CisgICAgICogQHBhcmFtCWlzTmFtZXNwYWNlIGRvZXMgdGhpcyBuYW1lIHJlcHJlc2VudCBhIG5hbWVzcGFjZT8KKyAgICAgKiBAcmV0dXJuCQl0aGUgbmV3IElNQVBGb2xkZXIgb2JqZWN0CisgICAgICovCisgICAgcHJvdGVjdGVkIElNQVBGb2xkZXIgbmV3SU1BUEZvbGRlcihTdHJpbmcgZnVsbE5hbWUsIGNoYXIgc2VwYXJhdG9yLAorCQkJCUJvb2xlYW4gaXNOYW1lc3BhY2UpIHsKKwlJTUFQRm9sZGVyIGYgPSBudWxsOworCWlmIChmb2xkZXJDb25zdHJ1Y3RvciAhPSBudWxsKSB7CisJICAgIHRyeSB7CisJCU9iamVjdFtdIG8gPQorCQkgIHsgZnVsbE5hbWUsIENoYXJhY3Rlci52YWx1ZU9mKHNlcGFyYXRvciksIHRoaXMsIGlzTmFtZXNwYWNlIH07CisJCWYgPSAoSU1BUEZvbGRlcilmb2xkZXJDb25zdHJ1Y3Rvci5uZXdJbnN0YW5jZShvKTsKKwkgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJCWxvZ2dlci5sb2coTGV2ZWwuRklORSwKKwkJCSAgICAiZXhjZXB0aW9uIGNyZWF0aW5nIElNQVBGb2xkZXIgY2xhc3MiLCBleCk7CisJICAgIH0KKwl9CisJaWYgKGYgPT0gbnVsbCkKKwkgICAgZiA9IG5ldyBJTUFQRm9sZGVyKGZ1bGxOYW1lLCBzZXBhcmF0b3IsIHRoaXMsIGlzTmFtZXNwYWNlKTsKKwlyZXR1cm4gZjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYW4gSU1BUEZvbGRlciBvYmplY3QuICBDYWxsIHRoZSBuZXdJTUFQRm9sZGVyIG1ldGhvZAorICAgICAqIGFib3ZlIHdpdGggYSBudWxsIGlzTmFtZXNwYWNlLgorICAgICAqCisgICAgICogQHBhcmFtCWZ1bGxOYW1lIHRoZSBmdWxsIG5hbWUgb2YgdGhlIGZvbGRlcgorICAgICAqIEBwYXJhbQlzZXBhcmF0b3IgdGhlIHNlcGFyYXRvciBjaGFyYWN0ZXIgZm9yIHRoZSBmb2xkZXIgaGllcmFyY2h5CisgICAgICogQHJldHVybgkJdGhlIG5ldyBJTUFQRm9sZGVyIG9iamVjdAorICAgICAqLworICAgIHByb3RlY3RlZCBJTUFQRm9sZGVyIG5ld0lNQVBGb2xkZXIoU3RyaW5nIGZ1bGxOYW1lLCBjaGFyIHNlcGFyYXRvcikgeworCXJldHVybiBuZXdJTUFQRm9sZGVyKGZ1bGxOYW1lLCBzZXBhcmF0b3IsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhbiBJTUFQRm9sZGVyIG9iamVjdC4gIElmIHVzZXIgc3VwcGxpZWQgdGhlaXIgb3duIGNsYXNzLAorICAgICAqIHVzZSBpdC4gIE90aGVyd2lzZSwgY2FsbCB0aGUgY29uc3RydWN0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0JbGkJdGhlIExpc3RJbmZvIGZvciB0aGUgZm9sZGVyCisgICAgICogQHJldHVybgkJdGhlIG5ldyBJTUFQRm9sZGVyIG9iamVjdAorICAgICAqLworICAgIHByb3RlY3RlZCBJTUFQRm9sZGVyIG5ld0lNQVBGb2xkZXIoTGlzdEluZm8gbGkpIHsKKwlJTUFQRm9sZGVyIGYgPSBudWxsOworCWlmIChmb2xkZXJDb25zdHJ1Y3RvckxJICE9IG51bGwpIHsKKwkgICAgdHJ5IHsKKwkJT2JqZWN0W10gbyA9IHsgbGksIHRoaXMgfTsKKwkJZiA9IChJTUFQRm9sZGVyKWZvbGRlckNvbnN0cnVjdG9yTEkubmV3SW5zdGFuY2Uobyk7CisJICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCQlsb2dnZXIubG9nKExldmVsLkZJTkUsCisJCQkiZXhjZXB0aW9uIGNyZWF0aW5nIElNQVBGb2xkZXIgY2xhc3MgTEkiLCBleCk7CisJICAgIH0KKwl9CisJaWYgKGYgPT0gbnVsbCkKKwkgICAgZiA9IG5ldyBJTUFQRm9sZGVyKGxpLCB0aGlzKTsKKwlyZXR1cm4gZjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVc2luZyB0aGUgSU1BUCBOQU1FU1BBQ0UgY29tbWFuZCAoUkZDIDIzNDIpLCByZXR1cm4gYSBzZXQKKyAgICAgKiBvZiBmb2xkZXJzIHJlcHJlc2VudGluZyB0aGUgUGVyc29uYWwgbmFtZXNwYWNlcy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRm9sZGVyW10gZ2V0UGVyc29uYWxOYW1lc3BhY2VzKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJTmFtZXNwYWNlcyBucyA9IGdldE5hbWVzcGFjZXMoKTsKKwlpZiAobnMgPT0gbnVsbCB8fCBucy5wZXJzb25hbCA9PSBudWxsKQorCSAgICByZXR1cm4gc3VwZXIuZ2V0UGVyc29uYWxOYW1lc3BhY2VzKCk7CisJcmV0dXJuIG5hbWVzcGFjZVRvRm9sZGVycyhucy5wZXJzb25hbCwgbnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVXNpbmcgdGhlIElNQVAgTkFNRVNQQUNFIGNvbW1hbmQgKFJGQyAyMzQyKSwgcmV0dXJuIGEgc2V0CisgICAgICogb2YgZm9sZGVycyByZXByZXNlbnRpbmcgdGhlIFVzZXIncyBuYW1lc3BhY2VzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBGb2xkZXJbXSBnZXRVc2VyTmFtZXNwYWNlcyhTdHJpbmcgdXNlcikKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlOYW1lc3BhY2VzIG5zID0gZ2V0TmFtZXNwYWNlcygpOworCWlmIChucyA9PSBudWxsIHx8IG5zLm90aGVyVXNlcnMgPT0gbnVsbCkKKwkgICAgcmV0dXJuIHN1cGVyLmdldFVzZXJOYW1lc3BhY2VzKHVzZXIpOworCXJldHVybiBuYW1lc3BhY2VUb0ZvbGRlcnMobnMub3RoZXJVc2VycywgdXNlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogVXNpbmcgdGhlIElNQVAgTkFNRVNQQUNFIGNvbW1hbmQgKFJGQyAyMzQyKSwgcmV0dXJuIGEgc2V0CisgICAgICogb2YgZm9sZGVycyByZXByZXNlbnRpbmcgdGhlIFNoYXJlZCBuYW1lc3BhY2VzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBGb2xkZXJbXSBnZXRTaGFyZWROYW1lc3BhY2VzKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJTmFtZXNwYWNlcyBucyA9IGdldE5hbWVzcGFjZXMoKTsKKwlpZiAobnMgPT0gbnVsbCB8fCBucy5zaGFyZWQgPT0gbnVsbCkKKwkgICAgcmV0dXJuIHN1cGVyLmdldFNoYXJlZE5hbWVzcGFjZXMoKTsKKwlyZXR1cm4gbmFtZXNwYWNlVG9Gb2xkZXJzKG5zLnNoYXJlZCwgbnVsbCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzeW5jaHJvbml6ZWQgTmFtZXNwYWNlcyBnZXROYW1lc3BhY2VzKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJY2hlY2tDb25uZWN0ZWQoKTsKKworICAgICAgICBJTUFQUHJvdG9jb2wgcCA9IG51bGw7CisKKwlpZiAobmFtZXNwYWNlcyA9PSBudWxsKSB7CisJICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcCA9IGdldFN0b3JlUHJvdG9jb2woKTsKKwkJbmFtZXNwYWNlcyA9IHAubmFtZXNwYWNlKCk7CisJICAgIH0gY2F0Y2ggKEJhZENvbW1hbmRFeGNlcHRpb24gYmV4KSB7IAorCQkvLyBOQU1FU1BBQ0Ugbm90IHN1cHBvcnRlZCwgaWdub3JlIGl0CisJICAgIH0gY2F0Y2ggKENvbm5lY3Rpb25FeGNlcHRpb24gY2V4KSB7CisJCXRocm93IG5ldyBTdG9yZUNsb3NlZEV4Y2VwdGlvbih0aGlzLCBjZXguZ2V0TWVzc2FnZSgpKTsKKwkgICAgfSBjYXRjaCAoUHJvdG9jb2xFeGNlcHRpb24gcGV4KSB7IAorCQl0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKHBleC5nZXRNZXNzYWdlKCksIHBleCk7CisJICAgIH0gZmluYWxseSB7CisJCXJlbGVhc2VTdG9yZVByb3RvY29sKHApOworCSAgICB9CisJfQorCXJldHVybiBuYW1lc3BhY2VzOworICAgIH0KKworICAgIHByaXZhdGUgRm9sZGVyW10gbmFtZXNwYWNlVG9Gb2xkZXJzKE5hbWVzcGFjZXMuTmFtZXNwYWNlW10gbnMsCisJCQkJCVN0cmluZyB1c2VyKSB7CisJRm9sZGVyW10gZmEgPSBuZXcgRm9sZGVyW25zLmxlbmd0aF07CisJZm9yIChpbnQgaSA9IDA7IGkgPCBmYS5sZW5ndGg7IGkrKykgeworCSAgICBTdHJpbmcgbmFtZSA9IG5zW2ldLnByZWZpeDsKKwkgICAgaWYgKHVzZXIgPT0gbnVsbCkgeworCQkvLyBzdHJpcCB0cmFpbGluZyBkZWxpbWl0ZXIKKwkJaW50IGxlbiA9IG5hbWUubGVuZ3RoKCk7CisJCWlmICggbGVuID4gMCAmJiBuYW1lLmNoYXJBdChsZW4gLSAxKSA9PSBuc1tpXS5kZWxpbWl0ZXIpCisJCSAgICBuYW1lID0gbmFtZS5zdWJzdHJpbmcoMCwgbGVuIC0gMSk7CisJICAgIH0gZWxzZSB7CisJCS8vIGFkZCB1c2VyCisJCW5hbWUgKz0gdXNlcjsKKwkgICAgfQorCSAgICBmYVtpXSA9IG5ld0lNQVBGb2xkZXIobmFtZSwgbnNbaV0uZGVsaW1pdGVyLAorCQkJCQlCb29sZWFuLnZhbHVlT2YodXNlciA9PSBudWxsKSk7CisJfQorCXJldHVybiBmYTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIHF1b3RhcyBmb3IgdGhlIG5hbWVkIHF1b3RhIHJvb3QuCisgICAgICogUXVvdGFzIGFyZSBjb250cm9sbGVkIG9uIHRoZSBiYXNpcyBvZiBhIHF1b3RhIHJvb3QsIG5vdAorICAgICAqIChuZWNlc3NhcmlseSkgYSBmb2xkZXIuICBUaGUgcmVsYXRpb25zaGlwIGJldHdlZW4gZm9sZGVycworICAgICAqIGFuZCBxdW90YSByb290cyBkZXBlbmRzIG9uIHRoZSBJTUFQIHNlcnZlci4gIFNvbWUgc2VydmVycworICAgICAqIG1pZ2h0IGltcGxlbWVudCBhIHNpbmdsZSBxdW90YSByb290IGZvciBhbGwgZm9sZGVycyBvd25lZCBieQorICAgICAqIGEgdXNlci4gIE90aGVyIHNlcnZlcnMgbWlnaHQgaW1wbGVtZW50IGEgc2VwYXJhdGUgcXVvdGEgcm9vdAorICAgICAqIGZvciBlYWNoIGZvbGRlci4gIEEgc2luZ2xlIGZvbGRlciBjYW4gZXZlbiBoYXZlIG11bHRpcGxlCisgICAgICogcXVvdGEgcm9vdHMsIHBlcmhhcHMgY29udHJvbGxpbmcgcXVvdGFzIGZvciBkaWZmZXJlbnQKKyAgICAgKiByZXNvdXJjZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jcm9vdAl0aGUgbmFtZSBvZiB0aGUgcXVvdGEgcm9vdAorICAgICAqIEByZXR1cm4JCWFycmF5IG9mIFF1b3RhIG9iamVjdHMKKyAgICAgKiBAZXhjZXB0aW9uIE1lc3NhZ2luZ0V4Y2VwdGlvbglpZiB0aGUgc2VydmVyIGRvZXNuJ3Qgc3VwcG9ydCB0aGUKKyAgICAgKgkJCQkJUVVPVEEgZXh0ZW5zaW9uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBRdW90YVtdIGdldFF1b3RhKFN0cmluZyByb290KQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWNoZWNrQ29ubmVjdGVkKCk7CisJUXVvdGFbXSBxYSA9IG51bGw7CisKKyAgICAgICAgSU1BUFByb3RvY29sIHAgPSBudWxsOworCXRyeSB7CisJICAgIHAgPSBnZXRTdG9yZVByb3RvY29sKCk7CisJICAgIHFhID0gcC5nZXRRdW90YVJvb3Qocm9vdCk7CisJfSBjYXRjaCAoQmFkQ29tbWFuZEV4Y2VwdGlvbiBiZXgpIHsKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiUVVPVEEgbm90IHN1cHBvcnRlZCIsIGJleCk7CisJfSBjYXRjaCAoQ29ubmVjdGlvbkV4Y2VwdGlvbiBjZXgpIHsKKwkgICAgdGhyb3cgbmV3IFN0b3JlQ2xvc2VkRXhjZXB0aW9uKHRoaXMsIGNleC5nZXRNZXNzYWdlKCkpOworCX0gY2F0Y2ggKFByb3RvY29sRXhjZXB0aW9uIHBleCkgeworCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKHBleC5nZXRNZXNzYWdlKCksIHBleCk7CisJfSBmaW5hbGx5IHsKKwkgICAgcmVsZWFzZVN0b3JlUHJvdG9jb2wocCk7CisJfQorCXJldHVybiBxYTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHF1b3RhcyBmb3IgdGhlIHF1b3RhIHJvb3Qgc3BlY2lmaWVkIGluIHRoZSBxdW90YSBhcmd1bWVudC4KKyAgICAgKiBUeXBpY2FsbHkgdGhpcyB3aWxsIGJlIG9uZSBvZiB0aGUgcXVvdGEgcm9vdHMgb2J0YWluZWQgZnJvbSB0aGUKKyAgICAgKiA8Y29kZT5nZXRRdW90YTwvY29kZT4gbWV0aG9kLCBidXQgaXQgbmVlZCBub3QgYmUuCisgICAgICoKKyAgICAgKiBAcGFyYW0JcXVvdGEJdGhlIHF1b3RhIHRvIHNldAorICAgICAqIEBleGNlcHRpb24gTWVzc2FnaW5nRXhjZXB0aW9uCWlmIHRoZSBzZXJ2ZXIgZG9lc24ndCBzdXBwb3J0IHRoZQorICAgICAqCQkJCQlRVU9UQSBleHRlbnNpb24KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgc2V0UXVvdGEoUXVvdGEgcXVvdGEpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWNoZWNrQ29ubmVjdGVkKCk7CisgICAgICAgIElNQVBQcm90b2NvbCBwID0gbnVsbDsKKwl0cnkgeworCSAgICBwID0gZ2V0U3RvcmVQcm90b2NvbCgpOworCSAgICBwLnNldFF1b3RhKHF1b3RhKTsKKwl9IGNhdGNoIChCYWRDb21tYW5kRXhjZXB0aW9uIGJleCkgeworCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKCJRVU9UQSBub3Qgc3VwcG9ydGVkIiwgYmV4KTsKKwl9IGNhdGNoIChDb25uZWN0aW9uRXhjZXB0aW9uIGNleCkgeworCSAgICB0aHJvdyBuZXcgU3RvcmVDbG9zZWRFeGNlcHRpb24odGhpcywgY2V4LmdldE1lc3NhZ2UoKSk7CisJfSBjYXRjaCAoUHJvdG9jb2xFeGNlcHRpb24gcGV4KSB7CisJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24ocGV4LmdldE1lc3NhZ2UoKSwgcGV4KTsKKwl9IGZpbmFsbHkgeworCSAgICByZWxlYXNlU3RvcmVQcm90b2NvbChwKTsKKwl9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrQ29ubmVjdGVkKCkgeworCWFzc2VydCBUaHJlYWQuaG9sZHNMb2NrKHRoaXMpOworCWlmICghc3VwZXIuaXNDb25uZWN0ZWQoKSkKKwkgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiTm90IGNvbm5lY3RlZCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlc3BvbnNlIGhhbmRsZXIgbWV0aG9kLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGhhbmRsZVJlc3BvbnNlKFJlc3BvbnNlIHIpIHsKKwkvLyBBbnkgb2YgdGhlc2UgcmVzcG9uc2VzIG1heSBoYXZlIGEgcmVzcG9uc2UgY29kZS4KKwlpZiAoci5pc09LKCkgfHwgci5pc05PKCkgfHwgci5pc0JBRCgpIHx8IHIuaXNCWUUoKSkKKwkgICAgaGFuZGxlUmVzcG9uc2VDb2RlKHIpOworCWlmIChyLmlzQllFKCkpIHsKKwkgICAgbG9nZ2VyLmZpbmUoIklNQVBTdG9yZSBjb25uZWN0aW9uIGRlYWQiKTsKKwkgICAgLy8gU3RvcmUncyBJTUFQIGNvbm5lY3Rpb24gaXMgZGVhZCwgc2F2ZSB0aGUgcmVzcG9uc2Ugc28gdGhhdAorCSAgICAvLyByZWxlYXNlU3RvcmVQcm90b2NvbCB3aWxsIGNsZWFudXAgbGF0ZXIuCisJICAgIHN5bmNocm9uaXplZCAoY29ubmVjdGlvbkZhaWxlZExvY2spIHsKKwkJY29ubmVjdGlvbkZhaWxlZCA9IHRydWU7CisJCWlmIChyLmlzU3ludGhldGljKCkpCisJCSAgICBmb3JjZUNsb3NlID0gdHJ1ZTsKKwkgICAgfQorCSAgICByZXR1cm47CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFVzZSB0aGUgSU1BUCBJRExFIGNvbW1hbmQgKHNlZQorICAgICAqIDxBIEhSRUY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIxNzcudHh0Ij5SRkMgMjE3NzwvQT4pLAorICAgICAqIGlmIHN1cHBvcnRlZCBieSB0aGUgc2VydmVyLCB0byBlbnRlciBpZGxlIG1vZGUgc28gdGhhdCB0aGUgc2VydmVyCisgICAgICogY2FuIHNlbmQgdW5zb2xpY2l0ZWQgbm90aWZpY2F0aW9ucworICAgICAqIHdpdGhvdXQgdGhlIG5lZWQgZm9yIHRoZSBjbGllbnQgdG8gY29uc3RhbnRseSBwb2xsIHRoZSBzZXJ2ZXIuCisgICAgICogVXNlIGEgPGNvZGU+Q29ubmVjdGlvbkxpc3RlbmVyPC9jb2RlPiB0byBiZSBub3RpZmllZCBvZgorICAgICAqIGV2ZW50cy4gIFdoZW4gYW5vdGhlciB0aHJlYWQgKGUuZy4sIHRoZSBsaXN0ZW5lciB0aHJlYWQpCisgICAgICogbmVlZHMgdG8gaXNzdWUgYW4gSU1BUCBjb21hbmQgZm9yIHRoaXMgU3RvcmUsIHRoZSBpZGxlIG1vZGUgd2lsbAorICAgICAqIGJlIHRlcm1pbmF0ZWQgYW5kIHRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuLiAgVHlwaWNhbGx5IHRoZSBjYWxsZXIKKyAgICAgKiB3aWxsIGludm9rZSB0aGlzIG1ldGhvZCBpbiBhIGxvb3AuIDxwPgorICAgICAqCisgICAgICogSWYgdGhlIG1haWwuaW1hcC5lbmFibGVpbWFwZXZlbnRzIHByb3BlcnR5IGlzIHNldCwgbm90aWZpY2F0aW9ucworICAgICAqIHJlY2VpdmVkIHdoaWxlIHRoZSBJRExFIGNvbW1hbmQgaXMgYWN0aXZlIHdpbGwgYmUgZGVsaXZlcmVkIHRvCisgICAgICogPGNvZGU+Q29ubmVjdGlvbkxpc3RlbmVyPC9jb2RlPnMgYXMgZXZlbnRzIHdpdGggYSB0eXBlIG9mCisgICAgICogPGNvZGU+SU1BUFN0b3JlLlJFU1BPTlNFPC9jb2RlPi4gIFRoZSBldmVudCdzIG1lc3NhZ2Ugd2lsbCBiZQorICAgICAqIHRoZSByYXcgSU1BUCByZXNwb25zZSBzdHJpbmcuCisgICAgICogTm90ZSB0aGF0IG1vc3QgSU1BUCBzZXJ2ZXJzIHdpbGwgbm90IGRlbGl2ZXIgYW55IGV2ZW50cyB3aGVuCisgICAgICogdXNpbmcgdGhlIElETEUgY29tbWFuZCBvbiBhIGNvbm5lY3Rpb24gd2l0aCBubyBtYWlsYm94IHNlbGVjdGVkCisgICAgICogKGkuZS4sIHRoaXMgbWV0aG9kKS4gIEluIG1vc3QgY2FzZXMgeW91J2xsIHdhbnQgdG8gdXNlIHRoZQorICAgICAqIDxjb2RlPmlkbGU8L2NvZGU+IG1ldGhvZCBvbiA8Y29kZT5JTUFQRm9sZGVyPC9jb2RlPi4gPHA+CisgICAgICoKKyAgICAgKiBOT1RFOiBUaGlzIGNhcGFiaWxpdHkgaXMgaGlnaGx5IGV4cGVyaW1lbnRhbCBhbmQgbGlrZWx5IHdpbGwgY2hhbmdlCisgICAgICogaW4gZnV0dXJlIHJlbGVhc2VzLiA8cD4KKyAgICAgKgorICAgICAqIFRoZSBtYWlsLmltYXAubWluaWRsZXRpbWUgcHJvcGVydHkgZW5mb3JjZXMgYSBtaW5pbXVtIGRlbGF5CisgICAgICogYmVmb3JlIHJldHVybmluZyBmcm9tIHRoaXMgbWV0aG9kLCB0byBlbnN1cmUgdGhhdCBvdGhlciB0aHJlYWRzCisgICAgICogaGF2ZSBhIGNoYW5jZSB0byBpc3N1ZSBjb21tYW5kcyBiZWZvcmUgdGhlIGNhbGxlciBpbnZva2VzIHRoaXMKKyAgICAgKiBtZXRob2QgYWdhaW4uICBUaGUgZGVmYXVsdCBkZWxheSBpcyAxMCBtaWxsaXNlY29uZHMuCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uIE1lc3NhZ2luZ0V4Y2VwdGlvbglpZiB0aGUgc2VydmVyIGRvZXNuJ3Qgc3VwcG9ydCB0aGUKKyAgICAgKgkJCQkJSURMRSBleHRlbnNpb24KKyAgICAgKiBAZXhjZXB0aW9uIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbglpZiB0aGUgc3RvcmUgaXNuJ3QgY29ubmVjdGVkCisgICAgICoKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS40LjEKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBpZGxlKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJSU1BUFByb3RvY29sIHAgPSBudWxsOworCS8vIEFTU0VSVDogTXVzdCBOT1QgYmUgY2FsbGVkIHdpdGggdGhlIGNvbm5lY3Rpb24gcG9vbAorCS8vIHN5bmNocm9uaXphdGlvbiBsb2NrIGhlbGQuCisJYXNzZXJ0ICFUaHJlYWQuaG9sZHNMb2NrKHBvb2wpOworCXN5bmNocm9uaXplZCAodGhpcykgeworCSAgICBjaGVja0Nvbm5lY3RlZCgpOworCX0KKwlib29sZWFuIG5lZWROb3RpZmljYXRpb24gPSBmYWxzZTsKKwl0cnkgeworCSAgICBzeW5jaHJvbml6ZWQgKHBvb2wpIHsKKwkJcCA9IGdldFN0b3JlUHJvdG9jb2woKTsKKwkJaWYgKHBvb2wuaWRsZVN0YXRlICE9IENvbm5lY3Rpb25Qb29sLlJVTk5JTkcpIHsKKwkJICAgIC8vIHNvbWUgb3RoZXIgdGhyZWFkIG11c3QgYmUgcnVubmluZyB0aGUgSURMRQorCQkgICAgLy8gY29tbWFuZCwgd2UnbGwganVzdCB3YWl0IGZvciBpdCB0byBmaW5pc2gKKwkJICAgIC8vIHdpdGhvdXQgYWJvcnRpbmcgaXQgb3Vyc2VsdmVzCisJCSAgICB0cnkgeworCQkJLy8gZ2l2ZSB1cCBsb2NrIGFuZCB3YWl0IHRvIGJlIG5vdCBpZGxlCisJCQlwb29sLndhaXQoKTsKKwkJICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGV4KSB7CisJCQkvLyByZXN0b3JlIHRoZSBpbnRlcnJ1cHRlZCBzdGF0ZSwgd2hpY2ggY2FsbGVycyBtaWdodAorCQkJLy8gZGVwZW5kIG9uCisJCQlUaHJlYWQuY3VycmVudFRocmVhZCgpLmludGVycnVwdCgpOworCQkJLy8gc3RvcCB3YWl0aW5nIGFuZCByZXR1cm4gdG8gY2FsbGVyCisJCQl0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKCJpZGxlIGludGVycnVwdGVkIiwgZXgpOworCQkgICAgfQorCQkgICAgcmV0dXJuOworCQl9CisJCXAuaWRsZVN0YXJ0KCk7CisJCW5lZWROb3RpZmljYXRpb24gPSB0cnVlOworCQlwb29sLmlkbGVTdGF0ZSA9IENvbm5lY3Rpb25Qb29sLklETEU7CisJCXBvb2wuaWRsZVByb3RvY29sID0gcDsKKwkgICAgfQorCisJICAgIC8qCisJICAgICAqIFdlIGdhdmUgdXAgdGhlIHBvb2wgbG9jayBzbyB0aGF0IG90aGVyIHRocmVhZHMKKwkgICAgICogY2FuIGdldCBpbnRvIHRoZSBwb29sIGZhciBlbm91Z2ggdG8gc2VlIHRoYXQgd2UncmUKKwkgICAgICogaW4gSURMRSBhbmQgYWJvcnQgdGhlIElETEUuCisJICAgICAqCisJICAgICAqIE5vdyB3ZSByZWFkIHJlc3BvbnNlcyBmcm9tIHRoZSBJRExFIGNvbW1hbmQsIGVzcGVjaWFsbHkKKwkgICAgICogaW5jbHVkaW5nIHVuc29saWNpdGVkIG5vdGlmaWNhdGlvbnMgZnJvbSB0aGUgc2VydmVyLgorCSAgICAgKiBXZSBkb24ndCBob2xkIHRoZSBwb29sIGxvY2sgd2hpbGUgcmVhZGluZyBiZWNhdXNlCisJICAgICAqIGl0IHByb3RlY3RzIHRoZSBpZGxlU3RhdGUgYW5kIG90aGVyIHRocmVhZHMgbmVlZCB0byBiZQorCSAgICAgKiBhYmxlIHRvIGV4YW1pbmUgdGhlIHN0YXRlLgorCSAgICAgKgorCSAgICAgKiBXZSBob2xkIHRoZSBwb29sIGxvY2sgd2hpbGUgcHJvY2Vzc2luZyB0aGUgcmVzcG9uc2VzLgorCSAgICAgKi8KKwkgICAgZm9yICg7OykgeworCQlSZXNwb25zZSByID0gcC5yZWFkSWRsZVJlc3BvbnNlKCk7CisJCXN5bmNocm9uaXplZCAocG9vbCkgeworCQkgICAgaWYgKHIgPT0gbnVsbCB8fCAhcC5wcm9jZXNzSWRsZVJlc3BvbnNlKHIpKSB7CisJCQlwb29sLmlkbGVTdGF0ZSA9IENvbm5lY3Rpb25Qb29sLlJVTk5JTkc7CisJCQlwb29sLmlkbGVQcm90b2NvbCA9IG51bGw7CisJCQlwb29sLm5vdGlmeUFsbCgpOworCQkJbmVlZE5vdGlmaWNhdGlvbiA9IGZhbHNlOworCQkJYnJlYWs7CisJCSAgICB9CisJCX0KKwkJaWYgKGVuYWJsZUltYXBFdmVudHMgJiYgci5pc1VuVGFnZ2VkKCkpIHsKKwkJICAgIG5vdGlmeVN0b3JlTGlzdGVuZXJzKElNQVBTdG9yZS5SRVNQT05TRSwgci50b1N0cmluZygpKTsKKwkJfQorCSAgICB9CisKKwkgICAgLyoKKwkgICAgICogRW5mb3JjZSBhIG1pbmltdW0gZGVsYXkgdG8gZ2l2ZSB0aW1lIHRvIHRocmVhZHMKKwkgICAgICogcHJvY2Vzc2luZyB0aGUgcmVzcG9uc2VzIHRoYXQgY2FtZSBpbiB3aGlsZSB3ZQorCSAgICAgKiB3ZXJlIGlkbGUuCisJICAgICAqLworCSAgICBpbnQgbWluaWRsZSA9IGdldE1pbklkbGVUaW1lKCk7CisJICAgIGlmIChtaW5pZGxlID4gMCkgeworCQl0cnkgeworCQkgICAgVGhyZWFkLnNsZWVwKG1pbmlkbGUpOworCQl9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBleCkgeworCQkgICAgLy8gcmVzdG9yZSB0aGUgaW50ZXJydXB0ZWQgc3RhdGUsIHdoaWNoIGNhbGxlcnMgbWlnaHQKKwkJICAgIC8vIGRlcGVuZCBvbgorCQkgICAgVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5pbnRlcnJ1cHQoKTsKKwkJfQorCSAgICB9CisKKwl9IGNhdGNoIChCYWRDb21tYW5kRXhjZXB0aW9uIGJleCkgeworCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKCJJRExFIG5vdCBzdXBwb3J0ZWQiLCBiZXgpOworCX0gY2F0Y2ggKENvbm5lY3Rpb25FeGNlcHRpb24gY2V4KSB7CisJICAgIHRocm93IG5ldyBTdG9yZUNsb3NlZEV4Y2VwdGlvbih0aGlzLCBjZXguZ2V0TWVzc2FnZSgpKTsKKwl9IGNhdGNoIChQcm90b2NvbEV4Y2VwdGlvbiBwZXgpIHsKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbihwZXguZ2V0TWVzc2FnZSgpLCBwZXgpOworCX0gZmluYWxseSB7CisJICAgIGlmIChuZWVkTm90aWZpY2F0aW9uKSB7CisJCXN5bmNocm9uaXplZCAocG9vbCkgeworCQkgICAgcG9vbC5pZGxlU3RhdGUgPSBDb25uZWN0aW9uUG9vbC5SVU5OSU5HOworCQkgICAgcG9vbC5pZGxlUHJvdG9jb2wgPSBudWxsOworCQkgICAgcG9vbC5ub3RpZnlBbGwoKTsKKwkJfQorCSAgICB9CisJICAgIHJlbGVhc2VTdG9yZVByb3RvY29sKHApOworCX0KKyAgICB9CisKKyAgICAvKgorICAgICAqIElmIGFuIElETEUgY29tbWFuZCBpcyBpbiBwcm9ncmVzcywgYWJvcnQgaXQgaWYgbmVjZXNzYXJ5LAorICAgICAqIGFuZCB3YWl0IHVudGlsIGl0IGNvbXBsZXRlcy4KKyAgICAgKiBBU1NFUlQ6IE11c3QgYmUgY2FsbGVkIHdpdGggdGhlIHBvb2wncyBsb2NrIGhlbGQuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHdhaXRJZklkbGUoKSB0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCWFzc2VydCBUaHJlYWQuaG9sZHNMb2NrKHBvb2wpOworCXdoaWxlIChwb29sLmlkbGVTdGF0ZSAhPSBDb25uZWN0aW9uUG9vbC5SVU5OSU5HKSB7CisJICAgIGlmIChwb29sLmlkbGVTdGF0ZSA9PSBDb25uZWN0aW9uUG9vbC5JRExFKSB7CisJCXBvb2wuaWRsZVByb3RvY29sLmlkbGVBYm9ydCgpOworCQlwb29sLmlkbGVTdGF0ZSA9IENvbm5lY3Rpb25Qb29sLkFCT1JUSU5HOworCSAgICB9CisJICAgIHRyeSB7CisJCS8vIGdpdmUgdXAgbG9jayBhbmQgd2FpdCB0byBiZSBub3QgaWRsZQorCQlwb29sLndhaXQoKTsKKwkgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZXgpIHsKKwkJLy8gSWYgc29tZW9uZSBpcyB0cnlpbmcgdG8gaW50ZXJydXB0IHVzIHdlIGNhbid0IGtlZXAgZ29pbmcKKwkJLy8gYXJvdW5kIHRoZSBsb29wIHdhaXRpbmcgZm9yIElETEUgdG8gY29tcGxldGUsIGJ1dCB3ZSBjYW4ndAorCQkvLyBqdXN0IHJldHVybiBiZWNhdXNlIGNhbGxlcnMgZXhwZWN0IHRoZSBpZGxlU3RhdGUgdG8gYmUKKwkJLy8gUlVOTklORyB3aGVuIHdlIHJldHVybi4gIFRocm93aW5nIHRoaXMgZXhjZXB0aW9uIHNlZW1zCisJCS8vIGxpa2UgdGhlIGJlc3QgY2hvaWNlLgorCQl0aHJvdyBuZXcgUHJvdG9jb2xFeGNlcHRpb24oIkludGVycnVwdGVkIHdhaXRJZklkbGUiLCBleCk7CisJICAgIH0KKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VuZCB0aGUgSU1BUCBJRCBjb21tYW5kIChpZiBzdXBwb3J0ZWQgYnkgdGhlIHNlcnZlcikgYW5kIHJldHVybgorICAgICAqIHRoZSByZXN1bHQgZnJvbSB0aGUgc2VydmVyLiAgVGhlIElEIGNvbW1hbmQgaWRlbnRmaWVzIHRoZSBjbGllbnQKKyAgICAgKiB0byB0aGUgc2VydmVyIGFuZCByZXR1cm5zIGluZm9ybWF0aW9uIGFib3V0IHRoZSBzZXJ2ZXIgdG8gdGhlIGNsaWVudC4KKyAgICAgKiBTZWUgPEEgSFJFRj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjk3MS50eHQiPlJGQyAyOTcxPC9BPi4KKyAgICAgKiBUaGUgcmV0dXJuZWQgTWFwIGlzIHVubW9kaWZpYWJsZS4KKyAgICAgKgorICAgICAqIEBwYXJhbQljbGllbnRQYXJhbXMJYSBNYXAgb2Yga2V5cyBhbmQgdmFsdWVzIGlkZW50aWZ5aW5nIHRoZSBjbGllbnQKKyAgICAgKiBAcmV0dXJuCQkJYSBNYXAgb2Yga2V5cyBhbmQgdmFsdWVzIGlkZW50aWZ5aW5nIHRoZSBzZXJ2ZXIKKyAgICAgKiBAZXhjZXB0aW9uIE1lc3NhZ2luZ0V4Y2VwdGlvbglpZiB0aGUgc2VydmVyIGRvZXNuJ3Qgc3VwcG9ydCB0aGUKKyAgICAgKgkJCQkJSUQgZXh0ZW5zaW9uCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNS4xCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBNYXA8U3RyaW5nLCBTdHJpbmc+IGlkKE1hcDxTdHJpbmcsIFN0cmluZz4gY2xpZW50UGFyYW1zKQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWNoZWNrQ29ubmVjdGVkKCk7CisJTWFwPFN0cmluZywgU3RyaW5nPiBzZXJ2ZXJQYXJhbXMgPSBudWxsOworCisgICAgICAgIElNQVBQcm90b2NvbCBwID0gbnVsbDsKKwl0cnkgeworCSAgICBwID0gZ2V0U3RvcmVQcm90b2NvbCgpOworCSAgICBzZXJ2ZXJQYXJhbXMgPSBwLmlkKGNsaWVudFBhcmFtcyk7CisJfSBjYXRjaCAoQmFkQ29tbWFuZEV4Y2VwdGlvbiBiZXgpIHsKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiSUQgbm90IHN1cHBvcnRlZCIsIGJleCk7CisJfSBjYXRjaCAoQ29ubmVjdGlvbkV4Y2VwdGlvbiBjZXgpIHsKKwkgICAgdGhyb3cgbmV3IFN0b3JlQ2xvc2VkRXhjZXB0aW9uKHRoaXMsIGNleC5nZXRNZXNzYWdlKCkpOworCX0gY2F0Y2ggKFByb3RvY29sRXhjZXB0aW9uIHBleCkgeworCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKHBleC5nZXRNZXNzYWdlKCksIHBleCk7CisJfSBmaW5hbGx5IHsKKwkgICAgcmVsZWFzZVN0b3JlUHJvdG9jb2wocCk7CisJfQorCXJldHVybiBzZXJ2ZXJQYXJhbXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogSGFuZGxlIG5vdGlmaWNhdGlvbnMgYW5kIGFsZXJ0cy4KKyAgICAgKiBSZXNwb25zZSBtdXN0IGJlIGFuIE9LLCBOTywgQkFELCBvciBCWUUgcmVzcG9uc2UuCisgICAgICovCisgICAgdm9pZCBoYW5kbGVSZXNwb25zZUNvZGUoUmVzcG9uc2UgcikgeworCWlmIChlbmFibGVSZXNwb25zZUV2ZW50cykKKwkgICAgbm90aWZ5U3RvcmVMaXN0ZW5lcnMoSU1BUFN0b3JlLlJFU1BPTlNFLCByLnRvU3RyaW5nKCkpOworCVN0cmluZyBzID0gci5nZXRSZXN0KCk7CS8vIGdldCB0aGUgdGV4dCBhZnRlciB0aGUgcmVzcG9uc2UKKwlib29sZWFuIGlzQWxlcnQgPSBmYWxzZTsKKwlpZiAocy5zdGFydHNXaXRoKCJbIikpIHsJLy8gYSByZXNwb25zZSBjb2RlCisJICAgIGludCBpID0gcy5pbmRleE9mKCddJyk7CisJICAgIC8vIHJlbWVtYmVyIGlmIGl0J3MgYW4gYWxlcnQKKwkgICAgaWYgKGkgPiAwICYmIHMuc3Vic3RyaW5nKDAsIGkgKyAxKS5lcXVhbHNJZ25vcmVDYXNlKCJbQUxFUlRdIikpCisJCWlzQWxlcnQgPSB0cnVlOworCSAgICAvLyBzdHJpcCBvZmYgdGhlIHJlc3BvbnNlIGNvZGUgaW4gYW55IGV2ZW50CisJICAgIHMgPSBzLnN1YnN0cmluZyhpICsgMSkudHJpbSgpOworCX0KKwlpZiAoaXNBbGVydCkKKwkgICAgbm90aWZ5U3RvcmVMaXN0ZW5lcnMoU3RvcmVFdmVudC5BTEVSVCwgcyk7CisJZWxzZSBpZiAoci5pc1VuVGFnZ2VkKCkgJiYgcy5sZW5ndGgoKSA+IDApCisJICAgIC8vIE9ubHkgc2VuZCBub3RpZmljYXRpb25zIHRoYXQgY29tZSB3aXRoIHVudGFnZ2VkCisJICAgIC8vIHJlc3BvbnNlcywgYW5kIG9ubHkgaWYgdGhlcmUgaXMgYWN0dWFsbHkgc29tZQorCSAgICAvLyB0ZXh0IHRoZXJlLgorCSAgICBub3RpZnlTdG9yZUxpc3RlbmVycyhTdG9yZUV2ZW50Lk5PVElDRSwgcyk7CisgICAgfQorCisgICAgcHJpdmF0ZSBTdHJpbmcgdHJhY2VVc2VyKFN0cmluZyB1c2VyKSB7CisJcmV0dXJuIGRlYnVndXNlcm5hbWUgPyB1c2VyIDogIjx1c2VyIG5hbWUgc3VwcHJlc3NlZD4iOworICAgIH0KKworICAgIHByaXZhdGUgU3RyaW5nIHRyYWNlUGFzc3dvcmQoU3RyaW5nIHBhc3N3b3JkKSB7CisJcmV0dXJuIGRlYnVncGFzc3dvcmQgPyBwYXNzd29yZCA6CisJCQkJKHBhc3N3b3JkID09IG51bGwgPyAiPG51bGw+IiA6ICI8bm9uLW51bGw+Iik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0lkbGVNYW5hZ2VyLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvSWRsZU1hbmFnZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ODFmNThkCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0lkbGVNYW5hZ2VyLmphdmEKQEAgLTAsMCArMSw0OTEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMTQsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmltYXA7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW50ZXJydXB0ZWRJT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXQ7CitpbXBvcnQgamF2YS5uaW8uKjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy4qOworaW1wb3J0IGphdmEudXRpbC4qOworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLio7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQ29uY3VycmVudExpbmtlZFF1ZXVlOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dG9yOworCitpbXBvcnQgamF2YXgubWFpbC4qOworCitpbXBvcnQgY29tLnN1bi5tYWlsLmltYXAucHJvdG9jb2wuSU1BUFByb3RvY29sOworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLk1haWxMb2dnZXI7CisKKy8qKgorICogSWRsZU1hbmFnZXIgdXNlcyB0aGUgb3B0aW9uYWwgSU1BUCBJRExFIGNvbW1hbmQKKyAqICg8QSBIUkVGPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMTc3LnR4dCI+UkZDIDIxNzc8L0E+KQorICogdG8gd2F0Y2ggbXVsdGlwbGUgZm9sZGVycyBmb3IgbmV3IG1lc3NhZ2VzLgorICogSWRsZU1hbmFnZXIgdXNlcyBhbiBFeGVjdXRvciB0byBleGVjdXRlIHRhc2tzIGluIHNlcGFyYXRlIHRocmVhZHMuCisgKiBBbiBFeGVjdXRvciBpcyB0eXBpY2FsbHkgcHJvdmlkZWQgYnkgYW4gRXhlY3V0b3JTZXJ2aWNlLgorICogRm9yIGV4YW1wbGUsIGZvciBhIEphdmEgU0UgYXBwbGljYXRpb246CisgKiA8YmxvY2txdW90ZT48cHJlPgorICoJRXhlY3V0b3JTZXJ2aWNlIGVzID0gRXhlY3V0b3JzLm5ld0NhY2hlZFRocmVhZFBvb2woKTsKKyAqCWZpbmFsIElkbGVNYW5hZ2VyIGlkbGVNYW5hZ2VyID0gbmV3IElkbGVNYW5hZ2VyKHNlc3Npb24sIGVzKTsKKyAqIDwvcHJlPjwvYmxvY2txdW90ZT4KKyAqIEZvciBhIEphdmEgRUUgNyBhcHBsaWNhdGlvbjoKKyAqIDxibG9ja3F1b3RlPjxwcmU+CisgKgl7QGxpdGVyYWwgQH1SZXNvdXJjZQorICoJTWFuYWdlZEV4ZWN1dG9yU2VydmljZSBlczsKKyAqCWZpbmFsIElkbGVNYW5hZ2VyIGlkbGVNYW5hZ2VyID0gbmV3IElkbGVNYW5hZ2VyKHNlc3Npb24sIGVzKTsKKyAqIDwvcHJlPjwvYmxvY2txdW90ZT4KKyAqIFRvIHdhdGNoIGZvciBuZXcgbWVzc2FnZXMgaW4gYSBmb2xkZXIsIG9wZW4gdGhlIGZvbGRlciwgcmVnaXN0ZXIgYSBsaXN0ZW5lciwKKyAqIGFuZCBhc2sgdGhlIElkbGVNYW5hZ2VyIHRvIHdhdGNoIHRoZSBmb2xkZXI6CisgKiA8YmxvY2txdW90ZT48cHJlPgorICoJRm9sZGVyIGZvbGRlciA9IHN0b3JlLmdldEZvbGRlcigiSU5CT1giKTsKKyAqCWZvbGRlci5vcGVuKEZvbGRlci5SRUFEX1dSSVRFKTsKKyAqCWZvbGRlci5hZGRNZXNzYWdlQ291bnRMaXN0ZW5lcihuZXcgTWVzc2FnZUNvdW50QWRhcHRlcigpIHsKKyAqCSAgICBwdWJsaWMgdm9pZCBtZXNzYWdlc0FkZGVkKE1lc3NhZ2VDb3VudEV2ZW50IGV2KSB7CisgKgkJRm9sZGVyIGZvbGRlciA9IChGb2xkZXIpZXYuZ2V0U291cmNlKCk7CisgKgkJTWVzc2FnZVtdIG1zZ3MgPSBldi5nZXRNZXNzYWdlcygpOworICoJCVN5c3RlbS5vdXQucHJpbnRsbigiRm9sZGVyOiAiICsgZm9sZGVyICsKKyAqCQkgICAgIiBnb3QgIiArIG1zZ3MubGVuZ3RoICsgIiBuZXcgbWVzc2FnZXMiKTsKKyAqCQl0cnkgeworICoJCSAgICAvLyBwcm9jZXNzIG5ldyBtZXNzYWdlcworICoJCSAgICBpZGxlTWFuYWdlci53YXRjaChmb2xkZXIpOyAvLyBrZWVwIHdhdGNoaW5nIGZvciBuZXcgbWVzc2FnZXMKKyAqCQl9IGNhdGNoIChNZXNzYWdpbmdFeGNlcHRpb24gbWV4KSB7CisgKgkJICAgIC8vIGhhbmRsZSBleGNlcHRpb24gcmVsYXRlZCB0byB0aGUgRm9sZGVyCisgKgkJfQorICoJICAgIH0KKyAqCX0pOworICoJaWRsZU1hbmFnZXIud2F0Y2goZm9sZGVyKTsKKyAqIDwvcHJlPjwvYmxvY2txdW90ZT4KKyAqIFRoaXMgZGVsaXZlcnMgdGhlIGV2ZW50cyBmb3IgZWFjaCBmb2xkZXIgaW4gYSBzZXBhcmF0ZSB0aHJlYWQsIDxiPk5PVDwvYj4KKyAqIHVzaW5nIHRoZSBFeGVjdXRvci4gIFRvIGRlbGl2ZXIgYWxsIGV2ZW50cyBpbiBhIHNpbmdsZSB0aHJlYWQKKyAqIHVzaW5nIHRoZSBFeGVjdXRvciwgc2V0IHRoZSBmb2xsb3dpbmcgcHJvcGVydGllcyBmb3IgdGhlIFNlc3Npb24KKyAqIChvbmNlKSwgYW5kIHRoZW4gYWRkIGxpc3RlbmVycyBhbmQgd2F0Y2ggdGhlIGZvbGRlciBhcyBhYm92ZS4KKyAqIDxibG9ja3F1b3RlPjxwcmU+CisgKgkvLyB0aGUgZm9sbG93aW5nIHNob3VsZCBiZSBkb25lIG9uY2UuLi4KKyAqCVByb3BlcnRpZXMgcHJvcHMgPSBzZXNzaW9uLmdldFByb3BlcnRpZXMoKTsKKyAqCXByb3BzLnB1dCgibWFpbC5ldmVudC5zY29wZSIsICJzZXNzaW9uIik7IC8vIG9yICJhcHBsaWNhdGlvbiIKKyAqCXByb3BzLnB1dCgibWFpbC5ldmVudC5leGVjdXRvciIsIGVzKTsKKyAqIDwvcHJlPjwvYmxvY2txdW90ZT4KKyAqIE5vdGUgdGhhdCwgYWZ0ZXIgcHJvY2Vzc2luZyBuZXcgbWVzc2FnZXMgaW4geW91ciBsaXN0ZW5lciwgb3IgZG9pbmcgYW55CisgKiBvdGhlciBvcGVyYXRpb25zIG9uIHRoZSBmb2xkZXIgaW4gYW55IG90aGVyIHRocmVhZCwgeW91IG5lZWQgdG8gdGVsbAorICogdGhlIElkbGVNYW5hZ2VyIHRvIHdhdGNoIGZvciBtb3JlIG5ldyBtZXNzYWdlcy4gIFVubGVzcywgb2YgY291cnNlLCB5b3UKKyAqIGNsb3NlIHRoZSBmb2xkZXIuCisgKiA8cD4KKyAqIFRoZSBJZGxlTWFuYWdlciBpcyBjcmVhdGVkIHdpdGggYSBTZXNzaW9uLCB3aGljaCBpdCB1c2VzIG9ubHkgdG8gY29udHJvbAorICogZGVidWcgb3V0cHV0LiAgQSBzaW5nbGUgSWRsZU1hbmFnZXIgaW5zdGFuY2UgY2FuIHdhdGNoIG11bHRpcGxlIEZvbGRlcnMKKyAqIGZyb20gbXVsdGlwbGUgU3RvcmVzIGFuZCBtdWx0aXBsZSBTZXNzaW9ucy4KKyAqIDxwPgorICogRHVlIHRvIGxpbWl0YXRpb25zIGluIHRoZSBKYXZhIFNFIG5pbyBzdXBwb3J0LCBhCisgKiB7QGxpbmsgamF2YS5uaW8uY2hhbm5lbHMuU29ja2V0Q2hhbm5lbCBTb2NrZXRDaGFubmVsfSBtdXN0IGJlIHVzZWQgaW5zdGVhZAorICogb2YgYSB7QGxpbmsgamF2YS5uZXQuU29ja2V0IFNvY2tldH0gdG8gY29ubmVjdCB0byB0aGUgc2VydmVyLiAgSG93ZXZlciwKKyAqIFNvY2tldENoYW5uZWxzIGRvbid0IHN1cHBvcnQgYWxsIHRoZSBmZWF0dXJlcyBvZiBTb2NrZXRzLCBzdWNoIGFzIGNvbm5lY3RpbmcKKyAqIHRocm91Z2ggYSBTT0NLUyBwcm94eSBzZXJ2ZXIuICBTb2NrZXRDaGFubmVscyBhbHNvIGRvbid0IHN1cHBvcnQKKyAqIHNpbXVsdGFuZW91cyByZWFkIGFuZCB3cml0ZSwgd2hpY2ggbWVhbnMgdGhhdCB0aGUKKyAqIHtAbGluayBjb20uc3VuLm1haWwuaW1hcC5JTUFQRm9sZGVyI2lkbGUgaWRsZX0gbWV0aG9kIGNhbid0IGJlIHVzZWQgaWYKKyAqIFNvY2tldENoYW5uZWxzIGFyZSBiZWluZyB1c2VkOyB1c2UgdGhpcyBJZGxlTWFuYWdlciBpbnN0ZWFkLgorICogVG8gZW5hYmxlIHN1cHBvcnQgZm9yIFNvY2tldENoYW5uZWxzIGluc3RlYWQgb2YgU29ja2V0cywgc2V0IHRoZQorICogPGNvZGU+bWFpbC5pbWFwLnVzZXNvY2tldGNoYW5uZWxzPC9jb2RlPiBwcm9wZXJ0eSBpbiB0aGUgU2Vzc2lvbiB1c2VkIHRvCisgKiBhY2Nlc3MgdGhlIElNQVAgRm9sZGVyLiAgKE9yIDxjb2RlPm1haWwuaW1hcHMudXNlc29ja2V0Y2hhbm5lbHM8L2NvZGU+IGlmCisgKiB5b3UncmUgdXNpbmcgdGhlICJpbWFwcyIgcHJvdG9jb2wuKSAgVGhpcyB3aWxsIGVmZmVjdCBhbGwgY29ubmVjdGlvbnMgaW4KKyAqIHRoYXQgU2Vzc2lvbiwgYnV0IHlvdSBjYW4gY3JlYXRlIGFub3RoZXIgU2Vzc2lvbiB3aXRob3V0IHRoaXMgcHJvcGVydHkgc2V0CisgKiBpZiB5b3UgbmVlZCB0byB1c2UgdGhlIGZlYXR1cmVzIHRoYXQgYXJlIGluY29tcGF0aWJsZSB3aXRoIFNvY2tldENoYW5uZWxzLgorICogPHA+CisgKiBOT1RFOiBUaGUgSWRsZU1hbmFnZXIsIGFuZCBhbGwgQVBJcyBhbmQgcHJvcGVydGllcyByZWxhdGVkIHRvIGl0LCBzaG91bGQKKyAqIGJlIGNvbnNpZGVyZWQgPHN0cm9uZz5FWFBFUklNRU5UQUw8L3N0cm9uZz4uICBUaGV5IG1heSBiZSBjaGFuZ2VkIGluIHRoZQorICogZnV0dXJlIGluIHdheXMgdGhhdCBhcmUgaW5jb21wYXRpYmxlIHdpdGggYXBwbGljYXRpb25zIHVzaW5nIHRoZQorICogY3VycmVudCBBUElzLgorICoKKyAqIEBzaW5jZSBKYXZhTWFpbCAxLjUuMgorICovCitwdWJsaWMgY2xhc3MgSWRsZU1hbmFnZXIgeworICAgIHByaXZhdGUgRXhlY3V0b3IgZXM7CisgICAgcHJpdmF0ZSBTZWxlY3RvciBzZWxlY3RvcjsKKyAgICBwcml2YXRlIE1haWxMb2dnZXIgbG9nZ2VyOworICAgIHByaXZhdGUgdm9sYXRpbGUgYm9vbGVhbiBkaWUgPSBmYWxzZTsKKyAgICBwcml2YXRlIHZvbGF0aWxlIGJvb2xlYW4gcnVubmluZzsKKyAgICBwcml2YXRlIFF1ZXVlPElNQVBGb2xkZXI+IHRvV2F0Y2ggPSBuZXcgQ29uY3VycmVudExpbmtlZFF1ZXVlPD4oKTsKKyAgICBwcml2YXRlIFF1ZXVlPElNQVBGb2xkZXI+IHRvQWJvcnQgPSBuZXcgQ29uY3VycmVudExpbmtlZFF1ZXVlPD4oKTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhbiBJZGxlTWFuYWdlci4gIFRoZSBTZXNzaW9uIGlzIHVzZWQgb25seSB0byBjb25maWd1cmUKKyAgICAgKiBkZWJ1Z2dpbmcgb3V0cHV0LiAgVGhlIEV4ZWN1dG9yIGlzIHVzZWQgdG8gY3JlYXRlIHRoZQorICAgICAqICJzZWxlY3QiIHRocmVhZC4KKyAgICAgKgorICAgICAqIEBwYXJhbQlzZXNzaW9uCXRoZSBTZXNzaW9uIGNvbnRhaW5pbmcgY29uZmlndXJhdGlvbiBpbmZvcm1hdGlvbgorICAgICAqIEBwYXJhbQllcwl0aGUgRXhlY3V0b3IgdXNlZCB0byBjcmVhdGUgdGhyZWFkcworICAgICAqIEBleGNlcHRpb24JSU9FeGNlcHRpb24JZm9yIFNlbGVjdG9yIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIElkbGVNYW5hZ2VyKFNlc3Npb24gc2Vzc2lvbiwgRXhlY3V0b3IgZXMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJdGhpcy5lcyA9IGVzOworCWxvZ2dlciA9IG5ldyBNYWlsTG9nZ2VyKHRoaXMuZ2V0Q2xhc3MoKSwgIkRFQlVHIElNQVAiLAorCQkJCXNlc3Npb24uZ2V0RGVidWcoKSwgc2Vzc2lvbi5nZXREZWJ1Z091dCgpKTsKKwlzZWxlY3RvciA9IFNlbGVjdG9yLm9wZW4oKTsKKwllcy5leGVjdXRlKG5ldyBSdW5uYWJsZSgpIHsKKwkgICAgQE92ZXJyaWRlCisJICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKwkJbG9nZ2VyLmZpbmUoIklkbGVNYW5hZ2VyIHNlbGVjdCBzdGFydGluZyIpOworCQl0cnkgeworCQkgICAgcnVubmluZyA9IHRydWU7CisJCSAgICBzZWxlY3QoKTsKKwkJfSBmaW5hbGx5IHsKKwkJICAgIHJ1bm5pbmcgPSBmYWxzZTsKKwkJICAgIGxvZ2dlci5maW5lKCJJZGxlTWFuYWdlciBzZWxlY3QgdGVybWluYXRpbmciKTsKKwkJfQorCSAgICB9CisJfSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSXMgdGhlIElkbGVNYW5hZ2VyIGN1cnJlbnRseSBydW5uaW5nPyAgVGhlIElkbGVNYW5hZ2VyIHN0YXJ0cworICAgICAqIHJ1bm5pbmcgd2hlbiB0aGUgRXhlY3V0b3Igc2NoZWR1bGVzIGl0cyB0YXNrLiAgVGhlIElkbGVNYW5hZ2VyCisgICAgICogc3RvcHMgcnVubmluZyBhZnRlciBpdHMgdGFzayBkZXRlY3RzIHRoZSBzdG9wIHJlcXVlc3QgZnJvbSB0aGUKKyAgICAgKiB7QGxpbmsgI3N0b3Agc3RvcH0gbWV0aG9kLCBvciBpZiBpdCB0ZXJtaW5hdGVzIGFibm9ybWFsbHkgZHVlCisgICAgICogdG8gYW4gdW5leHBlY3RlZCBlcnJvci4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdHJ1ZSBpZiB0aGUgSWRsZU1hYW5nZXIgaXMgcnVubmluZworICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjUuNQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzUnVubmluZygpIHsKKwlyZXR1cm4gcnVubmluZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXYXRjaCB0aGUgRm9sZGVyIGZvciBuZXcgbWVzc2FnZXMgYW5kIG90aGVyIGV2ZW50cyB1c2luZyB0aGUgSU1BUCBJRExFCisgICAgICogY29tbWFuZC4KKyAgICAgKgorICAgICAqIEBwYXJhbQlmb2xkZXIJdGhlIGZvbGRlciB0byB3YXRjaAorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uCWZvciBlcnJvcnMgcmVsYXRlZCB0byB0aGUgZm9sZGVyCisgICAgICovCisgICAgcHVibGljIHZvaWQgd2F0Y2goRm9sZGVyIGZvbGRlcikKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpZiAoZGllKQkvLyBYWFggLSBzaG91bGQgYmUgSWxsZWdhbFN0YXRlRXhjZXB0aW9uPworCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKCJJZGxlTWFuYWdlciBpcyBub3QgcnVubmluZyIpOworCWlmICghKGZvbGRlciBpbnN0YW5jZW9mIElNQVBGb2xkZXIpKQorCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKCJDYW4gb25seSB3YXRjaCBJTUFQIGZvbGRlcnMiKTsKKwlJTUFQRm9sZGVyIGlmb2xkZXIgPSAoSU1BUEZvbGRlcilmb2xkZXI7CisJU29ja2V0Q2hhbm5lbCBzYyA9IGlmb2xkZXIuZ2V0Q2hhbm5lbCgpOworCWlmIChzYyA9PSBudWxsKSB7CisJICAgIGlmIChmb2xkZXIuaXNPcGVuKCkpCisJCXRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oCisJCQkJCSJGb2xkZXIgaXMgbm90IHVzaW5nIFNvY2tldENoYW5uZWxzIik7CisJICAgIGVsc2UKKwkJdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiRm9sZGVyIGlzIG5vdCBvcGVuIik7CisJfQorCWlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FU1QpKQorCSAgICBsb2dnZXIubG9nKExldmVsLkZJTkVTVCwgIklkbGVNYW5hZ2VyIHdhdGNoaW5nIHswfSIsCisJCQkJCQkJZm9sZGVyTmFtZShpZm9sZGVyKSk7CisJLy8ga2VlcCB0cnlpbmcgdG8gc3RhcnQgdGhlIElETEUgY29tbWFuZCB1bnRpbCB3ZSdyZSBzdWNjZXNzZnVsLgorCS8vIG1heSBibG9jayBpZiB3ZSdyZSBpbiB0aGUgbWlkZGxlIG9mIGFib3J0aW5nIGFuIElETEUgY29tbWFuZC4KKwlpbnQgdHJpZXMgPSAwOworCXdoaWxlICghaWZvbGRlci5zdGFydElkbGUodGhpcykpIHsKKwkgICAgaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkVTVCkpCisJCWxvZ2dlci5sb2coTGV2ZWwuRklORVNULAorCQkJICAgICJJZGxlTWFuYWdlci53YXRjaCBzdGFydElkbGUgZmFpbGVkIGZvciB7MH0iLAorCQkJICAgIGZvbGRlck5hbWUoaWZvbGRlcikpOworCSAgICB0cmllcysrOworCX0KKwlpZiAobG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuRklORVNUKSkgeworCSAgICBpZiAodHJpZXMgPiAwKQorCQlsb2dnZXIubG9nKExldmVsLkZJTkVTVCwKKwkJCSJJZGxlTWFuYWdlci53YXRjaCBzdGFydElkbGUgc3VjY2VlZGVkIGZvciB7MH0iICsKKwkJCSIgYWZ0ZXIgIiArIHRyaWVzICsgIiB0cmllcyIsCisJCQlmb2xkZXJOYW1lKGlmb2xkZXIpKTsKKwkgICAgZWxzZQorCQlsb2dnZXIubG9nKExldmVsLkZJTkVTVCwKKwkJCSJJZGxlTWFuYWdlci53YXRjaCBzdGFydElkbGUgc3VjY2VlZGVkIGZvciB7MH0iLAorCQkJZm9sZGVyTmFtZShpZm9sZGVyKSk7CisJfQorCXN5bmNocm9uaXplZCAodGhpcykgeworCSAgICB0b1dhdGNoLmFkZChpZm9sZGVyKTsKKwkgICAgc2VsZWN0b3Iud2FrZXVwKCk7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlcXVlc3QgdGhhdCB0aGUgc3BlY2lmaWVkIGZvbGRlciBhYm9ydCBhbiBJRExFIGNvbW1hbmQuCisgICAgICogV2UgY2FuJ3QgZG8gdGhlIGFib3J0IGRpcmVjdGx5IGJlY2F1c2UgdGhlIERPTkUgbWVzc2FnZSBuZWVkcworICAgICAqIHRvIGJlIHNlbnQgdGhyb3VnaCB0aGUgKHBvdGVudGlhbGx5KSBTU0wgc29ja2V0LCB3aGljaCBtZWFucworICAgICAqIHdlIG5lZWQgdG8gYmUgaW4gYmxvY2tpbmcgSS9PIG1vZGUuICBXZSBjYW4gb25seSBzd2l0Y2ggdG8KKyAgICAgKiBibG9ja2luZyBJL08gbW9kZSB3aGVuIG5vdCBzZWxlY3RpbmcsIHNvIHdha2UgdXAgdGhlIHNlbGVjdG9yLAorICAgICAqIHdoaWNoIHdpbGwgcHJvY2VzcyB0aGlzIHJlcXVlc3Qgd2hlbiBpdCB3YWtlcyB1cC4KKyAgICAgKi8KKyAgICB2b2lkIHJlcXVlc3RBYm9ydChJTUFQRm9sZGVyIGZvbGRlcikgeworCXRvQWJvcnQuYWRkKGZvbGRlcik7CisJc2VsZWN0b3Iud2FrZXVwKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUnVuIHRoZSB7QGxpbmsgamF2YS5uaW8uY2hhbm5lbHMuU2VsZWN0b3Ijc2VsZWN0IHNlbGVjdH0gbG9vcAorICAgICAqIHRvIHBvbGwgZWFjaCB3YXRjaGVkIGZvbGRlciBmb3IgZXZlbnRzIHNlbnQgZnJvbSB0aGUgc2VydmVyLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBzZWxlY3QoKSB7CisJZGllID0gZmFsc2U7CisJdHJ5IHsKKwkgICAgd2hpbGUgKCFkaWUpIHsKKwkJd2F0Y2hBbGwoKTsKKwkJbG9nZ2VyLmZpbmVzdCgiSWRsZU1hbmFnZXIgd2FpdGluZy4uLiIpOworCQlpbnQgbnMgPSBzZWxlY3Rvci5zZWxlY3QoKTsKKwkJaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkVTVCkpCisJCSAgICBsb2dnZXIubG9nKExldmVsLkZJTkVTVCwKKwkJCSJJZGxlTWFuYWdlciBzZWxlY3RlZCB7MH0gY2hhbm5lbHMiLCBucyk7CisJCWlmIChkaWUgfHwgVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5pc0ludGVycnVwdGVkKCkpCisJCSAgICBicmVhazsKKworCQkvKgorCQkgKiBQcm9jZXNzIGFueSBzZWxlY3RlZCBmb2xkZXJzLiAgV2UgY2FuY2VsIHRoZQorCQkgKiBzZWxlY3Rpb24ga2V5IGZvciBhbnkgc2VsZWN0ZWQgZm9sZGVyLCBzbyBpZiB3ZQorCQkgKiBuZWVkIHRvIGNvbnRpbnVlIHdhdGNoaW5nIHRoYXQgZm9sZGVyIGl0J3MgYWRkZWQKKwkJICogdG8gdGhlIHRvV2F0Y2ggbGlzdCBhZ2Fpbi4gIFdlIGNhbid0IGFjdHVhbGx5CisJCSAqIHJlZ2lzdGVyIHRoYXQgZm9sZGVyIGFnYWluIHVudGlsIHRoZSBwcmV2aW91cworCQkgKiBzZWxlY3Rpb24ga2V5IGlzIGNhbmNlbGxlZCwgc28gd2UgY2FsbCBzZWxlY3ROb3coKQorCQkgKiBqdXN0IGZvciB0aGUgc2lkZSBlZmZlY3Qgb2YgY2FuY2VsbGluZyB0aGUgc2VsZWN0aW9uCisJCSAqIGtleXMuICBCdXQgaWYgc2VsZWN0Tm93KCkgc2VsZWN0cyBzb21ldGhpbmcsIHdlCisJCSAqIHByb2Nlc3MgaXQgYmVmb3JlIGFkZGluZyBmb2xkZXJzIGZyb20gdGhlIHRvV2F0Y2gKKwkJICogcXVldWUuICBBbmQgc28gb24gdW50aWwgdGhlcmUgaXMgbm90aGluZyB0byBkbywgYXQKKwkJICogd2hpY2ggcG9pbnQgaXQncyBzYWZlIHRvIHJlZ2lzdGVyIGZvbGRlcnMgZnJvbSB0aGUKKwkJICogdG9XYXRjaCBxdWV1ZS4gIFRoaXMgc2hvdWxkIGJlICJmYWlyIiBzaW5jZSBlYWNoCisJCSAqIHNlbGVjdGlvbiBrZXkgaXMgdXNlZCBvbmx5IG9uY2UgYmVmb3JlIGJlaW5nIGFkZGVkCisJCSAqIHRvIHRoZSB0b1dhdGNoIGxpc3QuCisJCSAqLworCQlkbyB7CisJCSAgICBwcm9jZXNzS2V5cygpOworCQl9IHdoaWxlIChzZWxlY3Rvci5zZWxlY3ROb3coKSA+IDAgfHwgIXRvQWJvcnQuaXNFbXB0eSgpKTsKKwkgICAgfQorCX0gY2F0Y2ggKEludGVycnVwdGVkSU9FeGNlcHRpb24gZXgpIHsKKwkgICAgbG9nZ2VyLmxvZyhMZXZlbC5GSU5FU1QsICJJZGxlTWFuYWdlciBpbnRlcnJ1cHRlZCIsIGV4KTsKKwl9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworCSAgICBsb2dnZXIubG9nKExldmVsLkZJTkVTVCwgIklkbGVNYW5hZ2VyIGdvdCBJL08gZXhjZXB0aW9uIiwgZXgpOworCX0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCSAgICBsb2dnZXIubG9nKExldmVsLkZJTkVTVCwgIklkbGVNYW5hZ2VyIGdvdCBleGNlcHRpb24iLCBleCk7CisJfSBmaW5hbGx5IHsKKwkgICAgZGllID0gdHJ1ZTsJLy8gcHJldmVudCBuZXcgd2F0Y2hlcyBpbiBjYXNlIG9mIGV4Y2VwdGlvbgorCSAgICBsb2dnZXIuZmluZXN0KCJJZGxlTWFuYWdlciB1bndhdGNoQWxsIik7CisJICAgIHRyeSB7CisJCXVud2F0Y2hBbGwoKTsKKwkJc2VsZWN0b3IuY2xvc2UoKTsKKwkgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgyKSB7CisJCS8vIG5vdGhpbmcgdG8gZG8uLi4KKwkJbG9nZ2VyLmxvZyhMZXZlbC5GSU5FU1QsICJJZGxlTWFuYWdlciB1bndhdGNoIGV4Y2VwdGlvbiIsIGV4Mik7CisJICAgIH0KKwkgICAgbG9nZ2VyLmZpbmUoIklkbGVNYW5hZ2VyIGV4aXRpbmciKTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVnaXN0ZXIgYWxsIG9mIHRoZSBmb2xkZXJzIGluIHRoZSBxdWV1ZSB3aXRoIHRoZSBzZWxlY3RvciwKKyAgICAgKiBzd2l0Y2hpbmcgdGhlbSB0byBub25ibG9ja2luZyBJL08gbW9kZSBmaXJzdC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgd2F0Y2hBbGwoKSB7CisJLyoKKwkgKiBQdWxsIGVhY2ggb2YgdGhlIGZvbGRlcnMgZnJvbSB0aGUgdG9XYXRjaCBxdWV1ZQorCSAqIGFuZCByZWdpc3RlciBpdC4KKwkgKi8KKwlJTUFQRm9sZGVyIGZvbGRlcjsKKwl3aGlsZSAoKGZvbGRlciA9IHRvV2F0Y2gucG9sbCgpKSAhPSBudWxsKSB7CisJICAgIGlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FU1QpKQorCQlsb2dnZXIubG9nKExldmVsLkZJTkVTVCwKKwkJICAgICJJZGxlTWFuYWdlciBhZGRpbmcgezB9IHRvIHNlbGVjdG9yIiwgZm9sZGVyTmFtZShmb2xkZXIpKTsKKwkgICAgdHJ5IHsKKwkJU29ja2V0Q2hhbm5lbCBzYyA9IGZvbGRlci5nZXRDaGFubmVsKCk7CisJCWlmIChzYyA9PSBudWxsKQorCQkgICAgY29udGludWU7CisJCS8vIGhhcyB0byBiZSBub24tYmxvY2tpbmcgdG8gc2VsZWN0CisJCXNjLmNvbmZpZ3VyZUJsb2NraW5nKGZhbHNlKTsKKwkJc2MucmVnaXN0ZXIoc2VsZWN0b3IsIFNlbGVjdGlvbktleS5PUF9SRUFELCBmb2xkZXIpOworCSAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworCQkvLyBvaCB3ZWxsLCBub3RoaW5nIHRvIGRvCisJCWxvZ2dlci5sb2coTGV2ZWwuRklORVNULAorCQkgICAgIklkbGVNYW5hZ2VyIGNhbid0IHJlZ2lzdGVyIGZvbGRlciIsIGV4KTsKKwkgICAgfSBjYXRjaCAoQ2FuY2VsbGVkS2V5RXhjZXB0aW9uIGV4KSB7CisJCS8vIHRoaXMgc2hvdWxkIG5ldmVyIGhhcHBlbgorCQlsb2dnZXIubG9nKExldmVsLkZJTkVTVCwKKwkJICAgICJJZGxlTWFuYWdlciBjYW4ndCByZWdpc3RlciBmb2xkZXIiLCBleCk7CisJICAgIH0KKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJvY2VzcyB0aGUgc2VsZWN0ZWQga2V5cy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcHJvY2Vzc0tleXMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCUlNQVBGb2xkZXIgZm9sZGVyOworCisJLyoKKwkgKiBGaXJzdCwgcHJvY2VzcyBhbnkgY2hhbm5lbHMgd2l0aCBkYXRhIHRvIHJlYWQuCisJICovCisJU2V0PFNlbGVjdGlvbktleT4gc2VsZWN0ZWRLZXlzID0gc2VsZWN0b3Iuc2VsZWN0ZWRLZXlzKCk7CisJLyoKKwkgKiBYWFggLSB0aGlzIGlzIHNpbXBsZXIsIGJ1dCBpdCBjYW4gZmFpbCB3aXRoCisJICoJIENvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb24KKwkgKgorCWZvciAoU2VsZWN0aW9uS2V5IHNrIDogc2VsZWN0ZWRLZXlzKSB7CisJICAgIHNlbGVjdGVkS2V5cy5yZW1vdmUoc2spOwkvLyBvbmx5IHByb2Nlc3MgZWFjaCBrZXkgb25jZQorCSAgICAuLi4KKwl9CisJKi8KKwlJdGVyYXRvcjxTZWxlY3Rpb25LZXk+IGl0ID0gc2VsZWN0ZWRLZXlzLml0ZXJhdG9yKCk7CisJd2hpbGUgKGl0Lmhhc05leHQoKSkgeworCSAgICBTZWxlY3Rpb25LZXkgc2sgPSBpdC5uZXh0KCk7CisJICAgIGl0LnJlbW92ZSgpOwkvLyBvbmx5IHByb2Nlc3MgZWFjaCBrZXkgb25jZQorCSAgICAvLyBoYXZlIHRvIGNhbmNlbCBzbyB3ZSBjYW4gc3dpdGNoIGJhY2sgdG8gYmxvY2tpbmcgSS9PIG1vZGUKKwkgICAgc2suY2FuY2VsKCk7CisJICAgIGZvbGRlciA9IChJTUFQRm9sZGVyKXNrLmF0dGFjaG1lbnQoKTsKKwkgICAgaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkVTVCkpCisJCWxvZ2dlci5sb2coTGV2ZWwuRklORVNULAorCQkgICAgIklkbGVNYW5hZ2VyIHNlbGVjdGVkIGZvbGRlcjogezB9IiwgZm9sZGVyTmFtZShmb2xkZXIpKTsKKwkgICAgU2VsZWN0YWJsZUNoYW5uZWwgc2MgPSBzay5jaGFubmVsKCk7CisJICAgIC8vIHN3aXRjaCBiYWNrIHRvIGJsb2NraW5nIHRvIGFsbG93IG5vcm1hbCBJL08KKwkgICAgc2MuY29uZmlndXJlQmxvY2tpbmcodHJ1ZSk7CisJICAgIHRyeSB7CisJCWlmIChmb2xkZXIuaGFuZGxlSWRsZShmYWxzZSkpIHsKKwkJICAgIGlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FU1QpKQorCQkJbG9nZ2VyLmxvZyhMZXZlbC5GSU5FU1QsCisJCQkgICAgIklkbGVNYW5hZ2VyIGNvbnRpbnVlIHdhdGNoaW5nIGZvbGRlciB7MH0iLAorCQkJCQkJCWZvbGRlck5hbWUoZm9sZGVyKSk7CisJCSAgICAvLyBtb3JlIHRvIGRvIHdpdGggdGhpcyBmb2xkZXIsIHNlbGVjdCBvbiBpdCBhZ2FpbgorCQkgICAgdG9XYXRjaC5hZGQoZm9sZGVyKTsKKwkJfSBlbHNlIHsKKwkJICAgIC8vIGRvbmUgd2F0Y2hpbmcgdGhpcyBmb2xkZXIsCisJCSAgICBpZiAobG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuRklORVNUKSkKKwkJCWxvZ2dlci5sb2coTGV2ZWwuRklORVNULAorCQkJICAgICJJZGxlTWFuYWdlciBkb25lIHdhdGNoaW5nIGZvbGRlciB7MH0iLAorCQkJCQkJCWZvbGRlck5hbWUoZm9sZGVyKSk7CisJCX0KKwkgICAgfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIGV4KSB7CisJCS8vIHNvbWV0aGluZyB3ZW50IHdyb25nLCBzdG9wIHdhdGNoaW5nIHRoaXMgZm9sZGVyCisJCWxvZ2dlci5sb2coTGV2ZWwuRklORVNULAorCQkgICAgIklkbGVNYW5hZ2VyIGdvdCBleGNlcHRpb24gZm9yIGZvbGRlcjogIiArCisJCQkJCQkgICAgZm9sZGVyTmFtZShmb2xkZXIpLCBleCk7CisJICAgIH0KKwl9CisKKwkvKgorCSAqIE5vdywgcHJvY2VzcyBhbnkgZm9sZGVycyB0aGF0IHdlIG5lZWQgdG8gYWJvcnQuCisJICovCisJd2hpbGUgKChmb2xkZXIgPSB0b0Fib3J0LnBvbGwoKSkgIT0gbnVsbCkgeworCSAgICBpZiAobG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuRklORVNUKSkKKwkJbG9nZ2VyLmxvZyhMZXZlbC5GSU5FU1QsCisJCSAgICAiSWRsZU1hbmFnZXIgYWJvcnRpbmcgSURMRSBmb3IgZm9sZGVyOiB7MH0iLAorCQkJCQkJCWZvbGRlck5hbWUoZm9sZGVyKSk7CisJICAgIFNvY2tldENoYW5uZWwgc2MgPSBmb2xkZXIuZ2V0Q2hhbm5lbCgpOworCSAgICBpZiAoc2MgPT0gbnVsbCkKKwkJY29udGludWU7CisJICAgIFNlbGVjdGlvbktleSBzayA9IHNjLmtleUZvcihzZWxlY3Rvcik7CisJICAgIC8vIGhhdmUgdG8gY2FuY2VsIHNvIHdlIGNhbiBzd2l0Y2ggYmFjayB0byBibG9ja2luZyBJL08gbW9kZQorCSAgICBpZiAoc2sgIT0gbnVsbCkKKwkJc2suY2FuY2VsKCk7CisJICAgIC8vIHN3aXRjaCBiYWNrIHRvIGJsb2NraW5nIHRvIGFsbG93IG5vcm1hbCBJL08KKwkgICAgc2MuY29uZmlndXJlQmxvY2tpbmcodHJ1ZSk7CisKKwkgICAgLy8gaWYgdGhlcmUncyBhIHJlYWQgdGltZW91dCwgaGF2ZSB0byBkbyB0aGUgYWJvcnQgaW4gYSBuZXcgdGhyZWFkCisJICAgIFNvY2tldCBzb2NrID0gc2Muc29ja2V0KCk7CisJICAgIGlmIChzb2NrICE9IG51bGwgJiYgc29jay5nZXRTb1RpbWVvdXQoKSA+IDApIHsKKwkJbG9nZ2VyLmZpbmVzdCgiSWRsZU1hbmFnZXIgcmVxdWVzdGluZyBET05FIHdpdGggdGltZW91dCIpOworCQl0b1dhdGNoLnJlbW92ZShmb2xkZXIpOworCQlmaW5hbCBJTUFQRm9sZGVyIGZvbGRlcjAgPSBmb2xkZXI7CisJCWVzLmV4ZWN1dGUobmV3IFJ1bm5hYmxlKCkgeworCQkgICAgQE92ZXJyaWRlCisJCSAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisJCQkvLyBzZW5kIHRoZSBET05FIGFuZCB3YWl0IGZvciB0aGUgcmVzcG9uc2UKKwkJCWZvbGRlcjAuaWRsZUFib3J0V2FpdCgpOworCQkgICAgfQorCQl9KTsKKwkgICAgfSBlbHNlIHsKKwkJZm9sZGVyLmlkbGVBYm9ydCgpOwkvLyBzZW5kIHRoZSBET05FIG1lc3NhZ2UKKwkJLy8gd2F0Y2ggZm9yIE9LIHJlc3BvbnNlIHRvIERPTkUKKwkJLy8gWFhYIC0gd2hhdCBpZiB3ZSBhbHNvIGFkZGVkIGl0IGFib3ZlPyAgc2hvdWxkIGJlIGEgbm9wCisJCXRvV2F0Y2guYWRkKGZvbGRlcik7CisJICAgIH0KKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogU3RvcCB3YXRjaGluZyBhbGwgZm9sZGVycy4gIENhbmNlbCBhbnkgc2VsZWN0aW9uIGtleXMgYW5kLAorICAgICAqIG1vc3QgaW1wb3J0YW50bHksIHN3aXRjaCB0aGUgY2hhbm5lbCBiYWNrIHRvIGJsb2NraW5nIG1vZGUuCisgICAgICogSWYgdGhlcmUncyBhbnkgZm9sZGVycyB3YWl0aW5nIHRvIGJlIHdhdGNoZWQsIG5lZWQgdG8gYWJvcnQKKyAgICAgKiB0aGVtIHRvby4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgdW53YXRjaEFsbCgpIHsKKwlJTUFQRm9sZGVyIGZvbGRlcjsKKwlTZXQ8U2VsZWN0aW9uS2V5PiBrZXlzID0gc2VsZWN0b3Iua2V5cygpOworCWZvciAoU2VsZWN0aW9uS2V5IHNrIDoga2V5cykgeworCSAgICAvLyBoYXZlIHRvIGNhbmNlbCBzbyB3ZSBjYW4gc3dpdGNoIGJhY2sgdG8gYmxvY2tpbmcgSS9PIG1vZGUKKwkgICAgc2suY2FuY2VsKCk7CisJICAgIGZvbGRlciA9IChJTUFQRm9sZGVyKXNrLmF0dGFjaG1lbnQoKTsKKwkgICAgaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkVTVCkpCisJCWxvZ2dlci5sb2coTGV2ZWwuRklORVNULAorCQkgICAgIklkbGVNYW5hZ2VyIG5vIGxvbmdlciB3YXRjaGluZyBmb2xkZXI6IHswfSIsCisJCQkJCQkJZm9sZGVyTmFtZShmb2xkZXIpKTsKKwkgICAgU2VsZWN0YWJsZUNoYW5uZWwgc2MgPSBzay5jaGFubmVsKCk7CisJICAgIC8vIHN3aXRjaCBiYWNrIHRvIGJsb2NraW5nIHRvIGFsbG93IG5vcm1hbCBJL08KKwkgICAgdHJ5IHsKKwkJc2MuY29uZmlndXJlQmxvY2tpbmcodHJ1ZSk7CisJCWZvbGRlci5pZGxlQWJvcnRXYWl0KCk7CS8vIHNlbmQgdGhlIERPTkUgbWVzc2FnZSBhbmQgd2FpdAorCSAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworCQkvLyBpZ25vcmUgaXQsIGNoYW5uZWwgbWlnaHQgYmUgY2xvc2VkCisJCWxvZ2dlci5sb2coTGV2ZWwuRklORVNULAorCQkgICAgIklkbGVNYW5hZ2VyIGV4Y2VwdGlvbiB3aGlsZSBhYm9ydGluZyBpZGxlIGZvciBmb2xkZXI6ICIgKworCQkJCQkJICAgIGZvbGRlck5hbWUoZm9sZGVyKSwgZXgpOworCSAgICB9CisJfQorCisJLyoKKwkgKiBGaW5hbGx5LCBwcm9jZXNzIGFueSBmb2xkZXJzIHdhaXRpbmcgdG8gYmUgd2F0Y2hlZC4KKwkgKi8KKwl3aGlsZSAoKGZvbGRlciA9IHRvV2F0Y2gucG9sbCgpKSAhPSBudWxsKSB7CisJICAgIGlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FU1QpKQorCQlsb2dnZXIubG9nKExldmVsLkZJTkVTVCwKKwkJICAgICJJZGxlTWFuYWdlciBhYm9ydGluZyBJRExFIGZvciB1bndhdGNoZWQgZm9sZGVyOiB7MH0iLAorCQkJCQkJCWZvbGRlck5hbWUoZm9sZGVyKSk7CisJICAgIFNvY2tldENoYW5uZWwgc2MgPSBmb2xkZXIuZ2V0Q2hhbm5lbCgpOworCSAgICBpZiAoc2MgPT0gbnVsbCkKKwkJY29udGludWU7CisJICAgIHRyeSB7CisJCS8vIGNoYW5uZWwgc2hvdWxkIHN0aWxsIGJlIGluIGJsb2NraW5nIG1vZGUsIGJ1dCBtYWtlIHN1cmUKKwkJc2MuY29uZmlndXJlQmxvY2tpbmcodHJ1ZSk7CisJCWZvbGRlci5pZGxlQWJvcnRXYWl0KCk7CS8vIHNlbmQgdGhlIERPTkUgbWVzc2FnZSBhbmQgd2FpdAorCSAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworCQkvLyBpZ25vcmUgaXQsIGNoYW5uZWwgbWlnaHQgYmUgY2xvc2VkCisJCWxvZ2dlci5sb2coTGV2ZWwuRklORVNULAorCQkgICAgIklkbGVNYW5hZ2VyIGV4Y2VwdGlvbiB3aGlsZSBhYm9ydGluZyBpZGxlIGZvciBmb2xkZXI6ICIgKworCQkJCQkJICAgIGZvbGRlck5hbWUoZm9sZGVyKSwgZXgpOworCSAgICB9CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFN0b3AgdGhlIElkbGVNYW5hZ2VyLiAgVGhlIElkbGVNYW5hZ2VyIGNhbiBub3QgYmUgcmVzdGFydGVkLgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzdG9wKCkgeworCWRpZSA9IHRydWU7CisJbG9nZ2VyLmZpbmUoIklkbGVNYW5hZ2VyIHN0b3BwaW5nIik7CisJc2VsZWN0b3Iud2FrZXVwKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBmdWxseSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgZm9sZGVyLCBmb3IgdXNlIGluIGxvZyBtZXNzYWdlcy4KKyAgICAgKiBFc3NlbnRpYWxseSBqdXN0IHRoZSBnZXRVUkxOYW1lIG1ldGhvZCwgYnV0IGlnbm9yaW5nIHRoZQorICAgICAqIE1lc3NhZ2luZ0V4Y2VwdGlvbiB0aGF0IGNhbiBuZXZlciBoYXBwZW4uCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGZvbGRlck5hbWUoRm9sZGVyIGZvbGRlcikgeworCXRyeSB7CisJICAgIHJldHVybiBmb2xkZXIuZ2V0VVJMTmFtZSgpLnRvU3RyaW5nKCk7CisJfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIG1leCkgeworCSAgICAvLyBjYW4ndCBoYXBwZW4KKwkgICAgcmV0dXJuIGZvbGRlci5nZXRTdG9yZSgpLnRvU3RyaW5nKCkgKyAiLyIgKyBmb2xkZXIudG9TdHJpbmcoKTsKKwl9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL01lc3NhZ2VDYWNoZS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL01lc3NhZ2VDYWNoZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg2Yzc4OTkKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvTWVzc2FnZUNhY2hlLmphdmEKQEAgLTAsMCArMSw0NDMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmltYXA7CisKK2ltcG9ydCBqYXZhLmlvLlByaW50U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC4qOworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkxldmVsOworCitpbXBvcnQgamF2YXgubWFpbC4qOworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLlByb3BVdGlsOworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLk1haWxMb2dnZXI7CisKKy8qKgorICogQSBjYWNoZSBvZiBJTUFQTWVzc2FnZSBvYmplY3RzIGFsb25nIHdpdGggdGhlCisgKiBtYXBwaW5nIGZyb20gbWVzc2FnZSBudW1iZXIgdG8gSU1BUCBzZXF1ZW5jZSBudW1iZXIuCisgKgorICogQWxsIG9wZXJhdGlvbnMgb24gdGhpcyBvYmplY3QgYXJlIHByb3RlY3RlZCBieSB0aGUgbWVzc2FnZUNhY2hlTG9jaworICogaW4gSU1BUEZvbGRlci4KKyAqLworcHVibGljIGNsYXNzIE1lc3NhZ2VDYWNoZSB7CisgICAgLyoKKyAgICAgKiBUaGUgYXJyYXkgb2YgSU1BUE1lc3NhZ2Ugb2JqZWN0cy4gIEVsZW1lbnRzIG9mIHRoZSBhcnJheSBtaWdodAorICAgICAqIGJlIG51bGwgaWYgbm8gb25lIGhhcyBhc2tlZCBmb3IgdGhlIG1lc3NhZ2UuICBUaGUgYXJyYXkgZXhwYW5kcworICAgICAqIGFzIG5lZWRlZCBhbmQgbWlnaHQgYmUgbGFyZ2VyIHRoYW4gdGhlIG51bWJlciBvZiBtZXNzYWdlcyBpbiB0aGUKKyAgICAgKiBmb2xkZXIuICBUaGUgInNpemUiIGZpZWxkIGluZGljYXRlcyB0aGUgbnVtYmVyIG9mIGVudHJpZXMgdGhhdAorICAgICAqIGFyZSB2YWxpZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIElNQVBNZXNzYWdlW10gbWVzc2FnZXM7CisKKyAgICAvKgorICAgICAqIEEgcGFyYWxsZWwgYXJyYXkgb2Ygc2VxdWVuY2UgbnVtYmVycyBmb3IgZWFjaCBtZXNzYWdlLiAgSWYgdGhlCisgICAgICogYXJyYXkgcG9pbnRlciBpcyBudWxsLCB0aGUgc2VxdWVuY2UgbnVtYmVyIG9mIGEgbWVzc2FnZSBpcyBqdXN0CisgICAgICogaXRzIG1lc3NhZ2UgbnVtYmVyLiAgVGhpcyBpcyB0aGUgY29tbW9uIGNhc2UsIHVudGlsIGEgbWVzc2FnZSBpcworICAgICAqIGV4cHVuZ2VkLgorICAgICAqLworICAgIHByaXZhdGUgaW50W10gc2VxbnVtczsKKworICAgIC8qCisgICAgICogVGhlIGFtb3VudCBvZiB0aGUgbWVzc2FnZXMgKGFuZCBzZXFudW0pIGFycmF5IHRoYXQgaXMgdmFsaWQuCisgICAgICogTWlnaHQgYmUgbGVzcyB0aGFuIHRoZSBhY3R1YWwgc2l6ZSBvZiB0aGUgYXJyYXkuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgc2l6ZTsKKworICAgIC8qKgorICAgICAqIFRoZSBmb2xkZXIgdGhlc2UgbWVzc2FnZXMgYmVsb25nIHRvLgorICAgICAqLworICAgIHByaXZhdGUgSU1BUEZvbGRlciBmb2xkZXI7CisKKyAgICAvLyBkZWJ1Z2dpbmcgbG9nZ2VyCisgICAgcHJpdmF0ZSBNYWlsTG9nZ2VyIGxvZ2dlcjsKKworICAgIC8qKgorICAgICAqIEdyb3cgdGhlIGFycmF5IGJ5IGF0IGxlYXN0IHRoaXMgbXVjaCwgdG8gYXZvaWQgY29uc3RhbnRseQorICAgICAqIHJlYWxsb2NhdGluZyB0aGUgYXJyYXkuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFNMT1AgPSA2NDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCBhIG5ldyBtZXNzYWdlIGNhY2hlIG9mIHRoZSBpbmRpY2F0ZWQgc2l6ZS4KKyAgICAgKi8KKyAgICBNZXNzYWdlQ2FjaGUoSU1BUEZvbGRlciBmb2xkZXIsIElNQVBTdG9yZSBzdG9yZSwgaW50IHNpemUpIHsKKwl0aGlzLmZvbGRlciA9IGZvbGRlcjsKKwlsb2dnZXIgPSBmb2xkZXIubG9nZ2VyLmdldFN1YkxvZ2dlcigibWVzc2FnZWNhY2hlIiwgIkRFQlVHIElNQVAgTUMiLAorCQkJCQkJc3RvcmUuZ2V0TWVzc2FnZUNhY2hlRGVidWcoKSk7CisJaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkNPTkZJRykpCisJICAgIGxvZ2dlci5jb25maWcoImNyZWF0ZSBjYWNoZSBvZiBzaXplICIgKyBzaXplKTsKKwllbnN1cmVDYXBhY2l0eShzaXplLCAxKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvciBmb3IgZGVidWdnaW5nIGFuZCB0ZXN0aW5nLgorICAgICAqLworICAgIE1lc3NhZ2VDYWNoZShpbnQgc2l6ZSwgYm9vbGVhbiBkZWJ1ZykgeworCXRoaXMuZm9sZGVyID0gbnVsbDsKKwlsb2dnZXIgPSBuZXcgTWFpbExvZ2dlcigKKwkJICAgIHRoaXMuZ2V0Q2xhc3MoKSwgIm1lc3NhZ2VjYWNoZSIsCisJCSAgICAiREVCVUcgSU1BUCBNQyIsIGRlYnVnLCBTeXN0ZW0ub3V0KTsKKwlpZiAobG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuQ09ORklHKSkKKwkgICAgbG9nZ2VyLmNvbmZpZygiY3JlYXRlIERFQlVHIGNhY2hlIG9mIHNpemUgIiArIHNpemUpOworCWVuc3VyZUNhcGFjaXR5KHNpemUsIDEpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNpemUgb2YgY2FjaGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBzaXplIG9mIHRoZSBjYWNoZQorICAgICAqLworICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKwlyZXR1cm4gc2l6ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIG1lc3NhZ2Ugb2JqZWN0IGZvciB0aGUgaW5kaWNhdGVkIG1lc3NhZ2UgbnVtYmVyLgorICAgICAqIElmIHRoZSBtZXNzYWdlIG9iamVjdCBoYXNuJ3QgYmVlbiBjcmVhdGVkLCBjcmVhdGUgaXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0JbXNnbnVtCXRoZSBtZXNzYWdlIG51bWJlcgorICAgICAqIEByZXR1cm4JCXRoZSBtZXNzYWdlCisgICAgICovCisgICAgcHVibGljIElNQVBNZXNzYWdlIGdldE1lc3NhZ2UoaW50IG1zZ251bSkgeworCS8vIGNoZWNrIHJhbmdlCisJaWYgKG1zZ251bSA8IDEgfHwgbXNnbnVtID4gc2l6ZSkKKwkgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigKKwkJIm1lc3NhZ2UgbnVtYmVyICgiICsgbXNnbnVtICsgIikgb3V0IG9mIGJvdW5kcyAoIiArIHNpemUgKyAiKSIpOworCUlNQVBNZXNzYWdlIG1zZyA9IG1lc3NhZ2VzW21zZ251bS0xXTsKKwlpZiAobXNnID09IG51bGwpIHsKKwkgICAgaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkUpKQorCQlsb2dnZXIuZmluZSgiY3JlYXRlIG1lc3NhZ2UgbnVtYmVyICIgKyBtc2dudW0pOworCSAgICBtc2cgPSBmb2xkZXIubmV3SU1BUE1lc3NhZ2UobXNnbnVtKTsKKwkgICAgbWVzc2FnZXNbbXNnbnVtLTFdID0gbXNnOworCSAgICAvLyBtYXJrIG1lc3NhZ2UgZXhwdW5nZWQgaWYgbm8gc2VxbnVtCisJICAgIGlmIChzZXFudW1PZihtc2dudW0pIDw9IDApIHsKKwkJbG9nZ2VyLmZpbmUoIml0J3MgZXhwdW5nZWQhIik7CisJCW1zZy5zZXRFeHB1bmdlZCh0cnVlKTsKKwkgICAgfQorCX0KKwlyZXR1cm4gbXNnOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgbWVzc2FnZSBvYmplY3QgZm9yIHRoZSBpbmRpY2F0ZWQgc2VxdWVuY2UgbnVtYmVyLgorICAgICAqIElmIHRoZSBtZXNzYWdlIG9iamVjdCBoYXNuJ3QgYmVlbiBjcmVhdGVkLCBjcmVhdGUgaXQuCisgICAgICogUmV0dXJuIG51bGwgaWYgdGhlcmUncyBubyBtZXNzYWdlIHdpdGggdGhhdCBzZXF1ZW5jZSBudW1iZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jc2VxbnVtCXRoZSBzZXF1ZW5jZSBudW1iZXIgb2YgdGhlIG1lc3NhZ2UKKyAgICAgKiBAcmV0dXJuCQl0aGUgbWVzc2FnZQorICAgICAqLworICAgIHB1YmxpYyBJTUFQTWVzc2FnZSBnZXRNZXNzYWdlQnlTZXFudW0oaW50IHNlcW51bSkgeworCWludCBtc2dudW0gPSBtc2dudW1PZihzZXFudW0pOworCWlmIChtc2dudW0gPCAwKSB7CQkvLyBYWFggLSA8IDEgPworCSAgICBpZiAobG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuRklORSkpCisJCWxvZ2dlci5maW5lKCJubyBtZXNzYWdlIHNlcW51bSAiICsgc2VxbnVtKTsKKwkgICAgcmV0dXJuIG51bGw7CisJfSBlbHNlCisJICAgIHJldHVybiBnZXRNZXNzYWdlKG1zZ251bSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXhwdW5nZSB0aGUgbWVzc2FnZSB3aXRoIHRoZSBnaXZlbiBzZXF1ZW5jZSBudW1iZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jc2VxbnVtCXRoZSBzZXF1ZW5jZSBudW1iZXIgb2YgdGhlIG1lc3NhZ2UgdG8gZXhwdW5nZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGV4cHVuZ2VNZXNzYWdlKGludCBzZXFudW0pIHsKKwlpbnQgbXNnbnVtID0gbXNnbnVtT2Yoc2VxbnVtKTsKKwlpZiAobXNnbnVtIDwgMCkgeworCSAgICBpZiAobG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuRklORSkpCisJCWxvZ2dlci5maW5lKCJleHB1bmdlIG5vIHNlcW51bSAiICsgc2VxbnVtKTsKKwkgICAgcmV0dXJuOwkJLy8gWFhYIC0gc2hvdWxkIG5ldmVyIGhhcHBlbgorCX0KKwlJTUFQTWVzc2FnZSBtc2cgPSBtZXNzYWdlc1ttc2dudW0tMV07CisJaWYgKG1zZyAhPSBudWxsKSB7CisJICAgIGlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FKSkKKwkJbG9nZ2VyLmZpbmUoImV4cHVuZ2UgZXhpc3RpbmcgIiArIG1zZ251bSk7CisJICAgIG1zZy5zZXRFeHB1bmdlZCh0cnVlKTsKKwl9CisJaWYgKHNlcW51bXMgPT0gbnVsbCkgewkJLy8gdGltZSB0byBmaWxsIGl0IGluCisJICAgIGxvZ2dlci5maW5lKCJjcmVhdGUgc2VxbnVtcyBhcnJheSIpOworCSAgICBzZXFudW1zID0gbmV3IGludFttZXNzYWdlcy5sZW5ndGhdOworCSAgICBmb3IgKGludCBpID0gMTsgaSA8IG1zZ251bTsgaSsrKQorCQlzZXFudW1zW2ktMV0gPSBpOworCSAgICBzZXFudW1zW21zZ251bSAtIDFdID0gMDsKKwkgICAgZm9yIChpbnQgaSA9IG1zZ251bSArIDE7IGkgPD0gc2VxbnVtcy5sZW5ndGg7IGkrKykKKwkJc2VxbnVtc1tpLTFdID0gaSAtIDE7CisJfSBlbHNlIHsKKwkgICAgc2VxbnVtc1ttc2dudW0gLSAxXSA9IDA7CisJICAgIGZvciAoaW50IGkgPSBtc2dudW0gKyAxOyBpIDw9IHNlcW51bXMubGVuZ3RoOyBpKyspIHsKKwkJYXNzZXJ0IHNlcW51bXNbaS0xXSAhPSAxOworCQlpZiAoc2VxbnVtc1tpLTFdID4gMCkKKwkJICAgIHNlcW51bXNbaS0xXS0tOworCSAgICB9CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZSBhbGwgdGhlIGV4cHVuZ2VkIG1lc3NhZ2VzIGZyb20gdGhlIGFycmF5LAorICAgICAqIHJldHVybmluZyBhIGxpc3Qgb2YgcmVtb3ZlZCBtZXNzYWdlIG9iamVjdHMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSByZW1vdmVkIG1lc3NhZ2VzCisgICAgICovCisgICAgcHVibGljIElNQVBNZXNzYWdlW10gcmVtb3ZlRXhwdW5nZWRNZXNzYWdlcygpIHsKKwlsb2dnZXIuZmluZSgicmVtb3ZlIGV4cHVuZ2VkIG1lc3NhZ2VzIik7CisJLy8gbGlzdCBvZiBleHB1bmdlZCBtZXNzYWdlcworCUxpc3Q8SU1BUE1lc3NhZ2U+IG1saXN0ID0gbmV3IEFycmF5TGlzdDw+KCk7CisKKwkvKgorCSAqIFdhbGsgdGhyb3VnaCB0aGUgYXJyYXkgY29tcHJlc3NpbmcgaXQgYnkgY29weWluZworCSAqIGhpZ2hlciBudW1iZXJlZCBtZXNzYWdlcyBmdXJ0aGVyIGRvd24gaW4gdGhlIGFycmF5LAorCSAqIGVmZmVjdGl2ZWx5IHJlbW92aW5nIGV4cHVuZ2VkIG1lc3NhZ2VzIGZyb20gdGhlIGFycmF5LgorCSAqIG9sZG51bSBpcyB0aGUgaW5kZXggd2UgdXNlIHRvIHdhbGsgdGhyb3VnaCB0aGUgYXJyYXkuCisJICogbmV3bnVtIGlzIHRoZSBpbmRleCB3aGVyZSB3ZSBjb3B5IHRoZSBuZXh0IHZhbGlkIG1lc3NhZ2UuCisJICogb2xkbnVtID09IG5ld251bSB1bnRpbCB3ZSBlbmNvdW50ZXIgYW4gZXhwdW5nZWQgbWVzc2FnZS4KKwkgKi8KKwlpbnQgb2xkbnVtID0gMTsKKwlpbnQgbmV3bnVtID0gMTsKKwl3aGlsZSAob2xkbnVtIDw9IHNpemUpIHsKKwkgICAgLy8gaXMgbWVzc2FnZSBleHB1bmdlZD8KKwkgICAgaWYgKHNlcW51bU9mKG9sZG51bSkgPD0gMCkgeworCQlJTUFQTWVzc2FnZSBtID0gZ2V0TWVzc2FnZShvbGRudW0pOworCQltbGlzdC5hZGQobSk7CisJICAgIH0gZWxzZSB7CisJCS8vIGtlZXAgdGhpcyBtZXNzYWdlCisJCWlmIChuZXdudW0gIT0gb2xkbnVtKSB7CisJCSAgICAvLyBtb3ZlIG1lc3NhZ2UgZG93biBpbiB0aGUgYXJyYXkgKGNvbXBhY3QgYXJyYXkpCisJCSAgICBtZXNzYWdlc1tuZXdudW0tMV0gPSBtZXNzYWdlc1tvbGRudW0tMV07CisJCSAgICBpZiAobWVzc2FnZXNbbmV3bnVtLTFdICE9IG51bGwpCisJCQltZXNzYWdlc1tuZXdudW0tMV0uc2V0TWVzc2FnZU51bWJlcihuZXdudW0pOworCQl9CisJCW5ld251bSsrOworCSAgICB9CisJICAgIG9sZG51bSsrOworCX0KKwlzZXFudW1zID0gbnVsbDsKKwlzaHJpbmsobmV3bnVtLCBvbGRudW0pOworCisJSU1BUE1lc3NhZ2VbXSBybXNncyA9IG5ldyBJTUFQTWVzc2FnZVttbGlzdC5zaXplKCldOworCWlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FKSkKKwkgICAgbG9nZ2VyLmZpbmUoInJldHVybiAiICsgcm1zZ3MubGVuZ3RoKTsKKwltbGlzdC50b0FycmF5KHJtc2dzKTsKKwlyZXR1cm4gcm1zZ3M7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlIGV4cHVuZ2VkIG1lc3NhZ2VzIGluIG1zZ3MgZnJvbSB0aGUgYXJyYXksCisgICAgICogcmV0dXJuaW5nIGEgbGlzdCBvZiByZW1vdmVkIG1lc3NhZ2Ugb2JqZWN0cy4KKyAgICAgKiBBbGwgbWVzc2FnZXMgaW4gbXNncyBtdXN0IGJlIElNQVBNZXNzYWdlIG9iamVjdHMKKyAgICAgKiBmcm9tIHRoaXMgZm9sZGVyLgorICAgICAqCisgICAgICogQHBhcmFtCW1zZ3MJdGhlIG1lc3NhZ2VzCisgICAgICogQHJldHVybgkJdGhlIHJlbW92ZWQgbWVzc2FnZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgSU1BUE1lc3NhZ2VbXSByZW1vdmVFeHB1bmdlZE1lc3NhZ2VzKE1lc3NhZ2VbXSBtc2dzKSB7CisJbG9nZ2VyLmZpbmUoInJlbW92ZSBleHB1bmdlZCBtZXNzYWdlcyIpOworCS8vIGxpc3Qgb2YgZXhwdW5nZWQgbWVzc2FnZXMKKwlMaXN0PElNQVBNZXNzYWdlPiBtbGlzdCA9IG5ldyBBcnJheUxpc3Q8PigpOworCisJLyoKKwkgKiBDb3B5IHRoZSBtZXNzYWdlIG51bWJlcnMgb2YgdGhlIGV4cHVuZ2VkIG1lc3NhZ2VzIGludG8KKwkgKiBhIHNlcGFyYXRlIGFycmF5IGFuZCBzb3J0IHRoZSBhcnJheSB0byBtYWtlIGl0IGVhc2llciB0bworCSAqIHByb2Nlc3MgbGF0ZXIuCisJICovCisJaW50W10gbW51bSA9IG5ldyBpbnRbbXNncy5sZW5ndGhdOworCWZvciAoaW50IGkgPSAwOyBpIDwgbXNncy5sZW5ndGg7IGkrKykKKwkgICAgbW51bVtpXSA9IG1zZ3NbaV0uZ2V0TWVzc2FnZU51bWJlcigpOworCUFycmF5cy5zb3J0KG1udW0pOworCisJLyoKKwkgKiBXYWxrIHRocm91Z2ggdGhlIGFycmF5IGNvbXByZXNzaW5nIGl0IGJ5IGNvcHlpbmcKKwkgKiBoaWdoZXIgbnVtYmVyZWQgbWVzc2FnZXMgZnVydGhlciBkb3duIGluIHRoZSBhcnJheSwKKwkgKiBlZmZlY3RpdmVseSByZW1vdmluZyBleHB1bmdlZCBtZXNzYWdlcyBmcm9tIHRoZSBhcnJheS4KKwkgKiBvbGRudW0gaXMgdGhlIGluZGV4IHdlIHVzZSB0byB3YWxrIHRocm91Z2ggdGhlIGFycmF5LgorCSAqIG5ld251bSBpcyB0aGUgaW5kZXggd2hlcmUgd2UgY29weSB0aGUgbmV4dCB2YWxpZCBtZXNzYWdlLgorCSAqIG9sZG51bSA9PSBuZXdudW0gdW50aWwgd2UgZW5jb3VudGVyIGFuIGV4cHVuZ2VkIG1lc3NhZ2UuCisJICoKKwkgKiBFdmVuIHRob3VnaCB3ZSBrbm93IHRoZSBtZXNzYWdlIG51bWJlciBvZiB0aGUgZmlyc3QgcG9zc2libHkKKwkgKiBleHB1bmdlZCBtZXNzYWdlLCB3ZSBzdGlsbCBzdGFydCBzY2FubmluZyBhdCBtZXNzYWdlIG51bWJlciAxCisJICogc28gdGhhdCB3ZSBjYW4gY2hlY2sgd2hldGhlciB0aGVyZSdzIGFueSBtZXNzYWdlIHdob3NlCisJICogc2VxdWVuY2UgbnVtYmVyIGlzIGRpZmZlcmVudCB0aGFuIGl0cyBtZXNzYWdlIG51bWJlci4gIElmIHRoZXJlCisJICogaXMsIHdlIGNhbid0IHRocm93IGF3YXkgdGhlIHNlcW51bXMgYXJyYXkgd2hlbiB3ZSdyZSBkb25lLgorCSAqLworCWludCBvbGRudW0gPSAxOworCWludCBuZXdudW0gPSAxOworCWludCBtbnVtaSA9IDA7CQkvLyBpbmRleCBpbnRvIG1udW0KKwlib29sZWFuIGtlZXBTZXFudW1zID0gZmFsc2U7CisJd2hpbGUgKG9sZG51bSA8PSBzaXplKSB7CisJICAgIC8qCisJICAgICAqIEFyZSB0aGVyZSBzdGlsbCBleHB1bmdlZCBtZXNzc2FnZXMgaW4gbXNncyB0byBjb25zaWRlciwKKwkgICAgICogYW5kIGlzIHRoZSBtZXNzYWdlIHdlJ3JlIGNvbnNpZGVyaW5nIHRoZSBuZXh0IG9uZSBpbiB0aGUKKwkgICAgICogbGlzdCwgYW5kIGlzIGl0IGV4cHVuZ2VkPworCSAgICAgKi8KKwkgICAgaWYgKG1udW1pIDwgbW51bS5sZW5ndGggJiYKKwkJICAgIG9sZG51bSA9PSBtbnVtW21udW1pXSAmJgorCQkgICAgc2VxbnVtT2Yob2xkbnVtKSA8PSAwKSB7CisJCUlNQVBNZXNzYWdlIG0gPSBnZXRNZXNzYWdlKG9sZG51bSk7CisJCW1saXN0LmFkZChtKTsKKwkJLyoKKwkJICogSnVzdCBpbiBjYXNlIHRoZXJlIGFyZSBkdXBsaWNhdGUgZW50cmllcyBpbiB0aGUgbXNncyBhcnJheSwKKwkJICogd2Uga2VlcCBhZHZhbmNpbmcgbW51bWkgcGFzdCBhbnkgZHVwbGljYXRlcywgYnV0IG9mIGNvdXJzZQorCQkgKiBzdG9wIHdoZW4gd2UgZ2V0IHRvIHRoZSBlbmQgb2YgdGhlIGFycmF5LgorCQkgKi8KKwkJd2hpbGUgKG1udW1pIDwgbW51bS5sZW5ndGggJiYgbW51bVttbnVtaV0gPD0gb2xkbnVtKQorCQkgICAgbW51bWkrKzsJLy8gY29uc2lkZXIgbmV4dCBtZXNzYWdlIGluIGFycmF5CisJICAgIH0gZWxzZSB7CisJCS8vIGtlZXAgdGhpcyBtZXNzYWdlCisJCWlmIChuZXdudW0gIT0gb2xkbnVtKSB7CisJCSAgICAvLyBtb3ZlIG1lc3NhZ2UgZG93biBpbiB0aGUgYXJyYXkgKGNvbXBhY3QgYXJyYXkpCisJCSAgICBtZXNzYWdlc1tuZXdudW0tMV0gPSBtZXNzYWdlc1tvbGRudW0tMV07CisJCSAgICBpZiAobWVzc2FnZXNbbmV3bnVtLTFdICE9IG51bGwpCisJCQltZXNzYWdlc1tuZXdudW0tMV0uc2V0TWVzc2FnZU51bWJlcihuZXdudW0pOworCQkgICAgaWYgKHNlcW51bXMgIT0gbnVsbCkKKwkJCXNlcW51bXNbbmV3bnVtLTFdID0gc2VxbnVtc1tvbGRudW0tMV07CisJCX0KKwkJaWYgKHNlcW51bXMgIT0gbnVsbCAmJiBzZXFudW1zW25ld251bS0xXSAhPSBuZXdudW0pCisJCSAgICBrZWVwU2VxbnVtcyA9IHRydWU7CisJCW5ld251bSsrOworCSAgICB9CisJICAgIG9sZG51bSsrOworCX0KKworCWlmICgha2VlcFNlcW51bXMpCisJICAgIHNlcW51bXMgPSBudWxsOworCXNocmluayhuZXdudW0sIG9sZG51bSk7CisKKwlJTUFQTWVzc2FnZVtdIHJtc2dzID0gbmV3IElNQVBNZXNzYWdlW21saXN0LnNpemUoKV07CisJaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkUpKQorCSAgICBsb2dnZXIuZmluZSgicmV0dXJuICIgKyBybXNncy5sZW5ndGgpOworCW1saXN0LnRvQXJyYXkocm1zZ3MpOworCXJldHVybiBybXNnczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTaHJpbmsgdGhlIG1lc3NhZ2VzIGFuZCBzZXFudW1zIGFycmF5cy4gIG5ld2VuZCBpcyBvbmUgcGFzdCBsYXN0CisgICAgICogdmFsaWQgZWxlbWVudC4gIG9sZGVuZCBpcyBvbmUgcGFzdCB0aGUgcHJldmlvdXMgbGFzdCB2YWxpZCBlbGVtZW50LgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBzaHJpbmsoaW50IG5ld2VuZCwgaW50IG9sZGVuZCkgeworCXNpemUgPSBuZXdlbmQgLSAxOworCWlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FKSkKKwkgICAgbG9nZ2VyLmZpbmUoInNpemUgbm93ICIgKyBzaXplKTsKKwlpZiAoc2l6ZSA9PSAwKSB7CS8vIG5vIG1lc3NhZ2VzIGxlZnQKKwkgICAgbWVzc2FnZXMgPSBudWxsOworCSAgICBzZXFudW1zID0gbnVsbDsKKwl9IGVsc2UgaWYgKHNpemUgPiBTTE9QICYmIHNpemUgPCBtZXNzYWdlcy5sZW5ndGggLyAyKSB7CisJICAgIC8vIGlmIGFycmF5IHNocmlua3MgYnkgdG9vIG11Y2gsIHJlYWxsb2NhdGUgaXQKKwkgICAgbG9nZ2VyLmZpbmUoInJlYWxsb2NhdGUgYXJyYXkiKTsKKwkgICAgSU1BUE1lc3NhZ2VbXSBuZXdtID0gbmV3IElNQVBNZXNzYWdlW3NpemUgKyBTTE9QXTsKKwkgICAgU3lzdGVtLmFycmF5Y29weShtZXNzYWdlcywgMCwgbmV3bSwgMCwgc2l6ZSk7CisJICAgIG1lc3NhZ2VzID0gbmV3bTsKKwkgICAgaWYgKHNlcW51bXMgIT0gbnVsbCkgeworCQlpbnRbXSBuZXdzID0gbmV3IGludFtzaXplICsgU0xPUF07CisJCVN5c3RlbS5hcnJheWNvcHkoc2VxbnVtcywgMCwgbmV3cywgMCwgc2l6ZSk7CisJCXNlcW51bXMgPSBuZXdzOworCSAgICB9CisJfSBlbHNlIHsKKwkgICAgaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkUpKQorCQlsb2dnZXIuZmluZSgiY2xlYW4gIiArIG5ld2VuZCArICIgdG8gIiArIG9sZGVuZCk7CisJICAgIC8vIGNsZWFyIG91dCB1bnVzZWQgZW50cmllcyBpbiBhcnJheQorCSAgICBmb3IgKGludCBtc2dudW0gPSBuZXdlbmQ7IG1zZ251bSA8IG9sZGVuZDsgbXNnbnVtKyspIHsKKwkJbWVzc2FnZXNbbXNnbnVtLTFdID0gbnVsbDsKKwkJaWYgKHNlcW51bXMgIT0gbnVsbCkKKwkJICAgIHNlcW51bXNbbXNnbnVtLTFdID0gMDsKKwkgICAgfQorCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGQgY291bnQgbWVzc2FnZXMgdG8gdGhlIGNhY2hlLgorICAgICAqIG5ld1NlcU51bSBpcyB0aGUgc2VxdWVuY2UgbnVtYmVyIG9mIHRoZSBmaXJzdCBtZXNzYWdlIGFkZGVkLgorICAgICAqCisgICAgICogQHBhcmFtCWNvdW50CXRoZSBudW1iZXIgb2YgbWVzc2dlcworICAgICAqIEBwYXJhbQluZXdTZXFOdW0Jc2VxdWVuY2UgbnVtYmVyIG9mIGZpcnN0IG1lc3NhZ2UKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGRNZXNzYWdlcyhpbnQgY291bnQsIGludCBuZXdTZXFOdW0pIHsKKwlpZiAobG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuRklORSkpCisJICAgIGxvZ2dlci5maW5lKCJhZGQgIiArIGNvdW50ICsgIiBtZXNzYWdlcyIpOworCS8vIGRvbid0IGhhdmUgdG8gZG8gYW55dGhpbmcgb3RoZXIgdGhhbiBtYWtpbmcgc3VyZSB0aGVyZSdzIHNwYWNlCisJZW5zdXJlQ2FwYWNpdHkoc2l6ZSArIGNvdW50LCBuZXdTZXFOdW0pOworICAgIH0KKworICAgIC8qCisgICAgICogTWFrZSBzdXJlIHRoZSBhcnJheXMgYXJlIGF0IGxlYXN0IGJpZyBlbm91Z2ggdG8gaG9sZAorICAgICAqICJuZXdzaXplIiBtZXNzYWdlcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgZW5zdXJlQ2FwYWNpdHkoaW50IG5ld3NpemUsIGludCBuZXdTZXFOdW0pIHsKKwlpZiAobWVzc2FnZXMgPT0gbnVsbCkKKwkgICAgbWVzc2FnZXMgPSBuZXcgSU1BUE1lc3NhZ2VbbmV3c2l6ZSArIFNMT1BdOworCWVsc2UgaWYgKG1lc3NhZ2VzLmxlbmd0aCA8IG5ld3NpemUpIHsKKwkgICAgaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkUpKQorCQlsb2dnZXIuZmluZSgiZXhwYW5kIGNhcGFjaXR5IHRvICIgKyBuZXdzaXplKTsKKwkgICAgSU1BUE1lc3NhZ2VbXSBuZXdtID0gbmV3IElNQVBNZXNzYWdlW25ld3NpemUgKyBTTE9QXTsKKwkgICAgU3lzdGVtLmFycmF5Y29weShtZXNzYWdlcywgMCwgbmV3bSwgMCwgbWVzc2FnZXMubGVuZ3RoKTsKKwkgICAgbWVzc2FnZXMgPSBuZXdtOworCSAgICBpZiAoc2VxbnVtcyAhPSBudWxsKSB7CisJCWludFtdIG5ld3MgPSBuZXcgaW50W25ld3NpemUgKyBTTE9QXTsKKwkJU3lzdGVtLmFycmF5Y29weShzZXFudW1zLCAwLCBuZXdzLCAwLCBzZXFudW1zLmxlbmd0aCk7CisJCWZvciAoaW50IGkgPSBzaXplOyBpIDwgbmV3cy5sZW5ndGg7IGkrKykKKwkJICAgIG5ld3NbaV0gPSBuZXdTZXFOdW0rKzsKKwkJc2VxbnVtcyA9IG5ld3M7CisJCWlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FKSkKKwkJICAgIGxvZ2dlci5maW5lKCJtZXNzYWdlICIgKyBuZXdzaXplICsKKwkJCSIgaGFzIHNlcXVlbmNlIG51bWJlciAiICsgc2VxbnVtc1tuZXdzaXplLTFdKTsKKwkgICAgfQorCX0gZWxzZSBpZiAobmV3c2l6ZSA8IHNpemUpIHsJCS8vIHNocmlua2luZz8KKwkgICAgLy8gdGhpcyBzaG91bGQgbmV2ZXIgaGFwcGVuCisJICAgIGlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FKSkKKwkJbG9nZ2VyLmZpbmUoInNocmluayBjYXBhY2l0eSB0byAiICsgbmV3c2l6ZSk7CisJICAgIGZvciAoaW50IG1zZ251bSA9IG5ld3NpemUgKyAxOyBtc2dudW0gPD0gc2l6ZTsgbXNnbnVtKyspIHsKKwkJbWVzc2FnZXNbbXNnbnVtLTFdID0gbnVsbDsKKwkJaWYgKHNlcW51bXMgIT0gbnVsbCkKKwkJICAgIHNlcW51bXNbbXNnbnVtLTFdID0gLTE7CisJICAgIH0KKwl9CisJc2l6ZSA9IG5ld3NpemU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBzZXF1ZW5jZSBudW1iZXIgZm9yIHRoZSBnaXZlbiBtZXNzYWdlIG51bWJlci4KKyAgICAgKgorICAgICAqIEBwYXJhbQltc2dudW0JdGhlIG1lc3NhZ2UgbnVtYmVyCisgICAgICogQHJldHVybgkJdGhlIHNlcXVlbmNlIG51bWJlcgorICAgICAqLworICAgIHB1YmxpYyBpbnQgc2VxbnVtT2YoaW50IG1zZ251bSkgeworCWlmIChzZXFudW1zID09IG51bGwpCisJICAgIHJldHVybiBtc2dudW07CisJZWxzZSB7CisJICAgIGlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FKSkKKwkJbG9nZ2VyLmZpbmUoIm1zZ251bSAiICsgbXNnbnVtICsgIiBpcyBzZXFudW0gIiArCisJCQkgICAgc2VxbnVtc1ttc2dudW0tMV0pOworCSAgICByZXR1cm4gc2VxbnVtc1ttc2dudW0tMV07CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgbWVzc2FnZSBudW1iZXIgZm9yIHRoZSBnaXZlbiBzZXF1ZW5jZSBudW1iZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgbXNnbnVtT2YoaW50IHNlcW51bSkgeworCWlmIChzZXFudW1zID09IG51bGwpCisJICAgIHJldHVybiBzZXFudW07CisJaWYgKHNlcW51bSA8IDEpIHsJCS8vIHNob3VsZCBuZXZlciBoYXBwZW4KKwkgICAgaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkUpKQorCQlsb2dnZXIuZmluZSgiYmFkIHNlcW51bSAiICsgc2VxbnVtKTsKKwkgICAgcmV0dXJuIC0xOworCX0KKwlmb3IgKGludCBtc2dudW0gPSBzZXFudW07IG1zZ251bSA8PSBzaXplOyBtc2dudW0rKykgeworCSAgICBpZiAoc2VxbnVtc1ttc2dudW0tMV0gPT0gc2VxbnVtKQorCQlyZXR1cm4gbXNnbnVtOworCSAgICBpZiAoc2VxbnVtc1ttc2dudW0tMV0gPiBzZXFudW0pCisJCWJyZWFrOwkJLy8gbWVzc2FnZSBkb2Vzbid0IGV4aXN0CisJfQorCXJldHVybiAtMTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvTWVzc2FnZVZhbmlzaGVkRXZlbnQuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9NZXNzYWdlVmFuaXNoZWRFdmVudC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA1NmNhYmMKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvTWVzc2FnZVZhbmlzaGVkRXZlbnQuamF2YQpAQCAtMCwwICsxLDYyIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5pbWFwOworCitpbXBvcnQgamF2YXgubWFpbC5Gb2xkZXI7CitpbXBvcnQgamF2YXgubWFpbC5NZXNzYWdlOworaW1wb3J0IGphdmF4Lm1haWwuZXZlbnQuTWVzc2FnZUNvdW50RXZlbnQ7CisKKy8qKgorICogVGhpcyBjbGFzcyBwcm92aWRlcyBub3RpZmljYXRpb24gb2YgbWVzc2FnZXMgdGhhdCBoYXZlIGJlZW4gcmVtb3ZlZAorICogc2luY2UgdGhlIGZvbGRlciB3YXMgbGFzdCBzeW5jaHJvbml6ZWQuCisgKgorICogQHNpbmNlCUphdmFNYWlsIDEuNS4xCisgKiBAYXV0aG9yCUJpbGwgU2hhbm5vbgorICovCisKK3B1YmxpYyBjbGFzcyBNZXNzYWdlVmFuaXNoZWRFdmVudCBleHRlbmRzIE1lc3NhZ2VDb3VudEV2ZW50IHsKKworICAgIC8qKgorICAgICAqIFRoZSBtZXNzYWdlIFVJRHMuCisgICAgICovCisgICAgcHJpdmF0ZSBsb25nW10gdWlkczsKKworICAgIC8vIGEgcmV1c2FibGUgZW1wdHkgYXJyYXkKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNZXNzYWdlW10gbm9NZXNzYWdlcyA9IHsgfTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDIxNDIwMjgwMTAyNTAwMjQ5MjJMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZm9sZGVyICAJdGhlIGNvbnRhaW5pbmcgZm9sZGVyCisgICAgICogQHBhcmFtIHVpZHMJdGhlIFVJRHMgZm9yIHRoZSB2YW5pc2hlZCBtZXNzYWdlcworICAgICAqLworICAgIHB1YmxpYyBNZXNzYWdlVmFuaXNoZWRFdmVudChGb2xkZXIgZm9sZGVyLCBsb25nW10gdWlkcykgeworCXN1cGVyKGZvbGRlciwgUkVNT1ZFRCwgdHJ1ZSwgbm9NZXNzYWdlcyk7CisJdGhpcy51aWRzID0gdWlkczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIFVJRHMgZm9yIHRoaXMgZXZlbnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuICB0aGUgVUlEcworICAgICAqLworICAgIHB1YmxpYyBsb25nW10gZ2V0VUlEcygpIHsKKwlyZXR1cm4gdWlkczsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvTW9kaWZpZWRTaW5jZVRlcm0uamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9Nb2RpZmllZFNpbmNlVGVybS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjczMzIyNjYKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvTW9kaWZpZWRTaW5jZVRlcm0uamF2YQpAQCAtMCwwICsxLDk0IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5pbWFwOworCitpbXBvcnQgamF2YXgubWFpbC5NZXNzYWdlOworaW1wb3J0IGphdmF4Lm1haWwuc2VhcmNoLlNlYXJjaFRlcm07CisKKy8qKgorICogRmluZCBtZXNzYWdlcyB0aGF0IGhhdmUgYmVlbiBtb2RpZmllZCBzaW5jZSBhIGdpdmVuIE1PRFNFUSB2YWx1ZS4KKyAqIFJlbGllcyBvbiB0aGUgc2VydmVyIGltcGxlbWVudGluZyB0aGUgQ09ORFNUT1JFIGV4dGVuc2lvbgorICogKDxBIEhSRUY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzQ1NTEudHh0Ij5SRkMgNDU1MTwvQT4pLgorICoKKyAqIEBzaW5jZQlKYXZhTWFpbCAxLjUuMQorICogQGF1dGhvcglCaWxsIFNoYW5ub24KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIE1vZGlmaWVkU2luY2VUZXJtIGV4dGVuZHMgU2VhcmNoVGVybSB7CisKKyAgICBwcml2YXRlIGxvbmcgbW9kc2VxOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNTE1MTQ1NzQ2OTYzNDcyNzk5Mkw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtb2RzZXEJbW9kaWZpY2F0aW9uIHNlcXVlbmNlIG51bWJlcgorICAgICAqLworICAgIHB1YmxpYyBNb2RpZmllZFNpbmNlVGVybShsb25nIG1vZHNlcSkgeworCXRoaXMubW9kc2VxID0gbW9kc2VxOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgbW9kc2VxLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgbW9kc2VxCisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0TW9kU2VxKCkgeworCXJldHVybiBtb2RzZXE7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIG1hdGNoIG1ldGhvZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtc2cJdGhlIGRhdGUgY29tcGFyYXRvciBpcyBhcHBsaWVkIHRvIHRoaXMgTWVzc2FnZSdzCisgICAgICoJCQlNT0RTRVEKKyAgICAgKiBAcmV0dXJuCQl0cnVlIGlmIHRoZSBjb21wYXJpc29uIHN1Y2NlZWRzLCBvdGhlcndpc2UgZmFsc2UKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBtYXRjaChNZXNzYWdlIG1zZykgeworCWxvbmcgbTsKKworCXRyeSB7CisJICAgIGlmIChtc2cgaW5zdGFuY2VvZiBJTUFQTWVzc2FnZSkKKwkJbSA9ICgoSU1BUE1lc3NhZ2UpbXNnKS5nZXRNb2RTZXEoKTsKKwkgICAgZWxzZQorCQlyZXR1cm4gZmFsc2U7CisJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKwkgICAgcmV0dXJuIGZhbHNlOworCX0KKworCXJldHVybiBtID49IG1vZHNlcTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFcXVhbGl0eSBjb21wYXJpc29uLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CisJaWYgKCEob2JqIGluc3RhbmNlb2YgTW9kaWZpZWRTaW5jZVRlcm0pKQorCSAgICByZXR1cm4gZmFsc2U7CisJcmV0dXJuIG1vZHNlcSA9PSAoKE1vZGlmaWVkU2luY2VUZXJtKW9iaikubW9kc2VxOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXB1dGUgYSBoYXNoQ29kZSBmb3IgdGhpcyBvYmplY3QuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKwlyZXR1cm4gKGludCltb2RzZXE7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL09sZGVyVGVybS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL09sZGVyVGVybS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE5ODU3YzQKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvT2xkZXJUZXJtLmphdmEKQEAgLTAsMCArMSw5NiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuaW1hcDsKKworaW1wb3J0IGphdmEudXRpbC5EYXRlOworaW1wb3J0IGphdmF4Lm1haWwuTWVzc2FnZTsKK2ltcG9ydCBqYXZheC5tYWlsLnNlYXJjaC5TZWFyY2hUZXJtOworCisvKioKKyAqIEZpbmQgbWVzc2FnZXMgdGhhdCBhcmUgb2xkZXIgdGhhbiBhIGdpdmVuIGludGVydmFsIChpbiBzZWNvbmRzKS4KKyAqIFJlbGllcyBvbiB0aGUgc2VydmVyIGltcGxlbWVudGluZyB0aGUgV0lUSElOIHNlYXJjaCBleHRlbnNpb24KKyAqICg8QSBIUkVGPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmM1MDMyLnR4dCI+UkZDIDUwMzI8L0E+KS4KKyAqCisgKiBAc2luY2UJSmF2YU1haWwgMS41LjEKKyAqIEBhdXRob3IJQmlsbCBTaGFubm9uCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBPbGRlclRlcm0gZXh0ZW5kcyBTZWFyY2hUZXJtIHsKKworICAgIHByaXZhdGUgaW50IGludGVydmFsOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMzk1MTA3ODk0ODcyNzk5NTY4Mkw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbnRlcnZhbAludW1iZXIgb2Ygc2Vjb25kcyBvbGRlcgorICAgICAqLworICAgIHB1YmxpYyBPbGRlclRlcm0oaW50IGludGVydmFsKSB7CisJdGhpcy5pbnRlcnZhbCA9IGludGVydmFsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgaW50ZXJ2YWwuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBpbnRlcnZhbAorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0SW50ZXJ2YWwoKSB7CisJcmV0dXJuIGludGVydmFsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBtYXRjaCBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbXNnCXRoZSBkYXRlIGNvbXBhcmF0b3IgaXMgYXBwbGllZCB0byB0aGlzIE1lc3NhZ2UncworICAgICAqCQkJcmVjZWl2ZWQgZGF0ZQorICAgICAqIEByZXR1cm4JCXRydWUgaWYgdGhlIGNvbXBhcmlzb24gc3VjY2VlZHMsIG90aGVyd2lzZSBmYWxzZQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIG1hdGNoKE1lc3NhZ2UgbXNnKSB7CisJRGF0ZSBkOworCisJdHJ5IHsKKwkgICAgZCA9IG1zZy5nZXRSZWNlaXZlZERhdGUoKTsKKwl9IGNhdGNoIChFeGNlcHRpb24gZSkgeworCSAgICByZXR1cm4gZmFsc2U7CisJfQorCisJaWYgKGQgPT0gbnVsbCkKKwkgICAgcmV0dXJuIGZhbHNlOworCisJcmV0dXJuIGQuZ2V0VGltZSgpIDw9CisJCSAgICBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSAtICgobG9uZylpbnRlcnZhbCAqIDEwMDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVxdWFsaXR5IGNvbXBhcmlzb24uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKKwlpZiAoIShvYmogaW5zdGFuY2VvZiBPbGRlclRlcm0pKQorCSAgICByZXR1cm4gZmFsc2U7CisJcmV0dXJuIGludGVydmFsID09ICgoT2xkZXJUZXJtKW9iaikuaW50ZXJ2YWw7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcHV0ZSBhIGhhc2hDb2RlIGZvciB0aGlzIG9iamVjdC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworCXJldHVybiBpbnRlcnZhbDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvUmVmZXJyYWxFeGNlcHRpb24uamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9SZWZlcnJhbEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY0YTMzNWMKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvUmVmZXJyYWxFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDY1IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5pbWFwOworCitpbXBvcnQgamF2YXgubWFpbC5BdXRoZW50aWNhdGlvbkZhaWxlZEV4Y2VwdGlvbjsKKworLyoqCisgKiBBIHNwZWNpYWwga2luZCBvZiBBdXRoZW50aWNhdGlvbkZhaWxlZEV4Y2VwdGlvbiB0aGF0IGluZGljYXRlcyB0aGF0CisgKiB0aGUgcmVhc29uIGZvciB0aGUgZmFpbHVyZSB3YXMgYW4gSU1BUCBSRUZFUlJBTCBpbiB0aGUgcmVzcG9uc2UgY29kZS4KKyAqIFNlZSA8YSBocmVmPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMjIxLnR4dCI+UkZDIDIyMjE8L2E+IGZvciBkZXRhaWxzLgorICoKKyAqIEBzaW5jZSBKYXZhTWFpbCAxLjUuNQorICovCisKK3B1YmxpYyBjbGFzcyBSZWZlcnJhbEV4Y2VwdGlvbiBleHRlbmRzIEF1dGhlbnRpY2F0aW9uRmFpbGVkRXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgU3RyaW5nIHVybDsKKyAgICBwcml2YXRlIFN0cmluZyB0ZXh0OworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTM0MTQwNjM1NTg1OTYyODc2ODNMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhbiBSZWZlcnJhbEV4Y2VwdGlvbiB3aXRoIHRoZSBzcGVjaWZpZWQgVVJMIGFuZCB0ZXh0LgorICAgICAqCisgICAgICogQHBhcmFtIHRleHQJdGhlIGRldGFpbCBtZXNzYWdlCisgICAgICogQHBhcmFtIHVybAl0aGUgVVJMCisgICAgICovCisgICAgcHVibGljIFJlZmVycmFsRXhjZXB0aW9uKFN0cmluZyB1cmwsIFN0cmluZyB0ZXh0KSB7CisJc3VwZXIoIltSRUZFUlJBTCAiICsgdXJsICsgIl0gIiArIHRleHQpOworCXRoaXMudXJsID0gdXJsOworCXRoaXMudGV4dCA9IHRleHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBJTUFQIFVSTCBpbiB0aGUgcmVmZXJyYWwuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBJTUFQIFVSTAorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0VXJsKCkgeworCXJldHVybiB1cmw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSB0ZXh0IHNlbnQgYnkgdGhlIHNlcnZlciBhbG9uZyB3aXRoIHRoZSByZWZlcnJhbC4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIHRleHQKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFRleHQoKSB7CisJcmV0dXJuIHRleHQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL1Jlc3luY0RhdGEuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9SZXN5bmNEYXRhLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjVjMjk1ZQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9SZXN5bmNEYXRhLmphdmEKQEAgLTAsMCArMSwxMTggQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmltYXA7CisKK2ltcG9ydCBjb20uc3VuLm1haWwuaW1hcC5wcm90b2NvbC5VSURTZXQ7CisKKy8qKgorICogUmVzeW5jaHJvbml6YXRpb24gZGF0YSBhcyBkZWZpbmVkIGJ5IHRoZSBRUkVTWU5DIGV4dGVuc2lvbgorICogKDxBIEhSRUY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzUxNjIudHh0Ij5SRkMgNTE2MjwvQT4pLgorICogQW4gaW5zdGFuY2Ugb2YgPENPREU+UmVzeW5jRGF0YTwvQ09ERT4gaXMgc3VwcGxpZWQgdG8gdGhlCisgKiB7QGxpbmsgY29tLnN1bi5tYWlsLmltYXAuSU1BUEZvbGRlciNvcGVuKGludCxjb20uc3VuLm1haWwuaW1hcC5SZXN5bmNEYXRhKQorICogSU1BUEZvbGRlciBvcGVufSBtZXRob2QuCisgKiBUaGUgQ09ORFNUT1JFIDxDT0RFPlJlc3luY0RhdGE8L0NPREU+IGluc3RhbmNlIGlzIHVzZWQgdG8gZW5hYmxlIHRoZQorICogQ09ORFNUT1JFIGV4dGVuc2lvbgorICogKDxBIEhSRUY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzQ1NTEudHh0Ij5SRkMgNDU1MTwvQT4pLgorICogQSA8Q09ERT5SZXN5bmNEYXRhPC9DT0RFPiBpbnN0YW5jZSB3aXRoIHVpZHZhbGlkaXR5IGFuZCBtb2RzZXEgdmFsdWVzCisgKiBpcyB1c2VkIHRvIGVuYWJsZSB0aGUgUVJFU1lOQyBleHRlbnNpb24uCisgKgorICogQHNpbmNlCUphdmFNYWlsIDEuNS4xCisgKiBAYXV0aG9yCUJpbGwgU2hhbm5vbgorICovCisKK3B1YmxpYyBjbGFzcyBSZXN5bmNEYXRhIHsgCisgICAgcHJpdmF0ZSBsb25nIHVpZHZhbGlkaXR5ID0gLTE7CisgICAgcHJpdmF0ZSBsb25nIG1vZHNlcSA9IC0xOworICAgIHByaXZhdGUgVUlEU2V0W10gdWlkcyA9IG51bGw7CisKKyAgICAvKioKKyAgICAgKiBVc2VkIHRvIGVuYWJsZSBvbmx5IHRoZSBDT05EU1RPUkUgZXh0ZW5zaW9uLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgUmVzeW5jRGF0YSBDT05EU1RPUkUgPSBuZXcgUmVzeW5jRGF0YSgtMSwgLTEpOworCisgICAgLyoqCisgICAgICogVXNlZCB0byByZXBvcnQgb24gY2hhbmdlcyBzaW5jZSB0aGUgc3BlY2lmaWVkIG1vZHNlcS4KKyAgICAgKiBJZiB0aGUgVUlEVkFMSURJVFkgb2YgdGhlIGZvbGRlciBoYXMgY2hhbmdlZCwgbm8gbWVzc2FnZQorICAgICAqIGNoYW5nZXMgd2lsbCBiZSByZXBvcnRlZC4gIFRoZSBhcHBsaWNhdGlvbiBtdXN0IGNoZWNrIHRoZQorICAgICAqIFVJRFZBTElESVRZIG9mIHRoZSBmb2xkZXIgYWZ0ZXIgb3BlbiB0byBtYWtlIHN1cmUgaXQncworICAgICAqIHRoZSBleHBlY3RlZCBmb2xkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0JdWlkdmFsaWRpdHkJdGhlIFVJRFZBTElESVRZCisgICAgICogQHBhcmFtCW1vZHNlcQkJdGhlIE1PRFNFUQorICAgICAqLworICAgIHB1YmxpYyBSZXN5bmNEYXRhKGxvbmcgdWlkdmFsaWRpdHksIGxvbmcgbW9kc2VxKSB7CisJdGhpcy51aWR2YWxpZGl0eSA9IHVpZHZhbGlkaXR5OworCXRoaXMubW9kc2VxID0gbW9kc2VxOworCXRoaXMudWlkcyA9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogVXNlZCB0byBsaW1pdCB0aGUgcmVwb3J0ZWQgbWVzc2FnZSBjaGFuZ2VzIHRvIHRob3NlIHdpdGggVUlEcworICAgICAqIGluIHRoZSBzcGVjaWZpZWQgcmFuZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0JdWlkdmFsaWRpdHkJdGhlIFVJRFZBTElESVRZCisgICAgICogQHBhcmFtCW1vZHNlcQkJdGhlIE1PRFNFUQorICAgICAqIEBwYXJhbQl1aWRGaXJzdAl0aGUgZmlyc3QgVUlECisgICAgICogQHBhcmFtCXVpZExhc3QJCXRoZSBsYXN0IFVJRAorICAgICAqLworICAgIHB1YmxpYyBSZXN5bmNEYXRhKGxvbmcgdWlkdmFsaWRpdHksIGxvbmcgbW9kc2VxLAorCQkJCWxvbmcgdWlkRmlyc3QsIGxvbmcgdWlkTGFzdCkgeworCXRoaXMudWlkdmFsaWRpdHkgPSB1aWR2YWxpZGl0eTsKKwl0aGlzLm1vZHNlcSA9IG1vZHNlcTsKKwl0aGlzLnVpZHMgPSBuZXcgVUlEU2V0W10geyBuZXcgVUlEU2V0KHVpZEZpcnN0LCB1aWRMYXN0KSB9OworICAgIH0KKworICAgIC8qKgorICAgICAqIFVzZWQgdG8gbGltaXQgdGhlIHJlcG9ydGVkIG1lc3NhZ2UgY2hhbmdlcyB0byB0aG9zZSB3aXRoIHRoZQorICAgICAqIHNwZWNpZmllZCBVSURzLgorICAgICAqCisgICAgICogQHBhcmFtCXVpZHZhbGlkaXR5CXRoZSBVSURWQUxJRElUWQorICAgICAqIEBwYXJhbQltb2RzZXEJCXRoZSBNT0RTRVEKKyAgICAgKiBAcGFyYW0JdWlkcwkJdGhlIFVJRCB2YWx1ZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgUmVzeW5jRGF0YShsb25nIHVpZHZhbGlkaXR5LCBsb25nIG1vZHNlcSwgbG9uZ1tdIHVpZHMpIHsKKwl0aGlzLnVpZHZhbGlkaXR5ID0gdWlkdmFsaWRpdHk7CisJdGhpcy5tb2RzZXEgPSBtb2RzZXE7CisJdGhpcy51aWRzID0gVUlEU2V0LmNyZWF0ZVVJRFNldHModWlkcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBVSURWQUxJRElUWSB2YWx1ZSBzcGVjaWZpZWQgd2hlbiB0aGlzIGluc3RhbmNlIHdhcyBjcmVhdGVkLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgVUlEVkFMSURJVFkgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXRVSURWYWxpZGl0eSgpIHsKKwlyZXR1cm4gdWlkdmFsaWRpdHk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBNT0RTRVEgdmFsdWUgc3BlY2lmaWVkIHdoZW4gdGhpcyBpbnN0YW5jZSB3YXMgY3JlYXRlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIE1PRFNFUSB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldE1vZFNlcSgpIHsKKwlyZXR1cm4gbW9kc2VxOworICAgIH0KKworICAgIC8qCisgICAgICogUGFja2FnZSBwcml2YXRlLiAgSU1BUFByb3RvY29sIGdldHMgdGhpcyBkYXRhIGluZGlyZWN0bHkKKyAgICAgKiB1c2luZyBVdGlsaXR5LmdldFJlc3luY1VJRFNldCgpLgorICAgICAqLworICAgIFVJRFNldFtdIGdldFVJRFNldCgpIHsKKwlyZXR1cm4gdWlkczsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvUmlnaHRzLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvUmlnaHRzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDljNGNlMAotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9SaWdodHMuamF2YQpAQCAtMCwwICsxLDQ0NCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuaW1hcDsKKworaW1wb3J0IGphdmEudXRpbC4qOworCisvKioKKyAqIFRoZSBSaWdodHMgY2xhc3MgcmVwcmVzZW50cyB0aGUgc2V0IG9mIHJpZ2h0cyBmb3IgYW4gYXV0aGVudGljYXRpb24KKyAqIGlkZW50aWZpZXIgKGZvciBpbnN0YW5jZSwgYSB1c2VyIG9yIGEgZ3JvdXApLiA8cD4KKyAqCisgKiBBIHJpZ2h0IGlzIHJlcHJlc2VudGVkIGJ5IHRoZSA8Y29kZT5SaWdodHMuUmlnaHQ8L2NvZGU+IAorICogaW5uZXIgY2xhc3MuIDxwPgorICoKKyAqIEEgc2V0IG9mIHN0YW5kYXJkIHJpZ2h0cyBhcmUgcHJlZGVmaW5lZCAoc2VlIFJGQyAyMDg2KS4gIE1vc3QgZm9sZGVyCisgKiBpbXBsZW1lbnRhdGlvbnMgYXJlIGV4cGVjdGVkIHRvIHN1cHBvcnQgdGhlc2UgcmlnaHRzLiAgU29tZQorICogaW1wbGVtZW50YXRpb25zIG1heSBhbHNvIHN1cHBvcnQgc2l0ZS1kZWZpbmVkIHJpZ2h0cy4gPHA+CisgKgorICogVGhlIGZvbGxvd2luZyBjb2RlIHNhbXBsZSBpbGx1c3RyYXRlcyBob3cgdG8gZXhhbWluZSB5b3VyCisgKiByaWdodHMgZm9yIGEgZm9sZGVyLgorICogPHByZT4KKyAqCisgKiBSaWdodHMgcmlnaHRzID0gZm9sZGVyLm15UmlnaHRzKCk7CisgKgorICogLy8gQ2hlY2sgaWYgSSBjYW4gd3JpdGUgdGhpcyBmb2xkZXIKKyAqIGlmIChyaWdodHMuY29udGFpbnMoUmlnaHRzLlJpZ2h0LldSSVRFKSkKKyAqCVN5c3RlbS5vdXQucHJpbnRsbigiQ2FuIHdyaXRlIGZvbGRlciIpOworICoKKyAqIC8vIE5vdyBnaXZlIEpvZSBhbGwgbXkgcmlnaHRzLCBleGNlcHQgdGhlIGFiaWxpdHkgdG8gd3JpdGUgdGhlIGZvbGRlcgorICogcmlnaHRzLnJlbW92ZShSaWdodHMuUmlnaHQuV1JJVEUpOworICogQUNMIGFjbCA9IG5ldyBBQ0woImpvZSIsIHJpZ2h0cyk7CisgKiBmb2xkZXIuc2V0QUNMKGFjbCk7CisgKiA8L3ByZT4KKyAqIDxwPgorICoKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKi8KKworcHVibGljIGNsYXNzIFJpZ2h0cyBpbXBsZW1lbnRzIENsb25lYWJsZSB7CisKKyAgICBwcml2YXRlIGJvb2xlYW5bXSByaWdodHMgPSBuZXcgYm9vbGVhblsxMjhdOwkvLyBYWFgKKworICAgIC8qKgorICAgICAqIFRoaXMgaW5uZXIgY2xhc3MgcmVwcmVzZW50cyBhbiBpbmRpdmlkdWFsIHJpZ2h0LiBBIHNldAorICAgICAqIG9mIHN0YW5kYXJkIHJpZ2h0cyBvYmplY3RzIGFyZSBwcmVkZWZpbmVkIGhlcmUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBSaWdodCB7CisJcHJpdmF0ZSBzdGF0aWMgUmlnaHRbXSBjYWNoZSA9IG5ldyBSaWdodFsxMjhdOworCisJLy8gWFhYIC0gaW5pdGlhbGl6YXRpb24gb3JkZXI/CisJLyoqCisJICogTG9va3VwIC0gbWFpbGJveCBpcyB2aXNpYmxlIHRvIExJU1QvTFNVQiBjb21tYW5kcy4KKwkgKi8KKwlwdWJsaWMgc3RhdGljIGZpbmFsIFJpZ2h0IExPT0tVUCA9IGdldEluc3RhbmNlKCdsJyk7CisKKwkvKioKKwkgKiBSZWFkIC0gU0VMRUNUIHRoZSBtYWlsYm94LCBwZXJmb3JtIENIRUNLLCBGRVRDSCwgUEFSVElBTCwKKwkgKiBTRUFSQ0gsIENPUFkgZnJvbSBtYWlsYm94CisJICovCisJcHVibGljIHN0YXRpYyBmaW5hbCBSaWdodCBSRUFEID0gZ2V0SW5zdGFuY2UoJ3InKTsKKworCS8qKgorCSAqIEtlZXAgc2Vlbi91bnNlZW4gaW5mb3JtYXRpb24gYWNyb3NzIHNlc3Npb25zIC0gU1RPUkUgXFNFRU4gZmxhZy4KKwkgKi8KKwlwdWJsaWMgc3RhdGljIGZpbmFsIFJpZ2h0IEtFRVBfU0VFTiA9IGdldEluc3RhbmNlKCdzJyk7CisKKwkvKioKKwkgKiBXcml0ZSAtIFNUT1JFIGZsYWdzIG90aGVyIHRoYW4gXFNFRU4gYW5kIFxERUxFVEVELgorCSAqLworCXB1YmxpYyBzdGF0aWMgZmluYWwgUmlnaHQgV1JJVEUgPSBnZXRJbnN0YW5jZSgndycpOworCisJLyoqCisJICogSW5zZXJ0IC0gcGVyZm9ybSBBUFBFTkQsIENPUFkgaW50byBtYWlsYm94LgorCSAqLworCXB1YmxpYyBzdGF0aWMgZmluYWwgUmlnaHQgSU5TRVJUID0gZ2V0SW5zdGFuY2UoJ2knKTsKKworCS8qKgorCSAqIFBvc3QgLSBzZW5kIG1haWwgdG8gc3VibWlzc2lvbiBhZGRyZXNzIGZvciBtYWlsYm94LAorCSAqIG5vdCBlbmZvcmNlZCBieSBJTUFQNCBpdHNlbGYuCisJICovCisJcHVibGljIHN0YXRpYyBmaW5hbCBSaWdodCBQT1NUID0gZ2V0SW5zdGFuY2UoJ3AnKTsKKworCS8qKgorCSAqIENyZWF0ZSAtIENSRUFURSBuZXcgc3ViLW1haWxib3hlcyBpbiBhbnkgaW1wbGVtZW50YXRpb24tZGVmaW5lZAorCSAqIGhpZXJhcmNoeSwgUkVOQU1FIG9yIERFTEVURSBtYWlsYm94LgorCSAqLworCXB1YmxpYyBzdGF0aWMgZmluYWwgUmlnaHQgQ1JFQVRFID0gZ2V0SW5zdGFuY2UoJ2MnKTsKKworCS8qKgorCSAqIERlbGV0ZSAtIFNUT1JFIFxERUxFVEVEIGZsYWcsIHBlcmZvcm0gRVhQVU5HRS4KKwkgKi8KKwlwdWJsaWMgc3RhdGljIGZpbmFsIFJpZ2h0IERFTEVURSA9IGdldEluc3RhbmNlKCdkJyk7CisKKwkvKioKKwkgKiBBZG1pbmlzdGVyIC0gcGVyZm9ybSBTRVRBQ0wuCisJICovCisJcHVibGljIHN0YXRpYyBmaW5hbCBSaWdodCBBRE1JTklTVEVSID0gZ2V0SW5zdGFuY2UoJ2EnKTsKKworCWNoYXIgcmlnaHQ7CS8vIHRoZSByaWdodCByZXByZXNlbnRlZCBieSB0aGlzIFJpZ2h0IG9iamVjdAorCisJLyoqCisJICogUHJpdmF0ZSBjb25zdHJ1Y3RvciB1c2VkIG9ubHkgYnkgZ2V0SW5zdGFuY2UuCisJICovCisJcHJpdmF0ZSBSaWdodChjaGFyIHJpZ2h0KSB7CisJICAgIGlmICgoaW50KXJpZ2h0ID49IDEyOCkKKwkJdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiUmlnaHQgbXVzdCBiZSBBU0NJSSIpOworCSAgICB0aGlzLnJpZ2h0ID0gcmlnaHQ7CisJfQorCisJLyoqCisJICogR2V0IGEgUmlnaHQgb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgc3BlY2lmaWVkIGNoYXJhY3Rlci4KKwkgKiBDaGFyYWN0ZXJzIGFyZSBhc3NpZ25lZCBwZXIgUkZDIDIwODYuCisJICoKKwkgKiBAcGFyYW0JcmlnaHQJdGhlIGNoYXJhY3RlciByZXByZXNlbnRpbmcgdGhlIHJpZ2h0CisJICogQHJldHVybgkJdGhlIFJpZ2h0IG9iamVjdAorCSAqLworCXB1YmxpYyBzdGF0aWMgc3luY2hyb25pemVkIFJpZ2h0IGdldEluc3RhbmNlKGNoYXIgcmlnaHQpIHsKKwkgICAgaWYgKChpbnQpcmlnaHQgPj0gMTI4KQorCQl0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJSaWdodCBtdXN0IGJlIEFTQ0lJIik7CisJICAgIGlmIChjYWNoZVsoaW50KXJpZ2h0XSA9PSBudWxsKQorCQljYWNoZVsoaW50KXJpZ2h0XSA9IG5ldyBSaWdodChyaWdodCk7CisJICAgIHJldHVybiBjYWNoZVsoaW50KXJpZ2h0XTsKKwl9CisKKwlAT3ZlcnJpZGUKKwlwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworCSAgICByZXR1cm4gU3RyaW5nLnZhbHVlT2YocmlnaHQpOworCX0KKyAgICB9CisKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCBhbiBlbXB0eSBSaWdodHMgb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyBSaWdodHMoKSB7IH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCBhIFJpZ2h0cyBvYmplY3QgaW5pdGlhbGl6ZWQgd2l0aCB0aGUgZ2l2ZW4gcmlnaHRzLgorICAgICAqCisgICAgICogQHBhcmFtIHJpZ2h0cwl0aGUgcmlnaHRzIGZvciBpbml0aWFsaXphdGlvbgorICAgICAqLworICAgIHB1YmxpYyBSaWdodHMoUmlnaHRzIHJpZ2h0cykgeworCVN5c3RlbS5hcnJheWNvcHkocmlnaHRzLnJpZ2h0cywgMCwgdGhpcy5yaWdodHMsIDAsIHRoaXMucmlnaHRzLmxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGEgUmlnaHRzIG9iamVjdCBpbml0aWFsaXplZCB3aXRoIHRoZSBnaXZlbiByaWdodHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmlnaHRzCXRoZSByaWdodHMgZm9yIGluaXRpYWxpemF0aW9uCisgICAgICovCisgICAgcHVibGljIFJpZ2h0cyhTdHJpbmcgcmlnaHRzKSB7CisJZm9yIChpbnQgaSA9IDA7IGkgPCByaWdodHMubGVuZ3RoKCk7IGkrKykKKwkgICAgYWRkKFJpZ2h0LmdldEluc3RhbmNlKHJpZ2h0cy5jaGFyQXQoaSkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYSBSaWdodHMgb2JqZWN0IGluaXRpYWxpemVkIHdpdGggdGhlIGdpdmVuIHJpZ2h0LgorICAgICAqCisgICAgICogQHBhcmFtIHJpZ2h0CXRoZSByaWdodCBmb3IgaW5pdGlhbGl6YXRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgUmlnaHRzKFJpZ2h0IHJpZ2h0KSB7CisJdGhpcy5yaWdodHNbKGludClyaWdodC5yaWdodF0gPSB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZCB0aGUgc3BlY2lmaWVkIHJpZ2h0IHRvIHRoaXMgUmlnaHRzIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSByaWdodAl0aGUgcmlnaHQgdG8gYWRkCisgICAgICovCisgICAgcHVibGljIHZvaWQgYWRkKFJpZ2h0IHJpZ2h0KSB7CisJdGhpcy5yaWdodHNbKGludClyaWdodC5yaWdodF0gPSB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZCBhbGwgdGhlIHJpZ2h0cyBpbiB0aGUgZ2l2ZW4gUmlnaHRzIG9iamVjdCB0byB0aGlzCisgICAgICogUmlnaHRzIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSByaWdodHMJUmlnaHRzIG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFkZChSaWdodHMgcmlnaHRzKSB7CisJZm9yIChpbnQgaSA9IDA7IGkgPCByaWdodHMucmlnaHRzLmxlbmd0aDsgaSsrKQorCSAgICBpZiAocmlnaHRzLnJpZ2h0c1tpXSkKKwkJdGhpcy5yaWdodHNbaV0gPSB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZSB0aGUgc3BlY2lmaWVkIHJpZ2h0IGZyb20gdGhpcyBSaWdodHMgb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtCXJpZ2h0IAl0aGUgcmlnaHQgdG8gYmUgcmVtb3ZlZAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlbW92ZShSaWdodCByaWdodCkgeworCXRoaXMucmlnaHRzWyhpbnQpcmlnaHQucmlnaHRdID0gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlIGFsbCByaWdodHMgaW4gdGhlIGdpdmVuIFJpZ2h0cyBvYmplY3QgZnJvbSB0aGlzIAorICAgICAqIFJpZ2h0cyBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0JcmlnaHRzIAl0aGUgcmlnaHRzIHRvIGJlIHJlbW92ZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZW1vdmUoUmlnaHRzIHJpZ2h0cykgeworCWZvciAoaW50IGkgPSAwOyBpIDwgcmlnaHRzLnJpZ2h0cy5sZW5ndGg7IGkrKykKKwkgICAgaWYgKHJpZ2h0cy5yaWdodHNbaV0pCisJCXRoaXMucmlnaHRzW2ldID0gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2sgd2hldGhlciB0aGUgc3BlY2lmaWVkIHJpZ2h0IGlzIHByZXNlbnQgaW4gdGhpcyBSaWdodHMgb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtCXJpZ2h0CXRoZSBSaWdodCB0byBjaGVjaworICAgICAqIEByZXR1cm4gCQl0cnVlIG9mIHRoZSBnaXZlbiByaWdodCBpcyBwcmVzZW50LCBvdGhlcndpc2UgZmFsc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoUmlnaHQgcmlnaHQpIHsKKwlyZXR1cm4gdGhpcy5yaWdodHNbKGludClyaWdodC5yaWdodF07CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2sgd2hldGhlciBhbGwgdGhlIHJpZ2h0cyBpbiB0aGUgc3BlY2lmaWVkIFJpZ2h0cyBvYmplY3QgYXJlCisgICAgICogcHJlc2VudCBpbiB0aGlzIFJpZ2h0cyBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0JcmlnaHRzCXRoZSBSaWdodHMgdG8gY2hlY2sKKyAgICAgKiBAcmV0dXJuCXRydWUgaWYgYWxsIHJpZ2h0cyBpbiB0aGUgZ2l2ZW4gUmlnaHRzIG9iamVjdCBhcmUgcHJlc2VudCwgCisgICAgICoJCW90aGVyd2lzZSBmYWxzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhSaWdodHMgcmlnaHRzKSB7CisJZm9yIChpbnQgaSA9IDA7IGkgPCByaWdodHMucmlnaHRzLmxlbmd0aDsgaSsrKQorCSAgICBpZiAocmlnaHRzLnJpZ2h0c1tpXSAmJiAhdGhpcy5yaWdodHNbaV0pCisJCXJldHVybiBmYWxzZTsKKworCS8vIElmIHdlJ3ZlIG1hZGUgaXQgdGlsbCBoZXJlLCByZXR1cm4gdHJ1ZQorCXJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrIHdoZXRoZXIgdGhlIHR3byBSaWdodHMgb2JqZWN0cyBhcmUgZXF1YWwuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRydWUgaWYgdGhleSdyZSBlcXVhbAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CisJaWYgKCEob2JqIGluc3RhbmNlb2YgUmlnaHRzKSkKKwkgICAgcmV0dXJuIGZhbHNlOworCisJUmlnaHRzIHJpZ2h0cyA9IChSaWdodHMpb2JqOworCisJZm9yIChpbnQgaSA9IDA7IGkgPCByaWdodHMucmlnaHRzLmxlbmd0aDsgaSsrKQorCSAgICBpZiAocmlnaHRzLnJpZ2h0c1tpXSAhPSB0aGlzLnJpZ2h0c1tpXSkKKwkJcmV0dXJuIGZhbHNlOworCisJcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcHV0ZSBhIGhhc2ggY29kZSBmb3IgdGhpcyBSaWdodHMgb2JqZWN0LgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgaGFzaCBjb2RlCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKwlpbnQgaGFzaCA9IDA7CisJZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLnJpZ2h0cy5sZW5ndGg7IGkrKykKKwkgICAgaWYgKHRoaXMucmlnaHRzW2ldKQorCQloYXNoKys7CisJcmV0dXJuIGhhc2g7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIGFsbCB0aGUgcmlnaHRzIGluIHRoaXMgUmlnaHRzIG9iamVjdC4gIFJldHVybnMKKyAgICAgKiBhbiBhcnJheSBvZiBzaXplIHplcm8gaWYgbm8gcmlnaHRzIGFyZSBzZXQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCWFycmF5IG9mIFJpZ2h0cy5SaWdodCBvYmplY3RzIHJlcHJlc2VudGluZyByaWdodHMKKyAgICAgKi8KKyAgICBwdWJsaWMgUmlnaHRbXSBnZXRSaWdodHMoKSB7CisJTGlzdDxSaWdodD4gdiA9IG5ldyBBcnJheUxpc3Q8PigpOworCWZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy5yaWdodHMubGVuZ3RoOyBpKyspCisJICAgIGlmICh0aGlzLnJpZ2h0c1tpXSkKKwkJdi5hZGQoUmlnaHQuZ2V0SW5zdGFuY2UoKGNoYXIpaSkpOworCXJldHVybiB2LnRvQXJyYXkobmV3IFJpZ2h0W3Yuc2l6ZSgpXSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGNsb25lIG9mIHRoaXMgUmlnaHRzIG9iamVjdC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgeworCVJpZ2h0cyByID0gbnVsbDsKKwl0cnkgeworCSAgICByID0gKFJpZ2h0cylzdXBlci5jbG9uZSgpOworCSAgICByLnJpZ2h0cyA9IG5ldyBib29sZWFuWzEyOF07CisJICAgIFN5c3RlbS5hcnJheWNvcHkodGhpcy5yaWdodHMsIDAsIHIucmlnaHRzLCAwLCB0aGlzLnJpZ2h0cy5sZW5ndGgpOworCX0gY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGNleCkgeworCSAgICAvLyBpZ25vcmUsIGNhbid0IGhhcHBlbgorCX0KKwlyZXR1cm4gcjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworCVN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworCWZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy5yaWdodHMubGVuZ3RoOyBpKyspCisJICAgIGlmICh0aGlzLnJpZ2h0c1tpXSkKKwkJc2IuYXBwZW5kKChjaGFyKWkpOworCXJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KKworICAgIC8qKioqKgorICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZyBhcmd2W10pIHRocm93cyBFeGNlcHRpb24geworCS8vIGEgbmV3IHJpZ2h0cyBvYmplY3QKKwlSaWdodHMgZjEgPSBuZXcgUmlnaHRzKCk7CisJZjEuYWRkKFJpZ2h0cy5SaWdodC5SRUFEKTsKKwlmMS5hZGQoUmlnaHRzLlJpZ2h0LldSSVRFKTsKKwlmMS5hZGQoUmlnaHRzLlJpZ2h0LkNSRUFURSk7CisJZjEuYWRkKFJpZ2h0cy5SaWdodC5ERUxFVEUpOworCisJLy8gY2hlY2sgY29weSBjb25zdHJ1Y3RvcgorCVJpZ2h0cyBmYyA9IG5ldyBSaWdodHMoZjEpOworCWlmIChmMS5lcXVhbHMoZmMpICYmIGZjLmVxdWFscyhmMSkpCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigic3VjY2VzcyIpOworCWVsc2UKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJmYWlsIik7CisKKwkvLyBjaGVjayBjbG9uZQorCWZjID0gKFJpZ2h0cylmMS5jbG9uZSgpOworCWlmIChmMS5lcXVhbHMoZmMpICYmIGZjLmVxdWFscyhmMSkpCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigic3VjY2VzcyIpOworCWVsc2UKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJmYWlsIik7CisKKwkvLyBhZGQgYSByaWdodCBhbmQgbWFrZSBzdXJlIGl0IHN0aWxsIHdvcmtzIHJpZ2h0CisJZjEuYWRkKFJpZ2h0cy5SaWdodC5BRE1JTklTVEVSKTsKKworCS8vIHNob3VsZG4ndCBiZSBlcXVhbCBoZXJlCisJaWYgKCFmMS5lcXVhbHMoZmMpICYmICFmYy5lcXVhbHMoZjEpKQorCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oInN1Y2Nlc3MiKTsKKwllbHNlCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZmFpbCIpOworCisJLy8gY2hlY2sgY2xvbmUKKwlmYyA9IChSaWdodHMpZjEuY2xvbmUoKTsKKwlpZiAoZjEuZXF1YWxzKGZjKSAmJiBmYy5lcXVhbHMoZjEpKQorCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oInN1Y2Nlc3MiKTsKKwllbHNlCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZmFpbCIpOworCisJZmMuYWRkKFJpZ2h0cy5SaWdodC5JTlNFUlQpOworCWlmICghZjEuZXF1YWxzKGZjKSAmJiAhZmMuZXF1YWxzKGYxKSkKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJzdWNjZXNzIik7CisJZWxzZQorCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oImZhaWwiKTsKKworCS8vIGNoZWNrIGNvcHkgY29uc3RydWN0b3IKKwlmYyA9IG5ldyBSaWdodHMoZjEpOworCWlmIChmMS5lcXVhbHMoZmMpICYmIGZjLmVxdWFscyhmMSkpCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigic3VjY2VzcyIpOworCWVsc2UKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJmYWlsIik7CisKKwkvLyBhbm90aGVyIG5ldyByaWdodHMgb2JqZWN0CisJUmlnaHRzIGYyID0gbmV3IFJpZ2h0cyhSaWdodHMuUmlnaHQuUkVBRCk7CisJZjIuYWRkKFJpZ2h0cy5SaWdodC5XUklURSk7CisKKwlpZiAoZjEuY29udGFpbnMoUmlnaHRzLlJpZ2h0LlJFQUQpKQorCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oInN1Y2Nlc3MiKTsKKwllbHNlCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZmFpbCIpOworCQkKKwlpZiAoZjEuY29udGFpbnMoUmlnaHRzLlJpZ2h0LldSSVRFKSkKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJzdWNjZXNzIik7CisJZWxzZQorCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oImZhaWwiKTsKKworCWlmIChmMS5jb250YWlucyhSaWdodHMuUmlnaHQuQ1JFQVRFKSkKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJzdWNjZXNzIik7CisJZWxzZQorCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oImZhaWwiKTsKKworCWlmIChmMS5jb250YWlucyhSaWdodHMuUmlnaHQuREVMRVRFKSkKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJzdWNjZXNzIik7CisJZWxzZQorCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oImZhaWwiKTsKKworCWlmIChmMi5jb250YWlucyhSaWdodHMuUmlnaHQuV1JJVEUpKQorCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oInN1Y2Nlc3MiKTsKKwllbHNlCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZmFpbCIpOworCisKKwlTeXN0ZW0ub3V0LnByaW50bG4oIi0tLS0tLS0tLS0tLS0tLS0iKTsKKworCVJpZ2h0W10gciA9IGYxLmdldFJpZ2h0cygpOworCWZvciAoaW50IGkgPSAwOyBpIDwgci5sZW5ndGg7IGkrKykKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKHJbaV0pOworCVN5c3RlbS5vdXQucHJpbnRsbigiLS0tLS0tLS0tLS0tLS0tLSIpOworCisJaWYgKGYxLmNvbnRhaW5zKGYyKSkgLy8gdGhpcyBzaG91bGQgYmUgdHJ1ZQorCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oInN1Y2Nlc3MiKTsKKwllbHNlCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZmFpbCIpOworCisJaWYgKCFmMi5jb250YWlucyhmMSkpIC8vIHRoaXMgc2hvdWxkIGJlIGZhbHNlCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigic3VjY2VzcyIpOworCWVsc2UKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJmYWlsIik7CisKKwlSaWdodHMgZjMgPSBuZXcgUmlnaHRzKCk7CisJZjMuYWRkKFJpZ2h0cy5SaWdodC5SRUFEKTsKKwlmMy5hZGQoUmlnaHRzLlJpZ2h0LldSSVRFKTsKKwlmMy5hZGQoUmlnaHRzLlJpZ2h0LkNSRUFURSk7CisJZjMuYWRkKFJpZ2h0cy5SaWdodC5ERUxFVEUpOworCWYzLmFkZChSaWdodHMuUmlnaHQuQURNSU5JU1RFUik7CisJZjMuYWRkKFJpZ2h0cy5SaWdodC5MT09LVVApOworCisJZjEuYWRkKFJpZ2h0cy5SaWdodC5MT09LVVApOworCisJaWYgKGYxLmVxdWFscyhmMykpCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZXF1YWxzIHN1Y2Nlc3MiKTsKKwllbHNlCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZmFpbCIpOworCWlmIChmMy5lcXVhbHMoZjEpKQorCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oImVxdWFscyBzdWNjZXNzIik7CisJZWxzZQorCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oImZhaWwiKTsKKwlTeXN0ZW0ub3V0LnByaW50bG4oImYxIGhhc2ggY29kZSAiICsgZjEuaGFzaENvZGUoKSk7CisJU3lzdGVtLm91dC5wcmludGxuKCJmMyBoYXNoIGNvZGUgIiArIGYzLmhhc2hDb2RlKCkpOworCWlmIChmMS5oYXNoQ29kZSgpID09IGYzLmhhc2hDb2RlKCkpCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigic3VjY2VzcyIpOworCWVsc2UKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJmYWlsIik7CisgICAgfQorICAgICoqKiovCit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvU29ydFRlcm0uamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9Tb3J0VGVybS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZmNjI0ZTgKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvU29ydFRlcm0uamF2YQpAQCAtMCwwICsxLDgxIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5pbWFwOworCisvKioKKyAqIEEgcGFydGljdWxhciBzb3J0IGNyaXRlcmlhLCBhcyBkZWZpbmVkIGJ5CisgKiA8QSBIUkVGPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmM1MjU2LnR4dCI+UkZDIDUyNTY8L0E+LgorICogU29ydCBjcml0ZXJpYSBhcmUgdXNlZCB3aXRoIHRoZQorICoge0BsaW5rIElNQVBGb2xkZXIjZ2V0U29ydGVkTWVzc2FnZXMgZ2V0U29ydGVkTWVzc2FnZXN9IG1ldGhvZC4KKyAqIE11bHRpcGxlIHNvcnQgY3JpdGVyaWEgYXJlIHNwZWNpZmllZCBpbiBhbiBhcnJheSB3aXRoIHRoZSBvcmRlciBpbgorICogdGhlIGFycmF5IHNwZWNpZnlpbmcgdGhlIG9yZGVyIGluIHdoaWNoIHRoZSBzb3J0IGNyaXRlcmlhIGFyZSBhcHBsaWVkLgorICoKKyAqIEBzaW5jZSBKYXZhTWFpbCAxLjQuNAorICovCitwdWJsaWMgZmluYWwgY2xhc3MgU29ydFRlcm0geworICAgIC8qKgorICAgICAqIFNvcnQgYnkgbWVzc2FnZSBhcnJpdmFsIGRhdGUgYW5kIHRpbWUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTb3J0VGVybSBBUlJJVkFMID0gbmV3IFNvcnRUZXJtKCJBUlJJVkFMIik7CisKKyAgICAvKioKKyAgICAgKiBTb3J0IGJ5IGVtYWlsIGFkZHJlc3Mgb2YgZmlyc3QgQ2MgcmVjaXBpZW50LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU29ydFRlcm0gQ0MgPSBuZXcgU29ydFRlcm0oIkNDIik7CisKKyAgICAvKioKKyAgICAgKiBTb3J0IGJ5IHNlbnQgZGF0ZSBhbmQgdGltZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFNvcnRUZXJtIERBVEUgPSBuZXcgU29ydFRlcm0oIkRBVEUiKTsKKworICAgIC8qKgorICAgICAqIFNvcnQgYnkgZmlyc3QgRnJvbSBlbWFpbCBhZGRyZXNzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU29ydFRlcm0gRlJPTSA9IG5ldyBTb3J0VGVybSgiRlJPTSIpOworCisgICAgLyoqCisgICAgICogUmV2ZXJzZSB0aGUgc29ydCBvcmRlciBvZiB0aGUgZm9sbG93aW5nIGl0ZW0uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTb3J0VGVybSBSRVZFUlNFID0gbmV3IFNvcnRUZXJtKCJSRVZFUlNFIik7CisKKyAgICAvKioKKyAgICAgKiBTb3J0IGJ5IHRoZSBtZXNzYWdlIHNpemUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTb3J0VGVybSBTSVpFID0gbmV3IFNvcnRUZXJtKCJTSVpFIik7CisKKyAgICAvKioKKyAgICAgKiBTb3J0IGJ5IHRoZSBiYXNlIHN1YmplY3QgdGV4dC4gIE5vdGUgdGhhdCB0aGUgImJhc2Ugc3ViamVjdCIKKyAgICAgKiBpcyBkZWZpbmVkIGJ5IFJGQyA1MjU2IGFuZCBkb2Vzbid0IGluY2x1ZGUgaXRlbXMgc3VjaCBhcyAiUmU6IgorICAgICAqIGluIHRoZSBzdWJqZWN0IGhlYWRlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFNvcnRUZXJtIFNVQkpFQ1QgPSBuZXcgU29ydFRlcm0oIlNVQkpFQ1QiKTsKKworICAgIC8qKgorICAgICAqIFNvcnQgYnkgZW1haWwgYWRkcmVzcyBvZiBmaXJzdCBUbyByZWNpcGllbnQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTb3J0VGVybSBUTyA9IG5ldyBTb3J0VGVybSgiVE8iKTsKKworICAgIHByaXZhdGUgU3RyaW5nIHRlcm07CisgICAgcHJpdmF0ZSBTb3J0VGVybShTdHJpbmcgdGVybSkgeworCXRoaXMudGVybSA9IHRlcm07CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKwlyZXR1cm4gdGVybTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvVXRpbGl0eS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL1V0aWxpdHkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40M2YxOTk4Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL1V0aWxpdHkuamF2YQpAQCAtMCwwICsxLDIxNCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuaW1hcDsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkNvbXBhcmF0b3I7CisKK2ltcG9ydCBqYXZheC5tYWlsLio7CisKK2ltcG9ydCBjb20uc3VuLm1haWwuaW1hcC5wcm90b2NvbC5NZXNzYWdlU2V0OworaW1wb3J0IGNvbS5zdW4ubWFpbC5pbWFwLnByb3RvY29sLlVJRFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCisvKioKKyAqIEhvbGRlciBmb3Igc29tZSBzdGF0aWMgdXRpbGl0eSBtZXRob2RzLgorICoKKyAqIEBhdXRob3IgIEpvaG4gTWFuaQorICogQGF1dGhvciAgQmlsbCBTaGFubm9uCisgKi8KKworcHVibGljIGZpbmFsIGNsYXNzIFV0aWxpdHkgeworCisgICAgLy8gQ2Fubm90IGJlIGluaXRpYWxpemVkCisgICAgcHJpdmF0ZSBVdGlsaXR5KCkgeyB9CisKKyAgICAvKioKKyAgICAgKiBSdW4gdGhydSB0aGUgZ2l2ZW4gYXJyYXkgb2YgbWVzc2FnZXMsIGFwcGx5IHRoZSBnaXZlbgorICAgICAqIENvbmRpdGlvbiBvbiBlYWNoIG1lc3NhZ2UgYW5kIGdlbmVyYXRlIHNldHMgb2YgY29udGlndW91cyAKKyAgICAgKiBzZXF1ZW5jZS1udW1iZXJzIGZvciB0aGUgc3VjY2Vzc2Z1bCBtZXNzYWdlcy4gSWYgYSBtZXNzYWdlIAorICAgICAqIGluIHRoZSBnaXZlbiBhcnJheSBpcyBmb3VuZCB0byBiZSBleHB1bmdlZCwgaXQgaXMgaWdub3JlZC4KKyAgICAgKgorICAgICAqIEFTU0VSVDogU2luY2UgdGhpcyBtZXRob2QgdXNlcyBhbmQgcmV0dXJucyBtZXNzYWdlIHNlcXVlbmNlCisgICAgICogbnVtYmVycywgeW91IHNob3VsZCB1c2UgdGhpcyBtZXRob2Qgb25seSB3aGVuIGhvbGRpbmcgdGhlCisgICAgICogbWVzc2FnZUNhY2hlTG9jay4KKyAgICAgKgorICAgICAqIEBwYXJhbQltc2dzCXRoZSBtZXNzYWdlcworICAgICAqIEBwYXJhbQljb25kCXRoZSBjb25kaXRpb24gdG8gY2hlY2sKKyAgICAgKiBAcmV0dXJuCQl0aGUgTWVzc2FnZVNldCBhcnJheQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgTWVzc2FnZVNldFtdIHRvTWVzc2FnZVNldChNZXNzYWdlW10gbXNncywgQ29uZGl0aW9uIGNvbmQpIHsKKwlMaXN0PE1lc3NhZ2VTZXQ+IHYgPSBuZXcgQXJyYXlMaXN0PD4oMSk7CisJaW50IGN1cnJlbnQsIG5leHQ7CisKKwlJTUFQTWVzc2FnZSBtc2c7CisJZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisJICAgIG1zZyA9IChJTUFQTWVzc2FnZSltc2dzW2ldOworCSAgICBpZiAobXNnLmlzRXhwdW5nZWQoKSkgLy8gZXhwdW5nZWQgbWVzc2FnZSwgc2tpcCBpdAorCQljb250aW51ZTsKKworCSAgICBjdXJyZW50ID0gbXNnLmdldFNlcXVlbmNlTnVtYmVyKCk7CisJICAgIC8vIEFwcGx5IHRoZSBjb25kaXRpb24uIElmIGl0IGZhaWxzLCBza2lwIGl0LgorCSAgICBpZiAoKGNvbmQgIT0gbnVsbCkgJiYgIWNvbmQudGVzdChtc2cpKQorCQljb250aW51ZTsKKwkgICAgCisJICAgIE1lc3NhZ2VTZXQgc2V0ID0gbmV3IE1lc3NhZ2VTZXQoKTsKKwkgICAgc2V0LnN0YXJ0ID0gY3VycmVudDsKKworCSAgICAvLyBMb29rIGZvciBjb250aWd1b3VzIHNlcXVlbmNlIG51bWJlcnMKKwkgICAgZm9yICgrK2k7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisJCS8vIGdldCBuZXh0IG1lc3NhZ2UKKwkJbXNnID0gKElNQVBNZXNzYWdlKW1zZ3NbaV07CisKKwkJaWYgKG1zZy5pc0V4cHVuZ2VkKCkpIC8vIGV4cHVuZ2VkIG1lc3NhZ2UsIHNraXAgaXQKKwkJICAgIGNvbnRpbnVlOworCQluZXh0ID0gbXNnLmdldFNlcXVlbmNlTnVtYmVyKCk7CisKKwkJLy8gRG9lcyB0aGlzIG1lc3NhZ2UgbWF0Y2ggb3VyIGNvbmRpdGlvbiA/CisJCWlmICgoY29uZCAhPSBudWxsKSAmJiAhY29uZC50ZXN0KG1zZykpCisJCSAgICBjb250aW51ZTsKKwkJCisJCWlmIChuZXh0ID09IGN1cnJlbnQrMSkKKwkJICAgIGN1cnJlbnQgPSBuZXh0OworCQllbHNlIHsgLy8gYnJlYWsgaW4gc2VxdWVuY2UKKwkJICAgIC8vIFdlIG5lZWQgdG8gcmVleGFtaW5lIHRoaXMgbWVzc2FnZSBhdCB0aGUgdG9wIG9mCisJCSAgICAvLyB0aGUgb3V0ZXIgbG9vcCwgc28gZGVjcmVtZW50ICdpJyB0byBjYW5jZWwgdGhlCisJCSAgICAvLyBvdXRlciBsb29wJ3MgYXV0b2luY3JlbWVudCAKKwkJICAgIGktLTsKKwkJICAgIGJyZWFrOworCQl9CisJICAgIH0KKwkgICAgc2V0LmVuZCA9IGN1cnJlbnQ7CisJICAgIHYuYWRkKHNldCk7CisJfQorCQorCWlmICh2LmlzRW1wdHkoKSkgLy8gTm8gdmFsaWQgbWVzc2FnZXMKKwkgICAgcmV0dXJuIG51bGw7CisJZWxzZSB7CisJICAgIHJldHVybiB2LnRvQXJyYXkobmV3IE1lc3NhZ2VTZXRbdi5zaXplKCldKTsKKwl9CisgICAgfQorICAgIC8qKgorICAgICAqIFNvcnQgKGEgY29weSBvZikgdGhlIGdpdmVuIGFycmF5IG9mIG1lc3NhZ2VzIGFuZCB0aGVuCisgICAgICogcnVuIHRocnUgdGhlIHNvcnRlZCBhcnJheSBvZiBtZXNzYWdlcywgYXBwbHkgdGhlIGdpdmVuCisgICAgICogQ29uZGl0aW9uIG9uIGVhY2ggbWVzc2FnZSBhbmQgZ2VuZXJhdGUgc2V0cyBvZiBjb250aWd1b3VzIAorICAgICAqIHNlcXVlbmNlLW51bWJlcnMgZm9yIHRoZSBzdWNjZXNzZnVsIG1lc3NhZ2VzLiBJZiBhIG1lc3NhZ2UgCisgICAgICogaW4gdGhlIGdpdmVuIGFycmF5IGlzIGZvdW5kIHRvIGJlIGV4cHVuZ2VkLCBpdCBpcyBpZ25vcmVkLgorICAgICAqCisgICAgICogQVNTRVJUOiBTaW5jZSB0aGlzIG1ldGhvZCB1c2VzIGFuZCByZXR1cm5zIG1lc3NhZ2Ugc2VxdWVuY2UKKyAgICAgKiBudW1iZXJzLCB5b3Ugc2hvdWxkIHVzZSB0aGlzIG1ldGhvZCBvbmx5IHdoZW4gaG9sZGluZyB0aGUKKyAgICAgKiBtZXNzYWdlQ2FjaGVMb2NrLgorICAgICAqCisgICAgICogQHBhcmFtCW1zZ3MJdGhlIG1lc3NhZ2VzCisgICAgICogQHBhcmFtCWNvbmQJdGhlIGNvbmRpdGlvbiB0byBjaGVjaworICAgICAqIEByZXR1cm4JCXRoZSBNZXNzYWdlU2V0IGFycmF5CisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNS40CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBNZXNzYWdlU2V0W10gdG9NZXNzYWdlU2V0U29ydGVkKE1lc3NhZ2VbXSBtc2dzLAorCQkJCQkJCSAgICBDb25kaXRpb24gY29uZCkgeworCS8qCisJICogWFhYIC0gVGhpcyBpcyBxdWljayBhbmQgZGlydHkuICBBIG1vcmUgZWZmaWNpZW50IHN0cmF0ZWd5IHdvdWxkIGJlCisJICogdG8gZ2VuZXJhdGUgYW4gYXJyYXkgb2YgbWVzc2FnZSBudW1iZXJzIGJ5IGFwcGx5aW5nIHRoZSBjb25kaXRpb24KKwkgKiAod2l0aCB6ZXJvIGluZGljYXRpbmcgdGhlIG1lc3NhZ2UgZG9lc24ndCBzYXRpc2Z5IHRoZSBjb25kaXRpb24pLAorCSAqIHNvcnQgaXQsIGFuZCB0aGVuIGNvbnZlcnQgaXQgdG8gYSBNZXNzYWdlU2V0IHNraXBwaW5nIGFsbCB0aGUgemVyb2VzLgorCSAqLworCW1zZ3MgPSBtc2dzLmNsb25lKCk7CisJQXJyYXlzLnNvcnQobXNncywKKwkgICAgbmV3IENvbXBhcmF0b3I8TWVzc2FnZT4oKSB7CisJCUBPdmVycmlkZQorCQlwdWJsaWMgaW50IGNvbXBhcmUoTWVzc2FnZSBtc2cxLCBNZXNzYWdlIG1zZzIpIHsKKwkJICAgIHJldHVybiBtc2cxLmdldE1lc3NhZ2VOdW1iZXIoKSAtIG1zZzIuZ2V0TWVzc2FnZU51bWJlcigpOworCQl9CisJICAgIH0pOworCXJldHVybiB0b01lc3NhZ2VTZXQobXNncywgY29uZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIFVJRFNldHMgZm9yIHRoZSBtZXNzYWdlcy4gIE5vdGUgdGhhdCB0aGUgVUlEcworICAgICAqIG11c3QgaGF2ZSBhbHJlYWR5IGJlZW4gZmV0Y2hlZCBmb3IgdGhlIG1lc3NhZ2VzLgorICAgICAqCisgICAgICogQHBhcmFtCW1zZ3MJdGhlIG1lc3NhZ2VzCisgICAgICogQHJldHVybgkJdGhlIFVJRFNldCBhcnJheQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgVUlEU2V0W10gdG9VSURTZXQoTWVzc2FnZVtdIG1zZ3MpIHsKKwlMaXN0PFVJRFNldD4gdiA9IG5ldyBBcnJheUxpc3Q8PigxKTsKKwlsb25nIGN1cnJlbnQsIG5leHQ7CisKKwlJTUFQTWVzc2FnZSBtc2c7CisJZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisJICAgIG1zZyA9IChJTUFQTWVzc2FnZSltc2dzW2ldOworCSAgICBpZiAobXNnLmlzRXhwdW5nZWQoKSkgLy8gZXhwdW5nZWQgbWVzc2FnZSwgc2tpcCBpdAorCQljb250aW51ZTsKKworCSAgICBjdXJyZW50ID0gbXNnLmdldFVJRCgpOworIAorCSAgICBVSURTZXQgc2V0ID0gbmV3IFVJRFNldCgpOworCSAgICBzZXQuc3RhcnQgPSBjdXJyZW50OworCisJICAgIC8vIExvb2sgZm9yIGNvbnRpZ3VvdXMgVUlEcworCSAgICBmb3IgKCsraTsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspIHsKKwkJLy8gZ2V0IG5leHQgbWVzc2FnZQorCQltc2cgPSAoSU1BUE1lc3NhZ2UpbXNnc1tpXTsKKworCQlpZiAobXNnLmlzRXhwdW5nZWQoKSkgLy8gZXhwdW5nZWQgbWVzc2FnZSwgc2tpcCBpdAorCQkgICAgY29udGludWU7CisJCW5leHQgPSBtc2cuZ2V0VUlEKCk7CisKKwkJaWYgKG5leHQgPT0gY3VycmVudCsxKQorCQkgICAgY3VycmVudCA9IG5leHQ7CisJCWVsc2UgeyAvLyBicmVhayBpbiBzZXF1ZW5jZQorCQkgICAgLy8gV2UgbmVlZCB0byByZWV4YW1pbmUgdGhpcyBtZXNzYWdlIGF0IHRoZSB0b3Agb2YKKwkJICAgIC8vIHRoZSBvdXRlciBsb29wLCBzbyBkZWNyZW1lbnQgJ2knIHRvIGNhbmNlbCB0aGUKKwkJICAgIC8vIG91dGVyIGxvb3AncyBhdXRvaW5jcmVtZW50IAorCQkgICAgaS0tOworCQkgICAgYnJlYWs7CisJCX0KKwkgICAgfQorCSAgICBzZXQuZW5kID0gY3VycmVudDsKKwkgICAgdi5hZGQoc2V0KTsKKwl9CisKKwlpZiAodi5pc0VtcHR5KCkpIC8vIE5vIHZhbGlkIG1lc3NhZ2VzCisJICAgIHJldHVybiBudWxsOworCWVsc2UgeworCSAgICByZXR1cm4gdi50b0FycmF5KG5ldyBVSURTZXRbdi5zaXplKCldKTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogTWFrZSB0aGUgUmVzeW5jRGF0YSBVSURTZXQgYXZhaWxhYmxlIHRvIElNQVBQcm90b2NvbCwKKyAgICAgKiB3aGljaCBpcyBpbiBhIGRpZmZlcmVudCBwYWNrYWdlLiAgTm90ZSB0aGF0IHRoaXMgY2xhc3MKKyAgICAgKiBpcyBub3QgaW5jbHVkZWQgaW4gdGhlIHB1YmxpYyBqYXZhZG9jcywgdGh1cyAiaGlkaW5nIgorICAgICAqIHRoaXMgbWV0aG9kLgorICAgICAqCisgICAgICogQHBhcmFtCXJkCXRoZSBSZXN5bmNEYXRhCisgICAgICogQHJldHVybgkJdGhlIFVJRFNldCBhcnJheQorICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjUuMQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgVUlEU2V0W10gZ2V0UmVzeW5jVUlEU2V0KFJlc3luY0RhdGEgcmQpIHsKKwlyZXR1cm4gcmQuZ2V0VUlEU2V0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBpbnRlcmZhY2UgZGVmaW5lcyB0aGUgdGVzdCB0byBiZSBleGVjdXRlZCBpbiAKKyAgICAgKiA8Y29kZT50b01lc3NhZ2VTZXQoKTwvY29kZT4uIAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50ZXJmYWNlIENvbmRpdGlvbiB7CisJcHVibGljIGJvb2xlYW4gdGVzdChJTUFQTWVzc2FnZSBtZXNzYWdlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvWW91bmdlclRlcm0uamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9Zb3VuZ2VyVGVybS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU4MjY0YWUKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvWW91bmdlclRlcm0uamF2YQpAQCAtMCwwICsxLDk2IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5pbWFwOworCitpbXBvcnQgamF2YS51dGlsLkRhdGU7CitpbXBvcnQgamF2YXgubWFpbC5NZXNzYWdlOworaW1wb3J0IGphdmF4Lm1haWwuc2VhcmNoLlNlYXJjaFRlcm07CisKKy8qKgorICogRmluZCBtZXNzYWdlcyB0aGF0IGFyZSB5b3VuZ2VyIHRoYW4gYSBnaXZlbiBpbnRlcnZhbCAoaW4gc2Vjb25kcykuCisgKiBSZWxpZXMgb24gdGhlIHNlcnZlciBpbXBsZW1lbnRpbmcgdGhlIFdJVEhJTiBzZWFyY2ggZXh0ZW5zaW9uCisgKiAoPEEgSFJFRj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjNTAzMi50eHQiPlJGQyA1MDMyPC9BPikuCisgKgorICogQHNpbmNlCUphdmFNYWlsIDEuNS4xCisgKiBAYXV0aG9yCUJpbGwgU2hhbm5vbgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgWW91bmdlclRlcm0gZXh0ZW5kcyBTZWFyY2hUZXJtIHsKKworICAgIHByaXZhdGUgaW50IGludGVydmFsOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMTU5MjcxNDIxMDY4ODE2MzQ5Nkw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbnRlcnZhbAludW1iZXIgb2Ygc2Vjb25kcyB5b3VuZ2VyCisgICAgICovCisgICAgcHVibGljIFlvdW5nZXJUZXJtKGludCBpbnRlcnZhbCkgeworCXRoaXMuaW50ZXJ2YWwgPSBpbnRlcnZhbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIGludGVydmFsLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgaW50ZXJ2YWwKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldEludGVydmFsKCkgeworCXJldHVybiBpbnRlcnZhbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgbWF0Y2ggbWV0aG9kLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZwl0aGUgZGF0ZSBjb21wYXJhdG9yIGlzIGFwcGxpZWQgdG8gdGhpcyBNZXNzYWdlJ3MKKyAgICAgKgkJCXJlY2VpdmVkIGRhdGUKKyAgICAgKiBAcmV0dXJuCQl0cnVlIGlmIHRoZSBjb21wYXJpc29uIHN1Y2NlZWRzLCBvdGhlcndpc2UgZmFsc2UKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBtYXRjaChNZXNzYWdlIG1zZykgeworCURhdGUgZDsKKworCXRyeSB7CisJICAgIGQgPSBtc2cuZ2V0UmVjZWl2ZWREYXRlKCk7CisJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKwkgICAgcmV0dXJuIGZhbHNlOworCX0KKworCWlmIChkID09IG51bGwpCisJICAgIHJldHVybiBmYWxzZTsKKworCXJldHVybiBkLmdldFRpbWUoKSA+PQorCQkgICAgU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSAoKGxvbmcpaW50ZXJ2YWwgKiAxMDAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFcXVhbGl0eSBjb21wYXJpc29uLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CisJaWYgKCEob2JqIGluc3RhbmNlb2YgWW91bmdlclRlcm0pKQorCSAgICByZXR1cm4gZmFsc2U7CisJcmV0dXJuIGludGVydmFsID09ICgoWW91bmdlclRlcm0pb2JqKS5pbnRlcnZhbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wdXRlIGEgaGFzaENvZGUgZm9yIHRoaXMgb2JqZWN0LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisJcmV0dXJuIGludGVydmFsOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9wYWNrYWdlLmh0bWwgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvcGFja2FnZS5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZhNWNjZGQKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvcGFja2FnZS5odG1sCkBAIC0wLDAgKzEsMTAwMCBAQAorPCFET0NUWVBFIGh0bWwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMDEgVHJhbnNpdGlvbmFsLy9FTiI+Cis8SFRNTD4KKzxIRUFEPgorPG1ldGEgaHR0cC1lcXVpdj0iQ29udGVudC1UeXBlIiBjb250ZW50PSJ0ZXh0L2h0bWw7IGNoYXJzZXQ9dXRmLTgiPgorPCEtLQorCisgICAgQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisKKyAgICBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAgICB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKworICAgIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAgICBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgICAgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgICAgdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisKKyAgICBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKworLS0+CisKKzxUSVRMRT5jb20uc3VuLm1haWwuaW1hcCBwYWNrYWdlPC9USVRMRT4KKzwvSEVBRD4KKzxCT0RZIEJHQ09MT1I9IndoaXRlIj4KKworPFA+CitBbiBJTUFQIHByb3RvY29sIHByb3ZpZGVyIGZvciB0aGUgSmF2YU1haWwgQVBJCit0aGF0IHByb3ZpZGVzIGFjY2VzcyB0byBhbiBJTUFQIG1lc3NhZ2Ugc3RvcmUuCitCb3RoIHRoZSBJTUFQNCBhbmQgSU1BUDRyZXYxIHByb3RvY29scyBhcmUgc3VwcG9ydGVkLgorUmVmZXIgdG8gPEEgSFJFRj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzUwMS50eHQiIFRBUkdFVD0iX3RvcCI+CitSRkMgMzUwMTwvQT4KK2ZvciBtb3JlIGluZm9ybWF0aW9uLgorVGhlIElNQVAgcHJvdG9jb2wgcHJvdmlkZXIgYWxzbyBzdXBwb3J0cyBtYW55IElNQVAgZXh0ZW5zaW9ucyAoZGVzY3JpYmVkIGJlbG93KS4KK05vdGUgdGhhdCB0aGUgc2VydmVyIG5lZWRzIHRvIHN1cHBvcnQgdGhlc2UgZXh0ZW5zaW9ucyAoYW5kIG5vdCBhbGwgc2VydmVycyBkbykKK2luIG9yZGVyIHRvIHVzZSB0aGUgc3VwcG9ydCBpbiB0aGUgSU1BUCBwcm92aWRlci4KK1lvdSBjYW4gcXVlcnkgdGhlIHNlcnZlciBmb3Igc3VwcG9ydCBvZiB0aGVzZSBleHRlbnNpb25zIHVzaW5nIHRoZQore0BsaW5rIGNvbS5zdW4ubWFpbC5pbWFwLklNQVBTdG9yZSNoYXNDYXBhYmlsaXR5IElNQVBTdG9yZSBoYXNDYXBhYmlsaXR5fQorbWV0aG9kIHVzaW5nIHRoZSBjYXBhYmlsaXR5IG5hbWUgZGVmaW5lZCBieSB0aGUgZXh0ZW5zaW9uCisoc2VlIHRoZSBhcHByb3ByaWF0ZSBSRkMpIGFmdGVyIGNvbm5lY3RpbmcgdG8gdGhlIHNlcnZlci4KKzwvUD4KKzxTVFJPTkc+VUlEUExVUyBTdXBwb3J0PC9TVFJPTkc+Cis8UD4KK1RoZSBJTUFQIFVJRFBMVVMgZXh0ZW5zaW9uCisoPEEgSFJFRj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjNDMxNS50eHQiIFRBUkdFVD0iX3RvcCI+UkZDIDQzMTU8L0E+KQoraXMgc3VwcG9ydGVkIHZpYSB0aGUgSU1BUEZvbGRlciBtZXRob2RzCit7QGxpbmsgY29tLnN1bi5tYWlsLmltYXAuSU1BUEZvbGRlciNhZGRNZXNzYWdlcyBhZGRNZXNzYWdlc30sCit7QGxpbmsgY29tLnN1bi5tYWlsLmltYXAuSU1BUEZvbGRlciNhcHBlbmRVSURNZXNzYWdlcyBhcHBlbmRVSURNZXNzYWdlc30sIGFuZAore0BsaW5rIGNvbS5zdW4ubWFpbC5pbWFwLklNQVBGb2xkZXIjY29weVVJRE1lc3NhZ2VzIGNvcHlVSURNZXNzYWdlc30uCis8L1A+Cis8U1RST05HPk1PVkUgU3VwcG9ydDwvU1RST05HPgorPFA+CitUaGUgSU1BUCBNT1ZFIGV4dGVuc2lvbgorKDxBIEhSRUY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzY4NTEudHh0IiBUQVJHRVQ9Il90b3AiPlJGQyA2ODUxPC9BPikKK2lzIHN1cHBvcnRlZCB2aWEgdGhlIElNQVBGb2xkZXIgbWV0aG9kcwore0BsaW5rIGNvbS5zdW4ubWFpbC5pbWFwLklNQVBGb2xkZXIjbW92ZU1lc3NhZ2VzIG1vdmVNZXNzYWdlc30gYW5kCit7QGxpbmsgY29tLnN1bi5tYWlsLmltYXAuSU1BUEZvbGRlciNtb3ZlVUlETWVzc2FnZXMgbW92ZVVJRE1lc3NhZ2VzfS4KKzwvUD4KKzxTVFJPTkc+U0FTTCBTdXBwb3J0PC9TVFJPTkc+Cis8UD4KK1RoZSBJTUFQIHByb3RvY29sIHByb3ZpZGVyIGNhbiB1c2UgU0FTTAorKDxBIEhSRUY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzQ0MjIudHh0IiBUQVJHRVQ9Il90b3AiPlJGQyA0NDIyPC9BPikKK2F1dGhlbnRpY2F0aW9uIG1lY2hhbmlzbXMgb24gc3lzdGVtcyB0aGF0IHN1cHBvcnQgdGhlCis8Q09ERT5qYXZheC5zZWN1cml0eS5zYXNsPC9DT0RFPiBBUElzLgorVGhlIFNBU0wtSVIKKyg8QSBIUkVGPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmM0OTU5LnR4dCIgVEFSR0VUPSJfdG9wIj5SRkMgNDk1OTwvQT4pCitjYXBhYmlsaXR5IGlzIGFsc28gc3VwcG9ydGVkLgorSW4gYWRkaXRpb24gdG8gdGhlIFNBU0wgbWVjaGFuaXNtcyB0aGF0IGFyZSBidWlsdCBpbnRvIAordGhlIFNBU0wgaW1wbGVtZW50YXRpb24sIHVzZXJzIGNhbiBhbHNvIHByb3ZpZGUgYWRkaXRpb25hbAorU0FTTCBtZWNoYW5pc21zIG9mIHRoZWlyIG93biBkZXNpZ24gdG8gc3VwcG9ydCBjdXN0b20gYXV0aGVudGljYXRpb24KK3NjaGVtZXMuICBTZWUgdGhlCis8QSBIUkVGPSJodHRwOi8vZG93bmxvYWQub3JhY2xlLmNvbS9qYXZhc2UvNi9kb2NzL3RlY2hub3Rlcy9ndWlkZXMvc2VjdXJpdHkvc2FzbC9zYXNsLXJlZmd1aWRlLmh0bWwiIFRBUkdFVD0iX3RvcCI+CitKYXZhIFNBU0wgQVBJIFByb2dyYW1taW5nIGFuZCBEZXBsb3ltZW50IEd1aWRlPC9BPiBmb3IgZGV0YWlscy4KK05vdGUgdGhhdCB0aGUgY3VycmVudCBpbXBsZW1lbnRhdGlvbiBkb2Vzbid0IHN1cHBvcnQgU0FTTCBtZWNoYW5pc21zCit0aGF0IHByb3ZpZGUgdGhlaXIgb3duIGludGVncml0eSBvciBjb25maWRlbnRpYWxpdHkgbGF5ZXIuCis8L1A+Cis8U1RST05HPk9BdXRoIDIuMCBTdXBwb3J0PC9TVFJPTkc+Cis8UD4KK1N1cHBvcnQgZm9yIE9BdXRoIDIuMCBhdXRoZW50aWNhdGlvbiB2aWEgdGhlCis8QSBIUkVGPSJodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9nbWFpbC94b2F1dGgyX3Byb3RvY29sIiBUQVJHRVQ9Il90b3AiPgorWE9BVVRIMiBhdXRoZW50aWNhdGlvbiBtZWNoYW5pc208L0E+IGlzIHByb3ZpZGVkIGVpdGhlciB0aHJvdWdoIHRoZSBTQVNMCitzdXBwb3J0IGRlc2NyaWJlZCBhYm92ZSBvciBhcyBhIGJ1aWx0LWluIGF1dGhlbnRpY2F0aW9uIG1lY2hhbmlzbSBpbiB0aGUKK0lNQVAgcHJvdmlkZXIuCitUaGUgT0F1dGggMi4wIEFjY2VzcyBUb2tlbiBzaG91bGQgYmUgcGFzc2VkIGFzIHRoZSBwYXNzd29yZCBmb3IgdGhpcyBtZWNoYW5pc20uCitTZWUgPEEgSFJFRj0iaHR0cHM6Ly9qYXZhLm5ldC9wcm9qZWN0cy9qYXZhbWFpbC9wYWdlcy9PQXV0aDIiIFRBUkdFVD0iX3RvcCI+CitPQXV0aDIgU3VwcG9ydDwvQT4gZm9yIGRldGFpbHMuCis8L1A+Cis8U1RST05HPkNvbm5lY3Rpb24gUG9vbDwvU1RST05HPgorPFA+CitBIGNvbm5lY3RlZCBJTUFQU3RvcmUgbWFpbnRhaW5zIGEgcG9vbCBvZiBJTUFQIHByb3RvY29sIG9iamVjdHMgZm9yCit1c2UgaW4gY29tbXVuaWNhdGluZyB3aXRoIHRoZSBJTUFQIHNlcnZlci4gVGhlIElNQVBTdG9yZSB3aWxsIGNyZWF0ZQordGhlIGluaXRpYWwgQVVUSEVOVElDQVRFRCBjb25uZWN0aW9uIGFuZCBzZWVkIHRoZSBwb29sIHdpdGggdGhpcworY29ubmVjdGlvbi4gQXMgZm9sZGVycyBhcmUgb3BlbmVkIGFuZCBuZXcgSU1BUCBwcm90b2NvbCBvYmplY3RzIGFyZQorbmVlZGVkLCB0aGUgSU1BUFN0b3JlIHdpbGwgcHJvdmlkZSB0aGVtIGZyb20gdGhlIGNvbm5lY3Rpb24gcG9vbCwKK29yIGNyZWF0ZSB0aGVtIGlmIG5vbmUgYXJlIGF2YWlsYWJsZS4gV2hlbiBhIGZvbGRlciBpcyBjbG9zZWQsCitpdHMgSU1BUCBwcm90b2NvbCBvYmplY3QgaXMgcmV0dXJuZWQgdG8gdGhlIGNvbm5lY3Rpb24gcG9vbCBpZiB0aGUKK3Bvb2wgaXMgbm90IG92ZXIgY2FwYWNpdHkuCis8L1A+Cis8UD4KK0EgbWVjaGFuaXNtIGlzIHByb3ZpZGVkIGZvciB0aW1pbmcgb3V0IGlkbGUgY29ubmVjdGlvbiBwb29sIElNQVAKK3Byb3RvY29sIG9iamVjdHMuIFRpbWVkIG91dCBjb25uZWN0aW9ucyBhcmUgY2xvc2VkIGFuZCByZW1vdmVkIChwcnVuZWQpCitmcm9tIHRoZSBjb25uZWN0aW9uIHBvb2wuCis8L1A+Cis8UD4KK1RoZSBjb25uZWN0ZWQgSU1BUFN0b3JlIG9iamVjdCBtYXkgb3IgbWF5IG5vdCBtYWludGFpbiBhIHNlcGFyYXRlIElNQVAKK3Byb3RvY29sIG9iamVjdCB0aGF0IHByb3ZpZGVzIHRoZSBzdG9yZSBhIGRlZGljYXRlZCBjb25uZWN0aW9uIHRvIHRoZQorSU1BUCBzZXJ2ZXIuIFRoaXMgaXMgcHJvdmlkZWQgbWFpbmx5IGZvciBjb21wYXRpYmlsaXR5IHdpdGggcHJldmlvdXMKK2ltcGxlbWVudGF0aW9ucyBvZiB0aGUgSU1BUCBwcm90b2NvbCBwcm92aWRlci4KKzwvUD4KKzxTVFJPTkc+UVVPVEEgU3VwcG9ydDwvU1RST05HPgorPFA+CitUaGUgSU1BUCBRVU9UQSBleHRlbnNpb24KKyg8QSBIUkVGPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMDg3LnR4dCIgVEFSR0VUPSJfdG9wIj5SRkMgMjA4NzwvQT4pCitpcyBzdXBwb3J0ZWQgdmlhIHRoZQore0BsaW5rIGphdmF4Lm1haWwuUXVvdGFBd2FyZVN0b3JlIFF1b3RhQXdhcmVTdG9yZX0gaW50ZXJmYWNlIGltcGxlbWVudGVkIGJ5Cit7QGxpbmsgY29tLnN1bi5tYWlsLmltYXAuSU1BUFN0b3JlIElNQVBTdG9yZX0sIGFuZCB0aGUKK3tAbGluayBjb20uc3VuLm1haWwuaW1hcC5JTUFQRm9sZGVyI2dldFF1b3RhIElNQVBGb2xkZXIgZ2V0UXVvdGF9IGFuZAore0BsaW5rIGNvbS5zdW4ubWFpbC5pbWFwLklNQVBGb2xkZXIjc2V0UXVvdGEgSU1BUEZvbGRlciBzZXRRdW90YX0gbWV0aG9kcy4KKzxTVFJPTkc+QUNMIFN1cHBvcnQ8L1NUUk9ORz4KKzxQPgorVGhlIElNQVAgQUNMIGV4dGVuc2lvbgorKDxBIEhSRUY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIwODYudHh0IiBUQVJHRVQ9Il90b3AiPlJGQyAyMDg2PC9BPikKK2lzIHN1cHBvcnRlZCB2aWEgdGhlCit7QGxpbmsgY29tLnN1bi5tYWlsLmltYXAuUmlnaHRzIFJpZ2h0c30gY2xhc3MgYW5kIHRoZSBJTUFQRm9sZGVyIG1ldGhvZHMKK3tAbGluayBjb20uc3VuLm1haWwuaW1hcC5JTUFQRm9sZGVyI2dldEFDTCBnZXRBQ0x9LAore0BsaW5rIGNvbS5zdW4ubWFpbC5pbWFwLklNQVBGb2xkZXIjYWRkQUNMIGFkZEFDTH0sCit7QGxpbmsgY29tLnN1bi5tYWlsLmltYXAuSU1BUEZvbGRlciNyZW1vdmVBQ0wgcmVtb3ZlQUNMfSwKK3tAbGluayBjb20uc3VuLm1haWwuaW1hcC5JTUFQRm9sZGVyI2FkZFJpZ2h0cyBhZGRSaWdodHN9LAore0BsaW5rIGNvbS5zdW4ubWFpbC5pbWFwLklNQVBGb2xkZXIjcmVtb3ZlUmlnaHRzIHJlbW92ZVJpZ2h0c30sCit7QGxpbmsgY29tLnN1bi5tYWlsLmltYXAuSU1BUEZvbGRlciNsaXN0UmlnaHRzIGxpc3RSaWdodHN9LCBhbmQKK3tAbGluayBjb20uc3VuLm1haWwuaW1hcC5JTUFQRm9sZGVyI215UmlnaHRzIG15UmlnaHRzfS4KKzwvUD4KKzxTVFJPTkc+U09SVCBTdXBwb3J0PC9TVFJPTkc+Cis8UD4KK1RoZSBJTUFQIFNPUlQgZXh0ZW5zaW9uCisoPEEgSFJFRj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjNTI1Ni50eHQiIFRBUkdFVD0iX3RvcCI+UkZDIDUyNTY8L0E+KQoraXMgc3VwcG9ydGVkIHZpYSB0aGUKK3tAbGluayBjb20uc3VuLm1haWwuaW1hcC5Tb3J0VGVybSBTb3J0VGVybX0gY2xhc3MgYW5kIHRoZSBJTUFQRm9sZGVyCit7QGxpbmsgY29tLnN1bi5tYWlsLmltYXAuSU1BUEZvbGRlciNnZXRTb3J0ZWRNZXNzYWdlcyBnZXRTb3J0ZWRNZXNzYWdlc30KK21ldGhvZHMuCis8L1A+Cis8U1RST05HPkNPTkRTVE9SRSBhbmQgUVJFU1lOQyBTdXBwb3J0PC9TVFJPTkc+Cis8UD4KK0Jhc2ljIHN1cHBvcnQgaXMgcHJvdmlkZWQgZm9yIHRoZSBJTUFQIENPTkRTVE9SRQorKDxBIEhSRUY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzQ1NTEudHh0IiBUQVJHRVQ9Il90b3AiPlJGQyA0NTUxPC9BPikKK2FuZCBRUkVTWU5DCisoPEEgSFJFRj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjNTE2Mi50eHQiIFRBUkdFVD0iX3RvcCI+UkZDIDUxNjI8L0E+KQorZXh0ZW5zaW9ucyBmb3IgdGhlIHB1cnBvc2Ugb2YgcmVzeW5jaHJvbml6aW5nIGEgZm9sZGVyIGFmdGVyIG9mZmxpbmUgb3BlcmF0aW9uLgorT2YgY291cnNlLCB0aGUgc2VydmVyIG11c3Qgc3VwcG9ydCB0aGVzZSBleHRlbnNpb25zLgorVXNlIG9mIHRoZXNlIGV4dGVuc2lvbnMgaXMgZW5hYmxlZCBieSB1c2luZyB0aGUgbmV3Cit7QGxpbmsgY29tLnN1bi5tYWlsLmltYXAuSU1BUEZvbGRlciNvcGVuKGludCxjb20uc3VuLm1haWwuaW1hcC5SZXN5bmNEYXRhKQorSU1BUEZvbGRlciBvcGVufSBtZXRob2QgYW5kIHN1cHBseWluZyBhbiBhcHByb3ByaWF0ZQore0BsaW5rIGNvbS5zdW4ubWFpbC5pbWFwLlJlc3luY0RhdGEgUmVzeW5jRGF0YX0gaW5zdGFuY2UuCitVc2luZwore0BsaW5rIGNvbS5zdW4ubWFpbC5pbWFwLlJlc3luY0RhdGEjQ09ORFNUT1JFIFJlc3luY0RhdGEuQ09ORFNUT1JFfQorZW5hYmxlcyB0aGUgQ09ORFNUT1JFIGV4dGVuc2lvbiwgd2hpY2ggYWxsb3dzIHlvdSB0byBkaXNjb3ZlciB0aGUKK21vZGlmaWNhdGlvbiBzZXF1ZW5jZSBudW1iZXIgKG1vZHNlcSkgb2YgbWVzc2FnZXMgdXNpbmcgdGhlCit7QGxpbmsgY29tLnN1bi5tYWlsLmltYXAuSU1BUE1lc3NhZ2UjZ2V0TW9kU2VxIElNQVBNZXNzYWdlIGdldE1vZFNlcX0KK21ldGhvZCBhbmQgdGhlCit7QGxpbmsgY29tLnN1bi5tYWlsLmltYXAuSU1BUEZvbGRlciNnZXRIaWdoZXN0TW9kU2VxCitJTUFQRm9sZGVyIGdldEhpZ2hlc3RNb2RTZXF9IG1ldGhvZC4KK1VzaW5nIGEKK3tAbGluayBjb20uc3VuLm1haWwuaW1hcC5SZXN5bmNEYXRhIFJlc3luY0RhdGF9IGluc3RhbmNlIHdpdGggYXBwcm9wcmlhdGUKK3ZhbHVlcyBhbHNvIGFsbG93cyB0aGUgc2VydmVyIHRvIHJlcG9ydCBhbnkgY2hhbmdlcyBpbiBtZXNzYWdlcyBzaW5jZSB0aGUgbGFzdAorcmVzeW5jaHJvbml6YXRpb24uCitUaGUgY2hhbmdlcyBhcmUgcmVwb3J0ZWQgYXMgYSBsaXN0IG9mCit7QGxpbmsgamF2YXgubWFpbC5ldmVudC5NYWlsRXZlbnQgTWFpbEV2ZW50fSBpbnN0YW5jZXMuCitUaGUgc3BlY2lhbAore0BsaW5rIGNvbS5zdW4ubWFpbC5pbWFwLk1lc3NhZ2VWYW5pc2hlZEV2ZW50IE1lc3NhZ2VWYW5pc2hlZEV2ZW50fSByZXBvcnRzIG9uCitVSURzIG9mIG1lc3NhZ2VzIHRoYXQgaGF2ZSBiZWVuIHJlbW92ZWQgc2luY2UgdGhlIGxhc3QgcmVzeW5jaHJvbml6YXRpb24uCitBCit7QGxpbmsgamF2YXgubWFpbC5ldmVudC5NZXNzYWdlQ2hhbmdlZEV2ZW50IE1lc3NhZ2VDaGFuZ2VkRXZlbnR9IHJlcG9ydHMgb24KK2NoYW5nZXMgdG8gZmxhZ3Mgb2YgbWVzc2FnZXMuCitGb3IgZXhhbXBsZToKKzwvUD4KKzxQUkU+CisJRm9sZGVyIGZvbGRlciA9IHN0b3JlLmdldEZvbGRlcigid2hhdGV2ZXIiKTsKKwlJTUFQRm9sZGVyIGlmb2xkZXIgPSAoSU1BUEZvbGRlcilmb2xkZXI7CisJTGlzdCZsdDtNYWlsRXZlbnQmZ3Q7IGV2ZW50cyA9IGlmb2xkZXIub3BlbihGb2xkZXIuUkVBRF9XUklURSwKKwkJICAgIG5ldyBSZXN5bmNEYXRhKHByZXZVaWRWYWxpZGl0eSwgcHJldk1vZFNlcSkpOworCWZvciAoTWFpbEV2ZW50IGV2IDogZXZlbnRzKSB7CisJICAgIGlmIChldiBpbnN0YW5jZU9mIE1lc3NhZ2VDaGFuZ2VkRXZlbnQpIHsKKwkJLy8gcHJvY2VzcyBmbGFnIGNoYW5nZXMKKwkgICAgfSBlbHNlIGlmIChldiBpbnN0YW5jZW9mIE1lc3NhZ2VWYW5pc2hlZEV2ZW50KSB7CisJCS8vIHByb2Nlc3MgbWVzc2FnZXMgdGhhdCB3ZXJlIHJlbW92ZWQKKwkgICAgfQorCX0KKzwvUFJFPgorPFA+CitTZWUgdGhlIHJlZmVyZW5jZWQgUkZDcyBmb3IgbW9yZSBkZXRhaWxzIG9uIHRoZXNlIElNQVAgZXh0ZW5zaW9ucy4KKzwvUD4KKzxTVFJPTkc+V0lUSElOIFNlYXJjaCBTdXBwb3J0PC9TVFJPTkc+Cis8UD4KK1RoZSBJTUFQIFdJVEhJTiBzZWFyY2ggZXh0ZW5zaW9uCisoPEEgSFJFRj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjNTAzMi50eHQiIFRBUkdFVD0iX3RvcCI+UkZDIDUwMzI8L0E+KQoraXMgc3VwcG9ydGVkIHZpYSB0aGUKK3tAbGluayBjb20uc3VuLm1haWwuaW1hcC5Zb3VuZ2VyVGVybSBZb3VuZ2VyVGVybX0gYW5kCit7QGxpbmsgY29tLnN1bi5tYWlsLmltYXAuT2xkZXJUZXJtIE9sZGVyVGVybX0gCit7QGxpbmsgamF2YXgubWFpbC5zZWFyY2guU2VhcmNoVGVybSBTZWFyY2hUZXJtc30sIHdoaWNoIGNhbiBiZSB1c2VkIGFzIGZvbGxvd3M6Cis8L1A+Cis8UFJFPgorCS8vIHNlYXJjaCBmb3IgbWVzc2FnZXMgZGVsaXZlcmVkIGluIHRoZSBsYXN0IGRheQorCU1lc3NhZ2VbXSBtc2dzID0gZm9sZGVyLnNlYXJjaChuZXcgWW91bmdlclRlcm0oMjQgKiA2MCAqIDYwKSk7Cis8L1BSRT4KKzxTVFJPTkc+TE9HSU4tUkVGRVJSQUwgU3VwcG9ydDwvU1RST05HPgorPFA+CitUaGUgSU1BUCBMT0dJTi1SRUZFUlJBTCBleHRlbnNpb24KKyg8QSBIUkVGPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMjIxLnR4dCIgVEFSR0VUPSJfdG9wIj5SRkMgMjIyMTwvQT4pCitpcyBzdXBwb3J0ZWQuCitJZiBhIGxvZ2luIHJlZmVycmFsIGlzIHJlY2VpdmVkIHdoZW4gY29ubmVjdGluZyBvciB3aGVuIGF1dGhlbnRpY2F0aW9uIGZhaWxzLCBhCit7QGxpbmsgY29tLnN1bi5tYWlsLmltYXAuUmVmZXJyYWxFeGNlcHRpb24gUmVmZXJyYWxFeGNlcHRpb259IGlzIHRocm93bi4KK0EgcmVmZXJyYWwgY2FuIGFsc28gb2NjdXIgd2hlbiBsb2dpbiBzdWNjZWVkcy4gIEJ5IGRlZmF1bHQsIG5vIGV4Y2VwdGlvbiBpcwordGhyb3duIGluIHRoaXMgY2FzZS4gIFRvIGZvcmNlIGFuIGV4Y2VwdGlvbiB0byBiZSB0aHJvd24gYW5kIHRoZSBhdXRoZW50aWNhdGlvbgordG8gZmFpbCwgc2V0IHRoZSA8Y29kZT5tYWlsLmltYXAucmVmZXJyYWxleGNlcHRpb248L2NvZGU+IHByb3BlcnR5IHRvICJ0cnVlIi4KKzwvUD4KKzxTVFJPTkc+Q09NUFJFU1MgU3VwcG9ydDwvU1RST05HPgorPFA+CitUaGUgSU1BUCBDT01QUkVTUyBleHRlbnNpb24KKyg8QSBIUkVGPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmM0OTc4LnR4dCIgVEFSR0VUPSJfdG9wIj5SRkMgNDk3ODwvQT4pCitpcyBzdXBwb3J0ZWQuCitJZiB0aGUgc2VydmVyIHN1cHBvcnRzIHRoZSBleHRlbnNpb24gYW5kIHRoZQorPGNvZGU+bWFpbC5pbWFwLmNvbXByZXNzLmVuYWJsZTwvY29kZT4gcHJvcGVydHkgaXMgc2V0IHRvICJ0cnVlIiwKK2NvbXByZXNzaW9uIHdpbGwgYmUgZW5hYmxlZC4KKzwvUD4KKzxTVFJPTkc+VVRGLTggU3VwcG9ydDwvU1RST05HPgorPFA+CitUaGUgSU1BUCBVVEY4IGV4dGVuc2lvbgorKDxBIEhSRUY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzY4NTUudHh0IiBUQVJHRVQ9Il90b3AiPlJGQyA2ODU1PC9BPikKK2lzIHN1cHBvcnRlZC4KK0lmIHRoZSBzZXJ2ZXIgc3VwcG9ydHMgdGhlIGV4dGVuc2lvbiwgdGhlIGNsaWVudCB3aWxsIGVuYWJsZSB1c2Ugb2YgVVRGLTgsCithbGxvd2luZyB1c2Ugb2YgVVRGLTggaW4gSU1BUCBwcm90b2NvbCBzdHJpbmdzIHN1Y2ggYXMgZm9sZGVyIG5hbWVzLgorPC9QPgorPEEgTkFNRT0icHJvcGVydGllcyI+PFNUUk9ORz5Qcm9wZXJ0aWVzPC9TVFJPTkc+PC9BPgorPFA+CitUaGUgSU1BUCBwcm90b2NvbCBwcm92aWRlciBzdXBwb3J0cyB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXMsCit3aGljaCBtYXkgYmUgc2V0IGluIHRoZSBKYXZhTWFpbCA8Y29kZT5TZXNzaW9uPC9jb2RlPiBvYmplY3QuCitUaGUgcHJvcGVydGllcyBhcmUgYWx3YXlzIHNldCBhcyBzdHJpbmdzOyB0aGUgVHlwZSBjb2x1bW4gZGVzY3JpYmVzCitob3cgdGhlIHN0cmluZyBpcyBpbnRlcnByZXRlZC4gIEZvciBleGFtcGxlLCB1c2UKKzwvUD4KKzxQUkU+CisJcHJvcHMucHV0KCJtYWlsLmltYXAucG9ydCIsICI4ODgiKTsKKzwvUFJFPgorPFA+Cit0byBzZXQgdGhlIDxDT0RFPm1haWwuaW1hcC5wb3J0PC9DT0RFPiBwcm9wZXJ0eSwgd2hpY2ggaXMgb2YgdHlwZSBpbnQuCis8L1A+Cis8UD4KK05vdGUgdGhhdCBpZiB5b3UncmUgdXNpbmcgdGhlICJpbWFwcyIgcHJvdG9jb2wgdG8gYWNjZXNzIElNQVAgb3ZlciBTU0wsCithbGwgdGhlIHByb3BlcnRpZXMgd291bGQgYmUgbmFtZWQgIm1haWwuaW1hcHMuKiIuCis8L1A+Cis8VEFCTEUgQk9SREVSIFNVTU1BUlk9IklNQVAgcHJvcGVydGllcyI+Cis8VFI+Cis8VEg+TmFtZTwvVEg+Cis8VEg+VHlwZTwvVEg+Cis8VEg+RGVzY3JpcHRpb248L1RIPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuaW1hcC51c2VyIj5tYWlsLmltYXAudXNlcjwvQT48L1REPgorPFREPlN0cmluZzwvVEQ+Cis8VEQ+RGVmYXVsdCB1c2VyIG5hbWUgZm9yIElNQVAuPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLmltYXAuaG9zdCI+bWFpbC5pbWFwLmhvc3Q8L0E+PC9URD4KKzxURD5TdHJpbmc8L1REPgorPFREPlRoZSBJTUFQIHNlcnZlciB0byBjb25uZWN0IHRvLjwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5pbWFwLnBvcnQiPm1haWwuaW1hcC5wb3J0PC9BPjwvVEQ+Cis8VEQ+aW50PC9URD4KKzxURD5UaGUgSU1BUCBzZXJ2ZXIgcG9ydCB0byBjb25uZWN0IHRvLCBpZiB0aGUgY29ubmVjdCgpIG1ldGhvZCBkb2Vzbid0CitleHBsaWNpdGx5IHNwZWNpZnkgb25lLiBEZWZhdWx0cyB0byAxNDMuPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLmltYXAucGFydGlhbGZldGNoIj5tYWlsLmltYXAucGFydGlhbGZldGNoPC9BPjwvVEQ+Cis8VEQ+Ym9vbGVhbjwvVEQ+Cis8VEQ+Q29udHJvbHMgd2hldGhlciB0aGUgSU1BUCBwYXJ0aWFsLWZldGNoIGNhcGFiaWxpdHkgc2hvdWxkIGJlIHVzZWQuCitEZWZhdWx0cyB0byB0cnVlLjwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5pbWFwLmZldGNoc2l6ZSI+bWFpbC5pbWFwLmZldGNoc2l6ZTwvQT48L1REPgorPFREPmludDwvVEQ+Cis8VEQ+UGFydGlhbCBmZXRjaCBzaXplIGluIGJ5dGVzLiBEZWZhdWx0cyB0byAxNksuPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLmltYXAucGVlayI+bWFpbC5pbWFwLnBlZWs8L0E+PC9URD4KKzxURD5ib29sZWFuPC9URD4KKzxURD4KK0lmIHNldCB0byB0cnVlLCB1c2UgdGhlIElNQVAgUEVFSyBvcHRpb24gd2hlbiBmZXRjaGluZyBib2R5IHBhcnRzLAordG8gYXZvaWQgc2V0dGluZyB0aGUgU0VFTiBmbGFnIG9uIG1lc3NhZ2VzLgorRGVmYXVsdHMgdG8gZmFsc2UuCitDYW4gYmUgb3ZlcnJpZGRlbiBvbiBhIHBlci1tZXNzYWdlIGJhc2lzIGJ5IHRoZQore0BsaW5rIGNvbS5zdW4ubWFpbC5pbWFwLklNQVBNZXNzYWdlI3NldFBlZWsgc2V0UGVla30KK21ldGhvZCBvbiBJTUFQTWVzc2FnZS4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5pbWFwLmlnbm9yZWJvZHlzdHJ1Y3R1cmVzaXplIj5tYWlsLmltYXAuaWdub3JlYm9keXN0cnVjdHVyZXNpemU8L0E+PC9URD4KKzxURD5ib29sZWFuPC9URD4KKzxURD5UaGUgSU1BUCBCT0RZU1RSVUNUVVJFIHJlc3BvbnNlIGluY2x1ZGVzIHRoZSBleGFjdCBzaXplIG9mIGVhY2ggYm9keSBwYXJ0LgorTm9ybWFsbHksIHRoaXMgc2l6ZSBpcyB1c2VkIHRvIGRldGVybWluZSBob3cgbXVjaCBkYXRhIHRvIGZldGNoIGZvciBlYWNoCitib2R5IHBhcnQuCitTb21lIHNlcnZlcnMgcmVwb3J0IHRoaXMgc2l6ZSBpbmNvcnJlY3RseSBpbiBzb21lIGNhc2VzOyB0aGlzIHByb3BlcnR5IGNhbgorYmUgc2V0IHRvIHdvcmsgYXJvdW5kIHN1Y2ggc2VydmVyIGJ1Z3MuCitJZiB0aGlzIHByb3BlcnR5IGlzIHNldCB0byB0cnVlLCB0aGlzIHNpemUgaXMgaWdub3JlZCBhbmQgZGF0YSBpcyBmZXRjaGVkCit1bnRpbCB0aGUgc2VydmVyIHJlcG9ydHMgdGhlIGVuZCBvZiBkYXRhLgorVGhpcyB3aWxsIHJlc3VsdCBpbiBhbiBleHRyYSBmZXRjaCBpZiB0aGUgZGF0YSBzaXplIGlzIGEgbXVsdGlwbGUgb2YgdGhlCitibG9jayBzaXplLgorRGVmYXVsdHMgdG8gZmFsc2UuPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLmltYXAuY29ubmVjdGlvbnRpbWVvdXQiPm1haWwuaW1hcC5jb25uZWN0aW9udGltZW91dDwvQT48L1REPgorPFREPmludDwvVEQ+Cis8VEQ+U29ja2V0IGNvbm5lY3Rpb24gdGltZW91dCB2YWx1ZSBpbiBtaWxsaXNlY29uZHMuCitUaGlzIHRpbWVvdXQgaXMgaW1wbGVtZW50ZWQgYnkgamF2YS5uZXQuU29ja2V0LgorRGVmYXVsdCBpcyBpbmZpbml0ZSB0aW1lb3V0LjwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5pbWFwLnRpbWVvdXQiPm1haWwuaW1hcC50aW1lb3V0PC9BPjwvVEQ+Cis8VEQ+aW50PC9URD4KKzxURD5Tb2NrZXQgcmVhZCB0aW1lb3V0IHZhbHVlIGluIG1pbGxpc2Vjb25kcy4KK1RoaXMgdGltZW91dCBpcyBpbXBsZW1lbnRlZCBieSBqYXZhLm5ldC5Tb2NrZXQuCitEZWZhdWx0IGlzIGluZmluaXRlIHRpbWVvdXQuPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLmltYXAud3JpdGV0aW1lb3V0Ij5tYWlsLmltYXAud3JpdGV0aW1lb3V0PC9BPjwvVEQ+Cis8VEQ+aW50PC9URD4KKzxURD5Tb2NrZXQgd3JpdGUgdGltZW91dCB2YWx1ZSBpbiBtaWxsaXNlY29uZHMuCitUaGlzIHRpbWVvdXQgaXMgaW1wbGVtZW50ZWQgYnkgdXNpbmcgYQoramF2YS51dGlsLmNvbmN1cnJlbnQuU2NoZWR1bGVkRXhlY3V0b3JTZXJ2aWNlIHBlciBjb25uZWN0aW9uCit0aGF0IHNjaGVkdWxlcyBhIHRocmVhZCB0byBjbG9zZSB0aGUgc29ja2V0IGlmIHRoZSB0aW1lb3V0IGV4cGlyZXMuCitUaHVzLCB0aGUgb3ZlcmhlYWQgb2YgdXNpbmcgdGhpcyB0aW1lb3V0IGlzIG9uZSB0aHJlYWQgcGVyIGNvbm5lY3Rpb24uCitEZWZhdWx0IGlzIGluZmluaXRlIHRpbWVvdXQuPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLmltYXAuc3RhdHVzY2FjaGV0aW1lb3V0Ij5tYWlsLmltYXAuc3RhdHVzY2FjaGV0aW1lb3V0PC9BPjwvVEQ+Cis8VEQ+aW50PC9URD4KKzxURD5UaW1lb3V0IHZhbHVlIGluIG1pbGxpc2Vjb25kcyBmb3IgY2FjaGUgb2YgU1RBVFVTIGNvbW1hbmQgcmVzcG9uc2UuCitEZWZhdWx0IGlzIDEwMDAgKDEgc2Vjb25kKS4gIFplcm8gZGlzYWJsZXMgY2FjaGUuPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLmltYXAuYXBwZW5kYnVmZmVyc2l6ZSI+bWFpbC5pbWFwLmFwcGVuZGJ1ZmZlcnNpemU8L0E+PC9URD4KKzxURD5pbnQ8L1REPgorPFREPgorTWF4aW11bSBzaXplIG9mIGEgbWVzc2FnZSB0byBidWZmZXIgaW4gbWVtb3J5IHdoZW4gYXBwZW5kaW5nIHRvIGFuIElNQVAKK2ZvbGRlci4gIElmIG5vdCBzZXQsIG9yIHNldCB0byAtMSwgdGhlcmUgaXMgbm8gbWF4aW11bSBhbmQgYWxsIG1lc3NhZ2VzCithcmUgYnVmZmVyZWQuICBJZiBzZXQgdG8gMCwgbm8gbWVzc2FnZXMgYXJlIGJ1ZmZlcmVkLiAgSWYgc2V0IHRvIChlLmcuKQorODE5MiwgbWVzc2FnZXMgb2YgOEsgYnl0ZXMgb3IgbGVzcyBhcmUgYnVmZmVyZWQsIGxhcmdlciBtZXNzYWdlcyBhcmUKK25vdCBidWZmZXJlZC4gIEJ1ZmZlcmluZyBzYXZlcyBjcHUgdGltZSBhdCB0aGUgZXhwZW5zZSBvZiBzaG9ydCB0ZXJtCittZW1vcnkgdXNhZ2UuICBJZiB5b3UgY29tbW9ubHkgYXBwZW5kIHZlcnkgbGFyZ2UgbWVzc2FnZXMgdG8gSU1BUAorbWFpbGJveGVzIHlvdSBtaWdodCB3YW50IHRvIHNldCB0aGlzIHRvIGEgbW9kZXJhdGUgdmFsdWUgKDFNIG9yIGxlc3MpLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLmltYXAuY29ubmVjdGlvbnBvb2xzaXplIj5tYWlsLmltYXAuY29ubmVjdGlvbnBvb2xzaXplPC9BPjwvVEQ+Cis8VEQ+aW50PC9URD4KKzxURD5NYXhpbXVtIG51bWJlciBvZiBhdmFpbGFibGUgY29ubmVjdGlvbnMgaW4gdGhlIGNvbm5lY3Rpb24gcG9vbC4KK0RlZmF1bHQgaXMgMS48L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuaW1hcC5jb25uZWN0aW9ucG9vbHRpbWVvdXQiPm1haWwuaW1hcC5jb25uZWN0aW9ucG9vbHRpbWVvdXQ8L0E+PC9URD4KKzxURD5pbnQ8L1REPgorPFREPlRpbWVvdXQgdmFsdWUgaW4gbWlsbGlzZWNvbmRzIGZvciBjb25uZWN0aW9uIHBvb2wgY29ubmVjdGlvbnMuICBEZWZhdWx0CitpcyA0NTAwMCAoNDUgc2Vjb25kcykuPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLmltYXAuc2VwYXJhdGVzdG9yZWNvbm5lY3Rpb24iPm1haWwuaW1hcC5zZXBhcmF0ZXN0b3JlY29ubmVjdGlvbjwvQT48L1REPgorPFREPmJvb2xlYW48L1REPgorPFREPkZsYWcgdG8gaW5kaWNhdGUgd2hldGhlciB0byB1c2UgYSBkZWRpY2F0ZWQgc3RvcmUgY29ubmVjdGlvbiBmb3Igc3RvcmUKK2NvbW1hbmRzLiAgRGVmYXVsdCBpcyBmYWxzZS48L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuaW1hcC5hbGxvd3JlYWRvbmx5c2VsZWN0Ij5tYWlsLmltYXAuYWxsb3dyZWFkb25seXNlbGVjdDwvQT48L1REPgorPFREPmJvb2xlYW48L1REPgorPFREPklmIGZhbHNlLCBhdHRlbXB0cyB0byBvcGVuIGEgZm9sZGVyIHJlYWQvd3JpdGUgd2lsbCBmYWlsCitpZiB0aGUgU0VMRUNUIGNvbW1hbmQgc3VjY2VlZHMgYnV0IGluZGljYXRlcyB0aGF0IHRoZSBmb2xkZXIgaXMgUkVBRC1PTkxZLgorVGhpcyBzb21ldGltZXMgaW5kaWNhdGVzIHRoYXQgdGhlIGZvbGRlciBjb250ZW50cyBjYW4ndGJlIGNoYW5nZWQsIGJ1dAordGhlIGZsYWdzIGFyZSBwZXItdXNlciBhbmQgY2FuIGJlIGNoYW5nZWQsIHN1Y2ggYXMgbWlnaHQgYmUgdGhlIGNhc2UgZm9yCitwdWJsaWMgc2hhcmVkIGZvbGRlcnMuICBJZiB0cnVlLCBzdWNoIG9wZW4gYXR0ZW1wdHMgd2lsbCBzdWNjZWVkLCBhbGxvd2luZwordGhlIGZsYWdzIHRvIGJlIGNoYW5nZWQuICBUaGUgPGNvZGU+Z2V0TW9kZTwvY29kZT4gbWV0aG9kIG9uIHRoZQorPGNvZGU+Rm9sZGVyPC9jb2RlPiBvYmplY3Qgd2lsbCByZXR1cm4gPGNvZGU+Rm9sZGVyLlJFQURfT05MWTwvY29kZT4KK2luIHRoaXMgY2FzZSBldmVuIHRob3VnaCB0aGUgPGNvZGU+b3BlbjwvY29kZT4gbWV0aG9kIHNwZWNpZmllZAorPGNvZGU+Rm9sZGVyLlJFQURfV1JJVEU8L2NvZGU+LiAgRGVmYXVsdCBpcyBmYWxzZS48L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuaW1hcC5hdXRoLm1lY2hhbmlzbXMiPm1haWwuaW1hcC5hdXRoLm1lY2hhbmlzbXM8L0E+PC9URD4KKzxURD5TdHJpbmc8L1REPgorPFREPgorSWYgc2V0LCBsaXN0cyB0aGUgYXV0aGVudGljYXRpb24gbWVjaGFuaXNtcyB0byBjb25zaWRlciwgYW5kIHRoZSBvcmRlcgoraW4gd2hpY2ggdG8gY29uc2lkZXIgdGhlbS4gIE9ubHkgbWVjaGFuaXNtcyBzdXBwb3J0ZWQgYnkgdGhlIHNlcnZlciBhbmQKK3N1cHBvcnRlZCBieSB0aGUgY3VycmVudCBpbXBsZW1lbnRhdGlvbiB3aWxsIGJlIHVzZWQuCitUaGUgZGVmYXVsdCBpcyA8Y29kZT4iUExBSU4gTE9HSU4gTlRMTSI8L2NvZGU+LCB3aGljaCBpbmNsdWRlcyBhbGwKK3RoZSBhdXRoZW50aWNhdGlvbiBtZWNoYW5pc21zIHN1cHBvcnRlZCBieSB0aGUgY3VycmVudCBpbXBsZW1lbnRhdGlvbgorZXhjZXB0IFhPQVVUSDIuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuaW1hcC5hdXRoLmxvZ2luLmRpc2FibGUiPm1haWwuaW1hcC5hdXRoLmxvZ2luLmRpc2FibGU8L0E+PC9URD4KKzxURD5ib29sZWFuPC9URD4KKzxURD5JZiB0cnVlLCBwcmV2ZW50cyB1c2Ugb2YgdGhlIG5vbi1zdGFuZGFyZCA8Y29kZT5BVVRIRU5USUNBVEUgTE9HSU48L2NvZGU+Citjb21tYW5kLCBpbnN0ZWFkIHVzaW5nIHRoZSBwbGFpbiA8Y29kZT5MT0dJTjwvY29kZT4gY29tbWFuZC4KK0RlZmF1bHQgaXMgZmFsc2UuPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLmltYXAuYXV0aC5wbGFpbi5kaXNhYmxlIj5tYWlsLmltYXAuYXV0aC5wbGFpbi5kaXNhYmxlPC9BPjwvVEQ+Cis8VEQ+Ym9vbGVhbjwvVEQ+Cis8VEQ+SWYgdHJ1ZSwgcHJldmVudHMgdXNlIG9mIHRoZSA8Y29kZT5BVVRIRU5USUNBVEUgUExBSU48L2NvZGU+IGNvbW1hbmQuCitEZWZhdWx0IGlzIGZhbHNlLjwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5pbWFwLmF1dGgubnRsbS5kaXNhYmxlIj5tYWlsLmltYXAuYXV0aC5udGxtLmRpc2FibGU8L0E+PC9URD4KKzxURD5ib29sZWFuPC9URD4KKzxURD5JZiB0cnVlLCBwcmV2ZW50cyB1c2Ugb2YgdGhlIDxjb2RlPkFVVEhFTlRJQ0FURSBOVExNPC9jb2RlPiBjb21tYW5kLgorRGVmYXVsdCBpcyBmYWxzZS48L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuaW1hcC5hdXRoLm50bG0uZG9tYWluIj5tYWlsLmltYXAuYXV0aC5udGxtLmRvbWFpbjwvQT48L1REPgorPFREPlN0cmluZzwvVEQ+Cis8VEQ+CitUaGUgTlRMTSBhdXRoZW50aWNhdGlvbiBkb21haW4uCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuaW1hcC5hdXRoLm50bG0uZmxhZ3MiPm1haWwuaW1hcC5hdXRoLm50bG0uZmxhZ3M8L0E+PC9URD4KKzxURD5pbnQ8L1REPgorPFREPgorTlRMTSBwcm90b2NvbC1zcGVjaWZpYyBmbGFncy4KK1NlZSA8QSBIUkVGPSJodHRwOi8vY3VybC5oYXh4LnNlL3JmYy9udGxtLmh0bWwjdGhlTnRsbUZsYWdzIiBUQVJHRVQ9Il90b3AiPgoraHR0cDovL2N1cmwuaGF4eC5zZS9yZmMvbnRsbS5odG1sI3RoZU50bG1GbGFnczwvQT4gZm9yIGRldGFpbHMuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuaW1hcC5hdXRoLnhvYXV0aDIuZGlzYWJsZSI+bWFpbC5pbWFwLmF1dGgueG9hdXRoMi5kaXNhYmxlPC9BPjwvVEQ+Cis8VEQ+Ym9vbGVhbjwvVEQ+Cis8VEQ+SWYgdHJ1ZSwgcHJldmVudHMgdXNlIG9mIHRoZSA8Y29kZT5BVVRIRU5USUNBVEUgWE9BVVRIMjwvY29kZT4gY29tbWFuZC4KK0JlY2F1c2UgdGhlIE9BdXRoIDIuMCBwcm90b2NvbCByZXF1aXJlcyBhIHNwZWNpYWwgYWNjZXNzIHRva2VuIGluc3RlYWQgb2YKK2EgcGFzc3dvcmQsIHRoaXMgbWVjaGFuaXNtIGlzIGRpc2FibGVkIGJ5IGRlZmF1bHQuICBFbmFibGUgaXQgYnkgZXhwbGljaXRseQorc2V0dGluZyB0aGlzIHByb3BlcnR5IHRvICJmYWxzZSIgb3IgYnkgc2V0dGluZyB0aGUgIm1haWwuaW1hcC5hdXRoLm1lY2hhbmlzbXMiCitwcm9wZXJ0eSB0byAiWE9BVVRIMiIuPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLmltYXAucHJveHlhdXRoLnVzZXIiPm1haWwuaW1hcC5wcm94eWF1dGgudXNlcjwvQT48L1REPgorPFREPlN0cmluZzwvVEQ+Cis8VEQ+SWYgdGhlIHNlcnZlciBzdXBwb3J0cyB0aGUgUFJPWFlBVVRIIGV4dGVuc2lvbiwgdGhpcyBwcm9wZXJ0eQorc3BlY2lmaWVzIHRoZSBuYW1lIG9mIHRoZSB1c2VyIHRvIGFjdCBhcy4gIEF1dGhlbnRpY2F0ZSB0byB0aGUKK3NlcnZlciB1c2luZyB0aGUgYWRtaW5pc3RyYXRvcidzIGNyZWRlbnRpYWxzLiAgQWZ0ZXIgYXV0aGVudGljYXRpb24sCit0aGUgSU1BUCBwcm92aWRlciB3aWxsIGlzc3VlIHRoZSA8Y29kZT5QUk9YWUFVVEg8L2NvZGU+IGNvbW1hbmQgd2l0aAordGhlIHVzZXIgbmFtZSBzcGVjaWZpZWQgaW4gdGhpcyBwcm9wZXJ0eS4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5pbWFwLmxvY2FsYWRkcmVzcyI+bWFpbC5pbWFwLmxvY2FsYWRkcmVzczwvQT48L1REPgorPFREPlN0cmluZzwvVEQ+Cis8VEQ+CitMb2NhbCBhZGRyZXNzIChob3N0IG5hbWUpIHRvIGJpbmQgdG8gd2hlbiBjcmVhdGluZyB0aGUgSU1BUCBzb2NrZXQuCitEZWZhdWx0cyB0byB0aGUgYWRkcmVzcyBwaWNrZWQgYnkgdGhlIFNvY2tldCBjbGFzcy4KK1Nob3VsZCBub3Qgbm9ybWFsbHkgbmVlZCB0byBiZSBzZXQsIGJ1dCB1c2VmdWwgd2l0aCBtdWx0aS1ob21lZCBob3N0cword2hlcmUgaXQncyBpbXBvcnRhbnQgdG8gcGljayBhIHBhcnRpY3VsYXIgbG9jYWwgYWRkcmVzcyB0byBiaW5kIHRvLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLmltYXAubG9jYWxwb3J0Ij5tYWlsLmltYXAubG9jYWxwb3J0PC9BPjwvVEQ+Cis8VEQ+aW50PC9URD4KKzxURD4KK0xvY2FsIHBvcnQgbnVtYmVyIHRvIGJpbmQgdG8gd2hlbiBjcmVhdGluZyB0aGUgSU1BUCBzb2NrZXQuCitEZWZhdWx0cyB0byB0aGUgcG9ydCBudW1iZXIgcGlja2VkIGJ5IHRoZSBTb2NrZXQgY2xhc3MuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuaW1hcC5zYXNsLmVuYWJsZSI+bWFpbC5pbWFwLnNhc2wuZW5hYmxlPC9BPjwvVEQ+Cis8VEQ+Ym9vbGVhbjwvVEQ+Cis8VEQ+CitJZiBzZXQgdG8gdHJ1ZSwgYXR0ZW1wdCB0byB1c2UgdGhlIGphdmF4LnNlY3VyaXR5LnNhc2wgcGFja2FnZSB0bworY2hvb3NlIGFuIGF1dGhlbnRpY2F0aW9uIG1lY2hhbmlzbSBmb3IgbG9naW4uCitEZWZhdWx0cyB0byBmYWxzZS4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5pbWFwLnNhc2wubWVjaGFuaXNtcyI+bWFpbC5pbWFwLnNhc2wubWVjaGFuaXNtczwvQT48L1REPgorPFREPlN0cmluZzwvVEQ+Cis8VEQ+CitBIHNwYWNlIG9yIGNvbW1hIHNlcGFyYXRlZCBsaXN0IG9mIFNBU0wgbWVjaGFuaXNtIG5hbWVzIHRvIHRyeQordG8gdXNlLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLmltYXAuc2FzbC5hdXRob3JpemF0aW9uaWQiPm1haWwuaW1hcC5zYXNsLmF1dGhvcml6YXRpb25pZDwvQT48L1REPgorPFREPlN0cmluZzwvVEQ+Cis8VEQ+CitUaGUgYXV0aG9yaXphdGlvbiBJRCB0byB1c2UgaW4gdGhlIFNBU0wgYXV0aGVudGljYXRpb24uCitJZiBub3Qgc2V0LCB0aGUgYXV0aGVudGljYXRpb24gSUQgKHVzZXIgbmFtZSkgaXMgdXNlZC4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5pbWFwLnNhc2wucmVhbG0iPm1haWwuaW1hcC5zYXNsLnJlYWxtPC9BPjwvVEQ+Cis8VEQ+U3RyaW5nPC9URD4KKzxURD5UaGUgcmVhbG0gdG8gdXNlIHdpdGggU0FTTCBhdXRoZW50aWNhdGlvbiBtZWNoYW5pc21zIHRoYXQKK3JlcXVpcmUgYSByZWFsbSwgc3VjaCBhcyBESUdFU1QtTUQ1LjwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5pbWFwLnNhc2wudXNlY2Fub25pY2FsaG9zdG5hbWUiPm1haWwuaW1hcC5zYXNsLnVzZWNhbm9uaWNhbGhvc3RuYW1lPC9BPjwvVEQ+Cis8VEQ+Ym9vbGVhbjwvVEQ+Cis8VEQ+CitJZiBzZXQgdG8gdHJ1ZSwgdGhlIGNhbm9uaWNhbCBob3N0IG5hbWUgcmV0dXJuZWQgYnkKK3tAbGluayBqYXZhLm5ldC5JbmV0QWRkcmVzcyNnZXRDYW5vbmljYWxIb3N0TmFtZSBJbmV0QWRkcmVzcy5nZXRDYW5vbmljYWxIb3N0TmFtZX0KK2lzIHBhc3NlZCB0byB0aGUgU0FTTCBtZWNoYW5pc20sIGluc3RlYWQgb2YgdGhlIGhvc3QgbmFtZSB1c2VkIHRvIGNvbm5lY3QuCitEZWZhdWx0cyB0byBmYWxzZS4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5pbWFwLnNhc2wueGd3dHJ1c3RlZGFwcGhhY2suZW5hYmxlIj5tYWlsLmltYXAuc2FzbC4geGd3dHJ1c3RlZGFwcGhhY2suZW5hYmxlPC9BPjwvVEQ+Cis8VEQ+Ym9vbGVhbjwvVEQ+Cis8VEQ+CitJZiBzZXQgdG8gdHJ1ZSwgZW5hYmxlcyBhIHdvcmthcm91bmQgZm9yIGEgYnVnIGluIHRoZSBOb3ZlbGwgR3JvdXB3aXNlCitYR1dUUlVTVEVEQVBQIFNBU0wgbWVjaGFuaXNtLCB3aGVuIHRoYXQgbWVjaGFuaXNtIGlzIGJlaW5nIHVzZWQuCitEZWZhdWx0cyB0byB0cnVlLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLmltYXAuc29ja2V0RmFjdG9yeSI+bWFpbC5pbWFwLnNvY2tldEZhY3Rvcnk8L0E+PC9URD4KKzxURD5Tb2NrZXRGYWN0b3J5PC9URD4KKzxURD4KK0lmIHNldCB0byBhIGNsYXNzIHRoYXQgaW1wbGVtZW50cyB0aGUKKzxjb2RlPmphdmF4Lm5ldC5Tb2NrZXRGYWN0b3J5PC9jb2RlPiBpbnRlcmZhY2UsIHRoaXMgY2xhc3MKK3dpbGwgYmUgdXNlZCB0byBjcmVhdGUgSU1BUCBzb2NrZXRzLiAgTm90ZSB0aGF0IHRoaXMgaXMgYW4KK2luc3RhbmNlIG9mIGEgY2xhc3MsIG5vdCBhIG5hbWUsIGFuZCBtdXN0IGJlIHNldCB1c2luZyB0aGUKKzxjb2RlPnB1dDwvY29kZT4gbWV0aG9kLCBub3QgdGhlIDxjb2RlPnNldFByb3BlcnR5PC9jb2RlPiBtZXRob2QuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuaW1hcC5zb2NrZXRGYWN0b3J5LmNsYXNzIj5tYWlsLmltYXAuc29ja2V0RmFjdG9yeS5jbGFzczwvQT48L1REPgorPFREPlN0cmluZzwvVEQ+Cis8VEQ+CitJZiBzZXQsIHNwZWNpZmllcyB0aGUgbmFtZSBvZiBhIGNsYXNzIHRoYXQgaW1wbGVtZW50cyB0aGUKKzxjb2RlPmphdmF4Lm5ldC5Tb2NrZXRGYWN0b3J5PC9jb2RlPiBpbnRlcmZhY2UuICBUaGlzIGNsYXNzCit3aWxsIGJlIHVzZWQgdG8gY3JlYXRlIElNQVAgc29ja2V0cy4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5pbWFwLnNvY2tldEZhY3RvcnkuZmFsbGJhY2siPm1haWwuaW1hcC5zb2NrZXRGYWN0b3J5LmZhbGxiYWNrPC9BPjwvVEQ+Cis8VEQ+Ym9vbGVhbjwvVEQ+Cis8VEQ+CitJZiBzZXQgdG8gdHJ1ZSwgZmFpbHVyZSB0byBjcmVhdGUgYSBzb2NrZXQgdXNpbmcgdGhlIHNwZWNpZmllZAorc29ja2V0IGZhY3RvcnkgY2xhc3Mgd2lsbCBjYXVzZSB0aGUgc29ja2V0IHRvIGJlIGNyZWF0ZWQgdXNpbmcKK3RoZSA8Y29kZT5qYXZhLm5ldC5Tb2NrZXQ8L2NvZGU+IGNsYXNzLgorRGVmYXVsdHMgdG8gdHJ1ZS4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5pbWFwLnNvY2tldEZhY3RvcnkucG9ydCI+bWFpbC5pbWFwLnNvY2tldEZhY3RvcnkucG9ydDwvQT48L1REPgorPFREPmludDwvVEQ+Cis8VEQ+CitTcGVjaWZpZXMgdGhlIHBvcnQgdG8gY29ubmVjdCB0byB3aGVuIHVzaW5nIHRoZSBzcGVjaWZpZWQgc29ja2V0CitmYWN0b3J5LgorSWYgbm90IHNldCwgdGhlIGRlZmF1bHQgcG9ydCB3aWxsIGJlIHVzZWQuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuaW1hcC51c2Vzb2NrZXRjaGFubmVscyI+bWFpbC5pbWFwLnVzZXNvY2tldGNoYW5uZWxzPC9BPjwvVEQ+Cis8VEQ+Ym9vbGVhbjwvVEQ+Cis8VEQ+CitJZiBzZXQgdG8gdHJ1ZSwgdXNlIFNvY2tldENoYW5uZWxzIGluc3RlYWQgb2YgU29ja2V0cyBmb3IgY29ubmVjdGluZwordG8gdGhlIHNlcnZlci4gIFJlcXVpcmVkIGlmIHVzaW5nIHRoZSBJZGxlTWFuYWdlci4KK0lnbm9yZWQgaWYgYSBzb2NrZXQgZmFjdG9yeSBpcyBzZXQuCitEZWZhdWx0cyB0byBmYWxzZS4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5pbWFwLnNzbC5lbmFibGUiPm1haWwuaW1hcC5zc2wuZW5hYmxlPC9BPjwvVEQ+Cis8VEQ+Ym9vbGVhbjwvVEQ+Cis8VEQ+CitJZiBzZXQgdG8gdHJ1ZSwgdXNlIFNTTCB0byBjb25uZWN0IGFuZCB1c2UgdGhlIFNTTCBwb3J0IGJ5IGRlZmF1bHQuCitEZWZhdWx0cyB0byBmYWxzZSBmb3IgdGhlICJpbWFwIiBwcm90b2NvbCBhbmQgdHJ1ZSBmb3IgdGhlICJpbWFwcyIgcHJvdG9jb2wuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuaW1hcC5zc2wuY2hlY2tzZXJ2ZXJpZGVudGl0eSI+bWFpbC5pbWFwLnNzbC5jaGVja3NlcnZlcmlkZW50aXR5PC9BPjwvVEQ+Cis8VEQ+Ym9vbGVhbjwvVEQ+Cis8VEQ+CitJZiBzZXQgdG8gdHJ1ZSwgY2hlY2sgdGhlIHNlcnZlciBpZGVudGl0eSBhcyBzcGVjaWZpZWQgYnkKKzxBIEhSRUY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzI1OTUudHh0IiBUQVJHRVQ9Il90b3AiPlJGQyAyNTk1PC9BPi4KK1RoZXNlIGFkZGl0aW9uYWwgY2hlY2tzIGJhc2VkIG9uIHRoZSBjb250ZW50IG9mIHRoZSBzZXJ2ZXIncyBjZXJ0aWZpY2F0ZQorYXJlIGludGVuZGVkIHRvIHByZXZlbnQgbWFuLWluLXRoZS1taWRkbGUgYXR0YWNrcy4KK0RlZmF1bHRzIHRvIGZhbHNlLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLmltYXAuc3NsLnRydXN0Ij5tYWlsLmltYXAuc3NsLnRydXN0PC9BPjwvVEQ+Cis8VEQ+U3RyaW5nPC9URD4KKzxURD4KK0lmIHNldCwgYW5kIGEgc29ja2V0IGZhY3RvcnkgaGFzbid0IGJlZW4gc3BlY2lmaWVkLCBlbmFibGVzIHVzZSBvZiBhCit7QGxpbmsgY29tLnN1bi5tYWlsLnV0aWwuTWFpbFNTTFNvY2tldEZhY3RvcnkgTWFpbFNTTFNvY2tldEZhY3Rvcnl9LgorSWYgc2V0IHRvICIqIiwgYWxsIGhvc3RzIGFyZSB0cnVzdGVkLgorSWYgc2V0IHRvIGEgd2hpdGVzcGFjZSBzZXBhcmF0ZWQgbGlzdCBvZiBob3N0cywgdGhvc2UgaG9zdHMgYXJlIHRydXN0ZWQuCitPdGhlcndpc2UsIHRydXN0IGRlcGVuZHMgb24gdGhlIGNlcnRpZmljYXRlIHRoZSBzZXJ2ZXIgcHJlc2VudHMuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuaW1hcC5zc2wuc29ja2V0RmFjdG9yeSI+bWFpbC5pbWFwLnNzbC5zb2NrZXRGYWN0b3J5PC9BPjwvVEQ+Cis8VEQ+U1NMU29ja2V0RmFjdG9yeTwvVEQ+Cis8VEQ+CitJZiBzZXQgdG8gYSBjbGFzcyB0aGF0IGV4dGVuZHMgdGhlCis8Y29kZT5qYXZheC5uZXQuc3NsLlNTTFNvY2tldEZhY3Rvcnk8L2NvZGU+IGNsYXNzLCB0aGlzIGNsYXNzCit3aWxsIGJlIHVzZWQgdG8gY3JlYXRlIElNQVAgU1NMIHNvY2tldHMuICBOb3RlIHRoYXQgdGhpcyBpcyBhbgoraW5zdGFuY2Ugb2YgYSBjbGFzcywgbm90IGEgbmFtZSwgYW5kIG11c3QgYmUgc2V0IHVzaW5nIHRoZQorPGNvZGU+cHV0PC9jb2RlPiBtZXRob2QsIG5vdCB0aGUgPGNvZGU+c2V0UHJvcGVydHk8L2NvZGU+IG1ldGhvZC4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5pbWFwLnNzbC5zb2NrZXRGYWN0b3J5LmNsYXNzIj5tYWlsLmltYXAuc3NsLnNvY2tldEZhY3RvcnkuY2xhc3M8L0E+PC9URD4KKzxURD5TdHJpbmc8L1REPgorPFREPgorSWYgc2V0LCBzcGVjaWZpZXMgdGhlIG5hbWUgb2YgYSBjbGFzcyB0aGF0IGV4dGVuZHMgdGhlCis8Y29kZT5qYXZheC5uZXQuc3NsLlNTTFNvY2tldEZhY3Rvcnk8L2NvZGU+IGNsYXNzLiAgVGhpcyBjbGFzcword2lsbCBiZSB1c2VkIHRvIGNyZWF0ZSBJTUFQIFNTTCBzb2NrZXRzLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLmltYXAuc3NsLnNvY2tldEZhY3RvcnkucG9ydCI+bWFpbC5pbWFwLnNzbC5zb2NrZXRGYWN0b3J5LnBvcnQ8L0E+PC9URD4KKzxURD5pbnQ8L1REPgorPFREPgorU3BlY2lmaWVzIHRoZSBwb3J0IHRvIGNvbm5lY3QgdG8gd2hlbiB1c2luZyB0aGUgc3BlY2lmaWVkIHNvY2tldAorZmFjdG9yeS4KK0lmIG5vdCBzZXQsIHRoZSBkZWZhdWx0IHBvcnQgd2lsbCBiZSB1c2VkLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLmltYXAuc3NsLnByb3RvY29scyI+bWFpbC5pbWFwLnNzbC5wcm90b2NvbHM8L0E+PC9URD4KKzxURD5zdHJpbmc8L1REPgorPFREPgorU3BlY2lmaWVzIHRoZSBTU0wgcHJvdG9jb2xzIHRoYXQgd2lsbCBiZSBlbmFibGVkIGZvciBTU0wgY29ubmVjdGlvbnMuCitUaGUgcHJvcGVydHkgdmFsdWUgaXMgYSB3aGl0ZXNwYWNlIHNlcGFyYXRlZCBsaXN0IG9mIHRva2VucyBhY2NlcHRhYmxlCit0byB0aGUgPGNvZGU+amF2YXgubmV0LnNzbC5TU0xTb2NrZXQuc2V0RW5hYmxlZFByb3RvY29sczwvY29kZT4gbWV0aG9kLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLmltYXAuc3NsLmNpcGhlcnN1aXRlcyI+bWFpbC5pbWFwLnNzbC5jaXBoZXJzdWl0ZXM8L0E+PC9URD4KKzxURD5zdHJpbmc8L1REPgorPFREPgorU3BlY2lmaWVzIHRoZSBTU0wgY2lwaGVyIHN1aXRlcyB0aGF0IHdpbGwgYmUgZW5hYmxlZCBmb3IgU1NMIGNvbm5lY3Rpb25zLgorVGhlIHByb3BlcnR5IHZhbHVlIGlzIGEgd2hpdGVzcGFjZSBzZXBhcmF0ZWQgbGlzdCBvZiB0b2tlbnMgYWNjZXB0YWJsZQordG8gdGhlIDxjb2RlPmphdmF4Lm5ldC5zc2wuU1NMU29ja2V0LnNldEVuYWJsZWRDaXBoZXJTdWl0ZXM8L2NvZGU+IG1ldGhvZC4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5pbWFwLnN0YXJ0dGxzLmVuYWJsZSI+bWFpbC5pbWFwLnN0YXJ0dGxzLmVuYWJsZTwvQT48L1REPgorPFREPmJvb2xlYW48L1REPgorPFREPklmIHRydWUsIGVuYWJsZXMgdGhlIHVzZSBvZiB0aGUgPGNvZGU+U1RBUlRUTFM8L2NvZGU+IGNvbW1hbmQgKGlmCitzdXBwb3J0ZWQgYnkgdGhlIHNlcnZlcikgdG8gc3dpdGNoIHRoZSBjb25uZWN0aW9uIHRvIGEgVExTLXByb3RlY3RlZAorY29ubmVjdGlvbiBiZWZvcmUgaXNzdWluZyBhbnkgbG9naW4gY29tbWFuZHMuCitJZiB0aGUgc2VydmVyIGRvZXMgbm90IHN1cHBvcnQgU1RBUlRUTFMsIHRoZSBjb25uZWN0aW9uIGNvbnRpbnVlcyB3aXRob3V0Cit0aGUgdXNlIG9mIFRMUzsgc2VlIHRoZQorPEEgSFJFRj0iI21haWwuaW1hcC5zdGFydHRscy5yZXF1aXJlZCI+PGNvZGU+bWFpbC5pbWFwLnN0YXJ0dGxzLnJlcXVpcmVkPC9jb2RlPjwvQT4KK3Byb3BlcnR5IHRvIGZhaWwgaWYgU1RBUlRUTFMgaXNuJ3Qgc3VwcG9ydGVkLgorTm90ZSB0aGF0IGFuIGFwcHJvcHJpYXRlIHRydXN0IHN0b3JlIG11c3QgY29uZmlndXJlZCBzbyB0aGF0IHRoZSBjbGllbnQKK3dpbGwgdHJ1c3QgdGhlIHNlcnZlcidzIGNlcnRpZmljYXRlLgorRGVmYXVsdCBpcyBmYWxzZS48L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuaW1hcC5zdGFydHRscy5yZXF1aXJlZCI+bWFpbC5pbWFwLnN0YXJ0dGxzLnJlcXVpcmVkPC9BPjwvVEQ+Cis8VEQ+Ym9vbGVhbjwvVEQ+Cis8VEQ+CitJZiB0cnVlLCByZXF1aXJlcyB0aGUgdXNlIG9mIHRoZSA8Y29kZT5TVEFSVFRMUzwvY29kZT4gY29tbWFuZC4KK0lmIHRoZSBzZXJ2ZXIgZG9lc24ndCBzdXBwb3J0IHRoZSBTVEFSVFRMUyBjb21tYW5kLCBvciB0aGUgY29tbWFuZAorZmFpbHMsIHRoZSBjb25uZWN0IG1ldGhvZCB3aWxsIGZhaWwuCitEZWZhdWx0cyB0byBmYWxzZS4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5pbWFwLnByb3h5Lmhvc3QiPm1haWwuaW1hcC5wcm94eS5ob3N0PC9BPjwvVEQ+Cis8VEQ+c3RyaW5nPC9URD4KKzxURD4KK1NwZWNpZmllcyB0aGUgaG9zdCBuYW1lIG9mIGFuIEhUVFAgd2ViIHByb3h5IHNlcnZlciB0aGF0IHdpbGwgYmUgdXNlZCBmb3IKK2Nvbm5lY3Rpb25zIHRvIHRoZSBtYWlsIHNlcnZlci4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5pbWFwLnByb3h5LnBvcnQiPm1haWwuaW1hcC5wcm94eS5wb3J0PC9BPjwvVEQ+Cis8VEQ+c3RyaW5nPC9URD4KKzxURD4KK1NwZWNpZmllcyB0aGUgcG9ydCBudW1iZXIgZm9yIHRoZSBIVFRQIHdlYiBwcm94eSBzZXJ2ZXIuCitEZWZhdWx0cyB0byBwb3J0IDgwLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLmltYXAucHJveHkudXNlciI+bWFpbC5pbWFwLnByb3h5LnVzZXI8L0E+PC9URD4KKzxURD5zdHJpbmc8L1REPgorPFREPgorU3BlY2lmaWVzIHRoZSB1c2VyIG5hbWUgdG8gdXNlIHRvIGF1dGhlbnRpY2F0ZSB3aXRoIHRoZSBIVFRQIHdlYiBwcm94eSBzZXJ2ZXIuCitCeSBkZWZhdWx0LCBubyBhdXRoZW50aWNhdGlvbiBpcyBkb25lLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLmltYXAucHJveHkucGFzc3dvcmQiPm1haWwuaW1hcC5wcm94eS5wYXNzd29yZDwvQT48L1REPgorPFREPnN0cmluZzwvVEQ+Cis8VEQ+CitTcGVjaWZpZXMgdGhlIHBhc3N3b3JkIHRvIHVzZSB0byBhdXRoZW50aWNhdGUgd2l0aCB0aGUgSFRUUCB3ZWIgcHJveHkgc2VydmVyLgorQnkgZGVmYXVsdCwgbm8gYXV0aGVudGljYXRpb24gaXMgZG9uZS4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5pbWFwLnNvY2tzLmhvc3QiPm1haWwuaW1hcC5zb2Nrcy5ob3N0PC9BPjwvVEQ+Cis8VEQ+c3RyaW5nPC9URD4KKzxURD4KK1NwZWNpZmllcyB0aGUgaG9zdCBuYW1lIG9mIGEgU09DS1M1IHByb3h5IHNlcnZlciB0aGF0IHdpbGwgYmUgdXNlZCBmb3IKK2Nvbm5lY3Rpb25zIHRvIHRoZSBtYWlsIHNlcnZlci4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5pbWFwLnNvY2tzLnBvcnQiPm1haWwuaW1hcC5zb2Nrcy5wb3J0PC9BPjwvVEQ+Cis8VEQ+c3RyaW5nPC9URD4KKzxURD4KK1NwZWNpZmllcyB0aGUgcG9ydCBudW1iZXIgZm9yIHRoZSBTT0NLUzUgcHJveHkgc2VydmVyLgorVGhpcyBzaG91bGQgb25seSBuZWVkIHRvIGJlIHVzZWQgaWYgdGhlIHByb3h5IHNlcnZlciBpcyBub3QgdXNpbmcKK3RoZSBzdGFuZGFyZCBwb3J0IG51bWJlciBvZiAxMDgwLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLmltYXAubWluaWRsZXRpbWUiPm1haWwuaW1hcC5taW5pZGxldGltZTwvQT48L1REPgorPFREPmludDwvVEQ+Cis8VEQ+CitBcHBsaWNhdGlvbnMgdHlwaWNhbGx5IGNhbGwgdGhlIGlkbGUgbWV0aG9kIGluIGEgbG9vcC4gIElmIGFub3RoZXIKK3RocmVhZCB0ZXJtaWFudGVzIHRoZSBJRExFIGNvbW1hbmQsIGl0IG5lZWRzIGEgY2hhbmNlIHRvIGRvIGl0cword29yayBiZWZvcmUgYW5vdGhlciBJRExFIGNvbW1hbmQgaXMgaXNzdWVkLiAgVGhlIGlkbGUgbWV0aG9kIGVuZm9yY2VzCithIGRlbGF5IHRvIHByZXZlbnQgdGhyYXNoaW5nIGJldHdlZW4gdGhlIElETEUgY29tbWFuZCBhbmQgcmVndWxhcgorY29tbWFuZHMuICBUaGlzIHByb3BlcnR5IHNldHMgdGhlIGRlbGF5IGluIG1pbGxpc2Vjb25kcy4gIElmIG5vdAorc2V0LCB0aGUgZGVmYXVsdCBpcyAxMCBtaWxsaXNlY29uZHMuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuaW1hcC5lbmFibGVyZXNwb25zZWV2ZW50cyI+bWFpbC5pbWFwLmVuYWJsZXJlc3BvbnNlZXZlbnRzPC9BPjwvVEQ+Cis8VEQ+Ym9vbGVhbjwvVEQ+Cis8VEQ+CitFbmFibGUgc3BlY2lhbCBJTUFQLXNwZWNpZmljIGV2ZW50cyB0byBiZSBkZWxpdmVyZWQgdG8gdGhlIFN0b3JlJ3MKKzxjb2RlPkNvbm5lY3Rpb25MaXN0ZW5lcjwvY29kZT4uICBJZiB0cnVlLCBJTUFQIE9LLCBOTywgQkFELCBvciBCWUUgcmVzcG9uc2VzCit3aWxsIGJlIHNlbnQgYXMgPGNvZGU+Q29ubmVjdGlvbkV2ZW50PC9jb2RlPnMgd2l0aCBhIHR5cGUgb2YKKzxjb2RlPklNQVBTdG9yZS5SRVNQT05TRTwvY29kZT4uICBUaGUgZXZlbnQncyBtZXNzYWdlIHdpbGwgYmUgdGhlCityYXcgSU1BUCByZXNwb25zZSBzdHJpbmcuCitCeSBkZWZhdWx0LCB0aGVzZSBldmVudHMgYXJlIG5vdCBzZW50LgorTk9URTogVGhpcyBjYXBhYmlsaXR5IGlzIGhpZ2hseSBleHBlcmltZW50YWwgYW5kIGxpa2VseSB3aWxsIGNoYW5nZQoraW4gZnV0dXJlIHJlbGVhc2VzLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLmltYXAuZW5hYmxlaW1hcGV2ZW50cyI+bWFpbC5pbWFwLmVuYWJsZWltYXBldmVudHM8L0E+PC9URD4KKzxURD5ib29sZWFuPC9URD4KKzxURD4KK0VuYWJsZSBzcGVjaWFsIElNQVAtc3BlY2lmaWMgZXZlbnRzIHRvIGJlIGRlbGl2ZXJlZCB0byB0aGUgU3RvcmUncworPGNvZGU+Q29ubmVjdGlvbkxpc3RlbmVyPC9jb2RlPi4gIElmIHRydWUsIHVuc29saWNpdGVkIHJlc3BvbnNlcworcmVjZWl2ZWQgZHVyaW5nIHRoZSBTdG9yZSdzIDxjb2RlPmlkbGU8L2NvZGU+IG1ldGhvZCB3aWxsIGJlIHNlbnQKK2FzIDxjb2RlPkNvbm5lY3Rpb25FdmVudDwvY29kZT5zIHdpdGggYSB0eXBlIG9mCis8Y29kZT5JTUFQU3RvcmUuUkVTUE9OU0U8L2NvZGU+LiAgVGhlIGV2ZW50J3MgbWVzc2FnZSB3aWxsIGJlIHRoZQorcmF3IElNQVAgcmVzcG9uc2Ugc3RyaW5nLgorQnkgZGVmYXVsdCwgdGhlc2UgZXZlbnRzIGFyZSBub3Qgc2VudC4KK05PVEU6IFRoaXMgY2FwYWJpbGl0eSBpcyBoaWdobHkgZXhwZXJpbWVudGFsIGFuZCBsaWtlbHkgd2lsbCBjaGFuZ2UKK2luIGZ1dHVyZSByZWxlYXNlcy4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5pbWFwLnRocm93c2VhcmNoZXhjZXB0aW9uIj5tYWlsLmltYXAudGhyb3dzZWFyY2hleGNlcHRpb248L0E+PC9URD4KKzxURD5ib29sZWFuPC9URD4KKzxURD4KK0lmIHNldCB0byB0cnVlIGFuZCBhIHtAbGluayBqYXZheC5tYWlsLnNlYXJjaC5TZWFyY2hUZXJtIFNlYXJjaFRlcm19CitwYXNzZWQgdG8gdGhlCit7QGxpbmsgamF2YXgubWFpbC5Gb2xkZXIjc2VhcmNoIEZvbGRlci5zZWFyY2h9CittZXRob2QgaXMgdG9vIGNvbXBsZXggZm9yIHRoZSBJTUFQIHByb3RvY29sLCB0aHJvdyBhCit7QGxpbmsgamF2YXgubWFpbC5zZWFyY2guU2VhcmNoRXhjZXB0aW9uIFNlYXJjaEV4Y2VwdGlvbn0uCitGb3IgZXhhbXBsZSwgdGhlIElNQVAgcHJvdG9jb2wgb25seSBzdXBwb3J0cyBsZXNzLXRoYW4gYW5kIGdyZWF0ZXItdGhhbgorY29tcGFyaXNvbnMgZm9yIGEge0BsaW5rIGphdmF4Lm1haWwuc2VhcmNoLlNpemVUZXJtIFNpemVUZXJtfS4KK0lmIGZhbHNlLCB0aGUgc2VhcmNoIHdpbGwgYmUgZG9uZSBsb2NhbGx5IGJ5IGZldGNoaW5nIHRoZSByZXF1aXJlZAorbWVzc2FnZSBkYXRhIGFuZCBjb21wYXJpbmcgaXQgbG9jYWxseS4KK0RlZmF1bHRzIHRvIGZhbHNlLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLmltYXAuZm9sZGVyLmNsYXNzIj5tYWlsLmltYXAuZm9sZGVyLmNsYXNzPC9BPjwvVEQ+Cis8VEQ+U3RyaW5nPC9URD4KKzxURD4KK0NsYXNzIG5hbWUgb2YgYSBzdWJjbGFzcyBvZiA8Y29kZT5jb20uc3VuLm1haWwuaW1hcC5JTUFQRm9sZGVyPC9jb2RlPi4KK1RoZSBzdWJjbGFzcyBjYW4gYmUgdXNlZCB0byBwcm92aWRlIHN1cHBvcnQgZm9yIGFkZGl0aW9uYWwgSU1BUCBjb21tYW5kcy4KK1RoZSBzdWJjbGFzcyBtdXN0IGhhdmUgcHVibGljIGNvbnN0cnVjdG9ycyBvZiB0aGUgZm9ybQorPGNvZGU+cHVibGljIE15SU1BUEZvbGRlcihTdHJpbmcgZnVsbE5hbWUsIGNoYXIgc2VwYXJhdG9yLCBJTUFQU3RvcmUgc3RvcmUsCitCb29sZWFuIGlzTmFtZXNwYWNlKTwvY29kZT4gYW5kCis8Y29kZT5wdWJsaWMgTXlJTUFQRm9sZGVyKExpc3RJbmZvIGxpLCBJTUFQU3RvcmUgc3RvcmUpPC9jb2RlPgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLmltYXAuY2xvc2Vmb2xkZXJzb25zdG9yZWZhaWx1cmUiPm1haWwuaW1hcC5jbG9zZWZvbGRlcnNvbnN0b3JlZmFpbHVyZTwvQT48L1REPgorPFREPmJvb2xlYW48L1REPgorPFREPgorSW4gc29tZSBjYXNlcywgYSBmYWlsdXJlIG9mIHRoZSBTdG9yZSBjb25uZWN0aW9uIGluZGljYXRlcyBhIGZhaWx1cmUgb2YgdGhlCitzZXJ2ZXIsIGFuZCBhbGwgRm9sZGVycyBhc3NvY2lhdGVkIHdpdGggdGhhdCBTdG9yZSBzaG91bGQgYWxzbyBiZSBjbG9zZWQuCitJbiBvdGhlciBjYXNlcywgYSBTdG9yZSBjb25uZWN0aW9uIGZhaWx1cmUgbWF5IGJlIGEgdHJhbnNpZW50IGZhaWx1cmUsIGFuZAorRm9sZGVycyBtYXkgY29udGludWUgdG8gb3BlcmF0ZSBub3JtYWxseS4KK0lmIHRoaXMgcHJvcGVydHkgaXMgdHJ1ZSAodGhlIGRlZmF1bHQpLCBmYWlsdXJlcyBpbiB0aGUgU3RvcmUgY29ubmVjdGlvbiBjYXVzZQorYWxsIGFzc29jaWF0ZWQgRm9sZGVycyB0byBiZSBjbG9zZWQuCitTZXQgdGhpcyBwcm9wZXJ0eSB0byBmYWxzZSB0byBiZXR0ZXIgaGFuZGxlIHRyYW5zaWVudCBmYWlsdXJlcyBpbiB0aGUgU3RvcmUKK2Nvbm5lY3Rpb24uCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuaW1hcC5maW5hbGl6ZWNsZWFuY2xvc2UiPm1haWwuaW1hcC5maW5hbGl6ZWNsZWFuY2xvc2U8L0E+PC9URD4KKzxURD5ib29sZWFuPC9URD4KKzxURD4KK1doZW4gdGhlIGZpbmFsaXplciBmb3IgSU1BUFN0b3JlIGlzIGNhbGxlZCwKK3Nob3VsZCB0aGUgY29ubmVjdGlvbiB0byB0aGUgc2VydmVyIGJlIGNsb3NlZCBjbGVhbmx5LCBhcyBpZiB0aGUKK2FwcGxpY2F0aW9uIGNhbGxlZCB0aGUgY2xvc2UgbWV0aG9kPworT3Igc2hvdWxkIHRoZSBjb25uZWN0aW9uIHRvIHRoZSBzZXJ2ZXIgYmUgY2xvc2VkIHdpdGhvdXQgc2VuZGluZworYW55IGNvbW1hbmRzIHRvIHRoZSBzZXJ2ZXI/CitEZWZhdWx0cyB0byBmYWxzZSwgdGhlIGNvbm5lY3Rpb24gaXMgbm90IGNsb3NlZCBjbGVhbmx5LgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLmltYXAucmVmZXJyYWxleGNlcHRpb24iPm1haWwuaW1hcC5yZWZlcnJhbGV4Y2VwdGlvbjwvQT48L1REPgorPFREPmJvb2xlYW48L1REPgorPFREPgorSWYgc2V0IHRvIHRydWUgYW5kIGFuIElNQVAgbG9naW4gcmVmZXJyYWwgaXMgcmV0dXJuZWQgd2hlbiB0aGUgYXV0aGVudGljYXRpb24KK3N1Y2NlZWRzLCBmYWlsIHRoZSBjb25uZWN0IHJlcXVlc3QgYW5kIHRocm93IGEKK3tAbGluayBjb20uc3VuLm1haWwuaW1hcC5SZWZlcnJhbEV4Y2VwdGlvbiBSZWZlcnJhbEV4Y2VwdGlvbn0uCitEZWZhdWx0cyB0byBmYWxzZS4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5pbWFwLmNvbXByZXNzLmVuYWJsZSI+bWFpbC5pbWFwLmNvbXByZXNzLmVuYWJsZTwvQT48L1REPgorPFREPmJvb2xlYW48L1REPgorPFREPgorSWYgc2V0IHRvIHRydWUgYW5kIHRoZSBJTUFQIHNlcnZlciBzdXBwb3J0cyB0aGUgQ09NUFJFU1M9REVGTEFURSBleHRlbnNpb24sCitjb21wcmVzc2lvbiB3aWxsIGJlIGVuYWJsZWQuCitEZWZhdWx0cyB0byBmYWxzZS4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5pbWFwLmNvbXByZXNzLmxldmVsIj5tYWlsLmltYXAuY29tcHJlc3MubGV2ZWw8L0E+PC9URD4KKzxURD5pbnQ8L1REPgorPFREPgorVGhlIGNvbXByZXNzaW9uIGxldmVsIHRvIGJlIHVzZWQsIGluIHRoZSByYW5nZSAtMSB0byA5LgorU2VlIHRoZSB7QGxpbmsgamF2YS51dGlsLnppcC5EZWZsYXRlciBEZWZsYXRlcn0gY2xhc3MgZm9yIGRldGFpbHMuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuaW1hcC5jb21wcmVzcy5zdHJhdGVneSI+bWFpbC5pbWFwLmNvbXByZXNzLnN0cmF0ZWd5PC9BPjwvVEQ+Cis8VEQ+aW50PC9URD4KKzxURD4KK1RoZSBjb21wcmVzc2lvbiBzdHJhdGVneSB0byBiZSB1c2VkLCBpbiB0aGUgcmFuZ2UgMCB0byAyLgorU2VlIHRoZSB7QGxpbmsgamF2YS51dGlsLnppcC5EZWZsYXRlciBEZWZsYXRlcn0gY2xhc3MgZm9yIGRldGFpbHMuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuaW1hcC5yZXVzZXRhZ3ByZWZpeCI+bWFpbC5pbWFwLmNvbXByZXNzLnN0cmF0ZWd5PC9BPjwvVEQ+Cis8VEQ+Ym9vbGVhbjwvVEQ+Cis8VEQ+CitJZiB0cnVlLCBhbHdheXMgdXNlICJBIiBmb3IgdGhlIElNQVAgY29tbWFuZCB0YWcgcHJlZml4LgorSWYgZmFsc2UsIHRoZSBJTUFQIGNvbW1hbmQgdGFnIHByZWZpeCBpcyBkaWZmZXJlbnQgZm9yIGVhY2ggY29ubmVjdGlvbiwKK2Zyb20gIkEiIHRocm91Z2ggIlpaWiIgYW5kIHRoZW4gd3JhcHBpbmcgYXJvdW5kIHRvICJBIi4KK0FwcGxpY2F0aW9ucyBzaG91bGQgbmV2ZXIgbmVlZCB0byBzZXQgdGhpcy4KK0RlZmF1bHRzIHRvIGZhbHNlLgorPC9URD4KKzwvVFI+CisKKzwvVEFCTEU+Cis8UD4KK0luIGdlbmVyYWwsIGFwcGxpY2F0aW9ucyBzaG91bGQgbm90IG5lZWQgdG8gdXNlIHRoZSBjbGFzc2VzIGluIHRoaXMKK3BhY2thZ2UgZGlyZWN0bHkuICBJbnN0ZWFkLCB0aGV5IHNob3VsZCB1c2UgdGhlIEFQSXMgZGVmaW5lZCBieSB0aGUKKzxjb2RlPmphdmF4Lm1haWw8L2NvZGU+IHBhY2thZ2UgKGFuZCBzdWJwYWNrYWdlcykuICBBcHBsaWNhdGlvbnMgc2hvdWxkCituZXZlciBjb25zdHJ1Y3QgaW5zdGFuY2VzIG9mIDxjb2RlPklNQVBTdG9yZTwvY29kZT4gb3IKKzxjb2RlPklNQVBGb2xkZXI8L2NvZGU+IGRpcmVjdGx5LiAgSW5zdGVhZCwgdGhleSBzaG91bGQgdXNlIHRoZQorPGNvZGU+U2Vzc2lvbjwvY29kZT4gbWV0aG9kIDxjb2RlPmdldFN0b3JlPC9jb2RlPiB0byBhY3F1aXJlIGFuCithcHByb3ByaWF0ZSA8Y29kZT5TdG9yZTwvY29kZT4gb2JqZWN0LCBhbmQgZnJvbSB0aGF0IGFjcXVpcmUKKzxjb2RlPkZvbGRlcjwvY29kZT4gb2JqZWN0cy4KKzwvUD4KKzxTVFJPTkc+TG9nZ2VyczwvU1RST05HPgorPFA+CitJbiBhZGRpdGlvbiB0byBwcmludGluZyBkZWJ1Z2dpbmcgb3V0cHV0IGFzIGNvbnRyb2xsZWQgYnkgdGhlCit7QGxpbmsgamF2YXgubWFpbC5TZXNzaW9uIFNlc3Npb259IGNvbmZpZ3VyYXRpb24sCit0aGUgY29tLnN1bi5tYWlsLmltYXAgcHJvdmlkZXIgbG9ncyB0aGUgc2FtZSBpbmZvcm1hdGlvbiB1c2luZwore0BsaW5rIGphdmEudXRpbC5sb2dnaW5nLkxvZ2dlcn0gYXMgZGVzY3JpYmVkIGluIHRoZSBmb2xsb3dpbmcgdGFibGU6Cis8L1A+Cis8VEFCTEUgQk9SREVSIFNVTU1BUlk9IklNQVAgTG9nZ2VycyI+Cis8VFI+Cis8VEg+TG9nZ2VyIE5hbWU8L1RIPgorPFRIPkxvZ2dpbmcgTGV2ZWw8L1RIPgorPFRIPlB1cnBvc2U8L1RIPgorPC9UUj4KKworPFRSPgorPFREPmNvbS5zdW4ubWFpbC5pbWFwPC9URD4KKzxURD5DT05GSUc8L1REPgorPFREPkNvbmZpZ3VyYXRpb24gb2YgdGhlIElNQVBTdG9yZTwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+Y29tLnN1bi5tYWlsLmltYXA8L1REPgorPFREPkZJTkU8L1REPgorPFREPkdlbmVyYWwgZGVidWdnaW5nIG91dHB1dDwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+Y29tLnN1bi5tYWlsLmltYXAuY29ubmVjdGlvbnBvb2w8L1REPgorPFREPkNPTkZJRzwvVEQ+Cis8VEQ+Q29uZmlndXJhdGlvbiBvZiB0aGUgSU1BUCBjb25uZWN0aW9uIHBvb2w8L1REPgorPC9UUj4KKworPFRSPgorPFREPmNvbS5zdW4ubWFpbC5pbWFwLmNvbm5lY3Rpb25wb29sPC9URD4KKzxURD5GSU5FPC9URD4KKzxURD5EZWJ1Z2dpbmcgb3V0cHV0IHJlbGF0ZWQgdG8gdGhlIElNQVAgY29ubmVjdGlvbiBwb29sPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD5jb20uc3VuLm1haWwuaW1hcC5tZXNzYWdlY2FjaGU8L1REPgorPFREPkNPTkZJRzwvVEQ+Cis8VEQ+Q29uZmlndXJhdGlvbiBvZiB0aGUgSU1BUCBtZXNzYWdlIGNhY2hlPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD5jb20uc3VuLm1haWwuaW1hcC5tZXNzYWdlY2FjaGU8L1REPgorPFREPkZJTkU8L1REPgorPFREPkRlYnVnZ2luZyBvdXRwdXQgcmVsYXRlZCB0byB0aGUgSU1BUCBtZXNzYWdlIGNhY2hlPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD5jb20uc3VuLm1haWwuaW1hcC5wcm90b2NvbDwvVEQ+Cis8VEQ+RklORVNUPC9URD4KKzxURD5Db21wbGV0ZSBwcm90b2NvbCB0cmFjZTwvVEQ+Cis8L1RSPgorPC9UQUJMRT4KKworPFNUUk9ORz5XQVJOSU5HPC9TVFJPTkc+Cis8UD4KKzxzdHJvbmc+V0FSTklORzo8L3N0cm9uZz4gVGhlIEFQSXMgdW5pcXVlIHRvIHRoaXMgcGFja2FnZSBzaG91bGQgYmUKK2NvbnNpZGVyZWQgPHN0cm9uZz5FWFBFUklNRU5UQUw8L3N0cm9uZz4uICBUaGV5IG1heSBiZSBjaGFuZ2VkIGluIHRoZQorZnV0dXJlIGluIHdheXMgdGhhdCBhcmUgaW5jb21wYXRpYmxlIHdpdGggYXBwbGljYXRpb25zIHVzaW5nIHRoZQorY3VycmVudCBBUElzLgorPC9QPgorCis8L0JPRFk+Cis8L0hUTUw+CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvcHJvdG9jb2wvQkFTRTY0TWFpbGJveERlY29kZXIuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9CQVNFNjRNYWlsYm94RGVjb2Rlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFmMzUwMjAKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvcHJvdG9jb2wvQkFTRTY0TWFpbGJveERlY29kZXIuamF2YQpAQCAtMCwwICsxLDE3MCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuaW1hcC5wcm90b2NvbDsKKworaW1wb3J0IGphdmEudGV4dC5TdHJpbmdDaGFyYWN0ZXJJdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnRleHQuQ2hhcmFjdGVySXRlcmF0b3I7CisKKy8qKgorICogU2VlIHRoZSBCQVNFNjRNYWlsYm94RW5jb2RlciBmb3IgYSBkZXNjcmlwdGlvbiBvZiB0aGUgUkZDMjA2MCBhbmQgaG93CisgKiBtYWlsYm94IG5hbWVzIHNob3VsZCBiZSBlbmNvZGVkLiAgVGhpcyBjbGFzcyB3aWxsIGRvIHRoZSBjb3JyZWN0IGRlY29kaW5nCisgKiBmb3IgbWFpbGJveCBuYW1lcy4KKyAqCisgKiBAYXV0aG9yCUNocmlzdG9waGVyIENvdHRvbgorICovCisKK3B1YmxpYyBjbGFzcyBCQVNFNjRNYWlsYm94RGVjb2RlciB7CisgICAgCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZGVjb2RlKFN0cmluZyBvcmlnaW5hbCkgeworCWlmIChvcmlnaW5hbCA9PSBudWxsIHx8IG9yaWdpbmFsLmxlbmd0aCgpID09IDApCisJICAgIHJldHVybiBvcmlnaW5hbDsKKworCWJvb2xlYW4gY2hhbmdlZFN0cmluZyA9IGZhbHNlOworCWludCBjb3B5VG8gPSAwOworCS8vIGl0IHdpbGwgYWx3YXlzIGJlIGxlc3MgdGhhbiB0aGUgb3JpZ2luYWwKKwljaGFyW10gY2hhcnMgPSBuZXcgY2hhcltvcmlnaW5hbC5sZW5ndGgoKV07IAorCVN0cmluZ0NoYXJhY3Rlckl0ZXJhdG9yIGl0ZXIgPSBuZXcgU3RyaW5nQ2hhcmFjdGVySXRlcmF0b3Iob3JpZ2luYWwpOworCQorCWZvcihjaGFyIGMgPSBpdGVyLmZpcnN0KCk7IGMgIT0gQ2hhcmFjdGVySXRlcmF0b3IuRE9ORTsgCisJICAgIGMgPSBpdGVyLm5leHQoKSkgeworCisJICAgIGlmIChjID09ICcmJykgeworCQljaGFuZ2VkU3RyaW5nID0gdHJ1ZTsKKwkJY29weVRvID0gYmFzZTY0ZGVjb2RlKGNoYXJzLCBjb3B5VG8sIGl0ZXIpOworCSAgICB9IGVsc2UgeworCQljaGFyc1tjb3B5VG8rK10gPSBjOworCSAgICB9CisJfQorCQorCS8vIG5vdyBjcmVhdGUgb3VyIHN0cmluZyBmcm9tIHRoZSBjaGFyIGFycmF5CisJaWYgKGNoYW5nZWRTdHJpbmcpIHsKKwkgICAgcmV0dXJuIG5ldyBTdHJpbmcoY2hhcnMsIDAsIGNvcHlUbyk7CisJfSBlbHNlIHsKKwkgICAgcmV0dXJuIG9yaWdpbmFsOworCX0JCisgICAgfQorCisKKyAgICBwcm90ZWN0ZWQgc3RhdGljIGludCBiYXNlNjRkZWNvZGUoY2hhcltdIGJ1ZmZlciwgaW50IG9mZnNldCwKKwkJCQkgICAgICBDaGFyYWN0ZXJJdGVyYXRvciBpdGVyKSB7CisJYm9vbGVhbiBmaXJzdHRpbWUgPSB0cnVlOworCWludCBsZWZ0b3ZlciA9IC0xOworCisJd2hpbGUodHJ1ZSkgeworCSAgICAvLyBnZXQgdGhlIGZpcnN0IGJ5dGUKKwkgICAgYnl0ZSBvcmlnXzAgPSAoYnl0ZSkgaXRlci5uZXh0KCk7CisJICAgIGlmIChvcmlnXzAgPT0gLTEpIGJyZWFrOyAvLyBubyBtb3JlIGNoYXJzCisJICAgIGlmIChvcmlnXzAgPT0gJy0nKSB7CisJCWlmIChmaXJzdHRpbWUpIHsKKwkJICAgIC8vIG1lYW5zIHdlIGdvdCB0aGUgc3RyaW5nICImLSIgd2hpY2ggaXMgdHVybmVkIGludG8gYSAiJiIKKwkJICAgIGJ1ZmZlcltvZmZzZXQrK10gPSAnJic7CisJCX0KKwkJLy8gd2UgYXJlIGRvbmUgbm93CisJCWJyZWFrOworCSAgICB9CisJICAgIGZpcnN0dGltZSA9IGZhbHNlOworCSAgICAKKwkgICAgLy8gbmV4dCBieXRlCisJICAgIGJ5dGUgb3JpZ18xID0gKGJ5dGUpIGl0ZXIubmV4dCgpOwkgICAgCisJICAgIGlmIChvcmlnXzEgPT0gLTEgfHwgb3JpZ18xID09ICctJykKKwkJYnJlYWs7IC8vIG5vIG1vcmUgY2hhcnMsIGludmFsaWQgYmFzZTY0CisJICAgIAorCSAgICBieXRlIGEsIGIsIGN1cnJlbnQ7CisJICAgIGEgPSBwZW1fY29udmVydF9hcnJheVtvcmlnXzAgJiAweGZmXTsKKwkgICAgYiA9IHBlbV9jb252ZXJ0X2FycmF5W29yaWdfMSAmIDB4ZmZdOworCSAgICAvLyBUaGUgZmlyc3QgZGVjb2RlZCBieXRlCisJICAgIGN1cnJlbnQgPSAoYnl0ZSkoKChhIDw8IDIpICYgMHhmYykgfCAoKGIgPj4+IDQpICYgMykpOworCisJICAgIC8vIHVzZSB0aGUgbGVmdG92ZXIgdG8gY3JlYXRlIGEgVW5pY29kZSBDaGFyYWN0ZXIgKDIgYnl0ZXMpCisJICAgIGlmIChsZWZ0b3ZlciAhPSAtMSkgeworCQlidWZmZXJbb2Zmc2V0KytdID0gKGNoYXIpKGxlZnRvdmVyIDw8IDggfCAoY3VycmVudCAmIDB4ZmYpKTsKKwkJbGVmdG92ZXIgPSAtMTsKKwkgICAgfSBlbHNlIHsKKwkJbGVmdG92ZXIgPSBjdXJyZW50ICYgMHhmZjsKKwkgICAgfQorCSAgICAKKwkgICAgYnl0ZSBvcmlnXzIgPSAoYnl0ZSkgaXRlci5uZXh0KCk7CisJICAgIGlmIChvcmlnXzIgPT0gJz0nKSB7IC8vIEVuZCBvZiB0aGlzIEJBU0U2NCBlbmNvZGluZworCQljb250aW51ZTsKKwkgICAgfSBlbHNlIGlmIChvcmlnXzIgPT0gLTEgfHwgb3JpZ18yID09ICctJykgeworCSAgICAJYnJlYWs7IC8vIG5vIG1vcmUgY2hhcnMKKwkgICAgfQorCSAgICAJICAgIAorCSAgICAvLyBzZWNvbmQgZGVjb2RlZCBieXRlCisJICAgIGEgPSBiOworCSAgICBiID0gcGVtX2NvbnZlcnRfYXJyYXlbb3JpZ18yICYgMHhmZl07CisJICAgIGN1cnJlbnQgPSAoYnl0ZSkoKChhIDw8IDQpICYgMHhmMCkgfCAoKGIgPj4+IDIpICYgMHhmKSk7CisKKwkgICAgLy8gdXNlIHRoZSBsZWZ0b3ZlciB0byBjcmVhdGUgYSBVbmljb2RlIENoYXJhY3RlciAoMiBieXRlcykKKwkgICAgaWYgKGxlZnRvdmVyICE9IC0xKSB7CisJCWJ1ZmZlcltvZmZzZXQrK10gPSAoY2hhcikobGVmdG92ZXIgPDwgOCB8IChjdXJyZW50ICYgMHhmZikpOworCQlsZWZ0b3ZlciA9IC0xOworCSAgICB9IGVsc2UgeworCQlsZWZ0b3ZlciA9IGN1cnJlbnQgJiAweGZmOworCSAgICB9CisKKwkgICAgYnl0ZSBvcmlnXzMgPSAoYnl0ZSkgaXRlci5uZXh0KCk7CisJICAgIGlmIChvcmlnXzMgPT0gJz0nKSB7IC8vIEVuZCBvZiB0aGlzIEJBU0U2NCBlbmNvZGluZworCQljb250aW51ZTsKKwkgICAgfSBlbHNlIGlmIChvcmlnXzMgPT0gLTEgfHwgb3JpZ18zID09ICctJykgeworCSAgICAJYnJlYWs7ICAvLyBubyBtb3JlIGNoYXJzCisJICAgIH0KKwkgICAgCisJICAgIC8vIFRoZSB0aGlyZCBkZWNvZGVkIGJ5dGUKKwkgICAgYSA9IGI7CisJICAgIGIgPSBwZW1fY29udmVydF9hcnJheVtvcmlnXzMgJiAweGZmXTsKKwkgICAgY3VycmVudCA9IChieXRlKSgoKGEgPDwgNikgJiAweGMwKSB8IChiICYgMHgzZikpOworCSAgICAKKwkgICAgLy8gdXNlIHRoZSBsZWZ0b3ZlciB0byBjcmVhdGUgYSBVbmljb2RlIENoYXJhY3RlciAoMiBieXRlcykKKwkgICAgaWYgKGxlZnRvdmVyICE9IC0xKSB7CisJCWJ1ZmZlcltvZmZzZXQrK10gPSAoY2hhcikobGVmdG92ZXIgPDwgOCB8IChjdXJyZW50ICYgMHhmZikpOworCQlsZWZ0b3ZlciA9IC0xOworCSAgICB9IGVsc2UgeworCQlsZWZ0b3ZlciA9IGN1cnJlbnQgJiAweGZmOworCSAgICB9CSAgICAKKwl9CisJCisJcmV0dXJuIG9mZnNldDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIGNoYXJhY3RlciBhcnJheSBwcm92aWRlcyB0aGUgY2hhcmFjdGVyIHRvIHZhbHVlIG1hcAorICAgICAqIGJhc2VkIG9uIFJGQzE1MjEsIGJ1dCB3aXRoIHRoZSBtb2RpZmljYXRpb24gZnJvbSBSRkMyMDYwCisgICAgICogd2hpY2ggY2hhbmdlcyB0aGUgJy8nIHRvIGEgJywnLgorICAgICAqLyAgCisKKyAgICAvLyBzaGFyZWQgd2l0aCBCQVNFNjRNYWlsYm94RW5jb2RlcgorICAgIHN0YXRpYyBmaW5hbCBjaGFyIHBlbV9hcnJheVtdID0geworCSdBJywnQicsJ0MnLCdEJywnRScsJ0YnLCdHJywnSCcsIC8vIDAKKwknSScsJ0onLCdLJywnTCcsJ00nLCdOJywnTycsJ1AnLCAvLyAxCisJJ1EnLCdSJywnUycsJ1QnLCdVJywnVicsJ1cnLCdYJywgLy8gMgorCSdZJywnWicsJ2EnLCdiJywnYycsJ2QnLCdlJywnZicsIC8vIDMKKwknZycsJ2gnLCdpJywnaicsJ2snLCdsJywnbScsJ24nLCAvLyA0CisJJ28nLCdwJywncScsJ3InLCdzJywndCcsJ3UnLCd2JywgLy8gNQorCSd3JywneCcsJ3knLCd6JywnMCcsJzEnLCcyJywnMycsIC8vIDYKKwknNCcsJzUnLCc2JywnNycsJzgnLCc5JywnKycsJywnICAvLyA3CisgICAgfTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGUgcGVtX2NvbnZlcnRfYXJyYXlbXSA9IG5ldyBieXRlWzI1Nl07CisKKyAgICBzdGF0aWMgeworCWZvciAoaW50IGkgPSAwOyBpIDwgMjU1OyBpKyspCisJICAgIHBlbV9jb252ZXJ0X2FycmF5W2ldID0gLTE7CisJZm9yKGludCBpID0gMDsgaSA8IHBlbV9hcnJheS5sZW5ndGg7IGkrKykKKwkgICAgcGVtX2NvbnZlcnRfYXJyYXlbcGVtX2FycmF5W2ldXSA9IChieXRlKSBpOworICAgIH0gICAgCit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvcHJvdG9jb2wvQkFTRTY0TWFpbGJveEVuY29kZXIuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9CQVNFNjRNYWlsYm94RW5jb2Rlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjEwMTNiYWYKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvcHJvdG9jb2wvQkFTRTY0TWFpbGJveEVuY29kZXIuamF2YQpAQCAtMCwwICsxLDIzMCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuaW1hcC5wcm90b2NvbDsKKworaW1wb3J0IGphdmEuaW8uKjsKKworCisvKioKKyAqIEZyb20gUkZDMjA2MDoKKyAqCisgKiA8YmxvY2txdW90ZT48cHJlPgorICoKKyAqIDUuMS4zLiAgTWFpbGJveCBJbnRlcm5hdGlvbmFsIE5hbWluZyBDb252ZW50aW9uCisgKgorICogICBCeSBjb252ZW50aW9uLCBpbnRlcm5hdGlvbmFsIG1haWxib3ggbmFtZXMgYXJlIHNwZWNpZmllZCB1c2luZyBhCisgKiAgIG1vZGlmaWVkIHZlcnNpb24gb2YgdGhlIFVURi03IGVuY29kaW5nIGRlc2NyaWJlZCBpbiBbVVRGLTddLiAgVGhlCisgKiAgIHB1cnBvc2Ugb2YgdGhlc2UgbW9kaWZpY2F0aW9ucyBpcyB0byBjb3JyZWN0IHRoZSBmb2xsb3dpbmcgcHJvYmxlbXMKKyAqICAgd2l0aCBVVEYtNzoKKyAqCisgKiAgICAgIDEpIFVURi03IHVzZXMgdGhlICIrIiBjaGFyYWN0ZXIgZm9yIHNoaWZ0aW5nOyB0aGlzIGNvbmZsaWN0cyB3aXRoCisgKiAgICAgICAgIHRoZSBjb21tb24gdXNlIG9mICIrIiBpbiBtYWlsYm94IG5hbWVzLCBpbiBwYXJ0aWN1bGFyIFVTRU5FVAorICogICAgICAgICBuZXdzZ3JvdXAgbmFtZXMuCisgKgorICogICAgICAyKSBVVEYtNydzIGVuY29kaW5nIGlzIEJBU0U2NCB3aGljaCB1c2VzIHRoZSAiLyIgY2hhcmFjdGVyOyB0aGlzCisgKiAgICAgICAgIGNvbmZsaWN0cyB3aXRoIHRoZSB1c2Ugb2YgIi8iIGFzIGEgcG9wdWxhciBoaWVyYXJjaHkgZGVsaW1pdGVyLgorICoKKyAqICAgICAgMykgVVRGLTcgcHJvaGliaXRzIHRoZSB1bmVuY29kZWQgdXNhZ2Ugb2YgIlwiOyB0aGlzIGNvbmZsaWN0cyB3aXRoCisgKiAgICAgICAgIHRoZSB1c2Ugb2YgIlwiIGFzIGEgcG9wdWxhciBoaWVyYXJjaHkgZGVsaW1pdGVyLgorICoKKyAqICAgICAgNCkgVVRGLTcgcHJvaGliaXRzIHRoZSB1bmVuY29kZWQgdXNhZ2Ugb2YgIn4iOyB0aGlzIGNvbmZsaWN0cyB3aXRoCisgKiAgICAgICAgIHRoZSB1c2Ugb2YgIn4iIGluIHNvbWUgc2VydmVycyBhcyBhIGhvbWUgZGlyZWN0b3J5IGluZGljYXRvci4KKyAqCisgKiAgICAgIDUpIFVURi03IHBlcm1pdHMgbXVsdGlwbGUgYWx0ZXJuYXRlIGZvcm1zIHRvIHJlcHJlc2VudCB0aGUgc2FtZQorICogICAgICAgICBzdHJpbmc7IGluIHBhcnRpY3VsYXIsIHByaW50YWJsZSBVUy1BU0NJSSBjaGFyYXJhY3RlcnMgY2FuIGJlCisgKiAgICAgICAgIHJlcHJlc2VudGVkIGluIGVuY29kZWQgZm9ybS4KKyAqCisgKiAgIEluIG1vZGlmaWVkIFVURi03LCBwcmludGFibGUgVVMtQVNDSUkgY2hhcmFjdGVycyBleGNlcHQgZm9yICImYW1wOyIKKyAqICAgcmVwcmVzZW50IHRoZW1zZWx2ZXM7IHRoYXQgaXMsIGNoYXJhY3RlcnMgd2l0aCBvY3RldCB2YWx1ZXMgMHgyMC0weDI1CisgKiAgIGFuZCAweDI3LTB4N2UuICBUaGUgY2hhcmFjdGVyICImYW1wOyIgKDB4MjYpIGlzIHJlcHJlc2VudGVkIGJ5IHRoZSB0d28tCisgKiAgIG9jdGV0IHNlcXVlbmNlICImYW1wOy0iLgorICoKKyAqICAgQWxsIG90aGVyIGNoYXJhY3RlcnMgKG9jdGV0IHZhbHVlcyAweDAwLTB4MWYsIDB4N2YtMHhmZiwgYW5kIGFsbAorICogICBVbmljb2RlIDE2LWJpdCBvY3RldHMpIGFyZSByZXByZXNlbnRlZCBpbiBtb2RpZmllZCBCQVNFNjQsIHdpdGggYQorICogICBmdXJ0aGVyIG1vZGlmaWNhdGlvbiBmcm9tIFtVVEYtN10gdGhhdCAiLCIgaXMgdXNlZCBpbnN0ZWFkIG9mICIvIi4KKyAqICAgTW9kaWZpZWQgQkFTRTY0IE1VU1QgTk9UIGJlIHVzZWQgdG8gcmVwcmVzZW50IGFueSBwcmludGluZyBVUy1BU0NJSQorICogICBjaGFyYWN0ZXIgd2hpY2ggY2FuIHJlcHJlc2VudCBpdHNlbGYuCisgKgorICogICAiJmFtcDsiIGlzIHVzZWQgdG8gc2hpZnQgdG8gbW9kaWZpZWQgQkFTRTY0IGFuZCAiLSIgdG8gc2hpZnQgYmFjayB0byBVUy0KKyAqICAgQVNDSUkuICBBbGwgbmFtZXMgc3RhcnQgaW4gVVMtQVNDSUksIGFuZCBNVVNUIGVuZCBpbiBVUy1BU0NJSSAodGhhdAorICogICBpcywgYSBuYW1lIHRoYXQgZW5kcyB3aXRoIGEgVW5pY29kZSAxNi1iaXQgb2N0ZXQgTVVTVCBlbmQgd2l0aCBhICItCisgKiAgICIpLgorICoKKyAqICAgRm9yIGV4YW1wbGUsIGhlcmUgaXMgYSBtYWlsYm94IG5hbWUgd2hpY2ggbWl4ZXMgRW5nbGlzaCwgSmFwYW5lc2UsCisgKiAgIGFuZCBDaGluZXNlIHRleHQ6IH5wZXRlci9tYWlsLyZhbXA7WmVWbkxJcWUtLyZhbXA7VSxCVEZ3LQorICoKKyAqIDwvcHJlPjwvYmxvY2txdW90ZT4KKyAqCisgKiBUaGlzIGNsYXNzIHdpbGwgZG8gdGhlIGNvcnJlY3QgRW5jb2RpbmcgZm9yIHRoZSBJTUFQIG1haWxib3hlcy4KKyAqCisgKiBAYXV0aG9yCUNocmlzdG9waGVyIENvdHRvbgorICovCisKK3B1YmxpYyBjbGFzcyBCQVNFNjRNYWlsYm94RW5jb2RlciB7CisgICAgcHJvdGVjdGVkIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVs0XTsKKyAgICBwcm90ZWN0ZWQgaW50IGJ1ZnNpemUgPSAwOworICAgIHByb3RlY3RlZCBib29sZWFuIHN0YXJ0ZWQgPSBmYWxzZTsKKyAgICBwcm90ZWN0ZWQgV3JpdGVyIG91dCA9IG51bGw7CisgICAgCisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBlbmNvZGUoU3RyaW5nIG9yaWdpbmFsKSB7CisJQkFTRTY0TWFpbGJveEVuY29kZXIgYmFzZTY0c3RyZWFtID0gbnVsbDsKKwljaGFyIG9yaWdjaGFyc1tdID0gb3JpZ2luYWwudG9DaGFyQXJyYXkoKTsKKwlpbnQgbGVuZ3RoID0gb3JpZ2NoYXJzLmxlbmd0aDsKKwlib29sZWFuIGNoYW5nZWRTdHJpbmcgPSBmYWxzZTsKKwlDaGFyQXJyYXlXcml0ZXIgd3JpdGVyID0gbmV3IENoYXJBcnJheVdyaXRlcihsZW5ndGgpOworCQorCS8vIGxvb3Agb3ZlciBhbGwgdGhlIGNoYXJzCisJZm9yKGludCBpbmRleCA9IDA7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrKSB7CisJICAgIGNoYXIgY3VycmVudCA9IG9yaWdjaGFyc1tpbmRleF07CisKKwkgICAgLy8gb2N0ZXRzIGluIHRoZSByYW5nZSAweDIwLTB4MjUsMHgyNy0weDdlIGFyZSB0aGVtc2VsdmVzCisJICAgIC8vIDB4MjYgIiYiIGlzIHJlcHJlc2VudGVkIGFzICImLSIKKwkgICAgaWYgKGN1cnJlbnQgPj0gMHgyMCAmJiBjdXJyZW50IDw9IDB4N2UpIHsKKwkJaWYgKGJhc2U2NHN0cmVhbSAhPSBudWxsKSB7CisJCSAgICBiYXNlNjRzdHJlYW0uZmx1c2goKTsKKwkJfQorCQkKKwkJaWYgKGN1cnJlbnQgPT0gJyYnKSB7CisJCSAgICBjaGFuZ2VkU3RyaW5nID0gdHJ1ZTsKKwkJICAgIHdyaXRlci53cml0ZSgnJicpOworCQkgICAgd3JpdGVyLndyaXRlKCctJyk7CisJCX0gZWxzZSB7CisJCSAgICB3cml0ZXIud3JpdGUoY3VycmVudCk7CisJCX0KKwkgICAgfSBlbHNlIHsKKworCQkvLyB1c2UgYSBCNjRNYWlsYm94RW5jb2RlciB0byB3cml0ZSBvdXQgdGhlIG90aGVyIGJ5dGVzCisJCS8vIGFzIGEgbW9kaWZpZWQgQkFTRTY0LiAgVGhlIHN0cmVhbSB3aWxsIHdyaXRlIG91dAorCQkvLyB0aGUgYmVnaW5uaW5nICcmJyBhbmQgdGhlIGVuZGluZyAnLScgd2hpY2ggaXMgcGFydAorCQkvLyBvZiBldmVyeSBlbmNvZGluZy4KKworCQlpZiAoYmFzZTY0c3RyZWFtID09IG51bGwpIHsKKwkJICAgIGJhc2U2NHN0cmVhbSA9IG5ldyBCQVNFNjRNYWlsYm94RW5jb2Rlcih3cml0ZXIpOworCQkgICAgY2hhbmdlZFN0cmluZyA9IHRydWU7CisJCX0KKwkJCisJCWJhc2U2NHN0cmVhbS53cml0ZShjdXJyZW50KTsKKwkgICAgfQorCX0KKworCisJaWYgKGJhc2U2NHN0cmVhbSAhPSBudWxsKSB7CisJICAgIGJhc2U2NHN0cmVhbS5mbHVzaCgpOworCX0KKworCWlmIChjaGFuZ2VkU3RyaW5nKSB7CisJICAgIHJldHVybiB3cml0ZXIudG9TdHJpbmcoKTsKKwl9IGVsc2UgeworCSAgICByZXR1cm4gb3JpZ2luYWw7CisJfQorICAgIH0KKworCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgQkFTRTY0IGVuY29kZXIKKyAgICAgKgorICAgICAqIEBwYXJhbQl3aGF0CXdoZXJlIHRvIHdyaXRlIHRoZSBlbmNvZGVkIG5hbWUKKyAgICAgKi8KKyAgICBwdWJsaWMgQkFTRTY0TWFpbGJveEVuY29kZXIoV3JpdGVyIHdoYXQpIHsKKwlvdXQgPSB3aGF0OworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKGludCBjKSB7CisJdHJ5IHsKKwkgICAgLy8gd3JpdGUgb3V0IHRoZSBpbml0aWFsIGNoYXJhY3RlciBpZiB0aGlzIGlzIHRoZSBmaXJzdCB0aW1lCisJICAgIGlmICghc3RhcnRlZCkgeworCQlzdGFydGVkID0gdHJ1ZTsKKwkJb3V0LndyaXRlKCcmJyk7CisJICAgIH0KKwkKKwkgICAgLy8gd2Ugd3JpdGUgZWFjaCBjaGFyYWN0ZXIgYXMgYSAyIGJ5dGUgdW5pY29kZSBjaGFyYWN0ZXIKKwkgICAgYnVmZmVyW2J1ZnNpemUrK10gPSAoYnl0ZSkgKGMgPj4gOCk7CisJICAgIGJ1ZmZlcltidWZzaXplKytdID0gKGJ5dGUpIChjICYgMHhmZik7CisKKwkgICAgaWYgKGJ1ZnNpemUgPj0gMykgeworCQllbmNvZGUoKTsKKwkJYnVmc2l6ZSAtPSAzOworCSAgICB9CisJfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworCSAgICAvL2UucHJpbnRTdGFja1RyYWNlKCk7CisJfQorICAgIH0KKyAgICAKKworICAgIHB1YmxpYyB2b2lkIGZsdXNoKCkgeworCXRyeSB7CisJICAgIC8vIGZsdXNoIGFueSBieXRlcyB3ZSBoYXZlCisJICAgIGlmIChidWZzaXplID4gMCkgeworCQllbmNvZGUoKTsKKwkJYnVmc2l6ZSA9IDA7CisJICAgIH0KKworCSAgICAvLyB3cml0ZSB0aGUgdGVybWluYXRpbmcgY2hhcmFjdGVyIG9mIHRoZSBlbmNvZGluZworCSAgICBpZiAoc3RhcnRlZCkgeworCQlvdXQud3JpdGUoJy0nKTsKKwkJc3RhcnRlZCA9IGZhbHNlOworCSAgICB9CisJfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworCSAgICAvL2UucHJpbnRTdGFja1RyYWNlKCk7CisJfQorICAgIH0KKworCisgICAgcHJvdGVjdGVkIHZvaWQgZW5jb2RlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlieXRlIGEsIGIsIGM7CisJaWYgKGJ1ZnNpemUgPT0gMSkgeworCSAgICBhID0gYnVmZmVyWzBdOworCSAgICBiID0gMDsKKwkgICAgYyA9IDA7CisJICAgIG91dC53cml0ZShwZW1fYXJyYXlbKGEgPj4+IDIpICYgMHgzRl0pOworCSAgICBvdXQud3JpdGUocGVtX2FycmF5WygoYSA8PCA0KSAmIDB4MzApICsgKChiID4+PiA0KSAmIDB4ZildKTsKKwkJLy8gbm8gcGFkZGluZyBjaGFyYWN0ZXJzIGFyZSB3cml0dGVuCisJfSBlbHNlIGlmIChidWZzaXplID09IDIpIHsKKwkgICAgYSA9IGJ1ZmZlclswXTsKKwkgICAgYiA9IGJ1ZmZlclsxXTsKKwkgICAgYyA9IDA7CisJICAgIG91dC53cml0ZShwZW1fYXJyYXlbKGEgPj4+IDIpICYgMHgzRl0pOworCSAgICBvdXQud3JpdGUocGVtX2FycmF5WygoYSA8PCA0KSAmIDB4MzApICsgKChiID4+PiA0KSAmIDB4ZildKTsKKwkgICAgb3V0LndyaXRlKHBlbV9hcnJheVsoKGIgPDwgMikgJiAweDNjKSArICgoYyA+Pj4gNikgJiAweDMpXSk7CisJCS8vIG5vIHBhZGRpbmcgY2hhcmFjdGVycyBhcmUgd3JpdHRlbgorCX0gZWxzZSB7CisJICAgIGEgPSBidWZmZXJbMF07CisJICAgIGIgPSBidWZmZXJbMV07CisJICAgIGMgPSBidWZmZXJbMl07CisJICAgIG91dC53cml0ZShwZW1fYXJyYXlbKGEgPj4+IDIpICYgMHgzRl0pOworCSAgICBvdXQud3JpdGUocGVtX2FycmF5WygoYSA8PCA0KSAmIDB4MzApICsgKChiID4+PiA0KSAmIDB4ZildKTsKKwkgICAgb3V0LndyaXRlKHBlbV9hcnJheVsoKGIgPDwgMikgJiAweDNjKSArICgoYyA+Pj4gNikgJiAweDMpXSk7CisJICAgIG91dC53cml0ZShwZW1fYXJyYXlbYyAmIDB4M0ZdKTsKKworCSAgICAvLyBjb3B5IGJhY2sgdGhlIGV4dHJhIGJ5dGUKKwkgICAgaWYgKGJ1ZnNpemUgPT0gNCkKKwkJYnVmZmVyWzBdID0gYnVmZmVyWzNdOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgY2hhciBwZW1fYXJyYXlbXSA9IHsKKwknQScsJ0InLCdDJywnRCcsJ0UnLCdGJywnRycsJ0gnLCAvLyAwCisJJ0knLCdKJywnSycsJ0wnLCdNJywnTicsJ08nLCdQJywgLy8gMQorCSdRJywnUicsJ1MnLCdUJywnVScsJ1YnLCdXJywnWCcsIC8vIDIKKwknWScsJ1onLCdhJywnYicsJ2MnLCdkJywnZScsJ2YnLCAvLyAzCisJJ2cnLCdoJywnaScsJ2onLCdrJywnbCcsJ20nLCduJywgLy8gNAorCSdvJywncCcsJ3EnLCdyJywncycsJ3QnLCd1JywndicsIC8vIDUKKwkndycsJ3gnLCd5JywneicsJzAnLCcxJywnMicsJzMnLCAvLyA2CisJJzQnLCc1JywnNicsJzcnLCc4JywnOScsJysnLCcsJyAgLy8gNworICAgIH07Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvcHJvdG9jb2wvQk9EWS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL3Byb3RvY29sL0JPRFkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hYmFlZDYxCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL3Byb3RvY29sL0JPRFkuamF2YQpAQCAtMCwwICsxLDg3IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5pbWFwLnByb3RvY29sOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBjb20uc3VuLm1haWwuaWFwLio7CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuQVNDSUlVdGlsaXR5OworCisvKioKKyAqIFRoZSBCT0RZIGZldGNoIHJlc3BvbnNlIGl0ZW0uCisgKgorICogQGF1dGhvciAgSm9obiBNYW5pCisgKiBAYXV0aG9yICBCaWxsIFNoYW5ub24KKyAqLworCitwdWJsaWMgY2xhc3MgQk9EWSBpbXBsZW1lbnRzIEl0ZW0geworICAgIAorICAgIHN0YXRpYyBmaW5hbCBjaGFyW10gbmFtZSA9IHsnQicsJ08nLCdEJywnWSd9OworCisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgbXNnbm87CisgICAgcHJpdmF0ZSBmaW5hbCBCeXRlQXJyYXkgZGF0YTsKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBzZWN0aW9uOworICAgIHByaXZhdGUgZmluYWwgaW50IG9yaWdpbjsKKyAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gaXNIZWFkZXI7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvcgorICAgICAqCisgICAgICogQHBhcmFtCXIJdGhlIEZldGNoUmVzcG9uc2UKKyAgICAgKiBAZXhjZXB0aW9uCVBhcnNpbmdFeGNlcHRpb24JZm9yIHBhcnNpbmcgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgQk9EWShGZXRjaFJlc3BvbnNlIHIpIHRocm93cyBQYXJzaW5nRXhjZXB0aW9uIHsKKwltc2dubyA9IHIuZ2V0TnVtYmVyKCk7CisKKwlyLnNraXBTcGFjZXMoKTsKKworCWlmIChyLnJlYWRCeXRlKCkgIT0gJ1snKQorCSAgICB0aHJvdyBuZXcgUGFyc2luZ0V4Y2VwdGlvbigKKwkJICAgICJCT0RZIHBhcnNlIGVycm9yOiBtaXNzaW5nIGBgWycnIGF0IHNlY3Rpb24gc3RhcnQiKTsKKwlzZWN0aW9uID0gci5yZWFkU3RyaW5nKCddJyk7CisJaWYgKHIucmVhZEJ5dGUoKSAhPSAnXScpCisJICAgIHRocm93IG5ldyBQYXJzaW5nRXhjZXB0aW9uKAorCQkgICAgIkJPRFkgcGFyc2UgZXJyb3I6IG1pc3NpbmcgYGBdJycgYXQgc2VjdGlvbiBlbmQiKTsKKwlpc0hlYWRlciA9IHNlY3Rpb24ucmVnaW9uTWF0Y2hlcyh0cnVlLCAwLCAiSEVBREVSIiwgMCwgNik7CisKKwlpZiAoci5yZWFkQnl0ZSgpID09ICc8JykgeyAvLyBvcmlnaW4KKwkgICAgb3JpZ2luID0gci5yZWFkTnVtYmVyKCk7CisJICAgIHIuc2tpcCgxKTsgLy8gc2tpcCAnPic7CisJfSBlbHNlCisJICAgIG9yaWdpbiA9IDA7CisKKwlkYXRhID0gci5yZWFkQnl0ZUFycmF5KCk7CisgICAgfQorCisgICAgcHVibGljIEJ5dGVBcnJheSBnZXRCeXRlQXJyYXkoKSB7CisJcmV0dXJuIGRhdGE7CisgICAgfQorCisgICAgcHVibGljIEJ5dGVBcnJheUlucHV0U3RyZWFtIGdldEJ5dGVBcnJheUlucHV0U3RyZWFtKCkgeworCWlmIChkYXRhICE9IG51bGwpCisJICAgIHJldHVybiBkYXRhLnRvQnl0ZUFycmF5SW5wdXRTdHJlYW0oKTsKKwllbHNlCisJICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGlzSGVhZGVyKCkgeworCXJldHVybiBpc0hlYWRlcjsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldFNlY3Rpb24oKSB7CisJcmV0dXJuIHNlY3Rpb247CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL3Byb3RvY29sL0JPRFlTVFJVQ1RVUkUuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9CT0RZU1RSVUNUVVJFLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2E1OTQ1YwotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9CT0RZU1RSVUNUVVJFLmphdmEKQEAgLTAsMCArMSw0NTAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmltYXAucHJvdG9jb2w7CisKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuUGFyYW1ldGVyTGlzdDsKK2ltcG9ydCBjb20uc3VuLm1haWwuaWFwLio7IAoraW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLlByb3BVdGlsOworCisvKioKKyAqIEEgQk9EWVNUUlVDVFVSRSByZXNwb25zZS4KKyAqCisgKiBAYXV0aG9yICBKb2huIE1hbmkKKyAqIEBhdXRob3IgIEJpbGwgU2hhbm5vbgorICovCisKK3B1YmxpYyBjbGFzcyBCT0RZU1RSVUNUVVJFIGltcGxlbWVudHMgSXRlbSB7CisgICAgCisgICAgc3RhdGljIGZpbmFsIGNoYXJbXSBuYW1lID0KKwl7J0InLCdPJywnRCcsJ1knLCdTJywnVCcsJ1InLCdVJywnQycsJ1QnLCdVJywnUicsJ0UnfTsKKyAgICBwdWJsaWMgaW50IG1zZ25vOworCisgICAgcHVibGljIFN0cmluZyB0eXBlOwkJLy8gVHlwZQorICAgIHB1YmxpYyBTdHJpbmcgc3VidHlwZTsJLy8gU3VidHlwZQorICAgIHB1YmxpYyBTdHJpbmcgZW5jb2Rpbmc7CS8vIEVuY29kaW5nCisgICAgcHVibGljIGludCBsaW5lcyA9IC0xOwkvLyBTaXplIGluIGxpbmVzCisgICAgcHVibGljIGludCBzaXplID0gLTE7CS8vIFNpemUgaW4gYnl0ZXMKKyAgICBwdWJsaWMgU3RyaW5nIGRpc3Bvc2l0aW9uOwkvLyBEaXNwb3NpdGlvbgorICAgIHB1YmxpYyBTdHJpbmcgaWQ7CQkvLyBDb250ZW50LUlECisgICAgcHVibGljIFN0cmluZyBkZXNjcmlwdGlvbjsJLy8gQ29udGVudC1EZXNjcmlwdGlvbgorICAgIHB1YmxpYyBTdHJpbmcgbWQ1OwkJLy8gTUQtNSBjaGVja3N1bQorICAgIHB1YmxpYyBTdHJpbmcgYXR0YWNobWVudDsJLy8gQXR0YWNobWVudCBuYW1lCisgICAgcHVibGljIFBhcmFtZXRlckxpc3QgY1BhcmFtczsgLy8gQm9keSBwYXJhbWV0ZXJzCisgICAgcHVibGljIFBhcmFtZXRlckxpc3QgZFBhcmFtczsgLy8gRGlzcG9zaXRpb24gcGFyYW1ldGVycworICAgIHB1YmxpYyBTdHJpbmdbXSBsYW5ndWFnZTsJLy8gTGFuZ3VhZ2UKKyAgICBwdWJsaWMgQk9EWVNUUlVDVFVSRVtdIGJvZGllczsgLy8gYXJyYXkgb2YgQk9EWVNUUlVDVFVSRSBvYmplY3RzCisJCQkJICAgLy8gIGZvciBtdWx0aXBhcnQgJiBtZXNzYWdlL3JmYzgyMgorICAgIHB1YmxpYyBFTlZFTE9QRSBlbnZlbG9wZTsJLy8gZm9yIG1lc3NhZ2UvcmZjODIyCisKKyAgICBwcml2YXRlIHN0YXRpYyBpbnQgU0lOR0xFCT0gMTsKKyAgICBwcml2YXRlIHN0YXRpYyBpbnQgTVVMVEkJPSAyOworICAgIHByaXZhdGUgc3RhdGljIGludCBORVNURUQJPSAzOworICAgIHByaXZhdGUgaW50IHByb2Nlc3NlZFR5cGU7CS8vIE1VTFRJIHwgU0lOR0xFIHwgTkVTVEVECisKKyAgICAvLyBzcGVjaWFsIGRlYnVnZ2luZyBvdXRwdXQgdG8gZGVidWcgcGFyc2luZyBlcnJvcnMKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIHBhcnNlRGVidWcgPQorCVByb3BVdGlsLmdldEJvb2xlYW5TeXN0ZW1Qcm9wZXJ0eSgibWFpbC5pbWFwLnBhcnNlLmRlYnVnIiwgZmFsc2UpOworCisKKyAgICBwdWJsaWMgQk9EWVNUUlVDVFVSRShGZXRjaFJlc3BvbnNlIHIpIHRocm93cyBQYXJzaW5nRXhjZXB0aW9uIHsKKwlpZiAocGFyc2VEZWJ1ZykKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJERUJVRyBJTUFQOiBwYXJzaW5nIEJPRFlTVFJVQ1RVUkUiKTsKKwltc2dubyA9IHIuZ2V0TnVtYmVyKCk7CisJaWYgKHBhcnNlRGVidWcpCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiREVCVUcgSU1BUDogbXNnbm8gIiArIG1zZ25vKTsKKworCXIuc2tpcFNwYWNlcygpOworCisJaWYgKHIucmVhZEJ5dGUoKSAhPSAnKCcpCisJICAgIHRocm93IG5ldyBQYXJzaW5nRXhjZXB0aW9uKAorCQkiQk9EWVNUUlVDVFVSRSBwYXJzZSBlcnJvcjogbWlzc2luZyBgYCgnJyBhdCBzdGFydCIpOworCisJaWYgKHIucGVla0J5dGUoKSA9PSAnKCcpIHsgLy8gbXVsdGlwYXJ0CisJICAgIGlmIChwYXJzZURlYnVnKQorCQlTeXN0ZW0ub3V0LnByaW50bG4oIkRFQlVHIElNQVA6IHBhcnNpbmcgbXVsdGlwYXJ0Iik7CisJICAgIHR5cGUgPSAibXVsdGlwYXJ0IjsKKwkgICAgcHJvY2Vzc2VkVHlwZSA9IE1VTFRJOworCSAgICBMaXN0PEJPRFlTVFJVQ1RVUkU+IHYgPSBuZXcgQXJyYXlMaXN0PD4oMSk7CisJICAgIGludCBpID0gMTsKKwkgICAgZG8geworCQl2LmFkZChuZXcgQk9EWVNUUlVDVFVSRShyKSk7CisJCS8qCisJCSAqIEV2ZW4gdGhvdWdoIHRoZSBJTUFQIHNwZWMgc2F5cyB0aGVyZSBjYW4ndCBiZSBhbnkgc3BhY2VzCisJCSAqIGJldHdlZW4gcGFydHMsIHNvbWUgc2VydmVycyBlcnJvbmVvdXNseSBwdXQgYSBzcGFjZSBpbgorCQkgKiBoZXJlLiAgSW4gdGhlIHNwaXJpdCBvZiAiYmUgbGliZXJhbCBpbiB3aGF0IHlvdSBhY2NlcHQiLAorCQkgKiB3ZSBza2lwIGl0LgorCQkgKi8KKwkJci5za2lwU3BhY2VzKCk7CisJICAgIH0gd2hpbGUgKHIucGVla0J5dGUoKSA9PSAnKCcpOworCisJICAgIC8vIHNldHVwIGJvZGllcy4KKwkgICAgYm9kaWVzID0gdi50b0FycmF5KG5ldyBCT0RZU1RSVUNUVVJFW3Yuc2l6ZSgpXSk7CisKKwkgICAgc3VidHlwZSA9IHIucmVhZFN0cmluZygpOyAvLyBzdWJ0eXBlCisJICAgIGlmIChwYXJzZURlYnVnKQorCQlTeXN0ZW0ub3V0LnByaW50bG4oIkRFQlVHIElNQVA6IHN1YnR5cGUgIiArIHN1YnR5cGUpOworCisJICAgIGlmIChyLmlzTmV4dE5vblNwYWNlKCcpJykpIHsgLy8gZG9uZQorCQlpZiAocGFyc2VEZWJ1ZykKKwkJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiREVCVUcgSU1BUDogcGFyc2UgRE9ORSIpOworCQlyZXR1cm47CisJICAgIH0KKworCSAgICAvLyBFbHNlLCB3ZSBoYXZlIGV4dGVuc2lvbiBkYXRhCisKKwkgICAgaWYgKHBhcnNlRGVidWcpCisJCVN5c3RlbS5vdXQucHJpbnRsbigiREVCVUcgSU1BUDogcGFyc2luZyBleHRlbnNpb24gZGF0YSIpOworCSAgICAvLyBCb2R5IHBhcmFtZXRlcnMKKwkgICAgY1BhcmFtcyA9IHBhcnNlUGFyYW1ldGVycyhyKTsKKwkgICAgaWYgKHIuaXNOZXh0Tm9uU3BhY2UoJyknKSkgeyAvLyBkb25lCisJCWlmIChwYXJzZURlYnVnKQorCQkgICAgU3lzdGVtLm91dC5wcmludGxuKCJERUJVRyBJTUFQOiBib2R5IHBhcmFtZXRlcnMgRE9ORSIpOworCQlyZXR1cm47CisJICAgIH0KKwkgICAgCisJICAgIC8vIERpc3Bvc2l0aW9uCisJICAgIGJ5dGUgYiA9IHIucGVla0J5dGUoKTsKKwkgICAgaWYgKGIgPT0gJygnKSB7CisJCWlmIChwYXJzZURlYnVnKQorCQkgICAgU3lzdGVtLm91dC5wcmludGxuKCJERUJVRyBJTUFQOiBwYXJzZSBkaXNwb3NpdGlvbiIpOworCQlyLnJlYWRCeXRlKCk7CisJCWRpc3Bvc2l0aW9uID0gci5yZWFkU3RyaW5nKCk7CisJCWlmIChwYXJzZURlYnVnKQorCQkgICAgU3lzdGVtLm91dC5wcmludGxuKCJERUJVRyBJTUFQOiBkaXNwb3NpdGlvbiAiICsKKwkJCQkJCQlkaXNwb3NpdGlvbik7CisJCWRQYXJhbXMgPSBwYXJzZVBhcmFtZXRlcnMocik7CisJCWlmICghci5pc05leHROb25TcGFjZSgnKScpKSAvLyBlYXQgdGhlIGVuZCAnKScKKwkJICAgIHRocm93IG5ldyBQYXJzaW5nRXhjZXB0aW9uKAorCQkJIkJPRFlTVFJVQ1RVUkUgcGFyc2UgZXJyb3I6ICIgKworCQkJIm1pc3NpbmcgYGApJycgYXQgZW5kIG9mIGRpc3Bvc2l0aW9uIGluIG11bHRpcGFydCIpOworCQlpZiAocGFyc2VEZWJ1ZykKKwkJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiREVCVUcgSU1BUDogZGlzcG9zaXRpb24gRE9ORSIpOworCSAgICB9IGVsc2UgaWYgKGIgPT0gJ04nIHx8IGIgPT0gJ24nKSB7CisJCWlmIChwYXJzZURlYnVnKQorCQkgICAgU3lzdGVtLm91dC5wcmludGxuKCJERUJVRyBJTUFQOiBkaXNwb3NpdGlvbiBOSUwiKTsKKwkJci5za2lwKDMpOyAvLyBza2lwICdOSUwnCisJICAgIH0gZWxzZSB7CisJCS8qCisJCXRocm93IG5ldyBQYXJzaW5nRXhjZXB0aW9uKAorCQkgICAgIkJPRFlTVFJVQ1RVUkUgcGFyc2UgZXJyb3I6ICIgKworCQkgICAgdHlwZSArICIvIiArIHN1YnR5cGUgKyAiOiAiICsKKwkJICAgICJiYWQgbXVsdGlwYXJ0IGRpc3Bvc2l0aW9uLCBiICIgKyBiKTsKKwkJKi8KKwkJaWYgKHBhcnNlRGVidWcpCisJCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkRFQlVHIElNQVA6IGJhZCBtdWx0aXBhcnQgZGlzcG9zaXRpb24iICsKKwkJCQkJIiwgYXBwbHlpbmcgRXhjaGFuZ2UgYnVnIHdvcmthcm91bmQiKTsKKwkJZGVzY3JpcHRpb24gPSByLnJlYWRTdHJpbmcoKTsKKwkJaWYgKHBhcnNlRGVidWcpCisJCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkRFQlVHIElNQVA6IG11bHRpcGFydCBkZXNjcmlwdGlvbiAiICsKKwkJCQkJZGVzY3JpcHRpb24pOworCQkvLyBUaHJvdyBhd2F5IHdoYXRldmVyIGNvbWVzIGFmdGVyIGl0LCBzaW5jZSB3ZSBoYXZlIG5vCisJCS8vIGlkZWEgd2hhdCBpdCdzIHN1cHBvc2VkIHRvIGJlCisJCXdoaWxlIChyLnJlYWRCeXRlKCkgPT0gJyAnKQorCQkgICAgcGFyc2VCb2R5RXh0ZW5zaW9uKHIpOworCQlyZXR1cm47CisJICAgIH0KKworCSAgICAvLyBSRkMzNTAxIGFsbG93cyBubyBib2R5LWZsZC1sYW5nIGFmdGVyIGJvZHktZmxkLWRpc3AsCisJICAgIC8vIGV2ZW4gdGhvdWdoIFJGQzIwNjAgcmVxdWlyZWQgaXQKKwkgICAgaWYgKHIuaXNOZXh0Tm9uU3BhY2UoJyknKSkgeworCQlpZiAocGFyc2VEZWJ1ZykKKwkJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiREVCVUcgSU1BUDogbm8gYm9keS1mbGQtbGFuZyIpOworCQlyZXR1cm47IC8vIGRvbmUKKwkgICAgfQorCisJICAgIC8vIExhbmd1YWdlCisJICAgIGlmIChyLnBlZWtCeXRlKCkgPT0gJygnKSB7IC8vIGEgbGlzdCBmb2xsb3dzCisJCWxhbmd1YWdlID0gci5yZWFkU3RyaW5nTGlzdCgpOworCQlpZiAocGFyc2VEZWJ1ZykKKwkJICAgIFN5c3RlbS5vdXQucHJpbnRsbigKKwkJCSJERUJVRyBJTUFQOiBsYW5ndWFnZSBsZW4gIiArIGxhbmd1YWdlLmxlbmd0aCk7CisJICAgIH0gZWxzZSB7CisJCVN0cmluZyBsID0gci5yZWFkU3RyaW5nKCk7CisJCWlmIChsICE9IG51bGwpIHsKKwkJICAgIFN0cmluZ1tdIGxhID0geyBsIH07CisJCSAgICBsYW5ndWFnZSA9IGxhOworCQkgICAgaWYgKHBhcnNlRGVidWcpCisJCQlTeXN0ZW0ub3V0LnByaW50bG4oIkRFQlVHIElNQVA6IGxhbmd1YWdlICIgKyBsKTsKKwkJfQorCSAgICB9CisKKwkgICAgLy8gUkZDMzUwMSBkZWZpbmVzIGFuIG9wdGlvbmFsICJib2R5IGxvY2F0aW9uIiBuZXh0LAorCSAgICAvLyBidXQgZm9yIG5vdyB3ZSBpZ25vcmUgaXQgYWxvbmcgd2l0aCBvdGhlciBleHRlbnNpb25zLgorCisJICAgIC8vIFRocm93IGF3YXkgYW55IGZ1cnRoZXIgZXh0ZW5zaW9uIGRhdGEKKwkgICAgd2hpbGUgKHIucmVhZEJ5dGUoKSA9PSAnICcpCisJCXBhcnNlQm9keUV4dGVuc2lvbihyKTsKKwl9IGVsc2UgaWYgKHIucGVla0J5dGUoKSA9PSAnKScpIHsJLy8gKGlsbGVnYWwpIGVtcHR5IGJvZHkKKwkgICAgLyoKKwkgICAgICogRG9taW5vIHdpbGwgZmFpbCB0byByZXR1cm4gdGhlIGJvZHkgc3RydWN0dXJlIG9mIG5lc3RlZCBtZXNzYWdlcy4KKwkgICAgICogRmFrZSBpdCBieSBwcm92aWRpbmcgYW4gZW1wdHkgbWVzc2FnZS4gIENvdWxkIHByb2JhYmx5IGRvIGJldHRlcgorCSAgICAgKiB3aXRoIG1vcmUgd29yay4uLgorCSAgICAgKi8KKwkgICAgLyoKKwkgICAgICogWFhYIC0gdGhpcyBwcmV2ZW50cyB0aGUgZXhjZXB0aW9uLCBidXQgd2l0aG91dCB0aGUgZXhjZXB0aW9uCisJICAgICAqIHRoZSBhcHBsaWNhdGlvbiBoYXMgbm8gd2F5IHRvIGtub3cgdGhlIGRhdGEgZnJvbSB0aGUgbWVzc2FnZQorCSAgICAgKiBpcyBtaXNzaW5nLgorCSAgICAgKgorCSAgICBpZiAocGFyc2VEZWJ1ZykKKwkJU3lzdGVtLm91dC5wcmludGxuKCJERUJVRyBJTUFQOiBlbXB0eSBib2R5LCBmYWtlIGl0Iik7CisJICAgIHIucmVhZEJ5dGUoKTsKKwkgICAgdHlwZSA9ICJ0ZXh0IjsKKwkgICAgc3VidHlwZSA9ICJwbGFpbiI7CisJICAgIGxpbmVzID0gMDsKKwkgICAgc2l6ZSA9IDA7CisJICAgICAqLworCSAgICB0aHJvdyBuZXcgUGFyc2luZ0V4Y2VwdGlvbigKKwkJCSAgICAiQk9EWVNUUlVDVFVSRSBwYXJzZSBlcnJvcjogbWlzc2luZyBib2R5IGNvbnRlbnQiKTsKKwl9IGVsc2UgeyAvLyBTaW5nbGUgcGFydAorCSAgICBpZiAocGFyc2VEZWJ1ZykKKwkJU3lzdGVtLm91dC5wcmludGxuKCJERUJVRyBJTUFQOiBzaW5nbGUgcGFydCIpOworCSAgICB0eXBlID0gci5yZWFkU3RyaW5nKCk7CisJICAgIGlmIChwYXJzZURlYnVnKQorCQlTeXN0ZW0ub3V0LnByaW50bG4oIkRFQlVHIElNQVA6IHR5cGUgIiArIHR5cGUpOworCSAgICBwcm9jZXNzZWRUeXBlID0gU0lOR0xFOworCSAgICBzdWJ0eXBlID0gci5yZWFkU3RyaW5nKCk7CisJICAgIGlmIChwYXJzZURlYnVnKQorCQlTeXN0ZW0ub3V0LnByaW50bG4oIkRFQlVHIElNQVA6IHN1YnR5cGUgIiArIHN1YnR5cGUpOworCisJICAgIC8vIFNJTVMgNC4wIHJldHVybnMgTklMIGZvciBhIENvbnRlbnQtVHlwZSBvZiAiYmluYXJ5IiwgZml4IGl0IGhlcmUKKwkgICAgaWYgKHR5cGUgPT0gbnVsbCkgeworCQl0eXBlID0gImFwcGxpY2F0aW9uIjsKKwkJc3VidHlwZSA9ICJvY3RldC1zdHJlYW0iOworCSAgICB9CisJICAgIGNQYXJhbXMgPSBwYXJzZVBhcmFtZXRlcnMocik7CisJICAgIGlmIChwYXJzZURlYnVnKQorCQlTeXN0ZW0ub3V0LnByaW50bG4oIkRFQlVHIElNQVA6IGNQYXJhbXMgIiArIGNQYXJhbXMpOworCSAgICBpZCA9IHIucmVhZFN0cmluZygpOworCSAgICBpZiAocGFyc2VEZWJ1ZykKKwkJU3lzdGVtLm91dC5wcmludGxuKCJERUJVRyBJTUFQOiBpZCAiICsgaWQpOworCSAgICBkZXNjcmlwdGlvbiA9IHIucmVhZFN0cmluZygpOworCSAgICBpZiAocGFyc2VEZWJ1ZykKKwkJU3lzdGVtLm91dC5wcmludGxuKCJERUJVRyBJTUFQOiBkZXNjcmlwdGlvbiAiICsgZGVzY3JpcHRpb24pOworCSAgICAvKgorCSAgICAgKiBYWFggLSBXb3JrIGFyb3VuZCBidWcgaW4gRXhjaGFuZ2UgMjAxMCB0aGF0CisJICAgICAqICAgICAgIHJldHVybnMgdW5xdW90ZWQgc3RyaW5nLgorCSAgICAgKi8KKwkgICAgZW5jb2RpbmcgPSByLnJlYWRBdG9tU3RyaW5nKCk7CisJICAgIGlmIChlbmNvZGluZyAhPSBudWxsICYmIGVuY29kaW5nLmVxdWFsc0lnbm9yZUNhc2UoIk5JTCIpKSB7CisJCWlmIChwYXJzZURlYnVnKQorCQkgICAgU3lzdGVtLm91dC5wcmludGxuKCJERUJVRyBJTUFQOiBOSUwgZW5jb2RpbmciICsKKwkJCQkJIiwgYXBwbHlpbmcgRXhjaGFuZ2UgYnVnIHdvcmthcm91bmQiKTsKKwkJZW5jb2RpbmcgPSBudWxsOworCSAgICB9CisJICAgIC8qCisJICAgICAqIFhYWCAtIFdvcmsgYXJvdW5kIGJ1ZyBpbiBvZmZpY2UzNjUuY29tIHRoYXQgcmV0dXJucworCSAgICAgKgkgICAgIGEgc3RyaW5nIHdpdGggYSB0cmFpbGluZyBzcGFjZSBpbiBzb21lIGNhc2VzLgorCSAgICAgKi8KKwkgICAgaWYgKGVuY29kaW5nICE9IG51bGwpCisJCWVuY29kaW5nID0gZW5jb2RpbmcudHJpbSgpOworCSAgICBpZiAocGFyc2VEZWJ1ZykKKwkJU3lzdGVtLm91dC5wcmludGxuKCJERUJVRyBJTUFQOiBlbmNvZGluZyAiICsgZW5jb2RpbmcpOworCSAgICBzaXplID0gci5yZWFkTnVtYmVyKCk7CisJICAgIGlmIChwYXJzZURlYnVnKQorCQlTeXN0ZW0ub3V0LnByaW50bG4oIkRFQlVHIElNQVA6IHNpemUgIiArIHNpemUpOworCSAgICBpZiAoc2l6ZSA8IDApCisJCXRocm93IG5ldyBQYXJzaW5nRXhjZXB0aW9uKAorCQkJICAgICJCT0RZU1RSVUNUVVJFIHBhcnNlIGVycm9yOiBiYWQgYGBzaXplJycgZWxlbWVudCIpOworCisJICAgIC8vICJ0ZXh0LyoiICYgIm1lc3NhZ2UvcmZjODIyIiB0eXBlcyBoYXZlIGFkZGl0aW9uYWwgZGF0YSAuLgorCSAgICBpZiAodHlwZS5lcXVhbHNJZ25vcmVDYXNlKCJ0ZXh0IikpIHsKKwkJbGluZXMgPSByLnJlYWROdW1iZXIoKTsKKwkJaWYgKHBhcnNlRGVidWcpCisJCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkRFQlVHIElNQVA6IGxpbmVzICIgKyBsaW5lcyk7CisJCWlmIChsaW5lcyA8IDApCisJCSAgICB0aHJvdyBuZXcgUGFyc2luZ0V4Y2VwdGlvbigKKwkJCSAgICAiQk9EWVNUUlVDVFVSRSBwYXJzZSBlcnJvcjogYmFkIGBgbGluZXMnJyBlbGVtZW50Iik7CisJICAgIH0gZWxzZSBpZiAodHlwZS5lcXVhbHNJZ25vcmVDYXNlKCJtZXNzYWdlIikgJiYKKwkJICAgICBzdWJ0eXBlLmVxdWFsc0lnbm9yZUNhc2UoInJmYzgyMiIpKSB7CisJCS8vIE5lc3RlZCBtZXNzYWdlCisJCXByb2Nlc3NlZFR5cGUgPSBORVNURUQ7CisJCS8vIFRoZSBlbnZlbG9wZSBjb21lcyBuZXh0LCBidXQgc2FkbHkgR21haWwgaGFuZGxlcyBuZXN0ZWQKKwkJLy8gbWVzc2FnZXMganVzdCBsaWtlIHNpbXBsZSBib2R5IHBhcnRzIGFuZCBmYWlscyB0byByZXR1cm4KKwkJLy8gdGhlIGVudmVsb3BlIGFuZCBib2R5IHN0cnVjdHVyZSBvZiB0aGUgbWVzc2FnZSAoc29ydCBvZgorCQkvLyBsaWtlIElNQVA0IGJlZm9yZSByZXYxKS4KKwkJci5za2lwU3BhY2VzKCk7CisJCWlmIChyLnBlZWtCeXRlKCkgPT0gJygnKSB7CS8vIHRoZSBlbnZlbG9wZSBmb2xsb3dzCisJCSAgICBlbnZlbG9wZSA9IG5ldyBFTlZFTE9QRShyKTsKKwkJICAgIGlmIChwYXJzZURlYnVnKQorCQkJU3lzdGVtLm91dC5wcmludGxuKAorCQkJICAgICJERUJVRyBJTUFQOiBnb3QgZW52ZWxvcGUgb2YgbmVzdGVkIG1lc3NhZ2UiKTsKKwkJICAgIEJPRFlTVFJVQ1RVUkVbXSBicyA9IHsgbmV3IEJPRFlTVFJVQ1RVUkUocikgfTsKKwkJICAgIGJvZGllcyA9IGJzOworCQkgICAgbGluZXMgPSByLnJlYWROdW1iZXIoKTsKKwkJICAgIGlmIChwYXJzZURlYnVnKQorCQkJU3lzdGVtLm91dC5wcmludGxuKCJERUJVRyBJTUFQOiBsaW5lcyAiICsgbGluZXMpOworCQkgICAgaWYgKGxpbmVzIDwgMCkKKwkJCXRocm93IG5ldyBQYXJzaW5nRXhjZXB0aW9uKAorCQkJICAgICJCT0RZU1RSVUNUVVJFIHBhcnNlIGVycm9yOiBiYWQgYGBsaW5lcycnIGVsZW1lbnQiKTsKKwkJfSBlbHNlIHsKKwkJICAgIGlmIChwYXJzZURlYnVnKQorCQkJU3lzdGVtLm91dC5wcmludGxuKCJERUJVRyBJTUFQOiAiICsKKwkJCSAgICAibWlzc2luZyBlbnZlbG9wZSBhbmQgYm9keSBvZiBuZXN0ZWQgbWVzc2FnZSIpOworCQl9CisJICAgIH0gZWxzZSB7CisJCS8vIERldGVjdCBjb21tb24gZXJyb3Igb2YgaW5jbHVkaW5nIGxpbmVzIGVsZW1lbnQgb24gb3RoZXIgdHlwZXMKKwkJci5za2lwU3BhY2VzKCk7CisJCWJ5dGUgYm4gPSByLnBlZWtCeXRlKCk7CisJCWlmIChDaGFyYWN0ZXIuaXNEaWdpdCgoY2hhcilibikpIC8vIG51bWJlcgorCQkgICAgdGhyb3cgbmV3IFBhcnNpbmdFeGNlcHRpb24oCisJCQkgICAgIkJPRFlTVFJVQ1RVUkUgcGFyc2UgZXJyb3I6IHNlcnZlciBlcnJvbmVvdXNseSAiICsKKwkJCQkiaW5jbHVkZWQgYGBsaW5lcycnIGVsZW1lbnQgd2l0aCB0eXBlICIgKworCQkJCXR5cGUgKyAiLyIgKyBzdWJ0eXBlKTsKKwkgICAgfQorCisJICAgIGlmIChyLmlzTmV4dE5vblNwYWNlKCcpJykpIHsKKwkJaWYgKHBhcnNlRGVidWcpCisJCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkRFQlVHIElNQVA6IHBhcnNlIERPTkUiKTsKKwkJcmV0dXJuOyAvLyBkb25lCisJICAgIH0KKworCSAgICAvLyBPcHRpb25hbCBleHRlbnNpb24gZGF0YQorCisJICAgIC8vIE1ENQorCSAgICBtZDUgPSByLnJlYWRTdHJpbmcoKTsKKwkgICAgaWYgKHIuaXNOZXh0Tm9uU3BhY2UoJyknKSkgeworCQlpZiAocGFyc2VEZWJ1ZykKKwkJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiREVCVUcgSU1BUDogbm8gTUQ1IERPTkUiKTsKKwkJcmV0dXJuOyAvLyBkb25lCisJICAgIH0KKwkgICAgCisJICAgIC8vIERpc3Bvc2l0aW9uCisJICAgIGJ5dGUgYiA9IHIucmVhZEJ5dGUoKTsKKwkgICAgaWYgKGIgPT0gJygnKSB7CisJCWRpc3Bvc2l0aW9uID0gci5yZWFkU3RyaW5nKCk7CisJCWlmIChwYXJzZURlYnVnKQorCQkgICAgU3lzdGVtLm91dC5wcmludGxuKCJERUJVRyBJTUFQOiBkaXNwb3NpdGlvbiAiICsKKwkJCQkJCQlkaXNwb3NpdGlvbik7CisJCWRQYXJhbXMgPSBwYXJzZVBhcmFtZXRlcnMocik7CisJCWlmIChwYXJzZURlYnVnKQorCQkgICAgU3lzdGVtLm91dC5wcmludGxuKCJERUJVRyBJTUFQOiBkUGFyYW1zICIgKyBkUGFyYW1zKTsKKwkJaWYgKCFyLmlzTmV4dE5vblNwYWNlKCcpJykpIC8vIGVhdCB0aGUgZW5kICcpJworCQkgICAgdGhyb3cgbmV3IFBhcnNpbmdFeGNlcHRpb24oCisJCQkiQk9EWVNUUlVDVFVSRSBwYXJzZSBlcnJvcjogIiArCisJCQkibWlzc2luZyBgYCknJyBhdCBlbmQgb2YgZGlzcG9zaXRpb24iKTsKKwkgICAgfSBlbHNlIGlmIChiID09ICdOJyB8fCBiID09ICduJykgeworCQlpZiAocGFyc2VEZWJ1ZykKKwkJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiREVCVUcgSU1BUDogZGlzcG9zaXRpb24gTklMIik7CisJCXIuc2tpcCgyKTsgLy8gc2tpcCAnTklMJworCSAgICB9IGVsc2UgeworCQl0aHJvdyBuZXcgUGFyc2luZ0V4Y2VwdGlvbigKKwkJICAgICJCT0RZU1RSVUNUVVJFIHBhcnNlIGVycm9yOiAiICsKKwkJICAgIHR5cGUgKyAiLyIgKyBzdWJ0eXBlICsgIjogIiArCisJCSAgICAiYmFkIHNpbmdsZSBwYXJ0IGRpc3Bvc2l0aW9uLCBiICIgKyBiKTsKKwkgICAgfQorCisJICAgIGlmIChyLmlzTmV4dE5vblNwYWNlKCcpJykpIHsKKwkJaWYgKHBhcnNlRGVidWcpCisJCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkRFQlVHIElNQVA6IGRpc3Bvc2l0aW9uIERPTkUiKTsKKwkJcmV0dXJuOyAvLyBkb25lCisJICAgIH0KKwkgICAgCisJICAgIC8vIExhbmd1YWdlCisJICAgIGlmIChyLnBlZWtCeXRlKCkgPT0gJygnKSB7IC8vIGEgbGlzdCBmb2xsb3dzCisJCWxhbmd1YWdlID0gci5yZWFkU3RyaW5nTGlzdCgpOworCQlpZiAocGFyc2VEZWJ1ZykKKwkJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiREVCVUcgSU1BUDogbGFuZ3VhZ2UgbGVuICIgKworCQkJCQkJCWxhbmd1YWdlLmxlbmd0aCk7CisJICAgIH0gZWxzZSB7IC8vIHByb3RvY29sIGlzIHVubmVzc2FyaWx5IGNvbXBsZXggaGVyZQorCQlTdHJpbmcgbCA9IHIucmVhZFN0cmluZygpOworCQlpZiAobCAhPSBudWxsKSB7CisJCSAgICBTdHJpbmdbXSBsYSA9IHsgbCB9OworCQkgICAgbGFuZ3VhZ2UgPSBsYTsKKwkJICAgIGlmIChwYXJzZURlYnVnKQorCQkJU3lzdGVtLm91dC5wcmludGxuKCJERUJVRyBJTUFQOiBsYW5ndWFnZSAiICsgbCk7CisJCX0KKwkgICAgfQorCisJICAgIC8vIFJGQzM1MDEgZGVmaW5lcyBhbiBvcHRpb25hbCAiYm9keSBsb2NhdGlvbiIgbmV4dCwKKwkgICAgLy8gYnV0IGZvciBub3cgd2UgaWdub3JlIGl0IGFsb25nIHdpdGggb3RoZXIgZXh0ZW5zaW9ucy4KKworCSAgICAvLyBUaHJvdyBhd2F5IGFueSBmdXJ0aGVyIGV4dGVuc2lvbiBkYXRhCisJICAgIHdoaWxlIChyLnJlYWRCeXRlKCkgPT0gJyAnKQorCQlwYXJzZUJvZHlFeHRlbnNpb24ocik7CisJICAgIGlmIChwYXJzZURlYnVnKQorCQlTeXN0ZW0ub3V0LnByaW50bG4oIkRFQlVHIElNQVA6IGFsbCBET05FIik7CisJfQorICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGlzTXVsdGkoKSB7CisJcmV0dXJuIHByb2Nlc3NlZFR5cGUgPT0gTVVMVEk7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaXNTaW5nbGUoKSB7CisJcmV0dXJuIHByb2Nlc3NlZFR5cGUgPT0gU0lOR0xFOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGlzTmVzdGVkKCkgeworCXJldHVybiBwcm9jZXNzZWRUeXBlID09IE5FU1RFRDsKKyAgICB9CisKKyAgICBwcml2YXRlIFBhcmFtZXRlckxpc3QgcGFyc2VQYXJhbWV0ZXJzKFJlc3BvbnNlIHIpCisJCQl0aHJvd3MgUGFyc2luZ0V4Y2VwdGlvbiB7CisJci5za2lwU3BhY2VzKCk7CisKKwlQYXJhbWV0ZXJMaXN0IGxpc3QgPSBudWxsOworCWJ5dGUgYiA9IHIucmVhZEJ5dGUoKTsKKwlpZiAoYiA9PSAnKCcpIHsKKwkgICAgbGlzdCA9IG5ldyBQYXJhbWV0ZXJMaXN0KCk7CisJICAgIGRvIHsKKwkJU3RyaW5nIG5hbWUgPSByLnJlYWRTdHJpbmcoKTsKKwkJaWYgKHBhcnNlRGVidWcpCisJCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkRFQlVHIElNQVA6IHBhcmFtZXRlciBuYW1lICIgKyBuYW1lKTsKKwkJaWYgKG5hbWUgPT0gbnVsbCkKKwkJICAgIHRocm93IG5ldyBQYXJzaW5nRXhjZXB0aW9uKAorCQkJIkJPRFlTVFJVQ1RVUkUgcGFyc2UgZXJyb3I6ICIgKworCQkJdHlwZSArICIvIiArIHN1YnR5cGUgKyAiOiAiICsKKwkJCSJudWxsIG5hbWUgaW4gcGFyYW1ldGVyIGxpc3QiKTsKKwkJU3RyaW5nIHZhbHVlID0gci5yZWFkU3RyaW5nKCk7CisJCWlmIChwYXJzZURlYnVnKQorCQkgICAgU3lzdGVtLm91dC5wcmludGxuKCJERUJVRyBJTUFQOiBwYXJhbWV0ZXIgdmFsdWUgIiArIHZhbHVlKTsKKwkJaWYgKHZhbHVlID09IG51bGwpIHsJLy8gd29yayBhcm91bmQgYnVnZ3kgc2VydmVycworCQkgICAgaWYgKHBhcnNlRGVidWcpCisJCQlTeXN0ZW0ub3V0LnByaW50bG4oIkRFQlVHIElNQVA6IE5JTCBwYXJhbWV0ZXIgdmFsdWUiICsKKwkJCQkJIiwgYXBwbHlpbmcgRXhjaGFuZ2UgYnVnIHdvcmthcm91bmQiKTsKKwkJICAgIHZhbHVlID0gIiI7CisJCX0KKwkJbGlzdC5zZXQobmFtZSwgdmFsdWUpOworCSAgICB9IHdoaWxlICghci5pc05leHROb25TcGFjZSgnKScpKTsKKwkgICAgbGlzdC5jb21iaW5lU2VnbWVudHMoKTsKKwl9IGVsc2UgaWYgKGIgPT0gJ04nIHx8IGIgPT0gJ24nKSB7CisJICAgIGlmIChwYXJzZURlYnVnKQorCQlTeXN0ZW0ub3V0LnByaW50bG4oIkRFQlVHIElNQVA6IHBhcmFtZXRlciBsaXN0IE5JTCIpOworCSAgICByLnNraXAoMik7CisJfSBlbHNlCisJICAgIHRocm93IG5ldyBQYXJzaW5nRXhjZXB0aW9uKCJQYXJhbWV0ZXIgbGlzdCBwYXJzZSBlcnJvciIpOworCisJcmV0dXJuIGxpc3Q7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHBhcnNlQm9keUV4dGVuc2lvbihSZXNwb25zZSByKSB0aHJvd3MgUGFyc2luZ0V4Y2VwdGlvbiB7CisJci5za2lwU3BhY2VzKCk7CisKKwlieXRlIGIgPSByLnBlZWtCeXRlKCk7CisJaWYgKGIgPT0gJygnKSB7CisJICAgIHIuc2tpcCgxKTsgLy8gc2tpcCAnKCcKKwkgICAgZG8geworCQlwYXJzZUJvZHlFeHRlbnNpb24ocik7CisJICAgIH0gd2hpbGUgKCFyLmlzTmV4dE5vblNwYWNlKCcpJykpOworCX0gZWxzZSBpZiAoQ2hhcmFjdGVyLmlzRGlnaXQoKGNoYXIpYikpIC8vIG51bWJlcgorCSAgICByLnJlYWROdW1iZXIoKTsKKwllbHNlIC8vIG5zdHJpbmcKKwkgICAgci5yZWFkU3RyaW5nKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL3Byb3RvY29sL0VOVkVMT1BFLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvcHJvdG9jb2wvRU5WRUxPUEUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZWFmZDE0Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL3Byb3RvY29sL0VOVkVMT1BFLmphdmEKQEAgLTAsMCArMSwyMjQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmltYXAucHJvdG9jb2w7CisKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5EYXRlOworaW1wb3J0IGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnRleHQuUGFyc2VFeGNlcHRpb247CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC5JbnRlcm5ldEFkZHJlc3M7CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC5BZGRyZXNzRXhjZXB0aW9uOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuTWFpbERhdGVGb3JtYXQ7CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC5NaW1lVXRpbGl0eTsKK2ltcG9ydCBjb20uc3VuLm1haWwuaWFwLio7CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuUHJvcFV0aWw7CisKKy8qKgorICogVGhlIEVORVZFTE9QRSBpdGVtIG9mIGFuIElNQVAgRkVUQ0ggcmVzcG9uc2UuCisgKgorICogQGF1dGhvciAgSm9obiBNYW5pCisgKiBAYXV0aG9yICBCaWxsIFNoYW5ub24KKyAqLworCitwdWJsaWMgY2xhc3MgRU5WRUxPUEUgaW1wbGVtZW50cyBJdGVtIHsKKyAgICAKKyAgICAvLyBJTUFQIGl0ZW0gbmFtZQorICAgIHN0YXRpYyBmaW5hbCBjaGFyW10gbmFtZSA9IHsnRScsJ04nLCdWJywnRScsJ0wnLCdPJywnUCcsJ0UnfTsKKyAgICBwdWJsaWMgaW50IG1zZ25vOworCisgICAgcHVibGljIERhdGUgZGF0ZSA9IG51bGw7CisgICAgcHVibGljIFN0cmluZyBzdWJqZWN0OworICAgIHB1YmxpYyBJbnRlcm5ldEFkZHJlc3NbXSBmcm9tOworICAgIHB1YmxpYyBJbnRlcm5ldEFkZHJlc3NbXSBzZW5kZXI7CisgICAgcHVibGljIEludGVybmV0QWRkcmVzc1tdIHJlcGx5VG87CisgICAgcHVibGljIEludGVybmV0QWRkcmVzc1tdIHRvOworICAgIHB1YmxpYyBJbnRlcm5ldEFkZHJlc3NbXSBjYzsKKyAgICBwdWJsaWMgSW50ZXJuZXRBZGRyZXNzW10gYmNjOworICAgIHB1YmxpYyBTdHJpbmcgaW5SZXBseVRvOworICAgIHB1YmxpYyBTdHJpbmcgbWVzc2FnZUlkOworCisgICAgLy8gVXNlZCB0byBwYXJzZSBkYXRlcworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE1haWxEYXRlRm9ybWF0IG1haWxEYXRlRm9ybWF0ID0gbmV3IE1haWxEYXRlRm9ybWF0KCk7CisKKyAgICAvLyBzcGVjaWFsIGRlYnVnZ2luZyBvdXRwdXQgdG8gZGVidWcgcGFyc2luZyBlcnJvcnMKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIHBhcnNlRGVidWcgPQorCVByb3BVdGlsLmdldEJvb2xlYW5TeXN0ZW1Qcm9wZXJ0eSgibWFpbC5pbWFwLnBhcnNlLmRlYnVnIiwgZmFsc2UpOworICAgIAorICAgIHB1YmxpYyBFTlZFTE9QRShGZXRjaFJlc3BvbnNlIHIpIHRocm93cyBQYXJzaW5nRXhjZXB0aW9uIHsKKwlpZiAocGFyc2VEZWJ1ZykKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJwYXJzZSBFTlZFTE9QRSIpOworCW1zZ25vID0gci5nZXROdW1iZXIoKTsKKworCXIuc2tpcFNwYWNlcygpOworCisJaWYgKHIucmVhZEJ5dGUoKSAhPSAnKCcpCisJICAgIHRocm93IG5ldyBQYXJzaW5nRXhjZXB0aW9uKCJFTlZFTE9QRSBwYXJzZSBlcnJvciIpOworCQorCVN0cmluZyBzID0gci5yZWFkU3RyaW5nKCk7CisJaWYgKHMgIT0gbnVsbCkgeworCSAgICB0cnkgeworICAgICAgICAgICAgc3luY2hyb25pemVkIChtYWlsRGF0ZUZvcm1hdCkgeworICAgICAgICAgICAgICAgIGRhdGUgPSBtYWlsRGF0ZUZvcm1hdC5wYXJzZShzKTsKKyAgICAgICAgICAgIH0KKwkgICAgfSBjYXRjaCAoUGFyc2VFeGNlcHRpb24gcGV4KSB7CisJICAgIH0KKwl9CisJaWYgKHBhcnNlRGVidWcpCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiICBEYXRlOiAiICsgZGF0ZSk7CisKKwlzdWJqZWN0ID0gci5yZWFkU3RyaW5nKCk7CisJaWYgKHBhcnNlRGVidWcpCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiICBTdWJqZWN0OiAiICsgc3ViamVjdCk7CisJaWYgKHBhcnNlRGVidWcpCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiICBGcm9tIGFkZHJlc3NlczoiKTsKKwlmcm9tID0gcGFyc2VBZGRyZXNzTGlzdChyKTsKKwlpZiAocGFyc2VEZWJ1ZykKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCIgIFNlbmRlciBhZGRyZXNzZXM6Iik7CisJc2VuZGVyID0gcGFyc2VBZGRyZXNzTGlzdChyKTsKKwlpZiAocGFyc2VEZWJ1ZykKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCIgIFJlcGx5LVRvIGFkZHJlc3NlczoiKTsKKwlyZXBseVRvID0gcGFyc2VBZGRyZXNzTGlzdChyKTsKKwlpZiAocGFyc2VEZWJ1ZykKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCIgIFRvIGFkZHJlc3NlczoiKTsKKwl0byA9IHBhcnNlQWRkcmVzc0xpc3Qocik7CisJaWYgKHBhcnNlRGVidWcpCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiICBDYyBhZGRyZXNzZXM6Iik7CisJY2MgPSBwYXJzZUFkZHJlc3NMaXN0KHIpOworCWlmIChwYXJzZURlYnVnKQorCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiAgQmNjIGFkZHJlc3NlczoiKTsKKwliY2MgPSBwYXJzZUFkZHJlc3NMaXN0KHIpOworCWluUmVwbHlUbyA9IHIucmVhZFN0cmluZygpOworCWlmIChwYXJzZURlYnVnKQorCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiAgSW4tUmVwbHktVG86ICIgKyBpblJlcGx5VG8pOworCW1lc3NhZ2VJZCA9IHIucmVhZFN0cmluZygpOworCWlmIChwYXJzZURlYnVnKQorCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiAgTWVzc2FnZS1JRDogIiArIG1lc3NhZ2VJZCk7CisKKwlpZiAoIXIuaXNOZXh0Tm9uU3BhY2UoJyknKSkKKwkgICAgdGhyb3cgbmV3IFBhcnNpbmdFeGNlcHRpb24oIkVOVkVMT1BFIHBhcnNlIGVycm9yIik7CisgICAgfQorCisgICAgcHJpdmF0ZSBJbnRlcm5ldEFkZHJlc3NbXSBwYXJzZUFkZHJlc3NMaXN0KFJlc3BvbnNlIHIpIAorCQl0aHJvd3MgUGFyc2luZ0V4Y2VwdGlvbiB7CisJci5za2lwU3BhY2VzKCk7IC8vIHNraXAgbGVhZGluZyBzcGFjZXMKKworCWJ5dGUgYiA9IHIucmVhZEJ5dGUoKTsKKwlpZiAoYiA9PSAnKCcpIHsKKwkgICAgLyoKKwkgICAgICogU29tZSBicm9rZW4gc2VydmVycyAoZS5nLiwgWWFob28gTWFpbCkgcmV0dXJuIGFuIGVtcHR5CisJICAgICAqIGxpc3QgaW5zdGVhZCBvZiBOSUwuICBIYW5kbGUgdGhhdCBoZXJlIGV2ZW4gdGhvdWdoIGl0CisJICAgICAqIGRvZXNuJ3QgY29uZm9ybSB0byB0aGUgSU1BUCBzcGVjLgorCSAgICAgKi8KKwkgICAgaWYgKHIuaXNOZXh0Tm9uU3BhY2UoJyknKSkKKwkJcmV0dXJuIG51bGw7CisKKwkgICAgTGlzdDxJbnRlcm5ldEFkZHJlc3M+IHYgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKworCSAgICBkbyB7CisJCUlNQVBBZGRyZXNzIGEgPSBuZXcgSU1BUEFkZHJlc3Mocik7CisJCWlmIChwYXJzZURlYnVnKQorCQkgICAgU3lzdGVtLm91dC5wcmludGxuKCIgICAgQWRkcmVzczogIiArIGEpOworCQkvLyBpZiB3ZSBzZWUgYW4gZW5kLW9mLWdyb3VwIGFkZHJlc3MgYXQgdGhlIHRvcCwgaWdub3JlIGl0CisJCWlmICghYS5pc0VuZE9mR3JvdXAoKSkKKwkJICAgIHYuYWRkKGEpOworCSAgICB9IHdoaWxlICghci5pc05leHROb25TcGFjZSgnKScpKTsKKworCSAgICByZXR1cm4gdi50b0FycmF5KG5ldyBJbnRlcm5ldEFkZHJlc3Nbdi5zaXplKCldKTsKKwl9IGVsc2UgaWYgKGIgPT0gJ04nIHx8IGIgPT0gJ24nKSB7IC8vIE5JTAorCSAgICByLnNraXAoMik7IC8vIHNraXAgJ05JTCcKKwkgICAgcmV0dXJuIG51bGw7CisJfSBlbHNlCisJICAgIHRocm93IG5ldyBQYXJzaW5nRXhjZXB0aW9uKCJBRERSRVNTIHBhcnNlIGVycm9yIik7CisgICAgfQorfQorCitjbGFzcyBJTUFQQWRkcmVzcyBleHRlbmRzIEludGVybmV0QWRkcmVzcyB7CisgICAgcHJpdmF0ZSBib29sZWFuIGdyb3VwID0gZmFsc2U7CisgICAgcHJpdmF0ZSBJbnRlcm5ldEFkZHJlc3NbXSBncm91cGxpc3Q7CisgICAgcHJpdmF0ZSBTdHJpbmcgZ3JvdXBuYW1lOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTM4MzU4MjIwMjk0ODMxMjIyMzJMOworCisgICAgSU1BUEFkZHJlc3MoUmVzcG9uc2UgcikgdGhyb3dzIFBhcnNpbmdFeGNlcHRpb24geworICAgICAgICByLnNraXBTcGFjZXMoKTsgLy8gc2tpcCBsZWFkaW5nIHNwYWNlcworCisgICAgICAgIGlmIChyLnJlYWRCeXRlKCkgIT0gJygnKQorICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNpbmdFeGNlcHRpb24oIkFERFJFU1MgcGFyc2UgZXJyb3IiKTsKKworICAgICAgICBlbmNvZGVkUGVyc29uYWwgPSByLnJlYWRTdHJpbmcoKTsKKworICAgICAgICByLnJlYWRTdHJpbmcoKTsgLy8gdGhyb3cgYXdheSBhZGRyZXNzX2xpc3QKKwlTdHJpbmcgbWIgPSByLnJlYWRTdHJpbmcoKTsKKwlTdHJpbmcgaG9zdCA9IHIucmVhZFN0cmluZygpOworCS8vIHNraXAgYm9ndXMgc3BhY2VzIGluc2VydGVkIGJ5IFlhaG9vIElNQVAgc2VydmVyIGlmCisJLy8gInVuZGlzY2xvc2VkLXJlY2lwaWVudHMiIGlzIGEgcmVjaXBpZW50CisJci5za2lwU3BhY2VzKCk7CisJaWYgKCFyLmlzTmV4dE5vblNwYWNlKCcpJykpIC8vIHNraXAgcGFzdCB0ZXJtaW5hdGluZyAnKScKKyAgICAgICAgICAgIHRocm93IG5ldyBQYXJzaW5nRXhjZXB0aW9uKCJBRERSRVNTIHBhcnNlIGVycm9yIik7CisKKwlpZiAoaG9zdCA9PSBudWxsKSB7CisJICAgIC8vIGl0J3MgYSBncm91cCBsaXN0LCBzdGFydCBvciBlbmQKKwkgICAgZ3JvdXAgPSB0cnVlOworCSAgICBncm91cG5hbWUgPSBtYjsKKwkgICAgaWYgKGdyb3VwbmFtZSA9PSBudWxsKQkvLyBlbmQgb2YgZ3JvdXAgbGlzdAorCQlyZXR1cm47CisJICAgIC8vIEFjY3VtdWxhdGUgYSBncm91cCBsaXN0LiAgVGhlIG1lbWJlcnMgb2YgdGhlIGdyb3VwCisJICAgIC8vIGFyZSBhY2N1bXVsYXRlZCBpbiBhIExpc3QgYW5kIHRoZSBjb3JyZXNwb25kaW5nIHN0cmluZworCSAgICAvLyByZXByZXNlbnRhdGlvbiBvZiB0aGUgZ3JvdXAgaXMgYWNjdW11bGF0ZWQgaW4gYSBTdHJpbmdCdWlsZGVyLgorCSAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKwkgICAgc2IuYXBwZW5kKGdyb3VwbmFtZSkuYXBwZW5kKCc6Jyk7CisJICAgIExpc3Q8SW50ZXJuZXRBZGRyZXNzPiB2ID0gbmV3IEFycmF5TGlzdDw+KCk7CisJICAgIHdoaWxlIChyLnBlZWtCeXRlKCkgIT0gJyknKSB7CisJCUlNQVBBZGRyZXNzIGEgPSBuZXcgSU1BUEFkZHJlc3Mocik7CisJCWlmIChhLmlzRW5kT2ZHcm91cCgpKQkvLyByZWFjaGVkIGVuZCBvZiBncm91cAorCQkgICAgYnJlYWs7CisJCWlmICh2LnNpemUoKSAhPSAwKQkvLyBpZiBub3QgZmlyc3QgZWxlbWVudCwgbmVlZCBhIGNvbW1hCisJCSAgICBzYi5hcHBlbmQoJywnKTsKKwkJc2IuYXBwZW5kKGEudG9TdHJpbmcoKSk7CisJCXYuYWRkKGEpOworCSAgICB9CisJICAgIHNiLmFwcGVuZCgnOycpOworCSAgICBhZGRyZXNzID0gc2IudG9TdHJpbmcoKTsKKwkgICAgZ3JvdXBsaXN0ID0gdi50b0FycmF5KG5ldyBJTUFQQWRkcmVzc1t2LnNpemUoKV0pOworCX0gZWxzZSB7CisJICAgIGlmIChtYiA9PSBudWxsIHx8IG1iLmxlbmd0aCgpID09IDApCisJCWFkZHJlc3MgPSBob3N0OworCSAgICBlbHNlIGlmIChob3N0Lmxlbmd0aCgpID09IDApCisJCWFkZHJlc3MgPSBtYjsKKwkgICAgZWxzZQorCQlhZGRyZXNzID0gbWIgKyAiQCIgKyBob3N0OworCX0KKworICAgIH0KKworICAgIGJvb2xlYW4gaXNFbmRPZkdyb3VwKCkgeworCXJldHVybiBncm91cCAmJiBncm91cG5hbWUgPT0gbnVsbDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0dyb3VwKCkgeworCXJldHVybiBncm91cDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgSW50ZXJuZXRBZGRyZXNzW10gZ2V0R3JvdXAoYm9vbGVhbiBzdHJpY3QpIHRocm93cyBBZGRyZXNzRXhjZXB0aW9uIHsKKwlpZiAoZ3JvdXBsaXN0ID09IG51bGwpCisJICAgIHJldHVybiBudWxsOworCXJldHVybiBncm91cGxpc3QuY2xvbmUoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvcHJvdG9jb2wvRkxBR1MuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9GTEFHUy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU2MjFhYTgKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvcHJvdG9jb2wvRkxBR1MuamF2YQpAQCAtMCwwICsxLDg2IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5pbWFwLnByb3RvY29sOworCitpbXBvcnQgamF2YXgubWFpbC5GbGFnczsKK2ltcG9ydCBjb20uc3VuLm1haWwuaWFwLio7IAorCisvKioKKyAqIFRoaXMgY2xhc3MgCisgKgorICogQGF1dGhvciAgSm9obiBNYW5pCisgKi8KKworcHVibGljIGNsYXNzIEZMQUdTIGV4dGVuZHMgRmxhZ3MgaW1wbGVtZW50cyBJdGVtIHsKKworICAgIC8vIElNQVAgaXRlbSBuYW1lCisgICAgc3RhdGljIGZpbmFsIGNoYXJbXSBuYW1lID0geydGJywnTCcsJ0EnLCdHJywnUyd9OworICAgIHB1YmxpYyBpbnQgbXNnbm87CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA0MzkwNDk4NDcwNTM3NTY2NzBMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jcgl0aGUgSU1BUFJlc3BvbnNlCisgICAgICogQGV4Y2VwdGlvbglQYXJzaW5nRXhjZXB0aW9uCWZvciBwYXJzaW5nIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIEZMQUdTKElNQVBSZXNwb25zZSByKSB0aHJvd3MgUGFyc2luZ0V4Y2VwdGlvbiB7CisJbXNnbm8gPSByLmdldE51bWJlcigpOworCisJci5za2lwU3BhY2VzKCk7CisJU3RyaW5nW10gZmxhZ3MgPSByLnJlYWRTaW1wbGVMaXN0KCk7CisJaWYgKGZsYWdzICE9IG51bGwpIHsgLy8gaWYgbm90IGVtcHR5IGZsYWdsaXN0CisJICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmxhZ3MubGVuZ3RoOyBpKyspIHsKKwkJU3RyaW5nIHMgPSBmbGFnc1tpXTsKKwkJaWYgKHMubGVuZ3RoKCkgPj0gMiAmJiBzLmNoYXJBdCgwKSA9PSAnXFwnKSB7CisJCSAgICBzd2l0Y2ggKENoYXJhY3Rlci50b1VwcGVyQ2FzZShzLmNoYXJBdCgxKSkpIHsKKwkJICAgIGNhc2UgJ1MnOiAvLyBcU2VlbgorCQkJYWRkKEZsYWdzLkZsYWcuU0VFTik7CisJCQlicmVhazsKKwkJICAgIGNhc2UgJ1InOiAvLyBcUmVjZW50CisJCQlhZGQoRmxhZ3MuRmxhZy5SRUNFTlQpOworCQkJYnJlYWs7CisJCSAgICBjYXNlICdEJzoKKwkJCWlmIChzLmxlbmd0aCgpID49IDMpIHsKKwkJCSAgICBjaGFyIGMgPSBzLmNoYXJBdCgyKTsKKwkJCSAgICBpZiAoYyA9PSAnZScgfHwgYyA9PSAnRScpIC8vIFxEZWxldGVkCisJCQkJYWRkKEZsYWdzLkZsYWcuREVMRVRFRCk7CisJCQkgICAgZWxzZSBpZiAoYyA9PSAncicgfHwgYyA9PSAnUicpIC8vIFxEcmFmdAorCQkJCWFkZChGbGFncy5GbGFnLkRSQUZUKTsKKwkJCX0gZWxzZQorCQkJICAgIGFkZChzKTsJLy8gdW5rbm93biwgdHJlYXQgaXQgYXMgYSB1c2VyIGZsYWcKKwkJCWJyZWFrOworCQkgICAgY2FzZSAnQSc6IC8vIFxBbnN3ZXJlZAorCQkJYWRkKEZsYWdzLkZsYWcuQU5TV0VSRUQpOworCQkJYnJlYWs7CisJCSAgICBjYXNlICdGJzogLy8gXEZsYWdnZWQKKwkJCWFkZChGbGFncy5GbGFnLkZMQUdHRUQpOworCQkJYnJlYWs7CisJCSAgICBjYXNlICcqJzogLy8gXCoKKwkJCWFkZChGbGFncy5GbGFnLlVTRVIpOworCQkJYnJlYWs7CisJCSAgICBkZWZhdWx0OgorCQkJYWRkKHMpOwkJLy8gdW5rbm93biwgdHJlYXQgaXQgYXMgYSB1c2VyIGZsYWcKKwkJCWJyZWFrOworCQkgICAgfQorCQl9IGVsc2UKKwkJICAgIGFkZChzKTsKKwkgICAgfQorCX0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvcHJvdG9jb2wvRmV0Y2hJdGVtLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvcHJvdG9jb2wvRmV0Y2hJdGVtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWVhYWU2YwotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9GZXRjaEl0ZW0uamF2YQpAQCAtMCwwICsxLDU4IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5pbWFwLnByb3RvY29sOworCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuKjsKKworaW1wb3J0IGphdmF4Lm1haWwuRmV0Y2hQcm9maWxlOworaW1wb3J0IGNvbS5zdW4ubWFpbC5pYXAuUGFyc2luZ0V4Y2VwdGlvbjsKKworLyoqCisgKiBNZXRhZGF0YSBkZXNjcmliaW5nIGEgRkVUQ0ggaXRlbS4KKyAqIE5vdGUgdGhhdCB0aGUgIm5hbWUiIGZpZWxkIE1VU1QgYmUgaW4gdXBwZXJjYXNlLiA8cD4KKyAqCisgKiBAYXV0aG9yICBCaWxsIFNoYW5ub24KKyAqIEBzaW5jZSBKYXZhTWFpbCAxLjQuNgorICovCisKK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBGZXRjaEl0ZW0geyAKKyAgICBwcml2YXRlIFN0cmluZyBuYW1lOworICAgIHByaXZhdGUgRmV0Y2hQcm9maWxlLkl0ZW0gZmV0Y2hQcm9maWxlSXRlbTsKKworICAgIHB1YmxpYyBGZXRjaEl0ZW0oU3RyaW5nIG5hbWUsIEZldGNoUHJvZmlsZS5JdGVtIGZldGNoUHJvZmlsZUl0ZW0pIHsKKwl0aGlzLm5hbWUgPSBuYW1lOworCXRoaXMuZmV0Y2hQcm9maWxlSXRlbSA9IGZldGNoUHJvZmlsZUl0ZW07CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgeworCXJldHVybiBuYW1lOworICAgIH0KKworICAgIHB1YmxpYyBGZXRjaFByb2ZpbGUuSXRlbSBnZXRGZXRjaFByb2ZpbGVJdGVtKCkgeworCXJldHVybiBmZXRjaFByb2ZpbGVJdGVtOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlIHRoZSBpdGVtIGludG8gc29tZSBraW5kIG9mIG9iamVjdCBhcHByb3ByaWF0ZSBmb3IgdGhlIGl0ZW0uCisgICAgICogTm90ZSB0aGF0IHRoZSBpdGVtIG5hbWUgd2lsbCBoYXZlIGJlZW4gcGFyc2VkIGFuZCBza2lwcGVkIGFscmVhZHkuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jcgl0aGUgcmVzcG9uc2UKKyAgICAgKiBAcmV0dXJuCQl0aGUgZmV0Y2ggaXRlbQorICAgICAqIEBleGNlcHRpb24JUGFyc2luZ0V4Y2VwdGlvbglmb3IgcGFyc2luZyBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBPYmplY3QgcGFyc2VJdGVtKEZldGNoUmVzcG9uc2UgcikgdGhyb3dzIFBhcnNpbmdFeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvcHJvdG9jb2wvRmV0Y2hSZXNwb25zZS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL3Byb3RvY29sL0ZldGNoUmVzcG9uc2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42NDc3YmE1Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL3Byb3RvY29sL0ZldGNoUmVzcG9uc2UuamF2YQpAQCAtMCwwICsxLDMyMCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuaW1hcC5wcm90b2NvbDsKKworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5BU0NJSVV0aWxpdHk7CitpbXBvcnQgY29tLnN1bi5tYWlsLmlhcC4qOworCisvKioKKyAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhIEZFVENIIHJlc3BvbnNlIG9idGFpbmVkIGZyb20gdGhlIGlucHV0IHN0cmVhbQorICogb2YgYW4gSU1BUCBzZXJ2ZXIuCisgKgorICogQGF1dGhvciAgSm9obiBNYW5pCisgKiBAYXV0aG9yICBCaWxsIFNoYW5ub24KKyAqLworCitwdWJsaWMgY2xhc3MgRmV0Y2hSZXNwb25zZSBleHRlbmRzIElNQVBSZXNwb25zZSB7CisgICAgLyoKKyAgICAgKiBSZWd1bGFyIEl0ZW1zIGFyZSBzYXZlZCBpbiB0aGUgaXRlbXMgYXJyYXkuCisgICAgICogRXh0ZW5zaW9uIGl0ZW1zIChpdGVtcyBoYW5kbGVkIGJ5IHN1YmNsYXNzZXMKKyAgICAgKiB0aGF0IGV4dGVuZCB0aGUgSU1BUCBwcm92aWRlcikgYXJlIHNhdmVkIGluIHRoZQorICAgICAqIGV4dGVuc2lvbkl0ZW1zIG1hcCwgaW5kZXhlZCBieSB0aGUgRkVUQ0ggaXRlbSBuYW1lLgorICAgICAqIFRoZSBtYXAgaXMgb25seSBjcmVhdGVkIHdoZW4gbmVlZGVkLgorICAgICAqCisgICAgICogWFhYIC0gU2hvdWxkIGNvbnNpZGVyIHVuaWZ5aW5nIHRoZSBoYW5kbGluZyBvZgorICAgICAqIHJlZ3VsYXIgaXRlbXMgYW5kIGV4dGVuc2lvbiBpdGVtcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIEl0ZW1bXSBpdGVtczsKKyAgICBwcml2YXRlIE1hcDxTdHJpbmcsIE9iamVjdD4gZXh0ZW5zaW9uSXRlbXM7CisgICAgcHJpdmF0ZSBmaW5hbCBGZXRjaEl0ZW1bXSBmaXRlbXM7CisKKyAgICBwdWJsaWMgRmV0Y2hSZXNwb25zZShQcm90b2NvbCBwKSAKKwkJdGhyb3dzIElPRXhjZXB0aW9uLCBQcm90b2NvbEV4Y2VwdGlvbiB7CisJc3VwZXIocCk7CisJZml0ZW1zID0gbnVsbDsKKwlwYXJzZSgpOworICAgIH0KKworICAgIHB1YmxpYyBGZXRjaFJlc3BvbnNlKElNQVBSZXNwb25zZSByKQorCQl0aHJvd3MgSU9FeGNlcHRpb24sIFByb3RvY29sRXhjZXB0aW9uIHsKKwl0aGlzKHIsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCBhIEZldGNoUmVzcG9uc2UgdGhhdCBoYW5kbGVzIHRoZSBhZGRpdGlvbmFsIEZldGNoSXRlbXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jcgl0aGUgSU1BUFJlc3BvbnNlCisgICAgICogQHBhcmFtCWZpdGVtcwl0aGUgZmV0Y2ggaXRlbXMKKyAgICAgKiBAZXhjZXB0aW9uCUlPRXhjZXB0aW9uCWZvciBJL08gZXJyb3JzCisgICAgICogQGV4Y2VwdGlvbglQcm90b2NvbEV4Y2VwdGlvbglmb3IgcHJvdG9jb2wgZmFpbHVyZXMKKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS40LjYKKyAgICAgKi8KKyAgICBwdWJsaWMgRmV0Y2hSZXNwb25zZShJTUFQUmVzcG9uc2UgciwgRmV0Y2hJdGVtW10gZml0ZW1zKQorCQl0aHJvd3MgSU9FeGNlcHRpb24sIFByb3RvY29sRXhjZXB0aW9uIHsKKwlzdXBlcihyKTsKKwl0aGlzLmZpdGVtcyA9IGZpdGVtczsKKwlwYXJzZSgpOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0SXRlbUNvdW50KCkgeworCXJldHVybiBpdGVtcy5sZW5ndGg7CisgICAgfQorCisgICAgcHVibGljIEl0ZW0gZ2V0SXRlbShpbnQgaW5kZXgpIHsKKwlyZXR1cm4gaXRlbXNbaW5kZXhdOworICAgIH0KKworICAgIHB1YmxpYyA8VCBleHRlbmRzIEl0ZW0+IFQgZ2V0SXRlbShDbGFzczxUPiBjKSB7CisJZm9yIChpbnQgaSA9IDA7IGkgPCBpdGVtcy5sZW5ndGg7IGkrKykgeworCSAgICBpZiAoYy5pc0luc3RhbmNlKGl0ZW1zW2ldKSkKKwkJcmV0dXJuIGMuY2FzdChpdGVtc1tpXSk7CisJfQorCisJcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBmaXJzdCBmZXRjaCByZXNwb25zZSBpdGVtIG9mIHRoZSBnaXZlbiBjbGFzcworICAgICAqIGZvciB0aGUgZ2l2ZW4gbWVzc2FnZSBudW1iZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jcgl0aGUgcmVzcG9uc2VzCisgICAgICogQHBhcmFtCW1zZ25vCXRoZSBtZXNzYWdlIG51bWJlcgorICAgICAqIEBwYXJhbQljCXRoZSBjbGFzcworICAgICAqIEBwYXJhbQk8VD4JdGhlIHR5cGUgb2YgZmV0Y2ggaXRlbQorICAgICAqIEByZXR1cm4JCXRoZSBmZXRjaCBpdGVtCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyA8VCBleHRlbmRzIEl0ZW0+IFQgZ2V0SXRlbShSZXNwb25zZVtdIHIsIGludCBtc2dubywKKwkJCQlDbGFzczxUPiBjKSB7CisJaWYgKHIgPT0gbnVsbCkKKwkgICAgcmV0dXJuIG51bGw7CisKKwlmb3IgKGludCBpID0gMDsgaSA8IHIubGVuZ3RoOyBpKyspIHsKKworCSAgICBpZiAocltpXSA9PSBudWxsIHx8CisJCSEocltpXSBpbnN0YW5jZW9mIEZldGNoUmVzcG9uc2UpIHx8CisJCSgoRmV0Y2hSZXNwb25zZSlyW2ldKS5nZXROdW1iZXIoKSAhPSBtc2dubykKKwkJY29udGludWU7CisKKwkgICAgRmV0Y2hSZXNwb25zZSBmID0gKEZldGNoUmVzcG9uc2UpcltpXTsKKwkgICAgZm9yIChpbnQgaiA9IDA7IGogPCBmLml0ZW1zLmxlbmd0aDsgaisrKSB7CisJCWlmIChjLmlzSW5zdGFuY2UoZi5pdGVtc1tqXSkpCisJCSAgICByZXR1cm4gYy5jYXN0KGYuaXRlbXNbal0pOworCSAgICB9CisJfQorCisJcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIGFsbCBmZXRjaCByZXNwb25zZSBpdGVtcyBvZiB0aGUgZ2l2ZW4gY2xhc3MKKyAgICAgKiBmb3IgdGhlIGdpdmVuIG1lc3NhZ2UgbnVtYmVyLgorICAgICAqCisgICAgICogQHBhcmFtCXIJdGhlIHJlc3BvbnNlcworICAgICAqIEBwYXJhbQltc2dubwl0aGUgbWVzc2FnZSBudW1iZXIKKyAgICAgKiBAcGFyYW0JYwl0aGUgY2xhc3MKKyAgICAgKiBAcGFyYW0JPFQ+CXRoZSB0eXBlIG9mIGZldGNoIGl0ZW1zCisgICAgICogQHJldHVybgkJdGhlIGxpc3Qgb2YgZmV0Y2ggaXRlbXMKKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS41LjIKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIDxUIGV4dGVuZHMgSXRlbT4gTGlzdDxUPiBnZXRJdGVtcyhSZXNwb25zZVtdIHIsIGludCBtc2dubywKKwkJCQlDbGFzczxUPiBjKSB7CisJTGlzdDxUPiBpdGVtcyA9IG5ldyBBcnJheUxpc3Q8PigpOworCisJaWYgKHIgPT0gbnVsbCkKKwkgICAgcmV0dXJuIGl0ZW1zOworCisJZm9yIChpbnQgaSA9IDA7IGkgPCByLmxlbmd0aDsgaSsrKSB7CisKKwkgICAgaWYgKHJbaV0gPT0gbnVsbCB8fAorCQkhKHJbaV0gaW5zdGFuY2VvZiBGZXRjaFJlc3BvbnNlKSB8fAorCQkoKEZldGNoUmVzcG9uc2UpcltpXSkuZ2V0TnVtYmVyKCkgIT0gbXNnbm8pCisJCWNvbnRpbnVlOworCisJICAgIEZldGNoUmVzcG9uc2UgZiA9IChGZXRjaFJlc3BvbnNlKXJbaV07CisJICAgIGZvciAoaW50IGogPSAwOyBqIDwgZi5pdGVtcy5sZW5ndGg7IGorKykgeworCQlpZiAoYy5pc0luc3RhbmNlKGYuaXRlbXNbal0pKQorCQkgICAgaXRlbXMuYWRkKGMuY2FzdChmLml0ZW1zW2pdKSk7CisJICAgIH0KKwl9CisKKwlyZXR1cm4gaXRlbXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIGEgbWFwIG9mIHRoZSBleHRlbnNpb24gaXRlbXMgZm91bmQgaW4gdGhpcyBmZXRjaCByZXNwb25zZS4KKyAgICAgKiBUaGUgbWFwIGlzIGluZGV4ZWQgYnkgZXh0ZW5zaW9uIGl0ZW0gbmFtZS4gIENhbGxlcnMgc2hvdWxkIG5vdAorICAgICAqIG1vZGlmeSB0aGUgbWFwLgorICAgICAqCisgICAgICogQHJldHVybglNYXAgb2YgZXh0ZW5zaW9uIGl0ZW1zLCBvciBudWxsIGlmIG5vbmUKKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS40LjYKKyAgICAgKi8KKyAgICBwdWJsaWMgTWFwPFN0cmluZywgT2JqZWN0PiBnZXRFeHRlbnNpb25JdGVtcygpIHsKKwlyZXR1cm4gZXh0ZW5zaW9uSXRlbXM7CisgICAgfQorCisgICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgY2hhcltdIEhFQURFUiA9IHsnLicsJ0gnLCdFJywnQScsJ0QnLCdFJywnUid9OworICAgIHByaXZhdGUgZmluYWwgc3RhdGljIGNoYXJbXSBURVhUID0geycuJywnVCcsJ0UnLCdYJywnVCd9OworCisgICAgcHJpdmF0ZSB2b2lkIHBhcnNlKCkgdGhyb3dzIFBhcnNpbmdFeGNlcHRpb24geworCWlmICghaXNOZXh0Tm9uU3BhY2UoJygnKSkKKwkgICAgdGhyb3cgbmV3IFBhcnNpbmdFeGNlcHRpb24oCisJCSJlcnJvciBpbiBGRVRDSCBwYXJzaW5nLCBtaXNzaW5nICcoJyBhdCBpbmRleCAiICsgaW5kZXgpOworCisJTGlzdDxJdGVtPiB2ID0gbmV3IEFycmF5TGlzdDw+KCk7CisJSXRlbSBpID0gbnVsbDsKKwlza2lwU3BhY2VzKCk7CisJZG8geworCisJICAgIGlmIChpbmRleCA+PSBzaXplKQorCQl0aHJvdyBuZXcgUGFyc2luZ0V4Y2VwdGlvbigKKwkJImVycm9yIGluIEZFVENIIHBhcnNpbmcsIHJhbiBvZmYgZW5kIG9mIGJ1ZmZlciwgc2l6ZSAiICsgc2l6ZSk7CisKKwkgICAgaSA9IHBhcnNlSXRlbSgpOworCSAgICBpZiAoaSAhPSBudWxsKQorCQl2LmFkZChpKTsKKwkgICAgZWxzZSBpZiAoIXBhcnNlRXh0ZW5zaW9uSXRlbSgpKQorCQl0aHJvdyBuZXcgUGFyc2luZ0V4Y2VwdGlvbigKKwkJICAgICJlcnJvciBpbiBGRVRDSCBwYXJzaW5nLCB1bnJlY29nbml6ZWQgaXRlbSBhdCBpbmRleCAiICsKKwkJICAgIGluZGV4ICsgIiwgc3RhcnRzIHdpdGggXCIiICsgbmV4dDIwKCkgKyAiXCIiKTsKKwl9IHdoaWxlICghaXNOZXh0Tm9uU3BhY2UoJyknKSk7CisKKwlpdGVtcyA9IHYudG9BcnJheShuZXcgSXRlbVt2LnNpemUoKV0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgbmV4dCAyMCBjaGFyYWN0ZXJzIGluIHRoZSBidWZmZXIsIGZvciBleGNlcHRpb24gbWVzc2FnZXMuCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgbmV4dDIwKCkgeworCWlmIChpbmRleCArIDIwID4gc2l6ZSkKKwkgICAgcmV0dXJuIEFTQ0lJVXRpbGl0eS50b1N0cmluZyhidWZmZXIsIGluZGV4LCBzaXplKTsKKwllbHNlCisJICAgIHJldHVybiBBU0NJSVV0aWxpdHkudG9TdHJpbmcoYnVmZmVyLCBpbmRleCwgaW5kZXggKyAyMCkgKyAiLi4uIjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZSB0aGUgaXRlbSBhdCB0aGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGUgYnVmZmVyLAorICAgICAqIHNraXBwaW5nIG92ZXIgdGhlIGl0ZW0gaWYgc3VjY2Vzc2Z1bC4gIE90aGVyd2lzZSwgcmV0dXJuIG51bGwKKyAgICAgKiBhbmQgbGVhdmUgdGhlIGJ1ZmZlciBwb3NpdGlvbiB1bm1vZGlmaWVkLgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJlbXB0eSIpCisgICAgcHJpdmF0ZSBJdGVtIHBhcnNlSXRlbSgpIHRocm93cyBQYXJzaW5nRXhjZXB0aW9uIHsKKwlzd2l0Y2ggKGJ1ZmZlcltpbmRleF0pIHsKKwljYXNlICdFJzogY2FzZSAnZSc6CisJICAgIGlmIChtYXRjaChFTlZFTE9QRS5uYW1lKSkKKwkJcmV0dXJuIG5ldyBFTlZFTE9QRSh0aGlzKTsKKwkgICAgYnJlYWs7CisJY2FzZSAnRic6IGNhc2UgJ2YnOgorCSAgICBpZiAobWF0Y2goRkxBR1MubmFtZSkpCisJCXJldHVybiBuZXcgRkxBR1MoKElNQVBSZXNwb25zZSl0aGlzKTsKKwkgICAgYnJlYWs7CisJY2FzZSAnSSc6IGNhc2UgJ2knOgorCSAgICBpZiAobWF0Y2goSU5URVJOQUxEQVRFLm5hbWUpKQorCQlyZXR1cm4gbmV3IElOVEVSTkFMREFURSh0aGlzKTsKKwkgICAgYnJlYWs7CisJY2FzZSAnQic6IGNhc2UgJ2InOgorCSAgICBpZiAobWF0Y2goQk9EWVNUUlVDVFVSRS5uYW1lKSkKKwkJcmV0dXJuIG5ldyBCT0RZU1RSVUNUVVJFKHRoaXMpOworCSAgICBlbHNlIGlmIChtYXRjaChCT0RZLm5hbWUpKSB7CisJCWlmIChidWZmZXJbaW5kZXhdID09ICdbJykKKwkJICAgIHJldHVybiBuZXcgQk9EWSh0aGlzKTsKKwkJZWxzZQorCQkgICAgcmV0dXJuIG5ldyBCT0RZU1RSVUNUVVJFKHRoaXMpOworCSAgICB9CisJICAgIGJyZWFrOworCWNhc2UgJ1InOiBjYXNlICdyJzoKKwkgICAgaWYgKG1hdGNoKFJGQzgyMlNJWkUubmFtZSkpCisJCXJldHVybiBuZXcgUkZDODIyU0laRSh0aGlzKTsKKwkgICAgZWxzZSBpZiAobWF0Y2goUkZDODIyREFUQS5uYW1lKSkgeworCQlib29sZWFuIGlzSGVhZGVyID0gZmFsc2U7CisJCWlmIChtYXRjaChIRUFERVIpKQorCQkgICAgaXNIZWFkZXIgPSB0cnVlOwkvLyBza2lwICIuSEVBREVSIgorCQllbHNlIGlmIChtYXRjaChURVhUKSkKKwkJICAgIGlzSGVhZGVyID0gZmFsc2U7CS8vIHNraXAgIi5URVhUIgorCQlyZXR1cm4gbmV3IFJGQzgyMkRBVEEodGhpcywgaXNIZWFkZXIpOworCSAgICB9CisJICAgIGJyZWFrOworCWNhc2UgJ1UnOiBjYXNlICd1JzoKKwkgICAgaWYgKG1hdGNoKFVJRC5uYW1lKSkKKwkJcmV0dXJuIG5ldyBVSUQodGhpcyk7CisJICAgIGJyZWFrOworCWNhc2UgJ00nOiBjYXNlICdtJzoKKwkgICAgaWYgKG1hdGNoKE1PRFNFUS5uYW1lKSkKKwkJcmV0dXJuIG5ldyBNT0RTRVEodGhpcyk7CisJICAgIGJyZWFrOworCWRlZmF1bHQ6IAorCSAgICBicmVhazsKKwl9CisJcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogSWYgdGhpcyBpdGVtIGlzIGEga25vd24gZXh0ZW5zaW9uIGl0ZW0sIHBhcnNlIGl0LgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBwYXJzZUV4dGVuc2lvbkl0ZW0oKSB0aHJvd3MgUGFyc2luZ0V4Y2VwdGlvbiB7CisJaWYgKGZpdGVtcyA9PSBudWxsKQorCSAgICByZXR1cm4gZmFsc2U7CisJZm9yIChpbnQgaSA9IDA7IGkgPCBmaXRlbXMubGVuZ3RoOyBpKyspIHsKKwkgICAgaWYgKG1hdGNoKGZpdGVtc1tpXS5nZXROYW1lKCkpKSB7CisJCWlmIChleHRlbnNpb25JdGVtcyA9PSBudWxsKQorCQkgICAgZXh0ZW5zaW9uSXRlbXMgPSBuZXcgSGFzaE1hcDw+KCk7CisJCWV4dGVuc2lvbkl0ZW1zLnB1dChmaXRlbXNbaV0uZ2V0TmFtZSgpLAorCQkJCSAgICBmaXRlbXNbaV0ucGFyc2VJdGVtKHRoaXMpKTsKKwkJcmV0dXJuIHRydWU7CisJICAgIH0KKwl9CisJcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIERvZXMgdGhlIGN1cnJlbnQgYnVmZmVyIG1hdGNoIHRoZSBnaXZlbiBpdGVtIG5hbWU/CisgICAgICogaXRlbU5hbWUgaXMgdGhlIG5hbWUgb2YgdGhlIElNQVAgaXRlbSB0byBjb21wYXJlIGFnYWluc3QuCisgICAgICogTk9URSB0aGF0IGl0ZW1OYW1lICptdXN0KiBiZSBhbGwgdXBwZXJjYXNlLgorICAgICAqIElmIHRoZSBtYXRjaCBpcyBzdWNjZXNzZnVsLCB0aGUgYnVmZmVyIHBvaW50ZXIgKGluZGV4KQorICAgICAqIGlzIGluY3JlbWVudGVkIHBhc3QgdGhlIG1hdGNoZWQgaXRlbS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gbWF0Y2goY2hhcltdIGl0ZW1OYW1lKSB7CisJaW50IGxlbiA9IGl0ZW1OYW1lLmxlbmd0aDsKKwlmb3IgKGludCBpID0gMCwgaiA9IGluZGV4OyBpIDwgbGVuOykKKwkgICAgLy8gSU1BUCB0b2tlbnMgYXJlIGNhc2UtaW5zZW5zaXRpdmUuIFdlIHN0b3JlIGl0ZW1OYW1lcyBpbgorCSAgICAvLyB1cHBlcmNhc2UsIHNvIGNvbnZlcnQgb3BlcmFuZCB0byB1cHBlcmNhc2UgYmVmb3JlIGNvbXBhcmluZy4KKwkgICAgaWYgKENoYXJhY3Rlci50b1VwcGVyQ2FzZSgoY2hhcilidWZmZXJbaisrXSkgIT0gaXRlbU5hbWVbaSsrXSkKKwkJcmV0dXJuIGZhbHNlOworCWluZGV4ICs9IGxlbjsKKwlyZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEb2VzIHRoZSBjdXJyZW50IGJ1ZmZlciBtYXRjaCB0aGUgZ2l2ZW4gaXRlbSBuYW1lPworICAgICAqIGl0ZW1OYW1lIGlzIHRoZSBuYW1lIG9mIHRoZSBJTUFQIGl0ZW0gdG8gY29tcGFyZSBhZ2FpbnN0LgorICAgICAqIE5PVEUgdGhhdCBpdGVtTmFtZSAqbXVzdCogYmUgYWxsIHVwcGVyY2FzZS4KKyAgICAgKiBJZiB0aGUgbWF0Y2ggaXMgc3VjY2Vzc2Z1bCwgdGhlIGJ1ZmZlciBwb2ludGVyIChpbmRleCkKKyAgICAgKiBpcyBpbmNyZW1lbnRlZCBwYXN0IHRoZSBtYXRjaGVkIGl0ZW0uCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIG1hdGNoKFN0cmluZyBpdGVtTmFtZSkgeworCWludCBsZW4gPSBpdGVtTmFtZS5sZW5ndGgoKTsKKwlmb3IgKGludCBpID0gMCwgaiA9IGluZGV4OyBpIDwgbGVuOykKKwkgICAgLy8gSU1BUCB0b2tlbnMgYXJlIGNhc2UtaW5zZW5zaXRpdmUuIFdlIHN0b3JlIGl0ZW1OYW1lcyBpbgorCSAgICAvLyB1cHBlcmNhc2UsIHNvIGNvbnZlcnQgb3BlcmFuZCB0byB1cHBlcmNhc2UgYmVmb3JlIGNvbXBhcmluZy4KKwkgICAgaWYgKENoYXJhY3Rlci50b1VwcGVyQ2FzZSgoY2hhcilidWZmZXJbaisrXSkgIT0KKwkJICAgIGl0ZW1OYW1lLmNoYXJBdChpKyspKQorCQlyZXR1cm4gZmFsc2U7CisJaW5kZXggKz0gbGVuOworCXJldHVybiB0cnVlOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9JRC5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL3Byb3RvY29sL0lELmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjZjYjg2NQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9JRC5qYXZhCkBAIC0wLDAgKzEsOTcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmltYXAucHJvdG9jb2w7CisKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBjb20uc3VuLm1haWwuaWFwLio7CisKKy8qKgorICogVGhpcyBjbGFzcyByZXByZXNlbnRzIHRoZSByZXNwb25zZSB0byB0aGUgSUQgY29tbWFuZC4gPHA+CisgKgorICogU2VlIDxBIEhSRUY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzI5NzEudHh0Ij5SRkMgMjk3MTwvQT4uCisgKgorICogQHNpbmNlIEphdmFNYWlsIDEuNS4xCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCisKK3B1YmxpYyBjbGFzcyBJRCB7CisKKyAgICBwcml2YXRlIE1hcDxTdHJpbmcsIFN0cmluZz4gc2VydmVyUGFyYW1zID0gbnVsbDsKKworICAgIC8qKgorICAgICAqIFBhcnNlIHRoZSBzZXJ2ZXIgcGFyYW1ldGVyIGxpc3Qgb3V0IG9mIHRoZSByZXNwb25zZS4KKyAgICAgKgorICAgICAqIEBwYXJhbQlyCXRoZSByZXNwb25zZQorICAgICAqIEBleGNlcHRpb24JUHJvdG9jb2xFeGNlcHRpb24JZm9yIHByb3RvY29sIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIElEKFJlc3BvbnNlIHIpIHRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJLy8gaWRfcmVzcG9uc2UgOjo9ICJJRCIgU1BBQ0UgaWRfcGFyYW1zX2xpc3QKKwkvLyBpZF9wYXJhbXNfbGlzdCA6Oj0gIigiICMoc3RyaW5nIFNQQUNFIG5zdHJpbmcpICIpIiAvIG5pbAorCS8vICAgICAgIDs7IGxpc3Qgb2YgZmllbGQgdmFsdWUgcGFpcnMKKworCXIuc2tpcFNwYWNlcygpOworCWludCBjID0gci5wZWVrQnl0ZSgpOworCWlmIChjID09ICdOJyB8fCBjID09ICduJykJLy8gYXNzdW1lIE5JTAorCSAgICByZXR1cm47CisKKwlpZiAoYyAhPSAnKCcpCisJICAgIHRocm93IG5ldyBQcm90b2NvbEV4Y2VwdGlvbigiTWlzc2luZyAnKCcgYXQgc3RhcnQgb2YgSUQiKTsKKworCXNlcnZlclBhcmFtcyA9IG5ldyBIYXNoTWFwPD4oKTsKKworCVN0cmluZ1tdIHYgPSByLnJlYWRTdHJpbmdMaXN0KCk7CisJaWYgKHYgIT0gbnVsbCkgeworCSAgICBmb3IgKGludCBpID0gMDsgaSA8IHYubGVuZ3RoOyBpICs9IDIpIHsKKwkJU3RyaW5nIG5hbWUgPSB2W2ldOworCQlpZiAobmFtZSA9PSBudWxsKQorCQkgICAgdGhyb3cgbmV3IFByb3RvY29sRXhjZXB0aW9uKCJJRCBmaWVsZCBuYW1lIG51bGwiKTsKKwkJaWYgKGkgKyAxID49IHYubGVuZ3RoKQorCQkgICAgdGhyb3cgbmV3IFByb3RvY29sRXhjZXB0aW9uKCJJRCBmaWVsZCB3aXRob3V0IHZhbHVlOiAiICsKKwkJCQkJCQkJCW5hbWUpOworCQlTdHJpbmcgdmFsdWUgPSB2W2kgKyAxXTsKKwkJc2VydmVyUGFyYW1zLnB1dChuYW1lLCB2YWx1ZSk7CisJICAgIH0KKwl9CisJc2VydmVyUGFyYW1zID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKHNlcnZlclBhcmFtcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBwYXJzZWQgc2VydmVyIHBhcmFtcy4KKyAgICAgKi8KKyAgICBNYXA8U3RyaW5nLCBTdHJpbmc+IGdldFNlcnZlclBhcmFtcygpIHsKKwlyZXR1cm4gc2VydmVyUGFyYW1zOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlcnQgdGhlIGNsaWVudCBwYXJhbWV0ZXJzIGludG8gYW4gYXJndW1lbnQgbGlzdCBmb3IgdGhlIElEIGNvbW1hbmQuCisgICAgICovCisgICAgc3RhdGljIEFyZ3VtZW50IGdldEFyZ3VtZW50TGlzdChNYXA8U3RyaW5nLFN0cmluZz4gY2xpZW50UGFyYW1zKSB7CisJQXJndW1lbnQgYXJnID0gbmV3IEFyZ3VtZW50KCk7CisJaWYgKGNsaWVudFBhcmFtcyA9PSBudWxsKSB7CisJICAgIGFyZy53cml0ZUF0b20oIk5JTCIpOworCSAgICByZXR1cm4gYXJnOworCX0KKwlBcmd1bWVudCBsaXN0ID0gbmV3IEFyZ3VtZW50KCk7CisJLy8gYWRkIHBhcmFtcyB0byBsaXN0CisJZm9yIChNYXAuRW50cnk8U3RyaW5nLCBTdHJpbmc+IGUgOiBjbGllbnRQYXJhbXMuZW50cnlTZXQoKSkgeworCSAgICBsaXN0LndyaXRlTlN0cmluZyhlLmdldEtleSgpKTsJLy8gYXNzdW1lIHRoZXNlIGFyZSBBU0NJSSBvbmx5CisJICAgIGxpc3Qud3JpdGVOU3RyaW5nKGUuZ2V0VmFsdWUoKSk7CisJfQorCWFyZy53cml0ZUFyZ3VtZW50KGxpc3QpOworCXJldHVybiBhcmc7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL3Byb3RvY29sL0lNQVBQcm90b2NvbC5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL3Byb3RvY29sL0lNQVBQcm90b2NvbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFjZDQ0YzgKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvcHJvdG9jb2wvSU1BUFByb3RvY29sLmphdmEKQEAgLTAsMCArMSwzMjkyIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5pbWFwLnByb3RvY29sOworCitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmEudXRpbC4qOworaW1wb3J0IGphdmEudGV4dC4qOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lio7CitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTGV2ZWw7CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5TdGFuZGFyZENoYXJzZXRzOworCitpbXBvcnQgamF2YXgubWFpbC4qOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuKjsKK2ltcG9ydCBqYXZheC5tYWlsLnNlYXJjaC4qOworCitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuUHJvcFV0aWw7CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuTWFpbExvZ2dlcjsKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5BU0NJSVV0aWxpdHk7CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuQkFTRTY0RW5jb2RlclN0cmVhbTsKK2ltcG9ydCBjb20uc3VuLm1haWwuaWFwLio7CitpbXBvcnQgY29tLnN1bi5tYWlsLmF1dGguTnRsbTsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC5pbWFwLkFDTDsKK2ltcG9ydCBjb20uc3VuLm1haWwuaW1hcC5SaWdodHM7CitpbXBvcnQgY29tLnN1bi5tYWlsLmltYXAuQXBwZW5kVUlEOworaW1wb3J0IGNvbS5zdW4ubWFpbC5pbWFwLkNvcHlVSUQ7CitpbXBvcnQgY29tLnN1bi5tYWlsLmltYXAuU29ydFRlcm07CitpbXBvcnQgY29tLnN1bi5tYWlsLmltYXAuUmVzeW5jRGF0YTsKK2ltcG9ydCBjb20uc3VuLm1haWwuaW1hcC5VdGlsaXR5OworCisvKioKKyAqIFRoaXMgY2xhc3MgZXh0ZW5kcyB0aGUgaWFwLlByb3RvY29sIG9iamVjdCBhbmQgaW1wbGVtZW50cyBJTUFQCisgKiBzZW1hbnRpY3MuIEluIGdlbmVyYWwsIHRoZXJlIGlzIGEgbWV0aG9kIGNvcnJlc3BvbmRpbmcgdG8gZWFjaAorICogSU1BUCBwcm90b2NvbCBjb21tYW5kLiBUaGUgdHlwaWNhbCBpbXBsZW1lbnRhdGlvbiBpc3N1ZXMgdGhlCisgKiBhcHByb3ByaWF0ZSBwcm90b2NvbCBjb21tYW5kLCBjb2xsZWN0cyBhbGwgcmVzcG9uc2VzLCBwcm9jZXNzZXMKKyAqIHRob3NlIHJlc3BvbnNlcyB0aGF0IGFyZSBzcGVjaWZpYyB0byB0aGlzIGNvbW1hbmQgYW5kIHRoZW4KKyAqIGRpc3BhdGNoZXMgdGhlIHJlc3QgKHRoZSB1bnNvbGljaXRlZCBvbmVzKSB0byB0aGUgZGlzcGF0Y2hlcgorICogdXNpbmcgdGhlIDxjb2RlPm5vdGlmeVJlc3BvbnNlSGFuZGxlcnMocik8L2NvZGU+LgorICoKKyAqIEBhdXRob3IgIEpvaG4gTWFuaQorICogQGF1dGhvciAgQmlsbCBTaGFubm9uCisgKi8KKworcHVibGljIGNsYXNzIElNQVBQcm90b2NvbCBleHRlbmRzIFByb3RvY29sIHsKKyAgICAKKyAgICBwcml2YXRlIGJvb2xlYW4gY29ubmVjdGVkID0gZmFsc2U7CS8vIGRpZCBjb25zdHJ1Y3RvciBzdWNjZWVkPworICAgIHByaXZhdGUgYm9vbGVhbiByZXYxID0gZmFsc2U7CS8vIFJFVjEgc2VydmVyID8KKyAgICBwcml2YXRlIGJvb2xlYW4gcmVmZXJyYWxFeGNlcHRpb247CS8vIHRocm93IGV4Y2VwdGlvbiBmb3IgSU1BUCBSRUZFUlJBTD8KKyAgICBwcml2YXRlIGJvb2xlYW4gbm9hdXRoZGVidWcgPSB0cnVlOwkvLyBoaWRlIGF1dGggaW5mbyBpbiBkZWJ1ZyBvdXRwdXQKKyAgICBwcml2YXRlIGJvb2xlYW4gYXV0aGVudGljYXRlZDsJLy8gYXV0aGVudGljYXRlZD8KKyAgICAvLyBXQVJOSU5HOiBhdXRoZW50aWNhdGVkIG1heSBiZSBzZXQgdG8gdHJ1ZSBpbiBzdXBlcmNsYXNzCisgICAgLy8JCWNvbnN0cnVjdG9yLCBkb24ndCBpbml0aWFsaXplIGl0IGhlcmUuCisKKyAgICBwcml2YXRlIE1hcDxTdHJpbmcsIFN0cmluZz4gY2FwYWJpbGl0aWVzOworICAgIC8vIFdBUk5JTkc6IGNhcGFiaWxpdGllcyBtYXkgYmUgaW5pdGlhbGl6ZWQgYXMgYSByZXN1bHQgb2Ygc3VwZXJjbGFzcworICAgIC8vCQljb25zdHJ1Y3RvciwgZG9uJ3QgaW5pdGlhbGl6ZSBpdCBoZXJlLgorICAgIHByaXZhdGUgTGlzdDxTdHJpbmc+IGF1dGhtZWNoczsKKyAgICAvLyBXQVJOSU5HOiBhdXRobWVjaHMgbWF5IGJlIGluaXRpYWxpemVkIGFzIGEgcmVzdWx0IG9mIHN1cGVyY2xhc3MKKyAgICAvLwkJY29uc3RydWN0b3IsIGRvbid0IGluaXRpYWxpemUgaXQgaGVyZS4KKyAgICBwcml2YXRlIGJvb2xlYW4gdXRmODsJCS8vIFVURi04IHN1cHBvcnQgZW5hYmxlZD8KKworICAgIHByb3RlY3RlZCBTZWFyY2hTZXF1ZW5jZSBzZWFyY2hTZXF1ZW5jZTsKKyAgICBwcm90ZWN0ZWQgU3RyaW5nW10gc2VhcmNoQ2hhcnNldHM7IAkvLyBhcnJheSBvZiBzZWFyY2ggY2hhcnNldHMKKworICAgIHByb3RlY3RlZCBTZXQ8U3RyaW5nPiBlbmFibGVkOwkvLyBlbmFibGVkIGNhcGFiaWxpdGllcyAtIFJGQyA1MTYxCisKKyAgICBwcml2YXRlIFN0cmluZyBuYW1lOworICAgIHByaXZhdGUgU2FzbEF1dGhlbnRpY2F0b3Igc2FzbEF1dGhlbnRpY2F0b3I7CS8vIGlmIFNBU0wgaXMgYmVpbmcgdXNlZAorICAgIHByaXZhdGUgU3RyaW5nIHByb3h5QXV0aFVzZXI7CS8vIHVzZXIgbmFtZSB1c2VkIHdpdGggUFJPWFlBVVRICisKKyAgICBwcml2YXRlIEJ5dGVBcnJheSBiYTsJCS8vIGEgYnVmZmVyIGZvciBmZXRjaEJvZHkKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBDUkxGID0geyAoYnl0ZSknXHInLCAoYnl0ZSknXG4nfTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEZldGNoSXRlbVtdIGZldGNoSXRlbXMgPSB7IH07CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAgKiBPcGVucyBhIGNvbm5lY3Rpb24gdG8gdGhlIGdpdmVuIGhvc3QgYXQgZ2l2ZW4gcG9ydC4KKyAgICAgKgorICAgICAqIEBwYXJhbQluYW1lCXRoZSBwcm90b2NvbCBuYW1lCisgICAgICogQHBhcmFtCWhvc3QJaG9zdCB0byBjb25uZWN0IHRvCisgICAgICogQHBhcmFtCXBvcnQJcG9ydCBudW1iZXIgdG8gY29ubmVjdCB0bworICAgICAqIEBwYXJhbQlwcm9wcwlQcm9wZXJ0aWVzIG9iamVjdCB1c2VkIGJ5IHRoaXMgcHJvdG9jb2wKKyAgICAgKiBAcGFyYW0JaXNTU0wJdHJ1ZSBpZiBTU0wgc2hvdWxkIGJlIHVzZWQKKyAgICAgKiBAcGFyYW0JbG9nZ2VyCXRoZSBNYWlsTG9nZ2VyIHRvIHVzZSBmb3IgZGVidWcgb3V0cHV0CisgICAgICogQGV4Y2VwdGlvbglJT0V4Y2VwdGlvbglmb3IgSS9PIGVycm9ycworICAgICAqIEBleGNlcHRpb24JUHJvdG9jb2xFeGNlcHRpb24JZm9yIHByb3RvY29sIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIElNQVBQcm90b2NvbChTdHJpbmcgbmFtZSwgU3RyaW5nIGhvc3QsIGludCBwb3J0LCAKKwkJCVByb3BlcnRpZXMgcHJvcHMsIGJvb2xlYW4gaXNTU0wsIE1haWxMb2dnZXIgbG9nZ2VyKQorCQkJdGhyb3dzIElPRXhjZXB0aW9uLCBQcm90b2NvbEV4Y2VwdGlvbiB7CisJc3VwZXIoaG9zdCwgcG9ydCwgcHJvcHMsICJtYWlsLiIgKyBuYW1lLCBpc1NTTCwgbG9nZ2VyKTsKKworCXRyeSB7CisJICAgIHRoaXMubmFtZSA9IG5hbWU7CisJICAgIG5vYXV0aGRlYnVnID0KKwkJIVByb3BVdGlsLmdldEJvb2xlYW5Qcm9wZXJ0eShwcm9wcywgIm1haWwuZGVidWcuYXV0aCIsIGZhbHNlKTsKKworCSAgICAvLyBpbiBjYXNlIGl0IHdhcyBub3QgaW5pdGlhbGl6ZWQgaW4gcHJvY2Vzc0dyZWV0aW5nCisJICAgIHJlZmVycmFsRXhjZXB0aW9uID0gUHJvcFV0aWwuZ2V0Qm9vbGVhblByb3BlcnR5KHByb3BzLAorCQkJCXByZWZpeCArICIucmVmZXJyYWxleGNlcHRpb24iLCBmYWxzZSk7CisKKwkgICAgaWYgKGNhcGFiaWxpdGllcyA9PSBudWxsKQorCQljYXBhYmlsaXR5KCk7CisKKwkgICAgaWYgKGhhc0NhcGFiaWxpdHkoIklNQVA0cmV2MSIpKQorCQlyZXYxID0gdHJ1ZTsKKworCSAgICBzZWFyY2hDaGFyc2V0cyA9IG5ldyBTdHJpbmdbMl07IC8vIDIsIGZvciBub3cuCisJICAgIHNlYXJjaENoYXJzZXRzWzBdID0gIlVURi04IjsKKwkgICAgc2VhcmNoQ2hhcnNldHNbMV0gPSBNaW1lVXRpbGl0eS5taW1lQ2hhcnNldCgKKwkJCQkgICAgTWltZVV0aWxpdHkuZ2V0RGVmYXVsdEphdmFDaGFyc2V0KCkKKwkJCQkpOworCisJICAgIGNvbm5lY3RlZCA9IHRydWU7CS8vIG11c3QgYmUgbGFzdCBzdGF0ZW1lbnQgaW4gY29uc3RydWN0b3IKKwl9IGZpbmFsbHkgeworCSAgICAvKgorCSAgICAgKiBJZiB3ZSBnZXQgaGVyZSBiZWNhdXNlIGFuIGV4Y2VwdGlvbiB3YXMgdGhyb3duLCB3ZSBuZWVkCisJICAgICAqIHRvIGRpc2Nvbm5lY3QgdG8gYXZvaWQgbGVhdmluZyBhIGNvbm5lY3RlZCBzb2NrZXQgdGhhdAorCSAgICAgKiBubyBvbmUgd2lsbCBiZSBhYmxlIHRvIHVzZSBiZWNhdXNlIHRoaXMgb2JqZWN0IHdhcyBuZXZlcgorCSAgICAgKiBjb21wbGV0ZWx5IGNvbnN0cnVjdGVkLgorCSAgICAgKi8KKwkgICAgaWYgKCFjb25uZWN0ZWQpCisJCWRpc2Nvbm5lY3QoKTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IgZm9yIGRlYnVnZ2luZy4KKyAgICAgKgorICAgICAqIEBwYXJhbQlpbgl0aGUgSW5wdXRTdHJlYW0gZnJvbSB3aGljaCB0byByZWFkCisgICAgICogQHBhcmFtCW91dAl0aGUgUHJpbnRTdHJlYW0gdG8gd2hpY2ggdG8gd3JpdGUKKyAgICAgKiBAcGFyYW0JcHJvcHMJUHJvcGVydGllcyBvYmplY3QgdXNlZCBieSB0aGlzIHByb3RvY29sCisgICAgICogQHBhcmFtCWRlYnVnCXRydWUgdG8gZW5hYmxlIGRlYnVnZ2luZyBvdXRwdXQKKyAgICAgKiBAZXhjZXB0aW9uCUlPRXhjZXB0aW9uCWZvciBJL08gZXJyb3JzCisgICAgICovCisgICAgcHVibGljIElNQVBQcm90b2NvbChJbnB1dFN0cmVhbSBpbiwgUHJpbnRTdHJlYW0gb3V0LAorCQkJUHJvcGVydGllcyBwcm9wcywgYm9vbGVhbiBkZWJ1ZykKKwkJCXRocm93cyBJT0V4Y2VwdGlvbiB7CisJc3VwZXIoaW4sIG91dCwgcHJvcHMsIGRlYnVnKTsKKworCXRoaXMubmFtZSA9ICJpbWFwIjsKKwlub2F1dGhkZWJ1ZyA9CisJICAgICFQcm9wVXRpbC5nZXRCb29sZWFuUHJvcGVydHkocHJvcHMsICJtYWlsLmRlYnVnLmF1dGgiLCBmYWxzZSk7CisKKwlpZiAoY2FwYWJpbGl0aWVzID09IG51bGwpCisJICAgIGNhcGFiaWxpdGllcyA9IG5ldyBIYXNoTWFwPD4oKTsKKworCXNlYXJjaENoYXJzZXRzID0gbmV3IFN0cmluZ1syXTsgLy8gMiwgZm9yIG5vdy4KKwlzZWFyY2hDaGFyc2V0c1swXSA9ICJVVEYtOCI7CisJc2VhcmNoQ2hhcnNldHNbMV0gPSBNaW1lVXRpbGl0eS5taW1lQ2hhcnNldCgKKwkJCQlNaW1lVXRpbGl0eS5nZXREZWZhdWx0SmF2YUNoYXJzZXQoKQorCQkJICAgICk7CisKKwljb25uZWN0ZWQgPSB0cnVlOwkvLyBtdXN0IGJlIGxhc3Qgc3RhdGVtZW50IGluIGNvbnN0cnVjdG9yCisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIGFuIGFycmF5IG9mIEZldGNoSXRlbSBvYmplY3RzIGRlc2NyaWJpbmcgdGhlCisgICAgICogRkVUQ0ggaXRlbXMgc3VwcG9ydGVkIGJ5IHRoaXMgcHJvdG9jb2wuICBTdWJjbGFzc2VzIG1heQorICAgICAqIG92ZXJyaWRlIHRoaXMgbWV0aG9kIHRvIGNvbWJpbmUgdGhlaXIgRmV0Y2hJdGVtcyB3aXRoCisgICAgICogdGhlIEZldGNoSXRlbXMgcmV0dXJuZWQgYnkgdGhlIHN1cGVyY2xhc3MuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCWFuIGFycmF5IG9mIEZldGNoSXRlbSBvYmplY3RzCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNC42CisgICAgICovCisgICAgcHVibGljIEZldGNoSXRlbVtdIGdldEZldGNoSXRlbXMoKSB7CisJcmV0dXJuIGZldGNoSXRlbXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ0FQQUJJTElUWSBjb21tYW5kLgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbglQcm90b2NvbEV4Y2VwdGlvbglmb3IgcHJvdG9jb2wgZmFpbHVyZXMKKyAgICAgKiBAc2VlICJSRkMyMDYwLCBzZWN0aW9uIDYuMS4xIgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNhcGFiaWxpdHkoKSB0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCS8vIENoZWNrIENBUEFCSUxJVFkKKwlSZXNwb25zZVtdIHIgPSBjb21tYW5kKCJDQVBBQklMSVRZIiwgbnVsbCk7CisJUmVzcG9uc2UgcmVzcG9uc2UgPSByW3IubGVuZ3RoLTFdOworCisJaWYgKHJlc3BvbnNlLmlzT0soKSkKKwkgICAgaGFuZGxlQ2FwYWJpbGl0eVJlc3BvbnNlKHIpOworCWhhbmRsZVJlc3VsdChyZXNwb25zZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSGFuZGxlIGFueSB1bnRhZ2dlZCBDQVBBQklMSVRZIHJlc3BvbnNlIGluIHRoZSBSZXNwb25zZSBhcnJheS4KKyAgICAgKgorICAgICAqIEBwYXJhbQlyCXRoZSByZXNwb25zZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBoYW5kbGVDYXBhYmlsaXR5UmVzcG9uc2UoUmVzcG9uc2VbXSByKSB7CisJYm9vbGVhbiBmaXJzdCA9IHRydWU7CisJZm9yIChpbnQgaSA9IDAsIGxlbiA9IHIubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHsKKwkgICAgaWYgKCEocltpXSBpbnN0YW5jZW9mIElNQVBSZXNwb25zZSkpCisJCWNvbnRpbnVlOworCisJICAgIElNQVBSZXNwb25zZSBpciA9IChJTUFQUmVzcG9uc2UpcltpXTsKKworCSAgICAvLyBIYW5kbGUgKmFsbCogdW50YWdnZWQgQ0FQQUJJTElUWSByZXNwb25zZXMuCisJICAgIC8vIFRob3VnaCB0aGUgc3BlYyBzZWVtaW5nbHkgc3RhdGVzIHRoYXQgb25seQorCSAgICAvLyBvbmUgQ0FQQUJJTElUWSByZXNwb25zZSBzdHJpbmcgaXMgYWxsb3dlZCAoNi4xLjEpLAorCSAgICAvLyBzb21lIHNlcnZlciB2ZW5kb3JzIGNsYWltIG90aGVyd2lzZS4KKwkgICAgaWYgKGlyLmtleUVxdWFscygiQ0FQQUJJTElUWSIpKSB7CisJCWlmIChmaXJzdCkgeworCQkgICAgLy8gY2xlYXIgb3V0IGN1cnJlbnQgd2hlbiBmaXJzdCByZXNwb25zZSBzZWVuCisJCSAgICBjYXBhYmlsaXRpZXMgPSBuZXcgSGFzaE1hcDw+KDEwKTsKKwkJICAgIGF1dGhtZWNocyA9IG5ldyBBcnJheUxpc3Q8Pig1KTsKKwkJICAgIGZpcnN0ID0gZmFsc2U7CisJCX0KKwkJcGFyc2VDYXBhYmlsaXRpZXMoaXIpOworCSAgICB9CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIElmIHRoZSByZXNwb25zZSBjb250YWlucyBhIENBUEFCSUxJVFkgcmVzcG9uc2UgY29kZSwgZXh0cmFjdAorICAgICAqIGl0IGFuZCBzYXZlIHRoZSBjYXBhYmlsaXRpZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jcgl0aGUgcmVzcG9uc2UKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRDYXBhYmlsaXRpZXMoUmVzcG9uc2UgcikgeworCWJ5dGUgYjsKKwl3aGlsZSAoKGIgPSByLnJlYWRCeXRlKCkpID4gMCAmJiBiICE9IChieXRlKSdbJykKKwkgICAgOworCWlmIChiID09IDApCisJICAgIHJldHVybjsKKwlTdHJpbmcgczsKKwlzID0gci5yZWFkQXRvbSgpOworCWlmICghcy5lcXVhbHNJZ25vcmVDYXNlKCJDQVBBQklMSVRZIikpCisJICAgIHJldHVybjsKKwljYXBhYmlsaXRpZXMgPSBuZXcgSGFzaE1hcDw+KDEwKTsKKwlhdXRobWVjaHMgPSBuZXcgQXJyYXlMaXN0PD4oNSk7CisJcGFyc2VDYXBhYmlsaXRpZXMocik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2UgdGhlIGNhcGFiaWxpdGllcyBmcm9tIGEgQ0FQQUJJTElUWSByZXNwb25zZSBvciBmcm9tCisgICAgICogYSBDQVBBQklMSVRZIHJlc3BvbnNlIGNvZGUgYXR0YWNoZWQgdG8gKGUuZy4pIGFuIE9LIHJlc3BvbnNlLgorICAgICAqCisgICAgICogQHBhcmFtCXIJdGhlIENBUEFCSUxJVFkgcmVzcG9uc2UKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBwYXJzZUNhcGFiaWxpdGllcyhSZXNwb25zZSByKSB7CisJU3RyaW5nIHM7CisJd2hpbGUgKChzID0gci5yZWFkQXRvbSgpKSAhPSBudWxsKSB7CisJICAgIGlmIChzLmxlbmd0aCgpID09IDApIHsKKwkJaWYgKHIucGVla0J5dGUoKSA9PSAoYnl0ZSknXScpCisJCSAgICBicmVhazsKKwkJLyoKKwkJICogUHJvYmFibHkgZm91bmQgc29tZXRoaW5nIGhlcmUgdGhhdCdzIG5vdCBhbiBhdG9tLgorCQkgKiBSYXRoZXIgdGhhbiBsb29wIGZvcmV2ZXIgb3IgZmFpbCBjb21wbGV0ZWx5LCB3ZSdsbAorCQkgKiB0cnkgdG8gc2tpcCB0aGlzIGJvZ3VzIGNhcGFiaWxpdHkuICBUaGlzIGlzIGtub3duCisJCSAqIHRvIGhhcHBlbiB3aXRoOgorCQkgKiAgIE5ldHNjYXBlIE1lc3NhZ2luZyBTZXJ2ZXIgNC4wMyAoYnVpbHQgQXByIDI3IDE5OTkpCisJCSAqIHRoYXQgcmV0dXJuczoKKwkJICogICAqIENBUEFCSUxJVFkgKiBDQVBBQklMSVRZIElNQVA0IElNQVA0cmV2MSAuLi4KKwkJICogVGhlICIqIiBpbiB0aGUgbWlkZGxlIG9mIHRoZSBjYXBhYmlsaXR5IGxpc3QgY2F1c2VzCisJCSAqIHVzIHRvIGxvb3AgZm9yZXZlciBoZXJlLgorCQkgKi8KKwkJci5za2lwVG9rZW4oKTsKKwkgICAgfSBlbHNlIHsKKwkJY2FwYWJpbGl0aWVzLnB1dChzLnRvVXBwZXJDYXNlKExvY2FsZS5FTkdMSVNIKSwgcyk7CisJCWlmIChzLnJlZ2lvbk1hdGNoZXModHJ1ZSwgMCwgIkFVVEg9IiwgMCwgNSkpIHsKKwkJICAgIGF1dGhtZWNocy5hZGQocy5zdWJzdHJpbmcoNSkpOworCQkgICAgaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkUpKQorCQkJbG9nZ2VyLmZpbmUoIkFVVEg6ICIgKyBzLnN1YnN0cmluZyg1KSk7CisJCX0KKwkgICAgfQorCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVjayB0aGUgZ3JlZXRpbmcgd2hlbiBmaXJzdCBjb25uZWN0aW5nOyBsb29rIGZvciBQUkVBVVRIIHJlc3BvbnNlLgorICAgICAqCisgICAgICogQHBhcmFtCXIJdGhlIGdyZWV0aW5nIHJlc3BvbnNlCisgICAgICogQGV4Y2VwdGlvbglQcm90b2NvbEV4Y2VwdGlvbglmb3IgcHJvdG9jb2wgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBwcm9jZXNzR3JlZXRpbmcoUmVzcG9uc2UgcikgdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKwlpZiAoci5pc0JZRSgpKSB7CisJICAgIGNoZWNrUmVmZXJyYWwocik7CS8vIG1heSB0aHJvdyBleGNlcHRpb24KKwkgICAgdGhyb3cgbmV3IENvbm5lY3Rpb25FeGNlcHRpb24odGhpcywgcik7CisJfQorCWlmIChyLmlzT0soKSkgewkJCS8vIGNoZWNrIGlmIGl0J3MgT0sKKwkgICAgLy8gWFhYIC0gaXMgYSBSRUZFUlJBTCByZXNwb25zZSBjb2RlIHJlYWxseSBhbGxvd2VkIGhlcmU/CisJICAgIC8vIFhYWCAtIHJlZmVycmFsRXhjZXB0aW9uIGhhc24ndCBiZWVuIGluaXRpYWxpemVkIGluIGMndG9yIHlldAorCSAgICByZWZlcnJhbEV4Y2VwdGlvbiA9IFByb3BVdGlsLmdldEJvb2xlYW5Qcm9wZXJ0eShwcm9wcywKKwkJCQlwcmVmaXggKyAiLnJlZmVycmFsZXhjZXB0aW9uIiwgZmFsc2UpOworCSAgICBpZiAocmVmZXJyYWxFeGNlcHRpb24pCisJCWNoZWNrUmVmZXJyYWwocik7CisJICAgIHNldENhcGFiaWxpdGllcyhyKTsKKwkgICAgcmV0dXJuOworCX0KKwkvLyBvbmx5IG90aGVyIGNob2ljZSBpcyBQUkVBVVRICisJYXNzZXJ0IHIgaW5zdGFuY2VvZiBJTUFQUmVzcG9uc2U7CisJSU1BUFJlc3BvbnNlIGlyID0gKElNQVBSZXNwb25zZSlyOworCWlmIChpci5rZXlFcXVhbHMoIlBSRUFVVEgiKSkgeworCSAgICBhdXRoZW50aWNhdGVkID0gdHJ1ZTsKKwkgICAgc2V0Q2FwYWJpbGl0aWVzKHIpOworCX0gZWxzZSB7CisJICAgIGRpc2Nvbm5lY3QoKTsKKwkgICAgdGhyb3cgbmV3IENvbm5lY3Rpb25FeGNlcHRpb24odGhpcywgcik7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrIGZvciBhbiBJTUFQIGxvZ2luIFJFRkVSUkFMIHJlc3BvbnNlIGNvZGUuCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uCUlNQVBSZWZlcnJhbEV4Y2VwdGlvbglpZiBSRUZFUlJBTCByZXNwb25zZSBjb2RlIGZvdW5kCisgICAgICogQHNlZSAiUkZDIDIyMjEiCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrUmVmZXJyYWwoUmVzcG9uc2UgcikgdGhyb3dzIElNQVBSZWZlcnJhbEV4Y2VwdGlvbiB7CisJU3RyaW5nIHMgPSByLmdldFJlc3QoKTsJLy8gZ2V0IHRoZSB0ZXh0IGFmdGVyIHRoZSByZXNwb25zZQorCWlmIChzLnN0YXJ0c1dpdGgoIlsiKSkgewkvLyBhIHJlc3BvbnNlIGNvZGUKKwkgICAgaW50IGkgPSBzLmluZGV4T2YoJyAnKTsKKwkgICAgaWYgKGkgPiAwICYmIHMuc3Vic3RyaW5nKDEsIGkpLmVxdWFsc0lnbm9yZUNhc2UoIlJFRkVSUkFMIikpIHsKKwkJU3RyaW5nIHVybCwgbXNnOworCQlpbnQgaiA9IHMuaW5kZXhPZignXScpOworCQlpZiAoaiA+IDApIHsJLy8gc2hvdWxkIGFsd2F5cyBiZSB0cnVlOworCQkgICAgdXJsID0gcy5zdWJzdHJpbmcoaSArIDEsIGopOworCQkgICAgbXNnID0gcy5zdWJzdHJpbmcoaiArIDEpLnRyaW0oKTsKKwkJfSBlbHNlIHsKKwkJICAgIHVybCA9IHMuc3Vic3RyaW5nKGkgKyAxKTsKKwkJICAgIG1zZyA9ICIiOworCQl9CisJCWlmIChyLmlzQllFKCkpCisJCSAgICBkaXNjb25uZWN0KCk7CisJCXRocm93IG5ldyBJTUFQUmVmZXJyYWxFeGNlcHRpb24obXNnLCB1cmwpOworCSAgICB9CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIGNvbm5lY3Rpb24gaGFzIGJlZW4gYXV0aGVudGljYXRlZCwKKyAgICAgKiBlaXRoZXIgZHVlIHRvIGEgc3VjY2Vzc2Z1bCBsb2dpbiwgb3IgZHVlIHRvIGEgUFJFQVVUSCBncmVldGluZyByZXNwb25zZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdHJ1ZSBpZiB0aGUgY29ubmVjdGlvbiBoYXMgYmVlbiBhdXRoZW50aWNhdGVkCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNBdXRoZW50aWNhdGVkKCkgeworCXJldHVybiBhdXRoZW50aWNhdGVkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhpcyBpcyBhbiBJTUFQNHJldjEgc2VydmVyCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRydWUgaWYgdGhpcyBpcyBhbiBJTUFQNHJldjEgc2VydmVyCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNSRVYxKCkgeworCXJldHVybiByZXYxOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgd2hldGhlciB0aGlzIFByb3RvY29sIHN1cHBvcnRzIG5vbi1zeW5jaHJvbml6aW5nIGxpdGVyYWxzLgorICAgICAqCisgICAgICogQHJldHVybgl0cnVlIGlmIG5vbi1zeW5jaHJvbml6aW5nIGxpdGVyYWxzIGFyZSBzdXBwb3J0ZWQKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBzdXBwb3J0c05vblN5bmNMaXRlcmFscygpIHsKKwlyZXR1cm4gaGFzQ2FwYWJpbGl0eSgiTElURVJBTCsiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkIGEgcmVzcG9uc2UgZnJvbSB0aGUgc2VydmVyLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgcmVzcG9uc2UKKyAgICAgKiBAZXhjZXB0aW9uCUlPRXhjZXB0aW9uCWZvciBJL08gZXJyb3JzCisgICAgICogQGV4Y2VwdGlvbglQcm90b2NvbEV4Y2VwdGlvbglmb3IgcHJvdG9jb2wgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgUmVzcG9uc2UgcmVhZFJlc3BvbnNlKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBQcm90b2NvbEV4Y2VwdGlvbiB7CisJLy8gYXNzZXJ0IFRocmVhZC5ob2xkc0xvY2sodGhpcyk7CisJLy8gY2FuJ3QgYXNzZXJ0IGJlY2F1c2UgaXQncyBjYWxsZWQgZnJvbSBjb25zdHJ1Y3RvcgorCUlNQVBSZXNwb25zZSByID0gbmV3IElNQVBSZXNwb25zZSh0aGlzKTsKKwlpZiAoci5rZXlFcXVhbHMoIkZFVENIIikpCisJICAgIHIgPSBuZXcgRmV0Y2hSZXNwb25zZShyLCBnZXRGZXRjaEl0ZW1zKCkpOworCXJldHVybiByOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrIHdoZXRoZXIgdGhlIGdpdmVuIGNhcGFiaWxpdHkgaXMgc3VwcG9ydGVkIGJ5CisgICAgICogdGhpcyBzZXJ2ZXIuIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgc28sIG90aGVyd2lzZQorICAgICAqIHJldHVybnMgZmFsc2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0JYwl0aGUgY2FwYWJpbGl0eSBuYW1lCisgICAgICogQHJldHVybgkJdHJ1ZSBpZiB0aGUgc2VydmVyIGhhcyB0aGUgY2FwYWJpbGl0eQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGhhc0NhcGFiaWxpdHkoU3RyaW5nIGMpIHsKKwlpZiAoYy5lbmRzV2l0aCgiKiIpKSB7CisJICAgIGMgPSBjLnN1YnN0cmluZygwLCBjLmxlbmd0aCgpIC0gMSkudG9VcHBlckNhc2UoTG9jYWxlLkVOR0xJU0gpOworCSAgICBJdGVyYXRvcjxTdHJpbmc+IGl0ID0gY2FwYWJpbGl0aWVzLmtleVNldCgpLml0ZXJhdG9yKCk7CisJICAgIHdoaWxlIChpdC5oYXNOZXh0KCkpIHsKKwkJaWYgKGl0Lm5leHQoKS5zdGFydHNXaXRoKGMpKQorCQkgICAgcmV0dXJuIHRydWU7CisJICAgIH0KKwkgICAgcmV0dXJuIGZhbHNlOworCX0KKwlyZXR1cm4gY2FwYWJpbGl0aWVzLmNvbnRhaW5zS2V5KGMudG9VcHBlckNhc2UoTG9jYWxlLkVOR0xJU0gpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIG1hcCBvZiBjYXBhYmlsaXRpZXMgcmV0dXJuZWQgYnkgdGhlIHNlcnZlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIE1hcCBvZiBjYXBhYmlsaXRpZXMKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS40LjEKKyAgICAgKi8KKyAgICBwdWJsaWMgTWFwPFN0cmluZywgU3RyaW5nPiBnZXRDYXBhYmlsaXRpZXMoKSB7CisJcmV0dXJuIGNhcGFiaWxpdGllczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEb2VzIHRoZSBzZXJ2ZXIgc3VwcG9ydCBVVEYtOD8KKyAgICAgKgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjYuMAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHN1cHBvcnRzVXRmOCgpIHsKKwlyZXR1cm4gdXRmODsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9zZSBzb2NrZXQgY29ubmVjdGlvbi4KKyAgICAgKgorICAgICAqIFRoaXMgbWV0aG9kIGp1c3QgbWFrZXMgdGhlIFByb3RvY29sLmRpc2Nvbm5lY3QoKSBtZXRob2QKKyAgICAgKiBwdWJsaWMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZGlzY29ubmVjdCgpIHsKKwlzdXBlci5kaXNjb25uZWN0KCk7CisJYXV0aGVudGljYXRlZCA9IGZhbHNlOwkvLyBqdXN0IGluIGNhc2UKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgTk9PUCBjb21tYW5kLgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbglQcm90b2NvbEV4Y2VwdGlvbglmb3IgcHJvdG9jb2wgZmFpbHVyZXMKKyAgICAgKiBAc2VlICJSRkMyMDYwLCBzZWN0aW9uIDYuMS4yIgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIG5vb3AoKSB0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCWxvZ2dlci5maW5lKCJJTUFQUHJvdG9jb2wgbm9vcCIpOworCXNpbXBsZUNvbW1hbmQoIk5PT1AiLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMT0dPVVQgQ29tbWFuZC4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24JUHJvdG9jb2xFeGNlcHRpb24JZm9yIHByb3RvY29sIGZhaWx1cmVzCisgICAgICogQHNlZSAiUkZDMjA2MCwgc2VjdGlvbiA2LjEuMyIKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBsb2dvdXQoKSB0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCXRyeSB7CisJICAgIFJlc3BvbnNlW10gciA9IGNvbW1hbmQoIkxPR09VVCIsIG51bGwpOworCisJICAgIGF1dGhlbnRpY2F0ZWQgPSBmYWxzZTsKKwkgICAgLy8gZGlzcGF0Y2ggYW55IHVuc29saWNpdGVkIHJlc3BvbnNlcy4KKwkgICAgLy8gIE5PVEUgdGhhdCB0aGUgQllFIHJlc3BvbnNlIGlzIGRpc3BhdGNoZWQgaGVyZSBhcyB3ZWxsCisJICAgIG5vdGlmeVJlc3BvbnNlSGFuZGxlcnMocik7CisJfSBmaW5hbGx5IHsKKwkgICAgZGlzY29ubmVjdCgpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMT0dJTiBDb21tYW5kLgorICAgICAqIAorICAgICAqIEBwYXJhbSAgdQkJdGhlIHVzZXJuYW1lCisgICAgICogQHBhcmFtICBwCQl0aGUgcGFzc3dvcmQKKyAgICAgKiBAdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIGFzIHRocm93biBieSB7QGxpbmsgUHJvdG9jb2wjaGFuZGxlUmVzdWx0fS4KKyAgICAgKiBAc2VlICJSRkMyMDYwLCBzZWN0aW9uIDYuMi4yIgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGxvZ2luKFN0cmluZyB1LCBTdHJpbmcgcCkgdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKwlBcmd1bWVudCBhcmdzID0gbmV3IEFyZ3VtZW50KCk7CisJYXJncy53cml0ZVN0cmluZyh1KTsKKwlhcmdzLndyaXRlU3RyaW5nKHApOworCisJUmVzcG9uc2VbXSByID0gbnVsbDsKKwl0cnkgeworCSAgICBpZiAobm9hdXRoZGVidWcgJiYgaXNUcmFjaW5nKCkpIHsKKwkJbG9nZ2VyLmZpbmUoIkxPR0lOIGNvbW1hbmQgdHJhY2Ugc3VwcHJlc3NlZCIpOworCQlzdXNwZW5kVHJhY2luZygpOworCSAgICB9CisJICAgIHIgPSBjb21tYW5kKCJMT0dJTiIsIGFyZ3MpOworCX0gZmluYWxseSB7CisJICAgIHJlc3VtZVRyYWNpbmcoKTsKKwl9CisKKwkvLyBoYW5kbGUgYW4gaWxsZWdhbCBidXQgbm90IHVuY29tbW9uIHVudGFnZ2VkIENBUEFCSUxUWSByZXNwb25zZQorCWhhbmRsZUNhcGFiaWxpdHlSZXNwb25zZShyKTsKKworCS8vIGRpc3BhdGNoIHVudGFnZ2VkIHJlc3BvbnNlcworCW5vdGlmeVJlc3BvbnNlSGFuZGxlcnMocik7CisKKwkvLyBIYW5kbGUgcmVzdWx0IG9mIHRoaXMgY29tbWFuZAorCWlmIChub2F1dGhkZWJ1ZyAmJiBpc1RyYWNpbmcoKSkKKwkgICAgbG9nZ2VyLmZpbmUoIkxPR0lOIGNvbW1hbmQgcmVzdWx0OiAiICsgcltyLmxlbmd0aC0xXSk7CisJaGFuZGxlTG9naW5SZXN1bHQocltyLmxlbmd0aC0xXSk7CisJLy8gSWYgdGhlIHJlc3BvbnNlIGluY2x1ZGVzIGEgQ0FQQUJJTElUWSByZXNwb25zZSBjb2RlLCBwcm9jZXNzIGl0CisJc2V0Q2FwYWJpbGl0aWVzKHJbci5sZW5ndGgtMV0pOworCS8vIGlmIHdlIGdldCB0aGlzIGZhciB3aXRob3V0IGFuIGV4Y2VwdGlvbiwgd2UncmUgYXV0aGVudGljYXRlZAorCWF1dGhlbnRpY2F0ZWQgPSB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBBVVRIRU5USUNBVEUgY29tbWFuZCB3aXRoIEFVVEg9TE9HSU4gYXV0aGVudGljYXRlIHNjaGVtZQorICAgICAqCisgICAgICogQHBhcmFtICB1CQl0aGUgdXNlcm5hbWUKKyAgICAgKiBAcGFyYW0gIHAJCXRoZSBwYXNzd29yZAorICAgICAqIEB0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24gYXMgdGhyb3duIGJ5IHtAbGluayBQcm90b2NvbCNoYW5kbGVSZXN1bHR9LgorICAgICAqIEBzZWUgIlJGQzIwNjAsIHNlY3Rpb24gNi4yLjEiCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGF1dGhsb2dpbihTdHJpbmcgdSwgU3RyaW5nIHApCisJCQkJdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKwlMaXN0PFJlc3BvbnNlPiB2ID0gbmV3IEFycmF5TGlzdDw+KCk7CisJU3RyaW5nIHRhZyA9IG51bGw7CisJUmVzcG9uc2UgciA9IG51bGw7CisJYm9vbGVhbiBkb25lID0gZmFsc2U7CisKKwl0cnkgeworCisJaWYgKG5vYXV0aGRlYnVnICYmIGlzVHJhY2luZygpKSB7CisJICAgIGxvZ2dlci5maW5lKCJBVVRIRU5USUNBVEUgTE9HSU4gY29tbWFuZCB0cmFjZSBzdXBwcmVzc2VkIik7CisJICAgIHN1c3BlbmRUcmFjaW5nKCk7CisJfQorCisJdHJ5IHsKKwkgICAgdGFnID0gd3JpdGVDb21tYW5kKCJBVVRIRU5USUNBVEUgTE9HSU4iLCBudWxsKTsKKwl9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKwkgICAgLy8gQ29udmVydCB0aGlzIGludG8gYSBCWUUgcmVzcG9uc2UKKwkgICAgciA9IFJlc3BvbnNlLmJ5ZVJlc3BvbnNlKGV4KTsKKwkgICAgZG9uZSA9IHRydWU7CisJfQorCisJT3V0cHV0U3RyZWFtIG9zID0gZ2V0T3V0cHV0U3RyZWFtKCk7IC8vIHN0cmVhbSB0byBJTUFQIHNlcnZlcgorCisJLyogV3JhcCBhIEJBU0U2NEVuY29kZXIgYXJvdW5kIGEgQnl0ZUFycmF5T3V0cHV0c3RyZWFtCisJICogdG8gY3JhZnQgYjY0IGVuY29kZWQgdXNlcm5hbWUgYW5kIHBhc3N3b3JkIHN0cmluZ3MKKwkgKgorCSAqIE5vdGUgdGhhdCB0aGUgZW5jb2RlZCBieXRlcyBzaG91bGQgYmUgc2VudCAiYXMtaXMiIHRvIHRoZQorCSAqIHNlcnZlciwgKm5vdCogYXMgbGl0ZXJhbHMgb3IgcXVvdGVkLXN0cmluZ3MuCisJICoKKwkgKiBBbHNvIG5vdGUgdGhhdCB1bmxpa2UgdGhlIEI2NCBkZWZpbml0aW9uIGluIE1JTUUsIENSTEZzIAorCSAqIHNob3VsZCAqbm90KiBiZSBpbnNlcnRlZCBkdXJpbmcgdGhlIGVuY29kaW5nIHByb2Nlc3MuIFNvLCBJCisJICogdXNlIEludGVnZXIuTUFYX1ZBTFVFICgweDdmZmZmZmZmICg+IDFHKSkgYXMgdGhlIGJ5dGVzUGVyTGluZSwKKwkgKiB3aGljaCBzaG91bGQgYmUgc3VmZmljaWVudGx5IGxhcmdlICEKKwkgKgorCSAqIEZpbmFsbHksIGZvcm1hdCB0aGUgbGluZSBpbiBhIGJ1ZmZlciBzbyBpdCBjYW4gYmUgc2VudCBhcworCSAqIGEgc2luZ2xlIHBhY2tldCwgdG8gYXZvaWQgdHJpZ2dlcmluZyBhIGJ1ZyBpbiBTVU4ncyBTSU1TIDIuMAorCSAqIHNlcnZlciBjYXVzZWQgYnkgcGF0Y2ggMTA1MzQ2LgorCSAqLworCisJQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKwlPdXRwdXRTdHJlYW0gYjY0b3MgPSBuZXcgQkFTRTY0RW5jb2RlclN0cmVhbShib3MsIEludGVnZXIuTUFYX1ZBTFVFKTsKKwlib29sZWFuIGZpcnN0ID0gdHJ1ZTsKKworCXdoaWxlICghZG9uZSkgeyAvLyBsb29wIHRpbGwgd2UgYXJlIGRvbmUKKwkgICAgdHJ5IHsKKwkJciA9IHJlYWRSZXNwb25zZSgpOworCSAgICAJaWYgKHIuaXNDb250aW51YXRpb24oKSkgeworCQkgICAgLy8gU2VydmVyIGNoYWxsZW5nZSAuLgorCQkgICAgU3RyaW5nIHM7CisJCSAgICBpZiAoZmlyc3QpIHsgLy8gU2VuZCBlbmNvZGVkIHVzZXJuYW1lCisJCQlzID0gdTsKKwkJCWZpcnN0ID0gZmFsc2U7CisJCSAgICB9IGVsc2UgCS8vIFNlbmQgZW5jb2RlZCBwYXNzd29yZAorCQkJcyA9IHA7CisJCSAgICAKKwkJICAgIC8vIG9idGFpbiBiNjQgZW5jb2RlZCBieXRlcworCQkgICAgYjY0b3Mud3JpdGUocy5nZXRCeXRlcyhTdGFuZGFyZENoYXJzZXRzLlVURl84KSk7CisJCSAgICBiNjRvcy5mbHVzaCgpOyAJLy8gY29tcGxldGUgdGhlIGVuY29kaW5nCisKKwkJICAgIGJvcy53cml0ZShDUkxGKTsgCS8vIENSTEYgdGVybWluYXRpb24KKwkJICAgIG9zLndyaXRlKGJvcy50b0J5dGVBcnJheSgpKTsgLy8gd3JpdGUgb3V0IGxpbmUKKwkJICAgIG9zLmZsdXNoKCk7IAkvLyBmbHVzaCB0aGUgc3RyZWFtCisJCSAgICBib3MucmVzZXQoKTsgCS8vIHJlc2V0IGJ1ZmZlcgorCQl9IGVsc2UgaWYgKHIuaXNUYWdnZWQoKSAmJiByLmdldFRhZygpLmVxdWFscyh0YWcpKQorCQkgICAgLy8gQWgsIG91ciB0YWdnZWQgcmVzcG9uc2UKKwkJICAgIGRvbmUgPSB0cnVlOworCQllbHNlIGlmIChyLmlzQllFKCkpIC8vIG91dHRhIGhlcmUKKwkJICAgIGRvbmUgPSB0cnVlOworCQkvLyBobW0gLi4gdW5zb2xpY2l0ZWQgcmVzcG9uc2UgaGVyZSA/IQorCSAgICB9IGNhdGNoIChFeGNlcHRpb24gaW9leCkgeworCQkvLyBjb252ZXJ0IHRoaXMgaW50byBhIEJZRSByZXNwb25zZQorCQlyID0gUmVzcG9uc2UuYnllUmVzcG9uc2UoaW9leCk7CisJCWRvbmUgPSB0cnVlOworCSAgICB9CisJICAgIHYuYWRkKHIpOworCX0KKworCX0gZmluYWxseSB7CisJICAgIHJlc3VtZVRyYWNpbmcoKTsKKwl9CisKKwlSZXNwb25zZVtdIHJlc3BvbnNlcyA9IHYudG9BcnJheShuZXcgUmVzcG9uc2Vbdi5zaXplKCldKTsKKworCS8vIGhhbmRsZSBhbiBpbGxlZ2FsIGJ1dCBub3QgdW5jb21tb24gdW50YWdnZWQgQ0FQQUJJTFRZIHJlc3BvbnNlCisJaGFuZGxlQ2FwYWJpbGl0eVJlc3BvbnNlKHJlc3BvbnNlcyk7CisKKwkvKgorCSAqIERpc3BhdGNoIHVudGFnZ2VkIHJlc3BvbnNlcy4KKwkgKiBOT1RFOiBpbiBvdXIgY3VycmVudCB1cHBlciBsZXZlbCBJTUFQIGNsYXNzZXMsIHdlIGFkZCB0aGUKKwkgKiByZXNwb25zZUhhbmRsZXIgdG8gdGhlIFByb3RvY29sIG9iamVjdCBvbmx5ICphZnRlciogdGhlIAorCSAqIGNvbm5lY3Rpb24gaGFzIGJlZW4gYXV0aGVudGljYXRlZC4gU28sIGZvciBub3csIHRoZSBiZWxvdworCSAqIGNvZGUgcmVhbGx5IGVuZHMgdXAgYmVpbmcganVzdCBhIG5vLW9wLgorCSAqLworCW5vdGlmeVJlc3BvbnNlSGFuZGxlcnMocmVzcG9uc2VzKTsKKworCS8vIEhhbmRsZSB0aGUgZmluYWwgT0ssIE5PLCBCQUQgb3IgQllFIHJlc3BvbnNlCisJaWYgKG5vYXV0aGRlYnVnICYmIGlzVHJhY2luZygpKQorCSAgICBsb2dnZXIuZmluZSgiQVVUSEVOVElDQVRFIExPR0lOIGNvbW1hbmQgcmVzdWx0OiAiICsgcik7CisJaGFuZGxlTG9naW5SZXN1bHQocik7CisJLy8gSWYgdGhlIHJlc3BvbnNlIGluY2x1ZGVzIGEgQ0FQQUJJTElUWSByZXNwb25zZSBjb2RlLCBwcm9jZXNzIGl0CisJc2V0Q2FwYWJpbGl0aWVzKHIpOworCS8vIGlmIHdlIGdldCB0aGlzIGZhciB3aXRob3V0IGFuIGV4Y2VwdGlvbiwgd2UncmUgYXV0aGVudGljYXRlZAorCWF1dGhlbnRpY2F0ZWQgPSB0cnVlOworICAgIH0KKworCisgICAgLyoqCisgICAgICogVGhlIEFVVEhFTlRJQ0FURSBjb21tYW5kIHdpdGggQVVUSD1QTEFJTiBhdXRoZW50aWNhdGlvbiBzY2hlbWUuCisgICAgICogVGhpcyBpcyBiYXNlZCBoZWF2bHkgb24gdGhlIHtAbGluayAjYXV0aGxvZ2lufSBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gIGF1dGh6aWQJCXRoZSBhdXRob3JpemF0aW9uIGlkCisgICAgICogQHBhcmFtICB1CQl0aGUgdXNlcm5hbWUKKyAgICAgKiBAcGFyYW0gIHAJCXRoZSBwYXNzd29yZAorICAgICAqIEB0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24gYXMgdGhyb3duIGJ5IHtAbGluayBQcm90b2NvbCNoYW5kbGVSZXN1bHR9LgorICAgICAqIEBzZWUgIlJGQzM1MDEsIHNlY3Rpb24gNi4yLjIiCisgICAgICogQHNlZSAiUkZDMjU5NSwgc2VjdGlvbiA2IgorICAgICAqIEBzaW5jZSAgSmF2YU1haWwgMS4zLjIKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgYXV0aHBsYWluKFN0cmluZyBhdXRoemlkLCBTdHJpbmcgdSwgU3RyaW5nIHApCisJCQkJdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKwlMaXN0PFJlc3BvbnNlPiB2ID0gbmV3IEFycmF5TGlzdDw+KCk7CisJU3RyaW5nIHRhZyA9IG51bGw7CisJUmVzcG9uc2UgciA9IG51bGw7CisJYm9vbGVhbiBkb25lID0gZmFsc2U7CisKKwl0cnkgeworCisJaWYgKG5vYXV0aGRlYnVnICYmIGlzVHJhY2luZygpKSB7CisJICAgIGxvZ2dlci5maW5lKCJBVVRIRU5USUNBVEUgUExBSU4gY29tbWFuZCB0cmFjZSBzdXBwcmVzc2VkIik7CisJICAgIHN1c3BlbmRUcmFjaW5nKCk7CisJfQorCisJdHJ5IHsKKwkgICAgdGFnID0gd3JpdGVDb21tYW5kKCJBVVRIRU5USUNBVEUgUExBSU4iLCBudWxsKTsKKwl9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKwkgICAgLy8gQ29udmVydCB0aGlzIGludG8gYSBCWUUgcmVzcG9uc2UKKwkgICAgciA9IFJlc3BvbnNlLmJ5ZVJlc3BvbnNlKGV4KTsKKwkgICAgZG9uZSA9IHRydWU7CisJfQorCisJT3V0cHV0U3RyZWFtIG9zID0gZ2V0T3V0cHV0U3RyZWFtKCk7IC8vIHN0cmVhbSB0byBJTUFQIHNlcnZlcgorCisJLyogV3JhcCBhIEJBU0U2NEVuY29kZXIgYXJvdW5kIGEgQnl0ZUFycmF5T3V0cHV0c3RyZWFtCisJICogdG8gY3JhZnQgYjY0IGVuY29kZWQgdXNlcm5hbWUgYW5kIHBhc3N3b3JkIHN0cmluZ3MKKwkgKgorCSAqIE5vdGUgdGhhdCB0aGUgZW5jb2RlZCBieXRlcyBzaG91bGQgYmUgc2VudCAiYXMtaXMiIHRvIHRoZQorCSAqIHNlcnZlciwgKm5vdCogYXMgbGl0ZXJhbHMgb3IgcXVvdGVkLXN0cmluZ3MuCisJICoKKwkgKiBBbHNvIG5vdGUgdGhhdCB1bmxpa2UgdGhlIEI2NCBkZWZpbml0aW9uIGluIE1JTUUsIENSTEZzCisJICogc2hvdWxkICpub3QqIGJlIGluc2VydGVkIGR1cmluZyB0aGUgZW5jb2RpbmcgcHJvY2Vzcy4gU28sIEkKKwkgKiB1c2UgSW50ZWdlci5NQVhfVkFMVUUgKDB4N2ZmZmZmZmYgKD4gMUcpKSBhcyB0aGUgYnl0ZXNQZXJMaW5lLAorCSAqIHdoaWNoIHNob3VsZCBiZSBzdWZmaWNpZW50bHkgbGFyZ2UgIQorCSAqCisJICogRmluYWxseSwgZm9ybWF0IHRoZSBsaW5lIGluIGEgYnVmZmVyIHNvIGl0IGNhbiBiZSBzZW50IGFzCisJICogYSBzaW5nbGUgcGFja2V0LCB0byBhdm9pZCB0cmlnZ2VyaW5nIGEgYnVnIGluIFNVTidzIFNJTVMgMi4wCisJICogc2VydmVyIGNhdXNlZCBieSBwYXRjaCAxMDUzNDYuCisJICovCisKKwlCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworCU91dHB1dFN0cmVhbSBiNjRvcyA9IG5ldyBCQVNFNjRFbmNvZGVyU3RyZWFtKGJvcywgSW50ZWdlci5NQVhfVkFMVUUpOworCisJd2hpbGUgKCFkb25lKSB7IC8vIGxvb3AgdGlsbCB3ZSBhcmUgZG9uZQorCSAgICB0cnkgeworCQlyID0gcmVhZFJlc3BvbnNlKCk7CisJCWlmIChyLmlzQ29udGludWF0aW9uKCkpIHsKKwkJICAgIC8vIFNlcnZlciBjaGFsbGVuZ2UgLi4KKwkJICAgIGZpbmFsIFN0cmluZyBudWxsQnl0ZSA9ICJcMCI7CisJCSAgICBTdHJpbmcgcyA9IChhdXRoemlkID09IG51bGwgPyAiIiA6IGF1dGh6aWQpICsKKwkJCQkgICAgbnVsbEJ5dGUgKyB1ICsgbnVsbEJ5dGUgKyBwOworCisJCSAgICAvLyBvYnRhaW4gYjY0IGVuY29kZWQgYnl0ZXMKKwkJICAgIGI2NG9zLndyaXRlKHMuZ2V0Qnl0ZXMoU3RhbmRhcmRDaGFyc2V0cy5VVEZfOCkpOworCQkgICAgYjY0b3MuZmx1c2goKTsgCS8vIGNvbXBsZXRlIHRoZSBlbmNvZGluZworCisJCSAgICBib3Mud3JpdGUoQ1JMRik7IAkvLyBDUkxGIHRlcm1pbmF0aW9uCisJCSAgICBvcy53cml0ZShib3MudG9CeXRlQXJyYXkoKSk7IC8vIHdyaXRlIG91dCBsaW5lCisJCSAgICBvcy5mbHVzaCgpOyAJLy8gZmx1c2ggdGhlIHN0cmVhbQorCQkgICAgYm9zLnJlc2V0KCk7IAkvLyByZXNldCBidWZmZXIKKwkJfSBlbHNlIGlmIChyLmlzVGFnZ2VkKCkgJiYgci5nZXRUYWcoKS5lcXVhbHModGFnKSkKKwkJICAgIC8vIEFoLCBvdXIgdGFnZ2VkIHJlc3BvbnNlCisJCSAgICBkb25lID0gdHJ1ZTsKKwkJZWxzZSBpZiAoci5pc0JZRSgpKSAvLyBvdXR0YSBoZXJlCisJCSAgICBkb25lID0gdHJ1ZTsKKwkJLy8gaG1tIC4uIHVuc29saWNpdGVkIHJlc3BvbnNlIGhlcmUgPyEKKwkgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGlvZXgpIHsKKwkJLy8gY29udmVydCB0aGlzIGludG8gYSBCWUUgcmVzcG9uc2UKKwkJciA9IFJlc3BvbnNlLmJ5ZVJlc3BvbnNlKGlvZXgpOworCQlkb25lID0gdHJ1ZTsKKwkgICAgfQorCSAgICB2LmFkZChyKTsKKwl9CisKKwl9IGZpbmFsbHkgeworCSAgICByZXN1bWVUcmFjaW5nKCk7CisJfQorCisJUmVzcG9uc2VbXSByZXNwb25zZXMgPSB2LnRvQXJyYXkobmV3IFJlc3BvbnNlW3Yuc2l6ZSgpXSk7CisKKwkvLyBoYW5kbGUgYW4gaWxsZWdhbCBidXQgbm90IHVuY29tbW9uIHVudGFnZ2VkIENBUEFCSUxUWSByZXNwb25zZQorCWhhbmRsZUNhcGFiaWxpdHlSZXNwb25zZShyZXNwb25zZXMpOworCisJLyoKKwkgKiBEaXNwYXRjaCB1bnRhZ2dlZCByZXNwb25zZXMuCisJICogTk9URTogaW4gb3VyIGN1cnJlbnQgdXBwZXIgbGV2ZWwgSU1BUCBjbGFzc2VzLCB3ZSBhZGQgdGhlCisJICogcmVzcG9uc2VIYW5kbGVyIHRvIHRoZSBQcm90b2NvbCBvYmplY3Qgb25seSAqYWZ0ZXIqIHRoZQorCSAqIGNvbm5lY3Rpb24gaGFzIGJlZW4gYXV0aGVudGljYXRlZC4gU28sIGZvciBub3csIHRoZSBiZWxvdworCSAqIGNvZGUgcmVhbGx5IGVuZHMgdXAgYmVpbmcganVzdCBhIG5vLW9wLgorCSAqLworCW5vdGlmeVJlc3BvbnNlSGFuZGxlcnMocmVzcG9uc2VzKTsKKworCS8vIEhhbmRsZSB0aGUgZmluYWwgT0ssIE5PLCBCQUQgb3IgQllFIHJlc3BvbnNlCisJaWYgKG5vYXV0aGRlYnVnICYmIGlzVHJhY2luZygpKQorCSAgICBsb2dnZXIuZmluZSgiQVVUSEVOVElDQVRFIFBMQUlOIGNvbW1hbmQgcmVzdWx0OiAiICsgcik7CisJaGFuZGxlTG9naW5SZXN1bHQocik7CisJLy8gSWYgdGhlIHJlc3BvbnNlIGluY2x1ZGVzIGEgQ0FQQUJJTElUWSByZXNwb25zZSBjb2RlLCBwcm9jZXNzIGl0CisJc2V0Q2FwYWJpbGl0aWVzKHIpOworCS8vIGlmIHdlIGdldCB0aGlzIGZhciB3aXRob3V0IGFuIGV4Y2VwdGlvbiwgd2UncmUgYXV0aGVudGljYXRlZAorCWF1dGhlbnRpY2F0ZWQgPSB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBBVVRIRU5USUNBVEUgY29tbWFuZCB3aXRoIEFVVEg9TlRMTSBhdXRoZW50aWNhdGlvbiBzY2hlbWUuCisgICAgICogVGhpcyBpcyBiYXNlZCBoZWF2bHkgb24gdGhlIHtAbGluayAjYXV0aGxvZ2lufSBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gIGF1dGh6aWQJCXRoZSBhdXRob3JpemF0aW9uIGlkCisgICAgICogQHBhcmFtICB1CQl0aGUgdXNlcm5hbWUKKyAgICAgKiBAcGFyYW0gIHAJCXRoZSBwYXNzd29yZAorICAgICAqIEB0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24gYXMgdGhyb3duIGJ5IHtAbGluayBQcm90b2NvbCNoYW5kbGVSZXN1bHR9LgorICAgICAqIEBzZWUgIlJGQzM1MDEsIHNlY3Rpb24gNi4yLjIiCisgICAgICogQHNlZSAiUkZDMjU5NSwgc2VjdGlvbiA2IgorICAgICAqIEBzaW5jZSAgSmF2YU1haWwgMS40LjMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgYXV0aG50bG0oU3RyaW5nIGF1dGh6aWQsIFN0cmluZyB1LCBTdHJpbmcgcCkKKwkJCQl0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCUxpc3Q8UmVzcG9uc2U+IHYgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKwlTdHJpbmcgdGFnID0gbnVsbDsKKwlSZXNwb25zZSByID0gbnVsbDsKKwlib29sZWFuIGRvbmUgPSBmYWxzZTsKKworCVN0cmluZyB0eXBlMU1zZyA9IG51bGw7CisJaW50IGZsYWdzID0gUHJvcFV0aWwuZ2V0SW50UHJvcGVydHkocHJvcHMsCisJICAgICJtYWlsLiIgKyBuYW1lICsgIi5hdXRoLm50bG0uZmxhZ3MiLCAwKTsKKwlTdHJpbmcgZG9tYWluID0gcHJvcHMuZ2V0UHJvcGVydHkoCisJICAgICJtYWlsLiIgKyBuYW1lICsgIi5hdXRoLm50bG0uZG9tYWluIiwgIiIpOworCU50bG0gbnRsbSA9IG5ldyBOdGxtKGRvbWFpbiwgZ2V0TG9jYWxIb3N0KCksIHUsIHAsIGxvZ2dlcik7CisKKwl0cnkgeworCisJaWYgKG5vYXV0aGRlYnVnICYmIGlzVHJhY2luZygpKSB7CisJICAgIGxvZ2dlci5maW5lKCJBVVRIRU5USUNBVEUgTlRMTSBjb21tYW5kIHRyYWNlIHN1cHByZXNzZWQiKTsKKwkgICAgc3VzcGVuZFRyYWNpbmcoKTsKKwl9CisKKwl0cnkgeworCSAgICB0YWcgPSB3cml0ZUNvbW1hbmQoIkFVVEhFTlRJQ0FURSBOVExNIiwgbnVsbCk7CisJfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJICAgIC8vIENvbnZlcnQgdGhpcyBpbnRvIGEgQllFIHJlc3BvbnNlCisJICAgIHIgPSBSZXNwb25zZS5ieWVSZXNwb25zZShleCk7CisJICAgIGRvbmUgPSB0cnVlOworCX0KKworCU91dHB1dFN0cmVhbSBvcyA9IGdldE91dHB1dFN0cmVhbSgpOyAvLyBzdHJlYW0gdG8gSU1BUCBzZXJ2ZXIKKwlib29sZWFuIGZpcnN0ID0gdHJ1ZTsKKworCXdoaWxlICghZG9uZSkgeyAvLyBsb29wIHRpbGwgd2UgYXJlIGRvbmUKKwkgICAgdHJ5IHsKKwkJciA9IHJlYWRSZXNwb25zZSgpOworCSAgICAJaWYgKHIuaXNDb250aW51YXRpb24oKSkgeworCQkgICAgLy8gU2VydmVyIGNoYWxsZW5nZSAuLgorCQkgICAgU3RyaW5nIHM7CisJCSAgICBpZiAoZmlyc3QpIHsKKwkJCXMgPSBudGxtLmdlbmVyYXRlVHlwZTFNc2coZmxhZ3MpOworCQkJZmlyc3QgPSBmYWxzZTsKKwkJICAgIH0gZWxzZSB7CisJCQlzID0gbnRsbS5nZW5lcmF0ZVR5cGUzTXNnKHIuZ2V0UmVzdCgpKTsKKwkJICAgIH0KKyAKKwkJICAgIG9zLndyaXRlKHMuZ2V0Qnl0ZXMoU3RhbmRhcmRDaGFyc2V0cy5VVEZfOCkpOworCQkgICAgb3Mud3JpdGUoQ1JMRik7IAkvLyBDUkxGIHRlcm1pbmF0aW9uCisJCSAgICBvcy5mbHVzaCgpOyAJLy8gZmx1c2ggdGhlIHN0cmVhbQorCQl9IGVsc2UgaWYgKHIuaXNUYWdnZWQoKSAmJiByLmdldFRhZygpLmVxdWFscyh0YWcpKQorCQkgICAgLy8gQWgsIG91ciB0YWdnZWQgcmVzcG9uc2UKKwkJICAgIGRvbmUgPSB0cnVlOworCQllbHNlIGlmIChyLmlzQllFKCkpIC8vIG91dHRhIGhlcmUKKwkJICAgIGRvbmUgPSB0cnVlOworCQkvLyBobW0gLi4gdW5zb2xpY2l0ZWQgcmVzcG9uc2UgaGVyZSA/IQorCSAgICB9IGNhdGNoIChFeGNlcHRpb24gaW9leCkgeworCQkvLyBjb252ZXJ0IHRoaXMgaW50byBhIEJZRSByZXNwb25zZQorCQlyID0gUmVzcG9uc2UuYnllUmVzcG9uc2UoaW9leCk7CisJCWRvbmUgPSB0cnVlOworCSAgICB9CisJICAgIHYuYWRkKHIpOworCX0KKworCX0gZmluYWxseSB7CisJICAgIHJlc3VtZVRyYWNpbmcoKTsKKwl9CisKKwlSZXNwb25zZVtdIHJlc3BvbnNlcyA9IHYudG9BcnJheShuZXcgUmVzcG9uc2Vbdi5zaXplKCldKTsKKworCS8vIGhhbmRsZSBhbiBpbGxlZ2FsIGJ1dCBub3QgdW5jb21tb24gdW50YWdnZWQgQ0FQQUJJTFRZIHJlc3BvbnNlCisJaGFuZGxlQ2FwYWJpbGl0eVJlc3BvbnNlKHJlc3BvbnNlcyk7CisKKwkvKgorCSAqIERpc3BhdGNoIHVudGFnZ2VkIHJlc3BvbnNlcy4KKwkgKiBOT1RFOiBpbiBvdXIgY3VycmVudCB1cHBlciBsZXZlbCBJTUFQIGNsYXNzZXMsIHdlIGFkZCB0aGUKKwkgKiByZXNwb25zZUhhbmRsZXIgdG8gdGhlIFByb3RvY29sIG9iamVjdCBvbmx5ICphZnRlciogdGhlCisJICogY29ubmVjdGlvbiBoYXMgYmVlbiBhdXRoZW50aWNhdGVkLiBTbywgZm9yIG5vdywgdGhlIGJlbG93CisJICogY29kZSByZWFsbHkgZW5kcyB1cCBiZWluZyBqdXN0IGEgbm8tb3AuCisJICovCisJbm90aWZ5UmVzcG9uc2VIYW5kbGVycyhyZXNwb25zZXMpOworCisJLy8gSGFuZGxlIHRoZSBmaW5hbCBPSywgTk8sIEJBRCBvciBCWUUgcmVzcG9uc2UKKwlpZiAobm9hdXRoZGVidWcgJiYgaXNUcmFjaW5nKCkpCisJICAgIGxvZ2dlci5maW5lKCJBVVRIRU5USUNBVEUgTlRMTSBjb21tYW5kIHJlc3VsdDogIiArIHIpOworCWhhbmRsZUxvZ2luUmVzdWx0KHIpOworCS8vIElmIHRoZSByZXNwb25zZSBpbmNsdWRlcyBhIENBUEFCSUxJVFkgcmVzcG9uc2UgY29kZSwgcHJvY2VzcyBpdAorCXNldENhcGFiaWxpdGllcyhyKTsKKwkvLyBpZiB3ZSBnZXQgdGhpcyBmYXIgd2l0aG91dCBhbiBleGNlcHRpb24sIHdlJ3JlIGF1dGhlbnRpY2F0ZWQKKwlhdXRoZW50aWNhdGVkID0gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgQVVUSEVOVElDQVRFIGNvbW1hbmQgd2l0aCBBVVRIPVhPQVVUSDIgYXV0aGVudGljYXRpb24gc2NoZW1lLgorICAgICAqIFRoaXMgaXMgYmFzZWQgaGVhdmx5IG9uIHRoZSB7QGxpbmsgI2F1dGhsb2dpbn0gbWV0aG9kLgorICAgICAqCisgICAgICogQHBhcmFtICB1CQl0aGUgdXNlcm5hbWUKKyAgICAgKiBAcGFyYW0gIHAJCXRoZSBwYXNzd29yZAorICAgICAqIEB0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24gYXMgdGhyb3duIGJ5IHtAbGluayBQcm90b2NvbCNoYW5kbGVSZXN1bHR9LgorICAgICAqIEBzZWUgIlJGQzM1MDEsIHNlY3Rpb24gNi4yLjIiCisgICAgICogQHNlZSAiUkZDMjU5NSwgc2VjdGlvbiA2IgorICAgICAqIEBzaW5jZSAgSmF2YU1haWwgMS41LjUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgYXV0aG9hdXRoMihTdHJpbmcgdSwgU3RyaW5nIHApCisJCQkJdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKwlMaXN0PFJlc3BvbnNlPiB2ID0gbmV3IEFycmF5TGlzdDw+KCk7CisJU3RyaW5nIHRhZyA9IG51bGw7CisJUmVzcG9uc2UgciA9IG51bGw7CisJYm9vbGVhbiBkb25lID0gZmFsc2U7CisKKwl0cnkgeworCisJaWYgKG5vYXV0aGRlYnVnICYmIGlzVHJhY2luZygpKSB7CisJICAgIGxvZ2dlci5maW5lKCJBVVRIRU5USUNBVEUgWE9BVVRIMiBjb21tYW5kIHRyYWNlIHN1cHByZXNzZWQiKTsKKwkgICAgc3VzcGVuZFRyYWNpbmcoKTsKKwl9CisKKwl0cnkgeworCSAgICBBcmd1bWVudCBhcmdzID0gbmV3IEFyZ3VtZW50KCk7CisJICAgIGFyZ3Mud3JpdGVBdG9tKCJYT0FVVEgyIik7CisJICAgIGlmIChoYXNDYXBhYmlsaXR5KCJTQVNMLUlSIikpIHsKKwkJU3RyaW5nIHJlc3AgPSAidXNlcj0iICsgdSArICJcMDAxYXV0aD1CZWFyZXIgIiArIHAgKyAiXDAwMVwwMDEiOworCQlieXRlW10gYmEgPSBCQVNFNjRFbmNvZGVyU3RyZWFtLmVuY29kZSgKKwkJCQkgICAgcmVzcC5nZXRCeXRlcyhTdGFuZGFyZENoYXJzZXRzLlVURl84KSk7CisJCVN0cmluZyBpcnMgPSBBU0NJSVV0aWxpdHkudG9TdHJpbmcoYmEsIDAsIGJhLmxlbmd0aCk7CisJCWFyZ3Mud3JpdGVBdG9tKGlycyk7CisJICAgIH0KKwkgICAgdGFnID0gd3JpdGVDb21tYW5kKCJBVVRIRU5USUNBVEUiLCBhcmdzKTsKKwl9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKwkgICAgLy8gQ29udmVydCB0aGlzIGludG8gYSBCWUUgcmVzcG9uc2UKKwkgICAgciA9IFJlc3BvbnNlLmJ5ZVJlc3BvbnNlKGV4KTsKKwkgICAgZG9uZSA9IHRydWU7CisJfQorCisJT3V0cHV0U3RyZWFtIG9zID0gZ2V0T3V0cHV0U3RyZWFtKCk7IC8vIHN0cmVhbSB0byBJTUFQIHNlcnZlcgorCisJd2hpbGUgKCFkb25lKSB7IC8vIGxvb3AgdGlsbCB3ZSBhcmUgZG9uZQorCSAgICB0cnkgeworCQlyID0gcmVhZFJlc3BvbnNlKCk7CisJCWlmIChyLmlzQ29udGludWF0aW9uKCkpIHsKKwkJICAgIC8vIFNlcnZlciBjaGFsbGVuZ2UgLi4KKwkJICAgIFN0cmluZyByZXNwID0gInVzZXI9IiArIHUgKyAiXDAwMWF1dGg9QmVhcmVyICIgKworCQkJCSAgICBwICsgIlwwMDFcMDAxIjsKKwkJICAgIGJ5dGVbXSBiID0gQkFTRTY0RW5jb2RlclN0cmVhbS5lbmNvZGUoCisJCQkJICAgIHJlc3AuZ2V0Qnl0ZXMoU3RhbmRhcmRDaGFyc2V0cy5VVEZfOCkpOworCQkgICAgb3Mud3JpdGUoYik7CS8vIHdyaXRlIG91dCByZXNwb25zZQorCQkgICAgb3Mud3JpdGUoQ1JMRik7IAkvLyBDUkxGIHRlcm1pbmF0aW9uCisJCSAgICBvcy5mbHVzaCgpOyAJLy8gZmx1c2ggdGhlIHN0cmVhbQorCQl9IGVsc2UgaWYgKHIuaXNUYWdnZWQoKSAmJiByLmdldFRhZygpLmVxdWFscyh0YWcpKQorCQkgICAgLy8gQWgsIG91ciB0YWdnZWQgcmVzcG9uc2UKKwkJICAgIGRvbmUgPSB0cnVlOworCQllbHNlIGlmIChyLmlzQllFKCkpIC8vIG91dHRhIGhlcmUKKwkJICAgIGRvbmUgPSB0cnVlOworCQkvLyBobW0gLi4gdW5zb2xpY2l0ZWQgcmVzcG9uc2UgaGVyZSA/IQorCSAgICB9IGNhdGNoIChFeGNlcHRpb24gaW9leCkgeworCQkvLyBjb252ZXJ0IHRoaXMgaW50byBhIEJZRSByZXNwb25zZQorCQlyID0gUmVzcG9uc2UuYnllUmVzcG9uc2UoaW9leCk7CisJCWRvbmUgPSB0cnVlOworCSAgICB9CisJICAgIHYuYWRkKHIpOworCX0KKworCX0gZmluYWxseSB7CisJICAgIHJlc3VtZVRyYWNpbmcoKTsKKwl9CisKKwlSZXNwb25zZVtdIHJlc3BvbnNlcyA9IHYudG9BcnJheShuZXcgUmVzcG9uc2Vbdi5zaXplKCldKTsKKworCS8vIGhhbmRsZSBhbiBpbGxlZ2FsIGJ1dCBub3QgdW5jb21tb24gdW50YWdnZWQgQ0FQQUJJTFRZIHJlc3BvbnNlCisJaGFuZGxlQ2FwYWJpbGl0eVJlc3BvbnNlKHJlc3BvbnNlcyk7CisKKwkvKgorCSAqIERpc3BhdGNoIHVudGFnZ2VkIHJlc3BvbnNlcy4KKwkgKiBOT1RFOiBpbiBvdXIgY3VycmVudCB1cHBlciBsZXZlbCBJTUFQIGNsYXNzZXMsIHdlIGFkZCB0aGUKKwkgKiByZXNwb25zZUhhbmRsZXIgdG8gdGhlIFByb3RvY29sIG9iamVjdCBvbmx5ICphZnRlciogdGhlCisJICogY29ubmVjdGlvbiBoYXMgYmVlbiBhdXRoZW50aWNhdGVkLiBTbywgZm9yIG5vdywgdGhlIGJlbG93CisJICogY29kZSByZWFsbHkgZW5kcyB1cCBiZWluZyBqdXN0IGEgbm8tb3AuCisJICovCisJbm90aWZ5UmVzcG9uc2VIYW5kbGVycyhyZXNwb25zZXMpOworCisJLy8gSGFuZGxlIHRoZSBmaW5hbCBPSywgTk8sIEJBRCBvciBCWUUgcmVzcG9uc2UKKwlpZiAobm9hdXRoZGVidWcgJiYgaXNUcmFjaW5nKCkpCisJICAgIGxvZ2dlci5maW5lKCJBVVRIRU5USUNBVEUgWE9BVVRIMiBjb21tYW5kIHJlc3VsdDogIiArIHIpOworCWhhbmRsZUxvZ2luUmVzdWx0KHIpOworCS8vIElmIHRoZSByZXNwb25zZSBpbmNsdWRlcyBhIENBUEFCSUxJVFkgcmVzcG9uc2UgY29kZSwgcHJvY2VzcyBpdAorCXNldENhcGFiaWxpdGllcyhyKTsKKwkvLyBpZiB3ZSBnZXQgdGhpcyBmYXIgd2l0aG91dCBhbiBleGNlcHRpb24sIHdlJ3JlIGF1dGhlbnRpY2F0ZWQKKwlhdXRoZW50aWNhdGVkID0gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTQVNMLWJhc2VkIGxvZ2luLgorICAgICAqCisgICAgICogQHBhcmFtCWFsbG93ZWQJdGhlIFNBU0wgbWVjaGFuaXNtcyB3ZSdyZSBhbGxvd2VkIHRvIHVzZQorICAgICAqIEBwYXJhbQlyZWFsbQl0aGUgU0FTTCByZWFsbQorICAgICAqIEBwYXJhbQlhdXRoemlkCXRoZSBhdXRob3JpemF0aW9uIGlkCisgICAgICogQHBhcmFtCXUJdGhlIHVzZXJuYW1lCisgICAgICogQHBhcmFtCXAJdGhlIHBhc3N3b3JkCisgICAgICogQGV4Y2VwdGlvbglQcm90b2NvbEV4Y2VwdGlvbglmb3IgcHJvdG9jb2wgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzYXNsbG9naW4oU3RyaW5nW10gYWxsb3dlZCwgU3RyaW5nIHJlYWxtLCBTdHJpbmcgYXV0aHppZCwKKwkJCQlTdHJpbmcgdSwgU3RyaW5nIHApIHRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJYm9vbGVhbiB1c2VDYW5vbmljYWxIb3N0TmFtZSA9IFByb3BVdGlsLmdldEJvb2xlYW5Qcm9wZXJ0eShwcm9wcywKKwkJICAgICJtYWlsLiIgKyBuYW1lICsgIi5zYXNsLnVzZWNhbm9uaWNhbGhvc3RuYW1lIiwgZmFsc2UpOworCVN0cmluZyBzZXJ2aWNlSG9zdDsKKwlpZiAodXNlQ2Fub25pY2FsSG9zdE5hbWUpCisJICAgIHNlcnZpY2VIb3N0ID0gZ2V0SW5ldEFkZHJlc3MoKS5nZXRDYW5vbmljYWxIb3N0TmFtZSgpOworCWVsc2UKKwkgICAgc2VydmljZUhvc3QgPSBob3N0OworCWlmIChzYXNsQXV0aGVudGljYXRvciA9PSBudWxsKSB7CisJICAgIHRyeSB7CisJCUNsYXNzPD8+IHNhYyA9IENsYXNzLmZvck5hbWUoCisJCSAgICAiY29tLnN1bi5tYWlsLmltYXAucHJvdG9jb2wuSU1BUFNhc2xBdXRoZW50aWNhdG9yIik7CisJCUNvbnN0cnVjdG9yPD8+IGMgPSBzYWMuZ2V0Q29uc3RydWN0b3IobmV3IENsYXNzPD8+W10geworCQkJCQlJTUFQUHJvdG9jb2wuY2xhc3MsCisJCQkJCVN0cmluZy5jbGFzcywKKwkJCQkJUHJvcGVydGllcy5jbGFzcywKKwkJCQkJTWFpbExvZ2dlci5jbGFzcywKKwkJCQkJU3RyaW5nLmNsYXNzCisJCQkJCX0pOworCQlzYXNsQXV0aGVudGljYXRvciA9IChTYXNsQXV0aGVudGljYXRvciljLm5ld0luc3RhbmNlKAorCQkJCQluZXcgT2JqZWN0W10geworCQkJCQl0aGlzLAorCQkJCQluYW1lLAorCQkJCQlwcm9wcywKKwkJCQkJbG9nZ2VyLAorCQkJCQlzZXJ2aWNlSG9zdAorCQkJCQl9KTsKKwkgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJCWxvZ2dlci5sb2coTGV2ZWwuRklORSwgIkNhbid0IGxvYWQgU0FTTCBhdXRoZW50aWNhdG9yIiwgZXgpOworCQkvLyBwcm9iYWJseSBiZWNhdXNlIHdlJ3JlIHJ1bm5pbmcgb24gYSBzeXN0ZW0gd2l0aG91dCBTQVNMCisJCXJldHVybjsJLy8gbm90IGF1dGhlbnRpY2F0ZWQsIHRyeSB3aXRob3V0IFNBU0wKKwkgICAgfQorCX0KKworCS8vIHdlcmUgYW55IGFsbG93ZWQgbWVjaGFuaXNtcyBzcGVjaWZpZWQ/CisJTGlzdDxTdHJpbmc+IHY7CisJaWYgKGFsbG93ZWQgIT0gbnVsbCAmJiBhbGxvd2VkLmxlbmd0aCA+IDApIHsKKwkgICAgLy8gcmVtb3ZlIGFueXRoaW5nIG5vdCBzdXBwb3J0ZWQgYnkgdGhlIHNlcnZlcgorCSAgICB2ID0gbmV3IEFycmF5TGlzdDw+KGFsbG93ZWQubGVuZ3RoKTsKKwkgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhbGxvd2VkLmxlbmd0aDsgaSsrKQorCQlpZiAoYXV0aG1lY2hzLmNvbnRhaW5zKGFsbG93ZWRbaV0pKQkvLyBYWFggLSBjYXNlIG11c3QgbWF0Y2gKKwkJICAgIHYuYWRkKGFsbG93ZWRbaV0pOworCX0gZWxzZSB7CisJICAgIC8vIGV2ZXJ5dGhpbmcgaXMgYWxsb3dlZAorCSAgICB2ID0gYXV0aG1lY2hzOworCX0KKwlTdHJpbmdbXSBtZWNocyA9IHYudG9BcnJheShuZXcgU3RyaW5nW3Yuc2l6ZSgpXSk7CisKKwl0cnkgeworCisJICAgIGlmIChub2F1dGhkZWJ1ZyAmJiBpc1RyYWNpbmcoKSkgeworCQlsb2dnZXIuZmluZSgiU0FTTCBhdXRoZW50aWNhdGlvbiBjb21tYW5kIHRyYWNlIHN1cHByZXNzZWQiKTsKKwkJc3VzcGVuZFRyYWNpbmcoKTsKKwkgICAgfQorCisJICAgIGlmIChzYXNsQXV0aGVudGljYXRvci5hdXRoZW50aWNhdGUobWVjaHMsIHJlYWxtLCBhdXRoemlkLCB1LCBwKSkgeworCQlpZiAobm9hdXRoZGVidWcgJiYgaXNUcmFjaW5nKCkpCisJCSAgICBsb2dnZXIuZmluZSgiU0FTTCBhdXRoZW50aWNhdGlvbiBzdWNjZWVkZWQiKTsKKwkJYXV0aGVudGljYXRlZCA9IHRydWU7CisJICAgIH0gZWxzZSB7CisJCWlmIChub2F1dGhkZWJ1ZyAmJiBpc1RyYWNpbmcoKSkKKwkJICAgIGxvZ2dlci5maW5lKCJTQVNMIGF1dGhlbnRpY2F0aW9uIGZhaWxlZCIpOworCSAgICB9CisJfSBmaW5hbGx5IHsKKwkgICAgcmVzdW1lVHJhY2luZygpOworCX0KKyAgICB9CisKKyAgICAvLyBYWFggLSBmb3IgSU1BUFNhc2xBdXRoZW50aWNhdG9yIGFjY2VzcyB0byBwcm90ZWN0ZWQgbWV0aG9kCisgICAgT3V0cHV0U3RyZWFtIGdldElNQVBPdXRwdXRTdHJlYW0oKSB7CisJcmV0dXJuIGdldE91dHB1dFN0cmVhbSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEhhbmRsZSB0aGUgcmVzdWx0IHJlc3BvbnNlIGZvciBhIExPR0lOIG9yIEFVVEhFTlRJQ0FURSBjb21tYW5kLgorICAgICAqIExvb2sgZm9yIElNQVAgbG9naW4gUkVGRVJSQUwuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jcgl0aGUgcmVzcG9uc2UKKyAgICAgKiBAZXhjZXB0aW9uCVByb3RvY29sRXhjZXB0aW9uCWZvciBwcm90b2NvbCBmYWlsdXJlcworICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjUuNQorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGhhbmRsZUxvZ2luUmVzdWx0KFJlc3BvbnNlIHIpIHRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJaWYgKGhhc0NhcGFiaWxpdHkoIkxPR0lOLVJFRkVSUkFMUyIpICYmCisJCSghci5pc09LKCkgfHwgcmVmZXJyYWxFeGNlcHRpb24pKQorCSAgICBjaGVja1JlZmVycmFsKHIpOworCWhhbmRsZVJlc3VsdChyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQUk9YWUFVVEggQ29tbWFuZC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0JdQl0aGUgUFJPWFlBVVRIIHVzZXIgbmFtZQorICAgICAqIEBleGNlcHRpb24JUHJvdG9jb2xFeGNlcHRpb24JZm9yIHByb3RvY29sIGZhaWx1cmVzCisgICAgICogQHNlZSAiTmV0c2NhcGUvaVBsYW5ldC9TdW5PTkUgTWVzc2FnaW5nIFNlcnZlciBleHRlbnNpb24iCisgICAgICovCisgICAgcHVibGljIHZvaWQgcHJveHlhdXRoKFN0cmluZyB1KSB0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCUFyZ3VtZW50IGFyZ3MgPSBuZXcgQXJndW1lbnQoKTsKKwlhcmdzLndyaXRlU3RyaW5nKHUpOworCisJc2ltcGxlQ29tbWFuZCgiUFJPWFlBVVRIIiwgYXJncyk7CisJcHJveHlBdXRoVXNlciA9IHU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSB1c2VyIG5hbWUgdXNlZCB3aXRoIHRoZSBQUk9YWUFVVEggY29tbWFuZC4KKyAgICAgKiBSZXR1cm5zIG51bGwgaWYgUFJPWFlBVVRIIHdhcyBub3QgdXNlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIFBST1hZQVVUSCB1c2VyIG5hbWUKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS41LjEKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFByb3h5QXV0aFVzZXIoKSB7CisJcmV0dXJuIHByb3h5QXV0aFVzZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogVU5BVVRIRU5USUNBVEUgQ29tbWFuZC4KKyAgICAgKiAKKyAgICAgKiBAZXhjZXB0aW9uCVByb3RvY29sRXhjZXB0aW9uCWZvciBwcm90b2NvbCBmYWlsdXJlcworICAgICAqIEBzZWUgIk5ldHNjYXBlL2lQbGFuZXQvU3VuT05FIE1lc3NhZ2luZyBTZXJ2ZXIgZXh0ZW5zaW9uIgorICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjUuMQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVuYXV0aGVudGljYXRlKCkgdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKwlpZiAoIWhhc0NhcGFiaWxpdHkoIlgtVU5BVVRIRU5USUNBVEUiKSkKKwkgICAgdGhyb3cgbmV3IEJhZENvbW1hbmRFeGNlcHRpb24oIlVOQVVUSEVOVElDQVRFIG5vdCBzdXBwb3J0ZWQiKTsKKwlzaW1wbGVDb21tYW5kKCJVTkFVVEhFTlRJQ0FURSIsIG51bGwpOworCWF1dGhlbnRpY2F0ZWQgPSBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJRCBDb21tYW5kLCBmb3IgWWFob28hIE1haWwgSU1BUCBzZXJ2ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0JZ3VpZAl0aGUgR1VJRAorICAgICAqIEBleGNlcHRpb24JUHJvdG9jb2xFeGNlcHRpb24JZm9yIHByb3RvY29sIGZhaWx1cmVzCisgICAgICogQGRlcHJlY2F0ZWQgQXMgb2YgSmF2YU1haWwgMS41LjEsIHJlcGxhY2VkIGJ5CisgICAgICoJCXtAbGluayAjaWQoTWFwKSBpZChNYXAmbHQ7U3RyaW5nLFN0cmluZyZndDspfQorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjQuNAorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIHZvaWQgaWQoU3RyaW5nIGd1aWQpIHRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJLy8gc3VwcG9ydCB0aGlzIGZvciBub3csIGJ1dCByZW1vdmUgaXQgc29vbgorCU1hcDxTdHJpbmcsU3RyaW5nPiBnbWFwID0gbmV3IEhhc2hNYXA8PigpOworCWdtYXAucHV0KCJHVUlEIiwgZ3VpZCk7CisJaWQoZ21hcCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU1RBUlRUTFMgQ29tbWFuZC4KKyAgICAgKiAKKyAgICAgKiBAZXhjZXB0aW9uCVByb3RvY29sRXhjZXB0aW9uCWZvciBwcm90b2NvbCBmYWlsdXJlcworICAgICAqIEBzZWUgIlJGQzM1MDEsIHNlY3Rpb24gNi4yLjEiCisgICAgICovCisgICAgcHVibGljIHZvaWQgc3RhcnRUTFMoKSB0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCXRyeSB7CisJICAgIHN1cGVyLnN0YXJ0VExTKCJTVEFSVFRMUyIpOworCX0gY2F0Y2ggKFByb3RvY29sRXhjZXB0aW9uIHBleCkgeworCSAgICBsb2dnZXIubG9nKExldmVsLkZJTkUsICJTVEFSVFRMUyBQcm90b2NvbEV4Y2VwdGlvbiIsIHBleCk7CisJICAgIC8vIFByb3RvY29sRXhjZXB0aW9uIGp1c3QgbWVhbnMgdGhlIGNvbW1hbmQgd2Fzbid0IHJlY29nbml6ZWQsCisJICAgIC8vIG9yIGZhaWxlZC4gIFRoaXMgc2hvdWxkIG5ldmVyIGhhcHBlbiBpZiB3ZSBjaGVjayB0aGUKKwkgICAgLy8gQ0FQQUJJTElUWSBmaXJzdC4KKwkgICAgdGhyb3cgcGV4OworCX0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCSAgICBsb2dnZXIubG9nKExldmVsLkZJTkUsICJTVEFSVFRMUyBFeGNlcHRpb24iLCBleCk7CisJICAgIC8vIGFueSBvdGhlciBleGNlcHRpb24gbWVhbnMgd2UgaGF2ZSB0byBzaHV0IGRvd24gdGhlIGNvbm5lY3Rpb24KKwkgICAgLy8gZ2VuZXJhdGUgYW4gYXJ0aWZpY2lhbCBCWUUgcmVzcG9uc2UgYW5kIGRpc2Nvbm5lY3QKKwkgICAgUmVzcG9uc2VbXSByID0geyBSZXNwb25zZS5ieWVSZXNwb25zZShleCkgfTsKKwkgICAgbm90aWZ5UmVzcG9uc2VIYW5kbGVycyhyKTsKKwkgICAgZGlzY29ubmVjdCgpOworCSAgICB0aHJvdyBuZXcgUHJvdG9jb2xFeGNlcHRpb24oIlNUQVJUVExTIGZhaWx1cmUiLCBleCk7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENPTVBSRVNTIENvbW1hbmQuICBPbmx5IHN1cHBvcnRzIERFRkxBVEUuCisgICAgICogCisgICAgICogQGV4Y2VwdGlvbglQcm90b2NvbEV4Y2VwdGlvbglmb3IgcHJvdG9jb2wgZmFpbHVyZXMKKyAgICAgKiBAc2VlICJSRkMgNDk3OCIKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjb21wcmVzcygpIHRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJdHJ5IHsKKwkgICAgc3VwZXIuc3RhcnRDb21wcmVzc2lvbigiQ09NUFJFU1MgREVGTEFURSIpOworCX0gY2F0Y2ggKFByb3RvY29sRXhjZXB0aW9uIHBleCkgeworCSAgICBsb2dnZXIubG9nKExldmVsLkZJTkUsICJDT01QUkVTUyBQcm90b2NvbEV4Y2VwdGlvbiIsIHBleCk7CisJICAgIC8vIFByb3RvY29sRXhjZXB0aW9uIGp1c3QgbWVhbnMgdGhlIGNvbW1hbmQgd2Fzbid0IHJlY29nbml6ZWQsCisJICAgIC8vIG9yIGZhaWxlZC4gIFRoaXMgc2hvdWxkIG5ldmVyIGhhcHBlbiBpZiB3ZSBjaGVjayB0aGUKKwkgICAgLy8gQ0FQQUJJTElUWSBmaXJzdC4KKwkgICAgdGhyb3cgcGV4OworCX0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCSAgICBsb2dnZXIubG9nKExldmVsLkZJTkUsICJDT01QUkVTUyBFeGNlcHRpb24iLCBleCk7CisJICAgIC8vIGFueSBvdGhlciBleGNlcHRpb24gbWVhbnMgd2UgaGF2ZSB0byBzaHV0IGRvd24gdGhlIGNvbm5lY3Rpb24KKwkgICAgLy8gZ2VuZXJhdGUgYW4gYXJ0aWZpY2lhbCBCWUUgcmVzcG9uc2UgYW5kIGRpc2Nvbm5lY3QKKwkgICAgUmVzcG9uc2VbXSByID0geyBSZXNwb25zZS5ieWVSZXNwb25zZShleCkgfTsKKwkgICAgbm90aWZ5UmVzcG9uc2VIYW5kbGVycyhyKTsKKwkgICAgZGlzY29ubmVjdCgpOworCSAgICB0aHJvdyBuZXcgUHJvdG9jb2xFeGNlcHRpb24oIkNPTVBSRVNTIGZhaWx1cmUiLCBleCk7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEVuY29kZSBhIG1haWxib3ggbmFtZSBhcHByb3ByaWF0ZWx5IGRlcGVuZGluZyBvbiB3aGV0aGVyIG9yIG5vdAorICAgICAqIHRoZSBzZXJ2ZXIgc3VwcG9ydHMgVVRGLTgsIGFuZCBhZGQgdGhlIGVuY29kZWQgbmFtZSB0byB0aGUKKyAgICAgKiBBcmd1bWVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbQlhcmdzCXRoZSBhcmd1bWVudHMKKyAgICAgKiBAcGFyYW0JbmFtZQl0aGUgbmFtZSB0byBlbmNvZGUKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS42LjAKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCB3cml0ZU1haWxib3hOYW1lKEFyZ3VtZW50IGFyZ3MsIFN0cmluZyBuYW1lKSB7CisJaWYgKHV0ZjgpCisJICAgIGFyZ3Mud3JpdGVTdHJpbmcobmFtZSwgU3RhbmRhcmRDaGFyc2V0cy5VVEZfOCk7CisJZWxzZQorCSAgICAvLyBlbmNvZGUgdGhlIG1ib3ggYXMgcGVyIFJGQzIwNjAKKwkgICAgYXJncy53cml0ZVN0cmluZyhCQVNFNjRNYWlsYm94RW5jb2Rlci5lbmNvZGUobmFtZSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNFTEVDVCBDb21tYW5kLgorICAgICAqCisgICAgICogQHBhcmFtCW1ib3gJdGhlIG1haWxib3ggbmFtZQorICAgICAqIEByZXR1cm4JCU1haWxib3hJbmZvIGlmIHN1Y2Nlc3NmdWwKKyAgICAgKiBAZXhjZXB0aW9uCVByb3RvY29sRXhjZXB0aW9uCWZvciBwcm90b2NvbCBmYWlsdXJlcworICAgICAqIEBzZWUgIlJGQzIwNjAsIHNlY3Rpb24gNi4zLjEiCisgICAgICovCisgICAgcHVibGljIE1haWxib3hJbmZvIHNlbGVjdChTdHJpbmcgbWJveCkgdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKwlyZXR1cm4gc2VsZWN0KG1ib3gsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNFTEVDVCBDb21tYW5kIHdpdGggUVJFU1lOQyBkYXRhLgorICAgICAqCisgICAgICogQHBhcmFtCW1ib3gJdGhlIG1haWxib3ggbmFtZQorICAgICAqIEBwYXJhbQlyZAl0aGUgUmVzeW5jRGF0YQorICAgICAqIEByZXR1cm4JCU1haWxib3hJbmZvIGlmIHN1Y2Nlc3NmdWwKKyAgICAgKiBAZXhjZXB0aW9uCVByb3RvY29sRXhjZXB0aW9uCWZvciBwcm90b2NvbCBmYWlsdXJlcworICAgICAqIEBzZWUgIlJGQzIwNjAsIHNlY3Rpb24gNi4zLjEiCisgICAgICogQHNlZSAiUkZDNTE2Miwgc2VjdGlvbiAzLjEiCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNS4xCisgICAgICovCisgICAgcHVibGljIE1haWxib3hJbmZvIHNlbGVjdChTdHJpbmcgbWJveCwgUmVzeW5jRGF0YSByZCkKKwkJCQl0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCUFyZ3VtZW50IGFyZ3MgPSBuZXcgQXJndW1lbnQoKTsJCisJd3JpdGVNYWlsYm94TmFtZShhcmdzLCBtYm94KTsKKworCWlmIChyZCAhPSBudWxsKSB7CisJICAgIGlmIChyZCA9PSBSZXN5bmNEYXRhLkNPTkRTVE9SRSkgeworCQlpZiAoIWhhc0NhcGFiaWxpdHkoIkNPTkRTVE9SRSIpKQorCQkgICAgdGhyb3cgbmV3IEJhZENvbW1hbmRFeGNlcHRpb24oIkNPTkRTVE9SRSBub3Qgc3VwcG9ydGVkIik7CisJCWFyZ3Mud3JpdGVBcmd1bWVudChuZXcgQXJndW1lbnQoKS53cml0ZUF0b20oIkNPTkRTVE9SRSIpKTsKKwkgICAgfSBlbHNlIHsKKwkJaWYgKCFoYXNDYXBhYmlsaXR5KCJRUkVTWU5DIikpIAorCQkgICAgdGhyb3cgbmV3IEJhZENvbW1hbmRFeGNlcHRpb24oIlFSRVNZTkMgbm90IHN1cHBvcnRlZCIpOworCQlhcmdzLndyaXRlQXJndW1lbnQocmVzeW5jQXJncyhyZCkpOworCSAgICB9CisJfQorCisJUmVzcG9uc2VbXSByID0gY29tbWFuZCgiU0VMRUNUIiwgYXJncyk7CisKKwkvLyBOb3RlIHRoYXQgTWFpbGJveEluZm8gYWxzbyByZW1vdmVzIHRob3NlIHJlc3BvbnNlcyAKKwkvLyBpdCBrbm93cyBhYm91dAorCU1haWxib3hJbmZvIG1pbmZvID0gbmV3IE1haWxib3hJbmZvKHIpOworCQorCS8vIGRpc3BhdGNoIGFueSByZW1haW5pbmcgdW50YWdnZWQgcmVzcG9uc2VzCisJbm90aWZ5UmVzcG9uc2VIYW5kbGVycyhyKTsKKworCVJlc3BvbnNlIHJlc3BvbnNlID0gcltyLmxlbmd0aC0xXTsKKworCWlmIChyZXNwb25zZS5pc09LKCkpIHsgLy8gY29tbWFuZCBzdWNjZXNmdWwgCisJICAgIGlmIChyZXNwb25zZS50b1N0cmluZygpLmluZGV4T2YoIlJFQUQtT05MWSIpICE9IC0xKQorCQltaW5mby5tb2RlID0gRm9sZGVyLlJFQURfT05MWTsKKwkgICAgZWxzZQorCQltaW5mby5tb2RlID0gRm9sZGVyLlJFQURfV1JJVEU7CisJfSAKKwkKKwloYW5kbGVSZXN1bHQocmVzcG9uc2UpOworCXJldHVybiBtaW5mbzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFWEFNSU5FIENvbW1hbmQuCisgICAgICoKKyAgICAgKiBAcGFyYW0JbWJveAl0aGUgbWFpbGJveCBuYW1lCisgICAgICogQHJldHVybgkJTWFpbGJveEluZm8gaWYgc3VjY2Vzc2Z1bAorICAgICAqIEBleGNlcHRpb24JUHJvdG9jb2xFeGNlcHRpb24JZm9yIHByb3RvY29sIGZhaWx1cmVzCisgICAgICogQHNlZSAiUkZDMjA2MCwgc2VjdGlvbiA2LjMuMiIKKyAgICAgKi8KKyAgICBwdWJsaWMgTWFpbGJveEluZm8gZXhhbWluZShTdHJpbmcgbWJveCkgdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKwlyZXR1cm4gZXhhbWluZShtYm94LCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFWEFNSU5FIENvbW1hbmQgd2l0aCBRUkVTWU5DIGRhdGEuCisgICAgICoKKyAgICAgKiBAcGFyYW0JbWJveAl0aGUgbWFpbGJveCBuYW1lCisgICAgICogQHBhcmFtCXJkCXRoZSBSZXN5bmNEYXRhCisgICAgICogQHJldHVybgkJTWFpbGJveEluZm8gaWYgc3VjY2Vzc2Z1bAorICAgICAqIEBleGNlcHRpb24JUHJvdG9jb2xFeGNlcHRpb24JZm9yIHByb3RvY29sIGZhaWx1cmVzCisgICAgICogQHNlZSAiUkZDMjA2MCwgc2VjdGlvbiA2LjMuMiIKKyAgICAgKiBAc2VlICJSRkM1MTYyLCBzZWN0aW9uIDMuMSIKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS41LjEKKyAgICAgKi8KKyAgICBwdWJsaWMgTWFpbGJveEluZm8gZXhhbWluZShTdHJpbmcgbWJveCwgUmVzeW5jRGF0YSByZCkKKwkJCQl0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCUFyZ3VtZW50IGFyZ3MgPSBuZXcgQXJndW1lbnQoKTsJCisJd3JpdGVNYWlsYm94TmFtZShhcmdzLCBtYm94KTsKKworCWlmIChyZCAhPSBudWxsKSB7CisJICAgIGlmIChyZCA9PSBSZXN5bmNEYXRhLkNPTkRTVE9SRSkgeworCQlpZiAoIWhhc0NhcGFiaWxpdHkoIkNPTkRTVE9SRSIpKQorCQkgICAgdGhyb3cgbmV3IEJhZENvbW1hbmRFeGNlcHRpb24oIkNPTkRTVE9SRSBub3Qgc3VwcG9ydGVkIik7CisJCWFyZ3Mud3JpdGVBcmd1bWVudChuZXcgQXJndW1lbnQoKS53cml0ZUF0b20oIkNPTkRTVE9SRSIpKTsKKwkgICAgfSBlbHNlIHsKKwkJaWYgKCFoYXNDYXBhYmlsaXR5KCJRUkVTWU5DIikpIAorCQkgICAgdGhyb3cgbmV3IEJhZENvbW1hbmRFeGNlcHRpb24oIlFSRVNZTkMgbm90IHN1cHBvcnRlZCIpOworCQlhcmdzLndyaXRlQXJndW1lbnQocmVzeW5jQXJncyhyZCkpOworCSAgICB9CisJfQorCisJUmVzcG9uc2VbXSByID0gY29tbWFuZCgiRVhBTUlORSIsIGFyZ3MpOworCisJLy8gTm90ZSB0aGF0IE1haWxib3hJbmZvIGFsc28gcmVtb3ZlcyB0aG9zZSByZXNwb25zZXMKKwkvLyBpdCBrbm93cyBhYm91dAorCU1haWxib3hJbmZvIG1pbmZvID0gbmV3IE1haWxib3hJbmZvKHIpOworCW1pbmZvLm1vZGUgPSBGb2xkZXIuUkVBRF9PTkxZOyAvLyBPYnZpb3VzbHkKKworCS8vIGRpc3BhdGNoIGFueSByZW1haW5pbmcgdW50YWdnZWQgcmVzcG9uc2VzCisJbm90aWZ5UmVzcG9uc2VIYW5kbGVycyhyKTsKKworCWhhbmRsZVJlc3VsdChyW3IubGVuZ3RoLTFdKTsKKwlyZXR1cm4gbWluZm87CisgICAgfQorCisgICAgLyoqCisgICAgICogR2VuZXJhdGUgYSBRUkVTWU5DIGFyZ3VtZW50IGxpc3QgYmFzZWQgb24gdGhlIFJlc3luY0RhdGEuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgQXJndW1lbnQgcmVzeW5jQXJncyhSZXN5bmNEYXRhIHJkKSB7CisJQXJndW1lbnQgY21kID0gbmV3IEFyZ3VtZW50KCk7CisJY21kLndyaXRlQXRvbSgiUVJFU1lOQyIpOworCUFyZ3VtZW50IGFyZ3MgPSBuZXcgQXJndW1lbnQoKTsKKwlhcmdzLndyaXRlTnVtYmVyKHJkLmdldFVJRFZhbGlkaXR5KCkpOworCWFyZ3Mud3JpdGVOdW1iZXIocmQuZ2V0TW9kU2VxKCkpOworCVVJRFNldFtdIHVpZHMgPSBVdGlsaXR5LmdldFJlc3luY1VJRFNldChyZCk7CisJaWYgKHVpZHMgIT0gbnVsbCkKKwkgICAgYXJncy53cml0ZVN0cmluZyhVSURTZXQudG9TdHJpbmcodWlkcykpOworCWNtZC53cml0ZUFyZ3VtZW50KGFyZ3MpOworCXJldHVybiBjbWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogRU5BQkxFIENvbW1hbmQuCisgICAgICoKKyAgICAgKiBAcGFyYW0JY2FwCXRoZSBuYW1lIG9mIHRoZSBjYXBhYmlsaXR5IHRvIGVuYWJsZQorICAgICAqIEBleGNlcHRpb24JUHJvdG9jb2xFeGNlcHRpb24JZm9yIHByb3RvY29sIGZhaWx1cmVzCisgICAgICogQHNlZSAiUkZDIDUxNjEiCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNS4xCisgICAgICovCisgICAgcHVibGljIHZvaWQgZW5hYmxlKFN0cmluZyBjYXApIHRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJaWYgKCFoYXNDYXBhYmlsaXR5KCJFTkFCTEUiKSkgCisJICAgIHRocm93IG5ldyBCYWRDb21tYW5kRXhjZXB0aW9uKCJFTkFCTEUgbm90IHN1cHBvcnRlZCIpOworCUFyZ3VtZW50IGFyZ3MgPSBuZXcgQXJndW1lbnQoKTsKKwlhcmdzLndyaXRlQXRvbShjYXApOworCXNpbXBsZUNvbW1hbmQoIkVOQUJMRSIsIGFyZ3MpOworCWlmIChlbmFibGVkID09IG51bGwpCisJICAgIGVuYWJsZWQgPSBuZXcgSGFzaFNldDw+KCk7CisJZW5hYmxlZC5hZGQoY2FwLnRvVXBwZXJDYXNlKExvY2FsZS5FTkdMSVNIKSk7CisKKwkvLyB1cGRhdGUgdGhlIHV0ZjggZmxhZworCXV0ZjggPSBpc0VuYWJsZWQoIlVURjg9QUNDRVBUIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogSXMgdGhlIGNhcGFiaWxpdHkvZXh0ZW5zaW9uIGVuYWJsZWQ/CisgICAgICoKKyAgICAgKiBAcGFyYW0JY2FwCXRoZSBjYXBhYmlsaXR5IG5hbWUKKyAgICAgKiBAcmV0dXJuCQl0cnVlIGlmIGVuYWJsZWQKKyAgICAgKiBAc2VlICJSRkMgNTE2MSIKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS41LjEKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0VuYWJsZWQoU3RyaW5nIGNhcCkgeworCWlmIChlbmFibGVkID09IG51bGwpCisJICAgIHJldHVybiBmYWxzZTsKKwllbHNlCisJICAgIHJldHVybiBlbmFibGVkLmNvbnRhaW5zKGNhcC50b1VwcGVyQ2FzZShMb2NhbGUuRU5HTElTSCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFVOU0VMRUNUIENvbW1hbmQuCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uCVByb3RvY29sRXhjZXB0aW9uCWZvciBwcm90b2NvbCBmYWlsdXJlcworICAgICAqIEBzZWUgIlJGQyAzNjkxIgorICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjQuNAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVuc2VsZWN0KCkgdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKwlpZiAoIWhhc0NhcGFiaWxpdHkoIlVOU0VMRUNUIikpIAorCSAgICB0aHJvdyBuZXcgQmFkQ29tbWFuZEV4Y2VwdGlvbigiVU5TRUxFQ1Qgbm90IHN1cHBvcnRlZCIpOworCXNpbXBsZUNvbW1hbmQoIlVOU0VMRUNUIiwgbnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU1RBVFVTIENvbW1hbmQuCisgICAgICoKKyAgICAgKiBAcGFyYW0JbWJveAl0aGUgbWFpbGJveAorICAgICAqIEBwYXJhbQlpdGVtcwl0aGUgU1RBVFVTIGl0ZW1zIHRvIHJlcXVlc3QKKyAgICAgKiBAcmV0dXJuCQlTVEFUVVMgcmVzdWx0cworICAgICAqIEBleGNlcHRpb24JUHJvdG9jb2xFeGNlcHRpb24JZm9yIHByb3RvY29sIGZhaWx1cmVzCisgICAgICogQHNlZSAiUkZDMjA2MCwgc2VjdGlvbiA2LjMuMTAiCisgICAgICovCisgICAgcHVibGljIFN0YXR1cyBzdGF0dXMoU3RyaW5nIG1ib3gsIFN0cmluZ1tdIGl0ZW1zKSAKKwkJdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKwlpZiAoIWlzUkVWMSgpICYmICFoYXNDYXBhYmlsaXR5KCJJTUFQNFNVTlZFUlNJT04iKSkgCisJICAgIC8vIFNUQVRVUyBpcyByZXYxIG9ubHksIGhvd2V2ZXIgdGhlIG5vbi1yZXYxIFNJTVMyLjAgCisJICAgIC8vIGRvZXMgc3VwcG9ydCB0aGlzLgorCSAgICB0aHJvdyBuZXcgQmFkQ29tbWFuZEV4Y2VwdGlvbigiU1RBVFVTIG5vdCBzdXBwb3J0ZWQiKTsKKworCUFyZ3VtZW50IGFyZ3MgPSBuZXcgQXJndW1lbnQoKTsJCisJd3JpdGVNYWlsYm94TmFtZShhcmdzLCBtYm94KTsKKworCUFyZ3VtZW50IGl0ZW1BcmdzID0gbmV3IEFyZ3VtZW50KCk7CisJaWYgKGl0ZW1zID09IG51bGwpCisJICAgIGl0ZW1zID0gU3RhdHVzLnN0YW5kYXJkSXRlbXM7CisKKwlmb3IgKGludCBpID0gMCwgbGVuID0gaXRlbXMubGVuZ3RoOyBpIDwgbGVuOyBpKyspCisJICAgIGl0ZW1BcmdzLndyaXRlQXRvbShpdGVtc1tpXSk7CisJYXJncy53cml0ZUFyZ3VtZW50KGl0ZW1BcmdzKTsKKworCVJlc3BvbnNlW10gciA9IGNvbW1hbmQoIlNUQVRVUyIsIGFyZ3MpOworCisJU3RhdHVzIHN0YXR1cyA9IG51bGw7CisJUmVzcG9uc2UgcmVzcG9uc2UgPSByW3IubGVuZ3RoLTFdOworCisJLy8gR3JhYiBhbGwgU1RBVFVTIHJlc3BvbnNlcworCWlmIChyZXNwb25zZS5pc09LKCkpIHsgLy8gY29tbWFuZCBzdWNjZXNmdWwgCisJICAgIGZvciAoaW50IGkgPSAwLCBsZW4gPSByLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7CisJCWlmICghKHJbaV0gaW5zdGFuY2VvZiBJTUFQUmVzcG9uc2UpKQorCQkgICAgY29udGludWU7CisKKwkJSU1BUFJlc3BvbnNlIGlyID0gKElNQVBSZXNwb25zZSlyW2ldOworCQlpZiAoaXIua2V5RXF1YWxzKCJTVEFUVVMiKSkgeworCQkgICAgaWYgKHN0YXR1cyA9PSBudWxsKQorCQkJc3RhdHVzID0gbmV3IFN0YXR1cyhpcik7CisJCSAgICBlbHNlIC8vIGNvbGxlY3QgJ2VtIGFsbAorCQkJU3RhdHVzLmFkZChzdGF0dXMsIG5ldyBTdGF0dXMoaXIpKTsKKwkJICAgIHJbaV0gPSBudWxsOworCQl9CisJICAgIH0KKwl9CisKKwkvLyBkaXNwYXRjaCByZW1haW5pbmcgdW50YWdnZWQgcmVzcG9uc2VzCisJbm90aWZ5UmVzcG9uc2VIYW5kbGVycyhyKTsKKwloYW5kbGVSZXN1bHQocmVzcG9uc2UpOworCXJldHVybiBzdGF0dXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ1JFQVRFIENvbW1hbmQuCisgICAgICoKKyAgICAgKiBAcGFyYW0JbWJveAl0aGUgbWFpbGJveCB0byBjcmVhdGUKKyAgICAgKiBAZXhjZXB0aW9uCVByb3RvY29sRXhjZXB0aW9uCWZvciBwcm90b2NvbCBmYWlsdXJlcworICAgICAqIEBzZWUgIlJGQzIwNjAsIHNlY3Rpb24gNi4zLjMiCisgICAgICovCisgICAgcHVibGljIHZvaWQgY3JlYXRlKFN0cmluZyBtYm94KSB0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCUFyZ3VtZW50IGFyZ3MgPSBuZXcgQXJndW1lbnQoKTsJCisJd3JpdGVNYWlsYm94TmFtZShhcmdzLCBtYm94KTsKKworCXNpbXBsZUNvbW1hbmQoIkNSRUFURSIsIGFyZ3MpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERFTEVURSBDb21tYW5kLgorICAgICAqCisgICAgICogQHBhcmFtCW1ib3gJdGhlIG1haWxib3ggdG8gZGVsZXRlCisgICAgICogQGV4Y2VwdGlvbglQcm90b2NvbEV4Y2VwdGlvbglmb3IgcHJvdG9jb2wgZmFpbHVyZXMKKyAgICAgKiBAc2VlICJSRkMyMDYwLCBzZWN0aW9uIDYuMy40IgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGRlbGV0ZShTdHJpbmcgbWJveCkgdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKwlBcmd1bWVudCBhcmdzID0gbmV3IEFyZ3VtZW50KCk7CQorCXdyaXRlTWFpbGJveE5hbWUoYXJncywgbWJveCk7CisKKwlzaW1wbGVDb21tYW5kKCJERUxFVEUiLCBhcmdzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSRU5BTUUgQ29tbWFuZC4KKyAgICAgKgorICAgICAqIEBwYXJhbQlvCW9sZCBtYWlsYm94IG5hbWUKKyAgICAgKiBAcGFyYW0JbgluZXcgbWFpbGJveCBuYW1lCisgICAgICogQGV4Y2VwdGlvbglQcm90b2NvbEV4Y2VwdGlvbglmb3IgcHJvdG9jb2wgZmFpbHVyZXMKKyAgICAgKiBAc2VlICJSRkMyMDYwLCBzZWN0aW9uIDYuMy41IgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlbmFtZShTdHJpbmcgbywgU3RyaW5nIG4pIHRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJQXJndW1lbnQgYXJncyA9IG5ldyBBcmd1bWVudCgpOwkKKwl3cml0ZU1haWxib3hOYW1lKGFyZ3MsIG8pOworCXdyaXRlTWFpbGJveE5hbWUoYXJncywgbik7CisKKwlzaW1wbGVDb21tYW5kKCJSRU5BTUUiLCBhcmdzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTVUJTQ1JJQkUgQ29tbWFuZC4KKyAgICAgKgorICAgICAqIEBwYXJhbQltYm94CXRoZSBtYWlsYm94CisgICAgICogQGV4Y2VwdGlvbglQcm90b2NvbEV4Y2VwdGlvbglmb3IgcHJvdG9jb2wgZmFpbHVyZXMKKyAgICAgKiBAc2VlICJSRkMyMDYwLCBzZWN0aW9uIDYuMy42IgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHN1YnNjcmliZShTdHJpbmcgbWJveCkgdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKwlBcmd1bWVudCBhcmdzID0gbmV3IEFyZ3VtZW50KCk7CQorCXdyaXRlTWFpbGJveE5hbWUoYXJncywgbWJveCk7CisKKwlzaW1wbGVDb21tYW5kKCJTVUJTQ1JJQkUiLCBhcmdzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVTlNVQlNDUklCRSBDb21tYW5kLgorICAgICAqCisgICAgICogQHBhcmFtCW1ib3gJdGhlIG1haWxib3gKKyAgICAgKiBAZXhjZXB0aW9uCVByb3RvY29sRXhjZXB0aW9uCWZvciBwcm90b2NvbCBmYWlsdXJlcworICAgICAqIEBzZWUgIlJGQzIwNjAsIHNlY3Rpb24gNi4zLjciCisgICAgICovCisgICAgcHVibGljIHZvaWQgdW5zdWJzY3JpYmUoU3RyaW5nIG1ib3gpIHRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJQXJndW1lbnQgYXJncyA9IG5ldyBBcmd1bWVudCgpOwkKKwl3cml0ZU1haWxib3hOYW1lKGFyZ3MsIG1ib3gpOworCisJc2ltcGxlQ29tbWFuZCgiVU5TVUJTQ1JJQkUiLCBhcmdzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMSVNUIENvbW1hbmQuCisgICAgICoKKyAgICAgKiBAcGFyYW0JcmVmCXJlZmVyZW5jZSBzdHJpbmcKKyAgICAgKiBAcGFyYW0JcGF0dGVybglwYXR0ZXJuIHRvIGxpc3QKKyAgICAgKiBAcmV0dXJuCQlMSVNUIHJlc3VsdHMKKyAgICAgKiBAZXhjZXB0aW9uCVByb3RvY29sRXhjZXB0aW9uCWZvciBwcm90b2NvbCBmYWlsdXJlcworICAgICAqIEBzZWUgIlJGQzIwNjAsIHNlY3Rpb24gNi4zLjgiCisgICAgICovCisgICAgcHVibGljIExpc3RJbmZvW10gbGlzdChTdHJpbmcgcmVmLCBTdHJpbmcgcGF0dGVybikgCisJCQl0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCXJldHVybiBkb0xpc3QoIkxJU1QiLCByZWYsIHBhdHRlcm4pOworICAgIH0KKworICAgIC8qKgorICAgICAqIExTVUIgQ29tbWFuZC4KKyAgICAgKgorICAgICAqIEBwYXJhbQlyZWYJcmVmZXJlbmNlIHN0cmluZworICAgICAqIEBwYXJhbQlwYXR0ZXJuCXBhdHRlcm4gdG8gbGlzdAorICAgICAqIEByZXR1cm4JCUxTVUIgcmVzdWx0cworICAgICAqIEBleGNlcHRpb24JUHJvdG9jb2xFeGNlcHRpb24JZm9yIHByb3RvY29sIGZhaWx1cmVzCisgICAgICogQHNlZSAiUkZDMjA2MCwgc2VjdGlvbiA2LjMuOSIKKyAgICAgKi8KKyAgICBwdWJsaWMgTGlzdEluZm9bXSBsc3ViKFN0cmluZyByZWYsIFN0cmluZyBwYXR0ZXJuKSAKKwkJCXRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJcmV0dXJuIGRvTGlzdCgiTFNVQiIsIHJlZiwgcGF0dGVybik7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXhlY3V0ZSB0aGUgc3BlY2lmaWVkIExJU1QtbGlrZSBjb21tYW5kIChlLmcuLCAiTElTVCIgb3IgIkxTVUIiKSwKKyAgICAgKiB1c2luZyB0aGUgcmVmZXJlbmNlIGFuZCBwYXR0ZXJuLgorICAgICAqCisgICAgICogQHBhcmFtCWNtZAl0aGUgbGlzdCBjb21tYW5kCisgICAgICogQHBhcmFtCXJlZgl0aGUgcmVmZXJlbmNlIHN0cmluZworICAgICAqIEBwYXJhbQlwYXQJdGhlIHBhdHRlcm4KKyAgICAgKiBAcmV0dXJuCQlhcnJheSBvZiBMaXN0SW5mbyByZXN1bHRzCisgICAgICogQGV4Y2VwdGlvbglQcm90b2NvbEV4Y2VwdGlvbglmb3IgcHJvdG9jb2wgZmFpbHVyZXMKKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS40LjYKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgTGlzdEluZm9bXSBkb0xpc3QoU3RyaW5nIGNtZCwgU3RyaW5nIHJlZiwgU3RyaW5nIHBhdCkKKwkJCXRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJQXJndW1lbnQgYXJncyA9IG5ldyBBcmd1bWVudCgpOwkKKwl3cml0ZU1haWxib3hOYW1lKGFyZ3MsIHJlZik7CisJd3JpdGVNYWlsYm94TmFtZShhcmdzLCBwYXQpOworCisJUmVzcG9uc2VbXSByID0gY29tbWFuZChjbWQsIGFyZ3MpOworCisJTGlzdEluZm9bXSBsaW5mbyA9IG51bGw7CisJUmVzcG9uc2UgcmVzcG9uc2UgPSByW3IubGVuZ3RoLTFdOworCisJaWYgKHJlc3BvbnNlLmlzT0soKSkgeyAvLyBjb21tYW5kIHN1Y2Nlc2Z1bCAKKwkgICAgTGlzdDxMaXN0SW5mbz4gdiA9IG5ldyBBcnJheUxpc3Q8PigxKTsKKwkgICAgZm9yIChpbnQgaSA9IDAsIGxlbiA9IHIubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHsKKwkJaWYgKCEocltpXSBpbnN0YW5jZW9mIElNQVBSZXNwb25zZSkpCisJCSAgICBjb250aW51ZTsKKworCQlJTUFQUmVzcG9uc2UgaXIgPSAoSU1BUFJlc3BvbnNlKXJbaV07CisJCWlmIChpci5rZXlFcXVhbHMoY21kKSkgeworCQkgICAgdi5hZGQobmV3IExpc3RJbmZvKGlyKSk7CisJCSAgICByW2ldID0gbnVsbDsKKwkJfQorCSAgICB9CisJICAgIGlmICh2LnNpemUoKSA+IDApIHsKKwkJbGluZm8gPSB2LnRvQXJyYXkobmV3IExpc3RJbmZvW3Yuc2l6ZSgpXSk7CisJICAgIH0KKwl9CisJCisJLy8gRGlzcGF0Y2ggcmVtYWluaW5nIHVudGFnZ2VkIHJlc3BvbnNlcworCW5vdGlmeVJlc3BvbnNlSGFuZGxlcnMocik7CisJaGFuZGxlUmVzdWx0KHJlc3BvbnNlKTsKKwlyZXR1cm4gbGluZm87CisgICAgfQorCQkKKyAgICAvKioKKyAgICAgKiBBUFBFTkQgQ29tbWFuZC4KKyAgICAgKgorICAgICAqIEBwYXJhbQltYm94CXRoZSBtYWlsYm94CisgICAgICogQHBhcmFtCWYJdGhlIG1lc3NhZ2UgRmxhZ3MKKyAgICAgKiBAcGFyYW0JZAl0aGUgbWVzc2FnZSBkYXRlCisgICAgICogQHBhcmFtCWRhdGEJdGhlIG1lc3NhZ2UgZGF0YQorICAgICAqIEBleGNlcHRpb24JUHJvdG9jb2xFeGNlcHRpb24JZm9yIHByb3RvY29sIGZhaWx1cmVzCisgICAgICogQHNlZSAiUkZDMjA2MCwgc2VjdGlvbiA2LjMuMTEiCisgICAgICovCisgICAgcHVibGljIHZvaWQgYXBwZW5kKFN0cmluZyBtYm94LCBGbGFncyBmLCBEYXRlIGQsCisJCQlMaXRlcmFsIGRhdGEpIHRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJYXBwZW5kdWlkKG1ib3gsIGYsIGQsIGRhdGEsIGZhbHNlKTsJLy8gaWdub3JlIHJldHVybiB2YWx1ZQorICAgIH0KKworICAgIC8qKgorICAgICAqIEFQUEVORCBDb21tYW5kLCByZXR1cm4gdWlkIGZyb20gQVBQRU5EVUlEIHJlc3BvbnNlIGNvZGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0JbWJveAl0aGUgbWFpbGJveAorICAgICAqIEBwYXJhbQlmCXRoZSBtZXNzYWdlIEZsYWdzCisgICAgICogQHBhcmFtCWQJdGhlIG1lc3NhZ2UgZGF0ZQorICAgICAqIEBwYXJhbQlkYXRhCXRoZSBtZXNzYWdlIGRhdGEKKyAgICAgKiBAcmV0dXJuCQlBUFBFTkRVSUQgZGF0YQorICAgICAqIEBleGNlcHRpb24JUHJvdG9jb2xFeGNlcHRpb24JZm9yIHByb3RvY29sIGZhaWx1cmVzCisgICAgICogQHNlZSAiUkZDMjA2MCwgc2VjdGlvbiA2LjMuMTEiCisgICAgICovCisgICAgcHVibGljIEFwcGVuZFVJRCBhcHBlbmR1aWQoU3RyaW5nIG1ib3gsIEZsYWdzIGYsIERhdGUgZCwKKwkJCUxpdGVyYWwgZGF0YSkgdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKwlyZXR1cm4gYXBwZW5kdWlkKG1ib3gsIGYsIGQsIGRhdGEsIHRydWUpOworICAgIH0KKworICAgIHB1YmxpYyBBcHBlbmRVSUQgYXBwZW5kdWlkKFN0cmluZyBtYm94LCBGbGFncyBmLCBEYXRlIGQsCisJCQlMaXRlcmFsIGRhdGEsIGJvb2xlYW4gdWlkKSB0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCUFyZ3VtZW50IGFyZ3MgPSBuZXcgQXJndW1lbnQoKTsJCisJd3JpdGVNYWlsYm94TmFtZShhcmdzLCBtYm94KTsKKworCWlmIChmICE9IG51bGwpIHsgLy8gc2V0IEZsYWdzIGluIGFwcGVuZGVkIG1lc3NhZ2UKKwkgICAgLy8gY2FuJ3Qgc2V0IHRoZSBcUmVjZW50IGZsYWcgaW4gQVBQRU5ECisJICAgIGlmIChmLmNvbnRhaW5zKEZsYWdzLkZsYWcuUkVDRU5UKSkgeworCQlmID0gbmV3IEZsYWdzKGYpOwkJLy8gY29weSwgZG9uJ3QgbW9kaWZ5IG9yaWcKKwkJZi5yZW1vdmUoRmxhZ3MuRmxhZy5SRUNFTlQpOwkvLyByZW1vdmUgUkVDRU5UIGZyb20gY29weQorCSAgICB9CisKKwkgICAgLyoKKwkgICAgICogSEFDSyBBTEVSVDogV2Ugd2FudCB0aGUgZmxhZ19saXN0IHRvIGJlIHdyaXR0ZW4gb3V0CisJICAgICAqIHdpdGhvdXQgYW55IGNoZWNraW5nL3Byb2Nlc3Npbmcgb2YgdGhlIGJ5dGVzIGluIGl0LiBJZgorCSAgICAgKiBJIHVzZSB3cml0ZVN0cmluZygpLCB0aGUgZmxhZ19saXN0IHdpbGwgZW5kIHVwIGJlaW5nCisJICAgICAqIHF1b3RlZCBzaW5jZSBpdCBjb250YWlucyAiaWxsZWdhbCIgY2hhcmFjdGVycy4gU28gSQorCSAgICAgKiBhbSBkZXBlbmRpbmcgb24gaW1wbGVtZW50YXRpb24ga25vd2xlZGdlIHRoYXQgd3JpdGVBdG9tKCkKKwkgICAgICogZG9lcyBub3QgZG8gYW55IGNoZWNraW5nL3Byb2Nlc3NpbmcgLSBpdCBqdXN0IHdyaXRlcyBvdXQKKwkgICAgICogdGhlIGJ5dGVzLiBXaGF0IHdlIHJlYWxseSBuZWVkIGlzIGEgd3JpdGVGb28oKSB0aGF0IGp1c3QKKwkgICAgICogZHVtcHMgb3V0IGl0cyBhcmd1bWVudC4KKwkgICAgICovCisJICAgIGFyZ3Mud3JpdGVBdG9tKGNyZWF0ZUZsYWdMaXN0KGYpKTsKKwl9CisJaWYgKGQgIT0gbnVsbCkgLy8gc2V0IElOVEVSTkFMREFURSBpbiBhcHBlbmRlZCBtZXNzYWdlCisJICAgIGFyZ3Mud3JpdGVTdHJpbmcoSU5URVJOQUxEQVRFLmZvcm1hdChkKSk7CisKKwlhcmdzLndyaXRlQnl0ZXMoZGF0YSk7CisKKwlSZXNwb25zZVtdIHIgPSBjb21tYW5kKCJBUFBFTkQiLCBhcmdzKTsKKworCS8vIGRpc3BhdGNoIHVudGFnZ2VkIHJlc3BvbnNlcworCW5vdGlmeVJlc3BvbnNlSGFuZGxlcnMocik7CisKKwkvLyBIYW5kbGUgcmVzdWx0IG9mIHRoaXMgY29tbWFuZAorCWhhbmRsZVJlc3VsdChyW3IubGVuZ3RoLTFdKTsKKworCWlmICh1aWQpCisJICAgIHJldHVybiBnZXRBcHBlbmRVSUQocltyLmxlbmd0aC0xXSk7CisJZWxzZQorCSAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJZiB0aGUgcmVzcG9uc2UgY29udGFpbnMgYW4gQVBQRU5EVUlEIHJlc3BvbnNlIGNvZGUsIGV4dHJhY3QKKyAgICAgKiBpdCBhbmQgcmV0dXJuIGFuIEFwcGVuZFVJRCBvYmplY3Qgd2l0aCB0aGUgaW5mb3JtYXRpb24uCisgICAgICovCisgICAgcHJpdmF0ZSBBcHBlbmRVSUQgZ2V0QXBwZW5kVUlEKFJlc3BvbnNlIHIpIHsKKwlpZiAoIXIuaXNPSygpKQorCSAgICByZXR1cm4gbnVsbDsKKwlieXRlIGI7CisJd2hpbGUgKChiID0gci5yZWFkQnl0ZSgpKSA+IDAgJiYgYiAhPSAoYnl0ZSknWycpCisJICAgIDsKKwlpZiAoYiA9PSAwKQorCSAgICByZXR1cm4gbnVsbDsKKwlTdHJpbmcgczsKKwlzID0gci5yZWFkQXRvbSgpOworCWlmICghcy5lcXVhbHNJZ25vcmVDYXNlKCJBUFBFTkRVSUQiKSkKKwkgICAgcmV0dXJuIG51bGw7CisKKwlsb25nIHVpZHZhbGlkaXR5ID0gci5yZWFkTG9uZygpOworCWxvbmcgdWlkID0gci5yZWFkTG9uZygpOworCXJldHVybiBuZXcgQXBwZW5kVUlEKHVpZHZhbGlkaXR5LCB1aWQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENIRUNLIENvbW1hbmQuCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uCVByb3RvY29sRXhjZXB0aW9uCWZvciBwcm90b2NvbCBmYWlsdXJlcworICAgICAqIEBzZWUgIlJGQzIwNjAsIHNlY3Rpb24gNi40LjEiCisgICAgICovCisgICAgcHVibGljIHZvaWQgY2hlY2soKSB0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCXNpbXBsZUNvbW1hbmQoIkNIRUNLIiwgbnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ0xPU0UgQ29tbWFuZC4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24JUHJvdG9jb2xFeGNlcHRpb24JZm9yIHByb3RvY29sIGZhaWx1cmVzCisgICAgICogQHNlZSAiUkZDMjA2MCwgc2VjdGlvbiA2LjQuMiIKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJc2ltcGxlQ29tbWFuZCgiQ0xPU0UiLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFWFBVTkdFIENvbW1hbmQuCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uCVByb3RvY29sRXhjZXB0aW9uCWZvciBwcm90b2NvbCBmYWlsdXJlcworICAgICAqIEBzZWUgIlJGQzIwNjAsIHNlY3Rpb24gNi40LjMiCisgICAgICovCisgICAgcHVibGljIHZvaWQgZXhwdW5nZSgpIHRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJc2ltcGxlQ29tbWFuZCgiRVhQVU5HRSIsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFVJRCBFWFBVTkdFIENvbW1hbmQuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jc2V0CVVJRHMgdG8gZXhwdW5nZQorICAgICAqIEBleGNlcHRpb24JUHJvdG9jb2xFeGNlcHRpb24JZm9yIHByb3RvY29sIGZhaWx1cmVzCisgICAgICogQHNlZSAiUkZDNDMxNSwgc2VjdGlvbiAyIgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVpZGV4cHVuZ2UoVUlEU2V0W10gc2V0KSB0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCWlmICghaGFzQ2FwYWJpbGl0eSgiVUlEUExVUyIpKSAKKwkgICAgdGhyb3cgbmV3IEJhZENvbW1hbmRFeGNlcHRpb24oIlVJRCBFWFBVTkdFIG5vdCBzdXBwb3J0ZWQiKTsKKwlzaW1wbGVDb21tYW5kKCJVSUQgRVhQVU5HRSAiICsgVUlEU2V0LnRvU3RyaW5nKHNldCksIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZldGNoIHRoZSBCT0RZU1RSVUNUVVJFIG9mIHRoZSBzcGVjaWZpZWQgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbQltc2dubwl0aGUgbWVzc2FnZSBudW1iZXIKKyAgICAgKiBAcmV0dXJuCQl0aGUgQk9EWVNUUlVDVFVSRSBpdGVtCisgICAgICogQGV4Y2VwdGlvbglQcm90b2NvbEV4Y2VwdGlvbglmb3IgcHJvdG9jb2wgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgQk9EWVNUUlVDVFVSRSBmZXRjaEJvZHlTdHJ1Y3R1cmUoaW50IG1zZ25vKSAKKwkJCXRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJUmVzcG9uc2VbXSByID0gZmV0Y2gobXNnbm8sICJCT0RZU1RSVUNUVVJFIik7CisJbm90aWZ5UmVzcG9uc2VIYW5kbGVycyhyKTsKKworCVJlc3BvbnNlIHJlc3BvbnNlID0gcltyLmxlbmd0aC0xXTsKKwlpZiAocmVzcG9uc2UuaXNPSygpKQorCSAgICByZXR1cm4gRmV0Y2hSZXNwb25zZS5nZXRJdGVtKHIsIG1zZ25vLCBCT0RZU1RSVUNUVVJFLmNsYXNzKTsKKwllbHNlIGlmIChyZXNwb25zZS5pc05PKCkpCisJICAgIHJldHVybiBudWxsOworCWVsc2UgeworCSAgICBoYW5kbGVSZXN1bHQocmVzcG9uc2UpOworCSAgICByZXR1cm4gbnVsbDsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogRmV0Y2ggZ2l2ZW4gQk9EWSBzZWN0aW9uLCB3aXRob3V0IG1hcmtpbmcgdGhlIG1lc3NhZ2UKKyAgICAgKiBhcyBTRUVOLgorICAgICAqCisgICAgICogQHBhcmFtCW1zZ25vCXRoZSBtZXNzYWdlIG51bWJlcgorICAgICAqIEBwYXJhbQlzZWN0aW9uCXRoZSBib2R5IHNlY3Rpb24KKyAgICAgKiBAcmV0dXJuCQl0aGUgQk9EWSBpdGVtCisgICAgICogQGV4Y2VwdGlvbglQcm90b2NvbEV4Y2VwdGlvbglmb3IgcHJvdG9jb2wgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgQk9EWSBwZWVrQm9keShpbnQgbXNnbm8sIFN0cmluZyBzZWN0aW9uKQorCQkJdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKwlyZXR1cm4gZmV0Y2hCb2R5KG1zZ25vLCBzZWN0aW9uLCB0cnVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGZXRjaCBnaXZlbiBCT0RZIHNlY3Rpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0JbXNnbm8JdGhlIG1lc3NhZ2UgbnVtYmVyCisgICAgICogQHBhcmFtCXNlY3Rpb24JdGhlIGJvZHkgc2VjdGlvbgorICAgICAqIEByZXR1cm4JCXRoZSBCT0RZIGl0ZW0KKyAgICAgKiBAZXhjZXB0aW9uCVByb3RvY29sRXhjZXB0aW9uCWZvciBwcm90b2NvbCBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBCT0RZIGZldGNoQm9keShpbnQgbXNnbm8sIFN0cmluZyBzZWN0aW9uKQorCQkJdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKwlyZXR1cm4gZmV0Y2hCb2R5KG1zZ25vLCBzZWN0aW9uLCBmYWxzZSk7CisgICAgfQorCisgICAgcHJvdGVjdGVkIEJPRFkgZmV0Y2hCb2R5KGludCBtc2dubywgU3RyaW5nIHNlY3Rpb24sIGJvb2xlYW4gcGVlaykKKwkJCXRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJUmVzcG9uc2VbXSByOworCisJaWYgKHNlY3Rpb24gPT0gbnVsbCkKKwkgICAgc2VjdGlvbiA9ICIiOworCVN0cmluZyBib2R5ID0gKHBlZWsgPyAiQk9EWS5QRUVLWyIgOiAiQk9EWVsiKSArIHNlY3Rpb24gKyAiXSI7CisJcmV0dXJuIGZldGNoU2VjdGlvbkJvZHkobXNnbm8sIHNlY3Rpb24sIGJvZHkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnRpYWwgRkVUQ0ggb2YgZ2l2ZW4gQk9EWSBzZWN0aW9uLCB3aXRob3V0IHNldHRpbmcgU0VFTiBmbGFnLgorICAgICAqCisgICAgICogQHBhcmFtCW1zZ25vCXRoZSBtZXNzYWdlIG51bWJlcgorICAgICAqIEBwYXJhbQlzZWN0aW9uCXRoZSBib2R5IHNlY3Rpb24KKyAgICAgKiBAcGFyYW0Jc3RhcnQJc3RhcnRpbmcgYnl0ZSBjb3VudAorICAgICAqIEBwYXJhbQlzaXplCW51bWJlciBvZiBieXRlcyB0byBmZXRjaAorICAgICAqIEByZXR1cm4JCXRoZSBCT0RZIGl0ZW0KKyAgICAgKiBAZXhjZXB0aW9uCVByb3RvY29sRXhjZXB0aW9uCWZvciBwcm90b2NvbCBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBCT0RZIHBlZWtCb2R5KGludCBtc2dubywgU3RyaW5nIHNlY3Rpb24sIGludCBzdGFydCwgaW50IHNpemUpCisJCQl0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCXJldHVybiBmZXRjaEJvZHkobXNnbm8sIHNlY3Rpb24sIHN0YXJ0LCBzaXplLCB0cnVlLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJ0aWFsIEZFVENIIG9mIGdpdmVuIEJPRFkgc2VjdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbQltc2dubwl0aGUgbWVzc2FnZSBudW1iZXIKKyAgICAgKiBAcGFyYW0Jc2VjdGlvbgl0aGUgYm9keSBzZWN0aW9uCisgICAgICogQHBhcmFtCXN0YXJ0CXN0YXJ0aW5nIGJ5dGUgY291bnQKKyAgICAgKiBAcGFyYW0Jc2l6ZQludW1iZXIgb2YgYnl0ZXMgdG8gZmV0Y2gKKyAgICAgKiBAcmV0dXJuCQl0aGUgQk9EWSBpdGVtCisgICAgICogQGV4Y2VwdGlvbglQcm90b2NvbEV4Y2VwdGlvbglmb3IgcHJvdG9jb2wgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgQk9EWSBmZXRjaEJvZHkoaW50IG1zZ25vLCBTdHJpbmcgc2VjdGlvbiwgaW50IHN0YXJ0LCBpbnQgc2l6ZSkKKwkJCXRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJcmV0dXJuIGZldGNoQm9keShtc2dubywgc2VjdGlvbiwgc3RhcnQsIHNpemUsIGZhbHNlLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJ0aWFsIEZFVENIIG9mIGdpdmVuIEJPRFkgc2VjdGlvbiwgd2l0aG91dCBzZXR0aW5nIFNFRU4gZmxhZy4KKyAgICAgKgorICAgICAqIEBwYXJhbQltc2dubwl0aGUgbWVzc2FnZSBudW1iZXIKKyAgICAgKiBAcGFyYW0Jc2VjdGlvbgl0aGUgYm9keSBzZWN0aW9uCisgICAgICogQHBhcmFtCXN0YXJ0CXN0YXJ0aW5nIGJ5dGUgY291bnQKKyAgICAgKiBAcGFyYW0Jc2l6ZQludW1iZXIgb2YgYnl0ZXMgdG8gZmV0Y2gKKyAgICAgKiBAcGFyYW0JYmEJdGhlIGJ1ZmZlciBpbnRvIHdoaWNoIHRvIHJlYWQgdGhlIHJlc3BvbnNlCisgICAgICogQHJldHVybgkJdGhlIEJPRFkgaXRlbQorICAgICAqIEBleGNlcHRpb24JUHJvdG9jb2xFeGNlcHRpb24JZm9yIHByb3RvY29sIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIEJPRFkgcGVla0JvZHkoaW50IG1zZ25vLCBTdHJpbmcgc2VjdGlvbiwgaW50IHN0YXJ0LCBpbnQgc2l6ZSwKKwkJCQlCeXRlQXJyYXkgYmEpIHRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJcmV0dXJuIGZldGNoQm9keShtc2dubywgc2VjdGlvbiwgc3RhcnQsIHNpemUsIHRydWUsIGJhKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJ0aWFsIEZFVENIIG9mIGdpdmVuIEJPRFkgc2VjdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbQltc2dubwl0aGUgbWVzc2FnZSBudW1iZXIKKyAgICAgKiBAcGFyYW0Jc2VjdGlvbgl0aGUgYm9keSBzZWN0aW9uCisgICAgICogQHBhcmFtCXN0YXJ0CXN0YXJ0aW5nIGJ5dGUgY291bnQKKyAgICAgKiBAcGFyYW0Jc2l6ZQludW1iZXIgb2YgYnl0ZXMgdG8gZmV0Y2gKKyAgICAgKiBAcGFyYW0JYmEJdGhlIGJ1ZmZlciBpbnRvIHdoaWNoIHRvIHJlYWQgdGhlIHJlc3BvbnNlCisgICAgICogQHJldHVybgkJdGhlIEJPRFkgaXRlbQorICAgICAqIEBleGNlcHRpb24JUHJvdG9jb2xFeGNlcHRpb24JZm9yIHByb3RvY29sIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIEJPRFkgZmV0Y2hCb2R5KGludCBtc2dubywgU3RyaW5nIHNlY3Rpb24sIGludCBzdGFydCwgaW50IHNpemUsCisJCQkJQnl0ZUFycmF5IGJhKSB0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCXJldHVybiBmZXRjaEJvZHkobXNnbm8sIHNlY3Rpb24sIHN0YXJ0LCBzaXplLCBmYWxzZSwgYmEpOworICAgIH0KKworICAgIHByb3RlY3RlZCBCT0RZIGZldGNoQm9keShpbnQgbXNnbm8sIFN0cmluZyBzZWN0aW9uLCBpbnQgc3RhcnQsIGludCBzaXplLAorCQkJYm9vbGVhbiBwZWVrLCBCeXRlQXJyYXkgYmEpIHRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJdGhpcy5iYSA9IGJhOwkvLyBzYXZlIGZvciBsYXRlciB1c2UgYnkgZ2V0UmVzcG9uc2VCdWZmZXIKKwlpZiAoc2VjdGlvbiA9PSBudWxsKQorCSAgICBzZWN0aW9uID0gIiI7CisJU3RyaW5nIGJvZHkgPSAocGVlayA/ICJCT0RZLlBFRUtbIiA6ICJCT0RZWyIpICsgc2VjdGlvbiArICJdPCIgKworCQkJU3RyaW5nLnZhbHVlT2Yoc3RhcnQpICsgIi4iICsKKwkJCVN0cmluZy52YWx1ZU9mKHNpemUpICsgIj4iOworCXJldHVybiBmZXRjaFNlY3Rpb25Cb2R5KG1zZ25vLCBzZWN0aW9uLCBib2R5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGZXRjaCB0aGUgZ2l2ZW4gYm9keSBzZWN0aW9uIG9mIHRoZSBnaXZlbiBtZXNzYWdlLCB1c2luZyB0aGUKKyAgICAgKiBib2R5IHN0cmluZyAiYm9keSIuCisgICAgICoKKyAgICAgKiBAcGFyYW0JbXNnbm8JdGhlIG1lc3NhZ2UgbnVtYmVyCisgICAgICogQHBhcmFtCXNlY3Rpb24JdGhlIGJvZHkgc2VjdGlvbgorICAgICAqIEBwYXJhbQlib2R5CXRoZSBib2R5IHN0cmluZworICAgICAqIEByZXR1cm4JCXRoZSBCT0RZIGl0ZW0KKyAgICAgKiBAZXhjZXB0aW9uCVByb3RvY29sRXhjZXB0aW9uCWZvciBwcm90b2NvbCBmYWlsdXJlcworICAgICAqLworICAgIHByb3RlY3RlZCBCT0RZIGZldGNoU2VjdGlvbkJvZHkoaW50IG1zZ25vLCBTdHJpbmcgc2VjdGlvbiwgU3RyaW5nIGJvZHkpCisJCQl0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCVJlc3BvbnNlW10gcjsKKworCXIgPSBmZXRjaChtc2dubywgYm9keSk7CisJbm90aWZ5UmVzcG9uc2VIYW5kbGVycyhyKTsKKworCVJlc3BvbnNlIHJlc3BvbnNlID0gcltyLmxlbmd0aC0xXTsKKwlpZiAocmVzcG9uc2UuaXNPSygpKSB7CisJICAgIExpc3Q8Qk9EWT4gYmwgPSBGZXRjaFJlc3BvbnNlLmdldEl0ZW1zKHIsIG1zZ25vLCBCT0RZLmNsYXNzKTsKKwkgICAgaWYgKGJsLnNpemUoKSA9PSAxKQorCQlyZXR1cm4gYmwuZ2V0KDApOwkvLyB0aGUgY29tbW9uIGNhc2UKKwkgICAgaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkVTVCkpCisJCWxvZ2dlci5maW5lc3QoImdvdCAiICsgYmwuc2l6ZSgpICsKKwkJCQkiIEJPRFkgcmVzcG9uc2VzIGZvciBzZWN0aW9uICIgKyBzZWN0aW9uKTsKKwkgICAgLy8gbW9yZSB0aGVuIG9uZSBCT0RZIHJlc3BvbnNlLCBoYXZlIHRvIGZpbmQgdGhlIHJpZ2h0IG9uZQorCSAgICBmb3IgKEJPRFkgYnIgOiBibCkgeworCQlpZiAobG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuRklORVNUKSkKKwkJICAgIGxvZ2dlci5maW5lc3QoImdvdCBCT0RZIHNlY3Rpb24gIiArIGJyLmdldFNlY3Rpb24oKSk7CisJCWlmIChici5nZXRTZWN0aW9uKCkuZXF1YWxzSWdub3JlQ2FzZShzZWN0aW9uKSkKKwkJICAgIHJldHVybiBicjsJLy8gdGhhdCdzIHRoZSBvbmUhCisJICAgIH0KKwkgICAgcmV0dXJuIG51bGw7CS8vIGNvdWxkbid0IGZpbmQgaXQKKwl9IGVsc2UgaWYgKHJlc3BvbnNlLmlzTk8oKSkKKwkgICAgcmV0dXJuIG51bGw7CisJZWxzZSB7CisJICAgIGhhbmRsZVJlc3VsdChyZXNwb25zZSk7CisJICAgIHJldHVybiBudWxsOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYSBidWZmZXIgdG8gcmVhZCBhIHJlc3BvbnNlIGludG8uCisgICAgICogVGhlIGJ1ZmZlciBpcyBwcm92aWRlZCBieSBmZXRjaEJvZHkgYW5kIGlzCisgICAgICogdXNlZCBvbmx5IG9uY2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBidWZmZXIgdG8gdXNlCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIEJ5dGVBcnJheSBnZXRSZXNwb25zZUJ1ZmZlcigpIHsKKwlCeXRlQXJyYXkgcmV0ID0gYmE7CisJYmEgPSBudWxsOworCXJldHVybiByZXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmV0Y2ggdGhlIHNwZWNpZmllZCBSRkM4MjIgRGF0YSBpdGVtLiAnd2hhdCcgbmFtZXMKKyAgICAgKiB0aGUgaXRlbSB0byBiZSBmZXRjaGVkLiAnd2hhdCcgY2FuIGJlIDxjb2RlPm51bGw8L2NvZGU+CisgICAgICogdG8gZmV0Y2ggdGhlIHdob2xlIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0JbXNnbm8JdGhlIG1lc3NhZ2UgbnVtYmVyCisgICAgICogQHBhcmFtCXdoYXQJdGhlIGl0ZW0gdG8gZmV0Y2gKKyAgICAgKiBAcmV0dXJuCQl0aGUgUkZDODIyREFUQSBpdGVtCisgICAgICogQGV4Y2VwdGlvbglQcm90b2NvbEV4Y2VwdGlvbglmb3IgcHJvdG9jb2wgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgUkZDODIyREFUQSBmZXRjaFJGQzgyMihpbnQgbXNnbm8sIFN0cmluZyB3aGF0KQorCQkJdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKwlSZXNwb25zZVtdIHIgPSBmZXRjaChtc2dubywKKwkJCSAgICAgd2hhdCA9PSBudWxsID8gIlJGQzgyMiIgOiAiUkZDODIyLiIgKyB3aGF0CisJCQkgICAgKTsKKworCS8vIGRpc3BhdGNoIHVudGFnZ2VkIHJlc3BvbnNlcworCW5vdGlmeVJlc3BvbnNlSGFuZGxlcnMocik7CisKKwlSZXNwb25zZSByZXNwb25zZSA9IHJbci5sZW5ndGgtMV07IAorCWlmIChyZXNwb25zZS5pc09LKCkpCisJICAgIHJldHVybiBGZXRjaFJlc3BvbnNlLmdldEl0ZW0ociwgbXNnbm8sIFJGQzgyMkRBVEEuY2xhc3MpOworCWVsc2UgaWYgKHJlc3BvbnNlLmlzTk8oKSkKKwkgICAgcmV0dXJuIG51bGw7CisJZWxzZSB7CisJICAgIGhhbmRsZVJlc3VsdChyZXNwb25zZSk7CisJICAgIHJldHVybiBudWxsOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGZXRjaCB0aGUgRkxBR1MgZm9yIHRoZSBnaXZlbiBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtCW1zZ25vCXRoZSBtZXNzYWdlIG51bWJlcgorICAgICAqIEByZXR1cm4JCXRoZSBGbGFncworICAgICAqIEBleGNlcHRpb24JUHJvdG9jb2xFeGNlcHRpb24JZm9yIHByb3RvY29sIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIEZsYWdzIGZldGNoRmxhZ3MoaW50IG1zZ25vKSB0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCUZsYWdzIGZsYWdzID0gbnVsbDsKKwlSZXNwb25zZVtdIHIgPSBmZXRjaChtc2dubywgIkZMQUdTIik7CisKKwkvLyBTZWFyY2ggZm9yIG91ciBGTEFHUyByZXNwb25zZQorCWZvciAoaW50IGkgPSAwLCBsZW4gPSByLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7CisJICAgIGlmIChyW2ldID09IG51bGwgfHwKKwkJIShyW2ldIGluc3RhbmNlb2YgRmV0Y2hSZXNwb25zZSkgfHwKKwkJKChGZXRjaFJlc3BvbnNlKXJbaV0pLmdldE51bWJlcigpICE9IG1zZ25vKQorCQljb250aW51ZTsJCQorCSAgICAKKwkgICAgRmV0Y2hSZXNwb25zZSBmciA9IChGZXRjaFJlc3BvbnNlKXJbaV07CisJICAgIGlmICgoZmxhZ3MgPSBmci5nZXRJdGVtKEZMQUdTLmNsYXNzKSkgIT0gbnVsbCkgeworCQlyW2ldID0gbnVsbDsgLy8gcmVtb3ZlIHRoaXMgcmVzcG9uc2UKKwkJYnJlYWs7CisJICAgIH0KKwl9CisKKwkvLyBkaXNwYXRjaCB1bnRhZ2dlZCByZXNwb25zZXMKKwlub3RpZnlSZXNwb25zZUhhbmRsZXJzKHIpOworCWhhbmRsZVJlc3VsdChyW3IubGVuZ3RoLTFdKTsKKwlyZXR1cm4gZmxhZ3M7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmV0Y2ggdGhlIElNQVAgVUlEIGZvciB0aGUgZ2l2ZW4gbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbQltc2dubwl0aGUgbWVzc2FnZSBudW1iZXIKKyAgICAgKiBAcmV0dXJuCQl0aGUgVUlECisgICAgICogQGV4Y2VwdGlvbglQcm90b2NvbEV4Y2VwdGlvbglmb3IgcHJvdG9jb2wgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgVUlEIGZldGNoVUlEKGludCBtc2dubykgdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKwlSZXNwb25zZVtdIHIgPSBmZXRjaChtc2dubywgIlVJRCIpOworCisJLy8gZGlzcGF0Y2ggdW50YWdnZWQgcmVzcG9uc2VzCisJbm90aWZ5UmVzcG9uc2VIYW5kbGVycyhyKTsKKworCVJlc3BvbnNlIHJlc3BvbnNlID0gcltyLmxlbmd0aC0xXTsgCisJaWYgKHJlc3BvbnNlLmlzT0soKSkKKwkgICAgcmV0dXJuIEZldGNoUmVzcG9uc2UuZ2V0SXRlbShyLCBtc2dubywgVUlELmNsYXNzKTsKKwllbHNlIGlmIChyZXNwb25zZS5pc05PKCkpIC8vIFhYWDogSXNzdWUgTk9PUCA/CisJICAgIHJldHVybiBudWxsOworCWVsc2UgeworCSAgICBoYW5kbGVSZXN1bHQocmVzcG9uc2UpOworCSAgICByZXR1cm4gbnVsbDsgLy8gTk9UUkVBQ0hFRAorCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGZXRjaCB0aGUgSU1BUCBNT0RTRVEgZm9yIHRoZSBnaXZlbiBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtCW1zZ25vCXRoZSBtZXNzYWdlIG51bWJlcgorICAgICAqIEByZXR1cm4JCXRoZSBNT0RTRVEKKyAgICAgKiBAZXhjZXB0aW9uCVByb3RvY29sRXhjZXB0aW9uCWZvciBwcm90b2NvbCBmYWlsdXJlcworICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjUuMQorICAgICAqLworICAgIHB1YmxpYyBNT0RTRVEgZmV0Y2hNT0RTRVEoaW50IG1zZ25vKSB0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCVJlc3BvbnNlW10gciA9IGZldGNoKG1zZ25vLCAiTU9EU0VRIik7CisKKwkvLyBkaXNwYXRjaCB1bnRhZ2dlZCByZXNwb25zZXMKKwlub3RpZnlSZXNwb25zZUhhbmRsZXJzKHIpOworCisJUmVzcG9uc2UgcmVzcG9uc2UgPSByW3IubGVuZ3RoLTFdOyAKKwlpZiAocmVzcG9uc2UuaXNPSygpKQorCSAgICByZXR1cm4gRmV0Y2hSZXNwb25zZS5nZXRJdGVtKHIsIG1zZ25vLCBNT0RTRVEuY2xhc3MpOworCWVsc2UgaWYgKHJlc3BvbnNlLmlzTk8oKSkgLy8gWFhYOiBJc3N1ZSBOT09QID8KKwkgICAgcmV0dXJuIG51bGw7CisJZWxzZSB7CisJICAgIGhhbmRsZVJlc3VsdChyZXNwb25zZSk7CisJICAgIHJldHVybiBudWxsOyAvLyBOT1RSRUFDSEVECisJfQorICAgIH0KKwkJCisgICAgLyoqCisgICAgICogR2V0IHRoZSBzZXF1ZW5jZSBudW1iZXIgZm9yIHRoZSBnaXZlbiBVSUQuICBOb3RoaW5nIGlzIHJldHVybmVkOworICAgICAqIHRoZSBGRVRDSCBVSUQgcmVzcG9uc2UgbXVzdCBiZSBoYW5kbGVkIGJ5IHRoZSByZXBvbnNlIGhhbmRsZXIsCisgICAgICogYWxvbmcgd2l0aCBhbnkgcG9zc2libGUgRVhQVU5HRSByZXNwb25zZXMsIHRvIGVuc3VyZSB0aGF0IHRoZQorICAgICAqIFVJRCBpcyBtYXRjaGVkIHdpdGggdGhlIGNvcnJlY3Qgc2VxdWVuY2UgbnVtYmVyLgorICAgICAqCisgICAgICogQHBhcmFtCXVpZAl0aGUgVUlECisgICAgICogQGV4Y2VwdGlvbglQcm90b2NvbEV4Y2VwdGlvbglmb3IgcHJvdG9jb2wgZmFpbHVyZXMKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS41LjMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBmZXRjaFNlcXVlbmNlTnVtYmVyKGxvbmcgdWlkKSB0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCVJlc3BvbnNlW10gciA9IGZldGNoKFN0cmluZy52YWx1ZU9mKHVpZCksICJVSUQiLCB0cnVlKTsJCisKKwlub3RpZnlSZXNwb25zZUhhbmRsZXJzKHIpOworCWhhbmRsZVJlc3VsdChyW3IubGVuZ3RoLTFdKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIHNlcXVlbmNlIG51bWJlcnMgZm9yIFVJRHMgcmFuZ2luZyBmcm9tIHN0YXJ0IHRpbGwgZW5kLgorICAgICAqIFNpbmNlIHRoZSByYW5nZSBtYXkgYmUgbGFyZ2UgYW5kIHNwYXJzZSwgYW4gYXJyYXkgb2YgdGhlIFVJRHMgYWN0dWFsbHkKKyAgICAgKiBmb3VuZCBpcyByZXR1cm5lZC4gIFRoZSBjYWxsZXIgbXVzdCBtYXAgdGhlc2UgdG8gbWVzc2FnZXMgYWZ0ZXIKKyAgICAgKiB0aGUgRkVUQ0ggVUlEIHJlc3BvbnNlcyBoYXZlIGJlZW4gaGFuZGxlZCBieSB0aGUgcmVwb25zZSBoYW5kbGVyLAorICAgICAqIGFsb25nIHdpdGggYW55IHBvc3NpYmxlIEVYUFVOR0UgcmVzcG9uc2VzLCB0byBlbnN1cmUgdGhhdCB0aGUKKyAgICAgKiBVSURzIGFyZSBtYXRjaGVkIHdpdGggdGhlIGNvcnJlY3Qgc2VxdWVuY2UgbnVtYmVycy4KKyAgICAgKgorICAgICAqIEBwYXJhbQlzdGFydAlmaXJzdCBVSUQKKyAgICAgKiBAcGFyYW0JZW5kCWxhc3QgVUlECisgICAgICogQHJldHVybgkJYXJyYXkgb2Ygc2VxdWVuY2UgbnVtYmVycworICAgICAqIEBleGNlcHRpb24JUHJvdG9jb2xFeGNlcHRpb24JZm9yIHByb3RvY29sIGZhaWx1cmVzCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNS4zCisgICAgICovCisgICAgcHVibGljIGxvbmdbXSBmZXRjaFNlcXVlbmNlTnVtYmVycyhsb25nIHN0YXJ0LCBsb25nIGVuZCkKKwkJCXRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJUmVzcG9uc2VbXSByID0gZmV0Y2goU3RyaW5nLnZhbHVlT2Yoc3RhcnQpICsgIjoiICsgCisJCQkJKGVuZCA9PSBVSURGb2xkZXIuTEFTVFVJRCA/ICIqIiA6IAorCQkJCVN0cmluZy52YWx1ZU9mKGVuZCkpLAorCQkJICAgICAiVUlEIiwgdHJ1ZSk7CQorCisJVUlEIHU7CisJTGlzdDxVSUQ+IHYgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKwlmb3IgKGludCBpID0gMCwgbGVuID0gci5sZW5ndGg7IGkgPCBsZW47IGkrKykgeworCSAgICBpZiAocltpXSA9PSBudWxsIHx8ICEocltpXSBpbnN0YW5jZW9mIEZldGNoUmVzcG9uc2UpKQorCQljb250aW51ZTsKKwkgICAgCisJICAgIEZldGNoUmVzcG9uc2UgZnIgPSAoRmV0Y2hSZXNwb25zZSlyW2ldOworCSAgICBpZiAoKHUgPSBmci5nZXRJdGVtKFVJRC5jbGFzcykpICE9IG51bGwpCisJCXYuYWRkKHUpOworCX0KKwkJCisJbm90aWZ5UmVzcG9uc2VIYW5kbGVycyhyKTsKKwloYW5kbGVSZXN1bHQocltyLmxlbmd0aC0xXSk7CisKKwlsb25nW10gbHYgPSBuZXcgbG9uZ1t2LnNpemUoKV07CisJZm9yIChpbnQgaSA9IDA7IGkgPCB2LnNpemUoKTsgaSsrKQorCSAgICBsdltpXSA9IHYuZ2V0KGkpLnVpZDsKKwlyZXR1cm4gbHY7CisgICAgfQorIAorICAgIC8qKgorICAgICAqIEdldCB0aGUgc2VxdWVuY2UgbnVtYmVycyBmb3IgVUlEcyBzcGVjaWZpZWQgaW4gdGhlIGFycmF5LgorICAgICAqIE5vdGhpbmcgaXMgcmV0dXJuZWQuICBUaGUgY2FsbGVyIG11c3QgbWFwIHRoZSBVSURzIHRvIG1lc3NhZ2VzIGFmdGVyCisgICAgICogdGhlIEZFVENIIFVJRCByZXNwb25zZXMgaGF2ZSBiZWVuIGhhbmRsZWQgYnkgdGhlIHJlcG9uc2UgaGFuZGxlciwKKyAgICAgKiBhbG9uZyB3aXRoIGFueSBwb3NzaWJsZSBFWFBVTkdFIHJlc3BvbnNlcywgdG8gZW5zdXJlIHRoYXQgdGhlCisgICAgICogVUlEcyBhcmUgbWF0Y2hlZCB3aXRoIHRoZSBjb3JyZWN0IHNlcXVlbmNlIG51bWJlcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0JdWlkcwl0aGUgVUlEcworICAgICAqIEBleGNlcHRpb24JUHJvdG9jb2xFeGNlcHRpb24JZm9yIHByb3RvY29sIGZhaWx1cmVzCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNS4zCisgICAgICovCisgICAgcHVibGljIHZvaWQgZmV0Y2hTZXF1ZW5jZU51bWJlcnMobG9uZ1tdIHVpZHMpIHRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisJZm9yIChpbnQgaSA9IDA7IGkgPCB1aWRzLmxlbmd0aDsgaSsrKSB7CisJICAgIGlmIChpID4gMCkKKwkJc2IuYXBwZW5kKCIsIik7CisJICAgIHNiLmFwcGVuZChTdHJpbmcudmFsdWVPZih1aWRzW2ldKSk7CisJfQorCisJUmVzcG9uc2VbXSByID0gZmV0Y2goc2IudG9TdHJpbmcoKSwgIlVJRCIsIHRydWUpOwkKKworCW5vdGlmeVJlc3BvbnNlSGFuZGxlcnMocik7CisJaGFuZGxlUmVzdWx0KHJbci5sZW5ndGgtMV0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgc2VxdWVuY2UgbnVtYmVycyBmb3IgbWVzc2FnZXMgY2hhbmdlZCBzaW5jZSB0aGUgZ2l2ZW4KKyAgICAgKiBtb2RzZXEgYW5kIHdpdGggVUlEcyByYW5naW5nIGZyb20gc3RhcnQgdGlsbCBlbmQuCisgICAgICogQWxzbywgcHJlZmV0Y2ggdGhlIGZsYWdzIGZvciB0aGUgcmV0dXJuZWQgbWVzc2FnZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jc3RhcnQJZmlyc3QgVUlECisgICAgICogQHBhcmFtCWVuZAlsYXN0IFVJRAorICAgICAqIEBwYXJhbQltb2RzZXEJdGhlIE1PRFNFUQorICAgICAqIEByZXR1cm4JCWFycmF5IG9mIHNlcXVlbmNlIG51bWJlcnMKKyAgICAgKiBAZXhjZXB0aW9uCVByb3RvY29sRXhjZXB0aW9uCWZvciBwcm90b2NvbCBmYWlsdXJlcworICAgICAqIEBzZWUJIlJGQyA0NTUxIgorICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjUuMQorICAgICAqLworICAgIHB1YmxpYyBpbnRbXSB1aWRmZXRjaENoYW5nZWRTaW5jZShsb25nIHN0YXJ0LCBsb25nIGVuZCwgbG9uZyBtb2RzZXEpCisJCQl0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCVN0cmluZyBtc2dTZXF1ZW5jZSA9IFN0cmluZy52YWx1ZU9mKHN0YXJ0KSArICI6IiArIAorCQkJCShlbmQgPT0gVUlERm9sZGVyLkxBU1RVSUQgPyAiKiIgOiAKKwkJCQlTdHJpbmcudmFsdWVPZihlbmQpKTsKKwlSZXNwb25zZVtdIHIgPSBjb21tYW5kKCJVSUQgRkVUQ0ggIiArIG1zZ1NlcXVlbmNlICsKKwkJIiAoRkxBR1MpIChDSEFOR0VEU0lOQ0UgIiArIFN0cmluZy52YWx1ZU9mKG1vZHNlcSkgKyAiKSIsIG51bGwpOworCisJTGlzdDxJbnRlZ2VyPiB2ID0gbmV3IEFycmF5TGlzdDw+KCk7CisJZm9yIChpbnQgaSA9IDAsIGxlbiA9IHIubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHsKKwkgICAgaWYgKHJbaV0gPT0gbnVsbCB8fCAhKHJbaV0gaW5zdGFuY2VvZiBGZXRjaFJlc3BvbnNlKSkKKwkJY29udGludWU7CisgCisJICAgIEZldGNoUmVzcG9uc2UgZnIgPSAoRmV0Y2hSZXNwb25zZSlyW2ldOworCSAgICB2LmFkZChJbnRlZ2VyLnZhbHVlT2YoZnIuZ2V0TnVtYmVyKCkpKTsKKwl9CisJCQorCW5vdGlmeVJlc3BvbnNlSGFuZGxlcnMocik7CisJaGFuZGxlUmVzdWx0KHJbci5sZW5ndGgtMV0pOworCisJLy8gQ29weSB0aGUgbGlzdCBpbnRvICdtYXRjaGVzJworCWludCB2c2l6ZSA9IHYuc2l6ZSgpOworCWludFtdIG1hdGNoZXMgPSBuZXcgaW50W3ZzaXplXTsKKwlmb3IgKGludCBpID0gMDsgaSA8IHZzaXplOyBpKyspCisJICAgIG1hdGNoZXNbaV0gPSB2LmdldChpKS5pbnRWYWx1ZSgpOworCXJldHVybiBtYXRjaGVzOworICAgIH0KKworICAgIHB1YmxpYyBSZXNwb25zZVtdIGZldGNoKE1lc3NhZ2VTZXRbXSBtc2dzZXRzLCBTdHJpbmcgd2hhdCkKKwkJCXRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJcmV0dXJuIGZldGNoKE1lc3NhZ2VTZXQudG9TdHJpbmcobXNnc2V0cyksIHdoYXQsIGZhbHNlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgUmVzcG9uc2VbXSBmZXRjaChpbnQgc3RhcnQsIGludCBlbmQsIFN0cmluZyB3aGF0KQorCQkJdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKwlyZXR1cm4gZmV0Y2goU3RyaW5nLnZhbHVlT2Yoc3RhcnQpICsgIjoiICsgU3RyaW5nLnZhbHVlT2YoZW5kKSwgCisJCSAgICAgd2hhdCwgZmFsc2UpOworICAgIH0KKworICAgIHB1YmxpYyBSZXNwb25zZVtdIGZldGNoKGludCBtc2csIFN0cmluZyB3aGF0KSAKKwkJCXRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJcmV0dXJuIGZldGNoKFN0cmluZy52YWx1ZU9mKG1zZyksIHdoYXQsIGZhbHNlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFJlc3BvbnNlW10gZmV0Y2goU3RyaW5nIG1zZ1NlcXVlbmNlLCBTdHJpbmcgd2hhdCwgYm9vbGVhbiB1aWQpCisJCQl0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCWlmICh1aWQpCisJICAgIHJldHVybiBjb21tYW5kKCJVSUQgRkVUQ0ggIiArIG1zZ1NlcXVlbmNlICsiICgiICsgd2hhdCArICIpIixudWxsKTsKKwllbHNlCisJICAgIHJldHVybiBjb21tYW5kKCJGRVRDSCAiICsgbXNnU2VxdWVuY2UgKyAiICgiICsgd2hhdCArICIpIiwgbnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ09QWSBjb21tYW5kLgorICAgICAqCisgICAgICogQHBhcmFtCW1zZ3NldHMJdGhlIG1lc3NhZ2VzIHRvIGNvcHkKKyAgICAgKiBAcGFyYW0JbWJveAl0aGUgbWFpbGJveCB0byBjb3B5IHRoZW0gdG8KKyAgICAgKiBAZXhjZXB0aW9uCVByb3RvY29sRXhjZXB0aW9uCWZvciBwcm90b2NvbCBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNvcHkoTWVzc2FnZVNldFtdIG1zZ3NldHMsIFN0cmluZyBtYm94KQorCQkJdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKwljb3B5dWlkKE1lc3NhZ2VTZXQudG9TdHJpbmcobXNnc2V0cyksIG1ib3gsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDT1BZIGNvbW1hbmQuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jc3RhcnQJc3RhcnQgbWVzc2FnZSBudW1iZXIKKyAgICAgKiBAcGFyYW0JZW5kCWVuZCBtZXNzYWdlIG51bWJlcgorICAgICAqIEBwYXJhbQltYm94CXRoZSBtYWlsYm94IHRvIGNvcHkgdGhlbSB0bworICAgICAqIEBleGNlcHRpb24JUHJvdG9jb2xFeGNlcHRpb24JZm9yIHByb3RvY29sIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIHZvaWQgY29weShpbnQgc3RhcnQsIGludCBlbmQsIFN0cmluZyBtYm94KQorCQkJdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKwljb3B5dWlkKFN0cmluZy52YWx1ZU9mKHN0YXJ0KSArICI6IiArIFN0cmluZy52YWx1ZU9mKGVuZCksCisJCSAgICBtYm94LCBmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ09QWSBjb21tYW5kLCByZXR1cm4gdWlkIGZyb20gQ09QWVVJRCByZXNwb25zZSBjb2RlLgorICAgICAqCisgICAgICogQHBhcmFtCW1zZ3NldHMJdGhlIG1lc3NhZ2VzIHRvIGNvcHkKKyAgICAgKiBAcGFyYW0JbWJveAl0aGUgbWFpbGJveCB0byBjb3B5IHRoZW0gdG8KKyAgICAgKiBAcmV0dXJuCQlDT1BZVUlEIHJlc3BvbnNlIGRhdGEKKyAgICAgKiBAZXhjZXB0aW9uCVByb3RvY29sRXhjZXB0aW9uCWZvciBwcm90b2NvbCBmYWlsdXJlcworICAgICAqIEBzZWUgIlJGQyA0MzE1LCBzZWN0aW9uIDMiCisgICAgICovCisgICAgcHVibGljIENvcHlVSUQgY29weXVpZChNZXNzYWdlU2V0W10gbXNnc2V0cywgU3RyaW5nIG1ib3gpCisJCQl0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCXJldHVybiBjb3B5dWlkKE1lc3NhZ2VTZXQudG9TdHJpbmcobXNnc2V0cyksIG1ib3gsIHRydWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENPUFkgY29tbWFuZCwgcmV0dXJuIHVpZCBmcm9tIENPUFlVSUQgcmVzcG9uc2UgY29kZS4KKyAgICAgKgorICAgICAqIEBwYXJhbQlzdGFydAlzdGFydCBtZXNzYWdlIG51bWJlcgorICAgICAqIEBwYXJhbQllbmQJZW5kIG1lc3NhZ2UgbnVtYmVyCisgICAgICogQHBhcmFtCW1ib3gJdGhlIG1haWxib3ggdG8gY29weSB0aGVtIHRvCisgICAgICogQHJldHVybgkJQ09QWVVJRCByZXNwb25zZSBkYXRhCisgICAgICogQGV4Y2VwdGlvbglQcm90b2NvbEV4Y2VwdGlvbglmb3IgcHJvdG9jb2wgZmFpbHVyZXMKKyAgICAgKiBAc2VlICJSRkMgNDMxNSwgc2VjdGlvbiAzIgorICAgICAqLworICAgIHB1YmxpYyBDb3B5VUlEIGNvcHl1aWQoaW50IHN0YXJ0LCBpbnQgZW5kLCBTdHJpbmcgbWJveCkKKwkJCXRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJcmV0dXJuIGNvcHl1aWQoU3RyaW5nLnZhbHVlT2Yoc3RhcnQpICsgIjoiICsgU3RyaW5nLnZhbHVlT2YoZW5kKSwKKwkJICAgIG1ib3gsIHRydWUpOworICAgIH0KKworICAgIHByaXZhdGUgQ29weVVJRCBjb3B5dWlkKFN0cmluZyBtc2dTZXF1ZW5jZSwgU3RyaW5nIG1ib3gsIGJvb2xlYW4gdWlkKQorCQkJCXRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJaWYgKHVpZCAmJiAhaGFzQ2FwYWJpbGl0eSgiVUlEUExVUyIpKSAKKwkgICAgdGhyb3cgbmV3IEJhZENvbW1hbmRFeGNlcHRpb24oIlVJRFBMVVMgbm90IHN1cHBvcnRlZCIpOworCisJQXJndW1lbnQgYXJncyA9IG5ldyBBcmd1bWVudCgpOwkKKwlhcmdzLndyaXRlQXRvbShtc2dTZXF1ZW5jZSk7CisJd3JpdGVNYWlsYm94TmFtZShhcmdzLCBtYm94KTsKKworCVJlc3BvbnNlW10gciA9IGNvbW1hbmQoIkNPUFkiLCBhcmdzKTsKKworCS8vIGRpc3BhdGNoIHVudGFnZ2VkIHJlc3BvbnNlcworCW5vdGlmeVJlc3BvbnNlSGFuZGxlcnMocik7CisKKwkvLyBIYW5kbGUgcmVzdWx0IG9mIHRoaXMgY29tbWFuZAorCWhhbmRsZVJlc3VsdChyW3IubGVuZ3RoLTFdKTsKKworCWlmICh1aWQpCisJICAgIHJldHVybiBnZXRDb3B5VUlEKHIpOworCWVsc2UKKwkgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogTU9WRSBjb21tYW5kLgorICAgICAqCisgICAgICogQHBhcmFtCW1zZ3NldHMJdGhlIG1lc3NhZ2VzIHRvIG1vdmUKKyAgICAgKiBAcGFyYW0JbWJveAl0aGUgbWFpbGJveCB0byBtb3ZlIHRoZW0gdG8KKyAgICAgKiBAZXhjZXB0aW9uCVByb3RvY29sRXhjZXB0aW9uCWZvciBwcm90b2NvbCBmYWlsdXJlcworICAgICAqIEBzZWUgIlJGQyA2ODUxIgorICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjUuNAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIG1vdmUoTWVzc2FnZVNldFtdIG1zZ3NldHMsIFN0cmluZyBtYm94KQorCQkJdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKwltb3ZldWlkKE1lc3NhZ2VTZXQudG9TdHJpbmcobXNnc2V0cyksIG1ib3gsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNT1ZFIGNvbW1hbmQuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jc3RhcnQJc3RhcnQgbWVzc2FnZSBudW1iZXIKKyAgICAgKiBAcGFyYW0JZW5kCWVuZCBtZXNzYWdlIG51bWJlcgorICAgICAqIEBwYXJhbQltYm94CXRoZSBtYWlsYm94IHRvIG1vdmUgdGhlbSB0bworICAgICAqIEBleGNlcHRpb24JUHJvdG9jb2xFeGNlcHRpb24JZm9yIHByb3RvY29sIGZhaWx1cmVzCisgICAgICogQHNlZSAiUkZDIDY4NTEiCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNS40CisgICAgICovCisgICAgcHVibGljIHZvaWQgbW92ZShpbnQgc3RhcnQsIGludCBlbmQsIFN0cmluZyBtYm94KQorCQkJdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKwltb3ZldWlkKFN0cmluZy52YWx1ZU9mKHN0YXJ0KSArICI6IiArIFN0cmluZy52YWx1ZU9mKGVuZCksCisJCSAgICBtYm94LCBmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTU9WRSBDb21tYW5kLCByZXR1cm4gdWlkIGZyb20gQ09QWVVJRCByZXNwb25zZSBjb2RlLgorICAgICAqCisgICAgICogQHBhcmFtCW1zZ3NldHMJdGhlIG1lc3NhZ2VzIHRvIG1vdmUKKyAgICAgKiBAcGFyYW0JbWJveAl0aGUgbWFpbGJveCB0byBtb3ZlIHRoZW0gdG8KKyAgICAgKiBAcmV0dXJuCQlDT1BZVUlEIHJlc3BvbnNlIGRhdGEKKyAgICAgKiBAZXhjZXB0aW9uCVByb3RvY29sRXhjZXB0aW9uCWZvciBwcm90b2NvbCBmYWlsdXJlcworICAgICAqIEBzZWUgIlJGQyA2ODUxIgorICAgICAqIEBzZWUgIlJGQyA0MzE1LCBzZWN0aW9uIDMiCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNS40CisgICAgICovCisgICAgcHVibGljIENvcHlVSUQgbW92ZXVpZChNZXNzYWdlU2V0W10gbXNnc2V0cywgU3RyaW5nIG1ib3gpCisJCQl0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCXJldHVybiBtb3ZldWlkKE1lc3NhZ2VTZXQudG9TdHJpbmcobXNnc2V0cyksIG1ib3gsIHRydWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIE1PVkUgQ29tbWFuZCwgcmV0dXJuIHVpZCBmcm9tIENPUFlVSUQgcmVzcG9uc2UgY29kZS4KKyAgICAgKgorICAgICAqIEBwYXJhbQlzdGFydAlzdGFydCBtZXNzYWdlIG51bWJlcgorICAgICAqIEBwYXJhbQllbmQJZW5kIG1lc3NhZ2UgbnVtYmVyCisgICAgICogQHBhcmFtCW1ib3gJdGhlIG1haWxib3ggdG8gbW92ZSB0aGVtIHRvCisgICAgICogQHJldHVybgkJQ09QWVVJRCByZXNwb25zZSBkYXRhCisgICAgICogQGV4Y2VwdGlvbglQcm90b2NvbEV4Y2VwdGlvbglmb3IgcHJvdG9jb2wgZmFpbHVyZXMKKyAgICAgKiBAc2VlICJSRkMgNjg1MSIKKyAgICAgKiBAc2VlICJSRkMgNDMxNSwgc2VjdGlvbiAzIgorICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjUuNAorICAgICAqLworICAgIHB1YmxpYyBDb3B5VUlEIG1vdmV1aWQoaW50IHN0YXJ0LCBpbnQgZW5kLCBTdHJpbmcgbWJveCkKKwkJCXRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJcmV0dXJuIG1vdmV1aWQoU3RyaW5nLnZhbHVlT2Yoc3RhcnQpICsgIjoiICsgU3RyaW5nLnZhbHVlT2YoZW5kKSwKKwkJICAgIG1ib3gsIHRydWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIE1PVkUgQ29tbWFuZCwgcmV0dXJuIHVpZCBmcm9tIENPUFlVSUQgcmVzcG9uc2UgY29kZS4KKyAgICAgKgorICAgICAqIEBzZWUgIlJGQyA2ODUxIgorICAgICAqIEBzZWUgIlJGQyA0MzE1LCBzZWN0aW9uIDMiCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNS40CisgICAgICovCisgICAgcHJpdmF0ZSBDb3B5VUlEIG1vdmV1aWQoU3RyaW5nIG1zZ1NlcXVlbmNlLCBTdHJpbmcgbWJveCwgYm9vbGVhbiB1aWQpCisJCQkJdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKwlpZiAoIWhhc0NhcGFiaWxpdHkoIk1PVkUiKSkgCisJICAgIHRocm93IG5ldyBCYWRDb21tYW5kRXhjZXB0aW9uKCJNT1ZFIG5vdCBzdXBwb3J0ZWQiKTsKKwlpZiAodWlkICYmICFoYXNDYXBhYmlsaXR5KCJVSURQTFVTIikpIAorCSAgICB0aHJvdyBuZXcgQmFkQ29tbWFuZEV4Y2VwdGlvbigiVUlEUExVUyBub3Qgc3VwcG9ydGVkIik7CisKKwlBcmd1bWVudCBhcmdzID0gbmV3IEFyZ3VtZW50KCk7CQorCWFyZ3Mud3JpdGVBdG9tKG1zZ1NlcXVlbmNlKTsKKwl3cml0ZU1haWxib3hOYW1lKGFyZ3MsIG1ib3gpOworCisJUmVzcG9uc2VbXSByID0gY29tbWFuZCgiTU9WRSIsIGFyZ3MpOworCisJLy8gZGlzcGF0Y2ggdW50YWdnZWQgcmVzcG9uc2VzCisJbm90aWZ5UmVzcG9uc2VIYW5kbGVycyhyKTsKKworCS8vIEhhbmRsZSByZXN1bHQgb2YgdGhpcyBjb21tYW5kCisJaGFuZGxlUmVzdWx0KHJbci5sZW5ndGgtMV0pOworCisJaWYgKHVpZCkKKwkgICAgcmV0dXJuIGdldENvcHlVSUQocik7CisJZWxzZQorCSAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJZiB0aGUgcmVzcG9uc2UgY29udGFpbnMgYSBDT1BZVUlEIHJlc3BvbnNlIGNvZGUsIGV4dHJhY3QKKyAgICAgKiBpdCBhbmQgcmV0dXJuIGEgQ29weVVJRCBvYmplY3Qgd2l0aCB0aGUgaW5mb3JtYXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0JcnIJdGhlIHJlc3BvbnNlcyB0byBleGFtaW5lCisgICAgICogQHJldHVybgkJdGhlIENPUFlVSUQgcmVzcG9uc2UgY29kZSBkYXRhLCBvciBudWxsIGlmIG5vdCBmb3VuZAorICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjUuNAorICAgICAqLworICAgIHByb3RlY3RlZCBDb3B5VUlEIGdldENvcHlVSUQoUmVzcG9uc2VbXSBycikgeworCS8vIG1vc3QgbGlrZWx5IGluIHRoZSBsYXN0IHJlc3BvbnNlLCBzbyBzdGFydCB0aGVyZSBhbmQgd29yayBiYWNrd2FyZAorCWZvciAoaW50IGkgPSByci5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgeworCSAgICBSZXNwb25zZSByID0gcnJbaV07CisJICAgIGlmIChyID09IG51bGwgfHwgIXIuaXNPSygpKQorCQljb250aW51ZTsKKwkgICAgYnl0ZSBiOworCSAgICB3aGlsZSAoKGIgPSByLnJlYWRCeXRlKCkpID4gMCAmJiBiICE9IChieXRlKSdbJykKKwkJOworCSAgICBpZiAoYiA9PSAwKQorCQljb250aW51ZTsKKwkgICAgU3RyaW5nIHM7CisJICAgIHMgPSByLnJlYWRBdG9tKCk7CisJICAgIGlmICghcy5lcXVhbHNJZ25vcmVDYXNlKCJDT1BZVUlEIikpCisJCWNvbnRpbnVlOworCisJICAgIC8vIFhYWCAtIG5lZWQgdG8gbWVyZ2UgbW9yZSB0aGFuIG9uZSByZXNwb25zZSBmb3IgTU9WRT8KKwkgICAgbG9uZyB1aWR2YWxpZGl0eSA9IHIucmVhZExvbmcoKTsKKwkgICAgU3RyaW5nIHNyYyA9IHIucmVhZEF0b20oKTsKKwkgICAgU3RyaW5nIGRzdCA9IHIucmVhZEF0b20oKTsKKwkgICAgcmV0dXJuIG5ldyBDb3B5VUlEKHVpZHZhbGlkaXR5LAorCQkJICAgIFVJRFNldC5wYXJzZVVJRFNldHMoc3JjKSwgVUlEU2V0LnBhcnNlVUlEU2V0cyhkc3QpKTsKKwl9CisJcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc3RvcmVGbGFncyhNZXNzYWdlU2V0W10gbXNnc2V0cywgRmxhZ3MgZmxhZ3MsIGJvb2xlYW4gc2V0KQorCQkJdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKwlzdG9yZUZsYWdzKE1lc3NhZ2VTZXQudG9TdHJpbmcobXNnc2V0cyksIGZsYWdzLCBzZXQpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHN0b3JlRmxhZ3MoaW50IHN0YXJ0LCBpbnQgZW5kLCBGbGFncyBmbGFncywgYm9vbGVhbiBzZXQpCisJCQl0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCXN0b3JlRmxhZ3MoU3RyaW5nLnZhbHVlT2Yoc3RhcnQpICsgIjoiICsgU3RyaW5nLnZhbHVlT2YoZW5kKSwKKwkJICAgZmxhZ3MsIHNldCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBzcGVjaWZpZWQgZmxhZ3Mgb24gdGhpcyBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtCW1zZwl0aGUgbWVzc2FnZSBudW1iZXIKKyAgICAgKiBAcGFyYW0JZmxhZ3MJdGhlIGZsYWdzCisgICAgICogQHBhcmFtCXNldAl0cnVlIHRvIHNldCwgZmFsc2UgdG8gY2xlYXIKKyAgICAgKiBAZXhjZXB0aW9uCVByb3RvY29sRXhjZXB0aW9uCWZvciBwcm90b2NvbCBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHN0b3JlRmxhZ3MoaW50IG1zZywgRmxhZ3MgZmxhZ3MsIGJvb2xlYW4gc2V0KQorCQkJdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsgCisJc3RvcmVGbGFncyhTdHJpbmcudmFsdWVPZihtc2cpLCBmbGFncywgc2V0KTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgc3RvcmVGbGFncyhTdHJpbmcgbXNnc2V0LCBGbGFncyBmbGFncywgYm9vbGVhbiBzZXQpCisJCQl0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCVJlc3BvbnNlW10gcjsKKwlpZiAoc2V0KQorCSAgICByID0gY29tbWFuZCgiU1RPUkUgIiArIG1zZ3NldCArICIgK0ZMQUdTICIgKyAKKwkJCSBjcmVhdGVGbGFnTGlzdChmbGFncyksIG51bGwpOworCWVsc2UKKwkgICAgciA9IGNvbW1hbmQoIlNUT1JFICIgKyBtc2dzZXQgKyAiIC1GTEFHUyAiICsgCisJCQljcmVhdGVGbGFnTGlzdChmbGFncyksIG51bGwpOworCQorCS8vIERpc3BhdGNoIHVudGFnZ2VkIHJlc3BvbnNlcworCW5vdGlmeVJlc3BvbnNlSGFuZGxlcnMocik7CisJaGFuZGxlUmVzdWx0KHJbci5sZW5ndGgtMV0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gSU1BUCBmbGFnX2xpc3QgZnJvbSB0aGUgZ2l2ZW4gRmxhZ3Mgb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtCWZsYWdzCXRoZSBmbGFncworICAgICAqIEByZXR1cm4JCXRoZSBJTUFQIGZsYWdfbGlzdAorICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjUuNAorICAgICAqLworICAgIHByb3RlY3RlZCBTdHJpbmcgY3JlYXRlRmxhZ0xpc3QoRmxhZ3MgZmxhZ3MpIHsKKwlTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoIigiKTsgLy8gc3RhcnQgb2YgZmxhZ19saXN0CisKKwlGbGFncy5GbGFnW10gc2YgPSBmbGFncy5nZXRTeXN0ZW1GbGFncygpOyAvLyBnZXQgdGhlIHN5c3RlbSBmbGFncworCWJvb2xlYW4gZmlyc3QgPSB0cnVlOworCWZvciAoaW50IGkgPSAwOyBpIDwgc2YubGVuZ3RoOyBpKyspIHsKKwkgICAgU3RyaW5nIHM7CisJICAgIEZsYWdzLkZsYWcgZiA9IHNmW2ldOworCSAgICBpZiAoZiA9PSBGbGFncy5GbGFnLkFOU1dFUkVEKQorCQlzID0gIlxcQW5zd2VyZWQiOworCSAgICBlbHNlIGlmIChmID09IEZsYWdzLkZsYWcuREVMRVRFRCkKKwkJcyA9ICJcXERlbGV0ZWQiOworCSAgICBlbHNlIGlmIChmID09IEZsYWdzLkZsYWcuRFJBRlQpCisJCXMgPSAiXFxEcmFmdCI7CisJICAgIGVsc2UgaWYgKGYgPT0gRmxhZ3MuRmxhZy5GTEFHR0VEKQorCQlzID0gIlxcRmxhZ2dlZCI7CisJICAgIGVsc2UgaWYgKGYgPT0gRmxhZ3MuRmxhZy5SRUNFTlQpCisJCXMgPSAiXFxSZWNlbnQiOworCSAgICBlbHNlIGlmIChmID09IEZsYWdzLkZsYWcuU0VFTikKKwkJcyA9ICJcXFNlZW4iOworCSAgICBlbHNlCisJCWNvbnRpbnVlOwkvLyBza2lwIGl0CisJICAgIGlmIChmaXJzdCkKKwkJZmlyc3QgPSBmYWxzZTsKKwkgICAgZWxzZQorCQlzYi5hcHBlbmQoJyAnKTsKKwkgICAgc2IuYXBwZW5kKHMpOworCX0KKworCVN0cmluZ1tdIHVmID0gZmxhZ3MuZ2V0VXNlckZsYWdzKCk7IC8vIGdldCB0aGUgdXNlciBmbGFnIHN0cmluZ3MKKwlmb3IgKGludCBpID0gMDsgaSA8IHVmLmxlbmd0aDsgaSsrKSB7CisJICAgIGlmIChmaXJzdCkKKwkJZmlyc3QgPSBmYWxzZTsKKwkgICAgZWxzZQorCQlzYi5hcHBlbmQoJyAnKTsKKwkgICAgc2IuYXBwZW5kKHVmW2ldKTsKKwl9CisKKwlzYi5hcHBlbmQoIikiKTsgLy8gdGVybWluYXRlIGZsYWdfbGlzdAorCXJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIElzc3VlIHRoZSBnaXZlbiBzZWFyY2ggY3JpdGVyaW9uIG9uIHRoZSBzcGVjaWZpZWQgbWVzc2FnZSBzZXRzLgorICAgICAqIFJldHVybnMgYXJyYXkgb2YgbWF0Y2hpbmcgc2VxdWVuY2UgbnVtYmVycy4gQW4gZW1wdHkgYXJyYXkKKyAgICAgKiBpcyByZXR1cm5lZCBpZiBubyBtYXRjaGVzIGFyZSBmb3VuZC4KKyAgICAgKgorICAgICAqIEBwYXJhbQltc2dzZXRzCWFycmF5IG9mIE1lc3NhZ2VTZXRzCisgICAgICogQHBhcmFtCXRlcm0JU2VhcmNoVGVybQorICAgICAqIEByZXR1cm4JCWFycmF5IG9mIG1hdGNoaW5nIHNlcXVlbmNlIG51bWJlcnMuCisgICAgICogQGV4Y2VwdGlvbglQcm90b2NvbEV4Y2VwdGlvbglmb3IgcHJvdG9jb2wgZmFpbHVyZXMKKyAgICAgKiBAZXhjZXB0aW9uCVNlYXJjaEV4Y2VwdGlvbglmb3Igc2VhcmNoIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIGludFtdIHNlYXJjaChNZXNzYWdlU2V0W10gbXNnc2V0cywgU2VhcmNoVGVybSB0ZXJtKQorCQkJdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uLCBTZWFyY2hFeGNlcHRpb24geworCXJldHVybiBzZWFyY2goTWVzc2FnZVNldC50b1N0cmluZyhtc2dzZXRzKSwgdGVybSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSXNzdWUgdGhlIGdpdmVuIHNlYXJjaCBjcml0ZXJpb24gb24gYWxsIG1lc3NhZ2VzIGluIHRoaXMgZm9sZGVyLgorICAgICAqIFJldHVybnMgYXJyYXkgb2YgbWF0Y2hpbmcgc2VxdWVuY2UgbnVtYmVycy4gQW4gZW1wdHkgYXJyYXkKKyAgICAgKiBpcyByZXR1cm5lZCBpZiBubyBtYXRjaGVzIGFyZSBmb3VuZC4KKyAgICAgKgorICAgICAqIEBwYXJhbQl0ZXJtCVNlYXJjaFRlcm0KKyAgICAgKiBAcmV0dXJuCQlhcnJheSBvZiBtYXRjaGluZyBzZXF1ZW5jZSBudW1iZXJzLgorICAgICAqIEBleGNlcHRpb24JUHJvdG9jb2xFeGNlcHRpb24JZm9yIHByb3RvY29sIGZhaWx1cmVzCisgICAgICogQGV4Y2VwdGlvbglTZWFyY2hFeGNlcHRpb24JZm9yIHNlYXJjaCBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBpbnRbXSBzZWFyY2goU2VhcmNoVGVybSB0ZXJtKSAKKwkJCXRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiwgU2VhcmNoRXhjZXB0aW9uIHsKKwlyZXR1cm4gc2VhcmNoKCJBTEwiLCB0ZXJtKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIEFwcGx5IHRoZSBnaXZlbiBTZWFyY2hUZXJtIG9uIHRoZSBzcGVjaWZpZWQgc2VxdWVuY2UuCisgICAgICogUmV0dXJucyBhcnJheSBvZiBtYXRjaGluZyBzZXF1ZW5jZSBudW1iZXJzLiBOb3RlIHRoYXQgYW4gZW1wdHkKKyAgICAgKiBhcnJheSBpcyByZXR1cm5lZCBmb3Igbm8gbWF0Y2hlcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludFtdIHNlYXJjaChTdHJpbmcgbXNnU2VxdWVuY2UsIFNlYXJjaFRlcm0gdGVybSkKKwkJCXRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiwgU2VhcmNoRXhjZXB0aW9uIHsKKwkvLyBDaGVjayBpZiB0aGUgc2VhcmNoICJ0ZXh0IiB0ZXJtcyBjb250YWluIG9ubHkgQVNDSUkgY2hhcnMsCisJLy8gb3IgaWYgdXRmOCBzdXBwb3J0IGhhcyBiZWVuIGVuYWJsZWQgKGluIHdoaWNoIGNhc2UgQ0hBUlNFVAorCS8vIGlzIG5vdCBhbGxvd2VkOyBzZWUgUkZDIDY4NTUsIHNlY3Rpb24gMywgbGFzdCBwYXJhZ3JhcGgpCisJaWYgKHN1cHBvcnRzVXRmOCgpIHx8IFNlYXJjaFNlcXVlbmNlLmlzQXNjaWkodGVybSkpIHsKKwkgICAgdHJ5IHsKKwkJcmV0dXJuIGlzc3VlU2VhcmNoKG1zZ1NlcXVlbmNlLCB0ZXJtLCBudWxsKTsKKwkgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9leCkgeyAvKiB3aWxsIG5vdCBoYXBwZW4gKi8gfQorCX0KKworCS8qCisJICogVGhlIHNlYXJjaCAidGV4dCIgdGVybXMgZG8gY29udGFpbiBub24tQVNDSUkgY2hhcnMgYW5kIHV0ZjgKKwkgKiBzdXBwb3J0IGhhcyBub3QgYmVlbiBlbmFibGVkLiAgV2UgbmVlZCB0byB1c2U6CisJICogIlNFQVJDSCBDSEFSU0VUIDxjaGFyc2V0PiAuLi4iCisJICogVGhlIGNoYXJzZXRzIHdlIHRyeSB0byB1c2UgYXJlIFVURi04IGFuZCB0aGUgbG9jYWxlJ3MKKwkgKiBkZWZhdWx0IGNoYXJzZXQuIElmIHRoZSBzZXJ2ZXIgc3VwcG9ydHMgVVRGLTgsIGdyZWF0LCAKKwkgKiBhbHdheXMgdXNlIGl0LiBFbHNlIHdlIHRyeSB0byB1c2UgdGhlIGRlZmF1bHQgY2hhcnNldC4KKwkgKi8KKworCS8vIEN5Y2xlIHRocnUgdGhlIGxpc3Qgb2YgY2hhcnNldHMKKwlmb3IgKGludCBpID0gMDsgaSA8IHNlYXJjaENoYXJzZXRzLmxlbmd0aDsgaSsrKSB7CisJICAgIGlmIChzZWFyY2hDaGFyc2V0c1tpXSA9PSBudWxsKQorCQljb250aW51ZTsKKworCSAgICB0cnkgeworCQlyZXR1cm4gaXNzdWVTZWFyY2gobXNnU2VxdWVuY2UsIHRlcm0sIHNlYXJjaENoYXJzZXRzW2ldKTsKKwkgICAgfSBjYXRjaCAoQ29tbWFuZEZhaWxlZEV4Y2VwdGlvbiBjZngpIHsKKwkJLyoKKwkJICogU2VydmVyIHJldHVybmVkIE5PLiBGb3Igbm93LCBJJ2xsIGp1c3QgYXNzdW1lIHRoYXQgCisJCSAqIHRoaXMgaW5kaWNhdGVzIHRoYXQgdGhpcyBjaGFyc2V0IGlzIHVuc3VwcG9ydGVkLgorCQkgKiBXZSBjYW4gY2hlY2sgdGhlIEJBRENIQVJTRVQgcmVzcG9uc2UgY29kZSBvbmNlCisJCSAqIHRoYXQncyBzcGVjJ2QgaW50byB0aGUgSU1BUCBSRkMgLi4KKwkJICovCisJCXNlYXJjaENoYXJzZXRzW2ldID0gbnVsbDsKKwkJY29udGludWU7CisJICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZXgpIHsKKwkJLyogQ2hhcnNldCBjb252ZXJzaW9uIGZhaWxlZC4gVHJ5IHRoZSBuZXh0IG9uZSAqLworCQljb250aW51ZTsKKwkgICAgfSBjYXRjaCAoUHJvdG9jb2xFeGNlcHRpb24gcGV4KSB7CisJCXRocm93IHBleDsKKwkgICAgfSBjYXRjaCAoU2VhcmNoRXhjZXB0aW9uIHNleCkgeworCQl0aHJvdyBzZXg7CisJICAgIH0KKwl9CisKKwkvLyBObyBsdWNrLgorCXRocm93IG5ldyBTZWFyY2hFeGNlcHRpb24oIlNlYXJjaCBmYWlsZWQiKTsKKyAgICB9CisKKyAgICAvKiBBcHBseSB0aGUgZ2l2ZW4gU2VhcmNoVGVybSBvbiB0aGUgc3BlY2lmaWVkIHNlcXVlbmNlLCB1c2luZyB0aGUKKyAgICAgKiBnaXZlbiBjaGFyc2V0LiA8cD4KKyAgICAgKiBSZXR1cm5zIGFycmF5IG9mIG1hdGNoaW5nIHNlcXVlbmNlIG51bWJlcnMuIE5vdGUgdGhhdCBhbiBlbXB0eQorICAgICAqIGFycmF5IGlzIHJldHVybmVkIGZvciBubyBtYXRjaGVzLgorICAgICAqLworICAgIHByaXZhdGUgaW50W10gaXNzdWVTZWFyY2goU3RyaW5nIG1zZ1NlcXVlbmNlLCBTZWFyY2hUZXJtIHRlcm0sCisgICAgICAJCQkgICAgICBTdHJpbmcgY2hhcnNldCkgCisJICAgICB0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24sIFNlYXJjaEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworCisJLy8gR2VuZXJhdGUgYSBzZWFyY2gtc2VxdWVuY2Ugd2l0aCB0aGUgZ2l2ZW4gY2hhcnNldAorCUFyZ3VtZW50IGFyZ3MgPSBnZXRTZWFyY2hTZXF1ZW5jZSgpLmdlbmVyYXRlU2VxdWVuY2UodGVybSwgCisJCQkgIGNoYXJzZXQgPT0gbnVsbCA/IG51bGwgOiAKKwkJCQkJICAgIE1pbWVVdGlsaXR5LmphdmFDaGFyc2V0KGNoYXJzZXQpCisJCQkpOworCWFyZ3Mud3JpdGVBdG9tKG1zZ1NlcXVlbmNlKTsKKworCVJlc3BvbnNlW10gcjsKKworCWlmIChjaGFyc2V0ID09IG51bGwpIC8vIHRleHQgaXMgYWxsIFVTLUFTQ0lJCisJICAgIHIgPSBjb21tYW5kKCJTRUFSQ0giLCBhcmdzKTsKKwllbHNlCisJICAgIHIgPSBjb21tYW5kKCJTRUFSQ0ggQ0hBUlNFVCAiICsgY2hhcnNldCwgYXJncyk7CisKKwlSZXNwb25zZSByZXNwb25zZSA9IHJbci5sZW5ndGgtMV07CisJaW50W10gbWF0Y2hlcyA9IG51bGw7CisKKwkvLyBHcmFiIGFsbCBTRUFSQ0ggcmVzcG9uc2VzCisJaWYgKHJlc3BvbnNlLmlzT0soKSkgeyAvLyBjb21tYW5kIHN1Y2Nlc2Z1bAorCSAgICBMaXN0PEludGVnZXI+IHYgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKwkgICAgaW50IG51bTsKKwkgICAgZm9yIChpbnQgaSA9IDAsIGxlbiA9IHIubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHsKKwkJaWYgKCEocltpXSBpbnN0YW5jZW9mIElNQVBSZXNwb25zZSkpCisJCSAgICBjb250aW51ZTsKKworCQlJTUFQUmVzcG9uc2UgaXIgPSAoSU1BUFJlc3BvbnNlKXJbaV07CisJCS8vIFRoZXJlICp3aWxsKiBiZSBvbmUgU0VBUkNIIHJlc3BvbnNlLgorCQlpZiAoaXIua2V5RXF1YWxzKCJTRUFSQ0giKSkgeworCQkgICAgd2hpbGUgKChudW0gPSBpci5yZWFkTnVtYmVyKCkpICE9IC0xKQorCQkJdi5hZGQoSW50ZWdlci52YWx1ZU9mKG51bSkpOworCQkgICAgcltpXSA9IG51bGw7CisJCX0KKwkgICAgfQorCisJICAgIC8vIENvcHkgdGhlIGxpc3QgaW50byAnbWF0Y2hlcycKKwkgICAgaW50IHZzaXplID0gdi5zaXplKCk7CisJICAgIG1hdGNoZXMgPSBuZXcgaW50W3ZzaXplXTsKKwkgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2c2l6ZTsgaSsrKQorCQltYXRjaGVzW2ldID0gdi5nZXQoaSkuaW50VmFsdWUoKTsKKwl9CisKKwkvLyBkaXNwYXRjaCByZW1haW5pbmcgdW50YWdnZWQgcmVzcG9uc2VzCisJbm90aWZ5UmVzcG9uc2VIYW5kbGVycyhyKTsKKwloYW5kbGVSZXN1bHQocmVzcG9uc2UpOworCXJldHVybiBtYXRjaGVzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgU2VhcmNoU2VxdWVuY2Ugb2JqZWN0LgorICAgICAqIFRoZSBTZWFyY2hTZXF1ZW5jZSBvYmplY3QgaW5zdGFuY2UgaXMgc2F2ZWQgaW4gdGhlIHNlYXJjaFNlcXVlbmNlCisgICAgICogZmllbGQuICBTdWJjbGFzc2VzIG9mIElNQVBQcm90b2NvbCBtYXkgb3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8KKyAgICAgKiByZXR1cm4gYSBzdWJjbGFzcyBvZiBTZWFyY2hTZXF1ZW5jZSwgaW4gb3JkZXIgdG8gYWRkIHN1cHBvcnQgZm9yCisgICAgICogcHJvZHVjdC1zcGVjaWZpYyBzZWFyY2ggdGVybXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBTZWFyY2hTZXF1ZW5jZQorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjQuNgorICAgICAqLworICAgIHByb3RlY3RlZCBTZWFyY2hTZXF1ZW5jZSBnZXRTZWFyY2hTZXF1ZW5jZSgpIHsKKwlpZiAoc2VhcmNoU2VxdWVuY2UgPT0gbnVsbCkKKwkgICAgc2VhcmNoU2VxdWVuY2UgPSBuZXcgU2VhcmNoU2VxdWVuY2UodGhpcyk7CisJcmV0dXJuIHNlYXJjaFNlcXVlbmNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNvcnQgbWVzc2FnZXMgaW4gdGhlIGZvbGRlciBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmllZCBzb3J0IGNyaXRlcmlhLgorICAgICAqIElmIHRoZSBzZWFyY2ggdGVybSBpcyBub3QgbnVsbCwgbGltaXQgdGhlIHNvcnQgdG8gb25seSB0aGUgbWVzc2FnZXMKKyAgICAgKiB0aGF0IG1hdGNoIHRoZSBzZWFyY2ggdGVybS4KKyAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIHNvcnRlZCBzZXF1ZW5jZSBudW1iZXJzLiBBbiBlbXB0eSBhcnJheQorICAgICAqIGlzIHJldHVybmVkIGlmIG5vIG1hdGNoZXMgYXJlIGZvdW5kLgorICAgICAqCisgICAgICogQHBhcmFtCXRlcm0Jc29ydCBjcml0ZXJpYQorICAgICAqIEBwYXJhbQlzdGVybQlTZWFyY2hUZXJtCisgICAgICogQHJldHVybgkJYXJyYXkgb2YgbWF0Y2hpbmcgc2VxdWVuY2UgbnVtYmVycy4KKyAgICAgKiBAZXhjZXB0aW9uCVByb3RvY29sRXhjZXB0aW9uCWZvciBwcm90b2NvbCBmYWlsdXJlcworICAgICAqIEBleGNlcHRpb24JU2VhcmNoRXhjZXB0aW9uCWZvciBzZWFyY2ggZmFpbHVyZXMKKyAgICAgKgorICAgICAqIEBzZWUJIlJGQyA1MjU2IgorICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjQuNAorICAgICAqLworICAgIHB1YmxpYyBpbnRbXSBzb3J0KFNvcnRUZXJtW10gdGVybSwgU2VhcmNoVGVybSBzdGVybSkKKwkJCXRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiwgU2VhcmNoRXhjZXB0aW9uIHsKKwlpZiAoIWhhc0NhcGFiaWxpdHkoIlNPUlQqIikpIAorCSAgICB0aHJvdyBuZXcgQmFkQ29tbWFuZEV4Y2VwdGlvbigiU09SVCBub3Qgc3VwcG9ydGVkIik7CisKKwlpZiAodGVybSA9PSBudWxsIHx8IHRlcm0ubGVuZ3RoID09IDApCisJICAgIHRocm93IG5ldyBCYWRDb21tYW5kRXhjZXB0aW9uKCJNdXN0IGhhdmUgYXQgbGVhc3Qgb25lIHNvcnQgdGVybSIpOworCisJQXJndW1lbnQgYXJncyA9IG5ldyBBcmd1bWVudCgpOworCUFyZ3VtZW50IHNhcmdzID0gbmV3IEFyZ3VtZW50KCk7CisJZm9yIChpbnQgaSA9IDA7IGkgPCB0ZXJtLmxlbmd0aDsgaSsrKQorCSAgICBzYXJncy53cml0ZUF0b20odGVybVtpXS50b1N0cmluZygpKTsKKwlhcmdzLndyaXRlQXJndW1lbnQoc2FyZ3MpOwkvLyBzb3J0IGNyaXRlcmlhCisKKwlhcmdzLndyaXRlQXRvbSgiVVRGLTgiKTsJLy8gY2hhcnNldCBzcGVjaWZpY2F0aW9uCisJaWYgKHN0ZXJtICE9IG51bGwpIHsKKwkgICAgdHJ5IHsKKwkJYXJncy5hcHBlbmQoCisJCSAgICBnZXRTZWFyY2hTZXF1ZW5jZSgpLmdlbmVyYXRlU2VxdWVuY2Uoc3Rlcm0sICJVVEYtOCIpKTsKKwkgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9leCkgeworCQkvLyBzaG91bGQgbmV2ZXIgaGFwcGVuCisJCXRocm93IG5ldyBTZWFyY2hFeGNlcHRpb24oaW9leC50b1N0cmluZygpKTsKKwkgICAgfQorCX0gZWxzZQorCSAgICBhcmdzLndyaXRlQXRvbSgiQUxMIik7CisKKwlSZXNwb25zZVtdIHIgPSBjb21tYW5kKCJTT1JUIiwgYXJncyk7CisJUmVzcG9uc2UgcmVzcG9uc2UgPSByW3IubGVuZ3RoLTFdOworCWludFtdIG1hdGNoZXMgPSBudWxsOworCisJLy8gR3JhYiBhbGwgU09SVCByZXNwb25zZXMKKwlpZiAocmVzcG9uc2UuaXNPSygpKSB7IC8vIGNvbW1hbmQgc3VjY2VzZnVsCisJICAgIExpc3Q8SW50ZWdlcj4gdiA9IG5ldyBBcnJheUxpc3Q8PigpOworCSAgICBpbnQgbnVtOworCSAgICBmb3IgKGludCBpID0gMCwgbGVuID0gci5sZW5ndGg7IGkgPCBsZW47IGkrKykgeworCQlpZiAoIShyW2ldIGluc3RhbmNlb2YgSU1BUFJlc3BvbnNlKSkKKwkJICAgIGNvbnRpbnVlOworCisJCUlNQVBSZXNwb25zZSBpciA9IChJTUFQUmVzcG9uc2UpcltpXTsKKwkJaWYgKGlyLmtleUVxdWFscygiU09SVCIpKSB7CisJCSAgICB3aGlsZSAoKG51bSA9IGlyLnJlYWROdW1iZXIoKSkgIT0gLTEpCisJCQl2LmFkZChJbnRlZ2VyLnZhbHVlT2YobnVtKSk7CisJCSAgICByW2ldID0gbnVsbDsKKwkJfQorCSAgICB9CisKKwkgICAgLy8gQ29weSB0aGUgbGlzdCBpbnRvICdtYXRjaGVzJworCSAgICBpbnQgdnNpemUgPSB2LnNpemUoKTsKKwkgICAgbWF0Y2hlcyA9IG5ldyBpbnRbdnNpemVdOworCSAgICBmb3IgKGludCBpID0gMDsgaSA8IHZzaXplOyBpKyspCisJCW1hdGNoZXNbaV0gPSB2LmdldChpKS5pbnRWYWx1ZSgpOworCX0KKworCS8vIGRpc3BhdGNoIHJlbWFpbmluZyB1bnRhZ2dlZCByZXNwb25zZXMKKwlub3RpZnlSZXNwb25zZUhhbmRsZXJzKHIpOworCWhhbmRsZVJlc3VsdChyZXNwb25zZSk7CisJcmV0dXJuIG1hdGNoZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogTkFNRVNQQUNFIENvbW1hbmQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBuYW1lc3BhY2VzCisgICAgICogQGV4Y2VwdGlvbglQcm90b2NvbEV4Y2VwdGlvbglmb3IgcHJvdG9jb2wgZmFpbHVyZXMKKyAgICAgKiBAc2VlICJSRkMyMzQyIgorICAgICAqLworICAgIHB1YmxpYyBOYW1lc3BhY2VzIG5hbWVzcGFjZSgpIHRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJaWYgKCFoYXNDYXBhYmlsaXR5KCJOQU1FU1BBQ0UiKSkgCisJICAgIHRocm93IG5ldyBCYWRDb21tYW5kRXhjZXB0aW9uKCJOQU1FU1BBQ0Ugbm90IHN1cHBvcnRlZCIpOworCisJUmVzcG9uc2VbXSByID0gY29tbWFuZCgiTkFNRVNQQUNFIiwgbnVsbCk7CisKKwlOYW1lc3BhY2VzIG5hbWVzcGFjZSA9IG51bGw7CisJUmVzcG9uc2UgcmVzcG9uc2UgPSByW3IubGVuZ3RoLTFdOworCisJLy8gR3JhYiBOQU1FU1BBQ0UgcmVzcG9uc2UKKwlpZiAocmVzcG9uc2UuaXNPSygpKSB7IC8vIGNvbW1hbmQgc3VjY2VzZnVsIAorCSAgICBmb3IgKGludCBpID0gMCwgbGVuID0gci5sZW5ndGg7IGkgPCBsZW47IGkrKykgeworCQlpZiAoIShyW2ldIGluc3RhbmNlb2YgSU1BUFJlc3BvbnNlKSkKKwkJICAgIGNvbnRpbnVlOworCisJCUlNQVBSZXNwb25zZSBpciA9IChJTUFQUmVzcG9uc2UpcltpXTsKKwkJaWYgKGlyLmtleUVxdWFscygiTkFNRVNQQUNFIikpIHsKKwkJICAgIGlmIChuYW1lc3BhY2UgPT0gbnVsbCkKKwkJCW5hbWVzcGFjZSA9IG5ldyBOYW1lc3BhY2VzKGlyKTsKKwkJICAgIHJbaV0gPSBudWxsOworCQl9CisJICAgIH0KKwl9CisKKwkvLyBkaXNwYXRjaCByZW1haW5pbmcgdW50YWdnZWQgcmVzcG9uc2VzCisJbm90aWZ5UmVzcG9uc2VIYW5kbGVycyhyKTsKKwloYW5kbGVSZXN1bHQocmVzcG9uc2UpOworCXJldHVybiBuYW1lc3BhY2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogR0VUUVVPVEFST09UIENvbW1hbmQuCisgICAgICoKKyAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIFF1b3RhIG9iamVjdHMsIHJlcHJlc2VudGluZyB0aGUgcXVvdGFzCisgICAgICogZm9yIHRoaXMgbWFpbGJveCBhbmQsIGluZGlyZWN0bHksIHRoZSBxdW90YXJvb3RzIGZvciB0aGlzCisgICAgICogbWFpbGJveC4KKyAgICAgKgorICAgICAqIEBwYXJhbQltYm94CXRoZSBtYWlsYm94CisgICAgICogQHJldHVybgkJYXJyYXkgb2YgUXVvdGEgb2JqZWN0cworICAgICAqIEBleGNlcHRpb24JUHJvdG9jb2xFeGNlcHRpb24JZm9yIHByb3RvY29sIGZhaWx1cmVzCisgICAgICogQHNlZSAiUkZDMjA4NyIKKyAgICAgKi8KKyAgICBwdWJsaWMgUXVvdGFbXSBnZXRRdW90YVJvb3QoU3RyaW5nIG1ib3gpIHRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJaWYgKCFoYXNDYXBhYmlsaXR5KCJRVU9UQSIpKSAKKwkgICAgdGhyb3cgbmV3IEJhZENvbW1hbmRFeGNlcHRpb24oIkdFVFFVT1RBUk9PVCBub3Qgc3VwcG9ydGVkIik7CisKKwlBcmd1bWVudCBhcmdzID0gbmV3IEFyZ3VtZW50KCk7CQorCXdyaXRlTWFpbGJveE5hbWUoYXJncywgbWJveCk7CisKKwlSZXNwb25zZVtdIHIgPSBjb21tYW5kKCJHRVRRVU9UQVJPT1QiLCBhcmdzKTsKKworCVJlc3BvbnNlIHJlc3BvbnNlID0gcltyLmxlbmd0aC0xXTsKKworCU1hcDxTdHJpbmcsIFF1b3RhPiB0YWIgPSBuZXcgSGFzaE1hcDw+KCk7CisKKwkvLyBHcmFiIGFsbCBRVU9UQVJPT1QgYW5kIFFVT1RBIHJlc3BvbnNlcworCWlmIChyZXNwb25zZS5pc09LKCkpIHsgLy8gY29tbWFuZCBzdWNjZXNmdWwgCisJICAgIGZvciAoaW50IGkgPSAwLCBsZW4gPSByLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7CisJCWlmICghKHJbaV0gaW5zdGFuY2VvZiBJTUFQUmVzcG9uc2UpKQorCQkgICAgY29udGludWU7CisKKwkJSU1BUFJlc3BvbnNlIGlyID0gKElNQVBSZXNwb25zZSlyW2ldOworCQlpZiAoaXIua2V5RXF1YWxzKCJRVU9UQVJPT1QiKSkgeworCQkgICAgLy8gcXVvdGFyb290X3Jlc3BvbnNlCisJCSAgICAvLwkJICAgICAgIDo6PSAiUVVPVEFST09UIiBTUCBhc3RyaW5nICooU1AgYXN0cmluZykKKworCQkgICAgLy8gcmVhZCBuYW1lIG9mIG1haWxib3ggYW5kIHRocm93IGF3YXkKKwkJICAgIGlyLnJlYWRBdG9tU3RyaW5nKCk7CisJCSAgICAvLyBmb3IgZWFjaCBxdW90YXJvb3QgYWRkIGEgcGxhY2Vob2xkZXIgcXVvdGEKKwkJICAgIFN0cmluZyByb290ID0gbnVsbDsKKwkJICAgIHdoaWxlICgocm9vdCA9IGlyLnJlYWRBdG9tU3RyaW5nKCkpICE9IG51bGwgJiYKKwkJCSAgICByb290Lmxlbmd0aCgpID4gMCkKKwkJCXRhYi5wdXQocm9vdCwgbmV3IFF1b3RhKHJvb3QpKTsKKwkJICAgIHJbaV0gPSBudWxsOworCQl9IGVsc2UgaWYgKGlyLmtleUVxdWFscygiUVVPVEEiKSkgeworCQkgICAgUXVvdGEgcXVvdGEgPSBwYXJzZVF1b3RhKGlyKTsKKwkJICAgIFF1b3RhIHEgPSB0YWIuZ2V0KHF1b3RhLnF1b3RhUm9vdCk7CisJCSAgICBpZiAocSAhPSBudWxsICYmIHEucmVzb3VyY2VzICE9IG51bGwpIHsKKwkJCS8vIG1lcmdlIHJlc291cmNlcworCQkJaW50IG5ld2wgPSBxLnJlc291cmNlcy5sZW5ndGggKyBxdW90YS5yZXNvdXJjZXMubGVuZ3RoOworCQkJUXVvdGEuUmVzb3VyY2VbXSBuZXdyID0gbmV3IFF1b3RhLlJlc291cmNlW25ld2xdOworCQkJU3lzdGVtLmFycmF5Y29weShxLnJlc291cmNlcywgMCwgbmV3ciwgMCwKKwkJCQkJCQlxLnJlc291cmNlcy5sZW5ndGgpOworCQkJU3lzdGVtLmFycmF5Y29weShxdW90YS5yZXNvdXJjZXMsIDAsCisJCQkgICAgbmV3ciwgcS5yZXNvdXJjZXMubGVuZ3RoLCBxdW90YS5yZXNvdXJjZXMubGVuZ3RoKTsKKwkJCXF1b3RhLnJlc291cmNlcyA9IG5ld3I7CisJCSAgICB9CisJCSAgICB0YWIucHV0KHF1b3RhLnF1b3RhUm9vdCwgcXVvdGEpOworCQkgICAgcltpXSA9IG51bGw7CisJCX0KKwkgICAgfQorCX0KKworCS8vIGRpc3BhdGNoIHJlbWFpbmluZyB1bnRhZ2dlZCByZXNwb25zZXMKKwlub3RpZnlSZXNwb25zZUhhbmRsZXJzKHIpOworCWhhbmRsZVJlc3VsdChyZXNwb25zZSk7CisKKwlyZXR1cm4gdGFiLnZhbHVlcygpLnRvQXJyYXkobmV3IFF1b3RhW3RhYi5zaXplKCldKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHRVRRVU9UQSBDb21tYW5kLgorICAgICAqCisgICAgICogUmV0dXJucyBhbiBhcnJheSBvZiBRdW90YSBvYmplY3RzLCByZXByZXNlbnRpbmcgdGhlIHF1b3RhcworICAgICAqIGZvciB0aGlzIHF1b3Rhcm9vdC4KKyAgICAgKgorICAgICAqIEBwYXJhbQlyb290CXRoZSBxdW90YXJvb3QKKyAgICAgKiBAcmV0dXJuCQl0aGUgcXVvdGFzCisgICAgICogQGV4Y2VwdGlvbglQcm90b2NvbEV4Y2VwdGlvbglmb3IgcHJvdG9jb2wgZmFpbHVyZXMKKyAgICAgKiBAc2VlICJSRkMyMDg3IgorICAgICAqLworICAgIHB1YmxpYyBRdW90YVtdIGdldFF1b3RhKFN0cmluZyByb290KSB0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCWlmICghaGFzQ2FwYWJpbGl0eSgiUVVPVEEiKSkgCisJICAgIHRocm93IG5ldyBCYWRDb21tYW5kRXhjZXB0aW9uKCJRVU9UQSBub3Qgc3VwcG9ydGVkIik7CisKKwlBcmd1bWVudCBhcmdzID0gbmV3IEFyZ3VtZW50KCk7CQorCWFyZ3Mud3JpdGVTdHJpbmcocm9vdCk7CQkvLyBYWFggLSBjb3VsZCBiZSBVVEYtOD8KKworCVJlc3BvbnNlW10gciA9IGNvbW1hbmQoIkdFVFFVT1RBIiwgYXJncyk7CisKKwlRdW90YSBxdW90YSA9IG51bGw7CisJTGlzdDxRdW90YT4gdiA9IG5ldyBBcnJheUxpc3Q8PigpOworCVJlc3BvbnNlIHJlc3BvbnNlID0gcltyLmxlbmd0aC0xXTsKKworCS8vIEdyYWIgYWxsIFFVT1RBIHJlc3BvbnNlcworCWlmIChyZXNwb25zZS5pc09LKCkpIHsgLy8gY29tbWFuZCBzdWNjZXNmdWwgCisJICAgIGZvciAoaW50IGkgPSAwLCBsZW4gPSByLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7CisJCWlmICghKHJbaV0gaW5zdGFuY2VvZiBJTUFQUmVzcG9uc2UpKQorCQkgICAgY29udGludWU7CisKKwkJSU1BUFJlc3BvbnNlIGlyID0gKElNQVBSZXNwb25zZSlyW2ldOworCQlpZiAoaXIua2V5RXF1YWxzKCJRVU9UQSIpKSB7CisJCSAgICBxdW90YSA9IHBhcnNlUXVvdGEoaXIpOworCQkgICAgdi5hZGQocXVvdGEpOworCQkgICAgcltpXSA9IG51bGw7CisJCX0KKwkgICAgfQorCX0KKworCS8vIGRpc3BhdGNoIHJlbWFpbmluZyB1bnRhZ2dlZCByZXNwb25zZXMKKwlub3RpZnlSZXNwb25zZUhhbmRsZXJzKHIpOworCWhhbmRsZVJlc3VsdChyZXNwb25zZSk7CisJcmV0dXJuIHYudG9BcnJheShuZXcgUXVvdGFbdi5zaXplKCldKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTRVRRVU9UQSBDb21tYW5kLgorICAgICAqCisgICAgICogU2V0IHRoZSBpbmRpY2F0ZWQgcXVvdGEgb24gdGhlIGNvcnJlc3BvbmRpbmcgcXVvdGFyb290LgorICAgICAqCisgICAgICogQHBhcmFtCXF1b3RhCXRoZSBxdW90YSB0byBzZXQKKyAgICAgKiBAZXhjZXB0aW9uCVByb3RvY29sRXhjZXB0aW9uCWZvciBwcm90b2NvbCBmYWlsdXJlcworICAgICAqIEBzZWUgIlJGQzIwODciCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UXVvdGEoUXVvdGEgcXVvdGEpIHRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJaWYgKCFoYXNDYXBhYmlsaXR5KCJRVU9UQSIpKSAKKwkgICAgdGhyb3cgbmV3IEJhZENvbW1hbmRFeGNlcHRpb24oIlFVT1RBIG5vdCBzdXBwb3J0ZWQiKTsKKworCUFyZ3VtZW50IGFyZ3MgPSBuZXcgQXJndW1lbnQoKTsJCisJYXJncy53cml0ZVN0cmluZyhxdW90YS5xdW90YVJvb3QpOwkvLyBYWFggLSBjb3VsZCBiZSBVVEYtOD8KKwlBcmd1bWVudCBxYXJncyA9IG5ldyBBcmd1bWVudCgpOwkKKwlpZiAocXVvdGEucmVzb3VyY2VzICE9IG51bGwpIHsKKwkgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBxdW90YS5yZXNvdXJjZXMubGVuZ3RoOyBpKyspIHsKKwkJcWFyZ3Mud3JpdGVBdG9tKHF1b3RhLnJlc291cmNlc1tpXS5uYW1lKTsKKwkJcWFyZ3Mud3JpdGVOdW1iZXIocXVvdGEucmVzb3VyY2VzW2ldLmxpbWl0KTsKKwkgICAgfQorCX0KKwlhcmdzLndyaXRlQXJndW1lbnQocWFyZ3MpOworCisJUmVzcG9uc2VbXSByID0gY29tbWFuZCgiU0VUUVVPVEEiLCBhcmdzKTsKKwlSZXNwb25zZSByZXNwb25zZSA9IHJbci5sZW5ndGgtMV07CisKKwkvLyBYWFggLSBJdCdzIG5vdCBjbGVhciBmcm9tIHRoZSBSRkMgd2hldGhlciB0aGUgU0VUUVVPVEEgY29tbWFuZAorCS8vIHdpbGwgcHJvdm9rZSB1bnRhZ2dlZCBRVU9UQSByZXNwb25zZXMuICBJZiBpdCBkb2VzLCBwZXJoYXBzCisJLy8gd2Ugc2hvdWxkIGdyYWIgdGhlbSBoZXJlIGFuZCByZXR1cm4gdGhlbT8KKworCS8qCisJUXVvdGEgcXVvdGEgPSBudWxsOworCUxpc3Q8UXVvdGE+IHYgPSBuZXcgQXJyYXlMaXN0PFF1b3RhPigpOworCisJLy8gR3JhYiBhbGwgUVVPVEEgcmVzcG9uc2VzCisJaWYgKHJlc3BvbnNlLmlzT0soKSkgeyAvLyBjb21tYW5kIHN1Y2Nlc2Z1bCAKKwkgICAgZm9yIChpbnQgaSA9IDAsIGxlbiA9IHIubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHsKKwkJaWYgKCEocltpXSBpbnN0YW5jZW9mIElNQVBSZXNwb25zZSkpCisJCSAgICBjb250aW51ZTsKKworCQlJTUFQUmVzcG9uc2UgaXIgPSAoSU1BUFJlc3BvbnNlKXJbaV07CisJCWlmIChpci5rZXlFcXVhbHMoIlFVT1RBIikpIHsKKwkJICAgIHF1b3RhID0gcGFyc2VRdW90YShpcik7CisJCSAgICB2LmFkZChxdW90YSk7CisJCSAgICByW2ldID0gbnVsbDsKKwkJfQorCSAgICB9CisJfQorCSovCisKKwkvLyBkaXNwYXRjaCByZW1haW5pbmcgdW50YWdnZWQgcmVzcG9uc2VzCisJbm90aWZ5UmVzcG9uc2VIYW5kbGVycyhyKTsKKwloYW5kbGVSZXN1bHQocmVzcG9uc2UpOworCS8qCisJcmV0dXJuIHYudG9BcnJheShuZXcgUXVvdGFbdi5zaXplKCldKTsKKwkqLworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlIGEgUVVPVEEgcmVzcG9uc2UuCisgICAgICovCisgICAgcHJpdmF0ZSBRdW90YSBwYXJzZVF1b3RhKFJlc3BvbnNlIHIpIHRocm93cyBQYXJzaW5nRXhjZXB0aW9uIHsKKwkvLyBxdW90YV9yZXNwb25zZSA6Oj0gIlFVT1RBIiBTUCBhc3RyaW5nIFNQIHF1b3RhX2xpc3QKKwlTdHJpbmcgcXVvdGFSb290ID0gci5yZWFkQXRvbVN0cmluZygpOwkvLyBxdW90YXJvb3QgOjo9IGFzdHJpbmcKKwlRdW90YSBxID0gbmV3IFF1b3RhKHF1b3RhUm9vdCk7CisJci5za2lwU3BhY2VzKCk7CisJLy8gcXVvdGFfbGlzdCA6Oj0gIigiICNxdW90YV9yZXNvdXJjZSAiKSIKKwlpZiAoci5yZWFkQnl0ZSgpICE9ICcoJykKKwkgICAgdGhyb3cgbmV3IFBhcnNpbmdFeGNlcHRpb24oInBhcnNlIGVycm9yIGluIFFVT1RBIik7CisKKwlMaXN0PFF1b3RhLlJlc291cmNlPiB2ID0gbmV3IEFycmF5TGlzdDw+KCk7CisJd2hpbGUgKCFyLmlzTmV4dE5vblNwYWNlKCcpJykpIHsKKwkgICAgLy8gcXVvdGFfcmVzb3VyY2UgOjo9IGF0b20gU1AgbnVtYmVyIFNQIG51bWJlcgorCSAgICBTdHJpbmcgbmFtZSA9IHIucmVhZEF0b20oKTsKKwkgICAgaWYgKG5hbWUgIT0gbnVsbCkgeworCQlsb25nIHVzYWdlID0gci5yZWFkTG9uZygpOworCQlsb25nIGxpbWl0ID0gci5yZWFkTG9uZygpOworCQlRdW90YS5SZXNvdXJjZSByZXMgPSBuZXcgUXVvdGEuUmVzb3VyY2UobmFtZSwgdXNhZ2UsIGxpbWl0KTsKKwkJdi5hZGQocmVzKTsKKwkgICAgfQorCX0KKwlxLnJlc291cmNlcyA9IHYudG9BcnJheShuZXcgUXVvdGEuUmVzb3VyY2Vbdi5zaXplKCldKTsKKwlyZXR1cm4gcTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFNFVEFDTCBDb21tYW5kLgorICAgICAqCisgICAgICogQHBhcmFtCW1ib3gJdGhlIG1haWxib3gKKyAgICAgKiBAcGFyYW0JbW9kaWZpZXIJdGhlIEFDTCBtb2RpZmllcgorICAgICAqIEBwYXJhbQlhY2wJdGhlIEFDTAorICAgICAqIEBleGNlcHRpb24JUHJvdG9jb2xFeGNlcHRpb24JZm9yIHByb3RvY29sIGZhaWx1cmVzCisgICAgICogQHNlZSAiUkZDMjA4NiIKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRBQ0woU3RyaW5nIG1ib3gsIGNoYXIgbW9kaWZpZXIsIEFDTCBhY2wpCisJCQkJdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKwlpZiAoIWhhc0NhcGFiaWxpdHkoIkFDTCIpKSAKKwkgICAgdGhyb3cgbmV3IEJhZENvbW1hbmRFeGNlcHRpb24oIkFDTCBub3Qgc3VwcG9ydGVkIik7CisKKwlBcmd1bWVudCBhcmdzID0gbmV3IEFyZ3VtZW50KCk7CQorCXdyaXRlTWFpbGJveE5hbWUoYXJncywgbWJveCk7CisJYXJncy53cml0ZVN0cmluZyhhY2wuZ2V0TmFtZSgpKTsKKwlTdHJpbmcgcmlnaHRzID0gYWNsLmdldFJpZ2h0cygpLnRvU3RyaW5nKCk7CisJaWYgKG1vZGlmaWVyID09ICcrJyB8fCBtb2RpZmllciA9PSAnLScpCisJICAgIHJpZ2h0cyA9IG1vZGlmaWVyICsgcmlnaHRzOworCWFyZ3Mud3JpdGVTdHJpbmcocmlnaHRzKTsKKworCVJlc3BvbnNlW10gciA9IGNvbW1hbmQoIlNFVEFDTCIsIGFyZ3MpOworCVJlc3BvbnNlIHJlc3BvbnNlID0gcltyLmxlbmd0aC0xXTsKKworCS8vIGRpc3BhdGNoIHVudGFnZ2VkIHJlc3BvbnNlcworCW5vdGlmeVJlc3BvbnNlSGFuZGxlcnMocik7CisJaGFuZGxlUmVzdWx0KHJlc3BvbnNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBERUxFVEVBQ0wgQ29tbWFuZC4KKyAgICAgKgorICAgICAqIEBwYXJhbQltYm94CXRoZSBtYWlsYm94CisgICAgICogQHBhcmFtCXVzZXIJdGhlIHVzZXIKKyAgICAgKiBAZXhjZXB0aW9uCVByb3RvY29sRXhjZXB0aW9uCWZvciBwcm90b2NvbCBmYWlsdXJlcworICAgICAqIEBzZWUgIlJGQzIwODYiCisgICAgICovCisgICAgcHVibGljIHZvaWQgZGVsZXRlQUNMKFN0cmluZyBtYm94LCBTdHJpbmcgdXNlcikgdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKwlpZiAoIWhhc0NhcGFiaWxpdHkoIkFDTCIpKSAKKwkgICAgdGhyb3cgbmV3IEJhZENvbW1hbmRFeGNlcHRpb24oIkFDTCBub3Qgc3VwcG9ydGVkIik7CisKKwlBcmd1bWVudCBhcmdzID0gbmV3IEFyZ3VtZW50KCk7CQorCXdyaXRlTWFpbGJveE5hbWUoYXJncywgbWJveCk7CisJYXJncy53cml0ZVN0cmluZyh1c2VyKTsJCS8vIFhYWCAtIGNvdWxkIGJlIFVURi04PworCisJUmVzcG9uc2VbXSByID0gY29tbWFuZCgiREVMRVRFQUNMIiwgYXJncyk7CisJUmVzcG9uc2UgcmVzcG9uc2UgPSByW3IubGVuZ3RoLTFdOworCisJLy8gZGlzcGF0Y2ggdW50YWdnZWQgcmVzcG9uc2VzCisJbm90aWZ5UmVzcG9uc2VIYW5kbGVycyhyKTsKKwloYW5kbGVSZXN1bHQocmVzcG9uc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdFVEFDTCBDb21tYW5kLgorICAgICAqCisgICAgICogQHBhcmFtCW1ib3gJdGhlIG1haWxib3gKKyAgICAgKiBAcmV0dXJuCQl0aGUgQUNMIGFycmF5CisgICAgICogQGV4Y2VwdGlvbglQcm90b2NvbEV4Y2VwdGlvbglmb3IgcHJvdG9jb2wgZmFpbHVyZXMKKyAgICAgKiBAc2VlICJSRkMyMDg2IgorICAgICAqLworICAgIHB1YmxpYyBBQ0xbXSBnZXRBQ0woU3RyaW5nIG1ib3gpIHRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJaWYgKCFoYXNDYXBhYmlsaXR5KCJBQ0wiKSkgCisJICAgIHRocm93IG5ldyBCYWRDb21tYW5kRXhjZXB0aW9uKCJBQ0wgbm90IHN1cHBvcnRlZCIpOworCisJQXJndW1lbnQgYXJncyA9IG5ldyBBcmd1bWVudCgpOwkKKwl3cml0ZU1haWxib3hOYW1lKGFyZ3MsIG1ib3gpOworCisJUmVzcG9uc2VbXSByID0gY29tbWFuZCgiR0VUQUNMIiwgYXJncyk7CisJUmVzcG9uc2UgcmVzcG9uc2UgPSByW3IubGVuZ3RoLTFdOworCisJLy8gR3JhYiBhbGwgQUNMIHJlc3BvbnNlcworCUxpc3Q8QUNMPiB2ID0gbmV3IEFycmF5TGlzdDw+KCk7CisJaWYgKHJlc3BvbnNlLmlzT0soKSkgeyAvLyBjb21tYW5kIHN1Y2Nlc2Z1bCAKKwkgICAgZm9yIChpbnQgaSA9IDAsIGxlbiA9IHIubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHsKKwkJaWYgKCEocltpXSBpbnN0YW5jZW9mIElNQVBSZXNwb25zZSkpCisJCSAgICBjb250aW51ZTsKKworCQlJTUFQUmVzcG9uc2UgaXIgPSAoSU1BUFJlc3BvbnNlKXJbaV07CisJCWlmIChpci5rZXlFcXVhbHMoIkFDTCIpKSB7CisJCSAgICAvLyBhY2xfZGF0YSA6Oj0gIkFDTCIgU1BBQ0UgbWFpbGJveAorCQkgICAgLy8JCSooU1BBQ0UgaWRlbnRpZmllciBTUEFDRSByaWdodHMpCisJCSAgICAvLyByZWFkIG5hbWUgb2YgbWFpbGJveCBhbmQgdGhyb3cgYXdheQorCQkgICAgaXIucmVhZEF0b21TdHJpbmcoKTsKKwkJICAgIFN0cmluZyBuYW1lID0gbnVsbDsKKwkJICAgIHdoaWxlICgobmFtZSA9IGlyLnJlYWRBdG9tU3RyaW5nKCkpICE9IG51bGwpIHsKKwkJCVN0cmluZyByaWdodHMgPSBpci5yZWFkQXRvbVN0cmluZygpOworCQkJaWYgKHJpZ2h0cyA9PSBudWxsKQorCQkJICAgIGJyZWFrOworCQkJQUNMIGFjbCA9IG5ldyBBQ0wobmFtZSwgbmV3IFJpZ2h0cyhyaWdodHMpKTsKKwkJCXYuYWRkKGFjbCk7CisJCSAgICB9CisJCSAgICByW2ldID0gbnVsbDsKKwkJfQorCSAgICB9CisJfQorCisJLy8gZGlzcGF0Y2ggcmVtYWluaW5nIHVudGFnZ2VkIHJlc3BvbnNlcworCW5vdGlmeVJlc3BvbnNlSGFuZGxlcnMocik7CisJaGFuZGxlUmVzdWx0KHJlc3BvbnNlKTsKKwlyZXR1cm4gdi50b0FycmF5KG5ldyBBQ0xbdi5zaXplKCldKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMSVNUUklHSFRTIENvbW1hbmQuCisgICAgICoKKyAgICAgKiBAcGFyYW0JbWJveAl0aGUgbWFpbGJveAorICAgICAqIEBwYXJhbQl1c2VyCXRoZSB1c2VyIHJpZ2h0cyB0byByZXR1cm4KKyAgICAgKiBAcmV0dXJuCQl0aGUgcmlnaHRzIGFycmF5CisgICAgICogQGV4Y2VwdGlvbglQcm90b2NvbEV4Y2VwdGlvbglmb3IgcHJvdG9jb2wgZmFpbHVyZXMKKyAgICAgKiBAc2VlICJSRkMyMDg2IgorICAgICAqLworICAgIHB1YmxpYyBSaWdodHNbXSBsaXN0UmlnaHRzKFN0cmluZyBtYm94LCBTdHJpbmcgdXNlcikKKwkJCQl0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCWlmICghaGFzQ2FwYWJpbGl0eSgiQUNMIikpIAorCSAgICB0aHJvdyBuZXcgQmFkQ29tbWFuZEV4Y2VwdGlvbigiQUNMIG5vdCBzdXBwb3J0ZWQiKTsKKworCUFyZ3VtZW50IGFyZ3MgPSBuZXcgQXJndW1lbnQoKTsJCisJd3JpdGVNYWlsYm94TmFtZShhcmdzLCBtYm94KTsKKwlhcmdzLndyaXRlU3RyaW5nKHVzZXIpOwkJLy8gWFhYIC0gY291bGQgYmUgVVRGLTg/CisKKwlSZXNwb25zZVtdIHIgPSBjb21tYW5kKCJMSVNUUklHSFRTIiwgYXJncyk7CisJUmVzcG9uc2UgcmVzcG9uc2UgPSByW3IubGVuZ3RoLTFdOworCisJLy8gR3JhYiBMSVNUUklHSFRTIHJlc3BvbnNlCisJTGlzdDxSaWdodHM+IHYgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKwlpZiAocmVzcG9uc2UuaXNPSygpKSB7IC8vIGNvbW1hbmQgc3VjY2VzZnVsIAorCSAgICBmb3IgKGludCBpID0gMCwgbGVuID0gci5sZW5ndGg7IGkgPCBsZW47IGkrKykgeworCQlpZiAoIShyW2ldIGluc3RhbmNlb2YgSU1BUFJlc3BvbnNlKSkKKwkJICAgIGNvbnRpbnVlOworCisJCUlNQVBSZXNwb25zZSBpciA9IChJTUFQUmVzcG9uc2UpcltpXTsKKwkJaWYgKGlyLmtleUVxdWFscygiTElTVFJJR0hUUyIpKSB7CisJCSAgICAvLyBsaXN0cmlnaHRzX2RhdGEgOjo9ICJMSVNUUklHSFRTIiBTUEFDRSBtYWlsYm94CisJCSAgICAvLwkJU1BBQ0UgaWRlbnRpZmllciBTUEFDRSByaWdodHMgKihTUEFDRSByaWdodHMpCisJCSAgICAvLyByZWFkIG5hbWUgb2YgbWFpbGJveCBhbmQgdGhyb3cgYXdheQorCQkgICAgaXIucmVhZEF0b21TdHJpbmcoKTsKKwkJICAgIC8vIHJlYWQgaWRlbnRpZmllciBhbmQgdGhyb3cgYXdheQorCQkgICAgaXIucmVhZEF0b21TdHJpbmcoKTsKKwkJICAgIFN0cmluZyByaWdodHM7CisJCSAgICB3aGlsZSAoKHJpZ2h0cyA9IGlyLnJlYWRBdG9tU3RyaW5nKCkpICE9IG51bGwpCisJCQl2LmFkZChuZXcgUmlnaHRzKHJpZ2h0cykpOworCQkgICAgcltpXSA9IG51bGw7CisJCX0KKwkgICAgfQorCX0KKworCS8vIGRpc3BhdGNoIHJlbWFpbmluZyB1bnRhZ2dlZCByZXNwb25zZXMKKwlub3RpZnlSZXNwb25zZUhhbmRsZXJzKHIpOworCWhhbmRsZVJlc3VsdChyZXNwb25zZSk7CisJcmV0dXJuIHYudG9BcnJheShuZXcgUmlnaHRzW3Yuc2l6ZSgpXSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTVlSSUdIVFMgQ29tbWFuZC4KKyAgICAgKgorICAgICAqIEBwYXJhbQltYm94CXRoZSBtYWlsYm94CisgICAgICogQHJldHVybgkJdGhlIHJpZ2h0cworICAgICAqIEBleGNlcHRpb24JUHJvdG9jb2xFeGNlcHRpb24JZm9yIHByb3RvY29sIGZhaWx1cmVzCisgICAgICogQHNlZSAiUkZDMjA4NiIKKyAgICAgKi8KKyAgICBwdWJsaWMgUmlnaHRzIG15UmlnaHRzKFN0cmluZyBtYm94KSB0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCWlmICghaGFzQ2FwYWJpbGl0eSgiQUNMIikpIAorCSAgICB0aHJvdyBuZXcgQmFkQ29tbWFuZEV4Y2VwdGlvbigiQUNMIG5vdCBzdXBwb3J0ZWQiKTsKKworCUFyZ3VtZW50IGFyZ3MgPSBuZXcgQXJndW1lbnQoKTsJCisJd3JpdGVNYWlsYm94TmFtZShhcmdzLCBtYm94KTsKKworCVJlc3BvbnNlW10gciA9IGNvbW1hbmQoIk1ZUklHSFRTIiwgYXJncyk7CisJUmVzcG9uc2UgcmVzcG9uc2UgPSByW3IubGVuZ3RoLTFdOworCisJLy8gR3JhYiBNWVJJR0hUUyByZXNwb25zZQorCVJpZ2h0cyByaWdodHMgPSBudWxsOworCWlmIChyZXNwb25zZS5pc09LKCkpIHsgLy8gY29tbWFuZCBzdWNjZXNmdWwgCisJICAgIGZvciAoaW50IGkgPSAwLCBsZW4gPSByLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7CisJCWlmICghKHJbaV0gaW5zdGFuY2VvZiBJTUFQUmVzcG9uc2UpKQorCQkgICAgY29udGludWU7CisKKwkJSU1BUFJlc3BvbnNlIGlyID0gKElNQVBSZXNwb25zZSlyW2ldOworCQlpZiAoaXIua2V5RXF1YWxzKCJNWVJJR0hUUyIpKSB7CisJCSAgICAvLyBteXJpZ2h0c19kYXRhIDo6PSAiTVlSSUdIVFMiIFNQQUNFIG1haWxib3ggU1BBQ0UgcmlnaHRzCisJCSAgICAvLyByZWFkIG5hbWUgb2YgbWFpbGJveCBhbmQgdGhyb3cgYXdheQorCQkgICAgaXIucmVhZEF0b21TdHJpbmcoKTsKKwkJICAgIFN0cmluZyBycyA9IGlyLnJlYWRBdG9tU3RyaW5nKCk7CisJCSAgICBpZiAocmlnaHRzID09IG51bGwpCisJCQlyaWdodHMgPSBuZXcgUmlnaHRzKHJzKTsKKwkJICAgIHJbaV0gPSBudWxsOworCQl9CisJICAgIH0KKwl9CisKKwkvLyBkaXNwYXRjaCByZW1haW5pbmcgdW50YWdnZWQgcmVzcG9uc2VzCisJbm90aWZ5UmVzcG9uc2VIYW5kbGVycyhyKTsKKwloYW5kbGVSZXN1bHQocmVzcG9uc2UpOworCXJldHVybiByaWdodHM7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBUaGUgdGFnIHVzZWQgb24gdGhlIElETEUgY29tbWFuZC4gIFNldCBieSBpZGxlU3RhcnQoKSBhbmQKKyAgICAgKiB1c2VkIGluIHByb2Nlc3NJZGxlUmVzcG9uc2UoKSB0byBkZXRlcm1pbmUgaWYgdGhlIHJlc3BvbnNlCisgICAgICogaXMgdGhlIG1hdGNoaW5nIGVuZCB0YWcuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2xhdGlsZSBTdHJpbmcgaWRsZVRhZzsKKworICAgIC8qKgorICAgICAqIElETEUgQ29tbWFuZC4gPHA+CisgICAgICoKKyAgICAgKiBJZiB0aGUgc2VydmVyIHN1cHBvcnRzIHRoZSBJRExFIGNvbW1hbmQgZXh0ZW5zaW9uLCB0aGUgSURMRQorICAgICAqIGNvbW1hbmQgaXMgaXNzdWVkIGFuZCB0aGlzIG1ldGhvZCBibG9ja3MgdW50aWwgYSByZXNwb25zZSBoYXMKKyAgICAgKiBiZWVuIHJlY2VpdmVkLiAgT25jZSB0aGUgZmlyc3QgcmVzcG9uc2UgaGFzIGJlZW4gcmVjZWl2ZWQsIHRoZQorICAgICAqIElETEUgY29tbWFuZCBpcyB0ZXJtaW5hdGVkIGFuZCBhbGwgcmVzcG9uc2VzIGFyZSBjb2xsZWN0ZWQgYW5kCisgICAgICogaGFuZGxlZCBhbmQgdGhpcyBtZXRob2QgcmV0dXJucy4gPHA+CisgICAgICoKKyAgICAgKiBOb3RlIHRoYXQgd2hpbGUgdGhpcyBtZXRob2QgaXMgYmxvY2tlZCB3YWl0aW5nIGZvciBhIHJlc3BvbnNlLAorICAgICAqIG5vIG90aGVyIHRocmVhZHMgbWF5IGlzc3VlIGFueSBjb21tYW5kcyB0byB0aGUgc2VydmVyIHRoYXQgd291bGQKKyAgICAgKiB1c2UgdGhpcyBzYW1lIGNvbm5lY3Rpb24uCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uCVByb3RvY29sRXhjZXB0aW9uCWZvciBwcm90b2NvbCBmYWlsdXJlcworICAgICAqIEBzZWUgIlJGQzIxNzciCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNC4xCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGlkbGVTdGFydCgpIHRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJaWYgKCFoYXNDYXBhYmlsaXR5KCJJRExFIikpIAorCSAgICB0aHJvdyBuZXcgQmFkQ29tbWFuZEV4Y2VwdGlvbigiSURMRSBub3Qgc3VwcG9ydGVkIik7CisKKwlMaXN0PFJlc3BvbnNlPiB2ID0gbmV3IEFycmF5TGlzdDw+KCk7CisJYm9vbGVhbiBkb25lID0gZmFsc2U7CisJUmVzcG9uc2UgciA9IG51bGw7CisKKwkvLyB3cml0ZSB0aGUgY29tbWFuZAorCXRyeSB7CisJICAgIGlkbGVUYWcgPSB3cml0ZUNvbW1hbmQoIklETEUiLCBudWxsKTsKKwl9IGNhdGNoIChMaXRlcmFsRXhjZXB0aW9uIGxleCkgeworCSAgICB2LmFkZChsZXguZ2V0UmVzcG9uc2UoKSk7CisJICAgIGRvbmUgPSB0cnVlOworCX0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCSAgICAvLyBDb252ZXJ0IHRoaXMgaW50byBhIEJZRSByZXNwb25zZQorCSAgICB2LmFkZChSZXNwb25zZS5ieWVSZXNwb25zZShleCkpOworCSAgICBkb25lID0gdHJ1ZTsKKwl9CisKKwl3aGlsZSAoIWRvbmUpIHsKKwkgICAgdHJ5IHsKKwkJciA9IHJlYWRSZXNwb25zZSgpOworCSAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2V4KSB7CisJCS8vIGNvbnZlcnQgdGhpcyBpbnRvIGEgQllFIHJlc3BvbnNlCisJCXIgPSBSZXNwb25zZS5ieWVSZXNwb25zZShpb2V4KTsKKwkgICAgfSBjYXRjaCAoUHJvdG9jb2xFeGNlcHRpb24gcGV4KSB7CisJCWNvbnRpbnVlOyAvLyBza2lwIHRoaXMgcmVzcG9uc2UKKwkgICAgfQorCisJICAgIHYuYWRkKHIpOworCisJICAgIGlmIChyLmlzQ29udGludWF0aW9uKCkgfHwgci5pc0JZRSgpKQorCQlkb25lID0gdHJ1ZTsKKwl9CisKKwlSZXNwb25zZVtdIHJlc3BvbnNlcyA9IHYudG9BcnJheShuZXcgUmVzcG9uc2Vbdi5zaXplKCldKTsKKwlyID0gcmVzcG9uc2VzW3Jlc3BvbnNlcy5sZW5ndGgtMV07CisKKwkvLyBkaXNwYXRjaCByZW1haW5pbmcgdW50YWdnZWQgcmVzcG9uc2VzCisJbm90aWZ5UmVzcG9uc2VIYW5kbGVycyhyZXNwb25zZXMpOworCWlmICghci5pc0NvbnRpbnVhdGlvbigpKQorCSAgICBoYW5kbGVSZXN1bHQocik7CisgICAgfQorCisgICAgLyoqCisgICAgICogV2hpbGUgYW4gSURMRSBjb21tYW5kIGlzIGluIHByb2dyZXNzLCByZWFkIGEgcmVzcG9uc2UKKyAgICAgKiBzZW50IGZyb20gdGhlIHNlcnZlci4gIFRoZSByZXNwb25zZSBpcyByZWFkIHdpdGggbm8gbG9ja3MKKyAgICAgKiBoZWxkIHNvIHRoYXQgd2hlbiB0aGUgcmVhZCBibG9ja3Mgd2FpdGluZyBmb3IgdGhlIHJlc3BvbnNlCisgICAgICogZnJvbSB0aGUgc2VydmVyIGl0J3Mgbm90IGhvbGRpbmcgbG9ja3MgdGhhdCB3b3VsZCBwcmV2ZW50CisgICAgICogb3RoZXIgdGhyZWFkcyBmcm9tIGludGVycnVwdGluZyB0aGUgSURMRSBjb21tYW5kLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgcmVzcG9uc2UKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS40LjEKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIFJlc3BvbnNlIHJlYWRJZGxlUmVzcG9uc2UoKSB7CisJaWYgKGlkbGVUYWcgPT0gbnVsbCkKKwkgICAgcmV0dXJuIG51bGw7CS8vIElETEUgbm90IGluIHByb2dyZXNzCisJUmVzcG9uc2UgciA9IG51bGw7CisJdHJ5IHsKKwkgICAgciA9IHJlYWRSZXNwb25zZSgpOworCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZXgpIHsKKwkgICAgLy8gY29udmVydCB0aGlzIGludG8gYSBCWUUgcmVzcG9uc2UKKwkgICAgciA9IFJlc3BvbnNlLmJ5ZVJlc3BvbnNlKGlvZXgpOworCX0gY2F0Y2ggKFByb3RvY29sRXhjZXB0aW9uIHBleCkgeworCSAgICAvLyBjb252ZXJ0IHRoaXMgaW50byBhIEJZRSByZXNwb25zZQorCSAgICByID0gUmVzcG9uc2UuYnllUmVzcG9uc2UocGV4KTsKKwl9CisJcmV0dXJuIHI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJvY2VzcyBhIHJlc3BvbnNlIHJldHVybmVkIGJ5IHJlYWRJZGxlUmVzcG9uc2UoKS4KKyAgICAgKiBUaGlzIG1ldGhvZCB3aWxsIGJlIGNhbGxlZCB3aXRoIGFwcHJvcHJpYXRlIGxvY2tzCisgICAgICogaGVsZCBzbyB0aGF0IHRoZSBwcm9jZXNzaW5nIG9mIHRoZSByZXNwb25zZSBpcyBzYWZlLgorICAgICAqCisgICAgICogQHBhcmFtCXIJdGhlIHJlc3BvbnNlCisgICAgICogQHJldHVybgkJdHJ1ZSBpZiBJRExFIGlzIGRvbmUKKyAgICAgKiBAZXhjZXB0aW9uCVByb3RvY29sRXhjZXB0aW9uCWZvciBwcm90b2NvbCBmYWlsdXJlcworICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjQuMQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHByb2Nlc3NJZGxlUmVzcG9uc2UoUmVzcG9uc2UgcikgdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKwlSZXNwb25zZVtdIHJlc3BvbnNlcyA9IG5ldyBSZXNwb25zZVsxXTsKKwlyZXNwb25zZXNbMF0gPSByOworCWJvb2xlYW4gZG9uZSA9IGZhbHNlOwkJLy8gZG9uZSByZWFkaW5nIHJlc3BvbnNlcz8KKwlub3RpZnlSZXNwb25zZUhhbmRsZXJzKHJlc3BvbnNlcyk7CisKKwlpZiAoci5pc0JZRSgpKSAvLyBzaG91bGRuJ3Qgd2FpdCBmb3IgY29tbWFuZCBjb21wbGV0aW9uIHJlc3BvbnNlCisJICAgIGRvbmUgPSB0cnVlOworCisJLy8gSWYgdGhpcyBpcyBhIG1hdGNoaW5nIGNvbW1hbmQgY29tcGxldGlvbiByZXNwb25zZSwgd2UgYXJlIGRvbmUKKwlpZiAoci5pc1RhZ2dlZCgpICYmIHIuZ2V0VGFnKCkuZXF1YWxzKGlkbGVUYWcpKQorCSAgICBkb25lID0gdHJ1ZTsKKworCWlmIChkb25lKQorCSAgICBpZGxlVGFnID0gbnVsbDsJLy8gbm8gbG9uZ2VyIGluIElETEUKKworCWhhbmRsZVJlc3VsdChyKTsKKwlyZXR1cm4gIWRvbmU7CisgICAgfQorCisgICAgLy8gdGhlIERPTkUgY29tbWFuZCB0byBicmVhayBvdXQgb2YgSURMRQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBET05FID0geyAnRCcsICdPJywgJ04nLCAnRScsICdccicsICdcbicgfTsKKworICAgIC8qKgorICAgICAqIEFib3J0IGFuIElETEUgY29tbWFuZC4gIFdoaWxlIG9uZSB0aHJlYWQgaXMgYmxvY2tlZCBpbgorICAgICAqIHJlYWRJZGxlUmVzcG9uc2UoKSwgYW5vdGhlciB0aHJlYWQgd2lsbCB1c2UgdGhpcyBtZXRob2QKKyAgICAgKiB0byBhYm9ydCB0aGUgSURMRSBjb21tYW5kLCB3aGljaCB3aWxsIGNhdXNlIHRoZSBzZXJ2ZXIKKyAgICAgKiB0byBzZW5kIHRoZSBjbG9zaW5nIHRhZyBmb3IgdGhlIElETEUgY29tbWFuZCwgd2hpY2gKKyAgICAgKiByZWFkSWRsZVJlc3BvbnNlKCkgYW5kIHByb2Nlc3NJZGxlUmVzcG9uc2UoKSB3aWxsIHNlZQorICAgICAqIGFuZCB0ZXJtaW5hdGUgdGhlIElETEUgc3RhdGUuCisgICAgICoKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS40LjEKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBpZGxlQWJvcnQoKSB7CisJT3V0cHV0U3RyZWFtIG9zID0gZ2V0T3V0cHV0U3RyZWFtKCk7CisJdHJ5IHsKKwkgICAgb3Mud3JpdGUoRE9ORSk7CisJICAgIG9zLmZsdXNoKCk7CisJfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJICAgIC8vIG5vdGhpbmcgdG8gZG8sIGhvcGUgdG8gZGV0ZWN0IGl0IGFnYWluIGxhdGVyCisJICAgIGxvZ2dlci5sb2coTGV2ZWwuRklORVNULCAiRXhjZXB0aW9uIGFib3J0aW5nIElETEUiLCBleCk7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIElEIENvbW1hbmQuCisgICAgICoKKyAgICAgKiBAcGFyYW0JY2xpZW50UGFyYW1zCW1hcCBvZiBuYW1lcyBhbmQgdmFsdWVzCisgICAgICogQHJldHVybgkJCW1hcCBvZiBuYW1lcyBhbmQgdmFsdWVzIGZyb20gc2VydmVyCisgICAgICogQGV4Y2VwdGlvbglQcm90b2NvbEV4Y2VwdGlvbglmb3IgcHJvdG9jb2wgZmFpbHVyZXMKKyAgICAgKiBAc2VlICJSRkMgMjk3MSIKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS41LjEKKyAgICAgKi8KKyAgICBwdWJsaWMgTWFwPFN0cmluZywgU3RyaW5nPiBpZChNYXA8U3RyaW5nLCBTdHJpbmc+IGNsaWVudFBhcmFtcykKKwkJCQl0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCWlmICghaGFzQ2FwYWJpbGl0eSgiSUQiKSkgCisJICAgIHRocm93IG5ldyBCYWRDb21tYW5kRXhjZXB0aW9uKCJJRCBub3Qgc3VwcG9ydGVkIik7CisKKwlSZXNwb25zZVtdIHIgPSBjb21tYW5kKCJJRCIsIElELmdldEFyZ3VtZW50TGlzdChjbGllbnRQYXJhbXMpKTsKKworCUlEIGlkID0gbnVsbDsKKwlSZXNwb25zZSByZXNwb25zZSA9IHJbci5sZW5ndGgtMV07CisKKwkvLyBHcmFiIElEIHJlc3BvbnNlCisJaWYgKHJlc3BvbnNlLmlzT0soKSkgeyAvLyBjb21tYW5kIHN1Y2Nlc2Z1bCAKKwkgICAgZm9yIChpbnQgaSA9IDAsIGxlbiA9IHIubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHsKKwkJaWYgKCEocltpXSBpbnN0YW5jZW9mIElNQVBSZXNwb25zZSkpCisJCSAgICBjb250aW51ZTsKKworCQlJTUFQUmVzcG9uc2UgaXIgPSAoSU1BUFJlc3BvbnNlKXJbaV07CisJCWlmIChpci5rZXlFcXVhbHMoIklEIikpIHsKKwkJICAgIGlmIChpZCA9PSBudWxsKQorCQkJaWQgPSBuZXcgSUQoaXIpOworCQkgICAgcltpXSA9IG51bGw7CisJCX0KKwkgICAgfQorCX0KKworCS8vIGRpc3BhdGNoIHJlbWFpbmluZyB1bnRhZ2dlZCByZXNwb25zZXMKKwlub3RpZnlSZXNwb25zZUhhbmRsZXJzKHIpOworCWhhbmRsZVJlc3VsdChyZXNwb25zZSk7CisJcmV0dXJuIGlkID09IG51bGwgPyBudWxsIDogaWQuZ2V0U2VydmVyUGFyYW1zKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL3Byb3RvY29sL0lNQVBSZWZlcnJhbEV4Y2VwdGlvbi5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL3Byb3RvY29sL0lNQVBSZWZlcnJhbEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgyZjFlYTMKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvcHJvdG9jb2wvSU1BUFJlZmVycmFsRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw1MyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuaW1hcC5wcm90b2NvbDsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC5pYXAuUHJvdG9jb2xFeGNlcHRpb247CisKKy8qKgorICogQSBQcm90b2NvbEV4Y2VwdGlvbiB0aGF0IGluY2x1ZGVzIElNQVAgbG9naW4gcmVmZXJyYWwgaW5mb3JtYXRpb24uCisgKgorICogQHNpbmNlIEphdmFNYWlsIDEuNS41CisgKi8KKworcHVibGljIGNsYXNzIElNQVBSZWZlcnJhbEV4Y2VwdGlvbiBleHRlbmRzIFByb3RvY29sRXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgU3RyaW5nIHVybDsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDI1Nzg3NzA2NjkzNjQyNTE5NjhMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhbiBJTUFQUmVmZXJyYWxFeGNlcHRpb24gd2l0aCB0aGUgc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlLgorICAgICAqIGFuZCBVUkwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcwkJdGhlIGRldGFpbCBtZXNzYWdlCisgICAgICogQHBhcmFtIHVybAl0aGUgVVJMCisgICAgICovCisgICAgcHVibGljIElNQVBSZWZlcnJhbEV4Y2VwdGlvbihTdHJpbmcgcywgU3RyaW5nIHVybCkgeworCXN1cGVyKHMpOworCXRoaXMudXJsID0gdXJsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgSU1BUCBVUkwgaW4gdGhlIHJlZmVycmFsLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgSU1BUCBVUkwKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFVybCgpIHsKKwlyZXR1cm4gdXJsOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9JTUFQUmVzcG9uc2UuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9JTUFQUmVzcG9uc2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ZTZiZTRlCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL3Byb3RvY29sL0lNQVBSZXNwb25zZS5qYXZhCkBAIC0wLDAgKzEsMTQwIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5pbWFwLnByb3RvY29sOworCitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmEudXRpbC4qOworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLkFTQ0lJVXRpbGl0eTsKK2ltcG9ydCBjb20uc3VuLm1haWwuaWFwLio7CisKKy8qKgorICogVGhpcyBjbGFzcyByZXByZXNlbnRzIGEgcmVzcG9uc2Ugb2J0YWluZWQgZnJvbSB0aGUgaW5wdXQgc3RyZWFtCisgKiBvZiBhbiBJTUFQIHNlcnZlci4KKyAqCisgKiBAYXV0aG9yICBKb2huIE1hbmkKKyAqLworCitwdWJsaWMgY2xhc3MgSU1BUFJlc3BvbnNlIGV4dGVuZHMgUmVzcG9uc2UgeworICAgIHByaXZhdGUgU3RyaW5nIGtleTsKKyAgICBwcml2YXRlIGludCBudW1iZXI7CisKKyAgICBwdWJsaWMgSU1BUFJlc3BvbnNlKFByb3RvY29sIGMpIHRocm93cyBJT0V4Y2VwdGlvbiwgUHJvdG9jb2xFeGNlcHRpb24geworCXN1cGVyKGMpOworCWluaXQoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgaW5pdCgpIHRocm93cyBJT0V4Y2VwdGlvbiwgUHJvdG9jb2xFeGNlcHRpb24geworCS8vIGNvbnRpbnVlIHBhcnNpbmcgaWYgdGhpcyBpcyBhbiB1bnRhZ2dlZCByZXNwb25zZQorCWlmIChpc1VuVGFnZ2VkKCkgJiYgIWlzT0soKSAmJiAhaXNOTygpICYmICFpc0JBRCgpICYmICFpc0JZRSgpKSB7CisJICAgIGtleSA9IHJlYWRBdG9tKCk7CisKKwkgICAgLy8gSXMgdGhpcyByZXNwb25zZSBvZiB0aGUgZm9ybSAiKiA8bnVtYmVyPiA8Y29tbWFuZD4iCisJICAgIHRyeSB7CisJCW51bWJlciA9IEludGVnZXIucGFyc2VJbnQoa2V5KTsKKwkJa2V5ID0gcmVhZEF0b20oKTsKKwkgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIG5lKSB7IH0KKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29weSBjb25zdHJ1Y3Rvci4KKyAgICAgKgorICAgICAqIEBwYXJhbQlyCXRoZSBJTUFQUmVzcG9uc2UgdG8gY29weQorICAgICAqLworICAgIHB1YmxpYyBJTUFQUmVzcG9uc2UoSU1BUFJlc3BvbnNlIHIpIHsKKwlzdXBlcigoUmVzcG9uc2Upcik7CisJa2V5ID0gci5rZXk7CisJbnVtYmVyID0gci5udW1iZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogRm9yIHRlc3RpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jcgl0aGUgcmVzcG9uc2Ugc3RyaW5nCisgICAgICogQGV4Y2VwdGlvbglJT0V4Y2VwdGlvbglmb3IgSS9PIGVycm9ycworICAgICAqIEBleGNlcHRpb24JUHJvdG9jb2xFeGNlcHRpb24JZm9yIHByb3RvY29sIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIElNQVBSZXNwb25zZShTdHJpbmcgcikgdGhyb3dzIElPRXhjZXB0aW9uLCBQcm90b2NvbEV4Y2VwdGlvbiB7CisJdGhpcyhyLCB0cnVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGb3IgdGVzdGluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbQlyCXRoZSByZXNwb25zZSBzdHJpbmcKKyAgICAgKiBAcGFyYW0JdXRmOAlVVEYtOCBhbGxvd2VkPworICAgICAqIEBleGNlcHRpb24JSU9FeGNlcHRpb24JZm9yIEkvTyBlcnJvcnMKKyAgICAgKiBAZXhjZXB0aW9uCVByb3RvY29sRXhjZXB0aW9uCWZvciBwcm90b2NvbCBmYWlsdXJlcworICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjYuMAorICAgICAqLworICAgIHB1YmxpYyBJTUFQUmVzcG9uc2UoU3RyaW5nIHIsIGJvb2xlYW4gdXRmOCkKKwkJCQl0aHJvd3MgSU9FeGNlcHRpb24sIFByb3RvY29sRXhjZXB0aW9uIHsKKwlzdXBlcihyLCB1dGY4KTsKKwlpbml0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZCBhIGxpc3Qgb2Ygc3BhY2Utc2VwYXJhdGVkICJmbGFnLWV4dGVuc2lvbiIgc2VxdWVuY2VzIGFuZCAKKyAgICAgKiByZXR1cm4gdGhlIGxpc3QgYXMgYSBhcnJheSBvZiBTdHJpbmdzLiBBbiBlbXB0eSBsaXN0IGlzIHJldHVybmVkCisgICAgICogYXMgbnVsbC4gIEVhY2ggaXRlbSBpcyBleHBlY3RlZCB0byBiZSBhbiBhdG9tLCBwb3NzaWJseSBwcmVjZWVkZWQKKyAgICAgKiBieSBhIGJhY2tzbGFzaCwgYnV0IHdlIGFyZW4ndCB0aGF0IHN0cmljdDsgd2UganVzdCBsb29rIGZvciBzdHJpbmdzCisgICAgICogc2VwYXJhdGVkIGJ5IHNwYWNlcyBhbmQgdGVybWluYXRlZCBieSBhIHJpZ2h0IHBhcmVuLiAgV2UgYXNzdW1lIGl0ZW1zCisgICAgICogYXJlIGFsd2F5cyBBU0NJSS4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIGxpc3QgaXRlbXMgYXMgYSBTdHJpbmcgYXJyYXkKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nW10gcmVhZFNpbXBsZUxpc3QoKSB7CisJc2tpcFNwYWNlcygpOworCisJaWYgKGJ1ZmZlcltpbmRleF0gIT0gJygnKSAvLyBub3Qgd2hhdCB3ZSBleHBlY3RlZAorCSAgICByZXR1cm4gbnVsbDsKKwlpbmRleCsrOyAvLyBza2lwICcoJworCisJTGlzdDxTdHJpbmc+IHYgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKwlpbnQgc3RhcnQ7CisJZm9yIChzdGFydCA9IGluZGV4OyBidWZmZXJbaW5kZXhdICE9ICcpJzsgaW5kZXgrKykgeworCSAgICBpZiAoYnVmZmVyW2luZGV4XSA9PSAnICcpIHsgLy8gZ290IG9uZSBpdGVtCisJCXYuYWRkKEFTQ0lJVXRpbGl0eS50b1N0cmluZyhidWZmZXIsIHN0YXJ0LCBpbmRleCkpOworCQlzdGFydCA9IGluZGV4KzE7IC8vIGluZGV4IGdldHMgaW5jcmVtZW50ZWQgYXQgdGhlIHRvcAorCSAgICB9CisJfQorCWlmIChpbmRleCA+IHN0YXJ0KSAvLyBnZXQgdGhlIGxhc3QgaXRlbQorCSAgICB2LmFkZChBU0NJSVV0aWxpdHkudG9TdHJpbmcoYnVmZmVyLCBzdGFydCwgaW5kZXgpKTsKKwlpbmRleCsrOyAvLyBza2lwICcpJworCQorCWludCBzaXplID0gdi5zaXplKCk7CisJaWYgKHNpemUgPiAwKQorCSAgICByZXR1cm4gdi50b0FycmF5KG5ldyBTdHJpbmdbc2l6ZV0pOworCWVsc2UgIC8vIGVtcHR5IGxpc3QKKwkgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRLZXkoKSB7CisJcmV0dXJuIGtleTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBrZXlFcXVhbHMoU3RyaW5nIGspIHsKKwlpZiAoa2V5ICE9IG51bGwgJiYga2V5LmVxdWFsc0lnbm9yZUNhc2UoaykpCisJICAgIHJldHVybiB0cnVlOworCWVsc2UKKwkgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0TnVtYmVyKCkgeworCXJldHVybiBudW1iZXI7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL3Byb3RvY29sL0lNQVBTYXNsQXV0aGVudGljYXRvci5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL3Byb3RvY29sL0lNQVBTYXNsQXV0aGVudGljYXRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ0MTg3ZTAKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvcHJvdG9jb2wvSU1BUFNhc2xBdXRoZW50aWNhdG9yLmphdmEKQEAgLTAsMCArMSwyODQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmltYXAucHJvdG9jb2w7CisKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YS51dGlsLio7CitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTGV2ZWw7CitpbXBvcnQgamF2YXguc2VjdXJpdHkuc2FzbC4qOworaW1wb3J0IGphdmF4LnNlY3VyaXR5LmF1dGguY2FsbGJhY2suKjsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC5pYXAuKjsKK2ltcG9ydCBjb20uc3VuLm1haWwuaW1hcC4qOworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLlByb3BVdGlsOworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLk1haWxMb2dnZXI7CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuQVNDSUlVdGlsaXR5OworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLkJBU0U2NEVuY29kZXJTdHJlYW07CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuQkFTRTY0RGVjb2RlclN0cmVhbTsKKworLyoqCisgKiBUaGlzIGNsYXNzIGNvbnRhaW5zIGEgc2luZ2xlIG1ldGhvZCB0aGF0IGRvZXMgYXV0aGVudGljYXRpb24gdXNpbmcKKyAqIFNBU0wuICBUaGlzIGlzIGluIGEgc2VwYXJhdGUgY2xhc3Mgc28gdGhhdCBpdCBjYW4gYmUgY29tcGlsZWQgd2l0aAorICogSjJTRSAxLjUuICBFdmVudHVhbGx5IGl0IHNob3VsZCBiZSBtZXJnZWQgaW50byBJTUFQUHJvdG9jb2wuamF2YS4KKyAqLworCitwdWJsaWMgY2xhc3MgSU1BUFNhc2xBdXRoZW50aWNhdG9yIGltcGxlbWVudHMgU2FzbEF1dGhlbnRpY2F0b3IgeworCisgICAgcHJpdmF0ZSBJTUFQUHJvdG9jb2wgcHI7CisgICAgcHJpdmF0ZSBTdHJpbmcgbmFtZTsKKyAgICBwcml2YXRlIFByb3BlcnRpZXMgcHJvcHM7CisgICAgcHJpdmF0ZSBNYWlsTG9nZ2VyIGxvZ2dlcjsKKyAgICBwcml2YXRlIFN0cmluZyBob3N0OworCisgICAgLyoKKyAgICAgKiBUaGlzIGlzIGEgaGFjayB0byBpbml0aWFsaXplIHRoZSBPQVVUSCBTQVNMIHByb3ZpZGVyIGp1c3QgYmVmb3JlLAorICAgICAqIGFuZCBvbmx5IGlmLCB3ZSBtaWdodCBuZWVkIGl0LiAgVGhpcyBhdm9pZHMgdGhlIG5lZWQgZm9yIHRoZSB1c2VyIAorICAgICAqIHRvIGluaXRpYWxpemUgaXQgZXhwbGljaXRseSwgb3IgbWFudWFsbHkgY29uZmlndXJlIHRoZSBzZWN1cml0eQorICAgICAqIHByb3ZpZGVycyBmaWxlLgorICAgICAqLworICAgIHN0YXRpYyB7CisJdHJ5IHsKKwkgICAgY29tLnN1bi5tYWlsLmF1dGguT0F1dGgyU2FzbENsaWVudEZhY3RvcnkuaW5pdCgpOworCX0gY2F0Y2ggKFRocm93YWJsZSB0KSB7IH0KKyAgICB9CisKKyAgICBwdWJsaWMgSU1BUFNhc2xBdXRoZW50aWNhdG9yKElNQVBQcm90b2NvbCBwciwgU3RyaW5nIG5hbWUsIFByb3BlcnRpZXMgcHJvcHMsCisJCQkJTWFpbExvZ2dlciBsb2dnZXIsIFN0cmluZyBob3N0KSB7CisJdGhpcy5wciA9IHByOworCXRoaXMubmFtZSA9IG5hbWU7CisJdGhpcy5wcm9wcyA9IHByb3BzOworCXRoaXMubG9nZ2VyID0gbG9nZ2VyOworCXRoaXMuaG9zdCA9IGhvc3Q7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gYXV0aGVudGljYXRlKFN0cmluZ1tdIG1lY2hzLCBmaW5hbCBTdHJpbmcgcmVhbG0sCisJCQkJZmluYWwgU3RyaW5nIGF1dGh6aWQsIGZpbmFsIFN0cmluZyB1LAorCQkJCWZpbmFsIFN0cmluZyBwKSB0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb24geworCisJc3luY2hyb25pemVkIChwcikgewkvLyBhdXRoZW50aWNhdGUgbWV0aG9kIHNob3VsZCBiZSBzeW5jaHJvbml6ZWQKKwlMaXN0PFJlc3BvbnNlPiB2ID0gbmV3IEFycmF5TGlzdDw+KCk7CisJU3RyaW5nIHRhZyA9IG51bGw7CisJUmVzcG9uc2UgciA9IG51bGw7CisJYm9vbGVhbiBkb25lID0gZmFsc2U7CisJaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkUpKSB7CisJICAgIGxvZ2dlci5maW5lKCJTQVNMIE1lY2hhbmlzbXM6Iik7CisJICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVjaHMubGVuZ3RoOyBpKyspCisJCWxvZ2dlci5maW5lKCIgIiArIG1lY2hzW2ldKTsKKwkgICAgbG9nZ2VyLmZpbmUoIiIpOworCX0KKworCVNhc2xDbGllbnQgc2M7CisJQ2FsbGJhY2tIYW5kbGVyIGNiaCA9IG5ldyBDYWxsYmFja0hhbmRsZXIoKSB7CisJCUBPdmVycmlkZQorCSAgICBwdWJsaWMgdm9pZCBoYW5kbGUoQ2FsbGJhY2tbXSBjYWxsYmFja3MpIHsKKwkJaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkUpKQorCQkgICAgbG9nZ2VyLmZpbmUoIlNBU0wgY2FsbGJhY2sgbGVuZ3RoOiAiICsgY2FsbGJhY2tzLmxlbmd0aCk7CisJCWZvciAoaW50IGkgPSAwOyBpIDwgY2FsbGJhY2tzLmxlbmd0aDsgaSsrKSB7CisJCSAgICBpZiAobG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuRklORSkpCisJCQlsb2dnZXIuZmluZSgiU0FTTCBjYWxsYmFjayAiICsgaSArICI6ICIgKyBjYWxsYmFja3NbaV0pOworCQkgICAgaWYgKGNhbGxiYWNrc1tpXSBpbnN0YW5jZW9mIE5hbWVDYWxsYmFjaykgeworCQkJTmFtZUNhbGxiYWNrIG5jYiA9IChOYW1lQ2FsbGJhY2spY2FsbGJhY2tzW2ldOworCQkJbmNiLnNldE5hbWUodSk7CisJCSAgICB9IGVsc2UgaWYgKGNhbGxiYWNrc1tpXSBpbnN0YW5jZW9mIFBhc3N3b3JkQ2FsbGJhY2spIHsKKwkJCVBhc3N3b3JkQ2FsbGJhY2sgcGNiID0gKFBhc3N3b3JkQ2FsbGJhY2spY2FsbGJhY2tzW2ldOworCQkJcGNiLnNldFBhc3N3b3JkKHAudG9DaGFyQXJyYXkoKSk7CisJCSAgICB9IGVsc2UgaWYgKGNhbGxiYWNrc1tpXSBpbnN0YW5jZW9mIFJlYWxtQ2FsbGJhY2spIHsKKwkJCVJlYWxtQ2FsbGJhY2sgcmNiID0gKFJlYWxtQ2FsbGJhY2spY2FsbGJhY2tzW2ldOworCQkJcmNiLnNldFRleHQocmVhbG0gIT0gbnVsbCA/CisJCQkJICAgIHJlYWxtIDogcmNiLmdldERlZmF1bHRUZXh0KCkpOworCQkgICAgfSBlbHNlIGlmIChjYWxsYmFja3NbaV0gaW5zdGFuY2VvZiBSZWFsbUNob2ljZUNhbGxiYWNrKSB7CisJCQlSZWFsbUNob2ljZUNhbGxiYWNrIHJjYiA9CisJCQkgICAgKFJlYWxtQ2hvaWNlQ2FsbGJhY2spY2FsbGJhY2tzW2ldOworCQkJaWYgKHJlYWxtID09IG51bGwpCisJCQkgICAgcmNiLnNldFNlbGVjdGVkSW5kZXgocmNiLmdldERlZmF1bHRDaG9pY2UoKSk7CisJCQllbHNlIHsKKwkJCSAgICAvLyBuZWVkIHRvIGZpbmQgc3BlY2lmaWVkIHJlYWxtIGluIGxpc3QKKwkJCSAgICBTdHJpbmdbXSBjaG9pY2VzID0gcmNiLmdldENob2ljZXMoKTsKKwkJCSAgICBmb3IgKGludCBrID0gMDsgayA8IGNob2ljZXMubGVuZ3RoOyBrKyspIHsKKwkJCQlpZiAoY2hvaWNlc1trXS5lcXVhbHMocmVhbG0pKSB7CisJCQkJICAgIHJjYi5zZXRTZWxlY3RlZEluZGV4KGspOworCQkJCSAgICBicmVhazsKKwkJCQl9CisJCQkgICAgfQorCQkJfQorCQkgICAgfQorCQl9CisJICAgIH0KKwl9OworCisJdHJ5IHsKKwkgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisJICAgIE1hcDxTdHJpbmcsID8+IHByb3BzTWFwID0gKE1hcCkgcHJvcHM7CisJICAgIHNjID0gU2FzbC5jcmVhdGVTYXNsQ2xpZW50KG1lY2hzLCBhdXRoemlkLCBuYW1lLCBob3N0LAorCQkJCQlwcm9wc01hcCwgY2JoKTsKKwl9IGNhdGNoIChTYXNsRXhjZXB0aW9uIHNleCkgeworCSAgICBsb2dnZXIubG9nKExldmVsLkZJTkUsICJGYWlsZWQgdG8gY3JlYXRlIFNBU0wgY2xpZW50Iiwgc2V4KTsKKwkgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKHNleC5nZXRNZXNzYWdlKCksIHNleCk7CisJfQorCWlmIChzYyA9PSBudWxsKSB7CisJICAgIGxvZ2dlci5maW5lKCJObyBTQVNMIHN1cHBvcnQiKTsKKwkgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJObyBTQVNMIHN1cHBvcnQiKTsKKwl9CisJaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkUpKQorCSAgICBsb2dnZXIuZmluZSgiU0FTTCBjbGllbnQgIiArIHNjLmdldE1lY2hhbmlzbU5hbWUoKSk7CisKKwl0cnkgeworCSAgICBBcmd1bWVudCBhcmdzID0gbmV3IEFyZ3VtZW50KCk7CisJICAgIGFyZ3Mud3JpdGVBdG9tKHNjLmdldE1lY2hhbmlzbU5hbWUoKSk7CisJICAgIGlmIChwci5oYXNDYXBhYmlsaXR5KCJTQVNMLUlSIikgJiYgc2MuaGFzSW5pdGlhbFJlc3BvbnNlKCkpIHsKKwkJU3RyaW5nIGlyczsKKwkJYnl0ZVtdIGJhID0gc2MuZXZhbHVhdGVDaGFsbGVuZ2UobmV3IGJ5dGVbMF0pOworCQlpZiAoYmEubGVuZ3RoID4gMCkgeworCQkgICAgYmEgPSBCQVNFNjRFbmNvZGVyU3RyZWFtLmVuY29kZShiYSk7CisJCSAgICBpcnMgPSBBU0NJSVV0aWxpdHkudG9TdHJpbmcoYmEsIDAsIGJhLmxlbmd0aCk7CisJCX0gZWxzZQorCQkgICAgaXJzID0gIj0iOworCQlhcmdzLndyaXRlQXRvbShpcnMpOworCSAgICB9CisJICAgIHRhZyA9IHByLndyaXRlQ29tbWFuZCgiQVVUSEVOVElDQVRFIiwgYXJncyk7CisJfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJICAgIGxvZ2dlci5sb2coTGV2ZWwuRklORSwgIlNBU0wgQVVUSEVOVElDQVRFIEV4Y2VwdGlvbiIsIGV4KTsKKwkgICAgcmV0dXJuIGZhbHNlOworCX0KKworCU91dHB1dFN0cmVhbSBvcyA9IHByLmdldElNQVBPdXRwdXRTdHJlYW0oKTsgLy8gc3RyZWFtIHRvIElNQVAgc2VydmVyCisKKwkvKgorCSAqIFdyYXAgYSBCQVNFNjRFbmNvZGVyIGFyb3VuZCBhIEJ5dGVBcnJheU91dHB1dHN0cmVhbQorCSAqIHRvIGNyYWZ0IGI2NCBlbmNvZGVkIHVzZXJuYW1lIGFuZCBwYXNzd29yZCBzdHJpbmdzCisJICoKKwkgKiBOb3RlIHRoYXQgdGhlIGVuY29kZWQgYnl0ZXMgc2hvdWxkIGJlIHNlbnQgImFzLWlzIiB0byB0aGUKKwkgKiBzZXJ2ZXIsICpub3QqIGFzIGxpdGVyYWxzIG9yIHF1b3RlZC1zdHJpbmdzLgorCSAqCisJICogQWxzbyBub3RlIHRoYXQgdW5saWtlIHRoZSBCNjQgZGVmaW5pdGlvbiBpbiBNSU1FLCBDUkxGcyAKKwkgKiBzaG91bGQgKm5vdCogYmUgaW5zZXJ0ZWQgZHVyaW5nIHRoZSBlbmNvZGluZyBwcm9jZXNzLiBTbywgSQorCSAqIHVzZSBJbnRlZ2VyLk1BWF9WQUxVRSAoMHg3ZmZmZmZmZiAoPiAxRykpIGFzIHRoZSBieXRlc1BlckxpbmUsCisJICogd2hpY2ggc2hvdWxkIGJlIHN1ZmZpY2llbnRseSBsYXJnZSAhCisJICovCisKKwlCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworCWJ5dGVbXSBDUkxGID0geyAoYnl0ZSknXHInLCAoYnl0ZSknXG4nfTsKKworCS8vIEhhY2sgZm9yIE5vdmVsbCBHcm91cFdpc2UgWEdXVFJVU1RFREFQUCBhdXRoZW50aWNhdGlvbiBtZWNoYW5pc20KKwkvLyBodHRwOi8vd3d3Lm5vdmVsbC5jb20vZGV2ZWxvcGVyL2RvY3VtZW50YXRpb24vZ3dpbWFwLz8KKwkvLyAgIHBhZ2U9L2RldmVsb3Blci9kb2N1bWVudGF0aW9uL2d3aW1hcC9nd2ltcGVudS9kYXRhL2FsN3RlOWouaHRtbAorCWJvb2xlYW4gaXNYR1dUUlVTVEVEQVBQID0KKwkgICAgc2MuZ2V0TWVjaGFuaXNtTmFtZSgpLmVxdWFscygiWEdXVFJVU1RFREFQUCIpICYmCisJICAgIFByb3BVdGlsLmdldEJvb2xlYW5Qcm9wZXJ0eShwcm9wcywKKwkJIm1haWwuIiArIG5hbWUgKyAiLnNhc2wueGd3dHJ1c3RlZGFwcGhhY2suZW5hYmxlIiwgdHJ1ZSk7CisJd2hpbGUgKCFkb25lKSB7IC8vIGxvb3AgdGlsbCB3ZSBhcmUgZG9uZQorCSAgICB0cnkgeworCQlyID0gcHIucmVhZFJlc3BvbnNlKCk7CisJICAgIAlpZiAoci5pc0NvbnRpbnVhdGlvbigpKSB7CisJCSAgICBieXRlW10gYmEgPSBudWxsOworCQkgICAgaWYgKCFzYy5pc0NvbXBsZXRlKCkpIHsKKwkJCWJhID0gci5yZWFkQnl0ZUFycmF5KCkuZ2V0TmV3Qnl0ZXMoKTsKKwkJCWlmIChiYS5sZW5ndGggPiAwKQorCQkJICAgIGJhID0gQkFTRTY0RGVjb2RlclN0cmVhbS5kZWNvZGUoYmEpOworCQkJaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkUpKQorCQkJICAgIGxvZ2dlci5maW5lKCJTQVNMIGNoYWxsZW5nZTogIiArCisJCQkJQVNDSUlVdGlsaXR5LnRvU3RyaW5nKGJhLCAwLCBiYS5sZW5ndGgpICsgIiA6Iik7CisJCQliYSA9IHNjLmV2YWx1YXRlQ2hhbGxlbmdlKGJhKTsKKwkJICAgIH0KKwkJICAgIGlmIChiYSA9PSBudWxsKSB7CisJCQlsb2dnZXIuZmluZSgiU0FTTCBubyByZXNwb25zZSIpOworCQkJb3Mud3JpdGUoQ1JMRik7IC8vIHdyaXRlIG91dCBlbXB0eSBsaW5lCisJCQlvcy5mbHVzaCgpOyAJLy8gZmx1c2ggdGhlIHN0cmVhbQorCQkJYm9zLnJlc2V0KCk7IAkvLyByZXNldCBidWZmZXIKKwkJICAgIH0gZWxzZSB7CisJCQlpZiAobG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuRklORSkpCisJCQkgICAgbG9nZ2VyLmZpbmUoIlNBU0wgcmVzcG9uc2U6ICIgKworCQkJCUFTQ0lJVXRpbGl0eS50b1N0cmluZyhiYSwgMCwgYmEubGVuZ3RoKSArICIgOiIpOworCQkJYmEgPSBCQVNFNjRFbmNvZGVyU3RyZWFtLmVuY29kZShiYSk7CisJCQlpZiAoaXNYR1dUUlVTVEVEQVBQKQorCQkJICAgIGJvcy53cml0ZShBU0NJSVV0aWxpdHkuZ2V0Qnl0ZXMoIlhHV1RSVVNURURBUFAgIikpOworCQkJYm9zLndyaXRlKGJhKTsKKworCQkJYm9zLndyaXRlKENSTEYpOyAJLy8gQ1JMRiB0ZXJtaW5hdGlvbgorCQkJb3Mud3JpdGUoYm9zLnRvQnl0ZUFycmF5KCkpOyAvLyB3cml0ZSBvdXQgbGluZQorCQkJb3MuZmx1c2goKTsgCS8vIGZsdXNoIHRoZSBzdHJlYW0KKwkJCWJvcy5yZXNldCgpOyAJLy8gcmVzZXQgYnVmZmVyCisJCSAgICB9CisJCX0gZWxzZSBpZiAoci5pc1RhZ2dlZCgpICYmIHIuZ2V0VGFnKCkuZXF1YWxzKHRhZykpCisJCSAgICAvLyBBaCwgb3VyIHRhZ2dlZCByZXNwb25zZQorCQkgICAgZG9uZSA9IHRydWU7CisJCWVsc2UgaWYgKHIuaXNCWUUoKSkgLy8gb3V0dGEgaGVyZQorCQkgICAgZG9uZSA9IHRydWU7CisJCWVsc2UgLy8gaG1tIC4uIHVuc29saWNpdGVkIHJlc3BvbnNlIGhlcmUgPyEKKwkJICAgIHYuYWRkKHIpOworCSAgICB9IGNhdGNoIChFeGNlcHRpb24gaW9leCkgeworCQlsb2dnZXIubG9nKExldmVsLkZJTkUsICJTQVNMIEV4Y2VwdGlvbiIsIGlvZXgpOworCQkvLyBjb252ZXJ0IHRoaXMgaW50byBhIEJZRSByZXNwb25zZQorCQlyID0gUmVzcG9uc2UuYnllUmVzcG9uc2UoaW9leCk7CisJCWRvbmUgPSB0cnVlOworCQkvLyBYWFggLSB1bHRpbWF0ZWx5IHJldHVybiB0cnVlPz8/CisJICAgIH0KKwl9CisKKwlpZiAoc2MuaXNDb21wbGV0ZSgpIC8qJiYgcmVzLnN0YXR1cyA9PSBTVUNDRVNTKi8pIHsKKwkgICAgU3RyaW5nIHFvcCA9IChTdHJpbmcpc2MuZ2V0TmVnb3RpYXRlZFByb3BlcnR5KFNhc2wuUU9QKTsKKwkgICAgaWYgKHFvcCAhPSBudWxsICYmIChxb3AuZXF1YWxzSWdub3JlQ2FzZSgiYXV0aC1pbnQiKSB8fAorCQkJCXFvcC5lcXVhbHNJZ25vcmVDYXNlKCJhdXRoLWNvbmYiKSkpIHsKKwkJLy8gWFhYIC0gTk9UIFNVUFBPUlRFRCEhIQorCQlsb2dnZXIuZmluZSgKKwkJCSJTQVNMIE1lY2hhbmlzbSByZXF1aXJlcyBpbnRlZ3JpdHkgb3IgY29uZmlkZW50aWFsaXR5Iik7CisJCXJldHVybiBmYWxzZTsKKwkgICAgfQorCX0KKworCVJlc3BvbnNlW10gcmVzcG9uc2VzID0gdi50b0FycmF5KG5ldyBSZXNwb25zZVt2LnNpemUoKV0pOworCisJLy8gaGFuZGxlIGFuIGlsbGVnYWwgYnV0IG5vdCB1bmNvbW1vbiB1bnRhZ2dlZCBDQVBBQklMVFkgcmVzcG9uc2UKKwlwci5oYW5kbGVDYXBhYmlsaXR5UmVzcG9uc2UocmVzcG9uc2VzKTsKKworCS8qCisJICogRGlzcGF0Y2ggdW50YWdnZWQgcmVzcG9uc2VzLgorCSAqIE5PVEU6IGluIG91ciBjdXJyZW50IHVwcGVyIGxldmVsIElNQVAgY2xhc3Nlcywgd2UgYWRkIHRoZQorCSAqIHJlc3BvbnNlSGFuZGxlciB0byB0aGUgUHJvdG9jb2wgb2JqZWN0IG9ubHkgKmFmdGVyKiB0aGUgCisJICogY29ubmVjdGlvbiBoYXMgYmVlbiBhdXRoZW50aWNhdGVkLiBTbywgZm9yIG5vdywgdGhlIGJlbG93CisJICogY29kZSByZWFsbHkgZW5kcyB1cCBiZWluZyBqdXN0IGEgbm8tb3AuCisJICovCisJcHIubm90aWZ5UmVzcG9uc2VIYW5kbGVycyhyZXNwb25zZXMpOworCisJLy8gSGFuZGxlIHRoZSBmaW5hbCBPSywgTk8sIEJBRCBvciBCWUUgcmVzcG9uc2UKKwlwci5oYW5kbGVMb2dpblJlc3VsdChyKTsKKwlwci5zZXRDYXBhYmlsaXRpZXMocik7CisKKwkvKgorCSAqIElmIHdlJ3JlIHVzaW5nIHRoZSBOb3ZlbGwgR3JvdXB3aXNlIFhHV1RSVVNURURBUFAgbWVjaGFuaXNtCisJICogdG8gcnVuIGFzIGEgc3BlY2lmaWVkIGF1dGhvcml6YXRpb24gSUQsIHdlIGhhdmUgdG8gaXNzdWUgYQorCSAqIExPR0lOIGNvbW1hbmQgdG8gc2VsZWN0IHRoZSB1c2VyIHdlIHdhbnQgdG8gb3BlcmF0ZSBhcy4KKwkgKi8KKwlpZiAoaXNYR1dUUlVTVEVEQVBQICYmIGF1dGh6aWQgIT0gbnVsbCkgeworCSAgICBBcmd1bWVudCBhcmdzID0gbmV3IEFyZ3VtZW50KCk7CisJICAgIGFyZ3Mud3JpdGVTdHJpbmcoYXV0aHppZCk7CisKKwkgICAgcmVzcG9uc2VzID0gcHIuY29tbWFuZCgiTE9HSU4iLCBhcmdzKTsKKworCSAgICAvLyBkaXNwYXRjaCB1bnRhZ2dlZCByZXNwb25zZXMKKwkgICAgcHIubm90aWZ5UmVzcG9uc2VIYW5kbGVycyhyZXNwb25zZXMpOworCisJICAgIC8vIEhhbmRsZSByZXN1bHQgb2YgdGhpcyBjb21tYW5kCisJICAgIHByLmhhbmRsZVJlc3VsdChyZXNwb25zZXNbcmVzcG9uc2VzLmxlbmd0aC0xXSk7CisJICAgIC8vIElmIHRoZSByZXNwb25zZSBpbmNsdWRlcyBhIENBUEFCSUxJVFkgcmVzcG9uc2UgY29kZSwgcHJvY2VzcyBpdAorCSAgICBwci5zZXRDYXBhYmlsaXRpZXMocmVzcG9uc2VzW3Jlc3BvbnNlcy5sZW5ndGgtMV0pOworCX0KKwlyZXR1cm4gdHJ1ZTsKKyAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL3Byb3RvY29sL0lOVEVSTkFMREFURS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL3Byb3RvY29sL0lOVEVSTkFMREFURS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdmNDMyZmYKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvcHJvdG9jb2wvSU5URVJOQUxEQVRFLmphdmEKQEAgLTAsMCArMSwxMjggQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmltYXAucHJvdG9jb2w7CisKK2ltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuVGltZVpvbmU7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBqYXZhLnRleHQuUGFyc2VFeGNlcHRpb247CitpbXBvcnQgamF2YS50ZXh0LlNpbXBsZURhdGVGb3JtYXQ7CitpbXBvcnQgamF2YS50ZXh0LkZpZWxkUG9zaXRpb247CisKK2ltcG9ydCBqYXZheC5tYWlsLmludGVybmV0Lk1haWxEYXRlRm9ybWF0OworCitpbXBvcnQgY29tLnN1bi5tYWlsLmlhcC4qOyAKKworCisvKioKKyAqIEFuIElOVEVSTkFMREFURSBGRVRDSCBpdGVtLgorICoKKyAqIEBhdXRob3IgIEpvaG4gTWFuaQorICovCisKK3B1YmxpYyBjbGFzcyBJTlRFUk5BTERBVEUgaW1wbGVtZW50cyBJdGVtIHsKKworICAgIHN0YXRpYyBmaW5hbCBjaGFyW10gbmFtZSA9CisJeydJJywnTicsJ1QnLCdFJywnUicsJ04nLCdBJywnTCcsJ0QnLCdBJywnVCcsJ0UnfTsKKyAgICBwdWJsaWMgaW50IG1zZ25vOworICAgIHByb3RlY3RlZCBEYXRlIGRhdGU7CisKKyAgICAvKgorICAgICAqIFVzZWQgdG8gcGFyc2UgZGF0ZXMgb25seS4gIFRoZSBwYXJzZSBtZXRob2QgaXMgdGhyZWFkIHNhZmUKKyAgICAgKiBzbyB3ZSBvbmx5IG5lZWQgdG8gY3JlYXRlIGEgc2luZ2xlIG9iamVjdCBmb3IgdXNlIGJ5IGFsbAorICAgICAqIGluc3RhbmNlcy4gIFdlIGRlcGVuZCBvbiB0aGUgZmFjdCB0aGF0IHRoZSBNYWlsRGF0ZUZvcm1hdAorICAgICAqIGNsYXNzIHdpbGwgcGFyc2UgZGF0ZXMgaW4gSU5URVJOQUxEQVRFIGZvcm1hdCBhcyB3ZWxsIGFzCisgICAgICogZGF0ZXMgaW4gUkZDIDgyMiBmb3JtYXQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTWFpbERhdGVGb3JtYXQgbWFpbERhdGVGb3JtYXQgPSBuZXcgTWFpbERhdGVGb3JtYXQoKTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yLgorICAgICAqCisgICAgICogQHBhcmFtCXIJdGhlIEZldGNoUmVzcG9uc2UKKyAgICAgKiBAZXhjZXB0aW9uCVBhcnNpbmdFeGNlcHRpb24JZm9yIHBhcnNpbmcgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgSU5URVJOQUxEQVRFKEZldGNoUmVzcG9uc2UgcikgdGhyb3dzIFBhcnNpbmdFeGNlcHRpb24geworCW1zZ25vID0gci5nZXROdW1iZXIoKTsKKwlyLnNraXBTcGFjZXMoKTsKKwlTdHJpbmcgcyA9IHIucmVhZFN0cmluZygpOworCWlmIChzID09IG51bGwpCisJICAgIHRocm93IG5ldyBQYXJzaW5nRXhjZXB0aW9uKCJJTlRFUk5BTERBVEUgaXMgTklMIik7CisJdHJ5IHsKKyAgICAgICAgc3luY2hyb25pemVkIChtYWlsRGF0ZUZvcm1hdCkgeworICAgICAgICAgICAgZGF0ZSA9IG1haWxEYXRlRm9ybWF0LnBhcnNlKHMpOworICAgICAgICB9CisJfSBjYXRjaCAoUGFyc2VFeGNlcHRpb24gcGV4KSB7CisJICAgIHRocm93IG5ldyBQYXJzaW5nRXhjZXB0aW9uKCJJTlRFUk5BTERBVEUgcGFyc2UgZXJyb3IiKTsKKwl9CisgICAgfQorCisgICAgcHVibGljIERhdGUgZ2V0RGF0ZSgpIHsKKwlyZXR1cm4gZGF0ZTsKKyAgICB9CisKKyAgICAvLyBJTlRFUk5BTERBVEUgZm9ybWF0dGVyCisKKyAgICBwcml2YXRlIHN0YXRpYyBTaW1wbGVEYXRlRm9ybWF0IGRmID0gCisJLy8gTmVlZCBMb2NhbGUuVVMsIHRoZSAiTU1NIiBmaWVsZCBjYW4gcHJvZHVjZSB1bmV4cGVjdGVkIHZhbHVlcworCS8vIGluIG5vbiBVUyBsb2NhbGVzICEKKwluZXcgU2ltcGxlRGF0ZUZvcm1hdCgiZGQtTU1NLXl5eXkgSEg6bW06c3MgIiwgTG9jYWxlLlVTKTsKKworICAgIC8qKgorICAgICAqIEZvcm1hdCBnaXZlbiBEYXRlIG9iamVjdCBpbnRvIElOVEVSTkFMREFURSBzdHJpbmcKKyAgICAgKgorICAgICAqIEBwYXJhbQlkCXRoZSBEYXRlCisgICAgICogQHJldHVybgkJSU5URVJOQUxEQVRFIHN0cmluZworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGZvcm1hdChEYXRlIGQpIHsKKwkvKgorCSAqIFNpbXBsZURhdGVGb3JtYXQgb2JqZWN0cyBhcmVuJ3QgdGhyZWFkIHNhZmUsIHNvIHJhdGhlcgorCSAqIHRoYW4gY3JlYXRlIGEgc2VwYXJhdGUgc3VjaCBvYmplY3QgZm9yIGVhY2ggcmVxdWVzdCwKKwkgKiB3ZSBjcmVhdGUgb25lIG9iamVjdCBhbmQgc3luY2hyb25pemUgaXRzIHVzZSBoZXJlCisJICogc28gdGhhdCBvbmx5IG9uZSB0aHJlYWQgaXMgdXNpbmcgaXQgYXQgYSB0aW1lLiAgVGhpcworCSAqIHRyYWRlcyBvZmYgc29tZSBwb3RlbnRpYWwgY29uY3VycmVuY3kgZm9yIHNwZWVkIGluIHRoZQorCSAqIGNvbW1vbiBjYXNlLgorCSAqCisJICogVGhpcyBtZXRob2QgaXMgb25seSB1c2VkIHdoZW4gZm9ybWF0dGluZyB0aGUgZGF0ZSBpbiBhCisJICogbWVzc2FnZSB0aGF0J3MgYmVpbmcgYXBwZW5kZWQgdG8gYSBmb2xkZXIuCisJICovCisJU3RyaW5nQnVmZmVyIHNiID0gbmV3IFN0cmluZ0J1ZmZlcigpOworCXN5bmNocm9uaXplZCAoZGYpIHsKKwkgICAgZGYuZm9ybWF0KGQsIHNiLCBuZXcgRmllbGRQb3NpdGlvbigwKSk7CisJfQorCisJLy8gY29tcHV0ZSB0aW1lem9uZSBvZmZzZXQgc3RyaW5nCisJVGltZVpvbmUgdHogPSBUaW1lWm9uZS5nZXREZWZhdWx0KCk7CisJaW50IG9mZnNldCA9IHR6LmdldE9mZnNldChkLmdldFRpbWUoKSk7CS8vIGdldCBvZmZzZXQgZnJvbSBHTVQKKwlpbnQgcmF3T2Zmc2V0SW5NaW5zID0gb2Zmc2V0IC8gNjAgLyAxMDAwOyAvLyBvZmZzZXQgZnJvbSBHTVQgaW4gbWlucworCWlmIChyYXdPZmZzZXRJbk1pbnMgPCAwKSB7CisJICAgIHNiLmFwcGVuZCgnLScpOworCSAgICByYXdPZmZzZXRJbk1pbnMgPSAoLXJhd09mZnNldEluTWlucyk7CisJfSBlbHNlCisJICAgIHNiLmFwcGVuZCgnKycpOworCQorCWludCBvZmZzZXRJbkhycyA9IHJhd09mZnNldEluTWlucyAvIDYwOworCWludCBvZmZzZXRJbk1pbnMgPSByYXdPZmZzZXRJbk1pbnMgJSA2MDsKKworCXNiLmFwcGVuZChDaGFyYWN0ZXIuZm9yRGlnaXQoKG9mZnNldEluSHJzLzEwKSwgMTApKTsKKwlzYi5hcHBlbmQoQ2hhcmFjdGVyLmZvckRpZ2l0KChvZmZzZXRJbkhycyUxMCksIDEwKSk7CisJc2IuYXBwZW5kKENoYXJhY3Rlci5mb3JEaWdpdCgob2Zmc2V0SW5NaW5zLzEwKSwgMTApKTsKKwlzYi5hcHBlbmQoQ2hhcmFjdGVyLmZvckRpZ2l0KChvZmZzZXRJbk1pbnMlMTApLCAxMCkpOworCisJcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL3Byb3RvY29sL0l0ZW0uamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9JdGVtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGQ2MDRhYgotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9JdGVtLmphdmEKQEAgLTAsMCArMSwzMCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuaW1hcC5wcm90b2NvbDsKKworLyoqCisgKiBBIHRhZ2dpbmcgaW50ZXJmYWNlIGZvciBhbGwgSU1BUCBkYXRhIGl0ZW1zLgorICogTm90ZSB0aGF0IHRoZSAibmFtZSIgZmllbGQgb2YgYWxsIElNQVAgaXRlbXMgTVVTVCBiZSBpbiB1cHBlcmNhc2UuIDxwPgorICoKKyAqIFNlZSB0aGUgQk9EWSwgQk9EWVNUUlVDVFVSRSwgRU5WRUxPUEUsIEZMQUdTLCBJTlRFUk5BTERBVEUsIFJGQzgyMkRBVEEsCisgKiBSRkM4MjJTSVpFLCBhbmQgVUlEIGNsYXNzZXMuCisgKgorICogQGF1dGhvciAgSm9obiBNYW5pCisgKi8KKworcHVibGljIGludGVyZmFjZSBJdGVtIHsgCit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvcHJvdG9jb2wvTGlzdEluZm8uamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9MaXN0SW5mby5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBkYjFmMDIKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvcHJvdG9jb2wvTGlzdEluZm8uamF2YQpAQCAtMCwwICsxLDc5IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5pbWFwLnByb3RvY29sOworCitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC5pYXAuKjsKKworLyoqCisgKiBBIExJU1QgcmVzcG9uc2UuCisgKgorICogQGF1dGhvciAgSm9obiBNYW5pCisgKiBAYXV0aG9yICBCaWxsIFNoYW5ub24KKyAqLworCitwdWJsaWMgY2xhc3MgTGlzdEluZm8geyAKKyAgICBwdWJsaWMgU3RyaW5nIG5hbWUgPSBudWxsOworICAgIHB1YmxpYyBjaGFyIHNlcGFyYXRvciA9ICcvJzsKKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNJbmZlcmlvcnMgPSB0cnVlOworICAgIHB1YmxpYyBib29sZWFuIGNhbk9wZW4gPSB0cnVlOworICAgIHB1YmxpYyBpbnQgY2hhbmdlU3RhdGUgPSBJTkRFVEVSTUlOQVRFOworICAgIHB1YmxpYyBTdHJpbmdbXSBhdHRyczsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENIQU5HRUQJCT0gMTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVTkNIQU5HRUQJCT0gMjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTkRFVEVSTUlOQVRFCT0gMzsKKworICAgIHB1YmxpYyBMaXN0SW5mbyhJTUFQUmVzcG9uc2UgcikgdGhyb3dzIFBhcnNpbmdFeGNlcHRpb24geworCVN0cmluZ1tdIHMgPSByLnJlYWRTaW1wbGVMaXN0KCk7CisKKwlMaXN0PFN0cmluZz4gdiA9IG5ldyBBcnJheUxpc3Q8PigpOwkvLyBhY2N1bXVsYXRlIGF0dHJpYnV0ZXMKKwlpZiAocyAhPSBudWxsKSB7CisJICAgIC8vIG5vbi1lbXB0eSBhdHRyaWJ1dGUgbGlzdAorCSAgICBmb3IgKGludCBpID0gMDsgaSA8IHMubGVuZ3RoOyBpKyspIHsKKwkJaWYgKHNbaV0uZXF1YWxzSWdub3JlQ2FzZSgiXFxNYXJrZWQiKSkKKwkJICAgIGNoYW5nZVN0YXRlID0gQ0hBTkdFRDsKKwkJZWxzZSBpZiAoc1tpXS5lcXVhbHNJZ25vcmVDYXNlKCJcXFVubWFya2VkIikpCisJCSAgICBjaGFuZ2VTdGF0ZSA9IFVOQ0hBTkdFRDsKKwkJZWxzZSBpZiAoc1tpXS5lcXVhbHNJZ25vcmVDYXNlKCJcXE5vc2VsZWN0IikpCisJCSAgICBjYW5PcGVuID0gZmFsc2U7CisJCWVsc2UgaWYgKHNbaV0uZXF1YWxzSWdub3JlQ2FzZSgiXFxOb2luZmVyaW9ycyIpKQorCQkgICAgaGFzSW5mZXJpb3JzID0gZmFsc2U7CisJCXYuYWRkKHNbaV0pOworCSAgICB9CisJfQorCWF0dHJzID0gdi50b0FycmF5KG5ldyBTdHJpbmdbdi5zaXplKCldKTsKKworCXIuc2tpcFNwYWNlcygpOworCWlmIChyLnJlYWRCeXRlKCkgPT0gJyInKSB7CisJICAgIGlmICgoc2VwYXJhdG9yID0gKGNoYXIpci5yZWFkQnl0ZSgpKSA9PSAnXFwnKQorCQkvLyBlc2NhcGVkIHNlcGFyYXRvciBjaGFyYWN0ZXIKKwkJc2VwYXJhdG9yID0gKGNoYXIpci5yZWFkQnl0ZSgpOwkKKwkgICAgci5za2lwKDEpOyAvLyBza2lwIDwiPgorCX0gZWxzZSAvLyBOSUwKKwkgICAgci5za2lwKDIpOworCQorCXIuc2tpcFNwYWNlcygpOworCW5hbWUgPSByLnJlYWRBdG9tU3RyaW5nKCk7CisKKwlpZiAoIXIuc3VwcG9ydHNVdGY4KCkpCisJICAgIC8vIGRlY29kZSB0aGUgbmFtZSAodXNpbmcgUkZDMjA2MCdzIG1vZGlmaWVkIFVURjcpCisJICAgIG5hbWUgPSBCQVNFNjRNYWlsYm94RGVjb2Rlci5kZWNvZGUobmFtZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL3Byb3RvY29sL01PRFNFUS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL3Byb3RvY29sL01PRFNFUS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY4MDA1NjkKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvcHJvdG9jb2wvTU9EU0VRLmphdmEKQEAgLTAsMCArMSw1MyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuaW1hcC5wcm90b2NvbDsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC5pYXAuKjsgCisKKy8qKgorICogVGhpcyBjbGFzcyByZXByZXNlbnRzIHRoZSBNT0RTRVEgZGF0YSBpdGVtLgorICoKKyAqIEBzaW5jZQlKYXZhTWFpbCAxLjUuMQorICogQGF1dGhvcglCaWxsIFNoYW5ub24KKyAqLworCitwdWJsaWMgY2xhc3MgTU9EU0VRIGltcGxlbWVudHMgSXRlbSB7CisgICAgCisgICAgc3RhdGljIGZpbmFsIGNoYXJbXSBuYW1lID0geydNJywnTycsJ0QnLCdTJywnRScsJ1EnfTsKKyAgICBwdWJsaWMgaW50IHNlcW51bTsKKworICAgIHB1YmxpYyBsb25nIG1vZHNlcTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yLgorICAgICAqCisgICAgICogQHBhcmFtCXIJdGhlIEZldGNoUmVzcG9uc2UKKyAgICAgKiBAZXhjZXB0aW9uCVBhcnNpbmdFeGNlcHRpb24JZm9yIHBhcnNpbmcgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgTU9EU0VRKEZldGNoUmVzcG9uc2UgcikgdGhyb3dzIFBhcnNpbmdFeGNlcHRpb24geworCXNlcW51bSA9IHIuZ2V0TnVtYmVyKCk7CisJci5za2lwU3BhY2VzKCk7CisKKwlpZiAoci5yZWFkQnl0ZSgpICE9ICcoJykKKwkgICAgdGhyb3cgbmV3IFBhcnNpbmdFeGNlcHRpb24oIk1PRFNFUSBwYXJzZSBlcnJvciIpOworCisJbW9kc2VxID0gci5yZWFkTG9uZygpOworCisJaWYgKCFyLmlzTmV4dE5vblNwYWNlKCcpJykpCisJICAgIHRocm93IG5ldyBQYXJzaW5nRXhjZXB0aW9uKCJNT0RTRVEgcGFyc2UgZXJyb3IiKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvcHJvdG9jb2wvTWFpbGJveEluZm8uamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9NYWlsYm94SW5mby5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNjZmYwYjYKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvcHJvdG9jb2wvTWFpbGJveEluZm8uamF2YQpAQCAtMCwwICsxLDE2MyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuaW1hcC5wcm90b2NvbDsKKworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CisKK2ltcG9ydCBqYXZheC5tYWlsLkZsYWdzOworCitpbXBvcnQgY29tLnN1bi5tYWlsLmlhcC4qOworCisvKioKKyAqIEluZm9ybWF0aW9uIGNvbGxlY3RlZCB3aGVuIG9wZW5pbmcgYSBtYWlsYm94LgorICoKKyAqIEBhdXRob3IgIEpvaG4gTWFuaQorICogQGF1dGhvciAgQmlsbCBTaGFubm9uCisgKi8KKworcHVibGljIGNsYXNzIE1haWxib3hJbmZvIHsgCisgICAgLyoqIFRoZSBhdmFpbGFibGUgZmxhZ3MuICovCisgICAgcHVibGljIEZsYWdzIGF2YWlsYWJsZUZsYWdzID0gbnVsbDsKKyAgICAvKiogVGhlIHBlcm1hbmVudCBmbGFncy4gKi8KKyAgICBwdWJsaWMgRmxhZ3MgcGVybWFuZW50RmxhZ3MgPSBudWxsOworICAgIC8qKiBUaGUgdG90YWwgbnVtYmVyIG9mIG1lc3NhZ2VzLiAqLworICAgIHB1YmxpYyBpbnQgdG90YWwgPSAtMTsKKyAgICAvKiogVGhlIG51bWJlciBvZiByZWNlbnQgbWVzc2FnZXMuICovCisgICAgcHVibGljIGludCByZWNlbnQgPSAtMTsKKyAgICAvKiogVGhlIGZpcnN0IHVuc2VlbiBtZXNzYWdlLiAqLworICAgIHB1YmxpYyBpbnQgZmlyc3QgPSAtMTsKKyAgICAvKiogVGhlIFVJRFZBTElESVRZLiAqLworICAgIHB1YmxpYyBsb25nIHVpZHZhbGlkaXR5ID0gLTE7CisgICAgLyoqIFRoZSBuZXh0IFVJRCB2YWx1ZSB0byBiZSBhc3NpZ25lZC4gKi8KKyAgICBwdWJsaWMgbG9uZyB1aWRuZXh0ID0gLTE7CisgICAgLyoqIFVJRHMgYXJlIG5vdCBzdGlja3kuICovCisgICAgcHVibGljIGJvb2xlYW4gdWlkTm90U3RpY2t5ID0gZmFsc2U7CS8vIFJGQyA0MzE1CisgICAgLyoqIFRoZSBoaWdoZXN0IE1PRFNFUSB2YWx1ZS4gKi8KKyAgICBwdWJsaWMgbG9uZyBoaWdoZXN0bW9kc2VxID0gLTE7CS8vIFJGQyA0NTUxIC0gQ09ORFNUT1JFCisgICAgLyoqIEZvbGRlci5SRUFEX1dSSVRFIG9yIEZvbGRlci5SRUFEX09OTFksIHNldCBieSBJTUFQUHJvdG9jb2wuICovCisgICAgcHVibGljIGludCBtb2RlOworICAgIC8qKiBWQU5JU0hFRCBvciBGRVRDSCByZXNwb25zZXMgcmVjZWl2ZWQgd2hpbGUgb3BlbmluZyB0aGUgbWFpbGJveC4gKi8KKyAgICBwdWJsaWMgTGlzdDxJTUFQUmVzcG9uc2U+IHJlc3BvbnNlczsKKworICAgIC8qKgorICAgICAqIENvbGxlY3QgdGhlIGluZm9ybWF0aW9uIGFib3V0IHRoaXMgbWFpbGJveCBmcm9tIHRoZQorICAgICAqIHJlc3BvbnNlcyB0byBhIFNFTEVDVCBvciBFWEFNSU5FLgorICAgICAqCisgICAgICogQHBhcmFtCXIJdGhlIHJlc3BvbnNlcworICAgICAqIEBleGNlcHRpb24JUGFyc2luZ0V4Y2VwdGlvbglmb3IgZXJyb3JzIHBhcnNpbmcgdGhlIHJlc3BvbnNlcworICAgICAqLworICAgIHB1YmxpYyBNYWlsYm94SW5mbyhSZXNwb25zZVtdIHIpIHRocm93cyBQYXJzaW5nRXhjZXB0aW9uIHsKKwlmb3IgKGludCBpID0gMDsgaSA8IHIubGVuZ3RoOyBpKyspIHsKKwkgICAgaWYgKHJbaV0gPT0gbnVsbCB8fCAhKHJbaV0gaW5zdGFuY2VvZiBJTUFQUmVzcG9uc2UpKQorCQljb250aW51ZTsKKworCSAgICBJTUFQUmVzcG9uc2UgaXIgPSAoSU1BUFJlc3BvbnNlKXJbaV07CisKKwkgICAgaWYgKGlyLmtleUVxdWFscygiRVhJU1RTIikpIHsKKwkJdG90YWwgPSBpci5nZXROdW1iZXIoKTsKKwkJcltpXSA9IG51bGw7IC8vIHJlbW92ZSB0aGlzIHJlc3BvbnNlCisJICAgIH0gZWxzZSBpZiAoaXIua2V5RXF1YWxzKCJSRUNFTlQiKSkgeworCQlyZWNlbnQgPSBpci5nZXROdW1iZXIoKTsKKwkJcltpXSA9IG51bGw7IC8vIHJlbW92ZSB0aGlzIHJlc3BvbnNlCisJICAgIH0gZWxzZSBpZiAoaXIua2V5RXF1YWxzKCJGTEFHUyIpKSB7CisJCWF2YWlsYWJsZUZsYWdzID0gbmV3IEZMQUdTKGlyKTsKKwkJcltpXSA9IG51bGw7IC8vIHJlbW92ZSB0aGlzIHJlc3BvbnNlCisJICAgIH0gZWxzZSBpZiAoaXIua2V5RXF1YWxzKCJWQU5JU0hFRCIpKSB7CisJCWlmIChyZXNwb25zZXMgPT0gbnVsbCkKKwkJICAgIHJlc3BvbnNlcyA9IG5ldyBBcnJheUxpc3Q8PigpOworCQlyZXNwb25zZXMuYWRkKGlyKTsKKwkJcltpXSA9IG51bGw7IC8vIHJlbW92ZSB0aGlzIHJlc3BvbnNlCisJICAgIH0gZWxzZSBpZiAoaXIua2V5RXF1YWxzKCJGRVRDSCIpKSB7CisJCWlmIChyZXNwb25zZXMgPT0gbnVsbCkKKwkJICAgIHJlc3BvbnNlcyA9IG5ldyBBcnJheUxpc3Q8PigpOworCQlyZXNwb25zZXMuYWRkKGlyKTsKKwkJcltpXSA9IG51bGw7IC8vIHJlbW92ZSB0aGlzIHJlc3BvbnNlCisJICAgIH0gZWxzZSBpZiAoaXIuaXNVblRhZ2dlZCgpICYmIGlyLmlzT0soKSkgeworCQkvKgorCQkgKiBzaG91bGQgYmUgb25lIG9mOgorCQkgKiAJKiBPSyBbVU5TRUVOIDEyXQorCQkgKiAJKiBPSyBbVUlEVkFMSURJVFkgMzg1NzUyOTA0NV0KKwkJICogCSogT0sgW1BFUk1BTkVOVEZMQUdTIChcRGVsZXRlZCldCisJCSAqIAkqIE9LIFtVSURORVhUIDQ0XQorCQkgKiAJKiBPSyBbSElHSEVTVE1PRFNFUSAxMDNdCisJCSAqLworCQlpci5za2lwU3BhY2VzKCk7CisKKwkJaWYgKGlyLnJlYWRCeXRlKCkgIT0gJ1snKSB7CS8vIGh1aCA/Pz8KKwkJICAgIGlyLnJlc2V0KCk7CisJCSAgICBjb250aW51ZTsKKwkJfQorCisJCWJvb2xlYW4gaGFuZGxlZCA9IHRydWU7CisJCVN0cmluZyBzID0gaXIucmVhZEF0b20oKTsKKwkJaWYgKHMuZXF1YWxzSWdub3JlQ2FzZSgiVU5TRUVOIikpCisJCSAgICBmaXJzdCA9IGlyLnJlYWROdW1iZXIoKTsKKwkJZWxzZSBpZiAocy5lcXVhbHNJZ25vcmVDYXNlKCJVSURWQUxJRElUWSIpKQorCQkgICAgdWlkdmFsaWRpdHkgPSBpci5yZWFkTG9uZygpOworCQllbHNlIGlmIChzLmVxdWFsc0lnbm9yZUNhc2UoIlBFUk1BTkVOVEZMQUdTIikpCisJCSAgICBwZXJtYW5lbnRGbGFncyA9IG5ldyBGTEFHUyhpcik7CisJCWVsc2UgaWYgKHMuZXF1YWxzSWdub3JlQ2FzZSgiVUlETkVYVCIpKQorCQkgICAgdWlkbmV4dCA9IGlyLnJlYWRMb25nKCk7CisJCWVsc2UgaWYgKHMuZXF1YWxzSWdub3JlQ2FzZSgiSElHSEVTVE1PRFNFUSIpKQorCQkgICAgaGlnaGVzdG1vZHNlcSA9IGlyLnJlYWRMb25nKCk7CisJCWVsc2UKKwkJICAgIGhhbmRsZWQgPSBmYWxzZTsJLy8gcG9zc2libHkgYW4gQUxFUlQKKworCQlpZiAoaGFuZGxlZCkKKwkJICAgIHJbaV0gPSBudWxsOyAvLyByZW1vdmUgdGhpcyByZXNwb25zZQorCQllbHNlCisJCSAgICBpci5yZXNldCgpOwkvLyBzbyBBTEVSVCBjYW4gYmUgcmVhZAorCSAgICB9IGVsc2UgaWYgKGlyLmlzVW5UYWdnZWQoKSAmJiBpci5pc05PKCkpIHsKKwkJLyoKKwkJICogc2hvdWxkIGJlIG9uZSBvZjoKKwkJICogCSogTk8gW1VJRE5PVFNUSUNLWV0KKwkJICovCisJCWlyLnNraXBTcGFjZXMoKTsKKworCQlpZiAoaXIucmVhZEJ5dGUoKSAhPSAnWycpIHsJLy8gaHVoID8/PworCQkgICAgaXIucmVzZXQoKTsKKwkJICAgIGNvbnRpbnVlOworCQl9CisKKwkJYm9vbGVhbiBoYW5kbGVkID0gdHJ1ZTsKKwkJU3RyaW5nIHMgPSBpci5yZWFkQXRvbSgpOworCQlpZiAocy5lcXVhbHNJZ25vcmVDYXNlKCJVSUROT1RTVElDS1kiKSkKKwkJICAgIHVpZE5vdFN0aWNreSA9IHRydWU7CisJCWVsc2UKKwkJICAgIGhhbmRsZWQgPSBmYWxzZTsJLy8gcG9zc2libHkgYW4gQUxFUlQKKworCQlpZiAoaGFuZGxlZCkKKwkJICAgIHJbaV0gPSBudWxsOyAvLyByZW1vdmUgdGhpcyByZXNwb25zZQorCQllbHNlCisJCSAgICBpci5yZXNldCgpOwkvLyBzbyBBTEVSVCBjYW4gYmUgcmVhZAorCSAgICB9CisJfQorCisJLyoKKwkgKiBUaGUgUEVSTUFORU5URkxBR1MgcmVzcG9uc2UgY29kZSBpcyBvcHRpb25hbCwgYW5kIGlmCisJICogbm90IHByZXNlbnQgaW1wbGllcyB0aGF0IGFsbCBmbGFncyBpbiB0aGUgcmVxdWlyZWQgRkxBR1MKKwkgKiByZXNwb25zZSBjYW4gYmUgY2hhbmdlZCBwZXJtYW5lbnRseS4KKwkgKi8KKwlpZiAocGVybWFuZW50RmxhZ3MgPT0gbnVsbCkgeworCSAgICBpZiAoYXZhaWxhYmxlRmxhZ3MgIT0gbnVsbCkKKwkJcGVybWFuZW50RmxhZ3MgPSBuZXcgRmxhZ3MoYXZhaWxhYmxlRmxhZ3MpOworCSAgICBlbHNlCisJCXBlcm1hbmVudEZsYWdzID0gbmV3IEZsYWdzKCk7CisJfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9NZXNzYWdlU2V0LmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvcHJvdG9jb2wvTWVzc2FnZVNldC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE3ZTZjYzYKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvcHJvdG9jb2wvTWVzc2FnZVNldC5qYXZhCkBAIC0wLDAgKzEsMTIwIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5pbWFwLnByb3RvY29sOworCitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKKworLyoqCisgKiBUaGlzIGNsYXNzIGhvbGRzIHRoZSAnc3RhcnQnIGFuZCAnZW5kJyBmb3IgYSByYW5nZSBvZiBtZXNzYWdlcy4KKyAqLworcHVibGljIGNsYXNzIE1lc3NhZ2VTZXQgeworCisgICAgcHVibGljIGludCBzdGFydDsKKyAgICBwdWJsaWMgaW50IGVuZDsKKworICAgIHB1YmxpYyBNZXNzYWdlU2V0KCkgeyB9CisKKyAgICBwdWJsaWMgTWVzc2FnZVNldChpbnQgc3RhcnQsIGludCBlbmQpIHsKKwl0aGlzLnN0YXJ0ID0gc3RhcnQ7CisJdGhpcy5lbmQgPSBlbmQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ291bnQgdGhlIHRvdGFsIG51bWJlciBvZiBlbGVtZW50cyBpbiBhIE1lc3NhZ2VTZXQKKyAgICAgKgorICAgICAqIEByZXR1cm4JaG93IG1hbnkgbWVzc2FnZXMgaW4gdGhpcyBNZXNzYWdlU2V0CisgICAgICovCisgICAgcHVibGljIGludCBzaXplKCkgeworCXJldHVybiBlbmQgLSBzdGFydCArIDE7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydCBhbiBhcnJheSBvZiBpbnRlZ2VycyBpbnRvIGFuIGFycmF5IG9mIE1lc3NhZ2VTZXRzCisgICAgICoKKyAgICAgKiBAcGFyYW0JbXNncwl0aGUgbWVzc2FnZXMKKyAgICAgKiBAcmV0dXJuCQlhcnJheSBvZiBNZXNzYWdlU2V0IG9iamVjdHMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIE1lc3NhZ2VTZXRbXSBjcmVhdGVNZXNzYWdlU2V0cyhpbnRbXSBtc2dzKSB7CisJTGlzdDxNZXNzYWdlU2V0PiB2ID0gbmV3IEFycmF5TGlzdDw+KCk7CisJaW50IGksajsKKworCWZvciAoaT0wOyBpIDwgbXNncy5sZW5ndGg7IGkrKykgeworCSAgICBNZXNzYWdlU2V0IG1zID0gbmV3IE1lc3NhZ2VTZXQoKTsKKwkgICAgbXMuc3RhcnQgPSBtc2dzW2ldOworCisJICAgIC8vIExvb2sgZm9yIGNvbnRpZ3VvdXMgZWxlbWVudHMKKwkgICAgZm9yIChqPWkrMTsgaiA8IG1zZ3MubGVuZ3RoOyBqKyspIHsKKwkJaWYgKG1zZ3Nbal0gIT0gbXNnc1tqLTFdICsxKQorCQkgICAgYnJlYWs7CisJICAgIH0KKwkgICAgbXMuZW5kID0gbXNnc1tqLTFdOworCSAgICB2LmFkZChtcyk7CisJICAgIGkgPSBqLTE7IC8vIGkgZ2V0cyBpbmNyZW1lbnRlZCBAIHRvcCBvZiB0aGUgbG9vcAorCX0KKwlyZXR1cm4gdi50b0FycmF5KG5ldyBNZXNzYWdlU2V0W3Yuc2l6ZSgpXSk7CQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlcnQgYW4gYXJyYXkgb2YgTWVzc2FnZVNldHMgaW50byBhbiBJTUFQIHNlcXVlbmNlIHJhbmdlCisgICAgICoKKyAgICAgKiBAcGFyYW0JbXNnc2V0cwl0aGUgTWVzc2FnZVNldHMKKyAgICAgKiBAcmV0dXJuCQlJTUFQIHNlcXVlbmNlIHN0cmluZworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHRvU3RyaW5nKE1lc3NhZ2VTZXRbXSBtc2dzZXRzKSB7CisJaWYgKG1zZ3NldHMgPT0gbnVsbCB8fCBtc2dzZXRzLmxlbmd0aCA9PSAwKSAvLyBFbXB0eSBtc2dzZXQKKwkgICAgcmV0dXJuIG51bGw7IAorCisJaW50IGkgPSAwOyAgLy8gbXNnc2V0IGluZGV4CisJU3RyaW5nQnVpbGRlciBzID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKwlpbnQgc2l6ZSA9IG1zZ3NldHMubGVuZ3RoOworCWludCBzdGFydCwgZW5kOworCisJZm9yICg7OykgeworCSAgICBzdGFydCA9IG1zZ3NldHNbaV0uc3RhcnQ7CisJICAgIGVuZCA9IG1zZ3NldHNbaV0uZW5kOworCisJICAgIGlmIChlbmQgPiBzdGFydCkKKwkJcy5hcHBlbmQoc3RhcnQpLmFwcGVuZCgnOicpLmFwcGVuZChlbmQpOworCSAgICBlbHNlIC8vIGVuZCA9PSBzdGFydCBtZWFucyBvbmx5IG9uZSBlbGVtZW50CisJCXMuYXBwZW5kKHN0YXJ0KTsKKwkKKwkgICAgaSsrOyAvLyBOZXh0IE1lc3NhZ2VTZXQKKwkgICAgaWYgKGkgPj0gc2l6ZSkgLy8gTm8gbW9yZSBNZXNzYWdlU2V0cworCQlicmVhazsKKwkgICAgZWxzZQorCQlzLmFwcGVuZCgnLCcpOworCX0KKwlyZXR1cm4gcy50b1N0cmluZygpOworICAgIH0KKworCQorICAgIC8qCisgICAgICogQ291bnQgdGhlIHRvdGFsIG51bWJlciBvZiBlbGVtZW50cyBpbiBhbiBhcnJheSBvZiBNZXNzYWdlU2V0cworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50IHNpemUoTWVzc2FnZVNldFtdIG1zZ3NldHMpIHsKKwlpbnQgY291bnQgPSAwOworCisJaWYgKG1zZ3NldHMgPT0gbnVsbCkgLy8gTnVsbCBtc2dzZXQKKwkgICAgcmV0dXJuIDA7IAorCisJZm9yIChpbnQgaT0wOyBpIDwgbXNnc2V0cy5sZW5ndGg7IGkrKykKKwkgICAgY291bnQgKz0gbXNnc2V0c1tpXS5zaXplKCk7CisJCisJcmV0dXJuIGNvdW50OworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9OYW1lc3BhY2VzLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvcHJvdG9jb2wvTmFtZXNwYWNlcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRmNTRlNjcKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvcHJvdG9jb2wvTmFtZXNwYWNlcy5qYXZhCkBAIC0wLDAgKzEsMTQ3IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5pbWFwLnByb3RvY29sOworCitpbXBvcnQgamF2YS51dGlsLio7CitpbXBvcnQgY29tLnN1bi5tYWlsLmlhcC4qOworCisvKioKKyAqIFRoaXMgY2xhc3MgYW5kIGl0cyBpbm5lciBjbGFzcyByZXByZXNlbnQgdGhlIHJlc3BvbnNlIHRvIHRoZQorICogTkFNRVNQQUNFIGNvbW1hbmQuIDxwPgorICoKKyAqIFNlZSA8QSBIUkVGPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMzQyLnR4dCI+UkZDIDIzNDI8L0E+LgorICoKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKi8KKworcHVibGljIGNsYXNzIE5hbWVzcGFjZXMgeworCisgICAgLyoqCisgICAgICogQSBzaW5nbGUgbmFtZXNwYWNlIGVudHJ5LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgTmFtZXNwYWNlIHsKKwkvKioKKwkgKiBQcmVmaXggc3RyaW5nIGZvciB0aGUgbmFtZXNwYWNlLgorCSAqLworCXB1YmxpYyBTdHJpbmcgcHJlZml4OworCisJLyoqCisJICogRGVsaW1pdGVyIGJldHdlZW4gbmFtZXMgaW4gdGhpcyBuYW1lc3BhY2UuCisJICovCisJcHVibGljIGNoYXIgZGVsaW1pdGVyOworCisJLyoqCisJICogUGFyc2UgYSBuYW1lc3BhY2UgZWxlbWVudCBvdXQgb2YgdGhlIHJlc3BvbnNlLgorCSAqCisJICogQHBhcmFtCXIJdGhlIFJlc3BvbnNlIHRvIHBhcnNlCisJICogQGV4Y2VwdGlvbglQcm90b2NvbEV4Y2VwdGlvbglmb3IgYW55IHByb3RvY29sIGVycm9ycworCSAqLworCXB1YmxpYyBOYW1lc3BhY2UoUmVzcG9uc2UgcikgdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKwkgICAgLy8gTmFtZXNwYWNlX0VsZW1lbnQgPSAiKCIgc3RyaW5nIFNQICg8Ij4gUVVPVEVEX0NIQVIgPCI+IC8gbmlsKQorCSAgICAvLwkJKihOYW1lc3BhY2VfUmVzcG9uc2VfRXh0ZW5zaW9uKSAiKSIKKwkgICAgaWYgKCFyLmlzTmV4dE5vblNwYWNlKCcoJykpCisJCXRocm93IG5ldyBQcm90b2NvbEV4Y2VwdGlvbigKKwkJCQkJIk1pc3NpbmcgJygnIGF0IHN0YXJ0IG9mIE5hbWVzcGFjZSIpOworCSAgICAvLyBmaXJzdCwgdGhlIHByZWZpeAorCSAgICBwcmVmaXggPSByLnJlYWRTdHJpbmcoKTsKKwkgICAgaWYgKCFyLnN1cHBvcnRzVXRmOCgpKQorCQlwcmVmaXggPSBCQVNFNjRNYWlsYm94RGVjb2Rlci5kZWNvZGUocHJlZml4KTsKKwkgICAgci5za2lwU3BhY2VzKCk7CisJICAgIC8vIGRlbGltaXRlciBpcyBhIHF1b3RlZCBjaGFyYWN0ZXIgb3IgTklMCisJICAgIGlmIChyLnBlZWtCeXRlKCkgPT0gJyInKSB7CisJCXIucmVhZEJ5dGUoKTsKKwkJZGVsaW1pdGVyID0gKGNoYXIpci5yZWFkQnl0ZSgpOworCQlpZiAoZGVsaW1pdGVyID09ICdcXCcpCisJCSAgICBkZWxpbWl0ZXIgPSAoY2hhcilyLnJlYWRCeXRlKCk7CisJCWlmIChyLnJlYWRCeXRlKCkgIT0gJyInKQorCQkgICAgdGhyb3cgbmV3IFByb3RvY29sRXhjZXB0aW9uKAorCQkJCSAgICAiTWlzc2luZyAnXCInIGF0IGVuZCBvZiBRVU9URURfQ0hBUiIpOworCSAgICB9IGVsc2UgeworCQlTdHJpbmcgcyA9IHIucmVhZEF0b20oKTsKKwkJaWYgKHMgPT0gbnVsbCkKKwkJICAgIHRocm93IG5ldyBQcm90b2NvbEV4Y2VwdGlvbigiRXhwZWN0ZWQgTklMLCBnb3QgbnVsbCIpOworCQlpZiAoIXMuZXF1YWxzSWdub3JlQ2FzZSgiTklMIikpCisJCSAgICB0aHJvdyBuZXcgUHJvdG9jb2xFeGNlcHRpb24oIkV4cGVjdGVkIE5JTCwgZ290ICIgKyBzKTsKKwkJZGVsaW1pdGVyID0gMDsKKwkgICAgfQorCSAgICAvLyBhdCBlbmQgb2YgTmFtZXNwYWNlIGRhdGE/CisJICAgIGlmIChyLmlzTmV4dE5vblNwYWNlKCcpJykpCisJCXJldHVybjsKKworCSAgICAvLyBvdGhlcndpc2UsIG11c3QgYmUgYSBOYW1lc3BhY2VfUmVzcG9uc2VfRXh0ZW5zaW9uCisJICAgIC8vICAgIE5hbWVzcGFjZV9SZXNwb25zZV9FeHRlbnNpb24gPSBTUCBzdHJpbmcgU1AKKwkgICAgLy8JICAgICIoIiBzdHJpbmcgKihTUCBzdHJpbmcpICIpIgorCSAgICByLnJlYWRTdHJpbmcoKTsKKwkgICAgci5za2lwU3BhY2VzKCk7CisJICAgIHIucmVhZFN0cmluZ0xpc3QoKTsKKwkgICAgaWYgKCFyLmlzTmV4dE5vblNwYWNlKCcpJykpCisJCXRocm93IG5ldyBQcm90b2NvbEV4Y2VwdGlvbigiTWlzc2luZyAnKScgYXQgZW5kIG9mIE5hbWVzcGFjZSIpOworCX0KKyAgICB9OworCisgICAgLyoqCisgICAgICogVGhlIHBlcnNvbmFsIG5hbWVzcGFjZXMuCisgICAgICogTWF5IGJlIG51bGwuCisgICAgICovCisgICAgcHVibGljIE5hbWVzcGFjZVtdIHBlcnNvbmFsOworCisgICAgLyoqCisgICAgICogVGhlIG5hbWVzcGFjZXMgZm9yIG90aGVyIHVzZXJzLgorICAgICAqIE1heSBiZSBudWxsLgorICAgICAqLworICAgIHB1YmxpYyBOYW1lc3BhY2VbXSBvdGhlclVzZXJzOworCisgICAgLyoqCisgICAgICogVGhlIHNoYXJlZCBuYW1lc3BhY2UuCisgICAgICogTWF5IGJlIG51bGwuCisgICAgICovCisgICAgcHVibGljIE5hbWVzcGFjZVtdIHNoYXJlZDsKKworICAgIC8qKgorICAgICAqIFBhcnNlIG91dCBhbGwgdGhlIG5hbWVzcGFjZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jcgl0aGUgUmVzcG9uc2UgdG8gcGFyc2UKKyAgICAgKiBAdGhyb3dzCVByb3RvY29sRXhjZXB0aW9uCWZvciBhbnkgcHJvdG9jb2wgZXJyb3JzCisgICAgICovCisgICAgcHVibGljIE5hbWVzcGFjZXMoUmVzcG9uc2UgcikgdGhyb3dzIFByb3RvY29sRXhjZXB0aW9uIHsKKwlwZXJzb25hbCA9IGdldE5hbWVzcGFjZXMocik7CisJb3RoZXJVc2VycyA9IGdldE5hbWVzcGFjZXMocik7CisJc2hhcmVkID0gZ2V0TmFtZXNwYWNlcyhyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZSBvdXQgb25lIG9mIHRoZSB0aHJlZSBzZXRzIG9mIG5hbWVzcGFjZXMuCisgICAgICovCisgICAgcHJpdmF0ZSBOYW1lc3BhY2VbXSBnZXROYW1lc3BhY2VzKFJlc3BvbnNlIHIpIHRocm93cyBQcm90b2NvbEV4Y2VwdGlvbiB7CisJLy8gICAgTmFtZXNwYWNlID0gbmlsIC8gIigiIDEqKCBOYW1lc3BhY2VfRWxlbWVudCkgIikiCisJaWYgKHIuaXNOZXh0Tm9uU3BhY2UoJygnKSkgeworCSAgICBMaXN0PE5hbWVzcGFjZT4gdiA9IG5ldyBBcnJheUxpc3Q8PigpOworCSAgICBkbyB7CisJCU5hbWVzcGFjZSBucyA9IG5ldyBOYW1lc3BhY2Uocik7CisJCXYuYWRkKG5zKTsKKwkgICAgfSB3aGlsZSAoIXIuaXNOZXh0Tm9uU3BhY2UoJyknKSk7CisJICAgIHJldHVybiB2LnRvQXJyYXkobmV3IE5hbWVzcGFjZVt2LnNpemUoKV0pOworCX0gZWxzZSB7CisJICAgIFN0cmluZyBzID0gci5yZWFkQXRvbSgpOworCSAgICBpZiAocyA9PSBudWxsKQorCQl0aHJvdyBuZXcgUHJvdG9jb2xFeGNlcHRpb24oIkV4cGVjdGVkIE5JTCwgZ290IG51bGwiKTsKKwkgICAgaWYgKCFzLmVxdWFsc0lnbm9yZUNhc2UoIk5JTCIpKQorCQl0aHJvdyBuZXcgUHJvdG9jb2xFeGNlcHRpb24oIkV4cGVjdGVkIE5JTCwgZ290ICIgKyBzKTsKKwkgICAgcmV0dXJuIG51bGw7CisJfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9SRkM4MjJEQVRBLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvcHJvdG9jb2wvUkZDODIyREFUQS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJkYTc1NGYKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvcHJvdG9jb2wvUkZDODIyREFUQS5qYXZhCkBAIC0wLDAgKzEsNzYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmltYXAucHJvdG9jb2w7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGNvbS5zdW4ubWFpbC5pYXAuKjsgCitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuQVNDSUlVdGlsaXR5OworCisvKioKKyAqIFRoZSBSRkM4MjIgcmVzcG9uc2UgZGF0YSBpdGVtLgorICoKKyAqIEBhdXRob3IgIEpvaG4gTWFuaQorICogQGF1dGhvciAgQmlsbCBTaGFubm9uCisgKi8KKworcHVibGljIGNsYXNzIFJGQzgyMkRBVEEgaW1wbGVtZW50cyBJdGVtIHsKKyAgIAorICAgIHN0YXRpYyBmaW5hbCBjaGFyW10gbmFtZSA9IHsnUicsJ0YnLCdDJywnOCcsJzInLCcyJ307CisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgbXNnbm87CisgICAgcHJpdmF0ZSBmaW5hbCBCeXRlQXJyYXkgZGF0YTsKKyAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gaXNIZWFkZXI7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvciwgaGVhZGVyIGZsYWcgaXMgZmFsc2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jcgl0aGUgRmV0Y2hSZXNwb25zZQorICAgICAqIEBleGNlcHRpb24JUGFyc2luZ0V4Y2VwdGlvbglmb3IgcGFyc2luZyBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBSRkM4MjJEQVRBKEZldGNoUmVzcG9uc2UgcikgdGhyb3dzIFBhcnNpbmdFeGNlcHRpb24geworCXRoaXMociwgZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yLCBzcGVjaWZ5aW5nIGhlYWRlciBmbGFnLgorICAgICAqCisgICAgICogQHBhcmFtCXIJdGhlIEZldGNoUmVzcG9uc2UKKyAgICAgKiBAcGFyYW0JaXNIZWFkZXIJanVzdCBoZWFkZXIgaW5mb3JtYXRpb24/CisgICAgICogQGV4Y2VwdGlvbglQYXJzaW5nRXhjZXB0aW9uCWZvciBwYXJzaW5nIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIFJGQzgyMkRBVEEoRmV0Y2hSZXNwb25zZSByLCBib29sZWFuIGlzSGVhZGVyKQorCQkJCXRocm93cyBQYXJzaW5nRXhjZXB0aW9uIHsKKwl0aGlzLmlzSGVhZGVyID0gaXNIZWFkZXI7CisJbXNnbm8gPSByLmdldE51bWJlcigpOworCXIuc2tpcFNwYWNlcygpOworCWRhdGEgPSByLnJlYWRCeXRlQXJyYXkoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgQnl0ZUFycmF5IGdldEJ5dGVBcnJheSgpIHsKKwlyZXR1cm4gZGF0YTsKKyAgICB9CisKKyAgICBwdWJsaWMgQnl0ZUFycmF5SW5wdXRTdHJlYW0gZ2V0Qnl0ZUFycmF5SW5wdXRTdHJlYW0oKSB7CisJaWYgKGRhdGEgIT0gbnVsbCkKKwkgICAgcmV0dXJuIGRhdGEudG9CeXRlQXJyYXlJbnB1dFN0cmVhbSgpOworCWVsc2UKKwkgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaXNIZWFkZXIoKSB7CisJcmV0dXJuIGlzSGVhZGVyOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9SRkM4MjJTSVpFLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvcHJvdG9jb2wvUkZDODIyU0laRS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU5MTE4ZjEKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvcHJvdG9jb2wvUkZDODIyU0laRS5qYXZhCkBAIC0wLDAgKzEsNDUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmltYXAucHJvdG9jb2w7CisKK2ltcG9ydCBjb20uc3VuLm1haWwuaWFwLio7IAorCisvKioKKyAqIEFuIFJGQzgyMlNJWkUgRkVUQ0ggaXRlbS4KKyAqCisgKiBAYXV0aG9yICBKb2huIE1hbmkKKyAqLworCitwdWJsaWMgY2xhc3MgUkZDODIyU0laRSBpbXBsZW1lbnRzIEl0ZW0geworICAgIAorICAgIHN0YXRpYyBmaW5hbCBjaGFyW10gbmFtZSA9IHsnUicsJ0YnLCdDJywnOCcsJzInLCcyJywnLicsJ1MnLCdJJywnWicsJ0UnfTsKKyAgICBwdWJsaWMgaW50IG1zZ25vOworCisgICAgcHVibGljIGxvbmcgc2l6ZTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yLgorICAgICAqCisgICAgICogQHBhcmFtCXIJdGhlIEZldGNoUmVzcG9uc2UKKyAgICAgKiBAZXhjZXB0aW9uCVBhcnNpbmdFeGNlcHRpb24JZm9yIHBhcnNpbmcgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgUkZDODIyU0laRShGZXRjaFJlc3BvbnNlIHIpIHRocm93cyBQYXJzaW5nRXhjZXB0aW9uIHsKKwltc2dubyA9IHIuZ2V0TnVtYmVyKCk7CisJci5za2lwU3BhY2VzKCk7CisJc2l6ZSA9IHIucmVhZExvbmcoKTsJCQorICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9TYXNsQXV0aGVudGljYXRvci5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL3Byb3RvY29sL1Nhc2xBdXRoZW50aWNhdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGMzMWM3NgotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9TYXNsQXV0aGVudGljYXRvci5qYXZhCkBAIC0wLDAgKzEsMjkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmltYXAucHJvdG9jb2w7CisKK2ltcG9ydCBjb20uc3VuLm1haWwuaWFwLlByb3RvY29sRXhjZXB0aW9uOworCisvKioKKyAqIEludGVyZmFjZSB0byBtYWtlIGl0IGVhc2llciB0byBjYWxsIElNQVBTYXNsQXV0aGVudGljYXRvci4KKyAqLworCitwdWJsaWMgaW50ZXJmYWNlIFNhc2xBdXRoZW50aWNhdG9yIHsKKyAgICBwdWJsaWMgYm9vbGVhbiBhdXRoZW50aWNhdGUoU3RyaW5nW10gbWVjaHMsIFN0cmluZyByZWFsbSwgU3RyaW5nIGF1dGh6aWQsCisJCQkJU3RyaW5nIHUsIFN0cmluZyBwKSB0aHJvd3MgUHJvdG9jb2xFeGNlcHRpb247CisKK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9TZWFyY2hTZXF1ZW5jZS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL3Byb3RvY29sL1NlYXJjaFNlcXVlbmNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzEzODgzNwotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9TZWFyY2hTZXF1ZW5jZS5qYXZhCkBAIC0wLDAgKzEsNTI3IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5pbWFwLnByb3RvY29sOworCitpbXBvcnQgamF2YS51dGlsLio7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworaW1wb3J0IGphdmF4Lm1haWwuKjsKK2ltcG9ydCBqYXZheC5tYWlsLnNlYXJjaC4qOworaW1wb3J0IGNvbS5zdW4ubWFpbC5pYXAuKjsKK2ltcG9ydCBjb20uc3VuLm1haWwuaW1hcC5PbGRlclRlcm07CitpbXBvcnQgY29tLnN1bi5tYWlsLmltYXAuWW91bmdlclRlcm07CitpbXBvcnQgY29tLnN1bi5tYWlsLmltYXAuTW9kaWZpZWRTaW5jZVRlcm07CisKKy8qKgorICogVGhpcyBjbGFzcyB0cmF2ZXJzZXMgYSBzZWFyY2gtdHJlZSBhbmQgZ2VuZXJhdGVzIHRoZSAKKyAqIGNvcnJlc3BvbmRpbmcgSU1BUCBzZWFyY2ggc2VxdWVuY2UuIAorICoKKyAqIEVhY2ggSU1BUFByb3RvY29sIGluc3RhbmNlIGNvbnRhaW5zIGFuIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MsCisgKiB3aGljaCBtaWdodCBiZSBzdWJjbGFzc2VkIGJ5IHN1YmNsYXNzZXMgb2YgSU1BUFByb3RvY29sIHRvIGFkZAorICogc3VwcG9ydCBmb3IgYWRkaXRpb25hbCBwcm9kdWN0LXNwZWNpZmljIHNlYXJjaCB0ZXJtcy4KKyAqCisgKiBAYXV0aG9yCUpvaG4gTWFuaQorICogQGF1dGhvcglCaWxsIFNoYW5ub24KKyAqLworcHVibGljIGNsYXNzIFNlYXJjaFNlcXVlbmNlIHsKKworICAgIHByaXZhdGUgSU1BUFByb3RvY29sIHByb3RvY29sOwkvLyBmb3IgaGFzQ2FwYWJpbGl0eSBjaGVja3M7IG1heSBiZSBudWxsCisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBTZWFyY2hTZXF1ZW5jZSBmb3IgdGhpcyBJTUFQUHJvdG9jb2wuCisgICAgICoKKyAgICAgKiBAcGFyYW0JcAl0aGUgSU1BUFByb3RvY29sIG9iamVjdCBmb3IgdGhlIHNlcnZlcgorICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjYuMAorICAgICAqLworICAgIHB1YmxpYyBTZWFyY2hTZXF1ZW5jZShJTUFQUHJvdG9jb2wgcCkgeworCXByb3RvY29sID0gcDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBTZWFyY2hTZXF1ZW5jZS4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBTZWFyY2hTZXF1ZW5jZSgpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZW5lcmF0ZSB0aGUgSU1BUCBzZWFyY2ggc2VxdWVuY2UgZm9yIHRoZSBnaXZlbiBzZWFyY2ggZXhwcmVzc2lvbi4gCisgICAgICoKKyAgICAgKiBAcGFyYW0JdGVybQl0aGUgc2VhcmNoIHRlcm0KKyAgICAgKiBAcGFyYW0JY2hhcnNldAljaGFyc2V0IGZvciB0aGUgc2VhcmNoCisgICAgICogQHJldHVybgkJdGhlIFNFQVJDSCBBcmd1bWVudAorICAgICAqIEBleGNlcHRpb24JU2VhcmNoRXhjZXB0aW9uCWZvciBmYWlsdXJlcworICAgICAqIEBleGNlcHRpb24JSU9FeGNlcHRpb24JZm9yIEkvTyBlcnJvcnMKKyAgICAgKi8KKyAgICBwdWJsaWMgQXJndW1lbnQgZ2VuZXJhdGVTZXF1ZW5jZShTZWFyY2hUZXJtIHRlcm0sIFN0cmluZyBjaGFyc2V0KSAKKwkJdGhyb3dzIFNlYXJjaEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworCS8qCisJICogQ2FsbCB0aGUgYXBwcm9wcmlhdGUgaGFuZGxlciBkZXBlbmRpbmcgb24gdGhlIHR5cGUgb2YKKwkgKiB0aGUgc2VhcmNoLXRlcm0gLi4uCisJICovCisJaWYgKHRlcm0gaW5zdGFuY2VvZiBBbmRUZXJtKSAJCS8vIEFORAorCSAgICByZXR1cm4gYW5kKChBbmRUZXJtKXRlcm0sIGNoYXJzZXQpOworCWVsc2UgaWYgKHRlcm0gaW5zdGFuY2VvZiBPclRlcm0pIAkvLyBPUgorCSAgICByZXR1cm4gb3IoKE9yVGVybSl0ZXJtLCBjaGFyc2V0KTsKKwllbHNlIGlmICh0ZXJtIGluc3RhbmNlb2YgTm90VGVybSkgCS8vIE5PVAorCSAgICByZXR1cm4gbm90KChOb3RUZXJtKXRlcm0sIGNoYXJzZXQpOworCWVsc2UgaWYgKHRlcm0gaW5zdGFuY2VvZiBIZWFkZXJUZXJtKSAJLy8gSEVBREVSCisJICAgIHJldHVybiBoZWFkZXIoKEhlYWRlclRlcm0pdGVybSwgY2hhcnNldCk7CisJZWxzZSBpZiAodGVybSBpbnN0YW5jZW9mIEZsYWdUZXJtKSAJLy8gRkxBRworCSAgICByZXR1cm4gZmxhZygoRmxhZ1Rlcm0pdGVybSk7CisJZWxzZSBpZiAodGVybSBpbnN0YW5jZW9mIEZyb21UZXJtKSB7CS8vIEZST00KKwkgICAgRnJvbVRlcm0gZnRlcm0gPSAoRnJvbVRlcm0pdGVybTsKKwkgICAgcmV0dXJuIGZyb20oZnRlcm0uZ2V0QWRkcmVzcygpLnRvU3RyaW5nKCksIGNoYXJzZXQpOworCX0KKwllbHNlIGlmICh0ZXJtIGluc3RhbmNlb2YgRnJvbVN0cmluZ1Rlcm0pIHsgLy8gRlJPTQorCSAgICBGcm9tU3RyaW5nVGVybSBmdGVybSA9IChGcm9tU3RyaW5nVGVybSl0ZXJtOworCSAgICByZXR1cm4gZnJvbShmdGVybS5nZXRQYXR0ZXJuKCksIGNoYXJzZXQpOworCX0KKwllbHNlIGlmICh0ZXJtIGluc3RhbmNlb2YgUmVjaXBpZW50VGVybSkJeyAvLyBSRUNJUElFTlQKKwkgICAgUmVjaXBpZW50VGVybSBydGVybSA9IChSZWNpcGllbnRUZXJtKXRlcm07CisJICAgIHJldHVybiByZWNpcGllbnQocnRlcm0uZ2V0UmVjaXBpZW50VHlwZSgpLCAKKwkJCSAgICAgcnRlcm0uZ2V0QWRkcmVzcygpLnRvU3RyaW5nKCksCisJCQkgICAgIGNoYXJzZXQpOworCX0KKwllbHNlIGlmICh0ZXJtIGluc3RhbmNlb2YgUmVjaXBpZW50U3RyaW5nVGVybSkgeyAvLyBSRUNJUElFTlQKKwkgICAgUmVjaXBpZW50U3RyaW5nVGVybSBydGVybSA9IChSZWNpcGllbnRTdHJpbmdUZXJtKXRlcm07CisJICAgIHJldHVybiByZWNpcGllbnQocnRlcm0uZ2V0UmVjaXBpZW50VHlwZSgpLAorCQkJICAgICBydGVybS5nZXRQYXR0ZXJuKCksCisJCQkgICAgIGNoYXJzZXQpOworCX0KKwllbHNlIGlmICh0ZXJtIGluc3RhbmNlb2YgU3ViamVjdFRlcm0pCS8vIFNVQkpFQ1QKKwkgICAgcmV0dXJuIHN1YmplY3QoKFN1YmplY3RUZXJtKXRlcm0sIGNoYXJzZXQpOworCWVsc2UgaWYgKHRlcm0gaW5zdGFuY2VvZiBCb2R5VGVybSkJLy8gQk9EWQorCSAgICByZXR1cm4gYm9keSgoQm9keVRlcm0pdGVybSwgY2hhcnNldCk7CisJZWxzZSBpZiAodGVybSBpbnN0YW5jZW9mIFNpemVUZXJtKQkvLyBTSVpFCisJICAgIHJldHVybiBzaXplKChTaXplVGVybSl0ZXJtKTsKKwllbHNlIGlmICh0ZXJtIGluc3RhbmNlb2YgU2VudERhdGVUZXJtKQkvLyBTRU5UREFURQorCSAgICByZXR1cm4gc2VudGRhdGUoKFNlbnREYXRlVGVybSl0ZXJtKTsKKwllbHNlIGlmICh0ZXJtIGluc3RhbmNlb2YgUmVjZWl2ZWREYXRlVGVybSkgLy8gSU5URVJOQUxEQVRFCisJICAgIHJldHVybiByZWNlaXZlZGRhdGUoKFJlY2VpdmVkRGF0ZVRlcm0pdGVybSk7CisJZWxzZSBpZiAodGVybSBpbnN0YW5jZW9mIE9sZGVyVGVybSkJLy8gUkZDIDUwMzIgT0xERVIKKwkgICAgcmV0dXJuIG9sZGVyKChPbGRlclRlcm0pdGVybSk7CisJZWxzZSBpZiAodGVybSBpbnN0YW5jZW9mIFlvdW5nZXJUZXJtKQkvLyBSRkMgNTAzMiBZT1VOR0VSCisJICAgIHJldHVybiB5b3VuZ2VyKChZb3VuZ2VyVGVybSl0ZXJtKTsKKwllbHNlIGlmICh0ZXJtIGluc3RhbmNlb2YgTWVzc2FnZUlEVGVybSkgLy8gTWVzc2FnZUlECisJICAgIHJldHVybiBtZXNzYWdlaWQoKE1lc3NhZ2VJRFRlcm0pdGVybSwgY2hhcnNldCk7CisJZWxzZSBpZiAodGVybSBpbnN0YW5jZW9mIE1vZGlmaWVkU2luY2VUZXJtKQkvLyBSRkMgNDU1MSBNT0RTRVEKKwkgICAgcmV0dXJuIG1vZGlmaWVkU2luY2UoKE1vZGlmaWVkU2luY2VUZXJtKXRlcm0pOworCWVsc2UKKwkgICAgdGhyb3cgbmV3IFNlYXJjaEV4Y2VwdGlvbigiU2VhcmNoIHRvbyBjb21wbGV4Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2sgaWYgdGhlICJ0ZXh0IiB0ZXJtcyBpbiB0aGUgZ2l2ZW4gU2VhcmNoVGVybSBjb250YWluCisgICAgICogbm9uIFVTLUFTQ0lJIGNoYXJhY3RlcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0JdGVybQl0aGUgc2VhcmNoIHRlcm0KKyAgICAgKiBAcmV0dXJuCQl0cnVlIGlmIG9ubHkgQVNDSUkKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNBc2NpaShTZWFyY2hUZXJtIHRlcm0pIHsKKwlpZiAodGVybSBpbnN0YW5jZW9mIEFuZFRlcm0pCisJICAgIHJldHVybiBpc0FzY2lpKCgoQW5kVGVybSl0ZXJtKS5nZXRUZXJtcygpKTsKKwllbHNlIGlmICh0ZXJtIGluc3RhbmNlb2YgT3JUZXJtKQorCSAgICByZXR1cm4gaXNBc2NpaSgoKE9yVGVybSl0ZXJtKS5nZXRUZXJtcygpKTsKKwllbHNlIGlmICh0ZXJtIGluc3RhbmNlb2YgTm90VGVybSkKKwkgICAgcmV0dXJuIGlzQXNjaWkoKChOb3RUZXJtKXRlcm0pLmdldFRlcm0oKSk7CisJZWxzZSBpZiAodGVybSBpbnN0YW5jZW9mIFN0cmluZ1Rlcm0pCisJICAgIHJldHVybiBpc0FzY2lpKCgoU3RyaW5nVGVybSl0ZXJtKS5nZXRQYXR0ZXJuKCkpOworCWVsc2UgaWYgKHRlcm0gaW5zdGFuY2VvZiBBZGRyZXNzVGVybSkKKwkgICAgcmV0dXJuIGlzQXNjaWkoKChBZGRyZXNzVGVybSl0ZXJtKS5nZXRBZGRyZXNzKCkudG9TdHJpbmcoKSk7CisJCisJLy8gQW55IG90aGVyIHRlcm0gcmV0dXJucyB0cnVlLgorCXJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrIGlmIGFueSBvZiB0aGUgInRleHQiIHRlcm1zIGluIHRoZSBnaXZlbiBTZWFyY2hUZXJtcyBjb250YWluCisgICAgICogbm9uIFVTLUFTQ0lJIGNoYXJhY3RlcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0JdGVybXMJdGhlIHNlYXJjaCB0ZXJtcworICAgICAqIEByZXR1cm4JCXRydWUgaWYgb25seSBBU0NJSQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0FzY2lpKFNlYXJjaFRlcm1bXSB0ZXJtcykgeworCWZvciAoaW50IGkgPSAwOyBpIDwgdGVybXMubGVuZ3RoOyBpKyspCisJICAgIGlmICghaXNBc2NpaSh0ZXJtc1tpXSkpIC8vIG91dHRhIGhlcmUgIQorCQlyZXR1cm4gZmFsc2U7CisJcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogRG9lcyB0aGlzIHN0cmluZyBjb250YWluIG9ubHkgQVNDSUkgY2hhcmFjdGVycz8KKyAgICAgKgorICAgICAqIEBwYXJhbQlzCXRoZSBzdHJpbmcKKyAgICAgKiBAcmV0dXJuCQl0cnVlIGlmIG9ubHkgQVNDSUkKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNBc2NpaShTdHJpbmcgcykgeworCWludCBsID0gcy5sZW5ndGgoKTsKKworCWZvciAoaW50IGk9MDsgaSA8IGw7IGkrKykgeworCSAgICBpZiAoKGludClzLmNoYXJBdChpKSA+IDAxNzcpIC8vIG5vbi1hc2NpaQorCQlyZXR1cm4gZmFsc2U7CisJfQorCXJldHVybiB0cnVlOworICAgIH0KKworICAgIHByb3RlY3RlZCBBcmd1bWVudCBhbmQoQW5kVGVybSB0ZXJtLCBTdHJpbmcgY2hhcnNldCkgCisJCQl0aHJvd3MgU2VhcmNoRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisJLy8gQ29tYmluZSB0aGUgc2VxdWVuY2VzIGZvciBib3RoIHRlcm1zCisJU2VhcmNoVGVybVtdIHRlcm1zID0gdGVybS5nZXRUZXJtcygpOworCS8vIEdlbmVyYXRlIHRoZSBzZWFyY2ggc2VxdWVuY2UgZm9yIHRoZSBmaXJzdCB0ZXJtCisJQXJndW1lbnQgcmVzdWx0ID0gZ2VuZXJhdGVTZXF1ZW5jZSh0ZXJtc1swXSwgY2hhcnNldCk7CisJLy8gQXBwZW5kIG90aGVyIHRlcm1zCisJZm9yIChpbnQgaSA9IDE7IGkgPCB0ZXJtcy5sZW5ndGg7IGkrKykKKwkgICAgcmVzdWx0LmFwcGVuZChnZW5lcmF0ZVNlcXVlbmNlKHRlcm1zW2ldLCBjaGFyc2V0KSk7CisJcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgQXJndW1lbnQgb3IoT3JUZXJtIHRlcm0sIFN0cmluZyBjaGFyc2V0KSAKKwkJCXRocm93cyBTZWFyY2hFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKwlTZWFyY2hUZXJtW10gdGVybXMgPSB0ZXJtLmdldFRlcm1zKCk7CisKKwkvKiBUaGUgSU1BUCBPUiBvcGVyYXRvciB0YWtlcyBvbmx5IHR3byBvcGVyYW5kcy4gU28gaWYKKwkgKiB3ZSBoYXZlIG1vcmUgdGhhbiAyIG9wZXJhbmRzLCBncm91cCB0aGVtIGludG8gMi1vcGVyYW5kCisJICogT1IgVGVybXMuCisJICovCisJaWYgKHRlcm1zLmxlbmd0aCA+IDIpIHsKKwkgICAgU2VhcmNoVGVybSB0ID0gdGVybXNbMF07CisKKwkgICAgLy8gSW5jbHVkZSByZXN0IG9mIHRoZSB0ZXJtcworCSAgICBmb3IgKGludCBpID0gMTsgaSA8IHRlcm1zLmxlbmd0aDsgaSsrKQorCQl0ID0gbmV3IE9yVGVybSh0LCB0ZXJtc1tpXSk7CisKKwkgICAgdGVybSA9IChPclRlcm0pdDsgCS8vIHNldCAndGVybScgdG8gdGhlIG5ldyBqdW1ibyBPclRlcm0gd2UKKwkJCQkvLyBqdXN0IGNyZWF0ZWQKKwkgICAgdGVybXMgPSB0ZXJtLmdldFRlcm1zKCk7CisJfQorCisJLy8gJ3Rlcm0nIG5vdyBoYXMgb25seSB0d28gb3BlcmFuZHMKKwlBcmd1bWVudCByZXN1bHQgPSBuZXcgQXJndW1lbnQoKTsKKworCS8vIEFkZCB0aGUgT1Igc2VhcmNoLWtleSwgaWYgbW9yZSB0aGFuIG9uZSB0ZXJtCisJaWYgKHRlcm1zLmxlbmd0aCA+IDEpCisJICAgIHJlc3VsdC53cml0ZUF0b20oIk9SIik7CisKKwkvKiBJZiB0aGlzIHRlcm0gaXMgYW4gQU5EIGV4cHJlc3Npb24sIHdlIG5lZWQgdG8gZW5jbG9zZSBpdAorCSAqIHdpdGhpbiBwYXJhbnRoZXNpcy4KKwkgKgorCSAqIEFORCBleHByZXNzaW9ucyBhcmUgZWl0aGVyIEFuZFRlcm1zIG9yIEZsYWdUZXJtcyAKKwkgKi8KKwlpZiAodGVybXNbMF0gaW5zdGFuY2VvZiBBbmRUZXJtIHx8IHRlcm1zWzBdIGluc3RhbmNlb2YgRmxhZ1Rlcm0pCisJICAgIHJlc3VsdC53cml0ZUFyZ3VtZW50KGdlbmVyYXRlU2VxdWVuY2UodGVybXNbMF0sIGNoYXJzZXQpKTsKKwllbHNlCisJICAgIHJlc3VsdC5hcHBlbmQoZ2VuZXJhdGVTZXF1ZW5jZSh0ZXJtc1swXSwgY2hhcnNldCkpOworCisJLy8gUmVwZWF0IHRoZSBhYm92ZSBmb3IgdGhlIHNlY29uZCB0ZXJtLCBpZiB0aGVyZSBpcyBvbmUKKwlpZiAodGVybXMubGVuZ3RoID4gMSkgeworCSAgICBpZiAodGVybXNbMV0gaW5zdGFuY2VvZiBBbmRUZXJtIHx8IHRlcm1zWzFdIGluc3RhbmNlb2YgRmxhZ1Rlcm0pCisJCXJlc3VsdC53cml0ZUFyZ3VtZW50KGdlbmVyYXRlU2VxdWVuY2UodGVybXNbMV0sIGNoYXJzZXQpKTsKKwkgICAgZWxzZQorCQlyZXN1bHQuYXBwZW5kKGdlbmVyYXRlU2VxdWVuY2UodGVybXNbMV0sIGNoYXJzZXQpKTsKKwl9CisKKwlyZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHByb3RlY3RlZCBBcmd1bWVudCBub3QoTm90VGVybSB0ZXJtLCBTdHJpbmcgY2hhcnNldCkgCisJCQl0aHJvd3MgU2VhcmNoRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisJQXJndW1lbnQgcmVzdWx0ID0gbmV3IEFyZ3VtZW50KCk7CisKKwkvLyBBZGQgdGhlIE5PVCBzZWFyY2gta2V5CisJcmVzdWx0LndyaXRlQXRvbSgiTk9UIik7CisKKwkvKiBJZiB0aGlzIHRlcm0gaXMgYW4gQU5EIGV4cHJlc3Npb24sIHdlIG5lZWQgdG8gZW5jbG9zZSBpdAorCSAqIHdpdGhpbiBwYXJhbnRoZXNpcy4gCisJICoKKwkgKiBBTkQgZXhwcmVzc2lvbnMgYXJlIGVpdGhlciBBbmRUZXJtcyBvciBGbGFnVGVybXMgCisJICovCisJU2VhcmNoVGVybSBudGVybSA9IHRlcm0uZ2V0VGVybSgpOworCWlmIChudGVybSBpbnN0YW5jZW9mIEFuZFRlcm0gfHwgbnRlcm0gaW5zdGFuY2VvZiBGbGFnVGVybSkKKwkgICAgcmVzdWx0LndyaXRlQXJndW1lbnQoZ2VuZXJhdGVTZXF1ZW5jZShudGVybSwgY2hhcnNldCkpOworCWVsc2UKKwkgICAgcmVzdWx0LmFwcGVuZChnZW5lcmF0ZVNlcXVlbmNlKG50ZXJtLCBjaGFyc2V0KSk7CisKKwlyZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHByb3RlY3RlZCBBcmd1bWVudCBoZWFkZXIoSGVhZGVyVGVybSB0ZXJtLCBTdHJpbmcgY2hhcnNldCkgCisJCQl0aHJvd3MgU2VhcmNoRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisJQXJndW1lbnQgcmVzdWx0ID0gbmV3IEFyZ3VtZW50KCk7CisJcmVzdWx0LndyaXRlQXRvbSgiSEVBREVSIik7CisJcmVzdWx0LndyaXRlU3RyaW5nKHRlcm0uZ2V0SGVhZGVyTmFtZSgpKTsKKwlyZXN1bHQud3JpdGVTdHJpbmcodGVybS5nZXRQYXR0ZXJuKCksIGNoYXJzZXQpOworCXJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHJvdGVjdGVkIEFyZ3VtZW50IG1lc3NhZ2VpZChNZXNzYWdlSURUZXJtIHRlcm0sIFN0cmluZyBjaGFyc2V0KSAKKwkJCXRocm93cyBTZWFyY2hFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKwlBcmd1bWVudCByZXN1bHQgPSBuZXcgQXJndW1lbnQoKTsKKwlyZXN1bHQud3JpdGVBdG9tKCJIRUFERVIiKTsKKwlyZXN1bHQud3JpdGVTdHJpbmcoIk1lc3NhZ2UtSUQiKTsKKwkvLyBYWFggY29uZmlybSB0aGF0IGNoYXJzZXQgY29udmVyc2lvbiBvdWdodCB0byBiZSBkb25lCisJcmVzdWx0LndyaXRlU3RyaW5nKHRlcm0uZ2V0UGF0dGVybigpLCBjaGFyc2V0KTsgCisJcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgQXJndW1lbnQgZmxhZyhGbGFnVGVybSB0ZXJtKSB0aHJvd3MgU2VhcmNoRXhjZXB0aW9uIHsKKwlib29sZWFuIHNldCA9IHRlcm0uZ2V0VGVzdFNldCgpOworCisJQXJndW1lbnQgcmVzdWx0ID0gbmV3IEFyZ3VtZW50KCk7CisKKwlGbGFncyBmbGFncyA9IHRlcm0uZ2V0RmxhZ3MoKTsKKwlGbGFncy5GbGFnW10gc2YgPSBmbGFncy5nZXRTeXN0ZW1GbGFncygpOworCVN0cmluZ1tdIHVmID0gZmxhZ3MuZ2V0VXNlckZsYWdzKCk7CisJaWYgKHNmLmxlbmd0aCA9PSAwICYmIHVmLmxlbmd0aCA9PSAwKQorCSAgICB0aHJvdyBuZXcgU2VhcmNoRXhjZXB0aW9uKCJJbnZhbGlkIEZsYWdUZXJtIik7CisKKwlmb3IgKGludCBpID0gMDsgaSA8IHNmLmxlbmd0aDsgaSsrKSB7CisJICAgIGlmIChzZltpXSA9PSBGbGFncy5GbGFnLkRFTEVURUQpCisJCXJlc3VsdC53cml0ZUF0b20oc2V0ID8gIkRFTEVURUQiOiAiVU5ERUxFVEVEIik7CisJICAgIGVsc2UgaWYgKHNmW2ldID09IEZsYWdzLkZsYWcuQU5TV0VSRUQpCisJCXJlc3VsdC53cml0ZUF0b20oc2V0ID8gIkFOU1dFUkVEIjogIlVOQU5TV0VSRUQiKTsKKwkgICAgZWxzZSBpZiAoc2ZbaV0gPT0gRmxhZ3MuRmxhZy5EUkFGVCkKKwkJcmVzdWx0LndyaXRlQXRvbShzZXQgPyAiRFJBRlQiOiAiVU5EUkFGVCIpOworCSAgICBlbHNlIGlmIChzZltpXSA9PSBGbGFncy5GbGFnLkZMQUdHRUQpCisJCXJlc3VsdC53cml0ZUF0b20oc2V0ID8gIkZMQUdHRUQiOiAiVU5GTEFHR0VEIik7CisJICAgIGVsc2UgaWYgKHNmW2ldID09IEZsYWdzLkZsYWcuUkVDRU5UKQorCQlyZXN1bHQud3JpdGVBdG9tKHNldCA/ICJSRUNFTlQiOiAiT0xEIik7CisJICAgIGVsc2UgaWYgKHNmW2ldID09IEZsYWdzLkZsYWcuU0VFTikKKwkJcmVzdWx0LndyaXRlQXRvbShzZXQgPyAiU0VFTiI6ICJVTlNFRU4iKTsKKwl9CisKKwlmb3IgKGludCBpID0gMDsgaSA8IHVmLmxlbmd0aDsgaSsrKSB7CisJICAgIHJlc3VsdC53cml0ZUF0b20oc2V0ID8gIktFWVdPUkQiIDogIlVOS0VZV09SRCIpOworCSAgICByZXN1bHQud3JpdGVBdG9tKHVmW2ldKTsKKwl9CisJCisJcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgQXJndW1lbnQgZnJvbShTdHJpbmcgYWRkcmVzcywgU3RyaW5nIGNoYXJzZXQpIAorCQkJdGhyb3dzIFNlYXJjaEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworCUFyZ3VtZW50IHJlc3VsdCA9IG5ldyBBcmd1bWVudCgpOworCXJlc3VsdC53cml0ZUF0b20oIkZST00iKTsKKwlyZXN1bHQud3JpdGVTdHJpbmcoYWRkcmVzcywgY2hhcnNldCk7CisJcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgQXJndW1lbnQgcmVjaXBpZW50KE1lc3NhZ2UuUmVjaXBpZW50VHlwZSB0eXBlLAorCQkJCSAgICAgIFN0cmluZyBhZGRyZXNzLCBTdHJpbmcgY2hhcnNldCkKKwkJCXRocm93cyBTZWFyY2hFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKwlBcmd1bWVudCByZXN1bHQgPSBuZXcgQXJndW1lbnQoKTsKKworCWlmICh0eXBlID09IE1lc3NhZ2UuUmVjaXBpZW50VHlwZS5UTykKKwkgICAgcmVzdWx0LndyaXRlQXRvbSgiVE8iKTsKKwllbHNlIGlmICh0eXBlID09IE1lc3NhZ2UuUmVjaXBpZW50VHlwZS5DQykKKwkgICAgcmVzdWx0LndyaXRlQXRvbSgiQ0MiKTsKKwllbHNlIGlmICh0eXBlID09IE1lc3NhZ2UuUmVjaXBpZW50VHlwZS5CQ0MpCisJICAgIHJlc3VsdC53cml0ZUF0b20oIkJDQyIpOworCWVsc2UKKwkgICAgdGhyb3cgbmV3IFNlYXJjaEV4Y2VwdGlvbigiSWxsZWdhbCBSZWNpcGllbnQgdHlwZSIpOworCisJcmVzdWx0LndyaXRlU3RyaW5nKGFkZHJlc3MsIGNoYXJzZXQpOworCXJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHJvdGVjdGVkIEFyZ3VtZW50IHN1YmplY3QoU3ViamVjdFRlcm0gdGVybSwgU3RyaW5nIGNoYXJzZXQpIAorCQkJdGhyb3dzIFNlYXJjaEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworCUFyZ3VtZW50IHJlc3VsdCA9IG5ldyBBcmd1bWVudCgpOworCQorCXJlc3VsdC53cml0ZUF0b20oIlNVQkpFQ1QiKTsKKwlyZXN1bHQud3JpdGVTdHJpbmcodGVybS5nZXRQYXR0ZXJuKCksIGNoYXJzZXQpOworCXJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHJvdGVjdGVkIEFyZ3VtZW50IGJvZHkoQm9keVRlcm0gdGVybSwgU3RyaW5nIGNoYXJzZXQpIAorCQkJdGhyb3dzIFNlYXJjaEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworCUFyZ3VtZW50IHJlc3VsdCA9IG5ldyBBcmd1bWVudCgpOworCisJcmVzdWx0LndyaXRlQXRvbSgiQk9EWSIpOworCXJlc3VsdC53cml0ZVN0cmluZyh0ZXJtLmdldFBhdHRlcm4oKSwgY2hhcnNldCk7CisJcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgQXJndW1lbnQgc2l6ZShTaXplVGVybSB0ZXJtKSAKKwkJCXRocm93cyBTZWFyY2hFeGNlcHRpb24geworCUFyZ3VtZW50IHJlc3VsdCA9IG5ldyBBcmd1bWVudCgpOworCisJc3dpdGNoICh0ZXJtLmdldENvbXBhcmlzb24oKSkgeworCSAgICBjYXNlIENvbXBhcmlzb25UZXJtLkdUOgorCQlyZXN1bHQud3JpdGVBdG9tKCJMQVJHRVIiKTsKKwkJYnJlYWs7CisJICAgIGNhc2UgQ29tcGFyaXNvblRlcm0uTFQ6CisJCXJlc3VsdC53cml0ZUF0b20oIlNNQUxMRVIiKTsKKwkJYnJlYWs7CisJICAgIGRlZmF1bHQ6CisJCS8vIEdUIGFuZCBMVCBpcyBhbGwgd2UgZ2V0IGZyb20gSU1BUCBmb3Igc2l6ZQorCSAgICAJdGhyb3cgbmV3IFNlYXJjaEV4Y2VwdGlvbigiQ2Fubm90IGhhbmRsZSBDb21wYXJpc29uIik7CisJfQorCisJcmVzdWx0LndyaXRlTnVtYmVyKHRlcm0uZ2V0TnVtYmVyKCkpOworCXJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLy8gRGF0ZSBTRUFSQ0ggc3R1ZmYgLi4uCisKKyAgICAvLyBOT1RFOiBUaGUgYnVpbHQtaW4gSU1BUCBkYXRlIGNvbXBhcmlzb25zIGFyZSBlcXVpdmFsZW50IHRvCisgICAgLy8gICAgICAgIjwiIChCRUZPUkUpLCAiPSIgKE9OKSwgYW5kICI+PSIgKFNJTkNFKSEhIQorICAgIC8vICAgICAgIFRoZXJlIGlzIG5vIGJ1aWx0LWluIGdyZWF0ZXItdGhhbiBjb21wYXJpc29uIQorCisgICAgLyoqCisgICAgICogUHJpbnQgYW4gSU1BUCBEYXRlIHN0cmluZywgdGhhdCBpcyBzdWl0YWJsZSBmb3IgdGhlIERhdGUKKyAgICAgKiBTRUFSQ0ggY29tbWFuZHMuCisgICAgICoKKyAgICAgKiBUaGUgSU1BUCBEYXRlIHN0cmluZyBpcyA6CisgICAgICoJZGF0ZSA6Oj0gZGF0ZV9kYXkgIi0iIGRhdGVfbW9udGggIi0iIGRhdGVfeWVhcgkKKyAgICAgKgorICAgICAqIE5vdGUgdGhhdCB0aGlzIGZvcm1hdCBkb2VzIG5vdCBjb250YWluIHRoZSBUaW1lWm9uZQorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBtb250aFRhYmxlW10gPSB7IAorCSAgIkphbiIsICJGZWIiLCAiTWFyIiwgIkFwciIsICJNYXkiLCAiSnVuIiwKKwkgICJKdWwiLCAiQXVnIiwgIlNlcCIsICJPY3QiLCAiTm92IiwgIkRlYyIKKyAgICB9OworCisgICAgLy8gQSBHcmVnb3JpYW5DYWxlbmRhciBvYmplY3QgaW4gdGhlIGN1cnJlbnQgdGltZXpvbmUKKyAgICBwcm90ZWN0ZWQgQ2FsZW5kYXIgY2FsID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKCk7CisKKyAgICBwcm90ZWN0ZWQgU3RyaW5nIHRvSU1BUERhdGUoRGF0ZSBkYXRlKSB7CisJU3RyaW5nQnVpbGRlciBzID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKworCWNhbC5zZXRUaW1lKGRhdGUpOworCisJcy5hcHBlbmQoY2FsLmdldChDYWxlbmRhci5EQVRFKSkuYXBwZW5kKCItIik7CisJcy5hcHBlbmQobW9udGhUYWJsZVtjYWwuZ2V0KENhbGVuZGFyLk1PTlRIKV0pLmFwcGVuZCgnLScpOworCXMuYXBwZW5kKGNhbC5nZXQoQ2FsZW5kYXIuWUVBUikpOworCisJcmV0dXJuIHMudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgQXJndW1lbnQgc2VudGRhdGUoRGF0ZVRlcm0gdGVybSkgCisJCQl0aHJvd3MgU2VhcmNoRXhjZXB0aW9uIHsKKwlBcmd1bWVudCByZXN1bHQgPSBuZXcgQXJndW1lbnQoKTsKKwlTdHJpbmcgZGF0ZSA9IHRvSU1BUERhdGUodGVybS5nZXREYXRlKCkpOworCisJc3dpdGNoICh0ZXJtLmdldENvbXBhcmlzb24oKSkgeworCSAgICBjYXNlIENvbXBhcmlzb25UZXJtLkdUOgorCQlyZXN1bHQud3JpdGVBdG9tKCJOT1QgU0VOVE9OICIgKyBkYXRlICsgIiBTRU5UU0lOQ0UgIiArIGRhdGUpOworCQlicmVhazsKKwkgICAgY2FzZSBDb21wYXJpc29uVGVybS5FUToKKwkJcmVzdWx0LndyaXRlQXRvbSgiU0VOVE9OICIgKyBkYXRlKTsKKwkJYnJlYWs7CisJICAgIGNhc2UgQ29tcGFyaXNvblRlcm0uTFQ6CisJCXJlc3VsdC53cml0ZUF0b20oIlNFTlRCRUZPUkUgIiArIGRhdGUpOworCQlicmVhazsKKwkgICAgY2FzZSBDb21wYXJpc29uVGVybS5HRToKKwkJcmVzdWx0LndyaXRlQXRvbSgiU0VOVFNJTkNFICIgKyBkYXRlKTsKKwkJYnJlYWs7CisJICAgIGNhc2UgQ29tcGFyaXNvblRlcm0uTEU6CisJCXJlc3VsdC53cml0ZUF0b20oIk9SIFNFTlRCRUZPUkUgIiArIGRhdGUgKyAiIFNFTlRPTiAiICsgZGF0ZSk7CisJCWJyZWFrOworCSAgICBjYXNlIENvbXBhcmlzb25UZXJtLk5FOgorCQlyZXN1bHQud3JpdGVBdG9tKCJOT1QgU0VOVE9OICIgKyBkYXRlKTsKKwkJYnJlYWs7CisJICAgIGRlZmF1bHQ6CisJICAgIAl0aHJvdyBuZXcgU2VhcmNoRXhjZXB0aW9uKCJDYW5ub3QgaGFuZGxlIERhdGUgQ29tcGFyaXNvbiIpOworCX0KKworCXJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHJvdGVjdGVkIEFyZ3VtZW50IHJlY2VpdmVkZGF0ZShEYXRlVGVybSB0ZXJtKSAKKwkJCXRocm93cyBTZWFyY2hFeGNlcHRpb24geworCUFyZ3VtZW50IHJlc3VsdCA9IG5ldyBBcmd1bWVudCgpOworCVN0cmluZyBkYXRlID0gdG9JTUFQRGF0ZSh0ZXJtLmdldERhdGUoKSk7CisKKwlzd2l0Y2ggKHRlcm0uZ2V0Q29tcGFyaXNvbigpKSB7CisJICAgIGNhc2UgQ29tcGFyaXNvblRlcm0uR1Q6CisJCXJlc3VsdC53cml0ZUF0b20oIk5PVCBPTiAiICsgZGF0ZSArICIgU0lOQ0UgIiArIGRhdGUpOworCQlicmVhazsKKwkgICAgY2FzZSBDb21wYXJpc29uVGVybS5FUToKKwkJcmVzdWx0LndyaXRlQXRvbSgiT04gIiArIGRhdGUpOworCQlicmVhazsKKwkgICAgY2FzZSBDb21wYXJpc29uVGVybS5MVDoKKwkJcmVzdWx0LndyaXRlQXRvbSgiQkVGT1JFICIgKyBkYXRlKTsKKwkJYnJlYWs7CisJICAgIGNhc2UgQ29tcGFyaXNvblRlcm0uR0U6CisJCXJlc3VsdC53cml0ZUF0b20oIlNJTkNFICIgKyBkYXRlKTsKKwkJYnJlYWs7CisJICAgIGNhc2UgQ29tcGFyaXNvblRlcm0uTEU6CisJCXJlc3VsdC53cml0ZUF0b20oIk9SIEJFRk9SRSAiICsgZGF0ZSArICIgT04gIiArIGRhdGUpOworCQlicmVhazsKKwkgICAgY2FzZSBDb21wYXJpc29uVGVybS5ORToKKwkJcmVzdWx0LndyaXRlQXRvbSgiTk9UIE9OICIgKyBkYXRlKTsKKwkJYnJlYWs7CisJICAgIGRlZmF1bHQ6CisJICAgIAl0aHJvdyBuZXcgU2VhcmNoRXhjZXB0aW9uKCJDYW5ub3QgaGFuZGxlIERhdGUgQ29tcGFyaXNvbiIpOworCX0KKworCXJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2VuZXJhdGUgYXJndW1lbnQgZm9yIE9sZGVyVGVybS4KKyAgICAgKgorICAgICAqIEBwYXJhbQl0ZXJtCXRoZSBzZWFyY2ggdGVybQorICAgICAqIEByZXR1cm4JCXRoZSBTRUFSQ0ggQXJndW1lbnQKKyAgICAgKiBAZXhjZXB0aW9uCVNlYXJjaEV4Y2VwdGlvbglmb3IgZmFpbHVyZXMKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS41LjEKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQXJndW1lbnQgb2xkZXIoT2xkZXJUZXJtIHRlcm0pIHRocm93cyBTZWFyY2hFeGNlcHRpb24geworCWlmIChwcm90b2NvbCAhPSBudWxsICYmICFwcm90b2NvbC5oYXNDYXBhYmlsaXR5KCJXSVRISU4iKSkKKwkgICAgdGhyb3cgbmV3IFNlYXJjaEV4Y2VwdGlvbigiU2VydmVyIGRvZXNuJ3Qgc3VwcG9ydCBPTERFUiBzZWFyY2hlcyIpOworCUFyZ3VtZW50IHJlc3VsdCA9IG5ldyBBcmd1bWVudCgpOworCXJlc3VsdC53cml0ZUF0b20oIk9MREVSIik7CisJcmVzdWx0LndyaXRlTnVtYmVyKHRlcm0uZ2V0SW50ZXJ2YWwoKSk7CisJcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZW5lcmF0ZSBhcmd1bWVudCBmb3IgWW91bmdlclRlcm0uCisgICAgICoKKyAgICAgKiBAcGFyYW0JdGVybQl0aGUgc2VhcmNoIHRlcm0KKyAgICAgKiBAcmV0dXJuCQl0aGUgU0VBUkNIIEFyZ3VtZW50CisgICAgICogQGV4Y2VwdGlvbglTZWFyY2hFeGNlcHRpb24JZm9yIGZhaWx1cmVzCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNS4xCisgICAgICovCisgICAgcHJvdGVjdGVkIEFyZ3VtZW50IHlvdW5nZXIoWW91bmdlclRlcm0gdGVybSkgdGhyb3dzIFNlYXJjaEV4Y2VwdGlvbiB7CisJaWYgKHByb3RvY29sICE9IG51bGwgJiYgIXByb3RvY29sLmhhc0NhcGFiaWxpdHkoIldJVEhJTiIpKQorCSAgICB0aHJvdyBuZXcgU2VhcmNoRXhjZXB0aW9uKCJTZXJ2ZXIgZG9lc24ndCBzdXBwb3J0IFlPVU5HRVIgc2VhcmNoZXMiKTsKKwlBcmd1bWVudCByZXN1bHQgPSBuZXcgQXJndW1lbnQoKTsKKwlyZXN1bHQud3JpdGVBdG9tKCJZT1VOR0VSIik7CisJcmVzdWx0LndyaXRlTnVtYmVyKHRlcm0uZ2V0SW50ZXJ2YWwoKSk7CisJcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZW5lcmF0ZSBhcmd1bWVudCBmb3IgTW9kaWZpZWRTaW5jZVRlcm0uCisgICAgICoKKyAgICAgKiBAcGFyYW0JdGVybQl0aGUgc2VhcmNoIHRlcm0KKyAgICAgKiBAcmV0dXJuCQl0aGUgU0VBUkNIIEFyZ3VtZW50CisgICAgICogQGV4Y2VwdGlvbglTZWFyY2hFeGNlcHRpb24JZm9yIGZhaWx1cmVzCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNS4xCisgICAgICovCisgICAgcHJvdGVjdGVkIEFyZ3VtZW50IG1vZGlmaWVkU2luY2UoTW9kaWZpZWRTaW5jZVRlcm0gdGVybSkKKwkJCQl0aHJvd3MgU2VhcmNoRXhjZXB0aW9uIHsKKwlpZiAocHJvdG9jb2wgIT0gbnVsbCAmJiAhcHJvdG9jb2wuaGFzQ2FwYWJpbGl0eSgiQ09ORFNUT1JFIikpCisJICAgIHRocm93IG5ldyBTZWFyY2hFeGNlcHRpb24oIlNlcnZlciBkb2Vzbid0IHN1cHBvcnQgTU9EU0VRIHNlYXJjaGVzIik7CisJQXJndW1lbnQgcmVzdWx0ID0gbmV3IEFyZ3VtZW50KCk7CisJcmVzdWx0LndyaXRlQXRvbSgiTU9EU0VRIik7CisJcmVzdWx0LndyaXRlTnVtYmVyKHRlcm0uZ2V0TW9kU2VxKCkpOworCXJldHVybiByZXN1bHQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL3Byb3RvY29sL1N0YXR1cy5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL3Byb3RvY29sL1N0YXR1cy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc2ZDI5YzMKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL2ltYXAvcHJvdG9jb2wvU3RhdHVzLmphdmEKQEAgLTAsMCArMSwxNDQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmltYXAucHJvdG9jb2w7CisKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CisKK2ltcG9ydCBjb20uc3VuLm1haWwuaWFwLio7CisKKy8qKgorICogU1RBVFVTIHJlc3BvbnNlLgorICoKKyAqIEBhdXRob3IgIEpvaG4gTWFuaQorICogQGF1dGhvciAgQmlsbCBTaGFubm9uCisgKi8KKworcHVibGljIGNsYXNzIFN0YXR1cyB7IAorICAgIHB1YmxpYyBTdHJpbmcgbWJveCA9IG51bGw7CisgICAgcHVibGljIGludCB0b3RhbCA9IC0xOworICAgIHB1YmxpYyBpbnQgcmVjZW50ID0gLTE7CisgICAgcHVibGljIGxvbmcgdWlkbmV4dCA9IC0xOworICAgIHB1YmxpYyBsb25nIHVpZHZhbGlkaXR5ID0gLTE7CisgICAgcHVibGljIGludCB1bnNlZW4gPSAtMTsKKyAgICBwdWJsaWMgbG9uZyBoaWdoZXN0bW9kc2VxID0gLTE7CisgICAgcHVibGljIE1hcDxTdHJpbmcsTG9uZz4gaXRlbXM7CS8vIGFueSB1bmtub3duIGl0ZW1zCisKKyAgICBzdGF0aWMgZmluYWwgU3RyaW5nW10gc3RhbmRhcmRJdGVtcyA9CisJeyAiTUVTU0FHRVMiLCAiUkVDRU5UIiwgIlVOU0VFTiIsICJVSURORVhUIiwgIlVJRFZBTElESVRZIiB9OworCisgICAgcHVibGljIFN0YXR1cyhSZXNwb25zZSByKSB0aHJvd3MgUGFyc2luZ0V4Y2VwdGlvbiB7CisJLy8gbWFpbGJveCA6PSBhc3RyaW5nCisJbWJveCA9IHIucmVhZEF0b21TdHJpbmcoKTsKKwlpZiAoIXIuc3VwcG9ydHNVdGY4KCkpCisJICAgIG1ib3ggPSBCQVNFNjRNYWlsYm94RGVjb2Rlci5kZWNvZGUobWJveCk7CisKKwkvLyBXb3JrYXJvdW5kIGJ1Z2d5IElNQVAgc2VydmVycyB0aGF0IGRvbid0IHF1b3RlIGZvbGRlciBuYW1lcworCS8vIHdpdGggc3BhY2VzLgorCWZpbmFsIFN0cmluZ0J1aWxkZXIgYnVmZmVyID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKwlib29sZWFuIG9ubHlTcGFjZXMgPSB0cnVlOworCisJd2hpbGUgKHIucGVla0J5dGUoKSAhPSAnKCcgJiYgci5wZWVrQnl0ZSgpICE9IDApIHsKKwkgICAgZmluYWwgY2hhciBuZXh0ID0gKGNoYXIpci5yZWFkQnl0ZSgpOworCisJICAgIGJ1ZmZlci5hcHBlbmQobmV4dCk7CisKKwkgICAgaWYgKG5leHQgIT0gJyAnKSB7CisJCW9ubHlTcGFjZXMgPSBmYWxzZTsKKwkgICAgfQorCX0KKworCWlmICghb25seVNwYWNlcykgeworCSAgICBtYm94ID0gKG1ib3ggKyBidWZmZXIpLnRyaW0oKTsKKwl9CisKKwlpZiAoci5yZWFkQnl0ZSgpICE9ICcoJykKKwkgICAgdGhyb3cgbmV3IFBhcnNpbmdFeGNlcHRpb24oInBhcnNlIGVycm9yIGluIFNUQVRVUyIpOworCQorCWRvIHsKKwkgICAgU3RyaW5nIGF0dHIgPSByLnJlYWRBdG9tKCk7CisJICAgIGlmIChhdHRyID09IG51bGwpCisJCXRocm93IG5ldyBQYXJzaW5nRXhjZXB0aW9uKCJwYXJzZSBlcnJvciBpbiBTVEFUVVMiKTsKKwkgICAgaWYgKGF0dHIuZXF1YWxzSWdub3JlQ2FzZSgiTUVTU0FHRVMiKSkKKwkJdG90YWwgPSByLnJlYWROdW1iZXIoKTsKKwkgICAgZWxzZSBpZiAoYXR0ci5lcXVhbHNJZ25vcmVDYXNlKCJSRUNFTlQiKSkKKwkJcmVjZW50ID0gci5yZWFkTnVtYmVyKCk7CisJICAgIGVsc2UgaWYgKGF0dHIuZXF1YWxzSWdub3JlQ2FzZSgiVUlETkVYVCIpKQorCQl1aWRuZXh0ID0gci5yZWFkTG9uZygpOworCSAgICBlbHNlIGlmIChhdHRyLmVxdWFsc0lnbm9yZUNhc2UoIlVJRFZBTElESVRZIikpCisJCXVpZHZhbGlkaXR5ID0gci5yZWFkTG9uZygpOworCSAgICBlbHNlIGlmIChhdHRyLmVxdWFsc0lnbm9yZUNhc2UoIlVOU0VFTiIpKQorCQl1bnNlZW4gPSByLnJlYWROdW1iZXIoKTsKKwkgICAgZWxzZSBpZiAoYXR0ci5lcXVhbHNJZ25vcmVDYXNlKCJISUdIRVNUTU9EU0VRIikpCisJCWhpZ2hlc3Rtb2RzZXEgPSByLnJlYWRMb25nKCk7CisJICAgIGVsc2UgeworCQlpZiAoaXRlbXMgPT0gbnVsbCkKKwkJICAgIGl0ZW1zID0gbmV3IEhhc2hNYXA8PigpOworCQlpdGVtcy5wdXQoYXR0ci50b1VwcGVyQ2FzZShMb2NhbGUuRU5HTElTSCksCisJCQkgICAgTG9uZy52YWx1ZU9mKHIucmVhZExvbmcoKSkpOworCSAgICB9CisJfSB3aGlsZSAoIXIuaXNOZXh0Tm9uU3BhY2UoJyknKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIFNUQVRVUyBpdGVtLgorICAgICAqCisgICAgICogQHBhcmFtCWl0ZW0JdGhlIFNUQVRVUyBpdGVtCisgICAgICogQHJldHVybgkJdGhlIHZhbHVlCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNS4yCisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0SXRlbShTdHJpbmcgaXRlbSkgeworCWl0ZW0gPSBpdGVtLnRvVXBwZXJDYXNlKExvY2FsZS5FTkdMSVNIKTsKKwlMb25nIHY7CisJbG9uZyByZXQgPSAtMTsKKwlpZiAoaXRlbXMgIT0gbnVsbCAmJiAodiA9IGl0ZW1zLmdldChpdGVtKSkgIT0gbnVsbCkKKwkgICAgcmV0ID0gdi5sb25nVmFsdWUoKTsKKwllbHNlIGlmIChpdGVtLmVxdWFscygiTUVTU0FHRVMiKSkKKwkgICAgcmV0ID0gdG90YWw7CisJZWxzZSBpZiAoaXRlbS5lcXVhbHMoIlJFQ0VOVCIpKQorCSAgICByZXQgPSByZWNlbnQ7CisJZWxzZSBpZiAoaXRlbS5lcXVhbHMoIlVJRE5FWFQiKSkKKwkgICAgcmV0ID0gdWlkbmV4dDsKKwllbHNlIGlmIChpdGVtLmVxdWFscygiVUlEVkFMSURJVFkiKSkKKwkgICAgcmV0ID0gdWlkdmFsaWRpdHk7CisJZWxzZSBpZiAoaXRlbS5lcXVhbHMoIlVOU0VFTiIpKQorCSAgICByZXQgPSB1bnNlZW47CisJZWxzZSBpZiAoaXRlbS5lcXVhbHMoIkhJR0hFU1RNT0RTRVEiKSkKKwkgICAgcmV0ID0gaGlnaGVzdG1vZHNlcTsKKwlyZXR1cm4gcmV0OworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBhZGQoU3RhdHVzIHMxLCBTdGF0dXMgczIpIHsKKwlpZiAoczIudG90YWwgIT0gLTEpCisJICAgIHMxLnRvdGFsID0gczIudG90YWw7CisJaWYgKHMyLnJlY2VudCAhPSAtMSkKKwkgICAgczEucmVjZW50ID0gczIucmVjZW50OworCWlmIChzMi51aWRuZXh0ICE9IC0xKQorCSAgICBzMS51aWRuZXh0ID0gczIudWlkbmV4dDsKKwlpZiAoczIudWlkdmFsaWRpdHkgIT0gLTEpCisJICAgIHMxLnVpZHZhbGlkaXR5ID0gczIudWlkdmFsaWRpdHk7CisJaWYgKHMyLnVuc2VlbiAhPSAtMSkKKwkgICAgczEudW5zZWVuID0gczIudW5zZWVuOworCWlmIChzMi5oaWdoZXN0bW9kc2VxICE9IC0xKQorCSAgICBzMS5oaWdoZXN0bW9kc2VxID0gczIuaGlnaGVzdG1vZHNlcTsKKwlpZiAoczEuaXRlbXMgPT0gbnVsbCkKKwkgICAgczEuaXRlbXMgPSBzMi5pdGVtczsKKwllbHNlIGlmIChzMi5pdGVtcyAhPSBudWxsKQorCSAgICBzMS5pdGVtcy5wdXRBbGwoczIuaXRlbXMpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9VSUQuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9VSUQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ODA4MmMyCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL3Byb3RvY29sL1VJRC5qYXZhCkBAIC0wLDAgKzEsNDUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmltYXAucHJvdG9jb2w7CisKK2ltcG9ydCBjb20uc3VuLm1haWwuaWFwLio7IAorCisvKioKKyAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyB0aGUgVUlEIGRhdGEgaXRlbS4KKyAqCisgKiBAYXV0aG9yICBKb2huIE1hbmkKKyAqLworCitwdWJsaWMgY2xhc3MgVUlEIGltcGxlbWVudHMgSXRlbSB7CisgICAgCisgICAgc3RhdGljIGZpbmFsIGNoYXJbXSBuYW1lID0geydVJywnSScsJ0QnfTsKKyAgICBwdWJsaWMgaW50IHNlcW51bTsKKworICAgIHB1YmxpYyBsb25nIHVpZDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yLgorICAgICAqCisgICAgICogQHBhcmFtCXIJdGhlIEZldGNoUmVzcG9uc2UKKyAgICAgKiBAZXhjZXB0aW9uCVBhcnNpbmdFeGNlcHRpb24JZm9yIHBhcnNpbmcgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgVUlEKEZldGNoUmVzcG9uc2UgcikgdGhyb3dzIFBhcnNpbmdFeGNlcHRpb24geworCXNlcW51bSA9IHIuZ2V0TnVtYmVyKCk7CisJci5za2lwU3BhY2VzKCk7CisJdWlkID0gci5yZWFkTG9uZygpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9VSURTZXQuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9VSURTZXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMjI4NTgxCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL3Byb3RvY29sL1VJRFNldC5qYXZhCkBAIC0wLDAgKzEsMjM1IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5pbWFwLnByb3RvY29sOworCitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyOworCisvKioKKyAqIFRoaXMgY2xhc3MgaG9sZHMgdGhlICdzdGFydCcgYW5kICdlbmQnIGZvciBhIHJhbmdlIG9mIFVJRHMuCisgKiBKdXN0IGxpa2UgTWVzc2FnZVNldCBleGNlcHQgdXNpbmcgbG9uZyBpbnN0ZWFkIG9mIGludC4KKyAqLworcHVibGljIGNsYXNzIFVJRFNldCB7CisKKyAgICBwdWJsaWMgbG9uZyBzdGFydDsKKyAgICBwdWJsaWMgbG9uZyBlbmQ7CisKKyAgICBwdWJsaWMgVUlEU2V0KCkgeyB9CisKKyAgICBwdWJsaWMgVUlEU2V0KGxvbmcgc3RhcnQsIGxvbmcgZW5kKSB7CisJdGhpcy5zdGFydCA9IHN0YXJ0OworCXRoaXMuZW5kID0gZW5kOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvdW50IHRoZSB0b3RhbCBudW1iZXIgb2YgZWxlbWVudHMgaW4gYSBVSURTZXQKKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIG51bWJlciBvZiBlbGVtZW50cworICAgICAqLworICAgIHB1YmxpYyBsb25nIHNpemUoKSB7CisJcmV0dXJuIGVuZCAtIHN0YXJ0ICsgMTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0IGFuIGFycmF5IG9mIGxvbmdzIGludG8gYW4gYXJyYXkgb2YgVUlEU2V0cworICAgICAqCisgICAgICogQHBhcmFtCXVpZHMJdGhlIFVJRHMKKyAgICAgKiBAcmV0dXJuCQlhcnJheSBvZiBVSURTZXQgb2JqZWN0cworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgVUlEU2V0W10gY3JlYXRlVUlEU2V0cyhsb25nW10gdWlkcykgeworCWlmICh1aWRzID09IG51bGwpCisJICAgIHJldHVybiBudWxsOworCUxpc3Q8VUlEU2V0PiB2ID0gbmV3IEFycmF5TGlzdDw+KCk7CisJaW50IGksajsKKworCWZvciAoaT0wOyBpIDwgdWlkcy5sZW5ndGg7IGkrKykgeworCSAgICBVSURTZXQgbXMgPSBuZXcgVUlEU2V0KCk7CisJICAgIG1zLnN0YXJ0ID0gdWlkc1tpXTsKKworCSAgICAvLyBMb29rIGZvciBjb250aWd1b3VzIGVsZW1lbnRzCisJICAgIGZvciAoaj1pKzE7IGogPCB1aWRzLmxlbmd0aDsgaisrKSB7CisJCWlmICh1aWRzW2pdICE9IHVpZHNbai0xXSArMSkKKwkJICAgIGJyZWFrOworCSAgICB9CisJICAgIG1zLmVuZCA9IHVpZHNbai0xXTsKKwkgICAgdi5hZGQobXMpOworCSAgICBpID0gai0xOyAvLyBpIGdldHMgaW5jcmVtZW50ZWQgQCB0b3Agb2YgdGhlIGxvb3AKKwl9CisJVUlEU2V0W10gdWlkc2V0ID0gbmV3IFVJRFNldFt2LnNpemUoKV07CQorCXJldHVybiB2LnRvQXJyYXkodWlkc2V0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZSBhIHN0cmluZyBpbiBJTUFQIFVJRCByYW5nZSBmb3JtYXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0JdWlkcwlVSUQgc3RyaW5nCisgICAgICogQHJldHVybgkJYXJyYXkgb2YgVUlEU2V0IG9iamVjdHMKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS41LjEKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFVJRFNldFtdIHBhcnNlVUlEU2V0cyhTdHJpbmcgdWlkcykgeworCWlmICh1aWRzID09IG51bGwpCisJICAgIHJldHVybiBudWxsOworCUxpc3Q8VUlEU2V0PiB2ID0gbmV3IEFycmF5TGlzdDw+KCk7CisJU3RyaW5nVG9rZW5pemVyIHN0ID0gbmV3IFN0cmluZ1Rva2VuaXplcih1aWRzLCAiLDoiLCB0cnVlKTsKKwlsb25nIHN0YXJ0ID0gLTE7CisJVUlEU2V0IGN1ciA9IG51bGw7CisJdHJ5IHsKKwkgICAgd2hpbGUoc3QuaGFzTW9yZVRva2VucygpKSB7CisJCVN0cmluZyBzID0gc3QubmV4dFRva2VuKCk7CisJCWlmIChzLmVxdWFscygiLCIpKSB7CisJCSAgICBpZiAoY3VyICE9IG51bGwpCisJCQl2LmFkZChjdXIpOworCQkgICAgY3VyID0gbnVsbDsKKwkJfSBlbHNlIGlmIChzLmVxdWFscygiOiIpKSB7CisJCSAgICAvLyBub3RoaW5nIHRvIGRvLCB3YWl0IGZvciBuZXh0IG51bWJlcgorCQl9IGVsc2UgewkvLyBiZXR0ZXIgYmUgYSBudW1iZXIKKwkJICAgIGxvbmcgbiA9IExvbmcucGFyc2VMb25nKHMpOworCQkgICAgaWYgKGN1ciAhPSBudWxsKQorCQkJY3VyLmVuZCA9IG47CisJCSAgICBlbHNlCisJCQljdXIgPSBuZXcgVUlEU2V0KG4sIG4pOworCQl9CisJICAgIH0KKwl9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gbmV4KSB7CisJICAgIC8vIGdpdmUgdXAgYW5kIHJldHVybiB3aGF0IHdlIGhhdmUgc28gZmFyCisJfQorCWlmIChjdXIgIT0gbnVsbCkKKwkgICAgdi5hZGQoY3VyKTsKKwlVSURTZXRbXSB1aWRzZXQgPSBuZXcgVUlEU2V0W3Yuc2l6ZSgpXTsKKwlyZXR1cm4gdi50b0FycmF5KHVpZHNldCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydCBhbiBhcnJheSBvZiBVSURTZXRzIGludG8gYW4gSU1BUCBzZXF1ZW5jZSByYW5nZS4KKyAgICAgKgorICAgICAqIEBwYXJhbQl1aWRzZXQJdGhlIFVJRFNldHMKKyAgICAgKiBAcmV0dXJuCQl0aGUgSU1BUCBzZXF1ZW5jZSBzdHJpbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyB0b1N0cmluZyhVSURTZXRbXSB1aWRzZXQpIHsKKwlpZiAodWlkc2V0ID09IG51bGwpCisJICAgIHJldHVybiBudWxsOworCWlmICh1aWRzZXQubGVuZ3RoID09IDApIC8vIEVtcHR5IHVpZHNldAorCSAgICByZXR1cm4gIiI7CisKKwlpbnQgaSA9IDA7ICAvLyB1aWRzZXQgaW5kZXgKKwlTdHJpbmdCdWlsZGVyIHMgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworCWludCBzaXplID0gdWlkc2V0Lmxlbmd0aDsKKwlsb25nIHN0YXJ0LCBlbmQ7CisKKwlmb3IgKDs7KSB7CisJICAgIHN0YXJ0ID0gdWlkc2V0W2ldLnN0YXJ0OworCSAgICBlbmQgPSB1aWRzZXRbaV0uZW5kOworCisJICAgIGlmIChlbmQgPiBzdGFydCkKKwkJcy5hcHBlbmQoc3RhcnQpLmFwcGVuZCgnOicpLmFwcGVuZChlbmQpOworCSAgICBlbHNlIC8vIGVuZCA9PSBzdGFydCBtZWFucyBvbmx5IG9uZSBlbGVtZW50CisJCXMuYXBwZW5kKHN0YXJ0KTsKKwkKKwkgICAgaSsrOyAvLyBOZXh0IFVJRFNldAorCSAgICBpZiAoaSA+PSBzaXplKSAvLyBObyBtb3JlIFVJRFNldHMKKwkJYnJlYWs7CisJICAgIGVsc2UKKwkJcy5hcHBlbmQoJywnKTsKKwl9CisJcmV0dXJuIHMudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0IGFuIGFycmF5IG9mIFVJRFNldHMgaW50byBhIGFycmF5IG9mIGxvbmcgVUlEcy4KKyAgICAgKgorICAgICAqIEBwYXJhbQl1aWRzZXQJdGhlIFVJRFNldHMKKyAgICAgKiBAcmV0dXJuCQlhcnJyYXkgb2YgVUlEcworICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjUuMQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgbG9uZ1tdIHRvQXJyYXkoVUlEU2V0W10gdWlkc2V0KSB7CisJLy9yZXR1cm4gdG9BcnJheSh1aWRzZXQsIC0xKTsKKwlpZiAodWlkc2V0ID09IG51bGwpCisJICAgIHJldHVybiBudWxsOworCWxvbmdbXSB1aWRzID0gbmV3IGxvbmdbKGludClVSURTZXQuc2l6ZSh1aWRzZXQpXTsKKwlpbnQgaSA9IDA7CisJZm9yIChVSURTZXQgdSA6IHVpZHNldCkgeworCSAgICBmb3IgKGxvbmcgbiA9IHUuc3RhcnQ7IG4gPD0gdS5lbmQ7IG4rKykKKwkJdWlkc1tpKytdID0gbjsKKwl9CisJcmV0dXJuIHVpZHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydCBhbiBhcnJheSBvZiBVSURTZXRzIGludG8gYSBhcnJheSBvZiBsb25nIFVJRHMuCisgICAgICogRG9uJ3QgaW5jbHVkZSBhbnkgVUlEcyBsYXJnZXIgdGhhbiB1aWRtYXguCisgICAgICoKKyAgICAgKiBAcGFyYW0JdWlkc2V0CXRoZSBVSURTZXRzCisgICAgICogQHBhcmFtCXVpZG1heAltYXhpbXVtIFVJRAorICAgICAqIEByZXR1cm4JCWFycnJheSBvZiBVSURzCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNS4xCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBsb25nW10gdG9BcnJheShVSURTZXRbXSB1aWRzZXQsIGxvbmcgdWlkbWF4KSB7CisJaWYgKHVpZHNldCA9PSBudWxsKQorCSAgICByZXR1cm4gbnVsbDsKKwlsb25nW10gdWlkcyA9IG5ldyBsb25nWyhpbnQpVUlEU2V0LnNpemUodWlkc2V0LCB1aWRtYXgpXTsKKwlpbnQgaSA9IDA7CisJZm9yIChVSURTZXQgdSA6IHVpZHNldCkgeworCSAgICBmb3IgKGxvbmcgbiA9IHUuc3RhcnQ7IG4gPD0gdS5lbmQ7IG4rKykgeworCQlpZiAodWlkbWF4ID49IDAgJiYgbiA+IHVpZG1heCkKKwkJICAgIGJyZWFrOworCQl1aWRzW2krK10gPSBuOworCSAgICB9CisJfQorCXJldHVybiB1aWRzOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvdW50IHRoZSB0b3RhbCBudW1iZXIgb2YgZWxlbWVudHMgaW4gYW4gYXJyYXkgb2YgVUlEU2V0cy4KKyAgICAgKgorICAgICAqIEBwYXJhbQl1aWRzZXQJdGhlIFVJRFNldHMKKyAgICAgKiBAcmV0dXJuCQl0aGUgbnVtYmVyIG9mIGVsZW1lbnRzCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBsb25nIHNpemUoVUlEU2V0W10gdWlkc2V0KSB7CisJbG9uZyBjb3VudCA9IDA7CisKKwlpZiAodWlkc2V0ICE9IG51bGwpCisJICAgIGZvciAoVUlEU2V0IHUgOiB1aWRzZXQpCisJCWNvdW50ICs9IHUuc2l6ZSgpOworCQorCXJldHVybiBjb3VudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb3VudCB0aGUgdG90YWwgbnVtYmVyIG9mIGVsZW1lbnRzIGluIGFuIGFycmF5IG9mIFVJRFNldHMuCisgICAgICogRG9uJ3QgY291bnQgVUlEcyBncmVhdGVyIHRoZW4gdWlkbWF4LgorICAgICAqCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNS4xCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgbG9uZyBzaXplKFVJRFNldFtdIHVpZHNldCwgbG9uZyB1aWRtYXgpIHsKKwlsb25nIGNvdW50ID0gMDsKKworCWlmICh1aWRzZXQgIT0gbnVsbCkKKwkgICAgZm9yIChVSURTZXQgdSA6IHVpZHNldCkgeworCQlpZiAodWlkbWF4IDwgMCkKKwkJICAgIGNvdW50ICs9IHUuc2l6ZSgpOworCQllbHNlIGlmICh1LnN0YXJ0IDw9IHVpZG1heCkgeworCQkgICAgaWYgKHUuZW5kIDwgdWlkbWF4KQorCQkJY291bnQgKz0gdS5lbmQgLSB1LnN0YXJ0ICsgMTsKKwkJICAgIGVsc2UKKwkJCWNvdW50ICs9IHVpZG1heCAtIHUuc3RhcnQgKyAxOworCQl9CisJICAgIH0KKwkKKwlyZXR1cm4gY291bnQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL3Byb3RvY29sL3BhY2thZ2UuaHRtbCBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9wYWNrYWdlLmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzcwNzI2ZQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9wYWNrYWdlLmh0bWwKQEAgLTAsMCArMSwzMyBAQAorPCFET0NUWVBFIGh0bWwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMDEgVHJhbnNpdGlvbmFsLy9FTiI+Cis8SFRNTD4KKzxIRUFEPgorPG1ldGEgaHR0cC1lcXVpdj0iQ29udGVudC1UeXBlIiBjb250ZW50PSJ0ZXh0L2h0bWw7IGNoYXJzZXQ9dXRmLTgiPgorPCEtLQorCisgICAgQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisKKyAgICBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAgICB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKworICAgIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAgICBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgICAgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgICAgdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisKKyAgICBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKworLS0+CisKKzxUSVRMRT5jb20uc3VuLm1haWwuaW1hcC5wcm90b2NvbCBwYWNrYWdlPC9USVRMRT4KKzwvSEVBRD4KKzxCT0RZIEJHQ09MT1I9IndoaXRlIj4KKworPFA+CitUaGlzIHBhY2thZ2UgaW5jbHVkZXMgaW50ZXJuYWwgSU1BUCBzdXBwb3J0IGNsYXNzZXMgYW5kCis8c3Ryb25nPlNIT1VMRCBOT1QgQkUgVVNFRCBESVJFQ1RMWSBCWSBBUFBMSUNBVElPTlM8L3N0cm9uZz4uCis8L1A+CisKKzwvQk9EWT4KKzwvSFRNTD4KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvcG9wMy9BcHBlbmRTdHJlYW0uamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvcG9wMy9BcHBlbmRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jYzU2Y2UzCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9wb3AzL0FwcGVuZFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsNjcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMTAsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLnBvcDM7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5SYW5kb21BY2Nlc3NGaWxlOworCisvKioKKyAqIEEgc3RyZWFtIGZvciB3cml0aW5nIHRvIHRoZSB0ZW1wIGZpbGUsIGFuZCB3aGVuIGRvbmUgY2FuIHJldHVybiBhIHN0cmVhbSBmb3IKKyAqIHJlYWRpbmcgdGhlIGRhdGEganVzdCB3cml0dGVuLiBOT1RFOiBXZSBhc3N1bWUgdGhhdCBvbmx5IG9uZSB0aHJlYWQgaXMKKyAqIHdyaXRpbmcgdG8gdGhlIGZpbGUgYXQgYSB0aW1lLgorICovCitjbGFzcyBBcHBlbmRTdHJlYW0gZXh0ZW5kcyBPdXRwdXRTdHJlYW0geworCisgICAgcHJpdmF0ZSBmaW5hbCBXcml0YWJsZVNoYXJlZEZpbGUgdGY7CisgICAgcHJpdmF0ZSBSYW5kb21BY2Nlc3NGaWxlIHJhZjsKKyAgICBwcml2YXRlIGZpbmFsIGxvbmcgc3RhcnQ7CisgICAgcHJpdmF0ZSBsb25nIGVuZDsKKworICAgIHB1YmxpYyBBcHBlbmRTdHJlYW0oV3JpdGFibGVTaGFyZWRGaWxlIHRmKSB0aHJvd3MgSU9FeGNlcHRpb24geworCXRoaXMudGYgPSB0ZjsKKwlyYWYgPSB0Zi5nZXRXcml0YWJsZUZpbGUoKTsKKwlzdGFydCA9IHJhZi5sZW5ndGgoKTsKKwlyYWYuc2VlayhzdGFydCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoaW50IGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJcmFmLndyaXRlKGIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGJ5dGVbXSBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworCXJhZi53cml0ZShiKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlyYWYud3JpdGUoYiwgb2ZmLCBsZW4pOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJZW5kID0gdGYudXBkYXRlTGVuZ3RoKCk7CisJcmFmID0gbnVsbDsJLy8gbm8gbW9yZSB3cml0aW5nIGFsbG93ZWQKKyAgICB9CisKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIElucHV0U3RyZWFtIGdldElucHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlyZXR1cm4gdGYubmV3U3RyZWFtKHN0YXJ0LCBlbmQpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvcG9wMy9EZWZhdWx0Rm9sZGVyLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3BvcDMvRGVmYXVsdEZvbGRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVhZjlkNjMKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3BvcDMvRGVmYXVsdEZvbGRlci5qYXZhCkBAIC0wLDAgKzEsMTQxIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5wb3AzOworCitpbXBvcnQgamF2YXgubWFpbC4qOworCisvKioKKyAqIFRoZSBQT1AzIERlZmF1bHRGb2xkZXIuICBPbmx5IGNvbnRhaW5zIHRoZSAiSU5CT1giIGZvbGRlci4KKyAqCisgKiBAYXV0aG9yIENocmlzdG9waGVyIENvdHRvbgorICovCitwdWJsaWMgY2xhc3MgRGVmYXVsdEZvbGRlciBleHRlbmRzIEZvbGRlciB7CisKKyAgICBEZWZhdWx0Rm9sZGVyKFBPUDNTdG9yZSBzdG9yZSkgeworCXN1cGVyKHN0b3JlKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7CisJcmV0dXJuICIiOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0RnVsbE5hbWUoKSB7CisJcmV0dXJuICIiOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBGb2xkZXIgZ2V0UGFyZW50KCkgeworCXJldHVybiBudWxsOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGV4aXN0cygpIHsKKwlyZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRm9sZGVyW10gbGlzdChTdHJpbmcgcGF0dGVybikgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJRm9sZGVyW10gZiA9IHsgZ2V0SW5ib3goKSB9OworCXJldHVybiBmOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBjaGFyIGdldFNlcGFyYXRvcigpIHsKKwlyZXR1cm4gJy8nOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0VHlwZSgpIHsKKwlyZXR1cm4gSE9MRFNfRk9MREVSUzsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBjcmVhdGUoaW50IHR5cGUpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXdNZXNzYWdlcygpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRm9sZGVyIGdldEZvbGRlcihTdHJpbmcgbmFtZSkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKCFuYW1lLmVxdWFsc0lnbm9yZUNhc2UoIklOQk9YIikpIHsKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigib25seSBJTkJPWCBzdXBwb3J0ZWQiKTsKKwl9IGVsc2UgeworCSAgICByZXR1cm4gZ2V0SW5ib3goKTsKKwl9CisgICAgfQorCisgICAgcHJvdGVjdGVkIEZvbGRlciBnZXRJbmJveCgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXJldHVybiBnZXRTdG9yZSgpLmdldEZvbGRlcigiSU5CT1giKTsKKyAgICB9CisgICAgCisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBkZWxldGUoYm9vbGVhbiByZWN1cnNlKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwl0aHJvdyBuZXcgTWV0aG9kTm90U3VwcG9ydGVkRXhjZXB0aW9uKCJkZWxldGUiKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiByZW5hbWVUbyhGb2xkZXIgZikgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJdGhyb3cgbmV3IE1ldGhvZE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigicmVuYW1lVG8iKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBvcGVuKGludCBtb2RlKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwl0aHJvdyBuZXcgTWV0aG9kTm90U3VwcG9ydGVkRXhjZXB0aW9uKCJvcGVuIik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2UoYm9vbGVhbiBleHB1bmdlKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwl0aHJvdyBuZXcgTWV0aG9kTm90U3VwcG9ydGVkRXhjZXB0aW9uKCJjbG9zZSIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGlzT3BlbigpIHsKKwlyZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEZsYWdzIGdldFBlcm1hbmVudEZsYWdzKCkgeworCXJldHVybiBuZXcgRmxhZ3MoKTsgLy8gZW1wdHkgZmxhZ3Mgb2JqZWN0CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRNZXNzYWdlQ291bnQoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gMDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgTWVzc2FnZSBnZXRNZXNzYWdlKGludCBtc2dubykgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJdGhyb3cgbmV3IE1ldGhvZE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigiZ2V0TWVzc2FnZSIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGFwcGVuZE1lc3NhZ2VzKE1lc3NhZ2VbXSBtc2dzKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwl0aHJvdyBuZXcgTWV0aG9kTm90U3VwcG9ydGVkRXhjZXB0aW9uKCJBcHBlbmQgbm90IHN1cHBvcnRlZCIpOwkKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgTWVzc2FnZVtdIGV4cHVuZ2UoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwl0aHJvdyBuZXcgTWV0aG9kTm90U3VwcG9ydGVkRXhjZXB0aW9uKCJleHB1bmdlIik7CQorICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvcG9wMy9QT1AzRm9sZGVyLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3BvcDMvUE9QM0ZvbGRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmEwNDVhMjQKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3BvcDMvUE9QM0ZvbGRlci5qYXZhCkBAIC0wLDAgKzEsNjExIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5wb3AzOworCitpbXBvcnQgamF2YXgubWFpbC4qOworaW1wb3J0IGphdmF4Lm1haWwuZXZlbnQuKjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5FT0ZFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLlN0cmluZ1Rva2VuaXplcjsKK2ltcG9ydCBqYXZhLnV0aWwubG9nZ2luZy5MZXZlbDsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLkxpbmVJbnB1dFN0cmVhbTsKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5NYWlsTG9nZ2VyOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKKy8qKgorICogQSBQT1AzIEZvbGRlciAoY2FuIG9ubHkgYmUgIklOQk9YIikuCisgKgorICogU2VlIHRoZSA8YSBocmVmPSJwYWNrYWdlLXN1bW1hcnkuaHRtbCI+Y29tLnN1bi5tYWlsLnBvcDM8L2E+IHBhY2thZ2UKKyAqIGRvY3VtZW50YXRpb24gZm9yIGZ1cnRoZXIgaW5mb3JtYXRpb24gb24gdGhlIFBPUDMgcHJvdG9jb2wgcHJvdmlkZXIuIDxwPgorICoKKyAqIEBhdXRob3IgICAgICBCaWxsIFNoYW5ub24KKyAqIEBhdXRob3IJSm9obiBNYW5pIChwb3J0ZWQgdG8gdGhlIGphdmF4Lm1haWwgQVBJcykKKyAqLworcHVibGljIGNsYXNzIFBPUDNGb2xkZXIgZXh0ZW5kcyBGb2xkZXIgeworCisgICAgcHJpdmF0ZSBTdHJpbmcgbmFtZTsKKyAgICBwcml2YXRlIFBPUDNTdG9yZSBzdG9yZTsKKyAgICBwcml2YXRlIHZvbGF0aWxlIFByb3RvY29sIHBvcnQ7CisgICAgcHJpdmF0ZSBpbnQgdG90YWw7CisgICAgcHJpdmF0ZSBpbnQgc2l6ZTsKKyAgICBwcml2YXRlIGJvb2xlYW4gZXhpc3RzID0gZmFsc2U7CisgICAgcHJpdmF0ZSB2b2xhdGlsZSBib29sZWFuIG9wZW5lZCA9IGZhbHNlOworICAgIHByaXZhdGUgUE9QM01lc3NhZ2VbXSBtZXNzYWdlX2NhY2hlOworICAgIHByaXZhdGUgYm9vbGVhbiBkb25lVWlkbCA9IGZhbHNlOworICAgIHByaXZhdGUgdm9sYXRpbGUgVGVtcEZpbGUgZmlsZUNhY2hlID0gbnVsbDsKKyAgICBwcml2YXRlIGJvb2xlYW4gZm9yY2VDbG9zZTsKKworICAgIE1haWxMb2dnZXIgbG9nZ2VyOwkvLyBwYWNrYWdlIHByaXZhdGUsIGZvciBQT1AzTWVzc2FnZQorCisgICAgcHJvdGVjdGVkIFBPUDNGb2xkZXIoUE9QM1N0b3JlIHN0b3JlLCBTdHJpbmcgbmFtZSkgeworCXN1cGVyKHN0b3JlKTsKKwl0aGlzLm5hbWUgPSBuYW1lOworCXRoaXMuc3RvcmUgPSBzdG9yZTsKKwlpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlKCJJTkJPWCIpKQorCSAgICBleGlzdHMgPSB0cnVlOworCWxvZ2dlciA9IG5ldyBNYWlsTG9nZ2VyKHRoaXMuZ2V0Q2xhc3MoKSwgIkRFQlVHIFBPUDMiLAorCSAgICBzdG9yZS5nZXRTZXNzaW9uKCkuZ2V0RGVidWcoKSwgc3RvcmUuZ2V0U2Vzc2lvbigpLmdldERlYnVnT3V0KCkpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKKwlyZXR1cm4gbmFtZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldEZ1bGxOYW1lKCkgeworCXJldHVybiBuYW1lOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBGb2xkZXIgZ2V0UGFyZW50KCkgeworCXJldHVybiBuZXcgRGVmYXVsdEZvbGRlcihzdG9yZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWx3YXlzIHRydWUgZm9yIHRoZSBmb2xkZXIgIklOQk9YIiwgYWx3YXlzIGZhbHNlIGZvcgorICAgICAqIGFueSBvdGhlciBuYW1lLgorICAgICAqCisgICAgICogQHJldHVybgl0cnVlIGZvciBJTkJPWCwgZmFsc2Ugb3RoZXJ3aXNlCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXhpc3RzKCkgeworCXJldHVybiBleGlzdHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWx3YXlzIHRocm93cyA8Y29kZT5NZXNzYWdpbmdFeGNlcHRpb248L2NvZGU+IGJlY2F1c2Ugbm8gUE9QMyBmb2xkZXJzCisgICAgICogY2FuIGNvbnRhaW4gc3ViZm9sZGVycy4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uCWFsd2F5cworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBGb2xkZXJbXSBsaXN0KFN0cmluZyBwYXR0ZXJuKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwl0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKCJub3QgYSBkaXJlY3RvcnkiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBbHdheXMgcmV0dXJucyBhIE5VTCBjaGFyYWN0ZXIgYmVjYXVzZSBQT1AzIGRvZXNuJ3Qgc3VwcG9ydCBhIGhpZXJhcmNoeS4KKyAgICAgKgorICAgICAqIEByZXR1cm4JTlVMCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGNoYXIgZ2V0U2VwYXJhdG9yKCkgeworCXJldHVybiAnXDAnOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFsd2F5cyByZXR1cm5zIEZvbGRlci5IT0xEU19NRVNTQUdFUy4KKyAgICAgKgorICAgICAqIEByZXR1cm4JRm9sZGVyLkhPTERTX01FU1NBR0VTCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRUeXBlKCkgeworCXJldHVybiBIT0xEU19NRVNTQUdFUzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBbHdheXMgcmV0dXJucyA8Y29kZT5mYWxzZTwvY29kZT47IHRoZSBQT1AzIHByb3RvY29sIGRvZXNuJ3QKKyAgICAgKiBzdXBwb3J0IGNyZWF0aW5nIGZvbGRlcnMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCWZhbHNlCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gY3JlYXRlKGludCB0eXBlKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWx3YXlzIHJldHVybnMgPGNvZGU+ZmFsc2U8L2NvZGU+OyB0aGUgUE9QMyBwcm90b2NvbCBwcm92aWRlcworICAgICAqIG5vIHdheSB0byBkZXRlcm1pbmUgd2hlbiBhIG5ldyBtZXNzYWdlIGFycml2ZXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCWZhbHNlCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaGFzTmV3TWVzc2FnZXMoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gZmFsc2U7ICAgIC8vIG5vIHdheSB0byBrbm93CisgICAgfQorCisgICAgLyoqCisgICAgICogQWx3YXlzIHRocm93cyA8Y29kZT5NZXNzYWdpbmdFeGNlcHRpb248L2NvZGU+IGJlY2F1c2Ugbm8gUE9QMyBmb2xkZXJzCisgICAgICogY2FuIGNvbnRhaW4gc3ViZm9sZGVycy4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uCWFsd2F5cworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBGb2xkZXIgZ2V0Rm9sZGVyKFN0cmluZyBuYW1lKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwl0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKCJub3QgYSBkaXJlY3RvcnkiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBbHdheXMgdGhyb3dzIDxjb2RlPk1ldGhvZE5vdFN1cHBvcnRlZEV4Y2VwdGlvbjwvY29kZT4KKyAgICAgKiBiZWNhdXNlIHRoZSBQT1AzIHByb3RvY29sIGRvZXNuJ3QgYWxsb3cgdGhlIElOQk9YIHRvCisgICAgICogYmUgZGVsZXRlZC4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24JTWV0aG9kTm90U3VwcG9ydGVkRXhjZXB0aW9uCWFsd2F5cworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGRlbGV0ZShib29sZWFuIHJlY3Vyc2UpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXRocm93IG5ldyBNZXRob2ROb3RTdXBwb3J0ZWRFeGNlcHRpb24oImRlbGV0ZSIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFsd2F5cyB0aHJvd3MgPGNvZGU+TWV0aG9kTm90U3VwcG9ydGVkRXhjZXB0aW9uPC9jb2RlPgorICAgICAqIGJlY2F1c2UgdGhlIFBPUDMgcHJvdG9jb2wgZG9lc24ndCBzdXBwb3J0IG11bHRpcGxlIGZvbGRlcnMuCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uCU1ldGhvZE5vdFN1cHBvcnRlZEV4Y2VwdGlvbglhbHdheXMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiByZW5hbWVUbyhGb2xkZXIgZikgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJdGhyb3cgbmV3IE1ldGhvZE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigicmVuYW1lVG8iKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaHJvd3MgPGNvZGU+Rm9sZGVyTm90Rm91bmRFeGNlcHRpb248L2NvZGU+IHVubGVzcyB0aGlzCisgICAgICogZm9sZGVyIGlzIG5hbWVkICJJTkJPWCIuCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uCUZvbGRlck5vdEZvdW5kRXhjZXB0aW9uCWlmIG5vdCBJTkJPWAorICAgICAqIEBleGNlcHRpb24JQXV0aGVudGljYXRpb25GYWlsZWRFeGNlcHRpb24JYXV0aGVudGljYXRpb24gZmFpbHVyZXMKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbglvdGhlciBvcGVuIGZhaWx1cmVzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIG9wZW4oaW50IG1vZGUpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWNoZWNrQ2xvc2VkKCk7CisJaWYgKCFleGlzdHMpCisJICAgIHRocm93IG5ldyBGb2xkZXJOb3RGb3VuZEV4Y2VwdGlvbih0aGlzLCAiZm9sZGVyIGlzIG5vdCBJTkJPWCIpOworCisJdHJ5IHsKKwkgICAgcG9ydCA9IHN0b3JlLmdldFBvcnQodGhpcyk7CisJICAgIFN0YXR1cyBzID0gcG9ydC5zdGF0KCk7CisJICAgIHRvdGFsID0gcy50b3RhbDsKKwkgICAgc2l6ZSA9IHMuc2l6ZTsKKwkgICAgdGhpcy5tb2RlID0gbW9kZTsKKwkgICAgaWYgKHN0b3JlLnVzZUZpbGVDYWNoZSkgeworCQl0cnkgeworCQkgICAgZmlsZUNhY2hlID0gbmV3IFRlbXBGaWxlKHN0b3JlLmZpbGVDYWNoZURpcik7CisJCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisJCSAgICBsb2dnZXIubG9nKExldmVsLkZJTkUsICJmYWlsZWQgdG8gY3JlYXRlIGZpbGUgY2FjaGUiLCBleCk7CisJCSAgICB0aHJvdyBleDsJLy8gY2F1Z2h0IGJlbG93CisJCX0KKwkgICAgfQorCSAgICBvcGVuZWQgPSB0cnVlOworCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZXgpIHsKKwkgICAgdHJ5IHsKKwkJaWYgKHBvcnQgIT0gbnVsbCkKKwkJICAgIHBvcnQucXVpdCgpOworCSAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2V4MikgeworCQkvLyBpZ25vcmUKKwkgICAgfSBmaW5hbGx5IHsKKwkJcG9ydCA9IG51bGw7CisJCXN0b3JlLmNsb3NlUG9ydCh0aGlzKTsKKwkgICAgfQorCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKCJPcGVuIGZhaWxlZCIsIGlvZXgpOworCX0KKworCS8vIENyZWF0ZSB0aGUgbWVzc2FnZSBjYWNoZSBhcnJheSBvZiBhcHByb3ByaWF0ZSBzaXplCisJbWVzc2FnZV9jYWNoZSA9IG5ldyBQT1AzTWVzc2FnZVt0b3RhbF07CisJZG9uZVVpZGwgPSBmYWxzZTsKKworCW5vdGlmeUNvbm5lY3Rpb25MaXN0ZW5lcnMoQ29ubmVjdGlvbkV2ZW50Lk9QRU5FRCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGNsb3NlKGJvb2xlYW4gZXhwdW5nZSkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJY2hlY2tPcGVuKCk7CisKKwl0cnkgeworCSAgICAvKgorCSAgICAgKiBTb21lIFBPUDMgc2VydmVycyB3aWxsIG1hcmsgbWVzc2FnZXMgZm9yIGRlbGV0aW9uIHdoZW4KKwkgICAgICogdGhleSdyZSByZWFkLiAgVG8gcHJldmVudCBzdWNoIG1lc3NhZ2VzIGZyb20gYmVpbmcKKwkgICAgICogZGVsZXRlZCBiZWZvcmUgdGhlIGNsaWVudCBkZWxldGVzIHRoZW0sIHlvdSBjYW4gc2V0CisJICAgICAqIHRoZSBtYWlsLnBvcDMucnNldGJlZm9yZXF1aXQgcHJvcGVydHkgdG8gdHJ1ZS4gIFRoaXMKKwkgICAgICogY2F1c2VzIHVzIHRvIGlzc3VlIGEgUE9QMyBSU0VUIGNvbW1hbmQgdG8gY2xlYXIgYWxsCisJICAgICAqIHRoZSAibWFya2VkIGZvciBkZWxldGlvbiIgZmxhZ3MuICBXZSBjYW4gdGhlbiBleHBsaWNpdGx5CisJICAgICAqIGRlbGV0ZSBtZXNzYWdlcyBhcyBkZXNpcmVkLgorCSAgICAgKi8KKwkgICAgaWYgKHN0b3JlLnJzZXRCZWZvcmVRdWl0ICYmICFmb3JjZUNsb3NlKQorCQlwb3J0LnJzZXQoKTsKKwkgICAgUE9QM01lc3NhZ2UgbTsKKwkgICAgaWYgKGV4cHVuZ2UgJiYgbW9kZSA9PSBSRUFEX1dSSVRFICYmICFmb3JjZUNsb3NlKSB7CisJCS8vIGZpbmQgYWxsIG1lc3NhZ2VzIG1hcmtlZCBkZWxldGVkIGFuZCBpc3N1ZSBERUxFIGNvbW1hbmRzCisJCWZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZV9jYWNoZS5sZW5ndGg7IGkrKykgeworCQkgICAgaWYgKChtID0gbWVzc2FnZV9jYWNoZVtpXSkgIT0gbnVsbCkgeworCQkJaWYgKG0uaXNTZXQoRmxhZ3MuRmxhZy5ERUxFVEVEKSkKKwkJCSAgICB0cnkgeworCQkJCXBvcnQuZGVsZShpICsgMSk7CisJCQkgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9leCkgeworCQkJCXRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oCisJCQkJICAgICJFeGNlcHRpb24gZGVsZXRpbmcgbWVzc2FnZXMgZHVyaW5nIGNsb3NlIiwKKwkJCQkgICAgaW9leCk7CisJCQkgICAgfQorCQkgICAgfQorCQl9CisJICAgIH0KKworCSAgICAvKgorCSAgICAgKiBGbHVzaCBhbmQgZnJlZSBhbGwgY2FjaGVkIGRhdGEgZm9yIHRoZSBtZXNzYWdlcy4KKwkgICAgICovCisJICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZV9jYWNoZS5sZW5ndGg7IGkrKykgeworCQlpZiAoKG0gPSBtZXNzYWdlX2NhY2hlW2ldKSAhPSBudWxsKQorCQkgICAgbS5pbnZhbGlkYXRlKHRydWUpOworCSAgICB9CisKKwkgICAgaWYgKGZvcmNlQ2xvc2UpCisJCXBvcnQuY2xvc2UoKTsKKwkgICAgZWxzZQorCQlwb3J0LnF1aXQoKTsKKwl9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworCSAgICAvLyBkbyBub3RoaW5nCisJfSBmaW5hbGx5IHsKKwkgICAgcG9ydCA9IG51bGw7CisJICAgIHN0b3JlLmNsb3NlUG9ydCh0aGlzKTsKKwkgICAgbWVzc2FnZV9jYWNoZSA9IG51bGw7CisJICAgIG9wZW5lZCA9IGZhbHNlOworCSAgICBub3RpZnlDb25uZWN0aW9uTGlzdGVuZXJzKENvbm5lY3Rpb25FdmVudC5DTE9TRUQpOworCSAgICBpZiAoZmlsZUNhY2hlICE9IG51bGwpIHsKKwkJZmlsZUNhY2hlLmNsb3NlKCk7CisJCWZpbGVDYWNoZSA9IG51bGw7CisJICAgIH0KKwl9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIGlzT3BlbigpIHsKKwlpZiAoIW9wZW5lZCkKKwkgICAgcmV0dXJuIGZhbHNlOworCXRyeSB7CisJICAgIGlmICghcG9ydC5ub29wKCkpCisJCXRocm93IG5ldyBJT0V4Y2VwdGlvbigiTk9PUCBmYWlsZWQiKTsKKwl9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2V4KSB7CisJICAgIHRyeSB7CisJCWNsb3NlKGZhbHNlKTsKKwkgICAgfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIG1leCkgeworCQkvLyBpZ25vcmUgaXQKKwkgICAgfQorCSAgICByZXR1cm4gZmFsc2U7CisJfQorCXJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFsd2F5cyByZXR1cm5zIGFuIGVtcHR5IDxjb2RlPkZsYWdzPC9jb2RlPiBvYmplY3QgYmVjYXVzZQorICAgICAqIHRoZSBQT1AzIHByb3RvY29sIGRvZXNuJ3Qgc3VwcG9ydCBhbnkgcGVybWFuZW50IGZsYWdzLgorICAgICAqCisgICAgICogQHJldHVybgllbXB0eSBGbGFncyBvYmplY3QKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRmxhZ3MgZ2V0UGVybWFuZW50RmxhZ3MoKSB7CisJcmV0dXJuIG5ldyBGbGFncygpOyAvLyBlbXB0eSBmbGFncyBvYmplY3QKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXaWxsIG5vdCBjaGFuZ2Ugd2hpbGUgdGhlIGZvbGRlciBpcyBvcGVuIGJlY2F1c2UgdGhlIFBPUDMKKyAgICAgKiBwcm90b2NvbCBkb2Vzbid0IHN1cHBvcnQgbm90aWZpY2F0aW9uIG9mIG5ldyBtZXNzYWdlcworICAgICAqIGFycml2aW5nIGluIG9wZW4gZm9sZGVycy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCBnZXRNZXNzYWdlQ291bnQoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpZiAoIW9wZW5lZCkKKwkgICAgcmV0dXJuIC0xOworCWNoZWNrUmVhZGFibGUoKTsKKwlyZXR1cm4gdG90YWw7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBNZXNzYWdlIGdldE1lc3NhZ2UoaW50IG1zZ25vKQorCQkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwljaGVja09wZW4oKTsKKworCVBPUDNNZXNzYWdlIG07CisKKwkvLyBBc3N1bWluZyB0aGF0IG1zZ25vIGlzIDw9IHRvdGFsIAorCWlmICgobSA9IG1lc3NhZ2VfY2FjaGVbbXNnbm8tMV0pID09IG51bGwpIHsKKwkgICAgbSA9IGNyZWF0ZU1lc3NhZ2UodGhpcywgbXNnbm8pOworCSAgICBtZXNzYWdlX2NhY2hlW21zZ25vLTFdID0gbTsKKwl9CisJcmV0dXJuIG07CisgICAgfQorCisgICAgcHJvdGVjdGVkIFBPUDNNZXNzYWdlIGNyZWF0ZU1lc3NhZ2UoRm9sZGVyIGYsIGludCBtc2dubykKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlQT1AzTWVzc2FnZSBtID0gbnVsbDsKKwlDb25zdHJ1Y3Rvcjw/PiBjb25zID0gc3RvcmUubWVzc2FnZUNvbnN0cnVjdG9yOworCWlmIChjb25zICE9IG51bGwpIHsKKwkgICAgdHJ5IHsKKwkJT2JqZWN0W10gbyA9IHsgdGhpcywgSW50ZWdlci52YWx1ZU9mKG1zZ25vKSB9OworCQltID0gKFBPUDNNZXNzYWdlKWNvbnMubmV3SW5zdGFuY2Uobyk7CisJICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCQkvLyBpZ25vcmUKKwkgICAgfQorCX0KKwlpZiAobSA9PSBudWxsKQorCSAgICBtID0gbmV3IFBPUDNNZXNzYWdlKHRoaXMsIG1zZ25vKTsKKwlyZXR1cm4gbTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBbHdheXMgdGhyb3dzIDxjb2RlPk1ldGhvZE5vdFN1cHBvcnRlZEV4Y2VwdGlvbjwvY29kZT4KKyAgICAgKiBiZWNhdXNlIHRoZSBQT1AzIHByb3RvY29sIGRvZXNuJ3Qgc3VwcG9ydCBhcHBlbmRpbmcgbWVzc2FnZXMuCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uCU1ldGhvZE5vdFN1cHBvcnRlZEV4Y2VwdGlvbglhbHdheXMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBhcHBlbmRNZXNzYWdlcyhNZXNzYWdlW10gbXNncykgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJdGhyb3cgbmV3IE1ldGhvZE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigiQXBwZW5kIG5vdCBzdXBwb3J0ZWQiKTsJCisgICAgfQorCisgICAgLyoqCisgICAgICogQWx3YXlzIHRocm93cyA8Y29kZT5NZXRob2ROb3RTdXBwb3J0ZWRFeGNlcHRpb248L2NvZGU+CisgICAgICogYmVjYXVzZSB0aGUgUE9QMyBwcm90b2NvbCBkb2Vzbid0IHN1cHBvcnQgZXhwdW5naW5nIG1lc3NhZ2VzCisgICAgICogd2l0aG91dCBjbG9zaW5nIHRoZSBmb2xkZXI7IGNhbGwgdGhlIHtAbGluayAjY2xvc2UgY2xvc2V9IG1ldGhvZAorICAgICAqIHdpdGggdGhlIDxjb2RlPmV4cHVuZ2U8L2NvZGU+IGFyZ3VtZW50IHNldCB0byA8Y29kZT50cnVlPC9jb2RlPgorICAgICAqIGluc3RlYWQuCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uCU1ldGhvZE5vdFN1cHBvcnRlZEV4Y2VwdGlvbglhbHdheXMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgTWVzc2FnZVtdIGV4cHVuZ2UoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwl0aHJvdyBuZXcgTWV0aG9kTm90U3VwcG9ydGVkRXhjZXB0aW9uKCJFeHB1bmdlIG5vdCBzdXBwb3J0ZWQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcmVmZXRjaCBpbmZvcm1hdGlvbiBhYm91dCBQT1AzIG1lc3NhZ2VzLgorICAgICAqIElmIHRoZSBGZXRjaFByb2ZpbGUgY29udGFpbnMgPGNvZGU+VUlERm9sZGVyLkZldGNoUHJvZmlsZUl0ZW0uVUlEPC9jb2RlPiwKKyAgICAgKiBQT1AzIFVJRHMgZm9yIGFsbCBtZXNzYWdlcyBpbiB0aGUgZm9sZGVyIGFyZSBmZXRjaGVkIHVzaW5nIHRoZSBQT1AzCisgICAgICogVUlETCBjb21tYW5kLgorICAgICAqIElmIHRoZSBGZXRjaFByb2ZpbGUgY29udGFpbnMgPGNvZGU+RmV0Y2hQcm9maWxlLkl0ZW0uRU5WRUxPUEU8L2NvZGU+LAorICAgICAqIHRoZSBoZWFkZXJzIGFuZCBzaXplIG9mIGFsbCBtZXNzYWdlcyBhcmUgZmV0Y2hlZCB1c2luZyB0aGUgUE9QMyBUT1AKKyAgICAgKiBhbmQgTElTVCBjb21tYW5kcy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgZmV0Y2goTWVzc2FnZVtdIG1zZ3MsIEZldGNoUHJvZmlsZSBmcCkKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwljaGVja1JlYWRhYmxlKCk7CisJaWYgKCFkb25lVWlkbCAmJiBzdG9yZS5zdXBwb3J0c1VpZGwgJiYKKwkJZnAuY29udGFpbnMoVUlERm9sZGVyLkZldGNoUHJvZmlsZUl0ZW0uVUlEKSkgeworCSAgICAvKgorCSAgICAgKiBTaW5jZSB0aGUgUE9QMyBwcm90b2NvbCBvbmx5IGxldHMgdXMgZmV0Y2ggdGhlIFVJRAorCSAgICAgKiBmb3IgYSBzaW5nbGUgbWVzc2FnZSBvciBmb3IgYWxsIG1lc3NhZ2VzLCB3ZSBnbyBhaGVhZAorCSAgICAgKiBhbmQgZmV0Y2ggVUlEcyBmb3IgYWxsIG1lc3NhZ2VzIGhlcmUsIGlnbm9yaW5nIHRoZSBtc2dzCisJICAgICAqIHBhcmFtZXRlci4gIFdlIGNvdWxkIGJlIG1vcmUgaW50ZWxsaWdlbnQgYW5kIGJhc2UgdGhpcworCSAgICAgKiBkZWNpc2lvbiBvbiB0aGUgbnVtYmVyIG9mIG1lc3NhZ2VzIGZldGNoZWQsIG9yIHRoZQorCSAgICAgKiBwZXJjZW50YWdlIG9mIHRoZSB0b3RhbCBudW1iZXIgb2YgbWVzc2FnZXMgZmV0Y2hlZC4KKwkgICAgICovCisJICAgIFN0cmluZ1tdIHVpZHMgPSBuZXcgU3RyaW5nW21lc3NhZ2VfY2FjaGUubGVuZ3RoXTsKKwkgICAgdHJ5IHsKKwkJaWYgKCFwb3J0LnVpZGwodWlkcykpCisJCSAgICByZXR1cm47CisJICAgIH0gY2F0Y2ggKEVPRkV4Y2VwdGlvbiBlZXgpIHsKKwkJY2xvc2UoZmFsc2UpOworCQl0aHJvdyBuZXcgRm9sZGVyQ2xvc2VkRXhjZXB0aW9uKHRoaXMsIGVleC50b1N0cmluZygpKTsKKwkgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKwkJdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiZXJyb3IgZ2V0dGluZyBVSURMIiwgZXgpOworCSAgICB9CisJICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdWlkcy5sZW5ndGg7IGkrKykgeworCQlpZiAodWlkc1tpXSA9PSBudWxsKQorCQkgICAgY29udGludWU7CisJCVBPUDNNZXNzYWdlIG0gPSAoUE9QM01lc3NhZ2UpZ2V0TWVzc2FnZShpICsgMSk7CisJCW0udWlkID0gdWlkc1tpXTsKKwkgICAgfQorCSAgICBkb25lVWlkbCA9IHRydWU7CS8vIG9ubHkgZG8gdGhpcyBvbmNlCisJfQorCWlmIChmcC5jb250YWlucyhGZXRjaFByb2ZpbGUuSXRlbS5FTlZFTE9QRSkpIHsKKwkgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisJCXRyeSB7CisJCSAgICBQT1AzTWVzc2FnZSBtc2cgPSAoUE9QM01lc3NhZ2UpbXNnc1tpXTsKKwkJICAgIC8vIGZldGNoIGhlYWRlcnMKKwkJICAgIG1zZy5nZXRIZWFkZXIoIiIpOworCQkgICAgLy8gZmV0Y2ggbWVzc2FnZSBzaXplCisJCSAgICBtc2cuZ2V0U2l6ZSgpOworCQl9IGNhdGNoIChNZXNzYWdlUmVtb3ZlZEV4Y2VwdGlvbiBtZXgpIHsKKwkJICAgIC8vIHNob3VsZCBuZXZlciBoYXBwZW4sIGJ1dCBpZ25vcmUgaXQgaWYgaXQgZG9lcworCQl9CisJICAgIH0KKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSB1bmlxdWUgSUQgc3RyaW5nIGZvciB0aGlzIG1lc3NhZ2UsIG9yIG51bGwgaWYKKyAgICAgKiBub3QgYXZhaWxhYmxlLiAgVXNlcyB0aGUgUE9QMyBVSURMIGNvbW1hbmQuCisgICAgICoKKyAgICAgKiBAcGFyYW0JbXNnCXRoZSBtZXNzYWdlCisgICAgICogQHJldHVybiAgICAgICAgICB1bmlxdWUgSUQgc3RyaW5nCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBTdHJpbmcgZ2V0VUlEKE1lc3NhZ2UgbXNnKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwljaGVja09wZW4oKTsKKwlpZiAoIShtc2cgaW5zdGFuY2VvZiBQT1AzTWVzc2FnZSkpCisJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oIm1lc3NhZ2UgaXMgbm90IGEgUE9QM01lc3NhZ2UiKTsKKwlQT1AzTWVzc2FnZSBtID0gKFBPUDNNZXNzYWdlKW1zZzsKKwl0cnkgeworCSAgICBpZiAoIXN0b3JlLnN1cHBvcnRzVWlkbCkKKwkJcmV0dXJuIG51bGw7CisJICAgIGlmIChtLnVpZCA9PSBQT1AzTWVzc2FnZS5VTktOT1dOKQorCQltLnVpZCA9IHBvcnQudWlkbChtLmdldE1lc3NhZ2VOdW1iZXIoKSk7CisJICAgIHJldHVybiBtLnVpZDsKKwl9IGNhdGNoIChFT0ZFeGNlcHRpb24gZWV4KSB7CisJICAgIGNsb3NlKGZhbHNlKTsKKwkgICAgdGhyb3cgbmV3IEZvbGRlckNsb3NlZEV4Y2VwdGlvbih0aGlzLCBlZXgudG9TdHJpbmcoKSk7CisJfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiZXJyb3IgZ2V0dGluZyBVSURMIiwgZXgpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIHNpemUgb2YgdGhpcyBmb2xkZXIsIGFzIHdhcyByZXR1cm5lZCBieSB0aGUgUE9QMyBTVEFUCisgICAgICogY29tbWFuZCB3aGVuIHRoaXMgZm9sZGVyIHdhcyBvcGVuZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCQlmb2xkZXIgc2l6ZQorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFN0YXRlRXhjZXB0aW9uCWlmIHRoZSBmb2xkZXIgaXNuJ3Qgb3BlbgorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBvdGhlciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IGdldFNpemUoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwljaGVja09wZW4oKTsKKwlyZXR1cm4gc2l6ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIHNpemVzIG9mIGFsbCBtZXNzYWdlcyBpbiB0aGlzIGZvbGRlciwgYXMgcmV0dXJuZWQKKyAgICAgKiBieSB0aGUgUE9QMyBMSVNUIGNvbW1hbmQuICBFYWNoIGVudHJ5IGluIHRoZSBhcnJheSBjb3JyZXNwb25kcworICAgICAqIHRvIGEgbWVzc2FnZTsgZW50cnkgPGk+aTwvaT4gY29ycmVzcG9uZHMgdG8gbWVzc2FnZSBudW1iZXIgPGk+aSsxPC9pPi4KKyAgICAgKgorICAgICAqIEByZXR1cm4JCWFycmF5IG9mIG1lc3NhZ2Ugc2l6ZXMKKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxTdGF0ZUV4Y2VwdGlvbglpZiB0aGUgZm9sZGVyIGlzbid0IG9wZW4KKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuMy4zCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBpbnRbXSBnZXRTaXplcygpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWNoZWNrT3BlbigpOworCWludCBzaXplc1tdID0gbmV3IGludFt0b3RhbF07CisJSW5wdXRTdHJlYW0gaXMgPSBudWxsOworCUxpbmVJbnB1dFN0cmVhbSBsaXMgPSBudWxsOworCXRyeSB7CisJICAgIGlzID0gcG9ydC5saXN0KCk7CisJICAgIGxpcyA9IG5ldyBMaW5lSW5wdXRTdHJlYW0oaXMpOworCSAgICBTdHJpbmcgbGluZTsKKwkgICAgd2hpbGUgKChsaW5lID0gbGlzLnJlYWRMaW5lKCkpICE9IG51bGwpIHsKKwkJdHJ5IHsKKwkJICAgIFN0cmluZ1Rva2VuaXplciBzdCA9IG5ldyBTdHJpbmdUb2tlbml6ZXIobGluZSk7CisJCSAgICBpbnQgbXNnbnVtID0gSW50ZWdlci5wYXJzZUludChzdC5uZXh0VG9rZW4oKSk7CisJCSAgICBpbnQgc2l6ZSA9IEludGVnZXIucGFyc2VJbnQoc3QubmV4dFRva2VuKCkpOworCQkgICAgaWYgKG1zZ251bSA+IDAgJiYgbXNnbnVtIDw9IHRvdGFsKQorCQkJc2l6ZXNbbXNnbnVtIC0gMV0gPSBzaXplOworCQl9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGUpIHsKKwkJfQorCSAgICB9CisJfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKwkgICAgLy8gaWdub3JlIGl0PworCX0gZmluYWxseSB7CisJICAgIHRyeSB7CisJCWlmIChsaXMgIT0gbnVsbCkKKwkJICAgIGxpcy5jbG9zZSgpOworCSAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBjZXgpIHsgfQorCSAgICB0cnkgeworCQlpZiAoaXMgIT0gbnVsbCkKKwkJICAgIGlzLmNsb3NlKCk7CisJICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGNleCkgeyB9CisJfQorCXJldHVybiBzaXplczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIHJhdyByZXN1bHRzIG9mIHRoZSBQT1AzIExJU1QgY29tbWFuZCB3aXRoIG5vIGFyZ3VtZW50cy4KKyAgICAgKgorICAgICAqIEByZXR1cm4JCUlucHV0U3RyZWFtIGNvbnRhaW5pbmcgcmVzdWx0cworICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFN0YXRlRXhjZXB0aW9uCWlmIHRoZSBmb2xkZXIgaXNuJ3Qgb3BlbgorICAgICAqIEBleGNlcHRpb24JSU9FeGNlcHRpb24gZm9yIEkvTyBlcnJvcnMgdGFsa2luZyB0byB0aGUgc2VydmVyCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGVycm9ycworICAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS4zLjMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIElucHV0U3RyZWFtIGxpc3RDb21tYW5kKCkKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisJY2hlY2tPcGVuKCk7CisJcmV0dXJuIHBvcnQubGlzdCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENsb3NlIHRoZSBmb2xkZXIgd2hlbiB3ZSdyZSBmaW5hbGl6ZWQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgZmluYWxpemUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKwlmb3JjZUNsb3NlID0gIXN0b3JlLmZpbmFsaXplQ2xlYW5DbG9zZTsKKwl0cnkgeworCSAgICBpZiAob3BlbmVkKQorCQljbG9zZShmYWxzZSk7CisJfSBmaW5hbGx5IHsKKwkgICAgc3VwZXIuZmluYWxpemUoKTsKKwkgICAgZm9yY2VDbG9zZSA9IGZhbHNlOworCX0KKyAgICB9CisKKyAgICAvKiBFbnN1cmUgdGhlIGZvbGRlciBpcyBvcGVuICovCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrT3BlbigpIHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24geworCWlmICghb3BlbmVkKSAKKwkgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiRm9sZGVyIGlzIG5vdCBPcGVuIik7CisgICAgfQorCisgICAgLyogRW5zdXJlIHRoZSBmb2xkZXIgaXMgbm90IG9wZW4gKi8KKyAgICBwcml2YXRlIHZvaWQgY2hlY2tDbG9zZWQoKSB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIHsKKwlpZiAob3BlbmVkKSAKKwkgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiRm9sZGVyIGlzIE9wZW4iKTsKKyAgICB9CisKKyAgICAvKiBFbnN1cmUgdGhlIGZvbGRlciBpcyBvcGVuICYgcmVhZGFibGUgKi8KKyAgICBwcml2YXRlIHZvaWQgY2hlY2tSZWFkYWJsZSgpIHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24geworCWlmICghb3BlbmVkIHx8IChtb2RlICE9IFJFQURfT05MWSAmJiBtb2RlICE9IFJFQURfV1JJVEUpKQorCSAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJGb2xkZXIgaXMgbm90IFJlYWRhYmxlIik7CisgICAgfQorCisgICAgLyogRW5zdXJlIHRoZSBmb2xkZXIgaXMgb3BlbiAmIHdyaXRhYmxlICovCisgICAgLyoKKyAgICBwcml2YXRlIHZvaWQgY2hlY2tXcml0YWJsZSgpIHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24geworCWlmICghb3BlbmVkIHx8IG1vZGUgIT0gUkVBRF9XUklURSkKKwkgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiRm9sZGVyIGlzIG5vdCBXcml0YWJsZSIpOworICAgIH0KKyAgICAqLworCisgICAgLyoqCisgICAgICogQ2VudHJhbGl6ZSBhY2Nlc3MgdG8gdGhlIFByb3RvY29sIG9iamVjdCBieSBQT1AzTWVzc2FnZQorICAgICAqIG9iamVjdHMgc28gdGhhdCB0aGV5IHdpbGwgZmFpbCBhcHByb3ByaWF0ZWx5IHdoZW4gdGhlIGZvbGRlcgorICAgICAqIGlzIGNsb3NlZC4KKyAgICAgKi8KKyAgICBQcm90b2NvbCBnZXRQcm90b2NvbCgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCVByb3RvY29sIHAgPSBwb3J0OwkvLyByZWFkIGl0IGJlZm9yZSBjbG9zZSgpIGNhbiBzZXQgaXQgdG8gbnVsbAorCWNoZWNrT3BlbigpOworCS8vIGNsb3NlKCkgbWlnaHQgaGFwcGVuIGhlcmUKKwlyZXR1cm4gcDsKKyAgICB9CisKKyAgICAvKgorICAgICAqIE9ubHkgaGVyZSB0byBtYWtlIGFjY2Vzc2libGUgdG8gUE9QM01lc3NhZ2UuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgbm90aWZ5TWVzc2FnZUNoYW5nZWRMaXN0ZW5lcnMoaW50IHR5cGUsIE1lc3NhZ2UgbSkgeworCXN1cGVyLm5vdGlmeU1lc3NhZ2VDaGFuZ2VkTGlzdGVuZXJzKHR5cGUsIG0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFVzZWQgYnkgUE9QM01lc3NhZ2UuCisgICAgICovCisgICAgVGVtcEZpbGUgZ2V0RmlsZUNhY2hlKCkgeworCXJldHVybiBmaWxlQ2FjaGU7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9wb3AzL1BPUDNNZXNzYWdlLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3BvcDMvUE9QM01lc3NhZ2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YmM5YzlmCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9wb3AzL1BPUDNNZXNzYWdlLmphdmEKQEAgLTAsMCArMSw2NDQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLnBvcDM7CisKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkxldmVsOworaW1wb3J0IGphdmEubGFuZy5yZWYuU29mdFJlZmVyZW5jZTsKK2ltcG9ydCBqYXZheC5tYWlsLio7CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC4qOworaW1wb3J0IGphdmF4Lm1haWwuZXZlbnQuKjsKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5SZWFkYWJsZU1pbWU7CisKKy8qKgorICogQSBQT1AzIE1lc3NhZ2UuICBKdXN0IGxpa2UgYSBNaW1lTWVzc2FnZSBleGNlcHQgdGhhdAorICogc29tZSB0aGluZ3MgYXJlIG5vdCBzdXBwb3J0ZWQuCisgKgorICogQGF1dGhvciAgICAgIEJpbGwgU2hhbm5vbgorICovCitwdWJsaWMgY2xhc3MgUE9QM01lc3NhZ2UgZXh0ZW5kcyBNaW1lTWVzc2FnZSBpbXBsZW1lbnRzIFJlYWRhYmxlTWltZSB7CisKKyAgICAvKgorICAgICAqIE91ciBsb2NraW5nIHN0cmF0ZWd5IGlzIHRvIGFsd2F5cyBsb2NrIHRoZSBQT1AzRm9sZGVyIGJlZm9yZSB0aGUKKyAgICAgKiBQT1AzTWVzc2FnZSBzbyB3ZSBoYXZlIHRvIGJlIGNhcmVmdWwgdG8gZHJvcCBvdXIgbG9jayBiZWZvcmUgY2FsbGluZworICAgICAqIGJhY2sgdG8gdGhlIGZvbGRlciB0byBjbG9zZSBpdCBhbmQgbm90aWZ5IG9mIGNvbm5lY3Rpb24gbG9zdCBldmVudHMuCisgICAgICovCisKKyAgICAvLyBmbGFnIHRvIGluZGljYXRlIHdlIGhhdmVuJ3QgdHJpZWQgdG8gZmV0Y2ggdGhlIFVJRCB5ZXQKKyAgICBzdGF0aWMgZmluYWwgU3RyaW5nIFVOS05PV04gPSAiVU5LTk9XTiI7CisKKyAgICBwcml2YXRlIFBPUDNGb2xkZXIgZm9sZGVyOwkvLyBvdmVycmlkZXMgZm9sZGVyIGluIE1pbWVNZXNzYWdlCisgICAgcHJpdmF0ZSBpbnQgaGRyU2l6ZSA9IC0xOworICAgIHByaXZhdGUgaW50IG1zZ1NpemUgPSAtMTsKKyAgICBTdHJpbmcgdWlkID0gVU5LTk9XTjsJLy8gY29udHJvbGxlZCBieSBmb2xkZXIgbG9jaworCisgICAgLy8gcmF3RGF0YSBpdHNlbGYgaXMgbmV2ZXIgbnVsbAorICAgIHByaXZhdGUgU29mdFJlZmVyZW5jZTxJbnB1dFN0cmVhbT4gcmF3RGF0YQorCSAgICA9IG5ldyBTb2Z0UmVmZXJlbmNlPD4obnVsbCk7CisKKyAgICBwdWJsaWMgUE9QM01lc3NhZ2UoRm9sZGVyIGZvbGRlciwgaW50IG1zZ25vKQorCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJc3VwZXIoZm9sZGVyLCBtc2dubyk7CisJYXNzZXJ0IGZvbGRlciBpbnN0YW5jZW9mIFBPUDNGb2xkZXI7CisJdGhpcy5mb2xkZXIgPSAoUE9QM0ZvbGRlcilmb2xkZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBzcGVjaWZpZWQgZmxhZ3Mgb24gdGhpcyBtZXNzYWdlIHRvIHRoZSBzcGVjaWZpZWQgdmFsdWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmV3RmxhZ3MJdGhlIGZsYWdzIHRvIGJlIHNldAorICAgICAqIEBwYXJhbSBzZXQJdGhlIHZhbHVlIHRvIGJlIHNldAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXRGbGFncyhGbGFncyBuZXdGbGFncywgYm9vbGVhbiBzZXQpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJRmxhZ3Mgb2xkRmxhZ3MgPSAoRmxhZ3MpZmxhZ3MuY2xvbmUoKTsKKwlzdXBlci5zZXRGbGFncyhuZXdGbGFncywgc2V0KTsKKwlpZiAoIWZsYWdzLmVxdWFscyhvbGRGbGFncykpCisJICAgIGZvbGRlci5ub3RpZnlNZXNzYWdlQ2hhbmdlZExpc3RlbmVycygKKwkJCQlNZXNzYWdlQ2hhbmdlZEV2ZW50LkZMQUdTX0NIQU5HRUQsIHRoaXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgc2l6ZSBvZiB0aGUgY29udGVudCBvZiB0aGlzIG1lc3NhZ2UgaW4gYnl0ZXMuIAorICAgICAqIFJldHVybnMgLTEgaWYgdGhlIHNpemUgY2Fubm90IGJlIGRldGVybWluZWQuIDxwPgorICAgICAqCisgICAgICogTm90ZSB0aGF0IHRoaXMgbnVtYmVyIG1heSBub3QgYmUgYW4gZXhhY3QgbWVhc3VyZSBvZiB0aGUKKyAgICAgKiBjb250ZW50IHNpemUgYW5kIG1heSBvciBtYXkgbm90IGFjY291bnQgZm9yIGFueSB0cmFuc2ZlcgorICAgICAqIGVuY29kaW5nIG9mIHRoZSBjb250ZW50LiA8cD4KKyAgICAgKgorICAgICAqIEByZXR1cm4gICAgICAgICAgc2l6ZSBvZiBjb250ZW50IGluIGJ5dGVzCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICovICAKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldFNpemUoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwl0cnkgeworCSAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKwkJLy8gaWYgd2UgYWxyZWFkeSBoYXZlIHRoZSBzaXplLCByZXR1cm4gaXQKKwkJaWYgKG1zZ1NpemUgPiAwKQorCQkgICAgcmV0dXJuIG1zZ1NpemU7CisJICAgIH0KKworCSAgICAvKgorCSAgICAgKiBVc2UgTElTVCB0byBkZXRlcm1pbmUgdGhlIGVudGlyZSBtZXNzYWdlCisJICAgICAqIHNpemUgYW5kIHN1YnRyYWN0IG91dCB0aGUgaGVhZGVyIHNpemUKKwkgICAgICogKHdoaWNoIG1heSBpbnZvbHZlIGxvYWRpbmcgdGhlIGhlYWRlcnMsCisJICAgICAqIHdoaWNoIG1heSBsb2FkIHRoZSBjb250ZW50IGFzIGEgc2lkZSBlZmZlY3QpLgorCSAgICAgKiBJZiB0aGUgY29udGVudCBpcyBsb2FkZWQgYXMgYSBzaWRlIGVmZmVjdCBvZgorCSAgICAgKiBsb2FkaW5nIHRoZSBoZWFkZXJzLCBpdCB3aWxsIHNldCB0aGUgc2l6ZS4KKwkgICAgICoKKwkgICAgICogTWFrZSBzdXJlIHRvIGNhbGwgbG9hZEhlYWRlcnMoKSBvdXRzaWRlIG9mIHRoZQorCSAgICAgKiBzeW5jaHJvbml6YXRpb24gYmxvY2suICBUaGVyZSdzIGEgcG90ZW50aWFsIHJhY2UKKwkgICAgICogY29uZGl0aW9uIGhlcmUgYnV0IHN5bmNocm9uaXphdGlvbiB3aWxsIG9jY3VyIGluCisJICAgICAqIGxvYWRIZWFkZXJzKCkgdG8gbWFrZSBzdXJlIHRoZSBoZWFkZXJzIGFyZSBvbmx5CisJICAgICAqIGxvYWRlZCBvbmNlLCBhbmQgYWdhaW4gaW4gdGhlIGZvbGxvd2luZyBibG9jayB0bworCSAgICAgKiBvbmx5IGNvbXB1dGUgbXNnU2l6ZSBvbmNlLgorCSAgICAgKi8KKwkgICAgaWYgKGhlYWRlcnMgPT0gbnVsbCkKKwkJbG9hZEhlYWRlcnMoKTsKKworCSAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKwkJaWYgKG1zZ1NpemUgPCAwKQorCQkgICAgbXNnU2l6ZSA9IGZvbGRlci5nZXRQcm90b2NvbCgpLmxpc3QobXNnbnVtKSAtIGhkclNpemU7CisJCXJldHVybiBtc2dTaXplOworCSAgICB9CisJfSBjYXRjaCAoRU9GRXhjZXB0aW9uIGVleCkgeworCSAgICBmb2xkZXIuY2xvc2UoZmFsc2UpOworCSAgICB0aHJvdyBuZXcgRm9sZGVyQ2xvc2VkRXhjZXB0aW9uKGZvbGRlciwgZWV4LnRvU3RyaW5nKCkpOworCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oImVycm9yIGdldHRpbmcgc2l6ZSIsIGV4KTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJvZHVjZSB0aGUgcmF3IGJ5dGVzIG9mIHRoZSBtZXNzYWdlLiAgVGhlIGRhdGEgaXMgZmV0Y2hlZCB1c2luZworICAgICAqIHRoZSBQT1AzIFJFVFIgY29tbWFuZC4gIElmIHNraXBIZWFkZXIgaXMgdHJ1ZSwganVzdCB0aGUgY29udGVudAorICAgICAqIGlzIHJldHVybmVkLgorICAgICAqLworICAgIHByaXZhdGUgSW5wdXRTdHJlYW0gZ2V0UmF3U3RyZWFtKGJvb2xlYW4gc2tpcEhlYWRlcikKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlJbnB1dFN0cmVhbSByYXdjb250ZW50ID0gbnVsbDsKKwl0cnkgeworCXN5bmNocm9uaXplZCh0aGlzKSB7CisJICAgIHJhd2NvbnRlbnQgPSByYXdEYXRhLmdldCgpOworCSAgICBpZiAocmF3Y29udGVudCA9PSBudWxsKSB7CisJCVRlbXBGaWxlIGNhY2hlID0gZm9sZGVyLmdldEZpbGVDYWNoZSgpOworCQlpZiAoY2FjaGUgIT0gbnVsbCkgeworCQkgICAgaWYgKGZvbGRlci5sb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FKSkKKwkJCWZvbGRlci5sb2dnZXIuZmluZSgiY2FjaGluZyBtZXNzYWdlICMiICsgbXNnbnVtICsKKwkJCQkJICAgICIgaW4gdGVtcCBmaWxlIik7CisJCSAgICBBcHBlbmRTdHJlYW0gb3MgPSBjYWNoZS5nZXRBcHBlbmRTdHJlYW0oKTsKKwkJICAgIEJ1ZmZlcmVkT3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCdWZmZXJlZE91dHB1dFN0cmVhbShvcyk7CisJCSAgICB0cnkgeworCQkJZm9sZGVyLmdldFByb3RvY29sKCkucmV0cihtc2dudW0sIGJvcyk7CisJCSAgICB9IGZpbmFsbHkgeworCQkJYm9zLmNsb3NlKCk7CisJCSAgICB9CisJCSAgICByYXdjb250ZW50ID0gb3MuZ2V0SW5wdXRTdHJlYW0oKTsKKwkJfSBlbHNlIHsKKwkJICAgIHJhd2NvbnRlbnQgPSBmb2xkZXIuZ2V0UHJvdG9jb2woKS5yZXRyKG1zZ251bSwKKwkJCQkJbXNnU2l6ZSA+IDAgPyBtc2dTaXplICsgaGRyU2l6ZSA6IDApOworCQl9CisJCWlmIChyYXdjb250ZW50ID09IG51bGwpIHsKKwkJICAgIGV4cHVuZ2VkID0gdHJ1ZTsKKwkJICAgIHRocm93IG5ldyBNZXNzYWdlUmVtb3ZlZEV4Y2VwdGlvbigKKwkJCSJjYW4ndCByZXRyaWV2ZSBtZXNzYWdlICMiICsgbXNnbnVtICsKKwkJCSIgaW4gUE9QM01lc3NhZ2UuZ2V0Q29udGVudFN0cmVhbSIpOyAvLyBYWFggLSB3aGF0IGVsc2U/CisJCX0KKworCQlpZiAoaGVhZGVycyA9PSBudWxsIHx8CisJCQkoKFBPUDNTdG9yZSkoZm9sZGVyLmdldFN0b3JlKCkpKS5mb3JnZXRUb3BIZWFkZXJzKSB7CisJCSAgICBoZWFkZXJzID0gbmV3IEludGVybmV0SGVhZGVycyhyYXdjb250ZW50KTsKKwkJICAgIGhkclNpemUgPQorCQkJKGludCkoKFNoYXJlZElucHV0U3RyZWFtKXJhd2NvbnRlbnQpLmdldFBvc2l0aW9uKCk7CisJCX0gZWxzZSB7CisJCSAgICAvKgorCQkgICAgICogQWxyZWFkeSBoYXZlIHRoZSBoZWFkZXJzLCBoYXZlIHRvIHNraXAgdGhlIGhlYWRlcnMKKwkJICAgICAqIGluIHRoZSBjb250ZW50IGFycmF5IGFuZCByZXR1cm4gdGhlIGJvZHkuCisJCSAgICAgKgorCQkgICAgICogWFhYIC0gSXQgc2VlbXMgdGhhdCBzb21lIG1haWwgc2VydmVycyByZXR1cm4gc2xpZ2h0bHkKKwkJICAgICAqIGRpZmZlcmVudCBoZWFkZXJzIGluIHRoZSBSRVRSIHJlc3VsdHMgdGhhbiB3ZXJlIHJldHVybmVkCisJCSAgICAgKiBpbiB0aGUgVE9QIHJlc3VsdHMsIHNvIHdlIGNhbid0IGRlcGVuZCBvbiByZW1lbWJlcmluZworCQkgICAgICogdGhlIHNpemUgb2YgdGhlIGhlYWRlcnMgZnJvbSB0aGUgVE9QIGNvbW1hbmQgYW5kIGp1c3QKKwkJICAgICAqIHNraXBwaW5nIHRoYXQgbWFueSBieXRlcy4gIEluc3RlYWQsIHdlIGhhdmUgdG8gcHJvY2VzcworCQkgICAgICogdGhlIGNvbnRlbnQsIHNraXBwaW5nIG92ZXIgdGhlIGhlYWRlciB1bnRpbCB3ZSBjb21lIHRvCisJCSAgICAgKiB0aGUgZW1wdHkgbGluZSB0aGF0IHNlcGFyYXRlcyB0aGUgaGVhZGVyIGZyb20gdGhlIGJvZHkuCisJCSAgICAgKi8KKwkJICAgIGludCBvZmZzZXQgPSAwOworCQkgICAgZm9yICg7OykgeworCQkJaW50IGxlbiA9IDA7CS8vIG51bWJlciBvZiBieXRlcyBpbiB0aGlzIGxpbmUKKwkJCWludCBjMTsKKwkJCXdoaWxlICgoYzEgPSByYXdjb250ZW50LnJlYWQoKSkgPj0gMCkgeworCQkJICAgIGlmIChjMSA9PSAnXG4nKQkvLyBlbmQgb2YgbGluZQorCQkJCWJyZWFrOworCQkJICAgIGVsc2UgaWYgKGMxID09ICdccicpIHsKKwkJCQkvLyBnb3QgQ1IsIGlzIHRoZSBuZXh0IGNoYXIgTEY/CisJCQkJaWYgKHJhd2NvbnRlbnQuYXZhaWxhYmxlKCkgPiAwKSB7CisJCQkJICAgIHJhd2NvbnRlbnQubWFyaygxKTsKKwkJCQkgICAgaWYgKHJhd2NvbnRlbnQucmVhZCgpICE9ICdcbicpCisJCQkJCXJhd2NvbnRlbnQucmVzZXQoKTsKKwkJCQl9CisJCQkJYnJlYWs7CS8vIGluIGFueSBjYXNlLCBlbmQgb2YgbGluZQorCQkJICAgIH0KKworCQkJICAgIC8vIG5vdCBDUiwgTkwsIG9yIENSTEYsIGNvdW50IHRoZSBieXRlCisJCQkgICAgbGVuKys7CisJCQl9CisJCQkvLyBoZXJlIHdoZW4gZW5kIG9mIGxpbmUgb3Igb3V0IG9mIGRhdGEKKworCQkJLy8gaWYgb3V0IG9mIGRhdGEsIHdlJ3JlIGRvbmUKKwkJCWlmIChyYXdjb250ZW50LmF2YWlsYWJsZSgpID09IDApCisJCQkgICAgYnJlYWs7CisJCQkKKwkJCS8vIGlmIGl0IHdhcyBhbiBlbXB0eSBsaW5lLCB3ZSdyZSBkb25lCisJCQlpZiAobGVuID09IDApCisJCQkgICAgYnJlYWs7CisJCSAgICB9CisJCSAgICBoZHJTaXplID0KKwkJCShpbnQpKChTaGFyZWRJbnB1dFN0cmVhbSlyYXdjb250ZW50KS5nZXRQb3NpdGlvbigpOworCQl9CisKKwkJLy8gc2tpcHBlZCB0aGUgaGVhZGVyLCB0aGUgbWVzc2FnZSBpcyB3aGF0J3MgbGVmdAorCQltc2dTaXplID0gcmF3Y29udGVudC5hdmFpbGFibGUoKTsKKworCQlyYXdEYXRhID0gbmV3IFNvZnRSZWZlcmVuY2U8PihyYXdjb250ZW50KTsKKwkgICAgfQorCX0KKwl9IGNhdGNoIChFT0ZFeGNlcHRpb24gZWV4KSB7CisJICAgIGZvbGRlci5jbG9zZShmYWxzZSk7CisJICAgIHRocm93IG5ldyBGb2xkZXJDbG9zZWRFeGNlcHRpb24oZm9sZGVyLCBlZXgudG9TdHJpbmcoKSk7CisJfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiZXJyb3IgZmV0Y2hpbmcgUE9QMyBjb250ZW50IiwgZXgpOworCX0KKworCS8qCisJICogV2UgaGF2ZSBhIGNhY2hlZCBzdHJlYW0sIGJ1dCB3ZSBuZWVkIHRvIHJldHVybgorCSAqIGEgZnJlc2ggc3RyZWFtIHRvIHJlYWQgZnJvbSB0aGUgYmVnaW5uaW5nIGFuZAorCSAqIHRoYXQgY2FuIGJlIHNhZmVseSBjbG9zZWQuCisJICovCisJcmF3Y29udGVudCA9ICgoU2hhcmVkSW5wdXRTdHJlYW0pcmF3Y29udGVudCkubmV3U3RyZWFtKAorCQkJCQkJc2tpcEhlYWRlciA/IGhkclNpemUgOiAwLCAtMSk7CisJcmV0dXJuIHJhd2NvbnRlbnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJvZHVjZSB0aGUgcmF3IGJ5dGVzIG9mIHRoZSBjb250ZW50LiAgVGhlIGRhdGEgaXMgZmV0Y2hlZCB1c2luZworICAgICAqIHRoZSBQT1AzIFJFVFIgY29tbWFuZC4KKyAgICAgKgorICAgICAqIEBzZWUgI2NvbnRlbnRTdHJlYW0KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgc3luY2hyb25pemVkIElucHV0U3RyZWFtIGdldENvbnRlbnRTdHJlYW0oKQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWlmIChjb250ZW50U3RyZWFtICE9IG51bGwpCisJICAgIHJldHVybiAoKFNoYXJlZElucHV0U3RyZWFtKWNvbnRlbnRTdHJlYW0pLm5ld1N0cmVhbSgwLCAtMSk7CisKKwlJbnB1dFN0cmVhbSBjc3RyZWFtID0gZ2V0UmF3U3RyZWFtKHRydWUpOworCisJLyoKKwkgKiBLZWVwIGEgaGFyZCByZWZlcmVuY2UgdG8gdGhlIGRhdGEgaWYgd2UncmUgdXNpbmcgYSBmaWxlCisJICogY2FjaGUgb3IgaWYgdGhlICJtYWlsLnBvcDMua2VlcG1lc3NhZ2Vjb250ZW50IiBwcm9wIGlzIHNldC4KKwkgKi8KKwlUZW1wRmlsZSBjYWNoZSA9IGZvbGRlci5nZXRGaWxlQ2FjaGUoKTsKKwlpZiAoY2FjaGUgIT0gbnVsbCB8fAorCQkoKFBPUDNTdG9yZSkoZm9sZGVyLmdldFN0b3JlKCkpKS5rZWVwTWVzc2FnZUNvbnRlbnQpCisJICAgIGNvbnRlbnRTdHJlYW0gPSAoKFNoYXJlZElucHV0U3RyZWFtKWNzdHJlYW0pLm5ld1N0cmVhbSgwLCAtMSk7CisJcmV0dXJuIGNzdHJlYW07CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBNSU1FIGZvcm1hdCBzdHJlYW0gY29ycmVzcG9uZGluZyB0byB0aGlzIG1lc3NhZ2UgcGFydC4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIE1JTUUgZm9ybWF0IHN0cmVhbQorICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjQuNQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBJbnB1dFN0cmVhbSBnZXRNaW1lU3RyZWFtKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJcmV0dXJuIGdldFJhd1N0cmVhbShmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW52YWxpZGF0ZSB0aGUgY2FjaGUgb2YgY29udGVudCBmb3IgdGhpcyBtZXNzYWdlIG9iamVjdCwgY2F1c2luZyAKKyAgICAgKiBpdCB0byBiZSBmZXRjaGVkIGFnYWluIGZyb20gdGhlIHNlcnZlciB0aGUgbmV4dCB0aW1lIGl0IGlzIG5lZWRlZC4KKyAgICAgKiBJZiA8Y29kZT5pbnZhbGlkYXRlSGVhZGVyczwvY29kZT4gaXMgdHJ1ZSwgaW52YWxpZGF0ZSB0aGUgaGVhZGVycworICAgICAqIGFzIHdlbGwuCisgICAgICoKKyAgICAgKiBAcGFyYW0JaW52YWxpZGF0ZUhlYWRlcnMJaW52YWxpZGF0ZSB0aGUgaGVhZGVycyBhcyB3ZWxsPworICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBpbnZhbGlkYXRlKGJvb2xlYW4gaW52YWxpZGF0ZUhlYWRlcnMpIHsKKwljb250ZW50ID0gbnVsbDsKKwlJbnB1dFN0cmVhbSByc3RyZWFtID0gcmF3RGF0YS5nZXQoKTsKKwlpZiAocnN0cmVhbSAhPSBudWxsKSB7CisJICAgIC8vIG5vdGUgdGhhdCBpZiB0aGUgY29udGVudCBpcyBpbiB0aGUgZmlsZSBjYWNoZSwgaXQgd2lsbCBiZSBsb3N0CisJICAgIC8vIGFuZCBmZXRjaGVkIGZyb20gdGhlIHNlcnZlciBpZiBpdCdzIG5lZWRlZCBhZ2FpbgorCSAgICB0cnkgeworCQlyc3RyZWFtLmNsb3NlKCk7CisJICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisJCS8vIGlnbm9yZSBpdAorCSAgICB9CisJICAgIHJhd0RhdGEgPSBuZXcgU29mdFJlZmVyZW5jZTw+KG51bGwpOworCX0KKwlpZiAoY29udGVudFN0cmVhbSAhPSBudWxsKSB7CisJICAgIHRyeSB7CisJCWNvbnRlbnRTdHJlYW0uY2xvc2UoKTsKKwkgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKwkJLy8gaWdub3JlIGl0CisJICAgIH0KKwkgICAgY29udGVudFN0cmVhbSA9IG51bGw7CisJfQorCW1zZ1NpemUgPSAtMTsKKwlpZiAoaW52YWxpZGF0ZUhlYWRlcnMpIHsKKwkgICAgaGVhZGVycyA9IG51bGw7CisJICAgIGhkclNpemUgPSAtMTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogRmV0Y2ggdGhlIGhlYWRlciBvZiB0aGUgbWVzc2FnZSBhbmQgdGhlIGZpcnN0IDxjb2RlPm48L2NvZGU+IGxpbmVzCisgICAgICogb2YgdGhlIHJhdyBjb250ZW50IG9mIHRoZSBtZXNzYWdlLiAgVGhlIGhlYWRlcnMgYW5kIGRhdGEgYXJlCisgICAgICogYXZhaWxhYmxlIGluIHRoZSByZXR1cm5lZCBJbnB1dFN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbQluCW51bWJlciBvZiBsaW5lcyBvZiBjb250ZW50IHRvIGZldGNoCisgICAgICogQHJldHVybglJbnB1dFN0cmVhbSBjb250YWluaW5nIHRoZSBtZXNzYWdlIGhlYWRlcnMgYW5kIG4gY29udGVudCBsaW5lcworICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBJbnB1dFN0cmVhbSB0b3AoaW50IG4pIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXRyeSB7CisJICAgIHN5bmNocm9uaXplZCAodGhpcykgeworCQlyZXR1cm4gZm9sZGVyLmdldFByb3RvY29sKCkudG9wKG1zZ251bSwgbik7CisJICAgIH0KKwl9IGNhdGNoIChFT0ZFeGNlcHRpb24gZWV4KSB7CisJICAgIGZvbGRlci5jbG9zZShmYWxzZSk7CisJICAgIHRocm93IG5ldyBGb2xkZXJDbG9zZWRFeGNlcHRpb24oZm9sZGVyLCBlZXgudG9TdHJpbmcoKSk7CisJfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiZXJyb3IgZ2V0dGluZyBzaXplIiwgZXgpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgYWxsIHRoZSBoZWFkZXJzIGZvciB0aGlzIGhlYWRlcl9uYW1lLiBOb3RlIHRoYXQgY2VydGFpbgorICAgICAqIGhlYWRlcnMgbWF5IGJlIGVuY29kZWQgYXMgcGVyIFJGQyAyMDQ3IGlmIHRoZXkgY29udGFpbiAKKyAgICAgKiBub24gVVMtQVNDSUkgY2hhcmFjdGVycyBhbmQgdGhlc2Ugc2hvdWxkIGJlIGRlY29kZWQuIDxwPgorICAgICAqCisgICAgICogQHBhcmFtCW5hbWUJbmFtZSBvZiBoZWFkZXIKKyAgICAgKiBAcmV0dXJuCWFycmF5IG9mIGhlYWRlcnMKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKiBAc2VlIAlqYXZheC5tYWlsLmludGVybmV0Lk1pbWVVdGlsaXR5CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZ1tdIGdldEhlYWRlcihTdHJpbmcgbmFtZSkKKwkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWlmIChoZWFkZXJzID09IG51bGwpCisJICAgIGxvYWRIZWFkZXJzKCk7CisJcmV0dXJuIGhlYWRlcnMuZ2V0SGVhZGVyKG5hbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCBhbGwgdGhlIGhlYWRlcnMgZm9yIHRoaXMgaGVhZGVyIG5hbWUsIHJldHVybmVkIGFzIGEgc2luZ2xlCisgICAgICogU3RyaW5nLCB3aXRoIGhlYWRlcnMgc2VwYXJhdGVkIGJ5IHRoZSBkZWxpbWl0ZXIuIElmIHRoZQorICAgICAqIGRlbGltaXRlciBpcyA8Y29kZT5udWxsPC9jb2RlPiwgb25seSB0aGUgZmlyc3QgaGVhZGVyIGlzIAorICAgICAqIHJldHVybmVkLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUJCXRoZSBuYW1lIG9mIHRoaXMgaGVhZGVyCisgICAgICogQHBhcmFtIGRlbGltaXRlcgkJZGVsaW1pdGVyIGJldHdlZW4gcmV0dXJuZWQgaGVhZGVycworICAgICAqIEByZXR1cm4gICAgICAgICAgICAgICAgICB0aGUgdmFsdWUgZmllbGRzIGZvciBhbGwgaGVhZGVycyB3aXRoIAorICAgICAqCQkJCXRoaXMgbmFtZQorICAgICAqIEBleGNlcHRpb24JCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldEhlYWRlcihTdHJpbmcgbmFtZSwgU3RyaW5nIGRlbGltaXRlcikKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpZiAoaGVhZGVycyA9PSBudWxsKQorCSAgICBsb2FkSGVhZGVycygpOworCXJldHVybiBoZWFkZXJzLmdldEhlYWRlcihuYW1lLCBkZWxpbWl0ZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgdmFsdWUgZm9yIHRoaXMgaGVhZGVyX25hbWUuICBUaHJvd3MgSWxsZWdhbFdyaXRlRXhjZXB0aW9uCisgICAgICogYmVjYXVzZSBQT1AzIG1lc3NhZ2VzIGFyZSByZWFkLW9ubHkuCisgICAgICoKKyAgICAgKiBAcGFyYW0JbmFtZSAJaGVhZGVyIG5hbWUKKyAgICAgKiBAcGFyYW0JdmFsdWUJaGVhZGVyIHZhbHVlCisgICAgICogQHNlZSAJamF2YXgubWFpbC5pbnRlcm5ldC5NaW1lVXRpbGl0eQorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFdyaXRlRXhjZXB0aW9uIGJlY2F1c2UgdGhlIHVuZGVybHlpbmcKKyAgICAgKgkJCWltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBtZXNzYWdlIGlzCisgICAgICoJCQlvYnRhaW5lZCBmcm9tIGEgUkVBRF9PTkxZIGZvbGRlci4KKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRIZWFkZXIoU3RyaW5nIG5hbWUsIFN0cmluZyB2YWx1ZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJLy8gWFhYIC0gc2hvdWxkIGNoZWNrIGZvciByZWFkLW9ubHkgZm9sZGVyPworCXRocm93IG5ldyBJbGxlZ2FsV3JpdGVFeGNlcHRpb24oIlBPUDMgbWVzc2FnZXMgYXJlIHJlYWQtb25seSIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZCB0aGlzIHZhbHVlIHRvIHRoZSBleGlzdGluZyB2YWx1ZXMgZm9yIHRoaXMgaGVhZGVyX25hbWUuCisgICAgICogVGhyb3dzIElsbGVnYWxXcml0ZUV4Y2VwdGlvbiBiZWNhdXNlIFBPUDMgbWVzc2FnZXMgYXJlIHJlYWQtb25seS4KKyAgICAgKgorICAgICAqIEBwYXJhbQluYW1lIAloZWFkZXIgbmFtZQorICAgICAqIEBwYXJhbQl2YWx1ZQloZWFkZXIgdmFsdWUKKyAgICAgKiBAc2VlIAlqYXZheC5tYWlsLmludGVybmV0Lk1pbWVVdGlsaXR5CisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsV3JpdGVFeGNlcHRpb24gYmVjYXVzZSB0aGUgdW5kZXJseWluZworICAgICAqCQkJaW1wbGVtZW50YXRpb24gZG9lcyBub3Qgc3VwcG9ydCBtb2RpZmljYXRpb24KKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIG1lc3NhZ2UgaXMKKyAgICAgKgkJCW9idGFpbmVkIGZyb20gYSBSRUFEX09OTFkgZm9sZGVyLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGFkZEhlYWRlcihTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwkvLyBYWFggLSBzaG91bGQgY2hlY2sgZm9yIHJlYWQtb25seSBmb2xkZXI/CisJdGhyb3cgbmV3IElsbGVnYWxXcml0ZUV4Y2VwdGlvbigiUE9QMyBtZXNzYWdlcyBhcmUgcmVhZC1vbmx5Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlIGFsbCBoZWFkZXJzIHdpdGggdGhpcyBuYW1lLgorICAgICAqIFRocm93cyBJbGxlZ2FsV3JpdGVFeGNlcHRpb24gYmVjYXVzZSBQT1AzIG1lc3NhZ2VzIGFyZSByZWFkLW9ubHkuCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxXcml0ZUV4Y2VwdGlvbiBiZWNhdXNlIHRoZSB1bmRlcmx5aW5nCisgICAgICoJCQlpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IG1vZGlmaWNhdGlvbgorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgbWVzc2FnZSBpcworICAgICAqCQkJb2J0YWluZWQgZnJvbSBhIFJFQURfT05MWSBmb2xkZXIuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcmVtb3ZlSGVhZGVyKFN0cmluZyBuYW1lKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwkvLyBYWFggLSBzaG91bGQgY2hlY2sgZm9yIHJlYWQtb25seSBmb2xkZXI/CisJdGhyb3cgbmV3IElsbGVnYWxXcml0ZUV4Y2VwdGlvbigiUE9QMyBtZXNzYWdlcyBhcmUgcmVhZC1vbmx5Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIGFsbCB0aGUgaGVhZGVycyBmcm9tIHRoaXMgTWVzc2FnZSBhcyBhbiBlbnVtZXJhdGlvbgorICAgICAqIG9mIEhlYWRlciBvYmplY3RzLiA8cD4KKyAgICAgKgorICAgICAqIE5vdGUgdGhhdCBjZXJ0YWluIGhlYWRlcnMgbWF5IGJlIGVuY29kZWQgYXMgcGVyIFJGQyAyMDQ3IAorICAgICAqIGlmIHRoZXkgY29udGFpbiBub24gVVMtQVNDSUkgY2hhcmFjdGVycyBhbmQgdGhlc2Ugc2hvdWxkIAorICAgICAqIGJlIGRlY29kZWQuIDxwPgorICAgICAqCisgICAgICogQHJldHVybglhcnJheSBvZiBoZWFkZXIgb2JqZWN0cworICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqIEBzZWUgCWphdmF4Lm1haWwuaW50ZXJuZXQuTWltZVV0aWxpdHkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRW51bWVyYXRpb248SGVhZGVyPiBnZXRBbGxIZWFkZXJzKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKGhlYWRlcnMgPT0gbnVsbCkKKwkgICAgbG9hZEhlYWRlcnMoKTsKKwlyZXR1cm4gaGVhZGVycy5nZXRBbGxIZWFkZXJzKCk7CQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiBtYXRjaGluZyBoZWFkZXJzIGZyb20gdGhpcyBNZXNzYWdlIGFzIGFuIEVudW1lcmF0aW9uIG9mCisgICAgICogSGVhZGVyIG9iamVjdHMuCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRW51bWVyYXRpb248SGVhZGVyPiBnZXRNYXRjaGluZ0hlYWRlcnMoU3RyaW5nW10gbmFtZXMpCisJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpZiAoaGVhZGVycyA9PSBudWxsKQorCSAgICBsb2FkSGVhZGVycygpOworCXJldHVybiBoZWFkZXJzLmdldE1hdGNoaW5nSGVhZGVycyhuYW1lcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIG5vbi1tYXRjaGluZyBoZWFkZXJzIGZyb20gdGhpcyBNZXNzYWdlIGFzIGFuCisgICAgICogRW51bWVyYXRpb24gb2YgSGVhZGVyIG9iamVjdHMuCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRW51bWVyYXRpb248SGVhZGVyPiBnZXROb25NYXRjaGluZ0hlYWRlcnMoU3RyaW5nW10gbmFtZXMpCisJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpZiAoaGVhZGVycyA9PSBudWxsKQorCSAgICBsb2FkSGVhZGVycygpOworCXJldHVybiBoZWFkZXJzLmdldE5vbk1hdGNoaW5nSGVhZGVycyhuYW1lcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkIGEgcmF3IFJGQzgyMiBoZWFkZXItbGluZS4gCisgICAgICogVGhyb3dzIElsbGVnYWxXcml0ZUV4Y2VwdGlvbiBiZWNhdXNlIFBPUDMgbWVzc2FnZXMgYXJlIHJlYWQtb25seS4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFdyaXRlRXhjZXB0aW9uIGJlY2F1c2UgdGhlIHVuZGVybHlpbmcKKyAgICAgKgkJCWltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBtZXNzYWdlIGlzCisgICAgICoJCQlvYnRhaW5lZCBmcm9tIGEgUkVBRF9PTkxZIGZvbGRlci4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBhZGRIZWFkZXJMaW5lKFN0cmluZyBsaW5lKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwkvLyBYWFggLSBzaG91bGQgY2hlY2sgZm9yIHJlYWQtb25seSBmb2xkZXI/CisJdGhyb3cgbmV3IElsbGVnYWxXcml0ZUV4Y2VwdGlvbigiUE9QMyBtZXNzYWdlcyBhcmUgcmVhZC1vbmx5Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IGFsbCBoZWFkZXIgbGluZXMgYXMgYW4gRW51bWVyYXRpb24gb2YgU3RyaW5ncy4gQSBIZWFkZXIKKyAgICAgKiBsaW5lIGlzIGEgcmF3IFJGQzgyMiBoZWFkZXItbGluZSwgY29udGFpbmluZyBib3RoIHRoZSAibmFtZSIgCisgICAgICogYW5kICJ2YWx1ZSIgZmllbGQuIAorICAgICAqCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEVudW1lcmF0aW9uPFN0cmluZz4gZ2V0QWxsSGVhZGVyTGluZXMoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpZiAoaGVhZGVycyA9PSBudWxsKQorCSAgICBsb2FkSGVhZGVycygpOworCXJldHVybiBoZWFkZXJzLmdldEFsbEhlYWRlckxpbmVzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IG1hdGNoaW5nIGhlYWRlciBsaW5lcyBhcyBhbiBFbnVtZXJhdGlvbiBvZiBTdHJpbmdzLiAKKyAgICAgKiBBIEhlYWRlciBsaW5lIGlzIGEgcmF3IFJGQzgyMiBoZWFkZXItbGluZSwgY29udGFpbmluZyBib3RoIAorICAgICAqIHRoZSAibmFtZSIgYW5kICJ2YWx1ZSIgZmllbGQuCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRW51bWVyYXRpb248U3RyaW5nPiBnZXRNYXRjaGluZ0hlYWRlckxpbmVzKFN0cmluZ1tdIG5hbWVzKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWlmIChoZWFkZXJzID09IG51bGwpCisJICAgIGxvYWRIZWFkZXJzKCk7CisJcmV0dXJuIGhlYWRlcnMuZ2V0TWF0Y2hpbmdIZWFkZXJMaW5lcyhuYW1lcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IG5vbi1tYXRjaGluZyBoZWFkZXIgbGluZXMgYXMgYW4gRW51bWVyYXRpb24gb2YgU3RyaW5ncy4gCisgICAgICogQSBIZWFkZXIgbGluZSBpcyBhIHJhdyBSRkM4MjIgaGVhZGVyLWxpbmUsIGNvbnRhaW5pbmcgYm90aCAKKyAgICAgKiB0aGUgIm5hbWUiIGFuZCAidmFsdWUiIGZpZWxkLgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEVudW1lcmF0aW9uPFN0cmluZz4gZ2V0Tm9uTWF0Y2hpbmdIZWFkZXJMaW5lcyhTdHJpbmdbXSBuYW1lcykKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpZiAoaGVhZGVycyA9PSBudWxsKQorCSAgICBsb2FkSGVhZGVycygpOworCXJldHVybiBoZWFkZXJzLmdldE5vbk1hdGNoaW5nSGVhZGVyTGluZXMobmFtZXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBPUDMgbWVzc2FnZSBjYW4ndCBiZSBjaGFuZ2VkLiAgVGhpcyBtZXRob2QgdGhyb3dzCisgICAgICogSWxsZWdhbFdyaXRlRXhjZXB0aW9uLgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsV3JpdGVFeGNlcHRpb24gYmVjYXVzZSB0aGUgdW5kZXJseWluZworICAgICAqCQkJaW1wbGVtZW50YXRpb24gZG9lcyBub3Qgc3VwcG9ydCBtb2RpZmljYXRpb24KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzYXZlQ2hhbmdlcygpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCS8vIFBPUDMgTWVzc2FnZXMgYXJlIHJlYWQtb25seQorCXRocm93IG5ldyBJbGxlZ2FsV3JpdGVFeGNlcHRpb24oIlBPUDMgbWVzc2FnZXMgYXJlIHJlYWQtb25seSIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIE91dHB1dCB0aGUgbWVzc2FnZSBhcyBhbiBSRkMgODIyIGZvcm1hdCBzdHJlYW0sIHdpdGhvdXQKKyAgICAgKiBzcGVjaWZpZWQgaGVhZGVycy4gIElmIHRoZSBwcm9wZXJ0eSAibWFpbC5wb3AzLmNhY2hld3JpdGV0byIKKyAgICAgKiBpcyBzZXQgdG8gInRydWUiLCBhbmQgaWdub3JlTGlzdCBpcyBudWxsLCBhbmQgdGhlIG1lc3NhZ2UgaGFzbid0CisgICAgICogYWxyZWFkeSBiZWVuIGNhY2hlZCBhcyBhIHNpZGUgZWZmZWN0IG9mIG90aGVyIG9wZXJhdGlvbnMsIHRoZSBtZXNzYWdlCisgICAgICogY29udGVudCBpcyBjYWNoZWQgYmVmb3JlIGJlaW5nIHdyaXR0ZW4uICBPdGhlcndpc2UsIHRoZSBtZXNzYWdlIGlzCisgICAgICogc3RyZWFtZWQgZGlyZWN0bHkgdG8gdGhlIG91dHB1dCBzdHJlYW0gd2l0aG91dCBiZWluZyBjYWNoZWQuCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uIElPRXhjZXB0aW9uCWlmIGFuIGVycm9yIG9jY3VycyB3cml0aW5nIHRvIHRoZSBzdHJlYW0KKyAgICAgKgkJCQlvciBpZiBhbiBlcnJvciBpcyBnZW5lcmF0ZWQgYnkgdGhlCisgICAgICoJCQkJamF2YXguYWN0aXZhdGlvbiBsYXllci4KKyAgICAgKiBAZXhjZXB0aW9uIE1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKiBAc2VlIGphdmF4LmFjdGl2YXRpb24uRGF0YUhhbmRsZXIjd3JpdGVUbworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCB3cml0ZVRvKE91dHB1dFN0cmVhbSBvcywgU3RyaW5nW10gaWdub3JlTGlzdCkKKwkJCQl0aHJvd3MgSU9FeGNlcHRpb24sIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJSW5wdXRTdHJlYW0gcmF3Y29udGVudCA9IHJhd0RhdGEuZ2V0KCk7CisJaWYgKHJhd2NvbnRlbnQgPT0gbnVsbCAmJiBpZ25vcmVMaXN0ID09IG51bGwgJiYKKwkJCSEoKFBPUDNTdG9yZSkoZm9sZGVyLmdldFN0b3JlKCkpKS5jYWNoZVdyaXRlVG8pIHsKKwkgICAgaWYgKGZvbGRlci5sb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FKSkKKwkJZm9sZGVyLmxvZ2dlci5maW5lKCJzdHJlYW1pbmcgbXNnICIgKyBtc2dudW0pOworCSAgICBpZiAoIWZvbGRlci5nZXRQcm90b2NvbCgpLnJldHIobXNnbnVtLCBvcykpIHsKKwkJZXhwdW5nZWQgPSB0cnVlOworCQl0aHJvdyBuZXcgTWVzc2FnZVJlbW92ZWRFeGNlcHRpb24oImNhbid0IHJldHJpZXZlIG1lc3NhZ2UgIyIgKworCQkgICAgbXNnbnVtICsgIiBpbiBQT1AzTWVzc2FnZS53cml0ZVRvIik7ICAgIC8vIFhYWCAtIHdoYXQgZWxzZT8KKwkgICAgfQorCX0gZWxzZSBpZiAocmF3Y29udGVudCAhPSBudWxsICYmIGlnbm9yZUxpc3QgPT0gbnVsbCkgeworCSAgICAvLyBjYW4ganVzdCBjb3B5IHRoZSBjYWNoZWQgZGF0YQorCSAgICBJbnB1dFN0cmVhbSBpbiA9ICgoU2hhcmVkSW5wdXRTdHJlYW0pcmF3Y29udGVudCkubmV3U3RyZWFtKDAsIC0xKTsKKwkgICAgdHJ5IHsKKwkJYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlWzE2KjEwMjRdOworCQlpbnQgbGVuOworCQl3aGlsZSAoKGxlbiA9IGluLnJlYWQoYnVmKSkgPiAwKQorCQkgICAgb3Mud3JpdGUoYnVmLCAwLCBsZW4pOyAKKwkgICAgfSBmaW5hbGx5IHsKKwkJdHJ5IHsKKwkJICAgIGlmIChpbiAhPSBudWxsKQorCQkJaW4uY2xvc2UoKTsKKwkJfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsgfQorCSAgICB9CisJfSBlbHNlCisJICAgIHN1cGVyLndyaXRlVG8ob3MsIGlnbm9yZUxpc3QpOworICAgIH0KKworICAgIC8qKgorICAgICAqIExvYWQgdGhlIGhlYWRlcnMgZm9yIHRoaXMgbWVzc2FnZSBpbnRvIHRoZSBJbnRlcm5ldEhlYWRlcnMgb2JqZWN0LgorICAgICAqIFRoZSBoZWFkZXJzIGFyZSBmZXRjaGVkIHVzaW5nIHRoZSBQT1AzIFRPUCBjb21tYW5kLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBsb2FkSGVhZGVycygpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWFzc2VydCAhVGhyZWFkLmhvbGRzTG9jayh0aGlzKTsKKwl0cnkgeworCSAgICBib29sZWFuIGZldGNoQ29udGVudCA9IGZhbHNlOworCSAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKwkJaWYgKGhlYWRlcnMgIT0gbnVsbCkgICAgLy8gY2hlY2sgYWdhaW4gdW5kZXIgbG9jaworCQkgICAgcmV0dXJuOworCQlJbnB1dFN0cmVhbSBoZHJzID0gbnVsbDsKKwkJaWYgKCgoUE9QM1N0b3JlKShmb2xkZXIuZ2V0U3RvcmUoKSkpLmRpc2FibGVUb3AgfHwKKwkJCShoZHJzID0gZm9sZGVyLmdldFByb3RvY29sKCkudG9wKG1zZ251bSwgMCkpID09IG51bGwpIHsKKwkJICAgIC8vIHBvc3NpYmx5IGJlY2F1c2UgdGhlIFRPUCBjb21tYW5kIGlzbid0IHN1cHBvcnRlZCwKKwkJICAgIC8vIGxvYWQgaGVhZGVycyBhcyBhIHNpZGUgZWZmZWN0IG9mIGxvYWRpbmcgdGhlIGVudGlyZQorCQkgICAgLy8gY29udGVudC4KKwkJICAgIGZldGNoQ29udGVudCA9IHRydWU7CisJCX0gZWxzZSB7CisJCSAgICB0cnkgeworCQkJaGRyU2l6ZSA9IGhkcnMuYXZhaWxhYmxlKCk7CisJCQloZWFkZXJzID0gbmV3IEludGVybmV0SGVhZGVycyhoZHJzKTsKKwkJICAgIH0gZmluYWxseSB7CisJCQloZHJzLmNsb3NlKCk7CisJCSAgICB9CisJCX0KKwkgICAgfQorCisJICAgIC8qCisJICAgICAqIE91dHNpZGUgdGhlIHN5bmNocm9uaXphdGlvbiBibG9jay4uLgorCSAgICAgKgorCSAgICAgKiBEbyB3ZSBuZWVkIHRvIGZldGNoIHRoZSBlbnRpcmUgbWVzYWdlIGNvbnRlbnQgaW4gb3JkZXIgdG8KKwkgICAgICogbG9hZCB0aGUgaGVhZGVycyBhcyBhIHNpZGUgZWZmZWN0PyAgWWVzLCB0aGVyZSdzIGEgcmFjZQorCSAgICAgKiBjb25kaXRpb24gaGVyZSAtIG11bHRpcGxlIHRocmVhZHMgY291bGQgZGVjaWRlIHRoYXQgdGhlCisJICAgICAqIGNvbnRlbnQgbmVlZHMgdG8gYmUgZmV0Y2hlZC4gIEZvcnR1bmF0ZWx5LCB0aGV5J2xsIGFsbAorCSAgICAgKiBzeW5jaHJvbml6ZSBpbiB0aGUgZ2V0Q29udGVudFN0cmVhbSBtZXRob2QgYW5kIHRoZSBjb250ZW50CisJICAgICAqIHdpbGwgb25seSBiZSBsb2FkZWQgb25jZS4KKwkgICAgICovCisJICAgIGlmIChmZXRjaENvbnRlbnQpIHsKKwkJSW5wdXRTdHJlYW0gY3MgPSBudWxsOworCQl0cnkgeworCQkgICAgY3MgPSBnZXRDb250ZW50U3RyZWFtKCk7CisJCX0gZmluYWxseSB7CisJCSAgICBpZiAoY3MgIT0gbnVsbCkKKwkJCWNzLmNsb3NlKCk7CisJCX0KKwkgICAgfQorCX0gY2F0Y2ggKEVPRkV4Y2VwdGlvbiBlZXgpIHsKKwkgICAgZm9sZGVyLmNsb3NlKGZhbHNlKTsKKwkgICAgdGhyb3cgbmV3IEZvbGRlckNsb3NlZEV4Y2VwdGlvbihmb2xkZXIsIGVleC50b1N0cmluZygpKTsKKwl9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKCJlcnJvciBsb2FkaW5nIFBPUDMgaGVhZGVycyIsIGV4KTsKKwl9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9wb3AzL1BPUDNQcm92aWRlci5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9wb3AzL1BPUDNQcm92aWRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjczNDg4ZTgKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3BvcDMvUE9QM1Byb3ZpZGVyLmphdmEKQEAgLTAsMCArMSwyOSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwucG9wMzsKKworaW1wb3J0IGphdmF4Lm1haWwuUHJvdmlkZXI7CisKKy8qKgorICogVGhlIFBPUDMgcHJvdG9jb2wgcHJvdmlkZXIuCisgKi8KK3B1YmxpYyBjbGFzcyBQT1AzUHJvdmlkZXIgZXh0ZW5kcyBQcm92aWRlciB7CisgICAgcHVibGljIFBPUDNQcm92aWRlcigpIHsKKwlzdXBlcihQcm92aWRlci5UeXBlLlNUT1JFLCAicG9wMyIsIFBPUDNTdG9yZS5jbGFzcy5nZXROYW1lKCksCisJICAgICJPcmFjbGUiLCBudWxsKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3BvcDMvUE9QM1NTTFByb3ZpZGVyLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3BvcDMvUE9QM1NTTFByb3ZpZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWFiN2MyYwotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvcG9wMy9QT1AzU1NMUHJvdmlkZXIuamF2YQpAQCAtMCwwICsxLDI5IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5wb3AzOworCitpbXBvcnQgamF2YXgubWFpbC5Qcm92aWRlcjsKKworLyoqCisgKiBUaGUgUE9QMyBTU0wgcHJvdG9jb2wgcHJvdmlkZXIuCisgKi8KK3B1YmxpYyBjbGFzcyBQT1AzU1NMUHJvdmlkZXIgZXh0ZW5kcyBQcm92aWRlciB7CisgICAgcHVibGljIFBPUDNTU0xQcm92aWRlcigpIHsKKwlzdXBlcihQcm92aWRlci5UeXBlLlNUT1JFLCAicG9wM3MiLCBQT1AzU1NMU3RvcmUuY2xhc3MuZ2V0TmFtZSgpLAorCSAgICAiT3JhY2xlIiwgbnVsbCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9wb3AzL1BPUDNTU0xTdG9yZS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9wb3AzL1BPUDNTU0xTdG9yZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZhMDA1NGMKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3BvcDMvUE9QM1NTTFN0b3JlLmphdmEKQEAgLTAsMCArMSwzMSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwucG9wMzsKKworaW1wb3J0IGphdmF4Lm1haWwuKjsKKworLyoqCisgKiBBIFBPUDMgTWVzc2FnZSBTdG9yZSB1c2luZyBTU0wuICBDb250YWlucyBvbmx5IG9uZSBmb2xkZXIsICJJTkJPWCIuCisgKgorICogQGF1dGhvciAgICAgIEJpbGwgU2hhbm5vbgorICovCitwdWJsaWMgY2xhc3MgUE9QM1NTTFN0b3JlIGV4dGVuZHMgUE9QM1N0b3JlIHsKKworICAgIHB1YmxpYyBQT1AzU1NMU3RvcmUoU2Vzc2lvbiBzZXNzaW9uLCBVUkxOYW1lIHVybCkgeworCXN1cGVyKHNlc3Npb24sIHVybCwgInBvcDNzIiwgdHJ1ZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9wb3AzL1BPUDNTdG9yZS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9wb3AzL1BPUDNTdG9yZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM5ODE4YTEKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3BvcDMvUE9QM1N0b3JlLmphdmEKQEAgLTAsMCArMSw0MjkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLnBvcDM7CisKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKK2ltcG9ydCBqYXZhLnV0aWwubG9nZ2luZy5MZXZlbDsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC4qOworCitpbXBvcnQgamF2YXgubWFpbC4qOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuKjsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5QcmludFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uRU9GRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworCitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuUHJvcFV0aWw7CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuTWFpbExvZ2dlcjsKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5Tb2NrZXRDb25uZWN0RXhjZXB0aW9uOworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLk1haWxDb25uZWN0RXhjZXB0aW9uOworCisvKioKKyAqIEEgUE9QMyBNZXNzYWdlIFN0b3JlLiAgQ29udGFpbnMgb25seSBvbmUgZm9sZGVyLCAiSU5CT1giLgorICoKKyAqIFNlZSB0aGUgPGEgaHJlZj0icGFja2FnZS1zdW1tYXJ5Lmh0bWwiPmNvbS5zdW4ubWFpbC5wb3AzPC9hPiBwYWNrYWdlCisgKiBkb2N1bWVudGF0aW9uIGZvciBmdXJ0aGVyIGluZm9ybWF0aW9uIG9uIHRoZSBQT1AzIHByb3RvY29sIHByb3ZpZGVyLiA8cD4KKyAqCisgKiBAYXV0aG9yICAgICAgQmlsbCBTaGFubm9uCisgKiBAYXV0aG9yICAgICAgSm9obiBNYW5pCisgKi8KK3B1YmxpYyBjbGFzcyBQT1AzU3RvcmUgZXh0ZW5kcyBTdG9yZSB7CisKKyAgICBwcml2YXRlIFN0cmluZyBuYW1lID0gInBvcDMiOwkJLy8gbXkgcHJvdG9jb2wgbmFtZQorICAgIHByaXZhdGUgaW50IGRlZmF1bHRQb3J0ID0gMTEwOwkJLy8gZGVmYXVsdCBQT1AzIHBvcnQKKyAgICBwcml2YXRlIGJvb2xlYW4gaXNTU0wgPSBmYWxzZTsJCS8vIHVzZSBTU0w/CisKKyAgICBwcml2YXRlIFByb3RvY29sIHBvcnQgPSBudWxsOwkJLy8gUE9QMyBwb3J0IGZvciBzZWxmCisgICAgcHJpdmF0ZSBQT1AzRm9sZGVyIHBvcnRPd25lciA9IG51bGw7CS8vIGZvbGRlciBvd25pbmcgcG9ydAorICAgIHByaXZhdGUgU3RyaW5nIGhvc3QgPSBudWxsOwkJCS8vIGhvc3QKKyAgICBwcml2YXRlIGludCBwb3J0TnVtID0gLTE7CisgICAgcHJpdmF0ZSBTdHJpbmcgdXNlciA9IG51bGw7CisgICAgcHJpdmF0ZSBTdHJpbmcgcGFzc3dkID0gbnVsbDsKKyAgICBwcml2YXRlIGJvb2xlYW4gdXNlU3RhcnRUTFMgPSBmYWxzZTsKKyAgICBwcml2YXRlIGJvb2xlYW4gcmVxdWlyZVN0YXJ0VExTID0gZmFsc2U7CisgICAgcHJpdmF0ZSBib29sZWFuIHVzaW5nU1NMID0gZmFsc2U7CisgICAgcHJpdmF0ZSBNYXA8U3RyaW5nLCBTdHJpbmc+IGNhcGFiaWxpdGllczsKKyAgICBwcml2YXRlIE1haWxMb2dnZXIgbG9nZ2VyOworCisgICAgLy8gZm9sbG93aW5nIHNldCBoZXJlIGFuZCBhY2Nlc3NlZCBieSBvdGhlciBjbGFzc2VzIGluIHRoaXMgcGFja2FnZQorICAgIHZvbGF0aWxlIENvbnN0cnVjdG9yPD8+IG1lc3NhZ2VDb25zdHJ1Y3RvciA9IG51bGw7CisgICAgdm9sYXRpbGUgYm9vbGVhbiByc2V0QmVmb3JlUXVpdCA9IGZhbHNlOworICAgIHZvbGF0aWxlIGJvb2xlYW4gZGlzYWJsZVRvcCA9IGZhbHNlOworICAgIHZvbGF0aWxlIGJvb2xlYW4gZm9yZ2V0VG9wSGVhZGVycyA9IGZhbHNlOworICAgIHZvbGF0aWxlIGJvb2xlYW4gc3VwcG9ydHNVaWRsID0gdHJ1ZTsKKyAgICB2b2xhdGlsZSBib29sZWFuIGNhY2hlV3JpdGVUbyA9IGZhbHNlOworICAgIHZvbGF0aWxlIGJvb2xlYW4gdXNlRmlsZUNhY2hlID0gZmFsc2U7CisgICAgdm9sYXRpbGUgRmlsZSBmaWxlQ2FjaGVEaXIgPSBudWxsOworICAgIHZvbGF0aWxlIGJvb2xlYW4ga2VlcE1lc3NhZ2VDb250ZW50ID0gZmFsc2U7CisgICAgdm9sYXRpbGUgYm9vbGVhbiBmaW5hbGl6ZUNsZWFuQ2xvc2UgPSBmYWxzZTsKKworICAgIHB1YmxpYyBQT1AzU3RvcmUoU2Vzc2lvbiBzZXNzaW9uLCBVUkxOYW1lIHVybCkgeworCXRoaXMoc2Vzc2lvbiwgdXJsLCAicG9wMyIsIGZhbHNlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgUE9QM1N0b3JlKFNlc3Npb24gc2Vzc2lvbiwgVVJMTmFtZSB1cmwsCisJCQkJU3RyaW5nIG5hbWUsIGJvb2xlYW4gaXNTU0wpIHsKKwlzdXBlcihzZXNzaW9uLCB1cmwpOworCWlmICh1cmwgIT0gbnVsbCkKKwkgICAgbmFtZSA9IHVybC5nZXRQcm90b2NvbCgpOworCXRoaXMubmFtZSA9IG5hbWU7CisJbG9nZ2VyID0gbmV3IE1haWxMb2dnZXIodGhpcy5nZXRDbGFzcygpLCAiREVCVUcgUE9QMyIsCisJCQkJc2Vzc2lvbi5nZXREZWJ1ZygpLCBzZXNzaW9uLmdldERlYnVnT3V0KCkpOworCisJaWYgKCFpc1NTTCkKKwkgICAgaXNTU0wgPSBQcm9wVXRpbC5nZXRCb29sZWFuUHJvcGVydHkoc2Vzc2lvbi5nZXRQcm9wZXJ0aWVzKCksCisJCQkJIm1haWwuIiArIG5hbWUgKyAiLnNzbC5lbmFibGUiLCBmYWxzZSk7CisJaWYgKGlzU1NMKQorCSAgICB0aGlzLmRlZmF1bHRQb3J0ID0gOTk1OworCWVsc2UKKwkgICAgdGhpcy5kZWZhdWx0UG9ydCA9IDExMDsKKwl0aGlzLmlzU1NMID0gaXNTU0w7CisKKwlyc2V0QmVmb3JlUXVpdCA9IGdldEJvb2xQcm9wKCJyc2V0YmVmb3JlcXVpdCIpOworCWRpc2FibGVUb3AgPSBnZXRCb29sUHJvcCgiZGlzYWJsZXRvcCIpOworCWZvcmdldFRvcEhlYWRlcnMgPSBnZXRCb29sUHJvcCgiZm9yZ2V0dG9waGVhZGVycyIpOworCWNhY2hlV3JpdGVUbyA9IGdldEJvb2xQcm9wKCJjYWNoZXdyaXRldG8iKTsKKwl1c2VGaWxlQ2FjaGUgPSBnZXRCb29sUHJvcCgiZmlsZWNhY2hlLmVuYWJsZSIpOworCVN0cmluZyBkaXIgPSBzZXNzaW9uLmdldFByb3BlcnR5KCJtYWlsLiIgKyBuYW1lICsgIi5maWxlY2FjaGUuZGlyIik7CisJaWYgKGRpciAhPSBudWxsICYmIGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkNPTkZJRykpCisJICAgIGxvZ2dlci5jb25maWcoIm1haWwuIiArIG5hbWUgKyAiLmZpbGVjYWNoZS5kaXI6ICIgKyBkaXIpOworCWlmIChkaXIgIT0gbnVsbCkKKwkgICAgZmlsZUNhY2hlRGlyID0gbmV3IEZpbGUoZGlyKTsKKwlrZWVwTWVzc2FnZUNvbnRlbnQgPSBnZXRCb29sUHJvcCgia2VlcG1lc3NhZ2Vjb250ZW50Iik7CisKKwkvLyBtYWlsLnBvcDMuc3RhcnR0bHMuZW5hYmxlIGVuYWJsZXMgdXNlIG9mIFNUTFMgY29tbWFuZAorCXVzZVN0YXJ0VExTID0gZ2V0Qm9vbFByb3AoInN0YXJ0dGxzLmVuYWJsZSIpOworCisJLy8gbWFpbC5wb3AzLnN0YXJ0dGxzLnJlcXVpcmVkIHJlcXVpcmVzIHVzZSBvZiBTVExTIGNvbW1hbmQKKwlyZXF1aXJlU3RhcnRUTFMgPSBnZXRCb29sUHJvcCgic3RhcnR0bHMucmVxdWlyZWQiKTsKKworCS8vIG1haWwucG9wMy5maW5hbGl6ZWNsZWFuY2xvc2UgcmVxdWlyZXMgY2xlYW4gY2xvc2Ugd2hlbiBmaW5hbGl6aW5nCisJZmluYWxpemVDbGVhbkNsb3NlID0gZ2V0Qm9vbFByb3AoImZpbmFsaXplY2xlYW5jbG9zZSIpOworCisJU3RyaW5nIHMgPSBzZXNzaW9uLmdldFByb3BlcnR5KCJtYWlsLiIgKyBuYW1lICsgIi5tZXNzYWdlLmNsYXNzIik7CisJaWYgKHMgIT0gbnVsbCkgeworCSAgICBsb2dnZXIubG9nKExldmVsLkNPTkZJRywgIm1lc3NhZ2UgY2xhc3M6IHswfSIsIHMpOworCSAgICB0cnkgeworCQlDbGFzc0xvYWRlciBjbCA9IHRoaXMuZ2V0Q2xhc3MoKS5nZXRDbGFzc0xvYWRlcigpOworCisJCS8vIG5vdyBsb2FkIHRoZSBjbGFzcworCQlDbGFzczw/PiBtZXNzYWdlQ2xhc3MgPSBudWxsOworCQl0cnkgeworCQkgICAgLy8gRmlyc3QgdHJ5IHRoZSAiYXBwbGljYXRpb24ncyIgY2xhc3MgbG9hZGVyLgorCQkgICAgLy8gVGhpcyBzaG91bGQgZXZlbnR1YWxseSBiZSByZXBsYWNlZCBieQorCQkgICAgLy8gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXRDb250ZXh0Q2xhc3NMb2FkZXIoKS4KKwkJICAgIG1lc3NhZ2VDbGFzcyA9IENsYXNzLmZvck5hbWUocywgZmFsc2UsIGNsKTsKKwkJfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBleDEpIHsKKwkJICAgIC8vIFRoYXQgZGlkbid0IHdvcmssIG5vdyB0cnkgdGhlICJzeXN0ZW0iIGNsYXNzIGxvYWRlci4KKwkJICAgIC8vIChOZWVkIGJvdGggb2YgdGhlc2UgYmVjYXVzZSBKREsgMS4xIGNsYXNzIGxvYWRlcnMKKwkJICAgIC8vIG1heSBub3QgZGVsZWdhdGUgdG8gdGhlaXIgcGFyZW50IGNsYXNzIGxvYWRlci4pCisJCSAgICBtZXNzYWdlQ2xhc3MgPSBDbGFzcy5mb3JOYW1lKHMpOworCQl9CisKKwkJQ2xhc3M8Pz5bXSBjID0ge2phdmF4Lm1haWwuRm9sZGVyLmNsYXNzLCBpbnQuY2xhc3N9OworCQltZXNzYWdlQ29uc3RydWN0b3IgPSBtZXNzYWdlQ2xhc3MuZ2V0Q29uc3RydWN0b3IoYyk7CisJICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCQlsb2dnZXIubG9nKExldmVsLkNPTkZJRywgImZhaWxlZCB0byBsb2FkIG1lc3NhZ2UgY2xhc3MiLCBleCk7CisJICAgIH0KKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSB2YWx1ZSBvZiBhIGJvb2xlYW4gcHJvcGVydHkuCisgICAgICogUHJpbnQgb3V0IHRoZSB2YWx1ZSBpZiBsb2dnaW5nIGlzIGVuYWJsZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBzeW5jaHJvbml6ZWQgYm9vbGVhbiBnZXRCb29sUHJvcChTdHJpbmcgcHJvcCkgeworCXByb3AgPSAibWFpbC4iICsgbmFtZSArICIuIiArIHByb3A7CisJYm9vbGVhbiB2YWwgPSBQcm9wVXRpbC5nZXRCb29sZWFuUHJvcGVydHkoc2Vzc2lvbi5nZXRQcm9wZXJ0aWVzKCksCisJCQkJCQkgICAgcHJvcCwgZmFsc2UpOworCWlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5DT05GSUcpKQorCSAgICBsb2dnZXIuY29uZmlnKHByb3AgKyAiOiAiICsgdmFsKTsKKwlyZXR1cm4gdmFsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCBhIHJlZmVyZW5jZSB0byB0aGUgc2Vzc2lvbi4KKyAgICAgKi8KKyAgICBzeW5jaHJvbml6ZWQgU2Vzc2lvbiBnZXRTZXNzaW9uKCkgeworICAgICAgICByZXR1cm4gc2Vzc2lvbjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgc3luY2hyb25pemVkIGJvb2xlYW4gcHJvdG9jb2xDb25uZWN0KFN0cmluZyBob3N0LCBpbnQgcG9ydE51bSwKKwkJU3RyaW5nIHVzZXIsIFN0cmluZyBwYXNzd2QpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCQkgICAgCisJLy8gY2hlY2sgZm9yIG5vbi1udWxsIHZhbHVlcyBvZiBob3N0LCBwYXNzd29yZCwgdXNlcgorCWlmIChob3N0ID09IG51bGwgfHwgcGFzc3dkID09IG51bGwgfHwgdXNlciA9PSBudWxsKQorCSAgICByZXR1cm4gZmFsc2U7CisKKwkvLyBpZiBwb3J0IGlzIG5vdCBzcGVjaWZpZWQsIHNldCBpdCB0byB2YWx1ZSBvZiBtYWlsLnBvcDMucG9ydAorICAgICAgICAvLyBwcm9wZXJ0eSBpZiBpdCBleGlzdHMsIG90aGVyd2lzZSBkZWZhdWx0IHRvIDExMAorICAgICAgICBpZiAocG9ydE51bSA9PSAtMSkKKwkgICAgcG9ydE51bSA9IFByb3BVdGlsLmdldEludFByb3BlcnR5KHNlc3Npb24uZ2V0UHJvcGVydGllcygpLAorCQkJCSJtYWlsLiIgKyBuYW1lICsgIi5wb3J0IiwgLTEpOworCisJaWYgKHBvcnROdW0gPT0gLTEpCisJICAgIHBvcnROdW0gPSBkZWZhdWx0UG9ydDsKKworCXRoaXMuaG9zdCA9IGhvc3Q7CisJdGhpcy5wb3J0TnVtID0gcG9ydE51bTsKKwl0aGlzLnVzZXIgPSB1c2VyOworCXRoaXMucGFzc3dkID0gcGFzc3dkOworCXRyeSB7CisJICAgIHBvcnQgPSBnZXRQb3J0KG51bGwpOworCX0gY2F0Y2ggKEVPRkV4Y2VwdGlvbiBlZXgpIHsgCisJCXRocm93IG5ldyBBdXRoZW50aWNhdGlvbkZhaWxlZEV4Y2VwdGlvbihlZXguZ2V0TWVzc2FnZSgpKTsKKwl9IGNhdGNoIChTb2NrZXRDb25uZWN0RXhjZXB0aW9uIHNjZXgpIHsKKwkgICAgdGhyb3cgbmV3IE1haWxDb25uZWN0RXhjZXB0aW9uKHNjZXgpOworCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZXgpIHsgCisJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oIkNvbm5lY3QgZmFpbGVkIiwgaW9leCk7CisJfQorCisJcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2sgd2hldGhlciB0aGlzIHN0b3JlIGlzIGNvbm5lY3RlZC4gT3ZlcnJpZGUgc3VwZXJjbGFzcworICAgICAqIG1ldGhvZCwgdG8gYWN0dWFsbHkgcGluZyBvdXIgc2VydmVyIGNvbm5lY3Rpb24uCisgICAgICovCisgICAgLyoKKyAgICAgKiBOb3RlIHRoYXQgd2UgbWFpbnRhaW4gc29tZXdoYXQgb2YgYW4gaWxsdXNpb24gb2YgYmVpbmcgY29ubmVjdGVkCisgICAgICogZXZlbiBpZiB3ZSdyZSBub3QgcmVhbGx5IGNvbm5lY3RlZC4gIFRoaXMgaXMgYmVjYXVzZSBhIEZvbGRlcgorICAgICAqIGNhbiB1c2UgdGhlIGNvbm5lY3Rpb24gYW5kIGNsb3NlIGl0IHdoZW4gaXQncyBkb25lLiAgSWYgd2UgdGhlbgorICAgICAqIGFzayB3aGV0aGVyIHRoZSBTdG9yZSdzIGNvbm5lY3RlZCB3ZSB3YW50IHRoZSBhbnN3ZXIgdG8gYmUgdHJ1ZSwKKyAgICAgKiBhcyBsb25nIGFzIHdlIGNhbiByZWNvbm5lY3QgYXQgdGhhdCBwb2ludC4gIFRoaXMgbWVhbnMgdGhhdCB3ZQorICAgICAqIG5lZWQgdG8gYmUgYWJsZSB0byByZWNvbm5lY3QgdGhlIFN0b3JlIG9uIGRlbWFuZC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGJvb2xlYW4gaXNDb25uZWN0ZWQoKSB7CisJaWYgKCFzdXBlci5pc0Nvbm5lY3RlZCgpKQorCSAgICAvLyBpZiB3ZSBoYXZlbid0IGJlZW4gY29ubmVjdGVkIGF0IGFsbCwgZG9uJ3QgYm90aGVyIHdpdGgKKwkgICAgLy8gdGhlIE5PT1AuCisJICAgIHJldHVybiBmYWxzZTsKKwl0cnkgeworCSAgICBpZiAocG9ydCA9PSBudWxsKQorCQlwb3J0ID0gZ2V0UG9ydChudWxsKTsKKwkgICAgZWxzZSBpZiAoIXBvcnQubm9vcCgpKQorCQl0aHJvdyBuZXcgSU9FeGNlcHRpb24oIk5PT1AgZmFpbGVkIik7CisJICAgIHJldHVybiB0cnVlOworCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZXgpIHsKKwkgICAgLy8gbm8gbG9uZ2VyIGNvbm5lY3RlZCwgY2xvc2UgaXQgZG93bgorCSAgICB0cnkgeworCQlzdXBlci5jbG9zZSgpOwkJLy8gbm90aWZpZXMgbGlzdGVuZXJzCisJICAgIH0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBtZXgpIHsKKwkJLy8gaWdub3JlIGl0CisJICAgIH0KKwkgICAgcmV0dXJuIGZhbHNlOworCX0KKyAgICB9CisKKyAgICBzeW5jaHJvbml6ZWQgUHJvdG9jb2wgZ2V0UG9ydChQT1AzRm9sZGVyIG93bmVyKSB0aHJvd3MgSU9FeGNlcHRpb24geworCVByb3RvY29sIHA7CisKKwkvLyBpZiB3ZSBhbHJlYWR5IGhhdmUgYSBwb3J0LCByZW1lbWJlciB3aG8ncyB1c2luZyBpdAorCWlmIChwb3J0ICE9IG51bGwgJiYgcG9ydE93bmVyID09IG51bGwpIHsKKwkgICAgcG9ydE93bmVyID0gb3duZXI7CisJICAgIHJldHVybiBwb3J0OworCX0KKworCS8vIG5lZWQgYSBuZXcgcG9ydCwgY3JlYXRlIGl0IGFuZCB0cnkgdG8gbG9naW4KKwlwID0gbmV3IFByb3RvY29sKGhvc3QsIHBvcnROdW0sIGxvZ2dlciwKKwkgICAgc2Vzc2lvbi5nZXRQcm9wZXJ0aWVzKCksICJtYWlsLiIgKyBuYW1lLCBpc1NTTCk7CisKKwlpZiAodXNlU3RhcnRUTFMgfHwgcmVxdWlyZVN0YXJ0VExTKSB7CisJICAgIGlmIChwLmhhc0NhcGFiaWxpdHkoIlNUTFMiKSkgeworCQlpZiAocC5zdGxzKCkpIHsKKwkJICAgIC8vIHN1Y2Nlc3MsIHJlZnJlc2ggY2FwYWJpbGl0aWVzCisJCSAgICBwLnNldENhcGFiaWxpdGllcyhwLmNhcGEoKSk7CisJCX0gZWxzZSBpZiAocmVxdWlyZVN0YXJ0VExTKSB7CisJCSAgICBsb2dnZXIuZmluZSgiU1RMUyByZXF1aXJlZCBidXQgZmFpbGVkIik7CisJCSAgICB0aHJvdyBjbGVhbnVwQW5kVGhyb3cocCwKKwkJCSAgICBuZXcgRU9GRXhjZXB0aW9uKCJTVExTIHJlcXVpcmVkIGJ1dCBmYWlsZWQiKSk7CisJCX0KKwkgICAgfSBlbHNlIGlmIChyZXF1aXJlU3RhcnRUTFMpIHsKKwkJbG9nZ2VyLmZpbmUoIlNUTFMgcmVxdWlyZWQgYnV0IG5vdCBzdXBwb3J0ZWQiKTsKKwkJdGhyb3cgY2xlYW51cEFuZFRocm93KHAsCisJCQluZXcgRU9GRXhjZXB0aW9uKCJTVExTIHJlcXVpcmVkIGJ1dCBub3Qgc3VwcG9ydGVkIikpOworCSAgICB9CisJfQorCisJY2FwYWJpbGl0aWVzID0gcC5nZXRDYXBhYmlsaXRpZXMoKTsJLy8gc2F2ZSBmb3IgbGF0ZXIsIG1heSBiZSBudWxsCisJdXNpbmdTU0wgPSBwLmlzU1NMKCk7CQkJLy8gaW4gY2FzZSBhbnlvbmUgYXNrcworCisJLyoKKwkgKiBJZiB3ZSBoYXZlbid0IGV4cGxpY2l0bHkgZGlzYWJsZWQgdXNlIG9mIHRoZSBUT1AgY29tbWFuZCwKKwkgKiBhbmQgdGhlIHNlcnZlciBoYXMgcHJvdmlkZWQgaXRzIGNhcGFiaWxpdGllcywKKwkgKiBhbmQgdGhlIHNlcnZlciBkb2Vzbid0IHN1cHBvcnQgdGhlIFRPUCBjb21tYW5kLAorCSAqIGRpc2FibGUgdGhlIFRPUCBjb21tYW5kLgorCSAqLworCWlmICghZGlzYWJsZVRvcCAmJgorCQljYXBhYmlsaXRpZXMgIT0gbnVsbCAmJiAhY2FwYWJpbGl0aWVzLmNvbnRhaW5zS2V5KCJUT1AiKSkgeworCSAgICBkaXNhYmxlVG9wID0gdHJ1ZTsKKwkgICAgbG9nZ2VyLmZpbmUoInNlcnZlciBkb2Vzbid0IHN1cHBvcnQgVE9QLCBkaXNhYmxpbmcgaXQiKTsKKwl9CisKKwlzdXBwb3J0c1VpZGwgPSBjYXBhYmlsaXRpZXMgPT0gbnVsbCB8fCBjYXBhYmlsaXRpZXMuY29udGFpbnNLZXkoIlVJREwiKTsKKworCVN0cmluZyBtc2cgPSBudWxsOworCWlmICgobXNnID0gcC5sb2dpbih1c2VyLCBwYXNzd2QpKSAhPSBudWxsKSB7CisJICAgIHRocm93IGNsZWFudXBBbmRUaHJvdyhwLCBuZXcgRU9GRXhjZXB0aW9uKG1zZykpOworCX0KKworCS8qCisJICogSWYgYSBGb2xkZXIgY2xvc2VzIHRoZSBwb3J0LCBhbmQgdGhlbiBhIEZvbGRlcgorCSAqIGlzIG9wZW5lZCwgdGhlIFN0b3JlIHdvbid0IGhhdmUgYSBwb3J0LiAgSW4gdGhhdAorCSAqIGNhc2UsIHRoZSBnZXRQb3J0IGNhbGwgd2lsbCBjb21lIGZyb20gRm9sZGVyLm9wZW4sCisJICogYnV0IHdlIG5lZWQgdG8ga2VlcCB0cmFjayBvZiB0aGUgcG9ydCBpbiB0aGUgU3RvcmUKKwkgKiBzbyB0aGF0IGEgbGF0ZXIgY2FsbCB0byBGb2xkZXIuaXNPcGVuLCB3aGljaCBjYWxscworCSAqIFN0b3JlLmlzQ29ubmVjdGVkLCB3aWxsIHVzZSB0aGUgc2FtZSBwb3J0LgorCSAqLworCWlmIChwb3J0ID09IG51bGwgJiYgb3duZXIgIT0gbnVsbCkgeworCSAgICBwb3J0ID0gcDsKKwkgICAgcG9ydE93bmVyID0gb3duZXI7CisJfQorCWlmIChwb3J0T3duZXIgPT0gbnVsbCkKKwkgICAgcG9ydE93bmVyID0gb3duZXI7CisJcmV0dXJuIHA7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgSU9FeGNlcHRpb24gY2xlYW51cEFuZFRocm93KFByb3RvY29sIHAsIElPRXhjZXB0aW9uIGlmZSkgeworCXRyeSB7CisJICAgIHAucXVpdCgpOworCX0gY2F0Y2ggKFRocm93YWJsZSB0aHIpIHsKKwkgICAgaWYgKGlzUmVjb3ZlcmFibGUodGhyKSkgeworCQlpZmUuYWRkU3VwcHJlc3NlZCh0aHIpOworCSAgICB9IGVsc2UgeworCQl0aHIuYWRkU3VwcHJlc3NlZChpZmUpOworCQlpZiAodGhyIGluc3RhbmNlb2YgRXJyb3IpIHsKKwkJICAgIHRocm93IChFcnJvcikgdGhyOworCQl9CisJCWlmICh0aHIgaW5zdGFuY2VvZiBSdW50aW1lRXhjZXB0aW9uKSB7CisJCSAgICB0aHJvdyAoUnVudGltZUV4Y2VwdGlvbikgdGhyOworCQl9CisJCXRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbiIsIHRocik7CisJICAgIH0KKwl9CisJcmV0dXJuIGlmZTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzUmVjb3ZlcmFibGUoVGhyb3dhYmxlIHQpIHsKKwlyZXR1cm4gKHQgaW5zdGFuY2VvZiBFeGNlcHRpb24pIHx8ICh0IGluc3RhbmNlb2YgTGlua2FnZUVycm9yKTsKKyAgICB9CisKKyAgICBzeW5jaHJvbml6ZWQgdm9pZCBjbG9zZVBvcnQoUE9QM0ZvbGRlciBvd25lcikgeworCWlmIChwb3J0T3duZXIgPT0gb3duZXIpIHsKKwkgICAgcG9ydCA9IG51bGw7CisJICAgIHBvcnRPd25lciA9IG51bGw7CisJfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBjbG9zZSgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWNsb3NlKGZhbHNlKTsKKyAgICB9CisKKyAgICBzeW5jaHJvbml6ZWQgdm9pZCBjbG9zZShib29sZWFuIGZvcmNlKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwl0cnkgeworCSAgICBpZiAocG9ydCAhPSBudWxsKSB7CisJCWlmIChmb3JjZSkKKwkJICAgIHBvcnQuY2xvc2UoKTsKKwkJZWxzZQorCQkgICAgcG9ydC5xdWl0KCk7CisJICAgIH0KKwl9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2V4KSB7CisJfSBmaW5hbGx5IHsKKwkgICAgcG9ydCA9IG51bGw7CisKKwkgICAgLy8gdG8gc2V0IHRoZSBzdGF0ZSBhbmQgc2VuZCB0aGUgY2xvc2VkIGNvbm5lY3Rpb24gZXZlbnQKKwkgICAgc3VwZXIuY2xvc2UoKTsKKwl9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEZvbGRlciBnZXREZWZhdWx0Rm9sZGVyKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJY2hlY2tDb25uZWN0ZWQoKTsKKwlyZXR1cm4gbmV3IERlZmF1bHRGb2xkZXIodGhpcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogT25seSB0aGUgbmFtZSAiSU5CT1giIGlzIHN1cHBvcnRlZC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRm9sZGVyIGdldEZvbGRlcihTdHJpbmcgbmFtZSkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJY2hlY2tDb25uZWN0ZWQoKTsKKwlyZXR1cm4gbmV3IFBPUDNGb2xkZXIodGhpcywgbmFtZSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEZvbGRlciBnZXRGb2xkZXIoVVJMTmFtZSB1cmwpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWNoZWNrQ29ubmVjdGVkKCk7CisJcmV0dXJuIG5ldyBQT1AzRm9sZGVyKHRoaXMsIHVybC5nZXRGaWxlKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiBhIE1hcCBvZiB0aGUgY2FwYWJpbGl0aWVzIHRoZSBzZXJ2ZXIgcHJvdmlkZWQsCisgICAgICogYXMgcGVyIFJGQyAyNDQ5LiAgSWYgdGhlIHNlcnZlciBkb2Vzbid0IHN1cHBvcnQgUkZDIDI0NDksCisgICAgICogYW4gZW10cHkgTWFwIGlzIHJldHVybmVkLiAgVGhlIHJldHVybmVkIE1hcCBjYW4gbm90IGJlIG1vZGlmaWVkLgorICAgICAqIFRoZSBrZXkgdG8gdGhlIE1hcCBpcyB0aGUgdXBwZXIgY2FzZSBjYXBhYmlsaXR5IG5hbWUgYXMKKyAgICAgKiBhIFN0cmluZy4gIFRoZSB2YWx1ZSBvZiB0aGUgZW50cnkgaXMgdGhlIGVudGlyZSBTdHJpbmcKKyAgICAgKiBjYXBhYmlsaXR5IGxpbmUgcmV0dXJuZWQgYnkgdGhlIHNlcnZlci4gPHA+CisgICAgICoKKyAgICAgKiBGb3IgZXhhbXBsZSwgdG8gY2hlY2sgaWYgdGhlIHNlcnZlciBzdXBwb3J0cyB0aGUgU1RMUyBjYXBhYmlsaXR5LCB1c2U6CisgICAgICogPGNvZGU+aWYgKHN0b3JlLmNhcGFiaWxpdGllcygpLmNvbnRhaW5zS2V5KCJTVExTIikpIC4uLjwvY29kZT4KKyAgICAgKgorICAgICAqIEByZXR1cm4JTWFwIG9mIGNhcGFiaWxpdGllcworICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjQuMworICAgICAqLworICAgIHB1YmxpYyBNYXA8U3RyaW5nLCBTdHJpbmc+IGNhcGFiaWxpdGllcygpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCU1hcDxTdHJpbmcsIFN0cmluZz4gYzsKKwlzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKwkgICAgYyA9IGNhcGFiaWxpdGllczsKKwl9CisJaWYgKGMgIT0gbnVsbCkKKwkgICAgcmV0dXJuIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChjKTsKKwllbHNlCisJICAgIHJldHVybiBDb2xsZWN0aW9ucy48U3RyaW5nLCBTdHJpbmc+ZW1wdHlNYXAoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJcyB0aGlzIFBPUDNTdG9yZSB1c2luZyBTU0wgdG8gY29ubmVjdCB0byB0aGUgc2VydmVyPworICAgICAqCisgICAgICogQHJldHVybgl0cnVlIGlmIHVzaW5nIFNTTAorICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjQuNgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgYm9vbGVhbiBpc1NTTCgpIHsKKwlyZXR1cm4gdXNpbmdTU0w7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgZmluYWxpemUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKwl0cnkgeworCSAgICBpZiAocG9ydCAhPSBudWxsKQkvLyBkb24ndCBmb3JjZSBhIGNvbm5lY3Rpb24gYXR0ZW1wdAorCQljbG9zZSghZmluYWxpemVDbGVhbkNsb3NlKTsKKwl9IGZpbmFsbHkgeworCSAgICBzdXBlci5maW5hbGl6ZSgpOworCX0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2hlY2tDb25uZWN0ZWQoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpZiAoIXN1cGVyLmlzQ29ubmVjdGVkKCkpCisJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oIk5vdCBjb25uZWN0ZWQiKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3BvcDMvUHJvdG9jb2wuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvcG9wMy9Qcm90b2NvbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJmYmEwZDkKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3BvcDMvUHJvdG9jb2wuamF2YQpAQCAtMCwwICsxLDg2MSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwucG9wMzsKKworaW1wb3J0IGphdmEudXRpbC4qOworaW1wb3J0IGphdmEubmV0Lio7CitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmEuc2VjdXJpdHkuKjsKK2ltcG9ydCBqYXZhLnV0aWwubG9nZ2luZy5MZXZlbDsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNvY2tldDsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLlByb3BVdGlsOworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLk1haWxMb2dnZXI7CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuU29ja2V0RmV0Y2hlcjsKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5MaW5lSW5wdXRTdHJlYW07CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuVHJhY2VJbnB1dFN0cmVhbTsKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5UcmFjZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5TaGFyZWRCeXRlQXJyYXlPdXRwdXRTdHJlYW07CisKK2NsYXNzIFJlc3BvbnNlIHsKKyAgICBib29sZWFuIG9rID0gZmFsc2U7CQkvLyB0cnVlIGlmICIrT0siCisgICAgU3RyaW5nIGRhdGEgPSBudWxsOwkJLy8gcmVzdCBvZiBsaW5lIGFmdGVyICIrT0siIG9yICItRVJSIgorICAgIElucHV0U3RyZWFtIGJ5dGVzID0gbnVsbDsJLy8gYWxsIHRoZSBieXRlcyBmcm9tIGEgbXVsdGktbGluZSByZXNwb25zZQorfQorCisvKioKKyAqIFRoaXMgY2xhc3MgcHJvdmlkZXMgYSBQT1AzIGNvbm5lY3Rpb24gYW5kIGltcGxlbWVudHMgCisgKiB0aGUgUE9QMyBwcm90b2NvbCByZXF1ZXN0cy4KKyAqCisgKiBBUE9QIHN1cHBvcnQgY291cnRlc3kgb2YgImNoYW1uZXNzIi4KKyAqCisgKiBAYXV0aG9yICAgICAgQmlsbCBTaGFubm9uCisgKi8KK2NsYXNzIFByb3RvY29sIHsKKyAgICBwcml2YXRlIFNvY2tldCBzb2NrZXQ7CQkvLyBQT1AzIHNvY2tldAorICAgIHByaXZhdGUgU3RyaW5nIGhvc3Q7CQkvLyBob3N0IHdlJ3JlIGNvbm5lY3RlZCB0bworICAgIHByaXZhdGUgUHJvcGVydGllcyBwcm9wczsJCS8vIHNlc3Npb24gcHJvcGVydGllcworICAgIHByaXZhdGUgU3RyaW5nIHByZWZpeDsJCS8vIHByb3RvY29sIG5hbWUgcHJlZml4LCBmb3IgcHJvcHMKKyAgICBwcml2YXRlIEJ1ZmZlcmVkUmVhZGVyIGlucHV0OwkvLyBpbnB1dCBidWYKKyAgICBwcml2YXRlIFByaW50V3JpdGVyIG91dHB1dDsJCS8vIG91dHB1dCBidWYKKyAgICBwcml2YXRlIFRyYWNlSW5wdXRTdHJlYW0gdHJhY2VJbnB1dDsKKyAgICBwcml2YXRlIFRyYWNlT3V0cHV0U3RyZWFtIHRyYWNlT3V0cHV0OworICAgIHByaXZhdGUgTWFpbExvZ2dlciBsb2dnZXI7CisgICAgcHJpdmF0ZSBNYWlsTG9nZ2VyIHRyYWNlTG9nZ2VyOworICAgIHByaXZhdGUgU3RyaW5nIGFwb3BDaGFsbGVuZ2UgPSBudWxsOworICAgIHByaXZhdGUgTWFwPFN0cmluZywgU3RyaW5nPiBjYXBhYmlsaXRpZXMgPSBudWxsOworICAgIHByaXZhdGUgYm9vbGVhbiBwaXBlbGluaW5nOworICAgIHByaXZhdGUgYm9vbGVhbiBub2F1dGhkZWJ1ZyA9IHRydWU7CS8vIGhpZGUgYXV0aCBpbmZvIGluIGRlYnVnIG91dHB1dAorICAgIHByaXZhdGUgYm9vbGVhbiB0cmFjZVN1c3BlbmRlZDsJLy8gdGVtcG9yYXJpbHkgc3VzcGVuZCB0cmFjaW5nCisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUE9QM19QT1JUID0gMTEwOyAvLyBzdGFuZGFyZCBQT1AzIHBvcnQKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ1JMRiA9ICJcclxuIjsKKyAgICAvLyBzb21ldGltZXMgdGhlIHJldHVybmVkIHNpemUgaXNuJ3QgcXVpdGUgYmlnIGVub3VnaAorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTTE9QID0gMTI4OworCisgICAgLyoqIAorICAgICAqIE9wZW4gYSBjb25uZWN0aW9uIHRvIHRoZSBQT1AzIHNlcnZlci4KKyAgICAgKi8KKyAgICBQcm90b2NvbChTdHJpbmcgaG9zdCwgaW50IHBvcnQsIE1haWxMb2dnZXIgbG9nZ2VyLAorCQkJUHJvcGVydGllcyBwcm9wcywgU3RyaW5nIHByZWZpeCwgYm9vbGVhbiBpc1NTTCkKKwkJCXRocm93cyBJT0V4Y2VwdGlvbiB7CisJdGhpcy5ob3N0ID0gaG9zdDsKKwl0aGlzLnByb3BzID0gcHJvcHM7CisJdGhpcy5wcmVmaXggPSBwcmVmaXg7CisJdGhpcy5sb2dnZXIgPSBsb2dnZXI7CisJdHJhY2VMb2dnZXIgPSBsb2dnZXIuZ2V0U3ViTG9nZ2VyKCJwcm90b2NvbCIsIG51bGwpOworCW5vYXV0aGRlYnVnID0gIVByb3BVdGlsLmdldEJvb2xlYW5Qcm9wZXJ0eShwcm9wcywKKwkJCSAgICAibWFpbC5kZWJ1Zy5hdXRoIiwgZmFsc2UpOworCisJUmVzcG9uc2UgcjsKKwlib29sZWFuIGVuYWJsZUFQT1AgPSBnZXRCb29sUHJvcChwcm9wcywgcHJlZml4ICsgIi5hcG9wLmVuYWJsZSIpOworCWJvb2xlYW4gZGlzYWJsZUNhcGEgPSBnZXRCb29sUHJvcChwcm9wcywgcHJlZml4ICsgIi5kaXNhYmxlY2FwYSIpOworCXRyeSB7CisJICAgIGlmIChwb3J0ID09IC0xKQorCQlwb3J0ID0gUE9QM19QT1JUOworCSAgICBpZiAobG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuRklORSkpCisJCWxvZ2dlci5maW5lKCJjb25uZWN0aW5nIHRvIGhvc3QgXCIiICsgaG9zdCArCisJCQkJIlwiLCBwb3J0ICIgKyBwb3J0ICsgIiwgaXNTU0wgIiArIGlzU1NMKTsKKworCSAgICBzb2NrZXQgPSBTb2NrZXRGZXRjaGVyLmdldFNvY2tldChob3N0LCBwb3J0LCBwcm9wcywgcHJlZml4LCBpc1NTTCk7CisJICAgIGluaXRTdHJlYW1zKCk7CisJICAgIHIgPSBzaW1wbGVDb21tYW5kKG51bGwpOworCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkgeworCSAgICB0aHJvdyBjbGVhbnVwQW5kVGhyb3coc29ja2V0LCBpb2UpOworCX0KKworCWlmICghci5vaykgeworCSAgICB0aHJvdyBjbGVhbnVwQW5kVGhyb3coc29ja2V0LCBuZXcgSU9FeGNlcHRpb24oIkNvbm5lY3QgZmFpbGVkIikpOworCX0KKwlpZiAoZW5hYmxlQVBPUCAmJiByLmRhdGEgIT0gbnVsbCkgeworCSAgICBpbnQgY2hhbGxTdGFydCA9IHIuZGF0YS5pbmRleE9mKCc8Jyk7CS8vIHN0YXJ0IG9mIGNoYWxsZW5nZQorCSAgICBpbnQgY2hhbGxFbmQgPSByLmRhdGEuaW5kZXhPZignPicsIGNoYWxsU3RhcnQpOyAvLyBlbmQgb2YgY2hhbGxlbmdlCisJICAgIGlmIChjaGFsbFN0YXJ0ICE9IC0xICYmIGNoYWxsRW5kICE9IC0xKQorCQlhcG9wQ2hhbGxlbmdlID0gci5kYXRhLnN1YnN0cmluZyhjaGFsbFN0YXJ0LCBjaGFsbEVuZCArIDEpOworCSAgICBsb2dnZXIubG9nKExldmVsLkZJTkUsICJBUE9QIGNoYWxsZW5nZTogezB9IiwgYXBvcENoYWxsZW5nZSk7CisJfQorCisJLy8gaWYgc2VydmVyIHN1cHBvcnRzIFJGQyAyNDQ5LCBzZXQgY2FwYWJpbGl0aWVzCisJaWYgKCFkaXNhYmxlQ2FwYSkKKwkgICAgc2V0Q2FwYWJpbGl0aWVzKGNhcGEoKSk7CisKKwlwaXBlbGluaW5nID0gaGFzQ2FwYWJpbGl0eSgiUElQRUxJTklORyIpIHx8CisJICAgIFByb3BVdGlsLmdldEJvb2xlYW5Qcm9wZXJ0eShwcm9wcywgcHJlZml4ICsgIi5waXBlbGluaW5nIiwgZmFsc2UpOworCWlmIChwaXBlbGluaW5nKQorCSAgICBsb2dnZXIuY29uZmlnKCJQSVBFTElOSU5HIGVuYWJsZWQiKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBJT0V4Y2VwdGlvbiBjbGVhbnVwQW5kVGhyb3coU29ja2V0IHNvY2tldCwgSU9FeGNlcHRpb24gaWZlKSB7CisJdHJ5IHsKKwkgICAgc29ja2V0LmNsb3NlKCk7CisJfSBjYXRjaCAoVGhyb3dhYmxlIHRocikgeworCSAgICBpZiAoaXNSZWNvdmVyYWJsZSh0aHIpKSB7CisJCWlmZS5hZGRTdXBwcmVzc2VkKHRocik7CisJICAgIH0gZWxzZSB7CisJCXRoci5hZGRTdXBwcmVzc2VkKGlmZSk7CisJCWlmICh0aHIgaW5zdGFuY2VvZiBFcnJvcikgeworCQkgICAgdGhyb3cgKEVycm9yKSB0aHI7CisJCX0KKwkJaWYgKHRociBpbnN0YW5jZW9mIFJ1bnRpbWVFeGNlcHRpb24pIHsKKwkJICAgIHRocm93IChSdW50aW1lRXhjZXB0aW9uKSB0aHI7CisJCX0KKwkJdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oInVuZXhwZWN0ZWQgZXhjZXB0aW9uIiwgdGhyKTsKKwkgICAgfQorCX0KKwlyZXR1cm4gaWZlOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNSZWNvdmVyYWJsZShUaHJvd2FibGUgdCkgeworCXJldHVybiAodCBpbnN0YW5jZW9mIEV4Y2VwdGlvbikgfHwgKHQgaW5zdGFuY2VvZiBMaW5rYWdlRXJyb3IpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgdmFsdWUgb2YgYSBib29sZWFuIHByb3BlcnR5LgorICAgICAqIFByaW50IG91dCB0aGUgdmFsdWUgaWYgbG9nZ2luZyBpcyBlbmFibGVkLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgc3luY2hyb25pemVkIGJvb2xlYW4gZ2V0Qm9vbFByb3AoUHJvcGVydGllcyBwcm9wcywKKwkJCQlTdHJpbmcgcHJvcCkgeworCWJvb2xlYW4gdmFsID0gUHJvcFV0aWwuZ2V0Qm9vbGVhblByb3BlcnR5KHByb3BzLCBwcm9wLCBmYWxzZSk7CisJaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkNPTkZJRykpCisJICAgIGxvZ2dlci5jb25maWcocHJvcCArICI6ICIgKyB2YWwpOworCXJldHVybiB2YWw7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGluaXRTdHJlYW1zKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlib29sZWFuIHF1b3RlID0gUHJvcFV0aWwuZ2V0Qm9vbGVhblByb3BlcnR5KHByb3BzLAorCQkJCQkibWFpbC5kZWJ1Zy5xdW90ZSIsIGZhbHNlKTsKKwl0cmFjZUlucHV0ID0KKwkgICAgbmV3IFRyYWNlSW5wdXRTdHJlYW0oc29ja2V0LmdldElucHV0U3RyZWFtKCksIHRyYWNlTG9nZ2VyKTsKKwl0cmFjZUlucHV0LnNldFF1b3RlKHF1b3RlKTsKKworCXRyYWNlT3V0cHV0ID0KKwkgICAgbmV3IFRyYWNlT3V0cHV0U3RyZWFtKHNvY2tldC5nZXRPdXRwdXRTdHJlYW0oKSwgdHJhY2VMb2dnZXIpOworCXRyYWNlT3V0cHV0LnNldFF1b3RlKHF1b3RlKTsKKworCS8vIHNob3VsZCBiZSBVUy1BU0NJSSwgYnV0IG5vdCBhbGwgSkRLJ3Mgc3VwcG9ydCBpdCBzbyB1c2UgaXNvLTg4NTktMQorCWlucHV0ID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBJbnB1dFN0cmVhbVJlYWRlcih0cmFjZUlucHV0LAorCQkJCQkJCSAgICAiaXNvLTg4NTktMSIpKTsKKwlvdXRwdXQgPSBuZXcgUHJpbnRXcml0ZXIoCisJCSAgICBuZXcgQnVmZmVyZWRXcml0ZXIoCisJCQluZXcgT3V0cHV0U3RyZWFtV3JpdGVyKHRyYWNlT3V0cHV0LCAiaXNvLTg4NTktMSIpKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgZmluYWxpemUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKwl0cnkgeworCSAgICBpZiAoc29ja2V0ICE9IG51bGwpCS8vIEZvcmdvdCB0byBsb2dvdXQgPyEKKwkJcXVpdCgpOworCX0gZmluYWxseSB7CisJICAgIHN1cGVyLmZpbmFsaXplKCk7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlIHRoZSBjYXBhYmlsaXRpZXMgZnJvbSBhIENBUEEgcmVzcG9uc2UuCisgICAgICovCisgICAgc3luY2hyb25pemVkIHZvaWQgc2V0Q2FwYWJpbGl0aWVzKElucHV0U3RyZWFtIGluKSB7CisJaWYgKGluID09IG51bGwpIHsKKwkgICAgY2FwYWJpbGl0aWVzID0gbnVsbDsKKwkgICAgcmV0dXJuOworCX0KKworCWNhcGFiaWxpdGllcyA9IG5ldyBIYXNoTWFwPD4oMTApOworCUJ1ZmZlcmVkUmVhZGVyIHIgPSBudWxsOworCXRyeSB7CisJICAgIHIgPSBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IElucHV0U3RyZWFtUmVhZGVyKGluLCAidXMtYXNjaWkiKSk7CisJfSBjYXRjaCAoVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBleCkgeworCSAgICAvLyBzaG91bGQgbmV2ZXIgaGFwcGVuCisJICAgIGFzc2VydCBmYWxzZTsKKwl9CisJU3RyaW5nIHM7CisJdHJ5IHsKKwkgICAgd2hpbGUgKChzID0gci5yZWFkTGluZSgpKSAhPSBudWxsKSB7CisJCVN0cmluZyBjYXAgPSBzOworCQlpbnQgaSA9IGNhcC5pbmRleE9mKCcgJyk7CisJCWlmIChpID4gMCkKKwkJICAgIGNhcCA9IGNhcC5zdWJzdHJpbmcoMCwgaSk7CisJCWNhcGFiaWxpdGllcy5wdXQoY2FwLnRvVXBwZXJDYXNlKExvY2FsZS5FTkdMSVNIKSwgcyk7CisJICAgIH0KKwl9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworCSAgICAvLyBzaG91bGQgbmV2ZXIgaGFwcGVuCisJfSBmaW5hbGx5IHsKKwkgICAgdHJ5IHsKKwkJaW4uY2xvc2UoKTsKKwkgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsgfQorCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVjayB3aGV0aGVyIHRoZSBnaXZlbiBjYXBhYmlsaXR5IGlzIHN1cHBvcnRlZCBieQorICAgICAqIHRoaXMgc2VydmVyLiBSZXR1cm5zIDxjb2RlPnRydWU8L2NvZGU+IGlmIHNvLCBvdGhlcndpc2UKKyAgICAgKiByZXR1cm5zIGZhbHNlLgorICAgICAqLworICAgIHN5bmNocm9uaXplZCBib29sZWFuIGhhc0NhcGFiaWxpdHkoU3RyaW5nIGMpIHsKKwlyZXR1cm4gY2FwYWJpbGl0aWVzICE9IG51bGwgJiYKKwkJY2FwYWJpbGl0aWVzLmNvbnRhaW5zS2V5KGMudG9VcHBlckNhc2UoTG9jYWxlLkVOR0xJU0gpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIG1hcCBvZiBjYXBhYmlsaXRpZXMgcmV0dXJuZWQgYnkgdGhlIHNlcnZlci4KKyAgICAgKi8KKyAgICBzeW5jaHJvbml6ZWQgTWFwPFN0cmluZywgU3RyaW5nPiBnZXRDYXBhYmlsaXRpZXMoKSB7CisJcmV0dXJuIGNhcGFiaWxpdGllczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb2dpbiB0byB0aGUgc2VydmVyLCB1c2luZyB0aGUgVVNFUiBhbmQgUEFTUyBjb21tYW5kcy4KKyAgICAgKi8KKyAgICBzeW5jaHJvbml6ZWQgU3RyaW5nIGxvZ2luKFN0cmluZyB1c2VyLCBTdHJpbmcgcGFzc3dvcmQpCisJCQkJCXRocm93cyBJT0V4Y2VwdGlvbiB7CisJUmVzcG9uc2UgcjsKKwkvLyBvbmx5IHBpcGVsaW5lIHBhc3N3b3JkIGlmIGNvbm5lY3Rpb24gaXMgc2VjdXJlCisJYm9vbGVhbiBiYXRjaCA9IHBpcGVsaW5pbmcgJiYgc29ja2V0IGluc3RhbmNlb2YgU1NMU29ja2V0OworCisJdHJ5IHsKKworCWlmIChub2F1dGhkZWJ1ZyAmJiBpc1RyYWNpbmcoKSkgeworCSAgICBsb2dnZXIuZmluZSgiYXV0aGVudGljYXRpb24gY29tbWFuZCB0cmFjZSBzdXBwcmVzc2VkIik7CisJICAgIHN1c3BlbmRUcmFjaW5nKCk7CisJfQorCVN0cmluZyBkcHcgPSBudWxsOworCWlmIChhcG9wQ2hhbGxlbmdlICE9IG51bGwpCisJICAgIGRwdyA9IGdldERpZ2VzdChwYXNzd29yZCk7CisJaWYgKGFwb3BDaGFsbGVuZ2UgIT0gbnVsbCAmJiBkcHcgIT0gbnVsbCkgeworCSAgICByID0gc2ltcGxlQ29tbWFuZCgiQVBPUCAiICsgdXNlciArICIgIiArIGRwdyk7CisJfSBlbHNlIGlmIChiYXRjaCkgeworCSAgICBTdHJpbmcgY21kID0gIlVTRVIgIiArIHVzZXI7CisJICAgIGJhdGNoQ29tbWFuZFN0YXJ0KGNtZCk7CisJICAgIGlzc3VlQ29tbWFuZChjbWQpOworCSAgICBjbWQgPSAiUEFTUyAiICsgcGFzc3dvcmQ7CisJICAgIGJhdGNoQ29tbWFuZENvbnRpbnVlKGNtZCk7CisJICAgIGlzc3VlQ29tbWFuZChjbWQpOworCSAgICByID0gcmVhZFJlc3BvbnNlKCk7CisJICAgIGlmICghci5vaykgeworCQlTdHJpbmcgZXJyID0gci5kYXRhICE9IG51bGwgPyByLmRhdGEgOiAiVVNFUiBjb21tYW5kIGZhaWxlZCI7CisJCXJlYWRSZXNwb25zZSgpOwkvLyByZWFkIGFuZCBpZ25vcmUgUEFTUyByZXNwb25zZQorCQliYXRjaENvbW1hbmRFbmQoKTsKKwkJcmV0dXJuIGVycjsKKwkgICAgfQorCSAgICByID0gcmVhZFJlc3BvbnNlKCk7CisJICAgIGJhdGNoQ29tbWFuZEVuZCgpOworCX0gZWxzZSB7CisJICAgIHIgPSBzaW1wbGVDb21tYW5kKCJVU0VSICIgKyB1c2VyKTsKKwkgICAgaWYgKCFyLm9rKQorCQlyZXR1cm4gci5kYXRhICE9IG51bGwgPyByLmRhdGEgOiAiVVNFUiBjb21tYW5kIGZhaWxlZCI7CisJICAgIHIgPSBzaW1wbGVDb21tYW5kKCJQQVNTICIgKyBwYXNzd29yZCk7CisJfQorCWlmIChub2F1dGhkZWJ1ZyAmJiBpc1RyYWNpbmcoKSkKKwkgICAgbG9nZ2VyLmxvZyhMZXZlbC5GSU5FLCAiYXV0aGVudGljYXRpb24gY29tbWFuZCB7MH0iLAorCQkJKHIub2sgPyAic3VjY2VlZGVkIiA6ICJmYWlsZWQiKSk7CisJaWYgKCFyLm9rKQorCSAgICByZXR1cm4gci5kYXRhICE9IG51bGwgPyByLmRhdGEgOiAibG9naW4gZmFpbGVkIjsKKwlyZXR1cm4gbnVsbDsKKworCX0gZmluYWxseSB7CisJICAgIHJlc3VtZVRyYWNpbmcoKTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgQVBPUCBtZXNzYWdlIGRpZ2VzdC4gCisgICAgICogRnJvbSBSRkMgMTkzOToKKyAgICAgKgorICAgICAqIFRoZSAnZGlnZXN0JyBwYXJhbWV0ZXIgaXMgY2FsY3VsYXRlZCBieSBhcHBseWluZyB0aGUgTUQ1CisgICAgICogYWxnb3JpdGhtIFtSRkMxMzIxXSB0byBhIHN0cmluZyBjb25zaXN0aW5nIG9mIHRoZSB0aW1lc3RhbXAKKyAgICAgKiAoaW5jbHVkaW5nIGFuZ2xlLWJyYWNrZXRzKSBmb2xsb3dlZCBieSBhIHNoYXJlZCBzZWNyZXQuCisgICAgICogVGhlICdkaWdlc3QnIHBhcmFtZXRlciBpdHNlbGYgaXMgYSAxNi1vY3RldCB2YWx1ZSB3aGljaCBpcworICAgICAqIHNlbnQgaW4gaGV4YWRlY2ltYWwgZm9ybWF0LCB1c2luZyBsb3dlci1jYXNlIEFTQ0lJIGNoYXJhY3RlcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0JcGFzc3dvcmQJVGhlIEFQT1AgcGFzc3dvcmQKKyAgICAgKiBAcmV0dXJuCQlUaGUgQVBPUCBkaWdlc3Qgb3IgYW4gZW1wdHkgc3RyaW5nIGlmIGFuIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyBnZXREaWdlc3QoU3RyaW5nIHBhc3N3b3JkKSB7CisJU3RyaW5nIGtleSA9IGFwb3BDaGFsbGVuZ2UgKyBwYXNzd29yZDsKKwlieXRlW10gZGlnZXN0OworCXRyeSB7CisJICAgIE1lc3NhZ2VEaWdlc3QgbWQgPSBNZXNzYWdlRGlnZXN0LmdldEluc3RhbmNlKCJNRDUiKTsKKwkgICAgZGlnZXN0ID0gbWQuZGlnZXN0KGtleS5nZXRCeXRlcygiaXNvLTg4NTktMSIpKTsJLy8gWFhYCisJfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIG5zYWUpIHsKKwkgICAgcmV0dXJuIG51bGw7CisJfSBjYXRjaCAoVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiB1ZWUpIHsKKwkgICAgcmV0dXJuIG51bGw7CisJfQorCXJldHVybiB0b0hleChkaWdlc3QpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGNoYXJbXSBkaWdpdHMgPSB7CisJJzAnLCAnMScsICcyJywgJzMnLCAnNCcsICc1JywgJzYnLCAnNycsCisJJzgnLCAnOScsICdhJywgJ2InLCAnYycsICdkJywgJ2UnLCAnZicKKyAgICB9OworCisgICAgLyoqCisgICAgICogQ29udmVydCBhIGJ5dGUgYXJyYXkgdG8gYSBzdHJpbmcgb2YgaGV4IGRpZ2l0cyByZXByZXNlbnRpbmcgdGhlIGJ5dGVzLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyB0b0hleChieXRlW10gYnl0ZXMpIHsKKwljaGFyW10gcmVzdWx0ID0gbmV3IGNoYXJbYnl0ZXMubGVuZ3RoICogMl07CisKKwlmb3IgKGludCBpbmRleCA9IDAsIGkgPSAwOyBpbmRleCA8IGJ5dGVzLmxlbmd0aDsgaW5kZXgrKykgeworCSAgICBpbnQgdGVtcCA9IGJ5dGVzW2luZGV4XSAmIDB4RkY7CisJICAgIHJlc3VsdFtpKytdID0gZGlnaXRzW3RlbXAgPj4gNF07CisJICAgIHJlc3VsdFtpKytdID0gZGlnaXRzW3RlbXAgJiAweEZdOworCX0KKwlyZXR1cm4gbmV3IFN0cmluZyhyZXN1bHQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENsb3NlIGRvd24gdGhlIGNvbm5lY3Rpb24sIHNlbmRpbmcgdGhlIFFVSVQgY29tbWFuZC4KKyAgICAgKi8KKyAgICBzeW5jaHJvbml6ZWQgYm9vbGVhbiBxdWl0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlib29sZWFuIG9rID0gZmFsc2U7CisJdHJ5IHsKKwkgICAgUmVzcG9uc2UgciA9IHNpbXBsZUNvbW1hbmQoIlFVSVQiKTsKKwkgICAgb2sgPSByLm9rOworCX0gZmluYWxseSB7CisJICAgIGNsb3NlKCk7CisJfQorCXJldHVybiBvazsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9zZSB0aGUgY29ubmVjdGlvbiB3aXRob3V0IHNlbmRpbmcgYW55IGNvbW1hbmRzLgorICAgICAqLworICAgIHZvaWQgY2xvc2UoKSB7CisJdHJ5IHsKKwkgICAgc29ja2V0LmNsb3NlKCk7CisJfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKwkgICAgLy8gaWdub3JlIGl0CisJfSBmaW5hbGx5IHsKKwkgICAgc29ja2V0ID0gbnVsbDsKKwkgICAgaW5wdXQgPSBudWxsOworCSAgICBvdXRwdXQgPSBudWxsOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIHRvdGFsIG51bWJlciBvZiBtZXNzYWdlcyBhbmQgbWFpbGJveCBzaXplLAorICAgICAqIHVzaW5nIHRoZSBTVEFUIGNvbW1hbmQuCisgICAgICovCisgICAgc3luY2hyb25pemVkIFN0YXR1cyBzdGF0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlSZXNwb25zZSByID0gc2ltcGxlQ29tbWFuZCgiU1RBVCIpOworCVN0YXR1cyBzID0gbmV3IFN0YXR1cygpOworCisJLyoKKwkgKiBOb3JtYWxseSB0aGUgU1RBVCBjb21tYW5kIHNob3VsZG4ndCBmYWlsIGJ1dCBhcHBhcmVudGx5IGl0CisJICogZG9lcyB3aGVuIGFjY2Vzc2luZyBIb3RtYWlsIHRvbyBvZnRlbiwgcmV0dXJuaW5nOgorCSAqIC1FUlIgbG9naW4gYWxsb3dlZCBvbmx5IGV2ZXJ5IDE1IG1pbnV0ZXMKKwkgKiAoV2h5IGl0IGRvZXNuJ3QganVzdCBmYWlsIHRoZSBsb2dpbiwgSSBkb24ndCBrbm93LikKKwkgKiBUaGlzIGlzIGEgc2VyaW91cyBmYWlsdXJlIHRoYXQgd2UgZG9uJ3Qgd2FudCB0byBoaWRlCisJICogZnJvbSB0aGUgdXNlci4KKwkgKi8KKwlpZiAoIXIub2spCisJICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiU1RBVCBjb21tYW5kIGZhaWxlZDogIiArIHIuZGF0YSk7CisKKwlpZiAoci5kYXRhICE9IG51bGwpIHsKKwkgICAgdHJ5IHsKKwkJU3RyaW5nVG9rZW5pemVyIHN0ID0gbmV3IFN0cmluZ1Rva2VuaXplcihyLmRhdGEpOworCQlzLnRvdGFsID0gSW50ZWdlci5wYXJzZUludChzdC5uZXh0VG9rZW4oKSk7CisJCXMuc2l6ZSA9IEludGVnZXIucGFyc2VJbnQoc3QubmV4dFRva2VuKCkpOworCSAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGUpIHsKKwkgICAgfQorCX0KKwlyZXR1cm4gczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIHNpemUgb2YgdGhlIG1lc3NhZ2UgdXNpbmcgdGhlIExJU1QgY29tbWFuZC4KKyAgICAgKi8KKyAgICBzeW5jaHJvbml6ZWQgaW50IGxpc3QoaW50IG1zZykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlSZXNwb25zZSByID0gc2ltcGxlQ29tbWFuZCgiTElTVCAiICsgbXNnKTsKKwlpbnQgc2l6ZSA9IC0xOworCWlmIChyLm9rICYmIHIuZGF0YSAhPSBudWxsKSB7CisJICAgIHRyeSB7CisJCVN0cmluZ1Rva2VuaXplciBzdCA9IG5ldyBTdHJpbmdUb2tlbml6ZXIoci5kYXRhKTsKKwkJc3QubmV4dFRva2VuKCk7ICAgIC8vIHNraXAgbWVzc2FnZSBudW1iZXIKKwkJc2l6ZSA9IEludGVnZXIucGFyc2VJbnQoc3QubmV4dFRva2VuKCkpOworCSAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGUpIHsKKwkJLy8gaWdub3JlIGl0CisJICAgIH0KKwl9CisJcmV0dXJuIHNpemU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBzaXplIG9mIGFsbCBtZXNzYWdlcyB1c2luZyB0aGUgTElTVCBjb21tYW5kLgorICAgICAqLworICAgIHN5bmNocm9uaXplZCBJbnB1dFN0cmVhbSBsaXN0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlSZXNwb25zZSByID0gbXVsdGlsaW5lQ29tbWFuZCgiTElTVCIsIDEyOCk7IC8vIDEyOCA9PSBvdXRwdXQgc2l6ZSBlc3QKKwlyZXR1cm4gci5ieXRlczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZSB0aGUgc3BlY2lmaWVkIG1lc3NhZ2UuCisgICAgICogR2l2ZW4gYW4gZXN0aW1hdGUgb2YgdGhlIG1lc3NhZ2UncyBzaXplIHdlIGNhbiBiZSBtb3JlIGVmZmljaWVudCwKKyAgICAgKiBwcmVhbGxvY2F0aW5nIHRoZSBhcnJheSBhbmQgcmV0dXJuaW5nIGEgU2hhcmVkSW5wdXRTdHJlYW0gdG8gYWxsb3cKKyAgICAgKiB1cyB0byBzaGFyZSB0aGUgYXJyYXkuCisgICAgICovCisgICAgc3luY2hyb25pemVkIElucHV0U3RyZWFtIHJldHIoaW50IG1zZywgaW50IHNpemUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJUmVzcG9uc2UgcjsKKwlTdHJpbmcgY21kOworCWJvb2xlYW4gYmF0Y2ggPSBzaXplID09IDAgJiYgcGlwZWxpbmluZzsKKwlpZiAoYmF0Y2gpIHsKKwkgICAgY21kID0gIkxJU1QgIiArIG1zZzsKKwkgICAgYmF0Y2hDb21tYW5kU3RhcnQoY21kKTsKKwkgICAgaXNzdWVDb21tYW5kKGNtZCk7CisJICAgIGNtZCA9ICJSRVRSICIgKyBtc2c7CisJICAgIGJhdGNoQ29tbWFuZENvbnRpbnVlKGNtZCk7CisJICAgIGlzc3VlQ29tbWFuZChjbWQpOworCSAgICByID0gcmVhZFJlc3BvbnNlKCk7CisJICAgIGlmIChyLm9rICYmIHIuZGF0YSAhPSBudWxsKSB7CisJCS8vIHBhcnNlIHRoZSBMSVNUIHJlc3BvbnNlIHRvIGdldCB0aGUgbWVzc2FnZSBzaXplCisJCXRyeSB7CisJCSAgICBTdHJpbmdUb2tlbml6ZXIgc3QgPSBuZXcgU3RyaW5nVG9rZW5pemVyKHIuZGF0YSk7CisJCSAgICBzdC5uZXh0VG9rZW4oKTsgICAgLy8gc2tpcCBtZXNzYWdlIG51bWJlcgorCQkgICAgc2l6ZSA9IEludGVnZXIucGFyc2VJbnQoc3QubmV4dFRva2VuKCkpOworCQkgICAgLy8gZG9uJ3QgYWxsb3cgcmlkaWN1bG91cyBzaXplcworCQkgICAgaWYgKHNpemUgPiAxMDI0KjEwMjQqMTAyNCB8fCBzaXplIDwgMCkKKwkJCXNpemUgPSAwOworCQkgICAgZWxzZSB7CisJCQlpZiAobG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuRklORSkpCisJCQkgICAgbG9nZ2VyLmZpbmUoInBpcGVsaW5lIG1lc3NhZ2Ugc2l6ZSAiICsgc2l6ZSk7CisJCQlzaXplICs9IFNMT1A7CisJCSAgICB9CisJCX0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gZSkgeworCQl9CisJICAgIH0KKwkgICAgciA9IHJlYWRSZXNwb25zZSgpOworCSAgICBpZiAoci5vaykKKwkJci5ieXRlcyA9IHJlYWRNdWx0aWxpbmVSZXNwb25zZShzaXplICsgU0xPUCk7CisJICAgIGJhdGNoQ29tbWFuZEVuZCgpOworCX0gZWxzZSB7CisJICAgIGNtZCA9ICJSRVRSICIgKyBtc2c7CisJICAgIG11bHRpbGluZUNvbW1hbmRTdGFydChjbWQpOworCSAgICBpc3N1ZUNvbW1hbmQoY21kKTsKKwkgICAgciA9IHJlYWRSZXNwb25zZSgpOworCSAgICBpZiAoIXIub2spIHsKKwkJbXVsdGlsaW5lQ29tbWFuZEVuZCgpOworCQlyZXR1cm4gbnVsbDsKKwkgICAgfQorCisJICAgIC8qCisJICAgICAqIE1hbnkgc2VydmVycyByZXR1cm4gYSByZXNwb25zZSB0byB0aGUgUkVUUiBjb21tYW5kIG9mIHRoZSBmb3JtOgorCSAgICAgKiArT0sgODMyIG9jdGV0cworCSAgICAgKiBJZiB3ZSBkb24ndCBoYXZlIGEgc2l6ZSBndWVzcyBhbHJlYWR5LCB0cnkgdG8gcGFyc2UgdGhlIHJlc3BvbnNlCisJICAgICAqIGZvciBkYXRhIGluIHRoYXQgZm9ybWF0IGFuZCB1c2UgaXQgaWYgZm91bmQuICBJdCdzIG9ubHkgYSBndWVzcywKKwkgICAgICogYnV0IGl0IG1pZ2h0IGJlIGEgZ29vZCBndWVzcy4KKwkgICAgICovCisJICAgIGlmIChzaXplIDw9IDAgJiYgci5kYXRhICE9IG51bGwpIHsKKwkJdHJ5IHsKKwkJICAgIFN0cmluZ1Rva2VuaXplciBzdCA9IG5ldyBTdHJpbmdUb2tlbml6ZXIoci5kYXRhKTsKKwkJICAgIFN0cmluZyBzID0gc3QubmV4dFRva2VuKCk7CisJCSAgICBTdHJpbmcgb2N0ZXRzID0gc3QubmV4dFRva2VuKCk7CisJCSAgICBpZiAob2N0ZXRzLmVxdWFscygib2N0ZXRzIikpIHsKKwkJCXNpemUgPSBJbnRlZ2VyLnBhcnNlSW50KHMpOworCQkJLy8gZG9uJ3QgYWxsb3cgcmlkaWN1bG91cyBzaXplcworCQkJaWYgKHNpemUgPiAxMDI0KjEwMjQqMTAyNCB8fCBzaXplIDwgMCkKKwkJCSAgICBzaXplID0gMDsKKwkJCWVsc2UgeworCQkJICAgIGlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FKSkKKwkJCQlsb2dnZXIuZmluZSgiZ3Vlc3NpbmcgbWVzc2FnZSBzaXplOiAiICsgc2l6ZSk7CisJCQkgICAgc2l6ZSArPSBTTE9QOworCQkJfQorCQkgICAgfQorCQl9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGUpIHsKKwkJfQorCSAgICB9CisJICAgIHIuYnl0ZXMgPSByZWFkTXVsdGlsaW5lUmVzcG9uc2Uoc2l6ZSk7CisJICAgIG11bHRpbGluZUNvbW1hbmRFbmQoKTsKKwl9CisJaWYgKHIub2spIHsKKwkgICAgaWYgKHNpemUgPiAwICYmIGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkUpKQorCQlsb2dnZXIuZmluZSgiZ290IG1lc3NhZ2Ugc2l6ZSAiICsgci5ieXRlcy5hdmFpbGFibGUoKSk7CisJfQorCXJldHVybiByLmJ5dGVzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHJpZXZlIHRoZSBzcGVjaWZpZWQgbWVzc2FnZSBhbmQgc3RyZWFtIHRoZSBjb250ZW50IHRvIHRoZQorICAgICAqIHNwZWNpZmllZCBPdXRwdXRTdHJlYW0uICBSZXR1cm4gdHJ1ZSBvbiBzdWNjZXNzLgorICAgICAqLworICAgIHN5bmNocm9uaXplZCBib29sZWFuIHJldHIoaW50IG1zZywgT3V0cHV0U3RyZWFtIG9zKSB0aHJvd3MgSU9FeGNlcHRpb24geworCVN0cmluZyBjbWQgPSAiUkVUUiAiICsgbXNnOworCW11bHRpbGluZUNvbW1hbmRTdGFydChjbWQpOworCWlzc3VlQ29tbWFuZChjbWQpOworCVJlc3BvbnNlIHIgPSByZWFkUmVzcG9uc2UoKTsKKwlpZiAoIXIub2spIHsKKwkgICAgbXVsdGlsaW5lQ29tbWFuZEVuZCgpOworCSAgICByZXR1cm4gZmFsc2U7CisJfQorCisJVGhyb3dhYmxlIHRlcnIgPSBudWxsOworCWludCBiLCBsYXN0YiA9ICdcbic7CisJdHJ5IHsKKwkgICAgd2hpbGUgKChiID0gaW5wdXQucmVhZCgpKSA+PSAwKSB7CisJCWlmIChsYXN0YiA9PSAnXG4nICYmIGIgPT0gJy4nKSB7CisJCSAgICBiID0gaW5wdXQucmVhZCgpOworCQkgICAgaWYgKGIgPT0gJ1xyJykgeworCQkJLy8gZW5kIG9mIHJlc3BvbnNlLCBjb25zdW1lIExGIGFzIHdlbGwKKwkJCWIgPSBpbnB1dC5yZWFkKCk7CisJCQlicmVhazsKKwkJICAgIH0KKwkJfQorCisJCS8qCisJCSAqIEtlZXAgd3JpdGluZyB1bmxlc3Mgd2UgZ2V0IGFuIGVycm9yIHdoaWxlIHdyaXRpbmcsCisJCSAqIHdoaWNoIHdlIGRlZmVyIHVudGlsIGFsbCBvZiB0aGUgZGF0YSBoYXMgYmVlbiByZWFkLgorCQkgKi8KKwkJaWYgKHRlcnIgPT0gbnVsbCkgeworCQkgICAgdHJ5IHsKKwkJCW9zLndyaXRlKGIpOworCQkgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKwkJCWxvZ2dlci5sb2coTGV2ZWwuRklORSwgImV4Y2VwdGlvbiB3aGlsZSBzdHJlYW1pbmciLCBleCk7CisJCQl0ZXJyID0gZXg7CisJCSAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGV4KSB7CisJCQlsb2dnZXIubG9nKExldmVsLkZJTkUsICJleGNlcHRpb24gd2hpbGUgc3RyZWFtaW5nIiwgZXgpOworCQkJdGVyciA9IGV4OworCQkgICAgfQorCQl9CisJCWxhc3RiID0gYjsKKwkgICAgfQorCX0gY2F0Y2ggKEludGVycnVwdGVkSU9FeGNlcHRpb24gaWlvZXgpIHsKKwkgICAgLyoKKwkgICAgICogQXMgYWJvdmUgaW4gc2ltcGxlQ29tbWFuZCwgY2xvc2UgdGhlIHNvY2tldCB0byByZWNvdmVyLgorCSAgICAgKi8KKwkgICAgdHJ5IHsKKwkJc29ja2V0LmNsb3NlKCk7CisJICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGNleCkgeyB9CisJICAgIHRocm93IGlpb2V4OworCX0KKwlpZiAoYiA8IDApCisJICAgIHRocm93IG5ldyBFT0ZFeGNlcHRpb24oIkVPRiBvbiBzb2NrZXQiKTsKKworCS8vIHdhcyB0aGVyZSBhIGRlZmVycmVkIGVycm9yPworCWlmICh0ZXJyICE9IG51bGwpIHsKKwkgICAgaWYgKHRlcnIgaW5zdGFuY2VvZiBJT0V4Y2VwdGlvbikKKwkJdGhyb3cgKElPRXhjZXB0aW9uKXRlcnI7CisJICAgIGlmICh0ZXJyIGluc3RhbmNlb2YgUnVudGltZUV4Y2VwdGlvbikKKwkJdGhyb3cgKFJ1bnRpbWVFeGNlcHRpb24pdGVycjsKKwkgICAgYXNzZXJ0IGZhbHNlOwkvLyBjYW4ndCBnZXQgaGVyZQorCX0KKwltdWx0aWxpbmVDb21tYW5kRW5kKCk7CisJcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBtZXNzYWdlIGhlYWRlciBhbmQgdGhlIGZpcnN0IG4gbGluZXMgb2YgdGhlIG1lc3NhZ2UuCisgICAgICovCisgICAgc3luY2hyb25pemVkIElucHV0U3RyZWFtIHRvcChpbnQgbXNnLCBpbnQgbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlSZXNwb25zZSByID0gbXVsdGlsaW5lQ29tbWFuZCgiVE9QICIgKyBtc2cgKyAiICIgKyBuLCAwKTsKKwlyZXR1cm4gci5ieXRlczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZWxldGUgKHBlcm1hbmVudGx5KSB0aGUgc3BlY2lmaWVkIG1lc3NhZ2UuCisgICAgICovCisgICAgc3luY2hyb25pemVkIGJvb2xlYW4gZGVsZShpbnQgbXNnKSB0aHJvd3MgSU9FeGNlcHRpb24geworCVJlc3BvbnNlIHIgPSBzaW1wbGVDb21tYW5kKCJERUxFICIgKyBtc2cpOworCXJldHVybiByLm9rOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgVUlETCBzdHJpbmcgZm9yIHRoZSBtZXNzYWdlLgorICAgICAqLworICAgIHN5bmNocm9uaXplZCBTdHJpbmcgdWlkbChpbnQgbXNnKSB0aHJvd3MgSU9FeGNlcHRpb24geworCVJlc3BvbnNlIHIgPSBzaW1wbGVDb21tYW5kKCJVSURMICIgKyBtc2cpOworCWlmICghci5vaykKKwkgICAgcmV0dXJuIG51bGw7CisJaW50IGkgPSByLmRhdGEuaW5kZXhPZignICcpOworCWlmIChpID4gMCkKKwkgICAgcmV0dXJuIHIuZGF0YS5zdWJzdHJpbmcoaSArIDEpOworCWVsc2UKKwkgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBVSURMIHN0cmluZ3MgZm9yIGFsbCBtZXNzYWdlcy4KKyAgICAgKiBUaGUgVUlEIGZvciBtc2cgI04gaXMgcmV0dXJuZWQgaW4gdWlkc1tOLTFdLgorICAgICAqLworICAgIHN5bmNocm9uaXplZCBib29sZWFuIHVpZGwoU3RyaW5nW10gdWlkcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlSZXNwb25zZSByID0gbXVsdGlsaW5lQ29tbWFuZCgiVUlETCIsIDE1ICogdWlkcy5sZW5ndGgpOworCWlmICghci5vaykKKwkgICAgcmV0dXJuIGZhbHNlOworCUxpbmVJbnB1dFN0cmVhbSBsaXMgPSBuZXcgTGluZUlucHV0U3RyZWFtKHIuYnl0ZXMpOworCVN0cmluZyBsaW5lID0gbnVsbDsKKwl3aGlsZSAoKGxpbmUgPSBsaXMucmVhZExpbmUoKSkgIT0gbnVsbCkgeworCSAgICBpbnQgaSA9IGxpbmUuaW5kZXhPZignICcpOworCSAgICBpZiAoaSA8IDEgfHwgaSA+PSBsaW5lLmxlbmd0aCgpKQorCQljb250aW51ZTsKKwkgICAgaW50IG4gPSBJbnRlZ2VyLnBhcnNlSW50KGxpbmUuc3Vic3RyaW5nKDAsIGkpKTsKKwkgICAgaWYgKG4gPiAwICYmIG4gPD0gdWlkcy5sZW5ndGgpCisJCXVpZHNbbiAtIDFdID0gbGluZS5zdWJzdHJpbmcoaSArIDEpOworCX0KKwl0cnkgeworCSAgICByLmJ5dGVzLmNsb3NlKCk7CisJfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKwkgICAgLy8gaWdub3JlIGl0CisJfQorCXJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIERvIGEgTk9PUC4KKyAgICAgKi8KKyAgICBzeW5jaHJvbml6ZWQgYm9vbGVhbiBub29wKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlSZXNwb25zZSByID0gc2ltcGxlQ29tbWFuZCgiTk9PUCIpOworCXJldHVybiByLm9rOworICAgIH0KKworICAgIC8qKgorICAgICAqIERvIGFuIFJTRVQuCisgICAgICovCisgICAgc3luY2hyb25pemVkIGJvb2xlYW4gcnNldCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJUmVzcG9uc2UgciA9IHNpbXBsZUNvbW1hbmQoIlJTRVQiKTsKKwlyZXR1cm4gci5vazsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTdGFydCBUTFMgdXNpbmcgU1RMUyBjb21tYW5kIHNwZWNpZmllZCBieSBSRkMgMjU5NS4KKyAgICAgKiBJZiBhbHJlYWR5IHVzaW5nIFNTTCwgdGhpcyBpcyBhIG5vcCBhbmQgdGhlIFNUTFMgY29tbWFuZCBpcyBub3QgaXNzdWVkLgorICAgICAqLworICAgIHN5bmNocm9uaXplZCBib29sZWFuIHN0bHMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCWlmIChzb2NrZXQgaW5zdGFuY2VvZiBTU0xTb2NrZXQpCisJICAgIHJldHVybiB0cnVlOwkvLyBub3RoaW5nIHRvIGRvCisJUmVzcG9uc2UgciA9IHNpbXBsZUNvbW1hbmQoIlNUTFMiKTsKKwlpZiAoci5vaykgeworCSAgICAvLyBpdCB3b3JrZWQsIG5vdyBzd2l0Y2ggdGhlIHNvY2tldCBpbnRvIFRMUyBtb2RlCisJICAgIHRyeSB7CisJCXNvY2tldCA9IFNvY2tldEZldGNoZXIuc3RhcnRUTFMoc29ja2V0LCBob3N0LCBwcm9wcywgcHJlZml4KTsKKwkJaW5pdFN0cmVhbXMoKTsKKwkgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9leCkgeworCQl0cnkgeworCQkgICAgc29ja2V0LmNsb3NlKCk7CisJCX0gZmluYWxseSB7CisJCSAgICBzb2NrZXQgPSBudWxsOworCQkgICAgaW5wdXQgPSBudWxsOworCQkgICAgb3V0cHV0ID0gbnVsbDsKKwkJfQorCQlJT0V4Y2VwdGlvbiBzaW9leCA9CisJCSAgICBuZXcgSU9FeGNlcHRpb24oIkNvdWxkIG5vdCBjb252ZXJ0IHNvY2tldCB0byBUTFMiKTsKKwkJc2lvZXguaW5pdENhdXNlKGlvZXgpOworCQl0aHJvdyBzaW9leDsKKwkgICAgfQorCX0KKwlyZXR1cm4gci5vazsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJcyB0aGlzIGNvbm5lY3Rpb24gdXNpbmcgU1NMPworICAgICAqLworICAgIHN5bmNocm9uaXplZCBib29sZWFuIGlzU1NMKCkgeworCXJldHVybiBzb2NrZXQgaW5zdGFuY2VvZiBTU0xTb2NrZXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHNlcnZlciBjYXBhYmlsaXRpZXMgdXNpbmcgQ0FQQSBjb21tYW5kIHNwZWNpZmllZCBieSBSRkMgMjQ0OS4KKyAgICAgKiBSZXR1cm5zIG51bGwgaWYgbm90IHN1cHBvcnRlZC4KKyAgICAgKi8KKyAgICBzeW5jaHJvbml6ZWQgSW5wdXRTdHJlYW0gY2FwYSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJUmVzcG9uc2UgciA9IG11bHRpbGluZUNvbW1hbmQoIkNBUEEiLCAxMjgpOyAvLyAxMjggPT0gb3V0cHV0IHNpemUgZXN0CisJaWYgKCFyLm9rKQorCSAgICByZXR1cm4gbnVsbDsKKwlyZXR1cm4gci5ieXRlczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJc3N1ZSBhIHNpbXBsZSBQT1AzIGNvbW1hbmQgYW5kIHJldHVybiB0aGUgcmVzcG9uc2UuCisgICAgICovCisgICAgcHJpdmF0ZSBSZXNwb25zZSBzaW1wbGVDb21tYW5kKFN0cmluZyBjbWQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJc2ltcGxlQ29tbWFuZFN0YXJ0KGNtZCk7CisJaXNzdWVDb21tYW5kKGNtZCk7CisJUmVzcG9uc2UgciA9IHJlYWRSZXNwb25zZSgpOworCXNpbXBsZUNvbW1hbmRFbmQoKTsKKwlyZXR1cm4gcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZW5kIHRoZSBzcGVjaWZpZWQgY29tbWFuZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgaXNzdWVDb21tYW5kKFN0cmluZyBjbWQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJaWYgKHNvY2tldCA9PSBudWxsKQorCSAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkZvbGRlciBpcyBjbG9zZWQiKTsJLy8gWFhYCisKKwlpZiAoY21kICE9IG51bGwpIHsKKwkgICAgY21kICs9IENSTEY7CisJICAgIG91dHB1dC5wcmludChjbWQpOwkvLyBkbyBpdCBpbiBvbmUgd3JpdGUKKwkgICAgb3V0cHV0LmZsdXNoKCk7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWQgdGhlIHJlc3BvbnNlIHRvIGEgY29tbWFuZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIFJlc3BvbnNlIHJlYWRSZXNwb25zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJU3RyaW5nIGxpbmUgPSBudWxsOworCXRyeSB7CisJICAgIGxpbmUgPSBpbnB1dC5yZWFkTGluZSgpOworCX0gY2F0Y2ggKEludGVycnVwdGVkSU9FeGNlcHRpb24gaWlvZXgpIHsKKwkgICAgLyoKKwkgICAgICogSWYgd2UgZ2V0IGEgdGltZW91dCB3aGlsZSB1c2luZyB0aGUgc29ja2V0LCB3ZSBoYXZlIG5vIGlkZWEKKwkgICAgICogd2hhdCBzdGF0ZSB0aGUgY29ubmVjdGlvbiBpcyBpbi4gIFRoZSBzZXJ2ZXIgY291bGQgc3RpbGwgYmUKKwkgICAgICogYWxpdmUsIGJ1dCBzbG93LCBhbmQgY291bGQgc3RpbGwgYmUgc2VuZGluZyBkYXRhLiAgVGhlIG9ubHkKKwkgICAgICogc2FmZSB3YXkgdG8gcmVjb3ZlciBpcyB0byBkcm9wIHRoZSBjb25uZWN0aW9uLgorCSAgICAgKi8KKwkgICAgdHJ5IHsKKwkJc29ja2V0LmNsb3NlKCk7CisJICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGNleCkgeyB9CisJICAgIHRocm93IG5ldyBFT0ZFeGNlcHRpb24oaWlvZXguZ2V0TWVzc2FnZSgpKTsKKwl9IGNhdGNoIChTb2NrZXRFeGNlcHRpb24gZXgpIHsKKwkgICAgLyoKKwkgICAgICogSWYgd2UgZ2V0IGFuIGVycm9yIHdoaWxlIHVzaW5nIHRoZSBzb2NrZXQsIHdlIGhhdmUgbm8gaWRlYQorCSAgICAgKiB3aGF0IHN0YXRlIHRoZSBjb25uZWN0aW9uIGlzIGluLiAgVGhlIHNlcnZlciBjb3VsZCBzdGlsbCBiZQorCSAgICAgKiBhbGl2ZSwgYnV0IHNsb3csIGFuZCBjb3VsZCBzdGlsbCBiZSBzZW5kaW5nIGRhdGEuICBUaGUgb25seQorCSAgICAgKiBzYWZlIHdheSB0byByZWNvdmVyIGlzIHRvIGRyb3AgdGhlIGNvbm5lY3Rpb24uCisJICAgICAqLworCSAgICB0cnkgeworCQlzb2NrZXQuY2xvc2UoKTsKKwkgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gY2V4KSB7IH0KKwkgICAgdGhyb3cgbmV3IEVPRkV4Y2VwdGlvbihleC5nZXRNZXNzYWdlKCkpOworCX0KKworCWlmIChsaW5lID09IG51bGwpIHsKKwkgICAgdHJhY2VMb2dnZXIuZmluZXN0KCI8RU9GPiIpOworCSAgICB0aHJvdyBuZXcgRU9GRXhjZXB0aW9uKCJFT0Ygb24gc29ja2V0Iik7CisJfQorCVJlc3BvbnNlIHIgPSBuZXcgUmVzcG9uc2UoKTsKKwlpZiAobGluZS5zdGFydHNXaXRoKCIrT0siKSkKKwkgICAgci5vayA9IHRydWU7CisJZWxzZSBpZiAobGluZS5zdGFydHNXaXRoKCItRVJSIikpCisJICAgIHIub2sgPSBmYWxzZTsKKwllbHNlCisJICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiVW5leHBlY3RlZCByZXNwb25zZTogIiArIGxpbmUpOworCWludCBpOworCWlmICgoaSA9IGxpbmUuaW5kZXhPZignICcpKSA+PSAwKQorCSAgICByLmRhdGEgPSBsaW5lLnN1YnN0cmluZyhpICsgMSk7CisJcmV0dXJuIHI7CisgICAgfQorCisgICAgLyoqCisgICAgICogSXNzdWUgYSBQT1AzIGNvbW1hbmQgdGhhdCBleHBlY3RzIGEgbXVsdGktbGluZSByZXNwb25zZS4KKyAgICAgKiA8Y29kZT5zaXplPC9jb2RlPiBpcyBhbiBlc3RpbWF0ZSBvZiB0aGUgcmVzcG9uc2Ugc2l6ZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIFJlc3BvbnNlIG11bHRpbGluZUNvbW1hbmQoU3RyaW5nIGNtZCwgaW50IHNpemUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJbXVsdGlsaW5lQ29tbWFuZFN0YXJ0KGNtZCk7CisJaXNzdWVDb21tYW5kKGNtZCk7CisJUmVzcG9uc2UgciA9IHJlYWRSZXNwb25zZSgpOworCWlmICghci5vaykgeworCSAgICBtdWx0aWxpbmVDb21tYW5kRW5kKCk7CisJICAgIHJldHVybiByOworCX0KKwlyLmJ5dGVzID0gcmVhZE11bHRpbGluZVJlc3BvbnNlKHNpemUpOworCW11bHRpbGluZUNvbW1hbmRFbmQoKTsKKwlyZXR1cm4gcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkIHRoZSByZXNwb25zZSB0byBhIG11bHRpbGluZSBjb21tYW5kIGFmdGVyIHRoZSBjb21tYW5kIHJlc3BvbnNlLgorICAgICAqIFRoZSBzaXplIHBhcmFtZXRlciBpbmRpY2F0ZXMgdGhlIGV4cGVjdGVkIHNpemUgb2YgdGhlIHJlc3BvbnNlOworICAgICAqIHRoZSBhY3R1YWwgc2l6ZSBjYW4gYmUgZGlmZmVyZW50LiAgUmV0dXJucyBhbiBJbnB1dFN0cmVhbSB0byB0aGUKKyAgICAgKiByZXNwb25zZSBieXRlcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIElucHV0U3RyZWFtIHJlYWRNdWx0aWxpbmVSZXNwb25zZShpbnQgc2l6ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlTaGFyZWRCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYnVmID0gbmV3IFNoYXJlZEJ5dGVBcnJheU91dHB1dFN0cmVhbShzaXplKTsKKwlpbnQgYiwgbGFzdGIgPSAnXG4nOworCXRyeSB7CisJICAgIHdoaWxlICgoYiA9IGlucHV0LnJlYWQoKSkgPj0gMCkgeworCQlpZiAobGFzdGIgPT0gJ1xuJyAmJiBiID09ICcuJykgeworCQkgICAgYiA9IGlucHV0LnJlYWQoKTsKKwkJICAgIGlmIChiID09ICdccicpIHsKKwkJCS8vIGVuZCBvZiByZXNwb25zZSwgY29uc3VtZSBMRiBhcyB3ZWxsCisJCQliID0gaW5wdXQucmVhZCgpOworCQkJYnJlYWs7CisJCSAgICB9CisJCX0KKwkJYnVmLndyaXRlKGIpOworCQlsYXN0YiA9IGI7CisJICAgIH0KKwl9IGNhdGNoIChJbnRlcnJ1cHRlZElPRXhjZXB0aW9uIGlpb2V4KSB7CisJICAgIC8qCisJICAgICAqIEFzIGFib3ZlIGluIHJlYWRSZXNwb25zZSwgY2xvc2UgdGhlIHNvY2tldCB0byByZWNvdmVyLgorCSAgICAgKi8KKwkgICAgdHJ5IHsKKwkJc29ja2V0LmNsb3NlKCk7CisJICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGNleCkgeyB9CisJICAgIHRocm93IGlpb2V4OworCX0KKwlpZiAoYiA8IDApCisJICAgIHRocm93IG5ldyBFT0ZFeGNlcHRpb24oIkVPRiBvbiBzb2NrZXQiKTsKKwlyZXR1cm4gYnVmLnRvU3RyZWFtKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSXMgcHJvdG9jb2wgdHJhY2luZyBlbmFibGVkPworICAgICAqLworICAgIHByb3RlY3RlZCBib29sZWFuIGlzVHJhY2luZygpIHsKKwlyZXR1cm4gdHJhY2VMb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FU1QpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlbXBvcmFyaWx5IHR1cm4gb2ZmIHByb3RvY29sIHRyYWNpbmcsIGUuZy4sIHRvIHByZXZlbnQKKyAgICAgKiB0cmFjaW5nIHRoZSBhdXRoZW50aWNhdGlvbiBzZXF1ZW5jZSwgaW5jbHVkaW5nIHRoZSBwYXNzd29yZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgc3VzcGVuZFRyYWNpbmcoKSB7CisJaWYgKHRyYWNlTG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuRklORVNUKSkgeworCSAgICB0cmFjZUlucHV0LnNldFRyYWNlKGZhbHNlKTsKKwkgICAgdHJhY2VPdXRwdXQuc2V0VHJhY2UoZmFsc2UpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXN1bWUgcHJvdG9jb2wgdHJhY2luZywgaWYgaXQgd2FzIGVuYWJsZWQgdG8gYmVnaW4gd2l0aC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmVzdW1lVHJhY2luZygpIHsKKwlpZiAodHJhY2VMb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FU1QpKSB7CisJICAgIHRyYWNlSW5wdXQuc2V0VHJhY2UodHJ1ZSk7CisJICAgIHRyYWNlT3V0cHV0LnNldFRyYWNlKHRydWUpOworCX0KKyAgICB9CisKKyAgICAvKgorICAgICAqIFByb2JlIHBvaW50cyBmb3IgR2xhc3NGaXNoIG1vbml0b3JpbmcuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHNpbXBsZUNvbW1hbmRTdGFydChTdHJpbmcgY29tbWFuZCkgeyB9CisgICAgcHJpdmF0ZSB2b2lkIHNpbXBsZUNvbW1hbmRFbmQoKSB7IH0KKyAgICBwcml2YXRlIHZvaWQgbXVsdGlsaW5lQ29tbWFuZFN0YXJ0KFN0cmluZyBjb21tYW5kKSB7IH0KKyAgICBwcml2YXRlIHZvaWQgbXVsdGlsaW5lQ29tbWFuZEVuZCgpIHsgfQorICAgIHByaXZhdGUgdm9pZCBiYXRjaENvbW1hbmRTdGFydChTdHJpbmcgY29tbWFuZCkgeyB9CisgICAgcHJpdmF0ZSB2b2lkIGJhdGNoQ29tbWFuZENvbnRpbnVlKFN0cmluZyBjb21tYW5kKSB7IH0KKyAgICBwcml2YXRlIHZvaWQgYmF0Y2hDb21tYW5kRW5kKCkgeyB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3BvcDMvU3RhdHVzLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3BvcDMvU3RhdHVzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmJmYmQ5YwotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvcG9wMy9TdGF0dXMuamF2YQpAQCAtMCwwICsxLDI1IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5wb3AzOworCisvKioKKyAqIFJlc3VsdCBvZiBQT1AzIFNUQVQgY29tbWFuZC4KKyAqLworY2xhc3MgU3RhdHVzIHsKKyAgICBpbnQgdG90YWwgPSAwOwkJLy8gbnVtYmVyIG9mIG1lc3NhZ2VzIGluIHRoZSBtYWlsYm94CisgICAgaW50IHNpemUgPSAwOwkJLy8gc2l6ZSBvZiB0aGUgbWFpbGJveAorfTsKZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvcG9wMy9UZW1wRmlsZS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9wb3AzL1RlbXBGaWxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGQ3NjllNAotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvcG9wMy9UZW1wRmlsZS5qYXZhCkBAIC0wLDAgKzEsNjcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMTAsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLnBvcDM7CisKK2ltcG9ydCBqYXZhLmlvLio7CisKKy8qKgorICogQSB0ZW1wb3JhcnkgZmlsZSB1c2VkIHRvIGNhY2hlIFBPUDMgbWVzc2FnZXMuCisgKi8KK2NsYXNzIFRlbXBGaWxlIHsKKworICAgIHByaXZhdGUgRmlsZSBmaWxlOwkvLyB0aGUgdGVtcCBmaWxlIG5hbWUKKyAgICBwcml2YXRlIFdyaXRhYmxlU2hhcmVkRmlsZSBzZjsKKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIHRlbXAgZmlsZSBpbiB0aGUgc3BlY2lmaWVkIGRpcmVjdG9yeSAoaWYgbm90IG51bGwpLgorICAgICAqIFRoZSBmaWxlIHdpbGwgYmUgZGVsZXRlZCB3aGVuIHRoZSBKVk0gZXhpdHMuCisgICAgICovCisgICAgcHVibGljIFRlbXBGaWxlKEZpbGUgZGlyKSB0aHJvd3MgSU9FeGNlcHRpb24geworCWZpbGUgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJwb3AzLiIsICIubWJveCIsIGRpcik7CisJLy8gWFhYIC0gbmVlZCBKREsgNiB0byBzZXQgcGVybWlzc2lvbnMgb24gdGhlIGZpbGUgdG8gb3duZXItb25seQorCWZpbGUuZGVsZXRlT25FeGl0KCk7CisJc2YgPSBuZXcgV3JpdGFibGVTaGFyZWRGaWxlKGZpbGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiBhIHN0cmVhbSBmb3IgYXBwZW5kaW5nIHRvIHRoZSB0ZW1wIGZpbGUuCisgICAgICovCisgICAgcHVibGljIEFwcGVuZFN0cmVhbSBnZXRBcHBlbmRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworCXJldHVybiBzZi5nZXRBcHBlbmRTdHJlYW0oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9zZSBhbmQgcmVtb3ZlIHRoaXMgdGVtcCBmaWxlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgeworCXRyeSB7CisJICAgIHNmLmNsb3NlKCk7CisJfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKwkgICAgLy8gaWdub3JlIGl0CisJfQorCWZpbGUuZGVsZXRlKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgZmluYWxpemUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKwl0cnkgeworCSAgICBjbG9zZSgpOworCX0gZmluYWxseSB7CisJICAgIHN1cGVyLmZpbmFsaXplKCk7CisJfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvcG9wMy9Xcml0YWJsZVNoYXJlZEZpbGUuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvcG9wMy9Xcml0YWJsZVNoYXJlZEZpbGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ZGFhMGM1Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9wb3AzL1dyaXRhYmxlU2hhcmVkRmlsZS5qYXZhCkBAIC0wLDAgKzEsODMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMTAsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLnBvcDM7CisKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGU7CitpbXBvcnQgamF2YXgubWFpbC51dGlsLlNoYXJlZEZpbGVJbnB1dFN0cmVhbTsKKworLyoqCisgKiBBIHN1YmNsYXNzIG9mIFNoYXJlZEZpbGVJbnB1dFN0cmVhbSB0aGF0IGFsc28gYWxsb3dzIHdyaXRpbmcuCisgKi8KK2NsYXNzIFdyaXRhYmxlU2hhcmVkRmlsZSBleHRlbmRzIFNoYXJlZEZpbGVJbnB1dFN0cmVhbSB7CisKKyAgICBwcml2YXRlIFJhbmRvbUFjY2Vzc0ZpbGUgcmFmOworICAgIHByaXZhdGUgQXBwZW5kU3RyZWFtIGFmOworCisgICAgcHVibGljIFdyaXRhYmxlU2hhcmVkRmlsZShGaWxlIGZpbGUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJc3VwZXIoZmlsZSk7CisJdHJ5IHsKKwkgICAgcmFmID0gbmV3IFJhbmRvbUFjY2Vzc0ZpbGUoZmlsZSwgInJ3Iik7CisJfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKwkgICAgLy8gaWYgYW55dGhpbmcgZ29lcyB3cm9uZyBvcGVuaW5nIHRoZSB3cml0YWJsZSBmaWxlLAorCSAgICAvLyBjbG9zZSB0aGUgcmVhZGFibGUgZmlsZSB0b28KKwkgICAgc3VwZXIuY2xvc2UoKTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSB3cml0YWJsZSB2ZXJzaW9uIG9mIHRoaXMgZmlsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUmFuZG9tQWNjZXNzRmlsZSBnZXRXcml0YWJsZUZpbGUoKSB7CisJcmV0dXJuIHJhZjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9zZSB0aGUgcmVhZGFibGUgYW5kIHdyaXRhYmxlIGZpbGVzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwl0cnkgeworCSAgICBzdXBlci5jbG9zZSgpOworCX0gZmluYWxseSB7CisJICAgIHJhZi5jbG9zZSgpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGUgdGhlIHNpemUgb2YgdGhlIHJlYWRhYmxlIGZpbGUgYWZ0ZXIgd3JpdGluZyB0byB0aGUgZmlsZS4gVXBkYXRlcworICAgICAqIHRoZSBsZW5ndGggdG8gYmUgdGhlIGN1cnJlbnQgc2l6ZSBvZiB0aGUgZmlsZS4KKyAgICAgKi8KKyAgICBzeW5jaHJvbml6ZWQgbG9uZyB1cGRhdGVMZW5ndGgoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCWRhdGFsZW4gPSBpbi5sZW5ndGgoKTsKKwlhZiA9IG51bGw7CisJcmV0dXJuIGRhdGFsZW47CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIGEgbmV3IEFwcGVuZFN0cmVhbSwgYnV0IG9ubHkgaWYgb25lIGlzbid0IGluIGFjdGl2ZSB1c2UuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBBcHBlbmRTdHJlYW0gZ2V0QXBwZW5kU3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlpZiAoYWYgIT0gbnVsbCkgeworCSAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oCisJCSAgICAiUE9QMyBmaWxlIGNhY2hlIG9ubHkgc3VwcG9ydHMgc2luZ2xlIHRocmVhZGVkIGFjY2VzcyIpOworCX0KKwlhZiA9IG5ldyBBcHBlbmRTdHJlYW0odGhpcyk7CisJcmV0dXJuIGFmOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvcG9wMy9wYWNrYWdlLmh0bWwgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3BvcDMvcGFja2FnZS5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVkNzZjYjcKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3BvcDMvcGFja2FnZS5odG1sCkBAIC0wLDAgKzEsNjcyIEBACis8IURPQ1RZUEUgaHRtbCBQVUJMSUMgIi0vL1czQy8vRFREIEhUTUwgNC4wMSBUcmFuc2l0aW9uYWwvL0VOIj4KKzxIVE1MPgorPEhFQUQ+Cis8bWV0YSBodHRwLWVxdWl2PSJDb250ZW50LVR5cGUiIGNvbnRlbnQ9InRleHQvaHRtbDsgY2hhcnNldD11dGYtOCI+Cis8IS0tCisKKyAgICBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKworICAgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICAgIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorCisgICAgVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICAgIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAgICBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAgICB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKworICAgIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorCistLT4KKworPFRJVExFPmNvbS5zdW4ubWFpbC5wb3AzIHBhY2thZ2U8L1RJVExFPgorPC9IRUFEPgorPEJPRFkgQkdDT0xPUj0id2hpdGUiPgorCitBIFBPUDMgcHJvdG9jb2wgcHJvdmlkZXIgZm9yIHRoZSBKYXZhTWFpbCBBUEkKK3RoYXQgcHJvdmlkZXMgYWNjZXNzIHRvIGEgUE9QMyBtZXNzYWdlIHN0b3JlLgorUmVmZXIgdG8gPEEgSFJFRj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMTkzOS50eHQiIFRBUkdFVD0iX3RvcCI+CitSRkMgMTkzOTwvQT4KK2ZvciBtb3JlIGluZm9ybWF0aW9uLgorPFA+CitUaGUgUE9QMyBwcm92aWRlciBwcm92aWRlcyBhIFN0b3JlIG9iamVjdCB0aGF0IGNvbnRhaW5zIGEgc2luZ2xlIEZvbGRlcgorbmFtZWQgIklOQk9YIi4gRHVlIHRvIHRoZSBsaW1pdGF0aW9ucyBvZiB0aGUgUE9QMyBwcm90b2NvbCwgbWFueSBvZgordGhlIEphdmFNYWlsIEFQSSBjYXBhYmlsaXRpZXMgbGlrZSBldmVudCBub3RpZmljYXRpb24sIGZvbGRlciBtYW5hZ2VtZW50LAorZmxhZyBtYW5hZ2VtZW50LCBldGMuIGFyZSBub3QgYWxsb3dlZC4gIFRoZSBjb3JyZXNwb25kaW5nIG1ldGhvZHMgdGhyb3cKK3RoZSBNZXRob2ROb3RTdXBwb3J0ZWRFeGNlcHRpb24gZXhjZXB0aW9uOyBzZWUgYmVsb3cgZm9yIGRldGFpbHMuCis8L1A+Cis8UD4KK05vdGUgdGhhdCBKYXZhTWFpbCBkb2VzIDxzdHJvbmc+bm90PC9zdHJvbmc+IGluY2x1ZGUgYSBsb2NhbCBzdG9yZSBpbnRvCit3aGljaCBtZXNzYWdlcyBjYW4gYmUgZG93bmxvYWRlZCBhbmQgc3RvcmVkLiAgU2VlIG91cgorPEEgSFJFRj0iaHR0cDovL2phdmEuc3VuLmNvbS9wcm9kdWN0cy9qYXZhbWFpbC9UaGlyZF9QYXJ0eS5odG1sIiBUQVJHRVQ9Il90b3AiPgorVGhpcmQgUGFydHkgUHJvZHVjdHM8L0E+Cit3ZWIgcGFnZSBmb3IgYXZhaWxhYmlsaXR5IG9mICJtYm94IiBhbmQgIk1IIiBsb2NhbCBzdG9yZSBwcm92aWRlcnMuCis8L1A+Cis8UD4KK1RoZSBQT1AzIHByb3ZpZGVyIGlzIGFjY2Vzc2VkIHRocm91Z2ggdGhlIEphdmFNYWlsIEFQSXMgYnkgdXNpbmcgdGhlIHByb3RvY29sCituYW1lICJwb3AzIiBvciBhIFVSTCBvZiB0aGUgZm9ybSAicG9wMzovL3VzZXI6cGFzc3dvcmRAaG9zdDpwb3J0L0lOQk9YIi4KKzwvUD4KKzxQPgorUE9QMyBzdXBwb3J0cyBvbmx5IGEgc2luZ2xlIGZvbGRlciBuYW1lZCAiSU5CT1giLgorPC9QPgorPFA+CitQT1AzIHN1cHBvcnRzIDxzdHJvbmc+bm88L3N0cm9uZz4gcGVybWFuZW50IGZsYWdzIChzZWUKK3tAbGluayBqYXZheC5tYWlsLkZvbGRlciNnZXRQZXJtYW5lbnRGbGFncyBGb2xkZXIuZ2V0UGVybWFuZW50RmxhZ3MoKX0pLgorSW4gcGFydGljdWxhciwgdGhlIDxjb2RlPkZsYWdzLkZsYWcuUkVDRU5UPC9jb2RlPiBmbGFnIHdpbGwgbmV2ZXIgYmUgc2V0Citmb3IgUE9QMworbWVzc2FnZXMuICBJdCdzIHVwIHRvIHRoZSBhcHBsaWNhdGlvbiB0byBkZXRlcm1pbmUgd2hpY2ggbWVzc2FnZXMgaW4gYQorUE9QMyBtYWlsYm94IGFyZSAibmV3Ii4gIFRoZXJlIGFyZSBzZXZlcmFsIHN0cmF0ZWdpZXMgdG8gYWNjb21wbGlzaAordGhpcywgZGVwZW5kaW5nIG9uIHRoZSBuZWVkcyBvZiB0aGUgYXBwbGljYXRpb24gYW5kIHRoZSBlbnZpcm9ubWVudDoKKzwvUD4KKzxVTD4KKzxMST4KK0Egc2ltcGxlIGFwcHJvYWNoIHdvdWxkIGJlIHRvIGtlZXAgdHJhY2sgb2YgdGhlIG5ld2VzdAorbWVzc2FnZSBzZWVuIGJ5IHRoZSBhcHBsaWNhdGlvbi4KKzwvTEk+Cis8TEk+CitBbiBhbHRlcm5hdGl2ZSB3b3VsZCBiZSB0byBrZWVwIHRyYWNrIG9mIHRoZSBVSURzIChzZWUgYmVsb3cpCitvZiBhbGwgbWVzc2FnZXMgdGhhdCBoYXZlIGJlZW4gc2Vlbi4KKzwvTEk+Cis8TEk+CitBbm90aGVyIGFwcHJvYWNoIGlzIHRvIGRvd25sb2FkIDxzdHJvbmc+YWxsPC9zdHJvbmc+IG1lc3NhZ2VzIGludG8gYSBsb2NhbAorbWFpbGJveCwgc28gdGhhdCBhbGwgbWVzc2FnZXMgaW4gdGhlIFBPUDMgbWFpbGJveCBhcmUsIGJ5CitkZWZpbml0aW9uLCBuZXcuCis8L0xJPgorPC9VTD4KKzxQPgorQWxsIGFwcHJvYWNoZXMgd2lsbCByZXF1aXJlIHNvbWUgcGVybWFuZW50IHN0b3JhZ2UgYXNzb2NpYXRlZCB3aXRoIHRoZSBjbGllbnQuCis8L1A+Cis8UD4KK1BPUDMgZG9lcyBub3Qgc3VwcG9ydCB0aGUgPGNvZGU+Rm9sZGVyLmV4cHVuZ2UoKTwvY29kZT4gbWV0aG9kLiAgVG8gZGVsZXRlIGFuZAorZXhwdW5nZSBtZXNzYWdlcywgc2V0IHRoZSA8Y29kZT5GbGFncy5GbGFnLkRFTEVURUQ8L2NvZGU+IGZsYWcgb24gdGhlIG1lc3NhZ2VzCithbmQgY2xvc2UgdGhlIGZvbGRlciB1c2luZyB0aGUgPGNvZGU+Rm9sZGVyLmNsb3NlKHRydWUpPC9jb2RlPiBtZXRob2QuICBZb3UKK2Nhbm5vdCBleHB1bmdlIHdpdGhvdXQgY2xvc2luZyB0aGUgZm9sZGVyLgorPC9QPgorPFA+CitQT1AzIGRvZXMgbm90IHByb3ZpZGUgYSAicmVjZWl2ZWQgZGF0ZSIsIHNvIHRoZSA8Y29kZT5nZXRSZWNlaXZlZERhdGU8L2NvZGU+CittZXRob2Qgd2lsbCByZXR1cm4gbnVsbC4KK0l0IG1heSBiZSBwb3NzaWJsZSB0byBleGFtaW5lIG90aGVyIG1lc3NhZ2UgaGVhZGVycyAoZS5nLiwgdGhlCisiUmVjZWl2ZWQiIGhlYWRlcnMpIHRvIGVzdGltYXRlIHRoZSByZWNlaXZlZCBkYXRlLCBidXQgdGhlc2UgdGVjaG5pcXVlcworYXJlIGVycm9yLXByb25lIGF0IGJlc3QuCis8L1A+Cis8UD4KK1RoZSBQT1AzIHByb3ZpZGVyIHN1cHBvcnRzIHRoZSBQT1AzIFVJREwgY29tbWFuZCwgc2VlCit7QGxpbmsgY29tLnN1bi5tYWlsLnBvcDMuUE9QM0ZvbGRlciNnZXRVSUQgUE9QM0ZvbGRlci5nZXRVSUQoKX0uCitZb3UgY2FuIHVzZSBpdCBhcyBmb2xsb3dzOgorPC9QPgorPEJMT0NLUVVPVEU+PFBSRT4KK2lmIChmb2xkZXIgaW5zdGFuY2VvZiBjb20uc3VuLm1haWwucG9wMy5QT1AzRm9sZGVyKSB7CisgICAgY29tLnN1bi5tYWlsLnBvcDMuUE9QM0ZvbGRlciBwZiA9CisJKGNvbS5zdW4ubWFpbC5wb3AzLlBPUDNGb2xkZXIpZm9sZGVyOworICAgIFN0cmluZyB1aWQgPSBwZi5nZXRVSUQobXNnKTsKKyAgICBpZiAodWlkICE9IG51bGwpCisJLi4uIC8vIHVzZSBpdAorfQorPC9QUkU+PC9CTE9DS1FVT1RFPgorPFA+CitZb3UgY2FuIGFsc28gcHJlLWZldGNoIGFsbCB0aGUgVUlEcyBmb3IgYWxsIG1lc3NhZ2VzIGxpa2UgdGhpczoKKzwvUD4KKzxCTE9DS1FVT1RFPjxQUkU+CitGZXRjaFByb2ZpbGUgZnAgPSBuZXcgRmV0Y2hQcm9maWxlKCk7CitmcC5hZGQoVUlERm9sZGVyLkZldGNoUHJvZmlsZUl0ZW0uVUlEKTsKK2ZvbGRlci5mZXRjaChmb2xkZXIuZ2V0TWVzc2FnZXMoKSwgZnApOworPC9QUkU+PC9CTE9DS1FVT1RFPgorPFA+CitUaGVuIHVzZSB0aGUgdGVjaG5pcXVlIGFib3ZlIHRvIGdldCB0aGUgVUlEIGZvciBlYWNoIG1lc3NhZ2UuICBUaGlzIGlzCitzaW1pbGFyIHRvIHRoZSB0ZWNobmlxdWUgdXNlZCB3aXRoIHRoZSBVSURGb2xkZXIgaW50ZXJmYWNlIHN1cHBvcnRlZCBieQorSU1BUCwgYnV0IG5vdGUgdGhhdCBQT1AzIFVJRHMgYXJlIHN0cmluZ3MsIG5vdCBpbnRlZ2VycyBsaWtlIElNQVAKK1VJRHMuICBTZWUgdGhlIFBPUDMgc3BlYyBmb3IgZGV0YWlscy4KKzwvUD4KKzxQPgorV2hlbiB0aGUgaGVhZGVycyBvZiBhIFBPUDMgbWVzc2FnZSBhcmUgYWNjZXNzZWQsIHRoZSBQT1AzIHByb3ZpZGVyIHVzZXMKK3RoZSBUT1AgY29tbWFuZCB0byBmZXRjaCBhbGwgaGVhZGVycywgd2hpY2ggYXJlIHRoZW4gY2FjaGVkLiAgVXNlIG9mIHRoZQorVE9QIGNvbW1hbmQgY2FuIGJlIGRpc2FibGVkIHdpdGggdGhlIDxDT0RFPm1haWwucG9wMy5kaXNhYmxldG9wPC9DT0RFPgorcHJvcGVydHksIGluIHdoaWNoIGNhc2UgdGhlIGVudGlyZSBtZXNzYWdlIGNvbnRlbnQgaXMgZmV0Y2hlZCB3aXRoIHRoZQorUkVUUiBjb21tYW5kLgorPC9QPgorPFA+CitXaGVuIHRoZSBjb250ZW50IG9mIGEgUE9QMyBtZXNzYWdlIGlzIGFjY2Vzc2VkLCB0aGUgUE9QMyBwcm92aWRlciB1c2VzCit0aGUgUkVUUiBjb21tYW5kIHRvIGZldGNoIHRoZSBlbnRpcmUgbWVzc2FnZS4gIE5vcm1hbGx5IHRoZSBtZXNzYWdlCitjb250ZW50IGlzIGNhY2hlZCBpbiBtZW1vcnkuICBCeSBzZXR0aW5nIHRoZQorPENPREU+bWFpbC5wb3AzLmZpbGVjYWNoZS5lbmFibGU8L0NPREU+IHByb3BlcnR5LCB0aGUgbWVzc2FnZSBjb250ZW50Cit3aWxsIGluc3RlYWQgYmUgY2FjaGVkIGluIGEgdGVtcG9yYXJ5IGZpbGUuICBUaGUgZmlsZSB3aWxsIGJlIHJlbW92ZWQKK3doZW4gdGhlIGZvbGRlciBpcyBjbG9zZWQuICBDYWNoaW5nIG1lc3NhZ2UgY29udGVudCBpbiBhIGZpbGUgaXMgZ2VuZXJhbGx5CitzbG93ZXIsIGJ1dCB1c2VzIHN1YnN0YW50aWFsbHkgbGVzcyBtZW1vcnkgYW5kIG1heSBiZSBoZWxwZnVsIHdoZW4gZGVhbGluZword2l0aCB2ZXJ5IGxhcmdlIG1lc3NhZ2VzLgorPC9QPgorPFA+CitUaGUge0BsaW5rIGNvbS5zdW4ubWFpbC5wb3AzLlBPUDNNZXNzYWdlI2ludmFsaWRhdGUgUE9QM01lc3NhZ2UuaW52YWxpZGF0ZX0KK21ldGhvZCBjYW4gYmUgdXNlZCB0byBpbnZhbGlkYXRlIGNhY2hlZCBkYXRhIHdpdGhvdXQgY2xvc2luZyB0aGUgZm9sZGVyLgorTm90ZSB0aGF0IGlmIHRoZSBmaWxlIGNhY2hlIGlzIGJlaW5nIHVzZWQgdGhlIGRhdGEgaW4gdGhlIGZpbGUgd2lsbCBiZQorZm9yZ290dGVuIGFuZCBmZXRjaGVkIGZyb20gdGhlIHNlcnZlciBpZiBpdCdzIG5lZWRlZCBhZ2FpbiwgYW5kIHN0b3JlZCBhZ2FpbgoraW4gdGhlIGZpbGUgY2FjaGUuCis8L1A+Cis8UD4KK1RoZSBQT1AzIENBUEEgY29tbWFuZCAoZGVmaW5lZCBieQorPEEgSFJFRj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjQ0OS50eHQiIFRBUkdFVD0iX3RvcCI+UkZDIDI0NDk8L0E+KQord2lsbCBiZSB1c2VkIHRvIGRldGVybWluZSB0aGUgY2FwYWJpbGl0aWVzIHN1cHBvcnRlZCBieSB0aGUgc2VydmVyLgorU29tZSBzZXJ2ZXJzIGRvbid0IGltcGxlbWVudCB0aGUgQ0FQQSBjb21tYW5kLCBhbmQgc29tZSBzZXJ2ZXJzIGRvbid0CityZXR1cm4gY29ycmVjdCBpbmZvcm1hdGlvbiwgc28gdmFyaW91cyBwcm9wZXJ0aWVzIGFyZSBhdmFpbGFibGUgdG8KK2Rpc2FibGUgdXNlIG9mIGNlcnRhaW4gUE9QMyBjb21tYW5kcywgaW5jbHVkaW5nIENBUEEuCis8L1A+Cis8UD4KK0lmIHRoZSBzZXJ2ZXIgYWR2ZXJ0aXNlcyB0aGUgUElQRUxJTklORyBjYXBhYmlsaXR5IChkZWZpbmVkIGJ5Cis8QSBIUkVGPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyNDQ5LnR4dCIgVEFSR0VUPSJfdG9wIj5SRkMgMjQ0OTwvQT4pLAorb3IgdGhlIDxDT0RFPm1haWwucG9wMy5waXBlbGluaW5nPC9DT0RFPiBwcm9wZXJ0eSBpcyBzZXQsIHRoZSBQT1AzCitwcm92aWRlciB3aWxsIHNlbmQgc29tZSBjb21tYW5kcyBpbiBiYXRjaGVzLCB3aGljaCBjYW4gc2lnbmlmaWNhbnRseQoraW1wcm92ZSBwZXJmb3JtYW5jZSBhbmQgbWVtb3J5IHVzZS4KK1NvbWUgc2VydmVycyB0aGF0IGRvbid0IHN1cHBvcnQgdGhlIENBUEEgY29tbWFuZCBvciBkb24ndCBhZHZlcnRpc2UKK1BJUEVMSU5JTkcgbWF5IHN0aWxsIHN1cHBvcnQgcGlwZWxpbmluZzsgZXhwZXJpbWVudGF0aW9uIG1heSBiZSByZXF1aXJlZC4KKzwvUD4KKzxQPgorSWYgcGlwZWxpbmluZyBpcyBzdXBwb3J0ZWQgYW5kIHRoZSBjb25uZWN0aW9uIGlzIHVzaW5nCitTU0wsIHRoZSBVU0VSIGFuZCBQQVNTIGNvbW1hbmRzIHdpbGwgYmUgc2VudCBhcyBhIGJhdGNoLgorKElmIFNTTCBpcyBub3QgYmVpbmcgdXNlZCwgdGhlIFBBU1MgY29tbWFuZCBpc24ndCBzZW50Cit1bnRpbCB0aGUgdXNlciBpcyB2ZXJpZmllZCB0byBhdm9pZCBleHBvc2luZyB0aGUgcGFzc3dvcmQKK2lmIHRoZSB1c2VyIG5hbWUgaXMgYmFkLikKKzwvUD4KKzxQPgorSWYgcGlwZWxpbmluZyBpcyBzdXBwb3J0ZWQsIHdoZW4gZmV0Y2hpbmcgYSBtZXNzYWdlIHdpdGggdGhlIFJFVFIgY29tbWFuZCwKK3RoZSBMSVNUIGNvbW1hbmQgd2lsbCBiZSBzZW50IGFzIHdlbGwsIGFuZCB0aGUgcmVzdWx0IHdpbGwgYmUgdXNlZCB0byBzaXplCit0aGUgSS9PIGJ1ZmZlciwgZ3JlYXRseSByZWR1Y2luZyBtZW1vcnkgdXNhZ2Ugd2hlbiBmZXRjaGluZyBtZXNzYWdlcy4KKzwvUD4KKzxBIE5BTUU9InByb3BlcnRpZXMiPjxTVFJPTkc+UHJvcGVydGllczwvU1RST05HPjwvQT4KKzxQPgorVGhlIFBPUDMgcHJvdG9jb2wgcHJvdmlkZXIgc3VwcG9ydHMgdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzLAord2hpY2ggbWF5IGJlIHNldCBpbiB0aGUgSmF2YU1haWwgPGNvZGU+U2Vzc2lvbjwvY29kZT4gb2JqZWN0LgorVGhlIHByb3BlcnRpZXMgYXJlIGFsd2F5cyBzZXQgYXMgc3RyaW5nczsgdGhlIFR5cGUgY29sdW1uIGRlc2NyaWJlcworaG93IHRoZSBzdHJpbmcgaXMgaW50ZXJwcmV0ZWQuICBGb3IgZXhhbXBsZSwgdXNlCis8L1A+Cis8UFJFPgorCXByb3BzLnB1dCgibWFpbC5wb3AzLnBvcnQiLCAiODg4Iik7Cis8L1BSRT4KKzxQPgordG8gc2V0IHRoZSA8Q09ERT5tYWlsLnBvcDMucG9ydDwvQ09ERT4gcHJvcGVydHksIHdoaWNoIGlzIG9mIHR5cGUgaW50LgorPC9QPgorPFA+CitOb3RlIHRoYXQgaWYgeW91J3JlIHVzaW5nIHRoZSAicG9wM3MiIHByb3RvY29sIHRvIGFjY2VzcyBQT1AzIG92ZXIgU1NMLAorYWxsIHRoZSBwcm9wZXJ0aWVzIHdvdWxkIGJlIG5hbWVkICJtYWlsLnBvcDNzLioiLgorPC9QPgorPFRBQkxFIEJPUkRFUiBTVU1NQVJZPSJQT1AzIHByb3BlcnRpZXMiPgorPFRSPgorPFRIPk5hbWU8L1RIPgorPFRIPlR5cGU8L1RIPgorPFRIPkRlc2NyaXB0aW9uPC9USD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnBvcDMudXNlciI+bWFpbC5wb3AzLnVzZXI8L0E+PC9URD4KKzxURD5TdHJpbmc8L1REPgorPFREPkRlZmF1bHQgdXNlciBuYW1lIGZvciBQT1AzLjwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5wb3AzLmhvc3QiPm1haWwucG9wMy5ob3N0PC9BPjwvVEQ+Cis8VEQ+U3RyaW5nPC9URD4KKzxURD5UaGUgUE9QMyBzZXJ2ZXIgdG8gY29ubmVjdCB0by48L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwucG9wMy5wb3J0Ij5tYWlsLnBvcDMucG9ydDwvQT48L1REPgorPFREPmludDwvVEQ+Cis8VEQ+VGhlIFBPUDMgc2VydmVyIHBvcnQgdG8gY29ubmVjdCB0bywgaWYgdGhlIGNvbm5lY3QoKSBtZXRob2QgZG9lc24ndAorZXhwbGljaXRseSBzcGVjaWZ5IG9uZS4gRGVmYXVsdHMgdG8gMTEwLjwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5wb3AzLmNvbm5lY3Rpb250aW1lb3V0Ij5tYWlsLnBvcDMuY29ubmVjdGlvbnRpbWVvdXQ8L0E+PC9URD4KKzxURD5pbnQ8L1REPgorPFREPlNvY2tldCBjb25uZWN0aW9uIHRpbWVvdXQgdmFsdWUgaW4gbWlsbGlzZWNvbmRzLgorVGhpcyB0aW1lb3V0IGlzIGltcGxlbWVudGVkIGJ5IGphdmEubmV0LlNvY2tldC4KK0RlZmF1bHQgaXMgaW5maW5pdGUgdGltZW91dC48L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwucG9wMy50aW1lb3V0Ij5tYWlsLnBvcDMudGltZW91dDwvQT48L1REPgorPFREPmludDwvVEQ+Cis8VEQ+U29ja2V0IHJlYWQgdGltZW91dCB2YWx1ZSBpbiBtaWxsaXNlY29uZHMuCitUaGlzIHRpbWVvdXQgaXMgaW1wbGVtZW50ZWQgYnkgamF2YS5uZXQuU29ja2V0LgorRGVmYXVsdCBpcyBpbmZpbml0ZSB0aW1lb3V0LjwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5wb3AzLndyaXRldGltZW91dCI+bWFpbC5wb3AzLndyaXRldGltZW91dDwvQT48L1REPgorPFREPmludDwvVEQ+Cis8VEQ+U29ja2V0IHdyaXRlIHRpbWVvdXQgdmFsdWUgaW4gbWlsbGlzZWNvbmRzLgorVGhpcyB0aW1lb3V0IGlzIGltcGxlbWVudGVkIGJ5IHVzaW5nIGEKK2phdmEudXRpbC5jb25jdXJyZW50LlNjaGVkdWxlZEV4ZWN1dG9yU2VydmljZSBwZXIgY29ubmVjdGlvbgordGhhdCBzY2hlZHVsZXMgYSB0aHJlYWQgdG8gY2xvc2UgdGhlIHNvY2tldCBpZiB0aGUgdGltZW91dCBleHBpcmVzLgorVGh1cywgdGhlIG92ZXJoZWFkIG9mIHVzaW5nIHRoaXMgdGltZW91dCBpcyBvbmUgdGhyZWFkIHBlciBjb25uZWN0aW9uLgorRGVmYXVsdCBpcyBpbmZpbml0ZSB0aW1lb3V0LjwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5wb3AzLnJzZXRiZWZvcmVxdWl0Ij5tYWlsLnBvcDMucnNldGJlZm9yZXF1aXQ8L0E+PC9URD4KKzxURD5ib29sZWFuPC9URD4KKzxURD4KK1NlbmQgYSBQT1AzIFJTRVQgY29tbWFuZCB3aGVuIGNsb3NpbmcgdGhlIGZvbGRlciwgYmVmb3JlIHNlbmRpbmcgdGhlCitRVUlUIGNvbW1hbmQuICBVc2VmdWwgd2l0aCBQT1AzIHNlcnZlcnMgdGhhdCBpbXBsaWNpdGx5IG1hcmsgYWxsCittZXNzYWdlcyB0aGF0IGFyZSByZWFkIGFzICJkZWxldGVkIjsgdGhpcyB3aWxsIHByZXZlbnQgc3VjaCBtZXNzYWdlcworZnJvbSBiZWluZyBkZWxldGVkIGFuZCBleHB1bmdlZCB1bmxlc3MgdGhlIGNsaWVudCByZXF1ZXN0cyBzby4gIERlZmF1bHQKK2lzIGZhbHNlLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnBvcDMubWVzc2FnZS5jbGFzcyI+bWFpbC5wb3AzLm1lc3NhZ2UuY2xhc3M8L0E+PC9URD4KKzxURD5TdHJpbmc8L1REPgorPFREPgorQ2xhc3MgbmFtZSBvZiBhIHN1YmNsYXNzIG9mIDxjb2RlPmNvbS5zdW4ubWFpbC5wb3AzLlBPUDNNZXNzYWdlPC9jb2RlPi4KK1RoZSBzdWJjbGFzcyBjYW4gYmUgdXNlZCB0byBoYW5kbGUgKGZvciBleGFtcGxlKSBub24tc3RhbmRhcmQKK0NvbnRlbnQtVHlwZSBoZWFkZXJzLiAgVGhlIHN1YmNsYXNzIG11c3QgaGF2ZSBhIHB1YmxpYyBjb25zdHJ1Y3Rvcgorb2YgdGhlIGZvcm0gPGNvZGU+TXlQT1AzTWVzc2FnZShGb2xkZXIgZiwgaW50IG1zZ25vKQordGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbjwvY29kZT4uCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwucG9wMy5sb2NhbGFkZHJlc3MiPm1haWwucG9wMy5sb2NhbGFkZHJlc3M8L0E+PC9URD4KKzxURD5TdHJpbmc8L1REPgorPFREPgorTG9jYWwgYWRkcmVzcyAoaG9zdCBuYW1lKSB0byBiaW5kIHRvIHdoZW4gY3JlYXRpbmcgdGhlIFBPUDMgc29ja2V0LgorRGVmYXVsdHMgdG8gdGhlIGFkZHJlc3MgcGlja2VkIGJ5IHRoZSBTb2NrZXQgY2xhc3MuCitTaG91bGQgbm90IG5vcm1hbGx5IG5lZWQgdG8gYmUgc2V0LCBidXQgdXNlZnVsIHdpdGggbXVsdGktaG9tZWQgaG9zdHMKK3doZXJlIGl0J3MgaW1wb3J0YW50IHRvIHBpY2sgYSBwYXJ0aWN1bGFyIGxvY2FsIGFkZHJlc3MgdG8gYmluZCB0by4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5wb3AzLmxvY2FscG9ydCI+bWFpbC5wb3AzLmxvY2FscG9ydDwvQT48L1REPgorPFREPmludDwvVEQ+Cis8VEQ+CitMb2NhbCBwb3J0IG51bWJlciB0byBiaW5kIHRvIHdoZW4gY3JlYXRpbmcgdGhlIFBPUDMgc29ja2V0LgorRGVmYXVsdHMgdG8gdGhlIHBvcnQgbnVtYmVyIHBpY2tlZCBieSB0aGUgU29ja2V0IGNsYXNzLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnBvcDMuYXBvcC5lbmFibGUiPm1haWwucG9wMy5hcG9wLmVuYWJsZTwvQT48L1REPgorPFREPmJvb2xlYW48L1REPgorPFREPgorSWYgc2V0IHRvIHRydWUsIHVzZSBBUE9QIGluc3RlYWQgb2YgVVNFUi9QQVNTIHRvIGxvZ2luIHRvIHRoZQorUE9QMyBzZXJ2ZXIsIGlmIHRoZSBQT1AzIHNlcnZlciBzdXBwb3J0cyBBUE9QLiAgQVBPUCBzZW5kcyBhCitkaWdlc3Qgb2YgdGhlIHBhc3N3b3JkIHJhdGhlciB0aGFuIHRoZSBjbGVhciB0ZXh0IHBhc3N3b3JkLgorRGVmYXVsdHMgdG8gZmFsc2UuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwucG9wMy5zb2NrZXRGYWN0b3J5Ij5tYWlsLnBvcDMuc29ja2V0RmFjdG9yeTwvQT48L1REPgorPFREPlNvY2tldEZhY3Rvcnk8L1REPgorPFREPgorSWYgc2V0IHRvIGEgY2xhc3MgdGhhdCBpbXBsZW1lbnRzIHRoZQorPGNvZGU+amF2YXgubmV0LlNvY2tldEZhY3Rvcnk8L2NvZGU+IGludGVyZmFjZSwgdGhpcyBjbGFzcword2lsbCBiZSB1c2VkIHRvIGNyZWF0ZSBQT1AzIHNvY2tldHMuICBOb3RlIHRoYXQgdGhpcyBpcyBhbgoraW5zdGFuY2Ugb2YgYSBjbGFzcywgbm90IGEgbmFtZSwgYW5kIG11c3QgYmUgc2V0IHVzaW5nIHRoZQorPGNvZGU+cHV0PC9jb2RlPiBtZXRob2QsIG5vdCB0aGUgPGNvZGU+c2V0UHJvcGVydHk8L2NvZGU+IG1ldGhvZC4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5wb3AzLnNvY2tldEZhY3RvcnkuY2xhc3MiPm1haWwucG9wMy5zb2NrZXRGYWN0b3J5LmNsYXNzPC9BPjwvVEQ+Cis8VEQ+U3RyaW5nPC9URD4KKzxURD4KK0lmIHNldCwgc3BlY2lmaWVzIHRoZSBuYW1lIG9mIGEgY2xhc3MgdGhhdCBpbXBsZW1lbnRzIHRoZQorPGNvZGU+amF2YXgubmV0LlNvY2tldEZhY3Rvcnk8L2NvZGU+IGludGVyZmFjZS4gIFRoaXMgY2xhc3MKK3dpbGwgYmUgdXNlZCB0byBjcmVhdGUgUE9QMyBzb2NrZXRzLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnBvcDMuc29ja2V0RmFjdG9yeS5mYWxsYmFjayI+bWFpbC5wb3AzLnNvY2tldEZhY3RvcnkuZmFsbGJhY2s8L0E+PC9URD4KKzxURD5ib29sZWFuPC9URD4KKzxURD4KK0lmIHNldCB0byB0cnVlLCBmYWlsdXJlIHRvIGNyZWF0ZSBhIHNvY2tldCB1c2luZyB0aGUgc3BlY2lmaWVkCitzb2NrZXQgZmFjdG9yeSBjbGFzcyB3aWxsIGNhdXNlIHRoZSBzb2NrZXQgdG8gYmUgY3JlYXRlZCB1c2luZwordGhlIDxjb2RlPmphdmEubmV0LlNvY2tldDwvY29kZT4gY2xhc3MuCitEZWZhdWx0cyB0byB0cnVlLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnBvcDMuc29ja2V0RmFjdG9yeS5wb3J0Ij5tYWlsLnBvcDMuc29ja2V0RmFjdG9yeS5wb3J0PC9BPjwvVEQ+Cis8VEQ+aW50PC9URD4KKzxURD4KK1NwZWNpZmllcyB0aGUgcG9ydCB0byBjb25uZWN0IHRvIHdoZW4gdXNpbmcgdGhlIHNwZWNpZmllZCBzb2NrZXQKK2ZhY3RvcnkuCitJZiBub3Qgc2V0LCB0aGUgZGVmYXVsdCBwb3J0IHdpbGwgYmUgdXNlZC4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5wb3AzLnNzbC5lbmFibGUiPm1haWwucG9wMy5zc2wuZW5hYmxlPC9BPjwvVEQ+Cis8VEQ+Ym9vbGVhbjwvVEQ+Cis8VEQ+CitJZiBzZXQgdG8gdHJ1ZSwgdXNlIFNTTCB0byBjb25uZWN0IGFuZCB1c2UgdGhlIFNTTCBwb3J0IGJ5IGRlZmF1bHQuCitEZWZhdWx0cyB0byBmYWxzZSBmb3IgdGhlICJwb3AzIiBwcm90b2NvbCBhbmQgdHJ1ZSBmb3IgdGhlICJwb3AzcyIgcHJvdG9jb2wuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwucG9wMy5zc2wuY2hlY2tzZXJ2ZXJpZGVudGl0eSI+bWFpbC5wb3AzLnNzbC5jaGVja3NlcnZlcmlkZW50aXR5PC9BPjwvVEQ+Cis8VEQ+Ym9vbGVhbjwvVEQ+Cis8VEQ+CitJZiBzZXQgdG8gdHJ1ZSwgY2hlY2sgdGhlIHNlcnZlciBpZGVudGl0eSBhcyBzcGVjaWZpZWQgYnkKKzxBIEhSRUY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzI1OTUudHh0IiBUQVJHRVQ9Il90b3AiPlJGQyAyNTk1PC9BPi4KK1RoZXNlIGFkZGl0aW9uYWwgY2hlY2tzIGJhc2VkIG9uIHRoZSBjb250ZW50IG9mIHRoZSBzZXJ2ZXIncyBjZXJ0aWZpY2F0ZQorYXJlIGludGVuZGVkIHRvIHByZXZlbnQgbWFuLWluLXRoZS1taWRkbGUgYXR0YWNrcy4KK0RlZmF1bHRzIHRvIGZhbHNlLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnBvcDMuc3NsLnRydXN0Ij5tYWlsLnBvcDMuc3NsLnRydXN0PC9BPjwvVEQ+Cis8VEQ+U3RyaW5nPC9URD4KKzxURD4KK0lmIHNldCwgYW5kIGEgc29ja2V0IGZhY3RvcnkgaGFzbid0IGJlZW4gc3BlY2lmaWVkLCBlbmFibGVzIHVzZSBvZiBhCit7QGxpbmsgY29tLnN1bi5tYWlsLnV0aWwuTWFpbFNTTFNvY2tldEZhY3RvcnkgTWFpbFNTTFNvY2tldEZhY3Rvcnl9LgorSWYgc2V0IHRvICIqIiwgYWxsIGhvc3RzIGFyZSB0cnVzdGVkLgorSWYgc2V0IHRvIGEgd2hpdGVzcGFjZSBzZXBhcmF0ZWQgbGlzdCBvZiBob3N0cywgdGhvc2UgaG9zdHMgYXJlIHRydXN0ZWQuCitPdGhlcndpc2UsIHRydXN0IGRlcGVuZHMgb24gdGhlIGNlcnRpZmljYXRlIHRoZSBzZXJ2ZXIgcHJlc2VudHMuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwucG9wMy5zc2wuc29ja2V0RmFjdG9yeSI+bWFpbC5wb3AzLnNzbC5zb2NrZXRGYWN0b3J5PC9BPjwvVEQ+Cis8VEQ+U1NMU29ja2V0RmFjdG9yeTwvVEQ+Cis8VEQ+CitJZiBzZXQgdG8gYSBjbGFzcyB0aGF0IGV4dGVuZHMgdGhlCis8Y29kZT5qYXZheC5uZXQuc3NsLlNTTFNvY2tldEZhY3Rvcnk8L2NvZGU+IGNsYXNzLCB0aGlzIGNsYXNzCit3aWxsIGJlIHVzZWQgdG8gY3JlYXRlIFBPUDMgU1NMIHNvY2tldHMuICBOb3RlIHRoYXQgdGhpcyBpcyBhbgoraW5zdGFuY2Ugb2YgYSBjbGFzcywgbm90IGEgbmFtZSwgYW5kIG11c3QgYmUgc2V0IHVzaW5nIHRoZQorPGNvZGU+cHV0PC9jb2RlPiBtZXRob2QsIG5vdCB0aGUgPGNvZGU+c2V0UHJvcGVydHk8L2NvZGU+IG1ldGhvZC4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5wb3AzLnNzbC5zb2NrZXRGYWN0b3J5LmNsYXNzIj5tYWlsLnBvcDMuc3NsLnNvY2tldEZhY3RvcnkuY2xhc3M8L0E+PC9URD4KKzxURD5TdHJpbmc8L1REPgorPFREPgorSWYgc2V0LCBzcGVjaWZpZXMgdGhlIG5hbWUgb2YgYSBjbGFzcyB0aGF0IGV4dGVuZHMgdGhlCis8Y29kZT5qYXZheC5uZXQuc3NsLlNTTFNvY2tldEZhY3Rvcnk8L2NvZGU+IGNsYXNzLiAgVGhpcyBjbGFzcword2lsbCBiZSB1c2VkIHRvIGNyZWF0ZSBQT1AzIFNTTCBzb2NrZXRzLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnBvcDMuc3NsLnNvY2tldEZhY3RvcnkucG9ydCI+bWFpbC5wb3AzLnNzbC5zb2NrZXRGYWN0b3J5LnBvcnQ8L0E+PC9URD4KKzxURD5pbnQ8L1REPgorPFREPgorU3BlY2lmaWVzIHRoZSBwb3J0IHRvIGNvbm5lY3QgdG8gd2hlbiB1c2luZyB0aGUgc3BlY2lmaWVkIHNvY2tldAorZmFjdG9yeS4KK0lmIG5vdCBzZXQsIHRoZSBkZWZhdWx0IHBvcnQgd2lsbCBiZSB1c2VkLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnBvcDMuc3NsLnByb3RvY29scyI+bWFpbC5wb3AzLnNzbC5wcm90b2NvbHM8L0E+PC9URD4KKzxURD5zdHJpbmc8L1REPgorPFREPgorU3BlY2lmaWVzIHRoZSBTU0wgcHJvdG9jb2xzIHRoYXQgd2lsbCBiZSBlbmFibGVkIGZvciBTU0wgY29ubmVjdGlvbnMuCitUaGUgcHJvcGVydHkgdmFsdWUgaXMgYSB3aGl0ZXNwYWNlIHNlcGFyYXRlZCBsaXN0IG9mIHRva2VucyBhY2NlcHRhYmxlCit0byB0aGUgPGNvZGU+amF2YXgubmV0LnNzbC5TU0xTb2NrZXQuc2V0RW5hYmxlZFByb3RvY29sczwvY29kZT4gbWV0aG9kLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnBvcDMuc3NsLmNpcGhlcnN1aXRlcyI+bWFpbC5wb3AzLnNzbC5jaXBoZXJzdWl0ZXM8L0E+PC9URD4KKzxURD5zdHJpbmc8L1REPgorPFREPgorU3BlY2lmaWVzIHRoZSBTU0wgY2lwaGVyIHN1aXRlcyB0aGF0IHdpbGwgYmUgZW5hYmxlZCBmb3IgU1NMIGNvbm5lY3Rpb25zLgorVGhlIHByb3BlcnR5IHZhbHVlIGlzIGEgd2hpdGVzcGFjZSBzZXBhcmF0ZWQgbGlzdCBvZiB0b2tlbnMgYWNjZXB0YWJsZQordG8gdGhlIDxjb2RlPmphdmF4Lm5ldC5zc2wuU1NMU29ja2V0LnNldEVuYWJsZWRDaXBoZXJTdWl0ZXM8L2NvZGU+IG1ldGhvZC4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5wb3AzLnN0YXJ0dGxzLmVuYWJsZSI+bWFpbC5wb3AzLnN0YXJ0dGxzLmVuYWJsZTwvQT48L1REPgorPFREPmJvb2xlYW48L1REPgorPFREPgorSWYgdHJ1ZSwgZW5hYmxlcyB0aGUgdXNlIG9mIHRoZSA8Y29kZT5TVExTPC9jb2RlPiBjb21tYW5kIChpZgorc3VwcG9ydGVkIGJ5IHRoZSBzZXJ2ZXIpIHRvIHN3aXRjaCB0aGUgY29ubmVjdGlvbiB0byBhIFRMUy1wcm90ZWN0ZWQKK2Nvbm5lY3Rpb24gYmVmb3JlIGlzc3VpbmcgYW55IGxvZ2luIGNvbW1hbmRzLgorSWYgdGhlIHNlcnZlciBkb2VzIG5vdCBzdXBwb3J0IFNUQVJUVExTLCB0aGUgY29ubmVjdGlvbiBjb250aW51ZXMgd2l0aG91dAordGhlIHVzZSBvZiBUTFM7IHNlZSB0aGUKKzxBIEhSRUY9IiNtYWlsLnBvcDMuc3RhcnR0bHMucmVxdWlyZWQiPjxjb2RlPm1haWwucG9wMy5zdGFydHRscy5yZXF1aXJlZDwvY29kZT48L0E+Citwcm9wZXJ0eSB0byBmYWlsIGlmIFNUQVJUVExTIGlzbid0IHN1cHBvcnRlZC4KK05vdGUgdGhhdCBhbiBhcHByb3ByaWF0ZSB0cnVzdCBzdG9yZSBtdXN0IGNvbmZpZ3VyZWQgc28gdGhhdCB0aGUgY2xpZW50Cit3aWxsIHRydXN0IHRoZSBzZXJ2ZXIncyBjZXJ0aWZpY2F0ZS4KK0RlZmF1bHRzIHRvIGZhbHNlLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnBvcDMuc3RhcnR0bHMucmVxdWlyZWQiPm1haWwucG9wMy5zdGFydHRscy5yZXF1aXJlZDwvQT48L1REPgorPFREPmJvb2xlYW48L1REPgorPFREPgorSWYgdHJ1ZSwgcmVxdWlyZXMgdGhlIHVzZSBvZiB0aGUgPGNvZGU+U1RMUzwvY29kZT4gY29tbWFuZC4KK0lmIHRoZSBzZXJ2ZXIgZG9lc24ndCBzdXBwb3J0IHRoZSBTVExTIGNvbW1hbmQsIG9yIHRoZSBjb21tYW5kCitmYWlscywgdGhlIGNvbm5lY3QgbWV0aG9kIHdpbGwgZmFpbC4KK0RlZmF1bHRzIHRvIGZhbHNlLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnBvcDMucHJveHkuaG9zdCI+bWFpbC5wb3AzLnByb3h5Lmhvc3Q8L0E+PC9URD4KKzxURD5zdHJpbmc8L1REPgorPFREPgorU3BlY2lmaWVzIHRoZSBob3N0IG5hbWUgb2YgYW4gSFRUUCB3ZWIgcHJveHkgc2VydmVyIHRoYXQgd2lsbCBiZSB1c2VkIGZvcgorY29ubmVjdGlvbnMgdG8gdGhlIG1haWwgc2VydmVyLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnBvcDMucHJveHkucG9ydCI+bWFpbC5wb3AzLnByb3h5LnBvcnQ8L0E+PC9URD4KKzxURD5zdHJpbmc8L1REPgorPFREPgorU3BlY2lmaWVzIHRoZSBwb3J0IG51bWJlciBmb3IgdGhlIEhUVFAgd2ViIHByb3h5IHNlcnZlci4KK0RlZmF1bHRzIHRvIHBvcnQgODAuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwucG9wMy5wcm94eS51c2VyIj5tYWlsLnBvcDMucHJveHkudXNlcjwvQT48L1REPgorPFREPnN0cmluZzwvVEQ+Cis8VEQ+CitTcGVjaWZpZXMgdGhlIHVzZXIgbmFtZSB0byB1c2UgdG8gYXV0aGVudGljYXRlIHdpdGggdGhlIEhUVFAgd2ViIHByb3h5IHNlcnZlci4KK0J5IGRlZmF1bHQsIG5vIGF1dGhlbnRpY2F0aW9uIGlzIGRvbmUuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwucG9wMy5wcm94eS5wYXNzd29yZCI+bWFpbC5wb3AzLnByb3h5LnBhc3N3b3JkPC9BPjwvVEQ+Cis8VEQ+c3RyaW5nPC9URD4KKzxURD4KK1NwZWNpZmllcyB0aGUgcGFzc3dvcmQgdG8gdXNlIHRvIGF1dGhlbnRpY2F0ZSB3aXRoIHRoZSBIVFRQIHdlYiBwcm94eSBzZXJ2ZXIuCitCeSBkZWZhdWx0LCBubyBhdXRoZW50aWNhdGlvbiBpcyBkb25lLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnBvcDMuc29ja3MuaG9zdCI+bWFpbC5wb3AzLnNvY2tzLmhvc3Q8L0E+PC9URD4KKzxURD5zdHJpbmc8L1REPgorPFREPgorU3BlY2lmaWVzIHRoZSBob3N0IG5hbWUgb2YgYSBTT0NLUzUgcHJveHkgc2VydmVyIHRoYXQgd2lsbCBiZSB1c2VkIGZvcgorY29ubmVjdGlvbnMgdG8gdGhlIG1haWwgc2VydmVyLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnBvcDMuc29ja3MucG9ydCI+bWFpbC5wb3AzLnNvY2tzLnBvcnQ8L0E+PC9URD4KKzxURD5zdHJpbmc8L1REPgorPFREPgorU3BlY2lmaWVzIHRoZSBwb3J0IG51bWJlciBmb3IgdGhlIFNPQ0tTNSBwcm94eSBzZXJ2ZXIuCitUaGlzIHNob3VsZCBvbmx5IG5lZWQgdG8gYmUgdXNlZCBpZiB0aGUgcHJveHkgc2VydmVyIGlzIG5vdCB1c2luZwordGhlIHN0YW5kYXJkIHBvcnQgbnVtYmVyIG9mIDEwODAuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwucG9wMy5kaXNhYmxldG9wIj5tYWlsLnBvcDMuZGlzYWJsZXRvcDwvQT48L1REPgorPFREPmJvb2xlYW48L1REPgorPFREPgorSWYgc2V0IHRvIHRydWUsIHRoZSBQT1AzIFRPUCBjb21tYW5kIHdpbGwgbm90IGJlIHVzZWQgdG8gZmV0Y2gKK21lc3NhZ2UgaGVhZGVycy4gIFRoaXMgaXMgdXNlZnVsIGZvciBQT1AzIHNlcnZlcnMgdGhhdCBkb24ndAorcHJvcGVybHkgaW1wbGVtZW50IHRoZSBUT1AgY29tbWFuZCwgb3IgdGhhdCBwcm92aWRlIGluY29ycmVjdAoraW5mb3JtYXRpb24gaW4gdGhlIFRPUCBjb21tYW5kIHJlc3VsdHMuCitEZWZhdWx0cyB0byBmYWxzZS4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5wb3AzLmRpc2FibGVjYXBhIj5tYWlsLnBvcDMuZGlzYWJsZWNhcGE8L0E+PC9URD4KKzxURD5ib29sZWFuPC9URD4KKzxURD4KK0lmIHNldCB0byB0cnVlLCB0aGUgUE9QMyBDQVBBIGNvbW1hbmQgd2lsbCBub3QgYmUgdXNlZCB0byBmZXRjaAorc2VydmVyIGNhcGFiaWxpdGllcy4gIFRoaXMgaXMgdXNlZnVsIGZvciBQT1AzIHNlcnZlcnMgdGhhdCBkb24ndAorcHJvcGVybHkgaW1wbGVtZW50IHRoZSBDQVBBIGNvbW1hbmQsIG9yIHRoYXQgcHJvdmlkZSBpbmNvcnJlY3QKK2luZm9ybWF0aW9uIGluIHRoZSBDQVBBIGNvbW1hbmQgcmVzdWx0cy4KK0RlZmF1bHRzIHRvIGZhbHNlLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnBvcDMuZm9yZ2V0dG9waGVhZGVycyI+bWFpbC5wb3AzLmZvcmdldHRvcGhlYWRlcnM8L0E+PC9URD4KKzxURD5ib29sZWFuPC9URD4KKzxURD4KK0lmIHNldCB0byB0cnVlLCB0aGUgaGVhZGVycyB0aGF0IG1pZ2h0IGhhdmUgYmVlbiByZXRyaWV2ZWQgdXNpbmcKK3RoZSBQT1AzIFRPUCBjb21tYW5kIHdpbGwgYmUgZm9yZ290dGVuIGFuZCByZXBsYWNlZCBieSBoZWFkZXJzCityZXRyaWV2ZWQgYXMgcGFydCBvZiB0aGUgUE9QMyBSRVRSIGNvbW1hbmQuICBTb21lIHNlcnZlcnMsIHN1Y2gKK2FzIHNvbWUgdmVyc2lvbnMgb2YgTWljcm9zZnQgRXhjaGFuZ2UgYW5kIElCTSBMb3R1cyBOb3RlcywKK3dpbGwgcmV0dXJuIHNsaWdodGx5IGRpZmZlcmVudAoraGVhZGVycyBlYWNoIHRpbWUgdGhlIFRPUCBvciBSRVRSIGNvbW1hbmQgaXMgdXNlZC4gIFRvIGFsbG93IHRoZQorUE9QMyBwcm92aWRlciB0byBwcm9wZXJseSBwYXJzZSB0aGUgbWVzc2FnZSBjb250ZW50IHJldHVybmVkIGZyb20KK3RoZSBSRVRSIGNvbW1hbmQsIHRoZSBoZWFkZXJzIGFsc28gcmV0dXJuZWQgYnkgdGhlIFJFVFIgY29tbWFuZAorbXVzdCBiZSB1c2VkLiAgU2V0dGluZyB0aGlzIHByb3BlcnR5IHRvIHRydWUgd2lsbCBjYXVzZSB0aGVzZQoraGVhZGVycyB0byBiZSB1c2VkLCBldmVuIGlmIHRoZXkgZGlmZmVyIGZyb20gdGhlIGhlYWRlcnMgcmV0dXJuZWQKK3ByZXZpb3VzbHkgYXMgYSByZXN1bHQgb2YgdXNpbmcgdGhlIFRPUCBjb21tYW5kLgorRGVmYXVsdHMgdG8gZmFsc2UuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwucG9wMy5maWxlY2FjaGUuZW5hYmxlIj5tYWlsLnBvcDMuZmlsZWNhY2hlLmVuYWJsZTwvQT48L1REPgorPFREPmJvb2xlYW48L1REPgorPFREPgorSWYgc2V0IHRvIHRydWUsIHRoZSBQT1AzIHByb3ZpZGVyIHdpbGwgY2FjaGUgbWVzc2FnZSBkYXRhIGluIGEgdGVtcG9yYXJ5CitmaWxlIHJhdGhlciB0aGFuIGluIG1lbW9yeS4gIE1lc3NhZ2VzIGFyZSBvbmx5IGFkZGVkIHRvIHRoZSBjYWNoZSB3aGVuCithY2Nlc3NpbmcgdGhlIG1lc3NhZ2UgY29udGVudC4gIE1lc3NhZ2UgaGVhZGVycyBhcmUgYWx3YXlzIGNhY2hlZCBpbgorbWVtb3J5IChvbiBkZW1hbmQpLiAgVGhlIGZpbGUgY2FjaGUgaXMgcmVtb3ZlZCB3aGVuIHRoZSBmb2xkZXIgaXMgY2xvc2VkCitvciB0aGUgSlZNIHRlcm1pbmF0ZXMuCitEZWZhdWx0cyB0byBmYWxzZS4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5wb3AzLmZpbGVjYWNoZS5kaXIiPm1haWwucG9wMy5maWxlY2FjaGUuZGlyPC9BPjwvVEQ+Cis8VEQ+U3RyaW5nPC9URD4KKzxURD4KK0lmIHRoZSBmaWxlIGNhY2hlIGlzIGVuYWJsZWQsIHRoaXMgcHJvcGVydHkgY2FuIGJlIHVzZWQgdG8gb3ZlcnJpZGUgdGhlCitkZWZhdWx0IGRpcmVjdG9yeSB1c2VkIGJ5IHRoZSBKREsgZm9yIHRlbXBvcmFyeSBmaWxlcy4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5wb3AzLmNhY2hld3JpdGV0byI+bWFpbC5wb3AzLmNhY2hld3JpdGV0bzwvQT48L1REPgorPFREPmJvb2xlYW48L1REPgorPFREPgorQ29udHJvbHMgdGhlIGJlaGF2aW9yIG9mIHRoZQore0BsaW5rIGNvbS5zdW4ubWFpbC5wb3AzLlBPUDNNZXNzYWdlI3dyaXRlVG8gd3JpdGVUb30gbWV0aG9kCitvbiBhIFBPUDMgbWVzc2FnZSBvYmplY3QuCitJZiBzZXQgdG8gdHJ1ZSwgYW5kIHRoZSBtZXNzYWdlIGNvbnRlbnQgaGFzbid0IHlldCBiZWVuIGNhY2hlZCwKK2FuZCBpZ25vcmVMaXN0IGlzIG51bGwsIHRoZSBtZXNzYWdlIGlzIGNhY2hlZCBiZWZvcmUgYmVpbmcgd3JpdHRlbi4KK090aGVyd2lzZSwgdGhlIG1lc3NhZ2UgaXMgc3RyZWFtZWQgZGlyZWN0bHkKK3RvIHRoZSBvdXRwdXQgc3RyZWFtIHdpdGhvdXQgYmVpbmcgY2FjaGVkLgorRGVmYXVsdHMgdG8gZmFsc2UuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwucG9wMy5rZWVwbWVzc2FnZWNvbnRlbnQiPm1haWwucG9wMy5rZWVwbWVzc2FnZWNvbnRlbnQ8L0E+PC9URD4KKzxURD5ib29sZWFuPC9URD4KKzxURD4KK1RoZSBjb250ZW50IG9mIGEgbWVzc2FnZSBpcyBjYWNoZWQgd2hlbiBpdCBpcyBmaXJzdCBmZXRjaGVkLgorTm9ybWFsbHkgdGhpcyBjYWNoZSB1c2VzIGEge0BsaW5rIGphdmEubGFuZy5yZWYuU29mdFJlZmVyZW5jZSBTb2Z0UmVmZXJlbmNlfQordG8gcmVmZXIgdG8gdGhlIGNhY2hlZCBjb250ZW50LiAgVGhpcyBhbGxvd3MgdGhlIGNhY2hlZCBjb250ZW50IHRvIGJlIHB1cmdlZAoraWYgbWVtb3J5IGlzIGxvdywgaW4gd2hpY2ggY2FzZSB0aGUgY29udGVudCB3aWxsIGJlIGZldGNoZWQgYWdhaW4gaWYgaXQncworbmVlZGVkLgorSWYgdGhpcyBwcm9wZXJ0eSBpcyBzZXQgdG8gdHJ1ZSwgYSBoYXJkIHJlZmVyZW5jZSB0byB0aGUgY2FjaGVkIGNvbnRlbnQKK3dpbGwgYmUga2VwdCwgcHJldmVudGluZyB0aGUgbWVtb3J5IGZyb20gYmVpbmcgcmV1c2VkIHVudGlsIHRoZSBmb2xkZXIKK2lzIGNsb3NlZCBvciB0aGUgY2FjaGVkIGNvbnRlbnQgaXMgZXhwbGljaXRseSBpbnZhbGlkYXRlZCAodXNpbmcgdGhlCit7QGxpbmsgY29tLnN1bi5tYWlsLnBvcDMuUE9QM01lc3NhZ2UjaW52YWxpZGF0ZSBpbnZhbGlkYXRlfSBtZXRob2QpLgorKFRoaXMgd2FzIHRoZSBiZWhhdmlvciBpbiBwcmV2aW91cyB2ZXJzaW9ucyBvZiBKYXZhTWFpbC4pCitEZWZhdWx0cyB0byBmYWxzZS4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5wb3AzLmZpbmFsaXplY2xlYW5jbG9zZSI+bWFpbC5wb3AzLmZpbmFsaXplY2xlYW5jbG9zZTwvQT48L1REPgorPFREPmJvb2xlYW48L1REPgorPFREPgorV2hlbiB0aGUgZmluYWxpemVyIGZvciBQT1AzU3RvcmUgb3IgUE9QM0ZvbGRlciBpcyBjYWxsZWQsCitzaG91bGQgdGhlIGNvbm5lY3Rpb24gdG8gdGhlIHNlcnZlciBiZSBjbG9zZWQgY2xlYW5seSwgYXMgaWYgdGhlCithcHBsaWNhdGlvbiBjYWxsZWQgdGhlIGNsb3NlIG1ldGhvZD8KK09yIHNob3VsZCB0aGUgY29ubmVjdGlvbiB0byB0aGUgc2VydmVyIGJlIGNsb3NlZCB3aXRob3V0IHNlbmRpbmcKK2FueSBjb21tYW5kcyB0byB0aGUgc2VydmVyPworRGVmYXVsdHMgdG8gZmFsc2UsIHRoZSBjb25uZWN0aW9uIGlzIG5vdCBjbG9zZWQgY2xlYW5seS4KKzwvVEQ+Cis8L1RSPgorCis8L1RBQkxFPgorPFA+CitJbiBnZW5lcmFsLCBhcHBsaWNhdGlvbnMgc2hvdWxkIG5vdCBuZWVkIHRvIHVzZSB0aGUgY2xhc3NlcyBpbiB0aGlzCitwYWNrYWdlIGRpcmVjdGx5LiAgSW5zdGVhZCwgdGhleSBzaG91bGQgdXNlIHRoZSBBUElzIGRlZmluZWQgYnkKKzxjb2RlPmphdmF4Lm1haWw8L2NvZGU+IHBhY2thZ2UgKGFuZCBzdWJwYWNrYWdlcykuICBBcHBsaWNhdGlvbnMgc2hvdWxkCituZXZlciBjb25zdHJ1Y3QgaW5zdGFuY2VzIG9mIDxjb2RlPlBPUDNTdG9yZTwvY29kZT4gb3IKKzxjb2RlPlBPUDNGb2xkZXI8L2NvZGU+IGRpcmVjdGx5LiAgSW5zdGVhZCwgdGhleSBzaG91bGQgdXNlIHRoZQorPGNvZGU+U2Vzc2lvbjwvY29kZT4gbWV0aG9kIDxjb2RlPmdldFN0b3JlPC9jb2RlPiB0byBhY3F1aXJlIGFuCithcHByb3ByaWF0ZSA8Y29kZT5TdG9yZTwvY29kZT4gb2JqZWN0LCBhbmQgZnJvbSB0aGF0IGFjcXVpcmUKKzxjb2RlPkZvbGRlcjwvY29kZT4gb2JqZWN0cy4KKzwvUD4KKzxQPgorSW4gYWRkaXRpb24gdG8gcHJpbnRpbmcgZGVidWdnaW5nIG91dHB1dCBhcyBjb250cm9sbGVkIGJ5IHRoZQore0BsaW5rIGphdmF4Lm1haWwuU2Vzc2lvbiBTZXNzaW9ufSBjb25maWd1cmF0aW9uLAordGhlIGNvbS5zdW4ubWFpbC5wb3AzIHByb3ZpZGVyIGxvZ3MgdGhlIHNhbWUgaW5mb3JtYXRpb24gdXNpbmcKK3tAbGluayBqYXZhLnV0aWwubG9nZ2luZy5Mb2dnZXJ9IGFzIGRlc2NyaWJlZCBpbiB0aGUgZm9sbG93aW5nIHRhYmxlOgorPC9QPgorPFRBQkxFIEJPUkRFUiBTVU1NQVJZPSJQT1AzIExvZ2dlcnMiPgorPFRSPgorPFRIPkxvZ2dlciBOYW1lPC9USD4KKzxUSD5Mb2dnaW5nIExldmVsPC9USD4KKzxUSD5QdXJwb3NlPC9USD4KKzwvVFI+CisKKzxUUj4KKzxURD5jb20uc3VuLm1haWwucG9wMzwvVEQ+Cis8VEQ+Q09ORklHPC9URD4KKzxURD5Db25maWd1cmF0aW9uIG9mIHRoZSBQT1AzU3RvcmU8L1REPgorPC9UUj4KKworPFRSPgorPFREPmNvbS5zdW4ubWFpbC5wb3AzPC9URD4KKzxURD5GSU5FPC9URD4KKzxURD5HZW5lcmFsIGRlYnVnZ2luZyBvdXRwdXQ8L1REPgorPC9UUj4KKworPFRSPgorPFREPmNvbS5zdW4ubWFpbC5wb3AzLnByb3RvY29sPC9URD4KKzxURD5GSU5FU1Q8L1REPgorPFREPkNvbXBsZXRlIHByb3RvY29sIHRyYWNlPC9URD4KKzwvVFI+Cis8L1RBQkxFPgorCis8UD4KKzxzdHJvbmc+V0FSTklORzo8L3N0cm9uZz4gVGhlIEFQSXMgdW5pcXVlIHRvIHRoaXMgcGFja2FnZSBzaG91bGQgYmUKK2NvbnNpZGVyZWQgPHN0cm9uZz5FWFBFUklNRU5UQUw8L3N0cm9uZz4uICBUaGV5IG1heSBiZSBjaGFuZ2VkIGluIHRoZQorZnV0dXJlIGluIHdheXMgdGhhdCBhcmUgaW5jb21wYXRpYmxlIHdpdGggYXBwbGljYXRpb25zIHVzaW5nIHRoZQorY3VycmVudCBBUElzLgorPC9QPgorCis8L0JPRFk+Cis8L0hUTUw+CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3NtdHAvRGlnZXN0TUQ1LmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3NtdHAvRGlnZXN0TUQ1LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDAxODM0YQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvc210cC9EaWdlc3RNRDUuamF2YQpAQCAtMCwwICsxLDIzMSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuc210cDsKKworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBqYXZhLnV0aWwubG9nZ2luZy5MZXZlbDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lio7CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5TdGFuZGFyZENoYXJzZXRzOworCitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuTWFpbExvZ2dlcjsKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5BU0NJSVV0aWxpdHk7CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuQkFTRTY0RW5jb2RlclN0cmVhbTsKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5CQVNFNjREZWNvZGVyU3RyZWFtOworCisvKioKKyAqIERJR0VTVC1NRDUgYXV0aGVudGljYXRpb24gc3VwcG9ydC4KKyAqCisgKiBAYXV0aG9yIERlYW4gR2lic29uCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCisKK3B1YmxpYyBjbGFzcyBEaWdlc3RNRDUgeworCisgICAgcHJpdmF0ZSBNYWlsTG9nZ2VyIGxvZ2dlcjsKKyAgICBwcml2YXRlIE1lc3NhZ2VEaWdlc3QgbWQ1OworICAgIHByaXZhdGUgU3RyaW5nIHVyaTsKKyAgICBwcml2YXRlIFN0cmluZyBjbGllbnRSZXNwb25zZTsKKworICAgIHB1YmxpYyBEaWdlc3RNRDUoTWFpbExvZ2dlciBsb2dnZXIpIHsKKwl0aGlzLmxvZ2dlciA9IGxvZ2dlci5nZXRMb2dnZXIodGhpcy5nZXRDbGFzcygpLCAiREVCVUcgRElHRVNULU1ENSIpOworCWxvZ2dlci5jb25maWcoIkRJR0VTVC1NRDUgTG9hZGVkIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIGNsaWVudCdzIGF1dGhlbnRpY2F0aW9uIHJlc3BvbnNlIHRvIHNlcnZlcidzIGNoYWxsZW5nZS4KKyAgICAgKgorICAgICAqIEBwYXJhbQlob3N0CXRoZSBob3N0IG5hbWUKKyAgICAgKiBAcGFyYW0JdXNlcgl0aGUgdXNlciBuYW1lCisgICAgICogQHBhcmFtCXBhc3N3ZAl0aGUgdXNlcidzIHBhc3N3b3JkCisgICAgICogQHBhcmFtCXJlYWxtCXRoZSBzZWN1cml0eSByZWFsbQorICAgICAqIEBwYXJhbQlzZXJ2ZXJDaGFsbGVuZ2UJdGhlIGNoYWxsZW5nZSBmcm9tIHRoZSBzZXJ2ZXIKKyAgICAgKiBAcmV0dXJuIGJ5dGUgYXJyYXkgd2l0aCBjbGllbnQncyByZXNwb25zZQorICAgICAqIEBleGNlcHRpb24JSU9FeGNlcHRpb24JZm9yIEkvTyBlcnJvcnMKKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZVtdIGF1dGhDbGllbnQoU3RyaW5nIGhvc3QsIFN0cmluZyB1c2VyLCBTdHJpbmcgcGFzc3dkLAorCQkJCVN0cmluZyByZWFsbSwgU3RyaW5nIHNlcnZlckNoYWxsZW5nZSkKKwkJCQl0aHJvd3MgSU9FeGNlcHRpb24geworCUJ5dGVBcnJheU91dHB1dFN0cmVhbSBib3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisJT3V0cHV0U3RyZWFtIGI2NG9zID0gbmV3IEJBU0U2NEVuY29kZXJTdHJlYW0oYm9zLCBJbnRlZ2VyLk1BWF9WQUxVRSk7CisJU2VjdXJlUmFuZG9tIHJhbmRvbTsKKwl0cnkgeworCSAgICAvL3JhbmRvbSA9IFNlY3VyZVJhbmRvbS5nZXRJbnN0YW5jZSgiU0hBMVBSTkciKTsKKwkgICAgcmFuZG9tID0gbmV3IFNlY3VyZVJhbmRvbSgpOworCSAgICBtZDUgPSBNZXNzYWdlRGlnZXN0LmdldEluc3RhbmNlKCJNRDUiKTsKKwl9IGNhdGNoIChOb1N1Y2hBbGdvcml0aG1FeGNlcHRpb24gZXgpIHsKKwkgICAgbG9nZ2VyLmxvZyhMZXZlbC5GSU5FLCAiTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIiwgZXgpOworCSAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oZXgudG9TdHJpbmcoKSk7CisJfQorCVN0cmluZ0J1aWxkZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKworCXVyaSA9ICJzbXRwLyIgKyBob3N0OworCVN0cmluZyBuYyA9ICIwMDAwMDAwMSI7CisJU3RyaW5nIHFvcCA9ICJhdXRoIjsKKwlieXRlW10gYnl0ZXMgPSBuZXcgYnl0ZVszMl07CS8vIGFyYml0cmFyeSBzaXplIC4uLgorCWludCByZXNwOworCisJbG9nZ2VyLmZpbmUoIkJlZ2luIGF1dGhlbnRpY2F0aW9uIC4uLiIpOworCisJLy8gQ29kZSBiYXNlZCBvbiBodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyODMxLnR4dAorCU1hcDxTdHJpbmcsIFN0cmluZz4gbWFwID0gdG9rZW5pemUoc2VydmVyQ2hhbGxlbmdlKTsKKworCWlmIChyZWFsbSA9PSBudWxsKSB7CisJICAgIFN0cmluZyB0ZXh0ID0gbWFwLmdldCgicmVhbG0iKTsKKwkgICAgcmVhbG0gPSB0ZXh0ICE9IG51bGwgPyBuZXcgU3RyaW5nVG9rZW5pemVyKHRleHQsICIsIikubmV4dFRva2VuKCkKKwkJCQkgOiBob3N0OworCX0KKworCS8vIHNlcnZlciBjaGFsbGVuZ2UgcmFuZG9tIHZhbHVlCisJU3RyaW5nIG5vbmNlID0gbWFwLmdldCgibm9uY2UiKTsKKworCS8vIERvZXMgc2VydmVyIHN1cHBvcnQgVVRGLTggdXNlcm5hbWVzIGFuZCBwYXNzd29yZHM/CisJU3RyaW5nIGNoYXJzZXQgPSBtYXAuZ2V0KCJjaGFyc2V0Iik7CisJYm9vbGVhbiB1dGY4ID0gY2hhcnNldCAhPSBudWxsICYmIGNoYXJzZXQuZXF1YWxzSWdub3JlQ2FzZSgidXRmLTgiKTsKKworCXJhbmRvbS5uZXh0Qnl0ZXMoYnl0ZXMpOworCWI2NG9zLndyaXRlKGJ5dGVzKTsKKwliNjRvcy5mbHVzaCgpOworCisJLy8gY2xpZW50IGNoYWxsZW5nZSByYW5kb20gdmFsdWUKKwlTdHJpbmcgY25vbmNlID0gYm9zLnRvU3RyaW5nKCJpc28tODg1OS0xIik7CS8vIHJlYWxseSBBU0NJST8KKwlib3MucmVzZXQoKTsKKworCS8vIERJR0VTVC1NRDUgY29tcHV0YXRpb24sIGNvbW1vbiBwb3J0aW9uIChvcmRlciBjcml0aWNhbCkKKwlpZiAodXRmOCkgeworCSAgICBTdHJpbmcgdXAgPSB1c2VyICsgIjoiICsgcmVhbG0gKyAiOiIgKyBwYXNzd2Q7CisJICAgIG1kNS51cGRhdGUobWQ1LmRpZ2VzdCh1cC5nZXRCeXRlcyhTdGFuZGFyZENoYXJzZXRzLlVURl84KSkpOworCX0gZWxzZQorCSAgICBtZDUudXBkYXRlKG1kNS5kaWdlc3QoCisJCUFTQ0lJVXRpbGl0eS5nZXRCeXRlcyh1c2VyICsgIjoiICsgcmVhbG0gKyAiOiIgKyBwYXNzd2QpKSk7CisJbWQ1LnVwZGF0ZShBU0NJSVV0aWxpdHkuZ2V0Qnl0ZXMoIjoiICsgbm9uY2UgKyAiOiIgKyBjbm9uY2UpKTsKKwljbGllbnRSZXNwb25zZSA9IHRvSGV4KG1kNS5kaWdlc3QoKSkKKwkJKyAiOiIgKyBub25jZSAgKyAiOiIgKyBuYyArICI6IiArIGNub25jZSArICI6IiArIHFvcCArICI6IjsKKwkKKwkvLyBESUdFU1QtTUQ1IGNvbXB1dGF0aW9uLCBjbGllbnQgcmVzcG9uc2UgKG9yZGVyIGNyaXRpY2FsKQorCW1kNS51cGRhdGUoQVNDSUlVdGlsaXR5LmdldEJ5dGVzKCJBVVRIRU5USUNBVEU6IiArIHVyaSkpOworCW1kNS51cGRhdGUoQVNDSUlVdGlsaXR5LmdldEJ5dGVzKGNsaWVudFJlc3BvbnNlICsgdG9IZXgobWQ1LmRpZ2VzdCgpKSkpOworCisJLy8gYnVpbGQgcmVzcG9uc2UgdGV4dCAob3JkZXIgbm90IGNyaXRpY2FsKQorCXJlc3VsdC5hcHBlbmQoInVzZXJuYW1lPVwiIiArIHVzZXIgKyAiXCIiKTsKKwlyZXN1bHQuYXBwZW5kKCIscmVhbG09XCIiICsgcmVhbG0gKyAiXCIiKTsKKwlyZXN1bHQuYXBwZW5kKCIscW9wPSIgKyBxb3ApOworCXJlc3VsdC5hcHBlbmQoIixuYz0iICsgbmMpOworCXJlc3VsdC5hcHBlbmQoIixub25jZT1cIiIgKyBub25jZSArICJcIiIpOworCXJlc3VsdC5hcHBlbmQoIixjbm9uY2U9XCIiICsgY25vbmNlICsgIlwiIik7CisJcmVzdWx0LmFwcGVuZCgiLGRpZ2VzdC11cmk9XCIiICsgdXJpICsgIlwiIik7CisJaWYgKHV0ZjgpCisJICAgIHJlc3VsdC5hcHBlbmQoIixjaGFyc2V0PVwidXRmLThcIiIpOworCXJlc3VsdC5hcHBlbmQoIixyZXNwb25zZT0iICsgdG9IZXgobWQ1LmRpZ2VzdCgpKSk7CisKKwlpZiAobG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuRklORSkpCisJICAgIGxvZ2dlci5maW5lKCJSZXNwb25zZSA9PiAiICsgcmVzdWx0LnRvU3RyaW5nKCkpOworCWI2NG9zLndyaXRlKEFTQ0lJVXRpbGl0eS5nZXRCeXRlcyhyZXN1bHQudG9TdHJpbmcoKSkpOworCWI2NG9zLmZsdXNoKCk7CisJcmV0dXJuIGJvcy50b0J5dGVBcnJheSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFsbG93IHRoZSBjbGllbnQgdG8gYXV0aGVudGljYXRlIHRoZSBzZXJ2ZXIgYmFzZWQgb24gaXRzCisgICAgICogcmVzcG9uc2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jc2VydmVyUmVzcG9uc2UJdGhlIHJlc3BvbnNlIHRoYXQgd2FzIHJlY2VpdmVkIGZyb20gdGhlIHNlcnZlcgorICAgICAqIEByZXR1cm4JdHJ1ZSBpZiBzZXJ2ZXIgaXMgYXV0aGVudGljYXRlZAorICAgICAqIEBleGNlcHRpb24JSU9FeGNlcHRpb24JZm9yIGNoYXJhY3RlciBjb252ZXJzaW9uIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gYXV0aFNlcnZlcihTdHJpbmcgc2VydmVyUmVzcG9uc2UpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJTWFwPFN0cmluZywgU3RyaW5nPiBtYXAgPSB0b2tlbml6ZShzZXJ2ZXJSZXNwb25zZSk7CisJLy8gRElHRVNULU1ENSBjb21wdXRhdGlvbiwgc2VydmVyIHJlc3BvbnNlIChvcmRlciBjcml0aWNhbCkKKwltZDUudXBkYXRlKEFTQ0lJVXRpbGl0eS5nZXRCeXRlcygiOiIgKyB1cmkpKTsKKwltZDUudXBkYXRlKEFTQ0lJVXRpbGl0eS5nZXRCeXRlcyhjbGllbnRSZXNwb25zZSArIHRvSGV4KG1kNS5kaWdlc3QoKSkpKTsKKwlTdHJpbmcgdGV4dCA9IHRvSGV4KG1kNS5kaWdlc3QoKSk7CisJaWYgKCF0ZXh0LmVxdWFscyhtYXAuZ2V0KCJyc3BhdXRoIikpKSB7CisJICAgIGlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FKSkKKwkJbG9nZ2VyLmZpbmUoIkV4cGVjdGVkID0+IHJzcGF1dGg9IiArIHRleHQpOworCSAgICByZXR1cm4gZmFsc2U7CS8vIHNlcnZlciBOT1QgYXV0aGVudGljYXRlZCBieSBjbGllbnQgISEhCisJfQorCXJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRva2VuaXplIGEgcmVzcG9uc2UgZnJvbSB0aGUgc2VydmVyLgorICAgICAqCisgICAgICogQHJldHVybglNYXAgY29udGFpbmluZyBrZXkvdmFsdWUgcGFpcnMgZnJvbSBzZXJ2ZXIKKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiZmFsbHRocm91Z2giKQorICAgIHByaXZhdGUgTWFwPFN0cmluZywgU3RyaW5nPiB0b2tlbml6ZShTdHJpbmcgc2VydmVyUmVzcG9uc2UpCisJICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJTWFwPFN0cmluZywgU3RyaW5nPiBtYXAJPSBuZXcgSGFzaE1hcDw+KCk7CisJYnl0ZVtdIGJ5dGVzID0gc2VydmVyUmVzcG9uc2UuZ2V0Qnl0ZXMoImlzby04ODU5LTEiKTsJLy8gcmVhbGx5IEFTQ0lJPworCVN0cmluZyBrZXkgPSBudWxsOworCWludCB0dHlwZTsKKwlTdHJlYW1Ub2tlbml6ZXIJdG9rZW5zCisJCT0gbmV3IFN0cmVhbVRva2VuaXplcigKKwkJICAgIG5ldyBJbnB1dFN0cmVhbVJlYWRlcigKKwkJICAgICAgbmV3IEJBU0U2NERlY29kZXJTdHJlYW0oCisJCQluZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYnl0ZXMsIDQsIGJ5dGVzLmxlbmd0aCAtIDQpCisJCSAgICAgICksICJpc28tODg1OS0xIgkvLyByZWFsbHkgQVNDSUk/CisJCSAgICApCisJCSAgKTsKKworCXRva2Vucy5vcmRpbmFyeUNoYXJzKCcwJywgJzknKTsJLy8gcmVzZXQgZGlnaXRzCisJdG9rZW5zLndvcmRDaGFycygnMCcsICc5Jyk7CS8vIGRpZ2l0cyBtYXkgc3RhcnQgd29yZHMKKwl3aGlsZSAoKHR0eXBlID0gdG9rZW5zLm5leHRUb2tlbigpKSAhPSBTdHJlYW1Ub2tlbml6ZXIuVFRfRU9GKSB7CisJICAgIHN3aXRjaCAodHR5cGUpIHsKKwkgICAgY2FzZSBTdHJlYW1Ub2tlbml6ZXIuVFRfV09SRDoKKwkJaWYgKGtleSA9PSBudWxsKSB7CisJCSAgICBrZXkgPSB0b2tlbnMuc3ZhbDsKKwkJICAgIGJyZWFrOworCQl9CisJCS8vIGZhbGwtdGhydQorCSAgICBjYXNlICciJzoKKwkJaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkUpKQorCQkgICAgbG9nZ2VyLmZpbmUoIlJlY2VpdmVkID0+ICIgKworCQkJIAkga2V5ICsgIj0nIiArIHRva2Vucy5zdmFsICsgIiciKTsKKwkJaWYgKG1hcC5jb250YWluc0tleShrZXkpKSB7ICAvLyBjb25jYXRlbmF0ZSBtdWx0aXBsZSB2YWx1ZXMKKwkJICAgIG1hcC5wdXQoa2V5LCBtYXAuZ2V0KGtleSkgKyAiLCIgKyB0b2tlbnMuc3ZhbCk7CisJCX0gZWxzZSB7CisJCSAgICBtYXAucHV0KGtleSwgdG9rZW5zLnN2YWwpOworCQl9CisJCWtleSA9IG51bGw7CisJCWJyZWFrOworCSAgICBkZWZhdWx0OgkvLyBYWFggLSBzaG91bGQgbmV2ZXIgaGFwcGVuPworCQlicmVhazsKKwkgICAgfQorCX0KKwlyZXR1cm4gbWFwOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGNoYXJbXSBkaWdpdHMgPSB7CisJJzAnLCAnMScsICcyJywgJzMnLCAnNCcsICc1JywgJzYnLCAnNycsCisJJzgnLCAnOScsICdhJywgJ2InLCAnYycsICdkJywgJ2UnLCAnZicKKyAgICB9OworCisgICAgLyoqCisgICAgICogQ29udmVydCBhIGJ5dGUgYXJyYXkgdG8gYSBzdHJpbmcgb2YgaGV4IGRpZ2l0cyByZXByZXNlbnRpbmcgdGhlIGJ5dGVzLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyB0b0hleChieXRlW10gYnl0ZXMpIHsKKwljaGFyW10gcmVzdWx0ID0gbmV3IGNoYXJbYnl0ZXMubGVuZ3RoICogMl07CisKKwlmb3IgKGludCBpbmRleCA9IDAsIGkgPSAwOyBpbmRleCA8IGJ5dGVzLmxlbmd0aDsgaW5kZXgrKykgeworCSAgICBpbnQgdGVtcCA9IGJ5dGVzW2luZGV4XSAmIDB4RkY7CisJICAgIHJlc3VsdFtpKytdID0gZGlnaXRzW3RlbXAgPj4gNF07CisJICAgIHJlc3VsdFtpKytdID0gZGlnaXRzW3RlbXAgJiAweEZdOworCX0KKwlyZXR1cm4gbmV3IFN0cmluZyhyZXN1bHQpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvc210cC9TTVRQQWRkcmVzc0ZhaWxlZEV4Y2VwdGlvbi5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9zbXRwL1NNVFBBZGRyZXNzRmFpbGVkRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjM0ODIwZQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvc210cC9TTVRQQWRkcmVzc0ZhaWxlZEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsODcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLnNtdHA7CisKK2ltcG9ydCBqYXZheC5tYWlsLlNlbmRGYWlsZWRFeGNlcHRpb247CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC5JbnRlcm5ldEFkZHJlc3M7CisKKy8qKgorICogVGhpcyBleGNlcHRpb24gaXMgdGhyb3duIHdoZW4gdGhlIG1lc3NhZ2UgY2Fubm90IGJlIHNlbnQuIDxwPgorICogCisgKiBUaGUgZXhjZXB0aW9uIGluY2x1ZGVzIHRoZSBhZGRyZXNzIHRvIHdoaWNoIHRoZSBtZXNzYWdlIGNvdWxkIG5vdCBiZQorICogc2VudC4gIFRoaXMgd2lsbCB1c3VhbGx5IGFwcGVhciBpbiBhIGNoYWluZWQgbGlzdCBvZiBleGNlcHRpb25zLAorICogb25lIHBlciBhZGRyZXNzLCBhdHRhY2hlZCB0byBhIHRvcCBsZXZlbCBTZW5kRmFpbGVkRXhjZXB0aW9uIHRoYXQKKyAqIGFnZ3JlZ2F0ZXMgYWxsIHRoZSBhZGRyZXNzZXMuCisgKgorICogQHNpbmNlIEphdmFNYWlsIDEuMy4yCisgKi8KKworcHVibGljIGNsYXNzIFNNVFBBZGRyZXNzRmFpbGVkRXhjZXB0aW9uIGV4dGVuZHMgU2VuZEZhaWxlZEV4Y2VwdGlvbiB7CisgICAgcHJvdGVjdGVkIEludGVybmV0QWRkcmVzcyBhZGRyOwkvLyBhZGRyZXNzIHRoYXQgZmFpbGVkCisgICAgcHJvdGVjdGVkIFN0cmluZyBjbWQ7CQkvLyBjb21tYW5kIGlzc3VlZCB0byBzZXJ2ZXIKKyAgICBwcm90ZWN0ZWQgaW50IHJjOwkJCS8vIHJldHVybiBjb2RlIGZyb20gU01UUCBzZXJ2ZXIKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDgwNDgzMTE5OTc2ODYzMDA5N0w7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGFuIFNNVFBBZGRyZXNzRmFpbGVkRXhjZXB0aW9uIHdpdGggdGhlIHNwZWNpZmllZCAKKyAgICAgKiBhZGRyZXNzLCByZXR1cm4gY29kZSwgYW5kIGVycm9yIHN0cmluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhZGRyCXRoZSBhZGRyZXNzIHRoYXQgZmFpbGVkCisgICAgICogQHBhcmFtIGNtZAl0aGUgY29tbWFuZCB0aGF0IHdhcyBzZW50IHRvIHRoZSBTTVRQIHNlcnZlcgorICAgICAqIEBwYXJhbSByYwl0aGUgU01UUCByZXR1cm4gY29kZSBpbmRpY2F0aW5nIHRoZSBmYWlsdXJlCisgICAgICogQHBhcmFtIGVycgl0aGUgZXJyb3Igc3RyaW5nIGZyb20gdGhlIFNNVFAgc2VydmVyCisgICAgICovCisgICAgcHVibGljIFNNVFBBZGRyZXNzRmFpbGVkRXhjZXB0aW9uKEludGVybmV0QWRkcmVzcyBhZGRyLCBTdHJpbmcgY21kLCBpbnQgcmMsCisJCQkJU3RyaW5nIGVycikgeworCXN1cGVyKGVycik7CisJdGhpcy5hZGRyID0gYWRkcjsKKwl0aGlzLmNtZCA9IGNtZDsKKwl0aGlzLnJjID0gcmM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBhZGRyZXNzIHRoYXQgZmFpbGVkLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgYWRkcmVzcworICAgICAqLworICAgIHB1YmxpYyBJbnRlcm5ldEFkZHJlc3MgZ2V0QWRkcmVzcygpIHsKKwlyZXR1cm4gYWRkcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIGNvbW1hbmQgdGhhdCBmYWlsZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBjb21tYW5kCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRDb21tYW5kKCkgeworCXJldHVybiBjbWQ7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIHJldHVybiBjb2RlIGZyb20gdGhlIFNNVFAgc2VydmVyIHRoYXQgaW5kaWNhdGVzIHRoZQorICAgICAqIHJlYXNvbiBmb3IgdGhlIGZhaWx1cmUuICBTZWUKKyAgICAgKiA8QSBIUkVGPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmM4MjEudHh0Ij5SRkMgODIxPC9BPgorICAgICAqIGZvciBpbnRlcnByZXRhdGlvbiBvZiB0aGUgcmV0dXJuIGNvZGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSByZXR1cm4gY29kZQorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0UmV0dXJuQ29kZSgpIHsKKwlyZXR1cm4gcmM7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9zbXRwL1NNVFBBZGRyZXNzU3VjY2VlZGVkRXhjZXB0aW9uLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3NtdHAvU01UUEFkZHJlc3NTdWNjZWVkZWRFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZGRiMjlhCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9zbXRwL1NNVFBBZGRyZXNzU3VjY2VlZGVkRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw4NiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuc210cDsKKworaW1wb3J0IGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuSW50ZXJuZXRBZGRyZXNzOworCisvKioKKyAqIFRoaXMgZXhjZXB0aW9uIGlzIGNoYWluZWQgb2ZmIGEgU2VuZEZhaWxlZEV4Y2VwdGlvbiB3aGVuIHRoZQorICogPGNvZGU+bWFpbC5zbXRwLnJlcG9ydHN1Y2Nlc3M8L2NvZGU+IHByb3BlcnR5IGlzIHRydWUuICBJdAorICogaW5kaWNhdGVzIGFuIGFkZHJlc3MgdG8gd2hpY2ggdGhlIG1lc3NhZ2Ugd2FzIHNlbnQuICBUaGUgY29tbWFuZAorICogd2lsbCBiZSBhbiBTTVRQIFJDUFQgY29tbWFuZCBhbmQgdGhlIHJldHVybiBjb2RlIHdpbGwgYmUgdGhlCisgKiByZXR1cm4gY29kZSBmcm9tIHRoYXQgY29tbWFuZC4KKyAqCisgKiBAc2luY2UgSmF2YU1haWwgMS4zLjIKKyAqLworCitwdWJsaWMgY2xhc3MgU01UUEFkZHJlc3NTdWNjZWVkZWRFeGNlcHRpb24gZXh0ZW5kcyBNZXNzYWdpbmdFeGNlcHRpb24geworICAgIHByb3RlY3RlZCBJbnRlcm5ldEFkZHJlc3MgYWRkcjsJLy8gYWRkcmVzcyB0aGF0IHN1Y2NlZWRlZAorICAgIHByb3RlY3RlZCBTdHJpbmcgY21kOwkJLy8gY29tbWFuZCBpc3N1ZWQgdG8gc2VydmVyCisgICAgcHJvdGVjdGVkIGludCByYzsJCQkvLyByZXR1cm4gY29kZSBmcm9tIFNNVFAgc2VydmVyCisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMTE2ODMzNTg0ODYyMzA5Njc0OUw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGFuIFNNVFBBZGRyZXNzU3VjY2VlZGVkRXhjZXB0aW9uIHdpdGggdGhlIHNwZWNpZmllZCAKKyAgICAgKiBhZGRyZXNzLCByZXR1cm4gY29kZSwgYW5kIGVycm9yIHN0cmluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhZGRyCXRoZSBhZGRyZXNzIHRoYXQgc3VjY2VlZGVkCisgICAgICogQHBhcmFtIGNtZAl0aGUgY29tbWFuZCB0aGF0IHdhcyBzZW50IHRvIHRoZSBTTVRQIHNlcnZlcgorICAgICAqIEBwYXJhbSByYwl0aGUgU01UUCByZXR1cm4gY29kZSBpbmRpY2F0aW5nIHRoZSBzdWNjZXNzCisgICAgICogQHBhcmFtIGVycgl0aGUgZXJyb3Igc3RyaW5nIGZyb20gdGhlIFNNVFAgc2VydmVyCisgICAgICovCisgICAgcHVibGljIFNNVFBBZGRyZXNzU3VjY2VlZGVkRXhjZXB0aW9uKEludGVybmV0QWRkcmVzcyBhZGRyLAorCQkJCVN0cmluZyBjbWQsIGludCByYywgU3RyaW5nIGVycikgeworCXN1cGVyKGVycik7CisJdGhpcy5hZGRyID0gYWRkcjsKKwl0aGlzLmNtZCA9IGNtZDsKKwl0aGlzLnJjID0gcmM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBhZGRyZXNzIHRoYXQgc3VjY2VlZGVkLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgYWRkcmVzcworICAgICAqLworICAgIHB1YmxpYyBJbnRlcm5ldEFkZHJlc3MgZ2V0QWRkcmVzcygpIHsKKwlyZXR1cm4gYWRkcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIGNvbW1hbmQgdGhhdCBzdWNjZWVkZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBjb21tYW5kCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRDb21tYW5kKCkgeworCXJldHVybiBjbWQ7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIHJldHVybiBjb2RlIGZyb20gdGhlIFNNVFAgc2VydmVyIHRoYXQgaW5kaWNhdGVzIHRoZQorICAgICAqIHJlYXNvbiBmb3IgdGhlIHN1Y2Nlc3MuICBTZWUKKyAgICAgKiA8QSBIUkVGPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmM4MjEudHh0Ij5SRkMgODIxPC9BPgorICAgICAqIGZvciBpbnRlcnByZXRhdGlvbiBvZiB0aGUgcmV0dXJuIGNvZGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSByZXR1cm4gY29kZQorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0UmV0dXJuQ29kZSgpIHsKKwlyZXR1cm4gcmM7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9zbXRwL1NNVFBNZXNzYWdlLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3NtdHAvU01UUE1lc3NhZ2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MjZlYTQ0Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9zbXRwL1NNVFBNZXNzYWdlLmphdmEKQEAgLTAsMCArMSwzMjEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLnNtdHA7CisKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YXgubWFpbC4qOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuKjsKKworLyoqCisgKiBUaGlzIGNsYXNzIGlzIGEgc3BlY2lhbGl6YXRpb24gb2YgdGhlIE1pbWVNZXNzYWdlIGNsYXNzIHRoYXQgYWxsb3dzCisgKiB5b3UgdG8gc3BlY2lmeSB2YXJpb3VzIFNNVFAgb3B0aW9ucyBhbmQgcGFyYW1ldGVycyB0aGF0IHdpbGwgYmUKKyAqIHVzZWQgd2hlbiB0aGlzIG1lc3NhZ2UgaXMgc2VudCBvdmVyIFNNVFAuICBTaW1wbHkgdXNlIHRoaXMgY2xhc3MKKyAqIGluc3RlYWQgb2YgTWltZU1lc3NhZ2UgYW5kIHNldCBTTVRQIG9wdGlvbnMgdXNpbmcgdGhlIG1ldGhvZHMgb24KKyAqIHRoaXMgY2xhc3MuIDxwPgorICoKKyAqIFNlZSB0aGUgPGEgaHJlZj0icGFja2FnZS1zdW1tYXJ5Lmh0bWwiPmNvbS5zdW4ubWFpbC5zbXRwPC9hPiBwYWNrYWdlCisgKiBkb2N1bWVudGF0aW9uIGZvciBmdXJ0aGVyIGluZm9ybWF0aW9uIG9uIHRoZSBTTVRQIHByb3RvY29sIHByb3ZpZGVyLiA8cD4KKyAqCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICogQHNlZQlqYXZheC5tYWlsLmludGVybmV0Lk1pbWVNZXNzYWdlCisgKi8KKworcHVibGljIGNsYXNzIFNNVFBNZXNzYWdlIGV4dGVuZHMgTWltZU1lc3NhZ2UgeworCisgICAgLyoqIE5ldmVyIG5vdGlmeSBvZiBkZWxpdmVyeSBzdGF0dXMgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOT1RJRllfTkVWRVIgPSAtMTsKKyAgICAvKiogTm90aWZ5IG9mIGRlbGl2ZXJ5IHN1Y2Nlc3MgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOT1RJRllfU1VDQ0VTUyA9IDE7CisgICAgLyoqIE5vdGlmeSBvZiBkZWxpdmVyeSBmYWlsdXJlICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTk9USUZZX0ZBSUxVUkUgPSAyOworICAgIC8qKiBOb3RpZnkgb2YgZGVsaXZlcnkgZGVsYXkgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOT1RJRllfREVMQVkgPSA0OworCisgICAgLyoqIFJldHVybiBmdWxsIG1lc3NhZ2Ugd2l0aCBkZWxpdmVyeSBzdGF0dXMgbm90aWZpY2F0aW9uICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVUVVJOX0ZVTEwgPSAxOworICAgIC8qKiBSZXR1cm4gb25seSBtZXNzYWdlIGhlYWRlcnMgd2l0aCBkZWxpdmVyeSBzdGF0dXMgbm90aWZpY2F0aW9uICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVUVVJOX0hEUlMgPSAyOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nW10gcmV0dXJuT3B0aW9uU3RyaW5nID0geyBudWxsLCAiRlVMTCIsICJIRFJTIiB9OworCisgICAgcHJpdmF0ZSBTdHJpbmcgZW52ZWxvcGVGcm9tOyAvLyB0aGUgc3RyaW5nIHRvIHVzZSBpbiB0aGUgTUFJTCBGUk9NOiBjb21tYW5kCisgICAgcHJpdmF0ZSBpbnQgbm90aWZ5T3B0aW9ucyA9IDA7CisgICAgcHJpdmF0ZSBpbnQgcmV0dXJuT3B0aW9uID0gMDsKKyAgICBwcml2YXRlIGJvb2xlYW4gc2VuZFBhcnRpYWwgPSBmYWxzZTsKKyAgICBwcml2YXRlIGJvb2xlYW4gYWxsb3c4Yml0TUlNRSA9IGZhbHNlOworICAgIHByaXZhdGUgU3RyaW5nIHN1Ym1pdHRlciA9IG51bGw7CS8vIFJGQyAyNTU0IEFVVEg9c3VibWl0dGVyCisgICAgcHJpdmF0ZSBTdHJpbmcgZXh0ZW5zaW9uID0gbnVsbDsJLy8gZXh0ZW5zaW9ucyB0byB1c2Ugd2l0aCBNQUlMIGNvbW1hbmQKKworICAgIC8qKgorICAgICAqIERlZmF1bHQgY29uc3RydWN0b3IuIEFuIGVtcHR5IG1lc3NhZ2Ugb2JqZWN0IGlzIGNyZWF0ZWQuCisgICAgICogVGhlIDxjb2RlPmhlYWRlcnM8L2NvZGU+IGZpZWxkIGlzIHNldCB0byBhbiBlbXB0eSBJbnRlcm5ldEhlYWRlcnMKKyAgICAgKiBvYmplY3QuIFRoZSA8Y29kZT5mbGFnczwvY29kZT4gZmllbGQgaXMgc2V0IHRvIGFuIGVtcHR5IEZsYWdzCisgICAgICogb2JqZWN0LiBUaGUgPGNvZGU+bW9kaWZpZWQ8L2NvZGU+IGZsYWcgaXMgc2V0IHRvIHRydWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jc2Vzc2lvbgl0aGUgU2Vzc2lvbgorICAgICAqLworICAgIHB1YmxpYyBTTVRQTWVzc2FnZShTZXNzaW9uIHNlc3Npb24pIHsKKwlzdXBlcihzZXNzaW9uKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGFuIFNNVFBNZXNzYWdlIGJ5IHJlYWRpbmcgYW5kIHBhcnNpbmcgdGhlIGRhdGEgZnJvbSB0aGUKKyAgICAgKiBzcGVjaWZpZWQgTUlNRSBJbnB1dFN0cmVhbS4gVGhlIElucHV0U3RyZWFtIHdpbGwgYmUgbGVmdCBwb3NpdGlvbmVkCisgICAgICogYXQgdGhlIGVuZCBvZiB0aGUgZGF0YSBmb3IgdGhlIG1lc3NhZ2UuIE5vdGUgdGhhdCB0aGUgaW5wdXQgc3RyZWFtCisgICAgICogcGFyc2UgaXMgZG9uZSB3aXRoaW4gdGhpcyBjb25zdHJ1Y3RvciBpdHNlbGYuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc2Vzc2lvbglTZXNzaW9uIG9iamVjdCBmb3IgdGhpcyBtZXNzYWdlCisgICAgICogQHBhcmFtIGlzCXRoZSBtZXNzYWdlIGlucHV0IHN0cmVhbQorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBTTVRQTWVzc2FnZShTZXNzaW9uIHNlc3Npb24sIElucHV0U3RyZWFtIGlzKSAKKwkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXN1cGVyKHNlc3Npb24sIGlzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IFNNVFBNZXNzYWdlIHdpdGggY29udGVudCBpbml0aWFsaXplZCBmcm9tIHRoZQorICAgICAqIDxjb2RlPnNvdXJjZTwvY29kZT4gTWltZU1lc3NhZ2UuICBUaGUgbmV3IG1lc3NhZ2UgaXMgaW5kZXBlbmRlbnQKKyAgICAgKiBvZiB0aGUgb3JpZ2luYWwuIDxwPgorICAgICAqCisgICAgICogTm90ZTogVGhlIGN1cnJlbnQgaW1wbGVtZW50YXRpb24gaXMgcmF0aGVyIGluZWZmaWNpZW50LCBjb3B5aW5nCisgICAgICogdGhlIGRhdGEgbW9yZSB0aW1lcyB0aGFuIHN0cmljdGx5IG5lY2Vzc2FyeS4KKyAgICAgKgorICAgICAqIEBwYXJhbQlzb3VyY2UJdGhlIG1lc3NhZ2UgdG8gY29weSBjb250ZW50IGZyb20KKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgU01UUE1lc3NhZ2UoTWltZU1lc3NhZ2Ugc291cmNlKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlzdXBlcihzb3VyY2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgRnJvbSBhZGRyZXNzIHRvIGFwcGVhciBpbiB0aGUgU01UUCBlbnZlbG9wZS4gIE5vdGUgdGhhdCB0aGlzCisgICAgICogaXMgZGlmZmVyZW50IHRoYW4gdGhlIEZyb20gYWRkcmVzcyB0aGF0IGFwcGVhcnMgaW4gdGhlIG1lc3NhZ2UgaXRzZWxmLgorICAgICAqIFRoZSBlbnZlbG9wZSBGcm9tIGFkZHJlc3MgaXMgdHlwaWNhbGx5IHVzZWQgd2hlbiByZXBvcnRpbmcgZXJyb3JzLgorICAgICAqIFNlZSA8QSBIUkVGPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmM4MjEudHh0Ij5SRkMgODIxPC9BPiBmb3IKKyAgICAgKiBkZXRhaWxzLiA8cD4KKyAgICAgKgorICAgICAqIElmIHNldCwgb3ZlcnJpZGVzIHRoZSA8Y29kZT5tYWlsLnNtdHAuZnJvbTwvY29kZT4gcHJvcGVydHkuCisgICAgICoKKyAgICAgKiBAcGFyYW0JZnJvbQl0aGUgZW52ZWxvcGUgRnJvbSBhZGRyZXNzCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RW52ZWxvcGVGcm9tKFN0cmluZyBmcm9tKSB7CisJZW52ZWxvcGVGcm9tID0gZnJvbTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIGVudmVsb3BlIEZyb20gYWRkcmVzcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIGVudmVsb3BlIEZyb20gYWRkcmVzcywgb3IgbnVsbCBpZiBub3Qgc2V0CisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRFbnZlbG9wZUZyb20oKSB7CisJcmV0dXJuIGVudmVsb3BlRnJvbTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgbm90aWZpY2F0aW9uIG9wdGlvbnMgdG8gYmUgdXNlZCBpZiB0aGUgc2VydmVyIHN1cHBvcnRzCisgICAgICogRGVsaXZlcnkgU3RhdHVzIE5vdGlmaWNhdGlvbgorICAgICAqICg8QSBIUkVGPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMxODkxLnR4dCI+UkZDIDE4OTE8L0E+KS4KKyAgICAgKiBFaXRoZXIgPGNvZGU+Tk9USUZZX05FVkVSPC9jb2RlPiBvciBzb21lIGNvbWJpbmF0aW9uIG9mCisgICAgICogPGNvZGU+Tk9USUZZX1NVQ0NFU1M8L2NvZGU+LCA8Y29kZT5OT1RJRllfRkFJTFVSRTwvY29kZT4sIGFuZAorICAgICAqIDxjb2RlPk5PVElGWV9ERUxBWTwvY29kZT4uIDxwPgorICAgICAqCisgICAgICogSWYgc2V0LCBvdmVycmlkZXMgdGhlIDxjb2RlPm1haWwuc210cC5kc24ubm90aWZ5PC9jb2RlPiBwcm9wZXJ0eS4KKyAgICAgKgorICAgICAqIEBwYXJhbQlvcHRpb25zCW5vdGlmaWNhdGlvbiBvcHRpb25zCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Tm90aWZ5T3B0aW9ucyhpbnQgb3B0aW9ucykgeworCWlmIChvcHRpb25zIDwgLTEgfHwgb3B0aW9ucyA+PSA4KQorCSAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJCYWQgcmV0dXJuIG9wdGlvbiIpOworCW5vdGlmeU9wdGlvbnMgPSBvcHRpb25zOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCBub3RpZmljYXRpb24gb3B0aW9ucy4gIFJldHVybnMgemVybyBpZiBubyBvcHRpb25zIHNldC4KKyAgICAgKgorICAgICAqIEByZXR1cm4Jbm90aWZpY2F0aW9uIG9wdGlvbnMKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE5vdGlmeU9wdGlvbnMoKSB7CisJcmV0dXJuIG5vdGlmeU9wdGlvbnM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIG5vdGlmaWNhdGlvbiBvcHRpb25zIGFzIGFuIFJGQyAxODkxIHN0cmluZy4KKyAgICAgKiBSZXR1cm5zIG51bGwgaWYgbm8gb3B0aW9ucyBzZXQuCisgICAgICovCisgICAgU3RyaW5nIGdldERTTk5vdGlmeSgpIHsKKwlpZiAobm90aWZ5T3B0aW9ucyA9PSAwKQorCSAgICByZXR1cm4gbnVsbDsKKwlpZiAobm90aWZ5T3B0aW9ucyA9PSBOT1RJRllfTkVWRVIpCisJICAgIHJldHVybiAiTkVWRVIiOworCVN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworCWlmICgobm90aWZ5T3B0aW9ucyAmIE5PVElGWV9TVUNDRVNTKSAhPSAwKQorCSAgICBzYi5hcHBlbmQoIlNVQ0NFU1MiKTsKKwlpZiAoKG5vdGlmeU9wdGlvbnMgJiBOT1RJRllfRkFJTFVSRSkgIT0gMCkgeworCSAgICBpZiAoc2IubGVuZ3RoKCkgIT0gMCkKKwkJc2IuYXBwZW5kKCcsJyk7CisJICAgIHNiLmFwcGVuZCgiRkFJTFVSRSIpOworCX0KKwlpZiAoKG5vdGlmeU9wdGlvbnMgJiBOT1RJRllfREVMQVkpICE9IDApIHsKKwkgICAgaWYgKHNiLmxlbmd0aCgpICE9IDApCisJCXNiLmFwcGVuZCgnLCcpOworCSAgICBzYi5hcHBlbmQoIkRFTEFZIik7CisJfQorCXJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCByZXR1cm4gb3B0aW9uIHRvIGJlIHVzZWQgaWYgc2VydmVyIHN1cHBvcnRzCisgICAgICogRGVsaXZlcnkgU3RhdHVzIE5vdGlmaWNhdGlvbgorICAgICAqICg8QSBIUkVGPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMxODkxLnR4dCI+UkZDIDE4OTE8L0E+KS4KKyAgICAgKiBFaXRoZXIgPGNvZGU+UkVUVVJOX0ZVTEw8L2NvZGU+IG9yIDxjb2RlPlJFVFVSTl9IRFJTPC9jb2RlPi4gPHA+CisgICAgICoKKyAgICAgKiBJZiBzZXQsIG92ZXJyaWRlcyB0aGUgPGNvZGU+bWFpbC5zbXRwLmRzbi5yZXQ8L2NvZGU+IHByb3BlcnR5LgorICAgICAqCisgICAgICogQHBhcmFtCW9wdGlvbglyZXR1cm4gb3B0aW9uCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UmV0dXJuT3B0aW9uKGludCBvcHRpb24pIHsKKwlpZiAob3B0aW9uIDwgMCB8fCBvcHRpb24gPiBSRVRVUk5fSERSUykKKwkgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiQmFkIHJldHVybiBvcHRpb24iKTsKKwlyZXR1cm5PcHRpb24gPSBvcHRpb247CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHJldHVybiBvcHRpb24uICBSZXR1cm5zIHplcm8gaWYgbm8gb3B0aW9uIHNldC4KKyAgICAgKgorICAgICAqIEByZXR1cm4JcmV0dXJuIG9wdGlvbgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0UmV0dXJuT3B0aW9uKCkgeworCXJldHVybiByZXR1cm5PcHRpb247CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHJldHVybiBvcHRpb24gYXMgYW4gUkZDIDE4OTEgc3RyaW5nLgorICAgICAqIFJldHVybnMgbnVsbCBpZiBubyBvcHRpb24gc2V0LgorICAgICAqLworICAgIFN0cmluZyBnZXREU05SZXQoKSB7CisJcmV0dXJuIHJldHVybk9wdGlvblN0cmluZ1tyZXR1cm5PcHRpb25dOworICAgIH0KKworICAgIC8qKgorICAgICAqIElmIHNldCB0byB0cnVlLCBhbmQgdGhlIHNlcnZlciBzdXBwb3J0cyB0aGUgOEJJVE1JTUUgZXh0ZW5zaW9uLCB0ZXh0CisgICAgICogcGFydHMgb2YgdGhpcyBtZXNzYWdlIHRoYXQgdXNlIHRoZSAicXVvdGVkLXByaW50YWJsZSIgb3IgImJhc2U2NCIKKyAgICAgKiBlbmNvZGluZ3MgYXJlIGNvbnZlcnRlZCB0byB1c2UgIjhiaXQiIGVuY29kaW5nIGlmIHRoZXkgZm9sbG93IHRoZQorICAgICAqIFJGQyAyMDQ1IHJ1bGVzIGZvciA4Yml0IHRleHQuIDxwPgorICAgICAqCisgICAgICogSWYgdHJ1ZSwgb3ZlcnJpZGVzIHRoZSA8Y29kZT5tYWlsLnNtdHAuYWxsb3c4Yml0bWltZTwvY29kZT4gcHJvcGVydHkuCisgICAgICoKKyAgICAgKiBAcGFyYW0JYWxsb3cJYWxsb3cgOC1iaXQgZmxhZworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEFsbG93OGJpdE1JTUUoYm9vbGVhbiBhbGxvdykgeworCWFsbG93OGJpdE1JTUUgPSBhbGxvdzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJcyB1c2Ugb2YgdGhlIDhCSVRNSU1FIGV4dGVuc2lvbiBpcyBhbGxvd2VkPworICAgICAqCisgICAgICogQHJldHVybglhbGxvdyA4LWJpdCBmbGFnCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZ2V0QWxsb3c4Yml0TUlNRSgpIHsKKwlyZXR1cm4gYWxsb3c4Yml0TUlNRTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJZiBzZXQgdG8gdHJ1ZSwgYW5kIHRoaXMgbWVzc2FnZSBoYXMgc29tZSB2YWxpZCBhbmQgc29tZSBpbnZhbGlkCisgICAgICogYWRkcmVzc2VzLCBzZW5kIHRoZSBtZXNzYWdlIGFueXdheSwgcmVwb3J0aW5nIHRoZSBwYXJ0aWFsIGZhaWx1cmUgd2l0aAorICAgICAqIGEgU2VuZEZhaWxlZEV4Y2VwdGlvbi4gIElmIHNldCB0byBmYWxzZSAodGhlIGRlZmF1bHQpLCB0aGUgbWVzc2FnZSBpcworICAgICAqIG5vdCBzZW50IHRvIGFueSBvZiB0aGUgcmVjaXBpZW50cyBpZiB0aGVyZSBpcyBhbiBpbnZhbGlkIHJlY2lwaWVudAorICAgICAqIGFkZHJlc3MuIDxwPgorICAgICAqCisgICAgICogSWYgdHJ1ZSwgb3ZlcnJpZGVzIHRoZSA8Y29kZT5tYWlsLnNtdHAuc2VuZHBhcnRpYWw8L2NvZGU+IHByb3BlcnR5LgorICAgICAqCisgICAgICogQHBhcmFtIHBhcnRpYWwJc2VuZCBwYXJ0aWFsIGZsYWcKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRTZW5kUGFydGlhbChib29sZWFuIHBhcnRpYWwpIHsKKwlzZW5kUGFydGlhbCA9IHBhcnRpYWw7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VuZCBtZXNzYWdlIGlmIHNvbWUgYWRkcmVzc2VzIGFyZSBpbnZhbGlkPworICAgICAqCisgICAgICogQHJldHVybglzZW5kIHBhcnRpYWwgZmxhZworICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGdldFNlbmRQYXJ0aWFsKCkgeworCXJldHVybiBzZW5kUGFydGlhbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBzdWJtaXR0ZXIgdG8gYmUgdXNlZCBmb3IgdGhlIFJGQyAyNTU0IEFVVEg9IHZhbHVlCisgICAgICogaW4gdGhlIE1BSUwgRlJPTSBjb21tYW5kLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgbmFtZSBvZiB0aGUgc3VibWl0dGVyLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3VibWl0dGVyKCkgeworCXJldHVybiBzdWJtaXR0ZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgc3VibWl0dGVyIHRvIGJlIHVzZWQgZm9yIHRoZSBSRkMgMjU1NCBBVVRIPSB2YWx1ZQorICAgICAqIGluIHRoZSBNQUlMIEZST00gY29tbWFuZC4gIE5vcm1hbGx5IG9ubHkgdXNlZCBieSBhIHNlcnZlcgorICAgICAqIHRoYXQncyByZWxheWluZyBhIG1lc3NhZ2UuICBDbGllbnRzIHdpbGwgdHlwaWNhbGx5IG5vdAorICAgICAqIHNldCBhIHN1Ym1pdHRlci4gIFNlZQorICAgICAqIDxBIEhSRUY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzI1NTQudHh0Ij5SRkMgMjU1NDwvQT4KKyAgICAgKiBmb3IgZGV0YWlscy4KKyAgICAgKgorICAgICAqIEBwYXJhbQlzdWJtaXR0ZXIJdGhlIG5hbWUgb2YgdGhlIHN1Ym1pdHRlcgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFN1Ym1pdHRlcihTdHJpbmcgc3VibWl0dGVyKSB7CisJdGhpcy5zdWJtaXR0ZXIgPSBzdWJtaXR0ZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgZXh0ZW5zaW9uIHN0cmluZyB0byB1c2Ugd2l0aCB0aGUgTUFJTCBjb21tYW5kLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgZXh0ZW5zaW9uIHN0cmluZworICAgICAqCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuMy4yCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRNYWlsRXh0ZW5zaW9uKCkgeworCXJldHVybiBleHRlbnNpb247CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBleHRlbnNpb24gc3RyaW5nIHRvIHVzZSB3aXRoIHRoZSBNQUlMIGNvbW1hbmQuCisgICAgICogVGhlIGV4dGVuc2lvbiBzdHJpbmcgY2FuIGJlIHVzZWQgdG8gc3BlY2lmeSBzdGFuZGFyZCBTTVRQCisgICAgICogc2VydmljZSBleHRlbnNpb25zIGFzIHdlbGwgYXMgdmVuZG9yLXNwZWNpZmljIGV4dGVuc2lvbnMuCisgICAgICogVHlwaWNhbGx5IHRoZSBhcHBsaWNhdGlvbiBzaG91bGQgdXNlIHRoZQorICAgICAqIHtAbGluayBjb20uc3VuLm1haWwuc210cC5TTVRQVHJhbnNwb3J0IFNNVFBUcmFuc3BvcnR9CisgICAgICogbWV0aG9kIHtAbGluayBjb20uc3VuLm1haWwuc210cC5TTVRQVHJhbnNwb3J0I3N1cHBvcnRzRXh0ZW5zaW9uCisgICAgICogc3VwcG9ydHNFeHRlbnNpb259CisgICAgICogdG8gdmVyaWZ5IHRoYXQgdGhlIHNlcnZlciBzdXBwb3J0cyB0aGUgZGVzaXJlZCBzZXJ2aWNlIGV4dGVuc2lvbi4KKyAgICAgKiBTZWUgPEEgSFJFRj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMTg2OS50eHQiPlJGQyAxODY5PC9BPgorICAgICAqIGFuZCBvdGhlciBSRkNzIHRoYXQgZGVmaW5lIHNwZWNpZmljIGV4dGVuc2lvbnMuIDxwPgorICAgICAqCisgICAgICogRm9yIGV4YW1wbGU6CisgICAgICoKKyAgICAgKiA8YmxvY2txdW90ZT48cHJlPgorICAgICAqIGlmIChzbXRwVHJhbnNwb3J0LnN1cHBvcnRzRXh0ZW5zaW9uKCJERUxJVkVSQlkiKSkKKyAgICAgKiAgICBzbXRwTXNnLnNldE1haWxFeHRlbnNpb24oIkJZPTYwO1IiKTsKKyAgICAgKiA8L3ByZT48L2Jsb2NrcXVvdGU+CisgICAgICoKKyAgICAgKiBAcGFyYW0JZXh0ZW5zaW9uCXRoZSBleHRlbnNpb24gc3RyaW5nCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuMy4yCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TWFpbEV4dGVuc2lvbihTdHJpbmcgZXh0ZW5zaW9uKSB7CisJdGhpcy5leHRlbnNpb24gPSBleHRlbnNpb247CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9zbXRwL1NNVFBPdXRwdXRTdHJlYW0uamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvc210cC9TTVRQT3V0cHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDJmZDc1YgotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvc210cC9TTVRQT3V0cHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSw5NSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuc210cDsKKworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5DUkxGT3V0cHV0U3RyZWFtOworCisvKioKKyAqIEluIGFkZGl0aW9uIHRvIGNvbnZlcnRpbmcgbGluZXMgaW50byB0aGUgY2Fub25pY2FsIGZvcm1hdCwKKyAqIGkuZS4sIHRlcm1pbmF0aW5nIGxpbmVzIHdpdGggdGhlIENSTEYgc2VxdWVuY2UsIGVzY2FwZXMgdGhlICIuIgorICogYnkgYWRkaW5nIGFub3RoZXIgIi4iIHRvIGFueSAiLiIgdGhhdCBhcHBlYXJzIGluIHRoZSBiZWdpbm5pbmcKKyAqIG9mIGEgbGluZS4gIFNlZSBSRkM4MjEgc2VjdGlvbiA0LjUuMi4KKyAqIAorICogQGF1dGhvciBNYXggU3BpdmFrCisgKiBAc2VlIENSTEZPdXRwdXRTdHJlYW0KKyAqLworcHVibGljIGNsYXNzIFNNVFBPdXRwdXRTdHJlYW0gZXh0ZW5kcyBDUkxGT3V0cHV0U3RyZWFtIHsKKyAgICBwdWJsaWMgU01UUE91dHB1dFN0cmVhbShPdXRwdXRTdHJlYW0gb3MpIHsKKwlzdXBlcihvcyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoaW50IGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJLy8gaWYgdGhhdCBsYXN0IGNoYXJhY3RlciB3YXMgYSBuZXdsaW5lLCBhbmQgdGhlIGN1cnJlbnQKKwkvLyBjaGFyYWN0ZXIgaXMgIi4iLCB3ZSBhbHdheXMgd3JpdGUgb3V0IGFuIGV4dHJhICIuIi4KKwlpZiAoKGxhc3RiID09ICdcbicgfHwgbGFzdGIgPT0gJ1xyJyB8fCBsYXN0YiA9PSAtMSkgJiYgYiA9PSAnLicpIHsKKwkgICAgb3V0LndyaXRlKCcuJyk7CisJfQorCQorCXN1cGVyLndyaXRlKGIpOworICAgIH0KKworICAgIC8qIAorICAgICAqIFRoaXMgbWV0aG9kIGhhcyBiZWVuIGFkZGVkIHRvIGltcHJvdmUgcGVyZm9ybWFuY2UuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoYnl0ZSBiW10sIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJaW50IGxhc3RjID0gKGxhc3RiID09IC0xKSA/ICdcbicgOiBsYXN0YjsKKwlpbnQgc3RhcnQgPSBvZmY7CisJCisJbGVuICs9IG9mZjsKKwlmb3IgKGludCBpID0gb2ZmOyBpIDwgbGVuOyBpKyspIHsKKwkgICAgaWYgKChsYXN0YyA9PSAnXG4nIHx8IGxhc3RjID09ICdccicpICYmIGJbaV0gPT0gJy4nKSB7CisJCXN1cGVyLndyaXRlKGIsIHN0YXJ0LCBpIC0gc3RhcnQpOworCQlvdXQud3JpdGUoJy4nKTsKKwkJc3RhcnQgPSBpOworCSAgICB9CisJICAgIGxhc3RjID0gYltpXTsKKwl9CisJaWYgKChsZW4gLSBzdGFydCkgPiAwKQorCSAgICBzdXBlci53cml0ZShiLCBzdGFydCwgbGVuIC0gc3RhcnQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIE92ZXJyaWRlIGZsdXNoIG1ldGhvZCBpbiBGaWx0ZXJPdXRwdXRTdHJlYW0uCisgICAgICoKKyAgICAgKiBUaGUgTWltZU1lc3NhZ2Ugd3JpdGVUbyBtZXRob2QgZmx1c2hlcyBpdHMgYnVmZmVyIGF0IHRoZSBlbmQsCisgICAgICogYnV0IHdlIGRvbid0IHdhbnQgdG8gZmx1c2ggZGF0YSBvdXQgdG8gdGhlIHNvY2tldCB1bnRpbCB3ZSd2ZQorICAgICAqIGFsc28gd3JpdHRlbiB0aGUgdGVybWluYXRpbmcgIlxyXG4uXHJcbiIuCisgICAgICoKKyAgICAgKiBXZSBidWZmZXIgbm90aGluZyBzbyB0aGVyZSdzIG5vdGhpbmcgdG8gZmx1c2guICBXZSBkZXBlbmQKKyAgICAgKiBvbiB0aGUgZmFjdCB0aGF0IENSTEZPdXRwdXRTdHJlYW0gYWxzbyBidWZmZXJzIG5vdGhpbmcuCisgICAgICogU01UUFRyYW5zcG9ydCB3aWxsIG1hbnVhbGx5IGZsdXNoIHRoZSBzb2NrZXQgYmVmb3JlIHJlYWRpbmcKKyAgICAgKiB0aGUgcmVzcG9uc2UuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZmx1c2goKSB7CisJLy8gZG8gbm90aGluZworICAgIH0KKworICAgIC8qKgorICAgICAqIEVuc3VyZSB3ZSdyZSBhdCB0aGUgYmVnaW5uaW5nIG9mIGEgbGluZS4KKyAgICAgKiBXcml0ZSBDUkxGIGlmIG5vdC4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24JSU9FeGNlcHRpb24JaWYgdGhlIHdyaXRlIGZhaWxzCisgICAgICovCisgICAgcHVibGljIHZvaWQgZW5zdXJlQXRCT0woKSB0aHJvd3MgSU9FeGNlcHRpb24geworCWlmICghYXRCT0wpCisJICAgIHN1cGVyLndyaXRlbG4oKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3NtdHAvU01UUFByb3ZpZGVyLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3NtdHAvU01UUFByb3ZpZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2I1YzFlOQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvc210cC9TTVRQUHJvdmlkZXIuamF2YQpAQCAtMCwwICsxLDI5IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5zbXRwOworCitpbXBvcnQgamF2YXgubWFpbC5Qcm92aWRlcjsKKworLyoqCisgKiBUaGUgU01UUCBwcm90b2NvbCBwcm92aWRlci4KKyAqLworcHVibGljIGNsYXNzIFNNVFBQcm92aWRlciBleHRlbmRzIFByb3ZpZGVyIHsKKyAgICBwdWJsaWMgU01UUFByb3ZpZGVyKCkgeworCXN1cGVyKFByb3ZpZGVyLlR5cGUuVFJBTlNQT1JULCAic210cCIsIFNNVFBUcmFuc3BvcnQuY2xhc3MuZ2V0TmFtZSgpLAorCSAgICAiT3JhY2xlIiwgbnVsbCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9zbXRwL1NNVFBTU0xQcm92aWRlci5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9zbXRwL1NNVFBTU0xQcm92aWRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQwYTJhY2QKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3NtdHAvU01UUFNTTFByb3ZpZGVyLmphdmEKQEAgLTAsMCArMSwyOSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuc210cDsKKworaW1wb3J0IGphdmF4Lm1haWwuUHJvdmlkZXI7CisKKy8qKgorICogVGhlIFNNVFAgU1NMIHByb3RvY29sIHByb3ZpZGVyLgorICovCitwdWJsaWMgY2xhc3MgU01UUFNTTFByb3ZpZGVyIGV4dGVuZHMgUHJvdmlkZXIgeworICAgIHB1YmxpYyBTTVRQU1NMUHJvdmlkZXIoKSB7CisJc3VwZXIoUHJvdmlkZXIuVHlwZS5UUkFOU1BPUlQsICJzbXRwcyIsCisJICAgIFNNVFBTU0xUcmFuc3BvcnQuY2xhc3MuZ2V0TmFtZSgpLCAiT3JhY2xlIiwgbnVsbCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9zbXRwL1NNVFBTU0xUcmFuc3BvcnQuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvc210cC9TTVRQU1NMVHJhbnNwb3J0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjNhNzMwMAotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvc210cC9TTVRQU1NMVHJhbnNwb3J0LmphdmEKQEAgLTAsMCArMSwzOSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuc210cDsKKworaW1wb3J0IGphdmF4Lm1haWwuKjsKKworLyoqCisgKiBUaGlzIGNsYXNzIGltcGxlbWVudHMgdGhlIFRyYW5zcG9ydCBhYnN0cmFjdCBjbGFzcyB1c2luZyBTTVRQCisgKiBvdmVyIFNTTCBmb3IgbWVzc2FnZSBzdWJtaXNzaW9uIGFuZCB0cmFuc3BvcnQuCisgKgorICogQGF1dGhvciBCaWxsIFNoYW5ub24KKyAqLworCitwdWJsaWMgY2xhc3MgU01UUFNTTFRyYW5zcG9ydCBleHRlbmRzIFNNVFBUcmFuc3BvcnQgeworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jc2Vzc2lvbgl0aGUgU2Vzc2lvbgorICAgICAqIEBwYXJhbQl1cmxuYW1lCXRoZSBVUkxOYW1lIG9mIHRoaXMgdHJhbnNwb3J0CisgICAgICovCisgICAgcHVibGljIFNNVFBTU0xUcmFuc3BvcnQoU2Vzc2lvbiBzZXNzaW9uLCBVUkxOYW1lIHVybG5hbWUpIHsKKwlzdXBlcihzZXNzaW9uLCB1cmxuYW1lLCAic210cHMiLCB0cnVlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3NtdHAvU01UUFNhc2xBdXRoZW50aWNhdG9yLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3NtdHAvU01UUFNhc2xBdXRoZW50aWNhdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzA1NDVhNQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvc210cC9TTVRQU2FzbEF1dGhlbnRpY2F0b3IuamF2YQpAQCAtMCwwICsxLDIyOCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuc210cDsKKworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBqYXZhLnV0aWwubG9nZ2luZy5MZXZlbDsKK2ltcG9ydCBqYXZheC5zZWN1cml0eS5zYXNsLio7CitpbXBvcnQgamF2YXguc2VjdXJpdHkuYXV0aC5jYWxsYmFjay4qOworaW1wb3J0IGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uOworCitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuTWFpbExvZ2dlcjsKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5BU0NJSVV0aWxpdHk7CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuQkFTRTY0RW5jb2RlclN0cmVhbTsKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5CQVNFNjREZWNvZGVyU3RyZWFtOworCisvKioKKyAqIFRoaXMgY2xhc3MgY29udGFpbnMgYSBzaW5nbGUgbWV0aG9kIHRoYXQgZG9lcyBhdXRoZW50aWNhdGlvbiB1c2luZworICogU0FTTC4gIFRoaXMgaXMgaW4gYSBzZXBhcmF0ZSBjbGFzcyBzbyB0aGF0IGl0IGNhbiBiZSBjb21waWxlZCB3aXRoCisgKiBKMlNFIDEuNS4gIEV2ZW50dWFsbHkgaXQgc2hvdWxkIGJlIG1lcmdlZCBpbnRvIFNNVFBUcmFuc3BvcnQuamF2YS4KKyAqLworCitwdWJsaWMgY2xhc3MgU01UUFNhc2xBdXRoZW50aWNhdG9yIGltcGxlbWVudHMgU2FzbEF1dGhlbnRpY2F0b3IgeworCisgICAgcHJpdmF0ZSBTTVRQVHJhbnNwb3J0IHByOworICAgIHByaXZhdGUgU3RyaW5nIG5hbWU7CisgICAgcHJpdmF0ZSBQcm9wZXJ0aWVzIHByb3BzOworICAgIHByaXZhdGUgTWFpbExvZ2dlciBsb2dnZXI7CisgICAgcHJpdmF0ZSBTdHJpbmcgaG9zdDsKKworICAgIC8qCisgICAgICogVGhpcyBpcyBhIGhhY2sgdG8gaW5pdGlhbGl6ZSB0aGUgT0FVVEggU0FTTCBwcm92aWRlciBqdXN0IGJlZm9yZSwKKyAgICAgKiBhbmQgb25seSBpZiwgd2UgbWlnaHQgbmVlZCBpdC4gIFRoaXMgYXZvaWRzIHRoZSBuZWVkIGZvciB0aGUgdXNlciAKKyAgICAgKiB0byBpbml0aWFsaXplIGl0IGV4cGxpY2l0bHksIG9yIG1hbnVhbGx5IGNvbmZpZ3VyZSB0aGUgc2VjdXJpdHkKKyAgICAgKiBwcm92aWRlcnMgZmlsZS4KKyAgICAgKi8KKyAgICBzdGF0aWMgeworCXRyeSB7CisJICAgIGNvbS5zdW4ubWFpbC5hdXRoLk9BdXRoMlNhc2xDbGllbnRGYWN0b3J5LmluaXQoKTsKKwl9IGNhdGNoIChUaHJvd2FibGUgdCkgeyB9CisgICAgfQorCisgICAgcHVibGljIFNNVFBTYXNsQXV0aGVudGljYXRvcihTTVRQVHJhbnNwb3J0IHByLCBTdHJpbmcgbmFtZSwKKwkJUHJvcGVydGllcyBwcm9wcywgTWFpbExvZ2dlciBsb2dnZXIsIFN0cmluZyBob3N0KSB7CisJdGhpcy5wciA9IHByOworCXRoaXMubmFtZSA9IG5hbWU7CisJdGhpcy5wcm9wcyA9IHByb3BzOworCXRoaXMubG9nZ2VyID0gbG9nZ2VyOworCXRoaXMuaG9zdCA9IGhvc3Q7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gYXV0aGVudGljYXRlKFN0cmluZ1tdIG1lY2hzLCBmaW5hbCBTdHJpbmcgcmVhbG0sCisJCQkJZmluYWwgU3RyaW5nIGF1dGh6aWQsIGZpbmFsIFN0cmluZyB1LAorCQkJCWZpbmFsIFN0cmluZyBwKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKworCWJvb2xlYW4gZG9uZSA9IGZhbHNlOworCWlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FKSkgeworCSAgICBsb2dnZXIuZmluZSgiU0FTTCBNZWNoYW5pc21zOiIpOworCSAgICBmb3IgKGludCBpID0gMDsgaSA8IG1lY2hzLmxlbmd0aDsgaSsrKQorCQlsb2dnZXIuZmluZSgiICIgKyBtZWNoc1tpXSk7CisJICAgIGxvZ2dlci5maW5lKCIiKTsKKwl9CisKKwlTYXNsQ2xpZW50IHNjOworCUNhbGxiYWNrSGFuZGxlciBjYmggPSBuZXcgQ2FsbGJhY2tIYW5kbGVyKCkgeworCSAgICBAT3ZlcnJpZGUKKwkgICAgcHVibGljIHZvaWQgaGFuZGxlKENhbGxiYWNrW10gY2FsbGJhY2tzKSB7CisJCWlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FKSkKKwkJICAgIGxvZ2dlci5maW5lKCJTQVNMIGNhbGxiYWNrIGxlbmd0aDogIiArIGNhbGxiYWNrcy5sZW5ndGgpOworCQlmb3IgKGludCBpID0gMDsgaSA8IGNhbGxiYWNrcy5sZW5ndGg7IGkrKykgeworCQkgICAgaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkUpKQorCQkJbG9nZ2VyLmZpbmUoIlNBU0wgY2FsbGJhY2sgIiArIGkgKyAiOiAiICsgY2FsbGJhY2tzW2ldKTsKKwkJICAgIGlmIChjYWxsYmFja3NbaV0gaW5zdGFuY2VvZiBOYW1lQ2FsbGJhY2spIHsKKwkJCU5hbWVDYWxsYmFjayBuY2IgPSAoTmFtZUNhbGxiYWNrKWNhbGxiYWNrc1tpXTsKKwkJCW5jYi5zZXROYW1lKHUpOworCQkgICAgfSBlbHNlIGlmIChjYWxsYmFja3NbaV0gaW5zdGFuY2VvZiBQYXNzd29yZENhbGxiYWNrKSB7CisJCQlQYXNzd29yZENhbGxiYWNrIHBjYiA9IChQYXNzd29yZENhbGxiYWNrKWNhbGxiYWNrc1tpXTsKKwkJCXBjYi5zZXRQYXNzd29yZChwLnRvQ2hhckFycmF5KCkpOworCQkgICAgfSBlbHNlIGlmIChjYWxsYmFja3NbaV0gaW5zdGFuY2VvZiBSZWFsbUNhbGxiYWNrKSB7CisJCQlSZWFsbUNhbGxiYWNrIHJjYiA9IChSZWFsbUNhbGxiYWNrKWNhbGxiYWNrc1tpXTsKKwkJCXJjYi5zZXRUZXh0KHJlYWxtICE9IG51bGwgPworCQkJCSAgICByZWFsbSA6IHJjYi5nZXREZWZhdWx0VGV4dCgpKTsKKwkJICAgIH0gZWxzZSBpZiAoY2FsbGJhY2tzW2ldIGluc3RhbmNlb2YgUmVhbG1DaG9pY2VDYWxsYmFjaykgeworCQkJUmVhbG1DaG9pY2VDYWxsYmFjayByY2IgPQorCQkJICAgIChSZWFsbUNob2ljZUNhbGxiYWNrKWNhbGxiYWNrc1tpXTsKKwkJCWlmIChyZWFsbSA9PSBudWxsKQorCQkJICAgIHJjYi5zZXRTZWxlY3RlZEluZGV4KHJjYi5nZXREZWZhdWx0Q2hvaWNlKCkpOworCQkJZWxzZSB7CisJCQkgICAgLy8gbmVlZCB0byBmaW5kIHNwZWNpZmllZCByZWFsbSBpbiBsaXN0CisJCQkgICAgU3RyaW5nW10gY2hvaWNlcyA9IHJjYi5nZXRDaG9pY2VzKCk7CisJCQkgICAgZm9yIChpbnQgayA9IDA7IGsgPCBjaG9pY2VzLmxlbmd0aDsgaysrKSB7CisJCQkJaWYgKGNob2ljZXNba10uZXF1YWxzKHJlYWxtKSkgeworCQkJCSAgICByY2Iuc2V0U2VsZWN0ZWRJbmRleChrKTsKKwkJCQkgICAgYnJlYWs7CisJCQkJfQorCQkJICAgIH0KKwkJCX0KKwkJICAgIH0KKwkJfQorCSAgICB9CisJfTsKKworCXRyeSB7CisJICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorCSAgICBNYXA8U3RyaW5nLCA/PiBwcm9wc01hcCA9IChNYXApIHByb3BzOworCSAgICBzYyA9IFNhc2wuY3JlYXRlU2FzbENsaWVudChtZWNocywgYXV0aHppZCwgbmFtZSwgaG9zdCwKKwkJCQkJcHJvcHNNYXAsIGNiaCk7CisJfSBjYXRjaCAoU2FzbEV4Y2VwdGlvbiBzZXgpIHsKKwkgICAgbG9nZ2VyLmxvZyhMZXZlbC5GSU5FLCAiRmFpbGVkIHRvIGNyZWF0ZSBTQVNMIGNsaWVudCIsIHNleCk7CisJICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbihzZXguZ2V0TWVzc2FnZSgpLCBzZXgpOworCX0KKwlpZiAoc2MgPT0gbnVsbCkgeworCSAgICBsb2dnZXIuZmluZSgiTm8gU0FTTCBzdXBwb3J0Iik7CisJICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm8gU0FTTCBzdXBwb3J0Iik7CisJfQorCWlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FKSkKKwkgICAgbG9nZ2VyLmZpbmUoIlNBU0wgY2xpZW50ICIgKyBzYy5nZXRNZWNoYW5pc21OYW1lKCkpOworCisJaW50IHJlc3A7CisJdHJ5IHsKKwkgICAgU3RyaW5nIG1lY2ggPSBzYy5nZXRNZWNoYW5pc21OYW1lKCk7CisJICAgIFN0cmluZyBpciA9IG51bGw7CisJICAgIGlmIChzYy5oYXNJbml0aWFsUmVzcG9uc2UoKSkgeworCQlieXRlW10gYmEgPSBzYy5ldmFsdWF0ZUNoYWxsZW5nZShuZXcgYnl0ZVswXSk7CisJCWlmIChiYS5sZW5ndGggPiAwKSB7CisJCSAgICBiYSA9IEJBU0U2NEVuY29kZXJTdHJlYW0uZW5jb2RlKGJhKTsKKwkJICAgIGlyID0gQVNDSUlVdGlsaXR5LnRvU3RyaW5nKGJhLCAwLCBiYS5sZW5ndGgpOworCQl9IGVsc2UKKwkJICAgIGlyID0gIj0iOworCSAgICB9CisJICAgIGlmIChpciAhPSBudWxsKQorCQlyZXNwID0gcHIuc2ltcGxlQ29tbWFuZCgiQVVUSCAiICsgbWVjaCArICIgIiArIGlyKTsKKwkgICAgZWxzZQorCQlyZXNwID0gcHIuc2ltcGxlQ29tbWFuZCgiQVVUSCAiICsgbWVjaCk7CisKKwkgICAgLyoKKwkgICAgICogQSA1MzAgcmVzcG9uc2UgaW5kaWNhdGVzIHRoYXQgdGhlIHNlcnZlciB3YW50cyB1cyB0bworCSAgICAgKiBpc3N1ZSBhIFNUQVJUVExTIGNvbW1hbmQgZmlyc3QuICBEbyB0aGF0IGFuZCB0cnkgYWdhaW4uCisJICAgICAqLworCSAgICBpZiAocmVzcCA9PSA1MzApIHsKKwkJcHIuc3RhcnRUTFMoKTsKKwkJaWYgKGlyICE9IG51bGwpCisJCSAgICByZXNwID0gcHIuc2ltcGxlQ29tbWFuZCgiQVVUSCAiICsgbWVjaCArICIgIiArIGlyKTsKKwkJZWxzZQorCQkgICAgcmVzcCA9IHByLnNpbXBsZUNvbW1hbmQoIkFVVEggIiArIG1lY2gpOworCSAgICB9CisKKwkgICAgaWYgKHJlc3AgPT0gMjM1KQorCQlyZXR1cm4gdHJ1ZTsJLy8gc3VjY2VzcyBhbHJlYWR5IQorCisJICAgIGlmIChyZXNwICE9IDMzNCkKKwkJcmV0dXJuIGZhbHNlOworCX0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCSAgICBsb2dnZXIubG9nKExldmVsLkZJTkUsICJTQVNMIEFVVEhFTlRJQ0FURSBFeGNlcHRpb24iLCBleCk7CisJICAgIHJldHVybiBmYWxzZTsKKwl9CisKKwl3aGlsZSAoIWRvbmUpIHsgLy8gbG9vcCB0aWxsIHdlIGFyZSBkb25lCisJICAgIHRyeSB7CisJICAgIAlpZiAocmVzcCA9PSAzMzQpIHsKKwkJICAgIGJ5dGVbXSBiYSA9IG51bGw7CisJCSAgICBpZiAoIXNjLmlzQ29tcGxldGUoKSkgeworCQkJYmEgPSBBU0NJSVV0aWxpdHkuZ2V0Qnl0ZXMocmVzcG9uc2VUZXh0KHByKSk7CisJCQlpZiAoYmEubGVuZ3RoID4gMCkKKwkJCSAgICBiYSA9IEJBU0U2NERlY29kZXJTdHJlYW0uZGVjb2RlKGJhKTsKKwkJCWlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FKSkKKwkJCSAgICBsb2dnZXIuZmluZSgiU0FTTCBjaGFsbGVuZ2U6ICIgKworCQkJCUFTQ0lJVXRpbGl0eS50b1N0cmluZyhiYSwgMCwgYmEubGVuZ3RoKSArICIgOiIpOworCQkJYmEgPSBzYy5ldmFsdWF0ZUNoYWxsZW5nZShiYSk7CisJCSAgICB9CisJCSAgICBpZiAoYmEgPT0gbnVsbCkgeworCQkJbG9nZ2VyLmZpbmUoIlNBU0w6IG5vIHJlc3BvbnNlIik7CisJCQlyZXNwID0gcHIuc2ltcGxlQ29tbWFuZCgiIik7CisJCSAgICB9IGVsc2UgeworCQkJaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkUpKQorCQkJICAgIGxvZ2dlci5maW5lKCJTQVNMIHJlc3BvbnNlOiAiICsKKwkJCQlBU0NJSVV0aWxpdHkudG9TdHJpbmcoYmEsIDAsIGJhLmxlbmd0aCkgKyAiIDoiKTsKKwkJCWJhID0gQkFTRTY0RW5jb2RlclN0cmVhbS5lbmNvZGUoYmEpOworCQkJcmVzcCA9IHByLnNpbXBsZUNvbW1hbmQoYmEpOworCQkgICAgfQorCQl9IGVsc2UKKwkJICAgIGRvbmUgPSB0cnVlOworCSAgICB9IGNhdGNoIChFeGNlcHRpb24gaW9leCkgeworCQlsb2dnZXIubG9nKExldmVsLkZJTkUsICJTQVNMIEV4Y2VwdGlvbiIsIGlvZXgpOworCQlkb25lID0gdHJ1ZTsKKwkJLy8gWFhYIC0gdWx0aW1hdGVseSByZXR1cm4gdHJ1ZT8/PworCSAgICB9CisJfQorCWlmIChyZXNwICE9IDIzNSkKKwkgICAgcmV0dXJuIGZhbHNlOworCisJaWYgKHNjLmlzQ29tcGxldGUoKSAvKiYmIHJlcy5zdGF0dXMgPT0gU1VDQ0VTUyovKSB7CisJICAgIFN0cmluZyBxb3AgPSAoU3RyaW5nKXNjLmdldE5lZ290aWF0ZWRQcm9wZXJ0eShTYXNsLlFPUCk7CisJICAgIGlmIChxb3AgIT0gbnVsbCAmJiAocW9wLmVxdWFsc0lnbm9yZUNhc2UoImF1dGgtaW50IikgfHwKKwkJCQlxb3AuZXF1YWxzSWdub3JlQ2FzZSgiYXV0aC1jb25mIikpKSB7CisJCS8vIFhYWCAtIE5PVCBTVVBQT1JURUQhISEKKwkJbG9nZ2VyLmZpbmUoCisJCSAgICAiU0FTTCBNZWNoYW5pc20gcmVxdWlyZXMgaW50ZWdyaXR5IG9yIGNvbmZpZGVudGlhbGl0eSIpOworCQlyZXR1cm4gZmFsc2U7CisJICAgIH0KKwl9CisKKwlyZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgcmVzcG9uc2VUZXh0KFNNVFBUcmFuc3BvcnQgcHIpIHsKKwlTdHJpbmcgcmVzcCA9IHByLmdldExhc3RTZXJ2ZXJSZXNwb25zZSgpLnRyaW0oKTsKKwlpZiAocmVzcC5sZW5ndGgoKSA+IDQpCisJICAgIHJldHVybiByZXNwLnN1YnN0cmluZyg0KTsKKwllbHNlCisJICAgIHJldHVybiAiIjsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3NtdHAvU01UUFNlbmRGYWlsZWRFeGNlcHRpb24uamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvc210cC9TTVRQU2VuZEZhaWxlZEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ4Y2YzZTYKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3NtdHAvU01UUFNlbmRGYWlsZWRFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDgyIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5zbXRwOworCitpbXBvcnQgamF2YXgubWFpbC5BZGRyZXNzOworaW1wb3J0IGphdmF4Lm1haWwuU2VuZEZhaWxlZEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5tYWlsLmludGVybmV0LkludGVybmV0QWRkcmVzczsKKworLyoqCisgKiBUaGlzIGV4Y2VwdGlvbiBpcyB0aHJvd24gd2hlbiB0aGUgbWVzc2FnZSBjYW5ub3QgYmUgc2VudC4gPHA+CisgKiAKKyAqIFRoaXMgZXhjZXB0aW9uIHdpbGwgdXN1YWxseSBhcHBlYXIgZmlyc3QgaW4gYSBjaGFpbmVkIGxpc3Qgb2YgZXhjZXB0aW9ucywKKyAqIGZvbGxvd2VkIGJ5IFNNVFBBZGRyZXNzRmFpbGVkRXhjZXB0aW9ucyBhbmQvb3IKKyAqIFNNVFBBZGRyZXNzU3VjY2VlZGVkRXhjZXB0aW9ucywgKiBvbmUgcGVyIGFkZHJlc3MuCisgKiBUaGlzIGV4Y2VwdGlvbiBjb3JyZXNwb25kcyB0byBvbmUgb2YgdGhlIFNNVFAgY29tbWFuZHMgdXNlZCB0bworICogc2VuZCBhIG1lc3NhZ2UsIHN1Y2ggYXMgdGhlIE1BSUwsIERBVEEsIGFuZCAiZW5kIG9mIGRhdGEiIGNvbW1hbmRzLAorICogYnV0IG5vdCBpbmNsdWRpbmcgdGhlIFJDUFQgY29tbWFuZC4KKyAqCisgKiBAc2luY2UgSmF2YU1haWwgMS4zLjIKKyAqLworCitwdWJsaWMgY2xhc3MgU01UUFNlbmRGYWlsZWRFeGNlcHRpb24gZXh0ZW5kcyBTZW5kRmFpbGVkRXhjZXB0aW9uIHsKKyAgICBwcm90ZWN0ZWQgSW50ZXJuZXRBZGRyZXNzIGFkZHI7CS8vIGFkZHJlc3MgdGhhdCBmYWlsZWQKKyAgICBwcm90ZWN0ZWQgU3RyaW5nIGNtZDsJCS8vIGNvbW1hbmQgaXNzdWVkIHRvIHNlcnZlcgorICAgIHByb3RlY3RlZCBpbnQgcmM7CQkJLy8gcmV0dXJuIGNvZGUgZnJvbSBTTVRQIHNlcnZlcgorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gODA0OTEyMjYyODcyODkzMjg5NEw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGFuIFNNVFBTZW5kRmFpbGVkRXhjZXB0aW9uIHdpdGggdGhlIHNwZWNpZmllZCAKKyAgICAgKiBhZGRyZXNzLCByZXR1cm4gY29kZSwgYW5kIGVycm9yIHN0cmluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjbWQJdGhlIGNvbW1hbmQgdGhhdCB3YXMgc2VudCB0byB0aGUgU01UUCBzZXJ2ZXIKKyAgICAgKiBAcGFyYW0gcmMJdGhlIFNNVFAgcmV0dXJuIGNvZGUgaW5kaWNhdGluZyB0aGUgZmFpbHVyZQorICAgICAqIEBwYXJhbSBlcnIJdGhlIGVycm9yIHN0cmluZyBmcm9tIHRoZSBTTVRQIHNlcnZlcgorICAgICAqIEBwYXJhbSBleAlhIGNoYWluZWQgZXhjZXB0aW9uCisgICAgICogQHBhcmFtIHZzCXRoZSB2YWxpZCBhZGRyZXNzZXMgdGhlIG1lc3NhZ2Ugd2FzIHNlbnQgdG8KKyAgICAgKiBAcGFyYW0gdnVzCXRoZSB2YWxpZCBhZGRyZXNzZXMgdGhlIG1lc3NhZ2Ugd2FzIG5vdCBzZW50IHRvCisgICAgICogQHBhcmFtIGludgl0aGUgaW52YWxpZCBhZGRyZXNzZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgU01UUFNlbmRGYWlsZWRFeGNlcHRpb24oU3RyaW5nIGNtZCwgaW50IHJjLCBTdHJpbmcgZXJyLCBFeGNlcHRpb24gZXgsCisJCQkJQWRkcmVzc1tdIHZzLCBBZGRyZXNzW10gdnVzLCBBZGRyZXNzW10gaW52KSB7CisJc3VwZXIoZXJyLCBleCwgdnMsIHZ1cywgaW52KTsKKwl0aGlzLmNtZCA9IGNtZDsKKwl0aGlzLnJjID0gcmM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBjb21tYW5kIHRoYXQgZmFpbGVkLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgY29tbWFuZAorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q29tbWFuZCgpIHsKKwlyZXR1cm4gY21kOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgcmV0dXJuIGNvZGUgZnJvbSB0aGUgU01UUCBzZXJ2ZXIgdGhhdCBpbmRpY2F0ZXMgdGhlCisgICAgICogcmVhc29uIGZvciB0aGUgZmFpbHVyZS4gIFNlZQorICAgICAqIDxBIEhSRUY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzgyMS50eHQiPlJGQyA4MjE8L0E+CisgICAgICogZm9yIGludGVycHJldGF0aW9uIG9mIHRoZSByZXR1cm4gY29kZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIHJldHVybiBjb2RlCisgICAgICovCisgICAgcHVibGljIGludCBnZXRSZXR1cm5Db2RlKCkgeworCXJldHVybiByYzsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3NtdHAvU01UUFNlbmRlckZhaWxlZEV4Y2VwdGlvbi5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9zbXRwL1NNVFBTZW5kZXJGYWlsZWRFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zMTM5Yzc5Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9zbXRwL1NNVFBTZW5kZXJGYWlsZWRFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDg1IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5zbXRwOworCitpbXBvcnQgamF2YXgubWFpbC5TZW5kRmFpbGVkRXhjZXB0aW9uOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuSW50ZXJuZXRBZGRyZXNzOworCisvKioKKyAqIFRoaXMgZXhjZXB0aW9uIGlzIHRocm93biB3aGVuIHRoZSBtZXNzYWdlIGNhbm5vdCBiZSBzZW50LiA8cD4KKyAqIAorICogVGhlIGV4Y2VwdGlvbiBpbmNsdWRlcyB0aGUgc2VuZGVyJ3MgYWRkcmVzcywgd2hpY2ggdGhlIG1haWwgc2VydmVyCisgKiByZWplY3RlZC4KKyAqCisgKiBAc2luY2UgSmF2YU1haWwgMS40LjQKKyAqLworCitwdWJsaWMgY2xhc3MgU01UUFNlbmRlckZhaWxlZEV4Y2VwdGlvbiBleHRlbmRzIFNlbmRGYWlsZWRFeGNlcHRpb24geworICAgIHByb3RlY3RlZCBJbnRlcm5ldEFkZHJlc3MgYWRkcjsJLy8gYWRkcmVzcyB0aGF0IGZhaWxlZAorICAgIHByb3RlY3RlZCBTdHJpbmcgY21kOwkJLy8gY29tbWFuZCBpc3N1ZWQgdG8gc2VydmVyCisgICAgcHJvdGVjdGVkIGludCByYzsJCQkvLyByZXR1cm4gY29kZSBmcm9tIFNNVFAgc2VydmVyCisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA1MTQ1NDA0NTQ5NjQ0NzY5NDdMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhbiBTTVRQU2VuZGVyRmFpbGVkRXhjZXB0aW9uIHdpdGggdGhlIHNwZWNpZmllZCAKKyAgICAgKiBhZGRyZXNzLCByZXR1cm4gY29kZSwgYW5kIGVycm9yIHN0cmluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhZGRyCXRoZSBhZGRyZXNzIHRoYXQgZmFpbGVkCisgICAgICogQHBhcmFtIGNtZAl0aGUgY29tbWFuZCB0aGF0IHdhcyBzZW50IHRvIHRoZSBTTVRQIHNlcnZlcgorICAgICAqIEBwYXJhbSByYwl0aGUgU01UUCByZXR1cm4gY29kZSBpbmRpY2F0aW5nIHRoZSBmYWlsdXJlCisgICAgICogQHBhcmFtIGVycgl0aGUgZXJyb3Igc3RyaW5nIGZyb20gdGhlIFNNVFAgc2VydmVyCisgICAgICovCisgICAgcHVibGljIFNNVFBTZW5kZXJGYWlsZWRFeGNlcHRpb24oSW50ZXJuZXRBZGRyZXNzIGFkZHIsIFN0cmluZyBjbWQsIGludCByYywKKwkJCQlTdHJpbmcgZXJyKSB7CisJc3VwZXIoZXJyKTsKKwl0aGlzLmFkZHIgPSBhZGRyOworCXRoaXMuY21kID0gY21kOworCXRoaXMucmMgPSByYzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIGFkZHJlc3MgdGhhdCBmYWlsZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBhZGRyZXNzCisgICAgICovCisgICAgcHVibGljIEludGVybmV0QWRkcmVzcyBnZXRBZGRyZXNzKCkgeworCXJldHVybiBhZGRyOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgY29tbWFuZCB0aGF0IGZhaWxlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIGNvbW1hbmQKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldENvbW1hbmQoKSB7CisJcmV0dXJuIGNtZDsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgcmV0dXJuIGNvZGUgZnJvbSB0aGUgU01UUCBzZXJ2ZXIgdGhhdCBpbmRpY2F0ZXMgdGhlCisgICAgICogcmVhc29uIGZvciB0aGUgZmFpbHVyZS4gIFNlZQorICAgICAqIDxBIEhSRUY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzgyMS50eHQiPlJGQyA4MjE8L0E+CisgICAgICogZm9yIGludGVycHJldGF0aW9uIG9mIHRoZSByZXR1cm4gY29kZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIHJldHVybiBjb2RlCisgICAgICovCisgICAgcHVibGljIGludCBnZXRSZXR1cm5Db2RlKCkgeworCXJldHVybiByYzsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3NtdHAvU01UUFRyYW5zcG9ydC5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9zbXRwL1NNVFBUcmFuc3BvcnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42YjJhY2ZiCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9zbXRwL1NNVFBUcmFuc3BvcnQuamF2YQpAQCAtMCwwICsxLDI3OTEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLnNtdHA7CisKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YS5uZXQuKjsKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBqYXZhLnV0aWwubG9nZ2luZy5MZXZlbDsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC4qOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuU3RhbmRhcmRDaGFyc2V0czsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTFNvY2tldDsKKworaW1wb3J0IGphdmF4Lm1haWwuKjsKK2ltcG9ydCBqYXZheC5tYWlsLmV2ZW50Lio7CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC4qOworCitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuUHJvcFV0aWw7CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuTWFpbExvZ2dlcjsKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5BU0NJSVV0aWxpdHk7CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuU29ja2V0RmV0Y2hlcjsKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5NYWlsQ29ubmVjdEV4Y2VwdGlvbjsKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5Tb2NrZXRDb25uZWN0RXhjZXB0aW9uOworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLkJBU0U2NEVuY29kZXJTdHJlYW07CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuTGluZUlucHV0U3RyZWFtOworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLlRyYWNlSW5wdXRTdHJlYW07CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuVHJhY2VPdXRwdXRTdHJlYW07CitpbXBvcnQgY29tLnN1bi5tYWlsLmF1dGguTnRsbTsKKworLyoqCisgKiBUaGlzIGNsYXNzIGltcGxlbWVudHMgdGhlIFRyYW5zcG9ydCBhYnN0cmFjdCBjbGFzcyB1c2luZyBTTVRQIGZvcgorICogbWVzc2FnZSBzdWJtaXNzaW9uIGFuZCB0cmFuc3BvcnQuIDxwPgorICoKKyAqIFNlZSB0aGUgPGEgaHJlZj0icGFja2FnZS1zdW1tYXJ5Lmh0bWwiPmNvbS5zdW4ubWFpbC5zbXRwPC9hPiBwYWNrYWdlCisgKiBkb2N1bWVudGF0aW9uIGZvciBmdXJ0aGVyIGluZm9ybWF0aW9uIG9uIHRoZSBTTVRQIHByb3RvY29sIHByb3ZpZGVyLiA8cD4KKyAqCisgKiBUaGlzIGNsYXNzIGluY2x1ZGVzIG1hbnkgcHJvdGVjdGVkIG1ldGhvZHMgdGhhdCBhbGxvdyBhIHN1YmNsYXNzIHRvCisgKiBleHRlbmQgdGhpcyBjbGFzcyBhbmQgYWRkIHN1cHBvcnQgZm9yIG5vbi1zdGFuZGFyZCBTTVRQIGNvbW1hbmRzLgorICogVGhlIHtAbGluayAjaXNzdWVDb21tYW5kfSBhbmQge0BsaW5rICNzZW5kQ29tbWFuZH0gbWV0aG9kcyBjYW4gYmUKKyAqIHVzZWQgdG8gc2VuZCBzaW1wbGUgU01UUCBjb21tYW5kcy4gIE90aGVyIG1ldGhvZHMgc3VjaCBhcyB0aGUKKyAqIHtAbGluayAjbWFpbEZyb219IGFuZCB7QGxpbmsgI2RhdGF9IG1ldGhvZHMgY2FuIGJlIG92ZXJyaWRkZW4gdG8KKyAqIGluc2VydCBuZXcgY29tbWFuZHMgYmVmb3JlIG9yIGFmdGVyIHRoZSBjb3JyZXNwb25kaW5nIFNNVFAgY29tbWFuZHMuCisgKiBGb3IgZXhhbXBsZSwgYSBzdWJjbGFzcyBjb3VsZCBkbyB0aGlzIHRvIHNlbmQgdGhlIFhBQ1QgY29tbWFuZAorICogYmVmb3JlIHNlbmRpbmcgdGhlIERBVEEgY29tbWFuZDoKKyAqIDxwcmU+CisgKglwcm90ZWN0ZWQgT3V0cHV0U3RyZWFtIGRhdGEoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKyAqCSAgICBpZiAoc3VwcG9ydHNFeHRlbnNpb24oIlhBQ0NPVU5USU5HIikpCisgKgkgICAgICAgIGlzc3VlQ29tbWFuZCgiWEFDVCIsIDI1KTsKKyAqCSAgICByZXR1cm4gc3VwZXIuZGF0YSgpOworICoJfQorICogPC9wcmU+CisgKgorICogQGF1dGhvciBNYXggU3BpdmFrCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICogQGF1dGhvciBEZWFuIEdpYnNvbiAoRElHRVNULU1ENSBhdXRoZW50aWNhdGlvbikKKyAqIEBhdXRob3IgTHVcdTAwRURzIFNlcnJhbGhlaXJvIChOVExNIGF1dGhlbnRpY2F0aW9uKQorICoKKyAqIEBzZWUgamF2YXgubWFpbC5ldmVudC5Db25uZWN0aW9uRXZlbnQKKyAqIEBzZWUgamF2YXgubWFpbC5ldmVudC5UcmFuc3BvcnRFdmVudAorICovCisKK3B1YmxpYyBjbGFzcyBTTVRQVHJhbnNwb3J0IGV4dGVuZHMgVHJhbnNwb3J0IHsKKworICAgIHByaXZhdGUgU3RyaW5nIG5hbWUgPSAic210cCI7CS8vIE5hbWUgb2YgdGhpcyBwcm90b2NvbAorICAgIHByaXZhdGUgaW50IGRlZmF1bHRQb3J0ID0gMjU7CS8vIGRlZmF1bHQgU01UUCBwb3J0CisgICAgcHJpdmF0ZSBib29sZWFuIGlzU1NMID0gZmFsc2U7CS8vIHVzZSBTU0w/CisgICAgcHJpdmF0ZSBTdHJpbmcgaG9zdDsJCS8vIGhvc3Qgd2UncmUgY29ubmVjdGVkIHRvCisKKyAgICAvLyBGb2xsb3dpbmcgZmllbGRzIHZhbGlkIG9ubHkgZHVyaW5nIHRoZSBzZW5kTWVzc2FnZSBtZXRob2QuCisgICAgcHJpdmF0ZSBNaW1lTWVzc2FnZSBtZXNzYWdlOwkvLyBNZXNzYWdlIHRvIGJlIHNlbnQKKyAgICBwcml2YXRlIEFkZHJlc3NbXSBhZGRyZXNzZXM7CS8vIEFkZHJlc3NlcyB0byB3aGljaCB0byBzZW5kIHRoZSBtc2cKKyAgICAvLyBWYWxpZCBzZW50LCB2YWxpZCB1bnNlbnQgYW5kIGludmFsaWQgYWRkcmVzc2VzCisgICAgcHJpdmF0ZSBBZGRyZXNzW10gdmFsaWRTZW50QWRkciwgdmFsaWRVbnNlbnRBZGRyLCBpbnZhbGlkQWRkcjsKKyAgICAvLyBEaWQgd2Ugc2VuZCB0aGUgbWVzc2FnZSBldmVuIHRob3VnaCBzb21lIGFkZHJlc3NlcyB3ZXJlIGludmFsaWQ/CisgICAgcHJpdmF0ZSBib29sZWFuIHNlbmRQYXJ0aWFsbHlGYWlsZWQgPSBmYWxzZTsKKyAgICAvLyBJZiBzbywgaGVyZSdzIGFuIGV4Y2VwdGlvbiB3ZSBuZWVkIHRvIHRocm93CisgICAgcHJpdmF0ZSBNZXNzYWdpbmdFeGNlcHRpb24gZXhjZXB0aW9uOworICAgIC8vIHN0cmVhbSB3aGVyZSBtZXNzYWdlIGRhdGEgaXMgd3JpdHRlbgorICAgIHByaXZhdGUgU01UUE91dHB1dFN0cmVhbSBkYXRhU3RyZWFtOworCisgICAgLy8gTWFwIG9mIFNNVFAgc2VydmljZSBleHRlbnNpb25zIHN1cHBvcnRlZCBieSBzZXJ2ZXIsIGlmIEVITE8gdXNlZC4KKyAgICBwcml2YXRlIEhhc2h0YWJsZTxTdHJpbmcsIFN0cmluZz4gZXh0TWFwOworCisgICAgcHJpdmF0ZSBNYXA8U3RyaW5nLCBBdXRoZW50aWNhdG9yPiBhdXRoZW50aWNhdG9ycworCSAgICA9IG5ldyBIYXNoTWFwPD4oKTsKKyAgICBwcml2YXRlIFN0cmluZyBkZWZhdWx0QXV0aGVudGljYXRpb25NZWNoYW5pc21zOwkvLyBzZXQgaW4gY29uc3RydWN0b3IKKworICAgIHByaXZhdGUgYm9vbGVhbiBxdWl0V2FpdCA9IGZhbHNlOwkvLyB0cnVlIGlmIHdlIHNob3VsZCB3YWl0CisKKyAgICBwcml2YXRlIFN0cmluZyBzYXNsUmVhbG0gPSBVTktOT1dOOworICAgIHByaXZhdGUgU3RyaW5nIGF1dGhvcml6YXRpb25JRCA9IFVOS05PV047CisgICAgcHJpdmF0ZSBib29sZWFuIGVuYWJsZVNBU0wgPSBmYWxzZTsJLy8gZW5hYmxlIFNBU0wgYXV0aGVudGljYXRpb24KKyAgICBwcml2YXRlIGJvb2xlYW4gdXNlQ2Fub25pY2FsSG9zdE5hbWUgPSBmYWxzZTsgLy8gdXNlIGNhbm9uaWNhbCBob3N0IG5hbWU/CisgICAgcHJpdmF0ZSBTdHJpbmdbXSBzYXNsTWVjaGFuaXNtcyA9IFVOS05PV05fU0E7CisKKyAgICBwcml2YXRlIFN0cmluZyBudGxtRG9tYWluID0gVU5LTk9XTjsgLy8gZm9yIG50bG0gYXV0aGVudGljYXRpb24KKworICAgIHByaXZhdGUgYm9vbGVhbiByZXBvcnRTdWNjZXNzOwkvLyB0aHJvdyBhbiBleGNlcHRpb24gZXZlbiBvbiBzdWNjZXNzCisgICAgcHJpdmF0ZSBib29sZWFuIHVzZVN0YXJ0VExTOwkvLyB1c2UgU1RBUlRUTFMgY29tbWFuZAorICAgIHByaXZhdGUgYm9vbGVhbiByZXF1aXJlU3RhcnRUTFM7CS8vIHJlcXVpcmUgU1RBUlRUTFMgY29tbWFuZAorICAgIHByaXZhdGUgYm9vbGVhbiB1c2VSc2V0OwkJLy8gdXNlIFJTRVQgaW5zdGVhZCBvZiBOT09QCisgICAgcHJpdmF0ZSBib29sZWFuIG5vb3BTdHJpY3QgPSB0cnVlOwkvLyBOT09QIG11c3QgcmV0dXJuIDI1MCBmb3Igc3VjY2VzcworCisgICAgcHJpdmF0ZSBNYWlsTG9nZ2VyIGxvZ2dlcjsJCS8vIGRlYnVnIGxvZ2dlcgorICAgIHByaXZhdGUgTWFpbExvZ2dlciB0cmFjZUxvZ2dlcjsJLy8gcHJvdG9jb2wgdHJhY2UgbG9nZ2VyCisgICAgcHJpdmF0ZSBTdHJpbmcgbG9jYWxIb3N0TmFtZTsJLy8gb3VyIG93biBob3N0IG5hbWUKKyAgICBwcml2YXRlIFN0cmluZyBsYXN0U2VydmVyUmVzcG9uc2U7CS8vIGxhc3QgU01UUCByZXNwb25zZQorICAgIHByaXZhdGUgaW50IGxhc3RSZXR1cm5Db2RlOwkJLy8gbGFzdCBTTVRQIHJldHVybiBjb2RlCisgICAgcHJpdmF0ZSBib29sZWFuIG5vdGlmaWNhdGlvbkRvbmU7CS8vIG9ubHkgbm90aWZ5IG9uY2UgcGVyIHNlbmQKKworICAgIHByaXZhdGUgU2FzbEF1dGhlbnRpY2F0b3Igc2FzbEF1dGhlbnRpY2F0b3I7IC8vIGlmIFNBU0wgaXMgYmVpbmcgdXNlZAorCisgICAgcHJpdmF0ZSBib29sZWFuIG5vYXV0aGRlYnVnID0gdHJ1ZTsJLy8gaGlkZSBhdXRoIGluZm8gaW4gZGVidWcgb3V0cHV0CisgICAgcHJpdmF0ZSBib29sZWFuIGRlYnVndXNlcm5hbWU7CS8vIGluY2x1ZGUgdXNlcm5hbWUgaW4gZGVidWcgb3V0cHV0PworICAgIHByaXZhdGUgYm9vbGVhbiBkZWJ1Z3Bhc3N3b3JkOwkvLyBpbmNsdWRlIHBhc3N3b3JkIGluIGRlYnVnIG91dHB1dD8KKyAgICBwcml2YXRlIGJvb2xlYW4gYWxsb3d1dGY4OwkJLy8gYWxsb3cgVVRGLTggdXNlcm5hbWVzIGFuZCBwYXNzd29yZHM/CisgICAgcHJpdmF0ZSBpbnQgY2h1bmtTaXplOwkJLy8gY2h1bmsgc2l6ZSBpZiBDSFVOS0lORyBzdXBwb3J0ZWQKKworICAgIC8qKiBIZWFkZXJzIHRoYXQgc2hvdWxkIG5vdCBiZSBpbmNsdWRlZCB3aGVuIHNlbmRpbmcgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBpZ25vcmVMaXN0ID0geyAiQmNjIiwgIkNvbnRlbnQtTGVuZ3RoIiB9OworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBDUkxGID0geyAoYnl0ZSknXHInLCAoYnl0ZSknXG4nIH07CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFVOS05PV04gPSAiVU5LTk9XTiI7CS8vIHBsYWNlIGhvbGRlcgorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIFVOS05PV05fU0EgPSBuZXcgU3RyaW5nWzBdOyAvLyBwbGFjZSBob2xkZXIKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yIHRoYXQgdGFrZXMgYSBTZXNzaW9uIG9iamVjdCBhbmQgYSBVUkxOYW1lCisgICAgICogdGhhdCByZXByZXNlbnRzIGEgc3BlY2lmaWMgU01UUCBzZXJ2ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jc2Vzc2lvbgl0aGUgU2Vzc2lvbgorICAgICAqIEBwYXJhbQl1cmxuYW1lCXRoZSBVUkxOYW1lIG9mIHRoaXMgdHJhbnNwb3J0CisgICAgICovCisgICAgcHVibGljIFNNVFBUcmFuc3BvcnQoU2Vzc2lvbiBzZXNzaW9uLCBVUkxOYW1lIHVybG5hbWUpIHsKKwl0aGlzKHNlc3Npb24sIHVybG5hbWUsICJzbXRwIiwgZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yIHVzZWQgYnkgdGhpcyBjbGFzcyBhbmQgYnkgU01UUFNTTFRyYW5zcG9ydCBzdWJjbGFzcy4KKyAgICAgKgorICAgICAqIEBwYXJhbQlzZXNzaW9uCXRoZSBTZXNzaW9uCisgICAgICogQHBhcmFtCXVybG5hbWUJdGhlIFVSTE5hbWUgb2YgdGhpcyB0cmFuc3BvcnQKKyAgICAgKiBAcGFyYW0JbmFtZQl0aGUgcHJvdG9jb2wgbmFtZSBvZiB0aGlzIHRyYW5zcG9ydAorICAgICAqIEBwYXJhbQlpc1NTTAl1c2UgU1NMIHRvIGNvbm5lY3Q/CisgICAgICovCisgICAgcHJvdGVjdGVkIFNNVFBUcmFuc3BvcnQoU2Vzc2lvbiBzZXNzaW9uLCBVUkxOYW1lIHVybG5hbWUsCisJCQkJU3RyaW5nIG5hbWUsIGJvb2xlYW4gaXNTU0wpIHsKKwlzdXBlcihzZXNzaW9uLCB1cmxuYW1lKTsKKwlQcm9wZXJ0aWVzIHByb3BzID0gc2Vzc2lvbi5nZXRQcm9wZXJ0aWVzKCk7CisKKwlsb2dnZXIgPSBuZXcgTWFpbExvZ2dlcih0aGlzLmdldENsYXNzKCksICJERUJVRyBTTVRQIiwKKwkJCQlzZXNzaW9uLmdldERlYnVnKCksIHNlc3Npb24uZ2V0RGVidWdPdXQoKSk7CisJdHJhY2VMb2dnZXIgPSBsb2dnZXIuZ2V0U3ViTG9nZ2VyKCJwcm90b2NvbCIsIG51bGwpOworCW5vYXV0aGRlYnVnID0gIVByb3BVdGlsLmdldEJvb2xlYW5Qcm9wZXJ0eShwcm9wcywKKwkJCSAgICAibWFpbC5kZWJ1Zy5hdXRoIiwgZmFsc2UpOworCWRlYnVndXNlcm5hbWUgPSBQcm9wVXRpbC5nZXRCb29sZWFuUHJvcGVydHkocHJvcHMsCisJCQkibWFpbC5kZWJ1Zy5hdXRoLnVzZXJuYW1lIiwgdHJ1ZSk7CisJZGVidWdwYXNzd29yZCA9IFByb3BVdGlsLmdldEJvb2xlYW5Qcm9wZXJ0eShwcm9wcywKKwkJCSJtYWlsLmRlYnVnLmF1dGgucGFzc3dvcmQiLCBmYWxzZSk7CisJaWYgKHVybG5hbWUgIT0gbnVsbCkKKwkgICAgbmFtZSA9IHVybG5hbWUuZ2V0UHJvdG9jb2woKTsKKwl0aGlzLm5hbWUgPSBuYW1lOworCWlmICghaXNTU0wpCisJICAgIGlzU1NMID0gUHJvcFV0aWwuZ2V0Qm9vbGVhblByb3BlcnR5KHByb3BzLAorCQkJCSJtYWlsLiIgKyBuYW1lICsgIi5zc2wuZW5hYmxlIiwgZmFsc2UpOworCWlmIChpc1NTTCkKKwkgICAgdGhpcy5kZWZhdWx0UG9ydCA9IDQ2NTsKKwllbHNlCisJICAgIHRoaXMuZGVmYXVsdFBvcnQgPSAyNTsKKwl0aGlzLmlzU1NMID0gaXNTU0w7CisKKwkvLyBzZXR0aW5nIG1haWwuc210cC5xdWl0d2FpdCB0byBmYWxzZSBjYXVzZXMgdXMgdG8gbm90IHdhaXQgZm9yIHRoZQorCS8vIHJlc3BvbnNlIGZyb20gdGhlIFFVSVQgY29tbWFuZAorCXF1aXRXYWl0ID0gUHJvcFV0aWwuZ2V0Qm9vbGVhblByb3BlcnR5KHByb3BzLAorCQkJCSJtYWlsLiIgKyBuYW1lICsgIi5xdWl0d2FpdCIsIHRydWUpOworCisJLy8gbWFpbC5zbXRwLnJlcG9ydHN1Y2Nlc3MgY2F1c2VzIHVzIHRvIHRocm93IGFuIGV4Y2VwdGlvbiBvbiBzdWNjZXNzCisJcmVwb3J0U3VjY2VzcyA9IFByb3BVdGlsLmdldEJvb2xlYW5Qcm9wZXJ0eShwcm9wcywKKwkJCQkibWFpbC4iICsgbmFtZSArICIucmVwb3J0c3VjY2VzcyIsIGZhbHNlKTsKKworCS8vIG1haWwuc210cC5zdGFydHRscy5lbmFibGUgZW5hYmxlcyB1c2Ugb2YgU1RBUlRUTFMgY29tbWFuZAorCXVzZVN0YXJ0VExTID0gUHJvcFV0aWwuZ2V0Qm9vbGVhblByb3BlcnR5KHByb3BzLAorCQkJCSJtYWlsLiIgKyBuYW1lICsgIi5zdGFydHRscy5lbmFibGUiLCBmYWxzZSk7CisKKwkvLyBtYWlsLnNtdHAuc3RhcnR0bHMucmVxdWlyZWQgcmVxdWlyZXMgdXNlIG9mIFNUQVJUVExTIGNvbW1hbmQKKwlyZXF1aXJlU3RhcnRUTFMgPSBQcm9wVXRpbC5nZXRCb29sZWFuUHJvcGVydHkocHJvcHMsCisJCQkJIm1haWwuIiArIG5hbWUgKyAiLnN0YXJ0dGxzLnJlcXVpcmVkIiwgZmFsc2UpOworCisJLy8gbWFpbC5zbXRwLnVzZXJzZXQgY2F1c2VzIHVzIHRvIHVzZSBSU0VUIGluc3RlYWQgb2YgTk9PUAorCS8vIGZvciBpc0Nvbm5lY3RlZAorCXVzZVJzZXQgPSBQcm9wVXRpbC5nZXRCb29sZWFuUHJvcGVydHkocHJvcHMsCisJCQkJIm1haWwuIiArIG5hbWUgKyAiLnVzZXJzZXQiLCBmYWxzZSk7CisKKwkvLyBtYWlsLnNtdHAubm9vcC5zdHJpY3QgcmVxdWlyZXMgMjUwIHJlc3BvbnNlIHRvIGluZGljYXRlIHN1Y2Nlc3MKKwlub29wU3RyaWN0ID0gUHJvcFV0aWwuZ2V0Qm9vbGVhblByb3BlcnR5KHByb3BzLAorCQkJCSJtYWlsLiIgKyBuYW1lICsgIi5ub29wLnN0cmljdCIsIHRydWUpOworCisJLy8gY2hlY2sgaWYgU0FTTCBpcyBlbmFibGVkCisJZW5hYmxlU0FTTCA9IFByb3BVdGlsLmdldEJvb2xlYW5Qcm9wZXJ0eShwcm9wcywKKwkgICAgIm1haWwuIiArIG5hbWUgKyAiLnNhc2wuZW5hYmxlIiwgZmFsc2UpOworCWlmIChlbmFibGVTQVNMKQorCSAgICBsb2dnZXIuY29uZmlnKCJlbmFibGUgU0FTTCIpOworCXVzZUNhbm9uaWNhbEhvc3ROYW1lID0gUHJvcFV0aWwuZ2V0Qm9vbGVhblByb3BlcnR5KHByb3BzLAorCSAgICAibWFpbC4iICsgbmFtZSArICIuc2FzbC51c2VjYW5vbmljYWxob3N0bmFtZSIsIGZhbHNlKTsKKwlpZiAodXNlQ2Fub25pY2FsSG9zdE5hbWUpCisJICAgIGxvZ2dlci5jb25maWcoInVzZSBjYW5vbmljYWwgaG9zdCBuYW1lIik7CisKKwlhbGxvd3V0ZjggPSBQcm9wVXRpbC5nZXRCb29sZWFuUHJvcGVydHkocHJvcHMsCisJICAgICJtYWlsLm1pbWUuYWxsb3d1dGY4IiwgZmFsc2UpOworCWlmIChhbGxvd3V0ZjgpCisJICAgIGxvZ2dlci5jb25maWcoImFsbG93IFVURi04Iik7CisKKwljaHVua1NpemUgPSBQcm9wVXRpbC5nZXRJbnRQcm9wZXJ0eShwcm9wcywKKwkgICAgIm1haWwuIiArIG5hbWUgKyAiLmNodW5rc2l6ZSIsIC0xKTsKKwlpZiAoY2h1bmtTaXplID4gMCAmJiBsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5DT05GSUcpKQorCSAgICBsb2dnZXIuY29uZmlnKCJjaHVuayBzaXplICIgKyBjaHVua1NpemUpOworCisJLy8gY3JlYXRlZCBoZXJlLCBiZWNhdXNlIHRoZXkncmUgaW5uZXIgY2xhc3NlcyB0aGF0IHJlZmVyZW5jZSAidGhpcyIKKwlBdXRoZW50aWNhdG9yW10gYSA9IG5ldyBBdXRoZW50aWNhdG9yW10geworCSAgICBuZXcgTG9naW5BdXRoZW50aWNhdG9yKCksCisJICAgIG5ldyBQbGFpbkF1dGhlbnRpY2F0b3IoKSwKKwkgICAgbmV3IERpZ2VzdE1ENUF1dGhlbnRpY2F0b3IoKSwKKwkgICAgbmV3IE50bG1BdXRoZW50aWNhdG9yKCksCisJICAgIG5ldyBPQXV0aDJBdXRoZW50aWNhdG9yKCkKKwl9OworCVN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworCWZvciAoaW50IGkgPSAwOyBpIDwgYS5sZW5ndGg7IGkrKykgeworCSAgICBhdXRoZW50aWNhdG9ycy5wdXQoYVtpXS5nZXRNZWNoYW5pc20oKSwgYVtpXSk7CisJICAgIHNiLmFwcGVuZChhW2ldLmdldE1lY2hhbmlzbSgpKS5hcHBlbmQoJyAnKTsKKwl9CisJZGVmYXVsdEF1dGhlbnRpY2F0aW9uTWVjaGFuaXNtcyA9IHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBuYW1lIG9mIHRoZSBsb2NhbCBob3N0LCBmb3IgdXNlIGluIHRoZSBFSExPIGFuZCBIRUxPIGNvbW1hbmRzLgorICAgICAqIFRoZSBwcm9wZXJ0eSBtYWlsLnNtdHAubG9jYWxob3N0IG92ZXJyaWRlcyBtYWlsLnNtdHAubG9jYWxhZGRyZXNzLAorICAgICAqIHdoaWNoIG92ZXJyaWRlcyB3aGF0IEluZXRBZGRyZXNzIHdvdWxkIHRlbGwgdXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBsb2NhbCBob3N0IG5hbWUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIFN0cmluZyBnZXRMb2NhbEhvc3QoKSB7CisJLy8gZ2V0IG91ciBob3N0bmFtZSBhbmQgY2FjaGUgaXQgZm9yIGZ1dHVyZSB1c2UKKwlpZiAobG9jYWxIb3N0TmFtZSA9PSBudWxsIHx8IGxvY2FsSG9zdE5hbWUubGVuZ3RoKCkgPD0gMCkKKwkgICAgbG9jYWxIb3N0TmFtZSA9CisJCSAgICBzZXNzaW9uLmdldFByb3BlcnR5KCJtYWlsLiIgKyBuYW1lICsgIi5sb2NhbGhvc3QiKTsKKwlpZiAobG9jYWxIb3N0TmFtZSA9PSBudWxsIHx8IGxvY2FsSG9zdE5hbWUubGVuZ3RoKCkgPD0gMCkKKwkgICAgbG9jYWxIb3N0TmFtZSA9CisJCSAgICBzZXNzaW9uLmdldFByb3BlcnR5KCJtYWlsLiIgKyBuYW1lICsgIi5sb2NhbGFkZHJlc3MiKTsKKwl0cnkgeworCSAgICBpZiAobG9jYWxIb3N0TmFtZSA9PSBudWxsIHx8IGxvY2FsSG9zdE5hbWUubGVuZ3RoKCkgPD0gMCkgeworCQlJbmV0QWRkcmVzcyBsb2NhbEhvc3QgPSBJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKTsKKwkJbG9jYWxIb3N0TmFtZSA9IGxvY2FsSG9zdC5nZXRDYW5vbmljYWxIb3N0TmFtZSgpOworCQkvLyBpZiB3ZSBjYW4ndCBnZXQgb3VyIG5hbWUsIHVzZSBsb2NhbCBhZGRyZXNzIGxpdGVyYWwKKwkJaWYgKGxvY2FsSG9zdE5hbWUgPT0gbnVsbCkKKwkJICAgIC8vIFhYWCAtIG5vdCBjb3JyZWN0IGZvciBJUHY2CisJCSAgICBsb2NhbEhvc3ROYW1lID0gIlsiICsgbG9jYWxIb3N0LmdldEhvc3RBZGRyZXNzKCkgKyAiXSI7CisJICAgIH0KKwl9IGNhdGNoIChVbmtub3duSG9zdEV4Y2VwdGlvbiB1aGV4KSB7CisJfQorCisJLy8gbGFzdCBjaGFuY2UsIHRyeSB0byBnZXQgb3VyIGFkZHJlc3MgZnJvbSBvdXIgc29ja2V0CisJaWYgKGxvY2FsSG9zdE5hbWUgPT0gbnVsbCB8fCBsb2NhbEhvc3ROYW1lLmxlbmd0aCgpIDw9IDApIHsKKwkgICAgaWYgKHNlcnZlclNvY2tldCAhPSBudWxsICYmIHNlcnZlclNvY2tldC5pc0JvdW5kKCkpIHsKKwkJSW5ldEFkZHJlc3MgbG9jYWxIb3N0ID0gc2VydmVyU29ja2V0LmdldExvY2FsQWRkcmVzcygpOworCQlsb2NhbEhvc3ROYW1lID0gbG9jYWxIb3N0LmdldENhbm9uaWNhbEhvc3ROYW1lKCk7CisJCS8vIGlmIHdlIGNhbid0IGdldCBvdXIgbmFtZSwgdXNlIGxvY2FsIGFkZHJlc3MgbGl0ZXJhbAorCQlpZiAobG9jYWxIb3N0TmFtZSA9PSBudWxsKQorCQkgICAgLy8gWFhYIC0gbm90IGNvcnJlY3QgZm9yIElQdjYKKwkJICAgIGxvY2FsSG9zdE5hbWUgPSAiWyIgKyBsb2NhbEhvc3QuZ2V0SG9zdEFkZHJlc3MoKSArICJdIjsKKwkgICAgfQorCX0KKwlyZXR1cm4gbG9jYWxIb3N0TmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIG5hbWUgb2YgdGhlIGxvY2FsIGhvc3QsIGZvciB1c2UgaW4gdGhlIEVITE8gYW5kIEhFTE8gY29tbWFuZHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0JbG9jYWxob3N0CXRoZSBsb2NhbCBob3N0IG5hbWUKKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS4zLjEKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgc2V0TG9jYWxIb3N0KFN0cmluZyBsb2NhbGhvc3QpIHsKKwlsb2NhbEhvc3ROYW1lID0gbG9jYWxob3N0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFN0YXJ0IHRoZSBTTVRQIHByb3RvY29sIG9uIHRoZSBnaXZlbiBzb2NrZXQsIHdoaWNoIHdhcyBhbHJlYWR5CisgICAgICogY29ubmVjdGVkIGJ5IHRoZSBjYWxsZXIuICBVc2VmdWwgZm9yIGltcGxlbWVudGluZyB0aGUgU01UUCBBVFJOCisgICAgICogY29tbWFuZCAoUkZDIDI2NDUpIHdoZXJlIGFuIGV4aXN0aW5nIGNvbm5lY3Rpb24gaXMgdXNlZCB3aGVuCisgICAgICogdGhlIHNlcnZlciByZXZlcnNlcyByb2xlcyBhbmQgYmVjb21lcyB0aGUgY2xpZW50LgorICAgICAqCisgICAgICogQHBhcmFtCXNvY2tldAl0aGUgYWxyZWFkeSBjb25uZWN0ZWQgc29ja2V0CisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuMy4zCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGNvbm5lY3QoU29ja2V0IHNvY2tldCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJc2VydmVyU29ja2V0ID0gc29ja2V0OworCXN1cGVyLmNvbm5lY3QoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBhdXRob3JpemF0aW9uIElEIHRvIGJlIHVzZWQgZm9yIGF1dGhlbnRpY2F0aW9uLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgYXV0aG9yaXphdGlvbiBJRCB0byB1c2UgZm9yIGF1dGhlbnRpY2F0aW9uLgorICAgICAqCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNC40CisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBTdHJpbmcgZ2V0QXV0aG9yaXphdGlvbklkKCkgeworCWlmIChhdXRob3JpemF0aW9uSUQgPT0gVU5LTk9XTikgeworCSAgICBhdXRob3JpemF0aW9uSUQgPQorCQlzZXNzaW9uLmdldFByb3BlcnR5KCJtYWlsLiIgKyBuYW1lICsgIi5zYXNsLmF1dGhvcml6YXRpb25pZCIpOworCX0KKwlyZXR1cm4gYXV0aG9yaXphdGlvbklEOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGF1dGhvcml6YXRpb24gSUQgdG8gYmUgdXNlZCBmb3IgYXV0aGVudGljYXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0JYXV0aHppZAkJdGhlIGF1dGhvcml6YXRpb24gSUQgdG8gdXNlIGZvcgorICAgICAqCQkJCWF1dGhlbnRpY2F0aW9uLgorICAgICAqCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNC40CisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHNldEF1dGhvcml6YXRpb25JRChTdHJpbmcgYXV0aHppZCkgeworCXRoaXMuYXV0aG9yaXphdGlvbklEID0gYXV0aHppZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJcyBTQVNMIGF1dGhlbnRpY2F0aW9uIGVuYWJsZWQ/CisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRydWUgaWYgU0FTTCBhdXRoZW50aWNhdGlvbiBpcyBlbmFibGVkCisgICAgICoKKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS40LjQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGJvb2xlYW4gZ2V0U0FTTEVuYWJsZWQoKSB7CisJcmV0dXJuIGVuYWJsZVNBU0w7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHdoZXRoZXIgU0FTTCBhdXRoZW50aWNhdGlvbiBpcyBlbmFibGVkLgorICAgICAqCisgICAgICogQHBhcmFtCWVuYWJsZVNBU0wJc2hvdWxkIHdlIGVuYWJsZSBTQVNMIGF1dGhlbnRpY2F0aW9uPworICAgICAqCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNC40CisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHNldFNBU0xFbmFibGVkKGJvb2xlYW4gZW5hYmxlU0FTTCkgeworCXRoaXMuZW5hYmxlU0FTTCA9IGVuYWJsZVNBU0w7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgU0FTTCByZWFsbSB0byBiZSB1c2VkIGZvciBESUdFU1QtTUQ1IGF1dGhlbnRpY2F0aW9uLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgbmFtZSBvZiB0aGUgcmVhbG0gdG8gdXNlIGZvciBTQVNMIGF1dGhlbnRpY2F0aW9uLgorICAgICAqCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuMy4xCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBTdHJpbmcgZ2V0U0FTTFJlYWxtKCkgeworCWlmIChzYXNsUmVhbG0gPT0gVU5LTk9XTikgeworCSAgICBzYXNsUmVhbG0gPSBzZXNzaW9uLmdldFByb3BlcnR5KCJtYWlsLiIgKyBuYW1lICsgIi5zYXNsLnJlYWxtIik7CisJICAgIGlmIChzYXNsUmVhbG0gPT0gbnVsbCkJLy8gdHJ5IG9sZCBuYW1lCisJCXNhc2xSZWFsbSA9IHNlc3Npb24uZ2V0UHJvcGVydHkoIm1haWwuIiArIG5hbWUgKyAiLnNhc2xyZWFsbSIpOworCX0KKwlyZXR1cm4gc2FzbFJlYWxtOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIFNBU0wgcmVhbG0gdG8gYmUgdXNlZCBmb3IgRElHRVNULU1ENSBhdXRoZW50aWNhdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbQlzYXNsUmVhbG0JdGhlIG5hbWUgb2YgdGhlIHJlYWxtIHRvIHVzZSBmb3IKKyAgICAgKgkJCQlTQVNMIGF1dGhlbnRpY2F0aW9uLgorICAgICAqCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuMy4xCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHNldFNBU0xSZWFsbShTdHJpbmcgc2FzbFJlYWxtKSB7CisJdGhpcy5zYXNsUmVhbG0gPSBzYXNsUmVhbG07CisgICAgfQorCisgICAgLyoqCisgICAgICogU2hvdWxkIFNBU0wgdXNlIHRoZSBjYW5vbmljYWwgaG9zdCBuYW1lPworICAgICAqCisgICAgICogQHJldHVybgl0cnVlIGlmIFNBU0wgc2hvdWxkIHVzZSB0aGUgY2Fub25pY2FsIGhvc3QgbmFtZQorICAgICAqCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNS4yCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIGdldFVzZUNhbm9uaWNhbEhvc3ROYW1lKCkgeworCXJldHVybiB1c2VDYW5vbmljYWxIb3N0TmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgd2hldGhlciBTQVNMIHNob3VsZCB1c2UgdGhlIGNhbm9uaWNhbCBob3N0IG5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0JdXNlQ2Fub25pY2FsSG9zdE5hbWUJc2hvdWxkIFNBU0wgdXNlIHRoZSBjYW5vbmljYWwgaG9zdCBuYW1lPworICAgICAqCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNS4yCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHNldFVzZUNhbm9uaWNhbEhvc3ROYW1lKAorCQkJCQkJYm9vbGVhbiB1c2VDYW5vbmljYWxIb3N0TmFtZSkgeworCXRoaXMudXNlQ2Fub25pY2FsSG9zdE5hbWUgPSB1c2VDYW5vbmljYWxIb3N0TmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGxpc3Qgb2YgU0FTTCBtZWNoYW5pc21zIHRvIGNvbnNpZGVyIGlmIFNBU0wgYXV0aGVudGljYXRpb24KKyAgICAgKiBpcyBlbmFibGVkLiAgSWYgdGhlIGxpc3QgaXMgZW1wdHkgb3IgbnVsbCwgYWxsIGF2YWlsYWJsZSBTQVNMIG1lY2hhbmlzbXMKKyAgICAgKiBhcmUgY29uc2lkZXJlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIGFycmF5IG9mIFNBU0wgbWVjaGFuaXNtcyB0byBjb25zaWRlcgorICAgICAqCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNC40CisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBTdHJpbmdbXSBnZXRTQVNMTWVjaGFuaXNtcygpIHsKKwlpZiAoc2FzbE1lY2hhbmlzbXMgPT0gVU5LTk9XTl9TQSkgeworCSAgICBMaXN0PFN0cmluZz4gdiA9IG5ldyBBcnJheUxpc3Q8Pig1KTsKKwkgICAgU3RyaW5nIHMgPSBzZXNzaW9uLmdldFByb3BlcnR5KCJtYWlsLiIgKyBuYW1lICsgIi5zYXNsLm1lY2hhbmlzbXMiKTsKKwkgICAgaWYgKHMgIT0gbnVsbCAmJiBzLmxlbmd0aCgpID4gMCkgeworCQlpZiAobG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuRklORSkpCisJCSAgICBsb2dnZXIuZmluZSgiU0FTTCBtZWNoYW5pc21zIGFsbG93ZWQ6ICIgKyBzKTsKKwkJU3RyaW5nVG9rZW5pemVyIHN0ID0gbmV3IFN0cmluZ1Rva2VuaXplcihzLCAiICwiKTsKKwkJd2hpbGUgKHN0Lmhhc01vcmVUb2tlbnMoKSkgeworCQkgICAgU3RyaW5nIG0gPSBzdC5uZXh0VG9rZW4oKTsKKwkJICAgIGlmIChtLmxlbmd0aCgpID4gMCkKKwkJCXYuYWRkKG0pOworCQl9CisJICAgIH0KKwkgICAgc2FzbE1lY2hhbmlzbXMgPSBuZXcgU3RyaW5nW3Yuc2l6ZSgpXTsKKwkgICAgdi50b0FycmF5KHNhc2xNZWNoYW5pc21zKTsKKwl9CisJaWYgKHNhc2xNZWNoYW5pc21zID09IG51bGwpCisJICAgIHJldHVybiBudWxsOworCXJldHVybiBzYXNsTWVjaGFuaXNtcy5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgbGlzdCBvZiBTQVNMIG1lY2hhbmlzbXMgdG8gY29uc2lkZXIgaWYgU0FTTCBhdXRoZW50aWNhdGlvbgorICAgICAqIGlzIGVuYWJsZWQuICBJZiB0aGUgbGlzdCBpcyBlbXB0eSBvciBudWxsLCBhbGwgYXZhaWxhYmxlIFNBU0wgbWVjaGFuaXNtcworICAgICAqIGFyZSBjb25zaWRlcmVkLgorICAgICAqCisgICAgICogQHBhcmFtCW1lY2hhbmlzbXMJdGhlIGFycmF5IG9mIFNBU0wgbWVjaGFuaXNtcyB0byBjb25zaWRlcgorICAgICAqCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNC40CisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHNldFNBU0xNZWNoYW5pc21zKFN0cmluZ1tdIG1lY2hhbmlzbXMpIHsKKwlpZiAobWVjaGFuaXNtcyAhPSBudWxsKQorCSAgICBtZWNoYW5pc21zID0gbWVjaGFuaXNtcy5jbG9uZSgpOworCXRoaXMuc2FzbE1lY2hhbmlzbXMgPSBtZWNoYW5pc21zOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIE5UTE0gZG9tYWluIHRvIGJlIHVzZWQgZm9yIE5UTE0gYXV0aGVudGljYXRpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBuYW1lIG9mIHRoZSBkb21haW4gdG8gdXNlIGZvciBOVExNIGF1dGhlbnRpY2F0aW9uLgorICAgICAqCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNC4zCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBTdHJpbmcgZ2V0TlRMTURvbWFpbigpIHsKKwlpZiAobnRsbURvbWFpbiA9PSBVTktOT1dOKSB7CisJICAgIG50bG1Eb21haW4gPQorCQlzZXNzaW9uLmdldFByb3BlcnR5KCJtYWlsLiIgKyBuYW1lICsgIi5hdXRoLm50bG0uZG9tYWluIik7CisJfQorCXJldHVybiBudGxtRG9tYWluOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIE5UTE0gZG9tYWluIHRvIGJlIHVzZWQgZm9yIE5UTE0gYXV0aGVudGljYXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0JbnRsbURvbWFpbgl0aGUgbmFtZSBvZiB0aGUgZG9tYWluIHRvIHVzZSBmb3IKKyAgICAgKgkJCQlOVExNIGF1dGhlbnRpY2F0aW9uLgorICAgICAqCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNC4zCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHNldE5UTE1Eb21haW4oU3RyaW5nIG50bG1Eb21haW4pIHsKKwl0aGlzLm50bG1Eb21haW4gPSBudGxtRG9tYWluOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNob3VsZCB3ZSByZXBvcnQgZXZlbiBzdWNjZXNzZnVsIHNlbmRzIGJ5IHRocm93aW5nIGFuIGV4Y2VwdGlvbj8KKyAgICAgKiBJZiBzbywgYSA8Y29kZT5TZW5kRmFpbGVkRXhjZXB0aW9uPC9jb2RlPiB3aWxsIGFsd2F5cyBiZSB0aHJvd24gYW5kCisgICAgICogYW4ge0BsaW5rIGNvbS5zdW4ubWFpbC5zbXRwLlNNVFBBZGRyZXNzU3VjY2VlZGVkRXhjZXB0aW9uCisgICAgICogU01UUEFkZHJlc3NTdWNjZWVkZWRFeGNlcHRpb259IHdpbGwgYmUgaW5jbHVkZWQgaW4gdGhlIGV4Y2VwdGlvbgorICAgICAqIGNoYWluIGZvciBlYWNoIHN1Y2Nlc3NmdWwgYWRkcmVzcywgYWxvbmcgd2l0aCB0aGUgdXN1YWwKKyAgICAgKiB7QGxpbmsgY29tLnN1bi5tYWlsLnNtdHAuU01UUEFkZHJlc3NGYWlsZWRFeGNlcHRpb24KKyAgICAgKiBTTVRQQWRkcmVzc0ZhaWxlZEV4Y2VwdGlvbn0gZm9yIGVhY2ggdW5zdWNjZXNzZnVsIGFkZHJlc3MuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRydWUgaWYgYW4gZXhjZXB0aW9uIHdpbGwgYmUgdGhyb3duIG9uIHN1Y2Nlc3NmdWwgc2VuZHMuCisgICAgICoKKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS4zLjIKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGJvb2xlYW4gZ2V0UmVwb3J0U3VjY2VzcygpIHsKKwlyZXR1cm4gcmVwb3J0U3VjY2VzczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgd2hldGhlciBzdWNjZXNzZnVsIHNlbmRzIHNob3VsZCBiZSByZXBvcnRlZCBieSB0aHJvd2luZworICAgICAqIGFuIGV4Y2VwdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbQlyZXBvcnRTdWNjZXNzCXNob3VsZCB3ZSB0aHJvdyBhbiBleGNlcHRpb24gb24gc3VjY2Vzcz8KKyAgICAgKgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjMuMgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXRSZXBvcnRTdWNjZXNzKGJvb2xlYW4gcmVwb3J0U3VjY2VzcykgeworCXRoaXMucmVwb3J0U3VjY2VzcyA9IHJlcG9ydFN1Y2Nlc3M7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2hvdWxkIHdlIHVzZSB0aGUgU1RBUlRUTFMgY29tbWFuZCB0byBzZWN1cmUgdGhlIGNvbm5lY3Rpb24KKyAgICAgKiBpZiB0aGUgc2VydmVyIHN1cHBvcnRzIGl0PworICAgICAqCisgICAgICogQHJldHVybgl0cnVlIGlmIHRoZSBTVEFSVFRMUyBjb21tYW5kIHdpbGwgYmUgdXNlZAorICAgICAqCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuMy4yCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIGdldFN0YXJ0VExTKCkgeworCXJldHVybiB1c2VTdGFydFRMUzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgd2hldGhlciB0aGUgU1RBUlRUTFMgY29tbWFuZCBzaG91bGQgYmUgdXNlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbQl1c2VTdGFydFRMUwlzaG91bGQgd2UgdXNlIHRoZSBTVEFSVFRMUyBjb21tYW5kPworICAgICAqCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuMy4yCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHNldFN0YXJ0VExTKGJvb2xlYW4gdXNlU3RhcnRUTFMpIHsKKwl0aGlzLnVzZVN0YXJ0VExTID0gdXNlU3RhcnRUTFM7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2hvdWxkIHdlIHJlcXVpcmUgdGhlIFNUQVJUVExTIGNvbW1hbmQgdG8gc2VjdXJlIHRoZSBjb25uZWN0aW9uPworICAgICAqCisgICAgICogQHJldHVybgl0cnVlIGlmIHRoZSBTVEFSVFRMUyBjb21tYW5kIHdpbGwgYmUgcmVxdWlyZWQKKyAgICAgKgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjQuMgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgYm9vbGVhbiBnZXRSZXF1aXJlU3RhcnRUTFMoKSB7CisJcmV0dXJuIHJlcXVpcmVTdGFydFRMUzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgd2hldGhlciB0aGUgU1RBUlRUTFMgY29tbWFuZCBzaG91bGQgYmUgcmVxdWlyZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0JcmVxdWlyZVN0YXJ0VExTCXNob3VsZCB3ZSByZXF1aXJlIHRoZSBTVEFSVFRMUyBjb21tYW5kPworICAgICAqCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNC4yCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHNldFJlcXVpcmVTdGFydFRMUyhib29sZWFuIHJlcXVpcmVTdGFydFRMUykgeworCXRoaXMucmVxdWlyZVN0YXJ0VExTID0gcmVxdWlyZVN0YXJ0VExTOworICAgIH0KKworICAgIC8qKgorICAgICAqIElzIHRoaXMgVHJhbnNwb3J0IHVzaW5nIFNTTCB0byBjb25uZWN0IHRvIHRoZSBzZXJ2ZXI/CisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRydWUgaWYgdXNpbmcgU1NMCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNC42CisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIGlzU1NMKCkgeworCXJldHVybiBzZXJ2ZXJTb2NrZXQgaW5zdGFuY2VvZiBTU0xTb2NrZXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2hvdWxkIHdlIHVzZSB0aGUgUlNFVCBjb21tYW5kIGluc3RlYWQgb2YgdGhlIE5PT1AgY29tbWFuZAorICAgICAqIGluIHRoZSBAe2xpbmsgI2lzQ29ubmVjdGVkIGlzQ29ubmVjdGVkfSBtZXRob2Q/CisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRydWUgaWYgUlNFVCB3aWxsIGJlIHVzZWQKKyAgICAgKgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGJvb2xlYW4gZ2V0VXNlUnNldCgpIHsKKwlyZXR1cm4gdXNlUnNldDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgd2hldGhlciB0aGUgUlNFVCBjb21tYW5kIHNob3VsZCBiZSB1c2VkIGluc3RlYWQgb2YgdGhlCisgICAgICogTk9PUCBjb21tYW5kIGluIHRoZSBAe2xpbmsgI2lzQ29ubmVjdGVkIGlzQ29ubmVjdGVkfSBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcGFyYW0JdXNlUnNldAlzaG91bGQgd2UgdXNlIHRoZSBSU0VUIGNvbW1hbmQ/CisgICAgICoKKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS40CisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHNldFVzZVJzZXQoYm9vbGVhbiB1c2VSc2V0KSB7CisJdGhpcy51c2VSc2V0ID0gdXNlUnNldDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJcyB0aGUgTk9PUCBjb21tYW5kIHJlcXVpcmVkIHRvIHJldHVybiBhIHJlc3BvbnNlIGNvZGUKKyAgICAgKiBvZiAyNTAgdG8gaW5kaWNhdGUgc3VjY2Vzcz8KKyAgICAgKgorICAgICAqIEByZXR1cm4JdHJ1ZSBpZiBOT09QIG11c3QgcmV0dXJuIDI1MAorICAgICAqCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNC4zCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIGdldE5vb3BTdHJpY3QoKSB7CisJcmV0dXJuIG5vb3BTdHJpY3Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHdoZXRoZXIgdGhlIE5PT1AgY29tbWFuZCBpcyByZXF1aXJlZCB0byByZXR1cm4gYSByZXNwb25zZSBjb2RlCisgICAgICogb2YgMjUwIHRvIGluZGljYXRlIHN1Y2Nlc3MuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jbm9vcFN0cmljdCBpcyBOT09QIHJlcXVpcmVkIHRvIHJldHVybiAyNTA/CisgICAgICoKKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS40LjMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgc2V0Tm9vcFN0cmljdChib29sZWFuIG5vb3BTdHJpY3QpIHsKKwl0aGlzLm5vb3BTdHJpY3QgPSBub29wU3RyaWN0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgbGFzdCByZXNwb25zZSB3ZSBnb3QgZnJvbSB0aGUgc2VydmVyLgorICAgICAqIEEgZmFpbGVkIHNlbmQgaXMgb2Z0ZW4gZm9sbG93ZWQgYnkgYW4gUlNFVCBjb21tYW5kLAorICAgICAqIGJ1dCB0aGUgcmVzcG9uc2UgZnJvbSB0aGUgUlNFVCBjb21tYW5kIGlzIG5vdCBzYXZlZC4KKyAgICAgKiBJbnN0ZWFkLCB0aGlzIHJldHVybnMgdGhlIHJlc3BvbnNlIGZyb20gdGhlIGNvbW1hbmQKKyAgICAgKiBiZWZvcmUgdGhlIFJTRVQgY29tbWFuZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4JbGFzdCByZXNwb25zZSBmcm9tIHNlcnZlcgorICAgICAqCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuMy4yCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBTdHJpbmcgZ2V0TGFzdFNlcnZlclJlc3BvbnNlKCkgeworCXJldHVybiBsYXN0U2VydmVyUmVzcG9uc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSByZXR1cm4gY29kZSBmcm9tIHRoZSBsYXN0IHJlc3BvbnNlIHdlIGdvdCBmcm9tIHRoZSBzZXJ2ZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXJldHVybiBjb2RlIGZyb20gbGFzdCByZXNwb25zZSBmcm9tIHNlcnZlcgorICAgICAqCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNC4xCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBpbnQgZ2V0TGFzdFJldHVybkNvZGUoKSB7CisJcmV0dXJuIGxhc3RSZXR1cm5Db2RlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIHRoZSBhY3R1YWwgcHJvdG9jb2wtc3BlY2lmaWMgY29ubmVjdGlvbiBhdHRlbXB0LgorICAgICAqIFdpbGwgYXR0ZW1wdCB0byBjb25uZWN0IHRvICJsb2NhbGhvc3QiIGlmIHRoZSBob3N0IHdhcyBudWxsLiA8cD4KKyAgICAgKgorICAgICAqIFVubGVzcyBtYWlsLnNtdHAuZWhsbyBpcyBzZXQgdG8gZmFsc2UsIHdlJ2xsIHRyeSB0byBpZGVudGlmeQorICAgICAqIG91cnNlbHZlcyB1c2luZyB0aGUgRVNNVFAgY29tbWFuZCBFSExPLgorICAgICAqCisgICAgICogSWYgbWFpbC5zbXRwLmF1dGggaXMgc2V0IHRvIHRydWUsIHdlIGluc2lzdCBvbiBoYXZpbmcgYSB1c2VybmFtZQorICAgICAqIGFuZCBwYXNzd29yZCwgYW5kIHdpbGwgdHJ5IHRvIGF1dGhlbnRpY2F0ZSBvdXJzZWx2ZXMgaWYgdGhlIHNlcnZlcgorICAgICAqIHN1cHBvcnRzIHRoZSBBVVRIIGV4dGVuc2lvbiAoUkZDIDI1NTQpLgorICAgICAqCisgICAgICogQHBhcmFtCWhvc3QJCSAgdGhlIG5hbWUgb2YgdGhlIGhvc3QgdG8gY29ubmVjdCB0bworICAgICAqIEBwYXJhbQlwb3J0CQkgIHRoZSBwb3J0IHRvIHVzZSAoLTEgbWVhbnMgdXNlIGRlZmF1bHQgcG9ydCkKKyAgICAgKiBAcGFyYW0JdXNlcgkJICB0aGUgbmFtZSBvZiB0aGUgdXNlciB0byBsb2dpbiBhcworICAgICAqIEBwYXJhbQlwYXNzd29yZAkgIHRoZSB1c2VyJ3MgcGFzc3dvcmQKKyAgICAgKiBAcmV0dXJuCXRydWUgaWYgY29ubmVjdGlvbiBzdWNjZXNzZnVsLCBmYWxzZSBpZiBhdXRoZW50aWNhdGlvbiBmYWlsZWQKKyAgICAgKiBAZXhjZXB0aW9uIE1lc3NhZ2luZ0V4Y2VwdGlvbglmb3Igbm9uLWF1dGhlbnRpY2F0aW9uIGZhaWx1cmVzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHN5bmNocm9uaXplZCBib29sZWFuIHByb3RvY29sQ29ubmVjdChTdHJpbmcgaG9zdCwgaW50IHBvcnQsCisJCQkJU3RyaW5nIHVzZXIsIFN0cmluZyBwYXNzd29yZCkKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlQcm9wZXJ0aWVzIHByb3BzID0gc2Vzc2lvbi5nZXRQcm9wZXJ0aWVzKCk7CisKKwkvLyBzZXR0aW5nIG1haWwuc210cC5hdXRoIHRvIHRydWUgZW5hYmxlcyBhdHRlbXB0cyB0byB1c2UgQVVUSAorCWJvb2xlYW4gdXNlQXV0aCA9IFByb3BVdGlsLmdldEJvb2xlYW5Qcm9wZXJ0eShwcm9wcywKKwkJCQkJIm1haWwuIiArIG5hbWUgKyAiLmF1dGgiLCBmYWxzZSk7CisKKwkvKgorCSAqIElmIG1haWwuc210cC5hdXRoIGlzIHNldCwgbWFrZSBzdXJlIHdlIGhhdmUgYSB2YWxpZCB1c2VybmFtZQorCSAqIGFuZCBwYXNzd29yZCwgZXZlbiBpZiB3ZSBtaWdodCBub3QgZW5kIHVwIHVzaW5nIGl0IChlLmcuLAorCSAqIGJlY2F1c2UgdGhlIHNlcnZlciBkb2Vzbid0IHN1cHBvcnQgRVNNVFAgb3IgZG9lc24ndCBzdXBwb3J0CisJICogdGhlIEFVVEggZXh0ZW5zaW9uKS4KKwkgKi8KKwlpZiAodXNlQXV0aCAmJiAodXNlciA9PSBudWxsIHx8IHBhc3N3b3JkID09IG51bGwpKSB7CisJICAgIGlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FKSkgeworCQlsb2dnZXIuZmluZSgibmVlZCB1c2VybmFtZSBhbmQgcGFzc3dvcmQgZm9yIGF1dGhlbnRpY2F0aW9uIik7CisJCWxvZ2dlci5maW5lKCJwcm90b2NvbENvbm5lY3QgcmV0dXJuaW5nIGZhbHNlIiArCisJCQkJIiwgaG9zdD0iICsgaG9zdCArCisJCQkJIiwgdXNlcj0iICsgdHJhY2VVc2VyKHVzZXIpICsKKwkJCQkiLCBwYXNzd29yZD0iICsgdHJhY2VQYXNzd29yZChwYXNzd29yZCkpOworCSAgICB9CisJICAgIHJldHVybiBmYWxzZTsKKwl9CisKKwkvLyBzZXR0aW5nIG1haWwuc210cC5laGxvIHRvIGZhbHNlIGRpc2FibGVzIGF0dGVtcHRzIHRvIHVzZSBFSExPCisJYm9vbGVhbiB1c2VFaGxvID0gIFByb3BVdGlsLmdldEJvb2xlYW5Qcm9wZXJ0eShwcm9wcywKKwkJCQkJIm1haWwuIiArIG5hbWUgKyAiLmVobG8iLCB0cnVlKTsKKwlpZiAobG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuRklORSkpCisJICAgIGxvZ2dlci5maW5lKCJ1c2VFaGxvICIgKyB1c2VFaGxvICsgIiwgdXNlQXV0aCAiICsgdXNlQXV0aCk7CisKKwkvKgorCSAqIElmIHBvcnQgaXMgbm90IHNwZWNpZmllZCwgc2V0IGl0IHRvIHZhbHVlIG9mIG1haWwuc210cC5wb3J0CisgICAgICAgICAqIHByb3BlcnR5IGlmIGl0IGV4aXN0cywgb3RoZXJ3aXNlIGRlZmF1bHQgdG8gMjUuCisJICovCisgICAgICAgIGlmIChwb3J0ID09IC0xKQorCSAgICBwb3J0ID0gUHJvcFV0aWwuZ2V0SW50UHJvcGVydHkocHJvcHMsCisJCQkJCSJtYWlsLiIgKyBuYW1lICsgIi5wb3J0IiwgLTEpOworICAgICAgICBpZiAocG9ydCA9PSAtMSkKKwkgICAgcG9ydCA9IGRlZmF1bHRQb3J0OworCisJaWYgKGhvc3QgPT0gbnVsbCB8fCBob3N0Lmxlbmd0aCgpID09IDApCisJICAgIGhvc3QgPSAibG9jYWxob3N0IjsKKworCS8qCisJICogSWYgYW55dGhpbmcgZ29lcyB3cm9uZywgd2UgbmVlZCB0byBiZSBzdXJlCisJICogdG8gY2xvc2UgdGhlIGNvbm5lY3Rpb24uCisJICovCisJYm9vbGVhbiBjb25uZWN0ZWQgPSBmYWxzZTsKKwl0cnkgeworCisJICAgIGlmIChzZXJ2ZXJTb2NrZXQgIT0gbnVsbCkKKwkJb3BlblNlcnZlcigpOwkvLyBvbmx5IGhhcHBlbnMgZnJvbSBjb25uZWN0KHNvY2tldCkKKwkgICAgZWxzZQorCQlvcGVuU2VydmVyKGhvc3QsIHBvcnQpOworCisJICAgIGJvb2xlYW4gc3VjY2VlZCA9IGZhbHNlOworCSAgICBpZiAodXNlRWhsbykKKwkJc3VjY2VlZCA9IGVobG8oZ2V0TG9jYWxIb3N0KCkpOworCSAgICBpZiAoIXN1Y2NlZWQpCisJCWhlbG8oZ2V0TG9jYWxIb3N0KCkpOworCisJICAgIGlmICh1c2VTdGFydFRMUyB8fCByZXF1aXJlU3RhcnRUTFMpIHsKKwkJaWYgKHNlcnZlclNvY2tldCBpbnN0YW5jZW9mIFNTTFNvY2tldCkgeworCQkgICAgbG9nZ2VyLmZpbmUoIlNUQVJUVExTIHJlcXVlc3RlZCBidXQgYWxyZWFkeSB1c2luZyBTU0wiKTsKKwkJfSBlbHNlIGlmIChzdXBwb3J0c0V4dGVuc2lvbigiU1RBUlRUTFMiKSkgeworCQkgICAgc3RhcnRUTFMoKTsKKwkJICAgIC8qCisJCSAgICAgKiBIYXZlIHRvIGlzc3VlIGFub3RoZXIgRUhMTyB0byB1cGRhdGUgbGlzdCBvZiBleHRlbnNpb25zCisJCSAgICAgKiBzdXBwb3J0ZWQsIGVzcGVjaWFsbHkgYXV0aGVudGljYXRpb24gbWVjaGFuaXNtcy4KKwkJICAgICAqIERvbid0IGtub3cgaWYgdGhpcyBjb3VsZCBldmVyIGZhaWwsIGJ1dCB3ZSBpZ25vcmUKKwkJICAgICAqIGZhaWx1cmUuCisJCSAgICAgKi8KKwkJICAgIGVobG8oZ2V0TG9jYWxIb3N0KCkpOworCQl9IGVsc2UgaWYgKHJlcXVpcmVTdGFydFRMUykgeworCQkgICAgbG9nZ2VyLmZpbmUoIlNUQVJUVExTIHJlcXVpcmVkIGJ1dCBub3Qgc3VwcG9ydGVkIik7CisJCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKAorCQkJIlNUQVJUVExTIGlzIHJlcXVpcmVkIGJ1dCAiICsKKwkJCSJob3N0IGRvZXMgbm90IHN1cHBvcnQgU1RBUlRUTFMiKTsKKwkJfQorCSAgICB9CisKKwkgICAgaWYgKGFsbG93dXRmOCAmJiAhc3VwcG9ydHNFeHRlbnNpb24oIlNNVFBVVEY4IikpCisJCWxvZ2dlci5sb2coTGV2ZWwuSU5GTywgIm1haWwubWltZS5hbGxvd3V0Zjggc2V0ICIgKworCQkJICAgICJidXQgc2VydmVyIGRvZXNuJ3QgYWR2ZXJ0aXNlIFNNVFBVVEY4IHN1cHBvcnQiKTsKKworCSAgICBpZiAoKHVzZUF1dGggfHwgKHVzZXIgIT0gbnVsbCAmJiBwYXNzd29yZCAhPSBudWxsKSkgJiYKKwkJICAoc3VwcG9ydHNFeHRlbnNpb24oIkFVVEgiKSB8fAorCQkgICBzdXBwb3J0c0V4dGVuc2lvbigiQVVUSD1MT0dJTiIpKSkgeworCQlpZiAobG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuRklORSkpCisJCSAgICBsb2dnZXIuZmluZSgicHJvdG9jb2xDb25uZWN0IGxvZ2luIiArCisJCQkJIiwgaG9zdD0iICsgaG9zdCArCisJCQkJIiwgdXNlcj0iICsgdHJhY2VVc2VyKHVzZXIpICsKKwkJCQkiLCBwYXNzd29yZD0iICsgdHJhY2VQYXNzd29yZChwYXNzd29yZCkpOworCQljb25uZWN0ZWQgPSBhdXRoZW50aWNhdGUodXNlciwgcGFzc3dvcmQpOworCQlyZXR1cm4gY29ubmVjdGVkOworCSAgICB9CisKKwkgICAgLy8gd2UgY29ubmVjdGVkIGNvcnJlY3RseQorCSAgICBjb25uZWN0ZWQgPSB0cnVlOworCSAgICByZXR1cm4gdHJ1ZTsKKworCX0gZmluYWxseSB7CisJICAgIC8vIGlmIHdlIGRpZG4ndCBjb25uZWN0IHN1Y2Nlc3NmdWxseSwKKwkgICAgLy8gbWFrZSBzdXJlIHRoZSBjb25uZWN0aW9uIGlzIGNsb3NlZAorCSAgICBpZiAoIWNvbm5lY3RlZCkgeworCQl0cnkgeworCQkgICAgY2xvc2VDb25uZWN0aW9uKCk7CisJCX0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBtZXgpIHsKKwkJICAgIC8vIGlnbm9yZSBpdAorCQl9CisJICAgIH0KKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogQXV0aGVudGljYXRlIHRvIHRoZSBzZXJ2ZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGF1dGhlbnRpY2F0ZShTdHJpbmcgdXNlciwgU3RyaW5nIHBhc3N3ZCkKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwkvLyBzZXR0aW5nIG1haWwuc210cC5hdXRoLm1lY2hhbmlzbXMgY29udHJvbHMgd2hpY2ggbWVjaGFuaXNtcyB3aWxsCisJLy8gYmUgdXNlZCwgYW5kIGluIHdoYXQgb3JkZXIgdGhleSdsbCBiZSBjb25zaWRlcmVkLiAgb25seSB0aGUgZmlyc3QKKwkvLyBtYXRjaCBpcyB1c2VkLgorCVN0cmluZyBtZWNocyA9IHNlc3Npb24uZ2V0UHJvcGVydHkoIm1haWwuIiArIG5hbWUgKyAiLmF1dGgubWVjaGFuaXNtcyIpOworCWlmIChtZWNocyA9PSBudWxsKQorCSAgICBtZWNocyA9IGRlZmF1bHRBdXRoZW50aWNhdGlvbk1lY2hhbmlzbXM7CisKKwlTdHJpbmcgYXV0aHppZCA9IGdldEF1dGhvcml6YXRpb25JZCgpOworCWlmIChhdXRoemlkID09IG51bGwpCisJICAgIGF1dGh6aWQgPSB1c2VyOworCWlmIChlbmFibGVTQVNMKSB7CisJICAgIGxvZ2dlci5maW5lKCJBdXRoZW50aWNhdGUgd2l0aCBTQVNMIik7CisJICAgIHRyeSB7CisJCWlmIChzYXNsbG9naW4oZ2V0U0FTTE1lY2hhbmlzbXMoKSwgZ2V0U0FTTFJlYWxtKCksIGF1dGh6aWQsCisJCQkJdXNlciwgcGFzc3dkKSkgeworCQkgICAgcmV0dXJuIHRydWU7CS8vIHN1Y2Nlc3MKKwkJfSBlbHNlIHsKKwkJICAgIGxvZ2dlci5maW5lKCJTQVNMIGF1dGhlbnRpY2F0aW9uIGZhaWxlZCIpOworCQkgICAgcmV0dXJuIGZhbHNlOworCQl9CisJICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGV4KSB7CisJCWxvZ2dlci5sb2coTGV2ZWwuRklORSwgIlNBU0wgc3VwcG9ydCBmYWlsZWQiLCBleCk7CisJCS8vIGlmIHRoZSBTQVNMIHN1cHBvcnQgZmFpbHMsIGZhbGwgYmFjayB0byBub24tU0FTTAorCSAgICB9CisJfQorCisJaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkUpKQorCSAgICBsb2dnZXIuZmluZSgiQXR0ZW1wdCB0byBhdXRoZW50aWNhdGUgdXNpbmcgbWVjaGFuaXNtczogIiArIG1lY2hzKTsKKworCS8qCisJICogTG9vcCB0aHJvdWdoIHRoZSBsaXN0IG9mIG1lY2hhbmlzbXMgc3VwcGxpZWQgYnkgdGhlIHVzZXIKKwkgKiAob3IgZGVmYXVsdGVkKSBhbmQgdHJ5IGVhY2ggaW4gdHVybi4gIElmIHRoZSBzZXJ2ZXIgc3VwcG9ydHMKKwkgKiB0aGUgbWVjaGFuaXNtIGFuZCB3ZSBoYXZlIGFuIGF1dGhlbnRpY2F0b3IgZm9yIHRoZSBtZWNoYW5pc20sCisJICogYW5kIGl0IGhhc24ndCBiZWVuIGRpc2FibGVkLCB1c2UgaXQuCisJICovCisJU3RyaW5nVG9rZW5pemVyIHN0ID0gbmV3IFN0cmluZ1Rva2VuaXplcihtZWNocyk7CisJd2hpbGUgKHN0Lmhhc01vcmVUb2tlbnMoKSkgeworCSAgICBTdHJpbmcgbSA9IHN0Lm5leHRUb2tlbigpOworCSAgICBtID0gbS50b1VwcGVyQ2FzZShMb2NhbGUuRU5HTElTSCk7CisJICAgIEF1dGhlbnRpY2F0b3IgYSA9IGF1dGhlbnRpY2F0b3JzLmdldChtKTsKKwkgICAgaWYgKGEgPT0gbnVsbCkgeworCQlsb2dnZXIubG9nKExldmVsLkZJTkUsICJubyBhdXRoZW50aWNhdG9yIGZvciBtZWNoYW5pc20gezB9IiwgbSk7CisJCWNvbnRpbnVlOworCSAgICB9CisKKwkgICAgaWYgKCFzdXBwb3J0c0F1dGhlbnRpY2F0aW9uKG0pKSB7CisJCWxvZ2dlci5sb2coTGV2ZWwuRklORSwgIm1lY2hhbmlzbSB7MH0gbm90IHN1cHBvcnRlZCBieSBzZXJ2ZXIiLAorCQkJCQltKTsKKwkJY29udGludWU7CisJICAgIH0KKworCSAgICAvKgorCSAgICAgKiBJZiB1c2luZyB0aGUgZGVmYXVsdCBtZWNoYW5pc21zLCBjaGVjayBpZiB0aGlzIG9uZSBpcyBkaXNhYmxlZC4KKwkgICAgICovCisJICAgIGlmIChtZWNocyA9PSBkZWZhdWx0QXV0aGVudGljYXRpb25NZWNoYW5pc21zKSB7CisJCVN0cmluZyBkcHJvcCA9ICJtYWlsLiIgKyBuYW1lICsgIi5hdXRoLiIgKworCQkJCSAgICBtLnRvTG93ZXJDYXNlKExvY2FsZS5FTkdMSVNIKSArICIuZGlzYWJsZSI7CisJCWJvb2xlYW4gZGlzYWJsZWQgPSBQcm9wVXRpbC5nZXRCb29sZWFuUHJvcGVydHkoCisJCQkJCQlzZXNzaW9uLmdldFByb3BlcnRpZXMoKSwKKwkJCQkJCWRwcm9wLCAhYS5lbmFibGVkKCkpOworCQlpZiAoZGlzYWJsZWQpIHsKKwkJICAgIGlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FKSkKKwkJCWxvZ2dlci5maW5lKCJtZWNoYW5pc20gIiArIG0gKworCQkJCQkiIGRpc2FibGVkIGJ5IHByb3BlcnR5OiAiICsgZHByb3ApOworCQkgICAgY29udGludWU7CisJCX0KKwkgICAgfQorCisJICAgIC8vIG9ubHkgdGhlIGZpcnN0IHN1cHBvcnRlZCBhbmQgZW5hYmxlZCBtZWNoYW5pc20gaXMgdXNlZAorCSAgICBsb2dnZXIubG9nKExldmVsLkZJTkUsICJVc2luZyBtZWNoYW5pc20gezB9IiwgbSk7CisJICAgIHJldHVybiBhLmF1dGhlbnRpY2F0ZShob3N0LCBhdXRoemlkLCB1c2VyLCBwYXNzd2QpOworCX0KKworCS8vIGlmIG5vIGF1dGhlbnRpY2F0aW9uIG1lY2hhbmlzbSBmb3VuZCwgZmFpbAorCXRocm93IG5ldyBBdXRoZW50aWNhdGlvbkZhaWxlZEV4Y2VwdGlvbigKKwkgICAgIk5vIGF1dGhlbnRpY2F0aW9uIG1lY2hhbmlzbXMgc3VwcG9ydGVkIGJ5IGJvdGggc2VydmVyIGFuZCBjbGllbnQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBYnN0cmFjdCBiYXNlIGNsYXNzIGZvciBTTVRQIGF1dGhlbnRpY2F0aW9uIG1lY2hhbmlzbSBpbXBsZW1lbnRhdGlvbnMuCisgICAgICovCisgICAgcHJpdmF0ZSBhYnN0cmFjdCBjbGFzcyBBdXRoZW50aWNhdG9yIHsKKwlwcm90ZWN0ZWQgaW50IHJlc3A7CS8vIHRoZSByZXNwb25zZSBjb2RlLCB1c2VkIGJ5IHN1YmNsYXNzZXMKKwlwcml2YXRlIGZpbmFsIFN0cmluZyBtZWNoOyAvLyB0aGUgbWVjaGFuaXNtIG5hbWUsIHNldCBpbiB0aGUgY29uc3RydWN0b3IKKwlwcml2YXRlIGZpbmFsIGJvb2xlYW4gZW5hYmxlZDsgLy8gaXMgdGhpcyBtZWNoYW5pc20gZW5hYmxlZCBieSBkZWZhdWx0PworCisJQXV0aGVudGljYXRvcihTdHJpbmcgbWVjaCkgeworCSAgICB0aGlzKG1lY2gsIHRydWUpOworCX0KKworCUF1dGhlbnRpY2F0b3IoU3RyaW5nIG1lY2gsIGJvb2xlYW4gZW5hYmxlZCkgeworCSAgICB0aGlzLm1lY2ggPSBtZWNoLnRvVXBwZXJDYXNlKExvY2FsZS5FTkdMSVNIKTsKKwkgICAgdGhpcy5lbmFibGVkID0gZW5hYmxlZDsKKwl9CisKKwlTdHJpbmcgZ2V0TWVjaGFuaXNtKCkgeworCSAgICByZXR1cm4gbWVjaDsKKwl9CisKKwlib29sZWFuIGVuYWJsZWQoKSB7CisJICAgIHJldHVybiBlbmFibGVkOworCX0KKworCS8qKgorCSAqIFN0YXJ0IHRoZSBhdXRoZW50aWNhdGlvbiBoYW5kc2hha2UgYnkgaXNzdWluZyB0aGUgQVVUSCBjb21tYW5kLgorCSAqIERlbGVnYXRlIHRvIHRoZSBkb0F1dGggbWV0aG9kIHRvIGRvIHRoZSBtZWNoYW5pc20tc3BlY2lmaWMKKwkgKiBwYXJ0IG9mIHRoZSBoYW5kc2hha2UuCisJICovCisJYm9vbGVhbiBhdXRoZW50aWNhdGUoU3RyaW5nIGhvc3QsIFN0cmluZyBhdXRoemlkLAorCQkJU3RyaW5nIHVzZXIsIFN0cmluZyBwYXNzd2QpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCSAgICBUaHJvd2FibGUgdGhyb3duID0gbnVsbDsKKwkgICAgdHJ5IHsKKwkJLy8gdXNlICJpbml0aWFsIHJlc3BvbnNlIiBjYXBhYmlsaXR5LCBpZiBzdXBwb3J0ZWQKKwkJU3RyaW5nIGlyID0gZ2V0SW5pdGlhbFJlc3BvbnNlKGhvc3QsIGF1dGh6aWQsIHVzZXIsIHBhc3N3ZCk7CisJCWlmIChub2F1dGhkZWJ1ZyAmJiBpc1RyYWNpbmcoKSkgeworCQkgICAgbG9nZ2VyLmZpbmUoIkFVVEggIiArIG1lY2ggKyAiIGNvbW1hbmQgdHJhY2Ugc3VwcHJlc3NlZCIpOworCQkgICAgc3VzcGVuZFRyYWNpbmcoKTsKKwkJfQorCQlpZiAoaXIgIT0gbnVsbCkKKwkJICAgIHJlc3AgPSBzaW1wbGVDb21tYW5kKCJBVVRIICIgKyBtZWNoICsgIiAiICsKKwkJCQkJICAgIChpci5sZW5ndGgoKSA9PSAwID8gIj0iIDogaXIpKTsKKwkJZWxzZQorCQkgICAgcmVzcCA9IHNpbXBsZUNvbW1hbmQoIkFVVEggIiArIG1lY2gpOworCisJCS8qCisJCSAqIEEgNTMwIHJlc3BvbnNlIGluZGljYXRlcyB0aGF0IHRoZSBzZXJ2ZXIgd2FudHMgdXMgdG8KKwkJICogaXNzdWUgYSBTVEFSVFRMUyBjb21tYW5kIGZpcnN0LiAgRG8gdGhhdCBhbmQgdHJ5IGFnYWluLgorCQkgKi8KKwkJaWYgKHJlc3AgPT0gNTMwKSB7CisJCSAgICBzdGFydFRMUygpOworCQkgICAgaWYgKGlyICE9IG51bGwpCisJCQlyZXNwID0gc2ltcGxlQ29tbWFuZCgiQVVUSCAiICsgbWVjaCArICIgIiArIGlyKTsKKwkJICAgIGVsc2UKKwkJCXJlc3AgPSBzaW1wbGVDb21tYW5kKCJBVVRIICIgKyBtZWNoKTsKKwkJfQorCQlpZiAocmVzcCA9PSAzMzQpCisJCSAgICBkb0F1dGgoaG9zdCwgYXV0aHppZCwgdXNlciwgcGFzc3dkKTsKKwkgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsJLy8gc2hvdWxkIG5ldmVyIGhhcHBlbiwgaWdub3JlCisJCWxvZ2dlci5sb2coTGV2ZWwuRklORSwgIkFVVEggIiArIG1lY2ggKyAiIGZhaWxlZCIsIGV4KTsKKwkgICAgfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsJLy8gY3J5cHRvIGNhbid0IGJlIGluaXRpYWxpemVkPworCQlsb2dnZXIubG9nKExldmVsLkZJTkUsICJBVVRIICIgKyBtZWNoICsgIiBmYWlsZWQiLCB0KTsKKwkJdGhyb3duID0gdDsKKwkgICAgfSBmaW5hbGx5IHsKKwkJaWYgKG5vYXV0aGRlYnVnICYmIGlzVHJhY2luZygpKQorCQkgICAgbG9nZ2VyLmZpbmUoIkFVVEggIiArIG1lY2ggKyAiICIgKworCQkJCSAgICAocmVzcCA9PSAyMzUgPyAic3VjY2VlZGVkIiA6ICJmYWlsZWQiKSk7CisJCXJlc3VtZVRyYWNpbmcoKTsKKwkJaWYgKHJlc3AgIT0gMjM1KSB7CisJCSAgICBjbG9zZUNvbm5lY3Rpb24oKTsKKwkJICAgIGlmICh0aHJvd24gIT0gbnVsbCkgeworCQkJaWYgKHRocm93biBpbnN0YW5jZW9mIEVycm9yKQorCQkJICAgIHRocm93IChFcnJvcil0aHJvd247CisJCQlpZiAodGhyb3duIGluc3RhbmNlb2YgRXhjZXB0aW9uKQorCQkJICAgIHRocm93IG5ldyBBdXRoZW50aWNhdGlvbkZhaWxlZEV4Y2VwdGlvbigKKwkJCQkJICAgIGdldExhc3RTZXJ2ZXJSZXNwb25zZSgpLAorCQkJCQkgICAgKEV4Y2VwdGlvbil0aHJvd24pOworCQkJYXNzZXJ0IGZhbHNlIDogInVua25vd24gVGhyb3dhYmxlIjsJLy8gY2FuJ3QgaGFwcGVuCisJCSAgICB9CisJCSAgICB0aHJvdyBuZXcgQXV0aGVudGljYXRpb25GYWlsZWRFeGNlcHRpb24oCisJCQkJCSAgICBnZXRMYXN0U2VydmVyUmVzcG9uc2UoKSk7CisJCX0KKwkgICAgfQorCSAgICByZXR1cm4gdHJ1ZTsKKwl9CisKKwkvKioKKwkgKiBQcm92aWRlIHRoZSBpbml0aWFsIHJlc3BvbnNlIHRvIHVzZSBpbiB0aGUgQVVUSCBjb21tYW5kLAorCSAqIG9yIG51bGwgaWYgbm90IHN1cHBvcnRlZC4gIFN1YmNsYXNzZXMgdGhhdCBzdXBwb3J0IHRoZQorCSAqIGluaXRpYWwgcmVzcG9uc2UgY2FwYWJpbGl0eSB3aWxsIG92ZXJyaWRlIHRoaXMgbWV0aG9kLgorCSAqLworCVN0cmluZyBnZXRJbml0aWFsUmVzcG9uc2UoU3RyaW5nIGhvc3QsIFN0cmluZyBhdXRoemlkLCBTdHJpbmcgdXNlciwKKwkJICAgIFN0cmluZyBwYXNzd2QpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKwkgICAgcmV0dXJuIG51bGw7CisJfQorCisJYWJzdHJhY3Qgdm9pZCBkb0F1dGgoU3RyaW5nIGhvc3QsIFN0cmluZyBhdXRoemlkLCBTdHJpbmcgdXNlciwKKwkJICAgIFN0cmluZyBwYXNzd2QpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24sIElPRXhjZXB0aW9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm0gdGhlIGF1dGhlbnRpY2F0aW9uIGhhbmRzaGFrZSBmb3IgTE9HSU4gYXV0aGVudGljYXRpb24uCisgICAgICovCisgICAgcHJpdmF0ZSBjbGFzcyBMb2dpbkF1dGhlbnRpY2F0b3IgZXh0ZW5kcyBBdXRoZW50aWNhdG9yIHsKKwlMb2dpbkF1dGhlbnRpY2F0b3IoKSB7CisJICAgIHN1cGVyKCJMT0dJTiIpOworCX0KKworCUBPdmVycmlkZQorCXZvaWQgZG9BdXRoKFN0cmluZyBob3N0LCBTdHJpbmcgYXV0aHppZCwgU3RyaW5nIHVzZXIsIFN0cmluZyBwYXNzd2QpCisJCQkJICAgIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKwkgICAgLy8gc2VuZCB1c2VybmFtZQorCSAgICByZXNwID0gc2ltcGxlQ29tbWFuZChCQVNFNjRFbmNvZGVyU3RyZWFtLmVuY29kZSgKKwkJCQl1c2VyLmdldEJ5dGVzKFN0YW5kYXJkQ2hhcnNldHMuVVRGXzgpKSk7CisJICAgIGlmIChyZXNwID09IDMzNCkgeworCQkvLyBzZW5kIHBhc3N3ZAorCQlyZXNwID0gc2ltcGxlQ29tbWFuZChCQVNFNjRFbmNvZGVyU3RyZWFtLmVuY29kZSgKKwkJCQlwYXNzd2QuZ2V0Qnl0ZXMoU3RhbmRhcmRDaGFyc2V0cy5VVEZfOCkpKTsKKwkgICAgfQorCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtIHRoZSBhdXRoZW50aWNhdGlvbiBoYW5kc2hha2UgZm9yIFBMQUlOIGF1dGhlbnRpY2F0aW9uLgorICAgICAqLworICAgIHByaXZhdGUgY2xhc3MgUGxhaW5BdXRoZW50aWNhdG9yIGV4dGVuZHMgQXV0aGVudGljYXRvciB7CisJUGxhaW5BdXRoZW50aWNhdG9yKCkgeworCSAgICBzdXBlcigiUExBSU4iKTsKKwl9CisKKwlAT3ZlcnJpZGUKKwlTdHJpbmcgZ2V0SW5pdGlhbFJlc3BvbnNlKFN0cmluZyBob3N0LCBTdHJpbmcgYXV0aHppZCwgU3RyaW5nIHVzZXIsCisJCQlTdHJpbmcgcGFzc3dkKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisJICAgIC8vIHJldHVybiAiYXV0aHppZDxOVUw+dXNlcjxOVUw+cGFzc3dkIgorCSAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworCSAgICBPdXRwdXRTdHJlYW0gYjY0b3MgPQorCQkJbmV3IEJBU0U2NEVuY29kZXJTdHJlYW0oYm9zLCBJbnRlZ2VyLk1BWF9WQUxVRSk7CisJICAgIGlmIChhdXRoemlkICE9IG51bGwpCisJCWI2NG9zLndyaXRlKGF1dGh6aWQuZ2V0Qnl0ZXMoU3RhbmRhcmRDaGFyc2V0cy5VVEZfOCkpOworCSAgICBiNjRvcy53cml0ZSgwKTsKKwkgICAgYjY0b3Mud3JpdGUodXNlci5nZXRCeXRlcyhTdGFuZGFyZENoYXJzZXRzLlVURl84KSk7CisJICAgIGI2NG9zLndyaXRlKDApOworCSAgICBiNjRvcy53cml0ZShwYXNzd2QuZ2V0Qnl0ZXMoU3RhbmRhcmRDaGFyc2V0cy5VVEZfOCkpOworCSAgICBiNjRvcy5mbHVzaCgpOyAJLy8gY29tcGxldGUgdGhlIGVuY29kaW5nCisKKwkgICAgcmV0dXJuIEFTQ0lJVXRpbGl0eS50b1N0cmluZyhib3MudG9CeXRlQXJyYXkoKSk7CisJfQorCisJQE92ZXJyaWRlCisJdm9pZCBkb0F1dGgoU3RyaW5nIGhvc3QsIFN0cmluZyBhdXRoemlkLCBTdHJpbmcgdXNlciwgU3RyaW5nIHBhc3N3ZCkKKwkJCQkgICAgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworCSAgICAvLyBzaG91bGQgbmV2ZXIgZ2V0IGhlcmUKKwkgICAgdGhyb3cgbmV3IEF1dGhlbnRpY2F0aW9uRmFpbGVkRXhjZXB0aW9uKCJQTEFJTiBhc2tlZCBmb3IgbW9yZSIpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtIHRoZSBhdXRoZW50aWNhdGlvbiBoYW5kc2hha2UgZm9yIERJR0VTVC1NRDUgYXV0aGVudGljYXRpb24uCisgICAgICovCisgICAgcHJpdmF0ZSBjbGFzcyBEaWdlc3RNRDVBdXRoZW50aWNhdG9yIGV4dGVuZHMgQXV0aGVudGljYXRvciB7CisJcHJpdmF0ZSBEaWdlc3RNRDUgbWQ1c3VwcG9ydDsJLy8gb25seSBjcmVhdGUgaWYgbmVlZGVkCisKKwlEaWdlc3RNRDVBdXRoZW50aWNhdG9yKCkgeworCSAgICBzdXBlcigiRElHRVNULU1ENSIpOworCX0KKworCXByaXZhdGUgc3luY2hyb25pemVkIERpZ2VzdE1ENSBnZXRNRDUoKSB7CisJICAgIGlmIChtZDVzdXBwb3J0ID09IG51bGwpCisJCW1kNXN1cHBvcnQgPSBuZXcgRGlnZXN0TUQ1KGxvZ2dlcik7CisJICAgIHJldHVybiBtZDVzdXBwb3J0OworCX0KKworCUBPdmVycmlkZQorCXZvaWQgZG9BdXRoKFN0cmluZyBob3N0LCBTdHJpbmcgYXV0aHppZCwgU3RyaW5nIHVzZXIsIFN0cmluZyBwYXNzd2QpCisJCQkJICAgIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKwkgICAgRGlnZXN0TUQ1IG1kNSA9IGdldE1ENSgpOworCSAgICBhc3NlcnQgbWQ1ICE9IG51bGw7CisKKwkgICAgYnl0ZVtdIGIgPSBtZDUuYXV0aENsaWVudChob3N0LCB1c2VyLCBwYXNzd2QsIGdldFNBU0xSZWFsbSgpLAorCQkJCQlnZXRMYXN0U2VydmVyUmVzcG9uc2UoKSk7CisJICAgIHJlc3AgPSBzaW1wbGVDb21tYW5kKGIpOworCSAgICBpZiAocmVzcCA9PSAzMzQpIHsgLy8gY2xpZW50IGF1dGhlbnRpY2F0ZWQgYnkgc2VydmVyCisJCWlmICghbWQ1LmF1dGhTZXJ2ZXIoZ2V0TGFzdFNlcnZlclJlc3BvbnNlKCkpKSB7CisJCSAgICAvLyBzZXJ2ZXIgTk9UIGF1dGhlbnRpY2F0ZWQgYnkgY2xpZW50ICEhIQorCQkgICAgcmVzcCA9IC0xOworCQl9IGVsc2UgeworCQkgICAgLy8gc2VuZCBudWxsIHJlc3BvbnNlCisJCSAgICByZXNwID0gc2ltcGxlQ29tbWFuZChuZXcgYnl0ZVswXSk7CisJCX0KKwkgICAgfQorCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtIHRoZSBhdXRoZW50aWNhdGlvbiBoYW5kc2hha2UgZm9yIE5UTE0gYXV0aGVudGljYXRpb24uCisgICAgICovCisgICAgcHJpdmF0ZSBjbGFzcyBOdGxtQXV0aGVudGljYXRvciBleHRlbmRzIEF1dGhlbnRpY2F0b3IgeworCXByaXZhdGUgTnRsbSBudGxtOworCXByaXZhdGUgaW50IGZsYWdzOworCisJTnRsbUF1dGhlbnRpY2F0b3IoKSB7CisJICAgIHN1cGVyKCJOVExNIik7CisJfQorCisJQE92ZXJyaWRlCisJU3RyaW5nIGdldEluaXRpYWxSZXNwb25zZShTdHJpbmcgaG9zdCwgU3RyaW5nIGF1dGh6aWQsIFN0cmluZyB1c2VyLAorCQlTdHJpbmcgcGFzc3dkKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisJICAgIG50bG0gPSBuZXcgTnRsbShnZXROVExNRG9tYWluKCksIGdldExvY2FsSG9zdCgpLAorCQkJCXVzZXIsIHBhc3N3ZCwgbG9nZ2VyKTsKKworCSAgICBmbGFncyA9IFByb3BVdGlsLmdldEludFByb3BlcnR5KAorCQkgICAgc2Vzc2lvbi5nZXRQcm9wZXJ0aWVzKCksCisJCSAgICAibWFpbC4iICsgbmFtZSArICIuYXV0aC5udGxtLmZsYWdzIiwgMCk7CisKKwkgICAgU3RyaW5nIHR5cGUxID0gbnRsbS5nZW5lcmF0ZVR5cGUxTXNnKGZsYWdzKTsKKwkgICAgcmV0dXJuIHR5cGUxOworCX0KKworCUBPdmVycmlkZQorCXZvaWQgZG9BdXRoKFN0cmluZyBob3N0LCBTdHJpbmcgYXV0aHppZCwgU3RyaW5nIHVzZXIsIFN0cmluZyBwYXNzd2QpCisJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKwkgICAgYXNzZXJ0IG50bG0gIT0gbnVsbDsKKwkgICAgU3RyaW5nIHR5cGUzID0gbnRsbS5nZW5lcmF0ZVR5cGUzTXNnKAorCQkgICAgZ2V0TGFzdFNlcnZlclJlc3BvbnNlKCkuc3Vic3RyaW5nKDQpLnRyaW0oKSk7CisKKwkgICAgcmVzcCA9IHNpbXBsZUNvbW1hbmQodHlwZTMpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtIHRoZSBhdXRoZW50aWNhdGlvbiBoYW5kc2hha2UgZm9yIFhPQVVUSDIgYXV0aGVudGljYXRpb24uCisgICAgICovCisgICAgcHJpdmF0ZSBjbGFzcyBPQXV0aDJBdXRoZW50aWNhdG9yIGV4dGVuZHMgQXV0aGVudGljYXRvciB7CisKKwlPQXV0aDJBdXRoZW50aWNhdG9yKCkgeworCSAgICBzdXBlcigiWE9BVVRIMiIsIGZhbHNlKTsJLy8gZGlzYWJsZWQgYnkgZGVmYXVsdAorCX0KKworCUBPdmVycmlkZQorCVN0cmluZyBnZXRJbml0aWFsUmVzcG9uc2UoU3RyaW5nIGhvc3QsIFN0cmluZyBhdXRoemlkLCBTdHJpbmcgdXNlciwKKwkJU3RyaW5nIHBhc3N3ZCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworCSAgICBTdHJpbmcgcmVzcCA9ICJ1c2VyPSIgKyB1c2VyICsgIlwwMDFhdXRoPUJlYXJlciAiICsKKwkJCSAgICBwYXNzd2QgKyAiXDAwMVwwMDEiOworCSAgICBieXRlW10gYiA9IEJBU0U2NEVuY29kZXJTdHJlYW0uZW5jb2RlKAorCQkJCQlyZXNwLmdldEJ5dGVzKFN0YW5kYXJkQ2hhcnNldHMuVVRGXzgpKTsKKwkgICAgcmV0dXJuIEFTQ0lJVXRpbGl0eS50b1N0cmluZyhiKTsKKwl9CisKKwlAT3ZlcnJpZGUKKwl2b2lkIGRvQXV0aChTdHJpbmcgaG9zdCwgU3RyaW5nIGF1dGh6aWQsIFN0cmluZyB1c2VyLCBTdHJpbmcgcGFzc3dkKQorCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisJICAgIC8vIHNob3VsZCBuZXZlciBnZXQgaGVyZQorCSAgICB0aHJvdyBuZXcgQXV0aGVudGljYXRpb25GYWlsZWRFeGNlcHRpb24oIk9BVVRIMiBhc2tlZCBmb3IgbW9yZSIpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTQVNMLWJhc2VkIGxvZ2luLgorICAgICAqCisgICAgICogQHBhcmFtCWFsbG93ZWQJdGhlIGFsbG93ZWQgU0FTTCBtZWNoYW5pc21zCisgICAgICogQHBhcmFtCXJlYWxtCXRoZSBTQVNMIHJlYWxtCisgICAgICogQHBhcmFtCWF1dGh6aWQJdGhlIGF1dGhvcml6YXRpb24gSUQKKyAgICAgKiBAcGFyYW0JdQl0aGUgdXNlciBuYW1lIGZvciBhdXRoZW50aWNhdGlvbgorICAgICAqIEBwYXJhbQlwCXRoZSBwYXNzd29yZCBmb3IgYXV0aGVudGljYXRpb24KKyAgICAgKiBAcmV0dXJuCQl0cnVlIGZvciBzdWNjZXNzCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIHNhc2xsb2dpbihTdHJpbmdbXSBhbGxvd2VkLCBTdHJpbmcgcmVhbG0sIFN0cmluZyBhdXRoemlkLAorCQkJCVN0cmluZyB1LCBTdHJpbmcgcCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJU3RyaW5nIHNlcnZpY2VIb3N0OworCWlmICh1c2VDYW5vbmljYWxIb3N0TmFtZSkKKwkgICAgc2VydmljZUhvc3QgPSBzZXJ2ZXJTb2NrZXQuZ2V0SW5ldEFkZHJlc3MoKS5nZXRDYW5vbmljYWxIb3N0TmFtZSgpOworCWVsc2UKKwkgICAgc2VydmljZUhvc3QgPSBob3N0OworCWlmIChzYXNsQXV0aGVudGljYXRvciA9PSBudWxsKSB7CisJICAgIHRyeSB7CisJCUNsYXNzPD8+IHNhYyA9IENsYXNzLmZvck5hbWUoCisJCSAgICAiY29tLnN1bi5tYWlsLnNtdHAuU01UUFNhc2xBdXRoZW50aWNhdG9yIik7CisJCUNvbnN0cnVjdG9yPD8+IGMgPSBzYWMuZ2V0Q29uc3RydWN0b3IobmV3IENsYXNzPD8+W10geworCQkJCQlTTVRQVHJhbnNwb3J0LmNsYXNzLAorCQkJCQlTdHJpbmcuY2xhc3MsCisJCQkJCVByb3BlcnRpZXMuY2xhc3MsCisJCQkJCU1haWxMb2dnZXIuY2xhc3MsCisJCQkJCVN0cmluZy5jbGFzcworCQkJCQl9KTsKKwkJc2FzbEF1dGhlbnRpY2F0b3IgPSAoU2FzbEF1dGhlbnRpY2F0b3IpYy5uZXdJbnN0YW5jZSgKKwkJCQkJbmV3IE9iamVjdFtdIHsKKwkJCQkJdGhpcywKKwkJCQkJbmFtZSwKKwkJCQkJc2Vzc2lvbi5nZXRQcm9wZXJ0aWVzKCksCisJCQkJCWxvZ2dlciwKKwkJCQkJc2VydmljZUhvc3QKKwkJCQkJfSk7CisJICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCQlsb2dnZXIubG9nKExldmVsLkZJTkUsICJDYW4ndCBsb2FkIFNBU0wgYXV0aGVudGljYXRvciIsIGV4KTsKKwkJLy8gcHJvYmFibHkgYmVjYXVzZSB3ZSdyZSBydW5uaW5nIG9uIGEgc3lzdGVtIHdpdGhvdXQgU0FTTAorCQlyZXR1cm4gZmFsc2U7CS8vIG5vdCBhdXRoZW50aWNhdGVkLCB0cnkgd2l0aG91dCBTQVNMCisJICAgIH0KKwl9CisKKwkvLyB3ZXJlIGFueSBhbGxvd2VkIG1lY2hhbmlzbXMgc3BlY2lmaWVkPworCUxpc3Q8U3RyaW5nPiB2OworCWlmIChhbGxvd2VkICE9IG51bGwgJiYgYWxsb3dlZC5sZW5ndGggPiAwKSB7CisJICAgIC8vIHJlbW92ZSBhbnl0aGluZyBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBzZXJ2ZXIKKwkgICAgdiA9IG5ldyBBcnJheUxpc3Q8PihhbGxvd2VkLmxlbmd0aCk7CisJICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYWxsb3dlZC5sZW5ndGg7IGkrKykKKwkJaWYgKHN1cHBvcnRzQXV0aGVudGljYXRpb24oYWxsb3dlZFtpXSkpCS8vIFhYWCAtIGNhc2UgbXVzdCBtYXRjaAorCQkgICAgdi5hZGQoYWxsb3dlZFtpXSk7CisJfSBlbHNlIHsKKwkgICAgLy8gZXZlcnl0aGluZyBpcyBhbGxvd2VkCisJICAgIHYgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKwkgICAgaWYgKGV4dE1hcCAhPSBudWxsKSB7CisJCVN0cmluZyBhID0gZXh0TWFwLmdldCgiQVVUSCIpOworCQlpZiAoYSAhPSBudWxsKSB7CisJCSAgICBTdHJpbmdUb2tlbml6ZXIgc3QgPSBuZXcgU3RyaW5nVG9rZW5pemVyKGEpOworCQkgICAgd2hpbGUgKHN0Lmhhc01vcmVUb2tlbnMoKSkKKwkJCXYuYWRkKHN0Lm5leHRUb2tlbigpKTsKKwkJfQorCSAgICB9CisJfQorCVN0cmluZ1tdIG1lY2hzID0gdi50b0FycmF5KG5ldyBTdHJpbmdbdi5zaXplKCldKTsKKwl0cnkgeworCSAgICBpZiAobm9hdXRoZGVidWcgJiYgaXNUcmFjaW5nKCkpIHsKKwkJbG9nZ2VyLmZpbmUoIlNBU0wgQVVUSCBjb21tYW5kIHRyYWNlIHN1cHByZXNzZWQiKTsKKwkJc3VzcGVuZFRyYWNpbmcoKTsKKwkgICAgfQorCSAgICByZXR1cm4gc2FzbEF1dGhlbnRpY2F0b3IuYXV0aGVudGljYXRlKG1lY2hzLCByZWFsbSwgYXV0aHppZCwgdSwgcCk7CisJfSBmaW5hbGx5IHsKKwkgICAgcmVzdW1lVHJhY2luZygpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZW5kIHRoZSBNZXNzYWdlIHRvIHRoZSBzcGVjaWZpZWQgbGlzdCBvZiBhZGRyZXNzZXMuPHA+CisgICAgICoKKyAgICAgKiBJZiBhbGwgdGhlIDxjb2RlPmFkZHJlc3NlczwvY29kZT4gc3VjY2VlZCB0aGUgU01UUCBjaGVjaworICAgICAqIHVzaW5nIHRoZSA8Y29kZT5SQ1BUIFRPOjwvY29kZT4gY29tbWFuZCwgd2UgYXR0ZW1wdCB0byBzZW5kIHRoZSBtZXNzYWdlLgorICAgICAqIEEgVHJhbnNwb3J0RXZlbnQgb2YgdHlwZSBNRVNTQUdFX0RFTElWRVJFRCBpcyBmaXJlZCBpbmRpY2F0aW5nIHRoZQorICAgICAqIHN1Y2Nlc3NmdWwgc3VibWlzc2lvbiBvZiBhIG1lc3NhZ2UgdG8gdGhlIFNNVFAgaG9zdC48cD4KKyAgICAgKgorICAgICAqIElmIHNvbWUgb2YgdGhlIDxjb2RlPmFkZHJlc3NlczwvY29kZT4gZmFpbCB0aGUgU01UUCBjaGVjaywKKyAgICAgKiBhbmQgdGhlIDxjb2RlPm1haWwuc210cC5zZW5kcGFydGlhbDwvY29kZT4gcHJvcGVydHkgaXMgbm90IHNldCwKKyAgICAgKiBzZW5kaW5nIGlzIGFib3J0ZWQuIFRoZSBUcmFuc3BvcnRFdmVudCBvZiB0eXBlIE1FU1NBR0VfTk9UX0RFTElWRVJFRAorICAgICAqIGlzIGZpcmVkIGNvbnRhaW5pbmcgdGhlIHZhbGlkIGFuZCBpbnZhbGlkIGFkZHJlc3Nlcy4gVGhlCisgICAgICogU2VuZEZhaWxlZEV4Y2VwdGlvbiBpcyBhbHNvIHRocm93bi4gPHA+CisgICAgICoKKyAgICAgKiBJZiBzb21lIG9mIHRoZSA8Y29kZT5hZGRyZXNzZXM8L2NvZGU+IGZhaWwgdGhlIFNNVFAgY2hlY2ssCisgICAgICogYW5kIHRoZSA8Y29kZT5tYWlsLnNtdHAuc2VuZHBhcnRpYWw8L2NvZGU+IHByb3BlcnR5IGlzIHNldCB0byB0cnVlLAorICAgICAqIHRoZSBtZXNzYWdlIGlzIHNlbnQuIFRoZSBUcmFuc3BvcnRFdmVudCBvZiB0eXBlCisgICAgICogTUVTU0FHRV9QQVJUSUFMTFlfREVMSVZFUkVECisgICAgICogaXMgZmlyZWQgY29udGFpbmluZyB0aGUgdmFsaWQgYW5kIGludmFsaWQgYWRkcmVzc2VzLiBUaGUKKyAgICAgKiBTTVRQU2VuZEZhaWxlZEV4Y2VwdGlvbiBpcyBhbHNvIHRocm93bi4gPHA+CisgICAgICoKKyAgICAgKiBNZXNzYWdpbmdFeGNlcHRpb24gaXMgdGhyb3duIGlmIHRoZSBtZXNzYWdlIGNhbid0IHdyaXRlIG91dAorICAgICAqIGFuIFJGQzgyMi1jb21wbGlhbnQgc3RyZWFtIHVzaW5nIGl0cyA8Y29kZT53cml0ZVRvPC9jb2RlPiBtZXRob2QuIDxwPgorICAgICAqCisgICAgICogQHBhcmFtIG1lc3NhZ2UJVGhlIE1pbWVNZXNzYWdlIHRvIGJlIHNlbnQKKyAgICAgKiBAcGFyYW0gYWRkcmVzc2VzCUxpc3Qgb2YgYWRkcmVzc2VzIHRvIHNlbmQgdGhpcyBtZXNzYWdlIHRvCisgICAgICogQHNlZSAJCWphdmF4Lm1haWwuZXZlbnQuVHJhbnNwb3J0RXZlbnQKKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIFNNVFBTZW5kRmFpbGVkRXhjZXB0aW9uIGlmIHRoZSBzZW5kIGZhaWxlZCBiZWNhdXNlIG9mCisgICAgICoJCQlhbiBTTVRQIGNvbW1hbmQgZXJyb3IKKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIFNlbmRGYWlsZWRFeGNlcHRpb24gaWYgdGhlIHNlbmQgZmFpbGVkIGJlY2F1c2Ugb2YKKyAgICAgKgkJCWludmFsaWQgYWRkcmVzc2VzLgorICAgICAqIEBleGNlcHRpb24gICAgICAgTWVzc2FnaW5nRXhjZXB0aW9uIGlmIHRoZSBjb25uZWN0aW9uIGlzIGRlYWQKKyAgICAgKiAgICAgICAgICAgICAgICAgIG9yIG5vdCBpbiB0aGUgY29ubmVjdGVkIHN0YXRlIG9yIGlmIHRoZSBtZXNzYWdlIGlzCisgICAgICogICAgICAgICAgICAgICAgICBub3QgYSBNaW1lTWVzc2FnZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgc2VuZE1lc3NhZ2UoTWVzc2FnZSBtZXNzYWdlLCBBZGRyZXNzW10gYWRkcmVzc2VzKQorCQkgICAgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiwgU2VuZEZhaWxlZEV4Y2VwdGlvbiB7CisKKwlzZW5kTWVzc2FnZVN0YXJ0KG1lc3NhZ2UgIT0gbnVsbCA/IG1lc3NhZ2UuZ2V0U3ViamVjdCgpIDogIiIpOworCWNoZWNrQ29ubmVjdGVkKCk7CisKKwkvLyBjaGVjayBpZiB0aGUgbWVzc2FnZSBpcyBhIHZhbGlkIE1JTUUvUkZDODIyIG1lc3NhZ2UgYW5kIHRoYXQKKwkvLyBpdCBoYXMgYWxsIHZhbGlkIEludGVybmV0QWRkcmVzc2VzOyBmYWlsIGlmIG5vdAorICAgICAgICBpZiAoIShtZXNzYWdlIGluc3RhbmNlb2YgTWltZU1lc3NhZ2UpKSB7CisJICAgIGxvZ2dlci5maW5lKCJDYW4gb25seSBzZW5kIFJGQzgyMiBtc2dzIik7CisJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oIlNNVFAgY2FuIG9ubHkgc2VuZCBSRkM4MjIgbWVzc2FnZXMiKTsKKwl9CisJZm9yIChpbnQgaSA9IDA7IGkgPCBhZGRyZXNzZXMubGVuZ3RoOyBpKyspIHsKKwkgICAgaWYgKCEoYWRkcmVzc2VzW2ldIGluc3RhbmNlb2YgSW50ZXJuZXRBZGRyZXNzKSkgeworCQl0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKGFkZHJlc3Nlc1tpXSArCisJCQkJCSAgICAgIiBpcyBub3QgYW4gSW50ZXJuZXRBZGRyZXNzIik7CisJICAgIH0KKwl9CisJaWYgKGFkZHJlc3Nlcy5sZW5ndGggPT0gMCkKKwkgICAgdGhyb3cgbmV3IFNlbmRGYWlsZWRFeGNlcHRpb24oIk5vIHJlY2lwaWVudCBhZGRyZXNzZXMiKTsKKworCXRoaXMubWVzc2FnZSA9IChNaW1lTWVzc2FnZSltZXNzYWdlOworCXRoaXMuYWRkcmVzc2VzID0gYWRkcmVzc2VzOworCXZhbGlkVW5zZW50QWRkciA9IGFkZHJlc3NlczsJLy8gdW50aWwgd2Uga25vdyBiZXR0ZXIKKwlleHBhbmRHcm91cHMoKTsKKworCWJvb2xlYW4gdXNlOGJpdCA9IGZhbHNlOworCWlmIChtZXNzYWdlIGluc3RhbmNlb2YgU01UUE1lc3NhZ2UpCisJICAgIHVzZThiaXQgPSAoKFNNVFBNZXNzYWdlKW1lc3NhZ2UpLmdldEFsbG93OGJpdE1JTUUoKTsKKwlpZiAoIXVzZThiaXQpCisJICAgIHVzZThiaXQgPSBQcm9wVXRpbC5nZXRCb29sZWFuUHJvcGVydHkoc2Vzc2lvbi5nZXRQcm9wZXJ0aWVzKCksCisJCQkJIm1haWwuIiArIG5hbWUgKyAiLmFsbG93OGJpdG1pbWUiLCBmYWxzZSk7CisJaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkUpKQorCSAgICBsb2dnZXIuZmluZSgidXNlOGJpdCAiICsgdXNlOGJpdCk7CisJaWYgKHVzZThiaXQgJiYgc3VwcG9ydHNFeHRlbnNpb24oIjhCSVRNSU1FIikpIHsKKwkgICAgaWYgKGNvbnZlcnRUbzhCaXQodGhpcy5tZXNzYWdlKSkgeworCQkvLyBpbiBjYXNlIHdlIG1hZGUgYW55IGNoYW5nZXMsIHNhdmUgdGhvc2UgY2hhbmdlcworCQkvLyBYWFggLSB0aGlzIHdpbGwgY2hhbmdlIHRoZSBNZXNzYWdlLUlECisJCXRyeSB7CisJCSAgICB0aGlzLm1lc3NhZ2Uuc2F2ZUNoYW5nZXMoKTsKKwkJfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIG1leCkgeworCQkgICAgLy8gaWdub3JlIGl0CisJCX0KKwkgICAgfQorCX0KKworCXRyeSB7CisJICAgIG1haWxGcm9tKCk7CisJICAgIHJjcHRUbygpOworCSAgICBpZiAoY2h1bmtTaXplID4gMCAmJiBzdXBwb3J0c0V4dGVuc2lvbigiQ0hVTktJTkciKSkgeworCQkvKgorCQkgKiBVc2UgQkRBVCB0byBzZW5kIHRoZSBkYXRhIGluIGNodW5rcy4KKwkJICogTm90ZSB0aGF0IGV2ZW4gdGhvdWdoIHRoZSBCREFUIGNvbW1hbmQgaXMgYWJsZSB0byBzZW5kCisJCSAqIG1lc3NhZ2VzIHRoYXQgY29udGFpbiBiaW5hcnkgZGF0YSwgd2UgY2FuJ3QgdXNlIGl0IHRvCisJCSAqIGRvIHRoYXQgYmVjYXVzZSBhKSB3ZSBzdGlsbCBuZWVkIHRvIGNhbm9uaWNhbGl6ZSB0aGUKKwkJICogbGluZSB0ZXJtaW5hdG9ycyBmb3IgdGV4dCBkYXRhLCB3aGljaCB3ZSBjYW4ndCB0ZWxsIGFwYXJ0CisJCSAqIGZyb20gdGhlIG1lc3NhZ2UgY29udGVudCwgYW5kIGIpIHRoZSBtZXNzYWdlIGNvbnRlbnQgaXMKKwkJICogZW5jb2RlZCBiZWZvcmUgd2UgZXZlbiBrbm93IHRoYXQgd2UgY2FuIHVzZSBCREFULgorCQkgKi8KKwkJdGhpcy5tZXNzYWdlLndyaXRlVG8oYmRhdCgpLCBpZ25vcmVMaXN0KTsKKwkJZmluaXNoQmRhdCgpOworCSAgICB9IGVsc2UgeworCQl0aGlzLm1lc3NhZ2Uud3JpdGVUbyhkYXRhKCksIGlnbm9yZUxpc3QpOworCQlmaW5pc2hEYXRhKCk7CisJICAgIH0KKwkgICAgaWYgKHNlbmRQYXJ0aWFsbHlGYWlsZWQpIHsKKwkJLy8gdGhyb3cgdGhlIGV4Y2VwdGlvbiwKKwkJLy8gZmlyZSBUcmFuc3BvcnRFdmVudC5NRVNTQUdFX1BBUlRJQUxMWV9ERUxJVkVSRUQgZXZlbnQKKwkJbG9nZ2VyLmZpbmUoIlNlbmRpbmcgcGFydGlhbGx5IGZhaWxlZCAiICsKKwkJCSJiZWNhdXNlIG9mIGludmFsaWQgZGVzdGluYXRpb24gYWRkcmVzc2VzIik7CisJCW5vdGlmeVRyYW5zcG9ydExpc3RlbmVycygKKwkJCVRyYW5zcG9ydEV2ZW50Lk1FU1NBR0VfUEFSVElBTExZX0RFTElWRVJFRCwKKwkJCXZhbGlkU2VudEFkZHIsIHZhbGlkVW5zZW50QWRkciwgaW52YWxpZEFkZHIsCisJCQl0aGlzLm1lc3NhZ2UpOworCisJCXRocm93IG5ldyBTTVRQU2VuZEZhaWxlZEV4Y2VwdGlvbigiLiIsIGxhc3RSZXR1cm5Db2RlLAorCQkJCWxhc3RTZXJ2ZXJSZXNwb25zZSwgZXhjZXB0aW9uLAorCQkJCXZhbGlkU2VudEFkZHIsIHZhbGlkVW5zZW50QWRkciwgaW52YWxpZEFkZHIpOworCSAgICB9CisJICAgIGxvZ2dlci5maW5lKCJtZXNzYWdlIHN1Y2Nlc3NmdWxseSBkZWxpdmVyZWQgdG8gbWFpbCBzZXJ2ZXIiKTsKKwkgICAgbm90aWZ5VHJhbnNwb3J0TGlzdGVuZXJzKFRyYW5zcG9ydEV2ZW50Lk1FU1NBR0VfREVMSVZFUkVELAorCQkJCSAgICAgdmFsaWRTZW50QWRkciwgdmFsaWRVbnNlbnRBZGRyLAorCQkJCSAgICAgaW52YWxpZEFkZHIsIHRoaXMubWVzc2FnZSk7CisJfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIG1leCkgeworCSAgICBsb2dnZXIubG9nKExldmVsLkZJTkUsICJNZXNzYWdpbmdFeGNlcHRpb24gd2hpbGUgc2VuZGluZyIsIG1leCk7CisJICAgIC8vIHRoZSBNZXNzYWdpbmdFeGNlcHRpb24gbWlnaHQgYmUgd3JhcHBpbmcgYW4gSU9FeGNlcHRpb24KKwkgICAgaWYgKG1leC5nZXROZXh0RXhjZXB0aW9uKCkgaW5zdGFuY2VvZiBJT0V4Y2VwdGlvbikgeworCQkvLyBpZiB3ZSBjYXRjaCBhbiBJT0V4Y2VwdGlvbiwgaXQgbWVhbnMgdGhhdCB3ZSB3YW50CisJCS8vIHRvIGRyb3AgdGhlIGNvbm5lY3Rpb24gc28gdGhhdCB0aGUgbWVzc2FnZSBpc24ndCBzZW50CisJCWxvZ2dlci5maW5lKCJuZXN0ZWQgSU9FeGNlcHRpb24sIGNsb3NpbmciKTsKKwkJdHJ5IHsKKwkJICAgIGNsb3NlQ29ubmVjdGlvbigpOworCQl9IGNhdGNoIChNZXNzYWdpbmdFeGNlcHRpb24gY2V4KSB7IC8qIGlnbm9yZSBpdCAqLyB9CisJICAgIH0KKwkgICAgYWRkcmVzc2VzRmFpbGVkKCk7CisJICAgIG5vdGlmeVRyYW5zcG9ydExpc3RlbmVycyhUcmFuc3BvcnRFdmVudC5NRVNTQUdFX05PVF9ERUxJVkVSRUQsCisJCQkJICAgICB2YWxpZFNlbnRBZGRyLCB2YWxpZFVuc2VudEFkZHIsCisJCQkJICAgICBpbnZhbGlkQWRkciwgdGhpcy5tZXNzYWdlKTsKKworCSAgICB0aHJvdyBtZXg7CisJfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKwkgICAgbG9nZ2VyLmxvZyhMZXZlbC5GSU5FLCAiSU9FeGNlcHRpb24gd2hpbGUgc2VuZGluZywgY2xvc2luZyIsIGV4KTsKKwkgICAgLy8gaWYgd2UgY2F0Y2ggYW4gSU9FeGNlcHRpb24sIGl0IG1lYW5zIHRoYXQgd2Ugd2FudAorCSAgICAvLyB0byBkcm9wIHRoZSBjb25uZWN0aW9uIHNvIHRoYXQgdGhlIG1lc3NhZ2UgaXNuJ3Qgc2VudAorCSAgICB0cnkgeworCQljbG9zZUNvbm5lY3Rpb24oKTsKKwkgICAgfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIG1leCkgeyAvKiBpZ25vcmUgaXQgKi8gfQorCSAgICBhZGRyZXNzZXNGYWlsZWQoKTsKKwkgICAgbm90aWZ5VHJhbnNwb3J0TGlzdGVuZXJzKFRyYW5zcG9ydEV2ZW50Lk1FU1NBR0VfTk9UX0RFTElWRVJFRCwKKwkJCQkgICAgIHZhbGlkU2VudEFkZHIsIHZhbGlkVW5zZW50QWRkciwKKwkJCQkgICAgIGludmFsaWRBZGRyLCB0aGlzLm1lc3NhZ2UpOworCisJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oIklPRXhjZXB0aW9uIHdoaWxlIHNlbmRpbmcgbWVzc2FnZSIsCisJCQkJCSBleCk7CisJfSBmaW5hbGx5IHsKKwkgICAgLy8gbm8gcmVhc29uIHRvIGtlZXAgdGhpcyBkYXRhIGFyb3VuZAorCSAgICB2YWxpZFNlbnRBZGRyID0gdmFsaWRVbnNlbnRBZGRyID0gaW52YWxpZEFkZHIgPSBudWxsOworCSAgICB0aGlzLmFkZHJlc3NlcyA9IG51bGw7CisJICAgIHRoaXMubWVzc2FnZSA9IG51bGw7CisJICAgIHRoaXMuZXhjZXB0aW9uID0gbnVsbDsKKwkgICAgc2VuZFBhcnRpYWxseUZhaWxlZCA9IGZhbHNlOworCSAgICBub3RpZmljYXRpb25Eb25lID0gZmFsc2U7CS8vIHJlc2V0IGZvciBuZXh0IHNlbmQKKwl9CisJc2VuZE1lc3NhZ2VFbmQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgc2VuZCBmYWlsZWQsIGZpeCB0aGUgYWRkcmVzcyBhcnJheXMgdG8gcmVwb3J0IHRoZSBmYWlsdXJlIGNvcnJlY3RseS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgYWRkcmVzc2VzRmFpbGVkKCkgeworCWlmICh2YWxpZFNlbnRBZGRyICE9IG51bGwpIHsKKwkgICAgaWYgKHZhbGlkVW5zZW50QWRkciAhPSBudWxsKSB7CisJCUFkZHJlc3MgbmV3YVtdID0KKwkJICAgIG5ldyBBZGRyZXNzW3ZhbGlkU2VudEFkZHIubGVuZ3RoICsgdmFsaWRVbnNlbnRBZGRyLmxlbmd0aF07CisJCVN5c3RlbS5hcnJheWNvcHkodmFsaWRTZW50QWRkciwgMCwKKwkJCW5ld2EsIDAsIHZhbGlkU2VudEFkZHIubGVuZ3RoKTsKKwkJU3lzdGVtLmFycmF5Y29weSh2YWxpZFVuc2VudEFkZHIsIDAsCisJCQluZXdhLCB2YWxpZFNlbnRBZGRyLmxlbmd0aCwgdmFsaWRVbnNlbnRBZGRyLmxlbmd0aCk7CisJCXZhbGlkU2VudEFkZHIgPSBudWxsOworCQl2YWxpZFVuc2VudEFkZHIgPSBuZXdhOworCSAgICB9IGVsc2UgeworCQl2YWxpZFVuc2VudEFkZHIgPSB2YWxpZFNlbnRBZGRyOworCQl2YWxpZFNlbnRBZGRyID0gbnVsbDsKKwkgICAgfQorCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9zZSB0aGUgVHJhbnNwb3J0IGFuZCB0ZXJtaW5hdGUgdGhlIGNvbm5lY3Rpb24gdG8gdGhlIHNlcnZlci4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgY2xvc2UoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpZiAoIXN1cGVyLmlzQ29ubmVjdGVkKCkpIC8vIEFscmVhZHkgY2xvc2VkLgorCSAgICByZXR1cm47CisJdHJ5IHsKKwkgICAgaWYgKHNlcnZlclNvY2tldCAhPSBudWxsKSB7CisJCXNlbmRDb21tYW5kKCJRVUlUIik7CisJCWlmIChxdWl0V2FpdCkgeworCQkgICAgaW50IHJlc3AgPSByZWFkU2VydmVyUmVzcG9uc2UoKTsKKwkJICAgIGlmIChyZXNwICE9IDIyMSAmJiByZXNwICE9IC0xICYmCisJCQkgICAgbG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuRklORSkpCisJCQlsb2dnZXIuZmluZSgiUVVJVCBmYWlsZWQgd2l0aCAiICsgcmVzcCk7CisJCX0KKwkgICAgfQorCX0gZmluYWxseSB7CisJICAgIGNsb3NlQ29ubmVjdGlvbigpOworCX0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2xvc2VDb25uZWN0aW9uKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJdHJ5IHsKKwkgICAgaWYgKHNlcnZlclNvY2tldCAhPSBudWxsKQorCQlzZXJ2ZXJTb2NrZXQuY2xvc2UoKTsKKwl9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2V4KSB7CSAgICAvLyBzaG91bGRuJ3QgaGFwcGVuCisJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oIlNlcnZlciBDbG9zZSBGYWlsZWQiLCBpb2V4KTsKKwl9IGZpbmFsbHkgeworCSAgICBzZXJ2ZXJTb2NrZXQgPSBudWxsOworCSAgICBzZXJ2ZXJPdXRwdXQgPSBudWxsOworCSAgICBzZXJ2ZXJJbnB1dCA9IG51bGw7CisJICAgIGxpbmVJbnB1dFN0cmVhbSA9IG51bGw7CisJICAgIGlmIChzdXBlci5pc0Nvbm5lY3RlZCgpKQkvLyBvbmx5IG5vdGlmeSBpZiBhbHJlYWR5IGNvbm5lY3RlZAorCQlzdXBlci5jbG9zZSgpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVjayB3aGV0aGVyIHRoZSB0cmFuc3BvcnQgaXMgY29ubmVjdGVkLiBPdmVycmlkZSBzdXBlcmNsYXNzCisgICAgICogbWV0aG9kLCB0byBhY3R1YWxseSBwaW5nIG91ciBzZXJ2ZXIgY29ubmVjdGlvbi4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGJvb2xlYW4gaXNDb25uZWN0ZWQoKSB7CisJaWYgKCFzdXBlci5pc0Nvbm5lY3RlZCgpKQorCSAgICAvLyBpZiB3ZSBoYXZlbid0IGJlZW4gY29ubmVjdGVkIGF0IGFsbCwgZG9uJ3QgYm90aGVyIHdpdGggTk9PUAorCSAgICByZXR1cm4gZmFsc2U7CisKKwl0cnkgeworCSAgICAvLyBzZW5kbWFpbCBtYXkgcmVzcG9uZCBzbG93bHkgdG8gTk9PUCBhZnRlciBtYW55IHJlcXVlc3RzCisJICAgIC8vIHNvIGlmIG1haWwuc210cC51c2Vyc2V0IGlzIHNldCB3ZSB1c2UgUlNFVCBpbnN0ZWFkIG9mIE5PT1AuCisJICAgIGlmICh1c2VSc2V0KQorCQlzZW5kQ29tbWFuZCgiUlNFVCIpOworCSAgICBlbHNlCisJCXNlbmRDb21tYW5kKCJOT09QIik7CisJICAgIGludCByZXNwID0gcmVhZFNlcnZlclJlc3BvbnNlKCk7CisKKwkgICAgLyoKKwkgICAgICogTk9PUCBzaG91bGQgcmV0dXJuIDI1MCBvbiBzdWNjZXNzLCBob3dldmVyLCBTSU1TIDMuMiByZXR1cm5zCisJICAgICAqIDIwMCwgc28gd2Ugd29yayBhcm91bmQgaXQuCisJICAgICAqCisJICAgICAqIEhvdG1haWwgZGlkbid0IHVzZWQgdG8gaW1wbGVtZW50IHRoZSBOT09QIGNvbW1hbmQgYXQgYWxsIHNvCisJICAgICAqIGFzc3VtZSBhbnkga2luZCBvZiByZXNwb25zZSBtZWFucyB3ZSdyZSBzdGlsbCBjb25uZWN0ZWQuCisJICAgICAqIFRoYXQgaXMsIGFueSByZXNwb25zZSBleGNlcHQgNDIxLCB3aGljaCBtZWFucyB0aGUgc2VydmVyCisJICAgICAqIGlzIHNodXR0aW5nIGRvd24gdGhlIGNvbm5lY3Rpb24uCisJICAgICAqCisJICAgICAqIFNvbWUgdmVyc2lvbnMgb2YgRXhjaGFuZ2UgcmV0dXJuIDQ1MSBpbnN0ZWFkIG9mIDQyMSB3aGVuCisJICAgICAqIHRpbWluZyBvdXQgYSBjb25uZWN0aW9uLgorCSAgICAgKgorCSAgICAgKiBBcmdoIQorCSAgICAgKgorCSAgICAgKiBJZiBtYWlsLnNtdHAubm9vcC5zdHJpY3QgaXMgc2V0IHRvIGZhbHNlLCBiZSB0b2xlcmFudCBvZgorCSAgICAgKiBzZXJ2ZXJzIHRoYXQgcmV0dXJuIHRoZSB3cm9uZyByZXNwb25zZSBjb2RlIGZvciBzdWNjZXNzLgorCSAgICAgKi8KKwkgICAgaWYgKHJlc3AgPj0gMCAmJiAobm9vcFN0cmljdCA/IHJlc3AgPT0gMjUwIDogcmVzcCAhPSA0MjEpKSB7CisJCXJldHVybiB0cnVlOworCSAgICB9IGVsc2UgeworCQl0cnkgeworCQkgICAgY2xvc2VDb25uZWN0aW9uKCk7CisJCX0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBtZXgpIHsKKwkJICAgIC8vIGlnbm9yZSBpdAorCQl9CisJCXJldHVybiBmYWxzZTsKKwkgICAgfQorCX0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCSAgICB0cnkgeworCQljbG9zZUNvbm5lY3Rpb24oKTsKKwkgICAgfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIG1leCkgeworCQkvLyBpZ25vcmUgaXQKKwkgICAgfQorCSAgICByZXR1cm4gZmFsc2U7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIE5vdGlmeSBhbGwgVHJhbnNwb3J0TGlzdGVuZXJzLiAgS2VlcCB0cmFjayBvZiB3aGV0aGVyIG5vdGlmaWNhdGlvbgorICAgICAqIGhhcyBiZWVuIGRvbmUgc28gYXMgdG8gb25seSBub3RpZnkgb25jZSBwZXIgc2VuZC4KKyAgICAgKgorICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjQuMgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIG5vdGlmeVRyYW5zcG9ydExpc3RlbmVycyhpbnQgdHlwZSwgQWRkcmVzc1tdIHZhbGlkU2VudCwKKwkJCQkJICAgIEFkZHJlc3NbXSB2YWxpZFVuc2VudCwKKwkJCQkJICAgIEFkZHJlc3NbXSBpbnZhbGlkLCBNZXNzYWdlIG1zZykgeworCisJaWYgKCFub3RpZmljYXRpb25Eb25lKSB7CisJICAgIHN1cGVyLm5vdGlmeVRyYW5zcG9ydExpc3RlbmVycyh0eXBlLCB2YWxpZFNlbnQsIHZhbGlkVW5zZW50LAorCQlpbnZhbGlkLCBtc2cpOworCSAgICBub3RpZmljYXRpb25Eb25lID0gdHJ1ZTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogRXhwYW5kIGFueSBncm91cCBhZGRyZXNzZXMuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGV4cGFuZEdyb3VwcygpIHsKKwlMaXN0PEFkZHJlc3M+IGdyb3VwcyA9IG51bGw7CisJZm9yIChpbnQgaSA9IDA7IGkgPCBhZGRyZXNzZXMubGVuZ3RoOyBpKyspIHsKKwkgICAgSW50ZXJuZXRBZGRyZXNzIGEgPSAoSW50ZXJuZXRBZGRyZXNzKWFkZHJlc3Nlc1tpXTsKKwkgICAgaWYgKGEuaXNHcm91cCgpKSB7CisJCWlmIChncm91cHMgPT0gbnVsbCkgeworCQkgICAgLy8gZmlyc3QgZ3JvdXAsIGNhdGNoIHVwIHdpdGggd2hlcmUgd2UgYXJlCisJCSAgICBncm91cHMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKwkJICAgIGZvciAoaW50IGsgPSAwOyBrIDwgaTsgaysrKQorCQkJZ3JvdXBzLmFkZChhZGRyZXNzZXNba10pOworCQl9CisJCS8vIHBhcnNlIGl0IGFuZCBhZGQgZWFjaCBpbmRpdmlkdWFsIGFkZHJlc3MKKwkJdHJ5IHsKKwkJICAgIEludGVybmV0QWRkcmVzc1tdIGlhID0gYS5nZXRHcm91cCh0cnVlKTsKKwkJICAgIGlmIChpYSAhPSBudWxsKSB7CisJCQlmb3IgKGludCBqID0gMDsgaiA8IGlhLmxlbmd0aDsgaisrKQorCQkJICAgIGdyb3Vwcy5hZGQoaWFbal0pOworCQkgICAgfSBlbHNlCisJCQlncm91cHMuYWRkKGEpOworCQl9IGNhdGNoIChQYXJzZUV4Y2VwdGlvbiBwZXgpIHsKKwkJICAgIC8vIHBhcnNlIGZhaWxlZCwgYWRkIHRoZSB3aG9sZSB0aGluZworCQkgICAgZ3JvdXBzLmFkZChhKTsKKwkJfQorCSAgICB9IGVsc2UgeworCQkvLyBpZiB3ZSd2ZSBzdGFydGVkIGFjY3VtdWxhdGluZyBhIGxpc3QsIGFkZCB0aGlzIHRvIGl0CisJCWlmIChncm91cHMgIT0gbnVsbCkKKwkJICAgIGdyb3Vwcy5hZGQoYSk7CisJICAgIH0KKwl9CisKKwkvLyBpZiB3ZSBoYXZlIGEgbmV3IGxpc3QsIGNvbnZlcnQgaXQgYmFjayB0byBhbiBhcnJheQorCWlmIChncm91cHMgIT0gbnVsbCkgeworCSAgICBJbnRlcm5ldEFkZHJlc3NbXSBuZXdhID0gbmV3IEludGVybmV0QWRkcmVzc1tncm91cHMuc2l6ZSgpXTsKKwkgICAgZ3JvdXBzLnRvQXJyYXkobmV3YSk7CisJICAgIGFkZHJlc3NlcyA9IG5ld2E7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIElmIHRoZSBQYXJ0IGlzIGEgdGV4dCBwYXJ0IGFuZCBoYXMgYSBDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nCisgICAgICogb2YgInF1b3RlZC1wcmludGFibGUiIG9yICJiYXNlNjQiLCBhbmQgaXQgb2JleXMgdGhlIHJ1bGVzIGZvcgorICAgICAqICI4Yml0IiBlbmNvZGluZywgY2hhbmdlIHRoZSBlbmNvZGluZyB0byAiOGJpdCIuICBJZiB0aGUgcGFydCBpcworICAgICAqIGEgbXVsdGlwYXJ0LCByZWN1cnNpdmVseSBwcm9jZXNzIGFsbCBpdHMgcGFydHMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRydWUJaWYgYW55IGNoYW5nZXMgd2VyZSBtYWRlCisgICAgICoKKyAgICAgKiBYWFggLSBUaGlzIGlzIHJlYWxseSBxdWl0ZSBhIGhhY2suCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGNvbnZlcnRUbzhCaXQoTWltZVBhcnQgcGFydCkgeworCWJvb2xlYW4gY2hhbmdlZCA9IGZhbHNlOworCXRyeSB7CisJICAgIGlmIChwYXJ0LmlzTWltZVR5cGUoInRleHQvKiIpKSB7CisJCVN0cmluZyBlbmMgPSBwYXJ0LmdldEVuY29kaW5nKCk7CisJCWlmIChlbmMgIT0gbnVsbCAmJiAoZW5jLmVxdWFsc0lnbm9yZUNhc2UoInF1b3RlZC1wcmludGFibGUiKSB8fAorCQkgICAgZW5jLmVxdWFsc0lnbm9yZUNhc2UoImJhc2U2NCIpKSkgeworCQkgICAgSW5wdXRTdHJlYW0gaXMgPSBudWxsOworCQkgICAgdHJ5IHsKKwkJCWlzID0gcGFydC5nZXRJbnB1dFN0cmVhbSgpOworCQkJaWYgKGlzOEJpdChpcykpIHsKKwkJCSAgICAvKgorCQkJICAgICAqIElmIHRoZSBtZXNzYWdlIHdhcyBjcmVhdGVkIHVzaW5nIGFuIElucHV0U3RyZWFtCisJCQkgICAgICogdGhlbiB3ZSBoYXZlIHRvIGV4dHJhY3QgdGhlIGNvbnRlbnQgYXMgYW4gb2JqZWN0CisJCQkgICAgICogYW5kIHNldCBpdCBiYWNrIGFzIGFuIG9iamVjdCBzbyB0aGF0IHRoZSBjb250ZW50CisJCQkgICAgICogd2lsbCBiZSByZS1lbmNvZGVkLgorCQkJICAgICAqCisJCQkgICAgICogSWYgdGhlIG1lc3NhZ2Ugd2FzIG5vdCBjcmVhdGVkIHVzaW5nIGFuCisJCQkgICAgICogSW5wdXRTdHJlYW0sIHRoZSBmb2xsb3dpbmcgc2hvdWxkIGhhdmUgbm8gZWZmZWN0LgorCQkJICAgICAqLworCQkJICAgIHBhcnQuc2V0Q29udGVudChwYXJ0LmdldENvbnRlbnQoKSwKKwkJCQkJICAgIHBhcnQuZ2V0Q29udGVudFR5cGUoKSk7CisJCQkgICAgcGFydC5zZXRIZWFkZXIoIkNvbnRlbnQtVHJhbnNmZXItRW5jb2RpbmciLCAiOGJpdCIpOworCQkJICAgIGNoYW5nZWQgPSB0cnVlOworCQkJfQorCQkgICAgfSBmaW5hbGx5IHsKKwkJCWlmIChpcyAhPSBudWxsKSB7CisJCQkgICAgdHJ5IHsKKwkJCQlpcy5jbG9zZSgpOworCQkJICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4MikgeworCQkJCS8vIGlnbm9yZSBpdAorCQkJICAgIH0KKwkJCX0KKwkJICAgIH0KKwkJfQorCSAgICB9IGVsc2UgaWYgKHBhcnQuaXNNaW1lVHlwZSgibXVsdGlwYXJ0LyoiKSkgeworCQlNaW1lTXVsdGlwYXJ0IG1wID0gKE1pbWVNdWx0aXBhcnQpcGFydC5nZXRDb250ZW50KCk7CisJCWludCBjb3VudCA9IG1wLmdldENvdW50KCk7CisJCWZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgeworCQkgICAgaWYgKGNvbnZlcnRUbzhCaXQoKE1pbWVQYXJ0KW1wLmdldEJvZHlQYXJ0KGkpKSkKKwkJCWNoYW5nZWQgPSB0cnVlOworCQl9CisJICAgIH0KKwl9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2V4KSB7CisJICAgIC8vIGFueSBleGNlcHRpb24gY2F1c2VzIHVzIHRvIGdpdmUgdXAKKwl9IGNhdGNoIChNZXNzYWdpbmdFeGNlcHRpb24gbWV4KSB7CisJICAgIC8vIGFueSBleGNlcHRpb24gY2F1c2VzIHVzIHRvIGdpdmUgdXAKKwl9CisJcmV0dXJuIGNoYW5nZWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2sgd2hldGhlciB0aGUgZGF0YSBpbiB0aGUgZ2l2ZW4gSW5wdXRTdHJlYW0gZm9sbG93cyB0aGUKKyAgICAgKiBydWxlcyBmb3IgOGJpdCB0ZXh0LiAgTGluZXMgaGF2ZSB0byBiZSA5OTggY2hhcmFjdGVycyBvciBsZXNzCisgICAgICogYW5kIG5vIE5VTHMgYXJlIGFsbG93ZWQuICBDUiBhbmQgTEYgbXVzdCBvY2N1ciBpbiBwYWlycyBidXQgd2UKKyAgICAgKiBkb24ndCBjaGVjayB0aGF0IGJlY2F1c2Ugd2UgYXNzdW1lIHRoaXMgaXMgdGV4dCBhbmQgd2UgY29udmVydAorICAgICAqIGFsbCBDUi9MRiBjb21iaW5hdGlvbnMgaW50byBjYW5vbmljYWwgQ1JMRiBsYXRlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gaXM4Qml0KElucHV0U3RyZWFtIGlzKSB7CisJaW50IGI7CisJaW50IGxpbmVsZW4gPSAwOworCWJvb2xlYW4gbmVlZDhiaXQgPSBmYWxzZTsKKwl0cnkgeworCSAgICB3aGlsZSAoKGIgPSBpcy5yZWFkKCkpID49IDApIHsKKwkJYiAmPSAweGZmOworCQlpZiAoYiA9PSAnXHInIHx8IGIgPT0gJ1xuJykKKwkJICAgIGxpbmVsZW4gPSAwOworCQllbHNlIGlmIChiID09IDApCisJCSAgICByZXR1cm4gZmFsc2U7CisJCWVsc2UgeworCQkgICAgbGluZWxlbisrOworCQkgICAgaWYgKGxpbmVsZW4gPiA5OTgpCS8vIDEwMDAgLSBDUkxGCisJCQlyZXR1cm4gZmFsc2U7CisJCX0KKwkJaWYgKGIgPiAweDdmKQorCQkgICAgbmVlZDhiaXQgPSB0cnVlOworCSAgICB9CisJfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKwkgICAgcmV0dXJuIGZhbHNlOworCX0KKwlpZiAobmVlZDhiaXQpCisJICAgIGxvZ2dlci5maW5lKCJmb3VuZCBhbiA4Yml0IHBhcnQiKTsKKwlyZXR1cm4gbmVlZDhiaXQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgZmluYWxpemUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKwl0cnkgeworCSAgICBjbG9zZUNvbm5lY3Rpb24oKTsKKwl9IGNhdGNoIChNZXNzYWdpbmdFeGNlcHRpb24gbWV4KSB7CisJICAgIC8vIGlnbm9yZSBpdAorCX0gZmluYWxseSB7CisJICAgIHN1cGVyLmZpbmFsaXplKCk7CisJfQorICAgIH0KKworICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLyBzbXRwIHN0dWZmIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisgICAgcHJpdmF0ZSBCdWZmZXJlZElucHV0U3RyZWFtIHNlcnZlcklucHV0OworICAgIHByaXZhdGUgTGluZUlucHV0U3RyZWFtICAgICBsaW5lSW5wdXRTdHJlYW07CisgICAgcHJpdmF0ZSBPdXRwdXRTdHJlYW0gICAgICAgIHNlcnZlck91dHB1dDsKKyAgICBwcml2YXRlIFNvY2tldCAgICAgICAgICAgICAgc2VydmVyU29ja2V0OworICAgIHByaXZhdGUgVHJhY2VJbnB1dFN0cmVhbQl0cmFjZUlucHV0OworICAgIHByaXZhdGUgVHJhY2VPdXRwdXRTdHJlYW0JdHJhY2VPdXRwdXQ7CisKKyAgICAvLy8vLy8vIHNtdHAgcHJvdG9jb2wgLy8vLy8vCisKKyAgICAvKioKKyAgICAgKiBJc3N1ZSB0aGUgPGNvZGU+SEVMTzwvY29kZT4gY29tbWFuZC4KKyAgICAgKgorICAgICAqIEBwYXJhbQlkb21haW4Jb3VyIGRvbWFpbgorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjQuMQorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGhlbG8oU3RyaW5nIGRvbWFpbikgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKGRvbWFpbiAhPSBudWxsKQorCSAgICBpc3N1ZUNvbW1hbmQoIkhFTE8gIiArIGRvbWFpbiwgMjUwKTsKKwllbHNlCisJICAgIGlzc3VlQ29tbWFuZCgiSEVMTyIsIDI1MCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSXNzdWUgdGhlIDxjb2RlPkVITE88L2NvZGU+IGNvbW1hbmQuCisgICAgICogQ29sbGVjdCB0aGUgcmV0dXJuZWQgbGlzdCBvZiBzZXJ2aWNlIGV4dGVuc2lvbnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0JZG9tYWluCW91ciBkb21haW4KKyAgICAgKiBAcmV0dXJuCQl0cnVlIGlmIGNvbW1hbmQgc3VjY2VlZHMKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS40LjEKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBlaGxvKFN0cmluZyBkb21haW4pIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCVN0cmluZyBjbWQ7CisJaWYgKGRvbWFpbiAhPSBudWxsKQorCSAgICBjbWQgPSAiRUhMTyAiICsgZG9tYWluOworCWVsc2UKKwkgICAgY21kID0gIkVITE8iOworCXNlbmRDb21tYW5kKGNtZCk7CisJaW50IHJlc3AgPSByZWFkU2VydmVyUmVzcG9uc2UoKTsKKwlpZiAocmVzcCA9PSAyNTApIHsKKwkgICAgLy8gZXh0cmFjdCB0aGUgc3VwcG9ydGVkIHNlcnZpY2UgZXh0ZW5zaW9ucworCSAgICBCdWZmZXJlZFJlYWRlciByZCA9CisJCW5ldyBCdWZmZXJlZFJlYWRlcihuZXcgU3RyaW5nUmVhZGVyKGxhc3RTZXJ2ZXJSZXNwb25zZSkpOworCSAgICBTdHJpbmcgbGluZTsKKwkgICAgZXh0TWFwID0gbmV3IEhhc2h0YWJsZTw+KCk7CisJICAgIHRyeSB7CisJCWJvb2xlYW4gZmlyc3QgPSB0cnVlOworCQl3aGlsZSAoKGxpbmUgPSByZC5yZWFkTGluZSgpKSAhPSBudWxsKSB7CisJCSAgICBpZiAoZmlyc3QpIHsJLy8gc2tpcCBmaXJzdCBsaW5lIHdoaWNoIGlzIHRoZSBncmVldGluZworCQkJZmlyc3QgPSBmYWxzZTsKKwkJCWNvbnRpbnVlOworCQkgICAgfQorCQkgICAgaWYgKGxpbmUubGVuZ3RoKCkgPCA1KQorCQkJY29udGludWU7CQkvLyBzaG91bGRuJ3QgaGFwcGVuCisJCSAgICBsaW5lID0gbGluZS5zdWJzdHJpbmcoNCk7CS8vIHNraXAgcmVzcG9uc2UgY29kZQorCQkgICAgaW50IGkgPSBsaW5lLmluZGV4T2YoJyAnKTsKKwkJICAgIFN0cmluZyBhcmcgPSAiIjsKKwkJICAgIGlmIChpID4gMCkgeworCQkJYXJnID0gbGluZS5zdWJzdHJpbmcoaSArIDEpOworCQkJbGluZSA9IGxpbmUuc3Vic3RyaW5nKDAsIGkpOworCQkgICAgfQorCQkgICAgaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkUpKQorCQkJbG9nZ2VyLmZpbmUoIkZvdW5kIGV4dGVuc2lvbiBcIiIgKworCQkJCQkgICAgbGluZSArICJcIiwgYXJnIFwiIiArIGFyZyArICJcIiIpOworCQkgICAgZXh0TWFwLnB1dChsaW5lLnRvVXBwZXJDYXNlKExvY2FsZS5FTkdMSVNIKSwgYXJnKTsKKwkJfQorCSAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeyB9CS8vIGNhbid0IGhhcHBlbgorCX0KKwlyZXR1cm4gcmVzcCA9PSAyNTA7CisgICAgfQorCisgICAgLyoqCisgICAgICogSXNzdWUgdGhlIDxjb2RlPk1BSUwgRlJPTTo8L2NvZGU+IGNvbW1hbmQgdG8gc3RhcnQgc2VuZGluZyBhIG1lc3NhZ2UuIDxwPgorICAgICAqCisgICAgICogR2V0cyB0aGUgc2VuZGVyJ3MgYWRkcmVzcyBpbiB0aGUgZm9sbG93aW5nIG9yZGVyOgorICAgICAqIDxvbD4KKyAgICAgKiA8bGk+U01UUE1lc3NhZ2UuZ2V0RW52ZWxvcGVGcm9tKCk8L2xpPgorICAgICAqIDxsaT5tYWlsLnNtdHAuZnJvbSBwcm9wZXJ0eTwvbGk+CisgICAgICogPGxpPkZyb206IGhlYWRlciBpbiB0aGUgbWVzc2FnZTwvbGk+CisgICAgICogPGxpPlN5c3RlbSB1c2VybmFtZSB1c2luZyB0aGUKKyAgICAgKiBJbnRlcm5ldEFkZHJlc3MuZ2V0TG9jYWxBZGRyZXNzKCkgbWV0aG9kPC9saT4KKyAgICAgKiA8L29sPgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNC4xCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgbWFpbEZyb20oKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlTdHJpbmcgZnJvbSA9IG51bGw7CisJaWYgKG1lc3NhZ2UgaW5zdGFuY2VvZiBTTVRQTWVzc2FnZSkKKwkgICAgZnJvbSA9ICgoU01UUE1lc3NhZ2UpbWVzc2FnZSkuZ2V0RW52ZWxvcGVGcm9tKCk7CisJaWYgKGZyb20gPT0gbnVsbCB8fCBmcm9tLmxlbmd0aCgpIDw9IDApCisJICAgIGZyb20gPSBzZXNzaW9uLmdldFByb3BlcnR5KCJtYWlsLiIgKyBuYW1lICsgIi5mcm9tIik7CisJaWYgKGZyb20gPT0gbnVsbCB8fCBmcm9tLmxlbmd0aCgpIDw9IDApIHsKKwkgICAgQWRkcmVzc1tdIGZhOworCSAgICBBZGRyZXNzIG1lOworCSAgICBpZiAobWVzc2FnZSAhPSBudWxsICYmIChmYSA9IG1lc3NhZ2UuZ2V0RnJvbSgpKSAhPSBudWxsICYmCisJCSAgICBmYS5sZW5ndGggPiAwKQorCQltZSA9IGZhWzBdOworCSAgICBlbHNlCisJCW1lID0gSW50ZXJuZXRBZGRyZXNzLmdldExvY2FsQWRkcmVzcyhzZXNzaW9uKTsKKworCSAgICBpZiAobWUgIT0gbnVsbCkKKwkJZnJvbSA9ICgoSW50ZXJuZXRBZGRyZXNzKW1lKS5nZXRBZGRyZXNzKCk7CisJICAgIGVsc2UKKwkJdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigKKwkJCQkJImNhbid0IGRldGVybWluZSBsb2NhbCBlbWFpbCBhZGRyZXNzIik7CisJfQorCisJU3RyaW5nIGNtZCA9ICJNQUlMIEZST006IiArIG5vcm1hbGl6ZUFkZHJlc3MoZnJvbSk7CisKKwlpZiAoYWxsb3d1dGY4ICYmIHN1cHBvcnRzRXh0ZW5zaW9uKCJTTVRQVVRGOCIpKQorCSAgICBjbWQgKz0gIiBTTVRQVVRGOCI7CisKKwkvLyByZXF1ZXN0IGRlbGl2ZXJ5IHN0YXR1cyBub3RpZmljYXRpb24/CisJaWYgKHN1cHBvcnRzRXh0ZW5zaW9uKCJEU04iKSkgeworCSAgICBTdHJpbmcgcmV0ID0gbnVsbDsKKwkgICAgaWYgKG1lc3NhZ2UgaW5zdGFuY2VvZiBTTVRQTWVzc2FnZSkKKwkJcmV0ID0gKChTTVRQTWVzc2FnZSltZXNzYWdlKS5nZXREU05SZXQoKTsKKwkgICAgaWYgKHJldCA9PSBudWxsKQorCQlyZXQgPSBzZXNzaW9uLmdldFByb3BlcnR5KCJtYWlsLiIgKyBuYW1lICsgIi5kc24ucmV0Iik7CisJICAgIC8vIFhYWCAtIGNoZWNrIGZvciBsZWdhbCBzeW50YXg/CisJICAgIGlmIChyZXQgIT0gbnVsbCkKKwkJY21kICs9ICIgUkVUPSIgKyByZXQ7CisJfQorCisJLyoKKwkgKiBJZiBhbiBSRkMgMjU1NCBzdWJtaXR0ZXIgaGFzIGJlZW4gc3BlY2lmaWVkLCBhbmQgdGhlIHNlcnZlcgorCSAqIHN1cHBvcnRzIHRoZSBBVVRIIGV4dGVuc2lvbiwgaW5jbHVkZSB0aGUgQVVUSD0gZWxlbWVudCBvbgorCSAqIHRoZSBNQUlMIEZST00gY29tbWFuZC4KKwkgKi8KKwlpZiAoc3VwcG9ydHNFeHRlbnNpb24oIkFVVEgiKSkgeworCSAgICBTdHJpbmcgc3VibWl0dGVyID0gbnVsbDsKKwkgICAgaWYgKG1lc3NhZ2UgaW5zdGFuY2VvZiBTTVRQTWVzc2FnZSkKKwkJc3VibWl0dGVyID0gKChTTVRQTWVzc2FnZSltZXNzYWdlKS5nZXRTdWJtaXR0ZXIoKTsKKwkgICAgaWYgKHN1Ym1pdHRlciA9PSBudWxsKQorCQlzdWJtaXR0ZXIgPSBzZXNzaW9uLmdldFByb3BlcnR5KCJtYWlsLiIgKyBuYW1lICsgIi5zdWJtaXR0ZXIiKTsKKwkgICAgLy8gWFhYIC0gY2hlY2sgZm9yIGxlZ2FsIHN5bnRheD8KKwkgICAgaWYgKHN1Ym1pdHRlciAhPSBudWxsKSB7CisJCXRyeSB7CisJCSAgICBTdHJpbmcgcyA9IHh0ZXh0KHN1Ym1pdHRlciwKKwkJCQkgICAgYWxsb3d1dGY4ICYmIHN1cHBvcnRzRXh0ZW5zaW9uKCJTTVRQVVRGOCIpKTsKKwkJICAgIGNtZCArPSAiIEFVVEg9IiArIHM7CisJCX0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleCkgeworCQkgICAgaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkUpKQorCQkJbG9nZ2VyLmxvZyhMZXZlbC5GSU5FLCAiaWdub3JpbmcgaW52YWxpZCBzdWJtaXR0ZXI6ICIgKworCQkJICAgIHN1Ym1pdHRlciwgZXgpOworCQl9CisJICAgIH0KKwl9CisKKwkvKgorCSAqIEhhdmUgYW55IGV4dGVuc2lvbnMgdG8gdGhlIE1BSUwgY29tbWFuZCBiZWVuIHNwZWNpZmllZD8KKwkgKi8KKwlTdHJpbmcgZXh0ID0gbnVsbDsKKwlpZiAobWVzc2FnZSBpbnN0YW5jZW9mIFNNVFBNZXNzYWdlKQorCSAgICBleHQgPSAoKFNNVFBNZXNzYWdlKW1lc3NhZ2UpLmdldE1haWxFeHRlbnNpb24oKTsKKwlpZiAoZXh0ID09IG51bGwpCisJICAgIGV4dCA9IHNlc3Npb24uZ2V0UHJvcGVydHkoIm1haWwuIiArIG5hbWUgKyAiLm1haWxleHRlbnNpb24iKTsKKwlpZiAoZXh0ICE9IG51bGwgJiYgZXh0Lmxlbmd0aCgpID4gMCkKKwkgICAgY21kICs9ICIgIiArIGV4dDsKKworCXRyeSB7CisJICAgIGlzc3VlU2VuZENvbW1hbmQoY21kLCAyNTApOworCX0gY2F0Y2ggKFNNVFBTZW5kRmFpbGVkRXhjZXB0aW9uIGV4KSB7CisJICAgIGludCByZXRDb2RlID0gZXguZ2V0UmV0dXJuQ29kZSgpOworCSAgICBzd2l0Y2ggKHJldENvZGUpIHsKKwkgICAgY2FzZSA1NTA6IGNhc2UgNTUzOiBjYXNlIDUwMzogY2FzZSA1NTE6IGNhc2UgNTAxOgorCQkvLyBnaXZlbiBhZGRyZXNzIGlzIGludmFsaWQKKwkJdHJ5IHsKKwkJICAgIGV4LnNldE5leHRFeGNlcHRpb24obmV3IFNNVFBTZW5kZXJGYWlsZWRFeGNlcHRpb24oCisJCQluZXcgSW50ZXJuZXRBZGRyZXNzKGZyb20pLCBjbWQsCisJCQlyZXRDb2RlLCBleC5nZXRNZXNzYWdlKCkpKTsKKwkJfSBjYXRjaCAoQWRkcmVzc0V4Y2VwdGlvbiBhZXgpIHsKKwkJICAgIC8vIG9oIHdlbGwuLi4KKwkJfQorCQlicmVhazsKKwkgICAgZGVmYXVsdDoKKwkJYnJlYWs7CisJICAgIH0KKwkgICAgdGhyb3cgZXg7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNlbmRzIGVhY2ggYWRkcmVzcyB0byB0aGUgU01UUCBob3N0IHVzaW5nIHRoZSA8Y29kZT5SQ1BUIFRPOjwvY29kZT4KKyAgICAgKiBjb21tYW5kIGFuZCBjb3BpZXMgdGhlIGFkZHJlc3MgZWl0aGVyIGludG8KKyAgICAgKiB0aGUgdmFsaWRTZW50QWRkciBvciBpbnZhbGlkQWRkciBhcnJheXMuCisgICAgICogU2V0cyB0aGUgPGNvZGU+c2VuZEZhaWxlZDwvY29kZT4KKyAgICAgKiBmbGFnIHRvIHRydWUgaWYgYW55IGFkZHJlc3NlcyBmYWlsZWQuCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS40LjEKKyAgICAgKi8KKyAgICAvKgorICAgICAqIHN1Y2Nlc3MvZmFpbHVyZS9lcnJvciBwb3NzaWJpbGl0aWVzIGZyb20gdGhlIFJDUFQgY29tbWFuZAorICAgICAqIGZyb20gcmZjODIxLCBzZWN0aW9uIDQuMworICAgICAqIFM6IDI1MCwgMjUxCisgICAgICogRjogNTUwLCA1NTEsIDU1MiwgNTUzLCA0NTAsIDQ1MSwgNDUyCisgICAgICogRTogNTAwLCA1MDEsIDUwMywgNDIxCisgICAgICoKKyAgICAgKiBhbmQgaG93IHdlIG1hcCB0aGUgYWJvdmUgZXJyb3IvZmFpbHVyZSBjb25kaXRpb25zIHRvIHZhbGlkL2ludmFsaWQKKyAgICAgKiBhZGRyZXNzIGxpc3RzIHRoYXQgYXJlIHJlcG9ydGVkIGluIHRoZSB0aHJvd24gZXhjZXB0aW9uOgorICAgICAqIGludmFsaWQgYWRkcjogNTUwLCA1MDEsIDUwMywgNTUxLCA1NTMKKyAgICAgKiB2YWxpZCBhZGRyOiA1NTIgKHF1b3RhKSwgNDUwLCA0NTEsIDQ1MiAocXVvdGEpLCA0MjEgKHNydnIgYWJvcnQpCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgcmNwdFRvKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJTGlzdDxJbnRlcm5ldEFkZHJlc3M+IHZhbGlkID0gbmV3IEFycmF5TGlzdDw+KCk7CisJTGlzdDxJbnRlcm5ldEFkZHJlc3M+IHZhbGlkVW5zZW50ID0gbmV3IEFycmF5TGlzdDw+KCk7CisJTGlzdDxJbnRlcm5ldEFkZHJlc3M+IGludmFsaWQgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKwlpbnQgcmV0Q29kZSA9IC0xOworCU1lc3NhZ2luZ0V4Y2VwdGlvbiBtZXggPSBudWxsOworCWJvb2xlYW4gc2VuZEZhaWxlZCA9IGZhbHNlOworCU1lc3NhZ2luZ0V4Y2VwdGlvbiBzZmV4ID0gbnVsbDsKKwl2YWxpZFNlbnRBZGRyID0gdmFsaWRVbnNlbnRBZGRyID0gaW52YWxpZEFkZHIgPSBudWxsOworCWJvb2xlYW4gc2VuZFBhcnRpYWwgPSBmYWxzZTsKKwlpZiAobWVzc2FnZSBpbnN0YW5jZW9mIFNNVFBNZXNzYWdlKQorCSAgICBzZW5kUGFydGlhbCA9ICgoU01UUE1lc3NhZ2UpbWVzc2FnZSkuZ2V0U2VuZFBhcnRpYWwoKTsKKwlpZiAoIXNlbmRQYXJ0aWFsKQorCSAgICBzZW5kUGFydGlhbCA9IFByb3BVdGlsLmdldEJvb2xlYW5Qcm9wZXJ0eShzZXNzaW9uLmdldFByb3BlcnRpZXMoKSwKKwkJCQkJIm1haWwuIiArIG5hbWUgKyAiLnNlbmRwYXJ0aWFsIiwgZmFsc2UpOworCWlmIChzZW5kUGFydGlhbCkKKwkgICAgbG9nZ2VyLmZpbmUoInNlbmRQYXJ0aWFsIHNldCIpOworCisJYm9vbGVhbiBkc24gPSBmYWxzZTsKKwlTdHJpbmcgbm90aWZ5ID0gbnVsbDsKKwlpZiAoc3VwcG9ydHNFeHRlbnNpb24oIkRTTiIpKSB7CisJICAgIGlmIChtZXNzYWdlIGluc3RhbmNlb2YgU01UUE1lc3NhZ2UpCisJCW5vdGlmeSA9ICgoU01UUE1lc3NhZ2UpbWVzc2FnZSkuZ2V0RFNOTm90aWZ5KCk7CisJICAgIGlmIChub3RpZnkgPT0gbnVsbCkKKwkJbm90aWZ5ID0gc2Vzc2lvbi5nZXRQcm9wZXJ0eSgibWFpbC4iICsgbmFtZSArICIuZHNuLm5vdGlmeSIpOworCSAgICAvLyBYWFggLSBjaGVjayBmb3IgbGVnYWwgc3ludGF4PworCSAgICBpZiAobm90aWZ5ICE9IG51bGwpCisJCWRzbiA9IHRydWU7CisJfQorCisJLy8gdHJ5IHRoZSBhZGRyZXNzZXMgb25lIGF0IGEgdGltZQorCWZvciAoaW50IGkgPSAwOyBpIDwgYWRkcmVzc2VzLmxlbmd0aDsgaSsrKSB7CisKKwkgICAgc2ZleCA9IG51bGw7CisJICAgIEludGVybmV0QWRkcmVzcyBpYSA9IChJbnRlcm5ldEFkZHJlc3MpYWRkcmVzc2VzW2ldOworCSAgICBTdHJpbmcgY21kID0gIlJDUFQgVE86IiArIG5vcm1hbGl6ZUFkZHJlc3MoaWEuZ2V0QWRkcmVzcygpKTsKKwkgICAgaWYgKGRzbikKKwkJY21kICs9ICIgTk9USUZZPSIgKyBub3RpZnk7CisJICAgIC8vIHNlbmQgdGhlIGFkZHJlc3NlcyB0byB0aGUgU01UUCBzZXJ2ZXIKKwkgICAgc2VuZENvbW1hbmQoY21kKTsKKwkgICAgLy8gY2hlY2sgdGhlIHNlcnZlcidzIHJlc3BvbnNlIGZvciBhZGRyZXNzIHZhbGlkaXR5CisJICAgIHJldENvZGUgPSByZWFkU2VydmVyUmVzcG9uc2UoKTsKKwkgICAgc3dpdGNoIChyZXRDb2RlKSB7CisJICAgIGNhc2UgMjUwOiBjYXNlIDI1MToKKwkJdmFsaWQuYWRkKGlhKTsKKwkJaWYgKCFyZXBvcnRTdWNjZXNzKQorCQkgICAgYnJlYWs7CisKKwkJLy8gdXNlciB3YW50cyBleGNlcHRpb24gZXZlbiB3aGVuIHN1Y2Nlc3NmdWwsIGluY2x1ZGluZworCQkvLyBkZXRhaWxzIG9mIHRoZSByZXR1cm4gY29kZQorCisJCS8vIGNyZWF0ZSBhbmQgY2hhaW4gdGhlIGV4Y2VwdGlvbgorCQlzZmV4ID0gbmV3IFNNVFBBZGRyZXNzU3VjY2VlZGVkRXhjZXB0aW9uKGlhLCBjbWQsIHJldENvZGUsCisJCQkJCQkJbGFzdFNlcnZlclJlc3BvbnNlKTsKKwkJaWYgKG1leCA9PSBudWxsKQorCQkgICAgbWV4ID0gc2ZleDsKKwkJZWxzZQorCQkgICAgbWV4LnNldE5leHRFeGNlcHRpb24oc2ZleCk7CisJCWJyZWFrOworCisJICAgIGNhc2UgNTUwOiBjYXNlIDU1MzogY2FzZSA1MDM6IGNhc2UgNTUxOiBjYXNlIDUwMToKKwkJLy8gZ2l2ZW4gYWRkcmVzcyBpcyBpbnZhbGlkCisJCWlmICghc2VuZFBhcnRpYWwpCisJCSAgICBzZW5kRmFpbGVkID0gdHJ1ZTsKKwkJaW52YWxpZC5hZGQoaWEpOworCQkvLyBjcmVhdGUgYW5kIGNoYWluIHRoZSBleGNlcHRpb24KKwkJc2ZleCA9IG5ldyBTTVRQQWRkcmVzc0ZhaWxlZEV4Y2VwdGlvbihpYSwgY21kLCByZXRDb2RlLAorCQkJCQkJCWxhc3RTZXJ2ZXJSZXNwb25zZSk7CisJCWlmIChtZXggPT0gbnVsbCkKKwkJICAgIG1leCA9IHNmZXg7CisJCWVsc2UKKwkJICAgIG1leC5zZXROZXh0RXhjZXB0aW9uKHNmZXgpOworCQlicmVhazsKKworCSAgICBjYXNlIDU1MjogY2FzZSA0NTA6IGNhc2UgNDUxOiBjYXNlIDQ1MjoKKwkJLy8gZ2l2ZW4gYWRkcmVzcyBpcyB2YWxpZAorCQlpZiAoIXNlbmRQYXJ0aWFsKQorCQkgICAgc2VuZEZhaWxlZCA9IHRydWU7CisJCXZhbGlkVW5zZW50LmFkZChpYSk7CisJCS8vIGNyZWF0ZSBhbmQgY2hhaW4gdGhlIGV4Y2VwdGlvbgorCQlzZmV4ID0gbmV3IFNNVFBBZGRyZXNzRmFpbGVkRXhjZXB0aW9uKGlhLCBjbWQsIHJldENvZGUsCisJCQkJCQkJbGFzdFNlcnZlclJlc3BvbnNlKTsKKwkJaWYgKG1leCA9PSBudWxsKQorCQkgICAgbWV4ID0gc2ZleDsKKwkJZWxzZQorCQkgICAgbWV4LnNldE5leHRFeGNlcHRpb24oc2ZleCk7CisJCWJyZWFrOworCisJICAgIGRlZmF1bHQ6CisJCS8vIGhhbmRsZSByZW1haW5pbmcgNHh5ICYgNXh5IGNvZGVzCisJCWlmIChyZXRDb2RlID49IDQwMCAmJiByZXRDb2RlIDw9IDQ5OSkgeworCQkgICAgLy8gYXNzdW1lIGFkZHJlc3MgaXMgdmFsaWQsIGFsdGhvdWdoIHdlIGRvbid0IHJlYWxseSBrbm93CisJCSAgICB2YWxpZFVuc2VudC5hZGQoaWEpOworCQl9IGVsc2UgaWYgKHJldENvZGUgPj0gNTAwICYmIHJldENvZGUgPD0gNTk5KSB7CisJCSAgICAvLyBhc3N1bWUgYWRkcmVzcyBpcyBpbnZhbGlkLCBhbHRob3VnaCB3ZSBkb24ndCByZWFsbHkga25vdworCQkgICAgaW52YWxpZC5hZGQoaWEpOworCQl9IGVsc2UgeworCQkgICAgLy8gY29tcGxldGVseSB1bmV4cGVjdGVkIHJlc3BvbnNlLCBqdXN0IGdpdmUgdXAKKwkJICAgIGlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FKSkKKwkJCWxvZ2dlci5maW5lKCJnb3QgcmVzcG9uc2UgY29kZSAiICsgcmV0Q29kZSArCisJCQkgICAgIiwgd2l0aCByZXNwb25zZTogIiArIGxhc3RTZXJ2ZXJSZXNwb25zZSk7CisJCSAgICBTdHJpbmcgX2xzciA9IGxhc3RTZXJ2ZXJSZXNwb25zZTsgLy8gZWxzZSByc2V0IHdpbGwgbnVrZSBpdAorCQkgICAgaW50IF9scmMgPSBsYXN0UmV0dXJuQ29kZTsKKwkJICAgIGlmIChzZXJ2ZXJTb2NrZXQgIT0gbnVsbCkJLy8gaGFzbid0IGFscmVhZHkgYmVlbiBjbG9zZWQKKwkJCWlzc3VlQ29tbWFuZCgiUlNFVCIsIC0xKTsKKwkJICAgIGxhc3RTZXJ2ZXJSZXNwb25zZSA9IF9sc3I7CS8vIHJlc3RvcmUsIGZvciBnZXQKKwkJICAgIGxhc3RSZXR1cm5Db2RlID0gX2xyYzsKKwkJICAgIHRocm93IG5ldyBTTVRQQWRkcmVzc0ZhaWxlZEV4Y2VwdGlvbihpYSwgY21kLCByZXRDb2RlLAorCQkJCQkJCQlfbHNyKTsKKwkJfQorCQlpZiAoIXNlbmRQYXJ0aWFsKQorCQkgICAgc2VuZEZhaWxlZCA9IHRydWU7CisJCS8vIGNyZWF0ZSBhbmQgY2hhaW4gdGhlIGV4Y2VwdGlvbgorCQlzZmV4ID0gbmV3IFNNVFBBZGRyZXNzRmFpbGVkRXhjZXB0aW9uKGlhLCBjbWQsIHJldENvZGUsCisJCQkJCQkJbGFzdFNlcnZlclJlc3BvbnNlKTsKKwkJaWYgKG1leCA9PSBudWxsKQorCQkgICAgbWV4ID0gc2ZleDsKKwkJZWxzZQorCQkgICAgbWV4LnNldE5leHRFeGNlcHRpb24oc2ZleCk7CisJCWJyZWFrOworCSAgICB9CisJfQorCisJLy8gaWYgd2UncmUgd2lsbGluZyB0byBzZW5kIHRvIGEgcGFydGlhbCBsaXN0LCBhbmQgd2UgZm91bmQgbm8KKwkvLyB2YWxpZCBhZGRyZXNzZXMsIHRoYXQncyBjb21wbGV0ZSBmYWlsdXJlCisJaWYgKHNlbmRQYXJ0aWFsICYmIHZhbGlkLnNpemUoKSA9PSAwKQorCSAgICBzZW5kRmFpbGVkID0gdHJ1ZTsKKworCS8vIGNvcHkgdGhlIGxpc3RzIGludG8gYXBwcm9wcmlhdGUgYXJyYXlzCisJaWYgKHNlbmRGYWlsZWQpIHsKKwkgICAgLy8gY29weSBpbnZhbGlkIGFkZHJzCisJICAgIGludmFsaWRBZGRyID0gbmV3IEFkZHJlc3NbaW52YWxpZC5zaXplKCldOworCSAgICBpbnZhbGlkLnRvQXJyYXkoaW52YWxpZEFkZHIpOworCisJICAgIC8vIGNvcHkgYWxsIHZhbGlkIGFkZHJlc3NlcyB0byB2YWxpZFVuc2VudCwgc2luY2Ugc29tZXRoaW5nIGZhaWxlZAorCSAgICB2YWxpZFVuc2VudEFkZHIgPSBuZXcgQWRkcmVzc1t2YWxpZC5zaXplKCkgKyB2YWxpZFVuc2VudC5zaXplKCldOworCSAgICBpbnQgaSA9IDA7CisJICAgIGZvciAoaW50IGogPSAwOyBqIDwgdmFsaWQuc2l6ZSgpOyBqKyspCisJCXZhbGlkVW5zZW50QWRkcltpKytdID0gKEFkZHJlc3MpdmFsaWQuZ2V0KGopOworCSAgICBmb3IgKGludCBqID0gMDsgaiA8IHZhbGlkVW5zZW50LnNpemUoKTsgaisrKQorCQl2YWxpZFVuc2VudEFkZHJbaSsrXSA9IChBZGRyZXNzKXZhbGlkVW5zZW50LmdldChqKTsKKwl9IGVsc2UgaWYgKHJlcG9ydFN1Y2Nlc3MgfHwgKHNlbmRQYXJ0aWFsICYmCisJCQkoaW52YWxpZC5zaXplKCkgPiAwIHx8IHZhbGlkVW5zZW50LnNpemUoKSA+IDApKSkgeworCSAgICAvLyB3ZSdsbCBnbyBvbiB0byBzZW5kIHRoZSBtZXNzYWdlLCBidXQgYWZ0ZXIgc2VuZGluZyB3ZSdsbAorCSAgICAvLyB0aHJvdyBhbiBleGNlcHRpb24gd2l0aCB0aGlzIGV4Y2VwdGlvbiBuZXN0ZWQKKwkgICAgc2VuZFBhcnRpYWxseUZhaWxlZCA9IHRydWU7CisJICAgIGV4Y2VwdGlvbiA9IG1leDsKKworCSAgICAvLyBjb3B5IGludmFsaWQgYWRkcnMKKwkgICAgaW52YWxpZEFkZHIgPSBuZXcgQWRkcmVzc1tpbnZhbGlkLnNpemUoKV07CisJICAgIGludmFsaWQudG9BcnJheShpbnZhbGlkQWRkcik7CisKKwkgICAgLy8gY29weSB2YWxpZCB1bnNlbnQgYWRkcmVzc2VzIHRvIHZhbGlkVW5zZW50CisJICAgIHZhbGlkVW5zZW50QWRkciA9IG5ldyBBZGRyZXNzW3ZhbGlkVW5zZW50LnNpemUoKV07CisJICAgIHZhbGlkVW5zZW50LnRvQXJyYXkodmFsaWRVbnNlbnRBZGRyKTsKKworCSAgICAvLyBjb3B5IHZhbGlkIGFkZHJlc3NlcyB0byB2YWxpZFNlbnQKKwkgICAgdmFsaWRTZW50QWRkciA9IG5ldyBBZGRyZXNzW3ZhbGlkLnNpemUoKV07CisJICAgIHZhbGlkLnRvQXJyYXkodmFsaWRTZW50QWRkcik7CisJfSBlbHNlIHsgICAgICAgIC8vIGFsbCBhZGRyZXNzZXMgcGFzcworCSAgICB2YWxpZFNlbnRBZGRyID0gYWRkcmVzc2VzOworCX0KKworCisJLy8gcHJpbnQgb3V0IHRoZSBkZWJ1ZyBpbmZvCisJaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkUpKSB7CisJICAgIGlmICh2YWxpZFNlbnRBZGRyICE9IG51bGwgJiYgdmFsaWRTZW50QWRkci5sZW5ndGggPiAwKSB7CisJCWxvZ2dlci5maW5lKCJWZXJpZmllZCBBZGRyZXNzZXMiKTsKKwkJZm9yIChpbnQgbCA9IDA7IGwgPCB2YWxpZFNlbnRBZGRyLmxlbmd0aDsgbCsrKSB7CisJCSAgICBsb2dnZXIuZmluZSgiICAiICsgdmFsaWRTZW50QWRkcltsXSk7CisJCX0KKwkgICAgfQorCSAgICBpZiAodmFsaWRVbnNlbnRBZGRyICE9IG51bGwgJiYgdmFsaWRVbnNlbnRBZGRyLmxlbmd0aCA+IDApIHsKKwkJbG9nZ2VyLmZpbmUoIlZhbGlkIFVuc2VudCBBZGRyZXNzZXMiKTsKKwkJZm9yIChpbnQgaiA9IDA7IGogPCB2YWxpZFVuc2VudEFkZHIubGVuZ3RoOyBqKyspIHsKKwkJICAgIGxvZ2dlci5maW5lKCIgICIgKyB2YWxpZFVuc2VudEFkZHJbal0pOworCQl9CisJICAgIH0KKwkgICAgaWYgKGludmFsaWRBZGRyICE9IG51bGwgJiYgaW52YWxpZEFkZHIubGVuZ3RoID4gMCkgeworCQlsb2dnZXIuZmluZSgiSW52YWxpZCBBZGRyZXNzZXMiKTsKKwkJZm9yIChpbnQgayA9IDA7IGsgPCBpbnZhbGlkQWRkci5sZW5ndGg7IGsrKykgeworCQkgICAgbG9nZ2VyLmZpbmUoIiAgIiArIGludmFsaWRBZGRyW2tdKTsKKwkJfQorCSAgICB9CisJfQorCisJLy8gdGhyb3cgdGhlIGV4Y2VwdGlvbiwgZmlyZSBUcmFuc3BvcnRFdmVudC5NRVNTQUdFX05PVF9ERUxJVkVSRUQgZXZlbnQKKwlpZiAoc2VuZEZhaWxlZCkgeworCSAgICBsb2dnZXIuZmluZSgKKwkJIlNlbmRpbmcgZmFpbGVkIGJlY2F1c2Ugb2YgaW52YWxpZCBkZXN0aW5hdGlvbiBhZGRyZXNzZXMiKTsKKwkgICAgbm90aWZ5VHJhbnNwb3J0TGlzdGVuZXJzKFRyYW5zcG9ydEV2ZW50Lk1FU1NBR0VfTk9UX0RFTElWRVJFRCwKKwkJCQkgICAgIHZhbGlkU2VudEFkZHIsIHZhbGlkVW5zZW50QWRkciwKKwkJCQkgICAgIGludmFsaWRBZGRyLCB0aGlzLm1lc3NhZ2UpOworCisJICAgIC8vIHJlc2V0IHRoZSBjb25uZWN0aW9uIHNvIG1vcmUgc2VuZHMgYXJlIGFsbG93ZWQKKwkgICAgU3RyaW5nIGxzciA9IGxhc3RTZXJ2ZXJSZXNwb25zZTsJLy8gc2F2ZSwgZm9yIGdldAorCSAgICBpbnQgbHJjID0gbGFzdFJldHVybkNvZGU7CisJICAgIHRyeSB7CisJCWlmIChzZXJ2ZXJTb2NrZXQgIT0gbnVsbCkKKwkJICAgIGlzc3VlQ29tbWFuZCgiUlNFVCIsIC0xKTsKKwkgICAgfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIGV4KSB7CisJCS8vIGlmIGNhbid0IHJlc2V0LCBiZXN0IHRvIGNsb3NlIHRoZSBjb25uZWN0aW9uCisJCXRyeSB7CisJCSAgICBjbG9zZSgpOworCQl9IGNhdGNoIChNZXNzYWdpbmdFeGNlcHRpb24gZXgyKSB7CisJCSAgICAvLyB0aHJvd24gYnkgY2xvc2UoKS0taWdub3JlLCB3aWxsIGNsb3NlKCkgbGF0ZXIgYW55d2F5CisJCSAgICBsb2dnZXIubG9nKExldmVsLkZJTkUsICJjbG9zZSBmYWlsZWQiLCBleDIpOworCQl9CisJICAgIH0gZmluYWxseSB7CisJCWxhc3RTZXJ2ZXJSZXNwb25zZSA9IGxzcjsJLy8gcmVzdG9yZQorCQlsYXN0UmV0dXJuQ29kZSA9IGxyYzsKKwkgICAgfQorCisJICAgIHRocm93IG5ldyBTZW5kRmFpbGVkRXhjZXB0aW9uKCJJbnZhbGlkIEFkZHJlc3NlcyIsIG1leCwKKwkJCQkJICB2YWxpZFNlbnRBZGRyLAorCQkJCQkgIHZhbGlkVW5zZW50QWRkciwgaW52YWxpZEFkZHIpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZW5kIHRoZSA8Y29kZT5EQVRBPC9jb2RlPiBjb21tYW5kIHRvIHRoZSBTTVRQIGhvc3QgYW5kIHJldHVybgorICAgICAqIGFuIE91dHB1dFN0cmVhbSB0byB3aGljaCB0aGUgZGF0YSBpcyB0byBiZSB3cml0dGVuLgorICAgICAqCisgICAgICogQHJldHVybgkJdGhlIHN0cmVhbSB0byB3cml0ZSB0bworICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjQuMQorICAgICAqLworICAgIHByb3RlY3RlZCBPdXRwdXRTdHJlYW0gZGF0YSgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWFzc2VydCBUaHJlYWQuaG9sZHNMb2NrKHRoaXMpOworCWlzc3VlU2VuZENvbW1hbmQoIkRBVEEiLCAzNTQpOworCWRhdGFTdHJlYW0gPSBuZXcgU01UUE91dHB1dFN0cmVhbShzZXJ2ZXJPdXRwdXQpOworCXJldHVybiBkYXRhU3RyZWFtOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlcm1pbmF0ZSB0aGUgc2VudCBkYXRhLgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbglJT0V4Y2VwdGlvbiBmb3IgSS9PIGVycm9ycworICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBvdGhlciBmYWlsdXJlcworICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjQuMQorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGZpbmlzaERhdGEoKSB0aHJvd3MgSU9FeGNlcHRpb24sIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJYXNzZXJ0IFRocmVhZC5ob2xkc0xvY2sodGhpcyk7CisJZGF0YVN0cmVhbS5lbnN1cmVBdEJPTCgpOworCWlzc3VlU2VuZENvbW1hbmQoIi4iLCAyNTApOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiBhIHN0cmVhbSB0aGF0IHdpbGwgdXNlIHRoZSBTTVRQIEJEQVQgY29tbWFuZCB0byBzZW5kIGRhdGEuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCQl0aGUgc3RyZWFtIHRvIHdyaXRlIHRvCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNi4wCisgICAgICovCisgICAgcHJvdGVjdGVkIE91dHB1dFN0cmVhbSBiZGF0KCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJYXNzZXJ0IFRocmVhZC5ob2xkc0xvY2sodGhpcyk7CisJZGF0YVN0cmVhbSA9IG5ldyBCREFUT3V0cHV0U3RyZWFtKHNlcnZlck91dHB1dCwgY2h1bmtTaXplKTsKKwlyZXR1cm4gZGF0YVN0cmVhbTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXJtaW5hdGUgdGhlIHNlbnQgZGF0YS4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24JSU9FeGNlcHRpb24gZm9yIEkvTyBlcnJvcnMKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS42LjAKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBmaW5pc2hCZGF0KCkgdGhyb3dzIElPRXhjZXB0aW9uLCBNZXNzYWdpbmdFeGNlcHRpb24geworCWFzc2VydCBUaHJlYWQuaG9sZHNMb2NrKHRoaXMpOworCWRhdGFTdHJlYW0uZW5zdXJlQXRCT0woKTsKKwlkYXRhU3RyZWFtLmNsb3NlKCk7CS8vIGRvZXNuJ3QgY2xvc2UgdW5kZXJseWluZyBzb2NrZXQKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJc3N1ZSB0aGUgPGNvZGU+U1RBUlRUTFM8L2NvZGU+IGNvbW1hbmQgYW5kIHN3aXRjaCB0aGUgc29ja2V0IHRvCisgICAgICogVExTIG1vZGUgaWYgaXQgc3VjY2VlZHMuCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS40LjEKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzdGFydFRMUygpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWlzc3VlQ29tbWFuZCgiU1RBUlRUTFMiLCAyMjApOworCS8vIGl0IHdvcmtlZCwgbm93IHN3aXRjaCB0aGUgc29ja2V0IGludG8gVExTIG1vZGUKKwl0cnkgeworCSAgICBzZXJ2ZXJTb2NrZXQgPSBTb2NrZXRGZXRjaGVyLnN0YXJ0VExTKHNlcnZlclNvY2tldCwgaG9zdCwKKwkJCQlzZXNzaW9uLmdldFByb3BlcnRpZXMoKSwgIm1haWwuIiArIG5hbWUpOworCSAgICBpbml0U3RyZWFtcygpOworCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZXgpIHsKKwkgICAgY2xvc2VDb25uZWN0aW9uKCk7CisJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oIkNvdWxkIG5vdCBjb252ZXJ0IHNvY2tldCB0byBUTFMiLAorCQkJCQkJCQlpb2V4KTsKKwl9CisgICAgfQorCisgICAgLy8vLy8vLyBwcmltaXRpdmVzIC8vLy8vLy8KKworICAgIC8qKgorICAgICAqIENvbm5lY3QgdG8gaG9zdCBvbiBwb3J0IGFuZCBzdGFydCB0aGUgU01UUCBwcm90b2NvbC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgb3BlblNlcnZlcihTdHJpbmcgaG9zdCwgaW50IHBvcnQpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisKKyAgICAgICAgaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkUpKQorCSAgICBsb2dnZXIuZmluZSgidHJ5aW5nIHRvIGNvbm5lY3QgdG8gaG9zdCBcIiIgKyBob3N0ICsKKwkJCQkiXCIsIHBvcnQgIiArIHBvcnQgKyAiLCBpc1NTTCAiICsgaXNTU0wpOworCisJdHJ5IHsKKwkgICAgUHJvcGVydGllcyBwcm9wcyA9IHNlc3Npb24uZ2V0UHJvcGVydGllcygpOworCisJICAgIHNlcnZlclNvY2tldCA9IFNvY2tldEZldGNoZXIuZ2V0U29ja2V0KGhvc3QsIHBvcnQsCisJCXByb3BzLCAibWFpbC4iICsgbmFtZSwgaXNTU0wpOworCisJICAgIC8vIHNvY2tldCBmYWN0b3J5IG1heSd2ZSBjaG9zZW4gYSBkaWZmZXJlbnQgcG9ydCwKKwkgICAgLy8gdXBkYXRlIGl0IGZvciB0aGUgZGVidWcgbWVzc2FnZXMgdGhhdCBmb2xsb3cKKwkgICAgcG9ydCA9IHNlcnZlclNvY2tldC5nZXRQb3J0KCk7CisJICAgIC8vIHNhdmUgaG9zdCBuYW1lIGZvciBzdGFydFRMUworCSAgICB0aGlzLmhvc3QgPSBob3N0OworCisJICAgIGluaXRTdHJlYW1zKCk7CisKKwkgICAgaW50IHIgPSAtMTsKKwkgICAgaWYgKChyID0gcmVhZFNlcnZlclJlc3BvbnNlKCkpICE9IDIyMCkgeworCQlzZXJ2ZXJTb2NrZXQuY2xvc2UoKTsKKwkJc2VydmVyU29ja2V0ID0gbnVsbDsKKwkJc2VydmVyT3V0cHV0ID0gbnVsbDsKKwkJc2VydmVySW5wdXQgPSBudWxsOworCQlsaW5lSW5wdXRTdHJlYW0gPSBudWxsOworCQlpZiAobG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuRklORSkpCisJCSAgICBsb2dnZXIuZmluZSgiY291bGQgbm90IGNvbm5lY3QgdG8gaG9zdCBcIiIgKworCQkJCSAgICBob3N0ICsgIlwiLCBwb3J0OiAiICsgcG9ydCArCisJCQkJICAgICIsIHJlc3BvbnNlOiAiICsgcik7CisJCXRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oCisJCQkiQ291bGQgbm90IGNvbm5lY3QgdG8gU01UUCBob3N0OiAiICsgaG9zdCArCisJCQkJICAgICIsIHBvcnQ6ICIgKyBwb3J0ICsKKwkJCQkgICAgIiwgcmVzcG9uc2U6ICIgKyByKTsKKwkgICAgfSBlbHNlIHsKKwkJaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkUpKQorCQkgICAgbG9nZ2VyLmZpbmUoImNvbm5lY3RlZCB0byBob3N0IFwiIiArCisJCQkJICAgICAgIGhvc3QgKyAiXCIsIHBvcnQ6ICIgKyBwb3J0KTsKKwkgICAgfQorCX0gY2F0Y2ggKFVua25vd25Ib3N0RXhjZXB0aW9uIHVoZXgpIHsKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiVW5rbm93biBTTVRQIGhvc3Q6ICIgKyBob3N0LCB1aGV4KTsKKwl9IGNhdGNoIChTb2NrZXRDb25uZWN0RXhjZXB0aW9uIHNjZXgpIHsKKwkgICAgdGhyb3cgbmV3IE1haWxDb25uZWN0RXhjZXB0aW9uKHNjZXgpOworCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkgeworCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKCJDb3VsZCBub3QgY29ubmVjdCB0byBTTVRQIGhvc3Q6ICIgKworCQkJCSAgICBob3N0ICsgIiwgcG9ydDogIiArIHBvcnQsIGlvZSk7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFN0YXJ0IHRoZSBwcm90b2NvbCB0byB0aGUgc2VydmVyIG9uIHNlcnZlclNvY2tldCwKKyAgICAgKiBhc3N1bWVkIHRvIGJlIHByb3ZpZGVkIGFuZCBjb25uZWN0ZWQgYnkgdGhlIGNhbGxlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgb3BlblNlcnZlcigpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWludCBwb3J0ID0gLTE7CisJaG9zdCA9ICJVTktOT1dOIjsKKwl0cnkgeworCSAgICBwb3J0ID0gc2VydmVyU29ja2V0LmdldFBvcnQoKTsKKwkgICAgaG9zdCA9IHNlcnZlclNvY2tldC5nZXRJbmV0QWRkcmVzcygpLmdldEhvc3ROYW1lKCk7CisJICAgIGlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FKSkKKwkJbG9nZ2VyLmZpbmUoInN0YXJ0aW5nIHByb3RvY29sIHRvIGhvc3QgXCIiICsKKwkJCQkJaG9zdCArICJcIiwgcG9ydCAiICsgcG9ydCk7CisKKwkgICAgaW5pdFN0cmVhbXMoKTsKKworCSAgICBpbnQgciA9IC0xOworCSAgICBpZiAoKHIgPSByZWFkU2VydmVyUmVzcG9uc2UoKSkgIT0gMjIwKSB7CisJCXNlcnZlclNvY2tldC5jbG9zZSgpOworCQlzZXJ2ZXJTb2NrZXQgPSBudWxsOworCQlzZXJ2ZXJPdXRwdXQgPSBudWxsOworCQlzZXJ2ZXJJbnB1dCA9IG51bGw7CisJCWxpbmVJbnB1dFN0cmVhbSA9IG51bGw7CisJCWlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FKSkKKwkJICAgIGxvZ2dlci5maW5lKCJnb3QgYmFkIGdyZWV0aW5nIGZyb20gaG9zdCBcIiIgKworCQkJCSAgICBob3N0ICsgIlwiLCBwb3J0OiAiICsgcG9ydCArCisJCQkJICAgICIsIHJlc3BvbnNlOiAiICsgcik7CisJCXRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oCisJCQkiR290IGJhZCBncmVldGluZyBmcm9tIFNNVFAgaG9zdDogIiArIGhvc3QgKworCQkJCSAgICAiLCBwb3J0OiAiICsgcG9ydCArCisJCQkJICAgICIsIHJlc3BvbnNlOiAiICsgcik7CisJICAgIH0gZWxzZSB7CisJCWlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FKSkKKwkJICAgIGxvZ2dlci5maW5lKCJwcm90b2NvbCBzdGFydGVkIHRvIGhvc3QgXCIiICsKKwkJCQkgICAgICAgaG9zdCArICJcIiwgcG9ydDogIiArIHBvcnQpOworCSAgICB9CisJfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9lKSB7CisJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oCisJCQkJICAgICJDb3VsZCBub3Qgc3RhcnQgcHJvdG9jb2wgdG8gU01UUCBob3N0OiAiICsKKwkJCQkgICAgaG9zdCArICIsIHBvcnQ6ICIgKyBwb3J0LCBpb2UpOworCX0KKyAgICB9CisKKworICAgIHByaXZhdGUgdm9pZCBpbml0U3RyZWFtcygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJYm9vbGVhbiBxdW90ZSA9IFByb3BVdGlsLmdldEJvb2xlYW5Qcm9wZXJ0eShzZXNzaW9uLmdldFByb3BlcnRpZXMoKSwKKwkJCQkJIm1haWwuZGVidWcucXVvdGUiLCBmYWxzZSk7CisKKwl0cmFjZUlucHV0ID0KKwkgICAgbmV3IFRyYWNlSW5wdXRTdHJlYW0oc2VydmVyU29ja2V0LmdldElucHV0U3RyZWFtKCksIHRyYWNlTG9nZ2VyKTsKKwl0cmFjZUlucHV0LnNldFF1b3RlKHF1b3RlKTsKKworCXRyYWNlT3V0cHV0ID0KKwkgICAgbmV3IFRyYWNlT3V0cHV0U3RyZWFtKHNlcnZlclNvY2tldC5nZXRPdXRwdXRTdHJlYW0oKSwgdHJhY2VMb2dnZXIpOworCXRyYWNlT3V0cHV0LnNldFF1b3RlKHF1b3RlKTsKKworCXNlcnZlck91dHB1dCA9CisJICAgIG5ldyBCdWZmZXJlZE91dHB1dFN0cmVhbSh0cmFjZU91dHB1dCk7CisJc2VydmVySW5wdXQgPQorCSAgICBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbSh0cmFjZUlucHV0KTsKKwlsaW5lSW5wdXRTdHJlYW0gPSBuZXcgTGluZUlucHV0U3RyZWFtKHNlcnZlcklucHV0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJcyBwcm90b2NvbCB0cmFjaW5nIGVuYWJsZWQ/CisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGlzVHJhY2luZygpIHsKKwlyZXR1cm4gdHJhY2VMb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FU1QpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlbXBvcmFyaWx5IHR1cm4gb2ZmIHByb3RvY29sIHRyYWNpbmcsIGUuZy4sIHRvIHByZXZlbnQKKyAgICAgKiB0cmFjaW5nIHRoZSBhdXRoZW50aWNhdGlvbiBzZXF1ZW5jZSwgaW5jbHVkaW5nIHRoZSBwYXNzd29yZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgc3VzcGVuZFRyYWNpbmcoKSB7CisJaWYgKHRyYWNlTG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuRklORVNUKSkgeworCSAgICB0cmFjZUlucHV0LnNldFRyYWNlKGZhbHNlKTsKKwkgICAgdHJhY2VPdXRwdXQuc2V0VHJhY2UoZmFsc2UpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXN1bWUgcHJvdG9jb2wgdHJhY2luZywgaWYgaXQgd2FzIGVuYWJsZWQgdG8gYmVnaW4gd2l0aC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmVzdW1lVHJhY2luZygpIHsKKwlpZiAodHJhY2VMb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FU1QpKSB7CisJICAgIHRyYWNlSW5wdXQuc2V0VHJhY2UodHJ1ZSk7CisJICAgIHRyYWNlT3V0cHV0LnNldFRyYWNlKHRydWUpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZW5kIHRoZSBjb21tYW5kIHRvIHRoZSBzZXJ2ZXIuICBJZiB0aGUgZXhwZWN0ZWQgcmVzcG9uc2UgY29kZQorICAgICAqIGlzIG5vdCByZWNlaXZlZCwgdGhyb3cgYSBNZXNzYWdpbmdFeGNlcHRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0JY21kCXRoZSBjb21tYW5kIHRvIHNlbmQKKyAgICAgKiBAcGFyYW0JZXhwZWN0CXRoZSBleHBlY3RlZCByZXNwb25zZSBjb2RlICgtMSBtZWFucyBkb24ndCBjYXJlKQorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjQuMQorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBpc3N1ZUNvbW1hbmQoU3RyaW5nIGNtZCwgaW50IGV4cGVjdCkKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlzZW5kQ29tbWFuZChjbWQpOworCisJLy8gaWYgc2VydmVyIHJlc3BvbmRlZCB3aXRoIGFuIHVuZXhwZWN0ZWQgcmV0dXJuIGNvZGUsCisJLy8gdGhyb3cgdGhlIGV4Y2VwdGlvbiwgbm90aWZ5aW5nIHRoZSBjbGllbnQgb2YgdGhlIHJlc3BvbnNlCisJaW50IHJlc3AgPSByZWFkU2VydmVyUmVzcG9uc2UoKTsKKwlpZiAoZXhwZWN0ICE9IC0xICYmIHJlc3AgIT0gZXhwZWN0KQorCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKGxhc3RTZXJ2ZXJSZXNwb25zZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSXNzdWUgYSBjb21tYW5kIHRoYXQncyBwYXJ0IG9mIHNlbmRpbmcgYSBtZXNzYWdlLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBpc3N1ZVNlbmRDb21tYW5kKFN0cmluZyBjbWQsIGludCBleHBlY3QpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJc2VuZENvbW1hbmQoY21kKTsKKworCS8vIGlmIHNlcnZlciByZXNwb25kZWQgd2l0aCBhbiB1bmV4cGVjdGVkIHJldHVybiBjb2RlLAorCS8vIHRocm93IHRoZSBleGNlcHRpb24sIG5vdGlmeWluZyB0aGUgY2xpZW50IG9mIHRoZSByZXNwb25zZQorCWludCByZXQ7CisJaWYgKChyZXQgPSByZWFkU2VydmVyUmVzcG9uc2UoKSkgIT0gZXhwZWN0KSB7CisJICAgIC8vIGFzc3VtZSBtZXNzYWdlIHdhcyBub3Qgc2VudCB0byBhbnlvbmUsCisJICAgIC8vIGNvbWJpbmUgdmFsaWQgc2VudCAmIHVuc2VudCBhZGRyZXNzZXMKKwkgICAgaW50IHZzbCA9IHZhbGlkU2VudEFkZHIgPT0gbnVsbCA/IDAgOiB2YWxpZFNlbnRBZGRyLmxlbmd0aDsKKwkgICAgaW50IHZ1bCA9IHZhbGlkVW5zZW50QWRkciA9PSBudWxsID8gMCA6IHZhbGlkVW5zZW50QWRkci5sZW5ndGg7CisJICAgIEFkZHJlc3NbXSB2YWxpZCA9IG5ldyBBZGRyZXNzW3ZzbCArIHZ1bF07CisJICAgIGlmICh2c2wgPiAwKQorCQlTeXN0ZW0uYXJyYXljb3B5KHZhbGlkU2VudEFkZHIsIDAsIHZhbGlkLCAwLCB2c2wpOworCSAgICBpZiAodnVsID4gMCkKKwkJU3lzdGVtLmFycmF5Y29weSh2YWxpZFVuc2VudEFkZHIsIDAsIHZhbGlkLCB2c2wsIHZ1bCk7CisJICAgIHZhbGlkU2VudEFkZHIgPSBudWxsOworCSAgICB2YWxpZFVuc2VudEFkZHIgPSB2YWxpZDsKKwkgICAgaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkUpKQorCQlsb2dnZXIuZmluZSgiZ290IHJlc3BvbnNlIGNvZGUgIiArIHJldCArCisJCSAgICAiLCB3aXRoIHJlc3BvbnNlOiAiICsgbGFzdFNlcnZlclJlc3BvbnNlKTsKKwkgICAgU3RyaW5nIF9sc3IgPSBsYXN0U2VydmVyUmVzcG9uc2U7IC8vIGVsc2UgcnNldCB3aWxsIG51a2UgaXQKKwkgICAgaW50IF9scmMgPSBsYXN0UmV0dXJuQ29kZTsKKwkgICAgaWYgKHNlcnZlclNvY2tldCAhPSBudWxsKQkvLyBoYXNuJ3QgYWxyZWFkeSBiZWVuIGNsb3NlZAorCQlpc3N1ZUNvbW1hbmQoIlJTRVQiLCAtMSk7CisJICAgIGxhc3RTZXJ2ZXJSZXNwb25zZSA9IF9sc3I7CS8vIHJlc3RvcmUsIGZvciBnZXQKKwkgICAgbGFzdFJldHVybkNvZGUgPSBfbHJjOworCSAgICB0aHJvdyBuZXcgU01UUFNlbmRGYWlsZWRFeGNlcHRpb24oY21kLCByZXQsIGxhc3RTZXJ2ZXJSZXNwb25zZSwKKwkJCWV4Y2VwdGlvbiwgdmFsaWRTZW50QWRkciwgdmFsaWRVbnNlbnRBZGRyLCBpbnZhbGlkQWRkcik7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNlbmQgdGhlIGNvbW1hbmQgdG8gdGhlIHNlcnZlciBhbmQgcmV0dXJuIHRoZSByZXNwb25zZSBjb2RlCisgICAgICogZnJvbSB0aGUgc2VydmVyLgorICAgICAqCisgICAgICogQHBhcmFtCWNtZAl0aGUgY29tbWFuZAorICAgICAqIEByZXR1cm4JCXRoZSByZXNwb25zZSBjb2RlCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNC4xCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBpbnQgc2ltcGxlQ29tbWFuZChTdHJpbmcgY21kKQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXNlbmRDb21tYW5kKGNtZCk7CisJcmV0dXJuIHJlYWRTZXJ2ZXJSZXNwb25zZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNlbmQgdGhlIGNvbW1hbmQgdG8gdGhlIHNlcnZlciBhbmQgcmV0dXJuIHRoZSByZXNwb25zZSBjb2RlCisgICAgICogZnJvbSB0aGUgc2VydmVyLgorICAgICAqCisgICAgICogQHBhcmFtCWNtZAl0aGUgY29tbWFuZAorICAgICAqIEByZXR1cm4JCXRoZSByZXNwb25zZSBjb2RlCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNC4xCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBzaW1wbGVDb21tYW5kKGJ5dGVbXSBjbWQpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWFzc2VydCBUaHJlYWQuaG9sZHNMb2NrKHRoaXMpOworCXNlbmRDb21tYW5kKGNtZCk7CisJcmV0dXJuIHJlYWRTZXJ2ZXJSZXNwb25zZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNlbmRzIGNvbW1hbmQgPGNvZGU+Y21kPC9jb2RlPiB0byB0aGUgc2VydmVyIHRlcm1pbmF0aW5nCisgICAgICogaXQgd2l0aCA8Y29kZT5DUkxGPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEBwYXJhbQljbWQJdGhlIGNvbW1hbmQKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS40LjEKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzZW5kQ29tbWFuZChTdHJpbmcgY21kKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlzZW5kQ29tbWFuZCh0b0J5dGVzKGNtZCkpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBzZW5kQ29tbWFuZChieXRlW10gY21kQnl0ZXMpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWFzc2VydCBUaHJlYWQuaG9sZHNMb2NrKHRoaXMpOworCS8vaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkUpKQorCSAgICAvL2xvZ2dlci5maW5lKCJTRU5UOiAiICsgbmV3IFN0cmluZyhjbWRCeXRlcywgMCkpOworCisgICAgICAgIHRyeSB7CisJICAgIHNlcnZlck91dHB1dC53cml0ZShjbWRCeXRlcyk7CisJICAgIHNlcnZlck91dHB1dC53cml0ZShDUkxGKTsKKwkgICAgc2VydmVyT3V0cHV0LmZsdXNoKCk7CisJfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiQ2FuJ3Qgc2VuZCBjb21tYW5kIHRvIFNNVFAgaG9zdCIsIGV4KTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgc2VydmVyIHJlcG9uc2UgcmV0dXJuaW5nIHRoZSA8Y29kZT5yZXR1cm5Db2RlPC9jb2RlPgorICAgICAqIGFzIHRoZSBudW1iZXIuICBSZXR1cm5zIC0xIG9uIGZhaWx1cmUuIFNldHMKKyAgICAgKiA8Y29kZT5sYXN0U2VydmVyUmVzcG9uc2U8L2NvZGU+IGFuZCA8Y29kZT5sYXN0UmV0dXJuQ29kZTwvY29kZT4uCisgICAgICoKKyAgICAgKiBAcmV0dXJuCQlzZXJ2ZXIgcmVzcG9uc2UgY29kZQorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjQuMQorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgcmVhZFNlcnZlclJlc3BvbnNlKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJYXNzZXJ0IFRocmVhZC5ob2xkc0xvY2sodGhpcyk7CisgICAgICAgIFN0cmluZyBzZXJ2ZXJSZXNwb25zZSA9ICIiOworICAgICAgICBpbnQgcmV0dXJuQ29kZSA9IDA7CisJU3RyaW5nQnVpbGRlciBidWYgPSBuZXcgU3RyaW5nQnVpbGRlcigxMDApOworCisJLy8gcmVhZCB0aGUgc2VydmVyIHJlc3BvbnNlIGxpbmUocykgYW5kIGFkZCB0aGVtIHRvIHRoZSBidWZmZXIKKwkvLyB0aGF0IHN0b3JlcyB0aGUgcmVzcG9uc2UKKyAgICAgICAgdHJ5IHsKKwkgICAgU3RyaW5nIGxpbmUgPSBudWxsOworCisJICAgIGRvIHsKKwkJbGluZSA9IGxpbmVJbnB1dFN0cmVhbS5yZWFkTGluZSgpOworCQlpZiAobGluZSA9PSBudWxsKSB7CisJCSAgICBzZXJ2ZXJSZXNwb25zZSA9IGJ1Zi50b1N0cmluZygpOworCQkgICAgaWYgKHNlcnZlclJlc3BvbnNlLmxlbmd0aCgpID09IDApCisJCQlzZXJ2ZXJSZXNwb25zZSA9ICJbRU9GXSI7CisJCSAgICBsYXN0U2VydmVyUmVzcG9uc2UgPSBzZXJ2ZXJSZXNwb25zZTsKKwkJICAgIGxhc3RSZXR1cm5Db2RlID0gLTE7CisJCSAgICBsb2dnZXIubG9nKExldmVsLkZJTkUsICJFT0Y6IHswfSIsIHNlcnZlclJlc3BvbnNlKTsKKwkJICAgIHJldHVybiAtMTsKKwkJfQorCQlidWYuYXBwZW5kKGxpbmUpOworCQlidWYuYXBwZW5kKCJcbiIpOworCSAgICB9IHdoaWxlIChpc05vdExhc3RMaW5lKGxpbmUpKTsKKworICAgICAgICAgICAgc2VydmVyUmVzcG9uc2UgPSBidWYudG9TdHJpbmcoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9leCkgeworCSAgICBsb2dnZXIubG9nKExldmVsLkZJTkUsICJleGNlcHRpb24gcmVhZGluZyByZXNwb25zZSIsIGlvZXgpOworICAgICAgICAgICAgLy9pb2V4LnByaW50U3RhY2tUcmFjZShvdXQpOworCSAgICBsYXN0U2VydmVyUmVzcG9uc2UgPSAiIjsKKwkgICAgbGFzdFJldHVybkNvZGUgPSAwOworCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKCJFeGNlcHRpb24gcmVhZGluZyByZXNwb25zZSIsIGlvZXgpOworICAgICAgICAgICAgLy9yZXR1cm5Db2RlID0gLTE7CisgICAgICAgIH0KKworCS8vIHByaW50IGRlYnVnIGluZm8KKyAgICAgICAgLy9pZiAobG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuRklORSkpCisgICAgICAgICAgICAvL2xvZ2dlci5maW5lKCJSQ1ZEOiAiICsgc2VydmVyUmVzcG9uc2UpOworCisJLy8gcGFyc2Ugb3V0IHRoZSByZXR1cm4gY29kZQorICAgICAgICBpZiAoc2VydmVyUmVzcG9uc2UubGVuZ3RoKCkgPj0gMykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICByZXR1cm5Db2RlID0gSW50ZWdlci5wYXJzZUludChzZXJ2ZXJSZXNwb25zZS5zdWJzdHJpbmcoMCwgMykpOworICAgICAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIG5mZSkgeworCQl0cnkgeworCQkgICAgY2xvc2UoKTsKKwkJfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIG1leCkgeworCQkgICAgLy8gdGhyb3duIGJ5IGNsb3NlKCktLWlnbm9yZSwgd2lsbCBjbG9zZSgpIGxhdGVyIGFueXdheQorCQkgICAgbG9nZ2VyLmxvZyhMZXZlbC5GSU5FLCAiY2xvc2UgZmFpbGVkIiwgbWV4KTsKKwkJfQorCQlyZXR1cm5Db2RlID0gLTE7CisgICAgICAgICAgICB9IGNhdGNoIChTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGV4KSB7CisJCXRyeSB7CisJCSAgICBjbG9zZSgpOworCQl9IGNhdGNoIChNZXNzYWdpbmdFeGNlcHRpb24gbWV4KSB7CisJCSAgICAvLyB0aHJvd24gYnkgY2xvc2UoKS0taWdub3JlLCB3aWxsIGNsb3NlKCkgbGF0ZXIgYW55d2F5CisJCSAgICBsb2dnZXIubG9nKExldmVsLkZJTkUsICJjbG9zZSBmYWlsZWQiLCBtZXgpOworCQl9CisgICAgICAgICAgICAgICAgcmV0dXJuQ29kZSA9IC0xOworCSAgICB9CisJfSBlbHNlIHsKKwkgICAgcmV0dXJuQ29kZSA9IC0xOworCX0KKwlpZiAocmV0dXJuQ29kZSA9PSAtMSkKKwkgICAgbG9nZ2VyLmxvZyhMZXZlbC5GSU5FLCAiYmFkIHNlcnZlciByZXNwb25zZTogezB9Iiwgc2VydmVyUmVzcG9uc2UpOworCisgICAgICAgIGxhc3RTZXJ2ZXJSZXNwb25zZSA9IHNlcnZlclJlc3BvbnNlOworCWxhc3RSZXR1cm5Db2RlID0gcmV0dXJuQ29kZTsKKyAgICAgICAgcmV0dXJuIHJldHVybkNvZGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2sgaWYgd2UncmUgaW4gdGhlIGNvbm5lY3RlZCBzdGF0ZS4gIERvbid0IGJvdGhlciBjaGVja2luZworICAgICAqIHdoZXRoZXIgdGhlIHNlcnZlciBpcyBzdGlsbCBhbGl2ZSwgdGhhdCB3aWxsIGJlIGRldGVjdGVkIGxhdGVyLgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24JaWYgbm90IGNvbm5lY3RlZAorICAgICAqCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNC4xCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgY2hlY2tDb25uZWN0ZWQoKSB7CisJaWYgKCFzdXBlci5pc0Nvbm5lY3RlZCgpKQorCSAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJOb3QgY29ubmVjdGVkIik7CisgICAgfQorCisgICAgLy8gdGVzdHMgaWYgdGhlIDxjb2RlPmxpbmU8L2NvZGU+IGlzIGFuIGludGVybWVkaWF0ZSBsaW5lIGFjY29yZGluZyB0byBTTVRQCisgICAgcHJpdmF0ZSBib29sZWFuIGlzTm90TGFzdExpbmUoU3RyaW5nIGxpbmUpIHsKKyAgICAgICAgcmV0dXJuIGxpbmUgIT0gbnVsbCAmJiBsaW5lLmxlbmd0aCgpID49IDQgJiYgbGluZS5jaGFyQXQoMykgPT0gJy0nOworICAgIH0KKworICAgIC8vIHdyYXBzIGFuIGFkZHJlc3MgaW4gIjw+IidzIGlmIG5lY2Vzc2FyeQorICAgIHByaXZhdGUgU3RyaW5nIG5vcm1hbGl6ZUFkZHJlc3MoU3RyaW5nIGFkZHIpIHsKKwlpZiAoKCFhZGRyLnN0YXJ0c1dpdGgoIjwiKSkgJiYgKCFhZGRyLmVuZHNXaXRoKCI+IikpKQorCSAgICByZXR1cm4gIjwiICsgYWRkciArICI+IjsKKwllbHNlCisJICAgIHJldHVybiBhZGRyOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0cnVlIGlmIHRoZSBTTVRQIHNlcnZlciBzdXBwb3J0cyB0aGUgc3BlY2lmaWVkIHNlcnZpY2UKKyAgICAgKiBleHRlbnNpb24uICBFeHRlbnNpb25zIGFyZSByZXBvcnRlZCBhcyByZXN1bHRzIG9mIHRoZSBFSExPCisgICAgICogY29tbWFuZCB3aGVuIGNvbm5lY3RpbmcgdG8gdGhlIHNlcnZlci4gU2VlCisgICAgICogPEEgSFJFRj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMTg2OS50eHQiPlJGQyAxODY5PC9BPgorICAgICAqIGFuZCBvdGhlciBSRkNzIHRoYXQgZGVmaW5lIHNwZWNpZmljIGV4dGVuc2lvbnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0JZXh0CXRoZSBzZXJ2aWNlIGV4dGVuc2lvbiBuYW1lCisgICAgICogQHJldHVybgkJdHJ1ZSBpZiB0aGUgZXh0ZW5zaW9uIGlzIHN1cHBvcnRlZAorICAgICAqCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuMy4yCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gc3VwcG9ydHNFeHRlbnNpb24oU3RyaW5nIGV4dCkgeworCXJldHVybiBleHRNYXAgIT0gbnVsbCAmJgorCQkJZXh0TWFwLmdldChleHQudG9VcHBlckNhc2UoTG9jYWxlLkVOR0xJU0gpKSAhPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgcGFyYW1ldGVyIHRoZSBzZXJ2ZXIgcHJvdmlkZWQgZm9yIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBzZXJ2aWNlIGV4dGVuc2lvbiwgb3IgbnVsbCBpZiB0aGUgZXh0ZW5zaW9uIGlzbid0IHN1cHBvcnRlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbQlleHQJdGhlIHNlcnZpY2UgZXh0ZW5zaW9uIG5hbWUKKyAgICAgKiBAcmV0dXJuCQl0aGUgZXh0ZW5zaW9uIHBhcmFtZXRlcgorICAgICAqCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuMy4yCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRFeHRlbnNpb25QYXJhbWV0ZXIoU3RyaW5nIGV4dCkgeworCXJldHVybiBleHRNYXAgPT0gbnVsbCA/IG51bGwgOgorCQkJZXh0TWFwLmdldChleHQudG9VcHBlckNhc2UoTG9jYWxlLkVOR0xJU0gpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEb2VzIHRoZSBzZXJ2ZXIgd2UncmUgY29ubmVjdGVkIHRvIHN1cHBvcnQgdGhlIHNwZWNpZmllZAorICAgICAqIGF1dGhlbnRpY2F0aW9uIG1lY2hhbmlzbT8gIFVzZXMgdGhlIGV4dGVuc2lvbiBpbmZvcm1hdGlvbgorICAgICAqIHJldHVybmVkIGJ5IHRoZSBzZXJ2ZXIgZnJvbSB0aGUgRUhMTyBjb21tYW5kLgorICAgICAqCisgICAgICogQHBhcmFtCWF1dGgJdGhlIGF1dGhlbnRpY2F0aW9uIG1lY2hhbmlzbQorICAgICAqIEByZXR1cm4JCXRydWUgaWYgdGhlIGF1dGhlbnRpY2F0aW9uIG1lY2hhbmlzbSBpcyBzdXBwb3J0ZWQKKyAgICAgKgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjQuMQorICAgICAqLworICAgIHByb3RlY3RlZCBib29sZWFuIHN1cHBvcnRzQXV0aGVudGljYXRpb24oU3RyaW5nIGF1dGgpIHsKKwlhc3NlcnQgVGhyZWFkLmhvbGRzTG9jayh0aGlzKTsKKwlpZiAoZXh0TWFwID09IG51bGwpCisJICAgIHJldHVybiBmYWxzZTsKKwlTdHJpbmcgYSA9IGV4dE1hcC5nZXQoIkFVVEgiKTsKKwlpZiAoYSA9PSBudWxsKQorCSAgICByZXR1cm4gZmFsc2U7CisJU3RyaW5nVG9rZW5pemVyIHN0ID0gbmV3IFN0cmluZ1Rva2VuaXplcihhKTsKKwl3aGlsZSAoc3QuaGFzTW9yZVRva2VucygpKSB7CisJICAgIFN0cmluZyB0b2sgPSBzdC5uZXh0VG9rZW4oKTsKKwkgICAgaWYgKHRvay5lcXVhbHNJZ25vcmVDYXNlKGF1dGgpKQorCQlyZXR1cm4gdHJ1ZTsKKwl9CisJLy8gaGFjayBmb3IgYnVnZ3kgc2VydmVycyB0aGF0IGFkdmVydGlzZSBjYXBhYmlsaXR5IGluY29ycmVjdGx5CisJaWYgKGF1dGguZXF1YWxzSWdub3JlQ2FzZSgiTE9HSU4iKSAmJiBzdXBwb3J0c0V4dGVuc2lvbigiQVVUSD1MT0dJTiIpKSB7CisJICAgIGxvZ2dlci5maW5lKCJ1c2UgQVVUSD1MT0dJTiBoYWNrIik7CisJICAgIHJldHVybiB0cnVlOworCX0KKwlyZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgY2hhcltdIGhleGNoYXIgPSB7CisJJzAnLCAnMScsICcyJywgJzMnLCAnNCcsICc1JywgJzYnLCAnNycsCisJJzgnLCAnOScsICdBJywgJ0InLCAnQycsICdEJywgJ0UnLCAnRicKKyAgICB9OworCisgICAgLyoqCisgICAgICogQ29udmVydCBhIHN0cmluZyB0byBSRkMgMTg5MSB4dGV4dCBmb3JtYXQuCisgICAgICoKKyAgICAgKiA8cHJlPgorICAgICAqICAgICB4dGV4dCA9ICooIHhjaGFyIC8gaGV4Y2hhciApCisgICAgICoKKyAgICAgKiAgICAgeGNoYXIgPSBhbnkgQVNDSUkgQ0hBUiBiZXR3ZWVuICIhIiAoMzMpIGFuZCAifiIgKDEyNikgaW5jbHVzaXZlLAorICAgICAqICAgICAgICAgIGV4Y2VwdCBmb3IgIisiIGFuZCAiPSIuCisgICAgICoKKyAgICAgKiA7ICJoZXhjaGFyInMgYXJlIGludGVuZGVkIHRvIGVuY29kZSBvY3RldHMgdGhhdCBjYW5ub3QgYXBwZWFyCisgICAgICogOyBhcyBBU0NJSSBjaGFyYWN0ZXJzIHdpdGhpbiBhbiBlc210cC12YWx1ZS4KKyAgICAgKgorICAgICAqICAgICBoZXhjaGFyID0gQVNDSUkgIisiIGltbWVkaWF0ZWx5IGZvbGxvd2VkIGJ5IHR3byB1cHBlciBjYXNlCisgICAgICogICAgICAgICAgaGV4YWRlY2ltYWwgZGlnaXRzCisgICAgICogPC9wcmU+CisgICAgICoKKyAgICAgKiBAcGFyYW0Jcwl0aGUgc3RyaW5nIHRvIGNvbnZlcnQKKyAgICAgKiBAcmV0dXJuCXRoZSB4dGV4dCBmb3JtYXQgc3RyaW5nCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNC4xCisgICAgICovCisgICAgLy8gWFhYIC0ga2VlcGluZyB0aGlzIGFyb3VuZCBvbmx5IGZvciBjb21wYXRpYmlsaXR5CisgICAgcHJvdGVjdGVkIHN0YXRpYyBTdHJpbmcgeHRleHQoU3RyaW5nIHMpIHsKKwlyZXR1cm4geHRleHQocywgZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIExpa2UgeHRleHQocyksIGJ1dCBhbGxvdyBVVEYtOCBzdHJpbmdzLgorICAgICAqCisgICAgICogQHBhcmFtCXMJdGhlIHN0cmluZyB0byBjb252ZXJ0CisgICAgICogQHBhcmFtCXV0ZjgJY29udmVydCBzdHJpbmcgdG8gVVRGLTggZmlyc3Q/CisgICAgICogQHJldHVybgl0aGUgeHRleHQgZm9ybWF0IHN0cmluZworICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjYuMAorICAgICAqLworICAgIHByb3RlY3RlZCBzdGF0aWMgU3RyaW5nIHh0ZXh0KFN0cmluZyBzLCBib29sZWFuIHV0ZjgpIHsKKwlTdHJpbmdCdWlsZGVyIHNiID0gbnVsbDsKKwlieXRlW10gYnl0ZXM7CisJaWYgKHV0ZjgpCisJICAgIGJ5dGVzID0gcy5nZXRCeXRlcyhTdGFuZGFyZENoYXJzZXRzLlVURl84KTsKKwllbHNlCisJICAgIGJ5dGVzID0gQVNDSUlVdGlsaXR5LmdldEJ5dGVzKHMpOworCWZvciAoaW50IGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyBpKyspIHsKKwkgICAgY2hhciBjID0gKGNoYXIpKCgoaW50KWJ5dGVzW2ldKSYweGZmKTsKKwkgICAgaWYgKCF1dGY4ICYmIGMgPj0gMTI4KQkvLyBub3QgQVNDSUkKKwkJdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKwkJCSAgICAiTm9uLUFTQ0lJIGNoYXJhY3RlciBpbiBTTVRQIHN1Ym1pdHRlcjogIiArIHMpOworCSAgICBpZiAoYyA8ICchJyB8fCBjID4gJ34nIHx8IGMgPT0gJysnIHx8IGMgPT0gJz0nKSB7CisJCS8vIG5vdCBwcmludGFibGUgQVNDSUkKKwkJaWYgKHNiID09IG51bGwpIHsKKwkJICAgIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIocy5sZW5ndGgoKSArIDQpOworCQkgICAgc2IuYXBwZW5kKHMuc3Vic3RyaW5nKDAsIGkpKTsKKwkJfQorCQlzYi5hcHBlbmQoJysnKTsKKwkJc2IuYXBwZW5kKGhleGNoYXJbKCgoaW50KWMpJiAweGYwKSA+PiA0XSk7CisJCXNiLmFwcGVuZChoZXhjaGFyWygoaW50KWMpJiAweDBmXSk7CisJICAgIH0gZWxzZSB7CisJCWlmIChzYiAhPSBudWxsKQorCQkgICAgc2IuYXBwZW5kKGMpOworCSAgICB9CisJfQorCXJldHVybiBzYiAhPSBudWxsID8gc2IudG9TdHJpbmcoKSA6IHM7CisgICAgfQorCisgICAgcHJpdmF0ZSBTdHJpbmcgdHJhY2VVc2VyKFN0cmluZyB1c2VyKSB7CisJcmV0dXJuIGRlYnVndXNlcm5hbWUgPyB1c2VyIDogIjx1c2VyIG5hbWUgc3VwcHJlc3NlZD4iOworICAgIH0KKworICAgIHByaXZhdGUgU3RyaW5nIHRyYWNlUGFzc3dvcmQoU3RyaW5nIHBhc3N3b3JkKSB7CisJcmV0dXJuIGRlYnVncGFzc3dvcmQgPyBwYXNzd29yZCA6CisJCQkJKHBhc3N3b3JkID09IG51bGwgPyAiPG51bGw+IiA6ICI8bm9uLW51bGw+Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydCB0aGUgU3RyaW5nIHRvIGVpdGhlciBBU0NJSSBvciBVVEYtOCBieXRlcworICAgICAqIGRlcGVuZGluZyBvbiBhbGxvd3V0ZjguCisgICAgICovCisgICAgcHJpdmF0ZSBieXRlW10gdG9CeXRlcyhTdHJpbmcgcykgeworCWlmIChhbGxvd3V0ZjgpCisJICAgIHJldHVybiBzLmdldEJ5dGVzKFN0YW5kYXJkQ2hhcnNldHMuVVRGXzgpOworCWVsc2UKKwkgICAgLy8gZG9uJ3QgdXNlIFN0YW5kYXJkQ2hhcnNldHMuVVNfQVNDSUkgYmVjYXVzZSBpdCByZWplY3RzIG5vbi1BU0NJSQorCSAgICByZXR1cm4gQVNDSUlVdGlsaXR5LmdldEJ5dGVzKHMpOworICAgIH0KKworICAgIC8qCisgICAgICogUHJvYmUgcG9pbnRzIGZvciBHbGFzc0Zpc2ggbW9uaXRvcmluZy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgc2VuZE1lc3NhZ2VTdGFydChTdHJpbmcgc3ViamVjdCkgeyB9CisgICAgcHJpdmF0ZSB2b2lkIHNlbmRNZXNzYWdlRW5kKCkgeyB9CisKKworICAgIC8qKgorICAgICAqIEFuIFNNVFBPdXRwdXRTdHJlYW0gdGhhdCB3cmFwcyBhIENodW5rZWRPdXRwdXRTdHJlYW0uCisgICAgICovCisgICAgcHJpdmF0ZSBjbGFzcyBCREFUT3V0cHV0U3RyZWFtIGV4dGVuZHMgU01UUE91dHB1dFN0cmVhbSB7CisKKwkvKioKKwkgKiBDcmVhdGUgYSBCREFUT3V0cHV0U3RyZWFtIHRoYXQgd3JhcHMgYSBDaHVua2VkT3V0cHV0U3RyZWFtCisJICogb2YgdGhlIGdpdmVuIHNpemUgYW5kIGJ1aWx0IG9uIHRvcCBvZiB0aGUgc3BlY2lmaWVkCisJICogdW5kZXJseWluZyBvdXRwdXQgc3RyZWFtLgorCSAqCisJICogQHBhcmFtCW91dAl0aGUgdW5kZXJseWluZyBvdXRwdXQgc3RyZWFtCisJICogQHBhcmFtCXNpemUJdGhlIGNodW5rIHNpemUKKwkgKi8KKwlwdWJsaWMgQkRBVE91dHB1dFN0cmVhbShPdXRwdXRTdHJlYW0gb3V0LCBpbnQgc2l6ZSkgeworCSAgICBzdXBlcihuZXcgQ2h1bmtlZE91dHB1dFN0cmVhbShvdXQsIHNpemUpKTsKKwl9CisKKwkvKioKKwkgKiBDbG9zZSB0aGlzIG91dHB1dCBzdHJlYW0uCisJICoKKwkgKiBAZXhjZXB0aW9uCUlPRXhjZXB0aW9uCWZvciBJL08gZXJyb3JzCisJICovCisJQE92ZXJyaWRlCisJcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCSAgICBvdXQuY2xvc2UoKTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogQW4gT3V0cHV0U3RyZWFtIHRoYXQgYnVmZmVycyBkYXRhIGluIGNodW5rcyBhbmQgdXNlcyB0aGUKKyAgICAgKiBSRkMgMzAzMCBCREFUIFNNVFAgY29tbWFuZCB0byBzZW5kIGVhY2ggY2h1bmsuCisgICAgICovCisgICAgcHJpdmF0ZSBjbGFzcyBDaHVua2VkT3V0cHV0U3RyZWFtIGV4dGVuZHMgT3V0cHV0U3RyZWFtIHsKKwlwcml2YXRlIGZpbmFsIE91dHB1dFN0cmVhbSBvdXQ7CisJcHJpdmF0ZSBmaW5hbCBieXRlW10gYnVmOworCXByaXZhdGUgaW50IGNvdW50ID0gMDsKKworCS8qKgorCSAqIENyZWF0ZSBhIENodW5rZWRPdXRwdXRTdHJlYW0gYnVpbHQgb24gdG9wIG9mIHRoZSBzcGVjaWZpZWQKKwkgKiB1bmRlcmx5aW5nIG91dHB1dCBzdHJlYW0uCisJICoKKwkgKiBAcGFyYW0Jb3V0CXRoZSB1bmRlcmx5aW5nIG91dHB1dCBzdHJlYW0KKwkgKiBAcGFyYW0Jc2l6ZQl0aGUgY2h1bmsgc2l6ZQorCSAqLworCXB1YmxpYyBDaHVua2VkT3V0cHV0U3RyZWFtKE91dHB1dFN0cmVhbSBvdXQsIGludCBzaXplKSB7CisJICAgIHRoaXMub3V0ID0gb3V0OworCSAgICBidWYgPSBuZXcgYnl0ZVtzaXplXTsKKwl9CisKKwkvKioKKwkgKiBXcml0ZXMgdGhlIHNwZWNpZmllZCA8Y29kZT5ieXRlPC9jb2RlPiB0byB0aGlzIG91dHB1dCBzdHJlYW0uCisJICoKKwkgKiBAcGFyYW0JYgl0aGUgYnl0ZSB0byB3cml0ZQorCSAqIEBleGNlcHRpb24JSU9FeGNlcHRpb24JZm9yIEkvTyBlcnJvcnMKKwkgKi8KKwlAT3ZlcnJpZGUKKwlwdWJsaWMgdm9pZCB3cml0ZShpbnQgYikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkgICAgYnVmW2NvdW50KytdID0gKGJ5dGUpYjsKKwkgICAgaWYgKGNvdW50ID49IGJ1Zi5sZW5ndGgpCisJCWZsdXNoKCk7CisJfQorCQkKKwkvKioKKwkgKiBXcml0ZXMgbGVuIGJ5dGVzIHRvIHRoaXMgb3V0cHV0IHN0cmVhbSBzdGFydGluZyBhdCBvZmYuCisJICoKKwkgKiBAcGFyYW0JYglieXRlcyB0byB3cml0ZQorCSAqIEBwYXJhbQlvZmYJb2Zmc2V0IGluIGFycmF5CisJICogQHBhcmFtCWxlbgludW1iZXIgb2YgYnl0ZXMgdG8gd3JpdGUKKwkgKiBAZXhjZXB0aW9uCUlPRXhjZXB0aW9uCWZvciBJL08gZXJyb3JzCisJICovCisJQE92ZXJyaWRlCisJcHVibGljIHZvaWQgd3JpdGUoYnl0ZSBiW10sIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJICAgIHdoaWxlIChsZW4gPiAwKSB7CisJCWludCBzaXplID0gTWF0aC5taW4oYnVmLmxlbmd0aCAtIGNvdW50LCBsZW4pOworCQlpZiAoc2l6ZSA9PSBidWYubGVuZ3RoKSB7CisJCSAgICAvLyBhdm9pZCB0aGUgY29weQorCQkgICAgYmRhdChiLCBvZmYsIHNpemUsIGZhbHNlKTsKKwkJfSBlbHNlIHsKKwkJICAgIFN5c3RlbS5hcnJheWNvcHkoYiwgb2ZmLCBidWYsIGNvdW50LCBzaXplKTsKKwkJICAgIGNvdW50ICs9IHNpemU7CisJCX0KKwkJb2ZmICs9IHNpemU7CisJCWxlbiAtPSBzaXplOworCQlpZiAoY291bnQgPj0gYnVmLmxlbmd0aCkKKwkJICAgIGZsdXNoKCk7CisJICAgIH0KKwl9CisKKwkvKioKKwkgKiBGbHVzaCB0aGlzIG91dHB1dCBzdHJlYW0uCisJICoKKwkgKiBAZXhjZXB0aW9uCUlPRXhjZXB0aW9uCWZvciBJL08gZXJyb3JzCisJICovCisJQE92ZXJyaWRlCisJcHVibGljIHZvaWQgZmx1c2goKSB0aHJvd3MgSU9FeGNlcHRpb24geworCSAgICBiZGF0KGJ1ZiwgMCwgY291bnQsIGZhbHNlKTsKKwkgICAgY291bnQgPSAwOworCX0KKworCS8qKgorCSAqIENsb3NlIHRoaXMgb3V0cHV0IHN0cmVhbS4KKwkgKgorCSAqIEBleGNlcHRpb24JSU9FeGNlcHRpb24JZm9yIEkvTyBlcnJvcnMKKwkgKi8KKwlAT3ZlcnJpZGUKKwlwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJICAgIGJkYXQoYnVmLCAwLCBjb3VudCwgdHJ1ZSk7CisJICAgIGNvdW50ID0gMDsKKwl9CisKKwkvKioKKwkgKiBTZW5kIHRoZSBzcGVjaWZpZWQgYnl0ZXMgdXNpbmcgdGhlIEJEQVQgY29tbWFuZC4KKwkgKi8KKwlwcml2YXRlIHZvaWQgYmRhdChieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbiwgYm9vbGVhbiBsYXN0KQorCQkJCXRocm93cyBJT0V4Y2VwdGlvbiB7CisJICAgIGlmIChsZW4gPiAwIHx8IGxhc3QpIHsKKwkJdHJ5IHsKKwkJICAgIGlmIChsYXN0KQorCQkJc2VuZENvbW1hbmQoIkJEQVQgIiArIGxlbiArICIgTEFTVCIpOworCQkgICAgZWxzZQorCQkJc2VuZENvbW1hbmQoIkJEQVQgIiArIGxlbik7CisJCSAgICBvdXQud3JpdGUoYiwgb2ZmLCBsZW4pOworCQkgICAgb3V0LmZsdXNoKCk7CisJCSAgICBpbnQgcmV0ID0gcmVhZFNlcnZlclJlc3BvbnNlKCk7CisJCSAgICBpZiAocmV0ICE9IDI1MCkKKwkJCXRocm93IG5ldyBJT0V4Y2VwdGlvbihsYXN0U2VydmVyUmVzcG9uc2UpOworCQl9IGNhdGNoIChNZXNzYWdpbmdFeGNlcHRpb24gbWV4KSB7CisJCSAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkJEQVQgd3JpdGUgZXhjZXB0aW9uIiwgbWV4KTsKKwkJfQorCSAgICB9CisJfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvc210cC9TYXNsQXV0aGVudGljYXRvci5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9zbXRwL1Nhc2xBdXRoZW50aWNhdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmMyYTY0NQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvc210cC9TYXNsQXV0aGVudGljYXRvci5qYXZhCkBAIC0wLDAgKzEsMjkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLnNtdHA7CisKK2ltcG9ydCBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworLyoqCisgKiBJbnRlcmZhY2UgdG8gbWFrZSBpdCBlYXNpZXIgdG8gY2FsbCBTTVRQU2FzbEF1dGhlbnRpY2F0b3IuCisgKi8KKworcHVibGljIGludGVyZmFjZSBTYXNsQXV0aGVudGljYXRvciB7CisgICAgcHVibGljIGJvb2xlYW4gYXV0aGVudGljYXRlKFN0cmluZ1tdIG1lY2hzLCBTdHJpbmcgcmVhbG0sIFN0cmluZyBhdXRoemlkLAorCQkJCVN0cmluZyB1LCBTdHJpbmcgcCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9zbXRwL3BhY2thZ2UuaHRtbCBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvc210cC9wYWNrYWdlLmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTNmNjA4ZQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvc210cC9wYWNrYWdlLmh0bWwKQEAgLTAsMCArMSw4MjIgQEAKKzwhRE9DVFlQRSBodG1sIFBVQkxJQyAiLS8vVzNDLy9EVEQgSFRNTCA0LjAxIFRyYW5zaXRpb25hbC8vRU4iPgorPEhUTUw+Cis8SEVBRD4KKzxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PXV0Zi04Ij4KKzwhLS0KKworICAgIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorCisgICAgVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgICAgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisKKyAgICBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgICAgTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICAgIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICAgIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorCisgICAgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisKKy0tPgorCis8VElUTEU+Y29tLnN1bi5tYWlsLnNtdHAgcGFja2FnZTwvVElUTEU+Cis8L0hFQUQ+Cis8Qk9EWSBCR0NPTE9SPSJ3aGl0ZSI+CisKK0FuIFNNVFAgcHJvdG9jb2wgcHJvdmlkZXIgZm9yIHRoZSBKYXZhTWFpbCBBUEkKK3RoYXQgcHJvdmlkZXMgYWNjZXNzIHRvIGFuIFNNVFAgc2VydmVyLgorUmVmZXIgdG8gPEEgSFJFRj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjODIxLnR4dCIgVEFSR0VUPSJfdG9wIj5SRkMgODIxPC9BPgorZm9yIG1vcmUgaW5mb3JtYXRpb24uCis8UD4KK1doZW4gc2VuZGluZyBhIG1lc3NhZ2UsIGRldGFpbGVkIGluZm9ybWF0aW9uIG9uIGVhY2ggYWRkcmVzcyB0aGF0CitmYWlscyBpcyBhdmFpbGFibGUgaW4gYW4KK3tAbGluayBjb20uc3VuLm1haWwuc210cC5TTVRQQWRkcmVzc0ZhaWxlZEV4Y2VwdGlvbiBTTVRQQWRkcmVzc0ZhaWxlZEV4Y2VwdGlvbn0KK2NoYWluZWQgb2ZmIHRoZSB0b3AgbGV2ZWwKK3tAbGluayBqYXZheC5tYWlsLlNlbmRGYWlsZWRFeGNlcHRpb24gU2VuZEZhaWxlZEV4Y2VwdGlvbn0KK3RoYXQgaXMgdGhyb3duLgorSW4gYWRkaXRpb24sIGlmIHRoZSA8Y29kZT5tYWlsLnNtdHAucmVwb3J0c3VjY2VzczwvY29kZT4gcHJvcGVydHkKK2lzIHNldCwgYW4KK3tAbGluayBjb20uc3VuLm1haWwuc210cC5TTVRQQWRkcmVzc1N1Y2NlZWRlZEV4Y2VwdGlvbgorU01UUEFkZHJlc3NTdWNjZWVkZWRFeGNlcHRpb259Cit3aWxsIGJlIGluY2x1ZGVkIGluIHRoZSBsaXN0IGZvciBlYWNoIGFkZHJlc3MgdGhhdCBpcyBzdWNjZXNzZnVsLgorTm90ZSB0aGF0IHRoaXMgd2lsbCBjYXVzZSBhIHRvcCBsZXZlbAore0BsaW5rIGphdmF4Lm1haWwuU2VuZEZhaWxlZEV4Y2VwdGlvbiBTZW5kRmFpbGVkRXhjZXB0aW9ufQordG8gYmUgdGhyb3duIGV2ZW4gdGhvdWdoIHRoZSBzZW5kIHdhcyBzdWNjZXNzZnVsLgorPC9QPgorPFA+CitUaGUgU01UUCBwcm92aWRlciBhbHNvIHN1cHBvcnRzIEVTTVRQCisoPEEgSFJFRj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMTY1MS50eHQiIFRBUkdFVD0iX3RvcCI+UkZDIDE2NTE8L0E+KS4KK0l0IGNhbiBvcHRpb25hbGx5IHVzZSBTTVRQIEF1dGhlbnRpY2F0aW9uIAorKDxBIEhSRUY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzI1NTQudHh0IiBUQVJHRVQ9Il90b3AiPlJGQyAyNTU0PC9BPikKK3VzaW5nIHRoZSBMT0dJTiwgUExBSU4sIERJR0VTVC1NRDUsIGFuZCBOVExNIG1lY2hhbmlzbXMKKyg8QSBIUkVGPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmM0NjE2LnR4dCIgVEFSR0VUPSJfdG9wIj5SRkMgNDYxNjwvQT4KK2FuZCA8QSBIUkVGPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyODMxLnR4dCIgVEFSR0VUPSJfdG9wIj5SRkMgMjgzMTwvQT4pLgorPC9QPgorPFA+CitUbyB1c2UgU01UUCBhdXRoZW50aWNhdGlvbiB5b3UnbGwgbmVlZCB0byBzZXQgdGhlIDxjb2RlPm1haWwuc210cC5hdXRoPC9jb2RlPgorcHJvcGVydHkgKHNlZSBiZWxvdykgb3IgcHJvdmlkZSB0aGUgU01UUCBUcmFuc3BvcnQKK3dpdGggYSB1c2VybmFtZSBhbmQgcGFzc3dvcmQgd2hlbiBjb25uZWN0aW5nIHRvIHRoZSBTTVRQIHNlcnZlci4gIFlvdQorY2FuIGRvIHRoaXMgdXNpbmcgb25lIG9mIHRoZSBmb2xsb3dpbmcgYXBwcm9hY2hlczoKKzwvUD4KKzxVTD4KKzxMST4KKzxQPgorUHJvdmlkZSBhbiBBdXRoZW50aWNhdG9yIG9iamVjdCB3aGVuIGNyZWF0aW5nIHlvdXIgbWFpbCBTZXNzaW9uCithbmQgcHJvdmlkZSB0aGUgdXNlcm5hbWUgYW5kIHBhc3N3b3JkIGluZm9ybWF0aW9uIGR1cmluZyB0aGUKK0F1dGhlbnRpY2F0b3IgY2FsbGJhY2suCis8L1A+Cis8UD4KK05vdGUgdGhhdCB0aGUgPGNvZGU+bWFpbC5zbXRwLnVzZXI8L2NvZGU+IHByb3BlcnR5IGNhbiBiZSBzZXQgdG8gcHJvdmlkZSBhCitkZWZhdWx0IHVzZXJuYW1lIGZvciB0aGUgY2FsbGJhY2ssIGJ1dCB0aGUgcGFzc3dvcmQgd2lsbCBzdGlsbCBuZWVkIHRvIGJlCitzdXBwbGllZCBleHBsaWNpdGx5LgorPC9QPgorPFA+CitUaGlzIGFwcHJvYWNoIGFsbG93cyB5b3UgdG8gdXNlIHRoZSBzdGF0aWMgVHJhbnNwb3J0IDxjb2RlPnNlbmQ8L2NvZGU+IG1ldGhvZAordG8gc2VuZCBtZXNzYWdlcy4KKzwvUD4KKzwvTEk+Cis8TEk+Cis8UD4KK0NhbGwgdGhlIFRyYW5zcG9ydCA8Y29kZT5jb25uZWN0PC9jb2RlPiBtZXRob2QgZXhwbGljaXRseSB3aXRoIHVzZXJuYW1lIGFuZAorcGFzc3dvcmQgYXJndW1lbnRzLgorPC9QPgorPFA+CitUaGlzIGFwcHJvYWNoIHJlcXVpcmVzIHlvdSB0byBleHBsaWNpdGx5IG1hbmFnZSBhIFRyYW5zcG9ydCBvYmplY3QKK2FuZCB1c2UgdGhlIFRyYW5zcG9ydCA8Y29kZT5zZW5kTWVzc2FnZTwvY29kZT4gbWV0aG9kIHRvIHNlbmQgdGhlIG1lc3NhZ2UuCitUaGUgdHJhbnNwb3J0LmphdmEgZGVtbyBwcm9ncmFtIGRlbW9uc3RyYXRlcyBob3cgdG8gbWFuYWdlIGEgVHJhbnNwb3J0CitvYmplY3QuICBUaGUgZm9sbG93aW5nIGlzIHJvdWdobHkgZXF1aXZhbGVudCB0byB0aGUgc3RhdGljCitUcmFuc3BvcnQgPGNvZGU+c2VuZDwvY29kZT4gbWV0aG9kLCBidXQgc3VwcGxpZXMgdGhlIG5lZWRlZCB1c2VybmFtZSBhbmQKK3Bhc3N3b3JkOgorPC9QPgorPEJMT0NLUVVPVEU+PFBSRT4KK1RyYW5zcG9ydCB0ciA9IHNlc3Npb24uZ2V0VHJhbnNwb3J0KCJzbXRwIik7Cit0ci5jb25uZWN0KHNtdHBob3N0LCB1c2VybmFtZSwgcGFzc3dvcmQpOworbXNnLnNhdmVDaGFuZ2VzKCk7CS8vIGRvbid0IGZvcmdldCB0aGlzCit0ci5zZW5kTWVzc2FnZShtc2csIG1zZy5nZXRBbGxSZWNpcGllbnRzKCkpOwordHIuY2xvc2UoKTsKKzwvUFJFPjwvQkxPQ0tRVU9URT4KKzwvTEk+Cis8L1VMPgorPFA+CitXaGVuIHVzaW5nIERJR0VTVC1NRDUgYXV0aGVudGljYXRpb24sCit5b3UnbGwgYWxzbyBuZWVkIHRvIHN1cHBseSBhbiBhcHByb3ByaWF0ZSByZWFsbTsKK3lvdXIgbWFpbCBzZXJ2ZXIgYWRtaW5pc3RyYXRvciBjYW4gc3VwcGx5IHRoaXMgaW5mb3JtYXRpb24uCitZb3UgY2FuIHNldCB0aGlzIHVzaW5nIHRoZSA8Y29kZT5tYWlsLnNtdHAuc2FzbC5yZWFsbTwvY29kZT4gcHJvcGVydHksCitvciB0aGUgPGNvZGU+c2V0U0FTTFJlYWxtPC9jb2RlPiBtZXRob2Qgb24gPGNvZGU+U01UUFRyYW5zcG9ydDwvY29kZT4uCis8L1A+Cis8UD4KK1RoZSBTTVRQIHByb3RvY29sIHByb3ZpZGVyIGNhbiB1c2UgU0FTTAorKDxBIEhSRUY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIyMjIudHh0IiBUQVJHRVQ9Il90b3AiPlJGQyAyMjIyPC9BPikKK2F1dGhlbnRpY2F0aW9uIG1lY2hhbmlzbXMgb24gc3lzdGVtcyB0aGF0IHN1cHBvcnQgdGhlCis8Q09ERT5qYXZheC5zZWN1cml0eS5zYXNsPC9DT0RFPiBBUElzLCBzdWNoIGFzIEoyU0UgNS4wLgorSW4gYWRkaXRpb24gdG8gdGhlIFNBU0wgbWVjaGFuaXNtcyB0aGF0IGFyZSBidWlsdCBpbnRvIAordGhlIFNBU0wgaW1wbGVtZW50YXRpb24sIHVzZXJzIGNhbiBhbHNvIHByb3ZpZGUgYWRkaXRpb25hbAorU0FTTCBtZWNoYW5pc21zIG9mIHRoZWlyIG93biBkZXNpZ24gdG8gc3VwcG9ydCBjdXN0b20gYXV0aGVudGljYXRpb24KK3NjaGVtZXMuICBTZWUgdGhlCis8QSBIUkVGPSJodHRwOi8vamF2YS5zdW4uY29tL2oyc2UvMS41LjAvZG9jcy9ndWlkZS9zZWN1cml0eS9zYXNsL3Nhc2wtcmVmZ3VpZGUuaHRtbCIgVEFSR0VUPSJfdG9wIj4KK0phdmEgU0FTTCBBUEkgUHJvZ3JhbW1pbmcgYW5kIERlcGxveW1lbnQgR3VpZGU8L0E+IGZvciBkZXRhaWxzLgorTm90ZSB0aGF0IHRoZSBjdXJyZW50IGltcGxlbWVudGF0aW9uIGRvZXNuJ3Qgc3VwcG9ydCBTQVNMIG1lY2hhbmlzbXMKK3RoYXQgcHJvdmlkZSB0aGVpciBvd24gaW50ZWdyaXR5IG9yIGNvbmZpZGVudGlhbGl0eSBsYXllci4KKzwvUD4KKzxQPgorU3VwcG9ydCBmb3IgT0F1dGggMi4wIGF1dGhlbnRpY2F0aW9uIHZpYSB0aGUKKzxBIEhSRUY9Imh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2dtYWlsL3hvYXV0aDJfcHJvdG9jb2wiIFRBUkdFVD0iX3RvcCI+CitYT0FVVEgyIGF1dGhlbnRpY2F0aW9uIG1lY2hhbmlzbTwvQT4gaXMgcHJvdmlkZWQgZWl0aGVyIHRocm91Z2ggdGhlIFNBU0wKK3N1cHBvcnQgZGVzY3JpYmVkIGFib3ZlIG9yIGFzIGEgYnVpbHQtaW4gYXV0aGVudGljYXRpb24gbWVjaGFuaXNtIGluIHRoZQorU01UUCBwcm92aWRlci4KK1RoZSBPQXV0aCAyLjAgQWNjZXNzIFRva2VuIHNob3VsZCBiZSBwYXNzZWQgYXMgdGhlIHBhc3N3b3JkIGZvciB0aGlzIG1lY2hhbmlzbS4KK1NlZSA8QSBIUkVGPSJodHRwczovL2phdmEubmV0L3Byb2plY3RzL2phdmFtYWlsL3BhZ2VzL09BdXRoMiIgVEFSR0VUPSJfdG9wIj4KK09BdXRoMiBTdXBwb3J0PC9BPiBmb3IgZGV0YWlscy4KKzwvUD4KKzxQPgorU01UUCBjYW4gYWxzbyBvcHRpb25hbGx5IHJlcXVlc3QgRGVsaXZlcnkgU3RhdHVzIE5vdGlmaWNhdGlvbnMKKyg8QSBIUkVGPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMxODkxLnR4dCIgVEFSR0VUPSJfdG9wIj5SRkMgMTg5MTwvQT4pLgorVGhlIGRlbGl2ZXJ5IHN0YXR1cyB3aWxsIHR5cGljYWxseSBiZSByZXBvcnRlZCB1c2luZworYSAibXVsdGlwYXJ0L3JlcG9ydCIKKyg8QSBIUkVGPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMxODkyLnR4dCIgVEFSR0VUPSJfdG9wIj5SRkMgMTg5MjwvQT4pCittZXNzYWdlIHR5cGUgd2l0aCBhICJtZXNzYWdlL2RlbGl2ZXJ5LXN0YXR1cyIKKyg8QSBIUkVGPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMxODk0LnR4dCIgVEFSR0VUPSJfdG9wIj5SRkMgMTg5NDwvQT4pCitwYXJ0LgorWW91IGNhbiB1c2UgdGhlIGNsYXNzZXMgaW4gdGhlIDxjb2RlPmNvbS5zdW4ubWFpbC5kc248L2NvZGU+IHBhY2thZ2UgdG8KK2hhbmRsZSB0aGVzZSBNSU1FIHR5cGVzLgorTm90ZSB0aGF0IHlvdSdsbCBuZWVkIHRvIGluY2x1ZGUgPGNvZGU+ZHNuLmphcjwvY29kZT4gaW4geW91ciBDTEFTU1BBVEgKK2FzIHRoaXMgc3VwcG9ydCBpcyBub3QgaW5jbHVkZWQgaW4gPGNvZGU+bWFpbC5qYXI8L2NvZGU+LgorPC9QPgorPFA+CitTZWUgYmVsb3cgZm9yIHRoZSBwcm9wZXJ0aWVzIHRvIGVuYWJsZSB0aGVzZSBmZWF0dXJlcy4KKzwvUD4KKzxQPgorTm90ZSBhbHNvIHRoYXQgPHN0cm9uZz5USEVSRSBJUyBOT1QgU1VGRklDSUVOVCBET0NVTUVOVEFUSU9OIEhFUkUgVE8gVVNFIFRIRVNFCitGRUFUVVJFUyEhITwvc3Ryb25nPiAgWW91IHdpbGwgbmVlZCB0byByZWFkIHRoZSBhcHByb3ByaWF0ZSBSRkNzIG1lbnRpb25lZCBhYm92ZQordG8gdW5kZXJzdGFuZCB3aGF0IHRoZXNlIGZlYXR1cmVzIGRvIGFuZCBob3cgdG8gdXNlIHRoZW0uICBEb24ndCBqdXN0CitzdGFydCBzZXR0aW5nIHByb3BlcnRpZXMgYW5kIHRoZW4gY29tcGxhaW4gdG8gdXMgd2hlbiBpdCBkb2Vzbid0IHdvcmsKK2xpa2UgeW91IGV4cGVjdCBpdCB0byB3b3JrLiAgPHN0cm9uZz5SRUFEIFRIRSBSRkNzIEZJUlNUISEhPC9zdHJvbmc+Cis8L1A+Cis8UD4KK1RoZSBTTVRQIHByb3RvY29sIHByb3ZpZGVyIHN1cHBvcnRzIHRoZSBDSFVOS0lORyBleHRlbnNpb24gZGVmaW5lZCBpbgorPEEgSFJFRj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzAzMC50eHQiIFRBUkdFVD0iX3RvcCI+UkZDIDMwMzA8L0E+LgorU2V0IHRoZSA8Y29kZT5tYWlsLnNtdHAuY2h1bmtzaXplPC9jb2RlPiBwcm9wZXJ0eSB0byB0aGUgZGVzaXJlZCBjaHVuaworc2l6ZSBpbiBieXRlcy4KK0lmIHRoZSBzZXJ2ZXIgc3VwcG9ydHMgdGhlIENIVU5LSU5HIGV4dGVuc2lvbiwgdGhlIEJEQVQgY29tbWFuZCB3aWxsIGJlCit1c2VkIHRvIHNlbmQgdGhlIG1lc3NhZ2UgaW4gY2h1bmtzaXplIHBpZWNlcy4gIE5vdGUgdGhhdCBubyBwaXBlbGluaW5nIGlzCitkb25lIHNvIHRoaXMgd2lsbCBiZSBzbG93ZXIgdGhhbiBzZW5kaW5nIHRoZSBtZXNzYWdlIGluIG9uZSBwaWVjZS4KK05vdGUgYWxzbyB0aGF0IHRoZSBCSU5BUllNSU1FIGV4dGVuc2lvbiBkZXNjcmliZWQgaW4gUkZDIDMwMzAgaXMgTk9UIHN1cHBvcnRlZC4KKzwvUD4KKzxBIE5BTUU9InByb3BlcnRpZXMiPjxTVFJPTkc+UHJvcGVydGllczwvU1RST05HPjwvQT4KKzxQPgorVGhlIFNNVFAgcHJvdG9jb2wgcHJvdmlkZXIgc3VwcG9ydHMgdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzLAord2hpY2ggbWF5IGJlIHNldCBpbiB0aGUgSmF2YU1haWwgPGNvZGU+U2Vzc2lvbjwvY29kZT4gb2JqZWN0LgorVGhlIHByb3BlcnRpZXMgYXJlIGFsd2F5cyBzZXQgYXMgc3RyaW5nczsgdGhlIFR5cGUgY29sdW1uIGRlc2NyaWJlcworaG93IHRoZSBzdHJpbmcgaXMgaW50ZXJwcmV0ZWQuICBGb3IgZXhhbXBsZSwgdXNlCis8L1A+Cis8UFJFPgorCXByb3BzLnB1dCgibWFpbC5zbXRwLnBvcnQiLCAiODg4Iik7Cis8L1BSRT4KKzxQPgordG8gc2V0IHRoZSA8Q09ERT5tYWlsLnNtdHAucG9ydDwvQ09ERT4gcHJvcGVydHksIHdoaWNoIGlzIG9mIHR5cGUgaW50LgorPC9QPgorPFA+CitOb3RlIHRoYXQgaWYgeW91J3JlIHVzaW5nIHRoZSAic210cHMiIHByb3RvY29sIHRvIGFjY2VzcyBTTVRQIG92ZXIgU1NMLAorYWxsIHRoZSBwcm9wZXJ0aWVzIHdvdWxkIGJlIG5hbWVkICJtYWlsLnNtdHBzLioiLgorPC9QPgorPFRBQkxFIEJPUkRFUiBTVU1NQVJZPSJTTVRQIHByb3BlcnRpZXMiPgorPFRSPgorPFRIPk5hbWU8L1RIPgorPFRIPlR5cGU8L1RIPgorPFRIPkRlc2NyaXB0aW9uPC9USD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnNtdHAudXNlciI+bWFpbC5zbXRwLnVzZXI8L0E+PC9URD4KKzxURD5TdHJpbmc8L1REPgorPFREPkRlZmF1bHQgdXNlciBuYW1lIGZvciBTTVRQLjwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5zbXRwLmhvc3QiPm1haWwuc210cC5ob3N0PC9BPjwvVEQ+Cis8VEQ+U3RyaW5nPC9URD4KKzxURD5UaGUgU01UUCBzZXJ2ZXIgdG8gY29ubmVjdCB0by48L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuc210cC5wb3J0Ij5tYWlsLnNtdHAucG9ydDwvQT48L1REPgorPFREPmludDwvVEQ+Cis8VEQ+VGhlIFNNVFAgc2VydmVyIHBvcnQgdG8gY29ubmVjdCB0bywgaWYgdGhlIGNvbm5lY3QoKSBtZXRob2QgZG9lc24ndAorZXhwbGljaXRseSBzcGVjaWZ5IG9uZS4gRGVmYXVsdHMgdG8gMjUuPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnNtdHAuY29ubmVjdGlvbnRpbWVvdXQiPm1haWwuc210cC5jb25uZWN0aW9udGltZW91dDwvQT48L1REPgorPFREPmludDwvVEQ+Cis8VEQ+U29ja2V0IGNvbm5lY3Rpb24gdGltZW91dCB2YWx1ZSBpbiBtaWxsaXNlY29uZHMuCitUaGlzIHRpbWVvdXQgaXMgaW1wbGVtZW50ZWQgYnkgamF2YS5uZXQuU29ja2V0LgorRGVmYXVsdCBpcyBpbmZpbml0ZSB0aW1lb3V0LjwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5zbXRwLnRpbWVvdXQiPm1haWwuc210cC50aW1lb3V0PC9BPjwvVEQ+Cis8VEQ+aW50PC9URD4KKzxURD5Tb2NrZXQgcmVhZCB0aW1lb3V0IHZhbHVlIGluIG1pbGxpc2Vjb25kcy4KK1RoaXMgdGltZW91dCBpcyBpbXBsZW1lbnRlZCBieSBqYXZhLm5ldC5Tb2NrZXQuCitEZWZhdWx0IGlzIGluZmluaXRlIHRpbWVvdXQuPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnNtdHAud3JpdGV0aW1lb3V0Ij5tYWlsLnNtdHAud3JpdGV0aW1lb3V0PC9BPjwvVEQ+Cis8VEQ+aW50PC9URD4KKzxURD5Tb2NrZXQgd3JpdGUgdGltZW91dCB2YWx1ZSBpbiBtaWxsaXNlY29uZHMuCitUaGlzIHRpbWVvdXQgaXMgaW1wbGVtZW50ZWQgYnkgdXNpbmcgYQoramF2YS51dGlsLmNvbmN1cnJlbnQuU2NoZWR1bGVkRXhlY3V0b3JTZXJ2aWNlIHBlciBjb25uZWN0aW9uCit0aGF0IHNjaGVkdWxlcyBhIHRocmVhZCB0byBjbG9zZSB0aGUgc29ja2V0IGlmIHRoZSB0aW1lb3V0IGV4cGlyZXMuCitUaHVzLCB0aGUgb3ZlcmhlYWQgb2YgdXNpbmcgdGhpcyB0aW1lb3V0IGlzIG9uZSB0aHJlYWQgcGVyIGNvbm5lY3Rpb24uCitEZWZhdWx0IGlzIGluZmluaXRlIHRpbWVvdXQuPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnNtdHAuZnJvbSI+bWFpbC5zbXRwLmZyb208L0E+PC9URD4KKzxURD5TdHJpbmc8L1REPgorPFREPgorRW1haWwgYWRkcmVzcyB0byB1c2UgZm9yIFNNVFAgTUFJTCBjb21tYW5kLiAgVGhpcyBzZXRzIHRoZSBlbnZlbG9wZQorcmV0dXJuIGFkZHJlc3MuICBEZWZhdWx0cyB0byBtc2cuZ2V0RnJvbSgpIG9yCitJbnRlcm5ldEFkZHJlc3MuZ2V0TG9jYWxBZGRyZXNzKCkuICBOT1RFOiBtYWlsLnNtdHAudXNlciB3YXMgcHJldmlvdXNseQordXNlZCBmb3IgdGhpcy4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5zbXRwLmxvY2FsaG9zdCI+bWFpbC5zbXRwLmxvY2FsaG9zdDwvQT48L1REPgorPFREPlN0cmluZzwvVEQ+Cis8VEQ+CitMb2NhbCBob3N0IG5hbWUgdXNlZCBpbiB0aGUgU01UUCBIRUxPIG9yIEVITE8gY29tbWFuZC4KK0RlZmF1bHRzIHRvIDxjb2RlPkluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLmdldEhvc3ROYW1lKCk8L2NvZGU+LgorU2hvdWxkIG5vdCBub3JtYWxseSBuZWVkIHRvCitiZSBzZXQgaWYgeW91ciBKREsgYW5kIHlvdXIgbmFtZSBzZXJ2aWNlIGFyZSBjb25maWd1cmVkIHByb3Blcmx5LgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnNtdHAubG9jYWxhZGRyZXNzIj5tYWlsLnNtdHAubG9jYWxhZGRyZXNzPC9BPjwvVEQ+Cis8VEQ+U3RyaW5nPC9URD4KKzxURD4KK0xvY2FsIGFkZHJlc3MgKGhvc3QgbmFtZSkgdG8gYmluZCB0byB3aGVuIGNyZWF0aW5nIHRoZSBTTVRQIHNvY2tldC4KK0RlZmF1bHRzIHRvIHRoZSBhZGRyZXNzIHBpY2tlZCBieSB0aGUgU29ja2V0IGNsYXNzLgorU2hvdWxkIG5vdCBub3JtYWxseSBuZWVkIHRvIGJlIHNldCwgYnV0IHVzZWZ1bCB3aXRoIG11bHRpLWhvbWVkIGhvc3RzCit3aGVyZSBpdCdzIGltcG9ydGFudCB0byBwaWNrIGEgcGFydGljdWxhciBsb2NhbCBhZGRyZXNzIHRvIGJpbmQgdG8uCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuc210cC5sb2NhbHBvcnQiPm1haWwuc210cC5sb2NhbHBvcnQ8L0E+PC9URD4KKzxURD5pbnQ8L1REPgorPFREPgorTG9jYWwgcG9ydCBudW1iZXIgdG8gYmluZCB0byB3aGVuIGNyZWF0aW5nIHRoZSBTTVRQIHNvY2tldC4KK0RlZmF1bHRzIHRvIHRoZSBwb3J0IG51bWJlciBwaWNrZWQgYnkgdGhlIFNvY2tldCBjbGFzcy4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5zbXRwLmVobG8iPm1haWwuc210cC5laGxvPC9BPjwvVEQ+Cis8VEQ+Ym9vbGVhbjwvVEQ+Cis8VEQ+CitJZiBmYWxzZSwgZG8gbm90IGF0dGVtcHQgdG8gc2lnbiBvbiB3aXRoIHRoZSBFSExPIGNvbW1hbmQuICBEZWZhdWx0cyB0bwordHJ1ZS4gIE5vcm1hbGx5IGZhaWx1cmUgb2YgdGhlIEVITE8gY29tbWFuZCB3aWxsIGZhbGxiYWNrIHRvIHRoZSBIRUxPCitjb21tYW5kOyB0aGlzIHByb3BlcnR5IGV4aXN0cyBvbmx5IGZvciBzZXJ2ZXJzIHRoYXQgZG9uJ3QgZmFpbCBFSExPCitwcm9wZXJseSBvciBkb24ndCBpbXBsZW1lbnQgRUhMTyBwcm9wZXJseS4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5zbXRwLmF1dGgiPm1haWwuc210cC5hdXRoPC9BPjwvVEQ+Cis8VEQ+Ym9vbGVhbjwvVEQ+Cis8VEQ+SWYgdHJ1ZSwgYXR0ZW1wdCB0byBhdXRoZW50aWNhdGUgdGhlIHVzZXIgdXNpbmcgdGhlIEFVVEggY29tbWFuZC4KK0RlZmF1bHRzIHRvIGZhbHNlLjwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5zbXRwLmF1dGgubWVjaGFuaXNtcyI+bWFpbC5zbXRwLmF1dGgubWVjaGFuaXNtczwvQT48L1REPgorPFREPlN0cmluZzwvVEQ+Cis8VEQ+CitJZiBzZXQsIGxpc3RzIHRoZSBhdXRoZW50aWNhdGlvbiBtZWNoYW5pc21zIHRvIGNvbnNpZGVyLCBhbmQgdGhlIG9yZGVyCitpbiB3aGljaCB0byBjb25zaWRlciB0aGVtLiAgT25seSBtZWNoYW5pc21zIHN1cHBvcnRlZCBieSB0aGUgc2VydmVyIGFuZAorc3VwcG9ydGVkIGJ5IHRoZSBjdXJyZW50IGltcGxlbWVudGF0aW9uIHdpbGwgYmUgdXNlZC4KK1RoZSBkZWZhdWx0IGlzIDxjb2RlPiJMT0dJTiBQTEFJTiBESUdFU1QtTUQ1IE5UTE0iPC9jb2RlPiwgd2hpY2ggaW5jbHVkZXMgYWxsCit0aGUgYXV0aGVudGljYXRpb24gbWVjaGFuaXNtcyBzdXBwb3J0ZWQgYnkgdGhlIGN1cnJlbnQgaW1wbGVtZW50YXRpb24KK2V4Y2VwdCBYT0FVVEgyLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnNtdHAuYXV0aC5sb2dpbi5kaXNhYmxlIj5tYWlsLnNtdHAuYXV0aC5sb2dpbi5kaXNhYmxlPC9BPjwvVEQ+Cis8VEQ+Ym9vbGVhbjwvVEQ+Cis8VEQ+SWYgdHJ1ZSwgcHJldmVudHMgdXNlIG9mIHRoZSA8Y29kZT5BVVRIIExPR0lOPC9jb2RlPiBjb21tYW5kLgorRGVmYXVsdCBpcyBmYWxzZS48L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuc210cC5hdXRoLnBsYWluLmRpc2FibGUiPm1haWwuc210cC5hdXRoLnBsYWluLmRpc2FibGU8L0E+PC9URD4KKzxURD5ib29sZWFuPC9URD4KKzxURD5JZiB0cnVlLCBwcmV2ZW50cyB1c2Ugb2YgdGhlIDxjb2RlPkFVVEggUExBSU48L2NvZGU+IGNvbW1hbmQuCitEZWZhdWx0IGlzIGZhbHNlLjwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5zbXRwLmF1dGguZGlnZXN0LW1kNS5kaXNhYmxlIj5tYWlsLnNtdHAuYXV0aC5kaWdlc3QtbWQ1LmRpc2FibGU8L0E+PC9URD4KKzxURD5ib29sZWFuPC9URD4KKzxURD5JZiB0cnVlLCBwcmV2ZW50cyB1c2Ugb2YgdGhlIDxjb2RlPkFVVEggRElHRVNULU1ENTwvY29kZT4gY29tbWFuZC4KK0RlZmF1bHQgaXMgZmFsc2UuPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnNtdHAuYXV0aC5udGxtLmRpc2FibGUiPm1haWwuc210cC5hdXRoLm50bG0uZGlzYWJsZTwvQT48L1REPgorPFREPmJvb2xlYW48L1REPgorPFREPklmIHRydWUsIHByZXZlbnRzIHVzZSBvZiB0aGUgPGNvZGU+QVVUSCBOVExNPC9jb2RlPiBjb21tYW5kLgorRGVmYXVsdCBpcyBmYWxzZS48L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuc210cC5hdXRoLm50bG0uZG9tYWluIj5tYWlsLnNtdHAuYXV0aC5udGxtLmRvbWFpbjwvQT48L1REPgorPFREPlN0cmluZzwvVEQ+Cis8VEQ+CitUaGUgTlRMTSBhdXRoZW50aWNhdGlvbiBkb21haW4uCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuc210cC5hdXRoLm50bG0uZmxhZ3MiPm1haWwuc210cC5hdXRoLm50bG0uZmxhZ3M8L0E+PC9URD4KKzxURD5pbnQ8L1REPgorPFREPgorTlRMTSBwcm90b2NvbC1zcGVjaWZpYyBmbGFncy4KK1NlZSA8QSBIUkVGPSJodHRwOi8vY3VybC5oYXh4LnNlL3JmYy9udGxtLmh0bWwjdGhlTnRsbUZsYWdzIiBUQVJHRVQ9Il90b3AiPgoraHR0cDovL2N1cmwuaGF4eC5zZS9yZmMvbnRsbS5odG1sI3RoZU50bG1GbGFnczwvQT4gZm9yIGRldGFpbHMuCis8L1REPgorPC9UUj4KKworPCEtLQorPFRSPgorPFREPjxBIE5BTUU9Im1haWwuc210cC5hdXRoLm50bG0udW5pY29kZSI+bWFpbC5zbXRwLmF1dGgubnRsbS51bmljb2RlPC9BPjwvVEQ+Cis8VEQ+Ym9vbGVhbjwvVEQ+Cis8VEQ+CitTZXQgdGhpcyB0byAidHJ1ZSIgaWYgdGhlIHVzZXJuYW1lIG9yIHBhc3N3b3JkIG1heSB1c2UKK1VuaWNvZGUgVVRGLTggZW5jb2RlZCBjaGFyYWN0ZXJzLiAgRGVmYXVsdCBpcyAidHJ1ZSIuCitDdXJyZW50bHkgaGFzIG5vIGVmZmVjdC4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5zbXRwLmF1dGgubnRsbS5sbWNvbXBhdCI+bWFpbC5zbXRwLmF1dGgubnRsbS5sbWNvbXBhdDwvQT48L1REPgorPFREPmludDwvVEQ+Cis8VEQ+CitTZXRzIHRoZSBMTSBjb21wYXRpYmlsaXR5IGxldmVsLCBhcyBkZXNjcmliZWQgaGVyZToKKzxBIEhSRUY9Imh0dHA6Ly9jdXJsLmhheHguc2UvcmZjL250bG0uaHRtbCNudGxtVmVyc2lvbjIiIFRBUkdFVD0iX3RvcCI+CitodHRwOi8vY3VybC5oYXh4LnNlL3JmYy9udGxtLmh0bWwjbnRsbVZlcnNpb24yPC9BPgorRGVmYXVsdHMgdG8gIjMiLiAgQ3VycmVudGx5IG5vdCB1c2VkLgorPC9URD4KKzwvVFI+CistLT4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuc210cC5hdXRoLnhvYXV0aDIuZGlzYWJsZSI+bWFpbC5zbXRwLmF1dGgueG9hdXRoMi5kaXNhYmxlPC9BPjwvVEQ+Cis8VEQ+Ym9vbGVhbjwvVEQ+Cis8VEQ+SWYgdHJ1ZSwgcHJldmVudHMgdXNlIG9mIHRoZSA8Y29kZT5BVVRIRU5USUNBVEUgWE9BVVRIMjwvY29kZT4gY29tbWFuZC4KK0JlY2F1c2UgdGhlIE9BdXRoIDIuMCBwcm90b2NvbCByZXF1aXJlcyBhIHNwZWNpYWwgYWNjZXNzIHRva2VuIGluc3RlYWQgb2YKK2EgcGFzc3dvcmQsIHRoaXMgbWVjaGFuaXNtIGlzIGRpc2FibGVkIGJ5IGRlZmF1bHQuICBFbmFibGUgaXQgYnkgZXhwbGljaXRseQorc2V0dGluZyB0aGlzIHByb3BlcnR5IHRvICJmYWxzZSIgb3IgYnkgc2V0dGluZyB0aGUgIm1haWwuc210cC5hdXRoLm1lY2hhbmlzbXMiCitwcm9wZXJ0eSB0byAiWE9BVVRIMiIuPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnNtdHAuc3VibWl0dGVyIj5tYWlsLnNtdHAuc3VibWl0dGVyPC9BPjwvVEQ+Cis8VEQ+U3RyaW5nPC9URD4KKzxURD5UaGUgc3VibWl0dGVyIHRvIHVzZSBpbiB0aGUgQVVUSCB0YWcgaW4gdGhlIE1BSUwgRlJPTSBjb21tYW5kLgorVHlwaWNhbGx5IHVzZWQgYnkgYSBtYWlsIHJlbGF5IHRvIHBhc3MgYWxvbmcgaW5mb3JtYXRpb24gYWJvdXQgdGhlCitvcmlnaW5hbCBzdWJtaXR0ZXIgb2YgdGhlIG1lc3NhZ2UuCitTZWUgYWxzbyB0aGUge0BsaW5rIGNvbS5zdW4ubWFpbC5zbXRwLlNNVFBNZXNzYWdlI3NldFN1Ym1pdHRlciBzZXRTdWJtaXR0ZXJ9CittZXRob2Qgb2Yge0BsaW5rIGNvbS5zdW4ubWFpbC5zbXRwLlNNVFBNZXNzYWdlIFNNVFBNZXNzYWdlfS4KK01haWwgY2xpZW50cyB0eXBpY2FsbHkgZG8gbm90IHVzZSB0aGlzLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnNtdHAuZHNuLm5vdGlmeSI+bWFpbC5zbXRwLmRzbi5ub3RpZnk8L0E+PC9URD4KKzxURD5TdHJpbmc8L1REPgorPFREPlRoZSBOT1RJRlkgb3B0aW9uIHRvIHRoZSBSQ1BUIGNvbW1hbmQuICBFaXRoZXIgTkVWRVIsIG9yIHNvbWUKK2NvbWJpbmF0aW9uIG9mIFNVQ0NFU1MsIEZBSUxVUkUsIGFuZCBERUxBWSAoc2VwYXJhdGVkIGJ5IGNvbW1hcykuPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnNtdHAuZHNuLnJldCI+bWFpbC5zbXRwLmRzbi5yZXQ8L0E+PC9URD4KKzxURD5TdHJpbmc8L1REPgorPFREPlRoZSBSRVQgb3B0aW9uIHRvIHRoZSBNQUlMIGNvbW1hbmQuICBFaXRoZXIgRlVMTCBvciBIRFJTLjwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5zbXRwLmFsbG93OGJpdG1pbWUiPm1haWwuc210cC5hbGxvdzhiaXRtaW1lPC9BPjwvVEQ+Cis8VEQ+Ym9vbGVhbjwvVEQ+Cis8VEQ+CitJZiBzZXQgdG8gdHJ1ZSwgYW5kIHRoZSBzZXJ2ZXIgc3VwcG9ydHMgdGhlIDhCSVRNSU1FIGV4dGVuc2lvbiwgdGV4dAorcGFydHMgb2YgbWVzc2FnZXMgdGhhdCB1c2UgdGhlICJxdW90ZWQtcHJpbnRhYmxlIiBvciAiYmFzZTY0IiBlbmNvZGluZ3MKK2FyZSBjb252ZXJ0ZWQgdG8gdXNlICI4Yml0IiBlbmNvZGluZyBpZiB0aGV5IGZvbGxvdyB0aGUgUkZDMjA0NSBydWxlcworZm9yIDhiaXQgdGV4dC4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5zbXRwLnNlbmRwYXJ0aWFsIj5tYWlsLnNtdHAuc2VuZHBhcnRpYWw8L0E+PC9URD4KKzxURD5ib29sZWFuPC9URD4KKzxURD4KK0lmIHNldCB0byB0cnVlLCBhbmQgYSBtZXNzYWdlIGhhcyBzb21lIHZhbGlkIGFuZCBzb21lIGludmFsaWQKK2FkZHJlc3Nlcywgc2VuZCB0aGUgbWVzc2FnZSBhbnl3YXksIHJlcG9ydGluZyB0aGUgcGFydGlhbCBmYWlsdXJlIHdpdGgKK2EgU2VuZEZhaWxlZEV4Y2VwdGlvbi4gIElmIHNldCB0byBmYWxzZSAodGhlIGRlZmF1bHQpLCB0aGUgbWVzc2FnZSBpcworbm90IHNlbnQgdG8gYW55IG9mIHRoZSByZWNpcGllbnRzIGlmIHRoZXJlIGlzIGFuIGludmFsaWQgcmVjaXBpZW50CithZGRyZXNzLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnNtdHAuc2FzbC5lbmFibGUiPm1haWwuc210cC5zYXNsLmVuYWJsZTwvQT48L1REPgorPFREPmJvb2xlYW48L1REPgorPFREPgorSWYgc2V0IHRvIHRydWUsIGF0dGVtcHQgdG8gdXNlIHRoZSBqYXZheC5zZWN1cml0eS5zYXNsIHBhY2thZ2UgdG8KK2Nob29zZSBhbiBhdXRoZW50aWNhdGlvbiBtZWNoYW5pc20gZm9yIGxvZ2luLgorRGVmYXVsdHMgdG8gZmFsc2UuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuc210cC5zYXNsLm1lY2hhbmlzbXMiPm1haWwuc210cC5zYXNsLm1lY2hhbmlzbXM8L0E+PC9URD4KKzxURD5TdHJpbmc8L1REPgorPFREPgorQSBzcGFjZSBvciBjb21tYSBzZXBhcmF0ZWQgbGlzdCBvZiBTQVNMIG1lY2hhbmlzbSBuYW1lcyB0byB0cnkKK3RvIHVzZS4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5zbXRwLnNhc2wuYXV0aG9yaXphdGlvbmlkIj5tYWlsLnNtdHAuc2FzbC5hdXRob3JpemF0aW9uaWQ8L0E+PC9URD4KKzxURD5TdHJpbmc8L1REPgorPFREPgorVGhlIGF1dGhvcml6YXRpb24gSUQgdG8gdXNlIGluIHRoZSBTQVNMIGF1dGhlbnRpY2F0aW9uLgorSWYgbm90IHNldCwgdGhlIGF1dGhlbnRpY2F0aW9uIElEICh1c2VyIG5hbWUpIGlzIHVzZWQuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuc210cC5zYXNsLnJlYWxtIj5tYWlsLnNtdHAuc2FzbC5yZWFsbTwvQT48L1REPgorPFREPlN0cmluZzwvVEQ+Cis8VEQ+VGhlIHJlYWxtIHRvIHVzZSB3aXRoIERJR0VTVC1NRDUgYXV0aGVudGljYXRpb24uPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnNtdHAuc2FzbC51c2VjYW5vbmljYWxob3N0bmFtZSI+bWFpbC5zbXRwLnNhc2wudXNlY2Fub25pY2FsaG9zdG5hbWU8L0E+PC9URD4KKzxURD5ib29sZWFuPC9URD4KKzxURD4KK0lmIHNldCB0byB0cnVlLCB0aGUgY2Fub25pY2FsIGhvc3QgbmFtZSByZXR1cm5lZCBieQore0BsaW5rIGphdmEubmV0LkluZXRBZGRyZXNzI2dldENhbm9uaWNhbEhvc3ROYW1lIEluZXRBZGRyZXNzLmdldENhbm9uaWNhbEhvc3ROYW1lfQoraXMgcGFzc2VkIHRvIHRoZSBTQVNMIG1lY2hhbmlzbSwgaW5zdGVhZCBvZiB0aGUgaG9zdCBuYW1lIHVzZWQgdG8gY29ubmVjdC4KK0RlZmF1bHRzIHRvIGZhbHNlLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnNtdHAucXVpdHdhaXQiPm1haWwuc210cC5xdWl0d2FpdDwvQT48L1REPgorPFREPmJvb2xlYW48L1REPgorPFREPgorSWYgc2V0IHRvIGZhbHNlLCB0aGUgUVVJVCBjb21tYW5kIGlzIHNlbnQKK2FuZCB0aGUgY29ubmVjdGlvbiBpcyBpbW1lZGlhdGVseSBjbG9zZWQuCitJZiBzZXQgdG8gdHJ1ZSAodGhlIGRlZmF1bHQpLCBjYXVzZXMgdGhlIHRyYW5zcG9ydCB0byB3YWl0Citmb3IgdGhlIHJlc3BvbnNlIHRvIHRoZSBRVUlUIGNvbW1hbmQuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuc210cC5yZXBvcnRzdWNjZXNzIj5tYWlsLnNtdHAucmVwb3J0c3VjY2VzczwvQT48L1REPgorPFREPmJvb2xlYW48L1REPgorPFREPgorSWYgc2V0IHRvIHRydWUsIGNhdXNlcyB0aGUgdHJhbnNwb3J0IHRvIGluY2x1ZGUgYW4KK3tAbGluayBjb20uc3VuLm1haWwuc210cC5TTVRQQWRkcmVzc1N1Y2NlZWRlZEV4Y2VwdGlvbgorU01UUEFkZHJlc3NTdWNjZWVkZWRFeGNlcHRpb259Citmb3IgZWFjaCBhZGRyZXNzIHRoYXQgaXMgc3VjY2Vzc2Z1bC4KK05vdGUgYWxzbyB0aGF0IHRoaXMgd2lsbCBjYXVzZSBhCit7QGxpbmsgamF2YXgubWFpbC5TZW5kRmFpbGVkRXhjZXB0aW9uIFNlbmRGYWlsZWRFeGNlcHRpb259Cit0byBiZSB0aHJvd24gZnJvbSB0aGUKK3tAbGluayBjb20uc3VuLm1haWwuc210cC5TTVRQVHJhbnNwb3J0I3NlbmRNZXNzYWdlIHNlbmRNZXNzYWdlfQorbWV0aG9kIG9mCit7QGxpbmsgY29tLnN1bi5tYWlsLnNtdHAuU01UUFRyYW5zcG9ydCBTTVRQVHJhbnNwb3J0fQorZXZlbiBpZiBhbGwgYWRkcmVzc2VzIHdlcmUgY29ycmVjdCBhbmQgdGhlIG1lc3NhZ2Ugd2FzIHNlbnQKK3N1Y2Nlc3NmdWxseS4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5zbXRwLnNvY2tldEZhY3RvcnkiPm1haWwuc210cC5zb2NrZXRGYWN0b3J5PC9BPjwvVEQ+Cis8VEQ+U29ja2V0RmFjdG9yeTwvVEQ+Cis8VEQ+CitJZiBzZXQgdG8gYSBjbGFzcyB0aGF0IGltcGxlbWVudHMgdGhlCis8Y29kZT5qYXZheC5uZXQuU29ja2V0RmFjdG9yeTwvY29kZT4gaW50ZXJmYWNlLCB0aGlzIGNsYXNzCit3aWxsIGJlIHVzZWQgdG8gY3JlYXRlIFNNVFAgc29ja2V0cy4gIE5vdGUgdGhhdCB0aGlzIGlzIGFuCitpbnN0YW5jZSBvZiBhIGNsYXNzLCBub3QgYSBuYW1lLCBhbmQgbXVzdCBiZSBzZXQgdXNpbmcgdGhlCis8Y29kZT5wdXQ8L2NvZGU+IG1ldGhvZCwgbm90IHRoZSA8Y29kZT5zZXRQcm9wZXJ0eTwvY29kZT4gbWV0aG9kLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnNtdHAuc29ja2V0RmFjdG9yeS5jbGFzcyI+bWFpbC5zbXRwLnNvY2tldEZhY3RvcnkuY2xhc3M8L0E+PC9URD4KKzxURD5TdHJpbmc8L1REPgorPFREPgorSWYgc2V0LCBzcGVjaWZpZXMgdGhlIG5hbWUgb2YgYSBjbGFzcyB0aGF0IGltcGxlbWVudHMgdGhlCis8Y29kZT5qYXZheC5uZXQuU29ja2V0RmFjdG9yeTwvY29kZT4gaW50ZXJmYWNlLiAgVGhpcyBjbGFzcword2lsbCBiZSB1c2VkIHRvIGNyZWF0ZSBTTVRQIHNvY2tldHMuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuc210cC5zb2NrZXRGYWN0b3J5LmZhbGxiYWNrIj5tYWlsLnNtdHAuc29ja2V0RmFjdG9yeS5mYWxsYmFjazwvQT48L1REPgorPFREPmJvb2xlYW48L1REPgorPFREPgorSWYgc2V0IHRvIHRydWUsIGZhaWx1cmUgdG8gY3JlYXRlIGEgc29ja2V0IHVzaW5nIHRoZSBzcGVjaWZpZWQKK3NvY2tldCBmYWN0b3J5IGNsYXNzIHdpbGwgY2F1c2UgdGhlIHNvY2tldCB0byBiZSBjcmVhdGVkIHVzaW5nCit0aGUgPGNvZGU+amF2YS5uZXQuU29ja2V0PC9jb2RlPiBjbGFzcy4KK0RlZmF1bHRzIHRvIHRydWUuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuc210cC5zb2NrZXRGYWN0b3J5LnBvcnQiPm1haWwuc210cC5zb2NrZXRGYWN0b3J5LnBvcnQ8L0E+PC9URD4KKzxURD5pbnQ8L1REPgorPFREPgorU3BlY2lmaWVzIHRoZSBwb3J0IHRvIGNvbm5lY3QgdG8gd2hlbiB1c2luZyB0aGUgc3BlY2lmaWVkIHNvY2tldAorZmFjdG9yeS4KK0lmIG5vdCBzZXQsIHRoZSBkZWZhdWx0IHBvcnQgd2lsbCBiZSB1c2VkLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnNtdHAuc3NsLmVuYWJsZSI+bWFpbC5zbXRwLnNzbC5lbmFibGU8L0E+PC9URD4KKzxURD5ib29sZWFuPC9URD4KKzxURD4KK0lmIHNldCB0byB0cnVlLCB1c2UgU1NMIHRvIGNvbm5lY3QgYW5kIHVzZSB0aGUgU1NMIHBvcnQgYnkgZGVmYXVsdC4KK0RlZmF1bHRzIHRvIGZhbHNlIGZvciB0aGUgInNtdHAiIHByb3RvY29sIGFuZCB0cnVlIGZvciB0aGUgInNtdHBzIiBwcm90b2NvbC4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5zbXRwLnNzbC5jaGVja3NlcnZlcmlkZW50aXR5Ij5tYWlsLnNtdHAuc3NsLmNoZWNrc2VydmVyaWRlbnRpdHk8L0E+PC9URD4KKzxURD5ib29sZWFuPC9URD4KKzxURD4KK0lmIHNldCB0byB0cnVlLCBjaGVjayB0aGUgc2VydmVyIGlkZW50aXR5IGFzIHNwZWNpZmllZCBieQorPEEgSFJFRj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjU5NS50eHQiIFRBUkdFVD0iX3RvcCI+UkZDIDI1OTU8L0E+LgorVGhlc2UgYWRkaXRpb25hbCBjaGVja3MgYmFzZWQgb24gdGhlIGNvbnRlbnQgb2YgdGhlIHNlcnZlcidzIGNlcnRpZmljYXRlCithcmUgaW50ZW5kZWQgdG8gcHJldmVudCBtYW4taW4tdGhlLW1pZGRsZSBhdHRhY2tzLgorRGVmYXVsdHMgdG8gZmFsc2UuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuc210cC5zc2wudHJ1c3QiPm1haWwuc210cC5zc2wudHJ1c3Q8L0E+PC9URD4KKzxURD5TdHJpbmc8L1REPgorPFREPgorSWYgc2V0LCBhbmQgYSBzb2NrZXQgZmFjdG9yeSBoYXNuJ3QgYmVlbiBzcGVjaWZpZWQsIGVuYWJsZXMgdXNlIG9mIGEKK3tAbGluayBjb20uc3VuLm1haWwudXRpbC5NYWlsU1NMU29ja2V0RmFjdG9yeSBNYWlsU1NMU29ja2V0RmFjdG9yeX0uCitJZiBzZXQgdG8gIioiLCBhbGwgaG9zdHMgYXJlIHRydXN0ZWQuCitJZiBzZXQgdG8gYSB3aGl0ZXNwYWNlIHNlcGFyYXRlZCBsaXN0IG9mIGhvc3RzLCB0aG9zZSBob3N0cyBhcmUgdHJ1c3RlZC4KK090aGVyd2lzZSwgdHJ1c3QgZGVwZW5kcyBvbiB0aGUgY2VydGlmaWNhdGUgdGhlIHNlcnZlciBwcmVzZW50cy4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5zbXRwLnNzbC5zb2NrZXRGYWN0b3J5Ij5tYWlsLnNtdHAuc3NsLnNvY2tldEZhY3Rvcnk8L0E+PC9URD4KKzxURD5TU0xTb2NrZXRGYWN0b3J5PC9URD4KKzxURD4KK0lmIHNldCB0byBhIGNsYXNzIHRoYXQgZXh0ZW5kcyB0aGUKKzxjb2RlPmphdmF4Lm5ldC5zc2wuU1NMU29ja2V0RmFjdG9yeTwvY29kZT4gY2xhc3MsIHRoaXMgY2xhc3MKK3dpbGwgYmUgdXNlZCB0byBjcmVhdGUgU01UUCBTU0wgc29ja2V0cy4gIE5vdGUgdGhhdCB0aGlzIGlzIGFuCitpbnN0YW5jZSBvZiBhIGNsYXNzLCBub3QgYSBuYW1lLCBhbmQgbXVzdCBiZSBzZXQgdXNpbmcgdGhlCis8Y29kZT5wdXQ8L2NvZGU+IG1ldGhvZCwgbm90IHRoZSA8Y29kZT5zZXRQcm9wZXJ0eTwvY29kZT4gbWV0aG9kLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnNtdHAuc3NsLnNvY2tldEZhY3RvcnkuY2xhc3MiPm1haWwuc210cC5zc2wuc29ja2V0RmFjdG9yeS5jbGFzczwvQT48L1REPgorPFREPlN0cmluZzwvVEQ+Cis8VEQ+CitJZiBzZXQsIHNwZWNpZmllcyB0aGUgbmFtZSBvZiBhIGNsYXNzIHRoYXQgZXh0ZW5kcyB0aGUKKzxjb2RlPmphdmF4Lm5ldC5zc2wuU1NMU29ja2V0RmFjdG9yeTwvY29kZT4gY2xhc3MuICBUaGlzIGNsYXNzCit3aWxsIGJlIHVzZWQgdG8gY3JlYXRlIFNNVFAgU1NMIHNvY2tldHMuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuc210cC5zc2wuc29ja2V0RmFjdG9yeS5wb3J0Ij5tYWlsLnNtdHAuc3NsLnNvY2tldEZhY3RvcnkucG9ydDwvQT48L1REPgorPFREPmludDwvVEQ+Cis8VEQ+CitTcGVjaWZpZXMgdGhlIHBvcnQgdG8gY29ubmVjdCB0byB3aGVuIHVzaW5nIHRoZSBzcGVjaWZpZWQgc29ja2V0CitmYWN0b3J5LgorSWYgbm90IHNldCwgdGhlIGRlZmF1bHQgcG9ydCB3aWxsIGJlIHVzZWQuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuc210cC5zc2wucHJvdG9jb2xzIj5tYWlsLnNtdHAuc3NsLnByb3RvY29sczwvQT48L1REPgorPFREPnN0cmluZzwvVEQ+Cis8VEQ+CitTcGVjaWZpZXMgdGhlIFNTTCBwcm90b2NvbHMgdGhhdCB3aWxsIGJlIGVuYWJsZWQgZm9yIFNTTCBjb25uZWN0aW9ucy4KK1RoZSBwcm9wZXJ0eSB2YWx1ZSBpcyBhIHdoaXRlc3BhY2Ugc2VwYXJhdGVkIGxpc3Qgb2YgdG9rZW5zIGFjY2VwdGFibGUKK3RvIHRoZSA8Y29kZT5qYXZheC5uZXQuc3NsLlNTTFNvY2tldC5zZXRFbmFibGVkUHJvdG9jb2xzPC9jb2RlPiBtZXRob2QuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuc210cC5zc2wuY2lwaGVyc3VpdGVzIj5tYWlsLnNtdHAuc3NsLmNpcGhlcnN1aXRlczwvQT48L1REPgorPFREPnN0cmluZzwvVEQ+Cis8VEQ+CitTcGVjaWZpZXMgdGhlIFNTTCBjaXBoZXIgc3VpdGVzIHRoYXQgd2lsbCBiZSBlbmFibGVkIGZvciBTU0wgY29ubmVjdGlvbnMuCitUaGUgcHJvcGVydHkgdmFsdWUgaXMgYSB3aGl0ZXNwYWNlIHNlcGFyYXRlZCBsaXN0IG9mIHRva2VucyBhY2NlcHRhYmxlCit0byB0aGUgPGNvZGU+amF2YXgubmV0LnNzbC5TU0xTb2NrZXQuc2V0RW5hYmxlZENpcGhlclN1aXRlczwvY29kZT4gbWV0aG9kLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnNtdHAuc3RhcnR0bHMuZW5hYmxlIj5tYWlsLnNtdHAuc3RhcnR0bHMuZW5hYmxlPC9BPjwvVEQ+Cis8VEQ+Ym9vbGVhbjwvVEQ+Cis8VEQ+CitJZiB0cnVlLCBlbmFibGVzIHRoZSB1c2Ugb2YgdGhlIDxjb2RlPlNUQVJUVExTPC9jb2RlPiBjb21tYW5kIChpZgorc3VwcG9ydGVkIGJ5IHRoZSBzZXJ2ZXIpIHRvIHN3aXRjaCB0aGUgY29ubmVjdGlvbiB0byBhIFRMUy1wcm90ZWN0ZWQKK2Nvbm5lY3Rpb24gYmVmb3JlIGlzc3VpbmcgYW55IGxvZ2luIGNvbW1hbmRzLgorSWYgdGhlIHNlcnZlciBkb2VzIG5vdCBzdXBwb3J0IFNUQVJUVExTLCB0aGUgY29ubmVjdGlvbiBjb250aW51ZXMgd2l0aG91dAordGhlIHVzZSBvZiBUTFM7IHNlZSB0aGUKKzxBIEhSRUY9IiNtYWlsLnNtdHAuc3RhcnR0bHMucmVxdWlyZWQiPjxjb2RlPm1haWwuc210cC5zdGFydHRscy5yZXF1aXJlZDwvY29kZT48L0E+Citwcm9wZXJ0eSB0byBmYWlsIGlmIFNUQVJUVExTIGlzbid0IHN1cHBvcnRlZC4KK05vdGUgdGhhdCBhbiBhcHByb3ByaWF0ZSB0cnVzdCBzdG9yZSBtdXN0IGNvbmZpZ3VyZWQgc28gdGhhdCB0aGUgY2xpZW50Cit3aWxsIHRydXN0IHRoZSBzZXJ2ZXIncyBjZXJ0aWZpY2F0ZS4KK0RlZmF1bHRzIHRvIGZhbHNlLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnNtdHAuc3RhcnR0bHMucmVxdWlyZWQiPm1haWwuc210cC5zdGFydHRscy5yZXF1aXJlZDwvQT48L1REPgorPFREPmJvb2xlYW48L1REPgorPFREPgorSWYgdHJ1ZSwgcmVxdWlyZXMgdGhlIHVzZSBvZiB0aGUgPGNvZGU+U1RBUlRUTFM8L2NvZGU+IGNvbW1hbmQuCitJZiB0aGUgc2VydmVyIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgU1RBUlRUTFMgY29tbWFuZCwgb3IgdGhlIGNvbW1hbmQKK2ZhaWxzLCB0aGUgY29ubmVjdCBtZXRob2Qgd2lsbCBmYWlsLgorRGVmYXVsdHMgdG8gZmFsc2UuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuc210cC5wcm94eS5ob3N0Ij5tYWlsLnNtdHAucHJveHkuaG9zdDwvQT48L1REPgorPFREPnN0cmluZzwvVEQ+Cis8VEQ+CitTcGVjaWZpZXMgdGhlIGhvc3QgbmFtZSBvZiBhbiBIVFRQIHdlYiBwcm94eSBzZXJ2ZXIgdGhhdCB3aWxsIGJlIHVzZWQgZm9yCitjb25uZWN0aW9ucyB0byB0aGUgbWFpbCBzZXJ2ZXIuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuc210cC5wcm94eS5wb3J0Ij5tYWlsLnNtdHAucHJveHkucG9ydDwvQT48L1REPgorPFREPnN0cmluZzwvVEQ+Cis8VEQ+CitTcGVjaWZpZXMgdGhlIHBvcnQgbnVtYmVyIGZvciB0aGUgSFRUUCB3ZWIgcHJveHkgc2VydmVyLgorRGVmYXVsdHMgdG8gcG9ydCA4MC4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5zbXRwLnByb3h5LnVzZXIiPm1haWwuc210cC5wcm94eS51c2VyPC9BPjwvVEQ+Cis8VEQ+c3RyaW5nPC9URD4KKzxURD4KK1NwZWNpZmllcyB0aGUgdXNlciBuYW1lIHRvIHVzZSB0byBhdXRoZW50aWNhdGUgd2l0aCB0aGUgSFRUUCB3ZWIgcHJveHkgc2VydmVyLgorQnkgZGVmYXVsdCwgbm8gYXV0aGVudGljYXRpb24gaXMgZG9uZS4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5zbXRwLnByb3h5LnBhc3N3b3JkIj5tYWlsLnNtdHAucHJveHkucGFzc3dvcmQ8L0E+PC9URD4KKzxURD5zdHJpbmc8L1REPgorPFREPgorU3BlY2lmaWVzIHRoZSBwYXNzd29yZCB0byB1c2UgdG8gYXV0aGVudGljYXRlIHdpdGggdGhlIEhUVFAgd2ViIHByb3h5IHNlcnZlci4KK0J5IGRlZmF1bHQsIG5vIGF1dGhlbnRpY2F0aW9uIGlzIGRvbmUuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuc210cC5zb2Nrcy5ob3N0Ij5tYWlsLnNtdHAuc29ja3MuaG9zdDwvQT48L1REPgorPFREPnN0cmluZzwvVEQ+Cis8VEQ+CitTcGVjaWZpZXMgdGhlIGhvc3QgbmFtZSBvZiBhIFNPQ0tTNSBwcm94eSBzZXJ2ZXIgdGhhdCB3aWxsIGJlIHVzZWQgZm9yCitjb25uZWN0aW9ucyB0byB0aGUgbWFpbCBzZXJ2ZXIuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuc210cC5zb2Nrcy5wb3J0Ij5tYWlsLnNtdHAuc29ja3MucG9ydDwvQT48L1REPgorPFREPnN0cmluZzwvVEQ+Cis8VEQ+CitTcGVjaWZpZXMgdGhlIHBvcnQgbnVtYmVyIGZvciB0aGUgU09DS1M1IHByb3h5IHNlcnZlci4KK1RoaXMgc2hvdWxkIG9ubHkgbmVlZCB0byBiZSB1c2VkIGlmIHRoZSBwcm94eSBzZXJ2ZXIgaXMgbm90IHVzaW5nCit0aGUgc3RhbmRhcmQgcG9ydCBudW1iZXIgb2YgMTA4MC4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5zbXRwLm1haWxleHRlbnNpb24iPm1haWwuc210cC5tYWlsZXh0ZW5zaW9uPC9BPjwvVEQ+Cis8VEQ+U3RyaW5nPC9URD4KKzxURD4KK0V4dGVuc2lvbiBzdHJpbmcgdG8gYXBwZW5kIHRvIHRoZSBNQUlMIGNvbW1hbmQuCitUaGUgZXh0ZW5zaW9uIHN0cmluZyBjYW4gYmUgdXNlZCB0byBzcGVjaWZ5IHN0YW5kYXJkIFNNVFAKK3NlcnZpY2UgZXh0ZW5zaW9ucyBhcyB3ZWxsIGFzIHZlbmRvci1zcGVjaWZpYyBleHRlbnNpb25zLgorVHlwaWNhbGx5IHRoZSBhcHBsaWNhdGlvbiBzaG91bGQgdXNlIHRoZQore0BsaW5rIGNvbS5zdW4ubWFpbC5zbXRwLlNNVFBUcmFuc3BvcnQgU01UUFRyYW5zcG9ydH0KK21ldGhvZCB7QGxpbmsgY29tLnN1bi5tYWlsLnNtdHAuU01UUFRyYW5zcG9ydCNzdXBwb3J0c0V4dGVuc2lvbgorc3VwcG9ydHNFeHRlbnNpb259Cit0byB2ZXJpZnkgdGhhdCB0aGUgc2VydmVyIHN1cHBvcnRzIHRoZSBkZXNpcmVkIHNlcnZpY2UgZXh0ZW5zaW9uLgorU2VlIDxBIEhSRUY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzE4NjkudHh0IiBUQVJHRVQ9Il90b3AiPlJGQyAxODY5PC9BPgorYW5kIG90aGVyIFJGQ3MgdGhhdCBkZWZpbmUgc3BlY2lmaWMgZXh0ZW5zaW9ucy4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5zbXRwLnVzZXJzZXQiPm1haWwuc210cC51c2Vyc2V0PC9BPjwvVEQ+Cis8VEQ+Ym9vbGVhbjwvVEQ+Cis8VEQ+CitJZiBzZXQgdG8gdHJ1ZSwgdXNlIHRoZSBSU0VUIGNvbW1hbmQgaW5zdGVhZCBvZiB0aGUgTk9PUCBjb21tYW5kCitpbiB0aGUge0BsaW5rIGphdmF4Lm1haWwuVHJhbnNwb3J0I2lzQ29ubmVjdGVkIGlzQ29ubmVjdGVkfSBtZXRob2QuCitJbiBzb21lIGNhc2VzIHNlbmRtYWlsIHdpbGwgcmVzcG9uZCBzbG93bHkgYWZ0ZXIgbWFueSBOT09QIGNvbW1hbmRzOwordXNlIG9mIFJTRVQgYXZvaWRzIHRoaXMgc2VuZG1haWwgaXNzdWUuCitEZWZhdWx0cyB0byBmYWxzZS4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5zbXRwLm5vb3Auc3RyaWN0Ij5tYWlsLnNtdHAubm9vcC5zdHJpY3Q8L0E+PC9URD4KKzxURD5ib29sZWFuPC9URD4KKzxURD4KK0lmIHNldCB0byB0cnVlICh0aGUgZGVmYXVsdCksIGluc2lzdCBvbiBhIDI1MCByZXNwb25zZSBjb2RlIGZyb20gdGhlIE5PT1AKK2NvbW1hbmQgdG8gaW5kaWNhdGUgc3VjY2Vzcy4gIFRoZSBOT09QIGNvbW1hbmQgaXMgdXNlZCBieSB0aGUKK3tAbGluayBqYXZheC5tYWlsLlRyYW5zcG9ydCNpc0Nvbm5lY3RlZCBpc0Nvbm5lY3RlZH0gbWV0aG9kIHRvIGRldGVybWluZQoraWYgdGhlIGNvbm5lY3Rpb24gaXMgc3RpbGwgYWxpdmUuCitTb21lIG9sZGVyIHNlcnZlcnMgcmV0dXJuIHRoZSB3cm9uZyByZXNwb25zZSBjb2RlIG9uIHN1Y2Nlc3MsIHNvbWUKK3NlcnZlcnMgZG9uJ3QgaW1wbGVtZW50IHRoZSBOT09QIGNvbW1hbmQgYXQgYWxsIGFuZCBzbyBhbHdheXMgcmV0dXJuCithIGZhaWx1cmUgY29kZS4gIFNldCB0aGlzIHByb3BlcnR5IHRvIGZhbHNlIHRvIGhhbmRsZSBzZXJ2ZXJzCit0aGF0IGFyZSBicm9rZW4gaW4gdGhpcyB3YXkuCitOb3JtYWxseSwgd2hlbiBhIHNlcnZlciB0aW1lcyBvdXQgYSBjb25uZWN0aW9uLCBpdCB3aWxsIHNlbmQgYSA0MjEKK3Jlc3BvbnNlIGNvZGUsIHdoaWNoIHRoZSBjbGllbnQgd2lsbCBzZWUgYXMgdGhlIHJlc3BvbnNlIHRvIHRoZSBuZXh0Citjb21tYW5kIGl0IGlzc3Vlcy4KK1NvbWUgc2VydmVycyBzZW5kIHRoZSB3cm9uZyBmYWlsdXJlIHJlc3BvbnNlIGNvZGUgd2hlbiB0aW1pbmcgb3V0IGEKK2Nvbm5lY3Rpb24uCitEbyBub3Qgc2V0IHRoaXMgcHJvcGVydHkgdG8gZmFsc2Ugd2hlbiBkZWFsaW5nIHdpdGggc2VydmVycyB0aGF0IGFyZQorYnJva2VuIGluIHRoaXMgd2F5LgorPC9URD4KKzwvVFI+CisKKzwvVEFCTEU+Cis8UD4KK0luIGdlbmVyYWwsIGFwcGxpY2F0aW9ucyBzaG91bGQgbm90IG5lZWQgdG8gdXNlIHRoZSBjbGFzc2VzIGluIHRoaXMKK3BhY2thZ2UgZGlyZWN0bHkuICBJbnN0ZWFkLCB0aGV5IHNob3VsZCB1c2UgdGhlIEFQSXMgZGVmaW5lZCBieQorPGNvZGU+amF2YXgubWFpbDwvY29kZT4gcGFja2FnZSAoYW5kIHN1YnBhY2thZ2VzKS4gIEFwcGxpY2F0aW9ucyBzaG91bGQKK25ldmVyIGNvbnN0cnVjdCBpbnN0YW5jZXMgb2YgPGNvZGU+U01UUFRyYW5zcG9ydDwvY29kZT4gZGlyZWN0bHkuCitJbnN0ZWFkLCB0aGV5IHNob3VsZCB1c2UgdGhlCis8Y29kZT5TZXNzaW9uPC9jb2RlPiBtZXRob2QgPGNvZGU+Z2V0VHJhbnNwb3J0PC9jb2RlPiB0byBhY3F1aXJlIGFuCithcHByb3ByaWF0ZSA8Y29kZT5UcmFuc3BvcnQ8L2NvZGU+IG9iamVjdC4KKzwvUD4KKzxQPgorSW4gYWRkaXRpb24gdG8gcHJpbnRpbmcgZGVidWdnaW5nIG91dHB1dCBhcyBjb250cm9sbGVkIGJ5IHRoZQore0BsaW5rIGphdmF4Lm1haWwuU2Vzc2lvbiBTZXNzaW9ufSBjb25maWd1cmF0aW9uLAordGhlIGNvbS5zdW4ubWFpbC5zbXRwIHByb3ZpZGVyIGxvZ3MgdGhlIHNhbWUgaW5mb3JtYXRpb24gdXNpbmcKK3tAbGluayBqYXZhLnV0aWwubG9nZ2luZy5Mb2dnZXJ9IGFzIGRlc2NyaWJlZCBpbiB0aGUgZm9sbG93aW5nIHRhYmxlOgorPC9QPgorPFRBQkxFIEJPUkRFUiBTVU1NQVJZPSJTTVRQIExvZ2dlcnMiPgorPFRSPgorPFRIPkxvZ2dlciBOYW1lPC9USD4KKzxUSD5Mb2dnaW5nIExldmVsPC9USD4KKzxUSD5QdXJwb3NlPC9USD4KKzwvVFI+CisKKzxUUj4KKzxURD5jb20uc3VuLm1haWwuc210cDwvVEQ+Cis8VEQ+Q09ORklHPC9URD4KKzxURD5Db25maWd1cmF0aW9uIG9mIHRoZSBTTVRQVHJhbnNwb3J0PC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD5jb20uc3VuLm1haWwuc210cDwvVEQ+Cis8VEQ+RklORTwvVEQ+Cis8VEQ+R2VuZXJhbCBkZWJ1Z2dpbmcgb3V0cHV0PC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD5jb20uc3VuLm1haWwuc210cC5wcm90b2NvbDwvVEQ+Cis8VEQ+RklORVNUPC9URD4KKzxURD5Db21wbGV0ZSBwcm90b2NvbCB0cmFjZTwvVEQ+Cis8L1RSPgorPC9UQUJMRT4KKzxQPgorPHN0cm9uZz5XQVJOSU5HOjwvc3Ryb25nPiBUaGUgQVBJcyB1bmlxdWUgdG8gdGhpcyBwYWNrYWdlIHNob3VsZCBiZQorY29uc2lkZXJlZCA8c3Ryb25nPkVYUEVSSU1FTlRBTDwvc3Ryb25nPi4gIFRoZXkgbWF5IGJlIGNoYW5nZWQgaW4gdGhlCitmdXR1cmUgaW4gd2F5cyB0aGF0IGFyZSBpbmNvbXBhdGlibGUgd2l0aCBhcHBsaWNhdGlvbnMgdXNpbmcgdGhlCitjdXJyZW50IEFQSXMuCis8L1A+CisKKzwvQk9EWT4KKzwvSFRNTD4KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvdXRpbC9BU0NJSVV0aWxpdHkuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvdXRpbC9BU0NJSVV0aWxpdHkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40YWI3YTU1Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL0FTQ0lJVXRpbGl0eS5qYXZhCkBAIC0wLDAgKzEsMjg0IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC51dGlsOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKK3B1YmxpYyBjbGFzcyBBU0NJSVV0aWxpdHkgeworCisgICAgLy8gUHJpdmF0ZSBjb25zdHJ1Y3RvciBzbyB0aGF0IHRoaXMgY2xhc3MgaXMgbm90IGluc3RhbnRpYXRlZAorICAgIHByaXZhdGUgQVNDSUlVdGlsaXR5KCkgeyB9CisJCisgICAgLyoqCisgICAgICogQ29udmVydCB0aGUgYnl0ZXMgd2l0aGluIHRoZSBzcGVjaWZpZWQgcmFuZ2Ugb2YgdGhlIGdpdmVuIGJ5dGUgCisgICAgICogYXJyYXkgaW50byBhIHNpZ25lZCBpbnRlZ2VyIGluIHRoZSBnaXZlbiByYWRpeCAuIFRoZSByYW5nZSBleHRlbmRzIAorICAgICAqIGZyb20gPGNvZGU+c3RhcnQ8L2NvZGU+IHRpbGwsIGJ1dCBub3QgaW5jbHVkaW5nIDxjb2RlPmVuZDwvY29kZT4uIDxwPgorICAgICAqCisgICAgICogQmFzZWQgb24gamF2YS5sYW5nLkludGVnZXIucGFyc2VJbnQoKQorICAgICAqCisgICAgICogQHBhcmFtCWIJdGhlIGJ5dGVzCisgICAgICogQHBhcmFtCXN0YXJ0CXRoZSBmaXJzdCBieXRlIG9mZnNldAorICAgICAqIEBwYXJhbQllbmQJdGhlIGxhc3QgYnl0ZSBvZmZzZXQKKyAgICAgKiBAcGFyYW0JcmFkaXgJdGhlIHJhZGl4CisgICAgICogQHJldHVybgkJdGhlIGludGVnZXIgdmFsdWUKKyAgICAgKiBAZXhjZXB0aW9uCU51bWJlckZvcm1hdEV4Y2VwdGlvbglmb3IgY29udmVyc2lvbiBlcnJvcnMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBwYXJzZUludChieXRlW10gYiwgaW50IHN0YXJ0LCBpbnQgZW5kLCBpbnQgcmFkaXgpCisJCXRocm93cyBOdW1iZXJGb3JtYXRFeGNlcHRpb24geworCWlmIChiID09IG51bGwpCisJICAgIHRocm93IG5ldyBOdW1iZXJGb3JtYXRFeGNlcHRpb24oIm51bGwiKTsKKwkKKwlpbnQgcmVzdWx0ID0gMDsKKwlib29sZWFuIG5lZ2F0aXZlID0gZmFsc2U7CisJaW50IGkgPSBzdGFydDsKKwlpbnQgbGltaXQ7CisJaW50IG11bHRtaW47CisJaW50IGRpZ2l0OworCisJaWYgKGVuZCA+IHN0YXJ0KSB7CisJICAgIGlmIChiW2ldID09ICctJykgeworCQluZWdhdGl2ZSA9IHRydWU7CisJCWxpbWl0ID0gSW50ZWdlci5NSU5fVkFMVUU7CisJCWkrKzsKKwkgICAgfSBlbHNlIHsKKwkJbGltaXQgPSAtSW50ZWdlci5NQVhfVkFMVUU7CisJICAgIH0KKwkgICAgbXVsdG1pbiA9IGxpbWl0IC8gcmFkaXg7CisJICAgIGlmIChpIDwgZW5kKSB7CisJCWRpZ2l0ID0gQ2hhcmFjdGVyLmRpZ2l0KChjaGFyKWJbaSsrXSwgcmFkaXgpOworCQlpZiAoZGlnaXQgPCAwKSB7CisJCSAgICB0aHJvdyBuZXcgTnVtYmVyRm9ybWF0RXhjZXB0aW9uKAorCQkJImlsbGVnYWwgbnVtYmVyOiAiICsgdG9TdHJpbmcoYiwgc3RhcnQsIGVuZCkKKwkJCSk7CisJCX0gZWxzZSB7CisJCSAgICByZXN1bHQgPSAtZGlnaXQ7CisJCX0KKwkgICAgfQorCSAgICB3aGlsZSAoaSA8IGVuZCkgeworCQkvLyBBY2N1bXVsYXRpbmcgbmVnYXRpdmVseSBhdm9pZHMgc3VycHJpc2VzIG5lYXIgTUFYX1ZBTFVFCisJCWRpZ2l0ID0gQ2hhcmFjdGVyLmRpZ2l0KChjaGFyKWJbaSsrXSwgcmFkaXgpOworCQlpZiAoZGlnaXQgPCAwKSB7CisJCSAgICB0aHJvdyBuZXcgTnVtYmVyRm9ybWF0RXhjZXB0aW9uKCJpbGxlZ2FsIG51bWJlciIpOworCQl9CisJCWlmIChyZXN1bHQgPCBtdWx0bWluKSB7CisJCSAgICB0aHJvdyBuZXcgTnVtYmVyRm9ybWF0RXhjZXB0aW9uKCJpbGxlZ2FsIG51bWJlciIpOworCQl9CisJCXJlc3VsdCAqPSByYWRpeDsKKwkJaWYgKHJlc3VsdCA8IGxpbWl0ICsgZGlnaXQpIHsKKwkJICAgIHRocm93IG5ldyBOdW1iZXJGb3JtYXRFeGNlcHRpb24oImlsbGVnYWwgbnVtYmVyIik7CisJCX0KKwkJcmVzdWx0IC09IGRpZ2l0OworCSAgICB9CisJfSBlbHNlIHsKKwkgICAgdGhyb3cgbmV3IE51bWJlckZvcm1hdEV4Y2VwdGlvbigiaWxsZWdhbCBudW1iZXIiKTsKKwl9CisJaWYgKG5lZ2F0aXZlKSB7CisJICAgIGlmIChpID4gc3RhcnQgKyAxKSB7CisJCXJldHVybiByZXN1bHQ7CisJICAgIH0gZWxzZSB7CS8qIE9ubHkgZ290ICItIiAqLworCQl0aHJvdyBuZXcgTnVtYmVyRm9ybWF0RXhjZXB0aW9uKCJpbGxlZ2FsIG51bWJlciIpOworCSAgICB9CisJfSBlbHNlIHsKKwkgICAgcmV0dXJuIC1yZXN1bHQ7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlcnQgdGhlIGJ5dGVzIHdpdGhpbiB0aGUgc3BlY2lmaWVkIHJhbmdlIG9mIHRoZSBnaXZlbiBieXRlIAorICAgICAqIGFycmF5IGludG8gYSBzaWduZWQgaW50ZWdlciAuIFRoZSByYW5nZSBleHRlbmRzIGZyb20gCisgICAgICogPGNvZGU+c3RhcnQ8L2NvZGU+IHRpbGwsIGJ1dCBub3QgaW5jbHVkaW5nIDxjb2RlPmVuZDwvY29kZT4uCisgICAgICoKKyAgICAgKiBAcGFyYW0JYgl0aGUgYnl0ZXMKKyAgICAgKiBAcGFyYW0Jc3RhcnQJdGhlIGZpcnN0IGJ5dGUgb2Zmc2V0CisgICAgICogQHBhcmFtCWVuZAl0aGUgbGFzdCBieXRlIG9mZnNldAorICAgICAqIEByZXR1cm4JCXRoZSBpbnRlZ2VyIHZhbHVlCisgICAgICogQGV4Y2VwdGlvbglOdW1iZXJGb3JtYXRFeGNlcHRpb24JZm9yIGNvbnZlcnNpb24gZXJyb3JzCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgcGFyc2VJbnQoYnl0ZVtdIGIsIGludCBzdGFydCwgaW50IGVuZCkKKwkJdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbiB7CisJcmV0dXJuIHBhcnNlSW50KGIsIHN0YXJ0LCBlbmQsIDEwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0IHRoZSBieXRlcyB3aXRoaW4gdGhlIHNwZWNpZmllZCByYW5nZSBvZiB0aGUgZ2l2ZW4gYnl0ZSAKKyAgICAgKiBhcnJheSBpbnRvIGEgc2lnbmVkIGxvbmcgaW4gdGhlIGdpdmVuIHJhZGl4IC4gVGhlIHJhbmdlIGV4dGVuZHMgCisgICAgICogZnJvbSA8Y29kZT5zdGFydDwvY29kZT4gdGlsbCwgYnV0IG5vdCBpbmNsdWRpbmcgPGNvZGU+ZW5kPC9jb2RlPi4gPHA+CisgICAgICoKKyAgICAgKiBCYXNlZCBvbiBqYXZhLmxhbmcuTG9uZy5wYXJzZUxvbmcoKQorICAgICAqCisgICAgICogQHBhcmFtCWIJdGhlIGJ5dGVzCisgICAgICogQHBhcmFtCXN0YXJ0CXRoZSBmaXJzdCBieXRlIG9mZnNldAorICAgICAqIEBwYXJhbQllbmQJdGhlIGxhc3QgYnl0ZSBvZmZzZXQKKyAgICAgKiBAcGFyYW0JcmFkaXgJdGhlIHJhZGl4CisgICAgICogQHJldHVybgkJdGhlIGxvbmcgdmFsdWUKKyAgICAgKiBAZXhjZXB0aW9uCU51bWJlckZvcm1hdEV4Y2VwdGlvbglmb3IgY29udmVyc2lvbiBlcnJvcnMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGxvbmcgcGFyc2VMb25nKGJ5dGVbXSBiLCBpbnQgc3RhcnQsIGludCBlbmQsIGludCByYWRpeCkKKwkJdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbiB7CisJaWYgKGIgPT0gbnVsbCkKKwkgICAgdGhyb3cgbmV3IE51bWJlckZvcm1hdEV4Y2VwdGlvbigibnVsbCIpOworCQorCWxvbmcgcmVzdWx0ID0gMDsKKwlib29sZWFuIG5lZ2F0aXZlID0gZmFsc2U7CisJaW50IGkgPSBzdGFydDsKKwlsb25nIGxpbWl0OworCWxvbmcgbXVsdG1pbjsKKwlpbnQgZGlnaXQ7CisKKwlpZiAoZW5kID4gc3RhcnQpIHsKKwkgICAgaWYgKGJbaV0gPT0gJy0nKSB7CisJCW5lZ2F0aXZlID0gdHJ1ZTsKKwkJbGltaXQgPSBMb25nLk1JTl9WQUxVRTsKKwkJaSsrOworCSAgICB9IGVsc2UgeworCQlsaW1pdCA9IC1Mb25nLk1BWF9WQUxVRTsKKwkgICAgfQorCSAgICBtdWx0bWluID0gbGltaXQgLyByYWRpeDsKKwkgICAgaWYgKGkgPCBlbmQpIHsKKwkJZGlnaXQgPSBDaGFyYWN0ZXIuZGlnaXQoKGNoYXIpYltpKytdLCByYWRpeCk7CisJCWlmIChkaWdpdCA8IDApIHsKKwkJICAgIHRocm93IG5ldyBOdW1iZXJGb3JtYXRFeGNlcHRpb24oCisJCQkiaWxsZWdhbCBudW1iZXI6ICIgKyB0b1N0cmluZyhiLCBzdGFydCwgZW5kKQorCQkJKTsKKwkJfSBlbHNlIHsKKwkJICAgIHJlc3VsdCA9IC1kaWdpdDsKKwkJfQorCSAgICB9CisJICAgIHdoaWxlIChpIDwgZW5kKSB7CisJCS8vIEFjY3VtdWxhdGluZyBuZWdhdGl2ZWx5IGF2b2lkcyBzdXJwcmlzZXMgbmVhciBNQVhfVkFMVUUKKwkJZGlnaXQgPSBDaGFyYWN0ZXIuZGlnaXQoKGNoYXIpYltpKytdLCByYWRpeCk7CisJCWlmIChkaWdpdCA8IDApIHsKKwkJICAgIHRocm93IG5ldyBOdW1iZXJGb3JtYXRFeGNlcHRpb24oImlsbGVnYWwgbnVtYmVyIik7CisJCX0KKwkJaWYgKHJlc3VsdCA8IG11bHRtaW4pIHsKKwkJICAgIHRocm93IG5ldyBOdW1iZXJGb3JtYXRFeGNlcHRpb24oImlsbGVnYWwgbnVtYmVyIik7CisJCX0KKwkJcmVzdWx0ICo9IHJhZGl4OworCQlpZiAocmVzdWx0IDwgbGltaXQgKyBkaWdpdCkgeworCQkgICAgdGhyb3cgbmV3IE51bWJlckZvcm1hdEV4Y2VwdGlvbigiaWxsZWdhbCBudW1iZXIiKTsKKwkJfQorCQlyZXN1bHQgLT0gZGlnaXQ7CisJICAgIH0KKwl9IGVsc2UgeworCSAgICB0aHJvdyBuZXcgTnVtYmVyRm9ybWF0RXhjZXB0aW9uKCJpbGxlZ2FsIG51bWJlciIpOworCX0KKwlpZiAobmVnYXRpdmUpIHsKKwkgICAgaWYgKGkgPiBzdGFydCArIDEpIHsKKwkJcmV0dXJuIHJlc3VsdDsKKwkgICAgfSBlbHNlIHsJLyogT25seSBnb3QgIi0iICovCisJCXRocm93IG5ldyBOdW1iZXJGb3JtYXRFeGNlcHRpb24oImlsbGVnYWwgbnVtYmVyIik7CisJICAgIH0KKwl9IGVsc2UgeworCSAgICByZXR1cm4gLXJlc3VsdDsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydCB0aGUgYnl0ZXMgd2l0aGluIHRoZSBzcGVjaWZpZWQgcmFuZ2Ugb2YgdGhlIGdpdmVuIGJ5dGUgCisgICAgICogYXJyYXkgaW50byBhIHNpZ25lZCBsb25nIC4gVGhlIHJhbmdlIGV4dGVuZHMgZnJvbSAKKyAgICAgKiA8Y29kZT5zdGFydDwvY29kZT4gdGlsbCwgYnV0IG5vdCBpbmNsdWRpbmcgPGNvZGU+ZW5kPC9jb2RlPi4gPHA+CisgICAgICoKKyAgICAgKiBAcGFyYW0JYgl0aGUgYnl0ZXMKKyAgICAgKiBAcGFyYW0Jc3RhcnQJdGhlIGZpcnN0IGJ5dGUgb2Zmc2V0CisgICAgICogQHBhcmFtCWVuZAl0aGUgbGFzdCBieXRlIG9mZnNldAorICAgICAqIEByZXR1cm4JCXRoZSBsb25nIHZhbHVlCisgICAgICogQGV4Y2VwdGlvbglOdW1iZXJGb3JtYXRFeGNlcHRpb24JZm9yIGNvbnZlcnNpb24gZXJyb3JzCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBsb25nIHBhcnNlTG9uZyhieXRlW10gYiwgaW50IHN0YXJ0LCBpbnQgZW5kKQorCQl0aHJvd3MgTnVtYmVyRm9ybWF0RXhjZXB0aW9uIHsKKwlyZXR1cm4gcGFyc2VMb25nKGIsIHN0YXJ0LCBlbmQsIDEwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0IHRoZSBieXRlcyB3aXRoaW4gdGhlIHNwZWNpZmllZCByYW5nZSBvZiB0aGUgZ2l2ZW4gYnl0ZSAKKyAgICAgKiBhcnJheSBpbnRvIGEgU3RyaW5nLiBUaGUgcmFuZ2UgZXh0ZW5kcyBmcm9tIDxjb2RlPnN0YXJ0PC9jb2RlPgorICAgICAqIHRpbGwsIGJ1dCBub3QgaW5jbHVkaW5nIDxjb2RlPmVuZDwvY29kZT4uCisgICAgICoKKyAgICAgKiBAcGFyYW0JYgl0aGUgYnl0ZXMKKyAgICAgKiBAcGFyYW0Jc3RhcnQJdGhlIGZpcnN0IGJ5dGUgb2Zmc2V0CisgICAgICogQHBhcmFtCWVuZAl0aGUgbGFzdCBieXRlIG9mZnNldAorICAgICAqIEByZXR1cm4JCXRoZSBTdHJpbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyB0b1N0cmluZyhieXRlW10gYiwgaW50IHN0YXJ0LCBpbnQgZW5kKSB7CisJaW50IHNpemUgPSBlbmQgLSBzdGFydDsKKwljaGFyW10gdGhlQ2hhcnMgPSBuZXcgY2hhcltzaXplXTsKKworCWZvciAoaW50IGkgPSAwLCBqID0gc3RhcnQ7IGkgPCBzaXplOyApCisJICAgIHRoZUNoYXJzW2krK10gPSAoY2hhcikoYltqKytdJjB4ZmYpOworCQorCXJldHVybiBuZXcgU3RyaW5nKHRoZUNoYXJzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0IHRoZSBieXRlcyBpbnRvIGEgU3RyaW5nLgorICAgICAqCisgICAgICogQHBhcmFtCWIJdGhlIGJ5dGVzCisgICAgICogQHJldHVybgkJdGhlIFN0cmluZworICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjQuNAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHRvU3RyaW5nKGJ5dGVbXSBiKSB7CisJcmV0dXJuIHRvU3RyaW5nKGIsIDAsIGIubGVuZ3RoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyB0b1N0cmluZyhCeXRlQXJyYXlJbnB1dFN0cmVhbSBpcykgeworCWludCBzaXplID0gaXMuYXZhaWxhYmxlKCk7CisJY2hhcltdIHRoZUNoYXJzID0gbmV3IGNoYXJbc2l6ZV07CisJYnl0ZVtdIGJ5dGVzICAgID0gbmV3IGJ5dGVbc2l6ZV07CisKKwlpcy5yZWFkKGJ5dGVzLCAwLCBzaXplKTsKKwlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7KQorCSAgICB0aGVDaGFyc1tpXSA9IChjaGFyKShieXRlc1tpKytdJjB4ZmYpOworCQorCXJldHVybiBuZXcgU3RyaW5nKHRoZUNoYXJzKTsKKyAgICB9CisKKworICAgIHB1YmxpYyBzdGF0aWMgYnl0ZVtdIGdldEJ5dGVzKFN0cmluZyBzKSB7CisJY2hhciBbXSBjaGFycz0gcy50b0NoYXJBcnJheSgpOworCWludCBzaXplID0gY2hhcnMubGVuZ3RoOworCWJ5dGVbXSBieXRlcyA9IG5ldyBieXRlW3NpemVdOworICAgIAkKKwlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7KQorCSAgICBieXRlc1tpXSA9IChieXRlKSBjaGFyc1tpKytdOworCXJldHVybiBieXRlczsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGJ5dGVbXSBnZXRCeXRlcyhJbnB1dFN0cmVhbSBpcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKworCWludCBsZW47CisJaW50IHNpemUgPSAxMDI0OworCWJ5dGUgW10gYnVmOworCisKKwlpZiAoaXMgaW5zdGFuY2VvZiBCeXRlQXJyYXlJbnB1dFN0cmVhbSkgeworCSAgICBzaXplID0gaXMuYXZhaWxhYmxlKCk7CisJICAgIGJ1ZiA9IG5ldyBieXRlW3NpemVdOworCSAgICBsZW4gPSBpcy5yZWFkKGJ1ZiwgMCwgc2l6ZSk7CisJfQorCWVsc2UgeworCSAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworCSAgICBidWYgPSBuZXcgYnl0ZVtzaXplXTsKKwkgICAgd2hpbGUgKChsZW4gPSBpcy5yZWFkKGJ1ZiwgMCwgc2l6ZSkpICE9IC0xKQorCQlib3Mud3JpdGUoYnVmLCAwLCBsZW4pOworCSAgICBidWYgPSBib3MudG9CeXRlQXJyYXkoKTsKKwl9CisJcmV0dXJuIGJ1ZjsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvQkFTRTY0RGVjb2RlclN0cmVhbS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL0JBU0U2NERlY29kZXJTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMWE4ZWRlCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL0JBU0U2NERlY29kZXJTdHJlYW0uamF2YQpAQCAtMCwwICsxLDQ1NCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwudXRpbDsKKworaW1wb3J0IGphdmEuaW8uKjsKKworLyoqCisgKiBUaGlzIGNsYXNzIGltcGxlbWVudHMgYSBCQVNFNjQgRGVjb2Rlci4gSXQgaXMgaW1wbGVtZW50ZWQgYXMKKyAqIGEgRmlsdGVySW5wdXRTdHJlYW0sIHNvIG9uZSBjYW4ganVzdCB3cmFwIHRoaXMgY2xhc3MgYXJvdW5kCisgKiBhbnkgaW5wdXQgc3RyZWFtIGFuZCByZWFkIGJ5dGVzIGZyb20gdGhpcyBmaWx0ZXIuIFRoZSBkZWNvZGluZworICogaXMgZG9uZSBhcyB0aGUgYnl0ZXMgYXJlIHJlYWQgb3V0LgorICogCisgKiBAYXV0aG9yIEpvaG4gTWFuaQorICogQGF1dGhvciBCaWxsIFNoYW5ub24KKyAqLworCitwdWJsaWMgY2xhc3MgQkFTRTY0RGVjb2RlclN0cmVhbSBleHRlbmRzIEZpbHRlcklucHV0U3RyZWFtIHsKKyAgICAvLyBidWZmZXIgb2YgZGVjb2RlZCBieXRlcyBmb3Igc2luZ2xlIGJ5dGUgcmVhZHMKKyAgICBwcml2YXRlIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVszXTsKKyAgICBwcml2YXRlIGludCBidWZzaXplID0gMDsJLy8gc2l6ZSBvZiB0aGUgY2FjaGUKKyAgICBwcml2YXRlIGludCBpbmRleCA9IDA7CS8vIGluZGV4IGludG8gdGhlIGNhY2hlCisKKyAgICAvLyBidWZmZXIgZm9yIGFsbW9zdCA4SyBvZiB0eXBpY2FsIDc2IGNoYXJzICsgQ1JMRiBsaW5lcywKKyAgICAvLyB1c2VkIGJ5IGdldEJ5dGUgbWV0aG9kLiAgdGhpcyBidWZmZXIgY29udGFpbnMgZW5jb2RlZCBieXRlcy4KKyAgICBwcml2YXRlIGJ5dGVbXSBpbnB1dF9idWZmZXIgPSBuZXcgYnl0ZVs3OCoxMDVdOworICAgIHByaXZhdGUgaW50IGlucHV0X3BvcyA9IDA7CisgICAgcHJpdmF0ZSBpbnQgaW5wdXRfbGVuID0gMDs7CisKKyAgICBwcml2YXRlIGJvb2xlYW4gaWdub3JlRXJyb3JzID0gZmFsc2U7CisKKyAgICAvKiogCisgICAgICogQ3JlYXRlIGEgQkFTRTY0IGRlY29kZXIgdGhhdCBkZWNvZGVzIHRoZSBzcGVjaWZpZWQgaW5wdXQgc3RyZWFtLgorICAgICAqIFRoZSBTeXN0ZW0gcHJvcGVydHkgPGNvZGU+bWFpbC5taW1lLmJhc2U2NC5pZ25vcmVlcnJvcnM8L2NvZGU+CisgICAgICogY29udHJvbHMgd2hldGhlciBlcnJvcnMgaW4gdGhlIGVuY29kZWQgZGF0YSBjYXVzZSBhbiBleGNlcHRpb24KKyAgICAgKiBvciBhcmUgaWdub3JlZC4gIFRoZSBkZWZhdWx0IGlzIGZhbHNlIChlcnJvcnMgY2F1c2UgZXhjZXB0aW9uKS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbgl0aGUgaW5wdXQgc3RyZWFtCisgICAgICovCisgICAgcHVibGljIEJBU0U2NERlY29kZXJTdHJlYW0oSW5wdXRTdHJlYW0gaW4pIHsKKwlzdXBlcihpbik7CisJLy8gZGVmYXVsdCB0byBmYWxzZQorCWlnbm9yZUVycm9ycyA9IFByb3BVdGlsLmdldEJvb2xlYW5TeXN0ZW1Qcm9wZXJ0eSgKKwkgICAgIm1haWwubWltZS5iYXNlNjQuaWdub3JlZXJyb3JzIiwgZmFsc2UpOworICAgIH0KKworICAgIC8qKiAKKyAgICAgKiBDcmVhdGUgYSBCQVNFNjQgZGVjb2RlciB0aGF0IGRlY29kZXMgdGhlIHNwZWNpZmllZCBpbnB1dCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW4JdGhlIGlucHV0IHN0cmVhbQorICAgICAqIEBwYXJhbSBpZ25vcmVFcnJvcnMJaWdub3JlIGVycm9ycyBpbiBlbmNvZGVkIGRhdGE/CisgICAgICovCisgICAgcHVibGljIEJBU0U2NERlY29kZXJTdHJlYW0oSW5wdXRTdHJlYW0gaW4sIGJvb2xlYW4gaWdub3JlRXJyb3JzKSB7CisJc3VwZXIoaW4pOworCXRoaXMuaWdub3JlRXJyb3JzID0gaWdub3JlRXJyb3JzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWQgdGhlIG5leHQgZGVjb2RlZCBieXRlIGZyb20gdGhpcyBpbnB1dCBzdHJlYW0uIFRoZSBieXRlCisgICAgICogaXMgcmV0dXJuZWQgYXMgYW4gPGNvZGU+aW50PC9jb2RlPiBpbiB0aGUgcmFuZ2UgPGNvZGU+MDwvY29kZT4gCisgICAgICogdG8gPGNvZGU+MjU1PC9jb2RlPi4gSWYgbm8gYnl0ZSBpcyBhdmFpbGFibGUgYmVjYXVzZSB0aGUgZW5kIG9mIAorICAgICAqIHRoZSBzdHJlYW0gaGFzIGJlZW4gcmVhY2hlZCwgdGhlIHZhbHVlIDxjb2RlPi0xPC9jb2RlPiBpcyByZXR1cm5lZC4KKyAgICAgKiBUaGlzIG1ldGhvZCBibG9ja3MgdW50aWwgaW5wdXQgZGF0YSBpcyBhdmFpbGFibGUsIHRoZSBlbmQgb2YgdGhlIAorICAgICAqIHN0cmVhbSBpcyBkZXRlY3RlZCwgb3IgYW4gZXhjZXB0aW9uIGlzIHRocm93bi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gICAgIG5leHQgYnl0ZSBvZiBkYXRhLCBvciA8Y29kZT4tMTwvY29kZT4gaWYgdGhlIGVuZCBvZiB0aGUKKyAgICAgKiAgICAgICAgICAgICBzdHJlYW0gaXMgcmVhY2hlZC4KKyAgICAgKiBAZXhjZXB0aW9uICBJT0V4Y2VwdGlvbiAgaWYgYW4gSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKiBAc2VlICAgICAgICBqYXZhLmlvLkZpbHRlcklucHV0U3RyZWFtI2luCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlpZiAoaW5kZXggPj0gYnVmc2l6ZSkgeworCSAgICBidWZzaXplID0gZGVjb2RlKGJ1ZmZlciwgMCwgYnVmZmVyLmxlbmd0aCk7CisJICAgIGlmIChidWZzaXplIDw9IDApIC8vIGJ1ZmZlciBpcyBlbXB0eQorCQlyZXR1cm4gLTE7CisJICAgIGluZGV4ID0gMDsgLy8gcmVzZXQgaW5kZXggaW50byBidWZmZXIKKwl9CisJcmV0dXJuIGJ1ZmZlcltpbmRleCsrXSAmIDB4ZmY7IC8vIFplcm8gb2ZmIHRoZSBNU0IKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyB1cCB0byA8Y29kZT5sZW48L2NvZGU+IGRlY29kZWQgYnl0ZXMgb2YgZGF0YSBmcm9tIHRoaXMgaW5wdXQgc3RyZWFtCisgICAgICogaW50byBhbiBhcnJheSBvZiBieXRlcy4gVGhpcyBtZXRob2QgYmxvY2tzIHVudGlsIHNvbWUgaW5wdXQgaXMKKyAgICAgKiBhdmFpbGFibGUuCisgICAgICogPHA+CisgICAgICoKKyAgICAgKiBAcGFyYW0gICAgICBidWYgICB0aGUgYnVmZmVyIGludG8gd2hpY2ggdGhlIGRhdGEgaXMgcmVhZC4KKyAgICAgKiBAcGFyYW0gICAgICBvZmYgICB0aGUgc3RhcnQgb2Zmc2V0IG9mIHRoZSBkYXRhLgorICAgICAqIEBwYXJhbSAgICAgIGxlbiAgIHRoZSBtYXhpbXVtIG51bWJlciBvZiBieXRlcyByZWFkLgorICAgICAqIEByZXR1cm4gICAgIHRoZSB0b3RhbCBudW1iZXIgb2YgYnl0ZXMgcmVhZCBpbnRvIHRoZSBidWZmZXIsIG9yCisgICAgICogICAgICAgICAgICAgPGNvZGU+LTE8L2NvZGU+IGlmIHRoZXJlIGlzIG5vIG1vcmUgZGF0YSBiZWNhdXNlIHRoZSBlbmQgb2YKKyAgICAgKiAgICAgICAgICAgICB0aGUgc3RyZWFtIGhhcyBiZWVuIHJlYWNoZWQuCisgICAgICogQGV4Y2VwdGlvbiAgSU9FeGNlcHRpb24gIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKGJ5dGVbXSBidWYsIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJLy8gZW1wdHkgb3V0IHNpbmdsZSBieXRlIHJlYWQgYnVmZmVyCisJaW50IG9mZjAgPSBvZmY7CisJd2hpbGUgKGluZGV4IDwgYnVmc2l6ZSAmJiBsZW4gPiAwKSB7CisJICAgIGJ1ZltvZmYrK10gPSBidWZmZXJbaW5kZXgrK107CisJICAgIGxlbi0tOworCX0KKwlpZiAoaW5kZXggPj0gYnVmc2l6ZSkKKwkgICAgYnVmc2l6ZSA9IGluZGV4ID0gMDsKKworCWludCBic2l6ZSA9IChsZW4gLyAzKSAqIDM7CS8vIHJvdW5kIGRvd24gdG8gbXVsdGlwbGUgb2YgMyBieXRlcworCWlmIChic2l6ZSA+IDApIHsKKwkgICAgaW50IHNpemUgPSBkZWNvZGUoYnVmLCBvZmYsIGJzaXplKTsKKwkgICAgb2ZmICs9IHNpemU7CisJICAgIGxlbiAtPSBzaXplOworCisJICAgIGlmIChzaXplICE9IGJzaXplKSB7CS8vIGhpdCBFT0Y/CisJCWlmIChvZmYgPT0gb2ZmMCkJLy8gaGF2ZW4ndCByZXR1cm5lZCBhbnkgZGF0YQorCQkgICAgcmV0dXJuIC0xOworCQllbHNlCQkJLy8gcmV0dXJuZWQgc29tZSBkYXRhIGJlZm9yZSBoaXR0aW5nIEVPRgorCQkgICAgcmV0dXJuIG9mZiAtIG9mZjA7CisJICAgIH0KKwl9CisKKwkvLyBmaW5pc2ggdXAgd2l0aCBhIHBhcnRpYWwgcmVhZCBpZiBuZWNlc3NhcnkKKwlmb3IgKDsgbGVuID4gMDsgbGVuLS0pIHsKKwkgICAgaW50IGMgPSByZWFkKCk7CisJICAgIGlmIChjID09IC0xKQkvLyBFT0YKKwkJYnJlYWs7CisJICAgIGJ1ZltvZmYrK10gPSAoYnl0ZSljOworCX0KKworCWlmIChvZmYgPT0gb2ZmMCkJLy8gaGF2ZW4ndCByZXR1cm5lZCBhbnkgZGF0YQorCSAgICByZXR1cm4gLTE7CisJZWxzZQkJCS8vIHJldHVybmVkIHNvbWUgZGF0YSBiZWZvcmUgaGl0dGluZyBFT0YKKwkgICAgcmV0dXJuIG9mZiAtIG9mZjA7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2tpcHMgb3ZlciBhbmQgZGlzY2FyZHMgbiBieXRlcyBvZiBkYXRhIGZyb20gdGhpcyBzdHJlYW0uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgc2tpcChsb25nIG4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJbG9uZyBza2lwcGVkID0gMDsKKwl3aGlsZSAobi0tID4gMCAmJiByZWFkKCkgPj0gMCkKKwkgICAgc2tpcHBlZCsrOworCXJldHVybiBza2lwcGVkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIGlmIHRoaXMgaW5wdXQgc3RyZWFtIHN1cHBvcnRzIG1hcmtzLiBDdXJyZW50bHkgdGhpcyBjbGFzcworICAgICAqIGRvZXMgbm90IHN1cHBvcnQgbWFya3MKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBtYXJrU3VwcG9ydGVkKCkgeworCXJldHVybiBmYWxzZTsgLy8gTWF5YmUgbGF0ZXIgLi4KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCBjYW4gYmUgcmVhZCBmcm9tIHRoaXMgaW5wdXQKKyAgICAgKiBzdHJlYW0gd2l0aG91dCBibG9ja2luZy4gSG93ZXZlciwgdGhpcyBmaWd1cmUgaXMgb25seQorICAgICAqIGEgY2xvc2UgYXBwcm94aW1hdGlvbiBpbiBjYXNlIHRoZSBvcmlnaW5hbCBlbmNvZGVkIHN0cmVhbQorICAgICAqIGNvbnRhaW5zIGVtYmVkZGVkIENSTEZzOyBzaW5jZSB0aGUgQ1JMRnMgYXJlIGRpc2NhcmRlZCwgbm90IGRlY29kZWQKKyAgICAgKi8gCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBhdmFpbGFibGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCSAvLyBUaGlzIGlzIG9ubHkgYW4gZXN0aW1hdGUsIHNpbmNlIGluLmF2YWlsYWJsZSgpCisJIC8vIG1pZ2h0IGluY2x1ZGUgQ1JMRnMgdG9vIC4uCisJIHJldHVybiAoKGluLmF2YWlsYWJsZSgpICogMykvNCArIChidWZzaXplLWluZGV4KSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBjaGFyYWN0ZXIgYXJyYXkgcHJvdmlkZXMgdGhlIGNoYXJhY3RlciB0byB2YWx1ZSBtYXAKKyAgICAgKiBiYXNlZCBvbiBSRkMxNTIxLgorICAgICAqLyAgCisgICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgY2hhciBwZW1fYXJyYXlbXSA9IHsKKwknQScsJ0InLCdDJywnRCcsJ0UnLCdGJywnRycsJ0gnLCAvLyAwCisJJ0knLCdKJywnSycsJ0wnLCdNJywnTicsJ08nLCdQJywgLy8gMQorCSdRJywnUicsJ1MnLCdUJywnVScsJ1YnLCdXJywnWCcsIC8vIDIKKwknWScsJ1onLCdhJywnYicsJ2MnLCdkJywnZScsJ2YnLCAvLyAzCisJJ2cnLCdoJywnaScsJ2onLCdrJywnbCcsJ20nLCduJywgLy8gNAorCSdvJywncCcsJ3EnLCdyJywncycsJ3QnLCd1JywndicsIC8vIDUKKwkndycsJ3gnLCd5JywneicsJzAnLCcxJywnMicsJzMnLCAvLyA2CisJJzQnLCc1JywnNicsJzcnLCc4JywnOScsJysnLCcvJyAgLy8gNworICAgIH07CisKKyAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBieXRlIHBlbV9jb252ZXJ0X2FycmF5W10gPSBuZXcgYnl0ZVsyNTZdOworCisgICAgc3RhdGljIHsKKwlmb3IgKGludCBpID0gMDsgaSA8IDI1NTsgaSsrKQorCSAgICBwZW1fY29udmVydF9hcnJheVtpXSA9IC0xOworCWZvciAoaW50IGkgPSAwOyBpIDwgcGVtX2FycmF5Lmxlbmd0aDsgaSsrKQorCSAgICBwZW1fY29udmVydF9hcnJheVtwZW1fYXJyYXlbaV1dID0gKGJ5dGUpaTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgZGVjb2RlciBhbGdvcml0aG0uICBNb3N0IG9mIHRoZSBjb21wbGV4aXR5IGhlcmUgaXMgZGVhbGluZworICAgICAqIHdpdGggZXJyb3IgY2FzZXMuICBSZXR1cm5zIHRoZSBudW1iZXIgb2YgYnl0ZXMgZGVjb2RlZCwgd2hpY2gKKyAgICAgKiBtYXkgYmUgemVyby4gIERlY29kaW5nIGlzIGRvbmUgYnkgZmlsbGluZyBhbiBpbnQgd2l0aCA0IDYtYml0CisgICAgICogdmFsdWVzIGJ5IHNoaWZ0aW5nIHRoZW0gaW4gZnJvbSB0aGUgYm90dG9tIGFuZCB0aGVuIGV4dHJhY3RpbmcKKyAgICAgKiAzIDgtYml0IGJ5dGVzIGZyb20gdGhlIGludCBieSBzaGlmdGluZyB0aGVtIG91dCBmcm9tIHRoZSBib3R0b20uCisgICAgICoKKyAgICAgKiBAcGFyYW0Jb3V0YnVmCXRoZSBidWZmZXIgaW50byB3aGljaCB0byBwdXQgdGhlIGRlY29kZWQgYnl0ZXMKKyAgICAgKiBAcGFyYW0JcG9zCXBvc2l0aW9uIGluIHRoZSBidWZmZXIgdG8gc3RhcnQgZmlsbGluZworICAgICAqIEBwYXJhbQlsZW4JdGhlIG51bWJlciBvZiBieXRlcyB0byBmaWxsCisgICAgICogQHJldHVybgkJdGhlIG51bWJlciBvZiBieXRlcyBmaWxsZWQsIGFsd2F5cyBhIG11bHRpcGxlCisgICAgICoJCQlvZiB0aHJlZSwgYW5kIG1heSBiZSB6ZXJvCisgICAgICogQGV4Y2VwdGlvbglJT0V4Y2VwdGlvbglpZiB0aGUgZGF0YSBpcyBpbmNvcnJlY3RseSBmb3JtYXR0ZWQKKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBkZWNvZGUoYnl0ZVtdIG91dGJ1ZiwgaW50IHBvcywgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlpbnQgcG9zMCA9IHBvczsKKwl3aGlsZSAobGVuID49IDMpIHsKKwkgICAgLyoKKwkgICAgICogV2UgbmVlZCA0IHZhbGlkIGJhc2U2NCBjaGFyYWN0ZXJzIGJlZm9yZSB3ZSBzdGFydCBkZWNvZGluZy4KKwkgICAgICogV2Ugc2tpcCBhbnl0aGluZyB0aGF0J3Mgbm90IGEgdmFsaWQgYmFzZTY0IGNoYXJhY3RlciAodXN1YWxseQorCSAgICAgKiBqdXN0IENSTEYpLgorCSAgICAgKi8KKwkgICAgaW50IGdvdCA9IDA7CisJICAgIGludCB2YWwgPSAwOworCSAgICB3aGlsZSAoZ290IDwgNCkgeworCQlpbnQgaSA9IGdldEJ5dGUoKTsKKwkJaWYgKGkgPT0gLTEgfHwgaSA9PSAtMikgeworCQkgICAgYm9vbGVhbiBhdEVPRjsKKwkJICAgIGlmIChpID09IC0xKSB7CisJCQlpZiAoZ290ID09IDApCisJCQkgICAgcmV0dXJuIHBvcyAtIHBvczA7CisJCQlpZiAoIWlnbm9yZUVycm9ycykKKwkJCSAgICB0aHJvdyBuZXcgRGVjb2RpbmdFeGNlcHRpb24oCisJCQkJIkJBU0U2NERlY29kZXI6IEVycm9yIGluIGVuY29kZWQgc3RyZWFtOiAiICsKKwkJCQkibmVlZGVkIDQgdmFsaWQgYmFzZTY0IGNoYXJhY3RlcnMgIiArCisJCQkJImJ1dCBvbmx5IGdvdCAiICsgZ290ICsgIiBiZWZvcmUgRU9GIiArCisJCQkJcmVjZW50Q2hhcnMoKSk7CisJCQlhdEVPRiA9IHRydWU7CS8vIGRvbid0IHJlYWQgYW55IG1vcmUKKwkJICAgIH0gZWxzZSB7CS8vIGkgPT0gLTIKKwkJCS8vIGZvdW5kIGEgcGFkZGluZyBjaGFyYWN0ZXIsIHdlJ3JlIGF0IEVPRgorCQkJLy8gWFhYIC0gc2hvdWxkIGRvIHNvbWV0aGluZyB0byBtYWtlIEVPRiAic3RpY2t5IgorCQkJaWYgKGdvdCA8IDIgJiYgIWlnbm9yZUVycm9ycykKKwkJCSAgICB0aHJvdyBuZXcgRGVjb2RpbmdFeGNlcHRpb24oCisJCQkJIkJBU0U2NERlY29kZXI6IEVycm9yIGluIGVuY29kZWQgc3RyZWFtOiAiICsKKwkJCQkibmVlZGVkIGF0IGxlYXN0IDIgdmFsaWQgYmFzZTY0IGNoYXJhY3RlcnMsIiArCisJCQkJIiBidXQgb25seSBnb3QgIiArIGdvdCArCisJCQkJIiBiZWZvcmUgcGFkZGluZyBjaGFyYWN0ZXIgKD0pIiArCisJCQkJcmVjZW50Q2hhcnMoKSk7CisKKwkJCS8vIGRpZG4ndCBnZXQgYW55IGNoYXJhY3RlcnMgYmVmb3JlIHBhZGRpbmcgY2hhcmFjdGVyPworCQkJaWYgKGdvdCA9PSAwKQorCQkJICAgIHJldHVybiBwb3MgLSBwb3MwOworCQkJYXRFT0YgPSBmYWxzZTsJLy8gbmVlZCB0byBrZWVwIHJlYWRpbmcKKwkJICAgIH0KKworCQkgICAgLy8gcGFkIHBhcnRpYWwgcmVzdWx0IHdpdGggemVyb2VzCisKKwkJICAgIC8vIGhvdyBtYW55IGJ5dGVzIHdpbGwgd2UgcHJvZHVjZSBvbiBvdXRwdXQ/CisJCSAgICAvLyAoZ290IGFsd2F5cyA8IDQsIHNvIHNpemUgYWx3YXlzIDwgMykKKwkJICAgIGludCBzaXplID0gZ290IC0gMTsKKwkJICAgIGlmIChzaXplID09IDApCisJCQlzaXplID0gMTsKKworCQkgICAgLy8gaGFuZGxlIHRoZSBvbmUgcGFkZGluZyBjaGFyYWN0ZXIgd2UndmUgc2VlbgorCQkgICAgZ290Kys7CisJCSAgICB2YWwgPDw9IDY7CisKKwkJICAgIHdoaWxlIChnb3QgPCA0KSB7CisJCQlpZiAoIWF0RU9GKSB7CisJCQkgICAgLy8gY29uc3VtZSB0aGUgcmVzdCBvZiB0aGUgcGFkZGluZyBjaGFyYWN0ZXJzLAorCQkJICAgIC8vIGZpbGxpbmcgd2l0aCB6ZXJvZXMKKwkJCSAgICBpID0gZ2V0Qnl0ZSgpOworCQkJICAgIGlmIChpID09IC0xKSB7CisJCQkJaWYgKCFpZ25vcmVFcnJvcnMpCisJCQkJICAgIHRocm93IG5ldyBEZWNvZGluZ0V4Y2VwdGlvbigKKwkJCQkJIkJBU0U2NERlY29kZXI6IEVycm9yIGluIGVuY29kZWQgIiArCisJCQkJCSJzdHJlYW06IGhpdCBFT0Ygd2hpbGUgbG9va2luZyBmb3IgIiArCisJCQkJCSJwYWRkaW5nIGNoYXJhY3RlcnMgKD0pIiArCisJCQkJCXJlY2VudENoYXJzKCkpOworCQkJICAgIH0gZWxzZSBpZiAoaSAhPSAtMikgeworCQkJCWlmICghaWdub3JlRXJyb3JzKQorCQkJCSAgICB0aHJvdyBuZXcgRGVjb2RpbmdFeGNlcHRpb24oCisJCQkJCSJCQVNFNjREZWNvZGVyOiBFcnJvciBpbiBlbmNvZGVkICIgKworCQkJCQkic3RyZWFtOiBmb3VuZCB2YWxpZCBiYXNlNjQgIiArCisJCQkJCSJjaGFyYWN0ZXIgYWZ0ZXIgYSBwYWRkaW5nIGNoYXJhY3RlciAiICsKKwkJCQkJIig9KSIgKyByZWNlbnRDaGFycygpKTsKKwkJCSAgICB9CisJCQl9CisJCQl2YWwgPDw9IDY7CisJCQlnb3QrKzsKKwkJICAgIH0KKworCQkgICAgLy8gbm93IHB1bGwgb3V0IGhvd2V2ZXIgbWFueSB2YWxpZCBieXRlcyB3ZSBnb3QKKwkJICAgIHZhbCA+Pj0gODsJCS8vIGFsd2F5cyBza2lwIGZpcnN0IG9uZQorCQkgICAgaWYgKHNpemUgPT0gMikKKwkJCW91dGJ1Zltwb3MgKyAxXSA9IChieXRlKSh2YWwgJiAweGZmKTsKKwkJICAgIHZhbCA+Pj0gODsKKwkJICAgIG91dGJ1Zltwb3NdID0gKGJ5dGUpKHZhbCAmIDB4ZmYpOworCQkgICAgLy8gbGVuIC09IHNpemU7CS8vIG5vdCBuZWVkZWQsIHJldHVybiBiZWxvdworCQkgICAgcG9zICs9IHNpemU7CisJCSAgICByZXR1cm4gcG9zIC0gcG9zMDsKKwkJfSBlbHNlIHsKKwkJICAgIC8vIGdvdCBhIHZhbGlkIGJ5dGUKKwkJICAgIHZhbCA8PD0gNjsKKwkJICAgIGdvdCsrOworCQkgICAgdmFsIHw9IGk7CisJCX0KKwkgICAgfQorCisJICAgIC8vIHJlYWQgNCB2YWxpZCBjaGFyYWN0ZXJzLCBub3cgZXh0cmFjdCAzIGJ5dGVzCisJICAgIG91dGJ1Zltwb3MgKyAyXSA9IChieXRlKSh2YWwgJiAweGZmKTsKKwkgICAgdmFsID4+PSA4OworCSAgICBvdXRidWZbcG9zICsgMV0gPSAoYnl0ZSkodmFsICYgMHhmZik7CisJICAgIHZhbCA+Pj0gODsKKwkgICAgb3V0YnVmW3Bvc10gPSAoYnl0ZSkodmFsICYgMHhmZik7CisJICAgIGxlbiAtPSAzOworCSAgICBwb3MgKz0gMzsKKwl9CisJcmV0dXJuIHBvcyAtIHBvczA7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZCB0aGUgbmV4dCB2YWxpZCBieXRlIGZyb20gdGhlIGlucHV0IHN0cmVhbS4KKyAgICAgKiBCdWZmZXIgbG90cyBvZiBkYXRhIGZyb20gdW5kZXJseWluZyBzdHJlYW0gaW4gaW5wdXRfYnVmZmVyLAorICAgICAqIGZvciBlZmZpY2llbmN5LgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgbmV4dCBieXRlLCAtMSBvbiBFT0YsIG9yIC0yIGlmIG5leHQgYnl0ZSBpcyAnPScKKyAgICAgKgkJKHBhZGRpbmcgYXQgZW5kIG9mIGVuY29kZWQgZGF0YSkKKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBnZXRCeXRlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlpbnQgYzsKKwlkbyB7CisJICAgIGlmIChpbnB1dF9wb3MgPj0gaW5wdXRfbGVuKSB7CisJCXRyeSB7CisJCSAgICBpbnB1dF9sZW4gPSBpbi5yZWFkKGlucHV0X2J1ZmZlcik7CisJCX0gY2F0Y2ggKEVPRkV4Y2VwdGlvbiBleCkgeworCQkgICAgcmV0dXJuIC0xOworCQl9CisJCWlmIChpbnB1dF9sZW4gPD0gMCkKKwkJICAgIHJldHVybiAtMTsKKwkJaW5wdXRfcG9zID0gMDsKKwkgICAgfQorCSAgICAvLyBnZXQgdGhlIG5leHQgYnl0ZSBpbiB0aGUgYnVmZmVyCisJICAgIGMgPSBpbnB1dF9idWZmZXJbaW5wdXRfcG9zKytdICYgMHhmZjsKKwkgICAgLy8gaXMgaXQgYSBwYWRkaW5nIGJ5dGU/CisJICAgIGlmIChjID09ICc9JykKKwkJcmV0dXJuIC0yOworCSAgICAvLyBubywgY29udmVydCBpdAorCSAgICBjID0gcGVtX2NvbnZlcnRfYXJyYXlbY107CisJICAgIC8vIGxvb3AgdW50aWwgd2UgZ2V0IGEgbGVnaXRpbWF0ZSBieXRlCisJfSB3aGlsZSAoYyA9PSAtMSk7CisJcmV0dXJuIGM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBtb3N0IHJlY2VudCBjaGFyYWN0ZXJzLCBmb3IgdXNlIGluIGFuIGVycm9yIG1lc3NhZ2UuCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgcmVjZW50Q2hhcnMoKSB7CisJLy8gcmVhY2ggaW50byB0aGUgaW5wdXQgYnVmZmVyIGFuZCBleHRyYWN0IHVwIHRvIDEwCisJLy8gcmVjZW50IGNoYXJhY3RlcnMsIHRvIGhlbHAgaW4gZGVidWdnaW5nLgorCVN0cmluZyBlcnJzdHIgPSAiIjsKKwlpbnQgbmMgPSBpbnB1dF9wb3MgPiAxMCA/IDEwIDogaW5wdXRfcG9zOworCWlmIChuYyA+IDApIHsKKwkgICAgZXJyc3RyICs9ICIsIHRoZSAiICsgbmMgKworCQkJICAgICIgbW9zdCByZWNlbnQgY2hhcmFjdGVycyB3ZXJlOiBcIiI7CisJICAgIGZvciAoaW50IGsgPSBpbnB1dF9wb3MgLSBuYzsgayA8IGlucHV0X3BvczsgaysrKSB7CisJCWNoYXIgYyA9IChjaGFyKShpbnB1dF9idWZmZXJba10gJiAweGZmKTsKKwkJc3dpdGNoIChjKSB7CisJCWNhc2UgJ1xyJzoJZXJyc3RyICs9ICJcXHIiOyBicmVhazsKKwkJY2FzZSAnXG4nOgllcnJzdHIgKz0gIlxcbiI7IGJyZWFrOworCQljYXNlICdcdCc6CWVycnN0ciArPSAiXFx0IjsgYnJlYWs7CisJCWRlZmF1bHQ6CisJCSAgICBpZiAoYyA+PSAnICcgJiYgYyA8IDAxNzcpCisJCQllcnJzdHIgKz0gYzsKKwkJICAgIGVsc2UKKwkJCWVycnN0ciArPSAoIlxcIiArIChpbnQpYyk7CisJCX0KKwkgICAgfQorCSAgICBlcnJzdHIgKz0gIlwiIjsKKwl9CisJcmV0dXJuIGVycnN0cjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBCYXNlNjQgZGVjb2RlIGEgYnl0ZSBhcnJheS4gIE5vIGxpbmUgYnJlYWtzIGFyZSBhbGxvd2VkLgorICAgICAqIFRoaXMgbWV0aG9kIGlzIHN1aXRhYmxlIGZvciBzaG9ydCBzdHJpbmdzLCBzdWNoIGFzIHRob3NlCisgICAgICogaW4gdGhlIElNQVAgQVVUSEVOVElDQVRFIHByb3RvY29sLCBidXQgbm90IHRvIGRlY29kZSB0aGUKKyAgICAgKiBlbnRpcmUgY29udGVudCBvZiBhIE1JTUUgcGFydC4KKyAgICAgKgorICAgICAqIE5PVEU6IGluYnVmIG1heSBvbmx5IGNvbnRhaW4gdmFsaWQgYmFzZTY0IGNoYXJhY3RlcnMuCisgICAgICogICAgICAgV2hpdGVzcGFjZSBpcyBub3QgaWdub3JlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbQlpbmJ1Zgl0aGUgYnl0ZSBhcnJheQorICAgICAqIEByZXR1cm4JCXRoZSBkZWNvZGVkIGJ5dGUgYXJyYXkKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJ5dGVbXSBkZWNvZGUoYnl0ZVtdIGluYnVmKSB7CisJaW50IHNpemUgPSAoaW5idWYubGVuZ3RoIC8gNCkgKiAzOworCWlmIChzaXplID09IDApCisJICAgIHJldHVybiBpbmJ1ZjsKKworCWlmIChpbmJ1ZltpbmJ1Zi5sZW5ndGggLSAxXSA9PSAnPScpIHsKKwkgICAgc2l6ZS0tOworCSAgICBpZiAoaW5idWZbaW5idWYubGVuZ3RoIC0gMl0gPT0gJz0nKQorCQlzaXplLS07CisJfQorCWJ5dGVbXSBvdXRidWYgPSBuZXcgYnl0ZVtzaXplXTsKKworCWludCBpbnBvcyA9IDAsIG91dHBvcyA9IDA7CisJc2l6ZSA9IGluYnVmLmxlbmd0aDsKKwl3aGlsZSAoc2l6ZSA+IDApIHsKKwkgICAgaW50IHZhbDsKKwkgICAgaW50IG9zaXplID0gMzsKKwkgICAgdmFsID0gcGVtX2NvbnZlcnRfYXJyYXlbaW5idWZbaW5wb3MrK10gJiAweGZmXTsKKwkgICAgdmFsIDw8PSA2OworCSAgICB2YWwgfD0gcGVtX2NvbnZlcnRfYXJyYXlbaW5idWZbaW5wb3MrK10gJiAweGZmXTsKKwkgICAgdmFsIDw8PSA2OworCSAgICBpZiAoaW5idWZbaW5wb3NdICE9ICc9JykgLy8gRW5kIG9mIHRoaXMgQkFTRTY0IGVuY29kaW5nCisJCXZhbCB8PSBwZW1fY29udmVydF9hcnJheVtpbmJ1ZltpbnBvcysrXSAmIDB4ZmZdOworCSAgICBlbHNlCisJCW9zaXplLS07CisJICAgIHZhbCA8PD0gNjsKKwkgICAgaWYgKGluYnVmW2lucG9zXSAhPSAnPScpIC8vIEVuZCBvZiB0aGlzIEJBU0U2NCBlbmNvZGluZworCQl2YWwgfD0gcGVtX2NvbnZlcnRfYXJyYXlbaW5idWZbaW5wb3MrK10gJiAweGZmXTsKKwkgICAgZWxzZQorCQlvc2l6ZS0tOworCSAgICBpZiAob3NpemUgPiAyKQorCQlvdXRidWZbb3V0cG9zICsgMl0gPSAoYnl0ZSkodmFsICYgMHhmZik7CisJICAgIHZhbCA+Pj0gODsKKwkgICAgaWYgKG9zaXplID4gMSkKKwkJb3V0YnVmW291dHBvcyArIDFdID0gKGJ5dGUpKHZhbCAmIDB4ZmYpOworCSAgICB2YWwgPj49IDg7CisJICAgIG91dGJ1ZltvdXRwb3NdID0gKGJ5dGUpKHZhbCAmIDB4ZmYpOworCSAgICBvdXRwb3MgKz0gb3NpemU7CisJICAgIHNpemUgLT0gNDsKKwl9CisJcmV0dXJuIG91dGJ1ZjsKKyAgICB9CisKKyAgICAvKioqIGJlZ2luIFRFU1QgcHJvZ3JhbSAqKioKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmcgYXJndltdKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAJRmlsZUlucHV0U3RyZWFtIGluZmlsZSA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oYXJndlswXSk7CisJQkFTRTY0RGVjb2RlclN0cmVhbSBkZWNvZGVyID0gbmV3IEJBU0U2NERlY29kZXJTdHJlYW0oaW5maWxlKTsKKwlpbnQgYzsKKworCXdoaWxlICgoYyA9IGRlY29kZXIucmVhZCgpKSAhPSAtMSkKKwkgICAgU3lzdGVtLm91dC5wcmludCgoY2hhciljKTsKKwlTeXN0ZW0ub3V0LmZsdXNoKCk7CisgICAgfQorICAgICoqKiBlbmQgVEVTVCBwcm9ncmFtICoqKi8KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvdXRpbC9CQVNFNjRFbmNvZGVyU3RyZWFtLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvQkFTRTY0RW5jb2RlclN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAzNmI1MzQKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvQkFTRTY0RW5jb2RlclN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsMzA2IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC51dGlsOworCitpbXBvcnQgamF2YS5pby4qOworCisvKioKKyAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyBhIEJBU0U2NCBlbmNvZGVyLiAgSXQgaXMgaW1wbGVtZW50ZWQgYXMKKyAqIGEgRmlsdGVyT3V0cHV0U3RyZWFtLCBzbyBvbmUgY2FuIGp1c3Qgd3JhcCB0aGlzIGNsYXNzIGFyb3VuZAorICogYW55IG91dHB1dCBzdHJlYW0gYW5kIHdyaXRlIGJ5dGVzIGludG8gdGhpcyBmaWx0ZXIuICBUaGUgZW5jb2RpbmcKKyAqIGlzIGRvbmUgYXMgdGhlIGJ5dGVzIGFyZSB3cml0dGVuIG91dC4KKyAqIAorICogQGF1dGhvciBKb2huIE1hbmkKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKi8KKworcHVibGljIGNsYXNzIEJBU0U2NEVuY29kZXJTdHJlYW0gZXh0ZW5kcyBGaWx0ZXJPdXRwdXRTdHJlYW0geworICAgIHByaXZhdGUgYnl0ZVtdIGJ1ZmZlcjsgCS8vIGNhY2hlIG9mIGJ5dGVzIHRoYXQgYXJlIHlldCB0byBiZSBlbmNvZGVkCisgICAgcHJpdmF0ZSBpbnQgYnVmc2l6ZSA9IDA7CS8vIHNpemUgb2YgdGhlIGNhY2hlCisgICAgcHJpdmF0ZSBieXRlW10gb3V0YnVmOyAJLy8gbGluZSBzaXplIG91dHB1dCBidWZmZXIKKyAgICBwcml2YXRlIGludCBjb3VudCA9IDA7IAkvLyBudW1iZXIgb2YgYnl0ZXMgdGhhdCBoYXZlIGJlZW4gb3V0cHV0CisgICAgcHJpdmF0ZSBpbnQgYnl0ZXNQZXJMaW5lOwkvLyBudW1iZXIgb2YgYnl0ZXMgcGVyIGxpbmUKKyAgICBwcml2YXRlIGludCBsaW5lTGltaXQ7CS8vIG51bWJlciBvZiBpbnB1dCBieXRlcyB0byBvdXRwdXQgYnl0ZXNQZXJMaW5lCisgICAgcHJpdmF0ZSBib29sZWFuIG5vQ1JMRiA9IGZhbHNlOworCisgICAgcHJpdmF0ZSBzdGF0aWMgYnl0ZVtdIG5ld2xpbmUgPSBuZXcgYnl0ZVtdIHsgJ1xyJywgJ1xuJyB9OworCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgQkFTRTY0IGVuY29kZXIgdGhhdCBlbmNvZGVzIHRoZSBzcGVjaWZpZWQgb3V0cHV0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvdXQgICAgICAgIHRoZSBvdXRwdXQgc3RyZWFtCisgICAgICogQHBhcmFtIGJ5dGVzUGVyTGluZSAgbnVtYmVyIG9mIGJ5dGVzIHBlciBsaW5lLiBUaGUgZW5jb2RlciBpbnNlcnRzCisgICAgICogCQkJYSBDUkxGIHNlcXVlbmNlIGFmdGVyIHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIGJ5dGVzLAorICAgICAqCQkJdW5sZXNzIGJ5dGVzUGVyTGluZSBpcyBJbnRlZ2VyLk1BWF9WQUxVRSwgaW4gd2hpY2gKKyAgICAgKgkJCWNhc2Ugbm8gQ1JMRiBpcyBpbnNlcnRlZC4gIGJ5dGVzUGVyTGluZSBpcyByb3VuZGVkCisgICAgICoJCQlkb3duIHRvIGEgbXVsdGlwbGUgb2YgNC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQkFTRTY0RW5jb2RlclN0cmVhbShPdXRwdXRTdHJlYW0gb3V0LCBpbnQgYnl0ZXNQZXJMaW5lKSB7CisJc3VwZXIob3V0KTsKKwlidWZmZXIgPSBuZXcgYnl0ZVszXTsKKwlpZiAoYnl0ZXNQZXJMaW5lID09IEludGVnZXIuTUFYX1ZBTFVFIHx8IGJ5dGVzUGVyTGluZSA8IDQpIHsKKwkgICAgbm9DUkxGID0gdHJ1ZTsKKwkgICAgYnl0ZXNQZXJMaW5lID0gNzY7CisJfQorCWJ5dGVzUGVyTGluZSA9IChieXRlc1BlckxpbmUgLyA0KSAqIDQ7CS8vIFJvdW5kZWQgZG93biB0byA0bgorCXRoaXMuYnl0ZXNQZXJMaW5lID0gYnl0ZXNQZXJMaW5lOwkvLyBzYXZlIGl0CisgICAgICAgIGxpbmVMaW1pdCA9IGJ5dGVzUGVyTGluZSAvIDQgKiAzOworCisJaWYgKG5vQ1JMRikgeworCSAgICBvdXRidWYgPSBuZXcgYnl0ZVtieXRlc1BlckxpbmVdOworCX0gZWxzZSB7CisJICAgIG91dGJ1ZiA9IG5ldyBieXRlW2J5dGVzUGVyTGluZSArIDJdOworCSAgICBvdXRidWZbYnl0ZXNQZXJMaW5lXSA9IChieXRlKSdccic7CisJICAgIG91dGJ1ZltieXRlc1BlckxpbmUgKyAxXSA9IChieXRlKSdcbic7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIEJBU0U2NCBlbmNvZGVyIHRoYXQgZW5jb2RlcyB0aGUgc3BlY2lmaWVkIGlucHV0IHN0cmVhbS4KKyAgICAgKiBJbnNlcnRzIHRoZSBDUkxGIHNlcXVlbmNlIGFmdGVyIG91dHB1dHRpbmcgNzYgYnl0ZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gb3V0ICAgICAgICB0aGUgb3V0cHV0IHN0cmVhbQorICAgICAqLworICAgIHB1YmxpYyBCQVNFNjRFbmNvZGVyU3RyZWFtKE91dHB1dFN0cmVhbSBvdXQpIHsKKwl0aGlzKG91dCwgNzYpOwkKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFbmNvZGVzIDxjb2RlPmxlbjwvY29kZT4gYnl0ZXMgZnJvbSB0aGUgc3BlY2lmaWVkCisgICAgICogPGNvZGU+Ynl0ZTwvY29kZT4gYXJyYXkgc3RhcnRpbmcgYXQgb2Zmc2V0IDxjb2RlPm9mZjwvY29kZT4gdG8KKyAgICAgKiB0aGlzIG91dHB1dCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gICAgICBiICAgICB0aGUgZGF0YS4KKyAgICAgKiBAcGFyYW0gICAgICBvZmYgICB0aGUgc3RhcnQgb2Zmc2V0IGluIHRoZSBkYXRhLgorICAgICAqIEBwYXJhbSAgICAgIGxlbiAgIHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gd3JpdGUuCisgICAgICogQGV4Y2VwdGlvbiAgSU9FeGNlcHRpb24gIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHdyaXRlKGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuKQorCQkJCXRocm93cyBJT0V4Y2VwdGlvbiB7CisJaW50IGVuZCA9IG9mZiArIGxlbjsKKworCS8vIGZpbmlzaCBvZmYgaW5jb21wbGV0ZSBjb2RpbmcgdW5pdAorCXdoaWxlIChidWZzaXplICE9IDAgJiYgb2ZmIDwgZW5kKQorCSAgICB3cml0ZShiW29mZisrXSk7CisKKwkvLyBmaW5pc2ggb2ZmIGxpbmUKKwlpbnQgYmxlbiA9ICgoYnl0ZXNQZXJMaW5lIC0gY291bnQpIC8gNCkgKiAzOworCWlmIChvZmYgKyBibGVuIDw9IGVuZCkgeworCSAgICAvLyBudW1iZXIgb2YgYnl0ZXMgdGhhdCB3aWxsIGJlIHByb2R1Y2VkIGluIG91dGJ1ZgorCSAgICBpbnQgb3V0bGVuID0gZW5jb2RlZFNpemUoYmxlbik7CisJICAgIGlmICghbm9DUkxGKSB7CisJCW91dGJ1ZltvdXRsZW4rK10gPSAoYnl0ZSknXHInOworCQlvdXRidWZbb3V0bGVuKytdID0gKGJ5dGUpJ1xuJzsKKwkgICAgfQorCSAgICBvdXQud3JpdGUoZW5jb2RlKGIsIG9mZiwgYmxlbiwgb3V0YnVmKSwgMCwgb3V0bGVuKTsKKwkgICAgb2ZmICs9IGJsZW47CisJICAgIGNvdW50ID0gMDsKKwl9CisKKwkvLyBkbyBidWxrIGVuY29kaW5nIGEgbGluZSBhdCBhIHRpbWUuCisJZm9yICg7IG9mZiArIGxpbmVMaW1pdCA8PSBlbmQ7IG9mZiArPSBsaW5lTGltaXQpCisJICAgIG91dC53cml0ZShlbmNvZGUoYiwgb2ZmLCBsaW5lTGltaXQsIG91dGJ1ZikpOworCisJLy8gaGFuZGxlIHJlbWFpbmluZyBwYXJ0aWFsIGxpbmUKKwlpZiAob2ZmICsgMyA8PSBlbmQpIHsKKwkgICAgYmxlbiA9IGVuZCAtIG9mZjsKKwkgICAgYmxlbiA9IChibGVuIC8gMykgKiAzOwkvLyByb3VuZCBkb3duCisJICAgIC8vIG51bWJlciBvZiBieXRlcyB0aGF0IHdpbGwgYmUgcHJvZHVjZWQgaW4gb3V0YnVmCisJICAgIGludCBvdXRsZW4gPSBlbmNvZGVkU2l6ZShibGVuKTsKKwkgICAgb3V0LndyaXRlKGVuY29kZShiLCBvZmYsIGJsZW4sIG91dGJ1ZiksIDAsIG91dGxlbik7CisJICAgIG9mZiArPSBibGVuOworCSAgICBjb3VudCArPSBvdXRsZW47CisJfQorCisJLy8gc3RhcnQgbmV4dCBjb2RpbmcgdW5pdAorCWZvciAoOyBvZmYgPCBlbmQ7IG9mZisrKQorCSAgICB3cml0ZShiW29mZl0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVuY29kZXMgPGNvZGU+Yi5sZW5ndGg8L2NvZGU+IGJ5dGVzIHRvIHRoaXMgb3V0cHV0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbSAgICAgIGIgICB0aGUgZGF0YSB0byBiZSB3cml0dGVuLgorICAgICAqIEBleGNlcHRpb24gIElPRXhjZXB0aW9uICBpZiBhbiBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGJ5dGVbXSBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworCXdyaXRlKGIsIDAsIGIubGVuZ3RoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgPGNvZGU+Ynl0ZTwvY29kZT4gdG8gdGhpcyBvdXRwdXQgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtICAgICAgYyAgIHRoZSA8Y29kZT5ieXRlPC9jb2RlPi4KKyAgICAgKiBAZXhjZXB0aW9uICBJT0V4Y2VwdGlvbiAgaWYgYW4gSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgd3JpdGUoaW50IGMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJYnVmZmVyW2J1ZnNpemUrK10gPSAoYnl0ZSljOworCWlmIChidWZzaXplID09IDMpIHsgLy8gRW5jb2RpbmcgdW5pdCA9IDMgYnl0ZXMKKwkgICAgZW5jb2RlKCk7CisJICAgIGJ1ZnNpemUgPSAwOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGbHVzaGVzIHRoaXMgb3V0cHV0IHN0cmVhbSBhbmQgZm9yY2VzIGFueSBidWZmZXJlZCBvdXRwdXQgYnl0ZXMKKyAgICAgKiB0byBiZSBlbmNvZGVkIG91dCB0byB0aGUgc3RyZWFtLiAKKyAgICAgKgorICAgICAqIEBleGNlcHRpb24gIElPRXhjZXB0aW9uICBpZiBhbiBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBmbHVzaCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJaWYgKGJ1ZnNpemUgPiAwKSB7IC8vIElmIHRoZXJlJ3MgdW5lbmNvZGVkIGNoYXJhY3RlcnMgaW4gdGhlIGJ1ZmZlciAuLgorCSAgICBlbmNvZGUoKTsgICAgICAvLyAuLiBlbmNvZGUgdGhlbQorCSAgICBidWZzaXplID0gMDsKKwl9CisJb3V0LmZsdXNoKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRm9yY2VzIGFueSBidWZmZXJlZCBvdXRwdXQgYnl0ZXMgdG8gYmUgZW5jb2RlZCBvdXQgdG8gdGhlIHN0cmVhbQorICAgICAqIGFuZCBjbG9zZXMgdGhpcyBvdXRwdXQgc3RyZWFtCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlmbHVzaCgpOworCWlmIChjb3VudCA+IDAgJiYgIW5vQ1JMRikgeworCSAgICBvdXQud3JpdGUobmV3bGluZSk7CisJICAgIG91dC5mbHVzaCgpOworCX0KKwlvdXQuY2xvc2UoKTsKKyAgICB9CisKKyAgICAvKiogVGhpcyBhcnJheSBtYXBzIHRoZSBjaGFyYWN0ZXJzIHRvIHRoZWlyIDYgYml0IHZhbHVlcyAqLworICAgIHByaXZhdGUgZmluYWwgc3RhdGljIGNoYXIgcGVtX2FycmF5W10gPSB7CisJJ0EnLCdCJywnQycsJ0QnLCdFJywnRicsJ0cnLCdIJywgLy8gMAorCSdJJywnSicsJ0snLCdMJywnTScsJ04nLCdPJywnUCcsIC8vIDEKKwknUScsJ1InLCdTJywnVCcsJ1UnLCdWJywnVycsJ1gnLCAvLyAyCisJJ1knLCdaJywnYScsJ2InLCdjJywnZCcsJ2UnLCdmJywgLy8gMworCSdnJywnaCcsJ2knLCdqJywnaycsJ2wnLCdtJywnbicsIC8vIDQKKwknbycsJ3AnLCdxJywncicsJ3MnLCd0JywndScsJ3YnLCAvLyA1CisJJ3cnLCd4JywneScsJ3onLCcwJywnMScsJzInLCczJywgLy8gNgorCSc0JywnNScsJzYnLCc3JywnOCcsJzknLCcrJywnLycgIC8vIDcKKyAgICB9OworCisgICAgLyoqCisgICAgICogRW5jb2RlIHRoZSBkYXRhIHN0b3JlZCBpbiA8Y29kZT5idWZmZXI8L2NvZGU+LgorICAgICAqIFVzZXMgPGNvZGU+b3V0YnVmPC9jb2RlPiB0byBzdG9yZSB0aGUgZW5jb2RlZAorICAgICAqIGRhdGEgYmVmb3JlIHdyaXRpbmcuCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uICBJT0V4Y2VwdGlvbiAgaWYgYW4gSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgZW5jb2RlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlpbnQgb3NpemUgPSBlbmNvZGVkU2l6ZShidWZzaXplKTsKKwlvdXQud3JpdGUoZW5jb2RlKGJ1ZmZlciwgMCwgYnVmc2l6ZSwgb3V0YnVmKSwgMCwgb3NpemUpOworCS8vIGluY3JlbWVudCBjb3VudAorCWNvdW50ICs9IG9zaXplOworCS8vIElmIHdyaXRpbmcgb3V0IHRoaXMgZW5jb2RlZCB1bml0IGNhdXNlZCBvdmVyZmxvdywKKwkvLyBzdGFydCBhIG5ldyBsaW5lLgorCWlmIChjb3VudCA+PSBieXRlc1BlckxpbmUpIHsKKwkgICAgaWYgKCFub0NSTEYpCisJCW91dC53cml0ZShuZXdsaW5lKTsKKwkgICAgY291bnQgPSAwOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBCYXNlNjQgZW5jb2RlIGEgYnl0ZSBhcnJheS4gIE5vIGxpbmUgYnJlYWtzIGFyZSBpbnNlcnRlZC4KKyAgICAgKiBUaGlzIG1ldGhvZCBpcyBzdWl0YWJsZSBmb3Igc2hvcnQgc3RyaW5ncywgc3VjaCBhcyB0aG9zZQorICAgICAqIGluIHRoZSBJTUFQIEFVVEhFTlRJQ0FURSBwcm90b2NvbCwgYnV0IG5vdCB0byBlbmNvZGUgdGhlCisgICAgICogZW50aXJlIGNvbnRlbnQgb2YgYSBNSU1FIHBhcnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0JaW5idWYJdGhlIGJ5dGUgYXJyYXkKKyAgICAgKiBAcmV0dXJuCQl0aGUgZW5jb2RlZCBieXRlIGFycmF5CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBieXRlW10gZW5jb2RlKGJ5dGVbXSBpbmJ1ZikgeworCWlmIChpbmJ1Zi5sZW5ndGggPT0gMCkKKwkgICAgcmV0dXJuIGluYnVmOworCXJldHVybiBlbmNvZGUoaW5idWYsIDAsIGluYnVmLmxlbmd0aCwgbnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW50ZXJuYWwgdXNlIG9ubHkgdmVyc2lvbiBvZiBlbmNvZGUuICBBbGxvdyBzcGVjaWZ5aW5nIHdoaWNoCisgICAgICogcGFydCBvZiB0aGUgaW5wdXQgYnVmZmVyIHRvIGVuY29kZS4gIElmIG91dGJ1ZiBpcyBub24tbnVsbCwKKyAgICAgKiBpdCdzIHVzZWQgYXMgaXMuICBPdGhlcndpc2UsIGEgbmV3IG91dHB1dCBidWZmZXIgaXMgYWxsb2NhdGVkLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGJ5dGVbXSBlbmNvZGUoYnl0ZVtdIGluYnVmLCBpbnQgb2ZmLCBpbnQgc2l6ZSwKKwkJCQlieXRlW10gb3V0YnVmKSB7CisJaWYgKG91dGJ1ZiA9PSBudWxsKQorCSAgICBvdXRidWYgPSBuZXcgYnl0ZVtlbmNvZGVkU2l6ZShzaXplKV07CisJaW50IGlucG9zLCBvdXRwb3M7CisJaW50IHZhbDsKKwlmb3IgKGlucG9zID0gb2ZmLCBvdXRwb3MgPSAwOyBzaXplID49IDM7IHNpemUgLT0gMywgb3V0cG9zICs9IDQpIHsKKwkgICAgdmFsID0gaW5idWZbaW5wb3MrK10gJiAweGZmOworCSAgICB2YWwgPDw9IDg7CisJICAgIHZhbCB8PSBpbmJ1ZltpbnBvcysrXSAmIDB4ZmY7CisJICAgIHZhbCA8PD0gODsKKwkgICAgdmFsIHw9IGluYnVmW2lucG9zKytdICYgMHhmZjsKKwkgICAgb3V0YnVmW291dHBvcyszXSA9IChieXRlKXBlbV9hcnJheVt2YWwgJiAweDNmXTsKKwkgICAgdmFsID4+PSA2OworCSAgICBvdXRidWZbb3V0cG9zKzJdID0gKGJ5dGUpcGVtX2FycmF5W3ZhbCAmIDB4M2ZdOworCSAgICB2YWwgPj49IDY7CisJICAgIG91dGJ1ZltvdXRwb3MrMV0gPSAoYnl0ZSlwZW1fYXJyYXlbdmFsICYgMHgzZl07CisJICAgIHZhbCA+Pj0gNjsKKwkgICAgb3V0YnVmW291dHBvcyswXSA9IChieXRlKXBlbV9hcnJheVt2YWwgJiAweDNmXTsKKwl9CisJLy8gZG9uZSB3aXRoIGdyb3VwcyBvZiB0aHJlZSwgZmluaXNoIHVwIGFueSBvZGQgYnl0ZXMgbGVmdAorCWlmIChzaXplID09IDEpIHsKKwkgICAgdmFsID0gaW5idWZbaW5wb3MrK10gJiAweGZmOworCSAgICB2YWwgPDw9IDQ7CisJICAgIG91dGJ1ZltvdXRwb3MrM10gPSAoYnl0ZSknPSc7CS8vIHBhZCBjaGFyYWN0ZXI7CisJICAgIG91dGJ1ZltvdXRwb3MrMl0gPSAoYnl0ZSknPSc7CS8vIHBhZCBjaGFyYWN0ZXI7CisJICAgIG91dGJ1ZltvdXRwb3MrMV0gPSAoYnl0ZSlwZW1fYXJyYXlbdmFsICYgMHgzZl07CisJICAgIHZhbCA+Pj0gNjsKKwkgICAgb3V0YnVmW291dHBvcyswXSA9IChieXRlKXBlbV9hcnJheVt2YWwgJiAweDNmXTsKKwl9IGVsc2UgaWYgKHNpemUgPT0gMikgeworCSAgICB2YWwgPSBpbmJ1ZltpbnBvcysrXSAmIDB4ZmY7CisJICAgIHZhbCA8PD0gODsKKwkgICAgdmFsIHw9IGluYnVmW2lucG9zKytdICYgMHhmZjsKKwkgICAgdmFsIDw8PSAyOworCSAgICBvdXRidWZbb3V0cG9zKzNdID0gKGJ5dGUpJz0nOwkvLyBwYWQgY2hhcmFjdGVyOworCSAgICBvdXRidWZbb3V0cG9zKzJdID0gKGJ5dGUpcGVtX2FycmF5W3ZhbCAmIDB4M2ZdOworCSAgICB2YWwgPj49IDY7CisJICAgIG91dGJ1ZltvdXRwb3MrMV0gPSAoYnl0ZSlwZW1fYXJyYXlbdmFsICYgMHgzZl07CisJICAgIHZhbCA+Pj0gNjsKKwkgICAgb3V0YnVmW291dHBvcyswXSA9IChieXRlKXBlbV9hcnJheVt2YWwgJiAweDNmXTsKKwl9CisJcmV0dXJuIG91dGJ1ZjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIGNvcnJlc3BvbmRpbmcgZW5jb2RlZCBzaXplIGZvciB0aGUgZ2l2ZW4gbnVtYmVyCisgICAgICogb2YgYnl0ZXMsIG5vdCBpbmNsdWRpbmcgYW55IENSTEYuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IGVuY29kZWRTaXplKGludCBzaXplKSB7CisJcmV0dXJuICgoc2l6ZSArIDIpIC8gMykgKiA0OworICAgIH0KKworICAgIC8qKiogYmVnaW4gVEVTVCBwcm9ncmFtCisgICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nIGFyZ3ZbXSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJRmlsZUlucHV0U3RyZWFtIGluZmlsZSA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oYXJndlswXSk7CisJQkFTRTY0RW5jb2RlclN0cmVhbSBlbmNvZGVyID0gbmV3IEJBU0U2NEVuY29kZXJTdHJlYW0oU3lzdGVtLm91dCk7CisJaW50IGM7CisKKwl3aGlsZSAoKGMgPSBpbmZpbGUucmVhZCgpKSAhPSAtMSkKKwkgICAgZW5jb2Rlci53cml0ZShjKTsKKwllbmNvZGVyLmNsb3NlKCk7CisgICAgfQorICAgICoqKiBlbmQgVEVTVCBwcm9ncmFtICoqLworfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL0JFbmNvZGVyU3RyZWFtLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvQkVuY29kZXJTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YTQzZGQ2Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL0JFbmNvZGVyU3RyZWFtLmphdmEKQEAgLTAsMCArMSw1MCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwudXRpbDsKKworaW1wb3J0IGphdmEuaW8uKjsKKworLyoqCisgKiBUaGlzIGNsYXNzIGltcGxlbWVudHMgYSAnQicgRW5jb2RlciBhcyBkZWZpbmVkIGJ5IFJGQzIwNDcgZm9yCisgKiBlbmNvZGluZyBNSU1FIGhlYWRlcnMuIEl0IHN1YmNsYXNzZXMgdGhlIEJBU0U2NEVuY29kZXJTdHJlYW0KKyAqIGNsYXNzLgorICogCisgKiBAYXV0aG9yIEpvaG4gTWFuaQorICovCisKK3B1YmxpYyBjbGFzcyBCRW5jb2RlclN0cmVhbSBleHRlbmRzIEJBU0U2NEVuY29kZXJTdHJlYW0geworCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgJ0InIGVuY29kZXIgdGhhdCBlbmNvZGVzIHRoZSBzcGVjaWZpZWQgaW5wdXQgc3RyZWFtLgorICAgICAqIEBwYXJhbSBvdXQgICAgICAgIHRoZSBvdXRwdXQgc3RyZWFtCisgICAgICovCisgICAgcHVibGljIEJFbmNvZGVyU3RyZWFtKE91dHB1dFN0cmVhbSBvdXQpIHsKKwlzdXBlcihvdXQsIEludGVnZXIuTUFYX1ZBTFVFKTsgLy8gTUFYX1ZBTFVFIGlzIDJeMzEsIHNob3VsZAorCQkJCSAgICAgICAvLyBzdWZmaWNlICghKSB0byBpbmRpY2F0ZSB0aGF0CisJCQkJICAgICAgIC8vIENSTEZzIHNob3VsZCBub3QgYmUgaW5zZXJ0ZWQKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsZW5ndGggb2YgdGhlIGVuY29kZWQgdmVyc2lvbiBvZiB0aGlzIGJ5dGUgYXJyYXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0JYgl0aGUgYnl0ZSBhcnJheQorICAgICAqIEByZXR1cm4JCXRoZSBsZW5ndGgKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBlbmNvZGVkTGVuZ3RoKGJ5dGVbXSBiKSB7CisgICAgICAgIHJldHVybiAoKGIubGVuZ3RoICsgMikvMykgKiA0OworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvdXRpbC9DUkxGT3V0cHV0U3RyZWFtLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvQ1JMRk91dHB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdjY2EzZDcKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvQ1JMRk91dHB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsODggQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLnV0aWw7CisKK2ltcG9ydCBqYXZhLmlvLio7CisKKworLyoqCisgKiBDb252ZXJ0IGxpbmVzIGludG8gdGhlIGNhbm9uaWNhbCBmb3JtYXQsIHRoYXQgaXMsIHRlcm1pbmF0ZSBsaW5lcyB3aXRoIHRoZQorICogQ1JMRiBzZXF1ZW5jZS4KKyAqIAorICogQGF1dGhvciBKb2huIE1hbmkKKyAqLworcHVibGljIGNsYXNzIENSTEZPdXRwdXRTdHJlYW0gZXh0ZW5kcyBGaWx0ZXJPdXRwdXRTdHJlYW0geworICAgIHByb3RlY3RlZCBpbnQgbGFzdGIgPSAtMTsKKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBhdEJPTCA9IHRydWU7CS8vIGF0IGJlZ2lubmluZyBvZiBsaW5lPworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBuZXdsaW5lID0geyAoYnl0ZSknXHInLCAoYnl0ZSknXG4nIH07CisKKyAgICBwdWJsaWMgQ1JMRk91dHB1dFN0cmVhbShPdXRwdXRTdHJlYW0gb3MpIHsKKwlzdXBlcihvcyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoaW50IGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJaWYgKGIgPT0gJ1xyJykgeworCSAgICB3cml0ZWxuKCk7CisJfSBlbHNlIGlmIChiID09ICdcbicpIHsKKwkgICAgaWYgKGxhc3RiICE9ICdccicpCisJCXdyaXRlbG4oKTsKKwl9IGVsc2UgeworCSAgICBvdXQud3JpdGUoYik7CisJICAgIGF0Qk9MID0gZmFsc2U7CisJfQorCWxhc3RiID0gYjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShieXRlIGJbXSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwl3cml0ZShiLCAwLCBiLmxlbmd0aCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoYnl0ZSBiW10sIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJaW50IHN0YXJ0ID0gb2ZmOworCQorCWxlbiArPSBvZmY7CisJZm9yIChpbnQgaSA9IHN0YXJ0OyBpIDwgbGVuIDsgaSsrKSB7CisJICAgIGlmIChiW2ldID09ICdccicpIHsKKwkJb3V0LndyaXRlKGIsIHN0YXJ0LCBpIC0gc3RhcnQpOworCQl3cml0ZWxuKCk7CisJCXN0YXJ0ID0gaSArIDE7CisJICAgIH0gZWxzZSBpZiAoYltpXSA9PSAnXG4nKSB7CisJCWlmIChsYXN0YiAhPSAnXHInKSB7CisJCSAgICBvdXQud3JpdGUoYiwgc3RhcnQsIGkgLSBzdGFydCk7CisJCSAgICB3cml0ZWxuKCk7CisJCX0KKwkJc3RhcnQgPSBpICsgMTsKKwkgICAgfQorCSAgICBsYXN0YiA9IGJbaV07CisJfQorCWlmICgobGVuIC0gc3RhcnQpID4gMCkgeworCSAgICBvdXQud3JpdGUoYiwgc3RhcnQsIGxlbiAtIHN0YXJ0KTsKKwkgICAgYXRCT0wgPSBmYWxzZTsKKwl9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBKdXN0IHdyaXRlIG91dCBhIG5ldyBsaW5lLCBzb21ldGhpbmcgc2ltaWxhciB0byBvdXQucHJpbnRsbigpCisgICAgICovCisgICAgcHVibGljIHZvaWQgd3JpdGVsbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG91dC53cml0ZShuZXdsaW5lKTsKKwlhdEJPTCA9IHRydWU7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL0RlY29kaW5nRXhjZXB0aW9uLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvRGVjb2RpbmdFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mZGRkODRmCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL0RlY29kaW5nRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0MSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwudXRpbDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKy8qKgorICogQSBzcGVjaWFsIElPRXhjZXB0aW9uIHRoYXQgaW5kaWNhdGVzIGEgZmFpbHVyZSB0byBkZWNvZGUgZGF0YSBkdWUKKyAqIHRvIGFuIGVycm9yIGluIHRoZSBmb3JtYXR0aW5nIG9mIHRoZSBkYXRhLiAgVGhpcyBhbGxvd3MgYXBwbGljYXRpb25zCisgKiB0byBkaXN0aW5ndWlzaCBkZWNvZGluZyBlcnJvcnMgZnJvbSBvdGhlciBJL08gZXJyb3JzLgorICoKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKi8KKworcHVibGljIGNsYXNzIERlY29kaW5nRXhjZXB0aW9uIGV4dGVuZHMgSU9FeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTY5MTM2NDc3OTQ0MjE0NTkzOTBMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jcwl0aGUgZXhjZXB0aW9uIG1lc3NhZ2UKKyAgICAgKi8KKyAgICBwdWJsaWMgRGVjb2RpbmdFeGNlcHRpb24oU3RyaW5nIHMpIHsKKwlzdXBlcihzKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvRm9sZGVyQ2xvc2VkSU9FeGNlcHRpb24uamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvdXRpbC9Gb2xkZXJDbG9zZWRJT0V4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVhNGVmMTAKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvRm9sZGVyQ2xvc2VkSU9FeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDYxIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC51dGlsOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5tYWlsLkZvbGRlcjsKKworLyoqCisgKiBBIHZhcmlhbnQgb2YgRm9sZGVyQ2xvc2VkRXhjZXB0aW9uIHRoYXQgY2FuIGJlIHRocm93biBmcm9tIG1ldGhvZHMKKyAqIHRoYXQgb25seSB0aHJvdyBJT0V4Y2VwdGlvbi4gIFRoZSBnZXRDb250ZW50IG1ldGhvZCB3aWxsIGNhdGNoIHRoaXMKKyAqIGV4Y2VwdGlvbiBhbmQgdHJhbnNsYXRlIGl0IGJhY2sgdG8gRm9sZGVyQ2xvc2VkRXhjZXB0aW9uLgorICoKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKi8KKworcHVibGljIGNsYXNzIEZvbGRlckNsb3NlZElPRXhjZXB0aW9uIGV4dGVuZHMgSU9FeGNlcHRpb24geworICAgIHRyYW5zaWVudCBwcml2YXRlIEZvbGRlciBmb2xkZXI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA0MjgxMTIyNTgwMzY1NTU1NzM1TDsKKyAgICAKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvcgorICAgICAqIEBwYXJhbSBmb2xkZXIJdGhlIEZvbGRlcgorICAgICAqLworICAgIHB1YmxpYyBGb2xkZXJDbG9zZWRJT0V4Y2VwdGlvbihGb2xkZXIgZm9sZGVyKSB7CisJdGhpcyhmb2xkZXIsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yCisgICAgICogQHBhcmFtIGZvbGRlciAJdGhlIEZvbGRlcgorICAgICAqIEBwYXJhbSBtZXNzYWdlCXRoZSBkZXRhaWxlZCBlcnJvciBtZXNzYWdlCisgICAgICovCisgICAgcHVibGljIEZvbGRlckNsb3NlZElPRXhjZXB0aW9uKEZvbGRlciBmb2xkZXIsIFN0cmluZyBtZXNzYWdlKSB7CisJc3VwZXIobWVzc2FnZSk7CisJdGhpcy5mb2xkZXIgPSBmb2xkZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZGVhZCBGb2xkZXIgb2JqZWN0CisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBkZWFkIEZvbGRlcgorICAgICAqLworICAgIHB1YmxpYyBGb2xkZXIgZ2V0Rm9sZGVyKCkgeworCXJldHVybiBmb2xkZXI7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL0xpbmVJbnB1dFN0cmVhbS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL0xpbmVJbnB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjljYjdmYjYKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvTGluZUlucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwxNDMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLnV0aWw7CisKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5TdGFuZGFyZENoYXJzZXRzOworCisvKioKKyAqIFRoaXMgY2xhc3MgaXMgdG8gc3VwcG9ydCByZWFkaW5nIENSTEYgdGVybWluYXRlZCBsaW5lcyB0aGF0CisgKiBjb250YWluIG9ubHkgVVMtQVNDSUkgY2hhcmFjdGVycyBmcm9tIGFuIGlucHV0IHN0cmVhbS4gUHJvdmlkZXMKKyAqIGZ1bmN0aW9uYWxpdHkgdGhhdCBpcyBzaW1pbGFyIHRvIHRoZSBkZXByZWNhdGVkIAorICogPGNvZGU+RGF0YUlucHV0U3RyZWFtLnJlYWRMaW5lKCk8L2NvZGU+LiBFeHBlY3RlZCB1c2UgaXMgdG8gcmVhZAorICogbGluZXMgYXMgU3RyaW5nIG9iamVjdHMgZnJvbSBhIFJGQzgyMiBzdHJlYW0uCisgKgorICogSXQgaXMgaW1wbGVtZW50ZWQgYXMgYSBGaWx0ZXJJbnB1dFN0cmVhbSwgc28gb25lIGNhbiBqdXN0IHdyYXAgCisgKiB0aGlzIGNsYXNzIGFyb3VuZCBhbnkgaW5wdXQgc3RyZWFtIGFuZCByZWFkIGJ5dGVzIGZyb20gdGhpcyBmaWx0ZXIuCisgKiAKKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCisKK3B1YmxpYyBjbGFzcyBMaW5lSW5wdXRTdHJlYW0gZXh0ZW5kcyBGaWx0ZXJJbnB1dFN0cmVhbSB7CisKKyAgICBwcml2YXRlIGJvb2xlYW4gYWxsb3d1dGY4OworICAgIHByaXZhdGUgYnl0ZVtdIGxpbmVCdWZmZXIgPSBudWxsOyAvLyByZXVzYWJsZSBieXRlIGJ1ZmZlcgorICAgIHByaXZhdGUgc3RhdGljIGludCBNQVhfSU5DUiA9IDEwMjQqMTAyNDsJLy8gMU1CCisKKyAgICBwdWJsaWMgTGluZUlucHV0U3RyZWFtKElucHV0U3RyZWFtIGluKSB7CisJdGhpcyhpbiwgZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBwYXJhbQlpbgl0aGUgSW5wdXRTdHJlYW0KKyAgICAgKiBAcGFyYW0JYWxsb3d1dGY4CWFsbG93IFVURi04IGNoYXJhY3RlcnM/CisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNgorICAgICAqLworICAgIHB1YmxpYyBMaW5lSW5wdXRTdHJlYW0oSW5wdXRTdHJlYW0gaW4sIGJvb2xlYW4gYWxsb3d1dGY4KSB7CisJc3VwZXIoaW4pOworCXRoaXMuYWxsb3d1dGY4ID0gYWxsb3d1dGY4OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWQgYSBsaW5lIGNvbnRhaW5pbmcgb25seSBBU0NJSSBjaGFyYWN0ZXJzIGZyb20gdGhlIGlucHV0IAorICAgICAqIHN0cmVhbS4gQSBsaW5lIGlzIHRlcm1pbmF0ZWQgYnkgYSBDUiBvciBOTCBvciBDUi1OTCBzZXF1ZW5jZS4KKyAgICAgKiBBIGNvbW1vbiBlcnJvciBpcyBhIENSLUNSLU5MIHNlcXVlbmNlLCB3aGljaCB3aWxsIGFsc28gdGVybWluYXRlCisgICAgICogYSBsaW5lLgorICAgICAqIFRoZSBsaW5lIHRlcm1pbmF0b3IgaXMgbm90IHJldHVybmVkIGFzIHBhcnQgb2YgdGhlIHJldHVybmVkIAorICAgICAqIFN0cmluZy4gUmV0dXJucyBudWxsIGlmIG5vIGRhdGEgaXMgYXZhaWxhYmxlLiA8cD4KKyAgICAgKgorICAgICAqIFRoaXMgY2xhc3MgaXMgc2ltaWxhciB0byB0aGUgZGVwcmVjYXRlZCAKKyAgICAgKiA8Y29kZT5EYXRhSW5wdXRTdHJlYW0ucmVhZExpbmUoKTwvY29kZT4KKyAgICAgKgorICAgICAqIEByZXR1cm4JCXRoZSBsaW5lCisgICAgICogQGV4Y2VwdGlvbglJT0V4Y2VwdGlvbglmb3IgSS9PIGVycm9ycworICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJkZXByZWNhdGlvbiIpCS8vIGZvciBvbGQgU3RyaW5nIGNvbnN0cnVjdG9yCisgICAgcHVibGljIFN0cmluZyByZWFkTGluZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJLy9JbnB1dFN0cmVhbSBpbiA9IHRoaXMuaW47CisJYnl0ZVtdIGJ1ZiA9IGxpbmVCdWZmZXI7CisKKwlpZiAoYnVmID09IG51bGwpCisJICAgIGJ1ZiA9IGxpbmVCdWZmZXIgPSBuZXcgYnl0ZVsxMjhdOworCisJaW50IGMxOworCWludCByb29tID0gYnVmLmxlbmd0aDsKKwlpbnQgb2Zmc2V0ID0gMDsKKworCXdoaWxlICgoYzEgPSBpbi5yZWFkKCkpICE9IC0xKSB7CisJICAgIGlmIChjMSA9PSAnXG4nKSAvLyBHb3QgTkwsIG91dGEgaGVyZS4KKwkJYnJlYWs7CisJICAgIGVsc2UgaWYgKGMxID09ICdccicpIHsKKwkJLy8gR290IENSLCBpcyB0aGUgbmV4dCBjaGFyIE5MID8KKwkJYm9vbGVhbiB0d29DUnMgPSBmYWxzZTsKKwkJaWYgKGluLm1hcmtTdXBwb3J0ZWQoKSkKKwkJICAgIGluLm1hcmsoMik7CisJCWludCBjMiA9IGluLnJlYWQoKTsKKwkJaWYgKGMyID09ICdccicpIHsJCS8vIGRpc2NhcmQgZXh0cmFuZW91cyBDUgorCQkgICAgdHdvQ1JzID0gdHJ1ZTsKKwkJICAgIGMyID0gaW4ucmVhZCgpOworCQl9CisJCWlmIChjMiAhPSAnXG4nKSB7CisJCSAgICAvKgorCQkgICAgICogSWYgdGhlIHN0cmVhbSBzdXBwb3J0cyBpdCAod2hpY2ggd2UgaG9wZSB3aWxsIGFsd2F5cworCQkgICAgICogYmUgdGhlIGNhc2UpLCByZXNldCB0byBhZnRlciB0aGUgZmlyc3QgQ1IuICBPdGhlcndpc2UsCisJCSAgICAgKiB3ZSB3cmFwIGEgUHVzaGJhY2tJbnB1dFN0cmVhbSBhcm91bmQgdGhlIHN0cmVhbSBzbyB3ZQorCQkgICAgICogY2FuIHVucmVhZCB0aGUgY2hhcmFjdGVycyB3ZSBkb24ndCBuZWVkLiAgVGhlIG9ubHkKKwkJICAgICAqIHByb2JsZW0gd2l0aCB0aGF0IGlzIHRoYXQgdGhlIGNhbGxlciBtaWdodCBzdG9wCisJCSAgICAgKiByZWFkaW5nIGZyb20gdGhpcyBMaW5lSW5wdXRTdHJlYW0sIHRocm93IGl0IGF3YXksCisJCSAgICAgKiBhbmQgdGhlbiBzdGFydCByZWFkaW5nIGZyb20gdGhlIHVuZGVybHlpbmcgc3RyZWFtLgorCQkgICAgICogSWYgdGhhdCBoYXBwZW5zLCB0aGUgcHVzaGVkIGJhY2sgY2hhcmFjdGVycyB3aWxsIGJlCisJCSAgICAgKiBsb3N0IGZvcmV2ZXIuCisJCSAgICAgKi8KKwkJICAgIGlmIChpbi5tYXJrU3VwcG9ydGVkKCkpCisJCQlpbi5yZXNldCgpOworCQkgICAgZWxzZSB7CisJCQlpZiAoIShpbiBpbnN0YW5jZW9mIFB1c2hiYWNrSW5wdXRTdHJlYW0pKQorCQkJICAgIGluIC8qPSB0aGlzLmluKi8gPSBuZXcgUHVzaGJhY2tJbnB1dFN0cmVhbShpbiwgMik7CisJCQlpZiAoYzIgIT0gLTEpCisJCQkgICAgKChQdXNoYmFja0lucHV0U3RyZWFtKWluKS51bnJlYWQoYzIpOworCQkJaWYgKHR3b0NScykKKwkJCSAgICAoKFB1c2hiYWNrSW5wdXRTdHJlYW0paW4pLnVucmVhZCgnXHInKTsKKwkJICAgIH0KKwkJfQorCQlicmVhazsgLy8gb3V0YSBoZXJlLgorCSAgICB9CisKKwkgICAgLy8gTm90IENSLCBOTCBvciBDUi1OTCAuLi4KKwkgICAgLy8gLi4gSW5zZXJ0IHRoZSBieXRlIGludG8gb3VyIGJ5dGUgYnVmZmVyCisJICAgIGlmICgtLXJvb20gPCAwKSB7IC8vIE5vIHJvb20sIG5lZWQgdG8gZ3Jvdy4KKwkJaWYgKGJ1Zi5sZW5ndGggPCBNQVhfSU5DUikKKwkJICAgIGJ1ZiA9IG5ldyBieXRlW2J1Zi5sZW5ndGggKiAyXTsKKwkJZWxzZQorCQkgICAgYnVmID0gbmV3IGJ5dGVbYnVmLmxlbmd0aCArIE1BWF9JTkNSXTsKKwkJcm9vbSA9IGJ1Zi5sZW5ndGggLSBvZmZzZXQgLSAxOworCQlTeXN0ZW0uYXJyYXljb3B5KGxpbmVCdWZmZXIsIDAsIGJ1ZiwgMCwgb2Zmc2V0KTsKKwkJbGluZUJ1ZmZlciA9IGJ1ZjsKKwkgICAgfQorCSAgICBidWZbb2Zmc2V0KytdID0gKGJ5dGUpYzE7CisJfQorCisJaWYgKChjMSA9PSAtMSkgJiYgKG9mZnNldCA9PSAwKSkKKwkgICAgcmV0dXJuIG51bGw7CisKKwlpZiAoYWxsb3d1dGY4KQorCSAgICByZXR1cm4gbmV3IFN0cmluZyhidWYsIDAsIG9mZnNldCwgU3RhbmRhcmRDaGFyc2V0cy5VVEZfOCk7CisJZWxzZQorCSAgICByZXR1cm4gbmV3IFN0cmluZyhidWYsIDAsIDAsIG9mZnNldCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL0xpbmVPdXRwdXRTdHJlYW0uamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvdXRpbC9MaW5lT3V0cHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDg2ZjVlYwotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvdXRpbC9MaW5lT3V0cHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSw3MiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwudXRpbDsKKworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LlN0YW5kYXJkQ2hhcnNldHM7CisKKy8qKgorICogVGhpcyBjbGFzcyBpcyB0byBzdXBwb3J0IHdyaXRpbmcgb3V0IFN0cmluZ3MgYXMgYSBzZXF1ZW5jZSBvZiBieXRlcworICogdGVybWluYXRlZCBieSBhIENSTEYgc2VxdWVuY2UuIFRoZSBTdHJpbmcgbXVzdCBjb250YWluIG9ubHkgVVMtQVNDSUkKKyAqIGNoYXJhY3RlcnMuPHA+CisgKgorICogVGhlIGV4cGVjdGVkIHVzZSBpcyB0byB3cml0ZSBvdXQgUkZDODIyIHN0eWxlIGhlYWRlcnMgdG8gYW4gb3V0cHV0CisgKiBzdHJlYW0uIDxwPgorICoKKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCisKK3B1YmxpYyBjbGFzcyBMaW5lT3V0cHV0U3RyZWFtIGV4dGVuZHMgRmlsdGVyT3V0cHV0U3RyZWFtIHsKKyAgICBwcml2YXRlIGJvb2xlYW4gYWxsb3d1dGY4OworCisgICAgcHJpdmF0ZSBzdGF0aWMgYnl0ZVtdIG5ld2xpbmU7CisKKyAgICBzdGF0aWMgeworCW5ld2xpbmUgPSBuZXcgYnl0ZVsyXTsKKwluZXdsaW5lWzBdID0gKGJ5dGUpJ1xyJzsKKwluZXdsaW5lWzFdID0gKGJ5dGUpJ1xuJzsKKyAgICB9CisKKyAgICBwdWJsaWMgTGluZU91dHB1dFN0cmVhbShPdXRwdXRTdHJlYW0gb3V0KSB7CisJdGhpcyhvdXQsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcGFyYW0Jb3V0CXRoZSBPdXRwdXRTdHJlYW0KKyAgICAgKiBAcGFyYW0JYWxsb3d1dGY4CWFsbG93IFVURi04IGNoYXJhY3RlcnM/CisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNgorICAgICAqLworICAgIHB1YmxpYyBMaW5lT3V0cHV0U3RyZWFtKE91dHB1dFN0cmVhbSBvdXQsIGJvb2xlYW4gYWxsb3d1dGY4KSB7CisJc3VwZXIob3V0KTsKKwl0aGlzLmFsbG93dXRmOCA9IGFsbG93dXRmODsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZWxuKFN0cmluZyBzKSB0aHJvd3MgSU9FeGNlcHRpb24geworCWJ5dGVbXSBieXRlczsKKwlpZiAoYWxsb3d1dGY4KQorCSAgICBieXRlcyA9IHMuZ2V0Qnl0ZXMoU3RhbmRhcmRDaGFyc2V0cy5VVEZfOCk7CisJZWxzZQorCSAgICBieXRlcyA9IEFTQ0lJVXRpbGl0eS5nZXRCeXRlcyhzKTsKKwlvdXQud3JpdGUoYnl0ZXMpOworCW91dC53cml0ZShuZXdsaW5lKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZWxuKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlvdXQud3JpdGUobmV3bGluZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL0xvZ091dHB1dFN0cmVhbS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL0xvZ091dHB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMxYzMxNTMKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvTG9nT3V0cHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwxMjggQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDgsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLnV0aWw7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkxldmVsOworCisvKioKKyAqIENhcHR1cmUgb3V0cHV0IGxpbmVzIGFuZCBzZW5kIHRoZW0gdG8gdGhlIG1haWwgbG9nZ2VyLgorICovCitwdWJsaWMgY2xhc3MgTG9nT3V0cHV0U3RyZWFtIGV4dGVuZHMgT3V0cHV0U3RyZWFtIHsKKyAgICBwcm90ZWN0ZWQgTWFpbExvZ2dlciBsb2dnZXI7CisgICAgcHJvdGVjdGVkIExldmVsIGxldmVsOworCisgICAgcHJpdmF0ZSBpbnQgbGFzdGIgPSAtMTsKKyAgICBwcml2YXRlIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVs4MF07CisgICAgcHJpdmF0ZSBpbnQgcG9zID0gMDsKKworICAgIC8qKgorICAgICAqIExvZyB0byB0aGUgc3BlY2lmaWVkIGxvZ2dlci4KKyAgICAgKgorICAgICAqIEBwYXJhbQlsb2dnZXIJdGhlIE1haWxMb2dnZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgTG9nT3V0cHV0U3RyZWFtKE1haWxMb2dnZXIgbG9nZ2VyKSB7CisJdGhpcy5sb2dnZXIgPSBsb2dnZXI7CisJdGhpcy5sZXZlbCA9IExldmVsLkZJTkVTVDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShpbnQgYikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlpZiAoIWxvZ2dlci5pc0xvZ2dhYmxlKGxldmVsKSkKKwkgICAgcmV0dXJuOworCisJaWYgKGIgPT0gJ1xyJykgeworCSAgICBsb2dCdWYoKTsKKwl9IGVsc2UgaWYgKGIgPT0gJ1xuJykgeworCSAgICBpZiAobGFzdGIgIT0gJ1xyJykKKwkJbG9nQnVmKCk7CisJfSBlbHNlIHsKKwkgICAgZXhwYW5kQ2FwYWNpdHkoMSk7CisJICAgIGJ1Zltwb3MrK10gPSAoYnl0ZSliOworCX0KKwlsYXN0YiA9IGI7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoYnl0ZSBiW10pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJd3JpdGUoYiwgMCwgYi5sZW5ndGgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGJ5dGUgYltdLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworCWludCBzdGFydCA9IG9mZjsKKwkKKwlpZiAoIWxvZ2dlci5pc0xvZ2dhYmxlKGxldmVsKSkKKwkgICAgcmV0dXJuOworCWxlbiArPSBvZmY7CisJZm9yIChpbnQgaSA9IHN0YXJ0OyBpIDwgbGVuIDsgaSsrKSB7CisJICAgIGlmIChiW2ldID09ICdccicpIHsKKwkJZXhwYW5kQ2FwYWNpdHkoaSAtIHN0YXJ0KTsKKwkJU3lzdGVtLmFycmF5Y29weShiLCBzdGFydCwgYnVmLCBwb3MsIGkgLSBzdGFydCk7CisJCXBvcyArPSBpIC0gc3RhcnQ7CisJCWxvZ0J1ZigpOworCQlzdGFydCA9IGkgKyAxOworCSAgICB9IGVsc2UgaWYgKGJbaV0gPT0gJ1xuJykgeworCQlpZiAobGFzdGIgIT0gJ1xyJykgeworCQkgICAgZXhwYW5kQ2FwYWNpdHkoaSAtIHN0YXJ0KTsKKwkJICAgIFN5c3RlbS5hcnJheWNvcHkoYiwgc3RhcnQsIGJ1ZiwgcG9zLCBpIC0gc3RhcnQpOworCQkgICAgcG9zICs9IGkgLSBzdGFydDsKKwkJICAgIGxvZ0J1ZigpOworCQl9CisJCXN0YXJ0ID0gaSArIDE7CisJICAgIH0KKwkgICAgbGFzdGIgPSBiW2ldOworCX0KKwlpZiAoKGxlbiAtIHN0YXJ0KSA+IDApIHsKKwkgICAgZXhwYW5kQ2FwYWNpdHkobGVuIC0gc3RhcnQpOworCSAgICBTeXN0ZW0uYXJyYXljb3B5KGIsIHN0YXJ0LCBidWYsIHBvcywgbGVuIC0gc3RhcnQpOworCSAgICBwb3MgKz0gbGVuIC0gc3RhcnQ7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIExvZyB0aGUgc3BlY2lmaWVkIG1lc3NhZ2UuCisgICAgICogQ2FuIGJlIG92ZXJyaWRkZW4gYnkgc3ViY2xhc3MgdG8gZG8gZGlmZmVyZW50IGxvZ2dpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0JbXNnCXRoZSBtZXNzYWdlIHRvIGxvZworICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGxvZyhTdHJpbmcgbXNnKSB7CisJbG9nZ2VyLmxvZyhsZXZlbCwgbXNnKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0IHRoZSBidWZmZXIgdG8gYSBzdHJpbmcgYW5kIGxvZyBpdC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgbG9nQnVmKCkgeworCVN0cmluZyBtc2cgPSBuZXcgU3RyaW5nKGJ1ZiwgMCwgcG9zKTsKKwlwb3MgPSAwOworCWxvZyhtc2cpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVuc3VyZSB0aGF0IHRoZSBidWZmZXIgY2FuIGhvbGQgYXQgbGVhc3QgbGVuIGJ5dGVzCisgICAgICogYmV5b25kIHRoZSBjdXJyZW50IHBvc2l0aW9uLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBleHBhbmRDYXBhY2l0eShpbnQgbGVuKSB7CisJd2hpbGUgKHBvcyArIGxlbiA+IGJ1Zi5sZW5ndGgpIHsKKwkgICAgYnl0ZVtdIG5iID0gbmV3IGJ5dGVbYnVmLmxlbmd0aCAqIDJdOworCSAgICBTeXN0ZW0uYXJyYXljb3B5KGJ1ZiwgMCwgbmIsIDAsIHBvcyk7CisJICAgIGJ1ZiA9IG5iOworCX0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvTWFpbENvbm5lY3RFeGNlcHRpb24uamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvdXRpbC9NYWlsQ29ubmVjdEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc2OGU5MGYKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvTWFpbENvbm5lY3RFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDgzIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC51dGlsOworCitpbXBvcnQgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb247CisKKy8qKgorICogQSBNZXNzYWdpbmdFeGNlcHRpb24gdGhhdCBpbmRpY2F0ZXMgYSBzb2NrZXQgY29ubmVjdGlvbiBhdHRlbXB0IGZhaWxlZC4KKyAqIFVubGlrZSBqYXZhLm5ldC5Db25uZWN0RXhjZXB0aW9uLCBpdCBpbmNsdWRlcyBkZXRhaWxzIG9mIHdoYXQgd2UKKyAqIHdlcmUgdHJ5aW5nIHRvIGNvbm5lY3QgdG8uICBUaGUgdW5kZXJseWluZyBleGNlcHRpb24gaXMgYXZhaWxhYmxlCisgKiBhcyB0aGUgImNhdXNlIiBvZiB0aGlzIGV4Y2VwdGlvbi4KKyAqCisgKiBAc2VlCQlqYXZhLm5ldC5Db25uZWN0RXhjZXB0aW9uCisgKiBAYXV0aG9yCUJpbGwgU2hhbm5vbgorICogQHNpbmNlIAlKYXZhTWFpbCAxLjUuMAorICovCisKK3B1YmxpYyBjbGFzcyBNYWlsQ29ubmVjdEV4Y2VwdGlvbiBleHRlbmRzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisgICAgcHJpdmF0ZSBTdHJpbmcgaG9zdDsKKyAgICBwcml2YXRlIGludCBwb3J0OworICAgIHByaXZhdGUgaW50IGN0bzsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0zODE4ODA3NzMxMTI1MzE3NzI5TDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBNYWlsQ29ubmVjdEV4Y2VwdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbQljZXgJdGhlIFNvY2tldENvbm5lY3RFeGNlcHRpb24gd2l0aCB0aGUgZGV0YWlscworICAgICAqLworICAgIHB1YmxpYyBNYWlsQ29ubmVjdEV4Y2VwdGlvbihTb2NrZXRDb25uZWN0RXhjZXB0aW9uIGNleCkgeworCXN1cGVyKAorCSAgICAiQ291bGRuJ3QgY29ubmVjdCB0byBob3N0LCBwb3J0OiAiICsKKwkgICAgY2V4LmdldEhvc3QoKSArICIsICIgKyBjZXguZ2V0UG9ydCgpICsKKwkgICAgIjsgdGltZW91dCAiICsgY2V4LmdldENvbm5lY3Rpb25UaW1lb3V0KCkgKworCSAgICAoY2V4LmdldE1lc3NhZ2UoKSAhPSBudWxsID8gKCI7ICIgKyBjZXguZ2V0TWVzc2FnZSgpKSA6ICIiKSk7CisJLy8gZXh0cmFjdCB0aGUgZGV0YWlscyBhbmQgc2F2ZSB0aGVtIGhlcmUKKwl0aGlzLmhvc3QgPSBjZXguZ2V0SG9zdCgpOworCXRoaXMucG9ydCA9IGNleC5nZXRQb3J0KCk7CisJdGhpcy5jdG8gPSBjZXguZ2V0Q29ubmVjdGlvblRpbWVvdXQoKTsKKwlzZXROZXh0RXhjZXB0aW9uKGNleC5nZXRFeGNlcHRpb24oKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIGhvc3Qgd2Ugd2VyZSB0cnlpbmcgdG8gY29ubmVjdCB0by4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIGhvc3QKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEhvc3QoKSB7CisJcmV0dXJuIGhvc3Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIHBvcnQgd2Ugd2VyZSB0cnlpbmcgdG8gY29ubmVjdCB0by4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIHBvcnQKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFBvcnQoKSB7CisJcmV0dXJuIHBvcnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIHRpbWVvdXQgdXNlZCBmb3IgdGhlIGNvbm5lY3Rpb24gYXR0ZW1wdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIGNvbm5lY3Rpb24gdGltZW91dAorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0Q29ubmVjdGlvblRpbWVvdXQoKSB7CisJcmV0dXJuIGN0bzsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvTWFpbExvZ2dlci5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL01haWxMb2dnZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yOTM2M2NhCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL01haWxMb2dnZXIuamF2YQpAQCAtMCwwICsxLDQxOSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAxMiwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwudXRpbDsKKworaW1wb3J0IGphdmEuaW8uUHJpbnRTdHJlYW07CitpbXBvcnQgamF2YS50ZXh0Lk1lc3NhZ2VGb3JtYXQ7CitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTGV2ZWw7CitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTG9nZ2VyOworaW1wb3J0IGphdmF4Lm1haWwuU2Vzc2lvbjsKKworLyoqCisgKiBBIHNpbXBsaWZpZWQgbG9nZ2VyIHVzZWQgYnkgSmF2YU1haWwgdG8gaGFuZGxlIGxvZ2dpbmcgdG8gYQorICogUHJpbnRTdHJlYW0gYW5kIGxvZ2dpbmcgdGhyb3VnaCBhIGphdmEudXRpbC5sb2dnaW5nLkxvZ2dlci4KKyAqIElmIGRlYnVnIGlzIHNldCwgbWVzc2FnZXMgYXJlIHdyaXR0ZW4gdG8gdGhlIFByaW50U3RyZWFtIGFuZAorICogcHJlZml4ZWQgYnkgdGhlIHNwZWNpZmllZCBwcmVmaXggKHdoaWNoIGlzIG5vdCBpbmNsdWRlZCBpbgorICogTG9nZ2VyIG1lc3NhZ2VzKS4KKyAqIE1lc3NhZ2VzIGFyZSBsb2dnZWQgYnkgdGhlIExvZ2dlciBiYXNlZCBvbiB0aGUgY29uZmlndXJhdGlvbgorICogb2YgdGhlIGxvZ2dpbmcgc3lzdGVtLgorICovCisKKy8qCisgKiBJdCB3b3VsZCBiZSBzbyBtdWNoIHNpbXBsZXIgdG8ganVzdCBzdWJjbGFzcyBMb2dnZXIgYW5kIG92ZXJyaWRlCisgKiB0aGUgbG9nKExvZ1JlY29yZCkgbWV0aG9kLCBhcyB0aGUgamF2YWRvY3Mgc3VnZ2VzdCwgYnV0IHRoYXQgZG9lc24ndAorICogd29yayBiZWNhdXNlIExvZ2dlciBtYWtlcyB0aGUgZGVjaXNpb24gYWJvdXQgd2hldGhlciB0byBsb2cgdGhlIG1lc3NhZ2UKKyAqIG9yIG5vdCBiZWZvcmUgY2FsbGluZyB0aGUgbG9nKExvZ1JlY29yZCkgbWV0aG9kLiAgSW5zdGVhZCwgd2UganVzdAorICogcHJvdmlkZSB0aGUgZmV3IGxvZyBtZXRob2RzIHdlIG5lZWQgaGVyZS4KKyAqLworCitwdWJsaWMgZmluYWwgY2xhc3MgTWFpbExvZ2dlciB7CisgICAgLyoqCisgICAgICogRm9yIGxvZyBtZXNzYWdlcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIExvZ2dlciBsb2dnZXI7CisgICAgLyoqCisgICAgICogRm9yIGRlYnVnIG91dHB1dC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBwcmVmaXg7CisgICAgLyoqCisgICAgICogUHJvZHVjZSBkZWJ1ZyBvdXRwdXQ/CisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIGRlYnVnOworICAgIC8qKgorICAgICAqIFN0cmVhbSBmb3IgZGVidWcgb3V0cHV0LgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgUHJpbnRTdHJlYW0gb3V0OworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGEgbmV3IE1haWxMb2dnZXIgdXNpbmcgdGhlIHNwZWNpZmllZCBMb2dnZXIgbmFtZSwKKyAgICAgKiBkZWJ1ZyBwcmVmaXggKGUuZy4sICJERUJVRyIpLCBkZWJ1ZyBmbGFnLCBhbmQgUHJpbnRTdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0JbmFtZQl0aGUgTG9nZ2VyIG5hbWUKKyAgICAgKiBAcGFyYW0JcHJlZml4CXRoZSBwcmVmaXggZm9yIGRlYnVnIG91dHB1dCwgb3IgbnVsbCBmb3Igbm9uZQorICAgICAqIEBwYXJhbQlkZWJ1ZwlpZiB0cnVlLCB3cml0ZSB0byBQcmludFN0cmVhbQorICAgICAqIEBwYXJhbQlvdXQJdGhlIFByaW50U3RyZWFtIHRvIHdyaXRlIHRvCisgICAgICovCisgICAgcHVibGljIE1haWxMb2dnZXIoU3RyaW5nIG5hbWUsIFN0cmluZyBwcmVmaXgsIGJvb2xlYW4gZGVidWcsCisJCQkJUHJpbnRTdHJlYW0gb3V0KSB7CisJbG9nZ2VyID0gTG9nZ2VyLmdldExvZ2dlcihuYW1lKTsKKwl0aGlzLnByZWZpeCA9IHByZWZpeDsKKwl0aGlzLmRlYnVnID0gZGVidWc7CisJdGhpcy5vdXQgPSBvdXQgIT0gbnVsbCA/IG91dCA6IFN5c3RlbS5vdXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGEgbmV3IE1haWxMb2dnZXIgdXNpbmcgdGhlIHNwZWNpZmllZCBjbGFzcycgcGFja2FnZQorICAgICAqIG5hbWUgYXMgdGhlIExvZ2dlciBuYW1lLAorICAgICAqIGRlYnVnIHByZWZpeCAoZS5nLiwgIkRFQlVHIiksIGRlYnVnIGZsYWcsIGFuZCBQcmludFN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbQljbGF6egl0aGUgTG9nZ2VyIG5hbWUgaXMgdGhlIHBhY2thZ2UgbmFtZSBvZiB0aGlzIGNsYXNzCisgICAgICogQHBhcmFtCXByZWZpeAl0aGUgcHJlZml4IGZvciBkZWJ1ZyBvdXRwdXQsIG9yIG51bGwgZm9yIG5vbmUKKyAgICAgKiBAcGFyYW0JZGVidWcJaWYgdHJ1ZSwgd3JpdGUgdG8gUHJpbnRTdHJlYW0KKyAgICAgKiBAcGFyYW0Jb3V0CXRoZSBQcmludFN0cmVhbSB0byB3cml0ZSB0bworICAgICAqLworICAgIHB1YmxpYyBNYWlsTG9nZ2VyKENsYXNzPD8+IGNsYXp6LCBTdHJpbmcgcHJlZml4LCBib29sZWFuIGRlYnVnLAorCQkJCVByaW50U3RyZWFtIG91dCkgeworCVN0cmluZyBuYW1lID0gcGFja2FnZU9mKGNsYXp6KTsKKwlsb2dnZXIgPSBMb2dnZXIuZ2V0TG9nZ2VyKG5hbWUpOworCXRoaXMucHJlZml4ID0gcHJlZml4OworCXRoaXMuZGVidWcgPSBkZWJ1ZzsKKwl0aGlzLm91dCA9IG91dCAhPSBudWxsID8gb3V0IDogU3lzdGVtLm91dDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYSBuZXcgTWFpbExvZ2dlciB1c2luZyB0aGUgc3BlY2lmaWVkIGNsYXNzJyBwYWNrYWdlCisgICAgICogbmFtZSBjb21iaW5lZCB3aXRoIHRoZSBzcGVjaWZpZWQgc3VibmFtZSBhcyB0aGUgTG9nZ2VyIG5hbWUsCisgICAgICogZGVidWcgcHJlZml4IChlLmcuLCAiREVCVUciKSwgZGVidWcgZmxhZywgYW5kIFByaW50U3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtCWNsYXp6CXRoZSBMb2dnZXIgbmFtZSBpcyB0aGUgcGFja2FnZSBuYW1lIG9mIHRoaXMgY2xhc3MKKyAgICAgKiBAcGFyYW0Jc3VibmFtZQl0aGUgTG9nZ2VyIG5hbWUgcmVsYXRpdmUgdG8gdGhpcyBMb2dnZXIgbmFtZQorICAgICAqIEBwYXJhbQlwcmVmaXgJdGhlIHByZWZpeCBmb3IgZGVidWcgb3V0cHV0LCBvciBudWxsIGZvciBub25lCisgICAgICogQHBhcmFtCWRlYnVnCWlmIHRydWUsIHdyaXRlIHRvIFByaW50U3RyZWFtCisgICAgICogQHBhcmFtCW91dAl0aGUgUHJpbnRTdHJlYW0gdG8gd3JpdGUgdG8KKyAgICAgKi8KKyAgICBwdWJsaWMgTWFpbExvZ2dlcihDbGFzczw/PiBjbGF6eiwgU3RyaW5nIHN1Ym5hbWUsIFN0cmluZyBwcmVmaXgsIGJvb2xlYW4gZGVidWcsCisJCQkJUHJpbnRTdHJlYW0gb3V0KSB7CisJU3RyaW5nIG5hbWUgPSBwYWNrYWdlT2YoY2xhenopICsgIi4iICsgc3VibmFtZTsKKwlsb2dnZXIgPSBMb2dnZXIuZ2V0TG9nZ2VyKG5hbWUpOworCXRoaXMucHJlZml4ID0gcHJlZml4OworCXRoaXMuZGVidWcgPSBkZWJ1ZzsKKwl0aGlzLm91dCA9IG91dCAhPSBudWxsID8gb3V0IDogU3lzdGVtLm91dDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYSBuZXcgTWFpbExvZ2dlciB1c2luZyB0aGUgc3BlY2lmaWVkIExvZ2dlciBuYW1lIGFuZAorICAgICAqIGRlYnVnIHByZWZpeCAoZS5nLiwgIkRFQlVHIikuICBHZXQgdGhlIGRlYnVnIGZsYWcgYW5kIFByaW50U3RyZWFtCisgICAgICogZnJvbSB0aGUgU2Vzc2lvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbQluYW1lCXRoZSBMb2dnZXIgbmFtZQorICAgICAqIEBwYXJhbQlwcmVmaXgJdGhlIHByZWZpeCBmb3IgZGVidWcgb3V0cHV0LCBvciBudWxsIGZvciBub25lCisgICAgICogQHBhcmFtCXNlc3Npb24Jd2hlcmUgdG8gZ2V0IHRoZSBkZWJ1ZyBmbGFnIGFuZCBQcmludFN0cmVhbQorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIE1haWxMb2dnZXIoU3RyaW5nIG5hbWUsIFN0cmluZyBwcmVmaXgsIFNlc3Npb24gc2Vzc2lvbikgeworCXRoaXMobmFtZSwgcHJlZml4LCBzZXNzaW9uLmdldERlYnVnKCksIHNlc3Npb24uZ2V0RGVidWdPdXQoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGEgbmV3IE1haWxMb2dnZXIgdXNpbmcgdGhlIHNwZWNpZmllZCBjbGFzcycgcGFja2FnZQorICAgICAqIG5hbWUgYXMgdGhlIExvZ2dlciBuYW1lIGFuZCB0aGUgc3BlY2lmaWVkCisgICAgICogZGVidWcgcHJlZml4IChlLmcuLCAiREVCVUciKS4gIEdldCB0aGUgZGVidWcgZmxhZyBhbmQgUHJpbnRTdHJlYW0KKyAgICAgKiBmcm9tIHRoZSBTZXNzaW9uLgorICAgICAqCisgICAgICogQHBhcmFtCWNsYXp6CXRoZSBMb2dnZXIgbmFtZSBpcyB0aGUgcGFja2FnZSBuYW1lIG9mIHRoaXMgY2xhc3MKKyAgICAgKiBAcGFyYW0JcHJlZml4CXRoZSBwcmVmaXggZm9yIGRlYnVnIG91dHB1dCwgb3IgbnVsbCBmb3Igbm9uZQorICAgICAqIEBwYXJhbQlzZXNzaW9uCXdoZXJlIHRvIGdldCB0aGUgZGVidWcgZmxhZyBhbmQgUHJpbnRTdHJlYW0KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBNYWlsTG9nZ2VyKENsYXNzPD8+IGNsYXp6LCBTdHJpbmcgcHJlZml4LCBTZXNzaW9uIHNlc3Npb24pIHsKKwl0aGlzKGNsYXp6LCBwcmVmaXgsIHNlc3Npb24uZ2V0RGVidWcoKSwgc2Vzc2lvbi5nZXREZWJ1Z091dCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBNYWlsTG9nZ2VyIHRoYXQgdXNlcyBhIExvZ2dlciB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZQorICAgICAqIGFuZCBwcmVmaXguICBUaGUgbmV3IE1haWxMb2dnZXIgdXNlcyB0aGUgc2FtZSBkZWJ1ZyBmbGFnIGFuZAorICAgICAqIFByaW50U3RyZWFtIGFzIHRoaXMgTWFpbExvZ2dlci4KKyAgICAgKgorICAgICAqIEBwYXJhbQluYW1lCXRoZSBMb2dnZXIgbmFtZQorICAgICAqIEBwYXJhbQlwcmVmaXgJdGhlIHByZWZpeCBmb3IgZGVidWcgb3V0cHV0LCBvciBudWxsIGZvciBub25lCisgICAgICogQHJldHVybiBhIE1haWxMb2dnZXIgZm9yIHRoZSBnaXZlbiBuYW1lIGFuZCBwcmVmaXguCisgICAgICovCisgICAgcHVibGljIE1haWxMb2dnZXIgZ2V0TG9nZ2VyKFN0cmluZyBuYW1lLCBTdHJpbmcgcHJlZml4KSB7CisJcmV0dXJuIG5ldyBNYWlsTG9nZ2VyKG5hbWUsIHByZWZpeCwgZGVidWcsIG91dCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgTWFpbExvZ2dlciB1c2luZyB0aGUgc3BlY2lmaWVkIGNsYXNzJyBwYWNrYWdlCisgICAgICogbmFtZSBhcyB0aGUgTG9nZ2VyIG5hbWUgYW5kIHRoZSBzcGVjaWZpZWQgcHJlZml4LgorICAgICAqIFRoZSBuZXcgTWFpbExvZ2dlciB1c2VzIHRoZSBzYW1lIGRlYnVnIGZsYWcgYW5kCisgICAgICogUHJpbnRTdHJlYW0gYXMgdGhpcyBNYWlsTG9nZ2VyLgorICAgICAqCisgICAgICogQHBhcmFtCWNsYXp6CXRoZSBMb2dnZXIgbmFtZSBpcyB0aGUgcGFja2FnZSBuYW1lIG9mIHRoaXMgY2xhc3MKKyAgICAgKiBAcGFyYW0JcHJlZml4CXRoZSBwcmVmaXggZm9yIGRlYnVnIG91dHB1dCwgb3IgbnVsbCBmb3Igbm9uZQorICAgICAqIEByZXR1cm4gYSBNYWlsTG9nZ2VyIGZvciB0aGUgZ2l2ZW4gbmFtZSBhbmQgcHJlZml4LgorICAgICAqLworICAgIHB1YmxpYyBNYWlsTG9nZ2VyIGdldExvZ2dlcihDbGFzczw/PiBjbGF6eiwgU3RyaW5nIHByZWZpeCkgeworCXJldHVybiBuZXcgTWFpbExvZ2dlcihjbGF6eiwgcHJlZml4LCBkZWJ1Zywgb3V0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBNYWlsTG9nZ2VyIHRoYXQgdXNlcyBhIExvZ2dlciB3aG9zZSBuYW1lIGlzIGNvbXBvc2VkCisgICAgICogb2YgdGhpcyBNYWlsTG9nZ2VyJ3MgbmFtZSBwbHVzIHRoZSBzcGVjaWZpZWQgc3ViLW5hbWUsIHNlcGFyYXRlZAorICAgICAqIGJ5IGEgZG90LiAgVGhlIG5ldyBNYWlsTG9nZ2VyIHVzZXMgdGhlIG5ldyBwcmVmaXggZm9yIGRlYnVnIG91dHB1dC4KKyAgICAgKiBUaGlzIGlzIHVzZWQgcHJpbWFyaWx5IGJ5IHRoZSBwcm90b2NvbCB0cmFjZSBjb2RlIHRoYXQgd2FudHMgYQorICAgICAqIGRpZmZlcmVudCBwcmVmaXggKG5vbmUpLgorICAgICAqCisgICAgICogQHBhcmFtCXN1Ym5hbWUJdGhlIExvZ2dlciBuYW1lIHJlbGF0aXZlIHRvIHRoaXMgTG9nZ2VyIG5hbWUKKyAgICAgKiBAcGFyYW0JcHJlZml4CXRoZSBwcmVmaXggZm9yIGRlYnVnIG91dHB1dCwgb3IgbnVsbCBmb3Igbm9uZQorICAgICAqIEByZXR1cm4gYSBNYWlsTG9nZ2VyIGZvciB0aGUgZ2l2ZW4gbmFtZSBhbmQgcHJlZml4LgorICAgICAqLworICAgIHB1YmxpYyBNYWlsTG9nZ2VyIGdldFN1YkxvZ2dlcihTdHJpbmcgc3VibmFtZSwgU3RyaW5nIHByZWZpeCkgeworCXJldHVybiBuZXcgTWFpbExvZ2dlcihsb2dnZXIuZ2V0TmFtZSgpICsgIi4iICsgc3VibmFtZSwgcHJlZml4LAorCQkJCWRlYnVnLCBvdXQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIE1haWxMb2dnZXIgdGhhdCB1c2VzIGEgTG9nZ2VyIHdob3NlIG5hbWUgaXMgY29tcG9zZWQKKyAgICAgKiBvZiB0aGlzIE1haWxMb2dnZXIncyBuYW1lIHBsdXMgdGhlIHNwZWNpZmllZCBzdWItbmFtZSwgc2VwYXJhdGVkCisgICAgICogYnkgYSBkb3QuICBUaGUgbmV3IE1haWxMb2dnZXIgdXNlcyB0aGUgbmV3IHByZWZpeCBmb3IgZGVidWcgb3V0cHV0LgorICAgICAqIFRoaXMgaXMgdXNlZCBwcmltYXJpbHkgYnkgdGhlIHByb3RvY29sIHRyYWNlIGNvZGUgdGhhdCB3YW50cyBhCisgICAgICogZGlmZmVyZW50IHByZWZpeCAobm9uZSkuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jc3VibmFtZQl0aGUgTG9nZ2VyIG5hbWUgcmVsYXRpdmUgdG8gdGhpcyBMb2dnZXIgbmFtZQorICAgICAqIEBwYXJhbQlwcmVmaXgJdGhlIHByZWZpeCBmb3IgZGVidWcgb3V0cHV0LCBvciBudWxsIGZvciBub25lCisgICAgICogQHBhcmFtCWRlYnVnCXRoZSBkZWJ1ZyBmbGFnIGZvciB0aGUgc3ViLWxvZ2dlcgorICAgICAqIEByZXR1cm4gYSBNYWlsTG9nZ2VyIGZvciB0aGUgZ2l2ZW4gbmFtZSBhbmQgcHJlZml4LgorICAgICAqLworICAgIHB1YmxpYyBNYWlsTG9nZ2VyIGdldFN1YkxvZ2dlcihTdHJpbmcgc3VibmFtZSwgU3RyaW5nIHByZWZpeCwKKwkJCQlib29sZWFuIGRlYnVnKSB7CisJcmV0dXJuIG5ldyBNYWlsTG9nZ2VyKGxvZ2dlci5nZXROYW1lKCkgKyAiLiIgKyBzdWJuYW1lLCBwcmVmaXgsCisJCQkJZGVidWcsIG91dCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTG9nIHRoZSBtZXNzYWdlIGF0IHRoZSBzcGVjaWZpZWQgbGV2ZWwuCisgICAgICogQHBhcmFtIGxldmVsIHRoZSBsb2cgbGV2ZWwuCisgICAgICogQHBhcmFtIG1zZyB0aGUgbWVzc2FnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBsb2coTGV2ZWwgbGV2ZWwsIFN0cmluZyBtc2cpIHsKKwlpZkRlYnVnT3V0KG1zZyk7CisJaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKGxldmVsKSkgeworCSAgICBmaW5hbCBTdGFja1RyYWNlRWxlbWVudCBmcmFtZSA9IGluZmVyQ2FsbGVyKCk7CisJICAgIGxvZ2dlci5sb2dwKGxldmVsLCBmcmFtZS5nZXRDbGFzc05hbWUoKSwgZnJhbWUuZ2V0TWV0aG9kTmFtZSgpLCBtc2cpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb2cgdGhlIG1lc3NhZ2UgYXQgdGhlIHNwZWNpZmllZCBsZXZlbC4KKyAgICAgKiBAcGFyYW0gbGV2ZWwgdGhlIGxvZyBsZXZlbC4KKyAgICAgKiBAcGFyYW0gbXNnIHRoZSBtZXNzYWdlLgorICAgICAqIEBwYXJhbSBwYXJhbTEgdGhlIGFkZGl0aW9uYWwgcGFyYW1ldGVyLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGxvZyhMZXZlbCBsZXZlbCwgU3RyaW5nIG1zZywgT2JqZWN0IHBhcmFtMSkgeworCWlmIChkZWJ1ZykgeworCSAgICBtc2cgPSBNZXNzYWdlRm9ybWF0LmZvcm1hdChtc2csIG5ldyBPYmplY3RbXSB7IHBhcmFtMSB9KTsKKwkgICAgZGVidWdPdXQobXNnKTsKKwl9CisJCisJaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKGxldmVsKSkgeworCSAgICBmaW5hbCBTdGFja1RyYWNlRWxlbWVudCBmcmFtZSA9IGluZmVyQ2FsbGVyKCk7CisJICAgIGxvZ2dlci5sb2dwKGxldmVsLCBmcmFtZS5nZXRDbGFzc05hbWUoKSwgZnJhbWUuZ2V0TWV0aG9kTmFtZSgpLCBtc2csIHBhcmFtMSk7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIExvZyB0aGUgbWVzc2FnZSBhdCB0aGUgc3BlY2lmaWVkIGxldmVsLgorICAgICAqIEBwYXJhbSBsZXZlbCB0aGUgbG9nIGxldmVsLgorICAgICAqIEBwYXJhbSBtc2cgdGhlIG1lc3NhZ2UuCisgICAgICogQHBhcmFtIHBhcmFtcyB0aGUgbWVzc2FnZSBwYXJhbWV0ZXJzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGxvZyhMZXZlbCBsZXZlbCwgU3RyaW5nIG1zZywgT2JqZWN0Li4uIHBhcmFtcykgeworCWlmIChkZWJ1ZykgeworCSAgICBtc2cgPSBNZXNzYWdlRm9ybWF0LmZvcm1hdChtc2csIHBhcmFtcyk7CisJICAgIGRlYnVnT3V0KG1zZyk7CisJfQorCQorCWlmIChsb2dnZXIuaXNMb2dnYWJsZShsZXZlbCkpIHsKKwkgICAgZmluYWwgU3RhY2tUcmFjZUVsZW1lbnQgZnJhbWUgPSBpbmZlckNhbGxlcigpOworCSAgICBsb2dnZXIubG9ncChsZXZlbCwgZnJhbWUuZ2V0Q2xhc3NOYW1lKCksIGZyYW1lLmdldE1ldGhvZE5hbWUoKSwgbXNnLCBwYXJhbXMpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb2cgdGhlIG1lc3NhZ2UgYXQgdGhlIHNwZWNpZmllZCBsZXZlbCB1c2luZyBhIGZvcm1hdCBzdHJpbmcuCisgICAgICogQHBhcmFtIGxldmVsIHRoZSBsb2cgbGV2ZWwuCisgICAgICogQHBhcmFtIG1zZyB0aGUgbWVzc2FnZSBmb3JtYXQgc3RyaW5nLgorICAgICAqIEBwYXJhbSBwYXJhbXMgdGhlIG1lc3NhZ2UgcGFyYW1ldGVycy4KKyAgICAgKgorICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjUuNAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGxvZ2YoTGV2ZWwgbGV2ZWwsIFN0cmluZyBtc2csIE9iamVjdC4uLiBwYXJhbXMpIHsKKwltc2cgPSBTdHJpbmcuZm9ybWF0KG1zZywgcGFyYW1zKTsKKwlpZkRlYnVnT3V0KG1zZyk7CisJbG9nZ2VyLmxvZyhsZXZlbCwgbXNnKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb2cgdGhlIG1lc3NhZ2UgYXQgdGhlIHNwZWNpZmllZCBsZXZlbC4KKyAgICAgKiBAcGFyYW0gbGV2ZWwgdGhlIGxvZyBsZXZlbC4KKyAgICAgKiBAcGFyYW0gbXNnIHRoZSBtZXNzYWdlLgorICAgICAqIEBwYXJhbSB0aHJvd24gdGhlIHRocm93YWJsZSB0byBsb2cuCisgICAgICovCisgICAgcHVibGljIHZvaWQgbG9nKExldmVsIGxldmVsLCBTdHJpbmcgbXNnLCBUaHJvd2FibGUgdGhyb3duKSB7CisJaWYgKGRlYnVnKSB7CisJICAgIGlmICh0aHJvd24gIT0gbnVsbCkgeworCQlkZWJ1Z091dChtc2cgKyAiLCBUSFJPVzogIik7CisJCXRocm93bi5wcmludFN0YWNrVHJhY2Uob3V0KTsKKwkgICAgfSBlbHNlIHsKKwkJZGVidWdPdXQobXNnKTsKKwkgICAgfQorCX0KKyAKKwlpZiAobG9nZ2VyLmlzTG9nZ2FibGUobGV2ZWwpKSB7CisJICAgIGZpbmFsIFN0YWNrVHJhY2VFbGVtZW50IGZyYW1lID0gaW5mZXJDYWxsZXIoKTsKKwkgICAgbG9nZ2VyLmxvZ3AobGV2ZWwsIGZyYW1lLmdldENsYXNzTmFtZSgpLCBmcmFtZS5nZXRNZXRob2ROYW1lKCksIG1zZywgdGhyb3duKTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogTG9nIGEgbWVzc2FnZSBhdCB0aGUgQ09ORklHIGxldmVsLgorICAgICAqIEBwYXJhbSBtc2cgdGhlIG1lc3NhZ2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgY29uZmlnKFN0cmluZyBtc2cpIHsKKwlsb2coTGV2ZWwuQ09ORklHLCBtc2cpOworICAgIH0KKworICAgIC8qKgorICAgICAqIExvZyBhIG1lc3NhZ2UgYXQgdGhlIEZJTkUgbGV2ZWwuCisgICAgICogQHBhcmFtIG1zZyB0aGUgbWVzc2FnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBmaW5lKFN0cmluZyBtc2cpIHsKKwlsb2coTGV2ZWwuRklORSwgbXNnKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb2cgYSBtZXNzYWdlIGF0IHRoZSBGSU5FUiBsZXZlbC4KKyAgICAgKiBAcGFyYW0gbXNnIHRoZSBtZXNzYWdlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGZpbmVyKFN0cmluZyBtc2cpIHsKKwlsb2coTGV2ZWwuRklORVIsIG1zZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTG9nIGEgbWVzc2FnZSBhdCB0aGUgRklORVNUIGxldmVsLgorICAgICAqIEBwYXJhbSBtc2cgdGhlIG1lc3NhZ2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgZmluZXN0KFN0cmluZyBtc2cpIHsKKwlsb2coTGV2ZWwuRklORVNULCBtc2cpOworICAgIH0KKworICAgIC8qKgorICAgICAqIElmICJkZWJ1ZyIgaXMgc2V0LCBvciBvdXIgZW1iZWRkZWQgTG9nZ2VyIGlzIGxvZ2dhYmxlIGF0IHRoZQorICAgICAqIGdpdmVuIGxldmVsLCByZXR1cm4gdHJ1ZS4KKyAgICAgKiBAcGFyYW0gbGV2ZWwgdGhlIGxvZyBsZXZlbC4KKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgbG9nZ2FibGUuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNMb2dnYWJsZShMZXZlbCBsZXZlbCkgeworCXJldHVybiBkZWJ1ZyB8fCBsb2dnZXIuaXNMb2dnYWJsZShsZXZlbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tbW9uIGNvZGUgdG8gY29uZGl0aW9uYWxseSBsb2cgZGVidWcgc3RhdGVtZW50cy4KKyAgICAgKiBAcGFyYW0gbXNnIHRoZSBtZXNzYWdlIHRvIGxvZy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgaWZEZWJ1Z091dChTdHJpbmcgbXNnKSB7CisJaWYgKGRlYnVnKQorCSAgICBkZWJ1Z091dChtc2cpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbW1vbiBmb3JtYXR0aW5nIGZvciBkZWJ1ZyBvdXRwdXQuCisgICAgICogQHBhcmFtIG1zZyB0aGUgbWVzc2FnZSB0byBsb2cuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGRlYnVnT3V0KFN0cmluZyBtc2cpIHsKKwlpZiAocHJlZml4ICE9IG51bGwpCisJICAgIG91dC5wcmludGxuKHByZWZpeCArICI6ICIgKyBtc2cpOworCWVsc2UKKwkgICAgb3V0LnByaW50bG4obXNnKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIHBhY2thZ2UgbmFtZSBvZiB0aGUgY2xhc3MuCisgICAgICogU29tZXRpbWVzIHRoZXJlIHdpbGwgYmUgbm8gUGFja2FnZSBvYmplY3QgZm9yIHRoZSBjbGFzcywKKyAgICAgKiBlLmcuLCBpZiB0aGUgY2xhc3MgbG9hZGVyIGhhc24ndCBjcmVhdGVkIG9uZSAoc2VlIENsYXNzLmdldFBhY2thZ2UoKSkuCisgICAgICogQHBhcmFtIGNsYXp6IHRoZSBjbGFzcyBzb3VyY2UuCisgICAgICogQHJldHVybiB0aGUgcGFja2FnZSBuYW1lIG9yIGFuIGVtcHR5IHN0cmluZy4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyBwYWNrYWdlT2YoQ2xhc3M8Pz4gY2xhenopIHsKKwlQYWNrYWdlIHAgPSBjbGF6ei5nZXRQYWNrYWdlKCk7CisJaWYgKHAgIT0gbnVsbCkKKwkgICAgcmV0dXJuIHAuZ2V0TmFtZSgpOwkJLy8gaG9wZWZ1bGx5IHRoZSBjb21tb24gY2FzZQorCVN0cmluZyBjbmFtZSA9IGNsYXp6LmdldE5hbWUoKTsKKwlpbnQgaSA9IGNuYW1lLmxhc3RJbmRleE9mKCcuJyk7CisJaWYgKGkgPiAwKQorCSAgICByZXR1cm4gY25hbWUuc3Vic3RyaW5nKDAsIGkpOworCS8vIG5vIHBhY2thZ2UgbmFtZSwgbm93IHdoYXQ/CisJcmV0dXJuICIiOworICAgIH0KKworICAgIC8qKgorICAgICAqIEEgZGlzYWR2YW50YWdlIG9mIG5vdCBiZWluZyBhYmxlIHRvIHVzZSBMb2dnZXIgZGlyZWN0bHkgaW4gSmF2YU1haWwKKyAgICAgKiBjb2RlIGlzIHRoYXQgdGhlICJzb3VyY2UgY2xhc3MiIGluZm9ybWF0aW9uIHRoYXQgTG9nZ2VyIGd1ZXNzZXMgd2lsbAorICAgICAqIGFsd2F5cyByZWZlciB0byB0aGlzIGNsYXNzIGluc3RlYWQgb2Ygb3VyIGNhbGxlci4gIFRoaXMgbWV0aG9kCisgICAgICogZHVwbGljYXRlcyB3aGF0IExvZ2dlciBkb2VzIHRvIHRyeSB0byBmaW5kICpvdXIqIGNhbGxlciwgc28gdGhhdAorICAgICAqIExvZ2dlciBkb2Vzbid0IGhhdmUgdG8gZG8gaXQgKGFuZCBnZXQgdGhlIHdyb25nIGFuc3dlciksIGFuZCBiZWNhdXNlCisgICAgICogb3VyIGNhbGxlciBpcyB3aGF0J3Mgd2FudGVkLgorICAgICAqIEByZXR1cm4gU3RhY2tUcmFjZUVsZW1lbnQgdGhhdCBsb2dnZWQgdGhlIG1lc3NhZ2UuICBUcmVhdCBhcyByZWFkLW9ubHkuCisgICAgICovCisgICAgcHJpdmF0ZSBTdGFja1RyYWNlRWxlbWVudCBpbmZlckNhbGxlcigpIHsKKwkvLyBHZXQgdGhlIHN0YWNrIHRyYWNlLgorCVN0YWNrVHJhY2VFbGVtZW50IHN0YWNrW10gPSAobmV3IFRocm93YWJsZSgpKS5nZXRTdGFja1RyYWNlKCk7CisJLy8gRmlyc3QsIHNlYXJjaCBiYWNrIHRvIGEgbWV0aG9kIGluIHRoZSBMb2dnZXIgY2xhc3MuCisJaW50IGl4ID0gMDsKKwl3aGlsZSAoaXggPCBzdGFjay5sZW5ndGgpIHsKKwkgICAgU3RhY2tUcmFjZUVsZW1lbnQgZnJhbWUgPSBzdGFja1tpeF07CisJICAgIFN0cmluZyBjbmFtZSA9IGZyYW1lLmdldENsYXNzTmFtZSgpOworCSAgICBpZiAoaXNMb2dnZXJJbXBsRnJhbWUoY25hbWUpKSB7CisJCWJyZWFrOworCSAgICB9CisJICAgIGl4Kys7CisJfQorCS8vIE5vdyBzZWFyY2ggZm9yIHRoZSBmaXJzdCBmcmFtZSBiZWZvcmUgdGhlICJMb2dnZXIiIGNsYXNzLgorCXdoaWxlIChpeCA8IHN0YWNrLmxlbmd0aCkgeworCSAgICBTdGFja1RyYWNlRWxlbWVudCBmcmFtZSA9IHN0YWNrW2l4XTsKKwkgICAgU3RyaW5nIGNuYW1lID0gZnJhbWUuZ2V0Q2xhc3NOYW1lKCk7CisJICAgIGlmICghaXNMb2dnZXJJbXBsRnJhbWUoY25hbWUpKSB7CisJCS8vIFdlJ3ZlIGZvdW5kIHRoZSByZWxldmFudCBmcmFtZS4KKwkJcmV0dXJuIGZyYW1lOworCSAgICB9CisJICAgIGl4Kys7CisJfQorCS8vIFdlIGhhdmVuJ3QgZm91bmQgYSBzdWl0YWJsZSBmcmFtZSwgc28ganVzdCBwdW50LiAgVGhpcyBpcworCS8vIE9LIGFzIHdlIGFyZSBvbmx5IGNvbW1pdHRlZCB0byBtYWtpbmcgYSAiYmVzdCBlZmZvcnQiIGhlcmUuCisJcmV0dXJuIG5ldyBTdGFja1RyYWNlRWxlbWVudChNYWlsTG9nZ2VyLmNsYXNzLmdldE5hbWUoKSwgImxvZyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1haWxMb2dnZXIuY2xhc3MuZ2V0TmFtZSgpLCAtMSk7CisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIEZyYW1lcyB0byBpZ25vcmUgYXMgcGFydCBvZiB0aGUgTWFpbExvZ2dlciB0byBKVUwgYnJpZGdlLgorICAgICAqIEBwYXJhbSBjbmFtZSB0aGUgY2xhc3MgbmFtZS4KKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGNsYXNzIG5hbWUgaXMgcGFydCBvZiB0aGUgTWFpbExvZ2dlciBicmlkZ2UuCisgICAgICovCisgICAgcHJpdmF0ZSBib29sZWFuIGlzTG9nZ2VySW1wbEZyYW1lKFN0cmluZyBjbmFtZSkgeworCXJldHVybiBNYWlsTG9nZ2VyLmNsYXNzLmdldE5hbWUoKS5lcXVhbHMoY25hbWUpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvdXRpbC9NYWlsU1NMU29ja2V0RmFjdG9yeS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL01haWxTU0xTb2NrZXRGYWN0b3J5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjcxNWYzNgotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvdXRpbC9NYWlsU1NMU29ja2V0RmFjdG9yeS5qYXZhCkBAIC0wLDAgKzEsMzU2IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC51dGlsOworCitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmEubmV0Lio7CitpbXBvcnQgamF2YS5zZWN1cml0eS4qOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC4qOworaW1wb3J0IGphdmEudXRpbC4qOworCitpbXBvcnQgamF2YXgubmV0LnNzbC4qOworCisvKioKKyAqIEFuIFNTTCBzb2NrZXQgZmFjdG9yeSB0aGF0IG1ha2VzIGl0IGVhc2llciB0byBzcGVjaWZ5IHRydXN0LgorICogVGhpcyBzb2NrZXQgZmFjdG9yeSBjYW4gYmUgY29uZmlndXJlZCB0byB0cnVzdCBhbGwgaG9zdHMgb3IKKyAqIHRydXN0IGEgc3BlY2lmaWMgc2V0IG9mIGhvc3RzLCBpbiB3aGljaCBjYXNlIHRoZSBzZXJ2ZXIncworICogY2VydGlmaWNhdGUgaXNuJ3QgdmVyaWZpZWQuICBBbHRlcm5hdGl2ZWx5LCBhIGN1c3RvbSBUcnVzdE1hbmFnZXIKKyAqIGNhbiBiZSBzdXBwbGllZC4gPHA+CisgKgorICogQW4gaW5zdGFuY2Ugb2YgdGhpcyBmYWN0b3J5IGNhbiBiZSBzZXQgYXMgdGhlIHZhbHVlIG9mIHRoZQorICogPGNvZGU+bWFpbC4mbHQ7cHJvdG9jb2wmZ3Q7LnNzbC5zb2NrZXRGYWN0b3J5PC9jb2RlPiBwcm9wZXJ0eS4KKyAqCisgKiBAc2luY2UJSmF2YU1haWwgMS40LjIKKyAqIEBhdXRob3IJU3RlcGhhbiBTYW5uCisgKiBAYXV0aG9yCUJpbGwgU2hhbm5vbgorICovCitwdWJsaWMgY2xhc3MgTWFpbFNTTFNvY2tldEZhY3RvcnkgZXh0ZW5kcyBTU0xTb2NrZXRGYWN0b3J5IHsKKworICAgIC8qKiBTaG91bGQgYWxsIGhvc3RzIGJlIHRydXN0ZWQ/ICovCisgICAgcHJpdmF0ZSBib29sZWFuIHRydXN0QWxsSG9zdHM7CisKKyAgICAvKiogU3RyaW5nLWFycmF5IG9mIHRydXN0ZWQgaG9zdHMgKi8KKyAgICBwcml2YXRlIFN0cmluZ1tdIHRydXN0ZWRIb3N0cyA9IG51bGw7CisKKyAgICAvKiogSG9sZHMgYSBTU0xDb250ZXh0IHRvIGdldCBTU0xTb2NrZXRGYWN0b3JpZXMgZnJvbSAqLworICAgIHByaXZhdGUgU1NMQ29udGV4dCBzc2xjb250ZXh0OworCisgICAgLyoqIEhvbGRzIHRoZSBLZXlNYW5hZ2VyIGFycmF5IHRvIHVzZSAqLworICAgIHByaXZhdGUgS2V5TWFuYWdlcltdIGtleU1hbmFnZXJzOworCisgICAgLyoqIEhvbGRzIHRoZSBUcnVzdE1hbmFnZXIgYXJyYXkgdG8gdXNlICovCisgICAgcHJpdmF0ZSBUcnVzdE1hbmFnZXJbXSB0cnVzdE1hbmFnZXJzOworCisgICAgLyoqIEhvbGRzIHRoZSBTZWN1cmVSYW5kb20gdG8gdXNlICovCisgICAgcHJpdmF0ZSBTZWN1cmVSYW5kb20gc2VjdXJlUmFuZG9tOworCisgICAgLyoqIEhvbGRzIGEgU1NMU29ja2V0RmFjdG9yeSB0byBwYXNzIGFsbCBBUEktbWV0aG9kLWNhbGxzIHRvICovCisgICAgcHJpdmF0ZSBTU0xTb2NrZXRGYWN0b3J5IGFkYXB0ZWVGYWN0b3J5ID0gbnVsbDsKKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemVzIGEgbmV3IE1haWxTU0xTb2NrZXRGYWN0b3J5LgorICAgICAqIAorICAgICAqIEB0aHJvd3MgIEdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbiBmb3Igc2VjdXJpdHkgZXJyb3JzCisgICAgICovCisgICAgcHVibGljIE1haWxTU0xTb2NrZXRGYWN0b3J5KCkgdGhyb3dzIEdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbiB7CisJdGhpcygiVExTIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZXMgYSBuZXcgTWFpbFNTTFNvY2tldEZhY3Rvcnkgd2l0aCBhIGdpdmVuIHByb3RvY29sLgorICAgICAqIE5vcm1hbGx5IHRoZSBwcm90b2NvbCB3aWxsIGJlIHNwZWNpZmllZCBhcyAiVExTIi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gICBwcm90b2NvbCAgVGhlIHByb3RvY29sIHRvIHVzZQorICAgICAqIEB0aHJvd3MgIE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBpZiBnaXZlbiBwcm90b2NvbCBpcyBub3Qgc3VwcG9ydGVkCisgICAgICogQHRocm93cyAgR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uIGZvciBzZWN1cml0eSBlcnJvcnMKKyAgICAgKi8KKyAgICBwdWJsaWMgTWFpbFNTTFNvY2tldEZhY3RvcnkoU3RyaW5nIHByb3RvY29sKQorCQkJCXRocm93cyBHZW5lcmFsU2VjdXJpdHlFeGNlcHRpb24geworCisJLy8gQnkgZGVmYXVsdCB3ZSBkbyBOT1QgdHJ1c3QgYWxsIGhvc3RzLgorCXRydXN0QWxsSG9zdHMgPSBmYWxzZTsKKworCS8vIEdldCBhbiBpbnN0YW5jZSBvZiBhbiBTU0xDb250ZXh0LgorCXNzbGNvbnRleHQgPSBTU0xDb250ZXh0LmdldEluc3RhbmNlKHByb3RvY29sKTsKKworCS8vIERlZmF1bHQgcHJvcGVydGllcyB0byBpbml0IHRoZSBTU0xDb250ZXh0CisJa2V5TWFuYWdlcnMgPSBudWxsOworCXRydXN0TWFuYWdlcnMgPSBuZXcgVHJ1c3RNYW5hZ2VyW10geyBuZXcgTWFpbFRydXN0TWFuYWdlcigpIH07CisJc2VjdXJlUmFuZG9tID0gbnVsbDsKKworCS8vIEFzc2VtYmxlIGEgZGVmYXVsdCBTU0xTb2NrZXRGYWN0b3J5IHRvIGRlbGVnYXRlIGFsbCBBUEktY2FsbHMgdG8uCisJbmV3QWRhcHRlZUZhY3RvcnkoKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIEdldHMgYW4gU1NMU29ja2V0RmFjdG9yeSBiYXNlZCBvbiB0aGUgZ2l2ZW4gKG9yIGRlZmF1bHQpCisgICAgICogS2V5TWFuYWdlciBhcnJheSwgVHJ1c3RNYW5hZ2VyIGFycmF5IGFuZCBTZWN1cmVSYW5kb20gYW5kCisgICAgICogc2V0cyBpdCB0byB0aGUgaW5zdGFuY2UgdmFyIGFkYXB0ZWVGYWN0b3J5LgorICAgICAqCisgICAgICogQHRocm93cwlLZXlNYW5hZ2VtZW50RXhjZXB0aW9uIGZvciBrZXkgbWFuYWdlciBlcnJvcnMKKyAgICAgKi8KKyAgICBwcml2YXRlIHN5bmNocm9uaXplZCB2b2lkIG5ld0FkYXB0ZWVGYWN0b3J5KCkKKwkJCQl0aHJvd3MgS2V5TWFuYWdlbWVudEV4Y2VwdGlvbiB7CisJc3NsY29udGV4dC5pbml0KGtleU1hbmFnZXJzLCB0cnVzdE1hbmFnZXJzLCBzZWN1cmVSYW5kb20pOworCisJLy8gR2V0IFNvY2tldEZhY3RvcnkgYW5kIHNhdmUgaXQgaW4gb3VyIGluc3RhbmNlIHZhcgorCWFkYXB0ZWVGYWN0b3J5ID0gc3NsY29udGV4dC5nZXRTb2NrZXRGYWN0b3J5KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHJldHVybiB0aGUga2V5TWFuYWdlcnMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIEtleU1hbmFnZXJbXSBnZXRLZXlNYW5hZ2VycygpIHsKKwlyZXR1cm4ga2V5TWFuYWdlcnMuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcGFyYW0ga2V5TWFuYWdlcnMgdGhlIGtleU1hbmFnZXJzIHRvIHNldAorICAgICAqIEB0aHJvd3MgIEdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbiBmb3Igc2VjdXJpdHkgZXJyb3JzCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHNldEtleU1hbmFnZXJzKEtleU1hbmFnZXJbXSBrZXlNYW5hZ2VycykKKwkJCQl0aHJvd3MgR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uICB7CisJdGhpcy5rZXlNYW5hZ2VycyA9IGtleU1hbmFnZXJzLmNsb25lKCk7CisJbmV3QWRhcHRlZUZhY3RvcnkoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcmV0dXJuIHRoZSBzZWN1cmVSYW5kb20KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIFNlY3VyZVJhbmRvbSBnZXRTZWN1cmVSYW5kb20oKSB7CisJcmV0dXJuIHNlY3VyZVJhbmRvbTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gc2VjdXJlUmFuZG9tIHRoZSBzZWN1cmVSYW5kb20gdG8gc2V0CisgICAgICogQHRocm93cyAgR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uIGZvciBzZWN1cml0eSBlcnJvcnMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgc2V0U2VjdXJlUmFuZG9tKFNlY3VyZVJhbmRvbSBzZWN1cmVSYW5kb20pCisJCQkJdGhyb3dzIEdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbiAgeworCXRoaXMuc2VjdXJlUmFuZG9tID0gc2VjdXJlUmFuZG9tOworCW5ld0FkYXB0ZWVGYWN0b3J5KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHJldHVybiB0aGUgdHJ1c3RNYW5hZ2VycworICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgVHJ1c3RNYW5hZ2VyW10gZ2V0VHJ1c3RNYW5hZ2VycygpIHsKKwlyZXR1cm4gdHJ1c3RNYW5hZ2VyczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gdHJ1c3RNYW5hZ2VycyB0aGUgdHJ1c3RNYW5hZ2VycyB0byBzZXQKKyAgICAgKiBAdGhyb3dzICBHZW5lcmFsU2VjdXJpdHlFeGNlcHRpb24gZm9yIHNlY3VyaXR5IGVycm9ycworICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXRUcnVzdE1hbmFnZXJzKFRydXN0TWFuYWdlcltdIHRydXN0TWFuYWdlcnMpCisJCQkJdGhyb3dzIEdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbiB7CisJdGhpcy50cnVzdE1hbmFnZXJzID0gdHJ1c3RNYW5hZ2VyczsKKwluZXdBZGFwdGVlRmFjdG9yeSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEByZXR1cm4JdHJ1ZSBpZiBhbGwgaG9zdHMgc2hvdWxkIGJlIHRydXN0ZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGJvb2xlYW4gaXNUcnVzdEFsbEhvc3RzKCkgeworCXJldHVybiB0cnVzdEFsbEhvc3RzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBwYXJhbQl0cnVzdEFsbEhvc3RzIHNob3VsZCBhbGwgaG9zdHMgYmUgdHJ1c3RlZD8KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgc2V0VHJ1c3RBbGxIb3N0cyhib29sZWFuIHRydXN0QWxsSG9zdHMpIHsKKwl0aGlzLnRydXN0QWxsSG9zdHMgPSB0cnVzdEFsbEhvc3RzOworICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiBAcmV0dXJuCXRoZSB0cnVzdGVkIGhvc3RzCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBTdHJpbmdbXSBnZXRUcnVzdGVkSG9zdHMoKSB7CisJaWYgKHRydXN0ZWRIb3N0cyA9PSBudWxsKQorCSAgICByZXR1cm4gbnVsbDsKKwllbHNlCisJICAgIHJldHVybiB0cnVzdGVkSG9zdHMuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcGFyYW0JdHJ1c3RlZEhvc3RzIHRoZSBob3N0cyB0byB0cnVzdAorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXRUcnVzdGVkSG9zdHMoU3RyaW5nW10gdHJ1c3RlZEhvc3RzKSB7CisJaWYgKHRydXN0ZWRIb3N0cyA9PSBudWxsKQorCSAgICB0aGlzLnRydXN0ZWRIb3N0cyA9IG51bGw7CisJZWxzZQorCSAgICB0aGlzLnRydXN0ZWRIb3N0cyA9IHRydXN0ZWRIb3N0cy5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFmdGVyIGEgc3VjY2Vzc2Z1bCBjb25lY3Rpb24gdG8gdGhlIHNlcnZlciwgdGhpcyBtZXRob2QgaXMKKyAgICAgKiBjYWxsZWQgdG8gZW5zdXJlIHRoYXQgdGhlIHNlcnZlciBzaG91bGQgYmUgdHJ1c3RlZC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0Jc2VydmVyCQluYW1lIG9mIHRoZSBzZXJ2ZXIgd2UgY29ubmVjdGVkIHRvCisgICAgICogQHBhcmFtICAgc3NsU29ja2V0CVNTTFNvY2tldCBjb25uZWN0ZWQgdG8gdGhlIHNlcnZlcgorICAgICAqIEByZXR1cm4gIHRydWUgIGlmICJ0cnVzdEFsbEhvc3RzIiBpcyBzZXQgdG8gdHJ1ZSBPUiB0aGUgc2VydmVyCisgICAgICoJCWlzIGNvbnRhaW5lZCBpbiB0aGUgInRydXN0ZWRIb3N0cyIgYXJyYXk7CisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIGlzU2VydmVyVHJ1c3RlZChTdHJpbmcgc2VydmVyLAorCQkJCVNTTFNvY2tldCBzc2xTb2NrZXQpIHsKKworCS8vU3lzdGVtLm91dC5wcmludGxuKCJERUJVRzogaXNTZXJ2ZXJUcnVzdGVkIGhvc3QgIiArIHNlcnZlcik7CisKKwkvLyBJZiAidHJ1c3RBbGxIb3N0cyIgaXMgc2V0IHRvIHRydWUsIHdlIHJldHVybiB0cnVlCisJaWYgKHRydXN0QWxsSG9zdHMpCisJICAgIHJldHVybiB0cnVlOworCisJLy8gSWYgdGhlIHNvY2tldCBob3N0IGlzIGNvbnRhaW5lZCBpbiB0aGUgInRydXN0ZWRIb3N0cyIgYXJyYXksCisJLy8gd2UgcmV0dXJuIHRydWUKKwlpZiAodHJ1c3RlZEhvc3RzICE9IG51bGwpCisJICAgIHJldHVybiBBcnJheXMuYXNMaXN0KHRydXN0ZWRIb3N0cykuY29udGFpbnMoc2VydmVyKTsgLy8gaWdub3JlIGNhc2U/CisKKwkvLyBJZiB3ZSBnZXQgaGVyZSwgdHJ1c3Qgb2YgdGhlIHNlcnZlciB3YXMgdmVyaWZpZWQgYnkgdGhlIHRydXN0IG1hbmFnZXIKKwlyZXR1cm4gdHJ1ZTsKKyAgICB9CisKKworICAgIC8vIFNvY2tldEZhY3RvcnkgbWV0aG9kcworCisgICAgLyogKG5vbi1KYXZhZG9jKQorICAgICAqIEBzZWUgamF2YXgubmV0LnNzbC5TU0xTb2NrZXRGYWN0b3J5I2NyZWF0ZVNvY2tldChqYXZhLm5ldC5Tb2NrZXQsCisgICAgICoJCQkJCQlqYXZhLmxhbmcuU3RyaW5nLCBpbnQsIGJvb2xlYW4pCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBTb2NrZXQgY3JlYXRlU29ja2V0KFNvY2tldCBzb2NrZXQsIFN0cmluZyBzLCBpbnQgaSwKKwkJCQlib29sZWFuIGZsYWcpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJcmV0dXJuIGFkYXB0ZWVGYWN0b3J5LmNyZWF0ZVNvY2tldChzb2NrZXQsIHMsIGksIGZsYWcpOworICAgIH0KKworICAgIC8qIChub24tSmF2YWRvYykKKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuU1NMU29ja2V0RmFjdG9yeSNnZXREZWZhdWx0Q2lwaGVyU3VpdGVzKCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIFN0cmluZ1tdIGdldERlZmF1bHRDaXBoZXJTdWl0ZXMoKSB7CisJcmV0dXJuIGFkYXB0ZWVGYWN0b3J5LmdldERlZmF1bHRDaXBoZXJTdWl0ZXMoKTsKKyAgICB9CisKKyAgICAvKiAobm9uLUphdmFkb2MpCisgICAgICogQHNlZSBqYXZheC5uZXQuc3NsLlNTTFNvY2tldEZhY3RvcnkjZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVzKCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIFN0cmluZ1tdIGdldFN1cHBvcnRlZENpcGhlclN1aXRlcygpIHsKKwlyZXR1cm4gYWRhcHRlZUZhY3RvcnkuZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVzKCk7CisgICAgfQorCisgICAgLyogKG5vbi1KYXZhZG9jKQorICAgICAqIEBzZWUgamF2YXgubmV0LlNvY2tldEZhY3RvcnkjY3JlYXRlU29ja2V0KCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIFNvY2tldCBjcmVhdGVTb2NrZXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCXJldHVybiBhZGFwdGVlRmFjdG9yeS5jcmVhdGVTb2NrZXQoKTsKKyAgICB9CisKKyAgICAvKiAobm9uLUphdmFkb2MpCisgICAgICogQHNlZSBqYXZheC5uZXQuU29ja2V0RmFjdG9yeSNjcmVhdGVTb2NrZXQoamF2YS5uZXQuSW5ldEFkZHJlc3MsIGludCwKKyAgICAgKgkJCQkJCWphdmEubmV0LkluZXRBZGRyZXNzLCBpbnQpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBTb2NrZXQgY3JlYXRlU29ja2V0KEluZXRBZGRyZXNzIGluZXRhZGRyZXNzLCBpbnQgaSwKKwkJCUluZXRBZGRyZXNzIGluZXRhZGRyZXNzMSwgaW50IGopIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJcmV0dXJuIGFkYXB0ZWVGYWN0b3J5LmNyZWF0ZVNvY2tldChpbmV0YWRkcmVzcywgaSwgaW5ldGFkZHJlc3MxLCBqKTsKKyAgICB9CisKKyAgICAvKiAobm9uLUphdmFkb2MpCisgICAgICogQHNlZSBqYXZheC5uZXQuU29ja2V0RmFjdG9yeSNjcmVhdGVTb2NrZXQoamF2YS5uZXQuSW5ldEFkZHJlc3MsIGludCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIFNvY2tldCBjcmVhdGVTb2NrZXQoSW5ldEFkZHJlc3MgaW5ldGFkZHJlc3MsIGludCBpKQorCQkJCXRocm93cyBJT0V4Y2VwdGlvbiB7CisJcmV0dXJuIGFkYXB0ZWVGYWN0b3J5LmNyZWF0ZVNvY2tldChpbmV0YWRkcmVzcywgaSk7CisgICAgfQorCisgICAgLyogKG5vbi1KYXZhZG9jKQorICAgICAqIEBzZWUgamF2YXgubmV0LlNvY2tldEZhY3RvcnkjY3JlYXRlU29ja2V0KGphdmEubGFuZy5TdHJpbmcsIGludCwKKyAgICAgKgkJCQkJCWphdmEubmV0LkluZXRBZGRyZXNzLCBpbnQpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBTb2NrZXQgY3JlYXRlU29ja2V0KFN0cmluZyBzLCBpbnQgaSwKKwkJCQlJbmV0QWRkcmVzcyBpbmV0YWRkcmVzcywgaW50IGopCisJCQkJdGhyb3dzIElPRXhjZXB0aW9uLCBVbmtub3duSG9zdEV4Y2VwdGlvbiB7CisJcmV0dXJuIGFkYXB0ZWVGYWN0b3J5LmNyZWF0ZVNvY2tldChzLCBpLCBpbmV0YWRkcmVzcywgaik7CisgICAgfQorCisgICAgLyogKG5vbi1KYXZhZG9jKQorICAgICAqIEBzZWUgamF2YXgubmV0LlNvY2tldEZhY3RvcnkjY3JlYXRlU29ja2V0KGphdmEubGFuZy5TdHJpbmcsIGludCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIFNvY2tldCBjcmVhdGVTb2NrZXQoU3RyaW5nIHMsIGludCBpKQorCQkJCXRocm93cyBJT0V4Y2VwdGlvbiwgVW5rbm93bkhvc3RFeGNlcHRpb24geworCXJldHVybiBhZGFwdGVlRmFjdG9yeS5jcmVhdGVTb2NrZXQocywgaSk7CisgICAgfQorCisKKyAgICAvLyBpbm5lciBjbGFzc2VzCisKKyAgICAvKioKKyAgICAgKiBBIGRlZmF1bHQgVHJ1c3RtYW5hZ2VyLgorICAgICAqIAorICAgICAqIEBhdXRob3IgIFN0ZXBoYW4gU2FubgorICAgICAqLworICAgIHByaXZhdGUgY2xhc3MgTWFpbFRydXN0TWFuYWdlciBpbXBsZW1lbnRzIFg1MDlUcnVzdE1hbmFnZXIgeworCisJLyoqIEEgVHJ1c3RNYW5hZ2VyIHRvIHBhc3MgbWV0aG9kIGNhbGxzIHRvICovCisJcHJpdmF0ZSBYNTA5VHJ1c3RNYW5hZ2VyIGFkYXB0ZWVUcnVzdE1hbmFnZXIgPSBudWxsOworCisJLyoqCisJICogSW5pdGlhbGl6ZXMgYSBuZXcgVHJ1c3RNYW5hZ2VyIGluc3RhbmNlLgorCSAqLworCXByaXZhdGUgTWFpbFRydXN0TWFuYWdlcigpIHRocm93cyBHZW5lcmFsU2VjdXJpdHlFeGNlcHRpb24geworCSAgICBUcnVzdE1hbmFnZXJGYWN0b3J5IHRtZiA9IFRydXN0TWFuYWdlckZhY3RvcnkuZ2V0SW5zdGFuY2UoIlg1MDkiKTsKKwkgICAgdG1mLmluaXQoKEtleVN0b3JlKW51bGwpOworCSAgICBhZGFwdGVlVHJ1c3RNYW5hZ2VyID0gKFg1MDlUcnVzdE1hbmFnZXIpdG1mLmdldFRydXN0TWFuYWdlcnMoKVswXTsKKwl9CisKKwkvKiAobm9uLUphdmFkb2MpCisJICogQHNlZSBqYXZheC5uZXQuc3NsLlg1MDlUcnVzdE1hbmFnZXIjY2hlY2tDbGllbnRUcnVzdGVkKAorCSAqCQlqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlW10sIGphdmEubGFuZy5TdHJpbmcpCisJICovCisJQE92ZXJyaWRlCisJcHVibGljIHZvaWQgY2hlY2tDbGllbnRUcnVzdGVkKFg1MDlDZXJ0aWZpY2F0ZVtdIGNlcnRzLCBTdHJpbmcgYXV0aFR5cGUpCisJCQkJCXRocm93cyBDZXJ0aWZpY2F0ZUV4Y2VwdGlvbiB7CisJICAgIGlmICghKGlzVHJ1c3RBbGxIb3N0cygpIHx8IGdldFRydXN0ZWRIb3N0cygpICE9IG51bGwpKQorCQlhZGFwdGVlVHJ1c3RNYW5hZ2VyLmNoZWNrQ2xpZW50VHJ1c3RlZChjZXJ0cywgYXV0aFR5cGUpOworCX0KKworCS8qIChub24tSmF2YWRvYykKKwkgKiBAc2VlIGphdmF4Lm5ldC5zc2wuWDUwOVRydXN0TWFuYWdlciNjaGVja1NlcnZlclRydXN0ZWQoCisJICoJCWphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGVbXSwgamF2YS5sYW5nLlN0cmluZykKKwkgKi8KKwlAT3ZlcnJpZGUKKwlwdWJsaWMgdm9pZCBjaGVja1NlcnZlclRydXN0ZWQoWDUwOUNlcnRpZmljYXRlW10gY2VydHMsIFN0cmluZyBhdXRoVHlwZSkKKwkJCQkJdGhyb3dzIENlcnRpZmljYXRlRXhjZXB0aW9uIHsKKworCSAgICBpZiAoIShpc1RydXN0QWxsSG9zdHMoKSB8fCBnZXRUcnVzdGVkSG9zdHMoKSAhPSBudWxsKSkKKwkJYWRhcHRlZVRydXN0TWFuYWdlci5jaGVja1NlcnZlclRydXN0ZWQoY2VydHMsIGF1dGhUeXBlKTsKKwl9CisKKwkvKiAobm9uLUphdmFkb2MpCisJICogQHNlZSBqYXZheC5uZXQuc3NsLlg1MDlUcnVzdE1hbmFnZXIjZ2V0QWNjZXB0ZWRJc3N1ZXJzKCkKKwkgKi8KKwlAT3ZlcnJpZGUKKwlwdWJsaWMgWDUwOUNlcnRpZmljYXRlW10gZ2V0QWNjZXB0ZWRJc3N1ZXJzKCkgeworCSAgICByZXR1cm4gYWRhcHRlZVRydXN0TWFuYWdlci5nZXRBY2NlcHRlZElzc3VlcnMoKTsKKwl9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL01lc3NhZ2VSZW1vdmVkSU9FeGNlcHRpb24uamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvdXRpbC9NZXNzYWdlUmVtb3ZlZElPRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTY4NDBmNwotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvdXRpbC9NZXNzYWdlUmVtb3ZlZElPRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0OSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwudXRpbDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKy8qKgorICogQSB2YXJpYW50IG9mIE1lc3NhZ2VSZW1vdmVkRXhjZXB0aW9uIHRoYXQgY2FuIGJlIHRocm93biBmcm9tIG1ldGhvZHMKKyAqIHRoYXQgb25seSB0aHJvdyBJT0V4Y2VwdGlvbi4gIFRoZSBnZXRDb250ZW50IG1ldGhvZCB3aWxsIGNhdGNoIHRoaXMKKyAqIGV4Y2VwdGlvbiBhbmQgdHJhbnNsYXRlIGl0IGJhY2sgdG8gTWVzc2FnZVJlbW92ZWRFeGNlcHRpb24uCisgKgorICogQHNlZQkgICBqYXZheC5tYWlsLk1lc3NhZ2UjaXNFeHB1bmdlZCgpCisgKiBAc2VlCSAgIGphdmF4Lm1haWwuTWVzc2FnZSNnZXRNZXNzYWdlTnVtYmVyKCkKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKi8KKworcHVibGljIGNsYXNzIE1lc3NhZ2VSZW1vdmVkSU9FeGNlcHRpb24gZXh0ZW5kcyBJT0V4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA0MjgwNDY4MDI2NTgxNjE2NDI0TDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBNZXNzYWdlUmVtb3ZlZElPRXhjZXB0aW9uIHdpdGggbm8gZGV0YWlsIG1lc3NhZ2UuCisgICAgICovCisgICAgcHVibGljIE1lc3NhZ2VSZW1vdmVkSU9FeGNlcHRpb24oKSB7CisJc3VwZXIoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgTWVzc2FnZVJlbW92ZWRJT0V4Y2VwdGlvbiB3aXRoIHRoZSBzcGVjaWZpZWQgZGV0YWlsIG1lc3NhZ2UuCisgICAgICogQHBhcmFtIHMJCXRoZSBkZXRhaWwgbWVzc2FnZQorICAgICAqLworICAgIHB1YmxpYyBNZXNzYWdlUmVtb3ZlZElPRXhjZXB0aW9uKFN0cmluZyBzKSB7CisJc3VwZXIocyk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL01pbWVVdGlsLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvTWltZVV0aWwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42OTQ0MjQ5Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL01pbWVVdGlsLmphdmEKQEAgLTAsMCArMSwxMDQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMTAsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLnV0aWw7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC4qOworaW1wb3J0IGphdmEuc2VjdXJpdHkuKjsKKworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuTWltZVBhcnQ7CisKKy8qKgorICogR2VuZXJhbCBNSU1FLXJlbGF0ZWQgdXRpbGl0eSBtZXRob2RzLgorICoKKyAqIEBhdXRob3IJQmlsbCBTaGFubm9uCisgKiBAc2luY2UJSmF2YU1haWwgMS40LjQKKyAqLworcHVibGljIGNsYXNzIE1pbWVVdGlsIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE1ldGhvZCBjbGVhbkNvbnRlbnRUeXBlOworCisgICAgc3RhdGljIHsKKwlNZXRob2QgbWV0aCA9IG51bGw7CisJdHJ5IHsKKwkgICAgU3RyaW5nIGN0aCA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgibWFpbC5taW1lLmNvbnRlbnR0eXBlaGFuZGxlciIpOworCSAgICBpZiAoY3RoICE9IG51bGwpIHsKKwkJQ2xhc3NMb2FkZXIgY2wgPSBnZXRDb250ZXh0Q2xhc3NMb2FkZXIoKTsKKwkJQ2xhc3M8Pz4gY2xzSGFuZGxlciA9IG51bGw7CisJCWlmIChjbCAhPSBudWxsKSB7CisJCSAgICB0cnkgeworCQkJY2xzSGFuZGxlciA9IENsYXNzLmZvck5hbWUoY3RoLCBmYWxzZSwgY2wpOworCQkgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBjZXgpIHsgfQorCQl9CisJCWlmIChjbHNIYW5kbGVyID09IG51bGwpCisJCSAgICBjbHNIYW5kbGVyID0gQ2xhc3MuZm9yTmFtZShjdGgpOworCQltZXRoID0gY2xzSGFuZGxlci5nZXRNZXRob2QoImNsZWFuQ29udGVudFR5cGUiLAorCQkJbmV3IENsYXNzPD8+W10geyBNaW1lUGFydC5jbGFzcywgU3RyaW5nLmNsYXNzIH0pOworCSAgICB9CisJfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBleCkgeworCSAgICAvLyBpZ25vcmUgaXQKKwl9IGNhdGNoIChOb1N1Y2hNZXRob2RFeGNlcHRpb24gZXgpIHsKKwkgICAgLy8gaWdub3JlIGl0CisJfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBleCkgeworCSAgICAvLyBpZ25vcmUgaXQKKwl9IGZpbmFsbHkgeworCSAgICBjbGVhbkNvbnRlbnRUeXBlID0gbWV0aDsKKwl9CisgICAgfQorCisgICAgLy8gTm8gb25lIHNob3VsZCBpbnN0YW50aWF0ZSB0aGlzIGNsYXNzLgorICAgIHByaXZhdGUgTWltZVV0aWwoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogSWYgYSBDb250ZW50LVR5cGUgaGFuZGxlciBoYXMgYmVlbiBzcGVjaWZpZWQsCisgICAgICogY2FsbCBpdCB0byBjbGVhbiB1cCB0aGUgQ29udGVudC1UeXBlIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtCW1wCXRoZSBNaW1lUGFydAorICAgICAqIEBwYXJhbQljb250ZW50VHlwZQl0aGUgQ29udGVudC1UeXBlIHZhbHVlCisgICAgICogQHJldHVybgkJdGhlIGNsZWFuZWQgQ29udGVudC1UeXBlIHZhbHVlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgY2xlYW5Db250ZW50VHlwZShNaW1lUGFydCBtcCwgU3RyaW5nIGNvbnRlbnRUeXBlKSB7CisJaWYgKGNsZWFuQ29udGVudFR5cGUgIT0gbnVsbCkgeworCSAgICB0cnkgeworCQlyZXR1cm4gKFN0cmluZyljbGVhbkNvbnRlbnRUeXBlLmludm9rZShudWxsLAorCQkJCQkgICAgbmV3IE9iamVjdFtdIHsgbXAsIGNvbnRlbnRUeXBlIH0pOworCSAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKwkJcmV0dXJuIGNvbnRlbnRUeXBlOworCSAgICB9CisJfSBlbHNlCisJICAgIHJldHVybiBjb250ZW50VHlwZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZW5pZW5jZSBtZXRob2QgdG8gZ2V0IG91ciBjb250ZXh0IGNsYXNzIGxvYWRlci4KKyAgICAgKiBBc3NlcnQgYW55IHByaXZpbGVnZXMgd2UgbWlnaHQgaGF2ZSBhbmQgdGhlbiBjYWxsIHRoZQorICAgICAqIFRocmVhZC5nZXRDb250ZXh0Q2xhc3NMb2FkZXIgbWV0aG9kLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIENsYXNzTG9hZGVyIGdldENvbnRleHRDbGFzc0xvYWRlcigpIHsKKwlyZXR1cm4KKwlBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZChuZXcgUHJpdmlsZWdlZEFjdGlvbjxDbGFzc0xvYWRlcj4oKSB7CisJICAgIEBPdmVycmlkZQorCSAgICBwdWJsaWMgQ2xhc3NMb2FkZXIgcnVuKCkgeworCQlDbGFzc0xvYWRlciBjbCA9IG51bGw7CisJCXRyeSB7CisJCSAgICBjbCA9IFRocmVhZC5jdXJyZW50VGhyZWFkKCkuZ2V0Q29udGV4dENsYXNzTG9hZGVyKCk7CisJCX0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGV4KSB7IH0KKwkJcmV0dXJuIGNsOworCSAgICB9CisJfSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL1Byb3BVdGlsLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvUHJvcFV0aWwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMWI3OTNjCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL1Byb3BVdGlsLmphdmEKQEAgLTAsMCArMSwxNjkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLnV0aWw7CisKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBqYXZheC5tYWlsLlNlc3Npb247CisKKy8qKgorICogVXRpbGl0aWVzIHRvIG1ha2UgaXQgZWFzaWVyIHRvIGdldCBwcm9wZXJ0eSB2YWx1ZXMuCisgKiBQcm9wZXJ0aWVzIGNhbiBiZSBzdHJpbmdzIG9yIHR5cGUtc3BlY2lmaWMgdmFsdWUgb2JqZWN0cy4KKyAqCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCitwdWJsaWMgY2xhc3MgUHJvcFV0aWwgeworCisgICAgLy8gTm8gb25lIHNob3VsZCBpbnN0YW50aWF0ZSB0aGlzIGNsYXNzLgorICAgIHByaXZhdGUgUHJvcFV0aWwoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IGFuIGludGVnZXIgdmFsdWVkIHByb3BlcnR5LgorICAgICAqCisgICAgICogQHBhcmFtCXByb3BzCXRoZSBwcm9wZXJ0aWVzCisgICAgICogQHBhcmFtCW5hbWUJdGhlIHByb3BlcnR5IG5hbWUKKyAgICAgKiBAcGFyYW0JZGVmCWRlZmF1bHQgdmFsdWUgaWYgcHJvcGVydHkgbm90IGZvdW5kCisgICAgICogQHJldHVybgkJdGhlIHByb3BlcnR5IHZhbHVlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBpbnQgZ2V0SW50UHJvcGVydHkoUHJvcGVydGllcyBwcm9wcywgU3RyaW5nIG5hbWUsIGludCBkZWYpIHsKKwlyZXR1cm4gZ2V0SW50KGdldFByb3AocHJvcHMsIG5hbWUpLCBkZWYpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCBhIGJvb2xlYW4gdmFsdWVkIHByb3BlcnR5LgorICAgICAqCisgICAgICogQHBhcmFtCXByb3BzCXRoZSBwcm9wZXJ0aWVzCisgICAgICogQHBhcmFtCW5hbWUJdGhlIHByb3BlcnR5IG5hbWUKKyAgICAgKiBAcGFyYW0JZGVmCWRlZmF1bHQgdmFsdWUgaWYgcHJvcGVydHkgbm90IGZvdW5kCisgICAgICogQHJldHVybgkJdGhlIHByb3BlcnR5IHZhbHVlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGdldEJvb2xlYW5Qcm9wZXJ0eShQcm9wZXJ0aWVzIHByb3BzLAorCQkJCVN0cmluZyBuYW1lLCBib29sZWFuIGRlZikgeworCXJldHVybiBnZXRCb29sZWFuKGdldFByb3AocHJvcHMsIG5hbWUpLCBkZWYpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCBhbiBpbnRlZ2VyIHZhbHVlZCBwcm9wZXJ0eS4KKyAgICAgKgorICAgICAqIEBwYXJhbQlzZXNzaW9uCXRoZSBTZXNzaW9uCisgICAgICogQHBhcmFtCW5hbWUJdGhlIHByb3BlcnR5IG5hbWUKKyAgICAgKiBAcGFyYW0JZGVmCWRlZmF1bHQgdmFsdWUgaWYgcHJvcGVydHkgbm90IGZvdW5kCisgICAgICogQHJldHVybgkJdGhlIHByb3BlcnR5IHZhbHVlCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgc3RhdGljIGludCBnZXRJbnRTZXNzaW9uUHJvcGVydHkoU2Vzc2lvbiBzZXNzaW9uLAorCQkJCVN0cmluZyBuYW1lLCBpbnQgZGVmKSB7CisJcmV0dXJuIGdldEludChnZXRQcm9wKHNlc3Npb24uZ2V0UHJvcGVydGllcygpLCBuYW1lKSwgZGVmKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgYSBib29sZWFuIHZhbHVlZCBwcm9wZXJ0eS4KKyAgICAgKgorICAgICAqIEBwYXJhbQlzZXNzaW9uCXRoZSBTZXNzaW9uCisgICAgICogQHBhcmFtCW5hbWUJdGhlIHByb3BlcnR5IG5hbWUKKyAgICAgKiBAcGFyYW0JZGVmCWRlZmF1bHQgdmFsdWUgaWYgcHJvcGVydHkgbm90IGZvdW5kCisgICAgICogQHJldHVybgkJdGhlIHByb3BlcnR5IHZhbHVlCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gZ2V0Qm9vbGVhblNlc3Npb25Qcm9wZXJ0eShTZXNzaW9uIHNlc3Npb24sCisJCQkJU3RyaW5nIG5hbWUsIGJvb2xlYW4gZGVmKSB7CisJcmV0dXJuIGdldEJvb2xlYW4oZ2V0UHJvcChzZXNzaW9uLmdldFByb3BlcnRpZXMoKSwgbmFtZSksIGRlZik7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IGEgYm9vbGVhbiB2YWx1ZWQgU3lzdGVtIHByb3BlcnR5LgorICAgICAqCisgICAgICogQHBhcmFtCW5hbWUJdGhlIHByb3BlcnR5IG5hbWUKKyAgICAgKiBAcGFyYW0JZGVmCWRlZmF1bHQgdmFsdWUgaWYgcHJvcGVydHkgbm90IGZvdW5kCisgICAgICogQHJldHVybgkJdGhlIHByb3BlcnR5IHZhbHVlCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGdldEJvb2xlYW5TeXN0ZW1Qcm9wZXJ0eShTdHJpbmcgbmFtZSwgYm9vbGVhbiBkZWYpIHsKKwl0cnkgeworCSAgICByZXR1cm4gZ2V0Qm9vbGVhbihnZXRQcm9wKFN5c3RlbS5nZXRQcm9wZXJ0aWVzKCksIG5hbWUpLCBkZWYpOworCX0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHNleCkgeworCSAgICAvLyBmYWxsIHRocm91Z2guLi4KKwl9CisKKwkvKgorCSAqIElmIHdlIGNhbid0IGdldCB0aGUgZW50aXJlIFN5c3RlbSBQcm9wZXJ0aWVzIG9iamVjdCBiZWNhdXNlCisJICogb2YgYSBTZWN1cml0eUV4Y2VwdGlvbiwganVzdCBhc2sgZm9yIHRoZSBzcGVjaWZpYyBwcm9wZXJ0eS4KKwkgKi8KKwl0cnkgeworCSAgICBTdHJpbmcgdmFsdWUgPSBTeXN0ZW0uZ2V0UHJvcGVydHkobmFtZSk7CisJICAgIGlmICh2YWx1ZSA9PSBudWxsKQorCQlyZXR1cm4gZGVmOworCSAgICBpZiAoZGVmKQorCQlyZXR1cm4gIXZhbHVlLmVxdWFsc0lnbm9yZUNhc2UoImZhbHNlIik7CisJICAgIGVsc2UKKwkJcmV0dXJuIHZhbHVlLmVxdWFsc0lnbm9yZUNhc2UoInRydWUiKTsKKwl9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBzZXgpIHsKKwkgICAgcmV0dXJuIGRlZjsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHByb3BlcnR5LgorICAgICAqIElmIHRoZSAiZ2V0IiBtZXRob2QgcmV0dXJucyBudWxsLCB1c2UgdGhlIGdldFByb3BlcnR5IG1ldGhvZCwKKyAgICAgKiB3aGljaCBtaWdodCBjYXNjYWRlIHRvIGEgZGVmYXVsdCBQcm9wZXJ0aWVzIG9iamVjdC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBPYmplY3QgZ2V0UHJvcChQcm9wZXJ0aWVzIHByb3BzLCBTdHJpbmcgbmFtZSkgeworCU9iamVjdCB2YWwgPSBwcm9wcy5nZXQobmFtZSk7CisJaWYgKHZhbCAhPSBudWxsKQorCSAgICByZXR1cm4gdmFsOworCWVsc2UKKwkgICAgcmV0dXJuIHByb3BzLmdldFByb3BlcnR5KG5hbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEludGVycHJldCB0aGUgdmFsdWUgb2JqZWN0IGFzIGFuIGludGVnZXIsCisgICAgICogcmV0dXJuaW5nIGRlZiBpZiB1bmFibGUuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IGdldEludChPYmplY3QgdmFsdWUsIGludCBkZWYpIHsKKwlpZiAodmFsdWUgPT0gbnVsbCkKKwkgICAgcmV0dXJuIGRlZjsKKwlpZiAodmFsdWUgaW5zdGFuY2VvZiBTdHJpbmcpIHsKKwkgICAgdHJ5IHsKKwkJcmV0dXJuIEludGVnZXIucGFyc2VJbnQoKFN0cmluZyl2YWx1ZSk7CisJICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBuZmV4KSB7IH0KKwl9CisJaWYgKHZhbHVlIGluc3RhbmNlb2YgSW50ZWdlcikKKwkgICAgcmV0dXJuICgoSW50ZWdlcil2YWx1ZSkuaW50VmFsdWUoKTsKKwlyZXR1cm4gZGVmOworICAgIH0KKworICAgIC8qKgorICAgICAqIEludGVycHJldCB0aGUgdmFsdWUgb2JqZWN0IGFzIGEgYm9vbGVhbiwKKyAgICAgKiByZXR1cm5pbmcgZGVmIGlmIHVuYWJsZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGdldEJvb2xlYW4oT2JqZWN0IHZhbHVlLCBib29sZWFuIGRlZikgeworCWlmICh2YWx1ZSA9PSBudWxsKQorCSAgICByZXR1cm4gZGVmOworCWlmICh2YWx1ZSBpbnN0YW5jZW9mIFN0cmluZykgeworCSAgICAvKgorCSAgICAgKiBJZiB0aGUgZGVmYXVsdCBpcyB0cnVlLCBvbmx5ICJmYWxzZSIgdHVybnMgaXQgb2ZmLgorCSAgICAgKiBJZiB0aGUgZGVmYXVsdCBpcyBmYWxzZSwgb25seSAidHJ1ZSIgdHVybnMgaXQgb24uCisJICAgICAqLworCSAgICBpZiAoZGVmKQorCQlyZXR1cm4gISgoU3RyaW5nKXZhbHVlKS5lcXVhbHNJZ25vcmVDYXNlKCJmYWxzZSIpOworCSAgICBlbHNlCisJCXJldHVybiAoKFN0cmluZyl2YWx1ZSkuZXF1YWxzSWdub3JlQ2FzZSgidHJ1ZSIpOworCX0KKwlpZiAodmFsdWUgaW5zdGFuY2VvZiBCb29sZWFuKQorCSAgICByZXR1cm4gKChCb29sZWFuKXZhbHVlKS5ib29sZWFuVmFsdWUoKTsKKwlyZXR1cm4gZGVmOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvdXRpbC9RRGVjb2RlclN0cmVhbS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL1FEZWNvZGVyU3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTllYTBjNgotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvdXRpbC9RRGVjb2RlclN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsNzAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLnV0aWw7CisKK2ltcG9ydCBqYXZhLmlvLio7CisKKy8qKgorICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIGEgUSBEZWNvZGVyIGFzIGRlZmluZWQgaW4gUkZDIDIwNDcKKyAqIGZvciBkZWNvZGluZyBNSU1FIGhlYWRlcnMuIEl0IHN1YmNsYXNzZXMgdGhlIFFQRGVjb2RlclN0cmVhbSBjbGFzcy4KKyAqIAorICogQGF1dGhvciBKb2huIE1hbmkKKyAqLworCitwdWJsaWMgY2xhc3MgUURlY29kZXJTdHJlYW0gZXh0ZW5kcyBRUERlY29kZXJTdHJlYW0geworCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgUS1kZWNvZGVyIHRoYXQgZGVjb2RlcyB0aGUgc3BlY2lmaWVkIGlucHV0IHN0cmVhbS4KKyAgICAgKiBAcGFyYW0gaW4gICAgICAgIHRoZSBpbnB1dCBzdHJlYW0KKyAgICAgKi8KKyAgICBwdWJsaWMgUURlY29kZXJTdHJlYW0oSW5wdXRTdHJlYW0gaW4pIHsKKwlzdXBlcihpbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZCB0aGUgbmV4dCBkZWNvZGVkIGJ5dGUgZnJvbSB0aGlzIGlucHV0IHN0cmVhbS4gVGhlIGJ5dGUKKyAgICAgKiBpcyByZXR1cm5lZCBhcyBhbiA8Y29kZT5pbnQ8L2NvZGU+IGluIHRoZSByYW5nZSA8Y29kZT4wPC9jb2RlPgorICAgICAqIHRvIDxjb2RlPjI1NTwvY29kZT4uIElmIG5vIGJ5dGUgaXMgYXZhaWxhYmxlIGJlY2F1c2UgdGhlIGVuZCBvZgorICAgICAqIHRoZSBzdHJlYW0gaGFzIGJlZW4gcmVhY2hlZCwgdGhlIHZhbHVlIDxjb2RlPi0xPC9jb2RlPiBpcyByZXR1cm5lZC4KKyAgICAgKiBUaGlzIG1ldGhvZCBibG9ja3MgdW50aWwgaW5wdXQgZGF0YSBpcyBhdmFpbGFibGUsIHRoZSBlbmQgb2YgdGhlCisgICAgICogc3RyZWFtIGlzIGRldGVjdGVkLCBvciBhbiBleGNlcHRpb24gaXMgdGhyb3duLgorICAgICAqCisgICAgICogQHJldHVybiAgICAgdGhlIG5leHQgYnl0ZSBvZiBkYXRhLCBvciA8Y29kZT4tMTwvY29kZT4gaWYgdGhlIGVuZCBvZiB0aGUKKyAgICAgKiAgICAgICAgICAgICBzdHJlYW0gaXMgcmVhY2hlZC4KKyAgICAgKiBAZXhjZXB0aW9uICBJT0V4Y2VwdGlvbiAgaWYgYW4gSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCWludCBjID0gaW4ucmVhZCgpOworCisJaWYgKGMgPT0gJ18nKSAvLyBSZXR1cm4gJ18nIGFzICcgJworCSAgICByZXR1cm4gJyAnOworCWVsc2UgaWYgKGMgPT0gJz0nKSB7CisJICAgIC8vIFFQIEVuY29kZWQgYXRvbS4gR2V0IHRoZSBuZXh0IHR3byBieXRlcyAuLgorCSAgICBiYVswXSA9IChieXRlKWluLnJlYWQoKTsKKwkgICAgYmFbMV0gPSAoYnl0ZSlpbi5yZWFkKCk7CisJICAgIC8vIC4uIGFuZCBkZWNvZGUgdGhlbQorCSAgICB0cnkgeworCQlyZXR1cm4gQVNDSUlVdGlsaXR5LnBhcnNlSW50KGJhLCAwLCAyLCAxNik7CisJICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBuZXgpIHsKKwkJdGhyb3cgbmV3IERlY29kaW5nRXhjZXB0aW9uKAorCQkJIlFEZWNvZGVyOiBFcnJvciBpbiBRUCBzdHJlYW0gIiArIG5leC5nZXRNZXNzYWdlKCkpOworCSAgICB9CisJfSBlbHNlCisJICAgIHJldHVybiBjOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvdXRpbC9RRW5jb2RlclN0cmVhbS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL1FFbmNvZGVyU3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjU5ODk3YQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvdXRpbC9RRW5jb2RlclN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsMTAwIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC51dGlsOworCitpbXBvcnQgamF2YS5pby4qOworCisvKioKKyAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyBhIFEgRW5jb2RlciBhcyBkZWZpbmVkIGJ5IFJGQyAyMDQ3IGZvciAKKyAqIGVuY29kaW5nIE1JTUUgaGVhZGVycy4gSXQgc3ViY2xhc3NlcyB0aGUgUVBFbmNvZGVyU3RyZWFtIGNsYXNzLgorICogCisgKiBAYXV0aG9yIEpvaG4gTWFuaQorICovCisKK3B1YmxpYyBjbGFzcyBRRW5jb2RlclN0cmVhbSBleHRlbmRzIFFQRW5jb2RlclN0cmVhbSB7CisKKyAgICBwcml2YXRlIFN0cmluZyBzcGVjaWFsczsKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgV09SRF9TUEVDSUFMUyA9ICI9Xz9cIiMkJSYnKCksLjo7PD5AW1xcXV5ge3x9fiI7CisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIFRFWFRfU1BFQ0lBTFMgPSAiPV8/IjsKKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIFEgZW5jb2RlciB0aGF0IGVuY29kZXMgdGhlIHNwZWNpZmllZCBpbnB1dCBzdHJlYW0KKyAgICAgKiBAcGFyYW0gb3V0ICAgICAgICB0aGUgb3V0cHV0IHN0cmVhbQorICAgICAqIEBwYXJhbSBlbmNvZGluZ1dvcmQgdHJ1ZSBpZiB3ZSBhcmUgUS1lbmNvZGluZyBhIHdvcmQgd2l0aGluIGEKKyAgICAgKgkJCXBocmFzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUUVuY29kZXJTdHJlYW0oT3V0cHV0U3RyZWFtIG91dCwgYm9vbGVhbiBlbmNvZGluZ1dvcmQpIHsKKwlzdXBlcihvdXQsIEludGVnZXIuTUFYX1ZBTFVFKTsgLy8gTUFYX1ZBTFVFIGlzIDJeMzEsIHNob3VsZAorCQkJCSAgICAgICAvLyBzdWZmaWNlICghKSB0byBpbmRpY2F0ZSB0aGF0CisJCQkJICAgICAgIC8vIENSTEZzIHNob3VsZCBub3QgYmUgaW5zZXJ0ZWQKKwkJCQkgICAgICAgLy8gd2hlbiBlbmNvZGluZyByZmM4MjIgaGVhZGVycworCisJLy8gYSBSRkM4MjIgIndvcmQiIHRva2VuIGhhcyBtb3JlIHJlc3RyaWN0aW9ucyB0aGFuIGEKKwkvLyBSRkM4MjIgInRleHQiIHRva2VuLgorCXNwZWNpYWxzID0gZW5jb2RpbmdXb3JkID8gV09SRF9TUEVDSUFMUyA6IFRFWFRfU1BFQ0lBTFM7CisgICAgfQorCisgICAgLyoqCisgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIDxjb2RlPmJ5dGU8L2NvZGU+IHRvIHRoaXMgb3V0cHV0IHN0cmVhbS4KKyAgICAgKiBAcGFyYW0gICAgICBjICAgdGhlIDxjb2RlPmJ5dGU8L2NvZGU+LgorICAgICAqIEBleGNlcHRpb24gIElPRXhjZXB0aW9uICBpZiBhbiBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGludCBjKSB0aHJvd3MgSU9FeGNlcHRpb24geworCWMgPSBjICYgMHhmZjsgLy8gVHVybiBvZmYgdGhlIE1TQi4KKwlpZiAoYyA9PSAnICcpCisJICAgIG91dHB1dCgnXycsIGZhbHNlKTsKKwllbHNlIGlmIChjIDwgMDQwIHx8IGMgPj0gMDE3NyB8fCBzcGVjaWFscy5pbmRleE9mKGMpID49IDApCisJICAgIC8vIEVuY29kaW5nIHJlcXVpcmVkLiAKKwkgICAgb3V0cHV0KGMsIHRydWUpOworCWVsc2UgLy8gTm8gZW5jb2RpbmcgcmVxdWlyZWQKKwkgICAgb3V0cHV0KGMsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsZW5ndGggb2YgdGhlIGVuY29kZWQgdmVyc2lvbiBvZiB0aGlzIGJ5dGUgYXJyYXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0JYgl0aGUgYnl0ZSBhcnJheQorICAgICAqIEBwYXJhbQllbmNvZGluZ1dvcmQJdHJ1ZSBpZiBlbmNvZGluZyB3b3JkcywgZmFsc2UgaWYgZW5jb2RpbmcgdGV4dAorICAgICAqIEByZXR1cm4JCXRoZSBsZW5ndGgKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludCBlbmNvZGVkTGVuZ3RoKGJ5dGVbXSBiLCBib29sZWFuIGVuY29kaW5nV29yZCkgeworCWludCBsZW4gPSAwOworCVN0cmluZyBzcGVjaWFscyA9IGVuY29kaW5nV29yZCA/IFdPUkRfU1BFQ0lBTFM6IFRFWFRfU1BFQ0lBTFM7CisJZm9yIChpbnQgaSA9IDA7IGkgPCBiLmxlbmd0aDsgaSsrKSB7CisJICAgIGludCBjID0gYltpXSAmIDB4ZmY7IC8vIE1hc2sgb2ZmIE1TQgorCSAgICBpZiAoYyA8IDA0MCB8fCBjID49IDAxNzcgfHwgc3BlY2lhbHMuaW5kZXhPZihjKSA+PSAwKQorCQkvLyBuZWVkcyBlbmNvZGluZworCQlsZW4gKz0gMzsgLy8gUS1lbmNvZGluZyBpcyAxIC0+IDMgY29udmVyc2lvbgorCSAgICBlbHNlCisJCWxlbisrOworCX0KKwlyZXR1cm4gbGVuOworICAgIH0KKworICAgIC8qKioqIGJlZ2luIFRFU1QgcHJvZ3JhbSAqKioKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmcgYXJndltdKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRmlsZUlucHV0U3RyZWFtIGluZmlsZSA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oYXJndlswXSk7CisgICAgICAgIFFFbmNvZGVyU3RyZWFtIGVuY29kZXIgPSBuZXcgUUVuY29kZXJTdHJlYW0oU3lzdGVtLm91dCk7CisgICAgICAgIGludCBjOworIAorICAgICAgICB3aGlsZSAoKGMgPSBpbmZpbGUucmVhZCgpKSAhPSAtMSkKKyAgICAgICAgICAgIGVuY29kZXIud3JpdGUoYyk7CisgICAgICAgIGVuY29kZXIuY2xvc2UoKTsKKyAgICB9CisgICAgKioqIGVuZCBURVNUIHByb2dyYW0gKioqLworfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL1FQRGVjb2RlclN0cmVhbS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL1FQRGVjb2RlclN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI4NGM2MTQKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvUVBEZWNvZGVyU3RyZWFtLmphdmEKQEAgLTAsMCArMSwxOTggQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLnV0aWw7CisKK2ltcG9ydCBqYXZhLmlvLio7CisKKy8qKgorICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIGEgUVAgRGVjb2Rlci4gSXQgaXMgaW1wbGVtZW50ZWQgYXMKKyAqIGEgRmlsdGVySW5wdXRTdHJlYW0sIHNvIG9uZSBjYW4ganVzdCB3cmFwIHRoaXMgY2xhc3MgYXJvdW5kCisgKiBhbnkgaW5wdXQgc3RyZWFtIGFuZCByZWFkIGJ5dGVzIGZyb20gdGhpcyBmaWx0ZXIuIFRoZSBkZWNvZGluZworICogaXMgZG9uZSBhcyB0aGUgYnl0ZXMgYXJlIHJlYWQgb3V0LgorICogCisgKiBAYXV0aG9yIEpvaG4gTWFuaQorICovCisKK3B1YmxpYyBjbGFzcyBRUERlY29kZXJTdHJlYW0gZXh0ZW5kcyBGaWx0ZXJJbnB1dFN0cmVhbSB7CisgICAgcHJvdGVjdGVkIGJ5dGVbXSBiYSA9IG5ldyBieXRlWzJdOworICAgIHByb3RlY3RlZCBpbnQgc3BhY2VzID0gMDsKKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIFF1b3RlZCBQcmludGFibGUgZGVjb2RlciB0aGF0IGRlY29kZXMgdGhlIHNwZWNpZmllZCAKKyAgICAgKiBpbnB1dCBzdHJlYW0uCisgICAgICogQHBhcmFtIGluICAgICAgICB0aGUgaW5wdXQgc3RyZWFtCisgICAgICovCisgICAgcHVibGljIFFQRGVjb2RlclN0cmVhbShJbnB1dFN0cmVhbSBpbikgeworCXN1cGVyKG5ldyBQdXNoYmFja0lucHV0U3RyZWFtKGluLCAyKSk7IC8vIHB1c2hiYWNrIG9mIHNpemU9MgorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWQgdGhlIG5leHQgZGVjb2RlZCBieXRlIGZyb20gdGhpcyBpbnB1dCBzdHJlYW0uIFRoZSBieXRlCisgICAgICogaXMgcmV0dXJuZWQgYXMgYW4gPGNvZGU+aW50PC9jb2RlPiBpbiB0aGUgcmFuZ2UgPGNvZGU+MDwvY29kZT4KKyAgICAgKiB0byA8Y29kZT4yNTU8L2NvZGU+LiBJZiBubyBieXRlIGlzIGF2YWlsYWJsZSBiZWNhdXNlIHRoZSBlbmQgb2YKKyAgICAgKiB0aGUgc3RyZWFtIGhhcyBiZWVuIHJlYWNoZWQsIHRoZSB2YWx1ZSA8Y29kZT4tMTwvY29kZT4gaXMgcmV0dXJuZWQuCisgICAgICogVGhpcyBtZXRob2QgYmxvY2tzIHVudGlsIGlucHV0IGRhdGEgaXMgYXZhaWxhYmxlLCB0aGUgZW5kIG9mIHRoZQorICAgICAqIHN0cmVhbSBpcyBkZXRlY3RlZCwgb3IgYW4gZXhjZXB0aW9uIGlzIHRocm93bi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gICAgIHRoZSBuZXh0IGJ5dGUgb2YgZGF0YSwgb3IgPGNvZGU+LTE8L2NvZGU+IGlmIHRoZSBlbmQgb2YgdGhlCisgICAgICogICAgICAgICAgICAgc3RyZWFtIGlzIHJlYWNoZWQuCisgICAgICogQGV4Y2VwdGlvbiAgSU9FeGNlcHRpb24gIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlpZiAoc3BhY2VzID4gMCkgeworCSAgICAvLyBXZSBoYXZlIGNhY2hlZCBzcGFjZSBjaGFyYWN0ZXJzLCByZXR1cm4gb25lCisJICAgIHNwYWNlcy0tOworCSAgICByZXR1cm4gJyAnOworCX0KKwkKKwlpbnQgYyA9IGluLnJlYWQoKTsKKworCWlmIChjID09ICcgJykgeyAKKwkgICAgLy8gR290IHNwYWNlLCBrZWVwIHJlYWRpbmcgdGlsbCB3ZSBnZXQgYSBub24tc3BhY2UgY2hhcgorCSAgICB3aGlsZSAoKGMgPSBpbi5yZWFkKCkpID09ICcgJykKKwkJc3BhY2VzKys7CisKKwkgICAgaWYgKGMgPT0gJ1xyJyB8fCBjID09ICdcbicgfHwgYyA9PSAtMSkKKwkJLy8gSWYgdGhlIG5vbi1zcGFjZSBjaGFyIGlzIENSL0xGL0VPRiwgdGhlIHNwYWNlcyB3ZSBnb3QKKwkgICAgCS8vIHNvIGZhciBpcyBqdW5rIGludHJvZHVjZWQgZHVyaW5nIHRyYW5zcG9ydC4gSnVuayAnZW0uCisJCXNwYWNlcyA9IDA7CisgICAgCSAgICBlbHNlIHsKKwkJLy8gVGhlIG5vbi1zcGFjZSBjaGFyIGlzIE5PVCBDUi9MRiwgdGhlIHNwYWNlcyBhcmUgdmFsaWQuCisJCSgoUHVzaGJhY2tJbnB1dFN0cmVhbSlpbikudW5yZWFkKGMpOworCQljID0gJyAnOworCSAgICB9CisJICAgIHJldHVybiBjOyAvLyByZXR1cm4gZWl0aGVyIDxTUEFDRT4gb3IgPENSL0xGPgorCX0KKwllbHNlIGlmIChjID09ICc9JykgeworCSAgICAvLyBRUCBFbmNvZGVkIGF0b20uIERlY29kZSB0aGUgbmV4dCB0d28gYnl0ZXMKKwkgICAgaW50IGEgPSBpbi5yZWFkKCk7CisKKwkgICAgaWYgKGEgPT0gJ1xuJykgeworCQkvKiBIbW0gLi4uIG5vdCByZWFsbHkgY29uZmlybWluZyBRUCBlbmNvZGluZywgYnV0IGxldHMKKwkJICogYWxsb3cgdGhpcyBhcyBhIExGIHRlcm1pbmF0ZWQgZW5jb2RlZCBsaW5lIC4uIGFuZAorCQkgKiBjb25zaWRlciB0aGlzIGEgc29mdCBsaW5lYnJlYWsgYW5kIHJlY3Vyc2UgdG8gZmV0Y2ggCisJCSAqIHRoZSBuZXh0IGNoYXIuCisJCSAqLworCQlyZXR1cm4gcmVhZCgpOworCSAgICB9IGVsc2UgaWYgKGEgPT0gJ1xyJykgeworCQkvLyBFeHBlY3RpbmcgTEYuIFRoaXMgZm9ybXMgYSBzb2Z0IGxpbmVicmVhayB0byBiZSBpZ25vcmVkLgorCQlpbnQgYiA9IGluLnJlYWQoKTsKKwkJaWYgKGIgIT0gJ1xuJykgCisJCSAgICAvKiBOb3QgcmVhbGx5IGNvbmZpcm1pbmcgUVAgZW5jb2RpbmcsIGJ1dAorCQkgICAgICogbGV0cyBhbGxvdyB0aGlzIGFzIHdlbGwuCisJCSAgICAgKi8KKwkJICAgICgoUHVzaGJhY2tJbnB1dFN0cmVhbSlpbikudW5yZWFkKGIpOworCQlyZXR1cm4gcmVhZCgpOworCSAgICB9IGVsc2UgaWYgKGEgPT0gLTEpIHsKKwkgICAJLy8gTm90IHZhbGlkIFFQIGVuY29kaW5nLCBidXQgd2UgYmUgbmljZSBhbmQgdG9sZXJhbnQgaGVyZSAhCisJCXJldHVybiAtMTsKKwkgICAgfSBlbHNlIHsKKwkJYmFbMF0gPSAoYnl0ZSlhOworCQliYVsxXSA9IChieXRlKWluLnJlYWQoKTsKKwkJdHJ5IHsKKwkJICAgIHJldHVybiBBU0NJSVV0aWxpdHkucGFyc2VJbnQoYmEsIDAsIDIsIDE2KTsKKwkJfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIG5leCkgeworCQkgICAgLyoKKwkJICAgIFN5c3RlbS5lcnIucHJpbnRsbigKKwkJICAgICAJIklsbGVnYWwgY2hhcmFjdGVycyBpbiBRUCBlbmNvZGVkIHN0cmVhbTogIiArIAorCQkgICAgIAlBU0NJSVV0aWxpdHkudG9TdHJpbmcoYmEsIDAsIDIpCisJCSAgICApOworCQkgICAgKi8KKworCQkgICAgKChQdXNoYmFja0lucHV0U3RyZWFtKWluKS51bnJlYWQoYmEpOworCQkgICAgcmV0dXJuIGM7CisJCX0KKwkgICAgfQorCX0KKwlyZXR1cm4gYzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkcyB1cCB0byA8Y29kZT5sZW48L2NvZGU+IGRlY29kZWQgYnl0ZXMgb2YgZGF0YSBmcm9tIHRoaXMgaW5wdXQgc3RyZWFtCisgICAgICogaW50byBhbiBhcnJheSBvZiBieXRlcy4gVGhpcyBtZXRob2QgYmxvY2tzIHVudGlsIHNvbWUgaW5wdXQgaXMKKyAgICAgKiBhdmFpbGFibGUuCisgICAgICogPHA+CisgICAgICoKKyAgICAgKiBAcGFyYW0gICAgICBidWYgICB0aGUgYnVmZmVyIGludG8gd2hpY2ggdGhlIGRhdGEgaXMgcmVhZC4KKyAgICAgKiBAcGFyYW0gICAgICBvZmYgICB0aGUgc3RhcnQgb2Zmc2V0IG9mIHRoZSBkYXRhLgorICAgICAqIEBwYXJhbSAgICAgIGxlbiAgIHRoZSBtYXhpbXVtIG51bWJlciBvZiBieXRlcyByZWFkLgorICAgICAqIEByZXR1cm4gICAgIHRoZSB0b3RhbCBudW1iZXIgb2YgYnl0ZXMgcmVhZCBpbnRvIHRoZSBidWZmZXIsIG9yCisgICAgICogICAgICAgICAgICAgPGNvZGU+LTE8L2NvZGU+IGlmIHRoZXJlIGlzIG5vIG1vcmUgZGF0YSBiZWNhdXNlIHRoZSBlbmQgb2YKKyAgICAgKiAgICAgICAgICAgICB0aGUgc3RyZWFtIGhhcyBiZWVuIHJlYWNoZWQuCisgICAgICogQGV4Y2VwdGlvbiAgSU9FeGNlcHRpb24gIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKGJ5dGVbXSBidWYsIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJaW50IGksIGM7CisJZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7CisJICAgIGlmICgoYyA9IHJlYWQoKSkgPT0gLTEpIHsKKwkJaWYgKGkgPT0gMCkgLy8gQXQgZW5kIG9mIHN0cmVhbSwgc28gd2Ugc2hvdWxkCisJCSAgICBpID0gLTE7IC8vIHJldHVybiAtMSAsIE5PVCAwLgorCQlicmVhazsKKwkgICAgfQorCSAgICBidWZbb2ZmK2ldID0gKGJ5dGUpYzsKKwl9CisgICAgICAgIHJldHVybiBpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNraXBzIG92ZXIgYW5kIGRpc2NhcmRzIG4gYnl0ZXMgb2YgZGF0YSBmcm9tIHRoaXMgc3RyZWFtLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBsb25nIHNraXAobG9uZyBuKSB0aHJvd3MgSU9FeGNlcHRpb24geworCWxvbmcgc2tpcHBlZCA9IDA7CisJd2hpbGUgKG4tLSA+IDAgJiYgcmVhZCgpID49IDApCisJICAgIHNraXBwZWQrKzsKKwlyZXR1cm4gc2tpcHBlZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyBpZiB0aGlzIGlucHV0IHN0cmVhbSBzdXBwb3J0cyBtYXJrcy4gQ3VycmVudGx5IHRoaXMgY2xhc3MKKyAgICAgKiBkb2VzIG5vdCBzdXBwb3J0IG1hcmtzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gbWFya1N1cHBvcnRlZCgpIHsKKwlyZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRoYXQgY2FuIGJlIHJlYWQgZnJvbSB0aGlzIGlucHV0CisgICAgICogc3RyZWFtIHdpdGhvdXQgYmxvY2tpbmcuIFRoZSBRUCBhbGdvcml0aG0gZG9lcyBub3QgcGVybWl0CisgICAgICogYSBwcmlvcmkga25vd2xlZGdlIG9mIHRoZSBudW1iZXIgb2YgYnl0ZXMgYWZ0ZXIgZGVjb2RpbmcsIHNvCisgICAgICogdGhpcyBtZXRob2QganVzdCBpbnZva2VzIHRoZSA8Y29kZT5hdmFpbGFibGU8L2NvZGU+IG1ldGhvZAorICAgICAqIG9mIHRoZSBvcmlnaW5hbCBpbnB1dCBzdHJlYW0uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBhdmFpbGFibGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCS8vIFRoaXMgaXMgYm9ndXMgISBXZSBkb24ndCByZWFsbHkga25vdyBob3cgbXVjaAorCS8vIGJ5dGVzIGFyZSBhdmFpbGFibGUgKmFmdGVyKiBkZWNvZGluZworCXJldHVybiBpbi5hdmFpbGFibGUoKTsKKyAgICB9CisKKyAgICAvKioqKiBiZWdpbiBURVNUIHByb2dyYW0KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmcgYXJndltdKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgRmlsZUlucHV0U3RyZWFtIGluZmlsZSA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oYXJndlswXSk7CisgICAgICAgIFFQRGVjb2RlclN0cmVhbSBkZWNvZGVyID0gbmV3IFFQRGVjb2RlclN0cmVhbShpbmZpbGUpOworICAgICAgICBpbnQgYzsKKyAKKyAgICAgICAgd2hpbGUgKChjID0gZGVjb2Rlci5yZWFkKCkpICE9IC0xKQorICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgoY2hhciljKTsKKyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCk7CisgICAgfQorICAgICoqKiBlbmQgVEVTVCBwcm9ncmFtICoqKiovCit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvUVBFbmNvZGVyU3RyZWFtLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvUVBFbmNvZGVyU3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDM5MTAyZAotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvdXRpbC9RUEVuY29kZXJTdHJlYW0uamF2YQpAQCAtMCwwICsxLDE5NiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwudXRpbDsKKworaW1wb3J0IGphdmEuaW8uKjsKKworLyoqCisgKiBUaGlzIGNsYXNzIGltcGxlbWVudHMgYSBRdW90ZWQgUHJpbnRhYmxlIEVuY29kZXIuIEl0IGlzIGltcGxlbWVudGVkIGFzCisgKiBhIEZpbHRlck91dHB1dFN0cmVhbSwgc28gb25lIGNhbiBqdXN0IHdyYXAgdGhpcyBjbGFzcyBhcm91bmQKKyAqIGFueSBvdXRwdXQgc3RyZWFtIGFuZCB3cml0ZSBieXRlcyBpbnRvIHRoaXMgZmlsdGVyLiBUaGUgRW5jb2RpbmcKKyAqIGlzIGRvbmUgYXMgdGhlIGJ5dGVzIGFyZSB3cml0dGVuIG91dC4KKyAqIAorICogQGF1dGhvciBKb2huIE1hbmkKKyAqLworCitwdWJsaWMgY2xhc3MgUVBFbmNvZGVyU3RyZWFtIGV4dGVuZHMgRmlsdGVyT3V0cHV0U3RyZWFtIHsKKyAgICBwcml2YXRlIGludCBjb3VudCA9IDA7IAkvLyBudW1iZXIgb2YgYnl0ZXMgdGhhdCBoYXZlIGJlZW4gb3V0cHV0CisgICAgcHJpdmF0ZSBpbnQgYnl0ZXNQZXJMaW5lOwkvLyBudW1iZXIgb2YgYnl0ZXMgcGVyIGxpbmUKKyAgICBwcml2YXRlIGJvb2xlYW4gZ290U3BhY2UgPSBmYWxzZTsKKyAgICBwcml2YXRlIGJvb2xlYW4gZ290Q1IgPSBmYWxzZTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIFFQIGVuY29kZXIgdGhhdCBlbmNvZGVzIHRoZSBzcGVjaWZpZWQgaW5wdXQgc3RyZWFtCisgICAgICogQHBhcmFtIG91dCAgICAgICAgdGhlIG91dHB1dCBzdHJlYW0KKyAgICAgKiBAcGFyYW0gYnl0ZXNQZXJMaW5lICB0aGUgbnVtYmVyIG9mIGJ5dGVzIHBlciBsaW5lLiBUaGUgZW5jb2RlcgorICAgICAqICAgICAgICAgICAgICAgICAgIGluc2VydHMgYSBDUkxGIHNlcXVlbmNlIGFmdGVyIHRoaXMgbWFueSBudW1iZXIKKyAgICAgKiAgICAgICAgICAgICAgICAgICBvZiBieXRlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgUVBFbmNvZGVyU3RyZWFtKE91dHB1dFN0cmVhbSBvdXQsIGludCBieXRlc1BlckxpbmUpIHsKKwlzdXBlcihvdXQpOworCS8vIFN1YnRyYWN0IDEgdG8gYWNjb3VudCBmb3IgdGhlICc9JyBpbiB0aGUgc29mdC1yZXR1cm4gCisJLy8gYXQgdGhlIGVuZCBvZiBhIGxpbmUKKwl0aGlzLmJ5dGVzUGVyTGluZSA9IGJ5dGVzUGVyTGluZSAtIDE7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgUVAgZW5jb2RlciB0aGF0IGVuY29kZXMgdGhlIHNwZWNpZmllZCBpbnB1dCBzdHJlYW0uCisgICAgICogSW5zZXJ0cyB0aGUgQ1JMRiBzZXF1ZW5jZSBhZnRlciBvdXRwdXR0aW5nIDc2IGJ5dGVzLgorICAgICAqIEBwYXJhbSBvdXQgICAgICAgIHRoZSBvdXRwdXQgc3RyZWFtCisgICAgICovCisgICAgcHVibGljIFFQRW5jb2RlclN0cmVhbShPdXRwdXRTdHJlYW0gb3V0KSB7CisJdGhpcyhvdXQsIDc2KTsJCisgICAgfQorCisgICAgLyoqCisgICAgICogRW5jb2RlcyA8Y29kZT5sZW48L2NvZGU+IGJ5dGVzIGZyb20gdGhlIHNwZWNpZmllZAorICAgICAqIDxjb2RlPmJ5dGU8L2NvZGU+IGFycmF5IHN0YXJ0aW5nIGF0IG9mZnNldCA8Y29kZT5vZmY8L2NvZGU+IHRvCisgICAgICogdGhpcyBvdXRwdXQgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtICAgICAgYiAgICAgdGhlIGRhdGEuCisgICAgICogQHBhcmFtICAgICAgb2ZmICAgdGhlIHN0YXJ0IG9mZnNldCBpbiB0aGUgZGF0YS4KKyAgICAgKiBAcGFyYW0gICAgICBsZW4gICB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIHdyaXRlLgorICAgICAqIEBleGNlcHRpb24gIElPRXhjZXB0aW9uICBpZiBhbiBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworCWZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyBpKyspCisJICAgIHdyaXRlKGJbb2ZmICsgaV0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVuY29kZXMgPGNvZGU+Yi5sZW5ndGg8L2NvZGU+IGJ5dGVzIHRvIHRoaXMgb3V0cHV0IHN0cmVhbS4KKyAgICAgKiBAcGFyYW0gICAgICBiICAgdGhlIGRhdGEgdG8gYmUgd3JpdHRlbi4KKyAgICAgKiBAZXhjZXB0aW9uICBJT0V4Y2VwdGlvbiAgaWYgYW4gSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShieXRlW10gYikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwl3cml0ZShiLCAwLCBiLmxlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIDxjb2RlPmJ5dGU8L2NvZGU+IHRvIHRoaXMgb3V0cHV0IHN0cmVhbS4KKyAgICAgKiBAcGFyYW0gICAgICBjICAgdGhlIDxjb2RlPmJ5dGU8L2NvZGU+LgorICAgICAqIEBleGNlcHRpb24gIElPRXhjZXB0aW9uICBpZiBhbiBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGludCBjKSB0aHJvd3MgSU9FeGNlcHRpb24geworCWMgPSBjICYgMHhmZjsgLy8gVHVybiBvZmYgdGhlIE1TQi4KKwlpZiAoZ290U3BhY2UpIHsgLy8gcHJldmlvdXMgY2hhcmFjdGVyIHdhcyA8U1BBQ0U+CisJICAgIGlmIChjID09ICdccicgfHwgYyA9PSAnXG4nKQorCQkvLyBpZiBDUi9MRiwgd2UgbmVlZCB0byBlbmNvZGUgdGhlIDxTUEFDRT4gY2hhcgorCQlvdXRwdXQoJyAnLCB0cnVlKTsKKwkgICAgZWxzZSAvLyBubyBlbmNvZGluZyByZXF1aXJlZCwganVzdCBvdXRwdXQgdGhlIGNoYXIKKwkJb3V0cHV0KCcgJywgZmFsc2UpOworCSAgICBnb3RTcGFjZSA9IGZhbHNlOworCX0KKworCWlmIChjID09ICdccicpIHsKKwkgICAgZ290Q1IgPSB0cnVlOworCSAgICBvdXRwdXRDUkxGKCk7CisJfSBlbHNlIHsKKwkgICAgaWYgKGMgPT0gJ1xuJykgeworCQlpZiAoZ290Q1IpIAorCQkgICAgLy8gVGhpcyBpcyBhIENSTEYgc2VxdWVuY2UsIHdlIGFscmVhZHkgb3V0cHV0IHRoZSAKKwkJICAgIC8vIGNvcnJlc3BvbmRpbmcgQ1JMRiB3aGVuIHdlIGdvdCB0aGUgQ1IsIHNvIGlnbm9yZSB0aGlzCisJCSAgICA7CisJCWVsc2UKKwkJICAgIG91dHB1dENSTEYoKTsKKwkgICAgfSBlbHNlIGlmIChjID09ICcgJykgeworCQlnb3RTcGFjZSA9IHRydWU7CisJICAgIH0gZWxzZSBpZiAoYyA8IDA0MCB8fCBjID49IDAxNzcgfHwgYyA9PSAnPScpCisJCS8vIEVuY29kaW5nIHJlcXVpcmVkLiAKKwkJb3V0cHV0KGMsIHRydWUpOworCSAgICBlbHNlIC8vIE5vIGVuY29kaW5nIHJlcXVpcmVkCisJCW91dHB1dChjLCBmYWxzZSk7CisJICAgIC8vIHdoYXRldmVyIGl0IHdhcywgaXQgd2Fzbid0IGEgQ1IKKwkgICAgZ290Q1IgPSBmYWxzZTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogRmx1c2hlcyB0aGlzIG91dHB1dCBzdHJlYW0gYW5kIGZvcmNlcyBhbnkgYnVmZmVyZWQgb3V0cHV0IGJ5dGVzCisgICAgICogdG8gYmUgZW5jb2RlZCBvdXQgdG8gdGhlIHN0cmVhbS4KKyAgICAgKiBAZXhjZXB0aW9uICBJT0V4Y2VwdGlvbiAgaWYgYW4gSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBmbHVzaCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJaWYgKGdvdFNwYWNlKSB7CisJICAgIG91dHB1dCgnICcsIHRydWUpOworCSAgICBnb3RTcGFjZSA9IGZhbHNlOworCX0KKwlvdXQuZmx1c2goKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGb3JjZXMgYW55IGJ1ZmZlcmVkIG91dHB1dCBieXRlcyB0byBiZSBlbmNvZGVkIG91dCB0byB0aGUgc3RyZWFtCisgICAgICogYW5kIGNsb3NlcyB0aGlzIG91dHB1dCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uCUlPRXhjZXB0aW9uCWZvciBJL08gZXJyb3JzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCWZsdXNoKCk7CisJb3V0LmNsb3NlKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIG91dHB1dENSTEYoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCW91dC53cml0ZSgnXHInKTsKKwlvdXQud3JpdGUoJ1xuJyk7CisJY291bnQgPSAwOworICAgIH0KKworICAgIC8vIFRoZSBlbmNvZGluZyB0YWJsZQorICAgIHByaXZhdGUgZmluYWwgc3RhdGljIGNoYXIgaGV4W10gPSB7CisJJzAnLCcxJywgJzInLCAnMycsICc0JywgJzUnLCAnNicsICc3JywKKwknOCcsJzknLCAnQScsICdCJywgJ0MnLCAnRCcsICdFJywgJ0YnCisgICAgfTsKKworICAgIHByb3RlY3RlZCB2b2lkIG91dHB1dChpbnQgYywgYm9vbGVhbiBlbmNvZGUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJaWYgKGVuY29kZSkgeworCSAgICBpZiAoKGNvdW50ICs9IDMpID4gYnl0ZXNQZXJMaW5lKSB7CisJCW91dC53cml0ZSgnPScpOworCSAgICAJb3V0LndyaXRlKCdccicpOworCSAgICAJb3V0LndyaXRlKCdcbicpOworCQljb3VudCA9IDM7IC8vIHNldCB0aGUgbmV4dCBsaW5lJ3MgbGVuZ3RoCisJICAgIH0KKwkgICAgb3V0LndyaXRlKCc9Jyk7CisJICAgIG91dC53cml0ZShoZXhbYyA+PiA0XSk7CisJICAgIG91dC53cml0ZShoZXhbYyAmIDB4Zl0pOworCX0gZWxzZSB7CisJICAgIGlmICgrK2NvdW50ID4gYnl0ZXNQZXJMaW5lKSB7CisJCW91dC53cml0ZSgnPScpOworCSAgICAJb3V0LndyaXRlKCdccicpOworCSAgICAJb3V0LndyaXRlKCdcbicpOworCQljb3VudCA9IDE7IC8vIHNldCB0aGUgbmV4dCBsaW5lJ3MgbGVuZ3RoCisJICAgIH0KKwkgICAgb3V0LndyaXRlKGMpOworCX0KKyAgICB9CisKKyAgICAvKioqKiBiZWdpbiBURVNUIHByb2dyYW0gKioqCisgICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nIGFyZ3ZbXSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEZpbGVJbnB1dFN0cmVhbSBpbmZpbGUgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGFyZ3ZbMF0pOworICAgICAgICBRUEVuY29kZXJTdHJlYW0gZW5jb2RlciA9IG5ldyBRUEVuY29kZXJTdHJlYW0oU3lzdGVtLm91dCk7CisgICAgICAgIGludCBjOworIAorICAgICAgICB3aGlsZSAoKGMgPSBpbmZpbGUucmVhZCgpKSAhPSAtMSkKKyAgICAgICAgICAgIGVuY29kZXIud3JpdGUoYyk7CisgICAgICAgIGVuY29kZXIuY2xvc2UoKTsKKyAgICB9CisgICAgKioqIGVuZCBURVNUIHByb2dyYW0gKioqLworfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL1JlYWRhYmxlTWltZS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL1JlYWRhYmxlTWltZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVjYmE3ZTIKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvUmVhZGFibGVNaW1lLmphdmEKQEAgLTAsMCArMSw0MCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAxMiwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwudXRpbDsKKworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CisKK2ltcG9ydCBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworLyoqCisgKiBBIE1lc3NhZ2Ugb3IgbWVzc2FnZSBQYXJ0IHdob3NlIGRhdGEgY2FuIGJlIHJlYWQgYXMgYSBNSU1FIGZvcm1hdAorICogc3RyZWFtLiAgTm90ZSB0aGF0IHRoZSBNSU1FIHN0cmVhbSB3aWxsIGluY2x1ZGUgYm90aCB0aGUgaGVhZGVycworICogYW5kIHRoZSBib2R5IG9mIHRoZSBtZXNzYWdlIG9yIHBhcnQuICBUaGlzIHNob3VsZCBiZSB0aGUgc2FtZSBkYXRhCisgKiB0aGF0IGlzIHByb2R1Y2VkIGJ5IHRoZSB3cml0ZVRvIG1ldGhvZCwgYnV0IGluIGEgcmVhZGFibGUgZm9ybS4KKyAqCisgKiBAYXV0aG9yCUJpbGwgU2hhbm5vbgorICogQHNpbmNlCUphdmFNYWlsIDEuNC41CisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgUmVhZGFibGVNaW1lIHsKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIE1JTUUgZm9ybWF0IHN0cmVhbSBjb3JyZXNwb25kaW5nIHRvIHRoaXMgbWVzc2FnZSBwYXJ0LgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgTUlNRSBmb3JtYXQgc3RyZWFtCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIElucHV0U3RyZWFtIGdldE1pbWVTdHJlYW0oKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL1NoYXJlZEJ5dGVBcnJheU91dHB1dFN0cmVhbS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL1NoYXJlZEJ5dGVBcnJheU91dHB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlmZDYxN2UKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvU2hhcmVkQnl0ZUFycmF5T3V0cHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSw0MCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAxMiwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwudXRpbDsKKworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CisKK2ltcG9ydCBqYXZheC5tYWlsLnV0aWwuU2hhcmVkQnl0ZUFycmF5SW5wdXRTdHJlYW07CisKKy8qKgorICogQSBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gdGhhdCBhbGxvd3MgdXMgdG8gc2hhcmUgdGhlIGJ5dGUgYXJyYXkKKyAqIHJhdGhlciB0aGFuIGNvcHkgaXQuICBFdmVudHVhbGx5IGNvdWxkIHJlcGxhY2UgdGhpcyB3aXRoIHNvbWV0aGluZworICogdGhhdCBkb2Vzbid0IHJlcXVpcmUgYSBzaW5nbGUgY29udGlndW91cyBieXRlIGFycmF5LgorICoKKyAqIEBhdXRob3IJQmlsbCBTaGFubm9uCisgKiBAc2luY2UJSmF2YU1haWwgMS40LjUKKyAqLworcHVibGljIGNsYXNzIFNoYXJlZEJ5dGVBcnJheU91dHB1dFN0cmVhbSBleHRlbmRzIEJ5dGVBcnJheU91dHB1dFN0cmVhbSB7CisgICAgcHVibGljIFNoYXJlZEJ5dGVBcnJheU91dHB1dFN0cmVhbShpbnQgc2l6ZSkgeworCXN1cGVyKHNpemUpOworICAgIH0KKworICAgIHB1YmxpYyBJbnB1dFN0cmVhbSB0b1N0cmVhbSgpIHsKKwlyZXR1cm4gbmV3IFNoYXJlZEJ5dGVBcnJheUlucHV0U3RyZWFtKGJ1ZiwgMCwgY291bnQpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvdXRpbC9Tb2NrZXRDb25uZWN0RXhjZXB0aW9uLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvU29ja2V0Q29ubmVjdEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZiM2MxNmUKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvU29ja2V0Q29ubmVjdEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsMTA1IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC51dGlsOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworLyoqCisgKiBBbiBJT0V4Y2VwdGlvbiB0aGF0IGluZGljYXRlcyBhIHNvY2tldCBjb25uZWN0aW9uIGF0dGVtcHQgZmFpbGVkLgorICogVW5saWtlIGphdmEubmV0LkNvbm5lY3RFeGNlcHRpb24sIGl0IGluY2x1ZGVzIGRldGFpbHMgb2Ygd2hhdCB3ZQorICogd2VyZSB0cnlpbmcgdG8gY29ubmVjdCB0by4KKyAqCisgKiBAc2VlCQlqYXZhLm5ldC5Db25uZWN0RXhjZXB0aW9uCisgKiBAYXV0aG9yCUJpbGwgU2hhbm5vbgorICogQHNpbmNlIAlKYXZhTWFpbCAxLjUuMAorICovCisKK3B1YmxpYyBjbGFzcyBTb2NrZXRDb25uZWN0RXhjZXB0aW9uIGV4dGVuZHMgSU9FeGNlcHRpb24geworICAgIC8qKgorICAgICAqIFRoZSBzb2NrZXQgaG9zdCBuYW1lLgorICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nIGhvc3Q7CisgICAgLyoqCisgICAgICogVGhlIHNvY2tldCBwb3J0LgorICAgICAqLworICAgIHByaXZhdGUgaW50IHBvcnQ7CisgICAgLyoqCisgICAgICogVGhlIGNvbm5lY3Rpb24gdGltZW91dC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBjdG87CisgICAgLyoqCisgICAgICogVGhlIGdlbmVyYXRlZCBzZXJpYWwgaWQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMzk5Nzg3MTU2MDUzODc1NTQ2M0w7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgU29ja2V0Q29ubmVjdEV4Y2VwdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbQltc2cJZXJyb3IgbWVzc2FnZSBkZXRhaWwKKyAgICAgKiBAcGFyYW0JY2F1c2UJdGhlIHVuZGVybHlpbmcgZXhjZXB0aW9uIHRoYXQgaW5kaWNhdGVzIHRoZSBmYWlsdXJlCisgICAgICogQHBhcmFtCWhvc3QJdGhlIGhvc3Qgd2Ugd2VyZSB0cnlpbmcgdG8gY29ubmVjdCB0bworICAgICAqIEBwYXJhbQlwb3J0CXRoZSBwb3J0IHdlIHdlcmUgdHJ5aW5nIHRvIGNvbm5lY3QgdG8KKyAgICAgKiBAcGFyYW0JY3RvCXRoZSB0aW1lb3V0IGZvciB0aGUgY29ubmVjdGlvbiBhdHRlbXB0CisgICAgICovCisgICAgcHVibGljIFNvY2tldENvbm5lY3RFeGNlcHRpb24oU3RyaW5nIG1zZywgRXhjZXB0aW9uIGNhdXNlLAorCQkJCSAgICBTdHJpbmcgaG9zdCwgaW50IHBvcnQsIGludCBjdG8pIHsKKwlzdXBlcihtc2cpOworCWluaXRDYXVzZShjYXVzZSk7CisJdGhpcy5ob3N0ID0gaG9zdDsKKwl0aGlzLnBvcnQgPSBwb3J0OworCXRoaXMuY3RvID0gY3RvOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBleGNlcHRpb24gdGhhdCBjYXVzZWQgdGhlIGZhaWx1cmUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBleGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgRXhjZXB0aW9uIGdldEV4Y2VwdGlvbigpIHsKKwkvLyB0aGUgImNhdXNlIiBpcyBhbHdheXMgYW4gRXhjZXB0aW9uOyBzZWUgY29uc3RydWN0b3IgYWJvdmUKKwlUaHJvd2FibGUgdCA9IGdldENhdXNlKCk7CisJYXNzZXJ0IHQgPT0gbnVsbCB8fCB0IGluc3RhbmNlb2YgRXhjZXB0aW9uOworCXJldHVybiAoRXhjZXB0aW9uKSB0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBob3N0IHdlIHdlcmUgdHJ5aW5nIHRvIGNvbm5lY3QgdG8uCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBob3N0CisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRIb3N0KCkgeworCXJldHVybiBob3N0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBwb3J0IHdlIHdlcmUgdHJ5aW5nIHRvIGNvbm5lY3QgdG8uCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBwb3J0CisgICAgICovCisgICAgcHVibGljIGludCBnZXRQb3J0KCkgeworCXJldHVybiBwb3J0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSB0aW1lb3V0IHVzZWQgZm9yIHRoZSBjb25uZWN0aW9uIGF0dGVtcHQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBjb25uZWN0aW9uIHRpbWVvdXQKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldENvbm5lY3Rpb25UaW1lb3V0KCkgeworCXJldHVybiBjdG87CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL1NvY2tldEZldGNoZXIuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvdXRpbC9Tb2NrZXRGZXRjaGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDZhZjIyMAotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvdXRpbC9Tb2NrZXRGZXRjaGVyLmphdmEKQEAgLTAsMCArMSw4OTUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLnV0aWw7CisKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lio7CitpbXBvcnQgamF2YS5uZXQuKjsKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuU29ja2V0Q2hhbm5lbDsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LlN0YW5kYXJkQ2hhcnNldHM7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuKjsKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBqYXZhLnV0aWwucmVnZXguKjsKK2ltcG9ydCBqYXZhLnV0aWwubG9nZ2luZy5MZXZlbDsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LmNlcnQuKjsKK2ltcG9ydCBqYXZheC5uZXQuKjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLio7CisKKy8qKgorICogVGhpcyBjbGFzcyBpcyB1c2VkIHRvIGdldCBTb2NrZXRzLiBEZXBlbmRpbmcgb24gdGhlIGFyZ3VtZW50cyBwYXNzZWQKKyAqIGl0IHdpbGwgZWl0aGVyIHJldHVybiBhIHBsYWluIGphdmEubmV0LlNvY2tldCBvciBkeW5hbWljYWxseSBsb2FkCisgKiB0aGUgU29ja2V0RmFjdG9yeSBjbGFzcyBzcGVjaWZpZWQgaW4gdGhlIGNsYXNzbmFtZSBwYXJhbSBhbmQgcmV0dXJuCisgKiBhIHNvY2tldCBjcmVhdGVkIGJ5IHRoYXQgU29ja2V0RmFjdG9yeS4KKyAqCisgKiBAYXV0aG9yIE1heCBTcGl2YWsKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKi8KK3B1YmxpYyBjbGFzcyBTb2NrZXRGZXRjaGVyIHsKKworICAgIHByaXZhdGUgc3RhdGljIE1haWxMb2dnZXIgbG9nZ2VyID0gbmV3IE1haWxMb2dnZXIoCisJU29ja2V0RmV0Y2hlci5jbGFzcywKKwkic29ja2V0IiwKKwkiREVCVUcgU29ja2V0RmV0Y2hlciIsCisJUHJvcFV0aWwuZ2V0Qm9vbGVhblN5c3RlbVByb3BlcnR5KCJtYWlsLnNvY2tldC5kZWJ1ZyIsIGZhbHNlKSwKKwlTeXN0ZW0ub3V0KTsKKworICAgIC8vIE5vIG9uZSBzaG91bGQgaW5zdGFudGlhdGUgdGhpcyBjbGFzcy4KKyAgICBwcml2YXRlIFNvY2tldEZldGNoZXIoKSB7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgcmV0dXJucyBhIFNvY2tldC4gIFByb3BlcnRpZXMgY29udHJvbCB0aGUgdXNlIG9mCisgICAgICogc29ja2V0IGZhY3RvcmllcyBhbmQgb3RoZXIgc29ja2V0IGNoYXJhY3RlcmlzdGljcy4gIFRoZSBwcm9wZXJ0aWVzCisgICAgICogdXNlZCBhcmU6CisgICAgICogPHVsPgorICAgICAqIDxsaT4gPGk+cHJlZml4PC9pPi5zb2NrZXRGYWN0b3J5CisgICAgICogPGxpPiA8aT5wcmVmaXg8L2k+LnNvY2tldEZhY3RvcnkuY2xhc3MKKyAgICAgKiA8bGk+IDxpPnByZWZpeDwvaT4uc29ja2V0RmFjdG9yeS5mYWxsYmFjaworICAgICAqIDxsaT4gPGk+cHJlZml4PC9pPi5zb2NrZXRGYWN0b3J5LnBvcnQKKyAgICAgKiA8bGk+IDxpPnByZWZpeDwvaT4uc3NsLnNvY2tldEZhY3RvcnkKKyAgICAgKiA8bGk+IDxpPnByZWZpeDwvaT4uc3NsLnNvY2tldEZhY3RvcnkuY2xhc3MKKyAgICAgKiA8bGk+IDxpPnByZWZpeDwvaT4uc3NsLnNvY2tldEZhY3RvcnkucG9ydAorICAgICAqIDxsaT4gPGk+cHJlZml4PC9pPi50aW1lb3V0CisgICAgICogPGxpPiA8aT5wcmVmaXg8L2k+LmNvbm5lY3Rpb250aW1lb3V0CisgICAgICogPGxpPiA8aT5wcmVmaXg8L2k+LmxvY2FsYWRkcmVzcworICAgICAqIDxsaT4gPGk+cHJlZml4PC9pPi5sb2NhbHBvcnQKKyAgICAgKiA8bGk+IDxpPnByZWZpeDwvaT4udXNlc29ja2V0Y2hhbm5lbHMKKyAgICAgKiA8L3VsPiA8cD4KKyAgICAgKiBJZiB3ZSdyZSBtYWtpbmcgYW4gU1NMIGNvbm5lY3Rpb24sIHRoZSBzc2wuc29ja2V0RmFjdG9yeQorICAgICAqIHByb3BlcnRpZXMgYXJlIHVzZWQgZmlyc3QsIGlmIHNldC4gPHA+CisgICAgICoKKyAgICAgKiBJZiB0aGUgc29ja2V0RmFjdG9yeSBwcm9wZXJ0eSBpcyBzZXQsIHRoZSB2YWx1ZSBpcyBhbgorICAgICAqIGluc3RhbmNlIG9mIGEgU29ja2V0RmFjdG9yeSBjbGFzcywgbm90IGEgc3RyaW5nLiAgVGhlCisgICAgICogaW5zdGFuY2UgaXMgdXNlZCBkaXJlY3RseS4gIElmIHRoZSBzb2NrZXRGYWN0b3J5IHByb3BlcnR5CisgICAgICogaXMgbm90IHNldCwgdGhlIHNvY2tldEZhY3RvcnkuY2xhc3MgcHJvcGVydHkgaXMgY29uc2lkZXJlZC4KKyAgICAgKiAoTm90ZSB0aGF0IHRoZSBTb2NrZXRGYWN0b3J5IHByb3BlcnR5IG11c3QgYmUgc2V0IHVzaW5nIHRoZQorICAgICAqIDxjb2RlPnB1dDwvY29kZT4gbWV0aG9kLCBub3QgdGhlIDxjb2RlPnNldFByb3BlcnR5PC9jb2RlPgorICAgICAqIG1ldGhvZC4pIDxwPgorICAgICAqCisgICAgICogSWYgdGhlIHNvY2tldEZhY3RvcnkuY2xhc3MgcHJvcGVydHkgaXNuJ3Qgc2V0LCB0aGUgc29ja2V0CisgICAgICogcmV0dXJuZWQgaXMgYW4gaW5zdGFuY2Ugb2YgamF2YS5uZXQuU29ja2V0IGNvbm5lY3RlZCB0byB0aGUKKyAgICAgKiBnaXZlbiBob3N0IGFuZCBwb3J0LiBJZiB0aGUgc29ja2V0RmFjdG9yeS5jbGFzcyBwcm9wZXJ0eSBpcyBzZXQsCisgICAgICogaXQgaXMgZXhwZWN0ZWQgdG8gY29udGFpbiBhIGZ1bGx5IHF1YWxpZmllZCBjbGFzc25hbWUgb2YgYQorICAgICAqIGphdmF4Lm5ldC5Tb2NrZXRGYWN0b3J5IHN1YmNsYXNzLiAgSW4gdGhpcyBjYXNlLCB0aGUgY2xhc3MgaXMKKyAgICAgKiBkeW5hbWljYWxseSBpbnN0YW50aWF0ZWQgYW5kIGEgc29ja2V0IGNyZWF0ZWQgYnkgdGhhdAorICAgICAqIFNvY2tldEZhY3RvcnkgaXMgcmV0dXJuZWQuIDxwPgorICAgICAqCisgICAgICogSWYgdGhlIHNvY2tldEZhY3RvcnkuZmFsbGJhY2sgcHJvcGVydHkgaXMgc2V0IHRvIGZhbHNlLCBkb24ndAorICAgICAqIGZhbGwgYmFjayB0byB1c2luZyByZWd1bGFyIHNvY2tldHMgaWYgdGhlIHNvY2tldCBmYWN0b3J5IGZhaWxzLiA8cD4KKyAgICAgKgorICAgICAqIFRoZSBzb2NrZXRGYWN0b3J5LnBvcnQgc3BlY2lmaWVzIGEgcG9ydCB0byB1c2Ugd2hlbiBjb25uZWN0aW5nCisgICAgICogdGhyb3VnaCB0aGUgc29ja2V0IGZhY3RvcnkuICBJZiB1bnNldCwgdGhlIHBvcnQgYXJndW1lbnQgd2lsbCBiZQorICAgICAqIHVzZWQuICA8cD4KKyAgICAgKgorICAgICAqIElmIHRoZSBjb25uZWN0aW9udGltZW91dCBwcm9wZXJ0eSBpcyBzZXQsIHRoZSB0aW1lb3V0IGlzIHBhc3NlZAorICAgICAqIHRvIHRoZSBzb2NrZXQgY29ubmVjdCBtZXRob2QuIDxwPgorICAgICAqCisgICAgICogSWYgdGhlIHRpbWVvdXQgcHJvcGVydHkgaXMgc2V0LCBpdCBpcyB1c2VkIHRvIHNldCB0aGUgc29ja2V0IHRpbWVvdXQuCisgICAgICogPHA+CisgICAgICoKKyAgICAgKiBJZiB0aGUgbG9jYWxhZGRyZXNzIHByb3BlcnR5IGlzIHNldCwgaXQncyB1c2VkIGFzIHRoZSBsb2NhbCBhZGRyZXNzCisgICAgICogdG8gYmluZCB0by4gIElmIHRoZSBsb2NhbHBvcnQgcHJvcGVydHkgaXMgYWxzbyBzZXQsIGl0J3MgdXNlZCBhcyB0aGUKKyAgICAgKiBsb2NhbCBwb3J0IG51bWJlciB0byBiaW5kIHRvLiA8cD4KKyAgICAgKgorICAgICAqIElmIHRoZSB1c2Vzb2NrZXRjaGFubmVscyBwcm9wZXJ0eSBpcyBzZXQsIGFuZCB3ZSBjcmVhdGUgdGhlIFNvY2tldAorICAgICAqIG91cnNlbGYsIGFuZCB0aGUgc2VsZWN0aW9uIG9mIG90aGVyIHByb3BlcnRpZXMgYWxsb3dzLCBjcmVhdGUgYQorICAgICAqIFNvY2tldENoYW5uZWwgYW5kIGdldCB0aGUgU29ja2V0IGZyb20gaXQuICBUaGlzIGFsbG93cyB1cyB0byBsYXRlcgorICAgICAqIHJldHJpZXZlIHRoZSBTb2NrZXRDaGFubmVsIGZyb20gdGhlIFNvY2tldCBhbmQgdXNlIGl0IHdpdGggU2VsZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIGhvc3QgVGhlIGhvc3QgdG8gY29ubmVjdCB0bworICAgICAqIEBwYXJhbSBwb3J0IFRoZSBwb3J0IHRvIGNvbm5lY3QgdG8gYXQgdGhlIGhvc3QKKyAgICAgKiBAcGFyYW0gcHJvcHMgUHJvcGVydGllcyBvYmplY3QgY29udGFpbmluZyBzb2NrZXQgcHJvcGVydGllcworICAgICAqIEBwYXJhbSBwcmVmaXggUHJvcGVydHkgbmFtZSBwcmVmaXgsIGUuZy4sICJtYWlsLmltYXAiCisgICAgICogQHBhcmFtIHVzZVNTTCB1c2UgdGhlIFNTTCBzb2NrZXQgZmFjdG9yeSBhcyB0aGUgZGVmYXVsdAorICAgICAqIEByZXR1cm4JCXRoZSBTb2NrZXQKKyAgICAgKiBAZXhjZXB0aW9uCUlPRXhjZXB0aW9uCWZvciBJL08gZXJyb3JzCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTb2NrZXQgZ2V0U29ja2V0KFN0cmluZyBob3N0LCBpbnQgcG9ydCwgUHJvcGVydGllcyBwcm9wcywKKwkJCQlTdHJpbmcgcHJlZml4LCBib29sZWFuIHVzZVNTTCkKKwkJCQl0aHJvd3MgSU9FeGNlcHRpb24geworCisJaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkVSKSkKKwkgICAgbG9nZ2VyLmZpbmVyKCJnZXRTb2NrZXQiICsgIiwgaG9zdCAiICsgaG9zdCArICIsIHBvcnQgIiArIHBvcnQgKworCQkJCSIsIHByZWZpeCAiICsgcHJlZml4ICsgIiwgdXNlU1NMICIgKyB1c2VTU0wpOworCWlmIChwcmVmaXggPT0gbnVsbCkKKwkgICAgcHJlZml4ID0gInNvY2tldCI7CisJaWYgKHByb3BzID09IG51bGwpCisJICAgIHByb3BzID0gbmV3IFByb3BlcnRpZXMoKTsJLy8gZW1wdHkKKwlpbnQgY3RvID0gUHJvcFV0aWwuZ2V0SW50UHJvcGVydHkocHJvcHMsCisJCQkJCXByZWZpeCArICIuY29ubmVjdGlvbnRpbWVvdXQiLCAtMSk7CisJU29ja2V0IHNvY2tldCA9IG51bGw7CisJU3RyaW5nIGxvY2FsYWRkcnN0ciA9IHByb3BzLmdldFByb3BlcnR5KHByZWZpeCArICIubG9jYWxhZGRyZXNzIiwgbnVsbCk7CisJSW5ldEFkZHJlc3MgbG9jYWxhZGRyID0gbnVsbDsKKwlpZiAobG9jYWxhZGRyc3RyICE9IG51bGwpCisJICAgIGxvY2FsYWRkciA9IEluZXRBZGRyZXNzLmdldEJ5TmFtZShsb2NhbGFkZHJzdHIpOworCWludCBsb2NhbHBvcnQgPSBQcm9wVXRpbC5nZXRJbnRQcm9wZXJ0eShwcm9wcywKKwkJCQkJcHJlZml4ICsgIi5sb2NhbHBvcnQiLCAwKTsKKworCWJvb2xlYW4gZmIgPSBQcm9wVXRpbC5nZXRCb29sZWFuUHJvcGVydHkocHJvcHMsCisJCQkJcHJlZml4ICsgIi5zb2NrZXRGYWN0b3J5LmZhbGxiYWNrIiwgdHJ1ZSk7CisKKwlpbnQgc2ZQb3J0ID0gLTE7CisJU3RyaW5nIHNmRXJyID0gInVua25vd24gc29ja2V0IGZhY3RvcnkiOworCWludCB0byA9IFByb3BVdGlsLmdldEludFByb3BlcnR5KHByb3BzLCBwcmVmaXggKyAiLnRpbWVvdXQiLCAtMSk7CisJdHJ5IHsKKwkgICAgLyoKKwkgICAgICogSWYgdXNpbmcgU1NMLCBmaXJzdCBsb29rIGZvciBTU0wtc3BlY2lmaWMgY2xhc3MgbmFtZSBvcgorCSAgICAgKiBmYWN0b3J5IGluc3RhbmNlLgorCSAgICAgKi8KKwkgICAgU29ja2V0RmFjdG9yeSBzZiA9IG51bGw7CisJICAgIFN0cmluZyBzZlBvcnROYW1lID0gbnVsbDsKKwkgICAgaWYgKHVzZVNTTCkgeworCQlPYmplY3Qgc2ZvID0gcHJvcHMuZ2V0KHByZWZpeCArICIuc3NsLnNvY2tldEZhY3RvcnkiKTsKKwkJaWYgKHNmbyBpbnN0YW5jZW9mIFNvY2tldEZhY3RvcnkpIHsKKwkJICAgIHNmID0gKFNvY2tldEZhY3Rvcnkpc2ZvOworCQkgICAgc2ZFcnIgPSAiU1NMIHNvY2tldCBmYWN0b3J5IGluc3RhbmNlICIgKyBzZjsKKwkJfQorCQlpZiAoc2YgPT0gbnVsbCkgeworCQkgICAgU3RyaW5nIHNmQ2xhc3MgPQorCQkJcHJvcHMuZ2V0UHJvcGVydHkocHJlZml4ICsgIi5zc2wuc29ja2V0RmFjdG9yeS5jbGFzcyIpOworCQkgICAgc2YgPSBnZXRTb2NrZXRGYWN0b3J5KHNmQ2xhc3MpOworCQkgICAgc2ZFcnIgPSAiU1NMIHNvY2tldCBmYWN0b3J5IGNsYXNzICIgKyBzZkNsYXNzOworCQl9CisJCXNmUG9ydE5hbWUgPSAiLnNzbC5zb2NrZXRGYWN0b3J5LnBvcnQiOworCSAgICB9CisKKwkgICAgaWYgKHNmID09IG51bGwpIHsKKwkJT2JqZWN0IHNmbyA9IHByb3BzLmdldChwcmVmaXggKyAiLnNvY2tldEZhY3RvcnkiKTsKKwkJaWYgKHNmbyBpbnN0YW5jZW9mIFNvY2tldEZhY3RvcnkpIHsKKwkJICAgIHNmID0gKFNvY2tldEZhY3Rvcnkpc2ZvOworCQkgICAgc2ZFcnIgPSAic29ja2V0IGZhY3RvcnkgaW5zdGFuY2UgIiArIHNmOworCQl9CisJCWlmIChzZiA9PSBudWxsKSB7CisJCSAgICBTdHJpbmcgc2ZDbGFzcyA9CisJCQlwcm9wcy5nZXRQcm9wZXJ0eShwcmVmaXggKyAiLnNvY2tldEZhY3RvcnkuY2xhc3MiKTsKKwkJICAgIHNmID0gZ2V0U29ja2V0RmFjdG9yeShzZkNsYXNzKTsKKwkJICAgIHNmRXJyID0gInNvY2tldCBmYWN0b3J5IGNsYXNzICIgKyBzZkNsYXNzOworCQl9CisJCXNmUG9ydE5hbWUgPSAiLnNvY2tldEZhY3RvcnkucG9ydCI7CisJICAgIH0KKworCSAgICAvLyBpZiB3ZSBub3cgaGF2ZSBhIHNvY2tldCBmYWN0b3J5LCB1c2UgaXQKKwkgICAgaWYgKHNmICE9IG51bGwpIHsKKwkJc2ZQb3J0ID0gUHJvcFV0aWwuZ2V0SW50UHJvcGVydHkocHJvcHMsCisJCQkJCQlwcmVmaXggKyBzZlBvcnROYW1lLCAtMSk7CisKKwkJLy8gaWYgcG9ydCBwYXNzZWQgaW4gdmlhIHByb3BlcnR5IGlzbid0IHZhbGlkLCB1c2UgcGFyYW0KKwkJaWYgKHNmUG9ydCA9PSAtMSkKKwkJICAgIHNmUG9ydCA9IHBvcnQ7CisJCXNvY2tldCA9IGNyZWF0ZVNvY2tldChsb2NhbGFkZHIsIGxvY2FscG9ydCwKKwkJICAgIGhvc3QsIHNmUG9ydCwgY3RvLCB0bywgcHJvcHMsIHByZWZpeCwgc2YsIHVzZVNTTCk7CisJICAgIH0KKwl9IGNhdGNoIChTb2NrZXRUaW1lb3V0RXhjZXB0aW9uIHNleCkgeworCSAgICB0aHJvdyBzZXg7CisJfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJICAgIGlmICghZmIpIHsKKwkJaWYgKGV4IGluc3RhbmNlb2YgSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbikgeworCQkgICAgVGhyb3dhYmxlIHQgPQorCQkgICAgICAoKEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24pZXgpLmdldFRhcmdldEV4Y2VwdGlvbigpOworCQkgICAgaWYgKHQgaW5zdGFuY2VvZiBFeGNlcHRpb24pCisJCQlleCA9IChFeGNlcHRpb24pdDsKKwkJfQorCQlpZiAoZXggaW5zdGFuY2VvZiBJT0V4Y2VwdGlvbikKKwkJICAgIHRocm93IChJT0V4Y2VwdGlvbilleDsKKwkJdGhyb3cgbmV3IFNvY2tldENvbm5lY3RFeGNlcHRpb24oIlVzaW5nICIgKyBzZkVyciwgZXgsCisJCQkJCQlob3N0LCBzZlBvcnQsIGN0byk7CisJICAgIH0KKwl9CisKKwlpZiAoc29ja2V0ID09IG51bGwpIHsKKwkgICAgc29ja2V0ID0gY3JlYXRlU29ja2V0KGxvY2FsYWRkciwgbG9jYWxwb3J0LAorCQkgICAgaG9zdCwgcG9ydCwgY3RvLCB0bywgcHJvcHMsIHByZWZpeCwgbnVsbCwgdXNlU1NMKTsKKworCX0gZWxzZSB7CisJICAgIGlmICh0byA+PSAwKSB7CisJCWlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FU1QpKQorCQkgICAgbG9nZ2VyLmZpbmVzdCgic2V0IHNvY2tldCByZWFkIHRpbWVvdXQgIiArIHRvKTsKKwkJc29ja2V0LnNldFNvVGltZW91dCh0byk7CisJICAgIH0KKwl9CisKKwlyZXR1cm4gc29ja2V0OworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU29ja2V0IGdldFNvY2tldChTdHJpbmcgaG9zdCwgaW50IHBvcnQsIFByb3BlcnRpZXMgcHJvcHMsCisJCQkJU3RyaW5nIHByZWZpeCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlyZXR1cm4gZ2V0U29ja2V0KGhvc3QsIHBvcnQsIHByb3BzLCBwcmVmaXgsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBzb2NrZXQgd2l0aCB0aGUgZ2l2ZW4gbG9jYWwgYWRkcmVzcyBhbmQgY29ubmVjdGVkIHRvCisgICAgICogdGhlIGdpdmVuIGhvc3QgYW5kIHBvcnQuICBVc2UgdGhlIHNwZWNpZmllZCBjb25uZWN0aW9uIHRpbWVvdXQKKyAgICAgKiBhbmQgcmVhZCB0aW1lb3V0LgorICAgICAqIElmIGEgc29ja2V0IGZhY3RvcnkgaXMgc3BlY2lmaWVkLCB1c2UgaXQuICBPdGhlcndpc2UsIHVzZSB0aGUKKyAgICAgKiBTU0xTb2NrZXRGYWN0b3J5IGlmIHVzZVNTTCBpcyB0cnVlLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFNvY2tldCBjcmVhdGVTb2NrZXQoSW5ldEFkZHJlc3MgbG9jYWxhZGRyLCBpbnQgbG9jYWxwb3J0LAorCQkJCVN0cmluZyBob3N0LCBpbnQgcG9ydCwgaW50IGN0bywgaW50IHRvLAorCQkJCVByb3BlcnRpZXMgcHJvcHMsIFN0cmluZyBwcmVmaXgsCisJCQkJU29ja2V0RmFjdG9yeSBzZiwgYm9vbGVhbiB1c2VTU0wpCisJCQkJdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlTb2NrZXQgc29ja2V0ID0gbnVsbDsKKworCWlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FU1QpKQorCSAgICBsb2dnZXIuZmluZXN0KCJjcmVhdGUgc29ja2V0OiBwcmVmaXggIiArIHByZWZpeCArCisJCSIsIGxvY2FsYWRkciAiICsgbG9jYWxhZGRyICsgIiwgbG9jYWxwb3J0ICIgKyBsb2NhbHBvcnQgKworCQkiLCBob3N0ICIgKyBob3N0ICsgIiwgcG9ydCAiICsgcG9ydCArCisJCSIsIGNvbm5lY3Rpb24gdGltZW91dCAiICsgY3RvICsgIiwgdGltZW91dCAiICsgdG8gKworCQkiLCBzb2NrZXQgZmFjdG9yeSAiICsgc2YgKyAiLCB1c2VTU0wgIiArIHVzZVNTTCk7CisKKwlTdHJpbmcgcHJveHlIb3N0ID0gcHJvcHMuZ2V0UHJvcGVydHkocHJlZml4ICsgIi5wcm94eS5ob3N0IiwgbnVsbCk7CisJU3RyaW5nIHByb3h5VXNlciA9IHByb3BzLmdldFByb3BlcnR5KHByZWZpeCArICIucHJveHkudXNlciIsIG51bGwpOworCVN0cmluZyBwcm94eVBhc3N3b3JkID0gcHJvcHMuZ2V0UHJvcGVydHkocHJlZml4ICsgIi5wcm94eS5wYXNzd29yZCIsIG51bGwpOworCWludCBwcm94eVBvcnQgPSA4MDsKKwlTdHJpbmcgc29ja3NIb3N0ID0gbnVsbDsKKwlpbnQgc29ja3NQb3J0ID0gMTA4MDsKKwlTdHJpbmcgZXJyID0gbnVsbDsKKworCWlmIChwcm94eUhvc3QgIT0gbnVsbCkgeworCSAgICBpbnQgaSA9IHByb3h5SG9zdC5pbmRleE9mKCc6Jyk7CisJICAgIGlmIChpID49IDApIHsKKwkJdHJ5IHsKKwkJICAgIHByb3h5UG9ydCA9IEludGVnZXIucGFyc2VJbnQocHJveHlIb3N0LnN1YnN0cmluZyhpICsgMSkpOworCQl9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZXgpIHsKKwkJICAgIC8vIGlnbm9yZSBpdAorCQl9CisJCXByb3h5SG9zdCA9IHByb3h5SG9zdC5zdWJzdHJpbmcoMCwgaSk7CisJICAgIH0KKwkgICAgcHJveHlQb3J0ID0gUHJvcFV0aWwuZ2V0SW50UHJvcGVydHkocHJvcHMsCisJCQkJCXByZWZpeCArICIucHJveHkucG9ydCIsIHByb3h5UG9ydCk7CisJICAgIGVyciA9ICJVc2luZyB3ZWIgcHJveHkgaG9zdCwgcG9ydDogIiArIHByb3h5SG9zdCArICIsICIgKyBwcm94eVBvcnQ7CisJICAgIGlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FUikpIHsKKwkJbG9nZ2VyLmZpbmVyKCJ3ZWIgcHJveHkgaG9zdCAiICsgcHJveHlIb3N0ICsgIiwgcG9ydCAiICsgcHJveHlQb3J0KTsKKwkJaWYgKHByb3h5VXNlciAhPSBudWxsKQorCQkgICAgbG9nZ2VyLmZpbmVyKCJ3ZWIgcHJveHkgdXNlciAiICsgcHJveHlVc2VyICsgIiwgcGFzc3dvcmQgIiArCisJCQkocHJveHlQYXNzd29yZCA9PSBudWxsID8gIjxudWxsPiIgOiAiPG5vbi1udWxsPiIpKTsKKwkgICAgfQorCX0gZWxzZSBpZiAoKHNvY2tzSG9zdCA9CisJCSAgICBwcm9wcy5nZXRQcm9wZXJ0eShwcmVmaXggKyAiLnNvY2tzLmhvc3QiLCBudWxsKSkgIT0gbnVsbCkgeworCSAgICBpbnQgaSA9IHNvY2tzSG9zdC5pbmRleE9mKCc6Jyk7CisJICAgIGlmIChpID49IDApIHsKKwkJdHJ5IHsKKwkJICAgIHNvY2tzUG9ydCA9IEludGVnZXIucGFyc2VJbnQoc29ja3NIb3N0LnN1YnN0cmluZyhpICsgMSkpOworCQl9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZXgpIHsKKwkJICAgIC8vIGlnbm9yZSBpdAorCQl9CisJCXNvY2tzSG9zdCA9IHNvY2tzSG9zdC5zdWJzdHJpbmcoMCwgaSk7CisJICAgIH0KKwkgICAgc29ja3NQb3J0ID0gUHJvcFV0aWwuZ2V0SW50UHJvcGVydHkocHJvcHMsCisJCQkJCXByZWZpeCArICIuc29ja3MucG9ydCIsIHNvY2tzUG9ydCk7CisJICAgIGVyciA9ICJVc2luZyBTT0NLUyBob3N0LCBwb3J0OiAiICsgc29ja3NIb3N0ICsgIiwgIiArIHNvY2tzUG9ydDsKKwkgICAgaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkVSKSkKKwkJbG9nZ2VyLmZpbmVyKCJzb2NrcyBob3N0ICIgKyBzb2Nrc0hvc3QgKyAiLCBwb3J0ICIgKyBzb2Nrc1BvcnQpOworCX0KKworCWlmIChzZiAhPSBudWxsICYmICEoc2YgaW5zdGFuY2VvZiBTU0xTb2NrZXRGYWN0b3J5KSkKKwkgICAgc29ja2V0ID0gc2YuY3JlYXRlU29ja2V0KCk7CisJaWYgKHNvY2tldCA9PSBudWxsKSB7CisJICAgIGlmIChzb2Nrc0hvc3QgIT0gbnVsbCkgeworCQlzb2NrZXQgPSBuZXcgU29ja2V0KAorCQkJCW5ldyBqYXZhLm5ldC5Qcm94eShqYXZhLm5ldC5Qcm94eS5UeXBlLlNPQ0tTLAorCQkJCW5ldyBJbmV0U29ja2V0QWRkcmVzcyhzb2Nrc0hvc3QsIHNvY2tzUG9ydCkpKTsKKwkgICAgfSBlbHNlIGlmIChQcm9wVXRpbC5nZXRCb29sZWFuUHJvcGVydHkocHJvcHMsCisJCQkJCXByZWZpeCArICIudXNlc29ja2V0Y2hhbm5lbHMiLCBmYWxzZSkpIHsKKwkJbG9nZ2VyLmZpbmVyKCJ1c2luZyBTb2NrZXRDaGFubmVscyIpOworCQlzb2NrZXQgPSBTb2NrZXRDaGFubmVsLm9wZW4oKS5zb2NrZXQoKTsKKwkgICAgfSBlbHNlCisJCXNvY2tldCA9IG5ldyBTb2NrZXQoKTsKKwl9CisJaWYgKHRvID49IDApIHsKKwkgICAgaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkVTVCkpCisJCWxvZ2dlci5maW5lc3QoInNldCBzb2NrZXQgcmVhZCB0aW1lb3V0ICIgKyB0byk7CisJICAgIHNvY2tldC5zZXRTb1RpbWVvdXQodG8pOworCX0KKwlpbnQgd3JpdGVUaW1lb3V0ID0gUHJvcFV0aWwuZ2V0SW50UHJvcGVydHkocHJvcHMsCisJCQkJCQlwcmVmaXggKyAiLndyaXRldGltZW91dCIsIC0xKTsKKwlpZiAod3JpdGVUaW1lb3V0ICE9IC0xKSB7CS8vIHdyYXAgb3JpZ2luYWwKKwkgICAgaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkVTVCkpCisJCWxvZ2dlci5maW5lc3QoInNldCBzb2NrZXQgd3JpdGUgdGltZW91dCAiICsgd3JpdGVUaW1lb3V0KTsKKwkgICAgc29ja2V0ID0gbmV3IFdyaXRlVGltZW91dFNvY2tldChzb2NrZXQsIHdyaXRlVGltZW91dCk7CisJfQorCWlmIChsb2NhbGFkZHIgIT0gbnVsbCkKKwkgICAgc29ja2V0LmJpbmQobmV3IEluZXRTb2NrZXRBZGRyZXNzKGxvY2FsYWRkciwgbG9jYWxwb3J0KSk7CisJdHJ5IHsKKwkgICAgbG9nZ2VyLmZpbmVzdCgiY29ubmVjdGluZy4uLiIpOworCSAgICBpZiAocHJveHlIb3N0ICE9IG51bGwpCisJCXByb3h5Q29ubmVjdChzb2NrZXQsIHByb3h5SG9zdCwgcHJveHlQb3J0LAorCQkJCXByb3h5VXNlciwgcHJveHlQYXNzd29yZCwgaG9zdCwgcG9ydCwgY3RvKTsKKwkgICAgZWxzZSBpZiAoY3RvID49IDApCisJCXNvY2tldC5jb25uZWN0KG5ldyBJbmV0U29ja2V0QWRkcmVzcyhob3N0LCBwb3J0KSwgY3RvKTsKKwkgICAgZWxzZQorCQlzb2NrZXQuY29ubmVjdChuZXcgSW5ldFNvY2tldEFkZHJlc3MoaG9zdCwgcG9ydCkpOworCSAgICBsb2dnZXIuZmluZXN0KCJzdWNjZXNzISIpOworCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisJICAgIGxvZ2dlci5sb2coTGV2ZWwuRklORVNULCAiY29ubmVjdGlvbiBmYWlsZWQiLCBleCk7CisJICAgIHRocm93IG5ldyBTb2NrZXRDb25uZWN0RXhjZXB0aW9uKGVyciwgZXgsIGhvc3QsIHBvcnQsIGN0byk7CisJfQorCisJLyoKKwkgKiBJZiB3ZSB3YW50IGFuIFNTTCBjb25uZWN0aW9uIGFuZCB3ZSBkaWRuJ3QgZ2V0IGFuIFNTTFNvY2tldCwKKwkgKiB3cmFwIG91ciBwbGFpbiBTb2NrZXQgd2l0aCBhbiBTU0xTb2NrZXQuCisJICovCisJaWYgKCh1c2VTU0wgfHwgc2YgaW5zdGFuY2VvZiBTU0xTb2NrZXRGYWN0b3J5KSAmJgorCQkhKHNvY2tldCBpbnN0YW5jZW9mIFNTTFNvY2tldCkpIHsKKwkgICAgU3RyaW5nIHRydXN0ZWQ7CisJICAgIFNTTFNvY2tldEZhY3Rvcnkgc3NmOworCSAgICBpZiAoKHRydXN0ZWQgPSBwcm9wcy5nZXRQcm9wZXJ0eShwcmVmaXggKyAiLnNzbC50cnVzdCIpKSAhPSBudWxsKSB7CisJCXRyeSB7CisJCSAgICBNYWlsU1NMU29ja2V0RmFjdG9yeSBtc2YgPSBuZXcgTWFpbFNTTFNvY2tldEZhY3RvcnkoKTsKKwkJICAgIGlmICh0cnVzdGVkLmVxdWFscygiKiIpKQorCQkJbXNmLnNldFRydXN0QWxsSG9zdHModHJ1ZSk7CisJCSAgICBlbHNlCisJCQltc2Yuc2V0VHJ1c3RlZEhvc3RzKHRydXN0ZWQuc3BsaXQoIlxccysiKSk7CisJCSAgICBzc2YgPSBtc2Y7CisJCX0gY2F0Y2ggKEdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbiBnZXgpIHsKKwkJICAgIElPRXhjZXB0aW9uIGlvZXggPSBuZXcgSU9FeGNlcHRpb24oCisJCQkJICAgICJDYW4ndCBjcmVhdGUgTWFpbFNTTFNvY2tldEZhY3RvcnkiKTsKKwkJICAgIGlvZXguaW5pdENhdXNlKGdleCk7CisJCSAgICB0aHJvdyBpb2V4OworCQl9CisJICAgIH0gZWxzZSBpZiAoc2YgaW5zdGFuY2VvZiBTU0xTb2NrZXRGYWN0b3J5KQorCQlzc2YgPSAoU1NMU29ja2V0RmFjdG9yeSlzZjsKKwkgICAgZWxzZQorCQlzc2YgPSAoU1NMU29ja2V0RmFjdG9yeSlTU0xTb2NrZXRGYWN0b3J5LmdldERlZmF1bHQoKTsKKwkgICAgc29ja2V0ID0gc3NmLmNyZWF0ZVNvY2tldChzb2NrZXQsIGhvc3QsIHBvcnQsIHRydWUpOworCSAgICBzZiA9IHNzZjsKKwl9CisKKwkvKgorCSAqIE5vIG1hdHRlciBob3cgd2UgY3JlYXRlZCB0aGUgc29ja2V0LCBpZiBpdCB0dXJucyBvdXQgdG8gYmUgYW4KKwkgKiBTU0xTb2NrZXQsIGNvbmZpZ3VyZSBpdC4KKwkgKi8KKwljb25maWd1cmVTU0xTb2NrZXQoc29ja2V0LCBob3N0LCBwcm9wcywgcHJlZml4LCBzZik7CisKKwlyZXR1cm4gc29ja2V0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiBhIHNvY2tldCBmYWN0b3J5IG9mIHRoZSBzcGVjaWZpZWQgY2xhc3MuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgU29ja2V0RmFjdG9yeSBnZXRTb2NrZXRGYWN0b3J5KFN0cmluZyBzZkNsYXNzKQorCQkJCXRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uLAorCQkJCSAgICBOb1N1Y2hNZXRob2RFeGNlcHRpb24sCisJCQkJICAgIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24sCisJCQkJICAgIEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24geworCWlmIChzZkNsYXNzID09IG51bGwgfHwgc2ZDbGFzcy5sZW5ndGgoKSA9PSAwKQorCSAgICByZXR1cm4gbnVsbDsKKworCS8vIGR5bmFtaWNhbGx5IGxvYWQgdGhlIGNsYXNzCisKKwlDbGFzc0xvYWRlciBjbCA9IGdldENvbnRleHRDbGFzc0xvYWRlcigpOworCUNsYXNzPD8+IGNsc1NvY2tGYWN0ID0gbnVsbDsKKwlpZiAoY2wgIT0gbnVsbCkgeworCSAgICB0cnkgeworCQljbHNTb2NrRmFjdCA9IENsYXNzLmZvck5hbWUoc2ZDbGFzcywgZmFsc2UsIGNsKTsKKwkgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBjZXgpIHsgfQorCX0KKwlpZiAoY2xzU29ja0ZhY3QgPT0gbnVsbCkKKwkgICAgY2xzU29ja0ZhY3QgPSBDbGFzcy5mb3JOYW1lKHNmQ2xhc3MpOworCS8vIGdldCAmIGludm9rZSB0aGUgZ2V0RGVmYXVsdCgpIG1ldGhvZAorCU1ldGhvZCBtdGhHZXREZWZhdWx0ID0gY2xzU29ja0ZhY3QuZ2V0TWV0aG9kKCJnZXREZWZhdWx0IiwKKwkJCQkJCSAgICAgbmV3IENsYXNzPD8+W117fSk7CisJU29ja2V0RmFjdG9yeSBzZiA9IChTb2NrZXRGYWN0b3J5KQorCSAgICBtdGhHZXREZWZhdWx0Lmludm9rZShuZXcgT2JqZWN0KCksIG5ldyBPYmplY3RbXXt9KTsKKwlyZXR1cm4gc2Y7CisgICAgfQorCisgICAgLyoqCisgICAgICogU3RhcnQgVExTIG9uIGFuIGV4aXN0aW5nIHNvY2tldC4KKyAgICAgKiBTdXBwb3J0cyB0aGUgIlNUQVJUVExTIiBjb21tYW5kIGluIG1hbnkgcHJvdG9jb2xzLgorICAgICAqIFRoaXMgdmVyc2lvbiBmb3IgY29tcGF0aWJpbGl0eSB3aXRoIHBvc3NpYmxlIHRoaXJkIHBhcnR5IGNvZGUKKyAgICAgKiB0aGF0IG1pZ2h0J3ZlIHVzZWQgdGhpcyBBUEkgZXZlbiB0aG91Z2ggaXQgc2hvdWxkbid0LgorICAgICAqCisgICAgICogQHBhcmFtCXNvY2tldAl0aGUgZXhpc3Rpbmcgc29ja2V0CisgICAgICogQHJldHVybgkJdGhlIHdyYXBwZWQgU29ja2V0CisgICAgICogQGV4Y2VwdGlvbglJT0V4Y2VwdGlvbglmb3IgSS9PIGVycm9ycworICAgICAqIEBkZXByZWNhdGVkCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgc3RhdGljIFNvY2tldCBzdGFydFRMUyhTb2NrZXQgc29ja2V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworCXJldHVybiBzdGFydFRMUyhzb2NrZXQsIG5ldyBQcm9wZXJ0aWVzKCksICJzb2NrZXQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTdGFydCBUTFMgb24gYW4gZXhpc3Rpbmcgc29ja2V0LgorICAgICAqIFN1cHBvcnRzIHRoZSAiU1RBUlRUTFMiIGNvbW1hbmQgaW4gbWFueSBwcm90b2NvbHMuCisgICAgICogVGhpcyB2ZXJzaW9uIGZvciBjb21wYXRpYmlsaXR5IHdpdGggcG9zc2libGUgdGhpcmQgcGFydHkgY29kZQorICAgICAqIHRoYXQgbWlnaHQndmUgdXNlZCB0aGlzIEFQSSBldmVuIHRob3VnaCBpdCBzaG91bGRuJ3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jc29ja2V0CXRoZSBleGlzdGluZyBzb2NrZXQKKyAgICAgKiBAcGFyYW0JcHJvcHMJdGhlIHByb3BlcnRpZXMKKyAgICAgKiBAcGFyYW0JcHJlZml4CXRoZSBwcm9wZXJ0eSBwcmVmaXgKKyAgICAgKiBAcmV0dXJuCQl0aGUgd3JhcHBlZCBTb2NrZXQKKyAgICAgKiBAZXhjZXB0aW9uCUlPRXhjZXB0aW9uCWZvciBJL08gZXJyb3JzCisgICAgICogQGRlcHJlY2F0ZWQKKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBzdGF0aWMgU29ja2V0IHN0YXJ0VExTKFNvY2tldCBzb2NrZXQsIFByb3BlcnRpZXMgcHJvcHMsCisJCQkJU3RyaW5nIHByZWZpeCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlJbmV0QWRkcmVzcyBhID0gc29ja2V0LmdldEluZXRBZGRyZXNzKCk7CisJU3RyaW5nIGhvc3QgPSBhLmdldEhvc3ROYW1lKCk7CisJcmV0dXJuIHN0YXJ0VExTKHNvY2tldCwgaG9zdCwgcHJvcHMsIHByZWZpeCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU3RhcnQgVExTIG9uIGFuIGV4aXN0aW5nIHNvY2tldC4KKyAgICAgKiBTdXBwb3J0cyB0aGUgIlNUQVJUVExTIiBjb21tYW5kIGluIG1hbnkgcHJvdG9jb2xzLgorICAgICAqCisgICAgICogQHBhcmFtCXNvY2tldAl0aGUgZXhpc3Rpbmcgc29ja2V0CisgICAgICogQHBhcmFtCWhvc3QJdGhlIGhvc3QgdGhlIHNvY2tldCBpcyBjb25uZWN0ZWQgdG8KKyAgICAgKiBAcGFyYW0JcHJvcHMJdGhlIHByb3BlcnRpZXMKKyAgICAgKiBAcGFyYW0JcHJlZml4CXRoZSBwcm9wZXJ0eSBwcmVmaXgKKyAgICAgKiBAcmV0dXJuCQl0aGUgd3JhcHBlZCBTb2NrZXQKKyAgICAgKiBAZXhjZXB0aW9uCUlPRXhjZXB0aW9uCWZvciBJL08gZXJyb3JzCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTb2NrZXQgc3RhcnRUTFMoU29ja2V0IHNvY2tldCwgU3RyaW5nIGhvc3QsIFByb3BlcnRpZXMgcHJvcHMsCisJCQkJU3RyaW5nIHByZWZpeCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlpbnQgcG9ydCA9IHNvY2tldC5nZXRQb3J0KCk7CisJaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkVSKSkKKwkgICAgbG9nZ2VyLmZpbmVyKCJzdGFydFRMUyBob3N0ICIgKyBob3N0ICsgIiwgcG9ydCAiICsgcG9ydCk7CisKKwlTdHJpbmcgc2ZFcnIgPSAidW5rbm93biBzb2NrZXQgZmFjdG9yeSI7CisJdHJ5IHsKKwkgICAgU1NMU29ja2V0RmFjdG9yeSBzc2YgPSBudWxsOworCSAgICBTb2NrZXRGYWN0b3J5IHNmID0gbnVsbDsKKworCSAgICAvLyBmaXJzdCwgbG9vayBmb3IgYW4gU1NMIHNvY2tldCBmYWN0b3J5CisJICAgIE9iamVjdCBzZm8gPSBwcm9wcy5nZXQocHJlZml4ICsgIi5zc2wuc29ja2V0RmFjdG9yeSIpOworCSAgICBpZiAoc2ZvIGluc3RhbmNlb2YgU29ja2V0RmFjdG9yeSkgeworCQlzZiA9IChTb2NrZXRGYWN0b3J5KXNmbzsKKwkJc2ZFcnIgPSAiU1NMIHNvY2tldCBmYWN0b3J5IGluc3RhbmNlICIgKyBzZjsKKwkgICAgfQorCSAgICBpZiAoc2YgPT0gbnVsbCkgeworCQlTdHJpbmcgc2ZDbGFzcyA9CisJCSAgICBwcm9wcy5nZXRQcm9wZXJ0eShwcmVmaXggKyAiLnNzbC5zb2NrZXRGYWN0b3J5LmNsYXNzIik7CisJCXNmID0gZ2V0U29ja2V0RmFjdG9yeShzZkNsYXNzKTsKKwkJc2ZFcnIgPSAiU1NMIHNvY2tldCBmYWN0b3J5IGNsYXNzICIgKyBzZkNsYXNzOworCSAgICB9CisJICAgIGlmIChzZiAhPSBudWxsICYmIHNmIGluc3RhbmNlb2YgU1NMU29ja2V0RmFjdG9yeSkKKwkJc3NmID0gKFNTTFNvY2tldEZhY3Rvcnkpc2Y7CisKKwkgICAgLy8gbmV4dCwgbG9vayBmb3IgYSByZWd1bGFyIHNvY2tldCBmYWN0b3J5IHRoYXQgaGFwcGVucyB0byBiZQorCSAgICAvLyBhbiBTU0wgc29ja2V0IGZhY3RvcnkKKwkgICAgaWYgKHNzZiA9PSBudWxsKSB7CisJCXNmbyA9IHByb3BzLmdldChwcmVmaXggKyAiLnNvY2tldEZhY3RvcnkiKTsKKwkJaWYgKHNmbyBpbnN0YW5jZW9mIFNvY2tldEZhY3RvcnkpIHsKKwkJICAgIHNmID0gKFNvY2tldEZhY3Rvcnkpc2ZvOworCQkgICAgc2ZFcnIgPSAic29ja2V0IGZhY3RvcnkgaW5zdGFuY2UgIiArIHNmOworCQl9CisJCWlmIChzZiA9PSBudWxsKSB7CisJCSAgICBTdHJpbmcgc2ZDbGFzcyA9CisJCQlwcm9wcy5nZXRQcm9wZXJ0eShwcmVmaXggKyAiLnNvY2tldEZhY3RvcnkuY2xhc3MiKTsKKwkJICAgIHNmID0gZ2V0U29ja2V0RmFjdG9yeShzZkNsYXNzKTsKKwkJICAgIHNmRXJyID0gInNvY2tldCBmYWN0b3J5IGNsYXNzICIgKyBzZkNsYXNzOworCQl9CisJCWlmIChzZiAhPSBudWxsICYmIHNmIGluc3RhbmNlb2YgU1NMU29ja2V0RmFjdG9yeSkKKwkJICAgIHNzZiA9IChTU0xTb2NrZXRGYWN0b3J5KXNmOworCSAgICB9CisKKwkgICAgLy8gZmluYWxseSwgdXNlIHRoZSBkZWZhdWx0IFNTTCBzb2NrZXQgZmFjdG9yeQorCSAgICBpZiAoc3NmID09IG51bGwpIHsKKwkJU3RyaW5nIHRydXN0ZWQ7CisJCWlmICgodHJ1c3RlZCA9IHByb3BzLmdldFByb3BlcnR5KHByZWZpeCArICIuc3NsLnRydXN0IikpICE9CisJCQludWxsKSB7CisJCSAgICB0cnkgeworCQkJTWFpbFNTTFNvY2tldEZhY3RvcnkgbXNmID0gbmV3IE1haWxTU0xTb2NrZXRGYWN0b3J5KCk7CisJCQlpZiAodHJ1c3RlZC5lcXVhbHMoIioiKSkKKwkJCSAgICBtc2Yuc2V0VHJ1c3RBbGxIb3N0cyh0cnVlKTsKKwkJCWVsc2UKKwkJCSAgICBtc2Yuc2V0VHJ1c3RlZEhvc3RzKHRydXN0ZWQuc3BsaXQoIlxccysiKSk7CisJCQlzc2YgPSBtc2Y7CisJCQlzZkVyciA9ICJtYWlsIFNTTCBzb2NrZXQgZmFjdG9yeSI7CisJCSAgICB9IGNhdGNoIChHZW5lcmFsU2VjdXJpdHlFeGNlcHRpb24gZ2V4KSB7CisJCQlJT0V4Y2VwdGlvbiBpb2V4ID0gbmV3IElPRXhjZXB0aW9uKAorCQkJCQkiQ2FuJ3QgY3JlYXRlIE1haWxTU0xTb2NrZXRGYWN0b3J5Iik7CisJCQlpb2V4LmluaXRDYXVzZShnZXgpOworCQkJdGhyb3cgaW9leDsKKwkJICAgIH0KKwkJfSBlbHNlIHsKKwkJICAgIHNzZiA9IChTU0xTb2NrZXRGYWN0b3J5KVNTTFNvY2tldEZhY3RvcnkuZ2V0RGVmYXVsdCgpOworCQkgICAgc2ZFcnIgPSAiZGVmYXVsdCBTU0wgc29ja2V0IGZhY3RvcnkiOworCQl9CisJICAgIH0KKworCSAgICBzb2NrZXQgPSBzc2YuY3JlYXRlU29ja2V0KHNvY2tldCwgaG9zdCwgcG9ydCwgdHJ1ZSk7CisJICAgIGNvbmZpZ3VyZVNTTFNvY2tldChzb2NrZXQsIGhvc3QsIHByb3BzLCBwcmVmaXgsIHNzZik7CisJfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJICAgIGlmIChleCBpbnN0YW5jZW9mIEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24pIHsKKwkJVGhyb3dhYmxlIHQgPQorCQkgICgoSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbilleCkuZ2V0VGFyZ2V0RXhjZXB0aW9uKCk7CisJCWlmICh0IGluc3RhbmNlb2YgRXhjZXB0aW9uKQorCQkgICAgZXggPSAoRXhjZXB0aW9uKXQ7CisJICAgIH0KKwkgICAgaWYgKGV4IGluc3RhbmNlb2YgSU9FeGNlcHRpb24pCisJCXRocm93IChJT0V4Y2VwdGlvbilleDsKKwkgICAgLy8gd3JhcCBhbnl0aGluZyBlbHNlIGJlZm9yZSBzZW5kaW5nIGl0IG9uCisJICAgIElPRXhjZXB0aW9uIGlvZXggPSBuZXcgSU9FeGNlcHRpb24oCisJCQkJIkV4Y2VwdGlvbiBpbiBzdGFydFRMUyB1c2luZyAiICsgc2ZFcnIgKworCQkJCSI6IGhvc3QsIHBvcnQ6ICIgKworCQkJCWhvc3QgKyAiLCAiICsgcG9ydCArCisJCQkJIjsgRXhjZXB0aW9uOiAiICsgZXgpOworCSAgICBpb2V4LmluaXRDYXVzZShleCk7CisJICAgIHRocm93IGlvZXg7CisJfQorCXJldHVybiBzb2NrZXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uZmlndXJlIHRoZSBTU0wgb3B0aW9ucyBmb3IgdGhlIHNvY2tldCAoaWYgaXQncyBhbiBTU0wgc29ja2V0KSwKKyAgICAgKiBiYXNlZCBvbiB0aGUgbWFpbC48cHJvdG9jb2w+LnNzbC5wcm90b2NvbHMgYW5kCisgICAgICogbWFpbC48cHJvdG9jb2w+LnNzbC5jaXBoZXJzdWl0ZXMgcHJvcGVydGllcy4KKyAgICAgKiBDaGVjayB0aGUgaWRlbnRpdHkgb2YgdGhlIHNlcnZlciBhcyBzcGVjaWZpZWQgYnkgdGhlCisgICAgICogbWFpbC48cHJvdG9jb2w+LnNzbC5jaGVja3NlcnZlcmlkZW50aXR5IHByb3BlcnR5LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgY29uZmlndXJlU1NMU29ja2V0KFNvY2tldCBzb2NrZXQsIFN0cmluZyBob3N0LAorCQkJUHJvcGVydGllcyBwcm9wcywgU3RyaW5nIHByZWZpeCwgU29ja2V0RmFjdG9yeSBzZikKKwkJCXRocm93cyBJT0V4Y2VwdGlvbiB7CisJaWYgKCEoc29ja2V0IGluc3RhbmNlb2YgU1NMU29ja2V0KSkKKwkgICAgcmV0dXJuOworCVNTTFNvY2tldCBzc2xzb2NrZXQgPSAoU1NMU29ja2V0KXNvY2tldDsKKworCVN0cmluZyBwcm90b2NvbHMgPSBwcm9wcy5nZXRQcm9wZXJ0eShwcmVmaXggKyAiLnNzbC5wcm90b2NvbHMiLCBudWxsKTsKKwlpZiAocHJvdG9jb2xzICE9IG51bGwpCisJICAgIHNzbHNvY2tldC5zZXRFbmFibGVkUHJvdG9jb2xzKHN0cmluZ0FycmF5KHByb3RvY29scykpOworCWVsc2UgeworCSAgICAvKgorCSAgICAgKiBUaGUgVVcgSU1BUCBzZXJ2ZXIgaW5zaXN0cyBvbiBhdCBsZWFzdCB0aGUgVExTdjEKKwkgICAgICogcHJvdG9jb2wgZm9yIFNUQVJUVExTLCBhbmQgd29uJ3QgYWNjZXB0IHRoZSBvbGQgU1NMdjIKKwkgICAgICogb3IgU1NMdjMgcHJvdG9jb2xzLiAgSGVyZSB3ZSBlbmFibGUgb25seSB0aGUgbm9uLVNTTAorCSAgICAgKiBwcm90b2NvbHMuICBYWFggLSB0aGlzIHNob3VsZCBwcm9iYWJseSBiZSBwYXJhbWV0ZXJpemVkLgorCSAgICAgKi8KKwkgICAgU3RyaW5nW10gcHJvdHMgPSBzc2xzb2NrZXQuZ2V0RW5hYmxlZFByb3RvY29scygpOworCSAgICBpZiAobG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuRklORVIpKQorCQlsb2dnZXIuZmluZXIoIlNTTCBlbmFibGVkIHByb3RvY29scyBiZWZvcmUgIiArCisJCSAgICBBcnJheXMuYXNMaXN0KHByb3RzKSk7CisJICAgIExpc3Q8U3RyaW5nPiBlcHJvdHMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKwkgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwcm90cy5sZW5ndGg7IGkrKykgeworCQlpZiAocHJvdHNbaV0gIT0gbnVsbCAmJiAhcHJvdHNbaV0uc3RhcnRzV2l0aCgiU1NMIikpCisJCSAgICBlcHJvdHMuYWRkKHByb3RzW2ldKTsKKwkgICAgfQorCSAgICBzc2xzb2NrZXQuc2V0RW5hYmxlZFByb3RvY29scygKKwkJCQllcHJvdHMudG9BcnJheShuZXcgU3RyaW5nW2Vwcm90cy5zaXplKCldKSk7CisJfQorCVN0cmluZyBjaXBoZXJzID0gcHJvcHMuZ2V0UHJvcGVydHkocHJlZml4ICsgIi5zc2wuY2lwaGVyc3VpdGVzIiwgbnVsbCk7CisJaWYgKGNpcGhlcnMgIT0gbnVsbCkKKwkgICAgc3Nsc29ja2V0LnNldEVuYWJsZWRDaXBoZXJTdWl0ZXMoc3RyaW5nQXJyYXkoY2lwaGVycykpOworCWlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FUikpIHsKKwkgICAgbG9nZ2VyLmZpbmVyKCJTU0wgZW5hYmxlZCBwcm90b2NvbHMgYWZ0ZXIgIiArCisJCUFycmF5cy5hc0xpc3Qoc3Nsc29ja2V0LmdldEVuYWJsZWRQcm90b2NvbHMoKSkpOworCSAgICBsb2dnZXIuZmluZXIoIlNTTCBlbmFibGVkIGNpcGhlcnMgYWZ0ZXIgIiArCisJCUFycmF5cy5hc0xpc3Qoc3Nsc29ja2V0LmdldEVuYWJsZWRDaXBoZXJTdWl0ZXMoKSkpOworCX0KKworCS8qCisJICogRm9yY2UgdGhlIGhhbmRzaGFrZSB0byBiZSBkb25lIG5vdyBzbyB0aGF0IHdlIGNhbiByZXBvcnQgYW55CisJICogZXJyb3JzIChlLmcuLCBjZXJ0aWZpY2F0ZSBlcnJvcnMpIHRvIHRoZSBjYWxsZXIgb2YgdGhlIHN0YXJ0VExTCisJICogbWV0aG9kLgorCSAqLworCXNzbHNvY2tldC5zdGFydEhhbmRzaGFrZSgpOworCisJLyoKKwkgKiBDaGVjayBzZXJ2ZXIgaWRlbnRpdHkgYW5kIHRydXN0LgorCSAqLworCWJvb2xlYW4gaWRDaGVjayA9IFByb3BVdGlsLmdldEJvb2xlYW5Qcm9wZXJ0eShwcm9wcywKKwkJCSAgICBwcmVmaXggKyAiLnNzbC5jaGVja3NlcnZlcmlkZW50aXR5IiwgZmFsc2UpOworCWlmIChpZENoZWNrKQorCSAgICBjaGVja1NlcnZlcklkZW50aXR5KGhvc3QsIHNzbHNvY2tldCk7CisJaWYgKHNmIGluc3RhbmNlb2YgTWFpbFNTTFNvY2tldEZhY3RvcnkpIHsKKwkgICAgTWFpbFNTTFNvY2tldEZhY3RvcnkgbXNmID0gKE1haWxTU0xTb2NrZXRGYWN0b3J5KXNmOworCSAgICBpZiAoIW1zZi5pc1NlcnZlclRydXN0ZWQoaG9zdCwgc3Nsc29ja2V0KSkgeworCQl0aHJvdyBjbGVhbnVwQW5kVGhyb3coc3Nsc29ja2V0LAorCQkJbmV3IElPRXhjZXB0aW9uKCJTZXJ2ZXIgaXMgbm90IHRydXN0ZWQ6ICIgKyBob3N0KSk7CisJICAgIH0KKwl9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgSU9FeGNlcHRpb24gY2xlYW51cEFuZFRocm93KFNvY2tldCBzb2NrZXQsIElPRXhjZXB0aW9uIGlmZSkgeworCXRyeSB7CisJICAgIHNvY2tldC5jbG9zZSgpOworCX0gY2F0Y2ggKFRocm93YWJsZSB0aHIpIHsKKwkgICAgaWYgKGlzUmVjb3ZlcmFibGUodGhyKSkgeworCQlpZmUuYWRkU3VwcHJlc3NlZCh0aHIpOworCSAgICB9IGVsc2UgeworCQl0aHIuYWRkU3VwcHJlc3NlZChpZmUpOworCQlpZiAodGhyIGluc3RhbmNlb2YgRXJyb3IpIHsKKwkJICAgIHRocm93IChFcnJvcikgdGhyOworCQl9CisJCWlmICh0aHIgaW5zdGFuY2VvZiBSdW50aW1lRXhjZXB0aW9uKSB7CisJCSAgICB0aHJvdyAoUnVudGltZUV4Y2VwdGlvbikgdGhyOworCQl9CisJCXRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbiIsIHRocik7CisJICAgIH0KKwl9CisJcmV0dXJuIGlmZTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzUmVjb3ZlcmFibGUoVGhyb3dhYmxlIHQpIHsKKwlyZXR1cm4gKHQgaW5zdGFuY2VvZiBFeGNlcHRpb24pIHx8ICh0IGluc3RhbmNlb2YgTGlua2FnZUVycm9yKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVjayB0aGUgc2VydmVyIGZyb20gdGhlIFNvY2tldCBjb25uZWN0aW9uIGFnYWluc3QgdGhlIHNlcnZlciBuYW1lKHMpCisgICAgICogYXMgZXhwcmVzc2VkIGluIHRoZSBzZXJ2ZXIgY2VydGlmaWNhdGUgKFJGQyAyNTk1IGNoZWNrKS4KKyAgICAgKgorICAgICAqIEBwYXJhbQlzZXJ2ZXIJCW5hbWUgb2YgdGhlIHNlcnZlciBleHBlY3RlZAorICAgICAqIEBwYXJhbSAgIHNzbFNvY2tldAlTU0xTb2NrZXQgY29ubmVjdGVkIHRvIHRoZSBzZXJ2ZXIKKyAgICAgKiBAZXhjZXB0aW9uCUlPRXhjZXB0aW9uCWlmIHdlIGNhbid0IHZlcmlmeSBpZGVudGl0eSBvZiBzZXJ2ZXIKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGNoZWNrU2VydmVySWRlbnRpdHkoU3RyaW5nIHNlcnZlciwgU1NMU29ja2V0IHNzbFNvY2tldCkKKwkJCQl0aHJvd3MgSU9FeGNlcHRpb24geworCisJLy8gQ2hlY2sgYWdhaW5zdCB0aGUgc2VydmVyIG5hbWUocykgYXMgZXhwcmVzc2VkIGluIHNlcnZlciBjZXJ0aWZpY2F0ZQorCXRyeSB7CisJICAgIGphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZVtdIGNlcnRDaGFpbiA9CisJCSAgICAgIHNzbFNvY2tldC5nZXRTZXNzaW9uKCkuZ2V0UGVlckNlcnRpZmljYXRlcygpOworCSAgICBpZiAoY2VydENoYWluICE9IG51bGwgJiYgY2VydENoYWluLmxlbmd0aCA+IDAgJiYKKwkJICAgIGNlcnRDaGFpblswXSBpbnN0YW5jZW9mIFg1MDlDZXJ0aWZpY2F0ZSAmJgorCQkgICAgbWF0Y2hDZXJ0KHNlcnZlciwgKFg1MDlDZXJ0aWZpY2F0ZSljZXJ0Q2hhaW5bMF0pKQorCQlyZXR1cm47CisJfSBjYXRjaCAoU1NMUGVlclVudmVyaWZpZWRFeGNlcHRpb24gZSkgeworCSAgICBzc2xTb2NrZXQuY2xvc2UoKTsKKwkgICAgSU9FeGNlcHRpb24gaW9leCA9IG5ldyBJT0V4Y2VwdGlvbigKKwkJIkNhbid0IHZlcmlmeSBpZGVudGl0eSBvZiBzZXJ2ZXI6ICIgKyBzZXJ2ZXIpOworCSAgICBpb2V4LmluaXRDYXVzZShlKTsKKwkgICAgdGhyb3cgaW9leDsKKwl9CisKKwkvLyBJZiB3ZSBnZXQgaGVyZSwgdGhlcmUgaXMgbm90aGluZyB0byBjb25zaWRlciB0aGUgc2VydmVyIGFzIHRydXN0ZWQuCisJc3NsU29ja2V0LmNsb3NlKCk7CisJdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJDYW4ndCB2ZXJpZnkgaWRlbnRpdHkgb2Ygc2VydmVyOiAiICsgc2VydmVyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEbyBhbnkgb2YgdGhlIG5hbWVzIGluIHRoZSBjZXJ0IG1hdGNoIHRoZSBzZXJ2ZXIgbmFtZT8KKyAgICAgKgorICAgICAqIEBwYXJhbQlzZXJ2ZXIJbmFtZSBvZiB0aGUgc2VydmVyIGV4cGVjdGVkCisgICAgICogQHBhcmFtICAgY2VydAlYNTA5Q2VydGlmaWNhdGUgdG8gZ2V0IHRoZSBzdWJqZWN0J3MgbmFtZSBmcm9tCisgICAgICogQHJldHVybiAgdHJ1ZSBpZiBpdCBtYXRjaGVzCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBtYXRjaENlcnQoU3RyaW5nIHNlcnZlciwgWDUwOUNlcnRpZmljYXRlIGNlcnQpIHsKKwlpZiAobG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuRklORVIpKQorCSAgICBsb2dnZXIuZmluZXIoIm1hdGNoQ2VydCBzZXJ2ZXIgIiArCisJCXNlcnZlciArICIsIGNlcnQgIiArIGNlcnQpOworCisJLyoKKwkgKiBGaXJzdCwgdHJ5IHRvIHVzZSBzdW4uc2VjdXJpdHkudXRpbC5Ib3N0bmFtZUNoZWNrZXIsCisJICogd2hpY2ggZXhpc3RzIGluIFN1bidzIEpESyBzdGFydGluZyB3aXRoIDEuNC4xLgorCSAqIFdlIHVzZSByZWZsZWN0aW9uIHRvIGFjY2VzcyBpdCBpbiBjYXNlIGl0J3Mgbm90IGF2YWlsYWJsZQorCSAqIGluIHRoZSBKREsgd2UncmUgcnVubmluZyBvbi4KKwkgKi8KKwl0cnkgeworCSAgICBDbGFzczw/PiBobmMgPSBDbGFzcy5mb3JOYW1lKCJzdW4uc2VjdXJpdHkudXRpbC5Ib3N0bmFtZUNoZWNrZXIiKTsKKwkgICAgLy8gaW52b2tlIEhvc3RuYW1lQ2hlY2tlci5nZXRJbnN0YW5jZShIb3N0bmFtZUNoZWNrZXIuVFlQRV9MREFQKQorCSAgICAvLyBIb3N0bmFtZUNoZWNrZXIuVFlQRV9MREFQID09IDIKKwkgICAgLy8gTERBUCByZXF1aXJlcyB0aGUgc2FtZSByZWdleCBoYW5kbGluZyBhcyB3ZSBuZWVkCisJICAgIE1ldGhvZCBnZXRJbnN0YW5jZSA9IGhuYy5nZXRNZXRob2QoImdldEluc3RhbmNlIiwKKwkJCQkJbmV3IENsYXNzPD8+W10geyBieXRlLmNsYXNzIH0pOworCSAgICBPYmplY3QgaG9zdG5hbWVDaGVja2VyID0gZ2V0SW5zdGFuY2UuaW52b2tlKG5ldyBPYmplY3QoKSwKKwkJCQkJbmV3IE9iamVjdFtdIHsgQnl0ZS52YWx1ZU9mKChieXRlKTIpIH0pOworCisJICAgIC8vIGludm9rZSBob3N0bmFtZUNoZWNrZXIubWF0Y2goIHNlcnZlciwgY2VydCkKKwkgICAgaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkVSKSkKKwkJbG9nZ2VyLmZpbmVyKCJ1c2luZyBzdW4uc2VjdXJpdHkudXRpbC5Ib3N0bmFtZUNoZWNrZXIiKTsKKwkgICAgTWV0aG9kIG1hdGNoID0gaG5jLmdldE1ldGhvZCgibWF0Y2giLAorCQkJbmV3IENsYXNzPD8+W10geyBTdHJpbmcuY2xhc3MsIFg1MDlDZXJ0aWZpY2F0ZS5jbGFzcyB9KTsKKwkgICAgdHJ5IHsKKwkJbWF0Y2guaW52b2tlKGhvc3RuYW1lQ2hlY2tlciwgbmV3IE9iamVjdFtdIHsgc2VydmVyLCBjZXJ0IH0pOworCQlyZXR1cm4gdHJ1ZTsKKwkgICAgfSBjYXRjaCAoSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiBjZXgpIHsKKwkJbG9nZ2VyLmxvZyhMZXZlbC5GSU5FUiwgIkhvc3RuYW1lQ2hlY2tlciBGQUlMIiwgY2V4KTsKKwkJcmV0dXJuIGZhbHNlOworCSAgICB9CisJfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJICAgIGxvZ2dlci5sb2coTGV2ZWwuRklORVIsICJOTyBzdW4uc2VjdXJpdHkudXRpbC5Ib3N0bmFtZUNoZWNrZXIiLCBleCk7CisJICAgIC8vIGlnbm9yZSBmYWlsdXJlIGFuZCBjb250aW51ZSBiZWxvdworCX0KKworCS8qCisJICogTGFja2luZyBIb3N0bmFtZUNoZWNrZXIsIHdlIGltcGxlbWVudCBhIGNydWRlIHZlcnNpb24gb2YKKwkgKiB0aGUgc2FtZSBjaGVja3Mgb3Vyc2VsdmVzLgorCSAqLworCXRyeSB7CisJICAgIC8qCisJICAgICAqIENoZWNrIGVhY2ggb2YgdGhlIHN1YmplY3RBbHROYW1lcy4KKwkgICAgICogWFhYIC0gb25seSBjaGVja3MgRE5TIG5hbWVzLCBzaG91bGQgYWxzbyBoYW5kbGUKKwkgICAgICogY2FzZSB3aGVyZSBzZXJ2ZXIgbmFtZSBpcyBhIGxpdGVyYWwgSVAgYWRkcmVzcworCSAgICAgKi8KKwkgICAgQ29sbGVjdGlvbjxMaXN0PD8+PiBuYW1lcyA9IGNlcnQuZ2V0U3ViamVjdEFsdGVybmF0aXZlTmFtZXMoKTsKKwkgICAgaWYgKG5hbWVzICE9IG51bGwpIHsKKwkJYm9vbGVhbiBmb3VuZE5hbWUgPSBmYWxzZTsKKwkJZm9yIChJdGVyYXRvcjxMaXN0PD8+PiBpdCA9IG5hbWVzLml0ZXJhdG9yKCk7IGl0Lmhhc05leHQoKTsgKSB7CisJCSAgICBMaXN0PD8+IG5hbWVFbnQgPSBpdC5uZXh0KCk7CisJCSAgICBJbnRlZ2VyIHR5cGUgPSAoSW50ZWdlciluYW1lRW50LmdldCgwKTsKKwkJICAgIGlmICh0eXBlLmludFZhbHVlKCkgPT0gMikgewkvLyAyID09IGROU05hbWUKKwkJCWZvdW5kTmFtZSA9IHRydWU7CisJCQlTdHJpbmcgbmFtZSA9IChTdHJpbmcpbmFtZUVudC5nZXQoMSk7CisJCQlpZiAobG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuRklORVIpKQorCQkJICAgIGxvZ2dlci5maW5lcigiZm91bmQgbmFtZTogIiArIG5hbWUpOworCQkJaWYgKG1hdGNoU2VydmVyKHNlcnZlciwgbmFtZSkpCisJCQkgICAgcmV0dXJuIHRydWU7CisJCSAgICB9CisJCX0KKwkJaWYgKGZvdW5kTmFtZSkJLy8gZm91bmQgYSBuYW1lLCBidXQgbm8gbWF0Y2gKKwkJICAgIHJldHVybiBmYWxzZTsKKwkgICAgfQorCX0gY2F0Y2ggKENlcnRpZmljYXRlUGFyc2luZ0V4Y2VwdGlvbiBleCkgeworCSAgICAvLyBpZ25vcmUgaXQKKwl9CisKKwkvLyBYWFggLSBmb2xsb3dpbmcgaXMgYSAqdmVyeSogY3J1ZGUgcGFyc2Ugb2YgdGhlIG5hbWUgYW5kIGlnbm9yZXMKKwkvLwkgYWxsIHNvcnRzIG9mIGltcG9ydGFudCBpc3N1ZXMgc3VjaCBhcyBxdW90aW5nCisJUGF0dGVybiBwID0gUGF0dGVybi5jb21waWxlKCJDTj0oW14sXSopIik7CisJTWF0Y2hlciBtID0gcC5tYXRjaGVyKGNlcnQuZ2V0U3ViamVjdFg1MDBQcmluY2lwYWwoKS5nZXROYW1lKCkpOworCWlmIChtLmZpbmQoKSAmJiBtYXRjaFNlcnZlcihzZXJ2ZXIsIG0uZ3JvdXAoMSkudHJpbSgpKSkKKwkgICAgcmV0dXJuIHRydWU7CisKKwlyZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogRG9lcyB0aGUgc2VydmVyIHdlJ3JlIGV4cGVjdGluZyB0byBjb25uZWN0IHRvIG1hdGNoIHRoZQorICAgICAqIGdpdmVuIG5hbWUgZnJvbSB0aGUgc2VydmVyJ3MgY2VydGlmaWNhdGU/CisgICAgICoKKyAgICAgKiBAcGFyYW0Jc2VydmVyCQluYW1lIG9mIHRoZSBzZXJ2ZXIgZXhwZWN0ZWQKKyAgICAgKiBAcGFyYW0JbmFtZQkJbmFtZSBmcm9tIHRoZSBzZXJ2ZXIncyBjZXJ0aWZpY2F0ZQorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gbWF0Y2hTZXJ2ZXIoU3RyaW5nIHNlcnZlciwgU3RyaW5nIG5hbWUpIHsKKwlpZiAobG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuRklORVIpKQorCSAgICBsb2dnZXIuZmluZXIoIm1hdGNoIHNlcnZlciAiICsgc2VydmVyICsgIiB3aXRoICIgKyBuYW1lKTsKKwlpZiAobmFtZS5zdGFydHNXaXRoKCIqLiIpKSB7CisJICAgIC8vIG1hdGNoICJmb28uZXhhbXBsZS5jb20iIHdpdGggIiouZXhhbXBsZS5jb20iCisJICAgIFN0cmluZyB0YWlsID0gbmFtZS5zdWJzdHJpbmcoMik7CisJICAgIGlmICh0YWlsLmxlbmd0aCgpID09IDApCisJCXJldHVybiBmYWxzZTsKKwkgICAgaW50IG9mZiA9IHNlcnZlci5sZW5ndGgoKSAtIHRhaWwubGVuZ3RoKCk7CisJICAgIGlmIChvZmYgPCAxKQorCQlyZXR1cm4gZmFsc2U7CisJICAgIC8vIGlmIHRhaWwgbWF0Y2hlcyBhbmQgaXMgcHJlY2VlZGVkIGJ5ICIuIgorCSAgICByZXR1cm4gc2VydmVyLmNoYXJBdChvZmYgLSAxKSA9PSAnLicgJiYKKwkJICAgIHNlcnZlci5yZWdpb25NYXRjaGVzKHRydWUsIG9mZiwgdGFpbCwgMCwgdGFpbC5sZW5ndGgoKSk7CisJfSBlbHNlCisJICAgIHJldHVybiBzZXJ2ZXIuZXF1YWxzSWdub3JlQ2FzZShuYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVc2UgdGhlIEhUVFAgQ09OTkVDVCBwcm90b2NvbCB0byBjb25uZWN0IHRvIGEKKyAgICAgKiBzaXRlIHRocm91Z2ggYW4gSFRUUCBwcm94eSBzZXJ2ZXIuIDxwPgorICAgICAqCisgICAgICogUHJvdG9jb2wgaXMgcm91Z2hseToKKyAgICAgKiA8cHJlPgorICAgICAqIENPTk5FQ1QgPGhvc3Q+Ojxwb3J0PiBIVFRQLzEuMQorICAgICAqIEhvc3Q6IDxob3N0Pjo8cG9ydD4KKyAgICAgKiA8YmxhbmsgbGluZT4KKyAgICAgKgorICAgICAqIEhUVFAvMS4xIDIwMCBDb25uZWN0IGVzdGFibGlzaGVkCisgICAgICogPGhlYWRlcnM+CisgICAgICogPGJsYW5rIGxpbmU+CisgICAgICogPC9wcmU+CisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBwcm94eUNvbm5lY3QoU29ja2V0IHNvY2tldCwKKwkJCQlTdHJpbmcgcHJveHlIb3N0LCBpbnQgcHJveHlQb3J0LAorCQkJCVN0cmluZyBwcm94eVVzZXIsIFN0cmluZyBwcm94eVBhc3N3b3JkLAorCQkJCVN0cmluZyBob3N0LCBpbnQgcG9ydCwgaW50IGN0bykKKwkJCQl0aHJvd3MgSU9FeGNlcHRpb24geworCWlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FKSkKKwkgICAgbG9nZ2VyLmZpbmUoImNvbm5lY3RpbmcgdGhyb3VnaCBwcm94eSAiICsKKwkJCXByb3h5SG9zdCArICI6IiArIHByb3h5UG9ydCArICIgdG8gIiArCisJCQlob3N0ICsgIjoiICsgcG9ydCk7CisJaWYgKGN0byA+PSAwKQorCSAgICBzb2NrZXQuY29ubmVjdChuZXcgSW5ldFNvY2tldEFkZHJlc3MocHJveHlIb3N0LCBwcm94eVBvcnQpLCBjdG8pOworCWVsc2UKKwkgICAgc29ja2V0LmNvbm5lY3QobmV3IEluZXRTb2NrZXRBZGRyZXNzKHByb3h5SG9zdCwgcHJveHlQb3J0KSk7CisJUHJpbnRTdHJlYW0gb3MgPSBuZXcgUHJpbnRTdHJlYW0oc29ja2V0LmdldE91dHB1dFN0cmVhbSgpLCBmYWxzZSwKKwkJCQkJICAgIFN0YW5kYXJkQ2hhcnNldHMuVVRGXzgubmFtZSgpKTsKKwlTdHJpbmdCdWlsZGVyIHJlcXVlc3RCdWlsZGVyID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKwlyZXF1ZXN0QnVpbGRlci5hcHBlbmQoIkNPTk5FQ1QgIikuYXBwZW5kKGhvc3QpLmFwcGVuZCgiOiIpLmFwcGVuZChwb3J0KS4KKwkJCWFwcGVuZCgiIEhUVFAvMS4xXHJcbiIpOworCXJlcXVlc3RCdWlsZGVyLmFwcGVuZCgiSG9zdDogIikuYXBwZW5kKGhvc3QpLmFwcGVuZCgiOiIpLmFwcGVuZChwb3J0KS4KKwkJCWFwcGVuZCgiXHJcbiIpOworCWlmIChwcm94eVVzZXIgIT0gbnVsbCAmJiBwcm94eVBhc3N3b3JkICE9IG51bGwpIHsKKwkgICAgYnl0ZVtdIHVwYnl0ZXMgPSAocHJveHlVc2VyICsgJzonICsgcHJveHlQYXNzd29yZCkuCisJCQkJZ2V0Qnl0ZXMoU3RhbmRhcmRDaGFyc2V0cy5VVEZfOCk7CisJICAgIFN0cmluZyBwcm94eUhlYWRlclZhbHVlID0gbmV3IFN0cmluZygKKwkJQkFTRTY0RW5jb2RlclN0cmVhbS5lbmNvZGUodXBieXRlcyksCisJCVN0YW5kYXJkQ2hhcnNldHMuVVNfQVNDSUkpOworCSAgICByZXF1ZXN0QnVpbGRlci5hcHBlbmQoIlByb3h5LUF1dGhvcml6YXRpb246IEJhc2ljICIpLgorCQkJCWFwcGVuZChwcm94eUhlYWRlclZhbHVlKS5hcHBlbmQoIlxyXG4iKTsKKwl9CisJcmVxdWVzdEJ1aWxkZXIuYXBwZW5kKCJQcm94eS1Db25uZWN0aW9uOiBrZWVwLWFsaXZlXHJcblxyXG4iKTsKKwlvcy5wcmludChyZXF1ZXN0QnVpbGRlci50b1N0cmluZygpKTsKKwlvcy5mbHVzaCgpOworCUJ1ZmZlcmVkUmVhZGVyIHIgPSBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IElucHV0U3RyZWFtUmVhZGVyKAorCQkJICAgIHNvY2tldC5nZXRJbnB1dFN0cmVhbSgpLCBTdGFuZGFyZENoYXJzZXRzLlVURl84KSk7CisJU3RyaW5nIGxpbmU7CisJYm9vbGVhbiBmaXJzdCA9IHRydWU7CisJd2hpbGUgKChsaW5lID0gci5yZWFkTGluZSgpKSAhPSBudWxsKSB7CisJICAgIGlmIChsaW5lLmxlbmd0aCgpID09IDApCisJCWJyZWFrOworCSAgICBsb2dnZXIuZmluZXN0KGxpbmUpOworCSAgICBpZiAoZmlyc3QpIHsKKwkJU3RyaW5nVG9rZW5pemVyIHN0ID0gbmV3IFN0cmluZ1Rva2VuaXplcihsaW5lKTsKKwkJU3RyaW5nIGh0dHAgPSBzdC5uZXh0VG9rZW4oKTsKKwkJU3RyaW5nIGNvZGUgPSBzdC5uZXh0VG9rZW4oKTsKKwkJaWYgKCFjb2RlLmVxdWFscygiMjAwIikpIHsKKwkJICAgIHRyeSB7CisJCQlzb2NrZXQuY2xvc2UoKTsKKwkJICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZXgpIHsKKwkJCS8vIGlnbm9yZWQKKwkJICAgIH0KKwkJICAgIENvbm5lY3RFeGNlcHRpb24gZXggPSBuZXcgQ29ubmVjdEV4Y2VwdGlvbigKKwkJCSJjb25uZWN0aW9uIHRocm91Z2ggcHJveHkgIiArCisJCQlwcm94eUhvc3QgKyAiOiIgKyBwcm94eVBvcnQgKyAiIHRvICIgKworCQkJaG9zdCArICI6IiArIHBvcnQgKyAiIGZhaWxlZDogIiArIGxpbmUpOworCQkgICAgbG9nZ2VyLmxvZyhMZXZlbC5GSU5FLCAiY29ubmVjdCBmYWlsZWQiLCBleCk7CisJCSAgICB0aHJvdyBleDsKKwkJfQorCQlmaXJzdCA9IGZhbHNlOworCSAgICB9CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlIGEgc3RyaW5nIGludG8gd2hpdGVzcGFjZSBzZXBhcmF0ZWQgdG9rZW5zCisgICAgICogYW5kIHJldHVybiB0aGUgdG9rZW5zIGluIGFuIGFycmF5LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZ1tdIHN0cmluZ0FycmF5KFN0cmluZyBzKSB7CisJU3RyaW5nVG9rZW5pemVyIHN0ID0gbmV3IFN0cmluZ1Rva2VuaXplcihzKTsKKwlMaXN0PFN0cmluZz4gdG9rZW5zID0gbmV3IEFycmF5TGlzdDw+KCk7CisJd2hpbGUgKHN0Lmhhc01vcmVUb2tlbnMoKSkKKwkgICAgdG9rZW5zLmFkZChzdC5uZXh0VG9rZW4oKSk7CisJcmV0dXJuIHRva2Vucy50b0FycmF5KG5ldyBTdHJpbmdbdG9rZW5zLnNpemUoKV0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlbmllbmNlIG1ldGhvZCB0byBnZXQgb3VyIGNvbnRleHQgY2xhc3MgbG9hZGVyLgorICAgICAqIEFzc2VydCBhbnkgcHJpdmlsZWdlcyB3ZSBtaWdodCBoYXZlIGFuZCB0aGVuIGNhbGwgdGhlCisgICAgICogVGhyZWFkLmdldENvbnRleHRDbGFzc0xvYWRlciBtZXRob2QuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgQ2xhc3NMb2FkZXIgZ2V0Q29udGV4dENsYXNzTG9hZGVyKCkgeworCXJldHVybgorCUFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKG5ldyBQcml2aWxlZ2VkQWN0aW9uPENsYXNzTG9hZGVyPigpIHsKKwkgICAgQE92ZXJyaWRlCisJICAgIHB1YmxpYyBDbGFzc0xvYWRlciBydW4oKSB7CisJCUNsYXNzTG9hZGVyIGNsID0gbnVsbDsKKwkJdHJ5IHsKKwkJICAgIGNsID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXRDb250ZXh0Q2xhc3NMb2FkZXIoKTsKKwkJfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gZXgpIHsgfQorCQlyZXR1cm4gY2w7CisJICAgIH0KKwl9KTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvVHJhY2VJbnB1dFN0cmVhbS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL1RyYWNlSW5wdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mY2ViN2FjCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL1RyYWNlSW5wdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDE0MCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwudXRpbDsKKworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZhLnV0aWwubG9nZ2luZy5MZXZlbDsKKworLyoqCisgKiBUaGlzIGNsYXNzIGlzIGEgRmlsdGVySW5wdXRTdHJlYW0gdGhhdCB3cml0ZXMgdGhlIGJ5dGVzCisgKiBiZWluZyByZWFkIGZyb20gdGhlIGdpdmVuIGlucHV0IHN0cmVhbSBpbnRvIHRoZSBnaXZlbiBvdXRwdXQKKyAqIHN0cmVhbS4gVGhpcyBjbGFzcyBpcyB0eXBpY2FsbHkgdXNlZCB0byBwcm92aWRlIGEgdHJhY2Ugb2YKKyAqIHRoZSBkYXRhIHRoYXQgaXMgYmVpbmcgcmV0cmlldmVkIGZyb20gYW4gaW5wdXQgc3RyZWFtLgorICoKKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKi8KKworcHVibGljIGNsYXNzIFRyYWNlSW5wdXRTdHJlYW0gZXh0ZW5kcyBGaWx0ZXJJbnB1dFN0cmVhbSB7CisgICAgcHJpdmF0ZSBib29sZWFuIHRyYWNlID0gZmFsc2U7CisgICAgcHJpdmF0ZSBib29sZWFuIHF1b3RlID0gZmFsc2U7CisgICAgcHJpdmF0ZSBPdXRwdXRTdHJlYW0gdHJhY2VPdXQ7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIGlucHV0IHN0cmVhbSBmaWx0ZXIgYnVpbHQgb24gdG9wIG9mIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBpbnB1dCBzdHJlYW0uCisgICAgICogICAKKyAgICAgKiBAcGFyYW0gICBpbiAgIHRoZSB1bmRlcmx5aW5nIGlucHV0IHN0cmVhbS4KKyAgICAgKiBAcGFyYW0gICBsb2dnZXIJbG9nIHRyYWNlIGhlcmUKKyAgICAgKi8KKyAgICBwdWJsaWMgVHJhY2VJbnB1dFN0cmVhbShJbnB1dFN0cmVhbSBpbiwgTWFpbExvZ2dlciBsb2dnZXIpIHsKKwlzdXBlcihpbik7CisJdGhpcy50cmFjZSA9IGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkZJTkVTVCk7CisJdGhpcy50cmFjZU91dCA9IG5ldyBMb2dPdXRwdXRTdHJlYW0obG9nZ2VyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIGlucHV0IHN0cmVhbSBmaWx0ZXIgYnVpbHQgb24gdG9wIG9mIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBpbnB1dCBzdHJlYW0uCisgICAgICogICAKKyAgICAgKiBAcGFyYW0gICBpbiAgIHRoZSB1bmRlcmx5aW5nIGlucHV0IHN0cmVhbS4KKyAgICAgKiBAcGFyYW0JdHJhY2VPdXQJdGhlIHRyYWNlIHN0cmVhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgVHJhY2VJbnB1dFN0cmVhbShJbnB1dFN0cmVhbSBpbiwgT3V0cHV0U3RyZWFtIHRyYWNlT3V0KSB7CisJc3VwZXIoaW4pOworCXRoaXMudHJhY2VPdXQgPSB0cmFjZU91dDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdHJhY2UgbW9kZS4KKyAgICAgKiBAcGFyYW0JdHJhY2UJdGhlIHRyYWNlIG1vZGUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRUcmFjZShib29sZWFuIHRyYWNlKSB7CisJdGhpcy50cmFjZSA9IHRyYWNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCBxdW90ZSBtb2RlLgorICAgICAqIEBwYXJhbQlxdW90ZQl0aGUgcXVvdGUgbW9kZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFF1b3RlKGJvb2xlYW4gcXVvdGUpIHsKKwl0aGlzLnF1b3RlID0gcXVvdGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZHMgdGhlIG5leHQgYnl0ZSBvZiBkYXRhIGZyb20gdGhpcyBpbnB1dCBzdHJlYW0uIFJldHVybnMKKyAgICAgKiA8Y29kZT4tMTwvY29kZT4gaWYgbm8gZGF0YSBpcyBhdmFpbGFibGUuIFdyaXRlcyBvdXQgdGhlIHJlYWQKKyAgICAgKiBieXRlIGludG8gdGhlIHRyYWNlIHN0cmVhbSwgaWYgdHJhY2UgbW9kZSBpcyA8Y29kZT50cnVlPC9jb2RlPgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJaW50IGIgPSBpbi5yZWFkKCk7CisJaWYgKHRyYWNlICYmIGIgIT0gLTEpIHsKKwkgICAgaWYgKHF1b3RlKQorCQl3cml0ZUJ5dGUoYik7CisJICAgIGVsc2UKKwkJdHJhY2VPdXQud3JpdGUoYik7CisJfQorCXJldHVybiBiOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIHVwIHRvIDxjb2RlPmxlbjwvY29kZT4gYnl0ZXMgb2YgZGF0YSBmcm9tIHRoaXMgaW5wdXQgc3RyZWFtCisgICAgICogaW50byBhbiBhcnJheSBvZiBieXRlcy4gUmV0dXJucyA8Y29kZT4tMTwvY29kZT4gaWYgbm8gbW9yZSBkYXRhCisgICAgICogaXMgYXZhaWxhYmxlLiBXcml0ZXMgb3V0IHRoZSByZWFkIGJ5dGVzIGludG8gdGhlIHRyYWNlIHN0cmVhbSwgaWYgCisgICAgICogdHJhY2UgbW9kZSBpcyA8Y29kZT50cnVlPC9jb2RlPgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZChieXRlIGJbXSwgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlpbnQgY291bnQgPSBpbi5yZWFkKGIsIG9mZiwgbGVuKTsKKwlpZiAodHJhY2UgJiYgY291bnQgIT0gLTEpIHsKKwkgICAgaWYgKHF1b3RlKSB7CisJCWZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykKKwkJICAgIHdyaXRlQnl0ZShiW29mZiArIGldKTsKKwkgICAgfSBlbHNlCisJCXRyYWNlT3V0LndyaXRlKGIsIG9mZiwgY291bnQpOworCX0KKwlyZXR1cm4gY291bnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGUgYSBieXRlIGluIGEgd2F5IHRoYXQgZXZlcnkgYnl0ZSB2YWx1ZSBpcyBwcmludGFibGUgQVNDSUkuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCB2b2lkIHdyaXRlQnl0ZShpbnQgYikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwliICY9IDB4ZmY7CisJaWYgKGIgPiAweDdmKSB7CisJICAgIHRyYWNlT3V0LndyaXRlKCdNJyk7CisJICAgIHRyYWNlT3V0LndyaXRlKCctJyk7CisJICAgIGIgJj0gMHg3ZjsKKwl9CisJaWYgKGIgPT0gJ1xyJykgeworCSAgICB0cmFjZU91dC53cml0ZSgnXFwnKTsKKwkgICAgdHJhY2VPdXQud3JpdGUoJ3InKTsKKwl9IGVsc2UgaWYgKGIgPT0gJ1xuJykgeworCSAgICB0cmFjZU91dC53cml0ZSgnXFwnKTsKKwkgICAgdHJhY2VPdXQud3JpdGUoJ24nKTsKKwkgICAgdHJhY2VPdXQud3JpdGUoJ1xuJyk7CisJfSBlbHNlIGlmIChiID09ICdcdCcpIHsKKwkgICAgdHJhY2VPdXQud3JpdGUoJ1xcJyk7CisJICAgIHRyYWNlT3V0LndyaXRlKCd0Jyk7CisJfSBlbHNlIGlmIChiIDwgJyAnKSB7CisJICAgIHRyYWNlT3V0LndyaXRlKCdeJyk7CisJICAgIHRyYWNlT3V0LndyaXRlKCdAJyArIGIpOworCX0gZWxzZSB7CisJICAgIHRyYWNlT3V0LndyaXRlKGIpOworCX0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvVHJhY2VPdXRwdXRTdHJlYW0uamF2YSBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvdXRpbC9UcmFjZU91dHB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI4ZjI4MjAKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvVHJhY2VPdXRwdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDE0NiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwudXRpbDsKKworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZhLnV0aWwubG9nZ2luZy5MZXZlbDsKKworLyoqCisgKiBUaGlzIGNsYXNzIGlzIGEgc3ViY2xhc3Mgb2YgRGF0YU91dHB1dFN0cmVhbSB0aGF0IGNvcGllcyB0aGUKKyAqIGRhdGEgYmVpbmcgd3JpdHRlbiBpbnRvIHRoZSBEYXRhT3V0cHV0U3RyZWFtIGludG8gYW5vdGhlciBvdXRwdXQKKyAqIHN0cmVhbS4gVGhpcyBjbGFzcyBpcyB1c2VkIGhlcmUgdG8gcHJvdmlkZSBhIGRlYnVnIHRyYWNlIG9mIHRoZQorICogc3R1ZmYgdGhhdHMgYmVpbmcgd3JpdHRlbiBvdXQgaW50byB0aGUgRGF0YU91dHB1dFN0cmVhbS4KKyAqCisgKiBAYXV0aG9yIEpvaG4gTWFuaQorICovCisKK3B1YmxpYyBjbGFzcyBUcmFjZU91dHB1dFN0cmVhbSBleHRlbmRzIEZpbHRlck91dHB1dFN0cmVhbSB7CisgICAgcHJpdmF0ZSBib29sZWFuIHRyYWNlID0gZmFsc2U7CisgICAgcHJpdmF0ZSBib29sZWFuIHF1b3RlID0gZmFsc2U7CisgICAgcHJpdmF0ZSBPdXRwdXRTdHJlYW0gdHJhY2VPdXQ7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIG91dHB1dCBzdHJlYW0gZmlsdGVyIGJ1aWx0IG9uIHRvcCBvZiB0aGUgc3BlY2lmaWVkCisgICAgICogdW5kZXJseWluZyBvdXRwdXQgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtICAgb3V0ICAgdGhlIHVuZGVybHlpbmcgb3V0cHV0IHN0cmVhbS4KKyAgICAgKiBAcGFyYW0JbG9nZ2VyCWxvZyB0cmFjZSBoZXJlCisgICAgICovCisgICAgcHVibGljIFRyYWNlT3V0cHV0U3RyZWFtKE91dHB1dFN0cmVhbSBvdXQsIE1haWxMb2dnZXIgbG9nZ2VyKSB7CisJc3VwZXIob3V0KTsKKwl0aGlzLnRyYWNlID0gbG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuRklORVNUKTsKKwl0aGlzLnRyYWNlT3V0ID0gbmV3IExvZ091dHB1dFN0cmVhbShsb2dnZXIpOzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIG91dHB1dCBzdHJlYW0gZmlsdGVyIGJ1aWx0IG9uIHRvcCBvZiB0aGUgc3BlY2lmaWVkCisgICAgICogdW5kZXJseWluZyBvdXRwdXQgc3RyZWFtLgorICAgICAqCisgICAgICogQHBhcmFtICAgb3V0ICAgdGhlIHVuZGVybHlpbmcgb3V0cHV0IHN0cmVhbS4KKyAgICAgKiBAcGFyYW0JdHJhY2VPdXQJdGhlIHRyYWNlIHN0cmVhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgVHJhY2VPdXRwdXRTdHJlYW0oT3V0cHV0U3RyZWFtIG91dCwgT3V0cHV0U3RyZWFtIHRyYWNlT3V0KSB7CisJc3VwZXIob3V0KTsKKwl0aGlzLnRyYWNlT3V0ID0gdHJhY2VPdXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSB0cmFjZSBtb2RlLgorICAgICAqCisgICAgICogQHBhcmFtCXRyYWNlCXRoZSB0cmFjZSBtb2RlCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0VHJhY2UoYm9vbGVhbiB0cmFjZSkgeworCXRoaXMudHJhY2UgPSB0cmFjZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgcXVvdGUgbW9kZS4KKyAgICAgKiBAcGFyYW0JcXVvdGUJdGhlIHF1b3RlIG1vZGUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRRdW90ZShib29sZWFuIHF1b3RlKSB7CisJdGhpcy5xdW90ZSA9IHF1b3RlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyB0aGUgc3BlY2lmaWVkIDxjb2RlPmJ5dGU8L2NvZGU+IHRvIHRoaXMgb3V0cHV0IHN0cmVhbS4KKyAgICAgKiBXcml0ZXMgb3V0IHRoZSBieXRlIGludG8gdGhlIHRyYWNlIHN0cmVhbSBpZiB0aGUgdHJhY2UgbW9kZQorICAgICAqIGlzIDxjb2RlPnRydWU8L2NvZGU+CisgICAgICoKKyAgICAgKiBAcGFyYW0JYgl0aGUgYnl0ZSB0byB3cml0ZQorICAgICAqIEBleGNlcHRpb24JSU9FeGNlcHRpb24JZm9yIEkvTyBlcnJvcnMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShpbnQgYikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlpZiAodHJhY2UpIHsKKwkgICAgaWYgKHF1b3RlKQorCQl3cml0ZUJ5dGUoYik7CisJICAgIGVsc2UKKwkJdHJhY2VPdXQud3JpdGUoYik7CisJfQorCW91dC53cml0ZShiKTsKKyAgICB9CisJICAgIAorICAgIC8qKgorICAgICAqIFdyaXRlcyA8Y29kZT5iLmxlbmd0aDwvY29kZT4gYnl0ZXMgdG8gdGhpcyBvdXRwdXQgc3RyZWFtLgorICAgICAqIFdyaXRlcyBvdXQgdGhlIGJ5dGVzIGludG8gdGhlIHRyYWNlIHN0cmVhbSBpZiB0aGUgdHJhY2UKKyAgICAgKiBtb2RlIGlzIDxjb2RlPnRydWU8L2NvZGU+CisgICAgICoKKyAgICAgKiBAcGFyYW0JYglieXRlcyB0byB3cml0ZQorICAgICAqIEBwYXJhbQlvZmYJb2Zmc2V0IGluIGFycmF5CisgICAgICogQHBhcmFtCWxlbgludW1iZXIgb2YgYnl0ZXMgdG8gd3JpdGUKKyAgICAgKiBAZXhjZXB0aW9uCUlPRXhjZXB0aW9uCWZvciBJL08gZXJyb3JzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoYnl0ZSBiW10sIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJaWYgKHRyYWNlKSB7CisJICAgIGlmIChxdW90ZSkgeworCQlmb3IgKGludCBpID0gMDsgaSA8IGxlbjsgaSsrKQorCQkgICAgd3JpdGVCeXRlKGJbb2ZmICsgaV0pOworCSAgICB9IGVsc2UKKwkJdHJhY2VPdXQud3JpdGUoYiwgb2ZmLCBsZW4pOworCX0KKwlvdXQud3JpdGUoYiwgb2ZmLCBsZW4pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlIGEgYnl0ZSBpbiBhIHdheSB0aGF0IGV2ZXJ5IGJ5dGUgdmFsdWUgaXMgcHJpbnRhYmxlIEFTQ0lJLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgdm9pZCB3cml0ZUJ5dGUoaW50IGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJYiAmPSAweGZmOworCWlmIChiID4gMHg3ZikgeworCSAgICB0cmFjZU91dC53cml0ZSgnTScpOworCSAgICB0cmFjZU91dC53cml0ZSgnLScpOworCSAgICBiICY9IDB4N2Y7CisJfQorCWlmIChiID09ICdccicpIHsKKwkgICAgdHJhY2VPdXQud3JpdGUoJ1xcJyk7CisJICAgIHRyYWNlT3V0LndyaXRlKCdyJyk7CisJfSBlbHNlIGlmIChiID09ICdcbicpIHsKKwkgICAgdHJhY2VPdXQud3JpdGUoJ1xcJyk7CisJICAgIHRyYWNlT3V0LndyaXRlKCduJyk7CisJICAgIHRyYWNlT3V0LndyaXRlKCdcbicpOworCX0gZWxzZSBpZiAoYiA9PSAnXHQnKSB7CisJICAgIHRyYWNlT3V0LndyaXRlKCdcXCcpOworCSAgICB0cmFjZU91dC53cml0ZSgndCcpOworCX0gZWxzZSBpZiAoYiA8ICcgJykgeworCSAgICB0cmFjZU91dC53cml0ZSgnXicpOworCSAgICB0cmFjZU91dC53cml0ZSgnQCcgKyBiKTsKKwl9IGVsc2UgeworCSAgICB0cmFjZU91dC53cml0ZShiKTsKKwl9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL1VVRGVjb2RlclN0cmVhbS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL1VVRGVjb2RlclN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgyZjk1N2MKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvVVVEZWNvZGVyU3RyZWFtLmphdmEKQEAgLTAsMCArMSwzMzQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLnV0aWw7CisKK2ltcG9ydCBqYXZhLmlvLio7CisKKy8qKgorICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIGEgVVVEZWNvZGVyLiBJdCBpcyBpbXBsZW1lbnRlZCBhcworICogYSBGaWx0ZXJJbnB1dFN0cmVhbSwgc28gb25lIGNhbiBqdXN0IHdyYXAgdGhpcyBjbGFzcyBhcm91bmQKKyAqIGFueSBpbnB1dCBzdHJlYW0gYW5kIHJlYWQgYnl0ZXMgZnJvbSB0aGlzIGZpbHRlci4gVGhlIGRlY29kaW5nCisgKiBpcyBkb25lIGFzIHRoZSBieXRlcyBhcmUgcmVhZCBvdXQuCisgKiAKKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCisKK3B1YmxpYyBjbGFzcyBVVURlY29kZXJTdHJlYW0gZXh0ZW5kcyBGaWx0ZXJJbnB1dFN0cmVhbSB7CisgICAgcHJpdmF0ZSBTdHJpbmcgbmFtZTsKKyAgICBwcml2YXRlIGludCBtb2RlOworCisgICAgcHJpdmF0ZSBieXRlW10gYnVmZmVyID0gbmV3IGJ5dGVbNDVdOyAvLyBtYXggZGVjb2RlZCBjaGFycyBpbiBhIGxpbmUgPSA0NQorICAgIHByaXZhdGUgaW50IGJ1ZnNpemUgPSAwOwkvLyBzaXplIG9mIHRoZSBjYWNoZQorICAgIHByaXZhdGUgaW50IGluZGV4ID0gMDsJLy8gaW5kZXggaW50byB0aGUgY2FjaGUKKyAgICBwcml2YXRlIGJvb2xlYW4gZ290UHJlZml4ID0gZmFsc2U7CisgICAgcHJpdmF0ZSBib29sZWFuIGdvdEVuZCA9IGZhbHNlOworICAgIHByaXZhdGUgTGluZUlucHV0U3RyZWFtIGxpbjsKKyAgICBwcml2YXRlIGJvb2xlYW4gaWdub3JlRXJyb3JzOworICAgIHByaXZhdGUgYm9vbGVhbiBpZ25vcmVNaXNzaW5nQmVnaW5FbmQ7CisgICAgcHJpdmF0ZSBTdHJpbmcgcmVhZEFoZWFkOworCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgVVVkZWNvZGVyIHRoYXQgZGVjb2RlcyB0aGUgc3BlY2lmaWVkIGlucHV0IHN0cmVhbS4KKyAgICAgKiBUaGUgU3lzdGVtIHByb3BlcnR5IDxjb2RlPm1haWwubWltZS51dWRlY29kZS5pZ25vcmVlcnJvcnM8L2NvZGU+CisgICAgICogY29udHJvbHMgd2hldGhlciBlcnJvcnMgaW4gdGhlIGVuY29kZWQgZGF0YSBjYXVzZSBhbiBleGNlcHRpb24KKyAgICAgKiBvciBhcmUgaWdub3JlZC4gIFRoZSBkZWZhdWx0IGlzIGZhbHNlIChlcnJvcnMgY2F1c2UgZXhjZXB0aW9uKS4KKyAgICAgKiBUaGUgU3lzdGVtIHByb3BlcnR5IDxjb2RlPm1haWwubWltZS51dWRlY29kZS5pZ25vcmVtaXNzaW5nYmVnaW5lbmQ8L2NvZGU+CisgICAgICogY29udHJvbHMgd2hldGhlciBhIG1pc3NpbmcgYmVnaW4gb3IgZW5kIGxpbmUgY2F1c2UgYW4gZXhjZXB0aW9uCisgICAgICogb3IgYXJlIGlnbm9yZWQuICBUaGUgZGVmYXVsdCBpcyBmYWxzZSAoZXJyb3JzIGNhdXNlIGV4Y2VwdGlvbikuCisgICAgICogQHBhcmFtIGluICAgICAgICB0aGUgaW5wdXQgc3RyZWFtCisgICAgICovCisgICAgcHVibGljIFVVRGVjb2RlclN0cmVhbShJbnB1dFN0cmVhbSBpbikgeworCXN1cGVyKGluKTsKKwlsaW4gPSBuZXcgTGluZUlucHV0U3RyZWFtKGluKTsKKwkvLyBkZWZhdWx0IHRvIGZhbHNlCisJaWdub3JlRXJyb3JzID0gUHJvcFV0aWwuZ2V0Qm9vbGVhblN5c3RlbVByb3BlcnR5KAorCSAgICAibWFpbC5taW1lLnV1ZGVjb2RlLmlnbm9yZWVycm9ycyIsIGZhbHNlKTsKKwkvLyBkZWZhdWx0IHRvIGZhbHNlCisJaWdub3JlTWlzc2luZ0JlZ2luRW5kID0gUHJvcFV0aWwuZ2V0Qm9vbGVhblN5c3RlbVByb3BlcnR5KAorCSAgICAibWFpbC5taW1lLnV1ZGVjb2RlLmlnbm9yZW1pc3NpbmdiZWdpbmVuZCIsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBVVWRlY29kZXIgdGhhdCBkZWNvZGVzIHRoZSBzcGVjaWZpZWQgaW5wdXQgc3RyZWFtLgorICAgICAqIEBwYXJhbSBpbiAgICAgICAgCXRoZSBpbnB1dCBzdHJlYW0KKyAgICAgKiBAcGFyYW0gaWdub3JlRXJyb3JzCWlnbm9yZSBlcnJvcnM/CisgICAgICogQHBhcmFtIGlnbm9yZU1pc3NpbmdCZWdpbkVuZAlpZ25vcmUgbWlzc2luZyBiZWdpbiBvciBlbmQ/CisgICAgICovCisgICAgcHVibGljIFVVRGVjb2RlclN0cmVhbShJbnB1dFN0cmVhbSBpbiwgYm9vbGVhbiBpZ25vcmVFcnJvcnMsCisJCQkJYm9vbGVhbiBpZ25vcmVNaXNzaW5nQmVnaW5FbmQpIHsKKwlzdXBlcihpbik7CisJbGluID0gbmV3IExpbmVJbnB1dFN0cmVhbShpbik7CisJdGhpcy5pZ25vcmVFcnJvcnMgPSBpZ25vcmVFcnJvcnM7CisJdGhpcy5pZ25vcmVNaXNzaW5nQmVnaW5FbmQgPSBpZ25vcmVNaXNzaW5nQmVnaW5FbmQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZCB0aGUgbmV4dCBkZWNvZGVkIGJ5dGUgZnJvbSB0aGlzIGlucHV0IHN0cmVhbS4gVGhlIGJ5dGUKKyAgICAgKiBpcyByZXR1cm5lZCBhcyBhbiA8Y29kZT5pbnQ8L2NvZGU+IGluIHRoZSByYW5nZSA8Y29kZT4wPC9jb2RlPgorICAgICAqIHRvIDxjb2RlPjI1NTwvY29kZT4uIElmIG5vIGJ5dGUgaXMgYXZhaWxhYmxlIGJlY2F1c2UgdGhlIGVuZCBvZgorICAgICAqIHRoZSBzdHJlYW0gaGFzIGJlZW4gcmVhY2hlZCwgdGhlIHZhbHVlIDxjb2RlPi0xPC9jb2RlPiBpcyByZXR1cm5lZC4KKyAgICAgKiBUaGlzIG1ldGhvZCBibG9ja3MgdW50aWwgaW5wdXQgZGF0YSBpcyBhdmFpbGFibGUsIHRoZSBlbmQgb2YgdGhlCisgICAgICogc3RyZWFtIGlzIGRldGVjdGVkLCBvciBhbiBleGNlcHRpb24gaXMgdGhyb3duLgorICAgICAqCisgICAgICogQHJldHVybiAgICAgbmV4dCBieXRlIG9mIGRhdGEsIG9yIDxjb2RlPi0xPC9jb2RlPiBpZiB0aGUgZW5kIG9mIAorICAgICAqICAgICAgICAgICAgIHN0cmVhbSBpcyByZWFjaGVkLgorICAgICAqIEBleGNlcHRpb24gIElPRXhjZXB0aW9uICBpZiBhbiBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqIEBzZWUgICAgICAgIGphdmEuaW8uRmlsdGVySW5wdXRTdHJlYW0jaW4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCWlmIChpbmRleCA+PSBidWZzaXplKSB7CisJICAgIHJlYWRQcmVmaXgoKTsKKwkgICAgaWYgKCFkZWNvZGUoKSkKKwkJcmV0dXJuIC0xOworCSAgICBpbmRleCA9IDA7IC8vIHJlc2V0IGluZGV4IGludG8gYnVmZmVyCisJfQorCXJldHVybiBidWZmZXJbaW5kZXgrK10gJiAweGZmOyAvLyByZXR1cm4gbG93ZXIgYnl0ZQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZChieXRlW10gYnVmLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworCWludCBpLCBjOworCWZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykgeworCSAgICBpZiAoKGMgPSByZWFkKCkpID09IC0xKSB7CisJCWlmIChpID09IDApIC8vIEF0IGVuZCBvZiBzdHJlYW0sIHNvIHdlIHNob3VsZAorCQkgICAgaSA9IC0xOyAvLyByZXR1cm4gLTEsIE5PVCAwLgorCQlicmVhazsKKwkgICAgfQorCSAgICBidWZbb2ZmK2ldID0gKGJ5dGUpYzsKKwl9CisJcmV0dXJuIGk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gbWFya1N1cHBvcnRlZCgpIHsKKwlyZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBhdmFpbGFibGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCSAvLyBUaGlzIGlzIG9ubHkgYW4gZXN0aW1hdGUsIHNpbmNlIGluLmF2YWlsYWJsZSgpCisJIC8vIG1pZ2h0IGluY2x1ZGUgQ1JMRnMgdG9vIC4uCisJIHJldHVybiAoKGluLmF2YWlsYWJsZSgpICogMykvNCArIChidWZzaXplLWluZGV4KSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSAibmFtZSIgZmllbGQgZnJvbSB0aGUgcHJlZml4LiBUaGlzIGlzIG1lYW50IHRvCisgICAgICogYmUgdGhlIHBhdGhuYW1lIG9mIHRoZSBkZWNvZGVkIGZpbGUKKyAgICAgKgorICAgICAqIEByZXR1cm4gICAgIG5hbWUgb2YgZGVjb2RlZCBmaWxlCisgICAgICogQGV4Y2VwdGlvbiAgSU9FeGNlcHRpb24gIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlyZWFkUHJlZml4KCk7CisJcmV0dXJuIG5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSAibW9kZSIgZmllbGQgZnJvbSB0aGUgcHJlZml4LiBUaGlzIGlzIHRoZSBwZXJtaXNzaW9uCisgICAgICogbW9kZSBvZiB0aGUgc291cmNlIGZpbGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuICAgICBwZXJtaXNzaW9uIG1vZGUgb2Ygc291cmNlIGZpbGUKKyAgICAgKiBAZXhjZXB0aW9uICBJT0V4Y2VwdGlvbiAgaWYgYW4gSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE1vZGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCXJlYWRQcmVmaXgoKTsKKwlyZXR1cm4gbW9kZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVVWVuY29kZWQgc3RyZWFtcyBzdGFydCBvZmYgd2l0aCB0aGUgbGluZToKKyAgICAgKiAgImJlZ2luIDxtb2RlPiA8ZmlsZW5hbWU+IgorICAgICAqIFNlYXJjaCBmb3IgdGhpcyBwcmVmaXggYW5kIGdvYmJsZSBpdCB1cC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmVhZFByZWZpeCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJaWYgKGdvdFByZWZpeCkgLy8gZ290IHRoZSBwcmVmaXgKKwkgICAgcmV0dXJuOworCisJbW9kZSA9IDA2NjY7CQkvLyBkZWZhdWx0cywgb3ZlcnJpZGRlbiBiZWxvdworCW5hbWUgPSAiZW5jb2Rlci5idWYiOwkvLyBzYW1lIGRlZmF1bHQgdXNlZCBieSBlbmNvZGVyCisJU3RyaW5nIGxpbmU7CisJZm9yICg7OykgeworCSAgICAvLyByZWFkIHRpbGwgd2UgZ2V0IHRoZSBwcmVmaXg6ICJiZWdpbiBNT0RFIEZJTEVOQU1FIgorCSAgICBsaW5lID0gbGluLnJlYWRMaW5lKCk7IC8vIE5PVEU6IHJlYWRMaW5lIGNvbnN1bWVzIENSTEYgcGFpcnMgdG9vCisJICAgIGlmIChsaW5lID09IG51bGwpIHsKKwkJaWYgKCFpZ25vcmVNaXNzaW5nQmVnaW5FbmQpCisJCSAgICB0aHJvdyBuZXcgRGVjb2RpbmdFeGNlcHRpb24oIlVVRGVjb2RlcjogTWlzc2luZyBiZWdpbiIpOworCQkvLyBhdCBFT0YsIGZha2UgaXQKKwkJZ290UHJlZml4ID0gdHJ1ZTsKKwkJZ290RW5kID0gdHJ1ZTsKKwkJYnJlYWs7CisJICAgIH0KKwkgICAgaWYgKGxpbmUucmVnaW9uTWF0Y2hlcyhmYWxzZSwgMCwgImJlZ2luIiwgMCwgNSkpIHsKKwkJdHJ5IHsKKwkJICAgIG1vZGUgPSBJbnRlZ2VyLnBhcnNlSW50KGxpbmUuc3Vic3RyaW5nKDYsOSkpOworCQl9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZXgpIHsKKwkJICAgIGlmICghaWdub3JlRXJyb3JzKQorCQkJdGhyb3cgbmV3IERlY29kaW5nRXhjZXB0aW9uKAorCQkJCSJVVURlY29kZXI6IEVycm9yIGluIG1vZGU6ICIgKyBleC50b1N0cmluZygpKTsKKwkJfQorCQlpZiAobGluZS5sZW5ndGgoKSA+IDEwKSB7CisJCSAgICBuYW1lID0gbGluZS5zdWJzdHJpbmcoMTApOworCQl9IGVsc2UgeworCQkgICAgaWYgKCFpZ25vcmVFcnJvcnMpCisJCQl0aHJvdyBuZXcgRGVjb2RpbmdFeGNlcHRpb24oCisJCQkJIlVVRGVjb2RlcjogTWlzc2luZyBuYW1lOiAiICsgbGluZSk7CisJCX0KKwkJZ290UHJlZml4ID0gdHJ1ZTsKKwkJYnJlYWs7CisJICAgIH0gZWxzZSBpZiAoaWdub3JlTWlzc2luZ0JlZ2luRW5kICYmIGxpbmUubGVuZ3RoKCkgIT0gMCkgeworCQlpbnQgY291bnQgPSBsaW5lLmNoYXJBdCgwKTsKKwkJY291bnQgPSAoY291bnQgLSAnICcpICYgMHgzZjsKKwkJaW50IG5lZWQgPSAoKGNvdW50ICogOCkrNSkvNjsKKwkJaWYgKG5lZWQgPT0gMCB8fCBsaW5lLmxlbmd0aCgpID49IG5lZWQgKyAxKSB7CisJCSAgICAvKgorCQkgICAgICogTG9va3MgbGlrZSBhIGxlZ2l0aW1hdGUgZW5jb2RlZCBsaW5lLgorCQkgICAgICogUHJldGVuZCB3ZSBzYXcgdGhlICJiZWdpbiIgbGluZSBhbmQKKwkJICAgICAqIHNhdmUgdGhpcyBsaW5lIGZvciBsYXRlciBwcm9jZXNzaW5nIGluCisJCSAgICAgKiBkZWNvZGUoKS4KKwkJICAgICAqLworCQkgICAgcmVhZEFoZWFkID0gbGluZTsKKwkJICAgIGdvdFByZWZpeCA9IHRydWU7CS8vIGZha2UgaXQKKwkJICAgIGJyZWFrOworCQl9CisJICAgIH0KKwl9CisgICAgfQorCisgICAgcHJpdmF0ZSBib29sZWFuIGRlY29kZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisKKwlpZiAoZ290RW5kKQorCSAgICByZXR1cm4gZmFsc2U7CisJYnVmc2l6ZSA9IDA7CisJaW50IGNvdW50ID0gMDsKKwlTdHJpbmcgbGluZTsKKwlmb3IgKDs7KSB7CisJICAgIC8qCisJICAgICAqIElmIHdlIGlnbm9yZWQgYSBtaXNzaW5nICJiZWdpbiIsIHRoZSBmaXJzdCBsaW5lCisJICAgICAqIHdpbGwgYmUgc2F2ZWQgaW4gcmVhZEFoZWFkLgorCSAgICAgKi8KKwkgICAgaWYgKHJlYWRBaGVhZCAhPSBudWxsKSB7CisJCWxpbmUgPSByZWFkQWhlYWQ7CisJCXJlYWRBaGVhZCA9IG51bGw7CisJICAgIH0gZWxzZQorCQlsaW5lID0gbGluLnJlYWRMaW5lKCk7CisKKwkgICAgLyoKKwkgICAgICogSW1wcm9wZXJseSBlbmNvZGVkIGRhdGEgc29tZXRpbWVzIG9taXRzIHRoZSB6ZXJvIGxlbmd0aAorCSAgICAgKiBsaW5lIHRoYXQgc3RhcnRzIHdpdGggYSBzcGFjZSBjaGFyYWN0ZXIsIHdlIGRldGVjdCB0aGUKKwkgICAgICogZm9sbG93aW5nICJlbmQiIGxpbmUgaGVyZS4KKwkgICAgICovCisJICAgIGlmIChsaW5lID09IG51bGwpIHsKKwkJaWYgKCFpZ25vcmVNaXNzaW5nQmVnaW5FbmQpCisJCSAgICB0aHJvdyBuZXcgRGVjb2RpbmdFeGNlcHRpb24oCisJCQkJCSJVVURlY29kZXI6IE1pc3NpbmcgZW5kIGF0IEVPRiIpOworCQlnb3RFbmQgPSB0cnVlOworCQlyZXR1cm4gZmFsc2U7CisJICAgIH0KKwkgICAgaWYgKGxpbmUuZXF1YWxzKCJlbmQiKSkgeworCQlnb3RFbmQgPSB0cnVlOworCQlyZXR1cm4gZmFsc2U7CisJICAgIH0KKwkgICAgaWYgKGxpbmUubGVuZ3RoKCkgPT0gMCkKKwkJY29udGludWU7CisJICAgIGNvdW50ID0gbGluZS5jaGFyQXQoMCk7CisJICAgIGlmIChjb3VudCA8ICcgJykgeworCQlpZiAoIWlnbm9yZUVycm9ycykKKwkJICAgIHRocm93IG5ldyBEZWNvZGluZ0V4Y2VwdGlvbigKKwkJCQkJIlVVRGVjb2RlcjogQnVmZmVyIGZvcm1hdCBlcnJvciIpOworCQljb250aW51ZTsKKwkgICAgfQorCisJICAgIC8qCisJICAgICAqIFRoZSBmaXJzdCBjaGFyYWN0ZXIgaW4gYSBsaW5lIGlzIHRoZSBudW1iZXIgb2Ygb3JpZ2luYWwgKG5vdAorCSAgICAgKiAgdGhlIGVuY29kZWQgYXRvbXMpIGNoYXJhY3RlcnMgaW4gdGhlIGxpbmUuIE5vdGUgdGhhdCBhbGwgdGhlCisJICAgICAqICBjb2RlIGJlbG93IGhhcyB0byBoYW5kbGUgdGhlIDxTUEFDRT4gY2hhcmFjdGVyIHRoYXQgaW5kaWNhdGVzCisJICAgICAqICBlbmQgb2YgZW5jb2RlZCBzdHJlYW0uCisJICAgICAqLworCSAgICBjb3VudCA9IChjb3VudCAtICcgJykgJiAweDNmOworCisJICAgIGlmIChjb3VudCA9PSAwKSB7CisJCWxpbmUgPSBsaW4ucmVhZExpbmUoKTsKKwkJaWYgKGxpbmUgPT0gbnVsbCB8fCAhbGluZS5lcXVhbHMoImVuZCIpKSB7CisJCSAgICBpZiAoIWlnbm9yZU1pc3NpbmdCZWdpbkVuZCkKKwkJCXRocm93IG5ldyBEZWNvZGluZ0V4Y2VwdGlvbigKKwkJCQkiVVVEZWNvZGVyOiBNaXNzaW5nIEVuZCBhZnRlciBjb3VudCAwIGxpbmUiKTsKKwkJfQorCQlnb3RFbmQgPSB0cnVlOworCQlyZXR1cm4gZmFsc2U7CisJICAgIH0KKworCSAgICBpbnQgbmVlZCA9ICgoY291bnQgKiA4KSs1KS82OworLy9TeXN0ZW0ub3V0LnByaW50bG4oImNvdW50ICIgKyBjb3VudCArICIsIG5lZWQgIiArIG5lZWQgKyAiLCBsZW4gIiArIGxpbmUubGVuZ3RoKCkpOworCSAgICBpZiAobGluZS5sZW5ndGgoKSA8IG5lZWQgKyAxKSB7CisJCWlmICghaWdub3JlRXJyb3JzKQorCQkgICAgdGhyb3cgbmV3IERlY29kaW5nRXhjZXB0aW9uKAorCQkJCQkiVVVEZWNvZGVyOiBTaG9ydCBidWZmZXIgZXJyb3IiKTsKKwkJY29udGludWU7CisJICAgIH0KKworCSAgICAvLyBnb3QgYSBsaW5lIHdlJ3JlIGNvbW1pdHRlZCB0bywgYnJlYWsgb3V0IGFuZCBkZWNvZGUgaXQKKwkgICAgYnJlYWs7CisJfQorCSAgICAKKwlpbnQgaSA9IDE7CisJYnl0ZSBhLCBiOworCS8qCisJICogQSBjb3JyZWN0IHV1ZW5jb2RlciBhbHdheXMgZW5jb2RlcyAzIGNoYXJhY3RlcnMgYXQgYSB0aW1lLCBldmVuCisJICogaWYgdGhlcmUgYXJlbid0IDMgY2hhcmFjdGVycyBsZWZ0LiAgQnV0IHNpbmNlIHNvbWUgcGVvcGxlIG91dAorCSAqIHRoZXJlIGhhdmUgYnJva2VuIHV1ZW5jb2RlcnMgd2UgaGFuZGxlIHRoZSBjYXNlIHdoZXJlIHRoZXkKKwkgKiBkb24ndCBpbmNsdWRlIHRoZXNlICJ1bm5lY2Vzc2FyeSIgY2hhcmFjdGVycy4KKwkgKi8KKwl3aGlsZSAoYnVmc2l6ZSA8IGNvdW50KSB7CisJICAgIC8vIGNvbnRpbnVlIGRlY29kaW5nIHVudGlsIHdlIGdldCAnY291bnQnIGRlY29kZWQgY2hhcnMKKwkgICAgYSA9IChieXRlKSgobGluZS5jaGFyQXQoaSsrKSAtICcgJykgJiAweDNmKTsKKwkgICAgYiA9IChieXRlKSgobGluZS5jaGFyQXQoaSsrKSAtICcgJykgJiAweDNmKTsKKwkgICAgYnVmZmVyW2J1ZnNpemUrK10gPSAoYnl0ZSkoKChhIDw8IDIpICYgMHhmYykgfCAoKGIgPj4+IDQpICYgMykpOworCisJICAgIGlmIChidWZzaXplIDwgY291bnQpIHsKKwkJYSA9IGI7CisJCWIgPSAoYnl0ZSkoKGxpbmUuY2hhckF0KGkrKykgLSAnICcpICYgMHgzZik7CisJCWJ1ZmZlcltidWZzaXplKytdID0KKwkJCQkoYnl0ZSkoKChhIDw8IDQpICYgMHhmMCkgfCAoKGIgPj4+IDIpICYgMHhmKSk7CisJICAgIH0KKworCSAgICBpZiAoYnVmc2l6ZSA8IGNvdW50KSB7CisJCWEgPSBiOworCQliID0gKGJ5dGUpKChsaW5lLmNoYXJBdChpKyspIC0gJyAnKSAmIDB4M2YpOworCQlidWZmZXJbYnVmc2l6ZSsrXSA9IChieXRlKSgoKGEgPDwgNikgJiAweGMwKSB8IChiICYgMHgzZikpOworCSAgICB9CisJfQorCXJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKiogYmVnaW4gVEVTVCBwcm9ncmFtICoqKioqCisgICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nIGFyZ3ZbXSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgCUZpbGVJbnB1dFN0cmVhbSBpbmZpbGUgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGFyZ3ZbMF0pOworCVVVRGVjb2RlclN0cmVhbSBkZWNvZGVyID0gbmV3IFVVRGVjb2RlclN0cmVhbShpbmZpbGUpOworCWludCBjOworCisJdHJ5IHsKKwkgICAgd2hpbGUgKChjID0gZGVjb2Rlci5yZWFkKCkpICE9IC0xKQorCQlTeXN0ZW0ub3V0LndyaXRlKGMpOworCSAgICBTeXN0ZW0ub3V0LmZsdXNoKCk7CisJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKwkgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKwl9CisgICAgfQorICAgICoqKiogZW5kIFRFU1QgcHJvZ3JhbSAqKioqLworfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL1VVRW5jb2RlclN0cmVhbS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL1VVRW5jb2RlclN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE4M2NjMzQKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvVVVFbmNvZGVyU3RyZWFtLmphdmEKQEAgLTAsMCArMSwyMDUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLnV0aWw7CisKK2ltcG9ydCBqYXZhLmlvLio7CisKKy8qKgorICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIGEgVVVFbmNvZGVyLiBJdCBpcyBpbXBsZW1lbnRlZCBhcworICogYSBGaWx0ZXJPdXRwdXRTdHJlYW0sIHNvIG9uZSBjYW4ganVzdCB3cmFwIHRoaXMgY2xhc3MgYXJvdW5kCisgKiBhbnkgb3V0cHV0IHN0cmVhbSBhbmQgd3JpdGUgYnl0ZXMgaW50byB0aGlzIGZpbHRlci4gVGhlIEVuY29kaW5nCisgKiBpcyBkb25lIGFzIHRoZSBieXRlcyBhcmUgd3JpdHRlbiBvdXQuCisgKiAKKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKi8KKworcHVibGljIGNsYXNzIFVVRW5jb2RlclN0cmVhbSBleHRlbmRzIEZpbHRlck91dHB1dFN0cmVhbSB7CisgICAgcHJpdmF0ZSBieXRlW10gYnVmZmVyOyAJLy8gY2FjaGUgb2YgYnl0ZXMgdGhhdCBhcmUgeWV0IHRvIGJlIGVuY29kZWQKKyAgICBwcml2YXRlIGludCBidWZzaXplID0gMDsJLy8gc2l6ZSBvZiB0aGUgY2FjaGUKKyAgICBwcml2YXRlIGJvb2xlYW4gd3JvdGVQcmVmaXggPSBmYWxzZTsKKyAgICBwcml2YXRlIGJvb2xlYW4gd3JvdGVTdWZmaXggPSBmYWxzZTsKKworICAgIHByaXZhdGUgU3RyaW5nIG5hbWU7IAkvLyBuYW1lIG9mIGZpbGUKKyAgICBwcml2YXRlIGludCBtb2RlOwkJLy8gcGVybWlzc2lvbnMgbW9kZQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgVVVlbmNvZGVyIHRoYXQgZW5jb2RlcyB0aGUgc3BlY2lmaWVkIGlucHV0IHN0cmVhbQorICAgICAqIEBwYXJhbSBvdXQgICAgICAgIHRoZSBvdXRwdXQgc3RyZWFtCisgICAgICovCisgICAgcHVibGljIFVVRW5jb2RlclN0cmVhbShPdXRwdXRTdHJlYW0gb3V0KSB7CisJdGhpcyhvdXQsICJlbmNvZGVyLmJ1ZiIsIDA2NDQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIFVVZW5jb2RlciB0aGF0IGVuY29kZXMgdGhlIHNwZWNpZmllZCBpbnB1dCBzdHJlYW0KKyAgICAgKiBAcGFyYW0gb3V0ICAgICAgICB0aGUgb3V0cHV0IHN0cmVhbQorICAgICAqIEBwYXJhbSBuYW1lCSBTcGVjaWZpZXMgYSBuYW1lIGZvciB0aGUgZW5jb2RlZCBidWZmZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgVVVFbmNvZGVyU3RyZWFtKE91dHB1dFN0cmVhbSBvdXQsIFN0cmluZyBuYW1lKSB7CisJdGhpcyhvdXQsIG5hbWUsIDA2NDQpOwkKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBVVWVuY29kZXIgdGhhdCBlbmNvZGVzIHRoZSBzcGVjaWZpZWQgaW5wdXQgc3RyZWFtCisgICAgICogQHBhcmFtIG91dCAgICAgICAgdGhlIG91dHB1dCBzdHJlYW0KKyAgICAgKiBAcGFyYW0gbmFtZSAgICAgICBTcGVjaWZpZXMgYSBuYW1lIGZvciB0aGUgZW5jb2RlZCBidWZmZXIKKyAgICAgKiBAcGFyYW0gbW9kZQkgU3BlY2lmaWVzIHBlcm1pc3Npb24gbW9kZSBmb3IgdGhlIGVuY29kZWQgYnVmZmVyCisgICAgICovCisgICAgcHVibGljIFVVRW5jb2RlclN0cmVhbShPdXRwdXRTdHJlYW0gb3V0LCBTdHJpbmcgbmFtZSwgaW50IG1vZGUpIHsKKwlzdXBlcihvdXQpOworCXRoaXMubmFtZSA9IG5hbWU7CisJdGhpcy5tb2RlID0gbW9kZTsKKwlidWZmZXIgPSBuZXcgYnl0ZVs0NV07CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHVwIHRoZSBidWZmZXIgbmFtZSBhbmQgcGVybWlzc2lvbiBtb2RlLgorICAgICAqIFRoaXMgbWV0aG9kIGhhcyBhbnkgZWZmZWN0IG9ubHkgaWYgaXQgaXMgaW52b2tlZCBiZWZvcmUKKyAgICAgKiB5b3Ugc3RhcnQgd3JpdGluZyBpbnRvIHRoZSBvdXRwdXQgc3RyZWFtCisgICAgICoKKyAgICAgKiBAcGFyYW0JbmFtZQl0aGUgYnVmZmVyIG5hbWUKKyAgICAgKiBAcGFyYW0JbW9kZQl0aGUgcGVybWlzc2lvbiBtb2RlCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TmFtZU1vZGUoU3RyaW5nIG5hbWUsIGludCBtb2RlKSB7CisJdGhpcy5uYW1lID0gbmFtZTsKKwl0aGlzLm1vZGUgPSBtb2RlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworCWZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyBpKyspCisJICAgIHdyaXRlKGJbb2ZmICsgaV0pOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGJ5dGVbXSBkYXRhKSB0aHJvd3MgSU9FeGNlcHRpb24geworCXdyaXRlKGRhdGEsIDAsIGRhdGEubGVuZ3RoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShpbnQgYykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkvKiBidWZmZXIgdXAgY2hhcmFjdGVycyB0aWxsIHdlIGdldCBhIGxpbmUncyB3b3J0aCwgdGhlbiBlbmNvZGUKKwkgKiBhbmQgd3JpdGUgdGhlbSBvdXQuIE1heCBudW1iZXIgb2YgY2hhcmFjdGVycyBhbGxvd2VkIHBlciAKKwkgKiBsaW5lIGlzIDQ1LgorCSAqLworCWJ1ZmZlcltidWZzaXplKytdID0gKGJ5dGUpYzsKKwlpZiAoYnVmc2l6ZSA9PSA0NSkgeworCSAgICB3cml0ZVByZWZpeCgpOworCSAgICBlbmNvZGUoKTsKKwkgICAgYnVmc2l6ZSA9IDA7CisJfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGZsdXNoKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlpZiAoYnVmc2l6ZSA+IDApIHsgLy8gSWYgdGhlcmUncyB1bmVuY29kZWQgY2hhcmFjdGVycyBpbiB0aGUgYnVmZmVyCisJICAgIHdyaXRlUHJlZml4KCk7CisJICAgIGVuY29kZSgpOyAgICAgIC8vIC4uIGVuY29kZSB0aGVtCisJICAgIGJ1ZnNpemUgPSAwOworCX0KKwl3cml0ZVN1ZmZpeCgpOworCW91dC5mbHVzaCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlmbHVzaCgpOworCW91dC5jbG9zZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlIG91dCB0aGUgcHJlZml4OiAiYmVnaW4gPG1vZGU+IDxuYW1lPiIKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgd3JpdGVQcmVmaXgoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCWlmICghd3JvdGVQcmVmaXgpIHsKKwkgICAgLy8gbmFtZSBzaG91bGQgYmUgQVNDSUksIGJ1dCB3aG8ga25vd3MuLi4KKwkgICAgUHJpbnRTdHJlYW0gcHMgPSBuZXcgUHJpbnRTdHJlYW0ob3V0LCBmYWxzZSwgInV0Zi04Iik7CisJICAgIHBzLmZvcm1hdCgiYmVnaW4gJW8gJXMlbiIsIG1vZGUsIG5hbWUpOworCSAgICBwcy5mbHVzaCgpOworCSAgICB3cm90ZVByZWZpeCA9IHRydWU7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlIGEgc2luZ2xlIGxpbmUgY29udGFpbmluZyBzcGFjZSBhbmQgdGhlIHN1ZmZpeCBsaW5lCisgICAgICogY29udGFpbmluZyB0aGUgc2luZ2xlIHdvcmQgImVuZCIgKHRlcm1pbmF0ZWQgYnkgYSBuZXdsaW5lKQorICAgICAqLworICAgIHByaXZhdGUgdm9pZCB3cml0ZVN1ZmZpeCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJaWYgKCF3cm90ZVN1ZmZpeCkgeworCSAgICBQcmludFN0cmVhbSBwcyA9IG5ldyBQcmludFN0cmVhbShvdXQsIGZhbHNlLCAidXMtYXNjaWkiKTsKKwkgICAgcHMucHJpbnRsbigiIFxuZW5kIik7CisJICAgIHBzLmZsdXNoKCk7CisJICAgIHdyb3RlU3VmZml4ID0gdHJ1ZTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogRW5jb2RlIGEgbGluZS4gCisgICAgICogU3RhcnQgb2ZmIHdpdGggdGhlIGNoYXJhY3RlciBjb3VudCwgZm9sbG93ZWQgYnkgdGhlIGVuY29kZWQgYXRvbXMKKyAgICAgKiBhbmQgdGVybWluYXRlIHdpdGggTEYuIChvciBpcyBpdCBDUkxGIG9yIHRoZSBsb2NhbCBsaW5lLXRlcm1pbmF0b3IgPykKKyAgICAgKiBUYWtlIHRocmVlIGJ5dGVzIGFuZCBlbmNvZGVzIHRoZW0gaW50byA0IGNoYXJhY3RlcnMKKyAgICAgKiBJZiBidWZzaXplIGlmIG5vdCBhIG11bHRpcGxlIG9mIDMsIHRoZSByZW1haW5pbmcgYnl0ZXMgYXJlIGZpbGxlZCAKKyAgICAgKiB3aXRoICcxJy4gVGhpcyBpbnN1cmVzIHRoYXQgdGhlIGxhc3QgbGluZSB3b24ndCBlbmQgaW4gc3BhY2VzIAorICAgICAqIGFuZCBwb3RlbnRpYWxsbHkgYmUgdHJ1bmNhdGVkLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBlbmNvZGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCWJ5dGUgYSwgYiwgYzsKKwlpbnQgYzEsIGMyLCBjMywgYzQ7CisJaW50IGkgPSAwOworCisJLy8gU3RhcnQgb2ZmIHdpdGggdGhlIGNvdW50IG9mIGNoYXJhY3RlcnMgaW4gdGhlIGxpbmUKKwlvdXQud3JpdGUoKGJ1ZnNpemUgJiAweDNmKSArICcgJyk7CisKKwl3aGlsZSAoaSA8IGJ1ZnNpemUpIHsKKwkgICAgYSA9IGJ1ZmZlcltpKytdOworCSAgICBpZiAoaSA8IGJ1ZnNpemUpIHsKKwkJYiA9IGJ1ZmZlcltpKytdOworCQlpZiAoaSA8IGJ1ZnNpemUpCisJCSAgICBjID0gYnVmZmVyW2krK107CisJCWVsc2UgLy8gZGVmYXVsdCBjIHRvIDEKKwkJICAgIGMgPSAxOworCSAgICB9CisJICAgIGVsc2UgeyAvLyBkZWZhdWx0IGIgJiBjIHRvIDEKKwkJYiA9IDE7CisJCWMgPSAxOworCSAgICB9CisKKwkgICAgYzEgPSAoYSA+Pj4gMikgJiAweDNmOworCSAgICBjMiA9ICgoYSA8PCA0KSAmIDB4MzApIHwgKChiID4+PiA0KSAmIDB4Zik7CisJICAgIGMzID0gKChiIDw8IDIpICYgMHgzYykgfCAoKGMgPj4+IDYpICYgMHgzKTsKKwkgICAgYzQgPSBjICYgMHgzZjsKKwkgICAgb3V0LndyaXRlKGMxICsgJyAnKTsKKwkgICAgb3V0LndyaXRlKGMyICsgJyAnKTsKKwkgICAgb3V0LndyaXRlKGMzICsgJyAnKTsKKwkgICAgb3V0LndyaXRlKGM0ICsgJyAnKTsKKwl9CisJLy8gVGVybWluYXRlIHdpdGggTEYuIChzaG91bGQgaXQgYmUgQ1JMRiBvciBsb2NhbCBsaW5lLXRlcm1pbmF0b3IgPykKKwlvdXQud3JpdGUoJ1xuJyk7CisgICAgfQorCisgICAgLyoqKiogYmVnaW4gVEVTVCBwcm9ncmFtICoqKioqCisgICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nIGFyZ3ZbXSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJRmlsZUlucHV0U3RyZWFtIGluZmlsZSA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oYXJndlswXSk7CisJVVVFbmNvZGVyU3RyZWFtIGVuY29kZXIgPSBuZXcgVVVFbmNvZGVyU3RyZWFtKFN5c3RlbS5vdXQpOworCWludCBjOworCisJd2hpbGUgKChjID0gaW5maWxlLnJlYWQoKSkgIT0gLTEpCisJICAgIGVuY29kZXIud3JpdGUoYyk7CisJZW5jb2Rlci5jbG9zZSgpOworICAgIH0KKyAgICAqKioqIGVuZCBURVNUIHByb2dyYW0gKioqKiovCit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvV3JpdGVUaW1lb3V0U29ja2V0LmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvV3JpdGVUaW1lb3V0U29ja2V0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWNkMDFiMgotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvdXRpbC9Xcml0ZVRpbWVvdXRTb2NrZXQuamF2YQpAQCAtMCwwICsxLDQwMSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAxMywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwudXRpbDsKKworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZhLm5ldC4qOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50Lio7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuU29ja2V0Q2hhbm5lbDsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC4qOworCisvKioKKyAqIEEgc3BlY2lhbCBTb2NrZXQgdGhhdCB1c2VzIGEgU2NoZWR1bGVkRXhlY3V0b3JTZXJ2aWNlIHRvCisgKiBpbXBsZW1lbnQgdGltZW91dHMgZm9yIHdyaXRlcy4gIFRoZSB3cml0ZSB0aW1lb3V0IGlzIHNwZWNpZmllZAorICogKGluIG1pbGxpc2Vjb25kcykgd2hlbiB0aGUgV3JpdGVUaW1lb3V0U29ja2V0IGlzIGNyZWF0ZWQuCisgKgorICogQGF1dGhvcglCaWxsIFNoYW5ub24KKyAqLworcHVibGljIGNsYXNzIFdyaXRlVGltZW91dFNvY2tldCBleHRlbmRzIFNvY2tldCB7CisKKyAgICAvLyBkZWxlZ2F0ZSBhbGwgb3BlcmF0aW9ucyB0byB0aGlzIHNvY2tldAorICAgIHByaXZhdGUgZmluYWwgU29ja2V0IHNvY2tldDsKKyAgICAvLyB0byBzY2hlZHVsZSB0YXNrIHRvIGNhbmNlbCB3cml0ZSBhZnRlciB0aW1lb3V0CisgICAgcHJpdmF0ZSBmaW5hbCBTY2hlZHVsZWRFeGVjdXRvclNlcnZpY2Ugc2VzOworICAgIC8vIHRoZSB0aW1lb3V0LCBpbiBtaWxsaXNlY29uZHMKKyAgICBwcml2YXRlIGZpbmFsIGludCB0aW1lb3V0OworCisgICAgcHVibGljIFdyaXRlVGltZW91dFNvY2tldChTb2NrZXQgc29ja2V0LCBpbnQgdGltZW91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwl0aGlzLnNvY2tldCA9IHNvY2tldDsKKwkvLyBYWFggLSBjb3VsZCBzaGFyZSBleGVjdXRvciB3aXRoIGFsbCBpbnN0YW5jZXM/CisgICAgICAgIHRoaXMuc2VzID0gRXhlY3V0b3JzLm5ld1NjaGVkdWxlZFRocmVhZFBvb2woMSk7CisJdGhpcy50aW1lb3V0ID0gdGltZW91dDsKKyAgICB9CisKKyAgICBwdWJsaWMgV3JpdGVUaW1lb3V0U29ja2V0KGludCB0aW1lb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworCXRoaXMobmV3IFNvY2tldCgpLCB0aW1lb3V0KTsKKyAgICB9CisKKyAgICBwdWJsaWMgV3JpdGVUaW1lb3V0U29ja2V0KEluZXRBZGRyZXNzIGFkZHJlc3MsIGludCBwb3J0LCBpbnQgdGltZW91dCkKKwkJCQl0aHJvd3MgSU9FeGNlcHRpb24geworCXRoaXModGltZW91dCk7CisJc29ja2V0LmNvbm5lY3QobmV3IEluZXRTb2NrZXRBZGRyZXNzKGFkZHJlc3MsIHBvcnQpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgV3JpdGVUaW1lb3V0U29ja2V0KEluZXRBZGRyZXNzIGFkZHJlc3MsIGludCBwb3J0LAorCQkJSW5ldEFkZHJlc3MgbG9jYWxBZGRyZXNzLCBpbnQgbG9jYWxQb3J0LCBpbnQgdGltZW91dCkKKwkJCXRocm93cyBJT0V4Y2VwdGlvbiB7CisJdGhpcyh0aW1lb3V0KTsKKwlzb2NrZXQuYmluZChuZXcgSW5ldFNvY2tldEFkZHJlc3MobG9jYWxBZGRyZXNzLCBsb2NhbFBvcnQpKTsKKwlzb2NrZXQuY29ubmVjdChuZXcgSW5ldFNvY2tldEFkZHJlc3MoYWRkcmVzcywgcG9ydCkpOworICAgIH0KKworICAgIHB1YmxpYyBXcml0ZVRpbWVvdXRTb2NrZXQoU3RyaW5nIGhvc3QsIGludCBwb3J0LCBpbnQgdGltZW91dCkKKwkJCQl0aHJvd3MgSU9FeGNlcHRpb24geworCXRoaXModGltZW91dCk7CisJc29ja2V0LmNvbm5lY3QobmV3IEluZXRTb2NrZXRBZGRyZXNzKGhvc3QsIHBvcnQpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgV3JpdGVUaW1lb3V0U29ja2V0KFN0cmluZyBob3N0LCBpbnQgcG9ydCwKKwkJCUluZXRBZGRyZXNzIGxvY2FsQWRkcmVzcywgaW50IGxvY2FsUG9ydCwgaW50IHRpbWVvdXQpCisJCQl0aHJvd3MgSU9FeGNlcHRpb24geworCXRoaXModGltZW91dCk7CisJc29ja2V0LmJpbmQobmV3IEluZXRTb2NrZXRBZGRyZXNzKGxvY2FsQWRkcmVzcywgbG9jYWxQb3J0KSk7CisJc29ja2V0LmNvbm5lY3QobmV3IEluZXRTb2NrZXRBZGRyZXNzKGhvc3QsIHBvcnQpKTsKKyAgICB9CisKKyAgICAvLyBvdmVycmlkZSBhbGwgU29ja2V0IG1ldGhvZHMgYW5kIGRlbGVnYXRlIHRvIHVuZGVybHlpbmcgU29ja2V0CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjb25uZWN0KFNvY2tldEFkZHJlc3MgcmVtb3RlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBzb2NrZXQuY29ubmVjdChyZW1vdGUsIDApOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNvbm5lY3QoU29ja2V0QWRkcmVzcyByZW1vdGUsIGludCB0aW1lb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworCXNvY2tldC5jb25uZWN0KHJlbW90ZSwgdGltZW91dCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgYmluZChTb2NrZXRBZGRyZXNzIGxvY2FsKSB0aHJvd3MgSU9FeGNlcHRpb24geworCXNvY2tldC5iaW5kKGxvY2FsKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU29ja2V0QWRkcmVzcyBnZXRSZW1vdGVTb2NrZXRBZGRyZXNzKCkgeworCXJldHVybiBzb2NrZXQuZ2V0UmVtb3RlU29ja2V0QWRkcmVzcygpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTb2NrZXRBZGRyZXNzIGdldExvY2FsU29ja2V0QWRkcmVzcygpIHsKKwlyZXR1cm4gc29ja2V0LmdldExvY2FsU29ja2V0QWRkcmVzcygpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFBlcmZvcm1hbmNlUHJlZmVyZW5jZXMoaW50IGNvbm5lY3Rpb25UaW1lLCBpbnQgbGF0ZW5jeSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBiYW5kd2lkdGgpIHsKKyAgICAgICAgc29ja2V0LnNldFBlcmZvcm1hbmNlUHJlZmVyZW5jZXMoY29ubmVjdGlvblRpbWUsIGxhdGVuY3ksIGJhbmR3aWR0aCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFNvY2tldENoYW5uZWwgZ2V0Q2hhbm5lbCgpIHsKKwlyZXR1cm4gc29ja2V0LmdldENoYW5uZWwoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgSW5ldEFkZHJlc3MgZ2V0SW5ldEFkZHJlc3MoKSB7CisJcmV0dXJuIHNvY2tldC5nZXRJbmV0QWRkcmVzcygpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBJbmV0QWRkcmVzcyBnZXRMb2NhbEFkZHJlc3MoKSB7CisJcmV0dXJuIHNvY2tldC5nZXRMb2NhbEFkZHJlc3MoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldFBvcnQoKSB7CisJcmV0dXJuIHNvY2tldC5nZXRQb3J0KCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRMb2NhbFBvcnQoKSB7CisJcmV0dXJuIHNvY2tldC5nZXRMb2NhbFBvcnQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgSW5wdXRTdHJlYW0gZ2V0SW5wdXRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworCXJldHVybiBzb2NrZXQuZ2V0SW5wdXRTdHJlYW0oKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIE91dHB1dFN0cmVhbSBnZXRPdXRwdXRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworCS8vIHdyYXAgdGhlIHJldHVybmVkIHN0cmVhbSB0byBpbXBsZW1lbnQgd3JpdGUgdGltZW91dAorICAgICAgICByZXR1cm4gbmV3IFRpbWVvdXRPdXRwdXRTdHJlYW0oc29ja2V0LmdldE91dHB1dFN0cmVhbSgpLCBzZXMsIHRpbWVvdXQpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFRjcE5vRGVsYXkoYm9vbGVhbiBvbikgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIHNvY2tldC5zZXRUY3BOb0RlbGF5KG9uKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBnZXRUY3BOb0RlbGF5KCkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBzb2NrZXQuZ2V0VGNwTm9EZWxheSgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFNvTGluZ2VyKGJvb2xlYW4gb24sIGludCBsaW5nZXIpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICBzb2NrZXQuc2V0U29MaW5nZXIob24sIGxpbmdlcik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRTb0xpbmdlcigpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gc29ja2V0LmdldFNvTGluZ2VyKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2VuZFVyZ2VudERhdGEoaW50IGRhdGEpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHNvY2tldC5zZW5kVXJnZW50RGF0YShkYXRhKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRPT0JJbmxpbmUoYm9vbGVhbiBvbikgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIHNvY2tldC5zZXRPT0JJbmxpbmUob24pOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGdldE9PQklubGluZSgpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gc29ja2V0LmdldE9PQklubGluZSgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFNvVGltZW91dChpbnQgdGltZW91dCkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisJc29ja2V0LnNldFNvVGltZW91dCh0aW1lb3V0KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldFNvVGltZW91dCgpIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gc29ja2V0LmdldFNvVGltZW91dCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFNlbmRCdWZmZXJTaXplKGludCBzaXplKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgc29ja2V0LnNldFNlbmRCdWZmZXJTaXplKHNpemUpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0U2VuZEJ1ZmZlclNpemUoKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHNvY2tldC5nZXRTZW5kQnVmZmVyU2l6ZSgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFJlY2VpdmVCdWZmZXJTaXplKGludCBzaXplKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgc29ja2V0LnNldFJlY2VpdmVCdWZmZXJTaXplKHNpemUpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0UmVjZWl2ZUJ1ZmZlclNpemUoKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHNvY2tldC5nZXRSZWNlaXZlQnVmZmVyU2l6ZSgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldEtlZXBBbGl2ZShib29sZWFuIG9uKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgc29ja2V0LnNldEtlZXBBbGl2ZShvbik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZ2V0S2VlcEFsaXZlKCkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBzb2NrZXQuZ2V0S2VlcEFsaXZlKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0VHJhZmZpY0NsYXNzKGludCB0YykgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIHNvY2tldC5zZXRUcmFmZmljQ2xhc3ModGMpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0VHJhZmZpY0NsYXNzKCkgdGhyb3dzIFNvY2tldEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBzb2NrZXQuZ2V0VHJhZmZpY0NsYXNzKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0UmV1c2VBZGRyZXNzKGJvb2xlYW4gb24pIHRocm93cyBTb2NrZXRFeGNlcHRpb24geworICAgICAgICBzb2NrZXQuc2V0UmV1c2VBZGRyZXNzKG9uKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBnZXRSZXVzZUFkZHJlc3MoKSB0aHJvd3MgU29ja2V0RXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHNvY2tldC5nZXRSZXVzZUFkZHJlc3MoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJdHJ5IHsKKwkgICAgc29ja2V0LmNsb3NlKCk7CisJfSBmaW5hbGx5IHsKKwkgICAgc2VzLnNodXRkb3duTm93KCk7CisJfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNodXRkb3duSW5wdXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCXNvY2tldC5zaHV0ZG93bklucHV0KCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2h1dGRvd25PdXRwdXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCXNvY2tldC5zaHV0ZG93bk91dHB1dCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisJcmV0dXJuIHNvY2tldC50b1N0cmluZygpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGlzQ29ubmVjdGVkKCkgeworICAgICAgICByZXR1cm4gc29ja2V0LmlzQ29ubmVjdGVkKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaXNCb3VuZCgpIHsKKyAgICAgICAgcmV0dXJuIHNvY2tldC5pc0JvdW5kKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaXNDbG9zZWQoKSB7CisgICAgICAgIHJldHVybiBzb2NrZXQuaXNDbG9zZWQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0lucHV0U2h1dGRvd24oKSB7CisgICAgICAgIHJldHVybiBzb2NrZXQuaXNJbnB1dFNodXRkb3duKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaXNPdXRwdXRTaHV0ZG93bigpIHsKKyAgICAgICAgcmV0dXJuIHNvY2tldC5pc091dHB1dFNodXRkb3duKCk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBUaGUgZm9sbG93aW5nIHRocmVlIG1ldGhvZHMgd2VyZSBhZGRlZCB0byBqYXZhLm5ldC5Tb2NrZXQgaW4gSmF2YSBTRSA5LgorICAgICAqIFNpbmNlIHRoZXkncmUgbm90IHN1cHBvcnRlZCBvbiBBbmRyb2lkLCBhbmQgc2luY2Ugd2Uga25vdyB0aGF0IHdlCisgICAgICogbmV2ZXIgdXNlIHRoZW0gaW4gSmF2YU1haWwsIHdlIGp1c3Qgc3R1YiB0aGVtIG91dCBoZXJlLgorICAgICAqLworICAgIC8vQE92ZXJyaWRlCisgICAgcHVibGljIDxUPiBTb2NrZXQgc2V0T3B0aW9uKFNvY2tldE9wdGlvbjxUPiBzbywgVCB2YWwpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJLy8gc29ja2V0LnNldE9wdGlvbihzbywgdmFsKTsKKwkvLyByZXR1cm4gdGhpczsKKwl0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIldyaXRlVGltZW91dFNvY2tldC5zZXRPcHRpb24iKTsKKyAgICB9CisKKyAgICAvL0BPdmVycmlkZQorICAgIHB1YmxpYyA8VD4gVCBnZXRPcHRpb24oU29ja2V0T3B0aW9uPFQ+IHNvKSB0aHJvd3MgSU9FeGNlcHRpb24geworCS8vIHJldHVybiBzb2NrZXQuZ2V0T3B0aW9uKHNvKTsKKwl0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIldyaXRlVGltZW91dFNvY2tldC5nZXRPcHRpb24iKTsKKyAgICB9CisKKyAgICAvL0BPdmVycmlkZQorICAgIHB1YmxpYyBTZXQ8U29ja2V0T3B0aW9uPD8+PiBzdXBwb3J0ZWRPcHRpb25zKCkgeworCS8vIHJldHVybiBzb2NrZXQuc3VwcG9ydGVkT3B0aW9ucygpOworCXJldHVybiBDb2xsZWN0aW9ucy5lbXB0eVNldCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEtMVURHRSBmb3IgQW5kcm9pZCwgd2hpY2ggaGFzIHRoaXMgaWxsZWdhbCBub24tSmF2YSBDb21wYXRpYmxlIG1ldGhvZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIEZpbGVEZXNjcmlwdG9yIG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyBGaWxlRGVzY3JpcHRvciBnZXRGaWxlRGVzY3JpcHRvciQoKSB7CisJdHJ5IHsKKwkgICAgTWV0aG9kIG0gPSBTb2NrZXQuY2xhc3MuZ2V0RGVjbGFyZWRNZXRob2QoImdldEZpbGVEZXNjcmlwdG9yJCIpOworCSAgICByZXR1cm4gKEZpbGVEZXNjcmlwdG9yKW0uaW52b2tlKHNvY2tldCk7CisJfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJICAgIHJldHVybiBudWxsOworCX0KKyAgICB9Cit9CisKKworLyoqCisgKiBBbiBPdXRwdXRTdHJlYW0gdGhhdCB3cmFwcyB0aGUgU29ja2V0J3MgT3V0cHV0U3RyZWFtIGFuZCB1c2VzCisgKiB0aGUgU2NoZWR1bGVkRXhlY3V0b3JTZXJ2aWNlIHRvIHNjaGVkdWxlIGEgdGFzayB0byBjbG9zZSB0aGUKKyAqIHNvY2tldCAoYWJvcnRpbmcgdGhlIHdyaXRlKSBpZiB0aGUgdGltZW91dCBleHBpcmVzLgorICovCitjbGFzcyBUaW1lb3V0T3V0cHV0U3RyZWFtIGV4dGVuZHMgT3V0cHV0U3RyZWFtIHsKKyAgICBwcml2YXRlIGZpbmFsIE91dHB1dFN0cmVhbSBvczsKKyAgICBwcml2YXRlIGZpbmFsIFNjaGVkdWxlZEV4ZWN1dG9yU2VydmljZSBzZXM7CisgICAgcHJpdmF0ZSBmaW5hbCBDYWxsYWJsZTxPYmplY3Q+IHRpbWVvdXRUYXNrOworICAgIHByaXZhdGUgZmluYWwgaW50IHRpbWVvdXQ7CisgICAgcHJpdmF0ZSBieXRlW10gYjE7CisKKyAgICBwdWJsaWMgVGltZW91dE91dHB1dFN0cmVhbShPdXRwdXRTdHJlYW0gb3MwLCBTY2hlZHVsZWRFeGVjdXRvclNlcnZpY2Ugc2VzLAorCQkJCWludCB0aW1lb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworCXRoaXMub3MgPSBvczA7CisJdGhpcy5zZXMgPSBzZXM7CisJdGhpcy50aW1lb3V0ID0gdGltZW91dDsKKwl0aW1lb3V0VGFzayA9IG5ldyBDYWxsYWJsZTxPYmplY3Q+KCkgeworCSAgICBAT3ZlcnJpZGUKKwkgICAgcHVibGljIE9iamVjdCBjYWxsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJCW9zLmNsb3NlKCk7CS8vIGNsb3NlIHRoZSBzdHJlYW0gdG8gYWJvcnQgdGhlIHdyaXRlCisJCXJldHVybiBudWxsOworCSAgICB9CisJfTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgd3JpdGUoaW50IGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJaWYgKGIxID09IG51bGwpCisJICAgIGIxID0gbmV3IGJ5dGVbMV07CisJYjFbMF0gPSAoYnl0ZSliOworCXRoaXMud3JpdGUoYjEpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCB3cml0ZShieXRlW10gYnMsIGludCBvZmYsIGludCBsZW4pCisJCQkJdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlpZiAoKG9mZiA8IDApIHx8IChvZmYgPiBicy5sZW5ndGgpIHx8IChsZW4gPCAwKSB8fAorCSAgICAoKG9mZiArIGxlbikgPiBicy5sZW5ndGgpIHx8ICgob2ZmICsgbGVuKSA8IDApKSB7CisJICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCk7CisJfSBlbHNlIGlmIChsZW4gPT0gMCkgeworCSAgICByZXR1cm47CisJfQorCisJLy8gSW1wbGVtZW50IHRpbWVvdXQgd2l0aCBhIHNjaGVkdWxlZCB0YXNrCisJU2NoZWR1bGVkRnV0dXJlPE9iamVjdD4gc2YgPSBudWxsOworCXRyeSB7CisJICAgIHRyeSB7CisJCWlmICh0aW1lb3V0ID4gMCkKKwkJICAgIHNmID0gc2VzLnNjaGVkdWxlKHRpbWVvdXRUYXNrLAorCQkJCQl0aW1lb3V0LCBUaW1lVW5pdC5NSUxMSVNFQ09ORFMpOworCSAgICB9IGNhdGNoIChSZWplY3RlZEV4ZWN1dGlvbkV4Y2VwdGlvbiBleCkgeworCQkvLyBpZ25vcmUgaXQ7IEV4ZWN1dG9yIHdhcyBzaHV0IGRvd24gYnkgYW5vdGhlciB0aHJlYWQsCisJCS8vIHRoZSBmb2xsb3dpbmcgd3JpdGUgc2hvdWxkIGZhaWwgd2l0aCBJT0V4Y2VwdGlvbgorCSAgICB9CisJICAgIG9zLndyaXRlKGJzLCBvZmYsIGxlbik7CisJfSBmaW5hbGx5IHsKKwkgICAgaWYgKHNmICE9IG51bGwpCisJCXNmLmNhbmNlbCh0cnVlKTsKKwl9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCW9zLmNsb3NlKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL2xvZ2dpbmcvQ29sbGVjdG9yRm9ybWF0dGVyLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvbG9nZ2luZy9Db2xsZWN0b3JGb3JtYXR0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zYjY3YmExCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL2xvZ2dpbmcvQ29sbGVjdG9yRm9ybWF0dGVyLmphdmEKQEAgLTAsMCArMSw2MDEgQEAKKy8qDQorICogQ29weXJpZ2h0IChjKSAyMDEzLCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQorICogQ29weXJpZ2h0IChjKSAyMDEzLCAyMDE4IEphc29uIE1laHJlbnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQorICoNCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUNCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdA0KKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4NCisgKg0KKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkNCisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlDQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsDQorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQNCisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuDQorICoNCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjANCisgKi8NCitwYWNrYWdlIGNvbS5zdW4ubWFpbC51dGlsLmxvZ2dpbmc7DQorDQoraW1wb3J0IHN0YXRpYyBjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nLkxvZ01hbmFnZXJQcm9wZXJ0aWVzLmZyb21Mb2dNYW5hZ2VyOw0KK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5VbmRlY2xhcmVkVGhyb3dhYmxlRXhjZXB0aW9uOw0KK2ltcG9ydCBqYXZhLnRleHQuTWVzc2FnZUZvcm1hdDsNCitpbXBvcnQgamF2YS51dGlsLkNvbXBhcmF0b3I7DQoraW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7DQoraW1wb3J0IGphdmEudXRpbC5SZXNvdXJjZUJ1bmRsZTsNCitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuRm9ybWF0dGVyOw0KK2ltcG9ydCBqYXZhLnV0aWwubG9nZ2luZy5IYW5kbGVyOw0KK2ltcG9ydCBqYXZhLnV0aWwubG9nZ2luZy5Mb2dSZWNvcmQ7DQorDQorLyoqDQorICogQSBMb2dSZWNvcmQgZm9ybWF0dGVyIHRoYXQgdGFrZXMgYSBzZXF1ZW5jZSBvZiBMb2dSZWNvcmRzIGFuZCBjb21iaW5lcyB0aGVtDQorICogaW50byBhIHNpbmdsZSBzdW1tYXJ5IHJlc3VsdC4gRm9ybWF0aW5nIG9mIHRoZSBoZWFkLCBMb2dSZWNvcmQsIGFuZCB0YWlsIGFyZQ0KKyAqIGRlbGVnYXRlZCB0byB0aGUgd3JhcHBlZCBmb3JtYXR0ZXIuDQorICoNCisgKiA8cD4NCisgKiBCeSBkZWZhdWx0IGVhY2ggPHR0PkNvbGxlY3RvckZvcm1hdHRlcjwvdHQ+IGlzIGluaXRpYWxpemVkIHVzaW5nIHRoZQ0KKyAqIGZvbGxvd2luZyBMb2dNYW5hZ2VyIGNvbmZpZ3VyYXRpb24gcHJvcGVydGllcyB3aGVyZQ0KKyAqIDx0dD4mbHQ7Zm9ybWF0dGVyLW5hbWUmZ3Q7PC90dD4gcmVmZXJzIHRvIHRoZSBmdWxseSBxdWFsaWZpZWQgY2xhc3MgbmFtZSBvcg0KKyAqIHRoZSBmdWxseSBxdWFsaWZpZWQgZGVyaXZlZCBjbGFzcyBuYW1lIG9mIHRoZSBmb3JtYXR0ZXIuICBJZiBwcm9wZXJ0aWVzIGFyZQ0KKyAqIG5vdCBkZWZpbmVkLCBvciBjb250YWluIGludmFsaWQgdmFsdWVzLCB0aGVuIHRoZSBzcGVjaWZpZWQgZGVmYXVsdCB2YWx1ZXMgYXJlDQorICogdXNlZC4NCisgKiA8dWw+DQorICogPGxpPiZsdDtmb3JtYXR0ZXItbmFtZSZndDsuY29tcGFyYXRvciBuYW1lIG9mIGENCisgKiB7QGxpbmtwbGFpbiBqYXZhLnV0aWwuQ29tcGFyYXRvcn0gY2xhc3MgdXNlZCB0byBjaG9vc2UgdGhlIGNvbGxlY3RlZA0KKyAqIDx0dD5Mb2dSZWNvcmQ8L3R0Pi4gSWYgYSBjb21wYXJhdG9yIGlzIHNwZWNpZmllZCB0aGVuIHRoZSBtYXgNCisgKiA8dHQ+TG9nUmVjb3JkPC90dD4gaXMgY2hvc2VuLiBJZiBjb21wYXJhdG9yIGlzIHNldCB0byB0aGUgc3RyaW5nIGxpdGVyYWwNCisgKiBudWxsLCB0aGVuIHRoZSBsYXN0IHJlY29yZCBpcyBjaG9zZW4uIChkZWZhdWx0cyB0bw0KKyAqIHtAbGlua3BsYWluIFNldmVyaXR5Q29tcGFyYXRvcn0pDQorICoNCisgKiA8bGk+Jmx0O2Zvcm1hdHRlci1uYW1lJmd0Oy5jb21wYXJhdG9yLnJldmVyc2UgYSBib29sZWFuDQorICogPHR0PnRydWU8L3R0PiB0byBjb2xsZWN0IHRoZSBtaW4gPHR0PkxvZ1JlY29yZDwvdHQ+IG9yIDx0dD5mYWxzZTwvdHQ+IHRvDQorICogY29sbGVjdCB0aGUgbWF4IDx0dD5Mb2dSZWNvcmQ8L3R0Pi4gKGRlZmF1bHRzIHRvIDx0dD5mYWxzZTwvdHQ+KQ0KKyAqDQorICogPGxpPiZsdDtmb3JtYXR0ZXItbmFtZSZndDsuZm9ybWF0IHRoZQ0KKyAqIHtAbGlua3BsYWluIGphdmEudGV4dC5NZXNzYWdlRm9ybWF0IE1lc3NhZ2VGb3JtYXR9IHN0cmluZyB1c2VkIHRvIGZvcm1hdCB0aGUNCisgKiBjb2xsZWN0ZWQgc3VtbWFyeSBzdGF0aXN0aWNzLiBUaGUgYXJndW1lbnRzIGFyZSBleHBsYWluZWQgaW4gZGV0YWlsIGluIHRoZQ0KKyAqIHtAbGlua3BsYWluICNnZXRUYWlsKGphdmEudXRpbC5sb2dnaW5nLkhhbmRsZXIpIGdldFRhaWx9IGRvY3VtZW50YXRpb24uDQorICogKGRlZmF1bHRzIHRvIDx0dD57MH17MX17Mn17NCxjaG9pY2UsLTEjfDAjfDAmbHQ7Li4uIHs0LG51bWJlcixpbnRlZ2VyfQ0KKyAqIG1vcmV9XG48L3R0PikNCisgKg0KKyAqIDxsaT4mbHQ7Zm9ybWF0dGVyLW5hbWUmZ3Q7LmZvcm1hdHRlciBuYW1lIG9mIGEgPHR0PkZvcm1hdHRlcjwvdHQ+IGNsYXNzIHVzZWQNCisgKiB0byBmb3JtYXQgdGhlIGNvbGxlY3RlZCBMb2dSZWNvcmQuIChkZWZhdWx0cyB0byB7QGxpbmtwbGFpbiBDb21wYWN0Rm9ybWF0dGVyfSkNCisgKg0KKyAqIDwvdWw+DQorICoNCisgKiBAYXV0aG9yIEphc29uIE1laHJlbnMNCisgKiBAc2luY2UgSmF2YU1haWwgMS41LjINCisgKi8NCitwdWJsaWMgY2xhc3MgQ29sbGVjdG9yRm9ybWF0dGVyIGV4dGVuZHMgRm9ybWF0dGVyIHsNCisgICAgLyoqDQorICAgICAqIEF2b2lkIGRlcGVuZGluZyBvbiBKTVggcnVudGltZSBiZWFuIHRvIGdldCB0aGUgc3RhcnQgdGltZS4NCisgICAgICovDQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgSU5JVF9USU1FID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7DQorICAgIC8qKg0KKyAgICAgKiBUaGUgbWVzc2FnZSBmb3JtYXQgc3RyaW5nIHVzZWQgYXMgdGhlIGZvcm1hdHRlZCBvdXRwdXQuDQorICAgICAqLw0KKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBmbXQ7DQorICAgIC8qKg0KKyAgICAgKiBUaGUgZm9ybWF0dGVyIHVzZWQgdG8gZm9ybWF0IHRoZSBjaG9zZW4gbG9nIHJlY29yZC4NCisgICAgICovDQorICAgIHByaXZhdGUgZmluYWwgRm9ybWF0dGVyIGZvcm1hdHRlcjsNCisgICAgLyoqDQorICAgICAqIFRoZSBjb21wYXJhdG9yIHVzZWQgdG8gcGljayB0aGUgbG9nIHJlY29yZCB0byBmb3JtYXQuDQorICAgICAqLw0KKyAgICBwcml2YXRlIGZpbmFsIENvbXBhcmF0b3I8PyBzdXBlciBMb2dSZWNvcmQ+IGNvbXBhcmF0b3I7DQorICAgIC8qKg0KKyAgICAgKiBUaGUgbGFzdCBhY2NlcHRlZCByZWNvcmQuIFN5bmNocm9uaXplZCBhY2Nlc3MgaXMgcHJlZmVycmVkIG92ZXIgdm9sYXRpbGUNCisgICAgICogZm9yIHRoaXMgY2xhc3MuDQorICAgICAqLw0KKyAgICBwcml2YXRlIExvZ1JlY29yZCBsYXN0Ow0KKyAgICAvKioNCisgICAgICogVGhlIG51bWJlciBvZiBsb2cgcmVjb3JkcyB0aGF0IGhhdmUgYmVlbiBmb3JtYXR0ZWQuDQorICAgICAqLw0KKyAgICBwcml2YXRlIGxvbmcgY291bnQ7DQorICAgIC8qKg0KKyAgICAgKiBUaGUgbnVtYmVyIG9mIGxvZyBwcm9kdWNlZCBjb250YWluaW5nIGF0IGxlYXN0IG9uZSBsb2cgcmVjb3JkLg0KKyAgICAgKiBPbmx5IGluY3JlbWVudGVkIHdoZW4gdGhpcyBmb3JtYXR0ZXIgaXMgcmVzZXQuDQorICAgICAqLw0KKyAgICBwcml2YXRlIGxvbmcgZ2VuZXJhdGlvbiA9IDFMOw0KKyAgICAvKioNCisgICAgICogVGhlIG51bWJlciBvZiBsb2cgcmVjb3JkcyB0aGF0IGhhdmUgYmVlbiBmb3JtYXR0ZWQgd2l0aCBhIHRocm93biBvYmplY3QuDQorICAgICAqLw0KKyAgICBwcml2YXRlIGxvbmcgdGhyb3duOw0KKyAgICAvKioNCisgICAgICogVGhlIGVsZGVzdCBsb2cgcmVjb3JkIHRpbWUgb3IgZWxkZXN0IHRpbWUgcG9zc2libGUgZm9yIHRoaXMgaW5zdGFuY2UuDQorICAgICAqLw0KKyAgICBwcml2YXRlIGxvbmcgbWluTWlsbGlzID0gSU5JVF9USU1FOw0KKyAgICAvKioNCisgICAgICogVGhlIG5ld2VzdCBsb2cgcmVjb3JkIHRpbWUuDQorICAgICAqLw0KKyAgICBwcml2YXRlIGxvbmcgbWF4TWlsbGlzID0gTG9uZy5NSU5fVkFMVUU7DQorDQorICAgIC8qKg0KKyAgICAgKiBDcmVhdGVzIHRoZSBmb3JtYXR0ZXIgdXNpbmcgdGhlIExvZ01hbmFnZXIgZGVmYXVsdHMuDQorICAgICAqDQorICAgICAqIEB0aHJvd3MgU2VjdXJpdHlFeGNlcHRpb24gaWYgYSBzZWN1cml0eSBtYW5hZ2VyIGV4aXN0cyBhbmQgdGhlIGNhbGxlcg0KKyAgICAgKiBkb2VzIG5vdCBoYXZlIDx0dD5Mb2dnaW5nUGVybWlzc2lvbigiY29udHJvbCIpPC90dD4uDQorICAgICAqIEB0aHJvd3MgVW5kZWNsYXJlZFRocm93YWJsZUV4Y2VwdGlvbiBpZiB0aGVyZSBhcmUgcHJvYmxlbXMgbG9hZGluZyBmcm9tDQorICAgICAqIHRoZSBMb2dNYW5hZ2VyLg0KKyAgICAgKi8NCisgICAgcHVibGljIENvbGxlY3RvckZvcm1hdHRlcigpIHsNCisgICAgICAgIGZpbmFsIFN0cmluZyBwID0gZ2V0Q2xhc3MoKS5nZXROYW1lKCk7DQorICAgICAgICB0aGlzLmZtdCA9IGluaXRGb3JtYXQocCk7DQorICAgICAgICB0aGlzLmZvcm1hdHRlciA9IGluaXRGb3JtYXR0ZXIocCk7DQorICAgICAgICB0aGlzLmNvbXBhcmF0b3IgPSBpbml0Q29tcGFyYXRvcihwKTsNCisgICAgfQ0KKw0KKyAgICAvKioNCisgICAgICogQ3JlYXRlcyB0aGUgZm9ybWF0dGVyIHVzaW5nIHRoZSBnaXZlbiBmb3JtYXQuDQorICAgICAqDQorICAgICAqIEBwYXJhbSBmb3JtYXQgdGhlIG1lc3NhZ2UgZm9ybWF0IG9yIG51bGwgdG8gdXNlIHRoZSBMb2dNYW5hZ2VyIGRlZmF1bHQuDQorICAgICAqIEB0aHJvd3MgU2VjdXJpdHlFeGNlcHRpb24gaWYgYSBzZWN1cml0eSBtYW5hZ2VyIGV4aXN0cyBhbmQgdGhlIGNhbGxlcg0KKyAgICAgKiBkb2VzIG5vdCBoYXZlIDx0dD5Mb2dnaW5nUGVybWlzc2lvbigiY29udHJvbCIpPC90dD4uDQorICAgICAqIEB0aHJvd3MgVW5kZWNsYXJlZFRocm93YWJsZUV4Y2VwdGlvbiBpZiB0aGVyZSBhcmUgcHJvYmxlbXMgbG9hZGluZyBmcm9tDQorICAgICAqIHRoZSBMb2dNYW5hZ2VyLg0KKyAgICAgKi8NCisgICAgcHVibGljIENvbGxlY3RvckZvcm1hdHRlcihTdHJpbmcgZm9ybWF0KSB7DQorICAgICAgICBmaW5hbCBTdHJpbmcgcCA9IGdldENsYXNzKCkuZ2V0TmFtZSgpOw0KKyAgICAgICAgdGhpcy5mbXQgPSBmb3JtYXQgPT0gbnVsbCA/IGluaXRGb3JtYXQocCkgOiBmb3JtYXQ7DQorICAgICAgICB0aGlzLmZvcm1hdHRlciA9IGluaXRGb3JtYXR0ZXIocCk7DQorICAgICAgICB0aGlzLmNvbXBhcmF0b3IgPSBpbml0Q29tcGFyYXRvcihwKTsNCisgICAgfQ0KKw0KKyAgICAvKioNCisgICAgICogQ3JlYXRlcyB0aGUgZm9ybWF0dGVyIHVzaW5nIHRoZSBnaXZlbiB2YWx1ZXMuDQorICAgICAqDQorICAgICAqIEBwYXJhbSBmb3JtYXQgdGhlIGZvcm1hdCBzdHJpbmcgb3IgbnVsbCB0byB1c2UgdGhlIExvZ01hbmFnZXIgZGVmYXVsdC4NCisgICAgICogQHBhcmFtIGYgdGhlIGZvcm1hdHRlciB1c2VkIG9uIHRoZSBjb2xsZWN0ZWQgbG9nIHJlY29yZCBvciBudWxsIHRvDQorICAgICAqIHNwZWNpZnkgbm8gZm9ybWF0dGVyLg0KKyAgICAgKiBAcGFyYW0gYyB0aGUgY29tcGFyYXRvciB1c2VkIHRvIGRldGVybWluZSB3aGljaCBsb2cgcmVjb3JkIHRvIGZvcm1hdCBvcg0KKyAgICAgKiBudWxsIHRvIHNwZWNpZnkgbm8gY29tcGFyYXRvci4NCisgICAgICogQHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbiBpZiBhIHNlY3VyaXR5IG1hbmFnZXIgZXhpc3RzIGFuZCB0aGUgY2FsbGVyDQorICAgICAqIGRvZXMgbm90IGhhdmUgPHR0PkxvZ2dpbmdQZXJtaXNzaW9uKCJjb250cm9sIik8L3R0Pi4NCisgICAgICogQHRocm93cyBVbmRlY2xhcmVkVGhyb3dhYmxlRXhjZXB0aW9uIGlmIHRoZXJlIGFyZSBwcm9ibGVtcyBsb2FkaW5nIGZyb20NCisgICAgICogdGhlIExvZ01hbmFnZXIuDQorICAgICAqLw0KKyAgICBwdWJsaWMgQ29sbGVjdG9yRm9ybWF0dGVyKFN0cmluZyBmb3JtYXQsIEZvcm1hdHRlciBmLA0KKyAgICAgICAgICAgIENvbXBhcmF0b3I8PyBzdXBlciBMb2dSZWNvcmQ+IGMpIHsNCisgICAgICAgIGZpbmFsIFN0cmluZyBwID0gZ2V0Q2xhc3MoKS5nZXROYW1lKCk7DQorICAgICAgICB0aGlzLmZtdCA9IGZvcm1hdCA9PSBudWxsID8gaW5pdEZvcm1hdChwKSA6IGZvcm1hdDsNCisgICAgICAgIHRoaXMuZm9ybWF0dGVyID0gZjsNCisgICAgICAgIHRoaXMuY29tcGFyYXRvciA9IGM7DQorICAgIH0NCisNCisgICAgLyoqDQorICAgICAqIEFjY3VtdWxhdGVzIGxvZyByZWNvcmRzIHdoaWNoIHdpbGwgYmUgdXNlZCB0byBwcm9kdWNlIHRoZSBmaW5hbCBvdXRwdXQuDQorICAgICAqIFRoZSBvdXRwdXQgaXMgZ2VuZXJhdGVkIHVzaW5nIHRoZSB7QGxpbmsgI2dldFRhaWx9IG1ldGhvZCB3aGljaCBhbHNvDQorICAgICAqIHJlc2V0cyB0aGlzIGZvcm1hdHRlciBiYWNrIHRvIGl0cyBvcmlnaW5hbCBzdGF0ZS4NCisgICAgICoNCisgICAgICogQHBhcmFtIHJlY29yZCB0aGUgcmVjb3JkIHRvIHN0b3JlLg0KKyAgICAgKiBAcmV0dXJuIGFuIGVtcHR5IHN0cmluZy4NCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgZ2l2ZW4gcmVjb3JkIGlzIG51bGwuDQorICAgICAqLw0KKyAgICBAT3ZlcnJpZGUNCisgICAgcHVibGljIFN0cmluZyBmb3JtYXQoZmluYWwgTG9nUmVjb3JkIHJlY29yZCkgew0KKyAgICAgICAgaWYgKHJlY29yZCA9PSBudWxsKSB7DQorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7DQorICAgICAgICB9DQorDQorICAgICAgICBib29sZWFuIGFjY2VwdGVkOw0KKyAgICAgICAgZG8gew0KKyAgICAgICAgICAgIGZpbmFsIExvZ1JlY29yZCBwZWVrID0gcGVlaygpOw0KKyAgICAgICAgICAgIC8vVGhlIHNlbGYgY29tcGFyZSBvZiB0aGUgZmlyc3QgcmVjb3JkIGFjdHMgbGlrZSBhIHR5cGUgY2hlY2suDQorICAgICAgICAgICAgTG9nUmVjb3JkIHVwZGF0ZSA9IGFwcGx5KHBlZWsgIT0gbnVsbCA/IHBlZWsgOiByZWNvcmQsIHJlY29yZCk7DQorICAgICAgICAgICAgaWYgKHBlZWsgIT0gdXBkYXRlKSB7IC8vTm90IGlkZW50aWNhbC4NCisgICAgICAgICAgICAgICAgdXBkYXRlLmdldFNvdXJjZU1ldGhvZE5hbWUoKTsgLy9JbmZlciBjYWxsZXIsIG51bGwgY2hlY2suDQorICAgICAgICAgICAgICAgIGFjY2VwdGVkID0gYWNjZXB0QW5kVXBkYXRlKHBlZWssIHVwZGF0ZSk7DQorICAgICAgICAgICAgfSBlbHNlIHsNCisgICAgICAgICAgICAgICAgYWNjZXB0ZWQgPSBhY2NlcHQocGVlaywgcmVjb3JkKTsNCisgICAgICAgICAgICB9DQorICAgICAgICB9IHdoaWxlICghYWNjZXB0ZWQpOw0KKyAgICAgICAgcmV0dXJuICIiOw0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBGb3JtYXRzIHRoZSBjb2xsZWN0ZWQgTG9nUmVjb3JkIGFuZCBzdW1tYXJ5IHN0YXRpc3RpY3MuIFRoZSBjb2xsZWN0ZWQNCisgICAgICogcmVzdWx0cyBhcmUgcmVzZXQgYWZ0ZXIgY2FsbGluZyB0aGlzIG1ldGhvZC4gVGhlDQorICAgICAqIHtAbGlua3BsYWluIGphdmEudGV4dC5NZXNzYWdlRm9ybWF0IGphdmEudGV4dH0gYXJndW1lbnQgaW5kZXhlcyBhcmUgYXNzaWduZWQNCisgICAgICogdG8gdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOg0KKyAgICAgKg0KKyAgICAgKiA8b2wgc3RhcnQ9JzAnPg0KKyAgICAgKiA8bGk+e0Bjb2RlIGhlYWR9IHRoZQ0KKyAgICAgKiB7QGxpbmtwbGFpbiBGb3JtYXR0ZXIjZ2V0SGVhZChqYXZhLnV0aWwubG9nZ2luZy5IYW5kbGVyKSBoZWFkfSBzdHJpbmcNCisgICAgICogcmV0dXJuZWQgZnJvbSB0aGUgdGFyZ2V0IGZvcm1hdHRlciBhbmQNCisgICAgICoge0BsaW5rcGxhaW4gI2ZpbmlzaChqYXZhLmxhbmcuU3RyaW5nKSBmaW5pc2hlZH0gYnkgdGhpcyBmb3JtYXR0ZXIuDQorICAgICAqIDxsaT57QGNvZGUgZm9ybWF0dGVkfSB0aGUgY3VycmVudCBsb2cgcmVjb3JkDQorICAgICAqIHtAbGlua3BsYWluIEZvcm1hdHRlciNmb3JtYXQoamF2YS51dGlsLmxvZ2dpbmcuTG9nUmVjb3JkKSBmb3JtYXR0ZWR9IGJ5DQorICAgICAqIHRoZSB0YXJnZXQgZm9ybWF0dGVyIGFuZCB7QGxpbmtwbGFpbiAjZmluaXNoKGphdmEubGFuZy5TdHJpbmcpIGZpbmlzaGVkfQ0KKyAgICAgKiBieSB0aGlzIGZvcm1hdHRlci4gIElmIHRoZSBmb3JtYXR0ZXIgaXMgbnVsbCB0aGVuIHJlY29yZCBpcyBmb3JtYXR0ZWQgYnkNCisgICAgICogdGhpcyB7QGxpbmtwbGFpbiAjZm9ybWF0TWVzc2FnZShqYXZhLnV0aWwubG9nZ2luZy5Mb2dSZWNvcmQpIGZvcm1hdHRlcn0uDQorICAgICAqIDxsaT57QGNvZGUgdGFpbH0gdGhlDQorICAgICAqIHtAbGlua3BsYWluIEZvcm1hdHRlciNnZXRUYWlsKGphdmEudXRpbC5sb2dnaW5nLkhhbmRsZXIpIHRhaWx9IHN0cmluZw0KKyAgICAgKiByZXR1cm5lZCBmcm9tIHRoZSB0YXJnZXQgZm9ybWF0dGVyIGFuZA0KKyAgICAgKiB7QGxpbmtwbGFpbiAjZmluaXNoKGphdmEubGFuZy5TdHJpbmcpIGZpbmlzaGVkfSBieSB0aGlzIGZvcm1hdHRlci4NCisgICAgICogPGxpPntAY29kZSBjb3VudH0gdGhlIHRvdGFsIG51bWJlciBvZiBsb2cgcmVjb3Jkcw0KKyAgICAgKiB7QGxpbmtwbGFpbiAjZm9ybWF0IGNvbnN1bWVkfSBieSB0aGlzIGZvcm1hdHRlci4NCisgICAgICogPGxpPntAY29kZSByZW1haW5pbmd9IHRoZSBjb3VudCBtaW51cyBvbmUuDQorICAgICAqIDxsaT57QGNvZGUgdGhyb3dufSB0aGUgdG90YWwgbnVtYmVyIG9mIGxvZyByZWNvcmRzDQorICAgICAqIHtAbGlua3BsYWluICNmb3JtYXQgY29uc3VtZWR9IGJ5IHRoaXMgZm9ybWF0dGVyIHdpdGggYW4gYXNzaWduZWQNCisgICAgICoge0BsaW5rcGxhaW4gamF2YS51dGlsLmxvZ2dpbmcuTG9nUmVjb3JkI2dldFRocm93biB0aHJvd2FibGV9Lg0KKyAgICAgKiA8bGk+e0Bjb2RlIG5vcm1hbCBtZXNzYWdlc30gdGhlIGNvdW50IG1pbnVzIHRoZSB0aHJvd24uDQorICAgICAqIDxsaT57QGNvZGUgbWluTWlsbGlzfSB0aGUgZWxkZXN0IGxvZyByZWNvcmQNCisgICAgICoge0BsaW5rcGxhaW4gamF2YS51dGlsLmxvZ2dpbmcuTG9nUmVjb3JkI2dldE1pbGxpcyBldmVudCB0aW1lfQ0KKyAgICAgKiB7QGxpbmtwbGFpbiAjZm9ybWF0IGNvbnN1bWVkfSBieSB0aGlzIGZvcm1hdHRlci4gSWYgdGhlIGNvdW50IGlzIHplcm8NCisgICAgICogdGhlbiB0aGlzIGlzIHNldCB0byB0aGUgcHJldmlvdXMgbWF4IG9yIGFwcHJveGltYXRlIHN0YXJ0IHRpbWUgaWYgdGhlcmUNCisgICAgICogd2FzIG5vIHByZXZpb3VzIG1heC4gQnkgZGVmYXVsdCB0aGlzIHBhcmFtZXRlciBpcyBkZWZpbmVkIGFzIGEgbnVtYmVyLg0KKyAgICAgKiBUaGUgZm9ybWF0IHR5cGUgYW5kIGZvcm1hdCBzdHlsZSBydWxlcyBmcm9tIHRoZQ0KKyAgICAgKiB7QGxpbmtwbGFpbiBqYXZhLnRleHQuTWVzc2FnZUZvcm1hdH0gc2hvdWxkIGJlIHVzZWQgdG8gY29udmVydCB0aGlzIGZyb20NCisgICAgICogbWlsbGlzZWNvbmRzIHRvIGEgZGF0ZSBvciB0aW1lLg0KKyAgICAgKiA8bGk+e0Bjb2RlIG1heE1pbGxpc30gdGhlIG1vc3QgcmVjZW50IGxvZyByZWNvcmQNCisgICAgICoge0BsaW5rcGxhaW4gamF2YS51dGlsLmxvZ2dpbmcuTG9nUmVjb3JkI2dldE1pbGxpcyBldmVudCB0aW1lfQ0KKyAgICAgKiB7QGxpbmtwbGFpbiAjZm9ybWF0IGNvbnN1bWVkfSBieSB0aGlzIGZvcm1hdHRlci4gSWYgdGhlIGNvdW50IGlzIHplcm8NCisgICAgICogdGhlbiB0aGlzIGlzIHNldCB0byB0aGUge0BsaW5rcGxhaW4gU3lzdGVtI2N1cnJlbnRUaW1lTWlsbGlzKCkgY3VycmVudCB0aW1lfS4NCisgICAgICogQnkgZGVmYXVsdCB0aGlzIHBhcmFtZXRlciBpcyBkZWZpbmVkIGFzIGEgbnVtYmVyLiBUaGUgZm9ybWF0IHR5cGUgYW5kDQorICAgICAqIGZvcm1hdCBzdHlsZSBydWxlcyBmcm9tIHRoZSB7QGxpbmtwbGFpbiBqYXZhLnRleHQuTWVzc2FnZUZvcm1hdH0gc2hvdWxkIGJlDQorICAgICAqIHVzZWQgdG8gY29udmVydCB0aGlzIGZyb20gbWlsbGlzZWNvbmRzIHRvIGEgZGF0ZSBvciB0aW1lLg0KKyAgICAgKiA8bGk+e0Bjb2RlIGVsYXBzZWR9IHRoZSBlbGFwc2VkIHRpbWUgaW4gbWlsbGlzZWNvbmRzIGJldHdlZW4gdGhlDQorICAgICAqIHtAY29kZSBtYXhNaWxsaXN9IGFuZCB7QGNvZGUgbWluTWlsbGlzfS4NCisgICAgICogPGxpPntAY29kZSBzdGFydFRpbWV9IHRoZSBhcHByb3hpbWF0ZSBzdGFydCB0aW1lIGluIG1pbGxpc2Vjb25kcy4gIEJ5DQorICAgICAqIGRlZmF1bHQgdGhpcyBwYXJhbWV0ZXIgaXMgZGVmaW5lZCBhcyBhIG51bWJlci4gVGhlIGZvcm1hdCB0eXBlIGFuZCBmb3JtYXQNCisgICAgICogc3R5bGUgcnVsZXMgZnJvbSB0aGUge0BsaW5rcGxhaW4gamF2YS50ZXh0Lk1lc3NhZ2VGb3JtYXR9IHNob3VsZCBiZSB1c2VkIHRvDQorICAgICAqIGNvbnZlcnQgdGhpcyBmcm9tIG1pbGxpc2Vjb25kcyB0byBhIGRhdGUgb3IgdGltZS4NCisgICAgICogPGxpPntAY29kZSBjdXJyZW50VGltZX0gdGhlDQorICAgICAqIHtAbGlua3BsYWluIFN5c3RlbSNjdXJyZW50VGltZU1pbGxpcygpIGN1cnJlbnQgdGltZX0gaW4gbWlsbGlzZWNvbmRzLiAgQnkNCisgICAgICogZGVmYXVsdCB0aGlzIHBhcmFtZXRlciBpcyBkZWZpbmVkIGFzIGEgbnVtYmVyLiBUaGUgZm9ybWF0IHR5cGUgYW5kIGZvcm1hdA0KKyAgICAgKiBzdHlsZSBydWxlcyBmcm9tIHRoZSB7QGxpbmtwbGFpbiBqYXZhLnRleHQuTWVzc2FnZUZvcm1hdH0gc2hvdWxkIGJlIHVzZWQgdG8NCisgICAgICogY29udmVydCB0aGlzIGZyb20gbWlsbGlzZWNvbmRzIHRvIGEgZGF0ZSBvciB0aW1lLg0KKyAgICAgKiA8bGk+e0Bjb2RlIHVwdGltZX0gdGhlIGVsYXBzZWQgdGltZSBpbiBtaWxsaXNlY29uZHMgYmV0d2VlbiB0aGUNCisgICAgICoge0Bjb2RlIGN1cnJlbnRUaW1lfSBhbmQge0Bjb2RlIHN0YXJ0VGltZX0uDQorICAgICAqIDxsaT57QGNvZGUgZ2VuZXJhdGlvbn0gdGhlIG51bWJlciB0aW1lcyB0aGlzIG1ldGhvZCBwcm9kdWNlZCBvdXRwdXQgd2l0aA0KKyAgICAgKiBhdCBsZWFzdCBvbmUge0BsaW5rcGxhaW4gI2Zvcm1hdCBjb25zdW1lZH0gbG9nIHJlY29yZC4gIFRoaXMgY2FuIGJlIHVzZWQNCisgICAgICogdG8gdHJhY2sgdGhlIG51bWJlciBvZiBjb21wbGV0ZSByZXBvcnRzIHRoaXMgZm9ybWF0dGVyIGhhcyBwcm9kdWNlZC4NCisgICAgICogPC9vbD4NCisgICAgICoNCisgICAgICogPHA+DQorICAgICAqIFNvbWUgZXhhbXBsZSBmb3JtYXRzOjxicj4NCisgICAgICogPHVsPg0KKyAgICAgKiA8bGk+e0Bjb2RlIGNvbS5zdW4ubWFpbC51dGlsLmxvZ2dpbmcuQ29sbGVjdG9yRm9ybWF0dGVyLmZvcm1hdD17MH17MX17Mn17NCxjaG9pY2UsLTEjfDAjfDA8Li4uIHs0LG51bWJlcixpbnRlZ2VyfSBtb3JlfVxufQ0KKyAgICAgKiA8cD4NCisgICAgICogVGhpcyBwcmludHMgdGhlIGhlYWQgKHtAY29kZSB7MH19KSwgZm9ybWF0ICh7QGNvZGUgezF9fSksIGFuZCB0YWlsDQorICAgICAqICh7QGNvZGUgezJ9fSkgZnJvbSB0aGUgdGFyZ2V0IGZvcm1hdHRlciBmb2xsb3dlZCBieSB0aGUgbnVtYmVyIG9mDQorICAgICAqIHJlbWFpbmluZyAoe0Bjb2RlIHs0fX0pIGxvZyByZWNvcmRzIGNvbnN1bWVkIGJ5IHRoaXMgZm9ybWF0dGVyIGlmIHRoZXJlDQorICAgICAqIGFyZSBhbnkgcmVtYWluaW5nIHJlY29yZHMuDQorICAgICAqIDxwcmU+DQorICAgICAqIEVuY29kaW5nIGZhaWxlZC58TnVsbFBvaW50ZXJFeGNlcHRpb246IG51bGwgU3RyaW5nLmdldEJ5dGVzKDo5MTMpLi4uIDMgbW9yZQ0KKyAgICAgKiA8L3ByZT4NCisgICAgICogPGxpPntAY29kZSBjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nLkNvbGxlY3RvckZvcm1hdHRlci5mb3JtYXQ9VGhlc2UgezN9IG1lc3NhZ2VzIG9jY3VycmVkIGJldHdlZW5cbns3LGRhdGUsRUVFLCBNTU0gZGQgSEg6bW06c3M6UyBaWlogeXl5eX0gYW5kIHs4LHRpbWUsRUVFLCBNTU0gZGQgSEg6bW06c3M6UyBaWlogeXl5eX1cbn0NCisgICAgICogPHA+DQorICAgICAqIFRoaXMgcHJpbnRzIHRoZSBjb3VudCAoe0Bjb2RlIHszfX0pIGZvbGxvd2VkIGJ5IHRoZSBkYXRlIGFuZCB0aW1lIG9mIHRoZQ0KKyAgICAgKiBlbGRlc3QgbG9nIHJlY29yZCAoe0Bjb2RlIHs3fX0pIGFuZCB0aGUgZGF0ZSBhbmQgdGltZSBvZiB0aGUgbW9zdCByZWNlbnQNCisgICAgICogbG9nIHJlY29yZCAoe0Bjb2RlIHs4fX0pLg0KKyAgICAgKiA8cHJlPg0KKyAgICAgKiBUaGVzZSAyOTIgbWVzc2FnZXMgb2NjdXJyZWQgYmV0d2Vlbg0KKyAgICAgKiBUdWUsIEp1bCAyMSAxNDoxMTo0Mjo0NDkgLTA1MDAgMjAwOSBhbmQgRnJpLCBOb3YgMjAgMDc6Mjk6MjQ6MCAtMDYwMCAyMDA5DQorICAgICAqIDwvcHJlPg0KKyAgICAgKiA8bGk+e0Bjb2RlIGNvbS5zdW4ubWFpbC51dGlsLmxvZ2dpbmcuQ29sbGVjdG9yRm9ybWF0dGVyLmZvcm1hdD1UaGVzZSB7M30gbWVzc2FnZXMgb2NjdXJyZWQgYmV0d2VlbiB7OSxjaG9pY2UsODY0MDAwMDAjezcsZGF0ZX0gezcsdGltZX0gYW5kIHs4LHRpbWV9fDg2NDAwMDAwPHs3LGRhdGV9IGFuZCB7OCxkYXRlfX1cbn0NCisgICAgICogPHA+DQorICAgICAqIFRoaXMgcHJpbnRzIHRoZSBjb3VudCAoe0Bjb2RlIHszfX0pIGFuZCB0aGVuIGNob29zZXMgdGhlIGZvcm1hdCBiYXNlZCBvbg0KKyAgICAgKiB0aGUgZWxhcHNlZCB0aW1lICh7QGNvZGUgezl9fSkuIElmIHRoZSBlbGFwc2VkIHRpbWUgaXMgbGVzcyB0aGFuIG9uZSBkYXkNCisgICAgICogdGhlbiB0aGUgZWxkZXN0IGxvZyByZWNvcmQgKHtAY29kZSB7N319KSBkYXRlIGFuZCB0aW1lIGlzIGZvcm1hdHRlZA0KKyAgICAgKiBmb2xsb3dlZCBieSBqdXN0IHRoZSB0aW1lIG9mIHRoZSBtb3N0IHJlY2VudCBsb2cgcmVjb3JkICh7QGNvZGUgezh9fS4NCisgICAgICogT3RoZXJ3aXNlLCB0aGUganVzdCB0aGUgZGF0ZSBvZiB0aGUgZWxkZXN0IGxvZyByZWNvcmQgKHtAY29kZSB7N319KSBhbmQNCisgICAgICoganVzdCB0aGUgZGF0ZSBvZiBtb3N0IHJlY2VudCBsb2cgcmVjb3JkICh7QGNvZGUgezh9fSBpcyBmb3JtYXR0ZWQuDQorICAgICAqIDxwcmU+DQorICAgICAqIFRoZXNlIDczIG1lc3NhZ2VzIG9jY3VycmVkIGJldHdlZW4gSnVsIDIxLCAyMDA5IDI6MTE6NDIgUE0gYW5kIDI6MTM6MzIgUE0NCisgICAgICoNCisgICAgICogVGhlc2UgMTE2IG1lc3NhZ2VzIG9jY3VycmVkIGJldHdlZW4gSnVsIDIxLCAyMDA5IGFuZCBBdWcgMjAsIDIwMDkNCisgICAgICogPC9wcmU+DQorICAgICAqIDxsaT57QGNvZGUgY29tLnN1bi5tYWlsLnV0aWwubG9nZ2luZy5Db2xsZWN0b3JGb3JtYXR0ZXIuZm9ybWF0PXsxM30gYWxlcnQgcmVwb3J0cyBzaW5jZSB7MTAsZGF0ZX0uXG59DQorICAgICAqIDxwPg0KKyAgICAgKiBUaGlzIHByaW50cyB0aGUgZ2VuZXJhdGlvbiAoe0Bjb2RlIHsxM319KSBmb2xsb3dlZCBieSB0aGUgc3RhcnQgdGltZQ0KKyAgICAgKiAoe0Bjb2RlIHsxMH19KSBmb3JtYXR0ZWQgYXMgYSBkYXRlLg0KKyAgICAgKiA8cHJlPg0KKyAgICAgKiA0LDMyMCBhbGVydCByZXBvcnRzIHNpbmNlIEp1bCAyMSwgMjAxMi4NCisgICAgICogPC9wcmU+DQorICAgICAqIDwvdWw+DQorICAgICAqDQorICAgICAqIEBwYXJhbSBoIHRoZSBoYW5kbGVyIG9yIG51bGwuDQorICAgICAqIEByZXR1cm4gdGhlIG91dHB1dCBzdHJpbmcuDQorICAgICAqLw0KKyAgICBAT3ZlcnJpZGUNCisgICAgcHVibGljIFN0cmluZyBnZXRUYWlsKGZpbmFsIEhhbmRsZXIgaCkgew0KKyAgICAgICAgc3VwZXIuZ2V0VGFpbChoKTsgIC8vQmUgZm9yd2FyZCBjb21wYXRpYmxlIHdpdGggc3VwZXIuZ2V0SGVhZC4NCisgICAgICAgIHJldHVybiBmb3JtYXRSZWNvcmQoaCwgdHJ1ZSk7DQorICAgIH0NCisNCisgICAgLyoqDQorICAgICAqIEZvcm1hdHMgdGhlIGNvbGxlY3RlZCBMb2dSZWNvcmQgYW5kIHN1bW1hcnkgc3RhdGlzdGljcy4gVGhlIExvZ1JlY29yZCBhbmQNCisgICAgICogc3VtbWFyeSBzdGF0aXN0aWNzIGFyZSBub3QgY2hhbmdlZCBieSBjYWxsaW5nIHRoaXMgbWV0aG9kLg0KKyAgICAgKg0KKyAgICAgKiBAcmV0dXJuIHRoZSBjdXJyZW50IHJlY29yZCBmb3JtYXR0ZWQgb3IgdGhlIGRlZmF1bHQgdG9TdHJpbmcuDQorICAgICAqIEBzZWUgI2dldFRhaWwoamF2YS51dGlsLmxvZ2dpbmcuSGFuZGxlcikNCisgICAgICovDQorICAgIEBPdmVycmlkZQ0KKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgew0KKyAgICAgICAgU3RyaW5nIHJlc3VsdDsNCisgICAgICAgIHRyeSB7DQorICAgICAgICAgICAgcmVzdWx0ID0gZm9ybWF0UmVjb3JkKChIYW5kbGVyKSBudWxsLCBmYWxzZSk7DQorICAgICAgICB9IGNhdGNoIChmaW5hbCBSdW50aW1lRXhjZXB0aW9uIGlnbm9yZSkgew0KKyAgICAgICAgICAgIHJlc3VsdCA9IHN1cGVyLnRvU3RyaW5nKCk7DQorICAgICAgICB9DQorICAgICAgICByZXR1cm4gcmVzdWx0Ow0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBVc2VkIHRvIGNob29zZSB0aGUgY29sbGVjdGVkIExvZ1JlY29yZC4gVGhpcyBpbXBsZW1lbnRhdGlvbiByZXR1cm5zIHRoZQ0KKyAgICAgKiBncmVhdGVyIG9mIHR3byBMb2dSZWNvcmRzLg0KKyAgICAgKg0KKyAgICAgKiBAcGFyYW0gdCB0aGUgY3VycmVudCByZWNvcmQuDQorICAgICAqIEBwYXJhbSB1IHRoZSByZWNvcmQgdGhhdCBjb3VsZCByZXBsYWNlIHRoZSBjdXJyZW50Lg0KKyAgICAgKiBAcmV0dXJuIHRoZSBncmVhdGVyIG9mIHRoZSBnaXZlbiBsb2cgcmVjb3Jkcy4NCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBtYXkgb2NjdXIgaWYgZWl0aGVyIHJlY29yZCBpcyBudWxsLg0KKyAgICAgKi8NCisgICAgcHJvdGVjdGVkIExvZ1JlY29yZCBhcHBseShmaW5hbCBMb2dSZWNvcmQgdCwgZmluYWwgTG9nUmVjb3JkIHUpIHsNCisgICAgICAgIGlmICh0ID09IG51bGwgfHwgdSA9PSBudWxsKSB7DQorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7DQorICAgICAgICB9DQorDQorICAgICAgICBpZiAoY29tcGFyYXRvciAhPSBudWxsKSB7DQorICAgICAgICAgICAgcmV0dXJuIGNvbXBhcmF0b3IuY29tcGFyZSh0LCB1KSA+PSAwID8gdCA6IHU7DQorICAgICAgICB9IGVsc2Ugew0KKyAgICAgICAgICAgIHJldHVybiB1Ow0KKyAgICAgICAgfQ0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBVcGRhdGVzIHRoZSBzdW1tYXJ5IHN0YXRpc3RpY3Mgb25seSBpZiB0aGUgZXhwZWN0ZWQgcmVjb3JkIG1hdGNoZXMgdGhlDQorICAgICAqIGxhc3QgcmVjb3JkLiAgVGhlIHVwZGF0ZSByZWNvcmQgaXMgbm90IHN0b3JlZC4NCisgICAgICoNCisgICAgICogQHBhcmFtIGUgdGhlIExvZ1JlY29yZCB0aGF0IGlzIGV4cGVjdGVkLg0KKyAgICAgKiBAcGFyYW0gdSB0aGUgTG9nUmVjb3JkIHVzZWQgdG8gY29sbGVjdCBzdGF0aXN0aWNzLg0KKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGxhc3QgcmVjb3JkIHdhcyB0aGUgZXhwZWN0ZWQgcmVjb3JkLg0KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSB1cGRhdGUgcmVjb3JkIGlzIG51bGwuDQorICAgICAqLw0KKyAgICBwcml2YXRlIHN5bmNocm9uaXplZCBib29sZWFuIGFjY2VwdChmaW5hbCBMb2dSZWNvcmQgZSwgZmluYWwgTG9nUmVjb3JkIHUpIHsNCisgICAgICAgIC8qKg0KKyAgICAgICAgICogTG9nUmVjb3JkIG1ldGhvZHMgbXVzdCBiZSBjYWxsZWQgYmVmb3JlIHRoZSBjaGVjayBvZiB0aGUgbGFzdCBzdG9yZWQNCisgICAgICAgICAqIHJlY29yZCB0byBndWFyZCBhZ2FpbnN0IHN1YmNsYXNzZXMgb2YgTG9nUmVjb3JkIHRoYXQgbWlnaHQgYXR0ZW1wdCB0bw0KKyAgICAgICAgICogcmVzZXQgdGhlIHN0YXRlIGJ5IHRyaWdnZXJpbmcgYSBjYWxsIHRvIGdldFRhaWwuDQorICAgICAgICAgKi8NCisgICAgICAgIGZpbmFsIGxvbmcgbWlsbGlzID0gdS5nZXRNaWxsaXMoKTsgLy9OdWxsIGNoZWNrLg0KKyAgICAgICAgZmluYWwgVGhyb3dhYmxlIGV4ID0gdS5nZXRUaHJvd24oKTsNCisgICAgICAgIGlmIChsYXN0ID09IGUpIHsgIC8vT25seSBpZiB0aGUgZXhhY3Qgc2FtZSByZWZlcmVuY2UuDQorICAgICAgICAgICAgaWYgKCsrY291bnQgIT0gMUwpIHsNCisgICAgICAgICAgICAgICAgbWluTWlsbGlzID0gTWF0aC5taW4obWluTWlsbGlzLCBtaWxsaXMpOw0KKyAgICAgICAgICAgIH0gZWxzZSB7IC8vU2hvdyBzaW5nbGUgcmVjb3JkcyBhcyBpbnN0YW50IGFuZCBub3QgYSB0aW1lIHBlcmlvZC4NCisgICAgICAgICAgICAgICAgbWluTWlsbGlzID0gbWlsbGlzOw0KKyAgICAgICAgICAgIH0NCisgICAgICAgICAgICBtYXhNaWxsaXMgPSBNYXRoLm1heChtYXhNaWxsaXMsIG1pbGxpcyk7DQorDQorICAgICAgICAgICAgaWYgKGV4ICE9IG51bGwpIHsNCisgICAgICAgICAgICAgICAgKyt0aHJvd247DQorICAgICAgICAgICAgfQ0KKyAgICAgICAgICAgIHJldHVybiB0cnVlOw0KKyAgICAgICAgfSBlbHNlIHsNCisgICAgICAgICAgICByZXR1cm4gZmFsc2U7DQorICAgICAgICB9DQorICAgIH0NCisNCisgICAgLyoqDQorICAgICAqIFJlc2V0cyBhbGwgb2YgdGhlIGNvbGxlY3RlZCBzdW1tYXJ5IHN0YXRpc3RpY3MgaW5jbHVkaW5nIHRoZSBMb2dSZWNvcmQuDQorICAgICAqIEBwYXJhbSBtaW4gdGhlIGN1cnJlbnQgbWluIG1pbGxpc2Vjb25kcy4NCisgICAgICovDQorICAgIHByaXZhdGUgc3luY2hyb25pemVkIHZvaWQgcmVzZXQoZmluYWwgbG9uZyBtaW4pIHsNCisgICAgICAgIGlmIChsYXN0ICE9IG51bGwpIHsNCisgICAgICAgICAgICBsYXN0ID0gbnVsbDsNCisgICAgICAgICAgICArK2dlbmVyYXRpb247DQorICAgICAgICB9DQorDQorICAgICAgICBjb3VudCA9IDBMOw0KKyAgICAgICAgdGhyb3duID0gMEw7DQorICAgICAgICBtaW5NaWxsaXMgPSBtaW47DQorICAgICAgICBtYXhNaWxsaXMgPSBMb25nLk1JTl9WQUxVRTsNCisgICAgfQ0KKw0KKyAgICAvKioNCisgICAgICogRm9ybWF0cyB0aGUgZ2l2ZW4gcmVjb3JkIHdpdGggdGhlIGhlYWQgYW5kIHRhaWwuDQorICAgICAqDQorICAgICAqIEBwYXJhbSBoIHRoZSBIYW5kbGVyIG9yIG51bGwuDQorICAgICAqIEBwYXJhbSByZXNldCB0cnVlIGlmIHRoZSBzdW1tYXJ5IHN0YXRpc3RpY3MgYW5kIExvZ1JlY29yZCBzaG91bGQgYmUgcmVzZXQNCisgICAgICogYmFjayB0byBpbml0aWFsIHZhbHVlcy4NCisgICAgICogQHJldHVybiB0aGUgZm9ybWF0dGVkIHN0cmluZy4NCisgICAgICogQHNlZSAjZ2V0VGFpbChqYXZhLnV0aWwubG9nZ2luZy5IYW5kbGVyKQ0KKyAgICAgKi8NCisgICAgcHJpdmF0ZSBTdHJpbmcgZm9ybWF0UmVjb3JkKGZpbmFsIEhhbmRsZXIgaCwgZmluYWwgYm9vbGVhbiByZXNldCkgew0KKyAgICAgICAgZmluYWwgTG9nUmVjb3JkIHJlY29yZDsNCisgICAgICAgIGZpbmFsIGxvbmcgYzsNCisgICAgICAgIGZpbmFsIGxvbmcgdDsNCisgICAgICAgIGZpbmFsIGxvbmcgZzsNCisgICAgICAgIGxvbmcgbXNsOw0KKyAgICAgICAgbG9uZyBtc2g7DQorICAgICAgICBsb25nIG5vdzsNCisgICAgICAgIHN5bmNocm9uaXplZCAodGhpcykgew0KKyAgICAgICAgICAgIHJlY29yZCA9IGxhc3Q7DQorICAgICAgICAgICAgYyA9IGNvdW50Ow0KKyAgICAgICAgICAgIGcgPSBnZW5lcmF0aW9uOw0KKyAgICAgICAgICAgIHQgPSB0aHJvd247DQorICAgICAgICAgICAgbXNsID0gbWluTWlsbGlzOw0KKyAgICAgICAgICAgIG1zaCA9IG1heE1pbGxpczsNCisgICAgICAgICAgICBub3cgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsNCisgICAgICAgICAgICBpZiAoYyA9PSAwTCkgew0KKyAgICAgICAgICAgICAgICBtc2ggPSBub3c7DQorICAgICAgICAgICAgfQ0KKw0KKyAgICAgICAgICAgIGlmIChyZXNldCkgeyAvL0JVRyBJRCA2MzUxNjg1DQorICAgICAgICAgICAgICAgIHJlc2V0KG1zaCk7DQorICAgICAgICAgICAgfQ0KKyAgICAgICAgfQ0KKw0KKyAgICAgICAgZmluYWwgU3RyaW5nIGhlYWQ7DQorICAgICAgICBmaW5hbCBTdHJpbmcgbXNnOw0KKyAgICAgICAgZmluYWwgU3RyaW5nIHRhaWw7DQorICAgICAgICBmaW5hbCBGb3JtYXR0ZXIgZiA9IHRoaXMuZm9ybWF0dGVyOw0KKyAgICAgICAgaWYgKGYgIT0gbnVsbCkgew0KKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAoZikgew0KKyAgICAgICAgICAgICAgICBoZWFkID0gZi5nZXRIZWFkKGgpOw0KKyAgICAgICAgICAgICAgICBtc2cgPSByZWNvcmQgIT0gbnVsbCA/IGYuZm9ybWF0KHJlY29yZCkgOiAiIjsNCisgICAgICAgICAgICAgICAgdGFpbCA9IGYuZ2V0VGFpbChoKTsNCisgICAgICAgICAgICB9DQorICAgICAgICB9IGVsc2Ugew0KKyAgICAgICAgICAgIGhlYWQgPSAiIjsNCisgICAgICAgICAgICBtc2cgPSByZWNvcmQgIT0gbnVsbCA/IGZvcm1hdE1lc3NhZ2UocmVjb3JkKSA6ICIiOw0KKyAgICAgICAgICAgIHRhaWwgPSAiIjsNCisgICAgICAgIH0NCisNCisgICAgICAgIExvY2FsZSBsID0gbnVsbDsNCisgICAgICAgIGlmIChyZWNvcmQgIT0gbnVsbCkgew0KKyAgICAgICAgICAgIFJlc291cmNlQnVuZGxlIHJiID0gcmVjb3JkLmdldFJlc291cmNlQnVuZGxlKCk7DQorICAgICAgICAgICAgbCA9IHJiID09IG51bGwgPyBudWxsIDogcmIuZ2V0TG9jYWxlKCk7DQorICAgICAgICB9DQorDQorICAgICAgICBmaW5hbCBNZXNzYWdlRm9ybWF0IG1mOw0KKyAgICAgICAgaWYgKGwgPT0gbnVsbCkgeyAvL0JVRyBJRCA4MDM5MTY1DQorICAgICAgICAgICAgbWYgPSBuZXcgTWVzc2FnZUZvcm1hdChmbXQpOw0KKyAgICAgICAgfSBlbHNlIHsNCisgICAgICAgICAgICBtZiA9IG5ldyBNZXNzYWdlRm9ybWF0KGZtdCwgbCk7DQorICAgICAgICB9DQorDQorICAgICAgICAvKioNCisgICAgICAgICAqIFRoZXNlIGFyZ3VtZW50cyBhcmUgZGVzY3JpYmVkIGluIHRoZSBnZXRUYWlsIGRvY3VtZW50YXRpb24uDQorICAgICAgICAgKi8NCisgICAgICAgIHJldHVybiBtZi5mb3JtYXQobmV3IE9iamVjdFtde2ZpbmlzaChoZWFkKSwgZmluaXNoKG1zZyksIGZpbmlzaCh0YWlsKSwNCisgICAgICAgICAgICBjLCAoYyAtIDFMKSwgdCwgKGMgLSB0KSwgbXNsLCBtc2gsIChtc2ggLSBtc2wpLCBJTklUX1RJTUUsIG5vdywNCisgICAgICAgICAgICAobm93IC0gSU5JVF9USU1FKSwgZ30pOw0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBBcHBsaWVkIHRvIHRoZSBoZWFkLCBmb3JtYXQsIGFuZCB0YWlsIHJldHVybmVkIGJ5IHRoZSB0YXJnZXQgZm9ybWF0dGVyLg0KKyAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIHRyaW1zIGFsbCBpbnB1dCBzdHJpbmdzLg0KKyAgICAgKg0KKyAgICAgKiBAcGFyYW0gcyB0aGUgc3RyaW5nIHRvIHRyYW5zZm9ybS4NCisgICAgICogQHJldHVybiB0aGUgdHJhbnNmb3JtZWQgc3RyaW5nLg0KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBnaXZlbiBzdHJpbmcgaXMgbnVsbC4NCisgICAgICovDQorICAgIHByb3RlY3RlZCBTdHJpbmcgZmluaXNoKFN0cmluZyBzKSB7DQorICAgICAgICByZXR1cm4gcy50cmltKCk7DQorICAgIH0NCisNCisgICAgLyoqDQorICAgICAqIFBlZWsgYXQgdGhlIGN1cnJlbnQgbG9nIHJlY29yZC4NCisgICAgICoNCisgICAgICogQHJldHVybiBudWxsIG9yIHRoZSBjdXJyZW50IGxvZyByZWNvcmQuDQorICAgICAqLw0KKyAgICBwcml2YXRlIHN5bmNocm9uaXplZCBMb2dSZWNvcmQgcGVlaygpIHsNCisgICAgICAgIHJldHVybiB0aGlzLmxhc3Q7DQorICAgIH0NCisNCisgICAgLyoqDQorICAgICAqIFVwZGF0ZXMgdGhlIHN1bW1hcnkgc3RhdGlzdGljcyBhbmQgc3RvcmVzIGdpdmVuIExvZ1JlY29yZCBpZiB0aGUgZXhwZWN0ZWQNCisgICAgICogcmVjb3JkIG1hdGNoZXMgdGhlIGN1cnJlbnQgcmVjb3JkLg0KKyAgICAgKg0KKyAgICAgKiBAcGFyYW0gZSB0aGUgZXhwZWN0ZWQgcmVjb3JkLg0KKyAgICAgKiBAcGFyYW0gdSB0aGUgdXBkYXRlIHJlY29yZC4NCisgICAgICogQHJldHVybiB0cnVlIGlmIHRoZSB1cGRhdGUgd2FzIHBlcmZvcm1lZC4NCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgdXBkYXRlIHJlY29yZCBpcyBudWxsLg0KKyAgICAgKi8NCisgICAgcHJpdmF0ZSBzeW5jaHJvbml6ZWQgYm9vbGVhbiBhY2NlcHRBbmRVcGRhdGUoTG9nUmVjb3JkIGUsIExvZ1JlY29yZCB1KSB7DQorICAgICAgICBpZiAoYWNjZXB0KGUsIHUpKSB7DQorICAgICAgICAgICAgdGhpcy5sYXN0ID0gdTsNCisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsNCisgICAgICAgIH0gZWxzZSB7DQorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOw0KKyAgICAgICAgfQ0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBHZXRzIHRoZSBtZXNzYWdlIGZvcm1hdCBzdHJpbmcgZnJvbSB0aGUgTG9nTWFuYWdlciBvciBjcmVhdGVzIHRoZSBkZWZhdWx0DQorICAgICAqIG1lc3NhZ2UgZm9ybWF0IHN0cmluZy4NCisgICAgICoNCisgICAgICogQHBhcmFtIHAgdGhlIGNsYXNzIG5hbWUgcHJlZml4Lg0KKyAgICAgKiBAcmV0dXJuIHRoZSBmb3JtYXQgc3RyaW5nLg0KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBnaXZlbiBhcmd1bWVudCBpcyBudWxsLg0KKyAgICAgKi8NCisgICAgcHJpdmF0ZSBTdHJpbmcgaW5pdEZvcm1hdChmaW5hbCBTdHJpbmcgcCkgew0KKyAgICAgICAgU3RyaW5nIHYgPSBmcm9tTG9nTWFuYWdlcihwLmNvbmNhdCgiLmZvcm1hdCIpKTsNCisgICAgICAgIGlmICh2ID09IG51bGwgfHwgdi5sZW5ndGgoKSA9PSAwKSB7DQorICAgICAgICAgICAgdiA9ICJ7MH17MX17Mn17NCxjaG9pY2UsLTEjfDAjfDA8Li4uIHs0LG51bWJlcixpbnRlZ2VyfSBtb3JlfVxuIjsNCisgICAgICAgIH0NCisgICAgICAgIHJldHVybiB2Ow0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBHZXRzIGFuZCBjcmVhdGVzIHRoZSBmb3JtYXR0ZXIgZnJvbSB0aGUgTG9nTWFuYWdlciBvciBjcmVhdGVzIHRoZSBkZWZhdWx0DQorICAgICAqIGZvcm1hdHRlci4NCisgICAgICoNCisgICAgICogQHBhcmFtIHAgdGhlIGNsYXNzIG5hbWUgcHJlZml4Lg0KKyAgICAgKiBAcmV0dXJuIHRoZSBmb3JtYXR0ZXIuDQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIGdpdmVuIGFyZ3VtZW50IGlzIG51bGwuDQorICAgICAqIEB0aHJvd3MgVW5kZWNsYXJlZFRocm93YWJsZUV4Y2VwdGlvbiBpZiB0aGUgZm9ybWF0dGVyIGNhbiBub3QgYmUgY3JlYXRlZC4NCisgICAgICovDQorICAgIHByaXZhdGUgRm9ybWF0dGVyIGluaXRGb3JtYXR0ZXIoZmluYWwgU3RyaW5nIHApIHsNCisgICAgICAgIEZvcm1hdHRlciBmOw0KKyAgICAgICAgU3RyaW5nIHYgPSBmcm9tTG9nTWFuYWdlcihwLmNvbmNhdCgiLmZvcm1hdHRlciIpKTsNCisgICAgICAgIGlmICh2ICE9IG51bGwgJiYgdi5sZW5ndGgoKSAhPSAwKSB7DQorICAgICAgICAgICAgaWYgKCEibnVsbCIuZXF1YWxzSWdub3JlQ2FzZSh2KSkgew0KKyAgICAgICAgICAgICAgICB0cnkgew0KKyAgICAgICAgICAgICAgICAgICAgZiA9IExvZ01hbmFnZXJQcm9wZXJ0aWVzLm5ld0Zvcm1hdHRlcih2KTsNCisgICAgICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgUnVudGltZUV4Y2VwdGlvbiByZSkgew0KKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgcmU7DQorICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGZpbmFsIEV4Y2VwdGlvbiBlKSB7DQorICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVW5kZWNsYXJlZFRocm93YWJsZUV4Y2VwdGlvbihlKTsNCisgICAgICAgICAgICAgICAgfQ0KKyAgICAgICAgICAgIH0gZWxzZSB7DQorICAgICAgICAgICAgICAgIGYgPSBudWxsOw0KKyAgICAgICAgICAgIH0NCisgICAgICAgIH0gZWxzZSB7DQorICAgICAgICAgICAgLy9Eb24ndCBmb3JjZSB0aGUgYnl0ZSBjb2RlIHZlcmlmaWVyIHRvIGxvYWQgdGhlIGZvcm1hdHRlci4NCisgICAgICAgICAgICBmID0gRm9ybWF0dGVyLmNsYXNzLmNhc3QobmV3IENvbXBhY3RGb3JtYXR0ZXIoKSk7DQorICAgICAgICB9DQorICAgICAgICByZXR1cm4gZjsNCisgICAgfQ0KKw0KKyAgICAvKioNCisgICAgICogR2V0cyBhbmQgY3JlYXRlcyB0aGUgY29tcGFyYXRvciBmcm9tIHRoZSBMb2dNYW5hZ2VyIG9yIHJldHVybnMgdGhlDQorICAgICAqIGRlZmF1bHQgY29tcGFyYXRvci4NCisgICAgICoNCisgICAgICogQHBhcmFtIHAgdGhlIGNsYXNzIG5hbWUgcHJlZml4Lg0KKyAgICAgKiBAcmV0dXJuIHRoZSBjb21wYXJhdG9yIG9yIG51bGwuDQorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIGl0IHdhcyBzcGVjaWZpZWQgdGhhdCB0aGUgY29tcGFyYXRvcg0KKyAgICAgKiBzaG91bGQgYmUgcmV2ZXJzZWQgYnV0IG5vIGluaXRpYWwgY29tcGFyYXRvciB3YXMgc3BlY2lmaWVkLg0KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBnaXZlbiBhcmd1bWVudCBpcyBudWxsLg0KKyAgICAgKiBAdGhyb3dzIFVuZGVjbGFyZWRUaHJvd2FibGVFeGNlcHRpb24gaWYgdGhlIGNvbXBhcmF0b3IgY2FuIG5vdCBiZQ0KKyAgICAgKiBjcmVhdGVkLg0KKyAgICAgKi8NCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpDQorICAgIHByaXZhdGUgQ29tcGFyYXRvcjw/IHN1cGVyIExvZ1JlY29yZD4gaW5pdENvbXBhcmF0b3IoZmluYWwgU3RyaW5nIHApIHsNCisgICAgICAgIENvbXBhcmF0b3I8PyBzdXBlciBMb2dSZWNvcmQ+IGM7DQorICAgICAgICBmaW5hbCBTdHJpbmcgbmFtZSA9IGZyb21Mb2dNYW5hZ2VyKHAuY29uY2F0KCIuY29tcGFyYXRvciIpKTsNCisgICAgICAgIGZpbmFsIFN0cmluZyByZXZlcnNlID0gZnJvbUxvZ01hbmFnZXIocC5jb25jYXQoIi5jb21wYXJhdG9yLnJldmVyc2UiKSk7DQorICAgICAgICB0cnkgew0KKyAgICAgICAgICAgIGlmIChuYW1lICE9IG51bGwgJiYgbmFtZS5sZW5ndGgoKSAhPSAwKSB7DQorICAgICAgICAgICAgICAgIGlmICghIm51bGwiLmVxdWFsc0lnbm9yZUNhc2UobmFtZSkpIHsNCisgICAgICAgICAgICAgICAgICAgIGMgPSBMb2dNYW5hZ2VyUHJvcGVydGllcy5uZXdDb21wYXJhdG9yKG5hbWUpOw0KKyAgICAgICAgICAgICAgICAgICAgaWYgKEJvb2xlYW4ucGFyc2VCb29sZWFuKHJldmVyc2UpKSB7DQorICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0IGMgIT0gbnVsbDsNCisgICAgICAgICAgICAgICAgICAgICAgICBjID0gTG9nTWFuYWdlclByb3BlcnRpZXMucmV2ZXJzZU9yZGVyKGMpOw0KKyAgICAgICAgICAgICAgICAgICAgfQ0KKyAgICAgICAgICAgICAgICB9IGVsc2Ugew0KKyAgICAgICAgICAgICAgICAgICAgaWYgKHJldmVyc2UgIT0gbnVsbCkgew0KKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oDQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTm8gY29tcGFyYXRvciB0byByZXZlcnNlLiIpOw0KKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsNCisgICAgICAgICAgICAgICAgICAgICAgICBjID0gbnVsbDsgLy9ObyBvcmRlcmluZy4NCisgICAgICAgICAgICAgICAgICAgIH0NCisgICAgICAgICAgICAgICAgfQ0KKyAgICAgICAgICAgIH0gZWxzZSB7DQorICAgICAgICAgICAgICAgIGlmIChyZXZlcnNlICE9IG51bGwpIHsNCisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oDQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJObyBjb21wYXJhdG9yIHRvIHJldmVyc2UuIik7DQorICAgICAgICAgICAgICAgIH0gZWxzZSB7DQorICAgICAgICAgICAgICAgICAgICAvL0Rvbid0IGZvcmNlIHRoZSBieXRlIGNvZGUgdmVyaWZpZXIgdG8gbG9hZCB0aGUgY29tcGFyYXRvci4NCisgICAgICAgICAgICAgICAgICAgIGMgPSBDb21wYXJhdG9yLmNsYXNzLmNhc3QoU2V2ZXJpdHlDb21wYXJhdG9yLmdldEluc3RhbmNlKCkpOw0KKyAgICAgICAgICAgICAgICB9DQorICAgICAgICAgICAgfQ0KKyAgICAgICAgfSBjYXRjaCAoZmluYWwgUnVudGltZUV4Y2VwdGlvbiByZSkgew0KKyAgICAgICAgICAgIHRocm93IHJlOyAvL0F2b2lkIGNhdGNoIGFsbC4NCisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIEV4Y2VwdGlvbiBlKSB7DQorICAgICAgICAgICAgdGhyb3cgbmV3IFVuZGVjbGFyZWRUaHJvd2FibGVFeGNlcHRpb24oZSk7DQorICAgICAgICB9DQorICAgICAgICByZXR1cm4gYzsNCisgICAgfQ0KK30NCmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvbG9nZ2luZy9Db21wYWN0Rm9ybWF0dGVyLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvbG9nZ2luZy9Db21wYWN0Rm9ybWF0dGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjM1OWYxOAotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvdXRpbC9sb2dnaW5nL0NvbXBhY3RGb3JtYXR0ZXIuamF2YQpAQCAtMCwwICsxLDg2NSBAQAorLyoNCisgKiBDb3B5cmlnaHQgKGMpIDIwMTMsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCisgKiBDb3B5cmlnaHQgKGMpIDIwMTMsIDIwMTggSmFzb24gTWVocmVucy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCisgKg0KKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQ0KKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0DQorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLg0KKyAqDQorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQ0KKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUNCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwNCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdA0KKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4NCisgKg0KKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMA0KKyAqLw0KK3BhY2thZ2UgY29tLnN1bi5tYWlsLnV0aWwubG9nZ2luZzsNCisNCitpbXBvcnQgamF2YS51dGlsLio7DQoraW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkxvZ1JlY29yZDsNCisNCisvKioNCisgKiBBIHBsYWluIHRleHQgZm9ybWF0dGVyIHRoYXQgY2FuIHByb2R1Y2UgZml4ZWQgd2lkdGggb3V0cHV0LiBCeSBkZWZhdWx0IHRoaXMNCisgKiBmb3JtYXR0ZXIgd2lsbCBwcm9kdWNlIG91dHB1dCBubyBncmVhdGVyIHRoYW4gMTYwIGNoYXJhY3RlcnMgd2lkZSBwbHVzIHRoZQ0KKyAqIHNlcGFyYXRvciBhbmQgbmV3bGluZSBjaGFyYWN0ZXJzLiBPbmx5IHNwZWNpZmllZCBmaWVsZHMgc3VwcG9ydCBhbg0KKyAqIHtAbGlua3BsYWluICN0b0FsdGVybmF0ZShqYXZhLmxhbmcuU3RyaW5nKSBhbHRlcm5hdGV9IGZpeGVkIHdpZHRoIGZvcm1hdC4NCisgKiA8cD4NCisgKiBCeSBkZWZhdWx0IGVhY2ggPHR0PkNvbXBhY3RGb3JtYXR0ZXI8L3R0PiBpcyBpbml0aWFsaXplZCB1c2luZyB0aGUgZm9sbG93aW5nDQorICogTG9nTWFuYWdlciBjb25maWd1cmF0aW9uIHByb3BlcnRpZXMgd2hlcmUNCisgKiA8dHQ+Jmx0O2Zvcm1hdHRlci1uYW1lJmd0OzwvdHQ+IHJlZmVycyB0byB0aGUgZnVsbHkgcXVhbGlmaWVkIGNsYXNzIG5hbWUgb3INCisgKiB0aGUgZnVsbHkgcXVhbGlmaWVkIGRlcml2ZWQgY2xhc3MgbmFtZSBvZiB0aGUgZm9ybWF0dGVyLiBJZiBwcm9wZXJ0aWVzIGFyZQ0KKyAqIG5vdCBkZWZpbmVkLCBvciBjb250YWluIGludmFsaWQgdmFsdWVzLCB0aGVuIHRoZSBzcGVjaWZpZWQgZGVmYXVsdCB2YWx1ZXMgYXJlDQorICogdXNlZC4NCisgKiA8dWw+DQorICogPGxpPiZsdDtmb3JtYXR0ZXItbmFtZSZndDsuZm9ybWF0IC0gdGhlIHtAbGlua3BsYWluIGphdmEudXRpbC5Gb3JtYXR0ZXINCisgKiAgICAgZm9ybWF0fSBzdHJpbmcgdXNlZCB0byB0cmFuc2Zvcm0gdGhlIG91dHB1dC4gVGhlIGZvcm1hdCBzdHJpbmcgY2FuIGJlDQorICogdXNlZCB0byBmaXggdGhlIG91dHB1dCBzaXplLiAoZGVmYXVsdHMgdG8gPHR0PiU3JCMuMTYwcyVuPC90dD4pPC9saT4NCisgKiA8L3VsPg0KKyAqDQorICogQGF1dGhvciBKYXNvbiBNZWhyZW5zDQorICogQHNpbmNlIEphdmFNYWlsIDEuNS4yDQorICovDQorcHVibGljIGNsYXNzIENvbXBhY3RGb3JtYXR0ZXIgZXh0ZW5kcyBqYXZhLnV0aWwubG9nZ2luZy5Gb3JtYXR0ZXIgew0KKw0KKyAgICAvKioNCisgICAgICogTG9hZCBhbnkgZGVjbGFyZWQgY2xhc3NlcyB0byB3b3JrYXJvdW5kIEdMQVNTRklTSC0yMTI1OC4NCisgICAgICovDQorICAgIHN0YXRpYyB7DQorICAgICAgICBsb2FkRGVjbGFyZWRDbGFzc2VzKCk7DQorICAgIH0NCisNCisgICAgLyoqDQorICAgICAqIFVzZWQgdG8gbG9hZCBkZWNsYXJlZCBjbGFzc2VzIGVuY2FzZSBjbGFzcyBsb2FkZXIgZG9lc24ndCBhbGxvdyBsb2FkaW5nDQorICAgICAqIGR1cmluZyBKVk0gdGVybWluYXRpb24uIFRoaXMgbWV0aG9kIGlzIHVzZWQgd2l0aCB1bml0IHRlc3RpbmcuDQorICAgICAqDQorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgb2YgY2xhc3NlcyBuZXZlciBudWxsLg0KKyAgICAgKi8NCisgICAgcHJpdmF0ZSBzdGF0aWMgQ2xhc3M8Pz5bXSBsb2FkRGVjbGFyZWRDbGFzc2VzKCkgew0KKyAgICAgICAgcmV0dXJuIG5ldyBDbGFzczw/Pltde0FsdGVybmF0ZS5jbGFzc307DQorICAgIH0NCisNCisgICAgLyoqDQorICAgICAqIEhvbGRzIHRoZSBqYXZhLnV0aWwuRm9ybWF0dGVyIHBhdHRlcm4uDQorICAgICAqLw0KKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBmbXQ7DQorDQorICAgIC8qKg0KKyAgICAgKiBDcmVhdGVzIGFuIGluc3RhbmNlIHdpdGggYSBkZWZhdWx0IGZvcm1hdCBwYXR0ZXJuLg0KKyAgICAgKi8NCisgICAgcHVibGljIENvbXBhY3RGb3JtYXR0ZXIoKSB7DQorICAgICAgICBTdHJpbmcgcCA9IGdldENsYXNzKCkuZ2V0TmFtZSgpOw0KKyAgICAgICAgdGhpcy5mbXQgPSBpbml0Rm9ybWF0KHApOw0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBDcmVhdGVzIGFuIGluc3RhbmNlIHdpdGggdGhlIGdpdmVuIGZvcm1hdCBwYXR0ZXJuLg0KKyAgICAgKg0KKyAgICAgKiBAcGFyYW0gZm9ybWF0IHRoZSB7QGxpbmtwbGFpbiBqYXZhLnV0aWwuRm9ybWF0dGVyIHBhdHRlcm59IG9yIG51bGwgdG8gdXNlDQorICAgICAqIHRoZSBMb2dNYW5hZ2VyIGRlZmF1bHQuIFRoZSBhcmd1bWVudHMgYXJlIGRlc2NyaWJlZCBpbiB0aGUNCisgICAgICoge0BsaW5rcGxhaW4gI2Zvcm1hdChqYXZhLnV0aWwubG9nZ2luZy5Mb2dSZWNvcmQpIGZvcm1hdH0gbWV0aG9kLg0KKyAgICAgKi8NCisgICAgcHVibGljIENvbXBhY3RGb3JtYXR0ZXIoZmluYWwgU3RyaW5nIGZvcm1hdCkgew0KKyAgICAgICAgU3RyaW5nIHAgPSBnZXRDbGFzcygpLmdldE5hbWUoKTsNCisgICAgICAgIHRoaXMuZm10ID0gZm9ybWF0ID09IG51bGwgPyBpbml0Rm9ybWF0KHApIDogZm9ybWF0Ow0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBGb3JtYXQgdGhlIGdpdmVuIGxvZyByZWNvcmQgYW5kIHJldHVybnMgdGhlIGZvcm1hdHRlZCBzdHJpbmcuIFRoZQ0KKyAgICAgKiB7QGxpbmtwbGFpbiBqYXZhLnV0aWwuRm9ybWF0dGVyI2Zvcm1hdChqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuT2JqZWN0Li4uKQ0KKyAgICAgKiBqYXZhLnV0aWx9IGFyZ3VtZW50IGluZGV4ZXMgYXJlIGFzc2lnbmVkIHRvIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllczoNCisgICAgICoNCisgICAgICogPG9sIHN0YXJ0PScwJz4NCisgICAgICogPGxpPntAY29kZSBmb3JtYXR9IC0gdGhlIHtAbGlua3BsYWluIGphdmEudXRpbC5Gb3JtYXR0ZXINCisgICAgICogICAgIGphdmEudXRpbC5Gb3JtYXR0ZXJ9IGZvcm1hdCBzdHJpbmcgc3BlY2lmaWVkIGluIHRoZQ0KKyAgICAgKiAmbHQ7Zm9ybWF0dGVyLW5hbWUmZ3Q7LmZvcm1hdCBwcm9wZXJ0eSBvciB0aGUgZm9ybWF0IHRoYXQgd2FzIGdpdmVuIHdoZW4NCisgICAgICogdGhpcyBmb3JtYXR0ZXIgd2FzIGNyZWF0ZWQuPC9saT4NCisgICAgICogPGxpPntAY29kZSBkYXRlfSAtIGlmIHRoZSBsb2cgcmVjb3JkIHN1cHBvcnRzIG5hbm9zZWNvbmRzIHRoZW4gYQ0KKyAgICAgKiBab25lZERhdGVUaW1lIG9iamVjdCByZXByZXNlbnRpbmcgdGhlIGV2ZW50IHRpbWUgb2YgdGhlIGxvZyByZWNvcmQgaW4gdGhlDQorICAgICAqIHN5c3RlbSB0aW1lIHpvbmUuIE90aGVyd2lzZSwgYSB7QGxpbmtwbGFpbiBEYXRlfSBvYmplY3QgcmVwcmVzZW50aW5nDQorICAgICAqIHtAbGlua3BsYWluIExvZ1JlY29yZCNnZXRNaWxsaXMgZXZlbnQgdGltZX0gb2YgdGhlIGxvZyByZWNvcmQuPC9saT4NCisgICAgICogPGxpPntAY29kZSBzb3VyY2V9IC0gYSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBjYWxsZXIsIGlmIGF2YWlsYWJsZTsNCisgICAgICogb3RoZXJ3aXNlLCB0aGUgbG9nZ2VyJ3MgbmFtZS48L2xpPg0KKyAgICAgKiA8bGk+e0Bjb2RlIGxvZ2dlcn0gLSB0aGUgbG9nZ2VyJ3MNCisgICAgICoge0BsaW5rcGxhaW4gQ2xhc3MjZ2V0U2ltcGxlTmFtZSgpIHNpbXBsZX0NCisgICAgICoge0BsaW5rcGxhaW4gTG9nUmVjb3JkI2dldExvZ2dlck5hbWUoKSBuYW1lfS48L2xpPg0KKyAgICAgKiA8bGk+e0Bjb2RlIGxldmVsfSAtIHRoZQ0KKyAgICAgKiB7QGxpbmtwbGFpbiBqYXZhLnV0aWwubG9nZ2luZy5MZXZlbCNnZXRMb2NhbGl6ZWROYW1lIGxvZyBsZXZlbH0uPC9saT4NCisgICAgICogPGxpPntAY29kZSBtZXNzYWdlfSAtIHRoZSBmb3JtYXR0ZWQgbG9nIG1lc3NhZ2UgcmV0dXJuZWQgZnJvbSB0aGUNCisgICAgICoge0BsaW5rcGxhaW4gI2Zvcm1hdE1lc3NhZ2UoTG9nUmVjb3JkKX0gbWV0aG9kLjwvbGk+DQorICAgICAqIDxsaT57QGNvZGUgdGhyb3dufSAtIGEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUNCisgICAgICoge0BsaW5rcGxhaW4gTG9nUmVjb3JkI2dldFRocm93biB0aHJvd2FibGV9IGFzc29jaWF0ZWQgd2l0aCB0aGUgbG9nIHJlY29yZA0KKyAgICAgKiBhbmQgYSByZWxldmFudCBzdGFjayB0cmFjZSBlbGVtZW50IGlmIGF2YWlsYWJsZTsgb3RoZXJ3aXNlLCBhbiBlbXB0eQ0KKyAgICAgKiBzdHJpbmcgaXMgdXNlZC48L2xpPg0KKyAgICAgKiA8bGk+e0Bjb2RlIG1lc3NhZ2V8dGhyb3dufSBUaGUgbWVzc2FnZSBhbmQgdGhlIHRocm93biBwcm9wZXJ0aWVzIGpvaW5lZA0KKyAgICAgKiBhcyBvbmUgcGFyYW1ldGVyLiBUaGlzIHBhcmFtZXRlciBzdXBwb3J0cw0KKyAgICAgKiB7QGxpbmtwbGFpbiAjdG9BbHRlcm5hdGUoamF2YS5sYW5nLlN0cmluZykgYWx0ZXJuYXRlfSBmb3JtLjwvbGk+DQorICAgICAqIDxsaT57QGNvZGUgdGhyb3dufG1lc3NhZ2V9IFRoZSB0aHJvd24gYW5kIG1lc3NhZ2UgcHJvcGVydGllcyBqb2luZWQgYXMNCisgICAgICogb25lIHBhcmFtZXRlci4gVGhpcyBwYXJhbWV0ZXIgc3VwcG9ydHMNCisgICAgICoge0BsaW5rcGxhaW4gI3RvQWx0ZXJuYXRlKGphdmEubGFuZy5TdHJpbmcpIGFsdGVybmF0ZX0gZm9ybS48L2xpPg0KKyAgICAgKiA8bGk+e0Bjb2RlIHNlcXVlbmNlfSB0aGUNCisgICAgICoge0BsaW5rcGxhaW4gTG9nUmVjb3JkI2dldFNlcXVlbmNlTnVtYmVyKCkgc2VxdWVuY2UgbnVtYmVyfSBpZiB0aGUgZ2l2ZW4NCisgICAgICogbG9nIHJlY29yZC48L2xpPg0KKyAgICAgKiA8bGk+e0Bjb2RlIHRocmVhZCBpZH0gdGhlIHtAbGlua3BsYWluIExvZ1JlY29yZCNnZXRUaHJlYWRJRCgpIHRocmVhZCBpZH0NCisgICAgICogb2YgdGhlIGdpdmVuIGxvZyByZWNvcmQuIEJ5IGRlZmF1bHQgdGhpcyBpcyBmb3JtYXR0ZWQgYXMgYSB7QGNvZGUgbG9uZ30NCisgICAgICogYnkgYW4gdW5zaWduZWQgY29udmVyc2lvbi48L2xpPg0KKyAgICAgKiA8bGk+e0Bjb2RlIGVycm9yfSB0aGUgdGhyb3dhYmxlDQorICAgICAqIHtAbGlua3BsYWluIENsYXNzI2dldFNpbXBsZU5hbWUoKSBzaW1wbGUgY2xhc3MgbmFtZX0gYW5kDQorICAgICAqIHtAbGlua3BsYWluICNmb3JtYXRFcnJvcihMb2dSZWNvcmQpIGVycm9yIG1lc3NhZ2V9IHdpdGhvdXQgYW55IHN0YWNrDQorICAgICAqIHRyYWNlLjwvbGk+DQorICAgICAqIDxsaT57QGNvZGUgbWVzc2FnZXxlcnJvcn0gVGhlIG1lc3NhZ2UgYW5kIGVycm9yIHByb3BlcnRpZXMgam9pbmVkIGFzIG9uZQ0KKyAgICAgKiBwYXJhbWV0ZXIuIFRoaXMgcGFyYW1ldGVyIHN1cHBvcnRzDQorICAgICAqIHtAbGlua3BsYWluICN0b0FsdGVybmF0ZShqYXZhLmxhbmcuU3RyaW5nKSBhbHRlcm5hdGV9IGZvcm0uPC9saT4NCisgICAgICogPGxpPntAY29kZSBlcnJvcnxtZXNzYWdlfSBUaGUgZXJyb3IgYW5kIG1lc3NhZ2UgcHJvcGVydGllcyBqb2luZWQgYXMgb25lDQorICAgICAqIHBhcmFtZXRlci4gVGhpcyBwYXJhbWV0ZXIgc3VwcG9ydHMNCisgICAgICoge0BsaW5rcGxhaW4gI3RvQWx0ZXJuYXRlKGphdmEubGFuZy5TdHJpbmcpIGFsdGVybmF0ZX0gZm9ybS48L2xpPg0KKyAgICAgKiA8bGk+e0Bjb2RlIGJhY2t0cmFjZX0gb25seSB0aGUNCisgICAgICoge0BsaW5rcGxhaW4gI2Zvcm1hdEJhY2tUcmFjZShMb2dSZWNvcmQpIHN0YWNrIHRyYWNlfSBvZiB0aGUgZ2l2ZW4NCisgICAgICogdGhyb3dhYmxlLjwvbGk+DQorICAgICAqIDxsaT57QGNvZGUgYnVuZGxlbmFtZX0gdGhlIHJlc291cmNlIGJ1bmRsZQ0KKyAgICAgKiB7QGxpbmtwbGFpbiBMb2dSZWNvcmQjZ2V0UmVzb3VyY2VCdW5kbGVOYW1lKCkgbmFtZX0gb2YgdGhlIGdpdmVuIGxvZw0KKyAgICAgKiByZWNvcmQuPC9saT4NCisgICAgICogPGxpPntAY29kZSBrZXl9IHRoZSB7QGxpbmtwbGFpbiBMb2dSZWNvcmQjZ2V0TWVzc2FnZSgpIHJhdyBtZXNzYWdlfQ0KKyAgICAgKiBiZWZvcmUgbG9jYWxpemF0aW9uIG9yIGZvcm1hdHRpbmcuPC9saT4NCisgICAgICogPC9vbD4NCisgICAgICoNCisgICAgICogPHA+DQorICAgICAqIFNvbWUgZXhhbXBsZSBmb3JtYXRzOjxicj4NCisgICAgICogPHVsPg0KKyAgICAgKiA8bGk+e0Bjb2RlIGNvbS5zdW4ubWFpbC51dGlsLmxvZ2dpbmcuQ29tcGFjdEZvcm1hdHRlci5mb3JtYXQ9JTckIy4xNjBzJW59DQorICAgICAqIDxwPg0KKyAgICAgKiBUaGlzIHByaW50cyBvbmx5IDE2MCBjaGFyYWN0ZXJzIG9mIHRoZSBtZXNzYWdlfHRocm93biAoe0Bjb2RlIDckfSkgdXNpbmcNCisgICAgICogdGhlIHtAbGlua3BsYWluICN0b0FsdGVybmF0ZShqYXZhLmxhbmcuU3RyaW5nKSBhbHRlcm5hdGV9IGZvcm0uIFRoZQ0KKyAgICAgKiBzZXBhcmF0b3IgaXMgbm90IGluY2x1ZGVkIGFzIHBhcnQgb2YgdGhlIHRvdGFsIHdpZHRoLg0KKyAgICAgKiA8cHJlPg0KKyAgICAgKiBFbmNvZGluZyBmYWlsZWQufE51bGxQb2ludGVyRXhjZXB0aW9uOiBudWxsIFN0cmluZy5nZXRCeXRlcyg6OTEzKQ0KKyAgICAgKiA8L3ByZT4NCisgICAgICoNCisgICAgICogPGxpPntAY29kZSBjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nLkNvbXBhY3RGb3JtYXR0ZXIuZm9ybWF0PSU3JCMuMjBzJW59DQorICAgICAqIDxwPg0KKyAgICAgKiBUaGlzIHByaW50cyBvbmx5IDIwIGNoYXJhY3RlcnMgb2YgdGhlIG1lc3NhZ2V8dGhyb3duICh7QGNvZGUgNyR9KSB1c2luZw0KKyAgICAgKiB0aGUge0BsaW5rcGxhaW4gI3RvQWx0ZXJuYXRlKGphdmEubGFuZy5TdHJpbmcpIGFsdGVybmF0ZX0gZm9ybS4gVGhpcyB3aWxsDQorICAgICAqIHBlcmZvcm0gYSB3ZWlnaHRlZCB0cnVuY2F0aW9uIG9mIGJvdGggdGhlIG1lc3NhZ2UgYW5kIHRocm93biBwcm9wZXJ0aWVzDQorICAgICAqIG9mIHRoZSBsb2cgcmVjb3JkLiBUaGUgc2VwYXJhdG9yIGlzIG5vdCBpbmNsdWRlZCBhcyBwYXJ0IG9mIHRoZSB0b3RhbA0KKyAgICAgKiB3aWR0aC4NCisgICAgICogPHByZT4NCisgICAgICogRW5jb2Rpbmd8TnVsbFBvaW50ZXJFDQorICAgICAqIDwvcHJlPg0KKyAgICAgKg0KKyAgICAgKiA8bGk+e0Bjb2RlIGNvbS5zdW4ubWFpbC51dGlsLmxvZ2dpbmcuQ29tcGFjdEZvcm1hdHRlci5mb3JtYXQ9JTEkdGMgJTIkcyVuJTQkczogJTUkcyU2JHMlbn0NCisgICAgICogPHA+DQorICAgICAqIFRoaXMgcHJpbnRzIHRoZSB0aW1lc3RhbXAgKHtAY29kZSAxJH0pIGFuZCB0aGUgc291cmNlICh7QGNvZGUgMiR9KSBvbiB0aGUNCisgICAgICogZmlyc3QgbGluZS4gVGhlIHNlY29uZCBsaW5lIGlzIHRoZSBsb2cgbGV2ZWwgKHtAY29kZSA0JH0pLCBsb2cgbWVzc2FnZQ0KKyAgICAgKiAoe0Bjb2RlIDUkfSksIGFuZCB0aGUgdGhyb3dhYmxlIHdpdGggYSByZWxldmFudCBzdGFjayB0cmFjZSBlbGVtZW50DQorICAgICAqICh7QGNvZGUgNiR9KSBpZiBvbmUgaXMgYXZhaWxhYmxlLg0KKyAgICAgKiA8cHJlPg0KKyAgICAgKiBGcmkgTm92IDIwIDA3OjI5OjI0IENTVCAyMDA5IE15Q2xhc3MgZmF0YWwNCisgICAgICogU0VWRVJFOiBFbmNvZGluZyBmYWlsZWQuTnVsbFBvaW50ZXJFeGNlcHRpb246IG51bGwgU3RyaW5nLmdldEJ5dGVzKDo5MTMpDQorICAgICAqIDwvcHJlPg0KKyAgICAgKg0KKyAgICAgKiA8bGk+e0Bjb2RlIGNvbS5zdW4ubWFpbC51dGlsLmxvZ2dpbmcuQ29tcGFjdEZvcm1hdHRlci5mb3JtYXQ9JTQkczogJTEyJCMuMTYwcyVufQ0KKyAgICAgKiA8cD4NCisgICAgICogVGhpcyBwcmludHMgdGhlIGxvZyBsZXZlbCAoe0Bjb2RlIDQkfSkgYW5kIG9ubHkgMTYwIGNoYXJhY3RlcnMgb2YgdGhlDQorICAgICAqIG1lc3NhZ2V8ZXJyb3IgKHtAY29kZSAxMiR9KSB1c2luZyB0aGUgYWx0ZXJuYXRlIGZvcm0uDQorICAgICAqIDxwcmU+DQorICAgICAqIFNFVkVSRTogVW5hYmxlIHRvIHNlbmQgbm90aWZpY2F0aW9uLnxTb2NrZXRFeGNlcHRpb246IFBlcm1pc3Npb24gZGVuaWVkOiBjb25uZWN0DQorICAgICAqIDwvcHJlPg0KKyAgICAgKg0KKyAgICAgKiA8bGk+e0Bjb2RlIGNvbS5zdW4ubWFpbC51dGlsLmxvZ2dpbmcuQ29tcGFjdEZvcm1hdHRlci5mb3JtYXQ9WyU5JGRdWyUxJHRUXVslMTAkZF1bJTIkc10gJTUkcyVuJTYkcyVufQ0KKyAgICAgKiA8cD4NCisgICAgICogVGhpcyBwcmludHMgdGhlIHNlcXVlbmNlICh7QGNvZGUgOSR9KSwgZXZlbnQgdGltZSAoe0Bjb2RlIDEkfSkgYXMgMjQgaG91cg0KKyAgICAgKiB0aW1lLCB0aHJlYWQgaWQgKHtAY29kZSAxMCR9KSwgc291cmNlICh7QGNvZGUgMiR9KSwgbG9nIG1lc3NhZ2UNCisgICAgICogKHtAY29kZSA1JH0pLCBhbmQgdGhlIHRocm93YWJsZSB3aXRoIGJhY2sgdHJhY2UgKHtAY29kZSA2JH0pLg0KKyAgICAgKiA8cHJlPg0KKyAgICAgKiBbMTI1XVsxNDoxMTo0Ml1bMzhdW015Q2xhc3MgZmF0YWxdIFVuYWJsZSB0byBzZW5kIG5vdGlmaWNhdGlvbi4NCisgICAgICogU29ja2V0RXhjZXB0aW9uOiBQZXJtaXNzaW9uIGRlbmllZDogY29ubmVjdCBTTVRQVHJhbnNwb3J0Lm9wZW5TZXJ2ZXIoOjE5NDkpDQorICAgICAqIDwvcHJlPg0KKyAgICAgKg0KKyAgICAgKiA8L3VsPg0KKyAgICAgKg0KKyAgICAgKiBAcGFyYW0gcmVjb3JkIHRoZSBsb2cgcmVjb3JkIHRvIGZvcm1hdC4NCisgICAgICogQHJldHVybiB0aGUgZm9ybWF0dGVkIHJlY29yZC4NCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgZ2l2ZW4gcmVjb3JkIGlzIG51bGwuDQorICAgICAqLw0KKyAgICBAT3ZlcnJpZGUNCisgICAgcHVibGljIFN0cmluZyBmb3JtYXQoZmluYWwgTG9nUmVjb3JkIHJlY29yZCkgew0KKyAgICAgICAgLy9Mb2dSZWNvcmQgaXMgbXV0YWJsZSBzbyBkZWZpbmUgbG9jYWwgdmFycy4NCisgICAgICAgIFJlc291cmNlQnVuZGxlIHJiID0gcmVjb3JkLmdldFJlc291cmNlQnVuZGxlKCk7DQorICAgICAgICBMb2NhbGUgbCA9IHJiID09IG51bGwgPyBudWxsIDogcmIuZ2V0TG9jYWxlKCk7DQorDQorICAgICAgICBTdHJpbmcgbXNnID0gZm9ybWF0TWVzc2FnZShyZWNvcmQpOw0KKyAgICAgICAgU3RyaW5nIHRocm93biA9IGZvcm1hdFRocm93bihyZWNvcmQpOw0KKyAgICAgICAgU3RyaW5nIGVyciA9IGZvcm1hdEVycm9yKHJlY29yZCk7DQorICAgICAgICBPYmplY3RbXSBwYXJhbXMgPSB7DQorICAgICAgICAgICAgZm9ybWF0Wm9uZWREYXRlVGltZShyZWNvcmQpLA0KKyAgICAgICAgICAgIGZvcm1hdFNvdXJjZShyZWNvcmQpLA0KKyAgICAgICAgICAgIGZvcm1hdExvZ2dlck5hbWUocmVjb3JkKSwNCisgICAgICAgICAgICBmb3JtYXRMZXZlbChyZWNvcmQpLA0KKyAgICAgICAgICAgIG1zZywNCisgICAgICAgICAgICB0aHJvd24sDQorICAgICAgICAgICAgbmV3IEFsdGVybmF0ZShtc2csIHRocm93biksDQorICAgICAgICAgICAgbmV3IEFsdGVybmF0ZSh0aHJvd24sIG1zZyksDQorICAgICAgICAgICAgcmVjb3JkLmdldFNlcXVlbmNlTnVtYmVyKCksDQorICAgICAgICAgICAgZm9ybWF0VGhyZWFkSUQocmVjb3JkKSwNCisgICAgICAgICAgICBlcnIsDQorICAgICAgICAgICAgbmV3IEFsdGVybmF0ZShtc2csIGVyciksDQorICAgICAgICAgICAgbmV3IEFsdGVybmF0ZShlcnIsIG1zZyksDQorICAgICAgICAgICAgZm9ybWF0QmFja1RyYWNlKHJlY29yZCksDQorICAgICAgICAgICAgcmVjb3JkLmdldFJlc291cmNlQnVuZGxlTmFtZSgpLA0KKyAgICAgICAgICAgIHJlY29yZC5nZXRNZXNzYWdlKCl9Ow0KKw0KKyAgICAgICAgaWYgKGwgPT0gbnVsbCkgeyAvL0JVRyBJRCA2MjgyMDk0DQorICAgICAgICAgICAgcmV0dXJuIFN0cmluZy5mb3JtYXQoZm10LCBwYXJhbXMpOw0KKyAgICAgICAgfSBlbHNlIHsNCisgICAgICAgICAgICByZXR1cm4gU3RyaW5nLmZvcm1hdChsLCBmbXQsIHBhcmFtcyk7DQorICAgICAgICB9DQorICAgIH0NCisNCisgICAgLyoqDQorICAgICAqIEZvcm1hdHMgbWVzc2FnZSBmb3IgdGhlIGxvZyByZWNvcmQuIFRoaXMgbWV0aG9kIHJlbW92ZXMgYW55IGZ1bGx5DQorICAgICAqIHF1YWxpZmllZCB0aHJvd2FibGUgY2xhc3MgbmFtZXMgZnJvbSB0aGUgbWVzc2FnZS4NCisgICAgICoNCisgICAgICogQHBhcmFtIHJlY29yZCB0aGUgbG9nIHJlY29yZC4NCisgICAgICogQHJldHVybiB0aGUgZm9ybWF0dGVkIG1lc3NhZ2Ugc3RyaW5nLg0KKyAgICAgKi8NCisgICAgQE92ZXJyaWRlDQorICAgIHB1YmxpYyBTdHJpbmcgZm9ybWF0TWVzc2FnZShmaW5hbCBMb2dSZWNvcmQgcmVjb3JkKSB7DQorICAgICAgICBTdHJpbmcgbXNnID0gc3VwZXIuZm9ybWF0TWVzc2FnZShyZWNvcmQpOw0KKyAgICAgICAgbXNnID0gcmVwbGFjZUNsYXNzTmFtZShtc2csIHJlY29yZC5nZXRUaHJvd24oKSk7DQorICAgICAgICBtc2cgPSByZXBsYWNlQ2xhc3NOYW1lKG1zZywgcmVjb3JkLmdldFBhcmFtZXRlcnMoKSk7DQorICAgICAgICByZXR1cm4gbXNnOw0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBGb3JtYXRzIHRoZSBtZXNzYWdlIGZyb20gdGhlIHRocm93biBwcm9wZXJ0eSBvZiB0aGUgbG9nIHJlY29yZC4gVGhpcw0KKyAgICAgKiBtZXRob2QgcmVwbGFjZXMgZnVsbHkgcXVhbGlmaWVkIHRocm93YWJsZSBjbGFzcyBuYW1lcyBmcm9tIHRoZSBtZXNzYWdlDQorICAgICAqIGNhdXNlIGNoYWluIHdpdGggc2ltcGxlIGNsYXNzIG5hbWVzLg0KKyAgICAgKg0KKyAgICAgKiBAcGFyYW0gdCB0aGUgdGhyb3dhYmxlIHRvIGZvcm1hdCBvciBudWxsLg0KKyAgICAgKiBAcmV0dXJuIHRoZSBlbXB0eSBzdHJpbmcgaWYgbnVsbCB3YXMgZ2l2ZW4gb3IgdGhlIGZvcm1hdHRlZCBtZXNzYWdlDQorICAgICAqIHN0cmluZyBmcm9tIHRoZSB0aHJvd2FibGUgd2hpY2ggbWF5IGJlIG51bGwuDQorICAgICAqLw0KKyAgICBwdWJsaWMgU3RyaW5nIGZvcm1hdE1lc3NhZ2UoZmluYWwgVGhyb3dhYmxlIHQpIHsNCisgICAgICAgIFN0cmluZyByOw0KKyAgICAgICAgaWYgKHQgIT0gbnVsbCkgew0KKyAgICAgICAgICAgIGZpbmFsIFRocm93YWJsZSBhcHBseSA9IGFwcGx5KHQpOw0KKyAgICAgICAgICAgIGZpbmFsIFN0cmluZyBtID0gYXBwbHkuZ2V0TG9jYWxpemVkTWVzc2FnZSgpOw0KKyAgICAgICAgICAgIGZpbmFsIFN0cmluZyBzID0gYXBwbHkudG9TdHJpbmcoKTsNCisgICAgICAgICAgICBmaW5hbCBTdHJpbmcgc24gPSBzaW1wbGVDbGFzc05hbWUoYXBwbHkuZ2V0Q2xhc3MoKSk7DQorICAgICAgICAgICAgaWYgKCFpc051bGxPclNwYWNlcyhtKSkgew0KKyAgICAgICAgICAgICAgICBpZiAocy5jb250YWlucyhtKSkgew0KKyAgICAgICAgICAgICAgICAgICAgaWYgKHMuc3RhcnRzV2l0aChhcHBseS5nZXRDbGFzcygpLmdldE5hbWUoKSkNCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgcy5zdGFydHNXaXRoKHNuKSkgew0KKyAgICAgICAgICAgICAgICAgICAgICAgIHIgPSByZXBsYWNlQ2xhc3NOYW1lKG0sIHQpOw0KKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsNCisgICAgICAgICAgICAgICAgICAgICAgICByID0gcmVwbGFjZUNsYXNzTmFtZShzaW1wbGVDbGFzc05hbWUocyksIHQpOw0KKyAgICAgICAgICAgICAgICAgICAgfQ0KKyAgICAgICAgICAgICAgICB9IGVsc2Ugew0KKyAgICAgICAgICAgICAgICAgICAgciA9IHJlcGxhY2VDbGFzc05hbWUoc2ltcGxlQ2xhc3NOYW1lKHMpICsgIjogIiArIG0sIHQpOw0KKyAgICAgICAgICAgICAgICB9DQorICAgICAgICAgICAgfSBlbHNlIHsNCisgICAgICAgICAgICAgICAgciA9IHJlcGxhY2VDbGFzc05hbWUoc2ltcGxlQ2xhc3NOYW1lKHMpLCB0KTsNCisgICAgICAgICAgICB9DQorDQorICAgICAgICAgICAgaWYgKCFyLmNvbnRhaW5zKHNuKSkgew0KKyAgICAgICAgICAgICAgICByID0gc24gKyAiOiAiICsgcjsNCisgICAgICAgICAgICB9DQorICAgICAgICB9IGVsc2Ugew0KKyAgICAgICAgICAgIHIgPSAiIjsNCisgICAgICAgIH0NCisgICAgICAgIHJldHVybiByOw0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBGb3JtYXRzIHRoZSBsZXZlbCBwcm9wZXJ0eSBvZiB0aGUgZ2l2ZW4gbG9nIHJlY29yZC4NCisgICAgICoNCisgICAgICogQHBhcmFtIHJlY29yZCB0aGUgcmVjb3JkLg0KKyAgICAgKiBAcmV0dXJuIHRoZSBmb3JtYXR0ZWQgbG9nZ2VyIG5hbWUuDQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIGdpdmVuIHJlY29yZCBpcyBudWxsLg0KKyAgICAgKi8NCisgICAgcHVibGljIFN0cmluZyBmb3JtYXRMZXZlbChmaW5hbCBMb2dSZWNvcmQgcmVjb3JkKSB7DQorICAgICAgICByZXR1cm4gcmVjb3JkLmdldExldmVsKCkuZ2V0TG9jYWxpemVkTmFtZSgpOw0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBGb3JtYXRzIHRoZSBzb3VyY2UgZnJvbSB0aGUgZ2l2ZW4gbG9nIHJlY29yZC4NCisgICAgICoNCisgICAgICogQHBhcmFtIHJlY29yZCB0aGUgcmVjb3JkLg0KKyAgICAgKiBAcmV0dXJuIHRoZSBmb3JtYXR0ZWQgc291cmNlIG9mIHRoZSBsb2cgcmVjb3JkLg0KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBnaXZlbiByZWNvcmQgaXMgbnVsbC4NCisgICAgICovDQorICAgIHB1YmxpYyBTdHJpbmcgZm9ybWF0U291cmNlKGZpbmFsIExvZ1JlY29yZCByZWNvcmQpIHsNCisgICAgICAgIFN0cmluZyBzb3VyY2UgPSByZWNvcmQuZ2V0U291cmNlQ2xhc3NOYW1lKCk7DQorICAgICAgICBpZiAoc291cmNlICE9IG51bGwpIHsNCisgICAgICAgICAgICBpZiAocmVjb3JkLmdldFNvdXJjZU1ldGhvZE5hbWUoKSAhPSBudWxsKSB7DQorICAgICAgICAgICAgICAgIHNvdXJjZSA9IHNpbXBsZUNsYXNzTmFtZShzb3VyY2UpICsgIiAiDQorICAgICAgICAgICAgICAgICAgICAgICAgKyByZWNvcmQuZ2V0U291cmNlTWV0aG9kTmFtZSgpOw0KKyAgICAgICAgICAgIH0gZWxzZSB7DQorICAgICAgICAgICAgICAgIHNvdXJjZSA9IHNpbXBsZUNsYXNzTmFtZShzb3VyY2UpOw0KKyAgICAgICAgICAgIH0NCisgICAgICAgIH0gZWxzZSB7DQorICAgICAgICAgICAgc291cmNlID0gc2ltcGxlQ2xhc3NOYW1lKHJlY29yZC5nZXRMb2dnZXJOYW1lKCkpOw0KKyAgICAgICAgfQ0KKyAgICAgICAgcmV0dXJuIHNvdXJjZTsNCisgICAgfQ0KKw0KKyAgICAvKioNCisgICAgICogRm9ybWF0cyB0aGUgbG9nZ2VyIG5hbWUgcHJvcGVydHkgb2YgdGhlIGdpdmVuIGxvZyByZWNvcmQuDQorICAgICAqDQorICAgICAqIEBwYXJhbSByZWNvcmQgdGhlIHJlY29yZC4NCisgICAgICogQHJldHVybiB0aGUgZm9ybWF0dGVkIGxvZ2dlciBuYW1lLg0KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBnaXZlbiByZWNvcmQgaXMgbnVsbC4NCisgICAgICovDQorICAgIHB1YmxpYyBTdHJpbmcgZm9ybWF0TG9nZ2VyTmFtZShmaW5hbCBMb2dSZWNvcmQgcmVjb3JkKSB7DQorICAgICAgICByZXR1cm4gc2ltcGxlQ2xhc3NOYW1lKHJlY29yZC5nZXRMb2dnZXJOYW1lKCkpOw0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBGb3JtYXRzIHRoZSB0aHJlYWQgaWQgcHJvcGVydHkgb2YgdGhlIGdpdmVuIGxvZyByZWNvcmQuIEJ5IGRlZmF1bHQgdGhpcw0KKyAgICAgKiBpcyBmb3JtYXR0ZWQgYXMgYSB7QGNvZGUgbG9uZ30gYnkgYW4gdW5zaWduZWQgY29udmVyc2lvbi4NCisgICAgICoNCisgICAgICogQHBhcmFtIHJlY29yZCB0aGUgcmVjb3JkLg0KKyAgICAgKiBAcmV0dXJuIHRoZSBmb3JtYXR0ZWQgdGhyZWFkIGlkIGFzIGEgbnVtYmVyLg0KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBnaXZlbiByZWNvcmQgaXMgbnVsbC4NCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNS40DQorICAgICAqLw0KKyAgICBwdWJsaWMgTnVtYmVyIGZvcm1hdFRocmVhZElEKGZpbmFsIExvZ1JlY29yZCByZWNvcmQpIHsNCisgICAgICAgIC8qKg0KKyAgICAgICAgICogVGhyZWFkLmdldElEIGlzIGRlZmluZWQgYXMgbG9uZyBhbmQgTG9nUmVjb3JkLmdldFRocmVhZElEIGlzIGRlZmluZWQNCisgICAgICAgICAqIGFzIGludC4gQ29udmVydCB0byB1bnNpZ25lZCBhcyBhIG1lYW5zIHRvIGJldHRlciBtYXAgdGhlIHR3byB0eXBlcyBvZg0KKyAgICAgICAgICogdGhyZWFkIGlkZW50aWZpZXJzLg0KKyAgICAgICAgICovDQorICAgICAgICByZXR1cm4gKCgobG9uZykgcmVjb3JkLmdldFRocmVhZElEKCkpICYgMHhmZmZmZmZmZkwpOw0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBGb3JtYXRzIHRoZSB0aHJvd24gcHJvcGVydHkgb2YgYSBMb2dSZWNvcmQuIFRoZSByZXR1cm5lZCBzdHJpbmcgd2lsbA0KKyAgICAgKiBjb250YWluIGEgdGhyb3dhYmxlIG1lc3NhZ2Ugd2l0aCBhIGJhY2sgdHJhY2UuDQorICAgICAqDQorICAgICAqIEBwYXJhbSByZWNvcmQgdGhlIHJlY29yZC4NCisgICAgICogQHJldHVybiBlbXB0eSBzdHJpbmcgaWYgbm90aGluZyB3YXMgdGhyb3duIG9yIGZvcm1hdHRlZCBzdHJpbmcuDQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIGdpdmVuIHJlY29yZCBpcyBudWxsLg0KKyAgICAgKiBAc2VlICNhcHBseShqYXZhLmxhbmcuVGhyb3dhYmxlKQ0KKyAgICAgKiBAc2VlICNmb3JtYXRCYWNrVHJhY2UoamF2YS51dGlsLmxvZ2dpbmcuTG9nUmVjb3JkKQ0KKyAgICAgKi8NCisgICAgcHVibGljIFN0cmluZyBmb3JtYXRUaHJvd24oZmluYWwgTG9nUmVjb3JkIHJlY29yZCkgew0KKyAgICAgICAgU3RyaW5nIG1zZzsNCisgICAgICAgIGZpbmFsIFRocm93YWJsZSB0ID0gcmVjb3JkLmdldFRocm93bigpOw0KKyAgICAgICAgaWYgKHQgIT0gbnVsbCkgew0KKyAgICAgICAgICAgIFN0cmluZyBzaXRlID0gZm9ybWF0QmFja1RyYWNlKHJlY29yZCk7DQorICAgICAgICAgICAgbXNnID0gZm9ybWF0TWVzc2FnZSh0KSArIChpc051bGxPclNwYWNlcyhzaXRlKSA/ICIiIDogJyAnICsgc2l0ZSk7DQorICAgICAgICB9IGVsc2Ugew0KKyAgICAgICAgICAgIG1zZyA9ICIiOw0KKyAgICAgICAgfQ0KKyAgICAgICAgcmV0dXJuIG1zZzsNCisgICAgfQ0KKw0KKyAgICAvKioNCisgICAgICogRm9ybWF0cyB0aGUgdGhyb3duIHByb3BlcnR5IG9mIGEgTG9nUmVjb3JkIGFzIGFuIGVycm9yIG1lc3NhZ2UuIFRoZQ0KKyAgICAgKiByZXR1cm5lZCBzdHJpbmcgd2lsbCBub3QgY29udGFpbiBhIGJhY2sgdHJhY2UuDQorICAgICAqDQorICAgICAqIEBwYXJhbSByZWNvcmQgdGhlIHJlY29yZC4NCisgICAgICogQHJldHVybiBlbXB0eSBzdHJpbmcgaWYgbm90aGluZyB3YXMgdGhyb3duIG9yIGZvcm1hdHRlZCBzdHJpbmcuDQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIGdpdmVuIHJlY29yZCBpcyBudWxsLg0KKyAgICAgKiBAc2VlIFRocm93YWJsZSN0b1N0cmluZygpDQorICAgICAqIEBzZWUgI2FwcGx5KGphdmEubGFuZy5UaHJvd2FibGUpDQorICAgICAqIEBzZWUgI2Zvcm1hdE1lc3NhZ2UoamF2YS5sYW5nLlRocm93YWJsZSkNCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNS40DQorICAgICAqLw0KKyAgICBwdWJsaWMgU3RyaW5nIGZvcm1hdEVycm9yKGZpbmFsIExvZ1JlY29yZCByZWNvcmQpIHsNCisgICAgICAgIHJldHVybiBmb3JtYXRNZXNzYWdlKHJlY29yZC5nZXRUaHJvd24oKSk7DQorICAgIH0NCisNCisgICAgLyoqDQorICAgICAqIEZvcm1hdHMgdGhlIGJhY2sgdHJhY2UgZm9yIHRoZSBnaXZlbiBsb2cgcmVjb3JkLg0KKyAgICAgKg0KKyAgICAgKiBAcGFyYW0gcmVjb3JkIHRoZSBsb2cgcmVjb3JkIHRvIGZvcm1hdC4NCisgICAgICogQHJldHVybiB0aGUgZm9ybWF0dGVkIGJhY2sgdHJhY2UuDQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIGdpdmVuIHJlY29yZCBpcyBudWxsLg0KKyAgICAgKiBAc2VlICNhcHBseShqYXZhLmxhbmcuVGhyb3dhYmxlKQ0KKyAgICAgKiBAc2VlICNmb3JtYXRUaHJvd24oamF2YS51dGlsLmxvZ2dpbmcuTG9nUmVjb3JkKQ0KKyAgICAgKiBAc2VlICNpZ25vcmUoamF2YS5sYW5nLlN0YWNrVHJhY2VFbGVtZW50KQ0KKyAgICAgKi8NCisgICAgcHVibGljIFN0cmluZyBmb3JtYXRCYWNrVHJhY2UoZmluYWwgTG9nUmVjb3JkIHJlY29yZCkgew0KKyAgICAgICAgU3RyaW5nIHNpdGUgPSAiIjsNCisgICAgICAgIGZpbmFsIFRocm93YWJsZSB0ID0gcmVjb3JkLmdldFRocm93bigpOw0KKyAgICAgICAgaWYgKHQgIT0gbnVsbCkgew0KKyAgICAgICAgICAgIGZpbmFsIFRocm93YWJsZSByb290ID0gYXBwbHkodCk7DQorICAgICAgICAgICAgU3RhY2tUcmFjZUVsZW1lbnRbXSB0cmFjZSA9IHJvb3QuZ2V0U3RhY2tUcmFjZSgpOw0KKyAgICAgICAgICAgIHNpdGUgPSBmaW5kQW5kRm9ybWF0KHRyYWNlKTsNCisgICAgICAgICAgICBpZiAoaXNOdWxsT3JTcGFjZXMoc2l0ZSkpIHsNCisgICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gMDsNCisgICAgICAgICAgICAgICAgZm9yIChUaHJvd2FibGUgYyA9IHQ7IGMgIT0gbnVsbDsgYyA9IGMuZ2V0Q2F1c2UoKSkgew0KKyAgICAgICAgICAgICAgICAgICAgU3RhY2tUcmFjZUVsZW1lbnRbXSBzdGUgPSBjLmdldFN0YWNrVHJhY2UoKTsNCisgICAgICAgICAgICAgICAgICAgIHNpdGUgPSBmaW5kQW5kRm9ybWF0KHN0ZSk7DQorICAgICAgICAgICAgICAgICAgICBpZiAoIWlzTnVsbE9yU3BhY2VzKHNpdGUpKSB7DQorICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQorICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugew0KKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0cmFjZS5sZW5ndGggPT0gMCkgew0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNlID0gc3RlOw0KKyAgICAgICAgICAgICAgICAgICAgICAgIH0NCisgICAgICAgICAgICAgICAgICAgIH0NCisNCisgICAgICAgICAgICAgICAgICAgIC8vRGVhbCB3aXRoIGV4Y2Vzc2l2ZSBjYXVzZSBjaGFpbnMNCisgICAgICAgICAgICAgICAgICAgIC8vYW5kIGN5Y2xpYyB0aHJvd2FibGVzLg0KKyAgICAgICAgICAgICAgICAgICAgaWYgKCsrbGltaXQgPT0gKDEgPDwgMTYpKSB7DQorICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7IC8vR2l2ZSB1cC4NCisgICAgICAgICAgICAgICAgICAgIH0NCisgICAgICAgICAgICAgICAgfQ0KKw0KKyAgICAgICAgICAgICAgICAvL1B1bnQuDQorICAgICAgICAgICAgICAgIGlmIChpc051bGxPclNwYWNlcyhzaXRlKSAmJiB0cmFjZS5sZW5ndGggIT0gMCkgew0KKyAgICAgICAgICAgICAgICAgICAgc2l0ZSA9IGZvcm1hdFN0YWNrVHJhY2VFbGVtZW50KHRyYWNlWzBdKTsNCisgICAgICAgICAgICAgICAgfQ0KKyAgICAgICAgICAgIH0NCisgICAgICAgIH0NCisgICAgICAgIHJldHVybiBzaXRlOw0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBGaW5kcyBhbmQgZm9ybWF0cyB0aGUgZmlyc3Qgc3RhY2sgZnJhbWUgb2YgaW50ZXJlc3QuDQorICAgICAqDQorICAgICAqIEBwYXJhbSB0cmFjZSB0aGUgZmlsbCBzdGFjayB0byBleGFtaW5lLg0KKyAgICAgKiBAcmV0dXJuIGEgU3RyaW5nIHRoYXQgYmVzdCBkZXNjcmliZXMgdGhlIGNhbGwgc2l0ZS4NCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiBzdGFjayB0cmFjZSBlbGVtZW50IGFycmF5IGlzIG51bGwuDQorICAgICAqLw0KKyAgICBwcml2YXRlIFN0cmluZyBmaW5kQW5kRm9ybWF0KGZpbmFsIFN0YWNrVHJhY2VFbGVtZW50W10gdHJhY2UpIHsNCisgICAgICAgIFN0cmluZyBzaXRlID0gIiI7DQorICAgICAgICBmb3IgKFN0YWNrVHJhY2VFbGVtZW50IHMgOiB0cmFjZSkgew0KKyAgICAgICAgICAgIGlmICghaWdub3JlKHMpKSB7DQorICAgICAgICAgICAgICAgIHNpdGUgPSBmb3JtYXRTdGFja1RyYWNlRWxlbWVudChzKTsNCisgICAgICAgICAgICAgICAgYnJlYWs7DQorICAgICAgICAgICAgfQ0KKyAgICAgICAgfQ0KKw0KKyAgICAgICAgLy9DaGVjayBpZiBhbGwgY29kZSB3YXMgY29tcGlsZWQgd2l0aCBubyBkZWJ1Z2dpbmcgaW5mby4NCisgICAgICAgIGlmIChpc051bGxPclNwYWNlcyhzaXRlKSkgew0KKyAgICAgICAgICAgIGZvciAoU3RhY2tUcmFjZUVsZW1lbnQgcyA6IHRyYWNlKSB7DQorICAgICAgICAgICAgICAgIGlmICghZGVmYXVsdElnbm9yZShzKSkgew0KKyAgICAgICAgICAgICAgICAgICAgc2l0ZSA9IGZvcm1hdFN0YWNrVHJhY2VFbGVtZW50KHMpOw0KKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQorICAgICAgICAgICAgICAgIH0NCisgICAgICAgICAgICB9DQorICAgICAgICB9DQorICAgICAgICByZXR1cm4gc2l0ZTsNCisgICAgfQ0KKw0KKyAgICAvKioNCisgICAgICogRm9ybWF0cyBhIHN0YWNrIHRyYWNlIGVsZW1lbnQgaW50byBhIHNpbXBsZSBjYWxsIHNpdGUuDQorICAgICAqDQorICAgICAqIEBwYXJhbSBzIHRoZSBzdGFjayB0cmFjZSBlbGVtZW50IHRvIGZvcm1hdC4NCisgICAgICogQHJldHVybiB0aGUgZm9ybWF0dGVkIHN0YWNrIHRyYWNlIGVsZW1lbnQuDQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgc3RhY2sgdHJhY2UgZWxlbWVudCBpcyBudWxsLg0KKyAgICAgKiBAc2VlICNmb3JtYXRUaHJvd24oamF2YS51dGlsLmxvZ2dpbmcuTG9nUmVjb3JkKQ0KKyAgICAgKi8NCisgICAgcHJpdmF0ZSBTdHJpbmcgZm9ybWF0U3RhY2tUcmFjZUVsZW1lbnQoZmluYWwgU3RhY2tUcmFjZUVsZW1lbnQgcykgew0KKyAgICAgICAgU3RyaW5nIHYgPSBzaW1wbGVDbGFzc05hbWUocy5nZXRDbGFzc05hbWUoKSk7DQorICAgICAgICBTdHJpbmcgcmVzdWx0Ow0KKyAgICAgICAgaWYgKHYgIT0gbnVsbCkgew0KKyAgICAgICAgICAgIHJlc3VsdCA9IHMudG9TdHJpbmcoKS5yZXBsYWNlKHMuZ2V0Q2xhc3NOYW1lKCksIHYpOw0KKyAgICAgICAgfSBlbHNlIHsNCisgICAgICAgICAgICByZXN1bHQgPSBzLnRvU3RyaW5nKCk7DQorICAgICAgICB9DQorDQorICAgICAgICAvL0lmIHRoZSBjbGFzcyBuYW1lIGNvbnRhaW5zIHRoZSBzaW1wbGUgZmlsZSBuYW1lIHRoZW4gcmVtb3ZlIGZpbGUgbmFtZS4NCisgICAgICAgIHYgPSBzaW1wbGVGaWxlTmFtZShzLmdldEZpbGVOYW1lKCkpOw0KKyAgICAgICAgaWYgKHYgIT0gbnVsbCAmJiByZXN1bHQuc3RhcnRzV2l0aCh2KSkgew0KKyAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5yZXBsYWNlKHMuZ2V0RmlsZU5hbWUoKSwgIiIpOw0KKyAgICAgICAgfQ0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsNCisgICAgfQ0KKw0KKyAgICAvKioNCisgICAgICogQ2hvb3NlcyBhIHNpbmdsZSB0aHJvd2FibGUgZnJvbSB0aGUgY2F1c2UgY2hhaW4gdGhhdCB3aWxsIGJlIGZvcm1hdHRlZC4NCisgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiBjaG9vc2VzIHRoZSB0aHJvd2FibGUgdGhhdCBiZXN0IGRlc2NyaWJlcyB0aGUgY2hhaW4uDQorICAgICAqIFN1YmNsYXNzZXMgY2FuIG92ZXJyaWRlIHRoaXMgbWV0aG9kIHRvIGNob29zZSBhbiBhbHRlcm5hdGUgdGhyb3dhYmxlIGZvcg0KKyAgICAgKiBmb3JtYXR0aW5nLg0KKyAgICAgKg0KKyAgICAgKiBAcGFyYW0gdCB0aGUgdGhyb3dhYmxlIGZyb20gdGhlIGxvZyByZWNvcmQuDQorICAgICAqIEByZXR1cm4gdGhlIGNob3NlbiB0aHJvd2FibGUgb3IgbnVsbCBvbmx5IGlmIHRoZSBnaXZlbiBhcmd1bWVudCBpcyBudWxsLg0KKyAgICAgKiBAc2VlICNmb3JtYXRUaHJvd24oamF2YS51dGlsLmxvZ2dpbmcuTG9nUmVjb3JkKQ0KKyAgICAgKi8NCisgICAgcHJvdGVjdGVkIFRocm93YWJsZSBhcHBseShmaW5hbCBUaHJvd2FibGUgdCkgew0KKyAgICAgICAgcmV0dXJuIFNldmVyaXR5Q29tcGFyYXRvci5nZXRJbnN0YW5jZSgpLmFwcGx5KHQpOw0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBEZXRlcm1pbmVzIGlmIGEgc3RhY2sgZnJhbWUgc2hvdWxkIGJlIGlnbm9yZWQgYXMgdGhlIGNhdXNlIG9mIGFuIGVycm9yLg0KKyAgICAgKg0KKyAgICAgKiBAcGFyYW0gcyB0aGUgc3RhY2sgdHJhY2UgZWxlbWVudC4NCisgICAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgZnJhbWUgc2hvdWxkIGJlIGlnbm9yZWQuDQorICAgICAqIEBzZWUgI2Zvcm1hdFRocm93bihqYXZhLnV0aWwubG9nZ2luZy5Mb2dSZWNvcmQpDQorICAgICAqLw0KKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpZ25vcmUoZmluYWwgU3RhY2tUcmFjZUVsZW1lbnQgcykgew0KKyAgICAgICAgcmV0dXJuIGlzVW5rbm93bihzKSB8fCBkZWZhdWx0SWdub3JlKHMpOw0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBEZWZpbmVzIHRoZSBhbHRlcm5hdGUgZm9ybWF0LiBUaGlzIGltcGxlbWVudGF0aW9uIHJlbW92ZXMgYWxsIGNvbnRyb2wNCisgICAgICogY2hhcmFjdGVycyBmcm9tIHRoZSBnaXZlbiBzdHJpbmcuDQorICAgICAqDQorICAgICAqIEBwYXJhbSBzIGFueSBzdHJpbmcgb3IgbnVsbC4NCisgICAgICogQHJldHVybiBudWxsIGlmIHRoZSBhcmd1bWVudCB3YXMgbnVsbCBvdGhlcndpc2UsIGFuIGFsdGVybmF0ZSBzdHJpbmcuDQorICAgICAqLw0KKyAgICBwcm90ZWN0ZWQgU3RyaW5nIHRvQWx0ZXJuYXRlKGZpbmFsIFN0cmluZyBzKSB7DQorICAgICAgICByZXR1cm4gcyAhPSBudWxsID8gcy5yZXBsYWNlQWxsKCJbXFx4MDAtXFx4MUZcXHg3Rl0rIiwgIiIpIDogbnVsbDsNCisgICAgfQ0KKw0KKyAgICAvKioNCisgICAgICogR2V0cyB0aGUgem9uZWQgZGF0ZSB0aW1lIGZyb20gdGhlIGdpdmVuIGxvZyByZWNvcmQuDQorICAgICAqDQorICAgICAqIEBwYXJhbSByZWNvcmQgdGhlIGN1cnJlbnQgbG9nIHJlY29yZC4NCisgICAgICogQHJldHVybiBhIHpvbmVkIGRhdGUgdGltZSBvciBhIGxlZ2FjeSBkYXRlIG9iamVjdC4NCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgZ2l2ZW4gcmVjb3JkIGlzIG51bGwuDQorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjUuNg0KKyAgICAgKi8NCisgICAgcHJpdmF0ZSBDb21wYXJhYmxlPD8+IGZvcm1hdFpvbmVkRGF0ZVRpbWUoZmluYWwgTG9nUmVjb3JkIHJlY29yZCkgew0KKyAgICAgICAgQ29tcGFyYWJsZTw/PiB6ZHQgPSBMb2dNYW5hZ2VyUHJvcGVydGllcy5nZXRab25lZERhdGVUaW1lKHJlY29yZCk7DQorICAgICAgICBpZiAoemR0ID09IG51bGwpIHsNCisgICAgICAgICAgICB6ZHQgPSBuZXcgamF2YS51dGlsLkRhdGUocmVjb3JkLmdldE1pbGxpcygpKTsNCisgICAgICAgIH0NCisgICAgICAgIHJldHVybiB6ZHQ7DQorICAgIH0NCisNCisgICAgLyoqDQorICAgICAqIERldGVybWluZXMgaWYgYSBzdGFjayBmcmFtZSBzaG91bGQgYmUgaWdub3JlZCBhcyB0aGUgY2F1c2Ugb2YgYW4gZXJyb3IuDQorICAgICAqIFRoaXMgZG9lcyBub3QgY2hlY2sgZm9yIHVua25vd24gbGluZSBudW1iZXJzIGJlY2F1c2UgY29kZSBjYW4gYmUgY29tcGlsZWQNCisgICAgICogd2l0aG91dCBkZWJ1Z2dpbmcgaW5mby4NCisgICAgICoNCisgICAgICogQHBhcmFtIHMgdGhlIHN0YWNrIHRyYWNlIGVsZW1lbnQuDQorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIGZyYW1lIHNob3VsZCBiZSBpZ25vcmVkLg0KKyAgICAgKi8NCisgICAgcHJpdmF0ZSBib29sZWFuIGRlZmF1bHRJZ25vcmUoZmluYWwgU3RhY2tUcmFjZUVsZW1lbnQgcykgew0KKyAgICAgICAgcmV0dXJuIGlzU3ludGhldGljKHMpIHx8IGlzU3RhdGljVXRpbGl0eShzKSB8fCBpc1JlZmxlY3Rpb24ocyk7DQorICAgIH0NCisNCisgICAgLyoqDQorICAgICAqIERldGVybWluZXMgaWYgYSBzdGFjayBmcmFtZSBpcyBmb3IgYSBzdGF0aWMgdXRpbGl0eSBjbGFzcy4NCisgICAgICoNCisgICAgICogQHBhcmFtIHMgdGhlIHN0YWNrIHRyYWNlIGVsZW1lbnQuDQorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIGZyYW1lIHNob3VsZCBiZSBpZ25vcmVkLg0KKyAgICAgKi8NCisgICAgcHJpdmF0ZSBib29sZWFuIGlzU3RhdGljVXRpbGl0eShmaW5hbCBTdGFja1RyYWNlRWxlbWVudCBzKSB7DQorICAgICAgICB0cnkgew0KKyAgICAgICAgICAgIHJldHVybiBMb2dNYW5hZ2VyUHJvcGVydGllcy5pc1N0YXRpY1V0aWxpdHlDbGFzcyhzLmdldENsYXNzTmFtZSgpKTsNCisgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gaWdub3JlKSB7DQorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gfCBMaW5rYWdlRXJyb3IgaWdub3JlKSB7DQorICAgICAgICB9DQorICAgICAgICBmaW5hbCBTdHJpbmcgY24gPSBzLmdldENsYXNzTmFtZSgpOw0KKyAgICAgICAgcmV0dXJuIChjbi5lbmRzV2l0aCgicyIpICYmICFjbi5lbmRzV2l0aCgiZXMiKSkNCisgICAgICAgICAgICAgICAgfHwgY24uY29udGFpbnMoIlV0aWwiKSB8fCBjbi5lbmRzV2l0aCgiVGhyb3dhYmxlcyIpOw0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBEZXRlcm1pbmVzIGlmIGEgc3RhY2sgdHJhY2UgZWxlbWVudCBpcyBmb3IgYSBzeW50aGV0aWMgbWV0aG9kLg0KKyAgICAgKg0KKyAgICAgKiBAcGFyYW0gcyB0aGUgc3RhY2sgdHJhY2UgZWxlbWVudC4NCisgICAgICogQHJldHVybiB0cnVlIGlmIHN5bnRoZXRpYy4NCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiBzdGFjayB0cmFjZSBlbGVtZW50IGlzIG51bGwuDQorICAgICAqLw0KKyAgICBwcml2YXRlIGJvb2xlYW4gaXNTeW50aGV0aWMoZmluYWwgU3RhY2tUcmFjZUVsZW1lbnQgcykgew0KKyAgICAgICAgcmV0dXJuIHMuZ2V0TWV0aG9kTmFtZSgpLmluZGV4T2YoJyQnKSA+IC0xOw0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBEZXRlcm1pbmVzIGlmIGEgc3RhY2sgdHJhY2UgZWxlbWVudCBoYXMgYW4gdW5rbm93biBsaW5lIG51bWJlciBvciBhDQorICAgICAqIG5hdGl2ZSBsaW5lIG51bWJlci4NCisgICAgICoNCisgICAgICogQHBhcmFtIHMgdGhlIHN0YWNrIHRyYWNlIGVsZW1lbnQuDQorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgbGluZSBudW1iZXIgaXMgdW5rbm93bi4NCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiBzdGFjayB0cmFjZSBlbGVtZW50IGlzIG51bGwuDQorICAgICAqLw0KKyAgICBwcml2YXRlIGJvb2xlYW4gaXNVbmtub3duKGZpbmFsIFN0YWNrVHJhY2VFbGVtZW50IHMpIHsNCisgICAgICAgIHJldHVybiBzLmdldExpbmVOdW1iZXIoKSA8IDA7DQorICAgIH0NCisNCisgICAgLyoqDQorICAgICAqIERldGVybWluZXMgaWYgYSBzdGFjayB0cmFjZSBlbGVtZW50IHJlcHJlc2VudHMgYSByZWZsZWN0aW9uIGZyYW1lLg0KKyAgICAgKg0KKyAgICAgKiBAcGFyYW0gcyB0aGUgc3RhY2sgdHJhY2UgZWxlbWVudC4NCisgICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBsaW5lIG51bWJlciBpcyB1bmtub3duLg0KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHN0YWNrIHRyYWNlIGVsZW1lbnQgaXMgbnVsbC4NCisgICAgICovDQorICAgIHByaXZhdGUgYm9vbGVhbiBpc1JlZmxlY3Rpb24oZmluYWwgU3RhY2tUcmFjZUVsZW1lbnQgcykgew0KKyAgICAgICAgdHJ5IHsNCisgICAgICAgICAgICByZXR1cm4gTG9nTWFuYWdlclByb3BlcnRpZXMuaXNSZWZsZWN0aW9uQ2xhc3Mocy5nZXRDbGFzc05hbWUoKSk7DQorICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGlnbm9yZSkgew0KKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIHwgTGlua2FnZUVycm9yIGlnbm9yZSkgew0KKyAgICAgICAgfQ0KKyAgICAgICAgcmV0dXJuIHMuZ2V0Q2xhc3NOYW1lKCkuc3RhcnRzV2l0aCgiamF2YS5sYW5nLnJlZmxlY3QuIikNCisgICAgICAgICAgICAgICAgfHwgcy5nZXRDbGFzc05hbWUoKS5zdGFydHNXaXRoKCJzdW4ucmVmbGVjdC4iKTsNCisgICAgfQ0KKw0KKyAgICAvKioNCisgICAgICogQ3JlYXRlcyB0aGUgZm9ybWF0IHBhdHRlcm4gZm9yIHRoaXMgZm9ybWF0dGVyLg0KKyAgICAgKg0KKyAgICAgKiBAcGFyYW0gcCB0aGUgY2xhc3MgbmFtZSBwcmVmaXguDQorICAgICAqIEByZXR1cm4gdGhlIGphdmEudXRpbC5Gb3JtYXR0ZXIgZm9ybWF0IHN0cmluZy4NCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgZ2l2ZW4gY2xhc3MgbmFtZSBpcyBudWxsLg0KKyAgICAgKi8NCisgICAgcHJpdmF0ZSBTdHJpbmcgaW5pdEZvcm1hdChmaW5hbCBTdHJpbmcgcCkgew0KKyAgICAgICAgU3RyaW5nIHYgPSBMb2dNYW5hZ2VyUHJvcGVydGllcy5mcm9tTG9nTWFuYWdlcihwLmNvbmNhdCgiLmZvcm1hdCIpKTsNCisgICAgICAgIGlmIChpc051bGxPclNwYWNlcyh2KSkgew0KKyAgICAgICAgICAgIHYgPSAiJTckIy4xNjBzJW4iOyAvLzE2MCBjaGFycyBzcGxpdCBiZXR3ZWVuIG1lc3NhZ2UgYW5kIHRocm93bi4NCisgICAgICAgIH0NCisgICAgICAgIHJldHVybiB2Ow0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBTZWFyY2hlcyB0aGUgZ2l2ZW4gbWVzc2FnZSBmb3IgYWxsIGluc3RhbmNlcyBmdWxseSBxdWFsaWZpZWQgY2xhc3MgbmFtZQ0KKyAgICAgKiB3aXRoIHNpbXBsZSBjbGFzcyBuYW1lIGJhc2VkIG9mZiBvZiB0aGUgdHlwZXMgY29udGFpbmVkIGluIHRoZSBnaXZlbg0KKyAgICAgKiBwYXJhbWV0ZXIgYXJyYXkuDQorICAgICAqDQorICAgICAqIEBwYXJhbSBtc2cgdGhlIG1lc3NhZ2UuDQorICAgICAqIEBwYXJhbSB0IHRoZSB0aHJvd2FibGUgY2F1c2UgY2hhaW4gdG8gc2VhcmNoIG9yIG51bGwuDQorICAgICAqIEByZXR1cm4gdGhlIG1vZGlmaWVkIG1lc3NhZ2Ugc3RyaW5nLg0KKyAgICAgKi8NCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIHJlcGxhY2VDbGFzc05hbWUoU3RyaW5nIG1zZywgVGhyb3dhYmxlIHQpIHsNCisgICAgICAgIGlmICghaXNOdWxsT3JTcGFjZXMobXNnKSkgew0KKyAgICAgICAgICAgIGludCBsaW1pdCA9IDA7DQorICAgICAgICAgICAgZm9yIChUaHJvd2FibGUgYyA9IHQ7IGMgIT0gbnVsbDsgYyA9IGMuZ2V0Q2F1c2UoKSkgew0KKyAgICAgICAgICAgICAgICBmaW5hbCBDbGFzczw/PiBrID0gYy5nZXRDbGFzcygpOw0KKyAgICAgICAgICAgICAgICBtc2cgPSBtc2cucmVwbGFjZShrLmdldE5hbWUoKSwgc2ltcGxlQ2xhc3NOYW1lKGspKTsNCisNCisgICAgICAgICAgICAgICAgLy9EZWFsIHdpdGggZXhjZXNzaXZlIGNhdXNlIGNoYWlucyBhbmQgY3ljbGljIHRocm93YWJsZXMuDQorICAgICAgICAgICAgICAgIGlmICgrK2xpbWl0ID09ICgxIDw8IDE2KSkgew0KKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7IC8vR2l2ZSB1cC4NCisgICAgICAgICAgICAgICAgfQ0KKyAgICAgICAgICAgIH0NCisgICAgICAgIH0NCisgICAgICAgIHJldHVybiBtc2c7DQorICAgIH0NCisNCisgICAgLyoqDQorICAgICAqIFNlYXJjaGVzIHRoZSBnaXZlbiBtZXNzYWdlIGZvciBhbGwgaW5zdGFuY2VzIGZ1bGx5IHF1YWxpZmllZCBjbGFzcyBuYW1lDQorICAgICAqIHdpdGggc2ltcGxlIGNsYXNzIG5hbWUgYmFzZWQgb2ZmIG9mIHRoZSB0eXBlcyBjb250YWluZWQgaW4gdGhlIGdpdmVuDQorICAgICAqIHBhcmFtZXRlciBhcnJheS4NCisgICAgICoNCisgICAgICogQHBhcmFtIG1zZyB0aGUgbWVzc2FnZSBvciBudWxsLg0KKyAgICAgKiBAcGFyYW0gcCB0aGUgcGFyYW1ldGVyIGFycmF5IG9yIG51bGwuDQorICAgICAqIEByZXR1cm4gdGhlIG1vZGlmaWVkIG1lc3NhZ2Ugc3RyaW5nLg0KKyAgICAgKi8NCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIHJlcGxhY2VDbGFzc05hbWUoU3RyaW5nIG1zZywgT2JqZWN0W10gcCkgew0KKyAgICAgICAgaWYgKCFpc051bGxPclNwYWNlcyhtc2cpICYmIHAgIT0gbnVsbCkgew0KKyAgICAgICAgICAgIGZvciAoT2JqZWN0IG8gOiBwKSB7DQorICAgICAgICAgICAgICAgIGlmIChvICE9IG51bGwpIHsNCisgICAgICAgICAgICAgICAgICAgIGZpbmFsIENsYXNzPD8+IGsgPSBvLmdldENsYXNzKCk7DQorICAgICAgICAgICAgICAgICAgICBtc2cgPSBtc2cucmVwbGFjZShrLmdldE5hbWUoKSwgc2ltcGxlQ2xhc3NOYW1lKGspKTsNCisgICAgICAgICAgICAgICAgfQ0KKyAgICAgICAgICAgIH0NCisgICAgICAgIH0NCisgICAgICAgIHJldHVybiBtc2c7DQorICAgIH0NCisNCisgICAgLyoqDQorICAgICAqIEdldHMgdGhlIHNpbXBsZSBjbGFzcyBuYW1lIGZyb20gdGhlIGdpdmVuIGNsYXNzLiBUaGlzIGlzIGEgd29ya2Fyb3VuZCBmb3INCisgICAgICogQlVHIElEIEpESy04MDU3OTE5Lg0KKyAgICAgKg0KKyAgICAgKiBAcGFyYW0gayB0aGUgY2xhc3Mgb2JqZWN0Lg0KKyAgICAgKiBAcmV0dXJuIHRoZSBzaW1wbGUgY2xhc3MgbmFtZSBvciBudWxsLg0KKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS41LjMNCisgICAgICovDQorICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBzaW1wbGVDbGFzc05hbWUoZmluYWwgQ2xhc3M8Pz4gaykgew0KKyAgICAgICAgdHJ5IHsNCisgICAgICAgICAgICByZXR1cm4gay5nZXRTaW1wbGVOYW1lKCk7DQorICAgICAgICB9IGNhdGNoIChmaW5hbCBJbnRlcm5hbEVycm9yIEpESzgwNTc5MTkpIHsNCisgICAgICAgIH0NCisgICAgICAgIHJldHVybiBzaW1wbGVDbGFzc05hbWUoay5nZXROYW1lKCkpOw0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBDb252ZXJ0cyBhIGZ1bGx5IHF1YWxpZmllZCBjbGFzcyBuYW1lIHRvIGEgc2ltcGxlIGNsYXNzIG5hbWUuIElmIHRoZQ0KKyAgICAgKiBsZWFkaW5nIHBhcnQgb2YgdGhlIGdpdmVuIHN0cmluZyBpcyBub3QgYSBsZWdhbCBjbGFzcyBuYW1lIHRoZW4gdGhlIGdpdmVuDQorICAgICAqIHN0cmluZyBpcyByZXR1cm5lZC4NCisgICAgICoNCisgICAgICogQHBhcmFtIG5hbWUgdGhlIGZ1bGx5IHF1YWxpZmllZCBjbGFzcyBuYW1lIHByZWZpeCBvciBudWxsLg0KKyAgICAgKiBAcmV0dXJuIHRoZSBzaW1wbGUgY2xhc3MgbmFtZSBvciBnaXZlbiBpbnB1dC4NCisgICAgICovDQorICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBzaW1wbGVDbGFzc05hbWUoU3RyaW5nIG5hbWUpIHsNCisgICAgICAgIGlmIChuYW1lICE9IG51bGwpIHsNCisgICAgICAgICAgICBpbnQgY3Vyc29yID0gMDsNCisgICAgICAgICAgICBpbnQgc2lnbiA9IC0xOw0KKyAgICAgICAgICAgIGludCBkb3QgPSAtMTsNCisgICAgICAgICAgICBmb3IgKGludCBjLCBwcmV2ID0gZG90OyBjdXJzb3IgPCBuYW1lLmxlbmd0aCgpOw0KKyAgICAgICAgICAgICAgICAgICAgY3Vyc29yICs9IENoYXJhY3Rlci5jaGFyQ291bnQoYykpIHsNCisgICAgICAgICAgICAgICAgYyA9IG5hbWUuY29kZVBvaW50QXQoY3Vyc29yKTsNCisgICAgICAgICAgICAgICAgaWYgKCFDaGFyYWN0ZXIuaXNKYXZhSWRlbnRpZmllclBhcnQoYykpIHsNCisgICAgICAgICAgICAgICAgICAgIGlmIChjID09ICgoaW50KSAnLicpKSB7DQorICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChkb3QgKyAxKSAhPSBjdXJzb3IgJiYgKGRvdCArIDEpICE9IHNpZ24pIHsNCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJldiA9IGRvdDsNCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG90ID0gY3Vyc29yOw0KKyAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7DQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuYW1lOw0KKyAgICAgICAgICAgICAgICAgICAgICAgIH0NCisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7DQorICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChkb3QgKyAxKSA9PSBjdXJzb3IpIHsNCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG90ID0gcHJldjsNCisgICAgICAgICAgICAgICAgICAgICAgICB9DQorICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQorICAgICAgICAgICAgICAgICAgICB9DQorICAgICAgICAgICAgICAgIH0gZWxzZSB7DQorICAgICAgICAgICAgICAgICAgICBpZiAoYyA9PSAoKGludCkgJyQnKSkgew0KKyAgICAgICAgICAgICAgICAgICAgICAgIHNpZ24gPSBjdXJzb3I7DQorICAgICAgICAgICAgICAgICAgICB9DQorICAgICAgICAgICAgICAgIH0NCisgICAgICAgICAgICB9DQorDQorICAgICAgICAgICAgaWYgKGRvdCA+IC0xICYmICsrZG90IDwgY3Vyc29yICYmICsrc2lnbiA8IGN1cnNvcikgew0KKyAgICAgICAgICAgICAgICBuYW1lID0gbmFtZS5zdWJzdHJpbmcoc2lnbiA+IGRvdCA/IHNpZ24gOiBkb3QpOw0KKyAgICAgICAgICAgIH0NCisgICAgICAgIH0NCisgICAgICAgIHJldHVybiBuYW1lOw0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBDb252ZXJ0cyBhIGZpbGUgbmFtZSB3aXRoIGFuIGV4dGVuc2lvbiB0byBhIGZpbGUgbmFtZSB3aXRob3V0IGFuDQorICAgICAqIGV4dGVuc2lvbi4NCisgICAgICoNCisgICAgICogQHBhcmFtIG5hbWUgdGhlIGZ1bGwgZmlsZSBuYW1lIG9yIG51bGwuDQorICAgICAqIEByZXR1cm4gdGhlIHNpbXBsZSBmaWxlIG5hbWUgb3IgbnVsbC4NCisgICAgICovDQorICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBzaW1wbGVGaWxlTmFtZShTdHJpbmcgbmFtZSkgew0KKyAgICAgICAgaWYgKG5hbWUgIT0gbnVsbCkgew0KKyAgICAgICAgICAgIGZpbmFsIGludCBpbmRleCA9IG5hbWUubGFzdEluZGV4T2YoJy4nKTsNCisgICAgICAgICAgICBuYW1lID0gaW5kZXggPiAtMSA/IG5hbWUuc3Vic3RyaW5nKDAsIGluZGV4KSA6IG5hbWU7DQorICAgICAgICB9DQorICAgICAgICByZXR1cm4gbmFtZTsNCisgICAgfQ0KKw0KKyAgICAvKioNCisgICAgICogRGV0ZXJtaW5lcyBpcyB0aGUgZ2l2ZW4gc3RyaW5nIGlzIG51bGwgb3Igc3BhY2VzLg0KKyAgICAgKg0KKyAgICAgKiBAcGFyYW0gcyB0aGUgc3RyaW5nIG9yIG51bGwuDQorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBudWxsIG9yIHNwYWNlcy4NCisgICAgICovDQorICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNOdWxsT3JTcGFjZXMoZmluYWwgU3RyaW5nIHMpIHsNCisgICAgICAgIHJldHVybiBzID09IG51bGwgfHwgcy50cmltKCkubGVuZ3RoKCkgPT0gMDsNCisgICAgfQ0KKw0KKyAgICAvKioNCisgICAgICogVXNlZCB0byBmb3JtYXQgdHdvIGFyZ3VtZW50cyBhcyBmaXhlZCBsZW5ndGggbWVzc2FnZS4NCisgICAgICovDQorICAgIHByaXZhdGUgY2xhc3MgQWx0ZXJuYXRlIGltcGxlbWVudHMgamF2YS51dGlsLkZvcm1hdHRhYmxlIHsNCisNCisgICAgICAgIC8qKg0KKyAgICAgICAgICogVGhlIGxlZnQgc2lkZSBvZiB0aGUgb3V0cHV0Lg0KKyAgICAgICAgICovDQorICAgICAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBsZWZ0Ow0KKyAgICAgICAgLyoqDQorICAgICAgICAgKiBUaGUgcmlnaHQgc2lkZSBvZiB0aGUgb3V0cHV0Lg0KKyAgICAgICAgICovDQorICAgICAgICBwcml2YXRlIGZpbmFsIFN0cmluZyByaWdodDsNCisNCisgICAgICAgIC8qKg0KKyAgICAgICAgICogQ3JlYXRlcyBhbiBhbHRlcm5hdGUgb3V0cHV0Lg0KKyAgICAgICAgICoNCisgICAgICAgICAqIEBwYXJhbSBsZWZ0IHRoZSBsZWZ0IHNpZGUgb3IgbnVsbC4NCisgICAgICAgICAqIEBwYXJhbSByaWdodCB0aGUgcmlnaHQgc2lkZSBvciBudWxsLg0KKyAgICAgICAgICovDQorICAgICAgICBBbHRlcm5hdGUoZmluYWwgU3RyaW5nIGxlZnQsIGZpbmFsIFN0cmluZyByaWdodCkgew0KKyAgICAgICAgICAgIHRoaXMubGVmdCA9IFN0cmluZy52YWx1ZU9mKGxlZnQpOw0KKyAgICAgICAgICAgIHRoaXMucmlnaHQgPSBTdHJpbmcudmFsdWVPZihyaWdodCk7DQorICAgICAgICB9DQorDQorICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygib3ZlcnJpZGUiKSAvL0pESy02OTU0MjM0DQorICAgICAgICBwdWJsaWMgdm9pZCBmb3JtYXRUbyhqYXZhLnV0aWwuRm9ybWF0dGVyIGZvcm1hdHRlciwgaW50IGZsYWdzLA0KKyAgICAgICAgICAgICAgICBpbnQgd2lkdGgsIGludCBwcmVjaXNpb24pIHsNCisNCisgICAgICAgICAgICBTdHJpbmcgbCA9IGxlZnQ7DQorICAgICAgICAgICAgU3RyaW5nIHIgPSByaWdodDsNCisgICAgICAgICAgICBpZiAoKGZsYWdzICYgamF2YS51dGlsLkZvcm1hdHRhYmxlRmxhZ3MuVVBQRVJDQVNFKQ0KKyAgICAgICAgICAgICAgICAgICAgPT0gamF2YS51dGlsLkZvcm1hdHRhYmxlRmxhZ3MuVVBQRVJDQVNFKSB7DQorICAgICAgICAgICAgICAgIGwgPSBsLnRvVXBwZXJDYXNlKGZvcm1hdHRlci5sb2NhbGUoKSk7DQorICAgICAgICAgICAgICAgIHIgPSByLnRvVXBwZXJDYXNlKGZvcm1hdHRlci5sb2NhbGUoKSk7DQorICAgICAgICAgICAgfQ0KKw0KKyAgICAgICAgICAgIGlmICgoZmxhZ3MgJiBqYXZhLnV0aWwuRm9ybWF0dGFibGVGbGFncy5BTFRFUk5BVEUpDQorICAgICAgICAgICAgICAgICAgICA9PSBqYXZhLnV0aWwuRm9ybWF0dGFibGVGbGFncy5BTFRFUk5BVEUpIHsNCisgICAgICAgICAgICAgICAgbCA9IHRvQWx0ZXJuYXRlKGwpOw0KKyAgICAgICAgICAgICAgICByID0gdG9BbHRlcm5hdGUocik7DQorICAgICAgICAgICAgfQ0KKw0KKyAgICAgICAgICAgIGlmIChwcmVjaXNpb24gPD0gMCkgew0KKyAgICAgICAgICAgICAgICBwcmVjaXNpb24gPSBJbnRlZ2VyLk1BWF9WQUxVRTsNCisgICAgICAgICAgICB9DQorDQorICAgICAgICAgICAgaW50IGZlbmNlID0gTWF0aC5taW4obC5sZW5ndGgoKSwgcHJlY2lzaW9uKTsNCisgICAgICAgICAgICBpZiAoZmVuY2UgPiAocHJlY2lzaW9uID4+IDEpKSB7DQorICAgICAgICAgICAgICAgIGZlbmNlID0gTWF0aC5tYXgoZmVuY2UgLSByLmxlbmd0aCgpLCBmZW5jZSA+PiAxKTsNCisgICAgICAgICAgICB9DQorDQorICAgICAgICAgICAgaWYgKGZlbmNlID4gMCkgew0KKyAgICAgICAgICAgICAgICBpZiAoZmVuY2UgPiBsLmxlbmd0aCgpDQorICAgICAgICAgICAgICAgICAgICAgICAgJiYgQ2hhcmFjdGVyLmlzSGlnaFN1cnJvZ2F0ZShsLmNoYXJBdChmZW5jZSAtIDEpKSkgew0KKyAgICAgICAgICAgICAgICAgICAgLS1mZW5jZTsNCisgICAgICAgICAgICAgICAgfQ0KKyAgICAgICAgICAgICAgICBsID0gbC5zdWJzdHJpbmcoMCwgZmVuY2UpOw0KKyAgICAgICAgICAgIH0NCisgICAgICAgICAgICByID0gci5zdWJzdHJpbmcoMCwgTWF0aC5taW4ocHJlY2lzaW9uIC0gZmVuY2UsIHIubGVuZ3RoKCkpKTsNCisNCisgICAgICAgICAgICBpZiAod2lkdGggPiAwKSB7DQorICAgICAgICAgICAgICAgIGZpbmFsIGludCBoYWxmID0gd2lkdGggPj4gMTsNCisgICAgICAgICAgICAgICAgaWYgKGwubGVuZ3RoKCkgPCBoYWxmKSB7DQorICAgICAgICAgICAgICAgICAgICBsID0gcGFkKGZsYWdzLCBsLCBoYWxmKTsNCisgICAgICAgICAgICAgICAgfQ0KKw0KKyAgICAgICAgICAgICAgICBpZiAoci5sZW5ndGgoKSA8IGhhbGYpIHsNCisgICAgICAgICAgICAgICAgICAgIHIgPSBwYWQoZmxhZ3MsIHIsIGhhbGYpOw0KKyAgICAgICAgICAgICAgICB9DQorICAgICAgICAgICAgfQ0KKw0KKyAgICAgICAgICAgIE9iamVjdFtdIGVtcHR5ID0gQ29sbGVjdGlvbnMuZW1wdHlTZXQoKS50b0FycmF5KCk7DQorICAgICAgICAgICAgZm9ybWF0dGVyLmZvcm1hdChsLCBlbXB0eSk7DQorICAgICAgICAgICAgaWYgKGwubGVuZ3RoKCkgIT0gMCAmJiByLmxlbmd0aCgpICE9IDApIHsNCisgICAgICAgICAgICAgICAgZm9ybWF0dGVyLmZvcm1hdCgifCIsIGVtcHR5KTsNCisgICAgICAgICAgICB9DQorICAgICAgICAgICAgZm9ybWF0dGVyLmZvcm1hdChyLCBlbXB0eSk7DQorICAgICAgICB9DQorDQorICAgICAgICAvKioNCisgICAgICAgICAqIFBhZCB0aGUgZ2l2ZW4gaW5wdXQgc3RyaW5nLg0KKyAgICAgICAgICoNCisgICAgICAgICAqIEBwYXJhbSBmbGFncyB0aGUgZm9ybWF0dGVyIGZsYWdzLg0KKyAgICAgICAgICogQHBhcmFtIHMgdGhlIHN0cmluZyB0byBwYWQuDQorICAgICAgICAgKiBAcGFyYW0gbGVuZ3RoIHRoZSBmaW5hbCBzdHJpbmcgbGVuZ3RoLg0KKyAgICAgICAgICogQHJldHVybiB0aGUgcGFkZGVkIHN0cmluZy4NCisgICAgICAgICAqLw0KKyAgICAgICAgcHJpdmF0ZSBTdHJpbmcgcGFkKGludCBmbGFncywgU3RyaW5nIHMsIGludCBsZW5ndGgpIHsNCisgICAgICAgICAgICBmaW5hbCBpbnQgcGFkZGluZyA9IGxlbmd0aCAtIHMubGVuZ3RoKCk7DQorICAgICAgICAgICAgZmluYWwgU3RyaW5nQnVpbGRlciBiID0gbmV3IFN0cmluZ0J1aWxkZXIobGVuZ3RoKTsNCisgICAgICAgICAgICBpZiAoKGZsYWdzICYgamF2YS51dGlsLkZvcm1hdHRhYmxlRmxhZ3MuTEVGVF9KVVNUSUZZKQ0KKyAgICAgICAgICAgICAgICAgICAgPT0gamF2YS51dGlsLkZvcm1hdHRhYmxlRmxhZ3MuTEVGVF9KVVNUSUZZKSB7DQorICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFkZGluZzsgKytpKSB7DQorICAgICAgICAgICAgICAgICAgICBiLmFwcGVuZCgnXHUwMDIwJyk7DQorICAgICAgICAgICAgICAgIH0NCisgICAgICAgICAgICAgICAgYi5hcHBlbmQocyk7DQorICAgICAgICAgICAgfSBlbHNlIHsNCisgICAgICAgICAgICAgICAgYi5hcHBlbmQocyk7DQorICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFkZGluZzsgKytpKSB7DQorICAgICAgICAgICAgICAgICAgICBiLmFwcGVuZCgnXHUwMDIwJyk7DQorICAgICAgICAgICAgICAgIH0NCisgICAgICAgICAgICB9DQorICAgICAgICAgICAgcmV0dXJuIGIudG9TdHJpbmcoKTsNCisgICAgICAgIH0NCisgICAgfQ0KK30NCmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvbG9nZ2luZy9EdXJhdGlvbkZpbHRlci5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL2xvZ2dpbmcvRHVyYXRpb25GaWx0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kODY4MjI5Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL2xvZ2dpbmcvRHVyYXRpb25GaWx0ZXIuamF2YQpAQCAtMCwwICsxLDQ0NCBAQAorLyoNCisgKiBDb3B5cmlnaHQgKGMpIDIwMTUsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCisgKiBDb3B5cmlnaHQgKGMpIDIwMTUsIDIwMTggSmFzb24gTWVocmVucy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCisgKg0KKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQ0KKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0DQorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLg0KKyAqDQorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQ0KKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUNCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwNCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdA0KKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4NCisgKg0KKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMA0KKyAqLw0KK3BhY2thZ2UgY29tLnN1bi5tYWlsLnV0aWwubG9nZ2luZzsNCisNCitpbXBvcnQgc3RhdGljIGNvbS5zdW4ubWFpbC51dGlsLmxvZ2dpbmcuTG9nTWFuYWdlclByb3BlcnRpZXMuZnJvbUxvZ01hbmFnZXI7DQoraW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLio7DQorDQorLyoqDQorICogQSBmaWx0ZXIgdXNlZCB0byBsaW1pdCBsb2cgcmVjb3JkcyBiYXNlZCBvbiBhIG1heGltdW0gZ2VuZXJhdGlvbiByYXRlLg0KKyAqDQorICogVGhlIGR1cmF0aW9uIHNwZWNpZmllZCBpcyB1c2VkIHRvIGNvbXB1dGUgdGhlIHJlY29yZCByYXRlIGFuZCB0aGUgYW1vdW50IG9mDQorICogdGltZSB0aGUgZmlsdGVyIHdpbGwgcmVqZWN0IHJlY29yZHMgb25jZSB0aGUgcmF0ZSBoYXMgYmVlbiBleGNlZWRlZC4gT25jZSB0aGUNCisgKiByYXRlIGlzIGV4Y2VlZGVkIHJlY29yZHMgYXJlIG5vdCBhbGxvd2VkIHVudGlsIHRoZSBkdXJhdGlvbiBoYXMgZWxhcHNlZC4NCisgKg0KKyAqIDxwPg0KKyAqIEJ5IGRlZmF1bHQgZWFjaCB7QGNvZGUgRHVyYXRpb25GaWx0ZXJ9IGlzIGluaXRpYWxpemVkIHVzaW5nIHRoZSBmb2xsb3dpbmcNCisgKiBMb2dNYW5hZ2VyIGNvbmZpZ3VyYXRpb24gcHJvcGVydGllcyB3aGVyZSB7QGNvZGUgPGZpbHRlci1uYW1lPn0gcmVmZXJzIHRvIHRoZQ0KKyAqIGZ1bGx5IHF1YWxpZmllZCBjbGFzcyBuYW1lIG9mIHRoZSBoYW5kbGVyLiBJZiBwcm9wZXJ0aWVzIGFyZSBub3QgZGVmaW5lZCwgb3INCisgKiBjb250YWluIGludmFsaWQgdmFsdWVzLCB0aGVuIHRoZSBzcGVjaWZpZWQgZGVmYXVsdCB2YWx1ZXMgYXJlIHVzZWQuDQorICoNCisgKiA8dWw+DQorICogPGxpPntAbGl0ZXJhbCA8ZmlsdGVyLW5hbWU+fS5yZWNvcmRzIHRoZSBtYXggbnVtYmVyIG9mIHJlY29yZHMgcGVyIGR1cmF0aW9uLg0KKyAqIEEgbnVtZXJpYyBsb25nIGludGVnZXIgb3IgYSBtdWx0aXBsaWNhdGlvbiBleHByZXNzaW9uIGNhbiBiZSB1c2VkIGFzIHRoZQ0KKyAqIHZhbHVlLiAoZGVmYXVsdHMgdG8ge0Bjb2RlIDEwMDB9KQ0KKyAqDQorICogPGxpPntAbGl0ZXJhbCA8ZmlsdGVyLW5hbWU+fS5kdXJhdGlvbiB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0byBzdXBwcmVzcw0KKyAqIGxvZyByZWNvcmRzIGZyb20gYmVpbmcgcHVibGlzaGVkLiBUaGlzIGlzIGFsc28gdXNlZCBhcyBkdXJhdGlvbiB0byBkZXRlcm1pbmUNCisgKiB0aGUgbG9nIHJlY29yZCByYXRlLiBBIG51bWVyaWMgbG9uZyBpbnRlZ2VyIG9yIGEgbXVsdGlwbGljYXRpb24gZXhwcmVzc2lvbg0KKyAqIGNhbiBiZSB1c2VkIGFzIHRoZSB2YWx1ZS4gSWYgdGhlIHtAY29kZSBqYXZhLnRpbWV9IHBhY2thZ2UgaXMgYXZhaWxhYmxlIHRoZW4NCisgKiBhbiBJU08tODYwMSBkdXJhdGlvbiBmb3JtYXQgb2Yge0Bjb2RlIFBuRFRuSG5Nbi5uU30gY2FuIGJlIHVzZWQgYXMgdGhlIHZhbHVlLg0KKyAqIFRoZSBzdWZmaXhlcyBvZiAiRCIsICJIIiwgIk0iIGFuZCAiUyIgYXJlIGZvciBkYXlzLCBob3VycywgbWludXRlcyBhbmQNCisgKiBzZWNvbmRzLiBUaGUgc3VmZml4ZXMgbXVzdCBvY2N1ciBpbiBvcmRlci4gVGhlIHNlY29uZHMgY2FuIGJlIHNwZWNpZmllZCB3aXRoDQorICogYSBmcmFjdGlvbmFsIGNvbXBvbmVudCB0byBkZWNsYXJlIG1pbGxpc2Vjb25kcy4gKGRlZmF1bHRzIHRvIHtAY29kZSBQVDE1TX0pDQorICogPC91bD4NCisgKg0KKyAqIDxwPg0KKyAqIEZvciBleGFtcGxlLCB0aGUgc2V0dGluZ3MgdG8gbGltaXQge0Bjb2RlIE1haWxIYW5kbGVyfSB3aXRoIGEgZGVmYXVsdA0KKyAqIGNhcGFjaXR5IHRvIG9ubHkgc2VuZCBhIG1heGltdW0gb2YgdHdvIGVtYWlsIG1lc3NhZ2VzIGV2ZXJ5IHNpeCBtaW51dGVzIHdvdWxkDQorICogYmUgYXMgZm9sbG93czoNCisgKiA8cHJlPg0KKyAqIHtAY29kZQ0KKyAqICBjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nLk1haWxIYW5kbGVyLmZpbHRlciA9IGNvbS5zdW4ubWFpbC51dGlsLmxvZ2dpbmcuRHVyYXRpb25GaWx0ZXINCisgKiAgY29tLnN1bi5tYWlsLnV0aWwubG9nZ2luZy5NYWlsSGFuZGxlci5jYXBhY2l0eSA9IDEwMDANCisgKiAgY29tLnN1bi5tYWlsLnV0aWwubG9nZ2luZy5EdXJhdGlvbkZpbHRlci5yZWNvcmRzID0gMkwgKiAxMDAwTA0KKyAqICBjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nLkR1cmF0aW9uRmlsdGVyLmR1cmF0aW9uID0gUFQ2TQ0KKyAqIH0NCisgKiA8L3ByZT4NCisgKg0KKyAqDQorICogQGF1dGhvciBKYXNvbiBNZWhyZW5zDQorICogQHNpbmNlIEphdmFNYWlsIDEuNS41DQorICovDQorcHVibGljIGNsYXNzIER1cmF0aW9uRmlsdGVyIGltcGxlbWVudHMgRmlsdGVyIHsNCisNCisgICAgLyoqDQorICAgICAqIFRoZSBudW1iZXIgb2YgZXhwZWN0ZWQgcmVjb3JkcyBwZXIgZHVyYXRpb24uDQorICAgICAqLw0KKyAgICBwcml2YXRlIGZpbmFsIGxvbmcgcmVjb3JkczsNCisgICAgLyoqDQorICAgICAqIFRoZSBkdXJhdGlvbiBpbiBtaWxsaXNlY29uZHMgdXNlZCB0byBkZXRlcm1pbmUgdGhlIHJhdGUuIFRoZSBkdXJhdGlvbiBpcw0KKyAgICAgKiBhbHNvIHVzZWQgYXMgdGhlIGFtb3VudCBvZiB0aW1lIHRoYXQgdGhlIGZpbHRlciB3aWxsIG5vdCBhbGxvdyByZWNvcmRzDQorICAgICAqIHdoZW4gc2F0dXJhdGVkLg0KKyAgICAgKi8NCisgICAgcHJpdmF0ZSBmaW5hbCBsb25nIGR1cmF0aW9uOw0KKyAgICAvKioNCisgICAgICogVGhlIG51bWJlciBvZiByZWNvcmRzIHNlZW4gZm9yIHRoZSBjdXJyZW50IGR1cmF0aW9uLiBUaGlzIHZhbHVlIG5lZ2F0aXZlDQorICAgICAqIGlmIHNhdHVyYXRlZC4gWmVybyBpcyBjb25zaWRlcmVkIHNhdHVyYXRlZCBidXQgaXMgcmVzZXJ2ZWQgZm9yIHJlY29yZGluZw0KKyAgICAgKiB0aGUgZmlyc3QgZHVyYXRpb24uDQorICAgICAqLw0KKyAgICBwcml2YXRlIGxvbmcgY291bnQ7DQorICAgIC8qKg0KKyAgICAgKiBUaGUgbW9zdCByZWNlbnQgcmVjb3JkIHRpbWUgc2VlbiBmb3IgdGhlIGN1cnJlbnQgZHVyYXRpb24uDQorICAgICAqLw0KKyAgICBwcml2YXRlIGxvbmcgcGVhazsNCisgICAgLyoqDQorICAgICAqIFRoZSBzdGFydCB0aW1lIGZvciB0aGUgY3VycmVudCBkdXJhdGlvbi4NCisgICAgICovDQorICAgIHByaXZhdGUgbG9uZyBzdGFydDsNCisNCisgICAgLyoqDQorICAgICAqIENyZWF0ZXMgdGhlIGZpbHRlciB1c2luZyB0aGUgZGVmYXVsdCBwcm9wZXJ0aWVzLg0KKyAgICAgKi8NCisgICAgcHVibGljIER1cmF0aW9uRmlsdGVyKCkgew0KKyAgICAgICAgdGhpcy5yZWNvcmRzID0gY2hlY2tSZWNvcmRzKGluaXRMb25nKCIucmVjb3JkcyIpKTsNCisgICAgICAgIHRoaXMuZHVyYXRpb24gPSBjaGVja0R1cmF0aW9uKGluaXRMb25nKCIuZHVyYXRpb24iKSk7DQorICAgIH0NCisNCisgICAgLyoqDQorICAgICAqIENyZWF0ZXMgdGhlIGZpbHRlciB1c2luZyB0aGUgZ2l2ZW4gcHJvcGVydGllcy4gRGVmYXVsdCB2YWx1ZXMgYXJlIHVzZWQgaWYNCisgICAgICogYW55IG9mIHRoZSBnaXZlbiB2YWx1ZXMgYXJlIG91dHNpZGUgdGhlIGFsbG93ZWQgcmFuZ2UuDQorICAgICAqDQorICAgICAqIEBwYXJhbSByZWNvcmRzIHRoZSBudW1iZXIgb2YgcmVjb3JkcyBwZXIgZHVyYXRpb24uDQorICAgICAqIEBwYXJhbSBkdXJhdGlvbiB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0byBzdXBwcmVzcyBsb2cgcmVjb3JkcyBmcm9tDQorICAgICAqIGJlaW5nIHB1Ymxpc2hlZC4NCisgICAgICovDQorICAgIHB1YmxpYyBEdXJhdGlvbkZpbHRlcihmaW5hbCBsb25nIHJlY29yZHMsIGZpbmFsIGxvbmcgZHVyYXRpb24pIHsNCisgICAgICAgIHRoaXMucmVjb3JkcyA9IGNoZWNrUmVjb3JkcyhyZWNvcmRzKTsNCisgICAgICAgIHRoaXMuZHVyYXRpb24gPSBjaGVja0R1cmF0aW9uKGR1cmF0aW9uKTsNCisgICAgfQ0KKw0KKyAgICAvKioNCisgICAgICogRGV0ZXJtaW5lcyBpZiB0aGlzIGZpbHRlciBpcyBlcXVhbCB0byBhbm90aGVyIGZpbHRlci4NCisgICAgICoNCisgICAgICogQHBhcmFtIG9iaiB0aGUgZ2l2ZW4gb2JqZWN0Lg0KKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgZXF1YWwgb3RoZXJ3aXNlIGZhbHNlLg0KKyAgICAgKi8NCisgICAgQE92ZXJyaWRlDQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBPYmplY3Qgb2JqKSB7DQorICAgICAgICBpZiAodGhpcyA9PSBvYmopIHsgLy9Bdm9pZCBsb2NrcyBhbmQgZGVhbCB3aXRoIHJhcGlkIHN0YXRlIGNoYW5nZXMuDQorICAgICAgICAgICAgcmV0dXJuIHRydWU7DQorICAgICAgICB9DQorDQorICAgICAgICBpZiAob2JqID09IG51bGwgfHwgZ2V0Q2xhc3MoKSAhPSBvYmouZ2V0Q2xhc3MoKSkgew0KKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsNCisgICAgICAgIH0NCisNCisgICAgICAgIGZpbmFsIER1cmF0aW9uRmlsdGVyIG90aGVyID0gKER1cmF0aW9uRmlsdGVyKSBvYmo7DQorICAgICAgICBpZiAodGhpcy5yZWNvcmRzICE9IG90aGVyLnJlY29yZHMpIHsNCisgICAgICAgICAgICByZXR1cm4gZmFsc2U7DQorICAgICAgICB9DQorDQorICAgICAgICBpZiAodGhpcy5kdXJhdGlvbiAhPSBvdGhlci5kdXJhdGlvbikgew0KKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsNCisgICAgICAgIH0NCisNCisgICAgICAgIGZpbmFsIGxvbmcgYzsNCisgICAgICAgIGZpbmFsIGxvbmcgcDsNCisgICAgICAgIGZpbmFsIGxvbmcgczsNCisgICAgICAgIHN5bmNocm9uaXplZCAodGhpcykgew0KKyAgICAgICAgICAgIGMgPSB0aGlzLmNvdW50Ow0KKyAgICAgICAgICAgIHAgPSB0aGlzLnBlYWs7DQorICAgICAgICAgICAgcyA9IHRoaXMuc3RhcnQ7DQorICAgICAgICB9DQorDQorICAgICAgICBzeW5jaHJvbml6ZWQgKG90aGVyKSB7DQorICAgICAgICAgICAgaWYgKGMgIT0gb3RoZXIuY291bnQgfHwgcCAhPSBvdGhlci5wZWFrIHx8IHMgIT0gb3RoZXIuc3RhcnQpIHsNCisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOw0KKyAgICAgICAgICAgIH0NCisgICAgICAgIH0NCisgICAgICAgIHJldHVybiB0cnVlOw0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBEZXRlcm1pbmVzIGlmIHRoaXMgZmlsdGVyIGlzIGFibGUgdG8gYWNjZXB0IHRoZSBtYXhpbXVtIG51bWJlciBvZiBsb2cNCisgICAgICogcmVjb3JkcyBmb3IgdGhpcyBpbnN0YW50IGluIHRpbWUuIFRoZSByZXN1bHQgaXMgYSBiZXN0LWVmZm9ydCBlc3RpbWF0ZQ0KKyAgICAgKiBhbmQgc2hvdWxkIGJlIGNvbnNpZGVyZWQgb3V0IG9mIGRhdGUgYXMgc29vbiBhcyBpdCBpcyBwcm9kdWNlZC4gVGhpcw0KKyAgICAgKiBtZXRob2QgaXMgZGVzaWduZWQgZm9yIHVzZSBpbiBtb25pdG9yaW5nIHRoZSBzdGF0ZSBvZiB0aGlzIGZpbHRlci4NCisgICAgICoNCisgICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBmaWx0ZXIgaXMgaWRsZTsgZmFsc2Ugb3RoZXJ3aXNlLg0KKyAgICAgKi8NCisgICAgcHVibGljIGJvb2xlYW4gaXNJZGxlKCkgew0KKyAgICAgICAgcmV0dXJuIHRlc3QoMEwsIFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpKTsNCisgICAgfQ0KKw0KKyAgICAvKioNCisgICAgICogUmV0dXJucyBhIGhhc2ggY29kZSB2YWx1ZSBmb3IgdGhpcyBmaWx0ZXIuDQorICAgICAqDQorICAgICAqIEByZXR1cm4gaGFzaCBjb2RlIGZvciB0aGlzIGZpbHRlci4NCisgICAgICovDQorICAgIEBPdmVycmlkZQ0KKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgew0KKyAgICAgICAgaW50IGhhc2ggPSAzOw0KKyAgICAgICAgaGFzaCA9IDg5ICogaGFzaCArIChpbnQpICh0aGlzLnJlY29yZHMgXiAodGhpcy5yZWNvcmRzID4+PiAzMikpOw0KKyAgICAgICAgaGFzaCA9IDg5ICogaGFzaCArIChpbnQpICh0aGlzLmR1cmF0aW9uIF4gKHRoaXMuZHVyYXRpb24gPj4+IDMyKSk7DQorICAgICAgICByZXR1cm4gaGFzaDsNCisgICAgfQ0KKw0KKyAgICAvKioNCisgICAgICogQ2hlY2sgaWYgdGhlIGdpdmVuIGxvZyByZWNvcmQgc2hvdWxkIGJlIHB1Ymxpc2hlZC4gVGhpcyBtZXRob2Qgd2lsbA0KKyAgICAgKiBtb2RpZnkgdGhlIGludGVybmFsIHN0YXRlIG9mIHRoaXMgZmlsdGVyLg0KKyAgICAgKg0KKyAgICAgKiBAcGFyYW0gcmVjb3JkIHRoZSBsb2cgcmVjb3JkIHRvIGNoZWNrLg0KKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgYWxsb3dlZDsgZmFsc2Ugb3RoZXJ3aXNlLg0KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIGdpdmVuIHJlY29yZCBpcyBudWxsLg0KKyAgICAgKi8NCisgICAgQFN1cHByZXNzV2FybmluZ3MoIm92ZXJyaWRlIikgLy9KREstNjk1NDIzNA0KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0xvZ2dhYmxlKGZpbmFsIExvZ1JlY29yZCByZWNvcmQpIHsNCisgICAgICAgIHJldHVybiBhY2NlcHQocmVjb3JkLmdldE1pbGxpcygpKTsNCisgICAgfQ0KKw0KKyAgICAvKioNCisgICAgICogRGV0ZXJtaW5lcyBpZiB0aGlzIGZpbHRlciB3aWxsIGFjY2VwdCBsb2cgcmVjb3JkcyBmb3IgdGhpcyBpbnN0YW50IGluDQorICAgICAqIHRpbWUuIFRoZSByZXN1bHQgaXMgYSBiZXN0LWVmZm9ydCBlc3RpbWF0ZSBhbmQgc2hvdWxkIGJlIGNvbnNpZGVyZWQgb3V0DQorICAgICAqIG9mIGRhdGUgYXMgc29vbiBhcyBpdCBpcyBwcm9kdWNlZC4gVGhpcyBtZXRob2QgaXMgZGVzaWduZWQgZm9yIHVzZSBpbg0KKyAgICAgKiBtb25pdG9yaW5nIHRoZSBzdGF0ZSBvZiB0aGlzIGZpbHRlci4NCisgICAgICoNCisgICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBmaWx0ZXIgaXMgbm90IHNhdHVyYXRlZDsgZmFsc2Ugb3RoZXJ3aXNlLg0KKyAgICAgKi8NCisgICAgcHVibGljIGJvb2xlYW4gaXNMb2dnYWJsZSgpIHsNCisgICAgICAgIHJldHVybiB0ZXN0KHJlY29yZHMsIFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpKTsNCisgICAgfQ0KKw0KKyAgICAvKioNCisgICAgICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIGZpbHRlci4gVGhlIHJlc3VsdCBpcyBhDQorICAgICAqIGJlc3QtZWZmb3J0IGVzdGltYXRlIGFuZCBzaG91bGQgYmUgY29uc2lkZXJlZCBvdXQgb2YgZGF0ZSBhcyBzb29uIGFzIGl0DQorICAgICAqIGlzIHByb2R1Y2VkLg0KKyAgICAgKg0KKyAgICAgKiBAcmV0dXJuIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgZmlsdGVyLg0KKyAgICAgKi8NCisgICAgQE92ZXJyaWRlDQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7DQorICAgICAgICBib29sZWFuIGlkbGU7DQorICAgICAgICBib29sZWFuIGxvZ2dhYmxlOw0KKyAgICAgICAgc3luY2hyb25pemVkICh0aGlzKSB7DQorICAgICAgICAgICAgZmluYWwgbG9uZyBtaWxsaXMgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsNCisgICAgICAgICAgICBpZGxlID0gdGVzdCgwTCwgbWlsbGlzKTsNCisgICAgICAgICAgICBsb2dnYWJsZSA9IHRlc3QocmVjb3JkcywgbWlsbGlzKTsNCisgICAgICAgIH0NCisNCisgICAgICAgIHJldHVybiBnZXRDbGFzcygpLmdldE5hbWUoKSArICJ7cmVjb3Jkcz0iICsgcmVjb3Jkcw0KKyAgICAgICAgICAgICAgICArICIsIGR1cmF0aW9uPSIgKyBkdXJhdGlvbg0KKyAgICAgICAgICAgICAgICArICIsIGlkbGU9IiArIGlkbGUNCisgICAgICAgICAgICAgICAgKyAiLCBsb2dnYWJsZT0iICsgbG9nZ2FibGUgKyAnfSc7DQorICAgIH0NCisNCisgICAgLyoqDQorICAgICAqIENyZWF0ZXMgYSBjb3B5IG9mIHRoaXMgZmlsdGVyIHRoYXQgcmV0YWlucyB0aGUgZmlsdGVyIHNldHRpbmdzIGJ1dCBkb2VzDQorICAgICAqIG5vdCBpbmNsdWRlIHRoZSBjdXJyZW50IGZpbHRlciBzdGF0ZS4gVGhlIG5ld2x5IGNyZWF0ZSBjbG9uZSBhY3RzIGFzIGlmDQorICAgICAqIGl0IGhhcyBuZXZlciBzZWVuIGFueSByZWNvcmRzLg0KKyAgICAgKg0KKyAgICAgKiBAcmV0dXJuIGEgY29weSBvZiB0aGlzIGZpbHRlci4NCisgICAgICogQHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBpZiB0aGlzIGZpbHRlciBpcyBub3QgYWxsb3dlZCB0byBiZQ0KKyAgICAgKiBjbG9uZWQuDQorICAgICAqLw0KKyAgICBAT3ZlcnJpZGUNCisgICAgcHJvdGVjdGVkIER1cmF0aW9uRmlsdGVyIGNsb25lKCkgdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsNCisgICAgICAgIGZpbmFsIER1cmF0aW9uRmlsdGVyIGNsb25lID0gKER1cmF0aW9uRmlsdGVyKSBzdXBlci5jbG9uZSgpOw0KKyAgICAgICAgY2xvbmUuY291bnQgPSAwTDsgLy9SZXNldCB0aGUgZmlsdGVyIHN0YXRlLg0KKyAgICAgICAgY2xvbmUucGVhayA9IDBMOw0KKyAgICAgICAgY2xvbmUuc3RhcnQgPSAwTDsNCisgICAgICAgIHJldHVybiBjbG9uZTsNCisgICAgfQ0KKw0KKyAgICAvKioNCisgICAgICogQ2hlY2tzIGlmIHRoaXMgZmlsdGVyIGlzIG5vdCBzYXR1cmF0ZWQgb3IgYmVsbG93IGEgbWF4aW11bSByYXRlLg0KKyAgICAgKg0KKyAgICAgKiBAcGFyYW0gbGltaXQgdGhlIG51bWJlciBvZiByZWNvcmRzIGFsbG93ZWQgdG8gYmUgdW5kZXIgdGhlIHJhdGUuDQorICAgICAqIEBwYXJhbSBtaWxsaXMgdGhlIGN1cnJlbnQgdGltZSBpbiBtaWxsaXNlY29uZHMuDQorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBub3Qgc2F0dXJhdGVkIG9yIGJlbGxvdyB0aGUgcmF0ZS4NCisgICAgICovDQorICAgIHByaXZhdGUgYm9vbGVhbiB0ZXN0KGZpbmFsIGxvbmcgbGltaXQsIGZpbmFsIGxvbmcgbWlsbGlzKSB7DQorICAgICAgICBhc3NlcnQgbGltaXQgPj0gMEwgOiBsaW1pdDsNCisgICAgICAgIGZpbmFsIGxvbmcgYzsNCisgICAgICAgIGZpbmFsIGxvbmcgczsNCisgICAgICAgIHN5bmNocm9uaXplZCAodGhpcykgew0KKyAgICAgICAgICAgIGMgPSBjb3VudDsNCisgICAgICAgICAgICBzID0gc3RhcnQ7DQorICAgICAgICB9DQorDQorICAgICAgICBpZiAoYyA+IDBMKSB7IC8vSWYgbm90IHNhdHVyYXRlZC4NCisgICAgICAgICAgICBpZiAoKG1pbGxpcyAtIHMpID49IGR1cmF0aW9uIHx8IGMgPCBsaW1pdCkgew0KKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsNCisgICAgICAgICAgICB9DQorICAgICAgICB9IGVsc2UgeyAgLy9TdWJ0cmFjdGlvbiBpcyB1c2VkIHRvIGRlYWwgd2l0aCBudW1lcmljIG92ZXJmbG93Lg0KKyAgICAgICAgICAgIGlmICgobWlsbGlzIC0gcykgPj0gMEwgfHwgYyA9PSAwTCkgew0KKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsNCisgICAgICAgICAgICB9DQorICAgICAgICB9DQorICAgICAgICByZXR1cm4gZmFsc2U7DQorICAgIH0NCisNCisgICAgLyoqDQorICAgICAqIERldGVybWluZXMgaWYgdGhlIHJlY29yZCBpcyBsb2dnYWJsZSBieSB0aW1lLg0KKyAgICAgKg0KKyAgICAgKiBAcGFyYW0gbWlsbGlzIHRoZSBsb2cgcmVjb3JkIG1pbGxpc2Vjb25kcy4NCisgICAgICogQHJldHVybiB0cnVlIGlmIGFjY2VwdGVkIGZhbHNlIG90aGVyd2lzZS4NCisgICAgICovDQorICAgIHByaXZhdGUgc3luY2hyb25pemVkIGJvb2xlYW4gYWNjZXB0KGZpbmFsIGxvbmcgbWlsbGlzKSB7DQorICAgICAgICAvL1N1YnRyYWN0aW9uIGlzIHVzZWQgdG8gZGVhbCB3aXRoIG51bWVyaWMgb3ZlcmZsb3cgb2YgbWlsbGlzLg0KKyAgICAgICAgYm9vbGVhbiBhbGxvdzsNCisgICAgICAgIGlmIChjb3VudCA+IDBMKSB7IC8vSWYgbm90IHNhdHVyYXRlZC4NCisgICAgICAgICAgICBpZiAoKG1pbGxpcyAtIHBlYWspID4gMEwpIHsNCisgICAgICAgICAgICAgICAgcGVhayA9IG1pbGxpczsgLy9SZWNvcmQgdGhlIG5ldyBwZWFrLg0KKyAgICAgICAgICAgIH0NCisNCisgICAgICAgICAgICAvL1VuZGVyIHRoZSByYXRlIGlmIHRoZSBjb3VudCBoYXMgbm90IGJlZW4gcmVhY2hlZC4NCisgICAgICAgICAgICBpZiAoY291bnQgIT0gcmVjb3Jkcykgew0KKyAgICAgICAgICAgICAgICArK2NvdW50Ow0KKyAgICAgICAgICAgICAgICBhbGxvdyA9IHRydWU7DQorICAgICAgICAgICAgfSBlbHNlIHsNCisgICAgICAgICAgICAgICAgaWYgKChwZWFrIC0gc3RhcnQpID49IGR1cmF0aW9uKSB7DQorICAgICAgICAgICAgICAgICAgICBjb3VudCA9IDFMOyAgLy9TdGFydCBhIG5ldyBkdXJhdGlvbi4NCisgICAgICAgICAgICAgICAgICAgIHN0YXJ0ID0gcGVhazsNCisgICAgICAgICAgICAgICAgICAgIGFsbG93ID0gdHJ1ZTsNCisgICAgICAgICAgICAgICAgfSBlbHNlIHsNCisgICAgICAgICAgICAgICAgICAgIGNvdW50ID0gLTFMOyAvL1NhdHVyYXRlIGZvciB0aGUgZHVyYXRpb24uDQorICAgICAgICAgICAgICAgICAgICBzdGFydCA9IHBlYWsgKyBkdXJhdGlvbjsNCisgICAgICAgICAgICAgICAgICAgIGFsbG93ID0gZmFsc2U7DQorICAgICAgICAgICAgICAgIH0NCisgICAgICAgICAgICB9DQorICAgICAgICB9IGVsc2Ugew0KKyAgICAgICAgICAgIC8vSWYgdGhlIHNhdHVyYXRpb24gcGVyaW9kIGhhcyBleHBpcmVkIG9yIHRoaXMgaXMgdGhlIGZpcnN0IHJlY29yZA0KKyAgICAgICAgICAgIC8vdGhlbiBzdGFydCBhIG5ldyBkdXJhdGlvbiBhbmQgYWxsb3cgcmVjb3Jkcy4NCisgICAgICAgICAgICBpZiAoKG1pbGxpcyAtIHN0YXJ0KSA+PSAwTCB8fCBjb3VudCA9PSAwTCkgew0KKyAgICAgICAgICAgICAgICBjb3VudCA9IDFMOw0KKyAgICAgICAgICAgICAgICBzdGFydCA9IG1pbGxpczsNCisgICAgICAgICAgICAgICAgcGVhayA9IG1pbGxpczsNCisgICAgICAgICAgICAgICAgYWxsb3cgPSB0cnVlOw0KKyAgICAgICAgICAgIH0gZWxzZSB7DQorICAgICAgICAgICAgICAgIGFsbG93ID0gZmFsc2U7IC8vUmVtYWluIGluIGEgc2F0dXJhdGVkIHN0YXRlLg0KKyAgICAgICAgICAgIH0NCisgICAgICAgIH0NCisgICAgICAgIHJldHVybiBhbGxvdzsNCisgICAgfQ0KKw0KKyAgICAvKioNCisgICAgICogUmVhZHMgYSBsb25nIHZhbHVlIG9yIG11bHRpcGxpY2F0aW9uIGV4cHJlc3Npb24gZnJvbSB0aGUgTG9nTWFuYWdlci4gSWYNCisgICAgICogdGhlIHZhbHVlIGNhbiBub3QgYmUgcGFyc2VkIG9yIGlzIG5vdCBkZWZpbmVkIHRoZW4gTG9uZy5NSU5fVkFMVUUgaXMNCisgICAgICogcmV0dXJuZWQuDQorICAgICAqDQorICAgICAqIEBwYXJhbSBzdWZmaXggYSBkb3QgY2hhcmFjdGVyIGZvbGxvd2VkIGJ5IHRoZSBrZXkgbmFtZS4NCisgICAgICogQHJldHVybiBhIGxvbmcgdmFsdWUgb3IgTG9uZy5NSU5fVkFMVUUgaWYgdW5hYmxlIHRvIHBhcnNlIG9yIHVuZGVmaW5lZC4NCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiBzdWZmaXggaXMgbnVsbC4NCisgICAgICovDQorICAgIHByaXZhdGUgbG9uZyBpbml0TG9uZyhmaW5hbCBTdHJpbmcgc3VmZml4KSB7DQorICAgICAgICBsb25nIHJlc3VsdCA9IDBMOw0KKyAgICAgICAgZmluYWwgU3RyaW5nIHAgPSBnZXRDbGFzcygpLmdldE5hbWUoKTsNCisgICAgICAgIFN0cmluZyB2YWx1ZSA9IGZyb21Mb2dNYW5hZ2VyKHAuY29uY2F0KHN1ZmZpeCkpOw0KKyAgICAgICAgaWYgKHZhbHVlICE9IG51bGwgJiYgdmFsdWUubGVuZ3RoKCkgIT0gMCkgew0KKyAgICAgICAgICAgIHZhbHVlID0gdmFsdWUudHJpbSgpOw0KKyAgICAgICAgICAgIGlmIChpc1RpbWVFbnRyeShzdWZmaXgsIHZhbHVlKSkgew0KKyAgICAgICAgICAgICAgICB0cnkgew0KKyAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gTG9nTWFuYWdlclByb3BlcnRpZXMucGFyc2VEdXJhdGlvblRvTWlsbGlzKHZhbHVlKTsNCisgICAgICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgUnVudGltZUV4Y2VwdGlvbiBpZ25vcmUpIHsNCisgICAgICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgRXhjZXB0aW9uIGlnbm9yZSkgew0KKyAgICAgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBMaW5rYWdlRXJyb3IgaWdub3JlKSB7DQorICAgICAgICAgICAgICAgIH0NCisgICAgICAgICAgICB9DQorDQorICAgICAgICAgICAgaWYgKHJlc3VsdCA9PSAwTCkgeyAvL1plcm8gaXMgaW52YWxpZC4NCisgICAgICAgICAgICAgICAgdHJ5IHsNCisgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IDFMOw0KKyAgICAgICAgICAgICAgICAgICAgZm9yIChTdHJpbmcgcyA6IHRva2VuaXplTG9uZ3ModmFsdWUpKSB7DQorICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHMuZW5kc1dpdGgoIkwiKSB8fCBzLmVuZHNXaXRoKCJsIikpIHsNCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcyA9IHMuc3Vic3RyaW5nKDAsIHMubGVuZ3RoKCkgLSAxKTsNCisgICAgICAgICAgICAgICAgICAgICAgICB9DQorICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gbXVsdGlwbHlFeGFjdChyZXN1bHQsIExvbmcucGFyc2VMb25nKHMpKTsNCisgICAgICAgICAgICAgICAgICAgIH0NCisgICAgICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgUnVudGltZUV4Y2VwdGlvbiBpZ25vcmUpIHsNCisgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IExvbmcuTUlOX1ZBTFVFOw0KKyAgICAgICAgICAgICAgICB9DQorICAgICAgICAgICAgfQ0KKyAgICAgICAgfSBlbHNlIHsNCisgICAgICAgICAgICByZXN1bHQgPSBMb25nLk1JTl9WQUxVRTsNCisgICAgICAgIH0NCisgICAgICAgIHJldHVybiByZXN1bHQ7DQorICAgIH0NCisNCisgICAgLyoqDQorICAgICAqIERldGVybWluZXMgaWYgdGhlIGdpdmVuIHN1ZmZpeCBjYW4gYmUgYSB0aW1lIHVuaXQgYW5kIHRoZSB2YWx1ZSBpcw0KKyAgICAgKiBlbmNvZGVkIGFzIGFuIElTTyBJU08tODYwMSBkdXJhdGlvbiBmb3JtYXQuDQorICAgICAqDQorICAgICAqIEBwYXJhbSBzdWZmaXggdGhlIHN1ZmZpeCBwcm9wZXJ0eS4NCisgICAgICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkuDQorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgZW50cnkgaXMgYSB0aW1lIGVudHJ5Lg0KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWYgdmFsdWUgaXMgZW1wdHkuDQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgZWl0aGVyIGFyZ3VtZW50IGlzIG51bGwuDQorICAgICAqLw0KKyAgICBwcml2YXRlIGJvb2xlYW4gaXNUaW1lRW50cnkoZmluYWwgU3RyaW5nIHN1ZmZpeCwgZmluYWwgU3RyaW5nIHZhbHVlKSB7DQorICAgICAgICByZXR1cm4gKHZhbHVlLmNoYXJBdCgwKSA9PSAnUCcgfHwgdmFsdWUuY2hhckF0KDApID09ICdwJykNCisgICAgICAgICAgICAgICAgJiYgc3VmZml4LmVxdWFscygiLmR1cmF0aW9uIik7DQorICAgIH0NCisNCisgICAgLyoqDQorICAgICAqIFBhcnNlIGFueSBsb25nIHZhbHVlIG9yIG11bHRpcGxpY2F0aW9uIGV4cHJlc3Npb25zIGludG8gdG9rZW5zLg0KKyAgICAgKg0KKyAgICAgKiBAcGFyYW0gdmFsdWUgdGhlIGV4cHJlc3Npb24gb3IgdmFsdWUuDQorICAgICAqIEByZXR1cm4gYW4gYXJyYXkgb2YgbG9uZyB0b2tlbnMsIG5ldmVyIGVtcHR5Lg0KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBnaXZlbiB2YWx1ZSBpcyBudWxsLg0KKyAgICAgKiBAdGhyb3dzIE51bWJlckZvcm1hdEV4Y2VwdGlvbiBpZiB0aGUgZXhwcmVzc2lvbiBpcyBpbnZhbGlkLg0KKyAgICAgKi8NCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nW10gdG9rZW5pemVMb25ncyhmaW5hbCBTdHJpbmcgdmFsdWUpIHsNCisgICAgICAgIFN0cmluZ1tdIGU7DQorICAgICAgICBmaW5hbCBpbnQgaSA9IHZhbHVlLmluZGV4T2YoJyonKTsNCisgICAgICAgIGlmIChpID4gLTEgJiYgKGUgPSB2YWx1ZS5zcGxpdCgiXFxzKlxcKlxccyoiKSkubGVuZ3RoICE9IDApIHsNCisgICAgICAgICAgICBpZiAoaSA9PSAwIHx8IHZhbHVlLmNoYXJBdCh2YWx1ZS5sZW5ndGgoKSAtIDEpID09ICcqJykgew0KKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVtYmVyRm9ybWF0RXhjZXB0aW9uKHZhbHVlKTsNCisgICAgICAgICAgICB9DQorDQorICAgICAgICAgICAgaWYgKGUubGVuZ3RoID09IDEpIHsNCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bWJlckZvcm1hdEV4Y2VwdGlvbihlWzBdKTsNCisgICAgICAgICAgICB9DQorICAgICAgICB9IGVsc2Ugew0KKyAgICAgICAgICAgIGUgPSBuZXcgU3RyaW5nW117dmFsdWV9Ow0KKyAgICAgICAgfQ0KKyAgICAgICAgcmV0dXJuIGU7DQorICAgIH0NCisNCisgICAgLyoqDQorICAgICAqIE11bHRpcGx5IGFuZCBjaGVjayBmb3Igb3ZlcmZsb3cuIFRoaXMgY2FuIGJlIHJlcGxhY2VkIHdpdGgNCisgICAgICoge0Bjb2RlIGphdmEubGFuZy5NYXRoLm11bHRpcGx5RXhhY3R9IHdoZW4gSmF2YU1haWwgcmVxdWlyZXMgSkRLIDguDQorICAgICAqDQorICAgICAqIEBwYXJhbSB4IHRoZSBmaXJzdCB2YWx1ZS4NCisgICAgICogQHBhcmFtIHkgdGhlIHNlY29uZCB2YWx1ZS4NCisgICAgICogQHJldHVybiB4IHRpbWVzIHkuDQorICAgICAqIEB0aHJvd3MgQXJpdGhtZXRpY0V4Y2VwdGlvbiBpZiBvdmVyZmxvdyBpcyBkZXRlY3RlZC4NCisgICAgICovDQorICAgIHByaXZhdGUgc3RhdGljIGxvbmcgbXVsdGlwbHlFeGFjdChmaW5hbCBsb25nIHgsIGZpbmFsIGxvbmcgeSkgew0KKyAgICAgICAgbG9uZyByID0geCAqIHk7DQorICAgICAgICBpZiAoKChNYXRoLmFicyh4KSB8IE1hdGguYWJzKHkpKSA+Pj4gMzFMICE9IDBMKSkgew0KKyAgICAgICAgICAgIGlmICgoKHkgIT0gMEwpICYmIChyIC8geSAhPSB4KSkNCisgICAgICAgICAgICAgICAgICAgIHx8ICh4ID09IExvbmcuTUlOX1ZBTFVFICYmIHkgPT0gLTFMKSkgew0KKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXJpdGhtZXRpY0V4Y2VwdGlvbigpOw0KKyAgICAgICAgICAgIH0NCisgICAgICAgIH0NCisgICAgICAgIHJldHVybiByOw0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBDb252ZXJ0cyByZWNvcmQgY291bnQgdG8gYSB2YWxpZCByZWNvcmQgY291bnQuIElmIHRoZSB2YWx1ZSBpcyBvdXQgb2YNCisgICAgICogYm91bmRzIHRoZW4gdGhlIGRlZmF1bHQgcmVjb3JkIGNvdW50IGlzIHVzZWQuDQorICAgICAqDQorICAgICAqIEBwYXJhbSByZWNvcmRzIHRoZSByZWNvcmQgY291bnQuDQorICAgICAqIEByZXR1cm4gYSB2YWxpZCBudW1iZXIgb2YgcmVjb3JkIGNvdW50Lg0KKyAgICAgKi8NCisgICAgcHJpdmF0ZSBzdGF0aWMgbG9uZyBjaGVja1JlY29yZHMoZmluYWwgbG9uZyByZWNvcmRzKSB7DQorICAgICAgICByZXR1cm4gcmVjb3JkcyA+IDBMID8gcmVjb3JkcyA6IDEwMDBMOw0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBDb252ZXJ0cyB0aGUgZHVyYXRpb24gdG8gYSB2YWxpZCBkdXJhdGlvbi4gSWYgdGhlIHZhbHVlIGlzIG91dCBvZiBib3VuZHMNCisgICAgICogdGhlbiB0aGUgZGVmYXVsdCBkdXJhdGlvbiBpcyB1c2VkLg0KKyAgICAgKg0KKyAgICAgKiBAcGFyYW0gZHVyYXRpb24gdGhlIGR1cmF0aW9uIHRvIGNoZWNrLg0KKyAgICAgKiBAcmV0dXJuIGEgdmFsaWQgZHVyYXRpb24uDQorICAgICAqLw0KKyAgICBwcml2YXRlIHN0YXRpYyBsb25nIGNoZWNrRHVyYXRpb24oZmluYWwgbG9uZyBkdXJhdGlvbikgew0KKyAgICAgICAgcmV0dXJuIGR1cmF0aW9uID4gMEwgPyBkdXJhdGlvbiA6IDE1TCAqIDYwTCAqIDEwMDBMOw0KKyAgICB9DQorfQ0KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvdXRpbC9sb2dnaW5nL0xvZ01hbmFnZXJQcm9wZXJ0aWVzLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvbG9nZ2luZy9Mb2dNYW5hZ2VyUHJvcGVydGllcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIyMGE4ZjIKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvbG9nZ2luZy9Mb2dNYW5hZ2VyUHJvcGVydGllcy5qYXZhCkBAIC0wLDAgKzEsMTA5MCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwOSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICogQ29weXJpZ2h0IChjKSAyMDA5LCAyMDE4IEphc29uIE1laHJlbnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworcGFja2FnZSBjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nOworCitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lkludm9jYXRpb25UYXJnZXRFeGNlcHRpb247CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lk1vZGlmaWVyOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LlVuZGVjbGFyZWRUaHJvd2FibGVFeGNlcHRpb247CitpbXBvcnQgamF2YS5zZWN1cml0eS5BY2Nlc3NDb250cm9sbGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmlsZWdlZEFjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBqYXZhLnV0aWwubG9nZ2luZy4qOworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkZvcm1hdHRlcjsKKworLyoqCisgKiBBbiBhZGFwdGVyIGNsYXNzIHRvIGFsbG93IHRoZSBNYWlsIEFQSSB0byBhY2Nlc3MgdGhlIExvZ01hbmFnZXIgcHJvcGVydGllcy4KKyAqIFRoZSBMb2dNYW5hZ2VyIHByb3BlcnRpZXMgYXJlIHRyZWF0ZWQgYXMgdGhlIHJvb3Qgb2YgYWxsIHByb3BlcnRpZXMuIEZpcnN0LAorICogdGhlIHBhcmVudCBwcm9wZXJ0aWVzIGFyZSBzZWFyY2hlZC4gSWYgbm8gdmFsdWUgaXMgZm91bmQsIHRoZW4sIHRoZQorICogTG9nTWFuYWdlciBpcyBzZWFyY2hlZCB3aXRoIHByZWZpeCB2YWx1ZS4gSWYgbm90IGZvdW5kLCB0aGVuLCBqdXN0IHRoZSBrZXkKKyAqIGl0c2VsZiBpcyBzZWFyY2hlZCBpbiB0aGUgTG9nTWFuYWdlci4gSWYgYSB2YWx1ZSBpcyBmb3VuZCBpbiB0aGUgTG9nTWFuYWdlcgorICogaXQgaXMgdGhlbiBjb3BpZWQgdG8gdGhpcyBwcm9wZXJ0aWVzIG9iamVjdCB3aXRoIG5vIGtleSBwcmVmaXguIElmIG5vIHZhbHVlCisgKiBpcyBmb3VuZCBpbiB0aGUgTG9nTWFuYWdlciBvciB0aGUgcGFyZW50IHByb3BlcnRpZXMsIHRoZW4gdGhpcyBwcm9wZXJ0aWVzCisgKiBvYmplY3QgaXMgc2VhcmNoZWQgb25seSBieSBwYXNzaW5nIHRoZSBrZXkgdmFsdWUuCisgKgorICogPHA+CisgKiBUaGlzIGNsYXNzIGFsc28gZW11bGF0ZXMgdGhlIExvZ01hbmFnZXIgZnVuY3Rpb25zIGZvciBjcmVhdGluZyBuZXcgb2JqZWN0cworICogZnJvbSBzdHJpbmcgY2xhc3MgbmFtZXMuIFRoaXMgaXMgdG8gc3VwcG9ydCBpbml0aWFsIHNldHVwIG9mIG9iamVjdHMgc3VjaCBhcworICogbG9nIGZpbHRlcnMsIGZvcm1hdHRlcnMsIGVycm9yIG1hbmFnZXJzLCBldGMuCisgKgorICogPHA+CisgKiBUaGlzIGNsYXNzIHNob3VsZCBuZXZlciBiZSBleHBvc2VkIG91dHNpZGUgb2YgdGhpcyBwYWNrYWdlLiBLZWVwIHRoaXMgY2xhc3MKKyAqIHBhY2thZ2UgcHJpdmF0ZSAoZGVmYXVsdCBhY2Nlc3MpLgorICoKKyAqIEBhdXRob3IgSmFzb24gTWVocmVucworICogQHNpbmNlIEphdmFNYWlsIDEuNC4zCisgKi8KK2ZpbmFsIGNsYXNzIExvZ01hbmFnZXJQcm9wZXJ0aWVzIGV4dGVuZHMgUHJvcGVydGllcyB7CisKKyAgICAvKioKKyAgICAgKiBHZW5lcmF0ZWQgc2VyaWFsIGlkLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0yMjM5OTgzMzQ5MDU2ODA2MjUyTDsKKyAgICAvKioKKyAgICAgKiBIb2xkcyB0aGUgbWV0aG9kIHVzZWQgdG8gZ2V0IHRoZSBMb2dSZWNvcmQgaW5zdGFudCBpZiBydW5uaW5nIG9uIEpESyA5IG9yCisgICAgICogbGF0ZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTWV0aG9kIExSX0dFVF9JTlNUQU5UOworCisgICAgLyoqCisgICAgICogSG9sZHMgdGhlIG1ldGhvZCB1c2VkIHRvIGdldCB0aGUgZGVmYXVsdCB0aW1lIHpvbmUgaWYgcnVubmluZyBvbiBKREsgOSBvcgorICAgICAqIGxhdGVyLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE1ldGhvZCBaSV9TWVNURU1fREVGQVVMVDsKKworICAgIC8qKgorICAgICAqIEhvbGRzIHRoZSBtZXRob2QgdXNlZCB0byBjb252ZXJ0IGFuZCBpbnN0YW50IHRvIGEgem9uZWQgZGF0ZSB0aW1lIGlmCisgICAgICogcnVubmluZyBvbiBKREsgOSBsYXRlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNZXRob2QgWkRUX09GX0lOU1RBTlQ7CisKKyAgICBzdGF0aWMgeworICAgICAgICBNZXRob2QgbHJnaSA9IG51bGw7CisgICAgICAgIE1ldGhvZCB6aXNkID0gbnVsbDsKKyAgICAgICAgTWV0aG9kIHpkdG9pID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGxyZ2kgPSBMb2dSZWNvcmQuY2xhc3MuZ2V0TWV0aG9kKCJnZXRJbnN0YW50Iik7CisgICAgICAgICAgICBhc3NlcnQgQ29tcGFyYWJsZS5jbGFzcworICAgICAgICAgICAgICAgICAgICAuaXNBc3NpZ25hYmxlRnJvbShscmdpLmdldFJldHVyblR5cGUoKSkgOiBscmdpOworICAgICAgICAgICAgemlzZCA9IGZpbmRDbGFzcygiamF2YS50aW1lLlpvbmVJZCIpCisgICAgICAgICAgICAgICAgICAgIC5nZXRNZXRob2QoInN5c3RlbURlZmF1bHQiKTsKKyAgICAgICAgICAgIGlmICghTW9kaWZpZXIuaXNTdGF0aWMoemlzZC5nZXRNb2RpZmllcnMoKSkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoTWV0aG9kRXhjZXB0aW9uKHppc2QudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHpkdG9pID0gZmluZENsYXNzKCJqYXZhLnRpbWUuWm9uZWREYXRlVGltZSIpCisgICAgICAgICAgICAgICAgICAgIC5nZXRNZXRob2QoIm9mSW5zdGFudCIsIGZpbmRDbGFzcygiamF2YS50aW1lLkluc3RhbnQiKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5kQ2xhc3MoImphdmEudGltZS5ab25lSWQiKSk7CisgICAgICAgICAgICBpZiAoIU1vZGlmaWVyLmlzU3RhdGljKHpkdG9pLmdldE1vZGlmaWVycygpKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hNZXRob2RFeGNlcHRpb24oemR0b2kudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmICghQ29tcGFyYWJsZS5jbGFzcy5pc0Fzc2lnbmFibGVGcm9tKHpkdG9pLmdldFJldHVyblR5cGUoKSkpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoTWV0aG9kRXhjZXB0aW9uKHpkdG9pLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChmaW5hbCBSdW50aW1lRXhjZXB0aW9uIGlnbm9yZSkgeworICAgICAgICB9IGNhdGNoIChmaW5hbCBFeGNlcHRpb24gaWdub3JlKSB7IC8vTm8gbmVlZCBmb3Igc3BlY2lmaWMgY2F0Y2guCisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIExpbmthZ2VFcnJvciBpZ25vcmUpIHsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChscmdpID09IG51bGwgfHwgemlzZCA9PSBudWxsIHx8IHpkdG9pID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBscmdpID0gbnVsbDsgLy9JZiBhbnkgYXJlIG51bGwgdGhlbiBjbGVhciBhbGwuCisgICAgICAgICAgICAgICAgemlzZCA9IG51bGw7CisgICAgICAgICAgICAgICAgemR0b2kgPSBudWxsOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgTFJfR0VUX0lOU1RBTlQgPSBscmdpOworICAgICAgICBaSV9TWVNURU1fREVGQVVMVCA9IHppc2Q7CisgICAgICAgIFpEVF9PRl9JTlNUQU5UID0gemR0b2k7CisgICAgfQorICAgIC8qKgorICAgICAqIENhY2hlcyB0aGUgcmVhZCBvbmx5IHJlZmxlY3Rpb24gY2xhc3MgbmFtZXMgc3RyaW5nIGFycmF5LiBEZWNsYXJlZAorICAgICAqIHZvbGF0aWxlIGZvciBzYWZlIHB1Ymxpc2hpbmcgb25seS4gVGhlIFZPX1ZPTEFUSUxFX1JFRkVSRU5DRV9UT19BUlJBWQorICAgICAqIHdhcm5pbmcgaXMgYSBmYWxzZSBwb3NpdGl2ZS4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiVm9sYXRpbGVBcnJheUZpZWxkIikKKyAgICBwcml2YXRlIHN0YXRpYyB2b2xhdGlsZSBTdHJpbmdbXSBSRUZMRUNUX05BTUVTOworICAgIC8qKgorICAgICAqIENhY2hlcyB0aGUgTG9nTWFuYWdlciBvciBQcm9wZXJ0aWVzIHNvIHdlIG9ubHkgcmVhZCB0aGUgY29uZmlndXJhdGlvbgorICAgICAqIG9uY2UuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgT2JqZWN0IExPR19NQU5BR0VSID0gbG9hZExvZ01hbmFnZXIoKTsKKworICAgIC8qKgorICAgICAqIEdldCB0aGUgTG9nTWFuYWdlciBvciBsb2FkcyBhIFByb3BlcnRpZXMgb2JqZWN0IHRvIHVzZSBhcyB0aGUgTG9nTWFuYWdlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIExvZ01hbmFnZXIgb3IgYSBsb2FkZWQgUHJvcGVydGllcyBvYmplY3QuCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNS4zCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgT2JqZWN0IGxvYWRMb2dNYW5hZ2VyKCkgeworICAgICAgICBPYmplY3QgbTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG0gPSBMb2dNYW5hZ2VyLmdldExvZ01hbmFnZXIoKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgTGlua2FnZUVycm9yIHJlc3RyaWN0ZWQpIHsKKyAgICAgICAgICAgIG0gPSByZWFkQ29uZmlndXJhdGlvbigpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBSdW50aW1lRXhjZXB0aW9uIHVuZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIG0gPSByZWFkQ29uZmlndXJhdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBtOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIHByb3BlcnRpZXMgb2JqZWN0IGZyb20gdGhlIGRlZmF1bHQgbG9nZ2luZyBjb25maWd1cmF0aW9uIGZpbGUuCisgICAgICogU2luY2UgdGhlIExvZ01hbmFnZXIgaXMgbm90IGF2YWlsYWJsZSBpbiByZXN0cmljdGVkIGVudmlyb25tZW50cywgb25seQorICAgICAqIHRoZSBkZWZhdWx0IGNvbmZpZ3VyYXRpb24gaXMgYXBwbGljYWJsZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBwcm9wZXJ0aWVzIG9iamVjdCBsb2FkZWQgd2l0aCB0aGUgZGVmYXVsdCBjb25maWd1cmF0aW9uLgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjUuMworICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFByb3BlcnRpZXMgcmVhZENvbmZpZ3VyYXRpb24oKSB7CisgICAgICAgIC8qKgorICAgICAgICAgKiBMb2FkIHRoZSBwcm9wZXJ0aWVzIGZpbGUgc28gdGhlIGRlZmF1bHQgc2V0dGluZ3MgYXJlIGF2YWlsYWJsZSB3aGVuCisgICAgICAgICAqIHVzZXIgY29kZSBjcmVhdGVzIGEgbG9nZ2luZyBvYmplY3QuIFRoZSBjbGFzcyBsb2FkZXIgZm9yIHRoZQorICAgICAgICAgKiByZXN0cmljdGVkIExvZ01hbmFnZXIgY2FuJ3QgYWNjZXNzIHRoZXNlIGNsYXNzZXMgdG8gYXR0YWNoIHRoZW0gdG8gYQorICAgICAgICAgKiBsb2dnZXIgb3IgaGFuZGxlciBvbiBzdGFydHVwLiBDcmVhdGluZyBsb2dnaW5nIG9iamVjdHMgYXQgdGhpcyBwb2ludAorICAgICAgICAgKiBpcyBib3RoIHVzZWxlc3MgYW5kIHJpc2t5LgorICAgICAgICAgKi8KKyAgICAgICAgZmluYWwgUHJvcGVydGllcyBwcm9wcyA9IG5ldyBQcm9wZXJ0aWVzKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcgbiA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS51dGlsLmxvZ2dpbmcuY29uZmlnLmZpbGUiKTsKKyAgICAgICAgICAgIGlmIChuICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBGaWxlIGYgPSBuZXcgRmlsZShuKS5nZXRDYW5vbmljYWxGaWxlKCk7CisgICAgICAgICAgICAgICAgZmluYWwgSW5wdXRTdHJlYW0gaW4gPSBuZXcgRmlsZUlucHV0U3RyZWFtKGYpOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHByb3BzLmxvYWQoaW4pOworICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChmaW5hbCBSdW50aW1lRXhjZXB0aW9uIHBlcm1pc3Npb25zT3JNYWxmb3JtZWQpIHsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgRXhjZXB0aW9uIGlvZSkgeworICAgICAgICB9IGNhdGNoIChmaW5hbCBMaW5rYWdlRXJyb3IgdW5leHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHJldHVybiBwcm9wczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIExvZ01hbmdlciBwcm9wZXJ0eSBmb3IgdGhlIHJ1bm5pbmcgSlZNLiBJZiB0aGUgTG9nTWFuYWdlciBkb2Vzbid0CisgICAgICogZXhpc3QgdGhlbiB0aGUgZGVmYXVsdCBMb2dNYW5nZXIgcHJvcGVydGllcyBhcmUgdXNlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lIHRoZSBwcm9wZXJ0eSBuYW1lLgorICAgICAqIEByZXR1cm4gdGhlIExvZ01hbmFnZXIuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgZ2l2ZW4gbmFtZSBpcyBudWxsLgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjUuMworICAgICAqLworICAgIHN0YXRpYyBTdHJpbmcgZnJvbUxvZ01hbmFnZXIoZmluYWwgU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBPYmplY3QgbSA9IExPR19NQU5BR0VSOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKG0gaW5zdGFuY2VvZiBQcm9wZXJ0aWVzKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuICgoUHJvcGVydGllcykgbSkuZ2V0UHJvcGVydHkobmFtZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIFJ1bnRpbWVFeGNlcHRpb24gdW5leHBlY3RlZCkgeworICAgICAgICB9CisKKyAgICAgICAgaWYgKG0gIT0gbnVsbCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpZiAobSBpbnN0YW5jZW9mIExvZ01hbmFnZXIpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgoTG9nTWFuYWdlcikgbSkuZ2V0UHJvcGVydHkobmFtZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgTGlua2FnZUVycm9yIHJlc3RyaWN0ZWQpIHsKKyAgICAgICAgICAgIH0gY2F0Y2ggKGZpbmFsIFJ1bnRpbWVFeGNlcHRpb24gdW5leHBlY3RlZCkgeworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrIHRoYXQgdGhlIGN1cnJlbnQgY29udGV4dCBpcyB0cnVzdGVkIHRvIG1vZGlmeSB0aGUgbG9nZ2luZworICAgICAqIGNvbmZpZ3VyYXRpb24uIFRoaXMgcmVxdWlyZXMgTG9nZ2luZ1Blcm1pc3Npb24oImNvbnRyb2wiKS4KKyAgICAgKiBAdGhyb3dzIFNlY3VyaXR5RXhjZXB0aW9uICBpZiBhIHNlY3VyaXR5IG1hbmFnZXIgZXhpc3RzIGFuZCB0aGUgY2FsbGVyCisgICAgICogZG9lcyBub3QgaGF2ZSB7QGNvZGUgTG9nZ2luZ1Blcm1pc3Npb24oImNvbnRyb2wiKX0uCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNS4zCisgICAgICovCisgICAgc3RhdGljIHZvaWQgY2hlY2tMb2dNYW5hZ2VyQWNjZXNzKCkgeworICAgICAgICBib29sZWFuIGNoZWNrZWQgPSBmYWxzZTsKKyAgICAgICAgZmluYWwgT2JqZWN0IG0gPSBMT0dfTUFOQUdFUjsKKyAgICAgICAgaWYgKG0gIT0gbnVsbCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpZiAobSBpbnN0YW5jZW9mIExvZ01hbmFnZXIpIHsKKyAgICAgICAgICAgICAgICAgICAgY2hlY2tlZCA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgICgoTG9nTWFuYWdlcikgbSkuY2hlY2tBY2Nlc3MoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBTZWN1cml0eUV4Y2VwdGlvbiBub3RBbGxvd2VkKSB7CisgICAgICAgICAgICAgICAgaWYgKGNoZWNrZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbm90QWxsb3dlZDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBMaW5rYWdlRXJyb3IgcmVzdHJpY3RlZCkgeworICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgUnVudGltZUV4Y2VwdGlvbiB1bmV4cGVjdGVkKSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBpZiAoIWNoZWNrZWQpIHsKKyAgICAgICAgICAgIGNoZWNrTG9nZ2luZ0FjY2VzcygpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2sgdGhhdCB0aGUgY3VycmVudCBjb250ZXh0IGlzIHRydXN0ZWQgdG8gbW9kaWZ5IHRoZSBsb2dnaW5nCisgICAgICogY29uZmlndXJhdGlvbiB3aGVuIHRoZSBMb2dNYW5hZ2VyIGlzIG5vdCBwcmVzZW50LiBUaGlzIHJlcXVpcmVzCisgICAgICogTG9nZ2luZ1Blcm1pc3Npb24oImNvbnRyb2wiKS4KKyAgICAgKiBAdGhyb3dzIFNlY3VyaXR5RXhjZXB0aW9uICBpZiBhIHNlY3VyaXR5IG1hbmFnZXIgZXhpc3RzIGFuZCB0aGUgY2FsbGVyCisgICAgICogZG9lcyBub3QgaGF2ZSB7QGNvZGUgTG9nZ2luZ1Blcm1pc3Npb24oImNvbnRyb2wiKX0uCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNS4zCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBjaGVja0xvZ2dpbmdBY2Nlc3MoKSB7CisgICAgICAgIC8qKgorICAgICAgICAgKiBTb21lIGVudmlyb25tZW50cyBzZWxlY3RpdmVseSBlbmZvcmNlIGxvZ2dpbmcgcGVybWlzc2lvbnMgYnkgYWxsb3dpbmcKKyAgICAgICAgICogYWNjZXNzIHRvIGxvZ2dlcnMgYnV0IG5vdCBhbGxvd2luZyBhY2Nlc3MgdG8gaGFuZGxlcnMuIFRoaXMgaXMgYW4KKyAgICAgICAgICogaW5kaXJlY3Qgd2F5IG9mIGNoZWNraW5nIGZvciBMb2dnaW5nUGVybWlzc2lvbiB3aGVuIHRoZSBMb2dNYW5hZ2VyIGlzCisgICAgICAgICAqIG5vdCBwcmVzZW50LiBUaGUgcm9vdCBsb2dnZXIgd2lsbCBsYXp5IGNyZWF0ZSBoYW5kbGVycyBzbyB0aGUgZ2xvYmFsCisgICAgICAgICAqIGxvZ2dlciBpcyB1c2VkIGluc3RlYWQgYXMgaXQgaXMgYSBrbm93biBuYW1lZCBsb2dnZXIgd2l0aCB3ZWxsCisgICAgICAgICAqIGRlZmluZWQgYmVoYXZpb3IuIElmIHRoZSBnbG9iYWwgbG9nZ2VyIGlzIGEgc3ViY2xhc3MgdGhlbiBmYWxsYmFjayB0bworICAgICAgICAgKiB1c2luZyB0aGUgU2VjdXJpdHlNYW5hZ2VyLgorICAgICAgICAgKi8KKyAgICAgICAgYm9vbGVhbiBjaGVja2VkID0gZmFsc2U7CisgICAgICAgIGZpbmFsIExvZ2dlciBnbG9iYWwgPSBMb2dnZXIuZ2V0TG9nZ2VyKCJnbG9iYWwiKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmIChMb2dnZXIuY2xhc3MgPT0gZ2xvYmFsLmdldENsYXNzKCkpIHsKKyAgICAgICAgICAgICAgICBnbG9iYWwucmVtb3ZlSGFuZGxlcigoSGFuZGxlcikgbnVsbCk7CisgICAgICAgICAgICAgICAgY2hlY2tlZCA9IHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIE51bGxQb2ludGVyRXhjZXB0aW9uIHVuZXhwZWN0ZWQpIHsKKyAgICAgICAgfQorCisgICAgICAgIGlmICghY2hlY2tlZCkgeworICAgICAgICAgICAgZmluYWwgU2VjdXJpdHlNYW5hZ2VyIHNtID0gU3lzdGVtLmdldFNlY3VyaXR5TWFuYWdlcigpOworICAgICAgICAgICAgaWYgKHNtICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBzbS5jaGVja1Blcm1pc3Npb24obmV3IExvZ2dpbmdQZXJtaXNzaW9uKCJjb250cm9sIiwgbnVsbCkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyBpZiBhY2Nlc3MgdG8gdGhlIHtAY29kZSBqYXZhLnV0aWwubG9nZ2luZy5Mb2dNYW5hZ2VyfSBjbGFzcyBpcworICAgICAqIHJlc3RyaWN0ZWQgYnkgdGhlIGNsYXNzIGxvYWRlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBhIExvZ01hbmFnZXIgaXMgcHJlc2VudC4KKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS41LjMKKyAgICAgKi8KKyAgICBzdGF0aWMgYm9vbGVhbiBoYXNMb2dNYW5hZ2VyKCkgeworICAgICAgICBmaW5hbCBPYmplY3QgbSA9IExPR19NQU5BR0VSOworICAgICAgICByZXR1cm4gbSAhPSBudWxsICYmICEobSBpbnN0YW5jZW9mIFByb3BlcnRpZXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIFpvbmVkRGF0ZVRpbWUgZnJvbSB0aGUgZ2l2ZW4gbG9nIHJlY29yZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZWNvcmQgdXNlZCB0byBnZW5lcmF0ZSB0aGUgem9uZWQgZGF0ZSB0aW1lLgorICAgICAqIEByZXR1cm4gbnVsbCBpZiBMb2dSZWNvcmQgZG9lc24ndCBzdXBwb3J0IG5hbm9zZWNvbmRzIG90aGVyd2lzZSBhIG5ldworICAgICAqIHpvbmVkIGRhdGUgdGltZSBpcyByZXR1cm5lZC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHJlY29yZCBpcyBudWxsLgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjUuNgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJVc2VTcGVjaWZpY0NhdGNoIikKKyAgICBzdGF0aWMgQ29tcGFyYWJsZTw/PiBnZXRab25lZERhdGVUaW1lKExvZ1JlY29yZCByZWNvcmQpIHsKKyAgICAgICAgaWYgKHJlY29yZCA9PSBudWxsKSB7CisgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGZpbmFsIE1ldGhvZCBtID0gWkRUX09GX0lOU1RBTlQ7CisgICAgICAgIGlmIChtICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIChDb21wYXJhYmxlPD8+KSBtLmludm9rZSgoT2JqZWN0KSBudWxsLAorICAgICAgICAgICAgICAgICAgICAgICAgTFJfR0VUX0lOU1RBTlQuaW52b2tlKHJlY29yZCksCisgICAgICAgICAgICAgICAgICAgICAgICBaSV9TWVNURU1fREVGQVVMVC5pbnZva2UoKE9iamVjdCkgbnVsbCkpOworICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgUnVudGltZUV4Y2VwdGlvbiBpZ25vcmUpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnQgTFJfR0VUX0lOU1RBTlQgIT0gbnVsbAorICAgICAgICAgICAgICAgICAgICAgICAgJiYgWklfU1lTVEVNX0RFRkFVTFQgIT0gbnVsbCA6IGlnbm9yZTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKGZpbmFsIEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24gaXRlKSB7CisgICAgICAgICAgICAgICAgZmluYWwgVGhyb3dhYmxlIGNhdXNlID0gaXRlLmdldENhdXNlKCk7CisgICAgICAgICAgICAgICAgaWYgKGNhdXNlIGluc3RhbmNlb2YgRXJyb3IpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgKEVycm9yKSBjYXVzZTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNhdXNlIGluc3RhbmNlb2YgUnVudGltZUV4Y2VwdGlvbikgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyAoUnVudGltZUV4Y2VwdGlvbikgY2F1c2U7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsgLy9TaG91bGQgbmV2ZXIgaGFwcGVuLgorICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVW5kZWNsYXJlZFRocm93YWJsZUV4Y2VwdGlvbihpdGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gY2F0Y2ggKGZpbmFsIEV4Y2VwdGlvbiBpZ25vcmUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBsb2NhbCBob3N0IG5hbWUgZnJvbSB0aGUgZ2l2ZW4gc2VydmljZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzIHRoZSBzZXJ2aWNlIHRvIGV4YW1pbmUuCisgICAgICogQHJldHVybiB0aGUgbG9jYWwgaG9zdCBuYW1lIG9yIG51bGwuCisgICAgICogQHRocm93cyBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGlmIHRoZSBtZXRob2QgaXMgaW5hY2Nlc3NpYmxlLgorICAgICAqIEB0aHJvd3MgSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiBpZiB0aGUgbWV0aG9kIHRocm93cyBhbiBleGNlcHRpb24uCisgICAgICogQHRocm93cyBMaW5rYWdlRXJyb3IgaWYgdGhlIGxpbmthZ2UgZmFpbHMuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgZ2l2ZW4gc2VydmljZSBpcyBudWxsLgorICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uSW5Jbml0aWFsaXplckVycm9yIGlmIHRoZSBzdGF0aWMgaW5pdGlhbGl6ZXIgZmFpbHMuCisgICAgICogQHRocm93cyBFeGNlcHRpb24gaWYgdGhlcmUgaXMgYSBwcm9ibGVtLgorICAgICAqIEB0aHJvd3MgTm9TdWNoTWV0aG9kRXhjZXB0aW9uIGlmIHRoZSBnaXZlbiBzZXJ2aWNlIGRvZXMgbm90IGhhdmUgYSBtZXRob2QKKyAgICAgKiB0byBnZXQgdGhlIGxvY2FsIGhvc3QgbmFtZSBhcyBhIHN0cmluZy4KKyAgICAgKiBAdGhyb3dzIFNlY3VyaXR5RXhjZXB0aW9uIGlmIHVuYWJsZSB0byBpbnNwZWN0IHByb3BlcnRpZXMgb2Ygb2JqZWN0LgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjUuMworICAgICAqLworICAgIHN0YXRpYyBTdHJpbmcgZ2V0TG9jYWxIb3N0KGZpbmFsIE9iamVjdCBzKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZpbmFsIE1ldGhvZCBtID0gcy5nZXRDbGFzcygpLmdldE1ldGhvZCgiZ2V0TG9jYWxIb3N0Iik7CisgICAgICAgICAgICBpZiAoIU1vZGlmaWVyLmlzU3RhdGljKG0uZ2V0TW9kaWZpZXJzKCkpCisgICAgICAgICAgICAgICAgICAgICYmIG0uZ2V0UmV0dXJuVHlwZSgpID09IFN0cmluZy5jbGFzcykgeworICAgICAgICAgICAgICAgIHJldHVybiAoU3RyaW5nKSBtLmludm9rZShzKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaE1ldGhvZEV4Y2VwdGlvbihtLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChmaW5hbCBFeGNlcHRpb25JbkluaXRpYWxpemVyRXJyb3IgRUlJRSkgeworICAgICAgICAgICAgdGhyb3cgd3JhcE9yVGhyb3coRUlJRSk7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24gaXRlKSB7CisgICAgICAgICAgICB0aHJvdyBwYXJhbU9yRXJyb3IoaXRlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFVzZWQgdG8gcGFyc2UgYW4gSVNPLTg2MDEgZHVyYXRpb24gZm9ybWF0IG9mIHtAY29kZSBQbkRUbkhuTW4ublN9LgorICAgICAqCisgICAgICogQHBhcmFtIHZhbHVlIGFuIElTTy04NjAxIGR1cmF0aW9uIGNoYXJhY3RlciBzZXF1ZW5jZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHBhcnNlZCBmcm9tIHRoZSBkdXJhdGlvbi4KKyAgICAgKiBAdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24gaWYgdGhlIGphdmEudGltZSBjbGFzc2VzIGFyZSBub3QgcHJlc2VudC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gaWYgdGhlIG1ldGhvZCBpcyBpbmFjY2Vzc2libGUuCisgICAgICogQHRocm93cyBJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uIGlmIHRoZSBtZXRob2QgdGhyb3dzIGFuIGV4Y2VwdGlvbi4KKyAgICAgKiBAdGhyb3dzIExpbmthZ2VFcnJvciBpZiB0aGUgbGlua2FnZSBmYWlscy4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBnaXZlbiBkdXJhdGlvbiBpcyBudWxsLgorICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uSW5Jbml0aWFsaXplckVycm9yIGlmIHRoZSBzdGF0aWMgaW5pdGlhbGl6ZXIgZmFpbHMuCisgICAgICogQHRocm93cyBFeGNlcHRpb24gaWYgdGhlcmUgaXMgYSBwcm9ibGVtLgorICAgICAqIEB0aHJvd3MgTm9TdWNoTWV0aG9kRXhjZXB0aW9uIGlmIHRoZSBjb3JyZWN0IHRpbWUgbWV0aG9kcyBhcmUgbWlzc2luZy4KKyAgICAgKiBAdGhyb3dzIFNlY3VyaXR5RXhjZXB0aW9uIGlmIHJlZmxlY3RpdmUgYWNjZXNzIHRvIHRoZSBqYXZhLnRpbWUgY2xhc3NlcworICAgICAqIGFyZSBub3QgYWxsb3dlZC4KKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS41LjUKKyAgICAgKi8KKyAgICBzdGF0aWMgbG9uZyBwYXJzZUR1cmF0aW9uVG9NaWxsaXMoZmluYWwgQ2hhclNlcXVlbmNlIHZhbHVlKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZpbmFsIENsYXNzPD8+IGsgPSBmaW5kQ2xhc3MoImphdmEudGltZS5EdXJhdGlvbiIpOworICAgICAgICAgICAgZmluYWwgTWV0aG9kIHBhcnNlID0gay5nZXRNZXRob2QoInBhcnNlIiwgQ2hhclNlcXVlbmNlLmNsYXNzKTsKKyAgICAgICAgICAgIGlmICghay5pc0Fzc2lnbmFibGVGcm9tKHBhcnNlLmdldFJldHVyblR5cGUoKSkKKyAgICAgICAgICAgICAgICAgICAgfHwgIU1vZGlmaWVyLmlzU3RhdGljKHBhcnNlLmdldE1vZGlmaWVycygpKSkgeworICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaE1ldGhvZEV4Y2VwdGlvbihwYXJzZS50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZmluYWwgTWV0aG9kIHRvTWlsbGlzID0gay5nZXRNZXRob2QoInRvTWlsbGlzIik7CisgICAgICAgICAgICBpZiAoIUxvbmcuVFlQRS5pc0Fzc2lnbmFibGVGcm9tKHRvTWlsbGlzLmdldFJldHVyblR5cGUoKSkKKyAgICAgICAgICAgICAgICAgICAgfHwgTW9kaWZpZXIuaXNTdGF0aWModG9NaWxsaXMuZ2V0TW9kaWZpZXJzKCkpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaE1ldGhvZEV4Y2VwdGlvbih0b01pbGxpcy50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiAoTG9uZykgdG9NaWxsaXMuaW52b2tlKHBhcnNlLmludm9rZShudWxsLCB2YWx1ZSkpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBFeGNlcHRpb25JbkluaXRpYWxpemVyRXJyb3IgRUlJRSkgeworICAgICAgICAgICAgdGhyb3cgd3JhcE9yVGhyb3coRUlJRSk7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24gaXRlKSB7CisgICAgICAgICAgICB0aHJvdyBwYXJhbU9yRXJyb3IoaXRlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlcnRzIGEgbG9jYWxlIHRvIGEgbGFuZ3VhZ2UgdGFnLgorICAgICAqCisgICAgICogQHBhcmFtIGxvY2FsZSB0aGUgbG9jYWxlIHRvIGNvbnZlcnQuCisgICAgICogQHJldHVybiB0aGUgbGFuZ3VhZ2UgdGFnLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIGdpdmVuIGxvY2FsZSBpcyBudWxsLgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjQuNQorICAgICAqLworICAgIHN0YXRpYyBTdHJpbmcgdG9MYW5ndWFnZVRhZyhmaW5hbCBMb2NhbGUgbG9jYWxlKSB7CisgICAgICAgIGZpbmFsIFN0cmluZyBsID0gbG9jYWxlLmdldExhbmd1YWdlKCk7CisgICAgICAgIGZpbmFsIFN0cmluZyBjID0gbG9jYWxlLmdldENvdW50cnkoKTsKKyAgICAgICAgZmluYWwgU3RyaW5nIHYgPSBsb2NhbGUuZ2V0VmFyaWFudCgpOworICAgICAgICBmaW5hbCBjaGFyW10gYiA9IG5ldyBjaGFyW2wubGVuZ3RoKCkgKyBjLmxlbmd0aCgpICsgdi5sZW5ndGgoKSArIDJdOworICAgICAgICBpbnQgY291bnQgPSBsLmxlbmd0aCgpOworICAgICAgICBsLmdldENoYXJzKDAsIGNvdW50LCBiLCAwKTsKKyAgICAgICAgaWYgKGMubGVuZ3RoKCkgIT0gMCB8fCAobC5sZW5ndGgoKSAhPSAwICYmIHYubGVuZ3RoKCkgIT0gMCkpIHsKKyAgICAgICAgICAgIGJbY291bnRdID0gJy0nOworICAgICAgICAgICAgKytjb3VudDsgLy9iZSBuaWNlIHRvIHRoZSBjbGllbnQgY29tcGlsZXIuCisgICAgICAgICAgICBjLmdldENoYXJzKDAsIGMubGVuZ3RoKCksIGIsIGNvdW50KTsKKyAgICAgICAgICAgIGNvdW50ICs9IGMubGVuZ3RoKCk7CisgICAgICAgIH0KKworICAgICAgICBpZiAodi5sZW5ndGgoKSAhPSAwICYmIChsLmxlbmd0aCgpICE9IDAgfHwgYy5sZW5ndGgoKSAhPSAwKSkgeworICAgICAgICAgICAgYltjb3VudF0gPSAnLSc7CisgICAgICAgICAgICArK2NvdW50OyAvL2JlIG5pY2UgdG8gdGhlIGNsaWVudCBjb21waWxlci4KKyAgICAgICAgICAgIHYuZ2V0Q2hhcnMoMCwgdi5sZW5ndGgoKSwgYiwgY291bnQpOworICAgICAgICAgICAgY291bnQgKz0gdi5sZW5ndGgoKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gU3RyaW5nLnZhbHVlT2YoYiwgMCwgY291bnQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBuZXcgZmlsdGVyIGZyb20gdGhlIGdpdmVuIGNsYXNzIG5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSB0aGUgZnVsbHkgcXVhbGlmaWVkIGNsYXNzIG5hbWUuCisgICAgICogQHJldHVybiBhIG5ldyBmaWx0ZXIuCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYgY2xhc3MgbmFtZSBkb2VzIG5vdCBtYXRjaCB0aGUgdHlwZS4KKyAgICAgKiBAdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24gaWYgdGhlIGNsYXNzIG5hbWUgd2FzIG5vdCBmb3VuZC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gaWYgdGhlIGNvbnN0cnVjdG9yIGlzIGluYWNjZXNzaWJsZS4KKyAgICAgKiBAdGhyb3dzIEluc3RhbnRpYXRpb25FeGNlcHRpb24gaWYgdGhlIGdpdmVuIGNsYXNzIG5hbWUgaXMgYWJzdHJhY3QuCisgICAgICogQHRocm93cyBJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uIGlmIHRoZSBjb25zdHJ1Y3RvciB0aHJvd3MgYW4gZXhjZXB0aW9uLgorICAgICAqIEB0aHJvd3MgTGlua2FnZUVycm9yIGlmIHRoZSBsaW5rYWdlIGZhaWxzLgorICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uSW5Jbml0aWFsaXplckVycm9yIGlmIHRoZSBzdGF0aWMgaW5pdGlhbGl6ZXIgZmFpbHMuCisgICAgICogQHRocm93cyBFeGNlcHRpb24gdG8gbWF0Y2ggdGhlIGVycm9yIG1ldGhvZCBvZiB0aGUgRXJyb3JNYW5hZ2VyLgorICAgICAqIEB0aHJvd3MgTm9TdWNoTWV0aG9kRXhjZXB0aW9uIGlmIHRoZSBjbGFzcyBuYW1lIGRvZXMgbm90IGhhdmUgYSBubworICAgICAqIGFyZ3VtZW50IGNvbnN0cnVjdG9yLgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjQuNQorICAgICAqLworICAgIHN0YXRpYyBGaWx0ZXIgbmV3RmlsdGVyKFN0cmluZyBuYW1lKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIG5ld09iamVjdEZyb20obmFtZSwgRmlsdGVyLmNsYXNzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbmV3IGZvcm1hdHRlciBmcm9tIHRoZSBnaXZlbiBjbGFzcyBuYW1lLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgdGhlIGZ1bGx5IHF1YWxpZmllZCBjbGFzcyBuYW1lLgorICAgICAqIEByZXR1cm4gYSBuZXcgZm9ybWF0dGVyLgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIGlmIGNsYXNzIG5hbWUgZG9lcyBub3QgbWF0Y2ggdGhlIHR5cGUuCisgICAgICogQHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGlmIHRoZSBjbGFzcyBuYW1lIHdhcyBub3QgZm91bmQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGlmIHRoZSBjb25zdHJ1Y3RvciBpcyBpbmFjY2Vzc2libGUuCisgICAgICogQHRocm93cyBJbnN0YW50aWF0aW9uRXhjZXB0aW9uIGlmIHRoZSBnaXZlbiBjbGFzcyBuYW1lIGlzIGFic3RyYWN0LgorICAgICAqIEB0aHJvd3MgSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiBpZiB0aGUgY29uc3RydWN0b3IgdGhyb3dzIGFuIGV4Y2VwdGlvbi4KKyAgICAgKiBAdGhyb3dzIExpbmthZ2VFcnJvciBpZiB0aGUgbGlua2FnZSBmYWlscy4KKyAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbkluSW5pdGlhbGl6ZXJFcnJvciBpZiB0aGUgc3RhdGljIGluaXRpYWxpemVyIGZhaWxzLgorICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uIHRvIG1hdGNoIHRoZSBlcnJvciBtZXRob2Qgb2YgdGhlIEVycm9yTWFuYWdlci4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBpZiB0aGUgY2xhc3MgbmFtZSBkb2VzIG5vdCBoYXZlIGEgbm8KKyAgICAgKiBhcmd1bWVudCBjb25zdHJ1Y3Rvci4KKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS40LjUKKyAgICAgKi8KKyAgICBzdGF0aWMgRm9ybWF0dGVyIG5ld0Zvcm1hdHRlcihTdHJpbmcgbmFtZSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBuZXdPYmplY3RGcm9tKG5hbWUsIEZvcm1hdHRlci5jbGFzcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBsb2cgcmVjb3JkIGNvbXBhcmF0b3IgZnJvbSB0aGUgZ2l2ZW4gY2xhc3MgbmFtZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lIHRoZSBmdWxseSBxdWFsaWZpZWQgY2xhc3MgbmFtZS4KKyAgICAgKiBAcmV0dXJuIGEgbmV3IGNvbXBhcmF0b3IuCisgICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYgY2xhc3MgbmFtZSBkb2VzIG5vdCBtYXRjaCB0aGUgdHlwZS4KKyAgICAgKiBAdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24gaWYgdGhlIGNsYXNzIG5hbWUgd2FzIG5vdCBmb3VuZC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gaWYgdGhlIGNvbnN0cnVjdG9yIGlzIGluYWNjZXNzaWJsZS4KKyAgICAgKiBAdGhyb3dzIEluc3RhbnRpYXRpb25FeGNlcHRpb24gaWYgdGhlIGdpdmVuIGNsYXNzIG5hbWUgaXMgYWJzdHJhY3QuCisgICAgICogQHRocm93cyBJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uIGlmIHRoZSBjb25zdHJ1Y3RvciB0aHJvd3MgYW4gZXhjZXB0aW9uLgorICAgICAqIEB0aHJvd3MgTGlua2FnZUVycm9yIGlmIHRoZSBsaW5rYWdlIGZhaWxzLgorICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uSW5Jbml0aWFsaXplckVycm9yIGlmIHRoZSBzdGF0aWMgaW5pdGlhbGl6ZXIgZmFpbHMuCisgICAgICogQHRocm93cyBFeGNlcHRpb24gdG8gbWF0Y2ggdGhlIGVycm9yIG1ldGhvZCBvZiB0aGUgRXJyb3JNYW5hZ2VyLgorICAgICAqIEB0aHJvd3MgTm9TdWNoTWV0aG9kRXhjZXB0aW9uIGlmIHRoZSBjbGFzcyBuYW1lIGRvZXMgbm90IGhhdmUgYSBubworICAgICAqIGFyZ3VtZW50IGNvbnN0cnVjdG9yLgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjQuNQorICAgICAqIEBzZWUgamF2YS51dGlsLmxvZ2dpbmcuTG9nUmVjb3JkCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgc3RhdGljIENvbXBhcmF0b3I8PyBzdXBlciBMb2dSZWNvcmQ+IG5ld0NvbXBhcmF0b3IoU3RyaW5nIG5hbWUpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICByZXR1cm4gbmV3T2JqZWN0RnJvbShuYW1lLCBDb21wYXJhdG9yLmNsYXNzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgY29tcGFyYXRvciB0aGF0IGltcG9zZXMgdGhlIHJldmVyc2Ugb3JkZXJpbmcgb2YgdGhlIHNwZWNpZmllZAorICAgICAqIHtAbGluayBDb21wYXJhdG9yfS4gSWYgdGhlIGdpdmVuIGNvbXBhcmF0b3IgZGVjbGFyZXMgYSBwdWJsaWMKKyAgICAgKiByZXZlcnNlT3JkZXIgbWV0aG9kIHRoYXQgbWV0aG9kIGlzIGNhbGxlZCBmaXJzdCBhbmQgdGhlIHJldHVybiB2YWx1ZSBpcworICAgICAqIHVzZWQuIElmIHRoYXQgbWV0aG9kIGlzIG5vdCBkZWNsYXJlZCBvciB0aGUgY2FsbGVyIGRvZXMgbm90IGhhdmUgYWNjZXNzCisgICAgICogdGhlbiBhIGNvbXBhcmF0b3Igd3JhcHBpbmcgdGhlIGdpdmVuIGNvbXBhcmF0b3IgaXMgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gPFQ+IHRoZSBlbGVtZW50IHR5cGUgdG8gYmUgY29tcGFyZWQKKyAgICAgKiBAcGFyYW0gYyBhIGNvbXBhcmF0b3Igd2hvc2Ugb3JkZXJpbmcgaXMgdG8gYmUgcmV2ZXJzZWQgYnkgdGhlIHJldHVybmVkCisgICAgICogY29tcGFyYXRvcgorICAgICAqIEByZXR1cm4gQSBjb21wYXJhdG9yIHRoYXQgaW1wb3NlcyB0aGUgcmV2ZXJzZSBvcmRlcmluZyBvZiB0aGUgc3BlY2lmaWVkCisgICAgICogY29tcGFyYXRvci4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBnaXZlbiBjb21wYXJhdG9yIGlzIG51bGwuCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNS4wCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bmNoZWNrZWQiLCAiVGhyb3dhYmxlUmVzdWx0SWdub3JlZCJ9KQorICAgIHN0YXRpYyA8VD4gQ29tcGFyYXRvcjxUPiByZXZlcnNlT3JkZXIoZmluYWwgQ29tcGFyYXRvcjxUPiBjKSB7CisgICAgICAgIGlmIChjID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgQ29tcGFyYXRvcjxUPiByZXZlcnNlID0gbnVsbDsKKyAgICAgICAgLy9Db21wYXJhdG9yIGluIEphdmEgMS44IGhhcyAncmV2ZXJzZWQnIGFzIGEgZGVmYXVsdCBtZXRob2QuCisgICAgICAgIC8vVGhpcyBjb2RlIGNhbGxzIHRoYXQgbWV0aG9kIGZpcnN0IHRvIGFsbG93IGN1c3RvbQorICAgICAgICAvL2NvZGUgdG8gZGVmaW5lIHdoYXQgcmV2ZXJzZSBvcmRlciBtZWFucy4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vYXNzZXJ0IE1vZGlmaWVyLmlzUHVibGljKGMuZ2V0Q2xhc3MoKS5nZXRNb2RpZmllcnMoKSkgOgorICAgICAgICAgICAgLy8gICAgICAgIE1vZGlmaWVyLnRvU3RyaW5nKGMuZ2V0Q2xhc3MoKS5nZXRNb2RpZmllcnMoKSk7CisgICAgICAgICAgICBmaW5hbCBNZXRob2QgbSA9IGMuZ2V0Q2xhc3MoKS5nZXRNZXRob2QoInJldmVyc2VkIik7CisgICAgICAgICAgICBpZiAoIU1vZGlmaWVyLmlzU3RhdGljKG0uZ2V0TW9kaWZpZXJzKCkpCisgICAgICAgICAgICAgICAgICAgICYmIENvbXBhcmF0b3IuY2xhc3MuaXNBc3NpZ25hYmxlRnJvbShtLmdldFJldHVyblR5cGUoKSkpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICByZXZlcnNlID0gKENvbXBhcmF0b3I8VD4pIG0uaW52b2tlKGMpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGZpbmFsIEV4Y2VwdGlvbkluSW5pdGlhbGl6ZXJFcnJvciBlaWllKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IHdyYXBPclRocm93KGVpaWUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoZmluYWwgTm9TdWNoTWV0aG9kRXhjZXB0aW9uIGlnbm9yZSkgeworICAgICAgICB9IGNhdGNoIChmaW5hbCBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGlnbm9yZSkgeworICAgICAgICB9IGNhdGNoIChmaW5hbCBSdW50aW1lRXhjZXB0aW9uIGlnbm9yZSkgeworICAgICAgICB9IGNhdGNoIChmaW5hbCBJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uIGl0ZSkgeworICAgICAgICAgICAgcGFyYW1PckVycm9yKGl0ZSk7IC8vSWdub3JlIGludm9jYXRpb24gYnVncyAocmV0dXJuZWQgdmFsdWVzKS4KKyAgICAgICAgfQorCisgICAgICAgIGlmIChyZXZlcnNlID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldmVyc2UgPSBDb2xsZWN0aW9ucy5yZXZlcnNlT3JkZXIoYyk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJldmVyc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBlcnJvciBtYW5hZ2VyIGZyb20gdGhlIGdpdmVuIGNsYXNzIG5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSB0aGUgZnVsbHkgcXVhbGlmaWVkIGNsYXNzIG5hbWUuCisgICAgICogQHJldHVybiBhIG5ldyBlcnJvciBtYW5hZ2VyLgorICAgICAqIEB0aHJvd3MgQ2xhc3NDYXN0RXhjZXB0aW9uIGlmIGNsYXNzIG5hbWUgZG9lcyBub3QgbWF0Y2ggdGhlIHR5cGUuCisgICAgICogQHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGlmIHRoZSBjbGFzcyBuYW1lIHdhcyBub3QgZm91bmQuCisgICAgICogQHRocm93cyBJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGlmIHRoZSBjb25zdHJ1Y3RvciBpcyBpbmFjY2Vzc2libGUuCisgICAgICogQHRocm93cyBJbnN0YW50aWF0aW9uRXhjZXB0aW9uIGlmIHRoZSBnaXZlbiBjbGFzcyBuYW1lIGlzIGFic3RyYWN0LgorICAgICAqIEB0aHJvd3MgSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiBpZiB0aGUgY29uc3RydWN0b3IgdGhyb3dzIGFuIGV4Y2VwdGlvbi4KKyAgICAgKiBAdGhyb3dzIExpbmthZ2VFcnJvciBpZiB0aGUgbGlua2FnZSBmYWlscy4KKyAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbkluSW5pdGlhbGl6ZXJFcnJvciBpZiB0aGUgc3RhdGljIGluaXRpYWxpemVyIGZhaWxzLgorICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uIHRvIG1hdGNoIHRoZSBlcnJvciBtZXRob2Qgb2YgdGhlIEVycm9yTWFuYWdlci4KKyAgICAgKiBAdGhyb3dzIE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBpZiB0aGUgY2xhc3MgbmFtZSBkb2VzIG5vdCBoYXZlIGEgbm8KKyAgICAgKiBhcmd1bWVudCBjb25zdHJ1Y3Rvci4KKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS40LjUKKyAgICAgKi8KKyAgICBzdGF0aWMgRXJyb3JNYW5hZ2VyIG5ld0Vycm9yTWFuYWdlcihTdHJpbmcgbmFtZSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBuZXdPYmplY3RGcm9tKG5hbWUsIEVycm9yTWFuYWdlci5jbGFzcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyBpZiB0aGUgZ2l2ZW4gY2xhc3MgbmFtZSBpZGVudGlmaWVzIGEgdXRpbGl0eSBjbGFzcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lIHRoZSBmdWxseSBxdWFsaWZpZWQgY2xhc3MgbmFtZS4KKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGdpdmVuIGNsYXNzIG5hbWUKKyAgICAgKiBAdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24gaWYgdGhlIGNsYXNzIG5hbWUgd2FzIG5vdCBmb3VuZC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gaWYgdGhlIGNvbnN0cnVjdG9yIGlzIGluYWNjZXNzaWJsZS4KKyAgICAgKiBAdGhyb3dzIExpbmthZ2VFcnJvciBpZiB0aGUgbGlua2FnZSBmYWlscy4KKyAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbkluSW5pdGlhbGl6ZXJFcnJvciBpZiB0aGUgc3RhdGljIGluaXRpYWxpemVyIGZhaWxzLgorICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uIHRvIG1hdGNoIHRoZSBlcnJvciBtZXRob2Qgb2YgdGhlIEVycm9yTWFuYWdlci4KKyAgICAgKiBAdGhyb3dzIFNlY3VyaXR5RXhjZXB0aW9uIGlmIHVuYWJsZSB0byBpbnNwZWN0IHByb3BlcnRpZXMgb2YgY2xhc3MuCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNS4yCisgICAgICovCisgICAgc3RhdGljIGJvb2xlYW4gaXNTdGF0aWNVdGlsaXR5Q2xhc3MoU3RyaW5nIG5hbWUpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBDbGFzczw/PiBjID0gZmluZENsYXNzKG5hbWUpOworICAgICAgICBmaW5hbCBDbGFzczw/PiBvYmogPSBPYmplY3QuY2xhc3M7CisgICAgICAgIE1ldGhvZFtdIG1ldGhvZHM7CisgICAgICAgIGJvb2xlYW4gdXRpbDsKKyAgICAgICAgaWYgKGMgIT0gb2JqICYmIChtZXRob2RzID0gYy5nZXRNZXRob2RzKCkpLmxlbmd0aCAhPSAwKSB7CisgICAgICAgICAgICB1dGlsID0gdHJ1ZTsKKyAgICAgICAgICAgIGZvciAoTWV0aG9kIG0gOiBtZXRob2RzKSB7CisgICAgICAgICAgICAgICAgaWYgKG0uZ2V0RGVjbGFyaW5nQ2xhc3MoKSAhPSBvYmoKKyAgICAgICAgICAgICAgICAgICAgICAgICYmICFNb2RpZmllci5pc1N0YXRpYyhtLmdldE1vZGlmaWVycygpKSkgeworICAgICAgICAgICAgICAgICAgICB1dGlsID0gZmFsc2U7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHV0aWwgPSBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdXRpbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIGlmIHRoZSBnaXZlbiBjbGFzcyBuYW1lIGlzIGEgcmVmbGVjdGlvbiBjbGFzcyBuYW1lIHJlc3BvbnNpYmxlCisgICAgICogZm9yIGludm9raW5nIG1ldGhvZHMgYW5kIG9yIGNvbnN0cnVjdG9ycy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lIHRoZSBmdWxseSBxdWFsaWZpZWQgY2xhc3MgbmFtZS4KKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGdpdmVuIGNsYXNzIG5hbWUKKyAgICAgKiBAdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24gaWYgdGhlIGNsYXNzIG5hbWUgd2FzIG5vdCBmb3VuZC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gaWYgdGhlIGNvbnN0cnVjdG9yIGlzIGluYWNjZXNzaWJsZS4KKyAgICAgKiBAdGhyb3dzIExpbmthZ2VFcnJvciBpZiB0aGUgbGlua2FnZSBmYWlscy4KKyAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbkluSW5pdGlhbGl6ZXJFcnJvciBpZiB0aGUgc3RhdGljIGluaXRpYWxpemVyIGZhaWxzLgorICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uIHRvIG1hdGNoIHRoZSBlcnJvciBtZXRob2Qgb2YgdGhlIEVycm9yTWFuYWdlci4KKyAgICAgKiBAdGhyb3dzIFNlY3VyaXR5RXhjZXB0aW9uIGlmIHVuYWJsZSB0byBpbnNwZWN0IHByb3BlcnRpZXMgb2YgY2xhc3MuCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNS4yCisgICAgICovCisgICAgc3RhdGljIGJvb2xlYW4gaXNSZWZsZWN0aW9uQ2xhc3MoU3RyaW5nIG5hbWUpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmdbXSBuYW1lcyA9IFJFRkxFQ1RfTkFNRVM7CisgICAgICAgIGlmIChuYW1lcyA9PSBudWxsKSB7IC8vQmVuaWduIGRhdGEgcmFjZS4KKyAgICAgICAgICAgIFJFRkxFQ1RfTkFNRVMgPSBuYW1lcyA9IHJlZmxlY3Rpb25DbGFzc05hbWVzKCk7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKFN0cmluZyByZiA6IG5hbWVzKSB7IC8vVGhlIHNldCBvZiBuYW1lcyBpcyBzbWFsbC4KKyAgICAgICAgICAgIGlmIChuYW1lLmVxdWFscyhyZikpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGZpbmRDbGFzcyhuYW1lKTsgLy9GYWlsIGxhdGUgaW5zdGVhZCBvZiBub3JtYWwgcmV0dXJuLgorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyBhbGwgb2YgdGhlIHJlZmxlY3Rpb24gY2xhc3MgbmFtZXMgdXNlZCB0byBpbnZva2UgbWV0aG9kcy4KKyAgICAgKgorICAgICAqIFRoaXMgbWV0aG9kIHBlcmZvcm1zIGluZGlyZWN0IGFuZCBkaXJlY3QgY2FsbHMgb24gYSB0aHJvd2FibGUgdG8gY2FwdHVyZQorICAgICAqIHRoZSBzdGFuZGFyZCBjbGFzcyBuYW1lcyBhbmQgdGhlIGltcGxlbWVudGF0aW9uIGNsYXNzIG5hbWVzLgorICAgICAqCisgICAgICogQHJldHVybiBhIHN0cmluZyBhcnJheSBjb250YWluaW5nIHRoZSBmdWxseSBxdWFsaWZpZWQgY2xhc3MgbmFtZXMuCisgICAgICogQHRocm93cyBFeGNlcHRpb24gaWYgdGhlcmUgaXMgYSBwcm9ibGVtLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZ1tdIHJlZmxlY3Rpb25DbGFzc05hbWVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIENsYXNzPD8+IHRoaXNDbGFzcyA9IExvZ01hbmFnZXJQcm9wZXJ0aWVzLmNsYXNzOworICAgICAgICBhc3NlcnQgTW9kaWZpZXIuaXNGaW5hbCh0aGlzQ2xhc3MuZ2V0TW9kaWZpZXJzKCkpIDogdGhpc0NsYXNzOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmluYWwgSGFzaFNldDxTdHJpbmc+IHRyYWNlcyA9IG5ldyBIYXNoU2V0PD4oKTsKKyAgICAgICAgICAgIFRocm93YWJsZSB0ID0gVGhyb3dhYmxlLmNsYXNzLmdldENvbnN0cnVjdG9yKCkubmV3SW5zdGFuY2UoKTsKKyAgICAgICAgICAgIGZvciAoU3RhY2tUcmFjZUVsZW1lbnQgc3RlIDogdC5nZXRTdGFja1RyYWNlKCkpIHsKKyAgICAgICAgICAgICAgICBpZiAoIXRoaXNDbGFzcy5nZXROYW1lKCkuZXF1YWxzKHN0ZS5nZXRDbGFzc05hbWUoKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgdHJhY2VzLmFkZChzdGUuZ2V0Q2xhc3NOYW1lKCkpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgVGhyb3dhYmxlLmNsYXNzLmdldE1ldGhvZCgiZmlsbEluU3RhY2tUcmFjZSIpLmludm9rZSh0KTsKKyAgICAgICAgICAgIGZvciAoU3RhY2tUcmFjZUVsZW1lbnQgc3RlIDogdC5nZXRTdGFja1RyYWNlKCkpIHsKKyAgICAgICAgICAgICAgICBpZiAoIXRoaXNDbGFzcy5nZXROYW1lKCkuZXF1YWxzKHN0ZS5nZXRDbGFzc05hbWUoKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgdHJhY2VzLmFkZChzdGUuZ2V0Q2xhc3NOYW1lKCkpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiB0cmFjZXMudG9BcnJheShuZXcgU3RyaW5nW3RyYWNlcy5zaXplKCldKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiBJVEUpIHsKKyAgICAgICAgICAgIHRocm93IHBhcmFtT3JFcnJvcihJVEUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIG5ldyBvYmplY3QgZnJvbSB0aGUgZ2l2ZW4gY2xhc3MgbmFtZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSA8VD4gVGhlIGdlbmVyaWMgY2xhc3MgdHlwZS4KKyAgICAgKiBAcGFyYW0gbmFtZSB0aGUgZnVsbHkgcXVhbGlmaWVkIGNsYXNzIG5hbWUuCisgICAgICogQHBhcmFtIHR5cGUgdGhlIGFzc2lnbmFibGUgdHlwZSBmb3IgdGhlIGdpdmVuIG5hbWUuCisgICAgICogQHJldHVybiBhIG5ldyBvYmplY3QgYXNzaWduYWJsZSB0byB0aGUgZ2l2ZW4gdHlwZS4KKyAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiBpZiBjbGFzcyBuYW1lIGRvZXMgbm90IG1hdGNoIHRoZSB0eXBlLgorICAgICAqIEB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBpZiB0aGUgY2xhc3MgbmFtZSB3YXMgbm90IGZvdW5kLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBpZiB0aGUgY29uc3RydWN0b3IgaXMgaW5hY2Nlc3NpYmxlLgorICAgICAqIEB0aHJvd3MgSW5zdGFudGlhdGlvbkV4Y2VwdGlvbiBpZiB0aGUgZ2l2ZW4gY2xhc3MgbmFtZSBpcyBhYnN0cmFjdC4KKyAgICAgKiBAdGhyb3dzIEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24gaWYgdGhlIGNvbnN0cnVjdG9yIHRocm93cyBhbiBleGNlcHRpb24uCisgICAgICogQHRocm93cyBMaW5rYWdlRXJyb3IgaWYgdGhlIGxpbmthZ2UgZmFpbHMuCisgICAgICogQHRocm93cyBFeGNlcHRpb25JbkluaXRpYWxpemVyRXJyb3IgaWYgdGhlIHN0YXRpYyBpbml0aWFsaXplciBmYWlscy4KKyAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbiB0byBtYXRjaCB0aGUgZXJyb3IgbWV0aG9kIG9mIHRoZSBFcnJvck1hbmFnZXIuCisgICAgICogQHRocm93cyBOb1N1Y2hNZXRob2RFeGNlcHRpb24gaWYgdGhlIGNsYXNzIG5hbWUgZG9lcyBub3QgaGF2ZSBhIG5vCisgICAgICogYXJndW1lbnQgY29uc3RydWN0b3IuCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNC41CisgICAgICovCisgICAgc3RhdGljIDxUPiBUIG5ld09iamVjdEZyb20oU3RyaW5nIG5hbWUsIENsYXNzPFQ+IHR5cGUpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmluYWwgQ2xhc3M8Pz4gY2xhenogPSBMb2dNYW5hZ2VyUHJvcGVydGllcy5maW5kQ2xhc3MobmFtZSk7CisgICAgICAgICAgICAvL1RoaXMgY2hlY2sgYXZvaWRzIGFkZGl0aW9uYWwgc2lkZSBlZmZlY3RzIHdoZW4gdGhlIG5hbWUgcGFyYW1ldGVyCisgICAgICAgICAgICAvL2lzIGEgbGl0ZXJhbCBuYW1lIGFuZCBub3QgYSBjbGFzcyBuYW1lLgorICAgICAgICAgICAgaWYgKHR5cGUuaXNBc3NpZ25hYmxlRnJvbShjbGF6eikpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHlwZS5jYXN0KGNsYXp6LmdldENvbnN0cnVjdG9yKCkubmV3SW5zdGFuY2UoKSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiBJVEUpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgcGFyYW1PckVycm9yKElURSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xhc3NDYXN0RXhjZXB0aW9uKGNsYXp6LmdldE5hbWUoKQorICAgICAgICAgICAgICAgICAgICAgICAgKyAiIGNhbm5vdCBiZSBjYXN0IHRvICIgKyB0eXBlLmdldE5hbWUoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIE5vQ2xhc3NEZWZGb3VuZEVycm9yIE5DREZFKSB7CisgICAgICAgICAgICAvL05vIGNsYXNzIGRlZiBmb3VuZCBjYW4gb2NjdXIgb24gZmlsZXN5c3RlbXMgdGhhdCBhcmUKKyAgICAgICAgICAgIC8vY2FzZSBpbnNlbnNpdGl2ZSAoQlVHIElEIDYxOTYwNjgpLiAgSW4gc29tZSBjYXNlcywgd2UgYWxsb3cgY2xhc3MKKyAgICAgICAgICAgIC8vbmFtZXMgb3IgbGl0ZXJhbCBuYW1lcywgdGhpcyBjb2RlIGd1YXJkcyBhZ2FpbnN0IHRoZSBjYXNlIHdoZXJlIGEKKyAgICAgICAgICAgIC8vbGl0ZXJhbCBuYW1lIGhhcHBlbnMgdG8gbWF0Y2ggYSBjbGFzcyBuYW1lIGluIGEgZGlmZmVyZW50IGNhc2UuCisgICAgICAgICAgICAvL1RoaXMgaXMgYWxzbyBhIG5pY2Ugd2F5IHRvIGFkYXB0IHRoaXMgZXJyb3IgZm9yIHRoZSBlcnJvciBtYW5hZ2VyLgorICAgICAgICAgICAgdGhyb3cgbmV3IENsYXNzTm90Rm91bmRFeGNlcHRpb24oTkNERkUudG9TdHJpbmcoKSwgTkNERkUpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBFeGNlcHRpb25JbkluaXRpYWxpemVyRXJyb3IgRUlJRSkgeworICAgICAgICAgICAgdGhyb3cgd3JhcE9yVGhyb3coRUlJRSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBnaXZlbiBleGNlcHRpb24gb3IgdGhyb3dzIHRoZSBlc2NhcGluZyBjYXVzZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpdGUgYW55IGludm9jYXRpb24gdGFyZ2V0LgorICAgICAqIEByZXR1cm4gdGhlIGV4Y2VwdGlvbi4KKyAgICAgKiBAdGhyb3dzIFZpcnR1YWxNYWNoaW5lRXJyb3IgaWYgcHJlc2VudCBhcyBjYXVzZS4KKyAgICAgKiBAdGhyb3dzIFRocmVhZERlYXRoIGlmIHByZXNlbnQgYXMgY2F1c2UuCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNC41CisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgRXhjZXB0aW9uIHBhcmFtT3JFcnJvcihJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uIGl0ZSkgeworICAgICAgICBmaW5hbCBUaHJvd2FibGUgY2F1c2UgPSBpdGUuZ2V0Q2F1c2UoKTsKKyAgICAgICAgaWYgKGNhdXNlICE9IG51bGwpIHsKKyAgICAgICAgICAgIC8vQml0d2lzZSBpbmNsdXNpdmUgT1IgcHJvZHVjZXMgdGlnaHRlciBieXRlY29kZSBmb3IgaW5zdGFuY2VvZgorICAgICAgICAgICAgLy9hbmQgbWF0Y2hlcyB3aXRoIG11bHRpY2F0Y2ggc3ludGF4LgorICAgICAgICAgICAgaWYgKGNhdXNlIGluc3RhbmNlb2YgVmlydHVhbE1hY2hpbmVFcnJvcgorICAgICAgICAgICAgICAgICAgICB8IGNhdXNlIGluc3RhbmNlb2YgVGhyZWFkRGVhdGgpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyAoRXJyb3IpIGNhdXNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBpdGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhyb3dzIHRoZSBnaXZlbiBlcnJvciBpZiB0aGUgY2F1c2UgaXMgYW4gZXJyb3Igb3RoZXJ3aXNlIHRoZSBnaXZlbiBlcnJvcgorICAgICAqIGlzIHdyYXBwZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZWlpZSB0aGUgZXJyb3IuCisgICAgICogQHJldHVybiBhbiBJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uLgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjUuMAorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24gd3JhcE9yVGhyb3coCisgICAgICAgICAgICBFeGNlcHRpb25JbkluaXRpYWxpemVyRXJyb3IgZWlpZSkgeworICAgICAgICAvL1RoaXMgbGlua2FnZSBlcnJvciB3aWxsIGVzY2FwZSB0aGUgY29uc3RydWN0b3IgbmV3IGluc3RhbmNlIGNhbGwuCisgICAgICAgIC8vSWYgdGhlIGNhdXNlIGlzIGFuIGVycm9yLCByZXRocm93IHRvIHNraXAgYW55IGVycm9yIG1hbmFnZXIuCisgICAgICAgIGlmIChlaWllLmdldENhdXNlKCkgaW5zdGFuY2VvZiBFcnJvcikgeworICAgICAgICAgICAgdGhyb3cgZWlpZTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vQ29uc2lkZXJlZCBhIGJ1ZyBpbiB0aGUgY29kZSwgd3JhcCB0aGUgZXJyb3Igc28gaXQgY2FuIGJlCisgICAgICAgICAgICAvL3JlcG9ydGVkIHRvIHRoZSBlcnJvciBtYW5hZ2VyLgorICAgICAgICAgICAgcmV0dXJuIG5ldyBJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uKGVpaWUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBjb2RlIGlzIG1vZGlmaWVkIGZyb20gdGhlIExvZ01hbmFnZXIsIHdoaWNoIGV4cGxpY3RseSBzdGF0ZXMKKyAgICAgKiBzZWFyY2hpbmcgdGhlIHN5c3RlbSBjbGFzcyBsb2FkZXIgZmlyc3QsIHRoZW4gdGhlIGNvbnRleHQgY2xhc3MgbG9hZGVyLgorICAgICAqIFRoZXJlIGlzIHJlc2lzdGFuY2UgKGNvbXBhdGliaWxpdHkpIHRvIGNoYW5nZSB0aGlzIGJlaGF2aW9yIHRvIHNpbXBseQorICAgICAqIHNlYXJjaGluZyB0aGUgY29udGV4dCBjbGFzcyBsb2FkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZSBmdWxsIGNsYXNzIG5hbWUKKyAgICAgKiBAcmV0dXJuIHRoZSBjbGFzcy4KKyAgICAgKiBAdGhyb3dzIExpbmthZ2VFcnJvciBpZiB0aGUgbGlua2FnZSBmYWlscy4KKyAgICAgKiBAdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24gaWYgdGhlIGNsYXNzIG5hbWUgd2FzIG5vdCBmb3VuZC4KKyAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbkluSW5pdGlhbGl6ZXJFcnJvciBpZiBzdGF0aWMgaW5pdGlhbGl6ZXIgZmFpbHMuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgQ2xhc3M8Pz4gZmluZENsYXNzKFN0cmluZyBuYW1lKSB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgIENsYXNzTG9hZGVyW10gbG9hZGVycyA9IGdldENsYXNzTG9hZGVycygpOworICAgICAgICBhc3NlcnQgbG9hZGVycy5sZW5ndGggPT0gMiA6IGxvYWRlcnMubGVuZ3RoOworICAgICAgICBDbGFzczw/PiBjbGF6ejsKKyAgICAgICAgaWYgKGxvYWRlcnNbMF0gIT0gbnVsbCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBjbGF6eiA9IENsYXNzLmZvck5hbWUobmFtZSwgZmFsc2UsIGxvYWRlcnNbMF0pOworICAgICAgICAgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB0cnlDb250ZXh0KSB7CisgICAgICAgICAgICAgICAgY2xhenogPSB0cnlMb2FkKG5hbWUsIGxvYWRlcnNbMV0pOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgY2xhenogPSB0cnlMb2FkKG5hbWUsIGxvYWRlcnNbMV0pOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjbGF6ejsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb2FkcyBhIGNsYXNzIHVzaW5nIHRoZSBnaXZlbiBsb2FkZXIgb3IgdGhlIGNsYXNzIGxvYWRlciBvZiB0aGlzIGNsYXNzLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgdGhlIGNsYXNzIG5hbWUuCisgICAgICogQHBhcmFtIGwgYW55IGNsYXNzIGxvYWRlciBvciBudWxsLgorICAgICAqIEByZXR1cm4gdGhlIHJhdyBjbGFzcy4KKyAgICAgKiBAdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24gaWYgbm90IGZvdW5kLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIENsYXNzPD8+IHRyeUxvYWQoU3RyaW5nIG5hbWUsIENsYXNzTG9hZGVyIGwpIHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGwgIT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIENsYXNzLmZvck5hbWUobmFtZSwgZmFsc2UsIGwpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIENsYXNzLmZvck5hbWUobmFtZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBjbGFzcyBsb2FkZXJzIHVzaW5nIGVsZXZhdGVkIHByaXZpbGVnZXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFueSBhcnJheSBvZiBjbGFzcyBsb2FkZXJzLiBJbmRleGVzIG1heSBiZSBudWxsLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIENsYXNzTG9hZGVyW10gZ2V0Q2xhc3NMb2FkZXJzKCkgeworICAgICAgICByZXR1cm4gQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQobmV3IFByaXZpbGVnZWRBY3Rpb248Q2xhc3NMb2FkZXJbXT4oKSB7CisKKyAgICAgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJvdmVycmlkZSIpIC8vSkRLLTY5NTQyMzQKKyAgICAgICAgICAgIHB1YmxpYyBDbGFzc0xvYWRlcltdIHJ1bigpIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBDbGFzc0xvYWRlcltdIGxvYWRlcnMgPSBuZXcgQ2xhc3NMb2FkZXJbMl07CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgbG9hZGVyc1swXSA9IENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gaWdub3JlKSB7CisgICAgICAgICAgICAgICAgICAgIGxvYWRlcnNbMF0gPSBudWxsOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGxvYWRlcnNbMV0gPSBUaHJlYWQuY3VycmVudFRocmVhZCgpLmdldENvbnRleHRDbGFzc0xvYWRlcigpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGlnbm9yZSkgeworICAgICAgICAgICAgICAgICAgICBsb2FkZXJzWzFdID0gbnVsbDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIGxvYWRlcnM7CisgICAgICAgICAgICB9CisgICAgICAgIH0pOworICAgIH0KKyAgICAvKioKKyAgICAgKiBUaGUgbmFtZXNwYWNlIHByZWZpeCB0byBzZWFyY2ggTG9nTWFuYWdlciBhbmQgZGVmYXVsdHMuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgcHJlZml4OworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIGxvZyBtYW5hZ2VyIHByb3BlcnRpZXMgb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIHBhcmVudCB0aGUgcGFyZW50IHByb3BlcnRpZXMuCisgICAgICogQHBhcmFtIHByZWZpeCB0aGUgbmFtZXNwYWNlIHByZWZpeC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDx0dD5wcmVmaXg8L3R0PiBvciA8dHQ+cGFyZW50PC90dD4gaXMKKyAgICAgKiA8dHQ+bnVsbDwvdHQ+LgorICAgICAqLworICAgIExvZ01hbmFnZXJQcm9wZXJ0aWVzKGZpbmFsIFByb3BlcnRpZXMgcGFyZW50LCBmaW5hbCBTdHJpbmcgcHJlZml4KSB7CisgICAgICAgIHN1cGVyKHBhcmVudCk7CisgICAgICAgIGlmIChwYXJlbnQgPT0gbnVsbCB8fCBwcmVmaXggPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5wcmVmaXggPSBwcmVmaXg7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHByb3BlcnRpZXMgb2JqZWN0IHRoYXQgY29udGFpbnMgYSBzbmFwc2hvdCBvZiB0aGUgY3VycmVudAorICAgICAqIHN0YXRlLiBUaGlzIG1ldGhvZCB2aW9sYXRlcyB0aGUgY2xvbmUgY29udHJhY3Qgc28gdGhhdCBubyBpbnN0YW5jZXMgb2YKKyAgICAgKiBMb2dNYW5hZ2VyUHJvcGVydGllcyBpcyBleHBvcnRlZCBmb3IgcHVibGljIHVzZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHNuYXBzaG90LgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjQuNAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJDbG9uZURvZXNudENhbGxTdXBlckNsb25lIikKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgcmV0dXJuIGV4cG9ydENvcHkoZGVmYXVsdHMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNlYXJjaGVzIGRlZmF1bHRzLCB0aGVuIHNlYXJjaGVzIHRoZSBsb2cgbWFuYWdlciBpZiBhdmFpbGFibGUgb3IgdGhlCisgICAgICogc3lzdGVtIHByb3BlcnRpZXMgYnkgdGhlIHByZWZpeCBwcm9wZXJ0eSwgYW5kIHRoZW4gYnkgdGhlIGtleSBpdHNlbGYuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5IGEgbm9uIG51bGwga2V5LgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIGZvciB0aGF0IGtleS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIFN0cmluZyBnZXRQcm9wZXJ0eShmaW5hbCBTdHJpbmcga2V5KSB7CisgICAgICAgIFN0cmluZyB2YWx1ZSA9IGRlZmF1bHRzLmdldFByb3BlcnR5KGtleSk7CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgICBpZiAoa2V5Lmxlbmd0aCgpID4gMCkgeworICAgICAgICAgICAgICAgIHZhbHVlID0gZnJvbUxvZ01hbmFnZXIocHJlZml4ICsgJy4nICsga2V5KTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB2YWx1ZSA9IGZyb21Mb2dNYW5hZ2VyKGtleSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8qKgorICAgICAgICAgICAgICogQ29weSB0aGUgbG9nIG1hbmFnZXIgcHJvcGVydGllcyBhcyB3ZSByZWFkIHRoZW0uIElmIGEgdmFsdWUgaXMgbm8KKyAgICAgICAgICAgICAqIGxvbmdlciBwcmVzZW50IGluIHRoZSBMb2dNYW5hZ2VyIHJlYWQgaXQgZnJvbSBoZXJlLiBUaGUgcmVhc29uCisgICAgICAgICAgICAgKiB0aGlzIHdvcmtzIGlzIGJlY2F1c2UgTG9nTWFuYWdlci5yZXNldCgpIGNsb3NlcyBhbGwgYXR0YWNoZWQKKyAgICAgICAgICAgICAqIGhhbmRsZXJzIHRoZXJlZm9yZSwgc3RhbGUgdmFsdWVzIG9ubHkgZXhpc3QgaW4gY2xvc2VkIGhhbmRsZXJzLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHN1cGVyLnB1dChrZXksIHZhbHVlKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgT2JqZWN0IHYgPSBzdXBlci5nZXQoa2V5KTsgLy9kZWZhdWx0cyBhcmUgbm90IHVzZWQuCisgICAgICAgICAgICAgICAgdmFsdWUgPSB2IGluc3RhbmNlb2YgU3RyaW5nID8gKFN0cmluZykgdiA6IG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENhbGxzIGdldFByb3BlcnR5IGRpcmVjdGx5LiBJZiBnZXRQcm9wZXJ0eSByZXR1cm5zIG51bGwgdGhlIGRlZmF1bHQgdmFsdWUKKyAgICAgKiBpcyByZXR1cm5lZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkgYSBrZXkgdG8gc2VhcmNoIGZvci4KKyAgICAgKiBAcGFyYW0gZGVmIHRoZSBkZWZhdWx0IHZhbHVlIHRvIHVzZSBpZiBub3QgZm91bmQuCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgZm9yIHRoZSBrZXkuCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNC40CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXRQcm9wZXJ0eShmaW5hbCBTdHJpbmcga2V5LCBmaW5hbCBTdHJpbmcgZGVmKSB7CisgICAgICAgIGZpbmFsIFN0cmluZyB2YWx1ZSA9IHRoaXMuZ2V0UHJvcGVydHkoa2V5KTsKKyAgICAgICAgcmV0dXJuIHZhbHVlID09IG51bGwgPyBkZWYgOiB2YWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXF1aXJlZCB0byB3b3JrIHdpdGggUHJvcFV0aWwuIENhbGxzIGdldFByb3BlcnR5IGRpcmVjdGx5IGlmIHRoZSBnaXZlbgorICAgICAqIGtleSBpcyBhIHN0cmluZy4gT3RoZXJ3aXNlLCBwZXJmb3JtcyBhIGdldCBvcGVyYXRpb24gb24gdGhlIGRlZmF1bHRzCisgICAgICogZm9sbG93ZWQgYnkgdGhlIG5vcm1hbCBoYXNoIHRhYmxlIGdldC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkgYW55IGtleS4KKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBmb3IgdGhlIGtleSBvciBudWxsLgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjQuNQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgT2JqZWN0IGdldChmaW5hbCBPYmplY3Qga2V5KSB7CisgICAgICAgIE9iamVjdCB2YWx1ZTsKKyAgICAgICAgaWYgKGtleSBpbnN0YW5jZW9mIFN0cmluZykgeworICAgICAgICAgICAgdmFsdWUgPSBnZXRQcm9wZXJ0eSgoU3RyaW5nKSBrZXkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdmFsdWUgPSBudWxsOworICAgICAgICB9CisKKyAgICAgICAgLy9TZWFyY2ggZm9yIG5vbi1zdHJpbmcgdmFsdWUuCisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgICB2YWx1ZSA9IGRlZmF1bHRzLmdldChrZXkpOworICAgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwgJiYgIWRlZmF1bHRzLmNvbnRhaW5zS2V5KGtleSkpIHsKKyAgICAgICAgICAgICAgICB2YWx1ZSA9IHN1cGVyLmdldChrZXkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiB2YWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXF1aXJlZCB0byB3b3JrIHdpdGggUHJvcFV0aWwuIEFuIHVwZGF0ZWQgY29weSBvZiB0aGUga2V5IGlzIGZldGNoZWQKKyAgICAgKiBmcm9tIHRoZSBsb2cgbWFuYWdlciBpZiB0aGUga2V5IGRvZXNuJ3QgZXhpc3QgaW4gdGhpcyBwcm9wZXJ0aWVzLgorICAgICAqCisgICAgICogQHBhcmFtIGtleSBhbnkga2V5LgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIGZvciB0aGUga2V5IG9yIHRoZSBkZWZhdWx0IHZhbHVlIGZvciB0aGUga2V5LgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjQuNQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgT2JqZWN0IHB1dChmaW5hbCBPYmplY3Qga2V5LCBmaW5hbCBPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgaWYgKGtleSBpbnN0YW5jZW9mIFN0cmluZyAmJiB2YWx1ZSBpbnN0YW5jZW9mIFN0cmluZykgeworICAgICAgICAgICAgZmluYWwgT2JqZWN0IGRlZiA9IHByZVdyaXRlKGtleSk7CisgICAgICAgICAgICBmaW5hbCBPYmplY3QgbWFuID0gc3VwZXIucHV0KGtleSwgdmFsdWUpOworICAgICAgICAgICAgcmV0dXJuIG1hbiA9PSBudWxsID8gZGVmIDogbWFuOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnB1dChrZXksIHZhbHVlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENhbGxzIHRoZSBwdXQgbWV0aG9kIGRpcmVjdGx5LgorICAgICAqCisgICAgICogQHBhcmFtIGtleSBhbnkga2V5LgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIGZvciB0aGUga2V5IG9yIHRoZSBkZWZhdWx0IHZhbHVlIGZvciB0aGUga2V5LgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjQuNQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3Qgc2V0UHJvcGVydHkoU3RyaW5nIGtleSwgU3RyaW5nIHZhbHVlKSB7CisgICAgICAgIHJldHVybiB0aGlzLnB1dChrZXksIHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXF1aXJlZCB0byB3b3JrIHdpdGggUHJvcFV0aWwuIEFuIHVwZGF0ZWQgY29weSBvZiB0aGUga2V5IGlzIGZldGNoZWQKKyAgICAgKiBmcm9tIHRoZSBsb2cgbWFuYWdlciBwcmlvciB0byByZXR1cm5pbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0ga2V5IGFueSBrZXkuCisgICAgICogQHJldHVybiB0aGUgdmFsdWUgZm9yIHRoZSBrZXkgb3IgbnVsbC4KKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS40LjUKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGJvb2xlYW4gY29udGFpbnNLZXkoZmluYWwgT2JqZWN0IGtleSkgeworICAgICAgICBib29sZWFuIGZvdW5kID0ga2V5IGluc3RhbmNlb2YgU3RyaW5nCisgICAgICAgICAgICAgICAgJiYgZ2V0UHJvcGVydHkoKFN0cmluZykga2V5KSAhPSBudWxsOworICAgICAgICBpZiAoIWZvdW5kKSB7CisgICAgICAgICAgICBmb3VuZCA9IGRlZmF1bHRzLmNvbnRhaW5zS2V5KGtleSkgfHwgc3VwZXIuY29udGFpbnNLZXkoa2V5KTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZm91bmQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVxdWlyZWQgdG8gd29yayB3aXRoIFByb3BVdGlsLiBBbiB1cGRhdGVkIGNvcHkgb2YgdGhlIGtleSBpcyBmZXRjaGVkCisgICAgICogZnJvbSB0aGUgbG9nIG1hbmFnZXIgaWYgdGhlIGtleSBkb2Vzbid0IGV4aXN0IGluIHRoaXMgcHJvcGVydGllcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBrZXkgYW55IGtleS4KKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBmb3IgdGhlIGtleSBvciB0aGUgZGVmYXVsdCB2YWx1ZSBmb3IgdGhlIGtleS4KKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS40LjUKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIE9iamVjdCByZW1vdmUoZmluYWwgT2JqZWN0IGtleSkgeworICAgICAgICBmaW5hbCBPYmplY3QgZGVmID0gcHJlV3JpdGUoa2V5KTsKKyAgICAgICAgZmluYWwgT2JqZWN0IG1hbiA9IHN1cGVyLnJlbW92ZShrZXkpOworICAgICAgICByZXR1cm4gbWFuID09IG51bGwgPyBkZWYgOiBtYW47CisgICAgfQorCisgICAgLyoqCisgICAgICogSXQgaXMgYXNzdW1lZCB0aGF0IHRoaXMgbWV0aG9kIHdpbGwgbmV2ZXIgYmUgY2FsbGVkLiBObyB3YXkgdG8gZ2V0IHRoZQorICAgICAqIHByb3BlcnR5IG5hbWVzIGZyb20gTG9nTWFuYWdlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHByb3BlcnR5IG5hbWVzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEVudW1lcmF0aW9uPD8+IHByb3BlcnR5TmFtZXMoKSB7CisgICAgICAgIGFzc2VydCBmYWxzZTsKKyAgICAgICAgcmV0dXJuIHN1cGVyLnByb3BlcnR5TmFtZXMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJdCBpcyBhc3N1bWVkIHRoYXQgdGhpcyBtZXRob2Qgd2lsbCBuZXZlciBiZSBjYWxsZWQuIFRoZSBwcmVmaXggdmFsdWUgaXMKKyAgICAgKiBub3QgdXNlZCBmb3IgdGhlIGVxdWFscyBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbyBhbnkgb2JqZWN0IG9yIG51bGwuCisgICAgICogQHJldHVybiB0cnVlIGlmIGVxdWFsLCBvdGhlcndpc2UgZmFsc2UuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIE9iamVjdCBvKSB7CisgICAgICAgIGlmIChvID09IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBpZiAobyA9PSB0aGlzKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAobyBpbnN0YW5jZW9mIFByb3BlcnRpZXMgPT0gZmFsc2UpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnQgZmFsc2UgOiBwcmVmaXg7CisgICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMobyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSXQgaXMgYXNzdW1lZCB0aGF0IHRoaXMgbWV0aG9kIHdpbGwgbmV2ZXIgYmUgY2FsbGVkLiBTZWUgZXF1YWxzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgaGFzaCBjb2RlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIGFzc2VydCBmYWxzZSA6IHByZWZpeC5oYXNoQ29kZSgpOworICAgICAgICByZXR1cm4gc3VwZXIuaGFzaENvZGUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDYWxsZWQgYmVmb3JlIGEgd3JpdGUgb3BlcmF0aW9uIG9mIGEga2V5LiBDYWNoZXMgYSBrZXkgcmVhZCBmcm9tIHRoZSBsb2cKKyAgICAgKiBtYW5hZ2VyIGluIHRoaXMgcHJvcGVydGllcyBvYmplY3QuIFRoZSBrZXkgaXMgb25seSBjYWNoZWQgaWYgaXQgaXMgYW4KKyAgICAgKiBpbnN0YW5jZSBvZiBhIFN0cmluZyBhbmQgdGhpcyBwcm9wZXJ0aWVzIGRvZXNuJ3QgY29udGFpbiBhIGNvcHkgb2YgdGhlCisgICAgICoga2V5LgorICAgICAqCisgICAgICogQHBhcmFtIGtleSB0aGUga2V5IHRvIHNlYXJjaC4KKyAgICAgKiBAcmV0dXJuIHRoZSBkZWZhdWx0IHZhbHVlIGZvciB0aGUga2V5LgorICAgICAqLworICAgIHByaXZhdGUgT2JqZWN0IHByZVdyaXRlKGZpbmFsIE9iamVjdCBrZXkpIHsKKyAgICAgICAgYXNzZXJ0IFRocmVhZC5ob2xkc0xvY2sodGhpcyk7CisgICAgICAgIHJldHVybiBnZXQoa2V5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgcHVibGljIHNuYXBzaG90IG9mIHRoaXMgcHJvcGVydGllcyBvYmplY3QgdXNpbmcgdGhlIGdpdmVuCisgICAgICogcGFyZW50IHByb3BlcnRpZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcGFyZW50IHRoZSBkZWZhdWx0cyB0byB1c2Ugd2l0aCB0aGUgc25hcHNob3QuCisgICAgICogQHJldHVybiB0aGUgc2FmZSBzbmFwc2hvdC4KKyAgICAgKi8KKyAgICBwcml2YXRlIFByb3BlcnRpZXMgZXhwb3J0Q29weShmaW5hbCBQcm9wZXJ0aWVzIHBhcmVudCkgeworICAgICAgICBUaHJlYWQuaG9sZHNMb2NrKHRoaXMpOworICAgICAgICBmaW5hbCBQcm9wZXJ0aWVzIGNoaWxkID0gbmV3IFByb3BlcnRpZXMocGFyZW50KTsKKyAgICAgICAgY2hpbGQucHV0QWxsKHRoaXMpOworICAgICAgICByZXR1cm4gY2hpbGQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogSXQgaXMgYXNzdW1lZCB0aGF0IHRoaXMgbWV0aG9kIHdpbGwgbmV2ZXIgYmUgY2FsbGVkLiBXZSByZXR1cm4gYSBzYWZlCisgICAgICogY29weSBmb3IgZXhwb3J0IHRvIGF2b2lkIGxvY2tpbmcgdGhpcyBwcm9wZXJ0aWVzIG9iamVjdCBvciB0aGUgZGVmYXVsdHMKKyAgICAgKiBkdXJpbmcgd3JpdGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBwYXJlbnQgcHJvcGVydGllcy4KKyAgICAgKiBAdGhyb3dzIE9iamVjdFN0cmVhbUV4Y2VwdGlvbiBpZiB0aGVyZSBpcyBhIHByb2JsZW0uCisgICAgICovCisgICAgcHJpdmF0ZSBzeW5jaHJvbml6ZWQgT2JqZWN0IHdyaXRlUmVwbGFjZSgpIHRocm93cyBPYmplY3RTdHJlYW1FeGNlcHRpb24geworICAgICAgICBhc3NlcnQgZmFsc2U7CisgICAgICAgIHJldHVybiBleHBvcnRDb3B5KChQcm9wZXJ0aWVzKSBkZWZhdWx0cy5jbG9uZSgpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvbG9nZ2luZy9NYWlsSGFuZGxlci5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL2xvZ2dpbmcvTWFpbEhhbmRsZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44OTFlOTIxCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL2xvZ2dpbmcvTWFpbEhhbmRsZXIuamF2YQpAQCAtMCwwICsxLDQzOTYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDksIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqIENvcHlyaWdodCAoYykgMjAwOSwgMjAxOCBKYXNvbiBNZWhyZW5zLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nOworCitpbXBvcnQgc3RhdGljIGNvbS5zdW4ubWFpbC51dGlsLmxvZ2dpbmcuTG9nTWFuYWdlclByb3BlcnRpZXMuZnJvbUxvZ01hbmFnZXI7CitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lkludm9jYXRpb25UYXJnZXRFeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuSW5ldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuVVJMQ29ubmVjdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5Vbmtub3duSG9zdEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXQ7CitpbXBvcnQgamF2YS5zZWN1cml0eS5BY2Nlc3NDb250cm9sbGVyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmlsZWdlZEFjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBqYXZhLnV0aWwubG9nZ2luZy4qOworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkZvcm1hdHRlcjsKK2ltcG9ydCBqYXZheC5hY3RpdmF0aW9uLio7CitpbXBvcnQgamF2YXgubWFpbC4qOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuKjsKK2ltcG9ydCBqYXZheC5tYWlsLnV0aWwuQnl0ZUFycmF5RGF0YVNvdXJjZTsKKworLyoqCisgKiA8dHQ+SGFuZGxlcjwvdHQ+IHRoYXQgZm9ybWF0cyBsb2cgcmVjb3JkcyBhcyBhbiBlbWFpbCBtZXNzYWdlLgorICoKKyAqIDxwPgorICogVGhpcyA8dHQ+SGFuZGxlcjwvdHQ+IHdpbGwgc3RvcmUgYSBmaXhlZCBudW1iZXIgb2YgbG9nIHJlY29yZHMgdXNlZCB0bworICogZ2VuZXJhdGUgYSBzaW5nbGUgZW1haWwgbWVzc2FnZS4gIFdoZW4gdGhlIGludGVybmFsIGJ1ZmZlciByZWFjaGVzIGNhcGFjaXR5LAorICogYWxsIGxvZyByZWNvcmRzIGFyZSBmb3JtYXR0ZWQgYW5kIHBsYWNlZCBpbiBhbiBlbWFpbCB3aGljaCBpcyBzZW50IHRvIGFuCisgKiBlbWFpbCBzZXJ2ZXIuICBUaGUgY29kZSB0byBtYW51YWxseSBzZXR1cCB0aGlzIGhhbmRsZXIgY2FuIGJlIGFzIHNpbXBsZSBhcworICogdGhlIGZvbGxvd2luZzoKKyAqCisgKiA8cHJlPgorICogICAgICBQcm9wZXJ0aWVzIHByb3BzID0gbmV3IFByb3BlcnRpZXMoKTsKKyAqICAgICAgcHJvcHMucHV0KCJtYWlsLnNtdHAuaG9zdCIsICJteS1tYWlsLXNlcnZlciIpOworICogICAgICBwcm9wcy5wdXQoIm1haWwudG8iLCAibWVAZXhhbXBsZS5jb20iKTsKKyAqICAgICAgcHJvcHMucHV0KCJ2ZXJpZnkiLCAibG9jYWwiKTsKKyAqICAgICAgTWFpbEhhbmRsZXIgaCA9IG5ldyBNYWlsSGFuZGxlcihwcm9wcyk7CisgKiAgICAgIGguc2V0TGV2ZWwoTGV2ZWwuV0FSTklORyk7CisgKiA8L3ByZT4KKyAqCisgKiA8cD4KKyAqIDxiPkNvbmZpZ3VyYXRpb246PC9iPgorICogVGhlIExvZ01hbmFnZXIgc2hvdWxkIGRlZmluZSBhdCBsZWFzdCBvbmUgb3IgbW9yZSByZWNpcGllbnQgYWRkcmVzc2VzIGFuZCBhCisgKiBtYWlsIGhvc3QgZm9yIG91dGdvaW5nIGVtYWlsLiAgVGhlIGNvZGUgdG8gc2V0dXAgdGhpcyBoYW5kbGVyIHZpYSB0aGUKKyAqIGxvZ2dpbmcgcHJvcGVydGllcyBjYW4gYmUgYXMgc2ltcGxlIGFzIHRoZSBmb2xsb3dpbmc6CisgKgorICogPHByZT4KKyAqICAgICAgI0RlZmF1bHQgTWFpbEhhbmRsZXIgc2V0dGluZ3MuCisgKiAgICAgIGNvbS5zdW4ubWFpbC51dGlsLmxvZ2dpbmcuTWFpbEhhbmRsZXIubWFpbC5zbXRwLmhvc3QgPSBteS1tYWlsLXNlcnZlcgorICogICAgICBjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nLk1haWxIYW5kbGVyLm1haWwudG8gPSBtZUBleGFtcGxlLmNvbQorICogICAgICBjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nLk1haWxIYW5kbGVyLmxldmVsID0gV0FSTklORworICogICAgICBjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nLk1haWxIYW5kbGVyLnZlcmlmeSA9IGxvY2FsCisgKiA8L3ByZT4KKyAqCisgKiBGb3IgYSBjdXN0b20gaGFuZGxlciwgZS5nLiA8dHQ+Y29tLmZvby5NeUhhbmRsZXI8L3R0PiwgdGhlIHByb3BlcnRpZXMgd291bGQKKyAqIGJlOgorICoKKyAqIDxwcmU+CisgKiAgICAgICNTdWJjbGFzcyBjb20uZm9vLk15SGFuZGxlciBzZXR0aW5ncy4KKyAqICAgICAgY29tLmZvby5NeUhhbmRsZXIubWFpbC5zbXRwLmhvc3QgPSBteS1tYWlsLXNlcnZlcgorICogICAgICBjb20uZm9vLk15SGFuZGxlci5tYWlsLnRvID0gbWVAZXhhbXBsZS5jb20KKyAqICAgICAgY29tLmZvby5NeUhhbmRsZXIubGV2ZWwgPSBXQVJOSU5HCisgKiAgICAgIGNvbS5mb28uTXlIYW5kbGVyLnZlcmlmeSA9IGxvY2FsCisgKiA8L3ByZT4KKyAqCisgKiBBbGwgbWFpbCBwcm9wZXJ0aWVzIGRvY3VtZW50ZWQgaW4gdGhlIDx0dD5KYXZhIE1haWwgQVBJPC90dD4gY2FzY2FkZSB0byB0aGUKKyAqIExvZ01hbmFnZXIgYnkgcHJlZml4aW5nIGEga2V5IHVzaW5nIHRoZSBmdWxseSBxdWFsaWZpZWQgY2xhc3MgbmFtZSBvZiB0aGlzCisgKiA8dHQ+TWFpbEhhbmRsZXI8L3R0PiBvciB0aGUgZnVsbHkgcXVhbGlmaWVkIGRlcml2ZWQgY2xhc3MgbmFtZSBkb3QgbWFpbAorICogcHJvcGVydHkuICBJZiB0aGUgcHJlZml4ZWQgcHJvcGVydHkgaXMgbm90IGZvdW5kLCB0aGVuIHRoZSBtYWlsIHByb3BlcnR5CisgKiBpdHNlbGYgaXMgc2VhcmNoZWQgaW4gdGhlIExvZ01hbmFnZXIuIEJ5IGRlZmF1bHQgZWFjaCA8dHQ+TWFpbEhhbmRsZXI8L3R0PiBpcworICogaW5pdGlhbGl6ZWQgdXNpbmcgdGhlIGZvbGxvd2luZyBMb2dNYW5hZ2VyIGNvbmZpZ3VyYXRpb24gcHJvcGVydGllcyB3aGVyZQorICogPHR0PiZsdDtoYW5kbGVyLW5hbWUmZ3Q7PC90dD4gcmVmZXJzIHRvIHRoZSBmdWxseSBxdWFsaWZpZWQgY2xhc3MgbmFtZSBvZiB0aGUKKyAqIGhhbmRsZXIuICBJZiBwcm9wZXJ0aWVzIGFyZSBub3QgZGVmaW5lZCwgb3IgY29udGFpbiBpbnZhbGlkIHZhbHVlcywgdGhlbiB0aGUKKyAqIHNwZWNpZmllZCBkZWZhdWx0IHZhbHVlcyBhcmUgdXNlZC4KKyAqCisgKiA8dWw+CisgKiA8bGk+Jmx0O2hhbmRsZXItbmFtZSZndDsuYXR0YWNobWVudC5maWx0ZXJzIGEgY29tbWEKKyAqIHNlcGFyYXRlZCBsaXN0IG9mIDx0dD5GaWx0ZXI8L3R0PiBjbGFzcyBuYW1lcyB1c2VkIHRvIGNyZWF0ZSBlYWNoIGF0dGFjaG1lbnQuCisgKiBUaGUgbGl0ZXJhbCA8dHQ+bnVsbDwvdHQ+IGlzIHJlc2VydmVkIGZvciBhdHRhY2htZW50cyB0aGF0IGRvIG5vdCByZXF1aXJlCisgKiBmaWx0ZXJpbmcuIChkZWZhdWx0cyB0byB0aGUKKyAqIHtAbGlua3BsYWluIGphdmEudXRpbC5sb2dnaW5nLkhhbmRsZXIjZ2V0RmlsdGVyKCkgYm9keX0gZmlsdGVyKQorICoKKyAqIDxsaT4mbHQ7aGFuZGxlci1uYW1lJmd0Oy5hdHRhY2htZW50LmZvcm1hdHRlcnMgYSBjb21tYQorICogc2VwYXJhdGVkIGxpc3Qgb2YgPHR0PkZvcm1hdHRlcjwvdHQ+IGNsYXNzIG5hbWVzIHVzZWQgdG8gY3JlYXRlIGVhY2gKKyAqIGF0dGFjaG1lbnQuIChkZWZhdWx0IGlzIG5vIGF0dGFjaG1lbnRzKQorICoKKyAqIDxsaT4mbHQ7aGFuZGxlci1uYW1lJmd0Oy5hdHRhY2htZW50Lm5hbWVzIGEgY29tbWEgc2VwYXJhdGVkCisgKiBsaXN0IG9mIG5hbWVzIG9yIDx0dD5Gb3JtYXR0ZXI8L3R0PiBjbGFzcyBuYW1lcyBvZiBlYWNoIGF0dGFjaG1lbnQuICBBbGwKKyAqIGNvbnRyb2wgY2hhcmFjdGVycyBhcmUgcmVtb3ZlZCBmcm9tIHRoZSBhdHRhY2htZW50IG5hbWVzLgorICogKGRlZmF1bHQgaXMge0BsaW5rcGxhaW4gamF2YS51dGlsLmxvZ2dpbmcuRm9ybWF0dGVyI3RvU3RyaW5nKCkgdG9TdHJpbmd9CisgKiBvZiB0aGUgYXR0YWNobWVudCBmb3JtYXR0ZXIpCisgKgorICogPGxpPiZsdDtoYW5kbGVyLW5hbWUmZ3Q7LmF1dGhlbnRpY2F0b3IgbmFtZSBvZiBhbgorICoge0BsaW5rcGxhaW4gamF2YXgubWFpbC5BdXRoZW50aWNhdG9yfSBjbGFzcyB1c2VkIHRvIHByb3ZpZGUgbG9naW4gY3JlZGVudGlhbHMKKyAqIHRvIHRoZSBlbWFpbCBzZXJ2ZXIgb3Igc3RyaW5nIGxpdGVyYWwgdGhhdCBpcyB0aGUgcGFzc3dvcmQgdXNlZCB3aXRoIHRoZQorICoge0BsaW5rcGxhaW4gQXV0aGVudGljYXRvciNnZXREZWZhdWx0VXNlck5hbWUoKSBkZWZhdWx0fSB1c2VyIG5hbWUuCisgKiAoZGVmYXVsdCBpcyA8dHQ+bnVsbDwvdHQ+KQorICoKKyAqIDxsaT4mbHQ7aGFuZGxlci1uYW1lJmd0Oy5jYXBhY2l0eSB0aGUgbWF4IG51bWJlciBvZgorICogPHR0PkxvZ1JlY29yZDwvdHQ+IG9iamVjdHMgaW5jbHVkZSBpbiBlYWNoIGVtYWlsIG1lc3NhZ2UuCisgKiAoZGVmYXVsdHMgdG8gPHR0PjEwMDA8L3R0PikKKyAqCisgKiA8bGk+Jmx0O2hhbmRsZXItbmFtZSZndDsuY29tcGFyYXRvciBuYW1lIG9mIGEKKyAqIHtAbGlua3BsYWluIGphdmEudXRpbC5Db21wYXJhdG9yfSBjbGFzcyB1c2VkIHRvIHNvcnQgdGhlIHB1Ymxpc2hlZAorICogPHR0PkxvZ1JlY29yZDwvdHQ+IG9iamVjdHMgcHJpb3IgdG8gYWxsIGZvcm1hdHRpbmcuCisgKiAoZGVmYXVsdHMgdG8gPHR0Pm51bGw8L3R0PiBtZWFuaW5nIHJlY29yZHMgYXJlIHVuc29ydGVkKS4KKyAqCisgKiA8bGk+Jmx0O2hhbmRsZXItbmFtZSZndDsuY29tcGFyYXRvci5yZXZlcnNlIGEgYm9vbGVhbgorICogPHR0PnRydWU8L3R0PiB0byByZXZlcnNlIHRoZSBvcmRlciBvZiB0aGUgc3BlY2lmaWVkIGNvbXBhcmF0b3Igb3IKKyAqIDx0dD5mYWxzZTwvdHQ+IHRvIHJldGFpbiB0aGUgb3JpZ2luYWwgb3JkZXIuIChkZWZhdWx0cyB0byA8dHQ+ZmFsc2U8L3R0PikKKyAqCisgKiA8bGk+Jmx0O2hhbmRsZXItbmFtZSZndDsuZW5jb2RpbmcgdGhlIG5hbWUgb2YgdGhlIEphdmEKKyAqIHtAbGlua3BsYWluIGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldCNuYW1lKCkgY2hhcmFjdGVyIHNldH0gdG8gdXNlIGZvciB0aGUKKyAqIGVtYWlsIG1lc3NhZ2UuIChkZWZhdWx0cyB0byA8dHQ+bnVsbDwvdHQ+LCB0aGUKKyAqIHtAbGlua3BsYWluIGphdmF4Lm1haWwuaW50ZXJuZXQuTWltZVV0aWxpdHkjZ2V0RGVmYXVsdEphdmFDaGFyc2V0KCkgZGVmYXVsdH0KKyAqIHBsYXRmb3JtIGVuY29kaW5nKS4KKyAqCisgKiA8bGk+Jmx0O2hhbmRsZXItbmFtZSZndDsuZXJyb3JNYW5hZ2VyIG5hbWUgb2YgYW4KKyAqIDx0dD5FcnJvck1hbmFnZXI8L3R0PiBjbGFzcyB1c2VkIHRvIGhhbmRsZSBhbnkgY29uZmlndXJhdGlvbiBvciBtYWlsCisgKiB0cmFuc3BvcnQgcHJvYmxlbXMuIChkZWZhdWx0cyB0byA8dHQ+amF2YS51dGlsLmxvZ2dpbmcuRXJyb3JNYW5hZ2VyPC90dD4pCisgKgorICogPGxpPiZsdDtoYW5kbGVyLW5hbWUmZ3Q7LmZpbHRlciBuYW1lIG9mIGEgPHR0PkZpbHRlcjwvdHQ+CisgKiBjbGFzcyB1c2VkIGZvciB0aGUgYm9keSBvZiB0aGUgbWVzc2FnZS4gKGRlZmF1bHRzIHRvIDx0dD5udWxsPC90dD4sCisgKiBhbGxvdyBhbGwgcmVjb3JkcykKKyAqCisgKiA8bGk+Jmx0O2hhbmRsZXItbmFtZSZndDsuZm9ybWF0dGVyIG5hbWUgb2YgYQorICogPHR0PkZvcm1hdHRlcjwvdHQ+IGNsYXNzIHVzZWQgdG8gZm9ybWF0IHRoZSBib2R5IG9mIHRoaXMgbWVzc2FnZS4KKyAqIChkZWZhdWx0cyB0byA8dHQ+amF2YS51dGlsLmxvZ2dpbmcuU2ltcGxlRm9ybWF0dGVyPC90dD4pCisgKgorICogPGxpPiZsdDtoYW5kbGVyLW5hbWUmZ3Q7LmxldmVsIHNwZWNpZmllcyB0aGUgZGVmYXVsdCBsZXZlbAorICogZm9yIHRoaXMgPHR0PkhhbmRsZXI8L3R0PiAoZGVmYXVsdHMgdG8gPHR0PkxldmVsLldBUk5JTkc8L3R0PikuCisgKgorICogPGxpPiZsdDtoYW5kbGVyLW5hbWUmZ3Q7Lm1haWwuYmNjIGEgY29tbWEgc2VwYXJhdGVkIGxpc3Qgb2YKKyAqIGFkZHJlc3NlcyB3aGljaCB3aWxsIGJlIGJsaW5kIGNhcmJvbiBjb3BpZWQuICBUeXBpY2FsbHksIHRoaXMgaXMgc2V0IHRvIHRoZQorICogcmVjaXBpZW50cyB0aGF0IG1heSBuZWVkIHRvIGJlIHByaXZhdGVseSBub3RpZmllZCBvZiBhIGxvZyBtZXNzYWdlIG9yCisgKiBub3RpZmllZCB0aGF0IGEgbG9nIG1lc3NhZ2Ugd2FzIHNlbnQgdG8gYSB0aGlyZCBwYXJ0eSBzdWNoIGFzIGEgc3VwcG9ydCB0ZWFtLgorICogVGhlIGVtcHR5IHN0cmluZyBjYW4gYmUgdXNlZCB0byBzcGVjaWZ5IG5vIGJsaW5kIGNhcmJvbiBjb3BpZWQgYWRkcmVzcy4KKyAqIChkZWZhdWx0cyB0byA8dHQ+bnVsbDwvdHQ+LCBub25lKQorICoKKyAqIDxsaT4mbHQ7aGFuZGxlci1uYW1lJmd0Oy5tYWlsLmNjIGEgY29tbWEgc2VwYXJhdGVkIGxpc3Qgb2YKKyAqIGFkZHJlc3NlcyB3aGljaCB3aWxsIGJlIGNhcmJvbiBjb3BpZWQuICBUeXBpY2FsbHksIHRoaXMgaXMgc2V0IHRvIHRoZQorICogcmVjaXBpZW50cyB0aGF0IG1heSBuZWVkIHRvIGJlIG5vdGlmaWVkIG9mIGEgbG9nIG1lc3NhZ2UgYnV0LCBhcmUgbm90CisgKiByZXF1aXJlZCB0byBwcm92aWRlIGRpcmVjdCBzdXBwb3J0LiAgVGhlIGVtcHR5IHN0cmluZyBjYW4gYmUgdXNlZCB0byBzcGVjaWZ5CisgKiBubyBjYXJib24gY29waWVkIGFkZHJlc3MuICAoZGVmYXVsdHMgdG8gPHR0Pm51bGw8L3R0Piwgbm9uZSkKKyAqCisgKiA8bGk+Jmx0O2hhbmRsZXItbmFtZSZndDsubWFpbC5mcm9tIGEgY29tbWEgc2VwYXJhdGVkIGxpc3Qgb2YKKyAqIGFkZHJlc3NlcyB3aGljaCB3aWxsIGJlIGZyb20gYWRkcmVzc2VzLiBUeXBpY2FsbHksIHRoaXMgaXMgc2V0IHRvIHRoZSBlbWFpbAorICogYWRkcmVzcyBpZGVudGlmeWluZyB0aGUgdXNlciBydW5uaW5nIHRoZSBhcHBsaWNhdGlvbi4gIFRoZSBlbXB0eSBzdHJpbmcgY2FuCisgKiBiZSB1c2VkIHRvIG92ZXJyaWRlIHRoZSBkZWZhdWx0IGJlaGF2aW9yIGFuZCBzcGVjaWZ5IG5vIGZyb20gYWRkcmVzcy4KKyAqIChkZWZhdWx0cyB0byB0aGUge0BsaW5rcGxhaW4gamF2YXgubWFpbC5NZXNzYWdlI3NldEZyb20oKSBsb2NhbCBhZGRyZXNzfSkKKyAqCisgKiA8bGk+Jmx0O2hhbmRsZXItbmFtZSZndDsubWFpbC5ob3N0IHRoZSBob3N0IG5hbWUgb3IgSVAKKyAqIGFkZHJlc3Mgb2YgdGhlIGVtYWlsIHNlcnZlci4gKGRlZmF1bHRzIHRvIDx0dD5udWxsPC90dD4sIHVzZQorICoge0BsaW5rcGxhaW4gVHJhbnNwb3J0I3Byb3RvY29sQ29ubmVjdCBkZWZhdWx0fQorICogPHR0PkphdmEgTWFpbDwvdHQ+IGJlaGF2aW9yKQorICoKKyAqIDxsaT4mbHQ7aGFuZGxlci1uYW1lJmd0Oy5tYWlsLnJlcGx5LnRvIGEgY29tbWEgc2VwYXJhdGVkCisgKiBsaXN0IG9mIGFkZHJlc3NlcyB3aGljaCB3aWxsIGJlIHJlcGx5LXRvIGFkZHJlc3Nlcy4gIFR5cGljYWxseSwgdGhpcyBpcyBzZXQKKyAqIHRvIHRoZSByZWNpcGllbnRzIHRoYXQgcHJvdmlkZSBzdXBwb3J0IGZvciB0aGUgYXBwbGljYXRpb24gaXRzZWxmLiAgVGhlIGVtcHR5CisgKiBzdHJpbmcgY2FuIGJlIHVzZWQgdG8gc3BlY2lmeSBubyByZXBseS10byBhZGRyZXNzLgorICogKGRlZmF1bHRzIHRvIDx0dD5udWxsPC90dD4sIG5vbmUpCisgKgorICogPGxpPiZsdDtoYW5kbGVyLW5hbWUmZ3Q7Lm1haWwudG8gYSBjb21tYSBzZXBhcmF0ZWQgbGlzdCBvZgorICogYWRkcmVzc2VzIHdoaWNoIHdpbGwgYmUgc2VuZC10byBhZGRyZXNzZXMuIFR5cGljYWxseSwgdGhpcyBpcyBzZXQgdG8gdGhlCisgKiByZWNpcGllbnRzIHRoYXQgcHJvdmlkZSBzdXBwb3J0IGZvciB0aGUgYXBwbGljYXRpb24sIHN5c3RlbSwgYW5kL29yCisgKiBzdXBwb3J0aW5nIGluZnJhc3RydWN0dXJlLiAgVGhlIGVtcHR5IHN0cmluZyBjYW4gYmUgdXNlZCB0byBzcGVjaWZ5IG5vCisgKiBzZW5kLXRvIGFkZHJlc3Mgd2hpY2ggb3ZlcnJpZGVzIHRoZSBkZWZhdWx0IGJlaGF2aW9yLiAgKGRlZmF1bHRzIHRvCisgKiB7QGxpbmtwbGFpbiBqYXZheC5tYWlsLmludGVybmV0LkludGVybmV0QWRkcmVzcyNnZXRMb2NhbEFkZHJlc3MKKyAqIGxvY2FsIGFkZHJlc3N9LikKKyAqCisgKiA8bGk+Jmx0O2hhbmRsZXItbmFtZSZndDsubWFpbC5zZW5kZXIgYSBzaW5nbGUgYWRkcmVzcworICogaWRlbnRpZnlpbmcgc2VuZGVyIG9mIHRoZSBlbWFpbDsgbmV2ZXIgZXF1YWwgdG8gdGhlIGZyb20gYWRkcmVzcy4gIFR5cGljYWxseSwKKyAqIHRoaXMgaXMgc2V0IHRvIHRoZSBlbWFpbCBhZGRyZXNzIGlkZW50aWZ5aW5nIHRoZSBhcHBsaWNhdGlvbiBpdHNlbGYuICBUaGUKKyAqIGVtcHR5IHN0cmluZyBjYW4gYmUgdXNlZCB0byBzcGVjaWZ5IG5vIHNlbmRlciBhZGRyZXNzLgorICogKGRlZmF1bHRzIHRvIDx0dD5udWxsPC90dD4sIG5vbmUpCisgKgorICogPGxpPiZsdDtoYW5kbGVyLW5hbWUmZ3Q7LnN1YmplY3QgdGhlIG5hbWUgb2YgYQorICogPHR0PkZvcm1hdHRlcjwvdHQ+IGNsYXNzIG9yIHN0cmluZyBsaXRlcmFsIHVzZWQgdG8gY3JlYXRlIHRoZSBzdWJqZWN0IGxpbmUuCisgKiBUaGUgZW1wdHkgc3RyaW5nIGNhbiBiZSB1c2VkIHRvIHNwZWNpZnkgbm8gc3ViamVjdC4gIEFsbCBjb250cm9sIGNoYXJhY3RlcnMKKyAqIGFyZSByZW1vdmVkIGZyb20gdGhlIHN1YmplY3QgbGluZS4gKGRlZmF1bHRzIHRvIHtAbGlua3BsYWluCisgKiBjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nLkNvbGxlY3RvckZvcm1hdHRlciBDb2xsZWN0b3JGb3JtYXR0ZXJ9LikKKyAqCisgKiA8bGk+Jmx0O2hhbmRsZXItbmFtZSZndDsucHVzaEZpbHRlciB0aGUgbmFtZSBvZiBhCisgKiA8dHQ+RmlsdGVyPC90dD4gY2xhc3MgdXNlZCB0byB0cmlnZ2VyIGFuIGVhcmx5IHB1c2guCisgKiAoZGVmYXVsdHMgdG8gPHR0Pm51bGw8L3R0Piwgbm8gZWFybHkgcHVzaCkKKyAqCisgKiA8bGk+Jmx0O2hhbmRsZXItbmFtZSZndDsucHVzaExldmVsIHRoZSBsZXZlbCB3aGljaCB3aWxsCisgKiB0cmlnZ2VyIGFuIGVhcmx5IHB1c2guIChkZWZhdWx0cyB0byA8dHQ+TGV2ZWwuT0ZGPC90dD4sIG9ubHkgcHVzaCB3aGVuIGZ1bGwpCisgKgorICogPGxpPiZsdDtoYW5kbGVyLW5hbWUmZ3Q7LnZlcmlmeSA8YSBuYW1lPSJ2ZXJpZnkiPnVzZWQ8L2E+IHRvCisgKiB2ZXJpZnkgdGhlIDx0dD5IYW5kbGVyPC90dD4gY29uZmlndXJhdGlvbiBwcmlvciB0byBhIHB1c2guCisgKiA8dWw+CisgKiAgICAgIDxsaT5JZiB0aGUgdmFsdWUgaXMgbm90IHNldCwgZXF1YWwgdG8gYW4gZW1wdHkgc3RyaW5nLCBvciBlcXVhbCB0byB0aGUKKyAqICAgICAgbGl0ZXJhbCA8dHQ+bnVsbDwvdHQ+IHRoZW4gbm8gc2V0dGluZ3MgYXJlIHZlcmlmaWVkIHByaW9yIHRvIGEgcHVzaC4KKyAqICAgICAgPGxpPklmIHNldCB0byBhIHZhbHVlIG9mIDx0dD5saW1pdGVkPC90dD4gdGhlbiB0aGUgPHR0PkhhbmRsZXI8L3R0PiB3aWxsCisgKiAgICAgIHZlcmlmeSBtaW5pbWFsIGxvY2FsIG1hY2hpbmUgc2V0dGluZ3MuCisgKiAgICAgIDxsaT5JZiBzZXQgdG8gYSB2YWx1ZSBvZiA8dHQ+bG9jYWw8L3R0PiB0aGUgPHR0PkhhbmRsZXI8L3R0PiB3aWxsIHZlcmlmeQorICogICAgICBhbGwgb2Ygc2V0dGluZ3Mgb2YgdGhlIGxvY2FsIG1hY2hpbmUuCisgKiAgICAgIDxsaT5JZiBzZXQgdG8gYSB2YWx1ZSBvZiA8dHQ+cmVzb2x2ZTwvdHQ+LCB0aGUgPHR0PkhhbmRsZXI8L3R0PiB3aWxsCisgKiAgICAgIHZlcmlmeSBhbGwgbG9jYWwgc2V0dGluZ3MgYW5kIHRyeSB0byByZXNvbHZlIHRoZSByZW1vdGUgaG9zdCBuYW1lIHdpdGgKKyAqICAgICAgdGhlIGRvbWFpbiBuYW1lIHNlcnZlci4KKyAqICAgICAgPGxpPklmIHNldCB0byBhIHZhbHVlIG9mIDx0dD5sb2dpbjwvdHQ+LCB0aGUgPHR0PkhhbmRsZXI8L3R0PiB3aWxsCisgKiAgICAgIHZlcmlmeSBhbGwgbG9jYWwgc2V0dGluZ3MgYW5kIHRyeSB0byBlc3RhYmxpc2ggYSBjb25uZWN0aW9uIHdpdGgKKyAqICAgICAgdGhlIGVtYWlsIHNlcnZlci4KKyAqICAgICAgPGxpPklmIHNldCB0byBhIHZhbHVlIG9mIDx0dD5yZW1vdGU8L3R0PiwgdGhlIDx0dD5IYW5kbGVyPC90dD4gd2lsbAorICogICAgICB2ZXJpZnkgYWxsIGxvY2FsIHNldHRpbmdzLCB0cnkgdG8gZXN0YWJsaXNoIGEgY29ubmVjdGlvbiB3aXRoIHRoZQorICogICAgICBlbWFpbCBzZXJ2ZXIsIGFuZCB0cnkgdG8gdmVyaWZ5IHRoZSBlbnZlbG9wZSBvZiB0aGUgZW1haWwgbWVzc2FnZS4KKyAqIDwvdWw+CisgKiBJZiB0aGlzIDx0dD5IYW5kbGVyPC90dD4gaXMgb25seSBpbXBsaWNpdGx5IGNsb3NlZCBieSB0aGUKKyAqIDx0dD5Mb2dNYW5hZ2VyPC90dD4sIHRoZW4gdmVyaWZpY2F0aW9uIHNob3VsZCBiZSB0dXJuZWQgb24uCisgKiAoZGVmYXVsdHMgdG8gPHR0Pm51bGw8L3R0Piwgbm8gdmVyaWZ5KS4KKyAqIDwvdWw+CisgKgorICogPHA+CisgKiA8Yj5Ob3JtYWxpemF0aW9uOjwvYj4KKyAqIFRoZSBlcnJvciBtYW5hZ2VyLCBmaWx0ZXJzLCBhbmQgZm9ybWF0dGVycyB3aGVuIGxvYWRlZCBmcm9tIHRoZSBMb2dNYW5hZ2VyCisgKiBhcmUgY29udmVydGVkIGludG8gY2Fub25pY2FsIGZvcm0gaW5zaWRlIHRoZSBNYWlsSGFuZGxlci4gIFRoZSBwb29sIG9mCisgKiBpbnRlcm5lZCB2YWx1ZXMgaXMgbGltaXRlZCB0byBlYWNoIE1haWxIYW5kbGVyIG9iamVjdCBzdWNoIHRoYXQgbm8gdHdvCisgKiBNYWlsSGFuZGxlciBvYmplY3RzIGNyZWF0ZWQgYnkgdGhlIExvZ01hbmFnZXIgd2lsbCBiZSBjcmVhdGVkIHNoYXJpbmcKKyAqIGlkZW50aWNhbCBlcnJvciBtYW5hZ2VycywgZmlsdGVycywgb3IgZm9ybWF0dGVycy4gIElmIGEgZmlsdGVyIG9yIGZvcm1hdHRlcgorICogc2hvdWxkIDxiPm5vdDwvYj4gYmUgaW50ZXJuZWQgdGhlbiBpdCBpcyByZWNvbW1lbmRlZCB0byByZXRhaW4gdGhlIGlkZW50aXR5CisgKiBlcXVhbHMgYW5kIGlkZW50aXR5IGhhc2hDb2RlIG1ldGhvZHMgYXMgdGhlIGltcGxlbWVudGF0aW9uLiAgRm9yIGEgZmlsdGVyIG9yCisgKiBmb3JtYXR0ZXIgdG8gYmUgaW50ZXJuZWQgdGhlIGNsYXNzIG11c3QgaW1wbGVtZW50IHRoZQorICoge0BsaW5rcGxhaW4gamF2YS5sYW5nLk9iamVjdCNlcXVhbHMoamF2YS5sYW5nLk9iamVjdCkgZXF1YWxzfQorICogYW5kIHtAbGlua3BsYWluIGphdmEubGFuZy5PYmplY3QjaGFzaENvZGUoKSBoYXNoQ29kZX0gbWV0aG9kcy4KKyAqIFRoZSByZWNvbW1lbmRlZCBjb2RlIHRvIHVzZSBmb3Igc3RhdGVsZXNzIGZpbHRlcnMgYW5kIGZvcm1hdHRlcnMgaXM6CisgKiA8cHJlPgorICogcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKKyAqICAgICByZXR1cm4gb2JqID09IG51bGwgPyBmYWxzZSA6IG9iai5nZXRDbGFzcygpID09IGdldENsYXNzKCk7CisgKiB9CisgKgorICogcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAqICAgICByZXR1cm4gMzEgKiBnZXRDbGFzcygpLmhhc2hDb2RlKCk7CisgKiB9CisgKiA8L3ByZT4KKyAqCisgKiA8cD4KKyAqIDxiPlNvcnRpbmc6PC9iPgorICogQWxsIDx0dD5Mb2dSZWNvcmQ8L3R0PiBvYmplY3RzIGFyZSBvcmRlcmVkIHByaW9yIHRvIGZvcm1hdHRpbmcgaWYgdGhpcworICogPHR0PkhhbmRsZXI8L3R0PiBoYXMgYSBub24gbnVsbCBjb21wYXJhdG9yLiAgRGV2ZWxvcGVycyBtaWdodCBiZSBpbnRlcmVzdGVkCisgKiBpbiBzb3J0aW5nIHRoZSBmb3JtYXR0ZWQgZW1haWwgYnkgdGhyZWFkIGlkLCB0aW1lLCBhbmQgc2VxdWVuY2UgcHJvcGVydGllcworICogb2YgYSA8dHQ+TG9nUmVjb3JkPC90dD4uICBXaGVyZSBhcyBzeXN0ZW0gYWRtaW5pc3RyYXRvcnMgbWlnaHQgYmUgaW50ZXJlc3RlZAorICogaW4gc29ydGluZyB0aGUgZm9ybWF0dGVkIGVtYWlsIGJ5IHRocm93biwgbGV2ZWwsIHRpbWUsIGFuZCBzZXF1ZW5jZQorICogcHJvcGVydGllcyBvZiBhIDx0dD5Mb2dSZWNvcmQ8L3R0Pi4gIElmIGNvbXBhcmF0b3IgZm9yIHRoaXMgaGFuZGxlciBpcworICogPHR0Pm51bGw8L3R0PiB0aGVuIHRoZSBvcmRlciBpcyB1bnNwZWNpZmllZC4KKyAqCisgKiA8cD4KKyAqIDxiPkZvcm1hdHRpbmc6PC9iPgorICogVGhlIG1haW4gbWVzc2FnZSBib2R5IGlzIGZvcm1hdHRlZCB1c2luZyB0aGUgPHR0PkZvcm1hdHRlcjwvdHQ+IHJldHVybmVkIGJ5CisgKiA8dHQ+Z2V0Rm9ybWF0dGVyKCk8L3R0Pi4gIE9ubHkgcmVjb3JkcyB0aGF0IHBhc3MgdGhlIGZpbHRlciByZXR1cm5lZCBieQorICogPHR0PmdldEZpbHRlcigpPC90dD4gd2lsbCBiZSBpbmNsdWRlZCBpbiB0aGUgbWVzc2FnZSBib2R5LiAgVGhlIHN1YmplY3QKKyAqIDx0dD5Gb3JtYXR0ZXI8L3R0PiB3aWxsIHNlZSBhbGwgPHR0PkxvZ1JlY29yZDwvdHQ+IG9iamVjdHMgdGhhdCB3ZXJlCisgKiBwdWJsaXNoZWQgcmVnYXJkbGVzcyBvZiB0aGUgY3VycmVudCA8dHQ+RmlsdGVyPC90dD4uICBUaGUgTUlNRSB0eXBlIG9mIHRoZQorICogbWVzc2FnZSBib2R5IGNhbiBiZSB7QGxpbmtwbGFpbiBGaWxlVHlwZU1hcCNzZXREZWZhdWx0RmlsZVR5cGVNYXAgb3ZlcnJpZGRlbn0KKyAqIGJ5IGFkZGluZyBhIE1JTUUge0BsaW5rcGxhaW4gTWltZXR5cGVzRmlsZVR5cGVNYXAgZW50cnl9IHVzaW5nIHRoZSBzaW1wbGUKKyAqIGNsYXNzIG5hbWUgb2YgdGhlIGJvZHkgZm9ybWF0dGVyIGFzIHRoZSBmaWxlIGV4dGVuc2lvbi4gIFRoZSBNSU1FIHR5cGUgb2YgdGhlCisgKiBhdHRhY2htZW50cyBjYW4gYmUgb3ZlcnJpZGRlbiBieSBjaGFuZ2luZyB0aGUgYXR0YWNobWVudCBmaWxlIG5hbWUgZXh0ZW5zaW9uCisgKiBvciBieSBlZGl0aW5nIHRoZSBkZWZhdWx0IE1JTUUgZW50cnkgZm9yIGEgc3BlY2lmaWMgZmlsZSBuYW1lIGV4dGVuc2lvbi4KKyAqCisgKiA8cD4KKyAqIDxiPkF0dGFjaG1lbnRzOjwvYj4KKyAqIFRoaXMgPHR0PkhhbmRsZXI8L3R0PiBhbGxvd3MgbXVsdGlwbGUgYXR0YWNobWVudHMgcGVyIGVhY2ggZW1haWwgbWVzc2FnZS4KKyAqIFRoZSBwcmVzZW5jZSBvZiBhbiBhdHRhY2htZW50IGZvcm1hdHRlciB3aWxsIGNoYW5nZSB0aGUgY29udGVudCB0eXBlIG9mIHRoZQorICogZW1haWwgbWVzc2FnZSB0byBhIG11bHRpLXBhcnQgbWVzc2FnZS4gIFRoZSBhdHRhY2htZW50IG9yZGVyIG1hcHMgZGlyZWN0bHkgdG8KKyAqIHRoZSBhcnJheSBpbmRleCBvcmRlciBpbiB0aGlzIDx0dD5IYW5kbGVyPC90dD4gd2l0aCB6ZXJvIGluZGV4IGJlaW5nIHRoZQorICogZmlyc3QgYXR0YWNobWVudC4gIFRoZSBudW1iZXIgb2YgYXR0YWNobWVudCBmb3JtYXR0ZXJzIGNvbnRyb2xzIHRoZSBudW1iZXIgb2YKKyAqIGF0dGFjaG1lbnRzIHBlciBlbWFpbCBhbmQgdGhlIGNvbnRlbnQgdHlwZSBvZiBlYWNoIGF0dGFjaG1lbnQuICBUaGUKKyAqIGF0dGFjaG1lbnQgZmlsdGVycyBkZXRlcm1pbmUgaWYgYSA8dHQ+TG9nUmVjb3JkPC90dD4gd2lsbCBiZSBpbmNsdWRlZCBpbiBhbgorICogYXR0YWNobWVudC4gIElmIGFuIGF0dGFjaG1lbnQgZmlsdGVyIGlzIDx0dD5udWxsPC90dD4gdGhlbiBhbGwgcmVjb3JkcyBhcmUKKyAqIGluY2x1ZGVkIGZvciB0aGF0IGF0dGFjaG1lbnQuICBBdHRhY2htZW50cyB3aXRob3V0IGNvbnRlbnQgd2lsbCBiZSBvbWl0dGVkCisgKiBmcm9tIGVtYWlsIG1lc3NhZ2UuICBUaGUgYXR0YWNobWVudCBuYW1lIGZvcm1hdHRlcnMgY3JlYXRlIHRoZSBmaWxlIG5hbWUgZm9yCisgKiBhbiBhdHRhY2htZW50LiAgQ3VzdG9tIGF0dGFjaG1lbnQgbmFtZSBmb3JtYXR0ZXJzIGNhbiBiZSB1c2VkIHRvIGdlbmVyYXRlIGFuCisgKiBhdHRhY2htZW50IG5hbWUgYmFzZWQgb24gdGhlIGNvbnRlbnRzIG9mIHRoZSBhdHRhY2htZW50LgorICoKKyAqIDxwPgorICogPGI+UHVzaCBMZXZlbCBhbmQgUHVzaCBGaWx0ZXI6PC9iPgorICogVGhlIHB1c2ggbWV0aG9kLCBwdXNoIGxldmVsLCBhbmQgb3B0aW9uYWwgcHVzaCBmaWx0ZXIgY2FuIGJlIHVzZWQgdG8KKyAqIGNvbmRpdGlvbmFsbHkgdHJpZ2dlciBhIHB1c2ggYXQgb3IgcHJpb3IgdG8gZnVsbCBjYXBhY2l0eS4gIFdoZW4gYSBwdXNoCisgKiBvY2N1cnMsIHRoZSBjdXJyZW50IGJ1ZmZlciBpcyBmb3JtYXR0ZWQgaW50byBhbiBlbWFpbCBhbmQgaXMgc2VudCB0byB0aGUKKyAqIGVtYWlsIHNlcnZlci4gIElmIHRoZSBwdXNoIG1ldGhvZCwgcHVzaCBsZXZlbCwgb3IgcHVzaCBmaWx0ZXIgdHJpZ2dlciBhIHB1c2gKKyAqIHRoZW4gdGhlIG91dGdvaW5nIGVtYWlsIGlzIGZsYWdnZWQgYXMgaGlnaCBpbXBvcnRhbmNlIHdpdGggdXJnZW50IHByaW9yaXR5LgorICoKKyAqIDxwPgorICogPGI+QnVmZmVyaW5nOjwvYj4KKyAqIExvZyByZWNvcmRzIHRoYXQgYXJlIHB1Ymxpc2hlZCBhcmUgc3RvcmVkIGluIGFuIGludGVybmFsIGJ1ZmZlci4gIFdoZW4gdGhpcworICogYnVmZmVyIHJlYWNoZXMgY2FwYWNpdHkgdGhlIGV4aXN0aW5nIHJlY29yZHMgYXJlIGZvcm1hdHRlZCBhbmQgc2VudCBpbiBhbgorICogZW1haWwuICBBbnkgcHVibGlzaGVkIHJlY29yZHMgY2FuIGJlIHNlbnQgYmVmb3JlIHJlYWNoaW5nIGNhcGFjaXR5IGJ5CisgKiBleHBsaWN0bHkgY2FsbGluZyB0aGUgPHR0PmZsdXNoPC90dD4sIDx0dD5wdXNoPC90dD4sIG9yIDx0dD5jbG9zZTwvdHQ+CisgKiBtZXRob2RzLiAgSWYgYSBjaXJjdWxhciBidWZmZXIgaXMgcmVxdWlyZWQgdGhlbiB0aGlzIGhhbmRsZXIgY2FuIGJlIHdyYXBwZWQKKyAqIHdpdGggYSB7QGxpbmtwbGFpbiBqYXZhLnV0aWwubG9nZ2luZy5NZW1vcnlIYW5kbGVyfSB0eXBpY2FsbHkgd2l0aCBhbgorICogZXF1aXZhbGVudCBjYXBhY2l0eSwgbGV2ZWwsIGFuZCBwdXNoIGxldmVsLgorICoKKyAqIDxwPgorICogPGI+RXJyb3IgSGFuZGxpbmc6PC9iPgorICogSWYgdGhlIHRyYW5zcG9ydCBvZiBhbiBlbWFpbCBtZXNzYWdlIGZhaWxzLCB0aGUgZW1haWwgaXMgY29udmVydGVkIHRvCisgKiBhIHtAbGlua3BsYWluIGphdmF4Lm1haWwuaW50ZXJuZXQuTWltZU1lc3NhZ2Ujd3JpdGVUbyByYXd9CisgKiB7QGxpbmtwbGFpbiBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbSN0b1N0cmluZyhqYXZhLmxhbmcuU3RyaW5nKSBzdHJpbmd9CisgKiBhbmQgaXMgdGhlbiBwYXNzZWQgYXMgdGhlIDx0dD5tc2c8L3R0PiBwYXJhbWV0ZXIgdG8KKyAqIHtAbGlua3BsYWluIEhhbmRsZXIjcmVwb3J0RXJyb3IgcmVwb3J0RXJyb3J9IGFsb25nIHdpdGggdGhlIGV4Y2VwdGlvbgorICogZGVzY3JpYmluZyB0aGUgY2F1c2Ugb2YgdGhlIGZhaWx1cmUuICBUaGlzIGFsbG93cyBjdXN0b20gZXJyb3IgbWFuYWdlcnMgdG8KKyAqIHN0b3JlLCB7QGxpbmtwbGFpbiBqYXZheC5tYWlsLmludGVybmV0Lk1pbWVNZXNzYWdlI01pbWVNZXNzYWdlKAorICogamF2YXgubWFpbC5TZXNzaW9uLCBqYXZhLmlvLklucHV0U3RyZWFtKSByZWNvbnN0cnVjdH0sIGFuZCByZXNlbmQgdGhlCisgKiBvcmlnaW5hbCBNaW1lTWVzc2FnZS4gIFRoZSBtZXNzYWdlIHBhcmFtZXRlciBzdHJpbmcgaXMgPGI+bm90PC9iPiBhIHJhdyBlbWFpbAorICogaWYgaXQgc3RhcnRzIHdpdGggdmFsdWUgcmV0dXJuZWQgZnJvbSA8dHQ+TGV2ZWwuU0VWRVJFLmdldE5hbWUoKTwvdHQ+LgorICogQ3VzdG9tIGVycm9yIG1hbmFnZXJzIGNhbiB1c2UgdGhlIGZvbGxvd2luZyB0ZXN0IHRvIGRldGVybWluZSBpZiB0aGUKKyAqIDx0dD5tc2c8L3R0PiBwYXJhbWV0ZXIgZnJvbSB0aGlzIGhhbmRsZXIgaXMgYSByYXcgZW1haWw6CisgKgorICogPHByZT4KKyAqIHB1YmxpYyB2b2lkIGVycm9yKFN0cmluZyBtc2csIEV4Y2VwdGlvbiBleCwgaW50IGNvZGUpIHsKKyAqICAgICAgaWYgKG1zZyA9PSBudWxsIHx8IG1zZy5sZW5ndGgoKSA9PSAwIHx8IG1zZy5zdGFydHNXaXRoKExldmVsLlNFVkVSRS5nZXROYW1lKCkpKSB7CisgKiAgICAgICAgICBzdXBlci5lcnJvcihtc2csIGV4LCBjb2RlKTsKKyAqICAgICAgfSBlbHNlIHsKKyAqICAgICAgICAgIC8vVGhlICdtc2cnIHBhcmFtZXRlciBpcyBhIHJhdyBlbWFpbC4KKyAqICAgICAgfQorICogfQorICogPC9wcmU+CisgKgorICogQGF1dGhvciBKYXNvbiBNZWhyZW5zCisgKiBAc2luY2UgSmF2YU1haWwgMS40LjMKKyAqLworcHVibGljIGNsYXNzIE1haWxIYW5kbGVyIGV4dGVuZHMgSGFuZGxlciB7CisgICAgLyoqCisgICAgICogVXNlIHRoZSBlbXB0eUZpbHRlckFycmF5IG1ldGhvZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBGaWx0ZXJbXSBFTVBUWV9GSUxURVJTID0gbmV3IEZpbHRlclswXTsKKyAgICAvKioKKyAgICAgKiBVc2UgdGhlIGVtcHR5Rm9ybWF0dGVyQXJyYXkgbWV0aG9kLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEZvcm1hdHRlcltdIEVNUFRZX0ZPUk1BVFRFUlMgPSBuZXcgRm9ybWF0dGVyWzBdOworICAgIC8qKgorICAgICAqIE1pbiBieXRlIHNpemUgZm9yIGhlYWRlciBkYXRhLiAgVXNlZCBmb3IgaW5pdGlhbCBhcnJheXMgc2l6aW5nLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNSU5fSEVBREVSX1NJWkUgPSAxMDI0OworICAgIC8qKgorICAgICAqIENhY2hlIHRoZSBvZmYgdmFsdWUuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IG9mZlZhbHVlID0gTGV2ZWwuT0ZGLmludFZhbHVlKCk7CisgICAgLyoqCisgICAgICogVGhlIGFjdGlvbiB0byBzZXQgdGhlIGNvbnRleHQgY2xhc3MgbG9hZGVyIGZvciB1c2Ugd2l0aCB0aGUgSmF2YU1haWwgQVBJLgorICAgICAqIExvYWQgYW5kIHBpbiB0aGlzIGJlZm9yZSBpdCBpcyBsb2FkZWQgaW4gdGhlIGNsb3NlIG1ldGhvZC4gVGhlIGZpZWxkIGlzCisgICAgICogZGVjbGFyZWQgYXMgamF2YS5zZWN1cml0eS5Qcml2aWxlZ2VkQWN0aW9uIHNvCisgICAgICogV2ViYXBwQ2xhc3NMb2FkZXIuY2xlYXJSZWZlcmVuY2VzU3RhdGljRmluYWwoKSBtZXRob2Qgd2lsbCBpZ25vcmUgdGhpcworICAgICAqIGZpZWxkLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFByaXZpbGVnZWRBY3Rpb248T2JqZWN0PiBNQUlMSEFORExFUl9MT0FERVIKKyAgICAgICAgICAgID0gbmV3IEdldEFuZFNldENvbnRleHQoTWFpbEhhbmRsZXIuY2xhc3MpOworICAgIC8qKgorICAgICAqIEEgdGhyZWFkIGxvY2FsIG11dGV4IHVzZWQgdG8gcHJldmVudCBsb2dnaW5nIGxvb3BzLiAgVGhpcyBjb2RlIGhhcyB0byBiZQorICAgICAqIHByZXBhcmVkIHRvIGRlYWwgd2l0aCB1bmV4cGVjdGVkIG51bGwgdmFsdWVzIHNpbmNlIHRoZQorICAgICAqIFdlYmFwcENsYXNzTG9hZGVyLmNsZWFyUmVmZXJlbmNlc1RocmVhZExvY2FscygpIGFuZAorICAgICAqIElubm9jdW91c1RocmVhZC5lcmFzZVRocmVhZExvY2FscygpIGNhbiByZW1vdmUgdGhyZWFkIGxvY2FsIHZhbHVlcy4KKyAgICAgKiBUaGUgTVVURVggaGFzIDUgc3RhdGVzOgorICAgICAqIDEuIEEgbnVsbCB2YWx1ZSBtZWFuaW5nIGRlZmF1bHQgc3RhdGUgb2Ygbm90IHB1Ymxpc2hpbmcuCisgICAgICogMi4gTVVURVhfUFVCTElTSCBvbiBmaXJzdCBlbnRyeSBvZiBhIHB1c2ggb3IgcHVibGlzaC4KKyAgICAgKiAzLiBUaGUgaW5kZXggb2YgdGhlIGZpcnN0IGZpbHRlciB0byBhY2NlcHQgYSBsb2cgcmVjb3JkLgorICAgICAqIDQuIE1VVEVYX1JFUE9SVCB3aGVuIGN5Y2xlIG9mIHJlY29yZHMgaXMgZGV0ZWN0ZWQuCisgICAgICogNS4gTVVURVhUX0xJTktBR0Ugd2hlbiBhIGxpbmthZ2UgZXJyb3IgaXMgcmVwb3J0ZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVGhyZWFkTG9jYWw8SW50ZWdlcj4gTVVURVggPSBuZXcgVGhyZWFkTG9jYWw8PigpOworICAgIC8qKgorICAgICAqIFRoZSBtYXJrZXIgb2JqZWN0IHVzZWQgdG8gcmVwb3J0IGEgcHVibGlzaGluZyBzdGF0ZS4KKyAgICAgKiBUaGlzIG11c3QgYmUgbGVzcyB0aGFuIHRoZSBib2R5IGZpbHRlciBpbmRleCAoLTEpLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEludGVnZXIgTVVURVhfUFVCTElTSCA9IC0yOworICAgIC8qKgorICAgICAqIFRoZSB1c2VkIGZvciB0aGUgZXJyb3IgcmVwb3J0aW5nIHN0YXRlLgorICAgICAqIFRoaXMgbXVzdCBiZSBsZXNzIHRoYW4gdGhlIFBVQkxJU0ggc3RhdGUuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgSW50ZWdlciBNVVRFWF9SRVBPUlQgPSAtNDsKKyAgICAvKioKKyAgICAgKiBUaGUgdXNlZCBmb3IgbGlua2FnZSBlcnJvciByZXBvcnRpbmcuCisgICAgICogVGhpcyBtdXN0IGJlIGxlc3MgdGhhbiB0aGUgUkVQT1JUIHN0YXRlLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEludGVnZXIgTVVURVhfTElOS0FHRSA9IC04OworICAgIC8qKgorICAgICAqIFVzZWQgdG8gdHVybiBvZmYgc2VjdXJpdHkgY2hlY2tzLgorICAgICAqLworICAgIHByaXZhdGUgdm9sYXRpbGUgYm9vbGVhbiBzZWFsZWQ7CisgICAgLyoqCisgICAgICogRGV0ZXJtaW5lcyBpZiB3ZSBhcmUgaW5zaWRlIG9mIGEgcHVzaC4KKyAgICAgKiBNYWtlcyB0aGUgaGFuZGxlciBwcm9wZXJ0aWVzIHJlYWQtb25seSBkdXJpbmcgYSBwdXNoLgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBpc1dyaXRpbmc7CisgICAgLyoqCisgICAgICogSG9sZHMgYWxsIG9mIHRoZSBlbWFpbCBzZXJ2ZXIgcHJvcGVydGllcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIFByb3BlcnRpZXMgbWFpbFByb3BzOworICAgIC8qKgorICAgICAqIEhvbGRzIHRoZSBhdXRoZW50aWNhdG9yIHJlcXVpcmVkIHRvIGxvZ2luIHRvIHRoZSBlbWFpbCBzZXJ2ZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBBdXRoZW50aWNhdG9yIGF1dGg7CisgICAgLyoqCisgICAgICogSG9sZHMgdGhlIHNlc3Npb24gb2JqZWN0IHVzZWQgdG8gZ2VuZXJhdGUgZW1haWxzLgorICAgICAqIFNlc3Npb25zIGNhbiBiZSBzaGFyZWQgYnkgbXVsdGlwbGUgdGhyZWFkcy4KKyAgICAgKiBTZWUgSkRLLTYyMjgzOTEgYW5kIEsgNjI3OC4KKyAgICAgKi8KKyAgICBwcml2YXRlIFNlc3Npb24gc2Vzc2lvbjsKKyAgICAvKioKKyAgICAgKiBBIG1hcHBpbmcgb2YgbG9nIHJlY29yZCB0byBtYXRjaGluZyBmaWx0ZXIgaW5kZXguICBOZWdhdGl2ZSBvbmUgaXMgdXNlZAorICAgICAqIHRvIHRyYWNrIHRoZSBib2R5IGZpbHRlci4gIFplcm8gYW5kIGdyZWF0ZXIgaXMgdXNlZCB0byB0cmFjayB0aGUKKyAgICAgKiBhdHRhY2htZW50IHBhcnRzLiAgQWxsIGluZGV4ZXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHRoZSBtYXRjaGVkIHZhbHVlCisgICAgICogaGF2ZSBhbHJlYWR5IHNlZW4gdGhlIGdpdmVuIGxvZyByZWNvcmQuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnRbXSBtYXRjaGVkOworICAgIC8qKgorICAgICAqIEhvbGRzIGFsbCBvZiB0aGUgbG9nIHJlY29yZHMgdGhhdCB3aWxsIGJlIHVzZWQgdG8gY3JlYXRlIHRoZSBlbWFpbC4KKyAgICAgKi8KKyAgICBwcml2YXRlIExvZ1JlY29yZFtdIGRhdGE7CisgICAgLyoqCisgICAgICogVGhlIG51bWJlciBvZiBsb2cgcmVjb3JkcyBpbiB0aGUgYnVmZmVyLgorICAgICAqLworICAgIHByaXZhdGUgaW50IHNpemU7CisgICAgLyoqCisgICAgICogVGhlIG1heGltdW0gbnVtYmVyIG9mIGxvZyByZWNvcmRzIHRvIGZvcm1hdCBwZXIgZW1haWwuCisgICAgICogVXNlZCB0byByb3VnaGx5IGJvdW5kIHRoZSBzaXplIG9mIGFuIGVtYWlsLgorICAgICAqIEV2ZXJ5IHRpbWUgdGhlIGNhcGFjaXR5IGlzIHJlYWNoZWQsIHRoZSBoYW5kbGVyIHdpbGwgcHVzaC4KKyAgICAgKiBUaGUgY2FwYWNpdHkgd2lsbCBiZSBuZWdhdGl2ZSBpZiB0aGlzIGhhbmRsZXIgaXMgY2xvc2VkLgorICAgICAqIE5lZ2F0aXZlIHZhbHVlcyBhcmUgdXNlZCB0byBlbnN1cmUgYWxsIHJlY29yZHMgYXJlIHB1c2hlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBjYXBhY2l0eTsKKyAgICAvKioKKyAgICAgKiBVc2VkIHRvIG9yZGVyIGFsbCBsb2cgcmVjb3JkcyBwcmlvciB0byBmb3JtYXR0aW5nLiAgVGhlIG1haW4gZW1haWwgYm9keQorICAgICAqIGFuZCBhbGwgYXR0YWNobWVudHMgdXNlIHRoZSBvcmRlciBkZXRlcm1pbmVkIGJ5IHRoaXMgY29tcGFyYXRvci4gIElmIG5vCisgICAgICogY29tcGFyYXRvciBpcyBwcmVzZW50IHRoZSBsb2cgcmVjb3JkcyB3aWxsIGJlIGluIG5vIHNwZWNpZmllZCBvcmRlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIENvbXBhcmF0b3I8PyBzdXBlciBMb2dSZWNvcmQ+IGNvbXBhcmF0b3I7CisgICAgLyoqCisgICAgICogSG9sZHMgdGhlIGZvcm1hdHRlciB1c2VkIHRvIGNyZWF0ZSB0aGUgc3ViamVjdCBsaW5lIG9mIHRoZSBlbWFpbC4KKyAgICAgKiBBIHN1YmplY3QgZm9ybWF0dGVyIGlzIG5vdCByZXF1aXJlZCBmb3IgdGhlIGVtYWlsIG1lc3NhZ2UuCisgICAgICogQWxsIHB1Ymxpc2hlZCByZWNvcmRzIHBhc3MgdGhyb3VnaCB0aGUgc3ViamVjdCBmb3JtYXR0ZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBGb3JtYXR0ZXIgc3ViamVjdEZvcm1hdHRlcjsKKyAgICAvKioKKyAgICAgKiBIb2xkcyB0aGUgcHVzaCBsZXZlbCBmb3IgdGhpcyBoYW5kbGVyLgorICAgICAqIFRoaXMgaXMgb25seSByZXF1aXJlZCBpZiBhbiBlbWFpbCBtdXN0IGJlIHNlbnQgcHJpb3IgdG8gc2h1dGRvd24KKyAgICAgKiBvciBiZWZvcmUgdGhlIGJ1ZmZlciBpcyBmdWxsLgorICAgICAqLworICAgIHByaXZhdGUgTGV2ZWwgcHVzaExldmVsOworICAgIC8qKgorICAgICAqIEhvbGRzIHRoZSBwdXNoIGZpbHRlciBmb3IgdHJpZ2dlciBjb25kaXRpb25zIHJlcXVpcmluZyBhbiBlYXJseSBwdXNoLgorICAgICAqIE9ubHkgZ2V0cyBjYWxsZWQgaWYgdGhlIGdpdmVuIGxvZyByZWNvcmQgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsCisgICAgICogdG8gdGhlIHB1c2ggbGV2ZWwgYW5kIHRoZSBwdXNoIGxldmVsIGlzIG5vdCBMZXZlbC5PRkYuCisgICAgICovCisgICAgcHJpdmF0ZSBGaWx0ZXIgcHVzaEZpbHRlcjsKKyAgICAvKioKKyAgICAgKiBIb2xkcyB0aGUgZW50cnkgYW5kIGJvZHkgZmlsdGVyIGZvciB0aGlzIGhhbmRsZXIuCisgICAgICogVGhlcmUgaXMgbm8gd2F5IHRvIHVuLXNlYWwgdGhlIHN1cGVyIGhhbmRsZXIuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2xhdGlsZSBGaWx0ZXIgZmlsdGVyOworICAgIC8qKgorICAgICAqIEhvbGRzIHRoZSBsZXZlbCBmb3IgdGhpcyBoYW5kbGVyLgorICAgICAqIFRoZXJlIGlzIG5vIHdheSB0byB1bi1zZWFsIHRoZSBzdXBlciBoYW5kbGVyLgorICAgICAqLworICAgIHByaXZhdGUgdm9sYXRpbGUgTGV2ZWwgbG9nTGV2ZWwgPSBMZXZlbC5BTEw7CisgICAgLyoqCisgICAgICogSG9sZHMgdGhlIGZpbHRlcnMgZm9yIGVhY2ggYXR0YWNobWVudC4gIEZpbHRlcnMgYXJlIG9wdGlvbmFsIGZvcgorICAgICAqIGVhY2ggYXR0YWNobWVudC4gIFRoaXMgaXMgZGVjbGFyZWQgdm9sYXRpbGUgYmVjYXVzZSB0aGlzIGlzIHRyZWF0ZWQgYXMKKyAgICAgKiBjb3B5LW9uLXdyaXRlLiBUaGUgVk9fVk9MQVRJTEVfUkVGRVJFTkNFX1RPX0FSUkFZIHdhcm5pbmcgaXMgYSBmYWxzZQorICAgICAqIHBvc2l0aXZlLgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJWb2xhdGlsZUFycmF5RmllbGQiKQorICAgIHByaXZhdGUgdm9sYXRpbGUgRmlsdGVyW10gYXR0YWNobWVudEZpbHRlcnM7CisgICAgLyoqCisgICAgICogSG9sZHMgdGhlIGVuY29kaW5nIG5hbWUgZm9yIHRoaXMgaGFuZGxlci4KKyAgICAgKiBUaGVyZSBpcyBubyB3YXkgdG8gdW4tc2VhbCB0aGUgc3VwZXIgaGFuZGxlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyBlbmNvZGluZzsKKyAgICAvKioKKyAgICAgKiBIb2xkcyB0aGUgZW50cnkgYW5kIGJvZHkgZmlsdGVyIGZvciB0aGlzIGhhbmRsZXIuCisgICAgICogVGhlcmUgaXMgbm8gd2F5IHRvIHVuLXNlYWwgdGhlIHN1cGVyIGhhbmRsZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBGb3JtYXR0ZXIgZm9ybWF0dGVyOworICAgIC8qKgorICAgICAqIEhvbGRzIHRoZSBmb3JtYXR0ZXJzIHRoYXQgY3JlYXRlIHRoZSBjb250ZW50IGZvciBlYWNoIGF0dGFjaG1lbnQuCisgICAgICogRWFjaCBmb3JtYXR0ZXIgbWFwcyBkaXJlY3RseSB0byBhbiBhdHRhY2htZW50LiAgVGhlIGZvcm1hdHRlcnMKKyAgICAgKiBnZXRIZWFkLCBmb3JtYXQsIGFuZCBnZXRUYWlsIG1ldGhvZHMgYXJlIG9ubHkgY2FsbGVkIGlmIG9uZSBvciBtb3JlCisgICAgICogbG9nIHJlY29yZHMgcGFzcyB0aHJvdWdoIHRoZSBhdHRhY2htZW50IGZpbHRlcnMuCisgICAgICovCisgICAgcHJpdmF0ZSBGb3JtYXR0ZXJbXSBhdHRhY2htZW50Rm9ybWF0dGVyczsKKyAgICAvKioKKyAgICAgKiBIb2xkcyB0aGUgZm9ybWF0dGVycyB0aGF0IGNyZWF0ZSB0aGUgZmlsZSBuYW1lIGZvciBlYWNoIGF0dGFjaG1lbnQuCisgICAgICogRWFjaCBmb3JtYXR0ZXIgbXVzdCBwcm9kdWNlIGEgbm9uIG51bGwgYW5kIG5vbiBlbXB0eSBuYW1lLgorICAgICAqIFRoZSBmaW5hbCBmaWxlIG5hbWUgd2lsbCBiZSB0aGUgY29uY2F0ZW5hdGlvbiBvZiBvbmUgZ2V0SGVhZCBjYWxsLCBwbHVzCisgICAgICogYWxsIG9mIHRoZSBmb3JtYXQgY2FsbHMsIHBsdXMgb25lIGdldFRhaWwgY2FsbC4KKyAgICAgKi8KKyAgICBwcml2YXRlIEZvcm1hdHRlcltdIGF0dGFjaG1lbnROYW1lczsKKyAgICAvKioKKyAgICAgKiBVc2VkIHRvIG92ZXJyaWRlIHRoZSBjb250ZW50IHR5cGUgZm9yIHRoZSBib2R5IGFuZCBzZXQgdGhlIGNvbnRlbnQgdHlwZQorICAgICAqIGZvciBlYWNoIGF0dGFjaG1lbnQuCisgICAgICovCisgICAgcHJpdmF0ZSBGaWxlVHlwZU1hcCBjb250ZW50VHlwZXM7CisgICAgLyoqCisgICAgICogSG9sZHMgdGhlIGVycm9yIG1hbmFnZXIgZm9yIHRoaXMgaGFuZGxlci4KKyAgICAgKiBUaGVyZSBpcyBubyB3YXkgdG8gdW4tc2VhbCB0aGUgc3VwZXIgaGFuZGxlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvbGF0aWxlIEVycm9yTWFuYWdlciBlcnJvck1hbmFnZXIgPSBkZWZhdWx0RXJyb3JNYW5hZ2VyKCk7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgPHR0Pk1haWxIYW5kbGVyPC90dD4gdGhhdCBpcyBjb25maWd1cmVkIGJ5IHRoZQorICAgICAqIDx0dD5Mb2dNYW5hZ2VyPC90dD4gY29uZmlndXJhdGlvbiBwcm9wZXJ0aWVzLgorICAgICAqIEB0aHJvd3MgU2VjdXJpdHlFeGNlcHRpb24gIGlmIGEgc2VjdXJpdHkgbWFuYWdlciBleGlzdHMgYW5kIHRoZQorICAgICAqIGNhbGxlciBkb2VzIG5vdCBoYXZlIDx0dD5Mb2dnaW5nUGVybWlzc2lvbigiY29udHJvbCIpPC90dD4uCisgICAgICovCisgICAgcHVibGljIE1haWxIYW5kbGVyKCkgeworICAgICAgICBpbml0KChQcm9wZXJ0aWVzKSBudWxsKTsKKyAgICAgICAgc2VhbGVkID0gdHJ1ZTsKKyAgICAgICAgY2hlY2tBY2Nlc3MoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgPHR0Pk1haWxIYW5kbGVyPC90dD4gdGhhdCBpcyBjb25maWd1cmVkIGJ5IHRoZQorICAgICAqIDx0dD5Mb2dNYW5hZ2VyPC90dD4gY29uZmlndXJhdGlvbiBwcm9wZXJ0aWVzIGJ1dCBvdmVycmlkZXMgdGhlCisgICAgICogPHR0PkxvZ01hbmFnZXI8L3R0PiBjYXBhY2l0eSB3aXRoIHRoZSBnaXZlbiBjYXBhY2l0eS4KKyAgICAgKiBAcGFyYW0gY2FwYWNpdHkgb2YgdGhlIGludGVybmFsIGJ1ZmZlci4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiA8dHQ+Y2FwYWNpdHk8L3R0PiBsZXNzIHRoYW4gb25lLgorICAgICAqIEB0aHJvd3MgU2VjdXJpdHlFeGNlcHRpb24gIGlmIGEgc2VjdXJpdHkgbWFuYWdlciBleGlzdHMgYW5kIHRoZQorICAgICAqIGNhbGxlciBkb2VzIG5vdCBoYXZlIDx0dD5Mb2dnaW5nUGVybWlzc2lvbigiY29udHJvbCIpPC90dD4uCisgICAgICovCisgICAgcHVibGljIE1haWxIYW5kbGVyKGZpbmFsIGludCBjYXBhY2l0eSkgeworICAgICAgICBpbml0KChQcm9wZXJ0aWVzKSBudWxsKTsKKyAgICAgICAgc2VhbGVkID0gdHJ1ZTsKKyAgICAgICAgc2V0Q2FwYWNpdHkwKGNhcGFjaXR5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgbWFpbCBoYW5kbGVyIHdpdGggdGhlIGdpdmVuIG1haWwgcHJvcGVydGllcy4KKyAgICAgKiBUaGUga2V5L3ZhbHVlIHBhaXJzIGFyZSBkZWZpbmVkIGluIHRoZSA8dHQ+SmF2YSBNYWlsIEFQSTwvdHQ+CisgICAgICogZG9jdW1lbnRhdGlvbi4gIFRoaXMgPHR0PkhhbmRsZXI8L3R0PiB3aWxsIGFsc28gc2VhcmNoIHRoZQorICAgICAqIDx0dD5Mb2dNYW5hZ2VyPC90dD4gZm9yIGRlZmF1bHRzIGlmIG5lZWRlZC4KKyAgICAgKiBAcGFyYW0gcHJvcHMgYSBub24gPHR0Pm51bGw8L3R0PiBwcm9wZXJ0aWVzIG9iamVjdC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDx0dD5wcm9wczwvdHQ+IGlzIDx0dD5udWxsPC90dD4uCisgICAgICogQHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbiAgaWYgYSBzZWN1cml0eSBtYW5hZ2VyIGV4aXN0cyBhbmQgdGhlCisgICAgICogY2FsbGVyIGRvZXMgbm90IGhhdmUgPHR0PkxvZ2dpbmdQZXJtaXNzaW9uKCJjb250cm9sIik8L3R0Pi4KKyAgICAgKi8KKyAgICBwdWJsaWMgTWFpbEhhbmRsZXIoZmluYWwgUHJvcGVydGllcyBwcm9wcykgeworICAgICAgICBpZiAocHJvcHMgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgaW5pdChwcm9wcyk7CisgICAgICAgIHNlYWxlZCA9IHRydWU7CisgICAgICAgIHNldE1haWxQcm9wZXJ0aWVzMChwcm9wcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2sgaWYgdGhpcyA8dHQ+SGFuZGxlcjwvdHQ+IHdvdWxkIGFjdHVhbGx5IGxvZyBhIGdpdmVuCisgICAgICogPHR0PkxvZ1JlY29yZDwvdHQ+IGludG8gaXRzIGludGVybmFsIGJ1ZmZlci4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIG1ldGhvZCBjaGVja3MgaWYgdGhlIDx0dD5Mb2dSZWNvcmQ8L3R0PiBoYXMgYW4gYXBwcm9wcmlhdGUgbGV2ZWwgYW5kCisgICAgICogd2hldGhlciBpdCBzYXRpc2ZpZXMgYW55IDx0dD5GaWx0ZXI8L3R0PiBpbmNsdWRpbmcgYW55IGF0dGFjaG1lbnQgZmlsdGVycy4KKyAgICAgKiBIb3dldmVyIGl0IGRvZXMgPGI+bm90PC9iPiBjaGVjayB3aGV0aGVyIHRoZSA8dHQ+TG9nUmVjb3JkPC90dD4gd291bGQKKyAgICAgKiByZXN1bHQgaW4gYSAicHVzaCIgb2YgdGhlIGJ1ZmZlciBjb250ZW50cy4KKyAgICAgKiA8cD4KKyAgICAgKiBAcGFyYW0gcmVjb3JkICBhIDx0dD5Mb2dSZWNvcmQ8L3R0PgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgPHR0PkxvZ1JlY29yZDwvdHQ+IHdvdWxkIGJlIGxvZ2dlZC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0xvZ2dhYmxlKGZpbmFsIExvZ1JlY29yZCByZWNvcmQpIHsKKyAgICAgICAgaW50IGxldmVsVmFsdWUgPSBnZXRMZXZlbCgpLmludFZhbHVlKCk7CisgICAgICAgIGlmIChyZWNvcmQuZ2V0TGV2ZWwoKS5pbnRWYWx1ZSgpIDwgbGV2ZWxWYWx1ZSB8fCBsZXZlbFZhbHVlID09IG9mZlZhbHVlKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBGaWx0ZXIgYm9keSA9IGdldEZpbHRlcigpOworICAgICAgICBpZiAoYm9keSA9PSBudWxsIHx8IGJvZHkuaXNMb2dnYWJsZShyZWNvcmQpKSB7CisgICAgICAgICAgICBzZXRNYXRjaGVkUGFydCgtMSk7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBpc0F0dGFjaG1lbnRMb2dnYWJsZShyZWNvcmQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFN0b3JlcyBhIDx0dD5Mb2dSZWNvcmQ8L3R0PiBpbiB0aGUgaW50ZXJuYWwgYnVmZmVyLgorICAgICAqIDxwPgorICAgICAqIFRoZSA8dHQ+aXNMb2dnYWJsZTwvdHQ+IG1ldGhvZCBpcyBjYWxsZWQgdG8gY2hlY2sgaWYgdGhlIGdpdmVuIGxvZyByZWNvcmQKKyAgICAgKiBpcyBsb2dnYWJsZS4gSWYgdGhlIGdpdmVuIHJlY29yZCBpcyBsb2dnYWJsZSwgaXQgaXMgY29waWVkIGludG8KKyAgICAgKiBhbiBpbnRlcm5hbCBidWZmZXIuICBUaGVuIHRoZSByZWNvcmQncyBsZXZlbCBwcm9wZXJ0eSBpcyBjb21wYXJlZCB3aXRoCisgICAgICogdGhlIHB1c2ggbGV2ZWwuIElmIHRoZSBnaXZlbiBsZXZlbCBvZiB0aGUgPHR0PkxvZ1JlY29yZDwvdHQ+CisgICAgICogaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBwdXNoIGxldmVsIHRoZW4gdGhlIHB1c2ggZmlsdGVyIGlzCisgICAgICogY2FsbGVkLiAgSWYgbm8gcHVzaCBmaWx0ZXIgZXhpc3RzLCB0aGUgcHVzaCBmaWx0ZXIgcmV0dXJucyB0cnVlLAorICAgICAqIG9yIHRoZSBjYXBhY2l0eSBvZiB0aGUgaW50ZXJuYWwgYnVmZmVyIGhhcyBiZWVuIHJlYWNoZWQgdGhlbiBhbGwgYnVmZmVyZWQKKyAgICAgKiByZWNvcmRzIGFyZSBmb3JtYXR0ZWQgaW50byBvbmUgZW1haWwgYW5kIHNlbnQgdG8gdGhlIHNlcnZlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSAgcmVjb3JkICBkZXNjcmlwdGlvbiBvZiB0aGUgbG9nIGV2ZW50LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHB1Ymxpc2goZmluYWwgTG9nUmVjb3JkIHJlY29yZCkgeworICAgICAgICAvKioKKyAgICAgICAgICogSXQgaXMgcG9zc2libGUgZm9yIHRoZSBoYW5kbGVyIHRvIGJlIGNsb3NlZCBhZnRlciB0aGUKKyAgICAgICAgICogY2FsbCB0byBpc0xvZ2dhYmxlLiAgSW4gdGhhdCBjYXNlLCB0aGUgY3VycmVudCB0aHJlYWQKKyAgICAgICAgICogd2lsbCBwdXNoIHRvIGVuc3VyZSB0aGF0IGFsbCBwdWJsaXNoZWQgcmVjb3JkcyBhcmUgc2VudC4KKyAgICAgICAgICogU2VlIGNsb3NlKCkuCisgICAgICAgICAqLworCisgICAgICAgIGlmICh0cnlNdXRleCgpKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGlmIChpc0xvZ2dhYmxlKHJlY29yZCkpIHsKKyAgICAgICAgICAgICAgICAgICAgcmVjb3JkLmdldFNvdXJjZU1ldGhvZE5hbWUoKTsgLy9JbmZlciBjYWxsZXIuCisgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2gwKHJlY29yZCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgTGlua2FnZUVycm9yIEpESzgxNTI1MTUpIHsKKyAgICAgICAgICAgICAgICByZXBvcnRMaW5rYWdlRXJyb3IoSkRLODE1MjUxNSwgRXJyb3JNYW5hZ2VyLldSSVRFX0ZBSUxVUkUpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICByZWxlYXNlTXV0ZXgoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJlcG9ydFVuUHVibGlzaGVkRXJyb3IocmVjb3JkKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIHRoZSBwdWJsaXNoIGFmdGVyIHRoZSByZWNvcmQgaGFzIGJlZW4gZmlsdGVyZWQuCisgICAgICogQHBhcmFtIHJlY29yZCB0aGUgcmVjb3JkLgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjQuNQorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBwdWJsaXNoMChmaW5hbCBMb2dSZWNvcmQgcmVjb3JkKSB7CisgICAgICAgIE1lc3NhZ2UgbXNnOworICAgICAgICBib29sZWFuIHByaW9yaXR5OworICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgIGlmIChzaXplID09IGRhdGEubGVuZ3RoICYmIHNpemUgPCBjYXBhY2l0eSkgeworICAgICAgICAgICAgICAgIGdyb3coKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKHNpemUgPCBkYXRhLmxlbmd0aCkgeworICAgICAgICAgICAgICAgIC8vYXNzZXJ0IGRhdGEubGVuZ3RoID09IG1hdGNoZWQubGVuZ3RoOworICAgICAgICAgICAgICAgIG1hdGNoZWRbc2l6ZV0gPSBnZXRNYXRjaGVkUGFydCgpOworICAgICAgICAgICAgICAgIGRhdGFbc2l6ZV0gPSByZWNvcmQ7CisgICAgICAgICAgICAgICAgKytzaXplOyAvL0JlIG5pY2UgdG8gY2xpZW50IGNvbXBpbGVyLgorICAgICAgICAgICAgICAgIHByaW9yaXR5ID0gaXNQdXNoYWJsZShyZWNvcmQpOworICAgICAgICAgICAgICAgIGlmIChwcmlvcml0eSB8fCBzaXplID49IGNhcGFjaXR5KSB7CisgICAgICAgICAgICAgICAgICAgIG1zZyA9IHdyaXRlTG9nUmVjb3JkcyhFcnJvck1hbmFnZXIuV1JJVEVfRkFJTFVSRSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgbXNnID0gbnVsbDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHByaW9yaXR5ID0gZmFsc2U7CisgICAgICAgICAgICAgICAgbXNnID0gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmIChtc2cgIT0gbnVsbCkgeworICAgICAgICAgICAgc2VuZChtc2csIHByaW9yaXR5LCBFcnJvck1hbmFnZXIuV1JJVEVfRkFJTFVSRSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXBvcnQgdG8gdGhlIGVycm9yIG1hbmFnZXIgdGhhdCBhIGxvZ2dpbmcgbG9vcCB3YXMgZGV0ZWN0ZWQgYW5kCisgICAgICogd2UgYXJlIGdvaW5nIHRvIGJyZWFrIHRoZSBjeWNsZSBvZiBtZXNzYWdlcy4gIEl0IGlzIHBvc3NpYmxlIHRoYXQKKyAgICAgKiBhIGN1c3RvbSBlcnJvciBtYW5hZ2VyIGNvdWxkIGNvbnRpbnVlIHRoZSBjeWNsZSBpbiB3aGljaCBjYXNlCisgICAgICogd2Ugd2lsbCBzdG9wIHRyeWluZyB0byByZXBvcnQgZXJyb3JzLgorICAgICAqIEBwYXJhbSByZWNvcmQgdGhlIHJlY29yZCBvciBudWxsLgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjQuNgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZXBvcnRVblB1Ymxpc2hlZEVycm9yKExvZ1JlY29yZCByZWNvcmQpIHsKKyAgICAgICAgZmluYWwgSW50ZWdlciBpZHggPSBNVVRFWC5nZXQoKTsKKyAgICAgICAgaWYgKGlkeCA9PSBudWxsIHx8IGlkeCA+IE1VVEVYX1JFUE9SVCkgeworICAgICAgICAgICAgTVVURVguc2V0KE1VVEVYX1JFUE9SVCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBtc2c7CisgICAgICAgICAgICAgICAgaWYgKHJlY29yZCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIEZvcm1hdHRlciBmID0gY3JlYXRlU2ltcGxlRm9ybWF0dGVyKCk7CisgICAgICAgICAgICAgICAgICAgIG1zZyA9ICJMb2cgcmVjb3JkICIgKyByZWNvcmQuZ2V0U2VxdWVuY2VOdW1iZXIoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiB3YXMgbm90IHB1Ymxpc2hlZC4gIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgaGVhZChmKSArIGZvcm1hdChmLCByZWNvcmQpICsgdGFpbChmLCAiIik7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgbXNnID0gbnVsbDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgRXhjZXB0aW9uIGUgPSBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICAgICAgIlJlY3Vyc2l2ZSBwdWJsaXNoIGRldGVjdGVkIGJ5IHRocmVhZCAiCisgICAgICAgICAgICAgICAgICAgICAgICArIFRocmVhZC5jdXJyZW50VGhyZWFkKCkpOworICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKG1zZywgZSwgRXJyb3JNYW5hZ2VyLldSSVRFX0ZBSUxVUkUpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBpZiAoaWR4ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgTVVURVguc2V0KGlkeCk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgTVVURVgucmVtb3ZlKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVXNlZCB0byBkZXRlY3QgcmVlbnRyYW5jZSBieSB0aGUgY3VycmVudCB0aHJlYWQgdG8gdGhlIHB1Ymxpc2ggbWV0aG9kLgorICAgICAqIFRoaXMgbXV0ZXggaXMgdGhyZWFkIGxvY2FsIHNjb3BlIGFuZCB3aWxsIG5vdCBibG9jayBvdGhlciB0aHJlYWRzLgorICAgICAqIFRoZSBzdGF0ZSBpcyBhZHZhbmNlZCBvbiBpZiB0aGUgY3VycmVudCB0aHJlYWQgaXMgaW4gYSByZXNldCBzdGF0ZS4KKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIG11dGV4IHdhcyBhY3F1aXJlZC4KKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS40LjYKKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gdHJ5TXV0ZXgoKSB7CisgICAgICAgIGlmIChNVVRFWC5nZXQoKSA9PSBudWxsKSB7CisgICAgICAgICAgICBNVVRFWC5zZXQoTVVURVhfUFVCTElTSCk7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbGVhc2VzIHRoZSBtdXRleCBoZWxkIGJ5IHRoZSBjdXJyZW50IHRocmVhZC4KKyAgICAgKiBUaGlzIG11dGV4IGlzIHRocmVhZCBsb2NhbCBzY29wZSBhbmQgd2lsbCBub3QgYmxvY2sgb3RoZXIgdGhyZWFkcy4KKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS40LjYKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmVsZWFzZU11dGV4KCkgeworICAgICAgICBNVVRFWC5yZW1vdmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIGlzIHVzZWQgdG8gZ2V0IHRoZSBmaWx0ZXIgaW5kZXggZnJvbSB3aGVuIHtAY29kZSBpc0xvZ2dhYmxlfSBhbmQKKyAgICAgKiB7QGNvZGUgaXNBdHRhY2htZW50TG9nZ2FibGV9IHdhcyBpbnZva2VkIGJ5IHtAY29kZSBwdWJsaXNofSBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBmaWx0ZXIgaW5kZXggb3IgTVVURVhfUFVCTElTSCBpZiB1bmtub3duLgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjUuNQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdHJ5TXV0ZXggd2FzIG5vdCBjYWxsZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgZ2V0TWF0Y2hlZFBhcnQoKSB7CisgICAgICAgIC8vYXNzZXJ0IFRocmVhZC5ob2xkc0xvY2sodGhpcyk7CisgICAgICAgIEludGVnZXIgaWR4ID0gTVVURVguZ2V0KCk7CisgICAgICAgIGlmIChpZHggPT0gbnVsbCB8fCBpZHggPj0gcmVhZE9ubHlBdHRhY2htZW50RmlsdGVycygpLmxlbmd0aCkgeworICAgICAgICAgICBpZHggPSBNVVRFWF9QVUJMSVNIOworICAgICAgICB9CisgICAgICAgIHJldHVybiBpZHg7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBpcyB1c2VkIHRvIHJlY29yZCB0aGUgZmlsdGVyIGluZGV4IHdoZW4ge0Bjb2RlIGlzTG9nZ2FibGV9IGFuZAorICAgICAqIHtAY29kZSBpc0F0dGFjaG1lbnRMb2dnYWJsZX0gd2FzIGludm9rZWQgYnkge0Bjb2RlIHB1Ymxpc2h9IG1ldGhvZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbmRleCB0aGUgZmlsdGVyIGluZGV4LgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjUuNQorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBzZXRNYXRjaGVkUGFydChpbnQgaW5kZXgpIHsKKyAgICAgICAgaWYgKE1VVEVYX1BVQkxJU0guZXF1YWxzKE1VVEVYLmdldCgpKSkgeworICAgICAgICAgICBNVVRFWC5zZXQoaW5kZXgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xlYXIgcHJldmlvdXMgbWF0Y2hlcyB3aGVuIHRoZSBmaWx0ZXJzIGFyZSBtb2RpZmllZCBhbmQgdGhlcmUgYXJlCisgICAgICogZXhpc3RpbmcgbG9nIHJlY29yZHMgdGhhdCB3ZXJlIG1hdGNoZWQuCisgICAgICogQHBhcmFtIGluZGV4IHRoZSBsb3dlc3QgZmlsdGVyIGluZGV4IHRvIGNsZWFyLgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjUuNQorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBjbGVhck1hdGNoZXMoaW50IGluZGV4KSB7CisgICAgICAgIGFzc2VydCBUaHJlYWQuaG9sZHNMb2NrKHRoaXMpOworICAgICAgICBmb3IgKGludCByID0gMDsgciA8IHNpemU7ICsrcikgeworICAgICAgICAgICAgaWYgKG1hdGNoZWRbcl0gPj0gaW5kZXgpIHsKKyAgICAgICAgICAgICAgICBtYXRjaGVkW3JdID0gTVVURVhfUFVCTElTSDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEEgY2FsbGJhY2sgbWV0aG9kIGZvciB3aGVuIHRoaXMgb2JqZWN0IGlzIGFib3V0IHRvIGJlIHBsYWNlZCBpbnRvCisgICAgICogY29tbWlzc2lvbi4gVGhpcyBjb250cmFjdCBpcyBkZWZpbmVkIGJ5IHRoZQorICAgICAqIHtAY29kZSBvcmcuZ2xhc3NmaXNoLmhrMi5hcGkuUG9zdENvbnN0cnVjdH0gaW50ZXJmYWNlLiBJZiB0aGlzIGNsYXNzIGlzCisgICAgICogbG9hZGVkIHZpYSBhIGxpZmVjeWNsZSBtYW5hZ2VkIGVudmlyb25tZW50IG90aGVyIHRoYW4gSEsyIHRoZW4gaXQgaXMKKyAgICAgKiByZWNvbW1lbmRlZCB0aGF0IHRoaXMgbWV0aG9kIGlzIGNhbGxlZCBlaXRoZXIgZGlyZWN0bHkgb3IgdGhyb3VnaAorICAgICAqIGV4dGVuZGluZyB0aGlzIGNsYXNzIHRvIHNpZ25hbCB0aGF0IHRoaXMgb2JqZWN0IGlzIHJlYWR5IGZvciB1c2UuCisgICAgICoKKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS41LjMKKyAgICAgKi8KKyAgICAvL0BqYXZheC5hbm5vdGF0aW9uLlBvc3RDb25zdHJ1Y3QKKyAgICBwdWJsaWMgdm9pZCBwb3N0Q29uc3RydWN0KCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIEEgY2FsbGJhY2sgbWV0aG9kIGZvciB3aGVuIHRoaXMgb2JqZWN0IGlzIGFib3V0IHRvIGJlIGRlY29tbWlzc2lvbmVkLgorICAgICAqIFRoaXMgY29udHJhY3QgaXMgZGVmaW5lZCBieSB0aGUge0Bjb2RlIG9yZy5nbGFzc2Zpc2guaGsyLmFwaS5QcmVEZXN0b3J5fQorICAgICAqIGludGVyZmFjZS4gSWYgdGhpcyBjbGFzcyBpcyBsb2FkZWQgdmlhIGEgbGlmZWN5Y2xlIG1hbmFnZWQgZW52aXJvbm1lbnQKKyAgICAgKiBvdGhlciB0aGFuIEhLMiB0aGVuIGl0IGlzIHJlY29tbWVuZGVkIHRoYXQgdGhpcyBtZXRob2QgaXMgY2FsbGVkIGVpdGhlcgorICAgICAqIGRpcmVjdGx5IG9yIHRocm91Z2ggZXh0ZW5kaW5nIHRoaXMgY2xhc3MgdG8gc2lnbmFsIHRoYXQgdGhpcyBvYmplY3Qgd2lsbAorICAgICAqIGJlIGRlc3Ryb3llZC4KKyAgICAgKgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjUuMworICAgICAqLworICAgIC8vQGphdmF4LmFubm90YXRpb24uUHJlRGVzdHJveQorICAgIHB1YmxpYyB2b2lkIHByZURlc3Ryb3koKSB7CisgICAgICAgIC8qKgorICAgICAgICAgKiBDbG9zZSBjYW4gcmVxdWlyZSBwZXJtaXNzaW9ucyBzbyBqdXN0IHRyaWdnZXIgYSBwdXNoLgorICAgICAgICAgKi8KKyAgICAgICAgcHVzaChmYWxzZSwgRXJyb3JNYW5hZ2VyLkNMT1NFX0ZBSUxVUkUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFB1c2hlcyBhbnkgYnVmZmVyZWQgcmVjb3JkcyB0byB0aGUgZW1haWwgc2VydmVyIGFzIGhpZ2ggaW1wb3J0YW5jZSB3aXRoCisgICAgICogdXJnZW50IHByaW9yaXR5LiAgVGhlIGludGVybmFsIGJ1ZmZlciBpcyB0aGVuIGNsZWFyZWQuICBEb2VzIG5vdGhpbmcgaWYKKyAgICAgKiBjYWxsZWQgZnJvbSBpbnNpZGUgYSBwdXNoLgorICAgICAqIEBzZWUgI2ZsdXNoKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwdXNoKCkgeworICAgICAgICBwdXNoKHRydWUsIEVycm9yTWFuYWdlci5GTFVTSF9GQUlMVVJFKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQdXNoZXMgYW55IGJ1ZmZlcmVkIHJlY29yZHMgdG8gdGhlIGVtYWlsIHNlcnZlciBhcyBub3JtYWwgcHJpb3JpdHkuCisgICAgICogVGhlIGludGVybmFsIGJ1ZmZlciBpcyB0aGVuIGNsZWFyZWQuICBEb2VzIG5vdGhpbmcgaWYgY2FsbGVkIGZyb20gaW5zaWRlCisgICAgICogYSBwdXNoLgorICAgICAqIEBzZWUgI3B1c2goKQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGZsdXNoKCkgeworICAgICAgICBwdXNoKGZhbHNlLCBFcnJvck1hbmFnZXIuRkxVU0hfRkFJTFVSRSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJldmVudHMgYW55IG90aGVyIHJlY29yZHMgZnJvbSBiZWluZyBwdWJsaXNoZWQuCisgICAgICogUHVzaGVzIGFueSBidWZmZXJlZCByZWNvcmRzIHRvIHRoZSBlbWFpbCBzZXJ2ZXIgYXMgbm9ybWFsIHByaW9yaXR5LgorICAgICAqIFRoZSBpbnRlcm5hbCBidWZmZXIgaXMgdGhlbiBjbGVhcmVkLiAgT25jZSB0aGlzIGhhbmRsZXIgaXMgY2xvc2VkIGl0CisgICAgICogd2lsbCByZW1haW4gY2xvc2VkLgorICAgICAqIDxwPgorICAgICAqIElmIHRoaXMgPHR0PkhhbmRsZXI8L3R0PiBpcyBvbmx5IGltcGxpY2l0bHkgY2xvc2VkIGJ5IHRoZQorICAgICAqIDx0dD5Mb2dNYW5hZ2VyPC90dD4sIHRoZW4gPGEgaHJlZj0iI3ZlcmlmeSI+dmVyaWZpY2F0aW9uPC9hPiBzaG91bGQgYmUKKyAgICAgKiB0dXJuZWQgb24uCisgICAgICogQHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbiAgaWYgYSBzZWN1cml0eSBtYW5hZ2VyIGV4aXN0cyBhbmQgdGhlCisgICAgICogY2FsbGVyIGRvZXMgbm90IGhhdmUgPHR0PkxvZ2dpbmdQZXJtaXNzaW9uKCJjb250cm9sIik8L3R0Pi4KKyAgICAgKiBAc2VlICNmbHVzaCgpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjaGVja0FjY2VzcygpOyAvL0Vuc3VyZSBzZXRMZXZlbCB3b3JrcyBiZWZvcmUgY2xlYXJpbmcgdGhlIGJ1ZmZlci4KKyAgICAgICAgICAgIE1lc3NhZ2UgbXNnID0gbnVsbDsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAodGhpcykgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIG1zZyA9IHdyaXRlTG9nUmVjb3JkcyhFcnJvck1hbmFnZXIuQ0xPU0VfRkFJTFVSRSk7CisgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsgIC8vQ2hhbmdlIGxldmVsIGFmdGVyIGZvcm1hdHRpbmcuCisgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nTGV2ZWwgPSBMZXZlbC5PRkY7CisgICAgICAgICAgICAgICAgICAgIC8qKgorICAgICAgICAgICAgICAgICAgICAgKiBUaGUgc2lnbiBiaXQgb2YgdGhlIGNhcGFjaXR5IGlzIHNldCB0byBlbnN1cmUgdGhhdAorICAgICAgICAgICAgICAgICAgICAgKiByZWNvcmRzIHRoYXQgaGF2ZSBwYXNzZWQgaXNMb2dnYWJsZSwgYnV0IGhhdmUgeWV0IHRvIGJlCisgICAgICAgICAgICAgICAgICAgICAqIGFkZGVkIHRvIHRoZSBpbnRlcm5hbCBidWZmZXIsIGFyZSBpbW1lZGlhdGVseSBwdXNoZWQgYXMKKyAgICAgICAgICAgICAgICAgICAgICogYW4gZW1haWwuCisgICAgICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5jYXBhY2l0eSA+IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2FwYWNpdHkgPSAtdGhpcy5jYXBhY2l0eTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIC8vRW5zdXJlIG5vdCBpbnNpZGUgYSBwdXNoLgorICAgICAgICAgICAgICAgICAgICBpZiAoc2l6ZSA9PSAwICYmIGRhdGEubGVuZ3RoICE9IDEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZGF0YSA9IG5ldyBMb2dSZWNvcmRbMV07CisgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1hdGNoZWQgPSBuZXcgaW50W3RoaXMuZGF0YS5sZW5ndGhdOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAobXNnICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBzZW5kKG1zZywgZmFsc2UsIEVycm9yTWFuYWdlci5DTE9TRV9GQUlMVVJFKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoZmluYWwgTGlua2FnZUVycm9yIEpESzgxNTI1MTUpIHsKKyAgICAgICAgICAgIHJlcG9ydExpbmthZ2VFcnJvcihKREs4MTUyNTE1LCBFcnJvck1hbmFnZXIuQ0xPU0VfRkFJTFVSRSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIGxvZyBsZXZlbCBzcGVjaWZ5aW5nIHdoaWNoIG1lc3NhZ2UgbGV2ZWxzIHdpbGwgYmUKKyAgICAgKiBsb2dnZWQgYnkgdGhpcyA8dHQ+SGFuZGxlcjwvdHQ+LiAgTWVzc2FnZSBsZXZlbHMgbG93ZXIgdGhhbiB0aGlzCisgICAgICogdmFsdWUgd2lsbCBiZSBkaXNjYXJkZWQuCisgICAgICogQHBhcmFtIG5ld0xldmVsICAgdGhlIG5ldyB2YWx1ZSBmb3IgdGhlIGxvZyBsZXZlbAorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPHR0Pm5ld0xldmVsPC90dD4gaXMgPHR0Pm51bGw8L3R0Pi4KKyAgICAgKiBAdGhyb3dzIFNlY3VyaXR5RXhjZXB0aW9uICBpZiBhIHNlY3VyaXR5IG1hbmFnZXIgZXhpc3RzIGFuZAorICAgICAqICAgICAgICAgIHRoZSBjYWxsZXIgZG9lcyBub3QgaGF2ZSA8dHQ+TG9nZ2luZ1Blcm1pc3Npb24oImNvbnRyb2wiKTwvdHQ+LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldExldmVsKGZpbmFsIExldmVsIG5ld0xldmVsKSB7CisgICAgICAgIGlmIChuZXdMZXZlbCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICBjaGVja0FjY2VzcygpOworCisgICAgICAgIC8vRG9uJ3QgYWxsb3cgYSBjbG9zZWQgaGFuZGxlciB0byBiZSBvcGVuZWQgKGhhbGYgd2F5KS4KKyAgICAgICAgc3luY2hyb25pemVkICh0aGlzKSB7IC8vV2FpdCBmb3Igd3JpdGVMb2dSZWNvcmRzLgorICAgICAgICAgICAgaWYgKHRoaXMuY2FwYWNpdHkgPiAwKSB7CisgICAgICAgICAgICAgICAgdGhpcy5sb2dMZXZlbCA9IG5ld0xldmVsOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBsb2cgbGV2ZWwgc3BlY2lmeWluZyB3aGljaCBtZXNzYWdlcyB3aWxsIGJlIGxvZ2dlZCBieSB0aGlzCisgICAgICogPHR0PkhhbmRsZXI8L3R0Pi4gIE1lc3NhZ2UgbGV2ZWxzIGxvd2VyIHRoYW4gdGhpcyBsZXZlbCB3aWxsIGJlCisgICAgICogZGlzY2FyZGVkLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgbGV2ZWwgb2YgbWVzc2FnZXMgYmVpbmcgbG9nZ2VkLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBMZXZlbCBnZXRMZXZlbCgpIHsKKyAgICAgICAgcmV0dXJuIGxvZ0xldmVsOyAvL1ZvbGF0aWxlIGFjY2Vzcy4KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZXMgdGhlIEVycm9yTWFuYWdlciBmb3IgdGhpcyBIYW5kbGVyLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgRXJyb3JNYW5hZ2VyIGZvciB0aGlzIEhhbmRsZXIKKyAgICAgKiBAdGhyb3dzIFNlY3VyaXR5RXhjZXB0aW9uIGlmIGEgc2VjdXJpdHkgbWFuYWdlciBleGlzdHMgYW5kIGlmIHRoZSBjYWxsZXIKKyAgICAgKiBkb2VzIG5vdCBoYXZlIDx0dD5Mb2dnaW5nUGVybWlzc2lvbigiY29udHJvbCIpPC90dD4uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEVycm9yTWFuYWdlciBnZXRFcnJvck1hbmFnZXIoKSB7CisgICAgICAgIGNoZWNrQWNjZXNzKCk7CisgICAgICAgIHJldHVybiB0aGlzLmVycm9yTWFuYWdlcjsgLy9Wb2xhdGlsZSBhY2Nlc3MuCisgICAgfQorCisgICAgLyoqCisgICAgICogRGVmaW5lIGFuIEVycm9yTWFuYWdlciBmb3IgdGhpcyBIYW5kbGVyLgorICAgICAqIDxwPgorICAgICAqIFRoZSBFcnJvck1hbmFnZXIncyAiZXJyb3IiIG1ldGhvZCB3aWxsIGJlIGludm9rZWQgaWYgYW55IGVycm9ycyBvY2N1cgorICAgICAqIHdoaWxlIHVzaW5nIHRoaXMgSGFuZGxlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlbSAgdGhlIG5ldyBFcnJvck1hbmFnZXIKKyAgICAgKiBAdGhyb3dzICBTZWN1cml0eUV4Y2VwdGlvbiAgaWYgYSBzZWN1cml0eSBtYW5hZ2VyIGV4aXN0cyBhbmQgaWYgdGhlCisgICAgICogY2FsbGVyIGRvZXMgbm90IGhhdmUgPHR0PkxvZ2dpbmdQZXJtaXNzaW9uKCJjb250cm9sIik8L3R0Pi4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBnaXZlbiBlcnJvciBtYW5hZ2VyIGlzIG51bGwuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0RXJyb3JNYW5hZ2VyKGZpbmFsIEVycm9yTWFuYWdlciBlbSkgeworICAgICAgICBjaGVja0FjY2VzcygpOworICAgICAgICBzZXRFcnJvck1hbmFnZXIwKGVtKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBlcnJvciBtYW5hZ2VyIG9uIHRoaXMgaGFuZGxlciBhbmQgdGhlIHN1cGVyIGhhbmRsZXIuICBJbiBzZWN1cmUKKyAgICAgKiBlbnZpcm9ubWVudHMgdGhlIHN1cGVyIGNhbGwgbWF5IG5vdCBiZSBhbGxvd2VkIHdoaWNoIGlzIG5vdCBhIGZhaWx1cmUKKyAgICAgKiBjb25kaXRpb24gYXMgaXQgaXMgYW4gYXR0ZW1wdCB0byBmcmVlIHRoZSB1bnVzZWQgaGFuZGxlciBlcnJvciBtYW5hZ2VyLgorICAgICAqCisgICAgICogQHBhcmFtIGVtIGEgbm9uIG51bGwgZXJyb3IgbWFuYWdlci4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBnaXZlbiBlcnJvciBtYW5hZ2VyIGlzIG51bGwuCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNS42CisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHNldEVycm9yTWFuYWdlcjAoZmluYWwgRXJyb3JNYW5hZ2VyIGVtKSB7CisgICAgICAgIGlmIChlbSA9PSBudWxsKSB7CisgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsgLy9XYWl0IGZvciB3cml0ZUxvZ1JlY29yZHMuCisgICAgICAgICAgICAgICB0aGlzLmVycm9yTWFuYWdlciA9IGVtOworICAgICAgICAgICAgICAgc3VwZXIuc2V0RXJyb3JNYW5hZ2VyKGVtKTsgLy9UcnkgdG8gZnJlZSBzdXBlciBlcnJvciBtYW5hZ2VyLgorICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHwgTGlua2FnZUVycm9yIGlnbm9yZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBjdXJyZW50IDx0dD5GaWx0ZXI8L3R0PiBmb3IgdGhpcyA8dHQ+SGFuZGxlcjwvdHQ+LgorICAgICAqCisgICAgICogQHJldHVybiAgYSA8dHQ+RmlsdGVyPC90dD4gb2JqZWN0IChtYXkgYmUgbnVsbCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRmlsdGVyIGdldEZpbHRlcigpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMuZmlsdGVyOyAvL1ZvbGF0aWxlIGFjY2Vzcy4KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgYSA8dHQ+RmlsdGVyPC90dD4gdG8gY29udHJvbCBvdXRwdXQgb24gdGhpcyA8dHQ+SGFuZGxlcjwvdHQ+LgorICAgICAqIDxQPgorICAgICAqIEZvciBlYWNoIGNhbGwgb2YgPHR0PnB1Ymxpc2g8L3R0PiB0aGUgPHR0PkhhbmRsZXI8L3R0PiB3aWxsIGNhbGwgdGhpcworICAgICAqIDx0dD5GaWx0ZXI8L3R0PiAoaWYgaXQgaXMgbm9uLW51bGwpIHRvIGNoZWNrIGlmIHRoZSA8dHQ+TG9nUmVjb3JkPC90dD4KKyAgICAgKiBzaG91bGQgYmUgcHVibGlzaGVkIG9yIGRpc2NhcmRlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuZXdGaWx0ZXIgIGEgPHR0PkZpbHRlcjwvdHQ+IG9iamVjdCAobWF5IGJlIG51bGwpCisgICAgICogQHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbiAgaWYgYSBzZWN1cml0eSBtYW5hZ2VyIGV4aXN0cyBhbmQgaWYgdGhlIGNhbGxlcgorICAgICAqIGRvZXMgbm90IGhhdmUgPHR0PkxvZ2dpbmdQZXJtaXNzaW9uKCJjb250cm9sIik8L3R0Pi4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRGaWx0ZXIoZmluYWwgRmlsdGVyIG5ld0ZpbHRlcikgeworICAgICAgICBjaGVja0FjY2VzcygpOworICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsgIC8vV2FpdCBmb3Igd3JpdGVMb2dSZWNvcmRzLgorICAgICAgICAgICAgaWYgKG5ld0ZpbHRlciAhPSBmaWx0ZXIpIHsKKyAgICAgICAgICAgICAgICBjbGVhck1hdGNoZXMoLTEpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhpcy5maWx0ZXIgPSBuZXdGaWx0ZXI7IC8vVm9sYXRpbGUgYWNjZXNzLgorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBjaGFyYWN0ZXIgZW5jb2RpbmcgZm9yIHRoaXMgPHR0PkhhbmRsZXI8L3R0Pi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gIFRoZSBlbmNvZGluZyBuYW1lLiAgTWF5IGJlIG51bGwsIHdoaWNoIGluZGljYXRlcyB0aGUgZGVmYXVsdAorICAgICAqIGVuY29kaW5nIHNob3VsZCBiZSB1c2VkLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgU3RyaW5nIGdldEVuY29kaW5nKCkgeworICAgICAgICByZXR1cm4gdGhpcy5lbmNvZGluZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIGNoYXJhY3RlciBlbmNvZGluZyB1c2VkIGJ5IHRoaXMgPHR0PkhhbmRsZXI8L3R0Pi4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgZW5jb2Rpbmcgc2hvdWxkIGJlIHNldCBiZWZvcmUgYW55IDx0dD5Mb2dSZWNvcmRzPC90dD4gYXJlIHdyaXR0ZW4KKyAgICAgKiB0byB0aGUgPHR0PkhhbmRsZXI8L3R0Pi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlbmNvZGluZyAgVGhlIG5hbWUgb2YgYSBzdXBwb3J0ZWQgY2hhcmFjdGVyIGVuY29kaW5nLiAgTWF5IGJlCisgICAgICogbnVsbCwgdG8gaW5kaWNhdGUgdGhlIGRlZmF1bHQgcGxhdGZvcm0gZW5jb2RpbmcuCisgICAgICogQHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbiAgaWYgYSBzZWN1cml0eSBtYW5hZ2VyIGV4aXN0cyBhbmQgaWYgdGhlIGNhbGxlcgorICAgICAqIGRvZXMgbm90IGhhdmUgPHR0PkxvZ2dpbmdQZXJtaXNzaW9uKCJjb250cm9sIik8L3R0Pi4KKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gaWYgdGhlIG5hbWVkIGVuY29kaW5nIGlzIG5vdAorICAgICAqIHN1cHBvcnRlZC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRFbmNvZGluZyhTdHJpbmcgZW5jb2RpbmcpIHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tBY2Nlc3MoKTsKKyAgICAgICAgc2V0RW5jb2RpbmcwKGVuY29kaW5nKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIGNoYXJhY3RlciBlbmNvZGluZyB1c2VkIGJ5IHRoaXMgaGFuZGxlci4gIFRoaXMgbWV0aG9kIGRvZXMgbm90CisgICAgICogY2hlY2sgcGVybWlzc2lvbnMgb2YgdGhlIGNhbGxlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBlIGFueSBlbmNvZGluZyBuYW1lIG9yIG51bGwgZm9yIHRoZSBkZWZhdWx0LgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBpZiB0aGUgZ2l2ZW4gZW5jb2RpbmcgaXMgbm90IHN1cHBvcnRlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgc2V0RW5jb2RpbmcwKFN0cmluZyBlKSB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChlICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaWYgKCFqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXQuaXNTdXBwb3J0ZWQoZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24oZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoamF2YS5uaW8uY2hhcnNldC5JbGxlZ2FsQ2hhcnNldE5hbWVFeGNlcHRpb24gaWNuZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uKGUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgc3luY2hyb25pemVkICh0aGlzKSB7ICAvL1dhaXQgZm9yIHdyaXRlTG9nUmVjb3Jkcy4KKyAgICAgICAgICAgIHRoaXMuZW5jb2RpbmcgPSBlOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSA8dHQ+Rm9ybWF0dGVyPC90dD4gZm9yIHRoaXMgPHR0PkhhbmRsZXI8L3R0Pi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIDx0dD5Gb3JtYXR0ZXI8L3R0PiAobWF5IGJlIG51bGwpLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgRm9ybWF0dGVyIGdldEZvcm1hdHRlcigpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMuZm9ybWF0dGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCBhIDx0dD5Gb3JtYXR0ZXI8L3R0Pi4gIFRoaXMgPHR0PkZvcm1hdHRlcjwvdHQ+IHdpbGwgYmUgdXNlZCB0byBmb3JtYXQKKyAgICAgKiA8dHQ+TG9nUmVjb3JkczwvdHQ+IGZvciB0aGlzIDx0dD5IYW5kbGVyPC90dD4uCisgICAgICogPHA+CisgICAgICogU29tZSA8dHQ+SGFuZGxlcnM8L3R0PiBtYXkgbm90IHVzZSA8dHQ+Rm9ybWF0dGVyczwvdHQ+LCBpbiB3aGljaCBjYXNlIHRoZQorICAgICAqIDx0dD5Gb3JtYXR0ZXI8L3R0PiB3aWxsIGJlIHJlbWVtYmVyZWQsIGJ1dCBub3QgdXNlZC4KKyAgICAgKiA8cD4KKyAgICAgKiBAcGFyYW0gbmV3Rm9ybWF0dGVyIHRoZSA8dHQ+Rm9ybWF0dGVyPC90dD4gdG8gdXNlIChtYXkgbm90IGJlIG51bGwpCisgICAgICogQHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbiAgaWYgYSBzZWN1cml0eSBtYW5hZ2VyIGV4aXN0cyBhbmQgaWYgdGhlIGNhbGxlcgorICAgICAqIGRvZXMgbm90IGhhdmUgPHR0PkxvZ2dpbmdQZXJtaXNzaW9uKCJjb250cm9sIik8L3R0Pi4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBnaXZlbiBmb3JtYXR0ZXIgaXMgbnVsbC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgc2V0Rm9ybWF0dGVyKEZvcm1hdHRlciBuZXdGb3JtYXR0ZXIpIHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbiB7CisgICAgICAgIGNoZWNrQWNjZXNzKCk7CisgICAgICAgIGlmIChuZXdGb3JtYXR0ZXIgPT0gbnVsbCkgeworICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmZvcm1hdHRlciA9IG5ld0Zvcm1hdHRlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBwdXNoIGxldmVsLiAgVGhlIGRlZmF1bHQgaXMgPHR0PkxldmVsLk9GRjwvdHQ+IG1lYW5pbmcgdGhhdAorICAgICAqIHRoaXMgPHR0PkhhbmRsZXI8L3R0PiB3aWxsIG9ubHkgcHVzaCB3aGVuIHRoZSBpbnRlcm5hbCBidWZmZXIgaXMgZnVsbC4KKyAgICAgKiBAcmV0dXJuIHRoZSBwdXNoIGxldmVsLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBzeW5jaHJvbml6ZWQgTGV2ZWwgZ2V0UHVzaExldmVsKCkgeworICAgICAgICByZXR1cm4gdGhpcy5wdXNoTGV2ZWw7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgcHVzaCBsZXZlbC4gIFRoaXMgbGV2ZWwgaXMgdXNlZCB0byB0cmlnZ2VyIGEgcHVzaCBzbyB0aGF0CisgICAgICogYWxsIHBlbmRpbmcgcmVjb3JkcyBhcmUgZm9ybWF0dGVkIGFuZCBzZW50IHRvIHRoZSBlbWFpbCBzZXJ2ZXIuICBXaGVuCisgICAgICogdGhlIHB1c2ggbGV2ZWwgdHJpZ2dlcnMgYSBzZW5kLCB0aGUgcmVzdWx0aW5nIGVtYWlsIGlzIGZsYWdnZWQgYXMKKyAgICAgKiBoaWdoIGltcG9ydGFuY2Ugd2l0aCB1cmdlbnQgcHJpb3JpdHkuCisgICAgICogQHBhcmFtIGxldmVsIExldmVsIG9iamVjdC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDx0dD5sZXZlbDwvdHQ+IGlzIDx0dD5udWxsPC90dD4uCisgICAgICogQHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbiAgaWYgYSBzZWN1cml0eSBtYW5hZ2VyIGV4aXN0cyBhbmQgdGhlCisgICAgICogY2FsbGVyIGRvZXMgbm90IGhhdmUgPHR0PkxvZ2dpbmdQZXJtaXNzaW9uKCJjb250cm9sIik8L3R0Pi4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiBjYWxsZWQgZnJvbSBpbnNpZGUgYSBwdXNoLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBzeW5jaHJvbml6ZWQgdm9pZCBzZXRQdXNoTGV2ZWwoZmluYWwgTGV2ZWwgbGV2ZWwpIHsKKyAgICAgICAgY2hlY2tBY2Nlc3MoKTsKKyAgICAgICAgaWYgKGxldmVsID09IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGlzV3JpdGluZykgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHRoaXMucHVzaExldmVsID0gbGV2ZWw7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgcHVzaCBmaWx0ZXIuICBUaGUgZGVmYXVsdCBpcyA8dHQ+bnVsbDwvdHQ+LgorICAgICAqIEByZXR1cm4gdGhlIHB1c2ggZmlsdGVyIG9yIDx0dD5udWxsPC90dD4uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHN5bmNocm9uaXplZCBGaWx0ZXIgZ2V0UHVzaEZpbHRlcigpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMucHVzaEZpbHRlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBwdXNoIGZpbHRlci4gIFRoaXMgZmlsdGVyIGlzIG9ubHkgY2FsbGVkIGlmIHRoZSBnaXZlbgorICAgICAqIDx0dD5Mb2dSZWNvcmQ8L3R0PiBsZXZlbCB3YXMgZ3JlYXRlciB0aGFuIHRoZSBwdXNoIGxldmVsLiAgSWYgdGhpcworICAgICAqIGZpbHRlciByZXR1cm5zIDx0dD50cnVlPC90dD4sIGFsbCBwZW5kaW5nIHJlY29yZHMgYXJlIGZvcm1hdHRlZCBhbmQgc2VudAorICAgICAqIHRvIHRoZSBlbWFpbCBzZXJ2ZXIuICBXaGVuIHRoZSBwdXNoIGZpbHRlciB0cmlnZ2VycyBhIHNlbmQsIHRoZSByZXN1bHRpbmcKKyAgICAgKiBlbWFpbCBpcyBmbGFnZ2VkIGFzIGhpZ2ggaW1wb3J0YW5jZSB3aXRoIHVyZ2VudCBwcmlvcml0eS4KKyAgICAgKiBAcGFyYW0gZmlsdGVyIHB1c2ggZmlsdGVyIG9yIDx0dD5udWxsPC90dD4KKyAgICAgKiBAdGhyb3dzIFNlY3VyaXR5RXhjZXB0aW9uICBpZiBhIHNlY3VyaXR5IG1hbmFnZXIgZXhpc3RzIGFuZCB0aGUKKyAgICAgKiBjYWxsZXIgZG9lcyBub3QgaGF2ZSA8dHQ+TG9nZ2luZ1Blcm1pc3Npb24oImNvbnRyb2wiKTwvdHQ+LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIGNhbGxlZCBmcm9tIGluc2lkZSBhIHB1c2guCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHN5bmNocm9uaXplZCB2b2lkIHNldFB1c2hGaWx0ZXIoZmluYWwgRmlsdGVyIGZpbHRlcikgeworICAgICAgICBjaGVja0FjY2VzcygpOworICAgICAgICBpZiAoaXNXcml0aW5nKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5wdXNoRmlsdGVyID0gZmlsdGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGNvbXBhcmF0b3IgdXNlZCB0byBvcmRlciBhbGwgPHR0PkxvZ1JlY29yZDwvdHQ+IG9iamVjdHMgcHJpb3IKKyAgICAgKiB0byBmb3JtYXR0aW5nLiAgSWYgPHR0Pm51bGw8L3R0PiB0aGVuIHRoZSBvcmRlciBpcyB1bnNwZWNpZmllZC4KKyAgICAgKiBAcmV0dXJuIHRoZSA8dHQ+TG9nUmVjb3JkPC90dD4gY29tcGFyYXRvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgc3luY2hyb25pemVkIENvbXBhcmF0b3I8PyBzdXBlciBMb2dSZWNvcmQ+IGdldENvbXBhcmF0b3IoKSB7CisgICAgICAgIHJldHVybiB0aGlzLmNvbXBhcmF0b3I7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgY29tcGFyYXRvciB1c2VkIHRvIG9yZGVyIGFsbCA8dHQ+TG9nUmVjb3JkPC90dD4gb2JqZWN0cyBwcmlvcgorICAgICAqIHRvIGZvcm1hdHRpbmcuICBJZiA8dHQ+bnVsbDwvdHQ+IHRoZW4gdGhlIG9yZGVyIGlzIHVuc3BlY2lmaWVkLgorICAgICAqIEBwYXJhbSBjIHRoZSA8dHQ+TG9nUmVjb3JkPC90dD4gY29tcGFyYXRvci4KKyAgICAgKiBAdGhyb3dzIFNlY3VyaXR5RXhjZXB0aW9uICBpZiBhIHNlY3VyaXR5IG1hbmFnZXIgZXhpc3RzIGFuZCB0aGUKKyAgICAgKiBjYWxsZXIgZG9lcyBub3QgaGF2ZSA8dHQ+TG9nZ2luZ1Blcm1pc3Npb24oImNvbnRyb2wiKTwvdHQ+LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIGNhbGxlZCBmcm9tIGluc2lkZSBhIHB1c2guCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHN5bmNocm9uaXplZCB2b2lkIHNldENvbXBhcmF0b3IoQ29tcGFyYXRvcjw/IHN1cGVyIExvZ1JlY29yZD4gYykgeworICAgICAgICBjaGVja0FjY2VzcygpOworICAgICAgICBpZiAoaXNXcml0aW5nKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5jb21wYXJhdG9yID0gYzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBudW1iZXIgb2YgbG9nIHJlY29yZHMgdGhlIGludGVybmFsIGJ1ZmZlciBjYW4gaG9sZC4gIFdoZW4KKyAgICAgKiBjYXBhY2l0eSBpcyByZWFjaGVkLCA8dHQ+SGFuZGxlcjwvdHQ+IHdpbGwgZm9ybWF0IGFsbCA8dHQ+TG9nUmVjb3JkPC90dD4KKyAgICAgKiBvYmplY3RzIGludG8gb25lIGVtYWlsIG1lc3NhZ2UuCisgICAgICogQHJldHVybiB0aGUgY2FwYWNpdHkuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHN5bmNocm9uaXplZCBpbnQgZ2V0Q2FwYWNpdHkoKSAgeworICAgICAgICBhc3NlcnQgY2FwYWNpdHkgIT0gSW50ZWdlci5NSU5fVkFMVUUgJiYgY2FwYWNpdHkgIT0gMCA6IGNhcGFjaXR5OworICAgICAgICByZXR1cm4gTWF0aC5hYnMoY2FwYWNpdHkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIDx0dD5BdXRoZW50aWNhdG9yPC90dD4gdXNlZCB0byBsb2dpbiB0byB0aGUgZW1haWwgc2VydmVyLgorICAgICAqIEByZXR1cm4gYW4gPHR0PkF1dGhlbnRpY2F0b3I8L3R0PiBvciA8dHQ+bnVsbDwvdHQ+IGlmIG5vbmUgaXMgcmVxdWlyZWQuCisgICAgICogQHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbiAgaWYgYSBzZWN1cml0eSBtYW5hZ2VyIGV4aXN0cyBhbmQgdGhlCisgICAgICogY2FsbGVyIGRvZXMgbm90IGhhdmUgPHR0PkxvZ2dpbmdQZXJtaXNzaW9uKCJjb250cm9sIik8L3R0Pi4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgc3luY2hyb25pemVkIEF1dGhlbnRpY2F0b3IgZ2V0QXV0aGVudGljYXRvcigpIHsKKyAgICAgICAgY2hlY2tBY2Nlc3MoKTsKKyAgICAgICAgcmV0dXJuIHRoaXMuYXV0aDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSA8dHQ+QXV0aGVudGljYXRvcjwvdHQ+IHVzZWQgdG8gbG9naW4gdG8gdGhlIGVtYWlsIHNlcnZlci4KKyAgICAgKiBAcGFyYW0gYXV0aCBhbiA8dHQ+QXV0aGVudGljYXRvcjwvdHQ+IG9iamVjdCBvciBudWxsIGlmIG5vbmUgaXMgcmVxdWlyZWQuCisgICAgICogQHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbiAgaWYgYSBzZWN1cml0eSBtYW5hZ2VyIGV4aXN0cyBhbmQgdGhlCisgICAgICogY2FsbGVyIGRvZXMgbm90IGhhdmUgPHR0PkxvZ2dpbmdQZXJtaXNzaW9uKCJjb250cm9sIik8L3R0Pi4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiBjYWxsZWQgZnJvbSBpbnNpZGUgYSBwdXNoLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHNldEF1dGhlbnRpY2F0b3IoZmluYWwgQXV0aGVudGljYXRvciBhdXRoKSB7CisgICAgICAgIHRoaXMuc2V0QXV0aGVudGljYXRvcjAoYXV0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgPHR0PkF1dGhlbnRpY2F0b3I8L3R0PiB1c2VkIHRvIGxvZ2luIHRvIHRoZSBlbWFpbCBzZXJ2ZXIuCisgICAgICogQHBhcmFtIHBhc3N3b3JkIGEgcGFzc3dvcmQsIGVtcHR5IGFycmF5IGNhbiBiZSB1c2VkIHRvIG9ubHkgc3VwcGx5IGEKKyAgICAgKiB1c2VyIG5hbWUgc2V0IGJ5IDx0dD5tYWlsLnVzZXI8L3R0PiBwcm9wZXJ0eSwgb3IgbnVsbCBpZiBubyBjcmVkZW50aWFscworICAgICAqIGFyZSByZXF1aXJlZC4KKyAgICAgKiBAdGhyb3dzIFNlY3VyaXR5RXhjZXB0aW9uICBpZiBhIHNlY3VyaXR5IG1hbmFnZXIgZXhpc3RzIGFuZCB0aGUKKyAgICAgKiBjYWxsZXIgZG9lcyBub3QgaGF2ZSA8dHQ+TG9nZ2luZ1Blcm1pc3Npb24oImNvbnRyb2wiKTwvdHQ+LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIGNhbGxlZCBmcm9tIGluc2lkZSBhIHB1c2guCisgICAgICogQHNlZSBTdHJpbmcjdG9DaGFyQXJyYXkoKQorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjQuNgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHNldEF1dGhlbnRpY2F0b3IoZmluYWwgY2hhci4uLiBwYXNzd29yZCkgeworICAgICAgICBpZiAocGFzc3dvcmQgPT0gbnVsbCkgeworICAgICAgICAgICAgc2V0QXV0aGVudGljYXRvcjAoKEF1dGhlbnRpY2F0b3IpIG51bGwpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgc2V0QXV0aGVudGljYXRvcjAoRGVmYXVsdEF1dGhlbnRpY2F0b3Iub2YobmV3IFN0cmluZyhwYXNzd29yZCkpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEEgcHJpdmF0ZSBob29rIHRvIGhhbmRsZSBwb3NzaWJsZSBmdXR1cmUgb3ZlcnJpZGVzLiBTZWUgcHVibGljIG1ldGhvZC4KKyAgICAgKiBAcGFyYW0gYXV0aCBzZWUgcHVibGljIG1ldGhvZC4KKyAgICAgKiBAdGhyb3dzIFNlY3VyaXR5RXhjZXB0aW9uICBpZiBhIHNlY3VyaXR5IG1hbmFnZXIgZXhpc3RzIGFuZCB0aGUKKyAgICAgKiBjYWxsZXIgZG9lcyBub3QgaGF2ZSA8dHQ+TG9nZ2luZ1Blcm1pc3Npb24oImNvbnRyb2wiKTwvdHQ+LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIGNhbGxlZCBmcm9tIGluc2lkZSBhIHB1c2guCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHNldEF1dGhlbnRpY2F0b3IwKGZpbmFsIEF1dGhlbnRpY2F0b3IgYXV0aCkgeworICAgICAgICBjaGVja0FjY2VzcygpOworCisgICAgICAgIFNlc3Npb24gc2V0dGluZ3M7CisgICAgICAgIHN5bmNocm9uaXplZCAodGhpcykgeworICAgICAgICAgICAgaWYgKGlzV3JpdGluZykgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRoaXMuYXV0aCA9IGF1dGg7CisgICAgICAgICAgICBzZXR0aW5ncyA9IHVwZGF0ZVNlc3Npb24oKTsKKyAgICAgICAgfQorICAgICAgICB2ZXJpZnlTZXR0aW5ncyhzZXR0aW5ncyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgbWFpbCBwcm9wZXJ0aWVzIHVzZWQgZm9yIHRoZSBzZXNzaW9uLiAgVGhlIGtleS92YWx1ZSBwYWlycworICAgICAqIGFyZSBkZWZpbmVkIGluIHRoZSA8dHQ+SmF2YSBNYWlsIEFQSTwvdHQ+IGRvY3VtZW50YXRpb24uICBUaGlzCisgICAgICogPHR0PkhhbmRsZXI8L3R0PiB3aWxsIGFsc28gc2VhcmNoIHRoZSA8dHQ+TG9nTWFuYWdlcjwvdHQ+IGZvciBkZWZhdWx0cworICAgICAqIGlmIG5lZWRlZC4KKyAgICAgKiBAcGFyYW0gcHJvcHMgYSBub24gPHR0Pm51bGw8L3R0PiBwcm9wZXJ0aWVzIG9iamVjdC4KKyAgICAgKiBAdGhyb3dzIFNlY3VyaXR5RXhjZXB0aW9uICBpZiBhIHNlY3VyaXR5IG1hbmFnZXIgZXhpc3RzIGFuZCB0aGUKKyAgICAgKiBjYWxsZXIgZG9lcyBub3QgaGF2ZSA8dHQ+TG9nZ2luZ1Blcm1pc3Npb24oImNvbnRyb2wiKTwvdHQ+LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgPHR0PnByb3BzPC90dD4gaXMgPHR0Pm51bGw8L3R0Pi4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiBjYWxsZWQgZnJvbSBpbnNpZGUgYSBwdXNoLgorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHNldE1haWxQcm9wZXJ0aWVzKFByb3BlcnRpZXMgcHJvcHMpIHsKKyAgICAgICAgdGhpcy5zZXRNYWlsUHJvcGVydGllczAocHJvcHMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEEgcHJpdmF0ZSBob29rIHRvIGhhbmRsZSBvdmVycmlkZXMgd2hlbiB0aGUgcHVibGljIG1ldGhvZCBpcyBkZWNsYXJlZAorICAgICAqIG5vbiBmaW5hbC4gU2VlIHB1YmxpYyBtZXRob2QgZm9yIGRldGFpbHMuCisgICAgICogQHBhcmFtIHByb3BzIHNlZSBwdWJsaWMgbWV0aG9kLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBzZXRNYWlsUHJvcGVydGllczAoUHJvcGVydGllcyBwcm9wcykgeworICAgICAgICBjaGVja0FjY2VzcygpOworICAgICAgICBwcm9wcyA9IChQcm9wZXJ0aWVzKSBwcm9wcy5jbG9uZSgpOyAvL0FsbG93IHN1YmNsYXNzLgorICAgICAgICBTZXNzaW9uIHNldHRpbmdzOworICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgIGlmIChpc1dyaXRpbmcpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0aGlzLm1haWxQcm9wcyA9IHByb3BzOworICAgICAgICAgICAgc2V0dGluZ3MgPSB1cGRhdGVTZXNzaW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgdmVyaWZ5U2V0dGluZ3Moc2V0dGluZ3MpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgYSBjb3B5IG9mIHRoZSBtYWlsIHByb3BlcnRpZXMgdXNlZCBmb3IgdGhlIHNlc3Npb24uCisgICAgICogQHJldHVybiBhIG5vbiBudWxsIHByb3BlcnRpZXMgb2JqZWN0LgorICAgICAqIEB0aHJvd3MgU2VjdXJpdHlFeGNlcHRpb24gIGlmIGEgc2VjdXJpdHkgbWFuYWdlciBleGlzdHMgYW5kIHRoZQorICAgICAqIGNhbGxlciBkb2VzIG5vdCBoYXZlIDx0dD5Mb2dnaW5nUGVybWlzc2lvbigiY29udHJvbCIpPC90dD4uCisgICAgICovCisgICAgcHVibGljIGZpbmFsIFByb3BlcnRpZXMgZ2V0TWFpbFByb3BlcnRpZXMoKSB7CisgICAgICAgIGNoZWNrQWNjZXNzKCk7CisgICAgICAgIGZpbmFsIFByb3BlcnRpZXMgcHJvcHM7CisgICAgICAgIHN5bmNocm9uaXplZCAodGhpcykgeworICAgICAgICAgICAgcHJvcHMgPSB0aGlzLm1haWxQcm9wczsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gKFByb3BlcnRpZXMpIHByb3BzLmNsb25lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgYXR0YWNobWVudCBmaWx0ZXJzLiAgSWYgdGhlIGF0dGFjaG1lbnQgZmlsdGVyIGRvZXMgbm90CisgICAgICogYWxsb3cgYW55IDx0dD5Mb2dSZWNvcmQ8L3R0PiB0byBiZSBmb3JtYXR0ZWQsIHRoZSBhdHRhY2htZW50IG1heQorICAgICAqIGJlIG9taXR0ZWQgZnJvbSB0aGUgZW1haWwuCisgICAgICogQHJldHVybiBhIG5vbiBudWxsIGFycmF5IG9mIGF0dGFjaG1lbnQgZmlsdGVycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgRmlsdGVyW10gZ2V0QXR0YWNobWVudEZpbHRlcnMoKSB7CisgICAgICAgIHJldHVybiByZWFkT25seUF0dGFjaG1lbnRGaWx0ZXJzKCkuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBhdHRhY2htZW50IGZpbHRlcnMuCisgICAgICogQHBhcmFtIGZpbHRlcnMgYSBub24gPHR0Pm51bGw8L3R0PiBhcnJheSBvZiBmaWx0ZXJzLiAgQSA8dHQ+bnVsbDwvdHQ+CisgICAgICogaW5kZXggdmFsdWUgaXMgYWxsb3dlZC4gIEEgPHR0Pm51bGw8L3R0PiB2YWx1ZSBtZWFucyB0aGF0IGFsbAorICAgICAqIHJlY29yZHMgYXJlIGFsbG93ZWQgZm9yIHRoZSBhdHRhY2htZW50IGF0IHRoYXQgaW5kZXguCisgICAgICogQHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbiAgaWYgYSBzZWN1cml0eSBtYW5hZ2VyIGV4aXN0cyBhbmQgdGhlCisgICAgICogY2FsbGVyIGRvZXMgbm90IGhhdmUgPHR0PkxvZ2dpbmdQZXJtaXNzaW9uKCJjb250cm9sIik8L3R0Pi4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIDx0dD5maWx0ZXJzPC90dD4gaXMgPHR0Pm51bGw8L3R0PgorICAgICAqIEB0aHJvd3MgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiB0aGUgbnVtYmVyIG9mIGF0dGFjaG1lbnQKKyAgICAgKiBuYW1lIGZvcm1hdHRlcnMgZG8gbm90IG1hdGNoIHRoZSBudW1iZXIgb2YgYXR0YWNobWVudCBmb3JtYXR0ZXJzLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIGNhbGxlZCBmcm9tIGluc2lkZSBhIHB1c2guCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgc2V0QXR0YWNobWVudEZpbHRlcnMoRmlsdGVyLi4uIGZpbHRlcnMpIHsKKyAgICAgICAgY2hlY2tBY2Nlc3MoKTsKKyAgICAgICAgaWYgKGZpbHRlcnMubGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgIGZpbHRlcnMgPSBlbXB0eUZpbHRlckFycmF5KCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmaWx0ZXJzID0gQXJyYXlzLmNvcHlPZihmaWx0ZXJzLCBmaWx0ZXJzLmxlbmd0aCwgRmlsdGVyW10uY2xhc3MpOworICAgICAgICB9CisgICAgICAgIHN5bmNocm9uaXplZCAodGhpcykgeworICAgICAgICAgICAgaWYgKHRoaXMuYXR0YWNobWVudEZvcm1hdHRlcnMubGVuZ3RoICE9IGZpbHRlcnMubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgYXR0YWNobWVudE1pc21hdGNoKHRoaXMuYXR0YWNobWVudEZvcm1hdHRlcnMubGVuZ3RoLCBmaWx0ZXJzLmxlbmd0aCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChpc1dyaXRpbmcpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChzaXplICE9IDApIHsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbHRlcnMubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGZpbHRlcnNbaV0gIT0gYXR0YWNobWVudEZpbHRlcnNbaV0pIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFyTWF0Y2hlcyhpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhpcy5hdHRhY2htZW50RmlsdGVycyA9IGZpbHRlcnM7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBhdHRhY2htZW50IGZvcm1hdHRlcnMuICBUaGlzIDx0dD5IYW5kbGVyPC90dD4gaXMgdXNpbmcKKyAgICAgKiBhdHRhY2htZW50cyBvbmx5IGlmIHRoZSByZXR1cm5lZCBhcnJheSBsZW5ndGggaXMgbm9uIHplcm8uCisgICAgICogQHJldHVybiBhIG5vbiA8dHQ+bnVsbDwvdHQ+IGFycmF5IG9mIGZvcm1hdHRlcnMuCisgICAgICovCisgICAgcHVibGljIGZpbmFsIEZvcm1hdHRlcltdIGdldEF0dGFjaG1lbnRGb3JtYXR0ZXJzKCkgeworICAgICAgICBGb3JtYXR0ZXJbXSBmb3JtYXR0ZXJzOworICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgIGZvcm1hdHRlcnMgPSB0aGlzLmF0dGFjaG1lbnRGb3JtYXR0ZXJzOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmb3JtYXR0ZXJzLmNsb25lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgYXR0YWNobWVudCA8dHQ+Rm9ybWF0dGVyPC90dD4gb2JqZWN0IGZvciB0aGlzIGhhbmRsZXIuCisgICAgICogVGhlIG51bWJlciBvZiBmb3JtYXR0ZXJzIGRldGVybWluZXMgdGhlIG51bWJlciBvZiBhdHRhY2htZW50cyBwZXIKKyAgICAgKiBlbWFpbC4gIFRoaXMgbWV0aG9kIHNob3VsZCBiZSB0aGUgZmlyc3QgYXR0YWNobWVudCBtZXRob2QgY2FsbGVkLgorICAgICAqIFRvIHJlbW92ZSBhbGwgYXR0YWNobWVudHMsIGNhbGwgdGhpcyBtZXRob2Qgd2l0aCBlbXB0eSBhcnJheS4KKyAgICAgKiBAcGFyYW0gZm9ybWF0dGVycyBhIG5vbiBudWxsIGFycmF5IG9mIGZvcm1hdHRlcnMuCisgICAgICogQHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbiAgaWYgYSBzZWN1cml0eSBtYW5hZ2VyIGV4aXN0cyBhbmQgdGhlCisgICAgICogY2FsbGVyIGRvZXMgbm90IGhhdmUgPHR0PkxvZ2dpbmdQZXJtaXNzaW9uKCJjb250cm9sIik8L3R0Pi4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBnaXZlbiBhcnJheSBvciBhbnkgYXJyYXkgaW5kZXggaXMKKyAgICAgKiA8dHQ+bnVsbDwvdHQ+LgorICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIGNhbGxlZCBmcm9tIGluc2lkZSBhIHB1c2guCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgc2V0QXR0YWNobWVudEZvcm1hdHRlcnMoRm9ybWF0dGVyLi4uIGZvcm1hdHRlcnMpIHsKKyAgICAgICAgY2hlY2tBY2Nlc3MoKTsKKyAgICAgICAgaWYgKGZvcm1hdHRlcnMubGVuZ3RoID09IDApIHsgLy9OdWxsIGNoZWNrIGFuZCBsZW5ndGggY2hlY2suCisgICAgICAgICAgICBmb3JtYXR0ZXJzID0gZW1wdHlGb3JtYXR0ZXJBcnJheSgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZm9ybWF0dGVycyA9IEFycmF5cy5jb3B5T2YoZm9ybWF0dGVycywKKyAgICAgICAgICAgICAgICAgICAgZm9ybWF0dGVycy5sZW5ndGgsIEZvcm1hdHRlcltdLmNsYXNzKTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZm9ybWF0dGVycy5sZW5ndGg7ICsraSkgeworICAgICAgICAgICAgICAgIGlmIChmb3JtYXR0ZXJzW2ldID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKGF0SW5kZXhNc2coaSkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHN5bmNocm9uaXplZCAodGhpcykgeworICAgICAgICAgICAgaWYgKGlzV3JpdGluZykgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdGhpcy5hdHRhY2htZW50Rm9ybWF0dGVycyA9IGZvcm1hdHRlcnM7CisgICAgICAgICAgICB0aGlzLmFsaWduQXR0YWNobWVudEZpbHRlcnMoKTsKKyAgICAgICAgICAgIHRoaXMuYWxpZ25BdHRhY2htZW50TmFtZXMoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGF0dGFjaG1lbnQgbmFtZSBmb3JtYXR0ZXJzLgorICAgICAqIElmIHRoZSBhdHRhY2htZW50IG5hbWVzIHdlcmUgc2V0IHVzaW5nIGV4cGxpY2l0IG5hbWVzIHRoZW4KKyAgICAgKiB0aGUgbmFtZXMgY2FuIGJlIHJldHVybmVkIGJ5IGNhbGxpbmcgPHR0PnRvU3RyaW5nPC90dD4gb24gZWFjaAorICAgICAqIGF0dGFjaG1lbnQgbmFtZSBmb3JtYXR0ZXIuCisgICAgICogQHJldHVybiBub24gPHR0Pm51bGw8L3R0PiBhcnJheSBvZiBhdHRhY2htZW50IG5hbWUgZm9ybWF0dGVycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgRm9ybWF0dGVyW10gZ2V0QXR0YWNobWVudE5hbWVzKCkgeworICAgICAgICBmaW5hbCBGb3JtYXR0ZXJbXSBmb3JtYXR0ZXJzOworICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgIGZvcm1hdHRlcnMgPSB0aGlzLmF0dGFjaG1lbnROYW1lczsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZm9ybWF0dGVycy5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGF0dGFjaG1lbnQgZmlsZSBuYW1lIGZvciBlYWNoIGF0dGFjaG1lbnQuICBBbGwgY29udHJvbAorICAgICAqIGNoYXJhY3RlcnMgYXJlIHJlbW92ZWQgZnJvbSB0aGUgYXR0YWNobWVudCBuYW1lcy4KKyAgICAgKiBUaGlzIG1ldGhvZCB3aWxsIGNyZWF0ZSBhIHNldCBvZiBjdXN0b20gZm9ybWF0dGVycy4KKyAgICAgKiBAcGFyYW0gbmFtZXMgYW4gYXJyYXkgb2YgbmFtZXMuCisgICAgICogQHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbiAgaWYgYSBzZWN1cml0eSBtYW5hZ2VyIGV4aXN0cyBhbmQgdGhlCisgICAgICogY2FsbGVyIGRvZXMgbm90IGhhdmUgPHR0PkxvZ2dpbmdQZXJtaXNzaW9uKCJjb250cm9sIik8L3R0Pi4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWYgdGhlIG51bWJlciBvZiBhdHRhY2htZW50CisgICAgICogbmFtZXMgZG8gbm90IG1hdGNoIHRoZSBudW1iZXIgb2YgYXR0YWNobWVudCBmb3JtYXR0ZXJzLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uICBpZiBhbnkgbmFtZSBpcyBlbXB0eS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIGFueSBnaXZlbiBhcnJheSBvciBuYW1lIGlzIDx0dD5udWxsPC90dD4uCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgY2FsbGVkIGZyb20gaW5zaWRlIGEgcHVzaC4KKyAgICAgKiBAc2VlIENoYXJhY3RlciNpc0lTT0NvbnRyb2woY2hhcikKKyAgICAgKiBAc2VlIENoYXJhY3RlciNpc0lTT0NvbnRyb2woaW50KQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHNldEF0dGFjaG1lbnROYW1lcyhmaW5hbCBTdHJpbmcuLi4gbmFtZXMpIHsKKyAgICAgICAgY2hlY2tBY2Nlc3MoKTsKKworICAgICAgICBmaW5hbCBGb3JtYXR0ZXJbXSBmb3JtYXR0ZXJzOworICAgICAgICBpZiAobmFtZXMubGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgIGZvcm1hdHRlcnMgPSBlbXB0eUZvcm1hdHRlckFycmF5KCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmb3JtYXR0ZXJzID0gbmV3IEZvcm1hdHRlcltuYW1lcy5sZW5ndGhdOworICAgICAgICB9CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuYW1lcy5sZW5ndGg7ICsraSkgeworICAgICAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUgPSBuYW1lc1tpXTsKKyAgICAgICAgICAgIGlmIChuYW1lICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBpZiAobmFtZS5sZW5ndGgoKSA+IDApIHsKKyAgICAgICAgICAgICAgICAgICAgZm9ybWF0dGVyc1tpXSA9IFRhaWxOYW1lRm9ybWF0dGVyLm9mKG5hbWUpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oYXRJbmRleE1zZyhpKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oYXRJbmRleE1zZyhpKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgIGlmICh0aGlzLmF0dGFjaG1lbnRGb3JtYXR0ZXJzLmxlbmd0aCAhPSBuYW1lcy5sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBhdHRhY2htZW50TWlzbWF0Y2godGhpcy5hdHRhY2htZW50Rm9ybWF0dGVycy5sZW5ndGgsIG5hbWVzLmxlbmd0aCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChpc1dyaXRpbmcpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0aGlzLmF0dGFjaG1lbnROYW1lcyA9IGZvcm1hdHRlcnM7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBhdHRhY2htZW50IGZpbGUgbmFtZSBmb3JtYXR0ZXJzLiAgVGhlIGZvcm1hdCBtZXRob2Qgb2YgZWFjaAorICAgICAqIGF0dGFjaG1lbnQgZm9ybWF0dGVyIHdpbGwgc2VlIG9ubHkgdGhlIDx0dD5Mb2dSZWNvcmQ8L3R0PiBvYmplY3RzIHRoYXQKKyAgICAgKiBwYXNzZWQgaXRzIGF0dGFjaG1lbnQgZmlsdGVyIGR1cmluZyBmb3JtYXR0aW5nLiBUaGUgZm9ybWF0IG1ldGhvZCB3aWxsCisgICAgICogdHlwaWNhbGx5IHJldHVybiBhbiBlbXB0eSBzdHJpbmcuIEluc3RlYWQgb2YgYmVpbmcgdXNlZCB0byBmb3JtYXQKKyAgICAgKiByZWNvcmRzLCBpdCBpcyB1c2VkIHRvIGdhdGhlciBpbmZvcm1hdGlvbiBhYm91dCB0aGUgY29udGVudHMgb2YgYW4KKyAgICAgKiBhdHRhY2htZW50LiAgVGhlIDx0dD5nZXRUYWlsPC90dD4gbWV0aG9kIHNob3VsZCBiZSB1c2VkIHRvIGNvbnN0cnVjdCB0aGUKKyAgICAgKiBhdHRhY2htZW50IGZpbGUgbmFtZSBhbmQgcmVzZXQgYW55IGZvcm1hdHRlciBjb2xsZWN0ZWQgc3RhdGUuICBBbGwKKyAgICAgKiBjb250cm9sIGNoYXJhY3RlcnMgd2lsbCBiZSByZW1vdmVkIGZyb20gdGhlIG91dHB1dCBvZiB0aGUgZm9ybWF0dGVyLiAgVGhlCisgICAgICogPHR0PnRvU3RyaW5nPC90dD4gbWV0aG9kIG9mIHRoZSBnaXZlbiBmb3JtYXR0ZXIgc2hvdWxkIGJlIG92ZXJyaWRkZW4gdG8KKyAgICAgKiBwcm92aWRlIGEgdXNlZnVsIGF0dGFjaG1lbnQgZmlsZSBuYW1lLCBpZiBwb3NzaWJsZS4KKyAgICAgKiBAcGFyYW0gZm9ybWF0dGVycyBhbmQgYXJyYXkgb2YgYXR0YWNobWVudCBuYW1lIGZvcm1hdHRlcnMuCisgICAgICogQHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbiAgaWYgYSBzZWN1cml0eSBtYW5hZ2VyIGV4aXN0cyBhbmQgdGhlCisgICAgICogY2FsbGVyIGRvZXMgbm90IGhhdmUgPHR0PkxvZ2dpbmdQZXJtaXNzaW9uKCJjb250cm9sIik8L3R0Pi4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWYgdGhlIG51bWJlciBvZiBhdHRhY2htZW50CisgICAgICogbmFtZSBmb3JtYXR0ZXJzIGRvIG5vdCBtYXRjaCB0aGUgbnVtYmVyIG9mIGF0dGFjaG1lbnQgZm9ybWF0dGVycy4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIGFueSBnaXZlbiBhcnJheSBvciBuYW1lIGlzIDx0dD5udWxsPC90dD4uCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgY2FsbGVkIGZyb20gaW5zaWRlIGEgcHVzaC4KKyAgICAgKiBAc2VlIENoYXJhY3RlciNpc0lTT0NvbnRyb2woY2hhcikKKyAgICAgKiBAc2VlIENoYXJhY3RlciNpc0lTT0NvbnRyb2woaW50KQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHNldEF0dGFjaG1lbnROYW1lcyhGb3JtYXR0ZXIuLi4gZm9ybWF0dGVycykgeworICAgICAgICBjaGVja0FjY2VzcygpOworCisgICAgICAgIGlmIChmb3JtYXR0ZXJzLmxlbmd0aCA9PSAwKSB7CisgICAgICAgICAgICBmb3JtYXR0ZXJzID0gZW1wdHlGb3JtYXR0ZXJBcnJheSgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZm9ybWF0dGVycyA9IEFycmF5cy5jb3B5T2YoZm9ybWF0dGVycywgZm9ybWF0dGVycy5sZW5ndGgsCisgICAgICAgICAgICAgICAgICAgIEZvcm1hdHRlcltdLmNsYXNzKTsKKyAgICAgICAgfQorCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZm9ybWF0dGVycy5sZW5ndGg7ICsraSkgeworICAgICAgICAgICAgaWYgKGZvcm1hdHRlcnNbaV0gPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbihhdEluZGV4TXNnKGkpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHN5bmNocm9uaXplZCAodGhpcykgeworICAgICAgICAgICAgaWYgKHRoaXMuYXR0YWNobWVudEZvcm1hdHRlcnMubGVuZ3RoICE9IGZvcm1hdHRlcnMubGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgYXR0YWNobWVudE1pc21hdGNoKHRoaXMuYXR0YWNobWVudEZvcm1hdHRlcnMubGVuZ3RoLAorICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWF0dGVycy5sZW5ndGgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoaXNXcml0aW5nKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0aGlzLmF0dGFjaG1lbnROYW1lcyA9IGZvcm1hdHRlcnM7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBmb3JtYXR0ZXIgdXNlZCB0byBjcmVhdGUgdGhlIHN1YmplY3QgbGluZS4KKyAgICAgKiBJZiB0aGUgc3ViamVjdCB3YXMgY3JlYXRlZCB1c2luZyBhIGxpdGVyYWwgc3RyaW5nIHRoZW4KKyAgICAgKiB0aGUgPHR0PnRvU3RyaW5nPC90dD4gbWV0aG9kIGNhbiBiZSB1c2VkIHRvIGdldCB0aGUgc3ViamVjdCBsaW5lLgorICAgICAqIEByZXR1cm4gdGhlIGZvcm1hdHRlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgc3luY2hyb25pemVkIEZvcm1hdHRlciBnZXRTdWJqZWN0KCkgeworICAgICAgICByZXR1cm4gdGhpcy5zdWJqZWN0Rm9ybWF0dGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgYSBsaXRlcmFsIHN0cmluZyBmb3IgdGhlIGVtYWlsIHN1YmplY3QuICBBbGwgY29udHJvbCBjaGFyYWN0ZXJzIGFyZQorICAgICAqIHJlbW92ZWQgZnJvbSB0aGUgc3ViamVjdCBsaW5lLgorICAgICAqIEBwYXJhbSBzdWJqZWN0IGEgbm9uIDx0dD5udWxsPC90dD4gc3RyaW5nLgorICAgICAqIEB0aHJvd3MgU2VjdXJpdHlFeGNlcHRpb24gIGlmIGEgc2VjdXJpdHkgbWFuYWdlciBleGlzdHMgYW5kIHRoZQorICAgICAqIGNhbGxlciBkb2VzIG5vdCBoYXZlIDx0dD5Mb2dnaW5nUGVybWlzc2lvbigiY29udHJvbCIpPC90dD4uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8dHQ+c3ViamVjdDwvdHQ+IGlzIDx0dD5udWxsPC90dD4uCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgY2FsbGVkIGZyb20gaW5zaWRlIGEgcHVzaC4KKyAgICAgKiBAc2VlIENoYXJhY3RlciNpc0lTT0NvbnRyb2woY2hhcikKKyAgICAgKiBAc2VlIENoYXJhY3RlciNpc0lTT0NvbnRyb2woaW50KQorICAgICAqLworICAgIHB1YmxpYyBmaW5hbCB2b2lkIHNldFN1YmplY3QoZmluYWwgU3RyaW5nIHN1YmplY3QpIHsKKyAgICAgICAgaWYgKHN1YmplY3QgIT0gbnVsbCkgeworICAgICAgICAgICAgdGhpcy5zZXRTdWJqZWN0KFRhaWxOYW1lRm9ybWF0dGVyLm9mKHN1YmplY3QpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGNoZWNrQWNjZXNzKCk7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHN1YmplY3QgZm9ybWF0dGVyIGZvciBlbWFpbC4gIFRoZSBmb3JtYXQgbWV0aG9kIG9mIHRoZSBzdWJqZWN0CisgICAgICogZm9ybWF0dGVyIHdpbGwgc2VlIGFsbCA8dHQ+TG9nUmVjb3JkPC90dD4gb2JqZWN0cyB0aGF0IHdlcmUgcHVibGlzaGVkIHRvCisgICAgICogdGhpcyA8dHQ+SGFuZGxlcjwvdHQ+IGR1cmluZyBmb3JtYXR0aW5nIGFuZCB3aWxsIHR5cGljYWxseSByZXR1cm4gYW4KKyAgICAgKiBlbXB0eSBzdHJpbmcuICBUaGlzIGZvcm1hdHRlciBpcyB1c2VkIHRvIGdhdGhlciBpbmZvcm1hdGlvbiB0byBjcmVhdGUgYQorICAgICAqIHN1bW1hcnkgYWJvdXQgd2hhdCBpbmZvcm1hdGlvbiBpcyBjb250YWluZWQgaW4gdGhlIGVtYWlsLiAgVGhlCisgICAgICogPHR0PmdldFRhaWw8L3R0PiBtZXRob2Qgc2hvdWxkIGJlIHVzZWQgdG8gY29uc3RydWN0IHRoZSBzdWJqZWN0IGFuZCByZXNldAorICAgICAqIGFueSBmb3JtYXR0ZXIgY29sbGVjdGVkIHN0YXRlLiAgQWxsIGNvbnRyb2wgY2hhcmFjdGVycworICAgICAqIHdpbGwgYmUgcmVtb3ZlZCBmcm9tIHRoZSBmb3JtYXR0ZXIgb3V0cHV0LiAgVGhlIDx0dD50b1N0cmluZzwvdHQ+CisgICAgICogbWV0aG9kIG9mIHRoZSBnaXZlbiBmb3JtYXR0ZXIgc2hvdWxkIGJlIG92ZXJyaWRkZW4gdG8gcHJvdmlkZSBhIHVzZWZ1bAorICAgICAqIHN1YmplY3QsIGlmIHBvc3NpYmxlLgorICAgICAqIEBwYXJhbSBmb3JtYXQgdGhlIHN1YmplY3QgZm9ybWF0dGVyLgorICAgICAqIEB0aHJvd3MgU2VjdXJpdHlFeGNlcHRpb24gIGlmIGEgc2VjdXJpdHkgbWFuYWdlciBleGlzdHMgYW5kIHRoZQorICAgICAqIGNhbGxlciBkb2VzIG5vdCBoYXZlIDx0dD5Mb2dnaW5nUGVybWlzc2lvbigiY29udHJvbCIpPC90dD4uCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiA8dHQ+Zm9ybWF0PC90dD4gaXMgPHR0Pm51bGw8L3R0Pi4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiBjYWxsZWQgZnJvbSBpbnNpZGUgYSBwdXNoLgorICAgICAqIEBzZWUgQ2hhcmFjdGVyI2lzSVNPQ29udHJvbChjaGFyKQorICAgICAqIEBzZWUgQ2hhcmFjdGVyI2lzSVNPQ29udHJvbChpbnQpCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHZvaWQgc2V0U3ViamVjdChmaW5hbCBGb3JtYXR0ZXIgZm9ybWF0KSB7CisgICAgICAgIGNoZWNrQWNjZXNzKCk7CisgICAgICAgIGlmIChmb3JtYXQgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgIGlmIChpc1dyaXRpbmcpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0aGlzLnN1YmplY3RGb3JtYXR0ZXIgPSBmb3JtYXQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcm90ZWN0ZWQgY29udmVuaWVuY2UgbWV0aG9kIHRvIHJlcG9ydCBhbiBlcnJvciB0byB0aGlzIEhhbmRsZXIncworICAgICAqIEVycm9yTWFuYWdlci4gIFRoaXMgbWV0aG9kIHdpbGwgcHJlZml4IGFsbCBub24gbnVsbCBlcnJvciBtZXNzYWdlcyB3aXRoCisgICAgICogPHR0PkxldmVsLlNFVkVSRS5nZXROYW1lKCk8L3R0Pi4gIFRoaXMgYWxsb3dzIHRoZSByZWNlaXZpbmcgZXJyb3IKKyAgICAgKiBtYW5hZ2VyIHRvIGRldGVybWluZSBpZiB0aGUgPHR0Pm1zZzwvdHQ+IHBhcmFtZXRlciBpcyBhIHNpbXBsZSBlcnJvcgorICAgICAqIG1lc3NhZ2Ugb3IgYSByYXcgZW1haWwgbWVzc2FnZS4KKyAgICAgKiBAcGFyYW0gbXNnICAgIGEgZGVzY3JpcHRpdmUgc3RyaW5nIChtYXkgYmUgbnVsbCkKKyAgICAgKiBAcGFyYW0gZXggICAgIGFuIGV4Y2VwdGlvbiAobWF5IGJlIG51bGwpCisgICAgICogQHBhcmFtIGNvZGUgICBhbiBlcnJvciBjb2RlIGRlZmluZWQgaW4gRXJyb3JNYW5hZ2VyCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgcmVwb3J0RXJyb3IoU3RyaW5nIG1zZywgRXhjZXB0aW9uIGV4LCBpbnQgY29kZSkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKG1zZyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgZXJyb3JNYW5hZ2VyLmVycm9yKExldmVsLlNFVkVSRS5nZXROYW1lKCkKKyAgICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQoIjogIikuY29uY2F0KG1zZyksIGV4LCBjb2RlKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZXJyb3JNYW5hZ2VyLmVycm9yKG51bGwsIGV4LCBjb2RlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiB8IExpbmthZ2VFcnJvciBHTEFTU0ZJU0hfMjEyNTgpIHsKKyAgICAgICAgICAgIHJlcG9ydExpbmthZ2VFcnJvcihHTEFTU0ZJU0hfMjEyNTgsIGNvZGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2FsbHMgbG9nIG1hbmFnZXIgY2hlY2tBY2Nlc3MgaWYgdGhpcyBpcyBzZWFsZWQuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrQWNjZXNzKCkgeworICAgICAgICBpZiAoc2VhbGVkKSB7CisgICAgICAgICAgICBMb2dNYW5hZ2VyUHJvcGVydGllcy5jaGVja0xvZ01hbmFnZXJBY2Nlc3MoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgdGhlIG1pbWVUeXBlIG9mIGEgZm9ybWF0dGVyIGZyb20gdGhlIGdldEhlYWQgY2FsbC4KKyAgICAgKiBUaGlzIGNvdWxkIGJlIG1hZGUgcHJvdGVjdGVkLCBvciBhIG5ldyBjbGFzcyBjb3VsZCBiZSBjcmVhdGVkIHRvIGRvCisgICAgICogdGhpcyB0eXBlIG9mIGNvbnZlcnNpb24uICBDdXJyZW50bHksIHRoaXMgaXMgb25seSB1c2VkIGZvciB0aGUgYm9keQorICAgICAqIHNpbmNlIHRoZSBhdHRhY2htZW50cyBhcmUgY29tcHV0ZWQgYnkgZmlsZW5hbWUuCisgICAgICogUGFja2FnZS1wcml2YXRlIGZvciB1bml0IHRlc3RpbmcuCisgICAgICogQHBhcmFtIGNodW5rIGFueSBjaGFyIHNlcXVlbmNlIG9yIG51bGwuCisgICAgICogQHJldHVybiByZXR1cm4gdGhlIG1pbWUgdHlwZSBvciBudWxsIGZvciB0ZXh0L3BsYWluLgorICAgICAqLworICAgIGZpbmFsIFN0cmluZyBjb250ZW50VHlwZU9mKENoYXJTZXF1ZW5jZSBjaHVuaykgeworICAgICAgICBpZiAoIWlzRW1wdHkoY2h1bmspKSB7CisgICAgICAgICAgICBmaW5hbCBpbnQgTUFYX0NIQVJTID0gMjU7CisgICAgICAgICAgICBpZiAoY2h1bmsubGVuZ3RoKCkgPiBNQVhfQ0hBUlMpIHsKKyAgICAgICAgICAgICAgICBjaHVuayA9IGNodW5rLnN1YlNlcXVlbmNlKDAsIE1BWF9DSEFSUyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBjaGFyc2V0ID0gZ2V0RW5jb2RpbmdOYW1lKCk7CisgICAgICAgICAgICAgICAgZmluYWwgYnl0ZVtdIGIgPSBjaHVuay50b1N0cmluZygpLmdldEJ5dGVzKGNoYXJzZXQpOworICAgICAgICAgICAgICAgIGZpbmFsIEJ5dGVBcnJheUlucHV0U3RyZWFtIGluID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGIpOworICAgICAgICAgICAgICAgIGFzc2VydCBpbi5tYXJrU3VwcG9ydGVkKCkgOiBpbi5nZXRDbGFzcygpLmdldE5hbWUoKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gVVJMQ29ubmVjdGlvbi5ndWVzc0NvbnRlbnRUeXBlRnJvbVN0cmVhbShpbik7CisgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBJT0V4Y2VwdGlvbiBJT0UpIHsKKyAgICAgICAgICAgICAgICByZXBvcnRFcnJvcihJT0UuZ2V0TWVzc2FnZSgpLCBJT0UsIEVycm9yTWFuYWdlci5GT1JNQVRfRkFJTFVSRSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7IC8vdGV4dC9wbGFpbgorICAgIH0KKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgdGhlIG1pbWVUeXBlIG9mIGEgZm9ybWF0dGVyIGJ5IHRoZSBjbGFzcyBuYW1lLiAgVGhpcyBtZXRob2QKKyAgICAgKiBhdm9pZHMgY2FsbGluZyBnZXRIZWFkIGFuZCBnZXRUYWlsIG9mIGNvbnRlbnQgZm9ybWF0dGVycyBkdXJpbmcgdmVyaWZ5CisgICAgICogYmVjYXVzZSB0aGV5IG1pZ2h0IHRyaWdnZXIgc2lkZSBlZmZlY3RzIG9yIGV4Y2Vzc2l2ZSB3b3JrLiAgVGhlIG5hbWUKKyAgICAgKiBmb3JtYXR0ZXJzIGFuZCBzdWJqZWN0IGFyZSB1c3VhbGx5IHNhZmUgdG8gY2FsbC4KKyAgICAgKiBQYWNrYWdlLXByaXZhdGUgZm9yIHVuaXQgdGVzdGluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmIHRoZSBmb3JtYXR0ZXIgb3IgbnVsbC4KKyAgICAgKiBAcmV0dXJuIHJldHVybiB0aGUgbWltZSB0eXBlIG9yIG51bGwsIG1lYW5pbmcgdGV4dC9wbGFpbi4KKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS41LjYKKyAgICAgKi8KKyAgICBmaW5hbCBTdHJpbmcgY29udGVudFR5cGVPZihmaW5hbCBGb3JtYXR0ZXIgZikgeworICAgICAgICBhc3NlcnQgVGhyZWFkLmhvbGRzTG9jayh0aGlzKTsKKyAgICAgICAgaWYgKGYgIT0gbnVsbCkgeworICAgICAgICAgICAgU3RyaW5nIHR5cGUgPSBnZXRDb250ZW50VHlwZShmLmdldENsYXNzKCkuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGlmICh0eXBlICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHlwZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZm9yIChDbGFzczw/PiBrID0gZi5nZXRDbGFzcygpOyBrICE9IEZvcm1hdHRlci5jbGFzczsKKyAgICAgICAgICAgICAgICAgICAgayA9IGsuZ2V0U3VwZXJjbGFzcygpKSB7CisgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWU7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgbmFtZSA9IGsuZ2V0U2ltcGxlTmFtZSgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGZpbmFsIEludGVybmFsRXJyb3IgSkRLODA1NzkxOSkgeworICAgICAgICAgICAgICAgICAgICBuYW1lID0gay5nZXROYW1lKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIG5hbWUgPSBuYW1lLnRvTG93ZXJDYXNlKExvY2FsZS5FTkdMSVNIKTsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpZHggPSBuYW1lLmluZGV4T2YoJyQnKSArIDE7CisgICAgICAgICAgICAgICAgICAgICAgICAoaWR4ID0gbmFtZS5pbmRleE9mKCJtbCIsIGlkeCkpID4gLTE7IGlkeCArPSAyKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChpZHggPiAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgIGlmIChuYW1lLmNoYXJBdChpZHggLSAxKSA9PSAneCcpICB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gImFwcGxpY2F0aW9uL3htbCI7CisgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlkeCA+IDEgJiYgbmFtZS5jaGFyQXQoaWR4IC0gMikgPT0gJ2gnCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgbmFtZS5jaGFyQXQoaWR4IC0gMSkgPT0gJ3QnKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gInRleHQvaHRtbCI7CisgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgIC8qKgorICAgICAqIERldGVybWluZXMgaWYgdGhlIGdpdmVuIHRocm93YWJsZSBpcyBhIG5vIGNvbnRlbnQgZXhjZXB0aW9uLiAgSXQgaXMKKyAgICAgKiBhc3N1bWVkIFRyYW5zcG9ydC5zZW5kTWVzc2FnZSB3aWxsIGNhbGwgTWVzc2FnZS53cml0ZVRvIHNvIHdlIG5lZWQgdG8KKyAgICAgKiBpZ25vcmUgYW55IGV4Y2VwdGlvbnMgdGhhdCBjb3VsZCBiZSBsYXllcmVkIG9uIHRvcCBvZiB0aGF0IGNhbGwgY2hhaW4gdG8KKyAgICAgKiBpbmZlciB0aGF0IHNlbmRNZXNzYWdlIGlzIGZhaWxpbmcgYmVjYXVzZSBvZiB3cml0ZVRvLiAgUGFja2FnZS1wcml2YXRlCisgICAgICogZm9yIHVuaXQgdGVzdGluZy4KKyAgICAgKiBAcGFyYW0gbXNnIHRoZSBtZXNzYWdlIHdpdGhvdXQgY29udGVudC4KKyAgICAgKiBAcGFyYW0gdCB0aGUgdGhyb3dhYmxlIGNoYWluIHRvIHRlc3QuCisgICAgICogQHJldHVybiB0cnVlIGlmIHRoZSB0aHJvd2FibGUgaXMgYSBtaXNzaW5nIGNvbnRlbnQgZXhjZXB0aW9uLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgYW55IG9mIHRoZSBhcmd1bWVudHMgYXJlIG51bGwuCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNC41CisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoeyJVc2VTcGVjaWZpY0NhdGNoIiwgIlRocm93YWJsZVJlc3VsdElnbm9yZWQifSkKKyAgICBmaW5hbCBib29sZWFuIGlzTWlzc2luZ0NvbnRlbnQoTWVzc2FnZSBtc2csIFRocm93YWJsZSB0KSB7CisgICAgICAgIGZpbmFsIE9iamVjdCBjY2wgPSBnZXRBbmRTZXRDb250ZXh0Q2xhc3NMb2FkZXIoTUFJTEhBTkRMRVJfTE9BREVSKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG1zZy53cml0ZVRvKG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oTUlOX0hFQURFUl9TSVpFKSk7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIFJ1bnRpbWVFeGNlcHRpb24gUkUpIHsKKyAgICAgICAgICAgIHRocm93IFJFOyAvL0F2b2lkIGNhdGNoIGFsbC4KKyAgICAgICAgfSBjYXRjaCAoZmluYWwgRXhjZXB0aW9uIG5vQ29udGVudCkgeworICAgICAgICAgICAgZmluYWwgU3RyaW5nIHR4dCA9IG5vQ29udGVudC5nZXRNZXNzYWdlKCk7CisgICAgICAgICAgICBpZiAoIWlzRW1wdHkodHh0KSkgeworICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IDA7CisgICAgICAgICAgICAgICAgd2hpbGUgKHQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBpZiAobm9Db250ZW50LmdldENsYXNzKCkgPT0gdC5nZXRDbGFzcygpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgdHh0LmVxdWFscyh0LmdldE1lc3NhZ2UoKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICAvL05vdCBhbGwgSmF2YU1haWwgaW1wbGVtZW50YXRpb25zIHN1cHBvcnQgSkRLIDEuNCBleGNlcHRpb24KKyAgICAgICAgICAgICAgICAgICAgLy9jaGFpbmluZy4KKyAgICAgICAgICAgICAgICAgICAgZmluYWwgVGhyb3dhYmxlIGNhdXNlID0gdC5nZXRDYXVzZSgpOworICAgICAgICAgICAgICAgICAgICBpZiAoY2F1c2UgPT0gbnVsbCAmJiB0IGluc3RhbmNlb2YgTWVzc2FnaW5nRXhjZXB0aW9uKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0ID0gKChNZXNzYWdpbmdFeGNlcHRpb24pIHQpLmdldE5leHRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHQgPSBjYXVzZTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIC8vRGVhbCB3aXRoIGV4Y2Vzc2l2ZSBjYXVzZSBjaGFpbnMgYW5kIGN5Y2xpYyB0aHJvd2FibGVzLgorICAgICAgICAgICAgICAgICAgICBpZiAoKytsaW1pdCA9PSAoMSA8PCAxNikpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOyAvL0dpdmUgdXAuCisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBnZXRBbmRTZXRDb250ZXh0Q2xhc3NMb2FkZXIoY2NsKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydHMgYSBtaW1lIG1lc3NhZ2UgdG8gYSByYXcgc3RyaW5nIG9yIGZvcm1hdHMgdGhlIHJlYXNvbgorICAgICAqIHdoeSBtZXNzYWdlIGNhbid0IGJlIGNoYW5nZWQgdG8gcmF3IHN0cmluZyBhbmQgcmVwb3J0cyBpdC4KKyAgICAgKiBAcGFyYW0gbXNnIHRoZSBtaW1lIG1lc3NhZ2UuCisgICAgICogQHBhcmFtIGV4IHRoZSBvcmlnaW5hbCBleGNlcHRpb24uCisgICAgICogQHBhcmFtIGNvZGUgdGhlIEVycm9yTWFuYWdlciBjb2RlLgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjQuNQorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJVc2VTcGVjaWZpY0NhdGNoIikKKyAgICBwcml2YXRlIHZvaWQgcmVwb3J0RXJyb3IoTWVzc2FnZSBtc2csIEV4Y2VwdGlvbiBleCwgaW50IGNvZGUpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRyeSB7IC8vVXNlIGRpcmVjdCBjYWxsIHNvIHdlIGRvIG5vdCBwcmVmaXggcmF3IGVtYWlsLgorICAgICAgICAgICAgICAgIGVycm9yTWFuYWdlci5lcnJvcih0b1Jhd1N0cmluZyhtc2cpLCBleCwgY29kZSk7CisgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBSdW50aW1lRXhjZXB0aW9uIHJlKSB7CisgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IodG9Nc2dTdHJpbmcocmUpLCBleCwgY29kZSk7CisgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKHRvTXNnU3RyaW5nKGUpLCBleCwgY29kZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIExpbmthZ2VFcnJvciBHTEFTU0ZJU0hfMjEyNTgpIHsKKyAgICAgICAgICAgIHJlcG9ydExpbmthZ2VFcnJvcihHTEFTU0ZJU0hfMjEyNTgsIGNvZGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVwb3J0cyB0aGUgZ2l2ZW4gbGlua2FnZSBlcnJvciBvciBydW50aW1lIGV4Y2VwdGlvbi4KKyAgICAgKgorICAgICAqIFRoZSBjdXJyZW50IExvZ01hbmFnZXIgY29kZSB3aWxsIHN0b3AgY2xvc2luZyBhbGwgcmVtYWluaW5nIGhhbmRsZXJzIGlmCisgICAgICogYW4gZXJyb3IgaXMgdGhyb3duIGR1cmluZyByZXNldExvZ2dlci4gIFRoaXMgaXMgYSB3b3JrYXJvdW5kIGZvcgorICAgICAqIEdMQVNTRklTSC0yMTI1OCBhbmQgSkRLLTgxNTI1MTUuCisgICAgICogQHBhcmFtIGxlIHRoZSBsaW5rYWdlIGVycm9yIG9yIGEgUnVudGltZUV4Y2VwdGlvbi4KKyAgICAgKiBAcGFyYW0gY29kZSB0aGUgRXJyb3JNYW5hZ2VyIGNvZGUuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiBlcnJvciBpcyBudWxsLgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjUuMworICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZXBvcnRMaW5rYWdlRXJyb3IoZmluYWwgVGhyb3dhYmxlIGxlLCBmaW5hbCBpbnQgY29kZSkgeworICAgICAgICBpZiAobGUgPT0gbnVsbCkgeworICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oU3RyaW5nLnZhbHVlT2YoY29kZSkpOworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgSW50ZWdlciBpZHggPSBNVVRFWC5nZXQoKTsKKyAgICAgICAgaWYgKGlkeCA9PSBudWxsIHx8IGlkeCA+IE1VVEVYX0xJTktBR0UpIHsKKyAgICAgICAgICAgIE1VVEVYLnNldChNVVRFWF9MSU5LQUdFKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXRVbmNhdWdodEV4Y2VwdGlvbkhhbmRsZXIoKQorICAgICAgICAgICAgICAgICAgICAgICAgLnVuY2F1Z2h0RXhjZXB0aW9uKFRocmVhZC5jdXJyZW50VGhyZWFkKCksIGxlKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gfCBMaW5rYWdlRXJyb3IgaWdub3JlKSB7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIGlmIChpZHggIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBNVVRFWC5zZXQoaWR4KTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBNVVRFWC5yZW1vdmUoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXRlcm1pbmVzIHRoZSBtaW1lVHlwZSBmcm9tIHRoZSBnaXZlbiBmaWxlIG5hbWUuCisgICAgICogVXNlZCB0byBvdmVycmlkZSB0aGUgYm9keSBjb250ZW50IHR5cGUgYW5kIHVzZWQgZm9yIGFsbCBhdHRhY2htZW50cy4KKyAgICAgKiBAcGFyYW0gbmFtZSB0aGUgZmlsZSBuYW1lIG9yIGNsYXNzIG5hbWUuCisgICAgICogQHJldHVybiB0aGUgbWltZSB0eXBlIG9yIG51bGwgZm9yIHRleHQvcGxhaW4uCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgZ2V0Q29udGVudFR5cGUoZmluYWwgU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgYXNzZXJ0IFRocmVhZC5ob2xkc0xvY2sodGhpcyk7CisgICAgICAgIGZpbmFsIFN0cmluZyB0eXBlID0gY29udGVudFR5cGVzLmdldENvbnRlbnRUeXBlKG5hbWUpOworICAgICAgICBpZiAoImFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSIuZXF1YWxzSWdub3JlQ2FzZSh0eXBlKSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7IC8vRm9ybWF0dGVycyByZXR1cm4gc3RyaW5ncywgZGVmYXVsdCB0byB0ZXh0L3BsYWluLgorICAgICAgICB9CisgICAgICAgIHJldHVybiB0eXBlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGVuY29kaW5nIHNldCBmb3IgdGhpcyBoYW5kbGVyLCBtaW1lIGVuY29kaW5nLCBvciBmaWxlIGVuY29kaW5nLgorICAgICAqIEByZXR1cm4gdGhlIGphdmEgY2hhcnNldCBuYW1lLCBuZXZlciBudWxsLgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjQuNQorICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nIGdldEVuY29kaW5nTmFtZSgpIHsKKyAgICAgICAgU3RyaW5nIGNoYXJzZXQgPSBnZXRFbmNvZGluZygpOworICAgICAgICBpZiAoY2hhcnNldCA9PSBudWxsKSB7CisgICAgICAgICAgICBjaGFyc2V0ID0gTWltZVV0aWxpdHkuZ2V0RGVmYXVsdEphdmFDaGFyc2V0KCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGNoYXJzZXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBjb250ZW50IGZvciBhIHBhcnQgdXNpbmcgdGhlIGVuY29kaW5nIGFzc2lnbmVkIHRvIHRoZSBoYW5kbGVyLgorICAgICAqIEBwYXJhbSBwYXJ0IHRoZSBwYXJ0IHRvIGFzc2lnbi4KKyAgICAgKiBAcGFyYW0gYnVmIHRoZSBmb3JtYXR0ZWQgZGF0YS4KKyAgICAgKiBAcGFyYW0gdHlwZSB0aGUgbWltZSB0eXBlIG9yIG51bGwsIG1lYW5pbmcgdGV4dC9wbGFpbi4KKyAgICAgKiBAdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiBpZiB0aGVyZSBpcyBhIHByb2JsZW0uCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHNldENvbnRlbnQoTWltZVBhcnQgcGFydCwgQ2hhclNlcXVlbmNlIGJ1ZiwgU3RyaW5nIHR5cGUpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworICAgICAgICBmaW5hbCBTdHJpbmcgY2hhcnNldCA9IGdldEVuY29kaW5nTmFtZSgpOworICAgICAgICBpZiAodHlwZSAhPSBudWxsICYmICEidGV4dC9wbGFpbiIuZXF1YWxzSWdub3JlQ2FzZSh0eXBlKSkgeworICAgICAgICAgICAgdHlwZSA9IGNvbnRlbnRXaXRoRW5jb2RpbmcodHlwZSwgY2hhcnNldCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIERhdGFTb3VyY2Ugc291cmNlID0gbmV3IEJ5dGVBcnJheURhdGFTb3VyY2UoYnVmLnRvU3RyaW5nKCksIHR5cGUpOworICAgICAgICAgICAgICAgIHBhcnQuc2V0RGF0YUhhbmRsZXIobmV3IERhdGFIYW5kbGVyKHNvdXJjZSkpOworICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgSU9FeGNlcHRpb24gSU9FKSB7CisgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoSU9FLmdldE1lc3NhZ2UoKSwgSU9FLCBFcnJvck1hbmFnZXIuRk9STUFUX0ZBSUxVUkUpOworICAgICAgICAgICAgICAgIHBhcnQuc2V0VGV4dChidWYudG9TdHJpbmcoKSwgY2hhcnNldCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBwYXJ0LnNldFRleHQoYnVmLnRvU3RyaW5nKCksIE1pbWVVdGlsaXR5Lm1pbWVDaGFyc2V0KGNoYXJzZXQpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlcGxhY2VzIHRoZSBjaGFyc2V0IHBhcmFtZXRlciB3aXRoIHRoZSBjdXJyZW50IGVuY29kaW5nLgorICAgICAqIEBwYXJhbSB0eXBlIHRoZSBjb250ZW50IHR5cGUuCisgICAgICogQHBhcmFtIGVuY29kaW5nIHRoZSBqYXZhIGNoYXJzZXQgbmFtZS4KKyAgICAgKiBAcmV0dXJuIHRoZSB0eXBlIHdpdGggYSBzcGVjaWZpZWQgZW5jb2RpbmcuCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgY29udGVudFdpdGhFbmNvZGluZyhTdHJpbmcgdHlwZSwgU3RyaW5nIGVuY29kaW5nKSB7CisgICAgICAgIGFzc2VydCBlbmNvZGluZyAhPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmluYWwgQ29udGVudFR5cGUgY3QgPSBuZXcgQ29udGVudFR5cGUodHlwZSk7CisgICAgICAgICAgICBjdC5zZXRQYXJhbWV0ZXIoImNoYXJzZXQiLCBNaW1lVXRpbGl0eS5taW1lQ2hhcnNldChlbmNvZGluZykpOworICAgICAgICAgICAgZW5jb2RpbmcgPSBjdC50b1N0cmluZygpOyAvL1NlZSBqYXZheC5tYWlsLmludGVybmV0LkNvbnRlbnRUeXBlLgorICAgICAgICAgICAgaWYgKCFpc0VtcHR5KGVuY29kaW5nKSkgeyAvL1N1cHBvcnQgcHJlIEs1Njg3LgorICAgICAgICAgICAgICAgIHR5cGUgPSBlbmNvZGluZzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoZmluYWwgTWVzc2FnaW5nRXhjZXB0aW9uIE1FKSB7CisgICAgICAgICAgICByZXBvcnRFcnJvcih0eXBlLCBNRSwgRXJyb3JNYW5hZ2VyLkZPUk1BVF9GQUlMVVJFKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdHlwZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBjYXBhY2l0eSBmb3IgdGhpcyBoYW5kbGVyLiAgVGhpcyBtZXRob2QgaXMga2VwdCBwcml2YXRlCisgICAgICogYmVjYXVzZSB3ZSB3b3VsZCBoYXZlIHRvIGRlZmluZSBhIHB1YmxpYyBwb2xpY3kgZm9yIHdoZW4gdGhlIHNpemUgaXMKKyAgICAgKiBncmVhdGVyIHRoYW4gdGhlIGNhcGFjaXR5LgorICAgICAqIEUuRy4gZG8gbm90aGluZywgZmx1c2ggbm93LCB0cnVuY2F0ZSBub3csIHB1c2ggbm93IGFuZCByZXNpemUuCisgICAgICogQHBhcmFtIG5ld0NhcGFjaXR5IHRoZSBtYXggbnVtYmVyIG9mIHJlY29yZHMuCisgICAgICogQHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbiAgaWYgYSBzZWN1cml0eSBtYW5hZ2VyIGV4aXN0cyBhbmQgdGhlCisgICAgICogY2FsbGVyIGRvZXMgbm90IGhhdmUgPHR0PkxvZ2dpbmdQZXJtaXNzaW9uKCJjb250cm9sIik8L3R0Pi4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiBjYWxsZWQgZnJvbSBpbnNpZGUgYSBwdXNoLgorICAgICAqLworICAgIHByaXZhdGUgc3luY2hyb25pemVkIHZvaWQgc2V0Q2FwYWNpdHkwKGZpbmFsIGludCBuZXdDYXBhY2l0eSkgeworICAgICAgICBjaGVja0FjY2VzcygpOworICAgICAgICBpZiAobmV3Q2FwYWNpdHkgPD0gMCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiQ2FwYWNpdHkgbXVzdCBiZSBncmVhdGVyIHRoYW4gemVyby4iKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChpc1dyaXRpbmcpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICh0aGlzLmNhcGFjaXR5IDwgMCkgeyAvL0lmIGNsb3NlZCwgcmVtYWluIGNsb3NlZC4KKyAgICAgICAgICAgIHRoaXMuY2FwYWNpdHkgPSAtbmV3Q2FwYWNpdHk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aGlzLmNhcGFjaXR5ID0gbmV3Q2FwYWNpdHk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBhdHRhY2htZW50IGZpbHRlcnMgdXNpbmcgYSBoYXBwZW5zLWJlZm9yZSByZWxhdGlvbnNoaXAgYmV0d2VlbgorICAgICAqIHRoaXMgbWV0aG9kIGFuZCBzZXRBdHRhY2htZW50RmlsdGVycy4gIFRoZSBhdHRhY2htZW50IGZpbHRlcnMgYXJlIHRyZWF0ZWQKKyAgICAgKiBhcyBjb3B5LW9uLXdyaXRlLCBzbyB0aGUgcmV0dXJuZWQgYXJyYXkgbXVzdCBuZXZlciBiZSBtb2RpZmllZCBvcgorICAgICAqIHB1Ymxpc2hlZCBvdXRzaWRlIHRoaXMgY2xhc3MuCisgICAgICogQHJldHVybiBhIHJlYWQgb25seSBhcnJheSBvZiBmaWx0ZXJzLgorICAgICAqLworICAgIHByaXZhdGUgRmlsdGVyW10gcmVhZE9ubHlBdHRhY2htZW50RmlsdGVycygpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMuYXR0YWNobWVudEZpbHRlcnM7CisgICAgfQorCisgICAgLyoqCisgICAgICogRmFjdG9yeSBmb3IgZW1wdHkgZm9ybWF0dGVyIGFycmF5cy4KKyAgICAgKiBAcmV0dXJuIGFuIGVtcHR5IGFycmF5LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIEZvcm1hdHRlcltdIGVtcHR5Rm9ybWF0dGVyQXJyYXkoKSB7CisgICAgICAgIHJldHVybiBFTVBUWV9GT1JNQVRURVJTOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZhY3RvcnkgZm9yIGVtcHR5IGZpbHRlciBhcnJheXMuCisgICAgICogQHJldHVybiBhbiBlbXB0eSBhcnJheS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBGaWx0ZXJbXSBlbXB0eUZpbHRlckFycmF5KCkgeworICAgICAgICByZXR1cm4gRU1QVFlfRklMVEVSUzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFeHBhbmQgb3Igc2hyaW5rIHRoZSBhdHRhY2htZW50IG5hbWUgZm9ybWF0dGVycyB3aXRoIHRoZSBhdHRhY2htZW50CisgICAgICogZm9ybWF0dGVycy4KKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgc2l6ZSB3YXMgY2hhbmdlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gYWxpZ25BdHRhY2htZW50TmFtZXMoKSB7CisgICAgICAgIGFzc2VydCBUaHJlYWQuaG9sZHNMb2NrKHRoaXMpOworICAgICAgICBib29sZWFuIGZpeGVkID0gZmFsc2U7CisgICAgICAgIGZpbmFsIGludCBleHBlY3QgPSB0aGlzLmF0dGFjaG1lbnRGb3JtYXR0ZXJzLmxlbmd0aDsKKyAgICAgICAgZmluYWwgaW50IGN1cnJlbnQgPSB0aGlzLmF0dGFjaG1lbnROYW1lcy5sZW5ndGg7CisgICAgICAgIGlmIChjdXJyZW50ICE9IGV4cGVjdCkgeworICAgICAgICAgICAgdGhpcy5hdHRhY2htZW50TmFtZXMgPSBBcnJheXMuY29weU9mKGF0dGFjaG1lbnROYW1lcywgZXhwZWN0LAorICAgICAgICAgICAgICAgICAgICBGb3JtYXR0ZXJbXS5jbGFzcyk7CisgICAgICAgICAgICBmaXhlZCA9IGN1cnJlbnQgIT0gMDsKKyAgICAgICAgfQorCisgICAgICAgIC8vQ29weSBvZiB6ZXJvIGxlbmd0aCBhcnJheSBpcyBjaGVhcCwgd2FybSB1cCBjb3B5T2YuCisgICAgICAgIGlmIChleHBlY3QgPT0gMCkgeworICAgICAgICAgICAgdGhpcy5hdHRhY2htZW50TmFtZXMgPSBlbXB0eUZvcm1hdHRlckFycmF5KCk7CisgICAgICAgICAgICBhc3NlcnQgdGhpcy5hdHRhY2htZW50TmFtZXMubGVuZ3RoID09IDA7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGV4cGVjdDsgKytpKSB7CisgICAgICAgICAgICAgICAgaWYgKHRoaXMuYXR0YWNobWVudE5hbWVzW2ldID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhpcy5hdHRhY2htZW50TmFtZXNbaV0gPSBUYWlsTmFtZUZvcm1hdHRlci5vZigKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b1N0cmluZyh0aGlzLmF0dGFjaG1lbnRGb3JtYXR0ZXJzW2ldKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBmaXhlZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFeHBhbmQgb3Igc2hyaW5rIHRoZSBhdHRhY2htZW50IGZpbHRlcnMgd2l0aCB0aGUgYXR0YWNobWVudCBmb3JtYXR0ZXJzLgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgc2l6ZSB3YXMgY2hhbmdlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gYWxpZ25BdHRhY2htZW50RmlsdGVycygpIHsKKyAgICAgICAgYXNzZXJ0IFRocmVhZC5ob2xkc0xvY2sodGhpcyk7CisKKyAgICAgICAgYm9vbGVhbiBmaXhlZCA9IGZhbHNlOworICAgICAgICBmaW5hbCBpbnQgZXhwZWN0ID0gdGhpcy5hdHRhY2htZW50Rm9ybWF0dGVycy5sZW5ndGg7CisgICAgICAgIGZpbmFsIGludCBjdXJyZW50ID0gdGhpcy5hdHRhY2htZW50RmlsdGVycy5sZW5ndGg7CisgICAgICAgIGlmIChjdXJyZW50ICE9IGV4cGVjdCkgeworICAgICAgICAgICAgdGhpcy5hdHRhY2htZW50RmlsdGVycyA9IEFycmF5cy5jb3B5T2YoYXR0YWNobWVudEZpbHRlcnMsIGV4cGVjdCwKKyAgICAgICAgICAgICAgICAgICAgRmlsdGVyW10uY2xhc3MpOworICAgICAgICAgICAgY2xlYXJNYXRjaGVzKGN1cnJlbnQpOworICAgICAgICAgICAgZml4ZWQgPSBjdXJyZW50ICE9IDA7CisKKyAgICAgICAgICAgIC8vQXJyYXkgZWxlbWVudHMgZGVmYXVsdCB0byBudWxsIHNvIHNraXAgZmlsbGluZyBpZiBib2R5IGZpbHRlcgorICAgICAgICAgICAgLy9pcyBudWxsLiAgSWYgbm90IG51bGwgdGhlbiBvbmx5IGFzc2lnbiB0byBleHBhbmRlZCBlbGVtZW50cy4KKyAgICAgICAgICAgIGZpbmFsIEZpbHRlciBib2R5ID0gdGhpcy5maWx0ZXI7CisgICAgICAgICAgICBpZiAoYm9keSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IGN1cnJlbnQ7IGkgPCBleHBlY3Q7ICsraSkgeworICAgICAgICAgICAgICAgICAgICB0aGlzLmF0dGFjaG1lbnRGaWx0ZXJzW2ldID0gYm9keTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvL0NvcHkgb2YgemVybyBsZW5ndGggYXJyYXkgaXMgY2hlYXAsIHdhcm0gdXAgY29weU9mLgorICAgICAgICBpZiAoZXhwZWN0ID09IDApIHsKKyAgICAgICAgICAgIHRoaXMuYXR0YWNobWVudEZpbHRlcnMgPSBlbXB0eUZpbHRlckFycmF5KCk7CisgICAgICAgICAgICBhc3NlcnQgdGhpcy5hdHRhY2htZW50RmlsdGVycy5sZW5ndGggPT0gMDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZml4ZWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgc2l6ZSB0byB6ZXJvIGFuZCBjbGVhcnMgdGhlIGN1cnJlbnQgYnVmZmVyLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZXNldCgpIHsKKyAgICAgICAgYXNzZXJ0IFRocmVhZC5ob2xkc0xvY2sodGhpcyk7CisgICAgICAgIGlmIChzaXplIDwgZGF0YS5sZW5ndGgpIHsKKyAgICAgICAgICAgIEFycmF5cy5maWxsKGRhdGEsIDAsIHNpemUsIG51bGwpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgQXJyYXlzLmZpbGwoZGF0YSwgbnVsbCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5zaXplID0gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFeHBhbmRzIHRoZSBpbnRlcm5hbCBidWZmZXIgdXAgdG8gdGhlIGNhcGFjaXR5LgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBncm93KCkgeworICAgICAgICBhc3NlcnQgVGhyZWFkLmhvbGRzTG9jayh0aGlzKTsKKyAgICAgICAgZmluYWwgaW50IGxlbiA9IGRhdGEubGVuZ3RoOworICAgICAgICBpbnQgbmV3Q2FwYWNpdHkgPSBsZW4gKyAobGVuID4+IDEpICsgMTsKKyAgICAgICAgaWYgKG5ld0NhcGFjaXR5ID4gY2FwYWNpdHkgfHwgbmV3Q2FwYWNpdHkgPCBsZW4pIHsKKyAgICAgICAgICAgIG5ld0NhcGFjaXR5ID0gY2FwYWNpdHk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0IGxlbiAhPSBjYXBhY2l0eSA6IGxlbjsKKyAgICAgICAgdGhpcy5kYXRhID0gQXJyYXlzLmNvcHlPZihkYXRhLCBuZXdDYXBhY2l0eSwgTG9nUmVjb3JkW10uY2xhc3MpOworICAgICAgICB0aGlzLm1hdGNoZWQgPSBBcnJheXMuY29weU9mKG1hdGNoZWQsIG5ld0NhcGFjaXR5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25maWd1cmVzIHRoZSBoYW5kbGVyIHByb3BlcnRpZXMgZnJvbSB0aGUgbG9nIG1hbmFnZXIuCisgICAgICogQHBhcmFtIHByb3BzIHRoZSBnaXZlbiBtYWlsIHByb3BlcnRpZXMuICBNYXliZSBudWxsIGFuZCBhcmUgbmV2ZXIKKyAgICAgKiBjYXB0dXJlZCBieSB0aGlzIGhhbmRsZXIuCisgICAgICogQHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbiAgaWYgYSBzZWN1cml0eSBtYW5hZ2VyIGV4aXN0cyBhbmQgdGhlCisgICAgICogY2FsbGVyIGRvZXMgbm90IGhhdmUgPHR0PkxvZ2dpbmdQZXJtaXNzaW9uKCJjb250cm9sIik8L3R0Pi4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN5bmNocm9uaXplZCB2b2lkIGluaXQoZmluYWwgUHJvcGVydGllcyBwcm9wcykgeworICAgICAgICBhc3NlcnQgdGhpcy5lcnJvck1hbmFnZXIgIT0gbnVsbDsKKyAgICAgICAgZmluYWwgU3RyaW5nIHAgPSBnZXRDbGFzcygpLmdldE5hbWUoKTsKKyAgICAgICAgdGhpcy5tYWlsUHJvcHMgPSBuZXcgUHJvcGVydGllcygpOyAvL1NlZSBtZXRob2QgcGFyYW0gY29tbWVudHMuCisgICAgICAgIGZpbmFsIE9iamVjdCBjY2wgPSBnZXRBbmRTZXRDb250ZXh0Q2xhc3NMb2FkZXIoTUFJTEhBTkRMRVJfTE9BREVSKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRoaXMuY29udGVudFR5cGVzID0gRmlsZVR5cGVNYXAuZ2V0RGVmYXVsdEZpbGVUeXBlTWFwKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBnZXRBbmRTZXRDb250ZXh0Q2xhc3NMb2FkZXIoY2NsKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vQXNzaWduIGFueSBjdXN0b20gZXJyb3IgbWFuYWdlciBmaXJzdCBzbyBpdCBjYW4gZGV0ZWN0IGFsbCBmYWlsdXJlcy4KKyAgICAgICAgaW5pdEVycm9yTWFuYWdlcihwKTsKKworICAgICAgICBpbml0TGV2ZWwocCk7CisgICAgICAgIGluaXRGaWx0ZXIocCk7CisgICAgICAgIGluaXRDYXBhY2l0eShwKTsKKyAgICAgICAgaW5pdEF1dGhlbnRpY2F0b3IocCk7CisKKyAgICAgICAgaW5pdEVuY29kaW5nKHApOworICAgICAgICBpbml0Rm9ybWF0dGVyKHApOworICAgICAgICBpbml0Q29tcGFyYXRvcihwKTsKKyAgICAgICAgaW5pdFB1c2hMZXZlbChwKTsKKyAgICAgICAgaW5pdFB1c2hGaWx0ZXIocCk7CisKKyAgICAgICAgaW5pdFN1YmplY3QocCk7CisKKyAgICAgICAgaW5pdEF0dGFjaG1lbnRGb3JtYXRlcnMocCk7CisgICAgICAgIGluaXRBdHRhY2htZW50RmlsdGVycyhwKTsKKyAgICAgICAgaW5pdEF0dGFjaG1lbnROYW1lcyhwKTsKKworICAgICAgICBpZiAocHJvcHMgPT0gbnVsbCAmJiBmcm9tTG9nTWFuYWdlcihwLmNvbmNhdCgiLnZlcmlmeSIpKSAhPSBudWxsKSB7CisgICAgICAgICAgICB2ZXJpZnlTZXR0aW5ncyhpbml0U2Vzc2lvbigpKTsKKyAgICAgICAgfQorICAgICAgICBpbnRlcm4oKTsgLy9TaG93IHZlcmlmeSB3YXJuaW5ncyBmaXJzdC4KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnRlcm5zIHRoZSBlcnJvciBtYW5hZ2VyLCBmb3JtYXR0ZXJzLCBhbmQgZmlsdGVycyBjb250YWluZWQgaW4gdGhpcworICAgICAqIGhhbmRsZXIuICBUaGUgY29tcGFyYXRvciBpcyBub3QgaW50ZXJuZWQuICBUaGlzIG1ldGhvZCBjYW4gb25seSBiZQorICAgICAqIGNhbGxlZCBmcm9tIGluaXQgYWZ0ZXIgYWxsIG9mIGZvcm1hdHRlcnMgYW5kIGZpbHRlcnMgYXJlIGluIGEgY29uc3RydWN0ZWQKKyAgICAgKiBhbmQgaW4gYSBjb25zaXN0ZW50IHN0YXRlLgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjUuMAorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBpbnRlcm4oKSB7CisgICAgICAgIGFzc2VydCBUaHJlYWQuaG9sZHNMb2NrKHRoaXMpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgT2JqZWN0IGNhbmlkYXRlOworICAgICAgICAgICAgT2JqZWN0IHJlc3VsdDsKKyAgICAgICAgICAgIGZpbmFsIE1hcDxPYmplY3QsIE9iamVjdD4gc2VlbiA9IG5ldyBIYXNoTWFwPD4oKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaW50ZXJuKHNlZW4sIHRoaXMuZXJyb3JNYW5hZ2VyKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKGZpbmFsIFNlY3VyaXR5RXhjZXB0aW9uIHNlKSB7CisgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3Ioc2UuZ2V0TWVzc2FnZSgpLCBzZSwgRXJyb3JNYW5hZ2VyLk9QRU5fRkFJTFVSRSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgY2FuaWRhdGUgPSB0aGlzLmZpbHRlcjsKKyAgICAgICAgICAgICAgICByZXN1bHQgPSBpbnRlcm4oc2VlbiwgY2FuaWRhdGUpOworICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgIT0gY2FuaWRhdGUgJiYgcmVzdWx0IGluc3RhbmNlb2YgRmlsdGVyKSB7CisgICAgICAgICAgICAgICAgICAgIHRoaXMuZmlsdGVyID0gKEZpbHRlcikgcmVzdWx0OworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGNhbmlkYXRlID0gdGhpcy5mb3JtYXR0ZXI7CisgICAgICAgICAgICAgICAgcmVzdWx0ID0gaW50ZXJuKHNlZW4sIGNhbmlkYXRlKTsKKyAgICAgICAgICAgICAgICBpZiAocmVzdWx0ICE9IGNhbmlkYXRlICYmIHJlc3VsdCBpbnN0YW5jZW9mIEZvcm1hdHRlcikgeworICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm1hdHRlciA9IChGb3JtYXR0ZXIpIHJlc3VsdDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBTZWN1cml0eUV4Y2VwdGlvbiBzZSkgeworICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKHNlLmdldE1lc3NhZ2UoKSwgc2UsIEVycm9yTWFuYWdlci5PUEVOX0ZBSUxVUkUpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBjYW5pZGF0ZSA9IHRoaXMuc3ViamVjdEZvcm1hdHRlcjsKKyAgICAgICAgICAgIHJlc3VsdCA9IGludGVybihzZWVuLCBjYW5pZGF0ZSk7CisgICAgICAgICAgICBpZiAocmVzdWx0ICE9IGNhbmlkYXRlICYmIHJlc3VsdCBpbnN0YW5jZW9mIEZvcm1hdHRlcikgeworICAgICAgICAgICAgICAgIHRoaXMuc3ViamVjdEZvcm1hdHRlciA9IChGb3JtYXR0ZXIpIHJlc3VsdDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgY2FuaWRhdGUgPSB0aGlzLnB1c2hGaWx0ZXI7CisgICAgICAgICAgICByZXN1bHQgPSBpbnRlcm4oc2VlbiwgY2FuaWRhdGUpOworICAgICAgICAgICAgaWYgKHJlc3VsdCAhPSBjYW5pZGF0ZSAmJiByZXN1bHQgaW5zdGFuY2VvZiBGaWx0ZXIpIHsKKyAgICAgICAgICAgICAgICB0aGlzLnB1c2hGaWx0ZXIgPSAoRmlsdGVyKSByZXN1bHQ7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXR0YWNobWVudEZvcm1hdHRlcnMubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgICAgICBjYW5pZGF0ZSA9IGF0dGFjaG1lbnRGb3JtYXR0ZXJzW2ldOworICAgICAgICAgICAgICAgIHJlc3VsdCA9IGludGVybihzZWVuLCBjYW5pZGF0ZSk7CisgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCAhPSBjYW5pZGF0ZSAmJiByZXN1bHQgaW5zdGFuY2VvZiBGb3JtYXR0ZXIpIHsKKyAgICAgICAgICAgICAgICAgICAgYXR0YWNobWVudEZvcm1hdHRlcnNbaV0gPSAoRm9ybWF0dGVyKSByZXN1bHQ7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgY2FuaWRhdGUgPSBhdHRhY2htZW50RmlsdGVyc1tpXTsKKyAgICAgICAgICAgICAgICByZXN1bHQgPSBpbnRlcm4oc2VlbiwgY2FuaWRhdGUpOworICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgIT0gY2FuaWRhdGUgJiYgcmVzdWx0IGluc3RhbmNlb2YgRmlsdGVyKSB7CisgICAgICAgICAgICAgICAgICAgIGF0dGFjaG1lbnRGaWx0ZXJzW2ldID0gKEZpbHRlcikgcmVzdWx0OworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGNhbmlkYXRlID0gYXR0YWNobWVudE5hbWVzW2ldOworICAgICAgICAgICAgICAgIHJlc3VsdCA9IGludGVybihzZWVuLCBjYW5pZGF0ZSk7CisgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCAhPSBjYW5pZGF0ZSAmJiByZXN1bHQgaW5zdGFuY2VvZiBGb3JtYXR0ZXIpIHsKKyAgICAgICAgICAgICAgICAgICAgYXR0YWNobWVudE5hbWVzW2ldID0gKEZvcm1hdHRlcikgcmVzdWx0OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoZmluYWwgRXhjZXB0aW9uIHNraXApIHsKKyAgICAgICAgICAgIHJlcG9ydEVycm9yKHNraXAuZ2V0TWVzc2FnZSgpLCBza2lwLCBFcnJvck1hbmFnZXIuT1BFTl9GQUlMVVJFKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgTGlua2FnZUVycm9yIHNraXApIHsKKyAgICAgICAgICAgIHJlcG9ydEVycm9yKHNraXAuZ2V0TWVzc2FnZSgpLCBuZXcgSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbihza2lwKSwKKyAgICAgICAgICAgICAgICAgICAgRXJyb3JNYW5hZ2VyLk9QRU5fRkFJTFVSRSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJZiBwb3NzaWJsZSBwZXJmb3JtcyBhbiBpbnRlcm4gb2YgdGhlIGdpdmVuIG9iamVjdCBpbnRvIHRoZQorICAgICAqIG1hcC4gIElmIHRoZSBvYmplY3QgY2FuIG5vdCBiZSBpbnRlcm5lZCB0aGUgZ2l2ZW4gb2JqZWN0IGlzIHJldHVybmVkLgorICAgICAqIEBwYXJhbSBtIHRoZSBtYXAgdXNlZCB0byByZWNvcmQgdGhlIGludGVybmVkIHZhbHVlcy4KKyAgICAgKiBAcGFyYW0gbyB0aGUgb2JqZWN0IHRvIHRyeSBhbiBpbnRlcm4uCisgICAgICogQHJldHVybiB0aGUgb3JpZ2luYWwgb2JqZWN0IG9yIGFuIGludGVybiByZXBsYWNlbWVudC4KKyAgICAgKiBAdGhyb3dzIFNlY3VyaXR5RXhjZXB0aW9uIGlmIHRoaXMgb3BlcmF0aW9uIGlzIG5vdCBhbGxvd2VkIGJ5IHRoZQorICAgICAqIHNlY3VyaXR5IG1hbmFnZXIuCisgICAgICogQHRocm93cyBFeGNlcHRpb24gaWYgdGhlcmUgaXMgYW4gdW5leHBlY3RlZCBwcm9ibGVtLgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjUuMAorICAgICAqLworICAgIHByaXZhdGUgT2JqZWN0IGludGVybihNYXA8T2JqZWN0LCBPYmplY3Q+IG0sIE9iamVjdCBvKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKG8gPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogVGhlIGNvbW1vbiBjYXNlIGlzIHRoYXQgbW9zdCBvYmplY3RzIHdpbGwgbm90IGludGVybi4gIFRoZSBnaXZlbgorICAgICAgICAgKiBvYmplY3QgaGFzIGEgcHVibGljIG5vIGFyZ3VtZW50IGNvbnN0cnVjdG9yIG9yIGlzIGFuIGluc3RhbmNlIG9mIGEKKyAgICAgICAgICogVGFpbE5hbWVGb3JtYXR0ZXIuICBUYWlsTmFtZUZvcm1hdHRlciBpcyBzYWZlIHVzZSBhcyBhIG1hcCBrZXkuCisgICAgICAgICAqIEZvciBldmVyeXRoaW5nIGVsc2Ugd2UgY3JlYXRlIGEgY2xvbmUgb2YgdGhlIGdpdmVuIG9iamVjdC4KKyAgICAgICAgICogVGhpcyBpcyBkb25lIGJlY2F1c2Ugb2YgdGhlIGZvbGxvd2luZzoKKyAgICAgICAgICogMS4gQ2xvbmVzIGNhbiBiZSB1c2VkIHRvIHRlc3QgdGhhdCBhIGNsYXNzIHByb3ZpZGVzIGFuIGVxdWFscyBtZXRob2QKKyAgICAgICAgICogYW5kIHRoYXQgdGhlIGVxdWFscyBtZXRob2Qgd29ya3MgY29ycmVjdGx5LgorICAgICAgICAgKiAyLiBDYWxsaW5nIGVxdWFscyBvbiB0aGUgZ2l2ZW4gb2JqZWN0IGlzIGFzc3VtZWQgdG8gYmUgY2hlYXAuCisgICAgICAgICAqIDMuIFRoZSBpbnRlcm4gbWFwIGNhbiBiZSBmaWx0ZXJlZCBzbyBpdCBvbmx5IGNvbnRhaW5zIG9iamVjdHMgdGhhdAorICAgICAgICAgKiBjYW4gYmUgaW50ZXJuZWQsIHdoaWNoIHJlZHVjZXMgdGhlIG1lbW9yeSBmb290cHJpbnQuCisgICAgICAgICAqIDQuIENsb25lcyBhcmUgbWV0aG9kIGxvY2FsIGdhcmJhZ2UuCisgICAgICAgICAqIDUuIEhhc2ggY29kZSBpcyBvbmx5IGNhbGxlZCBvbiB0aGUgY2xvbmVzIHNvIGJpYXMgbG9ja2luZyBpcyBub3QKKyAgICAgICAgICogZGlzYWJsZWQgb24gdGhlIG9iamVjdHMgdGhlIGhhbmRsZXIgd2lsbCB1c2UuCisgICAgICAgICAqLworICAgICAgICBmaW5hbCBPYmplY3Qga2V5OworICAgICAgICBpZiAoby5nZXRDbGFzcygpLmdldE5hbWUoKS5lcXVhbHMoVGFpbE5hbWVGb3JtYXR0ZXIuY2xhc3MuZ2V0TmFtZSgpKSkgeworICAgICAgICAgICAga2V5ID0gbzsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vVGhpcyBjYWxsIHdhcyBhbHJlYWR5IG1hZGUgaW4gdGhlIExvZ01hbmFnZXJQcm9wZXJ0aWVzIHNvIHRoaXMKKyAgICAgICAgICAgIC8vc2hvdWxkbid0IHRyaWdnZXIgbG9hZGluZyBvZiBhbnkgbGF6eSByZWZsZWN0aW9uIGNvZGUuCisgICAgICAgICAgICBrZXkgPSBvLmdldENsYXNzKCkuZ2V0Q29uc3RydWN0b3IoKS5uZXdJbnN0YW5jZSgpOworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgT2JqZWN0IHVzZTsKKyAgICAgICAgLy9DaGVjayB0aGUgY2xhc3Nsb2FkZXJzIG9mIGVhY2ggb2JqZWN0IGF2b2lkaW5nIHRoZSBzZWN1cml0eSBtYW5hZ2VyLgorICAgICAgICBpZiAoa2V5LmdldENsYXNzKCkgPT0gby5nZXRDbGFzcygpKSB7CisgICAgICAgICAgICBPYmplY3QgZm91bmQgPSBtLmdldChrZXkpOyAvL1RyYW5zaXRpdmUgZXF1YWxzIHRlc3QuCisgICAgICAgICAgICBpZiAoZm91bmQgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIC8vRW5zdXJlIHRoYXQgZXF1YWxzIGlzIHN5bW1ldHJpYyB0byBwcm92ZSBpbnRlcm4gaXMgc2FmZS4KKyAgICAgICAgICAgICAgICBmaW5hbCBib29sZWFuIHJpZ2h0ID0ga2V5LmVxdWFscyhvKTsKKyAgICAgICAgICAgICAgICBmaW5hbCBib29sZWFuIGxlZnQgPSBvLmVxdWFscyhrZXkpOworICAgICAgICAgICAgICAgIGlmIChyaWdodCAmJiBsZWZ0KSB7CisgICAgICAgICAgICAgICAgICAgIC8vQXNzdW1lIGhhc2hDb2RlIGlzIGRlZmluZWQgYXQgdGhpcyBwb2ludC4KKyAgICAgICAgICAgICAgICAgICAgZm91bmQgPSBtLnB1dChvLCBvKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGZvdW5kICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydE5vbkRpc2NyaW1pbmF0aW5nKGtleSwgZm91bmQpOworICAgICAgICAgICAgICAgICAgICAgICAgZm91bmQgPSBtLnJlbW92ZShrZXkpOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZvdW5kICE9IG8pIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnROb25EaXNjcmltaW5hdGluZyhrZXksIGZvdW5kKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBtLmNsZWFyKCk7IC8vVHJ5IHRvIHJlc3RvcmUgb3JkZXIuCisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBpZiAocmlnaHQgIT0gbGVmdCkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0Tm9uU3ltbWV0cmljKG8sIGtleSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdXNlID0gbzsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgLy9DaGVjayBmb3IgYSBkaXNjcmltaW5hdGluZyBlcXVhbHMgbWV0aG9kLgorICAgICAgICAgICAgICAgIGlmIChvLmdldENsYXNzKCkgPT0gZm91bmQuZ2V0Q2xhc3MoKSkgeworICAgICAgICAgICAgICAgICAgICB1c2UgPSBmb3VuZDsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICByZXBvcnROb25EaXNjcmltaW5hdGluZyhvLCBmb3VuZCk7CisgICAgICAgICAgICAgICAgICAgIHVzZSA9IG87CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdXNlID0gbzsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdXNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZhY3RvcnkgbWV0aG9kIHVzZWQgdG8gY3JlYXRlIGEgamF2YS51dGlsLmxvZ2dpbmcuU2ltcGxlRm9ybWF0dGVyLgorICAgICAqIEByZXR1cm4gYSBuZXcgU2ltcGxlRm9ybWF0dGVyLgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjUuNgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIEZvcm1hdHRlciBjcmVhdGVTaW1wbGVGb3JtYXR0ZXIoKSB7CisgICAgICAgIC8vRG9uJ3QgZm9yY2UgdGhlIGJ5dGUgY29kZSB2ZXJpZmllciB0byBsb2FkIHRoZSBmb3JtYXR0ZXIuCisgICAgICAgIHJldHVybiBGb3JtYXR0ZXIuY2xhc3MuY2FzdChuZXcgU2ltcGxlRm9ybWF0dGVyKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyBhIGNoYXIgc2VxdWVuY2UgdmFsdWUgZm9yIG51bGwgb3IgZW1wdHkuCisgICAgICogQHBhcmFtIHMgdGhlIGNoYXIgc2VxdWVuY2UuCisgICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBnaXZlbiBzdHJpbmcgaXMgbnVsbCBvciB6ZXJvIGxlbmd0aC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzRW1wdHkoZmluYWwgQ2hhclNlcXVlbmNlIHMpIHsKKyAgICAgICAgcmV0dXJuIHMgPT0gbnVsbCB8fCBzLmxlbmd0aCgpID09IDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIHRoYXQgYSBzdHJpbmcgaXMgbm90IGVtcHR5IGFuZCBub3QgZXF1YWwgdG8gdGhlIGxpdGVyYWwgIm51bGwiLgorICAgICAqIEBwYXJhbSBuYW1lIHRoZSBzdHJpbmcgdG8gY2hlY2sgZm9yIGEgdmFsdWUuCisgICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBzdHJpbmcgaGFzIGEgdmFsaWQgdmFsdWUuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBoYXNWYWx1ZShmaW5hbCBTdHJpbmcgbmFtZSkgeworICAgICAgICByZXR1cm4gIWlzRW1wdHkobmFtZSkgJiYgISJudWxsIi5lcXVhbHNJZ25vcmVDYXNlKG5hbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlcyBMb2dNYW5hZ2VyIHN0cmluZyB2YWx1ZXMgaW50byBvYmplY3RzIHVzZWQgYnkgdGhpcyBoYW5kbGVyLgorICAgICAqIEBwYXJhbSBwIHRoZSBoYW5kbGVyIGNsYXNzIG5hbWUgdXNlZCBhcyB0aGUgcHJlZml4LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIGdpdmVuIGFyZ3VtZW50IGlzIG51bGwuCisgICAgICogQHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbiBpZiBub3QgYWxsb3dlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgaW5pdEF0dGFjaG1lbnRGaWx0ZXJzKGZpbmFsIFN0cmluZyBwKSB7CisgICAgICAgIGFzc2VydCBUaHJlYWQuaG9sZHNMb2NrKHRoaXMpOworICAgICAgICBhc3NlcnQgdGhpcy5hdHRhY2htZW50Rm9ybWF0dGVycyAhPSBudWxsOworICAgICAgICBmaW5hbCBTdHJpbmcgbGlzdCA9IGZyb21Mb2dNYW5hZ2VyKHAuY29uY2F0KCIuYXR0YWNobWVudC5maWx0ZXJzIikpOworICAgICAgICBpZiAoIWlzRW1wdHkobGlzdCkpIHsKKyAgICAgICAgICAgIGZpbmFsIFN0cmluZ1tdIG5hbWVzID0gbGlzdC5zcGxpdCgiLCIpOworICAgICAgICAgICAgRmlsdGVyW10gYSA9IG5ldyBGaWx0ZXJbbmFtZXMubGVuZ3RoXTsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYS5sZW5ndGg7ICsraSkgeworICAgICAgICAgICAgICAgIG5hbWVzW2ldID0gbmFtZXNbaV0udHJpbSgpOworICAgICAgICAgICAgICAgIGlmICghIm51bGwiLmVxdWFsc0lnbm9yZUNhc2UobmFtZXNbaV0pKSB7CisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICBhW2ldID0gTG9nTWFuYWdlclByb3BlcnRpZXMubmV3RmlsdGVyKG5hbWVzW2ldKTsKKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgU2VjdXJpdHlFeGNlcHRpb24gU0UpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IFNFOyAvL0F2b2lkIGNhdGNoIGFsbC4KKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgRXhjZXB0aW9uIEUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKEUuZ2V0TWVzc2FnZSgpLCBFLCBFcnJvck1hbmFnZXIuT1BFTl9GQUlMVVJFKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdGhpcy5hdHRhY2htZW50RmlsdGVycyA9IGE7CisgICAgICAgICAgICBpZiAoYWxpZ25BdHRhY2htZW50RmlsdGVycygpKSB7CisgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoIkF0dGFjaG1lbnQgZmlsdGVycy4iLAorICAgICAgICAgICAgICAgICAgICAgICAgYXR0YWNobWVudE1pc21hdGNoKCJMZW5ndGggbWlzbWF0Y2guIiksIEVycm9yTWFuYWdlci5PUEVOX0ZBSUxVUkUpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhpcy5hdHRhY2htZW50RmlsdGVycyA9IGVtcHR5RmlsdGVyQXJyYXkoKTsKKyAgICAgICAgICAgIGFsaWduQXR0YWNobWVudEZpbHRlcnMoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlcyBMb2dNYW5hZ2VyIHN0cmluZyB2YWx1ZXMgaW50byBvYmplY3RzIHVzZWQgYnkgdGhpcyBoYW5kbGVyLgorICAgICAqIEBwYXJhbSBwIHRoZSBoYW5kbGVyIGNsYXNzIG5hbWUgdXNlZCBhcyB0aGUgcHJlZml4LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIGdpdmVuIGFyZ3VtZW50IGlzIG51bGwuCisgICAgICogQHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbiBpZiBub3QgYWxsb3dlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgaW5pdEF0dGFjaG1lbnRGb3JtYXRlcnMoZmluYWwgU3RyaW5nIHApIHsKKyAgICAgICAgYXNzZXJ0IFRocmVhZC5ob2xkc0xvY2sodGhpcyk7CisgICAgICAgIGZpbmFsIFN0cmluZyBsaXN0ID0gZnJvbUxvZ01hbmFnZXIocC5jb25jYXQoIi5hdHRhY2htZW50LmZvcm1hdHRlcnMiKSk7CisgICAgICAgIGlmICghaXNFbXB0eShsaXN0KSkgeworICAgICAgICAgICAgZmluYWwgRm9ybWF0dGVyW10gYTsKKyAgICAgICAgICAgIGZpbmFsIFN0cmluZ1tdIG5hbWVzID0gbGlzdC5zcGxpdCgiLCIpOworICAgICAgICAgICAgaWYgKG5hbWVzLmxlbmd0aCA9PSAwKSB7CisgICAgICAgICAgICAgICAgYSA9IGVtcHR5Rm9ybWF0dGVyQXJyYXkoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgYSA9IG5ldyBGb3JtYXR0ZXJbbmFtZXMubGVuZ3RoXTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhLmxlbmd0aDsgKytpKSB7CisgICAgICAgICAgICAgICAgbmFtZXNbaV0gPSBuYW1lc1tpXS50cmltKCk7CisgICAgICAgICAgICAgICAgaWYgKCEibnVsbCIuZXF1YWxzSWdub3JlQ2FzZShuYW1lc1tpXSkpIHsKKyAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFbaV0gPSBMb2dNYW5hZ2VyUHJvcGVydGllcy5uZXdGb3JtYXR0ZXIobmFtZXNbaV0pOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFbaV0gaW5zdGFuY2VvZiBUYWlsTmFtZUZvcm1hdHRlcikgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEV4Y2VwdGlvbiBDTkZFID0gbmV3IENsYXNzTm90Rm91bmRFeGNlcHRpb24oYVtpXS50b1N0cmluZygpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRFcnJvcigiQXR0YWNobWVudCBmb3JtYXR0ZXIuIiwgQ05GRSwgRXJyb3JNYW5hZ2VyLk9QRU5fRkFJTFVSRSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYVtpXSA9IGNyZWF0ZVNpbXBsZUZvcm1hdHRlcigpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBTZWN1cml0eUV4Y2VwdGlvbiBTRSkgeworICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgU0U7IC8vQXZvaWQgY2F0Y2ggYWxsLgorICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBFeGNlcHRpb24gRSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoRS5nZXRNZXNzYWdlKCksIEUsIEVycm9yTWFuYWdlci5PUEVOX0ZBSUxVUkUpOworICAgICAgICAgICAgICAgICAgICAgICAgYVtpXSA9IGNyZWF0ZVNpbXBsZUZvcm1hdHRlcigpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgRXhjZXB0aW9uIE5QRSA9IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbihhdEluZGV4TXNnKGkpKTsKKyAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoIkF0dGFjaG1lbnQgZm9ybWF0dGVyLiIsIE5QRSwgRXJyb3JNYW5hZ2VyLk9QRU5fRkFJTFVSRSk7CisgICAgICAgICAgICAgICAgICAgIGFbaV0gPSBjcmVhdGVTaW1wbGVGb3JtYXR0ZXIoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRoaXMuYXR0YWNobWVudEZvcm1hdHRlcnMgPSBhOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhpcy5hdHRhY2htZW50Rm9ybWF0dGVycyA9IGVtcHR5Rm9ybWF0dGVyQXJyYXkoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlcyBMb2dNYW5hZ2VyIHN0cmluZyB2YWx1ZXMgaW50byBvYmplY3RzIHVzZWQgYnkgdGhpcyBoYW5kbGVyLgorICAgICAqIEBwYXJhbSBwIHRoZSBoYW5kbGVyIGNsYXNzIG5hbWUgdXNlZCBhcyB0aGUgcHJlZml4LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIGdpdmVuIGFyZ3VtZW50IGlzIG51bGwuCisgICAgICogQHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbiBpZiBub3QgYWxsb3dlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgaW5pdEF0dGFjaG1lbnROYW1lcyhmaW5hbCBTdHJpbmcgcCkgeworICAgICAgICBhc3NlcnQgVGhyZWFkLmhvbGRzTG9jayh0aGlzKTsKKyAgICAgICAgYXNzZXJ0IHRoaXMuYXR0YWNobWVudEZvcm1hdHRlcnMgIT0gbnVsbDsKKworICAgICAgICBmaW5hbCBTdHJpbmcgbGlzdCA9IGZyb21Mb2dNYW5hZ2VyKHAuY29uY2F0KCIuYXR0YWNobWVudC5uYW1lcyIpKTsKKyAgICAgICAgaWYgKCFpc0VtcHR5KGxpc3QpKSB7CisgICAgICAgICAgICBmaW5hbCBTdHJpbmdbXSBuYW1lcyA9IGxpc3Quc3BsaXQoIiwiKTsKKyAgICAgICAgICAgIGZpbmFsIEZvcm1hdHRlcltdIGEgPSBuZXcgRm9ybWF0dGVyW25hbWVzLmxlbmd0aF07CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGEubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgICAgICBuYW1lc1tpXSA9IG5hbWVzW2ldLnRyaW0oKTsKKyAgICAgICAgICAgICAgICBpZiAoISJudWxsIi5lcXVhbHNJZ25vcmVDYXNlKG5hbWVzW2ldKSkgeworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBhW2ldID0gTG9nTWFuYWdlclByb3BlcnRpZXMubmV3Rm9ybWF0dGVyKG5hbWVzW2ldKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBDbGFzc0Nhc3RFeGNlcHRpb24gbGl0ZXJhbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFbaV0gPSBUYWlsTmFtZUZvcm1hdHRlci5vZihuYW1lc1tpXSk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGZpbmFsIFNlY3VyaXR5RXhjZXB0aW9uIFNFKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBTRTsgLy9Bdm9pZCBjYXRjaCBhbGwuCisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGZpbmFsIEV4Y2VwdGlvbiBFKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRFcnJvcihFLmdldE1lc3NhZ2UoKSwgRSwgRXJyb3JNYW5hZ2VyLk9QRU5fRkFJTFVSRSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBmaW5hbCBFeGNlcHRpb24gTlBFID0gbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKGF0SW5kZXhNc2coaSkpOworICAgICAgICAgICAgICAgICAgICByZXBvcnRFcnJvcigiQXR0YWNobWVudCBuYW1lcy4iLCBOUEUsIEVycm9yTWFuYWdlci5PUEVOX0ZBSUxVUkUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdGhpcy5hdHRhY2htZW50TmFtZXMgPSBhOworICAgICAgICAgICAgaWYgKGFsaWduQXR0YWNobWVudE5hbWVzKCkpIHsgLy9BbnkgbnVsbCBpbmRleGVzIGFyZSByZXBhaXJlZC4KKyAgICAgICAgICAgICAgICByZXBvcnRFcnJvcigiQXR0YWNobWVudCBuYW1lcy4iLAorICAgICAgICAgICAgICAgICAgICAgICAgYXR0YWNobWVudE1pc21hdGNoKCJMZW5ndGggbWlzbWF0Y2guIiksIEVycm9yTWFuYWdlci5PUEVOX0ZBSUxVUkUpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhpcy5hdHRhY2htZW50TmFtZXMgPSBlbXB0eUZvcm1hdHRlckFycmF5KCk7CisgICAgICAgICAgICBhbGlnbkF0dGFjaG1lbnROYW1lcygpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2VzIExvZ01hbmFnZXIgc3RyaW5nIHZhbHVlcyBpbnRvIG9iamVjdHMgdXNlZCBieSB0aGlzIGhhbmRsZXIuCisgICAgICogQHBhcmFtIHAgdGhlIGhhbmRsZXIgY2xhc3MgbmFtZSB1c2VkIGFzIHRoZSBwcmVmaXguCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgZ2l2ZW4gYXJndW1lbnQgaXMgbnVsbC4KKyAgICAgKiBAdGhyb3dzIFNlY3VyaXR5RXhjZXB0aW9uIGlmIG5vdCBhbGxvd2VkLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBpbml0QXV0aGVudGljYXRvcihmaW5hbCBTdHJpbmcgcCkgeworICAgICAgICBhc3NlcnQgVGhyZWFkLmhvbGRzTG9jayh0aGlzKTsKKyAgICAgICAgU3RyaW5nIG5hbWUgPSBmcm9tTG9nTWFuYWdlcihwLmNvbmNhdCgiLmF1dGhlbnRpY2F0b3IiKSk7CisgICAgICAgIGlmIChuYW1lICE9IG51bGwgJiYgISJudWxsIi5lcXVhbHNJZ25vcmVDYXNlKG5hbWUpKSB7CisgICAgICAgICAgICBpZiAobmFtZS5sZW5ndGgoKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgdGhpcy5hdXRoID0gTG9nTWFuYWdlclByb3BlcnRpZXMKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAubmV3T2JqZWN0RnJvbShuYW1lLCBBdXRoZW50aWNhdG9yLmNsYXNzKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBTZWN1cml0eUV4Y2VwdGlvbiBTRSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBTRTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uCisgICAgICAgICAgICAgICAgICAgICAgICB8IENsYXNzQ2FzdEV4Y2VwdGlvbiBsaXRlcmFsQXV0aCkgeworICAgICAgICAgICAgICAgICAgICB0aGlzLmF1dGggPSBEZWZhdWx0QXV0aGVudGljYXRvci5vZihuYW1lKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBFeGNlcHRpb24gRSkgeworICAgICAgICAgICAgICAgICAgICByZXBvcnRFcnJvcihFLmdldE1lc3NhZ2UoKSwgRSwgRXJyb3JNYW5hZ2VyLk9QRU5fRkFJTFVSRSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsgLy9BdXRoZW50aWNhdG9yIGlzIGluc3RhbGxlZCB0byBwcm92aWRlIHRoZSB1c2VyIG5hbWUuCisgICAgICAgICAgICAgICAgdGhpcy5hdXRoID0gRGVmYXVsdEF1dGhlbnRpY2F0b3Iub2YobmFtZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZXMgTG9nTWFuYWdlciBzdHJpbmcgdmFsdWVzIGludG8gb2JqZWN0cyB1c2VkIGJ5IHRoaXMgaGFuZGxlci4KKyAgICAgKiBAcGFyYW0gcCB0aGUgaGFuZGxlciBjbGFzcyBuYW1lIHVzZWQgYXMgdGhlIHByZWZpeC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBnaXZlbiBhcmd1bWVudCBpcyBudWxsLgorICAgICAqIEB0aHJvd3MgU2VjdXJpdHlFeGNlcHRpb24gaWYgbm90IGFsbG93ZWQuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGluaXRMZXZlbChmaW5hbCBTdHJpbmcgcCkgeworICAgICAgICBhc3NlcnQgVGhyZWFkLmhvbGRzTG9jayh0aGlzKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZpbmFsIFN0cmluZyB2YWwgPSBmcm9tTG9nTWFuYWdlcihwLmNvbmNhdCgiLmxldmVsIikpOworICAgICAgICAgICAgaWYgKHZhbCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgbG9nTGV2ZWwgPSBMZXZlbC5wYXJzZSh2YWwpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBsb2dMZXZlbCA9IExldmVsLldBUk5JTkc7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIFNlY3VyaXR5RXhjZXB0aW9uIFNFKSB7CisgICAgICAgICAgICAgdGhyb3cgU0U7IC8vQXZvaWQgY2F0Y2ggYWxsLgorICAgICAgICB9IGNhdGNoIChmaW5hbCBSdW50aW1lRXhjZXB0aW9uIFJFKSB7CisgICAgICAgICAgICByZXBvcnRFcnJvcihSRS5nZXRNZXNzYWdlKCksIFJFLCBFcnJvck1hbmFnZXIuT1BFTl9GQUlMVVJFKTsKKyAgICAgICAgICAgIGxvZ0xldmVsID0gTGV2ZWwuV0FSTklORzsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlcyBMb2dNYW5hZ2VyIHN0cmluZyB2YWx1ZXMgaW50byBvYmplY3RzIHVzZWQgYnkgdGhpcyBoYW5kbGVyLgorICAgICAqIEBwYXJhbSBwIHRoZSBoYW5kbGVyIGNsYXNzIG5hbWUgdXNlZCBhcyB0aGUgcHJlZml4LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIGdpdmVuIGFyZ3VtZW50IGlzIG51bGwuCisgICAgICogQHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbiBpZiBub3QgYWxsb3dlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgaW5pdEZpbHRlcihmaW5hbCBTdHJpbmcgcCkgeworICAgICAgICBhc3NlcnQgVGhyZWFkLmhvbGRzTG9jayh0aGlzKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyBuYW1lID0gZnJvbUxvZ01hbmFnZXIocC5jb25jYXQoIi5maWx0ZXIiKSk7CisgICAgICAgICAgICBpZiAoaGFzVmFsdWUobmFtZSkpIHsKKyAgICAgICAgICAgICAgICBmaWx0ZXIgPSBMb2dNYW5hZ2VyUHJvcGVydGllcy5uZXdGaWx0ZXIobmFtZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIFNlY3VyaXR5RXhjZXB0aW9uIFNFKSB7CisgICAgICAgICAgICB0aHJvdyBTRTsgLy9Bdm9pZCBjYXRjaCBhbGwuCisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIEV4Y2VwdGlvbiBFKSB7CisgICAgICAgICAgICByZXBvcnRFcnJvcihFLmdldE1lc3NhZ2UoKSwgRSwgRXJyb3JNYW5hZ2VyLk9QRU5fRkFJTFVSRSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZXMgTG9nTWFuYWdlciBzdHJpbmcgdmFsdWVzIGludG8gb2JqZWN0cyB1c2VkIGJ5IHRoaXMgaGFuZGxlci4KKyAgICAgKiBAcGFyYW0gcCB0aGUgaGFuZGxlciBjbGFzcyBuYW1lIHVzZWQgYXMgdGhlIHByZWZpeC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIGFyZ3VtZW50IGlzIG51bGwuCisgICAgICogQHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbiBpZiBub3QgYWxsb3dlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgaW5pdENhcGFjaXR5KGZpbmFsIFN0cmluZyBwKSB7CisgICAgICAgIGFzc2VydCBUaHJlYWQuaG9sZHNMb2NrKHRoaXMpOworICAgICAgICBmaW5hbCBpbnQgREVGQVVMVF9DQVBBQ0lUWSA9IDEwMDA7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaW5hbCBTdHJpbmcgdmFsdWUgPSBmcm9tTG9nTWFuYWdlcihwLmNvbmNhdCgiLmNhcGFjaXR5IikpOworICAgICAgICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aGlzLnNldENhcGFjaXR5MChJbnRlZ2VyLnBhcnNlSW50KHZhbHVlKSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHRoaXMuc2V0Q2FwYWNpdHkwKERFRkFVTFRfQ0FQQUNJVFkpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChmaW5hbCBTZWN1cml0eUV4Y2VwdGlvbiBTRSkgeworICAgICAgICAgICAgdGhyb3cgU0U7IC8vQXZvaWQgY2F0Y2ggYWxsLgorICAgICAgICB9IGNhdGNoIChmaW5hbCBSdW50aW1lRXhjZXB0aW9uIFJFKSB7CisgICAgICAgICAgICByZXBvcnRFcnJvcihSRS5nZXRNZXNzYWdlKCksIFJFLCBFcnJvck1hbmFnZXIuT1BFTl9GQUlMVVJFKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChjYXBhY2l0eSA8PSAwKSB7CisgICAgICAgICAgICBjYXBhY2l0eSA9IERFRkFVTFRfQ0FQQUNJVFk7CisgICAgICAgIH0KKworICAgICAgICB0aGlzLmRhdGEgPSBuZXcgTG9nUmVjb3JkWzFdOworICAgICAgICB0aGlzLm1hdGNoZWQgPSBuZXcgaW50W3RoaXMuZGF0YS5sZW5ndGhdOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlcyBMb2dNYW5hZ2VyIHN0cmluZyB2YWx1ZXMgaW50byBvYmplY3RzIHVzZWQgYnkgdGhpcyBoYW5kbGVyLgorICAgICAqIEBwYXJhbSBwIHRoZSBoYW5kbGVyIGNsYXNzIG5hbWUgdXNlZCBhcyB0aGUgcHJlZml4LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIGdpdmVuIGFyZ3VtZW50IGlzIG51bGwuCisgICAgICogQHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbiBpZiBub3QgYWxsb3dlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgaW5pdEVuY29kaW5nKGZpbmFsIFN0cmluZyBwKSB7CisgICAgICAgIGFzc2VydCBUaHJlYWQuaG9sZHNMb2NrKHRoaXMpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIGUgPSBmcm9tTG9nTWFuYWdlcihwLmNvbmNhdCgiLmVuY29kaW5nIikpOworICAgICAgICAgICAgaWYgKGUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHNldEVuY29kaW5nMChlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoZmluYWwgU2VjdXJpdHlFeGNlcHRpb24gU0UpIHsKKyAgICAgICAgICAgIHRocm93IFNFOyAvL0F2b2lkIGNhdGNoIGFsbC4KKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiB8IFJ1bnRpbWVFeGNlcHRpb24gVUVFKSB7CisgICAgICAgICAgICByZXBvcnRFcnJvcihVRUUuZ2V0TWVzc2FnZSgpLCBVRUUsIEVycm9yTWFuYWdlci5PUEVOX0ZBSUxVUkUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVXNlZCB0byBnZXQgb3IgY3JlYXRlIHRoZSBkZWZhdWx0IEVycm9yTWFuYWdlciB1c2VkIGJlZm9yZSBpbml0LgorICAgICAqIEByZXR1cm4gdGhlIHN1cGVyIGVycm9yIG1hbmFnZXIgb3IgYSBuZXcgRXJyb3JNYW5hZ2VyLgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjUuMworICAgICAqLworICAgIHByaXZhdGUgRXJyb3JNYW5hZ2VyIGRlZmF1bHRFcnJvck1hbmFnZXIoKSB7CisgICAgICAgIEVycm9yTWFuYWdlciBlbTsKKyAgICAgICAgdHJ5IHsgLy9UcnkgdG8gc2hhcmUgdGhlIHN1cGVyIGVycm9yIG1hbmFnZXIuCisgICAgICAgICAgICBlbSA9IHN1cGVyLmdldEVycm9yTWFuYWdlcigpOworICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHwgTGlua2FnZUVycm9yIGlnbm9yZSkgeworICAgICAgICAgICAgZW0gPSBudWxsOworICAgICAgICB9CisKKyAgICAgICAgLy9Eb24ndCBhc3N1bWUgdGhhdCB0aGUgc3VwZXIgY2FsbCBpcyBub3QgbnVsbC4KKyAgICAgICAgaWYgKGVtID09IG51bGwpIHsKKyAgICAgICAgICAgIGVtID0gbmV3IEVycm9yTWFuYWdlcigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBlbTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZXMgTG9nTWFuYWdlciBzdHJpbmcgdmFsdWVzIGludG8gb2JqZWN0cyB1c2VkIGJ5IHRoaXMgaGFuZGxlci4KKyAgICAgKiBAcGFyYW0gcCB0aGUgaGFuZGxlciBjbGFzcyBuYW1lIHVzZWQgYXMgdGhlIHByZWZpeC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBnaXZlbiBhcmd1bWVudCBpcyBudWxsLgorICAgICAqIEB0aHJvd3MgU2VjdXJpdHlFeGNlcHRpb24gaWYgbm90IGFsbG93ZWQuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGluaXRFcnJvck1hbmFnZXIoZmluYWwgU3RyaW5nIHApIHsKKyAgICAgICAgYXNzZXJ0IFRocmVhZC5ob2xkc0xvY2sodGhpcyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcgbmFtZSA9IGZyb21Mb2dNYW5hZ2VyKHAuY29uY2F0KCIuZXJyb3JNYW5hZ2VyIikpOworICAgICAgICAgICAgaWYgKG5hbWUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHNldEVycm9yTWFuYWdlcjAoTG9nTWFuYWdlclByb3BlcnRpZXMubmV3RXJyb3JNYW5hZ2VyKG5hbWUpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoZmluYWwgU2VjdXJpdHlFeGNlcHRpb24gU0UpIHsKKyAgICAgICAgICAgIHRocm93IFNFOyAvL0F2b2lkIGNhdGNoIGFsbC4KKyAgICAgICAgfSBjYXRjaCAoZmluYWwgRXhjZXB0aW9uIEUpIHsKKyAgICAgICAgICAgIHJlcG9ydEVycm9yKEUuZ2V0TWVzc2FnZSgpLCBFLCBFcnJvck1hbmFnZXIuT1BFTl9GQUlMVVJFKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlcyBMb2dNYW5hZ2VyIHN0cmluZyB2YWx1ZXMgaW50byBvYmplY3RzIHVzZWQgYnkgdGhpcyBoYW5kbGVyLgorICAgICAqIEBwYXJhbSBwIHRoZSBoYW5kbGVyIGNsYXNzIG5hbWUgdXNlZCBhcyB0aGUgcHJlZml4LgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIGdpdmVuIGFyZ3VtZW50IGlzIG51bGwuCisgICAgICogQHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbiBpZiBub3QgYWxsb3dlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgaW5pdEZvcm1hdHRlcihmaW5hbCBTdHJpbmcgcCkgeworICAgICAgICBhc3NlcnQgVGhyZWFkLmhvbGRzTG9jayh0aGlzKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyBuYW1lID0gZnJvbUxvZ01hbmFnZXIocC5jb25jYXQoIi5mb3JtYXR0ZXIiKSk7CisgICAgICAgICAgICBpZiAoaGFzVmFsdWUobmFtZSkpIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBGb3JtYXR0ZXIgZgorICAgICAgICAgICAgICAgICAgICAgICAgPSBMb2dNYW5hZ2VyUHJvcGVydGllcy5uZXdGb3JtYXR0ZXIobmFtZSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0IGYgIT0gbnVsbDsKKyAgICAgICAgICAgICAgICBpZiAoZiBpbnN0YW5jZW9mIFRhaWxOYW1lRm9ybWF0dGVyID09IGZhbHNlKSB7CisgICAgICAgICAgICAgICAgICAgIGZvcm1hdHRlciA9IGY7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgZm9ybWF0dGVyID0gY3JlYXRlU2ltcGxlRm9ybWF0dGVyKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBmb3JtYXR0ZXIgPSBjcmVhdGVTaW1wbGVGb3JtYXR0ZXIoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoZmluYWwgU2VjdXJpdHlFeGNlcHRpb24gU0UpIHsKKyAgICAgICAgICAgIHRocm93IFNFOyAvL0F2b2lkIGNhdGNoIGFsbC4KKyAgICAgICAgfSBjYXRjaCAoZmluYWwgRXhjZXB0aW9uIEUpIHsKKyAgICAgICAgICAgIHJlcG9ydEVycm9yKEUuZ2V0TWVzc2FnZSgpLCBFLCBFcnJvck1hbmFnZXIuT1BFTl9GQUlMVVJFKTsKKyAgICAgICAgICAgIGZvcm1hdHRlciA9IGNyZWF0ZVNpbXBsZUZvcm1hdHRlcigpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2VzIExvZ01hbmFnZXIgc3RyaW5nIHZhbHVlcyBpbnRvIG9iamVjdHMgdXNlZCBieSB0aGlzIGhhbmRsZXIuCisgICAgICogQHBhcmFtIHAgdGhlIGhhbmRsZXIgY2xhc3MgbmFtZSB1c2VkIGFzIHRoZSBwcmVmaXguCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgZ2l2ZW4gYXJndW1lbnQgaXMgbnVsbC4KKyAgICAgKiBAdGhyb3dzIFNlY3VyaXR5RXhjZXB0aW9uIGlmIG5vdCBhbGxvd2VkLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBpbml0Q29tcGFyYXRvcihmaW5hbCBTdHJpbmcgcCkgeworICAgICAgICBhc3NlcnQgVGhyZWFkLmhvbGRzTG9jayh0aGlzKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyBuYW1lID0gZnJvbUxvZ01hbmFnZXIocC5jb25jYXQoIi5jb21wYXJhdG9yIikpOworICAgICAgICAgICAgU3RyaW5nIHJldmVyc2UgPSBmcm9tTG9nTWFuYWdlcihwLmNvbmNhdCgiLmNvbXBhcmF0b3IucmV2ZXJzZSIpKTsKKyAgICAgICAgICAgIGlmIChoYXNWYWx1ZShuYW1lKSkgeworICAgICAgICAgICAgICAgIGNvbXBhcmF0b3IgPSBMb2dNYW5hZ2VyUHJvcGVydGllcy5uZXdDb21wYXJhdG9yKG5hbWUpOworICAgICAgICAgICAgICAgIGlmIChCb29sZWFuLnBhcnNlQm9vbGVhbihyZXZlcnNlKSkgeworICAgICAgICAgICAgICAgICAgICBhc3NlcnQgY29tcGFyYXRvciAhPSBudWxsIDogIm51bGwiOworICAgICAgICAgICAgICAgICAgICBjb21wYXJhdG9yID0gTG9nTWFuYWdlclByb3BlcnRpZXMucmV2ZXJzZU9yZGVyKGNvbXBhcmF0b3IpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgaWYgKCFpc0VtcHR5KHJldmVyc2UpKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5vIGNvbXBhcmF0b3IgdG8gcmV2ZXJzZS4iKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIFNlY3VyaXR5RXhjZXB0aW9uIFNFKSB7CisgICAgICAgICAgICB0aHJvdyBTRTsgLy9Bdm9pZCBjYXRjaCBhbGwuCisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIEV4Y2VwdGlvbiBFKSB7CisgICAgICAgICAgICByZXBvcnRFcnJvcihFLmdldE1lc3NhZ2UoKSwgRSwgRXJyb3JNYW5hZ2VyLk9QRU5fRkFJTFVSRSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZXMgTG9nTWFuYWdlciBzdHJpbmcgdmFsdWVzIGludG8gb2JqZWN0cyB1c2VkIGJ5IHRoaXMgaGFuZGxlci4KKyAgICAgKiBAcGFyYW0gcCB0aGUgaGFuZGxlciBjbGFzcyBuYW1lIHVzZWQgYXMgdGhlIHByZWZpeC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBnaXZlbiBhcmd1bWVudCBpcyBudWxsLgorICAgICAqIEB0aHJvd3MgU2VjdXJpdHlFeGNlcHRpb24gaWYgbm90IGFsbG93ZWQuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGluaXRQdXNoTGV2ZWwoZmluYWwgU3RyaW5nIHApIHsKKyAgICAgICAgYXNzZXJ0IFRocmVhZC5ob2xkc0xvY2sodGhpcyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaW5hbCBTdHJpbmcgdmFsID0gZnJvbUxvZ01hbmFnZXIocC5jb25jYXQoIi5wdXNoTGV2ZWwiKSk7CisgICAgICAgICAgICBpZiAodmFsICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aGlzLnB1c2hMZXZlbCA9IExldmVsLnBhcnNlKHZhbCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIFJ1bnRpbWVFeGNlcHRpb24gUkUpIHsKKyAgICAgICAgICAgIHJlcG9ydEVycm9yKFJFLmdldE1lc3NhZ2UoKSwgUkUsIEVycm9yTWFuYWdlci5PUEVOX0ZBSUxVUkUpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHRoaXMucHVzaExldmVsID09IG51bGwpIHsKKyAgICAgICAgICAgIHRoaXMucHVzaExldmVsID0gTGV2ZWwuT0ZGOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2VzIExvZ01hbmFnZXIgc3RyaW5nIHZhbHVlcyBpbnRvIG9iamVjdHMgdXNlZCBieSB0aGlzIGhhbmRsZXIuCisgICAgICogQHBhcmFtIHAgdGhlIGhhbmRsZXIgY2xhc3MgbmFtZSB1c2VkIGFzIHRoZSBwcmVmaXguCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgZ2l2ZW4gYXJndW1lbnQgaXMgbnVsbC4KKyAgICAgKiBAdGhyb3dzIFNlY3VyaXR5RXhjZXB0aW9uIGlmIG5vdCBhbGxvd2VkLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBpbml0UHVzaEZpbHRlcihmaW5hbCBTdHJpbmcgcCkgeworICAgICAgICBhc3NlcnQgVGhyZWFkLmhvbGRzTG9jayh0aGlzKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyBuYW1lID0gZnJvbUxvZ01hbmFnZXIocC5jb25jYXQoIi5wdXNoRmlsdGVyIikpOworICAgICAgICAgICAgaWYgKGhhc1ZhbHVlKG5hbWUpKSB7CisgICAgICAgICAgICAgICAgdGhpcy5wdXNoRmlsdGVyID0gTG9nTWFuYWdlclByb3BlcnRpZXMubmV3RmlsdGVyKG5hbWUpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChmaW5hbCBTZWN1cml0eUV4Y2VwdGlvbiBTRSkgeworICAgICAgICAgICAgdGhyb3cgU0U7IC8vQXZvaWQgY2F0Y2ggYWxsLgorICAgICAgICB9IGNhdGNoIChmaW5hbCBFeGNlcHRpb24gRSkgeworICAgICAgICAgICAgcmVwb3J0RXJyb3IoRS5nZXRNZXNzYWdlKCksIEUsIEVycm9yTWFuYWdlci5PUEVOX0ZBSUxVUkUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2VzIExvZ01hbmFnZXIgc3RyaW5nIHZhbHVlcyBpbnRvIG9iamVjdHMgdXNlZCBieSB0aGlzIGhhbmRsZXIuCisgICAgICogQHBhcmFtIHAgdGhlIGhhbmRsZXIgY2xhc3MgbmFtZSB1c2VkIGFzIHRoZSBwcmVmaXguCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgZ2l2ZW4gYXJndW1lbnQgaXMgbnVsbC4KKyAgICAgKiBAdGhyb3dzIFNlY3VyaXR5RXhjZXB0aW9uIGlmIG5vdCBhbGxvd2VkLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBpbml0U3ViamVjdChmaW5hbCBTdHJpbmcgcCkgeworICAgICAgICBhc3NlcnQgVGhyZWFkLmhvbGRzTG9jayh0aGlzKTsKKyAgICAgICAgU3RyaW5nIG5hbWUgPSBmcm9tTG9nTWFuYWdlcihwLmNvbmNhdCgiLnN1YmplY3QiKSk7CisgICAgICAgIGlmIChuYW1lID09IG51bGwpIHsgLy9Tb2Z0IGRlcGVuZGVuY3kgb24gQ29sbGVjdG9yRm9ybWF0dGVyLgorICAgICAgICAgICAgbmFtZSA9ICJjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nLkNvbGxlY3RvckZvcm1hdHRlciI7CisgICAgICAgIH0KKworICAgICAgICBpZiAoaGFzVmFsdWUobmFtZSkpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgdGhpcy5zdWJqZWN0Rm9ybWF0dGVyID0gTG9nTWFuYWdlclByb3BlcnRpZXMubmV3Rm9ybWF0dGVyKG5hbWUpOworICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgU2VjdXJpdHlFeGNlcHRpb24gU0UpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBTRTsgLy9Bdm9pZCBjYXRjaCBhbGwuCisgICAgICAgICAgICB9IGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uCisgICAgICAgICAgICAgICAgICAgIHwgQ2xhc3NDYXN0RXhjZXB0aW9uIGxpdGVyYWxTdWJqZWN0KSB7CisgICAgICAgICAgICAgICAgdGhpcy5zdWJqZWN0Rm9ybWF0dGVyID0gVGFpbE5hbWVGb3JtYXR0ZXIub2YobmFtZSk7CisgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBFeGNlcHRpb24gRSkgeworICAgICAgICAgICAgICAgIHRoaXMuc3ViamVjdEZvcm1hdHRlciA9IFRhaWxOYW1lRm9ybWF0dGVyLm9mKG5hbWUpOworICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKEUuZ2V0TWVzc2FnZSgpLCBFLCBFcnJvck1hbmFnZXIuT1BFTl9GQUlMVVJFKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsgLy9Vc2VyIGhhcyBmb3JjZWQgZW1wdHkgb3IgbGl0ZXJhbCBudWxsLgorICAgICAgICAgICAgdGhpcy5zdWJqZWN0Rm9ybWF0dGVyID0gVGFpbE5hbWVGb3JtYXR0ZXIub2YobmFtZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVjayBpZiBhbnkgYXR0YWNobWVudCB3b3VsZCBhY3R1YWxseSBmb3JtYXQgdGhlIGdpdmVuCisgICAgICogPHR0PkxvZ1JlY29yZDwvdHQ+LiAgVGhpcyBtZXRob2QgZG9lcyBub3QgY2hlY2sgaWYgdGhlIGhhbmRsZXIKKyAgICAgKiBpcyBsZXZlbCBpcyBzZXQgdG8gT0ZGIG9yIGlmIHRoZSBoYW5kbGVyIGlzIGNsb3NlZC4KKyAgICAgKiBAcGFyYW0gcmVjb3JkICBhIDx0dD5Mb2dSZWNvcmQ8L3R0PgorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgPHR0PkxvZ1JlY29yZDwvdHQ+IHdvdWxkIGJlIGZvcm1hdHRlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gaXNBdHRhY2htZW50TG9nZ2FibGUoZmluYWwgTG9nUmVjb3JkIHJlY29yZCkgeworICAgICAgICBmaW5hbCBGaWx0ZXJbXSBmaWx0ZXJzID0gcmVhZE9ubHlBdHRhY2htZW50RmlsdGVycygpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbHRlcnMubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgIGZpbmFsIEZpbHRlciBmID0gZmlsdGVyc1tpXTsKKyAgICAgICAgICAgIGlmIChmID09IG51bGwgfHwgZi5pc0xvZ2dhYmxlKHJlY29yZCkpIHsKKyAgICAgICAgICAgICAgICBzZXRNYXRjaGVkUGFydChpKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2sgaWYgdGhpcyA8dHQ+SGFuZGxlcjwvdHQ+IHdvdWxkIHB1c2ggYWZ0ZXIgc3RvcmluZyB0aGUKKyAgICAgKiA8dHQ+TG9nUmVjb3JkPC90dD4gaW50byBpdHMgaW50ZXJuYWwgYnVmZmVyLgorICAgICAqIEBwYXJhbSByZWNvcmQgIGEgPHR0PkxvZ1JlY29yZDwvdHQ+CisgICAgICogQHJldHVybiB0cnVlIGlmIHRoZSA8dHQ+TG9nUmVjb3JkPC90dD4gdHJpZ2dlcnMgYW4gZW1haWwgcHVzaC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRyeU11dGV4IHdhcyBub3QgY2FsbGVkLgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBpc1B1c2hhYmxlKGZpbmFsIExvZ1JlY29yZCByZWNvcmQpIHsKKyAgICAgICAgYXNzZXJ0IFRocmVhZC5ob2xkc0xvY2sodGhpcyk7CisgICAgICAgIGZpbmFsIGludCB2YWx1ZSA9IGdldFB1c2hMZXZlbCgpLmludFZhbHVlKCk7CisgICAgICAgIGlmICh2YWx1ZSA9PSBvZmZWYWx1ZSB8fCByZWNvcmQuZ2V0TGV2ZWwoKS5pbnRWYWx1ZSgpIDwgdmFsdWUpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIEZpbHRlciBwdXNoID0gZ2V0UHVzaEZpbHRlcigpOworICAgICAgICBpZiAocHVzaCA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIGludCBtYXRjaCA9IGdldE1hdGNoZWRQYXJ0KCk7CisgICAgICAgIGlmICgobWF0Y2ggPT0gLTEgJiYgZ2V0RmlsdGVyKCkgPT0gcHVzaCkKKyAgICAgICAgICAgICAgICB8fCAobWF0Y2ggPj0gMCAmJiBhdHRhY2htZW50RmlsdGVyc1ttYXRjaF0gPT0gcHVzaCkpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIHB1c2guaXNMb2dnYWJsZShyZWNvcmQpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVXNlZCB0byBwZXJmb3JtIHB1c2ggb3IgZmx1c2guCisgICAgICogQHBhcmFtIHByaW9yaXR5IHRydWUgZm9yIGhpZ2ggcHJpb3JpdHkgb3RoZXJ3aXNlIGZhbHNlIGZvciBub3JtYWwuCisgICAgICogQHBhcmFtIGNvZGUgdGhlIGVycm9yIG1hbmFnZXIgY29kZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcHVzaChmaW5hbCBib29sZWFuIHByaW9yaXR5LCBmaW5hbCBpbnQgY29kZSkgeworICAgICAgICBpZiAodHJ5TXV0ZXgoKSkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBmaW5hbCBNZXNzYWdlIG1zZyA9IHdyaXRlTG9nUmVjb3Jkcyhjb2RlKTsKKyAgICAgICAgICAgICAgICBpZiAobXNnICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgc2VuZChtc2csIHByaW9yaXR5LCBjb2RlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBMaW5rYWdlRXJyb3IgSkRLODE1MjUxNSkgeworICAgICAgICAgICAgICAgIHJlcG9ydExpbmthZ2VFcnJvcihKREs4MTUyNTE1LCBjb2RlKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgcmVsZWFzZU11dGV4KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXBvcnRVblB1Ymxpc2hlZEVycm9yKG51bGwpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVXNlZCB0byBzZW5kIHRoZSBnZW5lcmF0ZWQgZW1haWwgb3Igd3JpdGUgaXRzIGNvbnRlbnRzIHRvIHRoZQorICAgICAqIGVycm9yIG1hbmFnZXIgZm9yIHRoaXMgaGFuZGxlci4gIFRoaXMgbWV0aG9kIGRvZXMgbm90IGhvbGQgYW55CisgICAgICogbG9ja3Mgc28gbmV3IHJlY29yZHMgY2FuIGJlIGFkZGVkIHRvIHRoaXMgaGFuZGxlciBkdXJpbmcgYSBzZW5kIG9yCisgICAgICogZmFpbHVyZS4KKyAgICAgKiBAcGFyYW0gbXNnIHRoZSBtZXNzYWdlIG9yIG51bGwuCisgICAgICogQHBhcmFtIHByaW9yaXR5IHRydWUgZm9yIGhpZ2ggcHJpb3JpdHkgb3IgZmFsc2UgZm9yIG5vcm1hbC4KKyAgICAgKiBAcGFyYW0gY29kZSB0aGUgRXJyb3JNYW5hZ2VyIGNvZGUuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiBtZXNzYWdlIGlzIG51bGwuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHNlbmQoTWVzc2FnZSBtc2csIGJvb2xlYW4gcHJpb3JpdHksIGludCBjb2RlKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlbnZlbG9wZUZvcihtc2csIHByaW9yaXR5KTsKKyAgICAgICAgICAgIGZpbmFsIE9iamVjdCBjY2wgPSBnZXRBbmRTZXRDb250ZXh0Q2xhc3NMb2FkZXIoTUFJTEhBTkRMRVJfTE9BREVSKTsKKyAgICAgICAgICAgIHRyeSB7ICAvL0pESy04MDI1MjUxCisgICAgICAgICAgICAgICAgVHJhbnNwb3J0LnNlbmQobXNnKTsgLy9DYWxscyBzYXZlIGNoYW5nZXMuCisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIGdldEFuZFNldENvbnRleHRDbGFzc0xvYWRlcihjY2wpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChmaW5hbCBSdW50aW1lRXhjZXB0aW9uIHJlKSB7CisgICAgICAgICAgICByZXBvcnRFcnJvcihtc2csIHJlLCBjb2RlKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHJlcG9ydEVycm9yKG1zZywgZSwgY29kZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIHNvcnQgb24gdGhlIHJlY29yZHMgaWYgbmVlZGVkLgorICAgICAqIEFueSBleGNlcHRpb24gdGhyb3duIGR1cmluZyBhIHNvcnQgaXMgY29uc2lkZXJlZCBhIGZvcm1hdHRpbmcgZXJyb3IuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHNvcnQoKSB7CisgICAgICAgIGFzc2VydCBUaHJlYWQuaG9sZHNMb2NrKHRoaXMpOworICAgICAgICBpZiAoY29tcGFyYXRvciAhPSBudWxsKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGlmIChzaXplICE9IDEpIHsKKyAgICAgICAgICAgICAgICAgICAgQXJyYXlzLnNvcnQoZGF0YSwgMCwgc2l6ZSwgY29tcGFyYXRvcik7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGNvbXBhcmF0b3IuY29tcGFyZShkYXRhWzBdLCBkYXRhWzBdKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wYXJhdG9yLmdldENsYXNzKCkuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gY2F0Y2ggKGZpbmFsIFJ1bnRpbWVFeGNlcHRpb24gUkUpIHsKKyAgICAgICAgICAgICAgICByZXBvcnRFcnJvcihSRS5nZXRNZXNzYWdlKCksIFJFLCBFcnJvck1hbmFnZXIuRk9STUFUX0ZBSUxVUkUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRm9ybWF0cyBhbGwgcmVjb3JkcyBpbiB0aGUgYnVmZmVyIGFuZCBwbGFjZXMgdGhlIG91dHB1dCBpbiBhIE1lc3NhZ2UuCisgICAgICogVGhpcyBtZXRob2QgdW5kZXIgbW9zdCBjb25kaXRpb25zIHdpbGwgY2F0Y2gsIHJlcG9ydCwgYW5kIGNvbnRpbnVlIHdoZW4KKyAgICAgKiBleGNlcHRpb25zIG9jY3VyLiAgVGhpcyBtZXRob2QgaG9sZHMgYSBsb2NrIG9uIHRoaXMgaGFuZGxlci4KKyAgICAgKiBAcGFyYW0gY29kZSB0aGUgZXJyb3IgbWFuYWdlciBjb2RlLgorICAgICAqIEByZXR1cm4gbnVsbCBpZiB0aGVyZSBhcmUgbm8gcmVjb3JkcyBvciBpcyBjdXJyZW50bHkgaW4gYSBwdXNoLgorICAgICAqIE90aGVyd2lzZSBhIG5ldyBtZXNzYWdlIGlzIGNyZWF0ZWQgd2l0aCBhIGZvcm1hdHRlZCBtZXNzYWdlIGFuZAorICAgICAqIGF0dGFjaGVkIHNlc3Npb24uCisgICAgICovCisgICAgcHJpdmF0ZSBNZXNzYWdlIHdyaXRlTG9nUmVjb3JkcyhmaW5hbCBpbnQgY29kZSkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgc3luY2hyb25pemVkICh0aGlzKSB7CisgICAgICAgICAgICAgICAgaWYgKHNpemUgPiAwICYmICFpc1dyaXRpbmcpIHsKKyAgICAgICAgICAgICAgICAgICAgaXNXcml0aW5nID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB3cml0ZUxvZ1JlY29yZHMwKCk7CisgICAgICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpc1dyaXRpbmcgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzaXplID4gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc2V0KCk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIFJ1bnRpbWVFeGNlcHRpb24gcmUpIHsKKyAgICAgICAgICAgIHJlcG9ydEVycm9yKHJlLmdldE1lc3NhZ2UoKSwgcmUsIGNvZGUpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgcmVwb3J0RXJyb3IoZS5nZXRNZXNzYWdlKCksIGUsIGNvZGUpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZvcm1hdHMgYWxsIHJlY29yZHMgaW4gdGhlIGJ1ZmZlciBhbmQgcGxhY2VzIHRoZSBvdXRwdXQgaW4gYSBNZXNzYWdlLgorICAgICAqIFRoaXMgbWV0aG9kIHVuZGVyIG1vc3QgY29uZGl0aW9ucyB3aWxsIGNhdGNoLCByZXBvcnQsIGFuZCBjb250aW51ZSB3aGVuCisgICAgICogZXhjZXB0aW9ucyBvY2N1ci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gbnVsbCBpZiB0aGVyZSBhcmUgbm8gcmVjb3JkcyBvciBpcyBjdXJyZW50bHkgaW4gYSBwdXNoLiBPdGhlcndpc2UKKyAgICAgKiBhIG5ldyBtZXNzYWdlIGlzIGNyZWF0ZWQgd2l0aCBhIGZvcm1hdHRlZCBtZXNzYWdlIGFuZCBhdHRhY2hlZCBzZXNzaW9uLgorICAgICAqIEB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIGlmIHRoZXJlIGlzIGEgcHJvYmxlbS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHRoZXJlIGlzIGEgcHJvYmxlbS4KKyAgICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gaWYgdGhlcmUgaXMgYW4gdW5leHBlY3RlZCBwcm9ibGVtLgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjUuMworICAgICAqLworICAgIHByaXZhdGUgTWVzc2FnZSB3cml0ZUxvZ1JlY29yZHMwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydCBUaHJlYWQuaG9sZHNMb2NrKHRoaXMpOworICAgICAgICBzb3J0KCk7CisgICAgICAgIGlmIChzZXNzaW9uID09IG51bGwpIHsKKyAgICAgICAgICAgIGluaXRTZXNzaW9uKCk7CisgICAgICAgIH0KKyAgICAgICAgTWltZU1lc3NhZ2UgbXNnID0gbmV3IE1pbWVNZXNzYWdlKHNlc3Npb24pOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBQYXJ0cyBhcmUgbGF6aWx5IGNyZWF0ZWQgd2hlbiBhbiBhdHRhY2htZW50IHBlcmZvcm1zIGEgZ2V0SGVhZAorICAgICAgICAgKiBjYWxsLiAgVGhlcmVmb3JlLCBhIG51bGwgcGFydCBhdCBhbiBpbmRleCBtZWFucyB0aGF0IHRoZSBoZWFkIGlzCisgICAgICAgICAqIHJlcXVpcmVkLgorICAgICAgICAgKi8KKyAgICAgICAgTWltZUJvZHlQYXJ0W10gcGFydHMgPSBuZXcgTWltZUJvZHlQYXJ0W2F0dGFjaG1lbnRGb3JtYXR0ZXJzLmxlbmd0aF07CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBidWZmZXJzIGFyZSBsYXppbHkgY3JlYXRlZCB3aGVuIHRoZSBwYXJ0IHJlcXVpcmVzIGEgZ2V0SGVhZC4KKyAgICAgICAgICovCisgICAgICAgIFN0cmluZ0J1aWxkZXJbXSBidWZmZXJzID0gbmV3IFN0cmluZ0J1aWxkZXJbcGFydHMubGVuZ3RoXTsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBidWYgPSBudWxsOworICAgICAgICBmaW5hbCBNaW1lUGFydCBib2R5OworICAgICAgICBpZiAocGFydHMubGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgIG1zZy5zZXREZXNjcmlwdGlvbihkZXNjcmlwdGlvbkZyb20oCisgICAgICAgICAgICAgICAgICAgIGdldEZvcm1hdHRlcigpLCBnZXRGaWx0ZXIoKSwgc3ViamVjdEZvcm1hdHRlcikpOworICAgICAgICAgICAgYm9keSA9IG1zZzsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIG1zZy5zZXREZXNjcmlwdGlvbihkZXNjcmlwdGlvbkZyb20oCisgICAgICAgICAgICAgICAgICAgIGNvbXBhcmF0b3IsIHB1c2hMZXZlbCwgcHVzaEZpbHRlcikpOworICAgICAgICAgICAgYm9keSA9IGNyZWF0ZUJvZHlQYXJ0KCk7CisgICAgICAgIH0KKworICAgICAgICBhcHBlbmRTdWJqZWN0KG1zZywgaGVhZChzdWJqZWN0Rm9ybWF0dGVyKSk7CisgICAgICAgIGZpbmFsIEZvcm1hdHRlciBib2R5Rm9ybWF0ID0gZ2V0Rm9ybWF0dGVyKCk7CisgICAgICAgIGZpbmFsIEZpbHRlciBib2R5RmlsdGVyID0gZ2V0RmlsdGVyKCk7CisKKyAgICAgICAgTG9jYWxlIGxhc3RMb2NhbGUgPSBudWxsOworICAgICAgICBmb3IgKGludCBpeCA9IDA7IGl4IDwgc2l6ZTsgKytpeCkgeworICAgICAgICAgICAgYm9vbGVhbiBmb3JtYXR0ZWQgPSBmYWxzZTsKKyAgICAgICAgICAgIGZpbmFsIGludCBtYXRjaCA9IG1hdGNoZWRbaXhdOworICAgICAgICAgICAgZmluYWwgTG9nUmVjb3JkIHIgPSBkYXRhW2l4XTsKKyAgICAgICAgICAgIGRhdGFbaXhdID0gbnVsbDsgLy9DbGVhciB3aGlsZSBmb3JtYXR0aW5nLgorCisgICAgICAgICAgICBmaW5hbCBMb2NhbGUgbG9jYWxlID0gbG9jYWxlRm9yKHIpOworICAgICAgICAgICAgYXBwZW5kU3ViamVjdChtc2csIGZvcm1hdChzdWJqZWN0Rm9ybWF0dGVyLCByKSk7CisgICAgICAgICAgICBGaWx0ZXIgbG1mID0gbnVsbDsgLy9JZGVudGl0eSBvZiBsYXN0IG1hdGNoZWQgZmlsdGVyLgorICAgICAgICAgICAgaWYgKGJvZHlGaWx0ZXIgPT0gbnVsbCB8fCBtYXRjaCA9PSAtMSB8fCBwYXJ0cy5sZW5ndGggPT0gMAorICAgICAgICAgICAgICAgICAgICB8fCAobWF0Y2ggPCAtMSAmJiBib2R5RmlsdGVyLmlzTG9nZ2FibGUocikpKSB7CisgICAgICAgICAgICAgICAgbG1mID0gYm9keUZpbHRlcjsKKyAgICAgICAgICAgICAgICBpZiAoYnVmID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgYnVmID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZChoZWFkKGJvZHlGb3JtYXQpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZm9ybWF0dGVkID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICBidWYuYXBwZW5kKGZvcm1hdChib2R5Rm9ybWF0LCByKSk7CisgICAgICAgICAgICAgICAgaWYgKGxvY2FsZSAhPSBudWxsICYmICFsb2NhbGUuZXF1YWxzKGxhc3RMb2NhbGUpKSB7CisgICAgICAgICAgICAgICAgICAgIGFwcGVuZENvbnRlbnRMYW5nKGJvZHksIGxvY2FsZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhcnRzLmxlbmd0aDsgKytpKSB7CisgICAgICAgICAgICAgICAgLy9BIG1hdGNoIGluZGV4IGxlc3MgdGhhbiB0aGUgYXR0YWNobWVudCBpbmRleCBtZWFucyB0aGF0CisgICAgICAgICAgICAgICAgLy90aGUgZmlsdGVyIGhhcyBub3Qgc2VlbiB0aGlzIHJlY29yZC4KKyAgICAgICAgICAgICAgICBmaW5hbCBGaWx0ZXIgYWYgPSBhdHRhY2htZW50RmlsdGVyc1tpXTsKKyAgICAgICAgICAgICAgICBpZiAoYWYgPT0gbnVsbCB8fCBsbWYgPT0gYWYgfHwgbWF0Y2ggPT0gaQorICAgICAgICAgICAgICAgICAgICAgICAgfHwgKG1hdGNoIDwgaSAmJiBhZi5pc0xvZ2dhYmxlKHIpKSkgeworICAgICAgICAgICAgICAgICAgICBpZiAobG1mID09IG51bGwgJiYgYWYgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgbG1mID0gYWY7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaWYgKHBhcnRzW2ldID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHBhcnRzW2ldID0gY3JlYXRlQm9keVBhcnQoaSk7CisgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXJzW2ldID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlcnNbaV0uYXBwZW5kKGhlYWQoYXR0YWNobWVudEZvcm1hdHRlcnNbaV0pKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVuZEZpbGVOYW1lKHBhcnRzW2ldLCBoZWFkKGF0dGFjaG1lbnROYW1lc1tpXSkpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGZvcm1hdHRlZCA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgIGFwcGVuZEZpbGVOYW1lKHBhcnRzW2ldLCBmb3JtYXQoYXR0YWNobWVudE5hbWVzW2ldLCByKSk7CisgICAgICAgICAgICAgICAgICAgIGJ1ZmZlcnNbaV0uYXBwZW5kKGZvcm1hdChhdHRhY2htZW50Rm9ybWF0dGVyc1tpXSwgcikpOworICAgICAgICAgICAgICAgICAgICBpZiAobG9jYWxlICE9IG51bGwgJiYgIWxvY2FsZS5lcXVhbHMobGFzdExvY2FsZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVuZENvbnRlbnRMYW5nKHBhcnRzW2ldLCBsb2NhbGUpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoZm9ybWF0dGVkKSB7CisgICAgICAgICAgICAgICAgaWYgKGJvZHkgIT0gbXNnICYmIGxvY2FsZSAhPSBudWxsCisgICAgICAgICAgICAgICAgICAgICAgICAmJiAhbG9jYWxlLmVxdWFscyhsYXN0TG9jYWxlKSkgeworICAgICAgICAgICAgICAgICAgICBhcHBlbmRDb250ZW50TGFuZyhtc2csIGxvY2FsZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsgIC8vQmVsb25ncyB0byBubyBtaW1lIHBhcnQuCisgICAgICAgICAgICAgICAgcmVwb3J0RmlsdGVyRXJyb3Iocik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBsYXN0TG9jYWxlID0gbG9jYWxlOworICAgICAgICB9CisgICAgICAgIHRoaXMuc2l6ZSA9IDA7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IHBhcnRzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7CisgICAgICAgICAgICBpZiAocGFydHNbaV0gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGFwcGVuZEZpbGVOYW1lKHBhcnRzW2ldLCB0YWlsKGF0dGFjaG1lbnROYW1lc1tpXSwgImVyciIpKTsKKyAgICAgICAgICAgICAgICBidWZmZXJzW2ldLmFwcGVuZCh0YWlsKGF0dGFjaG1lbnRGb3JtYXR0ZXJzW2ldLCAiIikpOworCisgICAgICAgICAgICAgICAgaWYgKGJ1ZmZlcnNbaV0ubGVuZ3RoKCkgPiAwKSB7CisgICAgICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lID0gcGFydHNbaV0uZ2V0RmlsZU5hbWUoKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGlzRW1wdHkobmFtZSkpIHsgLy9FeGNlcHRpb25hbCBjYXNlLgorICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSA9IHRvU3RyaW5nKGF0dGFjaG1lbnRGb3JtYXR0ZXJzW2ldKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHBhcnRzW2ldLnNldEZpbGVOYW1lKG5hbWUpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHNldENvbnRlbnQocGFydHNbaV0sIGJ1ZmZlcnNbaV0sIGdldENvbnRlbnRUeXBlKG5hbWUpKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBzZXRJbmNvbXBsZXRlQ29weShtc2cpOworICAgICAgICAgICAgICAgICAgICBwYXJ0c1tpXSA9IG51bGw7IC8vU2tpcCB0aGlzIHBhcnQuCisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGJ1ZmZlcnNbaV0gPSBudWxsOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaWYgKGJ1ZiAhPSBudWxsKSB7CisgICAgICAgICAgICBidWYuYXBwZW5kKHRhaWwoYm9keUZvcm1hdCwgIiIpKTsKKyAgICAgICAgICAgIC8vVGhpcyBib2R5IHBhcnQgaXMgYWx3YXlzIGFkZGVkLCBldmVuIGlmIHRoZSBidWZmZXIgaXMgZW1wdHksCisgICAgICAgICAgICAvL3NvIHRoZSBib2R5IGlzIG5ldmVyIGNvbnNpZGVyZWQgYW4gaW5jb21wbGV0ZS1jb3B5LgorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgYnVmID0gbmV3IFN0cmluZ0J1aWxkZXIoMCk7CisgICAgICAgIH0KKworICAgICAgICBhcHBlbmRTdWJqZWN0KG1zZywgdGFpbChzdWJqZWN0Rm9ybWF0dGVyLCAiIikpOworCisgICAgICAgIFN0cmluZyBjb250ZW50VHlwZSA9IGNvbnRlbnRUeXBlT2YoYnVmKTsKKyAgICAgICAgU3RyaW5nIGFsdFR5cGUgPSBjb250ZW50VHlwZU9mKGJvZHlGb3JtYXQpOworICAgICAgICBzZXRDb250ZW50KGJvZHksIGJ1ZiwgYWx0VHlwZSA9PSBudWxsID8gY29udGVudFR5cGUgOiBhbHRUeXBlKTsKKyAgICAgICAgaWYgKGJvZHkgIT0gbXNnKSB7CisgICAgICAgICAgICBmaW5hbCBNaW1lTXVsdGlwYXJ0IG11bHRpcGFydCA9IG5ldyBNaW1lTXVsdGlwYXJ0KCk7CisgICAgICAgICAgICAvL2Fzc2VydCBib2R5IGluc3RhbmNlb2YgQm9keVBhcnQgOiBib2R5OworICAgICAgICAgICAgbXVsdGlwYXJ0LmFkZEJvZHlQYXJ0KChCb2R5UGFydCkgYm9keSk7CisKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFydHMubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgICAgICBpZiAocGFydHNbaV0gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBtdWx0aXBhcnQuYWRkQm9keVBhcnQocGFydHNbaV0pOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG1zZy5zZXRDb250ZW50KG11bHRpcGFydCk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gbXNnOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrcyBhbGwgb2YgdGhlIHNldHRpbmdzIGlmIHRoZSBjYWxsZXIgcmVxdWVzdHMgYSB2ZXJpZnkgYW5kIGEgdmVyaWZ5CisgICAgICogd2FzIG5vdCBwZXJmb3JtZWQgeWV0IGFuZCBubyB2ZXJpZnkgaXMgaW4gcHJvZ3Jlc3MuICBBIHZlcmlmeSBpcworICAgICAqIHBlcmZvcm1lZCBvbiBjcmVhdGUgYmVjYXVzZSB0aGlzIGhhbmRsZXIgbWF5IGJlIGF0IHRoZSBlbmQgb2YgYSBoYW5kbGVyCisgICAgICogY2hhaW4gYW5kIHRoZXJlZm9yZSBtYXkgbm90IHNlZSBhbnkgbG9nIHJlY29yZHMgdW50aWwgTG9nTWFuYWdlci5yZXNldCgpCisgICAgICogaXMgY2FsbGVkIGFuZCBhdCB0aGF0IHRpbWUgYWxsIG9mIHRoZSBzZXR0aW5ncyBoYXZlIGJlZW4gY2xlYXJlZC4KKyAgICAgKiBAcGFyYW0gc2Vzc2lvbiB0aGUgY3VycmVudCBzZXNzaW9uIG9yIG51bGwuCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNC40CisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHZlcmlmeVNldHRpbmdzKGZpbmFsIFNlc3Npb24gc2Vzc2lvbikgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKHNlc3Npb24gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGZpbmFsIFByb3BlcnRpZXMgcHJvcHMgPSBzZXNzaW9uLmdldFByb3BlcnRpZXMoKTsKKyAgICAgICAgICAgICAgICBmaW5hbCBPYmplY3QgY2hlY2sgPSBwcm9wcy5wdXQoInZlcmlmeSIsICIiKTsKKyAgICAgICAgICAgICAgICBpZiAoY2hlY2sgaW5zdGFuY2VvZiBTdHJpbmcpIHsKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHZhbHVlID0gKFN0cmluZykgY2hlY2s7CisgICAgICAgICAgICAgICAgICAgIC8vUGVyZm9ybSB0aGUgdmVyaWZ5IGlmIG5lZWRlZC4KKyAgICAgICAgICAgICAgICAgICAgaWYgKGhhc1ZhbHVlKHZhbHVlKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgdmVyaWZ5U2V0dGluZ3MwKHNlc3Npb24sIHZhbHVlKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChjaGVjayAhPSBudWxsKSB7IC8vUGFzcyBzb21lIGludmFsaWQgc3RyaW5nLgorICAgICAgICAgICAgICAgICAgICAgICAgdmVyaWZ5U2V0dGluZ3MwKHNlc3Npb24sIGNoZWNrLmdldENsYXNzKCkudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIExpbmthZ2VFcnJvciBKREs4MTUyNTE1KSB7CisgICAgICAgICAgICByZXBvcnRMaW5rYWdlRXJyb3IoSkRLODE1MjUxNSwgRXJyb3JNYW5hZ2VyLk9QRU5fRkFJTFVSRSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3MgYWxsIG9mIHRoZSBzZXR0aW5ncyB1c2luZyB0aGUgZ2l2ZW4gc2V0dGluZy4KKyAgICAgKiBUaGlzIHRyaWdnZXJzIHRoZSBMb2dNYW5hZ2VyUHJvcGVydGllcyB0byBjb3B5IGFsbCBvZiB0aGUgbWFpbAorICAgICAqIHNldHRpbmdzIHdpdGhvdXQgZXhwbGljdGx5IGtub3dpbmcgdGhlbS4gIE9uY2UgYWxsIG9mIHRoZSBwcm9wZXJ0aWVzCisgICAgICogYXJlIGNvcGllZCB0aGlzIGhhbmRsZXIgY2FuIGhhbmRsZSBMb2dNYW5hZ2VyLnJlc2V0IGNsZWFyaW5nIGFsbCBvZiB0aGUKKyAgICAgKiBwcm9wZXJ0aWVzLiAgSXQgaXMgZXhwZWN0ZWQgdGhhdCB0aGlzIG1ldGhvZCBpcywgYXQgbW9zdCwgb25seSBjYWxsZWQKKyAgICAgKiBvbmNlIHBlciBzZXNzaW9uLgorICAgICAqIEBwYXJhbSBzZXNzaW9uIHRoZSBjdXJyZW50IHNlc3Npb24uCisgICAgICogQHBhcmFtIHZlcmlmeSB0aGUgdHlwZSBvZiB2ZXJpZnkgdG8gcGVyZm9ybS4KKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS40LjQKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgdmVyaWZ5U2V0dGluZ3MwKFNlc3Npb24gc2Vzc2lvbiwgU3RyaW5nIHZlcmlmeSkgeworICAgICAgICBhc3NlcnQgdmVyaWZ5ICE9IG51bGwgOiAoU3RyaW5nKSBudWxsOworICAgICAgICBpZiAoISJsb2NhbCIuZXF1YWxzKHZlcmlmeSkgJiYgISJyZW1vdGUiLmVxdWFscyh2ZXJpZnkpCisgICAgICAgICAgICAgICAgJiYgISJsaW1pdGVkIi5lcXVhbHModmVyaWZ5KSAmJiAhInJlc29sdmUiLmVxdWFscyh2ZXJpZnkpCisgICAgICAgICAgICAgICAgJiYgISJsb2dpbiIuZXF1YWxzKHZlcmlmeSkpIHsKKyAgICAgICAgICAgIHJlcG9ydEVycm9yKCJWZXJpZnkgbXVzdCBiZSAnbGltaXRlZCcsIGxvY2FsJywgIgorICAgICAgICAgICAgICAgICAgICArICIncmVzb2x2ZScsICdsb2dpbicsIG9yICdyZW1vdGUnLiIsCisgICAgICAgICAgICAgICAgICAgIG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24odmVyaWZ5KSwKKyAgICAgICAgICAgICAgICAgICAgRXJyb3JNYW5hZ2VyLk9QRU5fRkFJTFVSRSk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBNaW1lTWVzc2FnZSBhYm9ydCA9IG5ldyBNaW1lTWVzc2FnZShzZXNzaW9uKTsKKyAgICAgICAgZmluYWwgU3RyaW5nIG1zZzsKKyAgICAgICAgaWYgKCEibGltaXRlZCIuZXF1YWxzKHZlcmlmeSkpIHsKKyAgICAgICAgICAgIG1zZyA9ICJMb2NhbCBhZGRyZXNzIGlzICIKKyAgICAgICAgICAgICAgICAgICAgKyBJbnRlcm5ldEFkZHJlc3MuZ2V0TG9jYWxBZGRyZXNzKHNlc3Npb24pICsgJy4nOworCisgICAgICAgICAgICB0cnkgeyAvL1ZlcmlmeSBzdWJjbGFzcyBvciBkZWNsYXJlZCBtaW1lIGNoYXJzZXQuCisgICAgICAgICAgICAgICAgQ2hhcnNldC5mb3JOYW1lKGdldEVuY29kaW5nTmFtZSgpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKGZpbmFsIFJ1bnRpbWVFeGNlcHRpb24gUkUpIHsKKyAgICAgICAgICAgICAgICBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIFVFRSA9CisgICAgICAgICAgICAgICAgICAgICAgICBuZXcgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbihSRS50b1N0cmluZygpKTsKKyAgICAgICAgICAgICAgICBVRUUuaW5pdENhdXNlKFJFKTsKKyAgICAgICAgICAgICAgICByZXBvcnRFcnJvcihtc2csIFVFRSwgRXJyb3JNYW5hZ2VyLkZPUk1BVF9GQUlMVVJFKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIG1zZyA9ICJTa2lwcGluZyBsb2NhbCBhZGRyZXNzIGNoZWNrLiI7CisgICAgICAgIH0KKworICAgICAgICAvL1BlcmZvcm0gYWxsIG9mIHRoZSBjb3B5IGFjdGlvbnMgZmlyc3QuCisgICAgICAgIFN0cmluZ1tdIGF0bjsKKyAgICAgICAgc3luY2hyb25pemVkICh0aGlzKSB7IC8vQ3JlYXRlIHRoZSBzdWJqZWN0LgorICAgICAgICAgICAgYXBwZW5kU3ViamVjdChhYm9ydCwgaGVhZChzdWJqZWN0Rm9ybWF0dGVyKSk7CisgICAgICAgICAgICBhcHBlbmRTdWJqZWN0KGFib3J0LCB0YWlsKHN1YmplY3RGb3JtYXR0ZXIsICIiKSk7CisgICAgICAgICAgICBhdG4gPSBuZXcgU3RyaW5nW2F0dGFjaG1lbnROYW1lcy5sZW5ndGhdOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhdG4ubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgICAgICBhdG5baV0gPSBoZWFkKGF0dGFjaG1lbnROYW1lc1tpXSk7CisgICAgICAgICAgICAgICAgaWYgKGF0bltpXS5sZW5ndGgoKSA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIGF0bltpXSA9IHRhaWwoYXR0YWNobWVudE5hbWVzW2ldLCAiIik7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgYXRuW2ldID0gYXRuW2ldLmNvbmNhdCh0YWlsKGF0dGFjaG1lbnROYW1lc1tpXSwgIiIpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBzZXRJbmNvbXBsZXRlQ29weShhYm9ydCk7IC8vT3JpZ2luYWwgYm9keSBwYXJ0IGlzIG5ldmVyIGFkZGVkLgorICAgICAgICBlbnZlbG9wZUZvcihhYm9ydCwgdHJ1ZSk7CisgICAgICAgIHNhdmVDaGFuZ2VzTm9Db250ZW50KGFib3J0LCBtc2cpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy9FbnN1cmUgdHJhbnNwb3J0IHByb3ZpZGVyIGlzIGluc3RhbGxlZC4KKyAgICAgICAgICAgIEFkZHJlc3NbXSBhbGwgPSBhYm9ydC5nZXRBbGxSZWNpcGllbnRzKCk7CisgICAgICAgICAgICBpZiAoYWxsID09IG51bGwpIHsgLy9Eb24ndCBwYXNzIG51bGwgdG8gc2VuZE1lc3NhZ2UuCisgICAgICAgICAgICAgICAgYWxsID0gbmV3IEludGVybmV0QWRkcmVzc1swXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIFRyYW5zcG9ydCB0OworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBmaW5hbCBBZGRyZXNzW10gYW55ID0gYWxsLmxlbmd0aCAhPSAwID8gYWxsIDogYWJvcnQuZ2V0RnJvbSgpOworICAgICAgICAgICAgICAgIGlmIChhbnkgIT0gbnVsbCAmJiBhbnkubGVuZ3RoICE9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgdCA9IHNlc3Npb24uZ2V0VHJhbnNwb3J0KGFueVswXSk7CisgICAgICAgICAgICAgICAgICAgIHNlc3Npb24uZ2V0UHJvcGVydHkoIm1haWwudHJhbnNwb3J0LnByb3RvY29sIik7IC8vRm9yY2UgY29weQorICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2luZ0V4Y2VwdGlvbiBtZSA9IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5vIHJlY2lwaWVudCBvciBmcm9tIGFkZHJlc3MuIik7CisgICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKG1zZywgbWUsIEVycm9yTWFuYWdlci5PUEVOX0ZBSUxVUkUpOworICAgICAgICAgICAgICAgICAgICB0aHJvdyBtZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBNZXNzYWdpbmdFeGNlcHRpb24gcHJvdG9jb2wpIHsKKyAgICAgICAgICAgICAgICAvL1N3aXRjaGluZyB0aGUgQ0NMIGVtdWxhdGVzIHRoZSBjdXJyZW50IHNlbmQgYmVoYXZpb3IuCisgICAgICAgICAgICAgICAgT2JqZWN0IGNjbCA9IGdldEFuZFNldENvbnRleHRDbGFzc0xvYWRlcihNQUlMSEFORExFUl9MT0FERVIpOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHQgPSBzZXNzaW9uLmdldFRyYW5zcG9ydCgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGZpbmFsIE1lc3NhZ2luZ0V4Y2VwdGlvbiBmYWlsKSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IGF0dGFjaChwcm90b2NvbCwgZmFpbCk7CisgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICAgICAgZ2V0QW5kU2V0Q29udGV4dENsYXNzTG9hZGVyKGNjbCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBTdHJpbmcgbG9jYWwgPSBudWxsOworICAgICAgICAgICAgaWYgKCJyZW1vdGUiLmVxdWFscyh2ZXJpZnkpIHx8ICJsb2dpbiIuZXF1YWxzKHZlcmlmeSkpIHsKKyAgICAgICAgICAgICAgICBNZXNzYWdpbmdFeGNlcHRpb24gY2xvc2VkID0gbnVsbDsKKyAgICAgICAgICAgICAgICB0LmNvbm5lY3QoKTsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgLy9DYXB0dXJlIGxvY2FsaG9zdCB3aGlsZSBjb25uZWN0aW9uIGlzIG9wZW4uCisgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbCA9IGdldExvY2FsSG9zdCh0KTsKKworICAgICAgICAgICAgICAgICAgICAgICAgLy9BIG1lc3NhZ2Ugd2l0aG91dCBjb250ZW50IHdpbGwgZmFpbCBhdCBtZXNzYWdlIHdyaXRlVG8KKyAgICAgICAgICAgICAgICAgICAgICAgIC8vd2hlbiBzZW5kTWVzc2FnZSBpcyBjYWxsZWQuICBUaGlzIGFsbG93cyB0aGUgaGFuZGxlcgorICAgICAgICAgICAgICAgICAgICAgICAgLy90byBjYXB0dXJlIGFsbCBtYWlsIHByb3BlcnRpZXMgc2V0IGluIHRoZSBMb2dNYW5hZ2VyLgorICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCJyZW1vdGUiLmVxdWFscyh2ZXJpZnkpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdC5zZW5kTWVzc2FnZShhYm9ydCwgYWxsKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdC5jbG9zZSgpOworICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgTWVzc2FnaW5nRXhjZXB0aW9uIE1FKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xvc2VkID0gTUU7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgLy9DbG9zZSB0aGUgdHJhbnNwb3J0IGJlZm9yZSByZXBvcnRpbmcgZXJyb3JzLgorICAgICAgICAgICAgICAgICAgICBpZiAoInJlbW90ZSIuZXF1YWxzKHZlcmlmeSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydFVuZXhwZWN0ZWRTZW5kKGFib3J0LCB2ZXJpZnksIG51bGwpOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIHByb3RvY29sID0gdC5nZXRVUkxOYW1lKCkuZ2V0UHJvdG9jb2woKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHZlcmlmeVByb3BlcnRpZXMoc2Vzc2lvbiwgcHJvdG9jb2wpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgU2VuZEZhaWxlZEV4Y2VwdGlvbiBzZmUpIHsKKyAgICAgICAgICAgICAgICAgICAgQWRkcmVzc1tdIHJlY2lwID0gc2ZlLmdldEludmFsaWRBZGRyZXNzZXMoKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHJlY2lwICE9IG51bGwgJiYgcmVjaXAubGVuZ3RoICE9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNldEVycm9yQ29udGVudChhYm9ydCwgdmVyaWZ5LCBzZmUpOworICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoYWJvcnQsIHNmZSwgRXJyb3JNYW5hZ2VyLk9QRU5fRkFJTFVSRSk7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICByZWNpcCA9IHNmZS5nZXRWYWxpZFNlbnRBZGRyZXNzZXMoKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHJlY2lwICE9IG51bGwgJiYgcmVjaXAubGVuZ3RoICE9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydFVuZXhwZWN0ZWRTZW5kKGFib3J0LCB2ZXJpZnksIHNmZSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBNZXNzYWdpbmdFeGNlcHRpb24gTUUpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCFpc01pc3NpbmdDb250ZW50KGFib3J0LCBNRSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNldEVycm9yQ29udGVudChhYm9ydCwgdmVyaWZ5LCBNRSk7CisgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRFcnJvcihhYm9ydCwgTUUsIEVycm9yTWFuYWdlci5PUEVOX0ZBSUxVUkUpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaWYgKGNsb3NlZCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIHNldEVycm9yQ29udGVudChhYm9ydCwgdmVyaWZ5LCBjbG9zZWQpOworICAgICAgICAgICAgICAgICAgICByZXBvcnRFcnJvcihhYm9ydCwgY2xvc2VkLCBFcnJvck1hbmFnZXIuQ0xPU0VfRkFJTFVSRSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAvL0ZvcmNlIGEgcHJvcGVydHkgY29weSwgSkRLLTcwOTI5ODEuCisgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIHByb3RvY29sID0gdC5nZXRVUkxOYW1lKCkuZ2V0UHJvdG9jb2woKTsKKyAgICAgICAgICAgICAgICB2ZXJpZnlQcm9wZXJ0aWVzKHNlc3Npb24sIHByb3RvY29sKTsKKyAgICAgICAgICAgICAgICBTdHJpbmcgbWFpbEhvc3QgPSBzZXNzaW9uLmdldFByb3BlcnR5KCJtYWlsLiIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgcHJvdG9jb2wgKyAiLmhvc3QiKTsKKyAgICAgICAgICAgICAgICBpZiAoaXNFbXB0eShtYWlsSG9zdCkpIHsKKyAgICAgICAgICAgICAgICAgICAgbWFpbEhvc3QgPSBzZXNzaW9uLmdldFByb3BlcnR5KCJtYWlsLmhvc3QiKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLmdldFByb3BlcnR5KCJtYWlsLmhvc3QiKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBsb2NhbCA9IHNlc3Npb24uZ2V0UHJvcGVydHkoIm1haWwuIiArIHByb3RvY29sICsgIi5sb2NhbGhvc3QiKTsKKyAgICAgICAgICAgICAgICBpZiAoaXNFbXB0eShsb2NhbCkpIHsKKyAgICAgICAgICAgICAgICAgICAgbG9jYWwgPSBzZXNzaW9uLmdldFByb3BlcnR5KCJtYWlsLiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICArIHByb3RvY29sICsgIi5sb2NhbGFkZHJlc3MiKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLmdldFByb3BlcnR5KCJtYWlsLiIgKyBwcm90b2NvbCArICIubG9jYWxhZGRyZXNzIik7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaWYgKCJyZXNvbHZlIi5lcXVhbHModmVyaWZ5KSkgeworICAgICAgICAgICAgICAgICAgICB0cnkgeyAvL1Jlc29sdmUgdGhlIHJlbW90ZSBob3N0IG5hbWUuCisgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdHJhbnNwb3J0SG9zdCA9IHQuZ2V0VVJMTmFtZSgpLmdldEhvc3QoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICghaXNFbXB0eSh0cmFuc3BvcnRIb3N0KSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlcmlmeUhvc3QodHJhbnNwb3J0SG9zdCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0cmFuc3BvcnRIb3N0LmVxdWFsc0lnbm9yZUNhc2UobWFpbEhvc3QpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlcmlmeUhvc3QobWFpbEhvc3QpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVyaWZ5SG9zdChtYWlsSG9zdCk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGZpbmFsIFJ1bnRpbWVFeGNlcHRpb24gfCBJT0V4Y2VwdGlvbiBJT0UpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2luZ0V4Y2VwdGlvbiBNRSA9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBNZXNzYWdpbmdFeGNlcHRpb24obXNnLCBJT0UpOworICAgICAgICAgICAgICAgICAgICAgICAgc2V0RXJyb3JDb250ZW50KGFib3J0LCB2ZXJpZnksIE1FKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKGFib3J0LCBNRSwgRXJyb3JNYW5hZ2VyLk9QRU5fRkFJTFVSRSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmICghImxpbWl0ZWQiLmVxdWFscyh2ZXJpZnkpKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsgLy9WZXJpZnkgaG9zdCBuYW1lIGFuZCBoaXQgdGhlIGhvc3QgbmFtZSBjYWNoZS4KKyAgICAgICAgICAgICAgICAgICAgaWYgKCEicmVtb3RlIi5lcXVhbHModmVyaWZ5KSAmJiAhImxvZ2luIi5lcXVhbHModmVyaWZ5KSkgeworICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWwgPSBnZXRMb2NhbEhvc3QodCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgdmVyaWZ5SG9zdChsb2NhbCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgUnVudGltZUV4Y2VwdGlvbiB8IElPRXhjZXB0aW9uIElPRSkgeworICAgICAgICAgICAgICAgICAgICBNZXNzYWdpbmdFeGNlcHRpb24gTUUgPSBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKG1zZywgSU9FKTsKKyAgICAgICAgICAgICAgICAgICAgc2V0RXJyb3JDb250ZW50KGFib3J0LCB2ZXJpZnksIE1FKTsKKyAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoYWJvcnQsIE1FLCBFcnJvck1hbmFnZXIuT1BFTl9GQUlMVVJFKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICB0cnkgeyAvL1ZlcmlmeSB0aGF0IHRoZSBEYXRhSGFuZGxlciBjYW4gYmUgbG9hZGVkLgorICAgICAgICAgICAgICAgICAgICBPYmplY3QgY2NsID0gZ2V0QW5kU2V0Q29udGV4dENsYXNzTG9hZGVyKE1BSUxIQU5ETEVSX0xPQURFUik7CisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvL0Fsd2F5cyBsb2FkIHRoZSBtdWx0aXBhcnQgY2xhc3Nlcy4KKyAgICAgICAgICAgICAgICAgICAgICAgIE1pbWVNdWx0aXBhcnQgbXVsdGlwYXJ0ID0gbmV3IE1pbWVNdWx0aXBhcnQoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIE1pbWVCb2R5UGFydFtdIGFtYnAgPSBuZXcgTWltZUJvZHlQYXJ0W2F0bi5sZW5ndGhdOworICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgTWltZUJvZHlQYXJ0IGJvZHk7CisgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgYm9keUNvbnRlbnRUeXBlOworICAgICAgICAgICAgICAgICAgICAgICAgc3luY2hyb25pemVkICh0aGlzKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9keUNvbnRlbnRUeXBlID0gY29udGVudFR5cGVPZihnZXRGb3JtYXR0ZXIoKSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9keSA9IGNyZWF0ZUJvZHlQYXJ0KCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhdG4ubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW1icFtpXSA9IGNyZWF0ZUJvZHlQYXJ0KGkpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbWJwW2ldLnNldEZpbGVOYW1lKGF0bltpXSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vQ29udmVydCBuYW1lcyB0byBtaW1lIHR5cGUgdW5kZXIgbG9jay4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXRuW2ldID0gZ2V0Q29udGVudFR5cGUoYXRuW2ldKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgICAgIGJvZHkuc2V0RGVzY3JpcHRpb24odmVyaWZ5KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNldENvbnRlbnQoYm9keSwgIiIsIGJvZHlDb250ZW50VHlwZSk7CisgICAgICAgICAgICAgICAgICAgICAgICBtdWx0aXBhcnQuYWRkQm9keVBhcnQoYm9keSk7CisgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFtYnAubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbWJwW2ldLnNldERlc2NyaXB0aW9uKHZlcmlmeSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0Q29udGVudChhbWJwW2ldLCAiIiwgYXRuW2ldKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICAgICAgYWJvcnQuc2V0Q29udGVudChtdWx0aXBhcnQpOworICAgICAgICAgICAgICAgICAgICAgICAgYWJvcnQuc2F2ZUNoYW5nZXMoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGFib3J0LndyaXRlVG8obmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbShNSU5fSEVBREVSX1NJWkUpKTsKKyAgICAgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGdldEFuZFNldENvbnRleHRDbGFzc0xvYWRlcihjY2wpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgSU9FeGNlcHRpb24gSU9FKSB7CisgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2luZ0V4Y2VwdGlvbiBNRSA9IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24obXNnLCBJT0UpOworICAgICAgICAgICAgICAgICAgICBzZXRFcnJvckNvbnRlbnQoYWJvcnQsIHZlcmlmeSwgTUUpOworICAgICAgICAgICAgICAgICAgICByZXBvcnRFcnJvcihhYm9ydCwgTUUsIEVycm9yTWFuYWdlci5GT1JNQVRfRkFJTFVSRSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvL1ZlcmlmeSBhbGwgcmVjaXBpZW50cy4KKyAgICAgICAgICAgIGlmIChhbGwubGVuZ3RoICE9IDApIHsKKyAgICAgICAgICAgICAgICB2ZXJpZnlBZGRyZXNzZXMoYWxsKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiTm8gcmVjaXBpZW50IGFkZHJlc3Nlcy4iKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy9WZXJpZnkgZnJvbSBhbmQgc2VuZGVyIGFkZHJlc3Nlcy4KKyAgICAgICAgICAgIEFkZHJlc3NbXSBmcm9tID0gYWJvcnQuZ2V0RnJvbSgpOworICAgICAgICAgICAgQWRkcmVzcyBzZW5kZXIgPSBhYm9ydC5nZXRTZW5kZXIoKTsKKyAgICAgICAgICAgIGlmIChzZW5kZXIgaW5zdGFuY2VvZiBJbnRlcm5ldEFkZHJlc3MpIHsKKyAgICAgICAgICAgICAgICAoKEludGVybmV0QWRkcmVzcykgc2VuZGVyKS52YWxpZGF0ZSgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvL0lmIGZyb20gYWRkcmVzcyBpcyBkZWNsYXJlZCB0aGVuIGNoZWNrIHNlbmRlci4KKyAgICAgICAgICAgIGlmIChhYm9ydC5nZXRIZWFkZXIoIkZyb20iLCAiLCIpICE9IG51bGwgJiYgZnJvbS5sZW5ndGggIT0gMCkgeworICAgICAgICAgICAgICAgIHZlcmlmeUFkZHJlc3Nlcyhmcm9tKTsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZyb20ubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGZyb21baV0uZXF1YWxzKHNlbmRlcikpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2luZ0V4Y2VwdGlvbiBNRSA9IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTZW5kZXIgYWRkcmVzcyAnIiArIHNlbmRlcgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICInIGVxdWFscyBmcm9tIGFkZHJlc3MuIik7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKG1zZywgTUUpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBpZiAoc2VuZGVyID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgTWVzc2FnaW5nRXhjZXB0aW9uIE1FID0gbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTm8gZnJvbSBvciBzZW5kZXIgYWRkcmVzcy4iKTsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbihtc2csIE1FKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vVmVyaWZ5IHJlcGx5LXRvIGFkZHJlc3Nlcy4KKyAgICAgICAgICAgIHZlcmlmeUFkZHJlc3NlcyhhYm9ydC5nZXRSZXBseVRvKCkpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBSdW50aW1lRXhjZXB0aW9uIFJFKSB7CisgICAgICAgICAgICBzZXRFcnJvckNvbnRlbnQoYWJvcnQsIHZlcmlmeSwgUkUpOworICAgICAgICAgICAgcmVwb3J0RXJyb3IoYWJvcnQsIFJFLCBFcnJvck1hbmFnZXIuT1BFTl9GQUlMVVJFKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgRXhjZXB0aW9uIE1FKSB7CisgICAgICAgICAgICBzZXRFcnJvckNvbnRlbnQoYWJvcnQsIHZlcmlmeSwgTUUpOworICAgICAgICAgICAgcmVwb3J0RXJyb3IoYWJvcnQsIE1FLCBFcnJvck1hbmFnZXIuT1BFTl9GQUlMVVJFKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEhhbmRsZXMgYWxsIGV4Y2VwdGlvbnMgdGhyb3duIHdoZW4gc2F2ZSBjaGFuZ2VzIGlzIGNhbGxlZCBvbiBhIG1lc3NhZ2UKKyAgICAgKiB0aGF0IGRvZXNuJ3QgaGF2ZSBhbnkgY29udGVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhYm9ydCB0aGUgbWVzc2FnZSByZXF1aXJpbmcgc2F2ZSBjaGFuZ2VzLgorICAgICAqIEBwYXJhbSBtc2cgdGhlIGVycm9yIGRlc2NyaXB0aW9uLgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjYuMAorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBzYXZlQ2hhbmdlc05vQ29udGVudChmaW5hbCBNZXNzYWdlIGFib3J0LCBmaW5hbCBTdHJpbmcgbXNnKSB7CisgICAgICAgIGlmIChhYm9ydCAhPSBudWxsKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGFib3J0LnNhdmVDaGFuZ2VzKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgTnVsbFBvaW50ZXJFeGNlcHRpb24geGZlckVuY29kaW5nKSB7CisgICAgICAgICAgICAgICAgICAgIC8vV29ya2Fyb3VuZCBHTlUgSmF2YU1haWwgYnVnIGluIE1pbWVVdGlsaXR5LmdldEVuY29kaW5nCisgICAgICAgICAgICAgICAgICAgIC8vd2hlbiB0aGUgbWltZSBtZXNzYWdlIGhhcyBubyBjb250ZW50LgorICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGN0ZSA9ICJDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nIjsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhYm9ydC5nZXRIZWFkZXIoY3RlKSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWJvcnQuc2V0SGVhZGVyKGN0ZSwgImJhc2U2NCIpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFib3J0LnNhdmVDaGFuZ2VzKCk7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IHhmZXJFbmNvZGluZzsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiB8IE1lc3NhZ2luZ0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZSAhPSB4ZmVyRW5jb2RpbmcpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGUuYWRkU3VwcHJlc3NlZCh4ZmVyRW5jb2RpbmcpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gfCBNZXNzYWdpbmdFeGNlcHRpb24gTUUpIHsKKyAgICAgICAgICAgICAgICByZXBvcnRFcnJvcihtc2csIE1FLCBFcnJvck1hbmFnZXIuRk9STUFUX0ZBSUxVUkUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2FjaGUgY29tbW9uIHNlc3Npb24gcHJvcGVydGllcyBpbnRvIHRoZSBMb2dNYW5hZ2VyUHJvcGVydGllcy4gIFRoaXMgaXMKKyAgICAgKiBhIHdvcmthcm91bmQgZm9yIEpESy03MDkyOTgxLgorICAgICAqCisgICAgICogQHBhcmFtIHNlc3Npb24gdGhlIHNlc3Npb24uCisgICAgICogQHBhcmFtIHByb3RvY29sIHRoZSBtYWlsIHByb3RvY29sLgorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgc2Vzc2lvbiBpcyBudWxsLgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjYuMAorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgdmVyaWZ5UHJvcGVydGllcyhTZXNzaW9uIHNlc3Npb24sIFN0cmluZyBwcm90b2NvbCkgeworICAgICAgICBzZXNzaW9uLmdldFByb3BlcnR5KCJtYWlsLmZyb20iKTsKKyAgICAgICAgc2Vzc2lvbi5nZXRQcm9wZXJ0eSgibWFpbC4iICsgcHJvdG9jb2wgKyAiLmZyb20iKTsKKyAgICAgICAgc2Vzc2lvbi5nZXRQcm9wZXJ0eSgibWFpbC5kc24ucmV0Iik7CisgICAgICAgIHNlc3Npb24uZ2V0UHJvcGVydHkoIm1haWwuIiArIHByb3RvY29sICsgIi5kc24ucmV0Iik7CisgICAgICAgIHNlc3Npb24uZ2V0UHJvcGVydHkoIm1haWwuZHNuLm5vdGlmeSIpOworICAgICAgICBzZXNzaW9uLmdldFByb3BlcnR5KCJtYWlsLiIgKyBwcm90b2NvbCArICIuZHNuLm5vdGlmeSIpOworICAgICAgICBzZXNzaW9uLmdldFByb3BlcnR5KCJtYWlsLiIgKyBwcm90b2NvbCArICIucG9ydCIpOworICAgICAgICBzZXNzaW9uLmdldFByb3BlcnR5KCJtYWlsLnVzZXIiKTsKKyAgICAgICAgc2Vzc2lvbi5nZXRQcm9wZXJ0eSgibWFpbC4iICsgcHJvdG9jb2wgKyAiLnVzZXIiKTsKKyAgICAgICAgc2Vzc2lvbi5nZXRQcm9wZXJ0eSgibWFpbC4iICsgcHJvdG9jb2wgKyAiLmxvY2FscG9ydCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm0gYSBsb29rdXAgb2YgdGhlIGhvc3QgYWRkcmVzcyBvciBGUUROLgorICAgICAqIEBwYXJhbSBob3N0IHRoZSBob3N0IG9yIG51bGwuCisgICAgICogQHJldHVybiB0aGUgYWRkcmVzcy4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHRoZSBob3N0IG5hbWUgaXMgbm90IHZhbGlkLgorICAgICAqIEB0aHJvd3MgU2VjdXJpdHlFeGNlcHRpb24gaWYgc2VjdXJpdHkgbWFuYWdlciBpcyBwcmVzZW50IGFuZCBkb2Vzbid0CisgICAgICogYWxsb3cgYWNjZXNzIHRvIGNoZWNrIGNvbm5lY3QgcGVybWlzc2lvbi4KKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS41LjAKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBJbmV0QWRkcmVzcyB2ZXJpZnlIb3N0KFN0cmluZyBob3N0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBJbmV0QWRkcmVzcyBhOworICAgICAgICBpZiAoaXNFbXB0eShob3N0KSkgeworICAgICAgICAgICAgYSA9IEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgYSA9IEluZXRBZGRyZXNzLmdldEJ5TmFtZShob3N0KTsKKyAgICAgICAgfQorICAgICAgICBpZiAoYS5nZXRDYW5vbmljYWxIb3N0TmFtZSgpLmxlbmd0aCgpID09IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbmtub3duSG9zdEV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBhOworICAgIH0KKworICAgIC8qKgorICAgICAqIENhbGxzIHZhbGlkYXRlIGZvciBldmVyeSBhZGRyZXNzIGdpdmVuLgorICAgICAqIElmIHRoZSBhZGRyZXNzZXMgZ2l2ZW4gYXJlIG51bGwsIGVtcHR5IG9yIG5vdCBhbiBJbnRlcm5ldEFkZHJlc3MgdGhlbgorICAgICAqIHRoZSBjaGVjayBpcyBza2lwcGVkLgorICAgICAqIEBwYXJhbSBhbGwgYW55IGFkZHJlc3MgYXJyYXksIG51bGwgb3IgZW1wdHkuCisgICAgICogQHRocm93cyBBZGRyZXNzRXhjZXB0aW9uIGlmIHRoZXJlIGlzIGEgcHJvYmxlbS4KKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS40LjUKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHZlcmlmeUFkZHJlc3NlcyhBZGRyZXNzW10gYWxsKSB0aHJvd3MgQWRkcmVzc0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChhbGwgIT0gbnVsbCkgeworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhbGwubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBBZGRyZXNzIGEgPSBhbGxbaV07CisgICAgICAgICAgICAgICAgaWYgKGEgaW5zdGFuY2VvZiBJbnRlcm5ldEFkZHJlc3MpIHsKKyAgICAgICAgICAgICAgICAgICAgKChJbnRlcm5ldEFkZHJlc3MpIGEpLnZhbGlkYXRlKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVwb3J0cyB0aGF0IGFuIGVtcHR5IGNvbnRlbnQgbWVzc2FnZSB3YXMgc2VudCBhbmQgc2hvdWxkIG5vdCBoYXZlIGJlZW4uCisgICAgICogQHBhcmFtIG1zZyB0aGUgTWltZU1lc3NhZ2UuCisgICAgICogQHBhcmFtIHZlcmlmeSB0aGUgdmVyaWZ5IGVudW0uCisgICAgICogQHBhcmFtIGNhdXNlIHRoZSBleGNlcHRpb24gdGhhdCBjYXVzZWQgdGhlIHByb2JsZW0gb3IgbnVsbC4KKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS40LjUKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmVwb3J0VW5leHBlY3RlZFNlbmQoTWltZU1lc3NhZ2UgbXNnLCBTdHJpbmcgdmVyaWZ5LCBFeGNlcHRpb24gY2F1c2UpIHsKKyAgICAgICAgZmluYWwgTWVzc2FnaW5nRXhjZXB0aW9uIHdyaXRlID0gbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAiQW4gZW1wdHkgbWVzc2FnZSB3YXMgc2VudC4iLCBjYXVzZSk7CisgICAgICAgIHNldEVycm9yQ29udGVudChtc2csIHZlcmlmeSwgd3JpdGUpOworICAgICAgICByZXBvcnRFcnJvcihtc2csIHdyaXRlLCBFcnJvck1hbmFnZXIuT1BFTl9GQUlMVVJFKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuZCBzZXRzIHRoZSBtZXNzYWdlIGNvbnRlbnQgZnJvbSB0aGUgZ2l2ZW4gVGhyb3dhYmxlLgorICAgICAqIFdoZW4gdmVyaWZ5IGZhaWxzLCB0aGlzIG1ldGhvZCBmaXhlcyB0aGUgJ2Fib3J0JyBtZXNzYWdlIHNvIHRoYXQgYW55CisgICAgICogY3JlYXRlZCBlbnZlbG9wZSBkYXRhIGNhbiBiZSB1c2VkIGluIHRoZSBlcnJvciBtYW5hZ2VyLgorICAgICAqIEBwYXJhbSBtc2cgdGhlIG1lc3NhZ2Ugd2l0aCBvciB3aXRob3V0IGNvbnRlbnQuCisgICAgICogQHBhcmFtIHZlcmlmeSB0aGUgdmVyaWZ5IGVudW0uCisgICAgICogQHBhcmFtIHQgdGhlIHRocm93YWJsZSBvciBudWxsLgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjQuNQorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBzZXRFcnJvckNvbnRlbnQoTWltZU1lc3NhZ2UgbXNnLCBTdHJpbmcgdmVyaWZ5LCBUaHJvd2FibGUgdCkgeworICAgICAgICB0cnkgeyAvL0FkZCBjb250ZW50IHNvIHRvUmF3U3RyaW5nIGRvZXNuJ3QgZmFpbC4KKyAgICAgICAgICAgIGZpbmFsIE1pbWVCb2R5UGFydCBib2R5OworICAgICAgICAgICAgZmluYWwgU3RyaW5nIHN1YmplY3RUeXBlOworICAgICAgICAgICAgZmluYWwgU3RyaW5nIG1zZ0Rlc2M7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgICAgICAgICAgICBib2R5ID0gY3JlYXRlQm9keVBhcnQoKTsKKyAgICAgICAgICAgICAgICBtc2dEZXNjID0gZGVzY3JpcHRpb25Gcm9tKGNvbXBhcmF0b3IsIHB1c2hMZXZlbCwgcHVzaEZpbHRlcik7CisgICAgICAgICAgICAgICAgc3ViamVjdFR5cGUgPSBnZXRDbGFzc0lkKHN1YmplY3RGb3JtYXR0ZXIpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBib2R5LnNldERlc2NyaXB0aW9uKCJGb3JtYXR0ZWQgdXNpbmcgIgorICAgICAgICAgICAgICAgICAgICArICh0ID09IG51bGwgPyBUaHJvd2FibGUuY2xhc3MuZ2V0TmFtZSgpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiB0LmdldENsYXNzKCkuZ2V0TmFtZSgpKSArICIsIGZpbHRlcmVkIHdpdGggIgorICAgICAgICAgICAgICAgICAgICArIHZlcmlmeSArICIsIGFuZCBuYW1lZCBieSAiCisgICAgICAgICAgICAgICAgICAgICsgc3ViamVjdFR5cGUgKyAnLicpOworICAgICAgICAgICAgc2V0Q29udGVudChib2R5LCB0b01zZ1N0cmluZyh0KSwgInRleHQvcGxhaW4iKTsKKyAgICAgICAgICAgIGZpbmFsIE1pbWVNdWx0aXBhcnQgbXVsdGlwYXJ0ID0gbmV3IE1pbWVNdWx0aXBhcnQoKTsKKyAgICAgICAgICAgIG11bHRpcGFydC5hZGRCb2R5UGFydChib2R5KTsKKyAgICAgICAgICAgIG1zZy5zZXRDb250ZW50KG11bHRpcGFydCk7CisgICAgICAgICAgICBtc2cuc2V0RGVzY3JpcHRpb24obXNnRGVzYyk7CisgICAgICAgICAgICBzZXRBY2NlcHRMYW5nKG1zZyk7CisgICAgICAgICAgICBtc2cuc2F2ZUNoYW5nZXMoKTsKKyAgICAgICAgfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIHwgUnVudGltZUV4Y2VwdGlvbiBNRSkgeworICAgICAgICAgICAgcmVwb3J0RXJyb3IoIlVuYWJsZSB0byBjcmVhdGUgYm9keS4iLCBNRSwgRXJyb3JNYW5hZ2VyLk9QRU5fRkFJTFVSRSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVc2VkIHRvIHVwZGF0ZSB0aGUgY2FjaGVkIHNlc3Npb24gb2JqZWN0IGJhc2VkIG9uIGNoYW5nZXMgaW4KKyAgICAgKiBtYWlsIHByb3BlcnRpZXMgb3IgYXV0aGVudGljYXRvci4KKyAgICAgKiBAcmV0dXJuIHRoZSBjdXJyZW50IHNlc3Npb24gb3IgbnVsbCBpZiBubyB2ZXJpZnkgaXMgcmVxdWlyZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBTZXNzaW9uIHVwZGF0ZVNlc3Npb24oKSB7CisgICAgICAgIGFzc2VydCBUaHJlYWQuaG9sZHNMb2NrKHRoaXMpOworICAgICAgICBmaW5hbCBTZXNzaW9uIHNldHRpbmdzOworICAgICAgICBpZiAobWFpbFByb3BzLmdldFByb3BlcnR5KCJ2ZXJpZnkiKSAhPSBudWxsKSB7CisgICAgICAgICAgICBzZXR0aW5ncyA9IGluaXRTZXNzaW9uKCk7CisgICAgICAgICAgICBhc3NlcnQgc2V0dGluZ3MgPT0gc2Vzc2lvbiA6IHNlc3Npb247CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBzZXNzaW9uID0gbnVsbDsgLy9SZW1vdmUgb2xkIHNlc3Npb24uCisgICAgICAgICAgICBzZXR0aW5ncyA9IG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHNldHRpbmdzOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBzZXNzaW9uIHVzaW5nIGEgcHJveHkgcHJvcGVydGllcyBvYmplY3QuCisgICAgICogQHJldHVybiB0aGUgc2Vzc2lvbiB0aGF0IHdhcyBjcmVhdGVkIGFuZCBhc3NpZ25lZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIFNlc3Npb24gaW5pdFNlc3Npb24oKSB7CisgICAgICAgIGFzc2VydCBUaHJlYWQuaG9sZHNMb2NrKHRoaXMpOworICAgICAgICBmaW5hbCBTdHJpbmcgcCA9IGdldENsYXNzKCkuZ2V0TmFtZSgpOworICAgICAgICBMb2dNYW5hZ2VyUHJvcGVydGllcyBwcm94eSA9IG5ldyBMb2dNYW5hZ2VyUHJvcGVydGllcyhtYWlsUHJvcHMsIHApOworICAgICAgICBzZXNzaW9uID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShwcm94eSwgYXV0aCk7CisgICAgICAgIHJldHVybiBzZXNzaW9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYWxsIG9mIHRoZSBlbnZlbG9wZSBpbmZvcm1hdGlvbiBmb3IgYSBtZXNzYWdlLgorICAgICAqIFRoaXMgbWV0aG9kIGlzIHNhZmUgdG8gY2FsbCBvdXRzaWRlIG9mIGEgbG9jayBiZWNhdXNlIHRoZSBtZXNzYWdlCisgICAgICogcHJvdmlkZXMgdGhlIHNhZmUgc25hcHNob3Qgb2YgdGhlIG1haWwgcHJvcGVydGllcy4KKyAgICAgKiBAcGFyYW0gbXNnIHRoZSBNZXNzYWdlIHRvIHdyaXRlIHRoZSBlbnZlbG9wZSBpbmZvcm1hdGlvbi4KKyAgICAgKiBAcGFyYW0gcHJpb3JpdHkgdHJ1ZSBmb3IgaGlnaCBwcmlvcml0eS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgZW52ZWxvcGVGb3IoTWVzc2FnZSBtc2csIGJvb2xlYW4gcHJpb3JpdHkpIHsKKyAgICAgICAgc2V0QWNjZXB0TGFuZyhtc2cpOworICAgICAgICBzZXRGcm9tKG1zZyk7CisgICAgICAgIGlmICghc2V0UmVjaXBpZW50KG1zZywgIm1haWwudG8iLCBNZXNzYWdlLlJlY2lwaWVudFR5cGUuVE8pKSB7CisgICAgICAgICAgICBzZXREZWZhdWx0UmVjaXBpZW50KG1zZywgTWVzc2FnZS5SZWNpcGllbnRUeXBlLlRPKTsKKyAgICAgICAgfQorICAgICAgICBzZXRSZWNpcGllbnQobXNnLCAibWFpbC5jYyIsIE1lc3NhZ2UuUmVjaXBpZW50VHlwZS5DQyk7CisgICAgICAgIHNldFJlY2lwaWVudChtc2csICJtYWlsLmJjYyIsIE1lc3NhZ2UuUmVjaXBpZW50VHlwZS5CQ0MpOworICAgICAgICBzZXRSZXBseVRvKG1zZyk7CisgICAgICAgIHNldFNlbmRlcihtc2cpOworICAgICAgICBzZXRNYWlsZXIobXNnKTsKKyAgICAgICAgc2V0QXV0b1N1Ym1pdHRlZChtc2cpOworICAgICAgICBpZiAocHJpb3JpdHkpIHsKKyAgICAgICAgICAgIHNldFByaW9yaXR5KG1zZyk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgbXNnLnNldFNlbnREYXRlKG5ldyBqYXZhLnV0aWwuRGF0ZSgpKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgTWVzc2FnaW5nRXhjZXB0aW9uIE1FKSB7CisgICAgICAgICAgICByZXBvcnRFcnJvcihNRS5nZXRNZXNzYWdlKCksIE1FLCBFcnJvck1hbmFnZXIuRk9STUFUX0ZBSUxVUkUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogRmFjdG9yeSB0byBjcmVhdGUgdGhlIGluLWxpbmUgYm9keSBwYXJ0LgorICAgICAqIEByZXR1cm4gYSBib2R5IHBhcnQgd2l0aCBkZWZhdWx0IGhlYWRlcnMgc2V0LgorICAgICAqIEB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIGlmIHRoZXJlIGlzIGEgcHJvYmxlbS4KKyAgICAgKi8KKyAgICBwcml2YXRlIE1pbWVCb2R5UGFydCBjcmVhdGVCb2R5UGFydCgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworICAgICAgICBhc3NlcnQgVGhyZWFkLmhvbGRzTG9jayh0aGlzKTsKKyAgICAgICAgZmluYWwgTWltZUJvZHlQYXJ0IHBhcnQgPSBuZXcgTWltZUJvZHlQYXJ0KCk7CisgICAgICAgIHBhcnQuc2V0RGlzcG9zaXRpb24oUGFydC5JTkxJTkUpOworICAgICAgICBwYXJ0LnNldERlc2NyaXB0aW9uKGRlc2NyaXB0aW9uRnJvbShnZXRGb3JtYXR0ZXIoKSwKKyAgICAgICAgICAgICAgICBnZXRGaWx0ZXIoKSwgc3ViamVjdEZvcm1hdHRlcikpOworICAgICAgICBzZXRBY2NlcHRMYW5nKHBhcnQpOworICAgICAgICByZXR1cm4gcGFydDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGYWN0b3J5IHRvIGNyZWF0ZSB0aGUgYXR0YWNobWVudCBib2R5IHBhcnQuCisgICAgICogQHBhcmFtIGluZGV4IHRoZSBhdHRhY2htZW50IGluZGV4LgorICAgICAqIEByZXR1cm4gYSBib2R5IHBhcnQgd2l0aCBkZWZhdWx0IGhlYWRlcnMgc2V0LgorICAgICAqIEB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIGlmIHRoZXJlIGlzIGEgcHJvYmxlbS4KKyAgICAgKiBAdGhyb3dzIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWYgdGhlIGdpdmVuIGluZGV4IGlzIG5vdCBhbiB2YWxpZAorICAgICAqIGF0dGFjaG1lbnQgaW5kZXguCisgICAgICovCisgICAgcHJpdmF0ZSBNaW1lQm9keVBhcnQgY3JlYXRlQm9keVBhcnQoaW50IGluZGV4KSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0IFRocmVhZC5ob2xkc0xvY2sodGhpcyk7CisgICAgICAgIGZpbmFsIE1pbWVCb2R5UGFydCBwYXJ0ID0gbmV3IE1pbWVCb2R5UGFydCgpOworICAgICAgICBwYXJ0LnNldERpc3Bvc2l0aW9uKFBhcnQuQVRUQUNITUVOVCk7CisgICAgICAgIHBhcnQuc2V0RGVzY3JpcHRpb24oZGVzY3JpcHRpb25Gcm9tKAorICAgICAgICAgICAgICAgIGF0dGFjaG1lbnRGb3JtYXR0ZXJzW2luZGV4XSwKKyAgICAgICAgICAgICAgICBhdHRhY2htZW50RmlsdGVyc1tpbmRleF0sCisgICAgICAgICAgICAgICAgYXR0YWNobWVudE5hbWVzW2luZGV4XSkpOworICAgICAgICBzZXRBY2NlcHRMYW5nKHBhcnQpOworICAgICAgICByZXR1cm4gcGFydDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBkZXNjcmlwdGlvbiBmb3IgdGhlIE1pbWVNZXNzYWdlIGl0c2VsZi4KKyAgICAgKiBUaGUgcHVzaCBsZXZlbCBhbmQgZmlsdGVyIGFyZSBpbmNsdWRlZCBiZWNhdXNlIHRoZXkgcGxheSBhIHJvbGUgaW4KKyAgICAgKiBmb3JtYXR0aW5nIG9mIGEgbWVzc2FnZSB3aGVuIHRyaWdnZXJlZCBvciBub3QgdHJpZ2dlcmVkLgorICAgICAqIEBwYXJhbSBjIHRoZSBjb21wYXJhdG9yLgorICAgICAqIEBwYXJhbSBsIHRoZSBwdXNoTGV2ZWwuCisgICAgICogQHBhcmFtIGYgdGhlIHB1c2hGaWx0ZXIKKyAgICAgKiBAcmV0dXJuIHRoZSBkZXNjcmlwdGlvbi4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIGxldmVsIGlzIG51bGwuCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNC41CisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgZGVzY3JpcHRpb25Gcm9tKENvbXBhcmF0b3I8Pz4gYywgTGV2ZWwgbCwgRmlsdGVyIGYpIHsKKyAgICAgICAgcmV0dXJuICJTb3J0ZWQgdXNpbmcgIisgKGMgPT0gbnVsbCA/ICJubyBjb21wYXJhdG9yIgorICAgICAgICAgICAgICAgIDogYy5nZXRDbGFzcygpLmdldE5hbWUoKSkgKyAiLCBwdXNoZWQgd2hlbiAiKyBsLmdldE5hbWUoKQorICAgICAgICAgICAgICAgICsgIiwgYW5kICIgKyAoZiA9PSBudWxsID8gIm5vIHB1c2ggZmlsdGVyIgorICAgICAgICAgICAgICAgICAgICAgICAgOiBmLmdldENsYXNzKCkuZ2V0TmFtZSgpKSArICcuJzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgZGVzY3JpcHRpb24gZm9yIGEgYm9keSBwYXJ0LgorICAgICAqIEBwYXJhbSBmIHRoZSBjb250ZW50IGZvcm1hdHRlci4KKyAgICAgKiBAcGFyYW0gZmlsdGVyIHRoZSBjb250ZW50IGZpbHRlci4KKyAgICAgKiBAcGFyYW0gbmFtZSB0aGUgbmFtaW5nIGZvcm1hdHRlci4KKyAgICAgKiBAcmV0dXJuIHRoZSBkZXNjcmlwdGlvbiBmb3IgdGhlIGJvZHkgcGFydC4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyBkZXNjcmlwdGlvbkZyb20oRm9ybWF0dGVyIGYsIEZpbHRlciBmaWx0ZXIsIEZvcm1hdHRlciBuYW1lKSB7CisgICAgICAgIHJldHVybiAiRm9ybWF0dGVkIHVzaW5nICIgKyBnZXRDbGFzc0lkKGYpCisgICAgICAgICAgICAgICAgKyAiLCBmaWx0ZXJlZCB3aXRoICIgKyAoZmlsdGVyID09IG51bGwgPyAibm8gZmlsdGVyIgorICAgICAgICAgICAgICAgIDogZmlsdGVyLmdldENsYXNzKCkuZ2V0TmFtZSgpKSArIiwgYW5kIG5hbWVkIGJ5ICIKKyAgICAgICAgICAgICAgICArIGdldENsYXNzSWQobmFtZSkgKyAnLic7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyBhIGNsYXNzIG5hbWUgcmVwcmVzZW50cyB0aGUgYmVoYXZpb3Igb2YgdGhlIGZvcm1hdHRlci4KKyAgICAgKiBUaGUgY2xhc3MgbmFtZSBtYXkgbm90IGJlIGFzc2lnbmFibGUgdG8gYSBGb3JtYXR0ZXIuCisgICAgICogQHBhcmFtIGYgdGhlIGZvcm1hdHRlci4KKyAgICAgKiBAcmV0dXJuIGEgY2xhc3MgbmFtZSB0aGF0IHJlcHJlc2VudHMgdGhlIGdpdmVuIGZvcm1hdHRlci4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBwYXJhbWV0ZXIgaXMgbnVsbC4KKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS40LjUKKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyBnZXRDbGFzc0lkKGZpbmFsIEZvcm1hdHRlciBmKSB7CisgICAgICAgIGlmIChmIGluc3RhbmNlb2YgVGFpbE5hbWVGb3JtYXR0ZXIpIHsKKyAgICAgICAgICAgIHJldHVybiBTdHJpbmcuY2xhc3MuZ2V0TmFtZSgpOyAvL0xpdGVyYWwgc3RyaW5nLgorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIGYuZ2V0Q2xhc3MoKS5nZXROYW1lKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFbnN1cmUgdGhhdCBhIGZvcm1hdHRlciBjcmVhdGVzIGEgdmFsaWQgc3RyaW5nIGZvciBhIHBhcnQgbmFtZS4KKyAgICAgKiBAcGFyYW0gZiB0aGUgZm9ybWF0dGVyLgorICAgICAqIEByZXR1cm4gdGhlIHRvIHN0cmluZyB2YWx1ZSBvciB0aGUgY2xhc3MgbmFtZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyB0b1N0cmluZyhmaW5hbCBGb3JtYXR0ZXIgZikgeworICAgICAgICAvL1Nob3VsZCBuZXZlciBiZSBudWxsIGJ1dCwgZ3VhcmQgYWdhaW5zdCBmb3JtYXR0ZXIgYnVncy4KKyAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUgPSBmLnRvU3RyaW5nKCk7CisgICAgICAgIGlmICghaXNFbXB0eShuYW1lKSkgeworICAgICAgICAgICAgcmV0dXJuIG5hbWU7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gZ2V0Q2xhc3NJZChmKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBmaWxlIG5hbWUgZnJvbSBhIGZvcm1hdHRlci4gIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBvZnRlbgorICAgICAqIGJ1dCwgcmFyZWx5IGRvZXMgYW55IHdvcmsuCisgICAgICogQHBhcmFtIHBhcnQgdG8gYXBwZW5kIHRvLgorICAgICAqIEBwYXJhbSBjaHVuayBub24gbnVsbCBzdHJpbmcgdG8gYXBwZW5kLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBhcHBlbmRGaWxlTmFtZShmaW5hbCBQYXJ0IHBhcnQsIGZpbmFsIFN0cmluZyBjaHVuaykgeworICAgICAgICBpZiAoY2h1bmsgIT0gbnVsbCkgeworICAgICAgICAgICAgaWYgKGNodW5rLmxlbmd0aCgpID4gMCkgeworICAgICAgICAgICAgICAgIGFwcGVuZEZpbGVOYW1lMChwYXJ0LCBjaHVuayk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXBvcnROdWxsRXJyb3IoRXJyb3JNYW5hZ2VyLkZPUk1BVF9GQUlMVVJFKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEl0IGlzIGFzc3VtZWQgdGhhdCBmaWxlIG5hbWVzIGFyZSBzaG9ydCBhbmQgdGhhdCBpbiBtb3N0IGNhc2VzCisgICAgICogZ2V0VGFpbCB3aWxsIGJlIHRoZSBvbmx5IG1ldGhvZCB0aGF0IHdpbGwgcHJvZHVjZSBhIHJlc3VsdC4KKyAgICAgKiBAcGFyYW0gcGFydCB0byBhcHBlbmQgdG8uCisgICAgICogQHBhcmFtIGNodW5rIG5vbiBudWxsIHN0cmluZyB0byBhcHBlbmQuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGFwcGVuZEZpbGVOYW1lMChmaW5hbCBQYXJ0IHBhcnQsIFN0cmluZyBjaHVuaykgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy9SZW1vdmUgYWxsIGNvbnRyb2wgY2hhcmFjdGVyIGdyb3Vwcy4KKyAgICAgICAgICAgIGNodW5rID0gY2h1bmsucmVwbGFjZUFsbCgiW1xceDAwLVxceDFGXFx4N0ZdKyIsICIiKTsKKyAgICAgICAgICAgIGZpbmFsIFN0cmluZyBvbGQgPSBwYXJ0LmdldEZpbGVOYW1lKCk7CisgICAgICAgICAgICBwYXJ0LnNldEZpbGVOYW1lKG9sZCAhPSBudWxsID8gb2xkLmNvbmNhdChjaHVuaykgOiBjaHVuayk7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIE1lc3NhZ2luZ0V4Y2VwdGlvbiBNRSkgeworICAgICAgICAgICAgcmVwb3J0RXJyb3IoTUUuZ2V0TWVzc2FnZSgpLCBNRSwgRXJyb3JNYW5hZ2VyLkZPUk1BVF9GQUlMVVJFKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBzdWJqZWN0IGxpbmUgZnJvbSBhIGZvcm1hdHRlci4KKyAgICAgKiBAcGFyYW0gbXNnIHRvIGFwcGVuZCB0by4KKyAgICAgKiBAcGFyYW0gY2h1bmsgbm9uIG51bGwgc3RyaW5nIHRvIGFwcGVuZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgYXBwZW5kU3ViamVjdChmaW5hbCBNZXNzYWdlIG1zZywgZmluYWwgU3RyaW5nIGNodW5rKSB7CisgICAgICAgIGlmIChjaHVuayAhPSBudWxsKSB7CisgICAgICAgICAgICBpZiAoY2h1bmsubGVuZ3RoKCkgPiAwKSB7CisgICAgICAgICAgICAgICAgYXBwZW5kU3ViamVjdDAobXNnLCBjaHVuayk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXBvcnROdWxsRXJyb3IoRXJyb3JNYW5hZ2VyLkZPUk1BVF9GQUlMVVJFKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEl0IGlzIGFzc3VtZWQgdGhhdCBzdWJqZWN0IGxpbmVzIGFyZSBzaG9ydCBhbmQgdGhhdCBpbiBtb3N0IGNhc2VzCisgICAgICogZ2V0VGFpbCB3aWxsIGJlIHRoZSBvbmx5IG1ldGhvZCB0aGF0IHdpbGwgcHJvZHVjZSBhIHJlc3VsdC4KKyAgICAgKiBAcGFyYW0gbXNnIHRvIGFwcGVuZCB0by4KKyAgICAgKiBAcGFyYW0gY2h1bmsgbm9uIG51bGwgc3RyaW5nIHRvIGFwcGVuZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgYXBwZW5kU3ViamVjdDAoZmluYWwgTWVzc2FnZSBtc2csIFN0cmluZyBjaHVuaykgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy9SZW1vdmUgYWxsIGNvbnRyb2wgY2hhcmFjdGVyIGdyb3Vwcy4KKyAgICAgICAgICAgIGNodW5rID0gY2h1bmsucmVwbGFjZUFsbCgiW1xceDAwLVxceDFGXFx4N0ZdKyIsICIiKTsKKyAgICAgICAgICAgIGZpbmFsIFN0cmluZyBjaGFyc2V0ID0gZ2V0RW5jb2RpbmdOYW1lKCk7CisgICAgICAgICAgICBmaW5hbCBTdHJpbmcgb2xkID0gbXNnLmdldFN1YmplY3QoKTsKKyAgICAgICAgICAgIGFzc2VydCBtc2cgaW5zdGFuY2VvZiBNaW1lTWVzc2FnZSA6IG1zZzsKKyAgICAgICAgICAgICgoTWltZU1lc3NhZ2UpIG1zZykuc2V0U3ViamVjdChvbGQgIT0gbnVsbCA/IG9sZC5jb25jYXQoY2h1bmspCisgICAgICAgICAgICAgICAgICAgIDogY2h1bmssIE1pbWVVdGlsaXR5Lm1pbWVDaGFyc2V0KGNoYXJzZXQpKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgTWVzc2FnaW5nRXhjZXB0aW9uIE1FKSB7CisgICAgICAgICAgICByZXBvcnRFcnJvcihNRS5nZXRNZXNzYWdlKCksIE1FLCBFcnJvck1hbmFnZXIuRk9STUFUX0ZBSUxVUkUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbG9jYWxlIGZvciB0aGUgZ2l2ZW4gbG9nIHJlY29yZCBmcm9tIHRoZSByZXNvdXJjZSBidW5kbGUuCisgICAgICogSWYgdGhlIHJlc291cmNlIGJ1bmRsZSBpcyB1c2luZyB0aGUgcm9vdCBsb2NhbGUgdGhlbiB0aGUgZGVmYXVsdCBsb2NhbGUKKyAgICAgKiBpcyByZXR1cm5lZC4KKyAgICAgKiBAcGFyYW0gciB0aGUgbG9nIHJlY29yZC4KKyAgICAgKiBAcmV0dXJuIG51bGwgaWYgbm90IGxvY2FsaXplZCBvdGhlcndpc2UsIHRoZSBsb2NhbGUgb2YgdGhlIHJlY29yZC4KKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS40LjUKKyAgICAgKi8KKyAgICBwcml2YXRlIExvY2FsZSBsb2NhbGVGb3IoZmluYWwgTG9nUmVjb3JkIHIpIHsKKyAgICAgICAgTG9jYWxlIGw7CisgICAgICAgIGZpbmFsIFJlc291cmNlQnVuZGxlIHJiID0gci5nZXRSZXNvdXJjZUJ1bmRsZSgpOworICAgICAgICBpZiAocmIgIT0gbnVsbCkgeworICAgICAgICAgICAgbCA9IHJiLmdldExvY2FsZSgpOworICAgICAgICAgICAgaWYgKGwgPT0gbnVsbCB8fCBpc0VtcHR5KGwuZ2V0TGFuZ3VhZ2UoKSkpIHsKKyAgICAgICAgICAgICAgICAvL1RoZSBsYW5ndWFnZSBvZiB0aGUgZmFsbGJhY2sgYnVuZGxlIChyb290KSBpcyB1bmtub3duLgorICAgICAgICAgICAgICAgIC8vMS4gVXNlIGRlZmF1bHQgbG9jYWxlLiAgU2hvdWxkIG9ubHkgYmUgd3JvbmcgaWYgdGhlIGFwcCBpcworICAgICAgICAgICAgICAgIC8vICAgdXNlZCB3aXRoIGEgbGFuZ2F1Z2UgdGhhdCB3YXMgdW5pbnRlbmRlZC4gKHVubGlrZWx5KQorICAgICAgICAgICAgICAgIC8vMi4gTWFyayBpdCBhcyBub3QgbG9jYWxpemVkIChmb3JjZSBudWxsLCBpbmZvIGxvc3MpLgorICAgICAgICAgICAgICAgIC8vMy4gVXNlIHRoZSBidW5kbGUgbmFtZSAoZW5jb2RlZCkgYXMgYW4gZXhwZXJpbWVudGFsIGxhbmd1YWdlLgorICAgICAgICAgICAgICAgIGwgPSBMb2NhbGUuZ2V0RGVmYXVsdCgpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgbCA9IG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXBwZW5kcyB0aGUgY29udGVudCBsYW5ndWFnZSB0byB0aGUgZ2l2ZW4gbWltZSBwYXJ0LgorICAgICAqIFRoZSBsYW5ndWFnZSB0YWcgaXMgb25seSBhcHBlbmRlZCBpZiB0aGUgZ2l2ZW4gbGFuZ3VhZ2UgaGFzIG5vdCBiZWVuCisgICAgICogc3BlY2lmaWVkLiAgVGhpcyBtZXRob2QgaXMgb25seSB1c2VkIHdoZW4gd2UgaGF2ZSBMb2dSZWNvcmRzIHRoYXQgYXJlCisgICAgICogbG9jYWxpemVkIHdpdGggYW4gYXNzaWduZWQgcmVzb3VyY2UgYnVuZGxlLgorICAgICAqIEBwYXJhbSBwIHRoZSBtaW1lIHBhcnQuCisgICAgICogQHBhcmFtIGwgdGhlIGxvY2FsZSB0byBhcHBlbmQuCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiBhbnkgYXJndW1lbnQgaXMgbnVsbC4KKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS40LjUKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgYXBwZW5kQ29udGVudExhbmcoZmluYWwgTWltZVBhcnQgcCwgZmluYWwgTG9jYWxlIGwpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyBsYW5nID0gTG9nTWFuYWdlclByb3BlcnRpZXMudG9MYW5ndWFnZVRhZyhsKTsKKyAgICAgICAgICAgIGlmIChsYW5nLmxlbmd0aCgpICE9IDApIHsKKyAgICAgICAgICAgICAgICBTdHJpbmcgaGVhZGVyID0gcC5nZXRIZWFkZXIoIkNvbnRlbnQtTGFuZ3VhZ2UiLCBudWxsKTsKKyAgICAgICAgICAgICAgICBpZiAoaXNFbXB0eShoZWFkZXIpKSB7CisgICAgICAgICAgICAgICAgICAgIHAuc2V0SGVhZGVyKCJDb250ZW50LUxhbmd1YWdlIiwgbGFuZyk7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghaGVhZGVyLmVxdWFsc0lnbm9yZUNhc2UobGFuZykpIHsKKyAgICAgICAgICAgICAgICAgICAgbGFuZyA9ICIsIi5jb25jYXQobGFuZyk7CisgICAgICAgICAgICAgICAgICAgIGludCBpZHggPSAwOworICAgICAgICAgICAgICAgICAgICB3aGlsZSAoKGlkeCA9IGhlYWRlci5pbmRleE9mKGxhbmcsIGlkeCkpID4gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlkeCArPSBsYW5nLmxlbmd0aCgpOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlkeCA9PSBoZWFkZXIubGVuZ3RoKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgaGVhZGVyLmNoYXJBdChpZHgpID09ICcsJykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgaWYgKGlkeCA8IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGludCBsZW4gPSBoZWFkZXIubGFzdEluZGV4T2YoIlxyXG5cdCIpOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxlbiA8IDApIHsgLy9JZiBub3QgZm9sZGVkLgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlbiA9ICgxOCArIDIpICsgaGVhZGVyLmxlbmd0aCgpOworICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZW4gPSAoaGVhZGVyLmxlbmd0aCgpIC0gbGVuKSArIDg7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vUGVyZm9ybSBmb2xkaW5nIG9mIGhlYWRlciBpZiBuZWVkZWQuCisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKGxlbiArIGxhbmcubGVuZ3RoKCkpID4gNzYpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWFkZXIgPSBoZWFkZXIuY29uY2F0KCJcclxuXHQiLmNvbmNhdChsYW5nKSk7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlYWRlciA9IGhlYWRlci5jb25jYXQobGFuZyk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBwLnNldEhlYWRlcigiQ29udGVudC1MYW5ndWFnZSIsIGhlYWRlcik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIE1lc3NhZ2luZ0V4Y2VwdGlvbiBNRSkgeworICAgICAgICAgICAgcmVwb3J0RXJyb3IoTUUuZ2V0TWVzc2FnZSgpLCBNRSwgRXJyb3JNYW5hZ2VyLkZPUk1BVF9GQUlMVVJFKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGFjY2VwdCBsYW5ndWFnZSB0byB0aGUgZGVmYXVsdCBsb2NhbGUgb2YgdGhlIEpWTS4KKyAgICAgKiBJZiB0aGUgbG9jYWxlIGlzIHRoZSByb290IGxvY2FsZSB0aGUgaGVhZGVyIGlzIG5vdCBhZGRlZC4KKyAgICAgKiBAcGFyYW0gcCB0aGUgcGFydCB0byBzZXQuCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNC41CisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHNldEFjY2VwdExhbmcoZmluYWwgUGFydCBwKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaW5hbCBTdHJpbmcgbGFuZyA9IExvZ01hbmFnZXJQcm9wZXJ0aWVzCisgICAgICAgICAgICAgICAgICAgIC50b0xhbmd1YWdlVGFnKExvY2FsZS5nZXREZWZhdWx0KCkpOworICAgICAgICAgICAgaWYgKGxhbmcubGVuZ3RoKCkgIT0gMCkgeworICAgICAgICAgICAgICAgIHAuc2V0SGVhZGVyKCJBY2NlcHQtTGFuZ3VhZ2UiLCBsYW5nKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoZmluYWwgTWVzc2FnaW5nRXhjZXB0aW9uIE1FKSB7CisgICAgICAgICAgICByZXBvcnRFcnJvcihNRS5nZXRNZXNzYWdlKCksIE1FLCBFcnJvck1hbmFnZXIuRk9STUFUX0ZBSUxVUkUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVXNlZCB3aGVuIGEgbG9nIHJlY29yZCB3YXMgbG9nZ2FibGUgcHJpb3IgdG8gYmVpbmcgaW5zZXJ0ZWQKKyAgICAgKiBpbnRvIHRoZSBidWZmZXIgYnV0IGF0IHRoZSB0aW1lIG9mIGZvcm1hdHRpbmcgd2FzIG5vIGxvbmdlciBsb2dnYWJsZS4KKyAgICAgKiBGaWx0ZXJzIHdlcmUgY2hhbmdlZCBhZnRlciBwdWJsaXNoIGJ1dCBwcmlvciB0byBhIHB1c2ggb3IgYSBidWcgaW4gdGhlCisgICAgICogYm9keSBmaWx0ZXIgb3Igb25lIG9mIHRoZSBhdHRhY2htZW50IGZpbHRlcnMuCisgICAgICogQHBhcmFtIHJlY29yZCB0aGF0IHdhcyBub3QgZm9ybWF0dGVkLgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjQuNQorICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZXBvcnRGaWx0ZXJFcnJvcihmaW5hbCBMb2dSZWNvcmQgcmVjb3JkKSB7CisgICAgICAgIGFzc2VydCBUaHJlYWQuaG9sZHNMb2NrKHRoaXMpOworICAgICAgICBmaW5hbCBGb3JtYXR0ZXIgZiA9IGNyZWF0ZVNpbXBsZUZvcm1hdHRlcigpOworICAgICAgICBmaW5hbCBTdHJpbmcgbXNnID0gIkxvZyByZWNvcmQgIiArIHJlY29yZC5nZXRTZXF1ZW5jZU51bWJlcigpCisgICAgICAgICAgICAgICAgKyAiIHdhcyBmaWx0ZXJlZCBmcm9tIGFsbCBtZXNzYWdlIHBhcnRzLiAgIgorICAgICAgICAgICAgICAgICsgaGVhZChmKSArIGZvcm1hdChmLCByZWNvcmQpICsgdGFpbChmLCAiIik7CisgICAgICAgIGZpbmFsIFN0cmluZyB0eHQgPSBnZXRGaWx0ZXIoKSArICIsICIKKyAgICAgICAgICAgICAgICArIEFycmF5cy5hc0xpc3QocmVhZE9ubHlBdHRhY2htZW50RmlsdGVycygpKTsKKyAgICAgICAgcmVwb3J0RXJyb3IobXNnLCBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKHR4dCksCisgICAgICAgICAgICAgICAgRXJyb3JNYW5hZ2VyLkZPUk1BVF9GQUlMVVJFKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXBvcnRzIHN5bW1ldHJpYyBjb250cmFjdCB2aW9sYXRpb25zIGFuIGVxdWFscyBpbXBsZW1lbnRhdGlvbi4KKyAgICAgKiBAcGFyYW0gbyB0aGUgdGVzdCBvYmplY3QgbXVzdCBiZSBub24gbnVsbC4KKyAgICAgKiBAcGFyYW0gZm91bmQgdGhlIHBvc3NpYmxlIGludGVybiwgbXVzdCBiZSBub24gbnVsbC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIGFueSBhcmd1bWVudCBpcyBudWxsLgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjUuMAorICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZXBvcnROb25TeW1tZXRyaWMoZmluYWwgT2JqZWN0IG8sIGZpbmFsIE9iamVjdCBmb3VuZCkgeworICAgICAgICByZXBvcnRFcnJvcigiTm9uIHN5bW1ldHJpYyBlcXVhbHMgaW1wbGVtZW50YXRpb24uIgorICAgICAgICAgICAgICAgICwgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihvLmdldENsYXNzKCkuZ2V0TmFtZSgpCisgICAgICAgICAgICAgICAgKyAiIGlzIG5vdCBlcXVhbCB0byAiICsgZm91bmQuZ2V0Q2xhc3MoKS5nZXROYW1lKCkpCisgICAgICAgICAgICAgICAgLCBFcnJvck1hbmFnZXIuT1BFTl9GQUlMVVJFKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXBvcnRzIGVxdWFscyBpbXBsZW1lbnRhdGlvbnMgdGhhdCBkbyBub3QgZGlzY3JpbWluYXRlIGJldHdlZW4gb2JqZWN0cworICAgICAqIG9mIGRpZmZlcmVudCB0eXBlcyBvciBzdWJjbGFzcyB0eXBlcy4KKyAgICAgKiBAcGFyYW0gbyB0aGUgdGVzdCBvYmplY3QgbXVzdCBiZSBub24gbnVsbC4KKyAgICAgKiBAcGFyYW0gZm91bmQgdGhlIHBvc3NpYmxlIGludGVybiwgbXVzdCBiZSBub24gbnVsbC4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIGFueSBhcmd1bWVudCBpcyBudWxsLgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjUuMAorICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZXBvcnROb25EaXNjcmltaW5hdGluZyhmaW5hbCBPYmplY3QgbywgZmluYWwgT2JqZWN0IGZvdW5kKSB7CisgICAgICAgIHJlcG9ydEVycm9yKCJOb24gZGlzY3JpbWluYXRpbmcgZXF1YWxzIGltcGxlbWVudGF0aW9uLiIKKyAgICAgICAgICAgICAgICAsIG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oby5nZXRDbGFzcygpLmdldE5hbWUoKQorICAgICAgICAgICAgICAgICsgIiBzaG91bGQgbm90IGJlIGVxdWFsIHRvICIgKyBmb3VuZC5nZXRDbGFzcygpLmdldE5hbWUoKSkKKyAgICAgICAgICAgICAgICAsIEVycm9yTWFuYWdlci5PUEVOX0ZBSUxVUkUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFVzZWQgdG8gb3V0bGluZSB0aGUgYnl0ZXMgdG8gcmVwb3J0IGEgbnVsbCBwb2ludGVyIGV4Y2VwdGlvbi4KKyAgICAgKiBTZWUgQlVEIElEIDY1MzMxNjUuCisgICAgICogQHBhcmFtIGNvZGUgdGhlIEVycm9yTWFuYWdlciBjb2RlLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCByZXBvcnROdWxsRXJyb3IoZmluYWwgaW50IGNvZGUpIHsKKyAgICAgICAgcmVwb3J0RXJyb3IoIm51bGwiLCBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKSwgY29kZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyB0aGUgaGVhZCBvciByZXBvcnRzIGEgZm9ybWF0dGluZyBlcnJvci4KKyAgICAgKiBAcGFyYW0gZiB0aGUgZm9ybWF0dGVyLgorICAgICAqIEByZXR1cm4gdGhlIGhlYWQgc3RyaW5nIG9yIGFuIGVtcHR5IHN0cmluZy4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyBoZWFkKGZpbmFsIEZvcm1hdHRlciBmKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gZi5nZXRIZWFkKHRoaXMpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBSdW50aW1lRXhjZXB0aW9uIFJFKSB7CisgICAgICAgICAgICByZXBvcnRFcnJvcihSRS5nZXRNZXNzYWdlKCksIFJFLCBFcnJvck1hbmFnZXIuRk9STUFUX0ZBSUxVUkUpOworICAgICAgICAgICAgcmV0dXJuICIiOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyB0aGUgZm9ybWF0dGVkIGxvZyByZWNvcmQgb3IgcmVwb3J0cyBhIGZvcm1hdHRpbmcgZXJyb3IuCisgICAgICogQHBhcmFtIGYgdGhlIGZvcm1hdHRlci4KKyAgICAgKiBAcGFyYW0gciB0aGUgbG9nIHJlY29yZC4KKyAgICAgKiBAcmV0dXJuIHRoZSBmb3JtYXR0ZWQgc3RyaW5nIG9yIGFuIGVtcHR5IHN0cmluZy4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyBmb3JtYXQoZmluYWwgRm9ybWF0dGVyIGYsIGZpbmFsIExvZ1JlY29yZCByKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXR1cm4gZi5mb3JtYXQocik7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIFJ1bnRpbWVFeGNlcHRpb24gUkUpIHsKKyAgICAgICAgICAgIHJlcG9ydEVycm9yKFJFLmdldE1lc3NhZ2UoKSwgUkUsIEVycm9yTWFuYWdlci5GT1JNQVRfRkFJTFVSRSk7CisgICAgICAgICAgICByZXR1cm4gIiI7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIHRoZSB0YWlsIG9yIHJlcG9ydHMgYSBmb3JtYXR0aW5nIGVycm9yLgorICAgICAqIEBwYXJhbSBmIHRoZSBmb3JtYXR0ZXIuCisgICAgICogQHBhcmFtIGRlZiB0aGUgZGVmYXVsdCBzdHJpbmcgdG8gdXNlIHdoZW4gdGhlcmUgaXMgYW4gZXJyb3IuCisgICAgICogQHJldHVybiB0aGUgdGFpbCBzdHJpbmcgb3IgdGhlIGdpdmVuIGRlZmF1bHQgc3RyaW5nLgorICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nIHRhaWwoZmluYWwgRm9ybWF0dGVyIGYsIGZpbmFsIFN0cmluZyBkZWYpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBmLmdldFRhaWwodGhpcyk7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIFJ1bnRpbWVFeGNlcHRpb24gUkUpIHsKKyAgICAgICAgICAgIHJlcG9ydEVycm9yKFJFLmdldE1lc3NhZ2UoKSwgUkUsIEVycm9yTWFuYWdlci5GT1JNQVRfRkFJTFVSRSk7CisgICAgICAgICAgICByZXR1cm4gZGVmOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgeC1tYWlsZXIgaGVhZGVyLgorICAgICAqIEBwYXJhbSBtc2cgdGhlIHRhcmdldCBtZXNzYWdlLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBzZXRNYWlsZXIoZmluYWwgTWVzc2FnZSBtc2cpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZpbmFsIENsYXNzPD8+IG1haWwgPSBNYWlsSGFuZGxlci5jbGFzczsKKyAgICAgICAgICAgIGZpbmFsIENsYXNzPD8+IGsgPSBnZXRDbGFzcygpOworICAgICAgICAgICAgU3RyaW5nIHZhbHVlOworICAgICAgICAgICAgaWYgKGsgPT0gbWFpbCkgeworICAgICAgICAgICAgICAgIHZhbHVlID0gbWFpbC5nZXROYW1lKCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gTWltZVV0aWxpdHkuZW5jb2RlVGV4dChrLmdldE5hbWUoKSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBFKSB7CisgICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKEUuZ2V0TWVzc2FnZSgpLCBFLCBFcnJvck1hbmFnZXIuRk9STUFUX0ZBSUxVUkUpOworICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGsuZ2V0TmFtZSgpLnJlcGxhY2VBbGwoIlteXFx4MDAtXFx4N0ZdIiwgIlx1dTAwMUEiKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdmFsdWUgPSBNaW1lVXRpbGl0eS5mb2xkKDEwLCBtYWlsLmdldE5hbWUoKSArICIgdXNpbmcgdGhlICIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgdmFsdWUgKyAiIGV4dGVuc2lvbi4iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG1zZy5zZXRIZWFkZXIoIlgtTWFpbGVyIiwgdmFsdWUpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBNZXNzYWdpbmdFeGNlcHRpb24gTUUpIHsKKyAgICAgICAgICAgIHJlcG9ydEVycm9yKE1FLmdldE1lc3NhZ2UoKSwgTUUsIEVycm9yTWFuYWdlci5GT1JNQVRfRkFJTFVSRSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBwcmlvcml0eSBhbmQgaW1wb3J0YW5jZSBoZWFkZXJzLgorICAgICAqIEBwYXJhbSBtc2cgdGhlIHRhcmdldCBtZXNzYWdlLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBzZXRQcmlvcml0eShmaW5hbCBNZXNzYWdlIG1zZykgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgbXNnLnNldEhlYWRlcigiSW1wb3J0YW5jZSIsICJIaWdoIik7CisgICAgICAgICAgICBtc2cuc2V0SGVhZGVyKCJQcmlvcml0eSIsICJ1cmdlbnQiKTsKKyAgICAgICAgICAgIG1zZy5zZXRIZWFkZXIoIlgtUHJpb3JpdHkiLCAiMiIpOyAvL0hpZ2gKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgTWVzc2FnaW5nRXhjZXB0aW9uIE1FKSB7CisgICAgICAgICAgICByZXBvcnRFcnJvcihNRS5nZXRNZXNzYWdlKCksIE1FLCBFcnJvck1hbmFnZXIuRk9STUFUX0ZBSUxVUkUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVXNlZCB0byBzaWduYWwgdGhhdCBib2R5IHBhcnRzIGFyZSBtaXNzaW5nIGZyb20gYSBtZXNzYWdlLiAgQWxzbyB1c2VkCisgICAgICogd2hlbiBMb2dSZWNvcmRzIHdlcmUgcGFzc2VkIHRvIGFuIGF0dGFjaG1lbnQgZm9ybWF0dGVyIGJ1dCB0aGUgZm9ybWF0dGVyCisgICAgICogcHJvZHVjZWQgbm8gb3V0cHV0LCB3aGljaCBpcyBhbGxvd2VkLiAgVXNlZCBkdXJpbmcgYSB2ZXJpZnkgYmVjYXVzZSBhbGwKKyAgICAgKiBwYXJ0cyBhcmUgb21pdHRlZCwgbm9uZSBvZiB0aGUgY29udGVudCBmb3JtYXR0ZXJzIGFyZSB1c2VkLiAgVGhpcyBpcworICAgICAqIG5vdCB1c2VkIHdoZW4gYSBmaWx0ZXIgcHJldmVudHMgTG9nUmVjb3JkcyBmcm9tIGJlaW5nIGZvcm1hdHRlZC4KKyAgICAgKiBUaGlzIGhlYWRlciBpcyBkZWZpbmVkIGluIFJGQyAyMTU2IGFuZCBSRkMgNDAyMS4KKyAgICAgKiBAcGFyYW0gbXNnIHRoZSBtZXNzYWdlLgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjQuNQorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBzZXRJbmNvbXBsZXRlQ29weShmaW5hbCBNZXNzYWdlIG1zZykgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgbXNnLnNldEhlYWRlcigiSW5jb21wbGV0ZS1Db3B5IiwgIiIpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBNZXNzYWdpbmdFeGNlcHRpb24gTUUpIHsKKyAgICAgICAgICAgIHJlcG9ydEVycm9yKE1FLmdldE1lc3NhZ2UoKSwgTUUsIEVycm9yTWFuYWdlci5GT1JNQVRfRkFJTFVSRSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTaWduYWxzIHRoYXQgdGhpcyBtZXNzYWdlIHdhcyBnZW5lcmF0ZWQgYnkgYXV0b21hdGljIHByb2Nlc3MuCisgICAgICogVGhpcyBoZWFkZXIgaXMgZGVmaW5lZCBpbiBSRkMgMzgzNCBzZWN0aW9uIDUuCisgICAgICogQHBhcmFtIG1zZyB0aGUgbWVzc2FnZS4KKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS40LjYKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgc2V0QXV0b1N1Ym1pdHRlZChmaW5hbCBNZXNzYWdlIG1zZykgeworICAgICAgICBpZiAoYWxsb3dSZXN0cmljdGVkSGVhZGVycygpKSB7CisgICAgICAgICAgICB0cnkgeyAvL1JGQyAzODM0ICg1LjIpCisgICAgICAgICAgICAgICAgbXNnLnNldEhlYWRlcigiYXV0by1zdWJtaXR0ZWQiLCAiYXV0by1nZW5lcmF0ZWQiKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKGZpbmFsIE1lc3NhZ2luZ0V4Y2VwdGlvbiBNRSkgeworICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKE1FLmdldE1lc3NhZ2UoKSwgTUUsIEVycm9yTWFuYWdlci5GT1JNQVRfRkFJTFVSRSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIGZyb20gYWRkcmVzcyBoZWFkZXIuCisgICAgICogQHBhcmFtIG1zZyB0aGUgdGFyZ2V0IG1lc3NhZ2UuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHNldEZyb20oZmluYWwgTWVzc2FnZSBtc2cpIHsKKyAgICAgICAgZmluYWwgU3RyaW5nIGZyb20gPSBnZXRTZXNzaW9uKG1zZykuZ2V0UHJvcGVydHkoIm1haWwuZnJvbSIpOworICAgICAgICBpZiAoZnJvbSAhPSBudWxsKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGZpbmFsIEFkZHJlc3NbXSBhZGRyZXNzID0gSW50ZXJuZXRBZGRyZXNzLnBhcnNlKGZyb20sIGZhbHNlKTsKKyAgICAgICAgICAgICAgICBpZiAoYWRkcmVzcy5sZW5ndGggPiAwKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChhZGRyZXNzLmxlbmd0aCA9PSAxKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBtc2cuc2V0RnJvbShhZGRyZXNzWzBdKTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsgLy9HcmVhdGVyIHRoYW4gMSBhZGRyZXNzLgorICAgICAgICAgICAgICAgICAgICAgICAgbXNnLmFkZEZyb20oYWRkcmVzcyk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgLy9DYW4ndCBwbGFjZSBhbiBlbHNlIHN0YXRlbWVudCBoZXJlIGJlY2F1c2UgdGhlICdmcm9tJyBpcworICAgICAgICAgICAgICAgIC8vbm90IG51bGwgd2hpY2ggY2F1c2VzIHRoZSBsb2NhbCBhZGRyZXNzIGNvbXB1dGF0aW9uCisgICAgICAgICAgICAgICAgLy90byBmYWlsLiAgQXNzdW1lIHRoZSB1c2VyIHdhbnRzIHRvIG9taXQgdGhlIGZyb20gYWRkcmVzcworICAgICAgICAgICAgICAgIC8vaGVhZGVyLgorICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgTWVzc2FnaW5nRXhjZXB0aW9uIE1FKSB7CisgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoTUUuZ2V0TWVzc2FnZSgpLCBNRSwgRXJyb3JNYW5hZ2VyLkZPUk1BVF9GQUlMVVJFKTsKKyAgICAgICAgICAgICAgICBzZXREZWZhdWx0RnJvbShtc2cpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgc2V0RGVmYXVsdEZyb20obXNnKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGZyb20gaGVhZGVyIHRvIHRoZSBsb2NhbCBhZGRyZXNzLgorICAgICAqIEBwYXJhbSBtc2cgdGhlIHRhcmdldCBtZXNzYWdlLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBzZXREZWZhdWx0RnJvbShmaW5hbCBNZXNzYWdlIG1zZykgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgbXNnLnNldEZyb20oKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgTWVzc2FnaW5nRXhjZXB0aW9uIE1FKSB7CisgICAgICAgICAgICByZXBvcnRFcnJvcihNRS5nZXRNZXNzYWdlKCksIE1FLCBFcnJvck1hbmFnZXIuRk9STUFUX0ZBSUxVUkUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcHV0ZXMgdGhlIGRlZmF1bHQgdG8tYWRkcmVzcyBpZiBub25lIHdhcyBzcGVjaWZpZWQuICBUaGlzIGNhbgorICAgICAqIGZhaWwgaWYgdGhlIGxvY2FsIGFkZHJlc3MgY2FuJ3QgYmUgY29tcHV0ZWQuCisgICAgICogQHBhcmFtIG1zZyB0aGUgbWVzc2FnZQorICAgICAqIEBwYXJhbSB0eXBlIHRoZSByZWNpcGllbnQgdHlwZS4KKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS41LjAKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgc2V0RGVmYXVsdFJlY2lwaWVudChmaW5hbCBNZXNzYWdlIG1zZywKKyAgICAgICAgICAgIGZpbmFsIE1lc3NhZ2UuUmVjaXBpZW50VHlwZSB0eXBlKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBBZGRyZXNzIGEgPSBJbnRlcm5ldEFkZHJlc3MuZ2V0TG9jYWxBZGRyZXNzKGdldFNlc3Npb24obXNnKSk7CisgICAgICAgICAgICBpZiAoYSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgbXNnLnNldFJlY2lwaWVudCh0eXBlLCBhKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZmluYWwgTWltZU1lc3NhZ2UgbSA9IG5ldyBNaW1lTWVzc2FnZShnZXRTZXNzaW9uKG1zZykpOworICAgICAgICAgICAgICAgIG0uc2V0RnJvbSgpOyAvL1Nob3VsZCB0aHJvdyBhbiBleGNlcHRpb24gd2l0aCBhIGNhdXNlLgorICAgICAgICAgICAgICAgIEFkZHJlc3NbXSBmcm9tID0gbS5nZXRGcm9tKCk7CisgICAgICAgICAgICAgICAgaWYgKGZyb20ubGVuZ3RoID4gMCkgeworICAgICAgICAgICAgICAgICAgICBtc2cuc2V0UmVjaXBpZW50cyh0eXBlLCBmcm9tKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKCJObyBsb2NhbCBhZGRyZXNzLiIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIHwgUnVudGltZUV4Y2VwdGlvbiBNRSkgeworICAgICAgICAgICAgcmVwb3J0RXJyb3IoIlVuYWJsZSB0byBjb21wdXRlIGEgZGVmYXVsdCByZWNpcGllbnQuIiwKKyAgICAgICAgICAgICAgICAgICAgTUUsIEVycm9yTWFuYWdlci5GT1JNQVRfRkFJTFVSRSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHJlcGx5LXRvIGFkZHJlc3MgaGVhZGVyLgorICAgICAqIEBwYXJhbSBtc2cgdGhlIHRhcmdldCBtZXNzYWdlLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBzZXRSZXBseVRvKGZpbmFsIE1lc3NhZ2UgbXNnKSB7CisgICAgICAgIGZpbmFsIFN0cmluZyByZXBseSA9IGdldFNlc3Npb24obXNnKS5nZXRQcm9wZXJ0eSgibWFpbC5yZXBseS50byIpOworICAgICAgICBpZiAoIWlzRW1wdHkocmVwbHkpKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGZpbmFsIEFkZHJlc3NbXSBhZGRyZXNzID0gSW50ZXJuZXRBZGRyZXNzLnBhcnNlKHJlcGx5LCBmYWxzZSk7CisgICAgICAgICAgICAgICAgaWYgKGFkZHJlc3MubGVuZ3RoID4gMCkgeworICAgICAgICAgICAgICAgICAgICBtc2cuc2V0UmVwbHlUbyhhZGRyZXNzKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBNZXNzYWdpbmdFeGNlcHRpb24gTUUpIHsKKyAgICAgICAgICAgICAgICByZXBvcnRFcnJvcihNRS5nZXRNZXNzYWdlKCksIE1FLCBFcnJvck1hbmFnZXIuRk9STUFUX0ZBSUxVUkUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyBzZW5kZXIgYWRkcmVzcyBoZWFkZXIuCisgICAgICogQHBhcmFtIG1zZyB0aGUgdGFyZ2V0IG1lc3NhZ2UuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHNldFNlbmRlcihmaW5hbCBNZXNzYWdlIG1zZykgeworICAgICAgICBhc3NlcnQgbXNnIGluc3RhbmNlb2YgTWltZU1lc3NhZ2UgOiBtc2c7CisgICAgICAgIGZpbmFsIFN0cmluZyBzZW5kZXIgPSBnZXRTZXNzaW9uKG1zZykuZ2V0UHJvcGVydHkoIm1haWwuc2VuZGVyIik7CisgICAgICAgIGlmICghaXNFbXB0eShzZW5kZXIpKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGZpbmFsIEludGVybmV0QWRkcmVzc1tdIGFkZHJlc3MgPQorICAgICAgICAgICAgICAgICAgICAgICAgSW50ZXJuZXRBZGRyZXNzLnBhcnNlKHNlbmRlciwgZmFsc2UpOworICAgICAgICAgICAgICAgIGlmIChhZGRyZXNzLmxlbmd0aCA+IDApIHsKKyAgICAgICAgICAgICAgICAgICAgKChNaW1lTWVzc2FnZSkgbXNnKS5zZXRTZW5kZXIoYWRkcmVzc1swXSk7CisgICAgICAgICAgICAgICAgICAgIGlmIChhZGRyZXNzLmxlbmd0aCA+IDEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCJJZ25vcmluZyBvdGhlciBzZW5kZXJzLiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvb01hbnlBZGRyZXNzZXMoYWRkcmVzcywgMSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVycm9yTWFuYWdlci5GT1JNQVRfRkFJTFVSRSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBNZXNzYWdpbmdFeGNlcHRpb24gTUUpIHsKKyAgICAgICAgICAgICAgICByZXBvcnRFcnJvcihNRS5nZXRNZXNzYWdlKCksIE1FLCBFcnJvck1hbmFnZXIuRk9STUFUX0ZBSUxVUkUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQSBjb21tb24gZmFjdG9yeSB1c2VkIHRvIGNyZWF0ZSB0aGUgdG9vIG1hbnkgYWRkcmVzc2VzIGV4Y2VwdGlvbi4KKyAgICAgKiBAcGFyYW0gYWRkcmVzcyB0aGUgYWRkcmVzc2VzLCBuZXZlciBudWxsLgorICAgICAqIEBwYXJhbSBvZmZzZXQgdGhlIHN0YXJ0aW5nIGFkZHJlc3MgdG8gZGlzcGxheS4KKyAgICAgKiBAcmV0dXJuIHRoZSB0b28gbWFueSBhZGRyZXNzZXMgZXhjZXB0aW9uLgorICAgICAqLworICAgIHByaXZhdGUgQWRkcmVzc0V4Y2VwdGlvbiB0b29NYW55QWRkcmVzc2VzKEFkZHJlc3NbXSBhZGRyZXNzLCBpbnQgb2Zmc2V0KSB7CisgICAgICAgIE9iamVjdCBsID0gQXJyYXlzLmFzTGlzdChhZGRyZXNzKS5zdWJMaXN0KG9mZnNldCwgYWRkcmVzcy5sZW5ndGgpOworICAgICAgICByZXR1cm4gbmV3IEFkZHJlc3NFeGNlcHRpb24obC50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSByZWNpcGllbnQgZm9yIHRoZSBnaXZlbiBtZXNzYWdlLgorICAgICAqIEBwYXJhbSBtc2cgdGhlIG1lc3NhZ2UuCisgICAgICogQHBhcmFtIGtleSB0aGUga2V5IHRvIHNlYXJjaCBpbiB0aGUgc2Vzc2lvbi4KKyAgICAgKiBAcGFyYW0gdHlwZSB0aGUgcmVjaXBpZW50IHR5cGUuCisgICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBrZXkgd2FzIGNvbnRhaW5lZCBpbiB0aGUgc2Vzc2lvbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gc2V0UmVjaXBpZW50KGZpbmFsIE1lc3NhZ2UgbXNnLAorICAgICAgICAgICAgZmluYWwgU3RyaW5nIGtleSwgZmluYWwgTWVzc2FnZS5SZWNpcGllbnRUeXBlIHR5cGUpIHsKKyAgICAgICAgYm9vbGVhbiBjb250YWluc0tleTsKKyAgICAgICAgZmluYWwgU3RyaW5nIHZhbHVlID0gZ2V0U2Vzc2lvbihtc2cpLmdldFByb3BlcnR5KGtleSk7CisgICAgICAgIGNvbnRhaW5zS2V5ID0gdmFsdWUgIT0gbnVsbDsKKyAgICAgICAgaWYgKCFpc0VtcHR5KHZhbHVlKSkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBmaW5hbCBBZGRyZXNzW10gYWRkcmVzcyA9IEludGVybmV0QWRkcmVzcy5wYXJzZSh2YWx1ZSwgZmFsc2UpOworICAgICAgICAgICAgICAgIGlmIChhZGRyZXNzLmxlbmd0aCA+IDApIHsKKyAgICAgICAgICAgICAgICAgICAgbXNnLnNldFJlY2lwaWVudHModHlwZSwgYWRkcmVzcyk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgTWVzc2FnaW5nRXhjZXB0aW9uIE1FKSB7CisgICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoTUUuZ2V0TWVzc2FnZSgpLCBNRSwgRXJyb3JNYW5hZ2VyLkZPUk1BVF9GQUlMVVJFKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY29udGFpbnNLZXk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydHMgYW4gZW1haWwgbWVzc2FnZSB0byBhIHJhdyBzdHJpbmcuICBUaGlzIHJhdyBzdHJpbmcKKyAgICAgKiBpcyBwYXNzZWQgdG8gdGhlIGVycm9yIG1hbmFnZXIgdG8gYWxsb3cgY3VzdG9tIGVycm9yIG1hbmFnZXJzCisgICAgICogdG8gcmVjcmVhdGUgdGhlIG9yaWdpbmFsIE1pbWVNZXNzYWdlIG9iamVjdC4KKyAgICAgKiBAcGFyYW0gbXNnIGEgTWVzc2FnZSBvYmplY3QuCisgICAgICogQHJldHVybiB0aGUgcmF3IHN0cmluZyBvciBudWxsIGlmIG1zZyB3YXMgbnVsbC4KKyAgICAgKiBAdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiBpZiB0aGVyZSB3YXMgYSBwcm9ibGVtIHdpdGggdGhlIG1lc3NhZ2UuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiB0aGVyZSB3YXMgYSBwcm9ibGVtLgorICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nIHRvUmF3U3RyaW5nKGZpbmFsIE1lc3NhZ2UgbXNnKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChtc2cgIT0gbnVsbCkgeworICAgICAgICAgICAgT2JqZWN0IGNjbCA9IGdldEFuZFNldENvbnRleHRDbGFzc0xvYWRlcihNQUlMSEFORExFUl9MT0FERVIpOworICAgICAgICAgICAgdHJ5IHsgIC8vSkRLLTgwMjUyNTEKKyAgICAgICAgICAgICAgICBpbnQgbmJ5dGVzID0gTWF0aC5tYXgobXNnLmdldFNpemUoKSArIE1JTl9IRUFERVJfU0laRSwgTUlOX0hFQURFUl9TSVpFKTsKKyAgICAgICAgICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbShuYnl0ZXMpOworICAgICAgICAgICAgICAgIG1zZy53cml0ZVRvKG91dCk7ICAvL0hlYWRlcnMgY2FuIGJlIFVURi04IG9yIFVTLUFTQ0lJLgorICAgICAgICAgICAgICAgIHJldHVybiBvdXQudG9TdHJpbmcoIlVURi04Iik7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIGdldEFuZFNldENvbnRleHRDbGFzc0xvYWRlcihjY2wpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeyAvL011c3QgbWF0Y2ggdGhpcy5yZXBvcnRFcnJvciBiZWhhdmlvciwgc2VlIHB1c2ggbWV0aG9kLgorICAgICAgICAgICAgcmV0dXJuIG51bGw7IC8vTnVsbCBpcyB0aGUgc2FmZSBjaG9pY2UuCisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0cyBhIHRocm93YWJsZSB0byBhIG1lc3NhZ2Ugc3RyaW5nLgorICAgICAqIEBwYXJhbSB0IGFueSB0aHJvd2FibGUgb3IgbnVsbC4KKyAgICAgKiBAcmV0dXJuIHRoZSB0aHJvd2FibGUgd2l0aCBhIHN0YWNrIHRyYWNlIG9yIHRoZSBsaXRlcmFsIG51bGwuCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgdG9Nc2dTdHJpbmcoZmluYWwgVGhyb3dhYmxlIHQpIHsKKyAgICAgICAgaWYgKHQgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuICJudWxsIjsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIFN0cmluZyBjaGFyc2V0ID0gZ2V0RW5jb2RpbmdOYW1lKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaW5hbCBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gb3V0ID0KKyAgICAgICAgICAgICAgICAgICAgbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbShNSU5fSEVBREVSX1NJWkUpOworCisgICAgICAgICAgICAvL0NyZWF0ZSBhbiBvdXRwdXQgc3RyZWFtIHdyaXRlciBzbyBzdHJlYW1zIGFyZSBub3QgZG91YmxlIGJ1ZmZlcmVkLgorICAgICAgICAgICAgdHJ5IChPdXRwdXRTdHJlYW1Xcml0ZXIgb3dzID0gbmV3IE91dHB1dFN0cmVhbVdyaXRlcihvdXQsIGNoYXJzZXQpOworICAgICAgICAgICAgICAgICBQcmludFdyaXRlciBwdyA9IG5ldyBQcmludFdyaXRlcihvd3MpKSB7CisgICAgICAgICAgICAgICAgcHcucHJpbnRsbih0LmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICAgICAgdC5wcmludFN0YWNrVHJhY2UocHcpOworICAgICAgICAgICAgICAgIHB3LmZsdXNoKCk7CisgICAgICAgICAgICB9IC8vQ2xvc2UgT1NXIGJlZm9yZSBnZW5lcmF0aW5nIHN0cmluZy4gSkRLLTY5OTU1MzcKKyAgICAgICAgICAgIHJldHVybiBvdXQudG9TdHJpbmcoY2hhcnNldCk7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIFJ1bnRpbWVFeGNlcHRpb24gdW5leHBlY3RlZCkgeworICAgICAgICAgICAgcmV0dXJuIHQudG9TdHJpbmcoKSArICcgJyArIHVuZXhwZWN0ZWQudG9TdHJpbmcoKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgRXhjZXB0aW9uIGJhZE1pbWVDaGFyc2V0KSB7CisgICAgICAgICAgICByZXR1cm4gdC50b1N0cmluZygpICsgJyAnICsgYmFkTWltZUNoYXJzZXQudG9TdHJpbmcoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlcGxhY2VzIHRoZSBjdXJyZW50IGNvbnRleHQgY2xhc3MgbG9hZGVyIHdpdGggb3VyIGNsYXNzIGxvYWRlci4KKyAgICAgKiBAcGFyYW0gY2NsIG51bGwgZm9yIGJvb3QgY2xhc3MgbG9hZGVyLCBhIGNsYXNzIGxvYWRlciwgYSBjbGFzcyB1c2VkIHRvCisgICAgICogZ2V0IHRoZSBjbGFzcyBsb2FkZXIsIG9yIGEgc291cmNlIG9iamVjdCB0byBnZXQgdGhlIGNsYXNzIGxvYWRlci4KKyAgICAgKiBAcmV0dXJuIG51bGwgZm9yIHRoZSBib290IGNsYXNzIGxvYWRlciwgYSBjbGFzcyBsb2FkZXIsIG9yIGEgbWFya2VyCisgICAgICogb2JqZWN0IHRvIHNpZ25hbCB0aGF0IG5vIG1vZGlmaWNhdGlvbiB3YXMgcmVxdWlyZWQuCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNS4zCisgICAgICovCisgICAgcHJpdmF0ZSBPYmplY3QgZ2V0QW5kU2V0Q29udGV4dENsYXNzTG9hZGVyKGZpbmFsIE9iamVjdCBjY2wpIHsKKyAgICAgICAgaWYgKGNjbCAhPSBHZXRBbmRTZXRDb250ZXh0Lk5PVF9NT0RJRklFRCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBmaW5hbCBQcml2aWxlZ2VkQWN0aW9uPD8+IHBhOworICAgICAgICAgICAgICAgIGlmIChjY2wgaW5zdGFuY2VvZiBQcml2aWxlZ2VkQWN0aW9uKSB7CisgICAgICAgICAgICAgICAgICAgIHBhID0gKFByaXZpbGVnZWRBY3Rpb248Pz4pIGNjbDsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBwYSA9IG5ldyBHZXRBbmRTZXRDb250ZXh0KGNjbCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZChwYSk7CisgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBTZWN1cml0eUV4Y2VwdGlvbiBpZ25vcmUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gR2V0QW5kU2V0Q29udGV4dC5OT1RfTU9ESUZJRUQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQSBmYWN0b3J5IHVzZWQgdG8gY3JlYXRlIGEgY29tbW9uIGF0dGFjaG1lbnQgbWlzbWF0Y2ggdHlwZS4KKyAgICAgKiBAcGFyYW0gbXNnIHRoZSBleGNlcHRpb24gbWVzc2FnZS4KKyAgICAgKiBAcmV0dXJuIGEgUnVudGltZUV4Y2VwdGlvbiB0byByZXByZXNlbnQgdGhlIHR5cGUgb2YgZXJyb3IuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgUnVudGltZUV4Y2VwdGlvbiBhdHRhY2htZW50TWlzbWF0Y2goZmluYWwgU3RyaW5nIG1zZykgeworICAgICAgICByZXR1cm4gbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24obXNnKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBPdXRsaW5lIHRoZSBhdHRhY2htZW50IG1pc21hdGNoIG1lc3NhZ2UuIFNlZSBCdWcgSUQgNjUzMzE2NS4KKyAgICAgKiBAcGFyYW0gZXhwZWN0ZWQgdGhlIGV4cGVjdGVkIGFycmF5IGxlbmd0aC4KKyAgICAgKiBAcGFyYW0gZm91bmQgdGhlIGFycmF5IGxlbmd0aCB0aGF0IHdhcyBnaXZlbi4KKyAgICAgKiBAcmV0dXJuIGEgUnVudGltZUV4Y2VwdGlvbiBwb3B1bGF0ZWQgd2l0aCBhIG1lc3NhZ2UuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgUnVudGltZUV4Y2VwdGlvbiBhdHRhY2htZW50TWlzbWF0Y2goaW50IGV4cGVjdGVkLCBpbnQgZm91bmQpIHsKKyAgICAgICAgcmV0dXJuIGF0dGFjaG1lbnRNaXNtYXRjaCgiQXR0YWNobWVudHMgbWlzbWF0Y2hlZCwgZXhwZWN0ZWQgIgorICAgICAgICAgICAgICAgICsgZXhwZWN0ZWQgKyAiIGJ1dCBnaXZlbiAiICsgZm91bmQgKyAnLicpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRyeSB0byBhdHRhY2ggYSBzdXBwcmVzc2VkIGV4Y2VwdGlvbiB0byBhIE1lc3NhZ2luZ0V4Y2VwdGlvbiBpbiBhbnkgb3JkZXIKKyAgICAgKiB0aGF0IGlzIHBvc3NpYmxlLgorICAgICAqIEBwYXJhbSByZXF1aXJlZCB0aGUgZXhjZXB0aW9uIGV4cGVjdGVkIHRvIHNlZSBhcyBhIHJlcG9ydGVkIGZhaWx1cmUuCisgICAgICogQHBhcmFtIG9wdGlvbmFsIHRoZSBzdXBwcmVzc2VkIGV4Y2VwdGlvbi4KKyAgICAgKiBAcmV0dXJuIGVpdGhlciB0aGUgcmVxdWlyZWQgb3IgdGhlIG9wdGlvbmFsIGV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBNZXNzYWdpbmdFeGNlcHRpb24gYXR0YWNoKAorICAgICAgICAgICAgTWVzc2FnaW5nRXhjZXB0aW9uIHJlcXVpcmVkLCBFeGNlcHRpb24gb3B0aW9uYWwpIHsKKyAgICAgICAgaWYgKG9wdGlvbmFsICE9IG51bGwgJiYgIXJlcXVpcmVkLnNldE5leHRFeGNlcHRpb24ob3B0aW9uYWwpKSB7CisgICAgICAgICAgICBpZiAob3B0aW9uYWwgaW5zdGFuY2VvZiBNZXNzYWdpbmdFeGNlcHRpb24pIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBNZXNzYWdpbmdFeGNlcHRpb24gaGVhZCA9IChNZXNzYWdpbmdFeGNlcHRpb24pIG9wdGlvbmFsOworICAgICAgICAgICAgICAgIGlmIChoZWFkLnNldE5leHRFeGNlcHRpb24ocmVxdWlyZWQpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBoZWFkOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKG9wdGlvbmFsICE9IHJlcXVpcmVkKSB7CisgICAgICAgICAgICAgICAgcmVxdWlyZWQuYWRkU3VwcHJlc3NlZChvcHRpb25hbCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlcXVpcmVkOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIGxvY2FsIGhvc3QgZnJvbSB0aGUgZ2l2ZW4gc2VydmljZSBvYmplY3QuCisgICAgICogQHBhcmFtIHMgdGhlIHNlcnZpY2UgdG8gY2hlY2suCisgICAgICogQHJldHVybiB0aGUgbG9jYWwgaG9zdCBvciBudWxsLgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjUuMworICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nIGdldExvY2FsSG9zdChmaW5hbCBTZXJ2aWNlIHMpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBMb2dNYW5hZ2VyUHJvcGVydGllcy5nZXRMb2NhbEhvc3Qocyk7CisgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHwgTm9TdWNoTWV0aG9kRXhjZXB0aW9uCisgICAgICAgICAgICAgICAgfCBMaW5rYWdlRXJyb3IgaWdub3JlKSB7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgcmVwb3J0RXJyb3Iocy50b1N0cmluZygpLCBleCwgRXJyb3JNYW5hZ2VyLk9QRU5fRkFJTFVSRSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogR29vZ2xlIEFwcCBFbmdpbmUgZG9lc24ndCBzdXBwb3J0IE1lc3NhZ2UuZ2V0U2Vzc2lvbi4KKyAgICAgKiBAcGFyYW0gbXNnIHRoZSBtZXNzYWdlLgorICAgICAqIEByZXR1cm4gdGhlIHNlc3Npb24gZnJvbSB0aGUgZ2l2ZW4gbWVzc2FnZS4KKyAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBnaXZlbiBtZXNzYWdlIGlzIG51bGwuCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNS4zCisgICAgICovCisgICAgcHJpdmF0ZSBTZXNzaW9uIGdldFNlc3Npb24oZmluYWwgTWVzc2FnZSBtc2cpIHsKKyAgICAgICAgaWYgKG1zZyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbmV3IE1lc3NhZ2VDb250ZXh0KG1zZykuZ2V0U2Vzc2lvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERldGVybWluZXMgaWYgcmVzdHJpY3RlZCBoZWFkZXJzIGFyZSBhbGxvd2VkIGluIHRoZSBjdXJyZW50IGVudmlyb25tZW50LgorICAgICAqCisgICAgICogQHJldHVybiB0cnVlIGlmIHJlc3RyaWN0ZWQgaGVhZGVycyBhcmUgYWxsb3dlZC4KKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS41LjMKKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gYWxsb3dSZXN0cmljdGVkSGVhZGVycygpIHsKKyAgICAgICAgLy9HQUUgd2lsbCBwcmV2ZW50IGRlbGl2ZXJ5IG9mIGVtYWlsIHdpdGggZm9yYmlkZGVuIGhlYWRlcnMuCisgICAgICAgIC8vQXNzdW1lIHRoZSBlbnZpcm9ubWVudCBpcyBHQUUgaWYgYWNjZXNzIHRvIHRoZSBMb2dNYW5hZ2VyIGlzCisgICAgICAgIC8vZm9yYmlkZGVuLgorICAgICAgICByZXR1cm4gTG9nTWFuYWdlclByb3BlcnRpZXMuaGFzTG9nTWFuYWdlcigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIE91dGxpbmUgdGhlIGNyZWF0aW9uIG9mIHRoZSBpbmRleCBlcnJvciBtZXNzYWdlLiBTZWUgSkRLLTY1MzMxNjUuCisgICAgICogQHBhcmFtIGkgdGhlIGluZGV4LgorICAgICAqIEByZXR1cm4gdGhlIGVycm9yIG1lc3NhZ2UuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGF0SW5kZXhNc2coZmluYWwgaW50IGkpIHsKKyAgICAgICAgcmV0dXJuICJBdCBpbmRleDogIiArIGkgKyAnLic7CisgICAgfQorCisgICAgLyoqCisgICAgICogVXNlZCBmb3Igc3RvcmluZyBhIHBhc3N3b3JkIGZyb20gdGhlIExvZ01hbmFnZXIgb3IgbGl0ZXJhbCBzdHJpbmcuCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNC42CisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRGVmYXVsdEF1dGhlbnRpY2F0b3IgZXh0ZW5kcyBBdXRoZW50aWNhdG9yIHsKKworICAgICAgICAvKioKKyAgICAgICAgICogQ3JlYXRlcyBhbiBBdXRoZW50aWNhdG9yIGZvciB0aGUgZ2l2ZW4gcGFzc3dvcmQuICBUaGlzIG1ldGhvZCBpcyB1c2VkCisgICAgICAgICAqIHNvIGNsYXNzIHZlcmlmaWNhdGlvbiBvZiBhc3NpZ25tZW50cyBpbiBNYWlsSGFuZGxlciBkb2Vzbid0IHJlcXVpcmUKKyAgICAgICAgICogbG9hZGluZyB0aGlzIGNsYXNzIHdoaWNoIG90aGVyd2lzZSBjYW4gb2NjdXIgd2hlbiB1c2luZyB0aGUKKyAgICAgICAgICogY29uc3RydWN0b3IuICBEZWZhdWx0IGFjY2VzcyB0byBhdm9pZCBnZW5lcmF0aW5nIGV4dHJhIGNsYXNzIGZpbGVzLgorICAgICAgICAgKgorICAgICAgICAgKiBAcGFyYW0gcGFzcyB0aGUgcGFzc3dvcmQuCisgICAgICAgICAqIEByZXR1cm4gYW4gQXV0aGVudGljYXRvciBmb3IgdGhlIHBhc3N3b3JkLgorICAgICAgICAgKiBAc2luY2UgSmF2YU1haWwgMS41LjYKKyAgICAgICAgICovCisgICAgICAgIHN0YXRpYyBBdXRoZW50aWNhdG9yIG9mKGZpbmFsIFN0cmluZyBwYXNzKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IERlZmF1bHRBdXRoZW50aWNhdG9yKHBhc3MpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBwYXNzd29yZCB0byB1c2UuCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBwYXNzOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBVc2UgdGhlIGZhY3RvcnkgbWV0aG9kIGluc3RlYWQgb2YgdGhpcyBjb25zdHJ1Y3Rvci4KKyAgICAgICAgICogQHBhcmFtIHBhc3MgdGhlIHBhc3N3b3JkLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBEZWZhdWx0QXV0aGVudGljYXRvcihmaW5hbCBTdHJpbmcgcGFzcykgeworICAgICAgICAgICAgYXNzZXJ0IHBhc3MgIT0gbnVsbDsKKyAgICAgICAgICAgIHRoaXMucGFzcyA9IHBhc3M7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIGZpbmFsIFBhc3N3b3JkQXV0aGVudGljYXRpb24gZ2V0UGFzc3dvcmRBdXRoZW50aWNhdGlvbigpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgUGFzc3dvcmRBdXRoZW50aWNhdGlvbihnZXREZWZhdWx0VXNlck5hbWUoKSwgcGFzcyk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIGdldCBhbmQgc2V0IG9mIHRoZSBjb250ZXh0IGNsYXNzIGxvYWRlciB3aXRoIHByaXZpbGVnZXMKKyAgICAgKiBlbmFibGVkLgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjQuNgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEdldEFuZFNldENvbnRleHQgaW1wbGVtZW50cyBQcml2aWxlZ2VkQWN0aW9uPE9iamVjdD4geworICAgICAgICAvKioKKyAgICAgICAgICogQSBtYXJrZXIgb2JqZWN0IHVzZWQgdG8gc2lnbmFsIHRoYXQgdGhlIGNsYXNzIGxvYWRlciB3YXMgbm90CisgICAgICAgICAqIG1vZGlmaWVkLgorICAgICAgICAgKi8KKyAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBPYmplY3QgTk9UX01PRElGSUVEID0gR2V0QW5kU2V0Q29udGV4dC5jbGFzczsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBzb3VyY2UgY29udGFpbmluZyB0aGUgY2xhc3MgbG9hZGVyLgorICAgICAgICAgKi8KKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBPYmplY3Qgc291cmNlOworICAgICAgICAvKioKKyAgICAgICAgICogQ3JlYXRlIHRoZSBhY3Rpb24uCisgICAgICAgICAqIEBwYXJhbSBzb3VyY2UgbnVsbCBmb3IgYm9vdCBjbGFzcyBsb2FkZXIsIGEgY2xhc3MgbG9hZGVyLCBhIGNsYXNzCisgICAgICAgICAqIHVzZWQgdG8gZ2V0IHRoZSBjbGFzcyBsb2FkZXIsIG9yIGEgc291cmNlIG9iamVjdCB0byBnZXQgdGhlIGNsYXNzCisgICAgICAgICAqIGxvYWRlci4gRGVmYXVsdCBhY2Nlc3MgdG8gYXZvaWQgZ2VuZXJhdGluZyBleHRyYSBjbGFzcyBmaWxlcy4KKyAgICAgICAgICovCisgICAgICAgIEdldEFuZFNldENvbnRleHQoZmluYWwgT2JqZWN0IHNvdXJjZSkgeworICAgICAgICAgICAgdGhpcy5zb3VyY2UgPSBzb3VyY2U7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogR2V0cyB0aGUgY2xhc3MgbG9hZGVyIGZyb20gdGhlIHNvdXJjZSBhbmQgc2V0cyB0aGUgQ0NMIG9ubHkgaWYKKyAgICAgICAgICogdGhlIHNvdXJjZSBhbmQgQ0NMIGFyZSBub3QgdGhlIHNhbWUuCisgICAgICAgICAqIEByZXR1cm4gdGhlIHJlcGxhY2VkIGNvbnRleHQgY2xhc3MgbG9hZGVyIHdoaWNoIGNhbiBiZSBudWxsIG9yCisgICAgICAgICAqIE5PVF9NT0RJRklFRCB0byBpbmRpY2F0ZSB0aGF0IG5vdGhpbmcgd2FzIG1vZGlmaWVkLgorICAgICAgICAgKi8KKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoIm92ZXJyaWRlIikgLy9KREstNjk1NDIzNAorICAgICAgICBwdWJsaWMgZmluYWwgT2JqZWN0IHJ1bigpIHsKKyAgICAgICAgICAgIGZpbmFsIFRocmVhZCBjdXJyZW50ID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKTsKKyAgICAgICAgICAgIGZpbmFsIENsYXNzTG9hZGVyIGNjbCA9IGN1cnJlbnQuZ2V0Q29udGV4dENsYXNzTG9hZGVyKCk7CisgICAgICAgICAgICBmaW5hbCBDbGFzc0xvYWRlciBsb2FkZXI7CisgICAgICAgICAgICBpZiAoc291cmNlID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBsb2FkZXIgPSBudWxsOyAvL2Jvb3QgY2xhc3MgbG9hZGVyCisgICAgICAgICAgICB9IGVsc2UgaWYgKHNvdXJjZSBpbnN0YW5jZW9mIENsYXNzTG9hZGVyKSB7CisgICAgICAgICAgICAgICAgbG9hZGVyID0gKENsYXNzTG9hZGVyKSBzb3VyY2U7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHNvdXJjZSBpbnN0YW5jZW9mIENsYXNzKSB7CisgICAgICAgICAgICAgICAgbG9hZGVyID0gKChDbGFzczw/Pikgc291cmNlKS5nZXRDbGFzc0xvYWRlcigpOworICAgICAgICAgICAgfSBlbHNlIGlmIChzb3VyY2UgaW5zdGFuY2VvZiBUaHJlYWQpIHsKKyAgICAgICAgICAgICAgICBsb2FkZXIgPSAoKFRocmVhZCkgc291cmNlKS5nZXRDb250ZXh0Q2xhc3NMb2FkZXIoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0ICEoc291cmNlIGluc3RhbmNlb2YgQ2xhc3MpIDogc291cmNlOworICAgICAgICAgICAgICAgIGxvYWRlciA9IHNvdXJjZS5nZXRDbGFzcygpLmdldENsYXNzTG9hZGVyKCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChjY2wgIT0gbG9hZGVyKSB7CisgICAgICAgICAgICAgICAgY3VycmVudC5zZXRDb250ZXh0Q2xhc3NMb2FkZXIobG9hZGVyKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gY2NsOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gTk9UX01PRElGSUVEOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVXNlZCBmb3IgbmFtaW5nIGF0dGFjaG1lbnQgZmlsZSBuYW1lcyBhbmQgdGhlIG1haW4gc3ViamVjdCBsaW5lLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFRhaWxOYW1lRm9ybWF0dGVyIGV4dGVuZHMgRm9ybWF0dGVyIHsKKworICAgICAgICAvKioKKyAgICAgICAgICogQ3JlYXRlcyBvciBnZXRzIGEgZm9ybWF0dGVyIGZyb20gdGhlIGdpdmVuIG5hbWUuICBUaGlzIG1ldGhvZCBpcyB1c2VkCisgICAgICAgICAqIHNvIGNsYXNzIHZlcmlmaWNhdGlvbiBvZiBhc3NpZ25tZW50cyBpbiBNYWlsSGFuZGxlciBkb2Vzbid0IHJlcXVpcmUKKyAgICAgICAgICogbG9hZGluZyB0aGlzIGNsYXNzIHdoaWNoIG90aGVyd2lzZSBjYW4gb2NjdXIgd2hlbiB1c2luZyB0aGUKKyAgICAgICAgICogY29uc3RydWN0b3IuICBEZWZhdWx0IGFjY2VzcyB0byBhdm9pZCBnZW5lcmF0aW5nIGV4dHJhIGNsYXNzIGZpbGVzLgorICAgICAgICAgKgorICAgICAgICAgKiBAcGFyYW0gbmFtZSBhbnkgbm90IG51bGwgc3RyaW5nLgorICAgICAgICAgKiBAcmV0dXJuIGEgZm9ybWF0dGVyIGZvciB0aGF0IHN0cmluZy4KKyAgICAgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNS42CisgICAgICAgICAqLworICAgICAgICBzdGF0aWMgRm9ybWF0dGVyIG9mKGZpbmFsIFN0cmluZyBuYW1lKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IFRhaWxOYW1lRm9ybWF0dGVyKG5hbWUpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSB2YWx1ZSB1c2VkIGFzIHRoZSBvdXRwdXQuCisgICAgICAgICAqLworICAgICAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBuYW1lOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBVc2UgdGhlIGZhY3RvcnkgbWV0aG9kIGluc3RlYWQgb2YgdGhpcyBjb25zdHJ1Y3Rvci4KKyAgICAgICAgICogQHBhcmFtIG5hbWUgYW55IG5vdCBudWxsIHN0cmluZy4KKyAgICAgICAgICovCisgICAgICAgIHByaXZhdGUgVGFpbE5hbWVGb3JtYXR0ZXIoZmluYWwgU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgICAgIGFzc2VydCBuYW1lICE9IG51bGw7CisgICAgICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgZm9ybWF0KExvZ1JlY29yZCByZWNvcmQpIHsKKyAgICAgICAgICAgIHJldHVybiAiIjsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgZmluYWwgU3RyaW5nIGdldFRhaWwoSGFuZGxlciBoKSB7CisgICAgICAgICAgICByZXR1cm4gbmFtZTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBFcXVhbHMgbWV0aG9kLgorICAgICAgICAgKiBAcGFyYW0gbyB0aGUgb3RoZXIgb2JqZWN0LgorICAgICAgICAgKiBAcmV0dXJuIHRydWUgaWYgZXF1YWwKKyAgICAgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNC40CisgICAgICAgICAqLworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvKSB7CisgICAgICAgICAgICBpZiAobyBpbnN0YW5jZW9mIFRhaWxOYW1lRm9ybWF0dGVyKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5hbWUuZXF1YWxzKCgoVGFpbE5hbWVGb3JtYXR0ZXIpIG8pLm5hbWUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEhhc2ggY29kZSBtZXRob2QuCisgICAgICAgICAqIEByZXR1cm4gdGhlIGhhc2ggY29kZS4KKyAgICAgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNC40CisgICAgICAgICAqLworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGZpbmFsIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBnZXRDbGFzcygpLmhhc2hDb2RlKCkgKyBuYW1lLmhhc2hDb2RlKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGZpbmFsIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgICAgIHJldHVybiBuYW1lOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL2xvZ2dpbmcvU2V2ZXJpdHlDb21wYXJhdG9yLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvbG9nZ2luZy9TZXZlcml0eUNvbXBhcmF0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zMzhhNzgwCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL2xvZ2dpbmcvU2V2ZXJpdHlDb21wYXJhdG9yLmphdmEKQEAgLTAsMCArMSwzMzIgQEAKKy8qDQorICogQ29weXJpZ2h0IChjKSAyMDEzLCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQorICogQ29weXJpZ2h0IChjKSAyMDEzLCAyMDE4IEphc29uIE1laHJlbnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQorICoNCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUNCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdA0KKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4NCisgKg0KKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkNCisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlDQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsDQorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQNCisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuDQorICoNCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjANCisgKi8NCitwYWNrYWdlIGNvbS5zdW4ubWFpbC51dGlsLmxvZ2dpbmc7DQorDQoraW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOw0KK2ltcG9ydCBqYXZhLnV0aWwuQ29tcGFyYXRvcjsNCitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTGV2ZWw7DQoraW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkxvZ1JlY29yZDsNCisNCisvKioNCisgKiBPcmRlcnMgbG9nIHJlY29yZHMgYnkgbGV2ZWwsIHRocm93biwgc2VxdWVuY2UsIGFuZCB0aW1lLg0KKyAqDQorICogVGhpcyBjb21wYXJhdG9yIG9yZGVycyBMb2dSZWNvcmRzIGJ5IGhvdyBzZXZlcmVseSBlYWNoIGlzIGF0dHJpYnV0ZWQgdG8NCisgKiBmYWlsdXJlcyBpbiBhIHByb2dyYW0uIFRoZSBwcmltYXJ5IG9yZGVyaW5nIGlzIGRldGVybWluZWQgYnkgdGhlIHVzZSBvZiB0aGUNCisgKiBsb2dnaW5nIEFQSSB0aHJvdWdob3V0IGEgcHJvZ3JhbSBieSBzcGVjaWZ5aW5nIGEgbGV2ZWwgdG8gZWFjaCBsb2cgbWVzc2FnZS4NCisgKiBUaGUgc2Vjb25kYXJ5IG9yZGVyaW5nIGlzIGRldGVybWluZWQgYXQgcnVudGltZSBieSB0aGUgdHlwZSBvZiBlcnJvcnMgYW5kDQorICogZXhjZXB0aW9ucyBnZW5lcmF0ZWQgYnkgdGhlIHByb2dyYW0uIFRoZSByZW1haW5pbmcgb3JkZXJpbmcgYXNzdW1lcyB0aGF0DQorICogb2xkZXIgbG9nIHJlY29yZHMgYXJlIGxlc3Mgc2V2ZXJlIHRoYW4gbmV3ZXIgbG9nIHJlY29yZHMuDQorICoNCisgKiA8cD4NCisgKiBUaGUgZm9sbG93aW5nIExvZ1JlY29yZCBwcm9wZXJ0aWVzIGRldGVybWluZSBzZXZlcml0eSBvcmRlcmluZzoNCisgKiA8b2w+DQorICogPGxpPiBUaGUgbmF0dXJhbCBjb21wYXJpc29uIG9mIHRoZSBMb2dSZWNvcmQNCisgKiB7QGxpbmtwbGFpbiBMZXZlbCNpbnRWYWx1ZSBsZXZlbH0uDQorICogPGxpPiBUaGUgZXhwZWN0ZWQgcmVjb3Zlcnkgb3JkZXIgb2Yge0BsaW5rcGxhaW4gTG9nUmVjb3JkI2dldFRocm93bigpIHRocm93bn0NCisgKiBwcm9wZXJ0eSBvZiBhIExvZ1JlY29yZCBhbmQgaXRzIGNhdXNlIGNoYWluLiBUaGlzIG9yZGVyaW5nIGlzIGRlcml2ZWQgZnJvbQ0KKyAqIHRoZSBKTFMgMTEuMS4xLiBUaGUgS2luZHMgb2YgRXhjZXB0aW9ucyBhbmQgSkxTIDExLjUgVGhlIEV4Y2VwdGlvbiBIaWVyYXJjaHkuDQorICogVGhpcyBpcyBwZXJmb3JtZWQgYnkge0BsaW5rcGxhaW4gI2FwcGx5KGphdmEubGFuZy5UaHJvd2FibGUpIGZpbmRpbmd9IHRoZQ0KKyAqIHRocm93YWJsZSB0aGF0IGJlc3QgZGVzY3JpYmVzIHRoZSBlbnRpcmUgY2F1c2UgY2hhaW4uIE9uY2UgYSBzcGVjaWZpYw0KKyAqIHRocm93YWJsZSBvZiBlYWNoIGNoYWluIGlzIGlkZW50aWZpZWQgaXQgaXMgdGhlbiByYW5rZWQgbG93ZXN0IHRvIGhpZ2hlc3QgYnkNCisgKiB0aGUgZm9sbG93aW5nIHJ1bGVzOg0KKyAqDQorICogPHVsPg0KKyAqIDxsaT5BbGwgTG9nUmVjb3JkcyB3aXRoIGEge0Bjb2RlIFRocm93YWJsZX0gZGVmaW5lZCBhcw0KKyAqICJ7QGxpbmsgI2lzTm9ybWFsKGphdmEubGFuZy5UaHJvd2FibGUpIG5vcm1hbCBvY2N1cnJlbmNlfSIuDQorICogPGxpPkFsbCBMb2dSZWNvcmRzIHRoYXQgZG8gbm90IGhhdmUgYSB0aHJvd24gb2JqZWN0Lg0KKyAqIDxsaT5BbGwgY2hlY2tlZCBleGNlcHRpb25zLiBUaGlzIGlzIGFueSBjbGFzcyB0aGF0IGlzIGFzc2lnbmFibGUgdG8gdGhlDQorICoge0Bjb2RlIGphdmEubGFuZy5UaHJvd2FibGV9IGNsYXNzIGFuZCBpcyBub3QgYQ0KKyAqIHtAY29kZSBqYXZhLmxhbmcuUnVudGltZUV4Y2VwdGlvbn0gb3IgYSB7QGNvZGUgamF2YS5sYW5nLkVycm9yfS4NCisgKiA8bGk+QWxsIHVuY2hlY2tlZCBleGNlcHRpb25zLiBUaGlzIGlzIGFsbCB7QGNvZGUgamF2YS5sYW5nLlJ1bnRpbWVFeGNlcHRpb259DQorICogb2JqZWN0cy4NCisgKiA8bGk+QWxsIGVycm9ycyB0aGF0IGluZGljYXRlIGEgc2VyaW91cyBwcm9ibGVtLiBUaGlzIGlzIGFsbA0KKyAqIHtAY29kZSBqYXZhLmxhbmcuRXJyb3J9IG9iamVjdHMuDQorICogPC91bD4NCisgKiA8bGk+IFRoZSBuYXR1cmFsIGNvbXBhcmlzb24gb2YgdGhlIExvZ1JlY29yZA0KKyAqIHtAbGlua3BsYWluIExvZ1JlY29yZCNnZXRTZXF1ZW5jZU51bWJlcigpIHNlcXVlbmNlfS4NCisgKiA8bGk+IFRoZSBuYXR1cmFsIGNvbXBhcmlzb24gb2YgdGhlIExvZ1JlY29yZA0KKyAqIHtAbGlua3BsYWluIExvZ1JlY29yZCNnZXRNaWxsaXMoKSBtaWxsaXN9Lg0KKyAqIDwvb2w+DQorICoNCisgKiBAYXV0aG9yIEphc29uIE1laHJlbnMNCisgKiBAc2luY2UgSmF2YU1haWwgMS41LjINCisgKi8NCitwdWJsaWMgY2xhc3MgU2V2ZXJpdHlDb21wYXJhdG9yIGltcGxlbWVudHMgQ29tcGFyYXRvcjxMb2dSZWNvcmQ+LCBTZXJpYWxpemFibGUgew0KKw0KKyAgICAvKioNCisgICAgICogVGhlIGdlbmVyYXRlZCBzZXJpYWwgdmVyc2lvbiBVSUQuDQorICAgICAqLw0KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMjYyMDQ0MjI0NTI1MTc5MTk2NUw7DQorDQorICAgIC8qKg0KKyAgICAgKiBBIHNpbmdsZSBpbnN0YW5jZSB0aGF0IGlzIHNoYXJlZCBhbW9uZyB0aGUgbG9nZ2luZyBwYWNrYWdlLg0KKyAgICAgKiBUaGUgZmllbGQgaXMgZGVjbGFyZWQgYXMgamF2YS51dGlsLkNvbXBhcmF0b3Igc28NCisgICAgICogV2ViYXBwQ2xhc3NMb2FkZXIuY2xlYXJSZWZlcmVuY2VzU3RhdGljRmluYWwoKSBtZXRob2Qgd2lsbCBpZ25vcmUgdGhpcw0KKyAgICAgKiBmaWVsZC4NCisgICAgICovDQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIENvbXBhcmF0b3I8TG9nUmVjb3JkPiBJTlNUQU5DRQ0KKyAgICAgICAgICAgID0gbmV3IFNldmVyaXR5Q29tcGFyYXRvcigpOw0KKw0KKyAgICAvKioNCisgICAgICogQSBzaGFyZWQgaW5zdGFuY2Ugb2YgYSBTZXZlcml0eUNvbXBhcmF0b3IuIFRoaXMgaXMgcGFja2FnZSBwcml2YXRlIHNvIHRoZQ0KKyAgICAgKiBwdWJsaWMgQVBJIGlzIG5vdCBwb2xsdXRlZCB3aXRoIG1vcmUgbWV0aG9kcy4NCisgICAgICoNCisgICAgICogQHJldHVybiBhIHNoYXJlZCBpbnN0YW5jZSBvZiBhIFNldmVyaXR5Q29tcGFyYXRvci4NCisgICAgICovDQorICAgIHN0YXRpYyBTZXZlcml0eUNvbXBhcmF0b3IgZ2V0SW5zdGFuY2UoKSB7DQorICAgICAgICByZXR1cm4gKFNldmVyaXR5Q29tcGFyYXRvcikgSU5TVEFOQ0U7DQorICAgIH0NCisNCisgICAgLyoqDQorICAgICAqIElkZW50aWZpZXMgYSBzaW5nbGUgdGhyb3dhYmxlIHRoYXQgYmVzdCBkZXNjcmliZXMgdGhlIGdpdmVuIHRocm93YWJsZSBhbmQNCisgICAgICogdGhlIGVudGlyZSB7QGxpbmtwbGFpbiBUaHJvd2FibGUjZ2V0Q2F1c2UoKSBjYXVzZX0gY2hhaW4uIFRoaXMgbWV0aG9kIGNhbg0KKyAgICAgKiBiZSBvdmVycmlkZGVuIHRvIGNoYW5nZSB0aGUgYmVoYXZpb3Igb2YNCisgICAgICoge0BsaW5rICNjb21wYXJlKGphdmEudXRpbC5sb2dnaW5nLkxvZ1JlY29yZCwgamF2YS51dGlsLmxvZ2dpbmcuTG9nUmVjb3JkKX0uDQorICAgICAqDQorICAgICAqIEBwYXJhbSBjaGFpbiB0aGUgdGhyb3dhYmxlIG9yIG51bGwuDQorICAgICAqIEByZXR1cm4gbnVsbCBpZiBudWxsIHdhcyBnaXZlbiwgb3RoZXJ3aXNlIHRoZSB0aHJvd2FibGUgdGhhdCBiZXN0DQorICAgICAqIGRlc2NyaWJlcyB0aGUgZW50aXJlIGNoYWluLg0KKyAgICAgKiBAc2VlICNpc05vcm1hbChqYXZhLmxhbmcuVGhyb3dhYmxlKQ0KKyAgICAgKi8NCisgICAgcHVibGljIFRocm93YWJsZSBhcHBseShmaW5hbCBUaHJvd2FibGUgY2hhaW4pIHsNCisgICAgICAgIC8vTWF0Y2hlcyB0aGUgai51LmYuVW5hcnlPcGVyYXRvcjxUaHJvd2FibGU+IGludGVyZmFjZS4NCisgICAgICAgIGludCBsaW1pdCA9IDA7DQorICAgICAgICBUaHJvd2FibGUgcm9vdCA9IGNoYWluOw0KKyAgICAgICAgVGhyb3dhYmxlIGhpZ2ggPSBudWxsOw0KKyAgICAgICAgVGhyb3dhYmxlIG5vcm1hbCA9IG51bGw7DQorICAgICAgICBmb3IgKFRocm93YWJsZSBjYXVzZSA9IGNoYWluOyBjYXVzZSAhPSBudWxsOyBjYXVzZSA9IGNhdXNlLmdldENhdXNlKCkpIHsNCisgICAgICAgICAgICByb290ID0gY2F1c2U7ICAvL0ZpbmQgdGhlIGRlZXBlc3QgY2F1c2UuDQorDQorICAgICAgICAgICAgLy9GaW5kIHRoZSBkZWVwZXN0IG5vbXJhbCBvY2N1cnJhbmNlLg0KKyAgICAgICAgICAgIGlmIChpc05vcm1hbChjYXVzZSkpIHsNCisgICAgICAgICAgICAgICAgbm9ybWFsID0gY2F1c2U7DQorICAgICAgICAgICAgfQ0KKw0KKyAgICAgICAgICAgIC8vRmluZCB0aGUgZGVlcGVzdCBlcnJvciB0aGF0IGhhcHBlbmVkIGJlZm9yZSBhIG5vcm1hbCBvY2N1cmFuY2UuDQorICAgICAgICAgICAgaWYgKG5vcm1hbCA9PSBudWxsICYmIGNhdXNlIGluc3RhbmNlb2YgRXJyb3IpIHsNCisgICAgICAgICAgICAgICAgaGlnaCA9IGNhdXNlOw0KKyAgICAgICAgICAgIH0NCisNCisgICAgICAgICAgICAvL0RlYWwgd2l0aCBleGNlc3NpdmUgY2F1c2UgY2hhaW5zIGFuZCBjeWNsaWMgdGhyb3dhYmxlcy4NCisgICAgICAgICAgICBpZiAoKytsaW1pdCA9PSAoMSA8PCAxNikpIHsNCisgICAgICAgICAgICAgICAgYnJlYWs7IC8vR2l2ZSB1cC4NCisgICAgICAgICAgICB9DQorICAgICAgICB9DQorICAgICAgICByZXR1cm4gaGlnaCAhPSBudWxsID8gaGlnaCA6IG5vcm1hbCAhPSBudWxsID8gbm9ybWFsIDogcm9vdDsNCisgICAgfQ0KKw0KKyAgICAvKioNCisgICAgICoge0BsaW5rICNhcHBseShqYXZhLmxhbmcuVGhyb3dhYmxlKSBSZWR1Y2VzfSBlYWNoIHRocm93YWJsZSBjaGFpbiBhcmd1bWVudA0KKyAgICAgKiB0aGVuIGNvbXBhcmUgZWFjaCB0aHJvd2FibGUgcmVzdWx0Lg0KKyAgICAgKg0KKyAgICAgKiBAcGFyYW0gdGMxIHRoZSBmaXJzdCB0aHJvd2FibGUgY2hhaW4gb3IgbnVsbC4NCisgICAgICogQHBhcmFtIHRjMiB0aGUgc2Vjb25kIHRocm93YWJsZSBjaGFpbiBvciBudWxsLg0KKyAgICAgKiBAcmV0dXJuIGEgbmVnYXRpdmUgaW50ZWdlciwgemVybywgb3IgYSBwb3NpdGl2ZSBpbnRlZ2VyIGFzIHRoZSBmaXJzdA0KKyAgICAgKiBhcmd1bWVudCBpcyBsZXNzIHRoYW4sIGVxdWFsIHRvLCBvciBncmVhdGVyIHRoYW4gdGhlIHNlY29uZC4NCisgICAgICogQHNlZSAjYXBwbHkoamF2YS5sYW5nLlRocm93YWJsZSkNCisgICAgICogQHNlZSAjY29tcGFyZVRocm93YWJsZShqYXZhLmxhbmcuVGhyb3dhYmxlLCBqYXZhLmxhbmcuVGhyb3dhYmxlKQ0KKyAgICAgKi8NCisgICAgcHVibGljIGZpbmFsIGludCBhcHBseVRoZW5Db21wYXJlKFRocm93YWJsZSB0YzEsIFRocm93YWJsZSB0YzIpIHsNCisgICAgICAgIHJldHVybiB0YzEgPT0gdGMyID8gMCA6IGNvbXBhcmVUaHJvd2FibGUoYXBwbHkodGMxKSwgYXBwbHkodGMyKSk7DQorICAgIH0NCisNCisgICAgLyoqDQorICAgICAqIENvbXBhcmVzIHR3byB0aHJvd2FibGUgb2JqZWN0cyBvciBudWxsLiBUaGlzIG1ldGhvZCBkb2VzIG5vdA0KKyAgICAgKiB7QGxpbmsgI2FwcGx5KGphdmEubGFuZy5UaHJvd2FibGUpIHJlZHVjZX0gZWFjaCBhcmd1bWVudCBiZWZvcmUNCisgICAgICogY29tcGFyaW5nLiBUaGlzIGlzIG1ldGhvZCBjYW4gYmUgb3ZlcnJpZGRlbiB0byBjaGFuZ2UgdGhlIGJlaGF2aW9yIG9mDQorICAgICAqIHtAbGlua3BsYWluICNjb21wYXJlKExvZ1JlY29yZCwgTG9nUmVjb3JkKX0uDQorICAgICAqDQorICAgICAqIEBwYXJhbSB0MSB0aGUgZmlyc3QgdGhyb3dhYmxlIG9yIG51bGwuDQorICAgICAqIEBwYXJhbSB0MiB0aGUgc2Vjb25kIHRocm93YWJsZSBvciBudWxsLg0KKyAgICAgKiBAcmV0dXJuIGEgbmVnYXRpdmUgaW50ZWdlciwgemVybywgb3IgYSBwb3NpdGl2ZSBpbnRlZ2VyIGFzIHRoZSBmaXJzdA0KKyAgICAgKiBhcmd1bWVudCBpcyBsZXNzIHRoYW4sIGVxdWFsIHRvLCBvciBncmVhdGVyIHRoYW4gdGhlIHNlY29uZC4NCisgICAgICogQHNlZSAjaXNOb3JtYWwoamF2YS5sYW5nLlRocm93YWJsZSkNCisgICAgICovDQorICAgIHB1YmxpYyBpbnQgY29tcGFyZVRocm93YWJsZShmaW5hbCBUaHJvd2FibGUgdDEsIGZpbmFsIFRocm93YWJsZSB0Mikgew0KKyAgICAgICAgaWYgKHQxID09IHQyKSB7IC8vUmVmbGV4aXZlIHRlc3QgaW5jbHVkaW5nIG51bGwuDQorICAgICAgICAgICAgcmV0dXJuIDA7DQorICAgICAgICB9IGVsc2Ugew0KKyAgICAgICAgICAgIC8vT25seSBvbmUgb3IgdGhlIG90aGVyIGlzIG51bGwgYXQgdGhpcyBwb2ludC4NCisgICAgICAgICAgICAvL0ZvcmNlIG5vcm1hbCBvY2N1cnJlbmNlIHRvIGJlIGxvd2VyIHRoYW4gbnVsbC4NCisgICAgICAgICAgICBpZiAodDEgPT0gbnVsbCkgew0KKyAgICAgICAgICAgICAgICByZXR1cm4gaXNOb3JtYWwodDIpID8gMSA6IC0xOw0KKyAgICAgICAgICAgIH0gZWxzZSB7DQorICAgICAgICAgICAgICAgIGlmICh0MiA9PSBudWxsKSB7DQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXNOb3JtYWwodDEpID8gLTEgOiAxOw0KKyAgICAgICAgICAgICAgICB9DQorICAgICAgICAgICAgfQ0KKw0KKyAgICAgICAgICAgIC8vRnJvbSB0aGlzIHBvaW50IG9uIG5laXRoZXIgYXJlIG51bGwuDQorICAgICAgICAgICAgLy9Gb2xsb3cgdGhlIHNob3J0Y3V0IGlmIHdlIGNhbi4NCisgICAgICAgICAgICBpZiAodDEuZ2V0Q2xhc3MoKSA9PSB0Mi5nZXRDbGFzcygpKSB7DQorICAgICAgICAgICAgICAgIHJldHVybiAwOw0KKyAgICAgICAgICAgIH0NCisNCisgICAgICAgICAgICAvL0Vuc3VyZSBub3JtYWwgb2NjdXJyZW5jZSBmbG93IGNvbnRyb2wgaXMgb3JkZXJlZCBsb3cuDQorICAgICAgICAgICAgaWYgKGlzTm9ybWFsKHQxKSkgew0KKyAgICAgICAgICAgICAgICByZXR1cm4gaXNOb3JtYWwodDIpID8gMCA6IC0xOw0KKyAgICAgICAgICAgIH0gZWxzZSB7DQorICAgICAgICAgICAgICAgIGlmIChpc05vcm1hbCh0MikpIHsNCisgICAgICAgICAgICAgICAgICAgIHJldHVybiAxOw0KKyAgICAgICAgICAgICAgICB9DQorICAgICAgICAgICAgfQ0KKw0KKyAgICAgICAgICAgIC8vUmFuayB0aGUgdHdvIHVuaWRlbnRpY2lhbCB0aHJvd2FibGVzIHVzaW5nIHRoZSBydWxlcyBmcm9tDQorICAgICAgICAgICAgLy9KTFMgMTEuMS4xLiBUaGUgS2luZHMgb2YgRXhjZXB0aW9ucyBhbmQNCisgICAgICAgICAgICAvL0pMUyAxMS41IFRoZSBFeGNlcHRpb24gSGllcmFyY2h5Lg0KKyAgICAgICAgICAgIGlmICh0MSBpbnN0YW5jZW9mIEVycm9yKSB7DQorICAgICAgICAgICAgICAgIHJldHVybiB0MiBpbnN0YW5jZW9mIEVycm9yID8gMCA6IDE7DQorICAgICAgICAgICAgfSBlbHNlIGlmICh0MSBpbnN0YW5jZW9mIFJ1bnRpbWVFeGNlcHRpb24pIHsNCisgICAgICAgICAgICAgICAgcmV0dXJuIHQyIGluc3RhbmNlb2YgRXJyb3IgPyAtMQ0KKyAgICAgICAgICAgICAgICAgICAgICAgIDogdDIgaW5zdGFuY2VvZiBSdW50aW1lRXhjZXB0aW9uID8gMCA6IDE7DQorICAgICAgICAgICAgfSBlbHNlIHsNCisgICAgICAgICAgICAgICAgcmV0dXJuIHQyIGluc3RhbmNlb2YgRXJyb3INCisgICAgICAgICAgICAgICAgICAgICAgICB8fCB0MiBpbnN0YW5jZW9mIFJ1bnRpbWVFeGNlcHRpb24gPyAtMSA6IDA7DQorICAgICAgICAgICAgfQ0KKyAgICAgICAgfQ0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBDb21wYXJlcyB0d28gbG9nIHJlY29yZHMgYmFzZWQgb24gc2V2ZXJpdHkuDQorICAgICAqDQorICAgICAqIEBwYXJhbSBvMSB0aGUgZmlyc3QgbG9nIHJlY29yZC4NCisgICAgICogQHBhcmFtIG8yIHRoZSBzZWNvbmQgbG9nIHJlY29yZC4NCisgICAgICogQHJldHVybiBhIG5lZ2F0aXZlIGludGVnZXIsIHplcm8sIG9yIGEgcG9zaXRpdmUgaW50ZWdlciBhcyB0aGUgZmlyc3QNCisgICAgICogYXJndW1lbnQgaXMgbGVzcyB0aGFuLCBlcXVhbCB0bywgb3IgZ3JlYXRlciB0aGFuIHRoZSBzZWNvbmQuDQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgZWl0aGVyIGFyZ3VtZW50IGlzIG51bGwuDQorICAgICAqLw0KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygib3ZlcnJpZGUiKSAvL0pESy02OTU0MjM0DQorICAgIHB1YmxpYyBpbnQgY29tcGFyZShmaW5hbCBMb2dSZWNvcmQgbzEsIGZpbmFsIExvZ1JlY29yZCBvMikgew0KKyAgICAgICAgaWYgKG8xID09IG51bGwgfHwgbzIgPT0gbnVsbCkgeyAvL0Rvbid0IGFsbG93IG51bGwuDQorICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKHRvU3RyaW5nKG8xLCBvMikpOw0KKyAgICAgICAgfQ0KKw0KKyAgICAgICAgLyoqDQorICAgICAgICAgKiBMb2dSZWNvcmRzIGFyZSBtdXRhYmxlIHNvIGEgcmVmbGV4aXZlIHJlbGF0aW9uc2hpcCB0ZXN0IGlzIGEgc2FmZXR5DQorICAgICAgICAgKiByZXF1aXJlbWVudC4NCisgICAgICAgICAqLw0KKyAgICAgICAgaWYgKG8xID09IG8yKSB7DQorICAgICAgICAgICAgcmV0dXJuIDA7DQorICAgICAgICB9DQorDQorICAgICAgICBpbnQgY21wID0gY29tcGFyZShvMS5nZXRMZXZlbCgpLCBvMi5nZXRMZXZlbCgpKTsNCisgICAgICAgIGlmIChjbXAgPT0gMCkgew0KKyAgICAgICAgICAgIGNtcCA9IGFwcGx5VGhlbkNvbXBhcmUobzEuZ2V0VGhyb3duKCksIG8yLmdldFRocm93bigpKTsNCisgICAgICAgICAgICBpZiAoY21wID09IDApIHsNCisgICAgICAgICAgICAgICAgY21wID0gY29tcGFyZShvMS5nZXRTZXF1ZW5jZU51bWJlcigpLCBvMi5nZXRTZXF1ZW5jZU51bWJlcigpKTsNCisgICAgICAgICAgICAgICAgaWYgKGNtcCA9PSAwKSB7DQorICAgICAgICAgICAgICAgICAgICBjbXAgPSBjb21wYXJlKG8xLmdldE1pbGxpcygpLCBvMi5nZXRNaWxsaXMoKSk7DQorICAgICAgICAgICAgICAgIH0NCisgICAgICAgICAgICB9DQorICAgICAgICB9DQorICAgICAgICByZXR1cm4gY21wOw0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBEZXRlcm1pbmVzIGlmIHRoZSBnaXZlbiBvYmplY3QgaXMgYWxzbyBhIGNvbXBhcmF0b3IgYW5kIGl0IGltcG9zZXMgdGhlDQorICAgICAqIHNhbWUgb3JkZXJpbmcgYXMgdGhpcyBjb21wYXJhdG9yLg0KKyAgICAgKg0KKyAgICAgKiBAcGFyYW0gbyB0aGUgcmVmZXJlbmNlIG9iamVjdCB3aXRoIHdoaWNoIHRvIGNvbXBhcmUuDQorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIG9iamVjdCBlcXVhbCB0byB0aGUgYXJndW1lbnQ7IGZhbHNlIG90aGVyd2lzZS4NCisgICAgICovDQorICAgIEBPdmVycmlkZQ0KKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgT2JqZWN0IG8pIHsNCisgICAgICAgIHJldHVybiBvID09IG51bGwgPyBmYWxzZSA6IG8uZ2V0Q2xhc3MoKSA9PSBnZXRDbGFzcygpOw0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBSZXR1cm5zIGEgaGFzaCBjb2RlIHZhbHVlIGZvciB0aGUgb2JqZWN0Lg0KKyAgICAgKg0KKyAgICAgKiBAcmV0dXJuIFJldHVybnMgYSBoYXNoIGNvZGUgdmFsdWUgZm9yIHRoZSBvYmplY3QuDQorICAgICAqLw0KKyAgICBAT3ZlcnJpZGUNCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsNCisgICAgICAgIHJldHVybiAzMSAqIGdldENsYXNzKCkuaGFzaENvZGUoKTsNCisgICAgfQ0KKw0KKyAgICAvKioNCisgICAgICogRGV0ZXJtaW5lcyBpZiB0aGUgZ2l2ZW4gdGhyb3dhYmxlIGluc3RhbmNlIGlzICJub3JtYWwgb2NjdXJyZW5jZSIuIFRoaXMNCisgICAgICogaXMgYW55IGNoZWNrZWQgb3IgdW5jaGVja2VkIGV4Y2VwdGlvbiB3aXRoICdJbnRlcnJ1cHQnIGluIHRoZSBjbGFzcyBuYW1lDQorICAgICAqIG9yIGFuY2VzdHJhbCBjbGFzcyBuYW1lLiBBbnkge0Bjb2RlIGphdmEubGFuZy5UaHJlYWREZWF0aH0gb2JqZWN0IG9yDQorICAgICAqIHN1YmNsYXNzZXMuDQorICAgICAqDQorICAgICAqIFRoaXMgbWV0aG9kIGNhbiBiZSBvdmVycmlkZGVuIHRvIGNoYW5nZSB0aGUgYmVoYXZpb3Igb2YgdGhlDQorICAgICAqIHtAbGlua3BsYWluICNhcHBseShqYXZhLmxhbmcuVGhyb3dhYmxlKX0gbWV0aG9kLg0KKyAgICAgKg0KKyAgICAgKiBAcGFyYW0gdCBhIHRocm93YWJsZSBvciBudWxsLg0KKyAgICAgKiBAcmV0dXJuIHRydWUgdGhlIGdpdmVuIHRocm93YWJsZSBpcyBhICJub3JtYWwgb2NjdXJyZW5jZSIuDQorICAgICAqLw0KKyAgICBwdWJsaWMgYm9vbGVhbiBpc05vcm1hbChmaW5hbCBUaHJvd2FibGUgdCkgew0KKyAgICAgICAgaWYgKHQgPT0gbnVsbCkgeyAvL1RoaXMgaXMgb25seSBuZWVkZWQgd2hlbiBjYWxsZWQgZGlyZWN0bHkuDQorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOw0KKyAgICAgICAgfQ0KKw0KKyAgICAgICAgLyoqDQorICAgICAgICAgKiBVc2UgdGhlIGNsYXNzIG5hbWVzIHRvIGF2b2lkIGxvYWRpbmcgbW9yZSBjbGFzc2VzLg0KKyAgICAgICAgICovDQorICAgICAgICBmaW5hbCBDbGFzczw/PiByb290ID0gVGhyb3dhYmxlLmNsYXNzOw0KKyAgICAgICAgZmluYWwgQ2xhc3M8Pz4gZXJyb3IgPSBFcnJvci5jbGFzczsNCisgICAgICAgIGZvciAoQ2xhc3M8Pz4gYyA9IHQuZ2V0Q2xhc3MoKTsgYyAhPSByb290OyBjID0gYy5nZXRTdXBlcmNsYXNzKCkpIHsNCisgICAgICAgICAgICBpZiAoZXJyb3IuaXNBc3NpZ25hYmxlRnJvbShjKSkgew0KKyAgICAgICAgICAgICAgICBpZiAoYy5nZXROYW1lKCkuZXF1YWxzKCJqYXZhLmxhbmcuVGhyZWFkRGVhdGgiKSkgew0KKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7DQorICAgICAgICAgICAgICAgIH0NCisgICAgICAgICAgICB9IGVsc2Ugew0KKyAgICAgICAgICAgICAgICAvL0ludGVycnVwdCwgSW50ZXJydXB0ZWQgb3IgSW50ZXJydXB0aW9uLg0KKyAgICAgICAgICAgICAgICBpZiAoYy5nZXROYW1lKCkuY29udGFpbnMoIkludGVycnVwdCIpKSB7DQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsNCisgICAgICAgICAgICAgICAgfQ0KKyAgICAgICAgICAgIH0NCisgICAgICAgIH0NCisgICAgICAgIHJldHVybiBmYWxzZTsNCisgICAgfQ0KKw0KKyAgICAvKioNCisgICAgICogQ29tcGFyZSB0d28gbGV2ZWwgb2JqZWN0cy4NCisgICAgICoNCisgICAgICogQHBhcmFtIGEgdGhlIGZpcnN0IGxldmVsLg0KKyAgICAgKiBAcGFyYW0gYiB0aGUgc2Vjb25kIGxldmVsLg0KKyAgICAgKiBAcmV0dXJuIGEgbmVnYXRpdmUgaW50ZWdlciwgemVybywgb3IgYSBwb3NpdGl2ZSBpbnRlZ2VyIGFzIHRoZSBmaXJzdA0KKyAgICAgKiBhcmd1bWVudCBpcyBsZXNzIHRoYW4sIGVxdWFsIHRvLCBvciBncmVhdGVyIHRoYW4gdGhlIHNlY29uZC4NCisgICAgICovDQorICAgIHByaXZhdGUgaW50IGNvbXBhcmUoZmluYWwgTGV2ZWwgYSwgZmluYWwgTGV2ZWwgYikgew0KKyAgICAgICAgcmV0dXJuIGEgPT0gYiA/IDAgOiBjb21wYXJlKGEuaW50VmFsdWUoKSwgYi5pbnRWYWx1ZSgpKTsNCisgICAgfQ0KKw0KKyAgICAvKioNCisgICAgICogT3V0bGluZSB0aGUgbWVzc2FnZSBjcmVhdGUgc3RyaW5nLg0KKyAgICAgKg0KKyAgICAgKiBAcGFyYW0gbzEgYXJndW1lbnQgb25lLg0KKyAgICAgKiBAcGFyYW0gbzIgYXJndW1lbnQgdHdvLg0KKyAgICAgKiBAcmV0dXJuIHRoZSBtZXNzYWdlIHN0cmluZy4NCisgICAgICovDQorICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyB0b1N0cmluZyhmaW5hbCBPYmplY3QgbzEsIGZpbmFsIE9iamVjdCBvMikgew0KKyAgICAgICAgcmV0dXJuIG8xICsgIiwgIiArIG8yOw0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBDb21wYXJlIHR3byBsb25ncy4gQ2FuIGJlIHJlbW92ZWQgd2hlbiBKREsgMS43IGlzIHJlcXVpcmVkLg0KKyAgICAgKg0KKyAgICAgKiBAcGFyYW0geCB0aGUgZmlyc3QgbG9uZy4NCisgICAgICogQHBhcmFtIHkgdGhlIHNlY29uZCBsb25nLg0KKyAgICAgKiBAcmV0dXJuIGEgbmVnYXRpdmUgaW50ZWdlciwgemVybywgb3IgYSBwb3NpdGl2ZSBpbnRlZ2VyIGFzIHRoZSBmaXJzdA0KKyAgICAgKiBhcmd1bWVudCBpcyBsZXNzIHRoYW4sIGVxdWFsIHRvLCBvciBncmVhdGVyIHRoYW4gdGhlIHNlY29uZC4NCisgICAgICovDQorICAgIHByaXZhdGUgaW50IGNvbXBhcmUoZmluYWwgbG9uZyB4LCBmaW5hbCBsb25nIHkpIHsNCisgICAgICAgIHJldHVybiB4IDwgeSA/IC0xIDogeCA+IHkgPyAxIDogMDsNCisgICAgfQ0KK30NCmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvbG9nZ2luZy9wYWNrYWdlLmh0bWwgYi9tYWlsL3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3V0aWwvbG9nZ2luZy9wYWNrYWdlLmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDhkYWJmYgotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvdXRpbC9sb2dnaW5nL3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDM0IEBACis8IURPQ1RZUEUgSFRNTCBQVUJMSUMgIi0vL1czQy8vRFREIEhUTUwgMy4yIEZpbmFsLy9FTiI+Cis8aHRtbD4KKyAgPGhlYWQ+Cis8IS0tCisKKyAgICBDb3B5cmlnaHQgKGMpIDIwMDksIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAgICBDb3B5cmlnaHQgKGMpIDIwMDksIDIwMTggSmFzb24gTWVocmVucy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKworICAgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICAgIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorCisgICAgVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICAgIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAgICBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAgICB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKworICAgIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorCistLT4KKworICAgIDx0aXRsZT48L3RpdGxlPgorICAgIDxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04Ij4KKyAgPC9oZWFkPgorICA8Ym9keT4KKyAgICAgIENvbnRhaW5zIEphdmFNYWlsJnRyYWRlOyBleHRlbnNpb25zIGZvcgorICAgICAgdGhlIEphdmEmdHJhZGU7IHBsYXRmb3JtJ3MgY29yZSBsb2dnaW5nCisgICAgICBmYWNpbGl0aWVzLiAgVGhpcyBwYWNrYWdlIGNvbnRhaW5zIGNsYXNzZXMgdXNlZCB0byBleHBvcnQgbG9nIG1lc3NhZ2VzCisgICAgICBhcyBhIGZvcm1hdHRlZCBlbWFpbCBtZXNzYWdlLiAgQ2xhc3NlcyBpbiB0aGlzIHBhY2thZ2UgdHlwaWNhbGx5IHVzZQorICAgICAgTG9nTWFuYWdlciBwcm9wZXJ0aWVzIHRvIHNldCBkZWZhdWx0IHZhbHVlczsgc2VlIHRoZSBzcGVjaWZpYworICAgICAgZG9jdW1lbnRhdGlvbiBmb3IgZWFjaCBjb25jcmV0ZSBjbGFzcy4KKyAgPC9ib2R5PgorPC9odG1sPgpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL3BhY2thZ2UuaHRtbCBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvdXRpbC9wYWNrYWdlLmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGI3YThlYQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvdXRpbC9wYWNrYWdlLmh0bWwKQEAgLTAsMCArMSw2MCBAQAorPCFET0NUWVBFIGh0bWwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMDEgVHJhbnNpdGlvbmFsLy9FTiI+Cis8SFRNTD4KKzxIRUFEPgorPG1ldGEgaHR0cC1lcXVpdj0iQ29udGVudC1UeXBlIiBjb250ZW50PSJ0ZXh0L2h0bWw7IGNoYXJzZXQ9dXRmLTgiPgorPCEtLQorCisgICAgQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisKKyAgICBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAgICB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKworICAgIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAgICBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgICAgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgICAgdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisKKyAgICBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKworLS0+CisKKzxUSVRMRT5jb20uc3VuLm1haWwudXRpbCBwYWNrYWdlPC9USVRMRT4KKzwvSEVBRD4KKzxCT0RZIEJHQ09MT1I9IndoaXRlIj4KKworPFA+CitVdGlsaXR5IGNsYXNzZXMgZm9yIHVzZSB3aXRoIHRoZSBKYXZhTWFpbCBBUEkuCitUaGVzZSB1dGlsaXR5IGNsYXNzZXMgYXJlIG5vdCBwYXJ0IG9mIHRoZSBKYXZhTWFpbCBzcGVjaWZpY2F0aW9uLgorV2hpbGUgdGhpcyBwYWNrYWdlIGNvbnRhaW5zIG1hbnkgY2xhc3NlcyB1c2VkIGJ5IHRoZSBKYXZhTWFpbCBpbXBsZW1lbnRhdGlvbgorYW5kIG5vdCBpbnRlbmRlZCBmb3IgZGlyZWN0IHVzZSBieSBhcHBsaWNhdGlvbnMsIHRoZSBjbGFzc2VzIGRvY3VtZW50ZWQKK2hlcmUgbWF5IGJlIG9mIHVzZSB0byBhcHBsaWNhdGlvbnMuCis8L1A+Cis8UD4KK0NsYXNzZXMgaW4gdGhpcyBwYWNrYWdlIGxvZyBkZWJ1Z2dpbmcgaW5mb3JtYXRpb24gdXNpbmcKK3tAbGluayBqYXZhLnV0aWwubG9nZ2luZ30gYXMgZGVzY3JpYmVkIGluIHRoZSBmb2xsb3dpbmcgdGFibGU6Cis8L1A+Cis8VEFCTEUgQk9SREVSIFNVTU1BUlk9ImNvbS5zdW4ubWFpbC51dGlsIExvZ2dlcnMiPgorPFRSPgorPFRIPkxvZ2dlciBOYW1lPC9USD4KKzxUSD5Mb2dnaW5nIExldmVsPC9USD4KKzxUSD5QdXJwb3NlPC9USD4KKzwvVFI+CisKKzxUUj4KKzxURD5jb20uc3VuLm1haWwudXRpbC5zb2NrZXQ8L1REPgorPFREPkZJTkVSPC9URD4KKzxURD5EZWJ1Z2dpbmcgb3V0cHV0IHJlbGF0ZWQgdG8gY3JlYXRpbmcgc29ja2V0czwvVEQ+Cis8L1RSPgorPC9UQUJMRT4KKworPFA+Cis8c3Ryb25nPldBUk5JTkc6PC9zdHJvbmc+IFRoZSBBUElzIGluIHRoaXMgcGFja2FnZSBzaG91bGQgYmUKK2NvbnNpZGVyZWQgPHN0cm9uZz5FWFBFUklNRU5UQUw8L3N0cm9uZz4uICBUaGV5IG1heSBiZSBjaGFuZ2VkIGluIHRoZQorZnV0dXJlIGluIHdheXMgdGhhdCBhcmUgaW5jb21wYXRpYmxlIHdpdGggYXBwbGljYXRpb25zIHVzaW5nIHRoZQorY3VycmVudCBBUElzLgorPC9QPgorCis8L0JPRFk+Cis8L0hUTUw+CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9BZGRyZXNzLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9BZGRyZXNzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmI4N2NmNAotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL0FkZHJlc3MuamF2YQpAQCAtMCwwICsxLDY2IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGphdmF4Lm1haWw7CisKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKKworLyoqCisgKiBUaGlzIGFic3RyYWN0IGNsYXNzIG1vZGVscyB0aGUgYWRkcmVzc2VzIGluIGEgbWVzc2FnZS4KKyAqIFN1YmNsYXNzZXMgcHJvdmlkZSBzcGVjaWZpYyBpbXBsZW1lbnRhdGlvbnMuICBTdWJjbGFzc2VzCisgKiB3aWxsIHR5cGljYWxseSBiZSBzZXJpYWxpemFibGUgc28gdGhhdCAoZm9yIGV4YW1wbGUpIHRoZQorICogdXNlIG9mIEFkZHJlc3Mgb2JqZWN0cyBpbiBzZWFyY2ggdGVybXMgY2FuIGJlIHNlcmlhbGl6ZWQKKyAqIGFsb25nIHdpdGggdGhlIHNlYXJjaCB0ZXJtcy4KKyAqCisgKiBAYXV0aG9yIEpvaG4gTWFuaQorICogQGF1dGhvciBCaWxsIFNoYW5ub24KKyAqLworCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQWRkcmVzcyBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNTgyMjQ1OTYyNjc1MTk5MjI3OEw7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYSB0eXBlIHN0cmluZyB0aGF0IGlkZW50aWZpZXMgdGhpcyBhZGRyZXNzIHR5cGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCWFkZHJlc3MgdHlwZQorICAgICAqIEBzZWUJamF2YXgubWFpbC5pbnRlcm5ldC5JbnRlcm5ldEFkZHJlc3MKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGdldFR5cGUoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybiBhIFN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIGFkZHJlc3Mgb2JqZWN0LgorICAgICAqCisgICAgICogQHJldHVybglzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBhZGRyZXNzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGFic3RyYWN0IFN0cmluZyB0b1N0cmluZygpOworCisgICAgLyoqCisgICAgICogVGhlIGVxdWFsaXR5IG9wZXJhdG9yLiAgU3ViY2xhc3NlcyBzaG91bGQgcHJvdmlkZSBhbgorICAgICAqIGltcGxlbWVudGF0aW9uIG9mIHRoaXMgbWV0aG9kIHRoYXQgc3VwcG9ydHMgdmFsdWUgZXF1YWxpdHkKKyAgICAgKiAoZG8gdGhlIHR3byBBZGRyZXNzIG9iamVjdHMgcmVwcmVzZW50IHRoZSBzYW1lIGRlc3RpbmF0aW9uPyksCisgICAgICogbm90IG9iamVjdCByZWZlcmVuY2UgZXF1YWxpdHkuICBBIHN1YmNsYXNzIG11c3QgYWxzbyBwcm92aWRlCisgICAgICogYSBjb3JyZXNwb25kaW5nIGltcGxlbWVudGF0aW9uIG9mIHRoZSA8Y29kZT5oYXNoQ29kZTwvY29kZT4KKyAgICAgKiBtZXRob2QgdGhhdCBwcmVzZXJ2ZXMgdGhlIGdlbmVyYWwgY29udHJhY3Qgb2YKKyAgICAgKiA8Y29kZT5lcXVhbHM8L2NvZGU+IGFuZCA8Y29kZT5oYXNoQ29kZTwvY29kZT4gLSBvYmplY3RzIHRoYXQKKyAgICAgKiBjb21wYXJlIGFzIGVxdWFsIG11c3QgaGF2ZSB0aGUgc2FtZSBoYXNoQ29kZS4KKyAgICAgKgorICAgICAqIEBwYXJhbQlhZGRyZXNzCUFkZHJlc3Mgb2JqZWN0CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gZXF1YWxzKE9iamVjdCBhZGRyZXNzKTsKK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL0F1dGhlbnRpY2F0aW9uRmFpbGVkRXhjZXB0aW9uLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9BdXRoZW50aWNhdGlvbkZhaWxlZEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUwZGU4MDkKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9BdXRoZW50aWNhdGlvbkZhaWxlZEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNjAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbDsKKworLyoqCisgKiBUaGlzIGV4Y2VwdGlvbiBpcyB0aHJvd24gd2hlbiB0aGUgY29ubmVjdCBtZXRob2Qgb24gYSBTdG9yZSBvcgorICogVHJhbnNwb3J0IG9iamVjdCBmYWlscyBkdWUgdG8gYW4gYXV0aGVudGljYXRpb24gZmFpbHVyZSAoZS5nLiwKKyAqIGJhZCB1c2VyIG5hbWUgb3IgcGFzc3dvcmQpLgorICoKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKi8KKworcHVibGljIGNsYXNzIEF1dGhlbnRpY2F0aW9uRmFpbGVkRXhjZXB0aW9uIGV4dGVuZHMgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDQ5MjA4MDc1NDA1NDQzNjUxMUw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGFuIEF1dGhlbnRpY2F0aW9uRmFpbGVkRXhjZXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBBdXRoZW50aWNhdGlvbkZhaWxlZEV4Y2VwdGlvbigpIHsKKwlzdXBlcigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYW4gQXV0aGVudGljYXRpb25GYWlsZWRFeGNlcHRpb24gd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogZGV0YWlsIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWVzc2FnZQlUaGUgZGV0YWlsZWQgZXJyb3IgbWVzc2FnZQorICAgICAqLworICAgIHB1YmxpYyBBdXRoZW50aWNhdGlvbkZhaWxlZEV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSkgeworCXN1cGVyKG1lc3NhZ2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYW4gQXV0aGVudGljYXRpb25GYWlsZWRFeGNlcHRpb24gd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogZGV0YWlsIG1lc3NhZ2UgYW5kIGVtYmVkZGVkIGV4Y2VwdGlvbi4gIFRoZSBleGNlcHRpb24gaXMgY2hhaW5lZAorICAgICAqIHRvIHRoaXMgZXhjZXB0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIG1lc3NhZ2UJVGhlIGRldGFpbGVkIGVycm9yIG1lc3NhZ2UKKyAgICAgKiBAcGFyYW0gZQkJVGhlIGVtYmVkZGVkIGV4Y2VwdGlvbgorICAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS41CisgICAgICovCisgICAgcHVibGljIEF1dGhlbnRpY2F0aW9uRmFpbGVkRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlLCBFeGNlcHRpb24gZSkgeworCXN1cGVyKG1lc3NhZ2UsIGUpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL0F1dGhlbnRpY2F0b3IuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL0F1dGhlbnRpY2F0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ZmE3ODM4Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvQXV0aGVudGljYXRvci5qYXZhCkBAIC0wLDAgKzEsMTM4IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGphdmF4Lm1haWw7CisKK2ltcG9ydCBqYXZhLm5ldC5JbmV0QWRkcmVzczsKKworLyoqCisgKiBUaGUgY2xhc3MgQXV0aGVudGljYXRvciByZXByZXNlbnRzIGFuIG9iamVjdCB0aGF0IGtub3dzIGhvdyB0byBvYnRhaW4KKyAqIGF1dGhlbnRpY2F0aW9uIGZvciBhIG5ldHdvcmsgY29ubmVjdGlvbi4gIFVzdWFsbHksIGl0IHdpbGwgZG8gdGhpcworICogYnkgcHJvbXB0aW5nIHRoZSB1c2VyIGZvciBpbmZvcm1hdGlvbi4KKyAqIDxwPgorICogQXBwbGljYXRpb25zIHVzZSB0aGlzIGNsYXNzIGJ5IGNyZWF0aW5nIGEgc3ViY2xhc3MsIGFuZCByZWdpc3RlcmluZworICogYW4gaW5zdGFuY2Ugb2YgdGhhdCBzdWJjbGFzcyB3aXRoIHRoZSBzZXNzaW9uIHdoZW4gaXQgaXMgY3JlYXRlZC4KKyAqIFdoZW4gYXV0aGVudGljYXRpb24gaXMgcmVxdWlyZWQsIHRoZSBzeXN0ZW0gd2lsbCBpbnZva2UgYSBtZXRob2QKKyAqIG9uIHRoZSBzdWJjbGFzcyAobGlrZSBnZXRQYXNzd29yZEF1dGhlbnRpY2F0aW9uKS4gIFRoZSBzdWJjbGFzcydzCisgKiBtZXRob2QgY2FuIHF1ZXJ5IGFib3V0IHRoZSBhdXRoZW50aWNhdGlvbiBiZWluZyByZXF1ZXN0ZWQgd2l0aCBhCisgKiBudW1iZXIgb2YgaW5oZXJpdGVkIG1ldGhvZHMgKGdldFJlcXVlc3RpbmdYWFgoKSksIGFuZCBmb3JtIGFuCisgKiBhcHByb3ByaWF0ZSBtZXNzYWdlIGZvciB0aGUgdXNlci4KKyAqIDxwPgorICogQWxsIG1ldGhvZHMgdGhhdCByZXF1ZXN0IGF1dGhlbnRpY2F0aW9uIGhhdmUgYSBkZWZhdWx0IGltcGxlbWVudGF0aW9uCisgKiB0aGF0IGZhaWxzLgorICoKKyAqIEBzZWUgamF2YS5uZXQuQXV0aGVudGljYXRvcgorICogQHNlZSBqYXZheC5tYWlsLlNlc3Npb24jZ2V0SW5zdGFuY2UoamF2YS51dGlsLlByb3BlcnRpZXMsCisgKgkJCQkJamF2YXgubWFpbC5BdXRoZW50aWNhdG9yKQorICogQHNlZSBqYXZheC5tYWlsLlNlc3Npb24jZ2V0RGVmYXVsdEluc3RhbmNlKGphdmEudXRpbC5Qcm9wZXJ0aWVzLAorICoJCQkJCWphdmF4Lm1haWwuQXV0aGVudGljYXRvcikKKyAqIEBzZWUgamF2YXgubWFpbC5TZXNzaW9uI3JlcXVlc3RQYXNzd29yZEF1dGhlbnRpY2F0aW9uCisgKiBAc2VlIGphdmF4Lm1haWwuUGFzc3dvcmRBdXRoZW50aWNhdGlvbgorICoKKyAqIEBhdXRob3IgIEJpbGwgRm9vdGUKKyAqIEBhdXRob3IgIEJpbGwgU2hhbm5vbgorICovCisKKy8vIFRoZXJlIGFyZSBubyBhYnN0cmFjdCBtZXRob2RzLCBidXQgdG8gYmUgdXNlZnVsIHRoZSB1c2VyIG11c3QKKy8vIHN1YmNsYXNzLgorcHVibGljIGFic3RyYWN0IGNsYXNzIEF1dGhlbnRpY2F0b3IgeworCisgICAgcHJpdmF0ZSBJbmV0QWRkcmVzcyByZXF1ZXN0aW5nU2l0ZTsKKyAgICBwcml2YXRlIGludCByZXF1ZXN0aW5nUG9ydDsKKyAgICBwcml2YXRlIFN0cmluZyByZXF1ZXN0aW5nUHJvdG9jb2w7CisgICAgcHJpdmF0ZSBTdHJpbmcgcmVxdWVzdGluZ1Byb21wdDsKKyAgICBwcml2YXRlIFN0cmluZyByZXF1ZXN0aW5nVXNlck5hbWU7CisKKyAgICAvKioKKyAgICAgKiBBc2sgdGhlIGF1dGhlbnRpY2F0b3IgZm9yIGEgcGFzc3dvcmQuCisgICAgICogPHA+CisgICAgICoKKyAgICAgKiBAcGFyYW0gYWRkciBUaGUgSW5ldEFkZHJlc3Mgb2YgdGhlIHNpdGUgcmVxdWVzdGluZyBhdXRob3JpemF0aW9uLAorICAgICAqICAgICAgICAgICAgIG9yIG51bGwgaWYgbm90IGtub3duLgorICAgICAqIEBwYXJhbSBwb3J0IHRoZSBwb3J0IGZvciB0aGUgcmVxdWVzdGVkIGNvbm5lY3Rpb24KKyAgICAgKiBAcGFyYW0gcHJvdG9jb2wgVGhlIHByb3RvY29sIHRoYXQncyByZXF1ZXN0aW5nIHRoZSBjb25uZWN0aW9uCisgICAgICogICAgICAgICAgKEBzZWUgamF2YS5uZXQuQXV0aGVudGljYXRvci5nZXRQcm90b2NvbCgpKQorICAgICAqIEBwYXJhbSBwcm9tcHQgQSBwcm9tcHQgc3RyaW5nIGZvciB0aGUgdXNlcgorICAgICAqCisgICAgICogQHJldHVybiBUaGUgdXNlcm5hbWUvcGFzc3dvcmQsIG9yIG51bGwgaWYgb25lIGNhbid0IGJlIGdvdHRlbi4KKyAgICAgKi8KKyAgICBmaW5hbCBzeW5jaHJvbml6ZWQgUGFzc3dvcmRBdXRoZW50aWNhdGlvbiByZXF1ZXN0UGFzc3dvcmRBdXRoZW50aWNhdGlvbigKKwkJCQlJbmV0QWRkcmVzcyBhZGRyLCBpbnQgcG9ydCwgU3RyaW5nIHByb3RvY29sLAorCQkJCVN0cmluZyBwcm9tcHQsIFN0cmluZyBkZWZhdWx0VXNlck5hbWUpIHsKKwlyZXF1ZXN0aW5nU2l0ZSA9IGFkZHI7CisJcmVxdWVzdGluZ1BvcnQgPSBwb3J0OworCXJlcXVlc3RpbmdQcm90b2NvbCA9IHByb3RvY29sOworCXJlcXVlc3RpbmdQcm9tcHQgPSBwcm9tcHQ7CisJcmVxdWVzdGluZ1VzZXJOYW1lID0gZGVmYXVsdFVzZXJOYW1lOworCXJldHVybiBnZXRQYXNzd29yZEF1dGhlbnRpY2F0aW9uKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHJldHVybiB0aGUgSW5ldEFkZHJlc3Mgb2YgdGhlIHNpdGUgcmVxdWVzdGluZyBhdXRob3JpemF0aW9uLCBvciBudWxsCisgICAgICoJCWlmIGl0J3Mgbm90IGF2YWlsYWJsZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgZmluYWwgSW5ldEFkZHJlc3MgZ2V0UmVxdWVzdGluZ1NpdGUoKSB7CisJcmV0dXJuIHJlcXVlc3RpbmdTaXRlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEByZXR1cm4gdGhlIHBvcnQgZm9yIHRoZSByZXF1ZXN0ZWQgY29ubmVjdGlvbgorICAgICAqLworICAgIHByb3RlY3RlZCBmaW5hbCBpbnQgZ2V0UmVxdWVzdGluZ1BvcnQoKSB7CisJcmV0dXJuIHJlcXVlc3RpbmdQb3J0OworICAgIH0KKworICAgIC8qKgorICAgICAqIEdpdmUgdGhlIHByb3RvY29sIHRoYXQncyByZXF1ZXN0aW5nIHRoZSBjb25uZWN0aW9uLiAgT2Z0ZW4gdGhpcworICAgICAqIHdpbGwgYmUgYmFzZWQgb24gYSBVUkxOYW1lLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgcHJvdGNvbAorICAgICAqCisgICAgICogQHNlZSBqYXZheC5tYWlsLlVSTE5hbWUjZ2V0UHJvdG9jb2wKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgZmluYWwgU3RyaW5nIGdldFJlcXVlc3RpbmdQcm90b2NvbCgpIHsKKwlyZXR1cm4gcmVxdWVzdGluZ1Byb3RvY29sOworICAgIH0KKworICAgIC8qKgorICAgICAqIEByZXR1cm4gdGhlIHByb21wdCBzdHJpbmcgZ2l2ZW4gYnkgdGhlIHJlcXVlc3RvcgorICAgICAqLworICAgIHByb3RlY3RlZCBmaW5hbCBTdHJpbmcgZ2V0UmVxdWVzdGluZ1Byb21wdCgpIHsKKwlyZXR1cm4gcmVxdWVzdGluZ1Byb21wdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcmV0dXJuIHRoZSBkZWZhdWx0IHVzZXIgbmFtZSBnaXZlbiBieSB0aGUgcmVxdWVzdG9yCisgICAgICovCisgICAgcHJvdGVjdGVkIGZpbmFsIFN0cmluZyBnZXREZWZhdWx0VXNlck5hbWUoKSB7CisJcmV0dXJuIHJlcXVlc3RpbmdVc2VyTmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDYWxsZWQgd2hlbiBwYXNzd29yZCBhdXRoZW50aWNhdGlvbiBpcyBuZWVkZWQuICBTdWJjbGFzc2VzIHNob3VsZAorICAgICAqIG92ZXJyaWRlIHRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uLCB3aGljaCByZXR1cm5zIG51bGwuIDxwPgorICAgICAqCisgICAgICogTm90ZSB0aGF0IGlmIHRoaXMgbWV0aG9kIHVzZXMgYSBkaWFsb2cgdG8gcHJvbXB0IHRoZSB1c2VyIGZvciB0aGlzCisgICAgICogaW5mb3JtYXRpb24sIHRoZSBkaWFsb2cgbmVlZHMgdG8gYmxvY2sgdW50aWwgdGhlIHVzZXIgc3VwcGxpZXMgdGhlCisgICAgICogaW5mb3JtYXRpb24uICBUaGlzIG1ldGhvZCBjYW4gbm90IHNpbXBseSByZXR1cm4gYWZ0ZXIgc2hvd2luZyB0aGUKKyAgICAgKiBkaWFsb2cuCisgICAgICogQHJldHVybiBUaGUgUGFzc3dvcmRBdXRoZW50aWNhdGlvbiBjb2xsZWN0ZWQgZnJvbSB0aGUKKyAgICAgKgkJdXNlciwgb3IgbnVsbCBpZiBub25lIGlzIHByb3ZpZGVkLgorICAgICAqLworICAgIHByb3RlY3RlZCBQYXNzd29yZEF1dGhlbnRpY2F0aW9uIGdldFBhc3N3b3JkQXV0aGVudGljYXRpb24oKSB7CisJcmV0dXJuIG51bGw7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvQm9keVBhcnQuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL0JvZHlQYXJ0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmI5NGY3NQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL0JvZHlQYXJ0LmphdmEKQEAgLTAsMCArMSw2MCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsOworCisvKioKKyAqIFRoaXMgY2xhc3MgbW9kZWxzIGEgUGFydCB0aGF0IGlzIGNvbnRhaW5lZCB3aXRoaW4gYSBNdWx0aXBhcnQuCisgKiBUaGlzIGlzIGFuIGFic3RyYWN0IGNsYXNzLiBTdWJjbGFzc2VzIHByb3ZpZGUgYWN0dWFsIGltcGxlbWVudGF0aW9ucy48cD4KKyAqCisgKiBCb2R5UGFydCBpbXBsZW1lbnRzIHRoZSBQYXJ0IGludGVyZmFjZS4gVGh1cywgaXQgY29udGFpbnMgYSBzZXQgb2YKKyAqIGF0dHJpYnV0ZXMgYW5kIGEgImNvbnRlbnQiLgorICoKKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCisKK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBCb2R5UGFydCBpbXBsZW1lbnRzIFBhcnQgeworCisgICAgLyoqCisgICAgICogVGhlIDxjb2RlPk11bHRpcGFydDwvY29kZT4gb2JqZWN0IGNvbnRhaW5pbmcgdGhpcyA8Y29kZT5Cb2R5UGFydDwvY29kZT4sCisgICAgICogaWYga25vd24uCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuMQorICAgICAqLworICAgIHByb3RlY3RlZCBNdWx0aXBhcnQgcGFyZW50OworCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBjb250YWluaW5nIDxjb2RlPk11bHRpcGFydDwvY29kZT4gb2JqZWN0LAorICAgICAqIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIG5vdCBrbm93bi4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIHBhcmVudCBNdWx0aXBhcnQKKyAgICAgKi8KKyAgICBwdWJsaWMgTXVsdGlwYXJ0IGdldFBhcmVudCgpIHsKKwlyZXR1cm4gcGFyZW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgcGFyZW50IG9mIHRoaXMgPGNvZGU+Qm9keVBhcnQ8L2NvZGU+IHRvIGJlIHRoZSBzcGVjaWZpZWQKKyAgICAgKiA8Y29kZT5NdWx0aXBhcnQ8L2NvZGU+LiAgTm9ybWFsbHkgY2FsbGVkIGJ5IDxjb2RlPk11bHRpcGFydDwvY29kZT4ncworICAgICAqIDxjb2RlPmFkZEJvZHlQYXJ0PC9jb2RlPiBtZXRob2QuICA8Y29kZT5wYXJlbnQ8L2NvZGU+IG1heSBiZQorICAgICAqIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZSA8Y29kZT5Cb2R5UGFydDwvY29kZT4gaXMgYmVpbmcgcmVtb3ZlZAorICAgICAqIGZyb20gaXRzIGNvbnRhaW5pbmcgPGNvZGU+TXVsdGlwYXJ0PC9jb2RlPi4KKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS4xCisgICAgICovCisgICAgdm9pZCBzZXRQYXJlbnQoTXVsdGlwYXJ0IHBhcmVudCkgeworCXRoaXMucGFyZW50ID0gcGFyZW50OworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL0VuY29kaW5nQXdhcmUuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL0VuY29kaW5nQXdhcmUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yN2VmYzcwCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvRW5jb2RpbmdBd2FyZS5qYXZhCkBAIC0wLDAgKzEsNTUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbDsKKworLyoqCisgKiBBIHtAbGluayBqYXZheC5hY3RpdmF0aW9uLkRhdGFTb3VyY2UgRGF0YVNvdXJjZX0gdGhhdCBhbHNvIGltcGxlbWVudHMKKyAqIDxjb2RlPkVuY29kaW5nQXdhcmU8L2NvZGU+IG1heSBzcGVjaWZ5IHRoZSBDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nCisgKiB0byB1c2UgZm9yIGl0cyBkYXRhLiAgVmFsaWQgQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZyB2YWx1ZXMgc3BlY2lmaWVkCisgKiBieSBSRkMgMjA0NSBhcmUgIjdiaXQiLCAiOGJpdCIsICJxdW90ZWQtcHJpbnRhYmxlIiwgImJhc2U2NCIsIGFuZCAiYmluYXJ5Ii4KKyAqIDxwPgorICogRm9yIGV4YW1wbGUsIGEge0BsaW5rIGphdmF4LmFjdGl2YXRpb24uRmlsZURhdGFTb3VyY2UgRmlsZURhdGFTb3VyY2V9CisgKiBjb3VsZCBiZSBjcmVhdGVkIHRoYXQgZm9yY2VzIGFsbCBmaWxlcyB0byBiZSBiYXNlNjQgZW5jb2RlZDoKKyAqIDxibG9ja3F1b3RlPjxwcmU+CisgKiAgcHVibGljIGNsYXNzIEJhc2U2NEZpbGVEYXRhU291cmNlIGV4dGVuZHMgRmlsZURhdGFTb3VyY2UKKyAqCQkJCQlpbXBsZW1lbnRzIEVuY29kaW5nQXdhcmUgeworICoJcHVibGljIEJhc2U2NEZpbGVEYXRhU291cmNlKEZpbGUgZmlsZSkgeworICoJICAgIHN1cGVyKGZpbGUpOworICoJfQorICoKKyAqCS8vIGltcGxlbWVudHMgRW5jb2RpbmdBd2FyZS5nZXRFbmNvZGluZygpCisgKglwdWJsaWMgU3RyaW5nIGdldEVuY29kaW5nKCkgeworICoJICAgIHJldHVybiAiYmFzZTY0IjsKKyAqCX0KKyAqICB9CisgKiA8L3ByZT48L2Jsb2NrcXVvdGU+PHA+CisgKgorICogQHNpbmNlCUphdmFNYWlsIDEuNQorICogQGF1dGhvcglCaWxsIFNoYW5ub24KKyAqLworCitwdWJsaWMgaW50ZXJmYWNlIEVuY29kaW5nQXdhcmUgeworCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBNSU1FIENvbnRlbnQtVHJhbnNmZXItRW5jb2RpbmcgdG8gdXNlIGZvciB0aGlzIGRhdGEsCisgICAgICogb3IgbnVsbCB0byBpbmRpY2F0ZSB0aGF0IGFuIGFwcHJvcHJpYXRlIHZhbHVlIHNob3VsZCBiZSBjaG9zZW4KKyAgICAgKiBieSB0aGUgY2FsbGVyLgorICAgICAqCisgICAgICogQHJldHVybgkJdGhlIENvbnRlbnQtVHJhbnNmZXItRW5jb2RpbmcgdmFsdWUsIG9yIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEVuY29kaW5nKCk7Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9FdmVudFF1ZXVlLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9FdmVudFF1ZXVlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTI2NGViZAotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL0V2ZW50UXVldWUuamF2YQpAQCAtMCwwICsxLDE1OSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsOworCitpbXBvcnQgamF2YS51dGlsLkV2ZW50TGlzdGVuZXI7CitpbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKK2ltcG9ydCBqYXZhLnV0aWwuUXVldWU7CitpbXBvcnQgamF2YS51dGlsLldlYWtIYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkJsb2NraW5nUXVldWU7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuTGlua2VkQmxvY2tpbmdRdWV1ZTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRvcjsKK2ltcG9ydCBqYXZheC5tYWlsLmV2ZW50Lk1haWxFdmVudDsKKworLyoqCisgKiBQYWNrYWdlIHByaXZhdGUgY2xhc3MgdXNlZCBieSBTdG9yZSAmIEZvbGRlciB0byBkaXNwYXRjaCBldmVudHMuCisgKiBUaGlzIGNsYXNzIGltcGxlbWVudHMgYW4gZXZlbnQgcXVldWUsIGFuZCBhIGRpc3BhdGNoZXIgdGhyZWFkIHRoYXQKKyAqIGRlcXVldWVzIGFuZCBkaXNwYXRjaGVzIGV2ZW50cyBmcm9tIHRoZSBxdWV1ZS4KKyAqCisgKiBAYXV0aG9yCUJpbGwgU2hhbm5vbgorICovCitjbGFzcyBFdmVudFF1ZXVlIGltcGxlbWVudHMgUnVubmFibGUgeworCisgICAgcHJpdmF0ZSB2b2xhdGlsZSBCbG9ja2luZ1F1ZXVlPFF1ZXVlRWxlbWVudD4gcTsKKyAgICBwcml2YXRlIEV4ZWN1dG9yIGV4ZWN1dG9yOworCisgICAgcHJpdmF0ZSBzdGF0aWMgV2Vha0hhc2hNYXA8Q2xhc3NMb2FkZXIsRXZlbnRRdWV1ZT4gYXBwcTsKKworICAgIC8qKgorICAgICAqIEEgc3BlY2lhbCBldmVudCB0aGF0IGNhdXNlcyB0aGUgcXVldWUgcHJvY2Vzc2luZyB0YXNrIHRvIHRlcm1pbmF0ZS4KKyAgICAgKi8KKyAgICBzdGF0aWMgY2xhc3MgVGVybWluYXRvckV2ZW50IGV4dGVuZHMgTWFpbEV2ZW50IHsKKwlwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMjQ4MTg5NTAwMDg0MTY2NDExMUw7CisKKwlUZXJtaW5hdG9yRXZlbnQoKSB7CisJICAgIHN1cGVyKG5ldyBPYmplY3QoKSk7CisJfQorCisJQE92ZXJyaWRlCisJcHVibGljIHZvaWQgZGlzcGF0Y2goT2JqZWN0IGxpc3RlbmVyKSB7CisJICAgIC8vIEtpbGwgdGhlIGV2ZW50IGRpc3BhdGNoaW5nIHRocmVhZC4KKwkgICAgVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5pbnRlcnJ1cHQoKTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogQSAic3RydWN0IiB0byBwdXQgb24gdGhlIHF1ZXVlLgorICAgICAqLworICAgIHN0YXRpYyBjbGFzcyBRdWV1ZUVsZW1lbnQgeworCU1haWxFdmVudCBldmVudCA9IG51bGw7CisJVmVjdG9yPD8gZXh0ZW5kcyBFdmVudExpc3RlbmVyPiB2ZWN0b3IgPSBudWxsOworCisJUXVldWVFbGVtZW50KE1haWxFdmVudCBldmVudCwgVmVjdG9yPD8gZXh0ZW5kcyBFdmVudExpc3RlbmVyPiB2ZWN0b3IpIHsKKwkgICAgdGhpcy5ldmVudCA9IGV2ZW50OworCSAgICB0aGlzLnZlY3RvciA9IHZlY3RvcjsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGFuIEV2ZW50UXVldWUgdXNpbmcgdGhlIHNwZWNpZmllZCBFeGVjdXRvci4KKyAgICAgKiBJZiB0aGUgRXhlY3V0b3IgaXMgbnVsbCwgdGhyZWFkcyB3aWxsIGJlIGNyZWF0ZWQgYXMgbmVlZGVkLgorICAgICAqLworICAgIEV2ZW50UXVldWUoRXhlY3V0b3IgZXgpIHsKKwl0aGlzLmV4ZWN1dG9yID0gZXg7CisgICAgfQorCisgICAgLyoqCisgICAgICogRW5xdWV1ZSBhbiBldmVudC4KKyAgICAgKi8KKyAgICBzeW5jaHJvbml6ZWQgdm9pZCBlbnF1ZXVlKE1haWxFdmVudCBldmVudCwKKwkgICAgVmVjdG9yPD8gZXh0ZW5kcyBFdmVudExpc3RlbmVyPiB2ZWN0b3IpIHsKKwkvLyBpZiB0aGlzIGlzIHRoZSBmaXJzdCBldmVudCwgY3JlYXRlIHRoZSBxdWV1ZSBhbmQgc3RhcnQgdGhlIGV2ZW50IHRhc2sKKwlpZiAocSA9PSBudWxsKSB7CisJICAgIHEgPSBuZXcgTGlua2VkQmxvY2tpbmdRdWV1ZTw+KCk7CisJICAgIGlmIChleGVjdXRvciAhPSBudWxsKSB7CisJCWV4ZWN1dG9yLmV4ZWN1dGUodGhpcyk7CisJICAgIH0gZWxzZSB7CisJCVRocmVhZCBxVGhyZWFkID0gbmV3IFRocmVhZCh0aGlzLCAiSmF2YU1haWwtRXZlbnRRdWV1ZSIpOworCQlxVGhyZWFkLnNldERhZW1vbih0cnVlKTsgIC8vIG5vdCBhIHVzZXIgdGhyZWFkCisJCXFUaHJlYWQuc3RhcnQoKTsKKwkgICAgfQorCX0KKwlxLmFkZChuZXcgUXVldWVFbGVtZW50KGV2ZW50LCB2ZWN0b3IpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXJtaW5hdGUgdGhlIHRhc2sgcnVubmluZyB0aGUgcXVldWUsIGJ1dCBvbmx5IGlmIHRoZXJlIGlzIGEgcXVldWUuCisgICAgICovCisgICAgc3luY2hyb25pemVkIHZvaWQgdGVybWluYXRlUXVldWUoKSB7CisJaWYgKHEgIT0gbnVsbCkgeworCSAgICBWZWN0b3I8RXZlbnRMaXN0ZW5lcj4gZHVtbXlMaXN0ZW5lcnMgPSBuZXcgVmVjdG9yPD4oKTsKKwkgICAgZHVtbXlMaXN0ZW5lcnMuc2V0U2l6ZSgxKTsgLy8gbmVlZCBhdGxlYXN0IG9uZSBsaXN0ZW5lcgorCSAgICBxLmFkZChuZXcgUXVldWVFbGVtZW50KG5ldyBUZXJtaW5hdG9yRXZlbnQoKSwgZHVtbXlMaXN0ZW5lcnMpKTsKKwkgICAgcSA9IG51bGw7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSAoaWYgbmVjZXNzYXJ5KSBhbiBhcHBsaWNhdGlvbi1zY29wZWQgZXZlbnQgcXVldWUuCisgICAgICogQXBwbGljYXRpb24gc2NvcGluZyBpcyBiYXNlZCBvbiB0aGUgdGhyZWFkJ3MgY29udGV4dCBjbGFzcyBsb2FkZXIuCisgICAgICovCisgICAgc3RhdGljIHN5bmNocm9uaXplZCBFdmVudFF1ZXVlIGdldEFwcGxpY2F0aW9uRXZlbnRRdWV1ZShFeGVjdXRvciBleCkgeworCUNsYXNzTG9hZGVyIGNsID0gU2Vzc2lvbi5nZXRDb250ZXh0Q2xhc3NMb2FkZXIoKTsKKwlpZiAoYXBwcSA9PSBudWxsKQorCSAgICBhcHBxID0gbmV3IFdlYWtIYXNoTWFwPD4oKTsKKwlFdmVudFF1ZXVlIHEgPSBhcHBxLmdldChjbCk7CisJaWYgKHEgPT0gbnVsbCkgeworCSAgICBxID0gbmV3IEV2ZW50UXVldWUoZXgpOworCSAgICBhcHBxLnB1dChjbCwgcSk7CisJfQorCXJldHVybiBxOworICAgIH0KKworICAgIC8qKgorICAgICAqIFB1bGwgZXZlbnRzIG9mZiB0aGUgcXVldWUgYW5kIGRpc3BhdGNoIHRoZW0uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcnVuKCkgeworCisJQmxvY2tpbmdRdWV1ZTxRdWV1ZUVsZW1lbnQ+IGJxID0gcTsKKwlpZiAoYnEgPT0gbnVsbCkKKwkgICAgcmV0dXJuOworCXRyeSB7CisJICAgIGxvb3A6CisJICAgIGZvciAoOzspIHsKKwkJLy8gYmxvY2sgdW50aWwgYW4gaXRlbSBpcyBhdmFpbGFibGUKKwkJUXVldWVFbGVtZW50IHFlID0gYnEudGFrZSgpOworCQlNYWlsRXZlbnQgZSA9IHFlLmV2ZW50OworCQlWZWN0b3I8PyBleHRlbmRzIEV2ZW50TGlzdGVuZXI+IHYgPSBxZS52ZWN0b3I7CisKKwkJZm9yIChpbnQgaSA9IDA7IGkgPCB2LnNpemUoKTsgaSsrKQorCQkgICAgdHJ5IHsKKwkJCWUuZGlzcGF0Y2godi5lbGVtZW50QXQoaSkpOworCQkgICAgfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKKwkJCWlmICh0IGluc3RhbmNlb2YgSW50ZXJydXB0ZWRFeGNlcHRpb24pCisJCQkgICAgYnJlYWsgbG9vcDsKKwkJCS8vIGlnbm9yZSBhbnl0aGluZyBlbHNlIHRocm93biBieSB0aGUgbGlzdGVuZXIKKwkJICAgIH0KKworCQlxZSA9IG51bGw7IGUgPSBudWxsOyB2ID0gbnVsbDsKKwkgICAgfQorCX0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKwkgICAgLy8ganVzdCBkaWUKKwl9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvRmV0Y2hQcm9maWxlLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9GZXRjaFByb2ZpbGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xYjQ5NDU0Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvRmV0Y2hQcm9maWxlLmphdmEKQEAgLTAsMCArMSwyMjMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbDsKKworaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7CisKKy8qKgorICogQ2xpZW50cyB1c2UgYSBGZXRjaFByb2ZpbGUgdG8gbGlzdCB0aGUgTWVzc2FnZSBhdHRyaWJ1dGVzIHRoYXQgCisgKiBpdCB3aXNoZXMgdG8gcHJlZmV0Y2ggZnJvbSB0aGUgc2VydmVyIGZvciBhIHJhbmdlIG9mIG1lc3NhZ2VzLjxwPgorICoKKyAqIE1lc3NhZ2VzIG9idGFpbmVkIGZyb20gYSBGb2xkZXIgYXJlIGxpZ2h0LXdlaWdodCBvYmplY3RzIHRoYXQgCisgKiB0eXBpY2FsbHkgc3RhcnQgb2ZmIGFzIGVtcHR5IHJlZmVyZW5jZXMgdG8gdGhlIGFjdHVhbCBtZXNzYWdlcy4KKyAqIFN1Y2ggYSBNZXNzYWdlIG9iamVjdCBpcyBmaWxsZWQgaW4gIm9uLWRlbWFuZCIgd2hlbiB0aGUgYXBwcm9wcmlhdGUgCisgKiBnZXQqKCkgbWV0aG9kcyBhcmUgaW52b2tlZCBvbiB0aGF0IHBhcnRpY3VsYXIgTWVzc2FnZS4gQ2VydGFpbgorICogc2VydmVyLWJhc2VkIG1lc3NhZ2UgYWNjZXNzIHByb3RvY29scyAoRXg6IElNQVApIGFsbG93IGJhdGNoCisgKiBmZXRjaGluZyBvZiBtZXNzYWdlIGF0dHJpYnV0ZXMgZm9yIGEgcmFuZ2Ugb2YgbWVzc2FnZXMgaW4gYSBzaW5nbGUKKyAqIHJlcXVlc3QuIENsaWVudHMgdGhhdCB3YW50IHRvIHVzZSBtZXNzYWdlIGF0dHJpYnV0ZXMgZm9yIGEgcmFuZ2Ugb2YKKyAqIE1lc3NhZ2VzIChFeGFtcGxlOiB0byBkaXNwbGF5IHRoZSB0b3AtbGV2ZWwgaGVhZGVycyBpbiBhIGhlYWRlcmxpc3QpCisgKiBtaWdodCB3YW50IHRvIHVzZSB0aGUgb3B0aW1pemF0aW9uIHByb3ZpZGVkIGJ5IHN1Y2ggc2VydmVycy4gVGhlCisgKiA8Y29kZT5GZXRjaFByb2ZpbGU8L2NvZGU+IGFsbG93cyB0aGUgY2xpZW50IHRvIGluZGljYXRlIHRoaXMgZGVzaXJlCisgKiB0byB0aGUgc2VydmVyLiA8cD4KKyAqCisgKiBOb3RlIHRoYXQgaW1wbGVtZW50YXRpb25zIGFyZSBub3Qgb2JsaWdhdGVkIHRvIHN1cHBvcnQKKyAqIEZldGNoUHJvZmlsZXMsIHNpbmNlIHRoZXJlIG1pZ2h0IGJlIGNhc2VzIHdoZXJlIHRoZSBiYWNrZW5kIHNlcnZpY2UgCisgKiBkb2VzIG5vdCBhbGxvdyBlYXN5LCBlZmZpY2llbnQgZmV0Y2hpbmcgb2Ygc3VjaCBwcm9maWxlcy4gPHA+CisgKgorICogU2FtcGxlIGNvZGUgdGhhdCBpbGx1c3RyYXRlcyB0aGUgdXNlIG9mIGEgRmV0Y2hQcm9maWxlIGlzIGdpdmVuCisgKiBiZWxvdzoKKyAqIDxibG9ja3F1b3RlPgorICogPHByZT4KKyAqCisgKiAgTWVzc2FnZVtdIG1zZ3MgPSBmb2xkZXIuZ2V0TWVzc2FnZXMoKTsKKyAqCisgKiAgRmV0Y2hQcm9maWxlIGZwID0gbmV3IEZldGNoUHJvZmlsZSgpOworICogIGZwLmFkZChGZXRjaFByb2ZpbGUuSXRlbS5FTlZFTE9QRSk7CisgKiAgZnAuYWRkKCJYLW1haWxlciIpOworICogIGZvbGRlci5mZXRjaChtc2dzLCBmcCk7CisgKgorICogPC9wcmU+PC9ibG9ja3F1b3RlPjxwPgorICoKKyAqIEBzZWUgamF2YXgubWFpbC5Gb2xkZXIjZmV0Y2gKKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCisKK3B1YmxpYyBjbGFzcyBGZXRjaFByb2ZpbGUgeworCisgICAgcHJpdmF0ZSBWZWN0b3I8SXRlbT4gc3BlY2lhbHM7IC8vIHNwZWNpYWxzCisgICAgcHJpdmF0ZSBWZWN0b3I8U3RyaW5nPiBoZWFkZXJzOyAvLyB2ZWN0b3Igb2YgaGVhZGVyIG5hbWVzCisKKyAgICAvKioKKyAgICAgKiBUaGlzIGlubmVyIGNsYXNzIGlzIHRoZSBiYXNlIGNsYXNzIG9mIGFsbCBpdGVtcyB0aGF0CisgICAgICogY2FuIGJlIHJlcXVlc3RlZCBpbiBhIEZldGNoUHJvZmlsZS4gVGhlIGl0ZW1zIGN1cnJlbnRseQorICAgICAqIGRlZmluZWQgaGVyZSBhcmUgPGNvZGU+RU5WRUxPUEU8L2NvZGU+LCA8Y29kZT5DT05URU5UX0lORk88L2NvZGU+CisgICAgICogYW5kIDxjb2RlPkZMQUdTPC9jb2RlPi4gVGhlIDxjb2RlPlVJREZvbGRlcjwvY29kZT4gaW50ZXJmYWNlIAorICAgICAqIGRlZmluZXMgdGhlIDxjb2RlPlVJRDwvY29kZT4gSXRlbSBhcyB3ZWxsLiA8cD4KKyAgICAgKgorICAgICAqIE5vdGUgdGhhdCB0aGlzIGNsYXNzIG9ubHkgaGFzIGEgcHJvdGVjdGVkIGNvbnN0cnVjdG9yLCB0aGVyYnkKKyAgICAgKiByZXN0cmljdGluZyBuZXcgSXRlbSB0eXBlcyB0byBlaXRoZXIgdGhpcyBjbGFzcyBvciBzdWJjbGFzc2VzLgorICAgICAqIFRoaXMgZWZmZWN0aXZlbHkgaW1wbGVtZW50cyBhIGVudW1lcmF0aW9uIG9mIGFsbG93ZWQgSXRlbSB0eXBlcy4KKyAgICAgKgorICAgICAqIEBzZWUgVUlERm9sZGVyCisgICAgICovCisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEl0ZW0geworCS8qKgorCSAqIFRoaXMgaXMgdGhlIEVudmVsb3BlIGl0ZW0uIDxwPgorCSAqCisJICogVGhlIEVudmVsb3BlIGlzIGFuIGFnZ3JlZ3JhdGlvbiBvZiB0aGUgY29tbW9uIGF0dHJpYnV0ZXMKKwkgKiBvZiBhIE1lc3NhZ2UuIEltcGxlbWVudGF0aW9ucyBzaG91bGQgaW5jbHVkZSB0aGUgZm9sbG93aW5nCisJICogYXR0cmlidXRlczogRnJvbSwgVG8sIENjLCBCY2MsIFJlcGx5VG8sIFN1YmplY3QgYW5kIERhdGUuCisJICogTW9yZSBpdGVtcyBtYXkgYmUgaW5jbHVkZWQgYXMgd2VsbC4gPHA+CisJICoKKwkgKiBGb3IgaW1wbGVtZW50YXRpb25zIG9mIHRoZSBJTUFQNCBwcm90b2NvbCAoUkZDIDIwNjApLCB0aGUgCisJICogRW52ZWxvcGUgc2hvdWxkIGluY2x1ZGUgdGhlIEVOVkVMT1BFIGRhdGEgaXRlbS4gTW9yZSBpdGVtcworCSAqIG1heSBiZSBpbmNsdWRlZCB0b28uCisJICovCisJcHVibGljIHN0YXRpYyBmaW5hbCBJdGVtIEVOVkVMT1BFID0gbmV3IEl0ZW0oIkVOVkVMT1BFIik7CisKKwkvKioKKwkgKiBUaGlzIGl0ZW0gaXMgZm9yIGZldGNoaW5nIGluZm9ybWF0aW9uIGFib3V0IHRoZSAKKwkgKiBjb250ZW50IG9mIHRoZSBtZXNzYWdlLiA8cD4KKwkgKgorCSAqIFRoaXMgaW5jbHVkZXMgYWxsIHRoZSBhdHRyaWJ1dGVzIHRoYXQgZGVzY3JpYmUgdGhlIGNvbnRlbnQKKwkgKiBvZiB0aGUgbWVzc2FnZS4gSW1wbGVtZW50YXRpb25zIHNob3VsZCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcKKwkgKiBhdHRyaWJ1dGVzOiBDb250ZW50VHlwZSwgQ29udGVudERpc3Bvc2l0aW9uLCAKKwkgKiBDb250ZW50RGVzY3JpcHRpb24sIFNpemUgYW5kIExpbmVDb3VudC4gT3RoZXIgaXRlbXMgbWF5IGJlCisJICogaW5jbHVkZWQgYXMgd2VsbC4KKwkgKi8KKwlwdWJsaWMgc3RhdGljIGZpbmFsIEl0ZW0gQ09OVEVOVF9JTkZPID0gbmV3IEl0ZW0oIkNPTlRFTlRfSU5GTyIpOworCisJLyoqCisJICogU0laRSBpcyBhIGZldGNoIHByb2ZpbGUgaXRlbSB0aGF0IGNhbiBiZSBpbmNsdWRlZCBpbiBhCisJICogPGNvZGU+RmV0Y2hQcm9maWxlPC9jb2RlPiBkdXJpbmcgYSBmZXRjaCByZXF1ZXN0IHRvIGEgRm9sZGVyLgorCSAqIFRoaXMgaXRlbSBpbmRpY2F0ZXMgdGhhdCB0aGUgc2l6ZXMgb2YgdGhlIG1lc3NhZ2VzIGluIHRoZSBzcGVjaWZpZWQgCisJICogcmFuZ2Ugc2hvdWxkIGJlIHByZWZldGNoZWQuIDxwPgorCSAqCisJICogQHNpbmNlCUphdmFNYWlsIDEuNQorCSAqLworCXB1YmxpYyBzdGF0aWMgZmluYWwgSXRlbSBTSVpFID0gbmV3IEl0ZW0oIlNJWkUiKTsKKworCS8qKgorCSAqIFRoaXMgaXMgdGhlIEZsYWdzIGl0ZW0uCisJICovCisJcHVibGljIHN0YXRpYyBmaW5hbCBJdGVtIEZMQUdTID0gbmV3IEl0ZW0oIkZMQUdTIik7CisKKwlwcml2YXRlIFN0cmluZyBuYW1lOworCisJLyoqCisJICogQ29uc3RydWN0b3IgZm9yIGFuIGl0ZW0uICBUaGUgbmFtZSBpcyB1c2VkIG9ubHkgZm9yIGRlYnVnZ2luZy4KKwkgKgorCSAqIEBwYXJhbQluYW1lCXRoZSBpdGVtIG5hbWUKKwkgKi8KKwlwcm90ZWN0ZWQgSXRlbShTdHJpbmcgbmFtZSkgeworCSAgICB0aGlzLm5hbWUgPSBuYW1lOworCX0KKworCS8qKgorCSAqIEluY2x1ZGUgdGhlIG5hbWUgaW4gdGhlIHRvU3RyaW5nIHJldHVybiB2YWx1ZSBmb3IgZGVidWdnaW5nLgorCSAqLworCUBPdmVycmlkZQorCXB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisJICAgIHJldHVybiBnZXRDbGFzcygpLmdldE5hbWUoKSArICJbIiArIG5hbWUgKyAiXSI7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhbiBlbXB0eSBGZXRjaFByb2ZpbGUuCisgICAgICovCisgICAgcHVibGljIEZldGNoUHJvZmlsZSgpIHsgCisJc3BlY2lhbHMgPSBudWxsOworCWhlYWRlcnMgPSBudWxsOworICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiBBZGQgdGhlIGdpdmVuIHNwZWNpYWwgaXRlbSBhcyBvbmUgb2YgdGhlIGF0dHJpYnV0ZXMgdG8KKyAgICAgKiBiZSBwcmVmZXRjaGVkLgorICAgICAqCisgICAgICogQHBhcmFtCWl0ZW0JCXRoZSBzcGVjaWFsIGl0ZW0gdG8gYmUgZmV0Y2hlZAorICAgICAqIEBzZWUJRmV0Y2hQcm9maWxlLkl0ZW0jRU5WRUxPUEUKKyAgICAgKiBAc2VlCUZldGNoUHJvZmlsZS5JdGVtI0NPTlRFTlRfSU5GTworICAgICAqIEBzZWUJRmV0Y2hQcm9maWxlLkl0ZW0jRkxBR1MKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGQoSXRlbSBpdGVtKSB7IAorCWlmIChzcGVjaWFscyA9PSBudWxsKQorCSAgICBzcGVjaWFscyA9IG5ldyBWZWN0b3I8PigpOworCXNwZWNpYWxzLmFkZEVsZW1lbnQoaXRlbSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkIHRoZSBzcGVjaWZpZWQgaGVhZGVyLWZpZWxkIHRvIHRoZSBsaXN0IG9mIGF0dHJpYnV0ZXMKKyAgICAgKiB0byBiZSBwcmVmZXRjaGVkLgorICAgICAqCisgICAgICogQHBhcmFtCWhlYWRlck5hbWUJaGVhZGVyIHRvIGJlIHByZWZldGNoZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGQoU3RyaW5nIGhlYWRlck5hbWUpIHsgCisgICAJaWYgKGhlYWRlcnMgPT0gbnVsbCkKKwkgICAgaGVhZGVycyA9IG5ldyBWZWN0b3I8PigpOworCWhlYWRlcnMuYWRkRWxlbWVudChoZWFkZXJOYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGZldGNoIHByb2ZpbGUgY29udGFpbnMgdGhlIGdpdmVuIHNwZWNpYWwgaXRlbS4KKyAgICAgKgorICAgICAqIEBwYXJhbQlpdGVtCXRoZSBJdGVtIHRvIHRlc3QKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGZldGNoIHByb2ZpbGUgY29udGFpbnMgdGhlIGdpdmVuIHNwZWNpYWwgaXRlbQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKEl0ZW0gaXRlbSkgeyAKKyAgIAlyZXR1cm4gc3BlY2lhbHMgIT0gbnVsbCAmJiBzcGVjaWFscy5jb250YWlucyhpdGVtKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGZldGNoIHByb2ZpbGUgY29udGFpbnMgdGhlIGdpdmVuIGhlYWRlciBuYW1lLgorICAgICAqCisgICAgICogQHBhcmFtCWhlYWRlck5hbWUJdGhlIGhlYWRlciB0byB0ZXN0CisgICAgICogQHJldHVybgl0cnVlIGlmIHRoZSBmZXRjaCBwcm9maWxlIGNvbnRhaW5zIHRoZSBnaXZlbiBoZWFkZXIgbmFtZQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKFN0cmluZyBoZWFkZXJOYW1lKSB7IAorICAgCXJldHVybiBoZWFkZXJzICE9IG51bGwgJiYgaGVhZGVycy5jb250YWlucyhoZWFkZXJOYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGl0ZW1zIHNldCBpbiB0aGlzIHByb2ZpbGUuIAorICAgICAqCisgICAgICogQHJldHVybgkJaXRlbXMgc2V0IGluIHRoaXMgcHJvZmlsZQorICAgICAqLworICAgIHB1YmxpYyBJdGVtW10gZ2V0SXRlbXMoKSB7IAorCWlmIChzcGVjaWFscyA9PSBudWxsKQorCSAgICByZXR1cm4gbmV3IEl0ZW1bMF07CisKKyAgIAlJdGVtW10gcyA9IG5ldyBJdGVtW3NwZWNpYWxzLnNpemUoKV07CisJc3BlY2lhbHMuY29weUludG8ocyk7CisJcmV0dXJuIHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBuYW1lcyBvZiB0aGUgaGVhZGVyLWZpZWxkcyBzZXQgaW4gdGhpcyBwcm9maWxlLiAKKyAgICAgKgorICAgICAqIEByZXR1cm4JCWhlYWRlcnMgc2V0IGluIHRoaXMgcHJvZmlsZQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRIZWFkZXJOYW1lcygpIHsgCisJaWYgKGhlYWRlcnMgPT0gbnVsbCkKKwkgICAgcmV0dXJuIG5ldyBTdHJpbmdbMF07CisKKyAgIAlTdHJpbmdbXSBzID0gbmV3IFN0cmluZ1toZWFkZXJzLnNpemUoKV07CisJaGVhZGVycy5jb3B5SW50byhzKTsKKwlyZXR1cm4gczsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9GbGFncy5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvRmxhZ3MuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mOTdjYWQzCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvRmxhZ3MuamF2YQpAQCAtMCwwICsxLDY2NyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsOworCitpbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CitpbXBvcnQgamF2YS51dGlsLio7CisKKy8qKgorICogVGhlIEZsYWdzIGNsYXNzIHJlcHJlc2VudHMgdGhlIHNldCBvZiBmbGFncyBvbiBhIE1lc3NhZ2UuICBGbGFncworICogYXJlIGNvbXBvc2VkIG9mIHByZWRlZmluZWQgc3lzdGVtIGZsYWdzLCBhbmQgdXNlciBkZWZpbmVkIGZsYWdzLiA8cD4KKyAqCisgKiBBIFN5c3RlbSBmbGFnIGlzIHJlcHJlc2VudGVkIGJ5IHRoZSA8Y29kZT5GbGFncy5GbGFnPC9jb2RlPiAKKyAqIGlubmVyIGNsYXNzLiBBIFVzZXIgZGVmaW5lZCBmbGFnIGlzIHJlcHJlc2VudGVkIGFzIGEgU3RyaW5nLgorICogVXNlciBmbGFncyBhcmUgY2FzZS1pbmRlcGVuZGVudC4gPHA+CisgKgorICogQSBzZXQgb2Ygc3RhbmRhcmQgc3lzdGVtIGZsYWdzIGFyZSBwcmVkZWZpbmVkLiAgTW9zdCBmb2xkZXIKKyAqIGltcGxlbWVudGF0aW9ucyBhcmUgZXhwZWN0ZWQgdG8gc3VwcG9ydCB0aGVzZSBmbGFncy4gIFNvbWUKKyAqIGltcGxlbWVudGF0aW9ucyBtYXkgYWxzbyBzdXBwb3J0IGFyYml0cmFyeSB1c2VyLWRlZmluZWQgZmxhZ3MuICBUaGUKKyAqIDxjb2RlPmdldFBlcm1hbmVudEZsYWdzPC9jb2RlPiBtZXRob2Qgb24gYSBGb2xkZXIgcmV0dXJucyBhIEZsYWdzCisgKiBvYmplY3QgdGhhdCBob2xkcyBhbGwgdGhlIGZsYWdzIHRoYXQgYXJlIHN1cHBvcnRlZCBieSB0aGF0IGZvbGRlcgorICogaW1wbGVtZW50YXRpb24uIDxwPgorICoKKyAqIEEgRmxhZ3Mgb2JqZWN0IGlzIHNlcmlhbGl6YWJsZSBzbyB0aGF0IChmb3IgZXhhbXBsZSkgdGhlCisgKiB1c2Ugb2YgRmxhZ3Mgb2JqZWN0cyBpbiBzZWFyY2ggdGVybXMgY2FuIGJlIHNlcmlhbGl6ZWQKKyAqIGFsb25nIHdpdGggdGhlIHNlYXJjaCB0ZXJtcy4gPHA+CisgKgorICogPHN0cm9uZz5XYXJuaW5nOjwvc3Ryb25nPgorICogU2VyaWFsaXplZCBvYmplY3RzIG9mIHRoaXMgY2xhc3MgbWF5IG5vdCBiZSBjb21wYXRpYmxlIHdpdGggZnV0dXJlCisgKiBKYXZhTWFpbCBBUEkgcmVsZWFzZXMuICBUaGUgY3VycmVudCBzZXJpYWxpemF0aW9uIHN1cHBvcnQgaXMKKyAqIGFwcHJvcHJpYXRlIGZvciBzaG9ydCB0ZXJtIHN0b3JhZ2UuIDxwPgorICoKKyAqIFRoZSBiZWxvdyBjb2RlIHNhbXBsZSBpbGx1c3RyYXRlcyBob3cgdG8gc2V0LCBleGFtaW5lLCBhbmQgZ2V0IHRoZSAKKyAqIGZsYWdzIGZvciBhIG1lc3NhZ2UuCisgKiA8cHJlPgorICoKKyAqIE1lc3NhZ2UgbSA9IGZvbGRlci5nZXRNZXNzYWdlKDEpOworICogbS5zZXRGbGFnKEZsYWdzLkZsYWcuREVMRVRFRCwgdHJ1ZSk7IC8vIHNldCB0aGUgREVMRVRFRCBmbGFnCisgKgorICogLy8gQ2hlY2sgaWYgREVMRVRFRCBmbGFnIGlzIHNldCBvbiB0aGlzIG1lc3NhZ2UKKyAqIGlmIChtLmlzU2V0KEZsYWdzLkZsYWcuREVMRVRFRCkpCisgKglTeXN0ZW0ub3V0LnByaW50bG4oIkRFTEVURUQgbWVzc2FnZSIpOworICoKKyAqIC8vIEV4YW1pbmUgQUxMIHN5c3RlbSBmbGFncyBmb3IgdGhpcyBtZXNzYWdlCisgKiBGbGFncyBmbGFncyA9IG0uZ2V0RmxhZ3MoKTsKKyAqIEZsYWdzLkZsYWdbXSBzZiA9IGZsYWdzLmdldFN5c3RlbUZsYWdzKCk7CisgKiBmb3IgKGludCBpID0gMDsgaSAmbHQ7IHNmLmxlbmd0aDsgaSsrKSB7CisgKglpZiAoc2ZbaV0gPT0gRmxhZ3MuRmxhZy5ERUxFVEVEKQorICogICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkRFTEVURUQgbWVzc2FnZSIpOworICoJZWxzZSBpZiAoc2ZbaV0gPT0gRmxhZ3MuRmxhZy5TRUVOKQorICogICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlNFRU4gbWVzc2FnZSIpOworICogICAgICAuLi4uLi4KKyAqICAgICAgLi4uLi4uCisgKiB9CisgKiA8L3ByZT4KKyAqIDxwPgorICoKKyAqIEBzZWUgICAgRm9sZGVyI2dldFBlcm1hbmVudEZsYWdzCisgKiBAYXV0aG9yIEpvaG4gTWFuaQorICogQGF1dGhvciBCaWxsIFNoYW5ub24KKyAqLworCitwdWJsaWMgY2xhc3MgRmxhZ3MgaW1wbGVtZW50cyBDbG9uZWFibGUsIFNlcmlhbGl6YWJsZSB7CisKKyAgICBwcml2YXRlIGludCBzeXN0ZW1fZmxhZ3MgPSAwOworICAgIC8vIHVzZWQgYXMgYSBjYXNlLWluZGVwZW5kZW50IFNldCB0aGF0IHByZXNlcnZlcyB0aGUgb3JpZ2luYWwgY2FzZSwKKyAgICAvLyB0aGUga2V5IGlzIHRoZSBsb3dlcmNhc2UgZmxhZyBuYW1lIGFuZCB0aGUgdmFsdWUgaXMgdGhlIG9yaWdpbmFsCisgICAgcHJpdmF0ZSBIYXNodGFibGU8U3RyaW5nLCBTdHJpbmc+IHVzZXJfZmxhZ3MgPSBudWxsOworCisgICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgaW50IEFOU1dFUkVEX0JJVCAJPSAweDAxOworICAgIHByaXZhdGUgZmluYWwgc3RhdGljIGludCBERUxFVEVEX0JJVCAJPSAweDAyOworICAgIHByaXZhdGUgZmluYWwgc3RhdGljIGludCBEUkFGVF9CSVQgCQk9IDB4MDQ7CisgICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgaW50IEZMQUdHRURfQklUIAk9IDB4MDg7CisgICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgaW50IFJFQ0VOVF9CSVQJCT0gMHgxMDsKKyAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBpbnQgU0VFTl9CSVQJCT0gMHgyMDsKKyAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBpbnQgVVNFUl9CSVQJCT0gMHg4MDAwMDAwMDsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDYyNDM1OTA0MDcyMTQxNjkwMjhMOworCisgICAgLyoqCisgICAgICogVGhpcyBpbm5lciBjbGFzcyByZXByZXNlbnRzIGFuIGluZGl2aWR1YWwgc3lzdGVtIGZsYWcuIEEgc2V0CisgICAgICogb2Ygc3RhbmRhcmQgc3lzdGVtIGZsYWcgb2JqZWN0cyBhcmUgcHJlZGVmaW5lZCBoZXJlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgRmxhZyB7CisJLyoqCisJICogVGhpcyBtZXNzYWdlIGhhcyBiZWVuIGFuc3dlcmVkLiBUaGlzIGZsYWcgaXMgc2V0IGJ5IGNsaWVudHMgCisJICogdG8gaW5kaWNhdGUgdGhhdCB0aGlzIG1lc3NhZ2UgaGFzIGJlZW4gYW5zd2VyZWQgdG8uCisJICovCisJcHVibGljIHN0YXRpYyBmaW5hbCBGbGFnIEFOU1dFUkVEID0gbmV3IEZsYWcoQU5TV0VSRURfQklUKTsKKworCS8qKgorCSAqIFRoaXMgbWVzc2FnZSBpcyBtYXJrZWQgZGVsZXRlZC4gQ2xpZW50cyBzZXQgdGhpcyBmbGFnIHRvCisJICogbWFyayBhIG1lc3NhZ2UgYXMgZGVsZXRlZC4gVGhlIGV4cHVuZ2Ugb3BlcmF0aW9uIG9uIGEgZm9sZGVyCisJICogcmVtb3ZlcyBhbGwgbWVzc2FnZXMgaW4gdGhhdCBmb2xkZXIgdGhhdCBhcmUgbWFya2VkIGZvciBkZWxldGlvbi4KKwkgKi8KKwlwdWJsaWMgc3RhdGljIGZpbmFsIEZsYWcgREVMRVRFRCA9IG5ldyBGbGFnKERFTEVURURfQklUKTsKKworCS8qKgorCSAqIFRoaXMgbWVzc2FnZSBpcyBhIGRyYWZ0LiBUaGlzIGZsYWcgaXMgc2V0IGJ5IGNsaWVudHMKKwkgKiB0byBpbmRpY2F0ZSB0aGF0IHRoZSBtZXNzYWdlIGlzIGEgZHJhZnQgbWVzc2FnZS4KKwkgKi8KKwlwdWJsaWMgc3RhdGljIGZpbmFsIEZsYWcgRFJBRlQgPSBuZXcgRmxhZyhEUkFGVF9CSVQpOworCisJLyoqCisJICogVGhpcyBtZXNzYWdlIGlzIGZsYWdnZWQuIE5vIHNlbWFudGljIGlzIGRlZmluZWQgZm9yIHRoaXMgZmxhZy4KKwkgKiBDbGllbnRzIGFsdGVyIHRoaXMgZmxhZy4KKwkgKi8KKwlwdWJsaWMgc3RhdGljIGZpbmFsIEZsYWcgRkxBR0dFRCA9IG5ldyBGbGFnKEZMQUdHRURfQklUKTsKKworCS8qKgorCSAqIFRoaXMgbWVzc2FnZSBpcyByZWNlbnQuIEZvbGRlciBpbXBsZW1lbnRhdGlvbnMgc2V0IHRoaXMgZmxhZworCSAqIHRvIGluZGljYXRlIHRoYXQgdGhpcyBtZXNzYWdlIGlzIG5ldyB0byB0aGlzIGZvbGRlciwgdGhhdCBpcywKKwkgKiBpdCBoYXMgYXJyaXZlZCBzaW5jZSB0aGUgbGFzdCB0aW1lIHRoaXMgZm9sZGVyIHdhcyBvcGVuZWQuIDxwPgorCSAqCisJICogQ2xpZW50cyBjYW5ub3QgYWx0ZXIgdGhpcyBmbGFnLgorCSAqLworCXB1YmxpYyBzdGF0aWMgZmluYWwgRmxhZyBSRUNFTlQgPSBuZXcgRmxhZyhSRUNFTlRfQklUKTsKKworCS8qKgorCSAqIFRoaXMgbWVzc2FnZSBpcyBzZWVuLiBUaGlzIGZsYWcgaXMgaW1wbGljaXRseSBzZXQgYnkgdGhlIAorCSAqIGltcGxlbWVudGF0aW9uIHdoZW4gdGhpcyBNZXNzYWdlJ3MgY29udGVudCBpcyByZXR1cm5lZCAKKwkgKiB0byB0aGUgY2xpZW50IGluIHNvbWUgZm9ybS4gVGhlIDxjb2RlPmdldElucHV0U3RyZWFtPC9jb2RlPgorCSAqIGFuZCA8Y29kZT5nZXRDb250ZW50PC9jb2RlPiBtZXRob2RzIG9uIE1lc3NhZ2UgY2F1c2UgdGhpcworCSAqIGZsYWcgdG8gYmUgc2V0LiA8cD4KKwkgKgorCSAqIENsaWVudHMgY2FuIGFsdGVyIHRoaXMgZmxhZy4KKwkgKi8KKwlwdWJsaWMgc3RhdGljIGZpbmFsIEZsYWcgU0VFTiA9IG5ldyBGbGFnKFNFRU5fQklUKTsKKworCS8qKgorCSAqIEEgc3BlY2lhbCBmbGFnIHRoYXQgaW5kaWNhdGVzIHRoYXQgdGhpcyBmb2xkZXIgc3VwcG9ydHMKKwkgKiB1c2VyIGRlZmluZWQgZmxhZ3MuIDxwPgorCSAqCisJICogVGhlIGltcGxlbWVudGF0aW9uIHNldHMgdGhpcyBmbGFnLiBDbGllbnRzIGNhbm5vdCBhbHRlciAKKwkgKiB0aGlzIGZsYWcgYnV0IGNhbiB1c2UgaXQgdG8gZGV0ZXJtaW5lIGlmIGEgZm9sZGVyIHN1cHBvcnRzCisJICogdXNlciBkZWZpbmVkIGZsYWdzIGJ5IHVzaW5nCisJICogPGNvZGU+Zm9sZGVyLmdldFBlcm1hbmVudEZsYWdzKCkuY29udGFpbnMoRmxhZ3MuRmxhZy5VU0VSKTwvY29kZT4uCisJICovCisJcHVibGljIHN0YXRpYyBmaW5hbCBGbGFnIFVTRVIgPSBuZXcgRmxhZyhVU0VSX0JJVCk7CisKKwkvLyBmbGFncyBhcmUgc3RvcmVkIGFzIGJpdHMgZm9yIGVmZmljaWVuY3kKKwlwcml2YXRlIGludCBiaXQ7CisJcHJpdmF0ZSBGbGFnKGludCBiaXQpIHsKKwkgICAgdGhpcy5iaXQgPSBiaXQ7CisJfQorICAgIH0KKworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGFuIGVtcHR5IEZsYWdzIG9iamVjdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRmxhZ3MoKSB7IH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCBhIEZsYWdzIG9iamVjdCBpbml0aWFsaXplZCB3aXRoIHRoZSBnaXZlbiBmbGFncy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmbGFncwl0aGUgZmxhZ3MgZm9yIGluaXRpYWxpemF0aW9uCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIEZsYWdzKEZsYWdzIGZsYWdzKSB7CisJdGhpcy5zeXN0ZW1fZmxhZ3MgPSBmbGFncy5zeXN0ZW1fZmxhZ3M7CisJaWYgKGZsYWdzLnVzZXJfZmxhZ3MgIT0gbnVsbCkKKwkgICAgdGhpcy51c2VyX2ZsYWdzID0gKEhhc2h0YWJsZSlmbGFncy51c2VyX2ZsYWdzLmNsb25lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGEgRmxhZ3Mgb2JqZWN0IGluaXRpYWxpemVkIHdpdGggdGhlIGdpdmVuIHN5c3RlbSBmbGFnLgorICAgICAqCisgICAgICogQHBhcmFtIGZsYWcJdGhlIGZsYWcgZm9yIGluaXRpYWxpemF0aW9uCisgICAgICovCisgICAgcHVibGljIEZsYWdzKEZsYWcgZmxhZykgeworCXRoaXMuc3lzdGVtX2ZsYWdzIHw9IGZsYWcuYml0OworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCBhIEZsYWdzIG9iamVjdCBpbml0aWFsaXplZCB3aXRoIHRoZSBnaXZlbiB1c2VyIGZsYWcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmxhZwl0aGUgZmxhZyBmb3IgaW5pdGlhbGl6YXRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgRmxhZ3MoU3RyaW5nIGZsYWcpIHsKKwl1c2VyX2ZsYWdzID0gbmV3IEhhc2h0YWJsZTw+KDEpOworCXVzZXJfZmxhZ3MucHV0KGZsYWcudG9Mb3dlckNhc2UoTG9jYWxlLkVOR0xJU0gpLCBmbGFnKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGQgdGhlIHNwZWNpZmllZCBzeXN0ZW0gZmxhZyB0byB0aGlzIEZsYWdzIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmbGFnCXRoZSBmbGFnIHRvIGFkZAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFkZChGbGFnIGZsYWcpIHsKKwlzeXN0ZW1fZmxhZ3MgfD0gZmxhZy5iaXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkIHRoZSBzcGVjaWZpZWQgdXNlciBmbGFnIHRvIHRoaXMgRmxhZ3Mgb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIGZsYWcJdGhlIGZsYWcgdG8gYWRkCisgICAgICovCisgICAgcHVibGljIHZvaWQgYWRkKFN0cmluZyBmbGFnKSB7CisJaWYgKHVzZXJfZmxhZ3MgPT0gbnVsbCkKKwkgICAgdXNlcl9mbGFncyA9IG5ldyBIYXNodGFibGU8PigxKTsKKwl1c2VyX2ZsYWdzLnB1dChmbGFnLnRvTG93ZXJDYXNlKExvY2FsZS5FTkdMSVNIKSwgZmxhZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkIGFsbCB0aGUgZmxhZ3MgaW4gdGhlIGdpdmVuIEZsYWdzIG9iamVjdCB0byB0aGlzCisgICAgICogRmxhZ3Mgb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIGYJRmxhZ3Mgb2JqZWN0CisgICAgICovCisgICAgcHVibGljIHZvaWQgYWRkKEZsYWdzIGYpIHsKKwlzeXN0ZW1fZmxhZ3MgfD0gZi5zeXN0ZW1fZmxhZ3M7IC8vIGFkZCBzeXN0ZW0gZmxhZ3MKKworCWlmIChmLnVzZXJfZmxhZ3MgIT0gbnVsbCkgeyAvLyBhZGQgdXNlci1kZWZpbmVkIGZsYWdzCisJICAgIGlmICh1c2VyX2ZsYWdzID09IG51bGwpCisJCXVzZXJfZmxhZ3MgPSBuZXcgSGFzaHRhYmxlPD4oMSk7CisKKwkgICAgRW51bWVyYXRpb248U3RyaW5nPiBlID0gZi51c2VyX2ZsYWdzLmtleXMoKTsKKworCSAgICB3aGlsZSAoZS5oYXNNb3JlRWxlbWVudHMoKSkgeworCQlTdHJpbmcgcyA9IGUubmV4dEVsZW1lbnQoKTsKKwkJdXNlcl9mbGFncy5wdXQocywgZi51c2VyX2ZsYWdzLmdldChzKSk7CisJICAgIH0KKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlIHRoZSBzcGVjaWZpZWQgc3lzdGVtIGZsYWcgZnJvbSB0aGlzIEZsYWdzIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbQlmbGFnIAl0aGUgZmxhZyB0byBiZSByZW1vdmVkCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVtb3ZlKEZsYWcgZmxhZykgeworCXN5c3RlbV9mbGFncyAmPSB+ZmxhZy5iaXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlIHRoZSBzcGVjaWZpZWQgdXNlciBmbGFnIGZyb20gdGhpcyBGbGFncyBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0JZmxhZyAJdGhlIGZsYWcgdG8gYmUgcmVtb3ZlZAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlbW92ZShTdHJpbmcgZmxhZykgeworCWlmICh1c2VyX2ZsYWdzICE9IG51bGwpCisJICAgIHVzZXJfZmxhZ3MucmVtb3ZlKGZsYWcudG9Mb3dlckNhc2UoTG9jYWxlLkVOR0xJU0gpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmUgYWxsIGZsYWdzIGluIHRoZSBnaXZlbiBGbGFncyBvYmplY3QgZnJvbSB0aGlzIAorICAgICAqIEZsYWdzIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbQlmIAl0aGUgZmxhZyB0byBiZSByZW1vdmVkCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVtb3ZlKEZsYWdzIGYpIHsKKwlzeXN0ZW1fZmxhZ3MgJj0gfmYuc3lzdGVtX2ZsYWdzOyAvLyByZW1vdmUgc3lzdGVtIGZsYWdzCisKKwlpZiAoZi51c2VyX2ZsYWdzICE9IG51bGwpIHsKKwkgICAgaWYgKHVzZXJfZmxhZ3MgPT0gbnVsbCkKKwkJcmV0dXJuOworCisJICAgIEVudW1lcmF0aW9uPFN0cmluZz4gZSA9IGYudXNlcl9mbGFncy5rZXlzKCk7CisJICAgIHdoaWxlIChlLmhhc01vcmVFbGVtZW50cygpKQorCQl1c2VyX2ZsYWdzLnJlbW92ZShlLm5leHRFbGVtZW50KCkpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmUgYW55IGZsYWdzIDxzdHJvbmc+bm90PC9zdHJvbmc+IGluIHRoZSBnaXZlbiBGbGFncyBvYmplY3QuCisgICAgICogVXNlZnVsIGZvciBjbGVhcmluZyBmbGFncyBub3Qgc3VwcG9ydGVkIGJ5IGEgc2VydmVyLiAgSWYgdGhlCisgICAgICogZ2l2ZW4gRmxhZ3Mgb2JqZWN0IGluY2x1ZGVzIHRoZSBGbGFncy5GbGFnLlVTRVIgZmxhZywgYWxsIHVzZXIKKyAgICAgKiBmbGFncyBpbiB0aGlzIEZsYWdzIG9iamVjdCBhcmUgcmV0YWluZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0JZgl0aGUgZmxhZ3MgdG8ga2VlcAorICAgICAqIEByZXR1cm4JCXRydWUgaWYgdGhpcyBGbGFncyBvYmplY3QgY2hhbmdlZAorICAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS42CisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gcmV0YWluQWxsKEZsYWdzIGYpIHsKKwlib29sZWFuIGNoYW5nZWQgPSBmYWxzZTsKKwlpbnQgc2YgPSBzeXN0ZW1fZmxhZ3MgJiBmLnN5c3RlbV9mbGFnczsKKwlpZiAoc3lzdGVtX2ZsYWdzICE9IHNmKSB7CisJICAgIHN5c3RlbV9mbGFncyA9IHNmOworCSAgICBjaGFuZ2VkID0gdHJ1ZTsKKwl9CisKKwkvLyBpZiB3ZSBoYXZlIHVzZXIgZmxhZ3MsIGFuZCB0aGUgVVNFUiBmbGFnIGlzIG5vdCBzZXQgaW4gImYiLAorCS8vIGRldGVybWluZSB3aGljaCB1c2VyIGZsYWdzIHRvIGNsZWFyCisJaWYgKHVzZXJfZmxhZ3MgIT0gbnVsbCAmJiAoZi5zeXN0ZW1fZmxhZ3MgJiBVU0VSX0JJVCkgPT0gMCkgeworCSAgICBpZiAoZi51c2VyX2ZsYWdzICE9IG51bGwpIHsKKwkJRW51bWVyYXRpb248U3RyaW5nPiBlID0gdXNlcl9mbGFncy5rZXlzKCk7CisJCXdoaWxlIChlLmhhc01vcmVFbGVtZW50cygpKSB7CisJCSAgICBTdHJpbmcga2V5ID0gZS5uZXh0RWxlbWVudCgpOworCQkgICAgaWYgKCFmLnVzZXJfZmxhZ3MuY29udGFpbnNLZXkoa2V5KSkgeworCQkJdXNlcl9mbGFncy5yZW1vdmUoa2V5KTsKKwkJCWNoYW5nZWQgPSB0cnVlOworCQkgICAgfQorCQl9CisJICAgIH0gZWxzZSB7CisJCS8vIGlmIGFueXRoaW5nIGluIHVzZXJfZmxhZ3MsIHRocm93IHRoZW0gYXdheQorCQljaGFuZ2VkID0gdXNlcl9mbGFncy5zaXplKCkgPiAwOworCQl1c2VyX2ZsYWdzID0gbnVsbDsKKwkgICAgfQorCX0KKwlyZXR1cm4gY2hhbmdlZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVjayB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgc3lzdGVtIGZsYWcgaXMgcHJlc2VudCBpbiB0aGlzIEZsYWdzIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbQlmbGFnCXRoZSBmbGFnIHRvIHRlc3QKKyAgICAgKiBAcmV0dXJuIAkJdHJ1ZSBvZiB0aGUgZ2l2ZW4gZmxhZyBpcyBwcmVzZW50LCBvdGhlcndpc2UgZmFsc2UuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoRmxhZyBmbGFnKSB7CisJcmV0dXJuIChzeXN0ZW1fZmxhZ3MgJiBmbGFnLmJpdCkgIT0gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVjayB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgdXNlciBmbGFnIGlzIHByZXNlbnQgaW4gdGhpcyBGbGFncyBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0JZmxhZwl0aGUgZmxhZyB0byB0ZXN0CisgICAgICogQHJldHVybiAJCXRydWUgb2YgdGhlIGdpdmVuIGZsYWcgaXMgcHJlc2VudCwgb3RoZXJ3aXNlIGZhbHNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKFN0cmluZyBmbGFnKSB7CisJaWYgKHVzZXJfZmxhZ3MgPT0gbnVsbCkgCisJICAgIHJldHVybiBmYWxzZTsKKwllbHNlCisJICAgIHJldHVybiB1c2VyX2ZsYWdzLmNvbnRhaW5zS2V5KGZsYWcudG9Mb3dlckNhc2UoTG9jYWxlLkVOR0xJU0gpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVjayB3aGV0aGVyIGFsbCB0aGUgZmxhZ3MgaW4gdGhlIHNwZWNpZmllZCBGbGFncyBvYmplY3QgYXJlCisgICAgICogcHJlc2VudCBpbiB0aGlzIEZsYWdzIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbQlmCXRoZSBmbGFncyB0byB0ZXN0CisgICAgICogQHJldHVybgl0cnVlIGlmIGFsbCBmbGFncyBpbiB0aGUgZ2l2ZW4gRmxhZ3Mgb2JqZWN0IGFyZSBwcmVzZW50LCAKKyAgICAgKgkJb3RoZXJ3aXNlIGZhbHNlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKEZsYWdzIGYpIHsKKwkvLyBDaGVjayBzeXN0ZW0gZmxhZ3MKKwlpZiAoKGYuc3lzdGVtX2ZsYWdzICYgc3lzdGVtX2ZsYWdzKSAhPSBmLnN5c3RlbV9mbGFncykKKwkgICAgcmV0dXJuIGZhbHNlOworCisJLy8gQ2hlY2sgdXNlciBmbGFncworCWlmIChmLnVzZXJfZmxhZ3MgIT0gbnVsbCkgeworCSAgICBpZiAodXNlcl9mbGFncyA9PSBudWxsKQorCQlyZXR1cm4gZmFsc2U7CisJICAgIEVudW1lcmF0aW9uPFN0cmluZz4gZSA9IGYudXNlcl9mbGFncy5rZXlzKCk7CisKKwkgICAgd2hpbGUgKGUuaGFzTW9yZUVsZW1lbnRzKCkpIHsKKwkJaWYgKCF1c2VyX2ZsYWdzLmNvbnRhaW5zS2V5KGUubmV4dEVsZW1lbnQoKSkpCisJCSAgICByZXR1cm4gZmFsc2U7CisJICAgIH0KKwl9CisKKwkvLyBJZiB3ZSd2ZSBtYWRlIGl0IHRpbGwgaGVyZSwgcmV0dXJuIHRydWUKKwlyZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVjayB3aGV0aGVyIHRoZSB0d28gRmxhZ3Mgb2JqZWN0cyBhcmUgZXF1YWwuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRydWUgaWYgdGhleSdyZSBlcXVhbAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CisJaWYgKCEob2JqIGluc3RhbmNlb2YgRmxhZ3MpKQorCSAgICByZXR1cm4gZmFsc2U7CisKKwlGbGFncyBmID0gKEZsYWdzKW9iajsKKworCS8vIENoZWNrIHN5c3RlbSBmbGFncworCWlmIChmLnN5c3RlbV9mbGFncyAhPSB0aGlzLnN5c3RlbV9mbGFncykKKwkgICAgcmV0dXJuIGZhbHNlOworCisJLy8gQ2hlY2sgdXNlciBmbGFncworCWludCBzaXplID0gdGhpcy51c2VyX2ZsYWdzID09IG51bGwgPyAwIDogdGhpcy51c2VyX2ZsYWdzLnNpemUoKTsKKwlpbnQgZnNpemUgPSBmLnVzZXJfZmxhZ3MgPT0gbnVsbCA/IDAgOiBmLnVzZXJfZmxhZ3Muc2l6ZSgpOworCWlmIChzaXplID09IDAgJiYgZnNpemUgPT0gMCkKKwkgICAgcmV0dXJuIHRydWU7CisJaWYgKGYudXNlcl9mbGFncyAhPSBudWxsICYmIHRoaXMudXNlcl9mbGFncyAhPSBudWxsICYmIGZzaXplID09IHNpemUpCisJICAgIHJldHVybiB1c2VyX2ZsYWdzLmtleVNldCgpLmVxdWFscyhmLnVzZXJfZmxhZ3Mua2V5U2V0KCkpOworCisJcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXB1dGUgYSBoYXNoIGNvZGUgZm9yIHRoaXMgRmxhZ3Mgb2JqZWN0LgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgaGFzaCBjb2RlCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKwlpbnQgaGFzaCA9IHN5c3RlbV9mbGFnczsKKwlpZiAodXNlcl9mbGFncyAhPSBudWxsKSB7CisJICAgIEVudW1lcmF0aW9uPFN0cmluZz4gZSA9IHVzZXJfZmxhZ3Mua2V5cygpOworCSAgICB3aGlsZSAoZS5oYXNNb3JlRWxlbWVudHMoKSkKKwkJaGFzaCArPSBlLm5leHRFbGVtZW50KCkuaGFzaENvZGUoKTsKKwl9CisJcmV0dXJuIGhhc2g7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIGFsbCB0aGUgc3lzdGVtIGZsYWdzIGluIHRoaXMgRmxhZ3Mgb2JqZWN0LiAgUmV0dXJucworICAgICAqIGFuIGFycmF5IG9mIHNpemUgemVybyBpZiBubyBmbGFncyBhcmUgc2V0LgorICAgICAqCisgICAgICogQHJldHVybglhcnJheSBvZiBGbGFncy5GbGFnIG9iamVjdHMgcmVwcmVzZW50aW5nIHN5c3RlbSBmbGFncworICAgICAqLworICAgIHB1YmxpYyBGbGFnW10gZ2V0U3lzdGVtRmxhZ3MoKSB7CisJVmVjdG9yPEZsYWc+IHYgPSBuZXcgVmVjdG9yPD4oKTsKKwlpZiAoKHN5c3RlbV9mbGFncyAmIEFOU1dFUkVEX0JJVCkgIT0gMCkKKwkgICAgdi5hZGRFbGVtZW50KEZsYWcuQU5TV0VSRUQpOworCWlmICgoc3lzdGVtX2ZsYWdzICYgREVMRVRFRF9CSVQpICE9IDApCisJICAgIHYuYWRkRWxlbWVudChGbGFnLkRFTEVURUQpOworCWlmICgoc3lzdGVtX2ZsYWdzICYgRFJBRlRfQklUKSAhPSAwKQorCSAgICB2LmFkZEVsZW1lbnQoRmxhZy5EUkFGVCk7CisJaWYgKChzeXN0ZW1fZmxhZ3MgJiBGTEFHR0VEX0JJVCkgIT0gMCkKKwkgICAgdi5hZGRFbGVtZW50KEZsYWcuRkxBR0dFRCk7CisJaWYgKChzeXN0ZW1fZmxhZ3MgJiBSRUNFTlRfQklUKSAhPSAwKQorCSAgICB2LmFkZEVsZW1lbnQoRmxhZy5SRUNFTlQpOworCWlmICgoc3lzdGVtX2ZsYWdzICYgU0VFTl9CSVQpICE9IDApCisJICAgIHYuYWRkRWxlbWVudChGbGFnLlNFRU4pOworCWlmICgoc3lzdGVtX2ZsYWdzICYgVVNFUl9CSVQpICE9IDApCisJICAgIHYuYWRkRWxlbWVudChGbGFnLlVTRVIpOworCisJRmxhZ1tdIGYgPSBuZXcgRmxhZ1t2LnNpemUoKV07CisJdi5jb3B5SW50byhmKTsKKwlyZXR1cm4gZjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYWxsIHRoZSB1c2VyIGZsYWdzIGluIHRoaXMgRmxhZ3Mgb2JqZWN0LiAgUmV0dXJucworICAgICAqIGFuIGFycmF5IG9mIHNpemUgemVybyBpZiBubyBmbGFncyBhcmUgc2V0LgorICAgICAqCisgICAgICogQHJldHVybglhcnJheSBvZiBTdHJpbmdzLCBlYWNoIFN0cmluZyByZXByZXNlbnRzIGEgZmxhZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nW10gZ2V0VXNlckZsYWdzKCkgeworCVZlY3RvcjxTdHJpbmc+IHYgPSBuZXcgVmVjdG9yPD4oKTsKKwlpZiAodXNlcl9mbGFncyAhPSBudWxsKSB7CisJICAgIEVudW1lcmF0aW9uPFN0cmluZz4gZSA9IHVzZXJfZmxhZ3MuZWxlbWVudHMoKTsKKworCSAgICB3aGlsZSAoZS5oYXNNb3JlRWxlbWVudHMoKSkKKwkJdi5hZGRFbGVtZW50KGUubmV4dEVsZW1lbnQoKSk7CisJfQorCisJU3RyaW5nW10gZiA9IG5ldyBTdHJpbmdbdi5zaXplKCldOworCXYuY29weUludG8oZik7CisJcmV0dXJuIGY7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xlYXIgYWxsIG9mIHRoZSBzeXN0ZW0gZmxhZ3MuCisgICAgICoKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS42CisgICAgICovCisgICAgcHVibGljIHZvaWQgY2xlYXJTeXN0ZW1GbGFncygpIHsKKwlzeXN0ZW1fZmxhZ3MgPSAwOworICAgIH0KKworICAgIC8qKgorICAgICAqIENsZWFyIGFsbCBvZiB0aGUgdXNlciBmbGFncy4KKyAgICAgKgorICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjbGVhclVzZXJGbGFncygpIHsKKwl1c2VyX2ZsYWdzID0gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgY2xvbmUgb2YgdGhpcyBGbGFncyBvYmplY3QuCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKKwlGbGFncyBmID0gbnVsbDsKKwl0cnkgeworCSAgICBmID0gKEZsYWdzKXN1cGVyLmNsb25lKCk7CisJfSBjYXRjaCAoQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gY2V4KSB7CisJICAgIC8vIGlnbm9yZSwgY2FuJ3QgaGFwcGVuCisJfQorCWlmICh0aGlzLnVzZXJfZmxhZ3MgIT0gbnVsbCkKKwkgICAgZi51c2VyX2ZsYWdzID0gKEhhc2h0YWJsZSl0aGlzLnVzZXJfZmxhZ3MuY2xvbmUoKTsKKwlyZXR1cm4gZjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBGbGFncyBvYmplY3QuCisgICAgICogTm90ZSB0aGF0IHRoZSBleGFjdCBmb3JtYXQgb2YgdGhlIHN0cmluZyBpcyBzdWJqZWN0IHRvIGNoYW5nZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworCVN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworCisJaWYgKChzeXN0ZW1fZmxhZ3MgJiBBTlNXRVJFRF9CSVQpICE9IDApCisJICAgIHNiLmFwcGVuZCgiXFxBbnN3ZXJlZCAiKTsKKwlpZiAoKHN5c3RlbV9mbGFncyAmIERFTEVURURfQklUKSAhPSAwKQorCSAgICBzYi5hcHBlbmQoIlxcRGVsZXRlZCAiKTsKKwlpZiAoKHN5c3RlbV9mbGFncyAmIERSQUZUX0JJVCkgIT0gMCkKKwkgICAgc2IuYXBwZW5kKCJcXERyYWZ0ICIpOworCWlmICgoc3lzdGVtX2ZsYWdzICYgRkxBR0dFRF9CSVQpICE9IDApCisJICAgIHNiLmFwcGVuZCgiXFxGbGFnZ2VkICIpOworCWlmICgoc3lzdGVtX2ZsYWdzICYgUkVDRU5UX0JJVCkgIT0gMCkKKwkgICAgc2IuYXBwZW5kKCJcXFJlY2VudCAiKTsKKwlpZiAoKHN5c3RlbV9mbGFncyAmIFNFRU5fQklUKSAhPSAwKQorCSAgICBzYi5hcHBlbmQoIlxcU2VlbiAiKTsKKwlpZiAoKHN5c3RlbV9mbGFncyAmIFVTRVJfQklUKSAhPSAwKQorCSAgICBzYi5hcHBlbmQoIlxcKiAiKTsKKworCWJvb2xlYW4gZmlyc3QgPSB0cnVlOworCWlmICh1c2VyX2ZsYWdzICE9IG51bGwpIHsKKwkgICAgRW51bWVyYXRpb248U3RyaW5nPiBlID0gdXNlcl9mbGFncy5lbGVtZW50cygpOworCisJICAgIHdoaWxlIChlLmhhc01vcmVFbGVtZW50cygpKSB7CisJCWlmIChmaXJzdCkKKwkJICAgIGZpcnN0ID0gZmFsc2U7CisJCWVsc2UKKwkJICAgIHNiLmFwcGVuZCgnICcpOworCQlzYi5hcHBlbmQoZS5uZXh0RWxlbWVudCgpKTsKKwkgICAgfQorCX0KKworCWlmIChmaXJzdCAmJiBzYi5sZW5ndGgoKSA+IDApCisJICAgIHNiLnNldExlbmd0aChzYi5sZW5ndGgoKSAtIDEpOwkvLyBzbWFzaCB0cmFpbGluZyBzcGFjZQorCisJcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqKioqCisgICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nIGFyZ3ZbXSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJLy8gYSBuZXcgZmxhZ3Mgb2JqZWN0CisJRmxhZ3MgZjEgPSBuZXcgRmxhZ3MoKTsKKwlmMS5hZGQoRmxhZ3MuRmxhZy5ERUxFVEVEKTsKKwlmMS5hZGQoRmxhZ3MuRmxhZy5TRUVOKTsKKwlmMS5hZGQoRmxhZ3MuRmxhZy5SRUNFTlQpOworCWYxLmFkZChGbGFncy5GbGFnLkFOU1dFUkVEKTsKKworCS8vIGNoZWNrIGNvcHkgY29uc3RydWN0b3Igd2l0aCBvbmx5IHN5c3RlbSBmbGFncworCUZsYWdzIGZjID0gbmV3IEZsYWdzKGYxKTsKKwlpZiAoZjEuZXF1YWxzKGZjKSAmJiBmYy5lcXVhbHMoZjEpKQorCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oInN1Y2Nlc3MiKTsKKwllbHNlCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZmFpbCIpOworCisJLy8gY2hlY2sgY2xvbmUgd2l0aCBvbmx5IHN5c3RlbSBmbGFncworCWZjID0gKEZsYWdzKWYxLmNsb25lKCk7CisJaWYgKGYxLmVxdWFscyhmYykgJiYgZmMuZXF1YWxzKGYxKSkKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJzdWNjZXNzIik7CisJZWxzZQorCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oImZhaWwiKTsKKworCS8vIGFkZCBhIHVzZXIgZmxhZyBhbmQgbWFrZSBzdXJlIGl0IHN0aWxsIHdvcmtzIHJpZ2h0CisJZjEuYWRkKCJNeUZsYWciKTsKKworCS8vIHNob3VsZG4ndCBiZSBlcXVhbCBoZXJlCisJaWYgKCFmMS5lcXVhbHMoZmMpICYmICFmYy5lcXVhbHMoZjEpKQorCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oInN1Y2Nlc3MiKTsKKwllbHNlCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZmFpbCIpOworCisJLy8gY2hlY2sgY2xvbmUKKwlmYyA9IChGbGFncylmMS5jbG9uZSgpOworCWlmIChmMS5lcXVhbHMoZmMpICYmIGZjLmVxdWFscyhmMSkpCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigic3VjY2VzcyIpOworCWVsc2UKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJmYWlsIik7CisKKwkvLyBtYWtlIHN1cmUgdXNlciBmbGFnIGhhc2ggdGFibGVzIGFyZSBzZXBhcmF0ZQorCWZjLmFkZCgiQW5vdGhlckZsYWciKTsKKwlpZiAoIWYxLmVxdWFscyhmYykgJiYgIWZjLmVxdWFscyhmMSkpCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigic3VjY2VzcyIpOworCWVsc2UKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJmYWlsIik7CisKKwkvLyBjaGVjayBjb3B5IGNvbnN0cnVjdG9yCisJZmMgPSBuZXcgRmxhZ3MoZjEpOworCWlmIChmMS5lcXVhbHMoZmMpICYmIGZjLmVxdWFscyhmMSkpCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigic3VjY2VzcyIpOworCWVsc2UKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJmYWlsIik7CisKKwkvLyBhbm90aGVyIG5ldyBmbGFncyBvYmplY3QKKwlGbGFncyBmMiA9IG5ldyBGbGFncyhGbGFncy5GbGFnLkFOU1dFUkVEKTsKKwlmMi5hZGQoIk15RmxhZyIpOworCisJaWYgKGYxLmNvbnRhaW5zKEZsYWdzLkZsYWcuREVMRVRFRCkpCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigic3VjY2VzcyIpOworCWVsc2UKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJmYWlsIik7CisJCQorCWlmIChmMS5jb250YWlucyhGbGFncy5GbGFnLlNFRU4pKQorCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oInN1Y2Nlc3MiKTsKKwllbHNlCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZmFpbCIpOworCisJaWYgKGYxLmNvbnRhaW5zKEZsYWdzLkZsYWcuUkVDRU5UKSkKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJzdWNjZXNzIik7CisJZWxzZQorCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oImZhaWwiKTsKKworCWlmIChmMS5jb250YWlucygiTXlGbGFnIikpCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigic3VjY2VzcyIpOworCWVsc2UKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJmYWlsIik7CisKKwlpZiAoZjIuY29udGFpbnMoRmxhZ3MuRmxhZy5BTlNXRVJFRCkpCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigic3VjY2VzcyIpOworCWVsc2UKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJmYWlsIik7CisKKworCVN5c3RlbS5vdXQucHJpbnRsbigiLS0tLS0tLS0tLS0tLS0tLSIpOworCisJU3RyaW5nW10gcyA9IGYxLmdldFVzZXJGbGFncygpOworCWZvciAoaW50IGkgPSAwOyBpIDwgcy5sZW5ndGg7IGkrKykKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKHNbaV0pOworCVN5c3RlbS5vdXQucHJpbnRsbigiLS0tLS0tLS0tLS0tLS0tLSIpOworCXMgPSBmMi5nZXRVc2VyRmxhZ3MoKTsKKwlmb3IgKGludCBpID0gMDsgaSA8IHMubGVuZ3RoOyBpKyspCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbihzW2ldKTsKKworCVN5c3RlbS5vdXQucHJpbnRsbigiLS0tLS0tLS0tLS0tLS0tLSIpOworCisJaWYgKGYxLmNvbnRhaW5zKGYyKSkgLy8gdGhpcyBzaG91bGQgYmUgdHJ1ZQorCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oInN1Y2Nlc3MiKTsKKwllbHNlCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZmFpbCIpOworCisJaWYgKCFmMi5jb250YWlucyhmMSkpIC8vIHRoaXMgc2hvdWxkIGJlIGZhbHNlCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigic3VjY2VzcyIpOworCWVsc2UKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJmYWlsIik7CisKKwlGbGFncyBmMyA9IG5ldyBGbGFncygpOworCWYzLmFkZChGbGFncy5GbGFnLkRFTEVURUQpOworCWYzLmFkZChGbGFncy5GbGFnLlNFRU4pOworCWYzLmFkZChGbGFncy5GbGFnLlJFQ0VOVCk7CisJZjMuYWRkKEZsYWdzLkZsYWcuQU5TV0VSRUQpOworCWYzLmFkZCgiQU5PVEhFUkZMQUciKTsKKwlmMy5hZGQoIk1ZRkxBRyIpOworCisJZjEuYWRkKCJBbm90aGVyRmxhZyIpOworCisJaWYgKGYxLmVxdWFscyhmMykpCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZXF1YWxzIHN1Y2Nlc3MiKTsKKwllbHNlCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZmFpbCIpOworCWlmIChmMy5lcXVhbHMoZjEpKQorCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oImVxdWFscyBzdWNjZXNzIik7CisJZWxzZQorCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oImZhaWwiKTsKKwlTeXN0ZW0ub3V0LnByaW50bG4oImYxIGhhc2ggY29kZSAiICsgZjEuaGFzaENvZGUoKSk7CisJU3lzdGVtLm91dC5wcmludGxuKCJmMyBoYXNoIGNvZGUgIiArIGYzLmhhc2hDb2RlKCkpOworCWlmIChmMS5oYXNoQ29kZSgpID09IGYzLmhhc2hDb2RlKCkpCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigic3VjY2VzcyIpOworCWVsc2UKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJmYWlsIik7CisgICAgfQorICAgICoqKiovCit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9Gb2xkZXIuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL0ZvbGRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBkZGNlMjEKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9Gb2xkZXIuamF2YQpAQCAtMCwwICsxLDE2NTcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbDsKKworaW1wb3J0IGphdmEubGFuZy4qOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkV2ZW50TGlzdGVuZXI7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRvcjsKK2ltcG9ydCBqYXZheC5tYWlsLnNlYXJjaC5TZWFyY2hUZXJtOworaW1wb3J0IGphdmF4Lm1haWwuZXZlbnQuKjsKKworLyoqCisgKiBGb2xkZXIgaXMgYW4gYWJzdHJhY3QgY2xhc3MgdGhhdCByZXByZXNlbnRzIGEgZm9sZGVyIGZvciBtYWlsCisgKiBtZXNzYWdlcy4gU3ViY2xhc3NlcyBpbXBsZW1lbnQgcHJvdG9jb2wgc3BlY2lmaWMgRm9sZGVycy48cD4KKyAqCisgKiBGb2xkZXJzIGNhbiBjb250YWluIE1lc3NhZ2VzLCBvdGhlciBGb2xkZXJzIG9yIGJvdGgsIHRodXMgcHJvdmlkaW5nCisgKiBhIHRyZWUtbGlrZSBoaWVyYXJjaHkgcm9vdGVkIGF0IHRoZSBTdG9yZSdzIGRlZmF1bHQgZm9sZGVyLiAoTm90ZSAKKyAqIHRoYXQgc29tZSBGb2xkZXIgaW1wbGVtZW50YXRpb25zIG1heSBub3QgYWxsb3cgYm90aCBNZXNzYWdlcyBhbmQgCisgKiBvdGhlciBGb2xkZXJzIGluIHRoZSBzYW1lIEZvbGRlcikuPHA+CisgKgorICogVGhlIGludGVycHJldGF0aW9uIG9mIGZvbGRlciBuYW1lcyBpcyBpbXBsZW1lbnRhdGlvbiBkZXBlbmRlbnQuCisgKiBUaGUgZGlmZmVyZW50IGxldmVscyBvZiBoaWVyYXJjaHkgaW4gYSBmb2xkZXIncyBmdWxsIG5hbWUKKyAqIGFyZSBzZXBhcmF0ZWQgZnJvbSBlYWNoIG90aGVyIGJ5IHRoZSBoaWVyYXJjaHkgZGVsaW1pdGVyIAorICogY2hhcmFjdGVyLjxwPgorICoKKyAqIFRoZSBjYXNlLWluc2Vuc2l0aXZlIGZ1bGwgZm9sZGVyIG5hbWUgKHRoYXQgaXMsIHRoZSBmdWxsIG5hbWUKKyAqIHJlbGF0aXZlIHRvIHRoZSBkZWZhdWx0IGZvbGRlciBmb3IgYSBTdG9yZSkgPHN0cm9uZz5JTkJPWDwvc3Ryb25nPgorICogaXMgcmVzZXJ2ZWQgdG8gbWVhbiB0aGUgInByaW1hcnkgZm9sZGVyIGZvciB0aGlzIHVzZXIgb24gdGhpcworICogc2VydmVyIi4gIE5vdCBhbGwgU3RvcmVzIHdpbGwgcHJvdmlkZSBhbiBJTkJPWCBmb2xkZXIsIGFuZCBub3QKKyAqIGFsbCB1c2VycyB3aWxsIGhhdmUgYW4gSU5CT1ggZm9sZGVyIGF0IGFsbCB0aW1lcy4gIFRoZSBuYW1lCisgKiA8c3Ryb25nPklOQk9YPC9zdHJvbmc+IGlzIHJlc2VydmVkIHRvIHJlZmVyIHRvIHRoaXMgZm9sZGVyLAorICogd2hlbiBpdCBleGlzdHMsIGluIFN0b3JlcyB0aGF0IHByb3ZpZGUgaXQuIDxwPgorICoKKyAqIEEgRm9sZGVyIG9iamVjdCBvYnRhaW5lZCBmcm9tIGEgU3RvcmUgbmVlZCBub3QgYWN0dWFsbHkgZXhpc3QKKyAqIGluIHRoZSBiYWNrZW5kIHN0b3JlLiBUaGUgPGNvZGU+ZXhpc3RzPC9jb2RlPiBtZXRob2QgdGVzdHMgd2hldGhlcgorICogdGhlIGZvbGRlciBleGlzdHMgb3Igbm90LiBUaGUgPGNvZGU+Y3JlYXRlPC9jb2RlPiBtZXRob2QKKyAqIGNyZWF0ZXMgYSBGb2xkZXIuIDxwPgorICoKKyAqIEEgRm9sZGVyIGlzIGluaXRpYWxseSBpbiB0aGUgY2xvc2VkIHN0YXRlLiBDZXJ0YWluIG1ldGhvZHMgYXJlIHZhbGlkCisgKiBpbiB0aGlzIHN0YXRlOyB0aGUgZG9jdW1lbnRhdGlvbiBmb3IgdGhvc2UgbWV0aG9kcyBub3RlIHRoaXMuICBBCisgKiBGb2xkZXIgaXMgb3BlbmVkIGJ5IGNhbGxpbmcgaXRzICdvcGVuJyBtZXRob2QuIEFsbCBGb2xkZXIgbWV0aG9kcywKKyAqIGV4Y2VwdCA8Y29kZT5vcGVuPC9jb2RlPiwgPGNvZGU+ZGVsZXRlPC9jb2RlPiBhbmQgCisgKiA8Y29kZT5yZW5hbWVUbzwvY29kZT4sIGFyZSB2YWxpZCBpbiB0aGlzIHN0YXRlLiA8cD4KKyAqCisgKiBUaGUgb25seSB3YXkgdG8gZ2V0IGEgRm9sZGVyIGlzIGJ5IGludm9raW5nIHRoZSAKKyAqIDxjb2RlPmdldEZvbGRlcjwvY29kZT4gbWV0aG9kIG9uIFN0b3JlLCBGb2xkZXIsIG9yIFNlc3Npb24sIG9yIGJ5IGludm9raW5nIAorICogdGhlIDxjb2RlPmxpc3Q8L2NvZGU+IG9yIDxjb2RlPmxpc3RTdWJzY3JpYmVkPC9jb2RlPiBtZXRob2RzIAorICogb24gRm9sZGVyLiBGb2xkZXIgb2JqZWN0cyByZXR1cm5lZCBieSB0aGUgYWJvdmUgbWV0aG9kcyBhcmUgbm90IAorICogY2FjaGVkIGJ5IHRoZSBTdG9yZS4gVGh1cywgaW52b2tpbmcgdGhlIDxjb2RlPmdldEZvbGRlcjwvY29kZT4gbWV0aG9kCisgKiB3aXRoIHRoZSBzYW1lIGZvbGRlciBuYW1lIG11bHRpcGxlIHRpbWVzIHdpbGwgcmV0dXJuIGRpc3RpbmN0IEZvbGRlciAKKyAqIG9iamVjdHMuICBMaWtld2lzZSBmb3IgdGhlIDxjb2RlPmxpc3Q8L2NvZGU+IGFuZCA8Y29kZT5saXN0U3Vic2NyaWJlZDwvY29kZT4KKyAqIG1ldGhvZHMuIDxwPgorICoKKyAqIFRoZSBNZXNzYWdlIG9iamVjdHMgd2l0aGluIHRoZSBGb2xkZXIgYXJlIGNhY2hlZCBieSB0aGUgRm9sZGVyLgorICogVGh1cywgaW52b2tpbmcgPGNvZGU+Z2V0TWVzc2FnZShtc2dubyk8L2NvZGU+IG9uIHRoZSBzYW1lIG1lc3NhZ2UgbnVtYmVyCisgKiBtdWx0aXBsZSB0aW1lcyB3aWxsIHJldHVybiB0aGUgc2FtZSBNZXNzYWdlIG9iamVjdCwgdW50aWwgYW4gCisgKiBleHB1bmdlIGlzIGRvbmUgb24gdGhpcyBGb2xkZXIuIDxwPgorICoKKyAqIE1lc3NhZ2Ugb2JqZWN0cyBmcm9tIGEgRm9sZGVyIGFyZSBvbmx5IHZhbGlkIHdoaWxlIGEgRm9sZGVyIGlzIG9wZW4KKyAqIGFuZCBzaG91bGQgbm90IGJlIGFjY2Vzc2VkIGFmdGVyIHRoZSBGb2xkZXIgaXMgY2xvc2VkLCBldmVuIGlmIHRoZQorICogRm9sZGVyIGlzIHN1YnNlcXVlbnRseSByZW9wZW5lZC4gIEluc3RlYWQsIG5ldyBNZXNzYWdlIG9iamVjdHMgbXVzdAorICogYmUgZmV0Y2hlZCBmcm9tIHRoZSBGb2xkZXIgYWZ0ZXIgdGhlIEZvbGRlciBpcyByZW9wZW5lZC4gPHA+CisgKgorICogTm90ZSB0aGF0IGEgTWVzc2FnZSdzIG1lc3NhZ2UgbnVtYmVyIGNhbiBjaGFuZ2Ugd2l0aGluIGEKKyAqIHNlc3Npb24gaWYgdGhlIGNvbnRhaW5pbmcgRm9sZGVyIGlzIGV4cHVuZ2VkIHVzaW5nIHRoZSBleHB1bmdlCisgKiBtZXRob2QuICBDbGllbnRzIHRoYXQgdXNlIG1lc3NhZ2UgbnVtYmVycyBhcyByZWZlcmVuY2VzIHRvIG1lc3NhZ2VzCisgKiBzaG91bGQgYmUgYXdhcmUgb2YgdGhpcyBhbmQgc2hvdWxkIGJlIHByZXBhcmVkIHRvIGRlYWwgd2l0aCB0aGlzCisgKiBzaXR1YXRpb24gKHByb2JhYmx5IGJ5IGZsdXNoaW5nIG91dCBleGlzdGluZyBtZXNzYWdlIG51bWJlciByZWZlcmVuY2VzCisgKiBhbmQgcmVsb2FkaW5nIHRoZW0pLiBCZWNhdXNlIG9mIHRoaXMgY29tcGxleGl0eSwgaXQgaXMgYmV0dGVyIGZvcgorICogY2xpZW50cyB0byB1c2UgTWVzc2FnZSBvYmplY3RzIGFzIHJlZmVyZW5jZXMgdG8gbWVzc2FnZXMsIHJhdGhlciB0aGFuCisgKiBtZXNzYWdlIG51bWJlcnMuIEV4cHVuZ2VkIE1lc3NhZ2Ugb2JqZWN0cyBzdGlsbCBoYXZlIHRvIGJlCisgKiBwcnVuZWQsIGJ1dCBvdGhlciBNZXNzYWdlIG9iamVjdHMgaW4gdGhhdCBmb2xkZXIgYXJlIG5vdCBhZmZlY3RlZCBieSB0aGUgCisgKiBleHB1bmdlLgorICoKKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCisKK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBGb2xkZXIgaW1wbGVtZW50cyBBdXRvQ2xvc2VhYmxlIHsKKworICAgIC8qKgorICAgICAqIFRoZSBwYXJlbnQgc3RvcmUuCisgICAgICovCisgICAgcHJvdGVjdGVkIFN0b3JlIHN0b3JlOworCisgICAgLyoqCisgICAgICogVGhlIG9wZW4gbW9kZSBvZiB0aGlzIGZvbGRlci4gIFRoZSBvcGVuIG1vZGUgaXMKKyAgICAgKiA8Y29kZT5Gb2xkZXIuUkVBRF9PTkxZPC9jb2RlPiwgPGNvZGU+Rm9sZGVyLlJFQURfV1JJVEU8L2NvZGU+LAorICAgICAqIG9yIC0xIGlmIG5vdCBrbm93bi4KKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS4xCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBtb2RlID0gLTE7CisKKyAgICAvKgorICAgICAqIFRoZSBxdWV1ZSBvZiBldmVudHMgdG8gYmUgZGVsaXZlcmVkLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgRXZlbnRRdWV1ZSBxOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IgdGhhdCB0YWtlcyBhIFN0b3JlIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdG9yZSB0aGUgU3RvcmUgdGhhdCBob2xkcyB0aGlzIGZvbGRlcgorICAgICAqLworICAgIHByb3RlY3RlZCBGb2xkZXIoU3RvcmUgc3RvcmUpIHsKKwl0aGlzLnN0b3JlID0gc3RvcmU7CisKKwkvLyBjcmVhdGUgb3IgY2hvb3NlIHRoZSBhcHByb3ByaWF0ZSBldmVudCBxdWV1ZQorCVNlc3Npb24gc2Vzc2lvbiA9IHN0b3JlLmdldFNlc3Npb24oKTsKKwlTdHJpbmcgc2NvcGUgPQorCSAgICBzZXNzaW9uLmdldFByb3BlcnRpZXMoKS5nZXRQcm9wZXJ0eSgibWFpbC5ldmVudC5zY29wZSIsICJmb2xkZXIiKTsKKwlFeGVjdXRvciBleGVjdXRvciA9CisJCShFeGVjdXRvcilzZXNzaW9uLmdldFByb3BlcnRpZXMoKS5nZXQoIm1haWwuZXZlbnQuZXhlY3V0b3IiKTsKKwlpZiAoc2NvcGUuZXF1YWxzSWdub3JlQ2FzZSgiYXBwbGljYXRpb24iKSkKKwkgICAgcSA9IEV2ZW50UXVldWUuZ2V0QXBwbGljYXRpb25FdmVudFF1ZXVlKGV4ZWN1dG9yKTsKKwllbHNlIGlmIChzY29wZS5lcXVhbHNJZ25vcmVDYXNlKCJzZXNzaW9uIikpCisJICAgIHEgPSBzZXNzaW9uLmdldEV2ZW50UXVldWUoKTsKKwllbHNlIGlmIChzY29wZS5lcXVhbHNJZ25vcmVDYXNlKCJzdG9yZSIpKQorCSAgICBxID0gc3RvcmUuZ2V0RXZlbnRRdWV1ZSgpOworCWVsc2UgLy8gaWYgKHNjb3BlLmVxdWFsc0lnbm9yZUNhc2UoImZvbGRlciIpKQorCSAgICBxID0gbmV3IEV2ZW50UXVldWUoZXhlY3V0b3IpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhpcyBGb2xkZXIuIDxwPgorICAgICAqCisgICAgICogVGhpcyBtZXRob2QgY2FuIGJlIGludm9rZWQgb24gYSBjbG9zZWQgRm9sZGVyLgorICAgICAqCisgICAgICogQHJldHVybgkJbmFtZSBvZiB0aGUgRm9sZGVyCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IFN0cmluZyBnZXROYW1lKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBmdWxsIG5hbWUgb2YgdGhpcyBGb2xkZXIuIElmIHRoZSBmb2xkZXIgcmVzaWRlcyB1bmRlcgorICAgICAqIHRoZSByb290IGhpZXJhcmNoeSBvZiB0aGlzIFN0b3JlLCB0aGUgcmV0dXJuZWQgbmFtZSBpcyByZWxhdGl2ZQorICAgICAqIHRvIHRoZSByb290LiBPdGhlcndpc2UgYW4gYWJzb2x1dGUgbmFtZSwgc3RhcnRpbmcgd2l0aCB0aGUgCisgICAgICogaGllcmFyY2h5IGRlbGltaXRlciwgaXMgcmV0dXJuZWQuIDxwPgorICAgICAqCisgICAgICogVGhpcyBtZXRob2QgY2FuIGJlIGludm9rZWQgb24gYSBjbG9zZWQgRm9sZGVyLgorICAgICAqCisgICAgICogQHJldHVybgkJZnVsbCBuYW1lIG9mIHRoZSBGb2xkZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGdldEZ1bGxOYW1lKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYSBVUkxOYW1lIHJlcHJlc2VudGluZyB0aGlzIGZvbGRlci4gIFRoZSByZXR1cm5lZCBVUkxOYW1lCisgICAgICogZG9lcyA8ZW0+bm90PC9lbT4gaW5jbHVkZSB0aGUgcGFzc3dvcmQgdXNlZCB0byBhY2Nlc3MgdGhlIHN0b3JlLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgVVJMTmFtZSByZXByZXNlbnRpbmcgdGhpcyBmb2xkZXIKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKiBAc2VlCVVSTE5hbWUKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS4xCisgICAgICovCisgICAgcHVibGljIFVSTE5hbWUgZ2V0VVJMTmFtZSgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCVVSTE5hbWUgc3RvcmVVUkwgPSBnZXRTdG9yZSgpLmdldFVSTE5hbWUoKTsKKwlTdHJpbmcgZnVsbG5hbWUgPSBnZXRGdWxsTmFtZSgpOworCVN0cmluZ0J1aWxkZXIgZW5jb2RlZE5hbWUgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworCisJaWYgKGZ1bGxuYW1lICE9IG51bGwpIHsKKwkgICAgLyoKKwkgICAgLy8gV2UgbmVlZCB0byBlbmNvZGUgZWFjaCBvZiB0aGUgZm9sZGVyJ3MgbmFtZXMuCisJICAgIGNoYXIgc2VwYXJhdG9yID0gZ2V0U2VwYXJhdG9yKCk7CisJICAgIFN0cmluZ1Rva2VuaXplciB0b2sgPSBuZXcgU3RyaW5nVG9rZW5pemVyKAorCQlmdWxsbmFtZSwgbmV3IENoYXJhY3RlcihzZXBhcmF0b3IpLnRvU3RyaW5nKCksIHRydWUpOworCisJICAgIHdoaWxlICh0b2suaGFzTW9yZVRva2VucygpKSB7CisJCVN0cmluZyBzID0gdG9rLm5leHRUb2tlbigpOworCQlpZiAocy5jaGFyQXQoMCkgPT0gc2VwYXJhdG9yKQorCQkgICAgZW5jb2RlZE5hbWUuYXBwZW5kKHNlcGFyYXRvcik7CisJCWVsc2UKKwkJICAgIC8vIFhYWCAtIHNob3VsZCBlbmNvZGUsIGJ1dCBzaW5jZSB0aGVyZSdzIG5vIGRlY29kZXIuLi4KKwkJICAgIC8vZW5jb2RlZE5hbWUuYXBwZW5kKGphdmEubmV0LlVSTEVuY29kZXIuZW5jb2RlKHMpKTsKKwkJICAgIGVuY29kZWROYW1lLmFwcGVuZChzKTsKKwkgICAgfQorCSAgICAqLworCSAgICAvLyBhcHBlbmQgdGhlIHdob2xlIHRoaW5nLCB1bnRpbCB3ZSBjYW4gZW5jb2RlCisJICAgIGVuY29kZWROYW1lLmFwcGVuZChmdWxsbmFtZSk7CisJfQorCisJLyoKKwkgKiBTdXJlIHdvdWxkIGJlIGNvbnZlbmllbnQgaWYgVVJMTmFtZSBoYWQgYQorCSAqIGNvbnN0cnVjdG9yIHRoYXQgdG9vayBhIGJhc2UgVVJMTmFtZS4KKwkgKi8KKwlyZXR1cm4gbmV3IFVSTE5hbWUoc3RvcmVVUkwuZ2V0UHJvdG9jb2woKSwgc3RvcmVVUkwuZ2V0SG9zdCgpLAorCQkJICAgIHN0b3JlVVJMLmdldFBvcnQoKSwgZW5jb2RlZE5hbWUudG9TdHJpbmcoKSwKKwkJCSAgICBzdG9yZVVSTC5nZXRVc2VybmFtZSgpLAorCQkJICAgIG51bGwgLyogbm8gcGFzc3dvcmQgKi8pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIFN0b3JlIHRoYXQgb3ducyB0aGlzIEZvbGRlciBvYmplY3QuCisgICAgICogVGhpcyBtZXRob2QgY2FuIGJlIGludm9rZWQgb24gYSBjbG9zZWQgRm9sZGVyLgorICAgICAqCisgICAgICogQHJldHVybiAJCXRoZSBTdG9yZQorICAgICAqLworICAgIHB1YmxpYyBTdG9yZSBnZXRTdG9yZSgpIHsKKwlyZXR1cm4gc3RvcmU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgcGFyZW50IGZvbGRlciBvZiB0aGlzIGZvbGRlci4KKyAgICAgKiBUaGlzIG1ldGhvZCBjYW4gYmUgaW52b2tlZCBvbiBhIGNsb3NlZCBGb2xkZXIuIElmIHRoaXMgZm9sZGVyCisgICAgICogaXMgdGhlIHRvcCBvZiBhIGZvbGRlciBoaWVyYXJjaHksIHRoaXMgbWV0aG9kIHJldHVybnMgbnVsbC4gPHA+CisgICAgICoKKyAgICAgKiBOb3RlIHRoYXQgc2luY2UgRm9sZGVyIG9iamVjdHMgYXJlIG5vdCBjYWNoZWQsIGludm9raW5nIHRoaXMgbWV0aG9kCisgICAgICogcmV0dXJucyBhIG5ldyBkaXN0aW5jdCBGb2xkZXIgb2JqZWN0LgorICAgICAqCisgICAgICogQHJldHVybgkJUGFyZW50IGZvbGRlcgorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBGb2xkZXIgZ2V0UGFyZW50KCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFRlc3RzIGlmIHRoaXMgZm9sZGVyIHBoeXNpY2FsbHkgZXhpc3RzIG9uIHRoZSBTdG9yZS4KKyAgICAgKiBUaGlzIG1ldGhvZCBjYW4gYmUgaW52b2tlZCBvbiBhIGNsb3NlZCBGb2xkZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGZvbGRlciBleGlzdHMsIG90aGVyd2lzZSBmYWxzZQorICAgICAqIEBzZWUgICAgI2NyZWF0ZQorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIHR5cGljYWxseSBpZiB0aGUgY29ubmVjdGlvbiAKKyAgICAgKgkJCXRvIHRoZSBzZXJ2ZXIgaXMgbG9zdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBleGlzdHMoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGxpc3Qgb2YgRm9sZGVycyBiZWxvbmdpbmcgdG8gdGhpcyBGb2xkZXIncyBuYW1lc3BhY2UKKyAgICAgKiB0aGF0IG1hdGNoIHRoZSBzcGVjaWZpZWQgcGF0dGVybi4gUGF0dGVybnMgbWF5IGNvbnRhaW4gdGhlIHdpbGRjYXJkCisgICAgICogY2hhcmFjdGVycyA8Y29kZT4iJSI8L2NvZGU+LCB3aGljaCBtYXRjaGVzIGFueSBjaGFyYWN0ZXIgZXhjZXB0IGhpZXJhcmNoeQorICAgICAqIGRlbGltaXRlcnMsIGFuZCA8Y29kZT4iKiI8L2NvZGU+LCB3aGljaCBtYXRjaGVzIGFueSBjaGFyYWN0ZXIuIDxwPgorICAgICAqCisgICAgICogQXMgYW4gZXhhbXBsZSwgZ2l2ZW4gdGhlIGZvbGRlciBoaWVyYXJjaHk6IDxwcmU+CisgICAgICogICAgUGVyc29uYWwvCisgICAgICogICAgICAgRmluYW5jZS8KKyAgICAgKiAgICAgICAgICBTdG9ja3MKKyAgICAgKiAgICAgICAgICBCb251cworICAgICAqICAgICAgICAgIFN0b2NrT3B0aW9ucworICAgICAqICAgICAgIEpva2VzCisgICAgICogPC9wcmU+CisgICAgICogPGNvZGU+bGlzdCgiKiIpPC9jb2RlPiBvbiAiUGVyc29uYWwiIHdpbGwgcmV0dXJuIHRoZSB3aG9sZSAKKyAgICAgKiBoaWVyYXJjaHkuIDxicj4KKyAgICAgKiA8Y29kZT5saXN0KCIlIik8L2NvZGU+IG9uICJQZXJzb25hbCIgd2lsbCByZXR1cm4gIkZpbmFuY2UiIGFuZCAKKyAgICAgKiAiSm9rZXMiLiA8YnI+CisgICAgICogPGNvZGU+bGlzdCgiSm9rZXMiKTwvY29kZT4gb24gIlBlcnNvbmFsIiB3aWxsIHJldHVybiAiSm9rZXMiLjxicj4KKyAgICAgKiA8Y29kZT5saXN0KCJTdG9jayoiKTwvY29kZT4gb24gIkZpbmFuY2UiIHdpbGwgcmV0dXJuICJTdG9ja3MiCisgICAgICogYW5kICJTdG9ja09wdGlvbnMiLiA8cD4KKyAgICAgKgorICAgICAqIEZvbGRlciBvYmplY3RzIGFyZSBub3QgY2FjaGVkIGJ5IHRoZSBTdG9yZSwgc28gaW52b2tpbmcgdGhpcworICAgICAqIG1ldGhvZCBvbiB0aGUgc2FtZSBwYXR0ZXJuIG11bHRpcGxlIHRpbWVzIHdpbGwgcmV0dXJuIHRoYXQgbWFueQorICAgICAqIGRpc3RpbmN0IEZvbGRlciBvYmplY3RzLiA8cD4KKyAgICAgKgorICAgICAqIFRoaXMgbWV0aG9kIGNhbiBiZSBpbnZva2VkIG9uIGEgY2xvc2VkIEZvbGRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXR0ZXJuCXRoZSBtYXRjaCBwYXR0ZXJuCisgICAgICogQHJldHVybgkJYXJyYXkgb2YgbWF0Y2hpbmcgRm9sZGVyIG9iamVjdHMuIEFuIGVtcHR5CisgICAgICoJCQlhcnJheSBpcyByZXR1cm5lZCBpZiBubyBtYXRjaGluZyBGb2xkZXJzIGV4aXN0LgorICAgICAqIEBzZWUgCQkjbGlzdFN1YnNjcmliZWQKKyAgICAgKiBAZXhjZXB0aW9uIAlGb2xkZXJOb3RGb3VuZEV4Y2VwdGlvbiBpZiB0aGlzIGZvbGRlciBkb2VzIAorICAgICAqCQkJbm90IGV4aXN0LgorICAgICAqIEBleGNlcHRpb24gCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgRm9sZGVyW10gbGlzdChTdHJpbmcgcGF0dGVybikgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBsaXN0IG9mIHN1YnNjcmliZWQgRm9sZGVycyBiZWxvbmdpbmcgdG8gdGhpcyBGb2xkZXIncworICAgICAqIG5hbWVzcGFjZSB0aGF0IG1hdGNoIHRoZSBzcGVjaWZpZWQgcGF0dGVybi4gSWYgdGhlIGZvbGRlciBkb2VzCisgICAgICogbm90IHN1cHBvcnQgc3Vic2NyaXB0aW9uLCB0aGlzIG1ldGhvZCBzaG91bGQgcmVzb2x2ZSB0bworICAgICAqIDxjb2RlPmxpc3Q8L2NvZGU+LgorICAgICAqIChUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBwcm92aWRlZCBoZXJlLCBkb2VzIGp1c3QgdGhpcykuCisgICAgICogVGhlIHBhdHRlcm4gY2FuIGNvbnRhaW4gd2lsZGNhcmRzIGFzIGZvciA8Y29kZT5saXN0PC9jb2RlPi4gPHA+CisgICAgICoKKyAgICAgKiBOb3RlIHRoYXQsIGF0IGEgZ2l2ZW4gbGV2ZWwgb2YgdGhlIGZvbGRlciBoaWVyYXJjaHksIGEgcGFydGljdWxhcgorICAgICAqIGZvbGRlciBtYXkgbm90IGJlIHN1YnNjcmliZWQsIGJ1dCBmb2xkZXJzIHVuZGVybmVhdGggdGhhdCBmb2xkZXIKKyAgICAgKiBpbiB0aGUgZm9sZGVyIGhpZXJhcmNoeSBtYXkgYmUgc3Vic2NyaWJlZC4gIEluIG9yZGVyIHRvIGFsbG93CisgICAgICogd2Fsa2luZyB0aGUgZm9sZGVyIGhpZXJhcmNoeSwgc3VjaCB1bnN1YnNjcmliZWQgZm9sZGVycyBtYXkgYmUKKyAgICAgKiByZXR1cm5lZCwgaW5kaWNhdGluZyB0aGF0IGEgZm9sZGVyIGxvd2VyIGluIHRoZSBoaWVyYXJjaHkgaXMKKyAgICAgKiBzdWJzY3JpYmVkLiAgVGhlIDxjb2RlPmlzU3Vic2NyaWJlZDwvY29kZT4gbWV0aG9kIG9uIGEgZm9sZGVyIHdpbGwKKyAgICAgKiB0ZWxsIHdoZXRoZXIgYW55IHBhcnRpY3VsYXIgZm9sZGVyIGlzIGFjdHVhbGx5IHN1YnNjcmliZWQuIDxwPgorICAgICAqCisgICAgICogRm9sZGVyIG9iamVjdHMgYXJlIG5vdCBjYWNoZWQgYnkgdGhlIFN0b3JlLCBzbyBpbnZva2luZyB0aGlzCisgICAgICogbWV0aG9kIG9uIHRoZSBzYW1lIHBhdHRlcm4gbXVsdGlwbGUgdGltZXMgd2lsbCByZXR1cm4gdGhhdCBtYW55CisgICAgICogZGlzdGluY3QgRm9sZGVyIG9iamVjdHMuIDxwPgorICAgICAqCisgICAgICogVGhpcyBtZXRob2QgY2FuIGJlIGludm9rZWQgb24gYSBjbG9zZWQgRm9sZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIHBhdHRlcm4JdGhlIG1hdGNoIHBhdHRlcm4KKyAgICAgKiBAcmV0dXJuCQlhcnJheSBvZiBtYXRjaGluZyBzdWJzY3JpYmVkIEZvbGRlciBvYmplY3RzLiBBbgorICAgICAqCQkJZW1wdHkgYXJyYXkgaXMgcmV0dXJuZWQgaWYgbm8gbWF0Y2hpbmcKKyAgICAgKgkJCXN1YnNjcmliZWQgZm9sZGVycyBleGlzdC4KKyAgICAgKiBAc2VlIAkJI2xpc3QKKyAgICAgKiBAZXhjZXB0aW9uIAlGb2xkZXJOb3RGb3VuZEV4Y2VwdGlvbiBpZiB0aGlzIGZvbGRlciBkb2VzCisgICAgICoJCQlub3QgZXhpc3QuCisgICAgICogQGV4Y2VwdGlvbiAJTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBvdGhlciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBGb2xkZXJbXSBsaXN0U3Vic2NyaWJlZChTdHJpbmcgcGF0dGVybikgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJcmV0dXJuIGxpc3QocGF0dGVybik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVuaWVuY2UgbWV0aG9kIHRoYXQgcmV0dXJucyB0aGUgbGlzdCBvZiBmb2xkZXJzIHVuZGVyIHRoaXMKKyAgICAgKiBGb2xkZXIuIFRoaXMgbWV0aG9kIGp1c3QgY2FsbHMgdGhlIDxjb2RlPmxpc3QoU3RyaW5nIHBhdHRlcm4pPC9jb2RlPgorICAgICAqIG1ldGhvZCB3aXRoIDxjb2RlPiIlIjwvY29kZT4gYXMgdGhlIG1hdGNoIHBhdHRlcm4uIFRoaXMgbWV0aG9kIGNhbgorICAgICAqIGJlIGludm9rZWQgb24gYSBjbG9zZWQgRm9sZGVyLgorICAgICAqCisgICAgICogQHJldHVybgkJYXJyYXkgb2YgRm9sZGVyIG9iamVjdHMgdW5kZXIgdGhpcyBGb2xkZXIuIEFuCisgICAgICoJCQllbXB0eSBhcnJheSBpcyByZXR1cm5lZCBpZiBubyBzdWJmb2xkZXJzIGV4aXN0LgorICAgICAqIEBzZWUJCSNsaXN0CisgICAgICogQGV4Y2VwdGlvbiAJRm9sZGVyTm90Rm91bmRFeGNlcHRpb24gaWYgdGhpcyBmb2xkZXIgZG9lcworICAgICAqCQkJbm90IGV4aXN0LgorICAgICAqIEBleGNlcHRpb24gCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKi8KKworICAgIHB1YmxpYyBGb2xkZXJbXSBsaXN0KCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJcmV0dXJuIGxpc3QoIiUiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZW5pZW5jZSBtZXRob2QgdGhhdCByZXR1cm5zIHRoZSBsaXN0IG9mIHN1YnNjcmliZWQgZm9sZGVycyAKKyAgICAgKiB1bmRlciB0aGlzIEZvbGRlci4gVGhpcyBtZXRob2QganVzdCBjYWxscyB0aGUKKyAgICAgKiA8Y29kZT5saXN0U3Vic2NyaWJlZChTdHJpbmcgcGF0dGVybik8L2NvZGU+IG1ldGhvZCB3aXRoIDxjb2RlPiIlIjwvY29kZT4KKyAgICAgKiBhcyB0aGUgbWF0Y2ggcGF0dGVybi4gVGhpcyBtZXRob2QgY2FuIGJlIGludm9rZWQgb24gYSBjbG9zZWQgRm9sZGVyLgorICAgICAqCisgICAgICogQHJldHVybgkJYXJyYXkgb2Ygc3Vic2NyaWJlZCBGb2xkZXIgb2JqZWN0cyB1bmRlciB0aGlzIAorICAgICAqCQkJRm9sZGVyLiBBbiBlbXB0eSBhcnJheSBpcyByZXR1cm5lZCBpZiBubyBzdWJzY3JpYmVkIAorICAgICAqCQkJc3ViZm9sZGVycyBleGlzdC4KKyAgICAgKiBAc2VlCQkjbGlzdFN1YnNjcmliZWQKKyAgICAgKiBAZXhjZXB0aW9uIAlGb2xkZXJOb3RGb3VuZEV4Y2VwdGlvbiBpZiB0aGlzIGZvbGRlciBkb2VzCisgICAgICoJCQlub3QgZXhpc3QuCisgICAgICogQGV4Y2VwdGlvbiAJTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBvdGhlciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBGb2xkZXJbXSBsaXN0U3Vic2NyaWJlZCgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXJldHVybiBsaXN0U3Vic2NyaWJlZCgiJSIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgZGVsaW1pdGVyIGNoYXJhY3RlciB0aGF0IHNlcGFyYXRlcyB0aGlzIEZvbGRlcidzIHBhdGhuYW1lCisgICAgICogZnJvbSB0aGUgbmFtZXMgb2YgaW1tZWRpYXRlIHN1YmZvbGRlcnMuIFRoaXMgbWV0aG9kIGNhbiBiZSBpbnZva2VkIAorICAgICAqIG9uIGEgY2xvc2VkIEZvbGRlci4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24gCUZvbGRlck5vdEZvdW5kRXhjZXB0aW9uIGlmIHRoZSBpbXBsZW1lbnRhdGlvbgorICAgICAqCQkJcmVxdWlyZXMgdGhlIGZvbGRlciB0byBleGlzdCwgYnV0IGl0IGRvZXMgbm90CisgICAgICogQHJldHVybiAgICAgICAgICBIaWVyYXJjaHkgc2VwYXJhdG9yIGNoYXJhY3RlcgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBjaGFyIGdldFNlcGFyYXRvcigpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBUaGlzIGZvbGRlciBjYW4gY29udGFpbiBtZXNzYWdlcworICAgICAqLworICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IEhPTERTX01FU1NBR0VTID0gMHgwMTsKKworICAgIC8qKgorICAgICAqIFRoaXMgZm9sZGVyIGNhbiBjb250YWluIG90aGVyIGZvbGRlcnMKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgc3RhdGljIGludCBIT0xEU19GT0xERVJTICA9IDB4MDI7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB0eXBlIG9mIHRoaXMgRm9sZGVyLCB0aGF0IGlzLCB3aGV0aGVyIHRoaXMgZm9sZGVyIGNhbiBob2xkCisgICAgICogbWVzc2FnZXMgb3Igc3ViZm9sZGVycyBvciBib3RoLiBUaGUgcmV0dXJuZWQgdmFsdWUgaXMgYW4gaW50ZWdlcgorICAgICAqIGJpdGZpZWxkIHdpdGggdGhlIGFwcHJvcHJpYXRlIGJpdHMgc2V0LiBUaGlzIG1ldGhvZCBjYW4gYmUgaW52b2tlZAorICAgICAqIG9uIGEgY2xvc2VkIGZvbGRlci4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIAkJaW50ZWdlciB3aXRoIGFwcHJvcHJpYXRlIGJpdHMgc2V0CisgICAgICogQGV4Y2VwdGlvbiAJRm9sZGVyTm90Rm91bmRFeGNlcHRpb24gaWYgdGhpcyBmb2xkZXIgZG9lcyAKKyAgICAgKgkJCW5vdCBleGlzdC4KKyAgICAgKiBAc2VlIAkJI0hPTERTX0ZPTERFUlMgCisgICAgICogQHNlZQkJI0hPTERTX01FU1NBR0VTCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGludCBnZXRUeXBlKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbjsgCisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgdGhpcyBmb2xkZXIgb24gdGhlIFN0b3JlLiBXaGVuIHRoaXMgZm9sZGVyIGlzIGNyZWF0ZWQsIGFueQorICAgICAqIGZvbGRlcnMgaW4gaXRzIHBhdGggdGhhdCBkbyBub3QgZXhpc3QgYXJlIGFsc28gY3JlYXRlZC4gPHA+CisgICAgICoKKyAgICAgKiBJZiB0aGUgY3JlYXRpb24gaXMgc3VjY2Vzc2Z1bCwgYSBDUkVBVEVEIEZvbGRlckV2ZW50IGlzIGRlbGl2ZXJlZAorICAgICAqIHRvIGFueSBGb2xkZXJMaXN0ZW5lcnMgcmVnaXN0ZXJlZCBvbiB0aGlzIEZvbGRlciBhbmQgdGhpcyBTdG9yZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSAgdHlwZQlUaGUgdHlwZSBvZiB0aGlzIGZvbGRlci4gCisgICAgICoKKyAgICAgKiBAcmV0dXJuCQl0cnVlIGlmIHRoZSBjcmVhdGlvbiBzdWNjZWVkcywgZWxzZSBmYWxzZS4KKyAgICAgKiBAZXhjZXB0aW9uIAlNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICogQHNlZSAJCSNIT0xEU19GT0xERVJTCisgICAgICogQHNlZQkJI0hPTERTX01FU1NBR0VTCisgICAgICogQHNlZQkJamF2YXgubWFpbC5ldmVudC5Gb2xkZXJFdmVudAorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGNyZWF0ZShpbnQgdHlwZSkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIEZvbGRlciBpcyBzdWJzY3JpYmVkLiA8cD4KKyAgICAgKgorICAgICAqIFRoaXMgbWV0aG9kIGNhbiBiZSBpbnZva2VkIG9uIGEgY2xvc2VkIEZvbGRlci4gPHA+CisgICAgICoKKyAgICAgKiBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBwcm92aWRlZCBoZXJlIGp1c3QgcmV0dXJucyB0cnVlLgorICAgICAqCisgICAgICogQHJldHVybgkJdHJ1ZSBpZiB0aGlzIEZvbGRlciBpcyBzdWJzY3JpYmVkCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNTdWJzY3JpYmVkKCkgeworCXJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFN1YnNjcmliZSBvciB1bnN1YnNjcmliZSB0aGlzIEZvbGRlci4gTm90IGFsbCBTdG9yZXMgc3VwcG9ydAorICAgICAqIHN1YnNjcmlwdGlvbi4gPHA+CisgICAgICoKKyAgICAgKiBUaGlzIG1ldGhvZCBjYW4gYmUgaW52b2tlZCBvbiBhIGNsb3NlZCBGb2xkZXIuIDxwPgorICAgICAqCisgICAgICogVGhlIGltcGxlbWVudGF0aW9uIHByb3ZpZGVkIGhlcmUganVzdCB0aHJvd3MgdGhlCisgICAgICogTWV0aG9kTm90U3VwcG9ydGVkRXhjZXB0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIHN1YnNjcmliZQl0cnVlIHRvIHN1YnNjcmliZSwgZmFsc2UgdG8gdW5zdWJzY3JpYmUKKyAgICAgKiBAZXhjZXB0aW9uIAlGb2xkZXJOb3RGb3VuZEV4Y2VwdGlvbiBpZiB0aGlzIGZvbGRlciBkb2VzCisgICAgICoJCQlub3QgZXhpc3QuCisgICAgICogQGV4Y2VwdGlvbiAJTWV0aG9kTm90U3VwcG9ydGVkRXhjZXB0aW9uIGlmIHRoaXMgc3RvcmUKKyAgICAgKgkJCWRvZXMgbm90IHN1cHBvcnQgc3Vic2NyaXB0aW9uCisgICAgICogQGV4Y2VwdGlvbiAJTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBvdGhlciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFN1YnNjcmliZWQoYm9vbGVhbiBzdWJzY3JpYmUpIAorCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJdGhyb3cgbmV3IE1ldGhvZE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIEZvbGRlciBoYXMgbmV3IG1lc3NhZ2VzIHNpbmNlIHRoZSBsYXN0IHRpbWUKKyAgICAgKiB0aGlzIGluZGljYXRpb24gd2FzIHJlc2V0LiAgV2hlbiB0aGlzIGluZGljYXRpb24gaXMgc2V0IG9yIHJlc2V0CisgICAgICogZGVwZW5kcyBvbiB0aGUgRm9sZGVyIGltcGxlbWVudGF0aW9uIChhbmQgaW4gdGhlIGNhc2Ugb2YgSU1BUCwKKyAgICAgKiBkZXBlbmRzIG9uIHRoZSBzZXJ2ZXIpLiAgVGhpcyBtZXRob2QgY2FuIGJlIHVzZWQgdG8gaW1wbGVtZW50CisgICAgICogYSBsaWdodHdlaWdodCAiY2hlY2sgZm9yIG5ldyBtYWlsIiBvcGVyYXRpb24gb24gYSBGb2xkZXIgd2l0aG91dAorICAgICAqIG9wZW5pbmcgaXQuICAoRm9yIGV4YW1wbGUsIGEgdGhyZWFkIHRoYXQgbW9uaXRvcnMgYSBtYWlsYm94IGFuZAorICAgICAqIGZsYWdzIHdoZW4gaXQgaGFzIG5ldyBtYWlsLikgIFRoaXMgbWV0aG9kIHNob3VsZCBpbmRpY2F0ZSB3aGV0aGVyCisgICAgICogYW55IG1lc3NhZ2VzIGluIHRoZSBGb2xkZXIgaGF2ZSB0aGUgPGNvZGU+UkVDRU5UPC9jb2RlPiBmbGFnIHNldC4gPHA+CisgICAgICoKKyAgICAgKiBOb3RlIHRoYXQgdGhpcyBpcyBub3QgYW4gaW5jcmVtZW50YWwgY2hlY2sgZm9yIG5ldyBtYWlsLCBpLmUuLAorICAgICAqIGl0IGNhbm5vdCBiZSB1c2VkIHRvIGRldGVybWluZSB3aGV0aGVyIGFueSBuZXcgbWVzc2FnZXMgaGF2ZQorICAgICAqIGFycml2ZWQgc2luY2UgdGhlIGxhc3QgdGltZSB0aGlzIG1ldGhvZCB3YXMgaW52b2tlZC4gVG8KKyAgICAgKiBpbXBsZW1lbnQgaW5jcmVtZW50YWwgY2hlY2tzLCB0aGUgRm9sZGVyIG5lZWRzIHRvIGJlIG9wZW5lZC4gPHA+CisgICAgICoKKyAgICAgKiBUaGlzIG1ldGhvZCBjYW4gYmUgaW52b2tlZCBvbiBhIGNsb3NlZCBGb2xkZXIgdGhhdCBjYW4gY29udGFpbgorICAgICAqIE1lc3NhZ2VzLgorICAgICAqCisgICAgICogQHJldHVybgkJdHJ1ZSBpZiB0aGUgU3RvcmUgaGFzIG5ldyBNZXNzYWdlcworICAgICAqIEBleGNlcHRpb24JRm9sZGVyTm90Rm91bmRFeGNlcHRpb24gaWYgdGhpcyBmb2xkZXIgZG9lcworICAgICAqCQkJbm90IGV4aXN0LgorICAgICAqIEBleGNlcHRpb24gCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBoYXNOZXdNZXNzYWdlcygpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIEZvbGRlciBvYmplY3QgY29ycmVzcG9uZGluZyB0byB0aGUgZ2l2ZW4gbmFtZS4gTm90ZSB0aGF0CisgICAgICogdGhpcyBmb2xkZXIgZG9lcyBub3QgcGh5c2ljYWxseSBoYXZlIHRvIGV4aXN0IGluIHRoZSBTdG9yZS4gVGhlCisgICAgICogPGNvZGU+ZXhpc3RzKCk8L2NvZGU+IG1ldGhvZCBvbiBhIEZvbGRlciBpbmRpY2F0ZXMgd2hldGhlciBpdCByZWFsbHkKKyAgICAgKiBleGlzdHMgb24gdGhlIFN0b3JlLiA8cD4KKyAgICAgKgorICAgICAqIEluIHNvbWUgU3RvcmVzLCBuYW1lIGNhbiBiZSBhbiBhYnNvbHV0ZSBwYXRoIGlmIGl0IHN0YXJ0cyB3aXRoIHRoZQorICAgICAqIGhpZXJhcmNoeSBkZWxpbWl0ZXIuICBPdGhlcndpc2UsIGl0IGlzIGludGVycHJldGVkIHJlbGF0aXZlIHRvCisgICAgICogdGhpcyBGb2xkZXIuIDxwPgorICAgICAqCisgICAgICogRm9sZGVyIG9iamVjdHMgYXJlIG5vdCBjYWNoZWQgYnkgdGhlIFN0b3JlLCBzbyBpbnZva2luZyB0aGlzCisgICAgICogbWV0aG9kIG9uIHRoZSBzYW1lIG5hbWUgbXVsdGlwbGUgdGltZXMgd2lsbCByZXR1cm4gdGhhdCBtYW55CisgICAgICogZGlzdGluY3QgRm9sZGVyIG9iamVjdHMuIDxwPgorICAgICAqCisgICAgICogVGhpcyBtZXRob2QgY2FuIGJlIGludm9rZWQgb24gYSBjbG9zZWQgRm9sZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgCW5hbWUgb2YgdGhlIEZvbGRlcgorICAgICAqIEByZXR1cm4JCUZvbGRlciBvYmplY3QKKyAgICAgKiBAZXhjZXB0aW9uIAlNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEZvbGRlciBnZXRGb2xkZXIoU3RyaW5nIG5hbWUpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIERlbGV0ZSB0aGlzIEZvbGRlci4gVGhpcyBtZXRob2Qgd2lsbCBzdWNjZWVkIG9ubHkgb24gYSBjbG9zZWQKKyAgICAgKiBGb2xkZXIuIDxwPgorICAgICAqCisgICAgICogVGhlIDxjb2RlPnJlY3Vyc2U8L2NvZGU+IGZsYWcgY29udHJvbHMgd2hldGhlciB0aGUgZGVsZXRpb24gYWZmZWN0cworICAgICAqIHN1YmZvbGRlcnMgb3Igbm90LiBJZiB0cnVlLCBhbGwgc3ViZm9sZGVycyBhcmUgZGVsZXRlZCwgdGhlbiB0aGlzCisgICAgICogZm9sZGVyIGl0c2VsZiBpcyBkZWxldGVkLiBJZiBmYWxzZSwgdGhlIGJlaGF2aW91ciBpcyBkZXBlbmRlbnQgb24KKyAgICAgKiB0aGUgZm9sZGVyIHR5cGUgYW5kIGlzIGVsYWJvcmF0ZWQgYmVsb3c6CisgICAgICoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPgorICAgICAqIFRoZSBmb2xkZXIgY2FuIGNvbnRhaW4gb25seSBtZXNzYWdlczogKHR5cGUgPT0gSE9MRFNfTUVTU0FHRVMpLgorICAgICAqIDxicj4KKyAgICAgKiBBbGwgbWVzc2FnZXMgd2l0aGluIHRoZSBmb2xkZXIgYXJlIHJlbW92ZWQuIFRoZSBmb2xkZXIgCisgICAgICogaXRzZWxmIGlzIHRoZW4gcmVtb3ZlZC4gQW4gYXBwcm9wcmlhdGUgRm9sZGVyRXZlbnQgaXMgZ2VuZXJhdGVkIGJ5IAorICAgICAqIHRoZSBTdG9yZSBhbmQgdGhpcyBmb2xkZXIuCisgICAgICoKKyAgICAgKiA8bGk+CisgICAgICogVGhlIGZvbGRlciBjYW4gY29udGFpbiBvbmx5IHN1YmZvbGRlcnM6ICh0eXBlID09IEhPTERTX0ZPTERFUlMpLgorICAgICAqIDxicj4KKyAgICAgKiBJZiB0aGlzIGZvbGRlciBpcyBlbXB0eSAoZG9lcyBub3QgY29udGFpbiBhbnkgCisgICAgICogc3ViZm9sZGVycyBhdCBhbGwpLCBpdCBpcyByZW1vdmVkLiBBbiBhcHByb3ByaWF0ZSBGb2xkZXJFdmVudCBpcyAKKyAgICAgKiBnZW5lcmF0ZWQgYnkgdGhlIFN0b3JlIGFuZCB0aGlzIGZvbGRlci48YnI+CisgICAgICogSWYgdGhpcyBmb2xkZXIgY29udGFpbnMgYW55IHN1YmZvbGRlcnMsIHRoZSBkZWxldGUgZmFpbHMgCisgICAgICogYW5kIHJldHVybnMgZmFsc2UuCisgICAgICoKKyAgICAgKiA8bGk+CisgICAgICogVGhlIGZvbGRlciBjYW4gY29udGFpbiBzdWJmb2xkZXJzIGFzIHdlbGwgYXMgbWVzc2FnZXM6IDxicj4KKyAgICAgKiBJZiB0aGUgZm9sZGVyIGlzIGVtcHR5IChubyBtZXNzYWdlcyBvciBzdWJmb2xkZXJzKSwgaXQKKyAgICAgKiBpcyByZW1vdmVkLiBJZiB0aGUgZm9sZGVyIGNvbnRhaW5zIG5vIHN1YmZvbGRlcnMsIGJ1dCBvbmx5IG1lc3NhZ2VzLAorICAgICAqIHRoZW4gYWxsIG1lc3NhZ2VzIGFyZSByZW1vdmVkLiBUaGUgZm9sZGVyIGl0c2VsZiBpcyB0aGVuIHJlbW92ZWQuCisgICAgICogSW4gYm90aCB0aGUgYWJvdmUgY2FzZXMsIGFuIGFwcHJvcHJpYXRlIEZvbGRlckV2ZW50IGlzCisgICAgICogZ2VuZXJhdGVkIGJ5IHRoZSBTdG9yZSBhbmQgdGhpcyBmb2xkZXIuIDxwPgorICAgICAqCisgICAgICogSWYgdGhlIGZvbGRlciBjb250YWlucyBzdWJmb2xkZXJzIHRoZXJlIGFyZSAzIHBvc3NpYmxlCisgICAgICogY2hvaWNlcyBhbiBpbXBsZW1lbnRhdGlvbiBpcyBmcmVlIHRvIGRvOgorICAgICAqIAorICAgICAqICA8b2w+CisgICAgICogICA8bGk+IFRoZSBvcGVyYXRpb24gZmFpbHMsIGlycmVzcGVjdGl2ZSBvZiB3aGV0aGVyIHRoaXMgZm9sZGVyCisgICAgICogY29udGFpbnMgbWVzc2FnZXMgb3Igbm90LiBTb21lIGltcGxlbWVudGF0aW9ucyBtaWdodCBlbGVjdCB0byBnbworICAgICAqIHdpdGggdGhpcyBzaW1wbGUgYXBwcm9hY2guIFRoZSBkZWxldGUoKSBtZXRob2QgcmV0dXJucyBmYWxzZS4KKyAgICAgKgorICAgICAqICAgPGxpPiBBbnkgbWVzc2FnZXMgd2l0aGluIHRoZSBmb2xkZXIgYXJlIHJlbW92ZWQuIFN1YmZvbGRlcnMKKyAgICAgKiBhcmUgbm90IHJlbW92ZWQuIFRoZSBmb2xkZXIgaXRzZWxmIGlzIG5vdCByZW1vdmVkIG9yIGFmZmVjdGVkCisgICAgICogaW4gYW55IG1hbm5lci4gVGhlIGRlbGV0ZSgpIG1ldGhvZCByZXR1cm5zIHRydWUuIEFuZCB0aGUgCisgICAgICogZXhpc3RzKCkgbWV0aG9kIG9uIHRoaXMgZm9sZGVyIHdpbGwgcmV0dXJuIHRydWUgaW5kaWNhdGluZyB0aGF0CisgICAgICogdGhpcyBmb2xkZXIgc3RpbGwgZXhpc3RzLiA8YnI+CisgICAgICogQW4gYXBwcm9wcmlhdGUgRm9sZGVyRXZlbnQgaXMgZ2VuZXJhdGVkIGJ5IHRoZSBTdG9yZSBhbmQgdGhpcyBmb2xkZXIuCisgICAgICoKKyAgICAgKiAgIDxsaT4gQW55IG1lc3NhZ2VzIHdpdGhpbiB0aGUgZm9sZGVyIGFyZSByZW1vdmVkLiBTdWJmb2xkZXJzIGFyZQorICAgICAqIG5vdCByZW1vdmVkLiBUaGUgZm9sZGVyIGl0c2VsZiBjaGFuZ2VzIGl0cyB0eXBlIGZyb20gCisgICAgICogSE9MRFNfRk9MREVSUyB8IEhPTERTX01FU1NBR0VTIHRvIEhPTERTX0ZPTERFUlMuIFRodXMgbmV3IAorICAgICAqIG1lc3NhZ2VzIGNhbm5vdCBiZSBhZGRlZCB0byB0aGlzIGZvbGRlciwgYnV0IG5ldyBzdWJmb2xkZXJzIGNhbgorICAgICAqIGJlIGNyZWF0ZWQgdW5kZXJuZWF0aC4gVGhlIGRlbGV0ZSgpIG1ldGhvZCByZXR1cm5zIHRydWUgaW5kaWNhdGluZworICAgICAqIHN1Y2Nlc3MuIFRoZSBleGlzdHMoKSBtZXRob2Qgb24gdGhpcyBmb2xkZXIgd2lsbCByZXR1cm4gdHJ1ZQorICAgICAqIGluZGljYXRpbmcgdGhhdCB0aGlzIGZvbGRlciBzdGlsbCBleGlzdHMuIDxicj4KKyAgICAgKiBBbiBhcHByb3ByaWF0ZSBGb2xkZXJFdmVudCBpcyBnZW5lcmF0ZWQgYnkgdGhlIFN0b3JlIGFuZCB0aGlzIGZvbGRlci4KKyAgICAgKiA8L29sPgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0JcmVjdXJzZQlhbHNvIGRlbGV0ZSBzdWJmb2xkZXJzPworICAgICAqIEByZXR1cm4JCXRydWUgaWYgdGhlIEZvbGRlciBpcyBkZWxldGVkIHN1Y2Nlc3NmdWxseQorICAgICAqIEBleGNlcHRpb24JRm9sZGVyTm90Rm91bmRFeGNlcHRpb24gaWYgdGhpcyBmb2xkZXIgZG9lcyAKKyAgICAgKgkJCW5vdCBleGlzdAorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgZm9sZGVyIGlzIG5vdCBpbiAKKyAgICAgKgkJCXRoZSBjbG9zZWQgc3RhdGUuCisgICAgICogQGV4Y2VwdGlvbiAgICAgICBNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICogQHNlZQkJamF2YXgubWFpbC5ldmVudC5Gb2xkZXJFdmVudAorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGRlbGV0ZShib29sZWFuIHJlY3Vyc2UpIAorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZW5hbWUgdGhpcyBGb2xkZXIuIFRoaXMgbWV0aG9kIHdpbGwgc3VjY2VlZCBvbmx5IG9uIGEgY2xvc2VkCisgICAgICogRm9sZGVyLiA8cD4KKyAgICAgKgorICAgICAqIElmIHRoZSByZW5hbWUgaXMgc3VjY2Vzc2Z1bCwgYSBSRU5BTUVEIEZvbGRlckV2ZW50IGlzIGRlbGl2ZXJlZAorICAgICAqIHRvIEZvbGRlckxpc3RlbmVycyByZWdpc3RlcmVkIG9uIHRoaXMgZm9sZGVyIGFuZCBpdHMgY29udGFpbmluZworICAgICAqIFN0b3JlLgorICAgICAqCisgICAgICogQHBhcmFtIGYJCWEgZm9sZGVyIHJlcHJlc2VudGluZyB0aGUgbmV3IG5hbWUgZm9yIHRoaXMgRm9sZGVyCisgICAgICogQHJldHVybgkJdHJ1ZSBpZiB0aGUgRm9sZGVyIGlzIHJlbmFtZWQgc3VjY2Vzc2Z1bGx5CisgICAgICogQGV4Y2VwdGlvbglGb2xkZXJOb3RGb3VuZEV4Y2VwdGlvbiBpZiB0aGlzIGZvbGRlciBkb2VzIAorICAgICAqCQkJbm90IGV4aXN0CisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBmb2xkZXIgaXMgbm90IGluIAorICAgICAqCQkJdGhlIGNsb3NlZCBzdGF0ZS4KKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIE1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKiBAc2VlCQlqYXZheC5tYWlsLmV2ZW50LkZvbGRlckV2ZW50CisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gcmVuYW1lVG8oRm9sZGVyIGYpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBUaGUgRm9sZGVyIGlzIHJlYWQgb25seS4gIFRoZSBzdGF0ZSBhbmQgY29udGVudHMgb2YgdGhpcworICAgICAqIGZvbGRlciBjYW5ub3QgYmUgbW9kaWZpZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVBRF9PTkxZIAk9IDE7CisKKyAgICAvKioKKyAgICAgKiBUaGUgc3RhdGUgYW5kIGNvbnRlbnRzIG9mIHRoaXMgZm9sZGVyIGNhbiBiZSBtb2RpZmllZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRUFEX1dSSVRFIAk9IDI7CisKKyAgICAvKioKKyAgICAgKiBPcGVuIHRoaXMgRm9sZGVyLiBUaGlzIG1ldGhvZCBpcyB2YWxpZCBvbmx5IG9uIEZvbGRlcnMgdGhhdAorICAgICAqIGNhbiBjb250YWluIE1lc3NhZ2VzIGFuZCB0aGF0IGFyZSBjbG9zZWQuIDxwPgorICAgICAqCisgICAgICogSWYgdGhpcyBmb2xkZXIgaXMgb3BlbmVkIHN1Y2Nlc3NmdWxseSwgYW4gT1BFTkVEIENvbm5lY3Rpb25FdmVudAorICAgICAqIGlzIGRlbGl2ZXJlZCB0byBhbnkgQ29ubmVjdGlvbkxpc3RlbmVycyByZWdpc3RlcmVkIG9uIHRoaXMgCisgICAgICogRm9sZGVyLiA8cD4KKyAgICAgKgorICAgICAqIFRoZSBlZmZlY3Qgb2Ygb3BlbmluZyBtdWx0aXBsZSBjb25uZWN0aW9ucyB0byB0aGUgc2FtZSBmb2xkZXIKKyAgICAgKiBvbiBhIHNwZWNpZmMgU3RvcmUgaXMgaW1wbGVtZW50YXRpb24gZGVwZW5kZW50LiBTb21lIGltcGxlbWVudGF0aW9ucworICAgICAqIGFsbG93IG11bHRpcGxlIHJlYWRlcnMsIGJ1dCBvbmx5IG9uZSB3cml0ZXIuIE90aGVycyBhbGxvdworICAgICAqIG11bHRpcGxlIHdyaXRlcnMgYXMgd2VsbCBhcyByZWFkZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIG1vZGUJb3BlbiB0aGUgRm9sZGVyIFJFQURfT05MWSBvciBSRUFEX1dSSVRFCisgICAgICogQGV4Y2VwdGlvbglGb2xkZXJOb3RGb3VuZEV4Y2VwdGlvbiBpZiB0aGlzIGZvbGRlciBkb2VzIAorICAgICAqCQkJbm90IGV4aXN0LgorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgZm9sZGVyIGlzIG5vdCBpbiAKKyAgICAgKgkJCXRoZSBjbG9zZWQgc3RhdGUuCisgICAgICogQGV4Y2VwdGlvbiAgICAgICBNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICogQHNlZSAJCSNSRUFEX09OTFkKKyAgICAgKiBAc2VlIAkJI1JFQURfV1JJVEUKKyAgICAgKiBAc2VlIAkJI2dldFR5cGUoKQorICAgICAqIEBzZWUgCQlqYXZheC5tYWlsLmV2ZW50LkNvbm5lY3Rpb25FdmVudAorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIG9wZW4oaW50IG1vZGUpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBDbG9zZSB0aGlzIEZvbGRlci4gVGhpcyBtZXRob2QgaXMgdmFsaWQgb25seSBvbiBvcGVuIEZvbGRlcnMuIDxwPgorICAgICAqCisgICAgICogQSBDTE9TRUQgQ29ubmVjdGlvbkV2ZW50IGlzIGRlbGl2ZXJlZCB0byBhbnkgQ29ubmVjdGlvbkxpc3RlbmVycworICAgICAqIHJlZ2lzdGVyZWQgb24gdGhpcyBGb2xkZXIuIE5vdGUgdGhhdCB0aGUgZm9sZGVyIGlzIGNsb3NlZCBldmVuCisgICAgICogaWYgdGhpcyBtZXRob2QgdGVybWluYXRlcyBhYm5vcm1hbGx5IGJ5IHRocm93aW5nIGEKKyAgICAgKiBNZXNzYWdpbmdFeGNlcHRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZXhwdW5nZQlleHB1bmdlcyBhbGwgZGVsZXRlZCBtZXNzYWdlcyBpZiB0aGlzIGZsYWcgaXMgdHJ1ZQorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgZm9sZGVyIGlzIG5vdCBvcGVuZWQKKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIE1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKiBAc2VlIAkJamF2YXgubWFpbC5ldmVudC5Db25uZWN0aW9uRXZlbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBjbG9zZShib29sZWFuIGV4cHVuZ2UpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBDbG9zZSB0aGlzIEZvbGRlciBhbmQgZXhwdW5nZSBkZWxldGVkIG1lc3NhZ2VzLiA8cD4KKyAgICAgKgorICAgICAqIEEgQ0xPU0VEIENvbm5lY3Rpb25FdmVudCBpcyBkZWxpdmVyZWQgdG8gYW55IENvbm5lY3Rpb25MaXN0ZW5lcnMKKyAgICAgKiByZWdpc3RlcmVkIG9uIHRoaXMgRm9sZGVyLiBOb3RlIHRoYXQgdGhlIGZvbGRlciBpcyBjbG9zZWQgZXZlbgorICAgICAqIGlmIHRoaXMgbWV0aG9kIHRlcm1pbmF0ZXMgYWJub3JtYWxseSBieSB0aHJvd2luZyBhCisgICAgICogTWVzc2FnaW5nRXhjZXB0aW9uLiA8cD4KKyAgICAgKgorICAgICAqIFRoaXMgbWV0aG9kIHN1cHBvcnRzIHRoZSB7QGxpbmsgamF2YS5sYW5nLkF1dG9DbG9zZWFibGUgQXV0b0Nsb3NlYWJsZX0KKyAgICAgKiBpbnRlcmZhY2UuIDxwPgorICAgICAqCisgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiBjYWxscyA8Y29kZT5jbG9zZSh0cnVlKTwvY29kZT4uCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIGZvbGRlciBpcyBub3Qgb3BlbmVkCisgICAgICogQGV4Y2VwdGlvbiAgICAgICBNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICogQHNlZSAJCWphdmF4Lm1haWwuZXZlbnQuQ29ubmVjdGlvbkV2ZW50CisgICAgICogQHNpbmNlCQlKYXZhTWFpbCAxLjYKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWNsb3NlKHRydWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMgRm9sZGVyIGlzIGluIHRoZSAnb3Blbicgc3RhdGUuCisgICAgICogQHJldHVybiAgdHJ1ZSBpZiB0aGlzIEZvbGRlciBpcyBpbiB0aGUgJ29wZW4nIHN0YXRlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGlzT3BlbigpOworCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBvcGVuIG1vZGUgb2YgdGhpcyBmb2xkZXIuICBSZXR1cm5zCisgICAgICogPGNvZGU+Rm9sZGVyLlJFQURfT05MWTwvY29kZT4sIDxjb2RlPkZvbGRlci5SRUFEX1dSSVRFPC9jb2RlPiwKKyAgICAgKiBvciAtMSBpZiB0aGUgb3BlbiBtb2RlIGlzIG5vdCBrbm93biAodXN1YWxseSBvbmx5IGJlY2F1c2UgYW4gb2xkZXIKKyAgICAgKiA8Y29kZT5Gb2xkZXI8L2NvZGU+IHByb3ZpZGVyIGhhcyBub3QgYmVlbiB1cGRhdGVkIHRvIHVzZSB0aGlzIG5ldworICAgICAqIG1ldGhvZCkuCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIGZvbGRlciBpcyBub3Qgb3BlbmVkCisgICAgICogQHJldHVybgkgICAgICAgIHRoZSBvcGVuIG1vZGUgb2YgdGhpcyBmb2xkZXIKKyAgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuMQorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IGdldE1vZGUoKSB7CisJaWYgKCFpc09wZW4oKSkKKwkgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiRm9sZGVyIG5vdCBvcGVuIik7CisJcmV0dXJuIG1vZGU7CisgICAgfQorIAorICAgIC8qKgorICAgICAqIEdldCB0aGUgcGVybWFuZW50IGZsYWdzIHN1cHBvcnRlZCBieSB0aGlzIEZvbGRlci4gUmV0dXJucyBhIEZsYWdzCisgICAgICogb2JqZWN0IHRoYXQgY29udGFpbnMgYWxsIHRoZSBmbGFncyBzdXBwb3J0ZWQuIDxwPgorICAgICAqCisgICAgICogVGhlIHNwZWNpYWwgZmxhZyA8Y29kZT5GbGFncy5GbGFnLlVTRVIgPC9jb2RlPiBpbmRpY2F0ZXMgdGhhdCB0aGlzIEZvbGRlcgorICAgICAqIHN1cHBvcnRzIGFyYml0cmFyeSB1c2VyLWRlZmluZWQgZmxhZ3MuIDxwPgorICAgICAqCisgICAgICogVGhlIHN1cHBvcnRlZCBwZXJtYW5lbnQgZmxhZ3MgZm9yIGEgZm9sZGVyIG1heSBub3QgYmUgYXZhaWxhYmxlCisgICAgICogdW50aWwgdGhlIGZvbGRlciBpcyBvcGVuZWQuCisgICAgICogCisgICAgICogQHJldHVybiAJCXBlcm1hbmVudCBmbGFncywgb3IgbnVsbCBpZiBub3Qga25vd24KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgRmxhZ3MgZ2V0UGVybWFuZW50RmxhZ3MoKTsKKworICAgIC8qKgorICAgICAqIEdldCB0b3RhbCBudW1iZXIgb2YgbWVzc2FnZXMgaW4gdGhpcyBGb2xkZXIuIDxwPgorICAgICAqCisgICAgICogVGhpcyBtZXRob2QgY2FuIGJlIGludm9rZWQgb24gYSBjbG9zZWQgZm9sZGVyLiBIb3dldmVyLCBub3RlCisgICAgICogdGhhdCBmb3Igc29tZSBmb2xkZXIgaW1wbGVtZW50YXRpb25zLCBnZXR0aW5nIHRoZSB0b3RhbCBtZXNzYWdlCisgICAgICogY291bnQgY2FuIGJlIGFuIGV4cGVuc2l2ZSBvcGVyYXRpb24gaW52b2x2aW5nIGFjdHVhbGx5IG9wZW5pbmcgCisgICAgICogdGhlIGZvbGRlci4gSW4gc3VjaCBjYXNlcywgYSBwcm92aWRlciBjYW4gY2hvb3NlIG5vdCB0byBzdXBwb3J0IAorICAgICAqIHRoaXMgZnVuY3Rpb25hbGl0eSBpbiB0aGUgY2xvc2VkIHN0YXRlLCBpbiB3aGljaCBjYXNlIHRoaXMgbWV0aG9kCisgICAgICogbXVzdCByZXR1cm4gLTEuIDxwPgorICAgICAqCisgICAgICogQ2xpZW50cyBpbnZva2luZyB0aGlzIG1ldGhvZCBvbiBhIGNsb3NlZCBmb2xkZXIgbXVzdCBiZSBhd2FyZQorICAgICAqIHRoYXQgdGhpcyBpcyBhIHBvdGVudGlhbGx5IGV4cGVuc2l2ZSBvcGVyYXRpb24uIENsaWVudHMgbXVzdAorICAgICAqIGFsc28gYmUgcHJlcGFyZWQgdG8gaGFuZGxlIGEgcmV0dXJuIHZhbHVlIG9mIC0xIGluIHRoaXMgY2FzZS4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIAkJdG90YWwgbnVtYmVyIG9mIG1lc3NhZ2VzLiAtMSBtYXkgYmUgcmV0dXJuZWQKKyAgICAgKgkJCWJ5IGNlcnRhaW4gaW1wbGVtZW50YXRpb25zIGlmIHRoaXMgbWV0aG9kIGlzCisgICAgICoJCQlpbnZva2VkIG9uIGEgY2xvc2VkIGZvbGRlci4KKyAgICAgKiBAZXhjZXB0aW9uCUZvbGRlck5vdEZvdW5kRXhjZXB0aW9uIGlmIHRoaXMgZm9sZGVyIGRvZXMgCisgICAgICoJCQlub3QgZXhpc3QuCisgICAgICogQGV4Y2VwdGlvbiAgICAgICBNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IGludCBnZXRNZXNzYWdlQ291bnQoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0IHRoZSBudW1iZXIgb2YgbmV3IG1lc3NhZ2VzIGluIHRoaXMgRm9sZGVyLiA8cD4KKyAgICAgKgorICAgICAqIFRoaXMgbWV0aG9kIGNhbiBiZSBpbnZva2VkIG9uIGEgY2xvc2VkIGZvbGRlci4gSG93ZXZlciwgbm90ZQorICAgICAqIHRoYXQgZm9yIHNvbWUgZm9sZGVyIGltcGxlbWVudGF0aW9ucywgZ2V0dGluZyB0aGUgbmV3IG1lc3NhZ2UKKyAgICAgKiBjb3VudCBjYW4gYmUgYW4gZXhwZW5zaXZlIG9wZXJhdGlvbiBpbnZvbHZpbmcgYWN0dWFsbHkgb3BlbmluZyAKKyAgICAgKiB0aGUgZm9sZGVyLiBJbiBzdWNoIGNhc2VzLCBhIHByb3ZpZGVyIGNhbiBjaG9vc2Ugbm90IHRvIHN1cHBvcnQgCisgICAgICogdGhpcyBmdW5jdGlvbmFsaXR5IGluIHRoZSBjbG9zZWQgc3RhdGUsIGluIHdoaWNoIGNhc2UgdGhpcyBtZXRob2QKKyAgICAgKiBtdXN0IHJldHVybiAtMS4gPHA+CisgICAgICoKKyAgICAgKiBDbGllbnRzIGludm9raW5nIHRoaXMgbWV0aG9kIG9uIGEgY2xvc2VkIGZvbGRlciBtdXN0IGJlIGF3YXJlCisgICAgICogdGhhdCB0aGlzIGlzIGEgcG90ZW50aWFsbHkgZXhwZW5zaXZlIG9wZXJhdGlvbi4gQ2xpZW50cyBtdXN0CisgICAgICogYWxzbyBiZSBwcmVwYXJlZCB0byBoYW5kbGUgYSByZXR1cm4gdmFsdWUgb2YgLTEgaW4gdGhpcyBjYXNlLiA8cD4KKyAgICAgKgorICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gcmV0dXJucyAtMSBpZiB0aGlzIGZvbGRlciBpcyBjbG9zZWQuIEVsc2UKKyAgICAgKiB0aGlzIGltcGxlbWVudGF0aW9uIGdldHMgZWFjaCBNZXNzYWdlIGluIHRoZSBmb2xkZXIgdXNpbmcKKyAgICAgKiA8Y29kZT5nZXRNZXNzYWdlKGludCk8L2NvZGU+IGFuZCBjaGVja3Mgd2hldGhlciBpdHMKKyAgICAgKiA8Y29kZT5SRUNFTlQ8L2NvZGU+IGZsYWcgaXMgc2V0LiBUaGUgdG90YWwgbnVtYmVyIG9mIG1lc3NhZ2VzCisgICAgICogdGhhdCBoYXZlIHRoaXMgZmxhZyBzZXQgaXMgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIAkJbnVtYmVyIG9mIG5ldyBtZXNzYWdlcy4gLTEgbWF5IGJlIHJldHVybmVkCisgICAgICoJCQlieSBjZXJ0YWluIGltcGxlbWVudGF0aW9ucyBpZiB0aGlzIG1ldGhvZCBpcworICAgICAqCQkJaW52b2tlZCBvbiBhIGNsb3NlZCBmb2xkZXIuCisgICAgICogQGV4Y2VwdGlvbglGb2xkZXJOb3RGb3VuZEV4Y2VwdGlvbiBpZiB0aGlzIGZvbGRlciBkb2VzIAorICAgICAqCQkJbm90IGV4aXN0LgorICAgICAqIEBleGNlcHRpb24gICAgICAgTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBvdGhlciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IGdldE5ld01lc3NhZ2VDb3VudCgpIAorCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKCFpc09wZW4oKSkKKwkgICAgcmV0dXJuIC0xOworCisJaW50IG5ld21zZ3MgPSAwOworCWludCB0b3RhbCA9IGdldE1lc3NhZ2VDb3VudCgpOworCWZvciAoaW50IGkgPSAxOyBpIDw9IHRvdGFsOyBpKyspIHsKKwkgICAgdHJ5IHsKKwkJaWYgKGdldE1lc3NhZ2UoaSkuaXNTZXQoRmxhZ3MuRmxhZy5SRUNFTlQpKQorCQkgICAgbmV3bXNncysrOworCSAgICB9IGNhdGNoIChNZXNzYWdlUmVtb3ZlZEV4Y2VwdGlvbiBtZSkgeworCQkvLyBUaGlzIGlzIGFuIGV4cHVuZ2VkIG1lc3NhZ2UsIGlnbm9yZSBpdC4KKwkJY29udGludWU7CisJICAgIH0KKwl9CisJcmV0dXJuIG5ld21zZ3M7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSB0b3RhbCBudW1iZXIgb2YgdW5yZWFkIG1lc3NhZ2VzIGluIHRoaXMgRm9sZGVyLiA8cD4KKyAgICAgKgorICAgICAqIFRoaXMgbWV0aG9kIGNhbiBiZSBpbnZva2VkIG9uIGEgY2xvc2VkIGZvbGRlci4gSG93ZXZlciwgbm90ZQorICAgICAqIHRoYXQgZm9yIHNvbWUgZm9sZGVyIGltcGxlbWVudGF0aW9ucywgZ2V0dGluZyB0aGUgdW5yZWFkIG1lc3NhZ2UKKyAgICAgKiBjb3VudCBjYW4gYmUgYW4gZXhwZW5zaXZlIG9wZXJhdGlvbiBpbnZvbHZpbmcgYWN0dWFsbHkgb3BlbmluZyAKKyAgICAgKiB0aGUgZm9sZGVyLiBJbiBzdWNoIGNhc2VzLCBhIHByb3ZpZGVyIGNhbiBjaG9vc2Ugbm90IHRvIHN1cHBvcnQgCisgICAgICogdGhpcyBmdW5jdGlvbmFsaXR5IGluIHRoZSBjbG9zZWQgc3RhdGUsIGluIHdoaWNoIGNhc2UgdGhpcyBtZXRob2QKKyAgICAgKiBtdXN0IHJldHVybiAtMS4gPHA+CisgICAgICoKKyAgICAgKiBDbGllbnRzIGludm9raW5nIHRoaXMgbWV0aG9kIG9uIGEgY2xvc2VkIGZvbGRlciBtdXN0IGJlIGF3YXJlCisgICAgICogdGhhdCB0aGlzIGlzIGEgcG90ZW50aWFsbHkgZXhwZW5zaXZlIG9wZXJhdGlvbi4gQ2xpZW50cyBtdXN0CisgICAgICogYWxzbyBiZSBwcmVwYXJlZCB0byBoYW5kbGUgYSByZXR1cm4gdmFsdWUgb2YgLTEgaW4gdGhpcyBjYXNlLiA8cD4KKyAgICAgKgorICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gcmV0dXJucyAtMSBpZiB0aGlzIGZvbGRlciBpcyBjbG9zZWQuIEVsc2UKKyAgICAgKiB0aGlzIGltcGxlbWVudGF0aW9uIGdldHMgZWFjaCBNZXNzYWdlIGluIHRoZSBmb2xkZXIgdXNpbmcKKyAgICAgKiA8Y29kZT5nZXRNZXNzYWdlKGludCk8L2NvZGU+IGFuZCBjaGVja3Mgd2hldGhlciBpdHMKKyAgICAgKiA8Y29kZT5TRUVOPC9jb2RlPiBmbGFnIGlzIHNldC4gVGhlIHRvdGFsIG51bWJlciBvZiBtZXNzYWdlcworICAgICAqIHRoYXQgZG8gbm90IGhhdmUgdGhpcyBmbGFnIHNldCBpcyByZXR1cm5lZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gCQl0b3RhbCBudW1iZXIgb2YgdW5yZWFkIG1lc3NhZ2VzLiAtMSBtYXkgYmUgcmV0dXJuZWQKKyAgICAgKgkJCWJ5IGNlcnRhaW4gaW1wbGVtZW50YXRpb25zIGlmIHRoaXMgbWV0aG9kIGlzCisgICAgICoJCQlpbnZva2VkIG9uIGEgY2xvc2VkIGZvbGRlci4KKyAgICAgKiBAZXhjZXB0aW9uCUZvbGRlck5vdEZvdW5kRXhjZXB0aW9uIGlmIHRoaXMgZm9sZGVyIGRvZXMgCisgICAgICoJCQlub3QgZXhpc3QuCisgICAgICogQGV4Y2VwdGlvbiAgICAgICBNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBpbnQgZ2V0VW5yZWFkTWVzc2FnZUNvdW50KCkgCisJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpZiAoIWlzT3BlbigpKQorCSAgICByZXR1cm4gLTE7CisKKwlpbnQgdW5yZWFkID0gMDsKKwlpbnQgdG90YWwgPSBnZXRNZXNzYWdlQ291bnQoKTsKKwlmb3IgKGludCBpID0gMTsgaSA8PSB0b3RhbDsgaSsrKSB7CisJICAgIHRyeSB7CisJCWlmICghZ2V0TWVzc2FnZShpKS5pc1NldChGbGFncy5GbGFnLlNFRU4pKQorCQkgICAgdW5yZWFkKys7CisJICAgIH0gY2F0Y2ggKE1lc3NhZ2VSZW1vdmVkRXhjZXB0aW9uIG1lKSB7CisJCS8vIFRoaXMgaXMgYW4gZXhwdW5nZWQgbWVzc2FnZSwgaWdub3JlIGl0LgorCQljb250aW51ZTsKKwkgICAgfQorCX0KKwlyZXR1cm4gdW5yZWFkOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgbnVtYmVyIG9mIGRlbGV0ZWQgbWVzc2FnZXMgaW4gdGhpcyBGb2xkZXIuIDxwPgorICAgICAqCisgICAgICogVGhpcyBtZXRob2QgY2FuIGJlIGludm9rZWQgb24gYSBjbG9zZWQgZm9sZGVyLiBIb3dldmVyLCBub3RlCisgICAgICogdGhhdCBmb3Igc29tZSBmb2xkZXIgaW1wbGVtZW50YXRpb25zLCBnZXR0aW5nIHRoZSBkZWxldGVkIG1lc3NhZ2UKKyAgICAgKiBjb3VudCBjYW4gYmUgYW4gZXhwZW5zaXZlIG9wZXJhdGlvbiBpbnZvbHZpbmcgYWN0dWFsbHkgb3BlbmluZyAKKyAgICAgKiB0aGUgZm9sZGVyLiBJbiBzdWNoIGNhc2VzLCBhIHByb3ZpZGVyIGNhbiBjaG9vc2Ugbm90IHRvIHN1cHBvcnQgCisgICAgICogdGhpcyBmdW5jdGlvbmFsaXR5IGluIHRoZSBjbG9zZWQgc3RhdGUsIGluIHdoaWNoIGNhc2UgdGhpcyBtZXRob2QKKyAgICAgKiBtdXN0IHJldHVybiAtMS4gPHA+CisgICAgICoKKyAgICAgKiBDbGllbnRzIGludm9raW5nIHRoaXMgbWV0aG9kIG9uIGEgY2xvc2VkIGZvbGRlciBtdXN0IGJlIGF3YXJlCisgICAgICogdGhhdCB0aGlzIGlzIGEgcG90ZW50aWFsbHkgZXhwZW5zaXZlIG9wZXJhdGlvbi4gQ2xpZW50cyBtdXN0CisgICAgICogYWxzbyBiZSBwcmVwYXJlZCB0byBoYW5kbGUgYSByZXR1cm4gdmFsdWUgb2YgLTEgaW4gdGhpcyBjYXNlLiA8cD4KKyAgICAgKgorICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gcmV0dXJucyAtMSBpZiB0aGlzIGZvbGRlciBpcyBjbG9zZWQuIEVsc2UKKyAgICAgKiB0aGlzIGltcGxlbWVudGF0aW9uIGdldHMgZWFjaCBNZXNzYWdlIGluIHRoZSBmb2xkZXIgdXNpbmcKKyAgICAgKiA8Y29kZT5nZXRNZXNzYWdlKGludCk8L2NvZGU+IGFuZCBjaGVja3Mgd2hldGhlciBpdHMKKyAgICAgKiA8Y29kZT5ERUxFVEVEPC9jb2RlPiBmbGFnIGlzIHNldC4gVGhlIHRvdGFsIG51bWJlciBvZiBtZXNzYWdlcworICAgICAqIHRoYXQgaGF2ZSB0aGlzIGZsYWcgc2V0IGlzIHJldHVybmVkLgorICAgICAqCisgICAgICogQHJldHVybiAJCW51bWJlciBvZiBkZWxldGVkIG1lc3NhZ2VzLiAtMSBtYXkgYmUgcmV0dXJuZWQKKyAgICAgKgkJCWJ5IGNlcnRhaW4gaW1wbGVtZW50YXRpb25zIGlmIHRoaXMgbWV0aG9kIGlzCisgICAgICoJCQlpbnZva2VkIG9uIGEgY2xvc2VkIGZvbGRlci4KKyAgICAgKiBAZXhjZXB0aW9uCUZvbGRlck5vdEZvdW5kRXhjZXB0aW9uIGlmIHRoaXMgZm9sZGVyIGRvZXMgCisgICAgICoJCQlub3QgZXhpc3QuCisgICAgICogQGV4Y2VwdGlvbiAgICAgICBNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICogQHNpbmNlCQlKYXZhTWFpbCAxLjMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCBnZXREZWxldGVkTWVzc2FnZUNvdW50KCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKCFpc09wZW4oKSkKKwkgICAgcmV0dXJuIC0xOworCisJaW50IGRlbGV0ZWQgPSAwOworCWludCB0b3RhbCA9IGdldE1lc3NhZ2VDb3VudCgpOworCWZvciAoaW50IGkgPSAxOyBpIDw9IHRvdGFsOyBpKyspIHsKKwkgICAgdHJ5IHsKKwkJaWYgKGdldE1lc3NhZ2UoaSkuaXNTZXQoRmxhZ3MuRmxhZy5ERUxFVEVEKSkKKwkJICAgIGRlbGV0ZWQrKzsKKwkgICAgfSBjYXRjaCAoTWVzc2FnZVJlbW92ZWRFeGNlcHRpb24gbWUpIHsKKwkJLy8gVGhpcyBpcyBhbiBleHB1bmdlZCBtZXNzYWdlLCBpZ25vcmUgaXQuCisJCWNvbnRpbnVlOworCSAgICB9CisJfQorCXJldHVybiBkZWxldGVkOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgTWVzc2FnZSBvYmplY3QgY29ycmVzcG9uZGluZyB0byB0aGUgZ2l2ZW4gbWVzc2FnZQorICAgICAqIG51bWJlci4gIEEgTWVzc2FnZSBvYmplY3QncyBtZXNzYWdlIG51bWJlciBpcyB0aGUgcmVsYXRpdmUKKyAgICAgKiBwb3NpdGlvbiBvZiB0aGlzIE1lc3NhZ2UgaW4gaXRzIEZvbGRlci4gTWVzc2FnZXMgYXJlIG51bWJlcmVkCisgICAgICogc3RhcnRpbmcgYXQgMSB0aHJvdWdoIHRoZSB0b3RhbCBudW1iZXIgb2YgbWVzc2FnZSBpbiB0aGUgZm9sZGVyLgorICAgICAqIE5vdGUgdGhhdCB0aGUgbWVzc2FnZSBudW1iZXIgZm9yIGEgcGFydGljdWxhciBNZXNzYWdlIGNhbiBjaGFuZ2UKKyAgICAgKiBkdXJpbmcgYSBzZXNzaW9uIGlmIG90aGVyIG1lc3NhZ2VzIGluIHRoZSBGb2xkZXIgYXJlIGRlbGV0ZWQgYW5kCisgICAgICogdGhlIEZvbGRlciBpcyBleHB1bmdlZC4gPHA+CisgICAgICoKKyAgICAgKiBNZXNzYWdlIG9iamVjdHMgYXJlIGxpZ2h0LXdlaWdodCByZWZlcmVuY2VzIHRvIHRoZSBhY3R1YWwgbWVzc2FnZQorICAgICAqIHRoYXQgZ2V0IGZpbGxlZCB1cCBvbiBkZW1hbmQuIEhlbmNlIEZvbGRlciBpbXBsZW1lbnRhdGlvbnMgYXJlIAorICAgICAqIGV4cGVjdGVkIHRvIHByb3ZpZGUgbGlnaHQtd2VpZ2h0IE1lc3NhZ2Ugb2JqZWN0cy4gPHA+CisgICAgICoKKyAgICAgKiBVbmxpa2UgRm9sZGVyIG9iamVjdHMsIHJlcGVhdGVkIGNhbGxzIHRvIGdldE1lc3NhZ2Ugd2l0aCB0aGUKKyAgICAgKiBzYW1lIG1lc3NhZ2UgbnVtYmVyIHdpbGwgcmV0dXJuIHRoZSBzYW1lIE1lc3NhZ2Ugb2JqZWN0LCBhcworICAgICAqIGxvbmcgYXMgbm8gbWVzc2FnZXMgaW4gdGhpcyBmb2xkZXIgaGF2ZSBiZWVuIGV4cHVuZ2VkLiA8cD4KKyAgICAgKgorICAgICAqIFNpbmNlIG1lc3NhZ2UgbnVtYmVycyBjYW4gY2hhbmdlIHdpdGhpbiBhIHNlc3Npb24gaWYgdGhlIGZvbGRlcgorICAgICAqIGlzIGV4cHVuZ2VkICwgY2xpZW50cyBhcmUgYWR2aXNlZCBub3QgdG8gdXNlIG1lc3NhZ2UgbnVtYmVycyBhcyAKKyAgICAgKiByZWZlcmVuY2VzIHRvIG1lc3NhZ2VzLiBVc2UgTWVzc2FnZSBvYmplY3RzIGluc3RlYWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbXNnbnVtCXRoZSBtZXNzYWdlIG51bWJlcgorICAgICAqIEByZXR1cm4gCQl0aGUgTWVzc2FnZSBvYmplY3QKKyAgICAgKiBAc2VlCQkjZ2V0TWVzc2FnZUNvdW50CisgICAgICogQHNlZQkJI2ZldGNoCisgICAgICogQGV4Y2VwdGlvbglGb2xkZXJOb3RGb3VuZEV4Y2VwdGlvbiBpZiB0aGlzIGZvbGRlciBkb2VzIAorICAgICAqCQkJbm90IGV4aXN0LgorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgZm9sZGVyIGlzIG5vdCBvcGVuZWQKKyAgICAgKiBAZXhjZXB0aW9uCUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWYgdGhlIG1lc3NhZ2UgbnVtYmVyCisgICAgICoJCQlpcyBvdXQgb2YgcmFuZ2UuCisgICAgICogQGV4Y2VwdGlvbiAJTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBvdGhlciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBNZXNzYWdlIGdldE1lc3NhZ2UoaW50IG1zZ251bSkKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0IHRoZSBNZXNzYWdlIG9iamVjdHMgZm9yIG1lc3NhZ2UgbnVtYmVycyByYW5naW5nIGZyb20gc3RhcnQKKyAgICAgKiB0aHJvdWdoIGVuZCwgYm90aCBzdGFydCBhbmQgZW5kIGluY2x1c2l2ZS4gTm90ZSB0aGF0IG1lc3NhZ2UgCisgICAgICogbnVtYmVycyBzdGFydCBhdCAxLCBub3QgMC4gPHA+CisgICAgICoKKyAgICAgKiBNZXNzYWdlIG9iamVjdHMgYXJlIGxpZ2h0LXdlaWdodCByZWZlcmVuY2VzIHRvIHRoZSBhY3R1YWwgbWVzc2FnZQorICAgICAqIHRoYXQgZ2V0IGZpbGxlZCB1cCBvbiBkZW1hbmQuIEhlbmNlIEZvbGRlciBpbXBsZW1lbnRhdGlvbnMgYXJlIAorICAgICAqIGV4cGVjdGVkIHRvIHByb3ZpZGUgbGlnaHQtd2VpZ2h0IE1lc3NhZ2Ugb2JqZWN0cy4gPHA+CisgICAgICoKKyAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIHVzZXMgZ2V0TWVzc2FnZShpbmRleCkgdG8gb2J0YWluIHRoZSByZXF1aXJlZAorICAgICAqIE1lc3NhZ2Ugb2JqZWN0cy4gTm90ZSB0aGF0IHRoZSByZXR1cm5lZCBhcnJheSBtdXN0IGNvbnRhaW4gCisgICAgICogPGNvZGU+KGVuZC1zdGFydCsxKTwvY29kZT4gTWVzc2FnZSBvYmplY3RzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBzdGFydAl0aGUgbnVtYmVyIG9mIHRoZSBmaXJzdCBtZXNzYWdlCisgICAgICogQHBhcmFtIGVuZAl0aGUgbnVtYmVyIG9mIHRoZSBsYXN0IG1lc3NhZ2UKKyAgICAgKiBAcmV0dXJuIAkJdGhlIE1lc3NhZ2Ugb2JqZWN0cworICAgICAqIEBzZWUJCSNmZXRjaAorICAgICAqIEBleGNlcHRpb24JRm9sZGVyTm90Rm91bmRFeGNlcHRpb24gaWYgdGhpcyBmb2xkZXIgZG9lcyAKKyAgICAgKgkJCW5vdCBleGlzdC4KKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIGZvbGRlciBpcyBub3Qgb3BlbmVkLgorICAgICAqIEBleGNlcHRpb24JSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiB0aGUgc3RhcnQgb3IgZW5kCisgICAgICoJCQltZXNzYWdlIG51bWJlcnMgYXJlIG91dCBvZiByYW5nZS4KKyAgICAgKiBAZXhjZXB0aW9uIAlNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICovIAorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgTWVzc2FnZVtdIGdldE1lc3NhZ2VzKGludCBzdGFydCwgaW50IGVuZCkgCisJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlNZXNzYWdlW10gbXNncyA9IG5ldyBNZXNzYWdlW2VuZCAtIHN0YXJ0ICsxXTsKKwlmb3IgKGludCBpID0gc3RhcnQ7IGkgPD0gZW5kOyBpKyspCisJICAgIG1zZ3NbaSAtIHN0YXJ0XSA9IGdldE1lc3NhZ2UoaSk7CisJcmV0dXJuIG1zZ3M7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBNZXNzYWdlIG9iamVjdHMgZm9yIG1lc3NhZ2UgbnVtYmVycyBzcGVjaWZpZWQgaW4KKyAgICAgKiB0aGUgYXJyYXkuIDxwPgorICAgICAqCisgICAgICogTWVzc2FnZSBvYmplY3RzIGFyZSBsaWdodC13ZWlnaHQgcmVmZXJlbmNlcyB0byB0aGUgYWN0dWFsIG1lc3NhZ2UKKyAgICAgKiB0aGF0IGdldCBmaWxsZWQgdXAgb24gZGVtYW5kLiBIZW5jZSBGb2xkZXIgaW1wbGVtZW50YXRpb25zIGFyZSAKKyAgICAgKiBleHBlY3RlZCB0byBwcm92aWRlIGxpZ2h0LXdlaWdodCBNZXNzYWdlIG9iamVjdHMuIDxwPgorICAgICAqCisgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiB1c2VzIGdldE1lc3NhZ2UoaW5kZXgpIHRvIG9idGFpbiB0aGUgcmVxdWlyZWQKKyAgICAgKiBNZXNzYWdlIG9iamVjdHMuIE5vdGUgdGhhdCB0aGUgcmV0dXJuZWQgYXJyYXkgbXVzdCBjb250YWluIAorICAgICAqIDxjb2RlPm1zZ251bXMubGVuZ3RoPC9jb2RlPiBNZXNzYWdlIG9iamVjdHMKKyAgICAgKgorICAgICAqIEBwYXJhbSBtc2dudW1zCXRoZSBhcnJheSBvZiBtZXNzYWdlIG51bWJlcnMKKyAgICAgKiBAcmV0dXJuIAkJdGhlIGFycmF5IG9mIE1lc3NhZ2Ugb2JqZWN0cy4gCisgICAgICogQHNlZQkJI2ZldGNoCisgICAgICogQGV4Y2VwdGlvbglGb2xkZXJOb3RGb3VuZEV4Y2VwdGlvbiBpZiB0aGlzIGZvbGRlciBkb2VzIAorICAgICAqCQkJbm90IGV4aXN0LgorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgZm9sZGVyIGlzIG5vdCBvcGVuZWQuCisgICAgICogQGV4Y2VwdGlvbglJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlmIGFueSBtZXNzYWdlIG51bWJlcgorICAgICAqCQkJaW4gdGhlIGdpdmVuIGFycmF5IGlzIG91dCBvZiByYW5nZS4KKyAgICAgKiBAZXhjZXB0aW9uIAlNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICovIAorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgTWVzc2FnZVtdIGdldE1lc3NhZ2VzKGludFtdIG1zZ251bXMpCisJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpbnQgbGVuID0gbXNnbnVtcy5sZW5ndGg7CisJTWVzc2FnZVtdIG1zZ3MgPSBuZXcgTWVzc2FnZVtsZW5dOworCWZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyBpKyspCisJICAgIG1zZ3NbaV0gPSBnZXRNZXNzYWdlKG1zZ251bXNbaV0pOworCXJldHVybiBtc2dzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCBhbGwgTWVzc2FnZSBvYmplY3RzIGZyb20gdGhpcyBGb2xkZXIuIFJldHVybnMgYW4gZW1wdHkgYXJyYXkKKyAgICAgKiBpZiB0aGUgZm9sZGVyIGlzIGVtcHR5LgorICAgICAqCisgICAgICogQ2xpZW50cyBjYW4gdXNlIE1lc3NhZ2Ugb2JqZWN0cyAoaW5zdGVhZCBvZiBzZXF1ZW5jZSBudW1iZXJzKSAKKyAgICAgKiBhcyByZWZlcmVuY2VzIHRvIHRoZSBtZXNzYWdlcyB3aXRoaW4gYSBmb2xkZXI7IHRoaXMgbWV0aG9kIHN1cHBsaWVzIAorICAgICAqIHRoZSBNZXNzYWdlIG9iamVjdHMgdG8gdGhlIGNsaWVudC4gRm9sZGVyIGltcGxlbWVudGF0aW9ucyBhcmUgCisgICAgICogZXhwZWN0ZWQgdG8gcHJvdmlkZSBsaWdodC13ZWlnaHQgTWVzc2FnZSBvYmplY3RzLCB3aGljaCBnZXQKKyAgICAgKiBmaWxsZWQgb24gZGVtYW5kLiA8cD4KKyAgICAgKgorICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gaW52b2tlcyA8Y29kZT5nZXRNZXNzYWdlQ291bnQoKTwvY29kZT4gdG8gZ2V0CisgICAgICogdGhlIGN1cnJlbnQgbWVzc2FnZSBjb3VudCBhbmQgdGhlbiB1c2VzIDxjb2RlPmdldE1lc3NhZ2UoKTwvY29kZT4KKyAgICAgKiB0byBnZXQgTWVzc2FnZSBvYmplY3RzIGZyb20gMSB0aWxsIHRoZSBtZXNzYWdlIGNvdW50LgorICAgICAqCisgICAgICogQHJldHVybiAJCWFycmF5IG9mIE1lc3NhZ2Ugb2JqZWN0cywgZW1wdHkgYXJyYXkgaWYgZm9sZGVyCisgICAgICoJCQlpcyBlbXB0eS4KKyAgICAgKiBAc2VlCQkjZmV0Y2gKKyAgICAgKiBAZXhjZXB0aW9uCUZvbGRlck5vdEZvdW5kRXhjZXB0aW9uIGlmIHRoaXMgZm9sZGVyIGRvZXMgCisgICAgICoJCQlub3QgZXhpc3QuCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBmb2xkZXIgaXMgbm90IG9wZW5lZC4KKyAgICAgKiBAZXhjZXB0aW9uIAlNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICovIAorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgTWVzc2FnZVtdIGdldE1lc3NhZ2VzKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKCFpc09wZW4oKSkJLy8gb3RoZXJ3aXNlIGdldE1lc3NhZ2VDb3VudCBtaWdodCByZXR1cm4gLTEKKwkgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiRm9sZGVyIG5vdCBvcGVuIik7CisJaW50IHRvdGFsID0gZ2V0TWVzc2FnZUNvdW50KCk7CisJTWVzc2FnZVtdIG1zZ3MgPSBuZXcgTWVzc2FnZVt0b3RhbF07CisJZm9yIChpbnQgaSA9IDE7IGkgPD0gdG90YWw7IGkrKykKKwkgICAgbXNnc1tpLTFdID0gZ2V0TWVzc2FnZShpKTsJCisJcmV0dXJuIG1zZ3M7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXBwZW5kIGdpdmVuIE1lc3NhZ2VzIHRvIHRoaXMgZm9sZGVyLiBUaGlzIG1ldGhvZCBjYW4gYmUgCisgICAgICogaW52b2tlZCBvbiBhIGNsb3NlZCBGb2xkZXIuIEFuIGFwcHJvcHJpYXRlIE1lc3NhZ2VDb3VudEV2ZW50IAorICAgICAqIGlzIGRlbGl2ZXJlZCB0byBhbnkgTWVzc2FnZUNvdW50TGlzdGVuZXIgcmVnaXN0ZXJlZCBvbiB0aGlzIAorICAgICAqIGZvbGRlciB3aGVuIHRoZSBtZXNzYWdlcyBhcnJpdmUgaW4gdGhlIGZvbGRlci4gPHA+CisgICAgICoKKyAgICAgKiBGb2xkZXIgaW1wbGVtZW50YXRpb25zIG11c3Qgbm90IGFib3J0IHRoaXMgb3BlcmF0aW9uIGlmIGEKKyAgICAgKiBNZXNzYWdlIGluIHRoZSBnaXZlbiBtZXNzYWdlIGFycmF5IHR1cm5zIG91dCB0byBiZSBhbgorICAgICAqIGV4cHVuZ2VkIE1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbXNncwlhcnJheSBvZiBNZXNzYWdlcyB0byBiZSBhcHBlbmRlZAorICAgICAqIEBleGNlcHRpb24JRm9sZGVyTm90Rm91bmRFeGNlcHRpb24gaWYgdGhpcyBmb2xkZXIgZG9lcyAKKyAgICAgKgkJCW5vdCBleGlzdC4KKyAgICAgKiBAZXhjZXB0aW9uIAlNZXNzYWdpbmdFeGNlcHRpb24gaWYgdGhlIGFwcGVuZCBmYWlsZWQuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgYXBwZW5kTWVzc2FnZXMoTWVzc2FnZVtdIG1zZ3MpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFByZWZldGNoIHRoZSBpdGVtcyBzcGVjaWZpZWQgaW4gdGhlIEZldGNoUHJvZmlsZSBmb3IgdGhlCisgICAgICogZ2l2ZW4gTWVzc2FnZXMuIDxwPgorICAgICAqCisgICAgICogQ2xpZW50cyB1c2UgdGhpcyBtZXRob2QgdG8gaW5kaWNhdGUgdGhhdCB0aGUgc3BlY2lmaWVkIGl0ZW1zIGFyZSAKKyAgICAgKiBuZWVkZWQgZW4tbWFzc2UgZm9yIHRoZSBnaXZlbiBtZXNzYWdlIHJhbmdlLiBJbXBsZW1lbnRhdGlvbnMgYXJlIAorICAgICAqIGV4cGVjdGVkIHRvIHJldHJpZXZlIHRoZXNlIGl0ZW1zIGZvciB0aGUgZ2l2ZW4gbWVzc2FnZSByYW5nZSBpbgorICAgICAqIGEgZWZmaWNpZW50IG1hbm5lci4gTm90ZSB0aGF0IHRoaXMgbWV0aG9kIGlzIGp1c3QgYSBoaW50IHRvIHRoZQorICAgICAqIGltcGxlbWVudGF0aW9uIHRvIHByZWZldGNoIHRoZSBkZXNpcmVkIGl0ZW1zLiA8cD4KKyAgICAgKgorICAgICAqIEFuIGV4YW1wbGUgaXMgYSBjbGllbnQgZmlsbGluZyBpdHMgaGVhZGVyLXZpZXcgd2luZG93IHdpdGgKKyAgICAgKiB0aGUgU3ViamVjdCwgRnJvbSBhbmQgWC1tYWlsZXIgaGVhZGVycyBmb3IgYWxsIG1lc3NhZ2VzIGluIHRoZSAKKyAgICAgKiBmb2xkZXIuCisgICAgICogPGJsb2NrcXVvdGU+PHByZT4KKyAgICAgKgorICAgICAqICBNZXNzYWdlW10gbXNncyA9IGZvbGRlci5nZXRNZXNzYWdlcygpOworICAgICAqCisgICAgICogIEZldGNoUHJvZmlsZSBmcCA9IG5ldyBGZXRjaFByb2ZpbGUoKTsKKyAgICAgKiAgZnAuYWRkKEZldGNoUHJvZmlsZS5JdGVtLkVOVkVMT1BFKTsKKyAgICAgKiAgZnAuYWRkKCJYLW1haWxlciIpOworICAgICAqICBmb2xkZXIuZmV0Y2gobXNncywgZnApOworICAgICAqICAKKyAgICAgKiAgZm9yIChpbnQgaSA9IDA7IGkgJmx0OyBmb2xkZXIuZ2V0TWVzc2FnZUNvdW50KCk7IGkrKykgeworICAgICAqICAgICAgZGlzcGxheShtc2dbaV0uZ2V0RnJvbSgpKTsKKyAgICAgKiAgICAgIGRpc3BsYXkobXNnW2ldLmdldFN1YmplY3QoKSk7CisgICAgICogICAgICBkaXNwbGF5KG1zZ1tpXS5nZXRIZWFkZXIoIlgtbWFpbGVyIikpOworICAgICAqICB9CisgICAgICoKKyAgICAgKiA8L3ByZT48L2Jsb2NrcXVvdGU+PHA+CisgICAgICoKKyAgICAgKiBUaGUgaW1wbGVtZW50YXRpb24gcHJvdmlkZWQgaGVyZSBqdXN0IHJldHVybnMgd2l0aG91dAorICAgICAqIGRvaW5nIGFueXRoaW5nIHVzZWZ1bC4gUHJvdmlkZXJzIHdhbnRpbmcgdG8gcHJvdmlkZSBhIHJlYWwgCisgICAgICogaW1wbGVtZW50YXRpb24gZm9yIHRoaXMgbWV0aG9kIHNob3VsZCBvdmVycmlkZSB0aGlzIG1ldGhvZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtc2dzCWZldGNoIGl0ZW1zIGZvciB0aGVzZSBtZXNzYWdlcworICAgICAqIEBwYXJhbSBmcAl0aGUgRmV0Y2hQcm9maWxlCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBmb2xkZXIgaXMgbm90IG9wZW5lZAorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBvdGhlciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyB2b2lkIGZldGNoKE1lc3NhZ2VbXSBtc2dzLCBGZXRjaFByb2ZpbGUgZnApCisJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm47CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBzcGVjaWZpZWQgZmxhZ3Mgb24gdGhlIG1lc3NhZ2VzIHNwZWNpZmllZCBpbiB0aGUgYXJyYXkuCisgICAgICogVGhpcyB3aWxsIHJlc3VsdCBpbiBhcHByb3ByaWF0ZSBNZXNzYWdlQ2hhbmdlZEV2ZW50cyBiZWluZworICAgICAqIGRlbGl2ZXJlZCB0byBhbnkgTWVzc2FnZUNoYW5nZWRMaXN0ZW5lciByZWdpc3RlcmVkIG9uIHRoaXMKKyAgICAgKiBNZXNzYWdlJ3MgY29udGFpbmluZyBmb2xkZXIuIDxwPgorICAgICAqCisgICAgICogTm90ZSB0aGF0IHRoZSBzcGVjaWZpZWQgTWVzc2FnZSBvYmplY3RzIDxzdHJvbmc+bXVzdDwvc3Ryb25nPiAKKyAgICAgKiBiZWxvbmcgdG8gdGhpcyBmb2xkZXIuIENlcnRhaW4gRm9sZGVyIGltcGxlbWVudGF0aW9ucyBjYW4KKyAgICAgKiBvcHRpbWl6ZSB0aGUgb3BlcmF0aW9uIG9mIHNldHRpbmcgRmxhZ3MgZm9yIGEgZ3JvdXAgb2YgbWVzc2FnZXMsCisgICAgICogc28gY2xpZW50cyBtaWdodCB3YW50IHRvIHVzZSB0aGlzIG1ldGhvZCwgcmF0aGVyIHRoYW4gaW52b2tpbmcKKyAgICAgKiA8Y29kZT5NZXNzYWdlLnNldEZsYWdzPC9jb2RlPiBmb3IgZWFjaCBNZXNzYWdlLiA8cD4KKyAgICAgKgorICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gZGVnZW5lcmF0ZXMgdG8gaW52b2tpbmcgPGNvZGU+c2V0RmxhZ3MoKTwvY29kZT4KKyAgICAgKiBvbiBlYWNoIE1lc3NhZ2Ugb2JqZWN0LiBTcGVjaWZpYyBGb2xkZXIgaW1wbGVtZW50YXRpb25zIHRoYXQgY2FuIAorICAgICAqIG9wdGltaXplIHRoaXMgY2FzZSBzaG91bGQgZG8gc28uIAorICAgICAqIEFsc28sIGFuIGltcGxlbWVudGF0aW9uIG11c3Qgbm90IGFib3J0IHRoZSBvcGVyYXRpb24gaWYgYSBNZXNzYWdlIAorICAgICAqIGluIHRoZSBhcnJheSB0dXJucyBvdXQgdG8gYmUgYW4gZXhwdW5nZWQgTWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtc2dzCXRoZSBhcnJheSBvZiBtZXNzYWdlIG9iamVjdHMKKyAgICAgKiBAcGFyYW0gZmxhZwlGbGFncyBvYmplY3QgY29udGFpbmluZyB0aGUgZmxhZ3MgdG8gYmUgc2V0CisgICAgICogQHBhcmFtIHZhbHVlCXNldCB0aGUgZmxhZ3MgdG8gdGhpcyBib29sZWFuIHZhbHVlCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBmb2xkZXIgaXMgbm90IG9wZW5lZAorICAgICAqCQkJb3IgaWYgaXQgaGFzIGJlZW4gb3BlbmVkIFJFQURfT05MWS4KKyAgICAgKiBAZXhjZXB0aW9uIAlNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICogQHNlZQkJTWVzc2FnZSNzZXRGbGFncworICAgICAqIEBzZWUJCWphdmF4Lm1haWwuZXZlbnQuTWVzc2FnZUNoYW5nZWRFdmVudAorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXRGbGFncyhNZXNzYWdlW10gbXNncywKKwkJCUZsYWdzIGZsYWcsIGJvb2xlYW4gdmFsdWUpIHRocm93cyAgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlmb3IgKGludCBpID0gMDsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspIHsKKwkgICAgdHJ5IHsKKwkJbXNnc1tpXS5zZXRGbGFncyhmbGFnLCB2YWx1ZSk7CisJICAgIH0gY2F0Y2ggKE1lc3NhZ2VSZW1vdmVkRXhjZXB0aW9uIG1lKSB7CisJCS8vIFRoaXMgbWVzc2FnZSBpcyBleHB1bmdlZCwgc2tpcCAKKwkgICAgfQorCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHNwZWNpZmllZCBmbGFncyBvbiB0aGUgbWVzc2FnZXMgbnVtYmVyZWQgZnJvbSBzdGFydAorICAgICAqIHRocm91Z2ggZW5kLCBib3RoIHN0YXJ0IGFuZCBlbmQgaW5jbHVzaXZlLiBOb3RlIHRoYXQgbWVzc2FnZSAKKyAgICAgKiBudW1iZXJzIHN0YXJ0IGF0IDEsIG5vdCAwLgorICAgICAqIFRoaXMgd2lsbCByZXN1bHQgaW4gYXBwcm9wcmlhdGUgTWVzc2FnZUNoYW5nZWRFdmVudHMgYmVpbmcKKyAgICAgKiBkZWxpdmVyZWQgdG8gYW55IE1lc3NhZ2VDaGFuZ2VkTGlzdGVuZXIgcmVnaXN0ZXJlZCBvbiB0aGlzCisgICAgICogTWVzc2FnZSdzIGNvbnRhaW5pbmcgZm9sZGVyLiA8cD4KKyAgICAgKgorICAgICAqIENlcnRhaW4gRm9sZGVyIGltcGxlbWVudGF0aW9ucyBjYW4KKyAgICAgKiBvcHRpbWl6ZSB0aGUgb3BlcmF0aW9uIG9mIHNldHRpbmcgRmxhZ3MgZm9yIGEgZ3JvdXAgb2YgbWVzc2FnZXMsCisgICAgICogc28gY2xpZW50cyBtaWdodCB3YW50IHRvIHVzZSB0aGlzIG1ldGhvZCwgcmF0aGVyIHRoYW4gaW52b2tpbmcKKyAgICAgKiA8Y29kZT5NZXNzYWdlLnNldEZsYWdzPC9jb2RlPiBmb3IgZWFjaCBNZXNzYWdlLiA8cD4KKyAgICAgKgorICAgICAqIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIHVzZXMgPGNvZGU+Z2V0TWVzc2FnZShpbnQpPC9jb2RlPiB0bworICAgICAqIGdldCBlYWNoIDxjb2RlPk1lc3NhZ2U8L2NvZGU+IG9iamVjdCBhbmQgdGhlbiBpbnZva2VzCisgICAgICogPGNvZGU+c2V0RmxhZ3M8L2NvZGU+IG9uIHRoYXQgb2JqZWN0IHRvIHNldCB0aGUgZmxhZ3MuCisgICAgICogU3BlY2lmaWMgRm9sZGVyIGltcGxlbWVudGF0aW9ucyB0aGF0IGNhbiBvcHRpbWl6ZSB0aGlzIGNhc2Ugc2hvdWxkIGRvIHNvLgorICAgICAqIEFsc28sIGFuIGltcGxlbWVudGF0aW9uIG11c3Qgbm90IGFib3J0IHRoZSBvcGVyYXRpb24gaWYgYSBtZXNzYWdlIAorICAgICAqIG51bWJlciByZWZlcnMgdG8gYW4gZXhwdW5nZWQgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdGFydAl0aGUgbnVtYmVyIG9mIHRoZSBmaXJzdCBtZXNzYWdlCisgICAgICogQHBhcmFtIGVuZAl0aGUgbnVtYmVyIG9mIHRoZSBsYXN0IG1lc3NhZ2UKKyAgICAgKiBAcGFyYW0gZmxhZwlGbGFncyBvYmplY3QgY29udGFpbmluZyB0aGUgZmxhZ3MgdG8gYmUgc2V0CisgICAgICogQHBhcmFtIHZhbHVlCXNldCB0aGUgZmxhZ3MgdG8gdGhpcyBib29sZWFuIHZhbHVlCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBmb2xkZXIgaXMgbm90IG9wZW5lZAorICAgICAqCQkJb3IgaWYgaXQgaGFzIGJlZW4gb3BlbmVkIFJFQURfT05MWS4KKyAgICAgKiBAZXhjZXB0aW9uCUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWYgdGhlIHN0YXJ0IG9yIGVuZAorICAgICAqCQkJbWVzc2FnZSBudW1iZXJzIGFyZSBvdXQgb2YgcmFuZ2UuCisgICAgICogQGV4Y2VwdGlvbiAJTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBvdGhlciBmYWlsdXJlcworICAgICAqIEBzZWUJCU1lc3NhZ2Ujc2V0RmxhZ3MKKyAgICAgKiBAc2VlCQlqYXZheC5tYWlsLmV2ZW50Lk1lc3NhZ2VDaGFuZ2VkRXZlbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgc2V0RmxhZ3MoaW50IHN0YXJ0LCBpbnQgZW5kLAorCQkJRmxhZ3MgZmxhZywgYm9vbGVhbiB2YWx1ZSkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJZm9yIChpbnQgaSA9IHN0YXJ0OyBpIDw9IGVuZDsgaSsrKSB7CisJICAgIHRyeSB7CisJCU1lc3NhZ2UgbXNnID0gZ2V0TWVzc2FnZShpKTsKKwkJbXNnLnNldEZsYWdzKGZsYWcsIHZhbHVlKTsKKwkgICAgfSBjYXRjaCAoTWVzc2FnZVJlbW92ZWRFeGNlcHRpb24gbWUpIHsKKwkJLy8gVGhpcyBtZXNzYWdlIGlzIGV4cHVuZ2VkLCBza2lwIAorCSAgICB9CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgc3BlY2lmaWVkIGZsYWdzIG9uIHRoZSBtZXNzYWdlcyB3aG9zZSBtZXNzYWdlIG51bWJlcnMKKyAgICAgKiBhcmUgaW4gdGhlIGFycmF5LgorICAgICAqIFRoaXMgd2lsbCByZXN1bHQgaW4gYXBwcm9wcmlhdGUgTWVzc2FnZUNoYW5nZWRFdmVudHMgYmVpbmcKKyAgICAgKiBkZWxpdmVyZWQgdG8gYW55IE1lc3NhZ2VDaGFuZ2VkTGlzdGVuZXIgcmVnaXN0ZXJlZCBvbiB0aGlzCisgICAgICogTWVzc2FnZSdzIGNvbnRhaW5pbmcgZm9sZGVyLiA8cD4KKyAgICAgKgorICAgICAqIENlcnRhaW4gRm9sZGVyIGltcGxlbWVudGF0aW9ucyBjYW4KKyAgICAgKiBvcHRpbWl6ZSB0aGUgb3BlcmF0aW9uIG9mIHNldHRpbmcgRmxhZ3MgZm9yIGEgZ3JvdXAgb2YgbWVzc2FnZXMsCisgICAgICogc28gY2xpZW50cyBtaWdodCB3YW50IHRvIHVzZSB0aGlzIG1ldGhvZCwgcmF0aGVyIHRoYW4gaW52b2tpbmcKKyAgICAgKiA8Y29kZT5NZXNzYWdlLnNldEZsYWdzPC9jb2RlPiBmb3IgZWFjaCBNZXNzYWdlLiA8cD4KKyAgICAgKgorICAgICAqIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIHVzZXMgPGNvZGU+Z2V0TWVzc2FnZShpbnQpPC9jb2RlPiB0bworICAgICAqIGdldCBlYWNoIDxjb2RlPk1lc3NhZ2U8L2NvZGU+IG9iamVjdCBhbmQgdGhlbiBpbnZva2VzCisgICAgICogPGNvZGU+c2V0RmxhZ3M8L2NvZGU+IG9uIHRoYXQgb2JqZWN0IHRvIHNldCB0aGUgZmxhZ3MuCisgICAgICogU3BlY2lmaWMgRm9sZGVyIGltcGxlbWVudGF0aW9ucyB0aGF0IGNhbiBvcHRpbWl6ZSB0aGlzIGNhc2Ugc2hvdWxkIGRvIHNvLgorICAgICAqIEFsc28sIGFuIGltcGxlbWVudGF0aW9uIG11c3Qgbm90IGFib3J0IHRoZSBvcGVyYXRpb24gaWYgYSBtZXNzYWdlIAorICAgICAqIG51bWJlciByZWZlcnMgdG8gYW4gZXhwdW5nZWQgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtc2dudW1zCXRoZSBhcnJheSBvZiBtZXNzYWdlIG51bWJlcnMKKyAgICAgKiBAcGFyYW0gZmxhZwlGbGFncyBvYmplY3QgY29udGFpbmluZyB0aGUgZmxhZ3MgdG8gYmUgc2V0CisgICAgICogQHBhcmFtIHZhbHVlCXNldCB0aGUgZmxhZ3MgdG8gdGhpcyBib29sZWFuIHZhbHVlCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBmb2xkZXIgaXMgbm90IG9wZW5lZAorICAgICAqCQkJb3IgaWYgaXQgaGFzIGJlZW4gb3BlbmVkIFJFQURfT05MWS4KKyAgICAgKiBAZXhjZXB0aW9uCUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWYgYW55IG1lc3NhZ2UgbnVtYmVyCisgICAgICoJCQlpbiB0aGUgZ2l2ZW4gYXJyYXkgaXMgb3V0IG9mIHJhbmdlLgorICAgICAqIEBleGNlcHRpb24gCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKiBAc2VlCQlNZXNzYWdlI3NldEZsYWdzCisgICAgICogQHNlZQkJamF2YXgubWFpbC5ldmVudC5NZXNzYWdlQ2hhbmdlZEV2ZW50CisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHNldEZsYWdzKGludFtdIG1zZ251bXMsCisJCQlGbGFncyBmbGFnLCBib29sZWFuIHZhbHVlKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlmb3IgKGludCBpID0gMDsgaSA8IG1zZ251bXMubGVuZ3RoOyBpKyspIHsKKwkgICAgdHJ5IHsKKwkJTWVzc2FnZSBtc2cgPSBnZXRNZXNzYWdlKG1zZ251bXNbaV0pOworCQltc2cuc2V0RmxhZ3MoZmxhZywgdmFsdWUpOworCSAgICB9IGNhdGNoIChNZXNzYWdlUmVtb3ZlZEV4Y2VwdGlvbiBtZSkgeworCQkvLyBUaGlzIG1lc3NhZ2UgaXMgZXhwdW5nZWQsIHNraXAgCisJICAgIH0KKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29weSB0aGUgc3BlY2lmaWVkIE1lc3NhZ2VzIGZyb20gdGhpcyBGb2xkZXIgaW50byBhbm90aGVyIAorICAgICAqIEZvbGRlci4gVGhpcyBvcGVyYXRpb24gYXBwZW5kcyB0aGVzZSBNZXNzYWdlcyB0byB0aGUgCisgICAgICogZGVzdGluYXRpb24gRm9sZGVyLiBUaGUgZGVzdGluYXRpb24gRm9sZGVyIGRvZXMgbm90IGhhdmUgdG8gCisgICAgICogYmUgb3BlbmVkLiAgQW4gYXBwcm9wcmlhdGUgTWVzc2FnZUNvdW50RXZlbnQgCisgICAgICogaXMgZGVsaXZlcmVkIHRvIGFueSBNZXNzYWdlQ291bnRMaXN0ZW5lciByZWdpc3RlcmVkIG9uIHRoZSAKKyAgICAgKiBkZXN0aW5hdGlvbiBmb2xkZXIgd2hlbiB0aGUgbWVzc2FnZXMgYXJyaXZlIGluIHRoZSBmb2xkZXIuIDxwPgorICAgICAqCisgICAgICogTm90ZSB0aGF0IHRoZSBzcGVjaWZpZWQgTWVzc2FnZSBvYmplY3RzIDxzdHJvbmc+bXVzdDwvc3Ryb25nPiAKKyAgICAgKiBiZWxvbmcgdG8gdGhpcyBmb2xkZXIuIEZvbGRlciBpbXBsZW1lbnRhdGlvbnMgbWlnaHQgYmUgYWJsZQorICAgICAqIHRvIG9wdGltaXplIHRoaXMgbWV0aG9kIGJ5IGRvaW5nIHNlcnZlci1zaWRlIGNvcGllcy4gPHA+CisgICAgICoKKyAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIGp1c3QgaW52b2tlcyA8Y29kZT5hcHBlbmRNZXNzYWdlcygpPC9jb2RlPgorICAgICAqIG9uIHRoZSBkZXN0aW5hdGlvbiBmb2xkZXIgdG8gYXBwZW5kIHRoZSBnaXZlbiBNZXNzYWdlcy4gU3BlY2lmaWMKKyAgICAgKiBmb2xkZXIgaW1wbGVtZW50YXRpb25zIHRoYXQgc3VwcG9ydCBzZXJ2ZXItc2lkZSBjb3BpZXMgc2hvdWxkCisgICAgICogZG8gc28sIGlmIHRoZSBkZXN0aW5hdGlvbiBmb2xkZXIncyBTdG9yZSBpcyB0aGUgc2FtZSBhcyB0aGlzCisgICAgICogZm9sZGVyJ3MgU3RvcmUuIAorICAgICAqIEFsc28sIGFuIGltcGxlbWVudGF0aW9uIG11c3Qgbm90IGFib3J0IHRoZSBvcGVyYXRpb24gaWYgYSAKKyAgICAgKiBNZXNzYWdlIGluIHRoZSBhcnJheSB0dXJucyBvdXQgdG8gYmUgYW4gZXhwdW5nZWQgTWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtc2dzCXRoZSBhcnJheSBvZiBtZXNzYWdlIG9iamVjdHMKKyAgICAgKiBAcGFyYW0gZm9sZGVyCXRoZSBmb2xkZXIgdG8gY29weSB0aGUgbWVzc2FnZXMgdG8KKyAgICAgKiBAZXhjZXB0aW9uCUZvbGRlck5vdEZvdW5kRXhjZXB0aW9uIGlmIHRoZSBkZXN0aW5hdGlvbgorICAgICAqCQkJZm9sZGVyIGRvZXMgbm90IGV4aXN0LgorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgZm9sZGVyIGlzIG5vdCBvcGVuZWQuCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICogQHNlZQkJI2FwcGVuZE1lc3NhZ2VzCisgICAgICovCisgICAgcHVibGljIHZvaWQgY29weU1lc3NhZ2VzKE1lc3NhZ2VbXSBtc2dzLCBGb2xkZXIgZm9sZGVyKQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWlmICghZm9sZGVyLmV4aXN0cygpKQorCSAgICB0aHJvdyBuZXcgRm9sZGVyTm90Rm91bmRFeGNlcHRpb24oCisJCQlmb2xkZXIuZ2V0RnVsbE5hbWUoKSArICIgZG9lcyBub3QgZXhpc3QiLAorCQkJZm9sZGVyKTsKKworCWZvbGRlci5hcHBlbmRNZXNzYWdlcyhtc2dzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFeHB1bmdlIChwZXJtYW5lbnRseSByZW1vdmUpIG1lc3NhZ2VzIG1hcmtlZCBERUxFVEVELiBSZXR1cm5zIGFuCisgICAgICogYXJyYXkgY29udGFpbmluZyB0aGUgZXhwdW5nZWQgbWVzc2FnZSBvYmplY3RzLiAgVGhlCisgICAgICogPGNvZGU+Z2V0TWVzc2FnZU51bWJlcjwvY29kZT4gbWV0aG9kCisgICAgICogb24gZWFjaCBvZiB0aGVzZSBtZXNzYWdlIG9iamVjdHMgcmV0dXJucyB0aGF0IE1lc3NhZ2UncyBvcmlnaW5hbAorICAgICAqICh0aGF0IGlzLCBwcmlvciB0byB0aGUgZXhwdW5nZSkgc2VxdWVuY2UgbnVtYmVyLiBBIE1lc3NhZ2VDb3VudEV2ZW50IAorICAgICAqIGNvbnRhaW5pbmcgdGhlIGV4cHVuZ2VkIG1lc3NhZ2VzIGlzIGRlbGl2ZXJlZCB0byBhbnkgCisgICAgICogTWVzc2FnZUNvdW50TGlzdGVuZXJzIHJlZ2lzdGVyZWQgb24gdGhlIGZvbGRlci4gPHA+CisgICAgICoKKyAgICAgKiBFeHB1bmdlIGNhdXNlcyB0aGUgcmVudW1iZXJpbmcgb2YgTWVzc2FnZSBvYmplY3RzIHN1YnNlcXVlbnQgdG8KKyAgICAgKiB0aGUgZXhwdW5nZWQgbWVzc2FnZXMuIENsaWVudHMgdGhhdCB1c2UgbWVzc2FnZSBudW1iZXJzIGFzIAorICAgICAqIHJlZmVyZW5jZXMgdG8gbWVzc2FnZXMgc2hvdWxkIGJlIGF3YXJlIG9mIHRoaXMgYW5kIHNob3VsZCBiZSAKKyAgICAgKiBwcmVwYXJlZCB0byBkZWFsIHdpdGggdGhlIHNpdHVhdGlvbiAocHJvYmFibHkgYnkgZmx1c2hpbmcgb3V0IAorICAgICAqIGV4aXN0aW5nIG1lc3NhZ2UgbnVtYmVyIGNhY2hlcyBhbmQgcmVsb2FkaW5nIHRoZW0pLiBCZWNhdXNlIG9mIAorICAgICAqIHRoaXMgY29tcGxleGl0eSwgaXQgaXMgYmV0dGVyIGZvciBjbGllbnRzIHRvIHVzZSBNZXNzYWdlIG9iamVjdHMKKyAgICAgKiBhcyByZWZlcmVuY2VzIHRvIG1lc3NhZ2VzLCByYXRoZXIgdGhhbiBtZXNzYWdlIG51bWJlcnMuIEFueSAKKyAgICAgKiBleHB1bmdlZCBNZXNzYWdlcyBvYmplY3RzIHN0aWxsIGhhdmUgdG8gYmUgcHJ1bmVkLCBidXQgb3RoZXIgCisgICAgICogTWVzc2FnZXMgaW4gdGhhdCBmb2xkZXIgYXJlIG5vdCBhZmZlY3RlZCBieSB0aGUgZXhwdW5nZS4gPHA+CisgICAgICoKKyAgICAgKiBBZnRlciBhIG1lc3NhZ2UgaXMgZXhwdW5nZWQsIG9ubHkgdGhlIDxjb2RlPmlzRXhwdW5nZWQ8L2NvZGU+IGFuZCAKKyAgICAgKiA8Y29kZT5nZXRNZXNzYWdlTnVtYmVyPC9jb2RlPiBtZXRob2RzIGFyZSBzdGlsbCB2YWxpZCBvbiB0aGUKKyAgICAgKiBjb3JyZXNwb25kaW5nIE1lc3NhZ2Ugb2JqZWN0OyBvdGhlciBtZXRob2RzIG1heSB0aHJvdworICAgICAqIDxjb2RlPk1lc3NhZ2VSZW1vdmVkRXhjZXB0aW9uPC9jb2RlPgorICAgICAqCisgICAgICogQHJldHVybgkJYXJyYXkgb2YgZXhwdW5nZWQgTWVzc2FnZSBvYmplY3RzCisgICAgICogQGV4Y2VwdGlvbglGb2xkZXJOb3RGb3VuZEV4Y2VwdGlvbiBpZiB0aGlzIGZvbGRlciBkb2VzIG5vdAorICAgICAqCQkJZXhpc3QKKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIGZvbGRlciBpcyBub3Qgb3BlbmVkLgorICAgICAqIEBleGNlcHRpb24gICAgICAgTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBvdGhlciBmYWlsdXJlcworICAgICAqIEBzZWUJCU1lc3NhZ2UjaXNFeHB1bmdlZAorICAgICAqIEBzZWUJCWphdmF4Lm1haWwuZXZlbnQuTWVzc2FnZUNvdW50RXZlbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgTWVzc2FnZVtdIGV4cHVuZ2UoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2VhcmNoIHRoaXMgRm9sZGVyIGZvciBtZXNzYWdlcyBtYXRjaGluZyB0aGUgc3BlY2lmaWVkCisgICAgICogc2VhcmNoIGNyaXRlcmlvbi4gUmV0dXJucyBhbiBhcnJheSBjb250YWluaW5nIHRoZSBtYXRjaGluZworICAgICAqIG1lc3NhZ2VzIC4gUmV0dXJucyBhbiBlbXB0eSBhcnJheSBpZiBubyBtYXRjaGVzIHdlcmUgZm91bmQuIDxwPgorICAgICAqCisgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiBpbnZva2VzIAorICAgICAqIDxjb2RlPnNlYXJjaCh0ZXJtLCBnZXRNZXNzYWdlcygpKTwvY29kZT4sIHRvIGFwcGx5IHRoZSBzZWFyY2ggCisgICAgICogb3ZlciBhbGwgdGhlIG1lc3NhZ2VzIGluIHRoaXMgZm9sZGVyLiBQcm92aWRlcnMgdGhhdCBjYW4gaW1wbGVtZW50CisgICAgICogc2VydmVyLXNpZGUgc2VhcmNoaW5nIG1pZ2h0IHdhbnQgdG8gb3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8gcHJvdmlkZQorICAgICAqIGEgbW9yZSBlZmZpY2llbnQgaW1wbGVtZW50YXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGVybQl0aGUgc2VhcmNoIGNyaXRlcmlvbgorICAgICAqIEByZXR1cm4gCQlhcnJheSBvZiBtYXRjaGluZyBtZXNzYWdlcyAKKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIGphdmF4Lm1haWwuc2VhcmNoLlNlYXJjaEV4Y2VwdGlvbiBpZiB0aGUgc2VhcmNoIAorICAgICAqCQkJdGVybSBpcyB0b28gY29tcGxleCBmb3IgdGhlIGltcGxlbWVudGF0aW9uIHRvIGhhbmRsZS4KKyAgICAgKiBAZXhjZXB0aW9uCUZvbGRlck5vdEZvdW5kRXhjZXB0aW9uIGlmIHRoaXMgZm9sZGVyIGRvZXMgCisgICAgICoJCQlub3QgZXhpc3QuCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBmb2xkZXIgaXMgbm90IG9wZW5lZC4KKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIE1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKiBAc2VlCQlqYXZheC5tYWlsLnNlYXJjaC5TZWFyY2hUZXJtCisgICAgICovCisgICAgcHVibGljIE1lc3NhZ2VbXSBzZWFyY2goU2VhcmNoVGVybSB0ZXJtKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gc2VhcmNoKHRlcm0sIGdldE1lc3NhZ2VzKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNlYXJjaCB0aGUgZ2l2ZW4gYXJyYXkgb2YgbWVzc2FnZXMgZm9yIHRob3NlIHRoYXQgbWF0Y2ggdGhlIAorICAgICAqIHNwZWNpZmllZCBzZWFyY2ggY3JpdGVyaW9uLiBSZXR1cm5zIGFuIGFycmF5IGNvbnRhaW5pbmcgdGhlIAorICAgICAqIG1hdGNoaW5nIG1lc3NhZ2VzLiBSZXR1cm5zIGFuIGVtcHR5IGFycmF5IGlmIG5vIG1hdGNoZXMgd2VyZSAKKyAgICAgKiBmb3VuZC4gPHA+CisgICAgICoKKyAgICAgKiBOb3RlIHRoYXQgdGhlIHNwZWNpZmllZCBNZXNzYWdlIG9iamVjdHMgPHN0cm9uZz5tdXN0PC9zdHJvbmc+IAorICAgICAqIGJlbG9uZyB0byB0aGlzIGZvbGRlci4gPHA+CisgICAgICoKKyAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIGl0ZXJhdGVzIHRocm91Z2ggdGhlIGdpdmVuIGFycmF5IG9mIG1lc3NhZ2VzLAorICAgICAqIGFuZCBhcHBsaWVzIHRoZSBzZWFyY2ggY3JpdGVyaW9uIG9uIGVhY2ggbWVzc2FnZSBieSBjYWxsaW5nCisgICAgICogaXRzIDxjb2RlPm1hdGNoKCk8L2NvZGU+IG1ldGhvZCB3aXRoIHRoZSBnaXZlbiB0ZXJtLiBUaGUKKyAgICAgKiBtZXNzYWdlcyB0aGF0IHN1Y2NlZWQgaW4gdGhlIG1hdGNoIGFyZSByZXR1cm5lZC4gUHJvdmlkZXJzCisgICAgICogdGhhdCBjYW4gaW1wbGVtZW50IHNlcnZlci1zaWRlIHNlYXJjaGluZyBtaWdodCB3YW50IHRvIG92ZXJyaWRlCisgICAgICogdGhpcyBtZXRob2QgdG8gcHJvdmlkZSBhIG1vcmUgZWZmaWNpZW50IGltcGxlbWVudGF0aW9uLiBJZiB0aGUKKyAgICAgKiBzZWFyY2ggdGVybSBpcyB0b28gY29tcGxleCBvciBjb250YWlucyB1c2VyLWRlZmluZWQgdGVybXMgdGhhdAorICAgICAqIGNhbm5vdCBiZSBleGVjdXRlZCBvbiB0aGUgc2VydmVyLCBwcm92aWRlcnMgbWF5IGVsZWN0IHRvIGVpdGhlcgorICAgICAqIHRocm93IGEgU2VhcmNoRXhjZXB0aW9uIG9yIGRlZ2VuZXJhdGUgdG8gY2xpZW50LXNpZGUgc2VhcmNoaW5nIGJ5CisgICAgICogY2FsbGluZyA8Y29kZT5zdXBlci5zZWFyY2goKTwvY29kZT4gdG8gaW52b2tlIHRoaXMgaW1wbGVtZW50YXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGVybQl0aGUgc2VhcmNoIGNyaXRlcmlvbgorICAgICAqIEBwYXJhbSBtc2dzIAl0aGUgbWVzc2FnZXMgdG8gYmUgc2VhcmNoZWQKKyAgICAgKiBAcmV0dXJuIAkJYXJyYXkgb2YgbWF0Y2hpbmcgbWVzc2FnZXMgCisgICAgICogQGV4Y2VwdGlvbiAgICAgICBqYXZheC5tYWlsLnNlYXJjaC5TZWFyY2hFeGNlcHRpb24gaWYgdGhlIHNlYXJjaCAKKyAgICAgKgkJCXRlcm0gaXMgdG9vIGNvbXBsZXggZm9yIHRoZSBpbXBsZW1lbnRhdGlvbiB0byBoYW5kbGUuCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBmb2xkZXIgaXMgbm90IG9wZW5lZAorICAgICAqIEBleGNlcHRpb24gICAgICAgTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBvdGhlciBmYWlsdXJlcworICAgICAqIEBzZWUJCWphdmF4Lm1haWwuc2VhcmNoLlNlYXJjaFRlcm0KKyAgICAgKi8KKyAgICBwdWJsaWMgTWVzc2FnZVtdIHNlYXJjaChTZWFyY2hUZXJtIHRlcm0sIE1lc3NhZ2VbXSBtc2dzKQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCUxpc3Q8TWVzc2FnZT4gbWF0Y2hlZE1zZ3MgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKworCS8vIFJ1biB0aHJ1IHRoZSBnaXZlbiBtZXNzYWdlcworCWZvciAoTWVzc2FnZSBtc2cgOiBtc2dzKSB7CisJICAgIHRyeSB7CisJCWlmIChtc2cubWF0Y2godGVybSkpIC8vIG1hdGNoZWQKKwkJICAgIG1hdGNoZWRNc2dzLmFkZChtc2cpOyAvLyBhZGQgaXQKKwkgICAgfSBjYXRjaChNZXNzYWdlUmVtb3ZlZEV4Y2VwdGlvbiBtcmV4KSB7IH0KKwl9CisKKwlyZXR1cm4gbWF0Y2hlZE1zZ3MudG9BcnJheShuZXcgTWVzc2FnZVttYXRjaGVkTXNncy5zaXplKCldKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIFRoZSBzZXQgb2YgbGlzdGVuZXJzIGFyZSBzdG9yZWQgaW4gVmVjdG9ycyBhcHByb3ByaWF0ZSB0byB0aGVpcgorICAgICAqIHR5cGUuICBXZSBtYXJrIGFsbCBsaXN0ZW5lciBWZWN0b3JzIGFzICJ2b2xhdGlsZSIgYmVjYXVzZSwgd2hpbGUKKyAgICAgKiB3ZSBpbml0aWFsaXplIHRoZW0gaW5zaWRlIHRoaXMgZm9sZGVyJ3Mgc3luY2hyb25pemF0aW9uIGxvY2ssCisgICAgICogdGhleSBhcmUgYWNjZXNzZWQgKGNoZWNrZWQgZm9yIG51bGwpIGluIHRoZSAibm90aWZ5IiBtZXRob2RzLAorICAgICAqIHdoaWNoIGNhbid0IGJlIHN5bmNocm9uaXplZCBkdWUgdG8gbG9jayBvcmRlcmluZyBjb25zdHJhaW50cy4KKyAgICAgKiBTaW5jZSB0aGUgbGlzdGVuZXIgZmllbGRzICh0aGUgaGFuZGxlcyBvbiB0aGUgVmVjdG9yIG9iamVjdHMpCisgICAgICogYXJlIG9ubHkgZXZlciBzZXQsIGFuZCBhcmUgbmV2ZXIgY2xlYXJlZCwgd2UgYmVsaWV2ZSB0aGlzIGlzCisgICAgICogc2FmZS4gIFRoZSBjb2RlIHRoYXQgZGlzcGF0Y2hlcyB0aGUgbm90aWZpY2F0aW9ucyB3aWxsIGVpdGhlcgorICAgICAqIHNlZSB0aGUgbnVsbCBhbmQgYXNzdW1lIHRoZXJlIGFyZSBubyBsaXN0ZW5lcnMgb3Igd2lsbCBzZWUgdGhlCisgICAgICogVmVjdG9yIGFuZCB3aWxsIHByb2Nlc3MgdGhlIGxpc3RlbmVycy4gIFRoZXJlJ3MgYW4gaW5oZXJlbnQgcmFjZQorICAgICAqIGJldHdlZW4gYWRkaW5nIGEgbGlzdGVuZXIgYW5kIG5vdGlmeWluZyB0aGUgbGlzdGVuZXJzOyB0aGUgbGFjaworICAgICAqIG9mIHN5bmNocm9uaXphdGlvbiBkdXJpbmcgbm90aWZpY2F0aW9uIGRvZXMgbm90IG1ha2UgdGhlIHJhY2UKKyAgICAgKiBjb25kaXRpb24gc2lnbmlmaWNhbnRseSB3b3JzZS4gIElmIG9uZSB0aHJlYWQgaXMgc2V0dGluZyBhCisgICAgICogbGlzdGVuZXIgYXQgdGhlICJzYW1lIiB0aW1lIGFuIGV2ZW50IGlzIGJlaW5nIGRpc3BhdGNoZWQsIHRoZQorICAgICAqIGRpc3BhdGNoIGNvZGUgbWlnaHQgbm90IHNlZSB0aGUgbGlzdGVuZXIgcmlnaHQgYXdheS4gIFRoZQorICAgICAqIGRpc3BhdGNoIGNvZGUgZG9lc24ndCBoYXZlIHRvIHdvcnJ5IGFib3V0IHRoZSBWZWN0b3IgaGFuZGxlCisgICAgICogYmVpbmcgc2V0IHRvIG51bGwsIGFuZCB0aHVzIHVzaW5nIGFuIG91dC1vZi1kYXRlIHNldCBvZgorICAgICAqIGxpc3RlbmVycywgYmVjYXVzZSB3ZSBuZXZlciBzZXQgdGhlIGZpZWxkIHRvIG51bGwuCisgICAgICovCisKKyAgICAvLyBWZWN0b3Igb2YgY29ubmVjdGlvbiBsaXN0ZW5lcnMuCisgICAgcHJpdmF0ZSB2b2xhdGlsZSBWZWN0b3I8Q29ubmVjdGlvbkxpc3RlbmVyPiBjb25uZWN0aW9uTGlzdGVuZXJzID0gbnVsbDsKKworICAgIC8qKgorICAgICAqIEFkZCBhIGxpc3RlbmVyIGZvciBDb25uZWN0aW9uIGV2ZW50cyBvbiB0aGlzIEZvbGRlci4gPHA+CisgICAgICoKKyAgICAgKiBUaGUgaW1wbGVtZW50YXRpb24gcHJvdmlkZWQgaGVyZSBhZGRzIHRoaXMgbGlzdGVuZXIKKyAgICAgKiB0byBhbiBpbnRlcm5hbCBsaXN0IG9mIENvbm5lY3Rpb25MaXN0ZW5lcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbCAJdGhlIExpc3RlbmVyIGZvciBDb25uZWN0aW9uIGV2ZW50cworICAgICAqIEBzZWUJCWphdmF4Lm1haWwuZXZlbnQuQ29ubmVjdGlvbkV2ZW50CisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkCisgICAgYWRkQ29ubmVjdGlvbkxpc3RlbmVyKENvbm5lY3Rpb25MaXN0ZW5lciBsKSB7IAorICAgCWlmIChjb25uZWN0aW9uTGlzdGVuZXJzID09IG51bGwpIAorCSAgICBjb25uZWN0aW9uTGlzdGVuZXJzID0gbmV3IFZlY3Rvcjw+KCk7CisJY29ubmVjdGlvbkxpc3RlbmVycy5hZGRFbGVtZW50KGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZSBhIENvbm5lY3Rpb24gZXZlbnQgbGlzdGVuZXIuIDxwPgorICAgICAqCisgICAgICogVGhlIGltcGxlbWVudGF0aW9uIHByb3ZpZGVkIGhlcmUgcmVtb3ZlcyB0aGlzIGxpc3RlbmVyCisgICAgICogZnJvbSB0aGUgaW50ZXJuYWwgbGlzdCBvZiBDb25uZWN0aW9uTGlzdGVuZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIGwgCXRoZSBsaXN0ZW5lcgorICAgICAqIEBzZWUJCSNhZGRDb25uZWN0aW9uTGlzdGVuZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQKKyAgICByZW1vdmVDb25uZWN0aW9uTGlzdGVuZXIoQ29ubmVjdGlvbkxpc3RlbmVyIGwpIHsgCisgICAJaWYgKGNvbm5lY3Rpb25MaXN0ZW5lcnMgIT0gbnVsbCkgCisJICAgIGNvbm5lY3Rpb25MaXN0ZW5lcnMucmVtb3ZlRWxlbWVudChsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBOb3RpZnkgYWxsIENvbm5lY3Rpb25MaXN0ZW5lcnMuIEZvbGRlciBpbXBsZW1lbnRhdGlvbnMgYXJlCisgICAgICogZXhwZWN0ZWQgdG8gdXNlIHRoaXMgbWV0aG9kIHRvIGJyb2FkY2FzdCBjb25uZWN0aW9uIGV2ZW50cy4gPHA+CisgICAgICoKKyAgICAgKiBUaGUgcHJvdmlkZWQgaW1wbGVtZW50YXRpb24gcXVldWVzIHRoZSBldmVudCBpbnRvCisgICAgICogYW4gaW50ZXJuYWwgZXZlbnQgcXVldWUuIEFuIGV2ZW50IGRpc3BhdGNoZXIgdGhyZWFkIGRlcXVldWVzCisgICAgICogZXZlbnRzIGZyb20gdGhlIHF1ZXVlIGFuZCBkaXNwYXRjaGVzIHRoZW0gdG8gdGhlIHJlZ2lzdGVyZWQKKyAgICAgKiBDb25uZWN0aW9uTGlzdGVuZXJzLiBOb3RlIHRoYXQgdGhlIGV2ZW50IGRpc3BhdGNoaW5nIG9jY3VycworICAgICAqIGluIGEgc2VwYXJhdGUgdGhyZWFkLCB0aHVzIGF2b2lkaW5nIHBvdGVudGlhbCBkZWFkbG9jayBwcm9ibGVtcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0eXBlCXRoZSBDb25uZWN0aW9uRXZlbnQgdHlwZQorICAgICAqIEBzZWUJCWphdmF4Lm1haWwuZXZlbnQuQ29ubmVjdGlvbkV2ZW50CisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgbm90aWZ5Q29ubmVjdGlvbkxpc3RlbmVycyhpbnQgdHlwZSkgeworICAgCWlmIChjb25uZWN0aW9uTGlzdGVuZXJzICE9IG51bGwpIHsKKwkgICAgQ29ubmVjdGlvbkV2ZW50IGUgPSBuZXcgQ29ubmVjdGlvbkV2ZW50KHRoaXMsIHR5cGUpOworCSAgICBxdWV1ZUV2ZW50KGUsIGNvbm5lY3Rpb25MaXN0ZW5lcnMpOworCX0KKworCS8qIEZpeCBmb3IgYnJva2VuIEpESzEuMS54IEdhcmJhZ2UgY29sbGVjdG9yIDoKKwkgKiAgVGhlICdjb25zZXJ2YXRpdmUnIEdDIGluIEpESzEuMS54IG9jY2FzaW9uYWxseSBmYWlscyB0bworCSAqICBnYXJiYWdlLWNvbGxlY3QgVGhyZWFkcyB3aGljaCBhcmUgaW4gdGhlIHdhaXQgc3RhdGUuCisJICogIFRoaXMgd291bGQgcmVzdWx0IGluIHRocmVhZCAoYW5kIGNvbnNlcXVlbnRseSBtZW1vcnkpIGxlYWtzLgorCSAqIAorCSAqIFdlIGF0dGVtcHQgdG8gZml4IHRoaXMgYnkgc2VuZGluZyBhICd0ZXJtaW5hdG9yJyBldmVudAorCSAqIHRvIHRoZSBxdWV1ZSwgYWZ0ZXIgd2UndmUgc2VudCB0aGUgQ0xPU0VEIGV2ZW50LiBUaGUKKwkgKiB0ZXJtaW5hdG9yIGV2ZW50IGNhdXNlcyB0aGUgZXZlbnQtZGlzcGF0Y2hpbmcgdGhyZWFkIHRvCisJICogc2VsZiBkZXN0cnVjdC4KKwkgKi8KKwlpZiAodHlwZSA9PSBDb25uZWN0aW9uRXZlbnQuQ0xPU0VEKQorCSAgICBxLnRlcm1pbmF0ZVF1ZXVlKCk7CisgICAgfQorCisgICAgLy8gVmVjdG9yIG9mIGZvbGRlciBsaXN0ZW5lcnMKKyAgICBwcml2YXRlIHZvbGF0aWxlIFZlY3RvcjxGb2xkZXJMaXN0ZW5lcj4gZm9sZGVyTGlzdGVuZXJzID0gbnVsbDsKKworICAgIC8qKgorICAgICAqIEFkZCBhIGxpc3RlbmVyIGZvciBGb2xkZXIgZXZlbnRzIG9uIHRoaXMgRm9sZGVyLiA8cD4KKyAgICAgKgorICAgICAqIFRoZSBpbXBsZW1lbnRhdGlvbiBwcm92aWRlZCBoZXJlIGFkZHMgdGhpcyBsaXN0ZW5lcgorICAgICAqIHRvIGFuIGludGVybmFsIGxpc3Qgb2YgRm9sZGVyTGlzdGVuZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIGwgCXRoZSBMaXN0ZW5lciBmb3IgRm9sZGVyIGV2ZW50cworICAgICAqIEBzZWUJCWphdmF4Lm1haWwuZXZlbnQuRm9sZGVyRXZlbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgYWRkRm9sZGVyTGlzdGVuZXIoRm9sZGVyTGlzdGVuZXIgbCkgeyAKKyAgIAlpZiAoZm9sZGVyTGlzdGVuZXJzID09IG51bGwpCisJICAgIGZvbGRlckxpc3RlbmVycyA9IG5ldyBWZWN0b3I8PigpOworCWZvbGRlckxpc3RlbmVycy5hZGRFbGVtZW50KGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZSBhIEZvbGRlciBldmVudCBsaXN0ZW5lci4gPHA+CisgICAgICoKKyAgICAgKiBUaGUgaW1wbGVtZW50YXRpb24gcHJvdmlkZWQgaGVyZSByZW1vdmVzIHRoaXMgbGlzdGVuZXIKKyAgICAgKiBmcm9tIHRoZSBpbnRlcm5hbCBsaXN0IG9mIEZvbGRlckxpc3RlbmVycy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsIAl0aGUgbGlzdGVuZXIKKyAgICAgKiBAc2VlCQkjYWRkRm9sZGVyTGlzdGVuZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgcmVtb3ZlRm9sZGVyTGlzdGVuZXIoRm9sZGVyTGlzdGVuZXIgbCkgeworCWlmIChmb2xkZXJMaXN0ZW5lcnMgIT0gbnVsbCkKKwkgICAgZm9sZGVyTGlzdGVuZXJzLnJlbW92ZUVsZW1lbnQobCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTm90aWZ5IGFsbCBGb2xkZXJMaXN0ZW5lcnMgcmVnaXN0ZXJlZCBvbiB0aGlzIEZvbGRlciBhbmQKKyAgICAgKiB0aGlzIGZvbGRlcidzIFN0b3JlLiBGb2xkZXIgaW1wbGVtZW50YXRpb25zIGFyZSBleHBlY3RlZAorICAgICAqIHRvIHVzZSB0aGlzIG1ldGhvZCB0byBicm9hZGNhc3QgRm9sZGVyIGV2ZW50cy4gPHA+CisgICAgICoKKyAgICAgKiBUaGUgaW1wbGVtZW50YXRpb24gcHJvdmlkZWQgaGVyZSBxdWV1ZXMgdGhlIGV2ZW50IGludG8KKyAgICAgKiBhbiBpbnRlcm5hbCBldmVudCBxdWV1ZS4gQW4gZXZlbnQgZGlzcGF0Y2hlciB0aHJlYWQgZGVxdWV1ZXMKKyAgICAgKiBldmVudHMgZnJvbSB0aGUgcXVldWUgYW5kIGRpc3BhdGNoZXMgdGhlbSB0byB0aGUgCisgICAgICogRm9sZGVyTGlzdGVuZXJzIHJlZ2lzdGVyZWQgb24gdGhpcyBmb2xkZXIuIFRoZSBpbXBsZW1lbnRhdGlvbgorICAgICAqIGFsc28gaW52b2tlcyA8Y29kZT5ub3RpZnlGb2xkZXJMaXN0ZW5lcnM8L2NvZGU+IG9uIHRoaXMgZm9sZGVyJ3MKKyAgICAgKiBTdG9yZSB0byBub3RpZnkgYW55IEZvbGRlckxpc3RlbmVycyByZWdpc3RlcmVkIG9uIHRoZSBzdG9yZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0eXBlCXR5cGUgb2YgRm9sZGVyRXZlbnQKKyAgICAgKiBAc2VlCQkjbm90aWZ5Rm9sZGVyUmVuYW1lZExpc3RlbmVycworICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIG5vdGlmeUZvbGRlckxpc3RlbmVycyhpbnQgdHlwZSkgeyAKKyAgIAlpZiAoZm9sZGVyTGlzdGVuZXJzICE9IG51bGwpIHsKKwkgICAgRm9sZGVyRXZlbnQgZSA9IG5ldyBGb2xkZXJFdmVudCh0aGlzLCB0aGlzLCB0eXBlKTsKKwkgICAgcXVldWVFdmVudChlLCBmb2xkZXJMaXN0ZW5lcnMpOworCX0KKwlzdG9yZS5ub3RpZnlGb2xkZXJMaXN0ZW5lcnModHlwZSwgdGhpcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTm90aWZ5IGFsbCBGb2xkZXJMaXN0ZW5lcnMgcmVnaXN0ZXJlZCBvbiB0aGlzIEZvbGRlciBhbmQKKyAgICAgKiB0aGlzIGZvbGRlcidzIFN0b3JlIGFib3V0IHRoZSByZW5hbWluZyBvZiB0aGlzIGZvbGRlci4KKyAgICAgKiBGb2xkZXIgaW1wbGVtZW50YXRpb25zIGFyZSBleHBlY3RlZCB0byB1c2UgdGhpcyBtZXRob2QgdG8KKyAgICAgKiBicm9hZGNhc3QgRm9sZGVyIGV2ZW50cyBpbmRpY2F0aW5nIHRoZSByZW5hbWluZyBvZiBmb2xkZXJzLiA8cD4KKyAgICAgKgorICAgICAqIFRoZSBpbXBsZW1lbnRhdGlvbiBwcm92aWRlZCBoZXJlIHF1ZXVlcyB0aGUgZXZlbnQgaW50bworICAgICAqIGFuIGludGVybmFsIGV2ZW50IHF1ZXVlLiBBbiBldmVudCBkaXNwYXRjaGVyIHRocmVhZCBkZXF1ZXVlcworICAgICAqIGV2ZW50cyBmcm9tIHRoZSBxdWV1ZSBhbmQgZGlzcGF0Y2hlcyB0aGVtIHRvIHRoZSAKKyAgICAgKiBGb2xkZXJMaXN0ZW5lcnMgcmVnaXN0ZXJlZCBvbiB0aGlzIGZvbGRlci4gVGhlIGltcGxlbWVudGF0aW9uCisgICAgICogYWxzbyBpbnZva2VzIDxjb2RlPm5vdGlmeUZvbGRlclJlbmFtZWRMaXN0ZW5lcnM8L2NvZGU+IG9uIHRoaXMgCisgICAgICogZm9sZGVyJ3MgU3RvcmUgdG8gbm90aWZ5IGFueSBGb2xkZXJMaXN0ZW5lcnMgcmVnaXN0ZXJlZCBvbiB0aGUgc3RvcmUuCisgICAgICoKKyAgICAgKiBAcGFyYW0JZm9sZGVyCUZvbGRlciByZXByZXNlbnRpbmcgdGhlIG5ldyBuYW1lLgorICAgICAqIEBzZWUJCSNub3RpZnlGb2xkZXJMaXN0ZW5lcnMKKyAgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuMQorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIG5vdGlmeUZvbGRlclJlbmFtZWRMaXN0ZW5lcnMoRm9sZGVyIGZvbGRlcikgeworICAgCWlmIChmb2xkZXJMaXN0ZW5lcnMgIT0gbnVsbCkgeworCSAgICBGb2xkZXJFdmVudCBlID0gbmV3IEZvbGRlckV2ZW50KHRoaXMsIHRoaXMsIGZvbGRlciwKKwkJCQkJICAgIEZvbGRlckV2ZW50LlJFTkFNRUQpOworCSAgICBxdWV1ZUV2ZW50KGUsIGZvbGRlckxpc3RlbmVycyk7CisJfQorCXN0b3JlLm5vdGlmeUZvbGRlclJlbmFtZWRMaXN0ZW5lcnModGhpcywgZm9sZGVyKTsKKyAgICB9CisKKyAgICAvLyBWZWN0b3Igb2YgTWVzc2FnZUNvdW50IGxpc3RlbmVycworICAgIHByaXZhdGUgdm9sYXRpbGUgVmVjdG9yPE1lc3NhZ2VDb3VudExpc3RlbmVyPiBtZXNzYWdlQ291bnRMaXN0ZW5lcnMgPSBudWxsOworCisgICAgLyoqCisgICAgICogQWRkIGEgbGlzdGVuZXIgZm9yIE1lc3NhZ2VDb3VudCBldmVudHMgb24gdGhpcyBGb2xkZXIuIDxwPgorICAgICAqCisgICAgICogVGhlIGltcGxlbWVudGF0aW9uIHByb3ZpZGVkIGhlcmUgYWRkcyB0aGlzIGxpc3RlbmVyCisgICAgICogdG8gYW4gaW50ZXJuYWwgbGlzdCBvZiBNZXNzYWdlQ291bnRMaXN0ZW5lcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbCAJdGhlIExpc3RlbmVyIGZvciBNZXNzYWdlQ291bnQgZXZlbnRzCisgICAgICogQHNlZQkJamF2YXgubWFpbC5ldmVudC5NZXNzYWdlQ291bnRFdmVudAorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBhZGRNZXNzYWdlQ291bnRMaXN0ZW5lcihNZXNzYWdlQ291bnRMaXN0ZW5lciBsKSB7IAorICAgCWlmIChtZXNzYWdlQ291bnRMaXN0ZW5lcnMgPT0gbnVsbCkKKwkgICAgbWVzc2FnZUNvdW50TGlzdGVuZXJzID0gbmV3IFZlY3Rvcjw+KCk7CisJbWVzc2FnZUNvdW50TGlzdGVuZXJzLmFkZEVsZW1lbnQobCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlIGEgTWVzc2FnZUNvdW50IGxpc3RlbmVyLiA8cD4KKyAgICAgKgorICAgICAqIFRoZSBpbXBsZW1lbnRhdGlvbiBwcm92aWRlZCBoZXJlIHJlbW92ZXMgdGhpcyBsaXN0ZW5lcgorICAgICAqIGZyb20gdGhlIGludGVybmFsIGxpc3Qgb2YgTWVzc2FnZUNvdW50TGlzdGVuZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIGwgCXRoZSBsaXN0ZW5lcgorICAgICAqIEBzZWUJCSNhZGRNZXNzYWdlQ291bnRMaXN0ZW5lcgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZAorCQkJcmVtb3ZlTWVzc2FnZUNvdW50TGlzdGVuZXIoTWVzc2FnZUNvdW50TGlzdGVuZXIgbCkgeyAKKyAgIAlpZiAobWVzc2FnZUNvdW50TGlzdGVuZXJzICE9IG51bGwpIAorCSAgICBtZXNzYWdlQ291bnRMaXN0ZW5lcnMucmVtb3ZlRWxlbWVudChsKTsgCisgICAgfQorCisgICAgLyoqCisgICAgICogTm90aWZ5IGFsbCBNZXNzYWdlQ291bnRMaXN0ZW5lcnMgYWJvdXQgdGhlIGFkZGl0aW9uIG9mIG1lc3NhZ2VzCisgICAgICogaW50byB0aGlzIGZvbGRlci4gRm9sZGVyIGltcGxlbWVudGF0aW9ucyBhcmUgZXhwZWN0ZWQgdG8gdXNlIHRoaXMgCisgICAgICogbWV0aG9kIHRvIGJyb2FkY2FzdCBNZXNzYWdlQ291bnQgZXZlbnRzIGZvciBpbmRpY2F0aW5nIGFycml2YWwgb2YKKyAgICAgKiBuZXcgbWVzc2FnZXMuIDxwPgorICAgICAqCisgICAgICogVGhlIHByb3ZpZGVkIGltcGxlbWVudGF0aW9uIHF1ZXVlcyB0aGUgZXZlbnQgaW50bworICAgICAqIGFuIGludGVybmFsIGV2ZW50IHF1ZXVlLiBBbiBldmVudCBkaXNwYXRjaGVyIHRocmVhZCBkZXF1ZXVlcworICAgICAqIGV2ZW50cyBmcm9tIHRoZSBxdWV1ZSBhbmQgZGlzcGF0Y2hlcyB0aGVtIHRvIHRoZSByZWdpc3RlcmVkCisgICAgICogTWVzc2FnZUNvdW50TGlzdGVuZXJzLiBOb3RlIHRoYXQgdGhlIGV2ZW50IGRpc3BhdGNoaW5nIG9jY3VycworICAgICAqIGluIGEgc2VwYXJhdGUgdGhyZWFkLCB0aHVzIGF2b2lkaW5nIHBvdGVudGlhbCBkZWFkbG9jayBwcm9ibGVtcy4KKyAgICAgKgorICAgICAqIEBwYXJhbQltc2dzCXRoZSBtZXNzYWdlcyB0aGF0IHdlcmUgYWRkZWQKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBub3RpZnlNZXNzYWdlQWRkZWRMaXN0ZW5lcnMoTWVzc2FnZVtdIG1zZ3MpIHsgCisgICAJaWYgKG1lc3NhZ2VDb3VudExpc3RlbmVycyA9PSBudWxsKQorCSAgICByZXR1cm47CisKKwlNZXNzYWdlQ291bnRFdmVudCBlID0gbmV3IE1lc3NhZ2VDb3VudEV2ZW50KAorCQkJCQl0aGlzLCAKKwkJCQkJTWVzc2FnZUNvdW50RXZlbnQuQURERUQsIAorCQkJCQlmYWxzZSwKKwkJCQkJbXNncyk7CisKKyAgIAlxdWV1ZUV2ZW50KGUsIG1lc3NhZ2VDb3VudExpc3RlbmVycyk7IAorICAgIH0KKworICAgIC8qKgorICAgICAqIE5vdGlmeSBhbGwgTWVzc2FnZUNvdW50TGlzdGVuZXJzIGFib3V0IHRoZSByZW1vdmFsIG9mIG1lc3NhZ2VzCisgICAgICogZnJvbSB0aGlzIEZvbGRlci4gRm9sZGVyIGltcGxlbWVudGF0aW9ucyBhcmUgZXhwZWN0ZWQgdG8gdXNlIHRoaXMgCisgICAgICogbWV0aG9kIHRvIGJyb2FkY2FzdCBNZXNzYWdlQ291bnQgZXZlbnRzIGluZGljYXRpbmcgcmVtb3ZhbCBvZgorICAgICAqIG1lc3NhZ2VzLiA8cD4KKyAgICAgKgorICAgICAqIFRoZSBwcm92aWRlZCBpbXBsZW1lbnRhdGlvbiBxdWV1ZXMgdGhlIGV2ZW50IGludG8KKyAgICAgKiBhbiBpbnRlcm5hbCBldmVudCBxdWV1ZS4gQW4gZXZlbnQgZGlzcGF0Y2hlciB0aHJlYWQgZGVxdWV1ZXMKKyAgICAgKiBldmVudHMgZnJvbSB0aGUgcXVldWUgYW5kIGRpc3BhdGNoZXMgdGhlbSB0byB0aGUgcmVnaXN0ZXJlZAorICAgICAqIE1lc3NhZ2VDb3VudExpc3RlbmVycy4gTm90ZSB0aGF0IHRoZSBldmVudCBkaXNwYXRjaGluZyBvY2N1cnMKKyAgICAgKiBpbiBhIHNlcGFyYXRlIHRocmVhZCwgdGh1cyBhdm9pZGluZyBwb3RlbnRpYWwgZGVhZGxvY2sgcHJvYmxlbXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0JcmVtb3ZlZAl3YXMgdGhlIG1lc3NhZ2UgcmVtb3ZlZCBieSB0aGlzIGNsaWVudD8KKyAgICAgKiBAcGFyYW0JbXNncwl0aGUgbWVzc2FnZXMgdGhhdCB3ZXJlIHJlbW92ZWQKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBub3RpZnlNZXNzYWdlUmVtb3ZlZExpc3RlbmVycyhib29sZWFuIHJlbW92ZWQsIAorCQkJCQkJIE1lc3NhZ2VbXSBtc2dzKSB7IAorICAgCWlmIChtZXNzYWdlQ291bnRMaXN0ZW5lcnMgPT0gbnVsbCkKKwkgICAgcmV0dXJuOworCisJTWVzc2FnZUNvdW50RXZlbnQgZSA9IG5ldyBNZXNzYWdlQ291bnRFdmVudCgKKwkJCQkJdGhpcywgCisJCQkJCU1lc3NhZ2VDb3VudEV2ZW50LlJFTU9WRUQsIAorCQkJCQlyZW1vdmVkLAorCQkJCQltc2dzKTsKKyAgIAlxdWV1ZUV2ZW50KGUsIG1lc3NhZ2VDb3VudExpc3RlbmVycyk7IAorICAgIH0KKworICAgIC8vIFZlY3RvciBvZiBNZXNzYWdlQ2hhbmdlZCBsaXN0ZW5lcnMuCisgICAgcHJpdmF0ZSB2b2xhdGlsZSBWZWN0b3I8TWVzc2FnZUNoYW5nZWRMaXN0ZW5lcj4gbWVzc2FnZUNoYW5nZWRMaXN0ZW5lcnMKKwkgICAgPSBudWxsOworCisgICAgLyoqCisgICAgICogQWRkIGEgbGlzdGVuZXIgZm9yIE1lc3NhZ2VDaGFuZ2VkIGV2ZW50cyBvbiB0aGlzIEZvbGRlci4gPHA+CisgICAgICoKKyAgICAgKiBUaGUgaW1wbGVtZW50YXRpb24gcHJvdmlkZWQgaGVyZSBhZGRzIHRoaXMgbGlzdGVuZXIKKyAgICAgKiB0byBhbiBpbnRlcm5hbCBsaXN0IG9mIE1lc3NhZ2VDaGFuZ2VkTGlzdGVuZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIGwgCXRoZSBMaXN0ZW5lciBmb3IgTWVzc2FnZUNoYW5nZWQgZXZlbnRzCisgICAgICogQHNlZQkJamF2YXgubWFpbC5ldmVudC5NZXNzYWdlQ2hhbmdlZEV2ZW50CisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkCisJCQlhZGRNZXNzYWdlQ2hhbmdlZExpc3RlbmVyKE1lc3NhZ2VDaGFuZ2VkTGlzdGVuZXIgbCkgeyAKKyAgIAlpZiAobWVzc2FnZUNoYW5nZWRMaXN0ZW5lcnMgPT0gbnVsbCkKKwkgICAgbWVzc2FnZUNoYW5nZWRMaXN0ZW5lcnMgPSBuZXcgVmVjdG9yPD4oKTsKKwltZXNzYWdlQ2hhbmdlZExpc3RlbmVycy5hZGRFbGVtZW50KGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZSBhIE1lc3NhZ2VDaGFuZ2VkIGxpc3RlbmVyLiA8cD4KKyAgICAgKgorICAgICAqIFRoZSBpbXBsZW1lbnRhdGlvbiBwcm92aWRlZCBoZXJlIHJlbW92ZXMgdGhpcyBsaXN0ZW5lcgorICAgICAqIGZyb20gdGhlIGludGVybmFsIGxpc3Qgb2YgTWVzc2FnZUNoYW5nZWRMaXN0ZW5lcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbCAJdGhlIGxpc3RlbmVyCisgICAgICogQHNlZQkJI2FkZE1lc3NhZ2VDaGFuZ2VkTGlzdGVuZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQKKwkJcmVtb3ZlTWVzc2FnZUNoYW5nZWRMaXN0ZW5lcihNZXNzYWdlQ2hhbmdlZExpc3RlbmVyIGwpIHsgCisgICAJaWYgKG1lc3NhZ2VDaGFuZ2VkTGlzdGVuZXJzICE9IG51bGwpIAorCSAgICBtZXNzYWdlQ2hhbmdlZExpc3RlbmVycy5yZW1vdmVFbGVtZW50KGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIE5vdGlmeSBhbGwgTWVzc2FnZUNoYW5nZWRMaXN0ZW5lcnMuIEZvbGRlciBpbXBsZW1lbnRhdGlvbnMgYXJlCisgICAgICogZXhwZWN0ZWQgdG8gdXNlIHRoaXMgbWV0aG9kIHRvIGJyb2FkY2FzdCBNZXNzYWdlQ2hhbmdlZCBldmVudHMuIDxwPgorICAgICAqCisgICAgICogVGhlIHByb3ZpZGVkIGltcGxlbWVudGF0aW9uIHF1ZXVlcyB0aGUgZXZlbnQgaW50bworICAgICAqIGFuIGludGVybmFsIGV2ZW50IHF1ZXVlLiBBbiBldmVudCBkaXNwYXRjaGVyIHRocmVhZCBkZXF1ZXVlcworICAgICAqIGV2ZW50cyBmcm9tIHRoZSBxdWV1ZSBhbmQgZGlzcGF0Y2hlcyB0aGVtIHRvIHJlZ2lzdGVyZWQKKyAgICAgKiBNZXNzYWdlQ2hhbmdlZExpc3RlbmVycy4gTm90ZSB0aGF0IHRoZSBldmVudCBkaXNwYXRjaGluZyBvY2N1cnMKKyAgICAgKiBpbiBhIHNlcGFyYXRlIHRocmVhZCwgdGh1cyBhdm9pZGluZyBwb3RlbnRpYWwgZGVhZGxvY2sgcHJvYmxlbXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0JdHlwZQl0aGUgTWVzc2FnZUNoYW5nZWRFdmVudCB0eXBlCisgICAgICogQHBhcmFtCW1zZwl0aGUgbWVzc2FnZSB0aGF0IGNoYW5nZWQKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBub3RpZnlNZXNzYWdlQ2hhbmdlZExpc3RlbmVycyhpbnQgdHlwZSwgTWVzc2FnZSBtc2cpIHsKKwlpZiAobWVzc2FnZUNoYW5nZWRMaXN0ZW5lcnMgPT0gbnVsbCkKKwkgICAgcmV0dXJuOworCQorCU1lc3NhZ2VDaGFuZ2VkRXZlbnQgZSA9IG5ldyBNZXNzYWdlQ2hhbmdlZEV2ZW50KHRoaXMsIHR5cGUsIG1zZyk7CisJcXVldWVFdmVudChlLCBtZXNzYWdlQ2hhbmdlZExpc3RlbmVycyk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBBZGQgdGhlIGV2ZW50IGFuZCB2ZWN0b3Igb2YgbGlzdGVuZXJzIHRvIHRoZSBxdWV1ZSB0byBiZSBkZWxpdmVyZWQuCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHJpdmF0ZSB2b2lkIHF1ZXVlRXZlbnQoTWFpbEV2ZW50IGV2ZW50LAorCSAgICBWZWN0b3I8PyBleHRlbmRzIEV2ZW50TGlzdGVuZXI+IHZlY3RvcikgeworCS8qCisgICAgICAgICAqIENvcHkgdGhlIHZlY3RvciBpbiBvcmRlciB0byBmcmVlemUgdGhlIHN0YXRlIG9mIHRoZSBzZXQKKyAgICAgICAgICogb2YgRXZlbnRMaXN0ZW5lcnMgdGhlIGV2ZW50IHNob3VsZCBiZSBkZWxpdmVyZWQgdG8gcHJpb3IKKyAgICAgICAgICogdG8gZGVsaXZlcnkuICBUaGlzIGVuc3VyZXMgdGhhdCBhbnkgY2hhbmdlcyBtYWRlIHRvIHRoZQorICAgICAgICAgKiBWZWN0b3IgZnJvbSBhIHRhcmdldCBsaXN0ZW5lcidzIG1ldGhvZCBkdXJpbmcgdGhlIGRlbGl2ZXJ5CisgICAgICAgICAqIG9mIHRoaXMgZXZlbnQgd2lsbCBub3QgdGFrZSBlZmZlY3QgdW50aWwgYWZ0ZXIgdGhlIGV2ZW50IGlzCisgICAgICAgICAqIGRlbGl2ZXJlZC4KKyAgICAgICAgICovCisJVmVjdG9yPD8gZXh0ZW5kcyBFdmVudExpc3RlbmVyPiB2ID0gKFZlY3Rvcil2ZWN0b3IuY2xvbmUoKTsKKwlxLmVucXVldWUoZXZlbnQsIHYpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIGZpbmFsaXplKCkgdGhyb3dzIFRocm93YWJsZSB7CisJdHJ5IHsKKwkgICAgcS50ZXJtaW5hdGVRdWV1ZSgpOworCX0gZmluYWxseSB7CisJICAgIHN1cGVyLmZpbmFsaXplKCk7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIG92ZXJyaWRlIHRoZSBkZWZhdWx0IHRvU3RyaW5nKCksIGl0IHdpbGwgcmV0dXJuIHRoZSBTdHJpbmcKKyAgICAgKiBmcm9tIEZvbGRlci5nZXRGdWxsTmFtZSgpIG9yIGlmIHRoYXQgaXMgbnVsbCwgaXQgd2lsbCB1c2UKKyAgICAgKiB0aGUgZGVmYXVsdCB0b1N0cmluZygpIGJlaGF2aW9yLgorICAgICAqLworCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKwlTdHJpbmcgcyA9IGdldEZ1bGxOYW1lKCk7CisJaWYgKHMgIT0gbnVsbCkKKwkgICAgcmV0dXJuIHM7CisJZWxzZQorCSAgICByZXR1cm4gc3VwZXIudG9TdHJpbmcoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9Gb2xkZXJDbG9zZWRFeGNlcHRpb24uamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL0ZvbGRlckNsb3NlZEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdlOGE0YjQKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9Gb2xkZXJDbG9zZWRFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDgzIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGphdmF4Lm1haWw7CisKKy8qKgorICogVGhpcyBleGNlcHRpb24gaXMgdGhyb3duIHdoZW4gYSBtZXRob2QgaXMgaW52b2tlZCBvbiBhIE1lc3NhZ2luZyBvYmplY3QKKyAqIGFuZCB0aGUgRm9sZGVyIHRoYXQgb3ducyB0aGF0IG9iamVjdCBoYXMgZGllZCBkdWUgdG8gc29tZSByZWFzb24uIDxwPgorICoKKyAqIEZvbGxvd2luZyB0aGUgZXhjZXB0aW9uLCB0aGUgRm9sZGVyIGlzIHJlc2V0IHRvIHRoZSAiY2xvc2VkIiBzdGF0ZS4gCisgKiBBbGwgbWVzc2FnaW5nIG9iamVjdHMgb3duZWQgYnkgdGhlIEZvbGRlciBzaG91bGQgYmUgY29uc2lkZXJlZCBpbnZhbGlkLiAKKyAqIFRoZSBGb2xkZXIgY2FuIGJlIHJlb3BlbmVkIHVzaW5nIHRoZSAib3BlbiIgbWV0aG9kIHRvIHJlZXN0YWJsaXNoIHRoZSAKKyAqIGxvc3QgY29ubmVjdGlvbi4gPHA+CisgKgorICogVGhlIGdldE1lc3NhZ2UoKSBtZXRob2QgcmV0dXJucyBtb3JlIGRldGFpbGVkIGluZm9ybWF0aW9uIGFib3V0IHRoZQorICogZXJyb3IgdGhhdCBjYXVzZWQgdGhpcyBleGNlcHRpb24uIDxwPgorICoKKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKi8KKworcHVibGljIGNsYXNzIEZvbGRlckNsb3NlZEV4Y2VwdGlvbiBleHRlbmRzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisgICAgdHJhbnNpZW50IHByaXZhdGUgRm9sZGVyIGZvbGRlcjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDE2ODc4NzkyMTM0MzMzMDIzMTVMOworICAgIAorICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBGb2xkZXJDbG9zZWRFeGNlcHRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZm9sZGVyCVRoZSBGb2xkZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgRm9sZGVyQ2xvc2VkRXhjZXB0aW9uKEZvbGRlciBmb2xkZXIpIHsKKwl0aGlzKGZvbGRlciwgbnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIEZvbGRlckNsb3NlZEV4Y2VwdGlvbiB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmb2xkZXIgCVRoZSBGb2xkZXIKKyAgICAgKiBAcGFyYW0gbWVzc2FnZQlUaGUgZGV0YWlsZWQgZXJyb3IgbWVzc2FnZQorICAgICAqLworICAgIHB1YmxpYyBGb2xkZXJDbG9zZWRFeGNlcHRpb24oRm9sZGVyIGZvbGRlciwgU3RyaW5nIG1lc3NhZ2UpIHsKKwlzdXBlcihtZXNzYWdlKTsKKwl0aGlzLmZvbGRlciA9IGZvbGRlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgRm9sZGVyQ2xvc2VkRXhjZXB0aW9uIHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIGRldGFpbCBtZXNzYWdlIGFuZCBlbWJlZGRlZCBleGNlcHRpb24uICBUaGUgZXhjZXB0aW9uIGlzIGNoYWluZWQKKyAgICAgKiB0byB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmb2xkZXIgCVRoZSBGb2xkZXIKKyAgICAgKiBAcGFyYW0gbWVzc2FnZQlUaGUgZGV0YWlsZWQgZXJyb3IgbWVzc2FnZQorICAgICAqIEBwYXJhbSBlCQlUaGUgZW1iZWRkZWQgZXhjZXB0aW9uCisgICAgICogQHNpbmNlCQlKYXZhTWFpbCAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgRm9sZGVyQ2xvc2VkRXhjZXB0aW9uKEZvbGRlciBmb2xkZXIsIFN0cmluZyBtZXNzYWdlLCBFeGNlcHRpb24gZSkgeworCXN1cGVyKG1lc3NhZ2UsIGUpOworCXRoaXMuZm9sZGVyID0gZm9sZGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGRlYWQgRm9sZGVyIG9iamVjdAorICAgICAqCisgICAgICogQHJldHVybgl0aGUgZGVhZCBGb2xkZXIgb2JqZWN0CisgICAgICovCisgICAgcHVibGljIEZvbGRlciBnZXRGb2xkZXIoKSB7CisJcmV0dXJuIGZvbGRlcjsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9Gb2xkZXJOb3RGb3VuZEV4Y2VwdGlvbi5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvRm9sZGVyTm90Rm91bmRFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZWE2NzQ1Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvRm9sZGVyTm90Rm91bmRFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDEwMCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsOworCitpbXBvcnQgamF2YS5sYW5nLio7CisKKy8qKgorICogVGhpcyBleGNlcHRpb24gaXMgdGhyb3duIGJ5IEZvbGRlciBtZXRob2RzLCB3aGVuIHRob3NlCisgKiBtZXRob2RzIGFyZSBpbnZva2VkIG9uIGEgbm9uIGV4aXN0ZW50IGZvbGRlci4KKyAqCisgKiBAYXV0aG9yIEpvaG4gTWFuaQorICovCisKK3B1YmxpYyBjbGFzcyBGb2xkZXJOb3RGb3VuZEV4Y2VwdGlvbiBleHRlbmRzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisgICAgdHJhbnNpZW50IHByaXZhdGUgRm9sZGVyIGZvbGRlcjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDQ3MjYxMjEwODg5MTI0OTQwM0w7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgRm9sZGVyTm90Rm91bmRFeGNlcHRpb24gd2l0aCBubyBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgRm9sZGVyTm90Rm91bmRFeGNlcHRpb24oKSB7CisJc3VwZXIoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgRm9sZGVyTm90Rm91bmRFeGNlcHRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZm9sZGVyCVRoZSBGb2xkZXIKKyAgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuMiAKKyAgICAgKi8KKyAgICBwdWJsaWMgRm9sZGVyTm90Rm91bmRFeGNlcHRpb24oRm9sZGVyIGZvbGRlcikgeworCXN1cGVyKCk7CisgICAgICAgIHRoaXMuZm9sZGVyID0gZm9sZGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBGb2xkZXJOb3RGb3VuZEV4Y2VwdGlvbiB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmb2xkZXIJVGhlIEZvbGRlcgorICAgICAqIEBwYXJhbSBzCQlUaGUgZGV0YWlsZWQgZXJyb3IgbWVzc2FnZQorICAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS4yCisgICAgICovCisgICAgcHVibGljIEZvbGRlck5vdEZvdW5kRXhjZXB0aW9uKEZvbGRlciBmb2xkZXIsIFN0cmluZyBzKSB7CisJc3VwZXIocyk7CisJdGhpcy5mb2xkZXIgPSBmb2xkZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIEZvbGRlck5vdEZvdW5kRXhjZXB0aW9uIHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIGRldGFpbCBtZXNzYWdlIGFuZCBlbWJlZGRlZCBleGNlcHRpb24uICBUaGUgZXhjZXB0aW9uIGlzIGNoYWluZWQKKyAgICAgKiB0byB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmb2xkZXIJVGhlIEZvbGRlcgorICAgICAqIEBwYXJhbSBzCQlUaGUgZGV0YWlsZWQgZXJyb3IgbWVzc2FnZQorICAgICAqIEBwYXJhbSBlCQlUaGUgZW1iZWRkZWQgZXhjZXB0aW9uCisgICAgICogQHNpbmNlCQlKYXZhTWFpbCAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgRm9sZGVyTm90Rm91bmRFeGNlcHRpb24oRm9sZGVyIGZvbGRlciwgU3RyaW5nIHMsIEV4Y2VwdGlvbiBlKSB7CisJc3VwZXIocywgZSk7CisJdGhpcy5mb2xkZXIgPSBmb2xkZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIEZvbGRlck5vdEZvdW5kRXhjZXB0aW9uIHdpdGggdGhlIHNwZWNpZmllZCBkZXRhaWwgbWVzc2FnZQorICAgICAqIGFuZCB0aGUgc3BlY2lmaWVkIGZvbGRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzCQlUaGUgZGV0YWlsIG1lc3NhZ2UKKyAgICAgKiBAcGFyYW0gZm9sZGVyCVRoZSBGb2xkZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgRm9sZGVyTm90Rm91bmRFeGNlcHRpb24oU3RyaW5nIHMsIEZvbGRlciBmb2xkZXIpIHsKKwlzdXBlcihzKTsKKwl0aGlzLmZvbGRlciA9IGZvbGRlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBvZmZlbmRpbmcgRm9sZGVyIG9iamVjdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIEZvbGRlciBvYmplY3QuIE5vdGUgdGhhdCB0aGUgcmV0dXJuZWQgdmFsdWUgY2FuIGJlCisgICAgICogCQk8Y29kZT5udWxsPC9jb2RlPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgRm9sZGVyIGdldEZvbGRlcigpIHsKKwlyZXR1cm4gZm9sZGVyOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL0hlYWRlci5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvSGVhZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTI0Zjg0YwotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL0hlYWRlci5qYXZhCkBAIC0wLDAgKzEsNzAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbDsKKworCisvKioKKyAqIFRoZSBIZWFkZXIgY2xhc3Mgc3RvcmVzIGEgbmFtZS92YWx1ZSBwYWlyIHRvIHJlcHJlc2VudCBoZWFkZXJzLgorICoKKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKi8KKworcHVibGljIGNsYXNzIEhlYWRlciB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbmFtZSBvZiB0aGUgaGVhZGVyLgorICAgICAqCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNAorICAgICAqLworICAgIHByb3RlY3RlZCBTdHJpbmcgbmFtZTsKKworICAgIC8qKgorICAgICAqIFRoZSB2YWx1ZSBvZiB0aGUgaGVhZGVyLgorICAgICAqCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNAorICAgICAqLworICAgIHByb3RlY3RlZCBTdHJpbmcgdmFsdWU7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYSBIZWFkZXIgb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUJbmFtZSBvZiB0aGUgaGVhZGVyCisgICAgICogQHBhcmFtIHZhbHVlCXZhbHVlIG9mIHRoZSBoZWFkZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgSGVhZGVyKFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsdWUpIHsKKwl0aGlzLm5hbWUgPSBuYW1lOworCXRoaXMudmFsdWUgPSB2YWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoaXMgaGVhZGVyLgorICAgICAqCisgICAgICogQHJldHVybiAJCW5hbWUgb2YgdGhlIGhlYWRlcgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKKwlyZXR1cm4gbmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGlzIGhlYWRlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gCQl2YWx1ZSBvZiB0aGUgaGVhZGVyCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRWYWx1ZSgpIHsKKwlyZXR1cm4gdmFsdWU7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvSWxsZWdhbFdyaXRlRXhjZXB0aW9uLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9JbGxlZ2FsV3JpdGVFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MDExYzRjCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvSWxsZWdhbFdyaXRlRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw2MCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsOworCisKKy8qKgorICogVGhlIGV4Y2VwdGlvbiB0aHJvd24gd2hlbiBhIHdyaXRlIGlzIGF0dGVtcHRlZCBvbiBhIHJlYWQtb25seSBhdHRyaWJ1dGUKKyAqIG9mIGFueSBNZXNzYWdpbmcgb2JqZWN0LiAKKyAqCisgKiBAYXV0aG9yIEpvaG4gTWFuaQorICovCisKK3B1YmxpYyBjbGFzcyBJbGxlZ2FsV3JpdGVFeGNlcHRpb24gZXh0ZW5kcyBNZXNzYWdpbmdFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMzk3NDM3MDIyMzMyODI2ODAxM0w7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGFuIElsbGVnYWxXcml0ZUV4Y2VwdGlvbiB3aXRoIG5vIGRldGFpbCBtZXNzYWdlLgorICAgICAqLworICAgIHB1YmxpYyBJbGxlZ2FsV3JpdGVFeGNlcHRpb24oKSB7CisJc3VwZXIoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGFuIElsbGVnYWxXcml0ZUV4Y2VwdGlvbiB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzCQlUaGUgZGV0YWlsZWQgZXJyb3IgbWVzc2FnZQorICAgICAqLworICAgIHB1YmxpYyBJbGxlZ2FsV3JpdGVFeGNlcHRpb24oU3RyaW5nIHMpIHsKKwlzdXBlcihzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGFuIElsbGVnYWxXcml0ZUV4Y2VwdGlvbiB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBkZXRhaWwgbWVzc2FnZSBhbmQgZW1iZWRkZWQgZXhjZXB0aW9uLiAgVGhlIGV4Y2VwdGlvbiBpcyBjaGFpbmVkCisgICAgICogdG8gdGhpcyBleGNlcHRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcwkJVGhlIGRldGFpbGVkIGVycm9yIG1lc3NhZ2UKKyAgICAgKiBAcGFyYW0gZQkJVGhlIGVtYmVkZGVkIGV4Y2VwdGlvbgorICAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS41CisgICAgICovCisgICAgcHVibGljIElsbGVnYWxXcml0ZUV4Y2VwdGlvbihTdHJpbmcgcywgRXhjZXB0aW9uIGUpIHsKKwlzdXBlcihzLCBlKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9NYWlsU2Vzc2lvbkRlZmluaXRpb24uamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL01haWxTZXNzaW9uRGVmaW5pdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc4OGZhNGUKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9NYWlsU2Vzc2lvbkRlZmluaXRpb24uamF2YQpAQCAtMCwwICsxLDEwOCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAxMiwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsOworCitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uRWxlbWVudFR5cGU7CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uOworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlJldGVudGlvblBvbGljeTsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5UYXJnZXQ7CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uUmVwZWF0YWJsZTsKKworLyoqCisgKiBBbm5vdGF0aW9uIHVzZWQgYnkgSmF2YSBFRSBhcHBsaWNhdGlvbnMgdG8gZGVmaW5lIGEgPGNvZGU+TWFpbFNlc3Npb248L2NvZGU+CisgKiB0byBiZSByZWdpc3RlcmVkIHdpdGggSk5ESS4gIFRoZSA8Y29kZT5NYWlsU2Vzc2lvbjwvY29kZT4gbWF5IGJlIGNvbmZpZ3VyZWQKKyAqIGJ5IHNldHRpbmcgdGhlIGFubm90YXRpb24gZWxlbWVudHMgZm9yIGNvbW1vbmx5IHVzZWQgPGNvZGU+U2Vzc2lvbjwvY29kZT4KKyAqIHByb3BlcnRpZXMuICBBZGRpdGlvbmFsIHN0YW5kYXJkIGFuZCB2ZW5kb3Itc3BlY2lmaWMgcHJvcGVydGllcyBtYXkgYmUKKyAqIHNwZWNpZmllZCB1c2luZyB0aGUgPGNvZGU+cHJvcGVydGllczwvY29kZT4gZWxlbWVudC4KKyAqIDxwPgorICogVGhlIHNlc3Npb24gd2lsbCBiZSByZWdpc3RlcmVkIHVuZGVyIHRoZSBuYW1lIHNwZWNpZmllZCBpbiB0aGUKKyAqIDxjb2RlPm5hbWU8L2NvZGU+IGVsZW1lbnQuICBJdCBtYXkgYmUgZGVmaW5lZCB0byBiZSBpbiBhbnkgdmFsaWQKKyAqIDxjb2RlPkphdmEgRUU8L2NvZGU+IG5hbWVzcGFjZSwgYW5kIHdpbGwgZGV0ZXJtaW5lIHRoZSBhY2Nlc3NpYmlsaXR5IG9mCisgKiB0aGUgc2Vzc2lvbiBmcm9tIG90aGVyIGNvbXBvbmVudHMuCisgKgorICogQHNpbmNlIEphdmFNYWlsIDEuNQorICovCitAVGFyZ2V0KHtFbGVtZW50VHlwZS5UWVBFfSkKK0BSZXRlbnRpb24oUmV0ZW50aW9uUG9saWN5LlJVTlRJTUUpCitAUmVwZWF0YWJsZShNYWlsU2Vzc2lvbkRlZmluaXRpb25zLmNsYXNzKQorcHVibGljIEBpbnRlcmZhY2UgTWFpbFNlc3Npb25EZWZpbml0aW9uIHsKKworICAgIC8qKgorICAgICAqIERlc2NyaXB0aW9uIG9mIHRoaXMgbWFpbCBzZXNzaW9uLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgZGVzY3JpcHRpb24KKyAgICAgKi8KKyAgICBTdHJpbmcgZGVzY3JpcHRpb24oKSBkZWZhdWx0ICIiOworCisgICAgLyoqCisgICAgICogSk5ESSBuYW1lIGJ5IHdoaWNoIHRoZSBtYWlsIHNlc3Npb24gd2lsbCBiZSByZWdpc3RlcmVkLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgSk5ESSBuYW1lCisgICAgICovCisgICAgU3RyaW5nIG5hbWUoKTsKKworICAgIC8qKgorICAgICAqIFN0b3JlIHByb3RvY29sIG5hbWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBzdG9yZSBwcm90b2NvbCBuYW1lCisgICAgICovCisgICAgU3RyaW5nIHN0b3JlUHJvdG9jb2woKSBkZWZhdWx0ICIiOworCisgICAgLyoqCisgICAgICogVHJhbnNwb3J0IHByb3RvY29sIG5hbWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSB0cmFuc3BvcnQgcHJvdG9jb2wgbmFtZQorICAgICAqLworICAgIFN0cmluZyB0cmFuc3BvcnRQcm90b2NvbCgpIGRlZmF1bHQgIiI7CisKKyAgICAvKioKKyAgICAgKiBIb3N0IG5hbWUgZm9yIHRoZSBtYWlsIHNlcnZlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIGhvc3QgbmFtZQorICAgICAqLworICAgIFN0cmluZyBob3N0KCkgZGVmYXVsdCAiIjsKKworICAgIC8qKgorICAgICAqIFVzZXIgbmFtZSB0byB1c2UgZm9yIGF1dGhlbnRpY2F0aW9uLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgdXNlciBuYW1lCisgICAgICovCisgICAgU3RyaW5nIHVzZXIoKSBkZWZhdWx0ICIiOworCisgICAgLyoqCisgICAgICogUGFzc3dvcmQgdG8gdXNlIGZvciBhdXRoZW50aWNhdGlvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIHBhc3N3b3JkCisgICAgICovCisgICAgU3RyaW5nIHBhc3N3b3JkKCkgZGVmYXVsdCAiIjsKKworICAgIC8qKgorICAgICAqIEZyb20gYWRkcmVzcyBmb3IgdGhlIHVzZXIuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBmcm9tIGFkZHJlc3MKKyAgICAgKi8KKyAgICBTdHJpbmcgZnJvbSgpIGRlZmF1bHQgIiI7CisKKyAgICAvKioKKyAgICAgKiBQcm9wZXJ0aWVzIHRvIGluY2x1ZGUgaW4gdGhlIFNlc3Npb24uCisgICAgICogUHJvcGVydGllcyBhcmUgc3BlY2lmaWVkIHVzaW5nIHRoZSBmb3JtYXQ6CisgICAgICogPGk+cHJvcGVydHlOYW1lPXByb3BlcnR5VmFsdWU8L2k+IHdpdGggb25lIHByb3BlcnR5IHBlciBhcnJheSBlbGVtZW50LgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgcHJvcGVydGllcworICAgICAqLworICAgIFN0cmluZ1tdIHByb3BlcnRpZXMoKSBkZWZhdWx0IHt9OworfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvTWFpbFNlc3Npb25EZWZpbml0aW9ucy5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvTWFpbFNlc3Npb25EZWZpbml0aW9ucy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI5NzQ2MmIKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9NYWlsU2Vzc2lvbkRlZmluaXRpb25zLmphdmEKQEAgLTAsMCArMSwzNCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAxMiwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsOworCitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uVGFyZ2V0OworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlJldGVudGlvbjsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5FbGVtZW50VHlwZTsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXRlbnRpb25Qb2xpY3k7CisKKy8qKgorICogRGVjbGFyZXMgb25lIG9yIG1vcmUgPGNvZGU+TWFpbFNlc3Npb25EZWZpbml0aW9uPC9jb2RlPiBhbm5vdGF0aW9ucy4KKyAqCisgKiBAc2VlIE1haWxTZXNzaW9uRGVmaW5pdGlvbgorICogQHNpbmNlIEphdmFNYWlsIDEuNQorICovCitAVGFyZ2V0KHtFbGVtZW50VHlwZS5UWVBFfSkKK0BSZXRlbnRpb24oUmV0ZW50aW9uUG9saWN5LlJVTlRJTUUpCitwdWJsaWMgQGludGVyZmFjZSBNYWlsU2Vzc2lvbkRlZmluaXRpb25zIHsKKyAgICBNYWlsU2Vzc2lvbkRlZmluaXRpb25bXSB2YWx1ZSgpOworfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvTWVzc2FnZS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvTWVzc2FnZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM3MGZkMjgKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9NZXNzYWdlLmphdmEKQEAgLTAsMCArMSw3MDQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbDsKKworaW1wb3J0IGphdmEudXRpbC5EYXRlOworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZheC5tYWlsLnNlYXJjaC5TZWFyY2hUZXJtOworCisvKioKKyAqIFRoaXMgY2xhc3MgbW9kZWxzIGFuIGVtYWlsIG1lc3NhZ2UuIFRoaXMgaXMgYW4gYWJzdHJhY3QgY2xhc3MuICAKKyAqIFN1YmNsYXNzZXMgcHJvdmlkZSBhY3R1YWwgaW1wbGVtZW50YXRpb25zLiA8cD4KKyAqCisgKiBNZXNzYWdlIGltcGxlbWVudHMgdGhlIFBhcnQgaW50ZXJmYWNlLiBNZXNzYWdlIGNvbnRhaW5zIGEgc2V0IG9mCisgKiBhdHRyaWJ1dGVzIGFuZCBhICJjb250ZW50Ii4gTWVzc2FnZXMgd2l0aGluIGEgZm9sZGVyIGFsc28gaGF2ZSBhIAorICogc2V0IG9mIGZsYWdzIHRoYXQgZGVzY3JpYmUgaXRzIHN0YXRlIHdpdGhpbiB0aGUgZm9sZGVyLjxwPgorICoKKyAqIE1lc3NhZ2UgZGVmaW5lcyBzb21lIG5ldyBhdHRyaWJ1dGVzIGluIGFkZGl0aW9uIHRvIHRob3NlIGRlZmluZWQKKyAqIGluIHRoZSA8Y29kZT5QYXJ0PC9jb2RlPiBpbnRlcmZhY2UuIFRoZXNlIGF0dHJpYnV0ZXMgc3BlY2lmeSBtZXRhLWRhdGEKKyAqIGZvciB0aGUgbWVzc2FnZSAtIGkuZS4sIGFkZHJlc3NpbmcgIGFuZCBkZXNjcmlwdGl2ZSBpbmZvcm1hdGlvbiBhYm91dCAKKyAqIHRoZSBtZXNzYWdlLiA8cD4KKyAqCisgKiBNZXNzYWdlIG9iamVjdHMgYXJlIG9idGFpbmVkIGVpdGhlciBmcm9tIGEgRm9sZGVyIG9yIGJ5IGNvbnN0cnVjdGluZworICogYSBuZXcgTWVzc2FnZSBvYmplY3Qgb2YgdGhlIGFwcHJvcHJpYXRlIHN1YmNsYXNzLiBNZXNzYWdlcyB0aGF0IGhhdmUKKyAqIGJlZW4gcmVjZWl2ZWQgYXJlIG5vcm1hbGx5IHJldHJpZXZlZCBmcm9tIGEgZm9sZGVyIG5hbWVkICJJTkJPWCIuIDxwPgorICoKKyAqIEEgTWVzc2FnZSBvYmplY3Qgb2J0YWluZWQgZnJvbSBhIGZvbGRlciBpcyBqdXN0IGEgbGlnaHR3ZWlnaHQKKyAqIHJlZmVyZW5jZSB0byB0aGUgYWN0dWFsIG1lc3NhZ2UuIFRoZSBNZXNzYWdlIGlzICdsYXppbHknIGZpbGxlZCAKKyAqIHVwIChvbiBkZW1hbmQpIHdoZW4gZWFjaCBpdGVtIGlzIHJlcXVlc3RlZCBmcm9tIHRoZSBtZXNzYWdlLiBOb3RlCisgKiB0aGF0IGNlcnRhaW4gZm9sZGVyIGltcGxlbWVudGF0aW9ucyBtYXkgcmV0dXJuIE1lc3NhZ2Ugb2JqZWN0cyB0aGF0CisgKiBhcmUgcHJlLWZpbGxlZCB3aXRoIGNlcnRhaW4gdXNlci1zcGVjaWZpZWQgaXRlbXMuCisgCisgKiBUbyBzZW5kIGEgbWVzc2FnZSwgYW4gYXBwcm9wcmlhdGUgc3ViY2xhc3Mgb2YgTWVzc2FnZSAoZS5nLiwgCisgKiBNaW1lTWVzc2FnZSkgaXMgaW5zdGFudGlhdGVkLCB0aGUgYXR0cmlidXRlcyBhbmQgY29udGVudCBhcmUgCisgKiBmaWxsZWQgaW4sIGFuZCB0aGUgbWVzc2FnZSBpcyBzZW50IHVzaW5nIHRoZSA8Y29kZT5UcmFuc3BvcnQuc2VuZDwvY29kZT4gCisgKiBtZXRob2QuIDxwPgorICoKKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICogQGF1dGhvciBNYXggU3BpdmFrCisgKiBAc2VlCSAgIGphdmF4Lm1haWwuUGFydAorICovCisKK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBNZXNzYWdlIGltcGxlbWVudHMgUGFydCB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbnVtYmVyIG9mIHRoaXMgbWVzc2FnZSB3aXRoaW4gaXRzIGZvbGRlciwgb3IgemVybyBpZgorICAgICAqIHRoZSBtZXNzYWdlIHdhcyBub3QgcmV0cmlldmVkIGZyb20gYSBmb2xkZXIuCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBtc2dudW0gPSAwOworCisgICAgLyoqCisgICAgICogVHJ1ZSBpZiB0aGlzIG1lc3NhZ2UgaGFzIGJlZW4gZXhwdW5nZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gZXhwdW5nZWQgCT0gZmFsc2U7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY29udGFpbmluZyBmb2xkZXIsIGlmIHRoaXMgbWVzc2FnZSBpcyBvYnRhaW5lZCBmcm9tIGEgZm9sZGVyCisgICAgICovCisgICAgcHJvdGVjdGVkIEZvbGRlciBmb2xkZXIJPSBudWxsOworCisgICAgLyoqCisgICAgICogVGhlIFNlc3Npb24gb2JqZWN0IGZvciB0aGlzIE1lc3NhZ2UKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU2Vzc2lvbiBzZXNzaW9uCT0gbnVsbDsKKworICAgIC8qKgorICAgICAqIE5vLWFyZyB2ZXJzaW9uIG9mIHRoZSBjb25zdHJ1Y3Rvci4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgTWVzc2FnZSgpIHsgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IgdGhhdCB0YWtlcyBhIEZvbGRlciBhbmQgYSBtZXNzYWdlIG51bWJlci4gCisgICAgICogVXNlZCBieSBGb2xkZXIgaW1wbGVtZW50YXRpb25zLgorICAgICAqCisgICAgICogQHBhcmFtCWZvbGRlcgljb250YWluaW5nIGZvbGRlcgorICAgICAqIEBwYXJhbQltc2dudW0JdGhpcyBtZXNzYWdlJ3Mgc2VxdWVuY2UgbnVtYmVyIHdpdGhpbiB0aGlzIGZvbGRlcgorICAgICAqLworICAgIHByb3RlY3RlZCBNZXNzYWdlKEZvbGRlciBmb2xkZXIsIGludCBtc2dudW0pIHsKKwl0aGlzLmZvbGRlciA9IGZvbGRlcjsKKwl0aGlzLm1zZ251bSA9IG1zZ251bTsKKwlzZXNzaW9uID0gZm9sZGVyLnN0b3JlLnNlc3Npb247CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IgdGhhdCB0YWtlcyBhIFNlc3Npb24uIFVzZWQgZm9yIGNsaWVudCBjcmVhdGVkCisgICAgICogTWVzc2FnZSBvYmplY3RzLgorICAgICAqCisgICAgICogQHBhcmFtCXNlc3Npb24JQSBTZXNzaW9uIG9iamVjdAorICAgICAqLworICAgIHByb3RlY3RlZCBNZXNzYWdlKFNlc3Npb24gc2Vzc2lvbikgeworCXRoaXMuc2Vzc2lvbiA9IHNlc3Npb247CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBTZXNzaW9uIHVzZWQgd2hlbiB0aGlzIG1lc3NhZ2Ugd2FzIGNyZWF0ZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCQl0aGUgbWVzc2FnZSdzIFNlc3Npb24KKyAgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuNQorICAgICAqLworICAgIHB1YmxpYyBTZXNzaW9uIGdldFNlc3Npb24oKSB7CisJcmV0dXJuIHNlc3Npb247CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgIkZyb20iIGF0dHJpYnV0ZS4gVGhlICJGcm9tIiBhdHRyaWJ1dGUgY29udGFpbnMKKyAgICAgKiB0aGUgaWRlbnRpdHkgb2YgdGhlIHBlcnNvbihzKSB3aG8gd2lzaGVkIHRoaXMgbWVzc2FnZSB0byAKKyAgICAgKiBiZSBzZW50LiA8cD4KKyAgICAgKiAKKyAgICAgKiBJbiBjZXJ0YWluIGltcGxlbWVudGF0aW9ucywgdGhpcyBtYXkgYmUgZGlmZmVyZW50CisgICAgICogZnJvbSB0aGUgZW50aXR5IHRoYXQgYWN0dWFsbHkgc2VudCB0aGUgbWVzc2FnZS4gPHA+CisgICAgICoKKyAgICAgKiBUaGlzIG1ldGhvZCByZXR1cm5zIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoaXMgYXR0cmlidXRlCisgICAgICogaXMgbm90IHByZXNlbnQgaW4gdGhpcyBtZXNzYWdlLiBSZXR1cm5zIGFuIGVtcHR5IGFycmF5IGlmCisgICAgICogdGhpcyBhdHRyaWJ1dGUgaXMgcHJlc2VudCwgYnV0IGNvbnRhaW5zIG5vIGFkZHJlc3Nlcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gICAgICAgICAgYXJyYXkgb2YgQWRkcmVzcyBvYmplY3RzCisgICAgICogQGV4Y2VwdGlvbiAgICAgICBNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEFkZHJlc3NbXSBnZXRGcm9tKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldCB0aGUgIkZyb20iIGF0dHJpYnV0ZSBpbiB0aGlzIE1lc3NhZ2UuIFRoZSB2YWx1ZSBvZiB0aGlzCisgICAgICogYXR0cmlidXRlIGlzIG9idGFpbmVkIGZyb20gdGhlIHByb3BlcnR5ICJtYWlsLnVzZXIiLiBJZiB0aGlzCisgICAgICogcHJvcGVydHkgaXMgYWJzZW50LCB0aGUgc3lzdGVtIHByb3BlcnR5ICJ1c2VyLm5hbWUiIGlzIHVzZWQuCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxXcml0ZUV4Y2VwdGlvbiBpZiB0aGUgdW5kZXJseWluZyAKKyAgICAgKgkJCWltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uIAorICAgICAqCQkJb2YgZXhpc3RpbmcgdmFsdWVzCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBtZXNzYWdlIGlzCisgICAgICoJCQlvYnRhaW5lZCBmcm9tIGEgUkVBRF9PTkxZIGZvbGRlci4KKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIE1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRGcm9tKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldCB0aGUgIkZyb20iIGF0dHJpYnV0ZSBpbiB0aGlzIE1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWRkcmVzcyAgIHRoZSBzZW5kZXIKKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxXcml0ZUV4Y2VwdGlvbiBpZiB0aGUgdW5kZXJseWluZyAKKyAgICAgKgkJCWltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uIAorICAgICAqCQkJb2YgZXhpc3RpbmcgdmFsdWVzCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBtZXNzYWdlIGlzCisgICAgICoJCQlvYnRhaW5lZCBmcm9tIGEgUkVBRF9PTkxZIGZvbGRlci4KKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIE1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRGcm9tKEFkZHJlc3MgYWRkcmVzcykgCisJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQWRkIHRoZXNlIGFkZHJlc3NlcyB0byB0aGUgZXhpc3RpbmcgIkZyb20iIGF0dHJpYnV0ZSAKKyAgICAgKgorICAgICAqIEBwYXJhbSBhZGRyZXNzZXMJdGhlIHNlbmRlcnMKKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxXcml0ZUV4Y2VwdGlvbiBpZiB0aGUgdW5kZXJseWluZyAKKyAgICAgKgkJCWltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uIAorICAgICAqCQkJb2YgZXhpc3RpbmcgdmFsdWVzCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBtZXNzYWdlIGlzCisgICAgICoJCQlvYnRhaW5lZCBmcm9tIGEgUkVBRF9PTkxZIGZvbGRlci4KKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIE1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBhZGRGcm9tKEFkZHJlc3NbXSBhZGRyZXNzZXMpIAorCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFRoaXMgaW5uZXIgY2xhc3MgZGVmaW5lcyB0aGUgdHlwZXMgb2YgcmVjaXBpZW50cyBhbGxvd2VkIGJ5CisgICAgICogdGhlIE1lc3NhZ2UgY2xhc3MuIFRoZSBjdXJyZW50bHkgZGVmaW5lZCB0eXBlcyBhcmUgVE8sCisgICAgICogQ0MgYW5kIEJDQy4KKyAgICAgKgorICAgICAqIE5vdGUgdGhhdCB0aGlzIGNsYXNzIG9ubHkgaGFzIGEgcHJvdGVjdGVkIGNvbnN0cnVjdG9yLCB0aGVyZWJ5CisgICAgICogcmVzdHJpY3RpbmcgbmV3IFJlY2lwaWVudCB0eXBlcyB0byBlaXRoZXIgdGhpcyBjbGFzcyBvciBzdWJjbGFzc2VzLgorICAgICAqIFRoaXMgZWZmZWN0aXZlbHkgaW1wbGVtZW50cyBhbiBlbnVtZXJhdGlvbiBvZiB0aGUgYWxsb3dlZCBSZWNpcGllbnQKKyAgICAgKiB0eXBlcy4KKyAgICAgKgorICAgICAqIFRoZSBmb2xsb3dpbmcgY29kZSBzYW1wbGUgc2hvd3MgaG93IHRvIHVzZSB0aGlzIGNsYXNzIHRvIG9idGFpbgorICAgICAqIHRoZSAiVE8iIHJlY2lwaWVudHMgZnJvbSBhIG1lc3NhZ2UuCisgICAgICogPGJsb2NrcXVvdGU+PHByZT4KKyAgICAgKgorICAgICAqIE1lc3NhZ2UgbXNnID0gZm9sZGVyLmdldE1lc3NhZ2VzKDEpOworICAgICAqIEFkZHJlc3NbXSBhID0gbS5nZXRSZWNpcGllbnRzKE1lc3NhZ2UuUmVjaXBpZW50VHlwZS5UTyk7CisgICAgICoKKyAgICAgKiA8L3ByZT48L2Jsb2NrcXVvdGU+CisgICAgICoKKyAgICAgKiBAc2VlIGphdmF4Lm1haWwuTWVzc2FnZSNnZXRSZWNpcGllbnRzCisgICAgICogQHNlZSBqYXZheC5tYWlsLk1lc3NhZ2Ujc2V0UmVjaXBpZW50cworICAgICAqIEBzZWUgamF2YXgubWFpbC5NZXNzYWdlI2FkZFJlY2lwaWVudHMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFJlY2lwaWVudFR5cGUgaW1wbGVtZW50cyBTZXJpYWxpemFibGUgeworCS8qKgorCSAqIFRoZSAiVG8iIChwcmltYXJ5KSByZWNpcGllbnRzLgorCSAqLworCXB1YmxpYyBzdGF0aWMgZmluYWwgUmVjaXBpZW50VHlwZSBUTyA9IG5ldyBSZWNpcGllbnRUeXBlKCJUbyIpOworCS8qKgorCSAqIFRoZSAiQ2MiIChjYXJib24gY29weSkgcmVjaXBpZW50cy4KKwkgKi8KKwlwdWJsaWMgc3RhdGljIGZpbmFsIFJlY2lwaWVudFR5cGUgQ0MgPSBuZXcgUmVjaXBpZW50VHlwZSgiQ2MiKTsKKwkvKioKKwkgKiBUaGUgIkJjYyIgKGJsaW5kIGNhcmJvbiBjb3B5KSByZWNpcGllbnRzLgorCSAqLworCXB1YmxpYyBzdGF0aWMgZmluYWwgUmVjaXBpZW50VHlwZSBCQ0MgPSBuZXcgUmVjaXBpZW50VHlwZSgiQmNjIik7CisKKwkvKioKKwkgKiBUaGUgdHlwZSBvZiByZWNpcGllbnQsIHVzdWFsbHkgdGhlIG5hbWUgb2YgYSBjb3JyZXNwb25kaW5nCisJICogSW50ZXJuZXQgc3RhbmRhcmQgaGVhZGVyLgorCSAqCisJICogQHNlcmlhbAorCSAqLworCXByb3RlY3RlZCBTdHJpbmcgdHlwZTsKKworCXByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC03NDc5NzkxNzUwNjA2MzQwMDA4TDsKKworCS8qKgorCSAqIENvbnN0cnVjdG9yIGZvciB1c2UgYnkgc3ViY2xhc3Nlcy4KKwkgKgorCSAqIEBwYXJhbQl0eXBlCXRoZSByZWNpcGllbnQgdHlwZQorCSAqLworCXByb3RlY3RlZCBSZWNpcGllbnRUeXBlKFN0cmluZyB0eXBlKSB7CisJICAgIHRoaXMudHlwZSA9IHR5cGU7CisJfQorCisJLyoqCisJICogV2hlbiBkZXNlcmlhbGl6aW5nIGEgUmVjaXBpZW50VHlwZSwgd2UgbmVlZCB0byBtYWtlIHN1cmUgdG8KKwkgKiByZXR1cm4gb25seSBvbmUgb2YgdGhlIGtub3duIHN0YXRpYyBmaW5hbCBpbnN0YW5jZXMgZGVmaW5lZAorCSAqIGluIHRoaXMgY2xhc3MuICBTdWJjbGFzc2VzIG11c3QgaW1wbGVtZW50IHRoZWlyIG93bgorCSAqIDxjb2RlPnJlYWRSZXNvbHZlPC9jb2RlPiBtZXRob2QgdGhhdCBjaGVja3MgZm9yIHRoZWlyIGtub3duCisJICogaW5zdGFuY2VzIGJlZm9yZSBjYWxsaW5nIHRoaXMgc3VwZXIgbWV0aG9kLgorCSAqCisJICogQHJldHVybgl0aGUgUmVjaXBpZW50VHlwZSBvYmplY3QgaW5zdGFuY2UKKwkgKiBAZXhjZXB0aW9uCU9iamVjdFN0cmVhbUV4Y2VwdGlvbiBmb3Igb2JqZWN0IHN0cmVhbSBlcnJvcnMKKwkgKi8KKwlwcm90ZWN0ZWQgT2JqZWN0IHJlYWRSZXNvbHZlKCkgdGhyb3dzIE9iamVjdFN0cmVhbUV4Y2VwdGlvbiB7CisJICAgIGlmICh0eXBlLmVxdWFscygiVG8iKSkKKwkJcmV0dXJuIFRPOworCSAgICBlbHNlIGlmICh0eXBlLmVxdWFscygiQ2MiKSkKKwkJcmV0dXJuIENDOworCSAgICBlbHNlIGlmICh0eXBlLmVxdWFscygiQmNjIikpCisJCXJldHVybiBCQ0M7CisJICAgIGVsc2UKKwkJdGhyb3cgbmV3IEludmFsaWRPYmplY3RFeGNlcHRpb24oCisJCSAgICAiQXR0ZW1wdCB0byByZXNvbHZlIHVua25vd24gUmVjaXBpZW50VHlwZTogIiArIHR5cGUpOworCX0KKworCUBPdmVycmlkZQorCXB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisJICAgIHJldHVybiB0eXBlOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgYWxsIHRoZSByZWNpcGllbnQgYWRkcmVzc2VzIG9mIHRoZSBnaXZlbiB0eXBlLiA8cD4KKyAgICAgKgorICAgICAqIFRoaXMgbWV0aG9kIHJldHVybnMgPGNvZGU+bnVsbDwvY29kZT4gaWYgbm8gcmVjaXBpZW50cyBvZgorICAgICAqIHRoZSBnaXZlbiB0eXBlIGFyZSBwcmVzZW50IGluIHRoaXMgbWVzc2FnZS4gSXQgbWF5IHJldHVybiBhbiAKKyAgICAgKiBlbXB0eSBhcnJheSBpZiB0aGUgaGVhZGVyIGlzIHByZXNlbnQsIGJ1dCBjb250YWlucyBubyBhZGRyZXNzZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdHlwZSAgICAgIHRoZSByZWNpcGllbnQgdHlwZQorICAgICAqIEByZXR1cm4gICAgICAgICAgYXJyYXkgb2YgQWRkcmVzcyBvYmplY3RzCisgICAgICogQGV4Y2VwdGlvbiAgICAgICBNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICogQHNlZSBNZXNzYWdlLlJlY2lwaWVudFR5cGUjVE8KKyAgICAgKiBAc2VlIE1lc3NhZ2UuUmVjaXBpZW50VHlwZSNDQworICAgICAqIEBzZWUgTWVzc2FnZS5SZWNpcGllbnRUeXBlI0JDQworICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBBZGRyZXNzW10gZ2V0UmVjaXBpZW50cyhSZWNpcGllbnRUeXBlIHR5cGUpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXQgYWxsIHRoZSByZWNpcGllbnQgYWRkcmVzc2VzIGZvciB0aGUgbWVzc2FnZS4KKyAgICAgKiBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBleHRyYWN0cyB0aGUgVE8sIENDLCBhbmQgQkNDCisgICAgICogcmVjaXBpZW50cyB1c2luZyB0aGUgPGNvZGU+Z2V0UmVjaXBpZW50czwvY29kZT4gbWV0aG9kLiA8cD4KKyAgICAgKgorICAgICAqIFRoaXMgbWV0aG9kIHJldHVybnMgPGNvZGU+bnVsbDwvY29kZT4gaWYgbm9uZSBvZiB0aGUgcmVjaXBpZW50CisgICAgICogaGVhZGVycyBhcmUgcHJlc2VudCBpbiB0aGlzIG1lc3NhZ2UuICBJdCBtYXkgUmV0dXJuIGFuIGVtcHR5IGFycmF5CisgICAgICogaWYgYW55IHJlY2lwaWVudCBoZWFkZXIgaXMgcHJlc2VudCwgYnV0IGNvbnRhaW5zIG5vIGFkZHJlc3Nlcy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gICAgICAgICAgYXJyYXkgb2YgQWRkcmVzcyBvYmplY3RzCisgICAgICogQGV4Y2VwdGlvbiAgICAgICBNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICogQHNlZSBNZXNzYWdlLlJlY2lwaWVudFR5cGUjVE8KKyAgICAgKiBAc2VlIE1lc3NhZ2UuUmVjaXBpZW50VHlwZSNDQworICAgICAqIEBzZWUgTWVzc2FnZS5SZWNpcGllbnRUeXBlI0JDQworICAgICAqIEBzZWUgI2dldFJlY2lwaWVudHMKKyAgICAgKi8KKyAgICBwdWJsaWMgQWRkcmVzc1tdIGdldEFsbFJlY2lwaWVudHMoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlBZGRyZXNzW10gdG8gPSBnZXRSZWNpcGllbnRzKFJlY2lwaWVudFR5cGUuVE8pOworCUFkZHJlc3NbXSBjYyA9IGdldFJlY2lwaWVudHMoUmVjaXBpZW50VHlwZS5DQyk7CisJQWRkcmVzc1tdIGJjYyA9IGdldFJlY2lwaWVudHMoUmVjaXBpZW50VHlwZS5CQ0MpOworCisJaWYgKGNjID09IG51bGwgJiYgYmNjID09IG51bGwpCisJICAgIHJldHVybiB0bzsJCS8vIGEgY29tbW9uIGNhc2UKKworCWludCBudW1SZWNpcCA9CisJICAgICh0byAhPSBudWxsID8gdG8ubGVuZ3RoIDogMCkgKworCSAgICAoY2MgIT0gbnVsbCA/IGNjLmxlbmd0aCA6IDApICsKKwkgICAgKGJjYyAhPSBudWxsID8gYmNjLmxlbmd0aCA6IDApOworCUFkZHJlc3NbXSBhZGRyZXNzZXMgPSBuZXcgQWRkcmVzc1tudW1SZWNpcF07CisJaW50IHBvcyA9IDA7CisJaWYgKHRvICE9IG51bGwpIHsKKwkgICAgU3lzdGVtLmFycmF5Y29weSh0bywgMCwgYWRkcmVzc2VzLCBwb3MsIHRvLmxlbmd0aCk7CisJICAgIHBvcyArPSB0by5sZW5ndGg7CisJfQorCWlmIChjYyAhPSBudWxsKSB7CisJICAgIFN5c3RlbS5hcnJheWNvcHkoY2MsIDAsIGFkZHJlc3NlcywgcG9zLCBjYy5sZW5ndGgpOworCSAgICBwb3MgKz0gY2MubGVuZ3RoOworCX0KKwlpZiAoYmNjICE9IG51bGwpIHsKKwkgICAgU3lzdGVtLmFycmF5Y29weShiY2MsIDAsIGFkZHJlc3NlcywgcG9zLCBiY2MubGVuZ3RoKTsKKwkgICAgLy8gcG9zICs9IGJjYy5sZW5ndGg7CisJfQorCXJldHVybiBhZGRyZXNzZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSByZWNpcGllbnQgYWRkcmVzc2VzLiAgQWxsIGFkZHJlc3NlcyBvZiB0aGUgc3BlY2lmaWVkCisgICAgICogdHlwZSBhcmUgcmVwbGFjZWQgYnkgdGhlIGFkZHJlc3NlcyBwYXJhbWV0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdHlwZSAgICAgIHRoZSByZWNpcGllbnQgdHlwZQorICAgICAqIEBwYXJhbSBhZGRyZXNzZXMgdGhlIGFkZHJlc3NlcworICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFdyaXRlRXhjZXB0aW9uIGlmIHRoZSB1bmRlcmx5aW5nIAorICAgICAqCQkJaW1wbGVtZW50YXRpb24gZG9lcyBub3Qgc3VwcG9ydCBtb2RpZmljYXRpb24gCisgICAgICoJCQlvZiBleGlzdGluZyB2YWx1ZXMKKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIG1lc3NhZ2UgaXMKKyAgICAgKgkJCW9idGFpbmVkIGZyb20gYSBSRUFEX09OTFkgZm9sZGVyLgorICAgICAqIEBleGNlcHRpb24gICAgICAgTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBvdGhlciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNldFJlY2lwaWVudHMoUmVjaXBpZW50VHlwZSB0eXBlLCBBZGRyZXNzW10gYWRkcmVzc2VzKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0IHRoZSByZWNpcGllbnQgYWRkcmVzcy4gIEFsbCBhZGRyZXNzZXMgb2YgdGhlIHNwZWNpZmllZAorICAgICAqIHR5cGUgYXJlIHJlcGxhY2VkIGJ5IHRoZSBhZGRyZXNzIHBhcmFtZXRlci4gPHA+CisgICAgICoKKyAgICAgKiBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiB1c2VzIHRoZSA8Y29kZT5zZXRSZWNpcGllbnRzPC9jb2RlPiBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdHlwZSAgICAgIHRoZSByZWNpcGllbnQgdHlwZQorICAgICAqIEBwYXJhbSBhZGRyZXNzCXRoZSBhZGRyZXNzCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsV3JpdGVFeGNlcHRpb24gaWYgdGhlIHVuZGVybHlpbmcgCisgICAgICoJCQlpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IG1vZGlmaWNhdGlvbiAKKyAgICAgKgkJCW9mIGV4aXN0aW5nIHZhbHVlcworICAgICAqIEBleGNlcHRpb24gICAgICAgTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBvdGhlciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFJlY2lwaWVudChSZWNpcGllbnRUeXBlIHR5cGUsIEFkZHJlc3MgYWRkcmVzcykKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKGFkZHJlc3MgPT0gbnVsbCkKKwkgICAgc2V0UmVjaXBpZW50cyh0eXBlLCBudWxsKTsKKwllbHNlIHsKKwkgICAgQWRkcmVzc1tdIGEgPSBuZXcgQWRkcmVzc1sxXTsKKwkgICAgYVswXSA9IGFkZHJlc3M7CisJICAgIHNldFJlY2lwaWVudHModHlwZSwgYSk7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZCB0aGVzZSByZWNpcGllbnQgYWRkcmVzc2VzIHRvIHRoZSBleGlzdGluZyBvbmVzIG9mIHRoZSBnaXZlbiB0eXBlLgorICAgICAqCisgICAgICogQHBhcmFtIHR5cGUgICAgICB0aGUgcmVjaXBpZW50IHR5cGUKKyAgICAgKiBAcGFyYW0gYWRkcmVzc2VzIHRoZSBhZGRyZXNzZXMKKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxXcml0ZUV4Y2VwdGlvbiBpZiB0aGUgdW5kZXJseWluZyAKKyAgICAgKgkJCWltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uIAorICAgICAqCQkJb2YgZXhpc3RpbmcgdmFsdWVzCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBtZXNzYWdlIGlzCisgICAgICoJCQlvYnRhaW5lZCBmcm9tIGEgUkVBRF9PTkxZIGZvbGRlci4KKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIE1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBhZGRSZWNpcGllbnRzKFJlY2lwaWVudFR5cGUgdHlwZSwgQWRkcmVzc1tdIGFkZHJlc3NlcykKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEFkZCB0aGlzIHJlY2lwaWVudCBhZGRyZXNzIHRvIHRoZSBleGlzdGluZyBvbmVzIG9mIHRoZSBnaXZlbiB0eXBlLiA8cD4KKyAgICAgKgorICAgICAqIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIHVzZXMgdGhlIDxjb2RlPmFkZFJlY2lwaWVudHM8L2NvZGU+IG1ldGhvZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0eXBlICAgICAgdGhlIHJlY2lwaWVudCB0eXBlCisgICAgICogQHBhcmFtIGFkZHJlc3MJdGhlIGFkZHJlc3MKKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxXcml0ZUV4Y2VwdGlvbiBpZiB0aGUgdW5kZXJseWluZyAKKyAgICAgKgkJCWltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uIAorICAgICAqCQkJb2YgZXhpc3RpbmcgdmFsdWVzCisgICAgICogQGV4Y2VwdGlvbiAgICAgICBNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIHZvaWQgYWRkUmVjaXBpZW50KFJlY2lwaWVudFR5cGUgdHlwZSwgQWRkcmVzcyBhZGRyZXNzKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlBZGRyZXNzW10gYSA9IG5ldyBBZGRyZXNzWzFdOworCWFbMF0gPSBhZGRyZXNzOworCWFkZFJlY2lwaWVudHModHlwZSwgYSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBhZGRyZXNzZXMgdG8gd2hpY2ggcmVwbGllcyBzaG91bGQgYmUgZGlyZWN0ZWQuCisgICAgICogVGhpcyB3aWxsIHVzdWFsbHkgYmUgdGhlIHNlbmRlciBvZiB0aGUgbWVzc2FnZSwgYnV0CisgICAgICogc29tZSBtZXNzYWdlcyBtYXkgZGlyZWN0IHJlcGxpZXMgdG8gYSBkaWZmZXJlbnQgYWRkcmVzcy4gPHA+CisgICAgICoKKyAgICAgKiBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBzaW1wbHkgY2FsbHMgdGhlIDxjb2RlPmdldEZyb208L2NvZGU+CisgICAgICogbWV0aG9kLiA8cD4KKyAgICAgKgorICAgICAqIFRoaXMgbWV0aG9kIHJldHVybnMgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlIGNvcnJlc3BvbmRpbmcKKyAgICAgKiBoZWFkZXIgaXMgbm90IHByZXNlbnQuIFJldHVybnMgYW4gZW1wdHkgYXJyYXkgaWYgdGhlIGhlYWRlcgorICAgICAqIGlzIHByZXNlbnQsIGJ1dCBjb250YWlucyBubyBhZGRyZXNzZXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuICAgICAgICAgIGFkZHJlc3NlcyB0byB3aGljaCByZXBsaWVzIHNob3VsZCBiZSBkaXJlY3RlZAorICAgICAqIEBleGNlcHRpb24gICAgICAgTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqIEBzZWUJCSNnZXRGcm9tCisgICAgICovCisgICAgcHVibGljIEFkZHJlc3NbXSBnZXRSZXBseVRvKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBnZXRGcm9tKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBhZGRyZXNzZXMgdG8gd2hpY2ggcmVwbGllcyBzaG91bGQgYmUgZGlyZWN0ZWQuCisgICAgICogKE5vcm1hbGx5IG9ubHkgYSBzaW5nbGUgYWRkcmVzcyB3aWxsIGJlIHNwZWNpZmllZC4pCisgICAgICogTm90IGFsbCBtZXNzYWdlIHR5cGVzIGFsbG93IHRoaXMgdG8gYmUgc3BlY2lmaWVkIHNlcGFyYXRlbHkKKyAgICAgKiBmcm9tIHRoZSBzZW5kZXIgb2YgdGhlIG1lc3NhZ2UuIDxwPgorICAgICAqCisgICAgICogVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gcHJvdmlkZWQgaGVyZSBqdXN0IHRocm93cyB0aGUKKyAgICAgKiBNZXRob2ROb3RTdXBwb3J0ZWRFeGNlcHRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWRkcmVzc2VzIGFkZHJlc3NlcyB0byB3aGljaCByZXBsaWVzIHNob3VsZCBiZSBkaXJlY3RlZAorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFdyaXRlRXhjZXB0aW9uIGlmIHRoZSB1bmRlcmx5aW5nIAorICAgICAqCQkJaW1wbGVtZW50YXRpb24gZG9lcyBub3Qgc3VwcG9ydCBtb2RpZmljYXRpb24gCisgICAgICoJCQlvZiBleGlzdGluZyB2YWx1ZXMKKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIG1lc3NhZ2UgaXMKKyAgICAgKgkJCW9idGFpbmVkIGZyb20gYSBSRUFEX09OTFkgZm9sZGVyLgorICAgICAqIEBleGNlcHRpb24JTWV0aG9kTm90U3VwcG9ydGVkRXhjZXB0aW9uIGlmIHRoZSB1bmRlcmx5aW5nIAorICAgICAqCQkJaW1wbGVtZW50YXRpb24gZG9lcyBub3Qgc3VwcG9ydCBzZXR0aW5nIHRoaXMKKyAgICAgKgkJCWF0dHJpYnV0ZQorICAgICAqIEBleGNlcHRpb24gICAgICAgTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBvdGhlciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFJlcGx5VG8oQWRkcmVzc1tdIGFkZHJlc3NlcykgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJdGhyb3cgbmV3IE1ldGhvZE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigic2V0UmVwbHlUbyBub3Qgc3VwcG9ydGVkIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBzdWJqZWN0IG9mIHRoaXMgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gICAgICAgICAgdGhlIHN1YmplY3QKKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIE1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGdldFN1YmplY3QoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0IHRoZSBzdWJqZWN0IG9mIHRoaXMgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdWJqZWN0ICAgdGhlIHN1YmplY3QKKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxXcml0ZUV4Y2VwdGlvbiBpZiB0aGUgdW5kZXJseWluZyAKKyAgICAgKgkJCWltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uIAorICAgICAqCQkJb2YgZXhpc3RpbmcgdmFsdWVzCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBtZXNzYWdlIGlzCisgICAgICoJCQlvYnRhaW5lZCBmcm9tIGEgUkVBRF9PTkxZIGZvbGRlci4KKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIE1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRTdWJqZWN0KFN0cmluZyBzdWJqZWN0KSAKKwkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGRhdGUgdGhpcyBtZXNzYWdlIHdhcyBzZW50LgorICAgICAqCisgICAgICogQHJldHVybiAgICAgICAgICB0aGUgZGF0ZSB0aGlzIG1lc3NhZ2Ugd2FzIHNlbnQKKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIE1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgRGF0ZSBnZXRTZW50RGF0ZSgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHNlbnQgZGF0ZSBvZiB0aGlzIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZGF0ZSAgICAgIHRoZSBzZW50IGRhdGUgb2YgdGhpcyBtZXNzYWdlCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsV3JpdGVFeGNlcHRpb24gaWYgdGhlIHVuZGVybHlpbmcgCisgICAgICoJCQlpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IG1vZGlmaWNhdGlvbiAKKyAgICAgKgkJCW9mIGV4aXN0aW5nIHZhbHVlcworICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgbWVzc2FnZSBpcworICAgICAqCQkJb2J0YWluZWQgZnJvbSBhIFJFQURfT05MWSBmb2xkZXIuCisgICAgICogQGV4Y2VwdGlvbiAgICAgICBNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0U2VudERhdGUoRGF0ZSBkYXRlKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0IHRoZSBkYXRlIHRoaXMgbWVzc2FnZSB3YXMgcmVjZWl2ZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuICAgICAgICAgIHRoZSBkYXRlIHRoaXMgbWVzc2FnZSB3YXMgcmVjZWl2ZWQKKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIE1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgRGF0ZSBnZXRSZWNlaXZlZERhdGUoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIDxjb2RlPkZsYWdzPC9jb2RlPiBvYmplY3QgY29udGFpbmluZyB0aGUgZmxhZ3MgZm9yIAorICAgICAqIHRoaXMgbWVzc2FnZS4gPHA+CisgICAgICoKKyAgICAgKiBNb2RpZnlpbmcgYW55IG9mIHRoZSBmbGFncyBpbiB0aGlzIHJldHVybmVkIEZsYWdzIG9iamVjdCB3aWxsIAorICAgICAqIG5vdCBhZmZlY3QgdGhlIGZsYWdzIG9mIHRoaXMgbWVzc2FnZS4gVXNlIDxjb2RlPnNldEZsYWdzKCk8L2NvZGU+CisgICAgICogdG8gZG8gdGhhdC4gPHA+CisgICAgICoKKyAgICAgKiBAcmV0dXJuCQlGbGFncyBvYmplY3QgY29udGFpbmluZyB0aGUgZmxhZ3MgZm9yIHRoaXMgbWVzc2FnZQorICAgICAqIEBzZWUgCQlqYXZheC5tYWlsLkZsYWdzCisgICAgICogQHNlZSAJCSNzZXRGbGFncworICAgICAqIEBleGNlcHRpb24gICAgICAgTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBGbGFncyBnZXRGbGFncygpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBDaGVjayB3aGV0aGVyIHRoZSBmbGFnIHNwZWNpZmllZCBpbiB0aGUgPGNvZGU+ZmxhZzwvY29kZT4KKyAgICAgKiBhcmd1bWVudCBpcyBzZXQgaW4gdGhpcyBtZXNzYWdlLiA8cD4KKyAgICAgKgorICAgICAqIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIHVzZXMgPGNvZGU+Z2V0RmxhZ3M8L2NvZGU+LgorICAgICAqCisgICAgICogQHBhcmFtIGZsYWcJdGhlIGZsYWcKKyAgICAgKiBAcmV0dXJuCQl2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIGZsYWcgZm9yIHRoaXMgbWVzc2FnZQorICAgICAqIEBzZWUgCQlqYXZheC5tYWlsLkZsYWdzLkZsYWcKKyAgICAgKiBAc2VlCQlqYXZheC5tYWlsLkZsYWdzLkZsYWcjQU5TV0VSRUQKKyAgICAgKiBAc2VlCQlqYXZheC5tYWlsLkZsYWdzLkZsYWcjREVMRVRFRAorICAgICAqIEBzZWUJCWphdmF4Lm1haWwuRmxhZ3MuRmxhZyNEUkFGVAorICAgICAqIEBzZWUJCWphdmF4Lm1haWwuRmxhZ3MuRmxhZyNGTEFHR0VECisgICAgICogQHNlZQkJamF2YXgubWFpbC5GbGFncy5GbGFnI1JFQ0VOVAorICAgICAqIEBzZWUJCWphdmF4Lm1haWwuRmxhZ3MuRmxhZyNTRUVOCisgICAgICogQGV4Y2VwdGlvbiAgICAgICBNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXQoRmxhZ3MuRmxhZyBmbGFnKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gZ2V0RmxhZ3MoKS5jb250YWlucyhmbGFnKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHNwZWNpZmllZCBmbGFncyBvbiB0aGlzIG1lc3NhZ2UgdG8gdGhlIHNwZWNpZmllZCB2YWx1ZS4KKyAgICAgKiBOb3RlIHRoYXQgYW55IGZsYWdzIGluIHRoaXMgbWVzc2FnZSB0aGF0IGFyZSBub3Qgc3BlY2lmaWVkIGluCisgICAgICogdGhlIGdpdmVuIDxjb2RlPkZsYWdzPC9jb2RlPiBvYmplY3QgYXJlIHVuYWZmZWN0ZWQuIDxwPgorICAgICAqCisgICAgICogVGhpcyB3aWxsIHJlc3VsdCBpbiBhIDxjb2RlPk1lc3NhZ2VDaGFuZ2VkRXZlbnQ8L2NvZGU+IGJlaW5nIAorICAgICAqIGRlbGl2ZXJlZCB0byBhbnkgTWVzc2FnZUNoYW5nZWRMaXN0ZW5lciByZWdpc3RlcmVkIG9uIHRoaXMgCisgICAgICogTWVzc2FnZSdzIGNvbnRhaW5pbmcgZm9sZGVyLgorICAgICAqCisgICAgICogQHBhcmFtIGZsYWcJRmxhZ3Mgb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGZsYWdzIHRvIGJlIHNldAorICAgICAqIEBwYXJhbSBzZXQJdGhlIHZhbHVlIHRvIGJlIHNldAorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFdyaXRlRXhjZXB0aW9uIGlmIHRoZSB1bmRlcmx5aW5nIAorICAgICAqCQkJaW1wbGVtZW50YXRpb24gZG9lcyBub3Qgc3VwcG9ydCBtb2RpZmljYXRpb24gCisgICAgICoJCQlvZiBleGlzdGluZyB2YWx1ZXMuCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBtZXNzYWdlIGlzCisgICAgICoJCQlvYnRhaW5lZCBmcm9tIGEgUkVBRF9PTkxZIGZvbGRlci4KKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIE1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKiBAc2VlCQlqYXZheC5tYWlsLmV2ZW50Lk1lc3NhZ2VDaGFuZ2VkRXZlbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRGbGFncyhGbGFncyBmbGFnLCBib29sZWFuIHNldCkKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0IHRoZSBzcGVjaWZpZWQgZmxhZyBvbiB0aGlzIG1lc3NhZ2UgdG8gdGhlIHNwZWNpZmllZCB2YWx1ZS4KKyAgICAgKgorICAgICAqIFRoaXMgd2lsbCByZXN1bHQgaW4gYSA8Y29kZT5NZXNzYWdlQ2hhbmdlZEV2ZW50PC9jb2RlPiBiZWluZyAKKyAgICAgKiBkZWxpdmVyZWQgdG8gYW55IE1lc3NhZ2VDaGFuZ2VkTGlzdGVuZXIgcmVnaXN0ZXJlZCBvbiB0aGlzIAorICAgICAqIE1lc3NhZ2UncyBjb250YWluaW5nIGZvbGRlci4gPHA+CisgICAgICoKKyAgICAgKiBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiB1c2VzIHRoZSA8Y29kZT5zZXRGbGFnczwvY29kZT4gbWV0aG9kLgorICAgICAqCisgICAgICogQHBhcmFtIGZsYWcJRmxhZ3MuRmxhZyBvYmplY3QgY29udGFpbmluZyB0aGUgZmxhZyB0byBiZSBzZXQKKyAgICAgKiBAcGFyYW0gc2V0CXRoZSB2YWx1ZSB0byBiZSBzZXQKKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxXcml0ZUV4Y2VwdGlvbiBpZiB0aGUgdW5kZXJseWluZyAKKyAgICAgKgkJCWltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uIAorICAgICAqCQkJb2YgZXhpc3RpbmcgdmFsdWVzLgorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgbWVzc2FnZSBpcworICAgICAqCQkJb2J0YWluZWQgZnJvbSBhIFJFQURfT05MWSBmb2xkZXIuCisgICAgICogQGV4Y2VwdGlvbiAgICAgICBNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICogQHNlZQkJamF2YXgubWFpbC5ldmVudC5NZXNzYWdlQ2hhbmdlZEV2ZW50CisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RmxhZyhGbGFncy5GbGFnIGZsYWcsIGJvb2xlYW4gc2V0KQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCUZsYWdzIGYgPSBuZXcgRmxhZ3MoZmxhZyk7CisJc2V0RmxhZ3MoZiwgc2V0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIE1lc3NhZ2UgbnVtYmVyIGZvciB0aGlzIE1lc3NhZ2UuCisgICAgICogQSBNZXNzYWdlIG9iamVjdCdzIG1lc3NhZ2UgbnVtYmVyIGlzIHRoZSByZWxhdGl2ZQorICAgICAqIHBvc2l0aW9uIG9mIHRoaXMgTWVzc2FnZSBpbiBpdHMgRm9sZGVyLiBOb3RlIHRoYXQgdGhlIG1lc3NhZ2UKKyAgICAgKiBudW1iZXIgZm9yIGEgcGFydGljdWxhciBNZXNzYWdlIGNhbiBjaGFuZ2UgZHVyaW5nIGEgc2Vzc2lvbgorICAgICAqIGlmIG90aGVyIG1lc3NhZ2VzIGluIHRoZSBGb2xkZXIgYXJlIGRlbGV0ZWQgYW5kIGV4cHVuZ2VkLiA8cD4KKyAgICAgKgorICAgICAqIFZhbGlkIG1lc3NhZ2UgbnVtYmVycyBzdGFydCBhdCAxLiBNZXNzYWdlcyB0aGF0IGRvIG5vdCBiZWxvbmcKKyAgICAgKiB0byBhbnkgZm9sZGVyIChsaWtlIG5ld2x5IGNvbXBvc2VkIG9yIGRlcml2ZWQgbWVzc2FnZXMpIGhhdmUgMAorICAgICAqIGFzIHRoZWlyIG1lc3NhZ2UgbnVtYmVyLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgbWVzc2FnZSBudW1iZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE1lc3NhZ2VOdW1iZXIoKSB7CisJcmV0dXJuIG1zZ251bTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIE1lc3NhZ2UgbnVtYmVyIGZvciB0aGlzIE1lc3NhZ2UuIFRoaXMgbWV0aG9kIGlzCisgICAgICogaW52b2tlZCBvbmx5IGJ5IHRoZSBpbXBsZW1lbnRhdGlvbiBjbGFzc2VzLgorICAgICAqCisgICAgICogQHBhcmFtCW1zZ251bQl0aGUgbWVzc2FnZSBudW1iZXIKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRNZXNzYWdlTnVtYmVyKGludCBtc2dudW0pIHsKKwl0aGlzLm1zZ251bSA9IG1zZ251bTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGZvbGRlciBmcm9tIHdoaWNoIHRoaXMgbWVzc2FnZSB3YXMgb2J0YWluZWQuIElmCisgICAgICogdGhpcyBpcyBhIG5ldyBtZXNzYWdlIG9yIG5lc3RlZCBtZXNzYWdlLCB0aGlzIG1ldGhvZCByZXR1cm5zCisgICAgICogbnVsbC4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIGNvbnRhaW5pbmcgZm9sZGVyCisgICAgICovCisgICAgcHVibGljIEZvbGRlciBnZXRGb2xkZXIoKSB7CisJcmV0dXJuIGZvbGRlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVja3Mgd2hldGhlciB0aGlzIG1lc3NhZ2UgaXMgZXhwdW5nZWQuIEFsbCBvdGhlciBtZXRob2RzIGV4Y2VwdAorICAgICAqIDxjb2RlPmdldE1lc3NhZ2VOdW1iZXIoKTwvY29kZT4gYXJlIGludmFsaWQgb24gYW4gZXhwdW5nZWQgCisgICAgICogTWVzc2FnZSBvYmplY3QuIDxwPgorICAgICAqCisgICAgICogTWVzc2FnZXMgdGhhdCBhcmUgZXhwdW5nZWQgZHVlIHRvIGFuIGV4cGxpY3QgPGNvZGU+ZXhwdW5nZSgpPC9jb2RlPgorICAgICAqIHJlcXVlc3Qgb24gdGhlIGNvbnRhaW5pbmcgRm9sZGVyIGFyZSByZW1vdmVkIGZyb20gdGhlIEZvbGRlciAKKyAgICAgKiBpbW1lZGlhdGVseS4gTWVzc2FnZXMgdGhhdCBhcmUgZXh0ZXJuYWxseSBleHB1bmdlZCBieSBhbm90aGVyIHNvdXJjZQorICAgICAqIGFyZSBtYXJrZWQgImV4cHVuZ2VkIiBhbmQgcmV0dXJuIHRydWUgZm9yIHRoZSBpc0V4cHVuZ2VkKCkgbWV0aG9kLCAKKyAgICAgKiBidXQgdGhleSBhcmUgbm90IHJlbW92ZWQgZnJvbSB0aGUgRm9sZGVyIHVudGlsIGFuIGV4cGxpY2l0IAorICAgICAqIDxjb2RlPmV4cHVuZ2UoKTwvY29kZT4gaXMgZG9uZSBvbiB0aGUgRm9sZGVyLiA8cD4KKyAgICAgKiAKKyAgICAgKiBTZWUgdGhlIGRlc2NyaXB0aW9uIG9mIDxjb2RlPmV4cHVuZ2UoKTwvY29kZT4gZm9yIG1vcmUgZGV0YWlscyBvbgorICAgICAqIGV4cHVuZ2UgaGFuZGxpbmcuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRydWUgaWYgdGhlIG1lc3NhZ2UgaXMgZXhwdW5nZWQKKyAgICAgKiBAc2VlCUZvbGRlciNleHB1bmdlCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNFeHB1bmdlZCgpIHsKKwlyZXR1cm4gZXhwdW5nZWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgZXhwdW5nZWQgZmxhZyBmb3IgdGhpcyBNZXNzYWdlLiBUaGlzIG1ldGhvZCBpcyB0bworICAgICAqIGJlIHVzZWQgb25seSBieSB0aGUgaW1wbGVtZW50YXRpb24gY2xhc3Nlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBleHB1bmdlZAl0aGUgZXhwdW5nZWQgZmxhZworICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHNldEV4cHVuZ2VkKGJvb2xlYW4gZXhwdW5nZWQpIHsKKwl0aGlzLmV4cHVuZ2VkID0gZXhwdW5nZWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IGEgbmV3IE1lc3NhZ2Ugc3VpdGFibGUgZm9yIGEgcmVwbHkgdG8gdGhpcyBtZXNzYWdlLgorICAgICAqIFRoZSBuZXcgTWVzc2FnZSB3aWxsIGhhdmUgaXRzIGF0dHJpYnV0ZXMgYW5kIGhlYWRlcnMgCisgICAgICogc2V0IHVwIGFwcHJvcHJpYXRlbHkuICBOb3RlIHRoYXQgdGhpcyBuZXcgbWVzc2FnZSBvYmplY3QKKyAgICAgKiB3aWxsIGJlIGVtcHR5LCB0aGF0IGlzLCBpdCB3aWxsIDxzdHJvbmc+bm90PC9zdHJvbmc+IGhhdmUgYSAiY29udGVudCIuCisgICAgICogVGhlc2Ugd2lsbCBoYXZlIHRvIGJlIHN1aXRhYmx5IGZpbGxlZCBpbiBieSB0aGUgY2xpZW50LiA8cD4KKyAgICAgKgorICAgICAqIElmIDxjb2RlPnJlcGx5VG9BbGw8L2NvZGU+IGlzIHNldCwgdGhlIG5ldyBNZXNzYWdlIHdpbGwgYmUgYWRkcmVzc2VkCisgICAgICogdG8gYWxsIHJlY2lwaWVudHMgb2YgdGhpcyBtZXNzYWdlLiAgT3RoZXJ3aXNlLCB0aGUgcmVwbHkgd2lsbCBiZQorICAgICAqIGFkZHJlc3NlZCB0byBvbmx5IHRoZSBzZW5kZXIgb2YgdGhpcyBtZXNzYWdlICh1c2luZyB0aGUgdmFsdWUKKyAgICAgKiBvZiB0aGUgPGNvZGU+Z2V0UmVwbHlUbzwvY29kZT4gbWV0aG9kKS4gIDxwPgorICAgICAqCisgICAgICogVGhlICJTdWJqZWN0IiBmaWVsZCBpcyBmaWxsZWQgaW4gd2l0aCB0aGUgb3JpZ2luYWwgc3ViamVjdAorICAgICAqIHByZWZpeGVkIHdpdGggIlJlOiIgKHVubGVzcyBpdCBhbHJlYWR5IHN0YXJ0cyB3aXRoICJSZToiKS4gPHA+CisgICAgICoKKyAgICAgKiBUaGUgcmVwbHkgbWVzc2FnZSB3aWxsIHVzZSB0aGUgc2FtZSBzZXNzaW9uIGFzIHRoaXMgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbQlyZXBseVRvQWxsCXJlcGx5IHNob3VsZCBiZSBzZW50IHRvIGFsbCByZWNpcGllbnRzCisgICAgICoJCQkJb2YgdGhpcyBtZXNzYWdlCisgICAgICogQHJldHVybgkJdGhlIHJlcGx5IE1lc3NhZ2UKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgTWVzc2FnZSByZXBseShib29sZWFuIHJlcGx5VG9BbGwpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTYXZlIGFueSBjaGFuZ2VzIG1hZGUgdG8gdGhpcyBtZXNzYWdlIGludG8gdGhlIG1lc3NhZ2Utc3RvcmUKKyAgICAgKiB3aGVuIHRoZSBjb250YWluaW5nIGZvbGRlciBpcyBjbG9zZWQsIGlmIHRoZSBtZXNzYWdlIGlzIGNvbnRhaW5lZAorICAgICAqIGluIGEgZm9sZGVyLiAgKFNvbWUgaW1wbGVtZW50YXRpb25zIG1heSBzYXZlIHRoZSBjaGFuZ2VzCisgICAgICogaW1tZWRpYXRlbHkuKSAgVXBkYXRlIGFueSBoZWFkZXIgZmllbGRzIHRvIGJlIGNvbnNpc3RlbnQgd2l0aCB0aGUKKyAgICAgKiBjaGFuZ2VkIG1lc3NhZ2UgY29udGVudHMuICBJZiBhbnkgcGFydCBvZiBhIG1lc3NhZ2UncyBoZWFkZXJzIG9yCisgICAgICogY29udGVudHMgYXJlIGNoYW5nZWQsIHNhdmVDaGFuZ2VzIG11c3QgYmUgY2FsbGVkIHRvIGVuc3VyZSB0aGF0CisgICAgICogdGhvc2UgY2hhbmdlcyBhcmUgcGVybWFuZW50LiAgSWYgc2F2ZUNoYW5nZXMgaXMgbm90IGNhbGxlZCwgYW55CisgICAgICogc3VjaCBtb2RpZmljYXRpb25zIG1heSBvciBtYXkgbm90IGJlIHNhdmVkLCBkZXBlbmRpbmcgb24gdGhlCisgICAgICogbWVzc2FnZSBzdG9yZSBhbmQgZm9sZGVyIGltcGxlbWVudGF0aW9uLiA8cD4KKyAgICAgKgorICAgICAqIE1lc3NhZ2VzIG9idGFpbmVkIGZyb20gZm9sZGVycyBvcGVuZWQgUkVBRF9PTkxZIHNob3VsZCBub3QgYmUKKyAgICAgKiBtb2RpZmllZCBhbmQgc2F2ZUNoYW5nZXMgc2hvdWxkIG5vdCBiZSBjYWxsZWQgb24gc3VjaCBtZXNzYWdlcy4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgbWVzc2FnZSBpcworICAgICAqCQkJb2J0YWluZWQgZnJvbSBhIFJFQURfT05MWSBmb2xkZXIuCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsV3JpdGVFeGNlcHRpb24gaWYgdGhlIHVuZGVybHlpbmcgCisgICAgICoJCQlpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IG1vZGlmaWNhdGlvbiAKKyAgICAgKgkJCW9mIGV4aXN0aW5nIHZhbHVlcy4KKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIE1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzYXZlQ2hhbmdlcygpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBBcHBseSB0aGUgc3BlY2lmaWVkIFNlYXJjaCBjcml0ZXJpb24gdG8gdGhpcyBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIHRlcm0JdGhlIFNlYXJjaCBjcml0ZXJpb24KKyAgICAgKiBAcmV0dXJuCQl0cnVlIGlmIHRoZSBNZXNzYWdlIG1hdGNoZXMgdGhpcyBzZWFyY2gKKyAgICAgKgkJCWNyaXRlcmlvbiwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgICAqIEBleGNlcHRpb24gICAgICAgTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqIEBzZWUJCWphdmF4Lm1haWwuc2VhcmNoLlNlYXJjaFRlcm0KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBtYXRjaChTZWFyY2hUZXJtIHRlcm0pIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXJldHVybiB0ZXJtLm1hdGNoKHRoaXMpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL01lc3NhZ2VBd2FyZS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvTWVzc2FnZUF3YXJlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzY1N2ZjYwotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL01lc3NhZ2VBd2FyZS5qYXZhCkBAIC0wLDAgKzEsMzYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbDsKKworLyoqCisgKiBBbiBpbnRlcmZhY2Ugb3B0aW9uYWxseSBpbXBsZW1lbnRlZCBieSA8Y29kZT5EYXRhU291cmNlczwvY29kZT4gdG8KKyAqIHN1cHBseSBpbmZvcm1hdGlvbiB0byBhIDxjb2RlPkRhdGFDb250ZW50SGFuZGxlcjwvY29kZT4gYWJvdXQgdGhlCisgKiBtZXNzYWdlIGNvbnRleHQgaW4gd2hpY2ggdGhlIGRhdGEgY29udGVudCBvYmplY3QgaXMgb3BlcmF0aW5nLgorICoKKyAqIEBzZWUgamF2YXgubWFpbC5NZXNzYWdlQ29udGV4dAorICogQHNlZSBqYXZheC5hY3RpdmF0aW9uLkRhdGFTb3VyY2UKKyAqIEBzZWUgamF2YXguYWN0aXZhdGlvbi5EYXRhQ29udGVudEhhbmRsZXIKKyAqIEBzaW5jZQlKYXZhTWFpbCAxLjEKKyAqLworcHVibGljIGludGVyZmFjZSBNZXNzYWdlQXdhcmUgeworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgbWVzc2FnZSBjb250ZXh0LgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgbWVzc2FnZSBjb250ZXh0CisgICAgICovCisgICAgcHVibGljIE1lc3NhZ2VDb250ZXh0IGdldE1lc3NhZ2VDb250ZXh0KCk7Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9NZXNzYWdlQ29udGV4dC5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvTWVzc2FnZUNvbnRleHQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMTM2NWNiCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvTWVzc2FnZUNvbnRleHQuamF2YQpAQCAtMCwwICsxLDEwMCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsOworCisvKioKKyAqIFRoZSBjb250ZXh0IGluIHdoaWNoIGEgcGllY2Ugb2YgTWVzc2FnZSBjb250ZW50IGlzIGNvbnRhaW5lZC4gIEEKKyAqIDxjb2RlPk1lc3NhZ2VDb250ZXh0PC9jb2RlPiBvYmplY3QgaXMgcmV0dXJuZWQgYnkgdGhlCisgKiA8Y29kZT5nZXRNZXNzYWdlQ29udGV4dDwvY29kZT4gbWV0aG9kIG9mIHRoZQorICogPGNvZGU+TWVzc2FnZUF3YXJlPC9jb2RlPiBpbnRlcmZhY2UuICA8Y29kZT5NZXNzYWdlQXdhcmU8L2NvZGU+IGlzCisgKiB0eXBpY2FsbHkgaW1wbGVtZW50ZWQgYnkgPGNvZGU+RGF0YVNvdXJjZXM8L2NvZGU+IHRvIGFsbG93IGEKKyAqIDxjb2RlPkRhdGFDb250ZW50SGFuZGxlcjwvY29kZT4gdG8gcGFzcyBvbiBpbmZvcm1hdGlvbiBhYm91dCB0aGUKKyAqIGNvbnRleHQgaW4gd2hpY2ggYSBkYXRhIGNvbnRlbnQgb2JqZWN0IGlzIG9wZXJhdGluZy4KKyAqCisgKiBAc2VlIGphdmF4Lm1haWwuTWVzc2FnZUF3YXJlCisgKiBAc2VlIGphdmF4LmFjdGl2YXRpb24uRGF0YVNvdXJjZQorICogQHNlZSBqYXZheC5hY3RpdmF0aW9uLkRhdGFDb250ZW50SGFuZGxlcgorICogQHNpbmNlCUphdmFNYWlsIDEuMQorICovCitwdWJsaWMgY2xhc3MgTWVzc2FnZUNvbnRleHQgeworICAgIHByaXZhdGUgUGFydCBwYXJ0OworCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgTWVzc2FnZUNvbnRleHQgb2JqZWN0IGRlc2NyaWJpbmcgdGhlIGNvbnRleHQgb2YgdGhlIGdpdmVuIFBhcnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0JcGFydAl0aGUgUGFydAorICAgICAqLworICAgIHB1YmxpYyBNZXNzYWdlQ29udGV4dChQYXJ0IHBhcnQpIHsKKwl0aGlzLnBhcnQgPSBwYXJ0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgUGFydCB0aGF0IGNvbnRhaW5zIHRoZSBjb250ZW50LgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgY29udGFpbmluZyBQYXJ0LCBvciBudWxsIGlmIG5vdCBrbm93bgorICAgICAqLworICAgIHB1YmxpYyBQYXJ0IGdldFBhcnQoKSB7CisJcmV0dXJuIHBhcnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBNZXNzYWdlIHRoYXQgY29udGFpbnMgdGhlIGNvbnRlbnQuCisgICAgICogRm9sbG93cyB0aGUgcGFyZW50IGNoYWluIHVwIHRocm91Z2ggY29udGFpbmluZyBNdWx0aXBhcnQKKyAgICAgKiBvYmplY3RzIHVudGlsIGl0IGNvbWVzIHRvIGEgTWVzc2FnZSBvYmplY3QsIG9yIG51bGwuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBjb250YWluaW5nIE1lc3NhZ2UsIG9yIG51bGwgaWYgbm90IGtub3duCisgICAgICovCisgICAgcHVibGljIE1lc3NhZ2UgZ2V0TWVzc2FnZSgpIHsKKwl0cnkgeworCSAgICByZXR1cm4gZ2V0TWVzc2FnZShwYXJ0KTsKKwl9IGNhdGNoIChNZXNzYWdpbmdFeGNlcHRpb24gZXgpIHsKKwkgICAgcmV0dXJuIG51bGw7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgTWVzc2FnZSBjb250YWluaW5nIGFuIGFyYml0cmFyeSBQYXJ0LgorICAgICAqIEZvbGxvd3MgdGhlIHBhcmVudCBjaGFpbiB1cCB0aHJvdWdoIGNvbnRhaW5pbmcgTXVsdGlwYXJ0CisgICAgICogb2JqZWN0cyB1bnRpbCBpdCBjb21lcyB0byBhIE1lc3NhZ2Ugb2JqZWN0LCBvciBudWxsLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgY29udGFpbmluZyBNZXNzYWdlLCBvciBudWxsIGlmIG5vbmUKKyAgICAgKiBAc2VlIGphdmF4Lm1haWwuQm9keVBhcnQjZ2V0UGFyZW50CisgICAgICogQHNlZSBqYXZheC5tYWlsLk11bHRpcGFydCNnZXRQYXJlbnQKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBNZXNzYWdlIGdldE1lc3NhZ2UoUGFydCBwKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwl3aGlsZSAocCAhPSBudWxsKSB7CisJICAgIGlmIChwIGluc3RhbmNlb2YgTWVzc2FnZSkKKwkJcmV0dXJuIChNZXNzYWdlKXA7CisJICAgIEJvZHlQYXJ0IGJwID0gKEJvZHlQYXJ0KXA7CisJICAgIE11bHRpcGFydCBtcCA9IGJwLmdldFBhcmVudCgpOworCSAgICBpZiAobXAgPT0gbnVsbCkJLy8gTWltZUJvZHlQYXJ0IG1pZ2h0IG5vdCBiZSBpbiBhIE1pbWVNdWx0aXBhcnQKKwkJcmV0dXJuIG51bGw7CisJICAgIHAgPSBtcC5nZXRQYXJlbnQoKTsKKwl9CisJcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBTZXNzaW9uIHdlJ3JlIG9wZXJhdGluZyBpbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIFNlc3Npb24sIG9yIG51bGwgaWYgbm90IGtub3duCisgICAgICovCisgICAgcHVibGljIFNlc3Npb24gZ2V0U2Vzc2lvbigpIHsKKwlNZXNzYWdlIG1zZyA9IGdldE1lc3NhZ2UoKTsKKwlyZXR1cm4gbXNnICE9IG51bGwgPyBtc2cuZ2V0U2Vzc2lvbigpIDogbnVsbDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9NZXNzYWdlUmVtb3ZlZEV4Y2VwdGlvbi5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvTWVzc2FnZVJlbW92ZWRFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yOGNkZTY4Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvTWVzc2FnZVJlbW92ZWRFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDYyIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGphdmF4Lm1haWw7CisKKy8qKgorICogVGhlIGV4Y2VwdGlvbiB0aHJvd24gd2hlbiBhbiBpbnZhbGlkIG1ldGhvZCBpcyBpbnZva2VkIG9uIGFuIGV4cHVuZ2VkCisgKiBNZXNzYWdlLiBUaGUgb25seSB2YWxpZCBtZXRob2RzIG9uIGFuIGV4cHVuZ2VkIE1lc3NhZ2UgYXJlCisgKiA8Y29kZT5pc0V4cHVuZ2VkKCk8L2NvZGU+IGFuZCA8Y29kZT5nZXRNZXNzYWdlTnVtYmVyKCk8L2NvZGU+LgorICoKKyAqIEBzZWUJICAgamF2YXgubWFpbC5NZXNzYWdlI2lzRXhwdW5nZWQoKQorICogQHNlZQkgICBqYXZheC5tYWlsLk1lc3NhZ2UjZ2V0TWVzc2FnZU51bWJlcigpCisgKiBAYXV0aG9yIEpvaG4gTWFuaQorICovCisKK3B1YmxpYyBjbGFzcyBNZXNzYWdlUmVtb3ZlZEV4Y2VwdGlvbiBleHRlbmRzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxOTUxMjkyNTUwNjc5NTI4NjkwTDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBNZXNzYWdlUmVtb3ZlZEV4Y2VwdGlvbiB3aXRoIG5vIGRldGFpbCBtZXNzYWdlLgorICAgICAqLworICAgIHB1YmxpYyBNZXNzYWdlUmVtb3ZlZEV4Y2VwdGlvbigpIHsKKwlzdXBlcigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBNZXNzYWdlUmVtb3ZlZEV4Y2VwdGlvbiB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzCQlUaGUgZGV0YWlsZWQgZXJyb3IgbWVzc2FnZQorICAgICAqLworICAgIHB1YmxpYyBNZXNzYWdlUmVtb3ZlZEV4Y2VwdGlvbihTdHJpbmcgcykgeworCXN1cGVyKHMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBNZXNzYWdlUmVtb3ZlZEV4Y2VwdGlvbiB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBkZXRhaWwgbWVzc2FnZSBhbmQgZW1iZWRkZWQgZXhjZXB0aW9uLiAgVGhlIGV4Y2VwdGlvbiBpcyBjaGFpbmVkCisgICAgICogdG8gdGhpcyBleGNlcHRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcwkJVGhlIGRldGFpbGVkIGVycm9yIG1lc3NhZ2UKKyAgICAgKiBAcGFyYW0gZQkJVGhlIGVtYmVkZGVkIGV4Y2VwdGlvbgorICAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS41CisgICAgICovCisgICAgcHVibGljIE1lc3NhZ2VSZW1vdmVkRXhjZXB0aW9uKFN0cmluZyBzLCBFeGNlcHRpb24gZSkgeworCXN1cGVyKHMsIGUpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL01lc3NhZ2luZ0V4Y2VwdGlvbi5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvTWVzc2FnaW5nRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODAzYTRhZgotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL01lc3NhZ2luZ0V4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsMTUyIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGphdmF4Lm1haWw7CisKK2ltcG9ydCBqYXZhLmxhbmcuKjsKKworLyoqCisgKiBUaGUgYmFzZSBjbGFzcyBmb3IgYWxsIGV4Y2VwdGlvbnMgdGhyb3duIGJ5IHRoZSBNZXNzYWdpbmcgY2xhc3NlcworICoKKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCisKK3B1YmxpYyBjbGFzcyBNZXNzYWdpbmdFeGNlcHRpb24gZXh0ZW5kcyBFeGNlcHRpb24geworCisgICAgLyoqCisgICAgICogVGhlIG5leHQgZXhjZXB0aW9uIGluIHRoZSBjaGFpbi4KKyAgICAgKgorICAgICAqIEBzZXJpYWwKKyAgICAgKi8KKyAgICBwcml2YXRlIEV4Y2VwdGlvbiBuZXh0OworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTc1NjkxOTIyODk4MTk5NTkyNTNMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIE1lc3NhZ2luZ0V4Y2VwdGlvbiB3aXRoIG5vIGRldGFpbCBtZXNzYWdlLgorICAgICAqLworICAgIHB1YmxpYyBNZXNzYWdpbmdFeGNlcHRpb24oKSB7CisJc3VwZXIoKTsKKwlpbml0Q2F1c2UobnVsbCk7CS8vIHByZXZlbnQgYW55b25lIGVsc2UgZnJvbSBzZXR0aW5nIGl0CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIE1lc3NhZ2luZ0V4Y2VwdGlvbiB3aXRoIHRoZSBzcGVjaWZpZWQgZGV0YWlsIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcwkJdGhlIGRldGFpbCBtZXNzYWdlCisgICAgICovCisgICAgcHVibGljIE1lc3NhZ2luZ0V4Y2VwdGlvbihTdHJpbmcgcykgeworCXN1cGVyKHMpOworCWluaXRDYXVzZShudWxsKTsJLy8gcHJldmVudCBhbnlvbmUgZWxzZSBmcm9tIHNldHRpbmcgaXQKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgTWVzc2FnaW5nRXhjZXB0aW9uIHdpdGggdGhlIHNwZWNpZmllZCAKKyAgICAgKiBFeGNlcHRpb24gYW5kIGRldGFpbCBtZXNzYWdlLiBUaGUgc3BlY2lmaWVkIGV4Y2VwdGlvbiBpcyBjaGFpbmVkCisgICAgICogdG8gdGhpcyBleGNlcHRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gcwkJdGhlIGRldGFpbCBtZXNzYWdlCisgICAgICogQHBhcmFtIGUJCXRoZSBlbWJlZGRlZCBleGNlcHRpb24KKyAgICAgKiBAc2VlCSNnZXROZXh0RXhjZXB0aW9uCisgICAgICogQHNlZQkjc2V0TmV4dEV4Y2VwdGlvbgorICAgICAqIEBzZWUJI2dldENhdXNlCisgICAgICovCisgICAgcHVibGljIE1lc3NhZ2luZ0V4Y2VwdGlvbihTdHJpbmcgcywgRXhjZXB0aW9uIGUpIHsKKwlzdXBlcihzKTsKKwluZXh0ID0gZTsKKwlpbml0Q2F1c2UobnVsbCk7CS8vIHByZXZlbnQgYW55b25lIGVsc2UgZnJvbSBzZXR0aW5nIGl0CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBuZXh0IGV4Y2VwdGlvbiBjaGFpbmVkIHRvIHRoaXMgb25lLiBJZiB0aGUKKyAgICAgKiBuZXh0IGV4Y2VwdGlvbiBpcyBhIE1lc3NhZ2luZ0V4Y2VwdGlvbiwgdGhlIGNoYWluCisgICAgICogbWF5IGV4dGVuZCBmdXJ0aGVyLgorICAgICAqCisgICAgICogQHJldHVybgluZXh0IEV4Y2VwdGlvbiwgbnVsbCBpZiBub25lLgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgRXhjZXB0aW9uIGdldE5leHRFeGNlcHRpb24oKSB7CisJcmV0dXJuIG5leHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogT3ZlcnJpZGVzIHRoZSA8Y29kZT5nZXRDYXVzZTwvY29kZT4gbWV0aG9kIG9mIDxjb2RlPlRocm93YWJsZTwvY29kZT4KKyAgICAgKiB0byByZXR1cm4gdGhlIG5leHQgZXhjZXB0aW9uIGluIHRoZSBjaGFpbiBvZiBuZXN0ZWQgZXhjZXB0aW9ucy4KKyAgICAgKgorICAgICAqIEByZXR1cm4JbmV4dCBFeGNlcHRpb24sIG51bGwgaWYgbm9uZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIFRocm93YWJsZSBnZXRDYXVzZSgpIHsKKwlyZXR1cm4gbmV4dDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGQgYW4gZXhjZXB0aW9uIHRvIHRoZSBlbmQgb2YgdGhlIGNoYWluLiBJZiB0aGUgZW5kCisgICAgICogaXMgPHN0cm9uZz5ub3Q8L3N0cm9uZz4gYSBNZXNzYWdpbmdFeGNlcHRpb24sIHRoaXMgCisgICAgICogZXhjZXB0aW9uIGNhbm5vdCBiZSBhZGRlZCB0byB0aGUgZW5kLgorICAgICAqCisgICAgICogQHBhcmFtCWV4CXRoZSBuZXcgZW5kIG9mIHRoZSBFeGNlcHRpb24gY2hhaW4KKyAgICAgKiBAcmV0dXJuCQk8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGlzIEV4Y2VwdGlvbgorICAgICAqCQkJd2FzIGFkZGVkLCA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgYm9vbGVhbiBzZXROZXh0RXhjZXB0aW9uKEV4Y2VwdGlvbiBleCkgeworCUV4Y2VwdGlvbiB0aGVFbmQgPSB0aGlzOworCXdoaWxlICh0aGVFbmQgaW5zdGFuY2VvZiBNZXNzYWdpbmdFeGNlcHRpb24gJiYKKwkgICAgICAgKChNZXNzYWdpbmdFeGNlcHRpb24pdGhlRW5kKS5uZXh0ICE9IG51bGwpIHsKKwkgICAgdGhlRW5kID0gKChNZXNzYWdpbmdFeGNlcHRpb24pdGhlRW5kKS5uZXh0OworCX0KKwkvLyBJZiB0aGUgZW5kIGlzIGEgTWVzc2FnaW5nRXhjZXB0aW9uLCB3ZSBjYW4gYWRkIHRoaXMgCisJLy8gZXhjZXB0aW9uIHRvIHRoZSBjaGFpbi4KKwlpZiAodGhlRW5kIGluc3RhbmNlb2YgTWVzc2FnaW5nRXhjZXB0aW9uKSB7CisJICAgICgoTWVzc2FnaW5nRXhjZXB0aW9uKXRoZUVuZCkubmV4dCA9IGV4OworCSAgICByZXR1cm4gdHJ1ZTsKKwl9IGVsc2UKKwkgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIE92ZXJyaWRlIHRvU3RyaW5nIG1ldGhvZCB0byBwcm92aWRlIGluZm9ybWF0aW9uIG9uCisgICAgICogbmVzdGVkIGV4Y2VwdGlvbnMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBTdHJpbmcgdG9TdHJpbmcoKSB7CisJU3RyaW5nIHMgPSBzdXBlci50b1N0cmluZygpOworCUV4Y2VwdGlvbiBuID0gbmV4dDsKKwlpZiAobiA9PSBudWxsKQorCSAgICByZXR1cm4gczsKKwlTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIocyA9PSBudWxsID8gIiIgOiBzKTsKKwl3aGlsZSAobiAhPSBudWxsKSB7CisJICAgIHNiLmFwcGVuZCgiO1xuICBuZXN0ZWQgZXhjZXB0aW9uIGlzOlxuXHQiKTsKKwkgICAgaWYgKG4gaW5zdGFuY2VvZiBNZXNzYWdpbmdFeGNlcHRpb24pIHsKKwkJTWVzc2FnaW5nRXhjZXB0aW9uIG1leCA9IChNZXNzYWdpbmdFeGNlcHRpb24pbjsKKwkJc2IuYXBwZW5kKG1leC5zdXBlclRvU3RyaW5nKCkpOworCQluID0gbWV4Lm5leHQ7CisJICAgIH0gZWxzZSB7CisJCXNiLmFwcGVuZChuLnRvU3RyaW5nKCkpOworCQluID0gbnVsbDsKKwkgICAgfQorCX0KKwlyZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlICJ0b1N0cmluZyIgaW5mb3JtYXRpb24gZm9yIHRoaXMgZXhjZXB0aW9uLAorICAgICAqIHdpdGhvdXQgYW55IGluZm9ybWF0aW9uIG9uIG5lc3RlZCBleGNlcHRpb25zLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIHN1cGVyVG9TdHJpbmcoKSB7CisJcmV0dXJuIHN1cGVyLnRvU3RyaW5nKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvTWV0aG9kTm90U3VwcG9ydGVkRXhjZXB0aW9uLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9NZXRob2ROb3RTdXBwb3J0ZWRFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZjcyODlmCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvTWV0aG9kTm90U3VwcG9ydGVkRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw2MCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsOworCisKKy8qKgorICogVGhlIGV4Y2VwdGlvbiB0aHJvd24gd2hlbiBhIG1ldGhvZCBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoZSAKKyAqIGltcGxlbWVudGF0aW9uCisgKgorICogQGF1dGhvciBKb2huIE1hbmkKKyAqLworCitwdWJsaWMgY2xhc3MgTWV0aG9kTm90U3VwcG9ydGVkRXhjZXB0aW9uIGV4dGVuZHMgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0zNzU3Mzg2NjE4NzI2MTMxMzIyTDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBNZXRob2ROb3RTdXBwb3J0ZWRFeGNlcHRpb24gd2l0aCBubyBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTWV0aG9kTm90U3VwcG9ydGVkRXhjZXB0aW9uKCkgeworCXN1cGVyKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIE1ldGhvZE5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzCQlUaGUgZGV0YWlsZWQgZXJyb3IgbWVzc2FnZQorICAgICAqLworICAgIHB1YmxpYyBNZXRob2ROb3RTdXBwb3J0ZWRFeGNlcHRpb24oU3RyaW5nIHMpIHsKKwlzdXBlcihzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgTWV0aG9kTm90U3VwcG9ydGVkRXhjZXB0aW9uIHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIGRldGFpbCBtZXNzYWdlIGFuZCBlbWJlZGRlZCBleGNlcHRpb24uICBUaGUgZXhjZXB0aW9uIGlzIGNoYWluZWQKKyAgICAgKiB0byB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzCQlUaGUgZGV0YWlsZWQgZXJyb3IgbWVzc2FnZQorICAgICAqIEBwYXJhbSBlCQlUaGUgZW1iZWRkZWQgZXhjZXB0aW9uCisgICAgICogQHNpbmNlCQlKYXZhTWFpbCAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgTWV0aG9kTm90U3VwcG9ydGVkRXhjZXB0aW9uKFN0cmluZyBzLCBFeGNlcHRpb24gZSkgeworCXN1cGVyKHMsIGUpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL011bHRpcGFydC5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvTXVsdGlwYXJ0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDFiY2MyNwotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL011bHRpcGFydC5qYXZhCkBAIC0wLDAgKzEsMjYwIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGphdmF4Lm1haWw7CisKK2ltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5hY3RpdmF0aW9uLkRhdGFTb3VyY2U7CisKKy8qKgorICogTXVsdGlwYXJ0IGlzIGEgY29udGFpbmVyIHRoYXQgaG9sZHMgbXVsdGlwbGUgYm9keSBwYXJ0cy4gTXVsdGlwYXJ0CisgKiBwcm92aWRlcyBtZXRob2RzIHRvIHJldHJpZXZlIGFuZCBzZXQgaXRzIHN1YnBhcnRzLiA8cD4KKyAqIAorICogTXVsdGlwYXJ0IGFsc28gYWN0cyBhcyB0aGUgYmFzZSBjbGFzcyBmb3IgdGhlIGNvbnRlbnQgb2JqZWN0IHJldHVybmVkIAorICogYnkgbW9zdCBNdWx0aXBhcnQgRGF0YUNvbnRlbnRIYW5kbGVycy4gRm9yIGV4YW1wbGUsIGludm9raW5nIGdldENvbnRlbnQoKQorICogb24gYSBEYXRhSGFuZGxlciB3aG9zZSBzb3VyY2UgaXMgYSAibXVsdGlwYXJ0L3NpZ25lZCIgZGF0YSBzb3VyY2UgbWF5CisgKiByZXR1cm4gYW4gYXBwcm9wcmlhdGUgc3ViY2xhc3Mgb2YgTXVsdGlwYXJ0LiA8cD4KKyAqCisgKiBTb21lIG1lc3NhZ2luZyBzeXN0ZW1zIHByb3ZpZGUgZGlmZmVyZW50IHN1YnR5cGVzIG9mIE11bHRpcGFydHMuIEZvcgorICogZXhhbXBsZSwgTUlNRSBzcGVjaWZpZXMgYSBzZXQgb2Ygc3VidHlwZXMgdGhhdCBpbmNsdWRlICJhbHRlcm5hdGl2ZSIsIAorICogIm1peGVkIiwgInJlbGF0ZWQiLCAicGFyYWxsZWwiLCAic2lnbmVkIiwgZXRjLiA8cD4KKyAqCisgKiBNdWx0aXBhcnQgaXMgYW4gYWJzdHJhY3QgY2xhc3MuICBTdWJjbGFzc2VzIHByb3ZpZGUgYWN0dWFsIGltcGxlbWVudGF0aW9ucy4KKyAqCisgKiBAYXV0aG9yIEpvaG4gTWFuaQorICovCisKK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBNdWx0aXBhcnQgeworCisgICAgLyoqCisgICAgICogVmVjdG9yIG9mIEJvZHlQYXJ0IG9iamVjdHMuCisgICAgICovCisgICAgcHJvdGVjdGVkIFZlY3RvcjxCb2R5UGFydD4gcGFydHMgPSBuZXcgVmVjdG9yPD4oKTsgLy8gSG9sZHMgQm9keVBhcnRzCisKKyAgICAvKioKKyAgICAgKiBUaGlzIGZpZWxkIHNwZWNpZmllcyB0aGUgY29udGVudC10eXBlIG9mIHRoaXMgbXVsdGlwYXJ0CisgICAgICogb2JqZWN0LiBJdCBkZWZhdWx0cyB0byAibXVsdGlwYXJ0L21peGVkIi4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU3RyaW5nIGNvbnRlbnRUeXBlID0gIm11bHRpcGFydC9taXhlZCI7IC8vIENvbnRlbnQtVHlwZQorCisgICAgLyoqCisgICAgICogVGhlIDxjb2RlPlBhcnQ8L2NvZGU+IGNvbnRhaW5pbmcgdGhpcyA8Y29kZT5NdWx0aXBhcnQ8L2NvZGU+LAorICAgICAqIGlmIGtub3duLgorICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjEKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgUGFydCBwYXJlbnQ7CisKKyAgICAvKiogCisgICAgICogRGVmYXVsdCBjb25zdHJ1Y3Rvci4gQW4gZW1wdHkgTXVsdGlwYXJ0IG9iamVjdCBpcyBjcmVhdGVkLgorICAgICAqLworICAgIHByb3RlY3RlZCBNdWx0aXBhcnQoKSB7IH0KKworICAgIC8qKgorICAgICAqIFNldHVwIHRoaXMgTXVsdGlwYXJ0IG9iamVjdCBmcm9tIHRoZSBnaXZlbiBNdWx0aXBhcnREYXRhU291cmNlLiA8cD4KKyAgICAgKgorICAgICAqIFRoZSBtZXRob2QgYWRkcyB0aGUgTXVsdGlwYXJ0RGF0YVNvdXJjZSdzIEJvZHlQYXJ0IAorICAgICAqIG9iamVjdHMgaW50byB0aGlzIE11bHRpcGFydC4gVGhpcyBNdWx0aXBhcnQncyBjb250ZW50VHlwZSBpcworICAgICAqIHNldCB0byB0aGF0IG9mIHRoZSBNdWx0aXBhcnREYXRhU291cmNlLiA8cD4KKyAgICAgKgorICAgICAqIFRoaXMgbWV0aG9kIGlzIHR5cGljYWxseSB1c2VkIGluIHRob3NlIGNhc2VzIHdoZXJlIG9uZSAKKyAgICAgKiBoYXMgYSBtdWx0aXBhcnQgZGF0YSBzb3VyY2UgdGhhdCBoYXMgYWxyZWFkeSBiZWVuIHByZS1wYXJzZWQgaW50bworICAgICAqIHRoZSBpbmRpdmlkdWFsIGJvZHkgcGFydHMgKGZvciBleGFtcGxlLCBhbiBJTUFQIGRhdGFzb3VyY2UpLCBidXQgCisgICAgICogbmVlZHMgdG8gY3JlYXRlIGFuIGFwcHJvcHJpYXRlIE11bHRpcGFydCBzdWJjbGFzcyB0aGF0IHJlcHJlc2VudHMKKyAgICAgKiBhIHNwZWNpZmljIG11bHRpcGFydCBzdWJ0eXBlLiAKKyAgICAgKiAKKyAgICAgKiBAcGFyYW0JbXAJTXVsdGlwYXJ0IGRhdGFzb3VyY2UKKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIE1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3luY2hyb25pemVkIHZvaWQgc2V0TXVsdGlwYXJ0RGF0YVNvdXJjZShNdWx0aXBhcnREYXRhU291cmNlIG1wKQorCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJY29udGVudFR5cGUgPSBtcC5nZXRDb250ZW50VHlwZSgpOworCisJaW50IGNvdW50ID0gbXAuZ2V0Q291bnQoKTsKKwlmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspCisJICAgIGFkZEJvZHlQYXJ0KG1wLmdldEJvZHlQYXJ0KGkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIGNvbnRlbnQtdHlwZSBvZiB0aGlzIE11bHRpcGFydC4gPHA+CisgICAgICoKKyAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIGp1c3QgcmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlCisgICAgICogPGNvZGU+Y29udGVudFR5cGU8L2NvZGU+IGZpZWxkLgorICAgICAqCisgICAgICogQHJldHVybiAJY29udGVudC10eXBlCisgICAgICogQHNlZQkjY29udGVudFR5cGUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIFN0cmluZyBnZXRDb250ZW50VHlwZSgpIHsKKwlyZXR1cm4gY29udGVudFR5cGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBudW1iZXIgb2YgZW5jbG9zZWQgQm9keVBhcnQgb2JqZWN0cy4gPHA+CisgICAgICoKKyAgICAgKiBAcmV0dXJuCQludW1iZXIgb2YgcGFydHMKKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIE1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKiBAc2VlCQkjcGFydHMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCBnZXRDb3VudCgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWlmIChwYXJ0cyA9PSBudWxsKQorCSAgICByZXR1cm4gMDsKKworCXJldHVybiBwYXJ0cy5zaXplKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBzcGVjaWZpZWQgUGFydC4gIFBhcnRzIGFyZSBudW1iZXJlZCBzdGFydGluZyBhdCAwLgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4CXRoZSBpbmRleCBvZiB0aGUgZGVzaXJlZCBQYXJ0CisgICAgICogQHJldHVybgkJdGhlIFBhcnQKKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWYgdGhlIGdpdmVuIGluZGV4CisgICAgICoJCQlpcyBvdXQgb2YgcmFuZ2UuCisgICAgICogQGV4Y2VwdGlvbiAgICAgICBNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBCb2R5UGFydCBnZXRCb2R5UGFydChpbnQgaW5kZXgpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKHBhcnRzID09IG51bGwpCisJICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCJObyBzdWNoIEJvZHlQYXJ0Iik7CisKKwlyZXR1cm4gcGFydHMuZWxlbWVudEF0KGluZGV4KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmUgdGhlIHNwZWNpZmllZCBwYXJ0IGZyb20gdGhlIG11bHRpcGFydCBtZXNzYWdlLgorICAgICAqIFNoaWZ0cyBhbGwgdGhlIHBhcnRzIGFmdGVyIHRoZSByZW1vdmVkIHBhcnQgZG93biBvbmUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gICBwYXJ0CVRoZSBwYXJ0IHRvIHJlbW92ZQorICAgICAqIEByZXR1cm4JCXRydWUgaWYgcGFydCByZW1vdmVkLCBmYWxzZSBvdGhlcndpc2UKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBpZiBubyBzdWNoIFBhcnQgZXhpc3RzCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsV3JpdGVFeGNlcHRpb24gaWYgdGhlIHVuZGVybHlpbmcKKyAgICAgKgkJCWltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uCisgICAgICoJCQlvZiBleGlzdGluZyB2YWx1ZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGJvb2xlYW4gcmVtb3ZlQm9keVBhcnQoQm9keVBhcnQgcGFydCkKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpZiAocGFydHMgPT0gbnVsbCkKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiTm8gc3VjaCBib2R5IHBhcnQiKTsKKworCWJvb2xlYW4gcmV0ID0gcGFydHMucmVtb3ZlRWxlbWVudChwYXJ0KTsKKwlwYXJ0LnNldFBhcmVudChudWxsKTsKKwlyZXR1cm4gcmV0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZSB0aGUgcGFydCBhdCBzcGVjaWZpZWQgbG9jYXRpb24gKHN0YXJ0aW5nIGZyb20gMCkuCisgICAgICogU2hpZnRzIGFsbCB0aGUgcGFydHMgYWZ0ZXIgdGhlIHJlbW92ZWQgcGFydCBkb3duIG9uZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSAgIGluZGV4CUluZGV4IG9mIHRoZSBwYXJ0IHRvIHJlbW92ZQorICAgICAqIEBleGNlcHRpb24gICAgICAgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiB0aGUgZ2l2ZW4gaW5kZXgKKyAgICAgKgkJCWlzIG91dCBvZiByYW5nZS4KKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxXcml0ZUV4Y2VwdGlvbiBpZiB0aGUgdW5kZXJseWluZworICAgICAqCQkJaW1wbGVtZW50YXRpb24gZG9lcyBub3Qgc3VwcG9ydCBtb2RpZmljYXRpb24KKyAgICAgKgkJCW9mIGV4aXN0aW5nIHZhbHVlcworICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBvdGhlciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCByZW1vdmVCb2R5UGFydChpbnQgaW5kZXgpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKHBhcnRzID09IG51bGwpCisJICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCJObyBzdWNoIEJvZHlQYXJ0Iik7CisKKwlCb2R5UGFydCBwYXJ0ID0gcGFydHMuZWxlbWVudEF0KGluZGV4KTsKKwlwYXJ0cy5yZW1vdmVFbGVtZW50QXQoaW5kZXgpOworCXBhcnQuc2V0UGFyZW50KG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgYSBQYXJ0IHRvIHRoZSBtdWx0aXBhcnQuICBUaGUgQm9keVBhcnQgaXMgYXBwZW5kZWQgdG8gCisgICAgICogdGhlIGxpc3Qgb2YgZXhpc3RpbmcgUGFydHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gIHBhcnQgIFRoZSBQYXJ0IHRvIGJlIGFwcGVuZGVkCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsV3JpdGVFeGNlcHRpb24gaWYgdGhlIHVuZGVybHlpbmcKKyAgICAgKgkJCWltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uCisgICAgICoJCQlvZiBleGlzdGluZyB2YWx1ZXMKKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIE1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgYWRkQm9keVBhcnQoQm9keVBhcnQgcGFydCkgCisJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWlmIChwYXJ0cyA9PSBudWxsKQorCSAgICBwYXJ0cyA9IG5ldyBWZWN0b3I8PigpOworCisJcGFydHMuYWRkRWxlbWVudChwYXJ0KTsKKwlwYXJ0LnNldFBhcmVudCh0aGlzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIGEgQm9keVBhcnQgYXQgcG9zaXRpb24gPGNvZGU+aW5kZXg8L2NvZGU+LgorICAgICAqIElmIDxjb2RlPmluZGV4PC9jb2RlPiBpcyBub3QgdGhlIGxhc3Qgb25lIGluIHRoZSBsaXN0LAorICAgICAqIHRoZSBzdWJzZXF1ZW50IHBhcnRzIGFyZSBzaGlmdGVkIHVwLiBJZiA8Y29kZT5pbmRleDwvY29kZT4KKyAgICAgKiBpcyBsYXJnZXIgdGhhbiB0aGUgbnVtYmVyIG9mIHBhcnRzIHByZXNlbnQsIHRoZQorICAgICAqIEJvZHlQYXJ0IGlzIGFwcGVuZGVkIHRvIHRoZSBlbmQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gIHBhcnQgIFRoZSBCb2R5UGFydCB0byBiZSBpbnNlcnRlZAorICAgICAqIEBwYXJhbSAgaW5kZXggTG9jYXRpb24gd2hlcmUgdG8gaW5zZXJ0IHRoZSBwYXJ0CisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsV3JpdGVFeGNlcHRpb24gaWYgdGhlIHVuZGVybHlpbmcKKyAgICAgKgkJCWltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uCisgICAgICoJCQlvZiBleGlzdGluZyB2YWx1ZXMKKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIE1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgYWRkQm9keVBhcnQoQm9keVBhcnQgcGFydCwgaW50IGluZGV4KSAKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpZiAocGFydHMgPT0gbnVsbCkKKwkgICAgcGFydHMgPSBuZXcgVmVjdG9yPD4oKTsKKworCXBhcnRzLmluc2VydEVsZW1lbnRBdChwYXJ0LCBpbmRleCk7CisJcGFydC5zZXRQYXJlbnQodGhpcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogT3V0cHV0IGFuIGFwcHJvcHJpYXRlbHkgZW5jb2RlZCBieXRlc3RyZWFtIHRvIHRoZSBnaXZlbgorICAgICAqIE91dHB1dFN0cmVhbS4gVGhlIGltcGxlbWVudGF0aW9uIHN1YmNsYXNzIGRlY2lkZXMgdGhlCisgICAgICogYXBwcm9wcmlhdGUgZW5jb2RpbmcgYWxnb3JpdGhtIHRvIGJlIHVzZWQuIFRoZSBieXRlc3RyZWFtCisgICAgICogaXMgdHlwaWNhbGx5IHVzZWQgZm9yIHNlbmRpbmcuCisgICAgICogCisgICAgICogQHBhcmFtCW9zCXRoZSBzdHJlYW0gdG8gd3JpdGUgdG8KKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIElPRXhjZXB0aW9uIGlmIGFuIElPIHJlbGF0ZWQgZXhjZXB0aW9uIG9jY3VycworICAgICAqIEBleGNlcHRpb24gICAgICAgTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBvdGhlciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHdyaXRlVG8oT3V0cHV0U3RyZWFtIG9zKSAKKwkJdGhyb3dzIElPRXhjZXB0aW9uLCBNZXNzYWdpbmdFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIDxjb2RlPlBhcnQ8L2NvZGU+IHRoYXQgY29udGFpbnMgdGhpcyA8Y29kZT5NdWx0aXBhcnQ8L2NvZGU+CisgICAgICogb2JqZWN0LCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBub3Qga25vd24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBwYXJlbnQgUGFydAorICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjEKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIFBhcnQgZ2V0UGFyZW50KCkgeworCXJldHVybiBwYXJlbnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBwYXJlbnQgb2YgdGhpcyA8Y29kZT5NdWx0aXBhcnQ8L2NvZGU+IHRvIGJlIHRoZSBzcGVjaWZpZWQKKyAgICAgKiA8Y29kZT5QYXJ0PC9jb2RlPi4gIE5vcm1hbGx5IGNhbGxlZCBieSB0aGUgPGNvZGU+TWVzc2FnZTwvY29kZT4KKyAgICAgKiBvciA8Y29kZT5Cb2R5UGFydDwvY29kZT4gPGNvZGU+c2V0Q29udGVudChNdWx0aXBhcnQpPC9jb2RlPiBtZXRob2QuCisgICAgICogPGNvZGU+cGFyZW50PC9jb2RlPiBtYXkgYmUgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlCisgICAgICogPGNvZGU+TXVsdGlwYXJ0PC9jb2RlPiBpcyBiZWluZyByZW1vdmVkIGZyb20gaXRzIGNvbnRhaW5pbmcKKyAgICAgKiA8Y29kZT5QYXJ0PC9jb2RlPi4KKyAgICAgKgorICAgICAqIEBwYXJhbQlwYXJlbnQJdGhlIHBhcmVudCBQYXJ0CisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuMQorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXRQYXJlbnQoUGFydCBwYXJlbnQpIHsKKwl0aGlzLnBhcmVudCA9IHBhcmVudDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9NdWx0aXBhcnREYXRhU291cmNlLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9NdWx0aXBhcnREYXRhU291cmNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGQ2ODM2MwotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL011bHRpcGFydERhdGFTb3VyY2UuamF2YQpAQCAtMCwwICsxLDU4IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGphdmF4Lm1haWw7CisKK2ltcG9ydCBqYXZheC5hY3RpdmF0aW9uLkRhdGFTb3VyY2U7CisKKy8qKgorICogTXVsdGlwYXJ0RGF0YVNvdXJjZSBpcyBhIDxjb2RlPkRhdGFTb3VyY2U8L2NvZGU+IHRoYXQgY29udGFpbnMgYm9keQorICogcGFydHMuICBUaGlzIGFsbG93cyAibWFpbCBhd2FyZSIgPGNvZGU+RGF0YUNvbnRlbnRIYW5kbGVyczwvY29kZT4gdG8KKyAqIGJlIGltcGxlbWVudGVkIG1vcmUgZWZmaWNpZW50bHkgYnkgYmVpbmcgYXdhcmUgb2Ygc3VjaAorICogPGNvZGU+RGF0YVNvdXJjZXM8L2NvZGU+IGFuZCB1c2luZyB0aGUgYXBwcm9wcmlhdGUgbWV0aG9kcyB0byBhY2Nlc3MKKyAqIDxjb2RlPkJvZHlQYXJ0czwvY29kZT4uIDxwPgorICoKKyAqIE5vdGUgdGhhdCB0aGUgZGF0YSBvZiBhIE11bHRpcGFydERhdGFTb3VyY2UgaXMgYWxzbyBhdmFpbGFibGUgYXMKKyAqIGFuIGlucHV0IHN0cmVhbS4gPHA+CisgKgorICogVGhpcyBpbnRlcmZhY2Ugd2lsbCB0eXBpY2FsbHkgYmUgaW1wbGVtZW50ZWQgYnkgcHJvdmlkZXJzIHRoYXQKKyAqIHByZXBhcnNlIG11bHRpcGFydCBib2RpZXMsIGZvciBleGFtcGxlIGFuIElNQVAgcHJvdmlkZXIuCisgKgorICogQGF1dGhvcglKb2huIE1hbmkKKyAqIEBzZWUJCWphdmF4LmFjdGl2YXRpb24uRGF0YVNvdXJjZQorICovCisKK3B1YmxpYyBpbnRlcmZhY2UgTXVsdGlwYXJ0RGF0YVNvdXJjZSBleHRlbmRzIERhdGFTb3VyY2UgeworCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBudW1iZXIgb2YgZW5jbG9zZWQgQm9keVBhcnQgb2JqZWN0cy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gICAgICAgICAgbnVtYmVyIG9mIHBhcnRzCisgICAgICovCisgICAgcHVibGljIGludCBnZXRDb3VudCgpOworCisgICAgLyoqCisgICAgICogR2V0IHRoZSBzcGVjaWZpZWQgUGFydC4gIFBhcnRzIGFyZSBudW1iZXJlZCBzdGFydGluZyBhdCAwLgorICAgICAqCisgICAgICogQHBhcmFtIGluZGV4ICAgICB0aGUgaW5kZXggb2YgdGhlIGRlc2lyZWQgUGFydAorICAgICAqIEByZXR1cm4gICAgICAgICAgdGhlIFBhcnQKKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWYgdGhlIGdpdmVuIGluZGV4CisgICAgICoJCQlpcyBvdXQgb2YgcmFuZ2UuCisgICAgICogQGV4Y2VwdGlvbiAgICAgICBNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIEJvZHlQYXJ0IGdldEJvZHlQYXJ0KGludCBpbmRleCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24uamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL05vU3VjaFByb3ZpZGVyRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjk0NTI3ZAotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL05vU3VjaFByb3ZpZGVyRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw1OSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsOworCisvKioKKyAqIFRoaXMgZXhjZXB0aW9uIGlzIHRocm93biB3aGVuIFNlc3Npb24gYXR0ZW1wdHMgdG8gaW5zdGFudGlhdGUgYSAgCisgKiBQcm92aWRlciB0aGF0IGRvZXNuJ3QgZXhpc3QuCisgKiAKKyAqIEBhdXRob3IgTWF4IFNwaXZhaworICovCisKK3B1YmxpYyBjbGFzcyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiBleHRlbmRzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA4MDU4MzE5MjkzMTU0NzA4ODI3TDsKKyAgICAKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gd2l0aCBubyBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24oKSB7CisJc3VwZXIoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogZGV0YWlsIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWVzc2FnZQlUaGUgZGV0YWlsZWQgZXJyb3IgbWVzc2FnZQorICAgICAqLworICAgIHB1YmxpYyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSkgeworCXN1cGVyKG1lc3NhZ2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBkZXRhaWwgbWVzc2FnZSBhbmQgZW1iZWRkZWQgZXhjZXB0aW9uLiAgVGhlIGV4Y2VwdGlvbiBpcyBjaGFpbmVkCisgICAgICogdG8gdGhpcyBleGNlcHRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0gbWVzc2FnZQlUaGUgZGV0YWlsZWQgZXJyb3IgbWVzc2FnZQorICAgICAqIEBwYXJhbSBlCQlUaGUgZW1iZWRkZWQgZXhjZXB0aW9uCisgICAgICogQHNpbmNlCQlKYXZhTWFpbCAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UsIEV4Y2VwdGlvbiBlKSB7CisJc3VwZXIobWVzc2FnZSwgZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvUGFydC5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvUGFydC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM4ZTVmZTMKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9QYXJ0LmphdmEKQEAgLTAsMCArMSw0NTEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbDsKKworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247CitpbXBvcnQgamF2YXguYWN0aXZhdGlvbi5EYXRhSGFuZGxlcjsKKworLyoqCisgKiBUaGUgPGNvZGU+UGFydDwvY29kZT4gaW50ZXJmYWNlIGlzIHRoZSBjb21tb24gYmFzZSBpbnRlcmZhY2UgZm9yIAorICogTWVzc2FnZXMgYW5kIEJvZHlQYXJ0cy4gPHA+CisgKgorICogUGFydCBjb25zaXN0cyBvZiBhIHNldCBvZiBhdHRyaWJ1dGVzIGFuZCBhICJDb250ZW50Ii48cD4KKyAqCisgKiA8c3Ryb25nPiBBdHRyaWJ1dGVzOiA8L3N0cm9uZz4gPHA+CisgKgorICogVGhlIEphdmFNYWlsIEFQSSBkZWZpbmVzIGEgc2V0IG9mIHN0YW5kYXJkIFBhcnQgYXR0cmlidXRlcyB0aGF0IGFyZQorICogY29uc2lkZXJlZCB0byBiZSBjb21tb24gdG8gbW9zdCBleGlzdGluZyBNYWlsIHN5c3RlbXMuIFRoZXNlCisgKiBhdHRyaWJ1dGVzIGhhdmUgdGhlaXIgb3duIHNldHRvciBhbmQgZ2V0dG9yIG1ldGhvZHMuIE1haWwgc3lzdGVtcyAKKyAqIG1heSBzdXBwb3J0IG90aGVyIFBhcnQgYXR0cmlidXRlcyBhcyB3ZWxsLCB0aGVzZSBhcmUgcmVwcmVzZW50ZWQgYXMgCisgKiBuYW1lLXZhbHVlIHBhaXJzIHdoZXJlIGJvdGggdGhlIG5hbWUgYW5kIHZhbHVlIGFyZSBTdHJpbmdzLjxwPgorICoKKyAqIDxzdHJvbmc+IENvbnRlbnQ6IDwvc3Ryb25nPiA8cD4KKyAqCisgKiBUaGUgPHN0cm9uZz5kYXRhIHR5cGU8L3N0cm9uZz4gb2YgdGhlICJjb250ZW50IiBpcyByZXR1cm5lZCBieQorICogdGhlIDxjb2RlPmdldENvbnRlbnRUeXBlKCk8L2NvZGU+IG1ldGhvZC4gVGhlIE1JTUUgdHlwaW5nIHN5c3RlbQorICogaXMgdXNlZCB0byBuYW1lIGRhdGEgdHlwZXMuIDxwPgorICoKKyAqIFRoZSAiY29udGVudCIgb2YgYSBQYXJ0IGlzIGF2YWlsYWJsZSBpbiB2YXJpb3VzIGZvcm1hdHM6CisgKiA8dWw+CisgKiA8bGk+IEFzIGEgRGF0YUhhbmRsZXIgLSB1c2luZyB0aGUgPGNvZGU+Z2V0RGF0YUhhbmRsZXIoKTwvY29kZT4gbWV0aG9kLgorICogVGhlICJjb250ZW50IiBvZiBhIFBhcnQgaXMgYWxzbyBhdmFpbGFibGUgdGhyb3VnaCBhIAorICogPGNvZGU+amF2YXguYWN0aXZhdGlvbi5EYXRhSGFuZGxlcjwvY29kZT4gb2JqZWN0LiBUaGUgRGF0YUhhbmRsZXIgCisgKiBvYmplY3QgYWxsb3dzIGNsaWVudHMgdG8gZGlzY292ZXIgdGhlIG9wZXJhdGlvbnMgYXZhaWxhYmxlIG9uIHRoZQorICogY29udGVudCwgYW5kIHRvIGluc3RhbnRpYXRlIHRoZSBhcHByb3ByaWF0ZSBjb21wb25lbnQgdG8gcGVyZm9ybQorICogdGhvc2Ugb3BlcmF0aW9ucy4gCisgKgorICogPGxpPiBBcyBhbiBpbnB1dCBzdHJlYW0gLSB1c2luZyB0aGUgPGNvZGU+Z2V0SW5wdXRTdHJlYW0oKTwvY29kZT4gbWV0aG9kLgorICogQW55IG1haWwtc3BlY2lmaWMgZW5jb2RpbmdzIGFyZSBkZWNvZGVkIGJlZm9yZSB0aGlzIHN0cmVhbSBpcyByZXR1cm5lZC4KKyAqCisgKiA8bGk+IEFzIGEgSmF2YSBvYmplY3QgLSB1c2luZyB0aGUgPGNvZGU+Z2V0Q29udGVudCgpPC9jb2RlPiBtZXRob2QuCisgKiBUaGlzIG1ldGhvZCByZXR1cm5zIHRoZSAiY29udGVudCIgYXMgYSBKYXZhIG9iamVjdC4KKyAqIFRoZSByZXR1cm5lZCBvYmplY3QgaXMgb2YgY291cnNlIGRlcGVuZGVudCBvbiB0aGUgY29udGVudAorICogaXRzZWxmLiBJbiBwYXJ0aWN1bGFyLCBhICJtdWx0aXBhcnQiIFBhcnQncyBjb250ZW50IGlzIGFsd2F5cyBhIAorICogTXVsdGlwYXJ0IG9yIHN1YmNsYXNzIHRoZXJlb2YuICBUaGF0IGlzLCA8Y29kZT5nZXRDb250ZW50KCk8L2NvZGU+IG9uIGEgCisgKiAibXVsdGlwYXJ0IiB0eXBlIFBhcnQgd2lsbCBhbHdheXMgcmV0dXJuIGEgTXVsdGlwYXJ0IChvciBzdWJjbGFzcykgb2JqZWN0LgorICogPC91bD4KKyAqCisgKiBQYXJ0IHByb3ZpZGVzIHRoZSA8Y29kZT53cml0ZVRvKCk8L2NvZGU+IG1ldGhvZCB0aGF0IHN0cmVhbXMKKyAqIG91dCBpdHMgYnl0ZXN0cmVhbSBpbiBtYWlsLXNhZmUgZm9ybSBzdWl0YWJsZSBmb3IgdHJhbnNtaXNzaW9uLiAKKyAqIFRoaXMgYnl0ZXN0cmVhbSBpcyB0eXBpY2FsbHkgYW4gYWdncmVnYXRpb24gb2YgdGhlIFBhcnQgYXR0cmlidXRlcworICogYW5kIGl0cyBjb250ZW50J3MgYnl0ZXN0cmVhbS4gPHA+CisgKgorICogTWVzc2FnZSBhbmQgQm9keVBhcnQgaW1wbGVtZW50IHRoZSBQYXJ0IGludGVyZmFjZS4gTm90ZSB0aGF0IGluCisgKiBNSU1FIHBhcmxhbmNlLCBQYXJ0IG1vZGVscyBhbiBFbnRpdHkgKFJGQyAyMDQ1LCBTZWN0aW9uIDIuNCkuCisgKgorICogQGF1dGhvciBKb2huIE1hbmkKKyAqLworCitwdWJsaWMgaW50ZXJmYWNlIFBhcnQgeworCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBzaXplIG9mIHRoZSBjb250ZW50IG9mIHRoaXMgcGFydCBpbiBieXRlcy4KKyAgICAgKiBSZXR1cm4gLTEgaWYgdGhlIHNpemUgY2Fubm90IGJlIGRldGVybWluZWQuIDxwPgorICAgICAqCisgICAgICogTm90ZSB0aGF0IHRoZSBzaXplIG1heSBub3QgYmUgYW4gZXhhY3QgbWVhc3VyZSBvZiB0aGUgY29udGVudAorICAgICAqIHNpemUgYW5kIG1heSBvciBtYXkgbm90IGFjY291bnQgZm9yIGFueSB0cmFuc2ZlciBlbmNvZGluZworICAgICAqIG9mIHRoZSBjb250ZW50LiBUaGUgc2l6ZSBpcyBhcHByb3ByaWF0ZSBmb3IgZGlzcGxheSBpbiBhIAorICAgICAqIHVzZXIgaW50ZXJmYWNlIHRvIGdpdmUgdGhlIHVzZXIgYSByb3VnaCBpZGVhIG9mIHRoZSBzaXplCisgICAgICogb2YgdGhpcyBwYXJ0LgorICAgICAqCisgICAgICogQHJldHVybgkJc2l6ZSBvZiBjb250ZW50IGluIGJ5dGVzCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIGludCBnZXRTaXplKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgbnVtYmVyIG9mIGxpbmVzIGluIHRoZSBjb250ZW50IG9mIHRoaXMgcGFydC4gCisgICAgICogUmV0dXJuIC0xIGlmIHRoZSBudW1iZXIgY2Fubm90IGJlIGRldGVybWluZWQuCisgICAgICoKKyAgICAgKiBOb3RlIHRoYXQgdGhpcyBudW1iZXIgbWF5IG5vdCBiZSBhbiBleGFjdCBtZWFzdXJlIG9mIHRoZSAKKyAgICAgKiBjb250ZW50IGxlbmd0aCBhbmQgbWF5IG9yIG1heSBub3QgYWNjb3VudCBmb3IgYW55IHRyYW5zZmVyIAorICAgICAqIGVuY29kaW5nIG9mIHRoZSBjb250ZW50LiAKKyAgICAgKgorICAgICAqIEByZXR1cm4JCW51bWJlciBvZiBsaW5lcyBpbiB0aGUgY29udGVudC4KKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldExpbmVDb3VudCgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBDb250ZW50LVR5cGUgb2YgdGhlIGNvbnRlbnQgb2YgdGhpcyBwYXJ0LgorICAgICAqIFJldHVybnMgbnVsbCBpZiB0aGUgQ29udGVudC1UeXBlIGNvdWxkIG5vdCBiZSBkZXRlcm1pbmVkLiA8cD4KKyAgICAgKgorICAgICAqIFRoZSBNSU1FIHR5cGluZyBzeXN0ZW0gaXMgdXNlZCB0byBuYW1lIENvbnRlbnQtdHlwZXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCQlUaGUgQ29udGVudFR5cGUgb2YgdGhpcyBwYXJ0CisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICogQHNlZQkJamF2YXguYWN0aXZhdGlvbi5EYXRhSGFuZGxlcgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q29udGVudFR5cGUoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogSXMgdGhpcyBQYXJ0IG9mIHRoZSBzcGVjaWZpZWQgTUlNRSB0eXBlPyAgVGhpcyBtZXRob2QKKyAgICAgKiBjb21wYXJlcyA8c3Ryb25nPm9ubHkgdGhlIDxjb2RlPnByaW1hcnlUeXBlPC9jb2RlPiBhbmQgCisgICAgICogPGNvZGU+c3ViVHlwZTwvY29kZT48L3N0cm9uZz4uCisgICAgICogVGhlIHBhcmFtZXRlcnMgb2YgdGhlIGNvbnRlbnQgdHlwZXMgYXJlIGlnbm9yZWQuIDxwPgorICAgICAqCisgICAgICogRm9yIGV4YW1wbGUsIHRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IHdoZW4KKyAgICAgKiBjb21wYXJpbmcgYSBQYXJ0IG9mIGNvbnRlbnQgdHlwZSA8c3Ryb25nPiJ0ZXh0L3BsYWluIjwvc3Ryb25nPgorICAgICAqIHdpdGggPHN0cm9uZz4idGV4dC9wbGFpbjsgY2hhcnNldD1mb29iYXIiPC9zdHJvbmc+LiA8cD4KKyAgICAgKgorICAgICAqIElmIHRoZSA8Y29kZT5zdWJUeXBlPC9jb2RlPiBvZiA8Y29kZT5taW1lVHlwZTwvY29kZT4gaXMgdGhlCisgICAgICogc3BlY2lhbCBjaGFyYWN0ZXIgJyonLCB0aGVuIHRoZSBzdWJ0eXBlIGlzIGlnbm9yZWQgZHVyaW5nIHRoZQorICAgICAqIGNvbXBhcmlzb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0JbWltZVR5cGUJdGhlIE1JTUUgdHlwZSB0byB0ZXN0CisgICAgICogQHJldHVybgl0cnVlIGlmIHRoaXMgcGFydCBpcyBvZiB0aGUgc3BlY2lmaWVkIHR5cGUKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc01pbWVUeXBlKFN0cmluZyBtaW1lVHlwZSkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFRoaXMgcGFydCBzaG91bGQgYmUgcHJlc2VudGVkIGFzIGFuIGF0dGFjaG1lbnQuCisgICAgICogQHNlZSAjZ2V0RGlzcG9zaXRpb24KKyAgICAgKiBAc2VlICNzZXREaXNwb3NpdGlvbgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVEFDSE1FTlQgPSAiYXR0YWNobWVudCI7CisKKyAgICAvKioKKyAgICAgKiBUaGlzIHBhcnQgc2hvdWxkIGJlIHByZXNlbnRlZCBpbmxpbmUuCisgICAgICogQHNlZSAjZ2V0RGlzcG9zaXRpb24KKyAgICAgKiBAc2VlICNzZXREaXNwb3NpdGlvbgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOTElORSA9ICJpbmxpbmUiOworCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBkaXNwb3NpdGlvbiBvZiB0aGlzIHBhcnQuICBUaGUgZGlzcG9zaXRpb24KKyAgICAgKiBkZXNjcmliZXMgaG93IHRoZSBwYXJ0IHNob3VsZCBiZSBwcmVzZW50ZWQgdG8gdGhlIHVzZXIuCisgICAgICogKFNlZSBSRkMgMjE4My4pICBUaGUgcmV0dXJuIHZhbHVlIHNob3VsZCBiZSBjb25zaWRlcmVkCisgICAgICogd2l0aG91dCByZWdhcmQgdG8gY2FzZS4gIEZvciBleGFtcGxlOgorICAgICAqIDxibG9ja3F1b3RlPjxwcmU+CisgICAgICogU3RyaW5nIGRpc3AgPSBwYXJ0LmdldERpc3Bvc2l0aW9uKCk7CisgICAgICogaWYgKGRpc3AgPT0gbnVsbCB8fCBkaXNwLmVxdWFsc0lnbm9yZUNhc2UoUGFydC5BVFRBQ0hNRU5UKSkKKyAgICAgKgkvLyB0cmVhdCBhcyBhdHRhY2htZW50IGlmIG5vdCBmaXJzdCBwYXJ0CisgICAgICogPC9wcmU+PC9ibG9ja3F1b3RlPgorICAgICAqCisgICAgICogQHJldHVybgkJZGlzcG9zaXRpb24gb2YgdGhpcyBwYXJ0LCBvciBudWxsIGlmIHVua25vd24KKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKiBAc2VlICNBVFRBQ0hNRU5UCisgICAgICogQHNlZSAjSU5MSU5FCisgICAgICogQHNlZSAjZ2V0RmlsZU5hbWUKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldERpc3Bvc2l0aW9uKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldCB0aGUgZGlzcG9zaXRpb24gb2YgdGhpcyBwYXJ0LgorICAgICAqCisgICAgICogQHBhcmFtCWRpc3Bvc2l0aW9uCWRpc3Bvc2l0aW9uIG9mIHRoaXMgcGFydAorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFdyaXRlRXhjZXB0aW9uIGlmIHRoZSB1bmRlcmx5aW5nIGltcGxlbWVudGF0aW9uCisgICAgICoJCQlkb2VzIG5vdCBzdXBwb3J0IG1vZGlmaWNhdGlvbiBvZiB0aGlzIGhlYWRlcgorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgUGFydCBpcyBvYnRhaW5lZAorICAgICAqCQkJZnJvbSBhIFJFQURfT05MWSBmb2xkZXIKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKiBAc2VlICNBVFRBQ0hNRU5UCisgICAgICogQHNlZSAjSU5MSU5FCisgICAgICogQHNlZSAjc2V0RmlsZU5hbWUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXREaXNwb3NpdGlvbihTdHJpbmcgZGlzcG9zaXRpb24pIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYSBkZXNjcmlwdGlvbiBTdHJpbmcgZm9yIHRoaXMgcGFydC4gVGhpcyB0eXBpY2FsbHkKKyAgICAgKiBhc3NvY2lhdGVzIHNvbWUgZGVzY3JpcHRpdmUgaW5mb3JtYXRpb24gd2l0aCB0aGlzIHBhcnQuCisgICAgICogUmV0dXJucyBudWxsIGlmIG5vbmUgaXMgYXZhaWxhYmxlLgorICAgICAqCisgICAgICogQHJldHVybgkJZGVzY3JpcHRpb24gb2YgdGhpcyBwYXJ0CisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXREZXNjcmlwdGlvbigpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBTZXQgYSBkZXNjcmlwdGlvbiBTdHJpbmcgZm9yIHRoaXMgcGFydC4gVGhpcyB0eXBpY2FsbHkKKyAgICAgKiBhc3NvY2lhdGVzIHNvbWUgZGVzY3JpcHRpdmUgaW5mb3JtYXRpb24gd2l0aCB0aGlzIHBhcnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0JZGVzY3JpcHRpb24JZGVzY3JpcHRpb24gb2YgdGhpcyBwYXJ0CisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsV3JpdGVFeGNlcHRpb24gaWYgdGhlIHVuZGVybHlpbmcgaW1wbGVtZW50YXRpb24KKyAgICAgKgkJCWRvZXMgbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uIG9mIHRoaXMgaGVhZGVyCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBQYXJ0IGlzIG9idGFpbmVkCisgICAgICoJCQlmcm9tIGEgUkVBRF9PTkxZIGZvbGRlcgorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBvdGhlciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldERlc2NyaXB0aW9uKFN0cmluZyBkZXNjcmlwdGlvbikgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldCB0aGUgZmlsZW5hbWUgYXNzb2NpYXRlZCB3aXRoIHRoaXMgcGFydCwgaWYgcG9zc2libGUuCisgICAgICogVXNlZnVsIGlmIHRoaXMgcGFydCByZXByZXNlbnRzIGFuICJhdHRhY2htZW50IiB0aGF0IHdhcworICAgICAqIGxvYWRlZCBmcm9tIGEgZmlsZS4gIFRoZSBmaWxlbmFtZSB3aWxsIHVzdWFsbHkgYmUgYSBzaW1wbGUKKyAgICAgKiBuYW1lLCBub3QgaW5jbHVkaW5nIGRpcmVjdG9yeSBjb21wb25lbnRzLgorICAgICAqCisgICAgICogQHJldHVybglGaWxlbmFtZSB0byBhc3NvY2lhdGUgd2l0aCB0aGlzIHBhcnQKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEZpbGVOYW1lKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFNldCB0aGUgZmlsZW5hbWUgYXNzb2NpYXRlZCB3aXRoIHRoaXMgcGFydCwgaWYgcG9zc2libGUuCisgICAgICogVXNlZnVsIGlmIHRoaXMgcGFydCByZXByZXNlbnRzIGFuICJhdHRhY2htZW50IiB0aGF0IHdhcworICAgICAqIGxvYWRlZCBmcm9tIGEgZmlsZS4gIFRoZSBmaWxlbmFtZSB3aWxsIHVzdWFsbHkgYmUgYSBzaW1wbGUKKyAgICAgKiBuYW1lLCBub3QgaW5jbHVkaW5nIGRpcmVjdG9yeSBjb21wb25lbnRzLgorICAgICAqCisgICAgICogQHBhcmFtCWZpbGVuYW1lCUZpbGVuYW1lIHRvIGFzc29jaWF0ZSB3aXRoIHRoaXMgcGFydAorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFdyaXRlRXhjZXB0aW9uIGlmIHRoZSB1bmRlcmx5aW5nIGltcGxlbWVudGF0aW9uCisgICAgICoJCQlkb2VzIG5vdCBzdXBwb3J0IG1vZGlmaWNhdGlvbiBvZiB0aGlzIGhlYWRlcgorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgUGFydCBpcyBvYnRhaW5lZAorICAgICAqCQkJZnJvbSBhIFJFQURfT05MWSBmb2xkZXIKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRGaWxlTmFtZShTdHJpbmcgZmlsZW5hbWUpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYW4gaW5wdXQgc3RyZWFtIGZvciB0aGlzIHBhcnQncyAiY29udGVudCIuIEFueSAKKyAgICAgKiBtYWlsLXNwZWNpZmljIHRyYW5zZmVyIGVuY29kaW5ncyB3aWxsIGJlIGRlY29kZWQgYmVmb3JlIHRoZSAKKyAgICAgKiBpbnB1dCBzdHJlYW0gaXMgcHJvdmlkZWQuIDxwPgorICAgICAqCisgICAgICogVGhpcyBpcyB0eXBpY2FsbHkgYSBjb252ZW5pZW5jZSBtZXRob2QgdGhhdCBqdXN0IGludm9rZXMKKyAgICAgKiB0aGUgRGF0YUhhbmRsZXIncyA8Y29kZT5nZXRJbnB1dFN0cmVhbSgpPC9jb2RlPiBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGFuIElucHV0U3RyZWFtCisgICAgICogQGV4Y2VwdGlvbglJT0V4Y2VwdGlvbiB0aGlzIGlzIHR5cGljYWxseSB0aHJvd24gYnkgdGhlIAorICAgICAqCQkJRGF0YUhhbmRsZXIuIFJlZmVyIHRvIHRoZSBkb2N1bWVudGF0aW9uIGZvciAKKyAgICAgKgkJCWphdmF4LmFjdGl2YXRpb24uRGF0YUhhbmRsZXIgZm9yIG1vcmUgZGV0YWlscy4KKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKiBAc2VlICNnZXREYXRhSGFuZGxlcgorICAgICAqIEBzZWUgamF2YXguYWN0aXZhdGlvbi5EYXRhSGFuZGxlciNnZXRJbnB1dFN0cmVhbQorICAgICAqLworICAgIHB1YmxpYyBJbnB1dFN0cmVhbSBnZXRJbnB1dFN0cmVhbSgpIAorCQl0aHJvd3MgSU9FeGNlcHRpb24sIE1lc3NhZ2luZ0V4Y2VwdGlvbjsKKyAgICAKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYSBEYXRhSGFuZGxlciBmb3IgdGhlIGNvbnRlbnQgd2l0aGluIHRoaXMgcGFydC4gVGhlCisgICAgICogRGF0YUhhbmRsZXIgYWxsb3dzIGNsaWVudHMgdG8gb3BlcmF0ZSBvbiBhcyB3ZWxsIGFzIHJldHJpZXZlCisgICAgICogdGhlIGNvbnRlbnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCQlEYXRhSGFuZGxlciBmb3IgdGhlIGNvbnRlbnQKKyAgICAgKiBAZXhjZXB0aW9uIAlNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIERhdGFIYW5kbGVyIGdldERhdGFIYW5kbGVyKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgY29udGVudCBhcyBhIEphdmEgb2JqZWN0LiBUaGUgdHlwZSBvZiB0aGUgcmV0dXJuZWQgCisgICAgICogb2JqZWN0IGlzIG9mIGNvdXJzZSBkZXBlbmRlbnQgb24gdGhlIGNvbnRlbnQgaXRzZWxmLiBGb3IgZXhhbXBsZSwKKyAgICAgKiB0aGUgb2JqZWN0IHJldHVybmVkIGZvciAidGV4dC9wbGFpbiIgY29udGVudCBpcyB1c3VhbGx5IGEgU3RyaW5nIAorICAgICAqIG9iamVjdC4gVGhlIG9iamVjdCByZXR1cm5lZCBmb3IgYSAibXVsdGlwYXJ0IiBjb250ZW50IGlzIGFsd2F5cyBhCisgICAgICogTXVsdGlwYXJ0IHN1YmNsYXNzLiBGb3IgY29udGVudC10eXBlcyB0aGF0IGFyZSAgdW5rbm93biB0byB0aGUKKyAgICAgKiBEYXRhSGFuZGxlciBzeXN0ZW0sIGFuIGlucHV0IHN0cmVhbSBpcyByZXR1cm5lZCBhcyB0aGUgY29udGVudCA8cD4KKyAgICAgKgorICAgICAqIFRoaXMgaXMgYSBjb252ZW5pZW5jZSBtZXRob2QgdGhhdCBqdXN0IGludm9rZXMgdGhlIERhdGFIYW5kbGVyJ3MKKyAgICAgKiBnZXRDb250ZW50KCkgbWV0aG9kCisgICAgICoKKyAgICAgKiBAcmV0dXJuCQlPYmplY3QKKyAgICAgKiBAZXhjZXB0aW9uCUlPRXhjZXB0aW9uIHRoaXMgaXMgdHlwaWNhbGx5IHRocm93biBieSB0aGUgCisgICAgICoJCQlEYXRhSGFuZGxlci4gUmVmZXIgdG8gdGhlIGRvY3VtZW50YXRpb24gZm9yIAorICAgICAqCQkJamF2YXguYWN0aXZhdGlvbi5EYXRhSGFuZGxlciBmb3IgbW9yZSBkZXRhaWxzLgorICAgICAqIEBleGNlcHRpb24gCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKgorICAgICAqIEBzZWUgamF2YXguYWN0aXZhdGlvbi5EYXRhSGFuZGxlciNnZXRDb250ZW50CisgICAgICovCisgICAgcHVibGljIE9iamVjdCBnZXRDb250ZW50KCkgdGhyb3dzIElPRXhjZXB0aW9uLCBNZXNzYWdpbmdFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBwcm92aWRlcyB0aGUgbWVjaGFuaXNtIHRvIHNldCB0aGlzIHBhcnQncyBjb250ZW50LgorICAgICAqIFRoZSBEYXRhSGFuZGxlciB3cmFwcyBhcm91bmQgdGhlIGFjdHVhbCBjb250ZW50LgorICAgICAqCisgICAgICogQHBhcmFtCWRoCVRoZSBEYXRhSGFuZGxlciBmb3IgdGhlIGNvbnRlbnQuCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsV3JpdGVFeGNlcHRpb24gaWYgdGhlIHVuZGVybHlpbmcgaW1wbGVtZW50YXRpb24KKyAgICAgKgkJCWRvZXMgbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uIG9mIGV4aXN0aW5nIHZhbHVlcworICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgUGFydCBpcyBvYnRhaW5lZAorICAgICAqCQkJZnJvbSBhIFJFQURfT05MWSBmb2xkZXIKKyAgICAgKiBAZXhjZXB0aW9uIAlNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RGF0YUhhbmRsZXIoRGF0YUhhbmRsZXIgZGgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBBIGNvbnZlbmllbmNlIG1ldGhvZCBmb3Igc2V0dGluZyB0aGlzIHBhcnQncyBjb250ZW50LiAgVGhlIHBhcnQKKyAgICAgKiBpbnRlcm5hbGx5IHdyYXBzIHRoZSBjb250ZW50IGluIGEgRGF0YUhhbmRsZXIuIDxwPgorICAgICAqCisgICAgICogTm90ZSB0aGF0IGEgRGF0YUNvbnRlbnRIYW5kbGVyIGNsYXNzIGZvciB0aGUgc3BlY2lmaWVkIHR5cGUgc2hvdWxkIAorICAgICAqIGJlIGF2YWlsYWJsZSB0byB0aGUgSmF2YU1haWwgaW1wbGVtZW50YXRpb24gZm9yIHRoaXMgdG8gd29yayByaWdodC4KKyAgICAgKiBpLmUuLCB0byBkbyA8Y29kZT5zZXRDb250ZW50KGZvb2JhciwgImFwcGxpY2F0aW9uL3gtZm9vYmFyIik8L2NvZGU+LAorICAgICAqIGEgRGF0YUNvbnRlbnRIYW5kbGVyIGZvciAiYXBwbGljYXRpb24veC1mb29iYXIiIHNob3VsZCBiZSBpbnN0YWxsZWQuCisgICAgICogUmVmZXIgdG8gdGhlIEphdmEgQWN0aXZhdGlvbiBGcmFtZXdvcmsgZm9yIG1vcmUgaW5mb3JtYXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0Jb2JqCUEgamF2YSBvYmplY3QuCisgICAgICogQHBhcmFtCXR5cGUJTUlNRSB0eXBlIG9mIHRoaXMgb2JqZWN0LgorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFdyaXRlRXhjZXB0aW9uIGlmIHRoZSB1bmRlcmx5aW5nIGltcGxlbWVudGF0aW9uCisgICAgICoJCQlkb2VzIG5vdCBzdXBwb3J0IG1vZGlmaWNhdGlvbiBvZiBleGlzdGluZyB2YWx1ZXMKKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIFBhcnQgaXMgb2J0YWluZWQKKyAgICAgKgkJCWZyb20gYSBSRUFEX09OTFkgZm9sZGVyCisgICAgICogQGV4Y2VwdGlvbiAJTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBvdGhlciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldENvbnRlbnQoT2JqZWN0IG9iaiwgU3RyaW5nIHR5cGUpIAorCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEEgY29udmVuaWVuY2UgbWV0aG9kIHRoYXQgc2V0cyB0aGUgZ2l2ZW4gU3RyaW5nIGFzIHRoaXMKKyAgICAgKiBwYXJ0J3MgY29udGVudCB3aXRoIGEgTUlNRSB0eXBlIG9mICJ0ZXh0L3BsYWluIi4gCisgICAgICoKKyAgICAgKiBAcGFyYW0gIHRleHQgICAgCVRoZSB0ZXh0IHRoYXQgaXMgdGhlIE1lc3NhZ2UncyBjb250ZW50LgorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFdyaXRlRXhjZXB0aW9uIGlmIHRoZSB1bmRlcmx5aW5nIAorICAgICAqCQkJaW1wbGVtZW50YXRpb24gZG9lcyBub3Qgc3VwcG9ydCBtb2RpZmljYXRpb24gb2YgCisgICAgICoJCQlleGlzdGluZyB2YWx1ZXMKKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIFBhcnQgaXMgb2J0YWluZWQKKyAgICAgKgkJCWZyb20gYSBSRUFEX09OTFkgZm9sZGVyCisgICAgICogQGV4Y2VwdGlvbiAJTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBvdGhlciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFRleHQoU3RyaW5nIHRleHQpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBzZXRzIHRoZSBnaXZlbiBNdWx0aXBhcnQgb2JqZWN0IGFzIHRoaXMgbWVzc2FnZSdzCisgICAgICogY29udGVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbSAgbXAgICAgICAJVGhlIG11bHRpcGFydCBvYmplY3QgdGhhdCBpcyB0aGUgTWVzc2FnZSdzIGNvbnRlbnQKKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxXcml0ZUV4Y2VwdGlvbiBpZiB0aGUgdW5kZXJseWluZyAKKyAgICAgKgkJCWltcGxlbWVudGF0aW9uCWRvZXMgbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uIG9mIAorICAgICAqCQkJZXhpc3RpbmcgdmFsdWVzCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBQYXJ0IGlzIG9idGFpbmVkCisgICAgICoJCQlmcm9tIGEgUkVBRF9PTkxZIGZvbGRlcgorICAgICAqIEBleGNlcHRpb24gCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDb250ZW50KE11bHRpcGFydCBtcCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIE91dHB1dCBhIGJ5dGVzdHJlYW0gZm9yIHRoaXMgUGFydC4gVGhpcyBieXRlc3RyZWFtIGlzCisgICAgICogdHlwaWNhbGx5IGFuIGFnZ3JlZ3JhdGlvbiBvZiB0aGUgUGFydCBhdHRyaWJ1dGVzIGFuZAorICAgICAqIGFuIGFwcHJvcHJpYXRlbHkgZW5jb2RlZCBieXRlc3RyZWFtIGZyb20gaXRzICdjb250ZW50Jy4gPHA+CisgICAgICoKKyAgICAgKiBDbGFzc2VzIHRoYXQgaW1wbGVtZW50IHRoZSBQYXJ0IGludGVyZmFjZSBkZWNpZGUgb24KKyAgICAgKiB0aGUgYXBwcm9wcmlhdGUgZW5jb2RpbmcgYWxnb3JpdGhtIHRvIGJlIHVzZWQuIDxwPgorICAgICAqCisgICAgICogVGhlIGJ5dGVzdHJlYW0gaXMgdHlwaWNhbGx5IHVzZWQgZm9yIHNlbmRpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jb3MJdGhlIHN0cmVhbSB0byB3cml0ZSB0bworICAgICAqIEBleGNlcHRpb24gSU9FeGNlcHRpb24JCWlmIGFuIGVycm9yIG9jY3VycyB3cml0aW5nIHRvIHRoZSAKKyAgICAgKgkJCQkJc3RyZWFtIG9yIGlmIGFuIGVycm9yIGlzIGdlbmVyYXRlZAorICAgICAqCQkJCQlieSB0aGUgamF2YXguYWN0aXZhdGlvbiBsYXllci4KKyAgICAgKiBAZXhjZXB0aW9uIE1lc3NhZ2luZ0V4Y2VwdGlvbglpZiBhbiBlcnJvciBvY2N1cnMgZmV0Y2hpbmcgdGhlCisgICAgICoJCQkJCWRhdGEgdG8gYmUgd3JpdHRlbgorICAgICAqCisgICAgICogQHNlZSBqYXZheC5hY3RpdmF0aW9uLkRhdGFIYW5kbGVyI3dyaXRlVG8KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKE91dHB1dFN0cmVhbSBvcykgdGhyb3dzIElPRXhjZXB0aW9uLCBNZXNzYWdpbmdFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXQgYWxsIHRoZSBoZWFkZXJzIGZvciB0aGlzIGhlYWRlciBuYW1lLiBSZXR1cm5zIDxjb2RlPm51bGw8L2NvZGU+CisgICAgICogaWYgbm8gaGVhZGVycyBmb3IgdGhpcyBoZWFkZXIgbmFtZSBhcmUgYXZhaWxhYmxlLgorICAgICAqCisgICAgICogQHBhcmFtIGhlYWRlcl9uYW1lICAgICAgIHRoZSBuYW1lIG9mIHRoaXMgaGVhZGVyCisgICAgICogQHJldHVybiAgICAgICAgICAgICAgICAgIHRoZSB2YWx1ZSBmaWVsZHMgZm9yIGFsbCBoZWFkZXJzIHdpdGggCisgICAgICoJCQkJdGhpcyBuYW1lCisgICAgICogQGV4Y2VwdGlvbiAgICAgICAJTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRIZWFkZXIoU3RyaW5nIGhlYWRlcl9uYW1lKQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb247CisgICAgCisgICAgLyoqCisgICAgICogU2V0IHRoZSB2YWx1ZSBmb3IgdGhpcyBoZWFkZXJfbmFtZS4gUmVwbGFjZXMgYWxsIGV4aXN0aW5nCisgICAgICogaGVhZGVyIHZhbHVlcyB3aXRoIHRoaXMgbmV3IHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGhlYWRlcl9uYW1lICAgICAgIHRoZSBuYW1lIG9mIHRoaXMgaGVhZGVyCisgICAgICogQHBhcmFtIGhlYWRlcl92YWx1ZSAgICAgIHRoZSB2YWx1ZSBmb3IgdGhpcyBoZWFkZXIKKyAgICAgKiBAZXhjZXB0aW9uCQlJbGxlZ2FsV3JpdGVFeGNlcHRpb24gaWYgdGhlIHVuZGVybHlpbmcgCisgICAgICoJCQkJaW1wbGVtZW50YXRpb24gZG9lcyBub3Qgc3VwcG9ydCBtb2RpZmljYXRpb24gCisgICAgICoJCQkJb2YgZXhpc3RpbmcgdmFsdWVzCisgICAgICogQGV4Y2VwdGlvbgkJSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgUGFydCBpcyAKKyAgICAgKgkJCQlvYnRhaW5lZCBmcm9tIGEgUkVBRF9PTkxZIGZvbGRlcgorICAgICAqIEBleGNlcHRpb24gICAgICAgCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRIZWFkZXIoU3RyaW5nIGhlYWRlcl9uYW1lLCBTdHJpbmcgaGVhZGVyX3ZhbHVlKQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb247CisgICAgLyoqCisgICAgICogQWRkIHRoaXMgdmFsdWUgdG8gdGhlIGV4aXN0aW5nIHZhbHVlcyBmb3IgdGhpcyBoZWFkZXJfbmFtZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBoZWFkZXJfbmFtZSAgICAgICB0aGUgbmFtZSBvZiB0aGlzIGhlYWRlcgorICAgICAqIEBwYXJhbSBoZWFkZXJfdmFsdWUgICAgICB0aGUgdmFsdWUgZm9yIHRoaXMgaGVhZGVyCisgICAgICogQGV4Y2VwdGlvbgkJSWxsZWdhbFdyaXRlRXhjZXB0aW9uIGlmIHRoZSB1bmRlcmx5aW5nIAorICAgICAqCQkJCWltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uIAorICAgICAqCQkJCW9mIGV4aXN0aW5nIHZhbHVlcworICAgICAqIEBleGNlcHRpb24JCUlsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIFBhcnQgaXMgCisgICAgICoJCQkJb2J0YWluZWQgZnJvbSBhIFJFQURfT05MWSBmb2xkZXIKKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIAlNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIHZvaWQgYWRkSGVhZGVyKFN0cmluZyBoZWFkZXJfbmFtZSwgU3RyaW5nIGhlYWRlcl92YWx1ZSkKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uOworICAgIC8qKgorICAgICAqIFJlbW92ZSBhbGwgaGVhZGVycyB3aXRoIHRoaXMgbmFtZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBoZWFkZXJfbmFtZSAgICAgICB0aGUgbmFtZSBvZiB0aGlzIGhlYWRlcgorICAgICAqIEBleGNlcHRpb24JCUlsbGVnYWxXcml0ZUV4Y2VwdGlvbiBpZiB0aGUgdW5kZXJseWluZyAKKyAgICAgKgkJCQlpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IG1vZGlmaWNhdGlvbiAKKyAgICAgKgkJCQlvZiBleGlzdGluZyB2YWx1ZXMKKyAgICAgKiBAZXhjZXB0aW9uCQlJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBQYXJ0IGlzIAorICAgICAqCQkJCW9idGFpbmVkIGZyb20gYSBSRUFEX09OTFkgZm9sZGVyCisgICAgICogQGV4Y2VwdGlvbiAgICAgICAJTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBvdGhlciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlbW92ZUhlYWRlcihTdHJpbmcgaGVhZGVyX25hbWUpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybiBhbGwgdGhlIGhlYWRlcnMgZnJvbSB0aGlzIHBhcnQgYXMgYW4gRW51bWVyYXRpb24gb2YKKyAgICAgKiBIZWFkZXIgb2JqZWN0cy4KKyAgICAgKgorICAgICAqIEByZXR1cm4gIGVudW1lcmF0aW9uIG9mIEhlYWRlciBvYmplY3RzCisgICAgICogQGV4Y2VwdGlvbiAgICAgICBNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIEVudW1lcmF0aW9uPEhlYWRlcj4gZ2V0QWxsSGVhZGVycygpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gbWF0Y2hpbmcgaGVhZGVycyBmcm9tIHRoaXMgcGFydCBhcyBhbiBFbnVtZXJhdGlvbiBvZgorICAgICAqIEhlYWRlciBvYmplY3RzLgorICAgICAqCisgICAgICogQHBhcmFtCWhlYWRlcl9uYW1lcwl0aGUgaGVhZGVycyB0byBtYXRjaAorICAgICAqIEByZXR1cm4gIGVudW1lcmF0aW9uIG9mIEhlYWRlciBvYmplY3RzCisgICAgICogQGV4Y2VwdGlvbiAgICAgICBNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIEVudW1lcmF0aW9uPEhlYWRlcj4gZ2V0TWF0Y2hpbmdIZWFkZXJzKFN0cmluZ1tdIGhlYWRlcl9uYW1lcykKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJuIG5vbi1tYXRjaGluZyBoZWFkZXJzIGZyb20gdGhpcyBlbnZlbG9wZSBhcyBhbiBFbnVtZXJhdGlvbgorICAgICAqIG9mIEhlYWRlciBvYmplY3RzLgorICAgICAqCisgICAgICogQHBhcmFtCWhlYWRlcl9uYW1lcwl0aGUgaGVhZGVycyB0byBub3QgbWF0Y2gKKyAgICAgKiBAcmV0dXJuICBlbnVtZXJhdGlvbiBvZiBIZWFkZXIgb2JqZWN0cworICAgICAqIEBleGNlcHRpb24gICAgICAgTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBFbnVtZXJhdGlvbjxIZWFkZXI+IGdldE5vbk1hdGNoaW5nSGVhZGVycyhTdHJpbmdbXSBoZWFkZXJfbmFtZXMpIAorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9QYXNzd29yZEF1dGhlbnRpY2F0aW9uLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9QYXNzd29yZEF1dGhlbnRpY2F0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODY1NGVlMAotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL1Bhc3N3b3JkQXV0aGVudGljYXRpb24uamF2YQpAQCAtMCwwICsxLDU5IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGphdmF4Lm1haWw7CisKKworLyoqCisgKiBUaGUgY2xhc3MgUGFzc3dvcmRBdXRoZW50aWNhdGlvbiBpcyBhIGRhdGEgaG9sZGVyIHRoYXQgaXMgdXNlZCBieQorICogQXV0aGVudGljYXRvci4gIEl0IGlzIHNpbXBseSBhIHJlcG9zaXRvcnkgZm9yIGEgdXNlciBuYW1lIGFuZCBhIHBhc3N3b3JkLgorICoKKyAqIEBzZWUgamF2YS5uZXQuUGFzc3dvcmRBdXRoZW50aWNhdGlvbgorICogQHNlZSBqYXZheC5tYWlsLkF1dGhlbnRpY2F0b3IKKyAqIEBzZWUgamF2YXgubWFpbC5BdXRoZW50aWNhdG9yI2dldFBhc3N3b3JkQXV0aGVudGljYXRpb24oKQorICoKKyAqIEBhdXRob3IgIEJpbGwgRm9vdGUKKyAqLworCitwdWJsaWMgZmluYWwgY2xhc3MgUGFzc3dvcmRBdXRoZW50aWNhdGlvbiB7CisKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyB1c2VyTmFtZTsKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBwYXNzd29yZDsKKworICAgIC8qKiAKKyAgICAgKiBJbml0aWFsaXplIGEgbmV3IFBhc3N3b3JkQXV0aGVudGljYXRpb24KKyAgICAgKiBAcGFyYW0gdXNlck5hbWUgdGhlIHVzZXIgbmFtZQorICAgICAqIEBwYXJhbSBwYXNzd29yZCBUaGUgdXNlcidzIHBhc3N3b3JkCisgICAgICovCisgICAgcHVibGljIFBhc3N3b3JkQXV0aGVudGljYXRpb24oU3RyaW5nIHVzZXJOYW1lLCBTdHJpbmcgcGFzc3dvcmQpIHsKKwl0aGlzLnVzZXJOYW1lID0gdXNlck5hbWU7CisJdGhpcy5wYXNzd29yZCA9IHBhc3N3b3JkOworICAgIH0KKworICAgIC8qKgorICAgICAqIEByZXR1cm4gdGhlIHVzZXIgbmFtZQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0VXNlck5hbWUoKSB7CisJcmV0dXJuIHVzZXJOYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIEByZXR1cm4gdGhlIHBhc3N3b3JkCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRQYXNzd29yZCgpIHsKKwlyZXR1cm4gcGFzc3dvcmQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvUHJvdmlkZXIuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL1Byb3ZpZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjg4OTg3NQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL1Byb3ZpZGVyLmphdmEKQEAgLTAsMCArMSwxMzggQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbDsKKworLyoqCisgKiBUaGUgUHJvdmlkZXIgaXMgYSBjbGFzcyB0aGF0IGRlc2NyaWJlcyBhIHByb3RvY29sIAorICogaW1wbGVtZW50YXRpb24uICBUaGUgdmFsdWVzIHR5cGljYWxseSBjb21lIGZyb20gdGhlCisgKiBqYXZhbWFpbC5wcm92aWRlcnMgYW5kIGphdmFtYWlsLmRlZmF1bHQucHJvdmlkZXJzCisgKiByZXNvdXJjZSBmaWxlcy4gIEFuIGFwcGxpY2F0aW9uIG1heSBhbHNvIGNyZWF0ZSBhbmQKKyAqIHJlZ2lzdGVyIGEgUHJvdmlkZXIgb2JqZWN0IHRvIGR5bmFtaWNhbGx5IGFkZCBzdXBwb3J0CisgKiBmb3IgYSBuZXcgcHJvdmlkZXIuCisgKgorICogQGF1dGhvciBNYXggU3BpdmFrCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCitwdWJsaWMgY2xhc3MgUHJvdmlkZXIgeworCisgICAgLyoqCisgICAgICogVGhpcyBpbm5lciBjbGFzcyBkZWZpbmVzIHRoZSBQcm92aWRlciB0eXBlLgorICAgICAqIEN1cnJlbnRseSwgU1RPUkUgYW5kIFRSQU5TUE9SVCBhcmUgdGhlIG9ubHkgdHdvIHByb3ZpZGVyIHR5cGVzIAorICAgICAqIHN1cHBvcnRlZC4KKyAgICAgKi8KKworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgVHlwZSB7CisJcHVibGljIHN0YXRpYyBmaW5hbCBUeXBlIFNUT1JFICAgICA9IG5ldyBUeXBlKCJTVE9SRSIpOworCXB1YmxpYyBzdGF0aWMgZmluYWwgVHlwZSBUUkFOU1BPUlQgPSBuZXcgVHlwZSgiVFJBTlNQT1JUIik7CisKKwlwcml2YXRlIFN0cmluZyB0eXBlOworCisJcHJpdmF0ZSBUeXBlKFN0cmluZyB0eXBlKSB7CisJICAgIHRoaXMudHlwZSA9IHR5cGU7CisJfQorCisJQE92ZXJyaWRlCisJcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKwkgICAgcmV0dXJuIHR5cGU7CisJfQorICAgIH0KKworICAgIHByaXZhdGUgVHlwZSB0eXBlOworICAgIHByaXZhdGUgU3RyaW5nIHByb3RvY29sLCBjbGFzc05hbWUsIHZlbmRvciwgdmVyc2lvbjsKKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIG5ldyBwcm92aWRlciBvZiB0aGUgc3BlY2lmaWVkIHR5cGUgZm9yIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBwcm90b2NvbC4gIFRoZSBzcGVjaWZpZWQgY2xhc3MgaW1wbGVtZW50cyB0aGUgcHJvdmlkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdHlwZSAgICAgIFR5cGUuU1RPUkUgb3IgVHlwZS5UUkFOU1BPUlQKKyAgICAgKiBAcGFyYW0gcHJvdG9jb2wgIHZhbGlkIHByb3RvY29sIGZvciB0aGUgdHlwZQorICAgICAqIEBwYXJhbSBjbGFzc25hbWUgY2xhc3MgbmFtZSB0aGF0IGltcGxlbWVudHMgdGhpcyBwcm90b2NvbAorICAgICAqIEBwYXJhbSB2ZW5kb3IgICAgb3B0aW9uYWwgc3RyaW5nIGlkZW50aWZ5aW5nIHRoZSB2ZW5kb3IgKG1heSBiZSBudWxsKQorICAgICAqIEBwYXJhbSB2ZXJzaW9uICAgb3B0aW9uYWwgaW1wbGVtZW50YXRpb24gdmVyc2lvbiBzdHJpbmcgKG1heSBiZSBudWxsKQorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgUHJvdmlkZXIoVHlwZSB0eXBlLCBTdHJpbmcgcHJvdG9jb2wsIFN0cmluZyBjbGFzc25hbWUsIAorCSAgICAgU3RyaW5nIHZlbmRvciwgU3RyaW5nIHZlcnNpb24pIHsKKwl0aGlzLnR5cGUgPSB0eXBlOworCXRoaXMucHJvdG9jb2wgPSBwcm90b2NvbDsKKwl0aGlzLmNsYXNzTmFtZSA9IGNsYXNzbmFtZTsKKwl0aGlzLnZlbmRvciA9IHZlbmRvcjsKKwl0aGlzLnZlcnNpb24gPSB2ZXJzaW9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHR5cGUgb2YgdGhpcyBQcm92aWRlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIHByb3ZpZGVyIHR5cGUKKyAgICAgKi8KKyAgICBwdWJsaWMgVHlwZSBnZXRUeXBlKCkgeworCXJldHVybiB0eXBlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHByb3RvY29sIHN1cHBvcnRlZCBieSB0aGlzIFByb3ZpZGVyLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgcHJvdG9jb2wKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFByb3RvY29sKCkgeworCXJldHVybiBwcm90b2NvbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBjbGFzcyB0aGF0IGltcGxlbWVudHMgdGhlIHByb3RvY29sLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgY2xhc3MgbmFtZQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q2xhc3NOYW1lKCkgeworCXJldHVybiBjbGFzc05hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgdmVuZG9yIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGltcGxlbWVudGF0aW9uCisgICAgICogb3IgbnVsbC4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIHZlbmRvcgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0VmVuZG9yKCkgeworCXJldHVybiB2ZW5kb3I7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmVyc2lvbiBvZiB0aGlzIGltcGxlbWVudGF0aW9uIG9yIG51bGwgaWYgbm8gdmVyc2lvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIHZlcnNpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFZlcnNpb24oKSB7CisJcmV0dXJuIHZlcnNpb247CisgICAgfQorCisgICAgLyoqIE92ZXJyaWRlcyBPYmplY3QudG9TdHJpbmcoKSAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisJU3RyaW5nIHMgPSAiamF2YXgubWFpbC5Qcm92aWRlclsiICsgdHlwZSArICIsIiArCisJCSAgICBwcm90b2NvbCArICIsIiArIGNsYXNzTmFtZTsKKworCWlmICh2ZW5kb3IgIT0gbnVsbCkKKwkgICAgcyArPSAiLCIgKyB2ZW5kb3I7CisKKwlpZiAodmVyc2lvbiAhPSBudWxsKQorCSAgICBzICs9ICIsIiArIHZlcnNpb247CisKKwlzICs9ICJdIjsKKwlyZXR1cm4gczsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9RdW90YS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvUXVvdGEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xM2RhOGI5Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvUXVvdGEuamF2YQpAQCAtMCwwICsxLDEwMyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsOworCisvKioKKyAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhIHNldCBvZiBxdW90YXMgZm9yIGEgZ2l2ZW4gcXVvdGEgcm9vdC4KKyAqIEVhY2ggcXVvdGEgcm9vdCBoYXMgYSBzZXQgb2YgcmVzb3VyY2VzLCByZXByZXNlbnRlZCBieSB0aGUKKyAqIDxjb2RlPlF1b3RhLlJlc291cmNlPC9jb2RlPiBjbGFzcy4gIEVhY2ggcmVzb3VyY2UgaGFzIGEgbmFtZQorICogKGZvciBleGFtcGxlLCAiU1RPUkFHRSIpLCBhIGN1cnJlbnQgdXNhZ2UsIGFuZCBhIHVzYWdlIGxpbWl0LgorICogU2VlIFJGQyAyMDg3LgorICoKKyAqIEBzaW5jZSBKYXZhTWFpbCAxLjQKKyAqIEBhdXRob3IgIEJpbGwgU2hhbm5vbgorICovCisKK3B1YmxpYyBjbGFzcyBRdW90YSB7CisKKyAgICAvKioKKyAgICAgKiBBbiBpbmRpdmlkdWFsIHJlc291cmNlIGluIGEgcXVvdGEgcm9vdC4KKyAgICAgKgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFJlc291cmNlIHsKKwkvKiogVGhlIG5hbWUgb2YgdGhlIHJlc291cmNlLiAqLworCXB1YmxpYyBTdHJpbmcgbmFtZTsKKwkvKiogVGhlIGN1cnJlbnQgdXNhZ2Ugb2YgdGhlIHJlc291cmNlLiAqLworCXB1YmxpYyBsb25nIHVzYWdlOworCS8qKiBUaGUgdXNhZ2UgbGltaXQgZm9yIHRoZSByZXNvdXJjZS4gKi8KKwlwdWJsaWMgbG9uZyBsaW1pdDsKKworCS8qKgorCSAqIENvbnN0cnVjdCBhIFJlc291cmNlIG9iamVjdCB3aXRoIHRoZSBnaXZlbiBuYW1lLAorCSAqIHVzYWdlLCBhbmQgbGltaXQuCisJICoKKwkgKiBAcGFyYW0JbmFtZQl0aGUgcmVzb3VyY2UgbmFtZQorCSAqIEBwYXJhbQl1c2FnZQl0aGUgY3VycmVudCB1c2FnZSBvZiB0aGUgcmVzb3VyY2UKKwkgKiBAcGFyYW0JbGltaXQJdGhlIHVzYWdlIGxpbWl0IGZvciB0aGUgcmVzb3VyY2UKKwkgKi8KKwlwdWJsaWMgUmVzb3VyY2UoU3RyaW5nIG5hbWUsIGxvbmcgdXNhZ2UsIGxvbmcgbGltaXQpIHsKKwkgICAgdGhpcy5uYW1lID0gbmFtZTsKKwkgICAgdGhpcy51c2FnZSA9IHVzYWdlOworCSAgICB0aGlzLmxpbWl0ID0gbGltaXQ7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBuYW1lIG9mIHRoZSBxdW90YSByb290LgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgcXVvdGFSb290OworCisgICAgLyoqCisgICAgICogVGhlIHNldCBvZiByZXNvdXJjZXMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgcXVvdGEgcm9vdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgUXVvdGEuUmVzb3VyY2VbXSByZXNvdXJjZXM7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBRdW90YSBvYmplY3QgZm9yIHRoZSBuYW1lZCBxdW90YXJvb3Qgd2l0aCBubyBhc3NvY2lhdGVkCisgICAgICogcmVzb3VyY2VzLgorICAgICAqCisgICAgICogQHBhcmFtCXF1b3RhUm9vdAl0aGUgbmFtZSBvZiB0aGUgcXVvdGEgcm9vdAorICAgICAqLworICAgIHB1YmxpYyBRdW90YShTdHJpbmcgcXVvdGFSb290KSB7CisJdGhpcy5xdW90YVJvb3QgPSBxdW90YVJvb3Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IGEgcmVzb3VyY2UgbGltaXQgZm9yIHRoaXMgcXVvdGEgcm9vdC4KKyAgICAgKgorICAgICAqIEBwYXJhbQluYW1lCXRoZSBuYW1lIG9mIHRoZSByZXNvdXJjZQorICAgICAqIEBwYXJhbQlsaW1pdAl0aGUgcmVzb3VyY2UgbGltaXQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRSZXNvdXJjZUxpbWl0KFN0cmluZyBuYW1lLCBsb25nIGxpbWl0KSB7CisJaWYgKHJlc291cmNlcyA9PSBudWxsKSB7CisJICAgIHJlc291cmNlcyA9IG5ldyBRdW90YS5SZXNvdXJjZVsxXTsKKwkgICAgcmVzb3VyY2VzWzBdID0gbmV3IFF1b3RhLlJlc291cmNlKG5hbWUsIDAsIGxpbWl0KTsKKwkgICAgcmV0dXJuOworCX0KKwlmb3IgKGludCBpID0gMDsgaSA8IHJlc291cmNlcy5sZW5ndGg7IGkrKykgeworCSAgICBpZiAocmVzb3VyY2VzW2ldLm5hbWUuZXF1YWxzSWdub3JlQ2FzZShuYW1lKSkgeworCQlyZXNvdXJjZXNbaV0ubGltaXQgPSBsaW1pdDsKKwkJcmV0dXJuOworCSAgICB9CisJfQorCVF1b3RhLlJlc291cmNlW10gcmEgPSBuZXcgUXVvdGEuUmVzb3VyY2VbcmVzb3VyY2VzLmxlbmd0aCArIDFdOworCVN5c3RlbS5hcnJheWNvcHkocmVzb3VyY2VzLCAwLCByYSwgMCwgcmVzb3VyY2VzLmxlbmd0aCk7CisJcmFbcmEubGVuZ3RoIC0gMV0gPSBuZXcgUXVvdGEuUmVzb3VyY2UobmFtZSwgMCwgbGltaXQpOworCXJlc291cmNlcyA9IHJhOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL1F1b3RhQXdhcmVTdG9yZS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvUXVvdGFBd2FyZVN0b3JlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTZmNTY2ZAotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL1F1b3RhQXdhcmVTdG9yZS5qYXZhCkBAIC0wLDAgKzEsNTcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbDsKKworLyoqCisgKiBBbiBpbnRlcmZhY2UgaW1wbGVtZW50ZWQgYnkgU3RvcmVzIHRoYXQgc3VwcG9ydCBxdW90YXMuCisgKiBUaGUge0BsaW5rICNnZXRRdW90YSBnZXRRdW90YX0gYW5kIHtAbGluayAjc2V0UXVvdGEgc2V0UXVvdGF9IG1ldGhvZHMKKyAqIHN1cHBvcnQgdGhlIHF1b3RhIG1vZGVsIGRlZmluZWQgYnkgdGhlIElNQVAgUVVPVEEgZXh0ZW5zaW9uLgorICogUmVmZXIgdG8gPEEgSFJFRj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjA4Ny50eHQiPlJGQyAyMDg3PC9BPgorICogZm9yIG1vcmUgaW5mb3JtYXRpb24uIDxwPgorICoKKyAqIEBzaW5jZSBKYXZhTWFpbCAxLjQKKyAqLworcHVibGljIGludGVyZmFjZSBRdW90YUF3YXJlU3RvcmUgeworICAgIC8qKgorICAgICAqIEdldCB0aGUgcXVvdGFzIGZvciB0aGUgbmFtZWQgZm9sZGVyLgorICAgICAqIFF1b3RhcyBhcmUgY29udHJvbGxlZCBvbiB0aGUgYmFzaXMgb2YgYSBxdW90YSByb290LCBub3QKKyAgICAgKiAobmVjZXNzYXJpbHkpIGEgZm9sZGVyLiAgVGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGZvbGRlcnMKKyAgICAgKiBhbmQgcXVvdGEgcm9vdHMgZGVwZW5kcyBvbiB0aGUgc2VydmVyLiAgU29tZSBzZXJ2ZXJzCisgICAgICogbWlnaHQgaW1wbGVtZW50IGEgc2luZ2xlIHF1b3RhIHJvb3QgZm9yIGFsbCBmb2xkZXJzIG93bmVkIGJ5CisgICAgICogYSB1c2VyLiAgT3RoZXIgc2VydmVycyBtaWdodCBpbXBsZW1lbnQgYSBzZXBhcmF0ZSBxdW90YSByb290CisgICAgICogZm9yIGVhY2ggZm9sZGVyLiAgQSBzaW5nbGUgZm9sZGVyIGNhbiBldmVuIGhhdmUgbXVsdGlwbGUKKyAgICAgKiBxdW90YSByb290cywgcGVyaGFwcyBjb250cm9sbGluZyBxdW90YXMgZm9yIGRpZmZlcmVudAorICAgICAqIHJlc291cmNlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbQlmb2xkZXIJdGhlIG5hbWUgb2YgdGhlIGZvbGRlcgorICAgICAqIEByZXR1cm4JCWFycmF5IG9mIFF1b3RhIG9iamVjdHMKKyAgICAgKiBAZXhjZXB0aW9uIE1lc3NhZ2luZ0V4Y2VwdGlvbglpZiB0aGUgc2VydmVyIGRvZXNuJ3Qgc3VwcG9ydCB0aGUKKyAgICAgKgkJCQkJUVVPVEEgZXh0ZW5zaW9uCisgICAgICovCisgICAgUXVvdGFbXSBnZXRRdW90YShTdHJpbmcgZm9sZGVyKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0IHRoZSBxdW90YXMgZm9yIHRoZSBxdW90YSByb290IHNwZWNpZmllZCBpbiB0aGUgcXVvdGEgYXJndW1lbnQuCisgICAgICogVHlwaWNhbGx5IHRoaXMgd2lsbCBiZSBvbmUgb2YgdGhlIHF1b3RhIHJvb3RzIG9idGFpbmVkIGZyb20gdGhlCisgICAgICogPGNvZGU+Z2V0UXVvdGE8L2NvZGU+IG1ldGhvZCwgYnV0IGl0IG5lZWQgbm90IGJlLgorICAgICAqCisgICAgICogQHBhcmFtCXF1b3RhCXRoZSBxdW90YSB0byBzZXQKKyAgICAgKiBAZXhjZXB0aW9uIE1lc3NhZ2luZ0V4Y2VwdGlvbglpZiB0aGUgc2VydmVyIGRvZXNuJ3Qgc3VwcG9ydCB0aGUKKyAgICAgKgkJCQkJUVVPVEEgZXh0ZW5zaW9uCisgICAgICovCisgICAgdm9pZCBzZXRRdW90YShRdW90YSBxdW90YSkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbjsKK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL1JlYWRPbmx5Rm9sZGVyRXhjZXB0aW9uLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9SZWFkT25seUZvbGRlckV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY2NThiNWMKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9SZWFkT25seUZvbGRlckV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsODIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbDsKKworLyoqCisgKiBUaGlzIGV4Y2VwdGlvbiBpcyB0aHJvd24gd2hlbiBhbiBhdHRlbXB0IGlzIG1hZGUgdG8gb3BlbiBhIGZvbGRlcgorICogcmVhZC13cml0ZSBhY2Nlc3Mgd2hlbiB0aGUgZm9sZGVyIGlzIG1hcmtlZCByZWFkLW9ubHkuIDxwPgorICoKKyAqIFRoZSBnZXRNZXNzYWdlKCkgbWV0aG9kIHJldHVybnMgbW9yZSBkZXRhaWxlZCBpbmZvcm1hdGlvbiBhYm91dCB0aGUKKyAqIGVycm9yIHRoYXQgY2F1c2VkIHRoaXMgZXhjZXB0aW9uLiA8cD4KKyAqCisgKiBAYXV0aG9yIEppbSBHbGVubm9uCisgKi8KKworcHVibGljIGNsYXNzIFJlYWRPbmx5Rm9sZGVyRXhjZXB0aW9uIGV4dGVuZHMgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKyAgICB0cmFuc2llbnQgcHJpdmF0ZSBGb2xkZXIgZm9sZGVyOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNTcxMTgyOTM3Mjc5OTAzOTMyNUw7CisgICAgCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIFJlYWRPbmx5Rm9sZGVyRXhjZXB0aW9uIHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIGZvbGRlciBhbmQgbm8gZGV0YWlsIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZm9sZGVyCXRoZSBGb2xkZXIKKyAgICAgKiBAc2luY2UgCQlKYXZhTWFpbCAxLjIKKyAgICAgKi8KKyAgICBwdWJsaWMgUmVhZE9ubHlGb2xkZXJFeGNlcHRpb24oRm9sZGVyIGZvbGRlcikgeworCXRoaXMoZm9sZGVyLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgUmVhZE9ubHlGb2xkZXJFeGNlcHRpb24gd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogZGV0YWlsIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZm9sZGVyIAlUaGUgRm9sZGVyCisgICAgICogQHBhcmFtIG1lc3NhZ2UJVGhlIGRldGFpbGVkIGVycm9yIG1lc3NhZ2UKKyAgICAgKiBAc2luY2UgCQlKYXZhTWFpbCAxLjIKKyAgICAgKi8KKyAgICBwdWJsaWMgUmVhZE9ubHlGb2xkZXJFeGNlcHRpb24oRm9sZGVyIGZvbGRlciwgU3RyaW5nIG1lc3NhZ2UpIHsKKwlzdXBlcihtZXNzYWdlKTsKKwl0aGlzLmZvbGRlciA9IGZvbGRlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgUmVhZE9ubHlGb2xkZXJFeGNlcHRpb24gd2l0aCB0aGUgc3BlY2lmaWVkCisgICAgICogZGV0YWlsIG1lc3NhZ2UgYW5kIGVtYmVkZGVkIGV4Y2VwdGlvbi4gIFRoZSBleGNlcHRpb24gaXMgY2hhaW5lZAorICAgICAqIHRvIHRoaXMgZXhjZXB0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIGZvbGRlciAJVGhlIEZvbGRlcgorICAgICAqIEBwYXJhbSBtZXNzYWdlCVRoZSBkZXRhaWxlZCBlcnJvciBtZXNzYWdlCisgICAgICogQHBhcmFtIGUJCVRoZSBlbWJlZGRlZCBleGNlcHRpb24KKyAgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuNQorICAgICAqLworICAgIHB1YmxpYyBSZWFkT25seUZvbGRlckV4Y2VwdGlvbihGb2xkZXIgZm9sZGVyLCBTdHJpbmcgbWVzc2FnZSwgRXhjZXB0aW9uIGUpIHsKKwlzdXBlcihtZXNzYWdlLCBlKTsKKwl0aGlzLmZvbGRlciA9IGZvbGRlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBGb2xkZXIgb2JqZWN0LgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgRm9sZGVyCisgICAgICogQHNpbmNlIAkJSmF2YU1haWwgMS4yCisgICAgICovCisgICAgcHVibGljIEZvbGRlciBnZXRGb2xkZXIoKSB7CisJcmV0dXJuIGZvbGRlcjsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9TZW5kRmFpbGVkRXhjZXB0aW9uLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9TZW5kRmFpbGVkRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWQ3MzQ4MAotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL1NlbmRGYWlsZWRFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDExNiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsOworCisvKioKKyAqIFRoaXMgZXhjZXB0aW9uIGlzIHRocm93biB3aGVuIHRoZSBtZXNzYWdlIGNhbm5vdCBiZSBzZW50LjxwPgorICogCisgKiBUaGUgZXhjZXB0aW9uIGluY2x1ZGVzIHRob3NlIGFkZHJlc3NlcyB0byB3aGljaCB0aGUgbWVzc2FnZSBjb3VsZCBub3QgYmUKKyAqIHNlbnQgYXMgd2VsbCBhcyB0aGUgdmFsaWQgYWRkcmVzc2VzIHRvIHdoaWNoIHRoZSBtZXNzYWdlIHdhcyBzZW50IGFuZAorICogdmFsaWQgYWRkcmVzc2VzIHRvIHdoaWNoIHRoZSBtZXNzYWdlIHdhcyBub3Qgc2VudC4KKyAqCisgKiBAc2VlCWphdmF4Lm1haWwuVHJhbnNwb3J0I3NlbmQKKyAqIEBzZWUJamF2YXgubWFpbC5UcmFuc3BvcnQjc2VuZE1lc3NhZ2UKKyAqIEBzZWUJamF2YXgubWFpbC5ldmVudC5UcmFuc3BvcnRFdmVudAorICoKKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKiBAYXV0aG9yIE1heCBTcGl2YWsKKyAqLworCitwdWJsaWMgY2xhc3MgU2VuZEZhaWxlZEV4Y2VwdGlvbiBleHRlbmRzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisgICAgdHJhbnNpZW50IHByb3RlY3RlZCBBZGRyZXNzW10gaW52YWxpZDsKKyAgICB0cmFuc2llbnQgcHJvdGVjdGVkIEFkZHJlc3NbXSB2YWxpZFNlbnQ7CisgICAgdHJhbnNpZW50IHByb3RlY3RlZCBBZGRyZXNzW10gdmFsaWRVbnNlbnQ7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNjQ1NzUzMTYyMTY4MjM3MjkxM0w7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgU2VuZEZhaWxlZEV4Y2VwdGlvbiB3aXRoIG5vIGRldGFpbCBtZXNzYWdlLgorICAgICAqLworICAgIHB1YmxpYyBTZW5kRmFpbGVkRXhjZXB0aW9uKCkgeworCXN1cGVyKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIFNlbmRGYWlsZWRFeGNlcHRpb24gd2l0aCB0aGUgc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlLgorICAgICAqIEBwYXJhbSBzCQl0aGUgZGV0YWlsIG1lc3NhZ2UKKyAgICAgKi8KKyAgICBwdWJsaWMgU2VuZEZhaWxlZEV4Y2VwdGlvbihTdHJpbmcgcykgeworCXN1cGVyKHMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBTZW5kRmFpbGVkRXhjZXB0aW9uIHdpdGggdGhlIHNwZWNpZmllZCAKKyAgICAgKiBFeGNlcHRpb24gYW5kIGRldGFpbCBtZXNzYWdlLiBUaGUgc3BlY2lmaWVkIGV4Y2VwdGlvbiBpcyBjaGFpbmVkCisgICAgICogdG8gdGhpcyBleGNlcHRpb24uCisgICAgICogQHBhcmFtIHMJCXRoZSBkZXRhaWwgbWVzc2FnZQorICAgICAqIEBwYXJhbSBlCQl0aGUgZW1iZWRkZWQgZXhjZXB0aW9uCisgICAgICogQHNlZQkjZ2V0TmV4dEV4Y2VwdGlvbgorICAgICAqIEBzZWUJI3NldE5leHRFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgU2VuZEZhaWxlZEV4Y2VwdGlvbihTdHJpbmcgcywgRXhjZXB0aW9uIGUpIHsKKwlzdXBlcihzLCBlKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBTZW5kRmFpbGVkRXhjZXB0aW9uIHdpdGggdGhlIHNwZWNpZmllZCBzdHJpbmcKKyAgICAgKiBhbmQgdGhlIHNwZWNpZmllZCBhZGRyZXNzIG9iamVjdHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbXNnCXRoZSBkZXRhaWwgbWVzc2FnZQorICAgICAqIEBwYXJhbSBleCAgICAgICAgdGhlIGVtYmVkZGVkIGV4Y2VwdGlvbgorICAgICAqIEBwYXJhbSB2YWxpZFNlbnQgdmFsaWQgYWRkcmVzc2VzIHRvIHdoaWNoIG1lc3NhZ2Ugd2FzIHNlbnQKKyAgICAgKiBAcGFyYW0gdmFsaWRVbnNlbnQgdmFsaWQgYWRkcmVzc2VzIHRvIHdoaWNoIG1lc3NhZ2Ugd2FzIG5vdCBzZW50CisgICAgICogQHBhcmFtIGludmFsaWQgCXRoZSBpbnZhbGlkIGFkZHJlc3NlcworICAgICAqIEBzZWUJI2dldE5leHRFeGNlcHRpb24KKyAgICAgKiBAc2VlCSNzZXROZXh0RXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFNlbmRGYWlsZWRFeGNlcHRpb24oU3RyaW5nIG1zZywgRXhjZXB0aW9uIGV4LCBBZGRyZXNzW10gdmFsaWRTZW50LCAKKwkJCSAgICAgICBBZGRyZXNzW10gdmFsaWRVbnNlbnQsIEFkZHJlc3NbXSBpbnZhbGlkKSB7CisJc3VwZXIobXNnLCBleCk7CisJdGhpcy52YWxpZFNlbnQgPSB2YWxpZFNlbnQ7CisJdGhpcy52YWxpZFVuc2VudCA9IHZhbGlkVW5zZW50OworCXRoaXMuaW52YWxpZCA9IGludmFsaWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBhZGRyZXNzZXMgdG8gd2hpY2ggdGhpcyBtZXNzYWdlIHdhcyBzZW50IHN1Y2Nlc2Z1bGx5LgorICAgICAqIEByZXR1cm4gQWRkcmVzc2VzIHRvIHdoaWNoIHRoZSBtZXNzYWdlIHdhcyBzZW50IHN1Y2Nlc3NmdWxseSBvciBudWxsCisgICAgICovCisgICAgcHVibGljIEFkZHJlc3NbXSBnZXRWYWxpZFNlbnRBZGRyZXNzZXMoKSB7CisJcmV0dXJuIHZhbGlkU2VudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIGFkZHJlc3NlcyB0aGF0IGFyZSB2YWxpZCBidXQgdG8gd2hpY2ggdGhpcyBtZXNzYWdlIAorICAgICAqIHdhcyBub3Qgc2VudC4KKyAgICAgKiBAcmV0dXJuIEFkZHJlc3NlcyB0aGF0IGFyZSB2YWxpZCBidXQgdG8gd2hpY2ggdGhlIG1lc3NhZ2Ugd2FzIAorICAgICAqICAgICAgICAgbm90IHNlbnQgc3VjY2Vzc2Z1bGx5IG9yIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgQWRkcmVzc1tdIGdldFZhbGlkVW5zZW50QWRkcmVzc2VzKCkgeworCXJldHVybiB2YWxpZFVuc2VudDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIGFkZHJlc3NlcyB0byB3aGljaCB0aGlzIG1lc3NhZ2UgY291bGQgbm90IGJlIHNlbnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIEFkZHJlc3NlcyB0byB3aGljaCB0aGUgbWVzc2FnZSBzZW5kaW5nIGZhaWxlZCBvciBudWxsOworICAgICAqLworICAgIHB1YmxpYyBBZGRyZXNzW10gZ2V0SW52YWxpZEFkZHJlc3NlcygpIHsKKwlyZXR1cm4gaW52YWxpZDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9TZXJ2aWNlLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9TZXJ2aWNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWM5ZTIwYwotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL1NlcnZpY2UuamF2YQpAQCAtMCwwICsxLDY1NyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsOworCitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmEubmV0Lio7CitpbXBvcnQgamF2YS51dGlsLio7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3I7CitpbXBvcnQgamF2YXgubWFpbC5ldmVudC4qOworCisvKioKKyAqIEFuIGFic3RyYWN0IGNsYXNzIHRoYXQgY29udGFpbnMgdGhlIGZ1bmN0aW9uYWxpdHkKKyAqIGNvbW1vbiB0byBtZXNzYWdpbmcgc2VydmljZXMsIHN1Y2ggYXMgc3RvcmVzIGFuZCB0cmFuc3BvcnRzLiA8cD4KKyAqIEEgbWVzc2FnaW5nIHNlcnZpY2UgaXMgY3JlYXRlZCBmcm9tIGEgPGNvZGU+U2Vzc2lvbjwvY29kZT4gYW5kIGlzCisgKiBuYW1lZCB1c2luZyBhIDxjb2RlPlVSTE5hbWU8L2NvZGU+LiAgQSBzZXJ2aWNlIG11c3QgYmUgY29ubmVjdGVkCisgKiBiZWZvcmUgaXQgY2FuIGJlIHVzZWQuICBDb25uZWN0aW9uIGV2ZW50cyBhcmUgc2VudCB0byByZWZsZWN0CisgKiBpdHMgY29ubmVjdGlvbiBzdGF0dXMuCisgKgorICogQGF1dGhvciBDaHJpc3RvcGhlciBDb3R0b24KKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKiBAYXV0aG9yIEthbndhciBPYmVyb2kKKyAqLworCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgU2VydmljZSBpbXBsZW1lbnRzIEF1dG9DbG9zZWFibGUgeworCisgICAgLyoqCisgICAgICogVGhlIHNlc3Npb24gZnJvbSB3aGljaCB0aGlzIHNlcnZpY2Ugd2FzIGNyZWF0ZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIFNlc3Npb24Jc2Vzc2lvbjsKKworICAgIC8qKgorICAgICAqIFRoZSA8Y29kZT5VUkxOYW1lPC9jb2RlPiBvZiB0aGlzIHNlcnZpY2UuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvbGF0aWxlIFVSTE5hbWUJdXJsID0gbnVsbDsKKworICAgIC8qKgorICAgICAqIERlYnVnIGZsYWcgZm9yIHRoaXMgc2VydmljZS4gIFNldCBmcm9tIHRoZSBzZXNzaW9uJ3MgZGVidWcKKyAgICAgKiBmbGFnIHdoZW4gdGhpcyBzZXJ2aWNlIGlzIGNyZWF0ZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4JZGVidWcgPSBmYWxzZTsKKworICAgIHByaXZhdGUgYm9vbGVhbgljb25uZWN0ZWQgPSBmYWxzZTsKKworICAgIC8qCisgICAgICogY29ubmVjdGlvbkxpc3RlbmVycyBpcyBhIFZlY3RvciwgaW5pdGlhbGl6ZWQgaGVyZSwKKyAgICAgKiBiZWNhdXNlIHdlIGRlcGVuZCBvbiBpdCBhbHdheXMgZXhpc3RpbmcgYW5kIGRlcGVuZAorICAgICAqIG9uIHRoZSBzeW5jaHJvbml6YXRpb24gdGhhdCBWZWN0b3IgcHJvdmlkZXMuCisgICAgICogKFN5Y2hyb25pemluZyBvbiB0aGUgU2VydmljZSBvYmplY3QgaXRzZWxmIGNhbiBjYXVzZQorICAgICAqIGRlYWRsb2NrcyB3aGVuIG5vdGlmeWluZyBsaXN0ZW5lcnMuKQorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgVmVjdG9yPENvbm5lY3Rpb25MaXN0ZW5lcj4gY29ubmVjdGlvbkxpc3RlbmVycworCSAgICA9IG5ldyBWZWN0b3I8PigpOworCisgICAgLyoqCisgICAgICogVGhlIHF1ZXVlIG9mIGV2ZW50cyB0byBiZSBkZWxpdmVyZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBFdmVudFF1ZXVlIHE7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAgKgorICAgICAqIEBwYXJhbQlzZXNzaW9uIFNlc3Npb24gb2JqZWN0IGZvciB0aGlzIHNlcnZpY2UKKyAgICAgKiBAcGFyYW0JdXJsbmFtZQlVUkxOYW1lIG9iamVjdCB0byBiZSB1c2VkIGZvciB0aGlzIHNlcnZpY2UKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU2VydmljZShTZXNzaW9uIHNlc3Npb24sIFVSTE5hbWUgdXJsbmFtZSkgeworCXRoaXMuc2Vzc2lvbiA9IHNlc3Npb247CisJZGVidWcgPSBzZXNzaW9uLmdldERlYnVnKCk7CisJdXJsID0gdXJsbmFtZTsKKworCS8qCisJICogSW5pdGlhbGl6ZSB0aGUgVVJMTmFtZSB3aXRoIGRlZmF1bHQgdmFsdWVzLgorCSAqIFRoZSBVUkxOYW1lIHdpbGwgYmUgdXBkYXRlZCB3aGVuIGNvbm5lY3QgaXMgY2FsbGVkLgorCSAqLworCVN0cmluZyBwcm90b2NvbCA9IG51bGw7CisJU3RyaW5nIGhvc3QgPSBudWxsOworCWludCBwb3J0ID0gLTE7CisJU3RyaW5nIHVzZXIgPSBudWxsOworCVN0cmluZyBwYXNzd29yZCA9IG51bGw7CisJU3RyaW5nIGZpbGUgPSBudWxsOworCisJLy8gZ2V0IHdoYXRldmVyIGluZm9ybWF0aW9uIHdlIGNhbiBmcm9tIHRoZSBVUkwKKwkvLyBYWFggLSB1cmwgc2hvdWxkIGFsd2F5cyBiZSBub24tbnVsbCBoZXJlLCBTZXNzaW9uCisJLy8gICAgICAgcGFzc2VzIGl0IGludG8gdGhlIGNvbnN0cnVjdG9yCisJaWYgKHVybCAhPSBudWxsKSB7CisJICAgIHByb3RvY29sID0gdXJsLmdldFByb3RvY29sKCk7CisJICAgIGhvc3QgPSB1cmwuZ2V0SG9zdCgpOworCSAgICBwb3J0ID0gdXJsLmdldFBvcnQoKTsKKwkgICAgdXNlciA9IHVybC5nZXRVc2VybmFtZSgpOworCSAgICBwYXNzd29yZCA9IHVybC5nZXRQYXNzd29yZCgpOworCSAgICBmaWxlID0gdXJsLmdldEZpbGUoKTsKKwl9CisKKwkvLyB0cnkgdG8gZ2V0IHByb3RvY29sLXNwZWNpZmljIGRlZmF1bHQgcHJvcGVydGllcworCWlmIChwcm90b2NvbCAhPSBudWxsKSB7CisJICAgIGlmIChob3N0ID09IG51bGwpCisJCWhvc3QgPSBzZXNzaW9uLmdldFByb3BlcnR5KCJtYWlsLiIgKyBwcm90b2NvbCArICIuaG9zdCIpOworCSAgICBpZiAodXNlciA9PSBudWxsKQorCQl1c2VyID0gc2Vzc2lvbi5nZXRQcm9wZXJ0eSgibWFpbC4iICsgcHJvdG9jb2wgKyAiLnVzZXIiKTsKKwl9CisKKwkvLyB0cnkgdG8gZ2V0IG1haWwtd2lkZSBkZWZhdWx0IHByb3BlcnRpZXMKKwlpZiAoaG9zdCA9PSBudWxsKQorCSAgICBob3N0ID0gc2Vzc2lvbi5nZXRQcm9wZXJ0eSgibWFpbC5ob3N0Iik7CisKKwlpZiAodXNlciA9PSBudWxsKQorCSAgICB1c2VyID0gc2Vzc2lvbi5nZXRQcm9wZXJ0eSgibWFpbC51c2VyIik7CisKKwkvLyB0cnkgdXNpbmcgdGhlIHN5c3RlbSB1c2VybmFtZQorCWlmICh1c2VyID09IG51bGwpIHsKKwkgICAgdHJ5IHsKKwkJdXNlciA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgidXNlci5uYW1lIik7CisJICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHNleCkgeworCQkvLyBYWFggLSBpdCdzIG5vdCB3b3J0aCBjcmVhdGluZyBhIE1haWxMb2dnZXIganVzdCBmb3IgdGhpcworCQkvL2xvZ2dlci5sb2coTGV2ZWwuQ09ORklHLCAiQ2FuJ3QgZ2V0IHVzZXIubmFtZSBwcm9wZXJ0eSIsIHNleCk7CisJICAgIH0KKwl9CisKKwl1cmwgPSBuZXcgVVJMTmFtZShwcm90b2NvbCwgaG9zdCwgcG9ydCwgZmlsZSwgdXNlciwgcGFzc3dvcmQpOworCisJLy8gY3JlYXRlIG9yIGNob29zZSB0aGUgYXBwcm9wcmlhdGUgZXZlbnQgcXVldWUKKwlTdHJpbmcgc2NvcGUgPQorCSAgICBzZXNzaW9uLmdldFByb3BlcnRpZXMoKS5nZXRQcm9wZXJ0eSgibWFpbC5ldmVudC5zY29wZSIsICJmb2xkZXIiKTsKKwlFeGVjdXRvciBleGVjdXRvciA9CisJCShFeGVjdXRvcilzZXNzaW9uLmdldFByb3BlcnRpZXMoKS5nZXQoIm1haWwuZXZlbnQuZXhlY3V0b3IiKTsKKwlpZiAoc2NvcGUuZXF1YWxzSWdub3JlQ2FzZSgiYXBwbGljYXRpb24iKSkKKwkgICAgcSA9IEV2ZW50UXVldWUuZ2V0QXBwbGljYXRpb25FdmVudFF1ZXVlKGV4ZWN1dG9yKTsKKwllbHNlIGlmIChzY29wZS5lcXVhbHNJZ25vcmVDYXNlKCJzZXNzaW9uIikpCisJICAgIHEgPSBzZXNzaW9uLmdldEV2ZW50UXVldWUoKTsKKwllbHNlIC8vIGlmIChzY29wZS5lcXVhbHNJZ25vcmVDYXNlKCJzdG9yZSIpIHx8CisJICAgICAvLyAgICAgc2NvcGUuZXF1YWxzSWdub3JlQ2FzZSgiZm9sZGVyIikpCisJICAgIHEgPSBuZXcgRXZlbnRRdWV1ZShleGVjdXRvcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQSBnZW5lcmljIGNvbm5lY3QgbWV0aG9kIHRoYXQgdGFrZXMgbm8gcGFyYW1ldGVycy4gU3ViY2xhc3NlcworICAgICAqIGNhbiBpbXBsZW1lbnQgdGhlIGFwcHJvcHJpYXRlIGF1dGhlbnRpY2F0aW9uIHNjaGVtZXMuIFN1YmNsYXNzZXMKKyAgICAgKiB0aGF0IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBtaWdodCB3YW50IHRvIHVzZSBzb21lIHByb3BlcnRpZXMKKyAgICAgKiBvciBtaWdodCBnZXQgaXQgaW50ZXJhY3RpdmVseSB1c2luZyBhIHBvcHVwIHdpbmRvdy4gPHA+CisgICAgICoKKyAgICAgKiBJZiB0aGUgY29ubmVjdGlvbiBpcyBzdWNjZXNzZnVsLCBhbiAib3BlbiIgPGNvZGU+Q29ubmVjdGlvbkV2ZW50PC9jb2RlPgorICAgICAqIGlzIGRlbGl2ZXJlZCB0byBhbnkgPGNvZGU+Q29ubmVjdGlvbkxpc3RlbmVyczwvY29kZT4gb24gdGhpcyBzZXJ2aWNlLiA8cD4KKyAgICAgKgorICAgICAqIE1vc3QgY2xpZW50cyBzaG91bGQganVzdCBjYWxsIHRoaXMgbWV0aG9kIHRvIGNvbm5lY3QgdG8gdGhlIHNlcnZpY2UuPHA+CisgICAgICoKKyAgICAgKiBJdCBpcyBhbiBlcnJvciB0byBjb25uZWN0IHRvIGFuIGFscmVhZHkgY29ubmVjdGVkIHNlcnZpY2UuIDxwPgorICAgICAqCisgICAgICogVGhlIGltcGxlbWVudGF0aW9uIHByb3ZpZGVkIGhlcmUgc2ltcGx5IGNhbGxzIHRoZSBmb2xsb3dpbmcKKyAgICAgKiA8Y29kZT5jb25uZWN0KFN0cmluZywgU3RyaW5nLCBTdHJpbmcpPC9jb2RlPiBtZXRob2Qgd2l0aCBudWxscy4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24gQXV0aGVudGljYXRpb25GYWlsZWRFeGNlcHRpb24JZm9yIGF1dGhlbnRpY2F0aW9uIGZhaWx1cmVzCisgICAgICogQGV4Y2VwdGlvbiBNZXNzYWdpbmdFeGNlcHRpb24JZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICogQGV4Y2VwdGlvbiBJbGxlZ2FsU3RhdGVFeGNlcHRpb24JaWYgdGhlIHNlcnZpY2UgaXMgYWxyZWFkeSBjb25uZWN0ZWQKKyAgICAgKgorICAgICAqIEBzZWUgamF2YXgubWFpbC5ldmVudC5Db25uZWN0aW9uRXZlbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjb25uZWN0KCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJY29ubmVjdChudWxsLCBudWxsLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25uZWN0IHRvIHRoZSBzcGVjaWZpZWQgYWRkcmVzcy4gVGhpcyBtZXRob2QgcHJvdmlkZXMgYSBzaW1wbGUKKyAgICAgKiBhdXRoZW50aWNhdGlvbiBzY2hlbWUgdGhhdCByZXF1aXJlcyBhIHVzZXJuYW1lIGFuZCBwYXNzd29yZC4gPHA+CisgICAgICoKKyAgICAgKiBJZiB0aGUgY29ubmVjdGlvbiBpcyBzdWNjZXNzZnVsLCBhbiAib3BlbiIgPGNvZGU+Q29ubmVjdGlvbkV2ZW50PC9jb2RlPgorICAgICAqIGlzIGRlbGl2ZXJlZCB0byBhbnkgPGNvZGU+Q29ubmVjdGlvbkxpc3RlbmVyczwvY29kZT4gb24gdGhpcyBzZXJ2aWNlLiA8cD4KKyAgICAgKgorICAgICAqIEl0IGlzIGFuIGVycm9yIHRvIGNvbm5lY3QgdG8gYW4gYWxyZWFkeSBjb25uZWN0ZWQgc2VydmljZS4gPHA+CisgICAgICoKKyAgICAgKiBUaGUgaW1wbGVtZW50YXRpb24gaW4gdGhlIFNlcnZpY2UgY2xhc3Mgd2lsbCBjb2xsZWN0IGRlZmF1bHRzCisgICAgICogZm9yIHRoZSBob3N0LCB1c2VyLCBhbmQgcGFzc3dvcmQgZnJvbSB0aGUgc2Vzc2lvbiwgZnJvbSB0aGUKKyAgICAgKiA8Y29kZT5VUkxOYW1lPC9jb2RlPiBmb3IgdGhpcyBzZXJ2aWNlLCBhbmQgZnJvbSB0aGUgc3VwcGxpZWQKKyAgICAgKiBwYXJhbWV0ZXJzIGFuZCB0aGVuIGNhbGwgdGhlIDxjb2RlPnByb3RvY29sQ29ubmVjdDwvY29kZT4gbWV0aG9kLgorICAgICAqIElmIHRoZSA8Y29kZT5wcm90b2NvbENvbm5lY3Q8L2NvZGU+IG1ldGhvZCByZXR1cm5zIDxjb2RlPmZhbHNlPC9jb2RlPiwKKyAgICAgKiB0aGUgdXNlciB3aWxsIGJlIHByb21wdGVkIGZvciBhbnkgbWlzc2luZyBpbmZvcm1hdGlvbiBhbmQgdGhlCisgICAgICogPGNvZGU+cHJvdG9jb2xDb25uZWN0PC9jb2RlPiBtZXRob2Qgd2lsbCBiZSBjYWxsZWQgYWdhaW4uICBUaGUKKyAgICAgKiBzdWJjbGFzcyBzaG91bGQgb3ZlcnJpZGUgdGhlIDxjb2RlPnByb3RvY29sQ29ubmVjdDwvY29kZT4gbWV0aG9kLgorICAgICAqIFRoZSBzdWJjbGFzcyBzaG91bGQgYWxzbyBpbXBsZW1lbnQgdGhlIDxjb2RlPmdldFVSTE5hbWU8L2NvZGU+CisgICAgICogbWV0aG9kLCBvciB1c2UgdGhlIGltcGxlbWVudGF0aW9uIGluIHRoaXMgY2xhc3MuIDxwPgorICAgICAqCisgICAgICogT24gYSBzdWNjZXNzZnVsIGNvbm5lY3Rpb24sIHRoZSA8Y29kZT5zZXRVUkxOYW1lPC9jb2RlPiBtZXRob2QgaXMKKyAgICAgKiBjYWxsZWQgd2l0aCBhIFVSTE5hbWUgdGhhdCBpbmNsdWRlcyB0aGUgaW5mb3JtYXRpb24gdXNlZCB0byBtYWtlCisgICAgICogdGhlIGNvbm5lY3Rpb24sIGluY2x1ZGluZyB0aGUgcGFzc3dvcmQuIDxwPgorICAgICAqCisgICAgICogSWYgdGhlIHVzZXJuYW1lIHBhc3NlZCBpbiBpcyBudWxsLCBhIGRlZmF1bHQgdmFsdWUgd2lsbCBiZSBjaG9zZW4KKyAgICAgKiBhcyBkZXNjcmliZWQgYWJvdmUuCisgICAgICoKKyAgICAgKiBJZiB0aGUgcGFzc3dvcmQgcGFzc2VkIGluIGlzIG51bGwgYW5kIHRoaXMgaXMgdGhlIGZpcnN0IHN1Y2Nlc3NmdWwKKyAgICAgKiBjb25uZWN0aW9uIHRvIHRoaXMgc2VydmljZSwgdGhlIHVzZXIgbmFtZSBhbmQgdGhlIHBhc3N3b3JkCisgICAgICogY29sbGVjdGVkIGZyb20gdGhlIHVzZXIgd2lsbCBiZSBzYXZlZCBhcyBkZWZhdWx0cyBmb3Igc3Vic2VxdWVudAorICAgICAqIGNvbm5lY3Rpb24gYXR0ZW1wdHMgdG8gdGhpcyBzYW1lIHNlcnZpY2Ugd2hlbiB1c2luZyBvdGhlciBTZXJ2aWNlIG9iamVjdAorICAgICAqIGluc3RhbmNlcyAodGhlIGNvbm5lY3Rpb24gaW5mb3JtYXRpb24gaXMgdHlwaWNhbGx5IGFsd2F5cyBzYXZlZCB3aXRoaW4KKyAgICAgKiBhIHBhcnRpY3VsYXIgU2VydmljZSBvYmplY3QgaW5zdGFuY2UpLiAgVGhlIHBhc3N3b3JkIGlzIHNhdmVkIHVzaW5nIHRoZQorICAgICAqIFNlc3Npb24gbWV0aG9kIDxjb2RlPnNldFBhc3N3b3JkQXV0aGVudGljYXRpb248L2NvZGU+LiAgSWYgdGhlCisgICAgICogcGFzc3dvcmQgcGFzc2VkIGluIGlzIG5vdCBudWxsLCBpdCBpcyBub3Qgc2F2ZWQsIG9uIHRoZSBhc3N1bXB0aW9uCisgICAgICogdGhhdCB0aGUgYXBwbGljYXRpb24gaXMgbWFuYWdpbmcgcGFzc3dvcmRzIGV4cGxpY2l0bHkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaG9zdCAJdGhlIGhvc3QgdG8gY29ubmVjdCB0bworICAgICAqIEBwYXJhbSB1c2VyCXRoZSB1c2VyIG5hbWUKKyAgICAgKiBAcGFyYW0gcGFzc3dvcmQJdGhpcyB1c2VyJ3MgcGFzc3dvcmQKKyAgICAgKiBAZXhjZXB0aW9uIEF1dGhlbnRpY2F0aW9uRmFpbGVkRXhjZXB0aW9uCWZvciBhdXRoZW50aWNhdGlvbiBmYWlsdXJlcworICAgICAqIEBleGNlcHRpb24gTWVzc2FnaW5nRXhjZXB0aW9uCQlmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKiBAZXhjZXB0aW9uIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbglpZiB0aGUgc2VydmljZSBpcyBhbHJlYWR5IGNvbm5lY3RlZAorICAgICAqIEBzZWUgamF2YXgubWFpbC5ldmVudC5Db25uZWN0aW9uRXZlbnQKKyAgICAgKiBAc2VlIGphdmF4Lm1haWwuU2Vzc2lvbiNzZXRQYXNzd29yZEF1dGhlbnRpY2F0aW9uCisgICAgICovCisgICAgcHVibGljIHZvaWQgY29ubmVjdChTdHJpbmcgaG9zdCwgU3RyaW5nIHVzZXIsIFN0cmluZyBwYXNzd29yZCkKKwkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWNvbm5lY3QoaG9zdCwgLTEsIHVzZXIsIHBhc3N3b3JkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25uZWN0IHRvIHRoZSBjdXJyZW50IGhvc3QgdXNpbmcgdGhlIHNwZWNpZmllZCB1c2VybmFtZQorICAgICAqIGFuZCBwYXNzd29yZC4gIFRoaXMgbWV0aG9kIGlzIGVxdWl2YWxlbnQgdG8gY2FsbGluZyB0aGUKKyAgICAgKiA8Y29kZT5jb25uZWN0KGhvc3QsIHVzZXIsIHBhc3N3b3JkKTwvY29kZT4gbWV0aG9kIHdpdGggbnVsbAorICAgICAqIGZvciB0aGUgaG9zdCBuYW1lLgorICAgICAqCisgICAgICogQHBhcmFtIHVzZXIgICAgICB0aGUgdXNlciBuYW1lCisgICAgICogQHBhcmFtIHBhc3N3b3JkICB0aGlzIHVzZXIncyBwYXNzd29yZAorICAgICAqIEBleGNlcHRpb24gQXV0aGVudGljYXRpb25GYWlsZWRFeGNlcHRpb24gZm9yIGF1dGhlbnRpY2F0aW9uIGZhaWx1cmVzCisgICAgICogQGV4Y2VwdGlvbiBNZXNzYWdpbmdFeGNlcHRpb24gICAgICAgICAgICBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKiBAZXhjZXB0aW9uIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGUgc2VydmljZSBpcyBhbHJlYWR5IGNvbm5lY3RlZAorICAgICAqIEBzZWUgamF2YXgubWFpbC5ldmVudC5Db25uZWN0aW9uRXZlbnQKKyAgICAgKiBAc2VlIGphdmF4Lm1haWwuU2Vzc2lvbiNzZXRQYXNzd29yZEF1dGhlbnRpY2F0aW9uCisgICAgICogQHNlZSAjY29ubmVjdChqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqIEBzaW5jZSAgICAgICAgICAgSmF2YU1haWwgMS40CisgICAgICovCisgICAgcHVibGljIHZvaWQgY29ubmVjdChTdHJpbmcgdXNlciwgU3RyaW5nIHBhc3N3b3JkKQorCSAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgY29ubmVjdChudWxsLCB1c2VyLCBwYXNzd29yZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2ltaWxhciB0byBjb25uZWN0KGhvc3QsIHVzZXIsIHBhc3N3b3JkKSBleGNlcHQgYSBzcGVjaWZpYyBwb3J0CisgICAgICogY2FuIGJlIHNwZWNpZmllZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBob3N0IAl0aGUgaG9zdCB0byBjb25uZWN0IHRvCisgICAgICogQHBhcmFtIHBvcnQJdGhlIHBvcnQgdG8gY29ubmVjdCB0byAoLTEgbWVhbnMgdGhlIGRlZmF1bHQgcG9ydCkKKyAgICAgKiBAcGFyYW0gdXNlcgl0aGUgdXNlciBuYW1lCisgICAgICogQHBhcmFtIHBhc3N3b3JkCXRoaXMgdXNlcidzIHBhc3N3b3JkCisgICAgICogQGV4Y2VwdGlvbiBBdXRoZW50aWNhdGlvbkZhaWxlZEV4Y2VwdGlvbglmb3IgYXV0aGVudGljYXRpb24gZmFpbHVyZXMKKyAgICAgKiBAZXhjZXB0aW9uIE1lc3NhZ2luZ0V4Y2VwdGlvbgkJZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICogQGV4Y2VwdGlvbiBJbGxlZ2FsU3RhdGVFeGNlcHRpb24JaWYgdGhlIHNlcnZpY2UgaXMgYWxyZWFkeSBjb25uZWN0ZWQKKyAgICAgKiBAc2VlICNjb25uZWN0KGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcpCisgICAgICogQHNlZSBqYXZheC5tYWlsLmV2ZW50LkNvbm5lY3Rpb25FdmVudAorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBjb25uZWN0KFN0cmluZyBob3N0LCBpbnQgcG9ydCwKKwkJU3RyaW5nIHVzZXIsIFN0cmluZyBwYXNzd29yZCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisKKwkvLyBzZWUgaWYgdGhlIHNlcnZpY2UgaXMgYWxyZWFkeSBjb25uZWN0ZWQKKwlpZiAoaXNDb25uZWN0ZWQoKSkKKwkgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiYWxyZWFkeSBjb25uZWN0ZWQiKTsKKworCVBhc3N3b3JkQXV0aGVudGljYXRpb24gcHc7CisJYm9vbGVhbiBjb25uZWN0ZWQgPSBmYWxzZTsKKwlib29sZWFuIHNhdmUgPSBmYWxzZTsKKwlTdHJpbmcgcHJvdG9jb2wgPSBudWxsOworCVN0cmluZyBmaWxlID0gbnVsbDsKKworCS8vIGdldCB3aGF0ZXZlciBpbmZvcm1hdGlvbiB3ZSBjYW4gZnJvbSB0aGUgVVJMCisJLy8gWFhYIC0gdXJsIHNob3VsZCBhbHdheXMgYmUgbm9uLW51bGwgaGVyZSwgU2Vzc2lvbgorCS8vICAgICAgIHBhc3NlcyBpdCBpbnRvIHRoZSBjb25zdHJ1Y3RvcgorCWlmICh1cmwgIT0gbnVsbCkgeworCSAgICBwcm90b2NvbCA9IHVybC5nZXRQcm90b2NvbCgpOworCSAgICBpZiAoaG9zdCA9PSBudWxsKQorCQlob3N0ID0gdXJsLmdldEhvc3QoKTsKKwkgICAgaWYgKHBvcnQgPT0gLTEpCisJCXBvcnQgPSB1cmwuZ2V0UG9ydCgpOworCisJICAgIGlmICh1c2VyID09IG51bGwpIHsKKwkJdXNlciA9IHVybC5nZXRVc2VybmFtZSgpOworCQlpZiAocGFzc3dvcmQgPT0gbnVsbCkJLy8gZ2V0IHBhc3N3b3JkIHRvbyBpZiB3ZSBuZWVkIGl0CisJCSAgICBwYXNzd29yZCA9IHVybC5nZXRQYXNzd29yZCgpOworCSAgICB9IGVsc2UgeworCQlpZiAocGFzc3dvcmQgPT0gbnVsbCAmJiB1c2VyLmVxdWFscyh1cmwuZ2V0VXNlcm5hbWUoKSkpCisJCSAgICAvLyBvbmx5IGdldCB0aGUgcGFzc3dvcmQgaWYgaXQgbWF0Y2hlcyB0aGUgdXNlcm5hbWUKKwkJICAgIHBhc3N3b3JkID0gdXJsLmdldFBhc3N3b3JkKCk7CisJICAgIH0KKworCSAgICBmaWxlID0gdXJsLmdldEZpbGUoKTsKKwl9CisKKwkvLyB0cnkgdG8gZ2V0IHByb3RvY29sLXNwZWNpZmljIGRlZmF1bHQgcHJvcGVydGllcworCWlmIChwcm90b2NvbCAhPSBudWxsKSB7CisJICAgIGlmIChob3N0ID09IG51bGwpCisJCWhvc3QgPSBzZXNzaW9uLmdldFByb3BlcnR5KCJtYWlsLiIgKyBwcm90b2NvbCArICIuaG9zdCIpOworCSAgICBpZiAodXNlciA9PSBudWxsKQorCQl1c2VyID0gc2Vzc2lvbi5nZXRQcm9wZXJ0eSgibWFpbC4iICsgcHJvdG9jb2wgKyAiLnVzZXIiKTsKKwl9CisKKwkvLyB0cnkgdG8gZ2V0IG1haWwtd2lkZSBkZWZhdWx0IHByb3BlcnRpZXMKKwlpZiAoaG9zdCA9PSBudWxsKQorCSAgICBob3N0ID0gc2Vzc2lvbi5nZXRQcm9wZXJ0eSgibWFpbC5ob3N0Iik7CisKKwlpZiAodXNlciA9PSBudWxsKQorCSAgICB1c2VyID0gc2Vzc2lvbi5nZXRQcm9wZXJ0eSgibWFpbC51c2VyIik7CisKKwkvLyB0cnkgdXNpbmcgdGhlIHN5c3RlbSB1c2VybmFtZQorCWlmICh1c2VyID09IG51bGwpIHsKKwkgICAgdHJ5IHsKKwkJdXNlciA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgidXNlci5uYW1lIik7CisJICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHNleCkgeworCQkvLyBYWFggLSBpdCdzIG5vdCB3b3J0aCBjcmVhdGluZyBhIE1haWxMb2dnZXIganVzdCBmb3IgdGhpcworCQkvL2xvZ2dlci5sb2coTGV2ZWwuQ09ORklHLCAiQ2FuJ3QgZ2V0IHVzZXIubmFtZSBwcm9wZXJ0eSIsIHNleCk7CisJICAgIH0KKwl9CisKKwkvLyBpZiB3ZSBkb24ndCBoYXZlIGEgcGFzc3dvcmQsIGxvb2sgZm9yIHNhdmVkIGF1dGhlbnRpY2F0aW9uIGluZm8KKwlpZiAocGFzc3dvcmQgPT0gbnVsbCAmJiB1cmwgIT0gbnVsbCkgeworCSAgICAvLyBjYW5vbmljYWxpemUgdGhlIFVSTE5hbWUKKwkgICAgc2V0VVJMTmFtZShuZXcgVVJMTmFtZShwcm90b2NvbCwgaG9zdCwgcG9ydCwgZmlsZSwgdXNlciwgbnVsbCkpOworCSAgICBwdyA9IHNlc3Npb24uZ2V0UGFzc3dvcmRBdXRoZW50aWNhdGlvbihnZXRVUkxOYW1lKCkpOworCSAgICBpZiAocHcgIT0gbnVsbCkgeworCQlpZiAodXNlciA9PSBudWxsKSB7CisJCSAgICB1c2VyID0gcHcuZ2V0VXNlck5hbWUoKTsKKwkJICAgIHBhc3N3b3JkID0gcHcuZ2V0UGFzc3dvcmQoKTsKKwkJfSBlbHNlIGlmICh1c2VyLmVxdWFscyhwdy5nZXRVc2VyTmFtZSgpKSkgeworCQkgICAgcGFzc3dvcmQgPSBwdy5nZXRQYXNzd29yZCgpOworCQl9CisJICAgIH0gZWxzZQorCQlzYXZlID0gdHJ1ZTsKKwl9CisKKwkvLyB0cnkgY29ubmVjdGluZywgaWYgdGhlIHByb3RvY29sIG5lZWRzIHNvbWUgbWlzc2luZworCS8vIGluZm9ybWF0aW9uICh1c2VyLCBwYXNzd29yZCkgaXQgd2lsbCBub3QgY29ubmVjdC4KKwkvLyBpZiBpdCB0cmllcyB0byBjb25uZWN0IGFuZCBmYWlscywgcmVtZW1iZXIgd2h5IGZvciBsYXRlci4KKwlBdXRoZW50aWNhdGlvbkZhaWxlZEV4Y2VwdGlvbiBhdXRoRXggPSBudWxsOworCXRyeSB7CisJICAgIGNvbm5lY3RlZCA9IHByb3RvY29sQ29ubmVjdChob3N0LCBwb3J0LCB1c2VyLCBwYXNzd29yZCk7CisJfSBjYXRjaCAoQXV0aGVudGljYXRpb25GYWlsZWRFeGNlcHRpb24gZXgpIHsKKwkgICAgYXV0aEV4ID0gZXg7CisJfQorCisJLy8gaWYgbm90IGNvbm5lY3RlZCwgYXNrIHRoZSB1c2VyIGFuZCB0cnkgYWdhaW4KKwlpZiAoIWNvbm5lY3RlZCkgeworCSAgICBJbmV0QWRkcmVzcyBhZGRyOworCSAgICB0cnkgeworCQlhZGRyID0gSW5ldEFkZHJlc3MuZ2V0QnlOYW1lKGhvc3QpOworCSAgICB9IGNhdGNoIChVbmtub3duSG9zdEV4Y2VwdGlvbiBlKSB7CisJCWFkZHIgPSBudWxsOworCSAgICB9CisJICAgIHB3ID0gc2Vzc2lvbi5yZXF1ZXN0UGFzc3dvcmRBdXRoZW50aWNhdGlvbigKKwkJCSAgICBhZGRyLCBwb3J0LAorCQkJICAgIHByb3RvY29sLAorCQkJICAgIG51bGwsIHVzZXIpOworCSAgICBpZiAocHcgIT0gbnVsbCkgeworCQl1c2VyID0gcHcuZ2V0VXNlck5hbWUoKTsKKwkJcGFzc3dvcmQgPSBwdy5nZXRQYXNzd29yZCgpOworCisJCS8vIGhhdmUgdGhlIHNlcnZpY2UgY29ubmVjdCBhZ2FpbgorCQljb25uZWN0ZWQgPSBwcm90b2NvbENvbm5lY3QoaG9zdCwgcG9ydCwgdXNlciwgcGFzc3dvcmQpOworCSAgICB9CisJfQorCisJLy8gaWYgd2UncmUgbm90IGNvbm5lY3RlZCBieSBub3csIHdlIGdpdmUgdXAKKwlpZiAoIWNvbm5lY3RlZCkgeworCSAgICBpZiAoYXV0aEV4ICE9IG51bGwpCisJCXRocm93IGF1dGhFeDsKKwkgICAgZWxzZSBpZiAodXNlciA9PSBudWxsKQorCQl0aHJvdyBuZXcgQXV0aGVudGljYXRpb25GYWlsZWRFeGNlcHRpb24oCisJCQkiZmFpbGVkIHRvIGNvbm5lY3QsIG5vIHVzZXIgbmFtZSBzcGVjaWZpZWQ/Iik7CisJICAgIGVsc2UgaWYgKHBhc3N3b3JkID09IG51bGwpCisJCXRocm93IG5ldyBBdXRoZW50aWNhdGlvbkZhaWxlZEV4Y2VwdGlvbigKKwkJCSJmYWlsZWQgdG8gY29ubmVjdCwgbm8gcGFzc3dvcmQgc3BlY2lmaWVkPyIpOworCSAgICBlbHNlCisJCXRocm93IG5ldyBBdXRoZW50aWNhdGlvbkZhaWxlZEV4Y2VwdGlvbigiZmFpbGVkIHRvIGNvbm5lY3QiKTsKKwl9CisKKwlzZXRVUkxOYW1lKG5ldyBVUkxOYW1lKHByb3RvY29sLCBob3N0LCBwb3J0LCBmaWxlLCB1c2VyLCBwYXNzd29yZCkpOworCisJaWYgKHNhdmUpCisJICAgIHNlc3Npb24uc2V0UGFzc3dvcmRBdXRoZW50aWNhdGlvbihnZXRVUkxOYW1lKCksCisJCQkgICAgbmV3IFBhc3N3b3JkQXV0aGVudGljYXRpb24odXNlciwgcGFzc3dvcmQpKTsKKworCS8vIHNldCBvdXIgY29ubmVjdGVkIHN0YXRlCisJc2V0Q29ubmVjdGVkKHRydWUpOworCisJLy8gZmluYWxseSwgZGVsaXZlciB0aGUgY29ubmVjdGlvbiBldmVudAorCW5vdGlmeUNvbm5lY3Rpb25MaXN0ZW5lcnMoQ29ubmVjdGlvbkV2ZW50Lk9QRU5FRCk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBUaGUgc2VydmljZSBpbXBsZW1lbnRhdGlvbiBzaG91bGQgb3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8KKyAgICAgKiBwZXJmb3JtIHRoZSBhY3R1YWwgcHJvdG9jb2wtc3BlY2lmaWMgY29ubmVjdGlvbiBhdHRlbXB0LgorICAgICAqIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIG9mIHRoZSA8Y29kZT5jb25uZWN0PC9jb2RlPiBtZXRob2QKKyAgICAgKiBjYWxscyB0aGlzIG1ldGhvZCBhcyBuZWVkZWQuIDxwPgorICAgICAqCisgICAgICogVGhlIDxjb2RlPnByb3RvY29sQ29ubmVjdDwvY29kZT4gbWV0aG9kIHNob3VsZCByZXR1cm4KKyAgICAgKiA8Y29kZT5mYWxzZTwvY29kZT4gaWYgYSB1c2VyIG5hbWUgb3IgcGFzc3dvcmQgaXMgcmVxdWlyZWQKKyAgICAgKiBmb3IgYXV0aGVudGljYXRpb24gYnV0IHRoZSBjb3JyZXNwb25kaW5nIHBhcmFtZXRlciBpcyBudWxsOworICAgICAqIHRoZSA8Y29kZT5jb25uZWN0PC9jb2RlPiBtZXRob2Qgd2lsbCBwcm9tcHQgdGhlIHVzZXIgd2hlbgorICAgICAqIG5lZWRlZCB0byBzdXBwbHkgbWlzc2luZyBpbmZvcm1hdGlvbi4gIFRoaXMgbWV0aG9kIG1heQorICAgICAqIGFsc28gcmV0dXJuIDxjb2RlPmZhbHNlPC9jb2RlPiBpZiBhdXRoZW50aWNhdGlvbiBmYWlscyBmb3IKKyAgICAgKiB0aGUgc3VwcGxpZWQgdXNlciBuYW1lIG9yIHBhc3N3b3JkLiAgQWx0ZXJuYXRpdmVseSwgdGhpcyBtZXRob2QKKyAgICAgKiBtYXkgdGhyb3cgYW4gQXV0aGVudGljYXRpb25GYWlsZWRFeGNlcHRpb24gd2hlbiBhdXRoZW50aWNhdGlvbgorICAgICAqIGZhaWxzLiAgVGhpcyBleGNlcHRpb24gbWF5IGluY2x1ZGUgYSBTdHJpbmcgbWVzc2FnZSB3aXRoIG1vcmUKKyAgICAgKiBkZXRhaWwgYWJvdXQgdGhlIGZhaWx1cmUuIDxwPgorICAgICAqCisgICAgICogVGhlIDxjb2RlPnByb3RvY29sQ29ubmVjdDwvY29kZT4gbWV0aG9kIHNob3VsZCB0aHJvdyBhbgorICAgICAqIGV4Y2VwdGlvbiB0byByZXBvcnQgZmFpbHVyZXMgbm90IHJlbGF0ZWQgdG8gYXV0aGVudGljYXRpb24sCisgICAgICogc3VjaCBhcyBhbiBpbnZhbGlkIGhvc3QgbmFtZSBvciBwb3J0IG51bWJlciwgbG9zcyBvZiBhCisgICAgICogY29ubmVjdGlvbiBkdXJpbmcgdGhlIGF1dGhlbnRpY2F0aW9uIHByb2Nlc3MsIHVuYXZhaWxhYmlsaXR5CisgICAgICogb2YgdGhlIHNlcnZlciwgZXRjLgorICAgICAqCisgICAgICogQHBhcmFtCWhvc3QJCXRoZSBuYW1lIG9mIHRoZSBob3N0IHRvIGNvbm5lY3QgdG8KKyAgICAgKiBAcGFyYW0JcG9ydAkJdGhlIHBvcnQgdG8gdXNlICgtMSBtZWFucyB1c2UgZGVmYXVsdCBwb3J0KQorICAgICAqIEBwYXJhbQl1c2VyCQl0aGUgbmFtZSBvZiB0aGUgdXNlciB0byBsb2dpbiBhcworICAgICAqIEBwYXJhbQlwYXNzd29yZAl0aGUgdXNlcidzIHBhc3N3b3JkCisgICAgICogQHJldHVybgl0cnVlIGlmIGNvbm5lY3Rpb24gc3VjY2Vzc2Z1bCwgZmFsc2UgaWYgYXV0aGVudGljYXRpb24gZmFpbGVkCisgICAgICogQGV4Y2VwdGlvbiBBdXRoZW50aWNhdGlvbkZhaWxlZEV4Y2VwdGlvbglmb3IgYXV0aGVudGljYXRpb24gZmFpbHVyZXMKKyAgICAgKiBAZXhjZXB0aW9uIE1lc3NhZ2luZ0V4Y2VwdGlvbglmb3Igbm9uLWF1dGhlbnRpY2F0aW9uIGZhaWx1cmVzCisgICAgICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gcHJvdG9jb2xDb25uZWN0KFN0cmluZyBob3N0LCBpbnQgcG9ydCwgU3RyaW5nIHVzZXIsCisJCQkJU3RyaW5nIHBhc3N3b3JkKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogSXMgdGhpcyBzZXJ2aWNlIGN1cnJlbnRseSBjb25uZWN0ZWQ/IDxwPgorICAgICAqCisgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiB1c2VzIGEgcHJpdmF0ZSBib29sZWFuIGZpZWxkIHRvIAorICAgICAqIHN0b3JlIHRoZSBjb25uZWN0aW9uIHN0YXRlLiBUaGlzIG1ldGhvZCByZXR1cm5zIHRoZSB2YWx1ZQorICAgICAqIG9mIHRoYXQgZmllbGQuIDxwPgorICAgICAqCisgICAgICogU3ViY2xhc3NlcyBtYXkgd2FudCB0byBvdmVycmlkZSB0aGlzIG1ldGhvZCB0byB2ZXJpZnkgdGhhdCBhbnkKKyAgICAgKiBjb25uZWN0aW9uIHRvIHRoZSBtZXNzYWdlIHN0b3JlIGlzIHN0aWxsIGFsaXZlLgorICAgICAqCisgICAgICogQHJldHVybgl0cnVlIGlmIHRoZSBzZXJ2aWNlIGlzIGNvbm5lY3RlZCwgZmFsc2UgaWYgaXQgaXMgbm90IGNvbm5lY3RlZAorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgYm9vbGVhbiBpc0Nvbm5lY3RlZCgpIHsKKwlyZXR1cm4gY29ubmVjdGVkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgY29ubmVjdGlvbiBzdGF0ZSBvZiB0aGlzIHNlcnZpY2UuICBUaGUgY29ubmVjdGlvbiBzdGF0ZQorICAgICAqIHdpbGwgYXV0b21hdGljYWxseSBiZSBzZXQgYnkgdGhlIHNlcnZpY2UgaW1wbGVtZW50YXRpb24gZHVyaW5nIHRoZQorICAgICAqIDxjb2RlPmNvbm5lY3Q8L2NvZGU+IGFuZCA8Y29kZT5jbG9zZTwvY29kZT4gbWV0aG9kcy4KKyAgICAgKiBTdWJjbGFzc2VzIHdpbGwgbmVlZCB0byBjYWxsIHRoaXMgbWV0aG9kIHRvIHNldCB0aGUgc3RhdGUKKyAgICAgKiBpZiB0aGUgc2VydmljZSB3YXMgYXV0b21hdGljYWxseSBkaXNjb25uZWN0ZWQuIDxwPgorICAgICAqCisgICAgICogVGhlIGltcGxlbWVudGF0aW9uIGluIHRoaXMgY2xhc3MgbWVyZWx5IHNldHMgdGhlIHByaXZhdGUgZmllbGQKKyAgICAgKiByZXR1cm5lZCBieSB0aGUgPGNvZGU+aXNDb25uZWN0ZWQ8L2NvZGU+IG1ldGhvZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjb25uZWN0ZWQgdHJ1ZSBpZiB0aGUgc2VydmljZSBpcyBjb25uZWN0ZWQsCisgICAgICogICAgICAgICAgICAgICAgICBmYWxzZSBpZiBpdCBpcyBub3QgY29ubmVjdGVkCisgICAgICovCisgICAgcHJvdGVjdGVkIHN5bmNocm9uaXplZCB2b2lkIHNldENvbm5lY3RlZChib29sZWFuIGNvbm5lY3RlZCkgeworCXRoaXMuY29ubmVjdGVkID0gY29ubmVjdGVkOworICAgIH0KKworICAgIC8qKgorICAgICAqIENsb3NlIHRoaXMgc2VydmljZSBhbmQgdGVybWluYXRlIGl0cyBjb25uZWN0aW9uLiBBIGNsb3NlCisgICAgICogQ29ubmVjdGlvbkV2ZW50IGlzIGRlbGl2ZXJlZCB0byBhbnkgQ29ubmVjdGlvbkxpc3RlbmVycy4gQW55CisgICAgICogTWVzc2FnaW5nIGNvbXBvbmVudHMgKEZvbGRlcnMsIE1lc3NhZ2VzLCBldGMuKSBiZWxvbmdpbmcgdG8gdGhpcworICAgICAqIHNlcnZpY2UgYXJlIGludmFsaWQgYWZ0ZXIgdGhpcyBzZXJ2aWNlIGlzIGNsb3NlZC4gTm90ZSB0aGF0IHRoZSBzZXJ2aWNlCisgICAgICogaXMgY2xvc2VkIGV2ZW4gaWYgdGhpcyBtZXRob2QgdGVybWluYXRlcyBhYm5vcm1hbGx5IGJ5IHRocm93aW5nCisgICAgICogYSBNZXNzYWdpbmdFeGNlcHRpb24uIDxwPgorICAgICAqCisgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiB1c2VzIDxjb2RlPnNldENvbm5lY3RlZChmYWxzZSk8L2NvZGU+IHRvIHNldAorICAgICAqIHRoaXMgc2VydmljZSdzIGNvbm5lY3RlZCBzdGF0ZSB0byA8Y29kZT5mYWxzZTwvY29kZT4uIEl0IHdpbGwgdGhlbgorICAgICAqIHNlbmQgYSBjbG9zZSBDb25uZWN0aW9uRXZlbnQgdG8gYW55IHJlZ2lzdGVyZWQgQ29ubmVjdGlvbkxpc3RlbmVycy4KKyAgICAgKiBTdWJjbGFzc2VzIG92ZXJyaWRpbmcgdGhpcyBtZXRob2QgdG8gZG8gaW1wbGVtZW50YXRpb24gc3BlY2lmaWMKKyAgICAgKiBjbGVhbnVwIHNob3VsZCBjYWxsIHRoaXMgbWV0aG9kIGFzIGEgbGFzdCBzdGVwIHRvIGluc3VyZSBldmVudAorICAgICAqIG5vdGlmaWNhdGlvbiwgcHJvYmFibHkgYnkgaW5jbHVkaW5nIGEgY2FsbCB0byA8Y29kZT5zdXBlci5jbG9zZSgpPC9jb2RlPgorICAgICAqIGluIGEgPGNvZGU+ZmluYWxseTwvY29kZT4gY2xhdXNlLgorICAgICAqCisgICAgICogQHNlZSBqYXZheC5tYWlsLmV2ZW50LkNvbm5lY3Rpb25FdmVudAorICAgICAqIEB0aHJvd3MJTWVzc2FnaW5nRXhjZXB0aW9uCWZvciBlcnJvcnMgd2hpbGUgY2xvc2luZworICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBjbG9zZSgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXNldENvbm5lY3RlZChmYWxzZSk7CisJbm90aWZ5Q29ubmVjdGlvbkxpc3RlbmVycyhDb25uZWN0aW9uRXZlbnQuQ0xPU0VEKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYSBVUkxOYW1lIHJlcHJlc2VudGluZyB0aGlzIHNlcnZpY2UuICBUaGUgcmV0dXJuZWQgVVJMTmFtZQorICAgICAqIGRvZXMgPGVtPm5vdDwvZW0+IGluY2x1ZGUgdGhlIHBhc3N3b3JkIGZpZWxkLiAgPHA+CisgICAgICoKKyAgICAgKiBTdWJjbGFzc2VzIHNob3VsZCBvbmx5IG92ZXJyaWRlIHRoaXMgbWV0aG9kIGlmIHRoZWlyCisgICAgICogVVJMTmFtZSBkb2VzIG5vdCBmb2xsb3cgdGhlIHN0YW5kYXJkIGZvcm1hdC4gPHA+CisgICAgICoKKyAgICAgKiBUaGUgaW1wbGVtZW50YXRpb24gaW4gdGhlIFNlcnZpY2UgY2xhc3MgcmV0dXJucyAodXN1YWxseSBhIGNvcHkgb2YpCisgICAgICogdGhlIDxjb2RlPnVybDwvY29kZT4gZmllbGQgd2l0aCB0aGUgcGFzc3dvcmQgYW5kIGZpbGUgaW5mb3JtYXRpb24KKyAgICAgKiBzdHJpcHBlZCBvdXQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBVUkxOYW1lIHJlcHJlc2VudGluZyB0aGlzIHNlcnZpY2UKKyAgICAgKiBAc2VlCVVSTE5hbWUKKyAgICAgKi8KKyAgICBwdWJsaWMgVVJMTmFtZSBnZXRVUkxOYW1lKCkgeworCVVSTE5hbWUgdXJsID0gdGhpcy51cmw7CS8vIHNuYXBzaG90CisJaWYgKHVybCAhPSBudWxsICYmICh1cmwuZ2V0UGFzc3dvcmQoKSAhPSBudWxsIHx8IHVybC5nZXRGaWxlKCkgIT0gbnVsbCkpCisJICAgIHJldHVybiBuZXcgVVJMTmFtZSh1cmwuZ2V0UHJvdG9jb2woKSwgdXJsLmdldEhvc3QoKSwKKwkJCXVybC5nZXRQb3J0KCksIG51bGwgLyogbm8gZmlsZSAqLywKKwkJCXVybC5nZXRVc2VybmFtZSgpLCBudWxsIC8qIG5vIHBhc3N3b3JkICovKTsKKwllbHNlCisJICAgIHJldHVybiB1cmw7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBVUkxOYW1lIHJlcHJlc2VudGluZyB0aGlzIHNlcnZpY2UuCisgICAgICogTm9ybWFsbHkgdXNlZCB0byB1cGRhdGUgdGhlIDxjb2RlPnVybDwvY29kZT4gZmllbGQKKyAgICAgKiBhZnRlciBhIHNlcnZpY2UgaGFzIHN1Y2Nlc3NmdWxseSBjb25uZWN0ZWQuIDxwPgorICAgICAqCisgICAgICogU3ViY2xhc3NlcyBzaG91bGQgb25seSBvdmVycmlkZSB0aGlzIG1ldGhvZCBpZiB0aGVpcgorICAgICAqIFVSTCBkb2VzIG5vdCBmb2xsb3cgdGhlIHN0YW5kYXJkIGZvcm1hdC4gIEluIHBhcnRpY3VsYXIsCisgICAgICogc3ViY2xhc3NlcyBzaG91bGQgb3ZlcnJpZGUgdGhpcyBtZXRob2QgaWYgdGhlaXIgVVJMCisgICAgICogZG9lcyBub3QgcmVxdWlyZSBhbGwgdGhlIHBvc3NpYmxlIGZpZWxkcyBzdXBwb3J0ZWQgYnkKKyAgICAgKiA8Y29kZT5VUkxOYW1lPC9jb2RlPjsgYSBuZXcgPGNvZGU+VVJMTmFtZTwvY29kZT4gc2hvdWxkCisgICAgICogYmUgY29uc3RydWN0ZWQgd2l0aCBhbnkgdW5uZWVkZWQgZmllbGRzIHJlbW92ZWQuIDxwPgorICAgICAqCisgICAgICogVGhlIGltcGxlbWVudGF0aW9uIGluIHRoZSBTZXJ2aWNlIGNsYXNzIHNpbXBseSBzZXRzIHRoZQorICAgICAqIDxjb2RlPnVybDwvY29kZT4gZmllbGQuCisgICAgICoKKyAgICAgKiBAcGFyYW0JdXJsCXRoZSBVUkxOYW1lCisgICAgICogQHNlZSBVUkxOYW1lCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgc2V0VVJMTmFtZShVUkxOYW1lIHVybCkgeworCXRoaXMudXJsID0gdXJsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZCBhIGxpc3RlbmVyIGZvciBDb25uZWN0aW9uIGV2ZW50cyBvbiB0aGlzIHNlcnZpY2UuIDxwPgorICAgICAqCisgICAgICogVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gcHJvdmlkZWQgaGVyZSBhZGRzIHRoaXMgbGlzdGVuZXIKKyAgICAgKiB0byBhbiBpbnRlcm5hbCBsaXN0IG9mIENvbm5lY3Rpb25MaXN0ZW5lcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbCAgICAgICAgIHRoZSBMaXN0ZW5lciBmb3IgQ29ubmVjdGlvbiBldmVudHMKKyAgICAgKiBAc2VlICAgICAgICAgICAgIGphdmF4Lm1haWwuZXZlbnQuQ29ubmVjdGlvbkV2ZW50CisgICAgICovCisgICAgcHVibGljIHZvaWQgYWRkQ29ubmVjdGlvbkxpc3RlbmVyKENvbm5lY3Rpb25MaXN0ZW5lciBsKSB7CisJY29ubmVjdGlvbkxpc3RlbmVycy5hZGRFbGVtZW50KGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZSBhIENvbm5lY3Rpb24gZXZlbnQgbGlzdGVuZXIuIDxwPgorICAgICAqCisgICAgICogVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gcHJvdmlkZWQgaGVyZSByZW1vdmVzIHRoaXMgbGlzdGVuZXIKKyAgICAgKiBmcm9tIHRoZSBpbnRlcm5hbCBsaXN0IG9mIENvbm5lY3Rpb25MaXN0ZW5lcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbCAgICAgICAgIHRoZSBsaXN0ZW5lcgorICAgICAqIEBzZWUgICAgICAgICAgICAgI2FkZENvbm5lY3Rpb25MaXN0ZW5lcgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlbW92ZUNvbm5lY3Rpb25MaXN0ZW5lcihDb25uZWN0aW9uTGlzdGVuZXIgbCkgeworCWNvbm5lY3Rpb25MaXN0ZW5lcnMucmVtb3ZlRWxlbWVudChsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBOb3RpZnkgYWxsIENvbm5lY3Rpb25MaXN0ZW5lcnMuIFNlcnZpY2UgaW1wbGVtZW50YXRpb25zIGFyZQorICAgICAqIGV4cGVjdGVkIHRvIHVzZSB0aGlzIG1ldGhvZCB0byBicm9hZGNhc3QgY29ubmVjdGlvbiBldmVudHMuIDxwPgorICAgICAqCisgICAgICogVGhlIHByb3ZpZGVkIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gcXVldWVzIHRoZSBldmVudCBpbnRvCisgICAgICogYW4gaW50ZXJuYWwgZXZlbnQgcXVldWUuIEFuIGV2ZW50IGRpc3BhdGNoZXIgdGhyZWFkIGRlcXVldWVzCisgICAgICogZXZlbnRzIGZyb20gdGhlIHF1ZXVlIGFuZCBkaXNwYXRjaGVzIHRoZW0gdG8gdGhlIHJlZ2lzdGVyZWQKKyAgICAgKiBDb25uZWN0aW9uTGlzdGVuZXJzLiBOb3RlIHRoYXQgdGhlIGV2ZW50IGRpc3BhdGNoaW5nIG9jY3VycworICAgICAqIGluIGEgc2VwYXJhdGUgdGhyZWFkLCB0aHVzIGF2b2lkaW5nIHBvdGVudGlhbCBkZWFkbG9jayBwcm9ibGVtcy4KKyAgICAgKgorICAgICAqIEBwYXJhbQl0eXBlCXRoZSBDb25uZWN0aW9uRXZlbnQgdHlwZQorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIG5vdGlmeUNvbm5lY3Rpb25MaXN0ZW5lcnMoaW50IHR5cGUpIHsKKwkvKgorCSAqIERvbid0IGJvdGhlciBxdWV1aW5nIGFuIGV2ZW50IGlmIHRoZXJlJ3Mgbm8gbGlzdGVuZXJzLgorCSAqIFllcywgbGlzdGVuZXJzIGNvdWxkIGJlIHJlbW92ZWQgYWZ0ZXIgY2hlY2tpbmcsIHdoaWNoCisJICoganVzdCBtYWtlcyB0aGlzIGFuIGV4cGVuc2l2ZSBuby1vcC4KKwkgKi8KKwlpZiAoY29ubmVjdGlvbkxpc3RlbmVycy5zaXplKCkgPiAwKSB7CisJICAgIENvbm5lY3Rpb25FdmVudCBlID0gbmV3IENvbm5lY3Rpb25FdmVudCh0aGlzLCB0eXBlKTsKKwkgICAgcXVldWVFdmVudChlLCBjb25uZWN0aW9uTGlzdGVuZXJzKTsKKwl9CisKKyAgICAgICAgLyogRml4IGZvciBicm9rZW4gSkRLMS4xLnggR2FyYmFnZSBjb2xsZWN0b3IgOgorICAgICAgICAgKiAgVGhlICdjb25zZXJ2YXRpdmUnIEdDIGluIEpESzEuMS54IG9jY2FzaW9uYWxseSBmYWlscyB0bworICAgICAgICAgKiAgZ2FyYmFnZS1jb2xsZWN0IFRocmVhZHMgd2hpY2ggYXJlIGluIHRoZSB3YWl0IHN0YXRlLgorICAgICAgICAgKiAgVGhpcyB3b3VsZCByZXN1bHQgaW4gdGhyZWFkIChhbmQgY29uc2VxdWVudGx5IG1lbW9yeSkgbGVha3MuCisgICAgICAgICAqCisgICAgICAgICAqIFdlIGF0dGVtcHQgdG8gZml4IHRoaXMgYnkgc2VuZGluZyBhICd0ZXJtaW5hdG9yJyBldmVudAorICAgICAgICAgKiB0byB0aGUgcXVldWUsIGFmdGVyIHdlJ3ZlIHNlbnQgdGhlIENMT1NFRCBldmVudC4gVGhlCisgICAgICAgICAqIHRlcm1pbmF0b3IgZXZlbnQgY2F1c2VzIHRoZSBldmVudC1kaXNwYXRjaGluZyB0aHJlYWQgdG8KKyAgICAgICAgICogc2VsZiBkZXN0cnVjdC4KKyAgICAgICAgICovCisgICAgICAgIGlmICh0eXBlID09IENvbm5lY3Rpb25FdmVudC5DTE9TRUQpCisgICAgICAgICAgICBxLnRlcm1pbmF0ZVF1ZXVlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIDxjb2RlPmdldFVSTE5hbWUudG9TdHJpbmcoKTwvY29kZT4gaWYgdGhpcyBzZXJ2aWNlIGhhcyBhIFVSTE5hbWUsCisgICAgICogb3RoZXJ3aXNlIGl0IHdpbGwgcmV0dXJuIHRoZSBkZWZhdWx0IDxjb2RlPnRvU3RyaW5nPC9jb2RlPi4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworCVVSTE5hbWUgdXJsID0gZ2V0VVJMTmFtZSgpOworCWlmICh1cmwgIT0gbnVsbCkKKwkgICAgcmV0dXJuIHVybC50b1N0cmluZygpOworCWVsc2UKKwkgICAgcmV0dXJuIHN1cGVyLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkIHRoZSBldmVudCBhbmQgdmVjdG9yIG9mIGxpc3RlbmVycyB0byB0aGUgcXVldWUgdG8gYmUgZGVsaXZlcmVkLgorICAgICAqCisgICAgICogQHBhcmFtCWV2ZW50CXRoZSBldmVudAorICAgICAqIEBwYXJhbQl2ZWN0b3IJdGhlIHZlY3RvciBvZiBsaXN0ZW5lcnMKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBxdWV1ZUV2ZW50KE1haWxFdmVudCBldmVudCwKKwkgICAgVmVjdG9yPD8gZXh0ZW5kcyBFdmVudExpc3RlbmVyPiB2ZWN0b3IpIHsKKwkvKgorICAgICAgICAgKiBDb3B5IHRoZSB2ZWN0b3IgaW4gb3JkZXIgdG8gZnJlZXplIHRoZSBzdGF0ZSBvZiB0aGUgc2V0CisgICAgICAgICAqIG9mIEV2ZW50TGlzdGVuZXJzIHRoZSBldmVudCBzaG91bGQgYmUgZGVsaXZlcmVkIHRvIHByaW9yCisgICAgICAgICAqIHRvIGRlbGl2ZXJ5LiAgVGhpcyBlbnN1cmVzIHRoYXQgYW55IGNoYW5nZXMgbWFkZSB0byB0aGUKKyAgICAgICAgICogVmVjdG9yIGZyb20gYSB0YXJnZXQgbGlzdGVuZXIncyBtZXRob2QgZHVyaW5nIHRoZSBkZWxpdmVyeQorICAgICAgICAgKiBvZiB0aGlzIGV2ZW50IHdpbGwgbm90IHRha2UgZWZmZWN0IHVudGlsIGFmdGVyIHRoZSBldmVudCBpcworICAgICAgICAgKiBkZWxpdmVyZWQuCisgICAgICAgICAqLworCUBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorCVZlY3Rvcjw/IGV4dGVuZHMgRXZlbnRMaXN0ZW5lcj4gdiA9IChWZWN0b3IpdmVjdG9yLmNsb25lKCk7CisJcS5lbnF1ZXVlKGV2ZW50LCB2KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTdG9wIHRoZSBldmVudCBkaXNwYXRjaGVyIHRocmVhZCBzbyB0aGUgcXVldWUgY2FuIGJlIGdhcmJhZ2UgY29sbGVjdGVkLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIGZpbmFsaXplKCkgdGhyb3dzIFRocm93YWJsZSB7CisJdHJ5IHsKKwkgICAgcS50ZXJtaW5hdGVRdWV1ZSgpOworCX0gZmluYWxseSB7CisJICAgIHN1cGVyLmZpbmFsaXplKCk7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFBhY2thZ2UgcHJpdmF0ZSBtZXRob2QgdG8gYWxsb3cgRm9sZGVyIHRvIGdldCB0aGUgU2Vzc2lvbiBmb3IgYSBTdG9yZS4KKyAgICAgKi8KKyAgICBTZXNzaW9uIGdldFNlc3Npb24oKSB7CisJcmV0dXJuIHNlc3Npb247CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFja2FnZSBwcml2YXRlIG1ldGhvZCB0byBhbGxvdyBGb2xkZXIgdG8gZ2V0IHRoZSBFdmVudFF1ZXVlIGZvciBhIFN0b3JlLgorICAgICAqLworICAgIEV2ZW50UXVldWUgZ2V0RXZlbnRRdWV1ZSgpIHsKKwlyZXR1cm4gcTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9TZXNzaW9uLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9TZXNzaW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTM0MTQzZQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL1Nlc3Npb24uamF2YQpAQCAtMCwwICsxLDE0MjEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbDsKKworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lio7CitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmEubmV0Lio7CitpbXBvcnQgamF2YS5zZWN1cml0eS4qOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKK2ltcG9ydCBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyOworaW1wb3J0IGphdmEudXRpbC5TZXJ2aWNlTG9hZGVyOworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkxldmVsOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dG9yOworCitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuTGluZUlucHV0U3RyZWFtOworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLk1haWxMb2dnZXI7CisKKy8qKgorICogVGhlIFNlc3Npb24gY2xhc3MgcmVwcmVzZW50cyBhIG1haWwgc2Vzc2lvbiBhbmQgaXMgbm90IHN1YmNsYXNzZWQuCisgKiBJdCBjb2xsZWN0cyB0b2dldGhlciBwcm9wZXJ0aWVzIGFuZCBkZWZhdWx0cyB1c2VkIGJ5IHRoZSBtYWlsIEFQSSdzLgorICogQSBzaW5nbGUgZGVmYXVsdCBzZXNzaW9uIGNhbiBiZSBzaGFyZWQgYnkgbXVsdGlwbGUgYXBwbGljYXRpb25zIG9uIHRoZQorICogZGVza3RvcC4gIFVuc2hhcmVkIHNlc3Npb25zIGNhbiBhbHNvIGJlIGNyZWF0ZWQuIDxwPgorICoKKyAqIFRoZSBTZXNzaW9uIGNsYXNzIHByb3ZpZGVzIGFjY2VzcyB0byB0aGUgcHJvdG9jb2wgcHJvdmlkZXJzIHRoYXQKKyAqIGltcGxlbWVudCB0aGUgPGNvZGU+U3RvcmU8L2NvZGU+LCA8Y29kZT5UcmFuc3BvcnQ8L2NvZGU+LCBhbmQgcmVsYXRlZAorICogY2xhc3Nlcy4gIFRoZSBwcm90b2NvbCBwcm92aWRlcnMgYXJlIGNvbmZpZ3VyZWQgdXNpbmcgdGhlIGZvbGxvd2luZyBmaWxlczoKKyAqIDx1bD4KKyAqICA8bGk+IDxjb2RlPmphdmFtYWlsLnByb3ZpZGVyczwvY29kZT4gYW5kCisgKiAJPGNvZGU+amF2YW1haWwuZGVmYXVsdC5wcm92aWRlcnM8L2NvZGU+IDwvbGk+CisgKiAgPGxpPiA8Y29kZT5qYXZhbWFpbC5hZGRyZXNzLm1hcDwvY29kZT4gYW5kCisgKiAJPGNvZGU+amF2YW1haWwuZGVmYXVsdC5hZGRyZXNzLm1hcDwvY29kZT4gPC9saT4KKyAqIDwvdWw+CisgKiA8cD4KKyAqIEVhY2ggPGNvZGU+amF2YW1haWwuPC9jb2RlPjxpPlg8L2k+IHJlc291cmNlIGZpbGUgaXMgc2VhcmNoZWQgZm9yIHVzaW5nCisgKiB0aHJlZSBtZXRob2RzIGluIHRoZSBmb2xsb3dpbmcgb3JkZXI6CisgKiA8b2w+CisgKiAgPGxpPiA8Y29kZT48aT5qYXZhLmhvbWU8L2k+LzxpPmNvbmY8L2k+L2phdmFtYWlsLjwvY29kZT48aT5YPC9pPiA8L2xpPgorICogIDxsaT4gPGNvZGU+TUVUQS1JTkYvamF2YW1haWwuPC9jb2RlPjxpPlg8L2k+IDwvbGk+CisgKiAgPGxpPiA8Y29kZT5NRVRBLUlORi9qYXZhbWFpbC5kZWZhdWx0LjwvY29kZT48aT5YPC9pPiA8L2xpPgorICogPC9vbD4KKyAqIDxwPgorICogKFdoZXJlIDxpPmphdmEuaG9tZTwvaT4gaXMgdGhlIHZhbHVlIG9mIHRoZSAiamF2YS5ob21lIiBTeXN0ZW0gcHJvcGVydHkKKyAqIGFuZCA8aT5jb25mPC9pPiBpcyB0aGUgZGlyZWN0b3J5IG5hbWVkICJjb25mIiBpZiBpdCBleGlzdHMsCisgKiBvdGhlcndpc2UgdGhlIGRpcmVjdG9yeSBuYW1lZCAibGliIjsgdGhlICJjb25mIiBkaXJlY3Rvcnkgd2FzCisgKiBpbnRyb2R1Y2VkIGluIEpESyAxLjkuKQorICogPHA+CisgKiBUaGUgZmlyc3QgbWV0aG9kIGFsbG93cyB0aGUgdXNlciB0byBpbmNsdWRlIHRoZWlyIG93biB2ZXJzaW9uIG9mIHRoZQorICogcmVzb3VyY2UgZmlsZSBieSBwbGFjaW5nIGl0IGluIHRoZSA8aT5jb25mPC9pPiBkaXJlY3Rvcnkgd2hlcmUgdGhlCisgKiA8Y29kZT5qYXZhLmhvbWU8L2NvZGU+IHByb3BlcnR5IHBvaW50cy4gIFRoZSBzZWNvbmQgbWV0aG9kIGFsbG93cyBhbgorICogYXBwbGljYXRpb24gdGhhdCB1c2VzIHRoZSBKYXZhTWFpbCBBUElzIHRvIGluY2x1ZGUgdGhlaXIgb3duIHJlc291cmNlCisgKiBmaWxlcyBpbiB0aGVpciBhcHBsaWNhdGlvbidzIG9yIGphciBmaWxlJ3MgPGNvZGU+TUVUQS1JTkY8L2NvZGU+CisgKiBkaXJlY3RvcnkuICBUaGUgPGNvZGU+amF2YW1haWwuZGVmYXVsdC48L2NvZGU+PGk+WDwvaT4gZGVmYXVsdCBmaWxlcworICogYXJlIHBhcnQgb2YgdGhlIEphdmFNYWlsIDxjb2RlPm1haWwuamFyPC9jb2RlPiBmaWxlIGFuZCBzaG91bGQgbm90IGJlCisgKiBzdXBwbGllZCBieSB1c2Vycy4gPHA+CisgKgorICogRmlsZSBsb2NhdGlvbiBkZXBlbmRzIHVwb24gaG93IHRoZSA8Y29kZT5DbGFzc0xvYWRlcjwvY29kZT4gbWV0aG9kCisgKiA8Y29kZT5nZXRSZXNvdXJjZTwvY29kZT4gaXMgaW1wbGVtZW50ZWQuICBVc3VhbGx5LCB0aGUKKyAqIDxjb2RlPmdldFJlc291cmNlPC9jb2RlPiBtZXRob2Qgc2VhcmNoZXMgdGhyb3VnaCBDTEFTU1BBVEggdW50aWwgaXQKKyAqIGZpbmRzIHRoZSByZXF1ZXN0ZWQgZmlsZSBhbmQgdGhlbiBzdG9wcy4gPHA+CisgKgorICogVGhlIG9yZGVyaW5nIG9mIGVudHJpZXMgaW4gdGhlIHJlc291cmNlIGZpbGVzIG1hdHRlcnMuICBJZiBtdWx0aXBsZQorICogZW50cmllcyBleGlzdCwgdGhlIGZpcnN0IGVudHJpZXMgdGFrZSBwcmVjZWRlbmNlIG92ZXIgdGhlIGxhdGVyCisgKiBlbnRyaWVzLiAgRm9yIGV4YW1wbGUsIHRoZSBmaXJzdCBJTUFQIHByb3ZpZGVyIGZvdW5kIHdpbGwgYmUgc2V0IGFzIHRoZQorICogZGVmYXVsdCBJTUFQIGltcGxlbWVudGF0aW9uIHVudGlsIGV4cGxpY2l0bHkgY2hhbmdlZCBieSB0aGUKKyAqIGFwcGxpY2F0aW9uLiAgVGhlIHVzZXItIG9yIHN5c3RlbS1zdXBwbGllZCByZXNvdXJjZSBmaWxlcyBhdWdtZW50LCB0aGV5CisgKiBkbyBub3Qgb3ZlcnJpZGUsIHRoZSBkZWZhdWx0IGZpbGVzIGluY2x1ZGVkIHdpdGggdGhlIEphdmFNYWlsIEFQSXMuCisgKiBUaGlzIG1lYW5zIHRoYXQgYWxsIGVudHJpZXMgaW4gYWxsIGZpbGVzIGxvYWRlZCB3aWxsIGJlIGF2YWlsYWJsZS4gPHA+CisgKgorICogPGI+PGNvZGU+amF2YW1haWwucHJvdmlkZXJzPC9jb2RlPjwvYj4gYW5kCisgKiA8Yj48Y29kZT5qYXZhbWFpbC5kZWZhdWx0LnByb3ZpZGVyczwvY29kZT48L2I+PHA+CisgKgorICogVGhlc2UgcmVzb3VyY2UgZmlsZXMgc3BlY2lmeSB0aGUgc3RvcmVzIGFuZCB0cmFuc3BvcnRzIHRoYXQgYXJlCisgKiBhdmFpbGFibGUgb24gdGhlIHN5c3RlbSwgYWxsb3dpbmcgYW4gYXBwbGljYXRpb24gdG8gImRpc2NvdmVyIiB3aGF0CisgKiBzdG9yZSBhbmQgdHJhbnNwb3J0IGltcGxlbWVudGF0aW9ucyBhcmUgYXZhaWxhYmxlLiAgVGhlIHByb3RvY29sCisgKiBpbXBsZW1lbnRhdGlvbnMgYXJlIGxpc3RlZCBvbmUgcGVyIGxpbmUuICBUaGUgZmlsZSBmb3JtYXQgZGVmaW5lcyBmb3VyCisgKiBhdHRyaWJ1dGVzIHRoYXQgZGVzY3JpYmUgYSBwcm90b2NvbCBpbXBsZW1lbnRhdGlvbi4gIEVhY2ggYXR0cmlidXRlIGlzCisgKiBhbiAiPSItc2VwYXJhdGVkIG5hbWUtdmFsdWUgcGFpciB3aXRoIHRoZSBuYW1lIGluIGxvd2VyY2FzZS4gRWFjaAorICogbmFtZS12YWx1ZSBwYWlyIGlzIHNlbWktY29sb24gKCI7Iikgc2VwYXJhdGVkLiAgVGhlIGZvbGxvd2luZyBuYW1lcworICogYXJlIGRlZmluZWQuCisgKgorICogPHRhYmxlIGJvcmRlcj0xPgorICogPGNhcHRpb24+CisgKiBBdHRyaWJ1dGUgTmFtZXMgaW4gUHJvdmlkZXJzIEZpbGVzCisgKiA8L2NhcHRpb24+CisgKiA8dHI+CisgKiA8dGg+TmFtZTwvdGg+PHRoPkRlc2NyaXB0aW9uPC90aD4KKyAqIDwvdHI+CisgKiA8dHI+CisgKiA8dGQ+cHJvdG9jb2w8L3RkPgorICogPHRkPk5hbWUgYXNzaWduZWQgdG8gcHJvdG9jb2wuCisgKiBGb3IgZXhhbXBsZSwgPGNvZGU+c210cDwvY29kZT4gZm9yIFRyYW5zcG9ydC48L3RkPgorICogPC90cj4KKyAqIDx0cj4KKyAqIDx0ZD50eXBlPC90ZD4KKyAqIDx0ZD5WYWxpZCBlbnRyaWVzIGFyZSA8Y29kZT5zdG9yZTwvY29kZT4gYW5kIDxjb2RlPnRyYW5zcG9ydDwvY29kZT4uPC90ZD4KKyAqIDwvdHI+CisgKiA8dHI+CisgKiA8dGQ+Y2xhc3M8L3RkPgorICogPHRkPkNsYXNzIG5hbWUgdGhhdCBpbXBsZW1lbnRzIHRoaXMgcHJvdG9jb2wuPC90ZD4KKyAqIDwvdHI+CisgKiA8dHI+CisgKiA8dGQ+dmVuZG9yPC90ZD4KKyAqIDx0ZD5PcHRpb25hbCBzdHJpbmcgaWRlbnRpZnlpbmcgdGhlIHZlbmRvci48L3RkPgorICogPC90cj4KKyAqIDx0cj4KKyAqIDx0ZD52ZXJzaW9uPC90ZD4KKyAqIDx0ZD5PcHRpb25hbCBzdHJpbmcgaWRlbnRpZnlpbmcgdGhlIHZlcnNpb24uPC90ZD4KKyAqIDwvdHI+CisgKiA8L3RhYmxlPjxwPgorICoKKyAqIEhlcmUncyBhbiBleGFtcGxlIG9mIDxjb2RlPk1FVEEtSU5GL2phdmFtYWlsLmRlZmF1bHQucHJvdmlkZXJzPC9jb2RlPgorICogZmlsZSBjb250ZW50czoKKyAqIDxwcmU+CisgKiBwcm90b2NvbD1pbWFwOyB0eXBlPXN0b3JlOyBjbGFzcz1jb20uc3VuLm1haWwuaW1hcC5JTUFQU3RvcmU7IHZlbmRvcj1PcmFjbGU7CisgKiBwcm90b2NvbD1zbXRwOyB0eXBlPXRyYW5zcG9ydDsgY2xhc3M9Y29tLnN1bi5tYWlsLnNtdHAuU01UUFRyYW5zcG9ydDsgdmVuZG9yPU9yYWNsZTsKKyAqIDwvcHJlPjxwPgorICoKKyAqIFRoZSBjdXJyZW50IGltcGxlbWVudGF0aW9uIGFsc28gc3VwcG9ydHMgY29uZmlndXJpbmcgcHJvdmlkZXJzIHVzaW5nCisgKiB0aGUgSmF2YSBTRSB7QGxpbmsgamF2YS51dGlsLlNlcnZpY2VMb2FkZXIgU2VydmljZUxvYWRlcn0gbWVjaGFuaXNtLgorICogV2hlbiBjcmVhdGluZyB5b3VyIG93biBwcm92aWRlciwgY3JlYXRlIGEge0BsaW5rIFByb3ZpZGVyfSBzdWJjbGFzcywKKyAqIGZvciBleGFtcGxlOgorICogPHByZT4KKyAqIHBhY2thZ2UgY29tLmV4YW1wbGU7CisgKgorICogaW1wb3J0IGphdmF4Lm1haWwuUHJvdmlkZXI7CisgKgorICogcHVibGljIGNsYXNzIE15UHJvdmlkZXIgZXh0ZW5kcyBQcm92aWRlciB7CisgKiAgICAgcHVibGljIE15UHJvdmlkZXIoKSB7CisgKiAgICAgICAgIHN1cGVyKFByb3ZpZGVyLlR5cGUuU1RPUkUsICJteXByb3QiLCBNeVN0b3JlLmNsYXNzLmdldE5hbWUoKSwKKyAqICAgICAgICAgICAgICJFeGFtcGxlIiwgbnVsbCk7CisgKiAgICAgfQorICogfQorICogPC9wcmU+CisgKiBUaGVuIGluY2x1ZGUgYSBmaWxlIG5hbWVkIDxjb2RlPk1FVEEtSU5GL3NlcnZpY2VzL2phdmF4Lm1haWwuUHJvdmlkZXI8L2NvZGU+CisgKiBpbiB5b3VyIGphciBmaWxlIHRoYXQgbGlzdHMgdGhlIG5hbWUgb2YgeW91ciBQcm92aWRlciBjbGFzczoKKyAqIDxwcmU+CisgKiBjb20uZXhhbXBsZS5NeVByb3ZpZGVyCisgKiA8L3ByZT4KKyAqIDxwPgorICoKKyAqIDxiPjxjb2RlPmphdmFtYWlsLmFkZHJlc3MubWFwPC9jb2RlPjwvYj4gYW5kCisgKiA8Yj48Y29kZT5qYXZhbWFpbC5kZWZhdWx0LmFkZHJlc3MubWFwPC9jb2RlPjwvYj48cD4KKyAqCisgKiBUaGVzZSByZXNvdXJjZSBmaWxlcyBtYXAgdHJhbnNwb3J0IGFkZHJlc3MgdHlwZXMgdG8gdGhlIHRyYW5zcG9ydAorICogcHJvdG9jb2wuICBUaGUgPGNvZGU+Z2V0VHlwZTwvY29kZT4gbWV0aG9kIG9mCisgKiA8Y29kZT5qYXZheC5tYWlsLkFkZHJlc3M8L2NvZGU+IHJldHVybnMgdGhlIGFkZHJlc3MgdHlwZS4gIFRoZQorICogPGNvZGU+amF2YW1haWwuYWRkcmVzcy5tYXA8L2NvZGU+IGZpbGUgbWFwcyB0aGUgdHJhbnNwb3J0IHR5cGUgdG8gdGhlCisgKiBwcm90b2NvbC4gIFRoZSBmaWxlIGZvcm1hdCBpcyBhIHNlcmllcyBvZiBuYW1lLXZhbHVlIHBhaXJzLiAgRWFjaCBrZXkKKyAqIG5hbWUgc2hvdWxkIGNvcnJlc3BvbmQgdG8gYW4gYWRkcmVzcyB0eXBlIHRoYXQgaXMgY3VycmVudGx5IGluc3RhbGxlZAorICogb24gdGhlIHN5c3RlbTsgdGhlcmUgc2hvdWxkIGFsc28gYmUgYW4gZW50cnkgZm9yIGVhY2gKKyAqIDxjb2RlPmphdmF4Lm1haWwuQWRkcmVzczwvY29kZT4gaW1wbGVtZW50YXRpb24gdGhhdCBpcyBwcmVzZW50IGlmIGl0IGlzCisgKiB0byBiZSB1c2VkLiAgRm9yIGV4YW1wbGUsIHRoZQorICogPGNvZGU+amF2YXgubWFpbC5pbnRlcm5ldC5JbnRlcm5ldEFkZHJlc3M8L2NvZGU+IG1ldGhvZAorICogPGNvZGU+Z2V0VHlwZTwvY29kZT4gcmV0dXJucyAicmZjODIyIi4gRWFjaCByZWZlcmVuY2VkIHByb3RvY29sIHNob3VsZAorICogYmUgaW5zdGFsbGVkIG9uIHRoZSBzeXN0ZW0uICBGb3IgdGhlIGNhc2Ugb2YgPGNvZGU+bmV3czwvY29kZT4sIGJlbG93LAorICogdGhlIGNsaWVudCBzaG91bGQgaW5zdGFsbCBhIFRyYW5zcG9ydCBwcm92aWRlciBzdXBwb3J0aW5nIHRoZSBubnRwCisgKiBwcm90b2NvbC4gPHA+CisgKgorICogSGVyZSBhcmUgdGhlIHR5cGljYWwgY29udGVudHMgb2YgYSA8Y29kZT5qYXZhbWFpbC5hZGRyZXNzLm1hcDwvY29kZT4gZmlsZToKKyAqIDxwcmU+CisgKiByZmM4MjI9c210cAorICogbmV3cz1ubnRwCisgKiA8L3ByZT4KKyAqCisgKiBAYXV0aG9yIEpvaG4gTWFuaQorICogQGF1dGhvciBCaWxsIFNoYW5ub24KKyAqIEBhdXRob3IgTWF4IFNwaXZhaworICovCisKK3B1YmxpYyBmaW5hbCBjbGFzcyBTZXNzaW9uIHsKKworICAgIHByaXZhdGUgZmluYWwgUHJvcGVydGllcyBwcm9wczsKKyAgICBwcml2YXRlIGZpbmFsIEF1dGhlbnRpY2F0b3IgYXV0aGVudGljYXRvcjsKKyAgICBwcml2YXRlIGZpbmFsIEhhc2h0YWJsZTxVUkxOYW1lLCBQYXNzd29yZEF1dGhlbnRpY2F0aW9uPiBhdXRoVGFibGUKKwkgICAgPSBuZXcgSGFzaHRhYmxlPD4oKTsKKyAgICBwcml2YXRlIGJvb2xlYW4gZGVidWcgPSBmYWxzZTsKKyAgICBwcml2YXRlIFByaW50U3RyZWFtIG91dDsJCQkvLyBkZWJ1ZyBvdXRwdXQgc3RyZWFtCisgICAgcHJpdmF0ZSBNYWlsTG9nZ2VyIGxvZ2dlcjsKKyAgICBwcml2YXRlIExpc3Q8UHJvdmlkZXI+IHByb3ZpZGVyczsKKyAgICBwcml2YXRlIGZpbmFsIE1hcDxTdHJpbmcsIFByb3ZpZGVyPiBwcm92aWRlcnNCeVByb3RvY29sID0gbmV3IEhhc2hNYXA8PigpOworICAgIHByaXZhdGUgZmluYWwgTWFwPFN0cmluZywgUHJvdmlkZXI+IHByb3ZpZGVyc0J5Q2xhc3NOYW1lID0gbmV3IEhhc2hNYXA8PigpOworICAgIHByaXZhdGUgZmluYWwgUHJvcGVydGllcyBhZGRyZXNzTWFwID0gbmV3IFByb3BlcnRpZXMoKTsKKwkJCQkJCS8vIG1hcHMgdHlwZSB0byBwcm90b2NvbAorICAgIHByaXZhdGUgYm9vbGVhbiBsb2FkZWRQcm92aWRlcnM7CS8vIGphdmFtYWlsLltkZWZhdWx0Ll1wcm92aWRlcnMgbG9hZGVkPworICAgIC8vIHRoZSBxdWV1ZSBvZiBldmVudHMgdG8gYmUgZGVsaXZlcmVkLCBpZiBtYWlsLmV2ZW50LnNjb3BlPT09c2Vzc2lvbgorICAgIHByaXZhdGUgZmluYWwgRXZlbnRRdWV1ZSBxOworCisgICAgLy8gVGhlIGRlZmF1bHQgc2Vzc2lvbi4KKyAgICBwcml2YXRlIHN0YXRpYyBTZXNzaW9uIGRlZmF1bHRTZXNzaW9uID0gbnVsbDsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBjb25mRGlyOworCisgICAgc3RhdGljIHsKKwlTdHJpbmcgZGlyID0gbnVsbDsKKwl0cnkgeworCSAgICBkaXIgPSBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZCgKKwkJbmV3IFByaXZpbGVnZWRBY3Rpb248U3RyaW5nPigpIHsKKwkJICAgIEBPdmVycmlkZQorCQkgICAgcHVibGljIFN0cmluZyBydW4oKSB7CisJCQlTdHJpbmcgaG9tZSA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS5ob21lIik7CisJCQlTdHJpbmcgbmV3ZGlyID0gaG9tZSArIEZpbGUuc2VwYXJhdG9yICsgImNvbmYiOworCQkJRmlsZSBjb25mID0gbmV3IEZpbGUobmV3ZGlyKTsKKwkJCWlmIChjb25mLmV4aXN0cygpKQorCQkJICAgIHJldHVybiBuZXdkaXIgKyBGaWxlLnNlcGFyYXRvcjsKKwkJCWVsc2UKKwkJCSAgICByZXR1cm4gaG9tZSArIEZpbGUuc2VwYXJhdG9yICsKKwkJCQkgICAgImxpYiIgKyBGaWxlLnNlcGFyYXRvcjsKKwkJICAgIH0KKwkJfSk7CisJfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJICAgIC8vIGlnbm9yZSBhbnkgZXhjZXB0aW9ucworCX0KKwljb25mRGlyID0gZGlyOworICAgIH0KKworICAgIC8vIENvbnN0cnVjdG9yIGlzIG5vdCBwdWJsaWMKKyAgICBwcml2YXRlIFNlc3Npb24oUHJvcGVydGllcyBwcm9wcywgQXV0aGVudGljYXRvciBhdXRoZW50aWNhdG9yKSB7CisJdGhpcy5wcm9wcyA9IHByb3BzOworCXRoaXMuYXV0aGVudGljYXRvciA9IGF1dGhlbnRpY2F0b3I7CisKKwlpZiAoQm9vbGVhbi52YWx1ZU9mKHByb3BzLmdldFByb3BlcnR5KCJtYWlsLmRlYnVnIikpLmJvb2xlYW5WYWx1ZSgpKQorCSAgICBkZWJ1ZyA9IHRydWU7CisKKwlpbml0TG9nZ2VyKCk7CisJbG9nZ2VyLmxvZyhMZXZlbC5DT05GSUcsICJKYXZhTWFpbCB2ZXJzaW9uIHswfSIsIFZlcnNpb24udmVyc2lvbik7CisKKwkvLyBnZXQgdGhlIENsYXNzIGFzc29jaWF0ZWQgd2l0aCB0aGUgQXV0aGVudGljYXRvcgorCUNsYXNzPD8+IGNsOworCWlmIChhdXRoZW50aWNhdG9yICE9IG51bGwpCisJICAgIGNsID0gYXV0aGVudGljYXRvci5nZXRDbGFzcygpOworCWVsc2UKKwkgICAgY2wgPSB0aGlzLmdldENsYXNzKCk7CisJLy8gbG9hZCB0aGUgcmVzb3VyY2VzCisJbG9hZEFkZHJlc3NNYXAoY2wpOworCXEgPSBuZXcgRXZlbnRRdWV1ZSgoRXhlY3V0b3IpcHJvcHMuZ2V0KCJtYWlsLmV2ZW50LmV4ZWN1dG9yIikpOworICAgIH0KKworICAgIHByaXZhdGUgZmluYWwgc3luY2hyb25pemVkIHZvaWQgaW5pdExvZ2dlcigpIHsKKwlsb2dnZXIgPSBuZXcgTWFpbExvZ2dlcih0aGlzLmdldENsYXNzKCksICJERUJVRyIsIGRlYnVnLCBnZXREZWJ1Z091dCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgYSBuZXcgU2Vzc2lvbiBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0JcHJvcHMJUHJvcGVydGllcyBvYmplY3QgdGhhdCBob2xkIHJlbGV2YW50IHByb3BlcnRpZXMuPGJyPgorICAgICAqICAgICAgICAgICAgICAgICAgSXQgaXMgZXhwZWN0ZWQgdGhhdCB0aGUgY2xpZW50IHN1cHBsaWVzIHZhbHVlcworICAgICAqICAgICAgICAgICAgICAgICAgZm9yIHRoZSBwcm9wZXJ0aWVzIGxpc3RlZCBpbiBBcHBlbmRpeCBBIG9mIHRoZQorICAgICAqICAgICAgICAgICAgICAgICAgSmF2YU1haWwgc3BlYyAocGFydGljdWxhcmx5ICBtYWlsLnN0b3JlLnByb3RvY29sLCAKKyAgICAgKiAgICAgICAgICAgICAgICAgIG1haWwudHJhbnNwb3J0LnByb3RvY29sLCBtYWlsLmhvc3QsIG1haWwudXNlciwgCisgICAgICogICAgICAgICAgICAgICAgICBhbmQgbWFpbC5mcm9tKSBhcyB0aGUgZGVmYXVsdHMgYXJlIHVubGlrZWx5IHRvIAorICAgICAqICAgICAgICAgICAgICAgICAgd29yayBpbiBhbGwgY2FzZXMuCisgICAgICogQHBhcmFtCWF1dGhlbnRpY2F0b3IgQXV0aGVudGljYXRvciBvYmplY3QgdXNlZCB0byBjYWxsIGJhY2sgdG8KKyAgICAgKgkJCXRoZSBhcHBsaWNhdGlvbiB3aGVuIGEgdXNlciBuYW1lIGFuZCBwYXNzd29yZCBpcworICAgICAqCQkJbmVlZGVkLgorICAgICAqIEByZXR1cm4JCWEgbmV3IFNlc3Npb24gb2JqZWN0CisgICAgICogQHNlZQlqYXZheC5tYWlsLkF1dGhlbnRpY2F0b3IKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFNlc3Npb24gZ2V0SW5zdGFuY2UoUHJvcGVydGllcyBwcm9wcywKKwkJCQkJQXV0aGVudGljYXRvciBhdXRoZW50aWNhdG9yKSB7CisJcmV0dXJuIG5ldyBTZXNzaW9uKHByb3BzLCBhdXRoZW50aWNhdG9yKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgYSBuZXcgU2Vzc2lvbiBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0JcHJvcHMJUHJvcGVydGllcyBvYmplY3QgdGhhdCBob2xkIHJlbGV2YW50IHByb3BlcnRpZXMuPGJyPgorICAgICAqICAgICAgICAgICAgICAgICAgSXQgaXMgZXhwZWN0ZWQgdGhhdCB0aGUgY2xpZW50IHN1cHBsaWVzIHZhbHVlcworICAgICAqICAgICAgICAgICAgICAgICAgZm9yIHRoZSBwcm9wZXJ0aWVzIGxpc3RlZCBpbiBBcHBlbmRpeCBBIG9mIHRoZQorICAgICAqICAgICAgICAgICAgICAgICAgSmF2YU1haWwgc3BlYyAocGFydGljdWxhcmx5ICBtYWlsLnN0b3JlLnByb3RvY29sLCAKKyAgICAgKiAgICAgICAgICAgICAgICAgIG1haWwudHJhbnNwb3J0LnByb3RvY29sLCBtYWlsLmhvc3QsIG1haWwudXNlciwgCisgICAgICogICAgICAgICAgICAgICAgICBhbmQgbWFpbC5mcm9tKSBhcyB0aGUgZGVmYXVsdHMgYXJlIHVubGlrZWx5IHRvIAorICAgICAqICAgICAgICAgICAgICAgICAgd29yayBpbiBhbGwgY2FzZXMuCisgICAgICogQHJldHVybgkJYSBuZXcgU2Vzc2lvbiBvYmplY3QKKyAgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuMgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU2Vzc2lvbiBnZXRJbnN0YW5jZShQcm9wZXJ0aWVzIHByb3BzKSB7CisJcmV0dXJuIG5ldyBTZXNzaW9uKHByb3BzLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGRlZmF1bHQgU2Vzc2lvbiBvYmplY3QuIElmIGEgZGVmYXVsdCBoYXMgbm90IHlldCBiZWVuCisgICAgICogc2V0dXAsIGEgbmV3IFNlc3Npb24gb2JqZWN0IGlzIGNyZWF0ZWQgYW5kIGluc3RhbGxlZCBhcyB0aGUgCisgICAgICogZGVmYXVsdC4gPHA+CisgICAgICoKKyAgICAgKiBTaW5jZSB0aGUgZGVmYXVsdCBzZXNzaW9uIGlzIHBvdGVudGlhbGx5IGF2YWlsYWJsZSB0byBhbGwKKyAgICAgKiBjb2RlIGV4ZWN1dGluZyBpbiB0aGUgc2FtZSBKYXZhIHZpcnR1YWwgbWFjaGluZSwgYW5kIHRoZSBzZXNzaW9uCisgICAgICogY2FuIGNvbnRhaW4gc2VjdXJpdHkgc2Vuc2l0aXZlIGluZm9ybWF0aW9uIHN1Y2ggYXMgdXNlciBuYW1lcworICAgICAqIGFuZCBwYXNzd29yZHMsIGFjY2VzcyB0byB0aGUgZGVmYXVsdCBzZXNzaW9uIGlzIHJlc3RyaWN0ZWQuCisgICAgICogVGhlIEF1dGhlbnRpY2F0b3Igb2JqZWN0LCB3aGljaCBtdXN0IGJlIGNyZWF0ZWQgYnkgdGhlIGNhbGxlciwKKyAgICAgKiBpcyB1c2VkIGluZGlyZWN0bHkgdG8gY2hlY2sgYWNjZXNzIHBlcm1pc3Npb24uICBUaGUgQXV0aGVudGljYXRvcgorICAgICAqIG9iamVjdCBwYXNzZWQgaW4gd2hlbiB0aGUgc2Vzc2lvbiBpcyBjcmVhdGVkIGlzIGNvbXBhcmVkIHdpdGgKKyAgICAgKiB0aGUgQXV0aGVudGljYXRvciBvYmplY3QgcGFzc2VkIGluIHRvIHN1YnNlcXVlbnQgcmVxdWVzdHMgdG8KKyAgICAgKiBnZXQgdGhlIGRlZmF1bHQgc2Vzc2lvbi4gIElmIGJvdGggb2JqZWN0cyBhcmUgdGhlIHNhbWUsIG9yIGFyZQorICAgICAqIGZyb20gdGhlIHNhbWUgQ2xhc3NMb2FkZXIsIHRoZSByZXF1ZXN0IGlzIGFsbG93ZWQuICBPdGhlcndpc2UsCisgICAgICogaXQgaXMgZGVuaWVkLiAgPHA+CisgICAgICoKKyAgICAgKiBOb3RlIHRoYXQgaWYgdGhlIEF1dGhlbnRpY2F0b3Igb2JqZWN0IHVzZWQgdG8gY3JlYXRlIHRoZSBzZXNzaW9uCisgICAgICogaXMgbnVsbCwgYW55b25lIGNhbiBnZXQgdGhlIGRlZmF1bHQgc2Vzc2lvbiBieSBwYXNzaW5nIGluIG51bGwuICA8cD4KKyAgICAgKgorICAgICAqIE5vdGUgYWxzbyB0aGF0IHRoZSBQcm9wZXJ0aWVzIG9iamVjdCBpcyB1c2VkIG9ubHkgdGhlIGZpcnN0IHRpbWUKKyAgICAgKiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQsIHdoZW4gYSBuZXcgU2Vzc2lvbiBvYmplY3QgaXMgY3JlYXRlZC4KKyAgICAgKiBTdWJzZXF1ZW50IGNhbGxzIHJldHVybiB0aGUgU2Vzc2lvbiBvYmplY3QgdGhhdCB3YXMgY3JlYXRlZCBieSB0aGUKKyAgICAgKiBmaXJzdCBjYWxsLCBhbmQgaWdub3JlIHRoZSBwYXNzZWQgUHJvcGVydGllcyBvYmplY3QuICBVc2UgdGhlCisgICAgICogPGNvZGU+Z2V0SW5zdGFuY2U8L2NvZGU+IG1ldGhvZCB0byBnZXQgYSBuZXcgU2Vzc2lvbiBvYmplY3QgZXZlcnkKKyAgICAgKiB0aW1lIHRoZSBtZXRob2QgaXMgY2FsbGVkLiA8cD4KKyAgICAgKgorICAgICAqIEFkZGl0aW9uYWwgc2VjdXJpdHkgUGVybWlzc2lvbiBvYmplY3RzIG1heSBiZSB1c2VkIHRvCisgICAgICogY29udHJvbCBhY2Nlc3MgdG8gdGhlIGRlZmF1bHQgc2Vzc2lvbi4gPHA+CisgICAgICoKKyAgICAgKiBJbiB0aGUgY3VycmVudCBpbXBsZW1lbnRhdGlvbiwgaWYgYSBTZWN1cml0eU1hbmFnZXIgaXMgc2V0LCB0aGUKKyAgICAgKiBjYWxsZXIgbXVzdCBoYXZlIHRoZSA8Y29kZT5SdW50aW1lUGVybWlzc2lvbigic2V0RmFjdG9yeSIpPC9jb2RlPgorICAgICAqIHBlcm1pc3Npb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0JcHJvcHMJUHJvcGVydGllcyBvYmplY3QuIFVzZWQgb25seSBpZiBhIG5ldyBTZXNzaW9uCisgICAgICoJCQlvYmplY3QgaXMgY3JlYXRlZC48YnI+CisgICAgICogICAgICAgICAgICAgICAgICBJdCBpcyBleHBlY3RlZCB0aGF0IHRoZSBjbGllbnQgc3VwcGxpZXMgdmFsdWVzCisgICAgICogICAgICAgICAgICAgICAgICBmb3IgdGhlIHByb3BlcnRpZXMgbGlzdGVkIGluIEFwcGVuZGl4IEEgb2YgdGhlCisgICAgICogICAgICAgICAgICAgICAgICBKYXZhTWFpbCBzcGVjIChwYXJ0aWN1bGFybHkgIG1haWwuc3RvcmUucHJvdG9jb2wsIAorICAgICAqICAgICAgICAgICAgICAgICAgbWFpbC50cmFuc3BvcnQucHJvdG9jb2wsIG1haWwuaG9zdCwgbWFpbC51c2VyLCAKKyAgICAgKiAgICAgICAgICAgICAgICAgIGFuZCBtYWlsLmZyb20pIGFzIHRoZSBkZWZhdWx0cyBhcmUgdW5saWtlbHkgdG8gCisgICAgICogICAgICAgICAgICAgICAgICB3b3JrIGluIGFsbCBjYXNlcy4KKyAgICAgKiBAcGFyYW0JYXV0aGVudGljYXRvciBBdXRoZW50aWNhdG9yIG9iamVjdC4gIFVzZWQgb25seSBpZiBhCisgICAgICoJCQluZXcgU2Vzc2lvbiBvYmplY3QgaXMgY3JlYXRlZC4gIE90aGVyd2lzZSwgCisgICAgICoJCQlpdCBtdXN0IG1hdGNoIHRoZSBBdXRoZW50aWNhdG9yIHVzZWQgdG8gY3JlYXRlCisgICAgICoJCQl0aGUgU2Vzc2lvbi4KKyAgICAgKiBAcmV0dXJuCQl0aGUgZGVmYXVsdCBTZXNzaW9uIG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgc3luY2hyb25pemVkIFNlc3Npb24gZ2V0RGVmYXVsdEluc3RhbmNlKFByb3BlcnRpZXMgcHJvcHMsCisJCQkJCUF1dGhlbnRpY2F0b3IgYXV0aGVudGljYXRvcikgeworCWlmIChkZWZhdWx0U2Vzc2lvbiA9PSBudWxsKSB7CisJICAgIFNlY3VyaXR5TWFuYWdlciBzZWN1cml0eSA9IFN5c3RlbS5nZXRTZWN1cml0eU1hbmFnZXIoKTsKKwkgICAgaWYgKHNlY3VyaXR5ICE9IG51bGwpCisJCXNlY3VyaXR5LmNoZWNrU2V0RmFjdG9yeSgpOworCSAgICBkZWZhdWx0U2Vzc2lvbiA9IG5ldyBTZXNzaW9uKHByb3BzLCBhdXRoZW50aWNhdG9yKTsKKwl9IGVsc2UgeworCSAgICAvLyBoYXZlIHRvIGNoZWNrIHdoZXRoZXIgY2FsbGVyIGlzIGFsbG93ZWQgdG8gc2VlIGRlZmF1bHQgc2Vzc2lvbgorCSAgICBpZiAoZGVmYXVsdFNlc3Npb24uYXV0aGVudGljYXRvciA9PSBhdXRoZW50aWNhdG9yKQorCQk7CS8vIGVpdGhlciBzYW1lIG9iamVjdCBvciBib3RoIG51bGwsIGVpdGhlciB3YXkgT0sKKwkgICAgZWxzZSBpZiAoZGVmYXVsdFNlc3Npb24uYXV0aGVudGljYXRvciAhPSBudWxsICYmCisJCSAgICBhdXRoZW50aWNhdG9yICE9IG51bGwgJiYKKwkJICAgIGRlZmF1bHRTZXNzaW9uLmF1dGhlbnRpY2F0b3IuZ2V0Q2xhc3MoKS5nZXRDbGFzc0xvYWRlcigpID09CisJCQlhdXRoZW50aWNhdG9yLmdldENsYXNzKCkuZ2V0Q2xhc3NMb2FkZXIoKSkKKwkJOwkvLyBib3RoIG9iamVjdHMgY2FtZSBmcm9tIHRoZSBzYW1lIGNsYXNzIGxvYWRlciwgT0sKKwkgICAgZWxzZQorCQkvLyBhbnl0aGluZyBlbHNlIGlzIG5vdCBhbGxvd2VkCisJCXRocm93IG5ldyBTZWN1cml0eUV4Y2VwdGlvbigiQWNjZXNzIHRvIGRlZmF1bHQgc2Vzc2lvbiBkZW5pZWQiKTsKKwl9CisKKwlyZXR1cm4gZGVmYXVsdFNlc3Npb247CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBkZWZhdWx0IFNlc3Npb24gb2JqZWN0LiBJZiBhIGRlZmF1bHQgaGFzIG5vdCB5ZXQgYmVlbgorICAgICAqIHNldHVwLCBhIG5ldyBTZXNzaW9uIG9iamVjdCBpcyBjcmVhdGVkIGFuZCBpbnN0YWxsZWQgYXMgdGhlIAorICAgICAqIGRlZmF1bHQuIDxwPgorICAgICAqCisgICAgICogTm90ZSB0aGF0IGEgZGVmYXVsdCBzZXNzaW9uIGNyZWF0ZWQgd2l0aCBubyBBdXRoZW50aWNhdG9yIGlzCisgICAgICogYXZhaWxhYmxlIHRvIGFsbCBjb2RlIGV4ZWN1dGluZyBpbiB0aGUgc2FtZSBKYXZhIHZpcnR1YWwKKyAgICAgKiBtYWNoaW5lLCBhbmQgdGhlIHNlc3Npb24gY2FuIGNvbnRhaW4gc2VjdXJpdHkgc2Vuc2l0aXZlCisgICAgICogaW5mb3JtYXRpb24gc3VjaCBhcyB1c2VyIG5hbWVzIGFuZCBwYXNzd29yZHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0JcHJvcHMJUHJvcGVydGllcyBvYmplY3QuIFVzZWQgb25seSBpZiBhIG5ldyBTZXNzaW9uCisgICAgICoJCQlvYmplY3QgaXMgY3JlYXRlZC48YnI+CisgICAgICogICAgICAgICAgICAgICAgICBJdCBpcyBleHBlY3RlZCB0aGF0IHRoZSBjbGllbnQgc3VwcGxpZXMgdmFsdWVzCisgICAgICogICAgICAgICAgICAgICAgICBmb3IgdGhlIHByb3BlcnRpZXMgbGlzdGVkIGluIEFwcGVuZGl4IEEgb2YgdGhlCisgICAgICogICAgICAgICAgICAgICAgICBKYXZhTWFpbCBzcGVjIChwYXJ0aWN1bGFybHkgIG1haWwuc3RvcmUucHJvdG9jb2wsIAorICAgICAqICAgICAgICAgICAgICAgICAgbWFpbC50cmFuc3BvcnQucHJvdG9jb2wsIG1haWwuaG9zdCwgbWFpbC51c2VyLCAKKyAgICAgKiAgICAgICAgICAgICAgICAgIGFuZCBtYWlsLmZyb20pIGFzIHRoZSBkZWZhdWx0cyBhcmUgdW5saWtlbHkgdG8gCisgICAgICogICAgICAgICAgICAgICAgICB3b3JrIGluIGFsbCBjYXNlcy4KKyAgICAgKiBAcmV0dXJuCQl0aGUgZGVmYXVsdCBTZXNzaW9uIG9iamVjdAorICAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS4yCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTZXNzaW9uIGdldERlZmF1bHRJbnN0YW5jZShQcm9wZXJ0aWVzIHByb3BzKSB7CisgICAgICAgIHJldHVybiBnZXREZWZhdWx0SW5zdGFuY2UocHJvcHMsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgZGVidWcgc2V0dGluZyBmb3IgdGhpcyBTZXNzaW9uLgorICAgICAqIDxwPgorICAgICAqIFNpbmNlIHRoZSBkZWJ1ZyBzZXR0aW5nIGNhbiBiZSB0dXJuZWQgb24gb25seSBhZnRlciB0aGUgU2Vzc2lvbgorICAgICAqIGhhcyBiZWVuIGNyZWF0ZWQsIHRvIHR1cm4gb24gZGVidWdnaW5nIGluIHRoZSBTZXNzaW9uCisgICAgICogY29uc3RydWN0b3IsIHNldCB0aGUgcHJvcGVydHkgPGNvZGU+bWFpbC5kZWJ1ZzwvY29kZT4gaW4gdGhlCisgICAgICogUHJvcGVydGllcyBvYmplY3QgcGFzc2VkIGluIHRvIHRoZSBjb25zdHJ1Y3RvciB0byB0cnVlLiAgVGhlCisgICAgICogdmFsdWUgb2YgdGhlIDxjb2RlPm1haWwuZGVidWc8L2NvZGU+IHByb3BlcnR5IGlzIHVzZWQgdG8KKyAgICAgKiBpbml0aWFsaXplIHRoZSBwZXItU2Vzc2lvbiBkZWJ1Z2dpbmcgZmxhZy4gIFN1YnNlcXVlbnQgY2FsbHMgdG8KKyAgICAgKiB0aGUgPGNvZGU+c2V0RGVidWc8L2NvZGU+IG1ldGhvZCBtYW5pcHVsYXRlIHRoZSBwZXItU2Vzc2lvbgorICAgICAqIGRlYnVnZ2luZyBmbGFnIGFuZCBoYXZlIG5vIGFmZmVjdCBvbiB0aGUgPGNvZGU+bWFpbC5kZWJ1ZzwvY29kZT4KKyAgICAgKiBwcm9wZXJ0eS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkZWJ1ZwlEZWJ1ZyBzZXR0aW5nCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHNldERlYnVnKGJvb2xlYW4gZGVidWcpIHsKKwl0aGlzLmRlYnVnID0gZGVidWc7CisJaW5pdExvZ2dlcigpOworCWxvZ2dlci5sb2coTGV2ZWwuQ09ORklHLCAic2V0RGVidWc6IEphdmFNYWlsIHZlcnNpb24gezB9IiwKKwkJCQkgICAgVmVyc2lvbi52ZXJzaW9uKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGRlYnVnIHNldHRpbmcgZm9yIHRoaXMgU2Vzc2lvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gY3VycmVudCBkZWJ1ZyBzZXR0aW5nCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIGdldERlYnVnKCkgeworCXJldHVybiBkZWJ1ZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHN0cmVhbSB0byBiZSB1c2VkIGZvciBkZWJ1Z2dpbmcgb3V0cHV0IGZvciB0aGlzIHNlc3Npb24uCisgICAgICogSWYgPGNvZGU+b3V0PC9jb2RlPiBpcyBudWxsLCA8Y29kZT5TeXN0ZW0ub3V0PC9jb2RlPiB3aWxsIGJlIHVzZWQuCisgICAgICogTm90ZSB0aGF0IGRlYnVnZ2luZyBvdXRwdXQgdGhhdCBvY2N1cnMgYmVmb3JlIGFueSBzZXNzaW9uIGlzIGNyZWF0ZWQsCisgICAgICogYXMgYSByZXN1bHQgb2Ygc2V0dGluZyB0aGUgPGNvZGU+bWFpbC5kZWJ1ZzwvY29kZT4gc3lzdGVtIHByb3BlcnR5LAorICAgICAqIHdpbGwgYWx3YXlzIGJlIHNlbnQgdG8gPGNvZGU+U3lzdGVtLm91dDwvY29kZT4uCisgICAgICoKKyAgICAgKiBAcGFyYW0Jb3V0CXRoZSBQcmludFN0cmVhbSB0byB1c2UgZm9yIGRlYnVnZ2luZyBvdXRwdXQKKyAgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuMworICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXREZWJ1Z091dChQcmludFN0cmVhbSBvdXQpIHsKKwl0aGlzLm91dCA9IG91dDsKKwlpbml0TG9nZ2VyKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc3RyZWFtIHRvIGJlIHVzZWQgZm9yIGRlYnVnZ2luZyBvdXRwdXQuICBJZiBubyBzdHJlYW0KKyAgICAgKiBoYXMgYmVlbiBzZXQsIDxjb2RlPlN5c3RlbS5vdXQ8L2NvZGU+IGlzIHJldHVybmVkLgorICAgICAqCisgICAgICogQHJldHVybgkJdGhlIFByaW50U3RyZWFtIHRvIHVzZSBmb3IgZGVidWdnaW5nIG91dHB1dAorICAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS4zCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBQcmludFN0cmVhbSBnZXREZWJ1Z091dCgpIHsKKwlpZiAob3V0ID09IG51bGwpCisJICAgIHJldHVybiBTeXN0ZW0ub3V0OworCWVsc2UKKwkgICAgcmV0dXJuIG91dDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCByZXR1cm5zIGFuIGFycmF5IG9mIGFsbCB0aGUgaW1wbGVtZW50YXRpb25zIGluc3RhbGxlZCAKKyAgICAgKiB2aWEgdGhlIGphdmFtYWlsLltkZWZhdWx0Ll1wcm92aWRlcnMgZmlsZXMgdGhhdCBjYW4KKyAgICAgKiBiZSBsb2FkZWQgdXNpbmcgdGhlIENsYXNzTG9hZGVyIGF2YWlsYWJsZSB0byB0aGlzIGFwcGxpY2F0aW9uLgorICAgICAqCisgICAgICogQHJldHVybiBBcnJheSBvZiBjb25maWd1cmVkIHByb3ZpZGVycworICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgUHJvdmlkZXJbXSBnZXRQcm92aWRlcnMoKSB7CisJTGlzdDxQcm92aWRlcj4gcGxpc3QgPSBuZXcgQXJyYXlMaXN0PFByb3ZpZGVyPigpOworCWJvb2xlYW4gbmVlZEZhbGxiYWNrID0gdHJ1ZTsKKwkvLyBmaXJzdCwgYWRkIGFsbCB0aGUgc2VydmljZXMKKwlTZXJ2aWNlTG9hZGVyPFByb3ZpZGVyPiBsb2FkZXIgPSBTZXJ2aWNlTG9hZGVyLmxvYWQoUHJvdmlkZXIuY2xhc3MpOworCWZvciAoUHJvdmlkZXIgcCA6IGxvYWRlcikgeworCSAgICBwbGlzdC5hZGQocCk7CisJICAgIG5lZWRGYWxsYmFjayA9IGZhbHNlOworCX0KKwkvLyB0aGVuLCBhZGQgYWxsIHRoZSBwcm92aWRlcnMgZnJvbSBjb25maWcgZmlsZXMKKwlpZiAoIWxvYWRlZFByb3ZpZGVycykKKwkgICAgbG9hZFByb3ZpZGVycyhuZWVkRmFsbGJhY2spOworCWlmIChwcm92aWRlcnMgIT0gbnVsbCkKKwkgICAgcGxpc3QuYWRkQWxsKHByb3ZpZGVycyk7CisJUHJvdmlkZXJbXSBfcHJvdmlkZXJzID0gbmV3IFByb3ZpZGVyW3BsaXN0LnNpemUoKV07CisJcGxpc3QudG9BcnJheShfcHJvdmlkZXJzKTsKKwlyZXR1cm4gX3Byb3ZpZGVyczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBkZWZhdWx0IFByb3ZpZGVyIGZvciB0aGUgcHJvdG9jb2wKKyAgICAgKiBzcGVjaWZpZWQuIENoZWNrcyBtYWlsLiZsdDtwcm90b2NvbCZndDsuY2xhc3MgcHJvcGVydHkKKyAgICAgKiBmaXJzdCBhbmQgaWYgaXQgZXhpc3RzLCByZXR1cm5zIHRoZSBQcm92aWRlcgorICAgICAqIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGltcGxlbWVudGF0aW9uLiBJZiBpdCBkb2Vzbid0IGV4aXN0LCAKKyAgICAgKiByZXR1cm5zIHRoZSBQcm92aWRlciB0aGF0IGFwcGVhcmVkIGZpcnN0IGluIHRoZSAKKyAgICAgKiBjb25maWd1cmF0aW9uIGZpbGVzLiBJZiBhbiBpbXBsZW1lbnRhdGlvbiBmb3IgdGhlIHByb3RvY29sIAorICAgICAqIGlzbid0IGZvdW5kLCB0aHJvd3MgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24KKyAgICAgKgorICAgICAqIEBwYXJhbSAgcHJvdG9jb2wgIENvbmZpZ3VyZWQgcHJvdG9jb2wgKGkuZS4gc210cCwgaW1hcCwgZXRjKQorICAgICAqIEByZXR1cm4gQ3VycmVudGx5IGNvbmZpZ3VyZWQgUHJvdmlkZXIgZm9yIHRoZSBzcGVjaWZpZWQgcHJvdG9jb2wKKyAgICAgKiBAZXhjZXB0aW9uCU5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIElmIGEgcHJvdmlkZXIgZm9yIHRoZSBnaXZlbgorICAgICAqCQkJcHJvdG9jb2wgaXMgbm90IGZvdW5kLgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgUHJvdmlkZXIgZ2V0UHJvdmlkZXIoU3RyaW5nIHByb3RvY29sKQorCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHsKKworCWlmIChwcm90b2NvbCA9PSBudWxsIHx8IHByb3RvY29sLmxlbmd0aCgpIDw9IDApIHsKKwkgICAgdGhyb3cgbmV3IE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uKCJJbnZhbGlkIHByb3RvY29sOiBudWxsIik7CisJfQorCisJUHJvdmlkZXIgX3Byb3ZpZGVyID0gbnVsbDsKKworCS8vIGNoZWNrIGlmIHRoZSBtYWlsLjxwcm90b2NvbD4uY2xhc3MgcHJvcGVydHkgZXhpc3RzCisJU3RyaW5nIF9jbGFzc05hbWUgPSBwcm9wcy5nZXRQcm9wZXJ0eSgibWFpbC4iK3Byb3RvY29sKyIuY2xhc3MiKTsKKwlpZiAoX2NsYXNzTmFtZSAhPSBudWxsKSB7CisJICAgIGlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FKSkgeworCQlsb2dnZXIuZmluZSgibWFpbC4iK3Byb3RvY29sKworCQkJCSAgICIuY2xhc3MgcHJvcGVydHkgZXhpc3RzIGFuZCBwb2ludHMgdG8gIiArIAorCQkJCSAgIF9jbGFzc05hbWUpOworCSAgICB9CisJICAgIF9wcm92aWRlciA9IGdldFByb3ZpZGVyQnlDbGFzc05hbWUoX2NsYXNzTmFtZSk7CisJfSAKKworCWlmIChfcHJvdmlkZXIgPT0gbnVsbCkKKwkgICAgX3Byb3ZpZGVyID0gZ2V0UHJvdmlkZXJCeVByb3RvY29sKHByb3RvY29sKTsKKworCWlmIChfcHJvdmlkZXIgPT0gbnVsbCkgeworCSAgICB0aHJvdyBuZXcgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24oIk5vIHByb3ZpZGVyIGZvciAiICsgcHJvdG9jb2wpOworCX0gZWxzZSB7CisJICAgIGlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5GSU5FKSkgeworCQlsb2dnZXIuZmluZSgiZ2V0UHJvdmlkZXIoKSByZXR1cm5pbmcgIiArIF9wcm92aWRlci50b1N0cmluZygpKTsKKwkgICAgfQorCSAgICByZXR1cm4gX3Byb3ZpZGVyOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHBhc3NlZCBQcm92aWRlciB0byBiZSB0aGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbgorICAgICAqIGZvciB0aGUgcHJvdG9jb2wgaW4gUHJvdmlkZXIucHJvdG9jb2wgb3ZlcnJpZGluZyBhbnkgcHJldmlvdXMgdmFsdWVzLgorICAgICAqCisgICAgICogQHBhcmFtIHByb3ZpZGVyIEN1cnJlbnRseSBjb25maWd1cmVkIFByb3ZpZGVyIHdoaWNoIHdpbGwgYmUgCisgICAgICogc2V0IGFzIHRoZSBkZWZhdWx0IGZvciB0aGUgcHJvdG9jb2wKKyAgICAgKiBAZXhjZXB0aW9uCU5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIElmIHRoZSBwcm92aWRlciBwYXNzZWQgaW4KKyAgICAgKgkJCWlzIGludmFsaWQuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHNldFByb3ZpZGVyKFByb3ZpZGVyIHByb3ZpZGVyKQorCQkJCXRocm93cyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiB7CisJaWYgKHByb3ZpZGVyID09IG51bGwpIHsKKwkgICAgdGhyb3cgbmV3IE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uKCJDYW4ndCBzZXQgbnVsbCBwcm92aWRlciIpOworCX0KKwlwcm92aWRlcnNCeVByb3RvY29sLnB1dChwcm92aWRlci5nZXRQcm90b2NvbCgpLCBwcm92aWRlcik7CisJcHJvdmlkZXJzQnlDbGFzc05hbWUucHV0KHByb3ZpZGVyLmdldENsYXNzTmFtZSgpLCBwcm92aWRlcik7CisJcHJvcHMucHV0KCJtYWlsLiIgKyBwcm92aWRlci5nZXRQcm90b2NvbCgpICsgIi5jbGFzcyIsIAorCQkgIHByb3ZpZGVyLmdldENsYXNzTmFtZSgpKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIEdldCBhIFN0b3JlIG9iamVjdCB0aGF0IGltcGxlbWVudHMgdGhpcyB1c2VyJ3MgZGVzaXJlZCBTdG9yZQorICAgICAqIHByb3RvY29sLiBUaGUgPGNvZGU+bWFpbC5zdG9yZS5wcm90b2NvbDwvY29kZT4gcHJvcGVydHkgc3BlY2lmaWVzIHRoZQorICAgICAqIGRlc2lyZWQgcHJvdG9jb2wuIElmIGFuIGFwcHJvcHJpYXRlIFN0b3JlIG9iamVjdCBpcyBub3Qgb2J0YWluZWQsIAorICAgICAqIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIGlzIHRocm93bgorICAgICAqCisgICAgICogQHJldHVybiAJCWEgU3RvcmUgb2JqZWN0IAorICAgICAqIEBleGNlcHRpb24JTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gSWYgYSBwcm92aWRlciBmb3IgdGhlIGdpdmVuCisgICAgICoJCQlwcm90b2NvbCBpcyBub3QgZm91bmQuCisgICAgICovCisgICAgcHVibGljIFN0b3JlIGdldFN0b3JlKCkgdGhyb3dzIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHsKKwlyZXR1cm4gZ2V0U3RvcmUoZ2V0UHJvcGVydHkoIm1haWwuc3RvcmUucHJvdG9jb2wiKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IGEgU3RvcmUgb2JqZWN0IHRoYXQgaW1wbGVtZW50cyB0aGUgc3BlY2lmaWVkIHByb3RvY29sLiBJZiBhbgorICAgICAqIGFwcHJvcHJpYXRlIFN0b3JlIG9iamVjdCBjYW5ub3QgYmUgb2J0YWluZWQsIAorICAgICAqIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIGlzIHRocm93bi4KKyAgICAgKgorICAgICAqIEBwYXJhbQkgICAgICAgIHByb3RvY29sCXRoZSBTdG9yZSBwcm90b2NvbAorICAgICAqIEByZXR1cm4JCWEgU3RvcmUgb2JqZWN0IAorICAgICAqIEBleGNlcHRpb24JTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gSWYgYSBwcm92aWRlciBmb3IgdGhlIGdpdmVuCisgICAgICoJCQlwcm90b2NvbCBpcyBub3QgZm91bmQuCisgICAgICovCisgICAgcHVibGljIFN0b3JlIGdldFN0b3JlKFN0cmluZyBwcm90b2NvbCkgdGhyb3dzIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHsKKwlyZXR1cm4gZ2V0U3RvcmUobmV3IFVSTE5hbWUocHJvdG9jb2wsIG51bGwsIC0xLCBudWxsLCBudWxsLCBudWxsKSk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBHZXQgYSBTdG9yZSBvYmplY3QgZm9yIHRoZSBnaXZlbiBVUkxOYW1lLiBJZiB0aGUgcmVxdWVzdGVkIFN0b3JlCisgICAgICogb2JqZWN0IGNhbm5vdCBiZSBvYnRhaW5lZCwgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gaXMgdGhyb3duLgorICAgICAqCisgICAgICogVGhlICJzY2hlbWUiIHBhcnQgb2YgdGhlIFVSTCBzdHJpbmcgKFJlZmVyIFJGQyAxNzM4KSBpcyB1c2VkIAorICAgICAqIHRvIGxvY2F0ZSB0aGUgU3RvcmUgcHJvdG9jb2wuIDxwPgorICAgICAqCisgICAgICogQHBhcmFtCXVybAlVUkxOYW1lIHRoYXQgcmVwcmVzZW50cyB0aGUgZGVzaXJlZCBTdG9yZQorICAgICAqIEByZXR1cm4JCWEgY2xvc2VkIFN0b3JlIG9iamVjdAorICAgICAqIEBzZWUJCSNnZXRGb2xkZXIoVVJMTmFtZSkKKyAgICAgKiBAc2VlCQlqYXZheC5tYWlsLlVSTE5hbWUKKyAgICAgKiBAZXhjZXB0aW9uCU5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIElmIGEgcHJvdmlkZXIgZm9yIHRoZSBnaXZlbgorICAgICAqCQkJVVJMTmFtZSBpcyBub3QgZm91bmQuCisgICAgICovCisgICAgcHVibGljIFN0b3JlIGdldFN0b3JlKFVSTE5hbWUgdXJsKSB0aHJvd3MgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24geworCVN0cmluZyBwcm90b2NvbCA9IHVybC5nZXRQcm90b2NvbCgpOworCVByb3ZpZGVyIHAgPSBnZXRQcm92aWRlcihwcm90b2NvbCk7CisJcmV0dXJuIGdldFN0b3JlKHAsIHVybCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IGFuIGluc3RhbmNlIG9mIHRoZSBzdG9yZSBzcGVjaWZpZWQgYnkgUHJvdmlkZXIuIEluc3RhbnRpYXRlcworICAgICAqIHRoZSBzdG9yZSBhbmQgcmV0dXJucyBpdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcHJvdmlkZXIgU3RvcmUgUHJvdmlkZXIgdGhhdCB3aWxsIGJlIGluc3RhbnRpYXRlZAorICAgICAqIEByZXR1cm4gSW5zdGFudGlhdGVkIFN0b3JlCisgICAgICogQGV4Y2VwdGlvbglOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiBJZiBhIHByb3ZpZGVyIGZvciB0aGUgZ2l2ZW4KKyAgICAgKgkJCVByb3ZpZGVyIGlzIG5vdCBmb3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RvcmUgZ2V0U3RvcmUoUHJvdmlkZXIgcHJvdmlkZXIpIHRocm93cyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiB7CisJcmV0dXJuIGdldFN0b3JlKHByb3ZpZGVyLCBudWxsKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIEdldCBhbiBpbnN0YW5jZSBvZiB0aGUgc3RvcmUgc3BlY2lmaWVkIGJ5IFByb3ZpZGVyLiBJZiB0aGUgVVJMTmFtZQorICAgICAqIGlzIG5vdCBudWxsLCB1c2VzIGl0LCBvdGhlcndpc2UgY3JlYXRlcyBhIG5ldyBvbmUuIEluc3RhbnRpYXRlcworICAgICAqIHRoZSBzdG9yZSBhbmQgcmV0dXJucyBpdC4gVGhpcyBpcyBhIHByaXZhdGUgbWV0aG9kIHVzZWQgYnkKKyAgICAgKiBnZXRTdG9yZShQcm92aWRlcikgYW5kIGdldFN0b3JlKFVSTE5hbWUpCisgICAgICogCisgICAgICogQHBhcmFtIHByb3ZpZGVyIFN0b3JlIFByb3ZpZGVyIHRoYXQgd2lsbCBiZSBpbnN0YW50aWF0ZWQKKyAgICAgKiBAcGFyYW0gdXJsICAgICAgVVJMTmFtZSB1c2VkIHRvIGluc3RhbnRpYXRlIHRoZSBTdG9yZQorICAgICAqIEByZXR1cm4gSW5zdGFudGlhdGVkIFN0b3JlCisgICAgICogQGV4Y2VwdGlvbglOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiBJZiBhIHByb3ZpZGVyIGZvciB0aGUgZ2l2ZW4KKyAgICAgKgkJCVByb3ZpZGVyL1VSTE5hbWUgaXMgbm90IGZvdW5kLgorICAgICAqLworICAgIHByaXZhdGUgU3RvcmUgZ2V0U3RvcmUoUHJvdmlkZXIgcHJvdmlkZXIsIFVSTE5hbWUgdXJsKSAKKwl0aHJvd3MgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24geworCisJLy8gbWFrZSBzdXJlIHdlIGhhdmUgdGhlIGNvcnJlY3QgdHlwZSBvZiBwcm92aWRlcgorCWlmIChwcm92aWRlciA9PSBudWxsIHx8IHByb3ZpZGVyLmdldFR5cGUoKSAhPSBQcm92aWRlci5UeXBlLlNUT1JFICkgeworCSAgICB0aHJvdyBuZXcgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24oImludmFsaWQgcHJvdmlkZXIiKTsKKwl9CisKKwlyZXR1cm4gZ2V0U2VydmljZShwcm92aWRlciwgdXJsLCBTdG9yZS5jbGFzcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IGEgY2xvc2VkIEZvbGRlciBvYmplY3QgZm9yIHRoZSBnaXZlbiBVUkxOYW1lLiBJZiB0aGUgcmVxdWVzdGVkCisgICAgICogRm9sZGVyIG9iamVjdCBjYW5ub3QgYmUgb2J0YWluZWQsIG51bGwgaXMgcmV0dXJuZWQuIDxwPgorICAgICAqCisgICAgICogVGhlICJzY2hlbWUiIHBhcnQgb2YgdGhlIFVSTCBzdHJpbmcgKFJlZmVyIFJGQyAxNzM4KSBpcyB1c2VkCisgICAgICogdG8gbG9jYXRlIHRoZSBTdG9yZSBwcm90b2NvbC4gVGhlIHJlc3Qgb2YgdGhlIFVSTCBzdHJpbmcgKHRoYXQgaXMsCisgICAgICogdGhlICJzY2hlbWVwYXJ0IiwgYXMgcGVyIFJGQyAxNzM4KSBpcyB1c2VkIGJ5IHRoYXQgU3RvcmUKKyAgICAgKiBpbiBhIHByb3RvY29sIGRlcGVuZGVudCBtYW5uZXIgdG8gbG9jYXRlIGFuZCBpbnN0YW50aWF0ZSB0aGUKKyAgICAgKiBhcHByb3ByaWF0ZSBGb2xkZXIgb2JqZWN0LiA8cD4KKyAgICAgKgorICAgICAqIE5vdGUgdGhhdCBSRkMgMTczOCBhbHNvIHNwZWNpZmllcyB0aGUgc3ludGF4IGZvciB0aGUgCisgICAgICogInNjaGVtZXBhcnQiIGZvciBJUC1iYXNlZCBwcm90b2NvbHMgKElNQVA0LCBQT1AzLCBldGMuKS4KKyAgICAgKiBQcm92aWRlcnMgb2YgSVAtYmFzZWQgbWFpbCBTdG9yZXMgc2hvdWxkIGltcGxlbWVudCB0aGF0CisgICAgICogc3ludGF4IGZvciByZWZlcnJpbmcgdG8gRm9sZGVycy4gPHA+CisgICAgICoKKyAgICAgKiBAcGFyYW0JdXJsCVVSTE5hbWUgdGhhdCByZXByZXNlbnRzIHRoZSBkZXNpcmVkIGZvbGRlcgorICAgICAqIEByZXR1cm4JCUZvbGRlcgorICAgICAqIEBzZWUJCSNnZXRTdG9yZShVUkxOYW1lKQorICAgICAqIEBzZWUJCWphdmF4Lm1haWwuVVJMTmFtZQorICAgICAqIEBleGNlcHRpb24JTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gSWYgYSBwcm92aWRlciBmb3IgdGhlIGdpdmVuCisgICAgICoJCQlVUkxOYW1lIGlzIG5vdCBmb3VuZC4KKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBpZiB0aGUgRm9sZGVyIGNvdWxkIG5vdCBiZSAKKyAgICAgKgkJCWxvY2F0ZWQgb3IgY3JlYXRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRm9sZGVyIGdldEZvbGRlcihVUkxOYW1lIHVybCkKKwkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJLy8gRmlyc3QgZ2V0IHRoZSBTdG9yZQorCVN0b3JlIHN0b3JlID0gZ2V0U3RvcmUodXJsKTsKKwlzdG9yZS5jb25uZWN0KCk7CisJcmV0dXJuIHN0b3JlLmdldEZvbGRlcih1cmwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCBhIFRyYW5zcG9ydCBvYmplY3QgdGhhdCBpbXBsZW1lbnRzIHRoaXMgdXNlcidzIGRlc2lyZWQgCisgICAgICogVHJhbnNwb3J0IHByb3Rjb2wuIFRoZSA8Y29kZT5tYWlsLnRyYW5zcG9ydC5wcm90b2NvbDwvY29kZT4gcHJvcGVydHkgCisgICAgICogc3BlY2lmaWVzIHRoZSBkZXNpcmVkIHByb3RvY29sLiBJZiBhbiBhcHByb3ByaWF0ZSBUcmFuc3BvcnQgCisgICAgICogb2JqZWN0IGNhbm5vdCBiZSBvYnRhaW5lZCwgTWVzc2FnaW5nRXhjZXB0aW9uIGlzIHRocm93bi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gCQlhIFRyYW5zcG9ydCBvYmplY3QgCisgICAgICogQGV4Y2VwdGlvbglOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiBJZiB0aGUgcHJvdmlkZXIgaXMgbm90IGZvdW5kLgorICAgICAqLworICAgIHB1YmxpYyBUcmFuc3BvcnQgZ2V0VHJhbnNwb3J0KCkgdGhyb3dzIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHsKKwlTdHJpbmcgcHJvdCA9IGdldFByb3BlcnR5KCJtYWlsLnRyYW5zcG9ydC5wcm90b2NvbCIpOworCWlmIChwcm90ICE9IG51bGwpCisJICAgIHJldHVybiBnZXRUcmFuc3BvcnQocHJvdCk7CisJLy8gaWYgdGhlIHByb3BlcnR5IGlzbid0IHNldCwgdXNlIHRoZSBwcm90b2NvbCBmb3IgInJmYzgyMiIKKwlwcm90ID0gKFN0cmluZylhZGRyZXNzTWFwLmdldCgicmZjODIyIik7CisJaWYgKHByb3QgIT0gbnVsbCkKKwkgICAgcmV0dXJuIGdldFRyYW5zcG9ydChwcm90KTsKKwlyZXR1cm4gZ2V0VHJhbnNwb3J0KCJzbXRwIik7CS8vIGlmIGFsbCBlbHNlIGZhaWxzCisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IGEgVHJhbnNwb3J0IG9iamVjdCB0aGF0IGltcGxlbWVudHMgdGhlIHNwZWNpZmllZCBwcm90b2NvbC4KKyAgICAgKiBJZiBhbiBhcHByb3ByaWF0ZSBUcmFuc3BvcnQgb2JqZWN0IGNhbm5vdCBiZSBvYnRhaW5lZCwgbnVsbCBpcworICAgICAqIHJldHVybmVkLgorICAgICAqCisgICAgICogQHBhcmFtCXByb3RvY29sIHRoZSBUcmFuc3BvcnQgcHJvdG9jb2wKKyAgICAgKiBAcmV0dXJuIAkJYSBUcmFuc3BvcnQgb2JqZWN0IAorICAgICAqIEBleGNlcHRpb24JTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gSWYgcHJvdmlkZXIgZm9yIHRoZSBnaXZlbgorICAgICAqCQkJcHJvdG9jb2wgaXMgbm90IGZvdW5kLgorICAgICAqLworICAgIHB1YmxpYyBUcmFuc3BvcnQgZ2V0VHJhbnNwb3J0KFN0cmluZyBwcm90b2NvbCkKKwkJCQl0aHJvd3MgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24geworCXJldHVybiBnZXRUcmFuc3BvcnQobmV3IFVSTE5hbWUocHJvdG9jb2wsIG51bGwsIC0xLCBudWxsLCBudWxsLCBudWxsKSk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBHZXQgYSBUcmFuc3BvcnQgb2JqZWN0IGZvciB0aGUgZ2l2ZW4gVVJMTmFtZS4gSWYgdGhlIHJlcXVlc3RlZCAKKyAgICAgKiBUcmFuc3BvcnQgb2JqZWN0IGNhbm5vdCBiZSBvYnRhaW5lZCwgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gaXMgdGhyb3duLgorICAgICAqCisgICAgICogVGhlICJzY2hlbWUiIHBhcnQgb2YgdGhlIFVSTCBzdHJpbmcgKFJlZmVyIFJGQyAxNzM4KSBpcyB1c2VkIAorICAgICAqIHRvIGxvY2F0ZSB0aGUgVHJhbnNwb3J0IHByb3RvY29sLiA8cD4KKyAgICAgKgorICAgICAqIEBwYXJhbQl1cmwJVVJMTmFtZSB0aGF0IHJlcHJlc2VudHMgdGhlIGRlc2lyZWQgVHJhbnNwb3J0CisgICAgICogQHJldHVybgkJYSBjbG9zZWQgVHJhbnNwb3J0IG9iamVjdAorICAgICAqIEBzZWUJCWphdmF4Lm1haWwuVVJMTmFtZQorICAgICAqIEBleGNlcHRpb24JTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gSWYgYSBwcm92aWRlciBmb3IgdGhlIGdpdmVuCisgICAgICoJCQlVUkxOYW1lIGlzIG5vdCBmb3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgVHJhbnNwb3J0IGdldFRyYW5zcG9ydChVUkxOYW1lIHVybCkgdGhyb3dzIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHsKKwlTdHJpbmcgcHJvdG9jb2wgPSB1cmwuZ2V0UHJvdG9jb2woKTsKKwlQcm92aWRlciBwID0gZ2V0UHJvdmlkZXIocHJvdG9jb2wpOworCXJldHVybiBnZXRUcmFuc3BvcnQocCwgdXJsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgYW4gaW5zdGFuY2Ugb2YgdGhlIHRyYW5zcG9ydCBzcGVjaWZpZWQgaW4gdGhlIFByb3ZpZGVyLiBJbnN0YW50aWF0ZXMKKyAgICAgKiB0aGUgdHJhbnNwb3J0IGFuZCByZXR1cm5zIGl0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBwcm92aWRlciBUcmFuc3BvcnQgUHJvdmlkZXIgdGhhdCB3aWxsIGJlIGluc3RhbnRpYXRlZAorICAgICAqIEByZXR1cm4gSW5zdGFudGlhdGVkIFRyYW5zcG9ydAorICAgICAqIEBleGNlcHRpb24JTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24gSWYgcHJvdmlkZXIgZm9yIHRoZSBnaXZlbgorICAgICAqCQkJcHJvdmlkZXIgaXMgbm90IGZvdW5kLgorICAgICAqLworICAgIHB1YmxpYyBUcmFuc3BvcnQgZ2V0VHJhbnNwb3J0KFByb3ZpZGVyIHByb3ZpZGVyKSAKKwkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHsKKwlyZXR1cm4gZ2V0VHJhbnNwb3J0KHByb3ZpZGVyLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgYSBUcmFuc3BvcnQgb2JqZWN0IHRoYXQgY2FuIHRyYW5zcG9ydCBhIE1lc3NhZ2Ugb2YgdGhlCisgICAgICogc3BlY2lmaWVkIGFkZHJlc3MgdHlwZS4KKyAgICAgKgorICAgICAqIEBwYXJhbQlhZGRyZXNzCWFuIGFkZHJlc3MgZm9yIHdoaWNoIGEgVHJhbnNwb3J0IGlzIG5lZWRlZAorICAgICAqIEByZXR1cm4JQSBUcmFuc3BvcnQgb2JqZWN0CisgICAgICogQHNlZSBqYXZheC5tYWlsLkFkZHJlc3MKKyAgICAgKiBAZXhjZXB0aW9uCU5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIElmIHByb3ZpZGVyIGZvciB0aGUgCisgICAgICoJCQlBZGRyZXNzIHR5cGUgaXMgbm90IGZvdW5kCisgICAgICovCisgICAgcHVibGljIFRyYW5zcG9ydCBnZXRUcmFuc3BvcnQoQWRkcmVzcyBhZGRyZXNzKSAKKwkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uIHsKKworCVN0cmluZyB0cmFuc3BvcnRQcm90b2NvbDsKKwl0cmFuc3BvcnRQcm90b2NvbCA9CisJICAgIGdldFByb3BlcnR5KCJtYWlsLnRyYW5zcG9ydC5wcm90b2NvbC4iICsgYWRkcmVzcy5nZXRUeXBlKCkpOworCWlmICh0cmFuc3BvcnRQcm90b2NvbCAhPSBudWxsKQorCSAgICByZXR1cm4gZ2V0VHJhbnNwb3J0KHRyYW5zcG9ydFByb3RvY29sKTsKKwl0cmFuc3BvcnRQcm90b2NvbCA9IChTdHJpbmcpYWRkcmVzc01hcC5nZXQoYWRkcmVzcy5nZXRUeXBlKCkpOworCWlmICh0cmFuc3BvcnRQcm90b2NvbCAhPSBudWxsKQorCSAgICByZXR1cm4gZ2V0VHJhbnNwb3J0KHRyYW5zcG9ydFByb3RvY29sKTsKKwl0aHJvdyBuZXcgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24oIk5vIHByb3ZpZGVyIGZvciBBZGRyZXNzIHR5cGU6ICIrCisJCQkJCQlhZGRyZXNzLmdldFR5cGUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IGEgVHJhbnNwb3J0IG9iamVjdCB1c2luZyB0aGUgZ2l2ZW4gcHJvdmlkZXIgYW5kIHVybG5hbWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0JcHJvdmlkZXIJdGhlIHByb3ZpZGVyIHRvIHVzZQorICAgICAqIEBwYXJhbQl1cmwJCXVybG5hbWUgdG8gdXNlIChjYW4gYmUgbnVsbCkKKyAgICAgKiBAcmV0dXJuIEEgVHJhbnNwb3J0IG9iamVjdAorICAgICAqIEBleGNlcHRpb24JTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24JSWYgbm8gcHJvdmlkZXIgb3IgdGhlIHByb3ZpZGVyCisgICAgICoJCQl3YXMgdGhlIHdyb25nIGNsYXNzLgkKKyAgICAgKi8KKworICAgIHByaXZhdGUgVHJhbnNwb3J0IGdldFRyYW5zcG9ydChQcm92aWRlciBwcm92aWRlciwgVVJMTmFtZSB1cmwpCisJCQkJCXRocm93cyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiB7CisJLy8gbWFrZSBzdXJlIHdlIGhhdmUgdGhlIGNvcnJlY3QgdHlwZSBvZiBwcm92aWRlcgorCWlmIChwcm92aWRlciA9PSBudWxsIHx8IHByb3ZpZGVyLmdldFR5cGUoKSAhPSBQcm92aWRlci5UeXBlLlRSQU5TUE9SVCkgeworCSAgICB0aHJvdyBuZXcgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24oImludmFsaWQgcHJvdmlkZXIiKTsKKwl9CisKKwlyZXR1cm4gZ2V0U2VydmljZShwcm92aWRlciwgdXJsLCBUcmFuc3BvcnQuY2xhc3MpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCBhIFNlcnZpY2Ugb2JqZWN0LiAgTmVlZHMgYSBwcm92aWRlciBvYmplY3QsIGJ1dCB3aWxsCisgICAgICogY3JlYXRlIGEgVVJMTmFtZSBpZiBuZWVkZWQuICBJdCBhdHRlbXB0cyB0byBpbnN0YW50aWF0ZQorICAgICAqIHRoZSBjb3JyZWN0IGNsYXNzLgorICAgICAqCisgICAgICogQHBhcmFtIHByb3ZpZGVyCXdoaWNoIHByb3ZpZGVyIHRvIHVzZQorICAgICAqIEBwYXJhbSB1cmwJd2hpY2ggVVJMTmFtZSB0byB1c2UgKGNhbiBiZSBudWxsKQorICAgICAqIEBwYXJhbSB0eXBlCXRoZSBzZXJ2aWNlIHR5cGUgKGNsYXNzKQorICAgICAqIEBleGNlcHRpb24JTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24JdGhyb3duIHdoZW4gdGhlIGNsYXNzIGNhbm5vdCBiZQorICAgICAqCQkJZm91bmQgb3Igd2hlbiBpdCBkb2VzIG5vdCBoYXZlIHRoZSBjb3JyZWN0IGNvbnN0cnVjdG9yCisgICAgICoJCQkoU2Vzc2lvbiwgVVJMTmFtZSksIG9yIGlmIGl0IGlzIG5vdCBkZXJpdmVkIGZyb20KKyAgICAgKgkJCVNlcnZpY2UuCisgICAgICovCisgICAgcHJpdmF0ZSA8VCBleHRlbmRzIFNlcnZpY2U+IFQgZ2V0U2VydmljZShQcm92aWRlciBwcm92aWRlciwgVVJMTmFtZSB1cmwsCisJCQkJCUNsYXNzPFQ+IHR5cGUpCisJCQkJCXRocm93cyBOb1N1Y2hQcm92aWRlckV4Y2VwdGlvbiB7CisJLy8gbmVlZCBhIHByb3ZpZGVyIGFuZCB1cmwKKwlpZiAocHJvdmlkZXIgPT0gbnVsbCkgeworCSAgICB0aHJvdyBuZXcgTm9TdWNoUHJvdmlkZXJFeGNlcHRpb24oIm51bGwiKTsKKwl9CisKKwkvLyBjcmVhdGUgYSB1cmwgaWYgbmVlZGVkCisJaWYgKHVybCA9PSBudWxsKSB7CisJICAgIHVybCA9IG5ldyBVUkxOYW1lKHByb3ZpZGVyLmdldFByb3RvY29sKCksIG51bGwsIC0xLCAKKwkJCSAgICAgIG51bGwsIG51bGwsIG51bGwpOworCX0KKworCU9iamVjdCBzZXJ2aWNlID0gbnVsbDsKKwkKKwkvLyBnZXQgdGhlIENsYXNzTG9hZGVyIGFzc29jaWF0ZWQgd2l0aCB0aGUgQXV0aGVudGljYXRvcgorCUNsYXNzTG9hZGVyIGNsOworCWlmIChhdXRoZW50aWNhdG9yICE9IG51bGwpCisJICAgIGNsID0gYXV0aGVudGljYXRvci5nZXRDbGFzcygpLmdldENsYXNzTG9hZGVyKCk7CisJZWxzZQorCSAgICBjbCA9IHRoaXMuZ2V0Q2xhc3MoKS5nZXRDbGFzc0xvYWRlcigpOworCisJLy8gbm93IGxvYWQgdGhlIGNsYXNzCisJQ2xhc3M8Pz4gc2VydmljZUNsYXNzID0gbnVsbDsKKwl0cnkgeworCSAgICAvLyBGaXJzdCB0cnkgdGhlICJhcHBsaWNhdGlvbidzIiBjbGFzcyBsb2FkZXIuCisJICAgIENsYXNzTG9hZGVyIGNjbCA9IGdldENvbnRleHRDbGFzc0xvYWRlcigpOworCSAgICBpZiAoY2NsICE9IG51bGwpCisJCXRyeSB7CisJCSAgICBzZXJ2aWNlQ2xhc3MgPQorCQkJQ2xhc3MuZm9yTmFtZShwcm92aWRlci5nZXRDbGFzc05hbWUoKSwgZmFsc2UsIGNjbCk7CisJCX0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZXgpIHsKKwkJICAgIC8vIGlnbm9yZSBpdAorCQl9CisJICAgIGlmIChzZXJ2aWNlQ2xhc3MgPT0gbnVsbCB8fCAhdHlwZS5pc0Fzc2lnbmFibGVGcm9tKHNlcnZpY2VDbGFzcykpCisJCXNlcnZpY2VDbGFzcyA9CisJCSAgICBDbGFzcy5mb3JOYW1lKHByb3ZpZGVyLmdldENsYXNzTmFtZSgpLCBmYWxzZSwgY2wpOworICAgICAgICAgICAgCisJICAgIGlmICghdHlwZS5pc0Fzc2lnbmFibGVGcm9tKHNlcnZpY2VDbGFzcykpCisJCXRocm93IG5ldyBDbGFzc0Nhc3RFeGNlcHRpb24oCisJCQkJdHlwZS5nZXROYW1lKCkgKyAiICIgKyBzZXJ2aWNlQ2xhc3MuZ2V0TmFtZSgpKTsKKwl9IGNhdGNoIChFeGNlcHRpb24gZXgxKSB7CisJICAgIC8vIFRoYXQgZGlkbid0IHdvcmssIG5vdyB0cnkgdGhlICJzeXN0ZW0iIGNsYXNzIGxvYWRlci4KKwkgICAgLy8gKE5lZWQgYm90aCBvZiB0aGVzZSBiZWNhdXNlIEpESyAxLjEgY2xhc3MgbG9hZGVycworCSAgICAvLyBtYXkgbm90IGRlbGVnYXRlIHRvIHRoZWlyIHBhcmVudCBjbGFzcyBsb2FkZXIuKQorCSAgICB0cnkgeworCQlzZXJ2aWNlQ2xhc3MgPSBDbGFzcy5mb3JOYW1lKHByb3ZpZGVyLmdldENsYXNzTmFtZSgpKTsKKwkJaWYgKCF0eXBlLmlzQXNzaWduYWJsZUZyb20oc2VydmljZUNsYXNzKSkKKwkJICAgIHRocm93IG5ldyBDbGFzc0Nhc3RFeGNlcHRpb24oCisJCQkJdHlwZS5nZXROYW1lKCkgKyAiICIgKyBzZXJ2aWNlQ2xhc3MuZ2V0TmFtZSgpKTsKKwkgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJCS8vIE5vdGhpbmcgd29ya2VkLCBnaXZlIHVwLgorCQlsb2dnZXIubG9nKExldmVsLkZJTkUsICJFeGNlcHRpb24gbG9hZGluZyBwcm92aWRlciIsIGV4KTsKKwkJdGhyb3cgbmV3IE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uKHByb3ZpZGVyLmdldFByb3RvY29sKCkpOworCSAgICB9CisJfQorCisJLy8gY29uc3RydWN0IGFuIGluc3RhbmNlIG9mIHRoZSBjbGFzcworCXRyeSB7CisJICAgIENsYXNzPD8+W10gYyA9IHtqYXZheC5tYWlsLlNlc3Npb24uY2xhc3MsIGphdmF4Lm1haWwuVVJMTmFtZS5jbGFzc307CisJICAgIENvbnN0cnVjdG9yPD8+IGNvbnMgPSBzZXJ2aWNlQ2xhc3MuZ2V0Q29uc3RydWN0b3IoYyk7CisKKwkgICAgT2JqZWN0W10gbyA9IHt0aGlzLCB1cmx9OworCSAgICBzZXJ2aWNlID0gY29ucy5uZXdJbnN0YW5jZShvKTsKKworCX0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCSAgICBsb2dnZXIubG9nKExldmVsLkZJTkUsICJFeGNlcHRpb24gbG9hZGluZyBwcm92aWRlciIsIGV4KTsKKwkgICAgdGhyb3cgbmV3IE5vU3VjaFByb3ZpZGVyRXhjZXB0aW9uKHByb3ZpZGVyLmdldFByb3RvY29sKCkpOworCX0KKworCXJldHVybiB0eXBlLmNhc3Qoc2VydmljZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2F2ZSBhIFBhc3N3b3JkQXV0aGVudGljYXRpb24gZm9yIHRoaXMgKHN0b3JlIG9yIHRyYW5zcG9ydCkgVVJMTmFtZS4KKyAgICAgKiBJZiBwdyBpcyBudWxsIHRoZSBlbnRyeSBjb3JyZXNwb25kaW5nIHRvIHRoZSBVUkxOYW1lIGlzIHJlbW92ZWQuCisgICAgICogPHA+CisgICAgICogVGhpcyBpcyBub3JtYWxseSB1c2VkIG9ubHkgYnkgdGhlIHN0b3JlIG9yIHRyYW5zcG9ydCBpbXBsZW1lbnRhdGlvbnMKKyAgICAgKiB0byBhbGxvdyBhdXRoZW50aWNhdGlvbiBpbmZvcm1hdGlvbiB0byBiZSBzaGFyZWQgYW1vbmcgbXVsdGlwbGUKKyAgICAgKiB1c2VzIG9mIGEgc2Vzc2lvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbQl1cmwJdGhlIFVSTE5hbWUKKyAgICAgKiBAcGFyYW0JcHcJdGhlIFBhc3N3b3JkQXV0aGVudGljYXRpb24gdG8gc2F2ZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFBhc3N3b3JkQXV0aGVudGljYXRpb24oVVJMTmFtZSB1cmwsCisJCQkJCSAgUGFzc3dvcmRBdXRoZW50aWNhdGlvbiBwdykgeworCWlmIChwdyA9PSBudWxsKQorCSAgICBhdXRoVGFibGUucmVtb3ZlKHVybCk7CisJZWxzZQorCSAgICBhdXRoVGFibGUucHV0KHVybCwgcHcpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiBhbnkgc2F2ZWQgUGFzc3dvcmRBdXRoZW50aWNhdGlvbiBmb3IgdGhpcyAoc3RvcmUgb3IgdHJhbnNwb3J0KQorICAgICAqIFVSTE5hbWUuICBOb3JtYWxseSB1c2VkIG9ubHkgYnkgc3RvcmUgb3IgdHJhbnNwb3J0IGltcGxlbWVudGF0aW9ucy4KKyAgICAgKgorICAgICAqIEBwYXJhbQl1cmwJdGhlIFVSTE5hbWUKKyAgICAgKiBAcmV0dXJuCXRoZSBQYXNzd29yZEF1dGhlbnRpY2F0aW9uIGNvcnJlc3BvbmRpbmcgdG8gdGhlIFVSTE5hbWUKKyAgICAgKi8KKyAgICBwdWJsaWMgUGFzc3dvcmRBdXRoZW50aWNhdGlvbiBnZXRQYXNzd29yZEF1dGhlbnRpY2F0aW9uKFVSTE5hbWUgdXJsKSB7CisJcmV0dXJuIGF1dGhUYWJsZS5nZXQodXJsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDYWxsIGJhY2sgdG8gdGhlIGFwcGxpY2F0aW9uIHRvIGdldCB0aGUgbmVlZGVkIHVzZXIgbmFtZSBhbmQgcGFzc3dvcmQuCisgICAgICogVGhlIGFwcGxpY2F0aW9uIHNob3VsZCBwdXQgdXAgYSBkaWFsb2cgc29tZXRoaW5nIGxpa2U6CisgICAgICogPHByZT4KKyAgICAgKiBDb25uZWN0aW5nIHRvICZsdDtwcm90b2NvbCZndDsgbWFpbCBzZXJ2aWNlIG9uIGhvc3QgJmx0O2FkZHImZ3Q7LCBwb3J0ICZsdDtwb3J0Jmd0Oy4KKyAgICAgKiAmbHQ7cHJvbXB0Jmd0OworICAgICAqCisgICAgICogVXNlciBOYW1lOiAmbHQ7ZGVmYXVsdFVzZXJOYW1lJmd0OworICAgICAqIFBhc3N3b3JkOgorICAgICAqIDwvcHJlPgorICAgICAqCisgICAgICogQHBhcmFtCWFkZHIJCUluZXRBZGRyZXNzIG9mIHRoZSBob3N0LiAgbWF5IGJlIG51bGwuCisgICAgICogQHBhcmFtCXBvcnQJCXRoZSBwb3J0IG9uIHRoZSBob3N0CisgICAgICogQHBhcmFtCXByb3RvY29sCXByb3RvY29sIHNjaGVtZSAoZS5nLiBpbWFwLCBwb3AzLCBldGMuKQorICAgICAqIEBwYXJhbQlwcm9tcHQJCWFueSBhZGRpdGlvbmFsIFN0cmluZyB0byBzaG93IGFzIHBhcnQgb2YKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIHByb21wdDsgbWF5IGJlIG51bGwuCisgICAgICogQHBhcmFtCWRlZmF1bHRVc2VyTmFtZQl0aGUgZGVmYXVsdCB1c2VybmFtZS4gbWF5IGJlIG51bGwuCisgICAgICogQHJldHVybgl0aGUgYXV0aGVudGljYXRpb24gd2hpY2ggd2FzIGNvbGxlY3RlZCBieSB0aGUgYXV0aGVudGljYXRvcjsgCisgICAgICogICAgICAgICAgbWF5IGJlIG51bGwuCisgICAgICovCisgICAgcHVibGljIFBhc3N3b3JkQXV0aGVudGljYXRpb24gcmVxdWVzdFBhc3N3b3JkQXV0aGVudGljYXRpb24oCisJSW5ldEFkZHJlc3MgYWRkciwgaW50IHBvcnQsCisJU3RyaW5nIHByb3RvY29sLCBTdHJpbmcgcHJvbXB0LCBTdHJpbmcgZGVmYXVsdFVzZXJOYW1lKSB7CisKKwlpZiAoYXV0aGVudGljYXRvciAhPSBudWxsKSB7CisJICAgIHJldHVybiBhdXRoZW50aWNhdG9yLnJlcXVlc3RQYXNzd29yZEF1dGhlbnRpY2F0aW9uKAorCQlhZGRyLCBwb3J0LCBwcm90b2NvbCwgcHJvbXB0LCBkZWZhdWx0VXNlck5hbWUpOworCX0gZWxzZSB7CisJICAgIHJldHVybiBudWxsOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBQcm9wZXJ0aWVzIG9iamVjdCBhc3NvY2lhdGVkIHdpdGggdGhpcyBTZXNzaW9uCisgICAgICoKKyAgICAgKiBAcmV0dXJuCQlQcm9wZXJ0aWVzIG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyBQcm9wZXJ0aWVzIGdldFByb3BlcnRpZXMoKSB7IAorICAgCXJldHVybiBwcm9wczsgCisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBwcm9wZXJ0eS4gUmV0dXJucyBudWxsCisgICAgICogaWYgdGhpcyBwcm9wZXJ0eSBkb2VzIG5vdCBleGlzdC4KKyAgICAgKgorICAgICAqIEBwYXJhbQluYW1lCXRoZSBwcm9wZXJ0eSBuYW1lCisgICAgICogQHJldHVybgkJU3RyaW5nIHRoYXQgaXMgdGhlIHByb3BlcnR5IHZhbHVlCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRQcm9wZXJ0eShTdHJpbmcgbmFtZSkgeyAKKyAgIAlyZXR1cm4gcHJvcHMuZ2V0UHJvcGVydHkobmFtZSk7IAorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgUHJvdmlkZXIgdGhhdCB1c2VzIHRoZSBzcGVjaWZpZWQgY2xhc3MgbmFtZS4KKyAgICAgKgorICAgICAqIEBwYXJhbQljbGFzc05hbWUJdGhlIGNsYXNzIG5hbWUKKyAgICAgKiBAcmV0dXJuCQl0aGUgUHJvdmlkZXIKKyAgICAgKi8KKyAgICBwcml2YXRlIFByb3ZpZGVyIGdldFByb3ZpZGVyQnlDbGFzc05hbWUoU3RyaW5nIGNsYXNzTmFtZSkgeworCS8vIGZpcnN0LCB0cnkgb3VyIGxvY2FsIGxpc3Qgb2YgcHJvdmlkZXJzCisJUHJvdmlkZXIgcCA9IHByb3ZpZGVyc0J5Q2xhc3NOYW1lLmdldChjbGFzc05hbWUpOworCWlmIChwICE9IG51bGwpCisJICAgIHJldHVybiBwOworCisJLy8gbm93LCB0cnkgc2VydmljZXMKKwlTZXJ2aWNlTG9hZGVyPFByb3ZpZGVyPiBsb2FkZXIgPSBTZXJ2aWNlTG9hZGVyLmxvYWQoUHJvdmlkZXIuY2xhc3MpOworCWZvciAoUHJvdmlkZXIgcHAgOiBsb2FkZXIpIHsKKwkgICAgaWYgKGNsYXNzTmFtZS5lcXVhbHMocHAuZ2V0Q2xhc3NOYW1lKCkpKQorCQlyZXR1cm4gcHA7CisJfQorCisJLy8gZmluYWxseSwgaWYgd2UgaGF2ZW4ndCBsb2FkZWQgb3VyIGNvbmZpZywgbG9hZCBpdCBhbmQgdHJ5IGFnYWluCisJaWYgKCFsb2FkZWRQcm92aWRlcnMpIHsKKwkgICAgbG9hZFByb3ZpZGVycyh0cnVlKTsKKwkgICAgcCA9IHByb3ZpZGVyc0J5Q2xhc3NOYW1lLmdldChjbGFzc05hbWUpOworCX0KKwlyZXR1cm4gcDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIFByb3ZpZGVyIGZvciB0aGUgc3BlY2lmaWVkIHByb3RvY29sLgorICAgICAqCisgICAgICogQHBhcmFtCXByb3RvY29sCXRoZSBwcm90b2NvbAorICAgICAqIEByZXR1cm4JCXRoZSBQcm92aWRlcgorICAgICAqLworICAgIHByaXZhdGUgUHJvdmlkZXIgZ2V0UHJvdmlkZXJCeVByb3RvY29sKFN0cmluZyBwcm90b2NvbCkgeworCS8vIGZpcnN0LCB0cnkgb3VyIGxvY2FsIGxpc3Qgb2YgcHJvdmlkZXJzCisJUHJvdmlkZXIgcCA9IHByb3ZpZGVyc0J5UHJvdG9jb2wuZ2V0KHByb3RvY29sKTsKKwlpZiAocCAhPSBudWxsKQorCSAgICByZXR1cm4gcDsKKworCS8vIG5vdywgdHJ5IHNlcnZpY2VzCisJU2VydmljZUxvYWRlcjxQcm92aWRlcj4gbG9hZGVyID0gU2VydmljZUxvYWRlci5sb2FkKFByb3ZpZGVyLmNsYXNzKTsKKwlmb3IgKFByb3ZpZGVyIHBwIDogbG9hZGVyKSB7CisJICAgIGlmIChwcm90b2NvbC5lcXVhbHMocHAuZ2V0UHJvdG9jb2woKSkpCisJCXJldHVybiBwcDsKKwl9CisKKwkvLyBmaW5hbGx5LCBpZiB3ZSBoYXZlbid0IGxvYWRlZCBvdXIgY29uZmlnLCBsb2FkIGl0IGFuZCB0cnkgYWdhaW4KKwlpZiAoIWxvYWRlZFByb3ZpZGVycykgeworCSAgICBsb2FkUHJvdmlkZXJzKHRydWUpOworCSAgICBwID0gcHJvdmlkZXJzQnlQcm90b2NvbC5nZXQocHJvdG9jb2wpOworCX0KKwlyZXR1cm4gcDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb2FkIHRoZSBwcm90b2NvbCBwcm92aWRlcnMgY29uZmlnIGZpbGVzLgorICAgICAqIElmIGZhbGxiYWNrIGlzIHRydWUsIHByb3ZpZGUgYnVpbHQgaW4gZGVmYXVsdHMgaWYgbm90aGluZyBpcyBsb2FkZWQuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGxvYWRQcm92aWRlcnMoYm9vbGVhbiBmYWxsYmFjaykgeworCVN0cmVhbUxvYWRlciBsb2FkZXIgPSBuZXcgU3RyZWFtTG9hZGVyKCkgeworCSAgICBAT3ZlcnJpZGUKKwkgICAgcHVibGljIHZvaWQgbG9hZChJbnB1dFN0cmVhbSBpcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkJbG9hZFByb3ZpZGVyc0Zyb21TdHJlYW0oaXMpOworCSAgICB9CisJfTsKKworCS8vIGxvYWQgc3lzdGVtLXdpZGUgamF2YW1haWwucHJvdmlkZXJzIGZyb20gdGhlCisJLy8gPGphdmEuaG9tZT4ve2NvbmYsbGlifSBkaXJlY3RvcnkKKwl0cnkgeworCSAgICBpZiAoY29uZkRpciAhPSBudWxsKQorCQlsb2FkRmlsZShjb25mRGlyICsgImphdmFtYWlsLnByb3ZpZGVycyIsIGxvYWRlcik7CisJfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gZXgpIHt9CisKKwkvLyBnZXQgdGhlIENsYXNzIGFzc29jaWF0ZWQgd2l0aCB0aGUgQXV0aGVudGljYXRvcgorCUNsYXNzPD8+IGNsOworCWlmIChhdXRoZW50aWNhdG9yICE9IG51bGwpCisJICAgIGNsID0gYXV0aGVudGljYXRvci5nZXRDbGFzcygpOworCWVsc2UKKwkgICAgY2wgPSB0aGlzLmdldENsYXNzKCk7CisKKwkvLyBsb2FkIHRoZSBNRVRBLUlORi9qYXZhbWFpbC5wcm92aWRlcnMgZmlsZSBzdXBwbGllZCBieSBhbiBhcHBsaWNhdGlvbgorCWxvYWRBbGxSZXNvdXJjZXMoIk1FVEEtSU5GL2phdmFtYWlsLnByb3ZpZGVycyIsIGNsLCBsb2FkZXIpOworCisJLy8gbG9hZCBkZWZhdWx0IE1FVEEtSU5GL2phdmFtYWlsLmRlZmF1bHQucHJvdmlkZXJzIGZyb20gbWFpbC5qYXIgZmlsZQorCWxvYWRSZXNvdXJjZSgiL01FVEEtSU5GL2phdmFtYWlsLmRlZmF1bHQucHJvdmlkZXJzIiwgY2wsIGxvYWRlciwgZmFsc2UpOworCisJLyoKKwkgKiBJZiB3ZSBoYXZlbid0IGxvYWRlZCBhbnkgcHJvdmlkZXJzIGFuZCB0aGUgZmFsbGJhY2sgY29uZmlndXJhdGlvbgorCSAqIGlzIG5lZWRlZCwgZmFrZSBpdC4KKwkgKi8KKwlpZiAoKHByb3ZpZGVycyA9PSBudWxsIHx8IHByb3ZpZGVycy5zaXplKCkgPT0gMCkgJiYgZmFsbGJhY2spIHsKKwkgICAgbG9nZ2VyLmNvbmZpZygiZmFpbGVkIHRvIGxvYWQgYW55IHByb3ZpZGVycywgdXNpbmcgZGVmYXVsdHMiKTsKKwkgICAgLy8gZmFpbGVkIHRvIGxvYWQgYW55IHByb3ZpZGVycywgaW5pdGlhbGl6ZSB3aXRoIG91ciBkZWZhdWx0cworCSAgICBhZGRQcm92aWRlcihuZXcgUHJvdmlkZXIoUHJvdmlkZXIuVHlwZS5TVE9SRSwKKwkJCSJpbWFwIiwgImNvbS5zdW4ubWFpbC5pbWFwLklNQVBTdG9yZSIsCisJCQkiT3JhY2xlIiwgVmVyc2lvbi52ZXJzaW9uKSk7CisJICAgIGFkZFByb3ZpZGVyKG5ldyBQcm92aWRlcihQcm92aWRlci5UeXBlLlNUT1JFLAorCQkJImltYXBzIiwgImNvbS5zdW4ubWFpbC5pbWFwLklNQVBTU0xTdG9yZSIsCisJCQkiT3JhY2xlIiwgVmVyc2lvbi52ZXJzaW9uKSk7CisJICAgIGFkZFByb3ZpZGVyKG5ldyBQcm92aWRlcihQcm92aWRlci5UeXBlLlNUT1JFLAorCQkJInBvcDMiLCAiY29tLnN1bi5tYWlsLnBvcDMuUE9QM1N0b3JlIiwKKwkJCSJPcmFjbGUiLCBWZXJzaW9uLnZlcnNpb24pKTsKKwkgICAgYWRkUHJvdmlkZXIobmV3IFByb3ZpZGVyKFByb3ZpZGVyLlR5cGUuU1RPUkUsCisJCQkicG9wM3MiLCAiY29tLnN1bi5tYWlsLnBvcDMuUE9QM1NTTFN0b3JlIiwKKwkJCSJPcmFjbGUiLCBWZXJzaW9uLnZlcnNpb24pKTsKKwkgICAgYWRkUHJvdmlkZXIobmV3IFByb3ZpZGVyKFByb3ZpZGVyLlR5cGUuVFJBTlNQT1JULAorCQkJInNtdHAiLCAiY29tLnN1bi5tYWlsLnNtdHAuU01UUFRyYW5zcG9ydCIsCisJCQkiT3JhY2xlIiwgVmVyc2lvbi52ZXJzaW9uKSk7CisJICAgIGFkZFByb3ZpZGVyKG5ldyBQcm92aWRlcihQcm92aWRlci5UeXBlLlRSQU5TUE9SVCwKKwkJCSJzbXRwcyIsICJjb20uc3VuLm1haWwuc210cC5TTVRQU1NMVHJhbnNwb3J0IiwKKwkJCSJPcmFjbGUiLCBWZXJzaW9uLnZlcnNpb24pKTsKKwl9CisKKwlpZiAobG9nZ2VyLmlzTG9nZ2FibGUoTGV2ZWwuQ09ORklHKSkgeworCSAgICAvLyBkdW1wIHRoZSBvdXRwdXQgb2YgdGhlIHRhYmxlcyBmb3IgZGVidWdnaW5nCisJICAgIGxvZ2dlci5jb25maWcoIlRhYmxlcyBvZiBsb2FkZWQgcHJvdmlkZXJzIGZyb20gamF2YW1haWwucHJvdmlkZXJzIik7CisJICAgIGxvZ2dlci5jb25maWcoIlByb3ZpZGVycyBMaXN0ZWQgQnkgQ2xhc3MgTmFtZTogIiArIAorCSAgICAgICBwcm92aWRlcnNCeUNsYXNzTmFtZS50b1N0cmluZygpKTsKKwkgICAgbG9nZ2VyLmNvbmZpZygiUHJvdmlkZXJzIExpc3RlZCBCeSBQcm90b2NvbDogIiArIAorCSAgICAgICBwcm92aWRlcnNCeVByb3RvY29sLnRvU3RyaW5nKCkpOworCX0KKwlsb2FkZWRQcm92aWRlcnMgPSB0cnVlOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBsb2FkUHJvdmlkZXJzRnJvbVN0cmVhbShJbnB1dFN0cmVhbSBpcykgCisJCQkJdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlpZiAoaXMgIT0gbnVsbCkgeworCSAgICBMaW5lSW5wdXRTdHJlYW0gbGlzID0gbmV3IExpbmVJbnB1dFN0cmVhbShpcyk7CisJICAgIFN0cmluZyBjdXJyTGluZTsKKworCSAgICAvLyBsb2FkIGFuZCBwcm9jZXNzIG9uZSBsaW5lIGF0IGEgdGltZSB1c2luZyBMaW5lSW5wdXRTdHJlYW0KKwkgICAgd2hpbGUgKChjdXJyTGluZSA9IGxpcy5yZWFkTGluZSgpKSAhPSBudWxsKSB7CisKKwkJaWYgKGN1cnJMaW5lLnN0YXJ0c1dpdGgoIiMiKSkKKwkJICAgIGNvbnRpbnVlOworCQlpZiAoY3VyckxpbmUudHJpbSgpLmxlbmd0aCgpID09IDApCisJCSAgICBjb250aW51ZTsJLy8gc2tpcCBibGFuayBsaW5lCisJCVByb3ZpZGVyLlR5cGUgdHlwZSA9IG51bGw7CisJCVN0cmluZyBwcm90b2NvbCA9IG51bGwsIGNsYXNzTmFtZSA9IG51bGw7CisJCVN0cmluZyB2ZW5kb3IgPSBudWxsLCB2ZXJzaW9uID0gbnVsbDsKKwkJICAgIAorCQkvLyBzZXBhcmF0ZSBsaW5lIGludG8ga2V5LXZhbHVlIHR1cGxlcworCQlTdHJpbmdUb2tlbml6ZXIgdHVwbGVzID0gbmV3IFN0cmluZ1Rva2VuaXplcihjdXJyTGluZSwiOyIpOworCQl3aGlsZSAodHVwbGVzLmhhc01vcmVUb2tlbnMoKSkgeworCQkgICAgU3RyaW5nIGN1cnJUdXBsZSA9IHR1cGxlcy5uZXh0VG9rZW4oKS50cmltKCk7CisJCQkKKwkJICAgIC8vIHNldCB0aGUgdmFsdWUgb2YgZWFjaCBhdHRyaWJ1dGUgYmFzZWQgb24gaXRzIGtleQorCQkgICAgaW50IHNlcCA9IGN1cnJUdXBsZS5pbmRleE9mKCI9Iik7CisJCSAgICBpZiAoY3VyclR1cGxlLnN0YXJ0c1dpdGgoInByb3RvY29sPSIpKSB7CisJCQlwcm90b2NvbCA9IGN1cnJUdXBsZS5zdWJzdHJpbmcoc2VwKzEpOworCQkgICAgfSBlbHNlIGlmIChjdXJyVHVwbGUuc3RhcnRzV2l0aCgidHlwZT0iKSkgeworCQkJU3RyaW5nIHN0clR5cGUgPSBjdXJyVHVwbGUuc3Vic3RyaW5nKHNlcCsxKTsKKwkJCWlmIChzdHJUeXBlLmVxdWFsc0lnbm9yZUNhc2UoInN0b3JlIikpIHsKKwkJCSAgICB0eXBlID0gUHJvdmlkZXIuVHlwZS5TVE9SRTsKKwkJCX0gZWxzZSBpZiAoc3RyVHlwZS5lcXVhbHNJZ25vcmVDYXNlKCJ0cmFuc3BvcnQiKSkgeworCQkJICAgIHR5cGUgPSBQcm92aWRlci5UeXBlLlRSQU5TUE9SVDsKKwkJICAgIAl9CisJCSAgICB9IGVsc2UgaWYgKGN1cnJUdXBsZS5zdGFydHNXaXRoKCJjbGFzcz0iKSkgeworCQkJY2xhc3NOYW1lID0gY3VyclR1cGxlLnN1YnN0cmluZyhzZXArMSk7CisJCSAgICB9IGVsc2UgaWYgKGN1cnJUdXBsZS5zdGFydHNXaXRoKCJ2ZW5kb3I9IikpIHsKKwkJCXZlbmRvciA9IGN1cnJUdXBsZS5zdWJzdHJpbmcoc2VwKzEpOworCQkgICAgfSBlbHNlIGlmIChjdXJyVHVwbGUuc3RhcnRzV2l0aCgidmVyc2lvbj0iKSkgeworCQkJdmVyc2lvbiA9IGN1cnJUdXBsZS5zdWJzdHJpbmcoc2VwKzEpOworCQkgICAgfQorCQl9CisKKwkJLy8gY2hlY2sgaWYgYSB2YWxpZCBQcm92aWRlcjsgZWxzZSwgY29udGludWUKKwkJaWYgKHR5cGUgPT0gbnVsbCB8fCBwcm90b2NvbCA9PSBudWxsIHx8IGNsYXNzTmFtZSA9PSBudWxsIAorCQkgICAgfHwgcHJvdG9jb2wubGVuZ3RoKCkgPD0gMCB8fCBjbGFzc05hbWUubGVuZ3RoKCkgPD0gMCkgeworCQkJCisJCSAgICBsb2dnZXIubG9nKExldmVsLkNPTkZJRywgIkJhZCBwcm92aWRlciBlbnRyeTogezB9IiwKKwkJCQkJCWN1cnJMaW5lKTsKKwkJICAgIGNvbnRpbnVlOworCQl9CisJCVByb3ZpZGVyIHByb3ZpZGVyID0gbmV3IFByb3ZpZGVyKHR5cGUsIHByb3RvY29sLCBjbGFzc05hbWUsCisJCQkJCSAgICAgICAgIHZlbmRvciwgdmVyc2lvbik7CisKKwkJLy8gYWRkIHRoZSBuZXdseS1jcmVhdGVkIFByb3ZpZGVyIHRvIHRoZSBsb29rdXAgdGFibGVzCisJCWFkZFByb3ZpZGVyKHByb3ZpZGVyKTsKKwkgICAgfQorCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGQgYSBwcm92aWRlciB0byB0aGUgc2Vzc2lvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbQlwcm92aWRlcgl0aGUgcHJvdmlkZXIgdG8gYWRkCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNAorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBhZGRQcm92aWRlcihQcm92aWRlciBwcm92aWRlcikgeworCWlmIChwcm92aWRlcnMgPT0gbnVsbCkKKwkgICAgcHJvdmlkZXJzID0gbmV3IEFycmF5TGlzdDxQcm92aWRlcj4oKTsKKwlwcm92aWRlcnMuYWRkKHByb3ZpZGVyKTsKKwlwcm92aWRlcnNCeUNsYXNzTmFtZS5wdXQocHJvdmlkZXIuZ2V0Q2xhc3NOYW1lKCksIHByb3ZpZGVyKTsKKwlpZiAoIXByb3ZpZGVyc0J5UHJvdG9jb2wuY29udGFpbnNLZXkocHJvdmlkZXIuZ2V0UHJvdG9jb2woKSkpCisJICAgIHByb3ZpZGVyc0J5UHJvdG9jb2wucHV0KHByb3ZpZGVyLmdldFByb3RvY29sKCksIHByb3ZpZGVyKTsKKyAgICB9CisKKyAgICAvLyBsb2FkIG1hcHMgaW4gcmV2ZXJzZSBvcmRlciBvZiBwcmVmZXJlbmNlIHNvIHRoYXQgdGhlIHByZWZlcnJlZAorICAgIC8vIG1hcCBpcyBsb2FkZWQgbGFzdCBzaW5jZSBpdHMgZW50cmllcyB3aWxsIG92ZXJyaWRlIHRoZSBwcmV2aW91cyBvbmVzCisgICAgcHJpdmF0ZSB2b2lkIGxvYWRBZGRyZXNzTWFwKENsYXNzPD8+IGNsKSB7CisJU3RyZWFtTG9hZGVyIGxvYWRlciA9IG5ldyBTdHJlYW1Mb2FkZXIoKSB7CisJICAgIEBPdmVycmlkZQorCSAgICBwdWJsaWMgdm9pZCBsb2FkKElucHV0U3RyZWFtIGlzKSB0aHJvd3MgSU9FeGNlcHRpb24geworCQlhZGRyZXNzTWFwLmxvYWQoaXMpOworCSAgICB9CisJfTsKKworCS8vIGxvYWQgZGVmYXVsdCBNRVRBLUlORi9qYXZhbWFpbC5kZWZhdWx0LmFkZHJlc3MubWFwIGZyb20gbWFpbC5qYXIKKwlsb2FkUmVzb3VyY2UoIi9NRVRBLUlORi9qYXZhbWFpbC5kZWZhdWx0LmFkZHJlc3MubWFwIiwgY2wsIGxvYWRlciwgdHJ1ZSk7CisKKwkvLyBsb2FkIHRoZSBNRVRBLUlORi9qYXZhbWFpbC5hZGRyZXNzLm1hcCBmaWxlIHN1cHBsaWVkIGJ5IGFuIGFwcAorCWxvYWRBbGxSZXNvdXJjZXMoIk1FVEEtSU5GL2phdmFtYWlsLmFkZHJlc3MubWFwIiwgY2wsIGxvYWRlcik7CisKKwkvLyBsb2FkIHN5c3RlbS13aWRlIGphdmFtYWlsLmFkZHJlc3MubWFwIGZyb20gdGhlCisJLy8gPGphdmEuaG9tZT4ve2NvbmYsbGlifSBkaXJlY3RvcnkKKwl0cnkgeworCSAgICBpZiAoY29uZkRpciAhPSBudWxsKQorCQlsb2FkRmlsZShjb25mRGlyICsgImphdmFtYWlsLmFkZHJlc3MubWFwIiwgbG9hZGVyKTsKKwl9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBleCkge30KKworCWlmIChhZGRyZXNzTWFwLmlzRW1wdHkoKSkgeworCSAgICBsb2dnZXIuY29uZmlnKCJmYWlsZWQgdG8gbG9hZCBhZGRyZXNzIG1hcCwgdXNpbmcgZGVmYXVsdHMiKTsKKwkgICAgYWRkcmVzc01hcC5wdXQoInJmYzgyMiIsICJzbXRwIik7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgZGVmYXVsdCB0cmFuc3BvcnQgcHJvdG9jb2wgdG8gdXNlIGZvciBhZGRyZXNzZXMgb2YKKyAgICAgKiB0aGUgc3BlY2lmaWVkIHR5cGUuICBOb3JtYWxseSB0aGUgZGVmYXVsdCBpcyBzZXQgYnkgdGhlCisgICAgICogPGNvZGU+amF2YW1haWwuZGVmYXVsdC5hZGRyZXNzLm1hcDwvY29kZT4gb3IKKyAgICAgKiA8Y29kZT5qYXZhbWFpbC5hZGRyZXNzLm1hcDwvY29kZT4gZmlsZXMgb3IgcmVzb3VyY2VzLgorICAgICAqCisgICAgICogQHBhcmFtCWFkZHJlc3N0eXBlCXR5cGUgb2YgYWRkcmVzcworICAgICAqIEBwYXJhbQlwcm90b2NvbAluYW1lIG9mIHByb3RvY29sCisgICAgICogQHNlZSAjZ2V0VHJhbnNwb3J0KEFkZHJlc3MpCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNAorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXRQcm90b2NvbEZvckFkZHJlc3MoU3RyaW5nIGFkZHJlc3N0eXBlLAorCQkJCVN0cmluZyBwcm90b2NvbCkgeworCWlmIChwcm90b2NvbCA9PSBudWxsKQorCSAgICBhZGRyZXNzTWFwLnJlbW92ZShhZGRyZXNzdHlwZSk7CisJZWxzZQorCSAgICBhZGRyZXNzTWFwLnB1dChhZGRyZXNzdHlwZSwgcHJvdG9jb2wpOworICAgIH0KKworICAgIC8qKgorICAgICAqIExvYWQgZnJvbSB0aGUgbmFtZWQgZmlsZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgbG9hZEZpbGUoU3RyaW5nIG5hbWUsIFN0cmVhbUxvYWRlciBsb2FkZXIpIHsKKwlJbnB1dFN0cmVhbSBjbGlzID0gbnVsbDsKKwl0cnkgeworCSAgICBjbGlzID0gbmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0obmV3IEZpbGVJbnB1dFN0cmVhbShuYW1lKSk7CisJICAgIGxvYWRlci5sb2FkKGNsaXMpOworCSAgICBsb2dnZXIubG9nKExldmVsLkNPTkZJRywgInN1Y2Nlc3NmdWxseSBsb2FkZWQgZmlsZTogezB9IiwgbmFtZSk7CisJfSBjYXRjaCAoRmlsZU5vdEZvdW5kRXhjZXB0aW9uIGZleCkgeworCSAgICAvLyBpZ25vcmUgaXQKKwl9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisJICAgIGlmIChsb2dnZXIuaXNMb2dnYWJsZShMZXZlbC5DT05GSUcpKQorCQlsb2dnZXIubG9nKExldmVsLkNPTkZJRywgIm5vdCBsb2FkaW5nIGZpbGU6ICIgKyBuYW1lLCBlKTsKKwl9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBzZXgpIHsKKwkgICAgaWYgKGxvZ2dlci5pc0xvZ2dhYmxlKExldmVsLkNPTkZJRykpCisJCWxvZ2dlci5sb2coTGV2ZWwuQ09ORklHLCAibm90IGxvYWRpbmcgZmlsZTogIiArIG5hbWUsIHNleCk7CisJfSBmaW5hbGx5IHsKKwkgICAgdHJ5IHsKKwkJaWYgKGNsaXMgIT0gbnVsbCkKKwkJICAgIGNsaXMuY2xvc2UoKTsKKwkgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsgfQkvLyBpZ25vcmUgaXQKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogTG9hZCBmcm9tIHRoZSBuYW1lZCByZXNvdXJjZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgbG9hZFJlc291cmNlKFN0cmluZyBuYW1lLCBDbGFzczw/PiBjbCwgU3RyZWFtTG9hZGVyIGxvYWRlciwKKwkJCQlib29sZWFuIGV4cGVjdGVkKSB7CisJSW5wdXRTdHJlYW0gY2xpcyA9IG51bGw7CisJdHJ5IHsKKwkgICAgY2xpcyA9IGdldFJlc291cmNlQXNTdHJlYW0oY2wsIG5hbWUpOworCSAgICBpZiAoY2xpcyAhPSBudWxsKSB7CisJCWxvYWRlci5sb2FkKGNsaXMpOworCQlsb2dnZXIubG9nKExldmVsLkNPTkZJRywgInN1Y2Nlc3NmdWxseSBsb2FkZWQgcmVzb3VyY2U6IHswfSIsCisJCQkJCSAgICBuYW1lKTsKKwkgICAgfSBlbHNlIHsKKwkJaWYgKGV4cGVjdGVkKQorCQkgICAgbG9nZ2VyLmxvZyhMZXZlbC5XQVJOSU5HLAorCQkJCSAgICAiZXhwZWN0ZWQgcmVzb3VyY2Ugbm90IGZvdW5kOiB7MH0iLCBuYW1lKTsKKwkgICAgfQorCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKwkgICAgbG9nZ2VyLmxvZyhMZXZlbC5DT05GSUcsICJFeGNlcHRpb24gbG9hZGluZyByZXNvdXJjZSIsIGUpOworCX0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHNleCkgeworCSAgICBsb2dnZXIubG9nKExldmVsLkNPTkZJRywgIkV4Y2VwdGlvbiBsb2FkaW5nIHJlc291cmNlIiwgc2V4KTsKKwl9IGZpbmFsbHkgeworCSAgICB0cnkgeworCQlpZiAoY2xpcyAhPSBudWxsKQorCQkgICAgY2xpcy5jbG9zZSgpOworCSAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeyB9CS8vIGlnbm9yZSBpdAorCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb2FkIGFsbCBvZiB0aGUgbmFtZWQgcmVzb3VyY2UuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGxvYWRBbGxSZXNvdXJjZXMoU3RyaW5nIG5hbWUsIENsYXNzPD8+IGNsLAorCSAgICBTdHJlYW1Mb2FkZXIgbG9hZGVyKSB7CisJYm9vbGVhbiBhbnlMb2FkZWQgPSBmYWxzZTsKKwl0cnkgeworCSAgICBVUkxbXSB1cmxzOworCSAgICBDbGFzc0xvYWRlciBjbGQgPSBudWxsOworCSAgICAvLyBGaXJzdCB0cnkgdGhlICJhcHBsaWNhdGlvbidzIiBjbGFzcyBsb2FkZXIuCisJICAgIGNsZCA9IGdldENvbnRleHRDbGFzc0xvYWRlcigpOworCSAgICBpZiAoY2xkID09IG51bGwpCisJCWNsZCA9IGNsLmdldENsYXNzTG9hZGVyKCk7CisJICAgIGlmIChjbGQgIT0gbnVsbCkKKwkJdXJscyA9IGdldFJlc291cmNlcyhjbGQsIG5hbWUpOworCSAgICBlbHNlCisJCXVybHMgPSBnZXRTeXN0ZW1SZXNvdXJjZXMobmFtZSk7CisJICAgIGlmICh1cmxzICE9IG51bGwpIHsKKwkJZm9yIChpbnQgaSA9IDA7IGkgPCB1cmxzLmxlbmd0aDsgaSsrKSB7CisJCSAgICBVUkwgdXJsID0gdXJsc1tpXTsKKwkJICAgIElucHV0U3RyZWFtIGNsaXMgPSBudWxsOworCQkgICAgbG9nZ2VyLmxvZyhMZXZlbC5DT05GSUcsICJVUkwgezB9IiwgdXJsKTsKKwkJICAgIHRyeSB7CisJCQljbGlzID0gb3BlblN0cmVhbSh1cmwpOworCQkJaWYgKGNsaXMgIT0gbnVsbCkgeworCQkJICAgIGxvYWRlci5sb2FkKGNsaXMpOworCQkJICAgIGFueUxvYWRlZCA9IHRydWU7CisJCQkgICAgbG9nZ2VyLmxvZyhMZXZlbC5DT05GSUcsCisJCQkJInN1Y2Nlc3NmdWxseSBsb2FkZWQgcmVzb3VyY2U6IHswfSIsIHVybCk7CisJCQl9IGVsc2UgeworCQkJICAgIGxvZ2dlci5sb2coTGV2ZWwuQ09ORklHLAorCQkJCSJub3QgbG9hZGluZyByZXNvdXJjZTogezB9IiwgdXJsKTsKKwkJCX0KKwkJICAgIH0gY2F0Y2ggKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBmZXgpIHsKKwkJCS8vIGlnbm9yZSBpdAorCQkgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9leCkgeworCQkJbG9nZ2VyLmxvZyhMZXZlbC5DT05GSUcsICJFeGNlcHRpb24gbG9hZGluZyByZXNvdXJjZSIsCisJCQkJICAgIGlvZXgpOworCQkgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gc2V4KSB7CisJCQlsb2dnZXIubG9nKExldmVsLkNPTkZJRywgIkV4Y2VwdGlvbiBsb2FkaW5nIHJlc291cmNlIiwKKwkJCQkgICAgc2V4KTsKKwkJICAgIH0gZmluYWxseSB7CisJCQl0cnkgeworCQkJICAgIGlmIChjbGlzICE9IG51bGwpCisJCQkJY2xpcy5jbG9zZSgpOworCQkJfSBjYXRjaCAoSU9FeGNlcHRpb24gY2V4KSB7IH0KKwkJICAgIH0KKwkJfQorCSAgICB9CisJfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJICAgIGxvZ2dlci5sb2coTGV2ZWwuQ09ORklHLCAiRXhjZXB0aW9uIGxvYWRpbmcgcmVzb3VyY2UiLCBleCk7CisJfQorCisJLy8gaWYgZmFpbGVkIHRvIGxvYWQgYW55dGhpbmcsIGZhbGwgYmFjayB0byBvbGQgdGVjaG5pcXVlLCBqdXN0IGluIGNhc2UKKwlpZiAoIWFueUxvYWRlZCkgeworCSAgICAvKgorCSAgICBsb2dnZXIuY29uZmlnKCIhYW55TG9hZGVkIik7CisJICAgICovCisJICAgIGxvYWRSZXNvdXJjZSgiLyIgKyBuYW1lLCBjbCwgbG9hZGVyLCBmYWxzZSk7CisJfQorICAgIH0KKworICAgIC8qCisgICAgICogRm9sbG93aW5nIGFyZSBzZWN1cml0eSByZWxhdGVkIG1ldGhvZHMgdGhhdCB3b3JrIG9uIEpESyAxLjIgb3IgbmV3ZXIuCisgICAgICovCisKKyAgICBzdGF0aWMgQ2xhc3NMb2FkZXIgZ2V0Q29udGV4dENsYXNzTG9hZGVyKCkgeworCXJldHVybiBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZCgKKwkJbmV3IFByaXZpbGVnZWRBY3Rpb248Q2xhc3NMb2FkZXI+KCkgeworCQkgICAgQE92ZXJyaWRlCisJCSAgICBwdWJsaWMgQ2xhc3NMb2FkZXIgcnVuKCkgeworCQkJQ2xhc3NMb2FkZXIgY2wgPSBudWxsOworCQkJdHJ5IHsKKwkJCSAgICBjbCA9IFRocmVhZC5jdXJyZW50VGhyZWFkKCkuZ2V0Q29udGV4dENsYXNzTG9hZGVyKCk7CisJCQl9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBleCkgeworCQkJfQorCQkJcmV0dXJuIGNsOworCQkgICAgfQorCQl9CisJKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBJbnB1dFN0cmVhbSBnZXRSZXNvdXJjZUFzU3RyZWFtKGZpbmFsIENsYXNzPD8+IGMsCisJCQkJZmluYWwgU3RyaW5nIG5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJdHJ5IHsKKwkgICAgcmV0dXJuIEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKAorCQkgICAgbmV3IFByaXZpbGVnZWRFeGNlcHRpb25BY3Rpb248SW5wdXRTdHJlYW0+KCkgeworCQkJQE92ZXJyaWRlCisJCQlwdWJsaWMgSW5wdXRTdHJlYW0gcnVuKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkJCSAgICB0cnkgeworCQkJCXJldHVybiBjLmdldFJlc291cmNlQXNTdHJlYW0obmFtZSk7CisJCQkgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBlKSB7CisJCQkJLy8gZ3JhY2VmdWxseSBoYW5kbGUgQ2xhc3NMb2FkZXIgYnVncyAoVG9tY2F0KQorCQkJCUlPRXhjZXB0aW9uIGlvZXggPSBuZXcgSU9FeGNlcHRpb24oCisJCQkJICAgICJDbGFzc0xvYWRlci5nZXRSZXNvdXJjZUFzU3RyZWFtIGZhaWxlZCIpOworCQkJCWlvZXguaW5pdENhdXNlKGUpOworCQkJCXRocm93IGlvZXg7CisJCQkgICAgfQorCQkJfQorCQkgICAgfQorCSAgICApOworCX0gY2F0Y2ggKFByaXZpbGVnZWRBY3Rpb25FeGNlcHRpb24gZSkgeworCSAgICB0aHJvdyAoSU9FeGNlcHRpb24pZS5nZXRFeGNlcHRpb24oKTsKKwl9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgVVJMW10gZ2V0UmVzb3VyY2VzKGZpbmFsIENsYXNzTG9hZGVyIGNsLCBmaW5hbCBTdHJpbmcgbmFtZSkgeworCXJldHVybiBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZChuZXcgUHJpdmlsZWdlZEFjdGlvbjxVUkxbXT4oKSB7CisJICAgIEBPdmVycmlkZQorCSAgICBwdWJsaWMgVVJMW10gcnVuKCkgeworCQlVUkxbXSByZXQgPSBudWxsOworCQl0cnkgeworCQkgICAgTGlzdDxVUkw+IHYgPSBDb2xsZWN0aW9ucy5saXN0KGNsLmdldFJlc291cmNlcyhuYW1lKSk7CisJCSAgICBpZiAoIXYuaXNFbXB0eSgpKSB7CisJCQlyZXQgPSBuZXcgVVJMW3Yuc2l6ZSgpXTsKKwkJCXYudG9BcnJheShyZXQpOworCQkgICAgfQorCQl9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2V4KSB7CisJCX0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGV4KSB7IH0KKwkJcmV0dXJuIHJldDsKKwkgICAgfQorCX0pOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIFVSTFtdIGdldFN5c3RlbVJlc291cmNlcyhmaW5hbCBTdHJpbmcgbmFtZSkgeworCXJldHVybiBBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZChuZXcgUHJpdmlsZWdlZEFjdGlvbjxVUkxbXT4oKSB7CisJICAgIEBPdmVycmlkZQorCSAgICBwdWJsaWMgVVJMW10gcnVuKCkgeworCQlVUkxbXSByZXQgPSBudWxsOworCQl0cnkgeworCQkgICAgTGlzdDxVUkw+IHYgPSBDb2xsZWN0aW9ucy5saXN0KAorCQkJICAgIENsYXNzTG9hZGVyLmdldFN5c3RlbVJlc291cmNlcyhuYW1lKSk7CisJCSAgICBpZiAoIXYuaXNFbXB0eSgpKSB7CisJCQlyZXQgPSBuZXcgVVJMW3Yuc2l6ZSgpXTsKKwkJCXYudG9BcnJheShyZXQpOworCQkgICAgfQorCQl9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2V4KSB7CisJCX0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGV4KSB7IH0KKwkJcmV0dXJuIHJldDsKKwkgICAgfQorCX0pOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIElucHV0U3RyZWFtIG9wZW5TdHJlYW0oZmluYWwgVVJMIHVybCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwl0cnkgeworCSAgICByZXR1cm4gQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQoCisJCSAgICBuZXcgUHJpdmlsZWdlZEV4Y2VwdGlvbkFjdGlvbjxJbnB1dFN0cmVhbT4oKSB7CisJCQlAT3ZlcnJpZGUKKwkJCXB1YmxpYyBJbnB1dFN0cmVhbSBydW4oKSB0aHJvd3MgSU9FeGNlcHRpb24geworCQkJICAgIHJldHVybiB1cmwub3BlblN0cmVhbSgpOworCQkJfQorCQkgICAgfQorCSAgICApOworCX0gY2F0Y2ggKFByaXZpbGVnZWRBY3Rpb25FeGNlcHRpb24gZSkgeworCSAgICB0aHJvdyAoSU9FeGNlcHRpb24pZS5nZXRFeGNlcHRpb24oKTsKKwl9CisgICAgfQorCisgICAgRXZlbnRRdWV1ZSBnZXRFdmVudFF1ZXVlKCkgeworCXJldHVybiBxOworICAgIH0KK30KKworLyoqCisgKiBTdXBwb3J0IGludGVyZmFjZSB0byBnZW5lcmFsaXplCisgKiBjb2RlIHRoYXQgbG9hZHMgcmVzb3VyY2VzIGZyb20gc3RyZWFtLgorICovCitpbnRlcmZhY2UgU3RyZWFtTG9hZGVyIHsKKyAgICBwdWJsaWMgdm9pZCBsb2FkKElucHV0U3RyZWFtIGlzKSB0aHJvd3MgSU9FeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9TdG9yZS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvU3RvcmUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNjc4YTA5Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvU3RvcmUuamF2YQpAQCAtMCwwICsxLDMwMSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsOworCitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmEubmV0Lio7CitpbXBvcnQgamF2YS51dGlsLio7CitpbXBvcnQgamF2YXgubWFpbC5ldmVudC4qOworCisvKioKKyAqIEFuIGFic3RyYWN0IGNsYXNzIHRoYXQgbW9kZWxzIGEgbWVzc2FnZSBzdG9yZSBhbmQgaXRzCisgKiBhY2Nlc3MgcHJvdG9jb2wsIGZvciBzdG9yaW5nIGFuZCByZXRyaWV2aW5nIG1lc3NhZ2VzLiAKKyAqIFN1YmNsYXNzZXMgcHJvdmlkZSBhY3R1YWwgaW1wbGVtZW50YXRpb25zLiA8cD4KKyAqCisgKiBOb3RlIHRoYXQgPGNvZGU+U3RvcmU8L2NvZGU+IGV4dGVuZHMgdGhlIDxjb2RlPlNlcnZpY2U8L2NvZGU+CisgKiBjbGFzcywgd2hpY2ggcHJvdmlkZXMgbWFueSBjb21tb24gbWV0aG9kcyBmb3IgbmFtaW5nIHN0b3JlcywKKyAqIGNvbm5lY3RpbmcgdG8gc3RvcmVzLCBhbmQgbGlzdGVuaW5nIHRvIGNvbm5lY3Rpb24gZXZlbnRzLgorICoKKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICoKKyAqIEBzZWUgamF2YXgubWFpbC5TZXJ2aWNlCisgKiBAc2VlIGphdmF4Lm1haWwuZXZlbnQuQ29ubmVjdGlvbkV2ZW50CisgKiBAc2VlIGphdmF4Lm1haWwuZXZlbnQuU3RvcmVFdmVudAorICovCisKK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBTdG9yZSBleHRlbmRzIFNlcnZpY2UgeworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jc2Vzc2lvbiBTZXNzaW9uIG9iamVjdCBmb3IgdGhpcyBTdG9yZS4KKyAgICAgKiBAcGFyYW0JdXJsbmFtZQlVUkxOYW1lIG9iamVjdCB0byBiZSB1c2VkIGZvciB0aGlzIFN0b3JlCisgICAgICovCisgICAgcHJvdGVjdGVkIFN0b3JlKFNlc3Npb24gc2Vzc2lvbiwgVVJMTmFtZSB1cmxuYW1lKSB7CisJc3VwZXIoc2Vzc2lvbiwgdXJsbmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIEZvbGRlciBvYmplY3QgdGhhdCByZXByZXNlbnRzIHRoZSAncm9vdCcgb2YKKyAgICAgKiB0aGUgZGVmYXVsdCBuYW1lc3BhY2UgcHJlc2VudGVkIHRvIHRoZSB1c2VyIGJ5IHRoZSBTdG9yZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHJvb3QgRm9sZGVyCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBTdG9yZSBpcyBub3QgY29ubmVjdGVkLgorICAgICAqIEBleGNlcHRpb24gCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgRm9sZGVyIGdldERlZmF1bHRGb2xkZXIoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBGb2xkZXIgb2JqZWN0IGNvcnJlc3BvbmRpbmcgdG8gdGhlIGdpdmVuIG5hbWUuIE5vdGUKKyAgICAgKiB0aGF0IGEgRm9sZGVyIG9iamVjdCBpcyByZXR1cm5lZCBldmVuIGlmIHRoZSBuYW1lZCBmb2xkZXIgZG9lcworICAgICAqIG5vdCBwaHlzaWNhbGx5IGV4aXN0IG9uIHRoZSBTdG9yZS4gVGhlIDxjb2RlPmV4aXN0cygpPC9jb2RlPiAKKyAgICAgKiBtZXRob2Qgb24gdGhlIGZvbGRlciBvYmplY3QgaW5kaWNhdGVzIHdoZXRoZXIgdGhpcyBmb2xkZXIgcmVhbGx5CisgICAgICogZXhpc3RzLiA8cD4KKyAgICAgKgorICAgICAqIEZvbGRlciBvYmplY3RzIGFyZSBub3QgY2FjaGVkIGJ5IHRoZSBTdG9yZSwgc28gaW52b2tpbmcgdGhpcworICAgICAqIG1ldGhvZCBvbiB0aGUgc2FtZSBuYW1lIG11bHRpcGxlIHRpbWVzIHdpbGwgcmV0dXJuIHRoYXQgbWFueQorICAgICAqIGRpc3RpbmN0IEZvbGRlciBvYmplY3RzLgorICAgICAqCisgICAgICogQHBhcmFtIG5hbWUgCVRoZSBuYW1lIG9mIHRoZSBGb2xkZXIuIEluIHNvbWUgU3RvcmVzLCBuYW1lIGNhbgorICAgICAqCQkJYmUgYW4gYWJzb2x1dGUgcGF0aCBpZiBpdCBzdGFydHMgd2l0aCB0aGUKKyAgICAgKgkJCWhpZXJhcmNoeSBkZWxpbWl0ZXIuIEVsc2UgaXQgaXMgaW50ZXJwcmV0ZWQKKyAgICAgKgkJCXJlbGF0aXZlIHRvIHRoZSAncm9vdCcgb2YgdGhpcyBuYW1lc3BhY2UuCisgICAgICogQHJldHVybgkJRm9sZGVyIG9iamVjdAorICAgICAqIEBleGNlcHRpb24gCUlsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIFN0b3JlIGlzIG5vdCBjb25uZWN0ZWQuCisgICAgICogQGV4Y2VwdGlvbiAJTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBvdGhlciBmYWlsdXJlcworICAgICAqIEBzZWUgCQlGb2xkZXIjZXhpc3RzCisgICAgICogQHNlZQkJRm9sZGVyI2NyZWF0ZQorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBGb2xkZXIgZ2V0Rm9sZGVyKFN0cmluZyBuYW1lKQorCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybiBhIGNsb3NlZCBGb2xkZXIgb2JqZWN0LCBjb3JyZXNwb25kaW5nIHRvIHRoZSBnaXZlbiAKKyAgICAgKiBVUkxOYW1lLiBUaGUgc3RvcmUgc3BlY2lmaWVkIGluIHRoZSBnaXZlbiBVUkxOYW1lIHNob3VsZAorICAgICAqIHJlZmVyIHRvIHRoaXMgU3RvcmUgb2JqZWN0LiA8cD4KKyAgICAgKgorICAgICAqIEltcGxlbWVudGF0aW9ucyBvZiB0aGlzIG1ldGhvZCBtYXkgb2J0YWluIHRoZSBuYW1lIG9mIHRoZQorICAgICAqIGFjdHVhbCBmb2xkZXIgdXNpbmcgdGhlIDxjb2RlPmdldEZpbGUoKTwvY29kZT4gbWV0aG9kIG9uCisgICAgICogVVJMTmFtZSwgYW5kIHVzZSB0aGF0IG5hbWUgdG8gY3JlYXRlIHRoZSBmb2xkZXIuCisgICAgICogCisgICAgICogQHBhcmFtIHVybAlVUkxOYW1lIHRoYXQgZGVub3RlcyBhIGZvbGRlcgorICAgICAqIEByZXR1cm4JCUZvbGRlciBvYmplY3QKKyAgICAgKiBAZXhjZXB0aW9uIAlJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBTdG9yZSBpcyBub3QgY29ubmVjdGVkLgorICAgICAqIEBleGNlcHRpb24gCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKiBAc2VlIAkJVVJMTmFtZQorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBGb2xkZXIgZ2V0Rm9sZGVyKFVSTE5hbWUgdXJsKQorCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybiBhIHNldCBvZiBmb2xkZXJzIHJlcHJlc2VudGluZyB0aGUgPGk+cGVyc29uYWw8L2k+IG5hbWVzcGFjZXMKKyAgICAgKiBmb3IgdGhlIGN1cnJlbnQgdXNlci4gIEEgcGVyc29uYWwgbmFtZXNwYWNlIGlzIGEgc2V0IG9mIG5hbWVzIHRoYXQKKyAgICAgKiBpcyBjb25zaWRlcmVkIHdpdGhpbiB0aGUgcGVyc29uYWwgc2NvcGUgb2YgdGhlIGF1dGhlbnRpY2F0ZWQgdXNlci4KKyAgICAgKiBUeXBpY2FsbHksIG9ubHkgdGhlIGF1dGhlbnRpY2F0ZWQgdXNlciBoYXMgYWNjZXNzIHRvIG1haWwgZm9sZGVycworICAgICAqIGluIHRoZWlyIHBlcnNvbmFsIG5hbWVzcGFjZS4gIElmIGFuIElOQk9YIGV4aXN0cyBmb3IgYSB1c2VyLCBpdAorICAgICAqIG11c3QgYXBwZWFyIHdpdGhpbiB0aGUgdXNlcidzIHBlcnNvbmFsIG5hbWVzcGFjZS4gIEluIHRoZQorICAgICAqIHR5cGljYWwgY2FzZSwgdGhlcmUgc2hvdWxkIGJlIG9ubHkgb25lIHBlcnNvbmFsIG5hbWVzcGFjZSBmb3IgZWFjaAorICAgICAqIHVzZXIgaW4gZWFjaCBTdG9yZS4gPHA+CisgICAgICoKKyAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIHJldHVybnMgYW4gYXJyYXkgd2l0aCBhIHNpbmdsZSBlbnRyeSBjb250YWluaW5nCisgICAgICogdGhlIHJldHVybiB2YWx1ZSBvZiB0aGUgPGNvZGU+Z2V0RGVmYXVsdEZvbGRlcjwvY29kZT4gbWV0aG9kLgorICAgICAqIFN1YmNsYXNzZXMgc2hvdWxkIG92ZXJyaWRlIHRoaXMgbWV0aG9kIHRvIHJldHVybiBhcHByb3ByaWF0ZSBpbmZvcm1hdGlvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4JCWFycmF5IG9mIEZvbGRlciBvYmplY3RzCisgICAgICogQGV4Y2VwdGlvbiAJSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgU3RvcmUgaXMgbm90IGNvbm5lY3RlZC4KKyAgICAgKiBAZXhjZXB0aW9uIAlNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICogQHNpbmNlCQlKYXZhTWFpbCAxLjIKKyAgICAgKi8KKyAgICBwdWJsaWMgRm9sZGVyW10gZ2V0UGVyc29uYWxOYW1lc3BhY2VzKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJcmV0dXJuIG5ldyBGb2xkZXJbXSB7IGdldERlZmF1bHRGb2xkZXIoKSB9OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiBhIHNldCBvZiBmb2xkZXJzIHJlcHJlc2VudGluZyB0aGUgbmFtZXNwYWNlcyBmb3IKKyAgICAgKiA8Y29kZT51c2VyPC9jb2RlPi4gIFRoZSBuYW1lc3BhY2VzIHJldHVybmVkIHJlcHJlc2VudCB0aGUKKyAgICAgKiBwZXJzb25hbCBuYW1lc3BhY2VzIGZvciB0aGUgdXNlci4gIFRvIGFjY2VzcyBtYWlsIGZvbGRlcnMgaW4gdGhlCisgICAgICogb3RoZXIgdXNlcidzIG5hbWVzcGFjZSwgdGhlIGN1cnJlbnRseSBhdXRoZW50aWNhdGVkIHVzZXIgbXVzdCBiZQorICAgICAqIGV4cGxpY2l0bHkgZ3JhbnRlZCBhY2Nlc3MgcmlnaHRzLiAgRm9yIGV4YW1wbGUsIGl0IGlzIGNvbW1vbiBmb3IKKyAgICAgKiBhIG1hbmFnZXIgdG8gZ3JhbnQgdG8gdGhlaXIgc2VjcmV0YXJ5IGFjY2VzcyByaWdodHMgdG8gdGhlaXIKKyAgICAgKiBtYWlsIGZvbGRlcnMuIDxwPgorICAgICAqCisgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiByZXR1cm5zIGFuIGVtcHR5IGFycmF5LiAgU3ViY2xhc3NlcyBzaG91bGQKKyAgICAgKiBvdmVycmlkZSB0aGlzIG1ldGhvZCB0byByZXR1cm4gYXBwcm9wcmlhdGUgaW5mb3JtYXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0JdXNlcgl0aGUgdXNlciBuYW1lCisgICAgICogQHJldHVybgkJYXJyYXkgb2YgRm9sZGVyIG9iamVjdHMKKyAgICAgKiBAZXhjZXB0aW9uIAlJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBTdG9yZSBpcyBub3QgY29ubmVjdGVkLgorICAgICAqIEBleGNlcHRpb24gCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuMgorICAgICAqLworICAgIHB1YmxpYyBGb2xkZXJbXSBnZXRVc2VyTmFtZXNwYWNlcyhTdHJpbmcgdXNlcikKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gbmV3IEZvbGRlclswXTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYSBzZXQgb2YgZm9sZGVycyByZXByZXNlbnRpbmcgdGhlIDxpPnNoYXJlZDwvaT4gbmFtZXNwYWNlcy4KKyAgICAgKiBBIHNoYXJlZCBuYW1lc3BhY2UgaXMgYSBuYW1lc3BhY2UgdGhhdCBjb25zaXN0cyBvZiBtYWlsIGZvbGRlcnMKKyAgICAgKiB0aGF0IGFyZSBpbnRlbmRlZCB0byBiZSBzaGFyZWQgYW1vbmdzdCB1c2VycyBhbmQgZG8gbm90IGV4aXN0CisgICAgICogd2l0aGluIGEgdXNlcidzIHBlcnNvbmFsIG5hbWVzcGFjZS4gPHA+CisgICAgICoKKyAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIHJldHVybnMgYW4gZW1wdHkgYXJyYXkuICBTdWJjbGFzc2VzIHNob3VsZAorICAgICAqIG92ZXJyaWRlIHRoaXMgbWV0aG9kIHRvIHJldHVybiBhcHByb3ByaWF0ZSBpbmZvcm1hdGlvbi4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24gCUlsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIFN0b3JlIGlzIG5vdCBjb25uZWN0ZWQuCisgICAgICogQGV4Y2VwdGlvbiAJTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBvdGhlciBmYWlsdXJlcworICAgICAqIEByZXR1cm4JCWFycmF5IG9mIEZvbGRlciBvYmplY3RzCisgICAgICogQHNpbmNlCQlKYXZhTWFpbCAxLjIKKyAgICAgKi8KKyAgICBwdWJsaWMgRm9sZGVyW10gZ2V0U2hhcmVkTmFtZXNwYWNlcygpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXJldHVybiBuZXcgRm9sZGVyWzBdOworICAgIH0KKworICAgIC8vIFZlY3RvciBvZiBTdG9yZSBsaXN0ZW5lcnMKKyAgICBwcml2YXRlIHZvbGF0aWxlIFZlY3RvcjxTdG9yZUxpc3RlbmVyPiBzdG9yZUxpc3RlbmVycyA9IG51bGw7CisKKyAgICAvKioKKyAgICAgKiBBZGQgYSBsaXN0ZW5lciBmb3IgU3RvcmVFdmVudHMgb24gdGhpcyBTdG9yZS4gPHA+CisgICAgICoKKyAgICAgKiBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBwcm92aWRlZCBoZXJlIGFkZHMgdGhpcyBsaXN0ZW5lcgorICAgICAqIHRvIGFuIGludGVybmFsIGxpc3Qgb2YgU3RvcmVMaXN0ZW5lcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbCAgICAgICAgIHRoZSBMaXN0ZW5lciBmb3IgU3RvcmUgZXZlbnRzCisgICAgICogQHNlZSAgICAgICAgICAgICBqYXZheC5tYWlsLmV2ZW50LlN0b3JlRXZlbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgYWRkU3RvcmVMaXN0ZW5lcihTdG9yZUxpc3RlbmVyIGwpIHsKKwlpZiAoc3RvcmVMaXN0ZW5lcnMgPT0gbnVsbCkKKwkgICAgc3RvcmVMaXN0ZW5lcnMgPSBuZXcgVmVjdG9yPD4oKTsKKwlzdG9yZUxpc3RlbmVycy5hZGRFbGVtZW50KGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZSBhIGxpc3RlbmVyIGZvciBTdG9yZSBldmVudHMuIDxwPgorICAgICAqCisgICAgICogVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gcHJvdmlkZWQgaGVyZSByZW1vdmVzIHRoaXMgbGlzdGVuZXIKKyAgICAgKiBmcm9tIHRoZSBpbnRlcm5hbCBsaXN0IG9mIFN0b3JlTGlzdGVuZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIGwgICAgICAgICB0aGUgbGlzdGVuZXIKKyAgICAgKiBAc2VlICAgICAgICAgICAgICNhZGRTdG9yZUxpc3RlbmVyCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHJlbW92ZVN0b3JlTGlzdGVuZXIoU3RvcmVMaXN0ZW5lciBsKSB7CisJaWYgKHN0b3JlTGlzdGVuZXJzICE9IG51bGwpCisJICAgIHN0b3JlTGlzdGVuZXJzLnJlbW92ZUVsZW1lbnQobCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTm90aWZ5IGFsbCBTdG9yZUxpc3RlbmVycy4gU3RvcmUgaW1wbGVtZW50YXRpb25zIGFyZQorICAgICAqIGV4cGVjdGVkIHRvIHVzZSB0aGlzIG1ldGhvZCB0byBicm9hZGNhc3QgU3RvcmVFdmVudHMuIDxwPgorICAgICAqCisgICAgICogVGhlIHByb3ZpZGVkIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gcXVldWVzIHRoZSBldmVudCBpbnRvCisgICAgICogYW4gaW50ZXJuYWwgZXZlbnQgcXVldWUuIEFuIGV2ZW50IGRpc3BhdGNoZXIgdGhyZWFkIGRlcXVldWVzCisgICAgICogZXZlbnRzIGZyb20gdGhlIHF1ZXVlIGFuZCBkaXNwYXRjaGVzIHRoZW0gdG8gdGhlIHJlZ2lzdGVyZWQKKyAgICAgKiBTdG9yZUxpc3RlbmVycy4gTm90ZSB0aGF0IHRoZSBldmVudCBkaXNwYXRjaGluZyBvY2N1cnMKKyAgICAgKiBpbiBhIHNlcGFyYXRlIHRocmVhZCwgdGh1cyBhdm9pZGluZyBwb3RlbnRpYWwgZGVhZGxvY2sgcHJvYmxlbXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0JdHlwZQl0aGUgU3RvcmVFdmVudCB0eXBlCisgICAgICogQHBhcmFtCW1lc3NhZ2UJYSBtZXNzYWdlIGZvciB0aGUgU3RvcmVFdmVudAorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIG5vdGlmeVN0b3JlTGlzdGVuZXJzKGludCB0eXBlLCBTdHJpbmcgbWVzc2FnZSkgeworICAgCWlmIChzdG9yZUxpc3RlbmVycyA9PSBudWxsKQorCSAgICByZXR1cm47CisJCisJU3RvcmVFdmVudCBlID0gbmV3IFN0b3JlRXZlbnQodGhpcywgdHlwZSwgbWVzc2FnZSk7CisJcXVldWVFdmVudChlLCBzdG9yZUxpc3RlbmVycyk7CisgICAgfQorCisgICAgLy8gVmVjdG9yIG9mIGZvbGRlciBsaXN0ZW5lcnMKKyAgICBwcml2YXRlIHZvbGF0aWxlIFZlY3RvcjxGb2xkZXJMaXN0ZW5lcj4gZm9sZGVyTGlzdGVuZXJzID0gbnVsbDsKKworICAgIC8qKgorICAgICAqIEFkZCBhIGxpc3RlbmVyIGZvciBGb2xkZXIgZXZlbnRzIG9uIGFueSBGb2xkZXIgb2JqZWN0IAorICAgICAqIG9idGFpbmVkIGZyb20gdGhpcyBTdG9yZS4gRm9sZGVyRXZlbnRzIGFyZSBkZWxpdmVyZWQgdG8KKyAgICAgKiBGb2xkZXJMaXN0ZW5lcnMgb24gdGhlIGFmZmVjdGVkIEZvbGRlciBhcyB3ZWxsIGFzIHRvIAorICAgICAqIEZvbGRlckxpc3RlbmVycyBvbiB0aGUgY29udGFpbmluZyBTdG9yZS4gPHA+CisgICAgICoKKyAgICAgKiBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBwcm92aWRlZCBoZXJlIGFkZHMgdGhpcyBsaXN0ZW5lcgorICAgICAqIHRvIGFuIGludGVybmFsIGxpc3Qgb2YgRm9sZGVyTGlzdGVuZXJzLgorICAgICAqCisgICAgICogQHBhcmFtIGwgICAgICAgICB0aGUgTGlzdGVuZXIgZm9yIEZvbGRlciBldmVudHMKKyAgICAgKiBAc2VlICAgICAgICAgICAgIGphdmF4Lm1haWwuZXZlbnQuRm9sZGVyRXZlbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgYWRkRm9sZGVyTGlzdGVuZXIoRm9sZGVyTGlzdGVuZXIgbCkgeworICAgCWlmIChmb2xkZXJMaXN0ZW5lcnMgPT0gbnVsbCkKKwkgICAgZm9sZGVyTGlzdGVuZXJzID0gbmV3IFZlY3Rvcjw+KCk7CisJZm9sZGVyTGlzdGVuZXJzLmFkZEVsZW1lbnQobCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlIGEgbGlzdGVuZXIgZm9yIEZvbGRlciBldmVudHMuIDxwPgorICAgICAqCisgICAgICogVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gcHJvdmlkZWQgaGVyZSByZW1vdmVzIHRoaXMgbGlzdGVuZXIKKyAgICAgKiBmcm9tIHRoZSBpbnRlcm5hbCBsaXN0IG9mIEZvbGRlckxpc3RlbmVycy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsICAgICAgICAgdGhlIGxpc3RlbmVyCisgICAgICogQHNlZSAgICAgICAgICAgICAjYWRkRm9sZGVyTGlzdGVuZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgcmVtb3ZlRm9sZGVyTGlzdGVuZXIoRm9sZGVyTGlzdGVuZXIgbCkgeworICAgCWlmIChmb2xkZXJMaXN0ZW5lcnMgIT0gbnVsbCkKKwkgICAgZm9sZGVyTGlzdGVuZXJzLnJlbW92ZUVsZW1lbnQobCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTm90aWZ5IGFsbCBGb2xkZXJMaXN0ZW5lcnMuIFN0b3JlIGltcGxlbWVudGF0aW9ucyBhcmUKKyAgICAgKiBleHBlY3RlZCB0byB1c2UgdGhpcyBtZXRob2QgdG8gYnJvYWRjYXN0IEZvbGRlciBldmVudHMuIDxwPgorICAgICAqCisgICAgICogVGhlIHByb3ZpZGVkIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gcXVldWVzIHRoZSBldmVudCBpbnRvCisgICAgICogYW4gaW50ZXJuYWwgZXZlbnQgcXVldWUuIEFuIGV2ZW50IGRpc3BhdGNoZXIgdGhyZWFkIGRlcXVldWVzCisgICAgICogZXZlbnRzIGZyb20gdGhlIHF1ZXVlIGFuZCBkaXNwYXRjaGVzIHRoZW0gdG8gdGhlIHJlZ2lzdGVyZWQKKyAgICAgKiBGb2xkZXJMaXN0ZW5lcnMuIE5vdGUgdGhhdCB0aGUgZXZlbnQgZGlzcGF0Y2hpbmcgb2NjdXJzCisgICAgICogaW4gYSBzZXBhcmF0ZSB0aHJlYWQsIHRodXMgYXZvaWRpbmcgcG90ZW50aWFsIGRlYWRsb2NrIHByb2JsZW1zLgorICAgICAqCisgICAgICogQHBhcmFtCXR5cGUJdHlwZSBvZiBGb2xkZXJFdmVudAorICAgICAqIEBwYXJhbQlmb2xkZXIJYWZmZWN0ZWQgRm9sZGVyCisgICAgICogQHNlZQkJI25vdGlmeUZvbGRlclJlbmFtZWRMaXN0ZW5lcnMKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBub3RpZnlGb2xkZXJMaXN0ZW5lcnMoaW50IHR5cGUsIEZvbGRlciBmb2xkZXIpIHsKKyAgIAlpZiAoZm9sZGVyTGlzdGVuZXJzID09IG51bGwpIAorCSAgICByZXR1cm47CisJCisJRm9sZGVyRXZlbnQgZSA9IG5ldyBGb2xkZXJFdmVudCh0aGlzLCBmb2xkZXIsIHR5cGUpOworCXF1ZXVlRXZlbnQoZSwgZm9sZGVyTGlzdGVuZXJzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBOb3RpZnkgYWxsIEZvbGRlckxpc3RlbmVycyBhYm91dCB0aGUgcmVuYW1pbmcgb2YgYSBmb2xkZXIuCisgICAgICogU3RvcmUgaW1wbGVtZW50YXRpb25zIGFyZSBleHBlY3RlZCB0byB1c2UgdGhpcyBtZXRob2QgdG8gYnJvYWRjYXN0IAorICAgICAqIEZvbGRlciBldmVudHMgaW5kaWNhdGluZyB0aGUgcmVuYW1pbmcgb2YgZm9sZGVycy4gPHA+CisgICAgICoKKyAgICAgKiBUaGUgcHJvdmlkZWQgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBxdWV1ZXMgdGhlIGV2ZW50IGludG8KKyAgICAgKiBhbiBpbnRlcm5hbCBldmVudCBxdWV1ZS4gQW4gZXZlbnQgZGlzcGF0Y2hlciB0aHJlYWQgZGVxdWV1ZXMKKyAgICAgKiBldmVudHMgZnJvbSB0aGUgcXVldWUgYW5kIGRpc3BhdGNoZXMgdGhlbSB0byB0aGUgcmVnaXN0ZXJlZAorICAgICAqIEZvbGRlckxpc3RlbmVycy4gTm90ZSB0aGF0IHRoZSBldmVudCBkaXNwYXRjaGluZyBvY2N1cnMKKyAgICAgKiBpbiBhIHNlcGFyYXRlIHRocmVhZCwgdGh1cyBhdm9pZGluZyBwb3RlbnRpYWwgZGVhZGxvY2sgcHJvYmxlbXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jb2xkRgl0aGUgZm9sZGVyIGJlaW5nIHJlbmFtZWQKKyAgICAgKiBAcGFyYW0JbmV3Rgl0aGUgZm9sZGVyIHJlcHJlc2VudGluZyB0aGUgbmV3IG5hbWUuCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuMQorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIG5vdGlmeUZvbGRlclJlbmFtZWRMaXN0ZW5lcnMoRm9sZGVyIG9sZEYsIEZvbGRlciBuZXdGKSB7CisgICAJaWYgKGZvbGRlckxpc3RlbmVycyA9PSBudWxsKSAKKwkgICAgcmV0dXJuOworCQorCUZvbGRlckV2ZW50IGUgPSBuZXcgRm9sZGVyRXZlbnQodGhpcywgb2xkRiwgbmV3RixGb2xkZXJFdmVudC5SRU5BTUVEKTsKKwlxdWV1ZUV2ZW50KGUsIGZvbGRlckxpc3RlbmVycyk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvU3RvcmVDbG9zZWRFeGNlcHRpb24uamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL1N0b3JlQ2xvc2VkRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjlhMGJiYgotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL1N0b3JlQ2xvc2VkRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw4MyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsOworCisvKioKKyAqIFRoaXMgZXhjZXB0aW9uIGlzIHRocm93biB3aGVuIGEgbWV0aG9kIGlzIGludm9rZWQgb24gYSBNZXNzYWdpbmcgb2JqZWN0CisgKiBhbmQgdGhlIFN0b3JlIHRoYXQgb3ducyB0aGF0IG9iamVjdCBoYXMgZGllZCBkdWUgdG8gc29tZSByZWFzb24uCisgKiBUaGlzIGV4Y2VwdGlvbiBzaG91bGQgYmUgdHJlYXRlZCBhcyBhIGZhdGFsIGVycm9yOyBpbiBwYXJ0aWN1bGFyIGFueQorICogbWVzc2FnaW5nIG9iamVjdCBiZWxvbmdpbmcgdG8gdGhhdCBTdG9yZSBtdXN0IGJlIGNvbnNpZGVyZWQgaW52YWxpZC4gPHA+CisgKgorICogVGhlIGNvbm5lY3QgbWV0aG9kIG1heSBiZSBpbnZva2VkIG9uIHRoZSBkZWFkIFN0b3JlIG9iamVjdCB0byAKKyAqIHJldml2ZSBpdC4gPHA+CisgKgorICogVGhlIGdldE1lc3NhZ2UoKSBtZXRob2QgcmV0dXJucyBtb3JlIGRldGFpbGVkIGluZm9ybWF0aW9uIGFib3V0IHRoZQorICogZXJyb3IgdGhhdCBjYXVzZWQgdGhpcyBleGNlcHRpb24uIDxwPgorICoKKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKi8KKworcHVibGljIGNsYXNzIFN0b3JlQ2xvc2VkRXhjZXB0aW9uIGV4dGVuZHMgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKyAgICB0cmFuc2llbnQgcHJpdmF0ZSBTdG9yZSBzdG9yZTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0zMTQ1MzkyMzM2MTIwMDgyNjU1TDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBTdG9yZUNsb3NlZEV4Y2VwdGlvbiB3aXRoIG5vIGRldGFpbCBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIHN0b3JlCVRoZSBkZWFkIFN0b3JlIG9iamVjdAorICAgICAqLworICAgIHB1YmxpYyBTdG9yZUNsb3NlZEV4Y2VwdGlvbihTdG9yZSBzdG9yZSkgeworCXRoaXMoc3RvcmUsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBTdG9yZUNsb3NlZEV4Y2VwdGlvbiB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdG9yZQlUaGUgZGVhZCBTdG9yZSBvYmplY3QKKyAgICAgKiBAcGFyYW0gbWVzc2FnZQlUaGUgZGV0YWlsZWQgZXJyb3IgbWVzc2FnZQorICAgICAqLworICAgIHB1YmxpYyBTdG9yZUNsb3NlZEV4Y2VwdGlvbihTdG9yZSBzdG9yZSwgU3RyaW5nIG1lc3NhZ2UpIHsKKwlzdXBlcihtZXNzYWdlKTsKKwl0aGlzLnN0b3JlID0gc3RvcmU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIFN0b3JlQ2xvc2VkRXhjZXB0aW9uIHdpdGggdGhlIHNwZWNpZmllZAorICAgICAqIGRldGFpbCBtZXNzYWdlIGFuZCBlbWJlZGRlZCBleGNlcHRpb24uICBUaGUgZXhjZXB0aW9uIGlzIGNoYWluZWQKKyAgICAgKiB0byB0aGlzIGV4Y2VwdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdG9yZQlUaGUgZGVhZCBTdG9yZSBvYmplY3QKKyAgICAgKiBAcGFyYW0gbWVzc2FnZQlUaGUgZGV0YWlsZWQgZXJyb3IgbWVzc2FnZQorICAgICAqIEBwYXJhbSBlCQlUaGUgZW1iZWRkZWQgZXhjZXB0aW9uCisgICAgICogQHNpbmNlCQlKYXZhTWFpbCAxLjUKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RvcmVDbG9zZWRFeGNlcHRpb24oU3RvcmUgc3RvcmUsIFN0cmluZyBtZXNzYWdlLCBFeGNlcHRpb24gZSkgeworCXN1cGVyKG1lc3NhZ2UsIGUpOworCXRoaXMuc3RvcmUgPSBzdG9yZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBkZWFkIFN0b3JlIG9iamVjdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIGRlYWQgU3RvcmUgb2JqZWN0CisgICAgICovCisgICAgcHVibGljIFN0b3JlIGdldFN0b3JlKCkgeworCXJldHVybiBzdG9yZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9UcmFuc3BvcnQuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL1RyYW5zcG9ydC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU5YjMwMjkKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9UcmFuc3BvcnQuamF2YQpAQCAtMCwwICsxLDQwMCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7CitpbXBvcnQgamF2YXgubWFpbC5ldmVudC4qOworCisvKioKKyAqIEFuIGFic3RyYWN0IGNsYXNzIHRoYXQgbW9kZWxzIGEgbWVzc2FnZSB0cmFuc3BvcnQuCisgKiBTdWJjbGFzc2VzIHByb3ZpZGUgYWN0dWFsIGltcGxlbWVudGF0aW9ucy4gPHA+CisgKgorICogTm90ZSB0aGF0IDxjb2RlPlRyYW5zcG9ydDwvY29kZT4gZXh0ZW5kcyB0aGUgPGNvZGU+U2VydmljZTwvY29kZT4KKyAqIGNsYXNzLCB3aGljaCBwcm92aWRlcyBtYW55IGNvbW1vbiBtZXRob2RzIGZvciBuYW1pbmcgdHJhbnNwb3J0cywKKyAqIGNvbm5lY3RpbmcgdG8gdHJhbnNwb3J0cywgYW5kIGxpc3RlbmluZyB0byBjb25uZWN0aW9uIGV2ZW50cy4KKyAqCisgKiBAYXV0aG9yIEpvaG4gTWFuaQorICogQGF1dGhvciBNYXggU3BpdmFrCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICogCisgKiBAc2VlIGphdmF4Lm1haWwuU2VydmljZQorICogQHNlZSBqYXZheC5tYWlsLmV2ZW50LkNvbm5lY3Rpb25FdmVudAorICogQHNlZSBqYXZheC5tYWlsLmV2ZW50LlRyYW5zcG9ydEV2ZW50CisgKi8KKworcHVibGljIGFic3RyYWN0IGNsYXNzIFRyYW5zcG9ydCBleHRlbmRzIFNlcnZpY2UgeworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jc2Vzc2lvbiBTZXNzaW9uIG9iamVjdCBmb3IgdGhpcyBUcmFuc3BvcnQuCisgICAgICogQHBhcmFtCXVybG5hbWUJVVJMTmFtZSBvYmplY3QgdG8gYmUgdXNlZCBmb3IgdGhpcyBUcmFuc3BvcnQKKyAgICAgKi8KKyAgICBwdWJsaWMgVHJhbnNwb3J0KFNlc3Npb24gc2Vzc2lvbiwgVVJMTmFtZSB1cmxuYW1lKSB7CisJc3VwZXIoc2Vzc2lvbiwgdXJsbmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VuZCBhIG1lc3NhZ2UuICBUaGUgbWVzc2FnZSB3aWxsIGJlIHNlbnQgdG8gYWxsIHJlY2lwaWVudAorICAgICAqIGFkZHJlc3NlcyBzcGVjaWZpZWQgaW4gdGhlIG1lc3NhZ2UgKGFzIHJldHVybmVkIGZyb20gdGhlCisgICAgICogPGNvZGU+TWVzc2FnZTwvY29kZT4gbWV0aG9kIDxjb2RlPmdldEFsbFJlY2lwaWVudHM8L2NvZGU+KSwKKyAgICAgKiB1c2luZyBtZXNzYWdlIHRyYW5zcG9ydHMgYXBwcm9wcmlhdGUgdG8gZWFjaCBhZGRyZXNzLiAgVGhlCisgICAgICogPGNvZGU+c2VuZDwvY29kZT4gbWV0aG9kIGNhbGxzIHRoZSA8Y29kZT5zYXZlQ2hhbmdlczwvY29kZT4KKyAgICAgKiBtZXRob2Qgb24gdGhlIG1lc3NhZ2UgYmVmb3JlIHNlbmRpbmcgaXQuIDxwPgorICAgICAqCisgICAgICogSWYgYW55IG9mIHRoZSByZWNpcGllbnQgYWRkcmVzc2VzIGlzIGRldGVjdGVkIHRvIGJlIGludmFsaWQgYnkKKyAgICAgKiB0aGUgVHJhbnNwb3J0IGR1cmluZyBtZXNzYWdlIHN1Ym1pc3Npb24sIGEgU2VuZEZhaWxlZEV4Y2VwdGlvbgorICAgICAqIGlzIHRocm93bi4gIENsaWVudHMgY2FuIGdldCBtb3JlIGRldGFpbCBhYm91dCB0aGUgZmFpbHVyZSBieSBleGFtaW5pbmcKKyAgICAgKiB0aGUgZXhjZXB0aW9uLiAgV2hldGhlciBvciBub3QgdGhlIG1lc3NhZ2UgaXMgc3RpbGwgc2VudCBzdWNjZXNzZnVsbHkKKyAgICAgKiB0byBhbnkgdmFsaWQgYWRkcmVzc2VzIGRlcGVuZHMgb24gdGhlIFRyYW5zcG9ydCBpbXBsZW1lbnRhdGlvbi4gIFNlZSAKKyAgICAgKiBTZW5kRmFpbGVkRXhjZXB0aW9uIGZvciBtb3JlIGRldGFpbHMuICBOb3RlIGFsc28gdGhhdCBzdWNjZXNzIGRvZXMgCisgICAgICogbm90IGltcGx5IHRoYXQgdGhlIG1lc3NhZ2Ugd2FzIGRlbGl2ZXJlZCB0byB0aGUgdWx0aW1hdGUgcmVjaXBpZW50LAorICAgICAqIGFzIGZhaWx1cmVzIG1heSBvY2N1ciBpbiBsYXRlciBzdGFnZXMgb2YgZGVsaXZlcnkuICBPbmNlIGEgVHJhbnNwb3J0IAorICAgICAqIGFjY2VwdHMgYSBtZXNzYWdlIGZvciBkZWxpdmVyeSB0byBhIHJlY2lwaWVudCwgZmFpbHVyZXMgdGhhdCBvY2N1ciBsYXRlcgorICAgICAqIHNob3VsZCBiZSByZXBvcnRlZCB0byB0aGUgdXNlciB2aWEgYW5vdGhlciBtZWNoYW5pc20sIHN1Y2ggYXMKKyAgICAgKiByZXR1cm5pbmcgdGhlIHVuZGVsaXZlcmFibGUgbWVzc2FnZS4gPHA+CisgICAgICoKKyAgICAgKiBJbiB0eXBpY2FsIHVzYWdlLCBhIFNlbmRGYWlsZWRFeGNlcHRpb24gcmVmbGVjdHMgYW4gZXJyb3IgZGV0ZWN0ZWQKKyAgICAgKiBieSB0aGUgc2VydmVyLiAgVGhlIGRldGFpbHMgb2YgdGhlIFNlbmRGYWlsZWRFeGNlcHRpb24gd2lsbCB1c3VhbGx5CisgICAgICogY29udGFpbiB0aGUgZXJyb3IgbWVzc2FnZSBmcm9tIHRoZSBzZXJ2ZXIgKHN1Y2ggYXMgYW4gU01UUCBlcnJvcgorICAgICAqIG1lc3NhZ2UpLiAgQW4gYWRkcmVzcyBtYXkgYmUgZGV0ZWN0ZWQgYXMgaW52YWxpZCBmb3IgYSB2YXJpZXR5IG9mCisgICAgICogcmVhc29ucyAtIHRoZSBhZGRyZXNzIG1heSBub3QgZXhpc3QsIHRoZSBhZGRyZXNzIG1heSBoYXZlIGludmFsaWQKKyAgICAgKiBzeW50YXgsIHRoZSBhZGRyZXNzIG1heSBoYXZlIGV4Y2VlZGVkIGl0cyBxdW90YSwgZXRjLiA8cD4KKyAgICAgKgorICAgICAqIE5vdGUgdGhhdCA8Y29kZT5zZW5kPC9jb2RlPiBpcyBhIHN0YXRpYyBtZXRob2QgdGhhdCBjcmVhdGVzIGFuZAorICAgICAqIG1hbmFnZXMgaXRzIG93biBjb25uZWN0aW9uLiAgQW55IGNvbm5lY3Rpb24gYXNzb2NpYXRlZCB3aXRoIGFueQorICAgICAqIFRyYW5zcG9ydCBpbnN0YW5jZSB1c2VkIHRvIGludm9rZSB0aGlzIG1ldGhvZCBpcyBpZ25vcmVkIGFuZCBub3QKKyAgICAgKiB1c2VkLiAgVGhpcyBtZXRob2Qgc2hvdWxkIG9ubHkgYmUgaW52b2tlZCB1c2luZyB0aGUgZm9ybQorICAgICAqIDxjb2RlPlRyYW5zcG9ydC5zZW5kKG1zZyk7PC9jb2RlPiwgYW5kIHNob3VsZCBuZXZlciBiZSBpbnZva2VkCisgICAgICogdXNpbmcgYW4gaW5zdGFuY2UgdmFyaWFibGUuCisgICAgICoKKyAgICAgKiBAcGFyYW0JbXNnCXRoZSBtZXNzYWdlIHRvIHNlbmQKKyAgICAgKiBAZXhjZXB0aW9uCVNlbmRGYWlsZWRFeGNlcHRpb24gaWYgdGhlIG1lc3NhZ2UgY291bGQgbm90CisgICAgICoJCQliZSBzZW50IHRvIHNvbWUgb3IgYW55IG9mIHRoZSByZWNpcGllbnRzLgorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBvdGhlciBmYWlsdXJlcworICAgICAqIEBzZWUJCU1lc3NhZ2Ujc2F2ZUNoYW5nZXMKKyAgICAgKiBAc2VlCQlNZXNzYWdlI2dldEFsbFJlY2lwaWVudHMKKyAgICAgKiBAc2VlCQkjc2VuZChNZXNzYWdlLCBBZGRyZXNzW10pCisgICAgICogQHNlZQkJamF2YXgubWFpbC5TZW5kRmFpbGVkRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHNlbmQoTWVzc2FnZSBtc2cpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCW1zZy5zYXZlQ2hhbmdlcygpOyAvLyBkbyB0aGlzIGZpcnN0CisJc2VuZDAobXNnLCBtc2cuZ2V0QWxsUmVjaXBpZW50cygpLCBudWxsLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZW5kIHRoZSBtZXNzYWdlIHRvIHRoZSBzcGVjaWZpZWQgYWRkcmVzc2VzLCBpZ25vcmluZyBhbnkKKyAgICAgKiByZWNpcGllbnRzIHNwZWNpZmllZCBpbiB0aGUgbWVzc2FnZSBpdHNlbGYuIFRoZQorICAgICAqIDxjb2RlPnNlbmQ8L2NvZGU+IG1ldGhvZCBjYWxscyB0aGUgPGNvZGU+c2F2ZUNoYW5nZXM8L2NvZGU+CisgICAgICogbWV0aG9kIG9uIHRoZSBtZXNzYWdlIGJlZm9yZSBzZW5kaW5nIGl0LiA8cD4KKyAgICAgKgorICAgICAqIEBwYXJhbQltc2cJdGhlIG1lc3NhZ2UgdG8gc2VuZAorICAgICAqIEBwYXJhbQlhZGRyZXNzZXMgdGhlIGFkZHJlc3NlcyB0byB3aGljaCB0byBzZW5kIHRoZSBtZXNzYWdlCisgICAgICogQGV4Y2VwdGlvbglTZW5kRmFpbGVkRXhjZXB0aW9uIGlmIHRoZSBtZXNzYWdlIGNvdWxkIG5vdAorICAgICAqCQkJYmUgc2VudCB0byBzb21lIG9yIGFueSBvZiB0aGUgcmVjaXBpZW50cy4KKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKiBAc2VlCQlNZXNzYWdlI3NhdmVDaGFuZ2VzCisgICAgICogQHNlZSAgICAgICAgICAgICAjc2VuZChNZXNzYWdlKQorICAgICAqIEBzZWUJCWphdmF4Lm1haWwuU2VuZEZhaWxlZEV4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZW5kKE1lc3NhZ2UgbXNnLCBBZGRyZXNzW10gYWRkcmVzc2VzKSAKKwkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisKKwltc2cuc2F2ZUNoYW5nZXMoKTsKKwlzZW5kMChtc2csIGFkZHJlc3NlcywgbnVsbCwgbnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VuZCBhIG1lc3NhZ2UuICBUaGUgbWVzc2FnZSB3aWxsIGJlIHNlbnQgdG8gYWxsIHJlY2lwaWVudAorICAgICAqIGFkZHJlc3NlcyBzcGVjaWZpZWQgaW4gdGhlIG1lc3NhZ2UgKGFzIHJldHVybmVkIGZyb20gdGhlCisgICAgICogPGNvZGU+TWVzc2FnZTwvY29kZT4gbWV0aG9kIDxjb2RlPmdldEFsbFJlY2lwaWVudHM8L2NvZGU+KS4KKyAgICAgKiBUaGUgPGNvZGU+c2VuZDwvY29kZT4gbWV0aG9kIGNhbGxzIHRoZSA8Y29kZT5zYXZlQ2hhbmdlczwvY29kZT4KKyAgICAgKiBtZXRob2Qgb24gdGhlIG1lc3NhZ2UgYmVmb3JlIHNlbmRpbmcgaXQuIDxwPgorICAgICAqCisgICAgICogVXNlIHRoZSBzcGVjaWZpZWQgdXNlciBuYW1lIGFuZCBwYXNzd29yZCB0byBhdXRoZW50aWNhdGUgdG8KKyAgICAgKiB0aGUgbWFpbCBzZXJ2ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0JbXNnCXRoZSBtZXNzYWdlIHRvIHNlbmQKKyAgICAgKiBAcGFyYW0JdXNlcgl0aGUgdXNlciBuYW1lCisgICAgICogQHBhcmFtCXBhc3N3b3JkIHRoaXMgdXNlcidzIHBhc3N3b3JkCisgICAgICogQGV4Y2VwdGlvbglTZW5kRmFpbGVkRXhjZXB0aW9uIGlmIHRoZSBtZXNzYWdlIGNvdWxkIG5vdAorICAgICAqCQkJYmUgc2VudCB0byBzb21lIG9yIGFueSBvZiB0aGUgcmVjaXBpZW50cy4KKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKiBAc2VlCQlNZXNzYWdlI3NhdmVDaGFuZ2VzCisgICAgICogQHNlZSAgICAgICAgICAgICAjc2VuZChNZXNzYWdlKQorICAgICAqIEBzZWUJCWphdmF4Lm1haWwuU2VuZEZhaWxlZEV4Y2VwdGlvbgorICAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS41CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHNlbmQoTWVzc2FnZSBtc2csCisJCVN0cmluZyB1c2VyLCBTdHJpbmcgcGFzc3dvcmQpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCisJbXNnLnNhdmVDaGFuZ2VzKCk7CisJc2VuZDAobXNnLCBtc2cuZ2V0QWxsUmVjaXBpZW50cygpLCB1c2VyLCBwYXNzd29yZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VuZCB0aGUgbWVzc2FnZSB0byB0aGUgc3BlY2lmaWVkIGFkZHJlc3NlcywgaWdub3JpbmcgYW55CisgICAgICogcmVjaXBpZW50cyBzcGVjaWZpZWQgaW4gdGhlIG1lc3NhZ2UgaXRzZWxmLiBUaGUKKyAgICAgKiA8Y29kZT5zZW5kPC9jb2RlPiBtZXRob2QgY2FsbHMgdGhlIDxjb2RlPnNhdmVDaGFuZ2VzPC9jb2RlPgorICAgICAqIG1ldGhvZCBvbiB0aGUgbWVzc2FnZSBiZWZvcmUgc2VuZGluZyBpdC4gPHA+CisgICAgICoKKyAgICAgKiBVc2UgdGhlIHNwZWNpZmllZCB1c2VyIG5hbWUgYW5kIHBhc3N3b3JkIHRvIGF1dGhlbnRpY2F0ZSB0bworICAgICAqIHRoZSBtYWlsIHNlcnZlci4KKyAgICAgKgorICAgICAqIEBwYXJhbQltc2cJdGhlIG1lc3NhZ2UgdG8gc2VuZAorICAgICAqIEBwYXJhbQlhZGRyZXNzZXMgdGhlIGFkZHJlc3NlcyB0byB3aGljaCB0byBzZW5kIHRoZSBtZXNzYWdlCisgICAgICogQHBhcmFtCXVzZXIJdGhlIHVzZXIgbmFtZQorICAgICAqIEBwYXJhbQlwYXNzd29yZCB0aGlzIHVzZXIncyBwYXNzd29yZAorICAgICAqIEBleGNlcHRpb24JU2VuZEZhaWxlZEV4Y2VwdGlvbiBpZiB0aGUgbWVzc2FnZSBjb3VsZCBub3QKKyAgICAgKgkJCWJlIHNlbnQgdG8gc29tZSBvciBhbnkgb2YgdGhlIHJlY2lwaWVudHMuCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICogQHNlZQkJTWVzc2FnZSNzYXZlQ2hhbmdlcworICAgICAqIEBzZWUgICAgICAgICAgICAgI3NlbmQoTWVzc2FnZSkKKyAgICAgKiBAc2VlCQlqYXZheC5tYWlsLlNlbmRGYWlsZWRFeGNlcHRpb24KKyAgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuNQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZW5kKE1lc3NhZ2UgbXNnLCBBZGRyZXNzW10gYWRkcmVzc2VzLAorCQlTdHJpbmcgdXNlciwgU3RyaW5nIHBhc3N3b3JkKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKworCW1zZy5zYXZlQ2hhbmdlcygpOworCXNlbmQwKG1zZywgYWRkcmVzc2VzLCB1c2VyLCBwYXNzd29yZCk7CisgICAgfQorCisgICAgLy8gc2VuZCwgYnV0IHdpdGhvdXQgdGhlIHNhdmVDaGFuZ2VzCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBzZW5kMChNZXNzYWdlIG1zZywgQWRkcmVzc1tdIGFkZHJlc3NlcywKKwkJU3RyaW5nIHVzZXIsIFN0cmluZyBwYXNzd29yZCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisKKwlpZiAoYWRkcmVzc2VzID09IG51bGwgfHwgYWRkcmVzc2VzLmxlbmd0aCA9PSAwKQorCSAgICB0aHJvdyBuZXcgU2VuZEZhaWxlZEV4Y2VwdGlvbigiTm8gcmVjaXBpZW50IGFkZHJlc3NlcyIpOworCisJLyoKKwkgKiBwcm90b2NvbHMgaXMgYSBtYXAgY29udGFpbmluZyB0aGUgYWRkcmVzc2VzCisJICogaW5kZXhlZCBieSBhZGRyZXNzIHR5cGUKKwkgKi8KKwlNYXA8U3RyaW5nLCBMaXN0PEFkZHJlc3M+PiBwcm90b2NvbHMKKwkJPSBuZXcgSGFzaE1hcDw+KCk7CisKKwkvLyBMaXN0cyBvZiBhZGRyZXNzZXMKKwlMaXN0PEFkZHJlc3M+IGludmFsaWQgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKwlMaXN0PEFkZHJlc3M+IHZhbGlkU2VudCA9IG5ldyBBcnJheUxpc3Q8PigpOworCUxpc3Q8QWRkcmVzcz4gdmFsaWRVbnNlbnQgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKworCWZvciAoaW50IGkgPSAwOyBpIDwgYWRkcmVzc2VzLmxlbmd0aDsgaSsrKSB7CisJICAgIC8vIGlzIHRoaXMgYWRkcmVzcyB0eXBlIGFscmVhZHkgaW4gdGhlIG1hcD8KKwkgICAgaWYgKHByb3RvY29scy5jb250YWluc0tleShhZGRyZXNzZXNbaV0uZ2V0VHlwZSgpKSkgeworCQlMaXN0PEFkZHJlc3M+IHYgPSBwcm90b2NvbHMuZ2V0KGFkZHJlc3Nlc1tpXS5nZXRUeXBlKCkpOworCQl2LmFkZChhZGRyZXNzZXNbaV0pOworCSAgICB9IGVsc2UgeworCQkvLyBuZWVkIHRvIGFkZCBhIG5ldyBwcm90b2NvbAorCQlMaXN0PEFkZHJlc3M+IHcgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKwkJdy5hZGQoYWRkcmVzc2VzW2ldKTsKKwkJcHJvdG9jb2xzLnB1dChhZGRyZXNzZXNbaV0uZ2V0VHlwZSgpLCB3KTsKKwkgICAgfQorCX0KKworCWludCBkc2l6ZSA9IHByb3RvY29scy5zaXplKCk7CisJaWYgKGRzaXplID09IDApCisJICAgIHRocm93IG5ldyBTZW5kRmFpbGVkRXhjZXB0aW9uKCJObyByZWNpcGllbnQgYWRkcmVzc2VzIik7CisKKwlTZXNzaW9uIHMgPSAobXNnLnNlc3Npb24gIT0gbnVsbCkgPyBtc2cuc2Vzc2lvbiA6CisJCSAgICAgU2Vzc2lvbi5nZXREZWZhdWx0SW5zdGFuY2UoU3lzdGVtLmdldFByb3BlcnRpZXMoKSwgbnVsbCk7CisJVHJhbnNwb3J0IHRyYW5zcG9ydDsKKworCS8qCisJICogT3B0aW1pemUgdGhlIGNhc2Ugb2YgYSBzaW5nbGUgcHJvdG9jb2wuCisJICovCisJaWYgKGRzaXplID09IDEpIHsKKwkgICAgdHJhbnNwb3J0ID0gcy5nZXRUcmFuc3BvcnQoYWRkcmVzc2VzWzBdKTsKKwkgICAgdHJ5IHsKKwkJaWYgKHVzZXIgIT0gbnVsbCkKKwkJICAgIHRyYW5zcG9ydC5jb25uZWN0KHVzZXIsIHBhc3N3b3JkKTsKKwkJZWxzZQorCQkgICAgdHJhbnNwb3J0LmNvbm5lY3QoKTsKKwkJdHJhbnNwb3J0LnNlbmRNZXNzYWdlKG1zZywgYWRkcmVzc2VzKTsKKwkgICAgfSBmaW5hbGx5IHsKKwkJdHJhbnNwb3J0LmNsb3NlKCk7CisJICAgIH0KKwkgICAgcmV0dXJuOworCX0KKworCS8qCisJICogTW9yZSB0aGFuIG9uZSBwcm90b2NvbC4gIEhhdmUgdG8gZG8gdGhlbSBvbmUgYXQgYSB0aW1lCisJICogYW5kIGNvbGxlY3QgYWRkcmVzc2VzIGFuZCBjaGFpbiBleGNlcHRpb25zLgorCSAqLworCU1lc3NhZ2luZ0V4Y2VwdGlvbiBjaGFpbmVkRXggPSBudWxsOworCWJvb2xlYW4gc2VuZEZhaWxlZCA9IGZhbHNlOworCisJZm9yKExpc3Q8QWRkcmVzcz4gdiA6IHByb3RvY29scy52YWx1ZXMoKSkgeworCSAgICBBZGRyZXNzW10gcHJvdGFkZHJlc3NlcyA9IG5ldyBBZGRyZXNzW3Yuc2l6ZSgpXTsKKwkgICAgdi50b0FycmF5KHByb3RhZGRyZXNzZXMpOworCisJICAgIC8vIEdldCBhIFRyYW5zcG9ydCB0aGF0IGNhbiBoYW5kbGUgdGhpcyBhZGRyZXNzIHR5cGUuCisJICAgIGlmICgodHJhbnNwb3J0ID0gcy5nZXRUcmFuc3BvcnQocHJvdGFkZHJlc3Nlc1swXSkpID09IG51bGwpIHsKKwkJLy8gQ291bGQgbm90IGZpbmQgYW4gYXBwcm9wcmlhdGUgVHJhbnNwb3J0IC4uCisJCS8vIE1hcmsgdGhlc2UgYWRkcmVzc2VzIGludmFsaWQuCisJCWZvciAoaW50IGogPSAwOyBqIDwgcHJvdGFkZHJlc3Nlcy5sZW5ndGg7IGorKykKKwkJICAgIGludmFsaWQuYWRkKHByb3RhZGRyZXNzZXNbal0pOworCQljb250aW51ZTsKKwkgICAgfQorCSAgICB0cnkgeworCQl0cmFuc3BvcnQuY29ubmVjdCgpOworCQl0cmFuc3BvcnQuc2VuZE1lc3NhZ2UobXNnLCBwcm90YWRkcmVzc2VzKTsKKwkgICAgfSBjYXRjaCAoU2VuZEZhaWxlZEV4Y2VwdGlvbiBzZXgpIHsKKwkJc2VuZEZhaWxlZCA9IHRydWU7CisJCS8vIGNoYWluIHRoZSBleGNlcHRpb24gd2UncmUgY2F0Y2hpbmcgdG8gYW55IHByZXZpb3VzIG9uZXMKKwkJaWYgKGNoYWluZWRFeCA9PSBudWxsKQorCQkgICAgY2hhaW5lZEV4ID0gc2V4OworCQllbHNlCisJCSAgICBjaGFpbmVkRXguc2V0TmV4dEV4Y2VwdGlvbihzZXgpOworCisJCS8vIHJldHJpZXZlIGludmFsaWQgYWRkcmVzc2VzCisJCUFkZHJlc3NbXSBhID0gc2V4LmdldEludmFsaWRBZGRyZXNzZXMoKTsKKwkJaWYgKGEgIT0gbnVsbCkKKwkJICAgIGZvciAoaW50IGogPSAwOyBqIDwgYS5sZW5ndGg7IGorKykgCisJCQlpbnZhbGlkLmFkZChhW2pdKTsKKworCQkvLyByZXRyaWV2ZSB2YWxpZFNlbnQgYWRkcmVzc2VzCisJCWEgPSBzZXguZ2V0VmFsaWRTZW50QWRkcmVzc2VzKCk7CisJCWlmIChhICE9IG51bGwpCisJCSAgICBmb3IgKGludCBrID0gMDsgayA8IGEubGVuZ3RoOyBrKyspIAorCQkJdmFsaWRTZW50LmFkZChhW2tdKTsKKworCQkvLyByZXRyaWV2ZSB2YWxpZFVuc2VudCBhZGRyZXNzZXMKKwkJQWRkcmVzc1tdIGMgPSBzZXguZ2V0VmFsaWRVbnNlbnRBZGRyZXNzZXMoKTsKKwkJaWYgKGMgIT0gbnVsbCkKKwkJICAgIGZvciAoaW50IGwgPSAwOyBsIDwgYy5sZW5ndGg7IGwrKykgCisJCQl2YWxpZFVuc2VudC5hZGQoY1tsXSk7CisJICAgIH0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBtZXgpIHsKKwkJc2VuZEZhaWxlZCA9IHRydWU7CisJCS8vIGNoYWluIHRoZSBleGNlcHRpb24gd2UncmUgY2F0Y2hpbmcgdG8gYW55IHByZXZpb3VzIG9uZXMKKwkJaWYgKGNoYWluZWRFeCA9PSBudWxsKQorCQkgICAgY2hhaW5lZEV4ID0gbWV4OworCQllbHNlCisJCSAgICBjaGFpbmVkRXguc2V0TmV4dEV4Y2VwdGlvbihtZXgpOworCSAgICB9IGZpbmFsbHkgeworCQl0cmFuc3BvcnQuY2xvc2UoKTsKKwkgICAgfQorCX0KKworCS8vIGRvbmUgd2l0aCBhbGwgcHJvdG9jb2xzLiB0aHJvdyBleGNlcHRpb24gaWYgc29tZXRoaW5nIGZhaWxlZAorCWlmIChzZW5kRmFpbGVkIHx8IGludmFsaWQuc2l6ZSgpICE9IDAgfHwgdmFsaWRVbnNlbnQuc2l6ZSgpICE9IDApIHsgCisJICAgIEFkZHJlc3NbXSBhID0gbnVsbCwgYiA9IG51bGwsIGMgPSBudWxsOworCisJICAgIC8vIGNvcHkgYWRkcmVzcyBsaXN0cyBpbnRvIGFycmF5cworCSAgICBpZiAodmFsaWRTZW50LnNpemUoKSA+IDApIHsKKwkJYSA9IG5ldyBBZGRyZXNzW3ZhbGlkU2VudC5zaXplKCldOworCQl2YWxpZFNlbnQudG9BcnJheShhKTsKKwkgICAgfQorCSAgICBpZiAodmFsaWRVbnNlbnQuc2l6ZSgpID4gMCkgeworCQliID0gbmV3IEFkZHJlc3NbdmFsaWRVbnNlbnQuc2l6ZSgpXTsKKwkJdmFsaWRVbnNlbnQudG9BcnJheShiKTsKKwkgICAgfQorCSAgICBpZiAoaW52YWxpZC5zaXplKCkgPiAwKSB7CisJCWMgPSBuZXcgQWRkcmVzc1tpbnZhbGlkLnNpemUoKV07CisJCWludmFsaWQudG9BcnJheShjKTsKKwkgICAgfQorCSAgICB0aHJvdyBuZXcgU2VuZEZhaWxlZEV4Y2VwdGlvbigiU2VuZGluZyBmYWlsZWQiLCBjaGFpbmVkRXgsIAorCQkJCQkgIGEsIGIsIGMpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZW5kIHRoZSBNZXNzYWdlIHRvIHRoZSBzcGVjaWZpZWQgbGlzdCBvZiBhZGRyZXNzZXMuIEFuIGFwcHJvcHJpYXRlCisgICAgICogVHJhbnNwb3J0RXZlbnQgaW5kaWNhdGluZyB0aGUgZGVsaXZlcnkgc3RhdHVzIGlzIGRlbGl2ZXJlZCB0byBhbnkgCisgICAgICogVHJhbnNwb3J0TGlzdGVuZXIgcmVnaXN0ZXJlZCBvbiB0aGlzIFRyYW5zcG9ydC4gQWxzbywgaWYgYW55IG9mCisgICAgICogdGhlIGFkZHJlc3NlcyBpcyBpbnZhbGlkLCBhIFNlbmRGYWlsZWRFeGNlcHRpb24gaXMgdGhyb3duLgorICAgICAqIFdoZXRoZXIgb3Igbm90IHRoZSBtZXNzYWdlIGlzIHN0aWxsIHNlbnQgc3VjY2VzZnVsbHkgdG8KKyAgICAgKiBhbnkgdmFsaWQgYWRkcmVzc2VzIGRlcGVuZHMgb24gdGhlIFRyYW5zcG9ydCBpbXBsZW1lbnRhdGlvbi4gPHA+CisgICAgICoKKyAgICAgKiBVbmxpa2UgdGhlIHN0YXRpYyA8Y29kZT5zZW5kPC9jb2RlPiBtZXRob2QsIHRoZSA8Y29kZT5zZW5kTWVzc2FnZTwvY29kZT4KKyAgICAgKiBtZXRob2QgZG9lcyA8ZW0+bm90PC9lbT4gY2FsbCB0aGUgPGNvZGU+c2F2ZUNoYW5nZXM8L2NvZGU+IG1ldGhvZCBvbgorICAgICAqIHRoZSBtZXNzYWdlOyB0aGUgY2FsbGVyIHNob3VsZCBkbyBzby4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtc2cJVGhlIE1lc3NhZ2UgdG8gYmUgc2VudAorICAgICAqIEBwYXJhbSBhZGRyZXNzZXMJYXJyYXkgb2YgYWRkcmVzc2VzIHRvIHNlbmQgdGhpcyBtZXNzYWdlIHRvCisgICAgICogQHNlZSAJCWphdmF4Lm1haWwuZXZlbnQuVHJhbnNwb3J0RXZlbnQKKyAgICAgKiBAZXhjZXB0aW9uIFNlbmRGYWlsZWRFeGNlcHRpb24gaWYgdGhlIHNlbmQgZmFpbGVkIGJlY2F1c2Ugb2YKKyAgICAgKgkJCWludmFsaWQgYWRkcmVzc2VzLgorICAgICAqIEBleGNlcHRpb24gTWVzc2FnaW5nRXhjZXB0aW9uIGlmIHRoZSBjb25uZWN0aW9uIGlzIGRlYWQgb3Igbm90IGluIHRoZSAKKyAgICAgKiAJCQkJY29ubmVjdGVkIHN0YXRlCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2VuZE1lc3NhZ2UoTWVzc2FnZSBtc2csIEFkZHJlc3NbXSBhZGRyZXNzZXMpIAorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb247CisKKyAgICAvLyBWZWN0b3Igb2YgVHJhbnNwb3J0IGxpc3RlbmVycworICAgIHByaXZhdGUgdm9sYXRpbGUgVmVjdG9yPFRyYW5zcG9ydExpc3RlbmVyPiB0cmFuc3BvcnRMaXN0ZW5lcnMgPSBudWxsOworCisgICAgLyoqCisgICAgICogQWRkIGEgbGlzdGVuZXIgZm9yIFRyYW5zcG9ydCBldmVudHMuIDxwPgorICAgICAqCisgICAgICogVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gcHJvdmlkZWQgaGVyZSBhZGRzIHRoaXMgbGlzdGVuZXIKKyAgICAgKiB0byBhbiBpbnRlcm5hbCBsaXN0IG9mIFRyYW5zcG9ydExpc3RlbmVycy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBsICAgICAgICAgdGhlIExpc3RlbmVyIGZvciBUcmFuc3BvcnQgZXZlbnRzCisgICAgICogQHNlZSAgICAgICAgICAgICBqYXZheC5tYWlsLmV2ZW50LlRyYW5zcG9ydEV2ZW50CisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGFkZFRyYW5zcG9ydExpc3RlbmVyKFRyYW5zcG9ydExpc3RlbmVyIGwpIHsKKwlpZiAodHJhbnNwb3J0TGlzdGVuZXJzID09IG51bGwpCisJICAgIHRyYW5zcG9ydExpc3RlbmVycyA9IG5ldyBWZWN0b3I8PigpOworCXRyYW5zcG9ydExpc3RlbmVycy5hZGRFbGVtZW50KGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZSBhIGxpc3RlbmVyIGZvciBUcmFuc3BvcnQgZXZlbnRzLiA8cD4KKyAgICAgKgorICAgICAqIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIHByb3ZpZGVkIGhlcmUgcmVtb3ZlcyB0aGlzIGxpc3RlbmVyCisgICAgICogZnJvbSB0aGUgaW50ZXJuYWwgbGlzdCBvZiBUcmFuc3BvcnRMaXN0ZW5lcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbCAgICAgICAgIHRoZSBsaXN0ZW5lcgorICAgICAqIEBzZWUgICAgICAgICAgICAgI2FkZFRyYW5zcG9ydExpc3RlbmVyCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHJlbW92ZVRyYW5zcG9ydExpc3RlbmVyKFRyYW5zcG9ydExpc3RlbmVyIGwpIHsKKwlpZiAodHJhbnNwb3J0TGlzdGVuZXJzICE9IG51bGwpCisJICAgIHRyYW5zcG9ydExpc3RlbmVycy5yZW1vdmVFbGVtZW50KGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIE5vdGlmeSBhbGwgVHJhbnNwb3J0TGlzdGVuZXJzLiBUcmFuc3BvcnQgaW1wbGVtZW50YXRpb25zIGFyZQorICAgICAqIGV4cGVjdGVkIHRvIHVzZSB0aGlzIG1ldGhvZCB0byBicm9hZGNhc3QgVHJhbnNwb3J0RXZlbnRzLjxwPgorICAgICAqCisgICAgICogVGhlIHByb3ZpZGVkIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gcXVldWVzIHRoZSBldmVudCBpbnRvCisgICAgICogYW4gaW50ZXJuYWwgZXZlbnQgcXVldWUuIEFuIGV2ZW50IGRpc3BhdGNoZXIgdGhyZWFkIGRlcXVldWVzCisgICAgICogZXZlbnRzIGZyb20gdGhlIHF1ZXVlIGFuZCBkaXNwYXRjaGVzIHRoZW0gdG8gdGhlIHJlZ2lzdGVyZWQKKyAgICAgKiBUcmFuc3BvcnRMaXN0ZW5lcnMuIE5vdGUgdGhhdCB0aGUgZXZlbnQgZGlzcGF0Y2hpbmcgb2NjdXJzCisgICAgICogaW4gYSBzZXBhcmF0ZSB0aHJlYWQsIHRodXMgYXZvaWRpbmcgcG90ZW50aWFsIGRlYWRsb2NrIHByb2JsZW1zLgorICAgICAqCisgICAgICogQHBhcmFtCXR5cGUJdGhlIFRyYW5zcG9ydEV2ZW50IHR5cGUKKyAgICAgKiBAcGFyYW0JdmFsaWRTZW50IHZhbGlkIGFkZHJlc3NlcyB0byB3aGljaCBtZXNzYWdlIHdhcyBzZW50CisgICAgICogQHBhcmFtCXZhbGlkVW5zZW50IHZhbGlkIGFkZHJlc3NlcyB0byB3aGljaCBtZXNzYWdlIHdhcyBub3Qgc2VudAorICAgICAqIEBwYXJhbQlpbnZhbGlkIHRoZSBpbnZhbGlkIGFkZHJlc3NlcworICAgICAqIEBwYXJhbQltc2cJdGhlIG1lc3NhZ2UKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBub3RpZnlUcmFuc3BvcnRMaXN0ZW5lcnMoaW50IHR5cGUsIEFkZHJlc3NbXSB2YWxpZFNlbnQsCisJCQkJCSAgICBBZGRyZXNzW10gdmFsaWRVbnNlbnQsCisJCQkJCSAgICBBZGRyZXNzW10gaW52YWxpZCwgTWVzc2FnZSBtc2cpIHsKKwlpZiAodHJhbnNwb3J0TGlzdGVuZXJzID09IG51bGwpCisJICAgIHJldHVybjsKKwkKKwlUcmFuc3BvcnRFdmVudCBlID0gbmV3IFRyYW5zcG9ydEV2ZW50KHRoaXMsIHR5cGUsIHZhbGlkU2VudCwgCisJCQkJCSAgICAgIHZhbGlkVW5zZW50LCBpbnZhbGlkLCBtc2cpOworCXF1ZXVlRXZlbnQoZSwgdHJhbnNwb3J0TGlzdGVuZXJzKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9VSURGb2xkZXIuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL1VJREZvbGRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJhOGI5N2MKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9VSURGb2xkZXIuamF2YQpAQCAtMCwwICsxLDIwNiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsOworCitpbXBvcnQgamF2YS51dGlsLk5vU3VjaEVsZW1lbnRFeGNlcHRpb247CisKKy8qKgorICogVGhlIDxjb2RlPlVJREZvbGRlcjwvY29kZT4gaW50ZXJmYWNlIGlzIGltcGxlbWVudGVkIGJ5IEZvbGRlcnMgCisgKiB0aGF0IGNhbiBzdXBwb3J0IHRoZSAiZGlzY29ubmVjdGVkIiBtb2RlIG9mIG9wZXJhdGlvbiwgYnkgcHJvdmlkaW5nIAorICogdW5pcXVlLWlkcyBmb3IgbWVzc2FnZXMgaW4gdGhlIGZvbGRlci4gVGhpcyBpbnRlcmZhY2UgaXMgYmFzZWQgb24KKyAqIHRoZSBJTUFQIG1vZGVsIGZvciBzdXBwb3J0aW5nIGRpc2Nvbm5lY3RlZCBvcGVyYXRpb24uIDxwPgorICoKKyAqIEEgVW5pcXVlIGlkZW50aWZpZXIgKFVJRCkgaXMgYSBwb3NpdGl2ZSBsb25nIHZhbHVlLCBhc3NpZ25lZCB0bworICogZWFjaCBtZXNzYWdlIGluIGEgc3BlY2lmaWMgZm9sZGVyLiBVbmlxdWUgaWRlbnRpZmllcnMgYXJlIGFzc2lnbmVkCisgKiBpbiBhIHN0cmljdGx5IDxzdHJvbmc+YXNjZW5kaW5nPC9zdHJvbmc+IGZhc2hpb24gaW4gdGhlIG1haWxib3guIAorICogVGhhdCBpcywgYXMgZWFjaCBtZXNzYWdlIGlzIGFkZGVkIHRvIHRoZSBtYWlsYm94IGl0IGlzIGFzc2lnbmVkIGEgCisgKiBoaWdoZXIgVUlEIHRoYW4gdGhlIG1lc3NhZ2Uocykgd2hpY2ggd2VyZSBhZGRlZCBwcmV2aW91c2x5LiBVbmlxdWUKKyAqIGlkZW50aWZpZXJzIHBlcnNpc3QgYWNyb3NzIHNlc3Npb25zLiBUaGlzIHBlcm1pdHMgYSBjbGllbnQgdG8gCisgKiByZXN5bmNocm9uaXplIGl0cyBzdGF0ZSBmcm9tIGEgcHJldmlvdXMgc2Vzc2lvbiB3aXRoIHRoZSBzZXJ2ZXIuIDxwPgorICoKKyAqIEFzc29jaWF0ZWQgd2l0aCBldmVyeSBtYWlsYm94IGlzIGEgdW5pcXVlIGlkZW50aWZpZXIgdmFsaWRpdHkgdmFsdWUuCisgKiBJZiB1bmlxdWUgaWRlbnRpZmllcnMgZnJvbSBhbiBlYXJsaWVyIHNlc3Npb24gZmFpbCB0byBwZXJzaXN0IHRvIAorICogdGhpcyBzZXNzaW9uLCB0aGUgdW5pcXVlIGlkZW50aWZpZXIgdmFsaWRpdHkgdmFsdWUgCisgKiA8c3Ryb25nPm11c3Q8L3N0cm9uZz4gYmUgZ3JlYXRlciB0aGFuIHRoZSBvbmUgdXNlZCBpbiB0aGUgZWFybGllcgorICogc2Vzc2lvbi4gPHA+CisgKgorICogUmVmZXIgdG8gPEEgSFJFRj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjA2MC50eHQiPlJGQyAyMDYwPC9BPgorICogZm9yIG1vcmUgaW5mb3JtYXRpb24uCisgKgorICogQWxsIHRoZSBGb2xkZXIgb2JqZWN0cyByZXR1cm5lZCBieSB0aGUgZGVmYXVsdCBJTUFQIHByb3ZpZGVyIGltcGxlbWVudAorICogdGhlIFVJREZvbGRlciBpbnRlcmZhY2UuICBVc2UgaXQgYXMgZm9sbG93czoKKyAqIDxibG9ja3F1b3RlPjxwcmU+CisgKgorICogCUZvbGRlciBmID0gc3RvcmUuZ2V0Rm9sZGVyKCJ3aGF0ZXZlciIpOworICoJVUlERm9sZGVyIHVmID0gKFVJREZvbGRlcilmOworICoJbG9uZyB1aWQgPSB1Zi5nZXRVSUQobXNnKTsKKyAqCisgKiA8L3ByZT48L2Jsb2NrcXVvdGU+PHA+CisgKgorICogQGF1dGhvciBCaWxsIFNoYW5ub24KKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKi8KKworcHVibGljIGludGVyZmFjZSBVSURGb2xkZXIgeworCisgICAgLyoqCisgICAgICogQSBmZXRjaCBwcm9maWxlIGl0ZW0gZm9yIGZldGNoaW5nIFVJRHMuCisgICAgICogVGhpcyBpbm5lciBjbGFzcyBleHRlbmRzIHRoZSA8Y29kZT5GZXRjaFByb2ZpbGUuSXRlbTwvY29kZT4KKyAgICAgKiBjbGFzcyB0byBhZGQgbmV3IEZldGNoUHJvZmlsZSBpdGVtIHR5cGVzLCBzcGVjaWZpYyB0byBVSURGb2xkZXJzLgorICAgICAqIFRoZSBvbmx5IGl0ZW0gY3VycmVudGx5IGRlZmluZWQgaGVyZSBpcyB0aGUgPGNvZGU+VUlEPC9jb2RlPiBpdGVtLgorICAgICAqCisgICAgICogQHNlZSBGZXRjaFByb2ZpbGUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEZldGNoUHJvZmlsZUl0ZW0gZXh0ZW5kcyBGZXRjaFByb2ZpbGUuSXRlbSB7CisJcHJvdGVjdGVkIEZldGNoUHJvZmlsZUl0ZW0oU3RyaW5nIG5hbWUpIHsKKwkgICAgc3VwZXIobmFtZSk7CisJfQorCisJLyoqCisJICogVUlEIGlzIGEgZmV0Y2ggcHJvZmlsZSBpdGVtIHRoYXQgY2FuIGJlIGluY2x1ZGVkIGluIGEKKwkgKiA8Y29kZT5GZXRjaFByb2ZpbGU8L2NvZGU+IGR1cmluZyBhIGZldGNoIHJlcXVlc3QgdG8gYSBGb2xkZXIuCisJICogVGhpcyBpdGVtIGluZGljYXRlcyB0aGF0IHRoZSBVSURzIGZvciBtZXNzYWdlcyBpbiB0aGUgc3BlY2lmaWVkIAorCSAqIHJhbmdlIGFyZSBkZXNpcmVkIHRvIGJlIHByZWZldGNoZWQuIDxwPgorCSAqIAorCSAqIEFuIGV4YW1wbGUgb2YgaG93IGEgY2xpZW50IHVzZXMgdGhpcyBpcyBiZWxvdzoKKwkgKiA8YmxvY2txdW90ZT48cHJlPgorCSAqCisJICogCUZldGNoUHJvZmlsZSBmcCA9IG5ldyBGZXRjaFByb2ZpbGUoKTsKKwkgKglmcC5hZGQoVUlERm9sZGVyLkZldGNoUHJvZmlsZUl0ZW0uVUlEKTsKKwkgKglmb2xkZXIuZmV0Y2gobXNncywgZnApOworCSAqCisJICogPC9wcmU+PC9ibG9ja3F1b3RlPgorCSAqLyAKKwlwdWJsaWMgc3RhdGljIGZpbmFsIEZldGNoUHJvZmlsZUl0ZW0gVUlEID0gCisJCW5ldyBGZXRjaFByb2ZpbGVJdGVtKCJVSUQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIGlzIGEgc3BlY2lhbCB2YWx1ZSB0aGF0IGNhbiBiZSB1c2VkIGFzIHRoZSA8Y29kZT5lbmQ8L2NvZGU+CisgICAgICogcGFyYW1ldGVyIGluIDxjb2RlPmdldE1lc3NhZ2VzQnlVSUQoc3RhcnQsIGVuZCk8L2NvZGU+LCB0byBkZW5vdGUgdGhlCisgICAgICogVUlEIG9mIHRoZSBsYXN0IG1lc3NhZ2UgaW4gdGhlIGZvbGRlci4KKyAgICAgKgorICAgICAqIEBzZWUgI2dldE1lc3NhZ2VzQnlVSUQKKyAgICAgKi8gCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBsb25nIExBU1RVSUQgPSAtMTsKKworICAgIC8qKgorICAgICAqIFRoZSBsYXJnZXN0IHZhbHVlIHBvc3NpYmxlIGZvciBhIFVJRCwgYSAzMi1iaXQgdW5zaWduZWQgaW50ZWdlci4KKyAgICAgKiBUaGlzIGNhbiBiZSB1c2VkIHRvIGZldGNoIGFsbCBuZXcgbWVzc2FnZXMgYnkga2VlcGluZyB0cmFjayBvZiB0aGUKKyAgICAgKiBsYXN0IFVJRCB0aGF0IHdhcyBzZWVuIGFuZCB1c2luZzoKKyAgICAgKiA8YmxvY2txdW90ZT48cHJlPgorICAgICAqCisgICAgICogCUZvbGRlciBmID0gc3RvcmUuZ2V0Rm9sZGVyKCJ3aGF0ZXZlciIpOworICAgICAqCVVJREZvbGRlciB1ZiA9IChVSURGb2xkZXIpZjsKKyAgICAgKglNZXNzYWdlW10gbmV3TXNncyA9CisgICAgICoJCXVmLmdldE1lc3NhZ2VzQnlVSUQobGFzdFNlZW5VSUQgKyAxLCBVSURGb2xkZXIuTUFYVUlEKTsKKyAgICAgKgorICAgICAqIDwvcHJlPjwvYmxvY2txdW90ZT48cD4KKyAgICAgKgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjYKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGxvbmcgTUFYVUlEID0gMHhmZmZmZmZmZkw7IC8vIG1heCAzMi1iaXQgdW5zaWduZWQgaW50CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBVSURWYWxpZGl0eSB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggdGhpcyBmb2xkZXIuIDxwPgorICAgICAqIAorICAgICAqIENsaWVudHMgdHlwaWNhbGx5IGNvbXBhcmUgdGhpcyB2YWx1ZSBhZ2FpbnN0IGEgVUlEVmFsaWRpdHkKKyAgICAgKiB2YWx1ZSBzYXZlZCBmcm9tIGEgcHJldmlvdXMgc2Vzc2lvbiB0byBpbnN1cmUgdGhhdCBhbnkgY2FjaGVkIAorICAgICAqIFVJRHMgYXJlIG5vdCBzdGFsZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gVUlEVmFsaWRpdHkKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXRVSURWYWxpZGl0eSgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIE1lc3NhZ2UgY29ycmVzcG9uZGluZyB0byB0aGUgZ2l2ZW4gVUlELiBJZiBubyBzdWNoIAorICAgICAqIG1lc3NhZ2UgZXhpc3RzLCA8Y29kZT5udWxsPC9jb2RlPiBpcyByZXR1cm5lZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1aWQJVUlEIGZvciB0aGUgZGVzaXJlZCBtZXNzYWdlCisgICAgICogQHJldHVybgkJdGhlIE1lc3NhZ2Ugb2JqZWN0LiA8Y29kZT5udWxsPC9jb2RlPiBpcyByZXR1cm5lZAorICAgICAqCQkJaWYgbm8gbWVzc2FnZSBjb3JyZXNwb25kaW5nIHRvIHRoaXMgVUlEIGlzIG9idGFpbmVkLgorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBNZXNzYWdlIGdldE1lc3NhZ2VCeVVJRChsb25nIHVpZCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldCB0aGUgTWVzc2FnZXMgc3BlY2lmaWVkIGJ5IHRoZSBnaXZlbiByYW5nZS4gVGhlIHNwZWNpYWwKKyAgICAgKiB2YWx1ZSBMQVNUVUlEIGNhbiBiZSB1c2VkIGZvciB0aGUgPGNvZGU+ZW5kPC9jb2RlPiBwYXJhbWV0ZXIKKyAgICAgKiB0byBpbmRpY2F0ZSB0aGUgVUlEIG9mIHRoZSBsYXN0IG1lc3NhZ2UgaW4gdGhlIGZvbGRlci4gPHA+CisgICAgICoKKyAgICAgKiBOb3RlIHRoYXQgPGNvZGU+ZW5kPC9jb2RlPiBuZWVkIG5vdCBiZSBncmVhdGVyIHRoYW4gPGNvZGU+c3RhcnQ8L2NvZGU+OworICAgICAqIHRoZSBvcmRlciBvZiB0aGUgcmFuZ2UgZG9lc24ndCBtYXR0ZXIuCisgICAgICogTm90ZSBhbHNvIHRoYXQsIHVubGVzcyB0aGUgZm9sZGVyIGlzIGVtcHR5LCB1c2Ugb2YgTEFTVFVJRCBlbnN1cmVzCisgICAgICogdGhhdCBhdCBsZWFzdCBvbmUgbWVzc2FnZSB3aWxsIGJlIHJldHVybmVkIC0gdGhlIGxhc3QgbWVzc2FnZSBpbiB0aGUKKyAgICAgKiBmb2xkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gc3RhcnQJc3RhcnQgVUlECisgICAgICogQHBhcmFtIGVuZAllbmQgVUlECisgICAgICogQHJldHVybgkJYXJyYXkgb2YgTWVzc2FnZSBvYmplY3RzCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICogQHNlZSAJCSNMQVNUVUlECisgICAgICovCisgICAgcHVibGljIE1lc3NhZ2VbXSBnZXRNZXNzYWdlc0J5VUlEKGxvbmcgc3RhcnQsIGxvbmcgZW5kKQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIE1lc3NhZ2VzIHNwZWNpZmllZCBieSB0aGUgZ2l2ZW4gYXJyYXkgb2YgVUlEcy4gSWYgYW55IFVJRCBpcyAKKyAgICAgKiBpbnZhbGlkLCA8Y29kZT5udWxsPC9jb2RlPiBpcyByZXR1cm5lZCBmb3IgdGhhdCBlbnRyeS4gPHA+CisgICAgICoKKyAgICAgKiBOb3RlIHRoYXQgdGhlIHJldHVybmVkIGFycmF5IHdpbGwgYmUgb2YgdGhlIHNhbWUgc2l6ZSBhcyB0aGUgc3BlY2lmaWVkCisgICAgICogYXJyYXkgb2YgVUlEcywgYW5kIDxjb2RlPm51bGw8L2NvZGU+IGVudHJpZXMgbWF5IGJlIHByZXNlbnQgaW4gdGhlCisgICAgICogYXJyYXkgdG8gaW5kaWNhdGUgaW52YWxpZCBVSURzLgorICAgICAqCisgICAgICogQHBhcmFtIHVpZHMJYXJyYXkgb2YgVUlEcworICAgICAqIEByZXR1cm4JCWFycmF5IG9mIE1lc3NhZ2Ugb2JqZWN0cworICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBNZXNzYWdlW10gZ2V0TWVzc2FnZXNCeVVJRChsb25nW10gdWlkcykgCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldCB0aGUgVUlEIGZvciB0aGUgc3BlY2lmaWVkIG1lc3NhZ2UuIE5vdGUgdGhhdCB0aGUgbWVzc2FnZQorICAgICAqIDxzdHJvbmc+bXVzdDwvc3Ryb25nPiBiZWxvbmcgdG8gdGhpcyBmb2xkZXIuIE90aGVyd2lzZQorICAgICAqIGphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uIGlzIHRocm93bi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtZXNzYWdlCU1lc3NhZ2UgZnJvbSB0aGlzIGZvbGRlcgorICAgICAqIEByZXR1cm4JCVVJRCBmb3IgdGhpcyBtZXNzYWdlCisgICAgICogQGV4Y2VwdGlvbglOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIGlmIHRoZSBnaXZlbiBNZXNzYWdlCisgICAgICoJCQlpcyBub3QgaW4gdGhpcyBGb2xkZXIuCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0VUlEKE1lc3NhZ2UgbWVzc2FnZSkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHByZWRpY3RlZCBVSUQgdGhhdCB3aWxsIGJlIGFzc2lnbmVkIHRvIHRoZQorICAgICAqIG5leHQgbWVzc2FnZSB0aGF0IGlzIGFwcGVuZGVkIHRvIHRoaXMgZm9sZGVyLgorICAgICAqIE1lc3NhZ2VzIG1pZ2h0IGJlIGFwcGVuZGVkIHRvIHRoZSBmb2xkZXIgYWZ0ZXIgdGhpcyB2YWx1ZQorICAgICAqIGlzIHJldHJpZXZlZCwgY2F1c2luZyB0aGlzIHZhbHVlIHRvIGJlIG91dCBvZiBkYXRlLgorICAgICAqIFRoaXMgdmFsdWUgbWlnaHQgb25seSBiZSB1cGRhdGVkIHdoZW4gYSBmb2xkZXIgaXMgZmlyc3Qgb3BlbmVkLgorICAgICAqIE5vdGUgdGhhdCBtZXNzYWdlcyBtYXkgaGF2ZSBiZWVuIGFwcGVuZGVkIHRvIHRoZSBmb2xkZXIKKyAgICAgKiB3aGlsZSBpdCB3YXMgb3BlbiBhbmQgdGh1cyB0aGlzIHZhbHVlIG1heSBiZSBvdXQgb2YKKyAgICAgKiBkYXRlLiA8cD4KKyAgICAgKgorICAgICAqIElmIHRoZSB2YWx1ZSBpcyB1bmtub3duLCAtMSBpcyByZXR1cm5lZC4gIDxwPgorICAgICAqCisgICAgICogQHJldHVybgkJdGhlIFVJRE5FWFQgdmFsdWUsIG9yIC0xIGlmIHVua25vd24KKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuNgorICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldFVJRE5leHQoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvVVJMTmFtZS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvVVJMTmFtZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUyNjk1NWMKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9VUkxOYW1lLmphdmEKQEAgLTAsMCArMSw3ODYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbDsKKworaW1wb3J0IGphdmEubmV0Lio7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbVdyaXRlcjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQml0U2V0OworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CisKKworLyoqCisgKiBUaGUgbmFtZSBvZiBhIFVSTC4gVGhpcyBjbGFzcyByZXByZXNlbnRzIGEgVVJMIG5hbWUgYW5kIGFsc28gCisgKiBwcm92aWRlcyB0aGUgYmFzaWMgcGFyc2luZyBmdW5jdGlvbmFsaXR5IHRvIHBhcnNlIG1vc3QgaW50ZXJuZXQgCisgKiBzdGFuZGFyZCBVUkwgc2NoZW1lcy4gPHA+CisgKgorICogTm90ZSB0aGF0IHRoaXMgY2xhc3MgZGlmZmVycyBmcm9tIDxjb2RlPmphdmEubmV0LlVSTDwvY29kZT4gCisgKiBpbiB0aGF0IHRoaXMgY2xhc3MganVzdCByZXByZXNlbnRzIHRoZSBuYW1lIG9mIGEgVVJMLCBpdCBkb2VzIAorICogbm90IG1vZGVsIHRoZSBjb25uZWN0aW9uIHRvIGEgVVJMLgorICoKKyAqIEBhdXRob3IJQ2hyaXN0b3BoZXIgQ290dG9uCisgKiBAYXV0aG9yCUJpbGwgU2hhbm5vbgorICovCisKK3B1YmxpYyBjbGFzcyBVUkxOYW1lIHsKKworICAgIC8qKgorICAgICAqIFRoZSBmdWxsIHZlcnNpb24gb2YgdGhlIFVSTAorICAgICAqLworICAgIHByb3RlY3RlZCBTdHJpbmcgZnVsbFVSTDsKKworICAgIC8qKiAKKyAgICAgKiBUaGUgcHJvdG9jb2wgdG8gdXNlIChmdHAsIGh0dHAsIG5udHAsIGltYXAsIHBvcDMgLi4uIGV0Yy4pIC4gCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgcHJvdG9jb2w7CisKKyAgICAvKiogCisgICAgICogVGhlIHVzZXJuYW1lIHRvIHVzZSB3aGVuIGNvbm5lY3RpbmcKKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyB1c2VybmFtZTsKKworICAgIC8qKiAKKyAgICAgKiBUaGUgcGFzc3dvcmQgdG8gdXNlIHdoZW4gY29ubmVjdGluZy4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyBwYXNzd29yZDsKKworICAgIC8qKiAKKyAgICAgKiBUaGUgaG9zdCBuYW1lIHRvIHdoaWNoIHRvIGNvbm5lY3QuIAorICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nIGhvc3Q7CisKKyAgICAvKioKKyAgICAgKiBUaGUgaG9zdCdzIElQIGFkZHJlc3MsIHVzZWQgaW4gZXF1YWxzIGFuZCBoYXNoQ29kZS4KKyAgICAgKiBDb21wdXRlZCBvbiBkZW1hbmQuCisgICAgICovCisgICAgcHJpdmF0ZSBJbmV0QWRkcmVzcyBob3N0QWRkcmVzczsKKyAgICBwcml2YXRlIGJvb2xlYW4gaG9zdEFkZHJlc3NLbm93biA9IGZhbHNlOworCisgICAgLyoqIAorICAgICAqIFRoZSBwcm90b2NvbCBwb3J0IHRvIGNvbm5lY3QgdG8uIAorICAgICAqLworICAgIHByaXZhdGUgaW50IHBvcnQgPSAtMTsKKworICAgIC8qKiAKKyAgICAgKiBUaGUgc3BlY2lmaWVkIGZpbGUgbmFtZSBvbiB0aGF0IGhvc3QuIAorICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nIGZpbGU7CisKKyAgICAvKiogCisgICAgICogIyByZWZlcmVuY2UuIAorICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nIHJlZjsKKworICAgIC8qKgorICAgICAqIE91ciBoYXNoIGNvZGUuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgaGFzaENvZGUgPSAwOworCisgICAgLyoqCisgICAgICogQSB3YXkgdG8gdHVybiBvZmYgZW5jb2RpbmcsIGp1c3QgaW4gY2FzZS4uLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gZG9FbmNvZGUgPSB0cnVlOworCisgICAgc3RhdGljIHsKKwl0cnkgeworCSAgICBkb0VuY29kZSA9ICFCb29sZWFuLmdldEJvb2xlYW4oIm1haWwuVVJMTmFtZS5kb250ZW5jb2RlIik7CisJfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJICAgIC8vIGlnbm9yZSBhbnkgZXJyb3JzCisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYSBVUkxOYW1lIG9iamVjdCBmcm9tIHRoZSBzcGVjaWZpZWQgcHJvdG9jb2wsCisgICAgICogaG9zdCwgcG9ydCBudW1iZXIsIGZpbGUsIHVzZXJuYW1lLCBhbmQgcGFzc3dvcmQuIFNwZWNpZnlpbmcgYSBwb3J0CisgICAgICogbnVtYmVyIG9mIC0xIGluZGljYXRlcyB0aGF0IHRoZSBVUkwgc2hvdWxkIHVzZSB0aGUgZGVmYXVsdCBwb3J0IGZvcgorICAgICAqIHRoZSBwcm90b2NvbC4KKyAgICAgKgorICAgICAqIEBwYXJhbQlwcm90b2NvbAl0aGUgcHJvdG9jb2wKKyAgICAgKiBAcGFyYW0JaG9zdAkJdGhlIGhvc3QgbmFtZQorICAgICAqIEBwYXJhbQlwb3J0CQl0aGUgcG9ydCBudW1iZXIKKyAgICAgKiBAcGFyYW0JZmlsZQkJdGhlIGZpbGUKKyAgICAgKiBAcGFyYW0JdXNlcm5hbWUJdGhlIHVzZXIgbmFtZQorICAgICAqIEBwYXJhbQlwYXNzd29yZAl0aGUgcGFzc3dvcmQKKyAgICAgKi8KKyAgICBwdWJsaWMgVVJMTmFtZSgKKwlTdHJpbmcgcHJvdG9jb2wsCisJU3RyaW5nIGhvc3QsCisJaW50IHBvcnQsCisJU3RyaW5nIGZpbGUsCisJU3RyaW5nIHVzZXJuYW1lLAorCVN0cmluZyBwYXNzd29yZAorCSkKKyAgICB7CisJdGhpcy5wcm90b2NvbCA9IHByb3RvY29sOworCXRoaXMuaG9zdCA9IGhvc3Q7CisJdGhpcy5wb3J0ID0gcG9ydDsKKwlpbnQgcmVmU3RhcnQ7CisJaWYgKGZpbGUgIT0gbnVsbCAmJiAocmVmU3RhcnQgPSBmaWxlLmluZGV4T2YoJyMnKSkgIT0gLTEpIHsKKwkgICAgdGhpcy5maWxlID0gZmlsZS5zdWJzdHJpbmcoMCwgcmVmU3RhcnQpOworCSAgICB0aGlzLnJlZiA9IGZpbGUuc3Vic3RyaW5nKHJlZlN0YXJ0ICsgMSk7CisJfSBlbHNlIHsKKwkgICAgdGhpcy5maWxlID0gZmlsZTsKKwkgICAgdGhpcy5yZWYgPSBudWxsOworCX0KKwl0aGlzLnVzZXJuYW1lID0gZG9FbmNvZGUgPyBlbmNvZGUodXNlcm5hbWUpIDogdXNlcm5hbWU7CisJdGhpcy5wYXNzd29yZCA9IGRvRW5jb2RlID8gZW5jb2RlKHBhc3N3b3JkKSA6IHBhc3N3b3JkOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCBhIFVSTE5hbWUgZnJvbSBhIGphdmEubmV0LlVSTCBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0JdXJsCXRoZSBVUkwKKyAgICAgKi8KKyAgICBwdWJsaWMgVVJMTmFtZShVUkwgdXJsKSB7CisJdGhpcyh1cmwudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGEgVVJMTmFtZSBmcm9tIHRoZSBzdHJpbmcuICBQYXJzZXMgb3V0IGFsbCB0aGUgcG9zc2libGUKKyAgICAgKiBpbmZvcm1hdGlvbiAocHJvdG9jb2wsIGhvc3QsIHBvcnQsIGZpbGUsIHVzZXJuYW1lLCBwYXNzd29yZCkuCisgICAgICoKKyAgICAgKiBAcGFyYW0JdXJsCXRoZSBVUkwgc3RyaW5nCisgICAgICovCisgICAgcHVibGljIFVSTE5hbWUoU3RyaW5nIHVybCkgeworCXBhcnNlU3RyaW5nKHVybCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIFVSTE5hbWUuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKwlpZiAoZnVsbFVSTCA9PSBudWxsKSB7CisJICAgIC8vIGFkZCB0aGUgInByb3RvY29sOiIKKwkgICAgU3RyaW5nQnVpbGRlciB0ZW1wVVJMID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKwkgICAgaWYgKHByb3RvY29sICE9IG51bGwpIHsKKwkJdGVtcFVSTC5hcHBlbmQocHJvdG9jb2wpOworCQl0ZW1wVVJMLmFwcGVuZCgiOiIpOworCSAgICB9CisKKwkgICAgaWYgKHVzZXJuYW1lICE9IG51bGwgfHwgaG9zdCAhPSBudWxsKSB7CisJCS8vIGFkZCB0aGUgIi8vIgorCQl0ZW1wVVJMLmFwcGVuZCgiLy8iKTsKKwkJCisJCS8vIGFkZCB0aGUgdXNlcjpwYXNzd29yZEAKKwkJLy8gWFhYIC0gY2FuIHlvdSBqdXN0IGhhdmUgYSBwYXNzd29yZD8gd2l0aG91dCBhIHVzZXJuYW1lPworCQlpZiAodXNlcm5hbWUgIT0gbnVsbCkgeworCQkgICAgdGVtcFVSTC5hcHBlbmQodXNlcm5hbWUpOworCQkKKwkJICAgIGlmIChwYXNzd29yZCAhPSBudWxsKXsKKwkJCXRlbXBVUkwuYXBwZW5kKCI6Iik7CisJCQl0ZW1wVVJMLmFwcGVuZChwYXNzd29yZCk7CisJCSAgICB9CisJCQorCQkgICAgdGVtcFVSTC5hcHBlbmQoIkAiKTsKKwkJfQorCSAgICAKKwkJLy8gYWRkIGhvc3QKKwkJaWYgKGhvc3QgIT0gbnVsbCkgeworCQkgICAgdGVtcFVSTC5hcHBlbmQoaG9zdCk7CisJCX0KKwkgICAgCisJCS8vIGFkZCBwb3J0IChpZiBuZWVkZWQpCisJCWlmIChwb3J0ICE9IC0xKSB7CisJCSAgICB0ZW1wVVJMLmFwcGVuZCgiOiIpOworCQkgICAgdGVtcFVSTC5hcHBlbmQoSW50ZWdlci50b1N0cmluZyhwb3J0KSk7CisJCX0KKwkJaWYgKGZpbGUgIT0gbnVsbCkKKwkJICAgIHRlbXBVUkwuYXBwZW5kKCIvIik7CisJICAgIH0KKwkgICAgCisJICAgIC8vIGFkZCB0aGUgZmlsZQorCSAgICBpZiAoZmlsZSAhPSBudWxsKSB7CisJCXRlbXBVUkwuYXBwZW5kKGZpbGUpOworCSAgICB9CisJICAgIAorCSAgICAvLyBhZGQgdGhlIHJlZgorCSAgICBpZiAocmVmICE9IG51bGwpIHsKKwkJdGVtcFVSTC5hcHBlbmQoIiMiKTsKKwkJdGVtcFVSTC5hcHBlbmQocmVmKTsKKwkgICAgfQorCisJICAgIC8vIGNyZWF0ZSB0aGUgZnVsbFVSTCBub3cKKwkgICAgZnVsbFVSTCA9IHRlbXBVUkwudG9TdHJpbmcoKTsKKwl9CisKKwlyZXR1cm4gZnVsbFVSTDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNZXRob2Qgd2hpY2ggZG9lcyBhbGwgb2YgdGhlIHdvcmsgb2YgcGFyc2luZyB0aGUgc3RyaW5nLgorICAgICAqCisgICAgICogQHBhcmFtCXVybAl0aGUgVVJMIHN0cmluZyB0byBwYXJzZQorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHBhcnNlU3RyaW5nKFN0cmluZyB1cmwpIHsKKwkvLyBpbml0aWFsaXplIGV2ZXJ5dGhpbmcgaW4gY2FzZSBjYWxsZWQgZnJvbSBzdWJjbGFzcworCS8vIChVUkxOYW1lIHJlYWxseSBzaG91bGQgYmUgYSBmaW5hbCBjbGFzcykKKwlwcm90b2NvbCA9IGZpbGUgPSByZWYgPSBob3N0ID0gdXNlcm5hbWUgPSBwYXNzd29yZCA9IG51bGw7CisJcG9ydCA9IC0xOworCisJaW50IGxlbiA9IHVybC5sZW5ndGgoKTsKKworCS8vIGZpbmQgdGhlIHByb3RvY29sCisJLy8gWFhYIC0gc2hvdWxkIGNoZWNrIGZvciBvbmx5IGxlZ2FsIGNoYXJhY3RlcnMgYmVmb3JlIHRoZSBjb2xvbgorCS8vIChsZWdhbDogYS16LCBBLVosIDAtOSwgIisiLCAiLiIsICItIikKKwlpbnQgcHJvdG9jb2xFbmQgPSB1cmwuaW5kZXhPZignOicpOworICAgICAgICBpZiAocHJvdG9jb2xFbmQgIT0gLTEpCisJICAgIHByb3RvY29sID0gdXJsLnN1YnN0cmluZygwLCBwcm90b2NvbEVuZCk7CisKKwkvLyBpcyB0aGlzIGFuIEludGVybmV0IHN0YW5kYXJkIFVSTCB0aGF0IGNvbnRhaW5zIGEgaG9zdCBuYW1lPworCWlmICh1cmwucmVnaW9uTWF0Y2hlcyhwcm90b2NvbEVuZCArIDEsICIvLyIsIDAsIDIpKSB7CisJICAgIC8vIGZpbmQgd2hlcmUgdGhlIGZpbGUgc3RhcnRzCisJICAgIFN0cmluZyBmdWxsaG9zdCA9IG51bGw7CisJICAgIGludCBmaWxlU3RhcnQgPSB1cmwuaW5kZXhPZignLycsIHByb3RvY29sRW5kICsgMyk7CisJICAgIGlmIChmaWxlU3RhcnQgIT0gLTEpIHsKKwkJZnVsbGhvc3QgPSB1cmwuc3Vic3RyaW5nKHByb3RvY29sRW5kICsgMywgZmlsZVN0YXJ0KTsKKwkJaWYgKGZpbGVTdGFydCArIDEgPCBsZW4pCisJCSAgICBmaWxlID0gdXJsLnN1YnN0cmluZyhmaWxlU3RhcnQgKyAxKTsKKwkJZWxzZQorCQkgICAgZmlsZSA9ICIiOworCSAgICB9IGVsc2UKKwkJZnVsbGhvc3QgPSB1cmwuc3Vic3RyaW5nKHByb3RvY29sRW5kICsgMyk7CisKKwkgICAgLy8gZXhhbWluZSB0aGUgZnVsbGhvc3QsIGZvciB1c2VybmFtZSBwYXNzd29yZCBldGMuCisJICAgIGludCBpID0gZnVsbGhvc3QuaW5kZXhPZignQCcpOworCSAgICBpZiAoaSAhPSAtMSkgeworCQlTdHJpbmcgZnVsbHVzZXJwYXNzID0gZnVsbGhvc3Quc3Vic3RyaW5nKDAsIGkpOworCQlmdWxsaG9zdCA9IGZ1bGxob3N0LnN1YnN0cmluZyhpICsgMSk7CisKKwkJLy8gZ2V0IHVzZXIgYW5kIHBhc3N3b3JkCisJCWludCBwYXNzaW5kZXggPSBmdWxsdXNlcnBhc3MuaW5kZXhPZignOicpOworCQlpZiAocGFzc2luZGV4ICE9IC0xKSB7CisJCSAgICB1c2VybmFtZSA9IGZ1bGx1c2VycGFzcy5zdWJzdHJpbmcoMCwgcGFzc2luZGV4KTsKKwkJICAgIHBhc3N3b3JkID0gZnVsbHVzZXJwYXNzLnN1YnN0cmluZyhwYXNzaW5kZXggKyAxKTsKKwkJfSBlbHNlIHsKKwkJICAgIHVzZXJuYW1lID0gZnVsbHVzZXJwYXNzOworCQl9CisJICAgIH0KKwkgICAgCisJICAgIC8vIGdldCB0aGUgcG9ydCAoaWYgdGhlcmUpCisJICAgIGludCBwb3J0aW5kZXg7CisJICAgIGlmIChmdWxsaG9zdC5sZW5ndGgoKSA+IDAgJiYgZnVsbGhvc3QuY2hhckF0KDApID09ICdbJykgeworCQkvLyBhbiBJUHY2IGFkZHJlc3M/CisJCXBvcnRpbmRleCA9IGZ1bGxob3N0LmluZGV4T2YoJzonLCBmdWxsaG9zdC5pbmRleE9mKCddJykpOworCSAgICB9IGVsc2UgeworCQlwb3J0aW5kZXggPSBmdWxsaG9zdC5pbmRleE9mKCc6Jyk7CisJICAgIH0KKwkgICAgaWYgKHBvcnRpbmRleCAhPSAtMSkgeworCQlTdHJpbmcgcG9ydHN0cmluZyA9IGZ1bGxob3N0LnN1YnN0cmluZyhwb3J0aW5kZXggKyAxKTsKKwkJaWYgKHBvcnRzdHJpbmcubGVuZ3RoKCkgPiAwKSB7CisJCSAgICB0cnkgeworCQkJcG9ydCA9IEludGVnZXIucGFyc2VJbnQocG9ydHN0cmluZyk7CisJCSAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gbmZleCkgeworCQkJcG9ydCA9IC0xOworCQkgICAgfQorCQl9CisJCQorCQlob3N0ID0gZnVsbGhvc3Quc3Vic3RyaW5nKDAsIHBvcnRpbmRleCk7CisJICAgIH0gZWxzZSB7CisJCWhvc3QgPSBmdWxsaG9zdDsKKwkgICAgfQorCX0gZWxzZSB7CisJICAgIGlmIChwcm90b2NvbEVuZCArIDEgPCBsZW4pCisJCWZpbGUgPSB1cmwuc3Vic3RyaW5nKHByb3RvY29sRW5kICsgMSk7CisJfQorCisJLy8gZXh0cmFjdCB0aGUgcmVmZXJlbmNlIGZyb20gdGhlIGZpbGUgbmFtZSwgaWYgYW55CisJaW50IHJlZlN0YXJ0OworCWlmIChmaWxlICE9IG51bGwgJiYgKHJlZlN0YXJ0ID0gZmlsZS5pbmRleE9mKCcjJykpICE9IC0xKSB7CisJICAgIHJlZiA9IGZpbGUuc3Vic3RyaW5nKHJlZlN0YXJ0ICsgMSk7CisJICAgIGZpbGUgPSBmaWxlLnN1YnN0cmluZygwLCByZWZTdGFydCk7CisJfQorICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwb3J0IG51bWJlciBvZiB0aGlzIFVSTE5hbWUuCisgICAgICogUmV0dXJucyAtMSBpZiB0aGUgcG9ydCBpcyBub3Qgc2V0LiAKKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIHBvcnQgbnVtYmVyCisgICAgICovCisgICAgcHVibGljIGludCBnZXRQb3J0KCkgeworCXJldHVybiBwb3J0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHByb3RvY29sIG9mIHRoaXMgVVJMTmFtZS4KKyAgICAgKiBSZXR1cm5zIG51bGwgaWYgdGhpcyBVUkxOYW1lIGhhcyBubyBwcm90b2NvbC4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIHByb3RvY29sCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRQcm90b2NvbCgpIHsKKwlyZXR1cm4gcHJvdG9jb2w7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZmlsZSBuYW1lIG9mIHRoaXMgVVJMTmFtZS4KKyAgICAgKiBSZXR1cm5zIG51bGwgaWYgdGhpcyBVUkxOYW1lIGhhcyBubyBmaWxlIG5hbWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBmaWxlIG5hbWUgb2YgdGhpcyBVUkxOYW1lCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRGaWxlKCkgeworCXJldHVybiBmaWxlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHJlZmVyZW5jZSBvZiB0aGlzIFVSTE5hbWUuCisgICAgICogUmV0dXJucyBudWxsIGlmIHRoaXMgVVJMTmFtZSBoYXMgbm8gcmVmZXJlbmNlLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgcmVmZXJlbmNlIHBhcnQgb2YgdGhlIFVSTE5hbWUKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFJlZigpIHsKKwlyZXR1cm4gcmVmOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGhvc3Qgb2YgdGhpcyBVUkxOYW1lLgorICAgICAqIFJldHVybnMgbnVsbCBpZiB0aGlzIFVSTE5hbWUgaGFzIG5vIGhvc3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBob3N0IG5hbWUKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEhvc3QoKSB7CisJcmV0dXJuIGhvc3Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdXNlciBuYW1lIG9mIHRoaXMgVVJMTmFtZS4KKyAgICAgKiBSZXR1cm5zIG51bGwgaWYgdGhpcyBVUkxOYW1lIGhhcyBubyB1c2VyIG5hbWUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSB1c2VyIG5hbWUKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFVzZXJuYW1lKCkgeworCXJldHVybiBkb0VuY29kZSA/IGRlY29kZSh1c2VybmFtZSkgOiB1c2VybmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwYXNzd29yZCBvZiB0aGlzIFVSTE5hbWUuCisgICAgICogUmV0dXJucyBudWxsIGlmIHRoaXMgVVJMTmFtZSBoYXMgbm8gcGFzc3dvcmQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBwYXNzd29yZAorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UGFzc3dvcmQoKSB7CisJcmV0dXJuIGRvRW5jb2RlID8gZGVjb2RlKHBhc3N3b3JkKSA6IHBhc3N3b3JkOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBVUkwgZnJvbSB0aGUgVVJMTmFtZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIFVSTAorICAgICAqIEBleGNlcHRpb24JTWFsZm9ybWVkVVJMRXhjZXB0aW9uIGlmIHRoZSBVUkwgaXMgbWFsZm9ybWVkCisgICAgICovCisgICAgcHVibGljIFVSTCBnZXRVUkwoKSB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uIHsKKwkvLyBVUkwgZXhwZWN0cyB0aGUgZmlsZSB0byBpbmNsdWRlIHRoZSBzZXBhcmF0aW5nICIvIgorCVN0cmluZyBmID0gZ2V0RmlsZSgpOworCWlmIChmID09IG51bGwpCisJICAgIGYgPSAiIjsKKwllbHNlCisJICAgIGYgPSAiLyIgKyBmOworICAgICAgICByZXR1cm4gbmV3IFVSTChnZXRQcm90b2NvbCgpLCBnZXRIb3N0KCksIGdldFBvcnQoKSwgZik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcGFyZXMgdHdvIFVSTE5hbWVzLiBUaGUgcmVzdWx0IGlzIHRydWUgaWYgYW5kIG9ubHkgaWYgdGhlCisgICAgICogYXJndW1lbnQgaXMgbm90IG51bGwgYW5kIGlzIGEgVVJMTmFtZSBvYmplY3QgdGhhdCByZXByZXNlbnRzIHRoZQorICAgICAqIHNhbWUgVVJMTmFtZSBhcyB0aGlzIG9iamVjdC4gVHdvIFVSTE5hbWUgb2JqZWN0cyBhcmUgZXF1YWwgaWYKKyAgICAgKiB0aGV5IGhhdmUgdGhlIHNhbWUgcHJvdG9jb2wgYW5kIHRoZSBzYW1lIGhvc3QsCisgICAgICogdGhlIHNhbWUgcG9ydCBudW1iZXIgb24gdGhlIGhvc3QsIHRoZSBzYW1lIHVzZXJuYW1lLAorICAgICAqIGFuZCB0aGUgc2FtZSBmaWxlIG9uIHRoZSBob3N0LiBUaGUgZmllbGRzIChob3N0LCB1c2VybmFtZSwKKyAgICAgKiBmaWxlKSBhcmUgYWxzbyBjb25zaWRlcmVkIHRoZSBzYW1lIGlmIHRoZXkgYXJlIGJvdGgKKyAgICAgKiBudWxsLiAgPHA+CisgICAgICoKKyAgICAgKiBIb3N0cyBhcmUgY29uc2lkZXJlZCBlcXVhbCBpZiB0aGUgbmFtZXMgYXJlIGVxdWFsIChjYXNlIGluZGVwZW5kZW50KQorICAgICAqIG9yIGlmIGhvc3QgbmFtZSBsb29rdXBzIGZvciB0aGVtIGJvdGggc3VjY2VlZCBhbmQgdGhleSBib3RoIHJlZmVyZW5jZQorICAgICAqIHRoZSBzYW1lIElQIGFkZHJlc3MuIDxwPgorICAgICAqCisgICAgICogTm90ZSB0aGF0IFVSTE5hbWUgaGFzIG5vIGtub3dsZWRnZSBvZiBkZWZhdWx0IHBvcnQgbnVtYmVycyBmb3IKKyAgICAgKiBwYXJ0aWN1bGFyIHByb3RvY29scywgc28gImltYXA6Ly9ob3N0IiBhbmQgImltYXA6Ly9ob3N0OjE0MyIKKyAgICAgKiB3b3VsZCBub3QgY29tcGFyZSBhcyBlcXVhbC4gPHA+CisgICAgICoKKyAgICAgKiBOb3RlIGFsc28gdGhhdCB0aGUgcGFzc3dvcmQgZmllbGQgaXMgbm90IGluY2x1ZGVkIGluIHRoZSBjb21wYXJpc29uLAorICAgICAqIG5vciBpcyBhbnkgcmVmZXJlbmNlIGZpZWxkIGFwcGVuZGVkIHRvIHRoZSBmaWxlbmFtZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgeworICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBVUkxOYW1lKSkKKwkgICAgcmV0dXJuIGZhbHNlOworCVVSTE5hbWUgdTIgPSAoVVJMTmFtZSlvYmo7CisKKwkvLyBjb21wYXJlIHByb3RvY29scworCWlmICghKHByb3RvY29sID09IHUyLnByb3RvY29sIHx8CisJCShwcm90b2NvbCAhPSBudWxsICYmIHByb3RvY29sLmVxdWFscyh1Mi5wcm90b2NvbCkpKSkKKwkgICAgcmV0dXJuIGZhbHNlOworCisJLy8gY29tcGFyZSBob3N0cworCUluZXRBZGRyZXNzIGExID0gZ2V0SG9zdEFkZHJlc3MoKSwgYTIgPSB1Mi5nZXRIb3N0QWRkcmVzcygpOworCS8vIGlmIHdlIGhhdmUgaW50ZXJuZXQgYWRkcmVzcyBmb3IgYm90aCwgYW5kIHRoZXkncmUgbm90IHRoZSBzYW1lLCBmYWlsCisJaWYgKGExICE9IG51bGwgJiYgYTIgIT0gbnVsbCkgeworCSAgICBpZiAoIWExLmVxdWFscyhhMikpCisJCXJldHVybiBmYWxzZTsKKwkvLyBlbHNlLCBpZiB3ZSBoYXZlIGhvc3QgbmFtZXMgZm9yIGJvdGgsIGFuZCB0aGV5J3JlIG5vdCB0aGUgc2FtZSwgZmFpbAorCX0gZWxzZSBpZiAoaG9zdCAhPSBudWxsICYmIHUyLmhvc3QgIT0gbnVsbCkgeworCSAgICBpZiAoIWhvc3QuZXF1YWxzSWdub3JlQ2FzZSh1Mi5ob3N0KSkKKwkJcmV0dXJuIGZhbHNlOworCS8vIGVsc2UsIGlmIG5vdCBib3RoIG51bGwKKwl9IGVsc2UgaWYgKGhvc3QgIT0gdTIuaG9zdCkgeworCSAgICByZXR1cm4gZmFsc2U7CisJfQorCS8vIGF0IHRoaXMgcG9pbnQsIGhvc3RzIG1hdGNoCisKKwkvLyBjb21wYXJlIHVzZXJuYW1lcworCWlmICghKHVzZXJuYW1lID09IHUyLnVzZXJuYW1lIHx8CisJCSh1c2VybmFtZSAhPSBudWxsICYmIHVzZXJuYW1lLmVxdWFscyh1Mi51c2VybmFtZSkpKSkKKwkgICAgcmV0dXJuIGZhbHNlOworCisJLy8gRm9yZ2V0IGFib3V0IHBhc3N3b3JkIHNpbmNlIGl0IGRvZXNuJ3QKKwkvLyByZWFsbHkgZGVub3RlIGEgZGlmZmVyZW50IHN0b3JlLgorCisJLy8gY29tcGFyZSBmaWxlcworCVN0cmluZyBmMSA9IGZpbGUgPT0gbnVsbCA/ICIiIDogZmlsZTsKKwlTdHJpbmcgZjIgPSB1Mi5maWxlID09IG51bGwgPyAiIiA6IHUyLmZpbGU7CisKKwlpZiAoIWYxLmVxdWFscyhmMikpCisJICAgIHJldHVybiBmYWxzZTsKKworCS8vIGNvbXBhcmUgcG9ydHMKKwlpZiAocG9ydCAhPSB1Mi5wb3J0KQorCSAgICByZXR1cm4gZmFsc2U7CisKKwkvLyBhbGwgY29tcGFyaXNvbnMgc3VjY2VlZGVkLCB0aGV5J3JlIGVxdWFsCisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXB1dGUgdGhlIGhhc2ggY29kZSBmb3IgdGhpcyBVUkxOYW1lLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisJaWYgKGhhc2hDb2RlICE9IDApCisJICAgIHJldHVybiBoYXNoQ29kZTsKKwlpZiAocHJvdG9jb2wgIT0gbnVsbCkKKwkgICAgaGFzaENvZGUgKz0gcHJvdG9jb2wuaGFzaENvZGUoKTsKKwlJbmV0QWRkcmVzcyBhZGRyID0gZ2V0SG9zdEFkZHJlc3MoKTsKKwlpZiAoYWRkciAhPSBudWxsKQorCSAgICBoYXNoQ29kZSArPSBhZGRyLmhhc2hDb2RlKCk7CisJZWxzZSBpZiAoaG9zdCAhPSBudWxsKQorCSAgICBoYXNoQ29kZSArPSBob3N0LnRvTG93ZXJDYXNlKExvY2FsZS5FTkdMSVNIKS5oYXNoQ29kZSgpOworCWlmICh1c2VybmFtZSAhPSBudWxsKQorCSAgICBoYXNoQ29kZSArPSB1c2VybmFtZS5oYXNoQ29kZSgpOworCWlmIChmaWxlICE9IG51bGwpCisJICAgIGhhc2hDb2RlICs9IGZpbGUuaGFzaENvZGUoKTsKKwloYXNoQ29kZSArPSBwb3J0OworCXJldHVybiBoYXNoQ29kZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIElQIGFkZHJlc3Mgb2Ygb3VyIGhvc3QuICBMb29rIHVwIHRoZQorICAgICAqIG5hbWUgdGhlIGZpcnN0IHRpbWUgYW5kIHJlbWVtYmVyIHRoYXQgd2UndmUgZG9uZQorICAgICAqIHNvLCB3aGV0aGVyIHRoZSBsb29rdXAgZmFpbHMgb3Igbm90LgorICAgICAqLworICAgIHByaXZhdGUgc3luY2hyb25pemVkIEluZXRBZGRyZXNzIGdldEhvc3RBZGRyZXNzKCkgeworCWlmIChob3N0QWRkcmVzc0tub3duKQorCSAgICByZXR1cm4gaG9zdEFkZHJlc3M7CisJaWYgKGhvc3QgPT0gbnVsbCkKKwkgICAgcmV0dXJuIG51bGw7CisJdHJ5IHsKKwkgICAgaG9zdEFkZHJlc3MgPSBJbmV0QWRkcmVzcy5nZXRCeU5hbWUoaG9zdCk7CisJfSBjYXRjaCAoVW5rbm93bkhvc3RFeGNlcHRpb24gZXgpIHsKKwkgICAgaG9zdEFkZHJlc3MgPSBudWxsOworCX0KKwlob3N0QWRkcmVzc0tub3duID0gdHJ1ZTsKKwlyZXR1cm4gaG9zdEFkZHJlc3M7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIGNsYXNzIGNvbnRhaW5zIGEgdXRpbGl0eSBtZXRob2QgZm9yIGNvbnZlcnRpbmcgYQorICAgICAqIDxjb2RlPlN0cmluZzwvY29kZT4gaW50byBhIE1JTUUgZm9ybWF0IGNhbGxlZAorICAgICAqICI8Y29kZT54LXd3dy1mb3JtLXVybGVuY29kZWQ8L2NvZGU+IiBmb3JtYXQuCisgICAgICogPHA+CisgICAgICogVG8gY29udmVydCBhIDxjb2RlPlN0cmluZzwvY29kZT4sIGVhY2ggY2hhcmFjdGVyIGlzIGV4YW1pbmVkIGluIHR1cm46CisgICAgICogPHVsPgorICAgICAqIDxsaT5UaGUgQVNDSUkgY2hhcmFjdGVycyAnPGNvZGU+YTwvY29kZT4nIHRocm91Z2ggJzxjb2RlPno8L2NvZGU+JywKKyAgICAgKiAgICAgJzxjb2RlPkE8L2NvZGU+JyB0aHJvdWdoICc8Y29kZT5aPC9jb2RlPicsICc8Y29kZT4wPC9jb2RlPicKKyAgICAgKiAgICAgdGhyb3VnaCAnPGNvZGU+OTwvY29kZT4nLCBhbmQgJnF1b3Q7LiZxdW90OywgJnF1b3Q7LSZxdW90OywgCisgICAgICogJnF1b3Q7KiZxdW90OywgJnF1b3Q7XyZxdW90OyByZW1haW4gdGhlIHNhbWUuCisgICAgICogPGxpPlRoZSBzcGFjZSBjaGFyYWN0ZXIgJzxjb2RlPiZuYnNwOzwvY29kZT4nIGlzIGNvbnZlcnRlZCBpbnRvIGEKKyAgICAgKiAgICAgcGx1cyBzaWduICc8Y29kZT4rPC9jb2RlPicuCisgICAgICogPGxpPkFsbCBvdGhlciBjaGFyYWN0ZXJzIGFyZSBjb252ZXJ0ZWQgaW50byB0aGUgMy1jaGFyYWN0ZXIgc3RyaW5nCisgICAgICogICAgICI8Y29kZT4lPGk+eHk8L2k+PC9jb2RlPiIsIHdoZXJlIDxpPnh5PC9pPiBpcyB0aGUgdHdvLWRpZ2l0CisgICAgICogICAgIGhleGFkZWNpbWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBsb3dlciA4LWJpdHMgb2YgdGhlIGNoYXJhY3Rlci4KKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogQGF1dGhvciAgSGVyYiBKZWxsaW5laworICAgICAqIEBzaW5jZSAgIEpESzEuMAorICAgICAqLworICAgIHN0YXRpYyBCaXRTZXQgZG9udE5lZWRFbmNvZGluZzsKKyAgICBzdGF0aWMgZmluYWwgaW50IGNhc2VEaWZmID0gKCdhJyAtICdBJyk7CisKKyAgICAvKiBUaGUgbGlzdCBvZiBjaGFyYWN0ZXJzIHRoYXQgYXJlIG5vdCBlbmNvZGVkIGhhdmUgYmVlbiBkZXRlcm1pbmVkIGJ5CisgICAgICAgcmVmZXJlbmNpbmcgTydSZWlsbHkncyAiSFRNTDogVGhlIERlZmluaXRpdmUgR3VpZGUiIChwYWdlIDE2NCkuICovCisKKyAgICBzdGF0aWMgeworCWRvbnROZWVkRW5jb2RpbmcgPSBuZXcgQml0U2V0KDI1Nik7CisJaW50IGk7CisJZm9yIChpID0gJ2EnOyBpIDw9ICd6JzsgaSsrKSB7CisJICAgIGRvbnROZWVkRW5jb2Rpbmcuc2V0KGkpOworCX0KKwlmb3IgKGkgPSAnQSc7IGkgPD0gJ1onOyBpKyspIHsKKwkgICAgZG9udE5lZWRFbmNvZGluZy5zZXQoaSk7CisJfQorCWZvciAoaSA9ICcwJzsgaSA8PSAnOSc7IGkrKykgeworCSAgICBkb250TmVlZEVuY29kaW5nLnNldChpKTsKKwl9CisJLyogZW5jb2RpbmcgYSBzcGFjZSB0byBhICsgaXMgZG9uZSBpbiB0aGUgZW5jb2RlKCkgbWV0aG9kICovCisJZG9udE5lZWRFbmNvZGluZy5zZXQoJyAnKTsKKwlkb250TmVlZEVuY29kaW5nLnNldCgnLScpOworCWRvbnROZWVkRW5jb2Rpbmcuc2V0KCdfJyk7CisJZG9udE5lZWRFbmNvZGluZy5zZXQoJy4nKTsKKwlkb250TmVlZEVuY29kaW5nLnNldCgnKicpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRyYW5zbGF0ZXMgYSBzdHJpbmcgaW50byA8Y29kZT54LXd3dy1mb3JtLXVybGVuY29kZWQ8L2NvZGU+IGZvcm1hdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSAgIHMgICA8Y29kZT5TdHJpbmc8L2NvZGU+IHRvIGJlIHRyYW5zbGF0ZWQuCisgICAgICogQHJldHVybiAgdGhlIHRyYW5zbGF0ZWQgPGNvZGU+U3RyaW5nPC9jb2RlPi4KKyAgICAgKi8KKyAgICBzdGF0aWMgU3RyaW5nIGVuY29kZShTdHJpbmcgcykgeworCWlmIChzID09IG51bGwpCisJICAgIHJldHVybiBudWxsOworCS8vIHRoZSBjb21tb24gY2FzZSBpcyBubyBlbmNvZGluZyBpcyBuZWVkZWQKKwlmb3IgKGludCBpID0gMDsgaSA8IHMubGVuZ3RoKCk7IGkrKykgeworCSAgICBpbnQgYyA9IChpbnQpcy5jaGFyQXQoaSk7CisJICAgIGlmIChjID09ICcgJyB8fCAhZG9udE5lZWRFbmNvZGluZy5nZXQoYykpCisJCXJldHVybiBfZW5jb2RlKHMpOworCX0KKwlyZXR1cm4gczsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgX2VuY29kZShTdHJpbmcgcykgeworCWludCBtYXhCeXRlc1BlckNoYXIgPSAxMDsKKyAgICAgICAgU3RyaW5nQnVpbGRlciBvdXQgPSBuZXcgU3RyaW5nQnVpbGRlcihzLmxlbmd0aCgpKTsKKwlCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYnVmID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbShtYXhCeXRlc1BlckNoYXIpOworCU91dHB1dFN0cmVhbVdyaXRlciB3cml0ZXIgPSBuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKGJ1Zik7CisKKwlmb3IgKGludCBpID0gMDsgaSA8IHMubGVuZ3RoKCk7IGkrKykgeworCSAgICBpbnQgYyA9IChpbnQpcy5jaGFyQXQoaSk7CisJICAgIGlmIChkb250TmVlZEVuY29kaW5nLmdldChjKSkgeworCQlpZiAoYyA9PSAnICcpIHsKKwkJICAgIGMgPSAnKyc7CisJCX0KKwkJb3V0LmFwcGVuZCgoY2hhciljKTsKKwkgICAgfSBlbHNlIHsKKwkJLy8gY29udmVydCB0byBleHRlcm5hbCBlbmNvZGluZyBiZWZvcmUgaGV4IGNvbnZlcnNpb24KKwkJdHJ5IHsKKwkJICAgIHdyaXRlci53cml0ZShjKTsKKwkJICAgIHdyaXRlci5mbHVzaCgpOworCQl9IGNhdGNoKElPRXhjZXB0aW9uIGUpIHsKKwkJICAgIGJ1Zi5yZXNldCgpOworCQkgICAgY29udGludWU7CisJCX0KKwkJYnl0ZVtdIGJhID0gYnVmLnRvQnl0ZUFycmF5KCk7CisJCWZvciAoaW50IGogPSAwOyBqIDwgYmEubGVuZ3RoOyBqKyspIHsKKwkJICAgIG91dC5hcHBlbmQoJyUnKTsKKwkJICAgIGNoYXIgY2ggPSBDaGFyYWN0ZXIuZm9yRGlnaXQoKGJhW2pdID4+IDQpICYgMHhGLCAxNik7CisJCSAgICAvLyBjb252ZXJ0aW5nIHRvIHVzZSB1cHBlcmNhc2UgbGV0dGVyIGFzIHBhcnQgb2YKKwkJICAgIC8vIHRoZSBoZXggdmFsdWUgaWYgY2ggaXMgYSBsZXR0ZXIuCisJCSAgICBpZiAoQ2hhcmFjdGVyLmlzTGV0dGVyKGNoKSkgeworCQkJY2ggLT0gY2FzZURpZmY7CisJCSAgICB9CisJCSAgICBvdXQuYXBwZW5kKGNoKTsKKwkJICAgIGNoID0gQ2hhcmFjdGVyLmZvckRpZ2l0KGJhW2pdICYgMHhGLCAxNik7CisJCSAgICBpZiAoQ2hhcmFjdGVyLmlzTGV0dGVyKGNoKSkgeworCQkJY2ggLT0gY2FzZURpZmY7CisJCSAgICB9CisJCSAgICBvdXQuYXBwZW5kKGNoKTsKKwkJfQorCQlidWYucmVzZXQoKTsKKwkgICAgfQorCX0KKworCXJldHVybiBvdXQudG9TdHJpbmcoKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFRoZSBjbGFzcyBjb250YWlucyBhIHV0aWxpdHkgbWV0aG9kIGZvciBjb252ZXJ0aW5nIGZyb20KKyAgICAgKiBhIE1JTUUgZm9ybWF0IGNhbGxlZCAiPGNvZGU+eC13d3ctZm9ybS11cmxlbmNvZGVkPC9jb2RlPiIKKyAgICAgKiB0byBhIDxjb2RlPlN0cmluZzwvY29kZT4KKyAgICAgKiA8cD4KKyAgICAgKiBUbyBjb252ZXJ0IHRvIGEgPGNvZGU+U3RyaW5nPC9jb2RlPiwgZWFjaCBjaGFyYWN0ZXIgaXMgZXhhbWluZWQgaW4gdHVybjoKKyAgICAgKiA8dWw+CisgICAgICogPGxpPlRoZSBBU0NJSSBjaGFyYWN0ZXJzICc8Y29kZT5hPC9jb2RlPicgdGhyb3VnaCAnPGNvZGU+ejwvY29kZT4nLAorICAgICAqICc8Y29kZT5BPC9jb2RlPicgdGhyb3VnaCAnPGNvZGU+WjwvY29kZT4nLCBhbmQgJzxjb2RlPjA8L2NvZGU+JworICAgICAqIHRocm91Z2ggJzxjb2RlPjk8L2NvZGU+JyByZW1haW4gdGhlIHNhbWUuCisgICAgICogPGxpPlRoZSBwbHVzIHNpZ24gJzxjb2RlPis8L2NvZGU+J2lzIGNvbnZlcnRlZCBpbnRvIGEKKyAgICAgKiBzcGFjZSBjaGFyYWN0ZXIgJzxjb2RlPiZuYnNwOzwvY29kZT4nLgorICAgICAqIDxsaT5UaGUgcmVtYWluaW5nIGNoYXJhY3RlcnMgYXJlIHJlcHJlc2VudGVkIGJ5IDMtY2hhcmFjdGVyCisgICAgICogc3RyaW5ncyB3aGljaCBiZWdpbiB3aXRoIHRoZSBwZXJjZW50IHNpZ24sCisgICAgICogIjxjb2RlPiU8aT54eTwvaT48L2NvZGU+Iiwgd2hlcmUgPGk+eHk8L2k+IGlzIHRoZSB0d28tZGlnaXQKKyAgICAgKiBoZXhhZGVjaW1hbCByZXByZXNlbnRhdGlvbiBvZiB0aGUgbG93ZXIgOC1iaXRzIG9mIHRoZSBjaGFyYWN0ZXIuCisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBhdXRob3IgIE1hcmsgQ2hhbW5lc3MKKyAgICAgKiBAYXV0aG9yICBNaWNoYWVsIE1jQ2xvc2tleQorICAgICAqIEBzaW5jZSAgIDEuMgorICAgICAqLworCisgICAgLyoqCisgICAgICogRGVjb2RlcyBhICZxdW90O3gtd3d3LWZvcm0tdXJsZW5jb2RlZCZxdW90OyAKKyAgICAgKiB0byBhIDx0dD5TdHJpbmc8L3R0Pi4KKyAgICAgKiBAcGFyYW0gcyB0aGUgPGNvZGU+U3RyaW5nPC9jb2RlPiB0byBkZWNvZGUKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXdseSBkZWNvZGVkIDxjb2RlPlN0cmluZzwvY29kZT4KKyAgICAgKi8KKyAgICBzdGF0aWMgU3RyaW5nIGRlY29kZShTdHJpbmcgcykgeworCWlmIChzID09IG51bGwpCisJICAgIHJldHVybiBudWxsOworCWlmIChpbmRleE9mQW55KHMsICIrJSIpID09IC0xKQorCSAgICByZXR1cm4gczsJCS8vIHRoZSBjb21tb24gY2FzZQorCisgICAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHMubGVuZ3RoKCk7IGkrKykgeworICAgICAgICAgICAgY2hhciBjID0gcy5jaGFyQXQoaSk7CisgICAgICAgICAgICBzd2l0Y2ggKGMpIHsKKyAgICAgICAgICAgICAgICBjYXNlICcrJzoKKyAgICAgICAgICAgICAgICAgICAgc2IuYXBwZW5kKCcgJyk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgJyUnOgorICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgc2IuYXBwZW5kKChjaGFyKUludGVnZXIucGFyc2VJbnQoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcy5zdWJzdHJpbmcoaSsxLGkrMyksMTYpKTsKKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisJCQkgICAgIklsbGVnYWwgVVJMIGVuY29kZWQgdmFsdWU6ICIgKworCQkJICAgIHMuc3Vic3RyaW5nKGksaSszKSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaSArPSAyOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQoYyk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIC8vIFVuZG8gY29udmVyc2lvbiB0byBleHRlcm5hbCBlbmNvZGluZworICAgICAgICBTdHJpbmcgcmVzdWx0ID0gc2IudG9TdHJpbmcoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJ5dGVbXSBpbnB1dEJ5dGVzID0gcmVzdWx0LmdldEJ5dGVzKCI4ODU5XzEiKTsKKyAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBTdHJpbmcoaW5wdXRCeXRlcyk7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gVGhlIHN5c3RlbSBzaG91bGQgYWx3YXlzIGhhdmUgODg1OV8xCisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIGZpcnN0IGluZGV4IG9mIGFueSBvZiB0aGUgY2hhcmFjdGVycyBpbiAiYW55IiBpbiAicyIsCisgICAgICogb3IgLTEgaWYgbm9uZSBhcmUgZm91bmQuCisgICAgICoKKyAgICAgKiBUaGlzIHNob3VsZCBiZSBhIG1ldGhvZCBvbiBTdHJpbmcuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IGluZGV4T2ZBbnkoU3RyaW5nIHMsIFN0cmluZyBhbnkpIHsKKwlyZXR1cm4gaW5kZXhPZkFueShzLCBhbnksIDApOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGludCBpbmRleE9mQW55KFN0cmluZyBzLCBTdHJpbmcgYW55LCBpbnQgc3RhcnQpIHsKKwl0cnkgeworCSAgICBpbnQgbGVuID0gcy5sZW5ndGgoKTsKKwkgICAgZm9yIChpbnQgaSA9IHN0YXJ0OyBpIDwgbGVuOyBpKyspIHsKKwkJaWYgKGFueS5pbmRleE9mKHMuY2hhckF0KGkpKSA+PSAwKQorCQkgICAgcmV0dXJuIGk7CisJICAgIH0KKwkgICAgcmV0dXJuIC0xOworCX0gY2F0Y2ggKFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworCSAgICByZXR1cm4gLTE7CisJfQorICAgIH0KKworICAgIC8qCisgICAgLy8gRG8gbm90IHJlbW92ZSwgdGhpcyBpcyBuZWVkZWQgd2hlbiB0ZXN0aW5nIG5ldyBVUkwgY2FzZXMKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmd2KSB7CisJU3RyaW5nIFtdIHRlc3RVUkxOYW1lcyA9IHsKKwkgICAgInByb3RvY29sOi8vdXNlcmlkOnBhc3N3b3JkQGhvc3Q6MTE5L2ZpbGUiLAorCSAgICAiaHR0cDovL2Z1bm55L2ZvbGRlci9maWxlLmh0bWwiLAorCSAgICAiaHR0cDovL2Z1bm55L2ZvbGRlci9maWxlLmh0bWwjcmVmIiwKKwkgICAgImh0dHA6Ly9mdW5ueS9mb2xkZXIvZmlsZS5odG1sIyIsCisJICAgICJodHRwOi8vZnVubnkvI3JlZiIsCisJICAgICJpbWFwOi8vam1yOnNlY3JldEBsYWJ5cmludGgvL3Zhci9tYWlsL2ptciIsCisJICAgICJubnRwOi8vZnJlZEBsYWJ5cmludGg6MTQzL3NhdmUvaXQvbm93Lm1ib3giLAorCSAgICAiaW1hcDovL2ptckBsYWJ5cmludGgvSU5CT1giLAorCSAgICAiaW1hcDovL2xhYnJ5cmludGgiLAorCSAgICAiaW1hcDovL2xhYnJ5cmludGgvIiwKKwkgICAgImZpbGU6IiwKKwkgICAgImZpbGU6SU5CT1giLAorCSAgICAiZmlsZTovaG9tZS9zaGFubm9uL21haWwvZm9vIiwKKwkgICAgIi90bXAvZm9vIiwKKwkgICAgIi8vaG9zdC90bXAvZm9vIiwKKwkgICAgIjovdG1wL2ZvbyIsCisJICAgICIvcmVhbGx5L3dlaXJkOi90bXAvZm9vI2JhciIsCisJICAgICIiCisJfTsKKworCVVSTE5hbWUgdXJsID0KKwkgICAgbmV3IFVSTE5hbWUoInByb3RvY29sIiwgImhvc3QiLCAxMTksICJmaWxlIiwgInVzZXJpZCIsICJwYXNzd29yZCIpOworCVN5c3RlbS5vdXQucHJpbnRsbigiVGVzdCBVUkw6ICIgKyB1cmwudG9TdHJpbmcoKSk7CisJaWYgKGFyZ3YubGVuZ3RoID09IDApIHsKKwkgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0ZXN0VVJMTmFtZXMubGVuZ3RoOyBpKyspIHsKKwkJcHJpbnQodGVzdFVSTE5hbWVzW2ldKTsKKwkJU3lzdGVtLm91dC5wcmludGxuKCk7CisJICAgIH0KKwl9IGVsc2UgeworCSAgICBmb3IgKGludCBpID0gMDsgaSA8IGFyZ3YubGVuZ3RoOyBpKyspIHsKKwkJcHJpbnQoYXJndltpXSk7CisJCVN5c3RlbS5vdXQucHJpbnRsbigpOworCSAgICB9CisJICAgIGlmIChhcmd2Lmxlbmd0aCA9PSAyKSB7CisJCVVSTE5hbWUgdTEgPSBuZXcgVVJMTmFtZShhcmd2WzBdKTsKKwkJVVJMTmFtZSB1MiA9IG5ldyBVUkxOYW1lKGFyZ3ZbMV0pOworCQlTeXN0ZW0ub3V0LnByaW50bG4oIlVSTDEgaGFzaCBjb2RlOiAiICsgdTEuaGFzaENvZGUoKSk7CisJCVN5c3RlbS5vdXQucHJpbnRsbigiVVJMMiBoYXNoIGNvZGU6ICIgKyB1Mi5oYXNoQ29kZSgpKTsKKwkJaWYgKHUxLmVxdWFscyh1MikpCisJCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oInN1Y2Nlc3MsIGVxdWFsIik7CisJCWVsc2UKKwkJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZmFpbCwgbm90IGVxdWFsIik7CisJCWlmICh1Mi5lcXVhbHModTEpKQorCQkgICAgU3lzdGVtLm91dC5wcmludGxuKCJzdWNjZXNzLCBlcXVhbCIpOworCQllbHNlCisJCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oImZhaWwsIG5vdCBlcXVhbCIpOworCQlpZiAodTEuaGFzaENvZGUoKSA9PSB1Mi5oYXNoQ29kZSgpKQorCQkgICAgU3lzdGVtLm91dC5wcmludGxuKCJzdWNjZXNzLCBoYXNoQ29kZXMgZXF1YWwiKTsKKwkJZWxzZQorCQkgICAgU3lzdGVtLm91dC5wcmludGxuKCJmYWlsLCBoYXNoQ29kZXMgbm90IGVxdWFsIik7CisJICAgIH0KKwl9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBwcmludChTdHJpbmcgbmFtZSkgeworCVVSTE5hbWUgdXJsID0gbmV3IFVSTE5hbWUobmFtZSk7CisJU3lzdGVtLm91dC5wcmludGxuKCJPcmlnaW5hbCBVUkw6ICIgKyBuYW1lKTsKKwlTeXN0ZW0ub3V0LnByaW50bG4oIlRoZSBmdWxsVXJsIDogIiArIHVybC50b1N0cmluZygpKTsKKwlpZiAoIW5hbWUuZXF1YWxzKHVybC50b1N0cmluZygpKSkKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCIgICAgICAgICAgICA6IE5PVCBFUVVBTCEiKTsKKwlTeXN0ZW0ub3V0LnByaW50bG4oIlRoZSBwcm90b2NvbCBpczogIiArIHVybC5nZXRQcm90b2NvbCgpKTsKKwlTeXN0ZW0ub3V0LnByaW50bG4oIlRoZSBob3N0IGlzOiAiICsgdXJsLmdldEhvc3QoKSk7CisJU3lzdGVtLm91dC5wcmludGxuKCJUaGUgcG9ydCBpczogIiArIHVybC5nZXRQb3J0KCkpOworCVN5c3RlbS5vdXQucHJpbnRsbigiVGhlIHVzZXIgaXM6ICIgKyB1cmwuZ2V0VXNlcm5hbWUoKSk7CisJU3lzdGVtLm91dC5wcmludGxuKCJUaGUgcGFzc3dvcmQgaXM6ICIgKyB1cmwuZ2V0UGFzc3dvcmQoKSk7CisJU3lzdGVtLm91dC5wcmludGxuKCJUaGUgZmlsZSBpczogIiArIHVybC5nZXRGaWxlKCkpOworCVN5c3RlbS5vdXQucHJpbnRsbigiVGhlIHJlZiBpczogIiArIHVybC5nZXRSZWYoKSk7CisgICAgfQorICAgICovCit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9ldmVudC9Db25uZWN0aW9uQWRhcHRlci5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvZXZlbnQvQ29ubmVjdGlvbkFkYXB0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMDdlMTUxCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvZXZlbnQvQ29ubmVjdGlvbkFkYXB0ZXIuamF2YQpAQCAtMCwwICsxLDM0IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGphdmF4Lm1haWwuZXZlbnQ7CisKKy8qKgorICogVGhlIGFkYXB0ZXIgd2hpY2ggcmVjZWl2ZXMgY29ubmVjdGlvbiBldmVudHMuCisgKiBUaGUgbWV0aG9kcyBpbiB0aGlzIGNsYXNzIGFyZSBlbXB0eTsgIHRoaXMgY2xhc3MgaXMgcHJvdmlkZWQgYXMgYQorICogY29udmVuaWVuY2UgZm9yIGVhc2lseSBjcmVhdGluZyBsaXN0ZW5lcnMgYnkgZXh0ZW5kaW5nIHRoaXMgY2xhc3MKKyAqIGFuZCBvdmVycmlkaW5nIG9ubHkgdGhlIG1ldGhvZHMgb2YgaW50ZXJlc3QuCisgKgorICogQGF1dGhvciBKb2huIE1hbmkKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIENvbm5lY3Rpb25BZGFwdGVyIGltcGxlbWVudHMgQ29ubmVjdGlvbkxpc3RlbmVyIHsKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBvcGVuZWQoQ29ubmVjdGlvbkV2ZW50IGUpIHt9CisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZGlzY29ubmVjdGVkKENvbm5lY3Rpb25FdmVudCBlKSB7fQorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlZChDb25uZWN0aW9uRXZlbnQgZSkge30KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2V2ZW50L0Nvbm5lY3Rpb25FdmVudC5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvZXZlbnQvQ29ubmVjdGlvbkV2ZW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzg5YTAwMwotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2V2ZW50L0Nvbm5lY3Rpb25FdmVudC5qYXZhCkBAIC0wLDAgKzEsNzcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5ldmVudDsKKworaW1wb3J0IGphdmEudXRpbC4qOworaW1wb3J0IGphdmF4Lm1haWwuKjsKKworLyoqCisgKiBUaGlzIGNsYXNzIG1vZGVscyBDb25uZWN0aW9uIGV2ZW50cy4KKyAqCisgKiBAYXV0aG9yIEpvaG4gTWFuaQorICovCisKK3B1YmxpYyBjbGFzcyBDb25uZWN0aW9uRXZlbnQgZXh0ZW5kcyBNYWlsRXZlbnQgIHsKKworICAgIC8qKiBBIGNvbm5lY3Rpb24gd2FzIG9wZW5lZC4gKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUEVORUQgCQk9IDE7CisgICAgLyoqIEEgY29ubmVjdGlvbiB3YXMgZGlzY29ubmVjdGVkIChub3QgY3VycmVudGx5IHVzZWQpLiAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERJU0NPTk5FQ1RFRCAJPSAyOworICAgIC8qKiBBIGNvbm5lY3Rpb24gd2FzIGNsb3NlZC4gKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDTE9TRUQgCQk9IDM7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZXZlbnQgdHlwZS4KKyAgICAgKgorICAgICAqIEBzZXJpYWwKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IHR5cGU7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMTg1NTQ4MDE3MTI4NDc5Mjk1N0w7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYSBDb25uZWN0aW9uRXZlbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jc291cmNlICBUaGUgc291cmNlIG9iamVjdAorICAgICAqIEBwYXJhbQl0eXBlCXRoZSBldmVudCB0eXBlCisgICAgICovCisgICAgcHVibGljIENvbm5lY3Rpb25FdmVudChPYmplY3Qgc291cmNlLCBpbnQgdHlwZSkgeworCXN1cGVyKHNvdXJjZSk7CisJdGhpcy50eXBlID0gdHlwZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIHR5cGUgb2YgdGhpcyBldmVudAorICAgICAqIEByZXR1cm4gIHR5cGUKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFR5cGUoKSB7CisJcmV0dXJuIHR5cGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW52b2tlcyB0aGUgYXBwcm9wcmlhdGUgQ29ubmVjdGlvbkxpc3RlbmVyIG1ldGhvZAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGRpc3BhdGNoKE9iamVjdCBsaXN0ZW5lcikgeworCWlmICh0eXBlID09IE9QRU5FRCkKKwkgICAgKChDb25uZWN0aW9uTGlzdGVuZXIpbGlzdGVuZXIpLm9wZW5lZCh0aGlzKTsKKwllbHNlIGlmICh0eXBlID09IERJU0NPTk5FQ1RFRCkKKwkgICAgKChDb25uZWN0aW9uTGlzdGVuZXIpbGlzdGVuZXIpLmRpc2Nvbm5lY3RlZCh0aGlzKTsKKwllbHNlIGlmICh0eXBlID09IENMT1NFRCkKKwkgICAgKChDb25uZWN0aW9uTGlzdGVuZXIpbGlzdGVuZXIpLmNsb3NlZCh0aGlzKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9ldmVudC9Db25uZWN0aW9uTGlzdGVuZXIuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2V2ZW50L0Nvbm5lY3Rpb25MaXN0ZW5lci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY0NzIxZGYKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9ldmVudC9Db25uZWN0aW9uTGlzdGVuZXIuamF2YQpAQCAtMCwwICsxLDUwIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGphdmF4Lm1haWwuZXZlbnQ7CisKK2ltcG9ydCBqYXZhLnV0aWwuKjsKKworLyoqCisgKiBUaGlzIGlzIHRoZSBMaXN0ZW5lciBpbnRlcmZhY2UgZm9yIENvbm5lY3Rpb24gZXZlbnRzLgorICoKKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKi8KKworcHVibGljIGludGVyZmFjZSBDb25uZWN0aW9uTGlzdGVuZXIgZXh0ZW5kcyBqYXZhLnV0aWwuRXZlbnRMaXN0ZW5lciB7CisKKyAgICAvKioKKyAgICAgKiBJbnZva2VkIHdoZW4gYSBTdG9yZS9Gb2xkZXIvVHJhbnNwb3J0IGlzIG9wZW5lZC4KKyAgICAgKgorICAgICAqIEBwYXJhbQllCXRoZSBDb25uZWN0aW9uRXZlbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBvcGVuZWQoQ29ubmVjdGlvbkV2ZW50IGUpOworCisgICAgLyoqCisgICAgICogSW52b2tlZCB3aGVuIGEgU3RvcmUgaXMgZGlzY29ubmVjdGVkLiBOb3RlIHRoYXQgYSBmb2xkZXIKKyAgICAgKiBjYW5ub3QgYmUgZGlzY29ubmVjdGVkLCBzbyBhIGZvbGRlciB3aWxsIG5vdCBmaXJlIHRoaXMgZXZlbnQKKyAgICAgKgorICAgICAqIEBwYXJhbQllCXRoZSBDb25uZWN0aW9uRXZlbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBkaXNjb25uZWN0ZWQoQ29ubmVjdGlvbkV2ZW50IGUpOworCisgICAgLyoqCisgICAgICogSW52b2tlZCB3aGVuIGEgU3RvcmUvRm9sZGVyL1RyYW5zcG9ydCBpcyBjbG9zZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0JZQl0aGUgQ29ubmVjdGlvbkV2ZW50CisgICAgICovCisgICAgcHVibGljIHZvaWQgY2xvc2VkKENvbm5lY3Rpb25FdmVudCBlKTsKK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2V2ZW50L0ZvbGRlckFkYXB0ZXIuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2V2ZW50L0ZvbGRlckFkYXB0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YmRkMDA5Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvZXZlbnQvRm9sZGVyQWRhcHRlci5qYXZhCkBAIC0wLDAgKzEsMzQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5ldmVudDsKKworLyoqCisgKiBUaGUgYWRhcHRlciB3aGljaCByZWNlaXZlcyBGb2xkZXIgZXZlbnRzLgorICogVGhlIG1ldGhvZHMgaW4gdGhpcyBjbGFzcyBhcmUgZW1wdHk7ICB0aGlzIGNsYXNzIGlzIHByb3ZpZGVkIGFzIGEKKyAqIGNvbnZlbmllbmNlIGZvciBlYXNpbHkgY3JlYXRpbmcgbGlzdGVuZXJzIGJ5IGV4dGVuZGluZyB0aGlzIGNsYXNzCisgKiBhbmQgb3ZlcnJpZGluZyBvbmx5IHRoZSBtZXRob2RzIG9mIGludGVyZXN0LgorICoKKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBGb2xkZXJBZGFwdGVyIGltcGxlbWVudHMgRm9sZGVyTGlzdGVuZXIgeworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGZvbGRlckNyZWF0ZWQoRm9sZGVyRXZlbnQgZSkge30KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBmb2xkZXJSZW5hbWVkKEZvbGRlckV2ZW50IGUpIHt9CisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZm9sZGVyRGVsZXRlZChGb2xkZXJFdmVudCBlKSB7fQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvZXZlbnQvRm9sZGVyRXZlbnQuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2V2ZW50L0ZvbGRlckV2ZW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGM4OWFlNgotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2V2ZW50L0ZvbGRlckV2ZW50LmphdmEKQEAgLTAsMCArMSwxNDQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5ldmVudDsKKworaW1wb3J0IGphdmEudXRpbC4qOworaW1wb3J0IGphdmF4Lm1haWwuKjsKKworLyoqCisgKiBUaGlzIGNsYXNzIG1vZGVscyBGb2xkZXIgPGVtPmV4aXN0ZW5jZTwvZW0+IGV2ZW50cy4gRm9sZGVyRXZlbnRzIGFyZQorICogZGVsaXZlcmVkIHRvIEZvbGRlckxpc3RlbmVycyByZWdpc3RlcmVkIG9uIHRoZSBhZmZlY3RlZCBGb2xkZXIgYXMKKyAqIHdlbGwgYXMgdGhlIGNvbnRhaW5pbmcgU3RvcmUuIDxwPgorICoKKyAqIFNlcnZpY2UgcHJvdmlkZXJzIHZhcnkgd2lkZWx5IGluIHRoZWlyIGFiaWxpdHkgdG8gbm90aWZ5IGNsaWVudHMgb2YKKyAqIHRoZXNlIGV2ZW50cy4gIEF0IGEgbWluaW11bSwgc2VydmljZSBwcm92aWRlcnMgbXVzdCBub3RpZnkgbGlzdGVuZXJzCisgKiByZWdpc3RlcmVkIG9uIHRoZSBzYW1lIFN0b3JlIG9yIEZvbGRlciBvYmplY3Qgb24gd2hpY2ggdGhlIG9wZXJhdGlvbgorICogb2NjdXJzLiAgU2VydmljZSBwcm92aWRlcnMgbWF5IGFsc28gbm90aWZ5IGxpc3RlbmVycyB3aGVuIGNoYW5nZXMKKyAqIGFyZSBtYWRlIHRocm91Z2ggb3BlcmF0aW9ucyBvbiBvdGhlciBvYmplY3RzIGluIHRoZSBzYW1lIHZpcnR1YWwKKyAqIG1hY2hpbmUsIG9yIGJ5IG90aGVyIGNsaWVudHMgaW4gdGhlIHNhbWUgb3Igb3RoZXIgaG9zdHMuICBTdWNoCisgKiBub3RpZmljYXRpb25zIGFyZSBub3QgcmVxdWlyZWQgYW5kIGFyZSB0eXBpY2FsbHkgbm90IHN1cHBvcnRlZAorICogYnkgbWFpbCBwcm90b2NvbHMgKGluY2x1ZGluZyBJTUFQKS4KKyAqCisgKiBAYXV0aG9yIEpvaG4gTWFuaQorICogQGF1dGhvciBCaWxsIFNoYW5ub24KKyAqLworCitwdWJsaWMgY2xhc3MgRm9sZGVyRXZlbnQgZXh0ZW5kcyBNYWlsRXZlbnQgeworCisgICAgLyoqIFRoZSBmb2xkZXIgd2FzIGNyZWF0ZWQuICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ1JFQVRFRCAJCT0gMTsKKyAgICAvKiogVGhlIGZvbGRlciB3YXMgZGVsZXRlZC4gKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUxFVEVEIAkJPSAyOworICAgIC8qKiBUaGUgZm9sZGVyIHdhcyByZW5hbWVkLiAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFTkFNRUQgCQk9IDM7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZXZlbnQgdHlwZS4KKyAgICAgKgorICAgICAqIEBzZXJpYWwKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IHR5cGU7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZm9sZGVyIHRoZSBldmVudCBvY2N1cnJlZCBvbi4KKyAgICAgKi8KKyAgICB0cmFuc2llbnQgcHJvdGVjdGVkIEZvbGRlciBmb2xkZXI7CisKKyAgICAvKioKKyAgICAgKiBUaGUgZm9sZGVyIHRoYXQgcmVwcmVzZW50cyB0aGUgbmV3IG5hbWUsIGluIGNhc2Ugb2YgYSBSRU5BTUVEIGV2ZW50LgorICAgICAqCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuMQorICAgICAqLworICAgIHRyYW5zaWVudCBwcm90ZWN0ZWQgRm9sZGVyIG5ld0ZvbGRlcjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDUyNzgxMzEzMTA1NjM2OTQzMDdMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IuIDxwPgorICAgICAqCisgICAgICogQHBhcmFtIHNvdXJjZSAgCVRoZSBzb3VyY2Ugb2YgdGhlIGV2ZW50CisgICAgICogQHBhcmFtIGZvbGRlcglUaGUgYWZmZWN0ZWQgZm9sZGVyCisgICAgICogQHBhcmFtIHR5cGUJVGhlIGV2ZW50IHR5cGUKKyAgICAgKi8KKyAgICBwdWJsaWMgRm9sZGVyRXZlbnQoT2JqZWN0IHNvdXJjZSwgRm9sZGVyIGZvbGRlciwgaW50IHR5cGUpIHsKKwl0aGlzKHNvdXJjZSwgZm9sZGVyLCBmb2xkZXIsIHR5cGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yLiBVc2UgZm9yIFJFTkFNRUQgZXZlbnRzLgorICAgICAqCisgICAgICogQHBhcmFtIHNvdXJjZSAgCVRoZSBzb3VyY2Ugb2YgdGhlIGV2ZW50CisgICAgICogQHBhcmFtIG9sZEZvbGRlcglUaGUgZm9sZGVyIHRoYXQgaXMgcmVuYW1lZAorICAgICAqIEBwYXJhbSBuZXdGb2xkZXIJVGhlIGZvbGRlciB0aGF0IHJlcHJlc2VudHMgdGhlIG5ldyBuYW1lCisgICAgICogQHBhcmFtIHR5cGUJVGhlIGV2ZW50IHR5cGUKKyAgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuMQorICAgICAqLworICAgIHB1YmxpYyBGb2xkZXJFdmVudChPYmplY3Qgc291cmNlLCBGb2xkZXIgb2xkRm9sZGVyLCAKKwkJICAgICAgIEZvbGRlciBuZXdGb2xkZXIsIGludCB0eXBlKSB7CisJc3VwZXIoc291cmNlKTsKKwl0aGlzLmZvbGRlciA9IG9sZEZvbGRlcjsKKwl0aGlzLm5ld0ZvbGRlciA9IG5ld0ZvbGRlcjsKKwl0aGlzLnR5cGUgPSB0eXBlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgdHlwZSBvZiB0aGlzIGV2ZW50LgorICAgICAqCisgICAgICogQHJldHVybiAgdHlwZQorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0VHlwZSgpIHsKKwlyZXR1cm4gdHlwZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIGFmZmVjdGVkIGZvbGRlci4KKyAgICAgKgorICAgICAqIEByZXR1cm4gCQl0aGUgYWZmZWN0ZWQgZm9sZGVyCisgICAgICogQHNlZSAJCSNnZXROZXdGb2xkZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgRm9sZGVyIGdldEZvbGRlcigpIHsKKwlyZXR1cm4gZm9sZGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIElmIHRoaXMgZXZlbnQgaW5kaWNhdGVzIHRoYXQgYSBmb2xkZXIgaXMgcmVuYW1lZCwgKGkuZSwgdGhlIGV2ZW50IHR5cGUKKyAgICAgKiBpcyBSRU5BTUVEKSwgdGhlbiB0aGlzIG1ldGhvZCByZXR1cm5zIHRoZSBGb2xkZXIgb2JqZWN0IHJlcHJlc2VudGluZyB0aGUKKyAgICAgKiBuZXcgbmFtZS4gPHA+CisgICAgICoKKyAgICAgKiBUaGUgPGNvZGU+Z2V0Rm9sZGVyKCk8L2NvZGU+IG1ldGhvZCByZXR1cm5zIHRoZSBmb2xkZXIgdGhhdCBpcyByZW5hbWVkLgorICAgICAqCisgICAgICogQHJldHVybgkJRm9sZGVyIHJlcHJlc2VudGluZyB0aGUgbmV3IG5hbWUuCisgICAgICogQHNlZQkJI2dldEZvbGRlcgorICAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS4xCisgICAgICovCisgICAgcHVibGljIEZvbGRlciBnZXROZXdGb2xkZXIoKSB7CisJcmV0dXJuIG5ld0ZvbGRlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnZva2VzIHRoZSBhcHByb3ByaWF0ZSBGb2xkZXJMaXN0ZW5lciBtZXRob2QKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBkaXNwYXRjaChPYmplY3QgbGlzdGVuZXIpIHsKKwlpZiAodHlwZSA9PSBDUkVBVEVEKQorCSAgICAoKEZvbGRlckxpc3RlbmVyKWxpc3RlbmVyKS5mb2xkZXJDcmVhdGVkKHRoaXMpOworCWVsc2UgaWYgKHR5cGUgPT0gREVMRVRFRCkKKwkgICAgKChGb2xkZXJMaXN0ZW5lcilsaXN0ZW5lcikuZm9sZGVyRGVsZXRlZCh0aGlzKTsKKwllbHNlIGlmICh0eXBlID09IFJFTkFNRUQpCisJICAgICgoRm9sZGVyTGlzdGVuZXIpbGlzdGVuZXIpLmZvbGRlclJlbmFtZWQodGhpcyk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvZXZlbnQvRm9sZGVyTGlzdGVuZXIuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2V2ZW50L0ZvbGRlckxpc3RlbmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWM2NTJhMwotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2V2ZW50L0ZvbGRlckxpc3RlbmVyLmphdmEKQEAgLTAsMCArMSw0OCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsLmV2ZW50OworCitpbXBvcnQgamF2YS51dGlsLio7CisKKy8qKgorICogVGhpcyBpcyB0aGUgTGlzdGVuZXIgaW50ZXJmYWNlIGZvciBGb2xkZXIgZXZlbnRzLgorICoKKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKi8KKworcHVibGljIGludGVyZmFjZSBGb2xkZXJMaXN0ZW5lciBleHRlbmRzIGphdmEudXRpbC5FdmVudExpc3RlbmVyIHsKKyAgICAvKioKKyAgICAgKiBJbnZva2VkIHdoZW4gYSBGb2xkZXIgaXMgY3JlYXRlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbQllCXRoZSBGb2xkZXJFdmVudAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGZvbGRlckNyZWF0ZWQoRm9sZGVyRXZlbnQgZSk7CisKKyAgICAvKioKKyAgICAgKiBJbnZva2VkIHdoZW4gYSBmb2xkZXIgaXMgZGVsZXRlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbQllCXRoZSBGb2xkZXJFdmVudAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGZvbGRlckRlbGV0ZWQoRm9sZGVyRXZlbnQgZSk7CisKKyAgICAvKioKKyAgICAgKiBJbnZva2VkIHdoZW4gYSBmb2xkZXIgaXMgcmVuYW1lZC4KKyAgICAgKgorICAgICAqIEBwYXJhbQllCXRoZSBGb2xkZXJFdmVudAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGZvbGRlclJlbmFtZWQoRm9sZGVyRXZlbnQgZSk7Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9ldmVudC9NYWlsRXZlbnQuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2V2ZW50L01haWxFdmVudC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk3ZTQxOTEKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9ldmVudC9NYWlsRXZlbnQuamF2YQpAQCAtMCwwICsxLDQ2IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGphdmF4Lm1haWwuZXZlbnQ7CisKK2ltcG9ydCBqYXZhLnV0aWwuRXZlbnRPYmplY3Q7CisKKy8qKgorICogQ29tbW9uIGJhc2UgY2xhc3MgZm9yIG1haWwgZXZlbnRzLCBkZWZpbmluZyB0aGUgZGlzcGF0Y2ggbWV0aG9kLgorICoKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKi8KKworcHVibGljIGFic3RyYWN0IGNsYXNzIE1haWxFdmVudCBleHRlbmRzIEV2ZW50T2JqZWN0IHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxODQ2Mjc1NjM2MzI1NDU2NjMxTDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCBhIE1haWxFdmVudCByZWZlcnJpbmcgdG8gdGhlIGdpdmVuIHNvdXJjZS4KKyAgICAgKgorICAgICAqIEBwYXJhbQlzb3VyY2UJdGhlIHNvdXJjZSBvZiB0aGUgZXZlbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgTWFpbEV2ZW50KE9iamVjdCBzb3VyY2UpIHsKKyAgICAgICAgc3VwZXIoc291cmNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBpbnZva2VzIHRoZSBhcHByb3ByaWF0ZSBtZXRob2Qgb24gYSBsaXN0ZW5lciBmb3IKKyAgICAgKiB0aGlzIGV2ZW50LiBTdWJjbGFzc2VzIHByb3ZpZGUgdGhlIGltcGxlbWVudGF0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtCWxpc3RlbmVyCXRoZSBsaXN0ZW5lciB0byBpbnZva2Ugb24KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBkaXNwYXRjaChPYmplY3QgbGlzdGVuZXIpOworfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvZXZlbnQvTWVzc2FnZUNoYW5nZWRFdmVudC5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvZXZlbnQvTWVzc2FnZUNoYW5nZWRFdmVudC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAwOTk1OTIKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9ldmVudC9NZXNzYWdlQ2hhbmdlZEV2ZW50LmphdmEKQEAgLTAsMCArMSw4NCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsLmV2ZW50OworCitpbXBvcnQgamF2YS51dGlsLio7CitpbXBvcnQgamF2YXgubWFpbC4qOworCisvKioKKyAqIFRoaXMgY2xhc3MgbW9kZWxzIE1lc3NhZ2UgY2hhbmdlIGV2ZW50cy4KKyAqCisgKiBAYXV0aG9yIEpvaG4gTWFuaQorICovCisKK3B1YmxpYyBjbGFzcyBNZXNzYWdlQ2hhbmdlZEV2ZW50IGV4dGVuZHMgTWFpbEV2ZW50IHsKKworICAgIC8qKiBUaGUgbWVzc2FnZSdzIGZsYWdzIGNoYW5nZWQuICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRkxBR1NfQ0hBTkdFRCAJPSAxOworICAgIC8qKiBUaGUgbWVzc2FnZSdzIGVudmVsb3BlIChoZWFkZXJzLCBidXQgbm90IGJvZHkpIGNoYW5nZWQuICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5WRUxPUEVfQ0hBTkdFRCAJPSAyOworCisgICAgLyoqCisgICAgICogVGhlIGV2ZW50IHR5cGUuCisgICAgICoKKyAgICAgKiBAc2VyaWFsCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCB0eXBlOworCisgICAgLyoqCisgICAgICogVGhlIG1lc3NhZ2UgdGhhdCBjaGFuZ2VkLgorICAgICAqLworICAgIHRyYW5zaWVudCBwcm90ZWN0ZWQgTWVzc2FnZSBtc2c7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNDk3NDk3Mjk3MjEwNTUzNTEwOEw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAgKiBAcGFyYW0gc291cmNlICAJVGhlIGZvbGRlciB0aGF0IG93bnMgdGhlIG1lc3NhZ2UKKyAgICAgKiBAcGFyYW0gdHlwZQlUaGUgY2hhbmdlIHR5cGUKKyAgICAgKiBAcGFyYW0gbXNnCVRoZSBjaGFuZ2VkIG1lc3NhZ2UgCisgICAgICovCisgICAgcHVibGljIE1lc3NhZ2VDaGFuZ2VkRXZlbnQoT2JqZWN0IHNvdXJjZSwgaW50IHR5cGUsIE1lc3NhZ2UgbXNnKSB7CisJc3VwZXIoc291cmNlKTsKKwl0aGlzLm1zZyA9IG1zZzsKKwl0aGlzLnR5cGUgPSB0eXBlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgdHlwZSBvZiB0aGlzIGV2ZW50LgorICAgICAqIEByZXR1cm4gIHR5cGUKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE1lc3NhZ2VDaGFuZ2VUeXBlKCkgeworCXJldHVybiB0eXBlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgY2hhbmdlZCBNZXNzYWdlLgorICAgICAqIEByZXR1cm4gIHRoZSBtZXNzYWdlCisgICAgICovCisgICAgcHVibGljIE1lc3NhZ2UgZ2V0TWVzc2FnZSgpIHsKKwlyZXR1cm4gbXNnOworICAgIH0KKworICAgIC8qKgorICAgICAqIEludm9rZXMgdGhlIGFwcHJvcHJpYXRlIE1lc3NhZ2VDaGFuZ2VkTGlzdGVuZXIgbWV0aG9kLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGRpc3BhdGNoKE9iamVjdCBsaXN0ZW5lcikgeworCSgoTWVzc2FnZUNoYW5nZWRMaXN0ZW5lcilsaXN0ZW5lcikubWVzc2FnZUNoYW5nZWQodGhpcyk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvZXZlbnQvTWVzc2FnZUNoYW5nZWRMaXN0ZW5lci5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvZXZlbnQvTWVzc2FnZUNoYW5nZWRMaXN0ZW5lci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM0ZWFjNDgKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9ldmVudC9NZXNzYWdlQ2hhbmdlZExpc3RlbmVyLmphdmEKQEAgLTAsMCArMSwzNyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsLmV2ZW50OworCitpbXBvcnQgamF2YS51dGlsLio7CisKKy8qKgorICogVGhpcyBpcyB0aGUgTGlzdGVuZXIgaW50ZXJmYWNlIGZvciBNZXNzYWdlQ2hhbmdlZCBldmVudHMKKyAqCisgKiBAYXV0aG9yIEpvaG4gTWFuaQorICovCisKK3B1YmxpYyBpbnRlcmZhY2UgTWVzc2FnZUNoYW5nZWRMaXN0ZW5lciBleHRlbmRzIGphdmEudXRpbC5FdmVudExpc3RlbmVyIHsKKyAgICAvKioKKyAgICAgKiBJbnZva2VkIHdoZW4gYSBtZXNzYWdlIGlzIGNoYW5nZWQuIFRoZSBjaGFuZ2UtdHlwZSBzcGVjaWZpZXMKKyAgICAgKiB3aGF0IGNoYW5nZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0JZQl0aGUgTWVzc2FnZUNoYW5nZWRFdmVudAorICAgICAqIEBzZWUgTWVzc2FnZUNoYW5nZWRFdmVudCNGTEFHU19DSEFOR0VECisgICAgICogQHNlZSBNZXNzYWdlQ2hhbmdlZEV2ZW50I0VOVkVMT1BFX0NIQU5HRUQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBtZXNzYWdlQ2hhbmdlZChNZXNzYWdlQ2hhbmdlZEV2ZW50IGUpOworfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvZXZlbnQvTWVzc2FnZUNvdW50QWRhcHRlci5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvZXZlbnQvTWVzc2FnZUNvdW50QWRhcHRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY5NDA2OWYKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9ldmVudC9NZXNzYWdlQ291bnRBZGFwdGVyLmphdmEKQEAgLTAsMCArMSwzMiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsLmV2ZW50OworCisvKioKKyAqIFRoZSBhZGFwdGVyIHdoaWNoIHJlY2VpdmVzIE1lc3NhZ2VDb3VudCBldmVudHMuCisgKiBUaGUgbWV0aG9kcyBpbiB0aGlzIGNsYXNzIGFyZSBlbXB0eTsgIHRoaXMgY2xhc3MgaXMgcHJvdmlkZWQgYXMgYQorICogY29udmVuaWVuY2UgZm9yIGVhc2lseSBjcmVhdGluZyBsaXN0ZW5lcnMgYnkgZXh0ZW5kaW5nIHRoaXMgY2xhc3MKKyAqIGFuZCBvdmVycmlkaW5nIG9ubHkgdGhlIG1ldGhvZHMgb2YgaW50ZXJlc3QuCisgKgorICogQGF1dGhvciBKb2huIE1hbmkKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIE1lc3NhZ2VDb3VudEFkYXB0ZXIgaW1wbGVtZW50cyBNZXNzYWdlQ291bnRMaXN0ZW5lciB7CisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgbWVzc2FnZXNBZGRlZChNZXNzYWdlQ291bnRFdmVudCBlKSB7fQorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIG1lc3NhZ2VzUmVtb3ZlZChNZXNzYWdlQ291bnRFdmVudCBlKSB7fQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvZXZlbnQvTWVzc2FnZUNvdW50RXZlbnQuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2V2ZW50L01lc3NhZ2VDb3VudEV2ZW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjRkMzhhOAotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2V2ZW50L01lc3NhZ2VDb3VudEV2ZW50LmphdmEKQEAgLTAsMCArMSwxMzQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5ldmVudDsKKworaW1wb3J0IGphdmEudXRpbC4qOworaW1wb3J0IGphdmF4Lm1haWwuKjsKKworLyoqCisgKiBUaGlzIGNsYXNzIG5vdGlmaWVzIGNoYW5nZXMgaW4gdGhlIG51bWJlciBvZiBtZXNzYWdlcyBpbiBhIGZvbGRlci4gPHA+CisgKgorICogTm90ZSB0aGF0IHNvbWUgZm9sZGVyIHR5cGVzIG1heSBvbmx5IGRlbGl2ZXIgTWVzc2FnZUNvdW50RXZlbnRzIGF0CisgKiBjZXJ0YWluIHRpbWVzIG9yIGFmdGVyIGNlcnRhaW4gb3BlcmF0aW9ucy4gIElNQVAgaW4gcGFydGljdWxhciB3aWxsCisgKiBvbmx5IG5vdGlmeSB0aGUgY2xpZW50IG9mIE1lc3NhZ2VDb3VudEV2ZW50cyB3aGVuIGEgY2xpZW50IGlzc3VlcyBhCisgKiBuZXcgY29tbWFuZC4gIFJlZmVyIHRvCisgKiA8QSBIUkVGPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMzNTAxLnR4dCIgVEFSR0VUPSJfdG9wIj5SRkMgMzUwMTwvQT4KKyAqIGZvciBkZXRhaWxzLgorICogQSBjbGllbnQgbWF5IHdhbnQgdG8gInBvbGwiIHRoZSBmb2xkZXIgYnkgb2NjYXNpb25hbGx5IGNhbGxpbmcgdGhlCisgKiB7QGxpbmsgamF2YXgubWFpbC5Gb2xkZXIjZ2V0TWVzc2FnZUNvdW50IGdldE1lc3NhZ2VDb3VudH0gb3IKKyAqIHtAbGluayBqYXZheC5tYWlsLkZvbGRlciNpc09wZW4gaXNPcGVufSBtZXRob2RzCisgKiB0byBzb2xpY2l0IGFueSBzdWNoIG5vdGlmaWNhdGlvbnMuCisgKgorICogQGF1dGhvciBKb2huIE1hbmkKKyAqLworCitwdWJsaWMgY2xhc3MgTWVzc2FnZUNvdW50RXZlbnQgZXh0ZW5kcyBNYWlsRXZlbnQgeworCisgICAgLyoqIFRoZSBtZXNzYWdlcyB3ZXJlIGFkZGVkIHRvIHRoZWlyIGZvbGRlciAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFEREVEIAkJPSAxOworICAgIC8qKiBUaGUgbWVzc2FnZXMgd2VyZSByZW1vdmVkIGZyb20gdGhlaXIgZm9sZGVyICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVNT1ZFRCAJCT0gMjsKKworICAgIC8qKgorICAgICAqIFRoZSBldmVudCB0eXBlLgorICAgICAqCisgICAgICogQHNlcmlhbAorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgdHlwZTsKKworICAgIC8qKgorICAgICAqIElmIHRydWUsIHRoaXMgZXZlbnQgaXMgdGhlIHJlc3VsdCBvZiBhbiBleHBsaWNpdAorICAgICAqIGV4cHVuZ2UgYnkgdGhpcyBjbGllbnQsIGFuZCB0aGUgbWVzc2FnZXMgaW4gdGhpcyAKKyAgICAgKiBmb2xkZXIgaGF2ZSBiZWVuIHJlbnVtYmVyZWQgdG8gYWNjb3VudCBmb3IgdGhpcy4KKyAgICAgKiBJZiBmYWxzZSwgdGhpcyBldmVudCBpcyB0aGUgcmVzdWx0IG9mIGFuIGV4cHVuZ2UKKyAgICAgKiBieSBleHRlcm5hbCBzb3VyY2VzLgorICAgICAqCisgICAgICogQHNlcmlhbAorICAgICAqLworICAgIHByb3RlY3RlZCBib29sZWFuIHJlbW92ZWQ7CisKKyAgICAvKioKKyAgICAgKiBUaGUgbWVzc2FnZXMuCisgICAgICovCisgICAgdHJhbnNpZW50IHByb3RlY3RlZCBNZXNzYWdlW10gbXNnczsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC03NDQ3MDIyMzQwODM3ODk3MzY5TDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yLgorICAgICAqIEBwYXJhbSBmb2xkZXIgIAlUaGUgY29udGFpbmluZyBmb2xkZXIKKyAgICAgKiBAcGFyYW0gdHlwZQlUaGUgZXZlbnQgdHlwZQorICAgICAqIEBwYXJhbSByZW1vdmVkCUlmIHRydWUsIHRoaXMgZXZlbnQgaXMgdGhlIHJlc3VsdCBvZiBhbiBleHBsaWNpdAorICAgICAqCQkJZXhwdW5nZSBieSB0aGlzIGNsaWVudCwgYW5kIHRoZSBtZXNzYWdlcyBpbiB0aGlzIAorICAgICAqCQkJZm9sZGVyIGhhdmUgYmVlbiByZW51bWJlcmVkIHRvIGFjY291bnQgZm9yIHRoaXMuCisgICAgICoJCQlJZiBmYWxzZSwgdGhpcyBldmVudCBpcyB0aGUgcmVzdWx0IG9mIGFuIGV4cHVuZ2UKKyAgICAgKgkJCWJ5IGV4dGVybmFsIHNvdXJjZXMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbXNncwlUaGUgbWVzc2FnZXMgYWRkZWQvcmVtb3ZlZAorICAgICAqLworICAgIHB1YmxpYyBNZXNzYWdlQ291bnRFdmVudChGb2xkZXIgZm9sZGVyLCBpbnQgdHlwZSwgCisJCQkgICAgIGJvb2xlYW4gcmVtb3ZlZCwgTWVzc2FnZVtdIG1zZ3MpIHsKKwlzdXBlcihmb2xkZXIpOworCXRoaXMudHlwZSA9IHR5cGU7CisJdGhpcy5yZW1vdmVkID0gcmVtb3ZlZDsKKwl0aGlzLm1zZ3MgPSBtc2dzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgdHlwZSBvZiB0aGlzIGV2ZW50LgorICAgICAqIEByZXR1cm4gIHR5cGUKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFR5cGUoKSB7CisJcmV0dXJuIHR5cGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhpcyBldmVudCBpcyB0aGUgcmVzdWx0IG9mIGFuIGV4cGxpY2l0CisgICAgICogZXhwdW5nZSBieSB0aGlzIGNsaWVudCwgb3IgZHVlIHRvIGFuIGV4cHVuZ2UgZnJvbSBleHRlcm5hbAorICAgICAqIHNvdXJjZXMuIElmIDxjb2RlPnRydWU8L2NvZGU+LCB0aGlzIGV2ZW50IGlzIGR1ZSB0byBhbgorICAgICAqIGV4cGxpY2l0IGV4cHVuZ2UgYW5kIGhlbmNlIGFsbCByZW1haW5pbmcgbWVzc2FnZXMgaW4gdGhpcworICAgICAqIGZvbGRlciBoYXZlIGJlZW4gcmVudW1iZXJlZC4gSWYgPGNvZGU+ZmFsc2U8L2NvZGU+LCB0aGlzIGV2ZW50CisgICAgICogaXMgZHVlIHRvIGFuIGV4dGVybmFsIGV4cHVuZ2UuIDxwPgorICAgICAqCisgICAgICogTm90ZSB0aGF0IHRoaXMgbWV0aG9kIGlzIHZhbGlkIG9ubHkgaWYgdGhlIHR5cGUgb2YgdGhpcyBldmVudAorICAgICAqIGlzIDxjb2RlPlJFTU9WRUQ8L2NvZGU+CisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRydWUgaWYgdGhlIG1lc3NhZ2UgaGFzIGJlZW4gcmVtb3ZlZAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzUmVtb3ZlZCgpIHsKKwlyZXR1cm4gcmVtb3ZlZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIGFycmF5IG9mIG1lc3NhZ2VzIGFkZGVkIG9yIHJlbW92ZWQuCisgICAgICogQHJldHVybiBhcnJheSBvZiBtZXNzYWdlcworICAgICAqLworICAgIHB1YmxpYyBNZXNzYWdlW10gZ2V0TWVzc2FnZXMoKSB7CisJcmV0dXJuIG1zZ3M7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW52b2tlcyB0aGUgYXBwcm9wcmlhdGUgTWVzc2FnZUNvdW50TGlzdGVuZXIgbWV0aG9kLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGRpc3BhdGNoKE9iamVjdCBsaXN0ZW5lcikgeworCWlmICh0eXBlID09IEFEREVEKQorCSAgICAoKE1lc3NhZ2VDb3VudExpc3RlbmVyKWxpc3RlbmVyKS5tZXNzYWdlc0FkZGVkKHRoaXMpOworCWVsc2UgLy8gUkVNT1ZFRAorCSAgICAoKE1lc3NhZ2VDb3VudExpc3RlbmVyKWxpc3RlbmVyKS5tZXNzYWdlc1JlbW92ZWQodGhpcyk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvZXZlbnQvTWVzc2FnZUNvdW50TGlzdGVuZXIuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2V2ZW50L01lc3NhZ2VDb3VudExpc3RlbmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTc5M2ZlMAotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2V2ZW50L01lc3NhZ2VDb3VudExpc3RlbmVyLmphdmEKQEAgLTAsMCArMSw0MSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsLmV2ZW50OworCitpbXBvcnQgamF2YS51dGlsLio7CisKKy8qKgorICogVGhpcyBpcyB0aGUgTGlzdGVuZXIgaW50ZXJmYWNlIGZvciBNZXNzYWdlQ291bnQgZXZlbnRzLgorICoKKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKi8KKworcHVibGljIGludGVyZmFjZSBNZXNzYWdlQ291bnRMaXN0ZW5lciBleHRlbmRzIGphdmEudXRpbC5FdmVudExpc3RlbmVyIHsKKyAgICAvKioKKyAgICAgKiBJbnZva2VkIHdoZW4gbWVzc2FnZXMgYXJlIGFkZGVkIGludG8gYSBmb2xkZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0JZQl0aGUgTWVzc2FnZUNvdW50RXZlbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBtZXNzYWdlc0FkZGVkKE1lc3NhZ2VDb3VudEV2ZW50IGUpOworCisgICAgLyoqCisgICAgICogSW52b2tlZCB3aGVuIG1lc3NhZ2VzIGFyZSByZW1vdmVkIChleHB1bmdlZCkgZnJvbSBhIGZvbGRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbQllCXRoZSBNZXNzYWdlQ291bnRFdmVudAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIG1lc3NhZ2VzUmVtb3ZlZChNZXNzYWdlQ291bnRFdmVudCBlKTsKK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2V2ZW50L1N0b3JlRXZlbnQuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2V2ZW50L1N0b3JlRXZlbnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNDMzMjgzCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvZXZlbnQvU3RvcmVFdmVudC5qYXZhCkBAIC0wLDAgKzEsOTkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5ldmVudDsKKworaW1wb3J0IGphdmEudXRpbC4qOworaW1wb3J0IGphdmF4Lm1haWwuKjsKKworLyoqCisgKiBUaGlzIGNsYXNzIG1vZGVscyBub3RpZmljYXRpb25zIGZyb20gdGhlIFN0b3JlIGNvbm5lY3Rpb24uIFRoZXNlCisgKiBub3RpZmljYXRpb25zIGNhbiBiZSBBTEVSVFMgb3IgTk9USUNFUy4gQUxFUlRTIG11c3QgYmUgcHJlc2VudGVkCisgKiB0byB0aGUgdXNlciBpbiBhIGZhc2hpb24gdGhhdCBjYWxscyB0aGUgdXNlcidzIGF0dGVudGlvbiB0byB0aGUKKyAqIG1lc3NhZ2UuCisgKgorICogQGF1dGhvciBKb2huIE1hbmkKKyAqLworCitwdWJsaWMgY2xhc3MgU3RvcmVFdmVudCBleHRlbmRzIE1haWxFdmVudCB7CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgdGhhdCB0aGlzIG1lc3NhZ2UgaXMgYW4gQUxFUlQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQUxFUlQgCQk9IDE7CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgdGhhdCB0aGlzIG1lc3NhZ2UgaXMgYSBOT1RJQ0UuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTk9USUNFIAkJPSAyOworCisgICAgLyoqCisgICAgICogVGhlIGV2ZW50IHR5cGUuCisgICAgICoKKyAgICAgKiBAc2VyaWFsCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCB0eXBlOworCisgICAgLyoqCisgICAgICogVGhlIG1lc3NhZ2UgdGV4dCB0byBiZSBwcmVzZW50ZWQgdG8gdGhlIHVzZXIuCisgICAgICoKKyAgICAgKiBAc2VyaWFsCisgICAgICovCisgICAgcHJvdGVjdGVkIFN0cmluZyBtZXNzYWdlOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMTkzODcwNDkxOTk5MjUxNTMzMEw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYSBTdG9yZUV2ZW50LgorICAgICAqCisgICAgICogQHBhcmFtCXN0b3JlCXRoZSBzb3VyY2UgU3RvcmUKKyAgICAgKiBAcGFyYW0JdHlwZQl0aGUgZXZlbnQgdHlwZQorICAgICAqIEBwYXJhbQltZXNzYWdlCWEgbWVzc2FnZSBhc3NvaWNhdGVkIHdpdGggdGhlIGV2ZW50CisgICAgICovCisgICAgcHVibGljIFN0b3JlRXZlbnQoU3RvcmUgc3RvcmUsIGludCB0eXBlLCBTdHJpbmcgbWVzc2FnZSkgeworCXN1cGVyKHN0b3JlKTsKKwl0aGlzLnR5cGUgPSB0eXBlOworCXRoaXMubWVzc2FnZSA9IG1lc3NhZ2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSB0eXBlIG9mIHRoaXMgZXZlbnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuICB0eXBlCisgICAgICogQHNlZSAjQUxFUlQKKyAgICAgKiBAc2VlICNOT1RJQ0UKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldE1lc3NhZ2VUeXBlKCkgeworCXJldHVybiB0eXBlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgbWVzc2FnZSBmcm9tIHRoZSBTdG9yZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gbWVzc2FnZSBmcm9tIHRoZSBTdG9yZQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWVzc2FnZSgpIHsKKwlyZXR1cm4gbWVzc2FnZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnZva2VzIHRoZSBhcHByb3ByaWF0ZSBTdG9yZUxpc3RlbmVyIG1ldGhvZC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBkaXNwYXRjaChPYmplY3QgbGlzdGVuZXIpIHsKKwkoKFN0b3JlTGlzdGVuZXIpbGlzdGVuZXIpLm5vdGlmaWNhdGlvbih0aGlzKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9ldmVudC9TdG9yZUxpc3RlbmVyLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9ldmVudC9TdG9yZUxpc3RlbmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2MwMGFiOAotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2V2ZW50L1N0b3JlTGlzdGVuZXIuamF2YQpAQCAtMCwwICsxLDM3IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGphdmF4Lm1haWwuZXZlbnQ7CisKK2ltcG9ydCBqYXZhLnV0aWwuKjsKKworLyoqCisgKiBUaGlzIGlzIHRoZSBMaXN0ZW5lciBpbnRlcmZhY2UgZm9yIFN0b3JlIE5vdGlmaWNhdGlvbnMuCisgKgorICogQGF1dGhvciBKb2huIE1hbmkKKyAqLworCitwdWJsaWMgaW50ZXJmYWNlIFN0b3JlTGlzdGVuZXIgZXh0ZW5kcyBqYXZhLnV0aWwuRXZlbnRMaXN0ZW5lciB7CisKKyAgIC8qKgorICAgICogSW52b2tlZCB3aGVuIHRoZSBTdG9yZSBnZW5lcmF0ZXMgYSBub3RpZmljYXRpb24gZXZlbnQuCisgICAgKgorICAgICogQHBhcmFtCWUJdGhlIFN0b3JlRXZlbnQKKyAgICAqIEBzZWUgU3RvcmVFdmVudCNBTEVSVAorICAgICogQHNlZSBTdG9yZUV2ZW50I05PVElDRQorICAgICovCisgICBwdWJsaWMgdm9pZCBub3RpZmljYXRpb24oU3RvcmVFdmVudCBlKTsKK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2V2ZW50L1RyYW5zcG9ydEFkYXB0ZXIuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2V2ZW50L1RyYW5zcG9ydEFkYXB0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43OThjZWY3Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvZXZlbnQvVHJhbnNwb3J0QWRhcHRlci5qYXZhCkBAIC0wLDAgKzEsMzQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5ldmVudDsKKworLyoqCisgKiBUaGUgYWRhcHRlciB3aGljaCByZWNlaXZlcyBUcmFuc3BvcnQgZXZlbnRzLgorICogVGhlIG1ldGhvZHMgaW4gdGhpcyBjbGFzcyBhcmUgZW1wdHk7ICB0aGlzIGNsYXNzIGlzIHByb3ZpZGVkIGFzIGEKKyAqIGNvbnZlbmllbmNlIGZvciBlYXNpbHkgY3JlYXRpbmcgbGlzdGVuZXJzIGJ5IGV4dGVuZGluZyB0aGlzIGNsYXNzCisgKiBhbmQgb3ZlcnJpZGluZyBvbmx5IHRoZSBtZXRob2RzIG9mIGludGVyZXN0LgorICoKKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBUcmFuc3BvcnRBZGFwdGVyIGltcGxlbWVudHMgVHJhbnNwb3J0TGlzdGVuZXIgeworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIG1lc3NhZ2VEZWxpdmVyZWQoVHJhbnNwb3J0RXZlbnQgZSkge30KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBtZXNzYWdlTm90RGVsaXZlcmVkKFRyYW5zcG9ydEV2ZW50IGUpIHt9CisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgbWVzc2FnZVBhcnRpYWxseURlbGl2ZXJlZChUcmFuc3BvcnRFdmVudCBlKSB7fQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvZXZlbnQvVHJhbnNwb3J0RXZlbnQuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2V2ZW50L1RyYW5zcG9ydEV2ZW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmY3NTRjYQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2V2ZW50L1RyYW5zcG9ydEV2ZW50LmphdmEKQEAgLTAsMCArMSwxNTQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5ldmVudDsKKworaW1wb3J0IGphdmEudXRpbC4qOworaW1wb3J0IGphdmF4Lm1haWwuKjsKKworLyoqCisgKiBUaGlzIGNsYXNzIG1vZGVscyBUcmFuc3BvcnQgZXZlbnRzLgorICoKKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKiBAYXV0aG9yIE1heCBTcGl2YWsKKyAqIAorICogQHNlZSBqYXZheC5tYWlsLlRyYW5zcG9ydAorICogQHNlZSBqYXZheC5tYWlsLmV2ZW50LlRyYW5zcG9ydExpc3RlbmVyCisgKi8KKworcHVibGljIGNsYXNzIFRyYW5zcG9ydEV2ZW50IGV4dGVuZHMgTWFpbEV2ZW50IHsKKworICAgIC8qKgorICAgICAqIE1lc3NhZ2UgaGFzIGJlZW4Jc3VjY2Vzc2Z1bGx5IGRlbGl2ZXJlZCB0byBhbGwgcmVjaXBpZW50cyBieSB0aGUKKyAgICAgKiB0cmFuc3BvcnQgZmlyaW5nIHRoaXMgZXZlbnQuIHZhbGlkU2VudFtdIGNvbnRhaW5zIGFsbCB0aGUgYWRkcmVzc2VzCisgICAgICogdGhpcyB0cmFuc3BvcnQgc2VudCB0byBzdWNjZXNzZnVsbHkuIHZhbGlkVW5zZW50W10gYW5kIGludmFsaWRbXSAKKyAgICAgKiBzaG91bGQgYmUgbnVsbCwKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNRVNTQUdFX0RFTElWRVJFRAkgID0gMTsKKworICAgIC8qKgorICAgICAqIE1lc3NhZ2Ugd2FzIG5vdCBzZW50IGZvciBzb21lIHJlYXNvbi4gdmFsaWRTZW50W10gc2hvdWxkIGJlIG51bGwuIAorICAgICAqIHZhbGlkVW5zZW50W10gbWF5IGhhdmUgYWRkcmVzc2VzIHRoYXQgYXJlIHZhbGlkIChidXQgdGhlIG1lc3NhZ2UKKyAgICAgKiB3YXNuJ3Qgc2VudCB0byB0aGVtKS4gaW52YWxpZFtdIHNob3VsZCBsaWtlbHkgY29udGFpbiBpbnZhbGlkIGFkZHJlc3Nlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNRVNTQUdFX05PVF9ERUxJVkVSRUQgPSAyOworCisgICAgLyoqCisgICAgICogTWVzc2FnZSB3YXMgc3VjY2Vzc2Z1bGx5IHNlbnQgdG8gc29tZSByZWNpcGllbnRzIGJ1dCBub3QgdG8gYWxsLiAKKyAgICAgKiB2YWxpZFNlbnRbXSBob2xkcyBhZGRyZXNzZXMgb2YgcmVjaXBpZW50cyB0byB3aG9tIHRoZSBtZXNzYWdlIHdhcyBzZW50LgorICAgICAqIHZhbGlkVW5zZW50W10gaG9sZHMgdmFsaWQgYWRkcmVzc2VzIHRvIHdoaWNoIHRoZSBtZXNzYWdlIHdhcyBub3Qgc2VudC4KKyAgICAgKiBpbnZhbGlkW10gaG9sZHMgaW52YWxpZCBhZGRyZXNzZXMsIGlmIGFueS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNRVNTQUdFX1BBUlRJQUxMWV9ERUxJVkVSRUQgPSAzOworCisKKyAgICAvKioKKyAgICAgKiBUaGUgZXZlbnQgdHlwZS4KKyAgICAgKgorICAgICAqIEBzZXJpYWwKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IHR5cGU7CisKKyAgICAvKiogVGhlIHZhbGlkIGFkZHJlc3MgdG8gd2hpY2ggdGhlIG1lc3NhZ2Ugd2FzIHNlbnQuICovCisgICAgdHJhbnNpZW50IHByb3RlY3RlZCBBZGRyZXNzW10gdmFsaWRTZW50OworICAgIC8qKiBUaGUgdmFsaWQgYWRkcmVzcyB0byB3aGljaCB0aGUgbWVzc2FnZSB3YXMgbm90IHNlbnQuICovCisgICAgdHJhbnNpZW50IHByb3RlY3RlZCBBZGRyZXNzW10gdmFsaWRVbnNlbnQ7CisgICAgLyoqIFRoZSBpbnZhbGlkIGFkZHJlc3Nlcy4gKi8KKyAgICB0cmFuc2llbnQgcHJvdGVjdGVkIEFkZHJlc3NbXSBpbnZhbGlkOworICAgIC8qKiBUaGUgTWVzc2FnZSB0byB3aGljaCB0aGlzIGV2ZW50IGFwcGxpZXMuICovCisgICAgdHJhbnNpZW50IHByb3RlY3RlZCBNZXNzYWdlIG1zZzsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC00NzI5ODUyMzY0Njg0MjczMDczTDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yLgorICAgICAqCisgICAgICogQHBhcmFtCXRyYW5zcG9ydCBUaGUgVHJhbnNwb3J0IG9iamVjdAorICAgICAqIEBwYXJhbQl0eXBlCXRoZSBldmVudCB0eXBlIChNRVNTQUdFX0RFTElWRVJFRCwgZXRjLikKKyAgICAgKiBAcGFyYW0JdmFsaWRTZW50IHRoZSB2YWxpZCBhZGRyZXNzZXMgdG8gd2hpY2ggdGhlIG1lc3NhZ2Ugd2FzIHNlbnQKKyAgICAgKiBAcGFyYW0JdmFsaWRVbnNlbnQgdGhlIHZhbGlkIGFkZHJlc3NlcyB0byB3aGljaCB0aGUgbWVzc2FnZSB3YXMKKyAgICAgKgkJCQlub3Qgc2VudAorICAgICAqIEBwYXJhbQlpbnZhbGlkCXRoZSBpbnZhbGlkIGFkZHJlc3NlcworICAgICAqIEBwYXJhbQltc2cJdGhlIG1lc3NhZ2UgYmVpbmcgc2VudAorICAgICAqLworICAgIHB1YmxpYyBUcmFuc3BvcnRFdmVudChUcmFuc3BvcnQgdHJhbnNwb3J0LCBpbnQgdHlwZSwgQWRkcmVzc1tdIHZhbGlkU2VudCwKKwkJCSAgQWRkcmVzc1tdIHZhbGlkVW5zZW50LCBBZGRyZXNzW10gaW52YWxpZCwKKwkJCSAgTWVzc2FnZSBtc2cpIHsKKwlzdXBlcih0cmFuc3BvcnQpOworCXRoaXMudHlwZSA9IHR5cGU7CisJdGhpcy52YWxpZFNlbnQgPSB2YWxpZFNlbnQ7CisJdGhpcy52YWxpZFVuc2VudCA9IHZhbGlkVW5zZW50OworCXRoaXMuaW52YWxpZCA9IGludmFsaWQ7CisJdGhpcy5tc2cgPSBtc2c7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSB0eXBlIG9mIHRoaXMgZXZlbnQuCisgICAgICogQHJldHVybiAgdHlwZQorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0VHlwZSgpIHsKKwlyZXR1cm4gdHlwZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIGFkZHJlc3NlcyB0byB3aGljaCB0aGlzIG1lc3NhZ2Ugd2FzIHNlbnQgc3VjY2VzZnVsbHkuCisgICAgICogQHJldHVybiBBZGRyZXNzZXMgdG8gd2hpY2ggdGhlIG1lc3NhZ2Ugd2FzIHNlbnQgc3VjY2Vzc2Z1bGx5IG9yIG51bGwKKyAgICAgKi8KKyAgICBwdWJsaWMgQWRkcmVzc1tdIGdldFZhbGlkU2VudEFkZHJlc3NlcygpIHsKKwlyZXR1cm4gdmFsaWRTZW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgYWRkcmVzc2VzIHRoYXQgYXJlIHZhbGlkIGJ1dCB0byB3aGljaCB0aGlzIG1lc3NhZ2UgCisgICAgICogd2FzIG5vdCBzZW50LgorICAgICAqIEByZXR1cm4gQWRkcmVzc2VzIHRoYXQgYXJlIHZhbGlkIGJ1dCB0byB3aGljaCB0aGUgbWVzc2FnZSB3YXMgCisgICAgICogICAgICAgICBub3Qgc2VudCBzdWNjZXNzZnVsbHkgb3IgbnVsbAorICAgICAqLworICAgIHB1YmxpYyBBZGRyZXNzW10gZ2V0VmFsaWRVbnNlbnRBZGRyZXNzZXMoKSB7CisJcmV0dXJuIHZhbGlkVW5zZW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgYWRkcmVzc2VzIHRvIHdoaWNoIHRoaXMgbWVzc2FnZSBjb3VsZCBub3QgYmUgc2VudC4KKyAgICAgKiBAcmV0dXJuIEFkZHJlc3NlcyB0byB3aGljaCB0aGUgbWVzc2FnZSBzZW5kaW5nIGZhaWxlZCBvciBudWxsCisgICAgICovCisgICAgcHVibGljIEFkZHJlc3NbXSBnZXRJbnZhbGlkQWRkcmVzc2VzKCkgeworCXJldHVybiBpbnZhbGlkOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgTWVzc2FnZSBvYmplY3QgYXNzb2NpYXRlZCB3aXRoIHRoaXMgVHJhbnNwb3J0IEV2ZW50LgorICAgICAqICAgCisgICAgICogQHJldHVybiAgICAgICAgICB0aGUgTWVzc2FnZSBvYmplY3QKKyAgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuMgorICAgICAqLyAgCisgICAgcHVibGljIE1lc3NhZ2UgZ2V0TWVzc2FnZSgpIHsKKyAgICAgICAgcmV0dXJuIG1zZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnZva2VzIHRoZSBhcHByb3ByaWF0ZSBUcmFuc3BvcnRMaXN0ZW5lciBtZXRob2QuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZGlzcGF0Y2goT2JqZWN0IGxpc3RlbmVyKSB7CisJaWYgKHR5cGUgPT0gTUVTU0FHRV9ERUxJVkVSRUQpCQorCSAgICAoKFRyYW5zcG9ydExpc3RlbmVyKWxpc3RlbmVyKS5tZXNzYWdlRGVsaXZlcmVkKHRoaXMpOworCWVsc2UgaWYgKHR5cGUgPT0gTUVTU0FHRV9OT1RfREVMSVZFUkVEKQorCSAgICAoKFRyYW5zcG9ydExpc3RlbmVyKWxpc3RlbmVyKS5tZXNzYWdlTm90RGVsaXZlcmVkKHRoaXMpOworCWVsc2UgLy8gTUVTU0FHRV9QQVJUSUFMTFlfREVMSVZFUkVECisJICAgICgoVHJhbnNwb3J0TGlzdGVuZXIpbGlzdGVuZXIpLm1lc3NhZ2VQYXJ0aWFsbHlEZWxpdmVyZWQodGhpcyk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvZXZlbnQvVHJhbnNwb3J0TGlzdGVuZXIuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2V2ZW50L1RyYW5zcG9ydExpc3RlbmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2ZjMDMwZAotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2V2ZW50L1RyYW5zcG9ydExpc3RlbmVyLmphdmEKQEAgLTAsMCArMSw1MiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsLmV2ZW50OworCitpbXBvcnQgamF2YS51dGlsLio7CisKKy8qKgorICogVGhpcyBpcyB0aGUgTGlzdGVuZXIgaW50ZXJmYWNlIGZvciBUcmFuc3BvcnQgZXZlbnRzCisgKgorICogQGF1dGhvciBKb2huIE1hbmkKKyAqIEBhdXRob3IgTWF4IFNwaXZhaworICoKKyAqIEBzZWUgamF2YXgubWFpbC5UcmFuc3BvcnQKKyAqIEBzZWUgamF2YXgubWFpbC5ldmVudC5UcmFuc3BvcnRFdmVudAorICovCisKK3B1YmxpYyBpbnRlcmZhY2UgVHJhbnNwb3J0TGlzdGVuZXIgZXh0ZW5kcyBqYXZhLnV0aWwuRXZlbnRMaXN0ZW5lciB7CisKKyAgICAvKioKKyAgICAgKiBJbnZva2VkIHdoZW4gYSBNZXNzYWdlIGlzIHN1Y2Nlc2Z1bGx5IGRlbGl2ZXJlZC4KKyAgICAgKiBAcGFyYW0JZSBUcmFuc3BvcnRFdmVudAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIG1lc3NhZ2VEZWxpdmVyZWQoVHJhbnNwb3J0RXZlbnQgZSk7CisKKyAgICAvKioKKyAgICAgKiBJbnZva2VkIHdoZW4gYSBNZXNzYWdlIGlzIG5vdCBkZWxpdmVyZWQuCisgICAgICogQHBhcmFtCWUgVHJhbnNwb3J0RXZlbnQKKyAgICAgKiBAc2VlIFRyYW5zcG9ydEV2ZW50CisgICAgICovCisgICAgcHVibGljIHZvaWQgbWVzc2FnZU5vdERlbGl2ZXJlZChUcmFuc3BvcnRFdmVudCBlKTsKKworICAgIC8qKgorICAgICAqIEludm9rZWQgd2hlbiBhIE1lc3NhZ2UgaXMgcGFydGlhbGx5IGRlbGl2ZXJlZC4KKyAgICAgKiBAcGFyYW0JZSBUcmFuc3BvcnRFdmVudAorICAgICAqIEBzZWUgVHJhbnNwb3J0RXZlbnQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBtZXNzYWdlUGFydGlhbGx5RGVsaXZlcmVkKFRyYW5zcG9ydEV2ZW50IGUpOworfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvZXZlbnQvcGFja2FnZS5odG1sIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvZXZlbnQvcGFja2FnZS5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQyMmMwMGIKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9ldmVudC9wYWNrYWdlLmh0bWwKQEAgLTAsMCArMSwzMSBAQAorPCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDMuMiBGaW5hbC8vRU4iPgorPEhUTUw+Cis8SEVBRD4KKzxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PXV0Zi04Ij4KKzwhLS0KKworICAgIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorCisgICAgVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgICAgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisKKyAgICBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgICAgTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICAgIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICAgIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorCisgICAgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisKKy0tPgorCis8L0hFQUQ+Cis8Qk9EWSBCR0NPTE9SPSJ3aGl0ZSI+CisKK0xpc3RlbmVycyBhbmQgZXZlbnRzIGZvciB0aGUgSmF2YU1haWwgQVBJLgorVGhpcyBwYWNrYWdlIGRlZmluZXMgbGlzdGVuZXIgY2xhc3NlcyBhbmQgZXZlbnQgY2xhc3NlcyB1c2VkIGJ5IHRoZSBjbGFzc2VzCitkZWZpbmVkIGluIHRoZSA8Y29kZT5qYXZheC5tYWlsPC9jb2RlPiBwYWNrYWdlLgorCis8L0JPRFk+Cis8L0hUTUw+CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9BZGRyZXNzRXhjZXB0aW9uLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9BZGRyZXNzRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjkxZTFjZQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2ludGVybmV0L0FkZHJlc3NFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDExNCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsLmludGVybmV0OworCisvKioKKyAqIFRoZSBleGNlcHRpb24gdGhyb3duIHdoZW4gYSB3cm9uZ2x5IGZvcm1hdHRlZCBhZGRyZXNzIGlzIGVuY291bnRlcmVkLgorICoKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKiBAYXV0aG9yIE1heCBTcGl2YWsKKyAqLworCitwdWJsaWMgY2xhc3MgQWRkcmVzc0V4Y2VwdGlvbiBleHRlbmRzIFBhcnNlRXhjZXB0aW9uIHsKKyAgICAvKioKKyAgICAgKiBUaGUgc3RyaW5nIGJlaW5nIHBhcnNlZC4KKyAgICAgKgorICAgICAqIEBzZXJpYWwKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU3RyaW5nIHJlZiA9IG51bGw7CisKKyAgICAvKioKKyAgICAgKiBUaGUgaW5kZXggaW4gdGhlIHN0cmluZyB3aGVyZSB0aGUgZXJyb3Igb2NjdXJyZWQsIG9yIC0xIGlmIG5vdCBrbm93bi4KKyAgICAgKgorICAgICAqIEBzZXJpYWwKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IHBvcyA9IC0xOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gOTEzNDU4MzQ0MzUzOTMyMzEyMEw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGFuIEFkZHJlc3NFeGNlcHRpb24gd2l0aCBubyBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQWRkcmVzc0V4Y2VwdGlvbigpIHsKKwlzdXBlcigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYW4gQWRkcmVzc0V4Y2VwdGlvbiB3aXRoIHRoZSBzcGVjaWZpZWQgZGV0YWlsIG1lc3NhZ2UuCisgICAgICogQHBhcmFtIHMJCXRoZSBkZXRhaWwgbWVzc2FnZQorICAgICAqLworICAgIHB1YmxpYyBBZGRyZXNzRXhjZXB0aW9uKFN0cmluZyBzKSB7CisJc3VwZXIocyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhbiBBZGRyZXNzRXhjZXB0aW9uIHdpdGggdGhlIHNwZWNpZmllZCBkZXRhaWwgbWVzc2FnZQorICAgICAqIGFuZCByZWZlcmVuY2UgaW5mby4KKyAgICAgKgorICAgICAqIEBwYXJhbQlzCXRoZSBkZXRhaWwgbWVzc2FnZQorICAgICAqIEBwYXJhbQlyZWYJdGhlIHN0cmluZyBiZWluZyBwYXJzZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgQWRkcmVzc0V4Y2VwdGlvbihTdHJpbmcgcywgU3RyaW5nIHJlZikgeworCXN1cGVyKHMpOworCXRoaXMucmVmID0gcmVmOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYW4gQWRkcmVzc0V4Y2VwdGlvbiB3aXRoIHRoZSBzcGVjaWZpZWQgZGV0YWlsIG1lc3NhZ2UKKyAgICAgKiBhbmQgcmVmZXJlbmNlIGluZm8uCisgICAgICoKKyAgICAgKiBAcGFyYW0Jcwl0aGUgZGV0YWlsIG1lc3NhZ2UKKyAgICAgKiBAcGFyYW0JcmVmCXRoZSBzdHJpbmcgYmVpbmcgcGFyc2VkCisgICAgICogQHBhcmFtCXBvcwl0aGUgcG9zaXRpb24gb2YgdGhlIGVycm9yCisgICAgICovCisgICAgcHVibGljIEFkZHJlc3NFeGNlcHRpb24oU3RyaW5nIHMsIFN0cmluZyByZWYsIGludCBwb3MpIHsKKwlzdXBlcihzKTsKKwl0aGlzLnJlZiA9IHJlZjsKKwl0aGlzLnBvcyA9IHBvczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIHN0cmluZyB0aGF0IHdhcyBiZWluZyBwYXJzZWQgd2hlbiB0aGUgZXJyb3Igd2FzIGRldGVjdGVkCisgICAgICogKG51bGwgaWYgbm90IHJlbGV2YW50KS4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIHN0cmluZyB0aGF0IHdhcyBiZWluZyBwYXJzZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFJlZigpIHsKKwlyZXR1cm4gcmVmOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgcG9zaXRpb24gd2l0aCB0aGUgcmVmZXJlbmNlIHN0cmluZyB3aGVyZSB0aGUgZXJyb3Igd2FzCisgICAgICogZGV0ZWN0ZWQgKC0xIGlmIG5vdCByZWxldmFudCkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBwb3NpdGlvbiB3aXRoaW4gdGhlIHN0cmluZyBvZiB0aGUgZXJyb3IKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFBvcygpIHsKKwlyZXR1cm4gcG9zOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisJU3RyaW5nIHMgPSBzdXBlci50b1N0cmluZygpOworCWlmIChyZWYgPT0gbnVsbCkKKwkgICAgcmV0dXJuIHM7CisJcyArPSAiIGluIHN0cmluZyBgYCIgKyByZWYgKyAiJyciOworCWlmIChwb3MgPCAwKQorCSAgICByZXR1cm4gczsKKwlyZXR1cm4gcyArICIgYXQgcG9zaXRpb24gIiArIHBvczsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9Db250ZW50RGlzcG9zaXRpb24uamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2ludGVybmV0L0NvbnRlbnREaXNwb3NpdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjEyM2ExZWYKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9Db250ZW50RGlzcG9zaXRpb24uamF2YQpAQCAtMCwwICsxLDE4NiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsLmludGVybmV0OworCitpbXBvcnQgamF2YXgubWFpbC4qOworaW1wb3J0IGphdmEudXRpbC4qOworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5Qcm9wVXRpbDsKKworLyoqCisgKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgYSBNSU1FIENvbnRlbnREaXNwb3NpdGlvbiB2YWx1ZS4gSXQgcHJvdmlkZXMKKyAqIG1ldGhvZHMgdG8gcGFyc2UgYSBDb250ZW50RGlzcG9zaXRpb24gc3RyaW5nIGludG8gaW5kaXZpZHVhbCBjb21wb25lbnRzCisgKiBhbmQgdG8gZ2VuZXJhdGUgYSBNSU1FIHN0eWxlIENvbnRlbnREaXNwb3NpdGlvbiBzdHJpbmcuCisgKgorICogQGF1dGhvciAgSm9obiBNYW5pCisgKi8KKworcHVibGljIGNsYXNzIENvbnRlbnREaXNwb3NpdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIGNvbnRlbnREaXNwb3NpdGlvblN0cmljdCA9CisgICAgICAgIFByb3BVdGlsLmdldEJvb2xlYW5TeXN0ZW1Qcm9wZXJ0eSgibWFpbC5taW1lLmNvbnRlbnRkaXNwb3NpdGlvbi5zdHJpY3QiLCB0cnVlKTsKKworICAgIHByaXZhdGUgU3RyaW5nIGRpc3Bvc2l0aW9uOyAvLyBkaXNwb3NpdGlvbgorICAgIHByaXZhdGUgUGFyYW1ldGVyTGlzdCBsaXN0OwkvLyBwYXJhbWV0ZXIgbGlzdAorCisgICAgLyoqCisgICAgICogTm8tYXJnIENvbnN0cnVjdG9yLgorICAgICAqLworICAgIHB1YmxpYyBDb250ZW50RGlzcG9zaXRpb24oKSB7IH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yLgorICAgICAqCisgICAgICogQHBhcmFtCWRpc3Bvc2l0aW9uCWRpc3Bvc2l0aW9uCisgICAgICogQHBhcmFtCWxpc3QJUGFyYW1ldGVyTGlzdAorICAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS4yCisgICAgICovCisgICAgcHVibGljIENvbnRlbnREaXNwb3NpdGlvbihTdHJpbmcgZGlzcG9zaXRpb24sIFBhcmFtZXRlckxpc3QgbGlzdCkgeworCXRoaXMuZGlzcG9zaXRpb24gPSBkaXNwb3NpdGlvbjsKKwl0aGlzLmxpc3QgPSBsaXN0OworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yIHRoYXQgdGFrZXMgYSBDb250ZW50RGlzcG9zaXRpb24gc3RyaW5nLiBUaGUgU3RyaW5nCisgICAgICogaXMgcGFyc2VkIGludG8gaXRzIGNvbnN0aXR1ZW50czogZGlzcG9zdGlvbiBhbmQgcGFyYW1ldGVycy4gCisgICAgICogQSBQYXJzZUV4Y2VwdGlvbiBpcyB0aHJvd24gaWYgdGhlIHBhcnNlIGZhaWxzLiAKKyAgICAgKgorICAgICAqIEBwYXJhbQlzCXRoZSBDb250ZW50RGlzcG9zaXRpb24gc3RyaW5nLgorICAgICAqIEBleGNlcHRpb24JUGFyc2VFeGNlcHRpb24gaWYgdGhlIHBhcnNlIGZhaWxzLgorICAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS4yCisgICAgICovCisgICAgcHVibGljIENvbnRlbnREaXNwb3NpdGlvbihTdHJpbmcgcykgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKKwlIZWFkZXJUb2tlbml6ZXIgaCA9IG5ldyBIZWFkZXJUb2tlbml6ZXIocywgSGVhZGVyVG9rZW5pemVyLk1JTUUpOworCUhlYWRlclRva2VuaXplci5Ub2tlbiB0azsKKworCS8vIEZpcnN0ICJkaXNwb3NpdGlvbiIgLi4KKwl0ayA9IGgubmV4dCgpOworCWlmICh0ay5nZXRUeXBlKCkgIT0gSGVhZGVyVG9rZW5pemVyLlRva2VuLkFUT00pIHsKKyAgICAgICAgICAgIGlmIChjb250ZW50RGlzcG9zaXRpb25TdHJpY3QpIHsKKwkgICAgICAgIHRocm93IG5ldyBQYXJzZUV4Y2VwdGlvbigiRXhwZWN0ZWQgZGlzcG9zaXRpb24sIGdvdCAiICsKKwkJCQkgICAgdGsuZ2V0VmFsdWUoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisJICAgIGRpc3Bvc2l0aW9uID0gdGsuZ2V0VmFsdWUoKTsKKyAgICAgICAgfQorCisJLy8gVGhlbiBwYXJhbWV0ZXJzIC4uCisJU3RyaW5nIHJlbSA9IGguZ2V0UmVtYWluZGVyKCk7CisJaWYgKHJlbSAhPSBudWxsKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGxpc3QgPSBuZXcgUGFyYW1ldGVyTGlzdChyZW0pOworICAgICAgICAgICAgfSBjYXRjaCAoUGFyc2VFeGNlcHRpb24gcHgpIHsKKyAgICAgICAgICAgICAgICBpZiAoY29udGVudERpc3Bvc2l0aW9uU3RyaWN0KSB7CisgICAgICAgICAgICAgICAgICAgIHRocm93IHB4OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgZGlzcG9zaXRpb24gdmFsdWUuCisgICAgICogQHJldHVybiB0aGUgZGlzcG9zaXRpb24KKyAgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuMgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0RGlzcG9zaXRpb24oKSB7CisJcmV0dXJuIGRpc3Bvc2l0aW9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlciB2YWx1ZS4gUmV0dXJucyA8Y29kZT5udWxsPC9jb2RlPgorICAgICAqIGlmIHRoaXMgcGFyYW1ldGVyIGlzIGFic2VudC4KKyAgICAgKgorICAgICAqIEBwYXJhbQluYW1lCXRoZSBwYXJhbWV0ZXIgbmFtZQorICAgICAqIEByZXR1cm4JcGFyYW1ldGVyIHZhbHVlCisgICAgICogQHNpbmNlCQlKYXZhTWFpbCAxLjIKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFBhcmFtZXRlcihTdHJpbmcgbmFtZSkgeworCWlmIChsaXN0ID09IG51bGwpCisJICAgIHJldHVybiBudWxsOworCisJcmV0dXJuIGxpc3QuZ2V0KG5hbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiBhIFBhcmFtZXRlckxpc3Qgb2JqZWN0IHRoYXQgaG9sZHMgYWxsIHRoZSBhdmFpbGFibGUgCisgICAgICogcGFyYW1ldGVycy4gUmV0dXJucyBudWxsIGlmIG5vIHBhcmFtZXRlcnMgYXJlIGF2YWlsYWJsZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4JUGFyYW1ldGVyTGlzdAorICAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS4yCisgICAgICovCisgICAgcHVibGljIFBhcmFtZXRlckxpc3QgZ2V0UGFyYW1ldGVyTGlzdCgpIHsKKwlyZXR1cm4gbGlzdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIGRpc3Bvc2l0aW9uLiAgUmVwbGFjZXMgdGhlIGV4aXN0aW5nIGRpc3Bvc2l0aW9uLgorICAgICAqIEBwYXJhbQlkaXNwb3NpdGlvbgl0aGUgZGlzcG9zaXRpb24KKyAgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuMgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldERpc3Bvc2l0aW9uKFN0cmluZyBkaXNwb3NpdGlvbikgeworCXRoaXMuZGlzcG9zaXRpb24gPSBkaXNwb3NpdGlvbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXIuIElmIHRoaXMgcGFyYW1ldGVyIGFscmVhZHkgZXhpc3RzLAorICAgICAqIGl0IGlzIHJlcGxhY2VkIGJ5IHRoaXMgbmV3IHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtCW5hbWUJcGFyYW1ldGVyIG5hbWUKKyAgICAgKiBAcGFyYW0JdmFsdWUJcGFyYW1ldGVyIHZhbHVlCisgICAgICogQHNpbmNlCQlKYXZhTWFpbCAxLjIKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRQYXJhbWV0ZXIoU3RyaW5nIG5hbWUsIFN0cmluZyB2YWx1ZSkgeworCWlmIChsaXN0ID09IG51bGwpCisJICAgIGxpc3QgPSBuZXcgUGFyYW1ldGVyTGlzdCgpOworCisJbGlzdC5zZXQobmFtZSwgdmFsdWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCBhIG5ldyBQYXJhbWV0ZXJMaXN0LgorICAgICAqIEBwYXJhbQlsaXN0CVBhcmFtZXRlckxpc3QKKyAgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuMgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFBhcmFtZXRlckxpc3QoUGFyYW1ldGVyTGlzdCBsaXN0KSB7CisJdGhpcy5saXN0ID0gbGlzdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZSBhIFJGQzIwNDUgc3R5bGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mCisgICAgICogdGhpcyBDb250ZW50RGlzcG9zaXRpb24uIFJldHVybnMgYW4gZW1wdHkgc3RyaW5nIGlmCisgICAgICogdGhlIGNvbnZlcnNpb24gZmFpbGVkLgorICAgICAqCisgICAgICogQHJldHVybglSRkMyMDQ1IHN0eWxlIHN0cmluZworICAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS4yCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKwlpZiAoZGlzcG9zaXRpb24gPT0gbnVsbCkKKwkgICAgcmV0dXJuICIiOworCisJaWYgKGxpc3QgPT0gbnVsbCkKKwkgICAgcmV0dXJuIGRpc3Bvc2l0aW9uOworCisJU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKGRpc3Bvc2l0aW9uKTsKKworICAgICAgICAvLyBhcHBlbmQgdGhlIHBhcmFtZXRlciBsaXN0ICAKKyAgICAgICAgLy8gdXNlIHRoZSBsZW5ndGggb2YgdGhlIHN0cmluZyBidWZmZXIgKyB0aGUgbGVuZ3RoIG9mIAorICAgICAgICAvLyB0aGUgaGVhZGVyIG5hbWUgZm9ybWF0dGVkIGFzIGZvbGxvd3MgIkNvbnRlbnQtRGlzcG9zaXRpb246ICIKKwlzYi5hcHBlbmQobGlzdC50b1N0cmluZyhzYi5sZW5ndGgoKSArIDIxKSk7CisJcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvQ29udGVudFR5cGUuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2ludGVybmV0L0NvbnRlbnRUeXBlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjAwNWQyZgotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2ludGVybmV0L0NvbnRlbnRUeXBlLmphdmEKQEAgLTAsMCArMSwyNzQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5pbnRlcm5ldDsKKworaW1wb3J0IGphdmF4Lm1haWwuKjsKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBqYXZhLmlvLio7CisKKy8qKgorICogVGhpcyBjbGFzcyByZXByZXNlbnRzIGEgTUlNRSBDb250ZW50LVR5cGUgdmFsdWUuIEl0IHByb3ZpZGVzCisgKiBtZXRob2RzIHRvIHBhcnNlIGEgQ29udGVudC1UeXBlIHN0cmluZyBpbnRvIGluZGl2aWR1YWwgY29tcG9uZW50cworICogYW5kIHRvIGdlbmVyYXRlIGEgTUlNRSBzdHlsZSBDb250ZW50LVR5cGUgc3RyaW5nLgorICoKKyAqIEBhdXRob3IgIEpvaG4gTWFuaQorICovCisKK3B1YmxpYyBjbGFzcyBDb250ZW50VHlwZSB7CisKKyAgICBwcml2YXRlIFN0cmluZyBwcmltYXJ5VHlwZTsJLy8gcHJpbWFyeSB0eXBlCisgICAgcHJpdmF0ZSBTdHJpbmcgc3ViVHlwZTsJLy8gc3VidHlwZQorICAgIHByaXZhdGUgUGFyYW1ldGVyTGlzdCBsaXN0OwkvLyBwYXJhbWV0ZXIgbGlzdAorCisgICAgLyoqCisgICAgICogTm8tYXJnIENvbnN0cnVjdG9yLgorICAgICAqLworICAgIHB1YmxpYyBDb250ZW50VHlwZSgpIHsgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0JcHJpbWFyeVR5cGUJcHJpbWFyeSB0eXBlCisgICAgICogQHBhcmFtCXN1YlR5cGUJc3ViVHlwZQorICAgICAqIEBwYXJhbQlsaXN0CVBhcmFtZXRlckxpc3QKKyAgICAgKi8KKyAgICBwdWJsaWMgQ29udGVudFR5cGUoU3RyaW5nIHByaW1hcnlUeXBlLCBTdHJpbmcgc3ViVHlwZSwgCisJCQlQYXJhbWV0ZXJMaXN0IGxpc3QpIHsKKwl0aGlzLnByaW1hcnlUeXBlID0gcHJpbWFyeVR5cGU7CisJdGhpcy5zdWJUeXBlID0gc3ViVHlwZTsKKwl0aGlzLmxpc3QgPSBsaXN0OworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yIHRoYXQgdGFrZXMgYSBDb250ZW50LVR5cGUgc3RyaW5nLiBUaGUgU3RyaW5nCisgICAgICogaXMgcGFyc2VkIGludG8gaXRzIGNvbnN0aXR1ZW50czogcHJpbWFyeVR5cGUsIHN1YlR5cGUKKyAgICAgKiBhbmQgcGFyYW1ldGVycy4gQSBQYXJzZUV4Y2VwdGlvbiBpcyB0aHJvd24gaWYgdGhlIHBhcnNlIGZhaWxzLiAKKyAgICAgKgorICAgICAqIEBwYXJhbQlzCXRoZSBDb250ZW50LVR5cGUgc3RyaW5nLgorICAgICAqIEBleGNlcHRpb24JUGFyc2VFeGNlcHRpb24gaWYgdGhlIHBhcnNlIGZhaWxzLgorICAgICAqLworICAgIHB1YmxpYyBDb250ZW50VHlwZShTdHJpbmcgcykgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKKwlIZWFkZXJUb2tlbml6ZXIgaCA9IG5ldyBIZWFkZXJUb2tlbml6ZXIocywgSGVhZGVyVG9rZW5pemVyLk1JTUUpOworCUhlYWRlclRva2VuaXplci5Ub2tlbiB0azsKKworCS8vIEZpcnN0ICJ0eXBlIiAuLgorCXRrID0gaC5uZXh0KCk7CisJaWYgKHRrLmdldFR5cGUoKSAhPSBIZWFkZXJUb2tlbml6ZXIuVG9rZW4uQVRPTSkKKwkgICAgdGhyb3cgbmV3IFBhcnNlRXhjZXB0aW9uKCJJbiBDb250ZW50LVR5cGUgc3RyaW5nIDwiICsgcyArICI+IiArCisJCQkJCSIsIGV4cGVjdGVkIE1JTUUgdHlwZSwgZ290ICIgKworCQkJCQl0ay5nZXRWYWx1ZSgpKTsKKwlwcmltYXJ5VHlwZSA9IHRrLmdldFZhbHVlKCk7CisKKwkvLyBUaGUgJy8nIHNlcGFyYXRvciAuLgorCXRrID0gaC5uZXh0KCk7CisJaWYgKChjaGFyKXRrLmdldFR5cGUoKSAhPSAnLycpCisJICAgIHRocm93IG5ldyBQYXJzZUV4Y2VwdGlvbigiSW4gQ29udGVudC1UeXBlIHN0cmluZyA8IiArIHMgKyAiPiIgKworCQkJCSIsIGV4cGVjdGVkICcvJywgZ290ICIgKyB0ay5nZXRWYWx1ZSgpKTsKKworCS8vIFRoZW4gInN1YlR5cGUiIC4uCisJdGsgPSBoLm5leHQoKTsKKwlpZiAodGsuZ2V0VHlwZSgpICE9IEhlYWRlclRva2VuaXplci5Ub2tlbi5BVE9NKQorCSAgICB0aHJvdyBuZXcgUGFyc2VFeGNlcHRpb24oIkluIENvbnRlbnQtVHlwZSBzdHJpbmcgPCIgKyBzICsgIj4iICsKKwkJCQkJIiwgZXhwZWN0ZWQgTUlNRSBzdWJ0eXBlLCBnb3QgIiArCisJCQkJCXRrLmdldFZhbHVlKCkpOworCXN1YlR5cGUgPSB0ay5nZXRWYWx1ZSgpOworCisJLy8gRmluYWxseSBwYXJhbWV0ZXJzIC4uCisJU3RyaW5nIHJlbSA9IGguZ2V0UmVtYWluZGVyKCk7CisJaWYgKHJlbSAhPSBudWxsKQorCSAgICBsaXN0ID0gbmV3IFBhcmFtZXRlckxpc3QocmVtKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIHByaW1hcnkgdHlwZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBwcmltYXJ5IHR5cGUKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFByaW1hcnlUeXBlKCkgeworCXJldHVybiBwcmltYXJ5VHlwZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIHN1YlR5cGUuCisgICAgICogQHJldHVybiB0aGUgc3ViVHlwZQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3ViVHlwZSgpIHsKKwlyZXR1cm4gc3ViVHlwZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIE1JTUUgdHlwZSBzdHJpbmcsIHdpdGhvdXQgdGhlIHBhcmFtZXRlcnMuCisgICAgICogVGhlIHJldHVybmVkIHZhbHVlIGlzIGJhc2ljYWxseSB0aGUgY29uY2F0ZW5hdGlvbiBvZgorICAgICAqIHRoZSBwcmltYXJ5VHlwZSwgdGhlICcvJyBjaGFyYWN0ZXIgYW5kIHRoZSBzZWNvbmRhcnlUeXBlLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgdHlwZQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0QmFzZVR5cGUoKSB7CisJaWYgKHByaW1hcnlUeXBlID09IG51bGwgfHwgc3ViVHlwZSA9PSBudWxsKQorCSAgICByZXR1cm4gIiI7CisJcmV0dXJuIHByaW1hcnlUeXBlICsgJy8nICsgc3ViVHlwZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXIgdmFsdWUuIFJldHVybnMgPGNvZGU+bnVsbDwvY29kZT4KKyAgICAgKiBpZiB0aGlzIHBhcmFtZXRlciBpcyBhYnNlbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0JbmFtZQl0aGUgcGFyYW1ldGVyIG5hbWUKKyAgICAgKiBAcmV0dXJuCXBhcmFtZXRlciB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UGFyYW1ldGVyKFN0cmluZyBuYW1lKSB7CisJaWYgKGxpc3QgPT0gbnVsbCkKKwkgICAgcmV0dXJuIG51bGw7CisKKwlyZXR1cm4gbGlzdC5nZXQobmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIGEgUGFyYW1ldGVyTGlzdCBvYmplY3QgdGhhdCBob2xkcyBhbGwgdGhlIGF2YWlsYWJsZSAKKyAgICAgKiBwYXJhbWV0ZXJzLiBSZXR1cm5zIG51bGwgaWYgbm8gcGFyYW1ldGVycyBhcmUgYXZhaWxhYmxlLgorICAgICAqCisgICAgICogQHJldHVybglQYXJhbWV0ZXJMaXN0CisgICAgICovCisgICAgcHVibGljIFBhcmFtZXRlckxpc3QgZ2V0UGFyYW1ldGVyTGlzdCgpIHsKKwlyZXR1cm4gbGlzdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHByaW1hcnkgdHlwZS4gT3ZlcnJpZGVzIGV4aXN0aW5nIHByaW1hcnkgdHlwZS4KKyAgICAgKiBAcGFyYW0JcHJpbWFyeVR5cGUJcHJpbWFyeSB0eXBlCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UHJpbWFyeVR5cGUoU3RyaW5nIHByaW1hcnlUeXBlKSB7CisJdGhpcy5wcmltYXJ5VHlwZSA9IHByaW1hcnlUeXBlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgc3ViVHlwZS4gIFJlcGxhY2VzIHRoZSBleGlzdGluZyBzdWJUeXBlLgorICAgICAqIEBwYXJhbQlzdWJUeXBlCXRoZSBzdWJUeXBlCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U3ViVHlwZShTdHJpbmcgc3ViVHlwZSkgeworCXRoaXMuc3ViVHlwZSA9IHN1YlR5cGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyLiBJZiB0aGlzIHBhcmFtZXRlciBhbHJlYWR5IGV4aXN0cywKKyAgICAgKiBpdCBpcyByZXBsYWNlZCBieSB0aGlzIG5ldyB2YWx1ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbQluYW1lCXBhcmFtZXRlciBuYW1lCisgICAgICogQHBhcmFtCXZhbHVlCXBhcmFtZXRlciB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFBhcmFtZXRlcihTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKSB7CisJaWYgKGxpc3QgPT0gbnVsbCkKKwkgICAgbGlzdCA9IG5ldyBQYXJhbWV0ZXJMaXN0KCk7CisKKwlsaXN0LnNldChuYW1lLCB2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IGEgbmV3IFBhcmFtZXRlckxpc3QuCisgICAgICogQHBhcmFtCWxpc3QJUGFyYW1ldGVyTGlzdAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFBhcmFtZXRlckxpc3QoUGFyYW1ldGVyTGlzdCBsaXN0KSB7CisJdGhpcy5saXN0ID0gbGlzdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXRyaWV2ZSBhIFJGQzIwNDUgc3R5bGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mCisgICAgICogdGhpcyBDb250ZW50LVR5cGUuIFJldHVybnMgYW4gZW1wdHkgc3RyaW5nIGlmCisgICAgICogdGhlIGNvbnZlcnNpb24gZmFpbGVkLgorICAgICAqCisgICAgICogQHJldHVybglSRkMyMDQ1IHN0eWxlIHN0cmluZworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisJaWYgKHByaW1hcnlUeXBlID09IG51bGwgfHwgc3ViVHlwZSA9PSBudWxsKSAvLyBuZWVkIGJvdGgKKwkgICAgcmV0dXJuICIiOworCisJU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisJc2IuYXBwZW5kKHByaW1hcnlUeXBlKS5hcHBlbmQoJy8nKS5hcHBlbmQoc3ViVHlwZSk7CisJaWYgKGxpc3QgIT0gbnVsbCkKKyAgICAgICAgICAgIC8vIGFwcGVuZCB0aGUgcGFyYW1ldGVyIGxpc3QgCisgICAgICAgICAgICAvLyB1c2UgdGhlIGxlbmd0aCBvZiB0aGUgc3RyaW5nIGJ1ZmZlciArIHRoZSBsZW5ndGggb2YKKyAgICAgICAgICAgIC8vIHRoZSBoZWFkZXIgbmFtZSBmb3JtYXR0ZWQgYXMgZm9sbG93cyAiQ29udGVudC1UeXBlOiAiCisJICAgIHNiLmFwcGVuZChsaXN0LnRvU3RyaW5nKHNiLmxlbmd0aCgpICsgMTQpKTsKKwkKKwlyZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNYXRjaCB3aXRoIHRoZSBzcGVjaWZpZWQgQ29udGVudFR5cGUgb2JqZWN0LiBUaGlzIG1ldGhvZAorICAgICAqIGNvbXBhcmVzIDxzdHJvbmc+b25seSB0aGUgPGNvZGU+cHJpbWFyeVR5cGU8L2NvZGU+IGFuZCAKKyAgICAgKiA8Y29kZT5zdWJUeXBlPC9jb2RlPiA8L3N0cm9uZz4uIFRoZSBwYXJhbWV0ZXJzIG9mIGJvdGggb3BlcmFuZHMKKyAgICAgKiBhcmUgaWdub3JlZC4gPHA+CisgICAgICoKKyAgICAgKiBGb3IgZXhhbXBsZSwgdGhpcyBtZXRob2Qgd2lsbCByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gd2hlbgorICAgICAqIGNvbXBhcmluZyB0aGUgQ29udGVudFR5cGVzIGZvciA8c3Ryb25nPiJ0ZXh0L3BsYWluIjwvc3Ryb25nPgorICAgICAqIGFuZCA8c3Ryb25nPiJ0ZXh0L3BsYWluOyBjaGFyc2V0PWZvb2JhciI8L3N0cm9uZz4uCisgICAgICoKKyAgICAgKiBJZiB0aGUgPGNvZGU+c3ViVHlwZTwvY29kZT4gb2YgZWl0aGVyIG9wZXJhbmQgaXMgdGhlIHNwZWNpYWwKKyAgICAgKiBjaGFyYWN0ZXIgJyonLCB0aGVuIHRoZSBzdWJ0eXBlIGlzIGlnbm9yZWQgZHVyaW5nIHRoZSBtYXRjaC4gCisgICAgICogRm9yIGV4YW1wbGUsIHRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IHdoZW4gCisgICAgICogY29tcGFyaW5nIHRoZSBDb250ZW50VHlwZXMgZm9yIDxzdHJvbmc+InRleHQvcGxhaW4iPC9zdHJvbmc+IAorICAgICAqIGFuZCA8c3Ryb25nPiJ0ZXh0LyoiIDwvc3Ryb25nPgorICAgICAqCisgICAgICogQHBhcmFtICAgY1R5cGUJQ29udGVudFR5cGUgdG8gY29tcGFyZSB0aGlzIGFnYWluc3QKKyAgICAgKiBAcmV0dXJuCXRydWUgaWYgaXQgbWF0Y2hlcworICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIG1hdGNoKENvbnRlbnRUeXBlIGNUeXBlKSB7CisJLy8gTWF0Y2ggcHJpbWFyeVR5cGUKKwlpZiAoISgocHJpbWFyeVR5cGUgPT0gbnVsbCAmJiBjVHlwZS5nZXRQcmltYXJ5VHlwZSgpID09IG51bGwpIHx8CisJCShwcmltYXJ5VHlwZSAhPSBudWxsICYmCisJCSAgICBwcmltYXJ5VHlwZS5lcXVhbHNJZ25vcmVDYXNlKGNUeXBlLmdldFByaW1hcnlUeXBlKCkpKSkpCisJICAgIHJldHVybiBmYWxzZTsKKwkKKwlTdHJpbmcgc1R5cGUgPSBjVHlwZS5nZXRTdWJUeXBlKCk7CisKKwkvLyBJZiBlaXRoZXIgb25lIG9mIHRoZSBzdWJUeXBlcyBpcyB3aWxkY2FyZGVkLCByZXR1cm4gdHJ1ZQorCWlmICgoc3ViVHlwZSAhPSBudWxsICYmIHN1YlR5cGUuc3RhcnRzV2l0aCgiKiIpKSB8fAorCSAgICAoc1R5cGUgIT0gbnVsbCAmJiBzVHlwZS5zdGFydHNXaXRoKCIqIikpKQorCSAgICByZXR1cm4gdHJ1ZTsKKwkKKwkvLyBNYXRjaCBzdWJUeXBlCisJcmV0dXJuIChzdWJUeXBlID09IG51bGwgJiYgc1R5cGUgPT0gbnVsbCkgfHwKKwkgICAgKHN1YlR5cGUgIT0gbnVsbCAmJiBzdWJUeXBlLmVxdWFsc0lnbm9yZUNhc2Uoc1R5cGUpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNYXRjaCB3aXRoIHRoZSBzcGVjaWZpZWQgY29udGVudC10eXBlIHN0cmluZy4gVGhpcyBtZXRob2QKKyAgICAgKiBjb21wYXJlcyA8c3Ryb25nPm9ubHkgdGhlIDxjb2RlPnByaW1hcnlUeXBlPC9jb2RlPiBhbmQgCisgICAgICogPGNvZGU+c3ViVHlwZTwvY29kZT4gPC9zdHJvbmc+LgorICAgICAqIFRoZSBwYXJhbWV0ZXJzIG9mIGJvdGggb3BlcmFuZHMgYXJlIGlnbm9yZWQuIDxwPgorICAgICAqCisgICAgICogRm9yIGV4YW1wbGUsIHRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IHdoZW4KKyAgICAgKiBjb21wYXJpbmcgdGhlIENvbnRlbnRUeXBlIGZvciA8c3Ryb25nPiJ0ZXh0L3BsYWluIjwvc3Ryb25nPgorICAgICAqIHdpdGggPHN0cm9uZz4idGV4dC9wbGFpbjsgY2hhcnNldD1mb29iYXIiPC9zdHJvbmc+LgorICAgICAqCisgICAgICogSWYgdGhlIDxjb2RlPnN1YlR5cGU8L2NvZGU+IG9mIGVpdGhlciBvcGVyYW5kIGlzIHRoZSBzcGVjaWFsIAorICAgICAqIGNoYXJhY3RlciAnKicsIHRoZW4gdGhlIHN1YnR5cGUgaXMgaWdub3JlZCBkdXJpbmcgdGhlIG1hdGNoLiAKKyAgICAgKiBGb3IgZXhhbXBsZSwgdGhpcyBtZXRob2Qgd2lsbCByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gd2hlbiAKKyAgICAgKiBjb21wYXJpbmcgdGhlIENvbnRlbnRUeXBlIGZvciA8c3Ryb25nPiJ0ZXh0L3BsYWluIjwvc3Ryb25nPiAKKyAgICAgKiB3aXRoIDxzdHJvbmc+InRleHQvKiIgPC9zdHJvbmc+CisgICAgICoKKyAgICAgKiBAcGFyYW0Jcwl0aGUgY29udGVudC10eXBlIHN0cmluZyB0byBtYXRjaAorICAgICAqIEByZXR1cm4JdHJ1ZSBpZiBpdCBtYXRjaGVzCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gbWF0Y2goU3RyaW5nIHMpIHsKKwl0cnkgeworCSAgICByZXR1cm4gbWF0Y2gobmV3IENvbnRlbnRUeXBlKHMpKTsKKwl9IGNhdGNoIChQYXJzZUV4Y2VwdGlvbiBwZXgpIHsKKwkgICAgcmV0dXJuIGZhbHNlOworCX0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9IZWFkZXJUb2tlbml6ZXIuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2ludGVybmV0L0hlYWRlclRva2VuaXplci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU1YmFmZTMKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9IZWFkZXJUb2tlbml6ZXIuamF2YQpAQCAtMCwwICsxLDQ3MSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsLmludGVybmV0OworCitpbXBvcnQgamF2YS51dGlsLio7CisKKy8qKgorICogVGhpcyBjbGFzcyB0b2tlbml6ZXMgUkZDODIyIGFuZCBNSU1FIGhlYWRlcnMgaW50byB0aGUgYmFzaWMKKyAqIHN5bWJvbHMgc3BlY2lmaWVkIGJ5IFJGQzgyMiBhbmQgTUlNRS4gPHA+CisgKgorICogVGhpcyBjbGFzcyBoYW5kbGVzIGZvbGRlZCBoZWFkZXJzIChpZSBoZWFkZXJzIHdpdGggZW1iZWRkZWQKKyAqIENSTEYgU1BBQ0Ugc2VxdWVuY2VzKS4gVGhlIGZvbGRzIGFyZSByZW1vdmVkIGluIHRoZSByZXR1cm5lZAorICogdG9rZW5zLiAKKyAqCisgKiBAYXV0aG9yICBKb2huIE1hbmkKKyAqIEBhdXRob3IgIEJpbGwgU2hhbm5vbgorICovCisKK3B1YmxpYyBjbGFzcyBIZWFkZXJUb2tlbml6ZXIgeworCisgICAgLyoqCisgICAgICogVGhlIFRva2VuIGNsYXNzIHJlcHJlc2VudHMgdG9rZW5zIHJldHVybmVkIGJ5IHRoZSAKKyAgICAgKiBIZWFkZXJUb2tlbml6ZXIuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBUb2tlbiB7CisKKwlwcml2YXRlIGludCB0eXBlOworCXByaXZhdGUgU3RyaW5nIHZhbHVlOworCisJLyoqCisJICogVG9rZW4gdHlwZSBpbmRpY2F0aW5nIGFuIEFUT00uCisJICovCisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQVRPTSAJCT0gLTE7CisKKwkvKioKKwkgKiBUb2tlbiB0eXBlIGluZGljYXRpbmcgYSBxdW90ZWQgc3RyaW5nLiBUaGUgdmFsdWUgCisJICogZmllbGQgY29udGFpbnMgdGhlIHN0cmluZyB3aXRob3V0IHRoZSBxdW90ZXMuCisgCSAqLworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFFVT1RFRFNUUklORyAJPSAtMjsKKworCS8qKgorCSAqIFRva2VuIHR5cGUgaW5kaWNhdGluZyBhIGNvbW1lbnQuIFRoZSB2YWx1ZSBmaWVsZCAKKwkgKiBjb250YWlucyB0aGUgY29tbWVudCBzdHJpbmcgd2l0aG91dCB0aGUgY29tbWVudCAKKwkgKiBzdGFydCBhbmQgZW5kIHN5bWJvbHMuCisJICovCisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ09NTUVOVAkJPSAtMzsKKworCS8qKgorCSAqIFRva2VuIHR5cGUgaW5kaWNhdGluZyBlbmQgb2YgaW5wdXQuCisJICovCisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgIEVPRiAJCT0gLTQ7CisKKwkvKioKKwkgKiBDb25zdHJ1Y3Rvci4KKwkgKiBAcGFyYW0JdHlwZQlUb2tlbiB0eXBlCisJICogQHBhcmFtCXZhbHVlCVRva2VuIHZhbHVlCisJICovCisJcHVibGljIFRva2VuKGludCB0eXBlLCBTdHJpbmcgdmFsdWUpIHsKKwkgICAgIHRoaXMudHlwZSA9IHR5cGU7CisJICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CisJfQorCisJLyoqCisJICogUmV0dXJuIHRoZSB0eXBlIG9mIHRoZSB0b2tlbi4gSWYgdGhlIHRva2VuIHJlcHJlc2VudHMgYQorCSAqIGRlbGltaXRlciBvciBhIGNvbnRyb2wgY2hhcmFjdGVyLCB0aGUgdHlwZSBpcyB0aGF0IGNoYXJhY3RlcgorCSAqIGl0c2VsZiwgY29udmVydGVkIHRvIGFuIGludGVnZXIuIE90aGVyd2lzZSwgaXQncyB2YWx1ZSBpcyAKKwkgKiBvbmUgb2YgdGhlIGZvbGxvd2luZzoKKwkgKiA8dWw+CisJICogPGxpPjxjb2RlPkFUT008L2NvZGU+IEEgc2VxdWVuY2Ugb2YgQVNDSUkgY2hhcmFjdGVycyAKKwkgKglkZWxpbWl0ZWQgYnkgZWl0aGVyIFNQQUNFLCBDVEwsICIoIiwgJmx0OyImZ3Q7IG9yIHRoZSAKKwkgKglzcGVjaWZpZWQgU1BFQ0lBTFMKKwkgKiA8bGk+PGNvZGU+UVVPVEVEU1RSSU5HPC9jb2RlPiBBIHNlcXVlbmNlIG9mIEFTQ0lJIGNoYXJhY3RlcnMKKwkgKgl3aXRoaW4gcXVvdGVzCisJICogPGxpPjxjb2RlPkNPTU1FTlQ8L2NvZGU+IEEgc2VxdWVuY2Ugb2YgQVNDSUkgY2hhcmFjdGVycyAKKwkgKgl3aXRoaW4gIigiIGFuZCAiKSIuCisJICogPGxpPjxjb2RlPkVPRjwvY29kZT4gRW5kIG9mIGhlYWRlcgorCSAqIDwvdWw+CisJICoKKwkgKiBAcmV0dXJuCXRoZSB0b2tlbiB0eXBlCisJICovCisJcHVibGljIGludCBnZXRUeXBlKCkgeworCSAgICByZXR1cm4gdHlwZTsKKwl9CisKKwkvKioKKwkgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgdG9rZW4ganVzdCByZWFkLiBXaGVuIHRoZSBjdXJyZW50CisJICogdG9rZW4gaXMgYSBxdW90ZWQgc3RyaW5nLCB0aGlzIGZpZWxkIGNvbnRhaW5zIHRoZSBib2R5IG9mIHRoZQorCSAqIHN0cmluZywgd2l0aG91dCB0aGUgcXVvdGVzLiBXaGVuIHRoZSBjdXJyZW50IHRva2VuIGlzIGEgY29tbWVudCwKKwkgKiB0aGlzIGZpZWxkIGNvbnRhaW5zIHRoZSBib2R5IG9mIHRoZSBjb21tZW50LgorCSAqCisJICogQHJldHVybgl0b2tlbiB2YWx1ZQorCSAqLworCXB1YmxpYyBTdHJpbmcgZ2V0VmFsdWUoKSB7CisJICAgIHJldHVybiB2YWx1ZTsKKwl9CisgICAgfQorCisgICAgcHJpdmF0ZSBTdHJpbmcgc3RyaW5nOyAvLyB0aGUgc3RyaW5nIHRvIGJlIHRva2VuaXplZAorICAgIHByaXZhdGUgYm9vbGVhbiBza2lwQ29tbWVudHM7IC8vIHNob3VsZCBjb21tZW50cyBiZSBza2lwcGVkID8KKyAgICBwcml2YXRlIFN0cmluZyBkZWxpbWl0ZXJzOyAvLyBkZWxpbWl0ZXIgc3RyaW5nCisgICAgcHJpdmF0ZSBpbnQgY3VycmVudFBvczsgLy8gY3VycmVudCBwYXJzZSBwb3NpdGlvbgorICAgIHByaXZhdGUgaW50IG1heFBvczsgLy8gc3RyaW5nIGxlbmd0aAorICAgIHByaXZhdGUgaW50IG5leHRQb3M7IC8vIHRyYWNrIHN0YXJ0IG9mIG5leHQgVG9rZW4gZm9yIG5leHQoKQorICAgIHByaXZhdGUgaW50IHBlZWtQb3M7IC8vIHRyYWNrIHN0YXJ0IG9mIG5leHQgVG9rZW4gZm9yIHBlZWsoKQorCisgICAgLyoqCisgICAgICogUkZDODIyIHNwZWNpYWxzCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHN0YXRpYyBTdHJpbmcgUkZDODIyID0gIigpPD5ALDs6XFxcIlx0IC5bXSI7CisKKyAgICAvKioKKyAgICAgKiBNSU1FIHNwZWNpYWxzCisgICAgICovCisgICAgcHVibGljIGZpbmFsIHN0YXRpYyBTdHJpbmcgTUlNRSA9ICIoKTw+QCw7OlxcXCJcdCBbXS8/PSI7CisKKyAgICAvLyBUaGUgRU9GIFRva2VuCisgICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgVG9rZW4gRU9GVG9rZW4gPSBuZXcgVG9rZW4oVG9rZW4uRU9GLCBudWxsKTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yIHRoYXQgdGFrZXMgYSByZmM4MjIgc3R5bGUgaGVhZGVyLgorICAgICAqCisgICAgICogQHBhcmFtCWhlYWRlcglUaGUgcmZjODIyIGhlYWRlciB0byBiZSB0b2tlbml6ZWQKKyAgICAgKiBAcGFyYW0JZGVsaW1pdGVycyAgICAgIFNldCBvZiBkZWxpbWl0ZXIgY2hhcmFjdGVycyAKKyAgICAgKgkJCQl0byBiZSB1c2VkIHRvIGRlbGltaXQgQVRPTVMuIFRoZXNlCisgICAgICoJCQkJYXJlIHVzdWFsbHkgPGNvZGU+UkZDODIyPC9jb2RlPiBvciAKKyAgICAgKgkJCQk8Y29kZT5NSU1FPC9jb2RlPgorICAgICAqIEBwYXJhbSAgIHNraXBDb21tZW50cyAgSWYgdHJ1ZSwgY29tbWVudHMgYXJlIHNraXBwZWQgYW5kCisgICAgICoJCQkJbm90IHJldHVybmVkIGFzIHRva2VucworICAgICAqLworICAgIHB1YmxpYyBIZWFkZXJUb2tlbml6ZXIoU3RyaW5nIGhlYWRlciwgU3RyaW5nIGRlbGltaXRlcnMsCisgICAgCQkJICAgYm9vbGVhbiBza2lwQ29tbWVudHMpIHsKKwlzdHJpbmcgPSAoaGVhZGVyID09IG51bGwpID8gIiIgOiBoZWFkZXI7IC8vIHBhcmFub2lhID8hCisJdGhpcy5za2lwQ29tbWVudHMgPSBza2lwQ29tbWVudHM7CisJdGhpcy5kZWxpbWl0ZXJzID0gZGVsaW1pdGVyczsKKwljdXJyZW50UG9zID0gbmV4dFBvcyA9IHBlZWtQb3MgPSAwOworCW1heFBvcyA9IHN0cmluZy5sZW5ndGgoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3Rvci4gQ29tbWVudHMgYXJlIGlnbm9yZWQgYW5kIG5vdCByZXR1cm5lZCBhcyB0b2tlbnMKKyAgICAgKgorICAgICAqIEBwYXJhbQloZWFkZXIgIFRoZSBoZWFkZXIgdGhhdCBpcyB0b2tlbml6ZWQKKyAgICAgKiBAcGFyYW0JZGVsaW1pdGVycyAgVGhlIGRlbGltaXRlcnMgdG8gYmUgdXNlZAorICAgICAqLworICAgIHB1YmxpYyBIZWFkZXJUb2tlbml6ZXIoU3RyaW5nIGhlYWRlciwgU3RyaW5nIGRlbGltaXRlcnMpIHsKKwl0aGlzKGhlYWRlciwgZGVsaW1pdGVycywgdHJ1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IuIFRoZSBSRkM4MjIgZGVmaW5lZCBkZWxpbWl0ZXJzIC0gUkZDODIyIC0gYXJlCisgICAgICogdXNlZCB0byBkZWxpbWl0IEFUT01TLiBBbHNvIGNvbW1lbnRzIGFyZSBza2lwcGVkIGFuZCBub3QKKyAgICAgKiByZXR1cm5lZCBhcyB0b2tlbnMKKyAgICAgKgorICAgICAqIEBwYXJhbQloZWFkZXIJdGhlIGhlYWRlciBzdHJpbmcKKyAgICAgKi8KKyAgICBwdWJsaWMgSGVhZGVyVG9rZW5pemVyKFN0cmluZyBoZWFkZXIpICB7CisJdGhpcyhoZWFkZXIsIFJGQzgyMik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2VzIHRoZSBuZXh0IHRva2VuIGZyb20gdGhpcyBTdHJpbmcuIDxwPgorICAgICAqCisgICAgICogQ2xpZW50cyBzaXQgaW4gYSBsb29wIGNhbGxpbmcgbmV4dCgpIHRvIHBhcnNlIHN1Y2Nlc3NpdmUKKyAgICAgKiB0b2tlbnMgdW50aWwgYW4gRU9GIFRva2VuIGlzIHJldHVybmVkLgorICAgICAqCisgICAgICogQHJldHVybgkJdGhlIG5leHQgVG9rZW4KKyAgICAgKiBAZXhjZXB0aW9uCVBhcnNlRXhjZXB0aW9uIGlmIHRoZSBwYXJzZSBmYWlscworICAgICAqLworICAgIHB1YmxpYyBUb2tlbiBuZXh0KCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsgCisJcmV0dXJuIG5leHQoJ1wwJywgZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlcyB0aGUgbmV4dCB0b2tlbiBmcm9tIHRoaXMgU3RyaW5nLgorICAgICAqIElmIGVuZE9mQXRvbSBpcyBub3QgTlVMLCB0aGUgdG9rZW4gZXh0ZW5kcyB1bnRpbCB0aGUKKyAgICAgKiBlbmRPZkF0b20gY2hhcmFjdGVyIGlzIHNlZW4sIG9yIHRvIHRoZSBlbmQgb2YgdGhlIGhlYWRlci4KKyAgICAgKiBUaGlzIG1ldGhvZCBpcyB1c2VmdWwgd2hlbiBwYXJzaW5nIGhlYWRlcnMgdGhhdCBkb24ndAorICAgICAqIG9iZXkgdGhlIE1JTUUgc3BlY2lmaWNhdGlvbiwgZS5nLiwgYnkgZmFpbGluZyB0byBxdW90ZQorICAgICAqIHBhcmFtZXRlciB2YWx1ZXMgdGhhdCBjb250YWluIHNwYWNlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbQllbmRPZkF0b20JaWYgbm90IE5VTCwgY2hhcmFjdGVyIG1hcmtpbmcgZW5kIG9mIHRva2VuCisgICAgICogQHJldHVybgkJdGhlIG5leHQgVG9rZW4KKyAgICAgKiBAZXhjZXB0aW9uCVBhcnNlRXhjZXB0aW9uIGlmIHRoZSBwYXJzZSBmYWlscworICAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS41CisgICAgICovCisgICAgcHVibGljIFRva2VuIG5leHQoY2hhciBlbmRPZkF0b20pIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7IAorCXJldHVybiBuZXh0KGVuZE9mQXRvbSwgZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlcyB0aGUgbmV4dCB0b2tlbiBmcm9tIHRoaXMgU3RyaW5nLgorICAgICAqIGVuZE9mQXRvbSBpcyBoYW5kbGVkIGFzIGFib3ZlLiAgSWYga2VlcEVzY2FwZXMgaXMgdHJ1ZSwKKyAgICAgKiBhbnkgYmFja3NsYXNoIGVzY2FwZXMgYXJlIHByZXNlcnZlZCBpbiB0aGUgcmV0dXJuZWQgc3RyaW5nLgorICAgICAqIFRoaXMgbWV0aG9kIGlzIHVzZWZ1bCB3aGVuIHBhcnNpbmcgaGVhZGVycyB0aGF0IGRvbid0CisgICAgICogb2JleSB0aGUgTUlNRSBzcGVjaWZpY2F0aW9uLCBlLmcuLCBieSBmYWlsaW5nIHRvIGVzY2FwZQorICAgICAqIGJhY2tzbGFzaGVzIGluIHRoZSBmaWxlbmFtZSBwYXJhbWV0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0JZW5kT2ZBdG9tCWlmIG5vdCBOVUwsIGNoYXJhY3RlciBtYXJraW5nIGVuZCBvZiB0b2tlbgorICAgICAqIEBwYXJhbQlrZWVwRXNjYXBlcwlrZWVwIGFsbCBiYWNrc2xhc2hlcyBpbiByZXR1cm5lZCBzdHJpbmc/CisgICAgICogQHJldHVybgkJdGhlIG5leHQgVG9rZW4KKyAgICAgKiBAZXhjZXB0aW9uCVBhcnNlRXhjZXB0aW9uIGlmIHRoZSBwYXJzZSBmYWlscworICAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS41CisgICAgICovCisgICAgcHVibGljIFRva2VuIG5leHQoY2hhciBlbmRPZkF0b20sIGJvb2xlYW4ga2VlcEVzY2FwZXMpCisJCQkJdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsgCisJVG9rZW4gdGs7CisKKwljdXJyZW50UG9zID0gbmV4dFBvczsgLy8gc2V0dXAgY3VycmVudFBvcworCXRrID0gZ2V0TmV4dChlbmRPZkF0b20sIGtlZXBFc2NhcGVzKTsKKwluZXh0UG9zID0gcGVla1BvcyA9IGN1cnJlbnRQb3M7IC8vIHVwZGF0ZSBjdXJyZW50UG9zIGFuZCBwZWVrUG9zCisJcmV0dXJuIHRrOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlZWsgYXQgdGhlIG5leHQgdG9rZW4sIHdpdGhvdXQgYWN0dWFsbHkgcmVtb3ZpbmcgdGhlIHRva2VuCisgICAgICogZnJvbSB0aGUgcGFyc2Ugc3RyZWFtLiBJbnZva2luZyB0aGlzIG1ldGhvZCBtdWx0aXBsZSB0aW1lcworICAgICAqIHdpbGwgcmV0dXJuIHN1Y2Nlc3NpdmUgdG9rZW5zLCB1bnRpbCA8Y29kZT5uZXh0KCk8L2NvZGU+IGlzCisgICAgICogY2FsbGVkLiA8cD4KKyAgICAgKgorICAgICAqIEByZXR1cm4JCXRoZSBuZXh0IFRva2VuCisgICAgICogQGV4Y2VwdGlvbglQYXJzZUV4Y2VwdGlvbiBpZiB0aGUgcGFyc2UgZmFpbHMKKyAgICAgKi8KKyAgICBwdWJsaWMgVG9rZW4gcGVlaygpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CisJVG9rZW4gdGs7CisKKwljdXJyZW50UG9zID0gcGVla1BvczsgLy8gc2V0dXAgY3VycmVudFBvcworCXRrID0gZ2V0TmV4dCgnXDAnLCBmYWxzZSk7CisJcGVla1BvcyA9IGN1cnJlbnRQb3M7IC8vIHVwZGF0ZSBwZWVrUG9zCisJcmV0dXJuIHRrOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgcmVzdCBvZiB0aGUgSGVhZGVyLgorICAgICAqCisgICAgICogQHJldHVybiBTdHJpbmcJcmVzdCBvZiBoZWFkZXIuIG51bGwgaXMgcmV0dXJuZWQgaWYgd2UgYXJlCisgICAgICoJCQlhbHJlYWR5IGF0IGVuZCBvZiBoZWFkZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFJlbWFpbmRlcigpIHsKKwlpZiAobmV4dFBvcyA+PSBzdHJpbmcubGVuZ3RoKCkpCisJICAgIHJldHVybiBudWxsOworCXJldHVybiBzdHJpbmcuc3Vic3RyaW5nKG5leHRQb3MpOworICAgIH0KKworICAgIC8qCisgICAgICogUmV0dXJuIHRoZSBuZXh0IHRva2VuIHN0YXJ0aW5nIGZyb20gJ2N1cnJlbnRQb3MnLiBBZnRlciB0aGUKKyAgICAgKiBwYXJzZSwgJ2N1cnJlbnRQb3MnIGlzIHVwZGF0ZWQgdG8gcG9pbnQgdG8gdGhlIHN0YXJ0IG9mIHRoZSAKKyAgICAgKiBuZXh0IHRva2VuLgorICAgICAqLworICAgIHByaXZhdGUgVG9rZW4gZ2V0TmV4dChjaGFyIGVuZE9mQXRvbSwgYm9vbGVhbiBrZWVwRXNjYXBlcykKKwkJCQl0aHJvd3MgUGFyc2VFeGNlcHRpb24geworCS8vIElmIHdlJ3JlIGFscmVhZHkgYXQgZW5kIG9mIHN0cmluZywgcmV0dXJuIEVPRgorCWlmIChjdXJyZW50UG9zID49IG1heFBvcykKKwkgICAgcmV0dXJuIEVPRlRva2VuOworCisJLy8gU2tpcCB3aGl0ZS1zcGFjZSwgcG9zaXRpb24gY3VycmVudFBvcyBiZXlvbmQgdGhlIHNwYWNlCisJaWYgKHNraXBXaGl0ZVNwYWNlKCkgPT0gVG9rZW4uRU9GKQorCSAgICByZXR1cm4gRU9GVG9rZW47CisKKwljaGFyIGM7IAorCWludCBzdGFydDsgCisJYm9vbGVhbiBmaWx0ZXIgPSBmYWxzZTsKKwkKKwljID0gc3RyaW5nLmNoYXJBdChjdXJyZW50UG9zKTsKKworCS8vIENoZWNrIG9yIFNraXAgY29tbWVudHMgYW5kIHBvc2l0aW9uIGN1cnJlbnRQb3MKKwkvLyBiZXlvbmQgdGhlIGNvbW1lbnQKKwl3aGlsZSAoYyA9PSAnKCcpIHsKKwkgICAgLy8gUGFyc2luZyBjb21tZW50IC4uCisJICAgIGludCBuZXN0aW5nOworCSAgICBmb3IgKHN0YXJ0ID0gKytjdXJyZW50UG9zLCBuZXN0aW5nID0gMTsgCisJCSBuZXN0aW5nID4gMCAmJiBjdXJyZW50UG9zIDwgbWF4UG9zOworCQkgY3VycmVudFBvcysrKSB7CisJCWMgPSBzdHJpbmcuY2hhckF0KGN1cnJlbnRQb3MpOworCQlpZiAoYyA9PSAnXFwnKSB7ICAvLyBFc2NhcGUgc2VxdWVuY2UKKwkJICAgIGN1cnJlbnRQb3MrKzsgLy8gc2tpcCB0aGUgZXNjYXBlZCBjaGFyYWN0ZXIKKwkJICAgIGZpbHRlciA9IHRydWU7CisJCX0gZWxzZSBpZiAoYyA9PSAnXHInKQorCQkgICAgZmlsdGVyID0gdHJ1ZTsKKwkJZWxzZSBpZiAoYyA9PSAnKCcpCisJCSAgICBuZXN0aW5nKys7CisJCWVsc2UgaWYgKGMgPT0gJyknKQorCQkgICAgbmVzdGluZy0tOworCSAgICB9CisJICAgIGlmIChuZXN0aW5nICE9IDApCisJCXRocm93IG5ldyBQYXJzZUV4Y2VwdGlvbigiVW5iYWxhbmNlZCBjb21tZW50cyIpOworCisJICAgIGlmICghc2tpcENvbW1lbnRzKSB7CisJCS8vIFJldHVybiB0aGUgY29tbWVudCwgaWYgd2UgYXJlIGFza2VkIHRvLgorCQkvLyBOb3RlIHRoYXQgdGhlIGNvbW1lbnQgc3RhcnQgJiBlbmQgbWFya2VycyBhcmUgaWdub3JlZC4KKwkJU3RyaW5nIHM7CisJCWlmIChmaWx0ZXIpIC8vIG5lZWQgdG8gZ28gdGhydSB0aGUgdG9rZW4gYWdhaW4uCisJCSAgICBzID0gZmlsdGVyVG9rZW4oc3RyaW5nLCBzdGFydCwgY3VycmVudFBvcy0xLCBrZWVwRXNjYXBlcyk7CisJCWVsc2UKKwkJICAgIHMgPSBzdHJpbmcuc3Vic3RyaW5nKHN0YXJ0LGN1cnJlbnRQb3MtMSk7CisKKwkJcmV0dXJuIG5ldyBUb2tlbihUb2tlbi5DT01NRU5ULCBzKTsKKwkgICAgfQorCisJICAgIC8vIFNraXAgYW55IHdoaXRlc3BhY2UgYWZ0ZXIgdGhlIGNvbW1lbnQuCisJICAgIGlmIChza2lwV2hpdGVTcGFjZSgpID09IFRva2VuLkVPRikKKwkJcmV0dXJuIEVPRlRva2VuOworCSAgICBjID0gc3RyaW5nLmNoYXJBdChjdXJyZW50UG9zKTsKKwl9CisKKwkvLyBDaGVjayBmb3IgcXVvdGVkLXN0cmluZyBhbmQgcG9zaXRpb24gY3VycmVudFBvcyAKKwkvLyAgYmV5b25kIHRoZSB0ZXJtaW5hdGluZyBxdW90ZQorCWlmIChjID09ICciJykgeworCSAgICBjdXJyZW50UG9zKys7CS8vIHNraXAgaW5pdGlhbCBxdW90ZQorCSAgICByZXR1cm4gY29sbGVjdFN0cmluZygnIicsIGtlZXBFc2NhcGVzKTsKKwl9CisJCisJLy8gQ2hlY2sgZm9yIFNQRUNJQUwgb3IgQ1RMCisJaWYgKGMgPCAwNDAgfHwgYyA+PSAwMTc3IHx8IGRlbGltaXRlcnMuaW5kZXhPZihjKSA+PSAwKSB7CisJICAgIGlmIChlbmRPZkF0b20gPiAwICYmIGMgIT0gZW5kT2ZBdG9tKSB7CisJCS8vIG5vdCBleHBlY3RpbmcgYSBzcGVjaWFsIGNoYXJhY3RlciBoZXJlLAorCQkvLyBwcmV0ZW5kIGl0J3MgYSBxdW90ZWQgc3RyaW5nCisJCXJldHVybiBjb2xsZWN0U3RyaW5nKGVuZE9mQXRvbSwga2VlcEVzY2FwZXMpOworCSAgICB9CisJICAgIGN1cnJlbnRQb3MrKzsgLy8gcmUtcG9zaXRpb24gY3VycmVudFBvcworCSAgICBjaGFyIGNoW10gPSBuZXcgY2hhclsxXTsKKwkgICAgY2hbMF0gPSBjOworCSAgICByZXR1cm4gbmV3IFRva2VuKChpbnQpYywgbmV3IFN0cmluZyhjaCkpOworCX0KKworCS8vIENoZWNrIGZvciBBVE9NCisJZm9yIChzdGFydCA9IGN1cnJlbnRQb3M7IGN1cnJlbnRQb3MgPCBtYXhQb3M7IGN1cnJlbnRQb3MrKykgeworCSAgICBjID0gc3RyaW5nLmNoYXJBdChjdXJyZW50UG9zKTsKKwkgICAgLy8gQVRPTSBpcyBkZWxpbWl0ZWQgYnkgZWl0aGVyIFNQQUNFLCBDVEwsICIoIiwgPCI+IAorCSAgICAvLyBvciB0aGUgc3BlY2lmaWVkIFNQRUNJQUxTCisJICAgIGlmIChjIDwgMDQwIHx8IGMgPj0gMDE3NyB8fCBjID09ICcoJyB8fCBjID09ICcgJyB8fAorCQkJYyA9PSAnIicgfHwgZGVsaW1pdGVycy5pbmRleE9mKGMpID49IDApIHsKKwkJaWYgKGVuZE9mQXRvbSA+IDAgJiYgYyAhPSBlbmRPZkF0b20pIHsKKwkJICAgIC8vIG5vdCB0aGUgZXhwZWN0ZWQgYXRvbSBhZnRlciBhbGw7CisJCSAgICAvLyBiYWNrIHVwIGFuZCBwcmV0ZW5kIGl0J3MgYSBxdW90ZWQgc3RyaW5nCisJCSAgICBjdXJyZW50UG9zID0gc3RhcnQ7CisJCSAgICByZXR1cm4gY29sbGVjdFN0cmluZyhlbmRPZkF0b20sIGtlZXBFc2NhcGVzKTsKKwkJfQorCQlicmVhazsKKwkgICAgfQorCX0KKwlyZXR1cm4gbmV3IFRva2VuKFRva2VuLkFUT00sIHN0cmluZy5zdWJzdHJpbmcoc3RhcnQsIGN1cnJlbnRQb3MpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFRva2VuIGNvbGxlY3RTdHJpbmcoY2hhciBlb3MsIGJvb2xlYW4ga2VlcEVzY2FwZXMpCisJCQkJdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKKwlpbnQgc3RhcnQ7CisJYm9vbGVhbiBmaWx0ZXIgPSBmYWxzZTsKKwlmb3IgKHN0YXJ0ID0gY3VycmVudFBvczsgY3VycmVudFBvcyA8IG1heFBvczsgY3VycmVudFBvcysrKSB7CisJICAgIGNoYXIgYyA9IHN0cmluZy5jaGFyQXQoY3VycmVudFBvcyk7CisJICAgIGlmIChjID09ICdcXCcpIHsgLy8gRXNjYXBlIHNlcXVlbmNlCisJCWN1cnJlbnRQb3MrKzsKKwkJZmlsdGVyID0gdHJ1ZTsKKwkgICAgfSBlbHNlIGlmIChjID09ICdccicpCisJCWZpbHRlciA9IHRydWU7CisJICAgIGVsc2UgaWYgKGMgPT0gZW9zKSB7CisJCWN1cnJlbnRQb3MrKzsKKwkJU3RyaW5nIHM7CisKKwkJaWYgKGZpbHRlcikKKwkJICAgIHMgPSBmaWx0ZXJUb2tlbihzdHJpbmcsIHN0YXJ0LCBjdXJyZW50UG9zLTEsIGtlZXBFc2NhcGVzKTsKKwkJZWxzZQorCQkgICAgcyA9IHN0cmluZy5zdWJzdHJpbmcoc3RhcnQsIGN1cnJlbnRQb3MtMSk7CisKKwkJaWYgKGMgIT0gJyInKSB7CQkvLyBub3QgYSByZWFsIHF1b3RlZCBzdHJpbmcKKwkJICAgIHMgPSB0cmltV2hpdGVTcGFjZShzKTsKKwkJICAgIGN1cnJlbnRQb3MtLTsJLy8gYmFjayB1cCBiZWZvcmUgdGhlIGVvcyBjaGFyCisJCX0KKworCQlyZXR1cm4gbmV3IFRva2VuKFRva2VuLlFVT1RFRFNUUklORywgcyk7CisJICAgIH0KKwl9CisKKwkvLyByYW4gb2ZmIHRoZSBlbmQgb2YgdGhlIHN0cmluZworCisJLy8gaWYgd2UncmUgbG9va2luZyBmb3IgYSBtYXRjaGluZyBxdW90ZSwgdGhhdCdzIGFuIGVycm9yCisJaWYgKGVvcyA9PSAnIicpCisJICAgIHRocm93IG5ldyBQYXJzZUV4Y2VwdGlvbigiVW5iYWxhbmNlZCBxdW90ZWQgc3RyaW5nIik7CisKKwkvLyBvdGhlcndpc2UsIGp1c3QgcmV0dXJuIHdoYXRldmVyJ3MgbGVmdAorCVN0cmluZyBzOworCWlmIChmaWx0ZXIpCisJICAgIHMgPSBmaWx0ZXJUb2tlbihzdHJpbmcsIHN0YXJ0LCBjdXJyZW50UG9zLCBrZWVwRXNjYXBlcyk7CisJZWxzZQorCSAgICBzID0gc3RyaW5nLnN1YnN0cmluZyhzdGFydCwgY3VycmVudFBvcyk7CisJcyA9IHRyaW1XaGl0ZVNwYWNlKHMpOworCXJldHVybiBuZXcgVG9rZW4oVG9rZW4uUVVPVEVEU1RSSU5HLCBzKTsKKyAgICB9CisKKyAgICAvLyBTa2lwIFNQQUNFLCBIVCwgQ1IgYW5kIE5MCisgICAgcHJpdmF0ZSBpbnQgc2tpcFdoaXRlU3BhY2UoKSB7CisJY2hhciBjOworCWZvciAoOyBjdXJyZW50UG9zIDwgbWF4UG9zOyBjdXJyZW50UG9zKyspCisJICAgIGlmICgoKGMgPSBzdHJpbmcuY2hhckF0KGN1cnJlbnRQb3MpKSAhPSAnICcpICYmIAorCQkoYyAhPSAnXHQnKSAmJiAoYyAhPSAnXHInKSAmJiAoYyAhPSAnXG4nKSkKKwkJcmV0dXJuIGN1cnJlbnRQb3M7CisJcmV0dXJuIFRva2VuLkVPRjsKKyAgICB9CisKKyAgICAvLyBUcmltIFNQQUNFLCBIVCwgQ1IgYW5kIE5MIGZyb20gZW5kIG9mIHN0cmluZworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyB0cmltV2hpdGVTcGFjZShTdHJpbmcgcykgeworCWNoYXIgYzsKKwlpbnQgaTsKKwlmb3IgKGkgPSBzLmxlbmd0aCgpIC0gMTsgaSA+PSAwOyBpLS0pIHsKKwkgICAgaWYgKCgoYyA9IHMuY2hhckF0KGkpKSAhPSAnICcpICYmIAorCQkoYyAhPSAnXHQnKSAmJiAoYyAhPSAnXHInKSAmJiAoYyAhPSAnXG4nKSkKKwkJYnJlYWs7CisJfQorCWlmIChpIDw9IDApCisJICAgIHJldHVybiAiIjsKKwllbHNlCisJICAgIHJldHVybiBzLnN1YnN0cmluZygwLCBpICsgMSk7CisgICAgfQorCisgICAgLyogUHJvY2VzcyBlc2NhcGUgc2VxdWVuY2VzIGFuZCBlbWJlZGRlZCBMV1NQcyBmcm9tIGEgY29tbWVudCBvcgorICAgICAqIHF1b3RlZCBzdHJpbmcuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGZpbHRlclRva2VuKFN0cmluZyBzLCBpbnQgc3RhcnQsIGludCBlbmQsCisJCQkJYm9vbGVhbiBrZWVwRXNjYXBlcykgeworCVN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworCWNoYXIgYzsKKwlib29sZWFuIGdvdEVzY2FwZSA9IGZhbHNlOworCWJvb2xlYW4gZ290Q1IgPSBmYWxzZTsKKworCWZvciAoaW50IGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7CisJICAgIGMgPSBzLmNoYXJBdChpKTsKKwkgICAgaWYgKGMgPT0gJ1xuJyAmJiBnb3RDUikgeworCQkvLyBUaGlzIExGIGlzIHBhcnQgb2YgYW4gdW5lc2NhcGVkIAorCQkvLyBDUkxGIHNlcXVlbmNlIChpLmUsIExXU1ApLiBTa2lwIGl0LgorCQlnb3RDUiA9IGZhbHNlOworCQljb250aW51ZTsKKwkgICAgfQorCisJICAgIGdvdENSID0gZmFsc2U7CisJICAgIGlmICghZ290RXNjYXBlKSB7CisJCS8vIFByZXZpb3VzIGNoYXJhY3RlciB3YXMgTk9UICdcJworCQlpZiAoYyA9PSAnXFwnKSAvLyBza2lwIHRoaXMgY2hhcmFjdGVyCisJCSAgICBnb3RFc2NhcGUgPSB0cnVlOworCQllbHNlIGlmIChjID09ICdccicpIC8vIHNraXAgdGhpcyBjaGFyYWN0ZXIKKwkJICAgIGdvdENSID0gdHJ1ZTsKKwkJZWxzZSAvLyBhcHBlbmQgdGhpcyBjaGFyYWN0ZXIKKwkJICAgIHNiLmFwcGVuZChjKTsKKwkgICAgfSBlbHNlIHsKKwkJLy8gUHJldmlvdXMgY2hhcmFjdGVyIHdhcyAnXCcuIFNvIG5vIG5lZWQgdG8gCisJCS8vIGJvdGhlciB3aXRoIGFueSBzcGVjaWFsIHByb2Nlc3NpbmcsIGp1c3QgCisJCS8vIGFwcGVuZCB0aGlzIGNoYXJhY3Rlci4gIElmIGtlZXBFc2NhcGVzIGlzCisJCS8vIHNldCwga2VlcCB0aGUgYmFja3NsYXNoLiAgSUU2IGZhaWxzIHRvIGVzY2FwZQorCQkvLyBiYWNrc2xhc2hlcyBpbiBxdW90ZWQgc3RyaW5ncyBpbiBIVFRQIGhlYWRlcnMsCisJCS8vIGUuZy4sIGluIHRoZSBmaWxlbmFtZSBwYXJhbWV0ZXIuCisJCWlmIChrZWVwRXNjYXBlcykKKwkJICAgIHNiLmFwcGVuZCgnXFwnKTsKKwkJc2IuYXBwZW5kKGMpOworCQlnb3RFc2NhcGUgPSBmYWxzZTsKKwkgICAgfQorCX0KKwlyZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9JbnRlcm5ldEFkZHJlc3MuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2ludGVybmV0L0ludGVybmV0QWRkcmVzcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk3Y2ViN2UKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9JbnRlcm5ldEFkZHJlc3MuamF2YQpAQCAtMCwwICsxLDE1MjMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5pbnRlcm5ldDsKKworaW1wb3J0IGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5JbmV0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5ldC5Vbmtub3duSG9zdEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LlN0YW5kYXJkQ2hhcnNldHM7CitpbXBvcnQgamF2YXgubWFpbC4qOworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLlByb3BVdGlsOworCisvKioKKyAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhbiBJbnRlcm5ldCBlbWFpbCBhZGRyZXNzIHVzaW5nIHRoZSBzeW50YXgKKyAqIG9mIDxhIGhyZWY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzgyMi50eHQiIHRhcmdldD0iX3RvcCI+UkZDODIyPC9hPi4KKyAqIFR5cGljYWwgYWRkcmVzcyBzeW50YXggaXMgb2YgdGhlIGZvcm0gInVzZXJAaG9zdC5kb21haW4iIG9yCisgKiAiUGVyc29uYWwgTmFtZSAmbHQ7dXNlckBob3N0LmRvbWFpbiZndDsiLgorICoKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKiBAYXV0aG9yIEpvaG4gTWFuaQorICovCisKK3B1YmxpYyBjbGFzcyBJbnRlcm5ldEFkZHJlc3MgZXh0ZW5kcyBBZGRyZXNzIGltcGxlbWVudHMgQ2xvbmVhYmxlIHsKKworICAgIHByb3RlY3RlZCBTdHJpbmcgYWRkcmVzczsgLy8gZW1haWwgYWRkcmVzcworCisgICAgLyoqCisgICAgICogVGhlIHBlcnNvbmFsIG5hbWUuCisgICAgICovCisgICAgcHJvdGVjdGVkIFN0cmluZyBwZXJzb25hbDsKKworICAgIC8qKgorICAgICAqIFRoZSBSRkMgMjA0NyBlbmNvZGVkIHZlcnNpb24gb2YgdGhlIHBlcnNvbmFsIG5hbWUuIDxwPgorICAgICAqCisgICAgICogVGhpcyBmaWVsZCBhbmQgdGhlIDxjb2RlPnBlcnNvbmFsPC9jb2RlPiBmaWVsZCB0cmFjayBlYWNoCisgICAgICogb3RoZXIsIHNvIGlmIGEgc3ViY2xhc3Mgc2V0cyBvbmUgb2YgdGhlc2UgZmllbGRzIGRpcmVjdGx5LCBpdAorICAgICAqIHNob3VsZCBzZXQgdGhlIG90aGVyIHRvIDxjb2RlPm51bGw8L2NvZGU+LCBzbyB0aGF0IGl0IGlzCisgICAgICogc3VpdGFibHkgcmVjb21wdXRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU3RyaW5nIGVuY29kZWRQZXJzb25hbDsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC03NTA3NTk1NTMwNzU4MzAyOTAzTDsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gaWdub3JlQm9ndXNHcm91cE5hbWUgPQorCVByb3BVdGlsLmdldEJvb2xlYW5TeXN0ZW1Qcm9wZXJ0eSgKKwkJCSAgICAibWFpbC5taW1lLmFkZHJlc3MuaWdub3JlYm9ndXNncm91cG5hbWUiLCB0cnVlKTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gdXNlQ2Fub25pY2FsSG9zdE5hbWUgPQorCVByb3BVdGlsLmdldEJvb2xlYW5TeXN0ZW1Qcm9wZXJ0eSgKKwkJCSAgICAibWFpbC5taW1lLmFkZHJlc3MudXNlY2Fub25pY2FsaG9zdG5hbWUiLCB0cnVlKTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gYWxsb3dVdGY4ID0KKwlQcm9wVXRpbC5nZXRCb29sZWFuU3lzdGVtUHJvcGVydHkoIm1haWwubWltZS5hbGxvd3V0ZjgiLCBmYWxzZSk7CisKKyAgICAvKioKKyAgICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yLgorICAgICAqLworICAgIHB1YmxpYyBJbnRlcm5ldEFkZHJlc3MoKSB7IH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yLiA8cD4KKyAgICAgKgorICAgICAqIFBhcnNlIHRoZSBnaXZlbiBzdHJpbmcgYW5kIGNyZWF0ZSBhbiBJbnRlcm5ldEFkZHJlc3MuCisgICAgICogU2VlIHRoZSA8Y29kZT5wYXJzZTwvY29kZT4gbWV0aG9kIGZvciBkZXRhaWxzIG9mIHRoZSBwYXJzaW5nLgorICAgICAqIFRoZSBhZGRyZXNzIGlzIHBhcnNlZCB1c2luZyAic3RyaWN0IiBwYXJzaW5nLgorICAgICAqIFRoaXMgY29uc3RydWN0b3IgZG9lcyA8Yj5ub3Q8L2I+IHBlcmZvcm0gdGhlIGFkZGl0aW9uYWwKKyAgICAgKiBzeW50YXggY2hlY2tzIHRoYXQgdGhlCisgICAgICogPGNvZGU+SW50ZXJuZXRBZGRyZXNzKFN0cmluZyBhZGRyZXNzLCBib29sZWFuIHN0cmljdCk8L2NvZGU+CisgICAgICogY29uc3RydWN0b3IgZG9lcyB3aGVuIDxjb2RlPnN0cmljdDwvY29kZT4gaXMgPGNvZGU+dHJ1ZTwvY29kZT4uCisgICAgICogVGhpcyBjb25zdHJ1Y3RvciBpcyBlcXVpdmFsZW50IHRvCisgICAgICogPGNvZGU+SW50ZXJuZXRBZGRyZXNzKGFkZHJlc3MsIGZhbHNlKTwvY29kZT4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWRkcmVzcwl0aGUgYWRkcmVzcyBpbiBSRkM4MjIgZm9ybWF0CisgICAgICogQGV4Y2VwdGlvbglBZGRyZXNzRXhjZXB0aW9uIGlmIHRoZSBwYXJzZSBmYWlsZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgSW50ZXJuZXRBZGRyZXNzKFN0cmluZyBhZGRyZXNzKSB0aHJvd3MgQWRkcmVzc0V4Y2VwdGlvbiB7CisJLy8gdXNlIG91ciBhZGRyZXNzIHBhcnNpbmcgdXRpbGl0eSByb3V0aW5lIHRvIHBhcnNlIHRoZSBzdHJpbmcKKwlJbnRlcm5ldEFkZHJlc3MgYVtdID0gcGFyc2UoYWRkcmVzcywgdHJ1ZSk7CisJLy8gaWYgd2UgZ290IGJhY2sgYW55dGhpbmcgb3RoZXIgdGhhbiBhIHNpbmdsZSBhZGRyZXNzLCBpdCdzIGFuIGVycm9yCisJaWYgKGEubGVuZ3RoICE9IDEpCisJICAgIHRocm93IG5ldyBBZGRyZXNzRXhjZXB0aW9uKCJJbGxlZ2FsIGFkZHJlc3MiLCBhZGRyZXNzKTsKKworCS8qCisJICogTm93IGNvcHkgdGhlIGNvbnRlbnRzIG9mIHRoZSBzaW5nbGUgYWRkcmVzcyB3ZSBwYXJzZWQKKwkgKiBpbnRvIHRoZSBjdXJyZW50IG9iamVjdCwgd2hpY2ggd2lsbCBiZSByZXR1cm5lZCBmcm9tIHRoZQorCSAqIGNvbnN0cnVjdG9yLgorCSAqIFhYWCAtIHRoaXMgc3VyZSBpcyBhIHJvdW5kLWFib3V0IHdheSBvZiBnZXR0aW5nIHRoaXMgZG9uZS4KKwkgKi8KKwl0aGlzLmFkZHJlc3MgPSBhWzBdLmFkZHJlc3M7CisJdGhpcy5wZXJzb25hbCA9IGFbMF0ucGVyc29uYWw7CisJdGhpcy5lbmNvZGVkUGVyc29uYWwgPSBhWzBdLmVuY29kZWRQZXJzb25hbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZSB0aGUgZ2l2ZW4gc3RyaW5nIGFuZCBjcmVhdGUgYW4gSW50ZXJuZXRBZGRyZXNzLgorICAgICAqIElmIDxjb2RlPnN0cmljdDwvY29kZT4gaXMgZmFsc2UsIHRoZSBkZXRhaWxlZCBzeW50YXggb2YgdGhlCisgICAgICogYWRkcmVzcyBpc24ndCBjaGVja2VkLgorICAgICAqCisgICAgICogQHBhcmFtCWFkZHJlc3MJCXRoZSBhZGRyZXNzIGluIFJGQzgyMiBmb3JtYXQKKyAgICAgKiBAcGFyYW0Jc3RyaWN0CQllbmZvcmNlIFJGQzgyMiBzeW50YXgKKyAgICAgKiBAZXhjZXB0aW9uCQlBZGRyZXNzRXhjZXB0aW9uIGlmIHRoZSBwYXJzZSBmYWlsZWQKKyAgICAgKiBAc2luY2UJCQlKYXZhTWFpbCAxLjMKKyAgICAgKi8KKyAgICBwdWJsaWMgSW50ZXJuZXRBZGRyZXNzKFN0cmluZyBhZGRyZXNzLCBib29sZWFuIHN0cmljdCkKKwkJCQkJCXRocm93cyBBZGRyZXNzRXhjZXB0aW9uIHsKKwl0aGlzKGFkZHJlc3MpOworCWlmIChzdHJpY3QpIHsKKwkgICAgaWYgKGlzR3JvdXAoKSkKKwkJZ2V0R3JvdXAodHJ1ZSk7CS8vIHRocm93IGF3YXkgdGhlIHJlc3VsdAorCSAgICBlbHNlCisJCWNoZWNrQWRkcmVzcyh0aGlzLmFkZHJlc3MsIHRydWUsIHRydWUpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYW4gSW50ZXJuZXRBZGRyZXNzIGdpdmVuIHRoZSBhZGRyZXNzIGFuZCBwZXJzb25hbCBuYW1lLgorICAgICAqIFRoZSBhZGRyZXNzIGlzIGFzc3VtZWQgdG8gYmUgYSBzeW50YWN0aWNhbGx5IHZhbGlkIFJGQzgyMiBhZGRyZXNzLgorICAgICAqCisgICAgICogQHBhcmFtIGFkZHJlc3MJdGhlIGFkZHJlc3MgaW4gUkZDODIyIGZvcm1hdAorICAgICAqIEBwYXJhbSBwZXJzb25hbAl0aGUgcGVyc29uYWwgbmFtZQorICAgICAqIEBleGNlcHRpb24JVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBpZiB0aGUgcGVyc29uYWwgbmFtZQorICAgICAqCQkJY2FuJ3QgYmUgZW5jb2RlZCBpbiB0aGUgZ2l2ZW4gY2hhcnNldAorICAgICAqLworICAgIHB1YmxpYyBJbnRlcm5ldEFkZHJlc3MoU3RyaW5nIGFkZHJlc3MsIFN0cmluZyBwZXJzb25hbCkKKwkJCQl0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiB7CisJdGhpcyhhZGRyZXNzLCBwZXJzb25hbCwgbnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGFuIEludGVybmV0QWRkcmVzcyBnaXZlbiB0aGUgYWRkcmVzcyBhbmQgcGVyc29uYWwgbmFtZS4KKyAgICAgKiBUaGUgYWRkcmVzcyBpcyBhc3N1bWVkIHRvIGJlIGEgc3ludGFjdGljYWxseSB2YWxpZCBSRkM4MjIgYWRkcmVzcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBhZGRyZXNzCXRoZSBhZGRyZXNzIGluIFJGQzgyMiBmb3JtYXQKKyAgICAgKiBAcGFyYW0gcGVyc29uYWwJdGhlIHBlcnNvbmFsIG5hbWUKKyAgICAgKiBAcGFyYW0gY2hhcnNldAl0aGUgTUlNRSBjaGFyc2V0IGZvciB0aGUgbmFtZQorICAgICAqIEBleGNlcHRpb24JVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBpZiB0aGUgcGVyc29uYWwgbmFtZQorICAgICAqCQkJY2FuJ3QgYmUgZW5jb2RlZCBpbiB0aGUgZ2l2ZW4gY2hhcnNldAorICAgICAqLworICAgIHB1YmxpYyBJbnRlcm5ldEFkZHJlc3MoU3RyaW5nIGFkZHJlc3MsIFN0cmluZyBwZXJzb25hbCwgU3RyaW5nIGNoYXJzZXQpCisJCQkJdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24geworCXRoaXMuYWRkcmVzcyA9IGFkZHJlc3M7CisJc2V0UGVyc29uYWwocGVyc29uYWwsIGNoYXJzZXQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiBhIGNvcHkgb2YgdGhpcyBJbnRlcm5ldEFkZHJlc3Mgb2JqZWN0LgorICAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS4yCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKKwlJbnRlcm5ldEFkZHJlc3MgYSA9IG51bGw7CisJdHJ5IHsKKwkgICAgYSA9IChJbnRlcm5ldEFkZHJlc3Mpc3VwZXIuY2xvbmUoKTsKKwl9IGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7fSAvLyBXb24ndCBoYXBwZW4KKwlyZXR1cm4gYTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIHR5cGUgb2YgdGhpcyBhZGRyZXNzLiBUaGUgdHlwZSBvZiBhbiBJbnRlcm5ldEFkZHJlc3MKKyAgICAgKiBpcyAicmZjODIyIi4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldFR5cGUoKSB7CisJcmV0dXJuICJyZmM4MjIiOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgZW1haWwgYWRkcmVzcy4KKyAgICAgKgorICAgICAqIEBwYXJhbQlhZGRyZXNzIGVtYWlsIGFkZHJlc3MKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRBZGRyZXNzKFN0cmluZyBhZGRyZXNzKSB7CisJdGhpcy5hZGRyZXNzID0gYWRkcmVzczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHBlcnNvbmFsIG5hbWUuIElmIHRoZSBuYW1lIGNvbnRhaW5zIG5vbiBVUy1BU0NJSQorICAgICAqIGNoYXJhY3RlcnMsIHRoZW4gdGhlIG5hbWUgd2lsbCBiZSBlbmNvZGVkIHVzaW5nIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBjaGFyc2V0IGFzIHBlciBSRkMgMjA0Ny4gSWYgdGhlIG5hbWUgY29udGFpbnMgb25seSBVUy1BU0NJSQorICAgICAqIGNoYXJhY3RlcnMsIG5vIGVuY29kaW5nIGlzIGRvbmUgYW5kIHRoZSBuYW1lIGlzIHVzZWQgYXMgaXMuIDxwPgorICAgICAqCisgICAgICogQHBhcmFtCW5hbWUgCXBlcnNvbmFsIG5hbWUKKyAgICAgKiBAcGFyYW0JY2hhcnNldAlNSU1FIGNoYXJzZXQgdG8gYmUgdXNlZCB0byBlbmNvZGUgdGhlIG5hbWUgYXMgCisgICAgICoJCQlwZXIgUkZDIDIwNDcKKyAgICAgKiBAc2VlIAkjc2V0UGVyc29uYWwoU3RyaW5nKQorICAgICAqIEBleGNlcHRpb24gVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBpZiB0aGUgY2hhcnNldCBlbmNvZGluZworICAgICAqCQkgIGZhaWxzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFBlcnNvbmFsKFN0cmluZyBuYW1lLCBTdHJpbmcgY2hhcnNldCkKKwkJCQl0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiB7CisJcGVyc29uYWwgPSBuYW1lOworCWlmIChuYW1lICE9IG51bGwpCisJICAgIGVuY29kZWRQZXJzb25hbCA9IE1pbWVVdGlsaXR5LmVuY29kZVdvcmQobmFtZSwgY2hhcnNldCwgbnVsbCk7CisJZWxzZQorCSAgICBlbmNvZGVkUGVyc29uYWwgPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgcGVyc29uYWwgbmFtZS4gSWYgdGhlIG5hbWUgY29udGFpbnMgbm9uIFVTLUFTQ0lJCisgICAgICogY2hhcmFjdGVycywgdGhlbiB0aGUgbmFtZSB3aWxsIGJlIGVuY29kZWQgdXNpbmcgdGhlIHBsYXRmb3JtJ3MgCisgICAgICogZGVmYXVsdCBjaGFyc2V0LiBJZiB0aGUgbmFtZSBjb250YWlucyBvbmx5IFVTLUFTQ0lJIGNoYXJhY3RlcnMsCisgICAgICogbm8gZW5jb2RpbmcgaXMgZG9uZSBhbmQgdGhlIG5hbWUgaXMgdXNlZCBhcyBpcy4gPHA+CisgICAgICoKKyAgICAgKiBAcGFyYW0JbmFtZSAJcGVyc29uYWwgbmFtZQorICAgICAqIEBzZWUgCSNzZXRQZXJzb25hbChTdHJpbmcgbmFtZSwgU3RyaW5nIGNoYXJzZXQpCisgICAgICogQGV4Y2VwdGlvbiBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGlmIHRoZSBjaGFyc2V0IGVuY29kaW5nCisgICAgICoJCSAgZmFpbHMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UGVyc29uYWwoU3RyaW5nIG5hbWUpIAorCQl0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiB7CisJcGVyc29uYWwgPSBuYW1lOworCWlmIChuYW1lICE9IG51bGwpCisJICAgIGVuY29kZWRQZXJzb25hbCA9IE1pbWVVdGlsaXR5LmVuY29kZVdvcmQobmFtZSk7CisJZWxzZQorCSAgICBlbmNvZGVkUGVyc29uYWwgPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgZW1haWwgYWRkcmVzcy4KKyAgICAgKiBAcmV0dXJuCWVtYWlsIGFkZHJlc3MKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEFkZHJlc3MoKSB7CisJcmV0dXJuIGFkZHJlc3M7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBwZXJzb25hbCBuYW1lLiBJZiB0aGUgbmFtZSBpcyBlbmNvZGVkIGFzIHBlciBSRkMgMjA0NywKKyAgICAgKiBpdCBpcyBkZWNvZGVkIGFuZCBjb252ZXJ0ZWQgaW50byBVbmljb2RlLiBJZiB0aGUgZGVjb2Rpbmcgb3IKKyAgICAgKiBjb252ZXJzaW9uIGZhaWxzLCB0aGUgcmF3IGRhdGEgaXMgcmV0dXJuZWQgYXMgaXMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXBlcnNvbmFsIG5hbWUKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFBlcnNvbmFsKCkgeworCWlmIChwZXJzb25hbCAhPSBudWxsKQorCSAgICByZXR1cm4gcGVyc29uYWw7CisJCisJaWYgKGVuY29kZWRQZXJzb25hbCAhPSBudWxsKSB7CisJICAgIHRyeSB7CisJCXBlcnNvbmFsID0gTWltZVV0aWxpdHkuZGVjb2RlVGV4dChlbmNvZGVkUGVyc29uYWwpOworCQlyZXR1cm4gcGVyc29uYWw7CisJICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCQkvLyAxLiBQYXJzZUV4Y2VwdGlvbjogZWl0aGVyIGl0cyBhbiB1bmVuY29kZWQgc3RyaW5nIG9yCisJCS8vCWl0IGNhbid0IGJlIHBhcnNlZAorCQkvLyAyLiBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uOiBjYW4ndCBkZWNvZGUgaXQuCisJCXJldHVybiBlbmNvZGVkUGVyc29uYWw7CisJICAgIH0KKwl9CisJLy8gTm8gcGVyc29uYWwgb3IgZW5jb2RlZFBlcnNvbmFsLCByZXR1cm4gbnVsbAorCXJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlcnQgdGhpcyBhZGRyZXNzIGludG8gYSBSRkMgODIyIC8gUkZDIDIwNDcgZW5jb2RlZCBhZGRyZXNzLgorICAgICAqIFRoZSByZXN1bHRpbmcgc3RyaW5nIGNvbnRhaW5zIG9ubHkgVVMtQVNDSUkgY2hhcmFjdGVycywgYW5kCisgICAgICogaGVuY2UgaXMgbWFpbC1zYWZlLgorICAgICAqCisgICAgICogQHJldHVybgkJcG9zc2libHkgZW5jb2RlZCBhZGRyZXNzIHN0cmluZworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisJU3RyaW5nIGEgPSBhZGRyZXNzID09IG51bGwgPyAiIiA6IGFkZHJlc3M7CisJaWYgKGVuY29kZWRQZXJzb25hbCA9PSBudWxsICYmIHBlcnNvbmFsICE9IG51bGwpCisJICAgIHRyeSB7CisJCWVuY29kZWRQZXJzb25hbCA9IE1pbWVVdGlsaXR5LmVuY29kZVdvcmQocGVyc29uYWwpOworCSAgICB9IGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGV4KSB7IH0KKwkKKwlpZiAoZW5jb2RlZFBlcnNvbmFsICE9IG51bGwpCisJICAgIHJldHVybiBxdW90ZVBocmFzZShlbmNvZGVkUGVyc29uYWwpICsgIiA8IiArIGEgKyAiPiI7CisJZWxzZSBpZiAoaXNHcm91cCgpIHx8IGlzU2ltcGxlKCkpCisJICAgIHJldHVybiBhOworCWVsc2UKKwkgICAgcmV0dXJuICI8IiArIGEgKyAiPiI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIHByb3Blcmx5IGZvcm1hdHRlZCBhZGRyZXNzIChSRkMgODIyIHN5bnRheCkgb2YKKyAgICAgKiBVbmljb2RlIGNoYXJhY3RlcnMuCisgICAgICogICAKKyAgICAgKiBAcmV0dXJuICAgICAgICAgIFVuaWNvZGUgYWRkcmVzcyBzdHJpbmcKKyAgICAgKiBAc2luY2UgICAgICAgICAgIEphdmFNYWlsIDEuMgorICAgICAqLyAgCisgICAgcHVibGljIFN0cmluZyB0b1VuaWNvZGVTdHJpbmcoKSB7CisJU3RyaW5nIHAgPSBnZXRQZXJzb25hbCgpOworICAgICAgICBpZiAocCAhPSBudWxsKQorICAgICAgICAgICAgcmV0dXJuIHF1b3RlUGhyYXNlKHApICsgIiA8IiArIGFkZHJlc3MgKyAiPiI7CisgICAgICAgIGVsc2UgaWYgKGlzR3JvdXAoKSB8fCBpc1NpbXBsZSgpKQorICAgICAgICAgICAgcmV0dXJuIGFkZHJlc3M7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIHJldHVybiAiPCIgKyBhZGRyZXNzICsgIj4iOworICAgIH0KKworICAgIC8qCisgICAgICogcXVvdGVQaHJhc2UoKSBxdW90ZXMgdGhlIHdvcmRzIHdpdGhpbiBhIFJGQzgyMiBwaHJhc2UuCisgICAgICoKKyAgICAgKiBUaGlzIGlzIHRyaWNreSwgc2luY2UgYSBwaHJhc2UgaXMgZGVmaW5lZCBhcyAxIG9yIG1vcmUKKyAgICAgKiBSRkM4MjIgd29yZHMsIHNlcGFyYXRlZCBieSBMV1NQLiBOb3csIGEgd29yZCB0aGF0IGNvbnRhaW5zCisgICAgICogTFdTUCBpcyBzdXBwb3NlZCB0byBiZSBxdW90ZWQsIGFuZCB0aGlzIGlzIGV4YWN0bHkgd2hhdCB0aGUgCisgICAgICogTWltZVV0aWxpdHkucXVvdGUoKSBtZXRob2QgZG9lcy4gSG93ZXZlciwgd2hlbiBkZWFsaW5nIHdpdGgKKyAgICAgKiBhIHBocmFzZSwgYW55IExXU1AgZW5jb3VudGVyZWQgY2FuIGJlIGNvbnN0cnVlZCB0byBiZSB0aGUKKyAgICAgKiBzZXBhcmF0b3IgYmV0d2VlbiB3b3JkcywgYW5kIG5vdCBwYXJ0IG9mIHRoZSB3b3JkcyB0aGVtc2VsdmVzLgorICAgICAqIFRvIGRlYWwgd2l0aCB0aGlzIGZ1bmtpbmVzcywgd2UgaGF2ZSB0aGUgYmVsb3cgdmFyaWFudCBvZgorICAgICAqIE1pbWVVdGlsaXR5LnF1b3RlKCksIHdoaWNoIGVzc2VudGlhbGx5IGlnbm9yZXMgTFdTUCB3aGVuCisgICAgICogZGVjaWRpbmcgd2hldGhlciB0byBxdW90ZSBhIHdvcmQuCisgICAgICoKKyAgICAgKiBJdCBhaW50IHByZXR0eSwgYnV0IGl0IGdldHMgdGhlIGpvYiBkb25lIDopCisgICAgICovCisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgcmZjODIycGhyYXNlID0KKwlIZWFkZXJUb2tlbml6ZXIuUkZDODIyLnJlcGxhY2UoJyAnLCAnXDAnKS5yZXBsYWNlKCdcdCcsICdcMCcpOworCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIHF1b3RlUGhyYXNlKFN0cmluZyBwaHJhc2UpIHsKKyAgICAgICAgaW50IGxlbiA9IHBocmFzZS5sZW5ndGgoKTsKKyAgICAgICAgYm9vbGVhbiBuZWVkUXVvdGluZyA9IGZhbHNlOworCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKKyAgICAgICAgICAgIGNoYXIgYyA9IHBocmFzZS5jaGFyQXQoaSk7CisgICAgICAgICAgICBpZiAoYyA9PSAnIicgfHwgYyA9PSAnXFwnKSB7IAorICAgICAgICAgICAgICAgIC8vIG5lZWQgdG8gZXNjYXBlIHRoZW0gYW5kIHRoZW4gcXVvdGUgdGhlIHdob2xlIHN0cmluZworICAgICAgICAgICAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcihsZW4gKyAzKTsKKyAgICAgICAgICAgICAgICBzYi5hcHBlbmQoJyInKTsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGxlbjsgaisrKSB7CisgICAgICAgICAgICAgICAgICAgIGNoYXIgY2MgPSBwaHJhc2UuY2hhckF0KGopOworICAgICAgICAgICAgICAgICAgICBpZiAoY2MgPT0gJyInIHx8IGNjID09ICdcXCcpCisgICAgICAgICAgICAgICAgICAgICAgICAvLyBFc2NhcGUgdGhlIGNoYXJhY3RlcgorICAgICAgICAgICAgICAgICAgICAgICAgc2IuYXBwZW5kKCdcXCcpOworICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQoY2MpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBzYi5hcHBlbmQoJyInKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoKGMgPCAwNDAgJiYgYyAhPSAnXHInICYmIGMgIT0gJ1xuJyAmJiBjICE9ICdcdCcpIHx8IAorCQkgICAgKGMgPj0gMDE3NyAmJiAhYWxsb3dVdGY4KSB8fCByZmM4MjJwaHJhc2UuaW5kZXhPZihjKSA+PSAwKQorCQkvLyBUaGVzZSBjaGFyYWN0ZXJzIGNhdXNlIHRoZSBzdHJpbmcgdG8gYmUgcXVvdGVkCisgICAgICAgICAgICAgICAgbmVlZFF1b3RpbmcgPSB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgaWYgKG5lZWRRdW90aW5nKSB7CisgICAgICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIobGVuICsgMik7CisgICAgICAgICAgICBzYi5hcHBlbmQoJyInKS5hcHBlbmQocGhyYXNlKS5hcHBlbmQoJyInKTsKKyAgICAgICAgICAgIHJldHVybiBzYi50b1N0cmluZygpOworICAgICAgICB9IGVsc2UKKyAgICAgICAgICAgIHJldHVybiBwaHJhc2U7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIHVucXVvdGUoU3RyaW5nIHMpIHsKKwlpZiAocy5zdGFydHNXaXRoKCJcIiIpICYmIHMuZW5kc1dpdGgoIlwiIikgJiYgcy5sZW5ndGgoKSA+IDEpIHsKKwkgICAgcyA9IHMuc3Vic3RyaW5nKDEsIHMubGVuZ3RoKCkgLSAxKTsKKwkgICAgLy8gY2hlY2sgZm9yIGFueSBlc2NhcGVkIGNoYXJhY3RlcnMKKwkgICAgaWYgKHMuaW5kZXhPZignXFwnKSA+PSAwKSB7CisJCVN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcihzLmxlbmd0aCgpKTsJLy8gYXBwcm94CisJCWZvciAoaW50IGkgPSAwOyBpIDwgcy5sZW5ndGgoKTsgaSsrKSB7CisJCSAgICBjaGFyIGMgPSBzLmNoYXJBdChpKTsKKwkJICAgIGlmIChjID09ICdcXCcgJiYgaSA8IHMubGVuZ3RoKCkgLSAxKQorCQkJYyA9IHMuY2hhckF0KCsraSk7CisJCSAgICBzYi5hcHBlbmQoYyk7CisJCX0KKwkJcyA9IHNiLnRvU3RyaW5nKCk7CisJICAgIH0KKwl9CisJcmV0dXJuIHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIGVxdWFsaXR5IG9wZXJhdG9yLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgYSkgeworCWlmICghKGEgaW5zdGFuY2VvZiBJbnRlcm5ldEFkZHJlc3MpKQorCSAgICByZXR1cm4gZmFsc2U7CisKKwlTdHJpbmcgcyA9ICgoSW50ZXJuZXRBZGRyZXNzKWEpLmdldEFkZHJlc3MoKTsKKwlpZiAocyA9PSBhZGRyZXNzKQorCSAgICByZXR1cm4gdHJ1ZTsKKwlpZiAoYWRkcmVzcyAhPSBudWxsICYmIGFkZHJlc3MuZXF1YWxzSWdub3JlQ2FzZShzKSkKKwkgICAgcmV0dXJuIHRydWU7CisKKwlyZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcHV0ZSBhIGhhc2ggY29kZSBmb3IgdGhlIGFkZHJlc3MuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKwlpZiAoYWRkcmVzcyA9PSBudWxsKQorCSAgICByZXR1cm4gMDsKKwllbHNlCisJICAgIHJldHVybiBhZGRyZXNzLnRvTG93ZXJDYXNlKExvY2FsZS5FTkdMSVNIKS5oYXNoQ29kZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlcnQgdGhlIGdpdmVuIGFycmF5IG9mIEludGVybmV0QWRkcmVzcyBvYmplY3RzIGludG8KKyAgICAgKiBhIGNvbW1hIHNlcGFyYXRlZCBzZXF1ZW5jZSBvZiBhZGRyZXNzIHN0cmluZ3MuIFRoZQorICAgICAqIHJlc3VsdGluZyBzdHJpbmcgY29udGFpbnMgb25seSBVUy1BU0NJSSBjaGFyYWN0ZXJzLCBhbmQKKyAgICAgKiBoZW5jZSBpcyBtYWlsLXNhZmUuIDxwPgorICAgICAqCisgICAgICogQHBhcmFtIGFkZHJlc3NlcwlhcnJheSBvZiBJbnRlcm5ldEFkZHJlc3Mgb2JqZWN0cworICAgICAqIEBleGNlcHRpb24gCUNsYXNzQ2FzdEV4Y2VwdGlvbiBpZiBhbnkgYWRkcmVzcyBvYmplY3QgaW4gdGhlIAorICAgICAqCQkJZ2l2ZW4gYXJyYXkgaXMgbm90IGFuIEludGVybmV0QWRkcmVzcyBvYmplY3QuIE5vdGUKKyAgICAgKgkJCXRoYXQgdGhpcyBpcyBhIFJ1bnRpbWVFeGNlcHRpb24uCisgICAgICogQHJldHVybgkJY29tbWEgc2VwYXJhdGVkIHN0cmluZyBvZiBhZGRyZXNzZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyB0b1N0cmluZyhBZGRyZXNzW10gYWRkcmVzc2VzKSB7CisJcmV0dXJuIHRvU3RyaW5nKGFkZHJlc3NlcywgMCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydCB0aGUgZ2l2ZW4gYXJyYXkgb2YgSW50ZXJuZXRBZGRyZXNzIG9iamVjdHMgaW50bworICAgICAqIGEgY29tbWEgc2VwYXJhdGVkIHNlcXVlbmNlIG9mIGFkZHJlc3Mgc3RyaW5ncy4gVGhlCisgICAgICogcmVzdWx0aW5nIHN0cmluZyBjb250YWlucyBVbmljb2RlIGNoYXJhY3RlcnMuIDxwPgorICAgICAqCisgICAgICogQHBhcmFtIGFkZHJlc3NlcwlhcnJheSBvZiBJbnRlcm5ldEFkZHJlc3Mgb2JqZWN0cworICAgICAqIEBleGNlcHRpb24gCUNsYXNzQ2FzdEV4Y2VwdGlvbiBpZiBhbnkgYWRkcmVzcyBvYmplY3QgaW4gdGhlIAorICAgICAqCQkJZ2l2ZW4gYXJyYXkgaXMgbm90IGFuIEludGVybmV0QWRkcmVzcyBvYmplY3QuIE5vdGUKKyAgICAgKgkJCXRoYXQgdGhpcyBpcyBhIFJ1bnRpbWVFeGNlcHRpb24uCisgICAgICogQHJldHVybgkJY29tbWEgc2VwYXJhdGVkIHN0cmluZyBvZiBhZGRyZXNzZXMKKyAgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuNgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHRvVW5pY29kZVN0cmluZyhBZGRyZXNzW10gYWRkcmVzc2VzKSB7CisJcmV0dXJuIHRvVW5pY29kZVN0cmluZyhhZGRyZXNzZXMsIDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlcnQgdGhlIGdpdmVuIGFycmF5IG9mIEludGVybmV0QWRkcmVzcyBvYmplY3RzIGludG8KKyAgICAgKiBhIGNvbW1hIHNlcGFyYXRlZCBzZXF1ZW5jZSBvZiBhZGRyZXNzIHN0cmluZ3MuIFRoZQorICAgICAqIHJlc3VsdGluZyBzdHJpbmcgY29udGFpbnMgb25seSBVUy1BU0NJSSBjaGFyYWN0ZXJzLCBhbmQKKyAgICAgKiBoZW5jZSBpcyBtYWlsLXNhZmUuIDxwPgorICAgICAqCisgICAgICogVGhlICd1c2VkJyBwYXJhbWV0ZXIgc3BlY2lmaWVzIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVyIHBvc2l0aW9ucworICAgICAqIGFscmVhZHkgdGFrZW4gdXAgaW4gdGhlIGZpZWxkIGludG8gd2hpY2ggdGhlIHJlc3VsdGluZyBhZGRyZXNzIAorICAgICAqIHNlcXVlbmNlIHN0cmluZyBpcyB0byBiZSBpbnNlcnRlZC4gSXQgaXMgdXNlZCB0byBkZXRlcm1pbmUgdGhlIAorICAgICAqIGxpbmUtYnJlYWsgcG9zaXRpb25zIGluIHRoZSByZXN1bHRpbmcgYWRkcmVzcyBzZXF1ZW5jZSBzdHJpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWRkcmVzc2VzCWFycmF5IG9mIEludGVybmV0QWRkcmVzcyBvYmplY3RzCisgICAgICogQHBhcmFtIHVzZWQJbnVtYmVyIG9mIGNoYXJhY3RlciBwb3NpdGlvbnMgYWxyZWFkeSB1c2VkLCBpbgorICAgICAqCQkJdGhlIGZpZWxkIGludG8gd2hpY2ggdGhlIGFkZHJlc3Mgc3RyaW5nIGlzIHRvCisgICAgICoJCQliZSBpbnNlcnRlZC4KKyAgICAgKiBAZXhjZXB0aW9uIAlDbGFzc0Nhc3RFeGNlcHRpb24gaWYgYW55IGFkZHJlc3Mgb2JqZWN0IGluIHRoZSAKKyAgICAgKgkJCWdpdmVuIGFycmF5IGlzIG5vdCBhbiBJbnRlcm5ldEFkZHJlc3Mgb2JqZWN0LiBOb3RlCisgICAgICoJCQl0aGF0IHRoaXMgaXMgYSBSdW50aW1lRXhjZXB0aW9uLgorICAgICAqIEByZXR1cm4JCWNvbW1hIHNlcGFyYXRlZCBzdHJpbmcgb2YgYWRkcmVzc2VzCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdG9TdHJpbmcoQWRkcmVzc1tdIGFkZHJlc3NlcywgaW50IHVzZWQpIHsKKwlpZiAoYWRkcmVzc2VzID09IG51bGwgfHwgYWRkcmVzc2VzLmxlbmd0aCA9PSAwKQorCSAgICByZXR1cm4gbnVsbDsKKworCVN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworCisJZm9yIChpbnQgaSA9IDA7IGkgPCBhZGRyZXNzZXMubGVuZ3RoOyBpKyspIHsKKwkgICAgaWYgKGkgIT0gMCkgeyAvLyBuZWVkIHRvIGFwcGVuZCBjb21tYQorCQlzYi5hcHBlbmQoIiwgIik7CisJCXVzZWQgKz0gMjsKKwkgICAgfQorCisJICAgIC8vIHByZWZlciBub3QgdG8gc3BsaXQgYSBzaW5nbGUgYWRkcmVzcyBhY3Jvc3MgbGluZXMgc28gdXNlZD0wIGJlbG93CisJICAgIFN0cmluZyBzID0gTWltZVV0aWxpdHkuZm9sZCgwLCBhZGRyZXNzZXNbaV0udG9TdHJpbmcoKSk7CisJICAgIGludCBsZW4gPSBsZW5ndGhPZkZpcnN0U2VnbWVudChzKTsgLy8gbGVuZ3RoIHRpbGwgQ1JMRgorCSAgICBpZiAodXNlZCArIGxlbiA+IDc2KSB7IC8vIG92ZXJmbG93cyAuLi4KKwkJLy8gc21hc2ggdHJhaWxpbmcgc3BhY2UgZnJvbSAiLCAiIGFib3ZlCisJCWludCBjdXJsZW4gPSBzYi5sZW5ndGgoKTsKKwkJaWYgKGN1cmxlbiA+IDAgJiYgc2IuY2hhckF0KGN1cmxlbiAtIDEpID09ICcgJykKKwkJICAgIHNiLnNldExlbmd0aChjdXJsZW4gLSAxKTsKKwkJc2IuYXBwZW5kKCJcclxuXHQiKTsgLy8gLi4gc3RhcnQgbmV3IGNvbnRpbnVhdGlvbiBsaW5lCisJCXVzZWQgPSA4OyAvLyBhY2NvdW50IGZvciB0aGUgc3RhcnRpbmcgPHRhYj4gY2hhcgorCSAgICB9CisJICAgIHNiLmFwcGVuZChzKTsKKwkgICAgdXNlZCA9IGxlbmd0aE9mTGFzdFNlZ21lbnQocywgdXNlZCk7CisJfQorCisJcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydCB0aGUgZ2l2ZW4gYXJyYXkgb2YgSW50ZXJuZXRBZGRyZXNzIG9iamVjdHMgaW50bworICAgICAqIGEgY29tbWEgc2VwYXJhdGVkIHNlcXVlbmNlIG9mIGFkZHJlc3Mgc3RyaW5ncy4gVGhlCisgICAgICogcmVzdWx0aW5nIHN0cmluZyBjb250YWlucyBVbmljb2RlIGNoYXJhY3RlcnMuIDxwPgorICAgICAqCisgICAgICogVGhlICd1c2VkJyBwYXJhbWV0ZXIgc3BlY2lmaWVzIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVyIHBvc2l0aW9ucworICAgICAqIGFscmVhZHkgdGFrZW4gdXAgaW4gdGhlIGZpZWxkIGludG8gd2hpY2ggdGhlIHJlc3VsdGluZyBhZGRyZXNzIAorICAgICAqIHNlcXVlbmNlIHN0cmluZyBpcyB0byBiZSBpbnNlcnRlZC4gSXQgaXMgdXNlZCB0byBkZXRlcm1pbmUgdGhlIAorICAgICAqIGxpbmUtYnJlYWsgcG9zaXRpb25zIGluIHRoZSByZXN1bHRpbmcgYWRkcmVzcyBzZXF1ZW5jZSBzdHJpbmcuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWRkcmVzc2VzCWFycmF5IG9mIEludGVybmV0QWRkcmVzcyBvYmplY3RzCisgICAgICogQHBhcmFtIHVzZWQJbnVtYmVyIG9mIGNoYXJhY3RlciBwb3NpdGlvbnMgYWxyZWFkeSB1c2VkLCBpbgorICAgICAqCQkJdGhlIGZpZWxkIGludG8gd2hpY2ggdGhlIGFkZHJlc3Mgc3RyaW5nIGlzIHRvCisgICAgICoJCQliZSBpbnNlcnRlZC4KKyAgICAgKiBAZXhjZXB0aW9uIAlDbGFzc0Nhc3RFeGNlcHRpb24gaWYgYW55IGFkZHJlc3Mgb2JqZWN0IGluIHRoZSAKKyAgICAgKgkJCWdpdmVuIGFycmF5IGlzIG5vdCBhbiBJbnRlcm5ldEFkZHJlc3Mgb2JqZWN0LiBOb3RlCisgICAgICoJCQl0aGF0IHRoaXMgaXMgYSBSdW50aW1lRXhjZXB0aW9uLgorICAgICAqIEByZXR1cm4JCWNvbW1hIHNlcGFyYXRlZCBzdHJpbmcgb2YgYWRkcmVzc2VzCisgICAgICogQHNpbmNlCQlKYXZhTWFpbCAxLjYKKyAgICAgKi8KKyAgICAvKgorICAgICAqIFhYWCAtIFRoaXMgaXMgZXhhY3RseSB0aGUgc2FtZSBhcyB0aGUgYWJvdmUsIGV4Y2VwdCBpdCB1c2VzCisgICAgICoJICAgICB0b1VuaWNvZGVTdHJpbmcgaW5zdGVhZCBvZiB0b1N0cmluZy4KKyAgICAgKiBYWFggLSBTaW5jZSB0aGUgbGluZSBsZW5ndGggcmVzdHJpY3Rpb25zIGFyZSBpbiBieXRlcywgbm90IGNoYXJhY3RlcnMsCisgICAgICoJICAgICB3ZSBjb252ZXJ0IGFsbCBub24tQVNDSUkgYWRkcmVzc2VzIHRvIFVURi04IGJ5dGUgc3RyaW5ncywKKyAgICAgKgkgICAgIHdoaWNoIHdlIHRoZW4gY29udmVydCB0byBJU08tODg1OS0xIFN0cmluZ3Mgd2hlcmUgZXZlcnkKKyAgICAgKgkgICAgIGNoYXJhY3RlciByZXNwcmVzZW50cyBvbmUgVVRGLTggYnl0ZS4gIEF0IHRoZSBlbmQgd2UgcmV2ZXJzZQorICAgICAqCSAgICAgdGhlIGNvbnZlcnNpb24gdG8gZ2V0IGJhY2sgdG8gYSBjb3JyZWN0IFVuaWNvZGUgc3RyaW5nLgorICAgICAqCSAgICAgVGhpcyBpcyBhIGhhY2sgdG8gYWxsb3cgYWxsIHRoZSBvdGhlciBjaGFyYWN0ZXItYmFzZWQgbWV0aG9kcworICAgICAqCSAgICAgdG8gd29yayBwcm9wZXJseSB3aXRoIFVURi04IGJ5dGVzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHRvVW5pY29kZVN0cmluZyhBZGRyZXNzW10gYWRkcmVzc2VzLCBpbnQgdXNlZCkgeworCWlmIChhZGRyZXNzZXMgPT0gbnVsbCB8fCBhZGRyZXNzZXMubGVuZ3RoID09IDApCisJICAgIHJldHVybiBudWxsOworCisJU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisKKwlib29sZWFuIHNhd05vbkFzY2lpID0gZmFsc2U7CisJZm9yIChpbnQgaSA9IDA7IGkgPCBhZGRyZXNzZXMubGVuZ3RoOyBpKyspIHsKKwkgICAgaWYgKGkgIT0gMCkgeyAvLyBuZWVkIHRvIGFwcGVuZCBjb21tYQorCQlzYi5hcHBlbmQoIiwgIik7CisJCXVzZWQgKz0gMjsKKwkgICAgfQorCisJICAgIC8vIHByZWZlciBub3QgdG8gc3BsaXQgYSBzaW5nbGUgYWRkcmVzcyBhY3Jvc3MgbGluZXMgc28gdXNlZD0wIGJlbG93CisJICAgIFN0cmluZyBhcyA9ICgoSW50ZXJuZXRBZGRyZXNzKWFkZHJlc3Nlc1tpXSkudG9Vbmljb2RlU3RyaW5nKCk7CisJICAgIGlmIChNaW1lVXRpbGl0eS5jaGVja0FzY2lpKGFzKSAhPSBNaW1lVXRpbGl0eS5BTExfQVNDSUkpIHsKKwkJc2F3Tm9uQXNjaWkgPSB0cnVlOworCQlhcyA9IG5ldyBTdHJpbmcoYXMuZ2V0Qnl0ZXMoU3RhbmRhcmRDaGFyc2V0cy5VVEZfOCksCisJICAgIAkJCVN0YW5kYXJkQ2hhcnNldHMuSVNPXzg4NTlfMSk7CisJICAgIH0KKwkgICAgU3RyaW5nIHMgPSBNaW1lVXRpbGl0eS5mb2xkKDAsIGFzKTsKKwkgICAgaW50IGxlbiA9IGxlbmd0aE9mRmlyc3RTZWdtZW50KHMpOyAvLyBsZW5ndGggdGlsbCBDUkxGCisJICAgIGlmICh1c2VkICsgbGVuID4gNzYpIHsgLy8gb3ZlcmZsb3dzIC4uLgorCQkvLyBzbWFzaCB0cmFpbGluZyBzcGFjZSBmcm9tICIsICIgYWJvdmUKKwkJaW50IGN1cmxlbiA9IHNiLmxlbmd0aCgpOworCQlpZiAoY3VybGVuID4gMCAmJiBzYi5jaGFyQXQoY3VybGVuIC0gMSkgPT0gJyAnKQorCQkgICAgc2Iuc2V0TGVuZ3RoKGN1cmxlbiAtIDEpOworCQlzYi5hcHBlbmQoIlxyXG5cdCIpOyAvLyAuLiBzdGFydCBuZXcgY29udGludWF0aW9uIGxpbmUKKwkJdXNlZCA9IDg7IC8vIGFjY291bnQgZm9yIHRoZSBzdGFydGluZyA8dGFiPiBjaGFyCisJICAgIH0KKwkgICAgc2IuYXBwZW5kKHMpOworCSAgICB1c2VkID0gbGVuZ3RoT2ZMYXN0U2VnbWVudChzLCB1c2VkKTsKKwl9CisKKwlTdHJpbmcgcmV0ID0gc2IudG9TdHJpbmcoKTsKKwlpZiAoc2F3Tm9uQXNjaWkpCisJICAgIHJldCA9IG5ldyBTdHJpbmcocmV0LmdldEJ5dGVzKFN0YW5kYXJkQ2hhcnNldHMuSVNPXzg4NTlfMSksCisJCQkJU3RhbmRhcmRDaGFyc2V0cy5VVEZfOCk7CisgICAgCXJldHVybiByZXQ7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBSZXR1cm4gdGhlIGxlbmd0aCBvZiB0aGUgZmlyc3Qgc2VnbWVudCB3aXRoaW4gdGhpcyBzdHJpbmcuCisgICAgICogSWYgbm8gc2VnbWVudHMgZXhpc3QsIHRoZSBsZW5ndGggb2YgdGhlIHdob2xlIGxpbmUgaXMgcmV0dXJuZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IGxlbmd0aE9mRmlyc3RTZWdtZW50KFN0cmluZyBzKSB7CisJaW50IHBvczsKKwlpZiAoKHBvcyA9IHMuaW5kZXhPZigiXHJcbiIpKSAhPSAtMSkKKwkgICAgcmV0dXJuIHBvczsKKwllbHNlCisJICAgIHJldHVybiBzLmxlbmd0aCgpOworICAgIH0KKworICAgIC8qCisgICAgICogUmV0dXJuIHRoZSBsZW5ndGggb2YgdGhlIGxhc3Qgc2VnbWVudCB3aXRoaW4gdGhpcyBzdHJpbmcuCisgICAgICogSWYgbm8gc2VnbWVudHMgZXhpc3QsIHRoZSBsZW5ndGggb2YgdGhlIHdob2xlIGxpbmUgcGx1cworICAgICAqIDxjb2RlPnVzZWQ8L2NvZGU+IGlzIHJldHVybmVkLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGludCBsZW5ndGhPZkxhc3RTZWdtZW50KFN0cmluZyBzLCBpbnQgdXNlZCkgeworCWludCBwb3M7CisJaWYgKChwb3MgPSBzLmxhc3RJbmRleE9mKCJcclxuIikpICE9IC0xKQorCSAgICByZXR1cm4gcy5sZW5ndGgoKSAtIHBvcyAtIDI7CisJZWxzZSAKKwkgICAgcmV0dXJuIHMubGVuZ3RoKCkgKyB1c2VkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiBhbiBJbnRlcm5ldEFkZHJlc3Mgb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgY3VycmVudCB1c2VyLgorICAgICAqIFRoZSBlbnRpcmUgZW1haWwgYWRkcmVzcyBtYXkgYmUgc3BlY2lmaWVkIGluIHRoZSAibWFpbC5mcm9tIgorICAgICAqIHByb3BlcnR5LiAgSWYgbm90IHNldCwgdGhlICJtYWlsLnVzZXIiIGFuZCAibWFpbC5ob3N0IiBwcm9wZXJ0aWVzCisgICAgICogYXJlIHRyaWVkLiAgSWYgdGhvc2UgYXJlIG5vdCBzZXQsIHRoZSAidXNlci5uYW1lIiBwcm9wZXJ0eSBhbmQKKyAgICAgKiA8Y29kZT5JbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3Q8L2NvZGU+IG1ldGhvZCBhcmUgdHJpZWQuCisgICAgICogU2VjdXJpdHkgZXhjZXB0aW9ucyB0aGF0IG1heSBvY2N1ciB3aGlsZSBhY2Nlc3NpbmcgdGhpcyBpbmZvcm1hdGlvbgorICAgICAqIGFyZSBpZ25vcmVkLiAgSWYgaXQgaXMgbm90IHBvc3NpYmxlIHRvIGRldGVybWluZSBhbiBlbWFpbCBhZGRyZXNzLAorICAgICAqIG51bGwgaXMgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jc2Vzc2lvbgkJU2Vzc2lvbiBvYmplY3QgdXNlZCBmb3IgcHJvcGVydHkgbG9va3VwCisgICAgICogQHJldHVybgkJCWN1cnJlbnQgdXNlcidzIGVtYWlsIGFkZHJlc3MKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEludGVybmV0QWRkcmVzcyBnZXRMb2NhbEFkZHJlc3MoU2Vzc2lvbiBzZXNzaW9uKSB7CisJdHJ5IHsKKwkgICAgcmV0dXJuIF9nZXRMb2NhbEFkZHJlc3Moc2Vzc2lvbik7CisJfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gc2V4KSB7CS8vIGlnbm9yZSBpdAorCX0gY2F0Y2ggKEFkZHJlc3NFeGNlcHRpb24gZXgpIHsJCS8vIGlnbm9yZSBpdAorCX0gY2F0Y2ggKFVua25vd25Ib3N0RXhjZXB0aW9uIGV4KSB7IH0JLy8gaWdub3JlIGl0CisJcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogQSBwYWNrYWdlLXByaXZhdGUgdmVyc2lvbiBvZiBnZXRMb2NhbEFkZHJlc3MgdGhhdCBkb2Vzbid0IHN3YWxsb3cKKyAgICAgKiB0aGUgZXhjZXB0aW9uLiAgVXNlZCBieSBNaW1lTWVzc2FnZS5zZXRGcm9tKCkgdG8gcmVwb3J0IHRoZSByZWFzb24KKyAgICAgKiBmb3IgdGhlIGZhaWx1cmUuCisgICAgICovCisgICAgLy8gcGFja2FnZS1wcml2YXRlCisgICAgc3RhdGljIEludGVybmV0QWRkcmVzcyBfZ2V0TG9jYWxBZGRyZXNzKFNlc3Npb24gc2Vzc2lvbikKKwkgICAgdGhyb3dzIFNlY3VyaXR5RXhjZXB0aW9uLCBBZGRyZXNzRXhjZXB0aW9uLCBVbmtub3duSG9zdEV4Y2VwdGlvbiB7CisJU3RyaW5nIHVzZXIgPSBudWxsLCBob3N0ID0gbnVsbCwgYWRkcmVzcyA9IG51bGw7CisJaWYgKHNlc3Npb24gPT0gbnVsbCkgeworCSAgICB1c2VyID0gU3lzdGVtLmdldFByb3BlcnR5KCJ1c2VyLm5hbWUiKTsKKwkgICAgaG9zdCA9IGdldExvY2FsSG9zdE5hbWUoKTsKKwl9IGVsc2UgeworCSAgICBhZGRyZXNzID0gc2Vzc2lvbi5nZXRQcm9wZXJ0eSgibWFpbC5mcm9tIik7CisJICAgIGlmIChhZGRyZXNzID09IG51bGwpIHsKKwkJdXNlciA9IHNlc3Npb24uZ2V0UHJvcGVydHkoIm1haWwudXNlciIpOworCQlpZiAodXNlciA9PSBudWxsIHx8IHVzZXIubGVuZ3RoKCkgPT0gMCkKKwkJICAgIHVzZXIgPSBzZXNzaW9uLmdldFByb3BlcnR5KCJ1c2VyLm5hbWUiKTsKKwkJaWYgKHVzZXIgPT0gbnVsbCB8fCB1c2VyLmxlbmd0aCgpID09IDApCisJCSAgICB1c2VyID0gU3lzdGVtLmdldFByb3BlcnR5KCJ1c2VyLm5hbWUiKTsKKwkJaG9zdCA9IHNlc3Npb24uZ2V0UHJvcGVydHkoIm1haWwuaG9zdCIpOworCQlpZiAoaG9zdCA9PSBudWxsIHx8IGhvc3QubGVuZ3RoKCkgPT0gMCkKKwkJICAgIGhvc3QgPSBnZXRMb2NhbEhvc3ROYW1lKCk7CisJICAgIH0KKwl9CisKKwlpZiAoYWRkcmVzcyA9PSBudWxsICYmIHVzZXIgIT0gbnVsbCAmJiB1c2VyLmxlbmd0aCgpICE9IDAgJiYKKwkJaG9zdCAhPSBudWxsICYmIGhvc3QubGVuZ3RoKCkgIT0gMCkKKwkgICAgYWRkcmVzcyA9IE1pbWVVdGlsaXR5LnF1b3RlKHVzZXIudHJpbSgpLCBzcGVjaWFsc05vRG90ICsgIlx0ICIpICsKKwkJCQkJCQkgICAgIkAiICsgaG9zdDsKKworCWlmIChhZGRyZXNzID09IG51bGwpCisJICAgIHJldHVybiBudWxsOworCisJcmV0dXJuIG5ldyBJbnRlcm5ldEFkZHJlc3MoYWRkcmVzcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBsb2NhbCBob3N0IG5hbWUgZnJvbSBJbmV0QWRkcmVzcyBhbmQgcmV0dXJuIGl0IGluIGEgZm9ybQorICAgICAqIHN1aXRhYmxlIGZvciB1c2UgaW4gYW4gZW1haWwgYWRkcmVzcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZ2V0TG9jYWxIb3N0TmFtZSgpIHRocm93cyBVbmtub3duSG9zdEV4Y2VwdGlvbiB7CisJU3RyaW5nIGhvc3QgPSBudWxsOworCUluZXRBZGRyZXNzIG1lID0gSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCk7CisJaWYgKG1lICE9IG51bGwpIHsKKwkgICAgLy8gdHJ5IGNhbm9uaWNhbCBob3N0IG5hbWUgZmlyc3QKKwkgICAgaWYgKHVzZUNhbm9uaWNhbEhvc3ROYW1lKQorCQlob3N0ID0gbWUuZ2V0Q2Fub25pY2FsSG9zdE5hbWUoKTsKKwkgICAgaWYgKGhvc3QgPT0gbnVsbCkKKwkJaG9zdCA9IG1lLmdldEhvc3ROYW1lKCk7CisJICAgIC8vIGlmIHdlIGNhbid0IGdldCBvdXIgbmFtZSwgdXNlIGxvY2FsIGFkZHJlc3MgbGl0ZXJhbAorCSAgICBpZiAoaG9zdCA9PSBudWxsKQorCQlob3N0ID0gbWUuZ2V0SG9zdEFkZHJlc3MoKTsKKwkgICAgaWYgKGhvc3QgIT0gbnVsbCAmJiBob3N0Lmxlbmd0aCgpID4gMCAmJiBpc0luZXRBZGRyZXNzTGl0ZXJhbChob3N0KSkKKwkJaG9zdCA9ICdbJyArIGhvc3QgKyAnXSc7CisJfQorCXJldHVybiBob3N0OworICAgIH0KKworICAgIC8qKgorICAgICAqIElzIHRoZSBhZGRyZXNzIGFuIElQdjQgb3IgSVB2NiBhZGRyZXNzIGxpdGVyYWwsIHdoaWNoIG5lZWRzIHRvCisgICAgICogYmUgZW5jbG9zZWQgaW4gIltdIiBpbiBhbiBlbWFpbCBhZGRyZXNzPyAgSVB2NCBsaXRlcmFscyBjb250YWluCisgICAgICogZGVjaW1hbCBkaWdpdHMgYW5kIGRvdHMsIElQdjYgbGl0ZXJhbHMgY29udGFpbiBoZXggZGlnaXRzLCBkb3RzLAorICAgICAqIGFuZCBjb2xvbnMuICBXZSdyZSBsYXp5IGFuZCBkb24ndCBjaGVjayB0aGUgZXhhY3Qgc3ludGF4LCBqdXN0CisgICAgICogdGhlIGFsbG93ZWQgY2hhcmFjdGVyczsgc3RyaW5ncyB0aGF0IGhhdmUgb25seSB0aGUgYWxsb3dlZAorICAgICAqIGNoYXJhY3RlcnMgaW4gYSBsaXRlcmFsIGJ1dCBkb24ndCBtZWV0IHRoZSBzeW50YXggcmVxdWlyZW1lbnRzCisgICAgICogZm9yIGEgbGl0ZXJhbCBkZWZpbml0ZWx5IGNhbid0IGJlIGEgaG9zdCBuYW1lIGFuZCB0aHVzIHdpbGwgZmFpbAorICAgICAqIGxhdGVyIHdoZW4gdXNlZCBhcyBhbiBhZGRyZXNzIGxpdGVyYWwuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc0luZXRBZGRyZXNzTGl0ZXJhbChTdHJpbmcgYWRkcikgeworCWJvb2xlYW4gc2F3SGV4ID0gZmFsc2UsIHNhd0NvbG9uID0gZmFsc2U7CisJZm9yIChpbnQgaSA9IDA7IGkgPCBhZGRyLmxlbmd0aCgpOyBpKyspIHsKKwkgICAgY2hhciBjID0gYWRkci5jaGFyQXQoaSk7CisJICAgIGlmIChjID49ICcwJyAmJiBjIDw9ICc5JykKKwkJOwkvLyBkaWdpdHMgYWx3YXlzIG9rCisJICAgIGVsc2UgaWYgKGMgPT0gJy4nKQorCQk7CS8vIGRvdCBhbHdheXMgb2sKKwkgICAgZWxzZSBpZiAoKGMgPj0gJ2EnICYmIGMgPD0gJ3onKSB8fCAoYyA+PSAnQScgJiYgYyA8PSAnWicpKQorCQlzYXdIZXggPSB0cnVlOwkvLyBuZWVkIHRvIHNlZSBhIGNvbG9uIHRvbworCSAgICBlbHNlIGlmIChjID09ICc6JykKKwkJc2F3Q29sb24gPSB0cnVlOworCSAgICBlbHNlCisJCXJldHVybiBmYWxzZTsJLy8gYW55dGhpbmcgZWxzZSwgZGVmaW5pdGVseSBub3QgYSBsaXRlcmFsCisJfQorCXJldHVybiAhc2F3SGV4IHx8IHNhd0NvbG9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlIHRoZSBnaXZlbiBjb21tYSBzZXBhcmF0ZWQgc2VxdWVuY2Ugb2YgYWRkcmVzc2VzIGludG8KKyAgICAgKiBJbnRlcm5ldEFkZHJlc3Mgb2JqZWN0cy4gIEFkZHJlc3NlcyBtdXN0IGZvbGxvdyBSRkM4MjIgc3ludGF4LgorICAgICAqCisgICAgICogQHBhcmFtIGFkZHJlc3NsaXN0CWNvbW1hIHNlcGFyYXRlZCBhZGRyZXNzIHN0cmluZ3MKKyAgICAgKiBAcmV0dXJuCQkJYXJyYXkgb2YgSW50ZXJuZXRBZGRyZXNzIG9iamVjdHMKKyAgICAgKiBAZXhjZXB0aW9uCQlBZGRyZXNzRXhjZXB0aW9uIGlmIHRoZSBwYXJzZSBmYWlsZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEludGVybmV0QWRkcmVzc1tdIHBhcnNlKFN0cmluZyBhZGRyZXNzbGlzdCkgCisJCQkJdGhyb3dzIEFkZHJlc3NFeGNlcHRpb24geworCXJldHVybiBwYXJzZShhZGRyZXNzbGlzdCwgdHJ1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2UgdGhlIGdpdmVuIHNlcXVlbmNlIG9mIGFkZHJlc3NlcyBpbnRvIEludGVybmV0QWRkcmVzcworICAgICAqIG9iamVjdHMuICBJZiA8Y29kZT5zdHJpY3Q8L2NvZGU+IGlzIGZhbHNlLCBzaW1wbGUgZW1haWwgYWRkcmVzc2VzCisgICAgICogc2VwYXJhdGVkIGJ5IHNwYWNlcyBhcmUgYWxzbyBhbGxvd2VkLiAgSWYgPGNvZGU+c3RyaWN0PC9jb2RlPiBpcworICAgICAqIHRydWUsIG1hbnkgKGJ1dCBub3QgYWxsKSBvZiB0aGUgUkZDODIyIHN5bnRheCBydWxlcyBhcmUgZW5mb3JjZWQuCisgICAgICogSW4gcGFydGljdWxhciwgZXZlbiBpZiA8Y29kZT5zdHJpY3Q8L2NvZGU+IGlzIHRydWUsIGFkZHJlc3NlcworICAgICAqIGNvbXBvc2VkIG9mIHNpbXBsZSBuYW1lcyAod2l0aCBubyAiQGRvbWFpbiIgcGFydCkgYXJlIGFsbG93ZWQuCisgICAgICogU3VjaCAiaWxsZWdhbCIgYWRkcmVzc2VzIGFyZSBub3QgdW5jb21tb24gaW4gcmVhbCBtZXNzYWdlcy4gPHA+CisgICAgICoKKyAgICAgKiBOb24tc3RyaWN0IHBhcnNpbmcgaXMgdHlwaWNhbGx5IHVzZWQgd2hlbiBwYXJzaW5nIGEgbGlzdCBvZgorICAgICAqIG1haWwgYWRkcmVzc2VzIGVudGVyZWQgYnkgYSBodW1hbi4gIFN0cmljdCBwYXJzaW5nIGlzIHR5cGljYWxseQorICAgICAqIHVzZWQgd2hlbiBwYXJzaW5nIGFkZHJlc3MgaGVhZGVycyBpbiBtYWlsIG1lc3NhZ2VzLgorICAgICAqCisgICAgICogQHBhcmFtCWFkZHJlc3NsaXN0CWNvbW1hIHNlcGFyYXRlZCBhZGRyZXNzIHN0cmluZ3MKKyAgICAgKiBAcGFyYW0Jc3RyaWN0CQllbmZvcmNlIFJGQzgyMiBzeW50YXgKKyAgICAgKiBAcmV0dXJuCQkJYXJyYXkgb2YgSW50ZXJuZXRBZGRyZXNzIG9iamVjdHMKKyAgICAgKiBAZXhjZXB0aW9uCQlBZGRyZXNzRXhjZXB0aW9uIGlmIHRoZSBwYXJzZSBmYWlsZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEludGVybmV0QWRkcmVzc1tdIHBhcnNlKFN0cmluZyBhZGRyZXNzbGlzdCwgYm9vbGVhbiBzdHJpY3QpCisJCQkJCSAgICB0aHJvd3MgQWRkcmVzc0V4Y2VwdGlvbiB7CisJcmV0dXJuIHBhcnNlKGFkZHJlc3NsaXN0LCBzdHJpY3QsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZSB0aGUgZ2l2ZW4gc2VxdWVuY2Ugb2YgYWRkcmVzc2VzIGludG8gSW50ZXJuZXRBZGRyZXNzCisgICAgICogb2JqZWN0cy4gIElmIDxjb2RlPnN0cmljdDwvY29kZT4gaXMgZmFsc2UsIHRoZSBmdWxsIHN5bnRheCBydWxlcyBmb3IKKyAgICAgKiBpbmRpdmlkdWFsIGFkZHJlc3NlcyBhcmUgbm90IGVuZm9yY2VkLiAgSWYgPGNvZGU+c3RyaWN0PC9jb2RlPiBpcworICAgICAqIHRydWUsIG1hbnkgKGJ1dCBub3QgYWxsKSBvZiB0aGUgUkZDODIyIHN5bnRheCBydWxlcyBhcmUgZW5mb3JjZWQuIDxwPgorICAgICAqCisgICAgICogVG8gYmV0dGVyIHN1cHBvcnQgdGhlIHJhbmdlIG9mICJpbnZhbGlkIiBhZGRyZXNzZXMgc2VlbiBpbiByZWFsCisgICAgICogbWVzc2FnZXMsIHRoaXMgbWV0aG9kIGVuZm9yY2VzIGZld2VyIHN5bnRheCBydWxlcyB0aGFuIHRoZQorICAgICAqIDxjb2RlPnBhcnNlPC9jb2RlPiBtZXRob2Qgd2hlbiB0aGUgc3RyaWN0IGZsYWcgaXMgZmFsc2UKKyAgICAgKiBhbmQgZW5mb3JjZXMgbW9yZSBydWxlcyB3aGVuIHRoZSBzdHJpY3QgZmxhZyBpcyB0cnVlLiAgSWYgdGhlCisgICAgICogc3RyaWN0IGZsYWcgaXMgZmFsc2UgYW5kIHRoZSBwYXJzZSBpcyBzdWNjZXNzZnVsIGluIHNlcGFyYXRpbmcgb3V0IGFuCisgICAgICogZW1haWwgYWRkcmVzcyBvciBhZGRyZXNzZXMsIHRoZSBzeW50YXggb2YgdGhlIGFkZHJlc3NlcyB0aGVtc2VsdmVzCisgICAgICogaXMgbm90IGNoZWNrZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0JYWRkcmVzc2xpc3QJY29tbWEgc2VwYXJhdGVkIGFkZHJlc3Mgc3RyaW5ncworICAgICAqIEBwYXJhbQlzdHJpY3QJCWVuZm9yY2UgUkZDODIyIHN5bnRheAorICAgICAqIEByZXR1cm4JCQlhcnJheSBvZiBJbnRlcm5ldEFkZHJlc3Mgb2JqZWN0cworICAgICAqIEBleGNlcHRpb24JCUFkZHJlc3NFeGNlcHRpb24gaWYgdGhlIHBhcnNlIGZhaWxlZAorICAgICAqIEBzaW5jZQkJCUphdmFNYWlsIDEuMworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgSW50ZXJuZXRBZGRyZXNzW10gcGFyc2VIZWFkZXIoU3RyaW5nIGFkZHJlc3NsaXN0LAorCQkJCWJvb2xlYW4gc3RyaWN0KSB0aHJvd3MgQWRkcmVzc0V4Y2VwdGlvbiB7CisJcmV0dXJuIHBhcnNlKE1pbWVVdGlsaXR5LnVuZm9sZChhZGRyZXNzbGlzdCksIHN0cmljdCwgdHJ1ZSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBSRkM4MjIgQWRkcmVzcyBwYXJzZXIuCisgICAgICoKKyAgICAgKiBYWFggLSBUaGlzIGlzIGNvbXBsZXggZW5vdWdoIHRoYXQgaXQgb3VnaHQgdG8gYmUgYSByZWFsIHBhcnNlciwKKyAgICAgKiAgICAgICBub3QgdGhpcyBhZC1ob2MgbWVzcywgYW5kIGJlY2F1c2Ugb2YgdGhhdCwgdGhpcyBpcyBub3QgcGVyZmVjdC4KKyAgICAgKgorICAgICAqIFhYWCAtIERlYWwgd2l0aCBlbmNvZGVkIEhlYWRlcnMgdG9vLgorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJmYWxsdGhyb3VnaCIpCisgICAgcHJpdmF0ZSBzdGF0aWMgSW50ZXJuZXRBZGRyZXNzW10gcGFyc2UoU3RyaW5nIHMsIGJvb2xlYW4gc3RyaWN0LAorCQkJCSAgICBib29sZWFuIHBhcnNlSGRyKSB0aHJvd3MgQWRkcmVzc0V4Y2VwdGlvbiB7CisJaW50IHN0YXJ0LCBlbmQsIGluZGV4LCBuZXN0aW5nOworCWludCBzdGFydF9wZXJzb25hbCA9IC0xLCBlbmRfcGVyc29uYWwgPSAtMTsKKwlpbnQgbGVuZ3RoID0gcy5sZW5ndGgoKTsKKwlib29sZWFuIGlnbm9yZUVycm9ycyA9IHBhcnNlSGRyICYmICFzdHJpY3Q7CisJYm9vbGVhbiBpbl9ncm91cCA9IGZhbHNlOwkvLyB3ZSdyZSBwcm9jZXNzaW5nIGEgZ3JvdXAgdGVybQorCWJvb2xlYW4gcm91dGVfYWRkciA9IGZhbHNlOwkvLyBhZGRyZXNzIGNhbWUgZnJvbSByb3V0ZS1hZGRyIHRlcm0KKwlib29sZWFuIHJmYzgyMiA9IGZhbHNlOwkJLy8gbG9va3MgbGlrZSBhbiBSRkM4MjIgYWRkcmVzcworCWNoYXIgYzsKKwlMaXN0PEludGVybmV0QWRkcmVzcz4gdiA9IG5ldyBBcnJheUxpc3Q8PigpOworCUludGVybmV0QWRkcmVzcyBtYTsKKworCWZvciAoc3RhcnQgPSBlbmQgPSAtMSwgaW5kZXggPSAwOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKykgeworICAgIAkgICAgYyA9IHMuY2hhckF0KGluZGV4KTsKKworCSAgICBzd2l0Y2ggKGMpIHsKKwkgICAgY2FzZSAnKCc6IC8vIFdlIGFyZSBwYXJzaW5nIGEgQ29tbWVudC4gSWdub3JlIGV2ZXJ5dGhpbmcgaW5zaWRlLgorCQkvLyBYWFggLSBjb21tZW50IGZpZWxkcyBzaG91bGQgYmUgcGFyc2VkIGFzIHdoaXRlc3BhY2UsCisJCS8vCSBtb3JlIHRoYW4gb25lIGFsbG93ZWQgcGVyIGFkZHJlc3MKKwkJcmZjODIyID0gdHJ1ZTsKKwkJaWYgKHN0YXJ0ID49IDAgJiYgZW5kID09IC0xKQorCQkgICAgZW5kID0gaW5kZXg7CisJCWludCBwaW5kZXggPSBpbmRleDsKKwkJZm9yIChpbmRleCsrLCBuZXN0aW5nID0gMTsgaW5kZXggPCBsZW5ndGggJiYgbmVzdGluZyA+IDA7CisJCSAgaW5kZXgrKykgeworCQkgICAgYyA9IHMuY2hhckF0KGluZGV4KTsKKwkJICAgIHN3aXRjaCAoYykgeworCQkgICAgY2FzZSAnXFwnOgorCQkJaW5kZXgrKzsgLy8gc2tpcCBib3RoICdcJyBhbmQgdGhlIGVzY2FwZWQgY2hhcgorCQkJYnJlYWs7CisJCSAgICBjYXNlICcoJzoKKwkJCW5lc3RpbmcrKzsKKwkJCWJyZWFrOworCQkgICAgY2FzZSAnKSc6CisJCQluZXN0aW5nLS07CisJCQlicmVhazsKKwkJICAgIGRlZmF1bHQ6CisJCQlicmVhazsKKwkJICAgIH0KKwkJfQorCQlpZiAobmVzdGluZyA+IDApIHsKKwkJICAgIGlmICghaWdub3JlRXJyb3JzKQorCQkJdGhyb3cgbmV3IEFkZHJlc3NFeGNlcHRpb24oIk1pc3NpbmcgJyknIiwgcywgaW5kZXgpOworCQkgICAgLy8gcHJldGVuZCB0aGUgZmlyc3QgcGFyZW4gd2FzIGEgcmVndWxhciBjaGFyYWN0ZXIgYW5kCisJCSAgICAvLyBjb250aW51ZSBwYXJzaW5nIGFmdGVyIGl0CisJCSAgICBpbmRleCA9IHBpbmRleCArIDE7CisJCSAgICBicmVhazsKKwkJfQorCQlpbmRleC0tOwkvLyBwb2ludCB0byBjbG9zaW5nIHBhcmVuCisJCWlmIChzdGFydF9wZXJzb25hbCA9PSAtMSkKKwkJICAgIHN0YXJ0X3BlcnNvbmFsID0gcGluZGV4ICsgMTsKKwkJaWYgKGVuZF9wZXJzb25hbCA9PSAtMSkKKwkJICAgIGVuZF9wZXJzb25hbCA9IGluZGV4OworCQlicmVhazsKKworCSAgICBjYXNlICcpJzoKKwkJaWYgKCFpZ25vcmVFcnJvcnMpCisJCSAgICB0aHJvdyBuZXcgQWRkcmVzc0V4Y2VwdGlvbigiTWlzc2luZyAnKCciLCBzLCBpbmRleCk7CisJCS8vIHByZXRlbmQgdGhlIGxlZnQgcGFyZW4gd2FzIGEgcmVndWxhciBjaGFyYWN0ZXIgYW5kCisJCS8vIGNvbnRpbnVlIHBhcnNpbmcKKwkJaWYgKHN0YXJ0ID09IC0xKQorCQkgICAgc3RhcnQgPSBpbmRleDsKKwkJYnJlYWs7CisKKwkgICAgY2FzZSAnPCc6CisJCXJmYzgyMiA9IHRydWU7CisJCWlmIChyb3V0ZV9hZGRyKSB7CisJCSAgICBpZiAoIWlnbm9yZUVycm9ycykKKwkJCXRocm93IG5ldyBBZGRyZXNzRXhjZXB0aW9uKAorCQkJCQkJIkV4dHJhIHJvdXRlLWFkZHIiLCBzLCBpbmRleCk7CisKKwkJICAgIC8vIGFzc3VtZSBtaXNzaW5nIGNvbW1hIGJldHdlZW4gYWRkcmVzc2VzCisJCSAgICBpZiAoc3RhcnQgPT0gLTEpIHsKKwkJCXJvdXRlX2FkZHIgPSBmYWxzZTsKKwkJCXJmYzgyMiA9IGZhbHNlOworCQkJc3RhcnQgPSBlbmQgPSAtMTsKKwkJCWJyZWFrOwkvLyBub3BlLCBub3RoaW5nIHRoZXJlCisJCSAgICB9CisJCSAgICBpZiAoIWluX2dyb3VwKSB7CisJCQkvLyBnb3QgYSB0b2tlbiwgYWRkIHRoaXMgdG8gb3VyIEludGVybmV0QWRkcmVzcyBsaXN0CisJCQlpZiAoZW5kID09IC0xKQkvLyBzaG91bGQgbmV2ZXIgaGFwcGVuCisJCQkgICAgZW5kID0gaW5kZXg7CisJCQlTdHJpbmcgYWRkciA9IHMuc3Vic3RyaW5nKHN0YXJ0LCBlbmQpLnRyaW0oKTsKKworCQkJbWEgPSBuZXcgSW50ZXJuZXRBZGRyZXNzKCk7CisJCQltYS5zZXRBZGRyZXNzKGFkZHIpOworCQkJaWYgKHN0YXJ0X3BlcnNvbmFsID49IDApIHsKKwkJCSAgICBtYS5lbmNvZGVkUGVyc29uYWwgPSB1bnF1b3RlKAorCQkJCXMuc3Vic3RyaW5nKHN0YXJ0X3BlcnNvbmFsLCBlbmRfcGVyc29uYWwpLgorCQkJCQkJCQl0cmltKCkpOworCQkJfQorCQkJdi5hZGQobWEpOworCisJCQlyb3V0ZV9hZGRyID0gZmFsc2U7CisJCQlyZmM4MjIgPSBmYWxzZTsKKwkJCXN0YXJ0ID0gZW5kID0gLTE7CisJCQlzdGFydF9wZXJzb25hbCA9IGVuZF9wZXJzb25hbCA9IC0xOworCQkJLy8gY29udGludWUgcHJvY2Vzc2luZyB0aGlzIG5ldyBhZGRyZXNzLi4uCisJCSAgICB9CisJCX0KKworCQlpbnQgcmluZGV4ID0gaW5kZXg7CisJCWJvb2xlYW4gaW5xdW90ZSA9IGZhbHNlOworCSAgICAgIG91dGY6CisJCWZvciAoaW5kZXgrKzsgaW5kZXggPCBsZW5ndGg7IGluZGV4KyspIHsKKwkJICAgIGMgPSBzLmNoYXJBdChpbmRleCk7CisJCSAgICBzd2l0Y2ggKGMpIHsKKwkJICAgIGNhc2UgJ1xcJzoJLy8gWFhYIC0gaXMgdGhpcyBuZWVkZWQ/CisJCQlpbmRleCsrOyAvLyBza2lwIGJvdGggJ1wnIGFuZCB0aGUgZXNjYXBlZCBjaGFyCisJCQlicmVhazsKKwkJICAgIGNhc2UgJyInOgorCQkJaW5xdW90ZSA9ICFpbnF1b3RlOworCQkJYnJlYWs7CisJCSAgICBjYXNlICc+JzoKKwkJCWlmIChpbnF1b3RlKQorCQkJICAgIGNvbnRpbnVlOworCQkJYnJlYWsgb3V0ZjsgLy8gb3V0IG9mIGZvciBsb29wCisJCSAgICBkZWZhdWx0OgorCQkJYnJlYWs7CisJCSAgICB9CisJCX0KKworCQkvLyBkaWQgd2UgZmluZCBhIG1hdGNoaW5nIHF1b3RlPworCQlpZiAoaW5xdW90ZSkgeworCQkgICAgaWYgKCFpZ25vcmVFcnJvcnMpCisJCQl0aHJvdyBuZXcgQWRkcmVzc0V4Y2VwdGlvbigiTWlzc2luZyAnXCInIiwgcywgaW5kZXgpOworCQkgICAgLy8gZGlkbid0IGZpbmQgbWF0Y2hpbmcgcXVvdGUsIHRyeSBhZ2FpbiBpZ25vcmluZyBxdW90ZXMKKwkJICAgIC8vIChlLmcuLCBgYDwiQGZvby5jb20+JycpCisJCSAgb3V0cToKKwkJICAgIGZvciAoaW5kZXggPSByaW5kZXggKyAxOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKykgeworCQkJYyA9IHMuY2hhckF0KGluZGV4KTsKKwkJCWlmIChjID09ICdcXCcpCS8vIFhYWCAtIGlzIHRoaXMgbmVlZGVkPworCQkJICAgIGluZGV4Kys7CS8vIHNraXAgYm90aCAnXCcgYW5kIHRoZSBlc2NhcGVkIGNoYXIKKwkJCWVsc2UgaWYgKGMgPT0gJz4nKQorCQkJICAgIGJyZWFrOworCQkgICAgfQorCQl9CisKKwkJLy8gZGlkIHdlIGZpbmQgYSB0ZXJtaW5hdGluZyAnPic/CisJCWlmIChpbmRleCA+PSBsZW5ndGgpIHsKKwkJICAgIGlmICghaWdub3JlRXJyb3JzKQorCQkJdGhyb3cgbmV3IEFkZHJlc3NFeGNlcHRpb24oIk1pc3NpbmcgJz4nIiwgcywgaW5kZXgpOworCQkgICAgLy8gcHJldGVuZCB0aGUgIjwiIHdhcyBhIHJlZ3VsYXIgY2hhcmFjdGVyIGFuZAorCQkgICAgLy8gY29udGludWUgcGFyc2luZyBhZnRlciBpdCAoZS5nLiwgYGA8QGZvby5jb20nJykKKwkJICAgIGluZGV4ID0gcmluZGV4ICsgMTsKKwkJICAgIGlmIChzdGFydCA9PSAtMSkKKwkJCXN0YXJ0ID0gcmluZGV4OwkvLyBiYWNrIHVwIHRvIGluY2x1ZGUgIjwiCisJCSAgICBicmVhazsKKwkJfQorCisJCWlmICghaW5fZ3JvdXApIHsKKwkJICAgIGlmIChzdGFydCA+PSAwKSB7CisJCQkvLyBzZWVuIHNvbWUgY2hhcmFjdGVycz8gIHVzZSB0aGVtIGFzIHRoZSBwZXJzb25hbCBuYW1lCisJCQlzdGFydF9wZXJzb25hbCA9IHN0YXJ0OworCQkJZW5kX3BlcnNvbmFsID0gcmluZGV4OworCQkgICAgfQorCQkgICAgc3RhcnQgPSByaW5kZXggKyAxOworCQl9CisJCXJvdXRlX2FkZHIgPSB0cnVlOworCQllbmQgPSBpbmRleDsKKwkJYnJlYWs7CisKKwkgICAgY2FzZSAnPic6CisJCWlmICghaWdub3JlRXJyb3JzKQorCQkgICAgdGhyb3cgbmV3IEFkZHJlc3NFeGNlcHRpb24oIk1pc3NpbmcgJzwnIiwgcywgaW5kZXgpOworCQkvLyBwcmV0ZW5kIHRoZSAiPiIgd2FzIGEgcmVndWxhciBjaGFyYWN0ZXIgYW5kCisJCS8vIGNvbnRpbnVlIHBhcnNpbmcgKGUuZy4sIGBgPkBmb28uY29tJycpCisJCWlmIChzdGFydCA9PSAtMSkKKwkJICAgIHN0YXJ0ID0gaW5kZXg7CisJCWJyZWFrOworCisJICAgIGNhc2UgJyInOgkvLyBwYXJzZSBxdW90ZWQgc3RyaW5nCisJCWludCBxaW5kZXggPSBpbmRleDsKKwkJcmZjODIyID0gdHJ1ZTsKKwkJaWYgKHN0YXJ0ID09IC0xKQorCQkgICAgc3RhcnQgPSBpbmRleDsKKwkgICAgICBvdXRxOgorCQlmb3IgKGluZGV4Kys7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrKSB7CisJCSAgICBjID0gcy5jaGFyQXQoaW5kZXgpOworCQkgICAgc3dpdGNoIChjKSB7CisJCSAgICBjYXNlICdcXCc6CisJCQlpbmRleCsrOyAvLyBza2lwIGJvdGggJ1wnIGFuZCB0aGUgZXNjYXBlZCBjaGFyCisJCQlicmVhazsKKwkJICAgIGNhc2UgJyInOgorCQkJYnJlYWsgb3V0cTsgLy8gb3V0IG9mIGZvciBsb29wCisJCSAgICBkZWZhdWx0OgorCQkJYnJlYWs7CisJCSAgICB9CisJCX0KKwkJaWYgKGluZGV4ID49IGxlbmd0aCkgeworCQkgICAgaWYgKCFpZ25vcmVFcnJvcnMpCisJCQl0aHJvdyBuZXcgQWRkcmVzc0V4Y2VwdGlvbigiTWlzc2luZyAnXCInIiwgcywgaW5kZXgpOworCQkgICAgLy8gcHJldGVuZCB0aGUgcXVvdGUgd2FzIGEgcmVndWxhciBjaGFyYWN0ZXIgYW5kCisJCSAgICAvLyBjb250aW51ZSBwYXJzaW5nIGFmdGVyIGl0IChlLmcuLCBgYCJAZm9vLmNvbScnKQorCQkgICAgaW5kZXggPSBxaW5kZXggKyAxOworCQl9CisJCWJyZWFrOworCisJICAgIGNhc2UgJ1snOgkvLyBhIGRvbWFpbi1saXRlcmFsLCBwcm9iYWJseQorCQlpbnQgbGluZGV4ID0gaW5kZXg7CisJCXJmYzgyMiA9IHRydWU7CisJCWlmIChzdGFydCA9PSAtMSkKKwkJICAgIHN0YXJ0ID0gaW5kZXg7CisJICAgICAgb3V0YjoKKwkJZm9yIChpbmRleCsrOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKykgeworCQkgICAgYyA9IHMuY2hhckF0KGluZGV4KTsKKwkJICAgIHN3aXRjaCAoYykgeworCQkgICAgY2FzZSAnXFwnOgorCQkJaW5kZXgrKzsgLy8gc2tpcCBib3RoICdcJyBhbmQgdGhlIGVzY2FwZWQgY2hhcgorCQkJYnJlYWs7CisJCSAgICBjYXNlICddJzoKKwkJCWJyZWFrIG91dGI7IC8vIG91dCBvZiBmb3IgbG9vcAorCQkgICAgZGVmYXVsdDoKKwkJCWJyZWFrOworCQkgICAgfQorCQl9CisJCWlmIChpbmRleCA+PSBsZW5ndGgpIHsKKwkJICAgIGlmICghaWdub3JlRXJyb3JzKQorCQkJdGhyb3cgbmV3IEFkZHJlc3NFeGNlcHRpb24oIk1pc3NpbmcgJ10nIiwgcywgaW5kZXgpOworCQkgICAgLy8gcHJldGVuZCB0aGUgIlsiIHdhcyBhIHJlZ3VsYXIgY2hhcmFjdGVyIGFuZAorCQkgICAgLy8gY29udGludWUgcGFyc2luZyBhZnRlciBpdCAoZS5nLiwgYGBbQGZvby5jb20nJykKKwkJICAgIGluZGV4ID0gbGluZGV4ICsgMTsKKwkJfQorCQlicmVhazsKKworCSAgICBjYXNlICc7JzoKKwkJaWYgKHN0YXJ0ID09IC0xKSB7CisJCSAgICByb3V0ZV9hZGRyID0gZmFsc2U7CisJCSAgICByZmM4MjIgPSBmYWxzZTsKKwkJICAgIHN0YXJ0ID0gZW5kID0gLTE7CisJCSAgICBicmVhazsJLy8gbm9wZSwgbm90aGluZyB0aGVyZQorCQl9CisJCWlmIChpbl9ncm91cCkgeworCQkgICAgaW5fZ3JvdXAgPSBmYWxzZTsKKwkJICAgIC8qCisJCSAgICAgKiBJZiBwYXJzaW5nIGhlYWRlcnMsIGJ1dCBub3Qgc3RyaWN0bHksIHBlZWsgYWhlYWQuCisJCSAgICAgKiBJZiBuZXh0IGNoYXIgaXMgIkAiLCB0cmVhdCB0aGUgZ3JvdXAgbmFtZQorCQkgICAgICogbGlrZSB0aGUgbG9jYWwgcGFydCBvZiB0aGUgYWRkcmVzcywgZS5nLiwKKwkJICAgICAqICJVbmRpc2Nsb3NlZC1SZWNpcGllbnQ6O0BqYXZhLnN1bi5jb20iLgorCQkgICAgICovCisJCSAgICBpZiAocGFyc2VIZHIgJiYgIXN0cmljdCAmJgorCQkJICAgIGluZGV4ICsgMSA8IGxlbmd0aCAmJiBzLmNoYXJBdChpbmRleCArIDEpID09ICdAJykKKwkJCWJyZWFrOworCQkgICAgbWEgPSBuZXcgSW50ZXJuZXRBZGRyZXNzKCk7CisJCSAgICBlbmQgPSBpbmRleCArIDE7CisJCSAgICBtYS5zZXRBZGRyZXNzKHMuc3Vic3RyaW5nKHN0YXJ0LCBlbmQpLnRyaW0oKSk7CisJCSAgICB2LmFkZChtYSk7CisKKwkJICAgIHJvdXRlX2FkZHIgPSBmYWxzZTsKKwkJICAgIHJmYzgyMiA9IGZhbHNlOworCQkgICAgc3RhcnQgPSBlbmQgPSAtMTsKKwkJICAgIHN0YXJ0X3BlcnNvbmFsID0gZW5kX3BlcnNvbmFsID0gLTE7CisJCSAgICBicmVhazsKKwkJfQorCQlpZiAoIWlnbm9yZUVycm9ycykKKwkJICAgIHRocm93IG5ldyBBZGRyZXNzRXhjZXB0aW9uKAorCQkJICAgICJJbGxlZ2FsIHNlbWljb2xvbiwgbm90IGluIGdyb3VwIiwgcywgaW5kZXgpOworCisJCS8vIG90aGVyd2lzZSwgcGFyc2luZyBhIGhlYWRlcjsgdHJlYXQgc2VtaWNvbG9uIGxpa2UgY29tbWEKKwkJLy8gZmFsbCB0aHJvdWdoIHRvIGNvbW1hIGNhc2UuLi4KKworCSAgICBjYXNlICcsJzoJLy8gZW5kIG9mIGFuIGFkZHJlc3MsIHByb2JhYmx5CisJCWlmIChzdGFydCA9PSAtMSkgeworCQkgICAgcm91dGVfYWRkciA9IGZhbHNlOworCQkgICAgcmZjODIyID0gZmFsc2U7CisJCSAgICBzdGFydCA9IGVuZCA9IC0xOworCQkgICAgYnJlYWs7CS8vIG5vcGUsIG5vdGhpbmcgdGhlcmUKKwkJfQorCQlpZiAoaW5fZ3JvdXApIHsKKwkJICAgIHJvdXRlX2FkZHIgPSBmYWxzZTsKKwkJICAgIGJyZWFrOworCQl9CisJCS8vIGdvdCBhIHRva2VuLCBhZGQgdGhpcyB0byBvdXIgSW50ZXJuZXRBZGRyZXNzIGxpc3QKKwkJaWYgKGVuZCA9PSAtMSkKKwkJICAgIGVuZCA9IGluZGV4OworCisJCVN0cmluZyBhZGRyID0gcy5zdWJzdHJpbmcoc3RhcnQsIGVuZCkudHJpbSgpOworCQlTdHJpbmcgcGVycyA9IG51bGw7CisJCWlmIChyZmM4MjIgJiYgc3RhcnRfcGVyc29uYWwgPj0gMCkgeworCQkgICAgcGVycyA9IHVucXVvdGUoCisJCQkgICAgcy5zdWJzdHJpbmcoc3RhcnRfcGVyc29uYWwsIGVuZF9wZXJzb25hbCkudHJpbSgpKTsKKwkJICAgIGlmIChwZXJzLnRyaW0oKS5sZW5ndGgoKSA9PSAwKQorCQkJcGVycyA9IG51bGw7CisJCX0KKworCQkvKgorCQkgKiBJZiB0aGUgcGVyc29uYWwgbmFtZSBmaWVsZCBoYXMgYW4gIkAiIGFuZCB0aGUgYWRkcmVzcworCQkgKiBmaWVsZCBkb2VzIG5vdCwgYXNzdW1lIHRoZXkgd2VyZSByZXZlcnNlZCwgZS5nLiwKKwkJICogYGAiam9lIGRvZSIgKGpvaG4uZG9lQGV4YW1wbGUuY29tKScnLgorCQkgKi8KKwkJaWYgKHBhcnNlSGRyICYmICFzdHJpY3QgJiYgcGVycyAhPSBudWxsICYmCisJCQlwZXJzLmluZGV4T2YoJ0AnKSA+PSAwICYmCisJCQlhZGRyLmluZGV4T2YoJ0AnKSA8IDAgJiYgYWRkci5pbmRleE9mKCchJykgPCAwKSB7CisJCSAgICBTdHJpbmcgdG1wID0gYWRkcjsKKwkJICAgIGFkZHIgPSBwZXJzOworCQkgICAgcGVycyA9IHRtcDsKKwkJfQorCQlpZiAocmZjODIyIHx8IHN0cmljdCB8fCBwYXJzZUhkcikgeworCQkgICAgaWYgKCFpZ25vcmVFcnJvcnMpCisJCQljaGVja0FkZHJlc3MoYWRkciwgcm91dGVfYWRkciwgZmFsc2UpOworCQkgICAgbWEgPSBuZXcgSW50ZXJuZXRBZGRyZXNzKCk7CisJCSAgICBtYS5zZXRBZGRyZXNzKGFkZHIpOworCQkgICAgaWYgKHBlcnMgIT0gbnVsbCkKKwkJCW1hLmVuY29kZWRQZXJzb25hbCA9IHBlcnM7CisJCSAgICB2LmFkZChtYSk7CisJCX0gZWxzZSB7CisJCSAgICAvLyBtYXliZSB3ZSBwYXNzZWQgb3ZlciBtb3JlIHRoYW4gb25lIHNwYWNlLXNlcGFyYXRlZCBhZGRyCisJCSAgICBTdHJpbmdUb2tlbml6ZXIgc3QgPSBuZXcgU3RyaW5nVG9rZW5pemVyKGFkZHIpOworCQkgICAgd2hpbGUgKHN0Lmhhc01vcmVUb2tlbnMoKSkgeworCQkJU3RyaW5nIGEgPSBzdC5uZXh0VG9rZW4oKTsKKwkJCWNoZWNrQWRkcmVzcyhhLCBmYWxzZSwgZmFsc2UpOworCQkJbWEgPSBuZXcgSW50ZXJuZXRBZGRyZXNzKCk7CisJCQltYS5zZXRBZGRyZXNzKGEpOworCQkJdi5hZGQobWEpOworCQkgICAgfQorCQl9CisKKwkJcm91dGVfYWRkciA9IGZhbHNlOworCQlyZmM4MjIgPSBmYWxzZTsKKwkJc3RhcnQgPSBlbmQgPSAtMTsKKwkJc3RhcnRfcGVyc29uYWwgPSBlbmRfcGVyc29uYWwgPSAtMTsKKwkJYnJlYWs7CisKKwkgICAgY2FzZSAnOic6CisJCXJmYzgyMiA9IHRydWU7CisJCWlmIChpbl9ncm91cCkKKwkJICAgIGlmICghaWdub3JlRXJyb3JzKQorCQkJdGhyb3cgbmV3IEFkZHJlc3NFeGNlcHRpb24oIk5lc3RlZCBncm91cCIsIHMsIGluZGV4KTsKKwkJaWYgKHN0YXJ0ID09IC0xKQorCQkgICAgc3RhcnQgPSBpbmRleDsKKwkJaWYgKHBhcnNlSGRyICYmICFzdHJpY3QpIHsKKwkJICAgIC8qCisJCSAgICAgKiBJZiBuZXh0IGNoYXIgaXMgYSBzcGVjaWFsIGNoYXJhY3RlciB0aGF0IGNhbid0IG9jY3VyIGF0CisJCSAgICAgKiB0aGUgc3RhcnQgb2YgYSB2YWxpZCBhZGRyZXNzLCB0cmVhdCB0aGUgZ3JvdXAgbmFtZQorCQkgICAgICogYXMgdGhlIGVudGlyZSBhZGRyZXNzLCBlLmcuLCAiRGF0ZTosIFR1ZSIsICJSZTpAZm9vIi4KKwkJICAgICAqLworCQkgICAgaWYgKGluZGV4ICsgMSA8IGxlbmd0aCkgeworCQkJU3RyaW5nIGFkZHJlc3NTcGVjaWFscyA9ICIpPltdOkBcXCwuIjsKKwkJCWNoYXIgbmMgPSBzLmNoYXJBdChpbmRleCArIDEpOworCQkJaWYgKGFkZHJlc3NTcGVjaWFscy5pbmRleE9mKG5jKSA+PSAwKSB7CisJCQkgICAgaWYgKG5jICE9ICdAJykKKwkJCQlicmVhazsJLy8gZG9uJ3QgY2hhbmdlIGluX2dyb3VwCisJCQkgICAgLyoKKwkJCSAgICAgKiBIYW5kbGUgYSBjb21tb24gZXJyb3I6CisJCQkgICAgICogYGBVbmRpc2Nsb3NlZC1SZWNpcGllbnQ6QGV4YW1wbGUuY29tOycnCisJCQkgICAgICoKKwkJCSAgICAgKiBTY2FuIGFoZWFkLiAgSWYgd2UgZmluZCBhIHNlbWljb2xvbiBiZWZvcmUKKwkJCSAgICAgKiBvbmUgb2YgdGhlc2Ugb3RoZXIgc3BlY2lhbCBjaGFyYWN0ZXJzLAorCQkJICAgICAqIGNvbnNpZGVyIGl0IHRvIGJlIGEgZ3JvdXAgYWZ0ZXIgYWxsLgorCQkJICAgICAqLworCQkJICAgIGZvciAoaW50IGkgPSBpbmRleCArIDI7IGkgPCBsZW5ndGg7IGkrKykgeworCQkJCW5jID0gcy5jaGFyQXQoaSk7CisJCQkJaWYgKG5jID09ICc7JykKKwkJCQkgICAgYnJlYWs7CisJCQkJaWYgKGFkZHJlc3NTcGVjaWFscy5pbmRleE9mKG5jKSA+PSAwKQorCQkJCSAgICBicmVhazsKKwkJCSAgICB9CisJCQkgICAgaWYgKG5jID09ICc7JykKKwkJCQlicmVhazsJLy8gZG9uJ3QgY2hhbmdlIGluX2dyb3VwCisJCQl9CisJCSAgICB9CisKKwkJICAgIC8vIGlnbm9yZSBib2d1cyAibWFpbHRvOiIgcHJlZml4IGluIGZyb250IG9mIGFuIGFkZHJlc3MsCisJCSAgICAvLyBvciBib2d1cyBtYWlsIGhlYWRlciBuYW1lIGluY2x1ZGVkIGluIHRoZSBhZGRyZXNzIGZpZWxkCisJCSAgICBTdHJpbmcgZ25hbWUgPSBzLnN1YnN0cmluZyhzdGFydCwgaW5kZXgpOworCQkgICAgaWYgKGlnbm9yZUJvZ3VzR3JvdXBOYW1lICYmCisJCQkoZ25hbWUuZXF1YWxzSWdub3JlQ2FzZSgibWFpbHRvIikgfHwKKwkJCWduYW1lLmVxdWFsc0lnbm9yZUNhc2UoIkZyb20iKSB8fAorCQkJZ25hbWUuZXF1YWxzSWdub3JlQ2FzZSgiVG8iKSB8fAorCQkJZ25hbWUuZXF1YWxzSWdub3JlQ2FzZSgiQ2MiKSB8fAorCQkJZ25hbWUuZXF1YWxzSWdub3JlQ2FzZSgiU3ViamVjdCIpIHx8CisJCQlnbmFtZS5lcXVhbHNJZ25vcmVDYXNlKCJSZSIpKSkKKwkJCXN0YXJ0ID0gLTE7CS8vIHdlJ3JlIG5vdCByZWFsbHkgaW4gYSBncm91cAorCQkgICAgZWxzZQorCQkJaW5fZ3JvdXAgPSB0cnVlOworCQl9IGVsc2UKKwkJICAgIGluX2dyb3VwID0gdHJ1ZTsKKwkJYnJlYWs7CisKKwkgICAgLy8gSWdub3JlIHdoaXRlc3BhY2UKKwkgICAgY2FzZSAnICc6CisJICAgIGNhc2UgJ1x0JzoKKwkgICAgY2FzZSAnXHInOgorCSAgICBjYXNlICdcbic6CisJCWJyZWFrOworCisJICAgIGRlZmF1bHQ6CisJCWlmIChzdGFydCA9PSAtMSkKKwkJICAgIHN0YXJ0ID0gaW5kZXg7CisJCWJyZWFrOworCSAgICAgfQorCX0KKworCWlmIChzdGFydCA+PSAwKSB7CisJICAgIC8qCisJICAgICAqIFRoZSBsYXN0IHRva2VuLCBhZGQgdGhpcyB0byBvdXIgSW50ZXJuZXRBZGRyZXNzIGxpc3QuCisJICAgICAqIE5vdGUgdGhhdCB0aGlzIGJsb2NrIG9mIGNvZGUgc2hvdWxkIGJlIGlkZW50aWNhbCB0byB0aGUKKwkgICAgICogYmxvY2sgYWJvdmUgZm9yICJjYXNlICcsJyIuCisJICAgICAqLworCSAgICBpZiAoZW5kID09IC0xKQorCQllbmQgPSBsZW5ndGg7CisKKwkgICAgU3RyaW5nIGFkZHIgPSBzLnN1YnN0cmluZyhzdGFydCwgZW5kKS50cmltKCk7CisJICAgIFN0cmluZyBwZXJzID0gbnVsbDsKKwkgICAgaWYgKHJmYzgyMiAmJiBzdGFydF9wZXJzb25hbCA+PSAwKSB7CisJCXBlcnMgPSB1bnF1b3RlKAorCQkJcy5zdWJzdHJpbmcoc3RhcnRfcGVyc29uYWwsIGVuZF9wZXJzb25hbCkudHJpbSgpKTsKKwkJaWYgKHBlcnMudHJpbSgpLmxlbmd0aCgpID09IDApCisJCSAgICBwZXJzID0gbnVsbDsKKwkgICAgfQorCisJICAgIC8qCisJICAgICAqIElmIHRoZSBwZXJzb25hbCBuYW1lIGZpZWxkIGhhcyBhbiAiQCIgYW5kIHRoZSBhZGRyZXNzCisJICAgICAqIGZpZWxkIGRvZXMgbm90LCBhc3N1bWUgdGhleSB3ZXJlIHJldmVyc2VkLCBlLmcuLAorCSAgICAgKiBgYCJqb2UgZG9lIiAoam9obi5kb2VAZXhhbXBsZS5jb20pJycuCisJICAgICAqLworCSAgICBpZiAocGFyc2VIZHIgJiYgIXN0cmljdCAmJgorCQkgICAgcGVycyAhPSBudWxsICYmIHBlcnMuaW5kZXhPZignQCcpID49IDAgJiYKKwkJICAgIGFkZHIuaW5kZXhPZignQCcpIDwgMCAmJiBhZGRyLmluZGV4T2YoJyEnKSA8IDApIHsKKwkJU3RyaW5nIHRtcCA9IGFkZHI7CisJCWFkZHIgPSBwZXJzOworCQlwZXJzID0gdG1wOworCSAgICB9CisJICAgIGlmIChyZmM4MjIgfHwgc3RyaWN0IHx8IHBhcnNlSGRyKSB7CisJCWlmICghaWdub3JlRXJyb3JzKQorCQkgICAgY2hlY2tBZGRyZXNzKGFkZHIsIHJvdXRlX2FkZHIsIGZhbHNlKTsKKwkJbWEgPSBuZXcgSW50ZXJuZXRBZGRyZXNzKCk7CisJCW1hLnNldEFkZHJlc3MoYWRkcik7CisJCWlmIChwZXJzICE9IG51bGwpCisJCSAgICBtYS5lbmNvZGVkUGVyc29uYWwgPSBwZXJzOworCQl2LmFkZChtYSk7CisJICAgIH0gZWxzZSB7CisJCS8vIG1heWJlIHdlIHBhc3NlZCBvdmVyIG1vcmUgdGhhbiBvbmUgc3BhY2Utc2VwYXJhdGVkIGFkZHIKKwkJU3RyaW5nVG9rZW5pemVyIHN0ID0gbmV3IFN0cmluZ1Rva2VuaXplcihhZGRyKTsKKwkJd2hpbGUgKHN0Lmhhc01vcmVUb2tlbnMoKSkgeworCQkgICAgU3RyaW5nIGEgPSBzdC5uZXh0VG9rZW4oKTsKKwkJICAgIGNoZWNrQWRkcmVzcyhhLCBmYWxzZSwgZmFsc2UpOworCQkgICAgbWEgPSBuZXcgSW50ZXJuZXRBZGRyZXNzKCk7CisJCSAgICBtYS5zZXRBZGRyZXNzKGEpOworCQkgICAgdi5hZGQobWEpOworCQl9CisJICAgIH0KKwl9CisKKwlJbnRlcm5ldEFkZHJlc3NbXSBhID0gbmV3IEludGVybmV0QWRkcmVzc1t2LnNpemUoKV07CisJdi50b0FycmF5KGEpOworCXJldHVybiBhOworICAgIH0KKworICAgIC8qKgorICAgICAqIFZhbGlkYXRlIHRoYXQgdGhpcyBhZGRyZXNzIGNvbmZvcm1zIHRvIHRoZSBzeW50YXggcnVsZXMgb2YKKyAgICAgKiBSRkMgODIyLiAgVGhlIGN1cnJlbnQgaW1wbGVtZW50YXRpb24gY2hlY2tzIG1hbnksIGJ1dCBub3QKKyAgICAgKiBhbGwsIHN5bnRheCBydWxlcy4gIE5vdGUgdGhhdCBldmVuIHRob3VnaCB0aGUgc3ludGF4IG9mCisgICAgICogdGhlIGFkZHJlc3MgbWF5IGJlIGNvcnJlY3QsIHRoZXJlJ3Mgbm8gZ3VhcmFudGVlIHRoYXQgYQorICAgICAqIG1haWxib3ggb2YgdGhhdCBuYW1lIGV4aXN0cy4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24JQWRkcmVzc0V4Y2VwdGlvbiBpZiB0aGUgYWRkcmVzcyBpc24ndCB2YWxpZC4KKyAgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuMworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHZhbGlkYXRlKCkgdGhyb3dzIEFkZHJlc3NFeGNlcHRpb24geworCWlmIChpc0dyb3VwKCkpCisJICAgIGdldEdyb3VwKHRydWUpOwkvLyB0aHJvdyBhd2F5IHRoZSByZXN1bHQKKwllbHNlCisJICAgIGNoZWNrQWRkcmVzcyhnZXRBZGRyZXNzKCksIHRydWUsIHRydWUpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBzcGVjaWFsc05vRG90Tm9BdCA9ICIoKTw+LDs6XFxcIltdIjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgc3BlY2lhbHNOb0RvdCA9IHNwZWNpYWxzTm9Eb3ROb0F0ICsgIkAiOworCisgICAgLyoqCisgICAgICogQ2hlY2sgdGhhdCB0aGUgYWRkcmVzcyBpcyBhIHZhbGlkICJtYWlsYm94IiBwZXIgUkZDODIyLgorICAgICAqIChXZSBhbHNvIGFsbG93IHNpbXBsZSBuYW1lcy4pCisgICAgICoKKyAgICAgKiBYWFggLSBtdWNoIG1vcmUgdG8gY2hlY2sKKyAgICAgKiBYWFggLSBkb2Vzbid0IGhhbmRsZSBkb21haW4tbGl0ZXJhbHMgcHJvcGVybHkgKGJ1dCBubyBvbmUgdXNlcyB0aGVtKQorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgY2hlY2tBZGRyZXNzKFN0cmluZyBhZGRyLAorCQkJCWJvb2xlYW4gcm91dGVBZGRyLCBib29sZWFuIHZhbGlkYXRlKQorCQkJCXRocm93cyBBZGRyZXNzRXhjZXB0aW9uIHsKKwlpbnQgaSwgc3RhcnQgPSAwOworCisJaWYgKGFkZHIgPT0gbnVsbCkKKwkgICAgdGhyb3cgbmV3IEFkZHJlc3NFeGNlcHRpb24oIkFkZHJlc3MgaXMgbnVsbCIpOworCWludCBsZW4gPSBhZGRyLmxlbmd0aCgpOworCWlmIChsZW4gPT0gMCkKKwkgICAgdGhyb3cgbmV3IEFkZHJlc3NFeGNlcHRpb24oIkVtcHR5IGFkZHJlc3MiLCBhZGRyKTsKKworCS8qCisJICogcm91dGVBZGRyIGluZGljYXRlcyB0aGF0IHRoZSBhZGRyZXNzIGlzIGFsbG93ZWQKKwkgKiB0byBoYXZlIGFuIFJGQyA4MjIgInJvdXRlIi4KKwkgKi8KKwlpZiAocm91dGVBZGRyICYmIGFkZHIuY2hhckF0KDApID09ICdAJykgeworCSAgICAvKgorCSAgICAgKiBDaGVjayBmb3IgYSBsZWdhbCAicm91dGUtYWRkciI6CisJICAgICAqCQlbQGRvbWFpblssQGRvbWFpbiAuLi5dOl1sb2NhbEBkb21haW4KKwkgICAgICovCisJICAgIGZvciAoc3RhcnQgPSAwOyAoaSA9IGluZGV4T2ZBbnkoYWRkciwgIiw6Iiwgc3RhcnQpKSA+PSAwOworCQkgICAgc3RhcnQgPSBpKzEpIHsKKwkJaWYgKGFkZHIuY2hhckF0KHN0YXJ0KSAhPSAnQCcpCisJCSAgICB0aHJvdyBuZXcgQWRkcmVzc0V4Y2VwdGlvbigiSWxsZWdhbCByb3V0ZS1hZGRyIiwgYWRkcik7CisJCWlmIChhZGRyLmNoYXJBdChpKSA9PSAnOicpIHsKKwkJICAgIC8vIGVuZCBvZiByb3V0ZS1hZGRyCisJCSAgICBzdGFydCA9IGkgKyAxOworCQkgICAgYnJlYWs7CisJCX0KKwkgICAgfQorCX0KKworCS8qCisJICogVGhlIHJlc3Qgc2hvdWxkIGJlICJsb2NhbEBkb21haW4iLCBidXQgd2UgYWxsb3cgc2ltcGx5ICJsb2NhbCIKKwkgKiB1bmxlc3MgY2FsbGVkIGZyb20gdmFsaWRhdGUuCisJICoKKwkgKiBsb2NhbC1wYXJ0IG11c3QgZm9sbG93IFJGQyA4MjIgLSBubyBzcGVjaWFscyBleGNlcHQgJy4nCisJICogdW5sZXNzIHF1b3RlZC4KKwkgKi8KKworCWNoYXIgYyA9IChjaGFyKS0xOworCWNoYXIgbGFzdGMgPSAoY2hhciktMTsKKwlib29sZWFuIGlucXVvdGUgPSBmYWxzZTsKKwlmb3IgKGkgPSBzdGFydDsgaSA8IGxlbjsgaSsrKSB7CisJICAgIGxhc3RjID0gYzsKKwkgICAgYyA9IGFkZHIuY2hhckF0KGkpOworCSAgICAvLyBhIHF1b3RlZC1wYWlyIGlzIG9ubHkgc3VwcG9zZWQgdG8gb2NjdXIgaW5zaWRlIGEgcXVvdGVkIHN0cmluZywKKwkgICAgLy8gYnV0IHNvbWUgcGVvcGxlIHVzZSBpdCBvdXRzaWRlIHNvIHdlJ3JlIG1vcmUgbGVuaWVudAorCSAgICBpZiAoYyA9PSAnXFwnIHx8IGxhc3RjID09ICdcXCcpCisJCWNvbnRpbnVlOworCSAgICBpZiAoYyA9PSAnIicpIHsKKwkJaWYgKGlucXVvdGUpIHsKKwkJICAgIC8vIHBlZWsgYWhlYWQsIG5leHQgY2hhciBtdXN0IGJlICJAIgorCQkgICAgaWYgKHZhbGlkYXRlICYmIGkgKyAxIDwgbGVuICYmIGFkZHIuY2hhckF0KGkgKyAxKSAhPSAnQCcpCisJCQl0aHJvdyBuZXcgQWRkcmVzc0V4Y2VwdGlvbigKKwkJCQkiUXVvdGUgbm90IGF0IGVuZCBvZiBsb2NhbCBhZGRyZXNzIiwgYWRkcik7CisJCSAgICBpbnF1b3RlID0gZmFsc2U7CisJCX0gZWxzZSB7CisJCSAgICBpZiAodmFsaWRhdGUgJiYgaSAhPSAwKQorCQkJdGhyb3cgbmV3IEFkZHJlc3NFeGNlcHRpb24oCisJCQkJIlF1b3RlIG5vdCBhdCBzdGFydCBvZiBsb2NhbCBhZGRyZXNzIiwgYWRkcik7CisJCSAgICBpbnF1b3RlID0gdHJ1ZTsKKwkJfQorCQljb250aW51ZTsKKwkgICAgfSBlbHNlIGlmIChjID09ICdccicpIHsKKwkJLy8gcGVlayBhaGVhZCwgbmV4dCBjaGFyIG11c3QgYmUgTEYKKwkJaWYgKGkgKyAxIDwgbGVuICYmIGFkZHIuY2hhckF0KGkgKyAxKSAhPSAnXG4nKQorCQkgICAgdGhyb3cgbmV3IEFkZHJlc3NFeGNlcHRpb24oCisJCQkiUXVvdGVkIGxvY2FsIGFkZHJlc3MgY29udGFpbnMgQ1Igd2l0aG91dCBMRiIsIGFkZHIpOworCSAgICB9IGVsc2UgaWYgKGMgPT0gJ1xuJykgeworCQkvKgorCQkgKiBDUkxGIGZvbGxvd2VkIGJ5IHdoaXRlc3BhY2UgaXMgYWxsb3dlZCBpbiBhIHF1b3RlZCBzdHJpbmcuCisJCSAqIFdlIGFsbG93ZWQgbmFrZWQgTEYsIGJ1dCBlbnN1cmUgTEYgaXMgYWx3YXlzIGZvbGxvd2VkIGJ5CisJCSAqIHdoaXRlc3BhY2UgdG8gcHJldmVudCBzcG9vZmluZyB0aGUgZW5kIG9mIHRoZSBoZWFkZXIuCisJCSAqLworCQlpZiAoaSArIDEgPCBsZW4gJiYgYWRkci5jaGFyQXQoaSArIDEpICE9ICcgJyAmJgorCQkJCSAgICBhZGRyLmNoYXJBdChpICsgMSkgIT0gJ1x0JykKKwkJICAgIHRocm93IG5ldyBBZGRyZXNzRXhjZXB0aW9uKAorCQkgICAgICJRdW90ZWQgbG9jYWwgYWRkcmVzcyBjb250YWlucyBuZXdsaW5lIHdpdGhvdXQgd2hpdGVzcGFjZSIsCisJCQlhZGRyKTsKKwkgICAgfSBlbHNlIGlmIChjID09ICcuJykgeworCQlpZiAoaSA9PSBzdGFydCkKKwkJICAgIHRocm93IG5ldyBBZGRyZXNzRXhjZXB0aW9uKAorCQkJIkxvY2FsIGFkZHJlc3Mgc3RhcnRzIHdpdGggZG90IiwgYWRkcik7CisJCWlmIChsYXN0YyA9PSAnLicpCisJCSAgICB0aHJvdyBuZXcgQWRkcmVzc0V4Y2VwdGlvbigKKwkJCSJMb2NhbCBhZGRyZXNzIGNvbnRhaW5zIGRvdC1kb3QiLCBhZGRyKTsKKwkgICAgfQorCSAgICBpZiAoaW5xdW90ZSkKKwkJY29udGludWU7CisJICAgIGlmIChjID09ICdAJykgeworCQlpZiAoaSA9PSAwKQorCQkgICAgdGhyb3cgbmV3IEFkZHJlc3NFeGNlcHRpb24oIk1pc3NpbmcgbG9jYWwgbmFtZSIsIGFkZHIpOworCQlpZiAobGFzdGMgPT0gJy4nKQorCQkgICAgdGhyb3cgbmV3IEFkZHJlc3NFeGNlcHRpb24oCisJCQkiTG9jYWwgYWRkcmVzcyBlbmRzIHdpdGggZG90IiwgYWRkcik7CisJCWJyZWFrOwkJLy8gZG9uZSB3aXRoIGxvY2FsIHBhcnQKKwkgICAgfQorCSAgICBpZiAoYyA8PSAwNDAgfHwgYyA9PSAwMTc3KQorCQl0aHJvdyBuZXcgQWRkcmVzc0V4Y2VwdGlvbigKKwkJCSJMb2NhbCBhZGRyZXNzIGNvbnRhaW5zIGNvbnRyb2wgb3Igd2hpdGVzcGFjZSIsIGFkZHIpOworCSAgICBpZiAoc3BlY2lhbHNOb0RvdC5pbmRleE9mKGMpID49IDApCisJCXRocm93IG5ldyBBZGRyZXNzRXhjZXB0aW9uKAorCQkJIkxvY2FsIGFkZHJlc3MgY29udGFpbnMgaWxsZWdhbCBjaGFyYWN0ZXIiLCBhZGRyKTsKKwl9CisJaWYgKGlucXVvdGUpCisJICAgIHRocm93IG5ldyBBZGRyZXNzRXhjZXB0aW9uKCJVbnRlcm1pbmF0ZWQgcXVvdGUiLCBhZGRyKTsKKworCS8qCisJICogRG9uZSB3aXRoIGxvY2FsIHBhcnQsIG5vdyBjaGVjayBkb21haW4uCisJICoKKwkgKiBOb3RlIHRoYXQgdGhlIE1pbWVNZXNzYWdlIGNsYXNzIGRvZXNuJ3QgcmVtZW1iZXIgYWRkcmVzc2VzCisJICogYXMgc2VwYXJhdGUgb2JqZWN0czsgaXQgd3JpdGVzIHRoZW0gb3V0IGFzIGhlYWRlcnMgYW5kIHRoZW4KKwkgKiBwYXJzZXMgdGhlIGhlYWRlcnMgd2hlbiB0aGUgYWRkcmVzc2VzIGFyZSByZXF1ZXN0ZWQuCisJICogSW4gb3JkZXIgdG8gc3VwcG9ydCB0aGUgY2FzZSB3aGVyZSBhICJzaW1wbGUiIGFkZHJlc3MgaXMgdXNlZCwKKwkgKiBidXQgdGhlIGFkZHJlc3MgYWxzbyBoYXMgYSBwZXJzb25hbCBuYW1lIGFuZCB0aHVzIGxvb2tzIGxpa2UKKwkgKiBpdCBzaG91bGQgYmUgYSB2YWxpZCBSRkM4MjIgYWRkcmVzcyB3aGVuIHBhcnNlZCwgd2Ugb25seSBjaGVjaworCSAqIHRoaXMgaWYgd2UncmUgZXhwbGljaXRseSBjYWxsZWQgZnJvbSB0aGUgdmFsaWRhdGUgbWV0aG9kLgorCSAqLworCisJaWYgKGMgIT0gJ0AnKSB7CisJICAgIGlmICh2YWxpZGF0ZSkKKwkJdGhyb3cgbmV3IEFkZHJlc3NFeGNlcHRpb24oIk1pc3NpbmcgZmluYWwgJ0Bkb21haW4nIiwgYWRkcik7CisJICAgIHJldHVybjsKKwl9CisKKwkvLyBjaGVjayBmb3IgaWxsZWdhbCBjaGFycyBpbiB0aGUgZG9tYWluLCBidXQgaWdub3JlIGRvbWFpbiBsaXRlcmFscworCisJc3RhcnQgPSBpICsgMTsKKwlpZiAoc3RhcnQgPj0gbGVuKQorCSAgICB0aHJvdyBuZXcgQWRkcmVzc0V4Y2VwdGlvbigiTWlzc2luZyBkb21haW4iLCBhZGRyKTsKKworCWlmIChhZGRyLmNoYXJBdChzdGFydCkgPT0gJy4nKQorCSAgICB0aHJvdyBuZXcgQWRkcmVzc0V4Y2VwdGlvbigiRG9tYWluIHN0YXJ0cyB3aXRoIGRvdCIsIGFkZHIpOworCWJvb2xlYW4gaW5saXRlcmFsID0gZmFsc2U7CisJZm9yIChpID0gc3RhcnQ7IGkgPCBsZW47IGkrKykgeworCSAgICBjID0gYWRkci5jaGFyQXQoaSk7CisJICAgIGlmIChjID09ICdbJykgeworCQlpZiAoaSAhPSBzdGFydCkKKwkJICAgIHRocm93IG5ldyBBZGRyZXNzRXhjZXB0aW9uKAorCQkJCSJEb21haW4gbGl0ZXJhbCBub3QgYXQgc3RhcnQgb2YgZG9tYWluIiwgYWRkcik7CisJCWlubGl0ZXJhbCA9IHRydWU7CS8vIGRvbWFpbiBsaXRlcmFsLCBkb24ndCB2YWxpZGF0ZQorCSAgICB9IGVsc2UgaWYgKGMgPT0gJ10nKSB7CisJCWlmIChpICE9IGxlbiAtIDEpCisJCSAgICB0aHJvdyBuZXcgQWRkcmVzc0V4Y2VwdGlvbigKKwkJCSAgICAiRG9tYWluIGxpdGVyYWwgZW5kIG5vdCBhdCBlbmQgb2YgZG9tYWluIiwgYWRkcik7CisJCWlubGl0ZXJhbCA9IGZhbHNlOworCSAgICB9IGVsc2UgaWYgKGMgPD0gMDQwIHx8IGMgPT0gMDE3NykgeworCQl0aHJvdyBuZXcgQWRkcmVzc0V4Y2VwdGlvbigKKwkJCQkiRG9tYWluIGNvbnRhaW5zIGNvbnRyb2wgb3Igd2hpdGVzcGFjZSIsIGFkZHIpOworCSAgICB9IGVsc2UgeworCQkvLyBSRkMgMjgyMiBydWxlCisJCS8vaWYgKHNwZWNpYWxzTm9Eb3QuaW5kZXhPZihjKSA+PSAwKQorCQkvKgorCQkgKiBSRkMgMTAzNCBydWxlIGlzIG1vcmUgc3RyaWN0CisJCSAqIHRoZSBmdWxsIHJ1bGUgaXM6CisJCSAqIAorCQkgKiA8ZG9tYWluPiA6Oj0gPHN1YmRvbWFpbj4gfCAiICIKKwkJICogPHN1YmRvbWFpbj4gOjo9IDxsYWJlbD4gfCA8c3ViZG9tYWluPiAiLiIgPGxhYmVsPgorCQkgKiA8bGFiZWw+IDo6PSA8bGV0dGVyPiBbIFsgPGxkaC1zdHI+IF0gPGxldC1kaWc+IF0KKwkJICogPGxkaC1zdHI+IDo6PSA8bGV0LWRpZy1oeXA+IHwgPGxldC1kaWctaHlwPiA8bGRoLXN0cj4KKwkJICogPGxldC1kaWctaHlwPiA6Oj0gPGxldC1kaWc+IHwgIi0iCisJCSAqIDxsZXQtZGlnPiA6Oj0gPGxldHRlcj4gfCA8ZGlnaXQ+CisJCSAqLworCQlpZiAoIWlubGl0ZXJhbCkgeworCQkgICAgaWYgKCEoQ2hhcmFjdGVyLmlzTGV0dGVyT3JEaWdpdChjKSB8fCBjID09ICctJyB8fCBjID09ICcuJykpCisJCQl0aHJvdyBuZXcgQWRkcmVzc0V4Y2VwdGlvbigKKwkJCQkgICAgIkRvbWFpbiBjb250YWlucyBpbGxlZ2FsIGNoYXJhY3RlciIsIGFkZHIpOworCQkgICAgaWYgKGMgPT0gJy4nICYmIGxhc3RjID09ICcuJykKKwkJCXRocm93IG5ldyBBZGRyZXNzRXhjZXB0aW9uKAorCQkJCQkiRG9tYWluIGNvbnRhaW5zIGRvdC1kb3QiLCBhZGRyKTsKKwkJfQorCSAgICB9CisJICAgIGxhc3RjID0gYzsKKwl9CisJaWYgKGxhc3RjID09ICcuJykKKwkgICAgdGhyb3cgbmV3IEFkZHJlc3NFeGNlcHRpb24oIkRvbWFpbiBlbmRzIHdpdGggZG90IiwgYWRkcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogSXMgdGhpcyBhICJzaW1wbGUiIGFkZHJlc3M/ICBTaW1wbGUgYWRkcmVzc2VzIGRvbid0IGNvbnRhaW4gcXVvdGVzCisgICAgICogb3IgYW55IFJGQzgyMiBzcGVjaWFsIGNoYXJhY3RlcnMgb3RoZXIgdGhhbiAnQCcgYW5kICcuJy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gaXNTaW1wbGUoKSB7CisJcmV0dXJuIGFkZHJlc3MgPT0gbnVsbCB8fCBpbmRleE9mQW55KGFkZHJlc3MsIHNwZWNpYWxzTm9Eb3ROb0F0KSA8IDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhpcyBhZGRyZXNzIGlzIGFuIFJGQyA4MjIgZ3JvdXAgYWRkcmVzcy4KKyAgICAgKiBOb3RlIHRoYXQgYSBncm91cCBhZGRyZXNzIGlzIGRpZmZlcmVudCB0aGFuIHRoZSBtYWlsaW5nCisgICAgICogbGlzdCBhZGRyZXNzZXMgc3VwcG9ydGVkIGJ5IG1vc3QgbWFpbCBzZXJ2ZXJzLiAgR3JvdXAgYWRkcmVzc2VzCisgICAgICogYXJlIHJhcmVseSB1c2VkOyBzZWUgUkZDIDgyMiBmb3IgZGV0YWlscy4KKyAgICAgKgorICAgICAqIEByZXR1cm4JCXRydWUgaWYgdGhpcyBhZGRyZXNzIHJlcHJlc2VudHMgYSBncm91cAorICAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS4zCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNHcm91cCgpIHsKKwkvLyBxdWljayBhbmQgZGlydHkgY2hlY2sKKwlyZXR1cm4gYWRkcmVzcyAhPSBudWxsICYmCisJICAgIGFkZHJlc3MuZW5kc1dpdGgoIjsiKSAmJiBhZGRyZXNzLmluZGV4T2YoJzonKSA+IDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBtZW1iZXJzIG9mIGEgZ3JvdXAgYWRkcmVzcy4gIEEgZ3JvdXAgbWF5IGhhdmUgemVybywKKyAgICAgKiBvbmUsIG9yIG1vcmUgbWVtYmVycy4gIElmIHRoaXMgYWRkcmVzcyBpcyBub3QgYSBncm91cCwgbnVsbAorICAgICAqIGlzIHJldHVybmVkLiAgVGhlIDxjb2RlPnN0cmljdDwvY29kZT4gcGFyYW1ldGVyIGNvbnRyb2xzIHdoZXRoZXIKKyAgICAgKiB0aGUgZ3JvdXAgbGlzdCBpcyBwYXJzZWQgdXNpbmcgc3RyaWN0IFJGQyA4MjIgcnVsZXMgb3Igbm90LgorICAgICAqIFRoZSBwYXJzaW5nIGlzIGRvbmUgdXNpbmcgdGhlIDxjb2RlPnBhcnNlSGVhZGVyPC9jb2RlPiBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jc3RyaWN0CXVzZSBzdHJpY3QgUkZDIDgyMiBydWxlcz8KKyAgICAgKiBAcmV0dXJuCQlhcnJheSBvZiBJbnRlcm5ldEFkZHJlc3Mgb2JqZWN0cywgb3IgbnVsbAorICAgICAqIEBleGNlcHRpb24JQWRkcmVzc0V4Y2VwdGlvbiBpZiB0aGUgZ3JvdXAgbGlzdCBjYW4ndCBiZSBwYXJzZWQKKyAgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuMworICAgICAqLworICAgIHB1YmxpYyBJbnRlcm5ldEFkZHJlc3NbXSBnZXRHcm91cChib29sZWFuIHN0cmljdCkgdGhyb3dzIEFkZHJlc3NFeGNlcHRpb24geworCVN0cmluZyBhZGRyID0gZ2V0QWRkcmVzcygpOworCWlmIChhZGRyID09IG51bGwpCisJICAgIHJldHVybiBudWxsOworCS8vIGdyb3VwcyBhcmUgb2YgdGhlIGZvcm0gIm5hbWU6YWRkcixhZGRyLC4uLjsiCisJaWYgKCFhZGRyLmVuZHNXaXRoKCI7IikpCisJICAgIHJldHVybiBudWxsOworCWludCBpeCA9IGFkZHIuaW5kZXhPZignOicpOworCWlmIChpeCA8IDApCisJICAgIHJldHVybiBudWxsOworCS8vIGV4dHJhY3QgdGhlIGxpc3QKKwlTdHJpbmcgbGlzdCA9IGFkZHIuc3Vic3RyaW5nKGl4ICsgMSwgYWRkci5sZW5ndGgoKSAtIDEpOworCS8vIHBhcnNlIGl0IGFuZCByZXR1cm4gdGhlIGluZGl2aWR1YWwgYWRkcmVzc2VzCisJcmV0dXJuIEludGVybmV0QWRkcmVzcy5wYXJzZUhlYWRlcihsaXN0LCBzdHJpY3QpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgZmlyc3QgaW5kZXggb2YgYW55IG9mIHRoZSBjaGFyYWN0ZXJzIGluICJhbnkiIGluICJzIiwKKyAgICAgKiBvciAtMSBpZiBub25lIGFyZSBmb3VuZC4KKyAgICAgKgorICAgICAqIFRoaXMgc2hvdWxkIGJlIGEgbWV0aG9kIG9uIFN0cmluZy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBpbnQgaW5kZXhPZkFueShTdHJpbmcgcywgU3RyaW5nIGFueSkgeworCXJldHVybiBpbmRleE9mQW55KHMsIGFueSwgMCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IGluZGV4T2ZBbnkoU3RyaW5nIHMsIFN0cmluZyBhbnksIGludCBzdGFydCkgeworCXRyeSB7CisJICAgIGludCBsZW4gPSBzLmxlbmd0aCgpOworCSAgICBmb3IgKGludCBpID0gc3RhcnQ7IGkgPCBsZW47IGkrKykgeworCQlpZiAoYW55LmluZGV4T2Yocy5jaGFyQXQoaSkpID49IDApCisJCSAgICByZXR1cm4gaTsKKwkgICAgfQorCSAgICByZXR1cm4gLTE7CisJfSBjYXRjaCAoU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisJICAgIHJldHVybiAtMTsKKwl9CisgICAgfQorCisgICAgLyoKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmcgYXJndltdKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlmb3IgKGludCBpID0gMDsgaSA8IGFyZ3YubGVuZ3RoOyBpKyspIHsKKwkgICAgSW50ZXJuZXRBZGRyZXNzW10gYSA9IEludGVybmV0QWRkcmVzcy5wYXJzZShhcmd2W2ldKTsKKwkgICAgZm9yIChpbnQgaiA9IDA7IGogPCBhLmxlbmd0aDsgaisrKSB7CisJCVN5c3RlbS5vdXQucHJpbnRsbigiYXJnICIgKyBpICsgIiBhZGRyZXNzICIgKyBqICsgIjogIiArIGFbal0pOworCQlTeXN0ZW0ub3V0LnByaW50bG4oIlx0QWRkcmVzczogIiArIGFbal0uZ2V0QWRkcmVzcygpICsKKwkJCQkgICAgIlx0UGVyc29uYWw6ICIgKyBhW2pdLmdldFBlcnNvbmFsKCkpOworCSAgICB9CisJICAgIGlmIChhLmxlbmd0aCA+IDEpIHsKKwkJU3lzdGVtLm91dC5wcmludGxuKCJhZGRyZXNzIDAgaGFzaCBjb2RlOiAiICsgYVswXS5oYXNoQ29kZSgpKTsKKwkJU3lzdGVtLm91dC5wcmludGxuKCJhZGRyZXNzIDEgaGFzaCBjb2RlOiAiICsgYVsxXS5oYXNoQ29kZSgpKTsKKwkJaWYgKGFbMF0uaGFzaENvZGUoKSA9PSBhWzFdLmhhc2hDb2RlKCkpCisJCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oInN1Y2Nlc3MsIGhhc2hjb2RlcyBlcXVhbCIpOworCQllbHNlCisJCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oImZhaWwsIGhhc2hjb2RlcyBub3QgZXF1YWwiKTsKKwkJaWYgKGFbMF0uZXF1YWxzKGFbMV0pKQorCQkgICAgU3lzdGVtLm91dC5wcmludGxuKCJzdWNjZXNzLCBhZGRyZXNzZXMgZXF1YWwiKTsKKwkJZWxzZQorCQkgICAgU3lzdGVtLm91dC5wcmludGxuKCJmYWlsLCBhZGRyZXNzZXMgbm90IGVxdWFsIik7CisJCWlmIChhWzFdLmVxdWFscyhhWzBdKSkKKwkJICAgIFN5c3RlbS5vdXQucHJpbnRsbigic3VjY2VzcywgYWRkcmVzc2VzIGVxdWFsIik7CisJCWVsc2UKKwkJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZmFpbCwgYWRkcmVzc2VzIG5vdCBlcXVhbCIpOworCSAgICB9CisJfQorICAgIH0KKyAgICAqLworfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvSW50ZXJuZXRIZWFkZXJzLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9JbnRlcm5ldEhlYWRlcnMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZGYwY2NhCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvSW50ZXJuZXRIZWFkZXJzLmphdmEKQEAgLTAsMCArMSw2ODMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5pbnRlcm5ldDsKKworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBqYXZheC5tYWlsLio7CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuTGluZUlucHV0U3RyZWFtOworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLlByb3BVdGlsOworCisvKioKKyAqIEludGVybmV0SGVhZGVycyBpcyBhIHV0aWxpdHkgY2xhc3MgdGhhdCBtYW5hZ2VzIFJGQzgyMiBzdHlsZQorICogaGVhZGVycy4gR2l2ZW4gYW4gUkZDODIyIGZvcm1hdCBtZXNzYWdlIHN0cmVhbSwgaXQgcmVhZHMgbGluZXMKKyAqIHVudGlsIHRoZSBibGFuayBsaW5lIHRoYXQgaW5kaWNhdGVzIGVuZCBvZiBoZWFkZXIuIFRoZSBpbnB1dCBzdHJlYW0KKyAqIGlzIHBvc2l0aW9uZWQgYXQgdGhlIHN0YXJ0IG9mIHRoZSBib2R5LiBUaGUgbGluZXMgYXJlIHN0b3JlZCAKKyAqIHdpdGhpbiB0aGUgb2JqZWN0IGFuZCBjYW4gYmUgZXh0cmFjdGVkIGFzIGVpdGhlciBTdHJpbmdzIG9yCisgKiB7QGxpbmsgamF2YXgubWFpbC5IZWFkZXJ9IG9iamVjdHMuIDxwPgorICoKKyAqIFRoaXMgY2xhc3MgaXMgbW9zdGx5IGludGVuZGVkIGZvciBzZXJ2aWNlIHByb3ZpZGVycy4gTWltZU1lc3NhZ2UKKyAqIGFuZCBNaW1lQm9keSB1c2UgdGhpcyBjbGFzcyBmb3IgaG9sZGluZyB0aGVpciBoZWFkZXJzLgorICogCisgKiA8aHI+IDxzdHJvbmc+QSBub3RlIG9uIFJGQzgyMiBhbmQgTUlNRSBoZWFkZXJzPC9zdHJvbmc+PHA+CisgKgorICogUkZDODIyIGFuZCBNSU1FIGhlYWRlciBmaWVsZHMgPHN0cm9uZz5tdXN0PC9zdHJvbmc+IGNvbnRhaW4gb25seSAKKyAqIFVTLUFTQ0lJIGNoYXJhY3RlcnMuIElmIGEgaGVhZGVyIGNvbnRhaW5zIG5vbiBVUy1BU0NJSSBjaGFyYWN0ZXJzLAorICogaXQgbXVzdCBiZSBlbmNvZGVkIGFzIHBlciB0aGUgcnVsZXMgaW4gUkZDIDIwNDcuIFRoZSBNaW1lVXRpbGl0eQorICogY2xhc3MgcHJvdmlkZWQgaW4gdGhpcyBwYWNrYWdlIGNhbiBiZSB1c2VkIHRvIHRvIGFjaGlldmUgdGhpcy4gCisgKiBDYWxsZXJzIG9mIHRoZSA8Y29kZT5zZXRIZWFkZXI8L2NvZGU+LCA8Y29kZT5hZGRIZWFkZXI8L2NvZGU+LCBhbmQKKyAqIDxjb2RlPmFkZEhlYWRlckxpbmU8L2NvZGU+IG1ldGhvZHMgYXJlIHJlc3BvbnNpYmxlIGZvciBlbmZvcmNpbmcKKyAqIHRoZSBNSU1FIHJlcXVpcmVtZW50cyBmb3IgdGhlIHNwZWNpZmllZCBoZWFkZXJzLiAgSW4gYWRkaXRpb24sIHRoZXNlCisgKiBoZWFkZXIgZmllbGRzIG11c3QgYmUgZm9sZGVkICh3cmFwcGVkKSBiZWZvcmUgYmVpbmcgc2VudCBpZiB0aGV5CisgKiBleGNlZWQgdGhlIGxpbmUgbGVuZ3RoIGxpbWl0YXRpb24gZm9yIHRoZSB0cmFuc3BvcnQgKDEwMDAgYnl0ZXMgZm9yCisgKiBTTVRQKS4gIFJlY2VpdmVkIGhlYWRlcnMgbWF5IGhhdmUgYmVlbiBmb2xkZWQuICBUaGUgYXBwbGljYXRpb24gaXMKKyAqIHJlc3BvbnNpYmxlIGZvciBmb2xkaW5nIGFuZCB1bmZvbGRpbmcgaGVhZGVycyBhcyBhcHByb3ByaWF0ZS4gPHA+CisgKgorICogVGhlIGN1cnJlbnQgaW1wbGVtZW50YXRpb24gc3VwcG9ydHMgdGhlIFN5c3RlbSBwcm9wZXJ0eQorICogPGNvZGU+bWFpbC5taW1lLmlnbm9yZXdoaXRlc3BhY2VsaW5lczwvY29kZT4sIHdoaWNoIGlmIHNldCB0byB0cnVlCisgKiB3aWxsIGNhdXNlIGEgbGluZSBjb250YWluaW5nIG9ubHkgd2hpdGVzcGFjZSB0byBiZSBjb25zaWRlcmVkCisgKiBhIGJsYW5rIGxpbmUgdGVybWluYXRpbmcgdGhlIGhlYWRlci4KKyAqCisgKiBAc2VlCWphdmF4Lm1haWwuaW50ZXJuZXQuTWltZVV0aWxpdHkKKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCisKK3B1YmxpYyBjbGFzcyBJbnRlcm5ldEhlYWRlcnMgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gaWdub3JlV2hpdGVzcGFjZUxpbmVzID0KKwlQcm9wVXRpbC5nZXRCb29sZWFuU3lzdGVtUHJvcGVydHkoIm1haWwubWltZS5pZ25vcmV3aGl0ZXNwYWNlbGluZXMiLAorCQkJCQkgICAgZmFsc2UpOworCisgICAgLyoqCisgICAgICogQW4gaW5kaXZpZHVhbCBpbnRlcm5ldCBoZWFkZXIuICBUaGlzIGNsYXNzIGlzIG9ubHkgdXNlZCBieQorICAgICAqIHN1YmNsYXNzZXMgb2YgSW50ZXJuZXRIZWFkZXJzLiA8cD4KKyAgICAgKgorICAgICAqIEFuIEludGVybmV0SGVhZGVyIG9iamVjdCB3aXRoIGEgbnVsbCB2YWx1ZSBpcyB1c2VkIGFzIGEgcGxhY2Vob2xkZXIKKyAgICAgKiBmb3IgaGVhZGVycyBvZiB0aGF0IG5hbWUsIHRvIHByZXNlcnZlIHRoZSBvcmRlciBvZiBoZWFkZXJzLgorICAgICAqIEEgcGxhY2Vob2xkZXIgSW50ZXJuZXRIZWFkZXIgb2JqZWN0IHdpdGggYSBuYW1lIG9mICI6IiBtYXJrcworICAgICAqIHRoZSBsb2NhdGlvbiBpbiB0aGUgbGlzdCBvZiBoZWFkZXJzIHdoZXJlIG5ldyBoZWFkZXJzIGFyZQorICAgICAqIGFkZGVkIGJ5IGRlZmF1bHQuCisgICAgICoKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS40CisgICAgICovCisgICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBjbGFzcyBJbnRlcm5ldEhlYWRlciBleHRlbmRzIEhlYWRlciB7CisJLyoKKwkgKiBOb3RlIHRoYXQgdGhlIHZhbHVlIGZpZWxkIGZyb20gdGhlIHN1cGVyY2xhc3MKKwkgKiBpc24ndCB1c2VkIGluIHRoaXMgY2xhc3MuICBXZSBleHRyYWN0IHRoZSB2YWx1ZQorCSAqIGZyb20gdGhlIGxpbmUgZmllbGQgYXMgbmVlZGVkLiAgV2Ugc3RvcmUgdGhlIGxpbmUKKwkgKiByYXRoZXIgdGhhbiBqdXN0IHRoZSB2YWx1ZSB0byBlbnN1cmUgdGhhdCB3ZSBjYW4KKwkgKiBnZXQgYmFjayB0aGUgZXhhY3Qgb3JpZ2luYWwgbGluZSwgd2l0aCB0aGUgb3JpZ2luYWwKKwkgKiB3aGl0ZXNwYWNlLCBldGMuCisJICovCisJU3RyaW5nIGxpbmU7ICAgIC8vIHRoZSBlbnRpcmUgUkZDODIyIGhlYWRlciAibGluZSIsCisJCQkvLyBvciBudWxsIGlmIHBsYWNlaG9sZGVyCisKKwkvKioKKwkgKiBDb25zdHJ1Y3RvciB0aGF0IHRha2VzIGEgbGluZSBhbmQgc3BsaXRzIG91dAorCSAqIHRoZSBoZWFkZXIgbmFtZS4KKwkgKgorCSAqIEBwYXJhbQlsCXRoZSBoZWFkZXIgbGluZQorCSAqLworCXB1YmxpYyBJbnRlcm5ldEhlYWRlcihTdHJpbmcgbCkgeworCSAgICBzdXBlcigiIiwgIiIpOwkvLyBYWFggLSB3ZSdsbCBjaGFuZ2UgaXQgbGF0ZXIKKwkgICAgaW50IGkgPSBsLmluZGV4T2YoJzonKTsKKwkgICAgaWYgKGkgPCAwKSB7CisJCS8vIHNob3VsZCBuZXZlciBoYXBwZW4KKwkJbmFtZSA9IGwudHJpbSgpOworCSAgICB9IGVsc2UgeworCQluYW1lID0gbC5zdWJzdHJpbmcoMCwgaSkudHJpbSgpOworCSAgICB9CisJICAgIGxpbmUgPSBsOworCX0KKworCS8qKgorCSAqIENvbnN0cnVjdG9yIHRoYXQgdGFrZXMgYSBoZWFkZXIgbmFtZSBhbmQgdmFsdWUuCisJICoKKwkgKiBAcGFyYW0Jbgl0aGUgbmFtZSBvZiB0aGUgaGVhZGVyCisJICogQHBhcmFtCXYJdGhlIHZhbHVlIG9mIHRoZSBoZWFkZXIKKwkgKi8KKwlwdWJsaWMgSW50ZXJuZXRIZWFkZXIoU3RyaW5nIG4sIFN0cmluZyB2KSB7CisJICAgIHN1cGVyKG4sICIiKTsKKwkgICAgaWYgKHYgIT0gbnVsbCkKKwkJbGluZSA9IG4gKyAiOiAiICsgdjsKKwkgICAgZWxzZQorCQlsaW5lID0gbnVsbDsKKwl9CisKKwkvKioKKwkgKiBSZXR1cm4gdGhlICJ2YWx1ZSIgcGFydCBvZiB0aGUgaGVhZGVyIGxpbmUuCisJICovCisJQE92ZXJyaWRlCisJcHVibGljIFN0cmluZyBnZXRWYWx1ZSgpIHsKKwkgICAgaW50IGkgPSBsaW5lLmluZGV4T2YoJzonKTsKKwkgICAgaWYgKGkgPCAwKQorCQlyZXR1cm4gbGluZTsKKwkgICAgLy8gc2tpcCB3aGl0ZXNwYWNlIGFmdGVyICc6JworCSAgICBpbnQgajsKKwkgICAgZm9yIChqID0gaSArIDE7IGogPCBsaW5lLmxlbmd0aCgpOyBqKyspIHsKKwkJY2hhciBjID0gbGluZS5jaGFyQXQoaik7CisJCWlmICghKGMgPT0gJyAnIHx8IGMgPT0gJ1x0JyB8fCBjID09ICdccicgfHwgYyA9PSAnXG4nKSkKKwkJICAgIGJyZWFrOworCSAgICB9CisJICAgIHJldHVybiBsaW5lLnN1YnN0cmluZyhqKTsKKwl9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBUaGUgZW51bWVyYXRpb24gb2JqZWN0IHVzZWQgdG8gZW51bWVyYXRlIGFuCisgICAgICogSW50ZXJuZXRIZWFkZXJzIG9iamVjdC4gIENhbiByZXR1cm4KKyAgICAgKiBlaXRoZXIgYSBTdHJpbmcgb3IgYSBIZWFkZXIgb2JqZWN0LgorICAgICAqLworICAgIHN0YXRpYyBjbGFzcyBNYXRjaEVudW0geworCXByaXZhdGUgSXRlcmF0b3I8SW50ZXJuZXRIZWFkZXI+IGU7CS8vIGVudW0gb2JqZWN0IG9mIGhlYWRlcnMgTGlzdAorCS8vIFhYWCAtIGlzIHRoaXMgb3ZlcmtpbGw/ICBzaG91bGQgd2Ugc3RlcCB0aHJvdWdoIGluIGluZGV4CisJLy8gb3JkZXIgaW5zdGVhZD8KKwlwcml2YXRlIFN0cmluZyBuYW1lc1tdOwkvLyBuYW1lcyB0byBtYXRjaCwgb3Igbm90CisJcHJpdmF0ZSBib29sZWFuIG1hdGNoOwkvLyByZXR1cm4gbWF0Y2hpbmcgaGVhZGVycz8KKwlwcml2YXRlIGJvb2xlYW4gd2FudF9saW5lOwkvLyByZXR1cm4gaGVhZGVyIGxpbmVzPworCXByaXZhdGUgSW50ZXJuZXRIZWFkZXIgbmV4dF9oZWFkZXI7IC8vIHRoZSBuZXh0IGhlYWRlciB0byBiZSByZXR1cm5lZAorCisJLyoKKwkgKiBDb25zdHJ1Y3Rvci4gIEluaXRpYWxpemUgdGhlIGVudW1lcmF0aW9uIGZvciB0aGUgZW50aXJlCisJICogTGlzdCBvZiBoZWFkZXJzLCB0aGUgc2V0IG9mIGhlYWRlcnMsIHdoZXRoZXIgdG8gcmV0dXJuCisJICogbWF0Y2hpbmcgb3Igbm9uLW1hdGNoaW5nIGhlYWRlcnMsIGFuZCB3aGV0aGVyIHRvIHJldHVybgorCSAqIGhlYWRlciBsaW5lcyBvciBIZWFkZXIgb2JqZWN0cy4KKwkgKi8KKwlNYXRjaEVudW0oTGlzdDxJbnRlcm5ldEhlYWRlcj4gdiwgU3RyaW5nIG5bXSwgYm9vbGVhbiBtLCBib29sZWFuIGwpIHsKKwkgICAgZSA9IHYuaXRlcmF0b3IoKTsKKwkgICAgbmFtZXMgPSBuOworCSAgICBtYXRjaCA9IG07CisJICAgIHdhbnRfbGluZSA9IGw7CisJICAgIG5leHRfaGVhZGVyID0gbnVsbDsKKwl9CisKKwkvKgorCSAqIEFueSBtb3JlIGVsZW1lbnRzIGluIHRoaXMgZW51bWVyYXRpb24/CisJICovCisJcHVibGljIGJvb2xlYW4gaGFzTW9yZUVsZW1lbnRzKCkgeworCSAgICAvLyBpZiBuZWNlc3NhcnksIHByZWZldGNoIHRoZSBuZXh0IG1hdGNoaW5nIGhlYWRlciwKKwkgICAgLy8gYW5kIHJlbWVtYmVyIGl0LgorCSAgICBpZiAobmV4dF9oZWFkZXIgPT0gbnVsbCkKKwkJbmV4dF9oZWFkZXIgPSBuZXh0TWF0Y2goKTsKKwkgICAgcmV0dXJuIG5leHRfaGVhZGVyICE9IG51bGw7CisJfQorCisJLyoKKwkgKiBSZXR1cm4gdGhlIG5leHQgZWxlbWVudC4KKwkgKi8KKwlwdWJsaWMgT2JqZWN0IG5leHRFbGVtZW50KCkgeworCSAgICBpZiAobmV4dF9oZWFkZXIgPT0gbnVsbCkKKwkJbmV4dF9oZWFkZXIgPSBuZXh0TWF0Y2goKTsKKworCSAgICBpZiAobmV4dF9oZWFkZXIgPT0gbnVsbCkKKwkJdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oIk5vIG1vcmUgaGVhZGVycyIpOworCisJICAgIEludGVybmV0SGVhZGVyIGggPSBuZXh0X2hlYWRlcjsKKwkgICAgbmV4dF9oZWFkZXIgPSBudWxsOworCSAgICBpZiAod2FudF9saW5lKQorCQlyZXR1cm4gaC5saW5lOworCSAgICBlbHNlCisJCXJldHVybiBuZXcgSGVhZGVyKGguZ2V0TmFtZSgpLCBoLmdldFZhbHVlKCkpOworCX0KKworCS8qCisJICogUmV0dXJuIHRoZSBuZXh0IEhlYWRlciBvYmplY3QgYWNjb3JkaW5nIHRvIHRoZSBtYXRjaAorCSAqIGNyaXRlcmlhLCBvciBudWxsIGlmIG5vbmUgbGVmdC4KKwkgKi8KKwlwcml2YXRlIEludGVybmV0SGVhZGVyIG5leHRNYXRjaCgpIHsKKwkgICAgbmV4dDoKKwkgICAgd2hpbGUgKGUuaGFzTmV4dCgpKSB7CisJCUludGVybmV0SGVhZGVyIGggPSBlLm5leHQoKTsKKworCQkvLyBza2lwICJwbGFjZSBob2xkZXIiIGhlYWRlcnMKKwkJaWYgKGgubGluZSA9PSBudWxsKQorCQkgICAgY29udGludWU7CisKKwkJLy8gaWYgbm8gbmFtZXMgdG8gbWF0Y2ggYWdhaW5zdCwgcmV0dXJuIGFwcHJvcHJpYXRlbHkKKwkJaWYgKG5hbWVzID09IG51bGwpCisJCSAgICByZXR1cm4gbWF0Y2ggPyBudWxsIDogaDsKKworCQkvLyBjaGVjayB3aGV0aGVyIHRoaXMgaGVhZGVyIG1hdGNoZXMgYW55IG9mIHRoZSBuYW1lcworCQlmb3IgKGludCBpID0gMDsgaSA8IG5hbWVzLmxlbmd0aDsgaSsrKSB7CisJCSAgICBpZiAobmFtZXNbaV0uZXF1YWxzSWdub3JlQ2FzZShoLmdldE5hbWUoKSkpIHsKKwkJCWlmIChtYXRjaCkKKwkJCSAgICByZXR1cm4gaDsKKwkJCWVsc2UKKwkJCSAgICAvLyBmb3VuZCBhIG1hdGNoLCBidXQgd2UncmUKKwkJCSAgICAvLyBsb29raW5nIGZvciBub24tbWF0Y2hlcy4KKwkJCSAgICAvLyB0cnkgbmV4dCBoZWFkZXIuCisJCQkgICAgY29udGludWUgbmV4dDsKKwkJICAgIH0KKwkJfQorCQkvLyBmb3VuZCBubyBtYXRjaGVzLiAgaWYgdGhhdCdzIHdoYXQgd2Ugd2FudGVkLCByZXR1cm4gaXQuCisJCWlmICghbWF0Y2gpCisJCSAgICByZXR1cm4gaDsKKwkgICAgfQorCSAgICByZXR1cm4gbnVsbDsKKwl9CisgICAgfQorCisgICAgc3RhdGljIGNsYXNzIE1hdGNoU3RyaW5nRW51bSBleHRlbmRzIE1hdGNoRW51bQorCSAgICBpbXBsZW1lbnRzIEVudW1lcmF0aW9uPFN0cmluZz4geworCisJTWF0Y2hTdHJpbmdFbnVtKExpc3Q8SW50ZXJuZXRIZWFkZXI+IHYsIFN0cmluZ1tdIG4sIGJvb2xlYW4gbSkgeworCSAgICBzdXBlcih2LCBuLCBtLCB0cnVlKTsKKwl9CisKKwlAT3ZlcnJpZGUKKwlwdWJsaWMgU3RyaW5nIG5leHRFbGVtZW50KCkgeworCSAgICByZXR1cm4gKFN0cmluZykgc3VwZXIubmV4dEVsZW1lbnQoKTsKKwl9CisKKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgTWF0Y2hIZWFkZXJFbnVtIGV4dGVuZHMgTWF0Y2hFbnVtCisJICAgIGltcGxlbWVudHMgRW51bWVyYXRpb248SGVhZGVyPiB7CisKKwlNYXRjaEhlYWRlckVudW0oTGlzdDxJbnRlcm5ldEhlYWRlcj4gdiwgU3RyaW5nW10gbiwgYm9vbGVhbiBtKSB7CisJICAgIHN1cGVyKHYsIG4sIG0sIGZhbHNlKTsKKwl9CisKKwlAT3ZlcnJpZGUKKwlwdWJsaWMgSGVhZGVyIG5leHRFbGVtZW50KCkgeworCSAgICByZXR1cm4gKEhlYWRlcikgc3VwZXIubmV4dEVsZW1lbnQoKTsKKwl9CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgYWN0dWFsIGxpc3Qgb2YgSGVhZGVycywgaW5jbHVkaW5nIHBsYWNlaG9sZGVyIGVudHJpZXMuCisgICAgICogUGxhY2Vob2xkZXIgZW50cmllcyBhcmUgSGVhZGVycyB3aXRoIGEgbnVsbCB2YWx1ZSBhbmQKKyAgICAgKiBhcmUgbmV2ZXIgc2VlbiBieSBjbGllbnRzIG9mIHRoZSBJbnRlcm5ldEhlYWRlcnMgY2xhc3MuCisgICAgICogUGxhY2Vob2xkZXIgZW50cmllcyBhcmUgdXNlZCB0byBrZWVwIHRyYWNrIG9mIHRoZSBwcmVmZXJyZWQKKyAgICAgKiBvcmRlciBvZiBoZWFkZXJzLiAgSGVhZGVycyBhcmUgbmV2ZXIgYWN0dWFsbHkgcmVtb3ZlZCBmcm9tCisgICAgICogdGhlIGxpc3QsIHRoZXkncmUgY29udmVydGVkIGludG8gcGxhY2Vob2xkZXIgZW50cmllcy4KKyAgICAgKiBOZXcgaGVhZGVycyBhcmUgYWRkZWQgYWZ0ZXIgZXhpc3RpbmcgaGVhZGVycyBvZiB0aGUgc2FtZSBuYW1lCisgICAgICogKG9yIGJlZm9yZSBpbiB0aGUgY2FzZSBvZiA8Y29kZT5SZWNlaXZlZDwvY29kZT4gYW5kCisgICAgICogPGNvZGU+UmV0dXJuLVBhdGg8L2NvZGU+IGhlYWRlcnMpLiAgSWYgbm8gZXhpc3RpbmcgaGVhZGVyCisgICAgICogb3IgcGxhY2Vob2xkZXIgZm9yIHRoZSBoZWFkZXIgaXMgZm91bmQsIG5ldyBoZWFkZXJzIGFyZQorICAgICAqIGFkZGVkIGFmdGVyIHRoZSBzcGVjaWFsIHBsYWNlaG9sZGVyIHdpdGggdGhlIG5hbWUgIjoiLgorICAgICAqCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNAorICAgICAqLworICAgIHByb3RlY3RlZCBMaXN0PEludGVybmV0SGVhZGVyPiBoZWFkZXJzOworCisgICAgLyoqCisgICAgICogQ3JlYXRlIGFuIGVtcHR5IEludGVybmV0SGVhZGVycyBvYmplY3QuICBQbGFjZWhvbGRlciBlbnRyaWVzCisgICAgICogYXJlIGluc2VydGVkIHRvIGluZGljYXRlIHRoZSBwcmVmZXJyZWQgb3JkZXIgb2YgaGVhZGVycy4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW50ZXJuZXRIZWFkZXJzKCkgeyAKKyAgIAloZWFkZXJzID0gbmV3IEFycmF5TGlzdDw+KDQwKTsgCisJaGVhZGVycy5hZGQobmV3IEludGVybmV0SGVhZGVyKCJSZXR1cm4tUGF0aCIsIG51bGwpKTsKKwloZWFkZXJzLmFkZChuZXcgSW50ZXJuZXRIZWFkZXIoIlJlY2VpdmVkIiwgbnVsbCkpOworCWhlYWRlcnMuYWRkKG5ldyBJbnRlcm5ldEhlYWRlcigiUmVzZW50LURhdGUiLCBudWxsKSk7CisJaGVhZGVycy5hZGQobmV3IEludGVybmV0SGVhZGVyKCJSZXNlbnQtRnJvbSIsIG51bGwpKTsKKwloZWFkZXJzLmFkZChuZXcgSW50ZXJuZXRIZWFkZXIoIlJlc2VudC1TZW5kZXIiLCBudWxsKSk7CisJaGVhZGVycy5hZGQobmV3IEludGVybmV0SGVhZGVyKCJSZXNlbnQtVG8iLCBudWxsKSk7CisJaGVhZGVycy5hZGQobmV3IEludGVybmV0SGVhZGVyKCJSZXNlbnQtQ2MiLCBudWxsKSk7CisJaGVhZGVycy5hZGQobmV3IEludGVybmV0SGVhZGVyKCJSZXNlbnQtQmNjIiwgbnVsbCkpOworCWhlYWRlcnMuYWRkKG5ldyBJbnRlcm5ldEhlYWRlcigiUmVzZW50LU1lc3NhZ2UtSWQiLCBudWxsKSk7CisJaGVhZGVycy5hZGQobmV3IEludGVybmV0SGVhZGVyKCJEYXRlIiwgbnVsbCkpOworCWhlYWRlcnMuYWRkKG5ldyBJbnRlcm5ldEhlYWRlcigiRnJvbSIsIG51bGwpKTsKKwloZWFkZXJzLmFkZChuZXcgSW50ZXJuZXRIZWFkZXIoIlNlbmRlciIsIG51bGwpKTsKKwloZWFkZXJzLmFkZChuZXcgSW50ZXJuZXRIZWFkZXIoIlJlcGx5LVRvIiwgbnVsbCkpOworCWhlYWRlcnMuYWRkKG5ldyBJbnRlcm5ldEhlYWRlcigiVG8iLCBudWxsKSk7CisJaGVhZGVycy5hZGQobmV3IEludGVybmV0SGVhZGVyKCJDYyIsIG51bGwpKTsKKwloZWFkZXJzLmFkZChuZXcgSW50ZXJuZXRIZWFkZXIoIkJjYyIsIG51bGwpKTsKKwloZWFkZXJzLmFkZChuZXcgSW50ZXJuZXRIZWFkZXIoIk1lc3NhZ2UtSWQiLCBudWxsKSk7CisJaGVhZGVycy5hZGQobmV3IEludGVybmV0SGVhZGVyKCJJbi1SZXBseS1UbyIsIG51bGwpKTsKKwloZWFkZXJzLmFkZChuZXcgSW50ZXJuZXRIZWFkZXIoIlJlZmVyZW5jZXMiLCBudWxsKSk7CisJaGVhZGVycy5hZGQobmV3IEludGVybmV0SGVhZGVyKCJTdWJqZWN0IiwgbnVsbCkpOworCWhlYWRlcnMuYWRkKG5ldyBJbnRlcm5ldEhlYWRlcigiQ29tbWVudHMiLCBudWxsKSk7CisJaGVhZGVycy5hZGQobmV3IEludGVybmV0SGVhZGVyKCJLZXl3b3JkcyIsIG51bGwpKTsKKwloZWFkZXJzLmFkZChuZXcgSW50ZXJuZXRIZWFkZXIoIkVycm9ycy1UbyIsIG51bGwpKTsKKwloZWFkZXJzLmFkZChuZXcgSW50ZXJuZXRIZWFkZXIoIk1JTUUtVmVyc2lvbiIsIG51bGwpKTsKKwloZWFkZXJzLmFkZChuZXcgSW50ZXJuZXRIZWFkZXIoIkNvbnRlbnQtVHlwZSIsIG51bGwpKTsKKwloZWFkZXJzLmFkZChuZXcgSW50ZXJuZXRIZWFkZXIoIkNvbnRlbnQtVHJhbnNmZXItRW5jb2RpbmciLCBudWxsKSk7CisJaGVhZGVycy5hZGQobmV3IEludGVybmV0SGVhZGVyKCJDb250ZW50LU1ENSIsIG51bGwpKTsKKwloZWFkZXJzLmFkZChuZXcgSW50ZXJuZXRIZWFkZXIoIjoiLCBudWxsKSk7CisJaGVhZGVycy5hZGQobmV3IEludGVybmV0SGVhZGVyKCJDb250ZW50LUxlbmd0aCIsIG51bGwpKTsKKwloZWFkZXJzLmFkZChuZXcgSW50ZXJuZXRIZWFkZXIoIlN0YXR1cyIsIG51bGwpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkIGFuZCBwYXJzZSB0aGUgZ2l2ZW4gUkZDODIyIG1lc3NhZ2Ugc3RyZWFtIHRpbGwgdGhlIAorICAgICAqIGJsYW5rIGxpbmUgc2VwYXJhdGluZyB0aGUgaGVhZGVyIGZyb20gdGhlIGJvZHkuIFRoZSBpbnB1dCAKKyAgICAgKiBzdHJlYW0gaXMgbGVmdCBwb3NpdGlvbmVkIGF0IHRoZSBzdGFydCBvZiB0aGUgYm9keS4gVGhlIAorICAgICAqIGhlYWRlciBsaW5lcyBhcmUgc3RvcmVkIGludGVybmFsbHkuIDxwPgorICAgICAqCisgICAgICogRm9yIGVmZmljaWVuY3ksIHdyYXAgYSBCdWZmZXJlZElucHV0U3RyZWFtIGFyb3VuZCB0aGUgYWN0dWFsCisgICAgICogaW5wdXQgc3RyZWFtIGFuZCBwYXNzIGl0IGFzIHRoZSBwYXJhbWV0ZXIuIDxwPgorICAgICAqCisgICAgICogTm8gcGxhY2Vob2xkZXIgZW50cmllcyBhcmUgaW5zZXJ0ZWQ7IHRoZSBvcmlnaW5hbCBvcmRlciBvZgorICAgICAqIHRoZSBoZWFkZXJzIGlzIHByZXNlcnZlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbQlpcyAJUkZDODIyIGlucHV0IHN0cmVhbQorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBhbnkgSS9PIGVycm9yIHJlYWRpbmcgdGhlIHN0cmVhbQorICAgICAqLworICAgIHB1YmxpYyBJbnRlcm5ldEhlYWRlcnMoSW5wdXRTdHJlYW0gaXMpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXRoaXMoaXMsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkIGFuZCBwYXJzZSB0aGUgZ2l2ZW4gUkZDODIyIG1lc3NhZ2Ugc3RyZWFtIHRpbGwgdGhlIAorICAgICAqIGJsYW5rIGxpbmUgc2VwYXJhdGluZyB0aGUgaGVhZGVyIGZyb20gdGhlIGJvZHkuIFRoZSBpbnB1dCAKKyAgICAgKiBzdHJlYW0gaXMgbGVmdCBwb3NpdGlvbmVkIGF0IHRoZSBzdGFydCBvZiB0aGUgYm9keS4gVGhlIAorICAgICAqIGhlYWRlciBsaW5lcyBhcmUgc3RvcmVkIGludGVybmFsbHkuIDxwPgorICAgICAqCisgICAgICogRm9yIGVmZmljaWVuY3ksIHdyYXAgYSBCdWZmZXJlZElucHV0U3RyZWFtIGFyb3VuZCB0aGUgYWN0dWFsCisgICAgICogaW5wdXQgc3RyZWFtIGFuZCBwYXNzIGl0IGFzIHRoZSBwYXJhbWV0ZXIuIDxwPgorICAgICAqCisgICAgICogTm8gcGxhY2Vob2xkZXIgZW50cmllcyBhcmUgaW5zZXJ0ZWQ7IHRoZSBvcmlnaW5hbCBvcmRlciBvZgorICAgICAqIHRoZSBoZWFkZXJzIGlzIHByZXNlcnZlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbQlpcyAJUkZDODIyIGlucHV0IHN0cmVhbQorICAgICAqIEBwYXJhbQlhbGxvd3V0ZjggCWlmIFVURi04IGVuY29kZWQgaGVhZGVycyBhcmUgYWxsb3dlZAorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBhbnkgSS9PIGVycm9yIHJlYWRpbmcgdGhlIHN0cmVhbQorICAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS42CisgICAgICovCisgICAgcHVibGljIEludGVybmV0SGVhZGVycyhJbnB1dFN0cmVhbSBpcywgYm9vbGVhbiBhbGxvd3V0ZjgpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisgICAJaGVhZGVycyA9IG5ldyBBcnJheUxpc3Q8Pig0MCk7IAorCWxvYWQoaXMsIGFsbG93dXRmOCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZCBhbmQgcGFyc2UgdGhlIGdpdmVuIFJGQzgyMiBtZXNzYWdlIHN0cmVhbSB0aWxsIHRoZQorICAgICAqIGJsYW5rIGxpbmUgc2VwYXJhdGluZyB0aGUgaGVhZGVyIGZyb20gdGhlIGJvZHkuIFN0b3JlIHRoZQorICAgICAqIGhlYWRlciBsaW5lcyBpbnNpZGUgdGhpcyBJbnRlcm5ldEhlYWRlcnMgb2JqZWN0LiBUaGUgb3JkZXIKKyAgICAgKiBvZiBoZWFkZXIgbGluZXMgaXMgcHJlc2VydmVkLiA8cD4KKyAgICAgKgorICAgICAqIE5vdGUgdGhhdCB0aGUgaGVhZGVyIGxpbmVzIGFyZSBhZGRlZCBpbnRvIHRoaXMgSW50ZXJuZXRIZWFkZXJzCisgICAgICogb2JqZWN0LCBzbyBhbnkgZXhpc3RpbmcgaGVhZGVycyBpbiB0aGlzIG9iamVjdCB3aWxsIG5vdCBiZQorICAgICAqIGFmZmVjdGVkLiAgSGVhZGVycyBhcmUgYWRkZWQgdG8gdGhlIGVuZCBvZiB0aGUgZXhpc3RpbmcgbGlzdAorICAgICAqIG9mIGhlYWRlcnMsIGluIG9yZGVyLgorICAgICAqCisgICAgICogQHBhcmFtCWlzIAlSRkM4MjIgaW5wdXQgc3RyZWFtCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGFueSBJL08gZXJyb3IgcmVhZGluZyB0aGUgc3RyZWFtCisgICAgICovCisgICAgcHVibGljIHZvaWQgbG9hZChJbnB1dFN0cmVhbSBpcykgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJbG9hZChpcywgZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWQgYW5kIHBhcnNlIHRoZSBnaXZlbiBSRkM4MjIgbWVzc2FnZSBzdHJlYW0gdGlsbCB0aGUKKyAgICAgKiBibGFuayBsaW5lIHNlcGFyYXRpbmcgdGhlIGhlYWRlciBmcm9tIHRoZSBib2R5LiBTdG9yZSB0aGUKKyAgICAgKiBoZWFkZXIgbGluZXMgaW5zaWRlIHRoaXMgSW50ZXJuZXRIZWFkZXJzIG9iamVjdC4gVGhlIG9yZGVyCisgICAgICogb2YgaGVhZGVyIGxpbmVzIGlzIHByZXNlcnZlZC4gPHA+CisgICAgICoKKyAgICAgKiBOb3RlIHRoYXQgdGhlIGhlYWRlciBsaW5lcyBhcmUgYWRkZWQgaW50byB0aGlzIEludGVybmV0SGVhZGVycworICAgICAqIG9iamVjdCwgc28gYW55IGV4aXN0aW5nIGhlYWRlcnMgaW4gdGhpcyBvYmplY3Qgd2lsbCBub3QgYmUKKyAgICAgKiBhZmZlY3RlZC4gIEhlYWRlcnMgYXJlIGFkZGVkIHRvIHRoZSBlbmQgb2YgdGhlIGV4aXN0aW5nIGxpc3QKKyAgICAgKiBvZiBoZWFkZXJzLCBpbiBvcmRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbQlpcyAJUkZDODIyIGlucHV0IHN0cmVhbQorICAgICAqIEBwYXJhbQlhbGxvd3V0ZjggCWlmIFVURi04IGVuY29kZWQgaGVhZGVycyBhcmUgYWxsb3dlZAorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBhbnkgSS9PIGVycm9yIHJlYWRpbmcgdGhlIHN0cmVhbQorICAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS42CisgICAgICovCisgICAgcHVibGljIHZvaWQgbG9hZChJbnB1dFN0cmVhbSBpcywgYm9vbGVhbiBhbGxvd3V0ZjgpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJLy8gUmVhZCBoZWFkZXIgbGluZXMgdW50aWwgYSBibGFuayBsaW5lLiBJdCBpcyB2YWxpZAorCS8vIHRvIGhhdmUgQm9keVBhcnRzIHdpdGggbm8gaGVhZGVyIGxpbmVzLgorCVN0cmluZyBsaW5lOworCUxpbmVJbnB1dFN0cmVhbSBsaXMgPSBuZXcgTGluZUlucHV0U3RyZWFtKGlzLCBhbGxvd3V0ZjgpOworCVN0cmluZyBwcmV2bGluZSA9IG51bGw7CS8vIHRoZSBwcmV2aW91cyBoZWFkZXIgbGluZSwgYXMgYSBzdHJpbmcKKwkvLyBhIGJ1ZmZlciB0byBhY2N1bXVsYXRlIHRoZSBoZWFkZXIgaW4sIHdoZW4gd2Uga25vdyBpdCdzIG5lZWRlZAorCVN0cmluZ0J1aWxkZXIgbGluZUJ1ZmZlciA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisKKwl0cnkgeworCSAgICAvLyBpZiB0aGUgZmlyc3QgbGluZSBiZWluZyByZWFkIGlzIGEgY29udGludWF0aW9uIGxpbmUsCisJICAgIC8vIHdlIGlnbm9yZSBpdCBpZiBpdCdzIG90aGVyd2lzZSBlbXB0eSBvciB3ZSB0cmVhdCBpdCBhcworCSAgICAvLyBhIG5vbi1jb250aW51YXRpb24gbGluZSBpZiBpdCBoYXMgbm9uLXdoaXRlc3BhY2UgY29udGVudAorCSAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKKwkgICAgZG8geworCQlsaW5lID0gbGlzLnJlYWRMaW5lKCk7CisJCWlmIChsaW5lICE9IG51bGwgJiYKKwkJCShsaW5lLnN0YXJ0c1dpdGgoIiAiKSB8fCBsaW5lLnN0YXJ0c1dpdGgoIlx0IikpKSB7CisJCSAgICAvLyBjb250aW51YXRpb24gb2YgaGVhZGVyCisJCSAgICBpZiAocHJldmxpbmUgIT0gbnVsbCkgeworCQkJbGluZUJ1ZmZlci5hcHBlbmQocHJldmxpbmUpOworCQkJcHJldmxpbmUgPSBudWxsOworCQkgICAgfQorCQkgICAgaWYgKGZpcnN0KSB7CisJCQlTdHJpbmcgbHQgPSBsaW5lLnRyaW0oKTsKKwkJCWlmIChsdC5sZW5ndGgoKSA+IDApCisJCQkgICAgbGluZUJ1ZmZlci5hcHBlbmQobHQpOworCQkgICAgfSBlbHNlIHsKKwkJCWlmIChsaW5lQnVmZmVyLmxlbmd0aCgpID4gMCkKKwkJCSAgICBsaW5lQnVmZmVyLmFwcGVuZCgiXHJcbiIpOworCQkJbGluZUJ1ZmZlci5hcHBlbmQobGluZSk7CisJCSAgICB9CisJCX0gZWxzZSB7CisJCSAgICAvLyBuZXcgaGVhZGVyCisJCSAgICBpZiAocHJldmxpbmUgIT0gbnVsbCkKKwkJCWFkZEhlYWRlckxpbmUocHJldmxpbmUpOworCQkgICAgZWxzZSBpZiAobGluZUJ1ZmZlci5sZW5ndGgoKSA+IDApIHsKKwkJCS8vIHN0b3JlIHByZXZpb3VzIGhlYWRlciBmaXJzdAorCQkJYWRkSGVhZGVyTGluZShsaW5lQnVmZmVyLnRvU3RyaW5nKCkpOworCQkJbGluZUJ1ZmZlci5zZXRMZW5ndGgoMCk7CisJCSAgICB9CisJCSAgICBwcmV2bGluZSA9IGxpbmU7CisJCX0KKwkJZmlyc3QgPSBmYWxzZTsKKwkgICAgfSB3aGlsZSAobGluZSAhPSBudWxsICYmICFpc0VtcHR5KGxpbmUpKTsKKwl9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2V4KSB7CisJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oIkVycm9yIGluIGlucHV0IHN0cmVhbSIsIGlvZXgpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJcyB0aGlzIGxpbmUgYW4gZW1wdHkgKGJsYW5rKSBsaW5lPworICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gaXNFbXB0eShTdHJpbmcgbGluZSkgeworCXJldHVybiBsaW5lLmxlbmd0aCgpID09IDAgfHwKKwkgICAgKGlnbm9yZVdoaXRlc3BhY2VMaW5lcyAmJiBsaW5lLnRyaW0oKS5sZW5ndGgoKSA9PSAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYWxsIHRoZSB2YWx1ZXMgZm9yIHRoZSBzcGVjaWZpZWQgaGVhZGVyLiBUaGUKKyAgICAgKiB2YWx1ZXMgYXJlIFN0cmluZyBvYmplY3RzLiAgUmV0dXJucyA8Y29kZT5udWxsPC9jb2RlPgorICAgICAqIGlmIG5vIGhlYWRlcnMgd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUgZXhpc3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0JbmFtZSAJaGVhZGVyIG5hbWUKKyAgICAgKiBAcmV0dXJuCQlhcnJheSBvZiBoZWFkZXIgdmFsdWVzLCBvciBudWxsIGlmIG5vbmUKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nW10gZ2V0SGVhZGVyKFN0cmluZyBuYW1lKSB7CisJSXRlcmF0b3I8SW50ZXJuZXRIZWFkZXI+IGUgPSBoZWFkZXJzLml0ZXJhdG9yKCk7CisJLy8gWFhYIC0gc2hvdWxkIHdlIGp1c3Qgc3RlcCB0aHJvdWdoIGluIGluZGV4IG9yZGVyPworCUxpc3Q8U3RyaW5nPiB2ID0gbmV3IEFycmF5TGlzdDw+KCk7IC8vIGFjY3VtdWxhdGUgcmV0dXJuIHZhbHVlcworCisJd2hpbGUgKGUuaGFzTmV4dCgpKSB7CisJICAgIEludGVybmV0SGVhZGVyIGggPSBlLm5leHQoKTsKKwkgICAgaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZShoLmdldE5hbWUoKSkgJiYgaC5saW5lICE9IG51bGwpIHsKKwkJdi5hZGQoaC5nZXRWYWx1ZSgpKTsKKwkgICAgfQorCX0KKwlpZiAodi5zaXplKCkgPT0gMCkKKwkgICAgcmV0dXJuIChudWxsKTsKKwkvLyBjb252ZXJ0IExpc3QgdG8gYW4gYXJyYXkgZm9yIHJldHVybgorCVN0cmluZyByW10gPSBuZXcgU3RyaW5nW3Yuc2l6ZSgpXTsKKwlyID0gdi50b0FycmF5KHIpOworCXJldHVybiAocik7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IGFsbCB0aGUgaGVhZGVycyBmb3IgdGhpcyBoZWFkZXIgbmFtZSwgcmV0dXJuZWQgYXMgYSBzaW5nbGUKKyAgICAgKiBTdHJpbmcsIHdpdGggaGVhZGVycyBzZXBhcmF0ZWQgYnkgdGhlIGRlbGltaXRlci4gSWYgdGhlCisgICAgICogZGVsaW1pdGVyIGlzIDxjb2RlPm51bGw8L2NvZGU+LCBvbmx5IHRoZSBmaXJzdCBoZWFkZXIgaXMgCisgICAgICogcmV0dXJuZWQuICBSZXR1cm5zIDxjb2RlPm51bGw8L2NvZGU+CisgICAgICogaWYgbm8gaGVhZGVycyB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZSBleGlzdC4KKyAgICAgKgorICAgICAqIEBwYXJhbQluYW1lIAkJaGVhZGVyIG5hbWUKKyAgICAgKiBAcGFyYW0gICBkZWxpbWl0ZXIJZGVsaW1pdGVyCisgICAgICogQHJldHVybiAgICAgICAgICAgICAgICAgIHRoZSB2YWx1ZSBmaWVsZHMgZm9yIGFsbCBoZWFkZXJzIHdpdGgKKyAgICAgKgkJCQl0aGlzIG5hbWUsIG9yIG51bGwgaWYgbm9uZQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0SGVhZGVyKFN0cmluZyBuYW1lLCBTdHJpbmcgZGVsaW1pdGVyKSB7CisJU3RyaW5nIHNbXSA9IGdldEhlYWRlcihuYW1lKTsKKworCWlmIChzID09IG51bGwpCisJICAgIHJldHVybiBudWxsOworCQorCWlmICgocy5sZW5ndGggPT0gMSkgfHwgZGVsaW1pdGVyID09IG51bGwpCisJICAgIHJldHVybiBzWzBdOworCQorCVN0cmluZ0J1aWxkZXIgciA9IG5ldyBTdHJpbmdCdWlsZGVyKHNbMF0pOworCWZvciAoaW50IGkgPSAxOyBpIDwgcy5sZW5ndGg7IGkrKykgeworCSAgICByLmFwcGVuZChkZWxpbWl0ZXIpOworCSAgICByLmFwcGVuZChzW2ldKTsKKwl9CisJcmV0dXJuIHIudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGFuZ2UgdGhlIGZpcnN0IGhlYWRlciBsaW5lIHRoYXQgbWF0Y2hlcyBuYW1lCisgICAgICogdG8gaGF2ZSB2YWx1ZSwgYWRkaW5nIGEgbmV3IGhlYWRlciBpZiBubyBleGlzdGluZyBoZWFkZXIKKyAgICAgKiBtYXRjaGVzLiBSZW1vdmUgYWxsIG1hdGNoaW5nIGhlYWRlcnMgYnV0IHRoZSBmaXJzdC4gPHA+CisgICAgICoKKyAgICAgKiBOb3RlIHRoYXQgUkZDODIyIGhlYWRlcnMgY2FuIG9ubHkgY29udGFpbiBVUy1BU0NJSSBjaGFyYWN0ZXJzCisgICAgICoKKyAgICAgKiBAcGFyYW0JbmFtZQloZWFkZXIgbmFtZQorICAgICAqIEBwYXJhbQl2YWx1ZQloZWFkZXIgdmFsdWUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRIZWFkZXIoU3RyaW5nIG5hbWUsIFN0cmluZyB2YWx1ZSkgeworCWJvb2xlYW4gZm91bmQgPSBmYWxzZTsKKworCWZvciAoaW50IGkgPSAwOyBpIDwgaGVhZGVycy5zaXplKCk7IGkrKykgeworCSAgICBJbnRlcm5ldEhlYWRlciBoID0gaGVhZGVycy5nZXQoaSk7CisJICAgIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UoaC5nZXROYW1lKCkpKSB7CisJCWlmICghZm91bmQpIHsKKwkJICAgIGludCBqOworCQkgICAgaWYgKGgubGluZSAhPSBudWxsICYmIChqID0gaC5saW5lLmluZGV4T2YoJzonKSkgPj0gMCkgeworCQkJaC5saW5lID0gaC5saW5lLnN1YnN0cmluZygwLCBqICsgMSkgKyAiICIgKyB2YWx1ZTsKKwkJCS8vIHByZXNlcnZlcyBjYXBpdGFsaXphdGlvbiwgc3BhY2luZworCQkgICAgfSBlbHNlIHsKKwkJCWgubGluZSA9IG5hbWUgKyAiOiAiICsgdmFsdWU7CisJCSAgICB9CisJCSAgICBmb3VuZCA9IHRydWU7CisJCX0gZWxzZSB7CisJCSAgICBoZWFkZXJzLnJlbW92ZShpKTsKKwkJICAgIGktLTsgICAgLy8gaGF2ZSB0byBsb29rIGF0IGkgYWdhaW4KKwkJfQorCSAgICB9CisJfQorICAgIAorCWlmICghZm91bmQpIHsKKwkgICAgYWRkSGVhZGVyKG5hbWUsIHZhbHVlKTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkIGEgaGVhZGVyIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lIGFuZCB2YWx1ZSB0byB0aGUgaGVhZGVyIGxpc3QuIDxwPgorICAgICAqCisgICAgICogVGhlIGN1cnJlbnQgaW1wbGVtZW50YXRpb24ga25vd3MgYWJvdXQgdGhlIHByZWZlcnJlZCBvcmRlciBvZiBtb3N0CisgICAgICogd2VsbC1rbm93biBoZWFkZXJzIGFuZCB3aWxsIGluc2VydCBoZWFkZXJzIGluIHRoYXQgb3JkZXIuICBJbgorICAgICAqIGFkZGl0aW9uLCBpdCBrbm93cyB0aGF0IDxjb2RlPlJlY2VpdmVkPC9jb2RlPiBoZWFkZXJzIHNob3VsZCBiZQorICAgICAqIGluc2VydGVkIGluIHJldmVyc2Ugb3JkZXIgKG5ld2VzdCBiZWZvcmUgb2xkZXN0KSwgYW5kIHRoYXQgdGhleQorICAgICAqIHNob3VsZCBhcHBlYXIgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgaGVhZGVycywgcHJlY2VlZGVkIG9ubHkgYnkKKyAgICAgKiBhIHBvc3NpYmxlIDxjb2RlPlJldHVybi1QYXRoPC9jb2RlPiBoZWFkZXIuICA8cD4KKyAgICAgKgorICAgICAqIE5vdGUgdGhhdCBSRkM4MjIgaGVhZGVycyBjYW4gb25seSBjb250YWluIFVTLUFTQ0lJIGNoYXJhY3RlcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0JbmFtZQloZWFkZXIgbmFtZQorICAgICAqIEBwYXJhbQl2YWx1ZQloZWFkZXIgdmFsdWUKKyAgICAgKi8gCisgICAgcHVibGljIHZvaWQgYWRkSGVhZGVyKFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsdWUpIHsKKwlpbnQgcG9zID0gaGVhZGVycy5zaXplKCk7CisJYm9vbGVhbiBhZGRSZXZlcnNlID0KKwkgICAgbmFtZS5lcXVhbHNJZ25vcmVDYXNlKCJSZWNlaXZlZCIpIHx8CisJICAgIG5hbWUuZXF1YWxzSWdub3JlQ2FzZSgiUmV0dXJuLVBhdGgiKTsKKwlpZiAoYWRkUmV2ZXJzZSkKKwkgICAgcG9zID0gMDsKKwlmb3IgKGludCBpID0gaGVhZGVycy5zaXplKCkgLSAxOyBpID49IDA7IGktLSkgeworCSAgICBJbnRlcm5ldEhlYWRlciBoID0gaGVhZGVycy5nZXQoaSk7CisJICAgIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UoaC5nZXROYW1lKCkpKSB7CisJCWlmIChhZGRSZXZlcnNlKSB7CisJCSAgICBwb3MgPSBpOworCQl9IGVsc2UgeworCQkgICAgaGVhZGVycy5hZGQoaSArIDEsIG5ldyBJbnRlcm5ldEhlYWRlcihuYW1lLCB2YWx1ZSkpOworCQkgICAgcmV0dXJuOworCQl9CisJICAgIH0KKwkgICAgLy8gbWFya2VyIGZvciBkZWZhdWx0IHBsYWNlIHRvIGFkZCBuZXcgaGVhZGVycworCSAgICBpZiAoIWFkZFJldmVyc2UgJiYgaC5nZXROYW1lKCkuZXF1YWxzKCI6IikpCisJCXBvcyA9IGk7CisJfQorCWhlYWRlcnMuYWRkKHBvcywgbmV3IEludGVybmV0SGVhZGVyKG5hbWUsIHZhbHVlKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlIGFsbCBoZWFkZXIgZW50cmllcyB0aGF0IG1hdGNoIHRoZSBnaXZlbiBuYW1lCisgICAgICogQHBhcmFtCW5hbWUgCWhlYWRlciBuYW1lCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVtb3ZlSGVhZGVyKFN0cmluZyBuYW1lKSB7IAorCWZvciAoaW50IGkgPSAwOyBpIDwgaGVhZGVycy5zaXplKCk7IGkrKykgeworCSAgICBJbnRlcm5ldEhlYWRlciBoID0gaGVhZGVycy5nZXQoaSk7CisJICAgIGlmIChuYW1lLmVxdWFsc0lnbm9yZUNhc2UoaC5nZXROYW1lKCkpKSB7CisJCWgubGluZSA9IG51bGw7CisJCS8vaGVhZGVycy5yZW1vdmUoaSk7CisJCS8vaS0tOyAgICAvLyBoYXZlIHRvIGxvb2sgYXQgaSBhZ2FpbgorCSAgICB9CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiBhbGwgdGhlIGhlYWRlcnMgYXMgYW4gRW51bWVyYXRpb24gb2YKKyAgICAgKiB7QGxpbmsgamF2YXgubWFpbC5IZWFkZXJ9IG9iamVjdHMuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCUVudW1lcmF0aW9uIG9mIEhlYWRlciBvYmplY3RzCQorICAgICAqLworICAgIHB1YmxpYyBFbnVtZXJhdGlvbjxIZWFkZXI+IGdldEFsbEhlYWRlcnMoKSB7CisJcmV0dXJuIChuZXcgTWF0Y2hIZWFkZXJFbnVtKGhlYWRlcnMsIG51bGwsIGZhbHNlKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIGFsbCBtYXRjaGluZyB7QGxpbmsgamF2YXgubWFpbC5IZWFkZXJ9IG9iamVjdHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0JbmFtZXMJdGhlIGhlYWRlcnMgdG8gcmV0dXJuCisgICAgICogQHJldHVybglFbnVtZXJhdGlvbiBvZiBtYXRjaGluZyBIZWFkZXIgb2JqZWN0cwkKKyAgICAgKi8KKyAgICBwdWJsaWMgRW51bWVyYXRpb248SGVhZGVyPiBnZXRNYXRjaGluZ0hlYWRlcnMoU3RyaW5nW10gbmFtZXMpIHsKKwlyZXR1cm4gKG5ldyBNYXRjaEhlYWRlckVudW0oaGVhZGVycywgbmFtZXMsIHRydWUpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYWxsIG5vbi1tYXRjaGluZyB7QGxpbmsgamF2YXgubWFpbC5IZWFkZXJ9IG9iamVjdHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0JbmFtZXMJdGhlIGhlYWRlcnMgdG8gbm90IHJldHVybgorICAgICAqIEByZXR1cm4JRW51bWVyYXRpb24gb2Ygbm9uLW1hdGNoaW5nIEhlYWRlciBvYmplY3RzCQorICAgICAqLworICAgIHB1YmxpYyBFbnVtZXJhdGlvbjxIZWFkZXI+IGdldE5vbk1hdGNoaW5nSGVhZGVycyhTdHJpbmdbXSBuYW1lcykgeworCXJldHVybiAobmV3IE1hdGNoSGVhZGVyRW51bShoZWFkZXJzLCBuYW1lcywgZmFsc2UpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGQgYW4gUkZDODIyIGhlYWRlciBsaW5lIHRvIHRoZSBoZWFkZXIgc3RvcmUuCisgICAgICogSWYgdGhlIGxpbmUgc3RhcnRzIHdpdGggYSBzcGFjZSBvciB0YWIgKGEgY29udGludWF0aW9uIGxpbmUpLAorICAgICAqIGFkZCBpdCB0byB0aGUgbGFzdCBoZWFkZXIgbGluZSBpbiB0aGUgbGlzdC4gIE90aGVyd2lzZSwKKyAgICAgKiBhcHBlbmQgdGhlIG5ldyBoZWFkZXIgbGluZSB0byB0aGUgbGlzdC4gIDxwPgorICAgICAqCisgICAgICogTm90ZSB0aGF0IFJGQzgyMiBoZWFkZXJzIGNhbiBvbmx5IGNvbnRhaW4gVVMtQVNDSUkgY2hhcmFjdGVycworICAgICAqCisgICAgICogQHBhcmFtCWxpbmUJcmF3IFJGQzgyMiBoZWFkZXIgbGluZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFkZEhlYWRlckxpbmUoU3RyaW5nIGxpbmUpIHsKKwl0cnkgeworCSAgICBjaGFyIGMgPSBsaW5lLmNoYXJBdCgwKTsKKwkgICAgaWYgKGMgPT0gJyAnIHx8IGMgPT0gJ1x0JykgeworCQlJbnRlcm5ldEhlYWRlciBoID0gaGVhZGVycy5nZXQoaGVhZGVycy5zaXplKCkgLSAxKTsKKwkJaC5saW5lICs9ICJcclxuIiArIGxpbmU7CisJICAgIH0gZWxzZQorCQloZWFkZXJzLmFkZChuZXcgSW50ZXJuZXRIZWFkZXIobGluZSkpOworCX0gY2F0Y2ggKFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworCSAgICAvLyBsaW5lIGlzIGVtcHR5LCBpZ25vcmUgaXQKKwkgICAgcmV0dXJuOworCX0gY2F0Y2ggKE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gZSkgeworCSAgICAvLyBYWFggLSBsaXN0IGlzIGVtcHR5PworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYWxsIHRoZSBoZWFkZXIgbGluZXMgYXMgYW4gRW51bWVyYXRpb24gb2YgU3RyaW5ncy4KKyAgICAgKgorICAgICAqIEByZXR1cm4JRW51bWVyYXRpb24gb2YgU3RyaW5ncyBvZiBhbGwgaGVhZGVyIGxpbmVzCisgICAgICovCisgICAgcHVibGljIEVudW1lcmF0aW9uPFN0cmluZz4gZ2V0QWxsSGVhZGVyTGluZXMoKSB7IAorCXJldHVybiAoZ2V0Tm9uTWF0Y2hpbmdIZWFkZXJMaW5lcyhudWxsKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIGFsbCBtYXRjaGluZyBoZWFkZXIgbGluZXMgYXMgYW4gRW51bWVyYXRpb24gb2YgU3RyaW5ncy4KKyAgICAgKgorICAgICAqIEBwYXJhbQluYW1lcwl0aGUgaGVhZGVycyB0byByZXR1cm4KKyAgICAgKiBAcmV0dXJuCUVudW1lcmF0aW9uIG9mIFN0cmluZ3Mgb2YgYWxsIG1hdGNoaW5nIGhlYWRlciBsaW5lcworICAgICAqLworICAgIHB1YmxpYyBFbnVtZXJhdGlvbjxTdHJpbmc+IGdldE1hdGNoaW5nSGVhZGVyTGluZXMoU3RyaW5nW10gbmFtZXMpIHsKKwlyZXR1cm4gKG5ldyBNYXRjaFN0cmluZ0VudW0oaGVhZGVycywgbmFtZXMsIHRydWUpKTsJCisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIGFsbCBub24tbWF0Y2hpbmcgaGVhZGVyIGxpbmVzCisgICAgICoKKyAgICAgKiBAcGFyYW0JbmFtZXMJdGhlIGhlYWRlcnMgdG8gbm90IHJldHVybgorICAgICAqIEByZXR1cm4JRW51bWVyYXRpb24gb2YgU3RyaW5ncyBvZiBhbGwgbm9uLW1hdGNoaW5nIGhlYWRlciBsaW5lcworICAgICAqLworICAgIHB1YmxpYyBFbnVtZXJhdGlvbjxTdHJpbmc+IGdldE5vbk1hdGNoaW5nSGVhZGVyTGluZXMoU3RyaW5nW10gbmFtZXMpIHsKKwlyZXR1cm4gKG5ldyBNYXRjaFN0cmluZ0VudW0oaGVhZGVycywgbmFtZXMsIGZhbHNlKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvTWFpbERhdGVGb3JtYXQuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2ludGVybmV0L01haWxEYXRlRm9ybWF0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGJkNDdiOQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2ludGVybmV0L01haWxEYXRlRm9ybWF0LmphdmEKQEAgLTAsMCArMSwxMDQyIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGphdmF4Lm1haWwuaW50ZXJuZXQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT2JqZWN0SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PYmplY3RTdHJlYW1FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CitpbXBvcnQgamF2YS51dGlsLkNhbGVuZGFyOworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQgamF2YS51dGlsLlRpbWVab25lOworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkxldmVsOworaW1wb3J0IGphdmEudGV4dC5EYXRlRm9ybWF0U3ltYm9sczsKK2ltcG9ydCBqYXZhLnRleHQuU2ltcGxlRGF0ZUZvcm1hdDsKK2ltcG9ydCBqYXZhLnRleHQuTnVtYmVyRm9ybWF0OworaW1wb3J0IGphdmEudGV4dC5GaWVsZFBvc2l0aW9uOworaW1wb3J0IGphdmEudGV4dC5QYXJzZVBvc2l0aW9uOworaW1wb3J0IGphdmEudGV4dC5QYXJzZUV4Y2VwdGlvbjsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLk1haWxMb2dnZXI7CisKKy8qKgorICogRm9ybWF0cyBhbmQgcGFyc2VzIGRhdGUgc3BlY2lmaWNhdGlvbiBiYXNlZCBvbgorICogPGEgaHJlZj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjgyMi50eHQiIHRhcmdldD0iX3RvcCI+UkZDIDI4MjI8L2E+LiA8cD4KKyAqCisgKiBUaGlzIGNsYXNzIGRvZXMgbm90IHN1cHBvcnQgbWV0aG9kcyB0aGF0IGluZmx1ZW5jZSB0aGUgZm9ybWF0LiBJdCBhbHdheXMKKyAqIGZvcm1hdHMgdGhlIGRhdGUgYmFzZWQgb24gdGhlIHNwZWNpZmljYXRpb24gYmVsb3cuPHA+CisgKgorICogMy4zLiBEYXRlIGFuZCBUaW1lIFNwZWNpZmljYXRpb24KKyAqIDxwPgorICogRGF0ZSBhbmQgdGltZSBvY2N1ciBpbiBzZXZlcmFsIGhlYWRlciBmaWVsZHMuICBUaGlzIHNlY3Rpb24gc3BlY2lmaWVzCisgKiB0aGUgc3ludGF4IGZvciBhIGZ1bGwgZGF0ZSBhbmQgdGltZSBzcGVjaWZpY2F0aW9uLiAgVGhvdWdoIGZvbGRpbmcKKyAqIHdoaXRlIHNwYWNlIGlzIHBlcm1pdHRlZCB0aHJvdWdob3V0IHRoZSBkYXRlLXRpbWUgc3BlY2lmaWNhdGlvbiwgaXQgaXMKKyAqIFJFQ09NTUVOREVEIHRoYXQgYSBzaW5nbGUgc3BhY2UgYmUgdXNlZCBpbiBlYWNoIHBsYWNlIHRoYXQgRldTIGFwcGVhcnMKKyAqICh3aGV0aGVyIGl0IGlzIHJlcXVpcmVkIG9yIG9wdGlvbmFsKTsgc29tZSBvbGRlciBpbXBsZW1lbnRhdGlvbnMgbWF5CisgKiBub3QgaW50ZXJwcmV0IG90aGVyIG9jY3VycmVuY2VzIG9mIGZvbGRpbmcgd2hpdGUgc3BhY2UgY29ycmVjdGx5LgorICogPHByZT4KKyAqIGRhdGUtdGltZSAgICAgICA9ICAgICAgIFsgZGF5LW9mLXdlZWsgIiwiIF0gZGF0ZSBGV1MgdGltZSBbQ0ZXU10KKyAqCisgKiBkYXktb2Ytd2VlayAgICAgPSAgICAgICAoW0ZXU10gZGF5LW5hbWUpIC8gb2JzLWRheS1vZi13ZWVrCisgKgorICogZGF5LW5hbWUgICAgICAgID0gICAgICAgIk1vbiIgLyAiVHVlIiAvICJXZWQiIC8gIlRodSIgLworICogICAgICAgICAgICAgICAgICAgICAgICAgIkZyaSIgLyAiU2F0IiAvICJTdW4iCisgKgorICogZGF0ZSAgICAgICAgICAgID0gICAgICAgZGF5IG1vbnRoIHllYXIKKyAqCisgKiB5ZWFyICAgICAgICAgICAgPSAgICAgICA0KkRJR0lUIC8gb2JzLXllYXIKKyAqCisgKiBtb250aCAgICAgICAgICAgPSAgICAgICAoRldTIG1vbnRoLW5hbWUgRldTKSAvIG9icy1tb250aAorICoKKyAqIG1vbnRoLW5hbWUgICAgICA9ICAgICAgICJKYW4iIC8gIkZlYiIgLyAiTWFyIiAvICJBcHIiIC8KKyAqICAgICAgICAgICAgICAgICAgICAgICAgICJNYXkiIC8gIkp1biIgLyAiSnVsIiAvICJBdWciIC8KKyAqICAgICAgICAgICAgICAgICAgICAgICAgICJTZXAiIC8gIk9jdCIgLyAiTm92IiAvICJEZWMiCisgKgorICogZGF5ICAgICAgICAgICAgID0gICAgICAgKFtGV1NdIDEqMkRJR0lUKSAvIG9icy1kYXkKKyAqCisgKiB0aW1lICAgICAgICAgICAgPSAgICAgICB0aW1lLW9mLWRheSBGV1Mgem9uZQorICoKKyAqIHRpbWUtb2YtZGF5ICAgICA9ICAgICAgIGhvdXIgIjoiIG1pbnV0ZSBbICI6IiBzZWNvbmQgXQorICoKKyAqIGhvdXIgICAgICAgICAgICA9ICAgICAgIDJESUdJVCAvIG9icy1ob3VyCisgKgorICogbWludXRlICAgICAgICAgID0gICAgICAgMkRJR0lUIC8gb2JzLW1pbnV0ZQorICoKKyAqIHNlY29uZCAgICAgICAgICA9ICAgICAgIDJESUdJVCAvIG9icy1zZWNvbmQKKyAqCisgKiB6b25lICAgICAgICAgICAgPSAgICAgICAoKCAiKyIgLyAiLSIgKSA0RElHSVQpIC8gb2JzLXpvbmUKKyAqIDwvcHJlPgorICogVGhlIGRheSBpcyB0aGUgbnVtZXJpYyBkYXkgb2YgdGhlIG1vbnRoLiAgVGhlIHllYXIgaXMgYW55IG51bWVyaWMgeWVhcgorICogMTkwMCBvciBsYXRlci4KKyAqIDxwPgorICogVGhlIHRpbWUtb2YtZGF5IHNwZWNpZmllcyB0aGUgbnVtYmVyIG9mIGhvdXJzLCBtaW51dGVzLCBhbmQgb3B0aW9uYWxseQorICogc2Vjb25kcyBzaW5jZSBtaWRuaWdodCBvZiB0aGUgZGF0ZSBpbmRpY2F0ZWQuCisgKiA8cD4KKyAqIFRoZSBkYXRlIGFuZCB0aW1lLW9mLWRheSBTSE9VTEQgZXhwcmVzcyBsb2NhbCB0aW1lLgorICogPHA+CisgKiBUaGUgem9uZSBzcGVjaWZpZXMgdGhlIG9mZnNldCBmcm9tIENvb3JkaW5hdGVkIFVuaXZlcnNhbCBUaW1lIChVVEMsCisgKiBmb3JtZXJseSByZWZlcnJlZCB0byBhcyAiR3JlZW53aWNoIE1lYW4gVGltZSIpIHRoYXQgdGhlIGRhdGUgYW5kCisgKiB0aW1lLW9mLWRheSByZXByZXNlbnQuICBUaGUgIisiIG9yICItIiBpbmRpY2F0ZXMgd2hldGhlciB0aGUKKyAqIHRpbWUtb2YtZGF5IGlzIGFoZWFkIG9mIChpLmUuLCBlYXN0IG9mKSBvciBiZWhpbmQgKGkuZS4sIHdlc3Qgb2YpCisgKiBVbml2ZXJzYWwgVGltZS4gIFRoZSBmaXJzdCB0d28gZGlnaXRzIGluZGljYXRlIHRoZSBudW1iZXIgb2YgaG91cnMKKyAqIGRpZmZlcmVuY2UgZnJvbSBVbml2ZXJzYWwgVGltZSwgYW5kIHRoZSBsYXN0IHR3byBkaWdpdHMgaW5kaWNhdGUgdGhlCisgKiBudW1iZXIgb2YgbWludXRlcyBkaWZmZXJlbmNlIGZyb20gVW5pdmVyc2FsIFRpbWUuICAoSGVuY2UsICtoaG1tIG1lYW5zCisgKiArKGhoICogNjAgKyBtbSkgbWludXRlcywgYW5kIC1oaG1tIG1lYW5zIC0oaGggKiA2MCArIG1tKSBtaW51dGVzKS4gIFRoZQorICogZm9ybSAiKzAwMDAiIFNIT1VMRCBiZSB1c2VkIHRvIGluZGljYXRlIGEgdGltZSB6b25lIGF0IFVuaXZlcnNhbCBUaW1lLgorICogVGhvdWdoICItMDAwMCIgYWxzbyBpbmRpY2F0ZXMgVW5pdmVyc2FsIFRpbWUsIGl0IGlzIHVzZWQgdG8gaW5kaWNhdGUKKyAqIHRoYXQgdGhlIHRpbWUgd2FzIGdlbmVyYXRlZCBvbiBhIHN5c3RlbSB0aGF0IG1heSBiZSBpbiBhIGxvY2FsIHRpbWUKKyAqIHpvbmUgb3RoZXIgdGhhbiBVbml2ZXJzYWwgVGltZSBhbmQgdGhlcmVmb3JlIGluZGljYXRlcyB0aGF0IHRoZQorICogZGF0ZS10aW1lIGNvbnRhaW5zIG5vIGluZm9ybWF0aW9uIGFib3V0IHRoZSBsb2NhbCB0aW1lIHpvbmUuCisgKiA8cD4KKyAqIEEgZGF0ZS10aW1lIHNwZWNpZmljYXRpb24gTVVTVCBiZSBzZW1hbnRpY2FsbHkgdmFsaWQuICBUaGF0IGlzLCB0aGUKKyAqIGRheS1vZi10aGUtd2VlayAoaWYgaW5jbHVkZWQpIE1VU1QgYmUgdGhlIGRheSBpbXBsaWVkIGJ5IHRoZSBkYXRlLCB0aGUKKyAqIG51bWVyaWMgZGF5LW9mLW1vbnRoIE1VU1QgYmUgYmV0d2VlbiAxIGFuZCB0aGUgbnVtYmVyIG9mIGRheXMgYWxsb3dlZAorICogZm9yIHRoZSBzcGVjaWZpZWQgbW9udGggKGluIHRoZSBzcGVjaWZpZWQgeWVhciksIHRoZSB0aW1lLW9mLWRheSBNVVNUCisgKiBiZSBpbiB0aGUgcmFuZ2UgMDA6MDA6MDAgdGhyb3VnaCAyMzo1OTo2MCAodGhlIG51bWJlciBvZiBzZWNvbmRzCisgKiBhbGxvd2luZyBmb3IgYSBsZWFwIHNlY29uZDsgc2VlIFtTVEQxMl0pLCBhbmQgdGhlIHpvbmUgTVVTVCBiZSB3aXRoaW4KKyAqIHRoZSByYW5nZSAtOTk1OSB0aHJvdWdoICs5OTU5LgorICoKKyAqIDxoMz48YSBuYW1lPSJzeW5jaHJvbml6YXRpb24iPlN5bmNocm9uaXphdGlvbjwvYT48L2gzPgorICogCisgKiA8cD4KKyAqIERhdGUgZm9ybWF0cyBhcmUgbm90IHN5bmNocm9uaXplZC4KKyAqIEl0IGlzIHJlY29tbWVuZGVkIHRvIGNyZWF0ZSBzZXBhcmF0ZSBmb3JtYXQgaW5zdGFuY2VzIGZvciBlYWNoIHRocmVhZC4KKyAqIElmIG11bHRpcGxlIHRocmVhZHMgYWNjZXNzIGEgZm9ybWF0IGNvbmN1cnJlbnRseSwgaXQgbXVzdCBiZSBzeW5jaHJvbml6ZWQKKyAqIGV4dGVybmFsbHkuCisgKgorICogQGF1dGhvcglBbnRob255IFZhbmVsdmVyZGluZ2hlCisgKiBAYXV0aG9yCU1heCBTcGl2YWsKKyAqIEBzaW5jZQlKYXZhTWFpbCAxLjIKKyAqLworcHVibGljIGNsYXNzIE1haWxEYXRlRm9ybWF0IGV4dGVuZHMgU2ltcGxlRGF0ZUZvcm1hdCB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtODE0ODIyNzYwNTIxMDYyODc3OUw7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFBBVFRFUk4gPSAiRUVFLCBkIE1NTSB5eXl5IEhIOm1tOnNzIFogKHopIjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE1haWxMb2dnZXIgTE9HR0VSID0gbmV3IE1haWxMb2dnZXIoCisgICAgICAgICAgICBNYWlsRGF0ZUZvcm1hdC5jbGFzcywgIkRFQlVHIiwgZmFsc2UsIFN5c3RlbS5vdXQpOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFVOS05PV05fREFZX05BTUUgPSAtMTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUaW1lWm9uZSBVVEMgPSBUaW1lWm9uZS5nZXRUaW1lWm9uZSgiVVRDIik7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IExFQVBfU0VDT05EID0gNjA7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBuZXcgZGF0ZSBmb3JtYXQgZm9yIHRoZSBSRkMyODIyIHNwZWNpZmljYXRpb24gd2l0aCBsZW5pZW50CisgICAgICogcGFyc2luZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgTWFpbERhdGVGb3JtYXQoKSB7CisgICAgICAgIHN1cGVyKFBBVFRFUk4sIExvY2FsZS5VUyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWxsb3dzIHRvIHNlcmlhbGl6ZSBpbnN0YW5jZXMgc3VjaCB0aGF0IHRoZXkgYXJlIGRlc2VyaWFsaXphYmxlIHdpdGggdGhlCisgICAgICogcHJldmlvdXMgaW1wbGVtZW50YXRpb24uCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBvYmplY3QgdG8gYmUgc2VyaWFsaXplZAorICAgICAqIEB0aHJvd3MgT2JqZWN0U3RyZWFtRXhjZXB0aW9uCW5ldmVyCisgICAgICovCisgICAgcHJpdmF0ZSBPYmplY3Qgd3JpdGVSZXBsYWNlKCkgdGhyb3dzIE9iamVjdFN0cmVhbUV4Y2VwdGlvbiB7CisgICAgICAgIE1haWxEYXRlRm9ybWF0IGZtdCA9IG5ldyBNYWlsRGF0ZUZvcm1hdCgpOworICAgICAgICBmbXQuc3VwZXJBcHBseVBhdHRlcm4oIkVFRSwgZCBNTU0geXl5eSBISDptbTpzcyAnWFhYWFgnICh6KSIpOworICAgICAgICBmbXQuc2V0VGltZVpvbmUoZ2V0VGltZVpvbmUoKSk7CisgICAgICAgIHJldHVybiBmbXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWxsb3dzIHRvIGRlc2VyaWFsaXplIGluc3RhbmNlcyB0aGF0IHdlcmUgc2VyaWFsaXplZCB3aXRoIHRoZSBwcmV2aW91cworICAgICAqIGltcGxlbWVudGF0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIGluIHRoZSBzdHJlYW0gY29udGFpbmluZyB0aGUgc2VyaWFsaXplZCBvYmplY3QKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCW9uIHJlYWQgZmFpbHVyZXMKKyAgICAgKiBAdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24JbmV2ZXIKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChPYmplY3RJbnB1dFN0cmVhbSBpbikKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgIGluLmRlZmF1bHRSZWFkT2JqZWN0KCk7CisgICAgICAgIHN1cGVyLmFwcGx5UGF0dGVybihQQVRURVJOKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBPdmVycmlkZXMgQ2xvbmVhYmxlLgorICAgICAqCisgICAgICogQHJldHVybiBhIGNsb25lIG9mIHRoaXMgaW5zdGFuY2UKKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS42CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE1haWxEYXRlRm9ybWF0IGNsb25lKCkgeworICAgICAgICByZXR1cm4gKE1haWxEYXRlRm9ybWF0KSBzdXBlci5jbG9uZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZvcm1hdHMgdGhlIGdpdmVuIGRhdGUgaW4gdGhlIGZvcm1hdCBzcGVjaWZpZWQgYnkgCisgICAgICogUkZDIDI4MjIgaW4gdGhlIGN1cnJlbnQgVGltZVpvbmUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gICBkYXRlICAgICAgICAgICAgdGhlIERhdGUgb2JqZWN0CisgICAgICogQHBhcmFtICAgZGF0ZVN0ckJ1ZiAgICAgIHRoZSBmb3JtYXR0ZWQgc3RyaW5nCisgICAgICogQHBhcmFtICAgZmllbGRQb3NpdGlvbiAgIHRoZSBjdXJyZW50IGZpZWxkIHBvc2l0aW9uCisgICAgICogQHJldHVybglTdHJpbmdCdWZmZXIgICAgdGhlIGZvcm1hdHRlZCBTdHJpbmcKKyAgICAgKiBAc2luY2UJCQlKYXZhTWFpbCAxLjIKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nQnVmZmVyIGZvcm1hdChEYXRlIGRhdGUsIFN0cmluZ0J1ZmZlciBkYXRlU3RyQnVmLAorICAgICAgICAgICAgRmllbGRQb3NpdGlvbiBmaWVsZFBvc2l0aW9uKSB7CisgICAgICAgIHJldHVybiBzdXBlci5mb3JtYXQoZGF0ZSwgZGF0ZVN0ckJ1ZiwgZmllbGRQb3NpdGlvbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2VzIHRoZSBnaXZlbiBkYXRlIGluIHRoZSBmb3JtYXQgc3BlY2lmaWVkIGJ5CisgICAgICogUkZDIDI4MjIuCisgICAgICogPHVsPgorICAgICAqIDxsaT5XaXRoIHN0cmljdCBwYXJzaW5nLCBvYnMtKiB0b2tlbnMgYXJlIHVuc3VwcG9ydGVkLiBMZW5pZW50IHBhcnNpbmcKKyAgICAgKiBzdXBwb3J0cyBvYnMteWVhciBhbmQgb2JzLXpvbmUsIHdpdGggdGhlIGV4Y2VwdGlvbiBvZiB0aGUgMS1jaGFyYWN0ZXIKKyAgICAgKiBtaWxpdGFyeSB0aW1lIHpvbmVzLgorICAgICAqIDxsaT5UaGUgb3B0aW9uYWwgQ0ZXUyB0b2tlbiBhdCB0aGUgZW5kIGlzIG5vdCBwYXJzZWQuCisgICAgICogPGxpPlJGQyAyODIyIHNwZWNpZmllcyB0aGF0IGEgem9uZSBvZiAiLTAwMDAiIGluZGljYXRlcyB0aGF0IHRoZQorICAgICAqIGRhdGUtdGltZSBjb250YWlucyBubyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgbG9jYWwgdGltZSB6b25lLiBUaGlzIGNsYXNzCisgICAgICogdXNlcyB0aGUgVVRDIHRpbWUgem9uZSBpbiB0aGlzIGNhc2UuCisgICAgICogPC91bD4KKyAgICAgKgorICAgICAqIEBwYXJhbSAgIHRleHQgICAgdGhlIGZvcm1hdHRlZCBkYXRlIHRvIGJlIHBhcnNlZAorICAgICAqIEBwYXJhbSAgIHBvcyAgICAgdGhlIGN1cnJlbnQgcGFyc2UgcG9zaXRpb24KKyAgICAgKiBAcmV0dXJuCURhdGUgICAgdGhlIHBhcnNlZCBkYXRlLiBJbiBjYXNlIG9mIGVycm9yLCByZXR1cm5zIG51bGwuCisgICAgICogQHNpbmNlCQlKYXZhTWFpbCAxLjIKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRGF0ZSBwYXJzZShTdHJpbmcgdGV4dCwgUGFyc2VQb3NpdGlvbiBwb3MpIHsKKyAgICAgICAgaWYgKHRleHQgPT0gbnVsbCB8fCBwb3MgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0gZWxzZSBpZiAoMCA+IHBvcy5nZXRJbmRleCgpIHx8IHBvcy5nZXRJbmRleCgpID49IHRleHQubGVuZ3RoKCkpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGlzTGVuaWVudCgpCisgICAgICAgICAgICAgICAgPyBuZXcgUmZjMjgyMkxlbmllbnRQYXJzZXIodGV4dCwgcG9zKS5wYXJzZSgpCisgICAgICAgICAgICAgICAgOiBuZXcgUmZjMjgyMlN0cmljdFBhcnNlcih0ZXh0LCBwb3MpLnBhcnNlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgYWx3YXlzIHRocm93cyBhbiBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBhbmQgc2hvdWxkIG5vdAorICAgICAqIGJlIHVzZWQgYmVjYXVzZSBSRkMgMjgyMiBtYW5kYXRlcyBhIHNwZWNpZmljIGNhbGVuZGFyLgorICAgICAqCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBpZiB0aGlzIG1ldGhvZCBpcyBpbnZva2VkCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0Q2FsZW5kYXIoQ2FsZW5kYXIgbmV3Q2FsZW5kYXIpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJNZXRob2QgIgorICAgICAgICAgICAgICAgICsgInNldENhbGVuZGFyKCkgc2hvdWxkbid0IGJlIGNhbGxlZCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIGFsd2F5cyB0aHJvd3MgYW4gVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gYW5kIHNob3VsZCBub3QKKyAgICAgKiBiZSB1c2VkIGJlY2F1c2UgUkZDIDI4MjIgbWFuZGF0ZXMgYSBzcGVjaWZpYyBudW1iZXIgZm9ybWF0LgorICAgICAqCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBpZiB0aGlzIG1ldGhvZCBpcyBpbnZva2VkCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0TnVtYmVyRm9ybWF0KE51bWJlckZvcm1hdCBuZXdOdW1iZXJGb3JtYXQpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJNZXRob2QgIgorICAgICAgICAgICAgICAgICsgInNldE51bWJlckZvcm1hdCgpIHNob3VsZG4ndCBiZSBjYWxsZWQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBhbHdheXMgdGhyb3dzIGFuIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGFuZCBzaG91bGQgbm90CisgICAgICogYmUgdXNlZCBiZWNhdXNlIFJGQyAyODIyIG1hbmRhdGVzIGEgc3BlY2lmaWMgcGF0dGVybi4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gaWYgdGhpcyBtZXRob2QgaXMgaW52b2tlZAorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjYKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBhcHBseUxvY2FsaXplZFBhdHRlcm4oU3RyaW5nIHBhdHRlcm4pIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJNZXRob2QgIgorICAgICAgICAgICAgICAgICsgImFwcGx5TG9jYWxpemVkUGF0dGVybigpIHNob3VsZG4ndCBiZSBjYWxsZWQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBhbHdheXMgdGhyb3dzIGFuIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGFuZCBzaG91bGQgbm90CisgICAgICogYmUgdXNlZCBiZWNhdXNlIFJGQyAyODIyIG1hbmRhdGVzIGEgc3BlY2lmaWMgcGF0dGVybi4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gaWYgdGhpcyBtZXRob2QgaXMgaW52b2tlZAorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjYKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBhcHBseVBhdHRlcm4oU3RyaW5nIHBhdHRlcm4pIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJNZXRob2QgIgorICAgICAgICAgICAgICAgICsgImFwcGx5UGF0dGVybigpIHNob3VsZG4ndCBiZSBjYWxsZWQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBhbGxvd3Mgc2VyaWFsaXphdGlvbiB0byBjaGFuZ2UgdGhlIHBhdHRlcm4uCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIHN1cGVyQXBwbHlQYXR0ZXJuKFN0cmluZyBwYXR0ZXJuKSB7CisgICAgICAgIHN1cGVyLmFwcGx5UGF0dGVybihwYXR0ZXJuKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBhbHdheXMgdGhyb3dzIGFuIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGFuZCBzaG91bGQgbm90CisgICAgICogYmUgdXNlZCBiZWNhdXNlIFJGQyAyODIyIG1hbmRhdGVzIGFub3RoZXIgc3RyYXRlZ3kgZm9yIGludGVycHJldGluZworICAgICAqIDItZGlnaXRzIHllYXJzLgorICAgICAqCisgICAgICogQHJldHVybiB0aGUgc3RhcnQgb2YgdGhlIDEwMC15ZWFyIHBlcmlvZCBpbnRvIHdoaWNoIHR3byBkaWdpdCB5ZWFycyBhcmUKKyAgICAgKiBwYXJzZWQKKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGlmIHRoaXMgbWV0aG9kIGlzIGludm9rZWQKKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS42CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIERhdGUgZ2V0MkRpZ2l0WWVhclN0YXJ0KCkgeworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk1ldGhvZCAiCisgICAgICAgICAgICAgICAgKyAiZ2V0MkRpZ2l0WWVhclN0YXJ0KCkgc2hvdWxkbid0IGJlIGNhbGxlZCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIGFsd2F5cyB0aHJvd3MgYW4gVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gYW5kIHNob3VsZCBub3QKKyAgICAgKiBiZSB1c2VkIGJlY2F1c2UgUkZDIDI4MjIgbWFuZGF0ZXMgYW5vdGhlciBzdHJhdGVneSBmb3IgaW50ZXJwcmV0aW5nCisgICAgICogMi1kaWdpdHMgeWVhcnMuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGlmIHRoaXMgbWV0aG9kIGlzIGludm9rZWQKKyAgICAgKiBAc2luY2UgSmF2YU1haWwgMS42CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0MkRpZ2l0WWVhclN0YXJ0KERhdGUgc3RhcnREYXRlKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTWV0aG9kICIKKyAgICAgICAgICAgICAgICArICJzZXQyRGlnaXRZZWFyU3RhcnQoKSBzaG91bGRuJ3QgYmUgY2FsbGVkIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgYWx3YXlzIHRocm93cyBhbiBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBhbmQgc2hvdWxkIG5vdAorICAgICAqIGJlIHVzZWQgYmVjYXVzZSBSRkMgMjgyMiBtYW5kYXRlcyBzcGVjaWZpYyBkYXRlIGZvcm1hdCBzeW1ib2xzLgorICAgICAqCisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBpZiB0aGlzIG1ldGhvZCBpcyBpbnZva2VkCisgICAgICogQHNpbmNlIEphdmFNYWlsIDEuNgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldERhdGVGb3JtYXRTeW1ib2xzKERhdGVGb3JtYXRTeW1ib2xzIG5ld0Zvcm1hdFN5bWJvbHMpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJNZXRob2QgIgorICAgICAgICAgICAgICAgICsgInNldERhdGVGb3JtYXRTeW1ib2xzKCkgc2hvdWxkbid0IGJlIGNhbGxlZCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGRhdGUsIGFzIHNwZWNpZmllZCBieSB0aGUgcGFyYW1ldGVycy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBkYXlOYW1lCisgICAgICogQHBhcmFtIGRheQorICAgICAqIEBwYXJhbSBtb250aAorICAgICAqIEBwYXJhbSB5ZWFyCisgICAgICogQHBhcmFtIGhvdXIKKyAgICAgKiBAcGFyYW0gbWludXRlCisgICAgICogQHBhcmFtIHNlY29uZAorICAgICAqIEBwYXJhbSB6b25lCisgICAgICogQHJldHVybiB0aGUgZGF0ZSwgYXMgc3BlY2lmaWVkIGJ5IHRoZSBwYXJhbWV0ZXJzCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhpcyBpbnN0YW5jZSdzIENhbGVuZGFyIGlzCisgICAgICogbm9uLWxlbmllbnQgYW5kIGFueSBvZiB0aGUgcGFyYW1ldGVycyBoYXZlIGludmFsaWQgdmFsdWVzLCBvciBpZiBkYXlOYW1lCisgICAgICogaXMgbm90IGNvbnNpc3RlbnQgd2l0aCBkYXktbW9udGgteWVhcgorICAgICAqLworICAgIHByaXZhdGUgRGF0ZSB0b0RhdGUoaW50IGRheU5hbWUsIGludCBkYXksIGludCBtb250aCwgaW50IHllYXIsCisgICAgICAgICAgICBpbnQgaG91ciwgaW50IG1pbnV0ZSwgaW50IHNlY29uZCwgaW50IHpvbmUpIHsKKyAgICAgICAgaWYgKHNlY29uZCA9PSBMRUFQX1NFQ09ORCkgeworICAgICAgICAgICAgc2Vjb25kID0gNTk7CisgICAgICAgIH0KKworICAgICAgICBUaW1lWm9uZSB0eiA9IGNhbGVuZGFyLmdldFRpbWVab25lKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBjYWxlbmRhci5zZXRUaW1lWm9uZShVVEMpOworICAgICAgICAgICAgY2FsZW5kYXIuY2xlYXIoKTsKKyAgICAgICAgICAgIGNhbGVuZGFyLnNldCh5ZWFyLCBtb250aCwgZGF5LCBob3VyLCBtaW51dGUsIHNlY29uZCk7CisKKyAgICAgICAgICAgIGlmIChkYXlOYW1lID09IFVOS05PV05fREFZX05BTUUKKyAgICAgICAgICAgICAgICAgICAgfHwgZGF5TmFtZSA9PSBjYWxlbmRhci5nZXQoQ2FsZW5kYXIuREFZX09GX1dFRUspKSB7CisgICAgICAgICAgICAgICAgY2FsZW5kYXIuYWRkKENhbGVuZGFyLk1JTlVURSwgem9uZSk7CisgICAgICAgICAgICAgICAgcmV0dXJuIGNhbGVuZGFyLmdldFRpbWUoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW5jb25zaXN0ZW50IGRheS1uYW1lIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBjYWxlbmRhci5zZXRUaW1lWm9uZSh0eik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIGNsYXNzIHByb3ZpZGVzIHRoZSBidWlsZGluZyBibG9ja3MgZm9yIGRhdGUgcGFyc2luZy4KKyAgICAgKiA8cD4KKyAgICAgKiBJdCBoYXMgdGhlIGZvbGxvd2luZyBpbnZhcmlhbnRzOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+bm8gZXhjZXB0aW9ucyBhcmUgdGhyb3duLCBleGNlcHQgZm9yIGphdmEudGV4dC5QYXJzZUV4Y2VwdGlvbiBmcm9tCisgICAgICogcGFyc2UqIG1ldGhvZHMKKyAgICAgKiA8bGk+d2hlbiBwYXJzZSogdGhyb3dzIFBhcnNlRXhjZXB0aW9uIE9SIGdldCogcmV0dXJucyBJTlZBTElEX0NIQVIgT1IKKyAgICAgKiBza2lwKiByZXR1cm5zIGZhbHNlIE9SIHBlZWsqIGlzIGludm9rZWQsIHRoZW4gcG9zLmdldEluZGV4KCkgb24gbWV0aG9kCisgICAgICogZXhpdCBpcyB0aGUgc2FtZSBhcyBpdCB3YXMgb24gbWV0aG9kIGVudHJ5CisgICAgICogPC91bD4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBhYnN0cmFjdCBjbGFzcyBBYnN0cmFjdERhdGVQYXJzZXIgeworCisgICAgICAgIHN0YXRpYyBmaW5hbCBpbnQgSU5WQUxJRF9DSEFSID0gLTE7CisgICAgICAgIHN0YXRpYyBmaW5hbCBpbnQgTUFYX1lFQVJfRElHSVRTID0gODsgLy8gZ3VhcmFudGVlcyB0aGF0OgorICAgICAgICAvLyB5ZWFyIDwgbmV3IEdyZWdvcmlhbkNhbGVuZGFyKCkuZ2V0TWF4aW11bShDYWxlbmRhci5ZRUFSKQorCisgICAgICAgIGZpbmFsIFN0cmluZyB0ZXh0OworICAgICAgICBmaW5hbCBQYXJzZVBvc2l0aW9uIHBvczsKKworICAgICAgICBBYnN0cmFjdERhdGVQYXJzZXIoU3RyaW5nIHRleHQsIFBhcnNlUG9zaXRpb24gcG9zKSB7CisgICAgICAgICAgICB0aGlzLnRleHQgPSB0ZXh0OworICAgICAgICAgICAgdGhpcy5wb3MgPSBwb3M7CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBEYXRlIHBhcnNlKCkgeworICAgICAgICAgICAgaW50IHN0YXJ0UG9zaXRpb24gPSBwb3MuZ2V0SW5kZXgoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRyeVBhcnNlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeyAvLyA9PSBQYXJzZUV4Y2VwdGlvbiB8IFJ1bnRpbWVFeGNlcHRpb24gZQorICAgICAgICAgICAgICAgIGlmIChMT0dHRVIuaXNMb2dnYWJsZShMZXZlbC5GSU5FKSkgeworICAgICAgICAgICAgICAgICAgICBMT0dHRVIubG9nKExldmVsLkZJTkUsICJCYWQgZGF0ZTogJyIgKyB0ZXh0ICsgIiciLCBlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcG9zLnNldEVycm9ySW5kZXgocG9zLmdldEluZGV4KCkpOworICAgICAgICAgICAgICAgIHBvcy5zZXRJbmRleChzdGFydFBvc2l0aW9uKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGFic3RyYWN0IERhdGUgdHJ5UGFyc2UoKSB0aHJvd3MgUGFyc2VFeGNlcHRpb247CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIEByZXR1cm4gdGhlIGphdmEudXRpbC5DYWxlbmRhciBjb25zdGFudCBmb3IgdGhlIHBhcnNlZCBkYXkgbmFtZQorICAgICAgICAgKi8KKyAgICAgICAgZmluYWwgaW50IHBhcnNlRGF5TmFtZSgpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CisgICAgICAgICAgICBzd2l0Y2ggKGdldENoYXIoKSkgeworICAgICAgICAgICAgICAgIGNhc2UgJ1MnOgorICAgICAgICAgICAgICAgICAgICBpZiAoc2tpcFBhaXIoJ3UnLCAnbicpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gQ2FsZW5kYXIuU1VOREFZOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHNraXBQYWlyKCdhJywgJ3QnKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIENhbGVuZGFyLlNBVFVSREFZOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgJ1QnOgorICAgICAgICAgICAgICAgICAgICBpZiAoc2tpcFBhaXIoJ3UnLCAnZScpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gQ2FsZW5kYXIuVFVFU0RBWTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChza2lwUGFpcignaCcsICd1JykpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBDYWxlbmRhci5USFVSU0RBWTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlICdNJzoKKyAgICAgICAgICAgICAgICAgICAgaWYgKHNraXBQYWlyKCdvJywgJ24nKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIENhbGVuZGFyLk1PTkRBWTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlICdXJzoKKyAgICAgICAgICAgICAgICAgICAgaWYgKHNraXBQYWlyKCdlJywgJ2QnKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIENhbGVuZGFyLldFRE5FU0RBWTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlICdGJzoKKyAgICAgICAgICAgICAgICAgICAgaWYgKHNraXBQYWlyKCdyJywgJ2knKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIENhbGVuZGFyLkZSSURBWTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIElOVkFMSURfQ0hBUjoKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlRXhjZXB0aW9uKCJJbnZhbGlkIGRheS1uYW1lIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3MuZ2V0SW5kZXgoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwb3Muc2V0SW5kZXgocG9zLmdldEluZGV4KCkgLSAxKTsKKyAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZUV4Y2VwdGlvbigiSW52YWxpZCBkYXktbmFtZSIsIHBvcy5nZXRJbmRleCgpKTsKKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBAcmV0dXJuIHRoZSBqYXZhLnV0aWwuQ2FsZW5kYXIgY29uc3RhbnQgZm9yIHRoZSBwYXJzZWQgbW9udGggbmFtZQorICAgICAgICAgKi8KKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoImZhbGx0aHJvdWdoIikKKyAgICAgICAgZmluYWwgaW50IHBhcnNlTW9udGhOYW1lKGJvb2xlYW4gY2FzZVNlbnNpdGl2ZSkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHN3aXRjaCAoZ2V0Q2hhcigpKSB7CisgICAgICAgICAgICAgICAgY2FzZSAnaic6CisgICAgICAgICAgICAgICAgICAgIGlmIChjYXNlU2Vuc2l0aXZlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGNhc2UgJ0onOgorICAgICAgICAgICAgICAgICAgICBpZiAoc2tpcENoYXIoJ3UnKSB8fCAoIWNhc2VTZW5zaXRpdmUgJiYgc2tpcENoYXIoJ1UnKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChza2lwQ2hhcignbCcpIHx8ICghY2FzZVNlbnNpdGl2ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBza2lwQ2hhcignTCcpKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBDYWxlbmRhci5KVUxZOworICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChza2lwQ2hhcignbicpIHx8ICghY2FzZVNlbnNpdGl2ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBza2lwQ2hhcignTicpKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBDYWxlbmRhci5KVU5FOworICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3Muc2V0SW5kZXgocG9zLmdldEluZGV4KCkgLSAxKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChza2lwUGFpcignYScsICduJykgfHwgKCFjYXNlU2Vuc2l0aXZlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgc2tpcEFsdGVybmF0aXZlUGFpcignYScsICdBJywgJ24nLCAnTicpKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIENhbGVuZGFyLkpBTlVBUlk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSAnbSc6CisgICAgICAgICAgICAgICAgICAgIGlmIChjYXNlU2Vuc2l0aXZlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGNhc2UgJ00nOgorICAgICAgICAgICAgICAgICAgICBpZiAoc2tpcENoYXIoJ2EnKSB8fCAoIWNhc2VTZW5zaXRpdmUgJiYgc2tpcENoYXIoJ0EnKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChza2lwQ2hhcigncicpIHx8ICghY2FzZVNlbnNpdGl2ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBza2lwQ2hhcignUicpKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBDYWxlbmRhci5NQVJDSDsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc2tpcENoYXIoJ3knKSB8fCAoIWNhc2VTZW5zaXRpdmUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgc2tpcENoYXIoJ1knKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gQ2FsZW5kYXIuTUFZOworICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3Muc2V0SW5kZXgocG9zLmdldEluZGV4KCkgLSAxKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlICdhJzoKKyAgICAgICAgICAgICAgICAgICAgaWYgKGNhc2VTZW5zaXRpdmUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgY2FzZSAnQSc6CisgICAgICAgICAgICAgICAgICAgIGlmIChza2lwUGFpcigndScsICdnJykgfHwgKCFjYXNlU2Vuc2l0aXZlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgc2tpcEFsdGVybmF0aXZlUGFpcigndScsICdVJywgJ2cnLCAnRycpKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIENhbGVuZGFyLkFVR1VTVDsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChza2lwUGFpcigncCcsICdyJykgfHwgKCFjYXNlU2Vuc2l0aXZlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgc2tpcEFsdGVybmF0aXZlUGFpcigncCcsICdQJywgJ3InLCAnUicpKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIENhbGVuZGFyLkFQUklMOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgJ2QnOgorICAgICAgICAgICAgICAgICAgICBpZiAoY2FzZVNlbnNpdGl2ZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBjYXNlICdEJzoKKyAgICAgICAgICAgICAgICAgICAgaWYgKHNraXBQYWlyKCdlJywgJ2MnKSB8fCAoIWNhc2VTZW5zaXRpdmUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBza2lwQWx0ZXJuYXRpdmVQYWlyKCdlJywgJ0UnLCAnYycsICdDJykpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gQ2FsZW5kYXIuREVDRU1CRVI7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSAnbyc6CisgICAgICAgICAgICAgICAgICAgIGlmIChjYXNlU2Vuc2l0aXZlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGNhc2UgJ08nOgorICAgICAgICAgICAgICAgICAgICBpZiAoc2tpcFBhaXIoJ2MnLCAndCcpIHx8ICghY2FzZVNlbnNpdGl2ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIHNraXBBbHRlcm5hdGl2ZVBhaXIoJ2MnLCAnQycsICd0JywgJ1QnKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBDYWxlbmRhci5PQ1RPQkVSOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgJ3MnOgorICAgICAgICAgICAgICAgICAgICBpZiAoY2FzZVNlbnNpdGl2ZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBjYXNlICdTJzoKKyAgICAgICAgICAgICAgICAgICAgaWYgKHNraXBQYWlyKCdlJywgJ3AnKSB8fCAoIWNhc2VTZW5zaXRpdmUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBza2lwQWx0ZXJuYXRpdmVQYWlyKCdlJywgJ0UnLCAncCcsICdQJykpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gQ2FsZW5kYXIuU0VQVEVNQkVSOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgJ24nOgorICAgICAgICAgICAgICAgICAgICBpZiAoY2FzZVNlbnNpdGl2ZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBjYXNlICdOJzoKKyAgICAgICAgICAgICAgICAgICAgaWYgKHNraXBQYWlyKCdvJywgJ3YnKSB8fCAoIWNhc2VTZW5zaXRpdmUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBza2lwQWx0ZXJuYXRpdmVQYWlyKCdvJywgJ08nLCAndicsICdWJykpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gQ2FsZW5kYXIuTk9WRU1CRVI7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSAnZic6CisgICAgICAgICAgICAgICAgICAgIGlmIChjYXNlU2Vuc2l0aXZlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGNhc2UgJ0YnOgorICAgICAgICAgICAgICAgICAgICBpZiAoc2tpcFBhaXIoJ2UnLCAnYicpIHx8ICghY2FzZVNlbnNpdGl2ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIHNraXBBbHRlcm5hdGl2ZVBhaXIoJ2UnLCAnRScsICdiJywgJ0InKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBDYWxlbmRhci5GRUJSVUFSWTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlIElOVkFMSURfQ0hBUjoKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlRXhjZXB0aW9uKCJJbnZhbGlkIG1vbnRoIiwgcG9zLmdldEluZGV4KCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcG9zLnNldEluZGV4KHBvcy5nZXRJbmRleCgpIC0gMSk7CisgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2VFeGNlcHRpb24oIkludmFsaWQgbW9udGgiLCBwb3MuZ2V0SW5kZXgoKSk7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIG1pbnV0ZXMgdG8gYmUgYWRkZWQgdG8gdGhlIHRpbWUgaW4gdGhlIGxvY2FsCisgICAgICAgICAqIHRpbWUgem9uZSwgaW4gb3JkZXIgdG8gb2J0YWluIHRoZSBlcXVpdmFsZW50IHRpbWUgaW4gdGhlIFVUQyB0aW1lCisgICAgICAgICAqIHpvbmUuIFJldHVybnMgMCBpZiB0aGUgZGF0ZS10aW1lIGNvbnRhaW5zIG5vIGluZm9ybWF0aW9uIGFib3V0IHRoZQorICAgICAgICAgKiBsb2NhbCB0aW1lIHpvbmUuCisgICAgICAgICAqLworICAgICAgICBmaW5hbCBpbnQgcGFyc2Vab25lT2Zmc2V0KCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGludCBzaWduID0gZ2V0Q2hhcigpOworICAgICAgICAgICAgaWYgKHNpZ24gPT0gJysnIHx8IHNpZ24gPT0gJy0nKSB7CisgICAgICAgICAgICAgICAgaW50IG9mZnNldCA9IHBhcnNlQXNjaWlEaWdpdHMoNCwgNCwgdHJ1ZSk7CisgICAgICAgICAgICAgICAgaWYgKCFpc1ZhbGlkWm9uZU9mZnNldChvZmZzZXQpKSB7CisgICAgICAgICAgICAgICAgICAgIHBvcy5zZXRJbmRleChwb3MuZ2V0SW5kZXgoKSAtIDUpOworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2VFeGNlcHRpb24oIkludmFsaWQgem9uZSIsIHBvcy5nZXRJbmRleCgpKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICByZXR1cm4gKChzaWduID09ICcrJykgPyAtMSA6IDEpCisgICAgICAgICAgICAgICAgICAgICAgICAqIChvZmZzZXQgLyAxMDAgKiA2MCArIG9mZnNldCAlIDEwMCk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHNpZ24gIT0gSU5WQUxJRF9DSEFSKSB7CisgICAgICAgICAgICAgICAgcG9zLnNldEluZGV4KHBvcy5nZXRJbmRleCgpIC0gMSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2VFeGNlcHRpb24oIkludmFsaWQgem9uZSIsIHBvcy5nZXRJbmRleCgpKTsKKyAgICAgICAgfQorCisgICAgICAgIGJvb2xlYW4gaXNWYWxpZFpvbmVPZmZzZXQoaW50IG9mZnNldCkgeworICAgICAgICAgICAgcmV0dXJuIChvZmZzZXQgJSAxMDApIDwgNjA7CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBpbnQgcGFyc2VBc2NpaURpZ2l0cyhpbnQgY291bnQpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gcGFyc2VBc2NpaURpZ2l0cyhjb3VudCwgY291bnQpOworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgaW50IHBhcnNlQXNjaWlEaWdpdHMoaW50IG1pbiwgaW50IG1heCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBwYXJzZUFzY2lpRGlnaXRzKG1pbiwgbWF4LCBmYWxzZSk7CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBpbnQgcGFyc2VBc2NpaURpZ2l0cyhpbnQgbWluLCBpbnQgbWF4LCBib29sZWFuIGlzRU9GKQorICAgICAgICAgICAgICAgIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CisgICAgICAgICAgICBpbnQgcmVzdWx0ID0gMDsKKyAgICAgICAgICAgIGludCBuYkRpZ2l0c1BhcnNlZCA9IDA7CisgICAgICAgICAgICB3aGlsZSAobmJEaWdpdHNQYXJzZWQgPCBtYXggJiYgcGVla0FzY2lpRGlnaXQoKSkgeworICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCAqIDEwICsgZ2V0QXNjaWlEaWdpdCgpOworICAgICAgICAgICAgICAgIG5iRGlnaXRzUGFyc2VkKys7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmICgobmJEaWdpdHNQYXJzZWQgPCBtaW4pCisgICAgICAgICAgICAgICAgICAgIHx8IChuYkRpZ2l0c1BhcnNlZCA9PSBtYXggJiYgIWlzRU9GICYmIHBlZWtBc2NpaURpZ2l0KCkpKSB7CisgICAgICAgICAgICAgICAgcG9zLnNldEluZGV4KHBvcy5nZXRJbmRleCgpIC0gbmJEaWdpdHNQYXJzZWQpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBTdHJpbmcgcmFuZ2UgPSAobWluID09IG1heCkKKyAgICAgICAgICAgICAgICAgICAgPyBJbnRlZ2VyLnRvU3RyaW5nKG1pbikKKyAgICAgICAgICAgICAgICAgICAgOiAiYmV0d2VlbiAiICsgbWluICsgIiBhbmQgIiArIG1heDsKKyAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZUV4Y2VwdGlvbigiSW52YWxpZCBpbnB1dDogZXhwZWN0ZWQgIgorICAgICAgICAgICAgICAgICAgICArIHJhbmdlICsgIiBBU0NJSSBkaWdpdHMiLCBwb3MuZ2V0SW5kZXgoKSk7CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCB2b2lkIHBhcnNlRm9sZGluZ1doaXRlU3BhY2UoKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24geworICAgICAgICAgICAgaWYgKCFza2lwRm9sZGluZ1doaXRlU3BhY2UoKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZUV4Y2VwdGlvbigiSW52YWxpZCBpbnB1dDogZXhwZWN0ZWQgRldTIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIHBvcy5nZXRJbmRleCgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIHZvaWQgcGFyc2VDaGFyKGNoYXIgY2gpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CisgICAgICAgICAgICBpZiAoIXNraXBDaGFyKGNoKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZUV4Y2VwdGlvbigiSW52YWxpZCBpbnB1dDogZXhwZWN0ZWQgJyIgKyBjaCArICInIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIHBvcy5nZXRJbmRleCgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIGludCBnZXRBc2NpaURpZ2l0KCkgeworICAgICAgICAgICAgaW50IGNoID0gZ2V0Q2hhcigpOworICAgICAgICAgICAgaWYgKCcwJyA8PSBjaCAmJiBjaCA8PSAnOScpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gQ2hhcmFjdGVyLmRpZ2l0KChjaGFyKSBjaCwgMTApOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBpZiAoY2ggIT0gSU5WQUxJRF9DSEFSKSB7CisgICAgICAgICAgICAgICAgICAgIHBvcy5zZXRJbmRleChwb3MuZ2V0SW5kZXgoKSAtIDEpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gSU5WQUxJRF9DSEFSOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgZmluYWwgaW50IGdldENoYXIoKSB7CisgICAgICAgICAgICBpZiAocG9zLmdldEluZGV4KCkgPCB0ZXh0Lmxlbmd0aCgpKSB7CisgICAgICAgICAgICAgICAgY2hhciBjaCA9IHRleHQuY2hhckF0KHBvcy5nZXRJbmRleCgpKTsKKyAgICAgICAgICAgICAgICBwb3Muc2V0SW5kZXgocG9zLmdldEluZGV4KCkgKyAxKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gY2g7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHJldHVybiBJTlZBTElEX0NIQVI7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBib29sZWFuIHNraXBGb2xkaW5nV2hpdGVTcGFjZSgpIHsKKyAgICAgICAgICAgIC8vIGZhc3QgcGF0aHM6IGEgc2luZ2xlIEFTQ0lJIHNwYWNlIG9yIG5vIEZXUworICAgICAgICAgICAgaWYgKHNraXBDaGFyKCcgJykpIHsKKyAgICAgICAgICAgICAgICBpZiAoIXBlZWtGb2xkaW5nV2hpdGVTcGFjZSgpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHBvcy5zZXRJbmRleChwb3MuZ2V0SW5kZXgoKSAtIDEpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSBpZiAoIXBlZWtGb2xkaW5nV2hpdGVTcGFjZSgpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBub3JtYWwgcGF0aAorICAgICAgICAgICAgaW50IHN0YXJ0SW5kZXggPSBwb3MuZ2V0SW5kZXgoKTsKKyAgICAgICAgICAgIGlmIChza2lwV2hpdGVTcGFjZSgpKSB7CisgICAgICAgICAgICAgICAgd2hpbGUgKHNraXBOZXdsaW5lKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCFza2lwV2hpdGVTcGFjZSgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBwb3Muc2V0SW5kZXgoc3RhcnRJbmRleCk7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9IGVsc2UgaWYgKHNraXBOZXdsaW5lKCkgJiYgc2tpcFdoaXRlU3BhY2UoKSkgeworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBwb3Muc2V0SW5kZXgoc3RhcnRJbmRleCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgZmluYWwgYm9vbGVhbiBza2lwV2hpdGVTcGFjZSgpIHsKKyAgICAgICAgICAgIGludCBzdGFydEluZGV4ID0gcG9zLmdldEluZGV4KCk7CisgICAgICAgICAgICB3aGlsZSAoc2tpcEFsdGVybmF0aXZlKCcgJywgJ1x0JykpIHsgLyogZW1wdHkgKi8gfQorICAgICAgICAgICAgcmV0dXJuIHBvcy5nZXRJbmRleCgpID4gc3RhcnRJbmRleDsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIGJvb2xlYW4gc2tpcE5ld2xpbmUoKSB7CisgICAgICAgICAgICByZXR1cm4gc2tpcFBhaXIoJ1xyJywgJ1xuJyk7CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBib29sZWFuIHNraXBBbHRlcm5hdGl2ZVRyaXBsZSgKKyAgICAgICAgICAgICAgICBjaGFyIGZpcnN0U3RhbmRhcmQsIGNoYXIgZmlyc3RBbHRlcm5hdGl2ZSwKKyAgICAgICAgICAgICAgICBjaGFyIHNlY29uZFN0YW5kYXJkLCBjaGFyIHNlY29uZEFsdGVybmF0aXZlLAorICAgICAgICAgICAgICAgIGNoYXIgdGhpcmRTdGFuZGFyZCwgY2hhciB0aGlyZEFsdGVybmF0aXZlCisgICAgICAgICkgeworICAgICAgICAgICAgaWYgKHNraXBBbHRlcm5hdGl2ZVBhaXIoZmlyc3RTdGFuZGFyZCwgZmlyc3RBbHRlcm5hdGl2ZSwKKyAgICAgICAgICAgICAgICAgICAgc2Vjb25kU3RhbmRhcmQsIHNlY29uZEFsdGVybmF0aXZlKSkgeworICAgICAgICAgICAgICAgIGlmIChza2lwQWx0ZXJuYXRpdmUodGhpcmRTdGFuZGFyZCwgdGhpcmRBbHRlcm5hdGl2ZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgcG9zLnNldEluZGV4KHBvcy5nZXRJbmRleCgpIC0gMik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgYm9vbGVhbiBza2lwQWx0ZXJuYXRpdmVQYWlyKAorICAgICAgICAgICAgICAgIGNoYXIgZmlyc3RTdGFuZGFyZCwgY2hhciBmaXJzdEFsdGVybmF0aXZlLAorICAgICAgICAgICAgICAgIGNoYXIgc2Vjb25kU3RhbmRhcmQsIGNoYXIgc2Vjb25kQWx0ZXJuYXRpdmUKKyAgICAgICAgKSB7CisgICAgICAgICAgICBpZiAoc2tpcEFsdGVybmF0aXZlKGZpcnN0U3RhbmRhcmQsIGZpcnN0QWx0ZXJuYXRpdmUpKSB7CisgICAgICAgICAgICAgICAgaWYgKHNraXBBbHRlcm5hdGl2ZShzZWNvbmRTdGFuZGFyZCwgc2Vjb25kQWx0ZXJuYXRpdmUpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHBvcy5zZXRJbmRleChwb3MuZ2V0SW5kZXgoKSAtIDEpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIGJvb2xlYW4gc2tpcEFsdGVybmF0aXZlKGNoYXIgc3RhbmRhcmQsIGNoYXIgYWx0ZXJuYXRpdmUpIHsKKyAgICAgICAgICAgIHJldHVybiBza2lwQ2hhcihzdGFuZGFyZCkgfHwgc2tpcENoYXIoYWx0ZXJuYXRpdmUpOworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgYm9vbGVhbiBza2lwUGFpcihjaGFyIGZpcnN0LCBjaGFyIHNlY29uZCkgeworICAgICAgICAgICAgaWYgKHNraXBDaGFyKGZpcnN0KSkgeworICAgICAgICAgICAgICAgIGlmIChza2lwQ2hhcihzZWNvbmQpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHBvcy5zZXRJbmRleChwb3MuZ2V0SW5kZXgoKSAtIDEpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIGJvb2xlYW4gc2tpcENoYXIoY2hhciBjaCkgeworICAgICAgICAgICAgaWYgKHBvcy5nZXRJbmRleCgpIDwgdGV4dC5sZW5ndGgoKQorICAgICAgICAgICAgICAgICAgICAmJiB0ZXh0LmNoYXJBdChwb3MuZ2V0SW5kZXgoKSkgPT0gY2gpIHsKKyAgICAgICAgICAgICAgICBwb3Muc2V0SW5kZXgocG9zLmdldEluZGV4KCkgKyAxKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgZmluYWwgYm9vbGVhbiBwZWVrQXNjaWlEaWdpdCgpIHsKKyAgICAgICAgICAgIHJldHVybiAocG9zLmdldEluZGV4KCkgPCB0ZXh0Lmxlbmd0aCgpCisgICAgICAgICAgICAgICAgICAgICYmICcwJyA8PSB0ZXh0LmNoYXJBdChwb3MuZ2V0SW5kZXgoKSkKKyAgICAgICAgICAgICAgICAgICAgJiYgdGV4dC5jaGFyQXQocG9zLmdldEluZGV4KCkpIDw9ICc5Jyk7CisgICAgICAgIH0KKworICAgICAgICBib29sZWFuIHBlZWtGb2xkaW5nV2hpdGVTcGFjZSgpIHsKKyAgICAgICAgICAgIHJldHVybiAocG9zLmdldEluZGV4KCkgPCB0ZXh0Lmxlbmd0aCgpCisgICAgICAgICAgICAgICAgICAgICYmICh0ZXh0LmNoYXJBdChwb3MuZ2V0SW5kZXgoKSkgPT0gJyAnCisgICAgICAgICAgICAgICAgICAgIHx8IHRleHQuY2hhckF0KHBvcy5nZXRJbmRleCgpKSA9PSAnXHQnCisgICAgICAgICAgICAgICAgICAgIHx8IHRleHQuY2hhckF0KHBvcy5nZXRJbmRleCgpKSA9PSAnXHInKSk7CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBib29sZWFuIHBlZWtDaGFyKGNoYXIgY2gpIHsKKyAgICAgICAgICAgIHJldHVybiAocG9zLmdldEluZGV4KCkgPCB0ZXh0Lmxlbmd0aCgpCisgICAgICAgICAgICAgICAgICAgICYmIHRleHQuY2hhckF0KHBvcy5nZXRJbmRleCgpKSA9PSBjaCk7CisgICAgICAgIH0KKworICAgIH0KKworICAgIHByaXZhdGUgY2xhc3MgUmZjMjgyMlN0cmljdFBhcnNlciBleHRlbmRzIEFic3RyYWN0RGF0ZVBhcnNlciB7CisKKyAgICAgICAgUmZjMjgyMlN0cmljdFBhcnNlcihTdHJpbmcgdGV4dCwgUGFyc2VQb3NpdGlvbiBwb3MpIHsKKyAgICAgICAgICAgIHN1cGVyKHRleHQsIHBvcyk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgRGF0ZSB0cnlQYXJzZSgpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CisgICAgICAgICAgICBpbnQgZGF5TmFtZSA9IHBhcnNlT3B0aW9uYWxCZWdpbigpOworCisgICAgICAgICAgICBpbnQgZGF5ID0gcGFyc2VEYXkoKTsKKyAgICAgICAgICAgIGludCBtb250aCA9IHBhcnNlTW9udGgoKTsKKyAgICAgICAgICAgIGludCB5ZWFyID0gcGFyc2VZZWFyKCk7CisKKyAgICAgICAgICAgIHBhcnNlRm9sZGluZ1doaXRlU3BhY2UoKTsKKworICAgICAgICAgICAgaW50IGhvdXIgPSBwYXJzZUhvdXIoKTsKKyAgICAgICAgICAgIHBhcnNlQ2hhcignOicpOworICAgICAgICAgICAgaW50IG1pbnV0ZSA9IHBhcnNlTWludXRlKCk7CisgICAgICAgICAgICBpbnQgc2Vjb25kID0gKHNraXBDaGFyKCc6JykpID8gcGFyc2VTZWNvbmQoKSA6IDA7CisKKyAgICAgICAgICAgIHBhcnNlRndzQmV0d2VlblRpbWVPZkRheUFuZFpvbmUoKTsKKworICAgICAgICAgICAgaW50IHpvbmUgPSBwYXJzZVpvbmUoKTsKKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICByZXR1cm4gTWFpbERhdGVGb3JtYXQudGhpcy50b0RhdGUoZGF5TmFtZSwgZGF5LCBtb250aCwgeWVhciwKKyAgICAgICAgICAgICAgICAgICAgICAgIGhvdXIsIG1pbnV0ZSwgc2Vjb25kLCB6b25lKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlRXhjZXB0aW9uKCJJbnZhbGlkIGlucHV0OiBzb21lIG9mIHRoZSBjYWxlbmRhciAiCisgICAgICAgICAgICAgICAgICAgICAgICArICJmaWVsZHMgaGF2ZSBpbnZhbGlkIHZhbHVlcywgb3IgZGF5LW5hbWUgaXMgIgorICAgICAgICAgICAgICAgICAgICAgICAgKyAiaW5jb25zaXN0ZW50IHdpdGggZGF0ZSIsIHBvcy5nZXRJbmRleCgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8qKgorICAgICAgICAgKiBAcmV0dXJuIHRoZSBqYXZhLnV0aWwuQ2FsZW5kYXIgY29uc3RhbnQgZm9yIHRoZSBwYXJzZWQgZGF5IG5hbWUsIG9yCisgICAgICAgICAqIFVOS05PV05fREFZX05BTUUgaWZmIHRoZSBiZWdpbiBpcyBtaXNzaW5nCisgICAgICAgICAqLworICAgICAgICBpbnQgcGFyc2VPcHRpb25hbEJlZ2luKCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGludCBkYXlOYW1lOworICAgICAgICAgICAgaWYgKCFwZWVrQXNjaWlEaWdpdCgpKSB7CisgICAgICAgICAgICAgICAgc2tpcEZvbGRpbmdXaGl0ZVNwYWNlKCk7CisgICAgICAgICAgICAgICAgZGF5TmFtZSA9IHBhcnNlRGF5TmFtZSgpOworICAgICAgICAgICAgICAgIHBhcnNlQ2hhcignLCcpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBkYXlOYW1lID0gVU5LTk9XTl9EQVlfTkFNRTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBkYXlOYW1lOworICAgICAgICB9CisKKyAgICAgICAgaW50IHBhcnNlRGF5KCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHNraXBGb2xkaW5nV2hpdGVTcGFjZSgpOworICAgICAgICAgICAgcmV0dXJuIHBhcnNlQXNjaWlEaWdpdHMoMSwgMik7CisgICAgICAgIH0KKworICAgICAgICAvKioKKyAgICAgICAgICogQHJldHVybiB0aGUgamF2YS51dGlsLkNhbGVuZGFyIGNvbnN0YW50IGZvciB0aGUgcGFyc2VkIG1vbnRoIG5hbWUKKyAgICAgICAgICovCisgICAgICAgIGludCBwYXJzZU1vbnRoKCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHBhcnNlRndzSW5Nb250aCgpOworICAgICAgICAgICAgaW50IG1vbnRoID0gcGFyc2VNb250aE5hbWUoaXNNb250aE5hbWVDYXNlU2Vuc2l0aXZlKCkpOworICAgICAgICAgICAgcGFyc2VGd3NJbk1vbnRoKCk7CisgICAgICAgICAgICByZXR1cm4gbW9udGg7CisgICAgICAgIH0KKworICAgICAgICB2b2lkIHBhcnNlRndzSW5Nb250aCgpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CisgICAgICAgICAgICBwYXJzZUZvbGRpbmdXaGl0ZVNwYWNlKCk7CisgICAgICAgIH0KKworICAgICAgICBib29sZWFuIGlzTW9udGhOYW1lQ2FzZVNlbnNpdGl2ZSgpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgaW50IHBhcnNlWWVhcigpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CisgICAgICAgICAgICBpbnQgeWVhciA9IHBhcnNlQXNjaWlEaWdpdHMoNCwgTUFYX1lFQVJfRElHSVRTKTsKKyAgICAgICAgICAgIGlmICh5ZWFyID49IDE5MDApIHsKKyAgICAgICAgICAgICAgICByZXR1cm4geWVhcjsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcG9zLnNldEluZGV4KHBvcy5nZXRJbmRleCgpIC0gNCk7CisgICAgICAgICAgICAgICAgd2hpbGUgKHRleHQuY2hhckF0KHBvcy5nZXRJbmRleCgpIC0gMSkgPT0gJzAnKSB7CisgICAgICAgICAgICAgICAgICAgIHBvcy5zZXRJbmRleChwb3MuZ2V0SW5kZXgoKSAtIDEpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2VFeGNlcHRpb24oIkludmFsaWQgeWVhciIsIHBvcy5nZXRJbmRleCgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGludCBwYXJzZUhvdXIoKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIHBhcnNlQXNjaWlEaWdpdHMoMik7CisgICAgICAgIH0KKworICAgICAgICBpbnQgcGFyc2VNaW51dGUoKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIHBhcnNlQXNjaWlEaWdpdHMoMik7CisgICAgICAgIH0KKworICAgICAgICBpbnQgcGFyc2VTZWNvbmQoKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIHBhcnNlQXNjaWlEaWdpdHMoMik7CisgICAgICAgIH0KKworICAgICAgICB2b2lkIHBhcnNlRndzQmV0d2VlblRpbWVPZkRheUFuZFpvbmUoKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24geworICAgICAgICAgICAgcGFyc2VGb2xkaW5nV2hpdGVTcGFjZSgpOworICAgICAgICB9CisKKyAgICAgICAgaW50IHBhcnNlWm9uZSgpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gcGFyc2Vab25lT2Zmc2V0KCk7CisgICAgICAgIH0KKworICAgIH0KKworICAgIHByaXZhdGUgY2xhc3MgUmZjMjgyMkxlbmllbnRQYXJzZXIgZXh0ZW5kcyBSZmMyODIyU3RyaWN0UGFyc2VyIHsKKworICAgICAgICBwcml2YXRlIEJvb2xlYW4gaGFzRGVmYXVsdEZ3czsKKworICAgICAgICBSZmMyODIyTGVuaWVudFBhcnNlcihTdHJpbmcgdGV4dCwgUGFyc2VQb3NpdGlvbiBwb3MpIHsKKyAgICAgICAgICAgIHN1cGVyKHRleHQsIHBvcyk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgaW50IHBhcnNlT3B0aW9uYWxCZWdpbigpIHsKKyAgICAgICAgICAgIHdoaWxlIChwb3MuZ2V0SW5kZXgoKSA8IHRleHQubGVuZ3RoKCkgJiYgIXBlZWtBc2NpaURpZ2l0KCkpIHsKKyAgICAgICAgICAgICAgICBwb3Muc2V0SW5kZXgocG9zLmdldEluZGV4KCkgKyAxKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcmV0dXJuIFVOS05PV05fREFZX05BTUU7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgaW50IHBhcnNlRGF5KCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHNraXBGb2xkaW5nV2hpdGVTcGFjZSgpOworICAgICAgICAgICAgcmV0dXJuIHBhcnNlQXNjaWlEaWdpdHMoMSwgMyk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgdm9pZCBwYXJzZUZ3c0luTW9udGgoKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24geworICAgICAgICAgICAgLy8gJy0nIGlzIGFsbG93ZWQgdG8gYWNjb21vZGF0ZSBmb3IgdGhlIGRhdGUgZm9ybWF0IGFzIHNwZWNpZmllZCBpbgorICAgICAgICAgICAgLy8gPGEgaHJlZj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzUwMS50eHQiPlJGQyAzNTAxPC9hPgorICAgICAgICAgICAgaWYgKGhhc0RlZmF1bHRGd3MgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGhhc0RlZmF1bHRGd3MgPSAhc2tpcENoYXIoJy0nKTsKKyAgICAgICAgICAgICAgICBza2lwRm9sZGluZ1doaXRlU3BhY2UoKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoaGFzRGVmYXVsdEZ3cykgeworICAgICAgICAgICAgICAgIHNraXBGb2xkaW5nV2hpdGVTcGFjZSgpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBwYXJzZUNoYXIoJy0nKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBib29sZWFuIGlzTW9udGhOYW1lQ2FzZVNlbnNpdGl2ZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBpbnQgcGFyc2VZZWFyKCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGludCB5ZWFyID0gcGFyc2VBc2NpaURpZ2l0cygxLCBNQVhfWUVBUl9ESUdJVFMpOworICAgICAgICAgICAgaWYgKHllYXIgPj0gMTAwMCkgeworICAgICAgICAgICAgICAgIHJldHVybiB5ZWFyOworICAgICAgICAgICAgfSBlbHNlIGlmICh5ZWFyID49IDUwKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHllYXIgKyAxOTAwOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICByZXR1cm4geWVhciArIDIwMDA7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgaW50IHBhcnNlSG91cigpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gcGFyc2VBc2NpaURpZ2l0cygxLCAyKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBpbnQgcGFyc2VNaW51dGUoKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24geworICAgICAgICAgICAgcmV0dXJuIHBhcnNlQXNjaWlEaWdpdHMoMSwgMik7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgaW50IHBhcnNlU2Vjb25kKCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBwYXJzZUFzY2lpRGlnaXRzKDEsIDIpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHZvaWQgcGFyc2VGd3NCZXR3ZWVuVGltZU9mRGF5QW5kWm9uZSgpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CisgICAgICAgICAgICBza2lwRm9sZGluZ1doaXRlU3BhY2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBpbnQgcGFyc2Vab25lKCkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaWYgKHBvcy5nZXRJbmRleCgpID49IHRleHQubGVuZ3RoKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlRXhjZXB0aW9uKCJNaXNzaW5nIHpvbmUiLCBwb3MuZ2V0SW5kZXgoKSk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaWYgKHBlZWtDaGFyKCcrJykgfHwgcGVla0NoYXIoJy0nKSkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2Vab25lT2Zmc2V0KCk7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChza2lwQWx0ZXJuYXRpdmVQYWlyKCdVJywgJ3UnLCAnVCcsICd0JykpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChza2lwQWx0ZXJuYXRpdmVUcmlwbGUoJ0cnLCAnZycsICdNJywgJ20nLAorICAgICAgICAgICAgICAgICAgICAgICAgJ1QnLCAndCcpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGludCBob3Vyc09mZnNldDsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHNraXBBbHRlcm5hdGl2ZSgnRScsICdlJykpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGhvdXJzT2Zmc2V0ID0gNDsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChza2lwQWx0ZXJuYXRpdmUoJ0MnLCAnYycpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBob3Vyc09mZnNldCA9IDU7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc2tpcEFsdGVybmF0aXZlKCdNJywgJ20nKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgaG91cnNPZmZzZXQgPSA2OworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHNraXBBbHRlcm5hdGl2ZSgnUCcsICdwJykpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGhvdXJzT2Zmc2V0ID0gNzsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZUV4Y2VwdGlvbigiSW52YWxpZCB6b25lIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zLmdldEluZGV4KCkpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGlmIChza2lwQWx0ZXJuYXRpdmVQYWlyKCdTJywgJ3MnLCAnVCcsICd0JykpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGhvdXJzT2Zmc2V0ICs9IDE7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc2tpcEFsdGVybmF0aXZlUGFpcignRCcsICdkJywgJ1QnLCAndCcpKSB7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBwb3Muc2V0SW5kZXgocG9zLmdldEluZGV4KCkgLSAxKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZUV4Y2VwdGlvbigiSW52YWxpZCB6b25lIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zLmdldEluZGV4KCkpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBob3Vyc09mZnNldCAqIDYwOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gY2F0Y2ggKFBhcnNlRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBpZiAoTE9HR0VSLmlzTG9nZ2FibGUoTGV2ZWwuRklORSkpIHsKKyAgICAgICAgICAgICAgICAgICAgTE9HR0VSLmxvZyhMZXZlbC5GSU5FLCAiTm8gdGltZXpvbmU/IDogJyIgKyB0ZXh0ICsgIiciLCBlKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBib29sZWFuIGlzVmFsaWRab25lT2Zmc2V0KGludCBvZmZzZXQpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIGJvb2xlYW4gc2tpcEZvbGRpbmdXaGl0ZVNwYWNlKCkgeworICAgICAgICAgICAgYm9vbGVhbiByZXN1bHQgPSBwZWVrRm9sZGluZ1doaXRlU3BhY2UoKTsKKworICAgICAgICAgICAgc2tpcExvb3A6CisgICAgICAgICAgICB3aGlsZSAocG9zLmdldEluZGV4KCkgPCB0ZXh0Lmxlbmd0aCgpKSB7CisgICAgICAgICAgICAgICAgc3dpdGNoICh0ZXh0LmNoYXJBdChwb3MuZ2V0SW5kZXgoKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgY2FzZSAnICc6CisgICAgICAgICAgICAgICAgICAgIGNhc2UgJ1x0JzoKKyAgICAgICAgICAgICAgICAgICAgY2FzZSAnXHInOgorICAgICAgICAgICAgICAgICAgICBjYXNlICdcbic6CisgICAgICAgICAgICAgICAgICAgICAgICBwb3Muc2V0SW5kZXgocG9zLmdldEluZGV4KCkgKyAxKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsgc2tpcExvb3A7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIGJvb2xlYW4gcGVla0ZvbGRpbmdXaGl0ZVNwYWNlKCkgeworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnBlZWtGb2xkaW5nV2hpdGVTcGFjZSgpCisgICAgICAgICAgICAgICAgICAgIHx8IChwb3MuZ2V0SW5kZXgoKSA8IHRleHQubGVuZ3RoKCkKKyAgICAgICAgICAgICAgICAgICAgJiYgdGV4dC5jaGFyQXQocG9zLmdldEluZGV4KCkpID09ICdcbicpOworICAgICAgICB9CisKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2ludGVybmV0L01pbWVCb2R5UGFydC5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvTWltZUJvZHlQYXJ0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWRkMzg3NgotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2ludGVybmV0L01pbWVCb2R5UGFydC5qYXZhCkBAIC0wLDAgKzEsMTcxMiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsLmludGVybmV0OworCitpbXBvcnQgamF2YXgubWFpbC4qOworaW1wb3J0IGphdmF4LmFjdGl2YXRpb24uKjsKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YS51dGlsLio7CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuUHJvcFV0aWw7CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuQVNDSUlVdGlsaXR5OworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLk1pbWVVdGlsOworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLk1lc3NhZ2VSZW1vdmVkSU9FeGNlcHRpb247CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuRm9sZGVyQ2xvc2VkSU9FeGNlcHRpb247CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuTGluZU91dHB1dFN0cmVhbTsKKworLyoqCisgKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgYSBNSU1FIGJvZHkgcGFydC4gSXQgaW1wbGVtZW50cyB0aGUgCisgKiA8Y29kZT5Cb2R5UGFydDwvY29kZT4gYWJzdHJhY3QgY2xhc3MgYW5kIHRoZSA8Y29kZT5NaW1lUGFydDwvY29kZT4KKyAqIGludGVyZmFjZS4gTWltZUJvZHlQYXJ0cyBhcmUgY29udGFpbmVkIGluIDxjb2RlPk1pbWVNdWx0aXBhcnQ8L2NvZGU+CisgKiBvYmplY3RzLiA8cD4KKyAqCisgKiBNaW1lQm9keVBhcnQgdXNlcyB0aGUgPGNvZGU+SW50ZXJuZXRIZWFkZXJzPC9jb2RlPiBjbGFzcyB0byBwYXJzZQorICogYW5kIHN0b3JlIHRoZSBoZWFkZXJzIG9mIHRoYXQgYm9keSBwYXJ0LgorICoKKyAqIDxocj48c3Ryb25nPkEgbm90ZSBvbiBSRkMgODIyIGFuZCBNSU1FIGhlYWRlcnM8L3N0cm9uZz48cD4KKyAqCisgKiBSRkMgODIyIGhlYWRlciBmaWVsZHMgPHN0cm9uZz5tdXN0PC9zdHJvbmc+IGNvbnRhaW4gb25seQorICogVVMtQVNDSUkgY2hhcmFjdGVycy4gTUlNRSBhbGxvd3Mgbm9uIEFTQ0lJIGNoYXJhY3RlcnMgdG8gYmUgcHJlc2VudAorICogaW4gY2VydGFpbiBwb3J0aW9ucyBvZiBjZXJ0YWluIGhlYWRlcnMsIGJ5IGVuY29kaW5nIHRob3NlIGNoYXJhY3RlcnMuCisgKiBSRkMgMjA0NyBzcGVjaWZpZXMgdGhlIHJ1bGVzIGZvciBkb2luZyB0aGlzLiBUaGUgTWltZVV0aWxpdHkKKyAqIGNsYXNzIHByb3ZpZGVkIGluIHRoaXMgcGFja2FnZSBjYW4gYmUgdXNlZCB0byB0byBhY2hpZXZlIHRoaXMuCisgKiBDYWxsZXJzIG9mIHRoZSA8Y29kZT5zZXRIZWFkZXI8L2NvZGU+LCA8Y29kZT5hZGRIZWFkZXI8L2NvZGU+LCBhbmQKKyAqIDxjb2RlPmFkZEhlYWRlckxpbmU8L2NvZGU+IG1ldGhvZHMgYXJlIHJlc3BvbnNpYmxlIGZvciBlbmZvcmNpbmcKKyAqIHRoZSBNSU1FIHJlcXVpcmVtZW50cyBmb3IgdGhlIHNwZWNpZmllZCBoZWFkZXJzLiAgSW4gYWRkaXRpb24sIHRoZXNlCisgKiBoZWFkZXIgZmllbGRzIG11c3QgYmUgZm9sZGVkICh3cmFwcGVkKSBiZWZvcmUgYmVpbmcgc2VudCBpZiB0aGV5CisgKiBleGNlZWQgdGhlIGxpbmUgbGVuZ3RoIGxpbWl0YXRpb24gZm9yIHRoZSB0cmFuc3BvcnQgKDEwMDAgYnl0ZXMgZm9yCisgKiBTTVRQKS4gIFJlY2VpdmVkIGhlYWRlcnMgbWF5IGhhdmUgYmVlbiBmb2xkZWQuICBUaGUgYXBwbGljYXRpb24gaXMKKyAqIHJlc3BvbnNpYmxlIGZvciBmb2xkaW5nIGFuZCB1bmZvbGRpbmcgaGVhZGVycyBhcyBhcHByb3ByaWF0ZS4gPHA+CisgKgorICogQGF1dGhvciBKb2huIE1hbmkKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKiBAYXV0aG9yIEthbndhciBPYmVyb2kKKyAqIEBzZWUgamF2YXgubWFpbC5QYXJ0CisgKiBAc2VlIGphdmF4Lm1haWwuaW50ZXJuZXQuTWltZVBhcnQKKyAqIEBzZWUgamF2YXgubWFpbC5pbnRlcm5ldC5NaW1lVXRpbGl0eQorICovCisKK3B1YmxpYyBjbGFzcyBNaW1lQm9keVBhcnQgZXh0ZW5kcyBCb2R5UGFydCBpbXBsZW1lbnRzIE1pbWVQYXJ0IHsKKworICAgIC8vIFBhcmFub2lhOgorICAgIC8vIGFsbG93IHRoaXMgbGFzdCBtaW51dGUgY2hhbmdlIHRvIGJlIGRpc2FibGVkIGlmIGl0IGNhdXNlcyBwcm9ibGVtcworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gc2V0RGVmYXVsdFRleHRDaGFyc2V0ID0KKwlQcm9wVXRpbC5nZXRCb29sZWFuU3lzdGVtUHJvcGVydHkoCisJICAgICJtYWlsLm1pbWUuc2V0ZGVmYXVsdHRleHRjaGFyc2V0IiwgdHJ1ZSk7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIHNldENvbnRlbnRUeXBlRmlsZU5hbWUgPQorCVByb3BVdGlsLmdldEJvb2xlYW5TeXN0ZW1Qcm9wZXJ0eSgKKwkgICAgIm1haWwubWltZS5zZXRjb250ZW50dHlwZWZpbGVuYW1lIiwgdHJ1ZSk7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIGVuY29kZUZpbGVOYW1lID0KKwlQcm9wVXRpbC5nZXRCb29sZWFuU3lzdGVtUHJvcGVydHkoIm1haWwubWltZS5lbmNvZGVmaWxlbmFtZSIsIGZhbHNlKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIGRlY29kZUZpbGVOYW1lID0KKwlQcm9wVXRpbC5nZXRCb29sZWFuU3lzdGVtUHJvcGVydHkoIm1haWwubWltZS5kZWNvZGVmaWxlbmFtZSIsIGZhbHNlKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIGlnbm9yZU11bHRpcGFydEVuY29kaW5nID0KKwlQcm9wVXRpbC5nZXRCb29sZWFuU3lzdGVtUHJvcGVydHkoCisJICAgICJtYWlsLm1pbWUuaWdub3JlbXVsdGlwYXJ0ZW5jb2RpbmciLCB0cnVlKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIGFsbG93dXRmOCA9CisJUHJvcFV0aWwuZ2V0Qm9vbGVhblN5c3RlbVByb3BlcnR5KCJtYWlsLm1pbWUuYWxsb3d1dGY4IiwgdHJ1ZSk7CisKKyAgICAvLyBQYXJhbm9pYToKKyAgICAvLyBhbGxvdyB0aGlzIGxhc3QgbWludXRlIGNoYW5nZSB0byBiZSBkaXNhYmxlZCBpZiBpdCBjYXVzZXMgcHJvYmxlbXMKKyAgICBzdGF0aWMgZmluYWwgYm9vbGVhbiBjYWNoZU11bHRpcGFydCA9IAkvLyBhY2Nlc3NlZCBieSBNaW1lTWVzc2FnZQorCVByb3BVdGlsLmdldEJvb2xlYW5TeXN0ZW1Qcm9wZXJ0eSgibWFpbC5taW1lLmNhY2hlbXVsdGlwYXJ0IiwgdHJ1ZSk7CisKKworICAgIC8qKgorICAgICAqIFRoZSBEYXRhSGFuZGxlciBvYmplY3QgcmVwcmVzZW50aW5nIHRoaXMgUGFydCdzIGNvbnRlbnQuCisgICAgICovCisgICAgcHJvdGVjdGVkIERhdGFIYW5kbGVyIGRoOworCisgICAgLyoqCisgICAgICogQnl0ZSBhcnJheSB0aGF0IGhvbGRzIHRoZSBieXRlcyBvZiB0aGUgY29udGVudCBvZiB0aGlzIFBhcnQuCisgICAgICovCisgICAgcHJvdGVjdGVkIGJ5dGVbXSBjb250ZW50OworCisgICAgLyoqCisgICAgICogSWYgdGhlIGRhdGEgZm9yIHRoaXMgYm9keSBwYXJ0IHdhcyBzdXBwbGllZCBieSBhbgorICAgICAqIElucHV0U3RyZWFtIHRoYXQgaW1wbGVtZW50cyB0aGUgU2hhcmVkSW5wdXRTdHJlYW0gaW50ZXJmYWNlLAorICAgICAqIDxjb2RlPmNvbnRlbnRTdHJlYW08L2NvZGU+IGlzIGFub3RoZXIgc3VjaCBzdHJlYW0gcmVwcmVzZW50aW5nCisgICAgICogdGhlIGNvbnRlbnQgb2YgdGhpcyBib2R5IHBhcnQuICBJbiB0aGlzIGNhc2UsIDxjb2RlPmNvbnRlbnQ8L2NvZGU+CisgICAgICogd2lsbCBiZSBudWxsLgorICAgICAqCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuMgorICAgICAqLworICAgIHByb3RlY3RlZCBJbnB1dFN0cmVhbSBjb250ZW50U3RyZWFtOworCisgICAgLyoqCisgICAgICogVGhlIEludGVybmV0SGVhZGVycyBvYmplY3QgdGhhdCBzdG9yZXMgYWxsIHRoZSBoZWFkZXJzCisgICAgICogb2YgdGhpcyBib2R5IHBhcnQuCisgICAgICovCisgICAgcHJvdGVjdGVkIEludGVybmV0SGVhZGVycyBoZWFkZXJzOworCisgICAgLyoqCisgICAgICogSWYgb3VyIGNvbnRlbnQgaXMgYSBNdWx0aXBhcnQgb2YgTWVzc2FnZSBvYmplY3QsIHdlIHNhdmUgaXQKKyAgICAgKiB0aGUgZmlyc3QgdGltZSBpdCdzIGNyZWF0ZWQgYnkgcGFyc2luZyBhIHN0cmVhbSBzbyB0aGF0IGNoYW5nZXMKKyAgICAgKiB0byB0aGUgY29udGFpbmVkIG9iamVjdHMgd2lsbCBub3QgYmUgbG9zdC4KKyAgICAgKgorICAgICAqIElmIHRoaXMgZmllbGQgaXMgbm90IG51bGwsIGl0J3MgcmV0dXJuIGJ5IHRoZSB7QGxpbmsgI2dldENvbnRlbnR9CisgICAgICogbWV0aG9kLiAgVGhlIHtAbGluayAjZ2V0Q29udGVudH0gbWV0aG9kIHNldHMgdGhpcyBmaWVsZCBpZiBpdAorICAgICAqIHdvdWxkIHJldHVybiBhIE11bHRpcGFydCBvciBNaW1lTWVzc2FnZSBvYmplY3QuICBUaGlzIGZpZWxkIGlzCisgICAgICogaXMgY2xlYXJlZCBieSB0aGUge0BsaW5rICNzZXREYXRhSGFuZGxlcn0gbWV0aG9kLgorICAgICAqCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNQorICAgICAqLworICAgIHByb3RlY3RlZCBPYmplY3QgY2FjaGVkQ29udGVudDsKKworICAgIC8qKgorICAgICAqIEFuIGVtcHR5IE1pbWVCb2R5UGFydCBvYmplY3QgaXMgY3JlYXRlZC4KKyAgICAgKiBUaGlzIGJvZHkgcGFydCBtYXliZSBmaWxsZWQgaW4gYnkgYSBjbGllbnQgY29uc3RydWN0aW5nIGEgbXVsdGlwYXJ0CisgICAgICogbWVzc2FnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTWltZUJvZHlQYXJ0KCkgeworCXN1cGVyKCk7CisJaGVhZGVycyA9IG5ldyBJbnRlcm5ldEhlYWRlcnMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgTWltZUJvZHlQYXJ0IGJ5IHJlYWRpbmcgYW5kIHBhcnNpbmcgdGhlIGRhdGEgZnJvbQorICAgICAqIHRoZSBzcGVjaWZpZWQgaW5wdXQgc3RyZWFtLiBUaGUgcGFyc2VyIGNvbnN1bWVzIGRhdGEgdGlsbCB0aGUgZW5kCisgICAgICogb2YgdGhlIGdpdmVuIGlucHV0IHN0cmVhbS4gIFRoZSBpbnB1dCBzdHJlYW0gbXVzdCBzdGFydCBhdCB0aGUKKyAgICAgKiBiZWdpbm5pbmcgb2YgYSB2YWxpZCBNSU1FIGJvZHkgcGFydCBhbmQgbXVzdCB0ZXJtaW5hdGUgYXQgdGhlIGVuZAorICAgICAqIG9mIHRoYXQgYm9keSBwYXJ0LiA8cD4KKyAgICAgKgorICAgICAqIE5vdGUgdGhhdCB0aGUgImJvdW5kYXJ5IiBzdHJpbmcgdGhhdCBkZWxpbWl0cyBib2R5IHBhcnRzIG11c3QgCisgICAgICogPHN0cm9uZz5ub3Q8L3N0cm9uZz4gYmUgaW5jbHVkZWQgaW4gdGhlIGlucHV0IHN0cmVhbS4gVGhlIGludGVudGlvbiAKKyAgICAgKiBpcyB0aGF0IHRoZSBNaW1lTXVsdGlwYXJ0IHBhcnNlciB3aWxsIGV4dHJhY3QgZWFjaCBib2R5IHBhcnQncyBieXRlcworICAgICAqIGZyb20gYSBtdWx0aXBhcnQgc3RyZWFtIGFuZCBmZWVkIHRoZW0gaW50byB0aGlzIGNvbnN0cnVjdG9yLCB3aXRob3V0IAorICAgICAqIHRoZSBkZWxpbWl0ZXIgc3RyaW5ncy4KKyAgICAgKgorICAgICAqIEBwYXJhbQlpcwl0aGUgYm9keSBwYXJ0IElucHV0IFN0cmVhbQorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBNaW1lQm9keVBhcnQoSW5wdXRTdHJlYW0gaXMpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWlmICghKGlzIGluc3RhbmNlb2YgQnl0ZUFycmF5SW5wdXRTdHJlYW0pICYmCisJICAgICEoaXMgaW5zdGFuY2VvZiBCdWZmZXJlZElucHV0U3RyZWFtKSAmJgorCSAgICAhKGlzIGluc3RhbmNlb2YgU2hhcmVkSW5wdXRTdHJlYW0pKQorCSAgICBpcyA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKGlzKTsKKwkKKwloZWFkZXJzID0gbmV3IEludGVybmV0SGVhZGVycyhpcyk7CisKKwlpZiAoaXMgaW5zdGFuY2VvZiBTaGFyZWRJbnB1dFN0cmVhbSkgeworCSAgICBTaGFyZWRJbnB1dFN0cmVhbSBzaXMgPSAoU2hhcmVkSW5wdXRTdHJlYW0paXM7CisJICAgIGNvbnRlbnRTdHJlYW0gPSBzaXMubmV3U3RyZWFtKHNpcy5nZXRQb3NpdGlvbigpLCAtMSk7CisJfSBlbHNlIHsKKwkgICAgdHJ5IHsKKwkJY29udGVudCA9IEFTQ0lJVXRpbGl0eS5nZXRCeXRlcyhpcyk7CisJICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZXgpIHsKKwkJdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiRXJyb3IgcmVhZGluZyBpbnB1dCBzdHJlYW0iLCBpb2V4KTsKKwkgICAgfQorCX0KKworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBNaW1lQm9keVBhcnQgdXNpbmcgdGhlIGdpdmVuIGhlYWRlciBhbmQKKyAgICAgKiBjb250ZW50IGJ5dGVzLiA8cD4KKyAgICAgKgorICAgICAqIFVzZWQgYnkgcHJvdmlkZXJzLgorICAgICAqCisgICAgICogQHBhcmFtCWhlYWRlcnMJVGhlIGhlYWRlciBvZiB0aGlzIHBhcnQKKyAgICAgKiBAcGFyYW0JY29udGVudAlieXRlcyByZXByZXNlbnRpbmcgdGhlIGJvZHkgb2YgdGhpcyBwYXJ0LgorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBNaW1lQm9keVBhcnQoSW50ZXJuZXRIZWFkZXJzIGhlYWRlcnMsIGJ5dGVbXSBjb250ZW50KSAKKwkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXN1cGVyKCk7CisJdGhpcy5oZWFkZXJzID0gaGVhZGVyczsKKwl0aGlzLmNvbnRlbnQgPSBjb250ZW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgc2l6ZSBvZiB0aGUgY29udGVudCBvZiB0aGlzIGJvZHkgcGFydCBpbiBieXRlcy4KKyAgICAgKiBSZXR1cm4gLTEgaWYgdGhlIHNpemUgY2Fubm90IGJlIGRldGVybWluZWQuIDxwPgorICAgICAqCisgICAgICogTm90ZSB0aGF0IHRoaXMgbnVtYmVyIG1heSBub3QgYmUgYW4gZXhhY3QgbWVhc3VyZSBvZiB0aGUKKyAgICAgKiBjb250ZW50IHNpemUgYW5kIG1heSBvciBtYXkgbm90IGFjY291bnQgZm9yIGFueSB0cmFuc2ZlcgorICAgICAqIGVuY29kaW5nIG9mIHRoZSBjb250ZW50LiA8cD4KKyAgICAgKgorICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gcmV0dXJucyB0aGUgc2l6ZSBvZiB0aGUgPGNvZGU+Y29udGVudDwvY29kZT4KKyAgICAgKiBhcnJheSAoaWYgbm90IG51bGwpLCBvciwgaWYgPGNvZGU+Y29udGVudFN0cmVhbTwvY29kZT4gaXMgbm90CisgICAgICogbnVsbCwgYW5kIHRoZSA8Y29kZT5hdmFpbGFibGU8L2NvZGU+IG1ldGhvZCByZXR1cm5zIGEgcG9zaXRpdmUKKyAgICAgKiBudW1iZXIsIGl0IHJldHVybnMgdGhhdCBudW1iZXIgYXMgdGhlIHNpemUuICBPdGhlcndpc2UsIGl0IHJldHVybnMKKyAgICAgKiAtMS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gc2l6ZSBpbiBieXRlcywgb3IgLTEgaWYgbm90IGtub3duCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRTaXplKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKGNvbnRlbnQgIT0gbnVsbCkKKwkgICAgcmV0dXJuIGNvbnRlbnQubGVuZ3RoOworCWlmIChjb250ZW50U3RyZWFtICE9IG51bGwpIHsKKwkgICAgdHJ5IHsKKwkJaW50IHNpemUgPSBjb250ZW50U3RyZWFtLmF2YWlsYWJsZSgpOworCQkvLyBvbmx5IGJlbGlldmUgdGhlIHNpemUgaWYgaXQncyBncmVhdGUgdGhhbiB6ZXJvLCBzaW5jZSB6ZXJvCisJCS8vIGlzIHRoZSBkZWZhdWx0IHJldHVybmVkIGJ5IHRoZSBJbnB1dFN0cmVhbSBjbGFzcyBpdHNlbGYKKwkJaWYgKHNpemUgPiAwKQorCQkgICAgcmV0dXJuIHNpemU7CisJICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisJCS8vIGlnbm9yZSBpdAorCSAgICB9CisJfQorCXJldHVybiAtMTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIG51bWJlciBvZiBsaW5lcyBmb3IgdGhlIGNvbnRlbnQgb2YgdGhpcyBQYXJ0LgorICAgICAqIFJldHVybiAtMSBpZiB0aGlzIG51bWJlciBjYW5ub3QgYmUgZGV0ZXJtaW5lZC4gPHA+CisgICAgICoKKyAgICAgKiBOb3RlIHRoYXQgdGhpcyBudW1iZXIgbWF5IG5vdCBiZSBhbiBleGFjdCBtZWFzdXJlIG9mIHRoZSAKKyAgICAgKiBjb250ZW50IGxlbmd0aCBhbmQgbWF5IG9yIG1heSBub3QgYWNjb3VudCBmb3IgYW55IHRyYW5zZmVyIAorICAgICAqIGVuY29kaW5nIG9mIHRoZSBjb250ZW50LiA8cD4KKyAgICAgKgorICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gcmV0dXJucyAtMS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gbnVtYmVyIG9mIGxpbmVzLCBvciAtMSBpZiBub3Qga25vd24KKyAgICAgKi8gIAorICAgIEBPdmVycmlkZQorICAgICBwdWJsaWMgaW50IGdldExpbmVDb3VudCgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXJldHVybiAtMTsKKyAgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIFJGQyA4MjIgIkNvbnRlbnQtVHlwZSIgaGVhZGVyIGZpZWxkLgorICAgICAqIFRoaXMgcmVwcmVzZW50cyB0aGUgY29udGVudCB0eXBlIG9mIHRoZSBjb250ZW50IG9mIHRoaXMKKyAgICAgKiBib2R5IHBhcnQuIFRoaXMgdmFsdWUgbXVzdCBub3QgYmUgbnVsbC4gSWYgdGhpcyBmaWVsZCBpcworICAgICAqIHVuYXZhaWxhYmxlLCAidGV4dC9wbGFpbiIgc2hvdWxkIGJlIHJldHVybmVkLiA8cD4KKyAgICAgKgorICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gdXNlcyA8Y29kZT5nZXRIZWFkZXIobmFtZSk8L2NvZGU+CisgICAgICogdG8gb2J0YWluIHRoZSByZXF1aXNpdGUgaGVhZGVyIGZpZWxkLgorICAgICAqCisgICAgICogQHJldHVybglDb250ZW50LVR5cGUgb2YgdGhpcyBib2R5IHBhcnQKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldENvbnRlbnRUeXBlKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJU3RyaW5nIHMgPSBnZXRIZWFkZXIoIkNvbnRlbnQtVHlwZSIsIG51bGwpOworCXMgPSBNaW1lVXRpbC5jbGVhbkNvbnRlbnRUeXBlKHRoaXMsIHMpOworCWlmIChzID09IG51bGwpCisJICAgIHMgPSAidGV4dC9wbGFpbiI7CisJcmV0dXJuIHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogSXMgdGhpcyBQYXJ0IG9mIHRoZSBzcGVjaWZpZWQgTUlNRSB0eXBlPyAgVGhpcyBtZXRob2QKKyAgICAgKiBjb21wYXJlcyA8c3Ryb25nPm9ubHkgdGhlIDxjb2RlPnByaW1hcnlUeXBlPC9jb2RlPiBhbmQgCisgICAgICogPGNvZGU+c3ViVHlwZTwvY29kZT48L3N0cm9uZz4uCisgICAgICogVGhlIHBhcmFtZXRlcnMgb2YgdGhlIGNvbnRlbnQgdHlwZXMgYXJlIGlnbm9yZWQuIDxwPgorICAgICAqCisgICAgICogRm9yIGV4YW1wbGUsIHRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IHdoZW4KKyAgICAgKiBjb21wYXJpbmcgYSBQYXJ0IG9mIGNvbnRlbnQgdHlwZSA8c3Ryb25nPiJ0ZXh0L3BsYWluIjwvc3Ryb25nPgorICAgICAqIHdpdGggPHN0cm9uZz4idGV4dC9wbGFpbjsgY2hhcnNldD1mb29iYXIiPC9zdHJvbmc+LiA8cD4KKyAgICAgKgorICAgICAqIElmIHRoZSA8Y29kZT5zdWJUeXBlPC9jb2RlPiBvZiA8Y29kZT5taW1lVHlwZTwvY29kZT4gaXMgdGhlCisgICAgICogc3BlY2lhbCBjaGFyYWN0ZXIgJyonLCB0aGVuIHRoZSBzdWJ0eXBlIGlzIGlnbm9yZWQgZHVyaW5nIHRoZQorICAgICAqIGNvbXBhcmlzb24uCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBpc01pbWVUeXBlKFN0cmluZyBtaW1lVHlwZSkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJcmV0dXJuIGlzTWltZVR5cGUodGhpcywgbWltZVR5cGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGRpc3Bvc2l0aW9uIGZyb20gdGhlICJDb250ZW50LURpc3Bvc2l0aW9uIiBoZWFkZXIgZmllbGQuCisgICAgICogVGhpcyByZXByZXNlbnRzIHRoZSBkaXNwb3NpdGlvbiBvZiB0aGlzIHBhcnQuIFRoZSBkaXNwb3NpdGlvbgorICAgICAqIGRlc2NyaWJlcyBob3cgdGhlIHBhcnQgc2hvdWxkIGJlIHByZXNlbnRlZCB0byB0aGUgdXNlci4gPHA+CisgICAgICoKKyAgICAgKiBJZiB0aGUgQ29udGVudC1EaXNwb3NpdGlvbiBmaWVsZCBpcyB1bmF2YWlsYWJsZSwKKyAgICAgKiBudWxsIGlzIHJldHVybmVkLiA8cD4KKyAgICAgKgorICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gdXNlcyA8Y29kZT5nZXRIZWFkZXIobmFtZSk8L2NvZGU+CisgICAgICogdG8gb2J0YWluIHRoZSByZXF1aXNpdGUgaGVhZGVyIGZpZWxkLgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICogQHNlZSAjaGVhZGVycworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0RGlzcG9zaXRpb24oKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gZ2V0RGlzcG9zaXRpb24odGhpcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBkaXNwb3NpdGlvbiBpbiB0aGUgIkNvbnRlbnQtRGlzcG9zaXRpb24iIGhlYWRlciBmaWVsZAorICAgICAqIG9mIHRoaXMgYm9keSBwYXJ0LiAgSWYgdGhlIGRpc3Bvc2l0aW9uIGlzIG51bGwsIGFueSBleGlzdGluZworICAgICAqICJDb250ZW50LURpc3Bvc2l0aW9uIiBoZWFkZXIgZmllbGQgaXMgcmVtb3ZlZC4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFdyaXRlRXhjZXB0aW9uIGlmIHRoZSB1bmRlcmx5aW5nCisgICAgICoJCQlpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IG1vZGlmaWNhdGlvbgorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgYm9keSBwYXJ0IGlzCisgICAgICoJCQlvYnRhaW5lZCBmcm9tIGEgUkVBRF9PTkxZIGZvbGRlci4KKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXREaXNwb3NpdGlvbihTdHJpbmcgZGlzcG9zaXRpb24pIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXNldERpc3Bvc2l0aW9uKHRoaXMsIGRpc3Bvc2l0aW9uKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjb250ZW50IHRyYW5zZmVyIGVuY29kaW5nIGZyb20gdGhlCisgICAgICogIkNvbnRlbnQtVHJhbnNmZXItRW5jb2RpbmciIGhlYWRlcgorICAgICAqIGZpZWxkLiBSZXR1cm5zIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZSBoZWFkZXIgaXMgdW5hdmFpbGFibGUKKyAgICAgKiBvciBpdHMgdmFsdWUgaXMgYWJzZW50LiA8cD4KKyAgICAgKgorICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gdXNlcyA8Y29kZT5nZXRIZWFkZXIobmFtZSk8L2NvZGU+CisgICAgICogdG8gb2J0YWluIHRoZSByZXF1aXNpdGUgaGVhZGVyIGZpZWxkLgorICAgICAqCisgICAgICogQHNlZSAjaGVhZGVycworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0RW5jb2RpbmcoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gZ2V0RW5jb2RpbmcodGhpcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlICJDb250ZW50LUlEIiBoZWFkZXIgZmllbGQuIFJldHVybnMKKyAgICAgKiA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGUgZmllbGQgaXMgdW5hdmFpbGFibGUgb3IgaXRzIHZhbHVlIGlzIAorICAgICAqIGFic2VudC4gPHA+CisgICAgICoKKyAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIHVzZXMgPGNvZGU+Z2V0SGVhZGVyKG5hbWUpPC9jb2RlPgorICAgICAqIHRvIG9idGFpbiB0aGUgcmVxdWlzaXRlIGhlYWRlciBmaWVsZC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldENvbnRlbnRJRCgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXJldHVybiBnZXRIZWFkZXIoIkNvbnRlbnQtSWQiLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlICJDb250ZW50LUlEIiBoZWFkZXIgZmllbGQgb2YgdGhpcyBib2R5IHBhcnQuCisgICAgICogSWYgdGhlIDxjb2RlPmNpZDwvY29kZT4gcGFyYW1ldGVyIGlzIG51bGwsIGFueSBleGlzdGluZyAKKyAgICAgKiAiQ29udGVudC1JRCIgaXMgcmVtb3ZlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbQljaWQJdGhlIENvbnRlbnQtSUQKKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxXcml0ZUV4Y2VwdGlvbiBpZiB0aGUgdW5kZXJseWluZworICAgICAqCQkJaW1wbGVtZW50YXRpb24gZG9lcyBub3Qgc3VwcG9ydCBtb2RpZmljYXRpb24KKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIGJvZHkgcGFydCBpcworICAgICAqCQkJb2J0YWluZWQgZnJvbSBhIFJFQURfT05MWSBmb2xkZXIuCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICogQHNpbmNlCQlKYXZhTWFpbCAxLjMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRDb250ZW50SUQoU3RyaW5nIGNpZCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKGNpZCA9PSBudWxsKQorCSAgICByZW1vdmVIZWFkZXIoIkNvbnRlbnQtSUQiKTsKKwllbHNlCisJICAgIHNldEhlYWRlcigiQ29udGVudC1JRCIsIGNpZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgIkNvbnRlbnQtTUQ1IiBoZWFkZXIgZmllbGQuIFJldHVybnMgCisgICAgICogPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhpcyBmaWVsZCBpcyB1bmF2YWlsYWJsZSBvciBpdHMgdmFsdWUKKyAgICAgKiBpcyBhYnNlbnQuIDxwPgorICAgICAqCisgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiB1c2VzIDxjb2RlPmdldEhlYWRlcihuYW1lKTwvY29kZT4KKyAgICAgKiB0byBvYnRhaW4gdGhlIHJlcXVpc2l0ZSBoZWFkZXIgZmllbGQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXRDb250ZW50TUQ1KCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJcmV0dXJuIGdldEhlYWRlcigiQ29udGVudC1NRDUiLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlICJDb250ZW50LU1ENSIgaGVhZGVyIGZpZWxkIG9mIHRoaXMgYm9keSBwYXJ0LgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsV3JpdGVFeGNlcHRpb24gaWYgdGhlIHVuZGVybHlpbmcKKyAgICAgKgkJCWltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBib2R5IHBhcnQgaXMKKyAgICAgKgkJCW9idGFpbmVkIGZyb20gYSBSRUFEX09OTFkgZm9sZGVyLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldENvbnRlbnRNRDUoU3RyaW5nIG1kNSkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJc2V0SGVhZGVyKCJDb250ZW50LU1ENSIsIG1kNSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBsYW5ndWFnZXMgc3BlY2lmaWVkIGluIHRoZSBDb250ZW50LUxhbmd1YWdlIGhlYWRlcgorICAgICAqIG9mIHRoaXMgTWltZVBhcnQuIFRoZSBDb250ZW50LUxhbmd1YWdlIGhlYWRlciBpcyBkZWZpbmVkIGJ5CisgICAgICogUkZDIDE3NjYuIFJldHVybnMgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhpcyBoZWFkZXIgaXMgbm90CisgICAgICogYXZhaWxhYmxlIG9yIGl0cyB2YWx1ZSBpcyBhYnNlbnQuIDxwPgorICAgICAqCisgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiB1c2VzIDxjb2RlPmdldEhlYWRlcihuYW1lKTwvY29kZT4KKyAgICAgKiB0byBvYnRhaW4gdGhlIHJlcXVpc2l0ZSBoZWFkZXIgZmllbGQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZ1tdIGdldENvbnRlbnRMYW5ndWFnZSgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXJldHVybiBnZXRDb250ZW50TGFuZ3VhZ2UodGhpcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBDb250ZW50LUxhbmd1YWdlIGhlYWRlciBvZiB0aGlzIE1pbWVQYXJ0LiBUaGUKKyAgICAgKiBDb250ZW50LUxhbmd1YWdlIGhlYWRlciBpcyBkZWZpbmVkIGJ5IFJGQyAxNzY2LgorICAgICAqCisgICAgICogQHBhcmFtIGxhbmd1YWdlcyAJYXJyYXkgb2YgbGFuZ3VhZ2UgdGFncworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldENvbnRlbnRMYW5ndWFnZShTdHJpbmdbXSBsYW5ndWFnZXMpCisJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlzZXRDb250ZW50TGFuZ3VhZ2UodGhpcywgbGFuZ3VhZ2VzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSAiQ29udGVudC1EZXNjcmlwdGlvbiIgaGVhZGVyIGZpZWxkIG9mIHRoaXMgYm9keSBwYXJ0LgorICAgICAqIFRoaXMgdHlwaWNhbGx5IGFzc29jaWF0ZXMgc29tZSBkZXNjcmlwdGl2ZSBpbmZvcm1hdGlvbiB3aXRoIAorICAgICAqIHRoaXMgcGFydC4gUmV0dXJucyBudWxsIGlmIHRoaXMgZmllbGQgaXMgdW5hdmFpbGFibGUgb3IgaXRzCisgICAgICogdmFsdWUgaXMgYWJzZW50LiA8cD4KKyAgICAgKgorICAgICAqIElmIHRoZSBDb250ZW50LURlc2NyaXB0aW9uIGZpZWxkIGlzIGVuY29kZWQgYXMgcGVyIFJGQyAyMDQ3LAorICAgICAqIGl0IGlzIGRlY29kZWQgYW5kIGNvbnZlcnRlZCBpbnRvIFVuaWNvZGUuIElmIHRoZSBkZWNvZGluZyBvciAKKyAgICAgKiBjb252ZXJzaW9uIGZhaWxzLCB0aGUgcmF3IGRhdGEgaXMgcmV0dXJuZWQgYXMgaXMuIDxwPgorICAgICAqCisgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiB1c2VzIDxjb2RlPmdldEhlYWRlcihuYW1lKTwvY29kZT4KKyAgICAgKiB0byBvYnRhaW4gdGhlIHJlcXVpc2l0ZSBoZWFkZXIgZmllbGQuCisgICAgICogCisgICAgICogQHJldHVybgljb250ZW50IGRlc2NyaXB0aW9uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXREZXNjcmlwdGlvbigpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXJldHVybiBnZXREZXNjcmlwdGlvbih0aGlzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlICJDb250ZW50LURlc2NyaXB0aW9uIiBoZWFkZXIgZmllbGQgZm9yIHRoaXMgYm9keSBwYXJ0LgorICAgICAqIElmIHRoZSBkZXNjcmlwdGlvbiBwYXJhbWV0ZXIgaXMgPGNvZGU+bnVsbDwvY29kZT4sIHRoZW4gYW55IAorICAgICAqIGV4aXN0aW5nICJDb250ZW50LURlc2NyaXB0aW9uIiBmaWVsZHMgYXJlIHJlbW92ZWQuIDxwPgorICAgICAqCisgICAgICogSWYgdGhlIGRlc2NyaXB0aW9uIGNvbnRhaW5zIG5vbiBVUy1BU0NJSSBjaGFyYWN0ZXJzLCBpdCB3aWxsIAorICAgICAqIGJlIGVuY29kZWQgdXNpbmcgdGhlIHBsYXRmb3JtJ3MgZGVmYXVsdCBjaGFyc2V0LiBJZiB0aGUgCisgICAgICogZGVzY3JpcHRpb24gY29udGFpbnMgb25seSBVUy1BU0NJSSBjaGFyYWN0ZXJzLCBubyBlbmNvZGluZyAKKyAgICAgKiBpcyBkb25lIGFuZCBpdCBpcyB1c2VkIGFzIGlzLiA8cD4KKyAgICAgKgorICAgICAqIE5vdGUgdGhhdCBpZiB0aGUgY2hhcnNldCBlbmNvZGluZyBwcm9jZXNzIGZhaWxzLCBhCisgICAgICogTWVzc2FnaW5nRXhjZXB0aW9uIGlzIHRocm93biwgYW5kIGFuIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24KKyAgICAgKiBpcyBpbmNsdWRlZCBpbiB0aGUgY2hhaW4gb2YgbmVzdGVkIGV4Y2VwdGlvbnMgd2l0aGluIHRoZQorICAgICAqIE1lc3NhZ2luZ0V4Y2VwdGlvbi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZGVzY3JpcHRpb24gY29udGVudCBkZXNjcmlwdGlvbgorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFdyaXRlRXhjZXB0aW9uIGlmIHRoZSB1bmRlcmx5aW5nCisgICAgICoJCQlpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IG1vZGlmaWNhdGlvbgorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgYm9keSBwYXJ0IGlzCisgICAgICoJCQlvYnRhaW5lZCBmcm9tIGEgUkVBRF9PTkxZIGZvbGRlci4KKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIE1lc3NhZ2luZ0V4Y2VwdGlvbiBvdGhlcndpc2U7IGFuCisgICAgICogICAgICAgICAgICAgICAgICBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIG1heSBiZSBpbmNsdWRlZAorICAgICAqICAgICAgICAgICAgICAgICAgaW4gdGhlIGV4Y2VwdGlvbiBjaGFpbiBpZiB0aGUgY2hhcnNldAorICAgICAqICAgICAgICAgICAgICAgICAgY29udmVyc2lvbiBmYWlscy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXREZXNjcmlwdGlvbihTdHJpbmcgZGVzY3JpcHRpb24pIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXNldERlc2NyaXB0aW9uKGRlc2NyaXB0aW9uLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlICJDb250ZW50LURlc2NyaXB0aW9uIiBoZWFkZXIgZmllbGQgZm9yIHRoaXMgYm9keSBwYXJ0LgorICAgICAqIElmIHRoZSBkZXNjcmlwdGlvbiBwYXJhbWV0ZXIgaXMgPGNvZGU+bnVsbDwvY29kZT4sIHRoZW4gYW55IAorICAgICAqIGV4aXN0aW5nICJDb250ZW50LURlc2NyaXB0aW9uIiBmaWVsZHMgYXJlIHJlbW92ZWQuIDxwPgorICAgICAqCisgICAgICogSWYgdGhlIGRlc2NyaXB0aW9uIGNvbnRhaW5zIG5vbiBVUy1BU0NJSSBjaGFyYWN0ZXJzLCBpdCB3aWxsIAorICAgICAqIGJlIGVuY29kZWQgdXNpbmcgdGhlIHNwZWNpZmllZCBjaGFyc2V0LiBJZiB0aGUgZGVzY3JpcHRpb24gCisgICAgICogY29udGFpbnMgb25seSBVUy1BU0NJSSBjaGFyYWN0ZXJzLCBubyBlbmNvZGluZyAgaXMgZG9uZSBhbmQgCisgICAgICogaXQgaXMgdXNlZCBhcyBpcy4gPHA+CisgICAgICoKKyAgICAgKiBOb3RlIHRoYXQgaWYgdGhlIGNoYXJzZXQgZW5jb2RpbmcgcHJvY2VzcyBmYWlscywgYQorICAgICAqIE1lc3NhZ2luZ0V4Y2VwdGlvbiBpcyB0aHJvd24sIGFuZCBhbiBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uCisgICAgICogaXMgaW5jbHVkZWQgaW4gdGhlIGNoYWluIG9mIG5lc3RlZCBleGNlcHRpb25zIHdpdGhpbiB0aGUKKyAgICAgKiBNZXNzYWdpbmdFeGNlcHRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0JZGVzY3JpcHRpb24JRGVzY3JpcHRpb24KKyAgICAgKiBAcGFyYW0JY2hhcnNldAkJQ2hhcnNldCBmb3IgZW5jb2RpbmcKKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxXcml0ZUV4Y2VwdGlvbiBpZiB0aGUgdW5kZXJseWluZworICAgICAqCQkJaW1wbGVtZW50YXRpb24gZG9lcyBub3Qgc3VwcG9ydCBtb2RpZmljYXRpb24KKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIGJvZHkgcGFydCBpcworICAgICAqCQkJb2J0YWluZWQgZnJvbSBhIFJFQURfT05MWSBmb2xkZXIuCisgICAgICogQGV4Y2VwdGlvbiAgICAgICBNZXNzYWdpbmdFeGNlcHRpb24gb3RoZXJ3aXNlOyBhbgorICAgICAqICAgICAgICAgICAgICAgICAgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBtYXkgYmUgaW5jbHVkZWQKKyAgICAgKiAgICAgICAgICAgICAgICAgIGluIHRoZSBleGNlcHRpb24gY2hhaW4gaWYgdGhlIGNoYXJzZXQKKyAgICAgKiAgICAgICAgICAgICAgICAgIGNvbnZlcnNpb24gZmFpbHMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RGVzY3JpcHRpb24oU3RyaW5nIGRlc2NyaXB0aW9uLCBTdHJpbmcgY2hhcnNldCkgCisJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXNldERlc2NyaXB0aW9uKHRoaXMsIGRlc2NyaXB0aW9uLCBjaGFyc2V0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGZpbGVuYW1lIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGJvZHkgcGFydC4gPHA+CisgICAgICoKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgImZpbGVuYW1lIiBwYXJhbWV0ZXIgZnJvbSB0aGUKKyAgICAgKiAiQ29udGVudC1EaXNwb3NpdGlvbiIgaGVhZGVyIGZpZWxkIG9mIHRoaXMgYm9keSBwYXJ0LiBJZiBpdHMKKyAgICAgKiBub3QgYXZhaWxhYmxlLCByZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgIm5hbWUiIHBhcmFtZXRlciBmcm9tCisgICAgICogdGhlICJDb250ZW50LVR5cGUiIGhlYWRlciBmaWVsZCBvZiB0aGlzIGJvZHkgcGFydC4KKyAgICAgKiBSZXR1cm5zIDxjb2RlPm51bGw8L2NvZGU+IGlmIGJvdGggYXJlIGFic2VudC4gPHA+CisgICAgICoKKyAgICAgKiBJZiB0aGUgPGNvZGU+bWFpbC5taW1lLmRlY29kZWZpbGVuYW1lPC9jb2RlPiBTeXN0ZW0gcHJvcGVydHkKKyAgICAgKiBpcyBzZXQgdG8gdHJ1ZSwgdGhlIHtAbGluayBNaW1lVXRpbGl0eSNkZWNvZGVUZXh0CisgICAgICogTWltZVV0aWxpdHkuZGVjb2RlVGV4dH0gbWV0aG9kIHdpbGwgYmUgdXNlZCB0byBkZWNvZGUgdGhlCisgICAgICogZmlsZW5hbWUuICBXaGlsZSBzdWNoIGVuY29kaW5nIGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhlIE1JTUUKKyAgICAgKiBzcGVjLCBtYW55IG1haWxlcnMgdXNlIHRoaXMgdGVjaG5pcXVlIHRvIHN1cHBvcnQgbm9uLUFTQ0lJCisgICAgICogY2hhcmFjdGVycyBpbiBmaWxlbmFtZXMuICBUaGUgZGVmYXVsdCB2YWx1ZSBvZiB0aGlzIHByb3BlcnR5CisgICAgICogaXMgZmFsc2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCWZpbGVuYW1lCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXRGaWxlTmFtZSgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXJldHVybiBnZXRGaWxlTmFtZSh0aGlzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIGZpbGVuYW1lIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGJvZHkgcGFydCwgaWYgcG9zc2libGUuIDxwPgorICAgICAqCisgICAgICogU2V0cyB0aGUgImZpbGVuYW1lIiBwYXJhbWV0ZXIgb2YgdGhlICJDb250ZW50LURpc3Bvc2l0aW9uIgorICAgICAqIGhlYWRlciBmaWVsZCBvZiB0aGlzIGJvZHkgcGFydC4gIEZvciBjb21wYXRpYmlsaXR5IHdpdGggb2xkZXIKKyAgICAgKiBtYWlsZXJzLCB0aGUgIm5hbWUiIHBhcmFtZXRlciBvZiB0aGUgIkNvbnRlbnQtVHlwZSIgaGVhZGVyIGlzCisgICAgICogYWxzbyBzZXQuIDxwPgorICAgICAqCisgICAgICogSWYgdGhlIDxjb2RlPm1haWwubWltZS5lbmNvZGVmaWxlbmFtZTwvY29kZT4gU3lzdGVtIHByb3BlcnR5CisgICAgICogaXMgc2V0IHRvIHRydWUsIHRoZSB7QGxpbmsgTWltZVV0aWxpdHkjZW5jb2RlVGV4dAorICAgICAqIE1pbWVVdGlsaXR5LmVuY29kZVRleHR9IG1ldGhvZCB3aWxsIGJlIHVzZWQgdG8gZW5jb2RlIHRoZQorICAgICAqIGZpbGVuYW1lLiAgV2hpbGUgc3VjaCBlbmNvZGluZyBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBNSU1FCisgICAgICogc3BlYywgbWFueSBtYWlsZXJzIHVzZSB0aGlzIHRlY2huaXF1ZSB0byBzdXBwb3J0IG5vbi1BU0NJSQorICAgICAqIGNoYXJhY3RlcnMgaW4gZmlsZW5hbWVzLiAgVGhlIGRlZmF1bHQgdmFsdWUgb2YgdGhpcyBwcm9wZXJ0eQorICAgICAqIGlzIGZhbHNlLgorICAgICAqCisgICAgICogQHBhcmFtCWZpbGVuYW1lCXRoZSBmaWxlIG5hbWUKKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxXcml0ZUV4Y2VwdGlvbiBpZiB0aGUgdW5kZXJseWluZworICAgICAqCQkJaW1wbGVtZW50YXRpb24gZG9lcyBub3Qgc3VwcG9ydCBtb2RpZmljYXRpb24KKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIGJvZHkgcGFydCBpcworICAgICAqCQkJb2J0YWluZWQgZnJvbSBhIFJFQURfT05MWSBmb2xkZXIuCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0RmlsZU5hbWUoU3RyaW5nIGZpbGVuYW1lKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlzZXRGaWxlTmFtZSh0aGlzLCBmaWxlbmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIGEgZGVjb2RlZCBpbnB1dCBzdHJlYW0gZm9yIHRoaXMgYm9keSBwYXJ0J3MgImNvbnRlbnQiLiA8cD4KKyAgICAgKgorICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gb2J0YWlucyB0aGUgaW5wdXQgc3RyZWFtIGZyb20gdGhlIERhdGFIYW5kbGVyLgorICAgICAqIFRoYXQgaXMsIGl0IGludm9rZXMgZ2V0RGF0YUhhbmRsZXIoKS5nZXRJbnB1dFN0cmVhbSgpOworICAgICAqCisgICAgICogQHJldHVybiAJCWFuIElucHV0U3RyZWFtCisgICAgICogQGV4Y2VwdGlvbiAgICAgICBJT0V4Y2VwdGlvbiB0aGlzIGlzIHR5cGljYWxseSB0aHJvd24gYnkgdGhlCisgICAgICoJCQlEYXRhSGFuZGxlci4gUmVmZXIgdG8gdGhlIGRvY3VtZW50YXRpb24gZm9yCisgICAgICoJCQlqYXZheC5hY3RpdmF0aW9uLkRhdGFIYW5kbGVyIGZvciBtb3JlIGRldGFpbHMuCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICoKKyAgICAgKiBAc2VlCSNnZXRDb250ZW50U3RyZWFtCisgICAgICogQHNlZSAJamF2YXguYWN0aXZhdGlvbi5EYXRhSGFuZGxlciNnZXRJbnB1dFN0cmVhbQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBJbnB1dFN0cmVhbSBnZXRJbnB1dFN0cmVhbSgpIAorCQl0aHJvd3MgSU9FeGNlcHRpb24sIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJcmV0dXJuIGdldERhdGFIYW5kbGVyKCkuZ2V0SW5wdXRTdHJlYW0oKTsKKyAgICB9CisKKyAgIC8qKgorICAgICAqIFByb2R1Y2UgdGhlIHJhdyBieXRlcyBvZiB0aGUgY29udGVudC4gVGhpcyBtZXRob2QgaXMgdXNlZAorICAgICAqIHdoZW4gY3JlYXRpbmcgYSBEYXRhSGFuZGxlciBvYmplY3QgZm9yIHRoZSBjb250ZW50LiBTdWJjbGFzc2VzCisgICAgICogdGhhdCBjYW4gcHJvdmlkZSBhIHNlcGFyYXRlIGlucHV0IHN0cmVhbSBmb3IganVzdCB0aGUgUGFydAorICAgICAqIGNvbnRlbnQgbWlnaHQgd2FudCB0byBvdmVycmlkZSB0aGlzIG1ldGhvZC4gPHA+CisgICAgICogCisgICAgICogQHJldHVybglhbiBJbnB1dFN0cmVhbSBjb250YWluaW5nIHRoZSByYXcgYnl0ZXMKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKiBAc2VlICNjb250ZW50CisgICAgICogQHNlZSBNaW1lTWVzc2FnZSNnZXRDb250ZW50U3RyZWFtCisgICAgICovCisgICAgcHJvdGVjdGVkIElucHV0U3RyZWFtIGdldENvbnRlbnRTdHJlYW0oKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpZiAoY29udGVudFN0cmVhbSAhPSBudWxsKQorCSAgICByZXR1cm4gKChTaGFyZWRJbnB1dFN0cmVhbSljb250ZW50U3RyZWFtKS5uZXdTdHJlYW0oMCwgLTEpOworCWlmIChjb250ZW50ICE9IG51bGwpCisJICAgIHJldHVybiBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oY29udGVudCk7CisJCisJdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiTm8gTWltZUJvZHlQYXJ0IGNvbnRlbnQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYW4gSW5wdXRTdHJlYW0gdG8gdGhlIHJhdyBkYXRhIHdpdGggYW55IENvbnRlbnQtVHJhbnNmZXItRW5jb2RpbmcKKyAgICAgKiBpbnRhY3QuICBUaGlzIG1ldGhvZCBpcyB1c2VmdWwgaWYgdGhlICJDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nIgorICAgICAqIGhlYWRlciBpcyBpbmNvcnJlY3Qgb3IgY29ycnVwdCwgd2hpY2ggd291bGQgcHJldmVudCB0aGUKKyAgICAgKiA8Y29kZT5nZXRJbnB1dFN0cmVhbTwvY29kZT4gbWV0aG9kIG9yIDxjb2RlPmdldENvbnRlbnQ8L2NvZGU+IG1ldGhvZAorICAgICAqIGZyb20gcmV0dXJuaW5nIHRoZSBjb3JyZWN0IGRhdGEuICBJbiBzdWNoIGEgY2FzZSB0aGUgYXBwbGljYXRpb24gbWF5CisgICAgICogdXNlIHRoaXMgbWV0aG9kIGFuZCBhdHRlbXB0IHRvIGRlY29kZSB0aGUgcmF3IGRhdGEgaXRzZWxmLiA8cD4KKyAgICAgKgorICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gc2ltcGx5IGNhbGxzIHRoZSA8Y29kZT5nZXRDb250ZW50U3RyZWFtPC9jb2RlPgorICAgICAqIG1ldGhvZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4JYW4gSW5wdXRTdHJlYW0gY29udGFpbmluZyB0aGUgcmF3IGJ5dGVzCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICogQHNlZQkjZ2V0SW5wdXRTdHJlYW0KKyAgICAgKiBAc2VlCSNnZXRDb250ZW50U3RyZWFtCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuMgorICAgICAqLworICAgIHB1YmxpYyBJbnB1dFN0cmVhbSBnZXRSYXdJbnB1dFN0cmVhbSgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXJldHVybiBnZXRDb250ZW50U3RyZWFtKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIGEgRGF0YUhhbmRsZXIgZm9yIHRoaXMgYm9keSBwYXJ0J3MgY29udGVudC4gPHA+CisgICAgICoKKyAgICAgKiBUaGUgaW1wbGVtZW50YXRpb24gcHJvdmlkZWQgaGVyZSB3b3JrcyBqdXN0IGxpa2UgdGhlCisgICAgICogdGhlIGltcGxlbWVudGF0aW9uIGluIE1pbWVNZXNzYWdlLgorICAgICAqIEBzZWUJTWltZU1lc3NhZ2UjZ2V0RGF0YUhhbmRsZXIKKyAgICAgKi8gIAorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBEYXRhSGFuZGxlciBnZXREYXRhSGFuZGxlcigpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWlmIChkaCA9PSBudWxsKQorCSAgICBkaCA9IG5ldyBNaW1lUGFydERhdGFIYW5kbGVyKHRoaXMpOworCXJldHVybiBkaDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIGNvbnRlbnQgYXMgYSBKYXZhIG9iamVjdC4gVGhlIHR5cGUgb2YgdGhlIG9iamVjdAorICAgICAqIHJldHVybmVkIGlzIG9mIGNvdXJzZSBkZXBlbmRlbnQgb24gdGhlIGNvbnRlbnQgaXRzZWxmLiBGb3IgCisgICAgICogZXhhbXBsZSwgdGhlIG5hdGl2ZSBmb3JtYXQgb2YgYSB0ZXh0L3BsYWluIGNvbnRlbnQgaXMgdXN1YWxseQorICAgICAqIGEgU3RyaW5nIG9iamVjdC4gVGhlIG5hdGl2ZSBmb3JtYXQgZm9yIGEgIm11bHRpcGFydCIKKyAgICAgKiBjb250ZW50IGlzIGFsd2F5cyBhIE11bHRpcGFydCBzdWJjbGFzcy4gRm9yIGNvbnRlbnQgdHlwZXMgdGhhdCBhcmUKKyAgICAgKiB1bmtub3duIHRvIHRoZSBEYXRhSGFuZGxlciBzeXN0ZW0sIGFuIGlucHV0IHN0cmVhbSBpcyByZXR1cm5lZAorICAgICAqIGFzIHRoZSBjb250ZW50LiA8cD4KKyAgICAgKgorICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gb2J0YWlucyB0aGUgY29udGVudCBmcm9tIHRoZSBEYXRhSGFuZGxlci4KKyAgICAgKiBUaGF0IGlzLCBpdCBpbnZva2VzIGdldERhdGFIYW5kbGVyKCkuZ2V0Q29udGVudCgpOworICAgICAqIElmIHRoZSBjb250ZW50IGlzIGEgTXVsdGlwYXJ0IG9yIE1lc3NhZ2Ugb2JqZWN0IGFuZCB3YXMgY3JlYXRlZCBieQorICAgICAqIHBhcnNpbmcgYSBzdHJlYW0sIHRoZSBvYmplY3QgaXMgY2FjaGVkIGFuZCByZXR1cm5lZCBpbiBzdWJzZXF1ZW50CisgICAgICogY2FsbHMgc28gdGhhdCBtb2RpZmljYXRpb25zIHRvIHRoZSBjb250ZW50IHdpbGwgbm90IGJlIGxvc3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuICAgICAgICAgIE9iamVjdAorICAgICAqIEBleGNlcHRpb24gICAgICAgSU9FeGNlcHRpb24gdGhpcyBpcyB0eXBpY2FsbHkgdGhyb3duIGJ5IHRoZQorICAgICAqCQkJRGF0YUhhbmRsZXIuIFJlZmVyIHRvIHRoZSBkb2N1bWVudGF0aW9uIGZvcgorICAgICAqCQkJamF2YXguYWN0aXZhdGlvbi5EYXRhSGFuZGxlciBmb3IgbW9yZSBkZXRhaWxzLgorICAgICAqIEBleGNlcHRpb24gICAgICAgTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBvdGhlciBmYWlsdXJlcworICAgICAqLyAgCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE9iamVjdCBnZXRDb250ZW50KCkgdGhyb3dzIElPRXhjZXB0aW9uLCBNZXNzYWdpbmdFeGNlcHRpb24geworCWlmIChjYWNoZWRDb250ZW50ICE9IG51bGwpCisJICAgIHJldHVybiBjYWNoZWRDb250ZW50OworCU9iamVjdCBjOworCXRyeSB7CisJICAgIGMgPSBnZXREYXRhSGFuZGxlcigpLmdldENvbnRlbnQoKTsKKwl9IGNhdGNoIChGb2xkZXJDbG9zZWRJT0V4Y2VwdGlvbiBmZXgpIHsKKwkgICAgdGhyb3cgbmV3IEZvbGRlckNsb3NlZEV4Y2VwdGlvbihmZXguZ2V0Rm9sZGVyKCksIGZleC5nZXRNZXNzYWdlKCkpOworCX0gY2F0Y2ggKE1lc3NhZ2VSZW1vdmVkSU9FeGNlcHRpb24gbWV4KSB7CisJICAgIHRocm93IG5ldyBNZXNzYWdlUmVtb3ZlZEV4Y2VwdGlvbihtZXguZ2V0TWVzc2FnZSgpKTsKKwl9CisJaWYgKGNhY2hlTXVsdGlwYXJ0ICYmCisJCShjIGluc3RhbmNlb2YgTXVsdGlwYXJ0IHx8IGMgaW5zdGFuY2VvZiBNZXNzYWdlKSAmJgorCQkoY29udGVudCAhPSBudWxsIHx8IGNvbnRlbnRTdHJlYW0gIT0gbnVsbCkpIHsKKwkgICAgY2FjaGVkQ29udGVudCA9IGM7CisJICAgIC8qCisJICAgICAqIFdlIG1heSBhYmFuZG9uIHRoZSBpbnB1dCBzdHJlYW0gc28gbWFrZSBzdXJlCisJICAgICAqIHRoZSBNaW1lTXVsdGlwYXJ0IGhhcyBjb25zdW1lZCB0aGUgc3RyZWFtLgorCSAgICAgKi8KKwkgICAgaWYgKGMgaW5zdGFuY2VvZiBNaW1lTXVsdGlwYXJ0KQorCQkoKE1pbWVNdWx0aXBhcnQpYykucGFyc2UoKTsKKwl9CisJcmV0dXJuIGM7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgcHJvdmlkZXMgdGhlIG1lY2hhbmlzbSB0byBzZXQgdGhpcyBib2R5IHBhcnQncyBjb250ZW50LgorICAgICAqIFRoZSBnaXZlbiBEYXRhSGFuZGxlciBvYmplY3Qgc2hvdWxkIHdyYXAgdGhlIGFjdHVhbCBjb250ZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSAgIGRoICAgICAgVGhlIERhdGFIYW5kbGVyIGZvciB0aGUgY29udGVudAorICAgICAqIEBleGNlcHRpb24gICAgICAgSWxsZWdhbFdyaXRlRXhjZXB0aW9uIGlmIHRoZSB1bmRlcmx5aW5nCisgICAgICogCQkJaW1wbGVtZW50YXRpb24gZG9lcyBub3Qgc3VwcG9ydCBtb2RpZmljYXRpb24KKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIGJvZHkgcGFydCBpcworICAgICAqCQkJb2J0YWluZWQgZnJvbSBhIFJFQURfT05MWSBmb2xkZXIuCisgICAgICovICAgICAgICAgICAgICAgICAKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXREYXRhSGFuZGxlcihEYXRhSGFuZGxlciBkaCkgCisJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXRoaXMuZGggPSBkaDsKKwljYWNoZWRDb250ZW50ID0gbnVsbDsKKwlNaW1lQm9keVBhcnQuaW52YWxpZGF0ZUNvbnRlbnRIZWFkZXJzKHRoaXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEEgY29udmVuaWVuY2UgbWV0aG9kIGZvciBzZXR0aW5nIHRoaXMgYm9keSBwYXJ0J3MgY29udGVudC4gPHA+CisgICAgICoKKyAgICAgKiBUaGUgY29udGVudCBpcyB3cmFwcGVkIGluIGEgRGF0YUhhbmRsZXIgb2JqZWN0LiBOb3RlIHRoYXQgYQorICAgICAqIERhdGFDb250ZW50SGFuZGxlciBjbGFzcyBmb3IgdGhlIHNwZWNpZmllZCB0eXBlIHNob3VsZCBiZQorICAgICAqIGF2YWlsYWJsZSB0byB0aGUgSmF2YU1haWwgaW1wbGVtZW50YXRpb24gZm9yIHRoaXMgdG8gd29yayByaWdodC4KKyAgICAgKiBUaGF0IGlzLCB0byBkbyA8Y29kZT5zZXRDb250ZW50KGZvb2JhciwgImFwcGxpY2F0aW9uL3gtZm9vYmFyIik8L2NvZGU+LAorICAgICAqIGEgRGF0YUNvbnRlbnRIYW5kbGVyIGZvciAiYXBwbGljYXRpb24veC1mb29iYXIiIHNob3VsZCBiZSBpbnN0YWxsZWQuCisgICAgICogUmVmZXIgdG8gdGhlIEphdmEgQWN0aXZhdGlvbiBGcmFtZXdvcmsgZm9yIG1vcmUgaW5mb3JtYXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0Jbwl0aGUgY29udGVudCBvYmplY3QKKyAgICAgKiBAcGFyYW0JdHlwZQlNaW1lIHR5cGUgb2YgdGhlIG9iamVjdAorICAgICAqIEBleGNlcHRpb24gICAgICAgSWxsZWdhbFdyaXRlRXhjZXB0aW9uIGlmIHRoZSB1bmRlcmx5aW5nCisgICAgICoJCQlpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IG1vZGlmaWNhdGlvbiBvZgorICAgICAqCQkJZXhpc3RpbmcgdmFsdWVzCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBib2R5IHBhcnQgaXMKKyAgICAgKgkJCW9idGFpbmVkIGZyb20gYSBSRUFEX09OTFkgZm9sZGVyLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldENvbnRlbnQoT2JqZWN0IG8sIFN0cmluZyB0eXBlKSAKKwkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKG8gaW5zdGFuY2VvZiBNdWx0aXBhcnQpIHsKKwkgICAgc2V0Q29udGVudCgoTXVsdGlwYXJ0KW8pOworCX0gZWxzZSB7CisJICAgIHNldERhdGFIYW5kbGVyKG5ldyBEYXRhSGFuZGxlcihvLCB0eXBlKSk7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlbmllbmNlIG1ldGhvZCB0aGF0IHNldHMgdGhlIGdpdmVuIFN0cmluZyBhcyB0aGlzCisgICAgICogcGFydCdzIGNvbnRlbnQsIHdpdGggYSBNSU1FIHR5cGUgb2YgInRleHQvcGxhaW4iLiBJZiB0aGUKKyAgICAgKiBzdHJpbmcgY29udGFpbnMgbm9uIFVTLUFTQ0lJIGNoYXJhY3RlcnMsIGl0IHdpbGwgYmUgZW5jb2RlZAorICAgICAqIHVzaW5nIHRoZSBwbGF0Zm9ybSdzIGRlZmF1bHQgY2hhcnNldC4gVGhlIGNoYXJzZXQgaXMgYWxzbworICAgICAqIHVzZWQgdG8gc2V0IHRoZSAiY2hhcnNldCIgcGFyYW1ldGVyLiA8cD4KKyAgICAgKgorICAgICAqIE5vdGUgdGhhdCB0aGVyZSBtYXkgYmUgYSBwZXJmb3JtYW5jZSBwZW5hbHR5IGlmCisgICAgICogPGNvZGU+dGV4dDwvY29kZT4gaXMgbGFyZ2UsIHNpbmNlIHRoaXMgbWV0aG9kIG1heSBoYXZlCisgICAgICogdG8gc2NhbiBhbGwgdGhlIGNoYXJhY3RlcnMgdG8gZGV0ZXJtaW5lIHdoYXQgY2hhcnNldCB0bworICAgICAqIHVzZS4gPHA+CisgICAgICoKKyAgICAgKiBJZiB0aGUgY2hhcnNldCBpcyBhbHJlYWR5IGtub3duLCB1c2UgdGhlCisgICAgICogPGNvZGU+c2V0VGV4dDwvY29kZT4gbWV0aG9kIHRoYXQgdGFrZXMgdGhlIGNoYXJzZXQgcGFyYW1ldGVyLgorICAgICAqCisgICAgICogQHBhcmFtCXRleHQJdGhlIHRleHQgY29udGVudCB0byBzZXQKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbglpZiBhbiBlcnJvciBvY2N1cnMKKyAgICAgKiBAc2VlCSNzZXRUZXh0KFN0cmluZyB0ZXh0LCBTdHJpbmcgY2hhcnNldCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRUZXh0KFN0cmluZyB0ZXh0KSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlzZXRUZXh0KHRleHQsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlbmllbmNlIG1ldGhvZCB0aGF0IHNldHMgdGhlIGdpdmVuIFN0cmluZyBhcyB0aGlzIHBhcnQncworICAgICAqIGNvbnRlbnQsIHdpdGggYSBNSU1FIHR5cGUgb2YgInRleHQvcGxhaW4iIGFuZCB0aGUgc3BlY2lmaWVkCisgICAgICogY2hhcnNldC4gVGhlIGdpdmVuIFVuaWNvZGUgc3RyaW5nIHdpbGwgYmUgY2hhcnNldC1lbmNvZGVkCisgICAgICogdXNpbmcgdGhlIHNwZWNpZmllZCBjaGFyc2V0LiBUaGUgY2hhcnNldCBpcyBhbHNvIHVzZWQgdG8gc2V0CisgICAgICogdGhlICJjaGFyc2V0IiBwYXJhbWV0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0JdGV4dAl0aGUgdGV4dCBjb250ZW50IHRvIHNldAorICAgICAqIEBwYXJhbQljaGFyc2V0CXRoZSBjaGFyc2V0IHRvIHVzZSBmb3IgdGhlIHRleHQKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbglpZiBhbiBlcnJvciBvY2N1cnMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRUZXh0KFN0cmluZyB0ZXh0LCBTdHJpbmcgY2hhcnNldCkKKwkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXNldFRleHQodGhpcywgdGV4dCwgY2hhcnNldCwgInBsYWluIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVuaWVuY2UgbWV0aG9kIHRoYXQgc2V0cyB0aGUgZ2l2ZW4gU3RyaW5nIGFzIHRoaXMgcGFydCdzCisgICAgICogY29udGVudCwgd2l0aCBhIHByaW1hcnkgTUlNRSB0eXBlIG9mICJ0ZXh0IiBhbmQgdGhlIHNwZWNpZmllZAorICAgICAqIE1JTUUgc3VidHlwZS4gIFRoZSBnaXZlbiBVbmljb2RlIHN0cmluZyB3aWxsIGJlIGNoYXJzZXQtZW5jb2RlZAorICAgICAqIHVzaW5nIHRoZSBzcGVjaWZpZWQgY2hhcnNldC4gVGhlIGNoYXJzZXQgaXMgYWxzbyB1c2VkIHRvIHNldAorICAgICAqIHRoZSAiY2hhcnNldCIgcGFyYW1ldGVyLgorICAgICAqCisgICAgICogQHBhcmFtCXRleHQJdGhlIHRleHQgY29udGVudCB0byBzZXQKKyAgICAgKiBAcGFyYW0JY2hhcnNldAl0aGUgY2hhcnNldCB0byB1c2UgZm9yIHRoZSB0ZXh0CisgICAgICogQHBhcmFtCXN1YnR5cGUJdGhlIE1JTUUgc3VidHlwZSB0byB1c2UgKGUuZy4sICJodG1sIikKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbglpZiBhbiBlcnJvciBvY2N1cnMKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS40CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0VGV4dChTdHJpbmcgdGV4dCwgU3RyaW5nIGNoYXJzZXQsIFN0cmluZyBzdWJ0eXBlKQorICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJc2V0VGV4dCh0aGlzLCB0ZXh0LCBjaGFyc2V0LCBzdWJ0eXBlKTsKKyAgICB9CisgCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2Qgc2V0cyB0aGUgYm9keSBwYXJ0J3MgY29udGVudCB0byBhIE11bHRpcGFydCBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gIG1wICAgICAgCVRoZSBtdWx0aXBhcnQgb2JqZWN0IHRoYXQgaXMgdGhlIE1lc3NhZ2UncyBjb250ZW50CisgICAgICogQGV4Y2VwdGlvbiAgICAgICBJbGxlZ2FsV3JpdGVFeGNlcHRpb24gaWYgdGhlIHVuZGVybHlpbmcKKyAgICAgKgkJCWltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uIG9mCisgICAgICoJCQlleGlzdGluZyB2YWx1ZXMuCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBib2R5IHBhcnQgaXMKKyAgICAgKgkJCW9idGFpbmVkIGZyb20gYSBSRUFEX09OTFkgZm9sZGVyLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldENvbnRlbnQoTXVsdGlwYXJ0IG1wKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlzZXREYXRhSGFuZGxlcihuZXcgRGF0YUhhbmRsZXIobXAsIG1wLmdldENvbnRlbnRUeXBlKCkpKTsKKwltcC5zZXRQYXJlbnQodGhpcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVXNlIHRoZSBzcGVjaWZpZWQgZmlsZSB0byBwcm92aWRlIHRoZSBkYXRhIGZvciB0aGlzIHBhcnQuCisgICAgICogVGhlIHNpbXBsZSBmaWxlIG5hbWUgaXMgdXNlZCBhcyB0aGUgZmlsZSBuYW1lIGZvciB0aGlzCisgICAgICogcGFydCBhbmQgdGhlIGRhdGEgaW4gdGhlIGZpbGUgaXMgdXNlZCBhcyB0aGUgZGF0YSBmb3IgdGhpcworICAgICAqIHBhcnQuICBUaGUgZW5jb2Rpbmcgd2lsbCBiZSBjaG9zZW4gYXBwcm9wcmlhdGVseSBmb3IgdGhlCisgICAgICogZmlsZSBkYXRhLiAgVGhlIGRpc3Bvc2l0aW9uIG9mIHRoaXMgcGFydCBpcyBzZXQgdG8KKyAgICAgKiB7QGxpbmsgUGFydCNBVFRBQ0hNRU5UIFBhcnQuQVRUQUNITUVOVH0uCisgICAgICoKKyAgICAgKiBAcGFyYW0JCWZpbGUJCXRoZSBGaWxlIG9iamVjdCB0byBhdHRhY2gKKyAgICAgKiBAZXhjZXB0aW9uCUlPRXhjZXB0aW9uCWVycm9ycyByZWxhdGVkIHRvIGFjY2Vzc2luZyB0aGUgZmlsZQorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uCW1lc3NhZ2UgcmVsYXRlZCBlcnJvcnMKKyAgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuNAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGF0dGFjaEZpbGUoRmlsZSBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24sIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJRmlsZURhdGFTb3VyY2UgZmRzID0gbmV3IEZpbGVEYXRhU291cmNlKGZpbGUpOyAgIAkKKwl0aGlzLnNldERhdGFIYW5kbGVyKG5ldyBEYXRhSGFuZGxlcihmZHMpKTsKKwl0aGlzLnNldEZpbGVOYW1lKGZkcy5nZXROYW1lKCkpOworCXRoaXMuc2V0RGlzcG9zaXRpb24oQVRUQUNITUVOVCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVXNlIHRoZSBzcGVjaWZpZWQgZmlsZSB0byBwcm92aWRlIHRoZSBkYXRhIGZvciB0aGlzIHBhcnQuCisgICAgICogVGhlIHNpbXBsZSBmaWxlIG5hbWUgaXMgdXNlZCBhcyB0aGUgZmlsZSBuYW1lIGZvciB0aGlzCisgICAgICogcGFydCBhbmQgdGhlIGRhdGEgaW4gdGhlIGZpbGUgaXMgdXNlZCBhcyB0aGUgZGF0YSBmb3IgdGhpcworICAgICAqIHBhcnQuICBUaGUgZW5jb2Rpbmcgd2lsbCBiZSBjaG9zZW4gYXBwcm9wcmlhdGVseSBmb3IgdGhlCisgICAgICogZmlsZSBkYXRhLgorICAgICAqCisgICAgICogQHBhcmFtCQlmaWxlCQl0aGUgbmFtZSBvZiB0aGUgZmlsZSB0byBhdHRhY2gKKyAgICAgKiBAZXhjZXB0aW9uCUlPRXhjZXB0aW9uCWVycm9ycyByZWxhdGVkIHRvIGFjY2Vzc2luZyB0aGUgZmlsZQorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uCW1lc3NhZ2UgcmVsYXRlZCBlcnJvcnMKKyAgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuNAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGF0dGFjaEZpbGUoU3RyaW5nIGZpbGUpIHRocm93cyBJT0V4Y2VwdGlvbiwgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKyAgICAJRmlsZSBmID0gbmV3IEZpbGUoZmlsZSk7CisgICAgCWF0dGFjaEZpbGUoZik7CisgICAgfQorCisgICAgLyoqCisgICAgICogVXNlIHRoZSBzcGVjaWZpZWQgZmlsZSB3aXRoIHRoZSBzcGVjaWZpZWQgQ29udGVudC1UeXBlIGFuZAorICAgICAqIENvbnRlbnQtVHJhbnNmZXItRW5jb2RpbmcgdG8gcHJvdmlkZSB0aGUgZGF0YSBmb3IgdGhpcyBwYXJ0LgorICAgICAqIElmIGNvbnRlbnRUeXBlIG9yIGVuY29kaW5nIGFyZSBudWxsLCBhcHByb3ByaWF0ZSB2YWx1ZXMgd2lsbAorICAgICAqIGJlIGNob3Nlbi4KKyAgICAgKiBUaGUgc2ltcGxlIGZpbGUgbmFtZSBpcyB1c2VkIGFzIHRoZSBmaWxlIG5hbWUgZm9yIHRoaXMKKyAgICAgKiBwYXJ0IGFuZCB0aGUgZGF0YSBpbiB0aGUgZmlsZSBpcyB1c2VkIGFzIHRoZSBkYXRhIGZvciB0aGlzCisgICAgICogcGFydC4gIFRoZSBkaXNwb3NpdGlvbiBvZiB0aGlzIHBhcnQgaXMgc2V0IHRvCisgICAgICoge0BsaW5rIFBhcnQjQVRUQUNITUVOVCBQYXJ0LkFUVEFDSE1FTlR9LgorICAgICAqCisgICAgICogQHBhcmFtCQlmaWxlCQl0aGUgRmlsZSBvYmplY3QgdG8gYXR0YWNoCisgICAgICogQHBhcmFtCQljb250ZW50VHlwZQl0aGUgQ29udGVudC1UeXBlLCBvciBudWxsCisgICAgICogQHBhcmFtCQllbmNvZGluZwl0aGUgQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZywgb3IgbnVsbAorICAgICAqIEBleGNlcHRpb24JSU9FeGNlcHRpb24JZXJyb3JzIHJlbGF0ZWQgdG8gYWNjZXNzaW5nIHRoZSBmaWxlCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24JbWVzc2FnZSByZWxhdGVkIGVycm9ycworICAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS41CisgICAgICovCisgICAgcHVibGljIHZvaWQgYXR0YWNoRmlsZShGaWxlIGZpbGUsIFN0cmluZyBjb250ZW50VHlwZSwgU3RyaW5nIGVuY29kaW5nKQorCQkJCXRocm93cyBJT0V4Y2VwdGlvbiwgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlEYXRhU291cmNlIGZkcyA9IG5ldyBFbmNvZGVkRmlsZURhdGFTb3VyY2UoZmlsZSwgY29udGVudFR5cGUsIGVuY29kaW5nKTsKKwl0aGlzLnNldERhdGFIYW5kbGVyKG5ldyBEYXRhSGFuZGxlcihmZHMpKTsKKwl0aGlzLnNldEZpbGVOYW1lKGZkcy5nZXROYW1lKCkpOworCXRoaXMuc2V0RGlzcG9zaXRpb24oQVRUQUNITUVOVCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVXNlIHRoZSBzcGVjaWZpZWQgZmlsZSB3aXRoIHRoZSBzcGVjaWZpZWQgQ29udGVudC1UeXBlIGFuZAorICAgICAqIENvbnRlbnQtVHJhbnNmZXItRW5jb2RpbmcgdG8gcHJvdmlkZSB0aGUgZGF0YSBmb3IgdGhpcyBwYXJ0LgorICAgICAqIElmIGNvbnRlbnRUeXBlIG9yIGVuY29kaW5nIGFyZSBudWxsLCBhcHByb3ByaWF0ZSB2YWx1ZXMgd2lsbAorICAgICAqIGJlIGNob3Nlbi4KKyAgICAgKiBUaGUgc2ltcGxlIGZpbGUgbmFtZSBpcyB1c2VkIGFzIHRoZSBmaWxlIG5hbWUgZm9yIHRoaXMKKyAgICAgKiBwYXJ0IGFuZCB0aGUgZGF0YSBpbiB0aGUgZmlsZSBpcyB1c2VkIGFzIHRoZSBkYXRhIGZvciB0aGlzCisgICAgICogcGFydC4gIFRoZSBkaXNwb3NpdGlvbiBvZiB0aGlzIHBhcnQgaXMgc2V0IHRvCisgICAgICoge0BsaW5rIFBhcnQjQVRUQUNITUVOVCBQYXJ0LkFUVEFDSE1FTlR9LgorICAgICAqCisgICAgICogQHBhcmFtCQlmaWxlCQl0aGUgbmFtZSBvZiB0aGUgZmlsZQorICAgICAqIEBwYXJhbQkJY29udGVudFR5cGUJdGhlIENvbnRlbnQtVHlwZSwgb3IgbnVsbAorICAgICAqIEBwYXJhbQkJZW5jb2RpbmcJdGhlIENvbnRlbnQtVHJhbnNmZXItRW5jb2RpbmcsIG9yIG51bGwKKyAgICAgKiBAZXhjZXB0aW9uCUlPRXhjZXB0aW9uCWVycm9ycyByZWxhdGVkIHRvIGFjY2Vzc2luZyB0aGUgZmlsZQorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uCW1lc3NhZ2UgcmVsYXRlZCBlcnJvcnMKKyAgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuNQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGF0dGFjaEZpbGUoU3RyaW5nIGZpbGUsIFN0cmluZyBjb250ZW50VHlwZSwgU3RyaW5nIGVuY29kaW5nKQorCQkJCXRocm93cyBJT0V4Y2VwdGlvbiwgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlhdHRhY2hGaWxlKG5ldyBGaWxlKGZpbGUpLCBjb250ZW50VHlwZSwgZW5jb2RpbmcpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEEgRmlsZURhdGFTb3VyY2UgY2xhc3MgdGhhdCBhbGxvd3MgdXMgdG8gc3BlY2lmeSB0aGUKKyAgICAgKiBDb250ZW50LVR5cGUgYW5kIENvbnRlbnQtVHJhbnNmZXItRW5jb2RpbmcuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgRW5jb2RlZEZpbGVEYXRhU291cmNlIGV4dGVuZHMgRmlsZURhdGFTb3VyY2UKKwkJCQkJaW1wbGVtZW50cyBFbmNvZGluZ0F3YXJlIHsKKwlwcml2YXRlIFN0cmluZyBjb250ZW50VHlwZTsKKwlwcml2YXRlIFN0cmluZyBlbmNvZGluZzsKKworCXB1YmxpYyBFbmNvZGVkRmlsZURhdGFTb3VyY2UoRmlsZSBmaWxlLCBTdHJpbmcgY29udGVudFR5cGUsCisJCQkJCQlTdHJpbmcgZW5jb2RpbmcpIHsKKwkgICAgc3VwZXIoZmlsZSk7CisJICAgIHRoaXMuY29udGVudFR5cGUgPSBjb250ZW50VHlwZTsKKwkgICAgdGhpcy5lbmNvZGluZyA9IGVuY29kaW5nOworCX0KKworCS8vIG92ZXJyaWRlcyBEYXRhU291cmNlLmdldENvbnRlbnRUeXBlKCkKKwlAT3ZlcnJpZGUKKwlwdWJsaWMgU3RyaW5nIGdldENvbnRlbnRUeXBlKCkgeworCSAgICByZXR1cm4gY29udGVudFR5cGUgIT0gbnVsbCA/IGNvbnRlbnRUeXBlIDogc3VwZXIuZ2V0Q29udGVudFR5cGUoKTsKKwl9CisKKwkvLyBpbXBsZW1lbnRzIEVuY29kaW5nQXdhcmUuZ2V0RW5jb2RpbmcoKQorCUBPdmVycmlkZQorCXB1YmxpYyBTdHJpbmcgZ2V0RW5jb2RpbmcoKSB7CisJICAgIHJldHVybiBlbmNvZGluZzsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogU2F2ZSB0aGUgY29udGVudHMgb2YgdGhpcyBwYXJ0IGluIHRoZSBzcGVjaWZpZWQgZmlsZS4gIFRoZSBjb250ZW50CisgICAgICogaXMgZGVjb2RlZCBhbmQgc2F2ZWQsIHdpdGhvdXQgYW55IG9mIHRoZSBNSU1FIGhlYWRlcnMuCisgICAgICoKKyAgICAgKiBAcGFyYW0JCWZpbGUJCXRoZSBGaWxlIG9iamVjdCB0byB3cml0ZSB0bworICAgICAqIEBleGNlcHRpb24JSU9FeGNlcHRpb24JZXJyb3JzIHJlbGF0ZWQgdG8gYWNjZXNzaW5nIHRoZSBmaWxlCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24JbWVzc2FnZSByZWxhdGVkIGVycm9ycworICAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS40CisgICAgICovCisgICAgcHVibGljIHZvaWQgc2F2ZUZpbGUoRmlsZSBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24sIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisgICAgCU91dHB1dFN0cmVhbSBvdXQgPSBudWxsOworICAgICAgICBJbnB1dFN0cmVhbSBpbiA9IG51bGw7CisgICAgICAgIHRyeSB7CisJICAgIG91dCA9IG5ldyBCdWZmZXJlZE91dHB1dFN0cmVhbShuZXcgRmlsZU91dHB1dFN0cmVhbShmaWxlKSk7CisJICAgIGluID0gdGhpcy5nZXRJbnB1dFN0cmVhbSgpOworCSAgICBieXRlW10gYnVmID0gbmV3IGJ5dGVbODE5Ml07CisJICAgIGludCBsZW47CisJICAgIHdoaWxlICgobGVuID0gaW4ucmVhZChidWYpKSA+IDApCisJCW91dC53cml0ZShidWYsIDAsIGxlbik7IAorICAgICAgICB9IGZpbmFsbHkgeworCSAgICAvLyBjbG9zZSBzdHJlYW1zLCBidXQgZG9uJ3QgbWFzayBvcmlnaW5hbCBleGNlcHRpb24sIGlmIGFueQorCSAgICB0cnkgeworCQlpZiAoaW4gIT0gbnVsbCkKKwkJICAgIGluLmNsb3NlKCk7CisJICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7IH0KKwkgICAgdHJ5IHsKKwkJaWYgKG91dCAhPSBudWxsKQorCQkgICAgb3V0LmNsb3NlKCk7CisJICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7IH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNhdmUgdGhlIGNvbnRlbnRzIG9mIHRoaXMgcGFydCBpbiB0aGUgc3BlY2lmaWVkIGZpbGUuICBUaGUgY29udGVudAorICAgICAqIGlzIGRlY29kZWQgYW5kIHNhdmVkLCB3aXRob3V0IGFueSBvZiB0aGUgTUlNRSBoZWFkZXJzLgorICAgICAqCisgICAgICogQHBhcmFtCQlmaWxlCQl0aGUgbmFtZSBvZiB0aGUgZmlsZSB0byB3cml0ZSB0bworICAgICAqIEBleGNlcHRpb24JSU9FeGNlcHRpb24JZXJyb3JzIHJlbGF0ZWQgdG8gYWNjZXNzaW5nIHRoZSBmaWxlCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24JbWVzc2FnZSByZWxhdGVkIGVycm9ycworICAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS40CisgICAgICovCisgICAgcHVibGljIHZvaWQgc2F2ZUZpbGUoU3RyaW5nIGZpbGUpIHRocm93cyBJT0V4Y2VwdGlvbiwgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKyAgICAJRmlsZSBmID0gbmV3IEZpbGUoZmlsZSk7CisgICAgCXNhdmVGaWxlKGYpOworICAgIH0KKworICAgIC8qKgorICAgICAqIE91dHB1dCB0aGUgYm9keSBwYXJ0IGFzIGFuIFJGQyA4MjIgZm9ybWF0IHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24gSU9FeGNlcHRpb24JaWYgYW4gZXJyb3Igb2NjdXJzIHdyaXRpbmcgdG8gdGhlCisgICAgICoJCQkJc3RyZWFtIG9yIGlmIGFuIGVycm9yIGlzIGdlbmVyYXRlZAorICAgICAqCQkJCWJ5IHRoZSBqYXZheC5hY3RpdmF0aW9uIGxheWVyLgorICAgICAqIEBleGNlcHRpb24gTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBvdGhlciBmYWlsdXJlcworICAgICAqIEBzZWUgamF2YXguYWN0aXZhdGlvbi5EYXRhSGFuZGxlciN3cml0ZVRvCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGVUbyhPdXRwdXRTdHJlYW0gb3MpCisJCQkJdGhyb3dzIElPRXhjZXB0aW9uLCBNZXNzYWdpbmdFeGNlcHRpb24geworCXdyaXRlVG8odGhpcywgb3MsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCBhbGwgdGhlIGhlYWRlcnMgZm9yIHRoaXMgaGVhZGVyX25hbWUuIE5vdGUgdGhhdCBjZXJ0YWluCisgICAgICogaGVhZGVycyBtYXkgYmUgZW5jb2RlZCBhcyBwZXIgUkZDIDIwNDcgaWYgdGhleSBjb250YWluCisgICAgICogbm9uIFVTLUFTQ0lJIGNoYXJhY3RlcnMgYW5kIHRoZXNlIHNob3VsZCBiZSBkZWNvZGVkLgorICAgICAqCisgICAgICogQHBhcmFtICAgbmFtZSAgICBuYW1lIG9mIGhlYWRlcgorICAgICAqIEByZXR1cm4gIGFycmF5IG9mIGhlYWRlcnMKKyAgICAgKiBAc2VlICAgICBqYXZheC5tYWlsLmludGVybmV0Lk1pbWVVdGlsaXR5CisgICAgICovICAKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nW10gZ2V0SGVhZGVyKFN0cmluZyBuYW1lKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gaGVhZGVycy5nZXRIZWFkZXIobmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IGFsbCB0aGUgaGVhZGVycyBmb3IgdGhpcyBoZWFkZXIgbmFtZSwgcmV0dXJuZWQgYXMgYSBzaW5nbGUKKyAgICAgKiBTdHJpbmcsIHdpdGggaGVhZGVycyBzZXBhcmF0ZWQgYnkgdGhlIGRlbGltaXRlci4gSWYgdGhlCisgICAgICogZGVsaW1pdGVyIGlzIDxjb2RlPm51bGw8L2NvZGU+LCBvbmx5IHRoZSBmaXJzdCBoZWFkZXIgaXMgCisgICAgICogcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQkJdGhlIG5hbWUgb2YgdGhpcyBoZWFkZXIKKyAgICAgKiBAcGFyYW0gZGVsaW1pdGVyCQlkZWxpbWl0ZXIgYmV0d2VlbiBmaWVsZHMgaW4gcmV0dXJuZWQgc3RyaW5nCisgICAgICogQHJldHVybgkJCXRoZSB2YWx1ZSBmaWVsZHMgZm9yIGFsbCBoZWFkZXJzIHdpdGggCisgICAgICoJCQkJdGhpcyBuYW1lCisgICAgICogQGV4Y2VwdGlvbiAgICAgICAJTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0SGVhZGVyKFN0cmluZyBuYW1lLCBTdHJpbmcgZGVsaW1pdGVyKQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXJldHVybiBoZWFkZXJzLmdldEhlYWRlcihuYW1lLCBkZWxpbWl0ZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgdmFsdWUgZm9yIHRoaXMgaGVhZGVyX25hbWUuIFJlcGxhY2VzIGFsbCBleGlzdGluZworICAgICAqIGhlYWRlciB2YWx1ZXMgd2l0aCB0aGlzIG5ldyB2YWx1ZS4gTm90ZSB0aGF0IFJGQyA4MjIgaGVhZGVycworICAgICAqIG11c3QgY29udGFpbiBvbmx5IFVTLUFTQ0lJIGNoYXJhY3RlcnMsIHNvIGEgaGVhZGVyIHRoYXQKKyAgICAgKiBjb250YWlucyBub24gVVMtQVNDSUkgY2hhcmFjdGVycyBtdXN0IGJlIGVuY29kZWQgYXMgcGVyIHRoZQorICAgICAqIHJ1bGVzIG9mIFJGQyAyMDQ3LgorICAgICAqCisgICAgICogQHBhcmFtICAgbmFtZSAgICBoZWFkZXIgbmFtZQorICAgICAqIEBwYXJhbSAgIHZhbHVlICAgaGVhZGVyIHZhbHVlCisgICAgICogQHNlZSAgICAgamF2YXgubWFpbC5pbnRlcm5ldC5NaW1lVXRpbGl0eQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldEhlYWRlcihTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwloZWFkZXJzLnNldEhlYWRlcihuYW1lLCB2YWx1ZSk7CisgICAgfQorIAorICAgIC8qKgorICAgICAqIEFkZCB0aGlzIHZhbHVlIHRvIHRoZSBleGlzdGluZyB2YWx1ZXMgZm9yIHRoaXMgaGVhZGVyX25hbWUuCisgICAgICogTm90ZSB0aGF0IFJGQyA4MjIgaGVhZGVycyBtdXN0IGNvbnRhaW4gb25seSBVUy1BU0NJSQorICAgICAqIGNoYXJhY3RlcnMsIHNvIGEgaGVhZGVyIHRoYXQgY29udGFpbnMgbm9uIFVTLUFTQ0lJIGNoYXJhY3RlcnMKKyAgICAgKiBtdXN0IGJlIGVuY29kZWQgYXMgcGVyIHRoZSBydWxlcyBvZiBSRkMgMjA0Ny4KKyAgICAgKgorICAgICAqIEBwYXJhbSAgIG5hbWUgICAgaGVhZGVyIG5hbWUKKyAgICAgKiBAcGFyYW0gICB2YWx1ZSAgIGhlYWRlciB2YWx1ZQorICAgICAqIEBzZWUgICAgIGphdmF4Lm1haWwuaW50ZXJuZXQuTWltZVV0aWxpdHkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBhZGRIZWFkZXIoU3RyaW5nIG5hbWUsIFN0cmluZyB2YWx1ZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaGVhZGVycy5hZGRIZWFkZXIobmFtZSwgdmFsdWUpOyAgICAKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmUgYWxsIGhlYWRlcnMgd2l0aCB0aGlzIG5hbWUuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcmVtb3ZlSGVhZGVyKFN0cmluZyBuYW1lKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwloZWFkZXJzLnJlbW92ZUhlYWRlcihuYW1lKTsKKyAgICB9CisgCisgICAgLyoqCisgICAgICogUmV0dXJuIGFsbCB0aGUgaGVhZGVycyBmcm9tIHRoaXMgTWVzc2FnZSBhcyBhbiBFbnVtZXJhdGlvbiBvZgorICAgICAqIEhlYWRlciBvYmplY3RzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBFbnVtZXJhdGlvbjxIZWFkZXI+IGdldEFsbEhlYWRlcnMoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gaGVhZGVycy5nZXRBbGxIZWFkZXJzKCk7CisgICAgfQorICAgCisgICAgLyoqCisgICAgICogUmV0dXJuIG1hdGNoaW5nIGhlYWRlcnMgZnJvbSB0aGlzIE1lc3NhZ2UgYXMgYW4gRW51bWVyYXRpb24gb2YKKyAgICAgKiBIZWFkZXIgb2JqZWN0cy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRW51bWVyYXRpb248SGVhZGVyPiBnZXRNYXRjaGluZ0hlYWRlcnMoU3RyaW5nW10gbmFtZXMpCisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gaGVhZGVycy5nZXRNYXRjaGluZ0hlYWRlcnMobmFtZXMpOworICAgIH0KKyAKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gbm9uLW1hdGNoaW5nIGhlYWRlcnMgZnJvbSB0aGlzIE1lc3NhZ2UgYXMgYW4KKyAgICAgKiBFbnVtZXJhdGlvbiBvZiBIZWFkZXIgb2JqZWN0cy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRW51bWVyYXRpb248SGVhZGVyPiBnZXROb25NYXRjaGluZ0hlYWRlcnMoU3RyaW5nW10gbmFtZXMpCisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gaGVhZGVycy5nZXROb25NYXRjaGluZ0hlYWRlcnMobmFtZXMpOworICAgIH0KKyAgICAgIAorICAgIC8qKgorICAgICAqIEFkZCBhIGhlYWRlciBsaW5lIHRvIHRoaXMgYm9keSBwYXJ0CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgYWRkSGVhZGVyTGluZShTdHJpbmcgbGluZSkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaGVhZGVycy5hZGRIZWFkZXJMaW5lKGxpbmUpOworICAgIH0KKyAgICAgCisgICAgLyoqCisgICAgICogR2V0IGFsbCBoZWFkZXIgbGluZXMgYXMgYW4gRW51bWVyYXRpb24gb2YgU3RyaW5ncy4gQSBIZWFkZXIKKyAgICAgKiBsaW5lIGlzIGEgcmF3IFJGQyA4MjIgaGVhZGVyIGxpbmUsIGNvbnRhaW5pbmcgYm90aCB0aGUgIm5hbWUiCisgICAgICogYW5kICJ2YWx1ZSIgZmllbGQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEVudW1lcmF0aW9uPFN0cmluZz4gZ2V0QWxsSGVhZGVyTGluZXMoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKyAgCXJldHVybiBoZWFkZXJzLmdldEFsbEhlYWRlckxpbmVzKCk7IAorICAgIH0KKyAKKyAgICAvKioKKyAgICAgKiBHZXQgbWF0Y2hpbmcgaGVhZGVyIGxpbmVzIGFzIGFuIEVudW1lcmF0aW9uIG9mIFN0cmluZ3MuCisgICAgICogQSBIZWFkZXIgbGluZSBpcyBhIHJhdyBSRkMgODIyIGhlYWRlciBsaW5lLCBjb250YWluaW5nIGJvdGgKKyAgICAgKiB0aGUgIm5hbWUiIGFuZCAidmFsdWUiIGZpZWxkLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBFbnVtZXJhdGlvbjxTdHJpbmc+IGdldE1hdGNoaW5nSGVhZGVyTGluZXMoU3RyaW5nW10gbmFtZXMpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gaGVhZGVycy5nZXRNYXRjaGluZ0hlYWRlckxpbmVzKG5hbWVzKTsKKyAgICB9CisgCisgICAgLyoqCisgICAgICogR2V0IG5vbi1tYXRjaGluZyBoZWFkZXIgbGluZXMgYXMgYW4gRW51bWVyYXRpb24gb2YgU3RyaW5ncy4KKyAgICAgKiBBIEhlYWRlciBsaW5lIGlzIGEgcmF3IFJGQyA4MjIgaGVhZGVyIGxpbmUsIGNvbnRhaW5pbmcgYm90aAorICAgICAqIHRoZSAibmFtZSIgIGFuZCAidmFsdWUiIGZpZWxkLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBFbnVtZXJhdGlvbjxTdHJpbmc+IGdldE5vbk1hdGNoaW5nSGVhZGVyTGluZXMoU3RyaW5nW10gbmFtZXMpICAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gaGVhZGVycy5nZXROb25NYXRjaGluZ0hlYWRlckxpbmVzKG5hbWVzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFeGFtaW5lIHRoZSBjb250ZW50IG9mIHRoaXMgYm9keSBwYXJ0IGFuZCB1cGRhdGUgdGhlIGFwcHJvcHJpYXRlCisgICAgICogTUlNRSBoZWFkZXJzLiAgVHlwaWNhbCBoZWFkZXJzIHRoYXQgZ2V0IHNldCBoZXJlIGFyZQorICAgICAqIDxjb2RlPkNvbnRlbnQtVHlwZTwvY29kZT4gYW5kIDxjb2RlPkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc8L2NvZGU+LgorICAgICAqIEhlYWRlcnMgbWlnaHQgbmVlZCB0byBiZSB1cGRhdGVkIGluIHR3byBjYXNlczoKKyAgICAgKgorICAgICAqIDxicj4KKyAgICAgKiAtIEEgbWVzc2FnZSBiZWluZyBjcmFmdGVkIGJ5IGEgbWFpbCBhcHBsaWNhdGlvbiB3aWxsIGNlcnRhaW5seQorICAgICAqIG5lZWQgdG8gYWN0aXZhdGUgdGhpcyBtZXRob2QgYXQgc29tZSBwb2ludCB0byBmaWxsIHVwIGl0cyBpbnRlcm5hbAorICAgICAqIGhlYWRlcnMuCisgICAgICoKKyAgICAgKiA8YnI+CisgICAgICogLSBBIG1lc3NhZ2UgcmVhZCBpbiBmcm9tIGEgU3RvcmUgd2lsbCBoYXZlIG9idGFpbmVkCisgICAgICogYWxsIGl0cyBoZWFkZXJzIGZyb20gdGhlIHN0b3JlLCBhbmQgc28gZG9lc24ndCBuZWVkIHRoaXMuCisgICAgICogSG93ZXZlciwgaWYgdGhpcyBtZXNzYWdlIGlzIGVkaXRhYmxlIGFuZCBpZiBhbnkgZWRpdHMgaGF2ZQorICAgICAqIGJlZW4gbWFkZSB0byBlaXRoZXIgdGhlIGNvbnRlbnQgb3IgbWVzc2FnZSBzdHJ1Y3R1cmUsIHdlIG1pZ2h0CisgICAgICogbmVlZCB0byByZXN5bmMgb3VyIGhlYWRlcnMuCisgICAgICoKKyAgICAgKiA8YnI+CisgICAgICogSW4gYm90aCBjYXNlcyB0aGlzIG1ldGhvZCBpcyB0eXBpY2FsbHkgY2FsbGVkIGJ5IHRoZQorICAgICAqIDxjb2RlPk1lc3NhZ2Uuc2F2ZUNoYW5nZXM8L2NvZGU+IG1ldGhvZC4gPHA+CisgICAgICoKKyAgICAgKiBJZiB0aGUge0BsaW5rICNjYWNoZWRDb250ZW50fSBmaWVsZCBpcyBub3QgbnVsbCAodGhhdCBpcywKKyAgICAgKiBpdCByZWZlcmVuY2VzIGEgTXVsdGlwYXJ0IG9yIE1lc3NhZ2Ugb2JqZWN0KSwgdGhlbgorICAgICAqIHRoYXQgb2JqZWN0IGlzIHVzZWQgdG8gc2V0IGEgbmV3IERhdGFIYW5kbGVyLCBhbnkKKyAgICAgKiBzdHJlYW0gZGF0YSB1c2VkIHRvIGNyZWF0ZSB0aGlzIG9iamVjdCBpcyBkaXNjYXJkZWQsCisgICAgICogYW5kIHRoZSB7QGxpbmsgI2NhY2hlZENvbnRlbnR9IGZpZWxkIGlzIGNsZWFyZWQuCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCB1cGRhdGVIZWFkZXJzKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJdXBkYXRlSGVhZGVycyh0aGlzKTsKKwkvKgorCSAqIElmIHdlJ3ZlIGNhY2hlZCBhIE11bHRpcGFydCBvciBNZXNzYWdlIG9iamVjdCB0aGVuCisJICogd2UncmUgbm93IGNvbW1pdHRlZCB0byB1c2luZyB0aGlzIGluc3RhbmNlIG9mIHRoZQorCSAqIG9iamVjdCBhbmQgd2UgZGlzY2FyZCBhbnkgc3RyZWFtIGRhdGEgdXNlZCB0byBjcmVhdGUKKwkgKiB0aGlzIG9iamVjdC4KKwkgKi8KKwlpZiAoY2FjaGVkQ29udGVudCAhPSBudWxsKSB7CisJICAgIGRoID0gbmV3IERhdGFIYW5kbGVyKGNhY2hlZENvbnRlbnQsIGdldENvbnRlbnRUeXBlKCkpOworCSAgICBjYWNoZWRDb250ZW50ID0gbnVsbDsKKwkgICAgY29udGVudCA9IG51bGw7CisJICAgIGlmIChjb250ZW50U3RyZWFtICE9IG51bGwpIHsKKwkJdHJ5IHsKKwkJICAgIGNvbnRlbnRTdHJlYW0uY2xvc2UoKTsKKwkJfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9leCkgeyB9CS8vIG5vdGhpbmcgdG8gZG8KKwkgICAgfQorCSAgICBjb250ZW50U3RyZWFtID0gbnVsbDsKKwl9CisgICAgfQorCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworICAgIC8vIFBhY2thZ2UgcHJpdmF0ZSBjb252ZW5pZW5jZSBtZXRob2RzIHRvIHNoYXJlIGNvZGUgYW1vbmcgLy8KKyAgICAvLyBNaW1lTWVzc2FnZSBhbmQgTWltZUJvZHlQYXJ0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vCisgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCisgICAgc3RhdGljIGJvb2xlYW4gaXNNaW1lVHlwZShNaW1lUGFydCBwYXJ0LCBTdHJpbmcgbWltZVR5cGUpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJLy8gWFhYIC0gbG90cyBvZiByb29tIGZvciBvcHRpbWl6YXRpb24gaGVyZSEKKwlTdHJpbmcgdHlwZSA9IHBhcnQuZ2V0Q29udGVudFR5cGUoKTsKKwl0cnkgeworCSAgICByZXR1cm4gbmV3IENvbnRlbnRUeXBlKHR5cGUpLm1hdGNoKG1pbWVUeXBlKTsKKwl9IGNhdGNoIChQYXJzZUV4Y2VwdGlvbiBleCkgeworCSAgICAvLyB3ZSBvbmx5IG5lZWQgdGhlIHR5cGUgYW5kIHN1YnR5cGUgc28gdGhyb3cgYXdheSB0aGUgcmVzdAorCSAgICB0cnkgeworCQlpbnQgaSA9IHR5cGUuaW5kZXhPZignOycpOworCQlpZiAoaSA+IDApCisJCSAgICByZXR1cm4gbmV3IENvbnRlbnRUeXBlKHR5cGUuc3Vic3RyaW5nKDAsIGkpKS5tYXRjaChtaW1lVHlwZSk7CisJICAgIH0gY2F0Y2ggKFBhcnNlRXhjZXB0aW9uIHBleDIpIHsKKwkgICAgfQorCSAgICByZXR1cm4gdHlwZS5lcXVhbHNJZ25vcmVDYXNlKG1pbWVUeXBlKTsKKwl9CisgICAgfQorCisgICAgc3RhdGljIHZvaWQgc2V0VGV4dChNaW1lUGFydCBwYXJ0LCBTdHJpbmcgdGV4dCwgU3RyaW5nIGNoYXJzZXQsCisJCQlTdHJpbmcgc3VidHlwZSkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKGNoYXJzZXQgPT0gbnVsbCkgeworCSAgICBpZiAoTWltZVV0aWxpdHkuY2hlY2tBc2NpaSh0ZXh0KSAhPSBNaW1lVXRpbGl0eS5BTExfQVNDSUkpCisJCWNoYXJzZXQgPSBNaW1lVXRpbGl0eS5nZXREZWZhdWx0TUlNRUNoYXJzZXQoKTsKKwkgICAgZWxzZQorCQljaGFyc2V0ID0gInVzLWFzY2lpIjsKKwl9CisJLy8gWFhYIC0gc2hvdWxkIGF0IGxlYXN0IGVuc3VyZSB0aGF0IHN1YnR5cGUgaXMgYW4gYXRvbQorCXBhcnQuc2V0Q29udGVudCh0ZXh0LCAidGV4dC8iICsgc3VidHlwZSArICI7IGNoYXJzZXQ9IiArCisJCQlNaW1lVXRpbGl0eS5xdW90ZShjaGFyc2V0LCBIZWFkZXJUb2tlbml6ZXIuTUlNRSkpOworICAgIH0KKworICAgIHN0YXRpYyBTdHJpbmcgZ2V0RGlzcG9zaXRpb24oTWltZVBhcnQgcGFydCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJU3RyaW5nIHMgPSBwYXJ0LmdldEhlYWRlcigiQ29udGVudC1EaXNwb3NpdGlvbiIsIG51bGwpOworCisJaWYgKHMgPT0gbnVsbCkKKwkgICAgcmV0dXJuIG51bGw7CisKKwlDb250ZW50RGlzcG9zaXRpb24gY2QgPSBuZXcgQ29udGVudERpc3Bvc2l0aW9uKHMpOworCXJldHVybiBjZC5nZXREaXNwb3NpdGlvbigpOworICAgIH0KKworICAgIHN0YXRpYyB2b2lkIHNldERpc3Bvc2l0aW9uKE1pbWVQYXJ0IHBhcnQsIFN0cmluZyBkaXNwb3NpdGlvbikKKwkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWlmIChkaXNwb3NpdGlvbiA9PSBudWxsKQorCSAgICBwYXJ0LnJlbW92ZUhlYWRlcigiQ29udGVudC1EaXNwb3NpdGlvbiIpOworCWVsc2UgeworCSAgICBTdHJpbmcgcyA9IHBhcnQuZ2V0SGVhZGVyKCJDb250ZW50LURpc3Bvc2l0aW9uIiwgbnVsbCk7CisJICAgIGlmIChzICE9IG51bGwpIHsgCisJCS8qIEEgQ29udGVudC1EaXNwb3NpdGlvbiBoZWFkZXIgYWxyZWFkeSBleGlzdHMgLi4KKwkJICoKKwkJICogT3ZlcnJpZGUgZGlzcG9zaXRpb24sIGJ1dCBhdHRlbXB0IHRvIHJldGFpbiAKKwkJICogZXhpc3RpbmcgZGlzcG9zaXRpb24gcGFyYW1ldGVycworCQkgKi8KKwkJQ29udGVudERpc3Bvc2l0aW9uIGNkID0gbmV3IENvbnRlbnREaXNwb3NpdGlvbihzKTsKKwkJY2Quc2V0RGlzcG9zaXRpb24oZGlzcG9zaXRpb24pOworCQlkaXNwb3NpdGlvbiA9IGNkLnRvU3RyaW5nKCk7CisJICAgIH0KKwkgICAgcGFydC5zZXRIZWFkZXIoIkNvbnRlbnQtRGlzcG9zaXRpb24iLCBkaXNwb3NpdGlvbik7CisJfQorICAgIH0KKworICAgIHN0YXRpYyBTdHJpbmcgZ2V0RGVzY3JpcHRpb24oTWltZVBhcnQgcGFydCkgCisJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlTdHJpbmcgcmF3dmFsdWUgPSBwYXJ0LmdldEhlYWRlcigiQ29udGVudC1EZXNjcmlwdGlvbiIsIG51bGwpOworCisJaWYgKHJhd3ZhbHVlID09IG51bGwpCisJICAgIHJldHVybiBudWxsOworCisJdHJ5IHsKKwkgICAgcmV0dXJuIE1pbWVVdGlsaXR5LmRlY29kZVRleHQoTWltZVV0aWxpdHkudW5mb2xkKHJhd3ZhbHVlKSk7CisJfSBjYXRjaCAoVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBleCkgeworCSAgICByZXR1cm4gcmF3dmFsdWU7CisJfQorICAgIH0KKworICAgIHN0YXRpYyB2b2lkIAorICAgIHNldERlc2NyaXB0aW9uKE1pbWVQYXJ0IHBhcnQsIFN0cmluZyBkZXNjcmlwdGlvbiwgU3RyaW5nIGNoYXJzZXQpIAorCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKGRlc2NyaXB0aW9uID09IG51bGwpIHsKKwkgICAgcGFydC5yZW1vdmVIZWFkZXIoIkNvbnRlbnQtRGVzY3JpcHRpb24iKTsKKwkgICAgcmV0dXJuOworCX0KKwkKKwl0cnkgeworCSAgICBwYXJ0LnNldEhlYWRlcigiQ29udGVudC1EZXNjcmlwdGlvbiIsIE1pbWVVdGlsaXR5LmZvbGQoMjEsCisJCU1pbWVVdGlsaXR5LmVuY29kZVRleHQoZGVzY3JpcHRpb24sIGNoYXJzZXQsIG51bGwpKSk7CisJfSBjYXRjaCAoVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiB1ZXgpIHsKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiRW5jb2RpbmcgZXJyb3IiLCB1ZXgpOworCX0KKyAgICB9CisKKyAgICBzdGF0aWMgU3RyaW5nIGdldEZpbGVOYW1lKE1pbWVQYXJ0IHBhcnQpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCVN0cmluZyBmaWxlbmFtZSA9IG51bGw7CisJU3RyaW5nIHMgPSBwYXJ0LmdldEhlYWRlcigiQ29udGVudC1EaXNwb3NpdGlvbiIsIG51bGwpOworCisJaWYgKHMgIT0gbnVsbCkgeworCSAgICAvLyBQYXJzZSB0aGUgaGVhZGVyIC4uCisJICAgIENvbnRlbnREaXNwb3NpdGlvbiBjZCA9IG5ldyBDb250ZW50RGlzcG9zaXRpb24ocyk7CisJICAgIGZpbGVuYW1lID0gY2QuZ2V0UGFyYW1ldGVyKCJmaWxlbmFtZSIpOworCX0KKwlpZiAoZmlsZW5hbWUgPT0gbnVsbCkgeworCSAgICAvLyBTdGlsbCBubyBmaWxlbmFtZSA/IFRyeSB0aGUgIm5hbWUiIENvbnRlbnRUeXBlIHBhcmFtZXRlcgorCSAgICBzID0gcGFydC5nZXRIZWFkZXIoIkNvbnRlbnQtVHlwZSIsIG51bGwpOworCSAgICBzID0gTWltZVV0aWwuY2xlYW5Db250ZW50VHlwZShwYXJ0LCBzKTsKKwkgICAgaWYgKHMgIT0gbnVsbCkgeworCQl0cnkgeworCQkgICAgQ29udGVudFR5cGUgY3QgPSBuZXcgQ29udGVudFR5cGUocyk7CisJCSAgICBmaWxlbmFtZSA9IGN0LmdldFBhcmFtZXRlcigibmFtZSIpOworCQl9IGNhdGNoIChQYXJzZUV4Y2VwdGlvbiBwZXgpIHsgfQkvLyBpZ25vcmUgaXQKKwkgICAgfQorCX0KKwlpZiAoZGVjb2RlRmlsZU5hbWUgJiYgZmlsZW5hbWUgIT0gbnVsbCkgeworCSAgICB0cnkgeworCQlmaWxlbmFtZSA9IE1pbWVVdGlsaXR5LmRlY29kZVRleHQoZmlsZW5hbWUpOworCSAgICB9IGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGV4KSB7CisJCXRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oIkNhbid0IGRlY29kZSBmaWxlbmFtZSIsIGV4KTsKKwkgICAgfQorCX0KKwlyZXR1cm4gZmlsZW5hbWU7CisgICAgfQorCisgICAgc3RhdGljIHZvaWQgc2V0RmlsZU5hbWUoTWltZVBhcnQgcGFydCwgU3RyaW5nIG5hbWUpIAorCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpZiAoZW5jb2RlRmlsZU5hbWUgJiYgbmFtZSAhPSBudWxsKSB7CisJICAgIHRyeSB7CisJCW5hbWUgPSBNaW1lVXRpbGl0eS5lbmNvZGVUZXh0KG5hbWUpOworCSAgICB9IGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGV4KSB7CisJCXRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oIkNhbid0IGVuY29kZSBmaWxlbmFtZSIsIGV4KTsKKwkgICAgfQorCX0KKworCS8vIFNldCB0aGUgQ29udGVudC1EaXNwb3NpdGlvbiAiZmlsZW5hbWUiIHBhcmFtZXRlcgorCVN0cmluZyBzID0gcGFydC5nZXRIZWFkZXIoIkNvbnRlbnQtRGlzcG9zaXRpb24iLCBudWxsKTsKKwlDb250ZW50RGlzcG9zaXRpb24gY2QgPSAKKwkJbmV3IENvbnRlbnREaXNwb3NpdGlvbihzID09IG51bGwgPyBQYXJ0LkFUVEFDSE1FTlQgOiBzKTsKKwkvLyBlbnN1cmUgdGhhdCB0aGUgZmlsZW5hbWUgaXMgZW5jb2RlZCBpZiBuZWNlc3NhcnkKKwlTdHJpbmcgY2hhcnNldCA9IE1pbWVVdGlsaXR5LmdldERlZmF1bHRNSU1FQ2hhcnNldCgpOworCVBhcmFtZXRlckxpc3QgcCA9IGNkLmdldFBhcmFtZXRlckxpc3QoKTsKKwlpZiAocCA9PSBudWxsKSB7CisJICAgIHAgPSBuZXcgUGFyYW1ldGVyTGlzdCgpOworCSAgICBjZC5zZXRQYXJhbWV0ZXJMaXN0KHApOworCX0KKwlpZiAoZW5jb2RlRmlsZU5hbWUpCisJICAgIHAuc2V0TGl0ZXJhbCgiZmlsZW5hbWUiLCBuYW1lKTsKKwllbHNlCisJICAgIHAuc2V0KCJmaWxlbmFtZSIsIG5hbWUsIGNoYXJzZXQpOworCXBhcnQuc2V0SGVhZGVyKCJDb250ZW50LURpc3Bvc2l0aW9uIiwgY2QudG9TdHJpbmcoKSk7CisKKwkvKgorCSAqIEFsc28gYXR0ZW1wdCB0byBzZXQgdGhlIENvbnRlbnQtVHlwZSAibmFtZSIgcGFyYW1ldGVyLAorCSAqIHRvIHNhdGlzZnkgYW5jaWVudCBNVUFzLiAgWFhYIC0gVGhpcyBpcyBub3QgUkZDIGNvbXBsaWFudC4KKwkgKi8KKwlpZiAoc2V0Q29udGVudFR5cGVGaWxlTmFtZSkgeworCSAgICBzID0gcGFydC5nZXRIZWFkZXIoIkNvbnRlbnQtVHlwZSIsIG51bGwpOworCSAgICBzID0gTWltZVV0aWwuY2xlYW5Db250ZW50VHlwZShwYXJ0LCBzKTsKKwkgICAgaWYgKHMgIT0gbnVsbCkgeworCQl0cnkgeworCQkgICAgQ29udGVudFR5cGUgY1R5cGUgPSBuZXcgQ29udGVudFR5cGUocyk7CisJCSAgICAvLyBlbnN1cmUgdGhhdCB0aGUgZmlsZW5hbWUgaXMgZW5jb2RlZCBpZiBuZWNlc3NhcnkKKwkJICAgIHAgPSBjVHlwZS5nZXRQYXJhbWV0ZXJMaXN0KCk7CisJCSAgICBpZiAocCA9PSBudWxsKSB7CisJCQlwID0gbmV3IFBhcmFtZXRlckxpc3QoKTsKKwkJCWNUeXBlLnNldFBhcmFtZXRlckxpc3QocCk7CisJCSAgICB9CisJCSAgICBpZiAoZW5jb2RlRmlsZU5hbWUpCisJCQlwLnNldExpdGVyYWwoIm5hbWUiLCBuYW1lKTsKKwkJICAgIGVsc2UKKwkJCXAuc2V0KCJuYW1lIiwgbmFtZSwgY2hhcnNldCk7CisJCSAgICBwYXJ0LnNldEhlYWRlcigiQ29udGVudC1UeXBlIiwgY1R5cGUudG9TdHJpbmcoKSk7CisJCX0gY2F0Y2ggKFBhcnNlRXhjZXB0aW9uIHBleCkgeyB9CS8vIGlnbm9yZSBpdAorCSAgICB9CisJfQorICAgIH0KKworICAgIHN0YXRpYyBTdHJpbmdbXSBnZXRDb250ZW50TGFuZ3VhZ2UoTWltZVBhcnQgcGFydCkgCisJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCVN0cmluZyBzID0gcGFydC5nZXRIZWFkZXIoIkNvbnRlbnQtTGFuZ3VhZ2UiLCBudWxsKTsKKworCWlmIChzID09IG51bGwpCisJICAgIHJldHVybiBudWxsOworCisJLy8gVG9rZW5pemUgdGhlIGhlYWRlciB0byBvYnRhaW4gdGhlIExhbmd1YWdlLXRhZ3MgKHNraXAgY29tbWVudHMpCisJSGVhZGVyVG9rZW5pemVyIGggPSBuZXcgSGVhZGVyVG9rZW5pemVyKHMsIEhlYWRlclRva2VuaXplci5NSU1FKTsKKwlMaXN0PFN0cmluZz4gdiA9IG5ldyBBcnJheUxpc3Q8PigpOworCisJSGVhZGVyVG9rZW5pemVyLlRva2VuIHRrOworCWludCB0a1R5cGU7CisKKwl3aGlsZSAodHJ1ZSkgeworCSAgICB0ayA9IGgubmV4dCgpOyAvLyBnZXQgYSBsYW5ndWFnZS10YWcKKwkgICAgdGtUeXBlID0gdGsuZ2V0VHlwZSgpOworCSAgICBpZiAodGtUeXBlID09IEhlYWRlclRva2VuaXplci5Ub2tlbi5FT0YpCisJCWJyZWFrOyAvLyBkb25lCisJICAgIGVsc2UgaWYgKHRrVHlwZSA9PSBIZWFkZXJUb2tlbml6ZXIuVG9rZW4uQVRPTSkKKwkJdi5hZGQodGsuZ2V0VmFsdWUoKSk7CisJICAgIGVsc2UgLy8gaW52YWxpZCB0b2tlbiwgc2tpcCBpdC4KKwkJY29udGludWU7CisJfQorCisJaWYgKHYuaXNFbXB0eSgpKQorCSAgICByZXR1cm4gbnVsbDsKKworCVN0cmluZ1tdIGxhbmd1YWdlID0gbmV3IFN0cmluZ1t2LnNpemUoKV07CisJdi50b0FycmF5KGxhbmd1YWdlKTsKKwlyZXR1cm4gbGFuZ3VhZ2U7CQorICAgIH0KKworICAgIHN0YXRpYyB2b2lkIHNldENvbnRlbnRMYW5ndWFnZShNaW1lUGFydCBwYXJ0LCBTdHJpbmdbXSBsYW5ndWFnZXMpCisJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIobGFuZ3VhZ2VzWzBdKTsKKwlpbnQgbGVuID0gIkNvbnRlbnQtTGFuZ3VhZ2UiLmxlbmd0aCgpICsgMiArIGxhbmd1YWdlc1swXS5sZW5ndGgoKTsKKwlmb3IgKGludCBpID0gMTsgaSA8IGxhbmd1YWdlcy5sZW5ndGg7IGkrKykgeworCSAgICBzYi5hcHBlbmQoJywnKTsKKwkgICAgbGVuKys7CisJICAgIGlmIChsZW4gPiA3NikgeworCQlzYi5hcHBlbmQoIlxyXG5cdCIpOworCQlsZW4gPSA4OworCSAgICB9CisJICAgIHNiLmFwcGVuZChsYW5ndWFnZXNbaV0pOworCSAgICBsZW4gKz0gbGFuZ3VhZ2VzW2ldLmxlbmd0aCgpOworCX0KKwlwYXJ0LnNldEhlYWRlcigiQ29udGVudC1MYW5ndWFnZSIsIHNiLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIHN0YXRpYyBTdHJpbmcgZ2V0RW5jb2RpbmcoTWltZVBhcnQgcGFydCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJU3RyaW5nIHMgPSBwYXJ0LmdldEhlYWRlcigiQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZyIsIG51bGwpOworCisJaWYgKHMgPT0gbnVsbCkKKwkgICAgcmV0dXJuIG51bGw7CisKKwlzID0gcy50cmltKCk7CS8vIGdldCByaWQgb2YgdHJhaWxpbmcgc3BhY2VzCisJaWYgKHMubGVuZ3RoKCkgPT0gMCkKKwkgICAgcmV0dXJuIG51bGw7CisJLy8gcXVpY2sgY2hlY2sgZm9yIGtub3duIHZhbHVlcyB0byBhdm9pZCB1bm5lY2Vzc2FyeSB1c2UKKwkvLyBvZiB0b2tlbml6ZXIuCisJaWYgKHMuZXF1YWxzSWdub3JlQ2FzZSgiN2JpdCIpIHx8IHMuZXF1YWxzSWdub3JlQ2FzZSgiOGJpdCIpIHx8CisJCXMuZXF1YWxzSWdub3JlQ2FzZSgicXVvdGVkLXByaW50YWJsZSIpIHx8CisJCXMuZXF1YWxzSWdub3JlQ2FzZSgiYmluYXJ5IikgfHwKKwkJcy5lcXVhbHNJZ25vcmVDYXNlKCJiYXNlNjQiKSkKKwkgICAgcmV0dXJuIHM7CisKKwkvLyBUb2tlbml6ZSB0aGUgaGVhZGVyIHRvIG9idGFpbiB0aGUgZW5jb2RpbmcgKHNraXAgY29tbWVudHMpCisJSGVhZGVyVG9rZW5pemVyIGggPSBuZXcgSGVhZGVyVG9rZW5pemVyKHMsIEhlYWRlclRva2VuaXplci5NSU1FKTsKKworCUhlYWRlclRva2VuaXplci5Ub2tlbiB0azsKKwlpbnQgdGtUeXBlOworCisJZm9yICg7OykgeworCSAgICB0ayA9IGgubmV4dCgpOyAvLyBnZXQgYSB0b2tlbgorCSAgICB0a1R5cGUgPSB0ay5nZXRUeXBlKCk7CisJICAgIGlmICh0a1R5cGUgPT0gSGVhZGVyVG9rZW5pemVyLlRva2VuLkVPRikKKwkJYnJlYWs7IC8vIGRvbmUKKwkgICAgZWxzZSBpZiAodGtUeXBlID09IEhlYWRlclRva2VuaXplci5Ub2tlbi5BVE9NKQorCQlyZXR1cm4gdGsuZ2V0VmFsdWUoKTsKKwkgICAgZWxzZSAvLyBpbnZhbGlkIHRva2VuLCBza2lwIGl0LgorCQljb250aW51ZTsKKwl9CisJcmV0dXJuIHM7CisgICAgfQorCisgICAgc3RhdGljIHZvaWQgc2V0RW5jb2RpbmcoTWltZVBhcnQgcGFydCwgU3RyaW5nIGVuY29kaW5nKQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXBhcnQuc2V0SGVhZGVyKCJDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nIiwgZW5jb2RpbmcpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlc3RyaWN0IHRoZSBlbmNvZGluZyB0byB2YWx1ZXMgYWxsb3dlZCBmb3IgdGhlCisgICAgICogQ29udGVudC1UeXBlIG9mIHRoZSBzcGVjaWZpZWQgTWltZVBhcnQuICBSZXR1cm5zCisgICAgICogZWl0aGVyIHRoZSBvcmlnaW5hbCBlbmNvZGluZyBvciBudWxsLgorICAgICAqLworICAgIHN0YXRpYyBTdHJpbmcgcmVzdHJpY3RFbmNvZGluZyhNaW1lUGFydCBwYXJ0LCBTdHJpbmcgZW5jb2RpbmcpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKCFpZ25vcmVNdWx0aXBhcnRFbmNvZGluZyB8fCBlbmNvZGluZyA9PSBudWxsKQorCSAgICByZXR1cm4gZW5jb2Rpbmc7CisKKwlpZiAoZW5jb2RpbmcuZXF1YWxzSWdub3JlQ2FzZSgiN2JpdCIpIHx8CisJCWVuY29kaW5nLmVxdWFsc0lnbm9yZUNhc2UoIjhiaXQiKSB8fAorCQllbmNvZGluZy5lcXVhbHNJZ25vcmVDYXNlKCJiaW5hcnkiKSkKKwkgICAgcmV0dXJuIGVuY29kaW5nOwkvLyB0aGVzZSBlbmNvZGluZ3MgYXJlIGFsd2F5cyB2YWxpZAorCisJU3RyaW5nIHR5cGUgPSBwYXJ0LmdldENvbnRlbnRUeXBlKCk7CisJaWYgKHR5cGUgPT0gbnVsbCkKKwkgICAgcmV0dXJuIGVuY29kaW5nOworCisJdHJ5IHsKKwkgICAgLyoKKwkgICAgICogbXVsdGlwYXJ0IGFuZCBtZXNzYWdlIHR5cGVzIGFyZW4ndCBhbGxvd2VkIHRvIGhhdmUKKwkgICAgICogZW5jb2RpbmdzIGV4Y2VwdCBmb3IgdGhlIHRocmVlIG1lbnRpb25lZCBhYm92ZS4KKwkgICAgICogSWYgaXQncyBvbmUgb2YgdGhlc2UgdHlwZXMsIGlnbm9yZSB0aGUgZW5jb2RpbmcuCisJICAgICAqLworCSAgICBDb250ZW50VHlwZSBjVHlwZSA9IG5ldyBDb250ZW50VHlwZSh0eXBlKTsKKwkgICAgaWYgKGNUeXBlLm1hdGNoKCJtdWx0aXBhcnQvKiIpKQorCQlyZXR1cm4gbnVsbDsKKwkgICAgaWYgKGNUeXBlLm1hdGNoKCJtZXNzYWdlLyoiKSAmJgorCQkgICAgIVByb3BVdGlsLmdldEJvb2xlYW5TeXN0ZW1Qcm9wZXJ0eSgKKwkJCSJtYWlsLm1pbWUuYWxsb3dlbmNvZGVkbWVzc2FnZXMiLCBmYWxzZSkpCisJCXJldHVybiBudWxsOworCX0gY2F0Y2ggKFBhcnNlRXhjZXB0aW9uIHBleCkgeworCSAgICAvLyBpZ25vcmUgaXQKKwl9CisJcmV0dXJuIGVuY29kaW5nOworICAgIH0KKworICAgIHN0YXRpYyB2b2lkIHVwZGF0ZUhlYWRlcnMoTWltZVBhcnQgcGFydCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJRGF0YUhhbmRsZXIgZGggPSBwYXJ0LmdldERhdGFIYW5kbGVyKCk7CisJaWYgKGRoID09IG51bGwpIC8vIEh1aCA/CisJICAgIHJldHVybjsKKworCXRyeSB7CisJICAgIFN0cmluZyB0eXBlID0gZGguZ2V0Q29udGVudFR5cGUoKTsKKwkgICAgYm9vbGVhbiBjb21wb3NpdGUgPSBmYWxzZTsKKwkgICAgYm9vbGVhbiBuZWVkQ1RIZWFkZXIgPSBwYXJ0LmdldEhlYWRlcigiQ29udGVudC1UeXBlIikgPT0gbnVsbDsKKworCSAgICBDb250ZW50VHlwZSBjVHlwZSA9IG5ldyBDb250ZW50VHlwZSh0eXBlKTsKKworCSAgICAvKgorCSAgICAgKiBJZiB0aGlzIGlzIGEgbXVsdGlwYXJ0LCBnaXZlIHN1Yi1wYXJ0cyBhIGNoYW5jZSB0bworCSAgICAgKiB1cGRhdGUgdGhlaXIgaGVhZGVycy4gIEV2ZW4gdGhvdWdoIHRoZSBkYXRhIGZvciB0aGlzCisJICAgICAqIG11bHRpcGFydCBtYXkgaGF2ZSBjb21lIGZyb20gYSBzdHJlYW0sIG9uZSBvZiB0aGUKKwkgICAgICogc3ViLXBhcnRzIG1heSBoYXZlIGJlZW4gdXBkYXRlZC4KKwkgICAgICovCisJICAgIGlmIChjVHlwZS5tYXRjaCgibXVsdGlwYXJ0LyoiKSkgeworCQkvLyBJZiBtdWx0aXBhcnQsIHJlY3Vyc2UKKwkJY29tcG9zaXRlID0gdHJ1ZTsKKwkJT2JqZWN0IG87CisJCWlmIChwYXJ0IGluc3RhbmNlb2YgTWltZUJvZHlQYXJ0KSB7CisJCSAgICBNaW1lQm9keVBhcnQgbWJwID0gKE1pbWVCb2R5UGFydClwYXJ0OworCQkgICAgbyA9IG1icC5jYWNoZWRDb250ZW50ICE9IG51bGwgPworCQkJCW1icC5jYWNoZWRDb250ZW50IDogZGguZ2V0Q29udGVudCgpOworCQl9IGVsc2UgaWYgKHBhcnQgaW5zdGFuY2VvZiBNaW1lTWVzc2FnZSkgeworCQkgICAgTWltZU1lc3NhZ2UgbXNnID0gKE1pbWVNZXNzYWdlKXBhcnQ7CisJCSAgICBvID0gbXNnLmNhY2hlZENvbnRlbnQgIT0gbnVsbCA/CisJCQkJbXNnLmNhY2hlZENvbnRlbnQgOiBkaC5nZXRDb250ZW50KCk7CisJCX0gZWxzZQorCQkgICAgbyA9IGRoLmdldENvbnRlbnQoKTsKKwkJaWYgKG8gaW5zdGFuY2VvZiBNaW1lTXVsdGlwYXJ0KQorCQkgICAgKChNaW1lTXVsdGlwYXJ0KW8pLnVwZGF0ZUhlYWRlcnMoKTsKKwkJZWxzZQorCQkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiTUlNRSBwYXJ0IG9mIHR5cGUgXCIiICsKKwkJCXR5cGUgKyAiXCIgY29udGFpbnMgb2JqZWN0IG9mIHR5cGUgIiArCisJCQlvLmdldENsYXNzKCkuZ2V0TmFtZSgpICsgIiBpbnN0ZWFkIG9mIE1pbWVNdWx0aXBhcnQiKTsKKwkgICAgfSBlbHNlIGlmIChjVHlwZS5tYXRjaCgibWVzc2FnZS9yZmM4MjIiKSkgeworCQljb21wb3NpdGUgPSB0cnVlOworCQkvLyBYWFggLSBjYWxsIE1pbWVNZXNzYWdlLnVwZGF0ZUhlYWRlcnMoKT8KKwkgICAgfQorCisJICAgIC8qCisJICAgICAqIElmIHRoaXMgaXMgb3VyIG93biBNaW1lUGFydERhdGFIYW5kbGVyLCB3ZSBjYW4ndCB1cGRhdGUgYW55CisJICAgICAqIG9mIHRoZSBoZWFkZXJzLgorCSAgICAgKgorCSAgICAgKiBJZiB0aGlzIGlzIGEgTWltZVBhcnREYXRhSGFuZGxlciBjb21pbmcgZnJvbSBhbm90aGVyIHBhcnQsCisJICAgICAqIHdlIG5lZWQgdG8gY29weSBvdmVyIHRoZSBjb250ZW50IGhlYWRlcnMgZnJvbSB0aGUgb3RoZXIgcGFydC4KKwkgICAgICogTm90ZSB0aGF0IHRoZSBNaW1lUGFydERhdGFIYW5kbGVyIHN0aWxsIHJlZmVycyB0byB0aGUgb3JpZ2luYWwKKwkgICAgICogZGF0YSBhbmQgdGhlIG9yaWdpbmFsIE1pbWVQYXJ0LgorCSAgICAgKi8KKwkgICAgaWYgKGRoIGluc3RhbmNlb2YgTWltZVBhcnREYXRhSGFuZGxlcikgeworCQlNaW1lUGFydERhdGFIYW5kbGVyIG1kaCA9IChNaW1lUGFydERhdGFIYW5kbGVyKWRoOworCQlNaW1lUGFydCBtcGFydCA9IG1kaC5nZXRQYXJ0KCk7CisJCWlmIChtcGFydCAhPSBwYXJ0KSB7CisJCSAgICBpZiAobmVlZENUSGVhZGVyKQorCQkJcGFydC5zZXRIZWFkZXIoIkNvbnRlbnQtVHlwZSIsIG1wYXJ0LmdldENvbnRlbnRUeXBlKCkpOworCQkgICAgLy8gWFhYIC0gY2FuJ3QgY2hhbmdlIHRoZSBlbmNvZGluZyBvZiB0aGUgZGF0YSBmcm9tIHRoZQorCQkgICAgLy8gb3RoZXIgcGFydCB3aXRob3V0IGRlY29kaW5nIGFuZCByZWVuY29kaW5nIGl0LCBzbworCQkgICAgLy8gd2UganVzdCBmb3JjZSBpdCB0byBtYXRjaCB0aGUgb3JpZ2luYWwsIGJ1dCBpZiB0aGUKKwkJICAgIC8vIG9yaWdpbmFsIGhhcyBubyBlbmNvZGluZyB3ZSdsbCBjb25zaWRlciByZWVuY29kaW5nIGl0CisJCSAgICBTdHJpbmcgZW5jID0gbXBhcnQuZ2V0RW5jb2RpbmcoKTsKKwkJICAgIGlmIChlbmMgIT0gbnVsbCkgeworCQkJc2V0RW5jb2RpbmcocGFydCwgZW5jKTsKKwkJCXJldHVybjsKKwkJICAgIH0KKwkJfSBlbHNlCisJCSAgICByZXR1cm47CisJICAgIH0KKworCSAgICAvLyBDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nLCBidXQgb25seSBpZiB3ZSBkb24ndAorCSAgICAvLyBhbHJlYWR5IGhhdmUgb25lCisJICAgIGlmICghY29tcG9zaXRlKSB7CS8vIG5vdCBhbGxvd2VkIG9uIGNvbXBvc2l0ZSBwYXJ0cworCQlpZiAocGFydC5nZXRIZWFkZXIoIkNvbnRlbnQtVHJhbnNmZXItRW5jb2RpbmciKSA9PSBudWxsKQorCQkgICAgc2V0RW5jb2RpbmcocGFydCwgTWltZVV0aWxpdHkuZ2V0RW5jb2RpbmcoZGgpKTsKKworCQlpZiAobmVlZENUSGVhZGVyICYmIHNldERlZmF1bHRUZXh0Q2hhcnNldCAmJgorCQkJY1R5cGUubWF0Y2goInRleHQvKiIpICYmCisJCQljVHlwZS5nZXRQYXJhbWV0ZXIoImNoYXJzZXQiKSA9PSBudWxsKSB7CisJCSAgICAvKgorCQkgICAgICogU2V0IGEgZGVmYXVsdCBjaGFyc2V0IGZvciB0ZXh0IHBhcnRzLgorCQkgICAgICogV2UgcmVhbGx5IHNob3VsZCBleGFtaW5lIHRoZSBkYXRhIHRvIGRldGVybWluZQorCQkgICAgICogd2hldGhlciBvciBub3QgaXQncyBhbGwgQVNDSUksIGJ1dCB0aGF0J3MgdG9vCisJCSAgICAgKiBleHBlbnNpdmUgc28gd2UgbWFrZSBhbiBhc3N1bXB0aW9uOiAgSWYgd2UKKwkJICAgICAqIGNob3NlIDdiaXQgZW5jb2RpbmcgZm9yIHRoaXMgZGF0YSwgaXQncyBwcm9iYWJseQorCQkgICAgICogQVNDSUkuICAoTWltZVV0aWxpdHkuZ2V0RW5jb2Rpbmcgd2lsbCBjaG9vc2UKKwkJICAgICAqIDdiaXQgb25seSBpbiB0aGlzIGNhc2UsIGJ1dCBzb21lb25lIG1pZ2h0J3ZlCisJCSAgICAgKiBzZXQgdGhlIENvbnRlbnQtVHJhbnNmZXItRW5jb2RpbmcgaGVhZGVyIG1hbnVhbGx5LikKKwkJICAgICAqLworCQkgICAgU3RyaW5nIGNoYXJzZXQ7CisJCSAgICBTdHJpbmcgZW5jID0gcGFydC5nZXRFbmNvZGluZygpOworCQkgICAgaWYgKGVuYyAhPSBudWxsICYmIGVuYy5lcXVhbHNJZ25vcmVDYXNlKCI3Yml0IikpCisJCQljaGFyc2V0ID0gInVzLWFzY2lpIjsKKwkJICAgIGVsc2UKKwkJCWNoYXJzZXQgPSBNaW1lVXRpbGl0eS5nZXREZWZhdWx0TUlNRUNoYXJzZXQoKTsKKwkJICAgIGNUeXBlLnNldFBhcmFtZXRlcigiY2hhcnNldCIsIGNoYXJzZXQpOworCQkgICAgdHlwZSA9IGNUeXBlLnRvU3RyaW5nKCk7CisJCX0KKwkgICAgfQorCisJICAgIC8vIE5vdywgbGV0J3MgdXBkYXRlIG91ciBvd24gaGVhZGVycyAuLi4KKworCSAgICAvLyBDb250ZW50LXR5cGUsIGJ1dCBvbmx5IGlmIHdlIGRvbid0IGFscmVhZHkgaGF2ZSBvbmUKKwkgICAgaWYgKG5lZWRDVEhlYWRlcikgeworCQkvKgorCQkgKiBQdWxsIG91dCAiZmlsZW5hbWUiIGZyb20gQ29udGVudC1EaXNwb3NpdGlvbiwgYW5kCisJCSAqIHVzZSB0aGF0IHRvIHNldCB0aGUgIm5hbWUiIHBhcmFtZXRlci4gVGhpcyBpcyB0bworCQkgKiBzYXRpc2Z5IG9sZGVyIE1VQXMgKER0TWFpbCwgUm9hbSBhbmQgcHJvYmFibHkKKwkJICogYSBidW5jaCBvZiBvdGhlcnMpLgorCQkgKi8KKwkJaWYgKHNldENvbnRlbnRUeXBlRmlsZU5hbWUpIHsKKwkJICAgIFN0cmluZyBzID0gcGFydC5nZXRIZWFkZXIoIkNvbnRlbnQtRGlzcG9zaXRpb24iLCBudWxsKTsKKwkJICAgIGlmIChzICE9IG51bGwpIHsKKwkJCS8vIFBhcnNlIHRoZSBoZWFkZXIgLi4KKwkJCUNvbnRlbnREaXNwb3NpdGlvbiBjZCA9IG5ldyBDb250ZW50RGlzcG9zaXRpb24ocyk7CisJCQlTdHJpbmcgZmlsZW5hbWUgPSBjZC5nZXRQYXJhbWV0ZXIoImZpbGVuYW1lIik7CisJCQlpZiAoZmlsZW5hbWUgIT0gbnVsbCkgeworCQkJICAgIFBhcmFtZXRlckxpc3QgcCA9IGNUeXBlLmdldFBhcmFtZXRlckxpc3QoKTsKKwkJCSAgICBpZiAocCA9PSBudWxsKSB7CisJCQkJcCA9IG5ldyBQYXJhbWV0ZXJMaXN0KCk7CisJCQkJY1R5cGUuc2V0UGFyYW1ldGVyTGlzdChwKTsKKwkJCSAgICB9CisJCQkgICAgaWYgKGVuY29kZUZpbGVOYW1lKQorCQkJCXAuc2V0TGl0ZXJhbCgibmFtZSIsCisJCQkJCU1pbWVVdGlsaXR5LmVuY29kZVRleHQoZmlsZW5hbWUpKTsKKwkJCSAgICBlbHNlCisJCQkJcC5zZXQoIm5hbWUiLCBmaWxlbmFtZSwKKwkJCQkJTWltZVV0aWxpdHkuZ2V0RGVmYXVsdE1JTUVDaGFyc2V0KCkpOworCQkJICAgIHR5cGUgPSBjVHlwZS50b1N0cmluZygpOworCQkJfQorCQkgICAgfQorCQl9CisJCQorCQlwYXJ0LnNldEhlYWRlcigiQ29udGVudC1UeXBlIiwgdHlwZSk7CisJICAgIH0KKwl9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKCJJT0V4Y2VwdGlvbiB1cGRhdGluZyBoZWFkZXJzIiwgZXgpOworCX0KKyAgICB9CisKKyAgICBzdGF0aWMgdm9pZCBpbnZhbGlkYXRlQ29udGVudEhlYWRlcnMoTWltZVBhcnQgcGFydCkKKwkJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJcGFydC5yZW1vdmVIZWFkZXIoIkNvbnRlbnQtVHlwZSIpOworCXBhcnQucmVtb3ZlSGVhZGVyKCJDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nIik7CisgICAgfQorICAgIAorICAgIHN0YXRpYyB2b2lkIHdyaXRlVG8oTWltZVBhcnQgcGFydCwgT3V0cHV0U3RyZWFtIG9zLCBTdHJpbmdbXSBpZ25vcmVMaXN0KQorCQkJdGhyb3dzIElPRXhjZXB0aW9uLCBNZXNzYWdpbmdFeGNlcHRpb24geworCisJLy8gc2VlIGlmIHdlIGFscmVhZHkgaGF2ZSBhIExPUworCUxpbmVPdXRwdXRTdHJlYW0gbG9zID0gbnVsbDsKKwlpZiAob3MgaW5zdGFuY2VvZiBMaW5lT3V0cHV0U3RyZWFtKSB7CisJICAgIGxvcyA9IChMaW5lT3V0cHV0U3RyZWFtKSBvczsKKwl9IGVsc2UgeworCSAgICBsb3MgPSBuZXcgTGluZU91dHB1dFN0cmVhbShvcywgYWxsb3d1dGY4KTsKKwl9CisKKwkvLyBGaXJzdCwgd3JpdGUgb3V0IHRoZSBoZWFkZXIKKwlFbnVtZXJhdGlvbjxTdHJpbmc+IGhkckxpbmVzCisJCT0gcGFydC5nZXROb25NYXRjaGluZ0hlYWRlckxpbmVzKGlnbm9yZUxpc3QpOworCXdoaWxlIChoZHJMaW5lcy5oYXNNb3JlRWxlbWVudHMoKSkKKwkgICAgbG9zLndyaXRlbG4oaGRyTGluZXMubmV4dEVsZW1lbnQoKSk7CisKKwkvLyBUaGUgQ1JMRiBzZXBhcmF0b3IgYmV0d2VlbiBoZWFkZXIgYW5kIGNvbnRlbnQKKwlsb3Mud3JpdGVsbigpOworCisJLy8gRmluYWxseSwgdGhlIGNvbnRlbnQuIEVuY29kZSBpZiByZXF1aXJlZC4KKwkvLyBYWFg6IE1heSBuZWVkIHRvIGFjY291bnQgZm9yIEVTTVRQID8KKwlJbnB1dFN0cmVhbSBpcyA9IG51bGw7CisJYnl0ZVtdIGJ1ZiA9IG51bGw7CisJdHJ5IHsKKwkgICAgLyoKKwkgICAgICogSWYgdGhlIGRhdGEgZm9yIHRoaXMgcGFydCBjb21lcyBmcm9tIGEgc3RyZWFtLAorCSAgICAgKiBhbmQgaXMgYWxyZWFkeSBlbmNvZGVkLAorCSAgICAgKiBqdXN0IGNvcHkgaXQgdG8gdGhlIG91dHB1dCBzdHJlYW0gd2l0aG91dCBkZWNvZGluZworCSAgICAgKiBhbmQgcmVlbmNvZGluZyBpdC4KKwkgICAgICovCisJICAgIERhdGFIYW5kbGVyIGRoID0gcGFydC5nZXREYXRhSGFuZGxlcigpOworCSAgICBpZiAoZGggaW5zdGFuY2VvZiBNaW1lUGFydERhdGFIYW5kbGVyKSB7CisJCU1pbWVQYXJ0RGF0YUhhbmRsZXIgbXBkaCA9IChNaW1lUGFydERhdGFIYW5kbGVyKWRoOworCQlNaW1lUGFydCBtcGFydCA9IG1wZGguZ2V0UGFydCgpOworCQlpZiAobXBhcnQuZ2V0RW5jb2RpbmcoKSAhPSBudWxsKQorCQkgICAgaXMgPSBtcGRoLmdldENvbnRlbnRTdHJlYW0oKTsKKwkgICAgfQorCSAgICBpZiAoaXMgIT0gbnVsbCkgeworCQkvLyBub3cgY29weSB0aGUgZGF0YSB0byB0aGUgb3V0cHV0IHN0cmVhbQorCQlidWYgPSBuZXcgYnl0ZVs4MTkyXTsKKwkJaW50IGxlbjsKKwkJd2hpbGUgKChsZW4gPSBpcy5yZWFkKGJ1ZikpID4gMCkKKwkJICAgIG9zLndyaXRlKGJ1ZiwgMCwgbGVuKTsKKwkgICAgfSBlbHNlIHsKKwkJb3MgPSBNaW1lVXRpbGl0eS5lbmNvZGUob3MsCisJCQlyZXN0cmljdEVuY29kaW5nKHBhcnQsIHBhcnQuZ2V0RW5jb2RpbmcoKSkpOworCQlwYXJ0LmdldERhdGFIYW5kbGVyKCkud3JpdGVUbyhvcyk7CisJICAgIH0KKwl9IGZpbmFsbHkgeworCSAgICBpZiAoaXMgIT0gbnVsbCkKKwkJaXMuY2xvc2UoKTsKKwkgICAgYnVmID0gbnVsbDsKKwl9CisJb3MuZmx1c2goKTsgLy8gTmVlZGVkIHRvIGNvbXBsZXRlIGVuY29kaW5nCisgICAgfQorCisgICAgLyoqCisgICAgICogQSBzcGVjaWFsIERhdGFIYW5kbGVyIHVzZWQgb25seSBhcyBhIG1hcmtlciB0byBpbmRpY2F0ZSB0aGF0CisgICAgICogdGhlIHNvdXJjZSBvZiB0aGUgZGF0YSBpcyBhIE1pbWVQYXJ0ICh0aGF0IGlzLCBhIGJ5dGUgYXJyYXkKKyAgICAgKiBvciBhIHN0cmVhbSkuICBUaGlzIHByZXZlbnRzIHVwZGF0ZUhlYWRlcnMgZnJvbSB0cnlpbmcgdG8KKyAgICAgKiBjaGFuZ2UgdGhlIGhlYWRlcnMgZm9yIHN1Y2ggZGF0YS4gIEluIHBhcnRpY3VsYXIsIHRoZSBvcmlnaW5hbAorICAgICAqIENvbnRlbnQtVHJhbnNmZXItRW5jb2RpbmcgZm9yIHRoZSBkYXRhIG11c3QgYmUgcHJlc2VydmVkLgorICAgICAqIE90aGVyd2lzZSB0aGUgZGF0YSB3b3VsZCBuZWVkIHRvIGJlIGRlY29kZWQgYW5kIHJlZW5jb2RlZC4KKyAgICAgKi8KKyAgICBzdGF0aWMgY2xhc3MgTWltZVBhcnREYXRhSGFuZGxlciBleHRlbmRzIERhdGFIYW5kbGVyIHsKKwlNaW1lUGFydCBwYXJ0OworCXB1YmxpYyBNaW1lUGFydERhdGFIYW5kbGVyKE1pbWVQYXJ0IHBhcnQpIHsKKwkgICAgc3VwZXIobmV3IE1pbWVQYXJ0RGF0YVNvdXJjZShwYXJ0KSk7CisJICAgIHRoaXMucGFydCA9IHBhcnQ7CisJfQorCisJSW5wdXRTdHJlYW0gZ2V0Q29udGVudFN0cmVhbSgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCSAgICBJbnB1dFN0cmVhbSBpcyA9IG51bGw7CisKKwkgICAgaWYgKHBhcnQgaW5zdGFuY2VvZiBNaW1lQm9keVBhcnQpIHsKKwkJTWltZUJvZHlQYXJ0IG1icCA9IChNaW1lQm9keVBhcnQpcGFydDsKKwkJaXMgPSBtYnAuZ2V0Q29udGVudFN0cmVhbSgpOworCSAgICB9IGVsc2UgaWYgKHBhcnQgaW5zdGFuY2VvZiBNaW1lTWVzc2FnZSkgeworCQlNaW1lTWVzc2FnZSBtc2cgPSAoTWltZU1lc3NhZ2UpcGFydDsKKwkJaXMgPSBtc2cuZ2V0Q29udGVudFN0cmVhbSgpOworCSAgICB9CisJICAgIHJldHVybiBpczsKKwl9CisKKwlNaW1lUGFydCBnZXRQYXJ0KCkgeworCSAgICByZXR1cm4gcGFydDsKKwl9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvTWltZU1lc3NhZ2UuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2ludGVybmV0L01pbWVNZXNzYWdlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmM1YThmMwotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2ludGVybmV0L01pbWVNZXNzYWdlLmphdmEKQEAgLTAsMCArMSwyMjk5IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGphdmF4Lm1haWwuaW50ZXJuZXQ7CisKK2ltcG9ydCBqYXZheC5tYWlsLio7CitpbXBvcnQgamF2YXguYWN0aXZhdGlvbi4qOworaW1wb3J0IGphdmEubGFuZy4qOworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBqYXZhLnRleHQuUGFyc2VFeGNlcHRpb247CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuUHJvcFV0aWw7CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuQVNDSUlVdGlsaXR5OworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLk1pbWVVdGlsOworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLk1lc3NhZ2VSZW1vdmVkSU9FeGNlcHRpb247CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuRm9sZGVyQ2xvc2VkSU9FeGNlcHRpb247CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuTGluZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZheC5tYWlsLnV0aWwuU2hhcmVkQnl0ZUFycmF5SW5wdXRTdHJlYW07CisKKy8qKgorICogVGhpcyBjbGFzcyByZXByZXNlbnRzIGEgTUlNRSBzdHlsZSBlbWFpbCBtZXNzYWdlLiBJdCBpbXBsZW1lbnRzCisgKiB0aGUgPGNvZGU+TWVzc2FnZTwvY29kZT4gYWJzdHJhY3QgY2xhc3MgYW5kIHRoZSA8Y29kZT5NaW1lUGFydDwvY29kZT4KKyAqIGludGVyZmFjZS4gPHA+CisgKgorICogQ2xpZW50cyB3YW50aW5nIHRvIGNyZWF0ZSBuZXcgTUlNRSBzdHlsZSBtZXNzYWdlcyB3aWxsIGluc3RhbnRpYXRlCisgKiBhbiBlbXB0eSBNaW1lTWVzc2FnZSBvYmplY3QgYW5kIHRoZW4gZmlsbCBpdCB3aXRoIGFwcHJvcHJpYXRlIAorICogYXR0cmlidXRlcyBhbmQgY29udGVudC4gPHA+CisgKiAKKyAqIFNlcnZpY2UgcHJvdmlkZXJzIHRoYXQgaW1wbGVtZW50IE1JTUUgY29tcGxpYW50IGJhY2tlbmQgc3RvcmVzIG1heQorICogd2FudCB0byBzdWJjbGFzcyBNaW1lTWVzc2FnZSBhbmQgb3ZlcnJpZGUgY2VydGFpbiBtZXRob2RzIHRvIHByb3ZpZGUKKyAqIHNwZWNpZmljIGltcGxlbWVudGF0aW9ucy4gVGhlIHNpbXBsZXN0IGNhc2UgaXMgcHJvYmFibHkgYSBwcm92aWRlcgorICogdGhhdCBnZW5lcmF0ZXMgYSBNSU1FIHN0eWxlIGlucHV0IHN0cmVhbSBhbmQgbGVhdmVzIHRoZSBwYXJzaW5nIG9mCisgKiB0aGUgc3RyZWFtIHRvIHRoaXMgY2xhc3MuIDxwPgorICoKKyAqIE1pbWVNZXNzYWdlIHVzZXMgdGhlIDxjb2RlPkludGVybmV0SGVhZGVyczwvY29kZT4gY2xhc3MgdG8gcGFyc2UgYW5kCisgKiBzdG9yZSB0aGUgdG9wIGxldmVsIFJGQyA4MjIgaGVhZGVycyBvZiBhIG1lc3NhZ2UuIDxwPgorICoKKyAqIFRoZSA8Y29kZT5tYWlsLm1pbWUuYWRkcmVzcy5zdHJpY3Q8L2NvZGU+IHNlc3Npb24gcHJvcGVydHkgY29udHJvbHMKKyAqIHRoZSBwYXJzaW5nIG9mIGFkZHJlc3MgaGVhZGVycy4gIEJ5IGRlZmF1bHQsIHN0cmljdCBwYXJzaW5nIG9mIGFkZHJlc3MKKyAqIGhlYWRlcnMgaXMgZG9uZS4gIElmIHRoaXMgcHJvcGVydHkgaXMgc2V0IHRvIDxjb2RlPiJmYWxzZSI8L2NvZGU+LAorICogc3RyaWN0IHBhcnNpbmcgaXMgbm90IGRvbmUgYW5kIG1hbnkgaWxsZWdhbCBhZGRyZXNzZXMgdGhhdCBzb21ldGltZXMKKyAqIG9jY3VyIGluIHJlYWwgbWVzc2FnZXMgYXJlIGFsbG93ZWQuICBTZWUgdGhlIDxjb2RlPkludGVybmV0QWRkcmVzczwvY29kZT4KKyAqIGNsYXNzIGZvciBkZXRhaWxzLgorICoKKyAqIDxocj48c3Ryb25nPkEgbm90ZSBvbiBSRkMgODIyIGFuZCBNSU1FIGhlYWRlcnM8L3N0cm9uZz48cD4KKyAqCisgKiBSRkMgODIyIGhlYWRlciBmaWVsZHMgPHN0cm9uZz5tdXN0PC9zdHJvbmc+IGNvbnRhaW4gb25seSAKKyAqIFVTLUFTQ0lJIGNoYXJhY3RlcnMuIE1JTUUgYWxsb3dzIG5vbiBBU0NJSSBjaGFyYWN0ZXJzIHRvIGJlIHByZXNlbnQKKyAqIGluIGNlcnRhaW4gcG9ydGlvbnMgb2YgY2VydGFpbiBoZWFkZXJzLCBieSBlbmNvZGluZyB0aG9zZSBjaGFyYWN0ZXJzLgorICogUkZDIDIwNDcgc3BlY2lmaWVzIHRoZSBydWxlcyBmb3IgZG9pbmcgdGhpcy4gVGhlIE1pbWVVdGlsaXR5CisgKiBjbGFzcyBwcm92aWRlZCBpbiB0aGlzIHBhY2thZ2UgY2FuIGJlIHVzZWQgdG8gdG8gYWNoaWV2ZSB0aGlzLgorICogQ2FsbGVycyBvZiB0aGUgPGNvZGU+c2V0SGVhZGVyPC9jb2RlPiwgPGNvZGU+YWRkSGVhZGVyPC9jb2RlPiwgYW5kCisgKiA8Y29kZT5hZGRIZWFkZXJMaW5lPC9jb2RlPiBtZXRob2RzIGFyZSByZXNwb25zaWJsZSBmb3IgZW5mb3JjaW5nCisgKiB0aGUgTUlNRSByZXF1aXJlbWVudHMgZm9yIHRoZSBzcGVjaWZpZWQgaGVhZGVycy4gIEluIGFkZGl0aW9uLCB0aGVzZQorICogaGVhZGVyIGZpZWxkcyBtdXN0IGJlIGZvbGRlZCAod3JhcHBlZCkgYmVmb3JlIGJlaW5nIHNlbnQgaWYgdGhleQorICogZXhjZWVkIHRoZSBsaW5lIGxlbmd0aCBsaW1pdGF0aW9uIGZvciB0aGUgdHJhbnNwb3J0ICgxMDAwIGJ5dGVzIGZvcgorICogU01UUCkuICBSZWNlaXZlZCBoZWFkZXJzIG1heSBoYXZlIGJlZW4gZm9sZGVkLiAgVGhlIGFwcGxpY2F0aW9uIGlzCisgKiByZXNwb25zaWJsZSBmb3IgZm9sZGluZyBhbmQgdW5mb2xkaW5nIGhlYWRlcnMgYXMgYXBwcm9wcmlhdGUuIDxwPgorICoKKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICogQGF1dGhvciBNYXggU3BpdmFrCisgKiBAYXV0aG9yIEthbndhciBPYmVyb2kKKyAqIEBzZWUJamF2YXgubWFpbC5pbnRlcm5ldC5NaW1lVXRpbGl0eQorICogQHNlZQlqYXZheC5tYWlsLlBhcnQKKyAqIEBzZWUJamF2YXgubWFpbC5NZXNzYWdlCisgKiBAc2VlCWphdmF4Lm1haWwuaW50ZXJuZXQuTWltZVBhcnQKKyAqIEBzZWUJamF2YXgubWFpbC5pbnRlcm5ldC5JbnRlcm5ldEFkZHJlc3MKKyAqLworCitwdWJsaWMgY2xhc3MgTWltZU1lc3NhZ2UgZXh0ZW5kcyBNZXNzYWdlIGltcGxlbWVudHMgTWltZVBhcnQgeworCisgICAgLyoqCisgICAgICogVGhlIERhdGFIYW5kbGVyIG9iamVjdCByZXByZXNlbnRpbmcgdGhpcyBNZXNzYWdlJ3MgY29udGVudC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgRGF0YUhhbmRsZXIgZGg7CisKKyAgICAvKioKKyAgICAgKiBCeXRlIGFycmF5IHRoYXQgaG9sZHMgdGhlIGJ5dGVzIG9mIHRoaXMgTWVzc2FnZSdzIGNvbnRlbnQuCisgICAgICovCisgICAgcHJvdGVjdGVkIGJ5dGVbXSBjb250ZW50OworCisgICAgLyoqCisgICAgICogSWYgdGhlIGRhdGEgZm9yIHRoaXMgbWVzc2FnZSB3YXMgc3VwcGxpZWQgYnkgYW4KKyAgICAgKiBJbnB1dFN0cmVhbSB0aGF0IGltcGxlbWVudHMgdGhlIFNoYXJlZElucHV0U3RyZWFtIGludGVyZmFjZSwKKyAgICAgKiA8Y29kZT5jb250ZW50U3RyZWFtPC9jb2RlPiBpcyBhbm90aGVyIHN1Y2ggc3RyZWFtIHJlcHJlc2VudGluZworICAgICAqIHRoZSBjb250ZW50IG9mIHRoaXMgbWVzc2FnZS4gIEluIHRoaXMgY2FzZSwgPGNvZGU+Y29udGVudDwvY29kZT4KKyAgICAgKiB3aWxsIGJlIG51bGwuCisgICAgICoKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS4yCisgICAgICovCisgICAgcHJvdGVjdGVkIElucHV0U3RyZWFtIGNvbnRlbnRTdHJlYW07CisKKyAgICAvKioKKyAgICAgKiBUaGUgSW50ZXJuZXRIZWFkZXJzIG9iamVjdCB0aGF0IHN0b3JlcyB0aGUgaGVhZGVyCisgICAgICogb2YgdGhpcyBtZXNzYWdlLgorICAgICAqLworICAgIHByb3RlY3RlZCBJbnRlcm5ldEhlYWRlcnMgaGVhZGVyczsKKworICAgIC8qKgorICAgICAqIFRoZSBGbGFncyBmb3IgdGhpcyBtZXNzYWdlLiAKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgRmxhZ3MgZmxhZ3M7CisKKyAgICAvKioKKyAgICAgKiBBIGZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHRoZSBtZXNzYWdlIGhhcyBiZWVuIG1vZGlmaWVkLgorICAgICAqIElmIHRoZSBtZXNzYWdlIGhhcyBub3QgYmVlbiBtb2RpZmllZCwgYW55IGRhdGEgaW4gdGhlCisgICAgICogPGNvZGU+Y29udGVudDwvY29kZT4gYXJyYXkgaXMgYXNzdW1lZCB0byBiZSB2YWxpZCBhbmQgaXMgdXNlZAorICAgICAqIGRpcmVjdGx5IGluIHRoZSA8Y29kZT53cml0ZVRvPC9jb2RlPiBtZXRob2QuICBUaGlzIGZsYWcgaXMKKyAgICAgKiBzZXQgdG8gdHJ1ZSB3aGVuIGFuIGVtcHR5IG1lc3NhZ2UgaXMgY3JlYXRlZCBvciB3aGVuIHRoZQorICAgICAqIDxjb2RlPnNhdmVDaGFuZ2VzPC9jb2RlPiBtZXRob2QgaXMgY2FsbGVkLgorICAgICAqCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuMgorICAgICAqLworICAgIHByb3RlY3RlZCBib29sZWFuIG1vZGlmaWVkID0gZmFsc2U7CisKKyAgICAvKioKKyAgICAgKiBEb2VzIHRoZSA8Y29kZT5zYXZlQ2hhbmdlczwvY29kZT4gbWV0aG9kIG5lZWQgdG8gYmUgY2FsbGVkIG9uCisgICAgICogdGhpcyBtZXNzYWdlPyAgVGhpcyBmbGFnIGlzIHNldCB0byBmYWxzZSBieSB0aGUgcHVibGljIGNvbnN0cnVjdG9yCisgICAgICogYW5kIHNldCB0byB0cnVlIGJ5IHRoZSA8Y29kZT5zYXZlQ2hhbmdlczwvY29kZT4gbWV0aG9kLiAgVGhlCisgICAgICogPGNvZGU+d3JpdGVUbzwvY29kZT4gbWV0aG9kIGNoZWNrcyB0aGlzIGZsYWcgYW5kIGNhbGxzIHRoZQorICAgICAqIDxjb2RlPnNhdmVDaGFuZ2VzPC9jb2RlPiBtZXRob2QgYXMgbmVjZXNzYXJ5LiAgVGhpcyBhdm9pZHMgdGhlCisgICAgICogY29tbW9uIG1pc3Rha2Ugb2YgZm9yZ2V0dGluZyB0byBjYWxsIHRoZSA8Y29kZT5zYXZlQ2hhbmdlczwvY29kZT4KKyAgICAgKiBtZXRob2Qgb24gYSBuZXdseSBjb25zdHJ1Y3RlZCBtZXNzYWdlLgorICAgICAqCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuMgorICAgICAqLworICAgIHByb3RlY3RlZCBib29sZWFuIHNhdmVkID0gZmFsc2U7CisKKyAgICAvKioKKyAgICAgKiBJZiBvdXIgY29udGVudCBpcyBhIE11bHRpcGFydCBvciBNZXNzYWdlIG9iamVjdCwgd2Ugc2F2ZSBpdAorICAgICAqIHRoZSBmaXJzdCB0aW1lIGl0J3MgY3JlYXRlZCBieSBwYXJzaW5nIGEgc3RyZWFtIHNvIHRoYXQgY2hhbmdlcworICAgICAqIHRvIHRoZSBjb250YWluZWQgb2JqZWN0cyB3aWxsIG5vdCBiZSBsb3N0LiA8cD4KKyAgICAgKgorICAgICAqIElmIHRoaXMgZmllbGQgaXMgbm90IG51bGwsIGl0J3MgcmV0dXJuIGJ5IHRoZSB7QGxpbmsgI2dldENvbnRlbnR9CisgICAgICogbWV0aG9kLiAgVGhlIHtAbGluayAjZ2V0Q29udGVudH0gbWV0aG9kIHNldHMgdGhpcyBmaWVsZCBpZiBpdAorICAgICAqIHdvdWxkIHJldHVybiBhIE11bHRpcGFydCBvciBNaW1lTWVzc2FnZSBvYmplY3QuICBUaGlzIGZpZWxkIGlzCisgICAgICogaXMgY2xlYXJlZCBieSB0aGUge0BsaW5rICNzZXREYXRhSGFuZGxlcn0gbWV0aG9kLgorICAgICAqCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNQorICAgICAqLworICAgIHByb3RlY3RlZCBPYmplY3QgY2FjaGVkQ29udGVudDsKKworICAgIC8vIFVzZWQgdG8gcGFyc2UgZGF0ZXMKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNYWlsRGF0ZUZvcm1hdCBtYWlsRGF0ZUZvcm1hdCA9IG5ldyBNYWlsRGF0ZUZvcm1hdCgpOworCisgICAgLy8gU2hvdWxkIGFkZHJlc3NlcyBpbiBoZWFkZXJzIGJlIHBhcnNlZCBpbiAic3RyaWN0IiBtb2RlPworICAgIHByaXZhdGUgYm9vbGVhbiBzdHJpY3QgPSB0cnVlOworICAgIC8vIElzIFVURi04IGFsbG93ZWQgaW4gaGVhZGVycz8KKyAgICBwcml2YXRlIGJvb2xlYW4gYWxsb3d1dGY4ID0gZmFsc2U7CisKKyAgICAvKioKKyAgICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiBBbiBlbXB0eSBtZXNzYWdlIG9iamVjdCBpcyBjcmVhdGVkLgorICAgICAqIFRoZSA8Y29kZT5oZWFkZXJzPC9jb2RlPiBmaWVsZCBpcyBzZXQgdG8gYW4gZW1wdHkgSW50ZXJuZXRIZWFkZXJzCisgICAgICogb2JqZWN0LiBUaGUgPGNvZGU+ZmxhZ3M8L2NvZGU+IGZpZWxkIGlzIHNldCB0byBhbiBlbXB0eSBGbGFncworICAgICAqIG9iamVjdC4gVGhlIDxjb2RlPm1vZGlmaWVkPC9jb2RlPiBmbGFnIGlzIHNldCB0byB0cnVlLgorICAgICAqCisgICAgICogQHBhcmFtCXNlc3Npb24JdGhlIFNlc3NzaW9uCisgICAgICovCisgICAgcHVibGljIE1pbWVNZXNzYWdlKFNlc3Npb24gc2Vzc2lvbikgeworCXN1cGVyKHNlc3Npb24pOworCW1vZGlmaWVkID0gdHJ1ZTsKKwloZWFkZXJzID0gbmV3IEludGVybmV0SGVhZGVycygpOworCWZsYWdzID0gbmV3IEZsYWdzKCk7CS8vIGVtcHR5IGZsYWdzIG9iamVjdAorCWluaXRTdHJpY3QoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgTWltZU1lc3NhZ2UgYnkgcmVhZGluZyBhbmQgcGFyc2luZyB0aGUgZGF0YSBmcm9tIHRoZQorICAgICAqIHNwZWNpZmllZCBNSU1FIElucHV0U3RyZWFtLiBUaGUgSW5wdXRTdHJlYW0gd2lsbCBiZSBsZWZ0IHBvc2l0aW9uZWQKKyAgICAgKiBhdCB0aGUgZW5kIG9mIHRoZSBkYXRhIGZvciB0aGUgbWVzc2FnZS4gTm90ZSB0aGF0IHRoZSBpbnB1dCBzdHJlYW0KKyAgICAgKiBwYXJzZSBpcyBkb25lIHdpdGhpbiB0aGlzIGNvbnN0cnVjdG9yIGl0c2VsZi4gPHA+CisgICAgICoKKyAgICAgKiBUaGUgaW5wdXQgc3RyZWFtIGNvbnRhaW5zIGFuIGVudGlyZSBNSU1FIGZvcm1hdHRlZCBtZXNzYWdlIHdpdGgKKyAgICAgKiBoZWFkZXJzIGFuZCBkYXRhLgorICAgICAqCisgICAgICogQHBhcmFtIHNlc3Npb24JU2Vzc2lvbiBvYmplY3QgZm9yIHRoaXMgbWVzc2FnZQorICAgICAqIEBwYXJhbSBpcwl0aGUgbWVzc2FnZSBpbnB1dCBzdHJlYW0KKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgTWltZU1lc3NhZ2UoU2Vzc2lvbiBzZXNzaW9uLCBJbnB1dFN0cmVhbSBpcykgCisJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlzdXBlcihzZXNzaW9uKTsKKwlmbGFncyA9IG5ldyBGbGFncygpOyAvLyBlbXB0eSBGbGFncyBvYmplY3QKKwlpbml0U3RyaWN0KCk7CisJcGFyc2UoaXMpOworCXNhdmVkID0gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IE1pbWVNZXNzYWdlIHdpdGggY29udGVudCBpbml0aWFsaXplZCBmcm9tIHRoZQorICAgICAqIDxjb2RlPnNvdXJjZTwvY29kZT4gTWltZU1lc3NhZ2UuICBUaGUgbmV3IG1lc3NhZ2UgaXMgaW5kZXBlbmRlbnQKKyAgICAgKiBvZiB0aGUgb3JpZ2luYWwuIDxwPgorICAgICAqCisgICAgICogTm90ZTogVGhlIGN1cnJlbnQgaW1wbGVtZW50YXRpb24gaXMgcmF0aGVyIGluZWZmaWNpZW50LCBjb3B5aW5nCisgICAgICogdGhlIGRhdGEgbW9yZSB0aW1lcyB0aGFuIHN0cmljdGx5IG5lY2Vzc2FyeS4KKyAgICAgKgorICAgICAqIEBwYXJhbQlzb3VyY2UJdGhlIG1lc3NhZ2UgdG8gY29weSBjb250ZW50IGZyb20KKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuMgorICAgICAqLworICAgIHB1YmxpYyBNaW1lTWVzc2FnZShNaW1lTWVzc2FnZSBzb3VyY2UpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXN1cGVyKHNvdXJjZS5zZXNzaW9uKTsKKwlmbGFncyA9IHNvdXJjZS5nZXRGbGFncygpOworCWlmIChmbGFncyA9PSBudWxsKQkvLyBtYWtlIHN1cmUgZmxhZ3MgaXMgYWx3YXlzIHNldAorCSAgICBmbGFncyA9IG5ldyBGbGFncygpOworCUJ5dGVBcnJheU91dHB1dFN0cmVhbSBib3M7CisJaW50IHNpemUgPSBzb3VyY2UuZ2V0U2l6ZSgpOworCWlmIChzaXplID4gMCkKKwkgICAgYm9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbShzaXplKTsKKwllbHNlCisJICAgIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKwl0cnkgeworCSAgICBzdHJpY3QgPSBzb3VyY2Uuc3RyaWN0OworCSAgICBzb3VyY2Uud3JpdGVUbyhib3MpOworCSAgICBib3MuY2xvc2UoKTsKKwkgICAgU2hhcmVkQnl0ZUFycmF5SW5wdXRTdHJlYW0gYmlzID0KKwkJCSAgICBuZXcgU2hhcmVkQnl0ZUFycmF5SW5wdXRTdHJlYW0oYm9zLnRvQnl0ZUFycmF5KCkpOworCSAgICBwYXJzZShiaXMpOworCSAgICBiaXMuY2xvc2UoKTsKKwkgICAgc2F2ZWQgPSB0cnVlOworCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisJICAgIC8vIHNob3VsZCBuZXZlciBoYXBwZW4sIGJ1dCBqdXN0IGluIGNhc2UuLi4KKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiSU9FeGNlcHRpb24gd2hpbGUgY29weWluZyBtZXNzYWdlIiwKKwkJCQkJICAgIGV4KTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhbiBlbXB0eSBNaW1lTWVzc2FnZSBvYmplY3Qgd2l0aCB0aGUgZ2l2ZW4gRm9sZGVyCisgICAgICogYW5kIG1lc3NhZ2UgbnVtYmVyLiA8cD4KKyAgICAgKgorICAgICAqIFRoaXMgbWV0aG9kIGlzIGZvciBwcm92aWRlcnMgc3ViY2xhc3NpbmcgPGNvZGU+TWltZU1lc3NhZ2U8L2NvZGU+LgorICAgICAqCisgICAgICogQHBhcmFtCWZvbGRlcgl0aGUgRm9sZGVyIHRoaXMgbWVzc2FnZSBpcyBmcm9tCisgICAgICogQHBhcmFtCW1zZ251bQl0aGUgbnVtYmVyIG9mIHRoaXMgbWVzc2FnZQorICAgICAqLworICAgIHByb3RlY3RlZCBNaW1lTWVzc2FnZShGb2xkZXIgZm9sZGVyLCBpbnQgbXNnbnVtKSB7CisJc3VwZXIoZm9sZGVyLCBtc2dudW0pOworCWZsYWdzID0gbmV3IEZsYWdzKCk7ICAvLyBlbXB0eSBGbGFncyBvYmplY3QKKwlzYXZlZCA9IHRydWU7CisJaW5pdFN0cmljdCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBNaW1lTWVzc2FnZSBieSByZWFkaW5nIGFuZCBwYXJzaW5nIHRoZSBkYXRhIGZyb20gdGhlCisgICAgICogc3BlY2lmaWVkIE1JTUUgSW5wdXRTdHJlYW0uIFRoZSBJbnB1dFN0cmVhbSB3aWxsIGJlIGxlZnQgcG9zaXRpb25lZAorICAgICAqIGF0IHRoZSBlbmQgb2YgdGhlIGRhdGEgZm9yIHRoZSBtZXNzYWdlLiBOb3RlIHRoYXQgdGhlIGlucHV0IHN0cmVhbQorICAgICAqIHBhcnNlIGlzIGRvbmUgd2l0aGluIHRoaXMgY29uc3RydWN0b3IgaXRzZWxmLiA8cD4KKyAgICAgKgorICAgICAqIFRoaXMgbWV0aG9kIGlzIGZvciBwcm92aWRlcnMgc3ViY2xhc3NpbmcgPGNvZGU+TWltZU1lc3NhZ2U8L2NvZGU+LgorICAgICAqCisgICAgICogQHBhcmFtIGZvbGRlcglUaGUgY29udGFpbmluZyBmb2xkZXIuCisgICAgICogQHBhcmFtIGlzCXRoZSBtZXNzYWdlIGlucHV0IHN0cmVhbQorICAgICAqIEBwYXJhbSBtc2dudW0JTWVzc2FnZSBudW1iZXIgb2YgdGhpcyBtZXNzYWdlIHdpdGhpbiBpdHMgZm9sZGVyCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICovCisgICAgcHJvdGVjdGVkIE1pbWVNZXNzYWdlKEZvbGRlciBmb2xkZXIsIElucHV0U3RyZWFtIGlzLCBpbnQgbXNnbnVtKQorCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwl0aGlzKGZvbGRlciwgbXNnbnVtKTsKKwlpbml0U3RyaWN0KCk7CisJcGFyc2UoaXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBNaW1lTWVzc2FnZSBmcm9tIHRoZSBnaXZlbiBJbnRlcm5ldEhlYWRlcnMgb2JqZWN0CisgICAgICogYW5kIGNvbnRlbnQuCisgICAgICoKKyAgICAgKiBUaGlzIG1ldGhvZCBpcyBmb3IgcHJvdmlkZXJzIHN1YmNsYXNzaW5nIDxjb2RlPk1pbWVNZXNzYWdlPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBmb2xkZXIJVGhlIGNvbnRhaW5pbmcgZm9sZGVyLgorICAgICAqIEBwYXJhbSBoZWFkZXJzCVRoZSBoZWFkZXJzCisgICAgICogQHBhcmFtIGNvbnRlbnQJVGhlIG1lc3NhZ2UgY29udGVudAorICAgICAqIEBwYXJhbSBtc2dudW0JTWVzc2FnZSBudW1iZXIgb2YgdGhpcyBtZXNzYWdlIHdpdGhpbiBpdHMgZm9sZGVyCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICovCisgICAgcHJvdGVjdGVkIE1pbWVNZXNzYWdlKEZvbGRlciBmb2xkZXIsIEludGVybmV0SGVhZGVycyBoZWFkZXJzLAorCQlieXRlW10gY29udGVudCwgaW50IG1zZ251bSkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJdGhpcyhmb2xkZXIsIG1zZ251bSk7CisJdGhpcy5oZWFkZXJzID0gaGVhZGVyczsKKwl0aGlzLmNvbnRlbnQgPSBjb250ZW50OworCWluaXRTdHJpY3QoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHN0cmljdCBmbGFnIGJhc2VkIG9uIHByb3BlcnR5LgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBpbml0U3RyaWN0KCkgeworCWlmIChzZXNzaW9uICE9IG51bGwpIHsKKwkgICAgUHJvcGVydGllcyBwcm9wcyA9IHNlc3Npb24uZ2V0UHJvcGVydGllcygpOworCSAgICBzdHJpY3QgPSBQcm9wVXRpbC5nZXRCb29sZWFuUHJvcGVydHkocHJvcHMsCisJCQkJICAgICJtYWlsLm1pbWUuYWRkcmVzcy5zdHJpY3QiLCB0cnVlKTsKKwkgICAgYWxsb3d1dGY4ID0gUHJvcFV0aWwuZ2V0Qm9vbGVhblByb3BlcnR5KHByb3BzLAorCQkJCSAgICAibWFpbC5taW1lLmFsbG93dXRmOCIsIGZhbHNlKTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogUGFyc2UgdGhlIElucHV0U3RyZWFtIHNldHRpbmcgdGhlIDxjb2RlPmhlYWRlcnM8L2NvZGU+IGFuZAorICAgICAqIDxjb2RlPmNvbnRlbnQ8L2NvZGU+IGZpZWxkcyBhcHByb3ByaWF0ZWx5LiAgQWxzbyByZXNldHMgdGhlCisgICAgICogPGNvZGU+bW9kaWZpZWQ8L2NvZGU+IGZsYWcuIDxwPgorICAgICAqCisgICAgICogVGhpcyBtZXRob2QgaXMgaW50ZW5kZWQgZm9yIHVzZSBieSBzdWJjbGFzc2VzIHRoYXQgbmVlZCB0bworICAgICAqIGNvbnRyb2wgd2hlbiB0aGUgSW5wdXRTdHJlYW0gaXMgcGFyc2VkLgorICAgICAqCisgICAgICogQHBhcmFtIGlzCVRoZSBtZXNzYWdlIGlucHV0IHN0cmVhbQorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHBhcnNlKElucHV0U3RyZWFtIGlzKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKworCWlmICghKGlzIGluc3RhbmNlb2YgQnl0ZUFycmF5SW5wdXRTdHJlYW0pICYmCisJICAgICEoaXMgaW5zdGFuY2VvZiBCdWZmZXJlZElucHV0U3RyZWFtKSAmJgorCSAgICAhKGlzIGluc3RhbmNlb2YgU2hhcmVkSW5wdXRTdHJlYW0pKQorCSAgICBpcyA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKGlzKTsKKwkKKwloZWFkZXJzID0gY3JlYXRlSW50ZXJuZXRIZWFkZXJzKGlzKTsKKworCWlmIChpcyBpbnN0YW5jZW9mIFNoYXJlZElucHV0U3RyZWFtKSB7CisJICAgIFNoYXJlZElucHV0U3RyZWFtIHNpcyA9IChTaGFyZWRJbnB1dFN0cmVhbSlpczsKKwkgICAgY29udGVudFN0cmVhbSA9IHNpcy5uZXdTdHJlYW0oc2lzLmdldFBvc2l0aW9uKCksIC0xKTsKKwl9IGVsc2UgeworCSAgICB0cnkgeworCQljb250ZW50ID0gQVNDSUlVdGlsaXR5LmdldEJ5dGVzKGlzKTsKKwkgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9leCkgeworCQl0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKCJJT0V4Y2VwdGlvbiIsIGlvZXgpOworCSAgICB9CisJfQorCisJbW9kaWZpZWQgPSBmYWxzZTsKKyAgICB9CisKKyAgICAvKiogCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIFJGQyA4MjIgIkZyb20iIGhlYWRlciBmaWVsZHMuIElmIHRoaXMgCisgICAgICogaGVhZGVyIGZpZWxkIGlzIGFic2VudCwgdGhlICJTZW5kZXIiIGhlYWRlciBmaWVsZCBpcyB1c2VkLiAKKyAgICAgKiBJZiB0aGUgIlNlbmRlciIgaGVhZGVyIGZpZWxkIGlzIGFsc28gYWJzZW50LCA8Y29kZT5udWxsPC9jb2RlPgorICAgICAqIGlzIHJldHVybmVkLjxwPgorICAgICAqCisgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiB1c2VzIHRoZSA8Y29kZT5nZXRIZWFkZXI8L2NvZGU+IG1ldGhvZAorICAgICAqIHRvIG9idGFpbiB0aGUgcmVxdWlzaXRlIGhlYWRlciBmaWVsZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4JCUFkZHJlc3Mgb2JqZWN0CisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICogQHNlZQkjaGVhZGVycworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBBZGRyZXNzW10gZ2V0RnJvbSgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCUFkZHJlc3NbXSBhID0gZ2V0QWRkcmVzc0hlYWRlcigiRnJvbSIpOworCWlmIChhID09IG51bGwpCisJICAgIGEgPSBnZXRBZGRyZXNzSGVhZGVyKCJTZW5kZXIiKTsKKwkKKwlyZXR1cm4gYTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIFJGQyA4MjIgIkZyb20iIGhlYWRlciBmaWVsZC4gQW55IGV4aXN0aW5nIHZhbHVlcyBhcmUgCisgICAgICogcmVwbGFjZWQgd2l0aCB0aGUgZ2l2ZW4gYWRkcmVzcy4gSWYgYWRkcmVzcyBpcyA8Y29kZT5udWxsPC9jb2RlPiwKKyAgICAgKiB0aGlzIGhlYWRlciBpcyByZW1vdmVkLgorICAgICAqCisgICAgICogQHBhcmFtIGFkZHJlc3MJdGhlIHNlbmRlciBvZiB0aGlzIG1lc3NhZ2UKKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxXcml0ZUV4Y2VwdGlvbiBpZiB0aGUgdW5kZXJseWluZworICAgICAqCQkJaW1wbGVtZW50YXRpb24gZG9lcyBub3Qgc3VwcG9ydCBtb2RpZmljYXRpb24KKyAgICAgKgkJCW9mIGV4aXN0aW5nIHZhbHVlcworICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgbWVzc2FnZSBpcworICAgICAqCQkJb2J0YWluZWQgZnJvbSBhIFJFQURfT05MWSBmb2xkZXIuCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0RnJvbShBZGRyZXNzIGFkZHJlc3MpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWlmIChhZGRyZXNzID09IG51bGwpCisJICAgIHJlbW92ZUhlYWRlcigiRnJvbSIpOworCWVsc2UKKwkgICAgc2V0SGVhZGVyKCJGcm9tIiwgTWltZVV0aWxpdHkuZm9sZCg2LCBhZGRyZXNzLnRvU3RyaW5nKCkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIFJGQyA4MjIgIkZyb20iIGhlYWRlciBmaWVsZC4gQW55IGV4aXN0aW5nIHZhbHVlcyBhcmUgCisgICAgICogcmVwbGFjZWQgd2l0aCB0aGUgZ2l2ZW4gYWRkcmVzc2VzLiBJZiBhZGRyZXNzIGlzIDxjb2RlPm51bGw8L2NvZGU+LAorICAgICAqIHRoaXMgaGVhZGVyIGlzIHJlbW92ZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWRkcmVzcwl0aGUgc2VuZGVyKHMpIG9mIHRoaXMgbWVzc2FnZQorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFdyaXRlRXhjZXB0aW9uIGlmIHRoZSB1bmRlcmx5aW5nCisgICAgICoJCQlpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IG1vZGlmaWNhdGlvbgorICAgICAqCQkJb2YgZXhpc3RpbmcgdmFsdWVzCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBtZXNzYWdlIGlzCisgICAgICoJCQlvYnRhaW5lZCBmcm9tIGEgUkVBRF9PTkxZIGZvbGRlci4KKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKiBAc2luY2UJCUp2YU1haWwgMS41CisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RnJvbShTdHJpbmcgYWRkcmVzcykgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKGFkZHJlc3MgPT0gbnVsbCkKKwkgICAgcmVtb3ZlSGVhZGVyKCJGcm9tIik7CisJZWxzZQorCSAgICBzZXRBZGRyZXNzSGVhZGVyKCJGcm9tIiwgSW50ZXJuZXRBZGRyZXNzLnBhcnNlKGFkZHJlc3MpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIFJGQyA4MjIgIkZyb20iIGhlYWRlciBmaWVsZCB1c2luZyB0aGUgdmFsdWUgb2YgdGhlCisgICAgICogPGNvZGU+SW50ZXJuZXRBZGRyZXNzLmdldExvY2FsQWRkcmVzczwvY29kZT4gbWV0aG9kLgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsV3JpdGVFeGNlcHRpb24gaWYgdGhlIHVuZGVybHlpbmcKKyAgICAgKgkJCWltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uCisgICAgICoJCQlvZiBleGlzdGluZyB2YWx1ZXMKKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIG1lc3NhZ2UgaXMKKyAgICAgKgkJCW9idGFpbmVkIGZyb20gYSBSRUFEX09OTFkgZm9sZGVyLgorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBvdGhlciBmYWlsdXJlcworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldEZyb20oKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlJbnRlcm5ldEFkZHJlc3MgbWUgPSBudWxsOworCXRyeSB7CisJICAgIG1lID0gSW50ZXJuZXRBZGRyZXNzLl9nZXRMb2NhbEFkZHJlc3Moc2Vzc2lvbik7CisJfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJICAgIC8vIGlmIGFueXRoaW5nIGdvZXMgd3JvbmcgKFNlY3VyaXR5RXhjZXB0aW9uLCBVbmtub3duSG9zdEV4Y2VwdGlvbiksCisJICAgIC8vIGNoYWluIHRoZSBleGNlcHRpb24KKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiTm8gRnJvbSBhZGRyZXNzIiwgZXgpOworCX0KKwlpZiAobWUgIT0gbnVsbCkKKwkgICAgc2V0RnJvbShtZSk7CisJZWxzZQorCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKCJObyBGcm9tIGFkZHJlc3MiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGQgdGhlIHNwZWNpZmllZCBhZGRyZXNzZXMgdG8gdGhlIGV4aXN0aW5nICJGcm9tIiBmaWVsZC4gSWYKKyAgICAgKiB0aGUgIkZyb20iIGZpZWxkIGRvZXMgbm90IGFscmVhZHkgZXhpc3QsIGl0IGlzIGNyZWF0ZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWRkcmVzc2VzCXRoZSBzZW5kZXJzIG9mIHRoaXMgbWVzc2FnZQorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFdyaXRlRXhjZXB0aW9uIGlmIHRoZSB1bmRlcmx5aW5nCisgICAgICoJCQlpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IG1vZGlmaWNhdGlvbgorICAgICAqCQkJb2YgZXhpc3RpbmcgdmFsdWVzCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBtZXNzYWdlIGlzCisgICAgICoJCQlvYnRhaW5lZCBmcm9tIGEgUkVBRF9PTkxZIGZvbGRlci4KKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBhZGRGcm9tKEFkZHJlc3NbXSBhZGRyZXNzZXMpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWFkZEFkZHJlc3NIZWFkZXIoIkZyb20iLCBhZGRyZXNzZXMpOworICAgIH0KKworICAgIC8qKiAKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgUkZDIDgyMiAiU2VuZGVyIiBoZWFkZXIgZmllbGQuCisgICAgICogSWYgdGhlICJTZW5kZXIiIGhlYWRlciBmaWVsZCBpcyBhYnNlbnQsIDxjb2RlPm51bGw8L2NvZGU+CisgICAgICogaXMgcmV0dXJuZWQuPHA+CisgICAgICoKKyAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIHVzZXMgdGhlIDxjb2RlPmdldEhlYWRlcjwvY29kZT4gbWV0aG9kCisgICAgICogdG8gb2J0YWluIHRoZSByZXF1aXNpdGUgaGVhZGVyIGZpZWxkLgorICAgICAqCisgICAgICogQHJldHVybgkJQWRkcmVzcyBvYmplY3QKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKiBAc2VlCQkjaGVhZGVycworICAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS4zCisgICAgICovCisgICAgcHVibGljIEFkZHJlc3MgZ2V0U2VuZGVyKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJQWRkcmVzc1tdIGEgPSBnZXRBZGRyZXNzSGVhZGVyKCJTZW5kZXIiKTsKKwlpZiAoYSA9PSBudWxsIHx8IGEubGVuZ3RoID09IDApCisJICAgIHJldHVybiBudWxsOworCXJldHVybiBhWzBdOwkvLyB0aGVyZSBjYW4gYmUgb25seSBvbmUKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIFJGQyA4MjIgIlNlbmRlciIgaGVhZGVyIGZpZWxkLiBBbnkgZXhpc3RpbmcgdmFsdWVzIGFyZSAKKyAgICAgKiByZXBsYWNlZCB3aXRoIHRoZSBnaXZlbiBhZGRyZXNzLiBJZiBhZGRyZXNzIGlzIDxjb2RlPm51bGw8L2NvZGU+LAorICAgICAqIHRoaXMgaGVhZGVyIGlzIHJlbW92ZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWRkcmVzcwl0aGUgc2VuZGVyIG9mIHRoaXMgbWVzc2FnZQorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFdyaXRlRXhjZXB0aW9uIGlmIHRoZSB1bmRlcmx5aW5nCisgICAgICoJCQlpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IG1vZGlmaWNhdGlvbgorICAgICAqCQkJb2YgZXhpc3RpbmcgdmFsdWVzCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBtZXNzYWdlIGlzCisgICAgICoJCQlvYnRhaW5lZCBmcm9tIGEgUkVBRF9PTkxZIGZvbGRlci4KKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuMworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFNlbmRlcihBZGRyZXNzIGFkZHJlc3MpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWlmIChhZGRyZXNzID09IG51bGwpCisJICAgIHJlbW92ZUhlYWRlcigiU2VuZGVyIik7CisJZWxzZQorCSAgICBzZXRIZWFkZXIoIlNlbmRlciIsIE1pbWVVdGlsaXR5LmZvbGQoOCwgYWRkcmVzcy50b1N0cmluZygpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBpbm5lciBjbGFzcyBleHRlbmRzIHRoZSBqYXZheC5tYWlsLk1lc3NhZ2UuUmVjaXBpZW50VHlwZQorICAgICAqIGNsYXNzIHRvIGFkZCBhZGRpdGlvbmFsIFJlY2lwaWVudFR5cGVzLiBUaGUgb25lIGFkZGl0aW9uYWwKKyAgICAgKiBSZWNpcGllbnRUeXBlIGN1cnJlbnRseSBkZWZpbmVkIGhlcmUgaXMgTkVXU0dST1VQUy4KKyAgICAgKgorICAgICAqIEBzZWUgamF2YXgubWFpbC5NZXNzYWdlLlJlY2lwaWVudFR5cGUKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFJlY2lwaWVudFR5cGUgZXh0ZW5kcyBNZXNzYWdlLlJlY2lwaWVudFR5cGUgeworCisJcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTU0NjgyOTA3MDE3MTQzOTU1NDNMOworCisJLyoqCisJICogVGhlICJOZXdzZ3JvdXAiIChVc2VuZXQgbmV3cykgcmVjaXBpZW50cy4KKwkgKi8KKwlwdWJsaWMgc3RhdGljIGZpbmFsIFJlY2lwaWVudFR5cGUgTkVXU0dST1VQUyA9CisJCQkJCW5ldyBSZWNpcGllbnRUeXBlKCJOZXdzZ3JvdXBzIik7CisJcHJvdGVjdGVkIFJlY2lwaWVudFR5cGUoU3RyaW5nIHR5cGUpIHsKKwkgICAgc3VwZXIodHlwZSk7CisJfQorCisJQE92ZXJyaWRlCisJcHJvdGVjdGVkIE9iamVjdCByZWFkUmVzb2x2ZSgpIHRocm93cyBPYmplY3RTdHJlYW1FeGNlcHRpb24geworCSAgICBpZiAodHlwZS5lcXVhbHMoIk5ld3Nncm91cHMiKSkKKwkJcmV0dXJuIE5FV1NHUk9VUFM7CisJICAgIGVsc2UKKwkJcmV0dXJuIHN1cGVyLnJlYWRSZXNvbHZlKCk7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHJlY2VwaWVudHMgc3BlY2lmaWVkIGJ5IHRoZSB0eXBlLiBUaGUgbWFwcGluZworICAgICAqIGJldHdlZW4gdGhlIHR5cGUgYW5kIHRoZSBjb3JyZXNwb25kaW5nIFJGQyA4MjIgaGVhZGVyIGlzCisgICAgICogYXMgZm9sbG93czoKKyAgICAgKiA8cHJlPgorICAgICAqCQlNZXNzYWdlLlJlY2lwaWVudFR5cGUuVE8JCSJUbyIKKyAgICAgKgkJTWVzc2FnZS5SZWNpcGllbnRUeXBlLkNDCQkiQ2MiCisgICAgICoJCU1lc3NhZ2UuUmVjaXBpZW50VHlwZS5CQ0MJCSJCY2MiCisgICAgICoJCU1pbWVNZXNzYWdlLlJlY2lwaWVudFR5cGUuTkVXU0dST1VQUwkiTmV3c2dyb3VwcyIKKyAgICAgKiA8L3ByZT48YnI+CisgICAgICoKKyAgICAgKiBSZXR1cm5zIG51bGwgaWYgdGhlIGhlYWRlciBzcGVjaWZpZWQgYnkgdGhlIHR5cGUgaXMgbm90IGZvdW5kCisgICAgICogb3IgaWYgaXRzIHZhbHVlIGlzIGVtcHR5LiA8cD4KKyAgICAgKgorICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gdXNlcyB0aGUgPGNvZGU+Z2V0SGVhZGVyPC9jb2RlPiBtZXRob2QKKyAgICAgKiB0byBvYnRhaW4gdGhlIHJlcXVpc2l0ZSBoZWFkZXIgZmllbGQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gICAgICAgICAgIHR5cGUJVHlwZSBvZiByZWNlcGllbnQKKyAgICAgKiBAcmV0dXJuICAgICAgICAgIGFycmF5IG9mIEFkZHJlc3Mgb2JqZWN0cworICAgICAqIEBleGNlcHRpb24gICAgICAgTWVzc2FnaW5nRXhjZXB0aW9uIGlmIGhlYWRlciBjb3VsZCBub3QKKyAgICAgKiAgICAgICAgICAgICAgICAgIGJlIHJldHJpZXZlZAorICAgICAqIEBleGNlcHRpb24gICAgICAgQWRkcmVzc0V4Y2VwdGlvbiBpZiB0aGUgaGVhZGVyIGlzIG1pc2Zvcm1hdHRlZAorICAgICAqIEBzZWUJCSNoZWFkZXJzCisgICAgICogQHNlZQkJamF2YXgubWFpbC5NZXNzYWdlLlJlY2lwaWVudFR5cGUjVE8KKyAgICAgKiBAc2VlCQlqYXZheC5tYWlsLk1lc3NhZ2UuUmVjaXBpZW50VHlwZSNDQworICAgICAqIEBzZWUJCWphdmF4Lm1haWwuTWVzc2FnZS5SZWNpcGllbnRUeXBlI0JDQworICAgICAqIEBzZWUJCWphdmF4Lm1haWwuaW50ZXJuZXQuTWltZU1lc3NhZ2UuUmVjaXBpZW50VHlwZSNORVdTR1JPVVBTCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEFkZHJlc3NbXSBnZXRSZWNpcGllbnRzKE1lc3NhZ2UuUmVjaXBpZW50VHlwZSB0eXBlKQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWlmICh0eXBlID09IFJlY2lwaWVudFR5cGUuTkVXU0dST1VQUykgeworCSAgICBTdHJpbmcgcyA9IGdldEhlYWRlcigiTmV3c2dyb3VwcyIsICIsIik7CisJICAgIHJldHVybiAocyA9PSBudWxsKSA/IG51bGwgOiBOZXdzQWRkcmVzcy5wYXJzZShzKTsKKwl9IGVsc2UKKwkgICAgcmV0dXJuIGdldEFkZHJlc3NIZWFkZXIoZ2V0SGVhZGVyTmFtZSh0eXBlKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IGFsbCB0aGUgcmVjaXBpZW50IGFkZHJlc3NlcyBmb3IgdGhlIG1lc3NhZ2UuCisgICAgICogRXh0cmFjdHMgdGhlIFRPLCBDQywgQkNDLCBhbmQgTkVXU0dST1VQUyByZWNpcGllbnRzLgorICAgICAqCisgICAgICogQHJldHVybiAgICAgICAgICBhcnJheSBvZiBBZGRyZXNzIG9iamVjdHMKKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIE1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKiBAc2VlCQlqYXZheC5tYWlsLk1lc3NhZ2UuUmVjaXBpZW50VHlwZSNUTworICAgICAqIEBzZWUJCWphdmF4Lm1haWwuTWVzc2FnZS5SZWNpcGllbnRUeXBlI0NDCisgICAgICogQHNlZQkJamF2YXgubWFpbC5NZXNzYWdlLlJlY2lwaWVudFR5cGUjQkNDCisgICAgICogQHNlZQkJamF2YXgubWFpbC5pbnRlcm5ldC5NaW1lTWVzc2FnZS5SZWNpcGllbnRUeXBlI05FV1NHUk9VUFMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQWRkcmVzc1tdIGdldEFsbFJlY2lwaWVudHMoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlBZGRyZXNzW10gYWxsID0gc3VwZXIuZ2V0QWxsUmVjaXBpZW50cygpOworCUFkZHJlc3NbXSBuZyA9IGdldFJlY2lwaWVudHMoUmVjaXBpZW50VHlwZS5ORVdTR1JPVVBTKTsKKworCWlmIChuZyA9PSBudWxsKQorCSAgICByZXR1cm4gYWxsOwkJLy8gdGhlIGNvbW1vbiBjYXNlCisJaWYgKGFsbCA9PSBudWxsKQorCSAgICByZXR1cm4gbmc7CQkvLyBhIHJhcmUgY2FzZQorCisJQWRkcmVzc1tdIGFkZHJlc3NlcyA9IG5ldyBBZGRyZXNzW2FsbC5sZW5ndGggKyBuZy5sZW5ndGhdOworCVN5c3RlbS5hcnJheWNvcHkoYWxsLCAwLCBhZGRyZXNzZXMsIDAsIGFsbC5sZW5ndGgpOworCVN5c3RlbS5hcnJheWNvcHkobmcsIDAsIGFkZHJlc3NlcywgYWxsLmxlbmd0aCwgbmcubGVuZ3RoKTsKKwlyZXR1cm4gYWRkcmVzc2VzOworICAgIH0KKwkKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHNwZWNpZmllZCByZWNpcGllbnQgdHlwZSB0byB0aGUgZ2l2ZW4gYWRkcmVzc2VzLgorICAgICAqIElmIHRoZSBhZGRyZXNzIHBhcmFtZXRlciBpcyA8Y29kZT5udWxsPC9jb2RlPiwgdGhlIGNvcnJlc3BvbmRpbmcKKyAgICAgKiByZWNpcGllbnQgZmllbGQgaXMgcmVtb3ZlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0eXBlCVJlY2lwaWVudCB0eXBlCisgICAgICogQHBhcmFtIGFkZHJlc3NlcwlBZGRyZXNzZXMKKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxXcml0ZUV4Y2VwdGlvbiBpZiB0aGUgdW5kZXJseWluZworICAgICAqCQkJaW1wbGVtZW50YXRpb24gZG9lcyBub3Qgc3VwcG9ydCBtb2RpZmljYXRpb24KKyAgICAgKgkJCW9mIGV4aXN0aW5nIHZhbHVlcworICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgbWVzc2FnZSBpcworICAgICAqCQkJb2J0YWluZWQgZnJvbSBhIFJFQURfT05MWSBmb2xkZXIuCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICogQHNlZQkJI2dldFJlY2lwaWVudHMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRSZWNpcGllbnRzKE1lc3NhZ2UuUmVjaXBpZW50VHlwZSB0eXBlLCBBZGRyZXNzW10gYWRkcmVzc2VzKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpZiAodHlwZSA9PSBSZWNpcGllbnRUeXBlLk5FV1NHUk9VUFMpIHsKKwkgICAgaWYgKGFkZHJlc3NlcyA9PSBudWxsIHx8IGFkZHJlc3Nlcy5sZW5ndGggPT0gMCkKKwkJcmVtb3ZlSGVhZGVyKCJOZXdzZ3JvdXBzIik7CisJICAgIGVsc2UKKwkJc2V0SGVhZGVyKCJOZXdzZ3JvdXBzIiwgTmV3c0FkZHJlc3MudG9TdHJpbmcoYWRkcmVzc2VzKSk7CisJfSBlbHNlCisJICAgIHNldEFkZHJlc3NIZWFkZXIoZ2V0SGVhZGVyTmFtZSh0eXBlKSwgYWRkcmVzc2VzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHNwZWNpZmllZCByZWNpcGllbnQgdHlwZSB0byB0aGUgZ2l2ZW4gYWRkcmVzc2VzLgorICAgICAqIElmIHRoZSBhZGRyZXNzIHBhcmFtZXRlciBpcyA8Y29kZT5udWxsPC9jb2RlPiwgdGhlIGNvcnJlc3BvbmRpbmcKKyAgICAgKiByZWNpcGllbnQgZmllbGQgaXMgcmVtb3ZlZC4KKyAgICAgKiAgIAorICAgICAqIEBwYXJhbSB0eXBlICAgICAgUmVjaXBpZW50IHR5cGUKKyAgICAgKiBAcGFyYW0gYWRkcmVzc2VzIEFkZHJlc3NlcworICAgICAqIEBleGNlcHRpb24gICAgICAgQWRkcmVzc0V4Y2VwdGlvbiBpZiB0aGUgYXR0ZW1wdCB0byBwYXJzZSB0aGUKKyAgICAgKiAgICAgICAgICAgICAgICAgIGFkZHJlc3NlcyBTdHJpbmcgZmFpbHMKKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIElsbGVnYWxXcml0ZUV4Y2VwdGlvbiBpZiB0aGUgdW5kZXJseWluZworICAgICAqICAgICAgICAgICAgICAgICAgaW1wbGVtZW50YXRpb24gZG9lcyBub3Qgc3VwcG9ydCBtb2RpZmljYXRpb24KKyAgICAgKiAgICAgICAgICAgICAgICAgIG9mIGV4aXN0aW5nIHZhbHVlcworICAgICAqIEBleGNlcHRpb24gICAgICAgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgbWVzc2FnZSBpcworICAgICAqICAgICAgICAgICAgICAgICAgb2J0YWluZWQgZnJvbSBhIFJFQURfT05MWSBmb2xkZXIuCisgICAgICogQGV4Y2VwdGlvbiAgICAgICBNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICogQHNlZSAgICAgICAgICAgICAjZ2V0UmVjaXBpZW50cworICAgICAqIEBzaW5jZSAgICAgICAgICAgSmF2YU1haWwgMS4yCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UmVjaXBpZW50cyhNZXNzYWdlLlJlY2lwaWVudFR5cGUgdHlwZSwgU3RyaW5nIGFkZHJlc3NlcykKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisgICAgICAgIGlmICh0eXBlID09IFJlY2lwaWVudFR5cGUuTkVXU0dST1VQUykgeworICAgICAgICAgICAgaWYgKGFkZHJlc3NlcyA9PSBudWxsIHx8IGFkZHJlc3Nlcy5sZW5ndGgoKSA9PSAwKQorICAgICAgICAgICAgICAgIHJlbW92ZUhlYWRlcigiTmV3c2dyb3VwcyIpOworICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgIHNldEhlYWRlcigiTmV3c2dyb3VwcyIsIGFkZHJlc3Nlcyk7CisgICAgICAgIH0gZWxzZQorICAgICAgICAgICAgc2V0QWRkcmVzc0hlYWRlcihnZXRIZWFkZXJOYW1lKHR5cGUpLAorCQlhZGRyZXNzZXMgPT0gbnVsbCA/IG51bGwgOiBJbnRlcm5ldEFkZHJlc3MucGFyc2UoYWRkcmVzc2VzKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkIHRoZSBnaXZlbiBhZGRyZXNzZXMgdG8gdGhlIHNwZWNpZmllZCByZWNpcGllbnQgdHlwZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0eXBlCVJlY2lwaWVudCB0eXBlCisgICAgICogQHBhcmFtIGFkZHJlc3NlcwlBZGRyZXNzZXMKKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxXcml0ZUV4Y2VwdGlvbiBpZiB0aGUgdW5kZXJseWluZworICAgICAqCQkJaW1wbGVtZW50YXRpb24gZG9lcyBub3Qgc3VwcG9ydCBtb2RpZmljYXRpb24KKyAgICAgKgkJCW9mIGV4aXN0aW5nIHZhbHVlcworICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgbWVzc2FnZSBpcworICAgICAqCQkJb2J0YWluZWQgZnJvbSBhIFJFQURfT05MWSBmb2xkZXIuCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgYWRkUmVjaXBpZW50cyhNZXNzYWdlLlJlY2lwaWVudFR5cGUgdHlwZSwgQWRkcmVzc1tdIGFkZHJlc3NlcykKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKHR5cGUgPT0gUmVjaXBpZW50VHlwZS5ORVdTR1JPVVBTKSB7CisJICAgIFN0cmluZyBzID0gTmV3c0FkZHJlc3MudG9TdHJpbmcoYWRkcmVzc2VzKTsKKwkgICAgaWYgKHMgIT0gbnVsbCkKKwkJYWRkSGVhZGVyKCJOZXdzZ3JvdXBzIiwgcyk7CisJfSBlbHNlCisJICAgIGFkZEFkZHJlc3NIZWFkZXIoZ2V0SGVhZGVyTmFtZSh0eXBlKSwgYWRkcmVzc2VzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGQgdGhlIGdpdmVuIGFkZHJlc3NlcyB0byB0aGUgc3BlY2lmaWVkIHJlY2lwaWVudCB0eXBlLgorICAgICAqIAorICAgICAqIEBwYXJhbSB0eXBlICAgICAgUmVjaXBpZW50IHR5cGUKKyAgICAgKiBAcGFyYW0gYWRkcmVzc2VzIEFkZHJlc3NlcworICAgICAqIEBleGNlcHRpb24gICAgICAgQWRkcmVzc0V4Y2VwdGlvbiBpZiB0aGUgYXR0ZW1wdCB0byBwYXJzZSB0aGUKKyAgICAgKiAgICAgICAgICAgICAgICAgIGFkZHJlc3NlcyBTdHJpbmcgZmFpbHMKKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIElsbGVnYWxXcml0ZUV4Y2VwdGlvbiBpZiB0aGUgdW5kZXJseWluZworICAgICAqICAgICAgICAgICAgICAgICAgaW1wbGVtZW50YXRpb24gZG9lcyBub3Qgc3VwcG9ydCBtb2RpZmljYXRpb24KKyAgICAgKiAgICAgICAgICAgICAgICAgIG9mIGV4aXN0aW5nIHZhbHVlcworICAgICAqIEBleGNlcHRpb24gICAgICAgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgbWVzc2FnZSBpcworICAgICAqICAgICAgICAgICAgICAgICAgb2J0YWluZWQgZnJvbSBhIFJFQURfT05MWSBmb2xkZXIuCisgICAgICogQGV4Y2VwdGlvbiAgICAgICBNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICogQHNpbmNlICAgICAgICAgICBKYXZhTWFpbCAxLjIKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGRSZWNpcGllbnRzKE1lc3NhZ2UuUmVjaXBpZW50VHlwZSB0eXBlLCBTdHJpbmcgYWRkcmVzc2VzKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHR5cGUgPT0gUmVjaXBpZW50VHlwZS5ORVdTR1JPVVBTKSB7CisgICAgICAgICAgICBpZiAoYWRkcmVzc2VzICE9IG51bGwgJiYgYWRkcmVzc2VzLmxlbmd0aCgpICE9IDApCisgICAgICAgICAgICAgICAgYWRkSGVhZGVyKCJOZXdzZ3JvdXBzIiwgYWRkcmVzc2VzKTsKKyAgICAgICAgfSBlbHNlCisgICAgICAgICAgICBhZGRBZGRyZXNzSGVhZGVyKGdldEhlYWRlck5hbWUodHlwZSksCisJCSAgICBJbnRlcm5ldEFkZHJlc3MucGFyc2UoYWRkcmVzc2VzKSk7CisgICAgfQorIAorICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgdmFsdWUgb2YgdGhlIFJGQyA4MjIgIlJlcGx5LVRvIiBoZWFkZXIgZmllbGQuIElmCisgICAgICogdGhpcyBoZWFkZXIgaXMgdW5hdmFpbGFibGUgb3IgaXRzIHZhbHVlIGlzIGFic2VudCwgdGhlbgorICAgICAqIHRoZSA8Y29kZT5nZXRGcm9tPC9jb2RlPiBtZXRob2QgaXMgY2FsbGVkIGFuZCBpdHMgdmFsdWUgaXMgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIHVzZXMgdGhlIDxjb2RlPmdldEhlYWRlcjwvY29kZT4gbWV0aG9kCisgICAgICogdG8gb2J0YWluIHRoZSByZXF1aXNpdGUgaGVhZGVyIGZpZWxkLgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICogQHNlZQkJI2hlYWRlcnMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQWRkcmVzc1tdIGdldFJlcGx5VG8oKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlBZGRyZXNzW10gYSA9IGdldEFkZHJlc3NIZWFkZXIoIlJlcGx5LVRvIik7CisJaWYgKGEgPT0gbnVsbCB8fCBhLmxlbmd0aCA9PSAwKQorCSAgICBhID0gZ2V0RnJvbSgpOworCXJldHVybiBhOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgUkZDIDgyMiAiUmVwbHktVG8iIGhlYWRlciBmaWVsZC4gSWYgdGhlIGFkZHJlc3MgCisgICAgICogcGFyYW1ldGVyIGlzIDxjb2RlPm51bGw8L2NvZGU+LCB0aGlzIGhlYWRlciBpcyByZW1vdmVkLgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsV3JpdGVFeGNlcHRpb24gaWYgdGhlIHVuZGVybHlpbmcKKyAgICAgKgkJCWltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uCisgICAgICoJCQlvZiBleGlzdGluZyB2YWx1ZXMKKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIG1lc3NhZ2UgaXMKKyAgICAgKgkJCW9idGFpbmVkIGZyb20gYSBSRUFEX09OTFkgZm9sZGVyLgorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBvdGhlciBmYWlsdXJlcworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFJlcGx5VG8oQWRkcmVzc1tdIGFkZHJlc3NlcykgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJc2V0QWRkcmVzc0hlYWRlcigiUmVwbHktVG8iLCBhZGRyZXNzZXMpOworICAgIH0KKworICAgIC8vIENvbnZlbmllbmNlIG1ldGhvZCB0byBnZXQgYWRkcmVzc2VzCisgICAgcHJpdmF0ZSBBZGRyZXNzW10gZ2V0QWRkcmVzc0hlYWRlcihTdHJpbmcgbmFtZSkgCisJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlTdHJpbmcgcyA9IGdldEhlYWRlcihuYW1lLCAiLCIpOworCXJldHVybiAocyA9PSBudWxsKSA/IG51bGwgOiBJbnRlcm5ldEFkZHJlc3MucGFyc2VIZWFkZXIocywgc3RyaWN0KTsKKyAgICB9CisKKyAgICAvLyBDb252ZW5pZW5jZSBtZXRob2QgdG8gc2V0IGFkZHJlc3NlcworICAgIHByaXZhdGUgdm9pZCBzZXRBZGRyZXNzSGVhZGVyKFN0cmluZyBuYW1lLCBBZGRyZXNzW10gYWRkcmVzc2VzKQorCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJU3RyaW5nIHM7CisJaWYgKGFsbG93dXRmOCkKKwkgICAgcyA9IEludGVybmV0QWRkcmVzcy50b1VuaWNvZGVTdHJpbmcoYWRkcmVzc2VzLCBuYW1lLmxlbmd0aCgpICsgMik7CisJZWxzZQorCSAgICBzID0gSW50ZXJuZXRBZGRyZXNzLnRvU3RyaW5nKGFkZHJlc3NlcywgbmFtZS5sZW5ndGgoKSArIDIpOworCWlmIChzID09IG51bGwpCisJICAgIHJlbW92ZUhlYWRlcihuYW1lKTsKKwllbHNlCisJICAgIHNldEhlYWRlcihuYW1lLCBzKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYWRkQWRkcmVzc0hlYWRlcihTdHJpbmcgbmFtZSwgQWRkcmVzc1tdIGFkZHJlc3NlcykKKwkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWlmIChhZGRyZXNzZXMgPT0gbnVsbCB8fCBhZGRyZXNzZXMubGVuZ3RoID09IDApCisJICAgIHJldHVybjsKKwlBZGRyZXNzW10gYSA9IGdldEFkZHJlc3NIZWFkZXIobmFtZSk7CisJQWRkcmVzc1tdIGFuZXc7CisJaWYgKGEgPT0gbnVsbCB8fCBhLmxlbmd0aCA9PSAwKQorCSAgICBhbmV3ID0gYWRkcmVzc2VzOworCWVsc2UgeworCSAgICBhbmV3ID0gbmV3IEFkZHJlc3NbYS5sZW5ndGggKyBhZGRyZXNzZXMubGVuZ3RoXTsKKwkgICAgU3lzdGVtLmFycmF5Y29weShhLCAwLCBhbmV3LCAwLCBhLmxlbmd0aCk7CisJICAgIFN5c3RlbS5hcnJheWNvcHkoYWRkcmVzc2VzLCAwLCBhbmV3LCBhLmxlbmd0aCwgYWRkcmVzc2VzLmxlbmd0aCk7CisJfQorCVN0cmluZyBzOworCWlmIChhbGxvd3V0ZjgpCisJICAgIHMgPSBJbnRlcm5ldEFkZHJlc3MudG9Vbmljb2RlU3RyaW5nKGFuZXcsIG5hbWUubGVuZ3RoKCkgKyAyKTsKKwllbHNlCisJICAgIHMgPSBJbnRlcm5ldEFkZHJlc3MudG9TdHJpbmcoYW5ldywgbmFtZS5sZW5ndGgoKSArIDIpOworCWlmIChzID09IG51bGwpCisJICAgIHJldHVybjsKKwlzZXRIZWFkZXIobmFtZSwgcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlICJTdWJqZWN0IiBoZWFkZXIgZmllbGQuIFJldHVybnMgbnVsbCAKKyAgICAgKiBpZiB0aGUgc3ViamVjdCBmaWVsZCBpcyB1bmF2YWlsYWJsZSBvciBpdHMgdmFsdWUgaXMgYWJzZW50LiA8cD4KKyAgICAgKgorICAgICAqIElmIHRoZSBzdWJqZWN0IGlzIGVuY29kZWQgYXMgcGVyIFJGQyAyMDQ3LCBpdCBpcyBkZWNvZGVkIGFuZAorICAgICAqIGNvbnZlcnRlZCBpbnRvIFVuaWNvZGUuIElmIHRoZSBkZWNvZGluZyBvciBjb252ZXJzaW9uIGZhaWxzLCB0aGUKKyAgICAgKiByYXcgZGF0YSBpcyByZXR1cm5lZCBhcyBpcy4gPHA+CisgICAgICoKKyAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIHVzZXMgdGhlIDxjb2RlPmdldEhlYWRlcjwvY29kZT4gbWV0aG9kCisgICAgICogdG8gb2J0YWluIHRoZSByZXF1aXNpdGUgaGVhZGVyIGZpZWxkLgorICAgICAqCisgICAgICogQHJldHVybiAgICAgICAgICBTdWJqZWN0CisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICogQHNlZQkJI2hlYWRlcnMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldFN1YmplY3QoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlTdHJpbmcgcmF3dmFsdWUgPSBnZXRIZWFkZXIoIlN1YmplY3QiLCBudWxsKTsKKworCWlmIChyYXd2YWx1ZSA9PSBudWxsKQorCSAgICByZXR1cm4gbnVsbDsKKworCXRyeSB7CisJICAgIHJldHVybiBNaW1lVXRpbGl0eS5kZWNvZGVUZXh0KE1pbWVVdGlsaXR5LnVuZm9sZChyYXd2YWx1ZSkpOworCX0gY2F0Y2ggKFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gZXgpIHsKKwkgICAgcmV0dXJuIHJhd3ZhbHVlOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlICJTdWJqZWN0IiBoZWFkZXIgZmllbGQuIElmIHRoZSBzdWJqZWN0IGNvbnRhaW5zIAorICAgICAqIG5vbiBVUy1BU0NJSSBjaGFyYWN0ZXJzLCBpdCB3aWxsIGJlIGVuY29kZWQgdXNpbmcgdGhlIAorICAgICAqIHBsYXRmb3JtJ3MgZGVmYXVsdCBjaGFyc2V0LiBJZiB0aGUgc3ViamVjdCBjb250YWlucyBvbmx5IAorICAgICAqIFVTLUFTQ0lJIGNoYXJhY3RlcnMsIG5vIGVuY29kaW5nIGlzIGRvbmUgYW5kIGl0IGlzIHVzZWQgCisgICAgICogYXMtaXMuIElmIHRoZSBzdWJqZWN0IGlzIG51bGwsIHRoZSBleGlzdGluZyAiU3ViamVjdCIgZmllbGQKKyAgICAgKiBpcyByZW1vdmVkLiA8cD4KKyAgICAgKgorICAgICAqIFRoZSBhcHBsaWNhdGlvbiBtdXN0IGVuc3VyZSB0aGF0IHRoZSBzdWJqZWN0IGRvZXMgbm90IGNvbnRhaW4KKyAgICAgKiBhbnkgbGluZSBicmVha3MuIDxwPgorICAgICAqCisgICAgICogTm90ZSB0aGF0IGlmIHRoZSBjaGFyc2V0IGVuY29kaW5nIHByb2Nlc3MgZmFpbHMsIGEKKyAgICAgKiBNZXNzYWdpbmdFeGNlcHRpb24gaXMgdGhyb3duLCBhbmQgYW4gVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbgorICAgICAqIGlzIGluY2x1ZGVkIGluIHRoZSBjaGFpbiBvZiBuZXN0ZWQgZXhjZXB0aW9ucyB3aXRoaW4gdGhlCisgICAgICogTWVzc2FnaW5nRXhjZXB0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIAlzdWJqZWN0CQlUaGUgc3ViamVjdAorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFdyaXRlRXhjZXB0aW9uIGlmIHRoZSB1bmRlcmx5aW5nCisgICAgICoJCQlpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IG1vZGlmaWNhdGlvbgorICAgICAqCQkJb2YgZXhpc3RpbmcgdmFsdWVzCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBtZXNzYWdlIGlzCisgICAgICoJCQlvYnRhaW5lZCBmcm9tIGEgUkVBRF9PTkxZIGZvbGRlci4KKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRTdWJqZWN0KFN0cmluZyBzdWJqZWN0KSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlzZXRTdWJqZWN0KHN1YmplY3QsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgIlN1YmplY3QiIGhlYWRlciBmaWVsZC4gSWYgdGhlIHN1YmplY3QgY29udGFpbnMgbm9uIAorICAgICAqIFVTLUFTQ0lJIGNoYXJhY3RlcnMsIGl0IHdpbGwgYmUgZW5jb2RlZCB1c2luZyB0aGUgc3BlY2lmaWVkCisgICAgICogY2hhcnNldC4gSWYgdGhlIHN1YmplY3QgY29udGFpbnMgb25seSBVUy1BU0NJSSBjaGFyYWN0ZXJzLCBubyAKKyAgICAgKiBlbmNvZGluZyBpcyBkb25lIGFuZCBpdCBpcyB1c2VkIGFzLWlzLiBJZiB0aGUgc3ViamVjdCBpcyBudWxsLCAKKyAgICAgKiB0aGUgZXhpc3RpbmcgIlN1YmplY3QiIGhlYWRlciBmaWVsZCBpcyByZW1vdmVkLiA8cD4KKyAgICAgKgorICAgICAqIFRoZSBhcHBsaWNhdGlvbiBtdXN0IGVuc3VyZSB0aGF0IHRoZSBzdWJqZWN0IGRvZXMgbm90IGNvbnRhaW4KKyAgICAgKiBhbnkgbGluZSBicmVha3MuIDxwPgorICAgICAqCisgICAgICogTm90ZSB0aGF0IGlmIHRoZSBjaGFyc2V0IGVuY29kaW5nIHByb2Nlc3MgZmFpbHMsIGEKKyAgICAgKiBNZXNzYWdpbmdFeGNlcHRpb24gaXMgdGhyb3duLCBhbmQgYW4gVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbgorICAgICAqIGlzIGluY2x1ZGVkIGluIHRoZSBjaGFpbiBvZiBuZXN0ZWQgZXhjZXB0aW9ucyB3aXRoaW4gdGhlCisgICAgICogTWVzc2FnaW5nRXhjZXB0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtCXN1YmplY3QJCVRoZSBzdWJqZWN0CisgICAgICogQHBhcmFtCWNoYXJzZXQJCVRoZSBjaGFyc2V0IAorICAgICAqIEBleGNlcHRpb24JCUlsbGVnYWxXcml0ZUV4Y2VwdGlvbiBpZiB0aGUgdW5kZXJseWluZworICAgICAqCQkJCWltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uCisgICAgICoJCQkJb2YgZXhpc3RpbmcgdmFsdWVzCisgICAgICogQGV4Y2VwdGlvbgkJSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgbWVzc2FnZSBpcworICAgICAqCQkJCW9idGFpbmVkIGZyb20gYSBSRUFEX09OTFkgZm9sZGVyLgorICAgICAqIEBleGNlcHRpb24JCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRTdWJqZWN0KFN0cmluZyBzdWJqZWN0LCBTdHJpbmcgY2hhcnNldCkKKwkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWlmIChzdWJqZWN0ID09IG51bGwpIHsKKwkgICAgcmVtb3ZlSGVhZGVyKCJTdWJqZWN0Iik7CisJfSBlbHNlIHsKKwkgICAgdHJ5IHsKKwkJc2V0SGVhZGVyKCJTdWJqZWN0IiwgTWltZVV0aWxpdHkuZm9sZCg5LAorCQkgICAgTWltZVV0aWxpdHkuZW5jb2RlVGV4dChzdWJqZWN0LCBjaGFyc2V0LCBudWxsKSkpOworCSAgICB9IGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIHVleCkgeworCQl0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKCJFbmNvZGluZyBlcnJvciIsIHVleCk7CisJICAgIH0KKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIFJGQyA4MjIgIkRhdGUiIGZpZWxkLiBUaGlzIGlzIHRoZSBkYXRlIAorICAgICAqIG9uIHdoaWNoIHRoaXMgbWVzc2FnZSB3YXMgc2VudC4gUmV0dXJucyBudWxsIGlmIHRoaXMgZmllbGQgaXMgCisgICAgICogdW5hdmFpbGFibGUgb3IgaXRzIHZhbHVlIGlzIGFic2VudC4gPHA+CisgICAgICogCisgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiB1c2VzIHRoZSA8Y29kZT5nZXRIZWFkZXI8L2NvZGU+IG1ldGhvZAorICAgICAqIHRvIG9idGFpbiB0aGUgcmVxdWlzaXRlIGhlYWRlciBmaWVsZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gICAgICAgICAgVGhlIHNlbnQgRGF0ZQorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBEYXRlIGdldFNlbnREYXRlKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJU3RyaW5nIHMgPSBnZXRIZWFkZXIoIkRhdGUiLCBudWxsKTsKKwlpZiAocyAhPSBudWxsKSB7CisJICAgIHRyeSB7CisJCXN5bmNocm9uaXplZCAobWFpbERhdGVGb3JtYXQpIHsKKwkJICAgIHJldHVybiBtYWlsRGF0ZUZvcm1hdC5wYXJzZShzKTsKKwkJfQorCSAgICB9IGNhdGNoIChQYXJzZUV4Y2VwdGlvbiBwZXgpIHsKKwkJcmV0dXJuIG51bGw7CisJICAgIH0KKwl9CisJCisJcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBSRkMgODIyICJEYXRlIiBoZWFkZXIgZmllbGQuIFRoaXMgaXMgdGhlIGRhdGUgb24gd2hpY2ggdGhlCisgICAgICogY3JlYXRvciBvZiB0aGUgbWVzc2FnZSBpbmRpY2F0ZXMgdGhhdCB0aGUgbWVzc2FnZSBpcyBjb21wbGV0ZQorICAgICAqIGFuZCByZWFkeSBmb3IgZGVsaXZlcnkuIElmIHRoZSBkYXRlIHBhcmFtZXRlciBpcyAKKyAgICAgKiA8Y29kZT5udWxsPC9jb2RlPiwgdGhlIGV4aXN0aW5nICJEYXRlIiBmaWVsZCBpcyByZW1vdmVkLgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsV3JpdGVFeGNlcHRpb24gaWYgdGhlIHVuZGVybHlpbmcKKyAgICAgKgkJCWltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBtZXNzYWdlIGlzCisgICAgICoJCQlvYnRhaW5lZCBmcm9tIGEgUkVBRF9PTkxZIGZvbGRlci4KKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRTZW50RGF0ZShEYXRlIGQpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWlmIChkID09IG51bGwpCisJICAgIHJlbW92ZUhlYWRlcigiRGF0ZSIpOworCWVsc2UgeworCSAgICBzeW5jaHJvbml6ZWQgKG1haWxEYXRlRm9ybWF0KSB7CisJCXNldEhlYWRlcigiRGF0ZSIsIG1haWxEYXRlRm9ybWF0LmZvcm1hdChkKSk7CisJICAgIH0KKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgRGF0ZSBvbiB0aGlzIG1lc3NhZ2Ugd2FzIHJlY2VpdmVkLiBSZXR1cm5zIAorICAgICAqIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoaXMgZGF0ZSBjYW5ub3QgYmUgb2J0YWluZWQuIDxwPgorICAgICAqCisgICAgICogTm90ZSB0aGF0IFJGQyA4MjIgZG9lcyBub3QgZGVmaW5lIGEgZmllbGQgZm9yIHRoZSByZWNlaXZlZAorICAgICAqIGRhdGUuIEhlbmNlIG9ubHkgaW1wbGVtZW50YXRpb25zIHRoYXQgY2FuIHByb3ZpZGUgdGhpcyBkYXRlCisgICAgICogbmVlZCByZXR1cm4gYSB2YWxpZCB2YWx1ZS4gPHA+CisgICAgICoKKyAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIHJldHVybnMgPGNvZGU+bnVsbDwvY29kZT4uCisgICAgICoKKyAgICAgKiBAcmV0dXJuICAgICAgICAgIHRoZSBkYXRlIHRoaXMgbWVzc2FnZSB3YXMgcmVjZWl2ZWQKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRGF0ZSBnZXRSZWNlaXZlZERhdGUoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gbnVsbDsJCisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBzaXplIG9mIHRoZSBjb250ZW50IG9mIHRoaXMgbWVzc2FnZSBpbiBieXRlcy4gCisgICAgICogUmV0dXJuIC0xIGlmIHRoZSBzaXplIGNhbm5vdCBiZSBkZXRlcm1pbmVkLiA8cD4KKyAgICAgKgorICAgICAqIE5vdGUgdGhhdCB0aGlzIG51bWJlciBtYXkgbm90IGJlIGFuIGV4YWN0IG1lYXN1cmUgb2YgdGhlCisgICAgICogY29udGVudCBzaXplIGFuZCBtYXkgb3IgbWF5IG5vdCBhY2NvdW50IGZvciBhbnkgdHJhbnNmZXIKKyAgICAgKiBlbmNvZGluZyBvZiB0aGUgY29udGVudC4gPHA+CisgICAgICoKKyAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIHJldHVybnMgdGhlIHNpemUgb2YgdGhlIDxjb2RlPmNvbnRlbnQ8L2NvZGU+CisgICAgICogYXJyYXkgKGlmIG5vdCBudWxsKSwgb3IsIGlmIDxjb2RlPmNvbnRlbnRTdHJlYW08L2NvZGU+IGlzIG5vdAorICAgICAqIG51bGwsIGFuZCB0aGUgPGNvZGU+YXZhaWxhYmxlPC9jb2RlPiBtZXRob2QgcmV0dXJucyBhIHBvc2l0aXZlCisgICAgICogbnVtYmVyLCBpdCByZXR1cm5zIHRoYXQgbnVtYmVyIGFzIHRoZSBzaXplLiAgT3RoZXJ3aXNlLCBpdCByZXR1cm5zCisgICAgICogLTEuCisgICAgICoKKyAgICAgKiBAcmV0dXJuICAgICAgICAgIHNpemUgb2YgY29udGVudCBpbiBieXRlcworICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqLyAgCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBnZXRTaXplKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKGNvbnRlbnQgIT0gbnVsbCkKKwkgICAgcmV0dXJuIGNvbnRlbnQubGVuZ3RoOworCWlmIChjb250ZW50U3RyZWFtICE9IG51bGwpIHsKKwkgICAgdHJ5IHsKKwkJaW50IHNpemUgPSBjb250ZW50U3RyZWFtLmF2YWlsYWJsZSgpOworCQkvLyBvbmx5IGJlbGlldmUgdGhlIHNpemUgaWYgaXQncyBncmVhdGVyIHRoYW4gemVybywgc2luY2UgemVybworCQkvLyBpcyB0aGUgZGVmYXVsdCByZXR1cm5lZCBieSB0aGUgSW5wdXRTdHJlYW0gY2xhc3MgaXRzZWxmCisJCWlmIChzaXplID4gMCkKKwkJICAgIHJldHVybiBzaXplOworCSAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworCQkvLyBpZ25vcmUgaXQKKwkgICAgfQorCX0KKwlyZXR1cm4gLTE7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBudW1iZXIgb2YgbGluZXMgZm9yIHRoZSBjb250ZW50IG9mIHRoaXMgbWVzc2FnZS4KKyAgICAgKiBSZXR1cm4gLTEgaWYgdGhpcyBudW1iZXIgY2Fubm90IGJlIGRldGVybWluZWQuIDxwPgorICAgICAqCisgICAgICogTm90ZSB0aGF0IHRoaXMgbnVtYmVyIG1heSBub3QgYmUgYW4gZXhhY3QgbWVhc3VyZSBvZiB0aGUgCisgICAgICogY29udGVudCBsZW5ndGggYW5kIG1heSBvciBtYXkgbm90IGFjY291bnQgZm9yIGFueSB0cmFuc2ZlciAKKyAgICAgKiBlbmNvZGluZyBvZiB0aGUgY29udGVudC4gPHA+CisgICAgICoKKyAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIHJldHVybnMgLTEuCisgICAgICoKKyAgICAgKiBAcmV0dXJuICAgICAgICAgIG51bWJlciBvZiBsaW5lcyBpbiB0aGUgY29udGVudC4KKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKi8gIAorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgZ2V0TGluZUNvdW50KCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJcmV0dXJuIC0xOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIHRoZSBSRkMgODIyICJDb250ZW50LVR5cGUiIGhlYWRlciBmaWVsZC4gCisgICAgICogVGhpcyByZXByZXNlbnRzIHRoZSBjb250ZW50LXR5cGUgb2YgdGhlIGNvbnRlbnQgb2YgdGhpcyAKKyAgICAgKiBtZXNzYWdlLiBUaGlzIHZhbHVlIG11c3Qgbm90IGJlIG51bGwuIElmIHRoaXMgZmllbGQgaXMgCisgICAgICogdW5hdmFpbGFibGUsICJ0ZXh0L3BsYWluIiBzaG91bGQgYmUgcmV0dXJuZWQuIDxwPgorICAgICAqCisgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiB1c2VzIHRoZSA8Y29kZT5nZXRIZWFkZXI8L2NvZGU+IG1ldGhvZAorICAgICAqIHRvIG9idGFpbiB0aGUgcmVxdWlzaXRlIGhlYWRlciBmaWVsZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gICAgICAgICAgVGhlIENvbnRlbnRUeXBlIG9mIHRoaXMgcGFydAorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqIEBzZWUgICAgICAgICAgICAgamF2YXguYWN0aXZhdGlvbi5EYXRhSGFuZGxlcgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q29udGVudFR5cGUoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlTdHJpbmcgcyA9IGdldEhlYWRlcigiQ29udGVudC1UeXBlIiwgbnVsbCk7CisJcyA9IE1pbWVVdGlsLmNsZWFuQ29udGVudFR5cGUodGhpcywgcyk7CisJaWYgKHMgPT0gbnVsbCkKKwkgICAgcmV0dXJuICJ0ZXh0L3BsYWluIjsKKwlyZXR1cm4gczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJcyB0aGlzIFBhcnQgb2YgdGhlIHNwZWNpZmllZCBNSU1FIHR5cGU/ICBUaGlzIG1ldGhvZAorICAgICAqIGNvbXBhcmVzIDxzdHJvbmc+b25seSB0aGUgPGNvZGU+cHJpbWFyeVR5cGU8L2NvZGU+IGFuZCAKKyAgICAgKiA8Y29kZT5zdWJUeXBlPC9jb2RlPjwvc3Ryb25nPi4KKyAgICAgKiBUaGUgcGFyYW1ldGVycyBvZiB0aGUgY29udGVudCB0eXBlcyBhcmUgaWdub3JlZC4gPHA+CisgICAgICoKKyAgICAgKiBGb3IgZXhhbXBsZSwgdGhpcyBtZXRob2Qgd2lsbCByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gd2hlbgorICAgICAqIGNvbXBhcmluZyBhIFBhcnQgb2YgY29udGVudCB0eXBlIDxzdHJvbmc+InRleHQvcGxhaW4iPC9zdHJvbmc+CisgICAgICogd2l0aCA8c3Ryb25nPiJ0ZXh0L3BsYWluOyBjaGFyc2V0PWZvb2JhciI8L3N0cm9uZz4uIDxwPgorICAgICAqCisgICAgICogSWYgdGhlIDxjb2RlPnN1YlR5cGU8L2NvZGU+IG9mIDxjb2RlPm1pbWVUeXBlPC9jb2RlPiBpcyB0aGUKKyAgICAgKiBzcGVjaWFsIGNoYXJhY3RlciAnKicsIHRoZW4gdGhlIHN1YnR5cGUgaXMgaWdub3JlZCBkdXJpbmcgdGhlCisgICAgICogY29tcGFyaXNvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbQltaW1lVHlwZQl0aGUgTUlNRSB0eXBlIHRvIGNoZWNrCisgICAgICogQHJldHVybgkJCXRydWUgaWYgaXQgbWF0Y2hlcyB0aGUgTUlNRSB0eXBlCisgICAgICogQGV4Y2VwdGlvbgkJTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGlzTWltZVR5cGUoU3RyaW5nIG1pbWVUeXBlKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gTWltZUJvZHlQYXJ0LmlzTWltZVR5cGUodGhpcywgbWltZVR5cGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGRpc3Bvc2l0aW9uIGZyb20gdGhlICJDb250ZW50LURpc3Bvc2l0aW9uIiBoZWFkZXIgZmllbGQuCisgICAgICogVGhpcyByZXByZXNlbnRzIHRoZSBkaXNwb3NpdGlvbiBvZiB0aGlzIHBhcnQuIFRoZSBkaXNwb3NpdGlvbgorICAgICAqIGRlc2NyaWJlcyBob3cgdGhlIHBhcnQgc2hvdWxkIGJlIHByZXNlbnRlZCB0byB0aGUgdXNlci4gPHA+CisgICAgICoKKyAgICAgKiBJZiB0aGUgQ29udGVudC1EaXNwb3NpdGlvbiBmaWVsZCBpcyB1bmF2YWlsYWJsZSwgCisgICAgICogPGNvZGU+bnVsbDwvY29kZT4gaXMgcmV0dXJuZWQuIDxwPgorICAgICAqCisgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiB1c2VzIHRoZSA8Y29kZT5nZXRIZWFkZXI8L2NvZGU+IG1ldGhvZAorICAgICAqIHRvIG9idGFpbiB0aGUgcmVxdWlzaXRlIGhlYWRlciBmaWVsZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gICAgICAgICAgZGlzcG9zaXRpb24gb2YgdGhpcyBwYXJ0LCBvciBudWxsIGlmIHVua25vd24KKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldERpc3Bvc2l0aW9uKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJcmV0dXJuIE1pbWVCb2R5UGFydC5nZXREaXNwb3NpdGlvbih0aGlzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIGRpc3Bvc2l0aW9uIGluIHRoZSAiQ29udGVudC1EaXNwb3NpdGlvbiIgaGVhZGVyIGZpZWxkCisgICAgICogb2YgdGhpcyBib2R5IHBhcnQuICBJZiB0aGUgZGlzcG9zaXRpb24gaXMgbnVsbCwgYW55IGV4aXN0aW5nCisgICAgICogIkNvbnRlbnQtRGlzcG9zaXRpb24iIGhlYWRlciBmaWVsZCBpcyByZW1vdmVkLgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsV3JpdGVFeGNlcHRpb24gaWYgdGhlIHVuZGVybHlpbmcKKyAgICAgKgkJCWltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBtZXNzYWdlIGlzCisgICAgICoJCQlvYnRhaW5lZCBmcm9tIGEgUkVBRF9PTkxZIGZvbGRlci4KKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXREaXNwb3NpdGlvbihTdHJpbmcgZGlzcG9zaXRpb24pIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCU1pbWVCb2R5UGFydC5zZXREaXNwb3NpdGlvbih0aGlzLCBkaXNwb3NpdGlvbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY29udGVudCB0cmFuc2ZlciBlbmNvZGluZyBmcm9tIHRoZQorICAgICAqICJDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nIiBoZWFkZXIKKyAgICAgKiBmaWVsZC4gUmV0dXJucyA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGUgaGVhZGVyIGlzIHVuYXZhaWxhYmxlCisgICAgICogb3IgaXRzIHZhbHVlIGlzIGFic2VudC4gPHA+CisgICAgICoKKyAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIHVzZXMgdGhlIDxjb2RlPmdldEhlYWRlcjwvY29kZT4gbWV0aG9kCisgICAgICogdG8gb2J0YWluIHRoZSByZXF1aXNpdGUgaGVhZGVyIGZpZWxkLgorICAgICAqCisgICAgICogQHJldHVybiAgICAgICAgICBjb250ZW50LXRyYW5zZmVyLWVuY29kaW5nCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXRFbmNvZGluZygpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXJldHVybiBNaW1lQm9keVBhcnQuZ2V0RW5jb2RpbmcodGhpcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlICJDb250ZW50LUlEIiBoZWFkZXIgZmllbGQuIFJldHVybnMKKyAgICAgKiA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGUgZmllbGQgaXMgdW5hdmFpbGFibGUgb3IgaXRzIHZhbHVlIGlzIAorICAgICAqIGFic2VudC4gPHA+CisgICAgICoKKyAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIHVzZXMgdGhlIDxjb2RlPmdldEhlYWRlcjwvY29kZT4gbWV0aG9kCisgICAgICogdG8gb2J0YWluIHRoZSByZXF1aXNpdGUgaGVhZGVyIGZpZWxkLgorICAgICAqCisgICAgICogQHJldHVybiAgICAgICAgICBjb250ZW50LUlECisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXRDb250ZW50SUQoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gZ2V0SGVhZGVyKCJDb250ZW50LUlkIiwgbnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSAiQ29udGVudC1JRCIgaGVhZGVyIGZpZWxkIG9mIHRoaXMgTWVzc2FnZS4KKyAgICAgKiBJZiB0aGUgPGNvZGU+Y2lkPC9jb2RlPiBwYXJhbWV0ZXIgaXMgbnVsbCwgYW55IGV4aXN0aW5nIAorICAgICAqICJDb250ZW50LUlEIiBpcyByZW1vdmVkLgorICAgICAqCisgICAgICogQHBhcmFtCWNpZAl0aGUgY29udGVudCBJRAorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFdyaXRlRXhjZXB0aW9uIGlmIHRoZSB1bmRlcmx5aW5nCisgICAgICoJCQlpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IG1vZGlmaWNhdGlvbgorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgbWVzc2FnZSBpcworICAgICAqCQkJb2J0YWluZWQgZnJvbSBhIFJFQURfT05MWSBmb2xkZXIuCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q29udGVudElEKFN0cmluZyBjaWQpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWlmIChjaWQgPT0gbnVsbCkKKwkgICAgcmVtb3ZlSGVhZGVyKCJDb250ZW50LUlEIik7CisJZWxzZQorCSAgICBzZXRIZWFkZXIoIkNvbnRlbnQtSUQiLCBjaWQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgdmFsdWUgb2YgdGhlICJDb250ZW50LU1ENSIgaGVhZGVyIGZpZWxkLiBSZXR1cm5zIAorICAgICAqIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoaXMgZmllbGQgaXMgdW5hdmFpbGFibGUgb3IgaXRzIHZhbHVlCisgICAgICogaXMgYWJzZW50LiA8cD4KKyAgICAgKgorICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gdXNlcyB0aGUgPGNvZGU+Z2V0SGVhZGVyPC9jb2RlPiBtZXRob2QKKyAgICAgKiB0byBvYnRhaW4gdGhlIHJlcXVpc2l0ZSBoZWFkZXIgZmllbGQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuICAgICAgICAgIGNvbnRlbnQtTUQ1CisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXRDb250ZW50TUQ1KCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJcmV0dXJuIGdldEhlYWRlcigiQ29udGVudC1NRDUiLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlICJDb250ZW50LU1ENSIgaGVhZGVyIGZpZWxkIG9mIHRoaXMgTWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFdyaXRlRXhjZXB0aW9uIGlmIHRoZSB1bmRlcmx5aW5nCisgICAgICoJCQlpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IG1vZGlmaWNhdGlvbgorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgbWVzc2FnZSBpcworICAgICAqCQkJb2J0YWluZWQgZnJvbSBhIFJFQURfT05MWSBmb2xkZXIuCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0Q29udGVudE1ENShTdHJpbmcgbWQ1KSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlzZXRIZWFkZXIoIkNvbnRlbnQtTUQ1IiwgbWQ1KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSAiQ29udGVudC1EZXNjcmlwdGlvbiIgaGVhZGVyIGZpZWxkIG9mIHRoaXMgTWVzc2FnZS4KKyAgICAgKiBUaGlzIHR5cGljYWxseSBhc3NvY2lhdGVzIHNvbWUgZGVzY3JpcHRpdmUgaW5mb3JtYXRpb24gd2l0aCAKKyAgICAgKiB0aGlzIHBhcnQuIFJldHVybnMgbnVsbCBpZiB0aGlzIGZpZWxkIGlzIHVuYXZhaWxhYmxlIG9yIGl0cworICAgICAqIHZhbHVlIGlzIGFic2VudC4gPHA+CisgICAgICoKKyAgICAgKiBJZiB0aGUgQ29udGVudC1EZXNjcmlwdGlvbiBmaWVsZCBpcyBlbmNvZGVkIGFzIHBlciBSRkMgMjA0NywKKyAgICAgKiBpdCBpcyBkZWNvZGVkIGFuZCBjb252ZXJ0ZWQgaW50byBVbmljb2RlLiBJZiB0aGUgZGVjb2Rpbmcgb3IgCisgICAgICogY29udmVyc2lvbiBmYWlscywgdGhlIHJhdyBkYXRhIGlzIHJldHVybmVkIGFzLWlzIDxwPgorICAgICAqCisgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiB1c2VzIHRoZSA8Y29kZT5nZXRIZWFkZXI8L2NvZGU+IG1ldGhvZAorICAgICAqIHRvIG9idGFpbiB0aGUgcmVxdWlzaXRlIGhlYWRlciBmaWVsZC4KKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuCWNvbnRlbnQtZGVzY3JpcHRpb24KKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldERlc2NyaXB0aW9uKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJcmV0dXJuIE1pbWVCb2R5UGFydC5nZXREZXNjcmlwdGlvbih0aGlzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlICJDb250ZW50LURlc2NyaXB0aW9uIiBoZWFkZXIgZmllbGQgZm9yIHRoaXMgTWVzc2FnZS4KKyAgICAgKiBJZiB0aGUgZGVzY3JpcHRpb24gcGFyYW1ldGVyIGlzIDxjb2RlPm51bGw8L2NvZGU+LCB0aGVuIGFueSAKKyAgICAgKiBleGlzdGluZyAiQ29udGVudC1EZXNjcmlwdGlvbiIgZmllbGRzIGFyZSByZW1vdmVkLiA8cD4KKyAgICAgKgorICAgICAqIElmIHRoZSBkZXNjcmlwdGlvbiBjb250YWlucyBub24gVVMtQVNDSUkgY2hhcmFjdGVycywgaXQgd2lsbCAKKyAgICAgKiBiZSBlbmNvZGVkIHVzaW5nIHRoZSBwbGF0Zm9ybSdzIGRlZmF1bHQgY2hhcnNldC4gSWYgdGhlIAorICAgICAqIGRlc2NyaXB0aW9uIGNvbnRhaW5zIG9ubHkgVVMtQVNDSUkgY2hhcmFjdGVycywgbm8gZW5jb2RpbmcgCisgICAgICogaXMgZG9uZSBhbmQgaXQgaXMgdXNlZCBhcy1pcy4gPHA+CisgICAgICoKKyAgICAgKiBOb3RlIHRoYXQgaWYgdGhlIGNoYXJzZXQgZW5jb2RpbmcgcHJvY2VzcyBmYWlscywgYQorICAgICAqIE1lc3NhZ2luZ0V4Y2VwdGlvbiBpcyB0aHJvd24sIGFuZCBhbiBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uCisgICAgICogaXMgaW5jbHVkZWQgaW4gdGhlIGNoYWluIG9mIG5lc3RlZCBleGNlcHRpb25zIHdpdGhpbiB0aGUKKyAgICAgKiBNZXNzYWdpbmdFeGNlcHRpb24uCisgICAgICogCisgICAgICogQHBhcmFtIGRlc2NyaXB0aW9uIGNvbnRlbnQtZGVzY3JpcHRpb24KKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxXcml0ZUV4Y2VwdGlvbiBpZiB0aGUgdW5kZXJseWluZworICAgICAqCQkJaW1wbGVtZW50YXRpb24gZG9lcyBub3Qgc3VwcG9ydCBtb2RpZmljYXRpb24KKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIG1lc3NhZ2UgaXMKKyAgICAgKgkJCW9idGFpbmVkIGZyb20gYSBSRUFEX09OTFkgZm9sZGVyLgorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIEFuCisgICAgICogCQkJVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBtYXkgYmUgaW5jbHVkZWQKKyAgICAgKgkJCWluIHRoZSBleGNlcHRpb24gY2hhaW4gaWYgdGhlIGNoYXJzZXQKKyAgICAgKgkJCWNvbnZlcnNpb24gZmFpbHMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0RGVzY3JpcHRpb24oU3RyaW5nIGRlc2NyaXB0aW9uKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlzZXREZXNjcmlwdGlvbihkZXNjcmlwdGlvbiwgbnVsbCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSAiQ29udGVudC1EZXNjcmlwdGlvbiIgaGVhZGVyIGZpZWxkIGZvciB0aGlzIE1lc3NhZ2UuCisgICAgICogSWYgdGhlIGRlc2NyaXB0aW9uIHBhcmFtZXRlciBpcyA8Y29kZT5udWxsPC9jb2RlPiwgdGhlbiBhbnkgCisgICAgICogZXhpc3RpbmcgIkNvbnRlbnQtRGVzY3JpcHRpb24iIGZpZWxkcyBhcmUgcmVtb3ZlZC4gPHA+CisgICAgICoKKyAgICAgKiBJZiB0aGUgZGVzY3JpcHRpb24gY29udGFpbnMgbm9uIFVTLUFTQ0lJIGNoYXJhY3RlcnMsIGl0IHdpbGwgCisgICAgICogYmUgZW5jb2RlZCB1c2luZyB0aGUgc3BlY2lmaWVkIGNoYXJzZXQuIElmIHRoZSBkZXNjcmlwdGlvbiAKKyAgICAgKiBjb250YWlucyBvbmx5IFVTLUFTQ0lJIGNoYXJhY3RlcnMsIG5vIGVuY29kaW5nICBpcyBkb25lIGFuZCAKKyAgICAgKiBpdCBpcyB1c2VkIGFzLWlzLiA8cD4KKyAgICAgKgorICAgICAqIE5vdGUgdGhhdCBpZiB0aGUgY2hhcnNldCBlbmNvZGluZyBwcm9jZXNzIGZhaWxzLCBhCisgICAgICogTWVzc2FnaW5nRXhjZXB0aW9uIGlzIHRocm93biwgYW5kIGFuIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24KKyAgICAgKiBpcyBpbmNsdWRlZCBpbiB0aGUgY2hhaW4gb2YgbmVzdGVkIGV4Y2VwdGlvbnMgd2l0aGluIHRoZQorICAgICAqIE1lc3NhZ2luZ0V4Y2VwdGlvbi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0JZGVzY3JpcHRpb24JRGVzY3JpcHRpb24KKyAgICAgKiBAcGFyYW0JY2hhcnNldAkJQ2hhcnNldCBmb3IgZW5jb2RpbmcKKyAgICAgKiBAZXhjZXB0aW9uCQlJbGxlZ2FsV3JpdGVFeGNlcHRpb24gaWYgdGhlIHVuZGVybHlpbmcKKyAgICAgKgkJCQlpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IG1vZGlmaWNhdGlvbgorICAgICAqIEBleGNlcHRpb24JCUlsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIG1lc3NhZ2UgaXMKKyAgICAgKgkJCQlvYnRhaW5lZCBmcm9tIGEgUkVBRF9PTkxZIGZvbGRlci4KKyAgICAgKiBAZXhjZXB0aW9uCQlNZXNzYWdpbmdFeGNlcHRpb24gQW4KKyAgICAgKiAJCQkJVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBtYXkgYmUgaW5jbHVkZWQKKyAgICAgKgkJCQlpbiB0aGUgZXhjZXB0aW9uIGNoYWluIGlmIHRoZSBjaGFyc2V0CisgICAgICoJCQkJY29udmVyc2lvbiBmYWlscy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXREZXNjcmlwdGlvbihTdHJpbmcgZGVzY3JpcHRpb24sIFN0cmluZyBjaGFyc2V0KSAKKwkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJTWltZUJvZHlQYXJ0LnNldERlc2NyaXB0aW9uKHRoaXMsIGRlc2NyaXB0aW9uLCBjaGFyc2V0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGxhbmd1YWdlcyBzcGVjaWZpZWQgaW4gdGhlICJDb250ZW50LUxhbmd1YWdlIiBoZWFkZXIKKyAgICAgKiBmaWVsZCBvZiB0aGlzIG1lc3NhZ2UuIFRoZSBDb250ZW50LUxhbmd1YWdlIGhlYWRlciBpcyBkZWZpbmVkIGJ5CisgICAgICogUkZDIDE3NjYuIFJldHVybnMgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhpcyBmaWVsZCBpcyB1bmF2YWlsYWJsZQorICAgICAqIG9yIGl0cyB2YWx1ZSBpcyBhYnNlbnQuIDxwPgorICAgICAqCisgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiB1c2VzIHRoZSA8Y29kZT5nZXRIZWFkZXI8L2NvZGU+IG1ldGhvZAorICAgICAqIHRvIG9idGFpbiB0aGUgcmVxdWlzaXRlIGhlYWRlciBmaWVsZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4JCQl2YWx1ZSBvZiBjb250ZW50LWxhbmd1YWdlIGhlYWRlci4KKyAgICAgKiBAZXhjZXB0aW9uCQlNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZ1tdIGdldENvbnRlbnRMYW5ndWFnZSgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXJldHVybiBNaW1lQm9keVBhcnQuZ2V0Q29udGVudExhbmd1YWdlKHRoaXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgIkNvbnRlbnQtTGFuZ3VhZ2UiIGhlYWRlciBvZiB0aGlzIE1pbWVQYXJ0LiBUaGUKKyAgICAgKiBDb250ZW50LUxhbmd1YWdlIGhlYWRlciBpcyBkZWZpbmVkIGJ5IFJGQyAxNzY2LgorICAgICAqCisgICAgICogQHBhcmFtIGxhbmd1YWdlcyAJYXJyYXkgb2YgbGFuZ3VhZ2UgdGFncworICAgICAqIEBleGNlcHRpb24JCUlsbGVnYWxXcml0ZUV4Y2VwdGlvbiBpZiB0aGUgdW5kZXJseWluZworICAgICAqCQkJCWltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uCisgICAgICogQGV4Y2VwdGlvbgkJSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgbWVzc2FnZSBpcworICAgICAqCQkJCW9idGFpbmVkIGZyb20gYSBSRUFEX09OTFkgZm9sZGVyLgorICAgICAqIEBleGNlcHRpb24JCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRDb250ZW50TGFuZ3VhZ2UoU3RyaW5nW10gbGFuZ3VhZ2VzKQorCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJTWltZUJvZHlQYXJ0LnNldENvbnRlbnRMYW5ndWFnZSh0aGlzLCBsYW5ndWFnZXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIHRoZSAiTWVzc2FnZS1JRCIgaGVhZGVyIGZpZWxkLiBSZXR1cm5zCisgICAgICogbnVsbCBpZiB0aGlzIGZpZWxkIGlzIHVuYXZhaWxhYmxlIG9yIGl0cyB2YWx1ZSBpcyBhYnNlbnQuIDxwPgorICAgICAqCisgICAgICogVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gcHJvdmlkZWQgaGVyZSB1c2VzIHRoZQorICAgICAqIDxjb2RlPmdldEhlYWRlcjwvY29kZT4gbWV0aG9kIHRvIHJldHVybiB0aGUgdmFsdWUgb2YgdGhlCisgICAgICogIk1lc3NhZ2UtSUQiIGZpZWxkLgorICAgICAqCisgICAgICogQHJldHVybiAgICAgTWVzc2FnZS1JRAorICAgICAqIEBleGNlcHRpb24gIE1lc3NhZ2luZ0V4Y2VwdGlvbiBpZiB0aGUgcmV0cmlldmFsIG9mIHRoaXMgZmllbGQKKyAgICAgKgkJCWNhdXNlcyBhbnkgZXhjZXB0aW9uLgorICAgICAqIEBzZWUgICAgICAgIGphdmF4Lm1haWwuc2VhcmNoLk1lc3NhZ2VJRFRlcm0KKyAgICAgKiBAc2luY2UgCSAgIEphdmFNYWlsIDEuMQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWVzc2FnZUlEKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJcmV0dXJuIGdldEhlYWRlcigiTWVzc2FnZS1JRCIsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgZmlsZW5hbWUgYXNzb2NpYXRlZCB3aXRoIHRoaXMgTWVzc2FnZS4gPHA+CisgICAgICoKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgImZpbGVuYW1lIiBwYXJhbWV0ZXIgZnJvbSB0aGUKKyAgICAgKiAiQ29udGVudC1EaXNwb3NpdGlvbiIgaGVhZGVyIGZpZWxkIG9mIHRoaXMgbWVzc2FnZS4gSWYgaXQncworICAgICAqIG5vdCBhdmFpbGFibGUsIHJldHVybnMgdGhlIHZhbHVlIG9mIHRoZSAibmFtZSIgcGFyYW1ldGVyIGZyb20KKyAgICAgKiB0aGUgIkNvbnRlbnQtVHlwZSIgaGVhZGVyIGZpZWxkIG9mIHRoaXMgQm9keVBhcnQuCisgICAgICogUmV0dXJucyA8Y29kZT5udWxsPC9jb2RlPiBpZiBib3RoIGFyZSBhYnNlbnQuIDxwPgorICAgICAqCisgICAgICogSWYgdGhlIDxjb2RlPm1haWwubWltZS5lbmNvZGVmaWxlbmFtZTwvY29kZT4gU3lzdGVtIHByb3BlcnR5CisgICAgICogaXMgc2V0IHRvIHRydWUsIHRoZSB7QGxpbmsgTWltZVV0aWxpdHkjZGVjb2RlVGV4dAorICAgICAqIE1pbWVVdGlsaXR5LmRlY29kZVRleHR9IG1ldGhvZCB3aWxsIGJlIHVzZWQgdG8gZGVjb2RlIHRoZQorICAgICAqIGZpbGVuYW1lLiAgV2hpbGUgc3VjaCBlbmNvZGluZyBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBNSU1FCisgICAgICogc3BlYywgbWFueSBtYWlsZXJzIHVzZSB0aGlzIHRlY2huaXF1ZSB0byBzdXBwb3J0IG5vbi1BU0NJSQorICAgICAqIGNoYXJhY3RlcnMgaW4gZmlsZW5hbWVzLiAgVGhlIGRlZmF1bHQgdmFsdWUgb2YgdGhpcyBwcm9wZXJ0eQorICAgICAqIGlzIGZhbHNlLgorICAgICAqCisgICAgICogQHJldHVybglmaWxlbmFtZQorICAgICAqIEBleGNlcHRpb24JCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldEZpbGVOYW1lKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJcmV0dXJuIE1pbWVCb2R5UGFydC5nZXRGaWxlTmFtZSh0aGlzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIGZpbGVuYW1lIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHBhcnQsIGlmIHBvc3NpYmxlLiA8cD4KKyAgICAgKgorICAgICAqIFNldHMgdGhlICJmaWxlbmFtZSIgcGFyYW1ldGVyIG9mIHRoZSAiQ29udGVudC1EaXNwb3NpdGlvbiIKKyAgICAgKiBoZWFkZXIgZmllbGQgb2YgdGhpcyBtZXNzYWdlLiA8cD4KKyAgICAgKgorICAgICAqIElmIHRoZSA8Y29kZT5tYWlsLm1pbWUuZW5jb2RlZmlsZW5hbWU8L2NvZGU+IFN5c3RlbSBwcm9wZXJ0eQorICAgICAqIGlzIHNldCB0byB0cnVlLCB0aGUge0BsaW5rIE1pbWVVdGlsaXR5I2VuY29kZVRleHQKKyAgICAgKiBNaW1lVXRpbGl0eS5lbmNvZGVUZXh0fSBtZXRob2Qgd2lsbCBiZSB1c2VkIHRvIGVuY29kZSB0aGUKKyAgICAgKiBmaWxlbmFtZS4gIFdoaWxlIHN1Y2ggZW5jb2RpbmcgaXMgbm90IHN1cHBvcnRlZCBieSB0aGUgTUlNRQorICAgICAqIHNwZWMsIG1hbnkgbWFpbGVycyB1c2UgdGhpcyB0ZWNobmlxdWUgdG8gc3VwcG9ydCBub24tQVNDSUkKKyAgICAgKiBjaGFyYWN0ZXJzIGluIGZpbGVuYW1lcy4gIFRoZSBkZWZhdWx0IHZhbHVlIG9mIHRoaXMgcHJvcGVydHkKKyAgICAgKiBpcyBmYWxzZS4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24JCUlsbGVnYWxXcml0ZUV4Y2VwdGlvbiBpZiB0aGUgdW5kZXJseWluZworICAgICAqCQkJCWltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uCisgICAgICogQGV4Y2VwdGlvbgkJSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgbWVzc2FnZSBpcworICAgICAqCQkJCW9idGFpbmVkIGZyb20gYSBSRUFEX09OTFkgZm9sZGVyLgorICAgICAqIEBleGNlcHRpb24JCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRGaWxlTmFtZShTdHJpbmcgZmlsZW5hbWUpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCU1pbWVCb2R5UGFydC5zZXRGaWxlTmFtZSh0aGlzLCBmaWxlbmFtZSk7CQorICAgIH0KKworICAgIHByaXZhdGUgU3RyaW5nIGdldEhlYWRlck5hbWUoTWVzc2FnZS5SZWNpcGllbnRUeXBlIHR5cGUpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJU3RyaW5nIGhlYWRlck5hbWU7CisKKwlpZiAodHlwZSA9PSBNZXNzYWdlLlJlY2lwaWVudFR5cGUuVE8pCisJICAgIGhlYWRlck5hbWUgPSAiVG8iOworCWVsc2UgaWYgKHR5cGUgPT0gTWVzc2FnZS5SZWNpcGllbnRUeXBlLkNDKQorCSAgICBoZWFkZXJOYW1lID0gIkNjIjsKKwllbHNlIGlmICh0eXBlID09IE1lc3NhZ2UuUmVjaXBpZW50VHlwZS5CQ0MpCisJICAgIGhlYWRlck5hbWUgPSAiQmNjIjsKKwllbHNlIGlmICh0eXBlID09IE1pbWVNZXNzYWdlLlJlY2lwaWVudFR5cGUuTkVXU0dST1VQUykKKwkgICAgaGVhZGVyTmFtZSA9ICJOZXdzZ3JvdXBzIjsKKwllbHNlCisJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oIkludmFsaWQgUmVjaXBpZW50IFR5cGUiKTsKKwlyZXR1cm4gaGVhZGVyTmFtZTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIFJldHVybiBhIGRlY29kZWQgaW5wdXQgc3RyZWFtIGZvciB0aGlzIE1lc3NhZ2UncyAiY29udGVudCIuIDxwPgorICAgICAqCisgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiBvYnRhaW5zIHRoZSBpbnB1dCBzdHJlYW0gZnJvbSB0aGUgRGF0YUhhbmRsZXIsCisgICAgICogdGhhdCBpcywgaXQgaW52b2tlcyA8Y29kZT5nZXREYXRhSGFuZGxlcigpLmdldElucHV0U3RyZWFtKCk8L2NvZGU+LgorICAgICAqCisgICAgICogQHJldHVybiAJCWFuIElucHV0U3RyZWFtCisgICAgICogQGV4Y2VwdGlvbiAgICAgICBJT0V4Y2VwdGlvbiB0aGlzIGlzIHR5cGljYWxseSB0aHJvd24gYnkgdGhlCisgICAgICoJCQlEYXRhSGFuZGxlci4gUmVmZXIgdG8gdGhlIGRvY3VtZW50YXRpb24gZm9yCisgICAgICoJCQlqYXZheC5hY3RpdmF0aW9uLkRhdGFIYW5kbGVyIGZvciBtb3JlIGRldGFpbHMuCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICoKKyAgICAgKiBAc2VlCSNnZXRDb250ZW50U3RyZWFtCisgICAgICogQHNlZSAJamF2YXguYWN0aXZhdGlvbi5EYXRhSGFuZGxlciNnZXRJbnB1dFN0cmVhbQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBJbnB1dFN0cmVhbSBnZXRJbnB1dFN0cmVhbSgpIAorCQl0aHJvd3MgSU9FeGNlcHRpb24sIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJcmV0dXJuIGdldERhdGFIYW5kbGVyKCkuZ2V0SW5wdXRTdHJlYW0oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcm9kdWNlIHRoZSByYXcgYnl0ZXMgb2YgdGhlIGNvbnRlbnQuIFRoaXMgbWV0aG9kIGlzIHVzZWQgZHVyaW5nCisgICAgICogcGFyc2luZywgdG8gY3JlYXRlIGEgRGF0YUhhbmRsZXIgb2JqZWN0IGZvciB0aGUgY29udGVudC4gU3ViY2xhc3NlcworICAgICAqIHRoYXQgY2FuIHByb3ZpZGUgYSBzZXBhcmF0ZSBpbnB1dCBzdHJlYW0gZm9yIGp1c3QgdGhlIG1lc3NhZ2UgCisgICAgICogY29udGVudCBtaWdodCB3YW50IHRvIG92ZXJyaWRlIHRoaXMgbWV0aG9kLiA8cD4KKyAgICAgKgorICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gcmV0dXJucyBhIFNoYXJlZElucHV0U3RyZWFtLCBpZgorICAgICAqIDxjb2RlPmNvbnRlbnRTdHJlYW08L2NvZGU+IGlzIG5vdCBudWxsLiAgT3RoZXJ3aXNlLCBpdAorICAgICAqIHJldHVybnMgYSBCeXRlQXJyYXlJbnB1dFN0cmVhbSBjb25zdHJ1Y3RlZAorICAgICAqIG91dCBvZiB0aGUgPGNvZGU+Y29udGVudDwvY29kZT4gYnl0ZSBhcnJheS4KKyAgICAgKgorICAgICAqIEByZXR1cm4JYW4gSW5wdXRTdHJlYW0gY29udGFpbmluZyB0aGUgcmF3IGJ5dGVzCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICogQHNlZSAjY29udGVudAorICAgICAqLworICAgIHByb3RlY3RlZCBJbnB1dFN0cmVhbSBnZXRDb250ZW50U3RyZWFtKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKGNvbnRlbnRTdHJlYW0gIT0gbnVsbCkKKwkgICAgcmV0dXJuICgoU2hhcmVkSW5wdXRTdHJlYW0pY29udGVudFN0cmVhbSkubmV3U3RyZWFtKDAsIC0xKTsKKwlpZiAoY29udGVudCAhPSBudWxsKQorCSAgICByZXR1cm4gbmV3IFNoYXJlZEJ5dGVBcnJheUlucHV0U3RyZWFtKGNvbnRlbnQpOworCisJdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiTm8gTWltZU1lc3NhZ2UgY29udGVudCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiBhbiBJbnB1dFN0cmVhbSB0byB0aGUgcmF3IGRhdGEgd2l0aCBhbnkgQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZworICAgICAqIGludGFjdC4gIFRoaXMgbWV0aG9kIGlzIHVzZWZ1bCBpZiB0aGUgIkNvbnRlbnQtVHJhbnNmZXItRW5jb2RpbmciCisgICAgICogaGVhZGVyIGlzIGluY29ycmVjdCBvciBjb3JydXB0LCB3aGljaCB3b3VsZCBwcmV2ZW50IHRoZQorICAgICAqIDxjb2RlPmdldElucHV0U3RyZWFtPC9jb2RlPiBtZXRob2Qgb3IgPGNvZGU+Z2V0Q29udGVudDwvY29kZT4gbWV0aG9kCisgICAgICogZnJvbSByZXR1cm5pbmcgdGhlIGNvcnJlY3QgZGF0YS4gIEluIHN1Y2ggYSBjYXNlIHRoZSBhcHBsaWNhdGlvbiBtYXkKKyAgICAgKiB1c2UgdGhpcyBtZXRob2QgYW5kIGF0dGVtcHQgdG8gZGVjb2RlIHRoZSByYXcgZGF0YSBpdHNlbGYuIDxwPgorICAgICAqCisgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiBzaW1wbHkgY2FsbHMgdGhlIDxjb2RlPmdldENvbnRlbnRTdHJlYW08L2NvZGU+CisgICAgICogbWV0aG9kLgorICAgICAqCisgICAgICogQHJldHVybglhbiBJbnB1dFN0cmVhbSBjb250YWluaW5nIHRoZSByYXcgYnl0ZXMKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKiBAc2VlCSNnZXRJbnB1dFN0cmVhbQorICAgICAqIEBzZWUJI2dldENvbnRlbnRTdHJlYW0KKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS4yCisgICAgICovCisgICAgcHVibGljIElucHV0U3RyZWFtIGdldFJhd0lucHV0U3RyZWFtKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJcmV0dXJuIGdldENvbnRlbnRTdHJlYW0oKTsKKyAgICB9CisKKyAgICAvKiogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKKyAgICAgKiBSZXR1cm4gYSBEYXRhSGFuZGxlciBmb3IgdGhpcyBNZXNzYWdlJ3MgY29udGVudC4gPHA+CisgICAgICoKKyAgICAgKiBUaGUgaW1wbGVtZW50YXRpb24gcHJvdmlkZWQgaGVyZSB3b3JrcyBhcHByb3hpbWF0ZWx5IGFzIGZvbGxvd3MuCisgICAgICogTm90ZSB0aGUgdXNlIG9mIHRoZSA8Y29kZT5nZXRDb250ZW50U3RyZWFtPC9jb2RlPiBtZXRob2QgdG8gCisgICAgICogZ2VuZXJhdGUgdGhlIGJ5dGUgc3RyZWFtIGZvciB0aGUgY29udGVudC4gQWxzbyBub3RlIHRoYXQKKyAgICAgKiBhbnkgdHJhbnNmZXItZGVjb2RpbmcgaXMgZG9uZSBhdXRvbWF0aWNhbGx5IHdpdGhpbiB0aGlzIG1ldGhvZC4KKyAgICAgKgorICAgICAqIDxibG9ja3F1b3RlPjxwcmU+CisgICAgICogIGdldERhdGFIYW5kbGVyKCkgeworICAgICAqICAgICAgaWYgKGRoID09IG51bGwpIHsKKyAgICAgKiAgICAgICAgICBkaCA9IG5ldyBEYXRhSGFuZGxlcihuZXcgTWltZVBhcnREYXRhU291cmNlKHRoaXMpKTsKKyAgICAgKiAgICAgIH0KKyAgICAgKiAgICAgIHJldHVybiBkaDsKKyAgICAgKiAgfQorICAgICAqCisgICAgICogIGNsYXNzIE1pbWVQYXJ0RGF0YVNvdXJjZSBpbXBsZW1lbnRzIERhdGFTb3VyY2UgeworICAgICAqICAgICAgcHVibGljIGdldElucHV0U3RyZWFtKCkgeworICAgICAqICAgICAgICAgIHJldHVybiBNaW1lVXRpbGl0eS5kZWNvZGUoCisgICAgICoJCSAgICAgZ2V0Q29udGVudFN0cmVhbSgpLCBnZXRFbmNvZGluZygpKTsKKyAgICAgKiAgICAgIH0KKyAgICAgKgkKKyAgICAgKgkJLi4uLiAmbHQ7b3RoZXIgRGF0YVNvdXJjZSBtZXRob2RzJmd0OworICAgICAqICB9CisgICAgICogPC9wcmU+PC9ibG9ja3F1b3RlPjxwPgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBEYXRhSGFuZGxlciBnZXREYXRhSGFuZGxlcigpIAorCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpZiAoZGggPT0gbnVsbCkKKwkgICAgZGggPSBuZXcgTWltZUJvZHlQYXJ0Lk1pbWVQYXJ0RGF0YUhhbmRsZXIodGhpcyk7CisJcmV0dXJuIGRoOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgY29udGVudCBhcyBhIEphdmEgb2JqZWN0LiBUaGUgdHlwZSBvZiB0aGlzCisgICAgICogb2JqZWN0IGlzIGRlcGVuZGVudCBvbiB0aGUgY29udGVudCBpdHNlbGYuIEZvciAKKyAgICAgKiBleGFtcGxlLCB0aGUgbmF0aXZlIGZvcm1hdCBvZiBhICJ0ZXh0L3BsYWluIiBjb250ZW50CisgICAgICogaXMgdXN1YWxseSBhIFN0cmluZyBvYmplY3QuIFRoZSBuYXRpdmUgZm9ybWF0IGZvciBhICJtdWx0aXBhcnQiCisgICAgICogbWVzc2FnZSBpcyBhbHdheXMgYSBNdWx0aXBhcnQgc3ViY2xhc3MuIEZvciBjb250ZW50IHR5cGVzIHRoYXQgYXJlCisgICAgICogdW5rbm93biB0byB0aGUgRGF0YUhhbmRsZXIgc3lzdGVtLCBhbiBpbnB1dCBzdHJlYW0gaXMgcmV0dXJuZWQKKyAgICAgKiBhcyB0aGUgY29udGVudC4gPHA+CisgICAgICoKKyAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIG9idGFpbnMgdGhlIGNvbnRlbnQgZnJvbSB0aGUgRGF0YUhhbmRsZXIsCisgICAgICogdGhhdCBpcywgaXQgaW52b2tlcyA8Y29kZT5nZXREYXRhSGFuZGxlcigpLmdldENvbnRlbnQoKTwvY29kZT4uCisgICAgICogSWYgdGhlIGNvbnRlbnQgaXMgYSBNdWx0aXBhcnQgb3IgTWVzc2FnZSBvYmplY3QgYW5kIHdhcyBjcmVhdGVkIGJ5CisgICAgICogcGFyc2luZyBhIHN0cmVhbSwgdGhlIG9iamVjdCBpcyBjYWNoZWQgYW5kIHJldHVybmVkIGluIHN1YnNlcXVlbnQKKyAgICAgKiBjYWxscyBzbyB0aGF0IG1vZGlmaWNhdGlvbnMgdG8gdGhlIGNvbnRlbnQgd2lsbCBub3QgYmUgbG9zdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gICAgICAgICAgT2JqZWN0CisgICAgICogQHNlZQkJamF2YXgubWFpbC5QYXJ0CisgICAgICogQHNlZSAJCWphdmF4LmFjdGl2YXRpb24uRGF0YUhhbmRsZXIjZ2V0Q29udGVudAorICAgICAqIEBleGNlcHRpb24gICAgICAgSU9FeGNlcHRpb24gdGhpcyBpcyB0eXBpY2FsbHkgdGhyb3duIGJ5IHRoZQorICAgICAqCQkJRGF0YUhhbmRsZXIuIFJlZmVyIHRvIHRoZSBkb2N1bWVudGF0aW9uIGZvcgorICAgICAqCQkJamF2YXguYWN0aXZhdGlvbi5EYXRhSGFuZGxlciBmb3IgbW9yZSBkZXRhaWxzLgorICAgICAqIEBleGNlcHRpb24gICAgICAgTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBvdGhlciBmYWlsdXJlcworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBPYmplY3QgZ2V0Q29udGVudCgpIHRocm93cyBJT0V4Y2VwdGlvbiwgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpZiAoY2FjaGVkQ29udGVudCAhPSBudWxsKQorCSAgICByZXR1cm4gY2FjaGVkQ29udGVudDsKKwlPYmplY3QgYzsKKwl0cnkgeworCSAgICBjID0gZ2V0RGF0YUhhbmRsZXIoKS5nZXRDb250ZW50KCk7CisJfSBjYXRjaCAoRm9sZGVyQ2xvc2VkSU9FeGNlcHRpb24gZmV4KSB7CisJICAgIHRocm93IG5ldyBGb2xkZXJDbG9zZWRFeGNlcHRpb24oZmV4LmdldEZvbGRlcigpLCBmZXguZ2V0TWVzc2FnZSgpKTsKKwl9IGNhdGNoIChNZXNzYWdlUmVtb3ZlZElPRXhjZXB0aW9uIG1leCkgeworCSAgICB0aHJvdyBuZXcgTWVzc2FnZVJlbW92ZWRFeGNlcHRpb24obWV4LmdldE1lc3NhZ2UoKSk7CisJfQorCWlmIChNaW1lQm9keVBhcnQuY2FjaGVNdWx0aXBhcnQgJiYKKwkJKGMgaW5zdGFuY2VvZiBNdWx0aXBhcnQgfHwgYyBpbnN0YW5jZW9mIE1lc3NhZ2UpICYmCisJCShjb250ZW50ICE9IG51bGwgfHwgY29udGVudFN0cmVhbSAhPSBudWxsKSkgeworCSAgICBjYWNoZWRDb250ZW50ID0gYzsKKwkgICAgLyoKKwkgICAgICogV2UgbWF5IGFiYW5kb24gdGhlIGlucHV0IHN0cmVhbSBzbyBtYWtlIHN1cmUKKwkgICAgICogdGhlIE1pbWVNdWx0aXBhcnQgaGFzIGNvbnN1bWVkIHRoZSBzdHJlYW0uCisJICAgICAqLworCSAgICBpZiAoYyBpbnN0YW5jZW9mIE1pbWVNdWx0aXBhcnQpCisJCSgoTWltZU11bHRpcGFydCljKS5wYXJzZSgpOworCX0KKwlyZXR1cm4gYzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBwcm92aWRlcyB0aGUgbWVjaGFuaXNtIHRvIHNldCB0aGlzIHBhcnQncyBjb250ZW50LgorICAgICAqIFRoZSBnaXZlbiBEYXRhSGFuZGxlciBvYmplY3Qgc2hvdWxkIHdyYXAgdGhlIGFjdHVhbCBjb250ZW50LgorICAgICAqCisgICAgICogQHBhcmFtICAgZGggICAgICBUaGUgRGF0YUhhbmRsZXIgZm9yIHRoZSBjb250ZW50LgorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFdyaXRlRXhjZXB0aW9uIGlmIHRoZSB1bmRlcmx5aW5nCisgICAgICoJCQlpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IG1vZGlmaWNhdGlvbgorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgbWVzc2FnZSBpcworICAgICAqCQkJb2J0YWluZWQgZnJvbSBhIFJFQURfT05MWSBmb2xkZXIuCisgICAgICogQGV4Y2VwdGlvbiAgICAgICBNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHNldERhdGFIYW5kbGVyKERhdGFIYW5kbGVyIGRoKSAKKwkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJdGhpcy5kaCA9IGRoOworCWNhY2hlZENvbnRlbnQgPSBudWxsOworCU1pbWVCb2R5UGFydC5pbnZhbGlkYXRlQ29udGVudEhlYWRlcnModGhpcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQSBjb252ZW5pZW5jZSBtZXRob2QgZm9yIHNldHRpbmcgdGhpcyBNZXNzYWdlJ3MgY29udGVudC4gPHA+CisgICAgICoKKyAgICAgKiBUaGUgY29udGVudCBpcyB3cmFwcGVkIGluIGEgRGF0YUhhbmRsZXIgb2JqZWN0LiBOb3RlIHRoYXQgYQorICAgICAqIERhdGFDb250ZW50SGFuZGxlciBjbGFzcyBmb3IgdGhlIHNwZWNpZmllZCB0eXBlIHNob3VsZCBiZQorICAgICAqIGF2YWlsYWJsZSB0byB0aGUgSmF2YU1haWwgaW1wbGVtZW50YXRpb24gZm9yIHRoaXMgdG8gd29yayByaWdodC4KKyAgICAgKiBpLmUuLCB0byBkbyA8Y29kZT5zZXRDb250ZW50KGZvb2JhciwgImFwcGxpY2F0aW9uL3gtZm9vYmFyIik8L2NvZGU+LAorICAgICAqIGEgRGF0YUNvbnRlbnRIYW5kbGVyIGZvciAiYXBwbGljYXRpb24veC1mb29iYXIiIHNob3VsZCBiZSBpbnN0YWxsZWQuCisgICAgICogUmVmZXIgdG8gdGhlIEphdmEgQWN0aXZhdGlvbiBGcmFtZXdvcmsgZm9yIG1vcmUgaW5mb3JtYXRpb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0Jbwl0aGUgY29udGVudCBvYmplY3QKKyAgICAgKiBAcGFyYW0JdHlwZQlNaW1lIHR5cGUgb2YgdGhlIG9iamVjdAorICAgICAqIEBleGNlcHRpb24gICAgICAgSWxsZWdhbFdyaXRlRXhjZXB0aW9uIGlmIHRoZSB1bmRlcmx5aW5nCisgICAgICoJCQlpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IG1vZGlmaWNhdGlvbiBvZgorICAgICAqCQkJZXhpc3RpbmcgdmFsdWVzCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBtZXNzYWdlIGlzCisgICAgICoJCQlvYnRhaW5lZCBmcm9tIGEgUkVBRF9PTkxZIGZvbGRlci4KKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIE1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRDb250ZW50KE9iamVjdCBvLCBTdHJpbmcgdHlwZSkgCisJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpZiAobyBpbnN0YW5jZW9mIE11bHRpcGFydCkKKwkgICAgc2V0Q29udGVudCgoTXVsdGlwYXJ0KW8pOworCWVsc2UKKwkgICAgc2V0RGF0YUhhbmRsZXIobmV3IERhdGFIYW5kbGVyKG8sIHR5cGUpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZW5pZW5jZSBtZXRob2QgdGhhdCBzZXRzIHRoZSBnaXZlbiBTdHJpbmcgYXMgdGhpcworICAgICAqIHBhcnQncyBjb250ZW50LCB3aXRoIGEgTUlNRSB0eXBlIG9mICJ0ZXh0L3BsYWluIi4gSWYgdGhlCisgICAgICogc3RyaW5nIGNvbnRhaW5zIG5vbiBVUy1BU0NJSSBjaGFyYWN0ZXJzLiBpdCB3aWxsIGJlIGVuY29kZWQKKyAgICAgKiB1c2luZyB0aGUgcGxhdGZvcm0ncyBkZWZhdWx0IGNoYXJzZXQuIFRoZSBjaGFyc2V0IGlzIGFsc28KKyAgICAgKiB1c2VkIHRvIHNldCB0aGUgImNoYXJzZXQiIHBhcmFtZXRlci48cD4KKyAgICAgKgorICAgICAqIE5vdGUgdGhhdCB0aGVyZSBtYXkgYmUgYSBwZXJmb3JtYW5jZSBwZW5hbHR5IGlmCisgICAgICogPGNvZGU+dGV4dDwvY29kZT4gaXMgbGFyZ2UsIHNpbmNlIHRoaXMgbWV0aG9kIG1heSBoYXZlCisgICAgICogdG8gc2NhbiBhbGwgdGhlIGNoYXJhY3RlcnMgdG8gZGV0ZXJtaW5lIHdoYXQgY2hhcnNldCB0bworICAgICAqIHVzZS4gPHA+CisgICAgICoKKyAgICAgKiBJZiB0aGUgY2hhcnNldCBpcyBhbHJlYWR5IGtub3duLCB1c2UgdGhlCisgICAgICogPGNvZGU+c2V0VGV4dDwvY29kZT4gbWV0aG9kIHRoYXQgdGFrZXMgdGhlIGNoYXJzZXQgcGFyYW1ldGVyLgorICAgICAqCisgICAgICogQHBhcmFtCXRleHQJdGhlIHRleHQgY29udGVudCB0byBzZXQKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbglpZiBhbiBlcnJvciBvY2N1cnMKKyAgICAgKiBAc2VlCSNzZXRUZXh0KFN0cmluZyB0ZXh0LCBTdHJpbmcgY2hhcnNldCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRUZXh0KFN0cmluZyB0ZXh0KSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlzZXRUZXh0KHRleHQsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlbmllbmNlIG1ldGhvZCB0aGF0IHNldHMgdGhlIGdpdmVuIFN0cmluZyBhcyB0aGlzIHBhcnQncworICAgICAqIGNvbnRlbnQsIHdpdGggYSBNSU1FIHR5cGUgb2YgInRleHQvcGxhaW4iIGFuZCB0aGUgc3BlY2lmaWVkCisgICAgICogY2hhcnNldC4gVGhlIGdpdmVuIFVuaWNvZGUgc3RyaW5nIHdpbGwgYmUgY2hhcnNldC1lbmNvZGVkCisgICAgICogdXNpbmcgdGhlIHNwZWNpZmllZCBjaGFyc2V0LiBUaGUgY2hhcnNldCBpcyBhbHNvIHVzZWQgdG8gc2V0CisgICAgICogdGhlICJjaGFyc2V0IiBwYXJhbWV0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0JdGV4dAl0aGUgdGV4dCBjb250ZW50IHRvIHNldAorICAgICAqIEBwYXJhbQljaGFyc2V0CXRoZSBjaGFyc2V0IHRvIHVzZSBmb3IgdGhlIHRleHQKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbglpZiBhbiBlcnJvciBvY2N1cnMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRUZXh0KFN0cmluZyB0ZXh0LCBTdHJpbmcgY2hhcnNldCkKKwkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCU1pbWVCb2R5UGFydC5zZXRUZXh0KHRoaXMsIHRleHQsIGNoYXJzZXQsICJwbGFpbiIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlbmllbmNlIG1ldGhvZCB0aGF0IHNldHMgdGhlIGdpdmVuIFN0cmluZyBhcyB0aGlzIHBhcnQncworICAgICAqIGNvbnRlbnQsIHdpdGggYSBwcmltYXJ5IE1JTUUgdHlwZSBvZiAidGV4dCIgYW5kIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBNSU1FIHN1YnR5cGUuICBUaGUgZ2l2ZW4gVW5pY29kZSBzdHJpbmcgd2lsbCBiZSBjaGFyc2V0LWVuY29kZWQKKyAgICAgKiB1c2luZyB0aGUgc3BlY2lmaWVkIGNoYXJzZXQuIFRoZSBjaGFyc2V0IGlzIGFsc28gdXNlZCB0byBzZXQKKyAgICAgKiB0aGUgImNoYXJzZXQiIHBhcmFtZXRlci4KKyAgICAgKgorICAgICAqIEBwYXJhbQl0ZXh0CXRoZSB0ZXh0IGNvbnRlbnQgdG8gc2V0CisgICAgICogQHBhcmFtCWNoYXJzZXQJdGhlIGNoYXJzZXQgdG8gdXNlIGZvciB0aGUgdGV4dAorICAgICAqIEBwYXJhbQlzdWJ0eXBlCXRoZSBNSU1FIHN1YnR5cGUgdG8gdXNlIChlLmcuLCAiaHRtbCIpCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24JaWYgYW4gZXJyb3Igb2NjdXJzCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFRleHQoU3RyaW5nIHRleHQsIFN0cmluZyBjaGFyc2V0LCBTdHJpbmcgc3VidHlwZSkKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCU1pbWVCb2R5UGFydC5zZXRUZXh0KHRoaXMsIHRleHQsIGNoYXJzZXQsIHN1YnR5cGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIHNldHMgdGhlIE1lc3NhZ2UncyBjb250ZW50IHRvIGEgTXVsdGlwYXJ0IG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSAgbXAgICAgICBUaGUgbXVsdGlwYXJ0IG9iamVjdCB0aGF0IGlzIHRoZSBNZXNzYWdlJ3MgY29udGVudAorICAgICAqIEBleGNlcHRpb24gICAgICAgSWxsZWdhbFdyaXRlRXhjZXB0aW9uIGlmIHRoZSB1bmRlcmx5aW5nCisgICAgICoJCQlpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IG1vZGlmaWNhdGlvbiBvZgorICAgICAqCQkJZXhpc3RpbmcgdmFsdWVzCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBtZXNzYWdlIGlzCisgICAgICoJCQlvYnRhaW5lZCBmcm9tIGEgUkVBRF9PTkxZIGZvbGRlci4KKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIE1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBzZXRDb250ZW50KE11bHRpcGFydCBtcCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJc2V0RGF0YUhhbmRsZXIobmV3IERhdGFIYW5kbGVyKG1wLCBtcC5nZXRDb250ZW50VHlwZSgpKSk7CisJbXAuc2V0UGFyZW50KHRoaXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCBhIG5ldyBNZXNzYWdlIHN1aXRhYmxlIGZvciBhIHJlcGx5IHRvIHRoaXMgbWVzc2FnZS4KKyAgICAgKiBUaGUgbmV3IE1lc3NhZ2Ugd2lsbCBoYXZlIGl0cyBhdHRyaWJ1dGVzIGFuZCBoZWFkZXJzIAorICAgICAqIHNldCB1cCBhcHByb3ByaWF0ZWx5LiAgTm90ZSB0aGF0IHRoaXMgbmV3IG1lc3NhZ2Ugb2JqZWN0CisgICAgICogd2lsbCBiZSBlbXB0eSwgaS5lLiwgaXQgd2lsbCA8c3Ryb25nPm5vdDwvc3Ryb25nPiBoYXZlIGEgImNvbnRlbnQiLgorICAgICAqIFRoZXNlIHdpbGwgaGF2ZSB0byBiZSBzdWl0YWJseSBmaWxsZWQgaW4gYnkgdGhlIGNsaWVudC4gPHA+CisgICAgICoKKyAgICAgKiBJZiA8Y29kZT5yZXBseVRvQWxsPC9jb2RlPiBpcyBzZXQsIHRoZSBuZXcgTWVzc2FnZSB3aWxsIGJlIGFkZHJlc3NlZAorICAgICAqIHRvIGFsbCByZWNpcGllbnRzIG9mIHRoaXMgbWVzc2FnZS4gIE90aGVyd2lzZSwgdGhlIHJlcGx5IHdpbGwgYmUKKyAgICAgKiBhZGRyZXNzZWQgdG8gb25seSB0aGUgc2VuZGVyIG9mIHRoaXMgbWVzc2FnZSAodXNpbmcgdGhlIHZhbHVlCisgICAgICogb2YgdGhlIDxjb2RlPmdldFJlcGx5VG88L2NvZGU+IG1ldGhvZCkuICA8cD4KKyAgICAgKgorICAgICAqIFRoZSAiU3ViamVjdCIgZmllbGQgaXMgZmlsbGVkIGluIHdpdGggdGhlIG9yaWdpbmFsIHN1YmplY3QKKyAgICAgKiBwcmVmaXhlZCB3aXRoICJSZToiICh1bmxlc3MgaXQgYWxyZWFkeSBzdGFydHMgd2l0aCAiUmU6IikuCisgICAgICogVGhlICJJbi1SZXBseS1UbyIgaGVhZGVyIGlzIHNldCBpbiB0aGUgbmV3IG1lc3NhZ2UgaWYgdGhpcworICAgICAqIG1lc3NhZ2UgaGFzIGEgIk1lc3NhZ2UtSWQiIGhlYWRlci4gIFRoZSA8Y29kZT5BTlNXRVJFRDwvY29kZT4KKyAgICAgKiBmbGFnIGlzIHNldCBpbiB0aGlzIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBUaGUgY3VycmVudCBpbXBsZW1lbnRhdGlvbiBhbHNvIHNldHMgdGhlICJSZWZlcmVuY2VzIiBoZWFkZXIKKyAgICAgKiBpbiB0aGUgbmV3IG1lc3NhZ2UgdG8gaW5jbHVkZSB0aGUgY29udGVudHMgb2YgdGhlICJSZWZlcmVuY2VzIgorICAgICAqIGhlYWRlciAob3IsIGlmIG1pc3NpbmcsIHRoZSAiSW4tUmVwbHktVG8iIGhlYWRlcikgaW4gdGhpcyBtZXNzYWdlLAorICAgICAqIHBsdXMgdGhlIGNvbnRlbnRzIG9mIHRoZSAiTWVzc2FnZS1JZCIgaGVhZGVyIG9mIHRoaXMgbWVzc2FnZSwKKyAgICAgKiBhcyBkZXNjcmliZWQgaW4gUkZDIDI4MjIuCisgICAgICoKKyAgICAgKiBAcGFyYW0JcmVwbHlUb0FsbAlyZXBseSBzaG91bGQgYmUgc2VudCB0byBhbGwgcmVjaXBpZW50cworICAgICAqCQkJCW9mIHRoaXMgbWVzc2FnZQorICAgICAqIEByZXR1cm4JCXRoZSByZXBseSBNZXNzYWdlCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE1lc3NhZ2UgcmVwbHkoYm9vbGVhbiByZXBseVRvQWxsKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gcmVwbHkocmVwbHlUb0FsbCwgdHJ1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IGEgbmV3IE1lc3NhZ2Ugc3VpdGFibGUgZm9yIGEgcmVwbHkgdG8gdGhpcyBtZXNzYWdlLgorICAgICAqIFRoZSBuZXcgTWVzc2FnZSB3aWxsIGhhdmUgaXRzIGF0dHJpYnV0ZXMgYW5kIGhlYWRlcnMgCisgICAgICogc2V0IHVwIGFwcHJvcHJpYXRlbHkuICBOb3RlIHRoYXQgdGhpcyBuZXcgbWVzc2FnZSBvYmplY3QKKyAgICAgKiB3aWxsIGJlIGVtcHR5LCBpLmUuLCBpdCB3aWxsIDxzdHJvbmc+bm90PC9zdHJvbmc+IGhhdmUgYSAiY29udGVudCIuCisgICAgICogVGhlc2Ugd2lsbCBoYXZlIHRvIGJlIHN1aXRhYmx5IGZpbGxlZCBpbiBieSB0aGUgY2xpZW50LiA8cD4KKyAgICAgKgorICAgICAqIElmIDxjb2RlPnJlcGx5VG9BbGw8L2NvZGU+IGlzIHNldCwgdGhlIG5ldyBNZXNzYWdlIHdpbGwgYmUgYWRkcmVzc2VkCisgICAgICogdG8gYWxsIHJlY2lwaWVudHMgb2YgdGhpcyBtZXNzYWdlLiAgT3RoZXJ3aXNlLCB0aGUgcmVwbHkgd2lsbCBiZQorICAgICAqIGFkZHJlc3NlZCB0byBvbmx5IHRoZSBzZW5kZXIgb2YgdGhpcyBtZXNzYWdlICh1c2luZyB0aGUgdmFsdWUKKyAgICAgKiBvZiB0aGUgPGNvZGU+Z2V0UmVwbHlUbzwvY29kZT4gbWV0aG9kKS4gIDxwPgorICAgICAqCisgICAgICogSWYgPGNvZGU+c2V0QW5zd2VyZWQ8L2NvZGU+IGlzIHNldCwgdGhlCisgICAgICoge0BsaW5rIGphdmF4Lm1haWwuRmxhZ3MuRmxhZyNBTlNXRVJFRCBBTlNXRVJFRH0gZmxhZyBpcyBzZXQKKyAgICAgKiBpbiB0aGlzIG1lc3NhZ2UuIDxwPgorICAgICAqCisgICAgICogVGhlICJTdWJqZWN0IiBmaWVsZCBpcyBmaWxsZWQgaW4gd2l0aCB0aGUgb3JpZ2luYWwgc3ViamVjdAorICAgICAqIHByZWZpeGVkIHdpdGggIlJlOiIgKHVubGVzcyBpdCBhbHJlYWR5IHN0YXJ0cyB3aXRoICJSZToiKS4KKyAgICAgKiBUaGUgIkluLVJlcGx5LVRvIiBoZWFkZXIgaXMgc2V0IGluIHRoZSBuZXcgbWVzc2FnZSBpZiB0aGlzCisgICAgICogbWVzc2FnZSBoYXMgYSAiTWVzc2FnZS1JZCIgaGVhZGVyLgorICAgICAqCisgICAgICogVGhlIGN1cnJlbnQgaW1wbGVtZW50YXRpb24gYWxzbyBzZXRzIHRoZSAiUmVmZXJlbmNlcyIgaGVhZGVyCisgICAgICogaW4gdGhlIG5ldyBtZXNzYWdlIHRvIGluY2x1ZGUgdGhlIGNvbnRlbnRzIG9mIHRoZSAiUmVmZXJlbmNlcyIKKyAgICAgKiBoZWFkZXIgKG9yLCBpZiBtaXNzaW5nLCB0aGUgIkluLVJlcGx5LVRvIiBoZWFkZXIpIGluIHRoaXMgbWVzc2FnZSwKKyAgICAgKiBwbHVzIHRoZSBjb250ZW50cyBvZiB0aGUgIk1lc3NhZ2UtSWQiIGhlYWRlciBvZiB0aGlzIG1lc3NhZ2UsCisgICAgICogYXMgZGVzY3JpYmVkIGluIFJGQyAyODIyLgorICAgICAqCisgICAgICogQHBhcmFtCXJlcGx5VG9BbGwJcmVwbHkgc2hvdWxkIGJlIHNlbnQgdG8gYWxsIHJlY2lwaWVudHMKKyAgICAgKgkJCQlvZiB0aGlzIG1lc3NhZ2UKKyAgICAgKiBAcGFyYW0Jc2V0QW5zd2VyZWQJc2V0IHRoZSBBTlNXRVJFRCBmbGFnIGluIHRoaXMgbWVzc2FnZT8KKyAgICAgKiBAcmV0dXJuCQl0aGUgcmVwbHkgTWVzc2FnZQorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS41CisgICAgICovCisgICAgcHVibGljIE1lc3NhZ2UgcmVwbHkoYm9vbGVhbiByZXBseVRvQWxsLCBib29sZWFuIHNldEFuc3dlcmVkKQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCU1pbWVNZXNzYWdlIHJlcGx5ID0gY3JlYXRlTWltZU1lc3NhZ2Uoc2Vzc2lvbik7CisJLyoKKwkgKiBIYXZlIHRvIG1hbmlwdWxhdGUgdGhlIHJhdyBTdWJqZWN0IGhlYWRlciBzbyB0aGF0IHdlIGRvbid0IGxvc2UKKwkgKiBhbnkgZW5jb2RpbmcgaW5mb3JtYXRpb24uICBUaGlzIGlzIHNhZmUgYmVjYXVzZSAiUmU6IiBpc24ndAorCSAqIGludGVybmF0aW9uYWxpemVkIGFuZCAoZ2VuZXJhbGx5KSBpc24ndCBlbmNvZGVkLiAgSWYgdGhlIGVudGlyZQorCSAqIFN1YmplY3QgaGVhZGVyIGlzIGVuY29kZWQsIHByZWZpeGluZyBpdCB3aXRoICJSZTogIiBzdGlsbCBsZWF2ZXMKKwkgKiBhIHZhbGlkIGFuZCBjb3JyZWN0IGVuY29kZWQgaGVhZGVyLgorCSAqLworCVN0cmluZyBzdWJqZWN0ID0gZ2V0SGVhZGVyKCJTdWJqZWN0IiwgbnVsbCk7CisJaWYgKHN1YmplY3QgIT0gbnVsbCkgeworCSAgICBpZiAoIXN1YmplY3QucmVnaW9uTWF0Y2hlcyh0cnVlLCAwLCAiUmU6ICIsIDAsIDQpKQorCQlzdWJqZWN0ID0gIlJlOiAiICsgc3ViamVjdDsKKwkgICAgcmVwbHkuc2V0SGVhZGVyKCJTdWJqZWN0Iiwgc3ViamVjdCk7CisJfQorCUFkZHJlc3MgYVtdID0gZ2V0UmVwbHlUbygpOworCXJlcGx5LnNldFJlY2lwaWVudHMoTWVzc2FnZS5SZWNpcGllbnRUeXBlLlRPLCBhKTsKKwlpZiAocmVwbHlUb0FsbCkgeworCSAgICBMaXN0PEFkZHJlc3M+IHYgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKwkgICAgLy8gYWRkIG15IG93biBhZGRyZXNzIHRvIGxpc3QKKwkgICAgSW50ZXJuZXRBZGRyZXNzIG1lID0gSW50ZXJuZXRBZGRyZXNzLmdldExvY2FsQWRkcmVzcyhzZXNzaW9uKTsKKwkgICAgaWYgKG1lICE9IG51bGwpCisJCXYuYWRkKG1lKTsKKwkgICAgLy8gYWRkIGFueSBhbHRlcm5hdGUgbmFtZXMgSSdtIGtub3duIGJ5CisJICAgIFN0cmluZyBhbHRlcm5hdGVzID0gbnVsbDsKKwkgICAgaWYgKHNlc3Npb24gIT0gbnVsbCkKKwkJYWx0ZXJuYXRlcyA9IHNlc3Npb24uZ2V0UHJvcGVydHkoIm1haWwuYWx0ZXJuYXRlcyIpOworCSAgICBpZiAoYWx0ZXJuYXRlcyAhPSBudWxsKQorCQllbGltaW5hdGVEdXBsaWNhdGVzKHYsCisJCQkJSW50ZXJuZXRBZGRyZXNzLnBhcnNlKGFsdGVybmF0ZXMsIGZhbHNlKSk7CisJICAgIC8vIHNob3VsZCB3ZSBDYyBhbGwgb3RoZXIgb3JpZ2luYWwgcmVjaXBpZW50cz8KKwkgICAgU3RyaW5nIHJlcGx5YWxsY2NTdHIgPSBudWxsOworCSAgICBib29sZWFuIHJlcGx5YWxsY2MgPSBmYWxzZTsKKwkgICAgaWYgKHNlc3Npb24gIT0gbnVsbCkKKwkJcmVwbHlhbGxjYyA9IFByb3BVdGlsLmdldEJvb2xlYW5Qcm9wZXJ0eSgKKwkJCQkJCXNlc3Npb24uZ2V0UHJvcGVydGllcygpLAorCQkJCQkJIm1haWwucmVwbHlhbGxjYyIsIGZhbHNlKTsKKwkgICAgLy8gYWRkIHRoZSByZWNpcGllbnRzIGZyb20gdGhlIFRvIGZpZWxkIHNvIGZhcgorCSAgICBlbGltaW5hdGVEdXBsaWNhdGVzKHYsIGEpOworCSAgICBhID0gZ2V0UmVjaXBpZW50cyhNZXNzYWdlLlJlY2lwaWVudFR5cGUuVE8pOworCSAgICBhID0gZWxpbWluYXRlRHVwbGljYXRlcyh2LCBhKTsKKwkgICAgaWYgKGEgIT0gbnVsbCAmJiBhLmxlbmd0aCA+IDApIHsKKwkJaWYgKHJlcGx5YWxsY2MpCisJCSAgICByZXBseS5hZGRSZWNpcGllbnRzKE1lc3NhZ2UuUmVjaXBpZW50VHlwZS5DQywgYSk7CisJCWVsc2UKKwkJICAgIHJlcGx5LmFkZFJlY2lwaWVudHMoTWVzc2FnZS5SZWNpcGllbnRUeXBlLlRPLCBhKTsKKwkgICAgfQorCSAgICBhID0gZ2V0UmVjaXBpZW50cyhNZXNzYWdlLlJlY2lwaWVudFR5cGUuQ0MpOworCSAgICBhID0gZWxpbWluYXRlRHVwbGljYXRlcyh2LCBhKTsKKwkgICAgaWYgKGEgIT0gbnVsbCAmJiBhLmxlbmd0aCA+IDApCisJCXJlcGx5LmFkZFJlY2lwaWVudHMoTWVzc2FnZS5SZWNpcGllbnRUeXBlLkNDLCBhKTsKKwkgICAgLy8gZG9uJ3QgZWxpbWluYXRlIGR1cGxpY2F0ZSBuZXdzZ3JvdXBzCisJICAgIGEgPSBnZXRSZWNpcGllbnRzKFJlY2lwaWVudFR5cGUuTkVXU0dST1VQUyk7CisJICAgIGlmIChhICE9IG51bGwgJiYgYS5sZW5ndGggPiAwKQorCQlyZXBseS5zZXRSZWNpcGllbnRzKFJlY2lwaWVudFR5cGUuTkVXU0dST1VQUywgYSk7CisJfQorCisJU3RyaW5nIG1zZ0lkID0gZ2V0SGVhZGVyKCJNZXNzYWdlLUlkIiwgbnVsbCk7CisJaWYgKG1zZ0lkICE9IG51bGwpCisJICAgIHJlcGx5LnNldEhlYWRlcigiSW4tUmVwbHktVG8iLCBtc2dJZCk7CisKKwkvKgorCSAqIFNldCB0aGUgUmVmZXJlbmNlcyBoZWFkZXIgYXMgZGVzY3JpYmVkIGluIFJGQyAyODIyOgorCSAqCisJICogVGhlICJSZWZlcmVuY2VzOiIgZmllbGQgd2lsbCBjb250YWluIHRoZSBjb250ZW50cyBvZiB0aGUgcGFyZW50J3MKKwkgKiAiUmVmZXJlbmNlczoiIGZpZWxkIChpZiBhbnkpIGZvbGxvd2VkIGJ5IHRoZSBjb250ZW50cyBvZiB0aGUgcGFyZW50J3MKKwkgKiAiTWVzc2FnZS1JRDoiIGZpZWxkIChpZiBhbnkpLiAgSWYgdGhlIHBhcmVudCBtZXNzYWdlIGRvZXMgbm90IGNvbnRhaW4KKwkgKiBhICJSZWZlcmVuY2VzOiIgZmllbGQgYnV0IGRvZXMgaGF2ZSBhbiAiSW4tUmVwbHktVG86IiBmaWVsZAorCSAqIGNvbnRhaW5pbmcgYSBzaW5nbGUgbWVzc2FnZSBpZGVudGlmaWVyLCB0aGVuIHRoZSAiUmVmZXJlbmNlczoiIGZpZWxkCisJICogd2lsbCBjb250YWluIHRoZSBjb250ZW50cyBvZiB0aGUgcGFyZW50J3MgIkluLVJlcGx5LVRvOiIgZmllbGQKKwkgKiBmb2xsb3dlZCBieSB0aGUgY29udGVudHMgb2YgdGhlIHBhcmVudCdzICJNZXNzYWdlLUlEOiIgZmllbGQgKGlmCisJICogYW55KS4gIElmIHRoZSBwYXJlbnQgaGFzIG5vbmUgb2YgdGhlICJSZWZlcmVuY2VzOiIsICJJbi1SZXBseS1UbzoiLAorCSAqIG9yICJNZXNzYWdlLUlEOiIgZmllbGRzLCB0aGVuIHRoZSBuZXcgbWVzc2FnZSB3aWxsIGhhdmUgbm8KKwkgKiAiUmVmZXJlbmNlczoiIGZpZWxkLgorCSAqLworCVN0cmluZyByZWZzID0gZ2V0SGVhZGVyKCJSZWZlcmVuY2VzIiwgIiAiKTsKKwlpZiAocmVmcyA9PSBudWxsKSB7CisJICAgIC8vIFhYWCAtIHNob3VsZCBvbmx5IHVzZSBpZiBpdCBjb250YWlucyBhIHNpbmdsZSBtZXNzYWdlIGlkZW50aWZpZXIKKwkgICAgcmVmcyA9IGdldEhlYWRlcigiSW4tUmVwbHktVG8iLCAiICIpOworCX0KKwlpZiAobXNnSWQgIT0gbnVsbCkgeworCSAgICBpZiAocmVmcyAhPSBudWxsKQorCQlyZWZzID0gTWltZVV0aWxpdHkudW5mb2xkKHJlZnMpICsgIiAiICsgbXNnSWQ7CisJICAgIGVsc2UKKwkJcmVmcyA9IG1zZ0lkOworCX0KKwlpZiAocmVmcyAhPSBudWxsKQorCSAgICByZXBseS5zZXRIZWFkZXIoIlJlZmVyZW5jZXMiLCBNaW1lVXRpbGl0eS5mb2xkKDEyLCByZWZzKSk7CisKKwlpZiAoc2V0QW5zd2VyZWQpIHsKKwkgICAgdHJ5IHsKKwkJc2V0RmxhZ3MoYW5zd2VyZWRGbGFnLCB0cnVlKTsKKwkgICAgfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIG1leCkgeworCQkvLyBpZ25vcmUgaXQKKwkgICAgfQorCX0KKwlyZXR1cm4gcmVwbHk7CisgICAgfQorCisgICAgLy8gdXNlZCBhYm92ZSBpbiByZXBseSgpCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRmxhZ3MgYW5zd2VyZWRGbGFnID0gbmV3IEZsYWdzKEZsYWdzLkZsYWcuQU5TV0VSRUQpOworCisgICAgLyoqCisgICAgICogQ2hlY2sgYWRkcnMgZm9yIGFueSBkdXBsaWNhdGVzIHRoYXQgbWF5IGFscmVhZHkgYmUgaW4gdi4KKyAgICAgKiBSZXR1cm4gYSBuZXcgYXJyYXkgd2l0aG91dCB0aGUgZHVwbGljYXRlcy4gIEFkZCBhbnkgbmV3CisgICAgICogYWRkcmVzc2VzIHRvIHYuICBOb3RlIHRoYXQgdGhlIGlucHV0IGFycmF5IG1heSBiZSBtb2RpZmllZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIEFkZHJlc3NbXSBlbGltaW5hdGVEdXBsaWNhdGVzKExpc3Q8QWRkcmVzcz4gdiwgQWRkcmVzc1tdIGFkZHJzKSB7CisJaWYgKGFkZHJzID09IG51bGwpCisJICAgIHJldHVybiBudWxsOworCWludCBnb25lID0gMDsKKwlmb3IgKGludCBpID0gMDsgaSA8IGFkZHJzLmxlbmd0aDsgaSsrKSB7CisJICAgIGJvb2xlYW4gZm91bmQgPSBmYWxzZTsKKwkgICAgLy8gc2VhcmNoIHRoZSBsaXN0IGZvciB0aGlzIGFkZHJlc3MKKwkgICAgZm9yIChpbnQgaiA9IDA7IGogPCB2LnNpemUoKTsgaisrKSB7CisJCWlmICgoKEludGVybmV0QWRkcmVzcyl2LmdldChqKSkuZXF1YWxzKGFkZHJzW2ldKSkgeworCQkgICAgLy8gZm91bmQgaXQ7IGNvdW50IGl0IGFuZCByZW1vdmUgaXQgZnJvbSB0aGUgaW5wdXQgYXJyYXkKKwkJICAgIGZvdW5kID0gdHJ1ZTsKKwkJICAgIGdvbmUrKzsKKwkJICAgIGFkZHJzW2ldID0gbnVsbDsKKwkJICAgIGJyZWFrOworCQl9CisJICAgIH0KKwkgICAgaWYgKCFmb3VuZCkKKwkJdi5hZGQoYWRkcnNbaV0pOwkvLyBhZGQgbmV3IGFkZHJlc3MgdG8gbGlzdAorCX0KKwkvLyBpZiB3ZSBmb3VuZCBhbnkgZHVwbGljYXRlcywgc3F1aXNoIHRoZSBhcnJheQorCWlmIChnb25lICE9IDApIHsKKwkgICAgQWRkcmVzc1tdIGE7CisJICAgIC8vIG5ldyBhcnJheSBzaG91bGQgYmUgc2FtZSB0eXBlIGFzIG9yaWdpbmFsIGFycmF5CisJICAgIC8vIFhYWCAtIHRoZXJlIG11c3QgYmUgYSBiZXR0ZXIgd2F5LCBwZXJoYXBzIHJlZmxlY3Rpb24/CisJICAgIGlmIChhZGRycyBpbnN0YW5jZW9mIEludGVybmV0QWRkcmVzc1tdKQorCQlhID0gbmV3IEludGVybmV0QWRkcmVzc1thZGRycy5sZW5ndGggLSBnb25lXTsKKwkgICAgZWxzZQorCQlhID0gbmV3IEFkZHJlc3NbYWRkcnMubGVuZ3RoIC0gZ29uZV07CisJICAgIGZvciAoaW50IGkgPSAwLCBqID0gMDsgaSA8IGFkZHJzLmxlbmd0aDsgaSsrKQorCQlpZiAoYWRkcnNbaV0gIT0gbnVsbCkKKwkJICAgIGFbaisrXSA9IGFkZHJzW2ldOworCSAgICBhZGRycyA9IGE7CisJfQorCXJldHVybiBhZGRyczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBPdXRwdXQgdGhlIG1lc3NhZ2UgYXMgYW4gUkZDIDgyMiBmb3JtYXQgc3RyZWFtLiA8cD4KKyAgICAgKgorICAgICAqIE5vdGUgdGhhdCwgZGVwZW5kaW5nIG9uIGhvdyB0aGUgbWVzc2FnIHdhcyBjb25zdHJ1Y3RlZCwgaXQgbWF5CisgICAgICogdXNlIGEgdmFyaWV0eSBvZiBsaW5lIHRlcm1pbmF0aW9uIGNvbnZlbnRpb25zLiAgR2VuZXJhbGx5IHRoZQorICAgICAqIG91dHB1dCBzaG91bGQgYmUgc2VudCB0aHJvdWdoIGFuIGFwcHJvcHJpYXRlIEZpbHRlck91dHB1dFN0cmVhbQorICAgICAqIHRoYXQgY29udmVydHMgdGhlIGxpbmUgdGVybWluYXRvcnMgdG8gdGhlIGRlc2lyZWQgZm9ybSwgZWl0aGVyCisgICAgICogQ1JMRiBmb3IgTUlNRSBjb21wYXRpYmlsaXR5IGFuZCBmb3IgdXNlIGluIEludGVybmV0IHByb3RvY29scywKKyAgICAgKiBvciB0aGUgbG9jYWwgcGxhdGZvcm0ncyBsaW5lIHRlcm1pbmF0b3IgZm9yIHN0b3JhZ2UgaW4gYSBsb2NhbAorICAgICAqIHRleHQgZmlsZS4gPHA+CisgICAgICoKKyAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHRoZSA8Y29kZT53cml0ZVRvKE91dHB1dFN0cmVhbSwKKyAgICAgKiBTdHJpbmdbXSk8L2NvZGU+IG1ldGhvZCB3aXRoIGEgbnVsbCBpZ25vcmUgbGlzdC4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24gSU9FeGNlcHRpb24JaWYgYW4gZXJyb3Igb2NjdXJzIHdyaXRpbmcgdG8gdGhlIHN0cmVhbQorICAgICAqCQkJCW9yIGlmIGFuIGVycm9yIGlzIGdlbmVyYXRlZCBieSB0aGUKKyAgICAgKgkJCQlqYXZheC5hY3RpdmF0aW9uIGxheWVyLgorICAgICAqIEBleGNlcHRpb24gTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBvdGhlciBmYWlsdXJlcworICAgICAqIEBzZWUgamF2YXguYWN0aXZhdGlvbi5EYXRhSGFuZGxlciN3cml0ZVRvCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGVUbyhPdXRwdXRTdHJlYW0gb3MpCisJCQkJdGhyb3dzIElPRXhjZXB0aW9uLCBNZXNzYWdpbmdFeGNlcHRpb24geworCXdyaXRlVG8ob3MsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIE91dHB1dCB0aGUgbWVzc2FnZSBhcyBhbiBSRkMgODIyIGZvcm1hdCBzdHJlYW0sIHdpdGhvdXQKKyAgICAgKiBzcGVjaWZpZWQgaGVhZGVycy4gIElmIHRoZSA8Y29kZT5zYXZlZDwvY29kZT4gZmxhZyBpcyBub3Qgc2V0LAorICAgICAqIHRoZSA8Y29kZT5zYXZlQ2hhbmdlczwvY29kZT4gbWV0aG9kIGlzIGNhbGxlZC4KKyAgICAgKiBJZiB0aGUgPGNvZGU+bW9kaWZpZWQ8L2NvZGU+IGZsYWcgaXMgbm90CisgICAgICogc2V0IGFuZCB0aGUgPGNvZGU+Y29udGVudDwvY29kZT4gYXJyYXkgaXMgbm90IG51bGwsIHRoZQorICAgICAqIDxjb2RlPmNvbnRlbnQ8L2NvZGU+IGFycmF5IGlzIHdyaXR0ZW4gZGlyZWN0bHksIGFmdGVyCisgICAgICogd3JpdGluZyB0aGUgYXBwcm9wcmlhdGUgbWVzc2FnZSBoZWFkZXJzLgorICAgICAqCisgICAgICogQHBhcmFtCW9zCQl0aGUgc3RyZWFtIHRvIHdyaXRlIHRvCisgICAgICogQHBhcmFtCWlnbm9yZUxpc3QJdGhlIGhlYWRlcnMgdG8gbm90IGluY2x1ZGUgaW4gdGhlIG91dHB1dAorICAgICAqIEBleGNlcHRpb24gSU9FeGNlcHRpb24JaWYgYW4gZXJyb3Igb2NjdXJzIHdyaXRpbmcgdG8gdGhlIHN0cmVhbQorICAgICAqCQkJCW9yIGlmIGFuIGVycm9yIGlzIGdlbmVyYXRlZCBieSB0aGUKKyAgICAgKgkJCQlqYXZheC5hY3RpdmF0aW9uIGxheWVyLgorICAgICAqIEBleGNlcHRpb24gamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICogQHNlZSBqYXZheC5hY3RpdmF0aW9uLkRhdGFIYW5kbGVyI3dyaXRlVG8KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKE91dHB1dFN0cmVhbSBvcywgU3RyaW5nW10gaWdub3JlTGlzdCkKKwkJCQl0aHJvd3MgSU9FeGNlcHRpb24sIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKCFzYXZlZCkKKwkgICAgc2F2ZUNoYW5nZXMoKTsKKworCWlmIChtb2RpZmllZCkgeworCSAgICBNaW1lQm9keVBhcnQud3JpdGVUbyh0aGlzLCBvcywgaWdub3JlTGlzdCk7CisJICAgIHJldHVybjsKKwl9CisKKwkvLyBFbHNlLCB0aGUgY29udGVudCBpcyB1bnRvdWNoZWQsIHNvIHdlIGNhbiBqdXN0IG91dHB1dCBpdAorCS8vIEZpcnN0LCB3cml0ZSBvdXQgdGhlIGhlYWRlcgorCUVudW1lcmF0aW9uPFN0cmluZz4gaGRyTGluZXMgPSBnZXROb25NYXRjaGluZ0hlYWRlckxpbmVzKGlnbm9yZUxpc3QpOworCUxpbmVPdXRwdXRTdHJlYW0gbG9zID0gbmV3IExpbmVPdXRwdXRTdHJlYW0ob3MsIGFsbG93dXRmOCk7CisJd2hpbGUgKGhkckxpbmVzLmhhc01vcmVFbGVtZW50cygpKQorCSAgICBsb3Mud3JpdGVsbihoZHJMaW5lcy5uZXh0RWxlbWVudCgpKTsKKworCS8vIFRoZSBDUkxGIHNlcGFyYXRvciBiZXR3ZWVuIGhlYWRlciBhbmQgY29udGVudAorCWxvcy53cml0ZWxuKCk7CisKKwkvLyBGaW5hbGx5LCB0aGUgY29udGVudC4gCisJaWYgKGNvbnRlbnQgPT0gbnVsbCkgeworCSAgICAvLyBjYWxsIGdldENvbnRlbnRTdHJlYW0gdG8gZ2l2ZSBzdWJjbGFzcyBhIGNoYW5jZSB0bworCSAgICAvLyBwcm92aWRlIHRoZSBkYXRhIG9uIGRlbWFuZAorCSAgICBJbnB1dFN0cmVhbSBpcyA9IG51bGw7CisJICAgIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVs4MTkyXTsKKwkgICAgdHJ5IHsKKwkJaXMgPSBnZXRDb250ZW50U3RyZWFtKCk7CisJCS8vIG5vdyBjb3B5IHRoZSBkYXRhIHRvIHRoZSBvdXRwdXQgc3RyZWFtCisJCWludCBsZW47CisJCXdoaWxlICgobGVuID0gaXMucmVhZChidWYpKSA+IDApCisJCSAgICBvcy53cml0ZShidWYsIDAsIGxlbik7CisJICAgIH0gZmluYWxseSB7CisJCWlmIChpcyAhPSBudWxsKQorCQkgICAgaXMuY2xvc2UoKTsKKwkJYnVmID0gbnVsbDsKKwkgICAgfQorCX0gZWxzZSB7CisJICAgIG9zLndyaXRlKGNvbnRlbnQpOworCX0KKwlvcy5mbHVzaCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCBhbGwgdGhlIGhlYWRlcnMgZm9yIHRoaXMgaGVhZGVyX25hbWUuIE5vdGUgdGhhdCBjZXJ0YWluCisgICAgICogaGVhZGVycyBtYXkgYmUgZW5jb2RlZCBhcyBwZXIgUkZDIDIwNDcgaWYgdGhleSBjb250YWluIAorICAgICAqIG5vbiBVUy1BU0NJSSBjaGFyYWN0ZXJzIGFuZCB0aGVzZSBzaG91bGQgYmUgZGVjb2RlZC4gPHA+CisgICAgICoKKyAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIG9idGFpbnMgdGhlIGhlYWRlcnMgZnJvbSB0aGUgCisgICAgICogPGNvZGU+aGVhZGVyczwvY29kZT4gSW50ZXJuZXRIZWFkZXJzIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbQluYW1lCW5hbWUgb2YgaGVhZGVyCisgICAgICogQHJldHVybglhcnJheSBvZiBoZWFkZXJzCisgICAgICogQGV4Y2VwdGlvbiAgICAgICBNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICogQHNlZSAJamF2YXgubWFpbC5pbnRlcm5ldC5NaW1lVXRpbGl0eQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRIZWFkZXIoU3RyaW5nIG5hbWUpCisJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gaGVhZGVycy5nZXRIZWFkZXIobmFtZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IGFsbCB0aGUgaGVhZGVycyBmb3IgdGhpcyBoZWFkZXIgbmFtZSwgcmV0dXJuZWQgYXMgYSBzaW5nbGUKKyAgICAgKiBTdHJpbmcsIHdpdGggaGVhZGVycyBzZXBhcmF0ZWQgYnkgdGhlIGRlbGltaXRlci4gSWYgdGhlCisgICAgICogZGVsaW1pdGVyIGlzIDxjb2RlPm51bGw8L2NvZGU+LCBvbmx5IHRoZSBmaXJzdCBoZWFkZXIgaXMgCisgICAgICogcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbmFtZQkJdGhlIG5hbWUgb2YgdGhpcyBoZWFkZXIKKyAgICAgKiBAcGFyYW0gZGVsaW1pdGVyCQlzZXBhcmF0b3IgYmV0d2VlbiB2YWx1ZXMKKyAgICAgKiBAcmV0dXJuICAgICAgICAgICAgICAgICAgdGhlIHZhbHVlIGZpZWxkcyBmb3IgYWxsIGhlYWRlcnMgd2l0aCAKKyAgICAgKgkJCQl0aGlzIG5hbWUKKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIAlNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXRIZWFkZXIoU3RyaW5nIG5hbWUsIFN0cmluZyBkZWxpbWl0ZXIpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJcmV0dXJuIGhlYWRlcnMuZ2V0SGVhZGVyKG5hbWUsIGRlbGltaXRlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSB2YWx1ZSBmb3IgdGhpcyBoZWFkZXJfbmFtZS4gUmVwbGFjZXMgYWxsIGV4aXN0aW5nCisgICAgICogaGVhZGVyIHZhbHVlcyB3aXRoIHRoaXMgbmV3IHZhbHVlLiBOb3RlIHRoYXQgUkZDIDgyMiBoZWFkZXJzCisgICAgICogbXVzdCBjb250YWluIG9ubHkgVVMtQVNDSUkgY2hhcmFjdGVycywgc28gYSBoZWFkZXIgdGhhdAorICAgICAqIGNvbnRhaW5zIG5vbiBVUy1BU0NJSSBjaGFyYWN0ZXJzIG11c3QgaGF2ZSBiZWVuIGVuY29kZWQgYnkgdGhlCisgICAgICogY2FsbGVyIGFzIHBlciB0aGUgcnVsZXMgb2YgUkZDIDIwNDcuCisgICAgICoKKyAgICAgKiBAcGFyYW0JbmFtZSAJaGVhZGVyIG5hbWUKKyAgICAgKiBAcGFyYW0JdmFsdWUJaGVhZGVyIHZhbHVlCisgICAgICogQHNlZSAJamF2YXgubWFpbC5pbnRlcm5ldC5NaW1lVXRpbGl0eQorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFdyaXRlRXhjZXB0aW9uIGlmIHRoZSB1bmRlcmx5aW5nCisgICAgICoJCQlpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IG1vZGlmaWNhdGlvbgorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgbWVzc2FnZSBpcworICAgICAqCQkJb2J0YWluZWQgZnJvbSBhIFJFQURfT05MWSBmb2xkZXIuCisgICAgICogQGV4Y2VwdGlvbiAgICAgICBNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0SGVhZGVyKFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsdWUpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWhlYWRlcnMuc2V0SGVhZGVyKG5hbWUsIHZhbHVlKTsJCisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkIHRoaXMgdmFsdWUgdG8gdGhlIGV4aXN0aW5nIHZhbHVlcyBmb3IgdGhpcyBoZWFkZXJfbmFtZS4KKyAgICAgKiBOb3RlIHRoYXQgUkZDIDgyMiBoZWFkZXJzIG11c3QgY29udGFpbiBvbmx5IFVTLUFTQ0lJIAorICAgICAqIGNoYXJhY3RlcnMsIHNvIGEgaGVhZGVyIHRoYXQgY29udGFpbnMgbm9uIFVTLUFTQ0lJIGNoYXJhY3RlcnMgCisgICAgICogbXVzdCBoYXZlIGJlZW4gZW5jb2RlZCBhcyBwZXIgdGhlIHJ1bGVzIG9mIFJGQyAyMDQ3LgorICAgICAqCisgICAgICogQHBhcmFtCW5hbWUgCWhlYWRlciBuYW1lCisgICAgICogQHBhcmFtCXZhbHVlCWhlYWRlciB2YWx1ZQorICAgICAqIEBzZWUgCWphdmF4Lm1haWwuaW50ZXJuZXQuTWltZVV0aWxpdHkKKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxXcml0ZUV4Y2VwdGlvbiBpZiB0aGUgdW5kZXJseWluZworICAgICAqCQkJaW1wbGVtZW50YXRpb24gZG9lcyBub3Qgc3VwcG9ydCBtb2RpZmljYXRpb24KKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIG1lc3NhZ2UgaXMKKyAgICAgKgkJCW9idGFpbmVkIGZyb20gYSBSRUFEX09OTFkgZm9sZGVyLgorICAgICAqIEBleGNlcHRpb24gICAgICAgTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBvdGhlciBmYWlsdXJlcworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGFkZEhlYWRlcihTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwloZWFkZXJzLmFkZEhlYWRlcihuYW1lLCB2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVtb3ZlIGFsbCBoZWFkZXJzIHdpdGggdGhpcyBuYW1lLgorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFdyaXRlRXhjZXB0aW9uIGlmIHRoZSB1bmRlcmx5aW5nCisgICAgICoJCQlpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IG1vZGlmaWNhdGlvbgorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgbWVzc2FnZSBpcworICAgICAqCQkJb2J0YWluZWQgZnJvbSBhIFJFQURfT05MWSBmb2xkZXIuCisgICAgICogQGV4Y2VwdGlvbiAgICAgICBNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcmVtb3ZlSGVhZGVyKFN0cmluZyBuYW1lKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwloZWFkZXJzLnJlbW92ZUhlYWRlcihuYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYWxsIHRoZSBoZWFkZXJzIGZyb20gdGhpcyBNZXNzYWdlIGFzIGFuIGVudW1lcmF0aW9uCisgICAgICogb2YgSGVhZGVyIG9iamVjdHMuIDxwPgorICAgICAqCisgICAgICogTm90ZSB0aGF0IGNlcnRhaW4gaGVhZGVycyBtYXkgYmUgZW5jb2RlZCBhcyBwZXIgUkZDIDIwNDcgCisgICAgICogaWYgdGhleSBjb250YWluIG5vbiBVUy1BU0NJSSBjaGFyYWN0ZXJzIGFuZCB0aGVzZSBzaG91bGQgCisgICAgICogYmUgZGVjb2RlZC4gPHA+CisgICAgICoKKyAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIG9idGFpbnMgdGhlIGhlYWRlcnMgZnJvbSB0aGUgCisgICAgICogPGNvZGU+aGVhZGVyczwvY29kZT4gSW50ZXJuZXRIZWFkZXJzIG9iamVjdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4JYXJyYXkgb2YgaGVhZGVyIG9iamVjdHMKKyAgICAgKiBAZXhjZXB0aW9uICBNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICogQHNlZSAJamF2YXgubWFpbC5pbnRlcm5ldC5NaW1lVXRpbGl0eQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBFbnVtZXJhdGlvbjxIZWFkZXI+IGdldEFsbEhlYWRlcnMoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gaGVhZGVycy5nZXRBbGxIZWFkZXJzKCk7CQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiBtYXRjaGluZyBoZWFkZXJzIGZyb20gdGhpcyBNZXNzYWdlIGFzIGFuIEVudW1lcmF0aW9uIG9mCisgICAgICogSGVhZGVyIG9iamVjdHMuIFRoaXMgaW1wbGVtZW50YXRpb24gb2J0YWlucyB0aGUgaGVhZGVycyBmcm9tCisgICAgICogdGhlIDxjb2RlPmhlYWRlcnM8L2NvZGU+IEludGVybmV0SGVhZGVycyBvYmplY3QuCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uICBNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEVudW1lcmF0aW9uPEhlYWRlcj4gZ2V0TWF0Y2hpbmdIZWFkZXJzKFN0cmluZ1tdIG5hbWVzKQorCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJcmV0dXJuIGhlYWRlcnMuZ2V0TWF0Y2hpbmdIZWFkZXJzKG5hbWVzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gbm9uLW1hdGNoaW5nIGhlYWRlcnMgZnJvbSB0aGlzIE1lc3NhZ2UgYXMgYW4KKyAgICAgKiBFbnVtZXJhdGlvbiBvZiBIZWFkZXIgb2JqZWN0cy4gVGhpcyBpbXBsZW1lbnRhdGlvbiAKKyAgICAgKiBvYnRhaW5zIHRoZSBoZWFkZXIgZnJvbSB0aGUgPGNvZGU+aGVhZGVyczwvY29kZT4gSW50ZXJuZXRIZWFkZXJzIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24gIE1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRW51bWVyYXRpb248SGVhZGVyPiBnZXROb25NYXRjaGluZ0hlYWRlcnMoU3RyaW5nW10gbmFtZXMpCisJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gaGVhZGVycy5nZXROb25NYXRjaGluZ0hlYWRlcnMobmFtZXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZCBhIHJhdyBSRkMgODIyIGhlYWRlci1saW5lLiAKKyAgICAgKgorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFdyaXRlRXhjZXB0aW9uIGlmIHRoZSB1bmRlcmx5aW5nCisgICAgICoJCQlpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IG1vZGlmaWNhdGlvbgorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgbWVzc2FnZSBpcworICAgICAqCQkJb2J0YWluZWQgZnJvbSBhIFJFQURfT05MWSBmb2xkZXIuCisgICAgICogQGV4Y2VwdGlvbiAgCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBhZGRIZWFkZXJMaW5lKFN0cmluZyBsaW5lKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwloZWFkZXJzLmFkZEhlYWRlckxpbmUobGluZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IGFsbCBoZWFkZXIgbGluZXMgYXMgYW4gRW51bWVyYXRpb24gb2YgU3RyaW5ncy4gQSBIZWFkZXIKKyAgICAgKiBsaW5lIGlzIGEgcmF3IFJGQyA4MjIgaGVhZGVyLWxpbmUsIGNvbnRhaW5pbmcgYm90aCB0aGUgIm5hbWUiIAorICAgICAqIGFuZCAidmFsdWUiIGZpZWxkLiAKKyAgICAgKgorICAgICAqIEBleGNlcHRpb24gIAlNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEVudW1lcmF0aW9uPFN0cmluZz4gZ2V0QWxsSGVhZGVyTGluZXMoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gaGVhZGVycy5nZXRBbGxIZWFkZXJMaW5lcygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCBtYXRjaGluZyBoZWFkZXIgbGluZXMgYXMgYW4gRW51bWVyYXRpb24gb2YgU3RyaW5ncy4gCisgICAgICogQSBIZWFkZXIgbGluZSBpcyBhIHJhdyBSRkMgODIyIGhlYWRlci1saW5lLCBjb250YWluaW5nIGJvdGggCisgICAgICogdGhlICJuYW1lIiBhbmQgInZhbHVlIiBmaWVsZC4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24gIAlNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEVudW1lcmF0aW9uPFN0cmluZz4gZ2V0TWF0Y2hpbmdIZWFkZXJMaW5lcyhTdHJpbmdbXSBuYW1lcykKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gaGVhZGVycy5nZXRNYXRjaGluZ0hlYWRlckxpbmVzKG5hbWVzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgbm9uLW1hdGNoaW5nIGhlYWRlciBsaW5lcyBhcyBhbiBFbnVtZXJhdGlvbiBvZiBTdHJpbmdzLiAKKyAgICAgKiBBIEhlYWRlciBsaW5lIGlzIGEgcmF3IFJGQyA4MjIgaGVhZGVyLWxpbmUsIGNvbnRhaW5pbmcgYm90aCAKKyAgICAgKiB0aGUgIm5hbWUiIGFuZCAidmFsdWUiIGZpZWxkLgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbiAgCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgRW51bWVyYXRpb248U3RyaW5nPiBnZXROb25NYXRjaGluZ0hlYWRlckxpbmVzKFN0cmluZ1tdIG5hbWVzKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXJldHVybiBoZWFkZXJzLmdldE5vbk1hdGNoaW5nSGVhZGVyTGluZXMobmFtZXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiBhIDxjb2RlPkZsYWdzPC9jb2RlPiBvYmplY3QgY29udGFpbmluZyB0aGUgZmxhZ3MgZm9yIAorICAgICAqIHRoaXMgbWVzc2FnZS4gPHA+CisgICAgICoKKyAgICAgKiBOb3RlIHRoYXQgYSBjbG9uZSBvZiB0aGUgaW50ZXJuYWwgRmxhZ3Mgb2JqZWN0IGlzIHJldHVybmVkLCBzbworICAgICAqIG1vZGlmeWluZyB0aGUgcmV0dXJuZWQgRmxhZ3Mgb2JqZWN0IHdpbGwgbm90IGFmZmVjdCB0aGUgZmxhZ3MKKyAgICAgKiBvZiB0aGlzIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcmV0dXJuICAgICAgICAgIEZsYWdzIG9iamVjdCBjb250YWluaW5nIHRoZSBmbGFncyBmb3IgdGhpcyBtZXNzYWdlCisgICAgICogQGV4Y2VwdGlvbiAgCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKiBAc2VlIAkJamF2YXgubWFpbC5GbGFncworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgRmxhZ3MgZ2V0RmxhZ3MoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gKEZsYWdzKWZsYWdzLmNsb25lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2sgd2hldGhlciB0aGUgZmxhZyBzcGVjaWZpZWQgaW4gdGhlIDxjb2RlPmZsYWc8L2NvZGU+CisgICAgICogYXJndW1lbnQgaXMgc2V0IGluIHRoaXMgbWVzc2FnZS4gPHA+CisgICAgICoKKyAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIGNoZWNrcyB0aGlzIG1lc3NhZ2UncyBpbnRlcm5hbCAKKyAgICAgKiA8Y29kZT5mbGFnczwvY29kZT4gb2JqZWN0LgorICAgICAqCisgICAgICogQHBhcmFtIGZsYWcJdGhlIGZsYWcKKyAgICAgKiBAcmV0dXJuCQl2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIGZsYWcgZm9yIHRoaXMgbWVzc2FnZQorICAgICAqIEBleGNlcHRpb24gICAgICAgTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqIEBzZWUgCQlqYXZheC5tYWlsLkZsYWdzLkZsYWcKKyAgICAgKiBAc2VlCQlqYXZheC5tYWlsLkZsYWdzLkZsYWcjQU5TV0VSRUQKKyAgICAgKiBAc2VlCQlqYXZheC5tYWlsLkZsYWdzLkZsYWcjREVMRVRFRAorICAgICAqIEBzZWUJCWphdmF4Lm1haWwuRmxhZ3MuRmxhZyNEUkFGVAorICAgICAqIEBzZWUJCWphdmF4Lm1haWwuRmxhZ3MuRmxhZyNGTEFHR0VECisgICAgICogQHNlZQkJamF2YXgubWFpbC5GbGFncy5GbGFnI1JFQ0VOVAorICAgICAqIEBzZWUJCWphdmF4Lm1haWwuRmxhZ3MuRmxhZyNTRUVOCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIGlzU2V0KEZsYWdzLkZsYWcgZmxhZykKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gKGZsYWdzLmNvbnRhaW5zKGZsYWcpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIGZsYWdzIGZvciB0aGlzIG1lc3NhZ2UuIDxwPgorICAgICAqCisgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiBtb2RpZmllcyB0aGUgPGNvZGU+ZmxhZ3M8L2NvZGU+IGZpZWxkLgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsV3JpdGVFeGNlcHRpb24gaWYgdGhlIHVuZGVybHlpbmcKKyAgICAgKgkJCWltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBtZXNzYWdlIGlzCisgICAgICoJCQlvYnRhaW5lZCBmcm9tIGEgUkVBRF9PTkxZIGZvbGRlci4KKyAgICAgKiBAZXhjZXB0aW9uICAJTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBvdGhlciBmYWlsdXJlcworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXRGbGFncyhGbGFncyBmbGFnLCBib29sZWFuIHNldCkKKwkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWlmIChzZXQpCisJICAgIGZsYWdzLmFkZChmbGFnKTsKKwllbHNlCisJICAgIGZsYWdzLnJlbW92ZShmbGFnKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIHRoZSBhcHByb3ByaWF0ZSBoZWFkZXIgZmllbGRzIG9mIHRoaXMgbWVzc2FnZSB0byBiZQorICAgICAqIGNvbnNpc3RlbnQgd2l0aCB0aGUgbWVzc2FnZSdzIGNvbnRlbnRzLiBJZiB0aGlzIG1lc3NhZ2UgaXMKKyAgICAgKiBjb250YWluZWQgaW4gYSBGb2xkZXIsIGFueSBjaGFuZ2VzIG1hZGUgdG8gdGhpcyBtZXNzYWdlIGFyZQorICAgICAqIGNvbW1pdHRlZCB0byB0aGUgY29udGFpbmluZyBmb2xkZXIuIDxwPgorICAgICAqCisgICAgICogSWYgYW55IHBhcnQgb2YgYSBtZXNzYWdlJ3MgaGVhZGVycyBvciBjb250ZW50cyBhcmUgY2hhbmdlZCwKKyAgICAgKiA8Y29kZT5zYXZlQ2hhbmdlczwvY29kZT4gbXVzdCBiZSBjYWxsZWQgdG8gZW5zdXJlIHRoYXQgdGhvc2UKKyAgICAgKiBjaGFuZ2VzIGFyZSBwZXJtYW5lbnQuIE90aGVyd2lzZSwgYW55IHN1Y2ggbW9kaWZpY2F0aW9ucyBtYXkgb3IgCisgICAgICogbWF5IG5vdCBiZSBzYXZlZCwgZGVwZW5kaW5nIG9uIHRoZSBmb2xkZXIgaW1wbGVtZW50YXRpb24uIDxwPgorICAgICAqCisgICAgICogTWVzc2FnZXMgb2J0YWluZWQgZnJvbSBmb2xkZXJzIG9wZW5lZCBSRUFEX09OTFkgc2hvdWxkIG5vdCBiZQorICAgICAqIG1vZGlmaWVkIGFuZCBzYXZlQ2hhbmdlcyBzaG91bGQgbm90IGJlIGNhbGxlZCBvbiBzdWNoIG1lc3NhZ2VzLiA8cD4KKyAgICAgKgorICAgICAqIFRoaXMgbWV0aG9kIHNldHMgdGhlIDxjb2RlPm1vZGlmaWVkPC9jb2RlPiBmbGFnIHRvIHRydWUsIHRoZQorICAgICAqIDxjb2RlPnNhdmU8L2NvZGU+IGZsYWcgdG8gdHJ1ZSwgYW5kIHRoZW4gY2FsbHMgdGhlCisgICAgICogPGNvZGU+dXBkYXRlSGVhZGVyczwvY29kZT4gbWV0aG9kLgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsV3JpdGVFeGNlcHRpb24gaWYgdGhlIHVuZGVybHlpbmcKKyAgICAgKgkJCWltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBtZXNzYWdlIGlzCisgICAgICoJCQlvYnRhaW5lZCBmcm9tIGEgUkVBRF9PTkxZIGZvbGRlci4KKyAgICAgKiBAZXhjZXB0aW9uICAJTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBvdGhlciBmYWlsdXJlcworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNhdmVDaGFuZ2VzKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJbW9kaWZpZWQgPSB0cnVlOworCXNhdmVkID0gdHJ1ZTsKKwl1cGRhdGVIZWFkZXJzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVXBkYXRlIHRoZSBNZXNzYWdlLUlEIGhlYWRlci4gIFRoaXMgbWV0aG9kIGlzIGNhbGxlZAorICAgICAqIGJ5IHRoZSA8Y29kZT51cGRhdGVIZWFkZXJzPC9jb2RlPiBhbmQgYWxsb3dzIGEgc3ViY2xhc3MKKyAgICAgKiB0byBvdmVycmlkZSBvbmx5IHRoZSBhbGdvcml0aG0gZm9yIGNob29zaW5nIGEgTWVzc2FnZS1JRC4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24gIAlNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICogQHNpbmNlCQlKYXZhTWFpbCAxLjQKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCB1cGRhdGVNZXNzYWdlSUQoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlzZXRIZWFkZXIoIk1lc3NhZ2UtSUQiLCAKKwkJICAiPCIgKyBVbmlxdWVWYWx1ZS5nZXRVbmlxdWVNZXNzYWdlSURWYWx1ZShzZXNzaW9uKSArICI+Iik7CisgICAgICAgICAgCisgICAgfQkKKworICAgIC8qKgorICAgICAqIENhbGxlZCBieSB0aGUgPGNvZGU+c2F2ZUNoYW5nZXM8L2NvZGU+IG1ldGhvZCB0byBhY3R1YWxseQorICAgICAqIHVwZGF0ZSB0aGUgTUlNRSBoZWFkZXJzLiAgVGhlIGltcGxlbWVudGF0aW9uIGhlcmUgc2V0cyB0aGUKKyAgICAgKiA8Y29kZT5Db250ZW50LVRyYW5zZmVyLUVuY29kaW5nPC9jb2RlPiBoZWFkZXIgKGlmIG5lZWRlZAorICAgICAqIGFuZCBub3QgYWxyZWFkeSBzZXQpLCB0aGUgPGNvZGU+RGF0ZTwvY29kZT4gaGVhZGVyIChpZgorICAgICAqIG5vdCBhbHJlYWR5IHNldCksIHRoZSA8Y29kZT5NSU1FLVZlcnNpb248L2NvZGU+IGhlYWRlcgorICAgICAqIGFuZCB0aGUgPGNvZGU+TWVzc2FnZS1JRDwvY29kZT4gaGVhZGVyLiBBbHNvLCBpZiB0aGUgY29udGVudAorICAgICAqIG9mIHRoaXMgbWVzc2FnZSBpcyBhIDxjb2RlPk1pbWVNdWx0aXBhcnQ8L2NvZGU+LCBpdHMKKyAgICAgKiA8Y29kZT51cGRhdGVIZWFkZXJzPC9jb2RlPiBtZXRob2QgaXMgY2FsbGVkLiA8cD4KKyAgICAgKgorICAgICAqIElmIHRoZSB7QGxpbmsgI2NhY2hlZENvbnRlbnR9IGZpZWxkIGlzIG5vdCBudWxsICh0aGF0IGlzLAorICAgICAqIGl0IHJlZmVyZW5jZXMgYSBNdWx0aXBhcnQgb3IgTWVzc2FnZSBvYmplY3QpLCB0aGVuCisgICAgICogdGhhdCBvYmplY3QgaXMgdXNlZCB0byBzZXQgYSBuZXcgRGF0YUhhbmRsZXIsIGFueQorICAgICAqIHN0cmVhbSBkYXRhIHVzZWQgdG8gY3JlYXRlIHRoaXMgb2JqZWN0IGlzIGRpc2NhcmRlZCwKKyAgICAgKiBhbmQgdGhlIHtAbGluayAjY2FjaGVkQ29udGVudH0gZmllbGQgaXMgY2xlYXJlZC4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFdyaXRlRXhjZXB0aW9uIGlmIHRoZSB1bmRlcmx5aW5nCisgICAgICoJCQlpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IG1vZGlmaWNhdGlvbgorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgbWVzc2FnZSBpcworICAgICAqCQkJb2J0YWluZWQgZnJvbSBhIFJFQURfT05MWSBmb2xkZXIuCisgICAgICogQGV4Y2VwdGlvbiAgCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3luY2hyb25pemVkIHZvaWQgdXBkYXRlSGVhZGVycygpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCU1pbWVCb2R5UGFydC51cGRhdGVIZWFkZXJzKHRoaXMpOwkKKwlzZXRIZWFkZXIoIk1JTUUtVmVyc2lvbiIsICIxLjAiKTsKKwlpZiAoZ2V0SGVhZGVyKCJEYXRlIikgPT0gbnVsbCkKKwkgICAgc2V0U2VudERhdGUobmV3IERhdGUoKSk7CisgICAgICAgIHVwZGF0ZU1lc3NhZ2VJRCgpOworCisJaWYgKGNhY2hlZENvbnRlbnQgIT0gbnVsbCkgeworCSAgICBkaCA9IG5ldyBEYXRhSGFuZGxlcihjYWNoZWRDb250ZW50LCBnZXRDb250ZW50VHlwZSgpKTsKKwkgICAgY2FjaGVkQ29udGVudCA9IG51bGw7CisJICAgIGNvbnRlbnQgPSBudWxsOworCSAgICBpZiAoY29udGVudFN0cmVhbSAhPSBudWxsKSB7CisJCXRyeSB7CisJCSAgICBjb250ZW50U3RyZWFtLmNsb3NlKCk7CisJCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZXgpIHsgfQkvLyBub3RoaW5nIHRvIGRvCisJICAgIH0KKwkgICAgY29udGVudFN0cmVhbSA9IG51bGw7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhbmQgcmV0dXJuIGFuIEludGVybmV0SGVhZGVycyBvYmplY3QgdGhhdCBsb2FkcyB0aGUKKyAgICAgKiBoZWFkZXJzIGZyb20gdGhlIGdpdmVuIElucHV0U3RyZWFtLiAgU3ViY2xhc3NlcyBjYW4gb3ZlcnJpZGUKKyAgICAgKiB0aGlzIG1ldGhvZCB0byByZXR1cm4gYSBzdWJjbGFzcyBvZiBJbnRlcm5ldEhlYWRlcnMsIGlmCisgICAgICogbmVjZXNzYXJ5LiAgVGhpcyBpbXBsZW1lbnRhdGlvbiBzaW1wbHkgY29uc3RydWN0cyBhbmQgcmV0dXJucworICAgICAqIGFuIEludGVybmV0SGVhZGVycyBvYmplY3QuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCWFuIEludGVybmV0SGVhZGVycyBvYmplY3QKKyAgICAgKiBAcGFyYW0JaXMJdGhlIElucHV0U3RyZWFtIHRvIHJlYWQgdGhlIGhlYWRlcnMgZnJvbQorICAgICAqIEBleGNlcHRpb24gIAlNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICogQHNpbmNlCQlKYXZhTWFpbCAxLjIKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgSW50ZXJuZXRIZWFkZXJzIGNyZWF0ZUludGVybmV0SGVhZGVycyhJbnB1dFN0cmVhbSBpcykKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gbmV3IEludGVybmV0SGVhZGVycyhpcywgYWxsb3d1dGY4KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYW5kIHJldHVybiBhIE1pbWVNZXNzYWdlIG9iamVjdC4gIFRoZSByZXBseSBtZXRob2QKKyAgICAgKiB1c2VzIHRoaXMgbWV0aG9kIHRvIGNyZWF0ZSB0aGUgTWltZU1lc3NhZ2Ugb2JqZWN0IHRoYXQgaXQKKyAgICAgKiB3aWxsIHJldHVybi4gIFN1YmNsYXNzZXMgY2FuIG92ZXJyaWRlIHRoaXMgbWV0aG9kIHRvIHJldHVybgorICAgICAqIGEgc3ViY2xhc3Mgb2YgTWltZU1lc3NhZ2UuICBUaGlzIGltcGxlbWVudGF0aW9uIHNpbXBseSBjb25zdHJ1Y3RzCisgICAgICogYW5kIHJldHVybnMgYSBNaW1lTWVzc2FnZSBvYmplY3QgdXNpbmcgdGhlIHN1cHBsaWVkIFNlc3Npb24uCisgICAgICoKKyAgICAgKiBAcGFyYW0Jc2Vzc2lvbgl0aGUgU2Vzc2lvbiB0byB1c2UgZm9yIHRoZSBuZXcgbWVzc2FnZQorICAgICAqIEByZXR1cm4JCXRoZSBuZXcgTWltZU1lc3NhZ2Ugb2JqZWN0CisgICAgICogQGV4Y2VwdGlvbiAgCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuNAorICAgICAqLworICAgIHByb3RlY3RlZCBNaW1lTWVzc2FnZSBjcmVhdGVNaW1lTWVzc2FnZShTZXNzaW9uIHNlc3Npb24pCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJcmV0dXJuIG5ldyBNaW1lTWVzc2FnZShzZXNzaW9uKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9NaW1lTXVsdGlwYXJ0LmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9NaW1lTXVsdGlwYXJ0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDQwOTBlZQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2ludGVybmV0L01pbWVNdWx0aXBhcnQuamF2YQpAQCAtMCwwICsxLDEwMDkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5pbnRlcm5ldDsKKworaW1wb3J0IGphdmF4Lm1haWwuKjsKK2ltcG9ydCBqYXZheC5hY3RpdmF0aW9uLio7CitpbXBvcnQgamF2YS51dGlsLio7CitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLkxpbmVPdXRwdXRTdHJlYW07CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuTGluZUlucHV0U3RyZWFtOworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLkFTQ0lJVXRpbGl0eTsKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5Qcm9wVXRpbDsKKworLyoqCisgKiBUaGUgTWltZU11bHRpcGFydCBjbGFzcyBpcyBhbiBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgYWJzdHJhY3QgTXVsdGlwYXJ0CisgKiBjbGFzcyB0aGF0IHVzZXMgTUlNRSBjb252ZW50aW9ucyBmb3IgdGhlIG11bHRpcGFydCBkYXRhLiA8cD4KKyAqCisgKiBBIE1pbWVNdWx0aXBhcnQgaXMgb2J0YWluZWQgZnJvbSBhIE1pbWVQYXJ0IHdob3NlIHByaW1hcnkgdHlwZQorICogaXMgIm11bHRpcGFydCIgKGJ5IGludm9raW5nIHRoZSBwYXJ0J3MgPGNvZGU+Z2V0Q29udGVudCgpPC9jb2RlPiBtZXRob2QpCisgKiBvciBpdCBjYW4gYmUgY3JlYXRlZCBieSBhIGNsaWVudCBhcyBwYXJ0IG9mIGNyZWF0aW5nIGEgbmV3IE1pbWVNZXNzYWdlLiA8cD4KKyAqCisgKiBUaGUgZGVmYXVsdCBtdWx0aXBhcnQgc3VidHlwZSBpcyAibWl4ZWQiLiAgVGhlIG90aGVyIG11bHRpcGFydAorICogc3VidHlwZXMsIHN1Y2ggYXMgImFsdGVybmF0aXZlIiwgInJlbGF0ZWQiLCBhbmQgc28gb24sIGNhbiBiZQorICogaW1wbGVtZW50ZWQgYXMgc3ViY2xhc3NlcyBvZiBNaW1lTXVsdGlwYXJ0IHdpdGggYWRkaXRpb25hbCBtZXRob2RzCisgKiB0byBpbXBsZW1lbnQgdGhlIGFkZGl0aW9uYWwgc2VtYW50aWNzIG9mIHRoYXQgdHlwZSBvZiBtdWx0aXBhcnQKKyAqIGNvbnRlbnQuIFRoZSBpbnRlbnQgaXMgdGhhdCBzZXJ2aWNlIHByb3ZpZGVycywgbWFpbCBKYXZhQmVhbiB3cml0ZXJzCisgKiBhbmQgbWFpbCBjbGllbnRzIHdpbGwgd3JpdGUgbWFueSBzdWNoIHN1YmNsYXNzZXMgYW5kIHRoZWlyIENvbW1hbmQKKyAqIEJlYW5zLCBhbmQgd2lsbCBpbnN0YWxsIHRoZW0gaW50byB0aGUgSmF2YUJlYW5zIEFjdGl2YXRpb24KKyAqIEZyYW1ld29yaywgc28gdGhhdCBhbnkgSmF2YU1haWwgaW1wbGVtZW50YXRpb24gYW5kIGl0cyBjbGllbnRzIGNhbgorICogdHJhbnNwYXJlbnRseSBmaW5kIGFuZCB1c2UgdGhlc2UgY2xhc3Nlcy4gVGh1cywgYSBNSU1FIG11bHRpcGFydAorICogaGFuZGxlciBpcyB0cmVhdGVkIGp1c3QgbGlrZSBhbnkgb3RoZXIgdHlwZSBoYW5kbGVyLCB0aGVyZWJ5CisgKiBkZWNvdXBsaW5nIHRoZSBwcm9jZXNzIG9mIHByb3ZpZGluZyBtdWx0aXBhcnQgaGFuZGxlcnMgZnJvbSB0aGUKKyAqIEphdmFNYWlsIEFQSS4gTGFja2luZyB0aGVzZSBhZGRpdGlvbmFsIE1pbWVNdWx0aXBhcnQgc3ViY2xhc3NlcywKKyAqIGFsbCBzdWJ0eXBlcyBvZiBNSU1FIG11bHRpcGFydCBkYXRhIGFwcGVhciBhcyBNaW1lTXVsdGlwYXJ0IG9iamVjdHMuIDxwPgorICoKKyAqIEFuIGFwcGxpY2F0aW9uIGNhbiBkaXJlY3RseSBjb25zdHJ1Y3QgYSBNSU1FIG11bHRpcGFydCBvYmplY3Qgb2YgYW55CisgKiBzdWJ0eXBlIGJ5IHVzaW5nIHRoZSA8Y29kZT5NaW1lTXVsdGlwYXJ0KFN0cmluZyBzdWJ0eXBlKTwvY29kZT4KKyAqIGNvbnN0cnVjdG9yLiAgRm9yIGV4YW1wbGUsIHRvIGNyZWF0ZSBhICJtdWx0aXBhcnQvYWx0ZXJuYXRpdmUiIG9iamVjdCwKKyAqIHVzZSA8Y29kZT5uZXcgTWltZU11bHRpcGFydCgiYWx0ZXJuYXRpdmUiKTwvY29kZT4uIDxwPgorICoKKyAqIFRoZSA8Y29kZT5tYWlsLm1pbWUubXVsdGlwYXJ0Lmlnbm9yZW1pc3NpbmdlbmRib3VuZGFyeTwvY29kZT4KKyAqIHByb3BlcnR5IG1heSBiZSBzZXQgdG8gPGNvZGU+ZmFsc2U8L2NvZGU+IHRvIGNhdXNlIGEKKyAqIDxjb2RlPk1lc3NhZ2luZ0V4Y2VwdGlvbjwvY29kZT4gdG8gYmUgdGhyb3duIGlmIHRoZSBtdWx0aXBhcnQKKyAqIGRhdGEgZG9lcyBub3QgZW5kIHdpdGggdGhlIHJlcXVpcmVkIGVuZCBib3VuZGFyeSBsaW5lLiAgSWYgdGhpcworICogcHJvcGVydHkgaXMgc2V0IHRvIDxjb2RlPnRydWU8L2NvZGU+IG9yIG5vdCBzZXQsIG1pc3NpbmcgZW5kCisgKiBib3VuZGFyaWVzIGFyZSBub3QgY29uc2lkZXJlZCBhbiBlcnJvciBhbmQgdGhlIGZpbmFsIGJvZHkgcGFydAorICogZW5kcyBhdCB0aGUgZW5kIG9mIHRoZSBkYXRhLiA8cD4KKyAqCisgKiBUaGUgPGNvZGU+bWFpbC5taW1lLm11bHRpcGFydC5pZ25vcmVtaXNzaW5nYm91bmRhcnlwYXJhbWV0ZXI8L2NvZGU+CisgKiBTeXN0ZW0gcHJvcGVydHkgbWF5IGJlIHNldCB0byA8Y29kZT5mYWxzZTwvY29kZT4gdG8gY2F1c2UgYQorICogPGNvZGU+TWVzc2FnaW5nRXhjZXB0aW9uPC9jb2RlPiB0byBiZSB0aHJvd24gaWYgdGhlIENvbnRlbnQtVHlwZQorICogb2YgdGhlIE1pbWVNdWx0aXBhcnQgZG9lcyBub3QgaW5jbHVkZSBhIDxjb2RlPmJvdW5kYXJ5PC9jb2RlPiBwYXJhbWV0ZXIuCisgKiBJZiB0aGlzIHByb3BlcnR5IGlzIHNldCB0byA8Y29kZT50cnVlPC9jb2RlPiBvciBub3Qgc2V0LCB0aGUgbXVsdGlwYXJ0CisgKiBwYXJzaW5nIGNvZGUgd2lsbCBsb29rIGZvciBhIGxpbmUgdGhhdCBsb29rcyBsaWtlIGEgYm91bmFyeSBsaW5lIGFuZAorICogdXNlIHRoYXQgYXMgdGhlIGJvdW5kYXJ5IHNlcGFyYXRpbmcgdGhlIHBhcnRzLiA8cD4KKyAqCisgKiBUaGUgPGNvZGU+bWFpbC5taW1lLm11bHRpcGFydC5pZ25vcmVleGlzdGluZ2JvdW5kYXJ5cGFyYW1ldGVyPC9jb2RlPgorICogU3lzdGVtIHByb3BlcnR5IG1heSBiZSBzZXQgdG8gPGNvZGU+dHJ1ZTwvY29kZT4gdG8gY2F1c2UgYW55IGJvdW5kYXJ5CisgKiB0byBiZSBpZ25vcmVkIGFuZCBpbnN0ZWFkIHNlYXJjaCBmb3IgYSBib3VuZGFyeSBsaW5lIGluIHRoZSBtZXNzYWdlCisgKiBhcyB3aXRoIDxjb2RlPm1haWwubWltZS5tdWx0aXBhcnQuaWdub3JlbWlzc2luZ2JvdW5kYXJ5cGFyYW1ldGVyPC9jb2RlPi4gPHA+CisgKgorICogTm9ybWFsbHksIHdoZW4gd3JpdGluZyBvdXQgYSBNaW1lTXVsdGlwYXJ0IHRoYXQgY29udGFpbnMgbm8gYm9keQorICogcGFydHMsIG9yIHdoZW4gdHJ5aW5nIHRvIHBhcnNlIGEgbXVsdGlwYXJ0IG1lc3NhZ2Ugd2l0aCBubyBib2R5IHBhcnRzLAorICogYSA8Y29kZT5NZXNzYWdpbmdFeGNlcHRpb248L2NvZGU+IGlzIHRocm93bi4gIFRoZSBNSU1FIHNwZWMgZG9lcyBub3QgYWxsb3cKKyAqIG11bHRpcGFydCBjb250ZW50IHdpdGggbm8gYm9keSBwYXJ0cy4gIFRoZQorICogPGNvZGU+bWFpbC5taW1lLm11bHRpcGFydC5hbGxvd2VtcHR5PC9jb2RlPiBTeXN0ZW0gcHJvcGVydHkgbWF5IGJlIHNldCB0bworICogPGNvZGU+dHJ1ZTwvY29kZT4gdG8gb3ZlcnJpZGUgdGhpcyBiZWhhdmlvci4KKyAqIFdoZW4gd3JpdGluZyBvdXQgc3VjaCBhIE1pbWVNdWx0aXBhcnQsIGEgc2luZ2xlIGVtcHR5IHBhcnQgd2lsbCBiZQorICogaW5jbHVkZWQuICBXaGVuIHJlYWRpbmcgc3VjaCBhIG11bHRpcGFydCwgYSBNaW1lTXVsdGlwYXJ0IHdpbGwgYmUgY3JlYXRlZAorICogd2l0aCBubyBib2R5IHBhcnRzLgorICoKKyAqIEBhdXRob3IgIEpvaG4gTWFuaQorICogQGF1dGhvciAgQmlsbCBTaGFubm9uCisgKiBAYXV0aG9yICBNYXggU3BpdmFrCisgKi8KKworcHVibGljIGNsYXNzIE1pbWVNdWx0aXBhcnQgZXh0ZW5kcyBNdWx0aXBhcnQgeworCisgICAgLyoqCisgICAgICogVGhlIERhdGFTb3VyY2Ugc3VwcGx5aW5nIG91ciBJbnB1dFN0cmVhbS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgRGF0YVNvdXJjZSBkcyA9IG51bGw7CisKKyAgICAvKioKKyAgICAgKiBIYXZlIHdlIHBhcnNlZCB0aGUgZGF0YSBmcm9tIG91ciBJbnB1dFN0cmVhbSB5ZXQ/CisgICAgICogRGVmYXVsdHMgdG8gdHJ1ZTsgc2V0IHRvIGZhbHNlIHdoZW4gb3VyIGNvbnN0cnVjdG9yIGlzCisgICAgICogZ2l2ZW4gYSBEYXRhU291cmNlIHdpdGggYW4gSW5wdXRTdHJlYW0gdGhhdCB3ZSBuZWVkIHRvCisgICAgICogcGFyc2UuCisgICAgICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gcGFyc2VkID0gdHJ1ZTsKKworICAgIC8qKgorICAgICAqIEhhdmUgd2Ugc2VlbiB0aGUgZmluYWwgYm91bmFyeSBsaW5lPworICAgICAqCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNQorICAgICAqLworICAgIHByb3RlY3RlZCBib29sZWFuIGNvbXBsZXRlID0gdHJ1ZTsKKworICAgIC8qKgorICAgICAqIFRoZSBNSU1FIG11bHRpcGFydCBwcmVhbWJsZSB0ZXh0LCB0aGUgdGV4dCB0aGF0CisgICAgICogb2NjdXJzIGJlZm9yZSB0aGUgZmlyc3QgYm91bmRhcnkgbGluZS4KKyAgICAgKgorICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjUKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU3RyaW5nIHByZWFtYmxlID0gbnVsbDsKKworICAgIC8qKgorICAgICAqIEZsYWcgY29ycmVzcG9uZGluZyB0byB0aGUgIm1haWwubWltZS5tdWx0aXBhcnQuaWdub3JlbWlzc2luZ2VuZGJvdW5kYXJ5IgorICAgICAqIHByb3BlcnR5LCBzZXQgaW4gdGhlIHtAbGluayAjaW5pdGlhbGl6ZVByb3BlcnRpZXN9IG1ldGhvZCBjYWxsZWQgZnJvbQorICAgICAqIGNvbnN0cnVjdG9ycyBhbmQgdGhlIHBhcnNlIG1ldGhvZC4KKyAgICAgKgorICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjUKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpZ25vcmVNaXNzaW5nRW5kQm91bmRhcnkgPSB0cnVlOworCisgICAgLyoqCisgICAgICogRmxhZyBjb3JyZXNwb25kaW5nIHRvIHRoZQorICAgICAqICJtYWlsLm1pbWUubXVsdGlwYXJ0Lmlnbm9yZW1pc3Npbmdib3VuZGFyeXBhcmFtZXRlciIKKyAgICAgKiBwcm9wZXJ0eSwgc2V0IGluIHRoZSB7QGxpbmsgI2luaXRpYWxpemVQcm9wZXJ0aWVzfSBtZXRob2QgY2FsbGVkIGZyb20KKyAgICAgKiBjb25zdHJ1Y3RvcnMgYW5kIHRoZSBwYXJzZSBtZXRob2QuCisgICAgICoKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS41CisgICAgICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gaWdub3JlTWlzc2luZ0JvdW5kYXJ5UGFyYW1ldGVyID0gdHJ1ZTsKKworICAgIC8qKgorICAgICAqIEZsYWcgY29ycmVzcG9uZGluZyB0byB0aGUKKyAgICAgKiAibWFpbC5taW1lLm11bHRpcGFydC5pZ25vcmVleGlzdGluZ2JvdW5kYXJ5cGFyYW1ldGVyIgorICAgICAqIHByb3BlcnR5LCBzZXQgaW4gdGhlIHtAbGluayAjaW5pdGlhbGl6ZVByb3BlcnRpZXN9IG1ldGhvZCBjYWxsZWQgZnJvbQorICAgICAqIGNvbnN0cnVjdG9ycyBhbmQgdGhlIHBhcnNlIG1ldGhvZC4KKyAgICAgKgorICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjUKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpZ25vcmVFeGlzdGluZ0JvdW5kYXJ5UGFyYW1ldGVyID0gZmFsc2U7CisKKyAgICAvKioKKyAgICAgKiBGbGFnIGNvcnJlc3BvbmRpbmcgdG8gdGhlICJtYWlsLm1pbWUubXVsdGlwYXJ0LmFsbG93ZW1wdHkiCisgICAgICogcHJvcGVydHksIHNldCBpbiB0aGUge0BsaW5rICNpbml0aWFsaXplUHJvcGVydGllc30gbWV0aG9kIGNhbGxlZCBmcm9tCisgICAgICogY29uc3RydWN0b3JzIGFuZCB0aGUgcGFyc2UgbWV0aG9kLgorICAgICAqCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNQorICAgICAqLworICAgIHByb3RlY3RlZCBib29sZWFuIGFsbG93RW1wdHkgPSBmYWxzZTsKKworICAgIC8qKgorICAgICAqIERlZmF1bHQgY29uc3RydWN0b3IuIEFuIGVtcHR5IE1pbWVNdWx0aXBhcnQgb2JqZWN0CisgICAgICogaXMgY3JlYXRlZC4gSXRzIGNvbnRlbnQgdHlwZSBpcyBzZXQgdG8gIm11bHRpcGFydC9taXhlZCIuCisgICAgICogQSB1bmlxdWUgYm91bmRhcnkgc3RyaW5nIGlzIGdlbmVyYXRlZCBhbmQgdGhpcyBzdHJpbmcgaXMKKyAgICAgKiBzZXR1cCBhcyB0aGUgImJvdW5kYXJ5IiBwYXJhbWV0ZXIgZm9yIHRoZSAKKyAgICAgKiA8Y29kZT5jb250ZW50VHlwZTwvY29kZT4gZmllbGQuIDxwPgorICAgICAqCisgICAgICogTWltZUJvZHlQYXJ0cyBtYXkgYmUgYWRkZWQgbGF0ZXIuCisgICAgICovCisgICAgcHVibGljIE1pbWVNdWx0aXBhcnQoKSB7CisJdGhpcygibWl4ZWQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYSBNaW1lTXVsdGlwYXJ0IG9iamVjdCBvZiB0aGUgZ2l2ZW4gc3VidHlwZS4KKyAgICAgKiBBIHVuaXF1ZSBib3VuZGFyeSBzdHJpbmcgaXMgZ2VuZXJhdGVkIGFuZCB0aGlzIHN0cmluZyBpcworICAgICAqIHNldHVwIGFzIHRoZSAiYm91bmRhcnkiIHBhcmFtZXRlciBmb3IgdGhlIAorICAgICAqIDxjb2RlPmNvbnRlbnRUeXBlPC9jb2RlPiBmaWVsZC4KKyAgICAgKiBDYWxscyB0aGUge0BsaW5rICNpbml0aWFsaXplUHJvcGVydGllc30gbWV0aG9kLjxwPgorICAgICAqCisgICAgICogTWltZUJvZHlQYXJ0cyBtYXkgYmUgYWRkZWQgbGF0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jc3VidHlwZQl0aGUgTUlNRSBjb250ZW50IHN1YnR5cGUKKyAgICAgKi8KKyAgICBwdWJsaWMgTWltZU11bHRpcGFydChTdHJpbmcgc3VidHlwZSkgeworCXN1cGVyKCk7CisJLyoKKwkgKiBDb21wdXRlIGEgYm91bmRhcnkgc3RyaW5nLgorCSAqLworCVN0cmluZyBib3VuZGFyeSA9IFVuaXF1ZVZhbHVlLmdldFVuaXF1ZUJvdW5kYXJ5VmFsdWUoKTsKKwlDb250ZW50VHlwZSBjVHlwZSA9IG5ldyBDb250ZW50VHlwZSgibXVsdGlwYXJ0Iiwgc3VidHlwZSwgbnVsbCk7CisJY1R5cGUuc2V0UGFyYW1ldGVyKCJib3VuZGFyeSIsIGJvdW5kYXJ5KTsKKwljb250ZW50VHlwZSA9IGNUeXBlLnRvU3RyaW5nKCk7CisJaW5pdGlhbGl6ZVByb3BlcnRpZXMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYSBNaW1lTXVsdGlwYXJ0IG9iamVjdCBvZiB0aGUgZGVmYXVsdCAibWl4ZWQiIHN1YnR5cGUsCisgICAgICogYW5kIHdpdGggdGhlIGdpdmVuIGJvZHkgcGFydHMuICBNb3JlIGJvZHkgcGFydHMgbWF5IGJlIGFkZGVkIGxhdGVyLgorICAgICAqCisgICAgICogQHBhcmFtCXBhcnRzCXRoZSBib2R5IHBhcnRzCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNQorICAgICAqLworICAgIHB1YmxpYyBNaW1lTXVsdGlwYXJ0KEJvZHlQYXJ0Li4uIHBhcnRzKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwl0aGlzKCk7CisJZm9yIChCb2R5UGFydCBicCA6IHBhcnRzKQorCSAgICBzdXBlci5hZGRCb2R5UGFydChicCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGEgTWltZU11bHRpcGFydCBvYmplY3Qgb2YgdGhlIGdpdmVuIHN1YnR5cGUKKyAgICAgKiBhbmQgd2l0aCB0aGUgZ2l2ZW4gYm9keSBwYXJ0cy4gIE1vcmUgYm9keSBwYXJ0cyBtYXkgYmUgYWRkZWQgbGF0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jc3VidHlwZQl0aGUgTUlNRSBjb250ZW50IHN1YnR5cGUKKyAgICAgKiBAcGFyYW0JcGFydHMJdGhlIGJvZHkgcGFydHMKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS41CisgICAgICovCisgICAgcHVibGljIE1pbWVNdWx0aXBhcnQoU3RyaW5nIHN1YnR5cGUsIEJvZHlQYXJ0Li4uIHBhcnRzKQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXRoaXMoc3VidHlwZSk7CisJZm9yIChCb2R5UGFydCBicCA6IHBhcnRzKQorCSAgICBzdXBlci5hZGRCb2R5UGFydChicCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIE1pbWVNdWx0aXBhcnQgb2JqZWN0IGFuZCBpdHMgYm9keXBhcnRzIGZyb20gdGhlIAorICAgICAqIGdpdmVuIERhdGFTb3VyY2UuIDxwPgorICAgICAqCisgICAgICogVGhpcyBjb25zdHJ1Y3RvciBoYW5kbGVzIGFzIGEgc3BlY2lhbCBjYXNlIHRoZSBzaXR1YXRpb24gd2hlcmUgdGhlCisgICAgICogZ2l2ZW4gRGF0YVNvdXJjZSBpcyBhIE11bHRpcGFydERhdGFTb3VyY2Ugb2JqZWN0LiAgSW4gdGhpcyBjYXNlLCB0aGlzCisgICAgICogbWV0aG9kIGp1c3QgaW52b2tlcyB0aGUgc3VwZXJjbGFzcyAoaS5lLiwgTXVsdGlwYXJ0KSBjb25zdHJ1Y3RvcgorICAgICAqIHRoYXQgdGFrZXMgYSBNdWx0aXBhcnREYXRhU291cmNlIG9iamVjdC4gPHA+CisgICAgICoKKyAgICAgKiBPdGhlcndpc2UsIHRoZSBEYXRhU291cmNlIGlzIGFzc3VtZWQgdG8gcHJvdmlkZSBhIE1JTUUgbXVsdGlwYXJ0IAorICAgICAqIGJ5dGUgc3RyZWFtLiAgVGhlIDxjb2RlPnBhcnNlZDwvY29kZT4gZmxhZyBpcyBzZXQgdG8gZmFsc2UuICBXaGVuCisgICAgICogdGhlIGRhdGEgZm9yIHRoZSBib2R5IHBhcnRzIGFyZSBuZWVkZWQsIHRoZSBwYXJzZXIgZXh0cmFjdHMgdGhlCisgICAgICogImJvdW5kYXJ5IiBwYXJhbWV0ZXIgZnJvbSB0aGUgY29udGVudCB0eXBlIG9mIHRoaXMgRGF0YVNvdXJjZSwKKyAgICAgKiBza2lwcyB0aGUgJ3ByZWFtYmxlJyBhbmQgcmVhZHMgYnl0ZXMgdGlsbCB0aGUgdGVybWluYXRpbmcKKyAgICAgKiBib3VuZGFyeSBhbmQgY3JlYXRlcyBNaW1lQm9keVBhcnRzIGZvciBlYWNoIHBhcnQgb2YgdGhlIHN0cmVhbS4KKyAgICAgKgorICAgICAqIEBwYXJhbQlkcwlEYXRhU291cmNlLCBjYW4gYmUgYSBNdWx0aXBhcnREYXRhU291cmNlCisgICAgICogQGV4Y2VwdGlvbglQYXJzZUV4Y2VwdGlvbiBmb3IgZmFpbHVyZXMgcGFyc2luZyB0aGUgbWVzc2FnZQorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBvdGhlciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBNaW1lTXVsdGlwYXJ0KERhdGFTb3VyY2UgZHMpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXN1cGVyKCk7CisKKwlpZiAoZHMgaW5zdGFuY2VvZiBNZXNzYWdlQXdhcmUpIHsKKwkgICAgTWVzc2FnZUNvbnRleHQgbWMgPSAoKE1lc3NhZ2VBd2FyZSlkcykuZ2V0TWVzc2FnZUNvbnRleHQoKTsKKwkgICAgc2V0UGFyZW50KG1jLmdldFBhcnQoKSk7CisJfQorCisJaWYgKGRzIGluc3RhbmNlb2YgTXVsdGlwYXJ0RGF0YVNvdXJjZSkgeworCSAgICAvLyBhc2sgc3VwZXIgdG8gZG8gdGhpcyBmb3IgdXMuCisJICAgIHNldE11bHRpcGFydERhdGFTb3VyY2UoKE11bHRpcGFydERhdGFTb3VyY2UpZHMpOworCSAgICByZXR1cm47CisJfQorCisJLy8gJ2RzJyB3YXMgbm90IGEgTXVsdGlwYXJ0RGF0YVNvdXJjZSwgd2UgaGF2ZQorCS8vIHRvIHBhcnNlIHRoaXMgb3Vyc2VsZi4KKwlwYXJzZWQgPSBmYWxzZTsKKwl0aGlzLmRzID0gZHM7CisJY29udGVudFR5cGUgPSBkcy5nZXRDb250ZW50VHlwZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEluaXRpYWxpemUgZmxhZ3MgdGhhdCBjb250cm9sIHBhcnNpbmcgYmVoYXZpb3IsCisgICAgICogYmFzZWQgb24gU3lzdGVtIHByb3BlcnRpZXMgZGVzY3JpYmVkIGFib3ZlIGluCisgICAgICogdGhlIGNsYXNzIGRvY3VtZW50YXRpb24uCisgICAgICoKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS41CisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgaW5pdGlhbGl6ZVByb3BlcnRpZXMoKSB7CisJLy8gcmVhZCBwcm9wZXJ0aWVzIHRoYXQgY29udHJvbCBwYXJzaW5nCisKKwkvLyBkZWZhdWx0IHRvIHRydWUKKwlpZ25vcmVNaXNzaW5nRW5kQm91bmRhcnkgPSBQcm9wVXRpbC5nZXRCb29sZWFuU3lzdGVtUHJvcGVydHkoCisJICAgICJtYWlsLm1pbWUubXVsdGlwYXJ0Lmlnbm9yZW1pc3NpbmdlbmRib3VuZGFyeSIsIHRydWUpOworCS8vIGRlZmF1bHQgdG8gdHJ1ZQorCWlnbm9yZU1pc3NpbmdCb3VuZGFyeVBhcmFtZXRlciA9IFByb3BVdGlsLmdldEJvb2xlYW5TeXN0ZW1Qcm9wZXJ0eSgKKwkgICAgIm1haWwubWltZS5tdWx0aXBhcnQuaWdub3JlbWlzc2luZ2JvdW5kYXJ5cGFyYW1ldGVyIiwgdHJ1ZSk7CisJLy8gZGVmYXVsdCB0byBmYWxzZQorCWlnbm9yZUV4aXN0aW5nQm91bmRhcnlQYXJhbWV0ZXIgPSBQcm9wVXRpbC5nZXRCb29sZWFuU3lzdGVtUHJvcGVydHkoCisJICAgICJtYWlsLm1pbWUubXVsdGlwYXJ0Lmlnbm9yZWV4aXN0aW5nYm91bmRhcnlwYXJhbWV0ZXIiLCBmYWxzZSk7CisJLy8gZGVmYXVsdCB0byBmYWxzZQorCWFsbG93RW1wdHkgPSBQcm9wVXRpbC5nZXRCb29sZWFuU3lzdGVtUHJvcGVydHkoCisJICAgICJtYWlsLm1pbWUubXVsdGlwYXJ0LmFsbG93ZW1wdHkiLCBmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBzdWJ0eXBlLiBUaGlzIG1ldGhvZCBzaG91bGQgYmUgaW52b2tlZCBvbmx5IG9uIGEgbmV3CisgICAgICogTWltZU11bHRpcGFydCBvYmplY3QgY3JlYXRlZCBieSB0aGUgY2xpZW50LiBUaGUgZGVmYXVsdCBzdWJ0eXBlCisgICAgICogb2Ygc3VjaCBhIG11bHRpcGFydCBvYmplY3QgaXMgIm1peGVkIi4gPHA+CisgICAgICoKKyAgICAgKiBAcGFyYW0Jc3VidHlwZQkJU3VidHlwZQorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXRTdWJUeXBlKFN0cmluZyBzdWJ0eXBlKSAKKwkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCUNvbnRlbnRUeXBlIGNUeXBlID0gbmV3IENvbnRlbnRUeXBlKGNvbnRlbnRUeXBlKTsJCisJY1R5cGUuc2V0U3ViVHlwZShzdWJ0eXBlKTsKKwljb250ZW50VHlwZSA9IGNUeXBlLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBudW1iZXIgb2YgZW5jbG9zZWQgQm9keVBhcnQgb2JqZWN0cy4KKyAgICAgKgorICAgICAqIEByZXR1cm4JCW51bWJlciBvZiBwYXJ0cworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IGdldENvdW50KCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJcGFyc2UoKTsKKwlyZXR1cm4gc3VwZXIuZ2V0Q291bnQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIHNwZWNpZmllZCBCb2R5UGFydC4gIEJvZHlQYXJ0cyBhcmUgbnVtYmVyZWQgc3RhcnRpbmcgYXQgMC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbmRleAl0aGUgaW5kZXggb2YgdGhlIGRlc2lyZWQgQm9keVBhcnQKKyAgICAgKiBAcmV0dXJuCQl0aGUgUGFydAorICAgICAqIEBleGNlcHRpb24gICAgICAgTWVzc2FnaW5nRXhjZXB0aW9uIGlmIG5vIHN1Y2ggQm9keVBhcnQgZXhpc3RzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBCb2R5UGFydCBnZXRCb2R5UGFydChpbnQgaW5kZXgpIAorCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJcGFyc2UoKTsKKwlyZXR1cm4gc3VwZXIuZ2V0Qm9keVBhcnQoaW5kZXgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgTWltZUJvZHlQYXJ0IHJlZmVycmVkIHRvIGJ5IHRoZSBnaXZlbiBDb250ZW50SUQgKENJRCkuIAorICAgICAqIFJldHVybnMgbnVsbCBpZiB0aGUgcGFydCBpcyBub3QgZm91bmQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gIENJRCAJdGhlIENvbnRlbnRJRCBvZiB0aGUgZGVzaXJlZCBwYXJ0CisgICAgICogQHJldHVybiAgICAgICAgICB0aGUgUGFydAorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgQm9keVBhcnQgZ2V0Qm9keVBhcnQoU3RyaW5nIENJRCkgCisJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlwYXJzZSgpOworCisJaW50IGNvdW50ID0gZ2V0Q291bnQoKTsKKwlmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKKwkgICBNaW1lQm9keVBhcnQgcGFydCA9IChNaW1lQm9keVBhcnQpZ2V0Qm9keVBhcnQoaSk7CisJICAgU3RyaW5nIHMgPSBwYXJ0LmdldENvbnRlbnRJRCgpOworCSAgIGlmIChzICE9IG51bGwgJiYgcy5lcXVhbHMoQ0lEKSkKKwkJcmV0dXJuIHBhcnQ7ICAgIAorCX0KKwlyZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmUgdGhlIHNwZWNpZmllZCBwYXJ0IGZyb20gdGhlIG11bHRpcGFydCBtZXNzYWdlLgorICAgICAqIFNoaWZ0cyBhbGwgdGhlIHBhcnRzIGFmdGVyIHRoZSByZW1vdmVkIHBhcnQgZG93biBvbmUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gICBwYXJ0CVRoZSBwYXJ0IHRvIHJlbW92ZQorICAgICAqIEByZXR1cm4JCXRydWUgaWYgcGFydCByZW1vdmVkLCBmYWxzZSBvdGhlcndpc2UKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBpZiBubyBzdWNoIFBhcnQgZXhpc3RzCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsV3JpdGVFeGNlcHRpb24gaWYgdGhlIHVuZGVybHlpbmcKKyAgICAgKgkJCWltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uCisgICAgICoJCQlvZiBleGlzdGluZyB2YWx1ZXMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiByZW1vdmVCb2R5UGFydChCb2R5UGFydCBwYXJ0KSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlwYXJzZSgpOworCXJldHVybiBzdXBlci5yZW1vdmVCb2R5UGFydChwYXJ0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZW1vdmUgdGhlIHBhcnQgYXQgc3BlY2lmaWVkIGxvY2F0aW9uIChzdGFydGluZyBmcm9tIDApLgorICAgICAqIFNoaWZ0cyBhbGwgdGhlIHBhcnRzIGFmdGVyIHRoZSByZW1vdmVkIHBhcnQgZG93biBvbmUuCisgICAgICoKKyAgICAgKiBAcGFyYW0gICBpbmRleAlJbmRleCBvZiB0aGUgcGFydCB0byByZW1vdmUKKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWYgdGhlIGdpdmVuIGluZGV4CisgICAgICoJCQlpcyBvdXQgb2YgcmFuZ2UuCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsV3JpdGVFeGNlcHRpb24gaWYgdGhlIHVuZGVybHlpbmcKKyAgICAgKgkJCWltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uCisgICAgICoJCQlvZiBleGlzdGluZyB2YWx1ZXMKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCByZW1vdmVCb2R5UGFydChpbnQgaW5kZXgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXBhcnNlKCk7CisJc3VwZXIucmVtb3ZlQm9keVBhcnQoaW5kZXgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZHMgYSBQYXJ0IHRvIHRoZSBtdWx0aXBhcnQuICBUaGUgQm9keVBhcnQgaXMgYXBwZW5kZWQgdG8gCisgICAgICogdGhlIGxpc3Qgb2YgZXhpc3RpbmcgUGFydHMuCisgICAgICoKKyAgICAgKiBAcGFyYW0gIHBhcnQgIFRoZSBQYXJ0IHRvIGJlIGFwcGVuZGVkCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsV3JpdGVFeGNlcHRpb24gaWYgdGhlIHVuZGVybHlpbmcKKyAgICAgKgkJCWltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uCisgICAgICoJCQlvZiBleGlzdGluZyB2YWx1ZXMKKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIE1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgYWRkQm9keVBhcnQoQm9keVBhcnQgcGFydCkgCisJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXBhcnNlKCk7CisJc3VwZXIuYWRkQm9keVBhcnQocGFydCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQWRkcyBhIEJvZHlQYXJ0IGF0IHBvc2l0aW9uIDxjb2RlPmluZGV4PC9jb2RlPi4KKyAgICAgKiBJZiA8Y29kZT5pbmRleDwvY29kZT4gaXMgbm90IHRoZSBsYXN0IG9uZSBpbiB0aGUgbGlzdCwKKyAgICAgKiB0aGUgc3Vic2VxdWVudCBwYXJ0cyBhcmUgc2hpZnRlZCB1cC4gSWYgPGNvZGU+aW5kZXg8L2NvZGU+CisgICAgICogaXMgbGFyZ2VyIHRoYW4gdGhlIG51bWJlciBvZiBwYXJ0cyBwcmVzZW50LCB0aGUKKyAgICAgKiBCb2R5UGFydCBpcyBhcHBlbmRlZCB0byB0aGUgZW5kLgorICAgICAqCisgICAgICogQHBhcmFtICBwYXJ0ICBUaGUgQm9keVBhcnQgdG8gYmUgaW5zZXJ0ZWQKKyAgICAgKiBAcGFyYW0gIGluZGV4IExvY2F0aW9uIHdoZXJlIHRvIGluc2VydCB0aGUgcGFydAorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFdyaXRlRXhjZXB0aW9uIGlmIHRoZSB1bmRlcmx5aW5nCisgICAgICoJCQlpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IG1vZGlmaWNhdGlvbgorICAgICAqCQkJb2YgZXhpc3RpbmcgdmFsdWVzCisgICAgICogQGV4Y2VwdGlvbiAgICAgICBNZXNzYWdpbmdFeGNlcHRpb24gZm9yIG90aGVyIGZhaWx1cmVzCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGFkZEJvZHlQYXJ0KEJvZHlQYXJ0IHBhcnQsIGludCBpbmRleCkgCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJcGFyc2UoKTsKKwlzdXBlci5hZGRCb2R5UGFydChwYXJ0LCBpbmRleCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRydWUgaWYgdGhlIGZpbmFsIGJvdW5kYXJ5IGxpbmUgZm9yIHRoaXMKKyAgICAgKiBtdWx0aXBhcnQgd2FzIHNlZW4uICBXaGVuIHBhcnNpbmcgbXVsdGlwYXJ0IGNvbnRlbnQsCisgICAgICogdGhpcyBjbGFzcyB3aWxsIChieSBkZWZhdWx0KSB0ZXJtaW5hdGUgcGFyc2luZyB3aXRoCisgICAgICogbm8gZXJyb3IgaWYgdGhlIGVuZCBvZiBpbnB1dCBpcyByZWFjaGVkIGJlZm9yZSBzZWVpbmcKKyAgICAgKiB0aGUgZmluYWwgbXVsdGlwYXJ0IGJvdW5kYXJ5IGxpbmUuICBJbiBzdWNoIGEgY2FzZSwKKyAgICAgKiB0aGlzIG1ldGhvZCB3aWxsIHJldHVybiBmYWxzZS4gIChJZiB0aGUgU3lzdGVtIHByb3BlcnR5CisgICAgICogIm1haWwubWltZS5tdWx0aXBhcnQuaWdub3JlbWlzc2luZ2VuZGJvdW5kYXJ5IiBpcyBzZXQgdG8KKyAgICAgKiBmYWxzZSwgcGFyc2luZyBzdWNoIGEgbWVzc2FnZSB3aWxsIGluc3RlYWQgdGhyb3cgYQorICAgICAqIE1lc3NhZ2luZ0V4Y2VwdGlvbi4pCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRydWUgaWYgdGhlIGZpbmFsIGJvdW5kYXJ5IGxpbmUgd2FzIHNlZW4KKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuNAorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgYm9vbGVhbiBpc0NvbXBsZXRlKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJcGFyc2UoKTsKKwlyZXR1cm4gY29tcGxldGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBwcmVhbWJsZSB0ZXh0LCBpZiBhbnksIHRoYXQgYXBwZWFycyBiZWZvcmUgdGhlCisgICAgICogZmlyc3QgYm9keSBwYXJ0IG9mIHRoaXMgbXVsdGlwYXJ0LiAgU29tZSBwcm90b2NvbHMsCisgICAgICogc3VjaCBhcyBJTUFQLCB3aWxsIG5vdCBhbGxvdyBhY2Nlc3MgdG8gdGhlIHByZWFtYmxlIHRleHQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCQl0aGUgcHJlYW1ibGUgdGV4dCwgb3IgbnVsbCBpZiBubyBwcmVhbWJsZQorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS40CisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBTdHJpbmcgZ2V0UHJlYW1ibGUoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlwYXJzZSgpOworCXJldHVybiBwcmVhbWJsZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHByZWFtYmxlIHRleHQgdG8gYmUgaW5jbHVkZWQgYmVmb3JlIHRoZSBmaXJzdAorICAgICAqIGJvZHkgcGFydC4gIEFwcGxpY2F0aW9ucyBzaG91bGQgZ2VuZXJhbGx5IG5vdCBpbmNsdWRlCisgICAgICogYW55IHByZWFtYmxlIHRleHQuICBJbiBzb21lIGNhc2VzIGl0IG1heSBiZSBoZWxwZnVsIHRvCisgICAgICogaW5jbHVkZSBwcmVhbWJsZSB0ZXh0IHdpdGggaW5zdHJ1Y3Rpb25zIGZvciB1c2VycyBvZgorICAgICAqIHByZS1NSU1FIHNvZnR3YXJlLiAgVGhlIHByZWFtYmxlIHRleHQgc2hvdWxkIGJlIGNvbXBsZXRlCisgICAgICogbGluZXMsIGluY2x1ZGluZyBuZXdsaW5lcy4KKyAgICAgKgorICAgICAqIEBwYXJhbQlwcmVhbWJsZQl0aGUgcHJlYW1ibGUgdGV4dAorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS40CisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHNldFByZWFtYmxlKFN0cmluZyBwcmVhbWJsZSkKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwl0aGlzLnByZWFtYmxlID0gcHJlYW1ibGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogVXBkYXRlIGhlYWRlcnMuIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIGhlcmUganVzdAorICAgICAqIGNhbGxzIHRoZSA8Y29kZT51cGRhdGVIZWFkZXJzPC9jb2RlPiBtZXRob2Qgb24gZWFjaCBvZiBpdHMKKyAgICAgKiBjaGlsZHJlbiBCb2R5UGFydHMuIDxwPgorICAgICAqCisgICAgICogTm90ZSB0aGF0IHRoZSBib3VuZGFyeSBwYXJhbWV0ZXIgaXMgYWxyZWFkeSBzZXQgdXAgd2hlbgorICAgICAqIGEgbmV3IGFuZCBlbXB0eSBNaW1lTXVsdGlwYXJ0IG9iamVjdCBpcyBjcmVhdGVkLiA8cD4KKyAgICAgKgorICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCB3aGVuIHRoZSA8Y29kZT5zYXZlQ2hhbmdlczwvY29kZT4KKyAgICAgKiBtZXRob2QgaXMgaW52b2tlZCBvbiB0aGUgTWVzc2FnZSBvYmplY3QgY29udGFpbmluZyB0aGlzCisgICAgICogTXVsdGlwYXJ0LiBUaGlzIGlzIHR5cGljYWxseSBkb25lIGFzIHBhcnQgb2YgdGhlIE1lc3NhZ2UKKyAgICAgKiBzZW5kIHByb2Nlc3MsIGhvd2V2ZXIgbm90ZSB0aGF0IGEgY2xpZW50IGlzIGZyZWUgdG8gY2FsbAorICAgICAqIGl0IGFueSBudW1iZXIgb2YgdGltZXMuIFNvIGlmIHRoZSBoZWFkZXIgdXBkYXRpbmcgcHJvY2VzcyBpcyAKKyAgICAgKiBleHBlbnNpdmUgZm9yIGEgc3BlY2lmaWMgTWltZU11bHRpcGFydCBzdWJjbGFzcywgdGhlbiBpdAorICAgICAqIG1pZ2h0IGl0c2VsZiB3YW50IHRvIHRyYWNrIHdoZXRoZXIgaXRzIGludGVybmFsIHN0YXRlIGFjdHVhbGx5CisgICAgICogZGlkIGNoYW5nZSwgYW5kIGRvIHRoZSBoZWFkZXIgdXBkYXRpbmcgb25seSBpZiBuZWNlc3NhcnkuCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3luY2hyb25pemVkIHZvaWQgdXBkYXRlSGVhZGVycygpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXBhcnNlKCk7CisJZm9yIChpbnQgaSA9IDA7IGkgPCBwYXJ0cy5zaXplKCk7IGkrKykKKwkgICAgKChNaW1lQm9keVBhcnQpcGFydHMuZWxlbWVudEF0KGkpKS51cGRhdGVIZWFkZXJzKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSXRlcmF0ZXMgdGhyb3VnaCBhbGwgdGhlIHBhcnRzIGFuZCBvdXRwdXRzIGVhY2ggTUlNRSBwYXJ0CisgICAgICogc2VwYXJhdGVkIGJ5IGEgYm91bmRhcnkuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHdyaXRlVG8oT3V0cHV0U3RyZWFtIG9zKQorCQkJCXRocm93cyBJT0V4Y2VwdGlvbiwgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlwYXJzZSgpOworCQorCVN0cmluZyBib3VuZGFyeSA9ICItLSIgKyAKKwkJKG5ldyBDb250ZW50VHlwZShjb250ZW50VHlwZSkpLmdldFBhcmFtZXRlcigiYm91bmRhcnkiKTsKKwlMaW5lT3V0cHV0U3RyZWFtIGxvcyA9IG5ldyBMaW5lT3V0cHV0U3RyZWFtKG9zKTsKKworCS8vIGlmIHRoZXJlJ3MgYSBwcmVhbWJsZSwgd3JpdGUgaXQgb3V0CisJaWYgKHByZWFtYmxlICE9IG51bGwpIHsKKwkgICAgYnl0ZVtdIHBiID0gQVNDSUlVdGlsaXR5LmdldEJ5dGVzKHByZWFtYmxlKTsKKwkgICAgbG9zLndyaXRlKHBiKTsKKwkgICAgLy8gbWFrZSBzdXJlIGl0IGVuZHMgd2l0aCBhIG5ld2xpbmUKKwkgICAgaWYgKHBiLmxlbmd0aCA+IDAgJiYKKwkJICAgICEocGJbcGIubGVuZ3RoLTFdID09ICdccicgfHwgcGJbcGIubGVuZ3RoLTFdID09ICdcbicpKSB7CisJCWxvcy53cml0ZWxuKCk7CisJICAgIH0KKwkgICAgLy8gWFhYIC0gY291bGQgZm9yY2UgYSBibGFuayBsaW5lIGJlZm9yZSBzdGFydCBib3VuZGFyeQorCX0KKworCWlmIChwYXJ0cy5zaXplKCkgPT0gMCkgeworCSAgICBpZiAoYWxsb3dFbXB0eSkgeworCQkvLyB3cml0ZSBvdXQgYSBzaW5nbGUgZW1wdHkgYm9keSBwYXJ0CisJCWxvcy53cml0ZWxuKGJvdW5kYXJ5KTsgLy8gcHV0IG91dCBib3VuZGFyeQorCQlsb3Mud3JpdGVsbigpOyAvLyBwdXQgb3V0IGVtcHR5IGxpbmUKKwkgICAgfSBlbHNlIHsKKwkJdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiRW1wdHkgbXVsdGlwYXJ0OiAiICsgY29udGVudFR5cGUpOworCSAgICB9CisJfSBlbHNlIHsKKwkgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYXJ0cy5zaXplKCk7IGkrKykgeworCQlsb3Mud3JpdGVsbihib3VuZGFyeSk7IC8vIHB1dCBvdXQgYm91bmRhcnkKKwkJKChNaW1lQm9keVBhcnQpcGFydHMuZWxlbWVudEF0KGkpKS53cml0ZVRvKG9zKTsKKwkJbG9zLndyaXRlbG4oKTsgLy8gcHV0IG91dCBlbXB0eSBsaW5lCisJICAgIH0KKwl9CisKKwkvLyBwdXQgb3V0IGxhc3QgYm91bmRhcnkKKwlsb3Mud3JpdGVsbihib3VuZGFyeSArICItLSIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlIHRoZSBJbnB1dFN0cmVhbSBmcm9tIG91ciBEYXRhU291cmNlLCBjb25zdHJ1Y3RpbmcgdGhlCisgICAgICogYXBwcm9wcmlhdGUgTWltZUJvZHlQYXJ0cy4gIFRoZSA8Y29kZT5wYXJzZWQ8L2NvZGU+IGZsYWcgaXMKKyAgICAgKiBzZXQgdG8gdHJ1ZSwgYW5kIGlmIHRydWUgb24gZW50cnkgbm90aGluZyBpcyBkb25lLiAgVGhpcworICAgICAqIG1ldGhvZCBpcyBjYWxsZWQgYnkgYWxsIG90aGVyIG1ldGhvZHMgdGhhdCBuZWVkIGRhdGEgZm9yCisgICAgICogdGhlIGJvZHkgcGFydHMsIHRvIG1ha2Ugc3VyZSB0aGUgZGF0YSBoYXMgYmVlbiBwYXJzZWQuCisgICAgICogVGhlIHtAbGluayAjaW5pdGlhbGl6ZVByb3BlcnRpZXN9IG1ldGhvZCBpcyBjYWxsZWQgYmVmb3JlCisgICAgICogcGFyc2luZyB0aGUgZGF0YS4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24JUGFyc2VFeGNlcHRpb24gZm9yIGZhaWx1cmVzIHBhcnNpbmcgdGhlIG1lc3NhZ2UKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS4yCisgICAgICovCisgICAgcHJvdGVjdGVkIHN5bmNocm9uaXplZCB2b2lkIHBhcnNlKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKHBhcnNlZCkKKwkgICAgcmV0dXJuOworCisJaW5pdGlhbGl6ZVByb3BlcnRpZXMoKTsKKworCUlucHV0U3RyZWFtIGluID0gbnVsbDsKKwlTaGFyZWRJbnB1dFN0cmVhbSBzaW4gPSBudWxsOworCWxvbmcgc3RhcnQgPSAwLCBlbmQgPSAwOworCisJdHJ5IHsKKwkgICAgaW4gPSBkcy5nZXRJbnB1dFN0cmVhbSgpOworCSAgICBpZiAoIShpbiBpbnN0YW5jZW9mIEJ5dGVBcnJheUlucHV0U3RyZWFtKSAmJgorCQkhKGluIGluc3RhbmNlb2YgQnVmZmVyZWRJbnB1dFN0cmVhbSkgJiYKKwkJIShpbiBpbnN0YW5jZW9mIFNoYXJlZElucHV0U3RyZWFtKSkKKwkJaW4gPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShpbik7CisJfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oIk5vIGlucHV0c3RyZWFtIGZyb20gZGF0YXNvdXJjZSIsIGV4KTsKKwl9CisJaWYgKGluIGluc3RhbmNlb2YgU2hhcmVkSW5wdXRTdHJlYW0pCisJICAgIHNpbiA9IChTaGFyZWRJbnB1dFN0cmVhbSlpbjsKKworCUNvbnRlbnRUeXBlIGNUeXBlID0gbmV3IENvbnRlbnRUeXBlKGNvbnRlbnRUeXBlKTsKKwlTdHJpbmcgYm91bmRhcnkgPSBudWxsOworCWlmICghaWdub3JlRXhpc3RpbmdCb3VuZGFyeVBhcmFtZXRlcikgeworCSAgICBTdHJpbmcgYnAgPSBjVHlwZS5nZXRQYXJhbWV0ZXIoImJvdW5kYXJ5Iik7CisJICAgIGlmIChicCAhPSBudWxsKQorCQlib3VuZGFyeSA9ICItLSIgKyBicDsKKwl9CisJaWYgKGJvdW5kYXJ5ID09IG51bGwgJiYgIWlnbm9yZU1pc3NpbmdCb3VuZGFyeVBhcmFtZXRlciAmJgorCQkhaWdub3JlRXhpc3RpbmdCb3VuZGFyeVBhcmFtZXRlcikKKwkgICAgdGhyb3cgbmV3IFBhcnNlRXhjZXB0aW9uKCJNaXNzaW5nIGJvdW5kYXJ5IHBhcmFtZXRlciIpOworCisJdHJ5IHsKKwkgICAgLy8gU2tpcCBhbmQgc2F2ZSB0aGUgcHJlYW1ibGUKKwkgICAgTGluZUlucHV0U3RyZWFtIGxpbiA9IG5ldyBMaW5lSW5wdXRTdHJlYW0oaW4pOworCSAgICBTdHJpbmdCdWlsZGVyIHByZWFtYmxlc2IgPSBudWxsOworCSAgICBTdHJpbmcgbGluZTsKKwkgICAgd2hpbGUgKChsaW5lID0gbGluLnJlYWRMaW5lKCkpICE9IG51bGwpIHsKKwkJLyoKKwkJICogU3RyaXAgdHJhaWxpbmcgd2hpdGVzcGFjZS4gIENhbid0IHVzZSB0cmltIG1ldGhvZAorCQkgKiBiZWNhdXNlIGl0J3MgdG9vIGFnZ3Jlc3NpdmUuICBTb21lIGJvZ3VzIE1JTUUKKwkJICogbWVzc2FnZXMgd2lsbCBpbmNsdWRlIGNvbnRyb2wgY2hhcmFjdGVycyBpbiB0aGUKKwkJICogYm91bmRhcnkgc3RyaW5nLgorCQkgKi8KKwkJaW50IGk7CisJCWZvciAoaSA9IGxpbmUubGVuZ3RoKCkgLSAxOyBpID49IDA7IGktLSkgeworCQkgICAgY2hhciBjID0gbGluZS5jaGFyQXQoaSk7CisJCSAgICBpZiAoIShjID09ICcgJyB8fCBjID09ICdcdCcpKQorCQkJYnJlYWs7CisJCX0KKwkJbGluZSA9IGxpbmUuc3Vic3RyaW5nKDAsIGkgKyAxKTsKKwkJaWYgKGJvdW5kYXJ5ICE9IG51bGwpIHsKKwkJICAgIGlmIChsaW5lLmVxdWFscyhib3VuZGFyeSkpCisJCQlicmVhazsKKwkJICAgIGlmIChsaW5lLmxlbmd0aCgpID09IGJvdW5kYXJ5Lmxlbmd0aCgpICsgMiAmJgorCQkJICAgIGxpbmUuc3RhcnRzV2l0aChib3VuZGFyeSkgJiYgbGluZS5lbmRzV2l0aCgiLS0iKSkgeworCQkJbGluZSA9IG51bGw7CS8vIHNpZ25hbCBlbmQgb2YgbXVsdGlwYXJ0CisJCQlicmVhazsKKwkJICAgIH0KKwkJfSBlbHNlIHsKKwkJICAgIC8qCisJCSAgICAgKiBCb3VuZGFyeSBoYXNuJ3QgYmVlbiBkZWZpbmVkLCBkb2VzIHRoaXMgbGluZQorCQkgICAgICogbG9vayBsaWtlIGEgYm91bmRhcnk/ICBJZiBzbywgYXNzdW1lIGl0IGlzCisJCSAgICAgKiB0aGUgYm91bmRhcnkgYW5kIHNhdmUgaXQuCisJCSAgICAgKi8KKwkJICAgIGlmIChsaW5lLmxlbmd0aCgpID4gMiAmJiBsaW5lLnN0YXJ0c1dpdGgoIi0tIikpIHsKKwkJCWlmIChsaW5lLmxlbmd0aCgpID4gNCAmJiBhbGxEYXNoZXMobGluZSkpIHsKKwkJCSAgICAvKgorCQkJICAgICAqIFRoZSBmaXJzdCBib3VuZGFyeS1saWtlIGxpbmUgd2UgZmluZCBpcworCQkJICAgICAqIHByb2JhYmx5ICpub3QqIHRoZSBlbmQtb2YtbXVsdGlwYXJ0IGJvdW5kYXJ5CisJCQkgICAgICogbGluZS4gIE1vcmUgbGlrZWx5IGl0J3MgYSBsaW5lIGZ1bGwgb2YgZGFzaGVzCisJCQkgICAgICogaW4gdGhlIHByZWFtYmxlIHRleHQuICBKdXN0IGtlZXAgcmVhZGluZy4KKwkJCSAgICAgKi8KKwkJCX0gZWxzZSB7CisJCQkgICAgYm91bmRhcnkgPSBsaW5lOworCQkJICAgIGJyZWFrOworCQkJfQorCQkgICAgfQorCQl9CisKKwkJLy8gc2F2ZSB0aGUgcHJlYW1ibGUgYWZ0ZXIgc2tpcHBpbmcgYmxhbmsgbGluZXMKKwkJaWYgKGxpbmUubGVuZ3RoKCkgPiAwKSB7CisJCSAgICAvLyBhY2N1bXVsYXRlIHRoZSBwcmVhbWJsZQorCQkgICAgaWYgKHByZWFtYmxlc2IgPT0gbnVsbCkKKwkJCXByZWFtYmxlc2IgPSBuZXcgU3RyaW5nQnVpbGRlcihsaW5lLmxlbmd0aCgpICsgMik7CisJCSAgICBwcmVhbWJsZXNiLmFwcGVuZChsaW5lKS5hcHBlbmQoU3lzdGVtLmxpbmVTZXBhcmF0b3IoKSk7CisJCX0KKwkgICAgfQorCisJICAgIGlmIChwcmVhbWJsZXNiICE9IG51bGwpCisJCXByZWFtYmxlID0gcHJlYW1ibGVzYi50b1N0cmluZygpOworCisJICAgIGlmIChsaW5lID09IG51bGwpIHsKKwkJaWYgKGFsbG93RW1wdHkpCisJCSAgICByZXR1cm47CisJCWVsc2UKKwkJICAgIHRocm93IG5ldyBQYXJzZUV4Y2VwdGlvbigiTWlzc2luZyBzdGFydCBib3VuZGFyeSIpOworCSAgICB9CisKKwkgICAgLy8gc2F2ZSBpbmRpdmlkdWFsIGJvdW5kYXJ5IGJ5dGVzIGZvciBjb21wYXJpc29uIGxhdGVyCisJICAgIGJ5dGVbXSBibmRieXRlcyA9IEFTQ0lJVXRpbGl0eS5nZXRCeXRlcyhib3VuZGFyeSk7CisJICAgIGludCBibCA9IGJuZGJ5dGVzLmxlbmd0aDsKKworCSAgICAvKgorCSAgICAgKiBDb21waWxlIEJveWVyLU1vb3JlIHBhcnNpbmcgdGFibGVzLgorCSAgICAgKi8KKworCSAgICAvLyBpbml0aWFsaXplIEJhZCBDaGFyYWN0ZXIgU2hpZnQgdGFibGUKKwkgICAgaW50W10gYmNzID0gbmV3IGludFsyNTZdOworCSAgICBmb3IgKGludCBpID0gMDsgaSA8IGJsOyBpKyspCisJCWJjc1tibmRieXRlc1tpXSAmIDB4ZmZdID0gaSArIDE7CisKKwkgICAgLy8gaW5pdGlhbGl6ZSBHb29kIFN1ZmZpeCBTaGlmdCB0YWJsZQorCSAgICBpbnRbXSBnc3MgPSBuZXcgaW50W2JsXTsKKwlORVhUOgorCSAgICBmb3IgKGludCBpID0gYmw7IGkgPiAwOyBpLS0pIHsKKwkJaW50IGo7CS8vIHRoZSBiZWdpbm5pbmcgaW5kZXggb2YgdGhlIHN1ZmZpeCBiZWluZyBjb25zaWRlcmVkCisJCWZvciAoaiA9IGJsIC0gMTsgaiA+PSBpOyBqLS0pIHsKKwkJICAgIC8vIFRlc3RpbmcgZm9yIGdvb2Qgc3VmZml4CisJCSAgICBpZiAoYm5kYnl0ZXNbal0gPT0gYm5kYnl0ZXNbaiAtIGldKSB7CisJCQkvLyBibmRieXRlc1tqLi5sZW5dIGlzIGEgZ29vZCBzdWZmaXgKKwkJCWdzc1tqIC0gMV0gPSBpOworCQkgICAgfSBlbHNlIHsKKwkJICAgICAgIC8vIE5vIG1hdGNoLiBUaGUgYXJyYXkgaGFzIGFscmVhZHkgYmVlbgorCQkgICAgICAgLy8gZmlsbGVkIHVwIHdpdGggY29ycmVjdCB2YWx1ZXMgYmVmb3JlLgorCQkgICAgICAgY29udGludWUgTkVYVDsKKwkJICAgIH0KKwkJfQorCQl3aGlsZSAoaiA+IDApCisJCSAgICBnc3NbLS1qXSA9IGk7CisJICAgIH0KKwkgICAgZ3NzW2JsIC0gMV0gPSAxOworIAorCSAgICAvKgorCSAgICAgKiBSZWFkIGFuZCBwcm9jZXNzIGJvZHkgcGFydHMgdW50aWwgd2Ugc2VlIHRoZQorCSAgICAgKiB0ZXJtaW5hdGluZyBib3VuZGFyeSBsaW5lIChvciBFT0YpLgorCSAgICAgKi8KKwkgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CisJZ2V0cGFydHM6CisJICAgIHdoaWxlICghZG9uZSkgeworCQlJbnRlcm5ldEhlYWRlcnMgaGVhZGVycyA9IG51bGw7CisJCWlmIChzaW4gIT0gbnVsbCkgeworCQkgICAgc3RhcnQgPSBzaW4uZ2V0UG9zaXRpb24oKTsKKwkJICAgIC8vIHNraXAgaGVhZGVycworCQkgICAgd2hpbGUgKChsaW5lID0gbGluLnJlYWRMaW5lKCkpICE9IG51bGwgJiYgbGluZS5sZW5ndGgoKSA+IDApCisJCQk7CisJCSAgICBpZiAobGluZSA9PSBudWxsKSB7CisJCQlpZiAoIWlnbm9yZU1pc3NpbmdFbmRCb3VuZGFyeSkKKwkJCSAgICB0aHJvdyBuZXcgUGFyc2VFeGNlcHRpb24oCisJCQkJCSJtaXNzaW5nIG11bHRpcGFydCBlbmQgYm91bmRhcnkiKTsKKwkJCS8vIGFzc3VtZSB0aGVyZSdzIGp1c3QgYSBtaXNzaW5nIGVuZCBib3VuZGFyeQorCQkJY29tcGxldGUgPSBmYWxzZTsKKwkJCWJyZWFrIGdldHBhcnRzOworCQkgICAgfQorCQl9IGVsc2UgeworCQkgICAgLy8gY29sbGVjdCB0aGUgaGVhZGVycyBmb3IgdGhpcyBib2R5IHBhcnQKKwkJICAgIGhlYWRlcnMgPSBjcmVhdGVJbnRlcm5ldEhlYWRlcnMoaW4pOworCQl9CisKKwkJaWYgKCFpbi5tYXJrU3VwcG9ydGVkKCkpCisJCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKCJTdHJlYW0gZG9lc24ndCBzdXBwb3J0IG1hcmsiKTsKKworCQlCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYnVmID0gbnVsbDsKKwkJLy8gaWYgd2UgZG9uJ3QgaGF2ZSBhIHNoYXJlZCBpbnB1dCBzdHJlYW0sIHdlIGNvcHkgdGhlIGRhdGEKKwkJaWYgKHNpbiA9PSBudWxsKQorCQkgICAgYnVmID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworCQllbHNlCisJCSAgICBlbmQgPSBzaW4uZ2V0UG9zaXRpb24oKTsKKwkJaW50IGI7CisKKwkJLyoKKwkJICogVGhlc2UgYnVmZmVycyBjb250YWluIHRoZSBieXRlcyB3ZSdyZSBjaGVja2luZworCQkgKiBmb3IgYSBtYXRjaC4gIGluYnVmIGlzIHRoZSBjdXJyZW50IGJ1ZmZlciBhbmQKKwkJICogcHJldmluYnVmIGlzIHRoZSBwcmV2aW91cyBidWZmZXIuICBXZSBuZWVkIHRoZQorCQkgKiBwcmV2aW91cyBidWZmZXIgdG8gY2hlY2sgdGhhdCB3ZSdyZSBwcmVjZWVkZWQKKwkJICogYnkgYW4gRU9MLgorCQkgKi8KKwkJLy8gWFhYIC0gYSBzbWFydGVyIGFsZ29yaXRobSB3b3VsZCB1c2UgYSBzbGlkaW5nIHdpbmRvdworCQkvLwkgb3ZlciBhIGxhcmdlciBidWZmZXIKKwkJYnl0ZVtdIGluYnVmID0gbmV3IGJ5dGVbYmxdOworCQlieXRlW10gcHJldmluYnVmID0gbmV3IGJ5dGVbYmxdOworCQlpbnQgaW5TaXplID0gMDsJCS8vIG51bWJlciBvZiB2YWxpZCBieXRlcyBpbiBpbmJ1ZgorCQlpbnQgcHJldlNpemUgPSAwOwkvLyBudW1iZXIgb2YgdmFsaWQgYnl0ZXMgaW4gcHJldmluYnVmCisJCWludCBlb2xMZW47CisJCWJvb2xlYW4gZmlyc3QgPSB0cnVlOworCisJCS8qCisJCSAqIFJlYWQgYW5kIHNhdmUgdGhlIGNvbnRlbnQgYnl0ZXMgaW4gYnVmLgorCQkgKi8KKwkJZm9yICg7OykgeworCQkgICAgaW4ubWFyayhibCArIDQgKyAxMDAwKTsgLy8gYm5kICsgIi0tXHJcbiIgKyBsb3RzIG9mIExXU1AKKwkJICAgIGVvbExlbiA9IDA7CisJCSAgICBpblNpemUgPSByZWFkRnVsbHkoaW4sIGluYnVmLCAwLCBibCk7CisJCSAgICBpZiAoaW5TaXplIDwgYmwpIHsKKwkJCS8vIGhpdCBFT0YKKwkJCWlmICghaWdub3JlTWlzc2luZ0VuZEJvdW5kYXJ5KQorCQkJICAgIHRocm93IG5ldyBQYXJzZUV4Y2VwdGlvbigKKwkJCQkJIm1pc3NpbmcgbXVsdGlwYXJ0IGVuZCBib3VuZGFyeSIpOworCQkJaWYgKHNpbiAhPSBudWxsKQorCQkJICAgIGVuZCA9IHNpbi5nZXRQb3NpdGlvbigpOworCQkJY29tcGxldGUgPSBmYWxzZTsKKwkJCWRvbmUgPSB0cnVlOworCQkJYnJlYWs7CisJCSAgICB9CisJCSAgICAvLyBjaGVjayB3aGV0aGVyIGluYnVmIGNvbnRhaW5zIGEgYm91bmRhcnkgc3RyaW5nCisJCSAgICBpbnQgaTsKKwkJICAgIGZvciAoaSA9IGJsIC0gMTsgaSA+PSAwOyBpLS0pIHsKKwkJCWlmIChpbmJ1ZltpXSAhPSBibmRieXRlc1tpXSkKKwkJCSAgICBicmVhazsKKwkJICAgIH0KKwkJICAgIGlmIChpIDwgMCkgewkvLyBtYXRjaGVkIGFsbCBieXRlcworCQkJZW9sTGVuID0gMDsKKwkJCWlmICghZmlyc3QpIHsKKwkJCSAgICAvLyB3b3JraW5nIGJhY2t3YXJkcywgZmluZCBvdXQgaWYgd2Ugd2VyZSBwcmVjZWVkZWQKKwkJCSAgICAvLyBieSBhbiBFT0wsIGFuZCBpZiBzbyBmaW5kIGl0cyBsZW5ndGgKKwkJCSAgICBiID0gcHJldmluYnVmW3ByZXZTaXplIC0gMV07CisJCQkgICAgaWYgKGIgPT0gJ1xyJyB8fCBiID09ICdcbicpIHsKKwkJCQllb2xMZW4gPSAxOworCQkJCWlmIChiID09ICdcbicgJiYgcHJldlNpemUgPj0gMikgeworCQkJCSAgICBiID0gcHJldmluYnVmW3ByZXZTaXplIC0gMl07CisJCQkJICAgIGlmIChiID09ICdccicpCisJCQkJCWVvbExlbiA9IDI7CisJCQkJfQorCQkJICAgIH0KKwkJCX0KKwkJCWlmIChmaXJzdCB8fCBlb2xMZW4gPiAwKSB7CS8vIHllcywgcHJlY2VlZCBieSBFT0wKKwkJCSAgICBpZiAoc2luICE9IG51bGwpIHsKKwkJCQkvLyB1cGRhdGUgImVuZCIsIGluIGNhc2UgdGhpcyByZWFsbHkgaXMKKwkJCQkvLyBhIHZhbGlkIGJvdW5kYXJ5CisJCQkJZW5kID0gc2luLmdldFBvc2l0aW9uKCkgLSBibCAtIGVvbExlbjsKKwkJCSAgICB9CisJCQkgICAgLy8gbWF0Y2hlZCB0aGUgYm91bmRhcnksIGNoZWNrIGZvciBsYXN0IGJvdW5kYXJ5CisJCQkgICAgaW50IGIyID0gaW4ucmVhZCgpOworCQkJICAgIGlmIChiMiA9PSAnLScpIHsKKwkJCQlpZiAoaW4ucmVhZCgpID09ICctJykgeworCQkJCSAgICBjb21wbGV0ZSA9IHRydWU7CisJCQkJICAgIGRvbmUgPSB0cnVlOworCQkJCSAgICBicmVhazsJLy8gaWdub3JlIHRyYWlsaW5nIHRleHQKKwkJCQl9CisJCQkgICAgfQorCQkJICAgIC8vIHNraXAgbGluZWFyIHdoaXRlc3BhY2UKKwkJCSAgICB3aGlsZSAoYjIgPT0gJyAnIHx8IGIyID09ICdcdCcpCisJCQkJYjIgPSBpbi5yZWFkKCk7CisJCQkgICAgLy8gY2hlY2sgZm9yIGVuZCBvZiBsaW5lCisJCQkgICAgaWYgKGIyID09ICdcbicpCisJCQkJYnJlYWs7CS8vIGdvdCBpdCEgIGJyZWFrIG91dCBvZiB0aGUgbG9vcAorCQkJICAgIGlmIChiMiA9PSAnXHInKSB7CisJCQkJaW4ubWFyaygxKTsKKwkJCQlpZiAoaW4ucmVhZCgpICE9ICdcbicpCisJCQkJICAgIGluLnJlc2V0KCk7CisJCQkJYnJlYWs7CS8vIGdvdCBpdCEgIGJyZWFrIG91dCBvZiB0aGUgbG9vcAorCQkJICAgIH0KKwkJCX0KKwkJCWkgPSAwOworCQkgICAgfQorCisJCSAgICAvKgorCQkgICAgICogR2V0IGhlcmUgaWYgYm91bmRhcnkgZGlkbid0IG1hdGNoLAorCQkgICAgICogd2Fzbid0IHByZWNlZWRlZCBieSBFT0wsIG9yIHdhc24ndAorCQkgICAgICogZm9sbG93ZWQgYnkgd2hpdGVzcGFjZSBvciBFT0wuCisJCSAgICAgKi8KKworCQkgICAgLy8gY29tcHV0ZSBob3cgbWFueSBieXRlcyB3ZSBjYW4gc2tpcAorCQkgICAgaW50IHNraXAgPSBNYXRoLm1heChpICsgMSAtIGJjc1tpbmJ1ZltpXSAmIDB4N2ZdLCBnc3NbaV0pOworCQkgICAgLy8gd2FudCB0byBrZWVwIGF0IGxlYXN0IHR3byBjaGFyYWN0ZXJzCisJCSAgICBpZiAoc2tpcCA8IDIpIHsKKwkJCS8vIG9ubHkgc2tpcHBpbmcgb25lIGJ5dGUsIHNhdmUgb25lIGJ5dGUKKwkJCS8vIGZyb20gcHJldmlvdXMgYnVmZmVyIGFzIHdlbGwKKwkJCS8vIGZpcnN0LCB3cml0ZSBvdXQgYnl0ZXMgd2UncmUgZG9uZSB3aXRoCisJCQlpZiAoc2luID09IG51bGwgJiYgcHJldlNpemUgPiAxKQorCQkJICAgIGJ1Zi53cml0ZShwcmV2aW5idWYsIDAsIHByZXZTaXplIC0gMSk7CisJCQlpbi5yZXNldCgpOworCQkJc2tpcEZ1bGx5KGluLCAxKTsKKwkJCWlmIChwcmV2U2l6ZSA+PSAxKSB7CS8vIGlzIHRoZXJlIGEgYnl0ZSB0byBzYXZlPworCQkJICAgIC8vIHllcywgc2F2ZSBvbmUgZnJvbSBwcmV2aW91cyBhbmQgb25lIGZyb20gY3VycmVudAorCQkJICAgIHByZXZpbmJ1ZlswXSA9IHByZXZpbmJ1ZltwcmV2U2l6ZSAtIDFdOworCQkJICAgIHByZXZpbmJ1ZlsxXSA9IGluYnVmWzBdOworCQkJICAgIHByZXZTaXplID0gMjsKKwkJCX0gZWxzZSB7CisJCQkgICAgLy8gbm8gcHJldmlvdXMgYnl0ZXMgdG8gc2F2ZSwgY2FuIG9ubHkgc2F2ZSBjdXJyZW50CisJCQkgICAgcHJldmluYnVmWzBdID0gaW5idWZbMF07CisJCQkgICAgcHJldlNpemUgPSAxOworCQkJfQorCQkgICAgfSBlbHNlIHsKKwkJCS8vIGZpcnN0LCB3cml0ZSBvdXQgZGF0YSBmcm9tIHByZXZpb3VzIGJ1ZmZlciBiZWZvcmUKKwkJCS8vIHdlIGR1bXAgaXQKKwkJCWlmIChwcmV2U2l6ZSA+IDAgJiYgc2luID09IG51bGwpCisJCQkgICAgYnVmLndyaXRlKHByZXZpbmJ1ZiwgMCwgcHJldlNpemUpOworCQkJLy8gYWxsIHRoZSBieXRlcyB3ZSdyZSBza2lwcGluZyBhcmUgc2F2ZWQgaW4gcHJldmluYnVmCisJCQlwcmV2U2l6ZSA9IHNraXA7CisJCQlpbi5yZXNldCgpOworCQkJc2tpcEZ1bGx5KGluLCBwcmV2U2l6ZSk7CisJCQkvLyBzd2FwIGJ1ZmZlcnMKKwkJCWJ5dGVbXSB0bXAgPSBpbmJ1ZjsKKwkJCWluYnVmID0gcHJldmluYnVmOworCQkJcHJldmluYnVmID0gdG1wOworCQkgICAgfQorCQkgICAgZmlyc3QgPSBmYWxzZTsKKwkJfQorCisJCS8qCisJCSAqIENyZWF0ZSBhIE1pbWVCb2R5IGVsZW1lbnQgdG8gcmVwcmVzZW50IHRoaXMgYm9keSBwYXJ0LgorCQkgKi8KKwkJTWltZUJvZHlQYXJ0IHBhcnQ7CisJCWlmIChzaW4gIT0gbnVsbCkgeworCQkgICAgcGFydCA9IGNyZWF0ZU1pbWVCb2R5UGFydElzKHNpbi5uZXdTdHJlYW0oc3RhcnQsIGVuZCkpOworCQl9IGVsc2UgeworCQkgICAgLy8gd3JpdGUgb3V0IGRhdGEgZnJvbSBwcmV2aW91cyBidWZmZXIsIG5vdCBpbmNsdWRpbmcgRU9MCisJCSAgICBpZiAocHJldlNpemUgLSBlb2xMZW4gPiAwKQorCQkJYnVmLndyaXRlKHByZXZpbmJ1ZiwgMCwgcHJldlNpemUgLSBlb2xMZW4pOworCQkgICAgLy8gaWYgd2UgZGlkbid0IGZpbmQgYSB0cmFpbGluZyBib3VuZGFyeSwKKwkJICAgIC8vIHRoZSBjdXJyZW50IGJ1ZmZlciBoYXMgZGF0YSB3ZSBuZWVkIHRvbworCQkgICAgaWYgKCFjb21wbGV0ZSAmJiBpblNpemUgPiAwKQorCQkJYnVmLndyaXRlKGluYnVmLCAwLCBpblNpemUpOworCQkgICAgcGFydCA9IGNyZWF0ZU1pbWVCb2R5UGFydChoZWFkZXJzLCBidWYudG9CeXRlQXJyYXkoKSk7CisJCX0KKwkJc3VwZXIuYWRkQm9keVBhcnQocGFydCk7CisJICAgIH0KKwl9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2V4KSB7CisJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oIklPIEVycm9yIiwgaW9leCk7CisJfSBmaW5hbGx5IHsKKwkgICAgdHJ5IHsKKwkJaW4uY2xvc2UoKTsKKwkgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gY2V4KSB7CisJCS8vIGlnbm9yZQorCSAgICB9CisJfQorCisJcGFyc2VkID0gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJcyB0aGUgc3RyaW5nIGFsbCBkYXNoZXMgKCctJyk/CisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBhbGxEYXNoZXMoU3RyaW5nIHMpIHsKKwlmb3IgKGludCBpID0gMDsgaSA8IHMubGVuZ3RoKCk7IGkrKykgeworCSAgICBpZiAocy5jaGFyQXQoaSkgIT0gJy0nKQorCQlyZXR1cm4gZmFsc2U7CisJfQorCXJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWQgZGF0YSBmcm9tIHRoZSBpbnB1dCBzdHJlYW0gdG8gZmlsbCB0aGUgYnVmZmVyIHN0YXJ0aW5nCisgICAgICogYXQgdGhlIHNwZWNpZmllZCBvZmZzZXQgd2l0aCB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiBieXRlcy4KKyAgICAgKiBJZiBsZW4gaXMgemVybywgcmV0dXJuIHplcm8uICBJZiBhdCBFT0YsIHJldHVybiAtMS4gIE90aGVyd2lzZSwKKyAgICAgKiByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyByZWFkLiAgQ2FsbCB0aGUgcmVhZCBtZXRob2Qgb24gdGhlCisgICAgICogaW5wdXQgc3RyZWFtIGFzIG1hbnkgdGltZXMgYXMgbmVjZXNzYXJ5IHRvIHJlYWQgbGVuIGJ5dGVzLgorICAgICAqCisgICAgICogQHBhcmFtCWluCUlucHV0U3RyZWFtIHRvIHJlYWQgZnJvbQorICAgICAqIEBwYXJhbQlidWYJYnVmZmVyIHRvIHJlYWQgaW50bworICAgICAqIEBwYXJhbQlvZmYJb2Zmc2V0IGluIHRoZSBidWZmZXIgZm9yIGZpcnN0IGJ5dGUKKyAgICAgKiBAcGFyYW0JbGVuCW51bWJlciBvZiBieXRlcyB0byByZWFkCisgICAgICogQHJldHVybgkJLTEgb24gRU9GLCBvdGhlcndpc2UgbnVtYmVyIG9mIGJ5dGVzIHJlYWQKKyAgICAgKiBAZXhjZXB0aW9uCUlPRXhjZXB0aW9uCW9uIEkvTyBlcnJvcnMKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBpbnQgcmVhZEZ1bGx5KElucHV0U3RyZWFtIGluLCBieXRlW10gYnVmLCBpbnQgb2ZmLCBpbnQgbGVuKQorCQkJCXRocm93cyBJT0V4Y2VwdGlvbiB7CisJaWYgKGxlbiA9PSAwKQorCSAgICByZXR1cm4gMDsKKwlpbnQgdG90YWwgPSAwOworCXdoaWxlIChsZW4gPiAwKSB7CisJICAgIGludCBic2l6ZSA9IGluLnJlYWQoYnVmLCBvZmYsIGxlbik7CisJICAgIGlmIChic2l6ZSA8PSAwKQkvLyBzaG91bGQgbmV2ZXIgYmUgemVybworCQlicmVhazsKKwkgICAgb2ZmICs9IGJzaXplOworCSAgICB0b3RhbCArPSBic2l6ZTsKKwkgICAgbGVuIC09IGJzaXplOworCX0KKwlyZXR1cm4gdG90YWwgPiAwID8gdG90YWwgOiAtMTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTa2lwIHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIGJ5dGVzLCByZXBlYXRlZGx5IGNhbGxpbmcKKyAgICAgKiB0aGUgc2tpcCBtZXRob2QgYXMgbmVjZXNzYXJ5LgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBza2lwRnVsbHkoSW5wdXRTdHJlYW0gaW4sIGxvbmcgb2Zmc2V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworCXdoaWxlIChvZmZzZXQgPiAwKSB7CisJICAgIGxvbmcgY3VyID0gaW4uc2tpcChvZmZzZXQpOworCSAgICBpZiAoY3VyIDw9IDApCisJCXRocm93IG5ldyBFT0ZFeGNlcHRpb24oImNhbid0IHNraXAiKTsKKwkgICAgb2Zmc2V0IC09IGN1cjsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGFuZCByZXR1cm4gYW4gSW50ZXJuZXRIZWFkZXJzIG9iamVjdCB0aGF0IGxvYWRzIHRoZQorICAgICAqIGhlYWRlcnMgZnJvbSB0aGUgZ2l2ZW4gSW5wdXRTdHJlYW0uICBTdWJjbGFzc2VzIGNhbiBvdmVycmlkZQorICAgICAqIHRoaXMgbWV0aG9kIHRvIHJldHVybiBhIHN1YmNsYXNzIG9mIEludGVybmV0SGVhZGVycywgaWYKKyAgICAgKiBuZWNlc3NhcnkuICBUaGlzIGltcGxlbWVudGF0aW9uIHNpbXBseSBjb25zdHJ1Y3RzIGFuZCByZXR1cm5zCisgICAgICogYW4gSW50ZXJuZXRIZWFkZXJzIG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbQlpcwl0aGUgSW5wdXRTdHJlYW0gdG8gcmVhZCB0aGUgaGVhZGVycyBmcm9tCisgICAgICogQHJldHVybglhbiBJbnRlcm5ldEhlYWRlcnMgb2JqZWN0CisgICAgICogQGV4Y2VwdGlvbiAgCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuMgorICAgICAqLworICAgIHByb3RlY3RlZCBJbnRlcm5ldEhlYWRlcnMgY3JlYXRlSW50ZXJuZXRIZWFkZXJzKElucHV0U3RyZWFtIGlzKQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXJldHVybiBuZXcgSW50ZXJuZXRIZWFkZXJzKGlzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYW5kIHJldHVybiBhIE1pbWVCb2R5UGFydCBvYmplY3QgdG8gcmVwcmVzZW50IGEKKyAgICAgKiBib2R5IHBhcnQgcGFyc2VkIGZyb20gdGhlIElucHV0U3RyZWFtLiAgU3ViY2xhc3NlcyBjYW4gb3ZlcnJpZGUKKyAgICAgKiB0aGlzIG1ldGhvZCB0byByZXR1cm4gYSBzdWJjbGFzcyBvZiBNaW1lQm9keVBhcnQsIGlmCisgICAgICogbmVjZXNzYXJ5LiAgVGhpcyBpbXBsZW1lbnRhdGlvbiBzaW1wbHkgY29uc3RydWN0cyBhbmQgcmV0dXJucworICAgICAqIGEgTWltZUJvZHlQYXJ0IG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbQloZWFkZXJzCQl0aGUgaGVhZGVycyBmb3IgdGhlIGJvZHkgcGFydAorICAgICAqIEBwYXJhbQljb250ZW50CQl0aGUgY29udGVudCBvZiB0aGUgYm9keSBwYXJ0CisgICAgICogQHJldHVybglhIE1pbWVCb2R5UGFydAorICAgICAqIEBleGNlcHRpb24gIAkJTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqIEBzaW5jZQkJCUphdmFNYWlsIDEuMgorICAgICAqLworICAgIHByb3RlY3RlZCBNaW1lQm9keVBhcnQgY3JlYXRlTWltZUJvZHlQYXJ0KEludGVybmV0SGVhZGVycyBoZWFkZXJzLAorCQkJCWJ5dGVbXSBjb250ZW50KSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gbmV3IE1pbWVCb2R5UGFydChoZWFkZXJzLCBjb250ZW50KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYW5kIHJldHVybiBhIE1pbWVCb2R5UGFydCBvYmplY3QgdG8gcmVwcmVzZW50IGEKKyAgICAgKiBib2R5IHBhcnQgcGFyc2VkIGZyb20gdGhlIElucHV0U3RyZWFtLiAgU3ViY2xhc3NlcyBjYW4gb3ZlcnJpZGUKKyAgICAgKiB0aGlzIG1ldGhvZCB0byByZXR1cm4gYSBzdWJjbGFzcyBvZiBNaW1lQm9keVBhcnQsIGlmCisgICAgICogbmVjZXNzYXJ5LiAgVGhpcyBpbXBsZW1lbnRhdGlvbiBzaW1wbHkgY29uc3RydWN0cyBhbmQgcmV0dXJucworICAgICAqIGEgTWltZUJvZHlQYXJ0IG9iamVjdC4KKyAgICAgKgorICAgICAqIEBwYXJhbQlpcwkJSW5wdXRTdHJlYW0gY29udGFpbmluZyB0aGUgYm9keSBwYXJ0CisgICAgICogQHJldHVybglhIE1pbWVCb2R5UGFydAorICAgICAqIEBleGNlcHRpb24gIAkJTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqIEBzaW5jZQkJCUphdmFNYWlsIDEuMgorICAgICAqLworICAgIHByb3RlY3RlZCBNaW1lQm9keVBhcnQgY3JlYXRlTWltZUJvZHlQYXJ0KElucHV0U3RyZWFtIGlzKQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXJldHVybiBuZXcgTWltZUJvZHlQYXJ0KGlzKTsKKyAgICB9CisKKyAgICBwcml2YXRlIE1pbWVCb2R5UGFydCBjcmVhdGVNaW1lQm9keVBhcnRJcyhJbnB1dFN0cmVhbSBpcykKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwl0cnkgeworCSAgICByZXR1cm4gY3JlYXRlTWltZUJvZHlQYXJ0KGlzKTsKKwl9IGZpbmFsbHkgeworCSAgICB0cnkgeworCQlpcy5jbG9zZSgpOworCSAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworCQkvLyBpZ25vcmUgaXQKKwkgICAgfQorCX0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9NaW1lUGFydC5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvTWltZVBhcnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNDNmYzRhCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvTWltZVBhcnQuamF2YQpAQCAtMCwwICsxLDIyNCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsLmludGVybmV0OworCitpbXBvcnQgamF2YXgubWFpbC4qOworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247CisKKy8qKgorICogVGhlIE1pbWVQYXJ0IGludGVyZmFjZSBtb2RlbHMgYW4gPHN0cm9uZz5FbnRpdHk8L3N0cm9uZz4gYXMgZGVmaW5lZAorICogYnkgTUlNRSAoUkZDMjA0NSwgU2VjdGlvbiAyLjQpLiA8cD4KKyAqCisgKiBNaW1lUGFydCBleHRlbmRzIHRoZSBQYXJ0IGludGVyZmFjZSB0byBhZGQgYWRkaXRpb25hbCBSRkM4MjIgYW5kIE1JTUUKKyAqIHNwZWNpZmljIHNlbWFudGljcyBhbmQgYXR0cmlidXRlcy4gSXQgcHJvdmlkZXMgdGhlIGJhc2UgaW50ZXJmYWNlIGZvcgorICogdGhlIE1pbWVNZXNzYWdlIGFuZCAgTWltZUJvZHlQYXJ0IGNsYXNzZXMgCisgKiAKKyAqIDxocj4gPHN0cm9uZz5BIG5vdGUgb24gUkZDODIyIGFuZCBNSU1FIGhlYWRlcnM8L3N0cm9uZz48cD4KKyAqCisgKiBSRkM4MjIgYW5kIE1JTUUgaGVhZGVyIGZpZWxkcyA8c3Ryb25nPm11c3Q8L3N0cm9uZz4gY29udGFpbiBvbmx5IAorICogVVMtQVNDSUkgY2hhcmFjdGVycy4gSWYgYSBoZWFkZXIgY29udGFpbnMgbm9uIFVTLUFTQ0lJIGNoYXJhY3RlcnMsCisgKiBpdCBtdXN0IGJlIGVuY29kZWQgYXMgcGVyIHRoZSBydWxlcyBpbiBSRkMgMjA0Ny4gVGhlIE1pbWVVdGlsaXR5CisgKiBjbGFzcyBwcm92aWRlZCBpbiB0aGlzIHBhY2thZ2UgY2FuIGJlIHVzZWQgdG8gdG8gYWNoaWV2ZSB0aGlzLiAKKyAqIENhbGxlcnMgb2YgdGhlIDxjb2RlPnNldEhlYWRlcjwvY29kZT4sIDxjb2RlPmFkZEhlYWRlcjwvY29kZT4sIGFuZAorICogPGNvZGU+YWRkSGVhZGVyTGluZTwvY29kZT4gbWV0aG9kcyBhcmUgcmVzcG9uc2libGUgZm9yIGVuZm9yY2luZworICogdGhlIE1JTUUgcmVxdWlyZW1lbnRzIGZvciB0aGUgc3BlY2lmaWVkIGhlYWRlcnMuICBJbiBhZGRpdGlvbiwgdGhlc2UKKyAqIGhlYWRlciBmaWVsZHMgbXVzdCBiZSBmb2xkZWQgKHdyYXBwZWQpIGJlZm9yZSBiZWluZyBzZW50IGlmIHRoZXkKKyAqIGV4Y2VlZCB0aGUgbGluZSBsZW5ndGggbGltaXRhdGlvbiBmb3IgdGhlIHRyYW5zcG9ydCAoMTAwMCBieXRlcyBmb3IKKyAqIFNNVFApLiAgUmVjZWl2ZWQgaGVhZGVycyBtYXkgaGF2ZSBiZWVuIGZvbGRlZC4gIFRoZSBhcHBsaWNhdGlvbiBpcworICogcmVzcG9uc2libGUgZm9yIGZvbGRpbmcgYW5kIHVuZm9sZGluZyBoZWFkZXJzIGFzIGFwcHJvcHJpYXRlLiA8cD4KKyAqCisgKiBAc2VlCQlNaW1lVXRpbGl0eQorICogQHNlZQkJamF2YXgubWFpbC5QYXJ0CisgKiBAYXV0aG9yIAlKb2huIE1hbmkKKyAqLworCitwdWJsaWMgaW50ZXJmYWNlIE1pbWVQYXJ0IGV4dGVuZHMgUGFydCB7CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIHZhbHVlcyBvZiBhbGwgaGVhZGVyIGZpZWxkcyBhdmFpbGFibGUgZm9yIHRoaXMgaGVhZGVyLAorICAgICAqIHJldHVybmVkIGFzIGEgc2luZ2xlIFN0cmluZywgd2l0aCB0aGUgdmFsdWVzIHNlcGFyYXRlZCBieSB0aGUgCisgICAgICogZGVsaW1pdGVyLiBJZiB0aGUgZGVsaW1pdGVyIGlzIDxjb2RlPm51bGw8L2NvZGU+LCBvbmx5IHRoZSAKKyAgICAgKiBmaXJzdCB2YWx1ZSBpcyByZXR1cm5lZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCQl0aGUgbmFtZSBvZiB0aGlzIGhlYWRlcgorICAgICAqIEBwYXJhbSBkZWxpbWl0ZXIJCWRlbGltaXRlciBiZXR3ZWVuIGZpZWxkcyBpbiByZXR1cm5lZCBzdHJpbmcKKyAgICAgKiBAcmV0dXJuICAgICAgICAgICAgICAgICAgdGhlIHZhbHVlIGZpZWxkcyBmb3IgYWxsIGhlYWRlcnMgd2l0aCAKKyAgICAgKgkJCQl0aGlzIG5hbWUKKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIAlNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRIZWFkZXIoU3RyaW5nIG5hbWUsIFN0cmluZyBkZWxpbWl0ZXIpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEFkZCBhIHJhdyBSRkM4MjIgaGVhZGVyLWxpbmUuIAorICAgICAqCisgICAgICogQHBhcmFtCWxpbmUJdGhlIGxpbmUgdG8gYWRkCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsV3JpdGVFeGNlcHRpb24gaWYgdGhlIHVuZGVybHlpbmcKKyAgICAgKgkJCWltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBQYXJ0IGlzCisgICAgICoJCQlvYnRhaW5lZCBmcm9tIGEgUkVBRF9PTkxZIGZvbGRlcgorICAgICAqIEBleGNlcHRpb24gICAgICAgTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBvdGhlciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFkZEhlYWRlckxpbmUoU3RyaW5nIGxpbmUpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXQgYWxsIGhlYWRlciBsaW5lcyBhcyBhbiBFbnVtZXJhdGlvbiBvZiBTdHJpbmdzLiBBIEhlYWRlcgorICAgICAqIGxpbmUgaXMgYSByYXcgUkZDODIyIGhlYWRlci1saW5lLCBjb250YWluaW5nIGJvdGggdGhlICJuYW1lIiAKKyAgICAgKiBhbmQgInZhbHVlIiBmaWVsZC4gCisgICAgICoKKyAgICAgKiBAcmV0dXJuCWFuIEVudW1lcmF0aW9uIG9mIFN0cmluZ3MKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgRW51bWVyYXRpb248U3RyaW5nPiBnZXRBbGxIZWFkZXJMaW5lcygpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXQgbWF0Y2hpbmcgaGVhZGVyIGxpbmVzIGFzIGFuIEVudW1lcmF0aW9uIG9mIFN0cmluZ3MuIAorICAgICAqIEEgSGVhZGVyIGxpbmUgaXMgYSByYXcgUkZDODIyIGhlYWRlci1saW5lLCBjb250YWluaW5nIGJvdGggCisgICAgICogdGhlICJuYW1lIiBhbmQgInZhbHVlIiBmaWVsZC4KKyAgICAgKgorICAgICAqIEBwYXJhbQluYW1lcwl0aGUgaGVhZGVycyB0byByZXR1cm4KKyAgICAgKiBAcmV0dXJuCWFuIEVudW1lcmF0aW9uIG9mIFN0cmluZ3MKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgRW51bWVyYXRpb248U3RyaW5nPiBnZXRNYXRjaGluZ0hlYWRlckxpbmVzKFN0cmluZ1tdIG5hbWVzKQorCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldCBub24tbWF0Y2hpbmcgaGVhZGVyIGxpbmVzIGFzIGFuIEVudW1lcmF0aW9uIG9mIFN0cmluZ3MuIAorICAgICAqIEEgSGVhZGVyIGxpbmUgaXMgYSByYXcgUkZDODIyIGhlYWRlci1saW5lLCBjb250YWluaW5nIGJvdGggCisgICAgICogdGhlICJuYW1lIiAgYW5kICJ2YWx1ZSIgZmllbGQuCisgICAgICoKKyAgICAgKiBAcGFyYW0JbmFtZXMJdGhlIGhlYWRlcnMgdG8gbm90IHJldHVybgorICAgICAqIEByZXR1cm4JYW4gRW51bWVyYXRpb24gb2YgU3RyaW5ncworICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBFbnVtZXJhdGlvbjxTdHJpbmc+IGdldE5vbk1hdGNoaW5nSGVhZGVyTGluZXMoU3RyaW5nW10gbmFtZXMpCisJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0IHRoZSB0cmFuc2ZlciBlbmNvZGluZyBvZiB0aGlzIHBhcnQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCQljb250ZW50LXRyYW5zZmVyLWVuY29kaW5nCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24gZm9yIGZhaWx1cmVzCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRFbmNvZGluZygpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIENvbnRlbnQtSUQgb2YgdGhpcyBwYXJ0LiBSZXR1cm5zIG51bGwgaWYgbm9uZSBwcmVzZW50LgorICAgICAqCisgICAgICogQHJldHVybgkJY29udGVudC1JRAorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q29udGVudElEKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldCB0aGUgQ29udGVudC1NRDUgZGlnZXN0IG9mIHRoaXMgcGFydC4gUmV0dXJucyBudWxsIGlmCisgICAgICogbm9uZSBwcmVzZW50LgorICAgICAqCisgICAgICogQHJldHVybgkJY29udGVudC1NRDUKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3IgZmFpbHVyZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldENvbnRlbnRNRDUoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0IHRoZSBDb250ZW50LU1ENSBvZiB0aGlzIHBhcnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gIG1kNQl0aGUgTUQ1IHZhbHVlCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsV3JpdGVFeGNlcHRpb24gaWYgdGhlIHVuZGVybHlpbmcKKyAgICAgKgkJCWltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBQYXJ0IGlzCisgICAgICoJCQlvYnRhaW5lZCBmcm9tIGEgUkVBRF9PTkxZIGZvbGRlcgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldENvbnRlbnRNRDUoU3RyaW5nIG1kNSkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldCB0aGUgbGFuZ3VhZ2UgdGFncyBzcGVjaWZpZWQgaW4gdGhlIENvbnRlbnQtTGFuZ3VhZ2UgaGVhZGVyCisgICAgICogb2YgdGhpcyBNaW1lUGFydC4gVGhlIENvbnRlbnQtTGFuZ3VhZ2UgaGVhZGVyIGlzIGRlZmluZWQgYnkKKyAgICAgKiBSRkMgMTc2Ni4gUmV0dXJucyA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGlzIGhlYWRlciBpcyBub3QKKyAgICAgKiBhdmFpbGFibGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCWFycmF5IG9mIGNvbnRlbnQgbGFuZ3VhZ2Ugc3RyaW5ncworICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uIGZvciBmYWlsdXJlcworICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRDb250ZW50TGFuZ3VhZ2UoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2V0IHRoZSBDb250ZW50LUxhbmd1YWdlIGhlYWRlciBvZiB0aGlzIE1pbWVQYXJ0LiBUaGUKKyAgICAgKiBDb250ZW50LUxhbmd1YWdlIGhlYWRlciBpcyBkZWZpbmVkIGJ5IFJGQzE3NjYuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbGFuZ3VhZ2VzCWFycmF5IG9mIGxhbmd1YWdlIHRhZ3MKKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxXcml0ZUV4Y2VwdGlvbiBpZiB0aGUgdW5kZXJseWluZworICAgICAqCQkJaW1wbGVtZW50YXRpb24gZG9lcyBub3Qgc3VwcG9ydCBtb2RpZmljYXRpb24KKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIFBhcnQgaXMKKyAgICAgKgkJCW9idGFpbmVkIGZyb20gYSBSRUFEX09OTFkgZm9sZGVyCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q29udGVudExhbmd1YWdlKFN0cmluZ1tdIGxhbmd1YWdlcykKKwkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb247CisgICAgCisgICAgLyoqCisgICAgICogQ29udmVuaWVuY2UgbWV0aG9kIHRoYXQgc2V0cyB0aGUgZ2l2ZW4gU3RyaW5nIGFzIHRoaXMKKyAgICAgKiBwYXJ0J3MgY29udGVudCwgd2l0aCBhIE1JTUUgdHlwZSBvZiAidGV4dC9wbGFpbiIuIElmIHRoZQorICAgICAqIHN0cmluZyBjb250YWlucyBub24gVVMtQVNDSUkgY2hhcmFjdGVycy4gaXQgd2lsbCBiZSBlbmNvZGVkCisgICAgICogdXNpbmcgdGhlIHBsYXRmb3JtJ3MgZGVmYXVsdCBjaGFyc2V0LiBUaGUgY2hhcnNldCBpcyBhbHNvCisgICAgICogdXNlZCB0byBzZXQgdGhlICJjaGFyc2V0IiBwYXJhbWV0ZXIuIDxwPgorICAgICAqCisgICAgICogTm90ZSB0aGF0IHRoZXJlIG1heSBiZSBhIHBlcmZvcm1hbmNlIHBlbmFsdHkgaWYKKyAgICAgKiA8Y29kZT50ZXh0PC9jb2RlPiBpcyBsYXJnZSwgc2luY2UgdGhpcyBtZXRob2QgbWF5IGhhdmUKKyAgICAgKiB0byBzY2FuIGFsbCB0aGUgY2hhcmFjdGVycyB0byBkZXRlcm1pbmUgd2hhdCBjaGFyc2V0IHRvCisgICAgICogdXNlLiA8cD4KKyAgICAgKgorICAgICAqIElmIHRoZSBjaGFyc2V0IGlzIGFscmVhZHkga25vd24sIHVzZSB0aGUKKyAgICAgKiA8Y29kZT5zZXRUZXh0PC9jb2RlPiBtZXRob2QgdGhhdCB0YWtlcyB0aGUgY2hhcnNldCBwYXJhbWV0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0JdGV4dAl0aGUgdGV4dCBjb250ZW50IHRvIHNldAorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uCWlmIGFuIGVycm9yIG9jY3VycworICAgICAqIEBzZWUJI3NldFRleHQoU3RyaW5nIHRleHQsIFN0cmluZyBjaGFyc2V0KQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldFRleHQoU3RyaW5nIHRleHQpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBDb252ZW5pZW5jZSBtZXRob2QgdGhhdCBzZXRzIHRoZSBnaXZlbiBTdHJpbmcgYXMgdGhpcyBwYXJ0J3MKKyAgICAgKiBjb250ZW50LCB3aXRoIGEgTUlNRSB0eXBlIG9mICJ0ZXh0L3BsYWluIiBhbmQgdGhlIHNwZWNpZmllZAorICAgICAqIGNoYXJzZXQuIFRoZSBnaXZlbiBVbmljb2RlIHN0cmluZyB3aWxsIGJlIGNoYXJzZXQtZW5jb2RlZAorICAgICAqIHVzaW5nIHRoZSBzcGVjaWZpZWQgY2hhcnNldC4gVGhlIGNoYXJzZXQgaXMgYWxzbyB1c2VkIHRvIHNldAorICAgICAqICJjaGFyc2V0IiBwYXJhbWV0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0JdGV4dAl0aGUgdGV4dCBjb250ZW50IHRvIHNldAorICAgICAqIEBwYXJhbQljaGFyc2V0CXRoZSBjaGFyc2V0IHRvIHVzZSBmb3IgdGhlIHRleHQKKyAgICAgKiBAZXhjZXB0aW9uCU1lc3NhZ2luZ0V4Y2VwdGlvbglpZiBhbiBlcnJvciBvY2N1cnMKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRUZXh0KFN0cmluZyB0ZXh0LCBTdHJpbmcgY2hhcnNldCkKKwkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBDb252ZW5pZW5jZSBtZXRob2QgdGhhdCBzZXRzIHRoZSBnaXZlbiBTdHJpbmcgYXMgdGhpcyBwYXJ0J3MKKyAgICAgKiBjb250ZW50LCB3aXRoIGEgcHJpbWFyeSBNSU1FIHR5cGUgb2YgInRleHQiIGFuZCB0aGUgc3BlY2lmaWVkCisgICAgICogTUlNRSBzdWJ0eXBlLiAgVGhlIGdpdmVuIFVuaWNvZGUgc3RyaW5nIHdpbGwgYmUgY2hhcnNldC1lbmNvZGVkCisgICAgICogdXNpbmcgdGhlIHNwZWNpZmllZCBjaGFyc2V0LiBUaGUgY2hhcnNldCBpcyBhbHNvIHVzZWQgdG8gc2V0CisgICAgICogdGhlICJjaGFyc2V0IiBwYXJhbWV0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0JdGV4dAl0aGUgdGV4dCBjb250ZW50IHRvIHNldAorICAgICAqIEBwYXJhbQljaGFyc2V0CXRoZSBjaGFyc2V0IHRvIHVzZSBmb3IgdGhlIHRleHQKKyAgICAgKiBAcGFyYW0Jc3VidHlwZQl0aGUgTUlNRSBzdWJ0eXBlIHRvIHVzZSAoZS5nLiwgImh0bWwiKQorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uCWlmIGFuIGVycm9yIG9jY3VycworICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRUZXh0KFN0cmluZyB0ZXh0LCBTdHJpbmcgY2hhcnNldCwgU3RyaW5nIHN1YnR5cGUpCisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvTWltZVBhcnREYXRhU291cmNlLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9NaW1lUGFydERhdGFTb3VyY2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZTQ4MWFlCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvTWltZVBhcnREYXRhU291cmNlLmphdmEKQEAgLTAsMCArMSwxNTMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5pbnRlcm5ldDsKKworaW1wb3J0IGphdmF4Lm1haWwuKjsKK2ltcG9ydCBqYXZheC5hY3RpdmF0aW9uLio7CitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmEubmV0LlVua25vd25TZXJ2aWNlRXhjZXB0aW9uOworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLlByb3BVdGlsOworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLkZvbGRlckNsb3NlZElPRXhjZXB0aW9uOworCisvKioKKyAqIEEgdXRpbGl0eSBjbGFzcyB0aGF0IGltcGxlbWVudHMgYSBEYXRhU291cmNlIG91dCBvZgorICogYSBNaW1lUGFydC4gVGhpcyBjbGFzcyBpcyBwcmltYXJpbHkgbWVhbnQgZm9yIHNlcnZpY2UgcHJvdmlkZXJzLgorICoKKyAqIEBzZWUJCWphdmF4Lm1haWwuaW50ZXJuZXQuTWltZVBhcnQKKyAqIEBzZWUJCWphdmF4LmFjdGl2YXRpb24uRGF0YVNvdXJjZQorICogQGF1dGhvciAJSm9obiBNYW5pCisgKi8KKworcHVibGljIGNsYXNzIE1pbWVQYXJ0RGF0YVNvdXJjZSBpbXBsZW1lbnRzIERhdGFTb3VyY2UsIE1lc3NhZ2VBd2FyZSB7CisgICAgLyoqCisgICAgICogVGhlIE1pbWVQYXJ0IHRoYXQgcHJvdmlkZXMgdGhlIGRhdGEgZm9yIHRoaXMgRGF0YVNvdXJjZS4KKyAgICAgKgorICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjQKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgTWltZVBhcnQgcGFydDsKKworICAgIHByaXZhdGUgTWVzc2FnZUNvbnRleHQgY29udGV4dDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yLCB0aGF0IGNvbnN0cnVjdHMgYSBEYXRhU291cmNlIGZyb20gYSBNaW1lUGFydC4KKyAgICAgKgorICAgICAqIEBwYXJhbQlwYXJ0CXRoZSBNaW1lUGFydAorICAgICAqLworICAgIHB1YmxpYyBNaW1lUGFydERhdGFTb3VyY2UoTWltZVBhcnQgcGFydCkgeworCXRoaXMucGFydCA9IHBhcnQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyBhbiBpbnB1dCBzdHJlYW0gZnJvbSB0aGlzICBNaW1lUGFydC4gPHA+CisgICAgICoKKyAgICAgKiBUaGlzIG1ldGhvZCBhcHBsaWVzIHRoZSBhcHByb3ByaWF0ZSB0cmFuc2Zlci1kZWNvZGluZywgYmFzZWQgCisgICAgICogb24gdGhlIENvbnRlbnQtVHJhbnNmZXItRW5jb2RpbmcgYXR0cmlidXRlIG9mIHRoaXMgTWltZVBhcnQuCisgICAgICogVGh1cyB0aGUgcmV0dXJuZWQgaW5wdXQgc3RyZWFtIGlzIGEgZGVjb2RlZCBzdHJlYW0gb2YgYnl0ZXMuPHA+CisgICAgICoKKyAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIG9idGFpbnMgdGhlIHJhdyBjb250ZW50IGZyb20gdGhlIFBhcnQKKyAgICAgKiB1c2luZyB0aGUgPGNvZGU+Z2V0Q29udGVudFN0cmVhbSgpPC9jb2RlPiBtZXRob2QgYW5kIGRlY29kZXMKKyAgICAgKiBpdCB1c2luZyB0aGUgPGNvZGU+TWltZVV0aWxpdHkuZGVjb2RlKCk8L2NvZGU+IG1ldGhvZC4KKyAgICAgKgorICAgICAqIEBzZWUJamF2YXgubWFpbC5pbnRlcm5ldC5NaW1lTWVzc2FnZSNnZXRDb250ZW50U3RyZWFtCisgICAgICogQHNlZQlqYXZheC5tYWlsLmludGVybmV0Lk1pbWVCb2R5UGFydCNnZXRDb250ZW50U3RyZWFtCisgICAgICogQHNlZQlqYXZheC5tYWlsLmludGVybmV0Lk1pbWVVdGlsaXR5I2RlY29kZQorICAgICAqIEByZXR1cm4gCWRlY29kZWQgaW5wdXQgc3RyZWFtCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIElucHV0U3RyZWFtIGdldElucHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlJbnB1dFN0cmVhbSBpczsKKworCXRyeSB7CisJICAgIGlmIChwYXJ0IGluc3RhbmNlb2YgTWltZUJvZHlQYXJ0KQorCQlpcyA9ICgoTWltZUJvZHlQYXJ0KXBhcnQpLmdldENvbnRlbnRTdHJlYW0oKTsKKwkgICAgZWxzZSBpZiAocGFydCBpbnN0YW5jZW9mIE1pbWVNZXNzYWdlKQorCQlpcyA9ICgoTWltZU1lc3NhZ2UpcGFydCkuZ2V0Q29udGVudFN0cmVhbSgpOworCSAgICBlbHNlCisJCXRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oIlVua25vd24gcGFydCIpOworCSAgICAKKwkgICAgU3RyaW5nIGVuY29kaW5nID0KKwkJTWltZUJvZHlQYXJ0LnJlc3RyaWN0RW5jb2RpbmcocGFydCwgcGFydC5nZXRFbmNvZGluZygpKTsKKwkgICAgaWYgKGVuY29kaW5nICE9IG51bGwpCisJCXJldHVybiBNaW1lVXRpbGl0eS5kZWNvZGUoaXMsIGVuY29kaW5nKTsKKwkgICAgZWxzZQorCQlyZXR1cm4gaXM7CisJfSBjYXRjaCAoRm9sZGVyQ2xvc2VkRXhjZXB0aW9uIGZleCkgeworCSAgICB0aHJvdyBuZXcgRm9sZGVyQ2xvc2VkSU9FeGNlcHRpb24oZmV4LmdldEZvbGRlcigpLAorCQkJCQkJZmV4LmdldE1lc3NhZ2UoKSk7CisJfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIG1leCkgeworCSAgICBJT0V4Y2VwdGlvbiBpb2V4ID0gbmV3IElPRXhjZXB0aW9uKG1leC5nZXRNZXNzYWdlKCkpOworCSAgICBpb2V4LmluaXRDYXVzZShtZXgpOworCSAgICB0aHJvdyBpb2V4OworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEYXRhU291cmNlIG1ldGhvZCB0byByZXR1cm4gYW4gb3V0cHV0IHN0cmVhbS4gPHA+CisgICAgICoKKyAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIHRocm93cyB0aGUgVW5rbm93blNlcnZpY2VFeGNlcHRpb24uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE91dHB1dFN0cmVhbSBnZXRPdXRwdXRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworCXRocm93IG5ldyBVbmtub3duU2VydmljZUV4Y2VwdGlvbigiV3JpdGluZyBub3Qgc3VwcG9ydGVkIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY29udGVudC10eXBlIG9mIHRoaXMgRGF0YVNvdXJjZS4gPHA+CisgICAgICoKKyAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIGp1c3QgaW52b2tlcyB0aGUgPGNvZGU+Z2V0Q29udGVudFR5cGU8L2NvZGU+CisgICAgICogbWV0aG9kIG9uIHRoZSBNaW1lUGFydC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldENvbnRlbnRUeXBlKCkgeworCXRyeSB7CisJICAgIHJldHVybiBwYXJ0LmdldENvbnRlbnRUeXBlKCk7CisJfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIG1leCkgeworCSAgICAvLyB3b3VsZCBsaWtlIHRvIGJlIGFibGUgdG8gcmVmbGVjdCB0aGUgZXhjZXB0aW9uIHRvIHRoZQorCSAgICAvLyBhcHBsaWNhdGlvbiwgYnV0IHNpbmNlIHdlIGNhbid0IGRvIHRoYXQgd2UgcmV0dXJuIGEKKwkgICAgLy8gZ2VuZXJpYyAidW5rbm93biIgdmFsdWUgaGVyZSBhbmQgaG9wZSBmb3IgYW5vdGhlcgorCSAgICAvLyBleGNlcHRpb24gbGF0ZXIuCisJICAgIHJldHVybiAiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIjsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogRGF0YVNvdXJjZSBtZXRob2QgdG8gcmV0dXJuIGEgbmFtZS4gIDxwPgorICAgICAqCisgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiBqdXN0IHJldHVybnMgYW4gZW1wdHkgc3RyaW5nLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKKwl0cnkgeworCSAgICBpZiAocGFydCBpbnN0YW5jZW9mIE1pbWVCb2R5UGFydCkKKwkJcmV0dXJuICgoTWltZUJvZHlQYXJ0KXBhcnQpLmdldEZpbGVOYW1lKCk7CisJfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIG1leCkgeworCSAgICAvLyBpZ25vcmUgaXQKKwl9CisJcmV0dXJuICIiOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgPGNvZGU+TWVzc2FnZUNvbnRleHQ8L2NvZGU+IGZvciB0aGUgY3VycmVudCBwYXJ0LgorICAgICAqIEBzaW5jZSBKYXZhTWFpbCAxLjEKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIE1lc3NhZ2VDb250ZXh0IGdldE1lc3NhZ2VDb250ZXh0KCkgeworCWlmIChjb250ZXh0ID09IG51bGwpCisJICAgIGNvbnRleHQgPSBuZXcgTWVzc2FnZUNvbnRleHQocGFydCk7CisJcmV0dXJuIGNvbnRleHQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvTWltZVV0aWxpdHkuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2ludGVybmV0L01pbWVVdGlsaXR5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmJiMDQzYgotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2ludGVybmV0L01pbWVVdGlsaXR5LmphdmEKQEAgLTAsMCArMSwxNzA4IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGphdmF4Lm1haWwuaW50ZXJuZXQ7CisKK2ltcG9ydCBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5tYWlsLkVuY29kaW5nQXdhcmU7CitpbXBvcnQgamF2YXguYWN0aXZhdGlvbi4qOworaW1wb3J0IGphdmEudXRpbC4qOworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXQ7CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuUHJvcFV0aWw7CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuQVNDSUlVdGlsaXR5OworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLkJBU0U2NERlY29kZXJTdHJlYW07CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuQkFTRTY0RW5jb2RlclN0cmVhbTsKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5CRW5jb2RlclN0cmVhbTsKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5MaW5lSW5wdXRTdHJlYW07CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuTGluZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5Mb2dPdXRwdXRTdHJlYW07CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuUURlY29kZXJTdHJlYW07CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuUUVuY29kZXJTdHJlYW07CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuUVBEZWNvZGVyU3RyZWFtOworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLlFQRW5jb2RlclN0cmVhbTsKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5VVURlY29kZXJTdHJlYW07CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuVVVFbmNvZGVyU3RyZWFtOworCisvKioKKyAqIFRoaXMgaXMgYSB1dGlsaXR5IGNsYXNzIHRoYXQgcHJvdmlkZXMgdmFyaW91cyBNSU1FIHJlbGF0ZWQKKyAqIGZ1bmN0aW9uYWxpdHkuIDxwPgorICoKKyAqIFRoZXJlIGFyZSBhIHNldCBvZiBtZXRob2RzIHRvIGVuY29kZSBhbmQgZGVjb2RlIE1JTUUgaGVhZGVycyBhcyAKKyAqIHBlciBSRkMgMjA0Ny4gIE5vdGUgdGhhdCwgaW4gZ2VuZXJhbCwgdGhlc2UgbWV0aG9kcyBhcmUKKyAqIDxzdHJvbmc+bm90PC9zdHJvbmc+IG5lZWRlZCB3aGVuIHVzaW5nIG1ldGhvZHMgc3VjaCBhcworICogPGNvZGU+c2V0U3ViamVjdDwvY29kZT4gYW5kIDxjb2RlPnNldFJlY2lwaWVudHM8L2NvZGU+OyBKYXZhTWFpbAorICogd2lsbCBhdXRvbWF0aWNhbGx5IGVuY29kZSBhbmQgZGVjb2RlIGRhdGEgd2hlbiB1c2luZyB0aGVzZSAiaGlnaGVyCisgKiBsZXZlbCIgbWV0aG9kcy4gIFRoZSBtZXRob2RzIGJlbG93IGFyZSBvbmx5IG5lZWRlZCB3aGVuIG1hbml1cGxhdGluZworICogcmF3IE1JTUUgaGVhZGVycyB1c2luZyA8Y29kZT5zZXRIZWFkZXI8L2NvZGU+IGFuZCA8Y29kZT5nZXRIZWFkZXI8L2NvZGU+CisgKiBtZXRob2RzLiAgQSBicmllZiBkZXNjcmlwdGlvbiBvbiBoYW5kbGluZyBzdWNoIGhlYWRlcnMgaXMgZ2l2ZW4gYmVsb3c6IDxwPgorICoKKyAqIFJGQyA4MjIgbWFpbCBoZWFkZXJzIDxzdHJvbmc+bXVzdDwvc3Ryb25nPiBjb250YWluIG9ubHkgVVMtQVNDSUkKKyAqIGNoYXJhY3RlcnMuIEhlYWRlcnMgdGhhdCBjb250YWluIG5vbiBVUy1BU0NJSSBjaGFyYWN0ZXJzIG11c3QgYmUKKyAqIGVuY29kZWQgc28gdGhhdCB0aGV5IGNvbnRhaW4gb25seSBVUy1BU0NJSSBjaGFyYWN0ZXJzLiBCYXNpY2FsbHksCisgKiB0aGlzIHByb2Nlc3MgaW52b2x2ZXMgdXNpbmcgZWl0aGVyIEJBU0U2NCBvciBRUCB0byBlbmNvZGUgY2VydGFpbgorICogY2hhcmFjdGVycy4gUkZDIDIwNDcgZGVzY3JpYmVzIHRoaXMgaW4gZGV0YWlsLiA8cD4KKyAqCisgKiBJbiBKYXZhLCBTdHJpbmdzIGNvbnRhaW4gKDE2IGJpdCkgVW5pY29kZSBjaGFyYWN0ZXJzLiBBU0NJSSBpcyBhCisgKiBzdWJzZXQgb2YgVW5pY29kZSAoYW5kIG9jY3VwaWVzIHRoZSByYW5nZSAwIC0gMTI3KS4gQSBTdHJpbmcKKyAqIHRoYXQgY29udGFpbnMgb25seSBBU0NJSSBjaGFyYWN0ZXJzIGlzIGFscmVhZHkgbWFpbC1zYWZlLiBJZiB0aGUKKyAqIFN0cmluZyBjb250YWlucyBub24gVVMtQVNDSUkgY2hhcmFjdGVycywgaXQgbXVzdCBiZSBlbmNvZGVkLiBBbgorICogYWRkaXRpb25hbCBjb21wbGV4aXR5IGluIHRoaXMgc3RlcCBpcyB0aGF0IHNpbmNlIFVuaWNvZGUgaXMgbm90CisgKiB5ZXQgYSB3aWRlbHkgdXNlZCBjaGFyc2V0LCBvbmUgbWlnaHQgd2FudCB0byBmaXJzdCBjaGFyc2V0LWVuY29kZQorICogdGhlIFN0cmluZyBpbnRvIGFub3RoZXIgY2hhcnNldCBhbmQgdGhlbiBkbyB0aGUgdHJhbnNmZXItZW5jb2RpbmcuCisgKiA8cD4KKyAqIE5vdGUgdGhhdCB0byBnZXQgdGhlIGFjdHVhbCBieXRlcyBvZiBhIG1haWwtc2FmZSBTdHJpbmcgKHNheSwKKyAqIGZvciBzZW5kaW5nIG92ZXIgU01UUCksIG9uZSBtdXN0IGRvIAorICogPGJsb2NrcXVvdGU+PHByZT4KKyAqCisgKglieXRlW10gYnl0ZXMgPSBzdHJpbmcuZ2V0Qnl0ZXMoImlzby04ODU5LTEiKTsJCisgKgorICogPC9wcmU+PC9ibG9ja3F1b3RlPjxwPgorICogCisgKiBUaGUgPGNvZGU+c2V0SGVhZGVyPC9jb2RlPiBhbmQgPGNvZGU+YWRkSGVhZGVyPC9jb2RlPiBtZXRob2RzCisgKiBvbiBNaW1lTWVzc2FnZSBhbmQgTWltZUJvZHlQYXJ0IGFzc3VtZSB0aGF0IHRoZSBnaXZlbiBoZWFkZXIgdmFsdWVzCisgKiBhcmUgVW5pY29kZSBzdHJpbmdzIHRoYXQgY29udGFpbiBvbmx5IFVTLUFTQ0lJIGNoYXJhY3RlcnMuIEhlbmNlCisgKiB0aGUgY2FsbGVycyBvZiB0aG9zZSBtZXRob2RzIG11c3QgaW5zdXJlIHRoYXQgdGhlIHZhbHVlcyB0aGV5IHBhc3MKKyAqIGRvIG5vdCBjb250YWluIG5vbiBVUy1BU0NJSSBjaGFyYWN0ZXJzLiBUaGUgbWV0aG9kcyBpbiB0aGlzIGNsYXNzIAorICogaGVscCBkbyB0aGlzLiA8cD4KKyAqCisgKiBUaGUgPGNvZGU+Z2V0SGVhZGVyPC9jb2RlPiBmYW1pbHkgb2YgbWV0aG9kcyBvbiBNaW1lTWVzc2FnZSBhbmQKKyAqIE1pbWVCb2R5UGFydCByZXR1cm4gdGhlIHJhdyBoZWFkZXIgdmFsdWUuIFRoZXNlIG1pZ2h0IGJlIGVuY29kZWQKKyAqIGFzIHBlciBSRkMgMjA0NywgYW5kIGlmIHNvLCBtdXN0IGJlIGRlY29kZWQgaW50byBVbmljb2RlIFN0cmluZ3MuCisgKiBUaGUgbWV0aG9kcyBpbiB0aGlzIGNsYXNzIGhlbHAgdG8gZG8gdGhpcy4gPHA+CisgKgorICogU2V2ZXJhbCBTeXN0ZW0gcHJvcGVydGllcyBjb250cm9sIHN0cmljdCBjb25mb3JtYW5jZSB0byB0aGUgTUlNRQorICogc3BlYy4gIE5vdGUgdGhhdCB0aGVzZSBhcmUgbm90IHNlc3Npb24gcHJvcGVydGllcyBidXQgbXVzdCBiZSBzZXQKKyAqIGdsb2JhbGx5IGFzIFN5c3RlbSBwcm9wZXJ0aWVzLiA8cD4KKyAqCisgKiBUaGUgPGNvZGU+bWFpbC5taW1lLmRlY29kZXRleHQuc3RyaWN0PC9jb2RlPiBwcm9wZXJ0eSBjb250cm9scworICogZGVjb2Rpbmcgb2YgTUlNRSBlbmNvZGVkIHdvcmRzLiAgVGhlIE1JTUUgc3BlYyByZXF1aXJlcyB0aGF0IGVuY29kZWQKKyAqIHdvcmRzIHN0YXJ0IGF0IHRoZSBiZWdpbm5pbmcgb2YgYSB3aGl0ZXNwYWNlIHNlcGFyYXRlZCB3b3JkLiAgU29tZQorICogbWFpbGVycyBpbmNvcnJlY3RseSBpbmNsdWRlIGVuY29kZWQgd29yZHMgaW4gdGhlIG1pZGRsZSBvZiBhIHdvcmQuCisgKiBJZiB0aGUgPGNvZGU+bWFpbC5taW1lLmRlY29kZXRleHQuc3RyaWN0PC9jb2RlPiBTeXN0ZW0gcHJvcGVydHkgaXMKKyAqIHNldCB0byA8Y29kZT4iZmFsc2UiPC9jb2RlPiwgYW4gYXR0ZW1wdCB3aWxsIGJlIG1hZGUgdG8gZGVjb2RlIHRoZXNlCisgKiBpbGxlZ2FsIGVuY29kZWQgd29yZHMuIFRoZSBkZWZhdWx0IGlzIHRydWUuIDxwPgorICoKKyAqIFRoZSA8Y29kZT5tYWlsLm1pbWUuZW5jb2RlZW9sLnN0cmljdDwvY29kZT4gcHJvcGVydHkgY29udHJvbHMgdGhlCisgKiBjaG9pY2Ugb2YgQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZyBmb3IgTUlNRSBwYXJ0cyB0aGF0IGFyZSBub3Qgb2YKKyAqIHR5cGUgInRleHQiLiAgT2Z0ZW4gc3VjaCBwYXJ0cyB3aWxsIGNvbnRhaW4gdGV4dHVhbCBkYXRhIGZvciB3aGljaAorICogYW4gZW5jb2RpbmcgdGhhdCBhbGxvd3Mgbm9ybWFsIGVuZCBvZiBsaW5lIGNvbnZlbnRpb25zIGlzIGFwcHJvcHJpYXRlLgorICogSW4gcmFyZSBjYXNlcywgc3VjaCBhIHBhcnQgd2lsbCBhcHBlYXIgdG8gY29udGFpbiBlbnRpcmVseSB0ZXh0dWFsCisgKiBkYXRhLCBidXQgd2lsbCByZXF1aXJlIGFuIGVuY29kaW5nIHRoYXQgcHJlc2VydmVzIENSIGFuZCBMRiBjaGFyYWN0ZXJzCisgKiB3aXRob3V0IGNoYW5nZS4gIElmIHRoZSA8Y29kZT5tYWlsLm1pbWUuZW5jb2RlZW9sLnN0cmljdDwvY29kZT4KKyAqIFN5c3RlbSBwcm9wZXJ0eSBpcyBzZXQgdG8gPGNvZGU+InRydWUiPC9jb2RlPiwgc3VjaCBhbiBlbmNvZGluZyB3aWxsCisgKiBiZSB1c2VkIHdoZW4gbmVjZXNzYXJ5LiAgVGhlIGRlZmF1bHQgaXMgZmFsc2UuIDxwPgorICoKKyAqIEluIGFkZGl0aW9uLCB0aGUgPGNvZGU+bWFpbC5taW1lLmNoYXJzZXQ8L2NvZGU+IFN5c3RlbSBwcm9wZXJ0eSBjYW4KKyAqIGJlIHVzZWQgdG8gc3BlY2lmeSB0aGUgZGVmYXVsdCBNSU1FIGNoYXJzZXQgdG8gdXNlIGZvciBlbmNvZGVkIHdvcmRzCisgKiBhbmQgdGV4dCBwYXJ0cyB0aGF0IGRvbid0IG90aGVyd2lzZSBzcGVjaWZ5IGEgY2hhcnNldC4gIE5vcm1hbGx5LCB0aGUKKyAqIGRlZmF1bHQgTUlNRSBjaGFyc2V0IGlzIGRlcml2ZWQgZnJvbSB0aGUgZGVmYXVsdCBKYXZhIGNoYXJzZXQsIGFzCisgKiBzcGVjaWZpZWQgaW4gdGhlIDxjb2RlPmZpbGUuZW5jb2Rpbmc8L2NvZGU+IFN5c3RlbSBwcm9wZXJ0eS4gIE1vc3QKKyAqIGFwcGxpY2F0aW9ucyB3aWxsIGhhdmUgbm8gbmVlZCB0byBleHBsaWNpdGx5IHNldCB0aGUgZGVmYXVsdCBNSU1FCisgKiBjaGFyc2V0LiAgSW4gY2FzZXMgd2hlcmUgdGhlIGRlZmF1bHQgTUlNRSBjaGFyc2V0IHRvIGJlIHVzZWQgZm9yCisgKiBtYWlsIG1lc3NhZ2VzIGlzIGRpZmZlcmVudCB0aGFuIHRoZSBjaGFyc2V0IHVzZWQgZm9yIGZpbGVzIHN0b3JlZCBvbgorICogdGhlIHN5c3RlbSwgdGhpcyBwcm9wZXJ0eSBzaG91bGQgYmUgc2V0LiA8cD4KKyAqCisgKiBUaGUgY3VycmVudCBpbXBsZW1lbnRhdGlvbiBhbHNvIHN1cHBvcnRzIHRoZSBmb2xsb3dpbmcgU3lzdGVtIHByb3BlcnR5LgorICogPHA+CisgKiBUaGUgPGNvZGU+bWFpbC5taW1lLmlnbm9yZXVua25vd25lbmNvZGluZzwvY29kZT4gcHJvcGVydHkgY29udHJvbHMKKyAqIHdoZXRoZXIgdW5rbm93biB2YWx1ZXMgaW4gdGhlIDxjb2RlPkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc8L2NvZGU+CisgKiBoZWFkZXIsIGFzIHBhc3NlZCB0byB0aGUgPGNvZGU+ZGVjb2RlPC9jb2RlPiBtZXRob2QsIGNhdXNlIGFuIGV4Y2VwdGlvbi4KKyAqIElmIHNldCB0byA8Y29kZT4idHJ1ZSI8L2NvZGU+LCB1bmtub3duIHZhbHVlcyBhcmUgaWdub3JlZCBhbmQgOGJpdAorICogZW5jb2RpbmcgaXMgYXNzdW1lZC4gIE90aGVyd2lzZSwgdW5rbm93biB2YWx1ZXMgY2F1c2UgYSBNZXNzYWdpbmdFeGNlcHRpb24KKyAqIHRvIGJlIHRocm93bi4KKyAqCisgKiBAYXV0aG9yICBKb2huIE1hbmkKKyAqIEBhdXRob3IgIEJpbGwgU2hhbm5vbgorICovCisKK3B1YmxpYyBjbGFzcyBNaW1lVXRpbGl0eSB7CisKKyAgICAvLyBUaGlzIGNsYXNzIGNhbm5vdCBiZSBpbnN0YW50aWF0ZWQKKyAgICBwcml2YXRlIE1pbWVVdGlsaXR5KCkgeyB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBTEwgPSAtMTsKKworICAgIC8vIGNhY2hlZCBtYXAgb2Ygd2hldGhlciBhIGNoYXJzZXQgaXMgY29tcGF0aWJsZSB3aXRoIEFTQ0lJCisgICAgLy8gTWFwPFN0cmluZyxCb29sZWFuPgorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE1hcDxTdHJpbmcsIEJvb2xlYW4+IG5vbkFzY2lpQ2hhcnNldE1hcAorCSAgICA9IG5ldyBIYXNoTWFwPD4oKTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gZGVjb2RlU3RyaWN0ID0KKwlQcm9wVXRpbC5nZXRCb29sZWFuU3lzdGVtUHJvcGVydHkoIm1haWwubWltZS5kZWNvZGV0ZXh0LnN0cmljdCIsIHRydWUpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gZW5jb2RlRW9sU3RyaWN0ID0KKwlQcm9wVXRpbC5nZXRCb29sZWFuU3lzdGVtUHJvcGVydHkoIm1haWwubWltZS5lbmNvZGVlb2wuc3RyaWN0IiwgZmFsc2UpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gaWdub3JlVW5rbm93bkVuY29kaW5nID0KKwlQcm9wVXRpbC5nZXRCb29sZWFuU3lzdGVtUHJvcGVydHkoCisJICAgICJtYWlsLm1pbWUuaWdub3JldW5rbm93bmVuY29kaW5nIiwgZmFsc2UpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gYWxsb3dVdGY4ID0KKwlQcm9wVXRpbC5nZXRCb29sZWFuU3lzdGVtUHJvcGVydHkoIm1haWwubWltZS5hbGxvd3V0ZjgiLCBmYWxzZSk7CisgICAgLyoKKyAgICAgKiBUaGUgZm9sbG93aW5nIHR3byBwcm9wZXJ0aWVzIGFsbG93IGRpc2FibGluZyB0aGUgZm9sZCgpCisgICAgICogYW5kIHVuZm9sZCgpIG1ldGhvZHMgYW5kIHJldmVydGluZyB0byB0aGUgcHJldmlvdXMgYmVoYXZpb3IuCisgICAgICogVGhleSBzaG91bGQgbmV2ZXIgbmVlZCB0byBiZSBjaGFuZ2VkIGFuZCBhcmUgaGVyZSBvbmx5IGJlY2F1c2UKKyAgICAgKiBvZiBteSBwYXJhbm9pZCBjb25jZXJuIHdpdGggY29tcGF0aWJpbGl0eS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIGZvbGRFbmNvZGVkV29yZHMgPQorCVByb3BVdGlsLmdldEJvb2xlYW5TeXN0ZW1Qcm9wZXJ0eSgibWFpbC5taW1lLmZvbGRlbmNvZGVkd29yZHMiLCBmYWxzZSk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBmb2xkVGV4dCA9CisJUHJvcFV0aWwuZ2V0Qm9vbGVhblN5c3RlbVByb3BlcnR5KCJtYWlsLm1pbWUuZm9sZHRleHQiLCB0cnVlKTsKKworCisgICAgLyoqCisgICAgICogR2V0IHRoZSBDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nIHRoYXQgc2hvdWxkIGJlIGFwcGxpZWQKKyAgICAgKiB0byB0aGUgaW5wdXQgc3RyZWFtIG9mIHRoaXMgRGF0YVNvdXJjZSwgdG8gbWFrZSBpdCBtYWlsLXNhZmUuIDxwPgorICAgICAqCisgICAgICogVGhlIGFsZ29yaXRobSB1c2VkIGhlcmUgaXM6IDxicj4KKyAgICAgKiA8dWw+CisgICAgICogPGxpPgorICAgICAqIElmIHRoZSBEYXRhU291cmNlIGltcGxlbWVudHMge0BsaW5rIEVuY29kaW5nQXdhcmV9LCBhc2sgaXQKKyAgICAgKiB3aGF0IGVuY29kaW5nIHRvIHVzZS4gIElmIGl0IHJldHVybnMgbm9uLW51bGwsIHJldHVybiB0aGF0IHZhbHVlLgorICAgICAqIDxsaT4KKyAgICAgKiBJZiB0aGUgcHJpbWFyeSB0eXBlIG9mIHRoaXMgZGF0YXNvdXJjZSBpcyAidGV4dCIgYW5kIGlmIGFsbAorICAgICAqIHRoZSBieXRlcyBpbiBpdHMgaW5wdXQgc3RyZWFtIGFyZSBVUy1BU0NJSSwgdGhlbiB0aGUgZW5jb2RpbmcKKyAgICAgKiBpcyAiN2JpdCIuIElmIG1vcmUgdGhhbiBoYWxmIG9mIHRoZSBieXRlcyBhcmUgbm9uLVVTLUFTQ0lJLCB0aGVuCisgICAgICogdGhlIGVuY29kaW5nIGlzICJiYXNlNjQiLiBJZiBsZXNzIHRoYW4gaGFsZiBvZiB0aGUgYnl0ZXMgYXJlCisgICAgICogbm9uLVVTLUFTQ0lJLCB0aGVuIHRoZSBlbmNvZGluZyBpcyAicXVvdGVkLXByaW50YWJsZSIuCisgICAgICogPGxpPgorICAgICAqIElmIHRoZSBwcmltYXJ5IHR5cGUgb2YgdGhpcyBkYXRhc291cmNlIGlzIG5vdCAidGV4dCIsIHRoZW4gaWYKKyAgICAgKiBhbGwgdGhlIGJ5dGVzIG9mIGl0cyBpbnB1dCBzdHJlYW0gYXJlIFVTLUFTQ0lJLCB0aGUgZW5jb2RpbmcKKyAgICAgKiBpcyAiN2JpdCIuIElmIHRoZXJlIGlzIGV2ZW4gb25lIG5vbi1VUy1BU0NJSSBjaGFyYWN0ZXIsIHRoZQorICAgICAqIGVuY29kaW5nIGlzICJiYXNlNjQiLgorICAgICAqIDwvdWw+CisgICAgICoKKyAgICAgKiBAcGFyYW0JZHMJdGhlIERhdGFTb3VyY2UKKyAgICAgKiBAcmV0dXJuCQl0aGUgZW5jb2RpbmcuIFRoaXMgaXMgZWl0aGVyICI3Yml0IiwKKyAgICAgKgkJCSJxdW90ZWQtcHJpbnRhYmxlIiBvciAiYmFzZTY0IgorICAgICAqLyAKKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRFbmNvZGluZyhEYXRhU291cmNlIGRzKSB7CisJQ29udGVudFR5cGUgY1R5cGUgPSBudWxsOworCUlucHV0U3RyZWFtIGlzID0gbnVsbDsKKwlTdHJpbmcgZW5jb2RpbmcgPSBudWxsOworCisJaWYgKGRzIGluc3RhbmNlb2YgRW5jb2RpbmdBd2FyZSkgeworCSAgICBlbmNvZGluZyA9ICgoRW5jb2RpbmdBd2FyZSlkcykuZ2V0RW5jb2RpbmcoKTsKKwkgICAgaWYgKGVuY29kaW5nICE9IG51bGwpCisJCXJldHVybiBlbmNvZGluZzsKKwl9CisJdHJ5IHsKKwkgICAgY1R5cGUgPSBuZXcgQ29udGVudFR5cGUoZHMuZ2V0Q29udGVudFR5cGUoKSk7CisJICAgIGlzID0gZHMuZ2V0SW5wdXRTdHJlYW0oKTsKKworCSAgICBib29sZWFuIGlzVGV4dCA9IGNUeXBlLm1hdGNoKCJ0ZXh0LyoiKTsKKwkgICAgLy8gaWYgbm90IHRleHQsIHN0b3AgcHJvY2Vzc2luZyB3aGVuIHdlIHNlZSBub24tQVNDSUkKKwkgICAgaW50IGkgPSBjaGVja0FzY2lpKGlzLCBBTEwsICFpc1RleHQpOworCSAgICBzd2l0Y2ggKGkpIHsKKwkgICAgY2FzZSBBTExfQVNDSUk6CisJCWVuY29kaW5nID0gIjdiaXQiOyAvLyBhbGwgQVNDSUkKKwkJYnJlYWs7CisJICAgIGNhc2UgTU9TVExZX0FTQ0lJOgorCQlpZiAoaXNUZXh0ICYmIG5vbkFzY2lpQ2hhcnNldChjVHlwZSkpCisJCSAgICBlbmNvZGluZyA9ICJiYXNlNjQiOyAvLyBjaGFyc2V0IGlzbid0IGNvbXBhdGlibGUgd2l0aCBBU0NJSQorCQllbHNlCisJCSAgICBlbmNvZGluZyA9ICJxdW90ZWQtcHJpbnRhYmxlIjsJLy8gbW9zdGx5IEFTQ0lJCisJCWJyZWFrOworCSAgICBkZWZhdWx0OgorCQllbmNvZGluZyA9ICJiYXNlNjQiOyAvLyBtb3N0bHkgYmluYXJ5CisJCWJyZWFrOworCSAgICB9CisKKwl9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKwkgICAgcmV0dXJuICJiYXNlNjQiOyAvLyB3aGF0IGVsc2UgPyEKKwl9IGZpbmFsbHkgeworCSAgICAvLyBDbG9zZSB0aGUgaW5wdXQgc3RyZWFtCisJICAgIHRyeSB7CisJCWlmIChpcyAhPSBudWxsKQorCQkgICAgaXMuY2xvc2UoKTsKKwkgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9leCkgeyB9CisJfQorCisJcmV0dXJuIGVuY29kaW5nOworICAgIH0KKworICAgIC8qKgorICAgICAqIERldGVybWluZSB3aGV0aGVyIHRoZSBjaGFyc2V0IGluIHRoZSBDb250ZW50LVR5cGUgaXMgY29tcGF0aWJsZQorICAgICAqIHdpdGggQVNDSUkgb3Igbm90LiAgQSBjaGFyc2V0IGlzIGNvbXBhdGlibGUgd2l0aCBBU0NJSSBpZiB0aGUKKyAgICAgKiBlbmNvZGVkIGJ5dGUgc3RyZWFtIHJlcHJlc2VudGluZyB0aGUgVW5pY29kZSBzdHJpbmcgIlxyXG4iIGlzCisgICAgICogdGhlIEFTQ0lJIGNoYXJhY3RlcnMgQ1IgYW5kIExGLiAgRm9yIGV4YW1wbGUsIHRoZSB1dGYtMTZiZQorICAgICAqIGNoYXJzZXQgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBBU0NJSS4KKyAgICAgKgorICAgICAqIEZvciBwZXJmb3JtYW5jZSwgd2Uga2VlcCBhIHN0YXRpYyBtYXAgdGhhdCBjYWNoZXMgdGhlIHJlc3VsdHMuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBub25Bc2NpaUNoYXJzZXQoQ29udGVudFR5cGUgY3QpIHsKKwlTdHJpbmcgY2hhcnNldCA9IGN0LmdldFBhcmFtZXRlcigiY2hhcnNldCIpOworCWlmIChjaGFyc2V0ID09IG51bGwpCisJICAgIHJldHVybiBmYWxzZTsKKwljaGFyc2V0ID0gY2hhcnNldC50b0xvd2VyQ2FzZShMb2NhbGUuRU5HTElTSCk7CisJQm9vbGVhbiBib29sOworCXN5bmNocm9uaXplZCAobm9uQXNjaWlDaGFyc2V0TWFwKSB7CisJICAgIGJvb2wgPSBub25Bc2NpaUNoYXJzZXRNYXAuZ2V0KGNoYXJzZXQpOworCX0KKwlpZiAoYm9vbCA9PSBudWxsKSB7CisJICAgIHRyeSB7CisJCWJ5dGVbXSBiID0gIlxyXG4iLmdldEJ5dGVzKGNoYXJzZXQpOworCQlib29sID0gQm9vbGVhbi52YWx1ZU9mKAorCQkgICAgYi5sZW5ndGggIT0gMiB8fCBiWzBdICE9IDAxNSB8fCBiWzFdICE9IDAxMik7CisJICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gdWV4KSB7CisJCWJvb2wgPSBCb29sZWFuLkZBTFNFOwkvLyBhIGd1ZXNzCisJICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gZXgpIHsKKwkJYm9vbCA9IEJvb2xlYW4uVFJVRTsJLy8gb25lIG9mIHRoZSB3ZWlyZCBvbmVzPworCSAgICB9CisJICAgIHN5bmNocm9uaXplZCAobm9uQXNjaWlDaGFyc2V0TWFwKSB7CisJCW5vbkFzY2lpQ2hhcnNldE1hcC5wdXQoY2hhcnNldCwgYm9vbCk7CisJICAgIH0KKwl9CisJcmV0dXJuIGJvb2wuYm9vbGVhblZhbHVlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2FtZSBhcyA8Y29kZT5nZXRFbmNvZGluZyhEYXRhU291cmNlKTwvY29kZT4gZXhjZXB0IHRoYXQgaW5zdGVhZAorICAgICAqIG9mIHJlYWRpbmcgdGhlIGRhdGEgZnJvbSBhbiA8Y29kZT5JbnB1dFN0cmVhbTwvY29kZT4gaXQgdXNlcyB0aGUKKyAgICAgKiA8Y29kZT53cml0ZVRvPC9jb2RlPiBtZXRob2QgdG8gZXhhbWluZSB0aGUgZGF0YS4gIFRoaXMgaXMgbW9yZQorICAgICAqIGVmZmljaWVudCBpbiB0aGUgY29tbW9uIGNhc2Ugb2YgYSA8Y29kZT5EYXRhSGFuZGxlcjwvY29kZT4KKyAgICAgKiBjcmVhdGVkIHdpdGggYW4gb2JqZWN0IGFuZCBhIE1JTUUgdHlwZSAoZm9yIGV4YW1wbGUsIGEKKyAgICAgKiAidGV4dC9wbGFpbiIgU3RyaW5nKSBiZWNhdXNlIGFsbCB0aGUgSS9PIGlzIGRvbmUgaW4gdGhpcworICAgICAqIHRocmVhZC4gIEluIHRoZSBjYXNlIHJlcXVpcmluZyBhbiA8Y29kZT5JbnB1dFN0cmVhbTwvY29kZT4gdGhlCisgICAgICogPGNvZGU+RGF0YUhhbmRsZXI8L2NvZGU+IHVzZXMgYSB0aHJlYWQsIGEgcGFpciBvZiBwaXBlIHN0cmVhbXMsCisgICAgICogYW5kIHRoZSA8Y29kZT53cml0ZVRvPC9jb2RlPiBtZXRob2QgdG8gcHJvZHVjZSB0aGUgZGF0YS4gPHA+CisgICAgICoKKyAgICAgKiBAcGFyYW0JZGgJdGhlIERhdGFIYW5kbGVyCisgICAgICogQHJldHVybgl0aGUgQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZworICAgICAqIEBzaW5jZQlKYXZhTWFpbCAxLjIKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRFbmNvZGluZyhEYXRhSGFuZGxlciBkaCkgeworCUNvbnRlbnRUeXBlIGNUeXBlID0gbnVsbDsKKwlTdHJpbmcgZW5jb2RpbmcgPSBudWxsOworCisJLyoKKwkgKiBUcnkgdG8gcGljayB0aGUgbW9zdCBlZmZpY2llbnQgbWVhbnMgb2YgZGV0ZXJtaW5pbmcgdGhlCisJICogZW5jb2RpbmcuICBJZiB0aGlzIERhdGFIYW5kbGVyIHdhcyBjcmVhdGVkIHVzaW5nIGEgRGF0YVNvdXJjZSwKKwkgKiB0aGUgZ2V0RW5jb2RpbmcoRGF0YVNvdXJjZSkgbWV0aG9kIGlzIHR5cGljYWxseSBmYXN0ZXIuICBJZgorCSAqIHRoZSBEYXRhSGFuZGxlciB3YXMgY3JlYXRlZCB3aXRoIGFuIG9iamVjdCwgdGhpcyBtZXRob2QgaXMKKwkgKiBtdWNoIGZhc3Rlci4gIFRvIGRpc3Rpbmd1aXNoIHRoZSB0d28gY2FzZXMsIHdlIHVzZSBhIGhldXJpc3RpYy4KKwkgKiBBIERhdGFIYW5kbGVyIGNyZWF0ZWQgd2l0aCBhbiBvYmplY3Qgd2lsbCBhbHdheXMgaGF2ZSBhIG51bGwgbmFtZS4KKwkgKiBBIERhdGFIYW5kbGVyIGNyZWF0ZWQgd2l0aCBhIERhdGFTb3VyY2Ugd2lsbCB1c3VhbGx5IGhhdmUgYQorCSAqIG5vbi1udWxsIG5hbWUuCisJICoKKwkgKiBYWFggLSBUaGlzIGlzIGFjdHVhbGx5IHF1aXRlIGEgZGlzZ3VzdGluZyBoYWNrLCBidXQgaXQgbWFrZXMKKwkgKgkgYSBjb21tb24gY2FzZSBydW4gb3ZlciB0d2ljZSBhcyBmYXN0LgorCSAqLworCWlmIChkaC5nZXROYW1lKCkgIT0gbnVsbCkKKwkgICAgcmV0dXJuIGdldEVuY29kaW5nKGRoLmdldERhdGFTb3VyY2UoKSk7CisKKwl0cnkgeworCSAgICBjVHlwZSA9IG5ldyBDb250ZW50VHlwZShkaC5nZXRDb250ZW50VHlwZSgpKTsKKwl9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKwkgICAgcmV0dXJuICJiYXNlNjQiOyAvLyB3aGF0IGVsc2UgPyEKKwl9CisKKwlpZiAoY1R5cGUubWF0Y2goInRleHQvKiIpKSB7CisJICAgIC8vIENoZWNrIGFsbCBvZiB0aGUgYXZhaWxhYmxlIGJ5dGVzCisJICAgIEFzY2lpT3V0cHV0U3RyZWFtIGFvcyA9IG5ldyBBc2NpaU91dHB1dFN0cmVhbShmYWxzZSwgZmFsc2UpOworCSAgICB0cnkgeworCQlkaC53cml0ZVRvKGFvcyk7CisJICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisJICAgIAkvLyBpZ25vcmUgaXQsIGNhbid0IGhhcHBlbgorCSAgICB9CisJICAgIHN3aXRjaCAoYW9zLmdldEFzY2lpKCkpIHsKKwkgICAgY2FzZSBBTExfQVNDSUk6CisJCWVuY29kaW5nID0gIjdiaXQiOyAvLyBhbGwgYXNjaWkKKwkJYnJlYWs7CisJICAgIGNhc2UgTU9TVExZX0FTQ0lJOgorCQllbmNvZGluZyA9ICJxdW90ZWQtcHJpbnRhYmxlIjsgLy8gbW9zdGx5IGFzY2lpCisJCWJyZWFrOworCSAgICBkZWZhdWx0OgorCQllbmNvZGluZyA9ICJiYXNlNjQiOyAvLyBtb3N0bHkgYmluYXJ5CisJCWJyZWFrOworCSAgICB9CisJfSBlbHNlIHsgLy8gbm90ICJ0ZXh0IgorCSAgICAvLyBDaGVjayBhbGwgb2YgYXZhaWxhYmxlIGJ5dGVzLCBicmVhayBvdXQgaWYgd2UgZmluZAorCSAgICAvLyBhdCBsZWFzdCBvbmUgbm9uLVVTLUFTQ0lJIGNoYXJhY3RlcgorCSAgICBBc2NpaU91dHB1dFN0cmVhbSBhb3MgPQorCQkJbmV3IEFzY2lpT3V0cHV0U3RyZWFtKHRydWUsIGVuY29kZUVvbFN0cmljdCk7CisJICAgIHRyeSB7CisJCWRoLndyaXRlVG8oYW9zKTsKKwkgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsgfQkvLyBpZ25vcmUgaXQKKwkgICAgaWYgKGFvcy5nZXRBc2NpaSgpID09IEFMTF9BU0NJSSkgLy8gYWxsIGFzY2lpCisJCWVuY29kaW5nID0gIjdiaXQiOworCSAgICBlbHNlIC8vIGZvdW5kIGF0bGVhc3Qgb25lIG5vbi1hc2NpaSBjaGFyYWN0ZXIsIHVzZSBiNjQgCisJCWVuY29kaW5nID0gImJhc2U2NCI7CisJfQorCisJcmV0dXJuIGVuY29kaW5nOworICAgIH0KKworICAgIC8qKgorICAgICAqIERlY29kZSB0aGUgZ2l2ZW4gaW5wdXQgc3RyZWFtLiBUaGUgSW5wdXQgc3RyZWFtIHJldHVybmVkIGlzCisgICAgICogdGhlIGRlY29kZWQgaW5wdXQgc3RyZWFtLiBBbGwgdGhlIGVuY29kaW5ncyBkZWZpbmVkIGluIFJGQyAyMDQ1CisgICAgICogYXJlIHN1cHBvcnRlZCBoZXJlLiBUaGV5IGluY2x1ZGUgImJhc2U2NCIsICJxdW90ZWQtcHJpbnRhYmxlIiwKKyAgICAgKiAiN2JpdCIsICI4Yml0IiwgYW5kICJiaW5hcnkiLiBJbiBhZGRpdGlvbiwgInV1ZW5jb2RlIiBpcyBhbHNvCisgICAgICogc3VwcG9ydGVkLiA8cD4KKyAgICAgKgorICAgICAqIEluIHRoZSBjdXJyZW50IGltcGxlbWVudGF0aW9uLCBpZiB0aGUKKyAgICAgKiA8Y29kZT5tYWlsLm1pbWUuaWdub3JldW5rbm93bmVuY29kaW5nPC9jb2RlPiBzeXN0ZW0gcHJvcGVydHkgaXMgc2V0IHRvCisgICAgICogPGNvZGU+InRydWUiPC9jb2RlPiwgdW5rbm93biBlbmNvZGluZyB2YWx1ZXMgYXJlIGlnbm9yZWQgYW5kIHRoZQorICAgICAqIG9yaWdpbmFsIElucHV0U3RyZWFtIGlzIHJldHVybmVkLgorICAgICAqCisgICAgICogQHBhcmFtCWlzCQlpbnB1dCBzdHJlYW0KKyAgICAgKiBAcGFyYW0JZW5jb2RpbmcJdGhlIGVuY29kaW5nIG9mIHRoZSBzdHJlYW0uCisgICAgICogQHJldHVybgkJCWRlY29kZWQgaW5wdXQgc3RyZWFtLgorICAgICAqIEBleGNlcHRpb24gTWVzc2FnaW5nRXhjZXB0aW9uCWlmIHRoZSBlbmNvZGluZyBpcyB1bmtub3duCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBJbnB1dFN0cmVhbSBkZWNvZGUoSW5wdXRTdHJlYW0gaXMsIFN0cmluZyBlbmNvZGluZykKKwkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKGVuY29kaW5nLmVxdWFsc0lnbm9yZUNhc2UoImJhc2U2NCIpKQorCSAgICByZXR1cm4gbmV3IEJBU0U2NERlY29kZXJTdHJlYW0oaXMpOworCWVsc2UgaWYgKGVuY29kaW5nLmVxdWFsc0lnbm9yZUNhc2UoInF1b3RlZC1wcmludGFibGUiKSkKKwkgICAgcmV0dXJuIG5ldyBRUERlY29kZXJTdHJlYW0oaXMpOworCWVsc2UgaWYgKGVuY29kaW5nLmVxdWFsc0lnbm9yZUNhc2UoInV1ZW5jb2RlIikgfHwKKwkJIGVuY29kaW5nLmVxdWFsc0lnbm9yZUNhc2UoIngtdXVlbmNvZGUiKSB8fAorCQkgZW5jb2RpbmcuZXF1YWxzSWdub3JlQ2FzZSgieC11dWUiKSkKKwkgICAgcmV0dXJuIG5ldyBVVURlY29kZXJTdHJlYW0oaXMpOworCWVsc2UgaWYgKGVuY29kaW5nLmVxdWFsc0lnbm9yZUNhc2UoImJpbmFyeSIpIHx8CisJCSBlbmNvZGluZy5lcXVhbHNJZ25vcmVDYXNlKCI3Yml0IikgfHwKKwkJIGVuY29kaW5nLmVxdWFsc0lnbm9yZUNhc2UoIjhiaXQiKSkKKwkgICAgcmV0dXJuIGlzOworCWVsc2UgeworCSAgICBpZiAoIWlnbm9yZVVua25vd25FbmNvZGluZykKKwkJdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiVW5rbm93biBlbmNvZGluZzogIiArIGVuY29kaW5nKTsKKwkgICAgcmV0dXJuIGlzOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcmFwIGFuIGVuY29kZXIgYXJvdW5kIHRoZSBnaXZlbiBvdXRwdXQgc3RyZWFtLiAKKyAgICAgKiBBbGwgdGhlIGVuY29kaW5ncyBkZWZpbmVkIGluIFJGQyAyMDQ1IGFyZSBzdXBwb3J0ZWQgaGVyZS4gCisgICAgICogVGhleSBpbmNsdWRlICJiYXNlNjQiLCAicXVvdGVkLXByaW50YWJsZSIsICI3Yml0IiwgIjhiaXQiIGFuZAorICAgICAqICJiaW5hcnkiLiBJbiBhZGRpdGlvbiwgInV1ZW5jb2RlIiBpcyBhbHNvIHN1cHBvcnRlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbQlvcwkJb3V0cHV0IHN0cmVhbQorICAgICAqIEBwYXJhbQllbmNvZGluZwl0aGUgZW5jb2Rpbmcgb2YgdGhlIHN0cmVhbS4gCisgICAgICogQHJldHVybgkJCW91dHB1dCBzdHJlYW0gdGhhdCBhcHBsaWVzIHRoZQorICAgICAqCQkJCXNwZWNpZmllZCBlbmNvZGluZy4KKyAgICAgKiBAZXhjZXB0aW9uIE1lc3NhZ2luZ0V4Y2VwdGlvbglpZiB0aGUgZW5jb2RpbmcgaXMgdW5rbm93bgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgT3V0cHV0U3RyZWFtIGVuY29kZShPdXRwdXRTdHJlYW0gb3MsIFN0cmluZyBlbmNvZGluZykKKwkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChlbmNvZGluZyA9PSBudWxsKQorCSAgICByZXR1cm4gb3M7CisJZWxzZSBpZiAoZW5jb2RpbmcuZXF1YWxzSWdub3JlQ2FzZSgiYmFzZTY0IikpCisJICAgIHJldHVybiBuZXcgQkFTRTY0RW5jb2RlclN0cmVhbShvcyk7CisJZWxzZSBpZiAoZW5jb2RpbmcuZXF1YWxzSWdub3JlQ2FzZSgicXVvdGVkLXByaW50YWJsZSIpKQorCSAgICByZXR1cm4gbmV3IFFQRW5jb2RlclN0cmVhbShvcyk7CisJZWxzZSBpZiAoZW5jb2RpbmcuZXF1YWxzSWdub3JlQ2FzZSgidXVlbmNvZGUiKSB8fAorCQkgZW5jb2RpbmcuZXF1YWxzSWdub3JlQ2FzZSgieC11dWVuY29kZSIpIHx8CisJCSBlbmNvZGluZy5lcXVhbHNJZ25vcmVDYXNlKCJ4LXV1ZSIpKQorCSAgICByZXR1cm4gbmV3IFVVRW5jb2RlclN0cmVhbShvcyk7CisJZWxzZSBpZiAoZW5jb2RpbmcuZXF1YWxzSWdub3JlQ2FzZSgiYmluYXJ5IikgfHwKKwkJIGVuY29kaW5nLmVxdWFsc0lnbm9yZUNhc2UoIjdiaXQiKSB8fAorCQkgZW5jb2RpbmcuZXF1YWxzSWdub3JlQ2FzZSgiOGJpdCIpKQorCSAgICByZXR1cm4gb3M7CisJZWxzZQorCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKCJVbmtub3duIGVuY29kaW5nOiAiICtlbmNvZGluZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JhcCBhbiBlbmNvZGVyIGFyb3VuZCB0aGUgZ2l2ZW4gb3V0cHV0IHN0cmVhbS4KKyAgICAgKiBBbGwgdGhlIGVuY29kaW5ncyBkZWZpbmVkIGluIFJGQyAyMDQ1IGFyZSBzdXBwb3J0ZWQgaGVyZS4KKyAgICAgKiBUaGV5IGluY2x1ZGUgImJhc2U2NCIsICJxdW90ZWQtcHJpbnRhYmxlIiwgIjdiaXQiLCAiOGJpdCIgYW5kCisgICAgICogImJpbmFyeSIuIEluIGFkZGl0aW9uLCAidXVlbmNvZGUiIGlzIGFsc28gc3VwcG9ydGVkLgorICAgICAqIFRoZSA8Y29kZT5maWxlbmFtZTwvY29kZT4gcGFyYW1ldGVyIGlzIHVzZWQgd2l0aCB0aGUgInV1ZW5jb2RlIgorICAgICAqIGVuY29kaW5nIGFuZCBpcyBpbmNsdWRlZCBpbiB0aGUgZW5jb2RlZCBvdXRwdXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gICBvcyAgICAgICAgICAgICAgb3V0cHV0IHN0cmVhbQorICAgICAqIEBwYXJhbSAgIGVuY29kaW5nICAgICAgICB0aGUgZW5jb2Rpbmcgb2YgdGhlIHN0cmVhbS4KKyAgICAgKiBAcGFyYW0gICBmaWxlbmFtZSAgICAgICAgbmFtZSBmb3IgdGhlIGZpbGUgYmVpbmcgZW5jb2RlZCAob25seSB1c2VkCisgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIHdpdGggdXVlbmNvZGUpCisgICAgICogQHJldHVybiAgICAgICAgICAgICAgICAgIG91dHB1dCBzdHJlYW0gdGhhdCBhcHBsaWVzIHRoZQorICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWZpZWQgZW5jb2RpbmcuCisgICAgICogQGV4Y2VwdGlvbgkJTWVzc2FnaW5nRXhjZXB0aW9uIGZvciB1bmtub3duIGVuY29kaW5ncworICAgICAqIEBzaW5jZSAgICAgICAgICAgICAgICAgICBKYXZhTWFpbCAxLjIKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIE91dHB1dFN0cmVhbSBlbmNvZGUoT3V0cHV0U3RyZWFtIG9zLCBTdHJpbmcgZW5jb2RpbmcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBmaWxlbmFtZSkKKyAgICAgICAgICAgICAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGVuY29kaW5nID09IG51bGwpCisgICAgICAgICAgICByZXR1cm4gb3M7CisgICAgICAgIGVsc2UgaWYgKGVuY29kaW5nLmVxdWFsc0lnbm9yZUNhc2UoImJhc2U2NCIpKQorICAgICAgICAgICAgcmV0dXJuIG5ldyBCQVNFNjRFbmNvZGVyU3RyZWFtKG9zKTsKKyAgICAgICAgZWxzZSBpZiAoZW5jb2RpbmcuZXF1YWxzSWdub3JlQ2FzZSgicXVvdGVkLXByaW50YWJsZSIpKQorICAgICAgICAgICAgcmV0dXJuIG5ldyBRUEVuY29kZXJTdHJlYW0ob3MpOworICAgICAgICBlbHNlIGlmIChlbmNvZGluZy5lcXVhbHNJZ25vcmVDYXNlKCJ1dWVuY29kZSIpIHx8CisgICAgICAgICAgICAgICAgIGVuY29kaW5nLmVxdWFsc0lnbm9yZUNhc2UoIngtdXVlbmNvZGUiKSB8fAorICAgICAgICAgICAgICAgICBlbmNvZGluZy5lcXVhbHNJZ25vcmVDYXNlKCJ4LXV1ZSIpKQorICAgICAgICAgICAgcmV0dXJuIG5ldyBVVUVuY29kZXJTdHJlYW0ob3MsIGZpbGVuYW1lKTsKKyAgICAgICAgZWxzZSBpZiAoZW5jb2RpbmcuZXF1YWxzSWdub3JlQ2FzZSgiYmluYXJ5IikgfHwKKyAgICAgICAgICAgICAgICAgZW5jb2RpbmcuZXF1YWxzSWdub3JlQ2FzZSgiN2JpdCIpIHx8CisgICAgICAgICAgICAgICAgIGVuY29kaW5nLmVxdWFsc0lnbm9yZUNhc2UoIjhiaXQiKSkKKyAgICAgICAgICAgIHJldHVybiBvczsKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiVW5rbm93biBlbmNvZGluZzogIiArZW5jb2RpbmcpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVuY29kZSBhIFJGQyA4MjIgInRleHQiIHRva2VuIGludG8gbWFpbC1zYWZlIGZvcm0gYXMgcGVyCisgICAgICogUkZDIDIwNDcuIDxwPgorICAgICAqCisgICAgICogVGhlIGdpdmVuIFVuaWNvZGUgc3RyaW5nIGlzIGV4YW1pbmVkIGZvciBub24gVVMtQVNDSUkKKyAgICAgKiBjaGFyYWN0ZXJzLiBJZiB0aGUgc3RyaW5nIGNvbnRhaW5zIG9ubHkgVVMtQVNDSUkgY2hhcmFjdGVycywKKyAgICAgKiBpdCBpcyByZXR1cm5lZCBhcy1pcy4gIElmIHRoZSBzdHJpbmcgY29udGFpbnMgbm9uIFVTLUFTQ0lJCisgICAgICogY2hhcmFjdGVycywgaXQgaXMgZmlyc3QgY2hhcmFjdGVyLWVuY29kZWQgdXNpbmcgdGhlIHBsYXRmb3JtJ3MKKyAgICAgKiBkZWZhdWx0IGNoYXJzZXQsIHRoZW4gdHJhbnNmZXItZW5jb2RlZCB1c2luZyBlaXRoZXIgdGhlIEIgb3IgCisgICAgICogUSBlbmNvZGluZy4gVGhlIHJlc3VsdGluZyBieXRlcyBhcmUgdGhlbiByZXR1cm5lZCBhcyBhIFVuaWNvZGUgCisgICAgICogc3RyaW5nIGNvbnRhaW5pbmcgb25seSBBU0NJSSAgY2hhcmFjdGVycy4gPHA+CisgICAgICoKKyAgICAgKiBOb3RlIHRoYXQgdGhpcyBtZXRob2Qgc2hvdWxkIGJlIHVzZWQgdG8gZW5jb2RlIG9ubHkgCisgICAgICogInVuc3RydWN0dXJlZCIgUkZDIDgyMiBoZWFkZXJzLiA8cD4KKyAgICAgKgorICAgICAqIEV4YW1wbGUgb2YgdXNhZ2U6CisgICAgICogPGJsb2NrcXVvdGU+PHByZT4KKyAgICAgKgorICAgICAqICBNaW1lUGFydCBwYXJ0ID0gLi4uCisgICAgICogIFN0cmluZyByYXd2YWx1ZSA9ICJGb29CYXIgTWFpbGVyLCBKYXBhbmVzZSB2ZXJzaW9uIDEuMSIKKyAgICAgKiAgdHJ5IHsKKyAgICAgKiAgICAvLyBJZiB3ZSBrbm93IGZvciBzdXJlIHRoYXQgcmF3dmFsdWUgY29udGFpbnMgb25seSBVUy1BU0NJSSAKKyAgICAgKiAgICAvLyBjaGFyYWN0ZXJzLCB3ZSBjYW4gc2tpcCB0aGUgZW5jb2RpbmcgcGFydAorICAgICAqICAgIHBhcnQuc2V0SGVhZGVyKCJYLW1haWxlciIsIE1pbWVVdGlsaXR5LmVuY29kZVRleHQocmF3dmFsdWUpKTsKKyAgICAgKiAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICogICAgLy8gZW5jb2RpbmcgZmFpbHVyZQorICAgICAqICB9IGNhdGNoIChNZXNzYWdpbmdFeGNlcHRpb24gbWUpIHsKKyAgICAgKiAgIC8vIHNldEhlYWRlcigpIGZhaWx1cmUKKyAgICAgKiAgfQorICAgICAqCisgICAgICogPC9wcmU+PC9ibG9ja3F1b3RlPjxwPgorICAgICAqIAorICAgICAqIEBwYXJhbQl0ZXh0CVVuaWNvZGUgc3RyaW5nCisgICAgICogQHJldHVybglVbmljb2RlIHN0cmluZyBjb250YWluaW5nIG9ubHkgVVMtQVNDSUkgY2hhcmFjdGVycworICAgICAqIEBleGNlcHRpb24gVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBpZiB0aGUgZW5jb2RpbmcgZmFpbHMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBlbmNvZGVUZXh0KFN0cmluZyB0ZXh0KQorCQkJdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24geworCXJldHVybiBlbmNvZGVUZXh0KHRleHQsIG51bGwsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVuY29kZSBhIFJGQyA4MjIgInRleHQiIHRva2VuIGludG8gbWFpbC1zYWZlIGZvcm0gYXMgcGVyCisgICAgICogUkZDIDIwNDcuIDxwPgorICAgICAqCisgICAgICogVGhlIGdpdmVuIFVuaWNvZGUgc3RyaW5nIGlzIGV4YW1pbmVkIGZvciBub24gVVMtQVNDSUkKKyAgICAgKiBjaGFyYWN0ZXJzLiBJZiB0aGUgc3RyaW5nIGNvbnRhaW5zIG9ubHkgVVMtQVNDSUkgY2hhcmFjdGVycywKKyAgICAgKiBpdCBpcyByZXR1cm5lZCBhcy1pcy4gIElmIHRoZSBzdHJpbmcgY29udGFpbnMgbm9uIFVTLUFTQ0lJCisgICAgICogY2hhcmFjdGVycywgaXQgaXMgZmlyc3QgY2hhcmFjdGVyLWVuY29kZWQgdXNpbmcgdGhlIHNwZWNpZmllZAorICAgICAqIGNoYXJzZXQsIHRoZW4gdHJhbnNmZXItZW5jb2RlZCB1c2luZyBlaXRoZXIgdGhlIEIgb3IgUSBlbmNvZGluZy4KKyAgICAgKiBUaGUgcmVzdWx0aW5nIGJ5dGVzIGFyZSB0aGVuIHJldHVybmVkIGFzIGEgVW5pY29kZSBzdHJpbmcgCisgICAgICogY29udGFpbmluZyBvbmx5IEFTQ0lJIGNoYXJhY3RlcnMuIDxwPgorICAgICAqCisgICAgICogTm90ZSB0aGF0IHRoaXMgbWV0aG9kIHNob3VsZCBiZSB1c2VkIHRvIGVuY29kZSBvbmx5IAorICAgICAqICJ1bnN0cnVjdHVyZWQiIFJGQyA4MjIgaGVhZGVycy4gCisgICAgICogCisgICAgICogQHBhcmFtCXRleHQJdGhlIGhlYWRlciB2YWx1ZQorICAgICAqIEBwYXJhbQljaGFyc2V0CXRoZSBjaGFyc2V0LiBJZiB0aGlzIHBhcmFtZXRlciBpcyBudWxsLCB0aGUKKyAgICAgKgkJcGxhdGZvcm0ncyBkZWZhdWx0IGNoYXRzZXQgaXMgdXNlZC4KKyAgICAgKiBAcGFyYW0JZW5jb2RpbmcgdGhlIGVuY29kaW5nIHRvIGJlIHVzZWQuIEN1cnJlbnRseSBzdXBwb3J0ZWQKKyAgICAgKgkJdmFsdWVzIGFyZSAiQiIgYW5kICJRIi4gSWYgdGhpcyBwYXJhbWV0ZXIgaXMgbnVsbCwgdGhlbgorICAgICAqCQl0aGUgIlEiIGVuY29kaW5nIGlzIHVzZWQgaWYgbW9zdCBvZiBjaGFyYWN0ZXJzIHRvIGJlCisgICAgICoJCWVuY29kZWQgYXJlIGluIHRoZSBBU0NJSSBjaGFyc2V0LCBvdGhlcndpc2UgIkIiIGVuY29kaW5nCisgICAgICoJCWlzIHVzZWQuCisgICAgICogQHJldHVybglVbmljb2RlIHN0cmluZyBjb250YWluaW5nIG9ubHkgVVMtQVNDSUkgY2hhcmFjdGVycworICAgICAqIEBleGNlcHRpb24gICAgICAgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBpZiB0aGUgY2hhcnNldAorICAgICAqCQkJY29udmVyc2lvbiBmYWlsZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZW5jb2RlVGV4dChTdHJpbmcgdGV4dCwgU3RyaW5nIGNoYXJzZXQsCisJCQkJICAgIFN0cmluZyBlbmNvZGluZykKKwkJCXRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gZW5jb2RlV29yZCh0ZXh0LCBjaGFyc2V0LCBlbmNvZGluZywgZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIERlY29kZSAidW5zdHJ1Y3R1cmVkIiBoZWFkZXJzLCB0aGF0IGlzLCBoZWFkZXJzIHRoYXQgYXJlIGRlZmluZWQKKyAgICAgKiBhcyAnKnRleHQnIGFzIHBlciBSRkMgODIyLiA8cD4KKyAgICAgKgorICAgICAqIFRoZSBzdHJpbmcgaXMgZGVjb2RlZCB1c2luZyB0aGUgYWxnb3JpdGhtIHNwZWNpZmllZCBpbgorICAgICAqIFJGQyAyMDQ3LCBTZWN0aW9uIDYuMS4gSWYgdGhlIGNoYXJzZXQtY29udmVyc2lvbiBmYWlscworICAgICAqIGZvciBhbnkgc2VxdWVuY2UsIGFuIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gaXMgdGhyb3duLgorICAgICAqIElmIHRoZSBTdHJpbmcgaXMgbm90IGFuIFJGQyAyMDQ3IHN0eWxlIGVuY29kZWQgaGVhZGVyLCBpdCBpcworICAgICAqIHJldHVybmVkIGFzLWlzIDxwPgorICAgICAqCisgICAgICogRXhhbXBsZSBvZiB1c2FnZToKKyAgICAgKiA8YmxvY2txdW90ZT48cHJlPgorICAgICAqCisgICAgICogIE1pbWVQYXJ0IHBhcnQgPSAuLi4KKyAgICAgKiAgU3RyaW5nIHJhd3ZhbHVlID0gbnVsbDsKKyAgICAgKiAgU3RyaW5nICB2YWx1ZSA9IG51bGw7CisgICAgICogIHRyeSB7CisgICAgICogICAgaWYgKChyYXd2YWx1ZSA9IHBhcnQuZ2V0SGVhZGVyKCJYLW1haWxlciIpWzBdKSAhPSBudWxsKQorICAgICAqICAgICAgdmFsdWUgPSBNaW1lVXRpbGl0eS5kZWNvZGVUZXh0KHJhd3ZhbHVlKTsKKyAgICAgKiAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICogICAgICAvLyBEb24ndCBjYXJlCisgICAgICogICAgICB2YWx1ZSA9IHJhd3ZhbHVlOworICAgICAqICB9IGNhdGNoIChNZXNzYWdpbmdFeGNlcHRpb24gbWUpIHsgfQorICAgICAqCisgICAgICogIHJldHVybiB2YWx1ZTsKKyAgICAgKgorICAgICAqIDwvcHJlPjwvYmxvY2txdW90ZT48cD4KKyAgICAgKgorICAgICAqIEBwYXJhbQlldGV4dAl0aGUgcG9zc2libHkgZW5jb2RlZCB2YWx1ZQorICAgICAqIEByZXR1cm4JdGhlIGRlY29kZWQgdGV4dAorICAgICAqIEBleGNlcHRpb24gICAgICAgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBpZiB0aGUgY2hhcnNldAorICAgICAqCQkJY29udmVyc2lvbiBmYWlsZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZGVjb2RlVGV4dChTdHJpbmcgZXRleHQpCisJCXRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIHsKKwkvKgorCSAqIFdlIGxvb2sgZm9yIHNlcXVlbmNlcyBzZXBhcmF0ZWQgYnkgImxpbmVhci13aGl0ZS1zcGFjZSIuCisJICogKGFzIHBlciBSRkMgMjA0NywgU2VjdGlvbiA2LjEpCisJICogUkZDIDgyMiBkZWZpbmVzICJsaW5lYXItd2hpdGUtc3BhY2UiIGFzIFNQQUNFIHwgSFQgfCBDUiB8IE5MLgorCSAqLworCVN0cmluZyBsd3NwID0gIiBcdFxuXHIiOworCVN0cmluZ1Rva2VuaXplciBzdDsKKworCS8qCisJICogRmlyc3QsIGxldHMgZG8gYSBxdWljayBydW4gdGhydSB0aGUgc3RyaW5nIGFuZCBjaGVjaworCSAqIHdoZXRoZXIgdGhlIHNlcXVlbmNlICI9PyIgIGV4aXN0cyBhdCBhbGwuIElmIG5vbmUgZXhpc3RzLAorCSAqIHdlIGtub3cgdGhlcmUgYXJlIG5vIGVuY29kZWQtd29yZHMgaW4gaGVyZSBhbmQgd2UgY2FuIGp1c3QKKwkgKiByZXR1cm4gdGhlIHN0cmluZyBhcy1pcywgd2l0aG91dCBzdWZmZXJpbmcgdGhydSB0aGUgbGF0ZXIgCisJICogZGVjb2RpbmcgbG9naWMuIAorCSAqIFRoaXMgaGFuZGxlcyB0aGUgbW9zdCBjb21tb24gY2FzZSBvZiB1bmVuY29kZWQgaGVhZGVycyAKKwkgKiBlZmZpY2llbnRseS4KKwkgKi8KKwlpZiAoZXRleHQuaW5kZXhPZigiPT8iKSA9PSAtMSkKKwkgICAgcmV0dXJuIGV0ZXh0OworCisJLy8gRW5jb2RlZCB3b3JkcyBmb3VuZC4gU3RhcnQgZGVjb2RpbmcgLi4uCisKKwlzdCA9IG5ldyBTdHJpbmdUb2tlbml6ZXIoZXRleHQsIGx3c3AsIHRydWUpOworCVN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOyAgLy8gZGVjb2RlIGJ1ZmZlcgorCVN0cmluZ0J1aWxkZXIgd3NiID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsgLy8gd2hpdGUgc3BhY2UgYnVmZmVyCisJYm9vbGVhbiBwcmV2V2FzRW5jb2RlZCA9IGZhbHNlOworCisJd2hpbGUgKHN0Lmhhc01vcmVUb2tlbnMoKSkgeworCSAgICBjaGFyIGM7CisJICAgIFN0cmluZyBzID0gc3QubmV4dFRva2VuKCk7CisJICAgIC8vIElmIHdoaXRlc3BhY2UsIGFwcGVuZCBpdCB0byB0aGUgd2hpdGVzcGFjZSBidWZmZXIKKwkgICAgaWYgKCgoYyA9IHMuY2hhckF0KDApKSA9PSAnICcpIHx8IChjID09ICdcdCcpIHx8CisJCShjID09ICdccicpIHx8IChjID09ICdcbicpKQorCQl3c2IuYXBwZW5kKGMpOworCSAgICBlbHNlIHsKKwkJLy8gQ2hlY2sgaWYgdG9rZW4gaXMgYW4gJ2VuY29kZWQtd29yZCcgLi4KKwkJU3RyaW5nIHdvcmQ7CisJCXRyeSB7CisJCSAgICB3b3JkID0gZGVjb2RlV29yZChzKTsKKwkJICAgIC8vIFllcywgdGhpcyBJUyBhbiAnZW5jb2RlZC13b3JkJy4KKwkJICAgIGlmICghcHJldldhc0VuY29kZWQgJiYgd3NiLmxlbmd0aCgpID4gMCkgeworCQkJLy8gaWYgdGhlIHByZXZpb3VzIHdvcmQgd2FzIGFsc28gZW5jb2RlZCwgd2UKKwkJCS8vIHNob3VsZCBpZ25vcmUgdGhlIGNvbGxlY3RlZCB3aGl0ZXNwYWNlLiBFbHNlCisJCQkvLyB3ZSBpbmNsdWRlIHRoZSB3aGl0ZXNwYWNlIGFzIHdlbGwuCisJCQlzYi5hcHBlbmQod3NiKTsKKwkJICAgIH0KKwkJICAgIHByZXZXYXNFbmNvZGVkID0gdHJ1ZTsKKwkJfSBjYXRjaCAoUGFyc2VFeGNlcHRpb24gcGV4KSB7CisJCSAgICAvLyBUaGlzIGlzIE5PVCBhbiAnZW5jb2RlZC13b3JkJy4KKwkJICAgIHdvcmQgPSBzOworCQkgICAgLy8gcG9zc2libHkgZGVjb2RlIGlubmVyIGVuY29kZWQgd29yZHMKKwkJICAgIGlmICghZGVjb2RlU3RyaWN0KSB7CisJCQlTdHJpbmcgZHdvcmQgPSBkZWNvZGVJbm5lcldvcmRzKHdvcmQpOworCQkJaWYgKGR3b3JkICE9IHdvcmQpIHsKKwkJCSAgICAvLyBpZiBhIGRpZmZlcmVudCBTdHJpbmcgb2JqZWN0IHdhcyByZXR1cm5lZCwKKwkJCSAgICAvLyBkZWNvZGluZyB3YXMgZG9uZS4KKwkJCSAgICBpZiAocHJldldhc0VuY29kZWQgJiYgd29yZC5zdGFydHNXaXRoKCI9PyIpKSB7CisJCQkJLy8gZW5jb2RlZCBmb2xsb3dlZCBieSBlbmNvZGVkLAorCQkJCS8vIHRocm93IGF3YXkgd2hpdGVzcGFjZSBiZXR3ZWVuCisJCQkgICAgfSBlbHNlIHsKKwkJCQkvLyBpbmNsdWRlIGNvbGxlY3RlZCB3aGl0ZXNwYWNlIC4uCisJCQkJaWYgKHdzYi5sZW5ndGgoKSA+IDApCisJCQkJICAgIHNiLmFwcGVuZCh3c2IpOworCQkJICAgIH0KKwkJCSAgICAvLyBkaWQgb3JpZ2luYWwgZW5kIHdpdGggZW5jb2RlZD8KKwkJCSAgICBwcmV2V2FzRW5jb2RlZCA9IHdvcmQuZW5kc1dpdGgoIj89Iik7CisJCQkgICAgd29yZCA9IGR3b3JkOworCQkJfSBlbHNlIHsKKwkJCSAgICAvLyBpbmNsdWRlIGNvbGxlY3RlZCB3aGl0ZXNwYWNlIC4uCisJCQkgICAgaWYgKHdzYi5sZW5ndGgoKSA+IDApCisJCQkJc2IuYXBwZW5kKHdzYik7CisJCQkgICAgcHJldldhc0VuY29kZWQgPSBmYWxzZTsKKwkJCX0KKwkJICAgIH0gZWxzZSB7CisJCQkvLyBpbmNsdWRlIGNvbGxlY3RlZCB3aGl0ZXNwYWNlIC4uCisJCQlpZiAod3NiLmxlbmd0aCgpID4gMCkKKwkJCSAgICBzYi5hcHBlbmQod3NiKTsKKwkJCXByZXZXYXNFbmNvZGVkID0gZmFsc2U7CisJCSAgICB9CisJCX0KKwkJc2IuYXBwZW5kKHdvcmQpOyAvLyBhcHBlbmQgdGhlIGFjdHVhbCB3b3JkCisJCXdzYi5zZXRMZW5ndGgoMCk7IC8vIHJlc2V0IHdzYiBmb3IgcmV1c2UKKwkgICAgfQorCX0KKwlzYi5hcHBlbmQod3NiKTsJCS8vIGFwcGVuZCB0cmFpbGluZyB3aGl0ZXNwYWNlCisJcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRW5jb2RlIGEgUkZDIDgyMiAid29yZCIgdG9rZW4gaW50byBtYWlsLXNhZmUgZm9ybSBhcyBwZXIKKyAgICAgKiBSRkMgMjA0Ny4gPHA+CisgICAgICoKKyAgICAgKiBUaGUgZ2l2ZW4gVW5pY29kZSBzdHJpbmcgaXMgZXhhbWluZWQgZm9yIG5vbiBVUy1BU0NJSQorICAgICAqIGNoYXJhY3RlcnMuIElmIHRoZSBzdHJpbmcgY29udGFpbnMgb25seSBVUy1BU0NJSSBjaGFyYWN0ZXJzLAorICAgICAqIGl0IGlzIHJldHVybmVkIGFzLWlzLiAgSWYgdGhlIHN0cmluZyBjb250YWlucyBub24gVVMtQVNDSUkKKyAgICAgKiBjaGFyYWN0ZXJzLCBpdCBpcyBmaXJzdCBjaGFyYWN0ZXItZW5jb2RlZCB1c2luZyB0aGUgcGxhdGZvcm0ncworICAgICAqIGRlZmF1bHQgY2hhcnNldCwgdGhlbiB0cmFuc2Zlci1lbmNvZGVkIHVzaW5nIGVpdGhlciB0aGUgQiBvciAKKyAgICAgKiBRIGVuY29kaW5nLiBUaGUgcmVzdWx0aW5nIGJ5dGVzIGFyZSB0aGVuIHJldHVybmVkIGFzIGEgVW5pY29kZSAKKyAgICAgKiBzdHJpbmcgY29udGFpbmluZyBvbmx5IEFTQ0lJICBjaGFyYWN0ZXJzLiA8cD4KKyAgICAgKiAKKyAgICAgKiBUaGlzIG1ldGhvZCBpcyBtZWFudCB0byBiZSB1c2VkIHdoZW4gY3JlYXRpbmcgUkZDIDgyMiAicGhyYXNlcyIuCisgICAgICogVGhlIEludGVybmV0QWRkcmVzcyBjbGFzcywgZm9yIGV4YW1wbGUsIHVzZXMgdGhpcyB0byBlbmNvZGUKKyAgICAgKiBpdCdzICdwaHJhc2UnIGNvbXBvbmVudC4KKyAgICAgKgorICAgICAqIEBwYXJhbQl3b3JkCVVuaWNvZGUgc3RyaW5nCisgICAgICogQHJldHVybglBcnJheSBvZiBVbmljb2RlIHN0cmluZ3MgY29udGFpbmluZyBvbmx5IFVTLUFTQ0lJIAorICAgICAqCQljaGFyYWN0ZXJzLgorICAgICAqIEBleGNlcHRpb24gVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBpZiB0aGUgZW5jb2RpbmcgZmFpbHMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBlbmNvZGVXb3JkKFN0cmluZyB3b3JkKSAKKwkJCXRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gZW5jb2RlV29yZCh3b3JkLCBudWxsLCBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFbmNvZGUgYSBSRkMgODIyICJ3b3JkIiB0b2tlbiBpbnRvIG1haWwtc2FmZSBmb3JtIGFzIHBlcgorICAgICAqIFJGQyAyMDQ3LiA8cD4KKyAgICAgKgorICAgICAqIFRoZSBnaXZlbiBVbmljb2RlIHN0cmluZyBpcyBleGFtaW5lZCBmb3Igbm9uIFVTLUFTQ0lJCisgICAgICogY2hhcmFjdGVycy4gSWYgdGhlIHN0cmluZyBjb250YWlucyBvbmx5IFVTLUFTQ0lJIGNoYXJhY3RlcnMsCisgICAgICogaXQgaXMgcmV0dXJuZWQgYXMtaXMuICBJZiB0aGUgc3RyaW5nIGNvbnRhaW5zIG5vbiBVUy1BU0NJSQorICAgICAqIGNoYXJhY3RlcnMsIGl0IGlzIGZpcnN0IGNoYXJhY3Rlci1lbmNvZGVkIHVzaW5nIHRoZSBzcGVjaWZpZWQKKyAgICAgKiBjaGFyc2V0LCB0aGVuIHRyYW5zZmVyLWVuY29kZWQgdXNpbmcgZWl0aGVyIHRoZSBCIG9yIFEgZW5jb2RpbmcuCisgICAgICogVGhlIHJlc3VsdGluZyBieXRlcyBhcmUgdGhlbiByZXR1cm5lZCBhcyBhIFVuaWNvZGUgc3RyaW5nIAorICAgICAqIGNvbnRhaW5pbmcgb25seSBBU0NJSSBjaGFyYWN0ZXJzLiA8cD4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0Jd29yZAlVbmljb2RlIHN0cmluZworICAgICAqIEBwYXJhbQljaGFyc2V0CXRoZSBNSU1FIGNoYXJzZXQKKyAgICAgKiBAcGFyYW0JZW5jb2RpbmcgdGhlIGVuY29kaW5nIHRvIGJlIHVzZWQuIEN1cnJlbnRseSBzdXBwb3J0ZWQKKyAgICAgKgkJdmFsdWVzIGFyZSAiQiIgYW5kICJRIi4gSWYgdGhpcyBwYXJhbWV0ZXIgaXMgbnVsbCwgdGhlbgorICAgICAqCQl0aGUgIlEiIGVuY29kaW5nIGlzIHVzZWQgaWYgbW9zdCBvZiBjaGFyYWN0ZXJzIHRvIGJlCisgICAgICoJCWVuY29kZWQgYXJlIGluIHRoZSBBU0NJSSBjaGFyc2V0LCBvdGhlcndpc2UgIkIiIGVuY29kaW5nCisgICAgICoJCWlzIHVzZWQuCisgICAgICogQHJldHVybglVbmljb2RlIHN0cmluZyBjb250YWluaW5nIG9ubHkgVVMtQVNDSUkgY2hhcmFjdGVycworICAgICAqIEBleGNlcHRpb24gVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBpZiB0aGUgZW5jb2RpbmcgZmFpbHMKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBlbmNvZGVXb3JkKFN0cmluZyB3b3JkLCBTdHJpbmcgY2hhcnNldCwgCisJCQkJICAgIFN0cmluZyBlbmNvZGluZykKKyAgICAJCQl0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiB7CisJcmV0dXJuIGVuY29kZVdvcmQod29yZCwgY2hhcnNldCwgZW5jb2RpbmcsIHRydWUpOworICAgIH0KKworICAgIC8qCisgICAgICogRW5jb2RlIHRoZSBnaXZlbiBzdHJpbmcuIFRoZSBwYXJhbWV0ZXIgJ2VuY29kaW5nV29yZCcgc2hvdWxkCisgICAgICogYmUgdHJ1ZSBpZiBhIFJGQyA4MjIgIndvcmQiIHRva2VuIGlzIGJlaW5nIGVuY29kZWQgYW5kIGZhbHNlIGlmIGEKKyAgICAgKiBSRkMgODIyICJ0ZXh0IiB0b2tlbiBpcyBiZWluZyBlbmNvZGVkLiBUaGlzIGlzIGJlY2F1c2UgdGhlIAorICAgICAqICJRIiBlbmNvZGluZyBkZWZpbmVkIGluIFJGQyAyMDQ3IGhhcyBtb3JlIHJlc3RyaWN0aW9ucyB3aGVuCisgICAgICogZW5jb2RpbmcgIndvcmQiIHRva2Vucy4gKFNpZ2gpCisgICAgICovIAorICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBlbmNvZGVXb3JkKFN0cmluZyBzdHJpbmcsIFN0cmluZyBjaGFyc2V0LAorCQkJCSAgICAgU3RyaW5nIGVuY29kaW5nLCBib29sZWFuIGVuY29kaW5nV29yZCkKKwkJCXRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIHsKKworCS8vIElmICdzdHJpbmcnIGNvbnRhaW5zIG9ubHkgVVMtQVNDSUkgY2hhcmFjdGVycywganVzdAorCS8vIHJldHVybiBpdC4KKwlpbnQgYXNjaWkgPSBjaGVja0FzY2lpKHN0cmluZyk7CisJaWYgKGFzY2lpID09IEFMTF9BU0NJSSkKKwkgICAgcmV0dXJuIHN0cmluZzsKKworCS8vIEVsc2UsIGFwcGx5IHRoZSBzcGVjaWZpZWQgY2hhcnNldCBjb252ZXJzaW9uLgorCVN0cmluZyBqY2hhcnNldDsKKwlpZiAoY2hhcnNldCA9PSBudWxsKSB7IC8vIHVzZSBkZWZhdWx0IGNoYXJzZXQKKwkgICAgamNoYXJzZXQgPSBnZXREZWZhdWx0SmF2YUNoYXJzZXQoKTsgLy8gdGhlIGphdmEgY2hhcnNldAorCSAgICBjaGFyc2V0ID0gZ2V0RGVmYXVsdE1JTUVDaGFyc2V0KCk7IC8vIHRoZSBNSU1FIGVxdWl2YWxlbnQKKwl9IGVsc2UgLy8gTUlNRSBjaGFyc2V0IC0+IGphdmEgY2hhcnNldAorCSAgICBqY2hhcnNldCA9IGphdmFDaGFyc2V0KGNoYXJzZXQpOworCisJLy8gSWYgbm8gdHJhbnNmZXItZW5jb2RpbmcgaXMgc3BlY2lmaWVkLCBmaWd1cmUgb25lIG91dC4KKwlpZiAoZW5jb2RpbmcgPT0gbnVsbCkgeworCSAgICBpZiAoYXNjaWkgIT0gTU9TVExZX05PTkFTQ0lJKQorCQllbmNvZGluZyA9ICJRIjsKKwkgICAgZWxzZQorCQllbmNvZGluZyA9ICJCIjsKKwl9CisKKwlib29sZWFuIGI2NDsKKwlpZiAoZW5jb2RpbmcuZXF1YWxzSWdub3JlQ2FzZSgiQiIpKSAKKwkgICAgYjY0ID0gdHJ1ZTsKKwllbHNlIGlmIChlbmNvZGluZy5lcXVhbHNJZ25vcmVDYXNlKCJRIikpCisJICAgIGI2NCA9IGZhbHNlOworCWVsc2UKKwkgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24oCisJCQkiVW5rbm93biB0cmFuc2ZlciBlbmNvZGluZzogIiArIGVuY29kaW5nKTsKKworCVN0cmluZ0J1aWxkZXIgb3V0YiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7IC8vIHRoZSBvdXRwdXQgYnVmZmVyCisJZG9FbmNvZGUoc3RyaW5nLCBiNjQsIGpjaGFyc2V0LCAKKwkJIC8vIEFzIHBlciBSRkMgMjA0Nywgc2l6ZSBvZiBhbiBlbmNvZGVkIHN0cmluZyBzaG91bGQgbm90CisJCSAvLyBleGNlZWQgNzUgYnl0ZXMuCisJCSAvLyA3ID0gc2l6ZSBvZiAiPT8iLCAnPycsICdCJy8nUScsICc/JywgIj89IgorCQkgNzUgLSA3IC0gY2hhcnNldC5sZW5ndGgoKSwgLy8gdGhlIGF2YWlsYWJsZSBzcGFjZQorCQkgIj0/IiArIGNoYXJzZXQgKyAiPyIgKyBlbmNvZGluZyArICI/IiwgLy8gcHJlZml4CisJCSB0cnVlLCBlbmNvZGluZ1dvcmQsIG91dGIpOworCisJcmV0dXJuIG91dGIudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGRvRW5jb2RlKFN0cmluZyBzdHJpbmcsIGJvb2xlYW4gYjY0LCAKKwkJU3RyaW5nIGpjaGFyc2V0LCBpbnQgYXZhaWwsIFN0cmluZyBwcmVmaXgsIAorCQlib29sZWFuIGZpcnN0LCBib29sZWFuIGVuY29kaW5nV29yZCwgU3RyaW5nQnVpbGRlciBidWYpCisJCQl0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiB7CisKKwkvLyBGaXJzdCBmaW5kIG91dCB3aGF0IHRoZSBsZW5ndGggb2YgdGhlIGVuY29kZWQgdmVyc2lvbiBvZgorCS8vICdzdHJpbmcnIHdvdWxkIGJlLgorCWJ5dGVbXSBieXRlcyA9IHN0cmluZy5nZXRCeXRlcyhqY2hhcnNldCk7CisJaW50IGxlbjsKKwlpZiAoYjY0KSAvLyAiQiIgZW5jb2RpbmcKKwkgICAgbGVuID0gQkVuY29kZXJTdHJlYW0uZW5jb2RlZExlbmd0aChieXRlcyk7CisJZWxzZSAvLyAiUSIKKwkgICAgbGVuID0gUUVuY29kZXJTdHJlYW0uZW5jb2RlZExlbmd0aChieXRlcywgZW5jb2RpbmdXb3JkKTsKKwkKKwlpbnQgc2l6ZTsKKwlpZiAoKGxlbiA+IGF2YWlsKSAmJiAoKHNpemUgPSBzdHJpbmcubGVuZ3RoKCkpID4gMSkpIHsgCisJICAgIC8vIElmIHRoZSBsZW5ndGggaXMgZ3JlYXRlciB0aGFuICdhdmFpbCcsIHNwbGl0ICdzdHJpbmcnCisJICAgIC8vIGludG8gdHdvIGFuZCByZWN1cnNlLgorCSAgICAvLyBIYXZlIHRvIG1ha2Ugc3VyZSBub3QgdG8gc3BsaXQgYSBVbmljb2RlIHN1cnJvZ2F0ZSBwYWlyLgorCSAgICBpbnQgc3BsaXQgPSBzaXplIC8gMjsKKwkgICAgaWYgKENoYXJhY3Rlci5pc0hpZ2hTdXJyb2dhdGUoc3RyaW5nLmNoYXJBdChzcGxpdC0xKSkpCisJCXNwbGl0LS07CisJICAgIGlmIChzcGxpdCA+IDApCisJCWRvRW5jb2RlKHN0cmluZy5zdWJzdHJpbmcoMCwgc3BsaXQpLCBiNjQsIGpjaGFyc2V0LCAKKwkJCSBhdmFpbCwgcHJlZml4LCBmaXJzdCwgZW5jb2RpbmdXb3JkLCBidWYpOworCSAgICBkb0VuY29kZShzdHJpbmcuc3Vic3RyaW5nKHNwbGl0LCBzaXplKSwgYjY0LCBqY2hhcnNldCwKKwkJICAgICBhdmFpbCwgcHJlZml4LCBmYWxzZSwgZW5jb2RpbmdXb3JkLCBidWYpOworCX0gZWxzZSB7CisJICAgIC8vIGxlbmd0aCA8PSB0aGFuICdhdmFpbCcuIEVuY29kZSB0aGUgZ2l2ZW4gc3RyaW5nCisJICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKwkgICAgT3V0cHV0U3RyZWFtIGVvczsgLy8gdGhlIGVuY29kZXIKKwkgICAgaWYgKGI2NCkgLy8gIkIiIGVuY29kaW5nCisJCWVvcyA9IG5ldyBCRW5jb2RlclN0cmVhbShvcyk7CisJICAgIGVsc2UgLy8gIlEiIGVuY29kaW5nCisJCWVvcyA9IG5ldyBRRW5jb2RlclN0cmVhbShvcywgZW5jb2RpbmdXb3JkKTsKKwkgICAgCisJICAgIHRyeSB7IC8vIGRvIHRoZSBlbmNvZGluZworCQllb3Mud3JpdGUoYnl0ZXMpOworCQllb3MuY2xvc2UoKTsKKwkgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9leCkgeyB9CisKKwkgICAgYnl0ZVtdIGVuY29kZWRCeXRlcyA9IG9zLnRvQnl0ZUFycmF5KCk7IC8vIHRoZSBlbmNvZGVkIHN0dWZmCisJICAgIC8vIE5vdyB3cml0ZSBvdXQgdGhlIGVuY29kZWQgKGFsbCBBU0NJSSkgYnl0ZXMgaW50byBvdXIKKwkgICAgLy8gU3RyaW5nQnVpbGRlcgorCSAgICBpZiAoIWZpcnN0KSAvLyBub3QgdGhlIGZpcnN0IGxpbmUgb2YgdGhpcyBzZXF1ZW5jZQorCQlpZiAoZm9sZEVuY29kZWRXb3JkcykKKwkJICAgIGJ1Zi5hcHBlbmQoIlxyXG4gIik7IC8vIHN0YXJ0IGEgY29udGludWF0aW9uIGxpbmUKKwkJZWxzZQorCQkgICAgYnVmLmFwcGVuZCgiICIpOyAvLyBsaW5lIHdpbGwgYmUgZm9sZGVkIGxhdGVyCisKKwkgICAgYnVmLmFwcGVuZChwcmVmaXgpOworCSAgICBmb3IgKGludCBpID0gMDsgaSA8IGVuY29kZWRCeXRlcy5sZW5ndGg7IGkrKykKKwkJYnVmLmFwcGVuZCgoY2hhcillbmNvZGVkQnl0ZXNbaV0pOworCSAgICBidWYuYXBwZW5kKCI/PSIpOyAvLyB0ZXJtaW5hdGUgdGhlIGN1cnJlbnQgc2VxdWVuY2UKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIHN0cmluZyBpcyBwYXJzZWQgdXNpbmcgdGhlIHJ1bGVzIGluIFJGQyAyMDQ3IGFuZCBSRkMgMjIzMSBmb3IKKyAgICAgKiBwYXJzaW5nIGFuICJlbmNvZGVkLXdvcmQiLiAgSWYgdGhlIHBhcnNlIGZhaWxzLCBhIFBhcnNlRXhjZXB0aW9uIGlzIAorICAgICAqIHRocm93bi4gT3RoZXJ3aXNlLCBpdCBpcyB0cmFuc2Zlci1kZWNvZGVkLCBhbmQgdGhlbiAKKyAgICAgKiBjaGFyc2V0LWNvbnZlcnRlZCBpbnRvIFVuaWNvZGUuIElmIHRoZSBjaGFyc2V0LWNvbnZlcnNpb24KKyAgICAgKiBmYWlscywgYW4gVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBpcyB0aHJvd24uPHA+CisgICAgICoKKyAgICAgKiBAcGFyYW0JZXdvcmQJdGhlIGVuY29kZWQgdmFsdWUKKyAgICAgKiBAcmV0dXJuCXRoZSBkZWNvZGVkIHdvcmQKKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIFBhcnNlRXhjZXB0aW9uIGlmIHRoZSBzdHJpbmcgaXMgbm90IGFuCisgICAgICoJCQllbmNvZGVkLXdvcmQgYXMgcGVyIFJGQyAyMDQ3IGFuZCBSRkMgMjIzMS4KKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gaWYgdGhlIGNoYXJzZXQKKyAgICAgKgkJCWNvbnZlcnNpb24gZmFpbGVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGRlY29kZVdvcmQoU3RyaW5nIGV3b3JkKQorCQl0aHJvd3MgUGFyc2VFeGNlcHRpb24sIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24geworCisJaWYgKCFld29yZC5zdGFydHNXaXRoKCI9PyIpKSAvLyBub3QgYW4gZW5jb2RlZCB3b3JkCisJICAgIHRocm93IG5ldyBQYXJzZUV4Y2VwdGlvbigKKwkJImVuY29kZWQgd29yZCBkb2VzIG5vdCBzdGFydCB3aXRoIFwiPT9cIjogIiArIGV3b3JkKTsKKwkKKwkvLyBnZXQgY2hhcnNldAorCWludCBzdGFydCA9IDI7IGludCBwb3M7IAorCWlmICgocG9zID0gZXdvcmQuaW5kZXhPZignPycsIHN0YXJ0KSkgPT0gLTEpCisJICAgIHRocm93IG5ldyBQYXJzZUV4Y2VwdGlvbigKKwkJImVuY29kZWQgd29yZCBkb2VzIG5vdCBpbmNsdWRlIGNoYXJzZXQ6ICIgKyBld29yZCk7CisJU3RyaW5nIGNoYXJzZXQgPSBld29yZC5zdWJzdHJpbmcoc3RhcnQsIHBvcyk7CisJaW50IGxwb3MgPSBjaGFyc2V0LmluZGV4T2YoJyonKTsJLy8gUkZDIDIyMzEgbGFuZ3VhZ2Ugc3BlY2lmaWVkPworCWlmIChscG9zID49IDApCQkJCS8vIHllcywgdGhyb3cgaXQgYXdheQorCSAgICBjaGFyc2V0ID0gY2hhcnNldC5zdWJzdHJpbmcoMCwgbHBvcyk7CisJY2hhcnNldCA9IGphdmFDaGFyc2V0KGNoYXJzZXQpOworCisJLy8gZ2V0IGVuY29kaW5nCisJc3RhcnQgPSBwb3MrMTsKKwlpZiAoKHBvcyA9IGV3b3JkLmluZGV4T2YoJz8nLCBzdGFydCkpID09IC0xKQorCSAgICB0aHJvdyBuZXcgUGFyc2VFeGNlcHRpb24oCisJCSJlbmNvZGVkIHdvcmQgZG9lcyBub3QgaW5jbHVkZSBlbmNvZGluZzogIiArIGV3b3JkKTsKKwlTdHJpbmcgZW5jb2RpbmcgPSBld29yZC5zdWJzdHJpbmcoc3RhcnQsIHBvcyk7CisKKwkvLyBnZXQgZW5jb2RlZC1zZXF1ZW5jZQorCXN0YXJ0ID0gcG9zKzE7CisJaWYgKChwb3MgPSBld29yZC5pbmRleE9mKCI/PSIsIHN0YXJ0KSkgPT0gLTEpCisJICAgIHRocm93IG5ldyBQYXJzZUV4Y2VwdGlvbigKKwkJImVuY29kZWQgd29yZCBkb2VzIG5vdCBlbmQgd2l0aCBcIj89XCI6ICIgKyBld29yZCk7CisJLyoKKwkgKiBYWFggLSBzaG91bGQgaW5jbHVkZSB0aGlzLCBidXQgbGVhdmluZyBpdCBvdXQgZm9yIGNvbXBhdGliaWxpdHkuLi4KKwkgKgorCWlmIChkZWNvZGVTdHJpY3QgJiYgcG9zICE9IGV3b3JkLmxlbmd0aCgpIC0gMikKKwkgICAgdGhyb3cgbmV3IFBhcnNlRXhjZXB0aW9uKAorCQkiZW5jb2RlZCB3b3JkIGRvZXMgbm90IGVuZCB3aXRoIFwiPz1cIjogIiArIGV3b3JkKTspOworCSAqLworCVN0cmluZyB3b3JkID0gZXdvcmQuc3Vic3RyaW5nKHN0YXJ0LCBwb3MpOworCisJdHJ5IHsKKwkgICAgU3RyaW5nIGRlY29kZWRXb3JkOworCSAgICBpZiAod29yZC5sZW5ndGgoKSA+IDApIHsKKwkJLy8gRXh0cmFjdCB0aGUgYnl0ZXMgZnJvbSB3b3JkCisJCUJ5dGVBcnJheUlucHV0U3RyZWFtIGJpcyA9IAorCQkgICAgbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKEFTQ0lJVXRpbGl0eS5nZXRCeXRlcyh3b3JkKSk7CisKKwkJLy8gR2V0IHRoZSBhcHByb3ByaWF0ZSBkZWNvZGVyCisJCUlucHV0U3RyZWFtIGlzOworCQlpZiAoZW5jb2RpbmcuZXF1YWxzSWdub3JlQ2FzZSgiQiIpKSAKKwkJICAgIGlzID0gbmV3IEJBU0U2NERlY29kZXJTdHJlYW0oYmlzKTsKKwkJZWxzZSBpZiAoZW5jb2RpbmcuZXF1YWxzSWdub3JlQ2FzZSgiUSIpKQorCQkgICAgaXMgPSBuZXcgUURlY29kZXJTdHJlYW0oYmlzKTsKKwkJZWxzZQorCQkgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24oCisJCQkJICAgICJ1bmtub3duIGVuY29kaW5nOiAiICsgZW5jb2RpbmcpOworCisJCS8vIEZvciBiNjQgJiBxLCBzaXplIG9mIGRlY29kZWQgd29yZCA8PSBzaXplIG9mIHdvcmQuIFNvCisJCS8vIHRoZSBkZWNvZGVkIGJ5dGVzIG11c3QgZml0IGludG8gdGhlICdieXRlcycgYXJyYXkuIFRoaXMKKwkJLy8gaXMgY2VydGFpbmx5IG1vcmUgZWZmaWNpZW50IHRoYW4gd3JpdGluZyBieXRlcyBpbnRvIGEKKwkJLy8gQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGFuZCB0aGVuIHB1bGxpbmcgb3V0IHRoZSBieXRlW10KKwkJLy8gZnJvbSBpdC4KKwkJaW50IGNvdW50ID0gYmlzLmF2YWlsYWJsZSgpOworCQlieXRlW10gYnl0ZXMgPSBuZXcgYnl0ZVtjb3VudF07CisJCS8vIGNvdW50IGlzIHNldCB0byB0aGUgYWN0dWFsIG51bWJlciBvZiBkZWNvZGVkIGJ5dGVzIAorCQljb3VudCA9IGlzLnJlYWQoYnl0ZXMsIDAsIGNvdW50KTsKKworCQkvLyBGaW5hbGx5LCBjb252ZXJ0IHRoZSBkZWNvZGVkIGJ5dGVzIGludG8gYSBTdHJpbmcgdXNpbmcKKwkJLy8gdGhlIHNwZWNpZmllZCBjaGFyc2V0CisJCWRlY29kZWRXb3JkID0gY291bnQgPD0gMCA/ICIiIDoKKwkJCQluZXcgU3RyaW5nKGJ5dGVzLCAwLCBjb3VudCwgY2hhcnNldCk7CisJICAgIH0gZWxzZSB7CisJCS8vIG5vIGNoYXJhY3RlcnMgdG8gZGVjb2RlLCByZXR1cm4gZW1wdHkgc3RyaW5nCisJCWRlY29kZWRXb3JkID0gIiI7CisJICAgIH0KKwkgICAgaWYgKHBvcyArIDIgPCBld29yZC5sZW5ndGgoKSkgeworCQkvLyB0aGVyZSdzIHN0aWxsIG1vcmUgdGV4dCBpbiB0aGUgc3RyaW5nCisJCVN0cmluZyByZXN0ID0gZXdvcmQuc3Vic3RyaW5nKHBvcyArIDIpOworCQlpZiAoIWRlY29kZVN0cmljdCkKKwkJICAgIHJlc3QgPSBkZWNvZGVJbm5lcldvcmRzKHJlc3QpOworCQlkZWNvZGVkV29yZCArPSByZXN0OworCSAgICB9CisJICAgIHJldHVybiBkZWNvZGVkV29yZDsKKwl9IGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIHVleCkgeworCSAgICAvLyBleHBsaWNpdGx5IGNhdGNoIGFuZCByZXRocm93IHRoaXMgZXhjZXB0aW9uLCBvdGhlcndpc2UKKwkgICAgLy8gdGhlIGJlbG93IElPRXhjZXB0aW9uIGNhdGNoIHdpbGwgc3dhbGxvdyB0aGlzIHVwIQorCSAgICB0aHJvdyB1ZXg7CisJfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9leCkgeworCSAgICAvLyBTaG91bGRuJ3QgaGFwcGVuLgorCSAgICB0aHJvdyBuZXcgUGFyc2VFeGNlcHRpb24oaW9leC50b1N0cmluZygpKTsKKwl9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWV4KSB7CisJICAgIC8qIEFuIHVua25vd24gY2hhcnNldCBvZiB0aGUgZm9ybSBJU08tWFhYLVhYWCwgd2lsbCBjYXVzZQorCSAgICAgKiB0aGUgSkRLIHRvIHRocm93IGFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiAuLi4gU2luY2UgdGhlCisJICAgICAqIEpESyB3aWxsIGF0dGVtcHQgdG8gY3JlYXRlIGEgY2xhc3NuYW1lIHVzaW5nIHRoaXMgc3RyaW5nLAorCSAgICAgKiBidXQgdmFsaWQgY2xhc3NuYW1lcyBtdXN0IG5vdCBjb250YWluIHRoZSBjaGFyYWN0ZXIgJy0nLAorCSAgICAgKiBhbmQgdGhpcyByZXN1bHRzIGluIGFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwgcmF0aGVyIHRoYW4KKwkgICAgICogdGhlIGV4cGVjdGVkIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24uIFlpa2VzCisJICAgICAqLworCSAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbihjaGFyc2V0KTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogTG9vayBmb3IgZW5jb2RlZCB3b3JkcyB3aXRoaW4gYSB3b3JkLiAgVGhlIE1JTUUgc3BlYyBkb2Vzbid0CisgICAgICogYWxsb3cgdGhpcywgYnV0IG1hbnkgYnJva2VuIG1haWxlcnMsIGVzcGVjaWFsbHkgSmFwYW5lc2UgbWFpbGVycywKKyAgICAgKiBwcm9kdWNlIHN1Y2ggaW5jb3JyZWN0IGVuY29kaW5ncy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZGVjb2RlSW5uZXJXb3JkcyhTdHJpbmcgd29yZCkKKwkJCQl0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiB7CisJaW50IHN0YXJ0ID0gMCwgaTsKKwlTdHJpbmdCdWlsZGVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisJd2hpbGUgKChpID0gd29yZC5pbmRleE9mKCI9PyIsIHN0YXJ0KSkgPj0gMCkgeworCSAgICBidWYuYXBwZW5kKHdvcmQuc3Vic3RyaW5nKHN0YXJ0LCBpKSk7CisJICAgIC8vIGZpbmQgZmlyc3QgJz8nIGFmdGVyIG9wZW5pbmcgJz0/JyAtIGVuZCBvZiBjaGFyc2V0CisJICAgIGludCBlbmQgPSB3b3JkLmluZGV4T2YoJz8nLCBpICsgMik7CisJICAgIGlmIChlbmQgPCAwKQorCQlicmVhazsKKwkgICAgLy8gZmluZCBuZXh0ICc/JyBhZnRlciB0aGF0IC0gZW5kIG9mIGVuY29kaW5nCisJICAgIGVuZCA9IHdvcmQuaW5kZXhPZignPycsIGVuZCArIDEpOworCSAgICBpZiAoZW5kIDwgMCkKKwkJYnJlYWs7CisJICAgIC8vIGZpbmQgdGVybWluYXRpbmcgJz89JworCSAgICBlbmQgPSB3b3JkLmluZGV4T2YoIj89IiwgZW5kICsgMSk7CisJICAgIGlmIChlbmQgPCAwKQorCQlicmVhazsKKwkgICAgU3RyaW5nIHMgPSB3b3JkLnN1YnN0cmluZyhpLCBlbmQgKyAyKTsKKwkgICAgdHJ5IHsKKwkJcyA9IGRlY29kZVdvcmQocyk7CisJICAgIH0gY2F0Y2ggKFBhcnNlRXhjZXB0aW9uIHBleCkgeworCQkvLyBpZ25vcmUgaXQsIGp1c3QgdXNlIHRoZSBvcmlnaW5hbCBzdHJpbmcKKwkgICAgfQorCSAgICBidWYuYXBwZW5kKHMpOworCSAgICBzdGFydCA9IGVuZCArIDI7CisJfQorCWlmIChzdGFydCA9PSAwKQorCSAgICByZXR1cm4gd29yZDsKKwlpZiAoc3RhcnQgPCB3b3JkLmxlbmd0aCgpKQorCSAgICBidWYuYXBwZW5kKHdvcmQuc3Vic3RyaW5nKHN0YXJ0KSk7CisJcmV0dXJuIGJ1Zi50b1N0cmluZygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEEgdXRpbGl0eSBtZXRob2QgdG8gcXVvdGUgYSB3b3JkLCBpZiB0aGUgd29yZCBjb250YWlucyBhbnkKKyAgICAgKiBjaGFyYWN0ZXJzIGZyb20gdGhlIHNwZWNpZmllZCAnc3BlY2lhbHMnIGxpc3QuPHA+CisgICAgICoKKyAgICAgKiBUaGUgPGNvZGU+SGVhZGVyVG9rZW5pemVyPC9jb2RlPiBjbGFzcyBkZWZpbmVzIHR3byBzcGVjaWFsCisgICAgICogc2V0cyBvZiBkZWxpbWl0ZXJzIC0gTUlNRSBhbmQgUkZDIDgyMi4gPHA+CisgICAgICoKKyAgICAgKiBUaGlzIG1ldGhvZCBpcyB0eXBpY2FsbHkgdXNlZCBkdXJpbmcgdGhlIGdlbmVyYXRpb24gb2YgCisgICAgICogUkZDIDgyMiBhbmQgTUlNRSBoZWFkZXIgZmllbGRzLgorICAgICAqCisgICAgICogQHBhcmFtCXdvcmQJd29yZCB0byBiZSBxdW90ZWQKKyAgICAgKiBAcGFyYW0Jc3BlY2lhbHMgdGhlIHNldCBvZiBzcGVjaWFsIGNoYXJhY3RlcnMKKyAgICAgKiBAcmV0dXJuCQl0aGUgcG9zc2libHkgcXVvdGVkIHdvcmQKKyAgICAgKiBAc2VlCWphdmF4Lm1haWwuaW50ZXJuZXQuSGVhZGVyVG9rZW5pemVyI01JTUUKKyAgICAgKiBAc2VlCWphdmF4Lm1haWwuaW50ZXJuZXQuSGVhZGVyVG9rZW5pemVyI1JGQzgyMgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHF1b3RlKFN0cmluZyB3b3JkLCBTdHJpbmcgc3BlY2lhbHMpIHsKKwlpbnQgbGVuID0gd29yZCA9PSBudWxsID8gMCA6IHdvcmQubGVuZ3RoKCk7CisJaWYgKGxlbiA9PSAwKQorCSAgICByZXR1cm4gIlwiXCIiOwkvLyBhbiBlbXB0eSBzdHJpbmcgaXMgaGFuZGxlZCBzcGVjaWFsbHkKKworCS8qCisJICogTG9vayBmb3IgYW55ICJiYWQiIGNoYXJhY3RlcnMsIEVzY2FwZSBhbmQKKwkgKiAgcXVvdGUgdGhlIGVudGlyZSBzdHJpbmcgaWYgbmVjZXNzYXJ5LgorCSAqLworCWJvb2xlYW4gbmVlZFF1b3RpbmcgPSBmYWxzZTsKKwlmb3IgKGludCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7CisJICAgIGNoYXIgYyA9IHdvcmQuY2hhckF0KGkpOworCSAgICBpZiAoYyA9PSAnIicgfHwgYyA9PSAnXFwnIHx8IGMgPT0gJ1xyJyB8fCBjID09ICdcbicpIHsKKwkJLy8gbmVlZCB0byBlc2NhcGUgdGhlbSBhbmQgdGhlbiBxdW90ZSB0aGUgd2hvbGUgc3RyaW5nCisJCVN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcihsZW4gKyAzKTsKKwkJc2IuYXBwZW5kKCciJyk7CisJCXNiLmFwcGVuZCh3b3JkLnN1YnN0cmluZygwLCBpKSk7CisJCWludCBsYXN0YyA9IDA7CisJCWZvciAoaW50IGogPSBpOyBqIDwgbGVuOyBqKyspIHsKKwkJICAgIGNoYXIgY2MgPSB3b3JkLmNoYXJBdChqKTsKKwkJICAgIGlmICgoY2MgPT0gJyInKSB8fCAoY2MgPT0gJ1xcJykgfHwgCisJCQkoY2MgPT0gJ1xyJykgfHwgKGNjID09ICdcbicpKQorCQkJaWYgKGNjID09ICdcbicgJiYgbGFzdGMgPT0gJ1xyJykKKwkJCSAgICA7CS8vIGRvIG5vdGhpbmcsIENSIHdhcyBhbHJlYWR5IGVzY2FwZWQKKwkJCWVsc2UKKwkJCSAgICBzYi5hcHBlbmQoJ1xcJyk7CS8vIEVzY2FwZSB0aGUgY2hhcmFjdGVyCisJCSAgICBzYi5hcHBlbmQoY2MpOworCQkgICAgbGFzdGMgPSBjYzsKKwkJfQorCQlzYi5hcHBlbmQoJyInKTsKKwkJcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisJICAgIH0gZWxzZSBpZiAoYyA8IDA0MCB8fCAoYyA+PSAwMTc3ICYmICFhbGxvd1V0ZjgpIHx8CisJCSAgICBzcGVjaWFscy5pbmRleE9mKGMpID49IDApCisJCS8vIFRoZXNlIGNoYXJhY3RlcnMgY2F1c2UgdGhlIHN0cmluZyB0byBiZSBxdW90ZWQKKwkJbmVlZFF1b3RpbmcgPSB0cnVlOworCX0KKworCWlmIChuZWVkUXVvdGluZykgeworCSAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIobGVuICsgMik7CisJICAgIHNiLmFwcGVuZCgnIicpLmFwcGVuZCh3b3JkKS5hcHBlbmQoJyInKTsKKwkgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisJfSBlbHNlIAorCSAgICByZXR1cm4gd29yZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGb2xkIGEgc3RyaW5nIGF0IGxpbmVhciB3aGl0ZXNwYWNlIHNvIHRoYXQgZWFjaCBsaW5lIGlzIG5vIGxvbmdlcgorICAgICAqIHRoYW4gNzYgY2hhcmFjdGVycywgaWYgcG9zc2libGUuICBJZiB0aGVyZSBhcmUgbW9yZSB0aGFuIDc2CisgICAgICogbm9uLXdoaXRlc3BhY2UgY2hhcmFjdGVycyBjb25zZWN1dGl2ZWx5LCB0aGUgc3RyaW5nIGlzIGZvbGRlZCBhdAorICAgICAqIHRoZSBmaXJzdCB3aGl0ZXNwYWNlIGFmdGVyIHRoYXQgc2VxdWVuY2UuICBUaGUgcGFyYW1ldGVyCisgICAgICogPGNvZGU+dXNlZDwvY29kZT4gaW5kaWNhdGVzIGhvdyBtYW55IGNoYXJhY3RlcnMgaGF2ZSBiZWVuIHVzZWQgaW4KKyAgICAgKiB0aGUgY3VycmVudCBsaW5lOyBpdCBpcyB1c3VhbGx5IHRoZSBsZW5ndGggb2YgdGhlIGhlYWRlciBuYW1lLiA8cD4KKyAgICAgKgorICAgICAqIE5vdGUgdGhhdCBsaW5lIGJyZWFrcyBpbiB0aGUgc3RyaW5nIGFyZW4ndCBlc2NhcGVkOyB0aGV5IHByb2JhYmx5CisgICAgICogc2hvdWxkIGJlLgorICAgICAqCisgICAgICogQHBhcmFtCXVzZWQJY2hhcmFjdGVycyB1c2VkIGluIGxpbmUgc28gZmFyCisgICAgICogQHBhcmFtCXMJdGhlIHN0cmluZyB0byBmb2xkCisgICAgICogQHJldHVybgkJdGhlIGZvbGRlZCBzdHJpbmcKKyAgICAgKiBAc2luY2UJCUphdmFNYWlsIDEuNAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGZvbGQoaW50IHVzZWQsIFN0cmluZyBzKSB7CisJaWYgKCFmb2xkVGV4dCkKKwkgICAgcmV0dXJuIHM7CisKKwlpbnQgZW5kOworCWNoYXIgYzsKKwkvLyBTdHJpcCB0cmFpbGluZyBzcGFjZXMgYW5kIG5ld2xpbmVzCisJZm9yIChlbmQgPSBzLmxlbmd0aCgpIC0gMTsgZW5kID49IDA7IGVuZC0tKSB7CisJICAgIGMgPSBzLmNoYXJBdChlbmQpOworCSAgICBpZiAoYyAhPSAnICcgJiYgYyAhPSAnXHQnICYmIGMgIT0gJ1xyJyAmJiBjICE9ICdcbicpCisJCWJyZWFrOworCX0KKwlpZiAoZW5kICE9IHMubGVuZ3RoKCkgLSAxKQorCSAgICBzID0gcy5zdWJzdHJpbmcoMCwgZW5kICsgMSk7CisKKwkvLyBpZiB0aGUgc3RyaW5nIGZpdHMgbm93LCBqdXN0IHJldHVybiBpdAorCWlmICh1c2VkICsgcy5sZW5ndGgoKSA8PSA3NikKKwkgICAgcmV0dXJuIG1ha2VzYWZlKHMpOworCisJLy8gaGF2ZSB0byBhY3R1YWxseSBmb2xkIHRoZSBzdHJpbmcKKwlTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIocy5sZW5ndGgoKSArIDQpOworCWNoYXIgbGFzdGMgPSAwOworCXdoaWxlICh1c2VkICsgcy5sZW5ndGgoKSA+IDc2KSB7CisJICAgIGludCBsYXN0c3BhY2UgPSAtMTsKKwkgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzLmxlbmd0aCgpOyBpKyspIHsKKwkJaWYgKGxhc3RzcGFjZSAhPSAtMSAmJiB1c2VkICsgaSA+IDc2KQorCQkgICAgYnJlYWs7CisJCWMgPSBzLmNoYXJBdChpKTsKKwkJaWYgKGMgPT0gJyAnIHx8IGMgPT0gJ1x0JykKKwkJICAgIGlmICghKGxhc3RjID09ICcgJyB8fCBsYXN0YyA9PSAnXHQnKSkKKwkJCWxhc3RzcGFjZSA9IGk7CisJCWxhc3RjID0gYzsKKwkgICAgfQorCSAgICBpZiAobGFzdHNwYWNlID09IC0xKSB7CisJCS8vIG5vIHNwYWNlLCB1c2UgdGhlIHdob2xlIHRoaW5nCisJCXNiLmFwcGVuZChzKTsKKwkJcyA9ICIiOworCQl1c2VkID0gMDsKKwkJYnJlYWs7CisJICAgIH0KKwkgICAgc2IuYXBwZW5kKHMuc3Vic3RyaW5nKDAsIGxhc3RzcGFjZSkpOworCSAgICBzYi5hcHBlbmQoIlxyXG4iKTsKKwkgICAgbGFzdGMgPSBzLmNoYXJBdChsYXN0c3BhY2UpOworCSAgICBzYi5hcHBlbmQobGFzdGMpOworCSAgICBzID0gcy5zdWJzdHJpbmcobGFzdHNwYWNlICsgMSk7CisJICAgIHVzZWQgPSAxOworCX0KKwlzYi5hcHBlbmQocyk7CisJcmV0dXJuIG1ha2VzYWZlKHNiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJZiB0aGUgU3RyaW5nIG9yIFN0cmluZ0J1aWxkZXIgaGFzIGFueSBlbWJlZGRlZCBuZXdsaW5lcywKKyAgICAgKiBtYWtlIHN1cmUgdGhleSdyZSBmb2xsb3dlZCBieSB3aGl0ZXNwYWNlLCB0byBwcmV2ZW50IGhlYWRlcgorICAgICAqIGluamVjdGlvbiBlcnJvcnMuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIG1ha2VzYWZlKENoYXJTZXF1ZW5jZSBzKSB7CisJaW50IGk7CisJZm9yIChpID0gMDsgaSA8IHMubGVuZ3RoKCk7IGkrKykgeworCSAgICBjaGFyIGMgPSBzLmNoYXJBdChpKTsKKwkgICAgaWYgKGMgPT0gJ1xyJyB8fCBjID09ICdcbicpCisJCWJyZWFrOworCX0KKwlpZiAoaSA9PSBzLmxlbmd0aCgpKQkvLyB3ZW50IHRocm91Z2ggd2hvbGUgc3RyaW5nIHdpdGggbm8gQ1Igb3IgTEYKKwkgICAgcmV0dXJuIHMudG9TdHJpbmcoKTsKKworCS8vIHJlYWQgdGhlIGxpbmVzIGluIHRoZSBzdHJpbmcgYW5kIHJlYXNzZW1ibGUgdGhlbSwKKwkvLyBlbGltaW5hdGluZyBibGFuayBsaW5lcyBhbmQgaW5zZXJ0aW5nIHdoaXRlc3BhY2UgYXMgbmVjZXNzYXJ5CisJU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKHMubGVuZ3RoKCkgKyAxKTsKKwlCdWZmZXJlZFJlYWRlciByID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBTdHJpbmdSZWFkZXIocy50b1N0cmluZygpKSk7CisJU3RyaW5nIGxpbmU7CisJdHJ5IHsKKwkgICAgd2hpbGUgKChsaW5lID0gci5yZWFkTGluZSgpKSAhPSBudWxsKSB7CisJCWlmIChsaW5lLnRyaW0oKS5sZW5ndGgoKSA9PSAwKQorCQkgICAgY29udGludWU7CS8vIGlnbm9yZSBlbXB0eSBsaW5lcworCQlpZiAoc2IubGVuZ3RoKCkgPiAwKSB7CisJCSAgICBzYi5hcHBlbmQoIlxyXG4iKTsKKwkJICAgIGFzc2VydCBsaW5lLmxlbmd0aCgpID4gMDsgLy8gcHJvdmVuIGFib3ZlCisJCSAgICBjaGFyIGMgPSBsaW5lLmNoYXJBdCgwKTsKKwkJICAgIGlmIChjICE9ICcgJyAmJiBjICE9ICdcdCcpCisJCQlzYi5hcHBlbmQoJyAnKTsKKwkJfQorCQlzYi5hcHBlbmQobGluZSk7CisJICAgIH0KKwl9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworCSAgICAvLyBYWFggLSBzaG91bGQgbmV2ZXIgaGFwcGVuIHdoZW4gcmVhZGluZyBmcm9tIGEgc3RyaW5nCisJICAgIHJldHVybiBzLnRvU3RyaW5nKCk7CisJfQorCXJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFVuZm9sZCBhIGZvbGRlZCBoZWFkZXIuICBBbnkgbGluZSBicmVha3MgdGhhdCBhcmVuJ3QgZXNjYXBlZCBhbmQKKyAgICAgKiBhcmUgZm9sbG93ZWQgYnkgd2hpdGVzcGFjZSBhcmUgcmVtb3ZlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbQlzCXRoZSBzdHJpbmcgdG8gdW5mb2xkCisgICAgICogQHJldHVybgkJdGhlIHVuZm9sZGVkIHN0cmluZworICAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS40CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdW5mb2xkKFN0cmluZyBzKSB7CisJaWYgKCFmb2xkVGV4dCkKKwkgICAgcmV0dXJuIHM7CisKKwlTdHJpbmdCdWlsZGVyIHNiID0gbnVsbDsKKwlpbnQgaTsKKwl3aGlsZSAoKGkgPSBpbmRleE9mQW55KHMsICJcclxuIikpID49IDApIHsKKwkgICAgaW50IHN0YXJ0ID0gaTsKKwkgICAgaW50IHNsZW4gPSBzLmxlbmd0aCgpOworCSAgICBpKys7CQkvLyBza2lwIENSIG9yIE5MCisJICAgIGlmIChpIDwgc2xlbiAmJiBzLmNoYXJBdChpIC0gMSkgPT0gJ1xyJyAmJiBzLmNoYXJBdChpKSA9PSAnXG4nKQorCQlpKys7CS8vIHNraXAgTEYKKwkgICAgaWYgKHN0YXJ0ID4gMCAmJiBzLmNoYXJBdChzdGFydCAtIDEpID09ICdcXCcpIHsKKwkJLy8gdGhlcmUncyBhIGJhY2tzbGFzaCBiZWZvcmUgdGhlIGxpbmUgYnJlYWsKKwkJLy8gc3RyaXAgaXQgb3V0LCBidXQgbGVhdmUgaW4gdGhlIGxpbmUgYnJlYWsKKwkJaWYgKHNiID09IG51bGwpCisJCSAgICBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKHMubGVuZ3RoKCkpOworCQlzYi5hcHBlbmQocy5zdWJzdHJpbmcoMCwgc3RhcnQgLSAxKSk7CisJCXNiLmFwcGVuZChzLnN1YnN0cmluZyhzdGFydCwgaSkpOworCQlzID0gcy5zdWJzdHJpbmcoaSk7CisJICAgIH0gZWxzZSB7CisJCWNoYXIgYzsKKwkJLy8gaWYgbmV4dCBsaW5lIHN0YXJ0cyB3aXRoIHdoaXRlc3BhY2UsCisJCS8vIG9yIGF0IHRoZSBlbmQgb2YgdGhlIHN0cmluZywgcmVtb3ZlIHRoZSBsaW5lIGJyZWFrCisJCS8vIFhYWCAtIG5leHQgbGluZSBzaG91bGQgYWx3YXlzIHN0YXJ0IHdpdGggd2hpdGVzcGFjZQorCQlpZiAoaSA+PSBzbGVuIHx8IChjID0gcy5jaGFyQXQoaSkpID09ICcgJyB8fCBjID09ICdcdCcpIHsKKwkJICAgIGlmIChzYiA9PSBudWxsKQorCQkJc2IgPSBuZXcgU3RyaW5nQnVpbGRlcihzLmxlbmd0aCgpKTsKKwkJICAgIHNiLmFwcGVuZChzLnN1YnN0cmluZygwLCBzdGFydCkpOworCQkgICAgcyA9IHMuc3Vic3RyaW5nKGkpOworCQl9IGVsc2UgeworCQkgICAgLy8gaXQncyBub3QgYSBjb250aW51YXRpb24gbGluZSwganVzdCBsZWF2ZSBpbiB0aGUgbmV3bGluZQorCQkgICAgaWYgKHNiID09IG51bGwpCisJCQlzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKHMubGVuZ3RoKCkpOworCQkgICAgc2IuYXBwZW5kKHMuc3Vic3RyaW5nKDAsIGkpKTsKKwkJICAgIHMgPSBzLnN1YnN0cmluZyhpKTsKKwkJfQorCSAgICB9CisJfQorCWlmIChzYiAhPSBudWxsKSB7CisJICAgIHNiLmFwcGVuZChzKTsKKwkgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisJfSBlbHNlCisJICAgIHJldHVybiBzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgZmlyc3QgaW5kZXggb2YgYW55IG9mIHRoZSBjaGFyYWN0ZXJzIGluICJhbnkiIGluICJzIiwKKyAgICAgKiBvciAtMSBpZiBub25lIGFyZSBmb3VuZC4KKyAgICAgKgorICAgICAqIFRoaXMgc2hvdWxkIGJlIGEgbWV0aG9kIG9uIFN0cmluZy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBpbnQgaW5kZXhPZkFueShTdHJpbmcgcywgU3RyaW5nIGFueSkgeworCXJldHVybiBpbmRleE9mQW55KHMsIGFueSwgMCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IGluZGV4T2ZBbnkoU3RyaW5nIHMsIFN0cmluZyBhbnksIGludCBzdGFydCkgeworCXRyeSB7CisJICAgIGludCBsZW4gPSBzLmxlbmd0aCgpOworCSAgICBmb3IgKGludCBpID0gc3RhcnQ7IGkgPCBsZW47IGkrKykgeworCQlpZiAoYW55LmluZGV4T2Yocy5jaGFyQXQoaSkpID49IDApCisJCSAgICByZXR1cm4gaTsKKwkgICAgfQorCSAgICByZXR1cm4gLTE7CisJfSBjYXRjaCAoU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisJICAgIHJldHVybiAtMTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydCBhIE1JTUUgY2hhcnNldCBuYW1lIGludG8gYSB2YWxpZCBKYXZhIGNoYXJzZXQgbmFtZS4gPHA+CisgICAgICoKKyAgICAgKiBAcGFyYW0gY2hhcnNldAl0aGUgTUlNRSBjaGFyc2V0IG5hbWUKKyAgICAgKiBAcmV0dXJuICB0aGUgSmF2YSBjaGFyc2V0IGVxdWl2YWxlbnQuIElmIGEgc3VpdGFibGUgbWFwcGluZyBpcworICAgICAqCQlub3QgYXZhaWxhYmxlLCB0aGUgcGFzc2VkIGluIGNoYXJzZXQgaXMgaXRzZWxmIHJldHVybmVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGphdmFDaGFyc2V0KFN0cmluZyBjaGFyc2V0KSB7CisJaWYgKG1pbWUyamF2YSA9PSBudWxsIHx8IGNoYXJzZXQgPT0gbnVsbCkKKwkgICAgLy8gbm8gbWFwcGluZyB0YWJsZSwgb3IgY2hhcnNldCBwYXJhbWV0ZXIgaXMgbnVsbAorCSAgICByZXR1cm4gY2hhcnNldDsKKworCVN0cmluZyBhbGlhcyA9IG1pbWUyamF2YS5nZXQoY2hhcnNldC50b0xvd2VyQ2FzZShMb2NhbGUuRU5HTElTSCkpOworCWlmIChhbGlhcyAhPSBudWxsKSB7CisJICAgIC8vIHZlcmlmeSB0aGF0IHRoZSBtYXBwZWQgbmFtZSBpcyB2YWxpZCBiZWZvcmUgdHJ5aW5nIHRvIHVzZSBpdAorCSAgICB0cnkgeworCQlDaGFyc2V0LmZvck5hbWUoYWxpYXMpOworCSAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKwkJYWxpYXMgPSBudWxsOwkvLyBjaGFyc2V0IGFsaWFzIG5vdCB2YWxpZCwgdXNlIG9yaWdpbmFsIG5hbWUKKwkgICAgfQorCX0KKwlyZXR1cm4gYWxpYXMgPT0gbnVsbCA/IGNoYXJzZXQgOiBhbGlhczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb252ZXJ0IGEgamF2YSBjaGFyc2V0IGludG8gaXRzIE1JTUUgY2hhcnNldCBuYW1lLiA8cD4KKyAgICAgKgorICAgICAqIE5vdGUgdGhhdCBhIGZ1dHVyZSB2ZXJzaW9uIG9mIEpESyAocG9zdCAxLjIpIG1pZ2h0IHByb3ZpZGUKKyAgICAgKiB0aGlzIGZ1bmN0aW9uYWxpdHksIGluIHdoaWNoIGNhc2UsIHdlIG1heSBkZXByZWNhdGUgdGhpcworICAgICAqIG1ldGhvZCB0aGVuLgorICAgICAqCisgICAgICogQHBhcmFtICAgY2hhcnNldCAgICB0aGUgSkRLIGNoYXJzZXQKKyAgICAgKiBAcmV0dXJuICAgICAgCXRoZSBNSU1FL0lBTkEgZXF1aXZhbGVudC4gSWYgYSBtYXBwaW5nCisgICAgICoJCQlpcyBub3QgcG9zc2libGUsIHRoZSBwYXNzZWQgaW4gY2hhcnNldCBpdHNlbGYKKyAgICAgKgkJCWlzIHJldHVybmVkLgorICAgICAqIEBzaW5jZQkJSmF2YU1haWwgMS4xCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgbWltZUNoYXJzZXQoU3RyaW5nIGNoYXJzZXQpIHsKKwlpZiAoamF2YTJtaW1lID09IG51bGwgfHwgY2hhcnNldCA9PSBudWxsKSAKKwkgICAgLy8gbm8gbWFwcGluZyB0YWJsZSBvciBjaGFyc2V0IHBhcmFtIGlzIG51bGwKKwkgICAgcmV0dXJuIGNoYXJzZXQ7CisKKwlTdHJpbmcgYWxpYXMgPSBqYXZhMm1pbWUuZ2V0KGNoYXJzZXQudG9Mb3dlckNhc2UoTG9jYWxlLkVOR0xJU0gpKTsKKwlyZXR1cm4gYWxpYXMgPT0gbnVsbCA/IGNoYXJzZXQgOiBhbGlhczsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZGVmYXVsdEphdmFDaGFyc2V0OworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBkZWZhdWx0TUlNRUNoYXJzZXQ7CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGRlZmF1bHQgY2hhcnNldCBjb3JyZXNwb25kaW5nIHRvIHRoZSBzeXN0ZW0ncyBjdXJyZW50IAorICAgICAqIGRlZmF1bHQgbG9jYWxlLiAgSWYgdGhlIFN5c3RlbSBwcm9wZXJ0eSA8Y29kZT5tYWlsLm1pbWUuY2hhcnNldDwvY29kZT4KKyAgICAgKiBpcyBzZXQsIGEgc3lzdGVtIGNoYXJzZXQgY29ycmVzcG9uZGluZyB0byB0aGlzIE1JTUUgY2hhcnNldCB3aWxsIGJlCisgICAgICogcmV0dXJuZWQuIDxwPgorICAgICAqIAorICAgICAqIEByZXR1cm4JdGhlIGRlZmF1bHQgY2hhcnNldCBvZiB0aGUgc3lzdGVtJ3MgZGVmYXVsdCBsb2NhbGUsIAorICAgICAqIAkJYXMgYSBKYXZhIGNoYXJzZXQuIChOT1QgYSBNSU1FIGNoYXJzZXQpCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuMQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldERlZmF1bHRKYXZhQ2hhcnNldCgpIHsKKwlpZiAoZGVmYXVsdEphdmFDaGFyc2V0ID09IG51bGwpIHsKKwkgICAgLyoKKwkgICAgICogSWYgbWFpbC5taW1lLmNoYXJzZXQgaXMgc2V0LCBpdCBjb250cm9scyB0aGUgZGVmYXVsdAorCSAgICAgKiBKYXZhIGNoYXJzZXQgYXMgd2VsbC4KKwkgICAgICovCisJICAgIFN0cmluZyBtaW1lY3MgPSBudWxsOworCSAgICB0cnkgeworCQltaW1lY3MgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoIm1haWwubWltZS5jaGFyc2V0Iik7CisJICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGV4KSB7IH0JLy8gaWdub3JlIGl0CisJICAgIGlmIChtaW1lY3MgIT0gbnVsbCAmJiBtaW1lY3MubGVuZ3RoKCkgPiAwKSB7CisJCWRlZmF1bHRKYXZhQ2hhcnNldCA9IGphdmFDaGFyc2V0KG1pbWVjcyk7CisJCXJldHVybiBkZWZhdWx0SmF2YUNoYXJzZXQ7CisJICAgIH0KKworCSAgICB0cnkgeworCQlkZWZhdWx0SmF2YUNoYXJzZXQgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImZpbGUuZW5jb2RpbmciLCAKKwkJCQkJCQkiODg1OV8xIik7CisJICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHNleCkgeworCQkKKwkJY2xhc3MgTnVsbElucHV0U3RyZWFtIGV4dGVuZHMgSW5wdXRTdHJlYW0geworCQkgICAgQE92ZXJyaWRlCisJCSAgICBwdWJsaWMgaW50IHJlYWQoKSB7CisJCQlyZXR1cm4gMDsKKwkJICAgIH0KKwkJfQorCQlJbnB1dFN0cmVhbVJlYWRlciByZWFkZXIgPSAKKwkJCW5ldyBJbnB1dFN0cmVhbVJlYWRlcihuZXcgTnVsbElucHV0U3RyZWFtKCkpOworCQlkZWZhdWx0SmF2YUNoYXJzZXQgPSByZWFkZXIuZ2V0RW5jb2RpbmcoKTsKKwkJaWYgKGRlZmF1bHRKYXZhQ2hhcnNldCA9PSBudWxsKQorCQkgICAgZGVmYXVsdEphdmFDaGFyc2V0ID0gIjg4NTlfMSI7CisJICAgIH0KKwl9CisKKwlyZXR1cm4gZGVmYXVsdEphdmFDaGFyc2V0OworICAgIH0KKworICAgIC8qCisgICAgICogR2V0IHRoZSBkZWZhdWx0IE1JTUUgY2hhcnNldCBmb3IgdGhpcyBsb2NhbGUuCisgICAgICovCisgICAgc3RhdGljIFN0cmluZyBnZXREZWZhdWx0TUlNRUNoYXJzZXQoKSB7CisJaWYgKGRlZmF1bHRNSU1FQ2hhcnNldCA9PSBudWxsKSB7CisJICAgIHRyeSB7CisJCWRlZmF1bHRNSU1FQ2hhcnNldCA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgibWFpbC5taW1lLmNoYXJzZXQiKTsKKwkgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gZXgpIHsgfQkvLyBpZ25vcmUgaXQKKwl9CisJaWYgKGRlZmF1bHRNSU1FQ2hhcnNldCA9PSBudWxsKQorCSAgICBkZWZhdWx0TUlNRUNoYXJzZXQgPSBtaW1lQ2hhcnNldChnZXREZWZhdWx0SmF2YUNoYXJzZXQoKSk7CisJcmV0dXJuIGRlZmF1bHRNSU1FQ2hhcnNldDsKKyAgICB9CisKKyAgICAvLyBUYWJsZXMgdG8gbWFwIE1JTUUgY2hhcnNldCBuYW1lcyB0byBKYXZhIG5hbWVzIGFuZCB2aWNlIHZlcnNhLgorICAgIC8vIFhYWCAtIFNob3VsZCBldmVudHVhbGx5IHVzZSBKMlNFIDEuNCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXQKKyAgICBwcml2YXRlIHN0YXRpYyBNYXA8U3RyaW5nLCBTdHJpbmc+IG1pbWUyamF2YTsKKyAgICBwcml2YXRlIHN0YXRpYyBNYXA8U3RyaW5nLCBTdHJpbmc+IGphdmEybWltZTsKKworICAgIHN0YXRpYyB7CisJamF2YTJtaW1lID0gbmV3IEhhc2hNYXA8Pig0MCk7CisJbWltZTJqYXZhID0gbmV3IEhhc2hNYXA8PigxNCk7CisKKwl0cnkgeworCSAgICAvLyBVc2UgdGhpcyBjbGFzcydzIGNsYXNzbG9hZGVyIHRvIGxvYWQgdGhlIG1hcHBpbmcgZmlsZQorCSAgICAvLyBYWFggLSB3ZSBzaG91bGQgdXNlIFNlY3VyaXR5U3VwcG9ydCwgYnV0IGl0J3MgaW4gYW5vdGhlciBwYWNrYWdlCisJICAgIElucHV0U3RyZWFtIGlzID0gCisJCSAgICBqYXZheC5tYWlsLmludGVybmV0Lk1pbWVVdGlsaXR5LmNsYXNzLmdldFJlc291cmNlQXNTdHJlYW0oCisJCSAgICAiL01FVEEtSU5GL2phdmFtYWlsLmNoYXJzZXQubWFwIik7CisKKwkgICAgaWYgKGlzICE9IG51bGwpIHsKKwkJdHJ5IHsKKwkJICAgIGlzID0gbmV3IExpbmVJbnB1dFN0cmVhbShpcyk7CisKKwkJICAgIC8vIExvYWQgdGhlIEpESy10by1NSU1FIGNoYXJzZXQgbWFwcGluZyB0YWJsZQorCQkgICAgbG9hZE1hcHBpbmdzKChMaW5lSW5wdXRTdHJlYW0paXMsIGphdmEybWltZSk7CisKKwkJICAgIC8vIExvYWQgdGhlIE1JTUUtdG8tSkRLIGNoYXJzZXQgbWFwcGluZyB0YWJsZQorCQkgICAgbG9hZE1hcHBpbmdzKChMaW5lSW5wdXRTdHJlYW0paXMsIG1pbWUyamF2YSk7CisJCX0gZmluYWxseSB7CisJCSAgICB0cnkgeworCQkJaXMuY2xvc2UoKTsKKwkJICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBjZXgpIHsKKwkJCS8vIGlnbm9yZQorCQkgICAgfQorCQl9CisJICAgIH0KKwl9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsgfQorCisJLy8gSWYgd2UgZGlkbid0IGxvYWQgdGhlIHRhYmxlcywgZS5nLiwgYmVjYXVzZSB3ZSBkaWRuJ3QgaGF2ZQorCS8vIHBlcm1pc3Npb24sIGxvYWQgdGhlbSBtYW51YWxseS4gIFRoZSBlbnRyaWVzIGhlcmUgc2hvdWxkIGJlCisJLy8gdGhlIHNhbWUgYXMgdGhlIGRlZmF1bHQgamF2YW1haWwuY2hhcnNldC5tYXAuCisJaWYgKGphdmEybWltZS5pc0VtcHR5KCkpIHsKKwkgICAgamF2YTJtaW1lLnB1dCgiODg1OV8xIiwgIklTTy04ODU5LTEiKTsKKwkgICAgamF2YTJtaW1lLnB1dCgiaXNvODg1OV8xIiwgIklTTy04ODU5LTEiKTsKKwkgICAgamF2YTJtaW1lLnB1dCgiaXNvODg1OS0xIiwgIklTTy04ODU5LTEiKTsKKworCSAgICBqYXZhMm1pbWUucHV0KCI4ODU5XzIiLCAiSVNPLTg4NTktMiIpOworCSAgICBqYXZhMm1pbWUucHV0KCJpc284ODU5XzIiLCAiSVNPLTg4NTktMiIpOworCSAgICBqYXZhMm1pbWUucHV0KCJpc284ODU5LTIiLCAiSVNPLTg4NTktMiIpOworCisJICAgIGphdmEybWltZS5wdXQoIjg4NTlfMyIsICJJU08tODg1OS0zIik7CisJICAgIGphdmEybWltZS5wdXQoImlzbzg4NTlfMyIsICJJU08tODg1OS0zIik7CisJICAgIGphdmEybWltZS5wdXQoImlzbzg4NTktMyIsICJJU08tODg1OS0zIik7CisKKwkgICAgamF2YTJtaW1lLnB1dCgiODg1OV80IiwgIklTTy04ODU5LTQiKTsKKwkgICAgamF2YTJtaW1lLnB1dCgiaXNvODg1OV80IiwgIklTTy04ODU5LTQiKTsKKwkgICAgamF2YTJtaW1lLnB1dCgiaXNvODg1OS00IiwgIklTTy04ODU5LTQiKTsKKworCSAgICBqYXZhMm1pbWUucHV0KCI4ODU5XzUiLCAiSVNPLTg4NTktNSIpOworCSAgICBqYXZhMm1pbWUucHV0KCJpc284ODU5XzUiLCAiSVNPLTg4NTktNSIpOworCSAgICBqYXZhMm1pbWUucHV0KCJpc284ODU5LTUiLCAiSVNPLTg4NTktNSIpOworCisJICAgIGphdmEybWltZS5wdXQoIjg4NTlfNiIsICJJU08tODg1OS02Iik7CisJICAgIGphdmEybWltZS5wdXQoImlzbzg4NTlfNiIsICJJU08tODg1OS02Iik7CisJICAgIGphdmEybWltZS5wdXQoImlzbzg4NTktNiIsICJJU08tODg1OS02Iik7CisKKwkgICAgamF2YTJtaW1lLnB1dCgiODg1OV83IiwgIklTTy04ODU5LTciKTsKKwkgICAgamF2YTJtaW1lLnB1dCgiaXNvODg1OV83IiwgIklTTy04ODU5LTciKTsKKwkgICAgamF2YTJtaW1lLnB1dCgiaXNvODg1OS03IiwgIklTTy04ODU5LTciKTsKKworCSAgICBqYXZhMm1pbWUucHV0KCI4ODU5XzgiLCAiSVNPLTg4NTktOCIpOworCSAgICBqYXZhMm1pbWUucHV0KCJpc284ODU5XzgiLCAiSVNPLTg4NTktOCIpOworCSAgICBqYXZhMm1pbWUucHV0KCJpc284ODU5LTgiLCAiSVNPLTg4NTktOCIpOworCisJICAgIGphdmEybWltZS5wdXQoIjg4NTlfOSIsICJJU08tODg1OS05Iik7CisJICAgIGphdmEybWltZS5wdXQoImlzbzg4NTlfOSIsICJJU08tODg1OS05Iik7CisJICAgIGphdmEybWltZS5wdXQoImlzbzg4NTktOSIsICJJU08tODg1OS05Iik7CisKKwkgICAgamF2YTJtaW1lLnB1dCgic2ppcyIsICJTaGlmdF9KSVMiKTsKKwkgICAgamF2YTJtaW1lLnB1dCgiamlzIiwgIklTTy0yMDIyLUpQIik7CisJICAgIGphdmEybWltZS5wdXQoImlzbzIwMjJqcCIsICJJU08tMjAyMi1KUCIpOworCSAgICBqYXZhMm1pbWUucHV0KCJldWNfanAiLCAiZXVjLWpwIik7CisJICAgIGphdmEybWltZS5wdXQoImtvaThfciIsICJrb2k4LXIiKTsKKwkgICAgamF2YTJtaW1lLnB1dCgiZXVjX2NuIiwgImV1Yy1jbiIpOworCSAgICBqYXZhMm1pbWUucHV0KCJldWNfdHciLCAiZXVjLXR3Iik7CisJICAgIGphdmEybWltZS5wdXQoImV1Y19rciIsICJldWMta3IiKTsKKwl9CisJaWYgKG1pbWUyamF2YS5pc0VtcHR5KCkpIHsKKwkgICAgbWltZTJqYXZhLnB1dCgiaXNvLTIwMjItY24iLCAiSVNPMjAyMkNOIik7CisJICAgIG1pbWUyamF2YS5wdXQoImlzby0yMDIyLWtyIiwgIklTTzIwMjJLUiIpOworCSAgICBtaW1lMmphdmEucHV0KCJ1dGYtOCIsICJVVEY4Iik7CisJICAgIG1pbWUyamF2YS5wdXQoInV0ZjgiLCAiVVRGOCIpOworCSAgICBtaW1lMmphdmEucHV0KCJqYV9qcC5pc28yMDIyLTciLCAiSVNPMjAyMkpQIik7CisJICAgIG1pbWUyamF2YS5wdXQoImphX2pwLmV1Y2pwIiwgIkVVQ0pJUyIpOworCSAgICBtaW1lMmphdmEucHV0KCJldWMta3IiLCAiS1NDNTYwMSIpOworCSAgICBtaW1lMmphdmEucHV0KCJldWNrciIsICJLU0M1NjAxIik7CisJICAgIG1pbWUyamF2YS5wdXQoInVzLWFzY2lpIiwgIklTTy04ODU5LTEiKTsKKwkgICAgbWltZTJqYXZhLnB1dCgieC11cy1hc2NpaSIsICJJU08tODg1OS0xIik7CisJICAgIG1pbWUyamF2YS5wdXQoImdiMjMxMiIsICJHQjE4MDMwIik7CisJICAgIG1pbWUyamF2YS5wdXQoImNwOTM2IiwgIkdCMTgwMzAiKTsKKwkgICAgbWltZTJqYXZhLnB1dCgibXM5MzYiLCAiR0IxODAzMCIpOworCSAgICBtaW1lMmphdmEucHV0KCJnYmsiLCAiR0IxODAzMCIpOworCX0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGxvYWRNYXBwaW5ncyhMaW5lSW5wdXRTdHJlYW0gaXMsCisJICAgIE1hcDxTdHJpbmcsIFN0cmluZz4gdGFibGUpIHsKKwlTdHJpbmcgY3VyckxpbmU7CisKKwl3aGlsZSAodHJ1ZSkgeworCSAgICB0cnkgeworCQljdXJyTGluZSA9IGlzLnJlYWRMaW5lKCk7CisJICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZXgpIHsKKwkJYnJlYWs7IC8vIGVycm9yIGluIHJlYWRpbmcsIHN0b3AKKwkgICAgfQorCisJICAgIGlmIChjdXJyTGluZSA9PSBudWxsKSAvLyBlbmQgb2YgZmlsZSwgc3RvcAorCQlicmVhazsKKwkgICAgaWYgKGN1cnJMaW5lLnN0YXJ0c1dpdGgoIi0tIikgJiYgY3VyckxpbmUuZW5kc1dpdGgoIi0tIikpCisJCS8vIGVuZCBvZiB0aGlzIHRhYmxlCisJCWJyZWFrOwkKKworCSAgICAvLyBpZ25vcmUgZW1wdHkgbGluZXMgYW5kIGNvbW1lbnRzCisJICAgIGlmIChjdXJyTGluZS50cmltKCkubGVuZ3RoKCkgPT0gMCB8fCBjdXJyTGluZS5zdGFydHNXaXRoKCIjIikpCisJCWNvbnRpbnVlOworCSAgICAKKwkgICAgLy8gQSB2YWxpZCBlbnRyeSBpcyBvZiB0aGUgZm9ybSA8a2V5PjxzZXBhcmF0b3I+PHZhbHVlPgorCSAgICAvLyB3aGVyZSwgPHNlcGFyYXRvcj4gOj0gU1BBQ0UgfCBIVC4gUGFyc2UgdGhpcworCSAgICBTdHJpbmdUb2tlbml6ZXIgdGsgPSBuZXcgU3RyaW5nVG9rZW5pemVyKGN1cnJMaW5lLCAiIFx0Iik7CisJICAgIHRyeSB7CisJCVN0cmluZyBrZXkgPSB0ay5uZXh0VG9rZW4oKTsKKwkJU3RyaW5nIHZhbHVlID0gdGsubmV4dFRva2VuKCk7CisJCXRhYmxlLnB1dChrZXkudG9Mb3dlckNhc2UoTG9jYWxlLkVOR0xJU0gpLCB2YWx1ZSk7CisJICAgIH0gY2F0Y2ggKE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gbmV4KSB7IH0KKwl9CisgICAgfQorCisgICAgc3RhdGljIGZpbmFsIGludCBBTExfQVNDSUkgCQk9IDE7CisgICAgc3RhdGljIGZpbmFsIGludCBNT1NUTFlfQVNDSUkgCT0gMjsKKyAgICBzdGF0aWMgZmluYWwgaW50IE1PU1RMWV9OT05BU0NJSSAJPSAzOworCisgICAgLyoqIAorICAgICAqIENoZWNrIGlmIHRoZSBnaXZlbiBzdHJpbmcgY29udGFpbnMgbm9uIFVTLUFTQ0lJIGNoYXJhY3RlcnMuCisgICAgICogQHBhcmFtCXMJc3RyaW5nCisgICAgICogQHJldHVybgkJQUxMX0FTQ0lJIGlmIGFsbCBjaGFyYWN0ZXJzIGluIHRoZSBzdHJpbmcgCisgICAgICoJCQliZWxvbmcgdG8gdGhlIFVTLUFTQ0lJIGNoYXJzZXQuIE1PU1RMWV9BU0NJSQorICAgICAqCQkJaWYgbW9yZSB0aGFuIGhhbGYgb2YgdGhlIGF2YWlsYWJsZSBjaGFyYWN0ZXJzCisgICAgICoJCQlhcmUgVVMtQVNDSUkgY2hhcmFjdGVycy4gRWxzZSBNT1NUTFlfTk9OQVNDSUkuCisgICAgICovCisgICAgc3RhdGljIGludCBjaGVja0FzY2lpKFN0cmluZyBzKSB7CisJaW50IGFzY2lpID0gMCwgbm9uX2FzY2lpID0gMDsKKwlpbnQgbCA9IHMubGVuZ3RoKCk7CisKKwlmb3IgKGludCBpID0gMDsgaSA8IGw7IGkrKykgeworCSAgICBpZiAobm9uYXNjaWkoKGludClzLmNoYXJBdChpKSkpIC8vIG5vbi1hc2NpaQorCQlub25fYXNjaWkrKzsKKwkgICAgZWxzZQorCQlhc2NpaSsrOworCX0KKworCWlmIChub25fYXNjaWkgPT0gMCkKKwkgICAgcmV0dXJuIEFMTF9BU0NJSTsKKwlpZiAoYXNjaWkgPiBub25fYXNjaWkpCisJICAgIHJldHVybiBNT1NUTFlfQVNDSUk7CisKKwlyZXR1cm4gTU9TVExZX05PTkFTQ0lJOworICAgIH0KKworICAgIC8qKiAKKyAgICAgKiBDaGVjayBpZiB0aGUgZ2l2ZW4gYnl0ZSBhcnJheSBjb250YWlucyBub24gVVMtQVNDSUkgY2hhcmFjdGVycy4KKyAgICAgKiBAcGFyYW0JYglieXRlIGFycmF5CisgICAgICogQHJldHVybgkJQUxMX0FTQ0lJIGlmIGFsbCBjaGFyYWN0ZXJzIGluIHRoZSBzdHJpbmcgCisgICAgICoJCQliZWxvbmcgdG8gdGhlIFVTLUFTQ0lJIGNoYXJzZXQuIE1PU1RMWV9BU0NJSQorICAgICAqCQkJaWYgbW9yZSB0aGFuIGhhbGYgb2YgdGhlIGF2YWlsYWJsZSBjaGFyYWN0ZXJzCisgICAgICoJCQlhcmUgVVMtQVNDSUkgY2hhcmFjdGVycy4gRWxzZSBNT1NUTFlfTk9OQVNDSUkuCisgICAgICoKKyAgICAgKiBYWFggLSB0aGlzIG1ldGhvZCBpcyBubyBsb25nZXIgdXNlZAorICAgICAqLworICAgIHN0YXRpYyBpbnQgY2hlY2tBc2NpaShieXRlW10gYikgeworCWludCBhc2NpaSA9IDAsIG5vbl9hc2NpaSA9IDA7CisKKwlmb3IgKGludCBpPTA7IGkgPCBiLmxlbmd0aDsgaSsrKSB7CisJICAgIC8vIFRoZSAnJicgb3BlcmF0b3IgYXV0b21hdGljYWxseSBjYXVzZXMgYltpXSB0byBiZSBwcm9tb3RlZAorCSAgICAvLyB0byBhbiBpbnQsIGFuZCB3ZSBtYXNrIG91dCB0aGUgaGlnaGVyIGJ5dGVzIGluIHRoZSBpbnQgCisJICAgIC8vIHNvIHRoYXQgdGhlIHJlc3VsdGluZyB2YWx1ZSBpcyBub3QgYSBuZWdhdGl2ZSBpbnRlZ2VyLgorCSAgICBpZiAobm9uYXNjaWkoYltpXSAmIDB4ZmYpKSAvLyBub24tYXNjaWkKKwkJbm9uX2FzY2lpKys7CisJICAgIGVsc2UKKwkJYXNjaWkrKzsKKwl9CisJCisJaWYgKG5vbl9hc2NpaSA9PSAwKQorCSAgICByZXR1cm4gQUxMX0FTQ0lJOworCWlmIChhc2NpaSA+IG5vbl9hc2NpaSkKKwkgICAgcmV0dXJuIE1PU1RMWV9BU0NJSTsKKwkKKwlyZXR1cm4gTU9TVExZX05PTkFTQ0lJOworICAgIH0KKworICAgIC8qKiAKKyAgICAgKiBDaGVjayBpZiB0aGUgZ2l2ZW4gaW5wdXQgc3RyZWFtIGNvbnRhaW5zIG5vbiBVUy1BU0NJSSBjaGFyYWN0ZXJzLgorICAgICAqIFVwdG8gPGNvZGU+bWF4PC9jb2RlPiBieXRlcyBhcmUgY2hlY2tlZC4gSWYgPGNvZGU+bWF4PC9jb2RlPiBpcworICAgICAqIHNldCB0byA8Y29kZT5BTEw8L2NvZGU+LCB0aGVuIGFsbCB0aGUgYnl0ZXMgYXZhaWxhYmxlIGluIHRoaXMKKyAgICAgKiBpbnB1dCBzdHJlYW0gYXJlIGNoZWNrZWQuIElmIDxjb2RlPmJyZWFrT25Ob25Bc2NpaTwvY29kZT4gaXMgdHJ1ZQorICAgICAqIHRoZSBjaGVjayB0ZXJtaW5hdGVzIHdoZW4gdGhlIGZpcnN0IG5vbi1VUy1BU0NJSSBjaGFyYWN0ZXIgaXMKKyAgICAgKiBmb3VuZCBhbmQgTU9TVExZX05PTkFTQ0lJIGlzIHJldHVybmVkLiBFbHNlLCB0aGUgY2hlY2sgY29udGludWVzCisgICAgICogdGlsbCA8Y29kZT5tYXg8L2NvZGU+IGJ5dGVzIG9yIHRpbGwgdGhlIGVuZCBvZiBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAcGFyYW0JaXMJdGhlIGlucHV0IHN0cmVhbQorICAgICAqIEBwYXJhbQltYXgJbWF4aW11bSBieXRlcyB0byBjaGVjayBmb3IuIFRoZSBzcGVjaWFsIHZhbHVlCisgICAgICoJCQlBTEwgaW5kaWNhdGVzIHRoYXQgYWxsIHRoZSBieXRlcyBpbiB0aGlzIGlucHV0CisgICAgICoJCQlzdHJlYW0gbXVzdCBiZSBjaGVja2VkLgorICAgICAqIEBwYXJhbQlicmVha09uTm9uQXNjaWkgaWYgPGNvZGU+dHJ1ZTwvY29kZT4sIHRoZW4gdGVybWluYXRlIHRoZQorICAgICAqCQkJdGhlIGNoZWNrIHdoZW4gdGhlIGZpcnN0IG5vbi1VUy1BU0NJSSBjaGFyYWN0ZXIKKyAgICAgKgkJCWlzIGZvdW5kLgorICAgICAqIEByZXR1cm4JCUFMTF9BU0NJSSBpZiBhbGwgY2hhcmFjdGVycyBpbiB0aGUgc3RyaW5nIAorICAgICAqCQkJYmVsb25nIHRvIHRoZSBVUy1BU0NJSSBjaGFyc2V0LiBNT1NUTFlfQVNDSUkKKyAgICAgKgkJCWlmIG1vcmUgdGhhbiBoYWxmIG9mIHRoZSBhdmFpbGFibGUgY2hhcmFjdGVycworICAgICAqCQkJYXJlIFVTLUFTQ0lJIGNoYXJhY3RlcnMuIEVsc2UgTU9TVExZX05PTkFTQ0lJLgorICAgICAqLworICAgIHN0YXRpYyBpbnQgY2hlY2tBc2NpaShJbnB1dFN0cmVhbSBpcywgaW50IG1heCwgYm9vbGVhbiBicmVha09uTm9uQXNjaWkpIHsKKwlpbnQgYXNjaWkgPSAwLCBub25fYXNjaWkgPSAwOworCWludCBsZW47CisJaW50IGJsb2NrID0gNDA5NjsKKwlpbnQgbGluZWxlbiA9IDA7CisJYm9vbGVhbiBsb25nTGluZSA9IGZhbHNlLCBiYWRFT0wgPSBmYWxzZTsKKwlib29sZWFuIGNoZWNrRU9MID0gZW5jb2RlRW9sU3RyaWN0ICYmIGJyZWFrT25Ob25Bc2NpaTsKKwlieXRlIGJ1ZltdID0gbnVsbDsKKwlpZiAobWF4ICE9IDApIHsKKwkgICAgYmxvY2sgPSAobWF4ID09IEFMTCkgPyA0MDk2IDogTWF0aC5taW4obWF4LCA0MDk2KTsKKwkgICAgYnVmID0gbmV3IGJ5dGVbYmxvY2tdOyAKKwl9CisJd2hpbGUgKG1heCAhPSAwKSB7CisJICAgIHRyeSB7CisJCWlmICgobGVuID0gaXMucmVhZChidWYsIDAsIGJsb2NrKSkgPT0gLTEpCisJCSAgICBicmVhazsKKwkJaW50IGxhc3RiID0gMDsKKwkJZm9yIChpbnQgaSA9IDA7IGkgPCBsZW47IGkrKykgeworCSAgICAJICAgIC8vIFRoZSAnJicgb3BlcmF0b3IgYXV0b21hdGljYWxseSBjYXVzZXMgYltpXSB0byAKKwkJICAgIC8vIGJlIHByb21vdGVkIHRvIGFuIGludCwgYW5kIHdlIG1hc2sgb3V0IHRoZSBoaWdoZXIKKwkJICAgIC8vIGJ5dGVzIGluIHRoZSBpbnQgc28gdGhhdCB0aGUgcmVzdWx0aW5nIHZhbHVlIGlzIAorCQkgICAgLy8gbm90IGEgbmVnYXRpdmUgaW50ZWdlci4KKwkJICAgIGludCBiID0gYnVmW2ldICYgMHhmZjsKKwkJICAgIGlmIChjaGVja0VPTCAmJgorCQkJICAgICgobGFzdGIgPT0gJ1xyJyAmJiBiICE9ICdcbicpIHx8CisJCQkgICAgKGxhc3RiICE9ICdccicgJiYgYiA9PSAnXG4nKSkpCisJCQliYWRFT0wgPSB0cnVlOworCQkgICAgaWYgKGIgPT0gJ1xyJyB8fCBiID09ICdcbicpCisJCQlsaW5lbGVuID0gMDsKKwkJICAgIGVsc2UgeworCQkJbGluZWxlbisrOworCQkJaWYgKGxpbmVsZW4gPiA5OTgpCS8vIDEwMDAgLSBDUkxGCisJCQkgICAgbG9uZ0xpbmUgPSB0cnVlOworCQkgICAgfQorCQkgICAgaWYgKG5vbmFzY2lpKGIpKSB7CS8vIG5vbi1hc2NpaQorCQkgICAgICAgIGlmIChicmVha09uTm9uQXNjaWkpIC8vIHdlIGFyZSBkb25lCisJCQkgICAgcmV0dXJuIE1PU1RMWV9OT05BU0NJSTsKKwkJICAgICAgICBlbHNlCisJCQkgICAgbm9uX2FzY2lpKys7CisJCSAgICB9IGVsc2UKKwkJICAgICAgICBhc2NpaSsrOworCQkgICAgbGFzdGIgPSBiOworCQl9CisJICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZXgpIHsKKwkJYnJlYWs7CisJICAgIH0KKwkgICAgaWYgKG1heCAhPSBBTEwpCisJCW1heCAtPSBsZW47CisJfQorCisJaWYgKG1heCA9PSAwICYmIGJyZWFrT25Ob25Bc2NpaSkKKwkgICAgLy8gV2UgaGF2ZSBiZWVuIHRvbGQgdG8gYnJlYWsgb24gdGhlIGZpcnN0IG5vbi1hc2NpaSBjaGFyYWN0ZXIuCisJICAgIC8vIFdlIGhhdmVuJ3QgZ290IGFueSBub24tYXNjaWkgY2hhcmFjdGVyIHlldCwgYnV0IHRoZW4gd2UKKwkgICAgLy8gaGF2ZSBub3QgY2hlY2tlZCBhbGwgb2YgdGhlIGF2YWlsYWJsZSBieXRlcyBlaXRoZXIuIFNvIHdlCisJICAgIC8vIGNhbm5vdCBzYXkgZm9yIHN1cmUgdGhhdCB0aGlzIGlucHV0IHN0cmVhbSBpcyBBTExfQVNDSUksCisJICAgIC8vIGFuZCBoZW5jZSB3ZSBtdXN0IHBsYXkgc2FmZSBhbmQgcmV0dXJuIE1PU1RMWV9OT05BU0NJSQorCisJICAgIHJldHVybiBNT1NUTFlfTk9OQVNDSUk7CisKKwlpZiAobm9uX2FzY2lpID09IDApIHsgLy8gbm8gbm9uLXVzLWFzY2lpIGNoYXJhY3RlcnMgc28gZmFyCisJICAgIC8vIElmIHdlJ3JlIGxvb2tpbmcgYXQgbm9uLXRleHQgZGF0YSwgYW5kIHdlIHNhdyBDUiB3aXRob3V0IExGCisJICAgIC8vIG9yIHZpY2UgdmVyc2EsIGNvbnNpZGVyIHRoaXMgbW9zdGx5IG5vbi1BU0NJSSBzbyB0aGF0IGl0CisJICAgIC8vIHdpbGwgYmUgYmFzZTY0IGVuY29kZWQgKHNpbmNlIHRoZSBxdW90ZWQtcHJpbnRhYmxlIGVuY29kZXIKKwkgICAgLy8gZG9lc24ndCBlbmNvZGUgdGhpcyBjYXNlIHByb3Blcmx5KS4KKwkgICAgaWYgKGJhZEVPTCkKKwkJcmV0dXJuIE1PU1RMWV9OT05BU0NJSTsKKwkgICAgLy8gaWYgd2UndmUgc2VlbiBhIGxvbmcgbGluZSwgd2UgZGVncmFkZSB0byBtb3N0bHkgYXNjaWkKKwkgICAgZWxzZSBpZiAobG9uZ0xpbmUpCisJCXJldHVybiBNT1NUTFlfQVNDSUk7CisJICAgIGVsc2UKKwkJcmV0dXJuIEFMTF9BU0NJSTsKKwl9CisJaWYgKGFzY2lpID4gbm9uX2FzY2lpKSAvLyBtb3N0bHkgYXNjaWkKKwkgICAgcmV0dXJuIE1PU1RMWV9BU0NJSTsKKwlyZXR1cm4gTU9TVExZX05PTkFTQ0lJOworICAgIH0KKworICAgIHN0YXRpYyBmaW5hbCBib29sZWFuIG5vbmFzY2lpKGludCBiKSB7CisJcmV0dXJuIGIgPj0gMDE3NyB8fCAoYiA8IDA0MCAmJiBiICE9ICdccicgJiYgYiAhPSAnXG4nICYmIGIgIT0gJ1x0Jyk7CisgICAgfQorfQorCisvKioKKyAqIEFuIE91dHB1dFN0cmVhbSB0aGF0IGRldGVybWluZXMgd2hldGhlciB0aGUgZGF0YSB3cml0dGVuIHRvCisgKiBpdCBpcyBhbGwgQVNDSUksIG1vc3RseSBBU0NJSSwgb3IgbW9zdGx5IG5vbi1BU0NJSS4KKyAqLworY2xhc3MgQXNjaWlPdXRwdXRTdHJlYW0gZXh0ZW5kcyBPdXRwdXRTdHJlYW0geworICAgIHByaXZhdGUgYm9vbGVhbiBicmVha09uTm9uQXNjaWk7CisgICAgcHJpdmF0ZSBpbnQgYXNjaWkgPSAwLCBub25fYXNjaWkgPSAwOworICAgIHByaXZhdGUgaW50IGxpbmVsZW4gPSAwOworICAgIHByaXZhdGUgYm9vbGVhbiBsb25nTGluZSA9IGZhbHNlOworICAgIHByaXZhdGUgYm9vbGVhbiBiYWRFT0wgPSBmYWxzZTsKKyAgICBwcml2YXRlIGJvb2xlYW4gY2hlY2tFT0wgPSBmYWxzZTsKKyAgICBwcml2YXRlIGludCBsYXN0YiA9IDA7CisgICAgcHJpdmF0ZSBpbnQgcmV0ID0gMDsKKworICAgIHB1YmxpYyBBc2NpaU91dHB1dFN0cmVhbShib29sZWFuIGJyZWFrT25Ob25Bc2NpaSwgYm9vbGVhbiBlbmNvZGVFb2xTdHJpY3QpIHsKKwl0aGlzLmJyZWFrT25Ob25Bc2NpaSA9IGJyZWFrT25Ob25Bc2NpaTsKKwljaGVja0VPTCA9IGVuY29kZUVvbFN0cmljdCAmJiBicmVha09uTm9uQXNjaWk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoaW50IGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJY2hlY2soYik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoYnl0ZSBiW10pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJd3JpdGUoYiwgMCwgYi5sZW5ndGgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGJ5dGUgYltdLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworCWxlbiArPSBvZmY7CisJZm9yIChpbnQgaSA9IG9mZjsgaSA8IGxlbiA7IGkrKykKKwkgICAgY2hlY2soYltpXSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBmaW5hbCB2b2lkIGNoZWNrKGludCBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworCWIgJj0gMHhmZjsKKwlpZiAoY2hlY2tFT0wgJiYKKwkJKChsYXN0YiA9PSAnXHInICYmIGIgIT0gJ1xuJykgfHwgKGxhc3RiICE9ICdccicgJiYgYiA9PSAnXG4nKSkpCisJICAgIGJhZEVPTCA9IHRydWU7CisJaWYgKGIgPT0gJ1xyJyB8fCBiID09ICdcbicpCisJICAgIGxpbmVsZW4gPSAwOworCWVsc2UgeworCSAgICBsaW5lbGVuKys7CisJICAgIGlmIChsaW5lbGVuID4gOTk4KQkvLyAxMDAwIC0gQ1JMRgorCQlsb25nTGluZSA9IHRydWU7CisJfQorCWlmIChNaW1lVXRpbGl0eS5ub25hc2NpaShiKSkgeyAvLyBub24tYXNjaWkKKwkgICAgbm9uX2FzY2lpKys7CisJICAgIGlmIChicmVha09uTm9uQXNjaWkpIHsJLy8gd2UgYXJlIGRvbmUKKwkJcmV0ID0gTWltZVV0aWxpdHkuTU9TVExZX05PTkFTQ0lJOworCQl0aHJvdyBuZXcgRU9GRXhjZXB0aW9uKCk7CisJICAgIH0KKwl9IGVsc2UKKwkgICAgYXNjaWkrKzsKKwlsYXN0YiA9IGI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIEFTQ0lJLW5lc3Mgb2YgZGF0YSBzdHJlYW0uCisgICAgICovCisgICAgcHVibGljIGludCBnZXRBc2NpaSgpIHsKKwlpZiAocmV0ICE9IDApCisJICAgIHJldHVybiByZXQ7CisJLy8gSWYgd2UncmUgbG9va2luZyBhdCBub24tdGV4dCBkYXRhLCBhbmQgd2Ugc2F3IENSIHdpdGhvdXQgTEYKKwkvLyBvciB2aWNlIHZlcnNhLCBjb25zaWRlciB0aGlzIG1vc3RseSBub24tQVNDSUkgc28gdGhhdCBpdAorCS8vIHdpbGwgYmUgYmFzZTY0IGVuY29kZWQgKHNpbmNlIHRoZSBxdW90ZWQtcHJpbnRhYmxlIGVuY29kZXIKKwkvLyBkb2Vzbid0IGVuY29kZSB0aGlzIGNhc2UgcHJvcGVybHkpLgorCWlmIChiYWRFT0wpCisJICAgIHJldHVybiBNaW1lVXRpbGl0eS5NT1NUTFlfTk9OQVNDSUk7CisJZWxzZSBpZiAobm9uX2FzY2lpID09IDApIHsgLy8gbm8gbm9uLXVzLWFzY2lpIGNoYXJhY3RlcnMgc28gZmFyCisJICAgIC8vIGlmIHdlJ3ZlIHNlZW4gYSBsb25nIGxpbmUsIHdlIGRlZ3JhZGUgdG8gbW9zdGx5IGFzY2lpCisJICAgIGlmIChsb25nTGluZSkKKwkJcmV0dXJuIE1pbWVVdGlsaXR5Lk1PU1RMWV9BU0NJSTsKKwkgICAgZWxzZQorCQlyZXR1cm4gTWltZVV0aWxpdHkuQUxMX0FTQ0lJOworCX0KKwlpZiAoYXNjaWkgPiBub25fYXNjaWkpIC8vIG1vc3RseSBhc2NpaQorCSAgICByZXR1cm4gTWltZVV0aWxpdHkuTU9TVExZX0FTQ0lJOworCXJldHVybiBNaW1lVXRpbGl0eS5NT1NUTFlfTk9OQVNDSUk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvTmV3c0FkZHJlc3MuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2ludGVybmV0L05ld3NBZGRyZXNzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2NhMTQ4YgotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2ludGVybmV0L05ld3NBZGRyZXNzLmphdmEKQEAgLTAsMCArMSwyMDIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5pbnRlcm5ldDsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLlN0cmluZ1Rva2VuaXplcjsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworaW1wb3J0IGphdmF4Lm1haWwuKjsKKworLyoqCisgKiBUaGlzIGNsYXNzIG1vZGVscyBhbiBSRkMxMDM2IG5ld3Nncm91cCBhZGRyZXNzLgorICoKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKiBAYXV0aG9yIEpvaG4gTWFuaQorICovCisKK3B1YmxpYyBjbGFzcyBOZXdzQWRkcmVzcyBleHRlbmRzIEFkZHJlc3MgeworCisgICAgcHJvdGVjdGVkIFN0cmluZyBuZXdzZ3JvdXA7CisgICAgcHJvdGVjdGVkIFN0cmluZyBob3N0OwkvLyBtYXkgYmUgbnVsbAorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTQyMDM3OTcyOTk4MjQ2ODQxNDNMOworCisgICAgLyoqCisgICAgICogRGVmYXVsdCBjb25zdHJ1Y3Rvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgTmV3c0FkZHJlc3MoKSB7IH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCBhIE5ld3NBZGRyZXNzIHdpdGggdGhlIGdpdmVuIG5ld3Nncm91cC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuZXdzZ3JvdXAJdGhlIG5ld3Nncm91cAorICAgICAqLworICAgIHB1YmxpYyBOZXdzQWRkcmVzcyhTdHJpbmcgbmV3c2dyb3VwKSB7CisJdGhpcyhuZXdzZ3JvdXAsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCBhIE5ld3NBZGRyZXNzIHdpdGggdGhlIGdpdmVuIG5ld3Nncm91cCBhbmQgaG9zdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuZXdzZ3JvdXAJdGhlIG5ld3Nncm91cAorICAgICAqIEBwYXJhbSBob3N0CXRoZSBob3N0CisgICAgICovCisgICAgcHVibGljIE5ld3NBZGRyZXNzKFN0cmluZyBuZXdzZ3JvdXAsIFN0cmluZyBob3N0KSB7CisJLy8gWFhYIC0gdGhpcyBtZXRob2Qgc2hvdWxkIHRocm93IGFuIGV4Y2VwdGlvbiBzbyB3ZSBjYW4gcmVwb3J0CisJLy8gaWxsZWdhbCBhZGRyZXNzZXMsIGJ1dCBmb3Igbm93IGp1c3QgcmVtb3ZlIHdoaXRlc3BhY2UKKwl0aGlzLm5ld3Nncm91cCA9IG5ld3Nncm91cC5yZXBsYWNlQWxsKCJcXHMrIiwgIiIpOworCXRoaXMuaG9zdCA9IGhvc3Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSB0eXBlIG9mIHRoaXMgYWRkcmVzcy4gIFRoZSB0eXBlIG9mIGEgTmV3c0FkZHJlc3MKKyAgICAgKiBpcyAibmV3cyIuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXRUeXBlKCkgeworCXJldHVybiAibmV3cyI7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBuZXdzZ3JvdXAuCisgICAgICoKKyAgICAgKiBAcGFyYW0JbmV3c2dyb3VwCXRoZSBuZXdzZ3JvdXAKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXROZXdzZ3JvdXAoU3RyaW5nIG5ld3Nncm91cCkgeworCXRoaXMubmV3c2dyb3VwID0gbmV3c2dyb3VwOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgbmV3c2dyb3VwLgorICAgICAqCisgICAgICogQHJldHVybgluZXdzZ3JvdXAKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldE5ld3Nncm91cCgpIHsKKwlyZXR1cm4gbmV3c2dyb3VwOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgaG9zdC4KKyAgICAgKgorICAgICAqIEBwYXJhbQlob3N0CXRoZSBob3N0CisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0SG9zdChTdHJpbmcgaG9zdCkgeworCXRoaXMuaG9zdCA9IGhvc3Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBob3N0LgorICAgICAqCisgICAgICogQHJldHVybglob3N0CisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRIb3N0KCkgeworCXJldHVybiBob3N0OworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlcnQgdGhpcyBhZGRyZXNzIGludG8gYSBSRkMgMTAzNiBhZGRyZXNzLgorICAgICAqCisgICAgICogQHJldHVybgkJbmV3c2dyb3VwCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKwlyZXR1cm4gbmV3c2dyb3VwOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBlcXVhbGl0eSBvcGVyYXRvci4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IGEpIHsKKwlpZiAoIShhIGluc3RhbmNlb2YgTmV3c0FkZHJlc3MpKQorCSAgICByZXR1cm4gZmFsc2U7CisKKwlOZXdzQWRkcmVzcyBzID0gKE5ld3NBZGRyZXNzKWE7CisJcmV0dXJuICgobmV3c2dyb3VwID09IG51bGwgJiYgcy5uZXdzZ3JvdXAgPT0gbnVsbCkgfHwKKwkgICAgIChuZXdzZ3JvdXAgIT0gbnVsbCAmJiBuZXdzZ3JvdXAuZXF1YWxzKHMubmV3c2dyb3VwKSkpICYmCisJICAgICgoaG9zdCA9PSBudWxsICYmIHMuaG9zdCA9PSBudWxsKSB8fAorCSAgICAgKGhvc3QgIT0gbnVsbCAmJiBzLmhvc3QgIT0gbnVsbCAmJiBob3N0LmVxdWFsc0lnbm9yZUNhc2Uocy5ob3N0KSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXB1dGUgYSBoYXNoIGNvZGUgZm9yIHRoZSBhZGRyZXNzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisJaW50IGhhc2ggPSAwOworCWlmIChuZXdzZ3JvdXAgIT0gbnVsbCkKKwkgICAgaGFzaCArPSBuZXdzZ3JvdXAuaGFzaENvZGUoKTsKKwlpZiAoaG9zdCAhPSBudWxsKQorCSAgICBoYXNoICs9IGhvc3QudG9Mb3dlckNhc2UoTG9jYWxlLkVOR0xJU0gpLmhhc2hDb2RlKCk7CisJcmV0dXJuIGhhc2g7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29udmVydCB0aGUgZ2l2ZW4gYXJyYXkgb2YgTmV3c0FkZHJlc3Mgb2JqZWN0cyBpbnRvCisgICAgICogYSBjb21tYSBzZXBhcmF0ZWQgc2VxdWVuY2Ugb2YgYWRkcmVzcyBzdHJpbmdzLiBUaGUKKyAgICAgKiByZXN1bHRpbmcgc3RyaW5nIGNvbnRhaW5zIG9ubHkgVVMtQVNDSUkgY2hhcmFjdGVycywgYW5kCisgICAgICogaGVuY2UgaXMgbWFpbC1zYWZlLgorICAgICAqCisgICAgICogQHBhcmFtIGFkZHJlc3NlcwlhcnJheSBvZiBOZXdzQWRkcmVzcyBvYmplY3RzCisgICAgICogQGV4Y2VwdGlvbiAgIAlDbGFzc0Nhc3RFeGNlcHRpb24gaWYgYW55IGFkZHJlc3Mgb2JqZWN0IGluIHRoZQorICAgICAqICAgICAgICAgICAgICAJZ2l2ZW4gYXJyYXkgaXMgbm90IGEgTmV3c0FkZHJlc3Mgb2JqZWN0cy4gTm90ZQorICAgICAqICAgICAgICAgICAgICAJdGhhdCB0aGlzIGlzIGEgUnVudGltZUV4Y2VwdGlvbi4KKyAgICAgKiBAcmV0dXJuCSAgICAJY29tbWEgc2VwYXJhdGVkIGFkZHJlc3Mgc3RyaW5ncworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHRvU3RyaW5nKEFkZHJlc3NbXSBhZGRyZXNzZXMpIHsKKwlpZiAoYWRkcmVzc2VzID09IG51bGwgfHwgYWRkcmVzc2VzLmxlbmd0aCA9PSAwKQorCSAgICByZXR1cm4gbnVsbDsKKworCVN0cmluZ0J1aWxkZXIgcyA9CisJCW5ldyBTdHJpbmdCdWlsZGVyKCgoTmV3c0FkZHJlc3MpYWRkcmVzc2VzWzBdKS50b1N0cmluZygpKTsKKwlpbnQgdXNlZCA9IHMubGVuZ3RoKCk7CisJZm9yIChpbnQgaSA9IDE7IGkgPCBhZGRyZXNzZXMubGVuZ3RoOyBpKyspIHsKKwkgICAgcy5hcHBlbmQoIiwiKTsKKwkgICAgdXNlZCsrOworCSAgICBTdHJpbmcgbmcgPSAoKE5ld3NBZGRyZXNzKWFkZHJlc3Nlc1tpXSkudG9TdHJpbmcoKTsKKwkgICAgaWYgKHVzZWQgKyBuZy5sZW5ndGgoKSA+IDc2KSB7CisJCXMuYXBwZW5kKCJcclxuXHQiKTsKKwkJdXNlZCA9IDg7CisJICAgIH0KKwkgICAgcy5hcHBlbmQobmcpOworCSAgICB1c2VkICs9IG5nLmxlbmd0aCgpOworCX0KKwkKKwlyZXR1cm4gcy50b1N0cmluZygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBhcnNlIHRoZSBnaXZlbiBjb21tYSBzZXBhcmF0ZWQgc2VxdWVuY2Ugb2YgbmV3c2dyb3VwcyBpbnRvCisgICAgICogTmV3c0FkZHJlc3Mgb2JqZWN0cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuZXdzZ3JvdXBzCWNvbW1hIHNlcGFyYXRlZCBuZXdzZ3JvdXAgc3RyaW5nCisgICAgICogQHJldHVybgkJCWFycmF5IG9mIE5ld3NBZGRyZXNzIG9iamVjdHMKKyAgICAgKiBAZXhjZXB0aW9uCQlBZGRyZXNzRXhjZXB0aW9uIGlmIHRoZSBwYXJzZSBmYWlsZWQKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIE5ld3NBZGRyZXNzW10gcGFyc2UoU3RyaW5nIG5ld3Nncm91cHMpIAorCQkJCXRocm93cyBBZGRyZXNzRXhjZXB0aW9uIHsKKwkvLyBYWFggLSB2ZXJpZnkgZm9ybWF0IG9mIG5ld3Nncm91cCBuYW1lPworCVN0cmluZ1Rva2VuaXplciBzdCA9IG5ldyBTdHJpbmdUb2tlbml6ZXIobmV3c2dyb3VwcywgIiwiKTsKKwlMaXN0PE5ld3NBZGRyZXNzPiBuZ2xpc3QgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKwl3aGlsZSAoc3QuaGFzTW9yZVRva2VucygpKSB7CisJICAgIFN0cmluZyBuZyA9IHN0Lm5leHRUb2tlbigpOworCSAgICBuZ2xpc3QuYWRkKG5ldyBOZXdzQWRkcmVzcyhuZykpOworCX0KKwlyZXR1cm4gbmdsaXN0LnRvQXJyYXkobmV3IE5ld3NBZGRyZXNzW25nbGlzdC5zaXplKCldKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9QYXJhbWV0ZXJMaXN0LmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9QYXJhbWV0ZXJMaXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTUwOWIzOQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2ludGVybmV0L1BhcmFtZXRlckxpc3QuamF2YQpAQCAtMCwwICsxLDg5MyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsLmludGVybmV0OworCitpbXBvcnQgamF2YS51dGlsLio7CitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLlByb3BVdGlsOworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLkFTQ0lJVXRpbGl0eTsKKworLyoqCisgKiBUaGlzIGNsYXNzIGhvbGRzIE1JTUUgcGFyYW1ldGVycyAoYXR0cmlidXRlLXZhbHVlIHBhaXJzKS4KKyAqIFRoZSA8Y29kZT5tYWlsLm1pbWUuZW5jb2RlcGFyYW1ldGVyczwvY29kZT4gYW5kCisgKiA8Y29kZT5tYWlsLm1pbWUuZGVjb2RlcGFyYW1ldGVyczwvY29kZT4gU3lzdGVtIHByb3BlcnRpZXMKKyAqIGNvbnRyb2wgd2hldGhlciBlbmNvZGVkIHBhcmFtZXRlcnMsIGFzIHNwZWNpZmllZCBieSAKKyAqIDxhIGhyZWY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIyMzEudHh0IiB0YXJnZXQ9Il90b3AiPlJGQyAyMjMxPC9hPiwKKyAqIGFyZSBzdXBwb3J0ZWQuICBCeSBkZWZhdWx0LCBzdWNoIGVuY29kZWQgcGFyYW1ldGVycyA8Yj5hcmU8L2I+CisgKiBzdXBwb3J0ZWQuIDxwPgorICoKKyAqIEFsc28sIGluIHRoZSBjdXJyZW50IGltcGxlbWVudGF0aW9uLCBzZXR0aW5nIHRoZSBTeXN0ZW0gcHJvcGVydHkKKyAqIDxjb2RlPm1haWwubWltZS5kZWNvZGVwYXJhbWV0ZXJzLnN0cmljdDwvY29kZT4gdG8gPGNvZGU+InRydWUiPC9jb2RlPgorICogd2lsbCBjYXVzZSBhIDxjb2RlPlBhcnNlRXhjZXB0aW9uPC9jb2RlPiB0byBiZSB0aHJvd24gZm9yIGVycm9ycworICogZGV0ZWN0ZWQgd2hpbGUgZGVjb2RpbmcgZW5jb2RlZCBwYXJhbWV0ZXJzLiAgQnkgZGVmYXVsdCwgaWYgYW55CisgKiBkZWNvZGluZyBlcnJvcnMgb2NjdXIsIHRoZSBvcmlnaW5hbCAodW5kZWNvZGVkKSBzdHJpbmcgaXMgdXNlZC4gPHA+CisgKgorICogVGhlIGN1cnJlbnQgaW1wbGVtZW50YXRpb24gc3VwcG9ydHMgdGhlIFN5c3RlbSBwcm9wZXJ0eQorICogPGNvZGU+bWFpbC5taW1lLnBhcmFtZXRlcnMuc3RyaWN0PC9jb2RlPiwgd2hpY2ggaWYgc2V0IHRvIGZhbHNlCisgKiB3aGVuIHBhcnNpbmcgYSBwYXJhbWV0ZXIgbGlzdCBhbGxvd3MgcGFyYW1ldGVyIHZhbHVlcworICogdG8gY29udGFpbiB3aGl0ZXNwYWNlIGFuZCBvdGhlciBzcGVjaWFsIGNoYXJhY3RlcnMgd2l0aG91dAorICogYmVpbmcgcXVvdGVkOyB0aGUgcGFyYW1ldGVyIHZhbHVlIGVuZHMgYXQgdGhlIG5leHQgc2VtaWNvbG9uLgorICogSWYgc2V0IHRvIHRydWUgKHRoZSBkZWZhdWx0KSwgcGFyYW1ldGVyIHZhbHVlcyBhcmUgcmVxdWlyZWQgdG8gY29uZm9ybQorICogdG8gdGhlIE1JTUUgc3BlY2lmaWNhdGlvbiBhbmQgbXVzdCBiZSBxdW90ZWQgaWYgdGhleSBjb250YWluIHdoaXRlc3BhY2UKKyAqIG9yIHNwZWNpYWwgY2hhcmFjdGVycy4KKyAqCisgKiBAYXV0aG9yICBKb2huIE1hbmkKKyAqIEBhdXRob3IgIEJpbGwgU2hhbm5vbgorICovCisKK3B1YmxpYyBjbGFzcyBQYXJhbWV0ZXJMaXN0IHsKKworICAgIC8qKgorICAgICAqIFRoZSBtYXAgb2YgbmFtZSwgdmFsdWUgcGFpcnMuCisgICAgICogVGhlIHZhbHVlIG9iamVjdCBpcyBlaXRoZXIgYSBTdHJpbmcsIGZvciB1bmVuY29kZWQKKyAgICAgKiB2YWx1ZXMsIG9yIGEgVmFsdWUgb2JqZWN0LCBmb3IgZW5jb2RlZCB2YWx1ZXMsCisgICAgICogb3IgYSBNdWx0aVZhbHVlIG9iamVjdCwgZm9yIG11bHRpLXNlZ21lbnQgcGFyYW1ldGVycywKKyAgICAgKiBvciBhIExpdGVyYWxWYWx1ZSBvYmplY3QgZm9yIHN0cmluZ3MgdGhhdCBzaG91bGQgbm90IGJlIGVuY29kZWQuCisgICAgICoKKyAgICAgKiBXZSB1c2UgYSBMaW5rZWRIYXNoTWFwIHNvIHRoYXQgcGFyYW1ldGVycyBhcmUgKGFzIG11Y2ggYXMKKyAgICAgKiBwb3NzaWJsZSkga2VwdCBpbiB0aGUgb3JpZ2luYWwgb3JkZXIuICBOb3RlIGhvd2V2ZXIgdGhhdAorICAgICAqIG11bHRpLXNlZ21lbnQgcGFyYW1ldGVycyAoc2VlIGJlbG93KSB3aWxsIGFwcGVhciBpbiB0aGUKKyAgICAgKiBwb3NpdGlvbiBvZiB0aGUgZmlyc3Qgc2VlbiBzZWdtZW50IGFuZCBvcnBoYW4gc2VnbWVudHMKKyAgICAgKiB3aWxsIGFsbCBtb3ZlIHRvIHRoZSBlbmQuCisgICAgICovCisgICAgLy8ga2VlcCBwYXJhbWV0ZXJzIGluIG9yZGVyCisgICAgcHJpdmF0ZSBNYXA8U3RyaW5nLCBPYmplY3Q+IGxpc3QgPSBuZXcgTGlua2VkSGFzaE1hcDw+KCk7CisKKyAgICAvKioKKyAgICAgKiBBIHNldCBvZiBuYW1lcyBmb3IgbXVsdGktc2VnbWVudCBwYXJhbWV0ZXJzIHRoYXQgd2UKKyAgICAgKiBoYXZlbid0IHByb2Nlc3NlZCB5ZXQuICBOb3JtYWxseSBzdWNoIG5hbWVzIGFyZSBhY2N1bXVsYXRlZAorICAgICAqIGR1cmluZyB0aGUgaW5pdGFsIHBhcnNlIGFuZCBwcm9jZXNzZWQgYXQgdGhlIGVuZCBvZiB0aGUgcGFyc2UsCisgICAgICogYnV0IHN1Y2ggbmFtZXMgY2FuIGFsc28gYmUgc2V0IHZpYSB0aGUgc2V0IG1ldGhvZCB3aGVuIHRoZQorICAgICAqIElNQVAgcHJvdmlkZXIgYWNjdW11bGF0ZXMgcHJlLXBhcnNlZCBwaWVjZXMgb2YgYSBwYXJhbWV0ZXIgbGlzdC4KKyAgICAgKiAoQSBzcGVjaWFsIGNhbGwgdG8gdGhlIHNldCBtZXRob2QgdGVsbHMgdXMgd2hlbiB0aGUgSU1BUCBwcm92aWRlcgorICAgICAqIGlzIGRvbmUgc2V0dGluZyBwYXJhbWV0ZXJzLikKKyAgICAgKgorICAgICAqIEEgbXVsdGktc2VnbWVudCBwYXJhbWV0ZXIgaXMgZGVmaW5lZCBieSBSRkMgMjIzMS4gIEZvciBleGFtcGxlLAorICAgICAqICJ0aXRsZSowPXBhcnQxOyB0aXRsZSoxPXBhcnQyIiwgd2hpY2ggcmVwcmVzZW50cyBhIHBhcmFtZXRlcgorICAgICAqIG5hbWVkICJ0aXRsZSIgd2l0aCB2YWx1ZSAicGFydDFwYXJ0MiIuCisgICAgICoKKyAgICAgKiBOb3RlIGFsc28gdGhhdCBlYWNoIHNlZ21lbnQgb2YgdGhlIHZhbHVlIG1pZ2h0IG9yIG1pZ2h0IG5vdCBiZQorICAgICAqIGVuY29kZWQsIGluZGljYXRlZCBieSBhIHRyYWlsaW5nICIqIiBvbiB0aGUgcGFyYW1ldGVyIG5hbWUuCisgICAgICogSWYgYW55IHNlZ21lbnQgaXMgZW5jb2RlZCwgdGhlIGZpcnN0IHNlZ21lbnQgbXVzdCBiZSBlbmNvZGVkLgorICAgICAqIE9ubHkgdGhlIGZpcnN0IHNlZ21lbnQgY29udGFpbnMgdGhlIGNoYXJzZXQgYW5kIGxhbmd1YWdlCisgICAgICogaW5mb3JtYXRpb24gbmVlZGVkIHRvIGRlY29kZSBhbnkgZW5jb2RlZCBzZWdtZW50cy4KKyAgICAgKgorICAgICAqIFJGQyAyMjMxIGludHJvZHVjZXMgbWFueSBwb3NzaWJsZSBmYWlsdXJlIG1vZGVzLCB3aGljaCB3ZSB0cnkKKyAgICAgKiB0byBoYW5kbGUgYXMgZ3JhY2VmdWxseSBhcyBwb3NzaWJsZS4gIEdlbmVyYWxseSwgYSBmYWlsdXJlIHRvCisgICAgICogZGVjb2RlIGEgcGFyYW1ldGVyIHZhbHVlIGNhdXNlcyB0aGUgbm9uLWRlY29kZWQgcGFyYW1ldGVyIHZhbHVlCisgICAgICogdG8gYmUgdXNlZCBpbnN0ZWFkLiAgTWlzc2luZyBzZWdtZW50cyBjYXVzZSBhbGwgbGF0ZXIgc2VnbWVudHMKKyAgICAgKiB0byBiZSBhcHBlYXIgYXMgaW5kZXBlbmRlbnQgcGFyYW1ldGVycyB3aXRoIG5hbWVzIHRoYXQgaW5jbHVkZQorICAgICAqIHRoZSBzZWdtZW50IG51bWJlci4gIEZvciBleGFtcGxlLCAidGl0bGUqMD1wYXJ0MTsgdGl0bGUqMT1wYXJ0MjsKKyAgICAgKiB0aXRsZSozPXBhcnQ0IiBhcHBlYXJzIGFzIHR3byBwYXJhbWV0ZXJzIG5hbWVkICJ0aXRsZSIgYW5kICJ0aXRsZSozIi4KKyAgICAgKi8KKyAgICBwcml2YXRlIFNldDxTdHJpbmc+IG11bHRpc2VnbWVudE5hbWVzOworCisgICAgLyoqCisgICAgICogQSBtYXAgY29udGFpbmluZyB0aGUgc2VnbWVudHMgZm9yIGFsbCBub3QteWV0LXByb2Nlc3NlZAorICAgICAqIG11bHRpLXNlZ21lbnQgcGFyYW1ldGVycy4gIFRoZSBtYXAgaXMgaW5kZXhlZCBieSAibmFtZSpzZWciLgorICAgICAqIFRoZSB2YWx1ZSBvYmplY3QgaXMgZWl0aGVyIGEgU3RyaW5nIG9yIGEgVmFsdWUgb2JqZWN0LgorICAgICAqIFRoZSBWYWx1ZSBvYmplY3QgaXMgbm90IGRlY29kZWQgZHVyaW5nIHRoZSBpbml0aWFsIHBhcnNlCisgICAgICogYmVjYXVzZSB0aGUgc2VnbWVudHMgbWF5IGFwcGVhciBpbiBhbnkgb3JkZXIgYW5kIHVudGlsIHRoZQorICAgICAqIGZpcnN0IHNlZ21lbnQgYXBwZWFycyB3ZSBkb24ndCBrbm93IHdoYXQgY2hhcnNldCB0byB1c2UgdG8KKyAgICAgKiBkZWNvZGUgdGhlIGVuY29kZWQgc2VnbWVudHMuICBUaGUgc2VnbWVudHMgYXJlIGhleCBkZWNvZGVkCisgICAgICogaW4gb3JkZXIsIGNvbWJpbmVkIGludG8gYSBzaW5nbGUgYnl0ZSBhcnJheSwgYW5kIGNvbnZlcnRlZAorICAgICAqIHRvIGEgU3RyaW5nIHVzaW5nIHRoZSBzcGVjaWZpZWQgY2hhcnNldCBpbiB0aGUKKyAgICAgKiBjb21iaW5lTXVsdGlzZWdtZW50TmFtZXMgbWV0aG9kLgorICAgICAqLworICAgIHByaXZhdGUgTWFwPFN0cmluZywgT2JqZWN0PiBzbGlzdDsKKworICAgIC8qKgorICAgICAqIE1XQiAzQlZpZXc6IFRoZSBuYW1lIG9mIHRoZSBsYXN0IHBhcmFtZXRlciBhZGRlZCB0byB0aGUgbWFwLgorICAgICAqIFVzZWQgZm9yIHRoZSBBcHBsZU1haWwgaGFjay4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyBsYXN0TmFtZSA9IG51bGw7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIGVuY29kZVBhcmFtZXRlcnMgPQorCVByb3BVdGlsLmdldEJvb2xlYW5TeXN0ZW1Qcm9wZXJ0eSgibWFpbC5taW1lLmVuY29kZXBhcmFtZXRlcnMiLCB0cnVlKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIGRlY29kZVBhcmFtZXRlcnMgPQorCVByb3BVdGlsLmdldEJvb2xlYW5TeXN0ZW1Qcm9wZXJ0eSgibWFpbC5taW1lLmRlY29kZXBhcmFtZXRlcnMiLCB0cnVlKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIGRlY29kZVBhcmFtZXRlcnNTdHJpY3QgPQorCVByb3BVdGlsLmdldEJvb2xlYW5TeXN0ZW1Qcm9wZXJ0eSgKKwkgICAgIm1haWwubWltZS5kZWNvZGVwYXJhbWV0ZXJzLnN0cmljdCIsIGZhbHNlKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIGFwcGxlaGFjayA9CisJUHJvcFV0aWwuZ2V0Qm9vbGVhblN5c3RlbVByb3BlcnR5KCJtYWlsLm1pbWUuYXBwbGVmaWxlbmFtZXMiLCBmYWxzZSk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiB3aW5kb3dzaGFjayA9CisJUHJvcFV0aWwuZ2V0Qm9vbGVhblN5c3RlbVByb3BlcnR5KCJtYWlsLm1pbWUud2luZG93c2ZpbGVuYW1lcyIsIGZhbHNlKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIHBhcmFtZXRlcnNTdHJpY3QgPSAKKwlQcm9wVXRpbC5nZXRCb29sZWFuU3lzdGVtUHJvcGVydHkoIm1haWwubWltZS5wYXJhbWV0ZXJzLnN0cmljdCIsIHRydWUpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gc3BsaXRMb25nUGFyYW1ldGVycyA9IAorCVByb3BVdGlsLmdldEJvb2xlYW5TeXN0ZW1Qcm9wZXJ0eSgKKwkgICAgIm1haWwubWltZS5zcGxpdGxvbmdwYXJhbWV0ZXJzIiwgdHJ1ZSk7CisKKworICAgIC8qKgorICAgICAqIEEgc3RydWN0IHRvIGhvbGQgYW4gZW5jb2RlZCB2YWx1ZS4KKyAgICAgKiBBIHBhcnNlZCBlbmNvZGVkIHZhbHVlIGlzIHN0b3JlZCBhcyBib3RoIHRoZQorICAgICAqIGRlY29kZWQgdmFsdWUgYW5kIHRoZSBvcmlnaW5hbCBlbmNvZGVkIHZhbHVlCisgICAgICogKHNvIHRoYXQgdG9TdHJpbmcgd2lsbCBwcm9kdWNlIHRoZSBzYW1lIHJlc3VsdCkuCisgICAgICogQW4gZW5jb2RlZCB2YWx1ZSB0aGF0IGlzIHNldCBleHBsaWNpdGx5IGlzIHN0b3JlZAorICAgICAqIGFzIHRoZSBvcmlnaW5hbCB2YWx1ZSBhbmQgdGhlIGVuY29kZWQgdmFsdWUsIHRvCisgICAgICogZW5zdXJlIHRoYXQgZ2V0IHdpbGwgcmV0dXJuIHRoZSBzYW1lIHZhbHVlIHRoYXQKKyAgICAgKiB3YXMgc2V0LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIFZhbHVlIHsKKwlTdHJpbmcgdmFsdWU7CisJU3RyaW5nIGNoYXJzZXQ7CisJU3RyaW5nIGVuY29kZWRWYWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBIHN0cnVjdCB0byBob2xkIGEgbGl0ZXJhbCB2YWx1ZSB0aGF0IHNob3VsZG4ndCBiZSBmdXJ0aGVyIGVuY29kZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgTGl0ZXJhbFZhbHVlIHsKKwlTdHJpbmcgdmFsdWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQSBzdHJ1Y3QgZm9yIGEgbXVsdGktc2VnbWVudCBwYXJhbWV0ZXIuICBFYWNoIGVudHJ5IGluIHRoZQorICAgICAqIExpc3QgaXMgZWl0aGVyIGEgU3RyaW5nIG9yIGEgVmFsdWUgb2JqZWN0LiAgV2hlbiBhbGwgdGhlCisgICAgICogc2VnbWVudHMgYXJlIHByZXNlbnQgYW5kIGNvbWJpbmVkIGluIHRoZSBjb21iaW5lTXVsdGlzZWdtZW50TmFtZXMKKyAgICAgKiBtZXRob2QsIHRoZSB2YWx1ZSBmaWVsZCBjb250YWlucyB0aGUgY29tYmluZWQgYW5kIGRlY29kZWQgdmFsdWUuCisgICAgICogVW50aWwgdGhlbiB0aGUgdmFsdWUgZmllbGQgY29udGFpbnMgYW4gZW1wdHkgc3RyaW5nIGFzIGEgcGxhY2Vob2xkZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgTXVsdGlWYWx1ZSBleHRlbmRzIEFycmF5TGlzdDxPYmplY3Q+IHsKKwkvLyBrZWVwIGxpbnQgaGFwcHkKKwlwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA2OTk1NjEwOTQ2MTg3NTEwMjNMOworCisJU3RyaW5nIHZhbHVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIE1hcCB0aGUgTGlua2VkSGFzaE1hcCdzIGtleVNldCBpdGVyYXRvciB0byBhbiBFbnVtZXJhdGlvbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBQYXJhbUVudW0gaW1wbGVtZW50cyBFbnVtZXJhdGlvbjxTdHJpbmc+IHsKKwlwcml2YXRlIEl0ZXJhdG9yPFN0cmluZz4gaXQ7CisKKwlQYXJhbUVudW0oSXRlcmF0b3I8U3RyaW5nPiBpdCkgeworCSAgICB0aGlzLml0ID0gaXQ7CisJfQorCisJQE92ZXJyaWRlCisJcHVibGljIGJvb2xlYW4gaGFzTW9yZUVsZW1lbnRzKCkgeworCSAgICByZXR1cm4gaXQuaGFzTmV4dCgpOworCX0KKworCUBPdmVycmlkZQorCXB1YmxpYyBTdHJpbmcgbmV4dEVsZW1lbnQoKSB7CisJICAgIHJldHVybiBpdC5uZXh0KCk7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIE5vLWFyZyBDb25zdHJ1Y3Rvci4KKyAgICAgKi8KKyAgICBwdWJsaWMgUGFyYW1ldGVyTGlzdCgpIHsgCisJLy8gaW5pdGlhbGl6ZSBvdGhlciBjb2xsZWN0aW9ucyBvbmx5IGlmIHRoZXknbGwgYmUgbmVlZGVkCisJaWYgKGRlY29kZVBhcmFtZXRlcnMpIHsKKwkgICAgbXVsdGlzZWdtZW50TmFtZXMgPSBuZXcgSGFzaFNldDw+KCk7CisJICAgIHNsaXN0ID0gbmV3IEhhc2hNYXA8PigpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvciB0aGF0IHRha2VzIGEgcGFyYW1ldGVyLWxpc3Qgc3RyaW5nLiBUaGUgU3RyaW5nCisgICAgICogaXMgcGFyc2VkIGFuZCB0aGUgcGFyYW1ldGVycyBhcmUgY29sbGVjdGVkIGFuZCBzdG9yZWQgaW50ZXJuYWxseS4KKyAgICAgKiBBIFBhcnNlRXhjZXB0aW9uIGlzIHRocm93biBpZiB0aGUgcGFyc2UgZmFpbHMuIAorICAgICAqIE5vdGUgdGhhdCBhbiBlbXB0eSBwYXJhbWV0ZXItbGlzdCBzdHJpbmcgaXMgdmFsaWQgYW5kIHdpbGwgYmUgCisgICAgICogcGFyc2VkIGludG8gYW4gZW1wdHkgUGFyYW1ldGVyTGlzdC4KKyAgICAgKgorICAgICAqIEBwYXJhbQlzCXRoZSBwYXJhbWV0ZXItbGlzdCBzdHJpbmcuCisgICAgICogQGV4Y2VwdGlvbglQYXJzZUV4Y2VwdGlvbiBpZiB0aGUgcGFyc2UgZmFpbHMuCisgICAgICovCisgICAgcHVibGljIFBhcmFtZXRlckxpc3QoU3RyaW5nIHMpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CisJdGhpcygpOworCisJSGVhZGVyVG9rZW5pemVyIGggPSBuZXcgSGVhZGVyVG9rZW5pemVyKHMsIEhlYWRlclRva2VuaXplci5NSU1FKTsKKwlmb3IgKDs7KSB7CisJICAgIEhlYWRlclRva2VuaXplci5Ub2tlbiB0ayA9IGgubmV4dCgpOworCSAgICBpbnQgdHlwZSA9IHRrLmdldFR5cGUoKTsKKwkgICAgU3RyaW5nIG5hbWUsIHZhbHVlOworCisJICAgIGlmICh0eXBlID09IEhlYWRlclRva2VuaXplci5Ub2tlbi5FT0YpIC8vIGRvbmUKKwkJYnJlYWs7CisKKwkgICAgaWYgKChjaGFyKXR5cGUgPT0gJzsnKSB7CisJCS8vIGV4cGVjdCBwYXJhbWV0ZXIgbmFtZQorCQl0ayA9IGgubmV4dCgpOworCQkvLyB0b2xlcmF0ZSB0cmFpbGluZyBzZW1pY29sb24sIGV2ZW4gdGhvdWdoIGl0IHZpb2xhdGVzIHRoZSBzcGVjCisJCWlmICh0ay5nZXRUeXBlKCkgPT0gSGVhZGVyVG9rZW5pemVyLlRva2VuLkVPRikKKwkJICAgIGJyZWFrOworCQkvLyBwYXJhbWV0ZXIgbmFtZSBtdXN0IGJlIGEgTUlNRSBBdG9tCisJCWlmICh0ay5nZXRUeXBlKCkgIT0gSGVhZGVyVG9rZW5pemVyLlRva2VuLkFUT00pCisJCSAgICB0aHJvdyBuZXcgUGFyc2VFeGNlcHRpb24oIkluIHBhcmFtZXRlciBsaXN0IDwiICsgcyArICI+IiArCisJCQkJCSAgICAiLCBleHBlY3RlZCBwYXJhbWV0ZXIgbmFtZSwgIiArCisJCQkJCSAgICAiZ290IFwiIiArIHRrLmdldFZhbHVlKCkgKyAiXCIiKTsKKwkJbmFtZSA9IHRrLmdldFZhbHVlKCkudG9Mb3dlckNhc2UoTG9jYWxlLkVOR0xJU0gpOworCisJCS8vIGV4cGVjdCAnPScKKwkJdGsgPSBoLm5leHQoKTsKKwkJaWYgKChjaGFyKXRrLmdldFR5cGUoKSAhPSAnPScpCisJCSAgICB0aHJvdyBuZXcgUGFyc2VFeGNlcHRpb24oIkluIHBhcmFtZXRlciBsaXN0IDwiICsgcyArICI+IiArCisJCQkJCSAgICAiLCBleHBlY3RlZCAnPScsICIgKworCQkJCQkgICAgImdvdCBcIiIgKyB0ay5nZXRWYWx1ZSgpICsgIlwiIik7CisKKwkJLy8gZXhwZWN0IHBhcmFtZXRlciB2YWx1ZQorCQlpZiAod2luZG93c2hhY2sgJiYKKwkJCShuYW1lLmVxdWFscygibmFtZSIpIHx8IG5hbWUuZXF1YWxzKCJmaWxlbmFtZSIpKSkKKwkJICAgIHRrID0gaC5uZXh0KCc7JywgdHJ1ZSk7CisJCWVsc2UgaWYgKHBhcmFtZXRlcnNTdHJpY3QpCisJCSAgICB0ayA9IGgubmV4dCgpOworCQllbHNlCisJCSAgICB0ayA9IGgubmV4dCgnOycpOworCQl0eXBlID0gdGsuZ2V0VHlwZSgpOworCQkvLyBwYXJhbWV0ZXIgdmFsdWUgbXVzdCBiZSBhIE1JTUUgQXRvbSBvciBRdW90ZWQgU3RyaW5nCisJCWlmICh0eXBlICE9IEhlYWRlclRva2VuaXplci5Ub2tlbi5BVE9NICYmCisJCSAgICB0eXBlICE9IEhlYWRlclRva2VuaXplci5Ub2tlbi5RVU9URURTVFJJTkcpCisJCSAgICB0aHJvdyBuZXcgUGFyc2VFeGNlcHRpb24oIkluIHBhcmFtZXRlciBsaXN0IDwiICsgcyArICI+IiArCisJCQkJCSAgICAiLCBleHBlY3RlZCBwYXJhbWV0ZXIgdmFsdWUsICIgKworCQkJCQkgICAgImdvdCBcIiIgKyB0ay5nZXRWYWx1ZSgpICsgIlwiIik7CisKKwkJdmFsdWUgPSB0ay5nZXRWYWx1ZSgpOworCQlsYXN0TmFtZSA9IG5hbWU7CisJCWlmIChkZWNvZGVQYXJhbWV0ZXJzKQorCQkgICAgcHV0RW5jb2RlZE5hbWUobmFtZSwgdmFsdWUpOworCQllbHNlCisJCSAgICBsaXN0LnB1dChuYW1lLCB2YWx1ZSk7CisgICAgICAgICAgICB9IGVsc2UgeworCQkvLyBNV0IgM0JWaWV3IG5ldyBjb2RlIHRvIGFkZCBpbiBmaWxlbmFtZXMgZ2VuZXJhdGVkIGJ5IAorCQkvLyBBcHBsZU1haWwuCisJCS8vIE5vdGUgLSBvbmUgc3BhY2UgaXMgYXNzdW1lZCBiZXR3ZWVuIG5hbWUgZWxlbWVudHMuCisJCS8vIFRoaXMgbWF5IG5vdCBiZSBjb3JyZWN0IGJ1dCBpdCBzaG91bGRuJ3QgbWF0dGVyIHRvbyBtdWNoLgorCQkvLyBOb3RlOiBBcHBsZU1haWwgZW5jb2RlcyBmaWxlbmFtZXMgd2l0aCBub24tYXNjaWkgY2hhcmFjdGVycyAKKwkJLy8gY29ycmVjdGx5LCBzbyB3ZSBkb24ndCBuZWVkIHRvIHdvcnJ5IGFib3V0IHRoZSBuYW1lKiBzdWJrZXlzLgorCQlpZiAodHlwZSA9PSBIZWFkZXJUb2tlbml6ZXIuVG9rZW4uQVRPTSAmJiBsYXN0TmFtZSAhPSBudWxsICYmCisJCQkgICAgKChhcHBsZWhhY2sgJiYKKwkJCQkobGFzdE5hbWUuZXF1YWxzKCJuYW1lIikgfHwKKwkJCQkgbGFzdE5hbWUuZXF1YWxzKCJmaWxlbmFtZSIpKSkgfHwKKwkJCSAgICAhcGFyYW1ldGVyc1N0cmljdCkKKwkJCSApIHsKKwkJICAgIC8vIEFkZCB2YWx1ZSB0byBwcmV2aW91cyB2YWx1ZQorCQkgICAgU3RyaW5nIGxhc3RWYWx1ZSA9IChTdHJpbmcpbGlzdC5nZXQobGFzdE5hbWUpOworCQkgICAgdmFsdWUgPSBsYXN0VmFsdWUgKyAiICIgKyB0ay5nZXRWYWx1ZSgpOworCQkgICAgbGlzdC5wdXQobGFzdE5hbWUsIHZhbHVlKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworCQkgICAgdGhyb3cgbmV3IFBhcnNlRXhjZXB0aW9uKCJJbiBwYXJhbWV0ZXIgbGlzdCA8IiArIHMgKyAiPiIgKworCQkJCQkgICAgIiwgZXhwZWN0ZWQgJzsnLCBnb3QgXCIiICsKKwkJCQkJICAgIHRrLmdldFZhbHVlKCkgKyAiXCIiKTsKKwkJfQorCSAgICB9CisgICAgICAgIH0KKworCWlmIChkZWNvZGVQYXJhbWV0ZXJzKSB7CisJICAgIC8qCisJICAgICAqIEFmdGVyIHBhcnNpbmcgYWxsIHRoZSBwYXJhbWV0ZXJzLCBjb21iaW5lIGFsbCB0aGUKKwkgICAgICogbXVsdGktc2VnbWVudCBwYXJhbWV0ZXIgdmFsdWVzIHRvZ2V0aGVyLgorCSAgICAgKi8KKwkgICAgY29tYmluZU11bHRpc2VnbWVudE5hbWVzKGZhbHNlKTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogTm9ybWFsIHVzZXJzIG9mIHRoaXMgY2xhc3Mgd2lsbCB1c2Ugc2ltcGxlIHBhcmFtZXRlciBuYW1lcy4KKyAgICAgKiBJbiBzb21lIGNhc2VzLCBmb3IgZXhhbXBsZSwgd2hlbiBwcm9jZXNzaW5nIElNQVAgcHJvdG9jb2wKKyAgICAgKiBtZXNzYWdlcywgaW5kaXZpZHVhbCBzZWdtZW50cyBvZiBhIG11bHRpLXNlZ21lbnQgbmFtZQorICAgICAqIChzcGVjaWZpZWQgYnkgUkZDIDIyMzEpIHdpbGwgYmUgZW5jb3VudGVyZWQgYW5kIHBhc3NlZCB0bworICAgICAqIHRoZSB7QGxpbmsgI3NldH0gbWV0aG9kLiAgQWZ0ZXIgYWxsIHRoZXNlIHNlZ21lbnRzIGFyZSBhZGRlZAorICAgICAqIHRvIHRoaXMgUGFyYW1ldGVyTGlzdCwgdGhleSBuZWVkIHRvIGJlIGNvbWJpbmVkIHRvIHJlcHJlc2VudAorICAgICAqIHRoZSBsb2dpY2FsIHBhcmFtZXRlciBuYW1lIGFuZCB2YWx1ZS4gIFRoaXMgbWV0aG9kIHdpbGwgY29tYmluZQorICAgICAqIGFsbCBzZWdtZW50cyBvZiBtdWx0aS1zZWdtZW50IG5hbWVzLiA8cD4KKyAgICAgKgorICAgICAqIE5vcm1hbCB1c2VycyBzaG91bGQgbmV2ZXIgbmVlZCB0byBjYWxsIHRoaXMgbWV0aG9kLgorICAgICAqCisgICAgICogQHNpbmNlCUphdmFNYWlsIDEuNQorICAgICAqLyAKKyAgICBwdWJsaWMgdm9pZCBjb21iaW5lU2VnbWVudHMoKSB7CisJLyoKKwkgKiBJZiB3ZSd2ZSBhY2N1bXVsYXRlZCBhbnkgbXVsdGktc2VnbWVudCBuYW1lcyBmcm9tIGNhbGxzIHRvCisJICogdGhlIHNldCBtZXRob2QgZnJvbSAoZS5nLikgdGhlIElNQVAgcHJvdmlkZXIsIGNvbWJpbmUgdGhlIHBpZWNlcy4KKwkgKiBJZ25vcmUgYW55IHBhcnNlIGVycm9ycyAoZS5nLiwgZnJvbSBkZWNvZGluZyB0aGUgdmFsdWVzKQorCSAqIGJlY2F1c2UgaXQncyB0b28gbGF0ZSB0byByZXBvcnQgdGhlbS4KKwkgKi8KKwlpZiAoZGVjb2RlUGFyYW1ldGVycyAmJiBtdWx0aXNlZ21lbnROYW1lcy5zaXplKCkgPiAwKSB7CisJICAgIHRyeSB7CisJCWNvbWJpbmVNdWx0aXNlZ21lbnROYW1lcyh0cnVlKTsKKwkgICAgfSBjYXRjaCAoUGFyc2VFeGNlcHRpb24gcGV4KSB7CisJCS8vIHRvbyBsYXRlIHRvIGRvIGFueXRoaW5nIGFib3V0IGl0CisJICAgIH0KKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogSWYgdGhlIG5hbWUgaXMgYW4gZW5jb2RlZCBvciBtdWx0aS1zZWdtZW50IG5hbWUgKG9yIGJvdGgpCisgICAgICogaGFuZGxlIGl0IGFwcHJvcHJpYXRlbHksIHN0b3JpbmcgdGhlIGFwcHJvcHJpYXRlIFN0cmluZworICAgICAqIG9yIFZhbHVlIG9iamVjdC4gIE11bHRpLXNlZ21lbnQgbmFtZXMgYXJlIHN0b3JlZCBpbiB0aGUKKyAgICAgKiBtYWluIHBhcmFtZXRlciBsaXN0IGFzIGFuIGVtdHB5IHN0cmluZyBhcyBhIHBsYWNlaG9sZGVyLAorICAgICAqIHJlcGxhY2VkIGxhdGVyIGluIGNvbWJpbmVNdWx0aXNlZ21lbnROYW1lcyB3aXRoIGEgTXVsdGlWYWx1ZQorICAgICAqIG9iamVjdC4gIFRoaXMgY2F1c2VzIGFsbCBwaWVjZXMgb2YgdGhlIG11bHRpLXNlZ21lbnQgcGFyYW1ldGVyCisgICAgICogdG8gYXBwZWFyIGluIHRoZSBwb3NpdGlvbiBvZiB0aGUgZmlyc3Qgc2VlbiBzZWdtZW50IG9mIHRoZQorICAgICAqIHBhcmFtZXRlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcHV0RW5jb2RlZE5hbWUoU3RyaW5nIG5hbWUsIFN0cmluZyB2YWx1ZSkKKwkJCQl0aHJvd3MgUGFyc2VFeGNlcHRpb24geworCWludCBzdGFyID0gbmFtZS5pbmRleE9mKCcqJyk7CisJaWYgKHN0YXIgPCAwKSB7CisJICAgIC8vIHNpbmdsZSBwYXJhbWV0ZXIsIHVuZW5jb2RlZCB2YWx1ZQorCSAgICBsaXN0LnB1dChuYW1lLCB2YWx1ZSk7CisJfSBlbHNlIGlmIChzdGFyID09IG5hbWUubGVuZ3RoKCkgLSAxKSB7CisJICAgIC8vIHNpbmdsZSBwYXJhbWV0ZXIsIGVuY29kZWQgdmFsdWUKKwkgICAgbmFtZSA9IG5hbWUuc3Vic3RyaW5nKDAsIHN0YXIpOworCSAgICBWYWx1ZSB2ID0gZXh0cmFjdENoYXJzZXQodmFsdWUpOworCSAgICB0cnkgeworCQl2LnZhbHVlID0gZGVjb2RlQnl0ZXModi52YWx1ZSwgdi5jaGFyc2V0KTsKKwkgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBleCkgeworCQlpZiAoZGVjb2RlUGFyYW1ldGVyc1N0cmljdCkKKwkJICAgIHRocm93IG5ldyBQYXJzZUV4Y2VwdGlvbihleC50b1N0cmluZygpKTsKKwkgICAgfQorCSAgICBsaXN0LnB1dChuYW1lLCB2KTsKKwl9IGVsc2UgeworCSAgICAvLyBtdWx0aXBsZSBzZWdtZW50cworCSAgICBTdHJpbmcgcm5hbWUgPSBuYW1lLnN1YnN0cmluZygwLCBzdGFyKTsKKwkgICAgbXVsdGlzZWdtZW50TmFtZXMuYWRkKHJuYW1lKTsKKwkgICAgbGlzdC5wdXQocm5hbWUsICIiKTsKKworCSAgICBPYmplY3QgdjsKKwkgICAgaWYgKG5hbWUuZW5kc1dpdGgoIioiKSkgeworCQkvLyBlbmNvZGVkIHZhbHVlCisJCWlmIChuYW1lLmVuZHNXaXRoKCIqMCoiKSkgewkvLyBmaXJzdCBzZWdtZW50CisJCSAgICB2ID0gZXh0cmFjdENoYXJzZXQodmFsdWUpOworCQl9IGVsc2UgeworCQkgICAgdiA9IG5ldyBWYWx1ZSgpOworCQkgICAgKChWYWx1ZSl2KS5lbmNvZGVkVmFsdWUgPSB2YWx1ZTsKKwkJICAgICgoVmFsdWUpdikudmFsdWUgPSB2YWx1ZTsJLy8gZGVmYXVsdDsgZGVjb2RlZCBsYXRlcgorCQl9CisJCW5hbWUgPSBuYW1lLnN1YnN0cmluZygwLCBuYW1lLmxlbmd0aCgpIC0gMSk7CisJICAgIH0gZWxzZSB7CisJCS8vIHVuZW5jb2RlZCB2YWx1ZQorCQl2ID0gdmFsdWU7CisJICAgIH0KKwkgICAgc2xpc3QucHV0KG5hbWUsIHYpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJdGVyYXRlIHRocm91Z2ggdGhlIHNhdmVkIHNldCBvZiBuYW1lcyBvZiBtdWx0aS1zZWdtZW50IHBhcmFtZXRlcnMsCisgICAgICogZm9yIGVhY2ggcGFyYW1ldGVyIGZpbmQgYWxsIHNlZ21lbnRzIHN0b3JlZCBpbiB0aGUgc2xpc3QgbWFwLAorICAgICAqIGRlY29kZSBlYWNoIHNlZ21lbnQgYXMgbmVlZGVkLCBjb21iaW5lIHRoZSBzZWdtZW50cyB0b2dldGhlciBpbnRvCisgICAgICogYSBzaW5nbGUgZGVjb2RlZCB2YWx1ZSwgYW5kIHNhdmUgYWxsIHNlZ21lbnRzIGluIGEgTXVsdGlWYWx1ZSBvYmplY3QKKyAgICAgKiBpbiB0aGUgbWFpbiBsaXN0IGluZGV4ZWQgYnkgdGhlIHBhcmFtZXRlciBuYW1lLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBjb21iaW5lTXVsdGlzZWdtZW50TmFtZXMoYm9vbGVhbiBrZWVwQ29uc2lzdGVudE9uRmFpbHVyZSkKKwkJCQl0aHJvd3MgUGFyc2VFeGNlcHRpb24geworCWJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworCXRyeSB7CisJICAgIEl0ZXJhdG9yPFN0cmluZz4gaXQgPSBtdWx0aXNlZ21lbnROYW1lcy5pdGVyYXRvcigpOworCSAgICB3aGlsZSAoaXQuaGFzTmV4dCgpKSB7CisJCVN0cmluZyBuYW1lID0gaXQubmV4dCgpOworCQlNdWx0aVZhbHVlIG12ID0gbmV3IE11bHRpVmFsdWUoKTsKKwkJLyoKKwkJICogTm93IGZpbmQgYWxsIHRoZSBzZWdtZW50cyBmb3IgdGhpcyBuYW1lIGFuZAorCQkgKiBkZWNvZGUgZWFjaCBzZWdtZW50IGFzIG5lZWRlZC4KKwkJICovCisJCVN0cmluZyBjaGFyc2V0ID0gbnVsbDsKKwkJQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKwkJaW50IHNlZ21lbnQ7CisJCWZvciAoc2VnbWVudCA9IDA7IDsgc2VnbWVudCsrKSB7CisJCSAgICBTdHJpbmcgc25hbWUgPSBuYW1lICsgIioiICsgc2VnbWVudDsKKwkJICAgIE9iamVjdCB2ID0gc2xpc3QuZ2V0KHNuYW1lKTsKKwkJICAgIGlmICh2ID09IG51bGwpCS8vIG91dCBvZiBzZWdtZW50cworCQkJYnJlYWs7CisJCSAgICBtdi5hZGQodik7CisJCSAgICB0cnkgeworCQkJaWYgKHYgaW5zdGFuY2VvZiBWYWx1ZSkgeworCQkJICAgIFZhbHVlIHZ2ID0gKFZhbHVlKXY7CisJCQkgICAgaWYgKHNlZ21lbnQgPT0gMCkgeworCQkJCS8vIHRoZSBmaXJzdCBzZWdtZW50IHNwZWNpZmllcyB0aGUgY2hhcnNldAorCQkJCS8vIGZvciBhbGwgb3RoZXIgZW5jb2RlZCBzZWdtZW50cworCQkJCWNoYXJzZXQgPSB2di5jaGFyc2V0OworCQkJICAgIH0gZWxzZSB7CisJCQkJaWYgKGNoYXJzZXQgPT0gbnVsbCkgeworCQkJCSAgICAvLyBzaG91bGQgbmV2ZXIgaGFwcGVuCisJCQkJICAgIG11bHRpc2VnbWVudE5hbWVzLnJlbW92ZShuYW1lKTsKKwkJCQkgICAgYnJlYWs7CisJCQkJfQorCQkJICAgIH0KKwkJCSAgICBkZWNvZGVCeXRlcyh2di52YWx1ZSwgYm9zKTsKKwkJCX0gZWxzZSB7CisJCQkgICAgYm9zLndyaXRlKEFTQ0lJVXRpbGl0eS5nZXRCeXRlcygoU3RyaW5nKXYpKTsKKwkJCX0KKwkJICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisJCQkvLyBYWFggLSBzaG91bGQgbmV2ZXIgaGFwcGVuCisJCSAgICB9CisJCSAgICBzbGlzdC5yZW1vdmUoc25hbWUpOworCQl9CisJCWlmIChzZWdtZW50ID09IDApIHsKKwkJICAgIC8vIGRpZG4ndCBmaW5kIGFueSBzZWdtZW50cyBhdCBhbGwKKwkJICAgIGxpc3QucmVtb3ZlKG5hbWUpOworCQl9IGVsc2UgeworCQkgICAgdHJ5IHsKKwkJCWlmIChjaGFyc2V0ICE9IG51bGwpCisJCQkgICAgY2hhcnNldCA9IE1pbWVVdGlsaXR5LmphdmFDaGFyc2V0KGNoYXJzZXQpOworCQkJaWYgKGNoYXJzZXQgPT0gbnVsbCB8fCBjaGFyc2V0Lmxlbmd0aCgpID09IDApCisJCQkgICAgY2hhcnNldCA9IE1pbWVVdGlsaXR5LmdldERlZmF1bHRKYXZhQ2hhcnNldCgpOworCQkJaWYgKGNoYXJzZXQgIT0gbnVsbCkKKwkJCSAgICBtdi52YWx1ZSA9IGJvcy50b1N0cmluZyhjaGFyc2V0KTsKKwkJCWVsc2UKKwkJCSAgICBtdi52YWx1ZSA9IGJvcy50b1N0cmluZygpOworCQkgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiB1ZXgpIHsKKwkJCWlmIChkZWNvZGVQYXJhbWV0ZXJzU3RyaWN0KQorCQkJICAgIHRocm93IG5ldyBQYXJzZUV4Y2VwdGlvbih1ZXgudG9TdHJpbmcoKSk7CisJCQkvLyBjb252ZXJ0IGFzIGlmIGlzby04ODU5LTEKKwkJCXRyeSB7CisJCQkgICAgbXYudmFsdWUgPSBib3MudG9TdHJpbmcoImlzby04ODU5LTEiKTsKKwkJCX0gY2F0Y2ggKFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gZXgpIHsKKwkJCSAgICAvLyBzaG91bGQgbmV2ZXIgaGFwcGVuCisJCQl9CisJCSAgICB9CisJCSAgICBsaXN0LnB1dChuYW1lLCBtdik7CisJCX0KKwkgICAgfQorCSAgICBzdWNjZXNzID0gdHJ1ZTsKKwl9IGZpbmFsbHkgeworCSAgICAvKgorCSAgICAgKiBJZiB3ZSBnZXQgaGVyZSBiZWNhdXNlIG9mIGFuIGV4Y2VwdGlvbiB0aGF0J3MgZ29pbmcgdG8KKwkgICAgICogYmUgdGhyb3duIChzdWNjZXNzID09IGZhbHNlKSBmcm9tIHRoZSBjb25zdHJ1Y3RvcgorCSAgICAgKiAoa2VlcENvbnNpc3RlbnRPbkZhaWx1cmUgPT0gZmFsc2UpLCB0aGlzIGlzIGFsbCB3YXN0ZWQgZWZmb3J0LgorCSAgICAgKi8KKwkgICAgaWYgKGtlZXBDb25zaXN0ZW50T25GYWlsdXJlIHx8IHN1Y2Nlc3MpICB7CisJCS8vIHdlIHNob3VsZCBuZXZlciBlbmQgdXAgd2l0aCBhbnl0aGluZyBpbiBzbGlzdCwKKwkJLy8gYnV0IGlmIHdlIGRvLCBhZGQgaXQgYWxsIHRvIGxpc3QKKwkJaWYgKHNsaXN0LnNpemUoKSA+IDApIHsKKwkJICAgIC8vIGZpcnN0LCBkZWNvZGUgYW55IHZhbHVlcyB0aGF0IHdlJ2xsIGFkZCB0byB0aGUgbGlzdAorCQkgICAgSXRlcmF0b3I8T2JqZWN0PiBzaXQgPSBzbGlzdC52YWx1ZXMoKS5pdGVyYXRvcigpOworCQkgICAgd2hpbGUgKHNpdC5oYXNOZXh0KCkpIHsKKwkJCU9iamVjdCB2ID0gc2l0Lm5leHQoKTsKKwkJCWlmICh2IGluc3RhbmNlb2YgVmFsdWUpIHsKKwkJCSAgICBWYWx1ZSB2diA9IChWYWx1ZSl2OworCQkJICAgIHRyeSB7CisJCQkJdnYudmFsdWUgPQorCQkJCSAgICBkZWNvZGVCeXRlcyh2di52YWx1ZSwgdnYuY2hhcnNldCk7CisJCQkgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBleCkgeworCQkJCWlmIChkZWNvZGVQYXJhbWV0ZXJzU3RyaWN0KQorCQkJCSAgICB0aHJvdyBuZXcgUGFyc2VFeGNlcHRpb24oZXgudG9TdHJpbmcoKSk7CisJCQkgICAgfQorCQkJfQorCQkgICAgfQorCQkgICAgbGlzdC5wdXRBbGwoc2xpc3QpOworCQl9CisKKwkJLy8gY2xlYXIgb3V0IHRoZSBzZXQgb2YgbmFtZXMgYW5kIHNlZ21lbnRzCisJCW11bHRpc2VnbWVudE5hbWVzLmNsZWFyKCk7CisJCXNsaXN0LmNsZWFyKCk7CisJICAgIH0KKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBudW1iZXIgb2YgcGFyYW1ldGVycyBpbiB0aGlzIGxpc3QuCisgICAgICogCisgICAgICogQHJldHVybiAgbnVtYmVyIG9mIHBhcmFtZXRlcnMuCisgICAgICovCisgICAgcHVibGljIGludCBzaXplKCkgeworCXJldHVybiBsaXN0LnNpemUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlci4gTm90ZSB0aGF0IAorICAgICAqIHBhcmFtZXRlciBuYW1lcyBhcmUgY2FzZS1pbnNlbnNpdGl2ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuYW1lCXBhcmFtZXRlciBuYW1lLgorICAgICAqIEByZXR1cm4JCVZhbHVlIG9mIHRoZSBwYXJhbWV0ZXIuIFJldHVybnMgCisgICAgICoJCQk8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGUgcGFyYW1ldGVyIGlzIG5vdCAKKyAgICAgKgkJCXByZXNlbnQuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXQoU3RyaW5nIG5hbWUpIHsKKwlTdHJpbmcgdmFsdWU7CisJT2JqZWN0IHYgPSBsaXN0LmdldChuYW1lLnRyaW0oKS50b0xvd2VyQ2FzZShMb2NhbGUuRU5HTElTSCkpOworCWlmICh2IGluc3RhbmNlb2YgTXVsdGlWYWx1ZSkKKwkgICAgdmFsdWUgPSAoKE11bHRpVmFsdWUpdikudmFsdWU7CisJZWxzZSBpZiAodiBpbnN0YW5jZW9mIExpdGVyYWxWYWx1ZSkKKwkgICAgdmFsdWUgPSAoKExpdGVyYWxWYWx1ZSl2KS52YWx1ZTsKKwllbHNlIGlmICh2IGluc3RhbmNlb2YgVmFsdWUpCisJICAgIHZhbHVlID0gKChWYWx1ZSl2KS52YWx1ZTsKKwllbHNlCisJICAgIHZhbHVlID0gKFN0cmluZyl2OworCXJldHVybiB2YWx1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgYSBwYXJhbWV0ZXIuIElmIHRoaXMgcGFyYW1ldGVyIGFscmVhZHkgZXhpc3RzLCBpdCBpcworICAgICAqIHJlcGxhY2VkIGJ5IHRoaXMgbmV3IHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtCW5hbWUgCW5hbWUgb2YgdGhlIHBhcmFtZXRlci4KKyAgICAgKiBAcGFyYW0JdmFsdWUJdmFsdWUgb2YgdGhlIHBhcmFtZXRlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXQoU3RyaW5nIG5hbWUsIFN0cmluZyB2YWx1ZSkgeworCW5hbWUgPSBuYW1lLnRyaW0oKS50b0xvd2VyQ2FzZShMb2NhbGUuRU5HTElTSCk7CisJaWYgKGRlY29kZVBhcmFtZXRlcnMpIHsKKwkgICAgdHJ5IHsKKwkJcHV0RW5jb2RlZE5hbWUobmFtZSwgdmFsdWUpOworCSAgICB9IGNhdGNoIChQYXJzZUV4Y2VwdGlvbiBwZXgpIHsKKwkJLy8gaWdub3JlIGl0CisJCWxpc3QucHV0KG5hbWUsIHZhbHVlKTsKKwkgICAgfQorCX0gZWxzZQorCSAgICBsaXN0LnB1dChuYW1lLCB2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IGEgcGFyYW1ldGVyLiBJZiB0aGlzIHBhcmFtZXRlciBhbHJlYWR5IGV4aXN0cywgaXQgaXMKKyAgICAgKiByZXBsYWNlZCBieSB0aGlzIG5ldyB2YWx1ZS4gIElmIHRoZQorICAgICAqIDxjb2RlPm1haWwubWltZS5lbmNvZGVwYXJhbWV0ZXJzPC9jb2RlPiBTeXN0ZW0gcHJvcGVydHkKKyAgICAgKiBpcyB0cnVlLCBhbmQgdGhlIHBhcmFtZXRlciB2YWx1ZSBpcyBub24tQVNDSUksIGl0IHdpbGwgYmUKKyAgICAgKiBlbmNvZGVkIHdpdGggdGhlIHNwZWNpZmllZCBjaGFyc2V0LCBhcyBzcGVjaWZpZWQgYnkgUkZDIDIyMzEuCisgICAgICoKKyAgICAgKiBAcGFyYW0JbmFtZSAJbmFtZSBvZiB0aGUgcGFyYW1ldGVyLgorICAgICAqIEBwYXJhbQl2YWx1ZQl2YWx1ZSBvZiB0aGUgcGFyYW1ldGVyLgorICAgICAqIEBwYXJhbQljaGFyc2V0CWNoYXJzZXQgb2YgdGhlIHBhcmFtZXRlciB2YWx1ZS4KKyAgICAgKiBAc2luY2UJSmF2YU1haWwgMS40CisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0KFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsdWUsIFN0cmluZyBjaGFyc2V0KSB7CisJaWYgKGVuY29kZVBhcmFtZXRlcnMpIHsKKwkgICAgVmFsdWUgZXYgPSBlbmNvZGVWYWx1ZSh2YWx1ZSwgY2hhcnNldCk7CisJICAgIC8vIHdhcyBpdCBhY3R1YWxseSBlbmNvZGVkPworCSAgICBpZiAoZXYgIT0gbnVsbCkKKwkJbGlzdC5wdXQobmFtZS50cmltKCkudG9Mb3dlckNhc2UoTG9jYWxlLkVOR0xJU0gpLCBldik7CisJICAgIGVsc2UKKwkJc2V0KG5hbWUsIHZhbHVlKTsKKwl9IGVsc2UKKwkgICAgc2V0KG5hbWUsIHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYWNrYWdlLXByaXZhdGUgbWV0aG9kIHRvIHNldCBhIGxpdGVyYWwgdmFsdWUgdGhhdCB3b24ndCBiZQorICAgICAqIGZ1cnRoZXIgZW5jb2RlZC4gIFVzZWQgdG8gc2V0IHRoZSBmaWxlbmFtZSBwYXJhbWV0ZXIgd2hlbgorICAgICAqICJtYWlsLm1pbWUuZW5jb2RlZmlsZW5hbWUiIGlzIHRydWUuCisgICAgICoKKyAgICAgKiBAcGFyYW0JbmFtZSAJbmFtZSBvZiB0aGUgcGFyYW1ldGVyLgorICAgICAqIEBwYXJhbQl2YWx1ZQl2YWx1ZSBvZiB0aGUgcGFyYW1ldGVyLgorICAgICAqLworICAgIHZvaWQgc2V0TGl0ZXJhbChTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKSB7CisJTGl0ZXJhbFZhbHVlIGx2ID0gbmV3IExpdGVyYWxWYWx1ZSgpOworCWx2LnZhbHVlID0gdmFsdWU7CisJbGlzdC5wdXQobmFtZSwgbHYpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlbW92ZXMgdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXIgZnJvbSB0aGlzIFBhcmFtZXRlckxpc3QuCisgICAgICogVGhpcyBtZXRob2QgZG9lcyBub3RoaW5nIGlmIHRoZSBwYXJhbWV0ZXIgaXMgbm90IHByZXNlbnQuCisgICAgICoKKyAgICAgKiBAcGFyYW0JbmFtZQluYW1lIG9mIHRoZSBwYXJhbWV0ZXIuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVtb3ZlKFN0cmluZyBuYW1lKSB7CisJbGlzdC5yZW1vdmUobmFtZS50cmltKCkudG9Mb3dlckNhc2UoTG9jYWxlLkVOR0xJU0gpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYW4gZW51bWVyYXRpb24gb2YgdGhlIG5hbWVzIG9mIGFsbCBwYXJhbWV0ZXJzIGluIHRoaXMKKyAgICAgKiBsaXN0LgorICAgICAqCisgICAgICogQHJldHVybiBFbnVtZXJhdGlvbiBvZiBhbGwgcGFyYW1ldGVyIG5hbWVzIGluIHRoaXMgbGlzdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRW51bWVyYXRpb248U3RyaW5nPiBnZXROYW1lcygpIHsKKwlyZXR1cm4gbmV3IFBhcmFtRW51bShsaXN0LmtleVNldCgpLml0ZXJhdG9yKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlcnQgdGhpcyBQYXJhbWV0ZXJMaXN0IGludG8gYSBNSU1FIFN0cmluZy4gSWYgdGhpcyBpcworICAgICAqIGFuIGVtcHR5IGxpc3QsIGFuIGVtcHR5IHN0cmluZyBpcyByZXR1cm5lZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4JCVN0cmluZworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisJcmV0dXJuIHRvU3RyaW5nKDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlcnQgdGhpcyBQYXJhbWV0ZXJMaXN0IGludG8gYSBNSU1FIFN0cmluZy4gSWYgdGhpcyBpcworICAgICAqIGFuIGVtcHR5IGxpc3QsIGFuIGVtcHR5IHN0cmluZyBpcyByZXR1cm5lZC4KKyAgICAgKiAgIAorICAgICAqIFRoZSAndXNlZCcgcGFyYW1ldGVyIHNwZWNpZmllcyB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlciBwb3NpdGlvbnMKKyAgICAgKiBhbHJlYWR5IHRha2VuIHVwIGluIHRoZSBmaWVsZCBpbnRvIHdoaWNoIHRoZSByZXN1bHRpbmcgcGFyYW1ldGVyCisgICAgICogbGlzdCBpcyB0byBiZSBpbnNlcnRlZC4gSXQncyB1c2VkIHRvIGRldGVybWluZSB3aGVyZSB0byBmb2xkIHRoZQorICAgICAqIHJlc3VsdGluZyBwYXJhbWV0ZXIgbGlzdC4KKyAgICAgKgorICAgICAqIEBwYXJhbSB1c2VkICAgICAgbnVtYmVyIG9mIGNoYXJhY3RlciBwb3NpdGlvbnMgYWxyZWFkeSB1c2VkLCBpbgorICAgICAqICAgICAgICAgICAgICAgICAgdGhlIGZpZWxkIGludG8gd2hpY2ggdGhlIHBhcmFtZXRlciBsaXN0IGlzIHRvCisgICAgICogICAgICAgICAgICAgICAgICBiZSBpbnNlcnRlZC4KKyAgICAgKiBAcmV0dXJuICAgICAgICAgIFN0cmluZworICAgICAqLyAgCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZyhpbnQgdXNlZCkgeworICAgICAgICBUb1N0cmluZ0J1ZmZlciBzYiA9IG5ldyBUb1N0cmluZ0J1ZmZlcih1c2VkKTsKKyAgICAgICAgSXRlcmF0b3I8TWFwLkVudHJ5PFN0cmluZywgT2JqZWN0Pj4gZSA9IGxpc3QuZW50cnlTZXQoKS5pdGVyYXRvcigpOworIAorICAgICAgICB3aGlsZSAoZS5oYXNOZXh0KCkpIHsKKwkgICAgTWFwLkVudHJ5PFN0cmluZywgT2JqZWN0PiBlbnQgPSBlLm5leHQoKTsKKwkgICAgU3RyaW5nIG5hbWUgPSBlbnQuZ2V0S2V5KCk7CisJICAgIFN0cmluZyB2YWx1ZTsKKwkgICAgT2JqZWN0IHYgPSBlbnQuZ2V0VmFsdWUoKTsKKwkgICAgaWYgKHYgaW5zdGFuY2VvZiBNdWx0aVZhbHVlKSB7CisJCU11bHRpVmFsdWUgdnYgPSAoTXVsdGlWYWx1ZSl2OworCQluYW1lICs9ICIqIjsKKwkJZm9yIChpbnQgaSA9IDA7IGkgPCB2di5zaXplKCk7IGkrKykgeworCQkgICAgT2JqZWN0IHZhID0gdnYuZ2V0KGkpOworCQkgICAgU3RyaW5nIG5zOworCQkgICAgaWYgKHZhIGluc3RhbmNlb2YgVmFsdWUpIHsKKwkJCW5zID0gbmFtZSArIGkgKyAiKiI7CisJCQl2YWx1ZSA9ICgoVmFsdWUpdmEpLmVuY29kZWRWYWx1ZTsKKwkJICAgIH0gZWxzZSB7CisJCQlucyA9IG5hbWUgKyBpOworCQkJdmFsdWUgPSAoU3RyaW5nKXZhOworCQkgICAgfQorCQkgICAgc2IuYWRkTlYobnMsIHF1b3RlKHZhbHVlKSk7CisJCX0KKwkgICAgfSBlbHNlIGlmICh2IGluc3RhbmNlb2YgTGl0ZXJhbFZhbHVlKSB7CisJCXZhbHVlID0gKChMaXRlcmFsVmFsdWUpdikudmFsdWU7CisJCXNiLmFkZE5WKG5hbWUsIHF1b3RlKHZhbHVlKSk7CisJICAgIH0gZWxzZSBpZiAodiBpbnN0YW5jZW9mIFZhbHVlKSB7CisJCS8qCisJCSAqIFhYWCAtIFdlIGNvdWxkIHNwbGl0IHRoZSBlbmNvZGVkIHZhbHVlIGludG8gbXVsdGlwbGUKKwkJICogc2VnbWVudHMgaWYgaXQncyB0b28gbG9uZywgYnV0IHRoYXQncyBtb3JlIGRpZmZpY3VsdC4KKwkJICovCisJCW5hbWUgKz0gIioiOworCQl2YWx1ZSA9ICgoVmFsdWUpdikuZW5jb2RlZFZhbHVlOworCQlzYi5hZGROVihuYW1lLCBxdW90ZSh2YWx1ZSkpOworCSAgICB9IGVsc2UgeworCQl2YWx1ZSA9IChTdHJpbmcpdjsKKwkJLyoKKwkJICogSWYgdGhpcyB2YWx1ZSBpcyAibG9uZyIsIHNwbGl0IGl0IGludG8gYSBtdWx0aS1zZWdtZW50CisJCSAqIHBhcmFtZXRlci4gIE9ubHkgZG8gdGhpcyBpZiB3ZSd2ZSBlbmFibGVkIFJGQzIyMzEgc3R5bGUKKwkJICogZW5jb2RlZCBwYXJhbWV0ZXJzLgorCQkgKgorCQkgKiBOb3RlIHRoYXQgd2UgY2hlY2sgdGhlIGxlbmd0aCBiZWZvcmUgcXVvdGluZyB0aGUgdmFsdWUuCisJCSAqIFF1b3RpbmcgbWlnaHQgbWFrZSB0aGUgc3RyaW5nIGxvbmdlciwgYWx0aG91Z2ggdHlwaWNhbGx5CisJCSAqIG5vdCBtdWNoLCBzbyB3ZSBhbGxvdyBhIGxpdHRsZSBzbG9wIGluIHRoZSBjYWxjdWxhdGlvbi4KKwkJICogSW4gdGhlIHdvcnN0IGNhc2UsIGEgNjAgY2hhcmFjdGVyIHN0cmluZyB3aWxsIHR1cm4gaW50bworCQkgKiAxMjIgY2hhcmFjdGVycyB3aGVuIHF1b3RlZCwgd2hpY2ggaXMgbG9uZyBidXQgbm90CisJCSAqIG91dHJhZ2VvdXMuCisJCSAqLworCQlpZiAodmFsdWUubGVuZ3RoKCkgPiA2MCAmJgorCQkJCXNwbGl0TG9uZ1BhcmFtZXRlcnMgJiYgZW5jb2RlUGFyYW1ldGVycykgeworCQkgICAgaW50IHNlZyA9IDA7CisJCSAgICBuYW1lICs9ICIqIjsKKwkJICAgIHdoaWxlICh2YWx1ZS5sZW5ndGgoKSA+IDYwKSB7CisJCQlzYi5hZGROVihuYW1lICsgc2VnLCBxdW90ZSh2YWx1ZS5zdWJzdHJpbmcoMCwgNjApKSk7CisJCQl2YWx1ZSA9IHZhbHVlLnN1YnN0cmluZyg2MCk7CisJCQlzZWcrKzsKKwkJICAgIH0KKwkJICAgIGlmICh2YWx1ZS5sZW5ndGgoKSA+IDApCisJCQlzYi5hZGROVihuYW1lICsgc2VnLCBxdW90ZSh2YWx1ZSkpOworCQl9IGVsc2UgeworCQkgICAgc2IuYWRkTlYobmFtZSwgcXVvdGUodmFsdWUpKTsKKwkJfQorCSAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQSBzcGVjaWFsIHdyYXBwZXIgZm9yIGEgU3RyaW5nQnVmZmVyIHRoYXQga2VlcHMgdHJhY2sgb2YgdGhlCisgICAgICogbnVtYmVyIG9mIGNoYXJhY3RlcnMgdXNlZCBpbiBhIGxpbmUsIHdyYXBwaW5nIHRvIGEgbmV3IGxpbmUKKyAgICAgKiBhcyBuZWNlc3Nhcnk7IGZvciB1c2UgYnkgdGhlIHRvU3RyaW5nIG1ldGhvZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBUb1N0cmluZ0J1ZmZlciB7CisJcHJpdmF0ZSBpbnQgdXNlZDsJLy8ga2VlcCB0cmFjayBvZiBob3cgbXVjaCB1c2VkIG9uIGN1cnJlbnQgbGluZQorCXByaXZhdGUgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisKKwlwdWJsaWMgVG9TdHJpbmdCdWZmZXIoaW50IHVzZWQpIHsKKwkgICAgdGhpcy51c2VkID0gdXNlZDsKKwl9CisKKwlwdWJsaWMgdm9pZCBhZGROVihTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKSB7CisJICAgIHNiLmFwcGVuZCgiOyAiKTsKKwkgICAgdXNlZCArPSAyOworCSAgICBpbnQgbGVuID0gbmFtZS5sZW5ndGgoKSArIHZhbHVlLmxlbmd0aCgpICsgMTsKKwkgICAgaWYgKHVzZWQgKyBsZW4gPiA3NikgeyAvLyBvdmVyZmxvd3MgLi4uCisJCXNiLmFwcGVuZCgiXHJcblx0Iik7IC8vIC4uIHN0YXJ0IG5ldyBjb250aW51YXRpb24gbGluZQorCQl1c2VkID0gODsgLy8gYWNjb3VudCBmb3IgdGhlIHN0YXJ0aW5nIDx0YWI+IGNoYXIKKwkgICAgfQorCSAgICBzYi5hcHBlbmQobmFtZSkuYXBwZW5kKCc9Jyk7CisJICAgIHVzZWQgKz0gbmFtZS5sZW5ndGgoKSArIDE7CisJICAgIGlmICh1c2VkICsgdmFsdWUubGVuZ3RoKCkgPiA3NikgeyAvLyBzdGlsbCBvdmVyZmxvd3MgLi4uCisJCS8vIGhhdmUgdG8gZm9sZCB2YWx1ZQorCQlTdHJpbmcgcyA9IE1pbWVVdGlsaXR5LmZvbGQodXNlZCwgdmFsdWUpOworCQlzYi5hcHBlbmQocyk7CisJCWludCBsYXN0bGYgPSBzLmxhc3RJbmRleE9mKCdcbicpOworCQlpZiAobGFzdGxmID49IDApCS8vIGFsd2F5cyB0cnVlCisJCSAgICB1c2VkICs9IHMubGVuZ3RoKCkgLSBsYXN0bGYgLSAxOworCQllbHNlCisJCSAgICB1c2VkICs9IHMubGVuZ3RoKCk7CisJICAgIH0gZWxzZSB7CisJCXNiLmFwcGVuZCh2YWx1ZSk7CisJCXVzZWQgKz0gdmFsdWUubGVuZ3RoKCk7CisJICAgIH0KKwl9CisKKwlAT3ZlcnJpZGUKKwlwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworCSAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKwl9CisgICAgfQorIAorICAgIC8vIFF1b3RlIGEgcGFyYW1ldGVyIHZhbHVlIHRva2VuIGlmIHJlcXVpcmVkLgorICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBxdW90ZShTdHJpbmcgdmFsdWUpIHsKKwlyZXR1cm4gTWltZVV0aWxpdHkucXVvdGUodmFsdWUsIEhlYWRlclRva2VuaXplci5NSU1FKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyIGhleFtdID0geworCScwJywnMScsICcyJywgJzMnLCAnNCcsICc1JywgJzYnLCAnNycsCisJJzgnLCc5JywgJ0EnLCAnQicsICdDJywgJ0QnLCAnRScsICdGJworICAgIH07CisKKyAgICAvKioKKyAgICAgKiBFbmNvZGUgYSBwYXJhbWV0ZXIgdmFsdWUsIGlmIG5lY2Vzc2FyeS4KKyAgICAgKiBJZiB0aGUgdmFsdWUgaXMgZW5jb2RlZCwgYSBWYWx1ZSBvYmplY3QgaXMgcmV0dXJuZWQuCisgICAgICogT3RoZXJ3aXNlLCBudWxsIGlzIHJldHVybmVkLgorICAgICAqIFhYWCAtIENvdWxkIHJldHVybiBhIE11bHRpVmFsdWUgb2JqZWN0IGlmIHBhcmFtZXRlciB2YWx1ZSBpcyB0b28gbG9uZy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBWYWx1ZSBlbmNvZGVWYWx1ZShTdHJpbmcgdmFsdWUsIFN0cmluZyBjaGFyc2V0KSB7CisJaWYgKE1pbWVVdGlsaXR5LmNoZWNrQXNjaWkodmFsdWUpID09IE1pbWVVdGlsaXR5LkFMTF9BU0NJSSkKKwkgICAgcmV0dXJuIG51bGw7CS8vIG5vIG5lZWQgdG8gZW5jb2RlIGl0CisKKwlieXRlW10gYjsJLy8gY2hhcnNldCBlbmNvZGVkIGJ5dGVzIGZyb20gdGhlIHN0cmluZworCXRyeSB7CisJICAgIGIgPSB2YWx1ZS5nZXRCeXRlcyhNaW1lVXRpbGl0eS5qYXZhQ2hhcnNldChjaGFyc2V0KSk7CisJfSBjYXRjaCAoVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBleCkgeworCSAgICByZXR1cm4gbnVsbDsKKwl9CisJU3RyaW5nQnVmZmVyIHNiID0gbmV3IFN0cmluZ0J1ZmZlcihiLmxlbmd0aCArIGNoYXJzZXQubGVuZ3RoKCkgKyAyKTsKKwlzYi5hcHBlbmQoY2hhcnNldCkuYXBwZW5kKCInJyIpOworCWZvciAoaW50IGkgPSAwOyBpIDwgYi5sZW5ndGg7IGkrKykgeworCSAgICBjaGFyIGMgPSAoY2hhcikoYltpXSAmIDB4ZmYpOworCSAgICAvLyBkbyB3ZSBuZWVkIHRvIGVuY29kZSB0aGlzIGNoYXJhY3Rlcj8KKwkgICAgaWYgKGMgPD0gJyAnIHx8IGMgPj0gMHg3ZiB8fCBjID09ICcqJyB8fCBjID09ICdcJycgfHwgYyA9PSAnJScgfHwKKwkJICAgIEhlYWRlclRva2VuaXplci5NSU1FLmluZGV4T2YoYykgPj0gMCkgeworCQlzYi5hcHBlbmQoJyUnKS5hcHBlbmQoaGV4W2M+PjRdKS5hcHBlbmQoaGV4W2MmMHhmXSk7CisJICAgIH0gZWxzZQorCQlzYi5hcHBlbmQoYyk7CisJfQorCVZhbHVlIHYgPSBuZXcgVmFsdWUoKTsKKwl2LmNoYXJzZXQgPSBjaGFyc2V0OworCXYudmFsdWUgPSB2YWx1ZTsKKwl2LmVuY29kZWRWYWx1ZSA9IHNiLnRvU3RyaW5nKCk7CisJcmV0dXJuIHY7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXh0cmFjdCBjaGFyc2V0IGFuZCBlbmNvZGVkIHZhbHVlLgorICAgICAqIFZhbHVlIHdpbGwgYmUgZGVjb2RlZCBsYXRlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBWYWx1ZSBleHRyYWN0Q2hhcnNldChTdHJpbmcgdmFsdWUpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CisJVmFsdWUgdiA9IG5ldyBWYWx1ZSgpOworCXYudmFsdWUgPSB2LmVuY29kZWRWYWx1ZSA9IHZhbHVlOworCXRyeSB7CisJICAgIGludCBpID0gdmFsdWUuaW5kZXhPZignXCcnKTsKKwkgICAgaWYgKGkgPCAwKSB7CisJCWlmIChkZWNvZGVQYXJhbWV0ZXJzU3RyaWN0KQorCQkgICAgdGhyb3cgbmV3IFBhcnNlRXhjZXB0aW9uKAorCQkJIk1pc3NpbmcgY2hhcnNldCBpbiBlbmNvZGVkIHZhbHVlOiAiICsgdmFsdWUpOworCQlyZXR1cm4gdjsJLy8gbm90IGVuY29kZWQgY29ycmVjdGx5PyAgcmV0dXJuIGFzIGlzLgorCSAgICB9CisJICAgIFN0cmluZyBjaGFyc2V0ID0gdmFsdWUuc3Vic3RyaW5nKDAsIGkpOworCSAgICBpbnQgbGkgPSB2YWx1ZS5pbmRleE9mKCdcJycsIGkgKyAxKTsKKwkgICAgaWYgKGxpIDwgMCkgeworCQlpZiAoZGVjb2RlUGFyYW1ldGVyc1N0cmljdCkKKwkJICAgIHRocm93IG5ldyBQYXJzZUV4Y2VwdGlvbigKKwkJCSJNaXNzaW5nIGxhbmd1YWdlIGluIGVuY29kZWQgdmFsdWU6ICIgKyB2YWx1ZSk7CisJCXJldHVybiB2OwkvLyBub3QgZW5jb2RlZCBjb3JyZWN0bHk/ICByZXR1cm4gYXMgaXMuCisJICAgIH0KKwkgICAgLy8gU3RyaW5nIGxhbmcgPSB2YWx1ZS5zdWJzdHJpbmcoaSArIDEsIGxpKTsKKwkgICAgdi52YWx1ZSA9IHZhbHVlLnN1YnN0cmluZyhsaSArIDEpOworCSAgICB2LmNoYXJzZXQgPSBjaGFyc2V0OworCX0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBuZXgpIHsKKwkgICAgaWYgKGRlY29kZVBhcmFtZXRlcnNTdHJpY3QpCisJCXRocm93IG5ldyBQYXJzZUV4Y2VwdGlvbihuZXgudG9TdHJpbmcoKSk7CisJfSBjYXRjaCAoU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBleCkgeworCSAgICBpZiAoZGVjb2RlUGFyYW1ldGVyc1N0cmljdCkKKwkJdGhyb3cgbmV3IFBhcnNlRXhjZXB0aW9uKGV4LnRvU3RyaW5nKCkpOworCX0KKwlyZXR1cm4gdjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZWNvZGUgdGhlIGVuY29kZWQgYnl0ZXMgaW4gdmFsdWUgdXNpbmcgdGhlIHNwZWNpZmllZCBjaGFyc2V0LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBkZWNvZGVCeXRlcyhTdHJpbmcgdmFsdWUsIFN0cmluZyBjaGFyc2V0KQorCQkJdGhyb3dzIFBhcnNlRXhjZXB0aW9uLCBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIHsKKwkvKgorCSAqIERlY29kZSB0aGUgQVNDSUkgY2hhcmFjdGVycyBpbiB2YWx1ZQorCSAqIGludG8gYW4gYXJyYXkgb2YgYnl0ZXMsIGFuZCB0aGVuIGNvbnZlcnQKKwkgKiB0aGUgYnl0ZXMgdG8gYSBTdHJpbmcgdXNpbmcgdGhlIHNwZWNpZmllZAorCSAqIGNoYXJzZXQuICBXZSdsbCBuZXZlciBuZWVkIG1vcmUgYnl0ZXMgdGhhbgorCSAqIGVuY29kZWQgY2hhcmFjdGVycywgc28gdXNlIHRoYXQgdG8gc2l6ZSB0aGUKKwkgKiBhcnJheS4KKwkgKi8KKwlieXRlW10gYiA9IG5ldyBieXRlW3ZhbHVlLmxlbmd0aCgpXTsKKwlpbnQgaSwgYmk7CisJZm9yIChpID0gMCwgYmkgPSAwOyBpIDwgdmFsdWUubGVuZ3RoKCk7IGkrKykgeworCSAgICBjaGFyIGMgPSB2YWx1ZS5jaGFyQXQoaSk7CisJICAgIGlmIChjID09ICclJykgeworCQl0cnkgeworCQkgICAgU3RyaW5nIGhleCA9IHZhbHVlLnN1YnN0cmluZyhpICsgMSwgaSArIDMpOworCQkgICAgYyA9IChjaGFyKUludGVnZXIucGFyc2VJbnQoaGV4LCAxNik7CisJCSAgICBpICs9IDI7CisJCX0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBleCkgeworCQkgICAgaWYgKGRlY29kZVBhcmFtZXRlcnNTdHJpY3QpCisJCQl0aHJvdyBuZXcgUGFyc2VFeGNlcHRpb24oZXgudG9TdHJpbmcoKSk7CisJCX0gY2F0Y2ggKFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXgpIHsKKwkJICAgIGlmIChkZWNvZGVQYXJhbWV0ZXJzU3RyaWN0KQorCQkJdGhyb3cgbmV3IFBhcnNlRXhjZXB0aW9uKGV4LnRvU3RyaW5nKCkpOworCQl9CisJICAgIH0KKwkgICAgYltiaSsrXSA9IChieXRlKWM7CisJfQorCWlmIChjaGFyc2V0ICE9IG51bGwpCisJICAgIGNoYXJzZXQgPSBNaW1lVXRpbGl0eS5qYXZhQ2hhcnNldChjaGFyc2V0KTsKKwlpZiAoY2hhcnNldCA9PSBudWxsIHx8IGNoYXJzZXQubGVuZ3RoKCkgPT0gMCkKKwkgICAgY2hhcnNldCA9IE1pbWVVdGlsaXR5LmdldERlZmF1bHRKYXZhQ2hhcnNldCgpOworCXJldHVybiBuZXcgU3RyaW5nKGIsIDAsIGJpLCBjaGFyc2V0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZWNvZGUgdGhlIGVuY29kZWQgYnl0ZXMgaW4gdmFsdWUgYW5kIHdyaXRlIHRoZW0gdG8gdGhlIE91dHB1dFN0cmVhbS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGRlY29kZUJ5dGVzKFN0cmluZyB2YWx1ZSwgT3V0cHV0U3RyZWFtIG9zKQorCQkJCXRocm93cyBQYXJzZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworCS8qCisJICogRGVjb2RlIHRoZSBBU0NJSSBjaGFyYWN0ZXJzIGluIHZhbHVlCisJICogYW5kIHdyaXRlIHRoZW0gdG8gdGhlIHN0cmVhbS4KKwkgKi8KKwlpbnQgaTsKKwlmb3IgKGkgPSAwOyBpIDwgdmFsdWUubGVuZ3RoKCk7IGkrKykgeworCSAgICBjaGFyIGMgPSB2YWx1ZS5jaGFyQXQoaSk7CisJICAgIGlmIChjID09ICclJykgeworCQl0cnkgeworCQkgICAgU3RyaW5nIGhleCA9IHZhbHVlLnN1YnN0cmluZyhpICsgMSwgaSArIDMpOworCQkgICAgYyA9IChjaGFyKUludGVnZXIucGFyc2VJbnQoaGV4LCAxNik7CisJCSAgICBpICs9IDI7CisJCX0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBleCkgeworCQkgICAgaWYgKGRlY29kZVBhcmFtZXRlcnNTdHJpY3QpCisJCQl0aHJvdyBuZXcgUGFyc2VFeGNlcHRpb24oZXgudG9TdHJpbmcoKSk7CisJCX0gY2F0Y2ggKFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXgpIHsKKwkJICAgIGlmIChkZWNvZGVQYXJhbWV0ZXJzU3RyaWN0KQorCQkJdGhyb3cgbmV3IFBhcnNlRXhjZXB0aW9uKGV4LnRvU3RyaW5nKCkpOworCQl9CisJICAgIH0KKwkgICAgb3Mud3JpdGUoKGJ5dGUpYyk7CisJfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2ludGVybmV0L1BhcnNlRXhjZXB0aW9uLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9QYXJzZUV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg0OTdiZTgKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9QYXJzZUV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNDYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5pbnRlcm5ldDsKKworaW1wb3J0IGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uOworCisvKioKKyAqIFRoZSBleGNlcHRpb24gdGhyb3duIGR1ZSB0byBhbiBlcnJvciBpbiBwYXJzaW5nIFJGQzgyMiAKKyAqIG9yIE1JTUUgaGVhZGVycywgaW5jbHVkaW5nIG11bHRpcGFydCBib2RpZXMuCisgKgorICogQGF1dGhvciBKb2huIE1hbmkKKyAqLworCitwdWJsaWMgY2xhc3MgUGFyc2VFeGNlcHRpb24gZXh0ZW5kcyBNZXNzYWdpbmdFeGNlcHRpb24geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNzY0OTk5MTIwNTE4MzY1ODA4OUw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgUGFyc2VFeGNlcHRpb24gd2l0aCBubyBkZXRhaWwgbWVzc2FnZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgUGFyc2VFeGNlcHRpb24oKSB7CisJc3VwZXIoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgUGFyc2VFeGNlcHRpb24gd2l0aCB0aGUgc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlLgorICAgICAqIEBwYXJhbSBzCQl0aGUgZGV0YWlsIG1lc3NhZ2UKKyAgICAgKi8KKyAgICBwdWJsaWMgUGFyc2VFeGNlcHRpb24oU3RyaW5nIHMpIHsKKwlzdXBlcihzKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9QcmVlbmNvZGVkTWltZUJvZHlQYXJ0LmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9QcmVlbmNvZGVkTWltZUJvZHlQYXJ0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzE4OGVjYQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2ludGVybmV0L1ByZWVuY29kZWRNaW1lQm9keVBhcnQuamF2YQpAQCAtMCwwICsxLDEwNSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsLmludGVybmV0OworCitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKK2ltcG9ydCBqYXZheC5tYWlsLio7CisKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5MaW5lT3V0cHV0U3RyZWFtOworCisvKioKKyAqIEEgTWltZUJvZHlQYXJ0IHRoYXQgaGFuZGxlcyBkYXRhIHRoYXQgaGFzIGFscmVhZHkgYmVlbiBlbmNvZGVkLgorICogVGhpcyBjbGFzcyBpcyB1c2VmdWwgd2hlbiBjb25zdHJ1Y3RpbmcgYSBtZXNzYWdlIGFuZCBhdHRhY2hpbmcKKyAqIGRhdGEgdGhhdCBoYXMgYWxyZWFkeSBiZWVuIGVuY29kZWQgKGZvciBleGFtcGxlLCB1c2luZyBiYXNlNjQKKyAqIGVuY29kaW5nKS4gIFRoZSBkYXRhIG1heSBoYXZlIGJlZW4gZW5jb2RlZCBieSB0aGUgYXBwbGljYXRpb24sCisgKiBvciBtYXkgaGF2ZSBiZWVuIHN0b3JlZCBpbiBhIGZpbGUgb3IgZGF0YWJhc2UgaW4gZW5jb2RlZCBmb3JtLgorICogVGhlIGVuY29kaW5nIGlzIHN1cHBsaWVkIHdoZW4gdGhpcyBvYmplY3QgaXMgY3JlYXRlZC4gIFRoZSBkYXRhCisgKiBpcyBhdHRhY2hlZCB0byB0aGlzIG9iamVjdCBpbiB0aGUgdXN1YWwgZmFzaGlvbiwgYnkgdXNpbmcgdGhlCisgKiA8Y29kZT5zZXRUZXh0PC9jb2RlPiwgPGNvZGU+c2V0Q29udGVudDwvY29kZT4sIG9yCisgKiA8Y29kZT5zZXREYXRhSGFuZGxlcjwvY29kZT4gbWV0aG9kcy4KKyAqCisgKiBAc2luY2UJSmF2YU1haWwgMS40CisgKi8KKworcHVibGljIGNsYXNzIFByZWVuY29kZWRNaW1lQm9keVBhcnQgZXh0ZW5kcyBNaW1lQm9keVBhcnQgeworICAgIHByaXZhdGUgU3RyaW5nIGVuY29kaW5nOworCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgUHJlZW5jb2RlZE1pbWVCb2R5UGFydCB0aGF0IGFzc3VtZXMgdGhlIGRhdGEgaXMKKyAgICAgKiBlbmNvZGVkIHVzaW5nIHRoZSBzcGVjaWZpZWQgZW5jb2RpbmcuICBUaGUgZW5jb2RpbmcgbXVzdAorICAgICAqIGJlIGEgTUlNRSBzdXBwb3J0ZWQgQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZy4KKyAgICAgKgorICAgICAqIEBwYXJhbQllbmNvZGluZwl0aGUgQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZworICAgICAqLworICAgIHB1YmxpYyBQcmVlbmNvZGVkTWltZUJvZHlQYXJ0KFN0cmluZyBlbmNvZGluZykgeworCXRoaXMuZW5jb2RpbmcgPSBlbmNvZGluZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBjb250ZW50IHRyYW5zZmVyIGVuY29kaW5nIHNwZWNpZmllZCB3aGVuCisgICAgICogdGhpcyBvYmplY3Qgd2FzIGNyZWF0ZWQuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyBnZXRFbmNvZGluZygpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXJldHVybiBlbmNvZGluZzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBPdXRwdXQgdGhlIGJvZHkgcGFydCBhcyBhbiBSRkMgODIyIGZvcm1hdCBzdHJlYW0uCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uIElPRXhjZXB0aW9uCWlmIGFuIGVycm9yIG9jY3VycyB3cml0aW5nIHRvIHRoZQorICAgICAqCQkJCXN0cmVhbSBvciBpZiBhbiBlcnJvciBpcyBnZW5lcmF0ZWQKKyAgICAgKgkJCQlieSB0aGUgamF2YXguYWN0aXZhdGlvbiBsYXllci4KKyAgICAgKiBAZXhjZXB0aW9uIE1lc3NhZ2luZ0V4Y2VwdGlvbiBmb3Igb3RoZXIgZmFpbHVyZXMKKyAgICAgKiBAc2VlIGphdmF4LmFjdGl2YXRpb24uRGF0YUhhbmRsZXIjd3JpdGVUbworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oT3V0cHV0U3RyZWFtIG9zKQorCQkJdGhyb3dzIElPRXhjZXB0aW9uLCBNZXNzYWdpbmdFeGNlcHRpb24geworCisJLy8gc2VlIGlmIHdlIGFscmVhZHkgaGF2ZSBhIExPUworCUxpbmVPdXRwdXRTdHJlYW0gbG9zID0gbnVsbDsKKwlpZiAob3MgaW5zdGFuY2VvZiBMaW5lT3V0cHV0U3RyZWFtKSB7CisJICAgIGxvcyA9IChMaW5lT3V0cHV0U3RyZWFtKSBvczsKKwl9IGVsc2UgeworCSAgICBsb3MgPSBuZXcgTGluZU91dHB1dFN0cmVhbShvcyk7CisJfQorCisJLy8gRmlyc3QsIHdyaXRlIG91dCB0aGUgaGVhZGVyCisJRW51bWVyYXRpb248U3RyaW5nPiBoZHJMaW5lcyA9IGdldEFsbEhlYWRlckxpbmVzKCk7CisJd2hpbGUgKGhkckxpbmVzLmhhc01vcmVFbGVtZW50cygpKQorCSAgICBsb3Mud3JpdGVsbihoZHJMaW5lcy5uZXh0RWxlbWVudCgpKTsKKworCS8vIFRoZSBDUkxGIHNlcGFyYXRvciBiZXR3ZWVuIGhlYWRlciBhbmQgY29udGVudAorCWxvcy53cml0ZWxuKCk7CisKKwkvLyBGaW5hbGx5LCB0aGUgY29udGVudCwgYWxyZWFkeSBlbmNvZGVkLgorCWdldERhdGFIYW5kbGVyKCkud3JpdGVUbyhvcyk7CisJb3MuZmx1c2goKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGb3JjZSB0aGUgPGNvZGU+Q29udGVudC1UcmFuc2Zlci1FbmNvZGluZzwvY29kZT4gaGVhZGVyIHRvIHVzZQorICAgICAqIHRoZSBlbmNvZGluZyB0aGF0IHdhcyBzcGVjaWZpZWQgd2hlbiB0aGlzIG9iamVjdCB3YXMgY3JlYXRlZC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCB1cGRhdGVIZWFkZXJzKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJc3VwZXIudXBkYXRlSGVhZGVycygpOworCU1pbWVCb2R5UGFydC5zZXRFbmNvZGluZyh0aGlzLCBlbmNvZGluZyk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvU2hhcmVkSW5wdXRTdHJlYW0uamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2ludGVybmV0L1NoYXJlZElucHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjVjZDQxOQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2ludGVybmV0L1NoYXJlZElucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSw2MCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsLmludGVybmV0OworCitpbXBvcnQgamF2YS5pby4qOworCisvKioKKyAqIEFuIElucHV0U3RyZWFtIHRoYXQgaXMgYmFja2VkIGJ5IGRhdGEgdGhhdCBjYW4gYmUgc2hhcmVkIGJ5IG11bHRpcGxlCisgKiByZWFkZXJzIG1heSBpbXBsZW1lbnQgdGhpcyBpbnRlcmZhY2UuICBUaGlzIGFsbG93cyB1c2VycyBvZiBzdWNoIGFuCisgKiBJbnB1dFN0cmVhbSB0byBkZXRlcm1pbmUgdGhlIGN1cnJlbnQgcG9zaXRpb24gaW4gdGhlIElucHV0U3RyZWFtLCBhbmQKKyAqIHRvIGNyZWF0ZSBuZXcgSW5wdXRTdHJlYW1zIHJlcHJlc2VudGluZyBhIHN1YnNldCBvZiB0aGUgZGF0YSBpbiB0aGUKKyAqIG9yaWdpbmFsIElucHV0U3RyZWFtLiAgVGhlIG5ldyBJbnB1dFN0cmVhbSB3aWxsIGFjY2VzcyB0aGUgc2FtZQorICogdW5kZXJseWluZyBkYXRhIGFzIHRoZSBvcmlnaW5hbCwgd2l0aG91dCBjb3B5aW5nIHRoZSBkYXRhLiA8cD4KKyAqCisgKiBOb3RlIHRoYXQgaW1wbGVtZW50YXRpb25zIG9mIHRoaXMgaW50ZXJmYWNlIG11c3QgZW5zdXJlIHRoYXQgdGhlCisgKiA8Y29kZT5jbG9zZTwvY29kZT4gbWV0aG9kIGRvZXMgbm90IGNsb3NlIGFueSB1bmRlcmx5aW5nIHN0cmVhbQorICogdGhhdCBtaWdodCBiZSBzaGFyZWQgYnkgbXVsdGlwbGUgaW5zdGFuY2VzIG9mIDxjb2RlPlNoYXJlZElucHV0U3RyZWFtPC9jb2RlPgorICogdW50aWwgYWxsIHNoYXJlZCBpbnN0YW5jZXMgaGF2ZSBiZWVuIGNsb3NlZC4KKyAqCisgKiBAYXV0aG9yICBCaWxsIFNoYW5ub24KKyAqIEBzaW5jZSBKYXZhTWFpbCAxLjIKKyAqLworCitwdWJsaWMgaW50ZXJmYWNlIFNoYXJlZElucHV0U3RyZWFtIHsKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIGN1cnJlbnQgcG9zaXRpb24gaW4gdGhlIElucHV0U3RyZWFtLCBhcyBhbgorICAgICAqIG9mZnNldCBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhlIElucHV0U3RyZWFtLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgY3VycmVudCBwb3NpdGlvbgorICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldFBvc2l0aW9uKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYSBuZXcgSW5wdXRTdHJlYW0gcmVwcmVzZW50aW5nIGEgc3Vic2V0IG9mIHRoZSBkYXRhCisgICAgICogZnJvbSB0aGlzIElucHV0U3RyZWFtLCBzdGFydGluZyBhdCA8Y29kZT5zdGFydDwvY29kZT4gKGluY2x1c2l2ZSkKKyAgICAgKiB1cCB0byA8Y29kZT5lbmQ8L2NvZGU+IChleGNsdXNpdmUpLiAgPGNvZGU+c3RhcnQ8L2NvZGU+IG11c3QgYmUKKyAgICAgKiBub24tbmVnYXRpdmUuICBJZiA8Y29kZT5lbmQ8L2NvZGU+IGlzIC0xLCB0aGUgbmV3IHN0cmVhbSBlbmRzCisgICAgICogYXQgdGhlIHNhbWUgcGxhY2UgYXMgdGhpcyBzdHJlYW0uICBUaGUgcmV0dXJuZWQgSW5wdXRTdHJlYW0KKyAgICAgKiB3aWxsIGFsc28gaW1wbGVtZW50IHRoZSBTaGFyZWRJbnB1dFN0cmVhbSBpbnRlcmZhY2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0Jc3RhcnQJdGhlIHN0YXJ0aW5nIHBvc2l0aW9uCisgICAgICogQHBhcmFtCWVuZAl0aGUgZW5kaW5nIHBvc2l0aW9uICsgMQorICAgICAqIEByZXR1cm4JCXRoZSBuZXcgc3RyZWFtCisgICAgICovCisgICAgcHVibGljIElucHV0U3RyZWFtIG5ld1N0cmVhbShsb25nIHN0YXJ0LCBsb25nIGVuZCk7Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9VbmlxdWVWYWx1ZS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvVW5pcXVlVmFsdWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hM2U5ZjhjCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvVW5pcXVlVmFsdWUuamF2YQpAQCAtMCwwICsxLDk1IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGphdmF4Lm1haWwuaW50ZXJuZXQ7CisKK2ltcG9ydCBqYXZhLm5ldC4qOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy5BdG9taWNJbnRlZ2VyOworaW1wb3J0IGphdmF4Lm1haWwuU2Vzc2lvbjsKKworLyoqCisgKiBUaGlzIGlzIGEgdXRpbGl0eSBjbGFzcyB0aGF0IGdlbmVyYXRlcyB1bmlxdWUgdmFsdWVzLiBUaGUgZ2VuZXJhdGVkCisgKiBTdHJpbmcgY29udGFpbnMgb25seSBVUy1BU0NJSSBjaGFyYWN0ZXJzIGFuZCBoZW5jZSBpcyBzYWZlIGZvciB1c2UKKyAqIGluIFJGQzgyMiBoZWFkZXJzLiA8cD4KKyAqCisgKiBUaGlzIGlzIGEgcGFja2FnZSBwcml2YXRlIGNsYXNzLgorICoKKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKiBAYXV0aG9yIE1heCBTcGl2YWsKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKi8KKworY2xhc3MgVW5pcXVlVmFsdWUgeworICAgIC8qKgorICAgICAqIEEgZ2xvYmFsIHVuaXF1ZSBudW1iZXIsIHRvIGVuc3VyZSB1bmlxdWVuZXNzIG9mIGdlbmVyYXRlZCBzdHJpbmdzLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIEF0b21pY0ludGVnZXIgaWQgPSBuZXcgQXRvbWljSW50ZWdlcigpOworCisgICAgLyoqCisgICAgICogR2V0IGEgdW5pcXVlIHZhbHVlIGZvciB1c2UgaW4gYSBtdWx0aXBhcnQgYm91bmRhcnkgc3RyaW5nLgorICAgICAqCisgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiBnZW5lcmF0ZXMgaXQgYnkgY29uY2F0ZW5hdGluZyBhIGdsb2JhbAorICAgICAqIHBhcnQgbnVtYmVyLCBhIG5ld2x5IGNyZWF0ZWQgb2JqZWN0J3MgPGNvZGU+aGFzaENvZGUoKTwvY29kZT4sCisgICAgICogYW5kIHRoZSBjdXJyZW50IHRpbWUgKGluIG1pbGxpc2Vjb25kcykuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0VW5pcXVlQm91bmRhcnlWYWx1ZSgpIHsKKwlTdHJpbmdCdWlsZGVyIHMgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworCWxvbmcgaGFzaCA9IHMuaGFzaENvZGUoKTsKKworCS8vIFVuaXF1ZSBzdHJpbmcgaXMgLS0tLT1fUGFydF88cGFydD5fPGhhc2hjb2RlPi48Y3VycmVudFRpbWU+CisJcy5hcHBlbmQoIi0tLS09X1BhcnRfIikuYXBwZW5kKGlkLmdldEFuZEluY3JlbWVudCgpKS5hcHBlbmQoIl8iKS4KKwkgIGFwcGVuZChoYXNoKS5hcHBlbmQoJy4nKS4KKwkgIGFwcGVuZChTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSk7CisJcmV0dXJuIHMudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgYSB1bmlxdWUgdmFsdWUgZm9yIHVzZSBpbiBhIE1lc3NhZ2UtSUQuCisgICAgICoKKyAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIGdlbmVyYXRlcyBpdCBieSBjb25jYXRlbmF0aW5nIGEgbmV3bHkKKyAgICAgKiBjcmVhdGVkIG9iamVjdCdzIDxjb2RlPmhhc2hDb2RlKCk8L2NvZGU+LCBhIGdsb2JhbCBJRAorICAgICAqIChpbmNyZW1lbnRlZCBvbiBldmVyeSB1c2UpLCB0aGUgY3VycmVudCB0aW1lIChpbiBtaWxsaXNlY29uZHMpLAorICAgICAqIGFuZCB0aGUgaG9zdCBuYW1lIGZyb20gdGhpcyB1c2VyJ3MgbG9jYWwgYWRkcmVzcyBnZW5lcmF0ZWQgYnkgCisgICAgICogPGNvZGU+SW50ZXJuZXRBZGRyZXNzLmdldExvY2FsQWRkcmVzcygpPC9jb2RlPi4KKyAgICAgKiAoVGhlIGhvc3QgbmFtZSBkZWZhdWx0cyB0byAibG9jYWxob3N0IiBpZgorICAgICAqIDxjb2RlPmdldExvY2FsQWRkcmVzcygpPC9jb2RlPiByZXR1cm5zIG51bGwuKQorICAgICAqCisgICAgICogQHBhcmFtIHNzbiBTZXNzaW9uIG9iamVjdCB1c2VkIHRvIGdldCB0aGUgbG9jYWwgYWRkcmVzcworICAgICAqIEBzZWUgamF2YXgubWFpbC5pbnRlcm5ldC5JbnRlcm5ldEFkZHJlc3MKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRVbmlxdWVNZXNzYWdlSURWYWx1ZShTZXNzaW9uIHNzbikgeworCVN0cmluZyBzdWZmaXggPSBudWxsOworCisJSW50ZXJuZXRBZGRyZXNzIGFkZHIgPSBJbnRlcm5ldEFkZHJlc3MuZ2V0TG9jYWxBZGRyZXNzKHNzbik7CisJaWYgKGFkZHIgIT0gbnVsbCkKKwkgICAgc3VmZml4ID0gYWRkci5nZXRBZGRyZXNzKCk7CisJZWxzZSB7CisJICAgIHN1ZmZpeCA9ICJqYXZhbWFpbHVzZXJAbG9jYWxob3N0IjsgLy8gd29yc3QtY2FzZSBkZWZhdWx0CisJfQorCWludCBhdCA9IHN1ZmZpeC5sYXN0SW5kZXhPZignQCcpOworCWlmIChhdCA+PSAwKQorCSAgICBzdWZmaXggPSBzdWZmaXguc3Vic3RyaW5nKGF0KTsKKworCVN0cmluZ0J1aWxkZXIgcyA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisKKwkvLyBVbmlxdWUgc3RyaW5nIGlzIDxoYXNoY29kZT4uPGlkPi48Y3VycmVudFRpbWU+PHN1ZmZpeD4KKwlzLmFwcGVuZChzLmhhc2hDb2RlKCkpLmFwcGVuZCgnLicpLgorCSAgYXBwZW5kKGlkLmdldEFuZEluY3JlbWVudCgpKS5hcHBlbmQoJy4nKS4KKwkgIGFwcGVuZChTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSkuCisJICBhcHBlbmQoc3VmZml4KTsKKwlyZXR1cm4gcy50b1N0cmluZygpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2ludGVybmV0L3BhY2thZ2UuaHRtbCBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL2ludGVybmV0L3BhY2thZ2UuaHRtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ZWNmNGFmCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvcGFja2FnZS5odG1sCkBAIC0wLDAgKzEsNTQ4IEBACis8IURPQ1RZUEUgaHRtbCBQVUJMSUMgIi0vL1czQy8vRFREIEhUTUwgNC4wMSBUcmFuc2l0aW9uYWwvL0VOIj4KKzxIVE1MPgorPEhFQUQ+Cis8bWV0YSBodHRwLWVxdWl2PSJDb250ZW50LVR5cGUiIGNvbnRlbnQ9InRleHQvaHRtbDsgY2hhcnNldD11dGYtOCI+Cis8IS0tCisKKyAgICBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKworICAgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICAgIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorCisgICAgVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICAgIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAgICBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAgICB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKworICAgIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorCistLT4KKworPFRJVExFPmphdmF4Lm1haWwuaW50ZXJuZXQgcGFja2FnZTwvVElUTEU+Cis8L0hFQUQ+Cis8Qk9EWSBCR0NPTE9SPSJ3aGl0ZSI+CisKKzxQPgorQ2xhc3NlcyBzcGVjaWZpYyB0byBJbnRlcm5ldCBtYWlsIHN5c3RlbXMuCitUaGlzIHBhY2thZ2Ugc3VwcG9ydHMgZmVhdHVyZXMgdGhhdCBhcmUgc3BlY2lmaWMgdG8gSW50ZXJuZXQgbWFpbCBzeXN0ZW1zCitiYXNlZCBvbiB0aGUgTUlNRSBzdGFuZGFyZAorKDxBIEhSRUY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIwNDUudHh0IiBUQVJHRVQ9Il90b3AiPlJGQyAyMDQ1PC9BPiwKKzxBIEhSRUY9Imh0dHA6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzIwNDUudHh0IiBUQVJHRVQ9Il90b3AiPlJGQyAyMDQ2PC9BPiwgYW5kCis8QSBIUkVGPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMDQ1LnR4dCIgVEFSR0VUPSJfdG9wIj5SRkMgMjA0NzwvQT4pLgorVGhlIElNQVAsIFNNVFAsIGFuZCBQT1AzIHByb3RvY29scyB1c2UKK3tAbGluayBqYXZheC5tYWlsLmludGVybmV0Lk1pbWVNZXNzYWdlIE1pbWVNZXNzYWdlc30uCis8L1A+Cis8QSBOQU1FPSJwcm9wZXJ0aWVzIj48U1RST05HPlByb3BlcnRpZXM8L1NUUk9ORz48L0E+Cis8UD4KK1RoZSBKYXZhTWFpbCBBUEkgc3VwcG9ydHMgdGhlIGZvbGxvd2luZyBzdGFuZGFyZCBwcm9wZXJ0aWVzLAord2hpY2ggbWF5IGJlIHNldCBpbiB0aGUgPGNvZGU+U2Vzc2lvbjwvY29kZT4gb2JqZWN0LCBvciBpbiB0aGUKKzxjb2RlPlByb3BlcnRpZXM8L2NvZGU+IG9iamVjdCB1c2VkIHRvIGNyZWF0ZSB0aGUgPGNvZGU+U2Vzc2lvbjwvY29kZT4gb2JqZWN0LgorVGhlIHByb3BlcnRpZXMgYXJlIGFsd2F5cyBzZXQgYXMgc3RyaW5nczsgdGhlIFR5cGUgY29sdW1uIGRlc2NyaWJlcworaG93IHRoZSBzdHJpbmcgaXMgaW50ZXJwcmV0ZWQuICBGb3IgZXhhbXBsZSwgdXNlCis8L1A+Cis8UFJFPgorCXNlc3Npb24uc2V0UHJvcGVydHkoIm1haWwubWltZS5hZGRyZXNzLnN0cmljdCIsICJmYWxzZSIpOworPC9QUkU+Cis8UD4KK3RvIHNldCB0aGUgPENPREU+bWFpbC5taW1lLmFkZHJlc3Muc3RyaWN0PC9DT0RFPiBwcm9wZXJ0eSwKK3doaWNoIGlzIG9mIHR5cGUgYm9vbGVhbi4KKzwvUD4KKzxUQUJMRSBCT1JERVIgU1VNTUFSWT0iSmF2YU1haWwgcHJvcGVydGllcyI+Cis8VFI+Cis8VEg+TmFtZTwvVEg+Cis8VEg+VHlwZTwvVEg+Cis8VEg+RGVzY3JpcHRpb248L1RIPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwubWltZS5hZGRyZXNzLnN0cmljdCI+bWFpbC5taW1lLmFkZHJlc3Muc3RyaWN0PC9BPjwvVEQ+Cis8VEQ+Ym9vbGVhbjwvVEQ+Cis8VEQ+CitUaGUgPGNvZGU+bWFpbC5taW1lLmFkZHJlc3Muc3RyaWN0PC9jb2RlPiBzZXNzaW9uIHByb3BlcnR5IGNvbnRyb2xzCit0aGUgcGFyc2luZyBvZiBhZGRyZXNzIGhlYWRlcnMuICBCeSBkZWZhdWx0LCBzdHJpY3QgcGFyc2luZyBvZiBhZGRyZXNzCitoZWFkZXJzIGlzIGRvbmUuICBJZiB0aGlzIHByb3BlcnR5IGlzIHNldCB0byA8Y29kZT4iZmFsc2UiPC9jb2RlPiwKK3N0cmljdCBwYXJzaW5nIGlzIG5vdCBkb25lIGFuZCBtYW55IGlsbGVnYWwgYWRkcmVzc2VzIHRoYXQgc29tZXRpbWVzCitvY2N1ciBpbiByZWFsIG1lc3NhZ2VzIGFyZSBhbGxvd2VkLiAgU2VlIHRoZSA8Y29kZT5JbnRlcm5ldEFkZHJlc3M8L2NvZGU+CitjbGFzcyBmb3IgZGV0YWlscy4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5taW1lLmFsbG93dXRmOCI+bWFpbC5taW1lLmFsbG93dXRmODwvQT48L1REPgorPFREPmJvb2xlYW48L1REPgorPFREPgorSWYgc2V0IHRvIDxjb2RlPiJ0cnVlIjwvY29kZT4sIFVURi04IHN0cmluZ3MgYXJlIGFsbG93ZWQgaW4gbWVzc2FnZSBoZWFkZXJzLAorZS5nLiwgaW4gYWRkcmVzc2VzLiAgVGhpcyBzaG91bGQgPGI+b25seTwvYj4gYmUgc2V0IGlmIHRoZSBtYWlsIHNlcnZlciBhbHNvCitzdXBwb3J0cyBVVEYtOC4KKzwvVEQ+Cis8L1RSPgorPC9UQUJMRT4KKzxQPgorVGhlIEphdmFNYWlsIEFQSSBzcGVjaWZpY2F0aW9uIHJlcXVpcmVzIHN1cHBvcnQgZm9yIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllcywKK3doaWNoIG11c3QgYmUgc2V0IGluIHRoZSA8Y29kZT5TeXN0ZW08L2NvZGU+IHByb3BlcnRpZXMuCitUaGUgcHJvcGVydGllcyBhcmUgYWx3YXlzIHNldCBhcyBzdHJpbmdzOyB0aGUgVHlwZSBjb2x1bW4gZGVzY3JpYmVzCitob3cgdGhlIHN0cmluZyBpcyBpbnRlcnByZXRlZC4gIEZvciBleGFtcGxlLCB1c2UKKzwvUD4KKzxQUkU+CisJU3lzdGVtLnNldFByb3BlcnR5KCJtYWlsLm1pbWUuZGVjb2RldGV4dC5zdHJpY3QiLCAiZmFsc2UiKTsKKzwvUFJFPgorPFA+Cit0byBzZXQgdGhlIDxDT0RFPm1haWwubWltZS5kZWNvZGV0ZXh0LnN0cmljdDwvQ09ERT4gcHJvcGVydHksCit3aGljaCBpcyBvZiB0eXBlIGJvb2xlYW4uCis8L1A+Cis8VEFCTEUgQk9SREVSIFNVTU1BUlk9IkphdmFNYWlsIFN5c3RlbSBwcm9wZXJ0aWVzIj4KKzxUUj4KKzxUSD5OYW1lPC9USD4KKzxUSD5UeXBlPC9USD4KKzxUSD5EZXNjcmlwdGlvbjwvVEg+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5taW1lLmNoYXJzZXQiPm1haWwubWltZS5jaGFyc2V0PC9BPjwvVEQ+Cis8VEQ+U3RyaW5nPC9URD4KKzxURD4KK1RoZSA8Y29kZT5tYWlsLm1pbWUuY2hhcnNldDwvY29kZT4gU3lzdGVtIHByb3BlcnR5IGNhbgorYmUgdXNlZCB0byBzcGVjaWZ5IHRoZSBkZWZhdWx0IE1JTUUgY2hhcnNldCB0byB1c2UgZm9yIGVuY29kZWQgd29yZHMKK2FuZCB0ZXh0IHBhcnRzIHRoYXQgZG9uJ3Qgb3RoZXJ3aXNlIHNwZWNpZnkgYSBjaGFyc2V0LiAgTm9ybWFsbHksIHRoZQorZGVmYXVsdCBNSU1FIGNoYXJzZXQgaXMgZGVyaXZlZCBmcm9tIHRoZSBkZWZhdWx0IEphdmEgY2hhcnNldCwgYXMKK3NwZWNpZmllZCBpbiB0aGUgPGNvZGU+ZmlsZS5lbmNvZGluZzwvY29kZT4gU3lzdGVtIHByb3BlcnR5LiAgTW9zdAorYXBwbGljYXRpb25zIHdpbGwgaGF2ZSBubyBuZWVkIHRvIGV4cGxpY2l0bHkgc2V0IHRoZSBkZWZhdWx0IE1JTUUKK2NoYXJzZXQuICBJbiBjYXNlcyB3aGVyZSB0aGUgZGVmYXVsdCBNSU1FIGNoYXJzZXQgdG8gYmUgdXNlZCBmb3IKK21haWwgbWVzc2FnZXMgaXMgZGlmZmVyZW50IHRoYW4gdGhlIGNoYXJzZXQgdXNlZCBmb3IgZmlsZXMgc3RvcmVkIG9uCit0aGUgc3lzdGVtLCB0aGlzIHByb3BlcnR5IHNob3VsZCBiZSBzZXQuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwubWltZS5kZWNvZGV0ZXh0LnN0cmljdCI+bWFpbC5taW1lLmRlY29kZXRleHQuc3RyaWN0PC9BPjwvVEQ+Cis8VEQ+Ym9vbGVhbjwvVEQ+Cis8VEQ+CitUaGUgPGNvZGU+bWFpbC5taW1lLmRlY29kZXRleHQuc3RyaWN0PC9jb2RlPiBwcm9wZXJ0eSBjb250cm9scworZGVjb2Rpbmcgb2YgTUlNRSBlbmNvZGVkIHdvcmRzLiAgVGhlIE1JTUUgc3BlYyByZXF1aXJlcyB0aGF0IGVuY29kZWQKK3dvcmRzIHN0YXJ0IGF0IHRoZSBiZWdpbm5pbmcgb2YgYSB3aGl0ZXNwYWNlIHNlcGFyYXRlZCB3b3JkLiAgU29tZQorbWFpbGVycyBpbmNvcnJlY3RseSBpbmNsdWRlIGVuY29kZWQgd29yZHMgaW4gdGhlIG1pZGRsZSBvZiBhIHdvcmQuCitJZiB0aGUgPGNvZGU+bWFpbC5taW1lLmRlY29kZXRleHQuc3RyaWN0PC9jb2RlPiBTeXN0ZW0gcHJvcGVydHkgaXMKK3NldCB0byA8Y29kZT4iZmFsc2UiPC9jb2RlPiwgYW4gYXR0ZW1wdCB3aWxsIGJlIG1hZGUgdG8gZGVjb2RlIHRoZXNlCitpbGxlZ2FsIGVuY29kZWQgd29yZHMuIFRoZSBkZWZhdWx0IGlzIHRydWUuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwubWltZS5lbmNvZGVlb2wuc3RyaWN0Ij5tYWlsLm1pbWUuZW5jb2RlZW9sLnN0cmljdDwvQT48L1REPgorPFREPmJvb2xlYW48L1REPgorPFREPgorVGhlIDxjb2RlPm1haWwubWltZS5lbmNvZGVlb2wuc3RyaWN0PC9jb2RlPiBwcm9wZXJ0eSBjb250cm9scyB0aGUKK2Nob2ljZSBvZiBDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nIGZvciBNSU1FIHBhcnRzIHRoYXQgYXJlIG5vdCBvZgordHlwZSAidGV4dCIuICBPZnRlbiBzdWNoIHBhcnRzIHdpbGwgY29udGFpbiB0ZXh0dWFsIGRhdGEgZm9yIHdoaWNoCithbiBlbmNvZGluZyB0aGF0IGFsbG93cyBub3JtYWwgZW5kIG9mIGxpbmUgY29udmVudGlvbnMgaXMgYXBwcm9wcmlhdGUuCitJbiByYXJlIGNhc2VzLCBzdWNoIGEgcGFydCB3aWxsIGFwcGVhciB0byBjb250YWluIGVudGlyZWx5IHRleHR1YWwKK2RhdGEsIGJ1dCB3aWxsIHJlcXVpcmUgYW4gZW5jb2RpbmcgdGhhdCBwcmVzZXJ2ZXMgQ1IgYW5kIExGIGNoYXJhY3RlcnMKK3dpdGhvdXQgY2hhbmdlLiAgSWYgdGhlIDxjb2RlPm1haWwubWltZS5lbmNvZGVlb2wuc3RyaWN0PC9jb2RlPgorU3lzdGVtIHByb3BlcnR5IGlzIHNldCB0byA8Y29kZT4idHJ1ZSI8L2NvZGU+LCBzdWNoIGFuIGVuY29kaW5nIHdpbGwKK2JlIHVzZWQgd2hlbiBuZWNlc3NhcnkuICBUaGUgZGVmYXVsdCBpcyBmYWxzZS4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5taW1lLmRlY29kZWZpbGVuYW1lIj5tYWlsLm1pbWUuZGVjb2RlZmlsZW5hbWU8L0E+PC9URD4KKzxURD5ib29sZWFuPC9URD4KKzxURD4KK0lmIHNldCB0byA8Y29kZT4idHJ1ZSI8L2NvZGU+LCB0aGUgPGNvZGU+Z2V0RmlsZU5hbWU8L2NvZGU+IG1ldGhvZAordXNlcyB0aGUgPGNvZGU+TWltZVV0aWxpdHk8L2NvZGU+CittZXRob2QgPGNvZGU+ZGVjb2RlVGV4dDwvY29kZT4gdG8gZGVjb2RlIGFueQorbm9uLUFTQ0lJIGNoYXJhY3RlcnMgaW4gdGhlIGZpbGVuYW1lLiAgTm90ZSB0aGF0IHRoaXMgZGVjb2RpbmcKK3Zpb2xhdGVzIHRoZSBNSU1FIHNwZWNpZmljYXRpb24sIGJ1dCBpcyB1c2VmdWwgZm9yIGludGVyb3BlcmF0aW5nCit3aXRoIHNvbWUgbWFpbCBjbGllbnRzIHRoYXQgdXNlIHRoaXMgY29udmVudGlvbi4KK1RoZSBkZWZhdWx0IGlzIGZhbHNlLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLm1pbWUuZW5jb2RlZmlsZW5hbWUiPm1haWwubWltZS5lbmNvZGVmaWxlbmFtZTwvQT48L1REPgorPFREPmJvb2xlYW48L1REPgorPFREPgorSWYgc2V0IHRvIDxjb2RlPiJ0cnVlIjwvY29kZT4sIHRoZSA8Y29kZT5zZXRGaWxlTmFtZTwvY29kZT4gbWV0aG9kCit1c2VzIHRoZSA8Y29kZT5NaW1lVXRpbGl0eTwvY29kZT4KK21ldGhvZCA8Y29kZT5lbmNvZGVUZXh0PC9jb2RlPiB0byBlbmNvZGUgYW55Citub24tQVNDSUkgY2hhcmFjdGVycyBpbiB0aGUgZmlsZW5hbWUuICBOb3RlIHRoYXQgdGhpcyBlbmNvZGluZwordmlvbGF0ZXMgdGhlIE1JTUUgc3BlY2lmaWNhdGlvbiwgYnV0IGlzIHVzZWZ1bCBmb3IgaW50ZXJvcGVyYXRpbmcKK3dpdGggc29tZSBtYWlsIGNsaWVudHMgdGhhdCB1c2UgdGhpcyBjb252ZW50aW9uLgorVGhlIGRlZmF1bHQgaXMgZmFsc2UuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwubWltZS5kZWNvZGVwYXJhbWV0ZXJzIj5tYWlsLm1pbWUuZGVjb2RlcGFyYW1ldGVyczwvQT48L1REPgorPFREPmJvb2xlYW48L1REPgorPFREPgorSWYgc2V0IHRvIDxjb2RlPiJmYWxzZSI8L2NvZGU+LCBub24tQVNDSUkgcGFyYW1ldGVycyBpbiBhCis8Y29kZT5QYXJhbWV0ZXJMaXN0PC9jb2RlPiwgZS5nLiwgaW4gYSBDb250ZW50LVR5cGUgaGVhZGVyLAord2lsbCA8Yj5ub3Q8L2I+IGJlIGRlY29kZWQgYXMgc3BlY2lmaWVkIGJ5Cis8QSBIUkVGPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMjMxLnR4dCIgVEFSR0VUPSJfdG9wIj5SRkMgMjIzMTwvQT4uCitUaGUgZGVmYXVsdCBpcyB0cnVlLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLm1pbWUuZW5jb2RlcGFyYW1ldGVycyI+bWFpbC5taW1lLmVuY29kZXBhcmFtZXRlcnM8L0E+PC9URD4KKzxURD5ib29sZWFuPC9URD4KKzxURD4KK0lmIHNldCB0byA8Y29kZT4iZmFsc2UiPC9jb2RlPiwgbm9uLUFTQ0lJIHBhcmFtZXRlcnMgaW4gYQorPGNvZGU+UGFyYW1ldGVyTGlzdDwvY29kZT4sIGUuZy4sIGluIGEgQ29udGVudC1UeXBlIGhlYWRlciwKK3dpbGwgPGI+bm90PC9iPiBiZSBlbmNvZGVkIGFzIHNwZWNpZmllZCBieQorPEEgSFJFRj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjIzMS50eHQiIFRBUkdFVD0iX3RvcCI+UkZDIDIyMzE8L0E+LgorVGhlIGRlZmF1bHQgaXMgdHJ1ZS4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5taW1lLm11bHRpcGFydC5pZ25vcmVtaXNzaW5nZW5kYm91bmRhcnkiPm1haWwubWltZS5tdWx0aXBhcnQuIGlnbm9yZW1pc3NpbmdlbmRib3VuZGFyeTwvQT48L1REPgorPFREPmJvb2xlYW48L1REPgorPFREPgorTm9ybWFsbHksIHdoZW4gcGFyc2luZyBhIG11bHRpcGFydCBNSU1FIG1lc3NhZ2UsIGEgbWVzc2FnZSB0aGF0IGlzCittaXNzaW5nIHRoZSBmaW5hbCBlbmQgYm91bmRhcnkgbGluZSBpcyBub3QgY29uc2lkZXJlZCBhbiBlcnJvci4KK1RoZSBkYXRhIHNpbXBseSBlbmRzIGF0IHRoZSBlbmQgb2YgdGhlIGlucHV0LiAgTm90ZSB0aGF0IG1lc3NhZ2VzCitvZiB0aGlzIGZvcm0gdmlvbGF0ZSB0aGUgTUlNRSBzcGVjaWZpY2F0aW9uLiAgSWYgdGhlIHByb3BlcnR5Cis8Y29kZT5tYWlsLm1pbWUubXVsdGlwYXJ0Lmlnbm9yZW1pc3NpbmdlbmRib3VuZGFyeTwvY29kZT4gaXMgc2V0Cit0byA8Y29kZT5mYWxzZTwvY29kZT4sIHN1Y2ggbWVzc2FnZXMgYXJlIGNvbnNpZGVyZWQgYW4gZXJyb3IgYW5kIGEKKzxjb2RlPk1lc2FnaW5nRXhjZXB0aW9uPC9jb2RlPiB3aWxsIGJlIHRocm93biB3aGVuIHBhcnNpbmcgc3VjaCBhCittZXNzYWdlLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLm1pbWUubXVsdGlwYXJ0Lmlnbm9yZW1pc3Npbmdib3VuZGFyeXBhcmFtZXRlciI+bWFpbC5taW1lLm11bHRpcGFydC4gaWdub3JlbWlzc2luZ2JvdW5kYXJ5cGFyYW1ldGVyPC9BPjwvVEQ+Cis8VEQ+Ym9vbGVhbjwvVEQ+Cis8VEQ+CitJZiB0aGUgQ29udGVudC1UeXBlIGhlYWRlciBmb3IgYSBtdWx0aXBhcnQgY29udGVudCBkb2VzIG5vdCBoYXZlCithIDxjb2RlPmJvdW5kYXJ5PC9jb2RlPiBwYXJhbWV0ZXIsIHRoZSBtdWx0aXBhcnQgcGFyc2luZyBjb2RlCit3aWxsIGxvb2sgZm9yIHRoZSBmaXJzdCBsaW5lIGluIHRoZSBjb250ZW50IHRoYXQgbG9va3MgbGlrZSBhCitib3VuZGFyeSBsaW5lIGFuZCBleHRyYWN0IHRoZSBib3VuZGFyeSBwYXJhbWV0ZXIgZnJvbSB0aGUgbGluZS4KK0lmIHRoaXMgcHJvcGVydHkgaXMgc2V0IHRvIDxjb2RlPiJmYWxzZSI8L2NvZGU+LCBhCis8Y29kZT5NZXNzYWdpbmdFeGNlcHRpb248L2NvZGU+IHdpbGwgYmUgdGhyb3duIGlmIHRoZSBDb250ZW50LVR5cGUKK2hlYWRlciBkb2Vzbid0IHNwZWNpZnkgYSBib3VuZGFyeSBwYXJhbWV0ZXIuCitUaGUgZGVmYXVsdCBpcyB0cnVlLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLm1pbWUubXVsdGlwYXJ0Lmlnbm9yZWV4aXN0aW5nYm91bmRhcnlwYXJhbWV0ZXIiPm1haWwubWltZS5tdWx0aXBhcnQuIGlnbm9yZWV4aXN0aW5nYm91bmRhcnlwYXJhbWV0ZXI8L0E+PC9URD4KKzxURD5ib29sZWFuPC9URD4KKzxURD4KK05vcm1hbGx5IHRoZSBib3VuZGFyeSBwYXJhbWV0ZXIgaW4gdGhlIENvbnRlbnQtVHlwZSBoZWFkZXIgb2YgYSBtdWx0aXBhcnQKK2JvZHkgcGFydCBpcyB1c2VkIHRvIHNwZWNpZnkgdGhlIHNlcGFyYXRvciBiZXR3ZWVuIHBhcnRzIG9mIHRoZSBtdWx0aXBhcnQKK2JvZHkuICBUaGlzIFN5c3RlbSBwcm9wZXJ0eSBtYXkgYmUgc2V0IHRvIDxjb2RlPiJ0cnVlIjwvY29kZT4gdG8gY2F1c2UKK3RoZSBwYXJzZXIgdG8gbG9vayBmb3IgYSBsaW5lIGluIHRoZSBtdWx0aXBhcnQgYm9keSB0aGF0IGxvb2tzIGxpa2UgYQorYm91bmRhcnkgbGluZSBhbmQgdXNlIHRoYXQgdmFsdWUgYXMgdGhlIHNlcGFyYXRvciBiZXR3ZWVuIHN1YnNlcXVlbnQgcGFydHMuCitUaGlzIG1heSBiZSB1c2VmdWwgaW4gY2FzZXMgd2hlcmUgYSBicm9rZW4gYW50aS12aXJ1cyBwcm9kdWN0IGhhcyByZXdyaXR0ZW4KK3RoZSBtZXNzYWdlIGluY29ycmVjdGx5IHN1Y2ggdGhhdCB0aGUgYm91bmRhcnkgcGFyYW1ldGVyIGFuZCB0aGUgYWN0dWFsCitib3VuZGFyeSB2YWx1ZSBubyBsb25nZXIgbWF0Y2guCitUaGUgZGVmYXVsdCB2YWx1ZSBvZiB0aGlzIHByb3BlcnR5IGlzIGZhbHNlLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLm1pbWUubXVsdGlwYXJ0LmFsbG93ZW1wdHkiPm1haWwubWltZS5tdWx0aXBhcnQuIGFsbG93ZW1wdHk8L0E+PC9URD4KKzxURD5ib29sZWFuPC9URD4KKzxURD4KK05vcm1hbGx5LCB3aGVuIHdyaXRpbmcgb3V0IGEgTWltZU11bHRpcGFydCB0aGF0IGNvbnRhaW5zIG5vIGJvZHkKK3BhcnRzLCBvciB3aGVuIHRyeWluZyB0byBwYXJzZSBhIG11bHRpcGFydCBtZXNzYWdlIHdpdGggbm8gYm9keSBwYXJ0cywKK2EgPGNvZGU+TWVzc2FnaW5nRXhjZXB0aW9uPC9jb2RlPiBpcyB0aHJvd24uICBUaGUgTUlNRSBzcGVjIGRvZXMgbm90IGFsbG93CittdWx0aXBhcnQgY29udGVudCB3aXRoIG5vIGJvZHkgcGFydHMuICBUaGlzCitTeXN0ZW0gcHJvcGVydHkgbWF5IGJlIHNldCB0byA8Y29kZT4idHJ1ZSI8L2NvZGU+IHRvIG92ZXJyaWRlIHRoaXMgYmVoYXZpb3IuCitXaGVuIHdyaXRpbmcgb3V0IHN1Y2ggYSBNaW1lTXVsdGlwYXJ0LCBhIHNpbmdsZSBlbXB0eSBwYXJ0IHdpbGwgYmUKK2luY2x1ZGVkLiAgV2hlbiByZWFkaW5nIHN1Y2ggYSBtdWx0aXBhcnQsIGEgTWltZU11bHRpcGFydCB3aWxsIGJlIGNyZWF0ZWQKK3dpdGggbm8gYm9keSBwYXJ0cy4KK1RoZSBkZWZhdWx0IHZhbHVlIG9mIHRoaXMgcHJvcGVydHkgaXMgZmFsc2UuCis8L1REPgorPC9UUj4KKworPC9UQUJMRT4KKworCis8UD4KK1RoZSBmb2xsb3dpbmcgcHJvcGVydGllcyBhcmUgc3VwcG9ydGVkIGJ5IHRoZSByZWZlcmVuY2UgaW1wbGVtZW50YXRpb24gKFJJKSBvZgorSmF2YU1haWwsIGJ1dCBhcmUgbm90IGN1cnJlbnRseSBhIHJlcXVpcmVkIHBhcnQgb2YgdGhlIHNwZWNpZmljYXRpb24uCitUaGVzZSBtdXN0IGJlIHNldCBhcyA8Q09ERT5TZXNzaW9uPC9DT0RFPiBwcm9wZXJ0aWVzLgorVGhlIG5hbWVzLCB0eXBlcywgZGVmYXVsdHMsIGFuZCBzZW1hbnRpY3Mgb2YgdGhlc2UgcHJvcGVydGllcyBtYXkKK2NoYW5nZSBpbiBmdXR1cmUgcmVsZWFzZXMuCis8L1A+Cis8VEFCTEUgQk9SREVSIFNVTU1BUlk9IkphdmFNYWlsIFJJIHByb3BlcnRpZXMiPgorPFRSPgorPFRIPk5hbWU8L1RIPgorPFRIPlR5cGU8L1RIPgorPFRIPkRlc2NyaXB0aW9uPC9USD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLmFsdGVybmF0ZXMiPm1haWwuYWx0ZXJuYXRlczwvQT48L1REPgorPFREPlN0cmluZzwvVEQ+Cis8VEQ+CitBIHN0cmluZyBjb250YWluaW5nIG90aGVyIGVtYWlsIGFkZHJlc3NlcyB0aGF0IHRoZSBjdXJyZW50IHVzZXIgaXMga25vd24gYnkuCitUaGUgPGNvZGU+TWltZU1lc3NhZ2U8L2NvZGU+IDxjb2RlPnJlcGx5PC9jb2RlPiBtZXRob2Qgd2lsbCBlbGltaW5hdGUgYW55CitvZiB0aGVzZSBhZGRyZXNzZXMgZnJvbSB0aGUgcmVjaXBpZW50IGxpc3QgaW4gdGhlIG1lc3NhZ2UgaXQgY29uc3RydWN0cywKK3RvIGF2b2lkIHNlbmRpbmcgdGhlIHJlcGx5IGJhY2sgdG8gdGhlIHNlbmRlci4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5yZXBseWFsbGNjIj5tYWlsLnJlcGx5YWxsY2M8L0E+PC9URD4KKzxURD5ib29sZWFuPC9URD4KKzxURD4KK0lmIHNldCB0byA8Y29kZT4idHJ1ZSI8L2NvZGU+LCB0aGUgPGNvZGU+TWltZU1lc3NhZ2U8L2NvZGU+Cis8Y29kZT5yZXBseTwvY29kZT4gbWV0aG9kIHdpbGwgcHV0IGFsbCByZWNpcGllbnRzIGV4Y2VwdCB0aGUgb3JpZ2luYWwKK3NlbmRlciBpbiB0aGUgPGNvZGU+Q2M8L2NvZGU+IGxpc3Qgb2YgdGhlIG5ld2x5IGNvbnN0cnVjdGVkIG1lc3NhZ2UuCitOb3JtYWxseSwgcmVjaXBpZW50cyBpbiB0aGUgPGNvZGU+VG88L2NvZGU+IGhlYWRlciBvZiB0aGUgb3JpZ2luYWwKK21lc3NhZ2Ugd2lsbCBhbHNvIGFwcGVhciBpbiB0aGUgPGNvZGU+VG88L2NvZGU+IGxpc3Qgb2YgdGhlIG5ld2x5Citjb25zdHJ1Y3RlZCBtZXNzYWdlLgorPC9URD4KKzwvVFI+Cis8L1RBQkxFPgorCis8UD4KK1RoZSBmb2xsb3dpbmcgcHJvcGVydGllcyBhcmUgc3VwcG9ydGVkIGJ5IHRoZSByZWZlcmVuY2UgaW1wbGVtZW50YXRpb24gKFJJKSBvZgorSmF2YU1haWwsIGJ1dCBhcmUgbm90IGN1cnJlbnRseSBhIHJlcXVpcmVkIHBhcnQgb2YgdGhlIHNwZWNpZmljYXRpb24uCitUaGVzZSBtdXN0IGJlIHNldCBhcyA8Q09ERT5TeXN0ZW08L0NPREU+IHByb3BlcnRpZXMuCitUaGUgbmFtZXMsIHR5cGVzLCBkZWZhdWx0cywgYW5kIHNlbWFudGljcyBvZiB0aGVzZSBwcm9wZXJ0aWVzIG1heQorY2hhbmdlIGluIGZ1dHVyZSByZWxlYXNlcy4KKzwvUD4KKzxUQUJMRSBCT1JERVIgU1VNTUFSWT0iSmF2YU1haWwgUkkgU3lzdGVtIHByb3BlcnRpZXMiPgorPFRSPgorPFRIPk5hbWU8L1RIPgorPFRIPlR5cGU8L1RIPgorPFRIPkRlc2NyaXB0aW9uPC9USD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLm1pbWUuYmFzZTY0Lmlnbm9yZWVycm9ycyI+bWFpbC5taW1lLmJhc2U2NC5pZ25vcmVlcnJvcnM8L0E+PC9URD4KKzxURD5ib29sZWFuPC9URD4KKzxURD4KK0lmIHNldCB0byA8Y29kZT4idHJ1ZSI8L2NvZGU+LCB0aGUgQkFTRTY0IGRlY29kZXIgd2lsbCBpZ25vcmUgZXJyb3JzCitpbiB0aGUgZW5jb2RlZCBkYXRhLCByZXR1cm5pbmcgRU9GLiAgVGhpcyBtYXkgYmUgdXNlZnVsIHdoZW4gZGVhbGluZword2l0aCBpbXByb3Blcmx5IGVuY29kZWQgbWVzc2FnZXMgdGhhdCBjb250YWluIGV4dHJhbmVvdXMgZGF0YSBhdCB0aGUKK2VuZCBvZiB0aGUgZW5jb2RlZCBzdHJlYW0uICBOb3RlIGhvd2V2ZXIgdGhhdCBlcnJvcnMgYW55d2hlcmUgaW4gdGhlCitzdHJlYW0gd2lsbCBjYXVzZSB0aGUgZGVjb2RlciB0byBzdG9wIGRlY29kaW5nIHNvIHRoaXMgc2hvdWxkIGJlIHVzZWQKK3dpdGggZXh0cmVtZSBjYXV0aW9uLiAgVGhlIGRlZmF1bHQgaXMgZmFsc2UuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwubWltZS5mb2xkdGV4dCI+bWFpbC5taW1lLmZvbGR0ZXh0PC9BPjwvVEQ+Cis8VEQ+Ym9vbGVhbjwvVEQ+Cis8VEQ+CitJZiBzZXQgdG8gPGNvZGU+InRydWUiPC9jb2RlPiwgaGVhZGVyIGZpZWxkcyBjb250YWluaW5nIGp1c3QgdGV4dAorc3VjaCBhcyB0aGUgPGNvZGU+U3ViamVjdDwvY29kZT4gYW5kIDxjb2RlPkNvbnRlbnQtRGVzY3JpcHRpb248L2NvZGU+CitoZWFkZXIgZmllbGRzLCBhbmQgbG9uZyBwYXJhbWV0ZXIgdmFsdWVzIGluIHN0cnVjdHVyZWQgaGVhZGVycyBzdWNoCithcyA8Y29kZT5Db250ZW50LVR5cGU8L2NvZGU+IHdpbGwgYmUgZm9sZGVkIChicm9rZW4gaW50byA3NiBjaGFyYWN0ZXIgbGluZXMpCit3aGVuIHNldCBhbmQgdW5mb2xkZWQgd2hlbiByZWFkLiAgVGhlIGRlZmF1bHQgaXMgdHJ1ZS4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5taW1lLnNldGNvbnRlbnR0eXBlZmlsZW5hbWUiPm1haWwubWltZS5zZXRjb250ZW50dHlwZWZpbGVuYW1lPC9BPjwvVEQ+Cis8VEQ+Ym9vbGVhbjwvVEQ+Cis8VEQ+CitJZiBzZXQgdG8gPGNvZGU+InRydWUiPC9jb2RlPiwgdGhlIDxjb2RlPnNldEZpbGVOYW1lPC9jb2RlPiBtZXRob2QKK3dpbGwgYWxzbyBzZXQgdGhlIDxjb2RlPm5hbWU8L2NvZGU+IHBhcmFtZXRlciBvbiB0aGUgPGNvZGU+Q29udGVudC1UeXBlPC9jb2RlPgoraGVhZGVyIHRvIHRoZSBzcGVjaWZpZWQgZmlsZW5hbWUuICBUaGlzIHN1cHBvcnRzIGludGVyb3BlcmFiaWxpdHkgd2l0aAorc29tZSBvbGQgbWFpbCBjbGllbnRzLiAgVGhlIGRlZmF1bHQgaXMgdHJ1ZS4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5taW1lLnNldGRlZmF1bHR0ZXh0Y2hhcnNldCI+bWFpbC5taW1lLnNldGRlZmF1bHR0ZXh0Y2hhcnNldDwvQT48L1REPgorPFREPmJvb2xlYW48L1REPgorPFREPgorV2hlbiB1cGRhdGluZyB0aGUgaGVhZGVycyBvZiBhIG1lc3NhZ2UsIGEgYm9keQorcGFydCB3aXRoIGEgPGNvZGU+dGV4dDwvY29kZT4gY29udGVudCB0eXBlIGJ1dCBubyA8Y29kZT5jaGFyc2V0PC9jb2RlPgorcGFyYW1ldGVyIHdpbGwgaGF2ZSBhIDxjb2RlPmNoYXJzZXQ8L2NvZGU+IHBhcmFtZXRlciBhZGRlZCB0byBpdAoraWYgdGhpcyBwcm9wZXJ0eSBpcyBzZXQgdG8gPGNvZGU+InRydWUiPC9jb2RlPi4KK1RoZSBkZWZhdWx0IGlzIHRydWUuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwubWltZS5wYXJhbWV0ZXJzLnN0cmljdCI+bWFpbC5taW1lLnBhcmFtZXRlcnMuc3RyaWN0PC9BPjwvVEQ+Cis8VEQ+Ym9vbGVhbjwvVEQ+Cis8VEQ+CitJZiBzZXQgdG8gZmFsc2UsIHdoZW4gcmVhZGluZyBhIG1lc3NhZ2UsIHBhcmFtZXRlciB2YWx1ZXMgaW4gaGVhZGVyIGZpZWxkcworc3VjaCBhcyA8Y29kZT5Db250ZW50LVR5cGU8L2NvZGU+IGFuZCA8Y29kZT5Db250ZW50LURpc3Bvc2l0aW9uPC9jb2RlPgorYXJlIGFsbG93ZWQgdG8gY29udGFpbiB3aGl0ZXNwYWNlIGFuZCBvdGhlciBzcGVjaWFsIGNoYXJhY3RlcnMgd2l0aG91dAorYmVpbmcgcXVvdGVkOyB0aGUgcGFyYW1ldGVyIHZhbHVlIGVuZHMgYXQgdGhlIG5leHQgc2VtaWNvbG9uLgorSWYgc2V0IHRvIHRydWUgKHRoZSBkZWZhdWx0KSwgcGFyYW1ldGVyIHZhbHVlcyBhcmUgcmVxdWlyZWQgdG8gY29uZm9ybQordG8gdGhlIE1JTUUgc3BlY2lmaWNhdGlvbiBhbmQgbXVzdCBiZSBxdW90ZWQgaWYgdGhleSBjb250YWluIHdoaXRlc3BhY2UKK29yIHNwZWNpYWwgY2hhcmFjdGVycy4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5taW1lLmFwcGxlZmlsZW5hbWVzIj5tYWlsLm1pbWUuYXBwbGVmaWxlbmFtZXM8L0E+PC9URD4KKzxURD5ib29sZWFuPC9URD4KKzxURD4KK0FwcGxlIE1haWwgaW5jb3JyZWN0bHkgZW5jb2RlcyBmaWxlbmFtZXMgdGhhdCBjb250YWluIHNwYWNlcywKK2ZvcmdldHRpbmcgdG8gcXVvdGUgdGhlIHBhcmFtZXRlciB2YWx1ZS4gIElmIHRoaXMgcHJvcGVydHkgaXMKK3NldCB0byA8Y29kZT4idHJ1ZSI8L2NvZGU+LCBKYXZhTWFpbCB3aWxsIHRyeSB0byBkZXRlY3QgdGhpcworc2l0dWF0aW9uIHdoZW4gcGFyc2luZyBwYXJhbWV0ZXJzIGFuZCB3b3JrIGFyb3VuZCBpdC4KK1RoZSBkZWZhdWx0IGlzIGZhbHNlLgorTm90ZSB0aGF0IHRoaXMgcHJvcGVydHkgaGFuZGxlcyBhIHN1YnNldCBvZiB0aGUgY2FzZXMgaGFuZGxlZAorYnkgc2V0dGluZyB0aGUgbWFpbC5taW1lLnBhcmFtZXRlcnMuc3RyaWN0IHByb3BlcnR5IHRvIGZhbHNlLgorVGhpcyBwcm9wZXJ0eSB3aWxsIGxpa2VseSBiZSByZW1vdmVkIGluIGEgZnV0dXJlIHJlbGVhc2UuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwubWltZS53aW5kb3dzZmlsZW5hbWVzIj5tYWlsLm1pbWUud2luZG93c2ZpbGVuYW1lczwvQT48L1REPgorPFREPmJvb2xlYW48L1REPgorPFREPgorSW50ZXJuZXQgRXhwbG9yZXIgNiBpbmNvcnJlY3RseSBpbmNsdWRlcyBhIGNvbXBsZXRlIHBhdGhuYW1lCitpbiB0aGUgZmlsZW5hbWUgcGFyYW1ldGVyIG9mIHRoZSBDb250ZW50LURpc3Bvc2l0aW9uIGhlYWRlcgorZm9yIHVwbG9hZGVkIGZpbGVzLCBhbmQgZmFpbHMgdG8gcHJvcGVybHkgZXNjYXBlIHRoZSBiYWNrc2xhc2hlcworaW4gdGhlIHBhdGhuYW1lLiAgSWYgdGhpcyBwcm9wZXJ0eSBpcworc2V0IHRvIDxjb2RlPiJ0cnVlIjwvY29kZT4sIEphdmFNYWlsIHdpbGwgcHJlc2VydmUgYWxsIGJhY2tzbGFzaGVzCitpbiB0aGUgImZpbGVuYW1lIiBhbmQgIm5hbWUiIHBhcmFtZXRlcnMgb2YgYW55IE1JTUUgaGVhZGVyLgorVGhlIGRlZmF1bHQgaXMgZmFsc2UuCitOb3RlIHRoYXQgdGhpcyBpcyBhIHZpb2xhdGlvbiBvZiB0aGUgTUlNRSBzcGVjaWZpY2F0aW9uIGJ1dCBtYXkKK2JlIHVzZWZ1bCB3aGVuIHVzaW5nIEphdmFNYWlsIHRvIHBhcnNlIEhUVFAgbWVzc2FnZXMgZm9yIHVwbG9hZGVkCitmaWxlcyBzZW50IGJ5IElFNi4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5taW1lLmlnbm9yZXVua25vd25lbmNvZGluZyI+bWFpbC5taW1lLiBpZ25vcmV1bmtub3duZW5jb2Rpbmc8L0E+PC9URD4KKzxURD5ib29sZWFuPC9URD4KKzxURD4KK0lmIHNldCB0byA8Y29kZT4idHJ1ZSI8L2NvZGU+LCBhbiB1bmtub3duIHZhbHVlIGluIHRoZQorPGNvZGU+Q29udGVudC1UcmFuc2Zlci1FbmNvZGluZzwvY29kZT4gaGVhZGVyIHdpbGwgYmUgaWdub3JlZAord2hlbiByZWFkaW5nIGEgbWVzc2FnZSBhbmQgYW4gZW5jb2Rpbmcgb2YgIjhiaXQiIHdpbGwgYmUgYXNzdW1lZC4KK0lmIHNldCB0byA8Y29kZT4iZmFsc2UiPC9jb2RlPiwgYW4gZXhjZXB0aW9uIGlzIHRocm93biBmb3IgYW4KK3Vua25vd24gZW5jb2RpbmcgdmFsdWUuICBUaGUgZGVmYXVsdCBpcyBmYWxzZS4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5taW1lLnV1ZGVjb2RlLmlnbm9yZWVycm9ycyI+bWFpbC5taW1lLnV1ZGVjb2RlLiBpZ25vcmVlcnJvcnM8L0E+PC9URD4KKzxURD5ib29sZWFuPC9URD4KKzxURD4KK0lmIHNldCB0byA8Y29kZT4idHJ1ZSI8L2NvZGU+LCBlcnJvcnMgaW4gdGhlIGVuY29kZWQgZm9ybWF0IG9mIGEKK3V1ZW5jb2RlZCBkb2N1bWVudCB3aWxsIGJlIGlnbm9yZWQgd2hlbiByZWFkaW5nIGEgbWVzc2FnZSBwYXJ0LgorSWYgc2V0IHRvIDxjb2RlPiJmYWxzZSI8L2NvZGU+LCBhbiBleGNlcHRpb24gaXMgdGhyb3duIGZvciBhbgoraW5jb3JyZWN0bHkgZW5jb2RlZCBtZXNzYWdlIHBhcnQuICBUaGUgZGVmYXVsdCBpcyBmYWxzZS4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5taW1lLnV1ZGVjb2RlLmlnbm9yZW1pc3NpbmdiZWdpbmVuZCI+bWFpbC5taW1lLnV1ZGVjb2RlLiBpZ25vcmVtaXNzaW5nYmVnaW5lbmQ8L0E+PC9URD4KKzxURD5ib29sZWFuPC9URD4KKzxURD4KK0lmIHNldCB0byA8Y29kZT4idHJ1ZSI8L2NvZGU+LCBhIG1pc3NpbmcgImJlaW5nIiBvciAiZW5kIiBsaW5lIGluIGEKK3V1ZW5jb2RlZCBkb2N1bWVudCB3aWxsIGJlIGlnbm9yZWQgd2hlbiByZWFkaW5nIGEgbWVzc2FnZSBwYXJ0LgorSWYgc2V0IHRvIDxjb2RlPiJmYWxzZSI8L2NvZGU+LCBhbiBleGNlcHRpb24gaXMgdGhyb3duIGZvciBhCit1dWVuY29kZWQgbWVzc2FnZSBwYXJ0IHdpdGhvdXQgdGhlIHJlcXVpcmVkICJiZWdpbiIgYW5kICJlbmQiIGxpbmVzLgorVGhlIGRlZmF1bHQgaXMgZmFsc2UuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwubWltZS5pZ25vcmV3aGl0ZXNwYWNlbGluZXMiPm1haWwubWltZS4gaWdub3Jld2hpdGVzcGFjZWxpbmVzPC9BPjwvVEQ+Cis8VEQ+Ym9vbGVhbjwvVEQ+Cis8VEQ+CitOb3JtYWxseSB0aGUgaGVhZGVyIG9mIGEgTUlNRSBwYXJ0IGlzIHNlcGFyYXRlZCBmcm9tIHRoZSBib2R5IGJ5IGFuIGVtcHR5CitsaW5lLiAgVGhpcyBTeXN0ZW0gcHJvcGVydHkgbWF5IGJlIHNldCB0byA8Y29kZT4idHJ1ZSI8L2NvZGU+IHRvIGNhdXNlCit0aGUgcGFyc2VyIHRvIGNvbnNpZGVyIGEgbGluZSBjb250YWluaW5nIG9ubHkgd2hpdGVzcGFjZSB0byBiZSBhbiBlbXB0eQorbGluZS4gIFRoZSBkZWZhdWx0IHZhbHVlIG9mIHRoaXMgcHJvcGVydHkgaXMgZmFsc2UuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwubWltZS5pZ25vcmVtdWx0aXBhcnRlbmNvZGluZyI+bWFpbC5taW1lLiBpZ25vcmVtdWx0aXBhcnRlbmNvZGluZzwvQT48L1REPgorPFREPmJvb2xlYW48L1REPgorPFREPgorVGhlIE1JTUUgc3BlYyBkb2VzIG5vdCBhbGxvdyBib2R5IHBhcnRzIG9mIHR5cGUgbXVsdGlwYXJ0LyogdG8gYmUgZW5jb2RlZC4KK1RoZSBDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nIGhlYWRlciBpcyBpZ25vcmVkIGluIHRoaXMgY2FzZS4KK1NldHRpbmcgdGhpcyBTeXN0ZW0gcHJvcGVydHkgdG8gPGNvZGU+ImZhbHNlIjwvY29kZT4gd2lsbAorY2F1c2UgdGhlIENvbnRlbnQtVHJhbnNmZXItRW5jb2RpbmcgaGVhZGVyIHRvIGJlIGhvbm9yZWQgZm9yIG11bHRpcGFydAorY29udGVudC4KK1RoZSBkZWZhdWx0IHZhbHVlIG9mIHRoaXMgcHJvcGVydHkgaXMgdHJ1ZS4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5taW1lLmFsbG93ZW5jb2RlZG1lc3NhZ2VzIj5tYWlsLm1pbWUuYWxsb3dlbmNvZGVkbWVzc2FnZXM8L0E+PC9URD4KKzxURD5ib29sZWFuPC9URD4KKzxURD4KK1RoZSBNSU1FIHNwZWMgZG9lcyBub3QgYWxsb3cgYm9keSBwYXJ0cyBvZiB0eXBlIG1lc3NhZ2UvKiB0byBiZSBlbmNvZGVkLgorVGhlIENvbnRlbnQtVHJhbnNmZXItRW5jb2RpbmcgaGVhZGVyIGlzIGlnbm9yZWQgaW4gdGhpcyBjYXNlLgorU29tZSB2ZXJzaW9ucyBvZiBNaWNyb3NvZnQgT3V0bG9vayB3aWxsIGluY29ycmVjdGx5IGVuY29kZSBtZXNzYWdlCithdHRhY2htZW50cy4gIFNldHRpbmcgdGhpcyBTeXN0ZW0gcHJvcGVydHkgdG8gPGNvZGU+InRydWUiPC9jb2RlPiB3aWxsCitjYXVzZSB0aGUgQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZyBoZWFkZXIgdG8gYmUgaG9ub3JlZCBmb3IgbWVzc2FnZQorYXR0YWNobWVudHMuCitUaGUgZGVmYXVsdCB2YWx1ZSBvZiB0aGlzIHByb3BlcnR5IGlzIGZhbHNlLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLm1pbWUuY29udGVudHR5cGVoYW5kbGVyIj5tYWlsLm1pbWUuY29udGVudHR5cGVoYW5kbGVyPC9BPjwvVEQ+Cis8VEQ+U3RyaW5nPC9URD4KKzxURD4KK0luIHNvbWUgY2FzZXMgSmF2YU1haWwgaXMgdW5hYmxlIHRvIHByb2Nlc3MgbWVzc2FnZXMgd2l0aCBhbiBpbnZhbGlkCitDb250ZW50LVR5cGUgaGVhZGVyLiAgVGhlIGhlYWRlciBtYXkgaGF2ZSBpbmNvcnJlY3Qgc3ludGF4IG9yIG90aGVyCitwcm9ibGVtcy4gIFRoaXMgcHJvcGVydHkgc3BlY2lmaWVzIHRoZSBuYW1lIG9mIGEgY2xhc3MgdGhhdCB3aWxsIGJlCit1c2VkIHRvIGNsZWFuIHVwIHRoZSBDb250ZW50LVR5cGUgaGVhZGVyIHZhbHVlIGJlZm9yZSBKYXZhTWFpbCB1c2VzIGl0LgorVGhlIGNsYXNzIG11c3QgaGF2ZSBhIG1ldGhvZCB3aXRoIHRoaXMgc2lnbmF0dXJlOgorPENPREU+cHVibGljIHN0YXRpYyBTdHJpbmcgY2xlYW5Db250ZW50VHlwZShNaW1lUGFydCBtcCwgU3RyaW5nIGNvbnRlbnRUeXBlKTwvQ09ERT4KK1doZW5ldmVyIEphdmFNYWlsIGFjY2Vzc2VzIHRoZSBDb250ZW50LVR5cGUgaGVhZGVyIG9mIGEgbWVzc2FnZSwgaXQKK3dpbGwgcGFzcyB0aGUgdmFsdWUgdG8gdGhpcyBtZXRob2QgYW5kIHVzZSB0aGUgcmV0dXJuZWQgdmFsdWUgaW5zdGVhZC4KK1RoZSB2YWx1ZSBtYXkgYmUgbnVsbCBpZiB0aGUgQ29udGVudC1UeXBlIGhlYWRlciBpc24ndCBwcmVzZW50LgorUmV0dXJuaW5nIG51bGwgd2lsbCBjYXVzZSB0aGUgZGVmYXVsdCBDb250ZW50LVR5cGUgdG8gYmUgdXNlZC4KK1RoZSBNaW1lUGFydCBtYXkgYmUgdXNlZCB0byBhY2Nlc3Mgb3RoZXIgaGVhZGVycyBvZiB0aGUgbWVzc2FnZSBwYXJ0Cit0byBkZXRlcm1pbmUgaG93IHRvIGNvcnJlY3QgdGhlIENvbnRlbnQtVHlwZS4KK05vdGUgdGhhdCB0aGUgQ29udGVudC1UeXBlIGhhbmRsZXIgZG9lc24ndCBhZmZlY3QgdGhlCis8Q09ERT5nZXRIZWFkZXI8L0NPREU+IG1ldGhvZCwgd2hpY2ggc3RpbGwgcmV0dXJucyB0aGUgcmF3IGhlYWRlciB2YWx1ZS4KK05vdGUgYWxzbyB0aGF0IHRoZSBoYW5kbGVyIGRvZXNuJ3QgYWZmZWN0IHRoZSBJTUFQIHByb3ZpZGVyOyB0aGUgSU1BUAorc2VydmVyIGlzIHJlc3BvbnNpYmxlIGZvciByZXR1cm5pbmcgcHJlLXBhcnNlZCwgc3ludGFjdGljYWxseSBjb3JyZWN0CitDb250ZW50LVR5cGUgaW5mb3JtYXRpb24uCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwubWltZS5hZGRyZXNzLnVzZWNhbm9uaWNhbGhvc3RuYW1lIj5tYWlsLm1pbWUuYWRkcmVzcy51c2VjYW5vbmljYWxob3N0bmFtZTwvQT48L1REPgorPFREPmJvb2xlYW48L1REPgorPFREPgorVXNlIHRoZQore0BsaW5rIGphdmEubmV0LkluZXRBZGRyZXNzI2dldENhbm9uaWNhbEhvc3ROYW1lIEluZXRBZGRyZXNzLmdldENhbm9uaWNhbEhvc3ROYW1lfQorbWV0aG9kIHRvIGRldGVybWluZSB0aGUgaG9zdCBuYW1lIGluIHRoZQore0BsaW5rIGphdmF4Lm1haWwuaW50ZXJuZXQuSW50ZXJuZXRBZGRyZXNzI2dldExvY2FsQWRkcmVzcyBJbnRlcm5ldEFkZHJlc3MuZ2V0TG9jYWxBZGRyZXNzfQorbWV0aG9kLgorV2l0aCBzb21lIG5ldHdvcmsgY29uZmlndXJhdGlvbnMsIEluZXRBZGRyZXNzLmdldENhbm9uaWNhbEhvc3ROYW1lIG1heSBiZQorc2xvdyBvciBtYXkgcmV0dXJuIGFuIGFkZHJlc3MgaW5zdGVhZCBvZiBhIGhvc3QgbmFtZS4KK0luIHRoYXQgY2FzZSwgc2V0dGluZyB0aGlzIFN5c3RlbSBwcm9wZXJ0eSB0byBmYWxzZSB3aWxsIGNhdXNlIHRoZQore0BsaW5rIGphdmEubmV0LkluZXRBZGRyZXNzI2dldEhvc3ROYW1lIEluZXRBZGRyZXNzLmdldEhvc3ROYW1lfQorbWV0aG9kIHRvIGJlIHVzZWQgaW5zdGVhZC4KK1RoZSBkZWZhdWx0IGlzIHRydWUuCis8L1REPgorPC9UUj4KKworPC9UQUJMRT4KKzxQPgorVGhlIGN1cnJlbnQKK2ltcGxlbWVudGF0aW9uIG9mIGNsYXNzZXMgaW4gdGhpcyBwYWNrYWdlIGxvZyBkZWJ1Z2dpbmcgaW5mb3JtYXRpb24gdXNpbmcKK3tAbGluayBqYXZhLnV0aWwubG9nZ2luZy5Mb2dnZXJ9IGFzIGRlc2NyaWJlZCBpbiB0aGUgZm9sbG93aW5nIHRhYmxlOgorPC9QPgorPFRBQkxFIEJPUkRFUiBTVU1NQVJZPSJKYXZhTWFpbCBMb2dnZXJzIj4KKzxUUj4KKzxUSD5Mb2dnZXIgTmFtZTwvVEg+Cis8VEg+TG9nZ2luZyBMZXZlbDwvVEg+Cis8VEg+UHVycG9zZTwvVEg+Cis8L1RSPgorCis8VFI+Cis8VEQ+amF2YXgubWFpbC5pbnRlcm5ldDwvVEQ+Cis8VEQ+RklORTwvVEQ+Cis8VEQ+R2VuZXJhbCBkZWJ1Z2dpbmcgb3V0cHV0PC9URD4KKzwvVFI+Cis8L1RBQkxFPgorCis8L0JPRFk+Cis8L0hUTUw+CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9wYWNrYWdlLmh0bWwgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9wYWNrYWdlLmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDExZDAyMwotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDM0NyBAQAorPCFET0NUWVBFIGh0bWwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMDEgVHJhbnNpdGlvbmFsLy9FTiI+Cis8SFRNTD4KKzxIRUFEPgorPG1ldGEgaHR0cC1lcXVpdj0iQ29udGVudC1UeXBlIiBjb250ZW50PSJ0ZXh0L2h0bWw7IGNoYXJzZXQ9dXRmLTgiPgorPCEtLQorCisgICAgQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisKKyAgICBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAgICB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKworICAgIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAgICBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgICAgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgICAgdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisKKyAgICBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKworLS0+CisKKzxUSVRMRT5qYXZheC5tYWlsIHBhY2thZ2U8L1RJVExFPgorPC9IRUFEPgorPEJPRFkgQkdDT0xPUj0id2hpdGUiPgorCis8UD4KK1RoZSBKYXZhTWFpbCZ0cmFkZTsgQVBJCitwcm92aWRlcyBjbGFzc2VzIHRoYXQgbW9kZWwgYSBtYWlsIHN5c3RlbS4KK1RoZSA8Y29kZT5qYXZheC5tYWlsPC9jb2RlPiBwYWNrYWdlIGRlZmluZXMgY2xhc3NlcyB0aGF0IGFyZSBjb21tb24gdG8KK2FsbCBtYWlsIHN5c3RlbXMuCitUaGUgPGNvZGU+amF2YXgubWFpbC5pbnRlcm5ldDwvY29kZT4gcGFja2FnZSBkZWZpbmVzIGNsYXNzZXMgdGhhdCBhcmUgc3BlY2lmaWMKK3RvIG1haWwgc3lzdGVtcyBiYXNlZCBvbiBpbnRlcm5ldCBzdGFuZGFyZHMgc3VjaCBhcyBNSU1FLCBTTVRQLCBQT1AzLCBhbmQgSU1BUC4KK1RoZSBKYXZhTWFpbCBBUEkgaW5jbHVkZXMgdGhlIDxjb2RlPmphdmF4Lm1haWw8L2NvZGU+IHBhY2thZ2UgYW5kIHN1YnBhY2thZ2VzLgorPC9QPgorPFA+CitGb3IgYW4gb3ZlcnZpZXcgb2YgdGhlIEphdmFNYWlsIEFQSSwgcmVhZCB0aGUKKzxBIEhSRUY9Imh0dHBzOi8vamF2YWVlLmdpdGh1Yi5pby9qYXZhbWFpbC9kb2NzL0phdmFNYWlsLTEuNi5wZGYiIFRBUkdFVD0iX3RvcCI+CitKYXZhTWFpbCBzcGVjaWZpY2F0aW9uPC9BPi4KKzwvUD4KKzxQPgorVGhlIGNvZGUgdG8gc2VuZCBhIHBsYWluIHRleHQgbWVzc2FnZSBjYW4gYmUgYXMgc2ltcGxlIGFzIHRoZSBmb2xsb3dpbmc6Cis8L1A+Cis8UFJFPgorICAgIFByb3BlcnRpZXMgcHJvcHMgPSBuZXcgUHJvcGVydGllcygpOworICAgIHByb3BzLnB1dCgibWFpbC5zbXRwLmhvc3QiLCAibXktbWFpbC1zZXJ2ZXIiKTsKKyAgICBTZXNzaW9uIHNlc3Npb24gPSBTZXNzaW9uLmdldEluc3RhbmNlKHByb3BzLCBudWxsKTsKKworICAgIHRyeSB7CisJTWltZU1lc3NhZ2UgbXNnID0gbmV3IE1pbWVNZXNzYWdlKHNlc3Npb24pOworCW1zZy5zZXRGcm9tKCJtZUBleGFtcGxlLmNvbSIpOworCW1zZy5zZXRSZWNpcGllbnRzKE1lc3NhZ2UuUmVjaXBpZW50VHlwZS5UTywKKwkJCSAgInlvdUBleGFtcGxlLmNvbSIpOworCW1zZy5zZXRTdWJqZWN0KCJKYXZhTWFpbCBoZWxsbyB3b3JsZCBleGFtcGxlIik7CisJbXNnLnNldFNlbnREYXRlKG5ldyBEYXRlKCkpOworCW1zZy5zZXRUZXh0KCJIZWxsbywgd29ybGQhXG4iKTsKKwlUcmFuc3BvcnQuc2VuZChtc2csICJtZUBleGFtcGxlLmNvbSIsICJteS1wYXNzd29yZCIpOworICAgIH0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBtZXgpIHsKKwlTeXN0ZW0ub3V0LnByaW50bG4oInNlbmQgZmFpbGVkLCBleGNlcHRpb246ICIgKyBtZXgpOworICAgIH0KKzwvUFJFPgorPFA+CitUaGUgSmF2YU1haWwgZG93bmxvYWQgYnVuZGxlIGNvbnRhaW5zIG1hbnkgbW9yZSBjb21wbGV0ZSBleGFtcGxlcworaW4gdGhlICJkZW1vIiBkaXJlY3RvcnkuCis8L1A+Cis8UD4KK0Rvbid0IGZvcmdldCB0byBzZWUgdGhlCis8QSBIUkVGPSJodHRwczovL2phdmFlZS5naXRodWIuaW8vamF2YW1haWwvRkFRLmh0bWwiIFRBUkdFVD0iX3RvcCI+CitKYXZhTWFpbCBBUEkgRkFRPC9BPgorZm9yIGFuc3dlcnMgdG8gdGhlIG1vc3QgY29tbW9uIHF1ZXN0aW9ucy4KK1RoZSA8QSBIUkVGPSJodHRwczovL2phdmFlZS5naXRodWIuaW8vamF2YW1haWwvIiBUQVJHRVQ9Il90b3AiPgorSmF2YU1haWwgd2ViIHNpdGU8L0E+Citjb250YWlucyBtYW55IGFkZGl0aW9uYWwgcmVzb3VyY2VzLgorPC9QPgorPEEgTkFNRT0icHJvcGVydGllcyI+PFNUUk9ORz5Qcm9wZXJ0aWVzPC9TVFJPTkc+PC9BPgorPFA+CitUaGUgSmF2YU1haWwgQVBJIHN1cHBvcnRzIHRoZSBmb2xsb3dpbmcgc3RhbmRhcmQgcHJvcGVydGllcywKK3doaWNoIG1heSBiZSBzZXQgaW4gdGhlIDxjb2RlPlNlc3Npb248L2NvZGU+IG9iamVjdCwgb3IgaW4gdGhlCis8Y29kZT5Qcm9wZXJ0aWVzPC9jb2RlPiBvYmplY3QgdXNlZCB0byBjcmVhdGUgdGhlIDxjb2RlPlNlc3Npb248L2NvZGU+IG9iamVjdC4KK1RoZSBwcm9wZXJ0aWVzIGFyZSBhbHdheXMgc2V0IGFzIHN0cmluZ3M7IHRoZSBUeXBlIGNvbHVtbiBkZXNjcmliZXMKK2hvdyB0aGUgc3RyaW5nIGlzIGludGVycHJldGVkLiAgRm9yIGV4YW1wbGUsIHVzZQorPC9QPgorPFBSRT4KKwlwcm9wcy5wdXQoIm1haWwuZGVidWciLCAidHJ1ZSIpOworPC9QUkU+Cis8UD4KK3RvIHNldCB0aGUgPGNvZGU+bWFpbC5kZWJ1ZzwvY29kZT4gcHJvcGVydHksIHdoaWNoIGlzIG9mIHR5cGUgYm9vbGVhbi4KKzwvUD4KKzxUQUJMRSBCT1JERVIgU1VNTUFSWT0iSmF2YU1haWwgcHJvcGVydGllcyI+Cis8VFI+Cis8VEg+TmFtZTwvVEg+Cis8VEg+VHlwZTwvVEg+Cis8VEg+RGVzY3JpcHRpb248L1RIPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuZGVidWciPm1haWwuZGVidWc8L0E+PC9URD4KKzxURD5ib29sZWFuPC9URD4KKzxURD4KK1RoZSBpbml0aWFsIGRlYnVnIG1vZGUuCitEZWZhdWx0IGlzIGZhbHNlLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLmZyb20iPm1haWwuZnJvbTwvQT48L1REPgorPFREPlN0cmluZzwvVEQ+Cis8VEQ+CitUaGUgcmV0dXJuIGVtYWlsIGFkZHJlc3Mgb2YgdGhlIGN1cnJlbnQgdXNlciwgdXNlZCBieSB0aGUKKzxjb2RlPkludGVybmV0QWRkcmVzczwvY29kZT4gbWV0aG9kIDxjb2RlPmdldExvY2FsQWRkcmVzczwvY29kZT4uCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwubWltZS5hZGRyZXNzLnN0cmljdCI+bWFpbC5taW1lLmFkZHJlc3Muc3RyaWN0PC9BPjwvVEQ+Cis8VEQ+Ym9vbGVhbjwvVEQ+Cis8VEQ+CitUaGUgTWltZU1lc3NhZ2UgY2xhc3MgdXNlcyB0aGUgPGNvZGU+SW50ZXJuZXRBZGRyZXNzPC9jb2RlPiBtZXRob2QKKzxjb2RlPnBhcnNlSGVhZGVyPC9jb2RlPiB0byBwYXJzZSBoZWFkZXJzIGluIG1lc3NhZ2VzLiAgVGhpcyBwcm9wZXJ0eQorY29udHJvbHMgdGhlIHN0cmljdCBmbGFnIHBhc3NlZCB0byB0aGUgPGNvZGU+cGFyc2VIZWFkZXI8L2NvZGU+CittZXRob2QuICBUaGUgZGVmYXVsdCBpcyB0cnVlLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLmhvc3QiPm1haWwuaG9zdDwvQT48L1REPgorPFREPlN0cmluZzwvVEQ+Cis8VEQ+CitUaGUgZGVmYXVsdCBob3N0IG5hbWUgb2YgdGhlIG1haWwgc2VydmVyIGZvciBib3RoIFN0b3JlcyBhbmQgVHJhbnNwb3J0cy4KK1VzZWQgaWYgdGhlIDxjb2RlPm1haWwuPGk+cHJvdG9jb2w8L2k+Lmhvc3Q8L2NvZGU+IHByb3BlcnR5IGlzbid0IHNldC4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5zdG9yZS5wcm90b2NvbCI+bWFpbC5zdG9yZS5wcm90b2NvbDwvQT48L1REPgorPFREPlN0cmluZzwvVEQ+Cis8VEQ+CitTcGVjaWZpZXMgdGhlIGRlZmF1bHQgbWVzc2FnZSBhY2Nlc3MgcHJvdG9jb2wuICBUaGUKKzxjb2RlPlNlc3Npb248L2NvZGU+IG1ldGhvZCA8Y29kZT5nZXRTdG9yZSgpPC9jb2RlPiByZXR1cm5zIGEgU3RvcmUKK29iamVjdCB0aGF0IGltcGxlbWVudHMgdGhpcyBwcm90b2NvbC4gIEJ5IGRlZmF1bHQgdGhlIGZpcnN0IFN0b3JlCitwcm92aWRlciBpbiB0aGUgY29uZmlndXJhdGlvbiBmaWxlcyBpcyByZXR1cm5lZC4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC50cmFuc3BvcnQucHJvdG9jb2wiPm1haWwudHJhbnNwb3J0LnByb3RvY29sPC9BPjwvVEQ+Cis8VEQ+U3RyaW5nPC9URD4KKzxURD4KK1NwZWNpZmllcyB0aGUgZGVmYXVsdCBtZXNzYWdlIHRyYW5zcG9ydCBwcm90b2NvbC4gIFRoZQorPGNvZGU+U2Vzc2lvbjwvY29kZT4gbWV0aG9kIDxjb2RlPmdldFRyYW5zcG9ydCgpPC9jb2RlPiByZXR1cm5zIGEgVHJhbnNwb3J0CitvYmplY3QgdGhhdCBpbXBsZW1lbnRzIHRoaXMgcHJvdG9jb2wuICBCeSBkZWZhdWx0IHRoZSBmaXJzdCBUcmFuc3BvcnQKK3Byb3ZpZGVyIGluIHRoZSBjb25maWd1cmF0aW9uIGZpbGVzIGlzIHJldHVybmVkLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnVzZXIiPm1haWwudXNlcjwvQT48L1REPgorPFREPlN0cmluZzwvVEQ+Cis8VEQ+CitUaGUgZGVmYXVsdCB1c2VyIG5hbWUgdG8gdXNlIHdoZW4gY29ubmVjdGluZyB0byB0aGUgbWFpbCBzZXJ2ZXIuCitVc2VkIGlmIHRoZSA8Y29kZT5tYWlsLjxpPnByb3RvY29sPC9pPi51c2VyPC9jb2RlPiBwcm9wZXJ0eSBpc24ndCBzZXQuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwucHJvdG9jb2wuY2xhc3MiPm1haWwuPGk+cHJvdG9jb2w8L2k+LmNsYXNzPC9BPjwvVEQ+Cis8VEQ+U3RyaW5nPC9URD4KKzxURD4KK1NwZWNpZmllcyB0aGUgZnVsbHkgcXVhbGlmaWVkIGNsYXNzIG5hbWUgb2YgdGhlIHByb3ZpZGVyIGZvciB0aGUKK3NwZWNpZmllZCBwcm90b2NvbC4gIFVzZWQgaW4gY2FzZXMgd2hlcmUgbW9yZSB0aGFuIG9uZSBwcm92aWRlcgorZm9yIGEgZ2l2ZW4gcHJvdG9jb2wgZXhpc3RzOyB0aGlzIHByb3BlcnR5IGNhbiBiZSB1c2VkIHRvIHNwZWNpZnkKK3doaWNoIHByb3ZpZGVyIHRvIHVzZSBieSBkZWZhdWx0LiAgVGhlIHByb3ZpZGVyIG11c3Qgc3RpbGwgYmUgbGlzdGVkCitpbiBhIGNvbmZpZ3VyYXRpb24gZmlsZS4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5wcm90b2NvbC5ob3N0Ij5tYWlsLjxpPnByb3RvY29sPC9pPi5ob3N0PC9BPjwvVEQ+Cis8VEQ+U3RyaW5nPC9URD4KKzxURD4KK1RoZSBob3N0IG5hbWUgb2YgdGhlIG1haWwgc2VydmVyIGZvciB0aGUgc3BlY2lmaWVkIHByb3RvY29sLgorT3ZlcnJpZGVzIHRoZSA8Y29kZT5tYWlsLmhvc3Q8L2NvZGU+IHByb3BlcnR5LgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnByb3RvY29sLnBvcnQiPm1haWwuPGk+cHJvdG9jb2w8L2k+LnBvcnQ8L0E+PC9URD4KKzxURD5pbnQ8L1REPgorPFREPgorVGhlIHBvcnQgbnVtYmVyIG9mIHRoZSBtYWlsIHNlcnZlciBmb3IgdGhlIHNwZWNpZmllZCBwcm90b2NvbC4KK0lmIG5vdCBzcGVjaWZpZWQgdGhlIHByb3RvY29sJ3MgZGVmYXVsdCBwb3J0IG51bWJlciBpcyB1c2VkLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnByb3RvY29sLnVzZXIiPm1haWwuPGk+cHJvdG9jb2w8L2k+LnVzZXI8L0E+PC9URD4KKzxURD5TdHJpbmc8L1REPgorPFREPgorVGhlIHVzZXIgbmFtZSB0byB1c2Ugd2hlbiBjb25uZWN0aW5nIHRvIG1haWwgc2VydmVycwordXNpbmcgdGhlIHNwZWNpZmllZCBwcm90b2NvbC4KK092ZXJyaWRlcyB0aGUgPGNvZGU+bWFpbC51c2VyPC9jb2RlPiBwcm9wZXJ0eS4KKzwvVEQ+Cis8L1RSPgorCis8L1RBQkxFPgorCis8UD4KK1RoZSBmb2xsb3dpbmcgcHJvcGVydGllcyBhcmUgc3VwcG9ydGVkIGJ5IHRoZSByZWZlcmVuY2UgaW1wbGVtZW50YXRpb24gKFJJKSBvZgorSmF2YU1haWwsIGJ1dCBhcmUgbm90IGN1cnJlbnRseSBhIHJlcXVpcmVkIHBhcnQgb2YgdGhlIHNwZWNpZmljYXRpb24uCitUaGUgbmFtZXMsIHR5cGVzLCBkZWZhdWx0cywgYW5kIHNlbWFudGljcyBvZiB0aGVzZSBwcm9wZXJ0aWVzIG1heQorY2hhbmdlIGluIGZ1dHVyZSByZWxlYXNlcy4KKzwvUD4KKzxUQUJMRSBCT1JERVIgU1VNTUFSWT0iSmF2YU1haWwgUkkgcHJvcGVydGllcyI+Cis8VFI+Cis8VEg+TmFtZTwvVEg+Cis8VEg+VHlwZTwvVEg+Cis8VEg+RGVzY3JpcHRpb248L1RIPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuZGVidWcuYXV0aCI+bWFpbC5kZWJ1Zy5hdXRoPC9BPjwvVEQ+Cis8VEQ+Ym9vbGVhbjwvVEQ+Cis8VEQ+CitJbmNsdWRlIHByb3RvY29sIGF1dGhlbnRpY2F0aW9uIGNvbW1hbmRzIChpbmNsdWRpbmcgdXNlcm5hbWVzIGFuZCBwYXNzd29yZHMpCitpbiB0aGUgZGVidWcgb3V0cHV0LgorRGVmYXVsdCBpcyBmYWxzZS4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5kZWJ1Zy5hdXRoLnVzZXJuYW1lIj5tYWlsLmRlYnVnLmF1dGgudXNlcm5hbWU8L0E+PC9URD4KKzxURD5ib29sZWFuPC9URD4KKzxURD4KK0luY2x1ZGUgdGhlIHVzZXIgbmFtZSBpbiBub24tcHJvdG9jb2wgZGVidWcgb3V0cHV0LgorRGVmYXVsdCBpcyB0cnVlLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLmRlYnVnLmF1dGgucGFzc3dvcmQiPm1haWwuZGVidWcuYXV0aC5wYXNzd29yZDwvQT48L1REPgorPFREPmJvb2xlYW48L1REPgorPFREPgorSW5jbHVkZSB0aGUgcGFzc3dvcmQgaW4gbm9uLXByb3RvY29sIGRlYnVnIG91dHB1dC4KK0RlZmF1bHQgaXMgZmFsc2UuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwudHJhbnNwb3J0LnByb3RvY29sLmFkZHJlc3MtdHlwZSI+bWFpbC50cmFuc3BvcnQucHJvdG9jb2wuPGk+YWRkcmVzcy10eXBlPC9pPjwvQT48L1REPgorPFREPlN0cmluZzwvVEQ+Cis8VEQ+CitTcGVjaWZpZXMgdGhlIGRlZmF1bHQgbWVzc2FnZSB0cmFuc3BvcnQgcHJvdG9jb2wgZm9yIHRoZSBzcGVjaWZpZWQgYWRkcmVzcyB0eXBlLgorVGhlIDxjb2RlPlNlc3Npb248L2NvZGU+IG1ldGhvZCA8Y29kZT5nZXRUcmFuc3BvcnQoQWRkcmVzcyk8L2NvZGU+IHJldHVybnMgYQorVHJhbnNwb3J0IG9iamVjdCB0aGF0IGltcGxlbWVudHMgdGhpcyBwcm90b2NvbCB3aGVuIHRoZSBhZGRyZXNzIGlzIG9mIHRoZQorc3BlY2lmaWVkIHR5cGUgKGUuZy4sICJyZmM4MjIiIGZvciBzdGFuZGFyZCBpbnRlcm5ldCBhZGRyZXNzZXMpLgorQnkgZGVmYXVsdCB0aGUgZmlyc3QgVHJhbnNwb3J0IGNvbmZpZ3VyZWQgZm9yIHRoYXQgYWRkcmVzcyB0eXBlIGlzIHVzZWQuCitUaGlzIHByb3BlcnR5IGNhbiBiZSB1c2VkIHRvIG92ZXJyaWRlIHRoZSBiZWhhdmlvciBvZiB0aGUKK3tAbGluayBqYXZheC5tYWlsLlRyYW5zcG9ydCNzZW5kIHNlbmR9IG1ldGhvZCBvZiB0aGUKK3tAbGluayBqYXZheC5tYWlsLlRyYW5zcG9ydCBUcmFuc3BvcnR9IGNsYXNzIHNvIHRoYXQgKGZvciBleGFtcGxlKSB0aGUgInNtdHBzIgorcHJvdG9jb2wgaXMgdXNlZCBpbnN0ZWFkIG9mIHRoZSAic210cCIgcHJvdG9jb2wgYnkgc2V0dGluZyB0aGUgcHJvcGVydHkKKzxjb2RlPm1haWwudHJhbnNwb3J0LnByb3RvY29sLnJmYzgyMjwvY29kZT4gdG8gPGNvZGU+InNtdHBzIjwvY29kZT4uCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuZXZlbnQuc2NvcGUiPm1haWwuZXZlbnQuc2NvcGU8L0E+PC9URD4KKzxURD5TdHJpbmc8L1REPgorPFREPgorQ29udHJvbHMgdGhlIHNjb3BlIG9mIGV2ZW50cy4gIChTZWUgdGhlIGphdmF4Lm1haWwuZXZlbnQgcGFja2FnZS4pCitCeSBkZWZhdWx0LCBhIHNlcGFyYXRlIGV2ZW50IHF1ZXVlIGFuZCB0aHJlYWQgaXMgdXNlZCBmb3IgZXZlbnRzIGZvciBlYWNoCitTdG9yZSwgVHJhbnNwb3J0LCBvciBGb2xkZXIuCitJZiB0aGlzIHByb3BlcnR5IGlzIHNldCB0byAic2Vzc2lvbiIsIGFsbCBzdWNoIGV2ZW50cyBhcmUgcHV0IGluIGEgc2luZ2xlCitldmVudCBxdWV1ZSBwcm9jZXNzZWQgYnkgYSBzaW5nbGUgdGhyZWFkIGZvciB0aGUgY3VycmVudCBzZXNzaW9uLgorSWYgdGhpcyBwcm9wZXJ0eSBpcyBzZXQgdG8gImFwcGxpY2F0aW9uIiwgYWxsIHN1Y2ggZXZlbnRzIGFyZSBwdXQgaW4gYSBzaW5nbGUKK2V2ZW50IHF1ZXVlIHByb2Nlc3NlZCBieSBhIHNpbmdsZSB0aHJlYWQgZm9yIHRoZSBjdXJyZW50IGFwcGxpY2F0aW9uLgorKEFwcGxpY2F0aW9ucyBhcmUgZGlzdGluZ3Vpc2hlZCBieSB0aGVpciBjb250ZXh0IGNsYXNzIGxvYWRlci4pCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuZXZlbnQuZXhlY3V0b3IiPm1haWwuZXZlbnQuZXhlY3V0b3I8L0E+PC9URD4KKzxURD5qYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRvcjwvVEQ+Cis8VEQ+CitCeSBkZWZhdWx0LCBhIG5ldyBUaHJlYWQgaXMgY3JlYXRlZCBmb3IgZWFjaCBldmVudCBxdWV1ZS4KK1RoaXMgdGhyZWFkIGlzIHVzZWQgdG8gY2FsbCB0aGUgbGlzdGVuZXJzIGZvciB0aGVzZSBldmVudHMuCitJZiB0aGlzIHByb3BlcnR5IGlzIHNldCB0byBhbiBpbnN0YW5jZSBvZiBhbiBFeGVjdXRvciwgdGhlCitFeGVjdXRvci5leGVjdXRlIG1ldGhvZCBpcyB1c2VkIHRvIHJ1biB0aGUgZXZlbnQgZGlzcGF0Y2hlcgorZm9yIGFuIGV2ZW50IHF1ZXVlLiAgVGhlIGV2ZW50IGRpc3BhdGNoZXIgcnVucyB1bnRpbCB0aGUKK2V2ZW50IHF1ZXVlIGlzIG5vIGxvbmdlciBpbiB1c2UuCis8L1REPgorPC9UUj4KKworPC9UQUJMRT4KKworPFA+CitUaGUgSmF2YU1haWwgQVBJIGFsc28gc3VwcG9ydHMgc2V2ZXJhbCBTeXN0ZW0gcHJvcGVydGllczsKK3NlZSB0aGUge0BsaW5rIGphdmF4Lm1haWwuaW50ZXJuZXR9IHBhY2thZ2UgZG9jdW1lbnRhdGlvbgorZm9yIGRldGFpbHMuCis8L1A+Cis8UD4KK1RoZSBKYXZhTWFpbCByZWZlcmVuY2UKK2ltcGxlbWVudGF0aW9uIGluY2x1ZGVzIHByb3RvY29sIHByb3ZpZGVycyBpbiBzdWJwYWNrYWdlcyBvZgorPGNvZGU+Y29tLnN1bi5tYWlsPC9jb2RlPi4gIE5vdGUgdGhhdCB0aGUgQVBJcyB0byB0aGVzZSBwcm90b2NvbAorcHJvdmlkZXJzIGFyZSBub3QgcGFydCBvZiB0aGUgc3RhbmRhcmQgSmF2YU1haWwgQVBJLiAgUG9ydGFibGUKK3Byb2dyYW1zIHdpbGwgbm90IHVzZSB0aGVzZSBBUElzLgorPC9QPgorPFA+CitOb25wb3J0YWJsZSBwcm9ncmFtcyBtYXkgdXNlIHRoZSBBUElzIG9mIHRoZSBwcm90b2NvbCBwcm92aWRlcnMKK2J5IChmb3IgZXhhbXBsZSkgY2FzdGluZyBhIHJldHVybmVkIDxjb2RlPkZvbGRlcjwvY29kZT4gb2JqZWN0IHRvIGEKKzxjb2RlPmNvbS5zdW4ubWFpbC5pbWFwLklNQVBGb2xkZXI8L2NvZGU+IG9iamVjdC4gIFNpbWlsYXJseSBmb3IKKzxjb2RlPlN0b3JlPC9jb2RlPiBhbmQgPGNvZGU+TWVzc2FnZTwvY29kZT4gb2JqZWN0cyByZXR1cm5lZCBmcm9tIHRoZQorc3RhbmRhcmQgSmF2YU1haWwgQVBJcy4KKzwvUD4KKzxQPgorVGhlIHByb3RvY29sIHByb3ZpZGVycyBhbHNvIHN1cHBvcnQgcHJvcGVydGllcyB0aGF0IGFyZSBzcGVjaWZpYyB0bwordGhvc2UgcHJvdmlkZXJzLiAgVGhlIHBhY2thZ2UgZG9jdW1lbnRhdGlvbiBmb3IgdGhlCit7QGxpbmsgY29tLnN1bi5tYWlsLmltYXAgSU1BUH0sIHtAbGluayBjb20uc3VuLm1haWwucG9wMyBQT1AzfSwKK2FuZCB7QGxpbmsgY29tLnN1bi5tYWlsLnNtdHAgU01UUH0gcGFja2FnZXMgcHJvdmlkZSBkZXRhaWxzLgorPC9QPgorPFA+CitJbiBhZGRpdGlvbiB0byBwcmludGluZyBkZWJ1Z2dpbmcgb3V0cHV0IGFzIGNvbnRyb2xsZWQgYnkgdGhlCit7QGxpbmsgamF2YXgubWFpbC5TZXNzaW9uIFNlc3Npb259IGNvbmZpZ3VyYXRpb24sIHRoZSBjdXJyZW50CitpbXBsZW1lbnRhdGlvbiBvZiBjbGFzc2VzIGluIHRoaXMgcGFja2FnZSBsb2cgdGhlIHNhbWUgaW5mb3JtYXRpb24gdXNpbmcKK3tAbGluayBqYXZhLnV0aWwubG9nZ2luZy5Mb2dnZXJ9IGFzIGRlc2NyaWJlZCBpbiB0aGUgZm9sbG93aW5nIHRhYmxlOgorPC9QPgorPFRBQkxFIEJPUkRFUiBTVU1NQVJZPSJKYXZhTWFpbCBMb2dnZXJzIj4KKzxUUj4KKzxUSD5Mb2dnZXIgTmFtZTwvVEg+Cis8VEg+TG9nZ2luZyBMZXZlbDwvVEg+Cis8VEg+UHVycG9zZTwvVEg+Cis8L1RSPgorCis8VFI+Cis8VEQ+amF2YXgubWFpbDwvVEQ+Cis8VEQ+Q09ORklHPC9URD4KKzxURD5Db25maWd1cmF0aW9uIG9mIHRoZSBTZXNzaW9uPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD5qYXZheC5tYWlsPC9URD4KKzxURD5GSU5FPC9URD4KKzxURD5HZW5lcmFsIGRlYnVnZ2luZyBvdXRwdXQ8L1REPgorPC9UUj4KKzwvVEFCTEU+CisKKzwvQk9EWT4KKzwvSFRNTD4KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL3NlYXJjaC9BZGRyZXNzU3RyaW5nVGVybS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvc2VhcmNoL0FkZHJlc3NTdHJpbmdUZXJtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWU0OGU3MgotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL3NlYXJjaC9BZGRyZXNzU3RyaW5nVGVybS5qYXZhCkBAIC0wLDAgKzEsODAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5zZWFyY2g7CisKK2ltcG9ydCBqYXZheC5tYWlsLk1lc3NhZ2U7CitpbXBvcnQgamF2YXgubWFpbC5BZGRyZXNzOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuSW50ZXJuZXRBZGRyZXNzOworCisvKioKKyAqIFRoaXMgYWJzdHJhY3QgY2xhc3MgaW1wbGVtZW50cyBzdHJpbmcgY29tcGFyaXNvbnMgZm9yIE1lc3NhZ2UgCisgKiBhZGRyZXNzZXMuIDxwPgorICoKKyAqIE5vdGUgdGhhdCB0aGlzIGNsYXNzIGRpZmZlcnMgZnJvbSB0aGUgPGNvZGU+QWRkcmVzc1Rlcm08L2NvZGU+IGNsYXNzCisgKiBpbiB0aGF0IHRoaXMgY2xhc3MgZG9lcyBjb21wYXJpc29ucyBvbiBhZGRyZXNzIHN0cmluZ3MgcmF0aGVyIHRoYW4KKyAqIEFkZHJlc3Mgb2JqZWN0cy4KKyAqCisgKiBAc2luY2UgICAgICAgSmF2YU1haWwgMS4xCisgKi8KKworcHVibGljIGFic3RyYWN0IGNsYXNzIEFkZHJlc3NTdHJpbmdUZXJtIGV4dGVuZHMgU3RyaW5nVGVybSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAzMDg2ODIxMjM0MjA0OTgwMzY4TDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yLgorICAgICAqCisgICAgICogQHBhcmFtIHBhdHRlcm4gICB0aGUgYWRkcmVzcyBwYXR0ZXJuIHRvIGJlIGNvbXBhcmVkLgorICAgICAqLworICAgIHByb3RlY3RlZCBBZGRyZXNzU3RyaW5nVGVybShTdHJpbmcgcGF0dGVybikgeworCXN1cGVyKHBhdHRlcm4sIHRydWUpOyAvLyB3ZSBuZWVkIGNhc2UtaW5zZW5zaXRpdmUgY29tcGFyaXNvbi4KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVjayB3aGV0aGVyIHRoZSBhZGRyZXNzIHBhdHRlcm4gc3BlY2lmaWVkIGluIHRoZSBjb25zdHJ1Y3RvciBpcworICAgICAqIGEgc3Vic3RyaW5nIG9mIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGdpdmVuIEFkZHJlc3MKKyAgICAgKiBvYmplY3QuIDxwPgorICAgICAqCisgICAgICogTm90ZSB0aGF0IGlmIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGdpdmVuIEFkZHJlc3Mgb2JqZWN0CisgICAgICogY29udGFpbnMgY2hhcnNldCBvciB0cmFuc2ZlciBlbmNvZGluZ3MsIHRoZSBlbmNvZGluZ3MgbXVzdCBiZSAKKyAgICAgKiBhY2NvdW50ZWQgZm9yLCBkdXJpbmcgdGhlIG1hdGNoIHByb2Nlc3MuIDxwPgorICAgICAqCisgICAgICogQHBhcmFtICAgYSAJVGhlIGNvbXBhcmlzb24gaXMgYXBwbGllZCB0byB0aGlzIEFkZHJlc3Mgb2JqZWN0LgorICAgICAqIEByZXR1cm4gICAgICAgICAgdHJ1ZSBpZiB0aGUgbWF0Y2ggc3VjY2VlZHMsIG90aGVyd2lzZSBmYWxzZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBtYXRjaChBZGRyZXNzIGEpIHsKKwlpZiAoYSBpbnN0YW5jZW9mIEludGVybmV0QWRkcmVzcykgeworCSAgICBJbnRlcm5ldEFkZHJlc3MgaWEgPSAoSW50ZXJuZXRBZGRyZXNzKWE7CisJICAgIC8vIFdlIGRvbnQgdXNlIHRvU3RyaW5nKCkgdG8gZ2V0ICJhIidzIFN0cmluZyByZXByZXNlbnRhdGlvbiwKKwkgICAgLy8gYmVjYXVzZSBJbnRlcm5ldEFkZHJlc3MudG9TdHJpbmcoKSByZXR1cm5zIGEgUkZDIDIwNDcgCisJICAgIC8vIGVuY29kZWQgc3RyaW5nLCB3aGljaCBpc24ndCB3aGF0IHdlIG5lZWQgaGVyZS4KKworCSAgICByZXR1cm4gc3VwZXIubWF0Y2goaWEudG9Vbmljb2RlU3RyaW5nKCkpOworCX0gZWxzZQorCSAgICByZXR1cm4gc3VwZXIubWF0Y2goYS50b1N0cmluZygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFcXVhbGl0eSBjb21wYXJpc29uLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CisJaWYgKCEob2JqIGluc3RhbmNlb2YgQWRkcmVzc1N0cmluZ1Rlcm0pKQorCSAgICByZXR1cm4gZmFsc2U7CisJcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL3NlYXJjaC9BZGRyZXNzVGVybS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvc2VhcmNoL0FkZHJlc3NUZXJtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzQ4YWQzMwotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL3NlYXJjaC9BZGRyZXNzVGVybS5qYXZhCkBAIC0wLDAgKzEsNzkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5zZWFyY2g7CisKK2ltcG9ydCBqYXZheC5tYWlsLkFkZHJlc3M7CisKKy8qKgorICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIE1lc3NhZ2UgQWRkcmVzcyBjb21wYXJpc29ucy4KKyAqCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICogQGF1dGhvciBKb2huIE1hbmkKKyAqLworCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQWRkcmVzc1Rlcm0gZXh0ZW5kcyBTZWFyY2hUZXJtIHsKKyAgICAvKioKKyAgICAgKiBUaGUgYWRkcmVzcy4KKyAgICAgKgorICAgICAqIEBzZXJpYWwKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgQWRkcmVzcyBhZGRyZXNzOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMjAwNTQwNTU1MTkyOTc2OTk4MEw7CisKKyAgICBwcm90ZWN0ZWQgQWRkcmVzc1Rlcm0oQWRkcmVzcyBhZGRyZXNzKSB7CisJdGhpcy5hZGRyZXNzID0gYWRkcmVzczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIGFkZHJlc3MgdG8gbWF0Y2ggd2l0aC4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIGFkZGRyZXNzCisgICAgICovCisgICAgcHVibGljIEFkZHJlc3MgZ2V0QWRkcmVzcygpIHsKKwlyZXR1cm4gYWRkcmVzczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNYXRjaCBhZ2FpbnN0IHRoZSBhcmd1bWVudCBBZGRyZXNzLgorICAgICAqCisgICAgICogQHBhcmFtCWEJdGhlIGFkZHJlc3MgdG8gbWF0Y2gKKyAgICAgKiBAcmV0dXJuCXRydWUgaWYgaXQgbWF0Y2hlcworICAgICAqLworICAgIHByb3RlY3RlZCBib29sZWFuIG1hdGNoKEFkZHJlc3MgYSkgeworCXJldHVybiAoYS5lcXVhbHMoYWRkcmVzcykpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVxdWFsaXR5IGNvbXBhcmlzb24uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKKwlpZiAoIShvYmogaW5zdGFuY2VvZiBBZGRyZXNzVGVybSkpCisJICAgIHJldHVybiBmYWxzZTsKKwlBZGRyZXNzVGVybSBhdCA9IChBZGRyZXNzVGVybSlvYmo7CisJcmV0dXJuIGF0LmFkZHJlc3MuZXF1YWxzKHRoaXMuYWRkcmVzcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcHV0ZSBhIGhhc2hDb2RlIGZvciB0aGlzIG9iamVjdC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworCXJldHVybiBhZGRyZXNzLmhhc2hDb2RlKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvc2VhcmNoL0FuZFRlcm0uamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL3NlYXJjaC9BbmRUZXJtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDBiOTM1ZAotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL3NlYXJjaC9BbmRUZXJtLmphdmEKQEAgLTAsMCArMSwxMTYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5zZWFyY2g7CisKK2ltcG9ydCBqYXZheC5tYWlsLk1lc3NhZ2U7CisKKy8qKgorICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIHRoZSBsb2dpY2FsIEFORCBvcGVyYXRvciBvbiBpbmRpdmlkdWFsCisgKiBTZWFyY2hUZXJtcy4KKyAqCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICogQGF1dGhvciBKb2huIE1hbmkKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEFuZFRlcm0gZXh0ZW5kcyBTZWFyY2hUZXJtIHsKKworICAgIC8qKgorICAgICAqIFRoZSBhcnJheSBvZiB0ZXJtcyBvbiB3aGljaCB0aGUgQU5EIG9wZXJhdG9yIHNob3VsZCBiZQorICAgICAqIGFwcGxpZWQuCisgICAgICoKKyAgICAgKiBAc2VyaWFsCisgICAgICovCisgICAgcHJpdmF0ZSBTZWFyY2hUZXJtW10gdGVybXM7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMzU4MzI3NDUwNTM4MDk4OTU4Mkw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvciB0aGF0IHRha2VzIHR3byB0ZXJtcy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdDEgZmlyc3QgdGVybQorICAgICAqIEBwYXJhbSB0MiBzZWNvbmQgdGVybQorICAgICAqLworICAgIHB1YmxpYyBBbmRUZXJtKFNlYXJjaFRlcm0gdDEsIFNlYXJjaFRlcm0gdDIpIHsKKwl0ZXJtcyA9IG5ldyBTZWFyY2hUZXJtWzJdOworCXRlcm1zWzBdID0gdDE7CisJdGVybXNbMV0gPSB0MjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvciB0aGF0IHRha2VzIGFuIGFycmF5IG9mIFNlYXJjaFRlcm1zLgorICAgICAqIAorICAgICAqIEBwYXJhbSB0ICBhcnJheSBvZiB0ZXJtcworICAgICAqLworICAgIHB1YmxpYyBBbmRUZXJtKFNlYXJjaFRlcm1bXSB0KSB7CisJdGVybXMgPSBuZXcgU2VhcmNoVGVybVt0Lmxlbmd0aF07IC8vIGNsb25lIHRoZSBhcnJheQorCWZvciAoaW50IGkgPSAwOyBpIDwgdC5sZW5ndGg7IGkrKykKKwkgICAgdGVybXNbaV0gPSB0W2ldOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgc2VhcmNoIHRlcm1zLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgc2VhcmNoIHRlcm1zCisgICAgICovCisgICAgcHVibGljIFNlYXJjaFRlcm1bXSBnZXRUZXJtcygpIHsKKwlyZXR1cm4gdGVybXMuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgQU5EIG9wZXJhdGlvbi4gPHA+CisgICAgICoKKyAgICAgKiBUaGUgdGVybXMgc3BlY2lmaWVkIGluIHRoZSBjb25zdHJ1Y3RvciBhcmUgYXBwbGllZCB0bworICAgICAqIHRoZSBnaXZlbiBvYmplY3QgYW5kIHRoZSBBTkQgb3BlcmF0b3IgaXMgYXBwbGllZCB0byB0aGVpciByZXN1bHRzLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZwlUaGUgc3BlY2lmaWVkIFNlYXJjaFRlcm1zIGFyZSBhcHBsaWVkIHRvIHRoaXMgTWVzc2FnZQorICAgICAqCQkJYW5kIHRoZSBBTkQgb3BlcmF0b3IgaXMgYXBwbGllZCB0byB0aGVpciByZXN1bHRzLgorICAgICAqIEByZXR1cm4JCXRydWUgaWYgdGhlIEFORCBzdWNjZWRzLCBvdGhlcndpc2UgZmFsc2UKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBtYXRjaChNZXNzYWdlIG1zZykgeworCWZvciAoaW50IGk9MDsgaSA8IHRlcm1zLmxlbmd0aDsgaSsrKQorCSAgICBpZiAoIXRlcm1zW2ldLm1hdGNoKG1zZykpCisJCXJldHVybiBmYWxzZTsKKwlyZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFcXVhbGl0eSBjb21wYXJpc29uLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CisJaWYgKCEob2JqIGluc3RhbmNlb2YgQW5kVGVybSkpCisJICAgIHJldHVybiBmYWxzZTsKKwlBbmRUZXJtIGF0ID0gKEFuZFRlcm0pb2JqOworCWlmIChhdC50ZXJtcy5sZW5ndGggIT0gdGVybXMubGVuZ3RoKQorCSAgICByZXR1cm4gZmFsc2U7CisJZm9yIChpbnQgaT0wOyBpIDwgdGVybXMubGVuZ3RoOyBpKyspCisJICAgIGlmICghdGVybXNbaV0uZXF1YWxzKGF0LnRlcm1zW2ldKSkKKwkJcmV0dXJuIGZhbHNlOworCXJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXB1dGUgYSBoYXNoQ29kZSBmb3IgdGhpcyBvYmplY3QuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKwlpbnQgaGFzaCA9IDA7CisJZm9yIChpbnQgaT0wOyBpIDwgdGVybXMubGVuZ3RoOyBpKyspCisJICAgIGhhc2ggKz0gdGVybXNbaV0uaGFzaENvZGUoKTsKKwlyZXR1cm4gaGFzaDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9zZWFyY2gvQm9keVRlcm0uamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL3NlYXJjaC9Cb2R5VGVybS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZhNjc4OTMKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9zZWFyY2gvQm9keVRlcm0uamF2YQpAQCAtMCwwICsxLDEwMyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsLnNlYXJjaDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YXgubWFpbC4qOworCisvKioKKyAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyBzZWFyY2hlcyBvbiBhIG1lc3NhZ2UgYm9keS4KKyAqIEFsbCBwYXJ0cyBvZiB0aGUgbWVzc2FnZSB0aGF0IGFyZSBvZiBNSU1FIHR5cGUgInRleHQvKiIgYXJlIHNlYXJjaGVkLgorICogVGhlIHBhdHRlcm4gaXMgYSBzaW1wbGUgc3RyaW5nIHRoYXQgbXVzdCBhcHBlYXIgYXMgYSBzdWJzdHJpbmcgaW4KKyAqIHRoZSBtZXNzYWdlIGJvZHkuCisgKiAKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKiBAYXV0aG9yIEpvaG4gTWFuaQorICovCitwdWJsaWMgZmluYWwgY2xhc3MgQm9keVRlcm0gZXh0ZW5kcyBTdHJpbmdUZXJtIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC00ODg4ODYyNTI3OTE2OTExMzg1TDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yCisgICAgICogQHBhcmFtIHBhdHRlcm4JVGhlIFN0cmluZyB0byBzZWFyY2ggZm9yCisgICAgICovCisgICAgcHVibGljIEJvZHlUZXJtKFN0cmluZyBwYXR0ZXJuKSB7CisJLy8gTm90ZTogY29tcGFyaXNvbiBpcyBjYXNlLWluc2Vuc2l0aXZlCisJc3VwZXIocGF0dGVybik7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIG1hdGNoIG1ldGhvZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtc2cJVGhlIHBhdHRlcm4gc2VhcmNoIGlzIGFwcGxpZWQgb24gdGhpcyBNZXNzYWdlJ3MgYm9keQorICAgICAqIEByZXR1cm4JCXRydWUgaWYgdGhlIHBhdHRlcm4gaXMgZm91bmQ7IG90aGVyd2lzZSBmYWxzZSAKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBtYXRjaChNZXNzYWdlIG1zZykgeworCXJldHVybiBtYXRjaFBhcnQobXNnKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZWFyY2ggYWxsIHRoZSBwYXJ0cyBvZiB0aGUgbWVzc2FnZSBmb3IgYW55IHRleHQgcGFydAorICAgICAqIHRoYXQgbWF0Y2hlcyB0aGUgcGF0dGVybi4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gbWF0Y2hQYXJ0KFBhcnQgcCkgeworCXRyeSB7CisJICAgIC8qCisJICAgICAqIFVzaW5nIGlzTWltZVR5cGUgdG8gZGV0ZXJtaW5lIHRoZSBjb250ZW50IHR5cGUgYXZvaWRzCisJICAgICAqIGZldGNoaW5nIHRoZSBhY3R1YWwgY29udGVudCBkYXRhIHVudGlsIHdlIG5lZWQgaXQuCisJICAgICAqLworCSAgICBpZiAocC5pc01pbWVUeXBlKCJ0ZXh0LyoiKSkgeworCQlTdHJpbmcgcyA9IChTdHJpbmcpcC5nZXRDb250ZW50KCk7CisJCWlmIChzID09IG51bGwpCisJCSAgICByZXR1cm4gZmFsc2U7CisJCS8qCisJCSAqIFdlIGludm9rZSBvdXIgc3VwZXJjbGFzcycgKGkuZS4sIFN0cmluZ1Rlcm0pIG1hdGNoIG1ldGhvZC4KKwkJICogTm90ZSBob3dldmVyIHRoYXQgU3RyaW5nVGVybS5tYXRjaCgpIGlzIG5vdCBvcHRpbWl6ZWQgCisJCSAqIGZvciBzdWJzdHJpbmcgc2VhcmNoZXMgaW4gbGFyZ2Ugc3RyaW5nIGJ1ZmZlcnMuIFdlIHJlYWxseQorCQkgKiBuZWVkIHRvIGhhdmUgYSBTdHJpbmdUZXJtIHN1YmNsYXNzLCBzYXkgQmlnU3RyaW5nVGVybSwgCisJCSAqIHdpdGggaXRzIG93biBtYXRjaCgpIG1ldGhvZCB0aGF0IHVzZXMgYSBiZXR0ZXIgYWxnb3JpdGhtIC4uCisJCSAqIGFuZCB0aGVuIHN1YmNsYXNzIEJvZHlUZXJtIGZyb20gQmlnU3RyaW5nVGVybS4KKwkJICovIAorCQlyZXR1cm4gc3VwZXIubWF0Y2gocyk7CisJICAgIH0gZWxzZSBpZiAocC5pc01pbWVUeXBlKCJtdWx0aXBhcnQvKiIpKSB7CisJCU11bHRpcGFydCBtcCA9IChNdWx0aXBhcnQpcC5nZXRDb250ZW50KCk7CisJCWludCBjb3VudCA9IG1wLmdldENvdW50KCk7CisJCWZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykKKwkJICAgIGlmIChtYXRjaFBhcnQobXAuZ2V0Qm9keVBhcnQoaSkpKQorCQkJcmV0dXJuIHRydWU7CisJICAgIH0gZWxzZSBpZiAocC5pc01pbWVUeXBlKCJtZXNzYWdlL3JmYzgyMiIpKSB7CisJCXJldHVybiBtYXRjaFBhcnQoKFBhcnQpcC5nZXRDb250ZW50KCkpOworCSAgICB9CisJfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIGV4KSB7CisJfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKwl9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGV4KSB7CisJfQorCXJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFcXVhbGl0eSBjb21wYXJpc29uLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CisJaWYgKCEob2JqIGluc3RhbmNlb2YgQm9keVRlcm0pKQorCSAgICByZXR1cm4gZmFsc2U7CisJcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL3NlYXJjaC9Db21wYXJpc29uVGVybS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvc2VhcmNoL0NvbXBhcmlzb25UZXJtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTczMzBlYwotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL3NlYXJjaC9Db21wYXJpc29uVGVybS5qYXZhCkBAIC0wLDAgKzEsNjEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5zZWFyY2g7CisKKy8qKgorICogVGhpcyBjbGFzcyBtb2RlbHMgdGhlIGNvbXBhcmlzb24gb3BlcmF0b3IuIFRoaXMgaXMgYW4gYWJzdHJhY3QKKyAqIGNsYXNzOyBzdWJjbGFzc2VzIGltcGxlbWVudCBjb21wYXJpc29ucyBmb3IgZGlmZmVyZW50IGRhdGF0eXBlcy4KKyAqCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICogQGF1dGhvciBKb2huIE1hbmkKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIENvbXBhcmlzb25UZXJtIGV4dGVuZHMgU2VhcmNoVGVybSB7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTEUgPSAxOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExUID0gMjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUSA9IDM7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTkUgPSA0OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEdUID0gNTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBHRSA9IDY7CisKKyAgICAvKioKKyAgICAgKiBUaGUgY29tcGFyaXNvbi4KKyAgICAgKgorICAgICAqIEBzZXJpYWwKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IGNvbXBhcmlzb247CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxNDU2NjQ2OTUzNjY2NDc0MzA4TDsKKworICAgIC8qKgorICAgICAqIEVxdWFsaXR5IGNvbXBhcmlzb24uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKKwlpZiAoIShvYmogaW5zdGFuY2VvZiBDb21wYXJpc29uVGVybSkpCisJICAgIHJldHVybiBmYWxzZTsKKwlDb21wYXJpc29uVGVybSBjdCA9IChDb21wYXJpc29uVGVybSlvYmo7CisJcmV0dXJuIGN0LmNvbXBhcmlzb24gPT0gdGhpcy5jb21wYXJpc29uOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXB1dGUgYSBoYXNoQ29kZSBmb3IgdGhpcyBvYmplY3QuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKwlyZXR1cm4gY29tcGFyaXNvbjsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9zZWFyY2gvRGF0ZVRlcm0uamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL3NlYXJjaC9EYXRlVGVybS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgzM2FkOTAKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9zZWFyY2gvRGF0ZVRlcm0uamF2YQpAQCAtMCwwICsxLDEwOCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsLnNlYXJjaDsKKworaW1wb3J0IGphdmEudXRpbC5EYXRlOworCisvKioKKyAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyBjb21wYXJpc29ucyBmb3IgRGF0ZXMKKyAqCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICogQGF1dGhvciBKb2huIE1hbmkKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIERhdGVUZXJtIGV4dGVuZHMgQ29tcGFyaXNvblRlcm0geworICAgIC8qKgorICAgICAqIFRoZSBkYXRlLgorICAgICAqCisgICAgICogQHNlcmlhbAorICAgICAqLworICAgIHByb3RlY3RlZCBEYXRlIGRhdGU7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA0ODE4ODczNDMwMDYzNzIwMDQzTDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yLgorICAgICAqIEBwYXJhbSBjb21wYXJpc29uIHRoZSBjb21wYXJpc29uIHR5cGUKKyAgICAgKiBAcGFyYW0gZGF0ZSAgVGhlIERhdGUgdG8gYmUgY29tcGFyZWQgYWdhaW5zdAorICAgICAqLworICAgIHByb3RlY3RlZCBEYXRlVGVybShpbnQgY29tcGFyaXNvbiwgRGF0ZSBkYXRlKSB7CisJdGhpcy5jb21wYXJpc29uID0gY29tcGFyaXNvbjsKKwl0aGlzLmRhdGUgPSBkYXRlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgRGF0ZSB0byBjb21wYXJlIHdpdGguCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBkYXRlCisgICAgICovCisgICAgcHVibGljIERhdGUgZ2V0RGF0ZSgpIHsKKwlyZXR1cm4gbmV3IERhdGUoZGF0ZS5nZXRUaW1lKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgdHlwZSBvZiBjb21wYXJpc29uLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgY29tcGFyaXNvbiB0eXBlCisgICAgICovCisgICAgcHVibGljIGludCBnZXRDb21wYXJpc29uKCkgeworCXJldHVybiBjb21wYXJpc29uOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBkYXRlIGNvbXBhcmlzb24gbWV0aG9kLgorICAgICAqCisgICAgICogQHBhcmFtIGQJdGhlIGRhdGUgaW4gdGhlIGNvbnN0cnVjdG9yIGlzIGNvbXBhcmVkIHdpdGggdGhpcyBkYXRlCisgICAgICogQHJldHVybiAgdHJ1ZSBpZiB0aGUgZGF0ZXMgbWF0Y2gsIG90aGVyd2lzZSBmYWxzZQorICAgICAqLworICAgIHByb3RlY3RlZCBib29sZWFuIG1hdGNoKERhdGUgZCkgeworCXN3aXRjaCAoY29tcGFyaXNvbikgeworCSAgICBjYXNlIExFOiAKKwkJcmV0dXJuIGQuYmVmb3JlKGRhdGUpIHx8IGQuZXF1YWxzKGRhdGUpOworCSAgICBjYXNlIExUOgorCQlyZXR1cm4gZC5iZWZvcmUoZGF0ZSk7CisJICAgIGNhc2UgRVE6CisJCXJldHVybiBkLmVxdWFscyhkYXRlKTsKKwkgICAgY2FzZSBORToKKwkJcmV0dXJuICFkLmVxdWFscyhkYXRlKTsKKwkgICAgY2FzZSBHVDoKKwkJcmV0dXJuIGQuYWZ0ZXIoZGF0ZSk7CisJICAgIGNhc2UgR0U6CisJCXJldHVybiBkLmFmdGVyKGRhdGUpIHx8IGQuZXF1YWxzKGRhdGUpOworCSAgICBkZWZhdWx0OgorCQlyZXR1cm4gZmFsc2U7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEVxdWFsaXR5IGNvbXBhcmlzb24uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKKwlpZiAoIShvYmogaW5zdGFuY2VvZiBEYXRlVGVybSkpCisJICAgIHJldHVybiBmYWxzZTsKKwlEYXRlVGVybSBkdCA9IChEYXRlVGVybSlvYmo7CisJcmV0dXJuIGR0LmRhdGUuZXF1YWxzKHRoaXMuZGF0ZSkgJiYgc3VwZXIuZXF1YWxzKG9iaik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcHV0ZSBhIGhhc2hDb2RlIGZvciB0aGlzIG9iamVjdC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworCXJldHVybiBkYXRlLmhhc2hDb2RlKCkgKyBzdXBlci5oYXNoQ29kZSgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL3NlYXJjaC9GbGFnVGVybS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvc2VhcmNoL0ZsYWdUZXJtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjA4OTdjNgotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL3NlYXJjaC9GbGFnVGVybS5qYXZhCkBAIC0wLDAgKzEsMTQ0IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGphdmF4Lm1haWwuc2VhcmNoOworCitpbXBvcnQgamF2YXgubWFpbC4qOworCisvKioKKyAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyBjb21wYXJpc29ucyBmb3IgTWVzc2FnZSBGbGFncy4KKyAqCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICogQGF1dGhvciBKb2huIE1hbmkKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEZsYWdUZXJtIGV4dGVuZHMgU2VhcmNoVGVybSB7CisKKyAgICAvKioKKyAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0byB0ZXN0IGZvciB0aGUgcHJlc2VuY2Ugb3IKKyAgICAgKiBhYnNlbmNlIG9mIHRoZSBzcGVjaWZpZWQgRmxhZy4gSWYgPGNvZGU+dHJ1ZTwvY29kZT4sCisgICAgICogdGhlbiB0ZXN0IHdoZXRoZXIgYWxsIHRoZSBzcGVjaWZpZWQgZmxhZ3MgYXJlIHByZXNlbnQsIGVsc2UKKyAgICAgKiB0ZXN0IHdoZXRoZXIgYWxsIHRoZSBzcGVjaWZpZWQgZmxhZ3MgYXJlIGFic2VudC4KKyAgICAgKgorICAgICAqIEBzZXJpYWwKKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gc2V0OworCisgICAgLyoqCisgICAgICogRmxhZ3Mgb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGZsYWdzIHRvIHRlc3QuCisgICAgICoKKyAgICAgKiBAc2VyaWFsCisgICAgICovCisgICAgcHJpdmF0ZSBGbGFncyBmbGFnczsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0xNDI5OTE1MDAzMDIwMzA2NDdMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmxhZ3MJRmxhZ3Mgb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGZsYWdzIHRvIGNoZWNrIGZvcgorICAgICAqIEBwYXJhbSBzZXQJdGhlIGZsYWcgc2V0dGluZyB0byBjaGVjayBmb3IKKyAgICAgKi8KKyAgICBwdWJsaWMgRmxhZ1Rlcm0oRmxhZ3MgZmxhZ3MsIGJvb2xlYW4gc2V0KSB7CisJdGhpcy5mbGFncyA9IGZsYWdzOworCXRoaXMuc2V0ID0gc2V0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgRmxhZ3MgdG8gdGVzdC4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIGZsYWdzCisgICAgICovCisgICAgcHVibGljIEZsYWdzIGdldEZsYWdzKCkgeworCXJldHVybiAoRmxhZ3MpZmxhZ3MuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdHJ1ZSBpZiB0ZXN0aW5nIHdoZXRoZXIgdGhlIGZsYWdzIGFyZSBzZXQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRydWUgaWYgdGVzdGluZyB3aGV0aGVyIHRoZSBmbGFncyBhcmUgc2V0CisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZ2V0VGVzdFNldCgpIHsKKwlyZXR1cm4gc2V0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBjb21wYXJpc29uIG1ldGhvZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtc2cJVGhlIGZsYWcgY29tcGFyaXNvbiBpcyBhcHBsaWVkIHRvIHRoaXMgTWVzc2FnZQorICAgICAqIEByZXR1cm4JCXRydWUgaWYgdGhlIGNvbXBhcnNvbiBzdWNjZWVkcywgb3RoZXJ3aXNlIGZhbHNlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIG1hdGNoKE1lc3NhZ2UgbXNnKSB7CisKKwl0cnkgeworCSAgICBGbGFncyBmID0gbXNnLmdldEZsYWdzKCk7CisJICAgIGlmIChzZXQpIHsgLy8gVGhpcyBpcyBlYXN5CisJCWlmIChmLmNvbnRhaW5zKGZsYWdzKSkKKwkJICAgIHJldHVybiB0cnVlOworCQllbHNlIAorCQkgICAgcmV0dXJuIGZhbHNlOworCSAgICB9CisKKwkgICAgLy8gUmV0dXJuIHRydWUgaWYgQUxMIGZsYWdzIGluIHRoZSBwYXNzZWQgaW4gRmxhZ3MKKwkgICAgLy8gb2JqZWN0IGFyZSBOT1Qgc2V0IGluIHRoaXMgTWVzc2FnZS4KKworCSAgICAvLyBHb3QgdG8gZG8gdGhpcyB0aGUgaGFyZCB3YXkgLi4uCisJICAgIEZsYWdzLkZsYWdbXSBzZiA9IGZsYWdzLmdldFN5c3RlbUZsYWdzKCk7CisKKwkgICAgLy8gQ2hlY2sgZWFjaCBmbGFnIGluIHRoZSBwYXNzZWQgaW4gRmxhZ3Mgb2JqZWN0CisJICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2YubGVuZ3RoOyBpKyspIHsKKwkJaWYgKGYuY29udGFpbnMoc2ZbaV0pKQorCQkgICAgLy8gdGhpcyBmbGFnIElTIHNldCBpbiB0aGlzIE1lc3NhZ2UsIGdldCBvdXQuCisJCSAgICByZXR1cm4gZmFsc2U7CisJICAgIH0KKworCSAgICBTdHJpbmdbXSBzID0gZmxhZ3MuZ2V0VXNlckZsYWdzKCk7CisKKwkgICAgLy8gQ2hlY2sgZWFjaCBmbGFnIGluIHRoZSBwYXNzZWQgaW4gRmxhZ3Mgb2JqZWN0CisJICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcy5sZW5ndGg7IGkrKykgeworCQlpZiAoZi5jb250YWlucyhzW2ldKSkKKwkJICAgIC8vIHRoaXMgZmxhZyBJUyBzZXQgaW4gdGhpcyBNZXNzYWdlLCBnZXQgb3V0LgorCQkgICAgcmV0dXJuIGZhbHNlOworCSAgICB9CisKKwkgICAgcmV0dXJuIHRydWU7CisKKwl9IGNhdGNoIChNZXNzYWdpbmdFeGNlcHRpb24gZSkgeworCSAgICByZXR1cm4gZmFsc2U7CisJfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBlKSB7CisJICAgIHJldHVybiBmYWxzZTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogRXF1YWxpdHkgY29tcGFyaXNvbi4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgeworCWlmICghKG9iaiBpbnN0YW5jZW9mIEZsYWdUZXJtKSkKKwkgICAgcmV0dXJuIGZhbHNlOworCUZsYWdUZXJtIGZ0ID0gKEZsYWdUZXJtKW9iajsKKwlyZXR1cm4gZnQuc2V0ID09IHRoaXMuc2V0ICYmIGZ0LmZsYWdzLmVxdWFscyh0aGlzLmZsYWdzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wdXRlIGEgaGFzaENvZGUgZm9yIHRoaXMgb2JqZWN0LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisJcmV0dXJuIHNldCA/IGZsYWdzLmhhc2hDb2RlKCkgOiB+ZmxhZ3MuaGFzaENvZGUoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9zZWFyY2gvRnJvbVN0cmluZ1Rlcm0uamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL3NlYXJjaC9Gcm9tU3RyaW5nVGVybS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY5YWI5MjYKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9zZWFyY2gvRnJvbVN0cmluZ1Rlcm0uamF2YQpAQCAtMCwwICsxLDgyIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGphdmF4Lm1haWwuc2VhcmNoOworCitpbXBvcnQgamF2YXgubWFpbC5NZXNzYWdlOworaW1wb3J0IGphdmF4Lm1haWwuQWRkcmVzczsKKworLyoqCisgKiBUaGlzIGNsYXNzIGltcGxlbWVudHMgc3RyaW5nIGNvbXBhcmlzb25zIGZvciB0aGUgRnJvbSBBZGRyZXNzCisgKiBoZWFkZXIuIDxwPgorICoKKyAqIE5vdGUgdGhhdCB0aGlzIGNsYXNzIGRpZmZlcnMgZnJvbSB0aGUgPGNvZGU+RnJvbVRlcm08L2NvZGU+IGNsYXNzCisgKiBpbiB0aGF0IHRoaXMgY2xhc3MgZG9lcyBjb21wYXJpc29ucyBvbiBhZGRyZXNzIHN0cmluZ3MgcmF0aGVyIHRoYW4gQWRkcmVzcworICogb2JqZWN0cy4gVGhlIHN0cmluZyBjb21wYXJpc29ucyBhcmUgY2FzZS1pbnNlbnNpdGl2ZS4KKyAqCisgKiBAc2luY2UgICAgICAgSmF2YU1haWwgMS4xCisgKi8KKworcHVibGljIGZpbmFsIGNsYXNzIEZyb21TdHJpbmdUZXJtIGV4dGVuZHMgQWRkcmVzc1N0cmluZ1Rlcm0geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNTgwMTEyNzUyMzgyNjc3Mjc4OEw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwYXR0ZXJuICAgdGhlIGFkZHJlc3MgcGF0dGVybiB0byBiZSBjb21wYXJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRnJvbVN0cmluZ1Rlcm0oU3RyaW5nIHBhdHRlcm4pIHsKKwlzdXBlcihwYXR0ZXJuKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVjayB3aGV0aGVyIHRoZSBhZGRyZXNzIHN0cmluZyBzcGVjaWZpZWQgaW4gdGhlIGNvbnN0cnVjdG9yIGlzCisgICAgICogYSBzdWJzdHJpbmcgb2YgdGhlIEZyb20gYWRkcmVzcyBvZiB0aGlzIE1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gICBtc2cgCVRoZSBjb21wYXJpc29uIGlzIGFwcGxpZWQgdG8gdGhpcyBNZXNzYWdlJ3MgRnJvbQorICAgICAqCQkgICAgCWFkZHJlc3MuCisgICAgICogQHJldHVybiAgICAgICAgICB0cnVlIGlmIHRoZSBtYXRjaCBzdWNjZWVkcywgb3RoZXJ3aXNlIGZhbHNlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIG1hdGNoKE1lc3NhZ2UgbXNnKSB7CisJQWRkcmVzc1tdIGZyb207CisKKwl0cnkgeworCSAgICBmcm9tID0gbXNnLmdldEZyb20oKTsKKwl9IGNhdGNoIChFeGNlcHRpb24gZSkgeworCSAgICByZXR1cm4gZmFsc2U7CisJfQorCisJaWYgKGZyb20gPT0gbnVsbCkKKwkgICAgcmV0dXJuIGZhbHNlOworCQorCWZvciAoaW50IGk9MDsgaSA8IGZyb20ubGVuZ3RoOyBpKyspCisJICAgIGlmIChzdXBlci5tYXRjaChmcm9tW2ldKSkKKwkJcmV0dXJuIHRydWU7CisJcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVxdWFsaXR5IGNvbXBhcmlzb24uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKKwlpZiAoIShvYmogaW5zdGFuY2VvZiBGcm9tU3RyaW5nVGVybSkpCisJICAgIHJldHVybiBmYWxzZTsKKwlyZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvc2VhcmNoL0Zyb21UZXJtLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9zZWFyY2gvRnJvbVRlcm0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MzIwYTk3Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvc2VhcmNoL0Zyb21UZXJtLmphdmEKQEAgLTAsMCArMSw3NCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsLnNlYXJjaDsKKworaW1wb3J0IGphdmF4Lm1haWwuTWVzc2FnZTsKK2ltcG9ydCBqYXZheC5tYWlsLkFkZHJlc3M7CisKKy8qKgorICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIGNvbXBhcmlzb25zIGZvciB0aGUgRnJvbSBBZGRyZXNzIGhlYWRlci4KKyAqCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICogQGF1dGhvciBKb2huIE1hbmkKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEZyb21UZXJtIGV4dGVuZHMgQWRkcmVzc1Rlcm0geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNTIxNDczMDI5MTUwMjY1ODY2NUw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvcgorICAgICAqIEBwYXJhbSBhZGRyZXNzCVRoZSBBZGRyZXNzIHRvIGJlIGNvbXBhcmVkCisgICAgICovCisgICAgcHVibGljIEZyb21UZXJtKEFkZHJlc3MgYWRkcmVzcykgeworCXN1cGVyKGFkZHJlc3MpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBhZGRyZXNzIGNvbXBhcmF0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbXNnCVRoZSBhZGRyZXNzIGNvbXBhcmlzb24gaXMgYXBwbGllZCB0byB0aGlzIE1lc3NhZ2UKKyAgICAgKiBAcmV0dXJuCQl0cnVlIGlmIHRoZSBjb21wYXJpc29uIHN1Y2NlZWRzLCBvdGhlcndpc2UgZmFsc2UKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBtYXRjaChNZXNzYWdlIG1zZykgeworCUFkZHJlc3NbXSBmcm9tOworCisJdHJ5IHsKKwkgICAgZnJvbSA9IG1zZy5nZXRGcm9tKCk7CisJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKwkgICAgcmV0dXJuIGZhbHNlOworCX0KKworCWlmIChmcm9tID09IG51bGwpCisJICAgIHJldHVybiBmYWxzZTsKKworCWZvciAoaW50IGk9MDsgaSA8IGZyb20ubGVuZ3RoOyBpKyspCisJICAgIGlmIChzdXBlci5tYXRjaChmcm9tW2ldKSkKKwkJcmV0dXJuIHRydWU7CisJcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVxdWFsaXR5IGNvbXBhcmlzb24uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKKwlpZiAoIShvYmogaW5zdGFuY2VvZiBGcm9tVGVybSkpCisJICAgIHJldHVybiBmYWxzZTsKKwlyZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvc2VhcmNoL0hlYWRlclRlcm0uamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL3NlYXJjaC9IZWFkZXJUZXJtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzJiODJkZQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL3NlYXJjaC9IZWFkZXJUZXJtLmphdmEKQEAgLTAsMCArMSwxMDUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5zZWFyY2g7CisKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworaW1wb3J0IGphdmF4Lm1haWwuTWVzc2FnZTsKKworLyoqCisgKiBUaGlzIGNsYXNzIGltcGxlbWVudHMgY29tcGFyaXNvbnMgZm9yIE1lc3NhZ2UgaGVhZGVycy4KKyAqIFRoZSBjb21wYXJpc29uIGlzIGNhc2UtaW5zZW5zaXRpdmUuCisgKgorICogQGF1dGhvciBCaWxsIFNoYW5ub24KKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBIZWFkZXJUZXJtIGV4dGVuZHMgU3RyaW5nVGVybSB7CisgICAgLyoqCisgICAgICogVGhlIG5hbWUgb2YgdGhlIGhlYWRlci4KKyAgICAgKgorICAgICAqIEBzZXJpYWwKKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyBoZWFkZXJOYW1lOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gODM0MjUxNDY1MDMzMzM4OTEyMkw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBoZWFkZXJOYW1lIFRoZSBuYW1lIG9mIHRoZSBoZWFkZXIKKyAgICAgKiBAcGFyYW0gcGF0dGVybiAgICBUaGUgcGF0dGVybiB0byBzZWFyY2ggZm9yCisgICAgICovCisgICAgcHVibGljIEhlYWRlclRlcm0oU3RyaW5nIGhlYWRlck5hbWUsIFN0cmluZyBwYXR0ZXJuKSB7CisJc3VwZXIocGF0dGVybik7CisJdGhpcy5oZWFkZXJOYW1lID0gaGVhZGVyTmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIG5hbWUgb2YgdGhlIGhlYWRlciB0byBjb21wYXJlIHdpdGguCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBuYW1lIG9mIHRoZSBoZWFkZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEhlYWRlck5hbWUoKSB7CisJcmV0dXJuIGhlYWRlck5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIGhlYWRlciBtYXRjaCBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbXNnCVRoZSBtYXRjaCBpcyBhcHBsaWVkIHRvIHRoaXMgTWVzc2FnZSdzIGhlYWRlcgorICAgICAqIEByZXR1cm4JCXRydWUgaWYgdGhlIG1hdGNoIHN1Y2NlZWRzLCBvdGhlcndpc2UgZmFsc2UKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBtYXRjaChNZXNzYWdlIG1zZykgeworCVN0cmluZ1tdIGhlYWRlcnM7CisKKwl0cnkgeworCSAgICBoZWFkZXJzID0gbXNnLmdldEhlYWRlcihoZWFkZXJOYW1lKTsKKwl9IGNhdGNoIChFeGNlcHRpb24gZSkgeworCSAgICByZXR1cm4gZmFsc2U7CisJfQorCisJaWYgKGhlYWRlcnMgPT0gbnVsbCkKKwkgICAgcmV0dXJuIGZhbHNlOworCisJZm9yIChpbnQgaT0wOyBpIDwgaGVhZGVycy5sZW5ndGg7IGkrKykKKwkgICAgaWYgKHN1cGVyLm1hdGNoKGhlYWRlcnNbaV0pKQorCQlyZXR1cm4gdHJ1ZTsKKwlyZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXF1YWxpdHkgY29tcGFyaXNvbi4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgeworCWlmICghKG9iaiBpbnN0YW5jZW9mIEhlYWRlclRlcm0pKQorCSAgICByZXR1cm4gZmFsc2U7CisJSGVhZGVyVGVybSBodCA9IChIZWFkZXJUZXJtKW9iajsKKwkvLyBYWFggLSBkZXBlbmRzIG9uIGhlYWRlciBjb21wYXJpc29ucyBiZWluZyBjYXNlIGluZGVwZW5kZW50CisJcmV0dXJuIGh0LmhlYWRlck5hbWUuZXF1YWxzSWdub3JlQ2FzZShoZWFkZXJOYW1lKSAmJiBzdXBlci5lcXVhbHMoaHQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXB1dGUgYSBoYXNoQ29kZSBmb3IgdGhpcyBvYmplY3QuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKwkvLyBYWFggLSBkZXBlbmRzIG9uIGhlYWRlciBjb21wYXJpc29ucyBiZWluZyBjYXNlIGluZGVwZW5kZW50CisJcmV0dXJuIGhlYWRlck5hbWUudG9Mb3dlckNhc2UoTG9jYWxlLkVOR0xJU0gpLmhhc2hDb2RlKCkgKworCQkJCQlzdXBlci5oYXNoQ29kZSgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL3NlYXJjaC9JbnRlZ2VyQ29tcGFyaXNvblRlcm0uamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL3NlYXJjaC9JbnRlZ2VyQ29tcGFyaXNvblRlcm0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mODkwMDUxCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvc2VhcmNoL0ludGVnZXJDb21wYXJpc29uVGVybS5qYXZhCkBAIC0wLDAgKzEsOTUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5zZWFyY2g7CisKKy8qKgorICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIGNvbXBhcmlzb25zIGZvciBpbnRlZ2Vycy4KKyAqCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICogQGF1dGhvciBKb2huIE1hbmkKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEludGVnZXJDb21wYXJpc29uVGVybSBleHRlbmRzIENvbXBhcmlzb25UZXJtIHsKKyAgICAvKioKKyAgICAgKiBUaGUgbnVtYmVyLgorICAgICAqCisgICAgICogQHNlcmlhbAorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgbnVtYmVyOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTY5NjM1NzEyNDAxNTQzMDI0ODRMOworCisgICAgcHJvdGVjdGVkIEludGVnZXJDb21wYXJpc29uVGVybShpbnQgY29tcGFyaXNvbiwgaW50IG51bWJlcikgeworCXRoaXMuY29tcGFyaXNvbiA9IGNvbXBhcmlzb247CisJdGhpcy5udW1iZXIgPSBudW1iZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBudW1iZXIgdG8gY29tcGFyZSB3aXRoLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgbnVtYmVyCisgICAgICovCisgICAgcHVibGljIGludCBnZXROdW1iZXIoKSB7CisJcmV0dXJuIG51bWJlcjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIHR5cGUgb2YgY29tcGFyaXNvbi4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIGNvbXBhcmlzb24gdHlwZQorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0Q29tcGFyaXNvbigpIHsKKwlyZXR1cm4gY29tcGFyaXNvbjsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBtYXRjaChpbnQgaSkgeworCXN3aXRjaCAoY29tcGFyaXNvbikgeworCSAgICBjYXNlIExFOiAKKwkJcmV0dXJuIGkgPD0gbnVtYmVyOworCSAgICBjYXNlIExUOgorCQlyZXR1cm4gaSA8IG51bWJlcjsKKwkgICAgY2FzZSBFUToKKwkJcmV0dXJuIGkgPT0gbnVtYmVyOworCSAgICBjYXNlIE5FOgorCQlyZXR1cm4gaSAhPSBudW1iZXI7CisJICAgIGNhc2UgR1Q6CisJCXJldHVybiBpID4gbnVtYmVyOworCSAgICBjYXNlIEdFOgorCQlyZXR1cm4gaSA+PSBudW1iZXI7CisJICAgIGRlZmF1bHQ6CisJCXJldHVybiBmYWxzZTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogRXF1YWxpdHkgY29tcGFyaXNvbi4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgeworCWlmICghKG9iaiBpbnN0YW5jZW9mIEludGVnZXJDb21wYXJpc29uVGVybSkpCisJICAgIHJldHVybiBmYWxzZTsKKwlJbnRlZ2VyQ29tcGFyaXNvblRlcm0gaWN0ID0gKEludGVnZXJDb21wYXJpc29uVGVybSlvYmo7CisJcmV0dXJuIGljdC5udW1iZXIgPT0gdGhpcy5udW1iZXIgJiYgc3VwZXIuZXF1YWxzKG9iaik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29tcHV0ZSBhIGhhc2hDb2RlIGZvciB0aGlzIG9iamVjdC4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworCXJldHVybiBudW1iZXIgKyBzdXBlci5oYXNoQ29kZSgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL3NlYXJjaC9NZXNzYWdlSURUZXJtLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9zZWFyY2gvTWVzc2FnZUlEVGVybS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY3NjJjMDQKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9zZWFyY2gvTWVzc2FnZUlEVGVybS5qYXZhCkBAIC0wLDAgKzEsODEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5zZWFyY2g7CisKK2ltcG9ydCBqYXZheC5tYWlsLk1lc3NhZ2U7CisKKy8qKgorICogVGhpcyB0ZXJtIG1vZGVscyB0aGUgUkZDODIyICJNZXNzYWdlSWQiIC0gYSBtZXNzYWdlLWlkIGZvciAKKyAqIEludGVybmV0IG1lc3NhZ2VzIHRoYXQgaXMgc3VwcG9zZWQgdG8gYmUgdW5pcXVlIHBlciBtZXNzYWdlLgorICogQ2xpZW50cyBjYW4gdXNlIHRoaXMgdGVybSB0byBzZWFyY2ggYSBmb2xkZXIgZm9yIGEgbWVzc2FnZSBnaXZlbgorICogaXRzIE1lc3NhZ2VJZC4gPHA+CisgKgorICogVGhlIE1lc3NhZ2VJZCBpcyByZXByZXNlbnRlZCBhcyBhIFN0cmluZy4KKyAqCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICogQGF1dGhvciBKb2huIE1hbmkKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIE1lc3NhZ2VJRFRlcm0gZXh0ZW5kcyBTdHJpbmdUZXJtIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0yMTIxMDk2Mjk2NDU0NjkxOTYzTDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZ2lkICB0aGUgbXNnaWQgdG8gc2VhcmNoIGZvcgorICAgICAqLworICAgIHB1YmxpYyBNZXNzYWdlSURUZXJtKFN0cmluZyBtc2dpZCkgeworCS8vIE5vdGU6IGNvbXBhcmlzb24gaXMgY2FzZS1pbnNlbnNpdGl2ZQorCXN1cGVyKG1zZ2lkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgbWF0Y2ggbWV0aG9kLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZwl0aGUgbWF0Y2ggaXMgYXBwbGllZCB0byB0aGlzIE1lc3NhZ2UncyAKKyAgICAgKgkJCU1lc3NhZ2UtSUQgaGVhZGVyCisgICAgICogQHJldHVybgkJdHJ1ZSBpZiB0aGUgbWF0Y2ggc3VjY2VlZHMsIG90aGVyd2lzZSBmYWxzZQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIG1hdGNoKE1lc3NhZ2UgbXNnKSB7CisJU3RyaW5nW10gczsKKworCXRyeSB7CisJICAgIHMgPSBtc2cuZ2V0SGVhZGVyKCJNZXNzYWdlLUlEIik7CisJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKwkgICAgcmV0dXJuIGZhbHNlOworCX0KKworCWlmIChzID09IG51bGwpCisJICAgIHJldHVybiBmYWxzZTsKKworCWZvciAoaW50IGk9MDsgaSA8IHMubGVuZ3RoOyBpKyspCisJICAgIGlmIChzdXBlci5tYXRjaChzW2ldKSkKKwkJcmV0dXJuIHRydWU7CisJcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVxdWFsaXR5IGNvbXBhcmlzb24uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKKwlpZiAoIShvYmogaW5zdGFuY2VvZiBNZXNzYWdlSURUZXJtKSkKKwkgICAgcmV0dXJuIGZhbHNlOworCXJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9zZWFyY2gvTWVzc2FnZU51bWJlclRlcm0uamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL3NlYXJjaC9NZXNzYWdlTnVtYmVyVGVybS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNlYzBmMjgKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9zZWFyY2gvTWVzc2FnZU51bWJlclRlcm0uamF2YQpAQCAtMCwwICsxLDY4IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGphdmF4Lm1haWwuc2VhcmNoOworCitpbXBvcnQgamF2YXgubWFpbC5NZXNzYWdlOworCisvKioKKyAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyBjb21wYXJpc29ucyBmb3IgTWVzc2FnZSBudW1iZXJzLgorICoKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKiBAYXV0aG9yIEpvaG4gTWFuaQorICovCitwdWJsaWMgZmluYWwgY2xhc3MgTWVzc2FnZU51bWJlclRlcm0gZXh0ZW5kcyBJbnRlZ2VyQ29tcGFyaXNvblRlcm0geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTUzNzk2MjU4Mjk2NTg2MjM4MTJMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbnVtYmVyICB0aGUgTWVzc2FnZSBudW1iZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgTWVzc2FnZU51bWJlclRlcm0oaW50IG51bWJlcikgeworCXN1cGVyKEVRLCBudW1iZXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBtYXRjaCBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbXNnCXRoZSBNZXNzYWdlIG51bWJlciBpcyBtYXRjaGVkIHdpdGggdGhpcyBNZXNzYWdlCisgICAgICogQHJldHVybgkJdHJ1ZSBpZiB0aGUgbWF0Y2ggc3VjY2VlZHMsIG90aGVyd2lzZSBmYWxzZQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIG1hdGNoKE1lc3NhZ2UgbXNnKSB7CisJaW50IG1zZ25vOworCisJdHJ5IHsKKwkgICAgbXNnbm8gPSBtc2cuZ2V0TWVzc2FnZU51bWJlcigpOworCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisJICAgIHJldHVybiBmYWxzZTsKKwl9CisJCisJcmV0dXJuIHN1cGVyLm1hdGNoKG1zZ25vKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFcXVhbGl0eSBjb21wYXJpc29uLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CisJaWYgKCEob2JqIGluc3RhbmNlb2YgTWVzc2FnZU51bWJlclRlcm0pKQorCSAgICByZXR1cm4gZmFsc2U7CisJcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL3NlYXJjaC9Ob3RUZXJtLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9zZWFyY2gvTm90VGVybS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI4N2MxNTEKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9zZWFyY2gvTm90VGVybS5qYXZhCkBAIC0wLDAgKzEsNzQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5zZWFyY2g7CisKK2ltcG9ydCBqYXZheC5tYWlsLk1lc3NhZ2U7CisKKy8qKgorICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIHRoZSBsb2dpY2FsIE5FR0FUSU9OIG9wZXJhdG9yLgorICoKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKiBAYXV0aG9yIEpvaG4gTWFuaQorICovCitwdWJsaWMgZmluYWwgY2xhc3MgTm90VGVybSBleHRlbmRzIFNlYXJjaFRlcm0geworICAgIC8qKgorICAgICAqIFRoZSBzZWFyY2ggdGVybSB0byBuZWdhdGUuCisgICAgICoKKyAgICAgKiBAc2VyaWFsCisgICAgICovCisgICAgcHJpdmF0ZSBTZWFyY2hUZXJtIHRlcm07CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA3MTUyMjkzMjE0MjE3MzEwMjE2TDsKKworICAgIHB1YmxpYyBOb3RUZXJtKFNlYXJjaFRlcm0gdCkgeworCXRlcm0gPSB0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgdGVybSB0byBuZWdhdGUuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBUZXJtCisgICAgICovCisgICAgcHVibGljIFNlYXJjaFRlcm0gZ2V0VGVybSgpIHsKKwlyZXR1cm4gdGVybTsKKyAgICB9CisKKyAgICAvKiBUaGUgTk9UIG9wZXJhdGlvbiAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIG1hdGNoKE1lc3NhZ2UgbXNnKSB7CisJcmV0dXJuICF0ZXJtLm1hdGNoKG1zZyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXF1YWxpdHkgY29tcGFyaXNvbi4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgeworCWlmICghKG9iaiBpbnN0YW5jZW9mIE5vdFRlcm0pKQorCSAgICByZXR1cm4gZmFsc2U7CisJTm90VGVybSBudCA9IChOb3RUZXJtKW9iajsKKwlyZXR1cm4gbnQudGVybS5lcXVhbHModGhpcy50ZXJtKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wdXRlIGEgaGFzaENvZGUgZm9yIHRoaXMgb2JqZWN0LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisJcmV0dXJuIHRlcm0uaGFzaENvZGUoKSA8PCAxOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL3NlYXJjaC9PclRlcm0uamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL3NlYXJjaC9PclRlcm0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZGY1OGY0Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvc2VhcmNoL09yVGVybS5qYXZhCkBAIC0wLDAgKzEsMTE2IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGphdmF4Lm1haWwuc2VhcmNoOworCitpbXBvcnQgamF2YXgubWFpbC5NZXNzYWdlOworCisvKioKKyAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyB0aGUgbG9naWNhbCBPUiBvcGVyYXRvciBvbiBpbmRpdmlkdWFsIFNlYXJjaFRlcm1zLgorICoKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKiBAYXV0aG9yIEpvaG4gTWFuaQorICovCitwdWJsaWMgZmluYWwgY2xhc3MgT3JUZXJtIGV4dGVuZHMgU2VhcmNoVGVybSB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgYXJyYXkgb2YgdGVybXMgb24gd2hpY2ggdGhlIE9SIG9wZXJhdG9yIHNob3VsZAorICAgICAqIGJlIGFwcGxpZWQuCisgICAgICoKKyAgICAgKiBAc2VyaWFsCisgICAgICovCisgICAgcHJpdmF0ZSBTZWFyY2hUZXJtW10gdGVybXM7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA1MzgwNTM0MDY3NTIzNjQ2OTM2TDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yIHRoYXQgdGFrZXMgdHdvIG9wZXJhbmRzLgorICAgICAqCisgICAgICogQHBhcmFtIHQxIGZpcnN0IHRlcm0KKyAgICAgKiBAcGFyYW0gdDIgc2Vjb25kIHRlcm0KKyAgICAgKi8KKyAgICBwdWJsaWMgT3JUZXJtKFNlYXJjaFRlcm0gdDEsIFNlYXJjaFRlcm0gdDIpIHsKKwl0ZXJtcyA9IG5ldyBTZWFyY2hUZXJtWzJdOworCXRlcm1zWzBdID0gdDE7CisJdGVybXNbMV0gPSB0MjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvciB0aGF0IHRha2VzIGFuIGFycmF5IG9mIFNlYXJjaFRlcm1zLgorICAgICAqCisgICAgICogQHBhcmFtIHQgYXJyYXkgb2Ygc2VhcmNoIHRlcm1zCisgICAgICovCisgICAgcHVibGljIE9yVGVybShTZWFyY2hUZXJtW10gdCkgeworCXRlcm1zID0gbmV3IFNlYXJjaFRlcm1bdC5sZW5ndGhdOworCWZvciAoaW50IGkgPSAwOyBpIDwgdC5sZW5ndGg7IGkrKykKKwkgICAgdGVybXNbaV0gPSB0W2ldOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgc2VhcmNoIHRlcm1zLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgc2VhcmNoIHRlcm1zCisgICAgICovCisgICAgcHVibGljIFNlYXJjaFRlcm1bXSBnZXRUZXJtcygpIHsKKwlyZXR1cm4gdGVybXMuY2xvbmUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgT1Igb3BlcmF0aW9uLiA8cD4KKyAgICAgKgorICAgICAqIFRoZSB0ZXJtcyBzcGVjaWZpZWQgaW4gdGhlIGNvbnN0cnVjdG9yIGFyZSBhcHBsaWVkIHRvCisgICAgICogdGhlIGdpdmVuIG9iamVjdCBhbmQgdGhlIE9SIG9wZXJhdG9yIGlzIGFwcGxpZWQgdG8gdGhlaXIgcmVzdWx0cy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtc2cJVGhlIHNwZWNpZmllZCBTZWFyY2hUZXJtcyBhcmUgYXBwbGllZCB0byB0aGlzIE1lc3NhZ2UKKyAgICAgKgkJCWFuZCB0aGUgT1Igb3BlcmF0b3IgaXMgYXBwbGllZCB0byB0aGVpciByZXN1bHRzLgorICAgICAqIEByZXR1cm4JCXRydWUgaWYgdGhlIE9SIHN1Y2NlZHMsIG90aGVyd2lzZSBmYWxzZQorICAgICAqLworCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gbWF0Y2goTWVzc2FnZSBtc2cpIHsKKwlmb3IgKGludCBpPTA7IGkgPCB0ZXJtcy5sZW5ndGg7IGkrKykKKwkgICAgaWYgKHRlcm1zW2ldLm1hdGNoKG1zZykpCisJCXJldHVybiB0cnVlOworCXJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFcXVhbGl0eSBjb21wYXJpc29uLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CisJaWYgKCEob2JqIGluc3RhbmNlb2YgT3JUZXJtKSkKKwkgICAgcmV0dXJuIGZhbHNlOworCU9yVGVybSBvdCA9IChPclRlcm0pb2JqOworCWlmIChvdC50ZXJtcy5sZW5ndGggIT0gdGVybXMubGVuZ3RoKQorCSAgICByZXR1cm4gZmFsc2U7CisJZm9yIChpbnQgaT0wOyBpIDwgdGVybXMubGVuZ3RoOyBpKyspCisJICAgIGlmICghdGVybXNbaV0uZXF1YWxzKG90LnRlcm1zW2ldKSkKKwkJcmV0dXJuIGZhbHNlOworCXJldHVybiB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXB1dGUgYSBoYXNoQ29kZSBmb3IgdGhpcyBvYmplY3QuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKwlpbnQgaGFzaCA9IDA7CisJZm9yIChpbnQgaT0wOyBpIDwgdGVybXMubGVuZ3RoOyBpKyspCisJICAgIGhhc2ggKz0gdGVybXNbaV0uaGFzaENvZGUoKTsKKwlyZXR1cm4gaGFzaDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9zZWFyY2gvUmVjZWl2ZWREYXRlVGVybS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvc2VhcmNoL1JlY2VpdmVkRGF0ZVRlcm0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iMTg5ZDAxCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvc2VhcmNoL1JlY2VpdmVkRGF0ZVRlcm0uamF2YQpAQCAtMCwwICsxLDc0IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGphdmF4Lm1haWwuc2VhcmNoOworCitpbXBvcnQgamF2YS51dGlsLkRhdGU7CitpbXBvcnQgamF2YXgubWFpbC5NZXNzYWdlOworCisvKioKKyAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyBjb21wYXJpc29ucyBmb3IgdGhlIE1lc3NhZ2UgUmVjZWl2ZWQgZGF0ZQorICoKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKiBAYXV0aG9yIEpvaG4gTWFuaQorICovCitwdWJsaWMgZmluYWwgY2xhc3MgUmVjZWl2ZWREYXRlVGVybSBleHRlbmRzIERhdGVUZXJtIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0yNzU2Njk1MjQ2MTk1NTAzMTcwTDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yLgorICAgICAqCisgICAgICogQHBhcmFtIGNvbXBhcmlzb24JdGhlIENvbXBhcmlzb24gdHlwZQorICAgICAqIEBwYXJhbSBkYXRlCQl0aGUgZGF0ZSB0byBiZSBjb21wYXJlZAorICAgICAqLworICAgIHB1YmxpYyBSZWNlaXZlZERhdGVUZXJtKGludCBjb21wYXJpc29uLCBEYXRlIGRhdGUpIHsKKwlzdXBlcihjb21wYXJpc29uLCBkYXRlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgbWF0Y2ggbWV0aG9kLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZwl0aGUgZGF0ZSBjb21wYXJhdG9yIGlzIGFwcGxpZWQgdG8gdGhpcyBNZXNzYWdlJ3MKKyAgICAgKgkJCXJlY2VpdmVkIGRhdGUKKyAgICAgKiBAcmV0dXJuCQl0cnVlIGlmIHRoZSBjb21wYXJpc29uIHN1Y2NlZWRzLCBvdGhlcndpc2UgZmFsc2UKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBtYXRjaChNZXNzYWdlIG1zZykgeworCURhdGUgZDsKKworCXRyeSB7CisJICAgIGQgPSBtc2cuZ2V0UmVjZWl2ZWREYXRlKCk7CisJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKwkgICAgcmV0dXJuIGZhbHNlOworCX0KKworCWlmIChkID09IG51bGwpCisJICAgIHJldHVybiBmYWxzZTsKKworCXJldHVybiBzdXBlci5tYXRjaChkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFcXVhbGl0eSBjb21wYXJpc29uLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CisJaWYgKCEob2JqIGluc3RhbmNlb2YgUmVjZWl2ZWREYXRlVGVybSkpCisJICAgIHJldHVybiBmYWxzZTsKKwlyZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvc2VhcmNoL1JlY2lwaWVudFN0cmluZ1Rlcm0uamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL3NlYXJjaC9SZWNpcGllbnRTdHJpbmdUZXJtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjA0NjZjZAotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL3NlYXJjaC9SZWNpcGllbnRTdHJpbmdUZXJtLmphdmEKQEAgLTAsMCArMSwxMDkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5zZWFyY2g7CisKK2ltcG9ydCBqYXZheC5tYWlsLk1lc3NhZ2U7CitpbXBvcnQgamF2YXgubWFpbC5BZGRyZXNzOworCisvKioKKyAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyBzdHJpbmcgY29tcGFyaXNvbnMgZm9yIHRoZSBSZWNpcGllbnQgQWRkcmVzcworICogaGVhZGVycy4gPHA+CisgKgorICogTm90ZSB0aGF0IHRoaXMgY2xhc3MgZGlmZmVycyBmcm9tIHRoZSA8Y29kZT5SZWNpcGllbnRUZXJtPC9jb2RlPiBjbGFzcworICogaW4gdGhhdCB0aGlzIGNsYXNzIGRvZXMgY29tcGFyaXNvbnMgb24gYWRkcmVzcyBzdHJpbmdzIHJhdGhlciB0aGFuIEFkZHJlc3MKKyAqIG9iamVjdHMuIFRoZSBzdHJpbmcgY29tcGFyaXNvbnMgYXJlIGNhc2UtaW5zZW5zaXRpdmUuCisgKgorICogQHNpbmNlICAgICAgIEphdmFNYWlsIDEuMQorICovCisKK3B1YmxpYyBmaW5hbCBjbGFzcyBSZWNpcGllbnRTdHJpbmdUZXJtIGV4dGVuZHMgQWRkcmVzc1N0cmluZ1Rlcm0geworCisgICAgLyoqCisgICAgICogVGhlIHJlY2lwaWVudCB0eXBlLgorICAgICAqCisgICAgICogQHNlcmlhbAorICAgICAqLworICAgIHByaXZhdGUgTWVzc2FnZS5SZWNpcGllbnRUeXBlIHR5cGU7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtODI5MzU2MjA4OTYxMTYxODg0OUw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3Rvci4KKyAgICAgKgorICAgICAqIEBwYXJhbSB0eXBlICAgICAgdGhlIHJlY2lwaWVudCB0eXBlCisgICAgICogQHBhcmFtIHBhdHRlcm4gICB0aGUgYWRkcmVzcyBwYXR0ZXJuIHRvIGJlIGNvbXBhcmVkLgorICAgICAqLworICAgIHB1YmxpYyBSZWNpcGllbnRTdHJpbmdUZXJtKE1lc3NhZ2UuUmVjaXBpZW50VHlwZSB0eXBlLCBTdHJpbmcgcGF0dGVybikgeworCXN1cGVyKHBhdHRlcm4pOworCXRoaXMudHlwZSA9IHR5cGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSB0eXBlIG9mIHJlY2lwaWVudCB0byBtYXRjaCB3aXRoLgorICAgICAqCisgICAgICogQHJldHVybgl0aGUgcmVjaXBpZW50IHR5cGUKKyAgICAgKi8KKyAgICBwdWJsaWMgTWVzc2FnZS5SZWNpcGllbnRUeXBlIGdldFJlY2lwaWVudFR5cGUoKSB7CisJcmV0dXJuIHR5cGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2sgd2hldGhlciB0aGUgYWRkcmVzcyBzcGVjaWZpZWQgaW4gdGhlIGNvbnN0cnVjdG9yIGlzCisgICAgICogYSBzdWJzdHJpbmcgb2YgdGhlIHJlY2lwaWVudCBhZGRyZXNzIG9mIHRoaXMgTWVzc2FnZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSAgIG1zZyAJVGhlIGNvbXBhcmlzb24gaXMgYXBwbGllZCB0byB0aGlzIE1lc3NhZ2UncyByZWNpcGllbnQKKyAgICAgKgkJICAgIAlhZGRyZXNzLgorICAgICAqIEByZXR1cm4gICAgICAgICAgdHJ1ZSBpZiB0aGUgbWF0Y2ggc3VjY2VlZHMsIG90aGVyd2lzZSBmYWxzZS4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBtYXRjaChNZXNzYWdlIG1zZykgeworCUFkZHJlc3NbXSByZWNpcGllbnRzOworCisJdHJ5IHsKKwkgICAgcmVjaXBpZW50cyA9IG1zZy5nZXRSZWNpcGllbnRzKHR5cGUpOworCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisJICAgIHJldHVybiBmYWxzZTsKKwl9CisKKwlpZiAocmVjaXBpZW50cyA9PSBudWxsKQorCSAgICByZXR1cm4gZmFsc2U7CisJCisJZm9yIChpbnQgaT0wOyBpIDwgcmVjaXBpZW50cy5sZW5ndGg7IGkrKykKKwkgICAgaWYgKHN1cGVyLm1hdGNoKHJlY2lwaWVudHNbaV0pKQorCQlyZXR1cm4gdHJ1ZTsKKwlyZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXF1YWxpdHkgY29tcGFyaXNvbi4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgeworCWlmICghKG9iaiBpbnN0YW5jZW9mIFJlY2lwaWVudFN0cmluZ1Rlcm0pKQorCSAgICByZXR1cm4gZmFsc2U7CisJUmVjaXBpZW50U3RyaW5nVGVybSByc3QgPSAoUmVjaXBpZW50U3RyaW5nVGVybSlvYmo7CisJcmV0dXJuIHJzdC50eXBlLmVxdWFscyh0aGlzLnR5cGUpICYmIHN1cGVyLmVxdWFscyhvYmopOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXB1dGUgYSBoYXNoQ29kZSBmb3IgdGhpcyBvYmplY3QuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKwlyZXR1cm4gdHlwZS5oYXNoQ29kZSgpICsgc3VwZXIuaGFzaENvZGUoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9zZWFyY2gvUmVjaXBpZW50VGVybS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvc2VhcmNoL1JlY2lwaWVudFRlcm0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZjJkMTQ5Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvc2VhcmNoL1JlY2lwaWVudFRlcm0uamF2YQpAQCAtMCwwICsxLDEwMyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsLnNlYXJjaDsKKworaW1wb3J0IGphdmF4Lm1haWwuTWVzc2FnZTsKK2ltcG9ydCBqYXZheC5tYWlsLkFkZHJlc3M7CisKKy8qKgorICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIGNvbXBhcmlzb25zIGZvciB0aGUgUmVjaXBpZW50IEFkZHJlc3MgaGVhZGVycy4KKyAqCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICogQGF1dGhvciBKb2huIE1hbmkKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFJlY2lwaWVudFRlcm0gZXh0ZW5kcyBBZGRyZXNzVGVybSB7CisKKyAgICAvKioKKyAgICAgKiBUaGUgcmVjaXBpZW50IHR5cGUuCisgICAgICoKKyAgICAgKiBAc2VyaWFsCisgICAgICovCisgICAgcHJpdmF0ZSBNZXNzYWdlLlJlY2lwaWVudFR5cGUgdHlwZTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDY1NDg3MDA2NTMxMjI2ODA0NjhMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdHlwZQl0aGUgcmVjaXBpZW50IHR5cGUKKyAgICAgKiBAcGFyYW0gYWRkcmVzcwl0aGUgYWRkcmVzcyB0byBtYXRjaCBmb3IKKyAgICAgKi8KKyAgICBwdWJsaWMgUmVjaXBpZW50VGVybShNZXNzYWdlLlJlY2lwaWVudFR5cGUgdHlwZSwgQWRkcmVzcyBhZGRyZXNzKSB7CisJc3VwZXIoYWRkcmVzcyk7CisJdGhpcy50eXBlID0gdHlwZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIHR5cGUgb2YgcmVjaXBpZW50IHRvIG1hdGNoIHdpdGguCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSByZWNpcGllbnQgdHlwZQorICAgICAqLworICAgIHB1YmxpYyBNZXNzYWdlLlJlY2lwaWVudFR5cGUgZ2V0UmVjaXBpZW50VHlwZSgpIHsKKwlyZXR1cm4gdHlwZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgbWF0Y2ggbWV0aG9kLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZwlUaGUgYWRkcmVzcyBtYXRjaCBpcyBhcHBsaWVkIHRvIHRoaXMgTWVzc2FnZSdzIHJlY2VwaWVudAorICAgICAqCQkJYWRkcmVzcworICAgICAqIEByZXR1cm4JCXRydWUgaWYgdGhlIG1hdGNoIHN1Y2NlZWRzLCBvdGhlcndpc2UgZmFsc2UKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBtYXRjaChNZXNzYWdlIG1zZykgeworCUFkZHJlc3NbXSByZWNpcGllbnRzOworCisJdHJ5IHsKKyAJICAgIHJlY2lwaWVudHMgPSBtc2cuZ2V0UmVjaXBpZW50cyh0eXBlKTsKKwl9IGNhdGNoIChFeGNlcHRpb24gZSkgeworCSAgICByZXR1cm4gZmFsc2U7CisJfQorCisJaWYgKHJlY2lwaWVudHMgPT0gbnVsbCkKKwkgICAgcmV0dXJuIGZhbHNlOworCisJZm9yIChpbnQgaT0wOyBpIDwgcmVjaXBpZW50cy5sZW5ndGg7IGkrKykKKwkgICAgaWYgKHN1cGVyLm1hdGNoKHJlY2lwaWVudHNbaV0pKQorCQlyZXR1cm4gdHJ1ZTsKKwlyZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXF1YWxpdHkgY29tcGFyaXNvbi4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgeworCWlmICghKG9iaiBpbnN0YW5jZW9mIFJlY2lwaWVudFRlcm0pKQorCSAgICByZXR1cm4gZmFsc2U7CisJUmVjaXBpZW50VGVybSBydCA9IChSZWNpcGllbnRUZXJtKW9iajsKKwlyZXR1cm4gcnQudHlwZS5lcXVhbHModGhpcy50eXBlKSAmJiBzdXBlci5lcXVhbHMob2JqKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wdXRlIGEgaGFzaENvZGUgZm9yIHRoaXMgb2JqZWN0LgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisJcmV0dXJuIHR5cGUuaGFzaENvZGUoKSArIHN1cGVyLmhhc2hDb2RlKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvc2VhcmNoL1NlYXJjaEV4Y2VwdGlvbi5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvc2VhcmNoL1NlYXJjaEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVjNGQ0NjAKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9zZWFyY2gvU2VhcmNoRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0NiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsLnNlYXJjaDsKKworaW1wb3J0IGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uOworCisKKy8qKgorICogVGhlIGV4Y2VwdGlvbiB0aHJvd24gd2hlbiBhIFNlYXJjaCBleHByZXNzaW9uIGNvdWxkIG5vdCBiZSBoYW5kbGVkLgorICoKKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKi8KKworcHVibGljIGNsYXNzIFNlYXJjaEV4Y2VwdGlvbiBleHRlbmRzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNzA5Mjg4Njc3ODIyNjI2ODY4Nkw7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEgU2VhcmNoRXhjZXB0aW9uIHdpdGggbm8gZGV0YWlsIG1lc3NhZ2UuCisgICAgICovCisgICAgcHVibGljIFNlYXJjaEV4Y2VwdGlvbigpIHsKKwlzdXBlcigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBTZWFyY2hFeGNlcHRpb24gd2l0aCB0aGUgc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlLgorICAgICAqIEBwYXJhbSBzCQl0aGUgZGV0YWlsIG1lc3NhZ2UKKyAgICAgKi8KKyAgICBwdWJsaWMgU2VhcmNoRXhjZXB0aW9uKFN0cmluZyBzKSB7CisJc3VwZXIocyk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvc2VhcmNoL1NlYXJjaFRlcm0uamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL3NlYXJjaC9TZWFyY2hUZXJtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzE5NGI2MwotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL3NlYXJjaC9TZWFyY2hUZXJtLmphdmEKQEAgLTAsMCArMSw1NCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsLnNlYXJjaDsKKworaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOworCitpbXBvcnQgamF2YXgubWFpbC5NZXNzYWdlOworCisvKioKKyAqIFNlYXJjaCBjcml0ZXJpYSBhcmUgZXhwcmVzc2VkIGFzIGEgdHJlZSBvZiBzZWFyY2gtdGVybXMsIGZvcm1pbmcKKyAqIGEgcGFyc2UtdHJlZSBmb3IgdGhlIHNlYXJjaCBleHByZXNzaW9uLiA8cD4KKyAqCisgKiBTZWFyY2gtdGVybXMgYXJlIHJlcHJlc2VudGVkIGJ5IHRoaXMgY2xhc3MuIFRoaXMgaXMgYW4gYWJzdHJhY3QKKyAqIGNsYXNzOyBzdWJjbGFzc2VzIGltcGxlbWVudCBzcGVjaWZpYyBtYXRjaCBtZXRob2RzLiA8cD4KKyAqCisgKiBTZWFyY2ggdGVybXMgYXJlIHNlcmlhbGl6YWJsZSwgd2hpY2ggYWxsb3dzIHN0b3JpbmcgYSBzZWFyY2ggdGVybQorICogYmV0d2VlbiBzZXNzaW9ucy4KKyAqCisgKiA8c3Ryb25nPldhcm5pbmc6PC9zdHJvbmc+CisgKiBTZXJpYWxpemVkIG9iamVjdHMgb2YgdGhpcyBjbGFzcyBtYXkgbm90IGJlIGNvbXBhdGlibGUgd2l0aCBmdXR1cmUKKyAqIEphdmFNYWlsIEFQSSByZWxlYXNlcy4gIFRoZSBjdXJyZW50IHNlcmlhbGl6YXRpb24gc3VwcG9ydCBpcworICogYXBwcm9wcmlhdGUgZm9yIHNob3J0IHRlcm0gc3RvcmFnZS4gPHA+CisgKgorICogQGF1dGhvciBCaWxsIFNoYW5ub24KKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBTZWFyY2hUZXJtIGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC02NjUyMzU4NDUyMjA1OTkyNzg5TDsKKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIGFwcGxpZXMgYSBzcGVjaWZpYyBtYXRjaCBjcml0ZXJpb24gdG8gdGhlIGdpdmVuCisgICAgICogbWVzc2FnZSBhbmQgcmV0dXJucyB0aGUgcmVzdWx0LgorICAgICAqCisgICAgICogQHBhcmFtIG1zZwlUaGUgbWF0Y2ggY3JpdGVyaW9uIGlzIGFwcGxpZWQgb24gdGhpcyBtZXNzYWdlCisgICAgICogQHJldHVybgkJdHJ1ZSwgaXQgdGhlIG1hdGNoIHN1Y2NlZWRzLCBmYWxzZSBpZiB0aGUgbWF0Y2ggZmFpbHMKKyAgICAgKi8KKworICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIG1hdGNoKE1lc3NhZ2UgbXNnKTsKK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL3NlYXJjaC9TZW50RGF0ZVRlcm0uamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL3NlYXJjaC9TZW50RGF0ZVRlcm0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYmQyZmNiCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvc2VhcmNoL1NlbnREYXRlVGVybS5qYXZhCkBAIC0wLDAgKzEsNzQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5zZWFyY2g7CisKK2ltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKK2ltcG9ydCBqYXZheC5tYWlsLk1lc3NhZ2U7CisKKy8qKgorICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIGNvbXBhcmlzb25zIGZvciB0aGUgTWVzc2FnZSBTZW50RGF0ZS4KKyAqCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICogQGF1dGhvciBKb2huIE1hbmkKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFNlbnREYXRlVGVybSBleHRlbmRzIERhdGVUZXJtIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDU2NDc3NTUwMzA1MzA5MDcyNjNMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29tcGFyaXNvbgl0aGUgQ29tcGFyaXNvbiB0eXBlCisgICAgICogQHBhcmFtIGRhdGUJCXRoZSBkYXRlIHRvIGJlIGNvbXBhcmVkCisgICAgICovCisgICAgcHVibGljIFNlbnREYXRlVGVybShpbnQgY29tcGFyaXNvbiwgRGF0ZSBkYXRlKSB7CisJc3VwZXIoY29tcGFyaXNvbiwgZGF0ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIG1hdGNoIG1ldGhvZC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBtc2cJdGhlIGRhdGUgY29tcGFyYXRvciBpcyBhcHBsaWVkIHRvIHRoaXMgTWVzc2FnZSdzCisgICAgICoJCQlzZW50IGRhdGUKKyAgICAgKiBAcmV0dXJuCQl0cnVlIGlmIHRoZSBjb21wYXJpc29uIHN1Y2NlZWRzLCBvdGhlcndpc2UgZmFsc2UKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBtYXRjaChNZXNzYWdlIG1zZykgeworCURhdGUgZDsKKworCXRyeSB7CisJICAgIGQgPSBtc2cuZ2V0U2VudERhdGUoKTsKKwl9IGNhdGNoIChFeGNlcHRpb24gZSkgeworCSAgICByZXR1cm4gZmFsc2U7CisJfQorCisJaWYgKGQgPT0gbnVsbCkKKwkgICAgcmV0dXJuIGZhbHNlOworCisJcmV0dXJuIHN1cGVyLm1hdGNoKGQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVxdWFsaXR5IGNvbXBhcmlzb24uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKKwlpZiAoIShvYmogaW5zdGFuY2VvZiBTZW50RGF0ZVRlcm0pKQorCSAgICByZXR1cm4gZmFsc2U7CisJcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL3NlYXJjaC9TaXplVGVybS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvc2VhcmNoL1NpemVUZXJtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTk0MDE3NgotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL3NlYXJjaC9TaXplVGVybS5qYXZhCkBAIC0wLDAgKzEsNzIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5zZWFyY2g7CisKK2ltcG9ydCBqYXZheC5tYWlsLk1lc3NhZ2U7CisKKy8qKgorICogVGhpcyBjbGFzcyBpbXBsZW1lbnRzIGNvbXBhcmlzb25zIGZvciBNZXNzYWdlIHNpemVzLgorICoKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKiBAYXV0aG9yIEpvaG4gTWFuaQorICovCitwdWJsaWMgZmluYWwgY2xhc3MgU2l6ZVRlcm0gZXh0ZW5kcyBJbnRlZ2VyQ29tcGFyaXNvblRlcm0geworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTI1NTYyMTk0NTEwMDUxMDM3MDlMOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IuCisgICAgICoKKyAgICAgKiBAcGFyYW0gY29tcGFyaXNvbgl0aGUgQ29tcGFyaXNvbiB0eXBlCisgICAgICogQHBhcmFtIHNpemUJCXRoZSBzaXplCisgICAgICovCisgICAgcHVibGljIFNpemVUZXJtKGludCBjb21wYXJpc29uLCBpbnQgc2l6ZSkgeworCXN1cGVyKGNvbXBhcmlzb24sIHNpemUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBtYXRjaCBtZXRob2QuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbXNnCXRoZSBzaXplIGNvbXBhcmF0b3IgaXMgYXBwbGllZCB0byB0aGlzIE1lc3NhZ2UncyBzaXplCisgICAgICogQHJldHVybgkJdHJ1ZSBpZiB0aGUgc2l6ZSBpcyBlcXVhbCwgb3RoZXJ3aXNlIGZhbHNlIAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIG1hdGNoKE1lc3NhZ2UgbXNnKSB7CisJaW50IHNpemU7CisKKwl0cnkgeworCSAgICBzaXplID0gbXNnLmdldFNpemUoKTsKKwl9IGNhdGNoIChFeGNlcHRpb24gZSkgeworCSAgICByZXR1cm4gZmFsc2U7CisJfQorCisJaWYgKHNpemUgPT0gLTEpCisJICAgIHJldHVybiBmYWxzZTsKKworCXJldHVybiBzdXBlci5tYXRjaChzaXplKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFcXVhbGl0eSBjb21wYXJpc29uLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CisJaWYgKCEob2JqIGluc3RhbmNlb2YgU2l6ZVRlcm0pKQorCSAgICByZXR1cm4gZmFsc2U7CisJcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL3NlYXJjaC9TdHJpbmdUZXJtLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9zZWFyY2gvU3RyaW5nVGVybS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUxZWRmYWUKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9zZWFyY2gvU3RyaW5nVGVybS5qYXZhCkBAIC0wLDAgKzEsMTE3IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGphdmF4Lm1haWwuc2VhcmNoOworCisvKioKKyAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyB0aGUgbWF0Y2ggbWV0aG9kIGZvciBTdHJpbmdzLiBUaGUgY3VycmVudAorICogaW1wbGVtZW50YXRpb24gcHJvdmlkZXMgb25seSBmb3Igc3Vic3RyaW5nIG1hdGNoaW5nLiBXZQorICogY291bGQgYWRkIGNvbXBhcmlzb25zIChsaWtlIHN0cmNtcCAuLi4pLgorICoKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKiBAYXV0aG9yIEpvaG4gTWFuaQorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgU3RyaW5nVGVybSBleHRlbmRzIFNlYXJjaFRlcm0geworICAgIC8qKgorICAgICAqIFRoZSBwYXR0ZXJuLgorICAgICAqCisgICAgICogQHNlcmlhbAorICAgICAqLworICAgIHByb3RlY3RlZCBTdHJpbmcgcGF0dGVybjsKKworICAgIC8qKgorICAgICAqIElnbm9yZSBjYXNlIHdoZW4gY29tcGFyaW5nPworICAgICAqCisgICAgICogQHNlcmlhbAorICAgICAqLworICAgIHByb3RlY3RlZCBib29sZWFuIGlnbm9yZUNhc2U7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxMjc0MDQyMTI5MDA3Njk2MjY5TDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCBhIFN0cmluZ1Rlcm0gd2l0aCB0aGUgZ2l2ZW4gcGF0dGVybi4KKyAgICAgKiBDYXNlIHdpbGwgYmUgaWdub3JlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbQlwYXR0ZXJuCQl0aGUgcGF0dGVybgorICAgICAqLworICAgIHByb3RlY3RlZCBTdHJpbmdUZXJtKFN0cmluZyBwYXR0ZXJuKSB7CisJdGhpcy5wYXR0ZXJuID0gcGF0dGVybjsKKwlpZ25vcmVDYXNlID0gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYSBTdHJpbmdUZXJtIHdpdGggdGhlIGdpdmVuIHBhdHRlcm4gYW5kIGlnbm9yZUNhc2UgZmxhZy4KKyAgICAgKgorICAgICAqIEBwYXJhbQlwYXR0ZXJuCQl0aGUgcGF0dGVybgorICAgICAqIEBwYXJhbQlpZ25vcmVDYXNlCXNob3VsZCB3ZSBpZ25vcmUgY2FzZT8KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU3RyaW5nVGVybShTdHJpbmcgcGF0dGVybiwgYm9vbGVhbiBpZ25vcmVDYXNlKSB7CisJdGhpcy5wYXR0ZXJuID0gcGF0dGVybjsKKwl0aGlzLmlnbm9yZUNhc2UgPSBpZ25vcmVDYXNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgc3RyaW5nIHRvIG1hdGNoIHdpdGguCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBzdHJpbmcgdG8gbWF0Y2gKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFBhdHRlcm4oKSB7CisJcmV0dXJuIHBhdHRlcm47CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRydWUgaWYgd2Ugc2hvdWxkIGlnbm9yZSBjYXNlIHdoZW4gbWF0Y2hpbmcuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRydWUgaWYgd2Ugc2hvdWxkIGlnbm9yZSBjYXNlCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZ2V0SWdub3JlQ2FzZSgpIHsKKwlyZXR1cm4gaWdub3JlQ2FzZTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBtYXRjaChTdHJpbmcgcykgeworCWludCBsZW4gPSBzLmxlbmd0aCgpIC0gcGF0dGVybi5sZW5ndGgoKTsKKwlmb3IgKGludCBpPTA7IGkgPD0gbGVuOyBpKyspIHsKKwkgICAgaWYgKHMucmVnaW9uTWF0Y2hlcyhpZ25vcmVDYXNlLCBpLCAKKwkJCQlwYXR0ZXJuLCAwLCBwYXR0ZXJuLmxlbmd0aCgpKSkKKwkJcmV0dXJuIHRydWU7CisJfQorCXJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFcXVhbGl0eSBjb21wYXJpc29uLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CisJaWYgKCEob2JqIGluc3RhbmNlb2YgU3RyaW5nVGVybSkpCisJICAgIHJldHVybiBmYWxzZTsKKwlTdHJpbmdUZXJtIHN0ID0gKFN0cmluZ1Rlcm0pb2JqOworCWlmIChpZ25vcmVDYXNlKQorCSAgICByZXR1cm4gc3QucGF0dGVybi5lcXVhbHNJZ25vcmVDYXNlKHRoaXMucGF0dGVybikgJiYKKwkJICAgIHN0Lmlnbm9yZUNhc2UgPT0gdGhpcy5pZ25vcmVDYXNlOworCWVsc2UKKwkgICAgcmV0dXJuIHN0LnBhdHRlcm4uZXF1YWxzKHRoaXMucGF0dGVybikgJiYKKwkJICAgIHN0Lmlnbm9yZUNhc2UgPT0gdGhpcy5pZ25vcmVDYXNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXB1dGUgYSBoYXNoQ29kZSBmb3IgdGhpcyBvYmplY3QuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKwlyZXR1cm4gaWdub3JlQ2FzZSA/IHBhdHRlcm4uaGFzaENvZGUoKSA6IH5wYXR0ZXJuLmhhc2hDb2RlKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvc2VhcmNoL1N1YmplY3RUZXJtLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9zZWFyY2gvU3ViamVjdFRlcm0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zMzI2MTgwCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvc2VhcmNoL1N1YmplY3RUZXJtLmphdmEKQEAgLTAsMCArMSw3NSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsLnNlYXJjaDsKKworaW1wb3J0IGphdmF4Lm1haWwuTWVzc2FnZTsKKworLyoqCisgKiBUaGlzIGNsYXNzIGltcGxlbWVudHMgY29tcGFyaXNvbnMgZm9yIHRoZSBtZXNzYWdlIFN1YmplY3QgaGVhZGVyLgorICogVGhlIGNvbXBhcmlzb24gaXMgY2FzZS1pbnNlbnNpdGl2ZS4gIFRoZSBwYXR0ZXJuIGlzIGEgc2ltcGxlIHN0cmluZworICogdGhhdCBtdXN0IGFwcGVhciBhcyBhIHN1YnN0cmluZyBpbiB0aGUgU3ViamVjdC4KKyAqCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICogQGF1dGhvciBKb2huIE1hbmkKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFN1YmplY3RUZXJtIGV4dGVuZHMgU3RyaW5nVGVybSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA3NDgxNTY4NjE4MDU1NTczNDMyTDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yLgorICAgICAqCisgICAgICogQHBhcmFtIHBhdHRlcm4gIHRoZSBwYXR0ZXJuIHRvIHNlYXJjaCBmb3IKKyAgICAgKi8KKyAgICBwdWJsaWMgU3ViamVjdFRlcm0oU3RyaW5nIHBhdHRlcm4pIHsKKwkvLyBOb3RlOiBjb21wYXJpc29uIGlzIGNhc2UtaW5zZW5zaXRpdmUKKwlzdXBlcihwYXR0ZXJuKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgbWF0Y2ggbWV0aG9kLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZwl0aGUgcGF0dGVybiBtYXRjaCBpcyBhcHBsaWVkIHRvIHRoaXMgTWVzc2FnZSdzIAorICAgICAqCQkJc3ViamVjdCBoZWFkZXIKKyAgICAgKiBAcmV0dXJuCQl0cnVlIGlmIHRoZSBwYXR0ZXJuIG1hdGNoIHN1Y2NlZWRzLCBvdGhlcndpc2UgZmFsc2UKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBtYXRjaChNZXNzYWdlIG1zZykgeworCVN0cmluZyBzdWJqOworCisJdHJ5IHsKKwkgICAgc3ViaiA9IG1zZy5nZXRTdWJqZWN0KCk7CisJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKwkgICAgcmV0dXJuIGZhbHNlOworCX0KKworCWlmIChzdWJqID09IG51bGwpCisJICAgIHJldHVybiBmYWxzZTsKKworCXJldHVybiBzdXBlci5tYXRjaChzdWJqKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFcXVhbGl0eSBjb21wYXJpc29uLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CisJaWYgKCEob2JqIGluc3RhbmNlb2YgU3ViamVjdFRlcm0pKQorCSAgICByZXR1cm4gZmFsc2U7CisJcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL3NlYXJjaC9wYWNrYWdlLmh0bWwgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9zZWFyY2gvcGFja2FnZS5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZiYWIzMTUKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC9zZWFyY2gvcGFja2FnZS5odG1sCkBAIC0wLDAgKzEsNDkgQEAKKzwhRE9DVFlQRSBodG1sIFBVQkxJQyAiLS8vVzNDLy9EVEQgSFRNTCA0LjAxIFRyYW5zaXRpb25hbC8vRU4iPgorPEhUTUw+Cis8SEVBRD4KKzxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PXV0Zi04Ij4KKzwhLS0KKworICAgIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorCisgICAgVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgICAgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisKKyAgICBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgICAgTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICAgIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICAgIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorCisgICAgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisKKy0tPgorCis8VElUTEU+amF2YXgubWFpbC5zZWFyY2ggcGFja2FnZTwvVElUTEU+Cis8L0hFQUQ+Cis8Qk9EWSBCR0NPTE9SPSJ3aGl0ZSI+CisKKzxQPgorTWVzc2FnZSBzZWFyY2ggdGVybXMgZm9yIHRoZSBKYXZhTWFpbCBBUEkuCitUaGlzIHBhY2thZ2UgZGVmaW5lcyBjbGFzc2VzIHRoYXQgY2FuIGJlIHVzZWQgdG8gY29uc3RydWN0IGEgc2VhcmNoCitleHByZXNzaW9uIHRvIHNlYXJjaCBhIGZvbGRlciBmb3IgbWVzc2FnZXMgbWF0Y2hpbmcgdGhlIGV4cHJlc3Npb247CitzZWUgdGhlIHtAbGluayBqYXZheC5tYWlsLkZvbGRlciNzZWFyY2ggc2VhcmNofSBtZXRob2Qgb24KK3tAbGluayBqYXZheC5tYWlsLkZvbGRlciBqYXZheC5tYWlsLkZvbGRlcn0uCitTZWUge0BsaW5rIGphdmF4Lm1haWwuc2VhcmNoLlNlYXJjaFRlcm0gU2VhcmNoVGVybX0uCis8L1A+Cis8UD4KK05vdGUgdGhhdCB0aGUgZXhhY3Qgc2VhcmNoIGNhcGFiaWxpdGllcyBkZXBlbmQgb24gdGhlIHByb3RvY29sLAorcHJvdmlkZXIsIGFuZCBzZXJ2ZXIgaW4gdXNlLiAgRm9yIHRoZSBQT1AzIHByb3RvY29sLCBhbGwgc2VhcmNoaW5nIGlzCitkb25lIG9uIHRoZSBjbGllbnQgc2lkZSB1c2luZyB0aGUgSmF2YU1haWwgY2xhc3Nlcy4gIEZvciBJTUFQLCBhbGwKK3NlYXJjaGluZyBpcyBkb25lIG9uIHRoZSBzZXJ2ZXIgc2lkZSBhbmQgaXMgbGltaXRlZCBieSB0aGUgc2VhcmNoCitjYXBhYmlsaXRpZXMgb2YgdGhlIElNQVAgcHJvdG9jb2wgYW5kIHRoZSBJTUFQIHNlcnZlciBiZWluZyB1c2VkLgorRm9yIGV4YW1wbGUsIElNQVAgZGF0ZSBiYXNlZCBzZWFyY2hlcyBoYXZlIG9ubHkgZGF5IGdyYW51bGFyaXR5LgorPC9QPgorPFA+CitJbiBnZW5lcmFsLCBhbGwgb2YgdGhlIHN0cmluZyBwYXR0ZXJucyBzdXBwb3J0ZWQgYnkgc2VhcmNoIHRlcm1zIGFyZQoranVzdCBzaW1wbGUgc3RyaW5nczsgbm8gcmVndWxhciBleHByZXNzaW9ucyBhcmUgc3VwcG9ydGVkLgorPC9QPgorCis8L0JPRFk+Cis8L0hUTUw+CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC91dGlsL0J5dGVBcnJheURhdGFTb3VyY2UuamF2YSBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL3V0aWwvQnl0ZUFycmF5RGF0YVNvdXJjZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU0YjllNWIKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC91dGlsL0J5dGVBcnJheURhdGFTb3VyY2UuamF2YQpAQCAtMCwwICsxLDE4MCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsLnV0aWw7CisKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YXguYWN0aXZhdGlvbi4qOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuKjsKKworLyoqCisgKiBBIERhdGFTb3VyY2UgYmFja2VkIGJ5IGEgYnl0ZSBhcnJheS4gIFRoZSBieXRlIGFycmF5IG1heSBiZQorICogcGFzc2VkIGluIGRpcmVjdGx5LCBvciBtYXkgYmUgaW5pdGlhbGl6ZWQgZnJvbSBhbiBJbnB1dFN0cmVhbQorICogb3IgYSBTdHJpbmcuCisgKgorICogQHNpbmNlIEphdmFNYWlsIDEuNAorICogQGF1dGhvciBKb2huIE1hbmkKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKiBAYXV0aG9yIE1heCBTcGl2YWsKKyAqLworcHVibGljIGNsYXNzIEJ5dGVBcnJheURhdGFTb3VyY2UgaW1wbGVtZW50cyBEYXRhU291cmNlIHsKKyAgICBwcml2YXRlIGJ5dGVbXSBkYXRhOwkvLyBkYXRhCisgICAgcHJpdmF0ZSBpbnQgbGVuID0gLTE7CisgICAgcHJpdmF0ZSBTdHJpbmcgdHlwZTsJLy8gY29udGVudC10eXBlCisgICAgcHJpdmF0ZSBTdHJpbmcgbmFtZSA9ICIiOworCisgICAgc3RhdGljIGNsYXNzIERTQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGV4dGVuZHMgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIHsKKwlwdWJsaWMgYnl0ZVtdIGdldEJ1ZigpIHsKKwkgICAgcmV0dXJuIGJ1ZjsKKwl9CisKKwlwdWJsaWMgaW50IGdldENvdW50KCkgeworCSAgICByZXR1cm4gY291bnQ7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIEJ5dGVBcnJheURhdGFTb3VyY2Ugd2l0aCBkYXRhIGZyb20gdGhlCisgICAgICogc3BlY2lmaWVkIElucHV0U3RyZWFtIGFuZCB3aXRoIHRoZSBzcGVjaWZpZWQgTUlNRSB0eXBlLgorICAgICAqIFRoZSBJbnB1dFN0cmVhbSBpcyByZWFkIGNvbXBsZXRlbHkgYW5kIHRoZSBkYXRhIGlzCisgICAgICogc3RvcmVkIGluIGEgYnl0ZSBhcnJheS4KKyAgICAgKgorICAgICAqIEBwYXJhbQlpcwl0aGUgSW5wdXRTdHJlYW0KKyAgICAgKiBAcGFyYW0JdHlwZQl0aGUgTUlNRSB0eXBlCisgICAgICogQGV4Y2VwdGlvbglJT0V4Y2VwdGlvbgllcnJvcnMgcmVhZGluZyB0aGUgc3RyZWFtCisgICAgICovCisgICAgcHVibGljIEJ5dGVBcnJheURhdGFTb3VyY2UoSW5wdXRTdHJlYW0gaXMsIFN0cmluZyB0eXBlKSB0aHJvd3MgSU9FeGNlcHRpb24geworCURTQnl0ZUFycmF5T3V0cHV0U3RyZWFtIG9zID0gbmV3IERTQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisJYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlWzgxOTJdOworCWludCBsZW47CisJd2hpbGUgKChsZW4gPSBpcy5yZWFkKGJ1ZikpID4gMCkKKwkgICAgb3Mud3JpdGUoYnVmLCAwLCBsZW4pOworCXRoaXMuZGF0YSA9IG9zLmdldEJ1ZigpOworCXRoaXMubGVuID0gb3MuZ2V0Q291bnQoKTsKKworCS8qCisJICogQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGRvdWJsZXMgdGhlIHNpemUgb2YgdGhlIGJ1ZmZlciBldmVyeSB0aW1lCisJICogaXQgbmVlZHMgdG8gZXhwYW5kLCB3aGljaCBjYW4gd2FzdGUgYSBsb3Qgb2YgbWVtb3J5IGluIHRoZSB3b3JzdAorCSAqIGNhc2Ugd2l0aCBsYXJnZSBidWZmZXJzLiAgQ2hlY2sgaG93IG11Y2ggaXMgd2FzdGVkIGhlcmUgYW5kIGlmCisJICogaXQncyB0b28gbXVjaCwgY29weSB0aGUgZGF0YSBpbnRvIGEgbmV3IGJ1ZmZlciBhbmQgYWxsb3cgdGhlCisJICogb2xkIGJ1ZmZlciB0byBiZSBnYXJiYWdlIGNvbGxlY3RlZC4KKwkgKi8KKwlpZiAodGhpcy5kYXRhLmxlbmd0aCAtIHRoaXMubGVuID4gMjU2KjEwMjQpIHsKKwkgICAgdGhpcy5kYXRhID0gb3MudG9CeXRlQXJyYXkoKTsKKwkgICAgdGhpcy5sZW4gPSB0aGlzLmRhdGEubGVuZ3RoOwkvLyBzaG91bGQgYmUgdGhlIHNhbWUKKwl9CisgICAgICAgIHRoaXMudHlwZSA9IHR5cGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgQnl0ZUFycmF5RGF0YVNvdXJjZSB3aXRoIGRhdGEgZnJvbSB0aGUKKyAgICAgKiBzcGVjaWZpZWQgYnl0ZSBhcnJheSBhbmQgd2l0aCB0aGUgc3BlY2lmaWVkIE1JTUUgdHlwZS4KKyAgICAgKgorICAgICAqIEBwYXJhbQlkYXRhCXRoZSBkYXRhCisgICAgICogQHBhcmFtCXR5cGUJdGhlIE1JTUUgdHlwZQorICAgICAqLworICAgIHB1YmxpYyBCeXRlQXJyYXlEYXRhU291cmNlKGJ5dGVbXSBkYXRhLCBTdHJpbmcgdHlwZSkgeworICAgICAgICB0aGlzLmRhdGEgPSBkYXRhOworCXRoaXMudHlwZSA9IHR5cGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgQnl0ZUFycmF5RGF0YVNvdXJjZSB3aXRoIGRhdGEgZnJvbSB0aGUKKyAgICAgKiBzcGVjaWZpZWQgU3RyaW5nIGFuZCB3aXRoIHRoZSBzcGVjaWZpZWQgTUlNRSB0eXBlLgorICAgICAqIFRoZSBNSU1FIHR5cGUgc2hvdWxkIGluY2x1ZGUgYSA8Y29kZT5jaGFyc2V0PC9jb2RlPgorICAgICAqIHBhcmFtZXRlciBzcGVjaWZ5aW5nIHRoZSBjaGFyc2V0IHRvIGJlIHVzZWQgZm9yIHRoZQorICAgICAqIHN0cmluZy4gIElmIHRoZSBwYXJhbWV0ZXIgaXMgbm90IGluY2x1ZGVkLCB0aGUKKyAgICAgKiBkZWZhdWx0IGNoYXJzZXQgaXMgdXNlZC4KKyAgICAgKgorICAgICAqIEBwYXJhbQlkYXRhCXRoZSBTdHJpbmcKKyAgICAgKiBAcGFyYW0JdHlwZQl0aGUgTUlNRSB0eXBlCisgICAgICogQGV4Y2VwdGlvbglJT0V4Y2VwdGlvbgllcnJvcnMgcmVhZGluZyB0aGUgU3RyaW5nCisgICAgICovCisgICAgcHVibGljIEJ5dGVBcnJheURhdGFTb3VyY2UoU3RyaW5nIGRhdGEsIFN0cmluZyB0eXBlKSB0aHJvd3MgSU9FeGNlcHRpb24geworCVN0cmluZyBjaGFyc2V0ID0gbnVsbDsKKwl0cnkgeworCSAgICBDb250ZW50VHlwZSBjdCA9IG5ldyBDb250ZW50VHlwZSh0eXBlKTsKKwkgICAgY2hhcnNldCA9IGN0LmdldFBhcmFtZXRlcigiY2hhcnNldCIpOworCX0gY2F0Y2ggKFBhcnNlRXhjZXB0aW9uIHBleCkgeworCSAgICAvLyBpZ25vcmUgcGFyc2UgZXJyb3IKKwl9CisJY2hhcnNldCA9IE1pbWVVdGlsaXR5LmphdmFDaGFyc2V0KGNoYXJzZXQpOworCWlmIChjaGFyc2V0ID09IG51bGwpCisJICAgIGNoYXJzZXQgPSBNaW1lVXRpbGl0eS5nZXREZWZhdWx0SmF2YUNoYXJzZXQoKTsKKwkvLyBYWFggLSBjb3VsZCBjb252ZXJ0IHRvIGJ5dGVzIG9uIGRlbWFuZCByYXRoZXIgdGhhbiBjb3B5aW5nIGhlcmUKKwl0aGlzLmRhdGEgPSBkYXRhLmdldEJ5dGVzKGNoYXJzZXQpOworCXRoaXMudHlwZSA9IHR5cGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIGFuIElucHV0U3RyZWFtIGZvciB0aGUgZGF0YS4KKyAgICAgKiBOb3RlIHRoYXQgYSBuZXcgc3RyZWFtIGlzIHJldHVybmVkIGVhY2ggdGltZQorICAgICAqIHRoaXMgbWV0aG9kIGlzIGNhbGxlZC4KKyAgICAgKgorICAgICAqIEByZXR1cm4JCXRoZSBJbnB1dFN0cmVhbQorICAgICAqIEBleGNlcHRpb24JSU9FeGNlcHRpb24JaWYgbm8gZGF0YSBoYXMgYmVlbiBzZXQKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgSW5wdXRTdHJlYW0gZ2V0SW5wdXRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworCWlmIChkYXRhID09IG51bGwpCisJICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigibm8gZGF0YSIpOworCWlmIChsZW4gPCAwKQorCSAgICBsZW4gPSBkYXRhLmxlbmd0aDsKKwlyZXR1cm4gbmV3IFNoYXJlZEJ5dGVBcnJheUlucHV0U3RyZWFtKGRhdGEsIDAsIGxlbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIGFuIE91dHB1dFN0cmVhbSBmb3IgdGhlIGRhdGEuCisgICAgICogV3JpdGluZyB0aGUgZGF0YSBpcyBub3Qgc3VwcG9ydGVkOyBhbiA8Y29kZT5JT0V4Y2VwdGlvbjwvY29kZT4KKyAgICAgKiBpcyBhbHdheXMgdGhyb3duLgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbglJT0V4Y2VwdGlvbglhbHdheXMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgT3V0cHV0U3RyZWFtIGdldE91dHB1dFN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJjYW5ub3QgZG8gdGhpcyIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgTUlNRSBjb250ZW50IHR5cGUgb2YgdGhlIGRhdGEuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBNSU1FIHR5cGUKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIGdldENvbnRlbnRUeXBlKCkgeworICAgICAgICByZXR1cm4gdHlwZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIG5hbWUgb2YgdGhlIGRhdGEuCisgICAgICogQnkgZGVmYXVsdCwgYW4gZW1wdHkgc3RyaW5nICgiIikgaXMgcmV0dXJuZWQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCXRoZSBuYW1lIG9mIHRoaXMgZGF0YQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKKyAgICAgICAgcmV0dXJuIG5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBuYW1lIG9mIHRoZSBkYXRhLgorICAgICAqCisgICAgICogQHBhcmFtCW5hbWUJdGhlIG5hbWUgb2YgdGhpcyBkYXRhCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TmFtZShTdHJpbmcgbmFtZSkgeworCXRoaXMubmFtZSA9IG5hbWU7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvdXRpbC9TaGFyZWRCeXRlQXJyYXlJbnB1dFN0cmVhbS5qYXZhIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvdXRpbC9TaGFyZWRCeXRlQXJyYXlJbnB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBlMTMyMTQKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC91dGlsL1NoYXJlZEJ5dGVBcnJheUlucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSw5MyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsLnV0aWw7CisKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC5TaGFyZWRJbnB1dFN0cmVhbTsKKworLyoqCisgKiBBIEJ5dGVBcnJheUlucHV0U3RyZWFtIHRoYXQgaW1wbGVtZW50cyB0aGUgU2hhcmVkSW5wdXRTdHJlYW0gaW50ZXJmYWNlLAorICogYWxsb3dpbmcgdGhlIHVuZGVybHlpbmcgYnl0ZSBhcnJheSB0byBiZSBzaGFyZWQgYmV0d2VlbiBtdWx0aXBsZSByZWFkZXJzLgorICoKKyAqIEBhdXRob3IgIEJpbGwgU2hhbm5vbgorICogQHNpbmNlIEphdmFNYWlsIDEuNAorICovCisKK3B1YmxpYyBjbGFzcyBTaGFyZWRCeXRlQXJyYXlJbnB1dFN0cmVhbSBleHRlbmRzIEJ5dGVBcnJheUlucHV0U3RyZWFtCisJCQkJaW1wbGVtZW50cyBTaGFyZWRJbnB1dFN0cmVhbSB7CisgICAgLyoqCisgICAgICogUG9zaXRpb24gd2l0aGluIHNoYXJlZCBidWZmZXIgdGhhdCB0aGlzIHN0cmVhbSBzdGFydHMgYXQuCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBzdGFydCA9IDA7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBTaGFyZWRCeXRlQXJyYXlJbnB1dFN0cmVhbSByZXByZXNlbnRpbmcgdGhlIGVudGlyZQorICAgICAqIGJ5dGUgYXJyYXkuCisgICAgICoKKyAgICAgKiBAcGFyYW0JYnVmCXRoZSBieXRlIGFycmF5CisgICAgICovCisgICAgcHVibGljIFNoYXJlZEJ5dGVBcnJheUlucHV0U3RyZWFtKGJ5dGVbXSBidWYpIHsKKwlzdXBlcihidWYpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIFNoYXJlZEJ5dGVBcnJheUlucHV0U3RyZWFtIHJlcHJlc2VudGluZyB0aGUgcGFydAorICAgICAqIG9mIHRoZSBieXRlIGFycmF5IGZyb20gPGNvZGU+b2Zmc2V0PC9jb2RlPiBmb3IgPGNvZGU+bGVuZ3RoPC9jb2RlPgorICAgICAqIGJ5dGVzLgorICAgICAqCisgICAgICogQHBhcmFtCWJ1Zgl0aGUgYnl0ZSBhcnJheQorICAgICAqIEBwYXJhbQlvZmZzZXQJb2Zmc2V0IGluIGJ5dGUgYXJyYXkgdG8gZmlyc3QgYnl0ZSB0byBpbmNsdWRlCisgICAgICogQHBhcmFtCWxlbmd0aAludW1iZXIgb2YgYnl0ZXMgdG8gaW5jbHVkZQorICAgICAqLworICAgIHB1YmxpYyBTaGFyZWRCeXRlQXJyYXlJbnB1dFN0cmVhbShieXRlW10gYnVmLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKSB7CisJc3VwZXIoYnVmLCBvZmZzZXQsIGxlbmd0aCk7CisJc3RhcnQgPSBvZmZzZXQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBJbnB1dFN0cmVhbSwgYXMgYW4KKyAgICAgKiBvZmZzZXQgZnJvbSB0aGUgYmVnaW5uaW5nIG9mIHRoZSBJbnB1dFN0cmVhbS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gIHRoZSBjdXJyZW50IHBvc2l0aW9uCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgZ2V0UG9zaXRpb24oKSB7CisJcmV0dXJuIHBvcyAtIHN0YXJ0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiBhIG5ldyBJbnB1dFN0cmVhbSByZXByZXNlbnRpbmcgYSBzdWJzZXQgb2YgdGhlIGRhdGEKKyAgICAgKiBmcm9tIHRoaXMgSW5wdXRTdHJlYW0sIHN0YXJ0aW5nIGF0IDxjb2RlPnN0YXJ0PC9jb2RlPiAoaW5jbHVzaXZlKQorICAgICAqIHVwIHRvIDxjb2RlPmVuZDwvY29kZT4gKGV4Y2x1c2l2ZSkuICA8Y29kZT5zdGFydDwvY29kZT4gbXVzdCBiZQorICAgICAqIG5vbi1uZWdhdGl2ZS4gIElmIDxjb2RlPmVuZDwvY29kZT4gaXMgLTEsIHRoZSBuZXcgc3RyZWFtIGVuZHMKKyAgICAgKiBhdCB0aGUgc2FtZSBwbGFjZSBhcyB0aGlzIHN0cmVhbS4gIFRoZSByZXR1cm5lZCBJbnB1dFN0cmVhbQorICAgICAqIHdpbGwgYWxzbyBpbXBsZW1lbnQgdGhlIFNoYXJlZElucHV0U3RyZWFtIGludGVyZmFjZS4KKyAgICAgKgorICAgICAqIEBwYXJhbQlzdGFydAl0aGUgc3RhcnRpbmcgcG9zaXRpb24KKyAgICAgKiBAcGFyYW0JZW5kCXRoZSBlbmRpbmcgcG9zaXRpb24gKyAxCisgICAgICogQHJldHVybgkJdGhlIG5ldyBzdHJlYW0KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgSW5wdXRTdHJlYW0gbmV3U3RyZWFtKGxvbmcgc3RhcnQsIGxvbmcgZW5kKSB7CisJaWYgKHN0YXJ0IDwgMCkKKwkgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigic3RhcnQgPCAwIik7CisJaWYgKGVuZCA9PSAtMSkKKwkgICAgZW5kID0gY291bnQgLSB0aGlzLnN0YXJ0OworCXJldHVybiBuZXcgU2hhcmVkQnl0ZUFycmF5SW5wdXRTdHJlYW0oYnVmLAorCQkJCXRoaXMuc3RhcnQgKyAoaW50KXN0YXJ0LCAoaW50KShlbmQgLSBzdGFydCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL3V0aWwvU2hhcmVkRmlsZUlucHV0U3RyZWFtLmphdmEgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC91dGlsL1NoYXJlZEZpbGVJbnB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMxZGYwZGEKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL2phdmEvamF2YXgvbWFpbC91dGlsL1NoYXJlZEZpbGVJbnB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsNTM5IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGphdmF4Lm1haWwudXRpbDsKKworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZheC5tYWlsLmludGVybmV0LlNoYXJlZElucHV0U3RyZWFtOworCisvKioKKyAqIEEgPGNvZGU+U2hhcmVkRmlsZUlucHV0U3RyZWFtPC9jb2RlPiBpcyBhCisgKiA8Y29kZT5CdWZmZXJlZElucHV0U3RyZWFtPC9jb2RlPiB0aGF0IGJ1ZmZlcnMKKyAqIGRhdGEgZnJvbSB0aGUgZmlsZSBhbmQgc3VwcG9ydHMgdGhlIDxjb2RlPm1hcms8L2NvZGU+CisgKiBhbmQgPGNvZGU+cmVzZXQ8L2NvZGU+IG1ldGhvZHMuICBJdCBhbHNvIHN1cHBvcnRzIHRoZQorICogPGNvZGU+bmV3U3RyZWFtPC9jb2RlPiBtZXRob2QgdGhhdCBhbGxvd3MgeW91IHRvIGNyZWF0ZQorICogb3RoZXIgc3RyZWFtcyB0aGF0IHJlcHJlc2VudCBzdWJzZXRzIG9mIHRoZSBmaWxlLgorICogQSA8Y29kZT5SYW5kb21BY2Nlc3NGaWxlPC9jb2RlPiBvYmplY3QgaXMgdXNlZCB0bworICogYWNjZXNzIHRoZSBmaWxlIGRhdGEuIDxwPgorICoKKyAqIE5vdGUgdGhhdCB3aGVuIHRoZSBTaGFyZWRGaWxlSW5wdXRTdHJlYW0gaXMgY2xvc2VkLAorICogYWxsIHN0cmVhbXMgY3JlYXRlZCB3aXRoIHRoZSA8Y29kZT5uZXdTdHJlYW08L2NvZGU+CisgKiBtZXRob2QgYXJlIGFsc28gY2xvc2VkLiAgVGhpcyBhbGxvd3MgdGhlIGNyZWF0b3Igb2YgdGhlCisgKiBTaGFyZWRGaWxlSW5wdXRTdHJlYW0gb2JqZWN0IHRvIGNvbnRyb2wgYWNjZXNzIHRvIHRoZQorICogdW5kZXJseWluZyBmaWxlIGFuZCBlbnN1cmUgdGhhdCBpdCBpcyBjbG9zZWQgd2hlbgorICogbmVlZGVkLCB0byBhdm9pZCBsZWFraW5nIGZpbGUgZGVzY3JpcHRvcnMuICBOb3RlIGFsc28KKyAqIHRoYXQgdGhpcyBiZWhhdmlvciBjb250cmFkaWN0cyB0aGUgcmVxdWlyZW1lbnRzIG9mCisgKiBTaGFyZWRJbnB1dFN0cmVhbSBhbmQgbWF5IGNoYW5nZSBpbiBhIGZ1dHVyZSByZWxlYXNlLgorICoKKyAqIEBhdXRob3IgIEJpbGwgU2hhbm5vbgorICogQHNpbmNlICAgSmF2YU1haWwgMS40CisgKi8KK3B1YmxpYyBjbGFzcyBTaGFyZWRGaWxlSW5wdXRTdHJlYW0gZXh0ZW5kcyBCdWZmZXJlZElucHV0U3RyZWFtCisJCQkJaW1wbGVtZW50cyBTaGFyZWRJbnB1dFN0cmVhbSB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBpbnQgZGVmYXVsdEJ1ZmZlclNpemUgPSAyMDQ4OworCisgICAgLyoqCisgICAgICogVGhlIGZpbGUgY29udGFpbmluZyB0aGUgZGF0YS4KKyAgICAgKiBTaGFyZWQgYnkgYWxsIHJlbGF0ZWQgU2hhcmVkRmlsZUlucHV0U3RyZWFtcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgUmFuZG9tQWNjZXNzRmlsZSBpbjsKKworICAgIC8qKgorICAgICAqIFRoZSBub3JtYWwgc2l6ZSBvZiB0aGUgcmVhZCBidWZmZXIuCisgICAgICovCisgICAgcHJvdGVjdGVkIGludCBidWZzaXplOworCisgICAgLyoqCisgICAgICogVGhlIGZpbGUgb2Zmc2V0IHRoYXQgY29ycmVzcG9uZHMgdG8gdGhlIGZpcnN0IGJ5dGUgaW4KKyAgICAgKiB0aGUgcmVhZCBidWZmZXIuCisgICAgICovCisgICAgcHJvdGVjdGVkIGxvbmcgYnVmcG9zOworCisgICAgLyoqCisgICAgICogVGhlIGZpbGUgb2Zmc2V0IG9mIHRoZSBzdGFydCBvZiBkYXRhIGluIHRoaXMgc3Vic2V0IG9mIHRoZSBmaWxlLgorICAgICAqLworICAgIHByb3RlY3RlZCBsb25nIHN0YXJ0ID0gMDsKKworICAgIC8qKgorICAgICAqIFRoZSBhbW91bnQgb2YgZGF0YSBpbiB0aGlzIHN1YnNldCBvZiB0aGUgZmlsZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgbG9uZyBkYXRhbGVuOworCisgICAgLyoqCisgICAgICogVHJ1ZSBpZiB0aGlzIGlzIGEgdG9wIGxldmVsIHN0cmVhbSBjcmVhdGVkIGRpcmVjdGx5IGJ5ICJuZXciLgorICAgICAqIEZhbHNlIGlmIHRoaXMgaXMgYSBkZXJpdmVkIHN0cmVhbSBjcmVhdGVkIGJ5IG5ld1N0cmVhbS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gbWFzdGVyID0gdHJ1ZTsKKworICAgIC8qKgorICAgICAqIEEgc2hhcmVkIGNsYXNzIHRoYXQga2VlcHMgdHJhY2sgb2YgdGhlIHJlZmVyZW5jZXMKKyAgICAgKiB0byBhIHBhcnRpY3VsYXIgZmlsZSBzbyBpdCBjYW4gYmUgY2xvc2VkIHdoZW4gdGhlCisgICAgICogbGFzdCByZWZlcmVuY2UgaXMgZ29uZS4KKyAgICAgKi8KKyAgICBzdGF0aWMgY2xhc3MgU2hhcmVkRmlsZSB7CisJcHJpdmF0ZSBpbnQgY250OworCXByaXZhdGUgUmFuZG9tQWNjZXNzRmlsZSBpbjsKKworCVNoYXJlZEZpbGUoU3RyaW5nIGZpbGUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJICAgIHRoaXMuaW4gPSBuZXcgUmFuZG9tQWNjZXNzRmlsZShmaWxlLCAiciIpOworCX0KKworCVNoYXJlZEZpbGUoRmlsZSBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24geworCSAgICB0aGlzLmluID0gbmV3IFJhbmRvbUFjY2Vzc0ZpbGUoZmlsZSwgInIiKTsKKwl9CisKKwlwdWJsaWMgc3luY2hyb25pemVkIFJhbmRvbUFjY2Vzc0ZpbGUgb3BlbigpIHsKKwkgICAgY250Kys7CisJICAgIHJldHVybiBpbjsKKwl9CisKKwlwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCSAgICBpZiAoY250ID4gMCAmJiAtLWNudCA8PSAwKQorCQlpbi5jbG9zZSgpOworCX0KKworCXB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBmb3JjZUNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkgICAgaWYgKGNudCA+IDApIHsKKwkJLy8gbm9ybWFsIGNhc2UsIGNsb3NlIGV4Y2VwdGlvbnMgcHJvcGFnYXRlZAorCQljbnQgPSAwOworCQlpbi5jbG9zZSgpOworCSAgICB9IGVsc2UgeworCQkvLyBzaG91bGQgYWxyZWFkeSBiZSBjbG9zZWQsIGlnbm9yZSBleGNlcHRpb24KKwkJdHJ5IHsKKwkJICAgIGluLmNsb3NlKCk7CisJCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZXgpIHsgfQorCSAgICB9CisJfQorCisJQE92ZXJyaWRlCisJcHJvdGVjdGVkIHZvaWQgZmluYWxpemUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKwkgICAgdHJ5IHsKKwkJaW4uY2xvc2UoKTsKKwkgICAgfSBmaW5hbGx5IHsKKwkJc3VwZXIuZmluYWxpemUoKTsKKwkgICAgfQorCX0KKyAgICB9CisKKyAgICBwcml2YXRlIFNoYXJlZEZpbGUgc2Y7CisKKyAgICAvKioKKyAgICAgKiBDaGVjayB0byBtYWtlIHN1cmUgdGhhdCB0aGlzIHN0cmVhbSBoYXMgbm90IGJlZW4gY2xvc2VkCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZU9wZW4oKSB0aHJvd3MgSU9FeGNlcHRpb24geworCWlmIChpbiA9PSBudWxsKQorCSAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlN0cmVhbSBjbG9zZWQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgPGNvZGU+U2hhcmVkRmlsZUlucHV0U3RyZWFtPC9jb2RlPgorICAgICAqIGZvciB0aGUgZmlsZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSAgIGZpbGUgICB0aGUgZmlsZQorICAgICAqIEBleGNlcHRpb24gSU9FeGNlcHRpb24gZm9yIGVycm9ycyBvcGVuaW5nIHRoZSBmaWxlCisgICAgICovCisgICAgcHVibGljIFNoYXJlZEZpbGVJbnB1dFN0cmVhbShGaWxlIGZpbGUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJdGhpcyhmaWxlLCBkZWZhdWx0QnVmZmVyU2l6ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIDxjb2RlPlNoYXJlZEZpbGVJbnB1dFN0cmVhbTwvY29kZT4KKyAgICAgKiBmb3IgdGhlIG5hbWVkIGZpbGUKKyAgICAgKgorICAgICAqIEBwYXJhbSAgIGZpbGUgICB0aGUgZmlsZQorICAgICAqIEBleGNlcHRpb24gSU9FeGNlcHRpb24gZm9yIGVycm9ycyBvcGVuaW5nIHRoZSBmaWxlCisgICAgICovCisgICAgcHVibGljIFNoYXJlZEZpbGVJbnB1dFN0cmVhbShTdHJpbmcgZmlsZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwl0aGlzKGZpbGUsIGRlZmF1bHRCdWZmZXJTaXplKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgPGNvZGU+U2hhcmVkRmlsZUlucHV0U3RyZWFtPC9jb2RlPgorICAgICAqIHdpdGggdGhlIHNwZWNpZmllZCBidWZmZXIgc2l6ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSAgIGZpbGUJdGhlIGZpbGUKKyAgICAgKiBAcGFyYW0gICBzaXplICAgdGhlIGJ1ZmZlciBzaXplLgorICAgICAqIEBleGNlcHRpb24gSU9FeGNlcHRpb24gZm9yIGVycm9ycyBvcGVuaW5nIHRoZSBmaWxlCisgICAgICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgc2l6ZSAmbGU7IDAuCisgICAgICovCisgICAgcHVibGljIFNoYXJlZEZpbGVJbnB1dFN0cmVhbShGaWxlIGZpbGUsIGludCBzaXplKSB0aHJvd3MgSU9FeGNlcHRpb24geworCXN1cGVyKG51bGwpOwkvLyBYWFggLSB3aWxsIGl0IE5QRT8KKyAgICAgICAgaWYgKHNpemUgPD0gMCkKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkJ1ZmZlciBzaXplIDw9IDAiKTsKKwlpbml0KG5ldyBTaGFyZWRGaWxlKGZpbGUpLCBzaXplKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGEgPGNvZGU+U2hhcmVkRmlsZUlucHV0U3RyZWFtPC9jb2RlPgorICAgICAqIHdpdGggdGhlIHNwZWNpZmllZCBidWZmZXIgc2l6ZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSAgIGZpbGUJdGhlIGZpbGUKKyAgICAgKiBAcGFyYW0gICBzaXplICAgdGhlIGJ1ZmZlciBzaXplLgorICAgICAqIEBleGNlcHRpb24gSU9FeGNlcHRpb24gZm9yIGVycm9ycyBvcGVuaW5nIHRoZSBmaWxlCisgICAgICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgc2l6ZSAmbGU7IDAuCisgICAgICovCisgICAgcHVibGljIFNoYXJlZEZpbGVJbnB1dFN0cmVhbShTdHJpbmcgZmlsZSwgaW50IHNpemUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJc3VwZXIobnVsbCk7CS8vIFhYWCAtIHdpbGwgaXQgTlBFPworICAgICAgICBpZiAoc2l6ZSA8PSAwKQorICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiQnVmZmVyIHNpemUgPD0gMCIpOworCWluaXQobmV3IFNoYXJlZEZpbGUoZmlsZSksIHNpemUpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBpbml0KFNoYXJlZEZpbGUgc2YsIGludCBzaXplKSB0aHJvd3MgSU9FeGNlcHRpb24geworCXRoaXMuc2YgPSBzZjsKKwl0aGlzLmluID0gc2Yub3BlbigpOworCXRoaXMuc3RhcnQgPSAwOworCXRoaXMuZGF0YWxlbiA9IGluLmxlbmd0aCgpOwkvLyBYWFggLSBmaWxlIGNhbid0IGdyb3cKKwl0aGlzLmJ1ZnNpemUgPSBzaXplOworCWJ1ZiA9IG5ldyBieXRlW3NpemVdOworICAgIH0KKworICAgIC8qKgorICAgICAqIFVzZWQgaW50ZXJuYWxseSBieSB0aGUgPGNvZGU+bmV3U3RyZWFtPC9jb2RlPiBtZXRob2QuCisgICAgICovCisgICAgcHJpdmF0ZSBTaGFyZWRGaWxlSW5wdXRTdHJlYW0oU2hhcmVkRmlsZSBzZiwgbG9uZyBzdGFydCwgbG9uZyBsZW4sCisJCQkJaW50IGJ1ZnNpemUpIHsKKwlzdXBlcihudWxsKTsKKwl0aGlzLm1hc3RlciA9IGZhbHNlOworCXRoaXMuc2YgPSBzZjsKKwl0aGlzLmluID0gc2Yub3BlbigpOworCXRoaXMuc3RhcnQgPSBzdGFydDsKKwl0aGlzLmJ1ZnBvcyA9IHN0YXJ0OworCXRoaXMuZGF0YWxlbiA9IGxlbjsKKwl0aGlzLmJ1ZnNpemUgPSBidWZzaXplOworCWJ1ZiA9IG5ldyBieXRlW2J1ZnNpemVdOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbGxzIHRoZSBidWZmZXIgd2l0aCBtb3JlIGRhdGEsIHRha2luZyBpbnRvIGFjY291bnQKKyAgICAgKiBzaHVmZmxpbmcgYW5kIG90aGVyIHRyaWNrcyBmb3IgZGVhbGluZyB3aXRoIG1hcmtzLgorICAgICAqIEFzc3VtZXMgdGhhdCBpdCBpcyBiZWluZyBjYWxsZWQgYnkgYSBzeW5jaHJvbml6ZWQgbWV0aG9kLgorICAgICAqIFRoaXMgbWV0aG9kIGFsc28gYXNzdW1lcyB0aGF0IGFsbCBkYXRhIGhhcyBhbHJlYWR5IGJlZW4gcmVhZCBpbiwKKyAgICAgKiBoZW5jZSBwb3MgPiBjb3VudC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgZmlsbCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJaWYgKG1hcmtwb3MgPCAwKSB7CisJICAgIHBvcyA9IDA7CQkvKiBubyBtYXJrOiB0aHJvdyBhd2F5IHRoZSBidWZmZXIgKi8KKwkgICAgYnVmcG9zICs9IGNvdW50OworCX0gZWxzZSBpZiAocG9zID49IGJ1Zi5sZW5ndGgpCS8qIG5vIHJvb20gbGVmdCBpbiBidWZmZXIgKi8KKwkgICAgaWYgKG1hcmtwb3MgPiAwKSB7CS8qIGNhbiB0aHJvdyBhd2F5IGVhcmx5IHBhcnQgb2YgdGhlIGJ1ZmZlciAqLworCQlpbnQgc3ogPSBwb3MgLSBtYXJrcG9zOworCQlTeXN0ZW0uYXJyYXljb3B5KGJ1ZiwgbWFya3BvcywgYnVmLCAwLCBzeik7CisJCXBvcyA9IHN6OworCQlidWZwb3MgKz0gbWFya3BvczsKKwkJbWFya3BvcyA9IDA7CisJICAgIH0gZWxzZSBpZiAoYnVmLmxlbmd0aCA+PSBtYXJrbGltaXQpIHsKKwkJbWFya3BvcyA9IC0xOwkvKiBidWZmZXIgZ290IHRvbyBiaWcsIGludmFsaWRhdGUgbWFyayAqLworCQlwb3MgPSAwOwkvKiBkcm9wIGJ1ZmZlciBjb250ZW50cyAqLworCQlidWZwb3MgKz0gY291bnQ7CisJICAgIH0gZWxzZSB7CQkvKiBncm93IGJ1ZmZlciAqLworCQlpbnQgbnN6ID0gcG9zICogMjsKKwkJaWYgKG5zeiA+IG1hcmtsaW1pdCkKKwkJICAgIG5zeiA9IG1hcmtsaW1pdDsKKwkJYnl0ZSBuYnVmW10gPSBuZXcgYnl0ZVtuc3pdOworCQlTeXN0ZW0uYXJyYXljb3B5KGJ1ZiwgMCwgbmJ1ZiwgMCwgcG9zKTsKKwkJYnVmID0gbmJ1ZjsKKwkgICAgfQorICAgICAgICBjb3VudCA9IHBvczsKKwkvLyBsaW1pdCB0byBkYXRhbGVuCisJaW50IGxlbiA9IGJ1Zi5sZW5ndGggLSBwb3M7CisJaWYgKGJ1ZnBvcyAtIHN0YXJ0ICsgcG9zICsgbGVuID4gZGF0YWxlbikKKwkgICAgbGVuID0gKGludCkoZGF0YWxlbiAtIChidWZwb3MgLSBzdGFydCArIHBvcykpOworCXN5bmNocm9uaXplZCAoaW4pIHsKKwkgICAgaW4uc2VlayhidWZwb3MgKyBwb3MpOworCSAgICBpbnQgbiA9IGluLnJlYWQoYnVmLCBwb3MsIGxlbik7CisJICAgIGlmIChuID4gMCkKKwkJY291bnQgPSBuICsgcG9zOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZWUgdGhlIGdlbmVyYWwgY29udHJhY3Qgb2YgdGhlIDxjb2RlPnJlYWQ8L2NvZGU+CisgICAgICogbWV0aG9kIG9mIDxjb2RlPklucHV0U3RyZWFtPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEByZXR1cm4gICAgIHRoZSBuZXh0IGJ5dGUgb2YgZGF0YSwgb3IgPGNvZGU+LTE8L2NvZGU+IGlmIHRoZSBlbmQgb2YgdGhlCisgICAgICogICAgICAgICAgICAgc3RyZWFtIGlzIHJlYWNoZWQuCisgICAgICogQGV4Y2VwdGlvbiAgSU9FeGNlcHRpb24gIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGVuc3VyZU9wZW4oKTsKKwlpZiAocG9zID49IGNvdW50KSB7CisJICAgIGZpbGwoKTsKKwkgICAgaWYgKHBvcyA+PSBjb3VudCkKKwkJcmV0dXJuIC0xOworCX0KKwlyZXR1cm4gYnVmW3BvcysrXSAmIDB4ZmY7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZCBjaGFyYWN0ZXJzIGludG8gYSBwb3J0aW9uIG9mIGFuIGFycmF5LCByZWFkaW5nIGZyb20gdGhlIHVuZGVybHlpbmcKKyAgICAgKiBzdHJlYW0gYXQgbW9zdCBvbmNlIGlmIG5lY2Vzc2FyeS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCByZWFkMShieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlpbnQgYXZhaWwgPSBjb3VudCAtIHBvczsKKwlpZiAoYXZhaWwgPD0gMCkgeworCSAgICBpZiAoZmFsc2UpIHsKKwkgICAgLyogSWYgdGhlIHJlcXVlc3RlZCBsZW5ndGggaXMgYXQgbGVhc3QgYXMgbGFyZ2UgYXMgdGhlIGJ1ZmZlciwgYW5kCisJICAgICAgIGlmIHRoZXJlIGlzIG5vIG1hcmsvcmVzZXQgYWN0aXZpdHksIGRvIG5vdCBib3RoZXIgdG8gY29weSB0aGUKKwkgICAgICAgYnl0ZXMgaW50byB0aGUgbG9jYWwgYnVmZmVyLiAgSW4gdGhpcyB3YXkgYnVmZmVyZWQgc3RyZWFtcyB3aWxsCisJICAgICAgIGNhc2NhZGUgaGFybWxlc3NseS4gKi8KKwkgICAgaWYgKGxlbiA+PSBidWYubGVuZ3RoICYmIG1hcmtwb3MgPCAwKSB7CisJCS8vIFhYWCAtIHNlZWssIHVwZGF0ZSBidWZwb3MgLSBob3c/CisJCXJldHVybiBpbi5yZWFkKGIsIG9mZiwgbGVuKTsKKwkgICAgfQorCSAgICB9CisJICAgIGZpbGwoKTsKKwkgICAgYXZhaWwgPSBjb3VudCAtIHBvczsKKwkgICAgaWYgKGF2YWlsIDw9IDApIHJldHVybiAtMTsKKwl9CisJaW50IGNudCA9IChhdmFpbCA8IGxlbikgPyBhdmFpbCA6IGxlbjsKKwlTeXN0ZW0uYXJyYXljb3B5KGJ1ZiwgcG9zLCBiLCBvZmYsIGNudCk7CisJcG9zICs9IGNudDsKKwlyZXR1cm4gY250OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWRzIGJ5dGVzIGZyb20gdGhpcyBzdHJlYW0gaW50byB0aGUgc3BlY2lmaWVkIGJ5dGUgYXJyYXksCisgICAgICogc3RhcnRpbmcgYXQgdGhlIGdpdmVuIG9mZnNldC4KKyAgICAgKgorICAgICAqIDxwPiBUaGlzIG1ldGhvZCBpbXBsZW1lbnRzIHRoZSBnZW5lcmFsIGNvbnRyYWN0IG9mIHRoZSBjb3JyZXNwb25kaW5nCisgICAgICogPGNvZGU+e0BsaW5rIGphdmEuaW8uSW5wdXRTdHJlYW0jcmVhZChieXRlW10sIGludCwgaW50KSByZWFkfTwvY29kZT4KKyAgICAgKiBtZXRob2Qgb2YgdGhlIDxjb2RlPntAbGluayBqYXZhLmlvLklucHV0U3RyZWFtfTwvY29kZT4gY2xhc3MuCisgICAgICoKKyAgICAgKiBAcGFyYW0gICAgICBiICAgICBkZXN0aW5hdGlvbiBidWZmZXIuCisgICAgICogQHBhcmFtICAgICAgb2ZmICAgb2Zmc2V0IGF0IHdoaWNoIHRvIHN0YXJ0IHN0b3JpbmcgYnl0ZXMuCisgICAgICogQHBhcmFtICAgICAgbGVuICAgbWF4aW11bSBudW1iZXIgb2YgYnl0ZXMgdG8gcmVhZC4KKyAgICAgKiBAcmV0dXJuICAgICB0aGUgbnVtYmVyIG9mIGJ5dGVzIHJlYWQsIG9yIDxjb2RlPi0xPC9jb2RlPiBpZiB0aGUgZW5kIG9mCisgICAgICogICAgICAgICAgICAgdGhlIHN0cmVhbSBoYXMgYmVlbiByZWFjaGVkLgorICAgICAqIEBleGNlcHRpb24gIElPRXhjZXB0aW9uICBpZiBhbiBJL08gZXJyb3Igb2NjdXJzLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IHJlYWQoYnl0ZSBiW10sIGludCBvZmYsIGludCBsZW4pCisJdGhyb3dzIElPRXhjZXB0aW9uCisgICAgeworICAgICAgICBlbnN1cmVPcGVuKCk7CisgICAgICAgIGlmICgob2ZmIHwgbGVuIHwgKG9mZiArIGxlbikgfCAoYi5sZW5ndGggLSAob2ZmICsgbGVuKSkpIDwgMCkgeworCSAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigpOworCX0gZWxzZSBpZiAobGVuID09IDApIHsKKwkgICAgcmV0dXJuIDA7CisJfQorCisJaW50IG4gPSByZWFkMShiLCBvZmYsIGxlbik7CisJaWYgKG4gPD0gMCkgcmV0dXJuIG47CisJd2hpbGUgKChuIDwgbGVuKSAvKiAmJiAoaW4uYXZhaWxhYmxlKCkgPiAwKSAqLykgeworCSAgICBpbnQgbjEgPSByZWFkMShiLCBvZmYgKyBuLCBsZW4gLSBuKTsKKwkgICAgaWYgKG4xIDw9IDApIGJyZWFrOworCSAgICBuICs9IG4xOworCX0KKwlyZXR1cm4gbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZWUgdGhlIGdlbmVyYWwgY29udHJhY3Qgb2YgdGhlIDxjb2RlPnNraXA8L2NvZGU+CisgICAgICogbWV0aG9kIG9mIDxjb2RlPklucHV0U3RyZWFtPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEBwYXJhbSAgICAgIG4gICB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIGJlIHNraXBwZWQuCisgICAgICogQHJldHVybiAgICAgdGhlIGFjdHVhbCBudW1iZXIgb2YgYnl0ZXMgc2tpcHBlZC4KKyAgICAgKiBAZXhjZXB0aW9uICBJT0V4Y2VwdGlvbiAgaWYgYW4gSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGxvbmcgc2tpcChsb25nIG4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGVuc3VyZU9wZW4oKTsKKwlpZiAobiA8PSAwKSB7CisJICAgIHJldHVybiAwOworCX0KKwlsb25nIGF2YWlsID0gY291bnQgLSBwb3M7CisgICAgIAorICAgICAgICBpZiAoYXZhaWwgPD0gMCkgeworICAgICAgICAgICAgLy8gSWYgbm8gbWFyayBwb3NpdGlvbiBzZXQgdGhlbiBkb24ndCBrZWVwIGluIGJ1ZmZlcgorCSAgICAvKgorICAgICAgICAgICAgaWYgKG1hcmtwb3MgPDApIAorICAgICAgICAgICAgICAgIHJldHVybiBpbi5za2lwKG4pOworCSAgICAqLworICAgICAgICAgICAgCisgICAgICAgICAgICAvLyBGaWxsIGluIGJ1ZmZlciB0byBzYXZlIGJ5dGVzIGZvciByZXNldAorICAgICAgICAgICAgZmlsbCgpOworICAgICAgICAgICAgYXZhaWwgPSBjb3VudCAtIHBvczsKKyAgICAgICAgICAgIGlmIChhdmFpbCA8PSAwKQorICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgICAgIAorICAgICAgICBsb25nIHNraXBwZWQgPSAoYXZhaWwgPCBuKSA/IGF2YWlsIDogbjsKKyAgICAgICAgcG9zICs9IHNraXBwZWQ7CisgICAgICAgIHJldHVybiBza2lwcGVkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IGNhbiBiZSByZWFkIGZyb20gdGhpcyBpbnB1dCAKKyAgICAgKiBzdHJlYW0gd2l0aG91dCBibG9ja2luZy4gCisgICAgICoKKyAgICAgKiBAcmV0dXJuICAgICB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRoYXQgY2FuIGJlIHJlYWQgZnJvbSB0aGlzIGlucHV0CisgICAgICogICAgICAgICAgICAgc3RyZWFtIHdpdGhvdXQgYmxvY2tpbmcuCisgICAgICogQGV4Y2VwdGlvbiAgSU9FeGNlcHRpb24gIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBpbnQgYXZhaWxhYmxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZW5zdXJlT3BlbigpOworCXJldHVybiAoY291bnQgLSBwb3MpICsgaW5fYXZhaWxhYmxlKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBpbnQgaW5fYXZhaWxhYmxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkvLyBYWFggLSBvdmVyZmxvdworCXJldHVybiAoaW50KSgoc3RhcnQgKyBkYXRhbGVuKSAtIChidWZwb3MgKyBjb3VudCkpOworICAgIH0KKworICAgIC8qKiAKKyAgICAgKiBTZWUgdGhlIGdlbmVyYWwgY29udHJhY3Qgb2YgdGhlIDxjb2RlPm1hcms8L2NvZGU+CisgICAgICogbWV0aG9kIG9mIDxjb2RlPklucHV0U3RyZWFtPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEBwYXJhbSAgIHJlYWRsaW1pdCAgIHRoZSBtYXhpbXVtIGxpbWl0IG9mIGJ5dGVzIHRoYXQgY2FuIGJlIHJlYWQgYmVmb3JlCisgICAgICogICAgICAgICAgICAgICAgICAgICAgdGhlIG1hcmsgcG9zaXRpb24gYmVjb21lcyBpbnZhbGlkLgorICAgICAqIEBzZWUgICAgICNyZXNldCgpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIG1hcmsoaW50IHJlYWRsaW1pdCkgeworCW1hcmtsaW1pdCA9IHJlYWRsaW1pdDsKKwltYXJrcG9zID0gcG9zOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNlZSB0aGUgZ2VuZXJhbCBjb250cmFjdCBvZiB0aGUgPGNvZGU+cmVzZXQ8L2NvZGU+CisgICAgICogbWV0aG9kIG9mIDxjb2RlPklucHV0U3RyZWFtPC9jb2RlPi4KKyAgICAgKiA8cD4KKyAgICAgKiBJZiA8Y29kZT5tYXJrcG9zPC9jb2RlPiBpcyA8Y29kZT4tMTwvY29kZT4KKyAgICAgKiAobm8gbWFyayBoYXMgYmVlbiBzZXQgb3IgdGhlIG1hcmsgaGFzIGJlZW4KKyAgICAgKiBpbnZhbGlkYXRlZCksIGFuIDxjb2RlPklPRXhjZXB0aW9uPC9jb2RlPgorICAgICAqIGlzIHRocm93bi4gT3RoZXJ3aXNlLCA8Y29kZT5wb3M8L2NvZGU+IGlzCisgICAgICogc2V0IGVxdWFsIHRvIDxjb2RlPm1hcmtwb3M8L2NvZGU+LgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbiAgSU9FeGNlcHRpb24gIGlmIHRoaXMgc3RyZWFtIGhhcyBub3QgYmVlbiBtYXJrZWQgb3IKKyAgICAgKiAgICAgICAgICAgICAgIGlmIHRoZSBtYXJrIGhhcyBiZWVuIGludmFsaWRhdGVkLgorICAgICAqIEBzZWUgICAgICAgICNtYXJrKGludCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgcmVzZXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBlbnN1cmVPcGVuKCk7CisJaWYgKG1hcmtwb3MgPCAwKQorCSAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlJlc2V0dGluZyB0byBpbnZhbGlkIG1hcmsiKTsKKwlwb3MgPSBtYXJrcG9zOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIGlmIHRoaXMgaW5wdXQgc3RyZWFtIHN1cHBvcnRzIHRoZSA8Y29kZT5tYXJrPC9jb2RlPiAKKyAgICAgKiBhbmQgPGNvZGU+cmVzZXQ8L2NvZGU+IG1ldGhvZHMuIFRoZSA8Y29kZT5tYXJrU3VwcG9ydGVkPC9jb2RlPiAKKyAgICAgKiBtZXRob2Qgb2YgPGNvZGU+U2hhcmVkRmlsZUlucHV0U3RyZWFtPC9jb2RlPiByZXR1cm5zIAorICAgICAqIDxjb2RlPnRydWU8L2NvZGU+LiAKKyAgICAgKgorICAgICAqIEByZXR1cm4gIGEgPGNvZGU+Ym9vbGVhbjwvY29kZT4gaW5kaWNhdGluZyBpZiB0aGlzIHN0cmVhbSB0eXBlIHN1cHBvcnRzCisgICAgICogICAgICAgICAgdGhlIDxjb2RlPm1hcms8L2NvZGU+IGFuZCA8Y29kZT5yZXNldDwvY29kZT4gbWV0aG9kcy4KKyAgICAgKiBAc2VlICAgICBqYXZhLmlvLklucHV0U3RyZWFtI21hcmsoaW50KQorICAgICAqIEBzZWUgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0jcmVzZXQoKQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIG1hcmtTdXBwb3J0ZWQoKSB7CisJcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2VzIHRoaXMgaW5wdXQgc3RyZWFtIGFuZCByZWxlYXNlcyBhbnkgc3lzdGVtIHJlc291cmNlcyAKKyAgICAgKiBhc3NvY2lhdGVkIHdpdGggdGhlIHN0cmVhbS4gCisgICAgICoKKyAgICAgKiBAZXhjZXB0aW9uICBJT0V4Y2VwdGlvbiAgaWYgYW4gSS9PIGVycm9yIG9jY3Vycy4KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChpbiA9PSBudWxsKQorICAgICAgICAgICAgcmV0dXJuOworCXRyeSB7CisJICAgIGlmIChtYXN0ZXIpCisJCXNmLmZvcmNlQ2xvc2UoKTsKKwkgICAgZWxzZQorCQlzZi5jbG9zZSgpOworCX0gZmluYWxseSB7CisJICAgIHNmID0gbnVsbDsKKwkgICAgaW4gPSBudWxsOworCSAgICBidWYgPSBudWxsOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIGN1cnJlbnQgcG9zaXRpb24gaW4gdGhlIElucHV0U3RyZWFtLCBhcyBhbgorICAgICAqIG9mZnNldCBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhlIElucHV0U3RyZWFtLgorICAgICAqCisgICAgICogQHJldHVybiAgdGhlIGN1cnJlbnQgcG9zaXRpb24KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbG9uZyBnZXRQb3NpdGlvbigpIHsKKy8vU3lzdGVtLm91dC5wcmludGxuKCJnZXRQb3NpdGlvbjogc3RhcnQgIiArIHN0YXJ0ICsgIiBwb3MgIiArIHBvcyAKKy8vCSsgIiBidWZwb3MgIiArIGJ1ZnBvcyArICIgPSAiICsgKGJ1ZnBvcyArIHBvcyAtIHN0YXJ0KSk7CisJaWYgKGluID09IG51bGwpCisJICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJTdHJlYW0gY2xvc2VkIik7CisJcmV0dXJuIGJ1ZnBvcyArIHBvcyAtIHN0YXJ0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiBhIG5ldyBJbnB1dFN0cmVhbSByZXByZXNlbnRpbmcgYSBzdWJzZXQgb2YgdGhlIGRhdGEKKyAgICAgKiBmcm9tIHRoaXMgSW5wdXRTdHJlYW0sIHN0YXJ0aW5nIGF0IDxjb2RlPnN0YXJ0PC9jb2RlPiAoaW5jbHVzaXZlKQorICAgICAqIHVwIHRvIDxjb2RlPmVuZDwvY29kZT4gKGV4Y2x1c2l2ZSkuICA8Y29kZT5zdGFydDwvY29kZT4gbXVzdCBiZQorICAgICAqIG5vbi1uZWdhdGl2ZS4gIElmIDxjb2RlPmVuZDwvY29kZT4gaXMgLTEsIHRoZSBuZXcgc3RyZWFtIGVuZHMKKyAgICAgKiBhdCB0aGUgc2FtZSBwbGFjZSBhcyB0aGlzIHN0cmVhbS4gIFRoZSByZXR1cm5lZCBJbnB1dFN0cmVhbQorICAgICAqIHdpbGwgYWxzbyBpbXBsZW1lbnQgdGhlIFNoYXJlZElucHV0U3RyZWFtIGludGVyZmFjZS4KKyAgICAgKgorICAgICAqIEBwYXJhbQlzdGFydAl0aGUgc3RhcnRpbmcgcG9zaXRpb24KKyAgICAgKiBAcGFyYW0JZW5kCXRoZSBlbmRpbmcgcG9zaXRpb24gKyAxCisgICAgICogQHJldHVybgkJdGhlIG5ldyBzdHJlYW0KKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIElucHV0U3RyZWFtIG5ld1N0cmVhbShsb25nIHN0YXJ0LCBsb25nIGVuZCkgeworCWlmIChpbiA9PSBudWxsKQorCSAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiU3RyZWFtIGNsb3NlZCIpOworCWlmIChzdGFydCA8IDApCisJICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInN0YXJ0IDwgMCIpOworCWlmIChlbmQgPT0gLTEpCisJICAgIGVuZCA9IGRhdGFsZW47CisJcmV0dXJuIG5ldyBTaGFyZWRGaWxlSW5wdXRTdHJlYW0oc2YsCisJCQl0aGlzLnN0YXJ0ICsgc3RhcnQsIGVuZCAtIHN0YXJ0LCBidWZzaXplKTsKKyAgICB9CisKKyAgICAvLyBmb3IgdGVzdGluZy4uLgorICAgIC8qCisgICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJndikgdGhyb3dzIEV4Y2VwdGlvbiB7CisJU2hhcmVkRmlsZUlucHV0U3RyZWFtIGlzID0gbmV3IFNoYXJlZEZpbGVJbnB1dFN0cmVhbShhcmd2WzBdKTsKKwlqYXZhLnV0aWwuUmFuZG9tIHIgPSBuZXcgamF2YS51dGlsLlJhbmRvbSgpOworCWludCBiOworCXdoaWxlICgoYiA9IGlzLnJlYWQoKSkgPj0gMCkgeworCSAgICBTeXN0ZW0ub3V0LndyaXRlKGIpOworCSAgICBpZiAoci5uZXh0RG91YmxlKCkgPCAwLjMpIHsKKwkJSW5wdXRTdHJlYW0gaXMyID0gaXMubmV3U3RyZWFtKGlzLmdldFBvc2l0aW9uKCksIC0xKTsKKwkJaW50IGIyOworCQl3aGlsZSAoKGIyID0gaXMyLnJlYWQoKSkgPj0gMCkKKwkJICAgIDsKKwkgICAgfQorCX0KKyAgICB9CisgICAgKi8KKworICAgIC8qKgorICAgICAqIEZvcmNlIHRoaXMgc3RyZWFtIHRvIGNsb3NlLgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIGZpbmFsaXplKCkgdGhyb3dzIFRocm93YWJsZSB7CisJc3VwZXIuZmluYWxpemUoKTsKKwljbG9zZSgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL3V0aWwvcGFja2FnZS5odG1sIGIvbWFpbC9zcmMvbWFpbi9qYXZhL2phdmF4L21haWwvdXRpbC9wYWNrYWdlLmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTkwYTI2YwotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vamF2YS9qYXZheC9tYWlsL3V0aWwvcGFja2FnZS5odG1sCkBAIC0wLDAgKzEsMzQgQEAKKzwhRE9DVFlQRSBodG1sIFBVQkxJQyAiLS8vVzNDLy9EVEQgSFRNTCA0LjAxIFRyYW5zaXRpb25hbC8vRU4iPgorPEhUTUw+Cis8SEVBRD4KKzxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PXV0Zi04Ij4KKzwhLS0KKworICAgIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorCisgICAgVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgICAgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisKKyAgICBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgICAgTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICAgIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICAgIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorCisgICAgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisKKy0tPgorCis8VElUTEU+amF2YXgubWFpbC51dGlsIHBhY2thZ2U8L1RJVExFPgorPC9IRUFEPgorPEJPRFkgQkdDT0xPUj0id2hpdGUiPgorCis8UD4KK0phdmFNYWlsIEFQSSB1dGlsaXR5IGNsYXNzZXMuCitUaGlzIHBhY2thZ2Ugc3BlY2lmaWVzIHV0aWxpdHkgY2xhc3NlcyB0aGF0IGFyZSB1c2VmdWwgd2l0aAorb3RoZXIgSmF2YU1haWwgQVBJcy4KKzwvUD4KKworPC9CT0RZPgorPC9IVE1MPgpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9qYXZhL292ZXJ2aWV3Lmh0bWwgYi9tYWlsL3NyYy9tYWluL2phdmEvb3ZlcnZpZXcuaHRtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40MTFkMDIzCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9qYXZhL292ZXJ2aWV3Lmh0bWwKQEAgLTAsMCArMSwzNDcgQEAKKzwhRE9DVFlQRSBodG1sIFBVQkxJQyAiLS8vVzNDLy9EVEQgSFRNTCA0LjAxIFRyYW5zaXRpb25hbC8vRU4iPgorPEhUTUw+Cis8SEVBRD4KKzxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PXV0Zi04Ij4KKzwhLS0KKworICAgIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorCisgICAgVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgICAgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisKKyAgICBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgICAgTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICAgIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICAgIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorCisgICAgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisKKy0tPgorCis8VElUTEU+amF2YXgubWFpbCBwYWNrYWdlPC9USVRMRT4KKzwvSEVBRD4KKzxCT0RZIEJHQ09MT1I9IndoaXRlIj4KKworPFA+CitUaGUgSmF2YU1haWwmdHJhZGU7IEFQSQorcHJvdmlkZXMgY2xhc3NlcyB0aGF0IG1vZGVsIGEgbWFpbCBzeXN0ZW0uCitUaGUgPGNvZGU+amF2YXgubWFpbDwvY29kZT4gcGFja2FnZSBkZWZpbmVzIGNsYXNzZXMgdGhhdCBhcmUgY29tbW9uIHRvCithbGwgbWFpbCBzeXN0ZW1zLgorVGhlIDxjb2RlPmphdmF4Lm1haWwuaW50ZXJuZXQ8L2NvZGU+IHBhY2thZ2UgZGVmaW5lcyBjbGFzc2VzIHRoYXQgYXJlIHNwZWNpZmljCit0byBtYWlsIHN5c3RlbXMgYmFzZWQgb24gaW50ZXJuZXQgc3RhbmRhcmRzIHN1Y2ggYXMgTUlNRSwgU01UUCwgUE9QMywgYW5kIElNQVAuCitUaGUgSmF2YU1haWwgQVBJIGluY2x1ZGVzIHRoZSA8Y29kZT5qYXZheC5tYWlsPC9jb2RlPiBwYWNrYWdlIGFuZCBzdWJwYWNrYWdlcy4KKzwvUD4KKzxQPgorRm9yIGFuIG92ZXJ2aWV3IG9mIHRoZSBKYXZhTWFpbCBBUEksIHJlYWQgdGhlCis8QSBIUkVGPSJodHRwczovL2phdmFlZS5naXRodWIuaW8vamF2YW1haWwvZG9jcy9KYXZhTWFpbC0xLjYucGRmIiBUQVJHRVQ9Il90b3AiPgorSmF2YU1haWwgc3BlY2lmaWNhdGlvbjwvQT4uCis8L1A+Cis8UD4KK1RoZSBjb2RlIHRvIHNlbmQgYSBwbGFpbiB0ZXh0IG1lc3NhZ2UgY2FuIGJlIGFzIHNpbXBsZSBhcyB0aGUgZm9sbG93aW5nOgorPC9QPgorPFBSRT4KKyAgICBQcm9wZXJ0aWVzIHByb3BzID0gbmV3IFByb3BlcnRpZXMoKTsKKyAgICBwcm9wcy5wdXQoIm1haWwuc210cC5ob3N0IiwgIm15LW1haWwtc2VydmVyIik7CisgICAgU2Vzc2lvbiBzZXNzaW9uID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShwcm9wcywgbnVsbCk7CisKKyAgICB0cnkgeworCU1pbWVNZXNzYWdlIG1zZyA9IG5ldyBNaW1lTWVzc2FnZShzZXNzaW9uKTsKKwltc2cuc2V0RnJvbSgibWVAZXhhbXBsZS5jb20iKTsKKwltc2cuc2V0UmVjaXBpZW50cyhNZXNzYWdlLlJlY2lwaWVudFR5cGUuVE8sCisJCQkgICJ5b3VAZXhhbXBsZS5jb20iKTsKKwltc2cuc2V0U3ViamVjdCgiSmF2YU1haWwgaGVsbG8gd29ybGQgZXhhbXBsZSIpOworCW1zZy5zZXRTZW50RGF0ZShuZXcgRGF0ZSgpKTsKKwltc2cuc2V0VGV4dCgiSGVsbG8sIHdvcmxkIVxuIik7CisJVHJhbnNwb3J0LnNlbmQobXNnLCAibWVAZXhhbXBsZS5jb20iLCAibXktcGFzc3dvcmQiKTsKKyAgICB9IGNhdGNoIChNZXNzYWdpbmdFeGNlcHRpb24gbWV4KSB7CisJU3lzdGVtLm91dC5wcmludGxuKCJzZW5kIGZhaWxlZCwgZXhjZXB0aW9uOiAiICsgbWV4KTsKKyAgICB9Cis8L1BSRT4KKzxQPgorVGhlIEphdmFNYWlsIGRvd25sb2FkIGJ1bmRsZSBjb250YWlucyBtYW55IG1vcmUgY29tcGxldGUgZXhhbXBsZXMKK2luIHRoZSAiZGVtbyIgZGlyZWN0b3J5LgorPC9QPgorPFA+CitEb24ndCBmb3JnZXQgdG8gc2VlIHRoZQorPEEgSFJFRj0iaHR0cHM6Ly9qYXZhZWUuZ2l0aHViLmlvL2phdmFtYWlsL0ZBUS5odG1sIiBUQVJHRVQ9Il90b3AiPgorSmF2YU1haWwgQVBJIEZBUTwvQT4KK2ZvciBhbnN3ZXJzIHRvIHRoZSBtb3N0IGNvbW1vbiBxdWVzdGlvbnMuCitUaGUgPEEgSFJFRj0iaHR0cHM6Ly9qYXZhZWUuZ2l0aHViLmlvL2phdmFtYWlsLyIgVEFSR0VUPSJfdG9wIj4KK0phdmFNYWlsIHdlYiBzaXRlPC9BPgorY29udGFpbnMgbWFueSBhZGRpdGlvbmFsIHJlc291cmNlcy4KKzwvUD4KKzxBIE5BTUU9InByb3BlcnRpZXMiPjxTVFJPTkc+UHJvcGVydGllczwvU1RST05HPjwvQT4KKzxQPgorVGhlIEphdmFNYWlsIEFQSSBzdXBwb3J0cyB0aGUgZm9sbG93aW5nIHN0YW5kYXJkIHByb3BlcnRpZXMsCit3aGljaCBtYXkgYmUgc2V0IGluIHRoZSA8Y29kZT5TZXNzaW9uPC9jb2RlPiBvYmplY3QsIG9yIGluIHRoZQorPGNvZGU+UHJvcGVydGllczwvY29kZT4gb2JqZWN0IHVzZWQgdG8gY3JlYXRlIHRoZSA8Y29kZT5TZXNzaW9uPC9jb2RlPiBvYmplY3QuCitUaGUgcHJvcGVydGllcyBhcmUgYWx3YXlzIHNldCBhcyBzdHJpbmdzOyB0aGUgVHlwZSBjb2x1bW4gZGVzY3JpYmVzCitob3cgdGhlIHN0cmluZyBpcyBpbnRlcnByZXRlZC4gIEZvciBleGFtcGxlLCB1c2UKKzwvUD4KKzxQUkU+CisJcHJvcHMucHV0KCJtYWlsLmRlYnVnIiwgInRydWUiKTsKKzwvUFJFPgorPFA+Cit0byBzZXQgdGhlIDxjb2RlPm1haWwuZGVidWc8L2NvZGU+IHByb3BlcnR5LCB3aGljaCBpcyBvZiB0eXBlIGJvb2xlYW4uCis8L1A+Cis8VEFCTEUgQk9SREVSIFNVTU1BUlk9IkphdmFNYWlsIHByb3BlcnRpZXMiPgorPFRSPgorPFRIPk5hbWU8L1RIPgorPFRIPlR5cGU8L1RIPgorPFRIPkRlc2NyaXB0aW9uPC9USD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLmRlYnVnIj5tYWlsLmRlYnVnPC9BPjwvVEQ+Cis8VEQ+Ym9vbGVhbjwvVEQ+Cis8VEQ+CitUaGUgaW5pdGlhbCBkZWJ1ZyBtb2RlLgorRGVmYXVsdCBpcyBmYWxzZS4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5mcm9tIj5tYWlsLmZyb208L0E+PC9URD4KKzxURD5TdHJpbmc8L1REPgorPFREPgorVGhlIHJldHVybiBlbWFpbCBhZGRyZXNzIG9mIHRoZSBjdXJyZW50IHVzZXIsIHVzZWQgYnkgdGhlCis8Y29kZT5JbnRlcm5ldEFkZHJlc3M8L2NvZGU+IG1ldGhvZCA8Y29kZT5nZXRMb2NhbEFkZHJlc3M8L2NvZGU+LgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLm1pbWUuYWRkcmVzcy5zdHJpY3QiPm1haWwubWltZS5hZGRyZXNzLnN0cmljdDwvQT48L1REPgorPFREPmJvb2xlYW48L1REPgorPFREPgorVGhlIE1pbWVNZXNzYWdlIGNsYXNzIHVzZXMgdGhlIDxjb2RlPkludGVybmV0QWRkcmVzczwvY29kZT4gbWV0aG9kCis8Y29kZT5wYXJzZUhlYWRlcjwvY29kZT4gdG8gcGFyc2UgaGVhZGVycyBpbiBtZXNzYWdlcy4gIFRoaXMgcHJvcGVydHkKK2NvbnRyb2xzIHRoZSBzdHJpY3QgZmxhZyBwYXNzZWQgdG8gdGhlIDxjb2RlPnBhcnNlSGVhZGVyPC9jb2RlPgorbWV0aG9kLiAgVGhlIGRlZmF1bHQgaXMgdHJ1ZS4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5ob3N0Ij5tYWlsLmhvc3Q8L0E+PC9URD4KKzxURD5TdHJpbmc8L1REPgorPFREPgorVGhlIGRlZmF1bHQgaG9zdCBuYW1lIG9mIHRoZSBtYWlsIHNlcnZlciBmb3IgYm90aCBTdG9yZXMgYW5kIFRyYW5zcG9ydHMuCitVc2VkIGlmIHRoZSA8Y29kZT5tYWlsLjxpPnByb3RvY29sPC9pPi5ob3N0PC9jb2RlPiBwcm9wZXJ0eSBpc24ndCBzZXQuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuc3RvcmUucHJvdG9jb2wiPm1haWwuc3RvcmUucHJvdG9jb2w8L0E+PC9URD4KKzxURD5TdHJpbmc8L1REPgorPFREPgorU3BlY2lmaWVzIHRoZSBkZWZhdWx0IG1lc3NhZ2UgYWNjZXNzIHByb3RvY29sLiAgVGhlCis8Y29kZT5TZXNzaW9uPC9jb2RlPiBtZXRob2QgPGNvZGU+Z2V0U3RvcmUoKTwvY29kZT4gcmV0dXJucyBhIFN0b3JlCitvYmplY3QgdGhhdCBpbXBsZW1lbnRzIHRoaXMgcHJvdG9jb2wuICBCeSBkZWZhdWx0IHRoZSBmaXJzdCBTdG9yZQorcHJvdmlkZXIgaW4gdGhlIGNvbmZpZ3VyYXRpb24gZmlsZXMgaXMgcmV0dXJuZWQuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwudHJhbnNwb3J0LnByb3RvY29sIj5tYWlsLnRyYW5zcG9ydC5wcm90b2NvbDwvQT48L1REPgorPFREPlN0cmluZzwvVEQ+Cis8VEQ+CitTcGVjaWZpZXMgdGhlIGRlZmF1bHQgbWVzc2FnZSB0cmFuc3BvcnQgcHJvdG9jb2wuICBUaGUKKzxjb2RlPlNlc3Npb248L2NvZGU+IG1ldGhvZCA8Y29kZT5nZXRUcmFuc3BvcnQoKTwvY29kZT4gcmV0dXJucyBhIFRyYW5zcG9ydAorb2JqZWN0IHRoYXQgaW1wbGVtZW50cyB0aGlzIHByb3RvY29sLiAgQnkgZGVmYXVsdCB0aGUgZmlyc3QgVHJhbnNwb3J0Citwcm92aWRlciBpbiB0aGUgY29uZmlndXJhdGlvbiBmaWxlcyBpcyByZXR1cm5lZC4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC51c2VyIj5tYWlsLnVzZXI8L0E+PC9URD4KKzxURD5TdHJpbmc8L1REPgorPFREPgorVGhlIGRlZmF1bHQgdXNlciBuYW1lIHRvIHVzZSB3aGVuIGNvbm5lY3RpbmcgdG8gdGhlIG1haWwgc2VydmVyLgorVXNlZCBpZiB0aGUgPGNvZGU+bWFpbC48aT5wcm90b2NvbDwvaT4udXNlcjwvY29kZT4gcHJvcGVydHkgaXNuJ3Qgc2V0LgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnByb3RvY29sLmNsYXNzIj5tYWlsLjxpPnByb3RvY29sPC9pPi5jbGFzczwvQT48L1REPgorPFREPlN0cmluZzwvVEQ+Cis8VEQ+CitTcGVjaWZpZXMgdGhlIGZ1bGx5IHF1YWxpZmllZCBjbGFzcyBuYW1lIG9mIHRoZSBwcm92aWRlciBmb3IgdGhlCitzcGVjaWZpZWQgcHJvdG9jb2wuICBVc2VkIGluIGNhc2VzIHdoZXJlIG1vcmUgdGhhbiBvbmUgcHJvdmlkZXIKK2ZvciBhIGdpdmVuIHByb3RvY29sIGV4aXN0czsgdGhpcyBwcm9wZXJ0eSBjYW4gYmUgdXNlZCB0byBzcGVjaWZ5Cit3aGljaCBwcm92aWRlciB0byB1c2UgYnkgZGVmYXVsdC4gIFRoZSBwcm92aWRlciBtdXN0IHN0aWxsIGJlIGxpc3RlZAoraW4gYSBjb25maWd1cmF0aW9uIGZpbGUuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwucHJvdG9jb2wuaG9zdCI+bWFpbC48aT5wcm90b2NvbDwvaT4uaG9zdDwvQT48L1REPgorPFREPlN0cmluZzwvVEQ+Cis8VEQ+CitUaGUgaG9zdCBuYW1lIG9mIHRoZSBtYWlsIHNlcnZlciBmb3IgdGhlIHNwZWNpZmllZCBwcm90b2NvbC4KK092ZXJyaWRlcyB0aGUgPGNvZGU+bWFpbC5ob3N0PC9jb2RlPiBwcm9wZXJ0eS4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5wcm90b2NvbC5wb3J0Ij5tYWlsLjxpPnByb3RvY29sPC9pPi5wb3J0PC9BPjwvVEQ+Cis8VEQ+aW50PC9URD4KKzxURD4KK1RoZSBwb3J0IG51bWJlciBvZiB0aGUgbWFpbCBzZXJ2ZXIgZm9yIHRoZSBzcGVjaWZpZWQgcHJvdG9jb2wuCitJZiBub3Qgc3BlY2lmaWVkIHRoZSBwcm90b2NvbCdzIGRlZmF1bHQgcG9ydCBudW1iZXIgaXMgdXNlZC4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5wcm90b2NvbC51c2VyIj5tYWlsLjxpPnByb3RvY29sPC9pPi51c2VyPC9BPjwvVEQ+Cis8VEQ+U3RyaW5nPC9URD4KKzxURD4KK1RoZSB1c2VyIG5hbWUgdG8gdXNlIHdoZW4gY29ubmVjdGluZyB0byBtYWlsIHNlcnZlcnMKK3VzaW5nIHRoZSBzcGVjaWZpZWQgcHJvdG9jb2wuCitPdmVycmlkZXMgdGhlIDxjb2RlPm1haWwudXNlcjwvY29kZT4gcHJvcGVydHkuCis8L1REPgorPC9UUj4KKworPC9UQUJMRT4KKworPFA+CitUaGUgZm9sbG93aW5nIHByb3BlcnRpZXMgYXJlIHN1cHBvcnRlZCBieSB0aGUgcmVmZXJlbmNlIGltcGxlbWVudGF0aW9uIChSSSkgb2YKK0phdmFNYWlsLCBidXQgYXJlIG5vdCBjdXJyZW50bHkgYSByZXF1aXJlZCBwYXJ0IG9mIHRoZSBzcGVjaWZpY2F0aW9uLgorVGhlIG5hbWVzLCB0eXBlcywgZGVmYXVsdHMsIGFuZCBzZW1hbnRpY3Mgb2YgdGhlc2UgcHJvcGVydGllcyBtYXkKK2NoYW5nZSBpbiBmdXR1cmUgcmVsZWFzZXMuCis8L1A+Cis8VEFCTEUgQk9SREVSIFNVTU1BUlk9IkphdmFNYWlsIFJJIHByb3BlcnRpZXMiPgorPFRSPgorPFRIPk5hbWU8L1RIPgorPFRIPlR5cGU8L1RIPgorPFRIPkRlc2NyaXB0aW9uPC9USD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLmRlYnVnLmF1dGgiPm1haWwuZGVidWcuYXV0aDwvQT48L1REPgorPFREPmJvb2xlYW48L1REPgorPFREPgorSW5jbHVkZSBwcm90b2NvbCBhdXRoZW50aWNhdGlvbiBjb21tYW5kcyAoaW5jbHVkaW5nIHVzZXJuYW1lcyBhbmQgcGFzc3dvcmRzKQoraW4gdGhlIGRlYnVnIG91dHB1dC4KK0RlZmF1bHQgaXMgZmFsc2UuCis8L1REPgorPC9UUj4KKworPFRSPgorPFREPjxBIE5BTUU9Im1haWwuZGVidWcuYXV0aC51c2VybmFtZSI+bWFpbC5kZWJ1Zy5hdXRoLnVzZXJuYW1lPC9BPjwvVEQ+Cis8VEQ+Ym9vbGVhbjwvVEQ+Cis8VEQ+CitJbmNsdWRlIHRoZSB1c2VyIG5hbWUgaW4gbm9uLXByb3RvY29sIGRlYnVnIG91dHB1dC4KK0RlZmF1bHQgaXMgdHJ1ZS4KKzwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+PEEgTkFNRT0ibWFpbC5kZWJ1Zy5hdXRoLnBhc3N3b3JkIj5tYWlsLmRlYnVnLmF1dGgucGFzc3dvcmQ8L0E+PC9URD4KKzxURD5ib29sZWFuPC9URD4KKzxURD4KK0luY2x1ZGUgdGhlIHBhc3N3b3JkIGluIG5vbi1wcm90b2NvbCBkZWJ1ZyBvdXRwdXQuCitEZWZhdWx0IGlzIGZhbHNlLgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLnRyYW5zcG9ydC5wcm90b2NvbC5hZGRyZXNzLXR5cGUiPm1haWwudHJhbnNwb3J0LnByb3RvY29sLjxpPmFkZHJlc3MtdHlwZTwvaT48L0E+PC9URD4KKzxURD5TdHJpbmc8L1REPgorPFREPgorU3BlY2lmaWVzIHRoZSBkZWZhdWx0IG1lc3NhZ2UgdHJhbnNwb3J0IHByb3RvY29sIGZvciB0aGUgc3BlY2lmaWVkIGFkZHJlc3MgdHlwZS4KK1RoZSA8Y29kZT5TZXNzaW9uPC9jb2RlPiBtZXRob2QgPGNvZGU+Z2V0VHJhbnNwb3J0KEFkZHJlc3MpPC9jb2RlPiByZXR1cm5zIGEKK1RyYW5zcG9ydCBvYmplY3QgdGhhdCBpbXBsZW1lbnRzIHRoaXMgcHJvdG9jb2wgd2hlbiB0aGUgYWRkcmVzcyBpcyBvZiB0aGUKK3NwZWNpZmllZCB0eXBlIChlLmcuLCAicmZjODIyIiBmb3Igc3RhbmRhcmQgaW50ZXJuZXQgYWRkcmVzc2VzKS4KK0J5IGRlZmF1bHQgdGhlIGZpcnN0IFRyYW5zcG9ydCBjb25maWd1cmVkIGZvciB0aGF0IGFkZHJlc3MgdHlwZSBpcyB1c2VkLgorVGhpcyBwcm9wZXJ0eSBjYW4gYmUgdXNlZCB0byBvdmVycmlkZSB0aGUgYmVoYXZpb3Igb2YgdGhlCit7QGxpbmsgamF2YXgubWFpbC5UcmFuc3BvcnQjc2VuZCBzZW5kfSBtZXRob2Qgb2YgdGhlCit7QGxpbmsgamF2YXgubWFpbC5UcmFuc3BvcnQgVHJhbnNwb3J0fSBjbGFzcyBzbyB0aGF0IChmb3IgZXhhbXBsZSkgdGhlICJzbXRwcyIKK3Byb3RvY29sIGlzIHVzZWQgaW5zdGVhZCBvZiB0aGUgInNtdHAiIHByb3RvY29sIGJ5IHNldHRpbmcgdGhlIHByb3BlcnR5Cis8Y29kZT5tYWlsLnRyYW5zcG9ydC5wcm90b2NvbC5yZmM4MjI8L2NvZGU+IHRvIDxjb2RlPiJzbXRwcyI8L2NvZGU+LgorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLmV2ZW50LnNjb3BlIj5tYWlsLmV2ZW50LnNjb3BlPC9BPjwvVEQ+Cis8VEQ+U3RyaW5nPC9URD4KKzxURD4KK0NvbnRyb2xzIHRoZSBzY29wZSBvZiBldmVudHMuICAoU2VlIHRoZSBqYXZheC5tYWlsLmV2ZW50IHBhY2thZ2UuKQorQnkgZGVmYXVsdCwgYSBzZXBhcmF0ZSBldmVudCBxdWV1ZSBhbmQgdGhyZWFkIGlzIHVzZWQgZm9yIGV2ZW50cyBmb3IgZWFjaAorU3RvcmUsIFRyYW5zcG9ydCwgb3IgRm9sZGVyLgorSWYgdGhpcyBwcm9wZXJ0eSBpcyBzZXQgdG8gInNlc3Npb24iLCBhbGwgc3VjaCBldmVudHMgYXJlIHB1dCBpbiBhIHNpbmdsZQorZXZlbnQgcXVldWUgcHJvY2Vzc2VkIGJ5IGEgc2luZ2xlIHRocmVhZCBmb3IgdGhlIGN1cnJlbnQgc2Vzc2lvbi4KK0lmIHRoaXMgcHJvcGVydHkgaXMgc2V0IHRvICJhcHBsaWNhdGlvbiIsIGFsbCBzdWNoIGV2ZW50cyBhcmUgcHV0IGluIGEgc2luZ2xlCitldmVudCBxdWV1ZSBwcm9jZXNzZWQgYnkgYSBzaW5nbGUgdGhyZWFkIGZvciB0aGUgY3VycmVudCBhcHBsaWNhdGlvbi4KKyhBcHBsaWNhdGlvbnMgYXJlIGRpc3Rpbmd1aXNoZWQgYnkgdGhlaXIgY29udGV4dCBjbGFzcyBsb2FkZXIuKQorPC9URD4KKzwvVFI+CisKKzxUUj4KKzxURD48QSBOQU1FPSJtYWlsLmV2ZW50LmV4ZWN1dG9yIj5tYWlsLmV2ZW50LmV4ZWN1dG9yPC9BPjwvVEQ+Cis8VEQ+amF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3I8L1REPgorPFREPgorQnkgZGVmYXVsdCwgYSBuZXcgVGhyZWFkIGlzIGNyZWF0ZWQgZm9yIGVhY2ggZXZlbnQgcXVldWUuCitUaGlzIHRocmVhZCBpcyB1c2VkIHRvIGNhbGwgdGhlIGxpc3RlbmVycyBmb3IgdGhlc2UgZXZlbnRzLgorSWYgdGhpcyBwcm9wZXJ0eSBpcyBzZXQgdG8gYW4gaW5zdGFuY2Ugb2YgYW4gRXhlY3V0b3IsIHRoZQorRXhlY3V0b3IuZXhlY3V0ZSBtZXRob2QgaXMgdXNlZCB0byBydW4gdGhlIGV2ZW50IGRpc3BhdGNoZXIKK2ZvciBhbiBldmVudCBxdWV1ZS4gIFRoZSBldmVudCBkaXNwYXRjaGVyIHJ1bnMgdW50aWwgdGhlCitldmVudCBxdWV1ZSBpcyBubyBsb25nZXIgaW4gdXNlLgorPC9URD4KKzwvVFI+CisKKzwvVEFCTEU+CisKKzxQPgorVGhlIEphdmFNYWlsIEFQSSBhbHNvIHN1cHBvcnRzIHNldmVyYWwgU3lzdGVtIHByb3BlcnRpZXM7CitzZWUgdGhlIHtAbGluayBqYXZheC5tYWlsLmludGVybmV0fSBwYWNrYWdlIGRvY3VtZW50YXRpb24KK2ZvciBkZXRhaWxzLgorPC9QPgorPFA+CitUaGUgSmF2YU1haWwgcmVmZXJlbmNlCitpbXBsZW1lbnRhdGlvbiBpbmNsdWRlcyBwcm90b2NvbCBwcm92aWRlcnMgaW4gc3VicGFja2FnZXMgb2YKKzxjb2RlPmNvbS5zdW4ubWFpbDwvY29kZT4uICBOb3RlIHRoYXQgdGhlIEFQSXMgdG8gdGhlc2UgcHJvdG9jb2wKK3Byb3ZpZGVycyBhcmUgbm90IHBhcnQgb2YgdGhlIHN0YW5kYXJkIEphdmFNYWlsIEFQSS4gIFBvcnRhYmxlCitwcm9ncmFtcyB3aWxsIG5vdCB1c2UgdGhlc2UgQVBJcy4KKzwvUD4KKzxQPgorTm9ucG9ydGFibGUgcHJvZ3JhbXMgbWF5IHVzZSB0aGUgQVBJcyBvZiB0aGUgcHJvdG9jb2wgcHJvdmlkZXJzCitieSAoZm9yIGV4YW1wbGUpIGNhc3RpbmcgYSByZXR1cm5lZCA8Y29kZT5Gb2xkZXI8L2NvZGU+IG9iamVjdCB0byBhCis8Y29kZT5jb20uc3VuLm1haWwuaW1hcC5JTUFQRm9sZGVyPC9jb2RlPiBvYmplY3QuICBTaW1pbGFybHkgZm9yCis8Y29kZT5TdG9yZTwvY29kZT4gYW5kIDxjb2RlPk1lc3NhZ2U8L2NvZGU+IG9iamVjdHMgcmV0dXJuZWQgZnJvbSB0aGUKK3N0YW5kYXJkIEphdmFNYWlsIEFQSXMuCis8L1A+Cis8UD4KK1RoZSBwcm90b2NvbCBwcm92aWRlcnMgYWxzbyBzdXBwb3J0IHByb3BlcnRpZXMgdGhhdCBhcmUgc3BlY2lmaWMgdG8KK3Rob3NlIHByb3ZpZGVycy4gIFRoZSBwYWNrYWdlIGRvY3VtZW50YXRpb24gZm9yIHRoZQore0BsaW5rIGNvbS5zdW4ubWFpbC5pbWFwIElNQVB9LCB7QGxpbmsgY29tLnN1bi5tYWlsLnBvcDMgUE9QM30sCithbmQge0BsaW5rIGNvbS5zdW4ubWFpbC5zbXRwIFNNVFB9IHBhY2thZ2VzIHByb3ZpZGUgZGV0YWlscy4KKzwvUD4KKzxQPgorSW4gYWRkaXRpb24gdG8gcHJpbnRpbmcgZGVidWdnaW5nIG91dHB1dCBhcyBjb250cm9sbGVkIGJ5IHRoZQore0BsaW5rIGphdmF4Lm1haWwuU2Vzc2lvbiBTZXNzaW9ufSBjb25maWd1cmF0aW9uLCB0aGUgY3VycmVudAoraW1wbGVtZW50YXRpb24gb2YgY2xhc3NlcyBpbiB0aGlzIHBhY2thZ2UgbG9nIHRoZSBzYW1lIGluZm9ybWF0aW9uIHVzaW5nCit7QGxpbmsgamF2YS51dGlsLmxvZ2dpbmcuTG9nZ2VyfSBhcyBkZXNjcmliZWQgaW4gdGhlIGZvbGxvd2luZyB0YWJsZToKKzwvUD4KKzxUQUJMRSBCT1JERVIgU1VNTUFSWT0iSmF2YU1haWwgTG9nZ2VycyI+Cis8VFI+Cis8VEg+TG9nZ2VyIE5hbWU8L1RIPgorPFRIPkxvZ2dpbmcgTGV2ZWw8L1RIPgorPFRIPlB1cnBvc2U8L1RIPgorPC9UUj4KKworPFRSPgorPFREPmphdmF4Lm1haWw8L1REPgorPFREPkNPTkZJRzwvVEQ+Cis8VEQ+Q29uZmlndXJhdGlvbiBvZiB0aGUgU2Vzc2lvbjwvVEQ+Cis8L1RSPgorCis8VFI+Cis8VEQ+amF2YXgubWFpbDwvVEQ+Cis8VEQ+RklORTwvVEQ+Cis8VEQ+R2VuZXJhbCBkZWJ1Z2dpbmcgb3V0cHV0PC9URD4KKzwvVFI+Cis8L1RBQkxFPgorCis8L0JPRFk+Cis8L0hUTUw+CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL3Jlc291cmNlcy9NRVRBLUlORi9MSUNFTlNFLnR4dCBiL21haWwvc3JjL21haW4vcmVzb3VyY2VzL01FVEEtSU5GL0xJQ0VOU0UudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVkZTNkMWIKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL3Jlc291cmNlcy9NRVRBLUlORi9MSUNFTlNFLnR4dApAQCAtMCwwICsxLDYzNyBAQAorIyBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIC0gdiAyLjAKKworICAgICAgICBUSEUgQUNDT01QQU5ZSU5HIFBST0dSQU0gSVMgUFJPVklERUQgVU5ERVIgVEhFIFRFUk1TIE9GIFRISVMgRUNMSVBTRQorICAgICAgICBQVUJMSUMgTElDRU5TRSAoIkFHUkVFTUVOVCIpLiBBTlkgVVNFLCBSRVBST0RVQ1RJT04gT1IgRElTVFJJQlVUSU9OCisgICAgICAgIE9GIFRIRSBQUk9HUkFNIENPTlNUSVRVVEVTIFJFQ0lQSUVOVCdTIEFDQ0VQVEFOQ0UgT0YgVEhJUyBBR1JFRU1FTlQuCisKKyAgICAxLiBERUZJTklUSU9OUworCisgICAgIkNvbnRyaWJ1dGlvbiIgbWVhbnM6CisKKyAgICAgIGEpIGluIHRoZSBjYXNlIG9mIHRoZSBpbml0aWFsIENvbnRyaWJ1dG9yLCB0aGUgaW5pdGlhbCBjb250ZW50CisgICAgICAgICBEaXN0cmlidXRlZCB1bmRlciB0aGlzIEFncmVlbWVudCwgYW5kCisKKyAgICAgIGIpIGluIHRoZSBjYXNlIG9mIGVhY2ggc3Vic2VxdWVudCBDb250cmlidXRvcjogCisgICAgICAgICBpKSBjaGFuZ2VzIHRvIHRoZSBQcm9ncmFtLCBhbmQgCisgICAgICAgICBpaSkgYWRkaXRpb25zIHRvIHRoZSBQcm9ncmFtOworICAgICAgd2hlcmUgc3VjaCBjaGFuZ2VzIGFuZC9vciBhZGRpdGlvbnMgdG8gdGhlIFByb2dyYW0gb3JpZ2luYXRlIGZyb20KKyAgICAgIGFuZCBhcmUgRGlzdHJpYnV0ZWQgYnkgdGhhdCBwYXJ0aWN1bGFyIENvbnRyaWJ1dG9yLiBBIENvbnRyaWJ1dGlvbgorICAgICAgIm9yaWdpbmF0ZXMiIGZyb20gYSBDb250cmlidXRvciBpZiBpdCB3YXMgYWRkZWQgdG8gdGhlIFByb2dyYW0gYnkKKyAgICAgIHN1Y2ggQ29udHJpYnV0b3IgaXRzZWxmIG9yIGFueW9uZSBhY3Rpbmcgb24gc3VjaCBDb250cmlidXRvcidzIGJlaGFsZi4KKyAgICAgIENvbnRyaWJ1dGlvbnMgZG8gbm90IGluY2x1ZGUgY2hhbmdlcyBvciBhZGRpdGlvbnMgdG8gdGhlIFByb2dyYW0gdGhhdAorICAgICAgYXJlIG5vdCBNb2RpZmllZCBXb3Jrcy4KKworICAgICJDb250cmlidXRvciIgbWVhbnMgYW55IHBlcnNvbiBvciBlbnRpdHkgdGhhdCBEaXN0cmlidXRlcyB0aGUgUHJvZ3JhbS4KKworICAgICJMaWNlbnNlZCBQYXRlbnRzIiBtZWFuIHBhdGVudCBjbGFpbXMgbGljZW5zYWJsZSBieSBhIENvbnRyaWJ1dG9yIHdoaWNoCisgICAgYXJlIG5lY2Vzc2FyaWx5IGluZnJpbmdlZCBieSB0aGUgdXNlIG9yIHNhbGUgb2YgaXRzIENvbnRyaWJ1dGlvbiBhbG9uZQorICAgIG9yIHdoZW4gY29tYmluZWQgd2l0aCB0aGUgUHJvZ3JhbS4KKworICAgICJQcm9ncmFtIiBtZWFucyB0aGUgQ29udHJpYnV0aW9ucyBEaXN0cmlidXRlZCBpbiBhY2NvcmRhbmNlIHdpdGggdGhpcworICAgIEFncmVlbWVudC4KKworICAgICJSZWNpcGllbnQiIG1lYW5zIGFueW9uZSB3aG8gcmVjZWl2ZXMgdGhlIFByb2dyYW0gdW5kZXIgdGhpcyBBZ3JlZW1lbnQKKyAgICBvciBhbnkgU2Vjb25kYXJ5IExpY2Vuc2UgKGFzIGFwcGxpY2FibGUpLCBpbmNsdWRpbmcgQ29udHJpYnV0b3JzLgorCisgICAgIkRlcml2YXRpdmUgV29ya3MiIHNoYWxsIG1lYW4gYW55IHdvcmssIHdoZXRoZXIgaW4gU291cmNlIENvZGUgb3Igb3RoZXIKKyAgICBmb3JtLCB0aGF0IGlzIGJhc2VkIG9uIChvciBkZXJpdmVkIGZyb20pIHRoZSBQcm9ncmFtIGFuZCBmb3Igd2hpY2ggdGhlCisgICAgZWRpdG9yaWFsIHJldmlzaW9ucywgYW5ub3RhdGlvbnMsIGVsYWJvcmF0aW9ucywgb3Igb3RoZXIgbW9kaWZpY2F0aW9ucworICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLgorCisgICAgIk1vZGlmaWVkIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrIGluIFNvdXJjZSBDb2RlIG9yIG90aGVyIGZvcm0gdGhhdAorICAgIHJlc3VsdHMgZnJvbSBhbiBhZGRpdGlvbiB0bywgZGVsZXRpb24gZnJvbSwgb3IgbW9kaWZpY2F0aW9uIG9mIHRoZQorICAgIGNvbnRlbnRzIG9mIHRoZSBQcm9ncmFtLCBpbmNsdWRpbmcsIGZvciBwdXJwb3NlcyBvZiBjbGFyaXR5IGFueSBuZXcgZmlsZQorICAgIGluIFNvdXJjZSBDb2RlIGZvcm0gdGhhdCBjb250YWlucyBhbnkgY29udGVudHMgb2YgdGhlIFByb2dyYW0uIE1vZGlmaWVkCisgICAgV29ya3Mgc2hhbGwgbm90IGluY2x1ZGUgd29ya3MgdGhhdCBjb250YWluIG9ubHkgZGVjbGFyYXRpb25zLAorICAgIGludGVyZmFjZXMsIHR5cGVzLCBjbGFzc2VzLCBzdHJ1Y3R1cmVzLCBvciBmaWxlcyBvZiB0aGUgUHJvZ3JhbSBzb2xlbHkKKyAgICBpbiBlYWNoIGNhc2UgaW4gb3JkZXIgdG8gbGluayB0bywgYmluZCBieSBuYW1lLCBvciBzdWJjbGFzcyB0aGUgUHJvZ3JhbQorICAgIG9yIE1vZGlmaWVkIFdvcmtzIHRoZXJlb2YuCisKKyAgICAiRGlzdHJpYnV0ZSIgbWVhbnMgdGhlIGFjdHMgb2YgYSkgZGlzdHJpYnV0aW5nIG9yIGIpIG1ha2luZyBhdmFpbGFibGUKKyAgICBpbiBhbnkgbWFubmVyIHRoYXQgZW5hYmxlcyB0aGUgdHJhbnNmZXIgb2YgYSBjb3B5LgorCisgICAgIlNvdXJjZSBDb2RlIiBtZWFucyB0aGUgZm9ybSBvZiBhIFByb2dyYW0gcHJlZmVycmVkIGZvciBtYWtpbmcKKyAgICBtb2RpZmljYXRpb25zLCBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLAorICAgIGRvY3VtZW50YXRpb24gc291cmNlLCBhbmQgY29uZmlndXJhdGlvbiBmaWxlcy4KKworICAgICJTZWNvbmRhcnkgTGljZW5zZSIgbWVhbnMgZWl0aGVyIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAgICBWZXJzaW9uIDIuMCwgb3IgYW55IGxhdGVyIHZlcnNpb25zIG9mIHRoYXQgbGljZW5zZSwgaW5jbHVkaW5nIGFueQorICAgIGV4Y2VwdGlvbnMgb3IgYWRkaXRpb25hbCBwZXJtaXNzaW9ucyBhcyBpZGVudGlmaWVkIGJ5IHRoZSBpbml0aWFsCisgICAgQ29udHJpYnV0b3IuCisKKyAgICAyLiBHUkFOVCBPRiBSSUdIVFMKKworICAgICAgYSkgU3ViamVjdCB0byB0aGUgdGVybXMgb2YgdGhpcyBBZ3JlZW1lbnQsIGVhY2ggQ29udHJpYnV0b3IgaGVyZWJ5CisgICAgICBncmFudHMgUmVjaXBpZW50IGEgbm9uLWV4Y2x1c2l2ZSwgd29ybGR3aWRlLCByb3lhbHR5LWZyZWUgY29weXJpZ2h0CisgICAgICBsaWNlbnNlIHRvIHJlcHJvZHVjZSwgcHJlcGFyZSBEZXJpdmF0aXZlIFdvcmtzIG9mLCBwdWJsaWNseSBkaXNwbGF5LAorICAgICAgcHVibGljbHkgcGVyZm9ybSwgRGlzdHJpYnV0ZSBhbmQgc3VibGljZW5zZSB0aGUgQ29udHJpYnV0aW9uIG9mIHN1Y2gKKyAgICAgIENvbnRyaWJ1dG9yLCBpZiBhbnksIGFuZCBzdWNoIERlcml2YXRpdmUgV29ya3MuCisKKyAgICAgIGIpIFN1YmplY3QgdG8gdGhlIHRlcm1zIG9mIHRoaXMgQWdyZWVtZW50LCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieQorICAgICAgZ3JhbnRzIFJlY2lwaWVudCBhIG5vbi1leGNsdXNpdmUsIHdvcmxkd2lkZSwgcm95YWx0eS1mcmVlIHBhdGVudAorICAgICAgbGljZW5zZSB1bmRlciBMaWNlbnNlZCBQYXRlbnRzIHRvIG1ha2UsIHVzZSwgc2VsbCwgb2ZmZXIgdG8gc2VsbCwKKyAgICAgIGltcG9ydCBhbmQgb3RoZXJ3aXNlIHRyYW5zZmVyIHRoZSBDb250cmlidXRpb24gb2Ygc3VjaCBDb250cmlidXRvciwKKyAgICAgIGlmIGFueSwgaW4gU291cmNlIENvZGUgb3Igb3RoZXIgZm9ybS4gVGhpcyBwYXRlbnQgbGljZW5zZSBzaGFsbAorICAgICAgYXBwbHkgdG8gdGhlIGNvbWJpbmF0aW9uIG9mIHRoZSBDb250cmlidXRpb24gYW5kIHRoZSBQcm9ncmFtIGlmLCBhdAorICAgICAgdGhlIHRpbWUgdGhlIENvbnRyaWJ1dGlvbiBpcyBhZGRlZCBieSB0aGUgQ29udHJpYnV0b3IsIHN1Y2ggYWRkaXRpb24KKyAgICAgIG9mIHRoZSBDb250cmlidXRpb24gY2F1c2VzIHN1Y2ggY29tYmluYXRpb24gdG8gYmUgY292ZXJlZCBieSB0aGUKKyAgICAgIExpY2Vuc2VkIFBhdGVudHMuIFRoZSBwYXRlbnQgbGljZW5zZSBzaGFsbCBub3QgYXBwbHkgdG8gYW55IG90aGVyCisgICAgICBjb21iaW5hdGlvbnMgd2hpY2ggaW5jbHVkZSB0aGUgQ29udHJpYnV0aW9uLiBObyBoYXJkd2FyZSBwZXIgc2UgaXMKKyAgICAgIGxpY2Vuc2VkIGhlcmV1bmRlci4KKworICAgICAgYykgUmVjaXBpZW50IHVuZGVyc3RhbmRzIHRoYXQgYWx0aG91Z2ggZWFjaCBDb250cmlidXRvciBncmFudHMgdGhlCisgICAgICBsaWNlbnNlcyB0byBpdHMgQ29udHJpYnV0aW9ucyBzZXQgZm9ydGggaGVyZWluLCBubyBhc3N1cmFuY2VzIGFyZQorICAgICAgcHJvdmlkZWQgYnkgYW55IENvbnRyaWJ1dG9yIHRoYXQgdGhlIFByb2dyYW0gZG9lcyBub3QgaW5mcmluZ2UgdGhlCisgICAgICBwYXRlbnQgb3Igb3RoZXIgaW50ZWxsZWN0dWFsIHByb3BlcnR5IHJpZ2h0cyBvZiBhbnkgb3RoZXIgZW50aXR5LgorICAgICAgRWFjaCBDb250cmlidXRvciBkaXNjbGFpbXMgYW55IGxpYWJpbGl0eSB0byBSZWNpcGllbnQgZm9yIGNsYWltcworICAgICAgYnJvdWdodCBieSBhbnkgb3RoZXIgZW50aXR5IGJhc2VkIG9uIGluZnJpbmdlbWVudCBvZiBpbnRlbGxlY3R1YWwKKyAgICAgIHByb3BlcnR5IHJpZ2h0cyBvciBvdGhlcndpc2UuIEFzIGEgY29uZGl0aW9uIHRvIGV4ZXJjaXNpbmcgdGhlCisgICAgICByaWdodHMgYW5kIGxpY2Vuc2VzIGdyYW50ZWQgaGVyZXVuZGVyLCBlYWNoIFJlY2lwaWVudCBoZXJlYnkKKyAgICAgIGFzc3VtZXMgc29sZSByZXNwb25zaWJpbGl0eSB0byBzZWN1cmUgYW55IG90aGVyIGludGVsbGVjdHVhbAorICAgICAgcHJvcGVydHkgcmlnaHRzIG5lZWRlZCwgaWYgYW55LiBGb3IgZXhhbXBsZSwgaWYgYSB0aGlyZCBwYXJ0eQorICAgICAgcGF0ZW50IGxpY2Vuc2UgaXMgcmVxdWlyZWQgdG8gYWxsb3cgUmVjaXBpZW50IHRvIERpc3RyaWJ1dGUgdGhlCisgICAgICBQcm9ncmFtLCBpdCBpcyBSZWNpcGllbnQncyByZXNwb25zaWJpbGl0eSB0byBhY3F1aXJlIHRoYXQgbGljZW5zZQorICAgICAgYmVmb3JlIGRpc3RyaWJ1dGluZyB0aGUgUHJvZ3JhbS4KKworICAgICAgZCkgRWFjaCBDb250cmlidXRvciByZXByZXNlbnRzIHRoYXQgdG8gaXRzIGtub3dsZWRnZSBpdCBoYXMKKyAgICAgIHN1ZmZpY2llbnQgY29weXJpZ2h0IHJpZ2h0cyBpbiBpdHMgQ29udHJpYnV0aW9uLCBpZiBhbnksIHRvIGdyYW50CisgICAgICB0aGUgY29weXJpZ2h0IGxpY2Vuc2Ugc2V0IGZvcnRoIGluIHRoaXMgQWdyZWVtZW50LgorCisgICAgICBlKSBOb3R3aXRoc3RhbmRpbmcgdGhlIHRlcm1zIG9mIGFueSBTZWNvbmRhcnkgTGljZW5zZSwgbm8KKyAgICAgIENvbnRyaWJ1dG9yIG1ha2VzIGFkZGl0aW9uYWwgZ3JhbnRzIHRvIGFueSBSZWNpcGllbnQgKG90aGVyIHRoYW4KKyAgICAgIHRob3NlIHNldCBmb3J0aCBpbiB0aGlzIEFncmVlbWVudCkgYXMgYSByZXN1bHQgb2Ygc3VjaCBSZWNpcGllbnQncworICAgICAgcmVjZWlwdCBvZiB0aGUgUHJvZ3JhbSB1bmRlciB0aGUgdGVybXMgb2YgYSBTZWNvbmRhcnkgTGljZW5zZQorICAgICAgKGlmIHBlcm1pdHRlZCB1bmRlciB0aGUgdGVybXMgb2YgU2VjdGlvbiAzKS4KKworICAgIDMuIFJFUVVJUkVNRU5UUworCisgICAgMy4xIElmIGEgQ29udHJpYnV0b3IgRGlzdHJpYnV0ZXMgdGhlIFByb2dyYW0gaW4gYW55IGZvcm0sIHRoZW46CisKKyAgICAgIGEpIHRoZSBQcm9ncmFtIG11c3QgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSBhcyBTb3VyY2UgQ29kZSwgaW4KKyAgICAgIGFjY29yZGFuY2Ugd2l0aCBzZWN0aW9uIDMuMiwgYW5kIHRoZSBDb250cmlidXRvciBtdXN0IGFjY29tcGFueQorICAgICAgdGhlIFByb2dyYW0gd2l0aCBhIHN0YXRlbWVudCB0aGF0IHRoZSBTb3VyY2UgQ29kZSBmb3IgdGhlIFByb2dyYW0KKyAgICAgIGlzIGF2YWlsYWJsZSB1bmRlciB0aGlzIEFncmVlbWVudCwgYW5kIGluZm9ybXMgUmVjaXBpZW50cyBob3cgdG8KKyAgICAgIG9idGFpbiBpdCBpbiBhIHJlYXNvbmFibGUgbWFubmVyIG9uIG9yIHRocm91Z2ggYSBtZWRpdW0gY3VzdG9tYXJpbHkKKyAgICAgIHVzZWQgZm9yIHNvZnR3YXJlIGV4Y2hhbmdlOyBhbmQKKworICAgICAgYikgdGhlIENvbnRyaWJ1dG9yIG1heSBEaXN0cmlidXRlIHRoZSBQcm9ncmFtIHVuZGVyIGEgbGljZW5zZQorICAgICAgZGlmZmVyZW50IHRoYW4gdGhpcyBBZ3JlZW1lbnQsIHByb3ZpZGVkIHRoYXQgc3VjaCBsaWNlbnNlOgorICAgICAgICAgaSkgZWZmZWN0aXZlbHkgZGlzY2xhaW1zIG9uIGJlaGFsZiBvZiBhbGwgb3RoZXIgQ29udHJpYnV0b3JzIGFsbAorICAgICAgICAgd2FycmFudGllcyBhbmQgY29uZGl0aW9ucywgZXhwcmVzcyBhbmQgaW1wbGllZCwgaW5jbHVkaW5nCisgICAgICAgICB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMgb2YgdGl0bGUgYW5kIG5vbi1pbmZyaW5nZW1lbnQsIGFuZAorICAgICAgICAgaW1wbGllZCB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMgb2YgbWVyY2hhbnRhYmlsaXR5IGFuZCBmaXRuZXNzCisgICAgICAgICBmb3IgYSBwYXJ0aWN1bGFyIHB1cnBvc2U7CisKKyAgICAgICAgIGlpKSBlZmZlY3RpdmVseSBleGNsdWRlcyBvbiBiZWhhbGYgb2YgYWxsIG90aGVyIENvbnRyaWJ1dG9ycyBhbGwKKyAgICAgICAgIGxpYWJpbGl0eSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGRpcmVjdCwgaW5kaXJlY3QsIHNwZWNpYWwsCisgICAgICAgICBpbmNpZGVudGFsIGFuZCBjb25zZXF1ZW50aWFsIGRhbWFnZXMsIHN1Y2ggYXMgbG9zdCBwcm9maXRzOworCisgICAgICAgICBpaWkpIGRvZXMgbm90IGF0dGVtcHQgdG8gbGltaXQgb3IgYWx0ZXIgdGhlIHJlY2lwaWVudHMnIHJpZ2h0cworICAgICAgICAgaW4gdGhlIFNvdXJjZSBDb2RlIHVuZGVyIHNlY3Rpb24gMy4yOyBhbmQKKworICAgICAgICAgaXYpIHJlcXVpcmVzIGFueSBzdWJzZXF1ZW50IGRpc3RyaWJ1dGlvbiBvZiB0aGUgUHJvZ3JhbSBieSBhbnkKKyAgICAgICAgIHBhcnR5IHRvIGJlIHVuZGVyIGEgbGljZW5zZSB0aGF0IHNhdGlzZmllcyB0aGUgcmVxdWlyZW1lbnRzCisgICAgICAgICBvZiB0aGlzIHNlY3Rpb24gMy4KKworICAgIDMuMiBXaGVuIHRoZSBQcm9ncmFtIGlzIERpc3RyaWJ1dGVkIGFzIFNvdXJjZSBDb2RlOgorCisgICAgICBhKSBpdCBtdXN0IGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoaXMgQWdyZWVtZW50LCBvciBpZiB0aGUKKyAgICAgIFByb2dyYW0gKGkpIGlzIGNvbWJpbmVkIHdpdGggb3RoZXIgbWF0ZXJpYWwgaW4gYSBzZXBhcmF0ZSBmaWxlIG9yCisgICAgICBmaWxlcyBtYWRlIGF2YWlsYWJsZSB1bmRlciBhIFNlY29uZGFyeSBMaWNlbnNlLCBhbmQgKGlpKSB0aGUgaW5pdGlhbAorICAgICAgQ29udHJpYnV0b3IgYXR0YWNoZWQgdG8gdGhlIFNvdXJjZSBDb2RlIHRoZSBub3RpY2UgZGVzY3JpYmVkIGluCisgICAgICBFeGhpYml0IEEgb2YgdGhpcyBBZ3JlZW1lbnQsIHRoZW4gdGhlIFByb2dyYW0gbWF5IGJlIG1hZGUgYXZhaWxhYmxlCisgICAgICB1bmRlciB0aGUgdGVybXMgb2Ygc3VjaCBTZWNvbmRhcnkgTGljZW5zZXMsIGFuZAorCisgICAgICBiKSBhIGNvcHkgb2YgdGhpcyBBZ3JlZW1lbnQgbXVzdCBiZSBpbmNsdWRlZCB3aXRoIGVhY2ggY29weSBvZgorICAgICAgdGhlIFByb2dyYW0uCisKKyAgICAzLjMgQ29udHJpYnV0b3JzIG1heSBub3QgcmVtb3ZlIG9yIGFsdGVyIGFueSBjb3B5cmlnaHQsIHBhdGVudCwKKyAgICB0cmFkZW1hcmssIGF0dHJpYnV0aW9uIG5vdGljZXMsIGRpc2NsYWltZXJzIG9mIHdhcnJhbnR5LCBvciBsaW1pdGF0aW9ucworICAgIG9mIGxpYWJpbGl0eSAoIm5vdGljZXMiKSBjb250YWluZWQgd2l0aGluIHRoZSBQcm9ncmFtIGZyb20gYW55IGNvcHkgb2YKKyAgICB0aGUgUHJvZ3JhbSB3aGljaCB0aGV5IERpc3RyaWJ1dGUsIHByb3ZpZGVkIHRoYXQgQ29udHJpYnV0b3JzIG1heSBhZGQKKyAgICB0aGVpciBvd24gYXBwcm9wcmlhdGUgbm90aWNlcy4KKworICAgIDQuIENPTU1FUkNJQUwgRElTVFJJQlVUSU9OCisKKyAgICBDb21tZXJjaWFsIGRpc3RyaWJ1dG9ycyBvZiBzb2Z0d2FyZSBtYXkgYWNjZXB0IGNlcnRhaW4gcmVzcG9uc2liaWxpdGllcworICAgIHdpdGggcmVzcGVjdCB0byBlbmQgdXNlcnMsIGJ1c2luZXNzIHBhcnRuZXJzIGFuZCB0aGUgbGlrZS4gV2hpbGUgdGhpcworICAgIGxpY2Vuc2UgaXMgaW50ZW5kZWQgdG8gZmFjaWxpdGF0ZSB0aGUgY29tbWVyY2lhbCB1c2Ugb2YgdGhlIFByb2dyYW0sCisgICAgdGhlIENvbnRyaWJ1dG9yIHdobyBpbmNsdWRlcyB0aGUgUHJvZ3JhbSBpbiBhIGNvbW1lcmNpYWwgcHJvZHVjdAorICAgIG9mZmVyaW5nIHNob3VsZCBkbyBzbyBpbiBhIG1hbm5lciB3aGljaCBkb2VzIG5vdCBjcmVhdGUgcG90ZW50aWFsCisgICAgbGlhYmlsaXR5IGZvciBvdGhlciBDb250cmlidXRvcnMuIFRoZXJlZm9yZSwgaWYgYSBDb250cmlidXRvciBpbmNsdWRlcworICAgIHRoZSBQcm9ncmFtIGluIGEgY29tbWVyY2lhbCBwcm9kdWN0IG9mZmVyaW5nLCBzdWNoIENvbnRyaWJ1dG9yCisgICAgKCJDb21tZXJjaWFsIENvbnRyaWJ1dG9yIikgaGVyZWJ5IGFncmVlcyB0byBkZWZlbmQgYW5kIGluZGVtbmlmeSBldmVyeQorICAgIG90aGVyIENvbnRyaWJ1dG9yICgiSW5kZW1uaWZpZWQgQ29udHJpYnV0b3IiKSBhZ2FpbnN0IGFueSBsb3NzZXMsCisgICAgZGFtYWdlcyBhbmQgY29zdHMgKGNvbGxlY3RpdmVseSAiTG9zc2VzIikgYXJpc2luZyBmcm9tIGNsYWltcywgbGF3c3VpdHMKKyAgICBhbmQgb3RoZXIgbGVnYWwgYWN0aW9ucyBicm91Z2h0IGJ5IGEgdGhpcmQgcGFydHkgYWdhaW5zdCB0aGUgSW5kZW1uaWZpZWQKKyAgICBDb250cmlidXRvciB0byB0aGUgZXh0ZW50IGNhdXNlZCBieSB0aGUgYWN0cyBvciBvbWlzc2lvbnMgb2Ygc3VjaAorICAgIENvbW1lcmNpYWwgQ29udHJpYnV0b3IgaW4gY29ubmVjdGlvbiB3aXRoIGl0cyBkaXN0cmlidXRpb24gb2YgdGhlIFByb2dyYW0KKyAgICBpbiBhIGNvbW1lcmNpYWwgcHJvZHVjdCBvZmZlcmluZy4gVGhlIG9ibGlnYXRpb25zIGluIHRoaXMgc2VjdGlvbiBkbyBub3QKKyAgICBhcHBseSB0byBhbnkgY2xhaW1zIG9yIExvc3NlcyByZWxhdGluZyB0byBhbnkgYWN0dWFsIG9yIGFsbGVnZWQKKyAgICBpbnRlbGxlY3R1YWwgcHJvcGVydHkgaW5mcmluZ2VtZW50LiBJbiBvcmRlciB0byBxdWFsaWZ5LCBhbiBJbmRlbW5pZmllZAorICAgIENvbnRyaWJ1dG9yIG11c3Q6IGEpIHByb21wdGx5IG5vdGlmeSB0aGUgQ29tbWVyY2lhbCBDb250cmlidXRvciBpbgorICAgIHdyaXRpbmcgb2Ygc3VjaCBjbGFpbSwgYW5kIGIpIGFsbG93IHRoZSBDb21tZXJjaWFsIENvbnRyaWJ1dG9yIHRvIGNvbnRyb2wsCisgICAgYW5kIGNvb3BlcmF0ZSB3aXRoIHRoZSBDb21tZXJjaWFsIENvbnRyaWJ1dG9yIGluLCB0aGUgZGVmZW5zZSBhbmQgYW55CisgICAgcmVsYXRlZCBzZXR0bGVtZW50IG5lZ290aWF0aW9ucy4gVGhlIEluZGVtbmlmaWVkIENvbnRyaWJ1dG9yIG1heQorICAgIHBhcnRpY2lwYXRlIGluIGFueSBzdWNoIGNsYWltIGF0IGl0cyBvd24gZXhwZW5zZS4KKworICAgIEZvciBleGFtcGxlLCBhIENvbnRyaWJ1dG9yIG1pZ2h0IGluY2x1ZGUgdGhlIFByb2dyYW0gaW4gYSBjb21tZXJjaWFsCisgICAgcHJvZHVjdCBvZmZlcmluZywgUHJvZHVjdCBYLiBUaGF0IENvbnRyaWJ1dG9yIGlzIHRoZW4gYSBDb21tZXJjaWFsCisgICAgQ29udHJpYnV0b3IuIElmIHRoYXQgQ29tbWVyY2lhbCBDb250cmlidXRvciB0aGVuIG1ha2VzIHBlcmZvcm1hbmNlCisgICAgY2xhaW1zLCBvciBvZmZlcnMgd2FycmFudGllcyByZWxhdGVkIHRvIFByb2R1Y3QgWCwgdGhvc2UgcGVyZm9ybWFuY2UKKyAgICBjbGFpbXMgYW5kIHdhcnJhbnRpZXMgYXJlIHN1Y2ggQ29tbWVyY2lhbCBDb250cmlidXRvcidzIHJlc3BvbnNpYmlsaXR5CisgICAgYWxvbmUuIFVuZGVyIHRoaXMgc2VjdGlvbiwgdGhlIENvbW1lcmNpYWwgQ29udHJpYnV0b3Igd291bGQgaGF2ZSB0bworICAgIGRlZmVuZCBjbGFpbXMgYWdhaW5zdCB0aGUgb3RoZXIgQ29udHJpYnV0b3JzIHJlbGF0ZWQgdG8gdGhvc2UgcGVyZm9ybWFuY2UKKyAgICBjbGFpbXMgYW5kIHdhcnJhbnRpZXMsIGFuZCBpZiBhIGNvdXJ0IHJlcXVpcmVzIGFueSBvdGhlciBDb250cmlidXRvciB0bworICAgIHBheSBhbnkgZGFtYWdlcyBhcyBhIHJlc3VsdCwgdGhlIENvbW1lcmNpYWwgQ29udHJpYnV0b3IgbXVzdCBwYXkKKyAgICB0aG9zZSBkYW1hZ2VzLgorCisgICAgNS4gTk8gV0FSUkFOVFkKKworICAgIEVYQ0VQVCBBUyBFWFBSRVNTTFkgU0VUIEZPUlRIIElOIFRISVMgQUdSRUVNRU5ULCBBTkQgVE8gVEhFIEVYVEVOVAorICAgIFBFUk1JVFRFRCBCWSBBUFBMSUNBQkxFIExBVywgVEhFIFBST0dSQU0gSVMgUFJPVklERUQgT04gQU4gIkFTIElTIgorICAgIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgRUlUSEVSIEVYUFJFU1MgT1IKKyAgICBJTVBMSUVEIElOQ0xVRElORywgV0lUSE9VVCBMSU1JVEFUSU9OLCBBTlkgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GCisgICAgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSBPUiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIKKyAgICBQVVJQT1NFLiBFYWNoIFJlY2lwaWVudCBpcyBzb2xlbHkgcmVzcG9uc2libGUgZm9yIGRldGVybWluaW5nIHRoZQorICAgIGFwcHJvcHJpYXRlbmVzcyBvZiB1c2luZyBhbmQgZGlzdHJpYnV0aW5nIHRoZSBQcm9ncmFtIGFuZCBhc3N1bWVzIGFsbAorICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBpdHMgZXhlcmNpc2Ugb2YgcmlnaHRzIHVuZGVyIHRoaXMgQWdyZWVtZW50LAorICAgIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIHJpc2tzIGFuZCBjb3N0cyBvZiBwcm9ncmFtIGVycm9ycywKKyAgICBjb21wbGlhbmNlIHdpdGggYXBwbGljYWJsZSBsYXdzLCBkYW1hZ2UgdG8gb3IgbG9zcyBvZiBkYXRhLCBwcm9ncmFtcworICAgIG9yIGVxdWlwbWVudCwgYW5kIHVuYXZhaWxhYmlsaXR5IG9yIGludGVycnVwdGlvbiBvZiBvcGVyYXRpb25zLgorCisgICAgNi4gRElTQ0xBSU1FUiBPRiBMSUFCSUxJVFkKKworICAgIEVYQ0VQVCBBUyBFWFBSRVNTTFkgU0VUIEZPUlRIIElOIFRISVMgQUdSRUVNRU5ULCBBTkQgVE8gVEhFIEVYVEVOVAorICAgIFBFUk1JVFRFRCBCWSBBUFBMSUNBQkxFIExBVywgTkVJVEhFUiBSRUNJUElFTlQgTk9SIEFOWSBDT05UUklCVVRPUlMKKyAgICBTSEFMTCBIQVZFIEFOWSBMSUFCSUxJVFkgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLAorICAgIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcgV0lUSE9VVCBMSU1JVEFUSU9OIExPU1QKKyAgICBQUk9GSVRTKSwgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOCisgICAgQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkKKyAgICBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT1IgRElTVFJJQlVUSU9OIE9GIFRIRSBQUk9HUkFNIE9SIFRIRQorICAgIEVYRVJDSVNFIE9GIEFOWSBSSUdIVFMgR1JBTlRFRCBIRVJFVU5ERVIsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUKKyAgICBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRVMuCisKKyAgICA3LiBHRU5FUkFMCisKKyAgICBJZiBhbnkgcHJvdmlzaW9uIG9mIHRoaXMgQWdyZWVtZW50IGlzIGludmFsaWQgb3IgdW5lbmZvcmNlYWJsZSB1bmRlcgorICAgIGFwcGxpY2FibGUgbGF3LCBpdCBzaGFsbCBub3QgYWZmZWN0IHRoZSB2YWxpZGl0eSBvciBlbmZvcmNlYWJpbGl0eSBvZgorICAgIHRoZSByZW1haW5kZXIgb2YgdGhlIHRlcm1zIG9mIHRoaXMgQWdyZWVtZW50LCBhbmQgd2l0aG91dCBmdXJ0aGVyCisgICAgYWN0aW9uIGJ5IHRoZSBwYXJ0aWVzIGhlcmV0bywgc3VjaCBwcm92aXNpb24gc2hhbGwgYmUgcmVmb3JtZWQgdG8gdGhlCisgICAgbWluaW11bSBleHRlbnQgbmVjZXNzYXJ5IHRvIG1ha2Ugc3VjaCBwcm92aXNpb24gdmFsaWQgYW5kIGVuZm9yY2VhYmxlLgorCisgICAgSWYgUmVjaXBpZW50IGluc3RpdHV0ZXMgcGF0ZW50IGxpdGlnYXRpb24gYWdhaW5zdCBhbnkgZW50aXR5CisgICAgKGluY2x1ZGluZyBhIGNyb3NzLWNsYWltIG9yIGNvdW50ZXJjbGFpbSBpbiBhIGxhd3N1aXQpIGFsbGVnaW5nIHRoYXQgdGhlCisgICAgUHJvZ3JhbSBpdHNlbGYgKGV4Y2x1ZGluZyBjb21iaW5hdGlvbnMgb2YgdGhlIFByb2dyYW0gd2l0aCBvdGhlciBzb2Z0d2FyZQorICAgIG9yIGhhcmR3YXJlKSBpbmZyaW5nZXMgc3VjaCBSZWNpcGllbnQncyBwYXRlbnQocyksIHRoZW4gc3VjaCBSZWNpcGllbnQncworICAgIHJpZ2h0cyBncmFudGVkIHVuZGVyIFNlY3Rpb24gMihiKSBzaGFsbCB0ZXJtaW5hdGUgYXMgb2YgdGhlIGRhdGUgc3VjaAorICAgIGxpdGlnYXRpb24gaXMgZmlsZWQuCisKKyAgICBBbGwgUmVjaXBpZW50J3MgcmlnaHRzIHVuZGVyIHRoaXMgQWdyZWVtZW50IHNoYWxsIHRlcm1pbmF0ZSBpZiBpdAorICAgIGZhaWxzIHRvIGNvbXBseSB3aXRoIGFueSBvZiB0aGUgbWF0ZXJpYWwgdGVybXMgb3IgY29uZGl0aW9ucyBvZiB0aGlzCisgICAgQWdyZWVtZW50IGFuZCBkb2VzIG5vdCBjdXJlIHN1Y2ggZmFpbHVyZSBpbiBhIHJlYXNvbmFibGUgcGVyaW9kIG9mCisgICAgdGltZSBhZnRlciBiZWNvbWluZyBhd2FyZSBvZiBzdWNoIG5vbmNvbXBsaWFuY2UuIElmIGFsbCBSZWNpcGllbnQncworICAgIHJpZ2h0cyB1bmRlciB0aGlzIEFncmVlbWVudCB0ZXJtaW5hdGUsIFJlY2lwaWVudCBhZ3JlZXMgdG8gY2Vhc2UgdXNlCisgICAgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgUHJvZ3JhbSBhcyBzb29uIGFzIHJlYXNvbmFibHkgcHJhY3RpY2FibGUuCisgICAgSG93ZXZlciwgUmVjaXBpZW50J3Mgb2JsaWdhdGlvbnMgdW5kZXIgdGhpcyBBZ3JlZW1lbnQgYW5kIGFueSBsaWNlbnNlcworICAgIGdyYW50ZWQgYnkgUmVjaXBpZW50IHJlbGF0aW5nIHRvIHRoZSBQcm9ncmFtIHNoYWxsIGNvbnRpbnVlIGFuZCBzdXJ2aXZlLgorCisgICAgRXZlcnlvbmUgaXMgcGVybWl0dGVkIHRvIGNvcHkgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoaXMgQWdyZWVtZW50LAorICAgIGJ1dCBpbiBvcmRlciB0byBhdm9pZCBpbmNvbnNpc3RlbmN5IHRoZSBBZ3JlZW1lbnQgaXMgY29weXJpZ2h0ZWQgYW5kCisgICAgbWF5IG9ubHkgYmUgbW9kaWZpZWQgaW4gdGhlIGZvbGxvd2luZyBtYW5uZXIuIFRoZSBBZ3JlZW1lbnQgU3Rld2FyZAorICAgIHJlc2VydmVzIHRoZSByaWdodCB0byBwdWJsaXNoIG5ldyB2ZXJzaW9ucyAoaW5jbHVkaW5nIHJldmlzaW9ucykgb2YKKyAgICB0aGlzIEFncmVlbWVudCBmcm9tIHRpbWUgdG8gdGltZS4gTm8gb25lIG90aGVyIHRoYW4gdGhlIEFncmVlbWVudAorICAgIFN0ZXdhcmQgaGFzIHRoZSByaWdodCB0byBtb2RpZnkgdGhpcyBBZ3JlZW1lbnQuIFRoZSBFY2xpcHNlIEZvdW5kYXRpb24KKyAgICBpcyB0aGUgaW5pdGlhbCBBZ3JlZW1lbnQgU3Rld2FyZC4gVGhlIEVjbGlwc2UgRm91bmRhdGlvbiBtYXkgYXNzaWduIHRoZQorICAgIHJlc3BvbnNpYmlsaXR5IHRvIHNlcnZlIGFzIHRoZSBBZ3JlZW1lbnQgU3Rld2FyZCB0byBhIHN1aXRhYmxlIHNlcGFyYXRlCisgICAgZW50aXR5LiBFYWNoIG5ldyB2ZXJzaW9uIG9mIHRoZSBBZ3JlZW1lbnQgd2lsbCBiZSBnaXZlbiBhIGRpc3Rpbmd1aXNoaW5nCisgICAgdmVyc2lvbiBudW1iZXIuIFRoZSBQcm9ncmFtIChpbmNsdWRpbmcgQ29udHJpYnV0aW9ucykgbWF5IGFsd2F5cyBiZQorICAgIERpc3RyaWJ1dGVkIHN1YmplY3QgdG8gdGhlIHZlcnNpb24gb2YgdGhlIEFncmVlbWVudCB1bmRlciB3aGljaCBpdCB3YXMKKyAgICByZWNlaXZlZC4gSW4gYWRkaXRpb24sIGFmdGVyIGEgbmV3IHZlcnNpb24gb2YgdGhlIEFncmVlbWVudCBpcyBwdWJsaXNoZWQsCisgICAgQ29udHJpYnV0b3IgbWF5IGVsZWN0IHRvIERpc3RyaWJ1dGUgdGhlIFByb2dyYW0gKGluY2x1ZGluZyBpdHMKKyAgICBDb250cmlidXRpb25zKSB1bmRlciB0aGUgbmV3IHZlcnNpb24uCisKKyAgICBFeGNlcHQgYXMgZXhwcmVzc2x5IHN0YXRlZCBpbiBTZWN0aW9ucyAyKGEpIGFuZCAyKGIpIGFib3ZlLCBSZWNpcGllbnQKKyAgICByZWNlaXZlcyBubyByaWdodHMgb3IgbGljZW5zZXMgdG8gdGhlIGludGVsbGVjdHVhbCBwcm9wZXJ0eSBvZiBhbnkKKyAgICBDb250cmlidXRvciB1bmRlciB0aGlzIEFncmVlbWVudCwgd2hldGhlciBleHByZXNzbHksIGJ5IGltcGxpY2F0aW9uLAorICAgIGVzdG9wcGVsIG9yIG90aGVyd2lzZS4gQWxsIHJpZ2h0cyBpbiB0aGUgUHJvZ3JhbSBub3QgZXhwcmVzc2x5IGdyYW50ZWQKKyAgICB1bmRlciB0aGlzIEFncmVlbWVudCBhcmUgcmVzZXJ2ZWQuIE5vdGhpbmcgaW4gdGhpcyBBZ3JlZW1lbnQgaXMgaW50ZW5kZWQKKyAgICB0byBiZSBlbmZvcmNlYWJsZSBieSBhbnkgZW50aXR5IHRoYXQgaXMgbm90IGEgQ29udHJpYnV0b3Igb3IgUmVjaXBpZW50LgorICAgIE5vIHRoaXJkLXBhcnR5IGJlbmVmaWNpYXJ5IHJpZ2h0cyBhcmUgY3JlYXRlZCB1bmRlciB0aGlzIEFncmVlbWVudC4KKworICAgIEV4aGliaXQgQSAtIEZvcm0gb2YgU2Vjb25kYXJ5IExpY2Vuc2VzIE5vdGljZQorCisgICAgIlRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyAKKyAgICBTZWNvbmRhcnkgTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIAorICAgIGluIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlLCB2LiAyLjAgYXJlIHNhdGlzZmllZDoge25hbWUgbGljZW5zZShzKSwKKyAgICB2ZXJzaW9uKHMpLCBhbmQgZXhjZXB0aW9ucyBvciBhZGRpdGlvbmFsIHBlcm1pc3Npb25zIGhlcmV9LiIKKworICAgICAgU2ltcGx5IGluY2x1ZGluZyBhIGNvcHkgb2YgdGhpcyBBZ3JlZW1lbnQsIGluY2x1ZGluZyB0aGlzIEV4aGliaXQgQQorICAgICAgaXMgbm90IHN1ZmZpY2llbnQgdG8gbGljZW5zZSB0aGUgU291cmNlIENvZGUgdW5kZXIgU2Vjb25kYXJ5IExpY2Vuc2VzLgorCisgICAgICBJZiBpdCBpcyBub3QgcG9zc2libGUgb3IgZGVzaXJhYmxlIHRvIHB1dCB0aGUgbm90aWNlIGluIGEgcGFydGljdWxhcgorICAgICAgZmlsZSwgdGhlbiBZb3UgbWF5IGluY2x1ZGUgdGhlIG5vdGljZSBpbiBhIGxvY2F0aW9uIChzdWNoIGFzIGEgTElDRU5TRQorICAgICAgZmlsZSBpbiBhIHJlbGV2YW50IGRpcmVjdG9yeSkgd2hlcmUgYSByZWNpcGllbnQgd291bGQgYmUgbGlrZWx5IHRvCisgICAgICBsb29rIGZvciBzdWNoIGEgbm90aWNlLgorCisgICAgICBZb3UgbWF5IGFkZCBhZGRpdGlvbmFsIGFjY3VyYXRlIG5vdGljZXMgb2YgY29weXJpZ2h0IG93bmVyc2hpcC4KKworLS0tCisKKyMjICAgIFRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSAoR1BMKSBWZXJzaW9uIDIsIEp1bmUgMTk5MQorCisgICAgQ29weXJpZ2h0IChDKSAxOTg5LCAxOTkxIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgSW5jLgorICAgIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IKKyAgICBCb3N0b24sIE1BIDAyMTEwLTEzMzUKKyAgICBVU0EKKworICAgIEV2ZXJ5b25lIGlzIHBlcm1pdHRlZCB0byBjb3B5IGFuZCBkaXN0cmlidXRlIHZlcmJhdGltIGNvcGllcworICAgIG9mIHRoaXMgbGljZW5zZSBkb2N1bWVudCwgYnV0IGNoYW5naW5nIGl0IGlzIG5vdCBhbGxvd2VkLgorCisgICAgUHJlYW1ibGUKKworICAgIFRoZSBsaWNlbnNlcyBmb3IgbW9zdCBzb2Z0d2FyZSBhcmUgZGVzaWduZWQgdG8gdGFrZSBhd2F5IHlvdXIgZnJlZWRvbSB0bworICAgIHNoYXJlIGFuZCBjaGFuZ2UgaXQuIEJ5IGNvbnRyYXN0LCB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgaXMKKyAgICBpbnRlbmRlZCB0byBndWFyYW50ZWUgeW91ciBmcmVlZG9tIHRvIHNoYXJlIGFuZCBjaGFuZ2UgZnJlZSBzb2Z0d2FyZS0tdG8KKyAgICBtYWtlIHN1cmUgdGhlIHNvZnR3YXJlIGlzIGZyZWUgZm9yIGFsbCBpdHMgdXNlcnMuIFRoaXMgR2VuZXJhbCBQdWJsaWMKKyAgICBMaWNlbnNlIGFwcGxpZXMgdG8gbW9zdCBvZiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uJ3Mgc29mdHdhcmUgYW5kCisgICAgdG8gYW55IG90aGVyIHByb2dyYW0gd2hvc2UgYXV0aG9ycyBjb21taXQgdG8gdXNpbmcgaXQuIChTb21lIG90aGVyIEZyZWUKKyAgICBTb2Z0d2FyZSBGb3VuZGF0aW9uIHNvZnR3YXJlIGlzIGNvdmVyZWQgYnkgdGhlIEdOVSBMaWJyYXJ5IEdlbmVyYWwKKyAgICBQdWJsaWMgTGljZW5zZSBpbnN0ZWFkLikgWW91IGNhbiBhcHBseSBpdCB0byB5b3VyIHByb2dyYW1zLCB0b28uCisKKyAgICBXaGVuIHdlIHNwZWFrIG9mIGZyZWUgc29mdHdhcmUsIHdlIGFyZSByZWZlcnJpbmcgdG8gZnJlZWRvbSwgbm90IHByaWNlLgorICAgIE91ciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlcyBhcmUgZGVzaWduZWQgdG8gbWFrZSBzdXJlIHRoYXQgeW91IGhhdmUgdGhlCisgICAgZnJlZWRvbSB0byBkaXN0cmlidXRlIGNvcGllcyBvZiBmcmVlIHNvZnR3YXJlIChhbmQgY2hhcmdlIGZvciB0aGlzCisgICAgc2VydmljZSBpZiB5b3Ugd2lzaCksIHRoYXQgeW91IHJlY2VpdmUgc291cmNlIGNvZGUgb3IgY2FuIGdldCBpdCBpZiB5b3UKKyAgICB3YW50IGl0LCB0aGF0IHlvdSBjYW4gY2hhbmdlIHRoZSBzb2Z0d2FyZSBvciB1c2UgcGllY2VzIG9mIGl0IGluIG5ldworICAgIGZyZWUgcHJvZ3JhbXM7IGFuZCB0aGF0IHlvdSBrbm93IHlvdSBjYW4gZG8gdGhlc2UgdGhpbmdzLgorCisgICAgVG8gcHJvdGVjdCB5b3VyIHJpZ2h0cywgd2UgbmVlZCB0byBtYWtlIHJlc3RyaWN0aW9ucyB0aGF0IGZvcmJpZCBhbnlvbmUKKyAgICB0byBkZW55IHlvdSB0aGVzZSByaWdodHMgb3IgdG8gYXNrIHlvdSB0byBzdXJyZW5kZXIgdGhlIHJpZ2h0cy4gVGhlc2UKKyAgICByZXN0cmljdGlvbnMgdHJhbnNsYXRlIHRvIGNlcnRhaW4gcmVzcG9uc2liaWxpdGllcyBmb3IgeW91IGlmIHlvdQorICAgIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZSBzb2Z0d2FyZSwgb3IgaWYgeW91IG1vZGlmeSBpdC4KKworICAgIEZvciBleGFtcGxlLCBpZiB5b3UgZGlzdHJpYnV0ZSBjb3BpZXMgb2Ygc3VjaCBhIHByb2dyYW0sIHdoZXRoZXIgZ3JhdGlzCisgICAgb3IgZm9yIGEgZmVlLCB5b3UgbXVzdCBnaXZlIHRoZSByZWNpcGllbnRzIGFsbCB0aGUgcmlnaHRzIHRoYXQgeW91IGhhdmUuCisgICAgWW91IG11c3QgbWFrZSBzdXJlIHRoYXQgdGhleSwgdG9vLCByZWNlaXZlIG9yIGNhbiBnZXQgdGhlIHNvdXJjZSBjb2RlLgorICAgIEFuZCB5b3UgbXVzdCBzaG93IHRoZW0gdGhlc2UgdGVybXMgc28gdGhleSBrbm93IHRoZWlyIHJpZ2h0cy4KKworICAgIFdlIHByb3RlY3QgeW91ciByaWdodHMgd2l0aCB0d28gc3RlcHM6ICgxKSBjb3B5cmlnaHQgdGhlIHNvZnR3YXJlLCBhbmQKKyAgICAoMikgb2ZmZXIgeW91IHRoaXMgbGljZW5zZSB3aGljaCBnaXZlcyB5b3UgbGVnYWwgcGVybWlzc2lvbiB0byBjb3B5LAorICAgIGRpc3RyaWJ1dGUgYW5kL29yIG1vZGlmeSB0aGUgc29mdHdhcmUuCisKKyAgICBBbHNvLCBmb3IgZWFjaCBhdXRob3IncyBwcm90ZWN0aW9uIGFuZCBvdXJzLCB3ZSB3YW50IHRvIG1ha2UgY2VydGFpbgorICAgIHRoYXQgZXZlcnlvbmUgdW5kZXJzdGFuZHMgdGhhdCB0aGVyZSBpcyBubyB3YXJyYW50eSBmb3IgdGhpcyBmcmVlCisgICAgc29mdHdhcmUuIElmIHRoZSBzb2Z0d2FyZSBpcyBtb2RpZmllZCBieSBzb21lb25lIGVsc2UgYW5kIHBhc3NlZCBvbiwgd2UKKyAgICB3YW50IGl0cyByZWNpcGllbnRzIHRvIGtub3cgdGhhdCB3aGF0IHRoZXkgaGF2ZSBpcyBub3QgdGhlIG9yaWdpbmFsLCBzbworICAgIHRoYXQgYW55IHByb2JsZW1zIGludHJvZHVjZWQgYnkgb3RoZXJzIHdpbGwgbm90IHJlZmxlY3Qgb24gdGhlIG9yaWdpbmFsCisgICAgYXV0aG9ycycgcmVwdXRhdGlvbnMuCisKKyAgICBGaW5hbGx5LCBhbnkgZnJlZSBwcm9ncmFtIGlzIHRocmVhdGVuZWQgY29uc3RhbnRseSBieSBzb2Z0d2FyZSBwYXRlbnRzLgorICAgIFdlIHdpc2ggdG8gYXZvaWQgdGhlIGRhbmdlciB0aGF0IHJlZGlzdHJpYnV0b3JzIG9mIGEgZnJlZSBwcm9ncmFtIHdpbGwKKyAgICBpbmRpdmlkdWFsbHkgb2J0YWluIHBhdGVudCBsaWNlbnNlcywgaW4gZWZmZWN0IG1ha2luZyB0aGUgcHJvZ3JhbQorICAgIHByb3ByaWV0YXJ5LiBUbyBwcmV2ZW50IHRoaXMsIHdlIGhhdmUgbWFkZSBpdCBjbGVhciB0aGF0IGFueSBwYXRlbnQgbXVzdAorICAgIGJlIGxpY2Vuc2VkIGZvciBldmVyeW9uZSdzIGZyZWUgdXNlIG9yIG5vdCBsaWNlbnNlZCBhdCBhbGwuCisKKyAgICBUaGUgcHJlY2lzZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgY29weWluZywgZGlzdHJpYnV0aW9uIGFuZAorICAgIG1vZGlmaWNhdGlvbiBmb2xsb3cuCisKKyAgICBURVJNUyBBTkQgQ09ORElUSU9OUyBGT1IgQ09QWUlORywgRElTVFJJQlVUSU9OIEFORCBNT0RJRklDQVRJT04KKworICAgIDAuIFRoaXMgTGljZW5zZSBhcHBsaWVzIHRvIGFueSBwcm9ncmFtIG9yIG90aGVyIHdvcmsgd2hpY2ggY29udGFpbnMgYQorICAgIG5vdGljZSBwbGFjZWQgYnkgdGhlIGNvcHlyaWdodCBob2xkZXIgc2F5aW5nIGl0IG1heSBiZSBkaXN0cmlidXRlZCB1bmRlcgorICAgIHRoZSB0ZXJtcyBvZiB0aGlzIEdlbmVyYWwgUHVibGljIExpY2Vuc2UuIFRoZSAiUHJvZ3JhbSIsIGJlbG93LCByZWZlcnMKKyAgICB0byBhbnkgc3VjaCBwcm9ncmFtIG9yIHdvcmssIGFuZCBhICJ3b3JrIGJhc2VkIG9uIHRoZSBQcm9ncmFtIiBtZWFucworICAgIGVpdGhlciB0aGUgUHJvZ3JhbSBvciBhbnkgZGVyaXZhdGl2ZSB3b3JrIHVuZGVyIGNvcHlyaWdodCBsYXc6IHRoYXQgaXMKKyAgICB0byBzYXksIGEgd29yayBjb250YWluaW5nIHRoZSBQcm9ncmFtIG9yIGEgcG9ydGlvbiBvZiBpdCwgZWl0aGVyCisgICAgdmVyYmF0aW0gb3Igd2l0aCBtb2RpZmljYXRpb25zIGFuZC9vciB0cmFuc2xhdGVkIGludG8gYW5vdGhlciBsYW5ndWFnZS4KKyAgICAoSGVyZWluYWZ0ZXIsIHRyYW5zbGF0aW9uIGlzIGluY2x1ZGVkIHdpdGhvdXQgbGltaXRhdGlvbiBpbiB0aGUgdGVybQorICAgICJtb2RpZmljYXRpb24iLikgRWFjaCBsaWNlbnNlZSBpcyBhZGRyZXNzZWQgYXMgInlvdSIuCisKKyAgICBBY3Rpdml0aWVzIG90aGVyIHRoYW4gY29weWluZywgZGlzdHJpYnV0aW9uIGFuZCBtb2RpZmljYXRpb24gYXJlIG5vdAorICAgIGNvdmVyZWQgYnkgdGhpcyBMaWNlbnNlOyB0aGV5IGFyZSBvdXRzaWRlIGl0cyBzY29wZS4gVGhlIGFjdCBvZiBydW5uaW5nCisgICAgdGhlIFByb2dyYW0gaXMgbm90IHJlc3RyaWN0ZWQsIGFuZCB0aGUgb3V0cHV0IGZyb20gdGhlIFByb2dyYW0gaXMKKyAgICBjb3ZlcmVkIG9ubHkgaWYgaXRzIGNvbnRlbnRzIGNvbnN0aXR1dGUgYSB3b3JrIGJhc2VkIG9uIHRoZSBQcm9ncmFtCisgICAgKGluZGVwZW5kZW50IG9mIGhhdmluZyBiZWVuIG1hZGUgYnkgcnVubmluZyB0aGUgUHJvZ3JhbSkuIFdoZXRoZXIgdGhhdAorICAgIGlzIHRydWUgZGVwZW5kcyBvbiB3aGF0IHRoZSBQcm9ncmFtIGRvZXMuCisKKyAgICAxLiBZb3UgbWF5IGNvcHkgYW5kIGRpc3RyaWJ1dGUgdmVyYmF0aW0gY29waWVzIG9mIHRoZSBQcm9ncmFtJ3Mgc291cmNlCisgICAgY29kZSBhcyB5b3UgcmVjZWl2ZSBpdCwgaW4gYW55IG1lZGl1bSwgcHJvdmlkZWQgdGhhdCB5b3UgY29uc3BpY3VvdXNseQorICAgIGFuZCBhcHByb3ByaWF0ZWx5IHB1Ymxpc2ggb24gZWFjaCBjb3B5IGFuIGFwcHJvcHJpYXRlIGNvcHlyaWdodCBub3RpY2UKKyAgICBhbmQgZGlzY2xhaW1lciBvZiB3YXJyYW50eTsga2VlcCBpbnRhY3QgYWxsIHRoZSBub3RpY2VzIHRoYXQgcmVmZXIgdG8KKyAgICB0aGlzIExpY2Vuc2UgYW5kIHRvIHRoZSBhYnNlbmNlIG9mIGFueSB3YXJyYW50eTsgYW5kIGdpdmUgYW55IG90aGVyCisgICAgcmVjaXBpZW50cyBvZiB0aGUgUHJvZ3JhbSBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlIGFsb25nIHdpdGggdGhlIFByb2dyYW0uCisKKyAgICBZb3UgbWF5IGNoYXJnZSBhIGZlZSBmb3IgdGhlIHBoeXNpY2FsIGFjdCBvZiB0cmFuc2ZlcnJpbmcgYSBjb3B5LCBhbmQKKyAgICB5b3UgbWF5IGF0IHlvdXIgb3B0aW9uIG9mZmVyIHdhcnJhbnR5IHByb3RlY3Rpb24gaW4gZXhjaGFuZ2UgZm9yIGEgZmVlLgorCisgICAgMi4gWW91IG1heSBtb2RpZnkgeW91ciBjb3B5IG9yIGNvcGllcyBvZiB0aGUgUHJvZ3JhbSBvciBhbnkgcG9ydGlvbiBvZgorICAgIGl0LCB0aHVzIGZvcm1pbmcgYSB3b3JrIGJhc2VkIG9uIHRoZSBQcm9ncmFtLCBhbmQgY29weSBhbmQgZGlzdHJpYnV0ZQorICAgIHN1Y2ggbW9kaWZpY2F0aW9ucyBvciB3b3JrIHVuZGVyIHRoZSB0ZXJtcyBvZiBTZWN0aW9uIDEgYWJvdmUsIHByb3ZpZGVkCisgICAgdGhhdCB5b3UgYWxzbyBtZWV0IGFsbCBvZiB0aGVzZSBjb25kaXRpb25zOgorCisgICAgICAgIGEpIFlvdSBtdXN0IGNhdXNlIHRoZSBtb2RpZmllZCBmaWxlcyB0byBjYXJyeSBwcm9taW5lbnQgbm90aWNlcworICAgICAgICBzdGF0aW5nIHRoYXQgeW91IGNoYW5nZWQgdGhlIGZpbGVzIGFuZCB0aGUgZGF0ZSBvZiBhbnkgY2hhbmdlLgorCisgICAgICAgIGIpIFlvdSBtdXN0IGNhdXNlIGFueSB3b3JrIHRoYXQgeW91IGRpc3RyaWJ1dGUgb3IgcHVibGlzaCwgdGhhdCBpbgorICAgICAgICB3aG9sZSBvciBpbiBwYXJ0IGNvbnRhaW5zIG9yIGlzIGRlcml2ZWQgZnJvbSB0aGUgUHJvZ3JhbSBvciBhbnkgcGFydAorICAgICAgICB0aGVyZW9mLCB0byBiZSBsaWNlbnNlZCBhcyBhIHdob2xlIGF0IG5vIGNoYXJnZSB0byBhbGwgdGhpcmQgcGFydGllcworICAgICAgICB1bmRlciB0aGUgdGVybXMgb2YgdGhpcyBMaWNlbnNlLgorCisgICAgICAgIGMpIElmIHRoZSBtb2RpZmllZCBwcm9ncmFtIG5vcm1hbGx5IHJlYWRzIGNvbW1hbmRzIGludGVyYWN0aXZlbHkKKyAgICAgICAgd2hlbiBydW4sIHlvdSBtdXN0IGNhdXNlIGl0LCB3aGVuIHN0YXJ0ZWQgcnVubmluZyBmb3Igc3VjaAorICAgICAgICBpbnRlcmFjdGl2ZSB1c2UgaW4gdGhlIG1vc3Qgb3JkaW5hcnkgd2F5LCB0byBwcmludCBvciBkaXNwbGF5IGFuCisgICAgICAgIGFubm91bmNlbWVudCBpbmNsdWRpbmcgYW4gYXBwcm9wcmlhdGUgY29weXJpZ2h0IG5vdGljZSBhbmQgYSBub3RpY2UKKyAgICAgICAgdGhhdCB0aGVyZSBpcyBubyB3YXJyYW50eSAob3IgZWxzZSwgc2F5aW5nIHRoYXQgeW91IHByb3ZpZGUgYQorICAgICAgICB3YXJyYW50eSkgYW5kIHRoYXQgdXNlcnMgbWF5IHJlZGlzdHJpYnV0ZSB0aGUgcHJvZ3JhbSB1bmRlciB0aGVzZQorICAgICAgICBjb25kaXRpb25zLCBhbmQgdGVsbGluZyB0aGUgdXNlciBob3cgdG8gdmlldyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlLgorICAgICAgICAoRXhjZXB0aW9uOiBpZiB0aGUgUHJvZ3JhbSBpdHNlbGYgaXMgaW50ZXJhY3RpdmUgYnV0IGRvZXMgbm90CisgICAgICAgIG5vcm1hbGx5IHByaW50IHN1Y2ggYW4gYW5ub3VuY2VtZW50LCB5b3VyIHdvcmsgYmFzZWQgb24gdGhlIFByb2dyYW0KKyAgICAgICAgaXMgbm90IHJlcXVpcmVkIHRvIHByaW50IGFuIGFubm91bmNlbWVudC4pCisKKyAgICBUaGVzZSByZXF1aXJlbWVudHMgYXBwbHkgdG8gdGhlIG1vZGlmaWVkIHdvcmsgYXMgYSB3aG9sZS4gSWYKKyAgICBpZGVudGlmaWFibGUgc2VjdGlvbnMgb2YgdGhhdCB3b3JrIGFyZSBub3QgZGVyaXZlZCBmcm9tIHRoZSBQcm9ncmFtLCBhbmQKKyAgICBjYW4gYmUgcmVhc29uYWJseSBjb25zaWRlcmVkIGluZGVwZW5kZW50IGFuZCBzZXBhcmF0ZSB3b3JrcyBpbgorICAgIHRoZW1zZWx2ZXMsIHRoZW4gdGhpcyBMaWNlbnNlLCBhbmQgaXRzIHRlcm1zLCBkbyBub3QgYXBwbHkgdG8gdGhvc2UKKyAgICBzZWN0aW9ucyB3aGVuIHlvdSBkaXN0cmlidXRlIHRoZW0gYXMgc2VwYXJhdGUgd29ya3MuIEJ1dCB3aGVuIHlvdQorICAgIGRpc3RyaWJ1dGUgdGhlIHNhbWUgc2VjdGlvbnMgYXMgcGFydCBvZiBhIHdob2xlIHdoaWNoIGlzIGEgd29yayBiYXNlZCBvbgorICAgIHRoZSBQcm9ncmFtLCB0aGUgZGlzdHJpYnV0aW9uIG9mIHRoZSB3aG9sZSBtdXN0IGJlIG9uIHRoZSB0ZXJtcyBvZiB0aGlzCisgICAgTGljZW5zZSwgd2hvc2UgcGVybWlzc2lvbnMgZm9yIG90aGVyIGxpY2Vuc2VlcyBleHRlbmQgdG8gdGhlIGVudGlyZQorICAgIHdob2xlLCBhbmQgdGh1cyB0byBlYWNoIGFuZCBldmVyeSBwYXJ0IHJlZ2FyZGxlc3Mgb2Ygd2hvIHdyb3RlIGl0LgorCisgICAgVGh1cywgaXQgaXMgbm90IHRoZSBpbnRlbnQgb2YgdGhpcyBzZWN0aW9uIHRvIGNsYWltIHJpZ2h0cyBvciBjb250ZXN0CisgICAgeW91ciByaWdodHMgdG8gd29yayB3cml0dGVuIGVudGlyZWx5IGJ5IHlvdTsgcmF0aGVyLCB0aGUgaW50ZW50IGlzIHRvCisgICAgZXhlcmNpc2UgdGhlIHJpZ2h0IHRvIGNvbnRyb2wgdGhlIGRpc3RyaWJ1dGlvbiBvZiBkZXJpdmF0aXZlIG9yCisgICAgY29sbGVjdGl2ZSB3b3JrcyBiYXNlZCBvbiB0aGUgUHJvZ3JhbS4KKworICAgIEluIGFkZGl0aW9uLCBtZXJlIGFnZ3JlZ2F0aW9uIG9mIGFub3RoZXIgd29yayBub3QgYmFzZWQgb24gdGhlIFByb2dyYW0KKyAgICB3aXRoIHRoZSBQcm9ncmFtIChvciB3aXRoIGEgd29yayBiYXNlZCBvbiB0aGUgUHJvZ3JhbSkgb24gYSB2b2x1bWUgb2YgYQorICAgIHN0b3JhZ2Ugb3IgZGlzdHJpYnV0aW9uIG1lZGl1bSBkb2VzIG5vdCBicmluZyB0aGUgb3RoZXIgd29yayB1bmRlciB0aGUKKyAgICBzY29wZSBvZiB0aGlzIExpY2Vuc2UuCisKKyAgICAzLiBZb3UgbWF5IGNvcHkgYW5kIGRpc3RyaWJ1dGUgdGhlIFByb2dyYW0gKG9yIGEgd29yayBiYXNlZCBvbiBpdCwKKyAgICB1bmRlciBTZWN0aW9uIDIpIGluIG9iamVjdCBjb2RlIG9yIGV4ZWN1dGFibGUgZm9ybSB1bmRlciB0aGUgdGVybXMgb2YKKyAgICBTZWN0aW9ucyAxIGFuZCAyIGFib3ZlIHByb3ZpZGVkIHRoYXQgeW91IGFsc28gZG8gb25lIG9mIHRoZSBmb2xsb3dpbmc6CisKKyAgICAgICAgYSkgQWNjb21wYW55IGl0IHdpdGggdGhlIGNvbXBsZXRlIGNvcnJlc3BvbmRpbmcgbWFjaGluZS1yZWFkYWJsZQorICAgICAgICBzb3VyY2UgY29kZSwgd2hpY2ggbXVzdCBiZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgdGVybXMgb2YgU2VjdGlvbnMgMQorICAgICAgICBhbmQgMiBhYm92ZSBvbiBhIG1lZGl1bSBjdXN0b21hcmlseSB1c2VkIGZvciBzb2Z0d2FyZSBpbnRlcmNoYW5nZTsgb3IsCisKKyAgICAgICAgYikgQWNjb21wYW55IGl0IHdpdGggYSB3cml0dGVuIG9mZmVyLCB2YWxpZCBmb3IgYXQgbGVhc3QgdGhyZWUKKyAgICAgICAgeWVhcnMsIHRvIGdpdmUgYW55IHRoaXJkIHBhcnR5LCBmb3IgYSBjaGFyZ2Ugbm8gbW9yZSB0aGFuIHlvdXIgY29zdAorICAgICAgICBvZiBwaHlzaWNhbGx5IHBlcmZvcm1pbmcgc291cmNlIGRpc3RyaWJ1dGlvbiwgYSBjb21wbGV0ZQorICAgICAgICBtYWNoaW5lLXJlYWRhYmxlIGNvcHkgb2YgdGhlIGNvcnJlc3BvbmRpbmcgc291cmNlIGNvZGUsIHRvIGJlCisgICAgICAgIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSB0ZXJtcyBvZiBTZWN0aW9ucyAxIGFuZCAyIGFib3ZlIG9uIGEgbWVkaXVtCisgICAgICAgIGN1c3RvbWFyaWx5IHVzZWQgZm9yIHNvZnR3YXJlIGludGVyY2hhbmdlOyBvciwKKworICAgICAgICBjKSBBY2NvbXBhbnkgaXQgd2l0aCB0aGUgaW5mb3JtYXRpb24geW91IHJlY2VpdmVkIGFzIHRvIHRoZSBvZmZlciB0bworICAgICAgICBkaXN0cmlidXRlIGNvcnJlc3BvbmRpbmcgc291cmNlIGNvZGUuIChUaGlzIGFsdGVybmF0aXZlIGlzIGFsbG93ZWQKKyAgICAgICAgb25seSBmb3Igbm9uY29tbWVyY2lhbCBkaXN0cmlidXRpb24gYW5kIG9ubHkgaWYgeW91IHJlY2VpdmVkIHRoZQorICAgICAgICBwcm9ncmFtIGluIG9iamVjdCBjb2RlIG9yIGV4ZWN1dGFibGUgZm9ybSB3aXRoIHN1Y2ggYW4gb2ZmZXIsIGluCisgICAgICAgIGFjY29yZCB3aXRoIFN1YnNlY3Rpb24gYiBhYm92ZS4pCisKKyAgICBUaGUgc291cmNlIGNvZGUgZm9yIGEgd29yayBtZWFucyB0aGUgcHJlZmVycmVkIGZvcm0gb2YgdGhlIHdvcmsgZm9yCisgICAgbWFraW5nIG1vZGlmaWNhdGlvbnMgdG8gaXQuIEZvciBhbiBleGVjdXRhYmxlIHdvcmssIGNvbXBsZXRlIHNvdXJjZSBjb2RlCisgICAgbWVhbnMgYWxsIHRoZSBzb3VyY2UgY29kZSBmb3IgYWxsIG1vZHVsZXMgaXQgY29udGFpbnMsIHBsdXMgYW55CisgICAgYXNzb2NpYXRlZCBpbnRlcmZhY2UgZGVmaW5pdGlvbiBmaWxlcywgcGx1cyB0aGUgc2NyaXB0cyB1c2VkIHRvIGNvbnRyb2wKKyAgICBjb21waWxhdGlvbiBhbmQgaW5zdGFsbGF0aW9uIG9mIHRoZSBleGVjdXRhYmxlLiBIb3dldmVyLCBhcyBhIHNwZWNpYWwKKyAgICBleGNlcHRpb24sIHRoZSBzb3VyY2UgY29kZSBkaXN0cmlidXRlZCBuZWVkIG5vdCBpbmNsdWRlIGFueXRoaW5nIHRoYXQgaXMKKyAgICBub3JtYWxseSBkaXN0cmlidXRlZCAoaW4gZWl0aGVyIHNvdXJjZSBvciBiaW5hcnkgZm9ybSkgd2l0aCB0aGUgbWFqb3IKKyAgICBjb21wb25lbnRzIChjb21waWxlciwga2VybmVsLCBhbmQgc28gb24pIG9mIHRoZSBvcGVyYXRpbmcgc3lzdGVtIG9uCisgICAgd2hpY2ggdGhlIGV4ZWN1dGFibGUgcnVucywgdW5sZXNzIHRoYXQgY29tcG9uZW50IGl0c2VsZiBhY2NvbXBhbmllcyB0aGUKKyAgICBleGVjdXRhYmxlLgorCisgICAgSWYgZGlzdHJpYnV0aW9uIG9mIGV4ZWN1dGFibGUgb3Igb2JqZWN0IGNvZGUgaXMgbWFkZSBieSBvZmZlcmluZyBhY2Nlc3MKKyAgICB0byBjb3B5IGZyb20gYSBkZXNpZ25hdGVkIHBsYWNlLCB0aGVuIG9mZmVyaW5nIGVxdWl2YWxlbnQgYWNjZXNzIHRvIGNvcHkKKyAgICB0aGUgc291cmNlIGNvZGUgZnJvbSB0aGUgc2FtZSBwbGFjZSBjb3VudHMgYXMgZGlzdHJpYnV0aW9uIG9mIHRoZSBzb3VyY2UKKyAgICBjb2RlLCBldmVuIHRob3VnaCB0aGlyZCBwYXJ0aWVzIGFyZSBub3QgY29tcGVsbGVkIHRvIGNvcHkgdGhlIHNvdXJjZQorICAgIGFsb25nIHdpdGggdGhlIG9iamVjdCBjb2RlLgorCisgICAgNC4gWW91IG1heSBub3QgY29weSwgbW9kaWZ5LCBzdWJsaWNlbnNlLCBvciBkaXN0cmlidXRlIHRoZSBQcm9ncmFtCisgICAgZXhjZXB0IGFzIGV4cHJlc3NseSBwcm92aWRlZCB1bmRlciB0aGlzIExpY2Vuc2UuIEFueSBhdHRlbXB0IG90aGVyd2lzZQorICAgIHRvIGNvcHksIG1vZGlmeSwgc3VibGljZW5zZSBvciBkaXN0cmlidXRlIHRoZSBQcm9ncmFtIGlzIHZvaWQsIGFuZCB3aWxsCisgICAgYXV0b21hdGljYWxseSB0ZXJtaW5hdGUgeW91ciByaWdodHMgdW5kZXIgdGhpcyBMaWNlbnNlLiBIb3dldmVyLCBwYXJ0aWVzCisgICAgd2hvIGhhdmUgcmVjZWl2ZWQgY29waWVzLCBvciByaWdodHMsIGZyb20geW91IHVuZGVyIHRoaXMgTGljZW5zZSB3aWxsCisgICAgbm90IGhhdmUgdGhlaXIgbGljZW5zZXMgdGVybWluYXRlZCBzbyBsb25nIGFzIHN1Y2ggcGFydGllcyByZW1haW4gaW4KKyAgICBmdWxsIGNvbXBsaWFuY2UuCisKKyAgICA1LiBZb3UgYXJlIG5vdCByZXF1aXJlZCB0byBhY2NlcHQgdGhpcyBMaWNlbnNlLCBzaW5jZSB5b3UgaGF2ZSBub3QKKyAgICBzaWduZWQgaXQuIEhvd2V2ZXIsIG5vdGhpbmcgZWxzZSBncmFudHMgeW91IHBlcm1pc3Npb24gdG8gbW9kaWZ5IG9yCisgICAgZGlzdHJpYnV0ZSB0aGUgUHJvZ3JhbSBvciBpdHMgZGVyaXZhdGl2ZSB3b3Jrcy4gVGhlc2UgYWN0aW9ucyBhcmUKKyAgICBwcm9oaWJpdGVkIGJ5IGxhdyBpZiB5b3UgZG8gbm90IGFjY2VwdCB0aGlzIExpY2Vuc2UuIFRoZXJlZm9yZSwgYnkKKyAgICBtb2RpZnlpbmcgb3IgZGlzdHJpYnV0aW5nIHRoZSBQcm9ncmFtIChvciBhbnkgd29yayBiYXNlZCBvbiB0aGUKKyAgICBQcm9ncmFtKSwgeW91IGluZGljYXRlIHlvdXIgYWNjZXB0YW5jZSBvZiB0aGlzIExpY2Vuc2UgdG8gZG8gc28sIGFuZCBhbGwKKyAgICBpdHMgdGVybXMgYW5kIGNvbmRpdGlvbnMgZm9yIGNvcHlpbmcsIGRpc3RyaWJ1dGluZyBvciBtb2RpZnlpbmcgdGhlCisgICAgUHJvZ3JhbSBvciB3b3JrcyBiYXNlZCBvbiBpdC4KKworICAgIDYuIEVhY2ggdGltZSB5b3UgcmVkaXN0cmlidXRlIHRoZSBQcm9ncmFtIChvciBhbnkgd29yayBiYXNlZCBvbiB0aGUKKyAgICBQcm9ncmFtKSwgdGhlIHJlY2lwaWVudCBhdXRvbWF0aWNhbGx5IHJlY2VpdmVzIGEgbGljZW5zZSBmcm9tIHRoZQorICAgIG9yaWdpbmFsIGxpY2Vuc29yIHRvIGNvcHksIGRpc3RyaWJ1dGUgb3IgbW9kaWZ5IHRoZSBQcm9ncmFtIHN1YmplY3QgdG8KKyAgICB0aGVzZSB0ZXJtcyBhbmQgY29uZGl0aW9ucy4gWW91IG1heSBub3QgaW1wb3NlIGFueSBmdXJ0aGVyIHJlc3RyaWN0aW9ucworICAgIG9uIHRoZSByZWNpcGllbnRzJyBleGVyY2lzZSBvZiB0aGUgcmlnaHRzIGdyYW50ZWQgaGVyZWluLiBZb3UgYXJlIG5vdAorICAgIHJlc3BvbnNpYmxlIGZvciBlbmZvcmNpbmcgY29tcGxpYW5jZSBieSB0aGlyZCBwYXJ0aWVzIHRvIHRoaXMgTGljZW5zZS4KKworICAgIDcuIElmLCBhcyBhIGNvbnNlcXVlbmNlIG9mIGEgY291cnQganVkZ21lbnQgb3IgYWxsZWdhdGlvbiBvZiBwYXRlbnQKKyAgICBpbmZyaW5nZW1lbnQgb3IgZm9yIGFueSBvdGhlciByZWFzb24gKG5vdCBsaW1pdGVkIHRvIHBhdGVudCBpc3N1ZXMpLAorICAgIGNvbmRpdGlvbnMgYXJlIGltcG9zZWQgb24geW91ICh3aGV0aGVyIGJ5IGNvdXJ0IG9yZGVyLCBhZ3JlZW1lbnQgb3IKKyAgICBvdGhlcndpc2UpIHRoYXQgY29udHJhZGljdCB0aGUgY29uZGl0aW9ucyBvZiB0aGlzIExpY2Vuc2UsIHRoZXkgZG8gbm90CisgICAgZXhjdXNlIHlvdSBmcm9tIHRoZSBjb25kaXRpb25zIG9mIHRoaXMgTGljZW5zZS4gSWYgeW91IGNhbm5vdCBkaXN0cmlidXRlCisgICAgc28gYXMgdG8gc2F0aXNmeSBzaW11bHRhbmVvdXNseSB5b3VyIG9ibGlnYXRpb25zIHVuZGVyIHRoaXMgTGljZW5zZSBhbmQKKyAgICBhbnkgb3RoZXIgcGVydGluZW50IG9ibGlnYXRpb25zLCB0aGVuIGFzIGEgY29uc2VxdWVuY2UgeW91IG1heSBub3QKKyAgICBkaXN0cmlidXRlIHRoZSBQcm9ncmFtIGF0IGFsbC4gRm9yIGV4YW1wbGUsIGlmIGEgcGF0ZW50IGxpY2Vuc2Ugd291bGQKKyAgICBub3QgcGVybWl0IHJveWFsdHktZnJlZSByZWRpc3RyaWJ1dGlvbiBvZiB0aGUgUHJvZ3JhbSBieSBhbGwgdGhvc2Ugd2hvCisgICAgcmVjZWl2ZSBjb3BpZXMgZGlyZWN0bHkgb3IgaW5kaXJlY3RseSB0aHJvdWdoIHlvdSwgdGhlbiB0aGUgb25seSB3YXkgeW91CisgICAgY291bGQgc2F0aXNmeSBib3RoIGl0IGFuZCB0aGlzIExpY2Vuc2Ugd291bGQgYmUgdG8gcmVmcmFpbiBlbnRpcmVseSBmcm9tCisgICAgZGlzdHJpYnV0aW9uIG9mIHRoZSBQcm9ncmFtLgorCisgICAgSWYgYW55IHBvcnRpb24gb2YgdGhpcyBzZWN0aW9uIGlzIGhlbGQgaW52YWxpZCBvciB1bmVuZm9yY2VhYmxlIHVuZGVyCisgICAgYW55IHBhcnRpY3VsYXIgY2lyY3Vtc3RhbmNlLCB0aGUgYmFsYW5jZSBvZiB0aGUgc2VjdGlvbiBpcyBpbnRlbmRlZCB0bworICAgIGFwcGx5IGFuZCB0aGUgc2VjdGlvbiBhcyBhIHdob2xlIGlzIGludGVuZGVkIHRvIGFwcGx5IGluIG90aGVyCisgICAgY2lyY3Vtc3RhbmNlcy4KKworICAgIEl0IGlzIG5vdCB0aGUgcHVycG9zZSBvZiB0aGlzIHNlY3Rpb24gdG8gaW5kdWNlIHlvdSB0byBpbmZyaW5nZSBhbnkKKyAgICBwYXRlbnRzIG9yIG90aGVyIHByb3BlcnR5IHJpZ2h0IGNsYWltcyBvciB0byBjb250ZXN0IHZhbGlkaXR5IG9mIGFueQorICAgIHN1Y2ggY2xhaW1zOyB0aGlzIHNlY3Rpb24gaGFzIHRoZSBzb2xlIHB1cnBvc2Ugb2YgcHJvdGVjdGluZyB0aGUKKyAgICBpbnRlZ3JpdHkgb2YgdGhlIGZyZWUgc29mdHdhcmUgZGlzdHJpYnV0aW9uIHN5c3RlbSwgd2hpY2ggaXMgaW1wbGVtZW50ZWQKKyAgICBieSBwdWJsaWMgbGljZW5zZSBwcmFjdGljZXMuIE1hbnkgcGVvcGxlIGhhdmUgbWFkZSBnZW5lcm91cworICAgIGNvbnRyaWJ1dGlvbnMgdG8gdGhlIHdpZGUgcmFuZ2Ugb2Ygc29mdHdhcmUgZGlzdHJpYnV0ZWQgdGhyb3VnaCB0aGF0CisgICAgc3lzdGVtIGluIHJlbGlhbmNlIG9uIGNvbnNpc3RlbnQgYXBwbGljYXRpb24gb2YgdGhhdCBzeXN0ZW07IGl0IGlzIHVwIHRvCisgICAgdGhlIGF1dGhvci9kb25vciB0byBkZWNpZGUgaWYgaGUgb3Igc2hlIGlzIHdpbGxpbmcgdG8gZGlzdHJpYnV0ZQorICAgIHNvZnR3YXJlIHRocm91Z2ggYW55IG90aGVyIHN5c3RlbSBhbmQgYSBsaWNlbnNlZSBjYW5ub3QgaW1wb3NlIHRoYXQgY2hvaWNlLgorCisgICAgVGhpcyBzZWN0aW9uIGlzIGludGVuZGVkIHRvIG1ha2UgdGhvcm91Z2hseSBjbGVhciB3aGF0IGlzIGJlbGlldmVkIHRvIGJlCisgICAgYSBjb25zZXF1ZW5jZSBvZiB0aGUgcmVzdCBvZiB0aGlzIExpY2Vuc2UuCisKKyAgICA4LiBJZiB0aGUgZGlzdHJpYnV0aW9uIGFuZC9vciB1c2Ugb2YgdGhlIFByb2dyYW0gaXMgcmVzdHJpY3RlZCBpbgorICAgIGNlcnRhaW4gY291bnRyaWVzIGVpdGhlciBieSBwYXRlbnRzIG9yIGJ5IGNvcHlyaWdodGVkIGludGVyZmFjZXMsIHRoZQorICAgIG9yaWdpbmFsIGNvcHlyaWdodCBob2xkZXIgd2hvIHBsYWNlcyB0aGUgUHJvZ3JhbSB1bmRlciB0aGlzIExpY2Vuc2UgbWF5CisgICAgYWRkIGFuIGV4cGxpY2l0IGdlb2dyYXBoaWNhbCBkaXN0cmlidXRpb24gbGltaXRhdGlvbiBleGNsdWRpbmcgdGhvc2UKKyAgICBjb3VudHJpZXMsIHNvIHRoYXQgZGlzdHJpYnV0aW9uIGlzIHBlcm1pdHRlZCBvbmx5IGluIG9yIGFtb25nIGNvdW50cmllcworICAgIG5vdCB0aHVzIGV4Y2x1ZGVkLiBJbiBzdWNoIGNhc2UsIHRoaXMgTGljZW5zZSBpbmNvcnBvcmF0ZXMgdGhlCisgICAgbGltaXRhdGlvbiBhcyBpZiB3cml0dGVuIGluIHRoZSBib2R5IG9mIHRoaXMgTGljZW5zZS4KKworICAgIDkuIFRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24gbWF5IHB1Ymxpc2ggcmV2aXNlZCBhbmQvb3IgbmV3CisgICAgdmVyc2lvbnMgb2YgdGhlIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZnJvbSB0aW1lIHRvIHRpbWUuIFN1Y2ggbmV3CisgICAgdmVyc2lvbnMgd2lsbCBiZSBzaW1pbGFyIGluIHNwaXJpdCB0byB0aGUgcHJlc2VudCB2ZXJzaW9uLCBidXQgbWF5CisgICAgZGlmZmVyIGluIGRldGFpbCB0byBhZGRyZXNzIG5ldyBwcm9ibGVtcyBvciBjb25jZXJucy4KKworICAgIEVhY2ggdmVyc2lvbiBpcyBnaXZlbiBhIGRpc3Rpbmd1aXNoaW5nIHZlcnNpb24gbnVtYmVyLiBJZiB0aGUgUHJvZ3JhbQorICAgIHNwZWNpZmllcyBhIHZlcnNpb24gbnVtYmVyIG9mIHRoaXMgTGljZW5zZSB3aGljaCBhcHBsaWVzIHRvIGl0IGFuZCAiYW55CisgICAgbGF0ZXIgdmVyc2lvbiIsIHlvdSBoYXZlIHRoZSBvcHRpb24gb2YgZm9sbG93aW5nIHRoZSB0ZXJtcyBhbmQKKyAgICBjb25kaXRpb25zIGVpdGhlciBvZiB0aGF0IHZlcnNpb24gb3Igb2YgYW55IGxhdGVyIHZlcnNpb24gcHVibGlzaGVkIGJ5CisgICAgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gSWYgdGhlIFByb2dyYW0gZG9lcyBub3Qgc3BlY2lmeSBhIHZlcnNpb24KKyAgICBudW1iZXIgb2YgdGhpcyBMaWNlbnNlLCB5b3UgbWF5IGNob29zZSBhbnkgdmVyc2lvbiBldmVyIHB1Ymxpc2hlZCBieSB0aGUKKyAgICBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCisKKyAgICAxMC4gSWYgeW91IHdpc2ggdG8gaW5jb3Jwb3JhdGUgcGFydHMgb2YgdGhlIFByb2dyYW0gaW50byBvdGhlciBmcmVlCisgICAgcHJvZ3JhbXMgd2hvc2UgZGlzdHJpYnV0aW9uIGNvbmRpdGlvbnMgYXJlIGRpZmZlcmVudCwgd3JpdGUgdG8gdGhlCisgICAgYXV0aG9yIHRvIGFzayBmb3IgcGVybWlzc2lvbi4gRm9yIHNvZnR3YXJlIHdoaWNoIGlzIGNvcHlyaWdodGVkIGJ5IHRoZQorICAgIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgd2UKKyAgICBzb21ldGltZXMgbWFrZSBleGNlcHRpb25zIGZvciB0aGlzLiBPdXIgZGVjaXNpb24gd2lsbCBiZSBndWlkZWQgYnkgdGhlCisgICAgdHdvIGdvYWxzIG9mIHByZXNlcnZpbmcgdGhlIGZyZWUgc3RhdHVzIG9mIGFsbCBkZXJpdmF0aXZlcyBvZiBvdXIgZnJlZQorICAgIHNvZnR3YXJlIGFuZCBvZiBwcm9tb3RpbmcgdGhlIHNoYXJpbmcgYW5kIHJldXNlIG9mIHNvZnR3YXJlIGdlbmVyYWxseS4KKworICAgIE5PIFdBUlJBTlRZCisKKyAgICAxMS4gQkVDQVVTRSBUSEUgUFJPR1JBTSBJUyBMSUNFTlNFRCBGUkVFIE9GIENIQVJHRSwgVEhFUkUgSVMgTk8KKyAgICBXQVJSQU5UWSBGT1IgVEhFIFBST0dSQU0sIFRPIFRIRSBFWFRFTlQgUEVSTUlUVEVEIEJZIEFQUExJQ0FCTEUgTEFXLgorICAgIEVYQ0VQVCBXSEVOIE9USEVSV0lTRSBTVEFURUQgSU4gV1JJVElORyBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EL09SCisgICAgT1RIRVIgUEFSVElFUyBQUk9WSURFIFRIRSBQUk9HUkFNICJBUyBJUyIgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwKKyAgICBFSVRIRVIgRVhQUkVTU0VEIE9SIElNUExJRUQsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRAorICAgIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gVEhFCisgICAgRU5USVJFIFJJU0sgQVMgVE8gVEhFIFFVQUxJVFkgQU5EIFBFUkZPUk1BTkNFIE9GIFRIRSBQUk9HUkFNIElTIFdJVEgKKyAgICBZT1UuIFNIT1VMRCBUSEUgUFJPR1JBTSBQUk9WRSBERUZFQ1RJVkUsIFlPVSBBU1NVTUUgVEhFIENPU1QgT0YgQUxMCisgICAgTkVDRVNTQVJZIFNFUlZJQ0lORywgUkVQQUlSIE9SIENPUlJFQ1RJT04uCisKKyAgICAxMi4gSU4gTk8gRVZFTlQgVU5MRVNTIFJFUVVJUkVEIEJZIEFQUExJQ0FCTEUgTEFXIE9SIEFHUkVFRCBUTyBJTgorICAgIFdSSVRJTkcgV0lMTCBBTlkgQ09QWVJJR0hUIEhPTERFUiwgT1IgQU5ZIE9USEVSIFBBUlRZIFdITyBNQVkgTU9ESUZZCisgICAgQU5EL09SIFJFRElTVFJJQlVURSBUSEUgUFJPR1JBTSBBUyBQRVJNSVRURUQgQUJPVkUsIEJFIExJQUJMRSBUTyBZT1UgRk9SCisgICAgREFNQUdFUywgSU5DTFVESU5HIEFOWSBHRU5FUkFMLCBTUEVDSUFMLCBJTkNJREVOVEFMIE9SIENPTlNFUVVFTlRJQUwKKyAgICBEQU1BR0VTIEFSSVNJTkcgT1VUIE9GIFRIRSBVU0UgT1IgSU5BQklMSVRZIFRPIFVTRSBUSEUgUFJPR1JBTQorICAgIChJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIExPU1MgT0YgREFUQSBPUiBEQVRBIEJFSU5HIFJFTkRFUkVECisgICAgSU5BQ0NVUkFURSBPUiBMT1NTRVMgU1VTVEFJTkVEIEJZIFlPVSBPUiBUSElSRCBQQVJUSUVTIE9SIEEgRkFJTFVSRSBPRgorICAgIFRIRSBQUk9HUkFNIFRPIE9QRVJBVEUgV0lUSCBBTlkgT1RIRVIgUFJPR1JBTVMpLCBFVkVOIElGIFNVQ0ggSE9MREVSIE9SCisgICAgT1RIRVIgUEFSVFkgSEFTIEJFRU4gQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0VTLgorCisgICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCisKKyAgICBIb3cgdG8gQXBwbHkgVGhlc2UgVGVybXMgdG8gWW91ciBOZXcgUHJvZ3JhbXMKKworICAgIElmIHlvdSBkZXZlbG9wIGEgbmV3IHByb2dyYW0sIGFuZCB5b3Ugd2FudCBpdCB0byBiZSBvZiB0aGUgZ3JlYXRlc3QKKyAgICBwb3NzaWJsZSB1c2UgdG8gdGhlIHB1YmxpYywgdGhlIGJlc3Qgd2F5IHRvIGFjaGlldmUgdGhpcyBpcyB0byBtYWtlIGl0CisgICAgZnJlZSBzb2Z0d2FyZSB3aGljaCBldmVyeW9uZSBjYW4gcmVkaXN0cmlidXRlIGFuZCBjaGFuZ2UgdW5kZXIgdGhlc2UgdGVybXMuCisKKyAgICBUbyBkbyBzbywgYXR0YWNoIHRoZSBmb2xsb3dpbmcgbm90aWNlcyB0byB0aGUgcHJvZ3JhbS4gSXQgaXMgc2FmZXN0IHRvCisgICAgYXR0YWNoIHRoZW0gdG8gdGhlIHN0YXJ0IG9mIGVhY2ggc291cmNlIGZpbGUgdG8gbW9zdCBlZmZlY3RpdmVseSBjb252ZXkKKyAgICB0aGUgZXhjbHVzaW9uIG9mIHdhcnJhbnR5OyBhbmQgZWFjaCBmaWxlIHNob3VsZCBoYXZlIGF0IGxlYXN0IHRoZQorICAgICJjb3B5cmlnaHQiIGxpbmUgYW5kIGEgcG9pbnRlciB0byB3aGVyZSB0aGUgZnVsbCBub3RpY2UgaXMgZm91bmQuCisKKyAgICAgICAgT25lIGxpbmUgdG8gZ2l2ZSB0aGUgcHJvZ3JhbSdzIG5hbWUgYW5kIGEgYnJpZWYgaWRlYSBvZiB3aGF0IGl0IGRvZXMuCisgICAgICAgIENvcHlyaWdodCAoQykgPHllYXI+IDxuYW1lIG9mIGF1dGhvcj4KKworICAgICAgICBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQorICAgICAgICBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQorICAgICAgICB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvcgorICAgICAgICAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgorCisgICAgICAgIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQKKyAgICAgICAgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgorICAgICAgICBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuIFNlZSB0aGUgR05VCisgICAgICAgIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KKworICAgICAgICBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQorICAgICAgICBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQorICAgICAgICBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMzUgVVNBCisKKyAgICBBbHNvIGFkZCBpbmZvcm1hdGlvbiBvbiBob3cgdG8gY29udGFjdCB5b3UgYnkgZWxlY3Ryb25pYyBhbmQgcGFwZXIgbWFpbC4KKworICAgIElmIHRoZSBwcm9ncmFtIGlzIGludGVyYWN0aXZlLCBtYWtlIGl0IG91dHB1dCBhIHNob3J0IG5vdGljZSBsaWtlIHRoaXMKKyAgICB3aGVuIGl0IHN0YXJ0cyBpbiBhbiBpbnRlcmFjdGl2ZSBtb2RlOgorCisgICAgICAgIEdub21vdmlzaW9uIHZlcnNpb24gNjksIENvcHlyaWdodCAoQykgeWVhciBuYW1lIG9mIGF1dGhvcgorICAgICAgICBHbm9tb3Zpc2lvbiBjb21lcyB3aXRoIEFCU09MVVRFTFkgTk8gV0FSUkFOVFk7IGZvciBkZXRhaWxzIHR5cGUKKyAgICAgICAgYHNob3cgdycuIFRoaXMgaXMgZnJlZSBzb2Z0d2FyZSwgYW5kIHlvdSBhcmUgd2VsY29tZSB0byByZWRpc3RyaWJ1dGUKKyAgICAgICAgaXQgdW5kZXIgY2VydGFpbiBjb25kaXRpb25zOyB0eXBlIGBzaG93IGMnIGZvciBkZXRhaWxzLgorCisgICAgVGhlIGh5cG90aGV0aWNhbCBjb21tYW5kcyBgc2hvdyB3JyBhbmQgYHNob3cgYycgc2hvdWxkIHNob3cgdGhlCisgICAgYXBwcm9wcmlhdGUgcGFydHMgb2YgdGhlIEdlbmVyYWwgUHVibGljIExpY2Vuc2UuIE9mIGNvdXJzZSwgdGhlIGNvbW1hbmRzCisgICAgeW91IHVzZSBtYXkgYmUgY2FsbGVkIHNvbWV0aGluZyBvdGhlciB0aGFuIGBzaG93IHcnIGFuZCBgc2hvdyBjJzsgdGhleQorICAgIGNvdWxkIGV2ZW4gYmUgbW91c2UtY2xpY2tzIG9yIG1lbnUgaXRlbXMtLXdoYXRldmVyIHN1aXRzIHlvdXIgcHJvZ3JhbS4KKworICAgIFlvdSBzaG91bGQgYWxzbyBnZXQgeW91ciBlbXBsb3llciAoaWYgeW91IHdvcmsgYXMgYSBwcm9ncmFtbWVyKSBvciB5b3VyCisgICAgc2Nob29sLCBpZiBhbnksIHRvIHNpZ24gYSAiY29weXJpZ2h0IGRpc2NsYWltZXIiIGZvciB0aGUgcHJvZ3JhbSwgaWYKKyAgICBuZWNlc3NhcnkuIEhlcmUgaXMgYSBzYW1wbGU7IGFsdGVyIHRoZSBuYW1lczoKKworICAgICAgICBZb3lvZHluZSwgSW5jLiwgaGVyZWJ5IGRpc2NsYWltcyBhbGwgY29weXJpZ2h0IGludGVyZXN0IGluIHRoZQorICAgICAgICBwcm9ncmFtIGBHbm9tb3Zpc2lvbicgKHdoaWNoIG1ha2VzIHBhc3NlcyBhdCBjb21waWxlcnMpIHdyaXR0ZW4gYnkKKyAgICAgICAgSmFtZXMgSGFja2VyLgorCisgICAgICAgIHNpZ25hdHVyZSBvZiBUeSBDb29uLCAxIEFwcmlsIDE5ODkKKyAgICAgICAgVHkgQ29vbiwgUHJlc2lkZW50IG9mIFZpY2UKKworICAgIFRoaXMgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBkb2VzIG5vdCBwZXJtaXQgaW5jb3Jwb3JhdGluZyB5b3VyIHByb2dyYW0KKyAgICBpbnRvIHByb3ByaWV0YXJ5IHByb2dyYW1zLiBJZiB5b3VyIHByb2dyYW0gaXMgYSBzdWJyb3V0aW5lIGxpYnJhcnksIHlvdQorICAgIG1heSBjb25zaWRlciBpdCBtb3JlIHVzZWZ1bCB0byBwZXJtaXQgbGlua2luZyBwcm9wcmlldGFyeSBhcHBsaWNhdGlvbnMKKyAgICB3aXRoIHRoZSBsaWJyYXJ5LiBJZiB0aGlzIGlzIHdoYXQgeW91IHdhbnQgdG8gZG8sIHVzZSB0aGUgR05VIExpYnJhcnkKKyAgICBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGluc3RlYWQgb2YgdGhpcyBMaWNlbnNlLgorCistLS0KKworIyMgQ0xBU1NQQVRIIEVYQ0VQVElPTgorCisgICAgTGlua2luZyB0aGlzIGxpYnJhcnkgc3RhdGljYWxseSBvciBkeW5hbWljYWxseSB3aXRoIG90aGVyIG1vZHVsZXMgaXMKKyAgICBtYWtpbmcgYSBjb21iaW5lZCB3b3JrIGJhc2VkIG9uIHRoaXMgbGlicmFyeS4gIFRodXMsIHRoZSB0ZXJtcyBhbmQKKyAgICBjb25kaXRpb25zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgY292ZXIgdGhlIHdob2xlCisgICAgY29tYmluYXRpb24uCisKKyAgICBBcyBhIHNwZWNpYWwgZXhjZXB0aW9uLCB0aGUgY29weXJpZ2h0IGhvbGRlcnMgb2YgdGhpcyBsaWJyYXJ5IGdpdmUgeW91CisgICAgcGVybWlzc2lvbiB0byBsaW5rIHRoaXMgbGlicmFyeSB3aXRoIGluZGVwZW5kZW50IG1vZHVsZXMgdG8gcHJvZHVjZSBhbgorICAgIGV4ZWN1dGFibGUsIHJlZ2FyZGxlc3Mgb2YgdGhlIGxpY2Vuc2UgdGVybXMgb2YgdGhlc2UgaW5kZXBlbmRlbnQKKyAgICBtb2R1bGVzLCBhbmQgdG8gY29weSBhbmQgZGlzdHJpYnV0ZSB0aGUgcmVzdWx0aW5nIGV4ZWN1dGFibGUgdW5kZXIKKyAgICB0ZXJtcyBvZiB5b3VyIGNob2ljZSwgcHJvdmlkZWQgdGhhdCB5b3UgYWxzbyBtZWV0LCBmb3IgZWFjaCBsaW5rZWQKKyAgICBpbmRlcGVuZGVudCBtb2R1bGUsIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB0aGUgbGljZW5zZSBvZiB0aGF0CisgICAgbW9kdWxlLiAgQW4gaW5kZXBlbmRlbnQgbW9kdWxlIGlzIGEgbW9kdWxlIHdoaWNoIGlzIG5vdCBkZXJpdmVkIGZyb20gb3IKKyAgICBiYXNlZCBvbiB0aGlzIGxpYnJhcnkuICBJZiB5b3UgbW9kaWZ5IHRoaXMgbGlicmFyeSwgeW91IG1heSBleHRlbmQgdGhpcworICAgIGV4Y2VwdGlvbiB0byB5b3VyIHZlcnNpb24gb2YgdGhlIGxpYnJhcnksIGJ1dCB5b3UgYXJlIG5vdCBvYmxpZ2F0ZWQgdG8KKyAgICBkbyBzby4gIElmIHlvdSBkbyBub3Qgd2lzaCB0byBkbyBzbywgZGVsZXRlIHRoaXMgZXhjZXB0aW9uIHN0YXRlbWVudAorICAgIGZyb20geW91ciB2ZXJzaW9uLgpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9yZXNvdXJjZXMvTUVUQS1JTkYvTUFOSUZFU1QuTUYgYi9tYWlsL3NyYy9tYWluL3Jlc291cmNlcy9NRVRBLUlORi9NQU5JRkVTVC5NRgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kYjVhY2Y2Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9yZXNvdXJjZXMvTUVUQS1JTkYvTUFOSUZFU1QuTUYKQEAgLTAsMCArMSw5IEBACitNYW5pZmVzdC1WZXJzaW9uOiAxLjAKK0V4dGVuc2lvbi1OYW1lOiBqYXZheC5tYWlsCitTcGVjaWZpY2F0aW9uLVRpdGxlOiBKYXZhTWFpbChUTSkgQVBJIERlc2lnbiBTcGVjaWZpY2F0aW9uCitTcGVjaWZpY2F0aW9uLVZlcnNpb246ICR7bWFpbC5zcGVjLnZlcnNpb259CitTcGVjaWZpY2F0aW9uLVZlbmRvcjogJHtwcm9qZWN0Lm9yZ2FuaXphdGlvbi5uYW1lfQorSW1wbGVtZW50YXRpb24tVGl0bGU6IGphdmF4Lm1haWwKK0ltcGxlbWVudGF0aW9uLVZlcnNpb246ICR7bWFpbC52ZXJzaW9ufQorSW1wbGVtZW50YXRpb24tVmVuZG9yOiAke3Byb2plY3Qub3JnYW5pemF0aW9uLm5hbWV9CitJbXBsZW1lbnRhdGlvbi1WZW5kb3ItSWQ6IGNvbS5zdW4KZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vcmVzb3VyY2VzL01FVEEtSU5GL2dmcHJvYmUtcHJvdmlkZXIueG1sIGIvbWFpbC9zcmMvbWFpbi9yZXNvdXJjZXMvTUVUQS1JTkYvZ2Zwcm9iZS1wcm92aWRlci54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjUxMTk1OQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vcmVzb3VyY2VzL01FVEEtSU5GL2dmcHJvYmUtcHJvdmlkZXIueG1sCkBAIC0wLDAgKzEsNjkgQEAKKzw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04Ij8+Cis8IS0tCisKKyAgICBDb3B5cmlnaHQgKGMpIDIwMTAsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKworICAgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICAgIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorCisgICAgVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICAgIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAgICBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAgICB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKworICAgIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorCistLT4KKworPHByb2JlLXByb3ZpZGVycz4KKyAgPHByb2JlLXByb3ZpZGVyIG1vZHVsZVByb3ZpZGVyTmFtZT0iZ2xhc3NmaXNoIiBtb2R1bGVOYW1lPSJqYXZhbWFpbCIKKyAgICAgIHByb2JlUHJvdmlkZXJOYW1lPSJzbXRwLXRyYW5zcG9ydCIKKyAgICAgIGNsYXNzPSJjb20uc3VuLm1haWwuc210cC5TTVRQVHJhbnNwb3J0Ij4KKyAgICA8cHJvYmUgbmFtZT0ic2VuZE1lc3NhZ2VTdGFydCI+CisgICAgICA8bWV0aG9kPnNlbmRNZXNzYWdlU3RhcnQ8L21ldGhvZD4KKyAgICAgIDxwcm9iZS1wYXJhbSB0eXBlPSJqYXZhLmxhbmcuU3RyaW5nIiBuYW1lPSJzdWJqZWN0IiAvPgorICAgICAgPHJldHVybi1wYXJhbSB0eXBlPSJ2b2lkIiAvPgorICAgIDwvcHJvYmU+CisgICAgPHByb2JlIG5hbWU9InNlbmRNZXNzYWdlRW5kIj4KKyAgICAgIDxtZXRob2Q+c2VuZE1lc3NhZ2VFbmQ8L21ldGhvZD4KKyAgICAgIDxyZXR1cm4tcGFyYW0gdHlwZT0idm9pZCIgLz4KKyAgICA8L3Byb2JlPgorICA8L3Byb2JlLXByb3ZpZGVyPgorICA8cHJvYmUtcHJvdmlkZXIgbW9kdWxlUHJvdmlkZXJOYW1lPSJnbGFzc2Zpc2giIG1vZHVsZU5hbWU9ImphdmFtYWlsIgorICAgICAgcHJvYmVQcm92aWRlck5hbWU9ImlhcC1wcm90b2NvbCIKKyAgICAgIGNsYXNzPSJjb20uc3VuLm1haWwuaWFwLlByb3RvY29sIj4KKyAgICA8cHJvYmUgbmFtZT0iY29tbWFuZFN0YXJ0Ij4KKyAgICAgIDxtZXRob2Q+Y29tbWFuZFN0YXJ0PC9tZXRob2Q+CisgICAgICA8cHJvYmUtcGFyYW0gdHlwZT0iamF2YS5sYW5nLlN0cmluZyIgbmFtZT0iY29tbWFuZCIgLz4KKyAgICAgIDxyZXR1cm4tcGFyYW0gdHlwZT0idm9pZCIgLz4KKyAgICA8L3Byb2JlPgorICAgIDxwcm9iZSBuYW1lPSJjb21tYW5kRW5kIj4KKyAgICAgIDxtZXRob2Q+Y29tbWFuZEVuZDwvbWV0aG9kPgorICAgICAgPHJldHVybi1wYXJhbSB0eXBlPSJ2b2lkIiAvPgorICAgIDwvcHJvYmU+CisgIDwvcHJvYmUtcHJvdmlkZXI+CisgIDxwcm9iZS1wcm92aWRlciBtb2R1bGVQcm92aWRlck5hbWU9ImdsYXNzZmlzaCIgbW9kdWxlTmFtZT0iamF2YW1haWwiCisgICAgICBwcm9iZVByb3ZpZGVyTmFtZT0icG9wMy1wcm90b2NvbCIKKyAgICAgIGNsYXNzPSJjb20uc3VuLm1haWwucG9wMy5Qcm90b2NvbCI+CisgICAgPHByb2JlIG5hbWU9InNpbXBsZUNvbW1hbmRTdGFydCI+CisgICAgICA8bWV0aG9kPnNpbXBsZUNvbW1hbmRTdGFydDwvbWV0aG9kPgorICAgICAgPHByb2JlLXBhcmFtIHR5cGU9ImphdmEubGFuZy5TdHJpbmciIG5hbWU9ImNvbW1hbmQiIC8+CisgICAgICA8cmV0dXJuLXBhcmFtIHR5cGU9InZvaWQiIC8+CisgICAgPC9wcm9iZT4KKyAgICA8cHJvYmUgbmFtZT0ic2ltcGxlQ29tbWFuZEVuZCI+CisgICAgICA8bWV0aG9kPnNpbXBsZUNvbW1hbmRFbmQ8L21ldGhvZD4KKyAgICAgIDxyZXR1cm4tcGFyYW0gdHlwZT0idm9pZCIgLz4KKyAgICA8L3Byb2JlPgorICAgIDxwcm9iZSBuYW1lPSJtdWx0aWxpbmVDb21tYW5kU3RhcnQiPgorICAgICAgPG1ldGhvZD5tdWx0aWxpbmVDb21tYW5kU3RhcnQ8L21ldGhvZD4KKyAgICAgIDxwcm9iZS1wYXJhbSB0eXBlPSJqYXZhLmxhbmcuU3RyaW5nIiBuYW1lPSJjb21tYW5kIiAvPgorICAgICAgPHJldHVybi1wYXJhbSB0eXBlPSJ2b2lkIiAvPgorICAgIDwvcHJvYmU+CisgICAgPHByb2JlIG5hbWU9Im11bHRpbGluZUNvbW1hbmRFbmQiPgorICAgICAgPG1ldGhvZD5tdWx0aWxpbmVDb21tYW5kRW5kPC9tZXRob2Q+CisgICAgICA8cmV0dXJuLXBhcmFtIHR5cGU9InZvaWQiIC8+CisgICAgPC9wcm9iZT4KKyAgPC9wcm9iZS1wcm92aWRlcj4KKzwvcHJvYmUtcHJvdmlkZXJzPgpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9yZXNvdXJjZXMvTUVUQS1JTkYvaGsyLWxvY2F0b3IvZGVmYXVsdCBiL21haWwvc3JjL21haW4vcmVzb3VyY2VzL01FVEEtSU5GL2hrMi1sb2NhdG9yL2RlZmF1bHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjI2ZmYxZAotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL21haW4vcmVzb3VyY2VzL01FVEEtSU5GL2hrMi1sb2NhdG9yL2RlZmF1bHQKQEAgLTAsMCArMSw5IEBACisjCisjIFRoaXMgbWV0YWRhdGEgYWxsb3dzIGNvbS5zdW4ubWFpbC51dGlsLmxvZ2dpbmcuTWFpbEhhbmRsZXIgdG8gYmUKKyMgY29uZmlndXJlZCBpbiB0aGUgbG9nZ2luZy5wcm9wZXJ0aWVzIGZpbGUgYW5kIHVzZWQgaW4gR2xhc3NGaXNoLgorIyBUaGlzIGZpbGUgd2FzIGNyZWF0ZWQgYnkgaGFuZCB0byBhdm9pZCBhIGNvbXBpbGUgdGltZSBkZXBlbmRlbmN5CisjIG9uIHRoZSBISzIgYW5ub3RhdGlvbnMuCisjCitbY29tLnN1bi5tYWlsLnV0aWwubG9nZ2luZy5NYWlsSGFuZGxlcl0KK2NvbnRyYWN0PXtqYXZhLnV0aWwubG9nZ2luZy5IYW5kbGVyfQorc2NvcGU9amF2YXguaW5qZWN0LlNpbmdsZXRvbgpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9yZXNvdXJjZXMvTUVUQS1JTkYvamF2YW1haWwuY2hhcnNldC5tYXAgYi9tYWlsL3NyYy9tYWluL3Jlc291cmNlcy9NRVRBLUlORi9qYXZhbWFpbC5jaGFyc2V0Lm1hcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jYzU4ZDRmCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9yZXNvdXJjZXMvTUVUQS1JTkYvamF2YW1haWwuY2hhcnNldC5tYXAKQEAgLTAsMCArMSw3NyBAQAorIyMjIEpESy10by1NSU1FIGNoYXJzZXQgbWFwcGluZyB0YWJsZSAjIyMjCisjIyMgVGhpcyBzaG91bGQgYmUgdGhlIGZpcnN0IG1hcHBpbmcgdGFibGUgIyMjCisKKzg4NTlfMQkJSVNPLTg4NTktMQoraXNvODg1OV8xCUlTTy04ODU5LTEKK0lTTzg4NTktMQlJU08tODg1OS0xCisKKzg4NTlfMgkJSVNPLTg4NTktMgoraXNvODg1OV8yCUlTTy04ODU5LTIKK0lTTzg4NTktMglJU08tODg1OS0yCisKKzg4NTlfMwkJSVNPLTg4NTktMworaXNvODg1OV8zCUlTTy04ODU5LTMKK0lTTzg4NTktMwlJU08tODg1OS0zCisKKzg4NTlfNAkJSVNPLTg4NTktNAoraXNvODg1OV80CUlTTy04ODU5LTQKK0lTTzg4NTktNAlJU08tODg1OS00CisKKzg4NTlfNQkJSVNPLTg4NTktNQoraXNvODg1OV81CUlTTy04ODU5LTUKK0lTTzg4NTktNQlJU08tODg1OS01CisKKzg4NTlfNgkJSVNPLTg4NTktNgoraXNvODg1OV82CUlTTy04ODU5LTYKK0lTTzg4NTktNglJU08tODg1OS02CisKKzg4NTlfNwkJSVNPLTg4NTktNworaXNvODg1OV83CUlTTy04ODU5LTcKK0lTTzg4NTktNwlJU08tODg1OS03CisKKzg4NTlfOAkJSVNPLTg4NTktOAoraXNvODg1OV84CUlTTy04ODU5LTgKK0lTTzg4NTktOAlJU08tODg1OS04CisKKzg4NTlfOQkJSVNPLTg4NTktOQoraXNvODg1OV85CUlTTy04ODU5LTkKK0lTTzg4NTktOQlJU08tODg1OS05CisKK1NKSVMJCVNoaWZ0X0pJUworSklTCQlJU08tMjAyMi1KUAorSVNPMjAyMkpQCUlTTy0yMDIyLUpQCitFVUNfSlAJCWV1Yy1qcAorS09JOF9SCQlrb2k4LXIKK0VVQ19DTgkJZXVjLWNuCitFVUNfVFcJCWV1Yy10dworRVVDX0tSCQlldWMta3IKKworLS1ESVZJREVSOiB0aGlzIGxpbmUgKm11c3QqIHN0YXJ0IHdpdGggIi0tIiBhbmQgZW5kIHdpdGggIi0tIiAtLQorCisjIyMjIFhYWC10by1KREsgY2hhcnNldCBtYXBwaW5nIHRhYmxlICMjIyMKKworaXNvLTIwMjItY24gICAgIElTTzIwMjJDTgoraXNvLTIwMjIta3IgICAgIElTTzIwMjJLUgordXRmLTggICAgICAgICAgIFVURjgKK3V0ZjgJCVVURjgKK2phX2pwLmlzbzIwMjItNyBJU08yMDIySlAKK2phX2pwLmV1Y2pwICAgICBFVUNKSVMKKworIyB0aGVzZSB0d28gYXJlIG5vdCBuZWVkZWQgaW4gMS4xLjYuICAoc2luY2UgRVVDX0tSIGV4aXN0cworIyBhbmQgS1NDNTYwMSB3aWxsIG1hcCB0byB0aGUgY29ycmVjdCBjb252ZXJ0ZXIpCitldWMta3IgICAgICAgICAgS1NDNTYwMQorZXVja3IgICAgICAgICAgIEtTQzU2MDEKKworIyBpbiBKREsgMS4xLjYgd2Ugd2lsbCBubyBsb25nZXIgbmVlZCB0aGUgInVzLWFzY2lpIiBjb252ZXJ0Cit1cy1hc2NpaSAgICAgICAgSVNPLTg4NTktMQoreC11cy1hc2NpaSAgICAgIElTTy04ODU5LTEKKworIyBDaGluZXNlIGNoYXJzZXRzIGFyZSBhIG1lc3MgYW5kIHdpZGVseSBtaXNyZXByZXNlbnRlZC4KKyMgZ2IxODAzMCBpcyBhIHN1cGVyc2V0IG9mIGdiaywgd2hpY2ggaXMgYSBzdXBzZXJzZXQgb2YgY3A5MzYvbXM5MzYsCisjIHdoaWNoIGlzIGEgc3VwZXJzZXQgb2YgZ2IyMzEyLgorIyBodHRwczovL2J1Z3ppbGxhLmdub21lLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9NDQ2NzgzCisjIG1hcCBhbGwgb2YgdGhlc2UgdG8gZ2IxODAzMC4KK2diMjMxMgkJR0IxODAzMAorY3A5MzYJCUdCMTgwMzAKK21zOTM2CQlHQjE4MDMwCitnYmsJCUdCMTgwMzAKZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vcmVzb3VyY2VzL01FVEEtSU5GL2phdmFtYWlsLmRlZmF1bHQuYWRkcmVzcy5tYXAgYi9tYWlsL3NyYy9tYWluL3Jlc291cmNlcy9NRVRBLUlORi9qYXZhbWFpbC5kZWZhdWx0LmFkZHJlc3MubWFwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRhYjU1NzIKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL3Jlc291cmNlcy9NRVRBLUlORi9qYXZhbWFpbC5kZWZhdWx0LmFkZHJlc3MubWFwCkBAIC0wLDAgKzEgQEAKK3JmYzgyMj1zbXRwCmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL3Jlc291cmNlcy9NRVRBLUlORi9qYXZhbWFpbC5kZWZhdWx0LnByb3ZpZGVycyBiL21haWwvc3JjL21haW4vcmVzb3VyY2VzL01FVEEtSU5GL2phdmFtYWlsLmRlZmF1bHQucHJvdmlkZXJzCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJlZGMwNzYKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL3Jlc291cmNlcy9NRVRBLUlORi9qYXZhbWFpbC5kZWZhdWx0LnByb3ZpZGVycwpAQCAtMCwwICsxLDkgQEAKKyMgSmF2YU1haWwgSU1BUCBwcm92aWRlciBPcmFjbGUKK3Byb3RvY29sPWltYXA7IHR5cGU9c3RvcmU7IGNsYXNzPWNvbS5zdW4ubWFpbC5pbWFwLklNQVBTdG9yZTsgdmVuZG9yPU9yYWNsZTsKK3Byb3RvY29sPWltYXBzOyB0eXBlPXN0b3JlOyBjbGFzcz1jb20uc3VuLm1haWwuaW1hcC5JTUFQU1NMU3RvcmU7IHZlbmRvcj1PcmFjbGU7CisjIEphdmFNYWlsIFNNVFAgcHJvdmlkZXIgT3JhY2xlCitwcm90b2NvbD1zbXRwOyB0eXBlPXRyYW5zcG9ydDsgY2xhc3M9Y29tLnN1bi5tYWlsLnNtdHAuU01UUFRyYW5zcG9ydDsgdmVuZG9yPU9yYWNsZTsKK3Byb3RvY29sPXNtdHBzOyB0eXBlPXRyYW5zcG9ydDsgY2xhc3M9Y29tLnN1bi5tYWlsLnNtdHAuU01UUFNTTFRyYW5zcG9ydDsgdmVuZG9yPU9yYWNsZTsKKyMgSmF2YU1haWwgUE9QMyBwcm92aWRlciBPcmFjbGUKK3Byb3RvY29sPXBvcDM7IHR5cGU9c3RvcmU7IGNsYXNzPWNvbS5zdW4ubWFpbC5wb3AzLlBPUDNTdG9yZTsgdmVuZG9yPU9yYWNsZTsKK3Byb3RvY29sPXBvcDNzOyB0eXBlPXN0b3JlOyBjbGFzcz1jb20uc3VuLm1haWwucG9wMy5QT1AzU1NMU3RvcmU7IHZlbmRvcj1PcmFjbGU7CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9tYWluL3Jlc291cmNlcy9NRVRBLUlORi9tYWlsY2FwIGIvbWFpbC9zcmMvbWFpbi9yZXNvdXJjZXMvTUVUQS1JTkYvbWFpbGNhcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MjU5YWU3Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9yZXNvdXJjZXMvTUVUQS1JTkYvbWFpbGNhcApAQCAtMCwwICsxLDE2IEBACisjCisjCisjIERlZmF1bHQgbWFpbGNhcCBmaWxlIGZvciB0aGUgSmF2YU1haWwgU3lzdGVtLgorIworIyBKYXZhTWFpbCBjb250ZW50LWhhbmRsZXJzOgorIwordGV4dC9wbGFpbjs7CQl4LWphdmEtY29udGVudC1oYW5kbGVyPWNvbS5zdW4ubWFpbC5oYW5kbGVycy50ZXh0X3BsYWluCit0ZXh0L2h0bWw7OwkJeC1qYXZhLWNvbnRlbnQtaGFuZGxlcj1jb20uc3VuLm1haWwuaGFuZGxlcnMudGV4dF9odG1sCit0ZXh0L3htbDs7CQl4LWphdmEtY29udGVudC1oYW5kbGVyPWNvbS5zdW4ubWFpbC5oYW5kbGVycy50ZXh0X3htbAorbXVsdGlwYXJ0Lyo7OwkJeC1qYXZhLWNvbnRlbnQtaGFuZGxlcj1jb20uc3VuLm1haWwuaGFuZGxlcnMubXVsdGlwYXJ0X21peGVkOyB4LWphdmEtZmFsbGJhY2stZW50cnk9dHJ1ZQorbWVzc2FnZS9yZmM4MjI7Owl4LWphdmEtY29udGVudC1oYW5kbGVyPWNvbS5zdW4ubWFpbC5oYW5kbGVycy5tZXNzYWdlX3JmYzgyMgorIworIyBjYW4ndCBzdXBwb3J0IGltYWdlIHR5cGVzIGJlY2F1c2UgamF2YS5hd3QuVG9vbGtpdCBkb2Vzbid0IHdvcmsgb24gc2VydmVycworIworI2ltYWdlL2dpZjs7CQl4LWphdmEtY29udGVudC1oYW5kbGVyPWNvbS5zdW4ubWFpbC5oYW5kbGVycy5pbWFnZV9naWYKKyNpbWFnZS9qcGVnOzsJCXgtamF2YS1jb250ZW50LWhhbmRsZXI9Y29tLnN1bi5tYWlsLmhhbmRsZXJzLmltYWdlX2pwZWcKZGlmZiAtLWdpdCBhL21haWwvc3JjL21haW4vcmVzb3VyY2VzL01FVEEtSU5GL3NlcnZpY2VzL2phdmF4Lm1haWwuUHJvdmlkZXIgYi9tYWlsL3NyYy9tYWluL3Jlc291cmNlcy9NRVRBLUlORi9zZXJ2aWNlcy9qYXZheC5tYWlsLlByb3ZpZGVyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ2ODhlNWEKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9tYWluL3Jlc291cmNlcy9NRVRBLUlORi9zZXJ2aWNlcy9qYXZheC5tYWlsLlByb3ZpZGVyCkBAIC0wLDAgKzEsNiBAQAorY29tLnN1bi5tYWlsLmltYXAuSU1BUFByb3ZpZGVyCitjb20uc3VuLm1haWwuaW1hcC5JTUFQU1NMUHJvdmlkZXIKK2NvbS5zdW4ubWFpbC5zbXRwLlNNVFBQcm92aWRlcgorY29tLnN1bi5tYWlsLnNtdHAuU01UUFNTTFByb3ZpZGVyCitjb20uc3VuLm1haWwucG9wMy5QT1AzUHJvdmlkZXIKK2NvbS5zdW4ubWFpbC5wb3AzLlBPUDNTU0xQcm92aWRlcgpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvbWFpbi9yZXNvdXJjZXMvamF2YXgvbWFpbC9WZXJzaW9uLmphdmEgYi9tYWlsL3NyYy9tYWluL3Jlc291cmNlcy9qYXZheC9tYWlsL1ZlcnNpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMWQ5ODk5Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvbWFpbi9yZXNvdXJjZXMvamF2YXgvbWFpbC9WZXJzaW9uLmphdmEKQEAgLTAsMCArMSwyNiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsOworCisvKioKKyAqIFBhY2thZ2UtcHJpdmF0ZSBjbGFzcyB0aGF0IGRlZmluZXMgdGhlIHZlcnNpb24gb2YgSmF2YU1haWwuCisgKiBUaGlzIGZpbGUgaXMgYSB0ZW1wbGF0ZSBmb3IgdGhlIGNsYXNzIHRoYXQgaXMgZ2VuZXJhdGVkCisgKiBhdCBidWlsZCB0aW1lLgorICovCitjbGFzcyBWZXJzaW9uIHsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyB2ZXJzaW9uID0gIiR7bWFpbC52ZXJzaW9ufSI7Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9vbGR0ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9kZWNvZGV0ZXN0IGIvbWFpbC9zcmMvb2xkdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvZGVjb2RldGVzdApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ZDdmNDk2Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvb2xkdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvZGVjb2RldGVzdApAQCAtMCwwICsxLDQgQEAKKyMhL2Jpbi9zaAoramF2YSBkZWNvZGV0ZXh0IDwgZW5jb2RlZGhlYWRlcnMuZGF0YSA+IHgxCitqYXZhIC1EbWFpbC5taW1lLmRlY29kZXRleHQuc3RyaWN0PWZhbHNlIGRlY29kZXRleHQgPCBlbmNvZGVkaGVhZGVycy5kYXRhID4geDIKK2RpZmYgLWMgeDEgeDIKZGlmZiAtLWdpdCBhL21haWwvc3JjL29sZHRlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L2VuY29kZWRoZWFkZXJzLmRhdGEgYi9tYWlsL3NyYy9vbGR0ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9lbmNvZGVkaGVhZGVycy5kYXRhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU4NTM3MzYKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9vbGR0ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9lbmNvZGVkaGVhZGVycy5kYXRhCkBAIC0wLDAgKzEsMjggQEAKKz0/SVNPLTg4NTktMT9CP1NXWWdlVzkxSUdOaGJpQnlaV0ZrSUhSb2FYTWdlVzg9Pz0KKyA9P0lTTy04ODU5LTI/Qj9kU0IxYm1SbGNuTjBZVzVrSUhSb1pTQmxlR0Z0Y0d4bExnPT0/PSBDb25ncmF0cyEKK0hlbGxvIFdvcmxkCisgIEhlbGxvICAgCisJV29ybGQKKz0/SVNPLTg4NTktMT9RP0FuZHI9RTk/PSBQaXJhcmQgPFBJUkFSREB2bTEudWxnLmFjLmJlPgorPT9JU08tODg1OS0xP1E/S2VsZF9KPUY4cm5fU2ltb25zZW4/PSA8a2VsZEBka3V1Zy5kaz4KKz0/SVNPLTg4NTktMT9RP1BhdHJpa19GPUU0bHRzdHI9RjZtPz0gPHBhZkBuYWRhLmt0aC5zZT4KKz0/aXNvLTg4NTktOD9iPzdlWHMrU0R2NFNEcDdPajA4QT09Pz0KKz0/SVNPLTIwMjItSlA/Qj9HeVJDUW1kQ1BDRWhXRVl3YkU4Nkd5aEs/PQorW21penVraSAxMDA3XSBSZTogSGFqaW1lbWFzaXRlISEKK0thenV5dWtpIE11cmF0YSA8aGlyb2tvQGhhbWFra28ub3IuanA+CitbbWl6dWtpIDEwMDldID0/SVNPLTIwMjItSlA/Qj9HeVJDSlVZbGJDVlRQVkF4YVQ1d1NuTWJLRUk9Pz0KKz0/SVNPLTg4NTktMT9RP2E/PQorPT9JU08tODg1OS0xP1E/YT89IGIKKz0/SVNPLTg4NTktMT9RP2E/PSA9P0lTTy04ODU5LTE/UT9iPz0KKz0/SVNPLTg4NTktMT9RP2E/PSAgPT9JU08tODg1OS0xP1E/Yj89Cis9P0lTTy04ODU5LTE/UT9hX2I/PQorPT9JU08tODg1OS0xP1E/YT89ID0/SVNPLTg4NTktMj9RP19iPz0KKz0/VVMtQVNDSUk/UT9LZWl0aF9Nb29yZT89Cis9P0lTTy04ODU5LTE/Qj9TV1lnZVc5MUlHTmhiaUJ5WldGa0lIUm9hWE1nZVc4PT89Cis9P0lTTy04ODU5LTI/Qj9kU0IxYm1SbGNuTjBZVzVrSUhSb1pTQmxlR0Z0Y0d4bExnPT0/PQorPT9JU08tODg1OS0xP1E/T2xsZV9KPUU0cm5lZm9ycz89CisKK2JhYmFiYWJhPT9JU08tMjAyMi1KUD9CP0d5UkNNajBrTVNSckd5aEs/PQorYmFiYWJhYmE9P0lTTy0yMDIyLUpQP0I/R3lSQ01qMGtNU1JyR3loSz89YmFiYWJhYmEKK2JhYmFiYSA9P0lTTy0yMDIyLUpQP0I/SUJza1FqSTlKREVrYXhzb1NnPT0/PQorPT9JU08tODg1OS0xP1E/YT89PT9JU08tODg1OS0xP1E/Yj89CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9vbGR0ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9tZXNzYWdlY2FjaGV0ZXN0LmphdmEgYi9tYWlsL3NyYy9vbGR0ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9tZXNzYWdlY2FjaGV0ZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzRlNTZhMgotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL29sZHRlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L21lc3NhZ2VjYWNoZXRlc3QuamF2YQpAQCAtMCwwICsxLDMwMiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworaW1wb3J0IGphdmEudXRpbC4qOworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZheC5tYWlsLio7CitpbXBvcnQgamF2YXgubWFpbC5ldmVudC4qOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuKjsKK2ltcG9ydCBqYXZheC5hY3RpdmF0aW9uLio7CisKKy8qCisgKiBUZXN0IElNQVAgbWVzc2FnZSBjYWNoZS4KKyAqCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCisKK3B1YmxpYyBjbGFzcyBtZXNzYWdlY2FjaGV0ZXN0IHsKKworICAgIHN0YXRpYyBTdHJpbmcgcHJvdG9jb2w7CisgICAgc3RhdGljIFN0cmluZyBob3N0ID0gbnVsbDsKKyAgICBzdGF0aWMgU3RyaW5nIHVzZXIgPSBudWxsOworICAgIHN0YXRpYyBTdHJpbmcgcGFzc3dvcmQgPSBudWxsOworICAgIHN0YXRpYyBTdHJpbmcgbWJveCA9IG51bGw7CisgICAgc3RhdGljIFN0cmluZyB1cmwgPSBudWxsOworICAgIHN0YXRpYyBpbnQgcG9ydCA9IC0xOworICAgIHN0YXRpYyBib29sZWFuIHZlcmJvc2UgPSBmYWxzZTsKKyAgICBzdGF0aWMgYm9vbGVhbiBkZWJ1ZyA9IGZhbHNlOworICAgIHN0YXRpYyBTZXNzaW9uIHNlc3Npb247CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmcgYXJndltdKSB7CisJaW50IG51bW1zZyA9IDI1NjsKKwlpbnQgb3B0aW5kOworCisJZm9yIChvcHRpbmQgPSAwOyBvcHRpbmQgPCBhcmd2Lmxlbmd0aDsgb3B0aW5kKyspIHsKKwkgICAgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1UIikpIHsKKwkJcHJvdG9jb2wgPSBhcmd2Wysrb3B0aW5kXTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItSCIpKSB7CisJCWhvc3QgPSBhcmd2Wysrb3B0aW5kXTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItVSIpKSB7CisJCXVzZXIgPSBhcmd2Wysrb3B0aW5kXTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItUCIpKSB7CisJCXBhc3N3b3JkID0gYXJndlsrK29wdGluZF07CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLXYiKSkgeworCQl2ZXJib3NlID0gdHJ1ZTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItRCIpKSB7CisJCWRlYnVnID0gdHJ1ZTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItZiIpKSB7CisJCW1ib3ggPSBhcmd2Wysrb3B0aW5kXTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItTCIpKSB7CisJCXVybCA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1wIikpIHsKKwkJcG9ydCA9IEludGVnZXIucGFyc2VJbnQoYXJndlsrK29wdGluZF0pOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi0tIikpIHsKKwkJb3B0aW5kKys7CisJCWJyZWFrOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5zdGFydHNXaXRoKCItIikpIHsKKwkJU3lzdGVtLm91dC5wcmludGxuKAorIlVzYWdlOiBtZXNzYWdlY2FjaGV0ZXN0IFstTCB1cmxdIFstVCBwcm90b2NvbF0gWy1IIGhvc3RdIFstcCBwb3J0XSBbLVUgdXNlcl0iKTsKKwkJU3lzdGVtLm91dC5wcmludGxuKAorIlx0Wy1QIHBhc3N3b3JkXSBbLWYgbWFpbGJveF0gW21zZ251bV0gWy12XSBbLURdIik7CisJCVN5c3RlbS5leGl0KDEpOworCSAgICB9IGVsc2UgeworCQlicmVhazsKKwkgICAgfQorCX0KKworCXRyeSB7CisJICAgIGlmIChvcHRpbmQgPCBhcmd2Lmxlbmd0aCkKKwkJIG51bW1zZyA9IEludGVnZXIucGFyc2VJbnQoYXJndltvcHRpbmRdKTsKKworCSAgICAvLyBHZXQgYSBQcm9wZXJ0aWVzIG9iamVjdAorCSAgICBQcm9wZXJ0aWVzIHByb3BzID0gU3lzdGVtLmdldFByb3BlcnRpZXMoKTsKKworCSAgICAvLyBHZXQgYSBTZXNzaW9uIG9iamVjdAorCSAgICBzZXNzaW9uID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShwcm9wcywgbnVsbCk7CisJICAgIHNlc3Npb24uc2V0RGVidWcoZGVidWcpOworCisJICAgIC8vIEdldCBhIFN0b3JlIG9iamVjdAorCSAgICBTdG9yZSBzdG9yZSA9IG51bGw7CisJICAgIGlmICh1cmwgIT0gbnVsbCkgeworCQlVUkxOYW1lIHVybG4gPSBuZXcgVVJMTmFtZSh1cmwpOworCQlzdG9yZSA9IHNlc3Npb24uZ2V0U3RvcmUodXJsbik7CisJCXN0b3JlLmNvbm5lY3QoKTsKKwkgICAgfSBlbHNlIHsKKwkJaWYgKHByb3RvY29sICE9IG51bGwpCQkKKwkJICAgIHN0b3JlID0gc2Vzc2lvbi5nZXRTdG9yZShwcm90b2NvbCk7CisJCWVsc2UKKwkJICAgIHN0b3JlID0gc2Vzc2lvbi5nZXRTdG9yZSgpOworCisJCS8vIENvbm5lY3QKKwkJaWYgKGhvc3QgIT0gbnVsbCB8fCB1c2VyICE9IG51bGwgfHwgcGFzc3dvcmQgIT0gbnVsbCkKKwkJICAgIHN0b3JlLmNvbm5lY3QoaG9zdCwgcG9ydCwgdXNlciwgcGFzc3dvcmQpOworCQllbHNlCisJCSAgICBzdG9yZS5jb25uZWN0KCk7CisJICAgIH0KKwkgICAgCisKKwkgICAgLy8gT3BlbiB0aGUgRm9sZGVyCisKKwkgICAgRm9sZGVyIGZvbGRlciA9IHN0b3JlLmdldERlZmF1bHRGb2xkZXIoKTsKKwkgICAgaWYgKGZvbGRlciA9PSBudWxsKSB7CisJCVN5c3RlbS5vdXQucHJpbnRsbigiTm8gZGVmYXVsdCBmb2xkZXIiKTsKKwkJU3lzdGVtLmV4aXQoMSk7CisJICAgIH0KKworCSAgICBpZiAobWJveCA9PSBudWxsKQorCQltYm94ID0gIm1lc3NhZ2VjYWNoZXRlc3QiOworCSAgICBmb2xkZXIgPSBmb2xkZXIuZ2V0Rm9sZGVyKG1ib3gpOworCSAgICBpZiAoZm9sZGVyID09IG51bGwpIHsKKwkJU3lzdGVtLm91dC5wcmludGxuKCJJbnZhbGlkIGZvbGRlciIpOworCQlTeXN0ZW0uZXhpdCgxKTsKKwkgICAgfQorCisJICAgIE1lc3NhZ2VbXSBtc2dzID0gY3JlYXRlTWVzc2FnZXMobnVtbXNnKTsKKwkgICAgaWYgKGZvbGRlci5leGlzdHMoKSkKKwkJZm9sZGVyLmRlbGV0ZShmYWxzZSk7CisJICAgIGZvbGRlci5jcmVhdGUoRm9sZGVyLkhPTERTX01FU1NBR0VTKTsKKworCSAgICBmb2xkZXIub3BlbihGb2xkZXIuUkVBRF9XUklURSk7CisJICAgIGlmICh2ZXJib3NlKQorCQlTeXN0ZW0ub3V0LnByaW50bG4oImZpbGwgZm9sZGVyIik7CisJICAgIGZvbGRlci5hcHBlbmRNZXNzYWdlcyhtc2dzKTsKKwkgICAgZm9sZGVyLmNsb3NlKGZhbHNlKTsKKworCSAgICBmb2xkZXIub3BlbihGb2xkZXIuUkVBRF9XUklURSk7CisJICAgIGlmICh2ZXJib3NlKQorCQlTeXN0ZW0ub3V0LnByaW50bG4oInRlc3QgbWVzc2FnZSBudW1iZXIiKTsKKwkgICAgdGVzdE1lc3NhZ2VOdW1iZXIoZm9sZGVyKTsKKwkgICAgZm9sZGVyLmNsb3NlKGZhbHNlKTsKKwkgICAgZm9sZGVyLm9wZW4oRm9sZGVyLlJFQURfV1JJVEUpOworCSAgICBpZiAodmVyYm9zZSkKKwkJU3lzdGVtLm91dC5wcmludGxuKCJ0ZXN0IGV4cHVuZ2UgZm9yd2FyZCIpOworCSAgICB0ZXN0RXhwdW5nZUZvcndhcmQoZm9sZGVyKTsKKwkgICAgZm9sZGVyLmNsb3NlKGZhbHNlKTsKKworCSAgICBmb2xkZXIub3BlbihGb2xkZXIuUkVBRF9XUklURSk7CisJICAgIGZvbGRlci5hcHBlbmRNZXNzYWdlcyhtc2dzKTsKKwkgICAgZm9sZGVyLmNsb3NlKGZhbHNlKTsKKwkgICAgZm9sZGVyLm9wZW4oRm9sZGVyLlJFQURfV1JJVEUpOworCSAgICBpZiAodmVyYm9zZSkKKwkJU3lzdGVtLm91dC5wcmludGxuKCJ0ZXN0IGV4cHVuZ2UgcmV2ZXJzZSIpOworCSAgICB0ZXN0RXhwdW5nZVJldmVyc2UoZm9sZGVyKTsKKwkgICAgZm9sZGVyLmNsb3NlKGZhbHNlKTsKKworCSAgICBmb2xkZXIub3BlbihGb2xkZXIuUkVBRF9XUklURSk7CisJICAgIGZvbGRlci5hcHBlbmRNZXNzYWdlcyhtc2dzKTsKKwkgICAgZm9sZGVyLmNsb3NlKGZhbHNlKTsKKwkgICAgZm9sZGVyLm9wZW4oRm9sZGVyLlJFQURfV1JJVEUpOworCSAgICBpZiAodmVyYm9zZSkKKwkJU3lzdGVtLm91dC5wcmludGxuKCJ0ZXN0IGV4cHVuZ2UgcmFuZG9tIik7CisJICAgIHRlc3RFeHB1bmdlUmFuZG9tKGZvbGRlcik7CisJICAgIGZvbGRlci5jbG9zZShmYWxzZSk7CisKKwkgICAgZm9sZGVyLm9wZW4oRm9sZGVyLlJFQURfV1JJVEUpOworCSAgICBmb2xkZXIuYXBwZW5kTWVzc2FnZXMobXNncyk7CisJICAgIGZvbGRlci5jbG9zZShmYWxzZSk7CisJICAgIGZvbGRlci5vcGVuKEZvbGRlci5SRUFEX1dSSVRFKTsKKwkgICAgaWYgKHZlcmJvc2UpCisJCVN5c3RlbS5vdXQucHJpbnRsbigidGVzdCBleHB1bmdlIG90aGVyIik7CisJICAgIHRlc3RFeHB1bmdlT3RoZXIoZm9sZGVyKTsKKwkgICAgZm9sZGVyLmNsb3NlKGZhbHNlKTsKKwkgICAgc3RvcmUuY2xvc2UoKTsKKwl9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJPb3BzLCBnb3QgZXhjZXB0aW9uISAiICsgZXguZ2V0TWVzc2FnZSgpKTsKKwkgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7CisJICAgIFN5c3RlbS5leGl0KDEpOworCX0KKwlTeXN0ZW0uZXhpdCgwKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBNZXNzYWdlW10gY3JlYXRlTWVzc2FnZXMoaW50IG51bSkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJTWVzc2FnZVtdIG1zZ3MgPSBuZXcgTWVzc2FnZVtudW1dOworCWZvciAoaW50IGkgPSAxOyBpIDw9IG51bTsgaSsrKSB7CisJICAgIE1pbWVNZXNzYWdlIG1zZyA9IG5ldyBNaW1lTWVzc2FnZShzZXNzaW9uKTsKKwkgICAgbXNnLnNldFNlbnREYXRlKG5ldyBEYXRlKCkpOworCSAgICBtc2cuc2V0RnJvbSgpOworCSAgICBtc2cuc2V0UmVjaXBpZW50cyhNZXNzYWdlLlJlY2lwaWVudFR5cGUuVE8sICJub2JvZHlAbm93aGVyZS5jb20iKTsKKwkgICAgbXNnLnNldFN1YmplY3QoSW50ZWdlci50b1N0cmluZyhpKSk7CisJICAgIG1zZy5zZXRUZXh0KGkgKyAiXG4iKTsKKwkgICAgbXNnLnNhdmVDaGFuZ2VzKCk7CisJICAgIG1zZ3NbaS0xXSA9IG1zZzsKKwl9CisJcmV0dXJuIG1zZ3M7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCB0ZXN0TWVzc2FnZU51bWJlcihGb2xkZXIgZm9sZGVyKQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWludCBudW1tc2cgPSBmb2xkZXIuZ2V0TWVzc2FnZUNvdW50KCk7CisJTWVzc2FnZSBtc2dzW10gPSBuZXcgTWVzc2FnZVtudW1tc2ddOworCWZvciAoaW50IGkgPSAxOyBpIDw9IG51bW1zZzsgaSsrKSB7CisJICAgIE1lc3NhZ2UgbXNnID0gZm9sZGVyLmdldE1lc3NhZ2UoaSk7CisJICAgIG1zZ3NbaS0xXSA9IG1zZzsKKwkgICAgaWYgKEludGVnZXIudmFsdWVPZihtc2cuZ2V0U3ViamVjdCgpKSAhPSBpKSB7CisJCVN5c3RlbS5vdXQucHJpbnRsbigiRkFJTDogV3JvbmcgbWVzc2FnZSEgR290ICIgKworCQkJCW1zZy5nZXRTdWJqZWN0KCkgKyAiLCBFeHBlY3RlZCAiICsgaSk7CisJICAgIH0KKwl9CisJZm9yIChpbnQgaSA9IDE7IGkgPD0gbnVtbXNnOyBpKyspIHsKKwkgICAgTWVzc2FnZSBtc2cgPSBmb2xkZXIuZ2V0TWVzc2FnZShpKTsKKwkgICAgaWYgKG1zZ3NbaS0xXSAhPSBtc2cgfHwgbXNnLmdldE1lc3NhZ2VOdW1iZXIoKSAhPSBpKSB7CisJCVN5c3RlbS5vdXQucHJpbnRsbigiRkFJTDogV3JvbmcgbWVzc2FnZSEgR290ICIgKworCQkJCW1zZy5nZXRNZXNzYWdlTnVtYmVyKCkgKyAiLCBFeHBlY3RlZCAiICsgaSk7CisJICAgIH0KKwl9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCB0ZXN0RXhwdW5nZUZvcndhcmQoRm9sZGVyIGZvbGRlcikKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpbnQgbnVtbXNnID0gZm9sZGVyLmdldE1lc3NhZ2VDb3VudCgpOworCWZvciAoaW50IGkgPSAxOyBpIDw9IG51bW1zZzsgaSsrKSB7CisJICAgIE1lc3NhZ2UgbXNnID0gZm9sZGVyLmdldE1lc3NhZ2UoMSk7CisJICAgIG1zZy5zZXRGbGFnKEZsYWdzLkZsYWcuREVMRVRFRCwgdHJ1ZSk7CisJICAgIGZvbGRlci5leHB1bmdlKCk7CisJICAgIGZvciAoaW50IGogPSAxOyBqIDwgbnVtbXNnIC0gaTsgaisrKSB7CisJCW1zZyA9IGZvbGRlci5nZXRNZXNzYWdlKGopOworCQlpZiAobXNnLmdldE1lc3NhZ2VOdW1iZXIoKSAhPSBqKSB7CisJCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkZBSUw6IFdyb25nIG1lc3NhZ2UhIEdvdCAiICsKKwkJCQkgICAgbXNnLmdldE1lc3NhZ2VOdW1iZXIoKSArICIsIEV4cGVjdGVkICIgKyBqKTsKKwkJfQorCSAgICB9CisJfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgdGVzdEV4cHVuZ2VSZXZlcnNlKEZvbGRlciBmb2xkZXIpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaW50IG51bW1zZyA9IGZvbGRlci5nZXRNZXNzYWdlQ291bnQoKTsKKwlmb3IgKGludCBpID0gbnVtbXNnOyBpID49IDE7IGktLSkgeworCSAgICBNZXNzYWdlIG1zZyA9IGZvbGRlci5nZXRNZXNzYWdlKGkpOworCSAgICBtc2cuc2V0RmxhZyhGbGFncy5GbGFnLkRFTEVURUQsIHRydWUpOworCSAgICBmb2xkZXIuZXhwdW5nZSgpOworCSAgICBmb3IgKGludCBqID0gMTsgaiA8IGk7IGorKykgeworCQltc2cgPSBmb2xkZXIuZ2V0TWVzc2FnZShqKTsKKwkJaWYgKG1zZy5nZXRNZXNzYWdlTnVtYmVyKCkgIT0gaikgeworCQkgICAgU3lzdGVtLm91dC5wcmludGxuKCJGQUlMOiBXcm9uZyBtZXNzYWdlISBHb3QgIiArCisJCQkJICAgIG1zZy5nZXRNZXNzYWdlTnVtYmVyKCkgKyAiLCBFeHBlY3RlZCAiICsgaik7CisJCX0KKwkgICAgfQorCX0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHRlc3RFeHB1bmdlUmFuZG9tKEZvbGRlciBmb2xkZXIpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaW50IG51bW1zZyA9IGZvbGRlci5nZXRNZXNzYWdlQ291bnQoKTsKKwlSYW5kb20gcm5kID0gbmV3IFJhbmRvbShTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSk7CisJd2hpbGUgKG51bW1zZyA+IDApIHsKKwkgICAgTWVzc2FnZSBtc2cgPSBmb2xkZXIuZ2V0TWVzc2FnZShybmQubmV4dEludChudW1tc2cpICsgMSk7CisJICAgIG1zZy5zZXRGbGFnKEZsYWdzLkZsYWcuREVMRVRFRCwgdHJ1ZSk7CisJICAgIGZvbGRlci5leHB1bmdlKCk7CisJICAgIG51bW1zZy0tOworCSAgICBmb3IgKGludCBqID0gMTsgaiA8PSBudW1tc2c7IGorKykgeworCQltc2cgPSBmb2xkZXIuZ2V0TWVzc2FnZShqKTsKKwkJaWYgKG1zZy5nZXRNZXNzYWdlTnVtYmVyKCkgIT0gaikgeworCQkgICAgU3lzdGVtLm91dC5wcmludGxuKCJGQUlMOiBXcm9uZyBtZXNzYWdlISBHb3QgIiArCisJCQkJICAgIG1zZy5nZXRNZXNzYWdlTnVtYmVyKCkgKyAiLCBFeHBlY3RlZCAiICsgaik7CisJCX0KKwkgICAgfQorCX0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHRlc3RFeHB1bmdlT3RoZXIoRm9sZGVyIGZvbGRlcikKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlGb2xkZXIgb3RoZXIgPSBmb2xkZXIuZ2V0U3RvcmUoKS5nZXRGb2xkZXIoZm9sZGVyLmdldEZ1bGxOYW1lKCkpOworCW90aGVyLm9wZW4oRm9sZGVyLlJFQURfV1JJVEUpOworCU1lc3NhZ2UgbXNnID0gb3RoZXIuZ2V0TWVzc2FnZSgyKTsKKwltc2cuc2V0RmxhZyhGbGFncy5GbGFnLkRFTEVURUQsIHRydWUpOworCW90aGVyLmV4cHVuZ2UoKTsKKwlTeXN0ZW0ub3V0LnByaW50bG4oIndhaXRpbmcgZm9yIGV4cHVuZ2Ugbm90aWZpY2F0aW9uIik7CisJdHJ5IHsgVGhyZWFkLnNsZWVwKDIwMDApOyB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBleCkgeyB9CisJZm9sZGVyLmlzT3BlbigpOworCXRyeSB7CisJICAgIG1zZyA9IGZvbGRlci5nZXRNZXNzYWdlKDIpOworCSAgICBtc2cuZ2V0RmxhZ3MoKTsKKwkgICAgaWYgKCFtc2cuaXNFeHB1bmdlZCgpKSB7CisJCVN5c3RlbS5vdXQucHJpbnRsbigiRkFJTDogTWVzc2FnZSAyIGlzIG5vdCBleHB1bmdlZCEiKTsKKwkgICAgfQorCX0gY2F0Y2ggKE1lc3NhZ2VSZW1vdmVkRXhjZXB0aW9uIG1leCkgeworCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlNVQ0NFU1M6IG1lc3NhZ2UgMiBpcyByZW1vdmVkISIpOworCX0KKwltc2cgPSBmb2xkZXIuZ2V0TWVzc2FnZSgxKTsKKwlpZiAoSW50ZWdlci52YWx1ZU9mKG1zZy5nZXRTdWJqZWN0KCkpICE9IDEpIHsKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJGQUlMOiBNZXNzYWdlIDEgaXMgd3JvbmchIik7CisJfQorCW1zZyA9IGZvbGRlci5nZXRNZXNzYWdlKDMpOworCWlmIChJbnRlZ2VyLnZhbHVlT2YobXNnLmdldFN1YmplY3QoKSkgIT0gMykgeworCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkZBSUw6IE1lc3NhZ2UgMyBpcyB3cm9uZyEiKTsKKwl9CisJb3RoZXIuY2xvc2UoZmFsc2UpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL29sZHRlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L3NvY2tldGZhY3RvcnkvRHVtbXlTU0xTb2NrZXRGYWN0b3J5LmphdmEgYi9tYWlsL3NyYy9vbGR0ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9zb2NrZXRmYWN0b3J5L0R1bW15U1NMU29ja2V0RmFjdG9yeS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjEyZTM4MzQKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9vbGR0ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9zb2NrZXRmYWN0b3J5L0R1bW15U1NMU29ja2V0RmFjdG9yeS5qYXZhCkBAIC0wLDAgKzEsODIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorICovCisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LkluZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LlNvY2tldDsKKworaW1wb3J0IGphdmF4Lm5ldC5Tb2NrZXRGYWN0b3J5OworaW1wb3J0IGphdmF4Lm5ldC5zc2wuKjsKKworCisvKioKKyAqIER1bW15U1NMU29ja2V0RmFjdG9yeQorICovCitwdWJsaWMgY2xhc3MgRHVtbXlTU0xTb2NrZXRGYWN0b3J5IGV4dGVuZHMgU1NMU29ja2V0RmFjdG9yeSB7CisgICAgcHJpdmF0ZSBTU0xTb2NrZXRGYWN0b3J5IGZhY3Rvcnk7CisKKyAgICBwdWJsaWMgRHVtbXlTU0xTb2NrZXRGYWN0b3J5KCkgeworCXRyeSB7CisJICAgIFNTTENvbnRleHQgc3NsY29udGV4dCA9IFNTTENvbnRleHQuZ2V0SW5zdGFuY2UoIlRMUyIpOworCSAgICBzc2xjb250ZXh0LmluaXQobnVsbCwKKwkJCQkgbmV3IFRydXN0TWFuYWdlcltdIHsgbmV3IER1bW15VHJ1c3RNYW5hZ2VyKCl9LAorCQkJCSBudWxsKTsKKwkgICAgZmFjdG9yeSA9IChTU0xTb2NrZXRGYWN0b3J5KXNzbGNvbnRleHQuZ2V0U29ja2V0RmFjdG9yeSgpOworCX0gY2F0Y2goRXhjZXB0aW9uIGV4KSB7CisJICAgIC8vIGlnbm9yZQorCX0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIFNvY2tldEZhY3RvcnkgZ2V0RGVmYXVsdCgpIHsKKwlyZXR1cm4gbmV3IER1bW15U1NMU29ja2V0RmFjdG9yeSgpOworICAgIH0KKworICAgIHB1YmxpYyBTb2NrZXQgY3JlYXRlU29ja2V0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlUZXN0UmVzdWx0LnN1Y2Nlc3MoKTsKKwlyZXR1cm4gZmFjdG9yeS5jcmVhdGVTb2NrZXQoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgU29ja2V0IGNyZWF0ZVNvY2tldChTb2NrZXQgc29ja2V0LCBTdHJpbmcgcywgaW50IGksIGJvb2xlYW4gZmxhZykKKwkJCQl0aHJvd3MgSU9FeGNlcHRpb24geworCVRlc3RSZXN1bHQuc3VjY2VzcygpOworCXJldHVybiBmYWN0b3J5LmNyZWF0ZVNvY2tldChzb2NrZXQsIHMsIGksIGZsYWcpOworICAgIH0KKworICAgIHB1YmxpYyBTb2NrZXQgY3JlYXRlU29ja2V0KEluZXRBZGRyZXNzIGluYWRkciwgaW50IGksCisJCQkJSW5ldEFkZHJlc3MgaW5hZGRyMSwgaW50IGopIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJVGVzdFJlc3VsdC5zdWNjZXNzKCk7CisJcmV0dXJuIGZhY3RvcnkuY3JlYXRlU29ja2V0KGluYWRkciwgaSwgaW5hZGRyMSwgaik7CisgICAgfQorCisgICAgcHVibGljIFNvY2tldCBjcmVhdGVTb2NrZXQoSW5ldEFkZHJlc3MgaW5hZGRyLCBpbnQgaSkKKwkJCQl0aHJvd3MgSU9FeGNlcHRpb24geworCVRlc3RSZXN1bHQuc3VjY2VzcygpOworCXJldHVybiBmYWN0b3J5LmNyZWF0ZVNvY2tldChpbmFkZHIsIGkpOworICAgIH0KKworICAgIHB1YmxpYyBTb2NrZXQgY3JlYXRlU29ja2V0KFN0cmluZyBzLCBpbnQgaSwgSW5ldEFkZHJlc3MgaW5hZGRyLCBpbnQgaikKKwkJCQl0aHJvd3MgSU9FeGNlcHRpb24geworCVRlc3RSZXN1bHQuc3VjY2VzcygpOworCXJldHVybiBmYWN0b3J5LmNyZWF0ZVNvY2tldChzLCBpLCBpbmFkZHIsIGopOworICAgIH0KKworICAgIHB1YmxpYyBTb2NrZXQgY3JlYXRlU29ja2V0KFN0cmluZyBzLCBpbnQgaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlUZXN0UmVzdWx0LnN1Y2Nlc3MoKTsKKwlyZXR1cm4gZmFjdG9yeS5jcmVhdGVTb2NrZXQocywgaSk7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZ1tdIGdldERlZmF1bHRDaXBoZXJTdWl0ZXMoKSB7CisJcmV0dXJuIGZhY3RvcnkuZ2V0RGVmYXVsdENpcGhlclN1aXRlcygpOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmdbXSBnZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoKSB7CisJcmV0dXJuIGZhY3RvcnkuZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVzKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvb2xkdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvc29ja2V0ZmFjdG9yeS9EdW1teVNvY2tldEZhY3RvcnkuamF2YSBiL21haWwvc3JjL29sZHRlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L3NvY2tldGZhY3RvcnkvRHVtbXlTb2NrZXRGYWN0b3J5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWEyNDcyMgotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL29sZHRlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L3NvY2tldGZhY3RvcnkvRHVtbXlTb2NrZXRGYWN0b3J5LmphdmEKQEAgLTAsMCArMSw1OSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgRGlzdHJpYnV0aW9uIExpY2Vuc2Ugdi4gMS4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvb3JnL2RvY3VtZW50cy9lZGwtdjEwLnBocC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQlNELTMtQ2xhdXNlCisgKi8KKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuSW5ldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuU29ja2V0OworCitpbXBvcnQgamF2YXgubmV0LlNvY2tldEZhY3Rvcnk7CisKKworLyoqCisgKiBEdW1teVNvY2tldEZhY3RvcnkKKyAqLworcHVibGljIGNsYXNzIER1bW15U29ja2V0RmFjdG9yeSBleHRlbmRzIFNvY2tldEZhY3RvcnkgeworICAgIHByaXZhdGUgU29ja2V0RmFjdG9yeSBmYWN0b3J5OworCisgICAgcHVibGljIER1bW15U29ja2V0RmFjdG9yeSgpIHsKKwlmYWN0b3J5ID0gU29ja2V0RmFjdG9yeS5nZXREZWZhdWx0KCk7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBTb2NrZXRGYWN0b3J5IGdldERlZmF1bHQoKSB7CisJcmV0dXJuIG5ldyBEdW1teVNvY2tldEZhY3RvcnkoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgU29ja2V0IGNyZWF0ZVNvY2tldCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJVGVzdFJlc3VsdC5zdWNjZXNzKCk7CisJcmV0dXJuIGZhY3RvcnkuY3JlYXRlU29ja2V0KCk7CisgICAgfQorCisgICAgcHVibGljIFNvY2tldCBjcmVhdGVTb2NrZXQoSW5ldEFkZHJlc3MgaW5hZGRyLCBpbnQgaSwKKwkJCQlJbmV0QWRkcmVzcyBpbmFkZHIxLCBpbnQgaikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlUZXN0UmVzdWx0LnN1Y2Nlc3MoKTsKKwlyZXR1cm4gZmFjdG9yeS5jcmVhdGVTb2NrZXQoaW5hZGRyLCBpLCBpbmFkZHIxLCBqKTsKKyAgICB9CisKKyAgICBwdWJsaWMgU29ja2V0IGNyZWF0ZVNvY2tldChJbmV0QWRkcmVzcyBpbmFkZHIsIGludCBpKQorCQkJCXRocm93cyBJT0V4Y2VwdGlvbiB7CisJVGVzdFJlc3VsdC5zdWNjZXNzKCk7CisJcmV0dXJuIGZhY3RvcnkuY3JlYXRlU29ja2V0KGluYWRkciwgaSk7CisgICAgfQorCisgICAgcHVibGljIFNvY2tldCBjcmVhdGVTb2NrZXQoU3RyaW5nIHMsIGludCBpLCBJbmV0QWRkcmVzcyBpbmFkZHIsIGludCBqKQorCQkJCXRocm93cyBJT0V4Y2VwdGlvbiB7CisJVGVzdFJlc3VsdC5zdWNjZXNzKCk7CisJcmV0dXJuIGZhY3RvcnkuY3JlYXRlU29ja2V0KHMsIGksIGluYWRkciwgaik7CisgICAgfQorCisgICAgcHVibGljIFNvY2tldCBjcmVhdGVTb2NrZXQoU3RyaW5nIHMsIGludCBpKSB0aHJvd3MgSU9FeGNlcHRpb24geworCVRlc3RSZXN1bHQuc3VjY2VzcygpOworCXJldHVybiBmYWN0b3J5LmNyZWF0ZVNvY2tldChzLCBpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9vbGR0ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9zb2NrZXRmYWN0b3J5L0R1bW15VHJ1c3RNYW5hZ2VyLmphdmEgYi9tYWlsL3NyYy9vbGR0ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9zb2NrZXRmYWN0b3J5L0R1bW15VHJ1c3RNYW5hZ2VyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDMwNzYyMwotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL29sZHRlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L3NvY2tldGZhY3RvcnkvRHVtbXlUcnVzdE1hbmFnZXIuamF2YQpAQCAtMCwwICsxLDMxIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBEaXN0cmlidXRpb24gTGljZW5zZSB2LiAxLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9vcmcvZG9jdW1lbnRzL2VkbC12MTAucGhwLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBCU0QtMy1DbGF1c2UKKyAqLworCitpbXBvcnQgamF2YXgubmV0LnNzbC5YNTA5VHJ1c3RNYW5hZ2VyOworaW1wb3J0IGphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGU7CisKKworLyoqCisgKiBEdW1teVRydXN0TWFuYWdlcgorICovCitwdWJsaWMgY2xhc3MgRHVtbXlUcnVzdE1hbmFnZXIgaW1wbGVtZW50cyBYNTA5VHJ1c3RNYW5hZ2VyIHsKKworICAgIHB1YmxpYyB2b2lkIGNoZWNrQ2xpZW50VHJ1c3RlZChYNTA5Q2VydGlmaWNhdGVbXSBjZXJ0LCBTdHJpbmcgYXV0aFR5cGUpIHsKKwkvLyBldmVyeXRoaW5nIGlzIHRydXN0ZWQKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBjaGVja1NlcnZlclRydXN0ZWQoWDUwOUNlcnRpZmljYXRlW10gY2VydCwgU3RyaW5nIGF1dGhUeXBlKSB7CisJLy8gZXZlcnl0aGluZyBpcyB0cnVzdGVkCisgICAgfQorCisgICAgcHVibGljIFg1MDlDZXJ0aWZpY2F0ZVtdIGdldEFjY2VwdGVkSXNzdWVycygpIHsKKwlyZXR1cm4gbmV3IFg1MDlDZXJ0aWZpY2F0ZVswXTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy9vbGR0ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9zb2NrZXRmYWN0b3J5L1Rlc3RSZXN1bHQuamF2YSBiL21haWwvc3JjL29sZHRlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L3NvY2tldGZhY3RvcnkvVGVzdFJlc3VsdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE5NDZkMGMKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9vbGR0ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9zb2NrZXRmYWN0b3J5L1Rlc3RSZXN1bHQuamF2YQpAQCAtMCwwICsxLDI3IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBEaXN0cmlidXRpb24gTGljZW5zZSB2LiAxLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9vcmcvZG9jdW1lbnRzL2VkbC12MTAucGhwLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBCU0QtMy1DbGF1c2UKKyAqLworCitwdWJsaWMgY2xhc3MgVGVzdFJlc3VsdCB7CisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBwYXNzID0gZmFsc2U7CisKKyAgICBwcml2YXRlIFRlc3RSZXN1bHQoKSB7IH0JLy8gbm8gcHVibGljIGNvbnN0cnVjdG9yCisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgcmVzZXQoKSB7CisJcGFzcyA9IGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzdWNjZXNzKCkgeworCXBhc3MgPSB0cnVlOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBwcmludChTdHJpbmcgcykgeworCVN5c3RlbS5vdXQucHJpbnRsbigocGFzcyA/ICJTVUNDRVNTOiAiIDogIkZBSUw6ICIpICsgcyk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvb2xkdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvc29ja2V0ZmFjdG9yeS9zb2NrZXRmYWN0b3J5dGVzdC5qYXZhIGIvbWFpbC9zcmMvb2xkdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvc29ja2V0ZmFjdG9yeS9zb2NrZXRmYWN0b3J5dGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNhZjk0YWEKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy9vbGR0ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9zb2NrZXRmYWN0b3J5L3NvY2tldGZhY3Rvcnl0ZXN0LmphdmEKQEAgLTAsMCArMSwyNzYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorICovCisKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7CisKK2ltcG9ydCBqYXZheC5tYWlsLio7CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC4qOworCitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuTWFpbFNTTFNvY2tldEZhY3Rvcnk7CisKKy8qKgorICogVGVzdCBzb2NrZXQgZmFjdG9yeSBwcm9wZXJ0aWVzLgorICogTmVlZHMgdG8gYmUgcnVuIHdpdGggYW4gU01UUCBzZXJ2ZXIgdGhhdCBzdXBwb3J0cyBib3RoIFNTTAorICogY29ubmVjdGlvbnMgYW5kIHRoZSBTVEFSVFRMUyBjb21tYW5kLCBlLmcuLCBtYWlsLXNmYmF5LnN1bi5jb20uCisgKgorICogQGF1dGhvciBCaWxsIFNoYW5ub24KKyAqLworCitwdWJsaWMgY2xhc3Mgc29ja2V0ZmFjdG9yeXRlc3QgeworCisgICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJndikgeworCVN0cmluZyBtYWlsaG9zdCA9ICJtYWlsLXNmYmF5LnN1bi5jb20iOworCVN0cmluZyB1c2VyID0gbnVsbCwgcGFzc3dvcmQgPSBudWxsOworCWJvb2xlYW4gZGVidWcgPSBmYWxzZTsKKwlib29sZWFuIGF1dGggPSBmYWxzZTsKKwlpbnQgb3B0aW5kOworCisJZm9yIChvcHRpbmQgPSAwOyBvcHRpbmQgPCBhcmd2Lmxlbmd0aDsgb3B0aW5kKyspIHsKKwkgICAgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1VIikpIHsKKwkJdXNlciA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1QIikpIHsKKwkJcGFzc3dvcmQgPSBhcmd2Wysrb3B0aW5kXTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItTSIpKSB7CisJCW1haWxob3N0ID0gYXJndlsrK29wdGluZF07CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLWQiKSkgeworCQlkZWJ1ZyA9IHRydWU7CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLUEiKSkgeworCQlhdXRoID0gdHJ1ZTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItLSIpKSB7CisJCW9wdGluZCsrOworCQlicmVhazsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uc3RhcnRzV2l0aCgiLSIpKSB7CisJCVN5c3RlbS5vdXQucHJpbnRsbigKKwkJCSJVc2FnZTogc29ja2V0ZmFjdG9yeXRlc3QgWy1VIHVzZXJdIFstUCBwYXNzd2RdXSIpOworCQlTeXN0ZW0ub3V0LnByaW50bG4oIlx0Wy1NIHRyYW5zcG9ydC1ob3N0XSBbLWRdIFstQV0iKTsKKwkJU3lzdGVtLmV4aXQoMSk7CisJICAgIH0gZWxzZSB7CisJCWJyZWFrOworCSAgICB9CisJfQorCisJdHJ5IHsKKworCSAgICAvLyBmaXJzdCwgbm8gZmFjdG9yaWVzCisKKwkgICAgUHJvcGVydGllcyBwcm9wcyA9IG5ldyBQcm9wZXJ0aWVzKCk7CisJICAgIHByb3BzLnB1dCgibWFpbC5zbXRwLmhvc3QiLCBtYWlsaG9zdCk7CisJICAgIFNlc3Npb24gc2Vzc2lvbiA9IFNlc3Npb24uZ2V0SW5zdGFuY2UocHJvcHMsIG51bGwpOworCSAgICBpZiAoZGVidWcpCisJCXNlc3Npb24uc2V0RGVidWcodHJ1ZSk7CisKKwkgICAgVHJhbnNwb3J0IHQgPSBzZXNzaW9uLmdldFRyYW5zcG9ydCgic210cCIpOworCSAgICB0cnkgeworCQlpZiAoYXV0aCkKKwkJICAgIHQuY29ubmVjdChtYWlsaG9zdCwgdXNlciwgcGFzc3dvcmQpOworCQllbHNlCisJCSAgICB0LmNvbm5lY3QoKTsKKwkJVGVzdFJlc3VsdC5zdWNjZXNzKCk7CisJICAgIH0gZmluYWxseSB7CisJCXQuY2xvc2UoKTsKKwkgICAgfQorCSAgICBUZXN0UmVzdWx0LnByaW50KCJubyBmYWN0b3JpZXMiKTsKKworCSAgICAvLyBzb2NrZXQgZmFjdG9yeSBwcm9wZXJ0eQorCisJICAgIFRlc3RSZXN1bHQucmVzZXQoKTsKKwkgICAgcHJvcHMgPSBuZXcgUHJvcGVydGllcygpOworCSAgICBwcm9wcy5wdXQoIm1haWwuc210cC5ob3N0IiwgbWFpbGhvc3QpOworCSAgICBwcm9wcy5wdXQoIm1haWwuc210cC5zb2NrZXRGYWN0b3J5LmNsYXNzIiwgIkR1bW15U29ja2V0RmFjdG9yeSIpOworCSAgICBzZXNzaW9uID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShwcm9wcywgbnVsbCk7CisJICAgIGlmIChkZWJ1ZykKKwkJc2Vzc2lvbi5zZXREZWJ1Zyh0cnVlKTsKKworCSAgICB0ID0gc2Vzc2lvbi5nZXRUcmFuc3BvcnQoInNtdHAiKTsKKwkgICAgdHJ5IHsKKwkJaWYgKGF1dGgpCisJCSAgICB0LmNvbm5lY3QobWFpbGhvc3QsIHVzZXIsIHBhc3N3b3JkKTsKKwkJZWxzZQorCQkgICAgdC5jb25uZWN0KCk7CisJICAgIH0gZmluYWxseSB7CisJCXQuY2xvc2UoKTsKKwkgICAgfQorCSAgICBUZXN0UmVzdWx0LnByaW50KCJzb2NrZXQgZmFjdG9yeSBwcm9wZXJ0eSIpOworCisJICAgIC8vIHNvY2tldCBmYWN0b3J5IG9iamVjdAorCisJICAgIFRlc3RSZXN1bHQucmVzZXQoKTsKKwkgICAgcHJvcHMgPSBuZXcgUHJvcGVydGllcygpOworCSAgICBwcm9wcy5wdXQoIm1haWwuc210cC5ob3N0IiwgbWFpbGhvc3QpOworCSAgICBwcm9wcy5wdXQoIm1haWwuc210cC5zb2NrZXRGYWN0b3J5IiwgbmV3IER1bW15U29ja2V0RmFjdG9yeSgpKTsKKwkgICAgc2Vzc2lvbiA9IFNlc3Npb24uZ2V0SW5zdGFuY2UocHJvcHMsIG51bGwpOworCSAgICBpZiAoZGVidWcpCisJCXNlc3Npb24uc2V0RGVidWcodHJ1ZSk7CisKKwkgICAgdCA9IHNlc3Npb24uZ2V0VHJhbnNwb3J0KCJzbXRwIik7CisJICAgIHRyeSB7CisJCWlmIChhdXRoKQorCQkgICAgdC5jb25uZWN0KG1haWxob3N0LCB1c2VyLCBwYXNzd29yZCk7CisJCWVsc2UKKwkJICAgIHQuY29ubmVjdCgpOworCSAgICB9IGZpbmFsbHkgeworCQl0LmNsb3NlKCk7CisJICAgIH0KKwkgICAgVGVzdFJlc3VsdC5wcmludCgic29ja2V0IGZhY3Rvcnkgb2JqZWN0Iik7CisKKwkgICAgLy8gU1NMIHNvY2tldCBmYWN0b3J5IHByb3BlcnR5CisKKwkgICAgVGVzdFJlc3VsdC5yZXNldCgpOworCSAgICBwcm9wcyA9IG5ldyBQcm9wZXJ0aWVzKCk7CisJICAgIHByb3BzLnB1dCgibWFpbC5zbXRwLmhvc3QiLCBtYWlsaG9zdCk7CisJICAgIHByb3BzLnB1dCgibWFpbC5zbXRwLnNzbC5lbmFibGUiLCAidHJ1ZSIpOworCSAgICBwcm9wcy5wdXQoIm1haWwuc210cC5zc2wuY2hlY2tzZXJ2ZXJpZGVudGl0eSIsICJ0cnVlIik7CisJICAgIHByb3BzLnB1dCgibWFpbC5zbXRwLnNzbC5zb2NrZXRGYWN0b3J5LmNsYXNzIiwKKwkJCQkJCSJEdW1teVNTTFNvY2tldEZhY3RvcnkiKTsKKwkgICAgc2Vzc2lvbiA9IFNlc3Npb24uZ2V0SW5zdGFuY2UocHJvcHMsIG51bGwpOworCSAgICBpZiAoZGVidWcpCisJCXNlc3Npb24uc2V0RGVidWcodHJ1ZSk7CisKKwkgICAgdCA9IHNlc3Npb24uZ2V0VHJhbnNwb3J0KCJzbXRwIik7CisJICAgIHRyeSB7CisJCWlmIChhdXRoKQorCQkgICAgdC5jb25uZWN0KG1haWxob3N0LCB1c2VyLCBwYXNzd29yZCk7CisJCWVsc2UKKwkJICAgIHQuY29ubmVjdCgpOworCSAgICB9IGZpbmFsbHkgeworCQl0LmNsb3NlKCk7CisJICAgIH0KKwkgICAgVGVzdFJlc3VsdC5wcmludCgiU1NMIHNvY2tldCBmYWN0b3J5IHByb3BlcnR5Iik7CisKKwkgICAgLy8gU1NMIHNvY2tldCBmYWN0b3J5IG9iamVjdAorCisJICAgIFRlc3RSZXN1bHQucmVzZXQoKTsKKwkgICAgcHJvcHMgPSBuZXcgUHJvcGVydGllcygpOworCSAgICBwcm9wcy5wdXQoIm1haWwuc210cC5ob3N0IiwgbWFpbGhvc3QpOworCSAgICBwcm9wcy5wdXQoIm1haWwuc210cC5zc2wuZW5hYmxlIiwgInRydWUiKTsKKwkgICAgcHJvcHMucHV0KCJtYWlsLnNtdHAuc3NsLmNoZWNrc2VydmVyaWRlbnRpdHkiLCAidHJ1ZSIpOworCSAgICBwcm9wcy5wdXQoIm1haWwuc210cC5zc2wuc29ja2V0RmFjdG9yeSIsCisJCQkJCQluZXcgRHVtbXlTU0xTb2NrZXRGYWN0b3J5KCkpOworCSAgICBzZXNzaW9uID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShwcm9wcywgbnVsbCk7CisJICAgIGlmIChkZWJ1ZykKKwkJc2Vzc2lvbi5zZXREZWJ1Zyh0cnVlKTsKKworCSAgICB0ID0gc2Vzc2lvbi5nZXRUcmFuc3BvcnQoInNtdHAiKTsKKwkgICAgdHJ5IHsKKwkJaWYgKGF1dGgpCisJCSAgICB0LmNvbm5lY3QobWFpbGhvc3QsIHVzZXIsIHBhc3N3b3JkKTsKKwkJZWxzZQorCQkgICAgdC5jb25uZWN0KCk7CisJICAgIH0gZmluYWxseSB7CisJCXQuY2xvc2UoKTsKKwkgICAgfQorCSAgICBUZXN0UmVzdWx0LnByaW50KCJTU0wgc29ja2V0IGZhY3Rvcnkgb2JqZWN0Iik7CisKKwkgICAgLy8gU1RBUlRUTFMgbm8gc29ja2V0IGZhY3RvcnkKKworCSAgICBUZXN0UmVzdWx0LnJlc2V0KCk7CisJICAgIHByb3BzID0gbmV3IFByb3BlcnRpZXMoKTsKKwkgICAgcHJvcHMucHV0KCJtYWlsLnNtdHAuaG9zdCIsIG1haWxob3N0KTsKKwkgICAgcHJvcHMucHV0KCJtYWlsLnNtdHAuc3RhcnR0bHMuZW5hYmxlIiwgInRydWUiKTsKKwkgICAgc2Vzc2lvbiA9IFNlc3Npb24uZ2V0SW5zdGFuY2UocHJvcHMsIG51bGwpOworCSAgICBpZiAoZGVidWcpCisJCXNlc3Npb24uc2V0RGVidWcodHJ1ZSk7CisKKwkgICAgdCA9IHNlc3Npb24uZ2V0VHJhbnNwb3J0KCJzbXRwIik7CisJICAgIHRyeSB7CisJCWlmIChhdXRoKQorCQkgICAgdC5jb25uZWN0KG1haWxob3N0LCB1c2VyLCBwYXNzd29yZCk7CisJCWVsc2UKKwkJICAgIHQuY29ubmVjdCgpOworCQlUZXN0UmVzdWx0LnN1Y2Nlc3MoKTsKKwkgICAgfSBmaW5hbGx5IHsKKwkJdC5jbG9zZSgpOworCSAgICB9CisJICAgIFRlc3RSZXN1bHQucHJpbnQoIlNUQVJUVExTIG5vIHNvY2tldCBmYWN0b3J5Iik7CisKKwkgICAgLy8gU1RBUlRUTFMgU1NMIHNvY2tldCBmYWN0b3J5IHByb3BlcnR5CisKKwkgICAgVGVzdFJlc3VsdC5yZXNldCgpOworCSAgICBwcm9wcyA9IG5ldyBQcm9wZXJ0aWVzKCk7CisJICAgIHByb3BzLnB1dCgibWFpbC5zbXRwLmhvc3QiLCBtYWlsaG9zdCk7CisJICAgIHByb3BzLnB1dCgibWFpbC5zbXRwLnN0YXJ0dGxzLmVuYWJsZSIsICJ0cnVlIik7CisJICAgIHByb3BzLnB1dCgibWFpbC5zbXRwLnNzbC5jaGVja3NlcnZlcmlkZW50aXR5IiwgInRydWUiKTsKKwkgICAgcHJvcHMucHV0KCJtYWlsLnNtdHAuc3NsLnNvY2tldEZhY3RvcnkuY2xhc3MiLAorCQkJCQkJIkR1bW15U1NMU29ja2V0RmFjdG9yeSIpOworCSAgICBzZXNzaW9uID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShwcm9wcywgbnVsbCk7CisJICAgIGlmIChkZWJ1ZykKKwkJc2Vzc2lvbi5zZXREZWJ1Zyh0cnVlKTsKKworCSAgICB0ID0gc2Vzc2lvbi5nZXRUcmFuc3BvcnQoInNtdHAiKTsKKwkgICAgdHJ5IHsKKwkJaWYgKGF1dGgpCisJCSAgICB0LmNvbm5lY3QobWFpbGhvc3QsIHVzZXIsIHBhc3N3b3JkKTsKKwkJZWxzZQorCQkgICAgdC5jb25uZWN0KCk7CisJICAgIH0gZmluYWxseSB7CisJCXQuY2xvc2UoKTsKKwkgICAgfQorCSAgICBUZXN0UmVzdWx0LnByaW50KCJTVEFSVFRMUyBTU0wgc29ja2V0IGZhY3RvcnkgcHJvcGVydHkiKTsKKworCSAgICAvLyBTVEFSVFRMUyBTU0wgc29ja2V0IGZhY3Rvcnkgb2JqZWN0CisKKwkgICAgVGVzdFJlc3VsdC5yZXNldCgpOworCSAgICBwcm9wcyA9IG5ldyBQcm9wZXJ0aWVzKCk7CisJICAgIHByb3BzLnB1dCgibWFpbC5zbXRwLmhvc3QiLCBtYWlsaG9zdCk7CisJICAgIHByb3BzLnB1dCgibWFpbC5zbXRwLnN0YXJ0dGxzLmVuYWJsZSIsICJ0cnVlIik7CisJICAgIHByb3BzLnB1dCgibWFpbC5zbXRwLnNzbC5jaGVja3NlcnZlcmlkZW50aXR5IiwgInRydWUiKTsKKwkgICAgcHJvcHMucHV0KCJtYWlsLnNtdHAuc3NsLnNvY2tldEZhY3RvcnkiLAorCQkJCQkJbmV3IER1bW15U1NMU29ja2V0RmFjdG9yeSgpKTsKKwkgICAgc2Vzc2lvbiA9IFNlc3Npb24uZ2V0SW5zdGFuY2UocHJvcHMsIG51bGwpOworCSAgICBpZiAoZGVidWcpCisJCXNlc3Npb24uc2V0RGVidWcodHJ1ZSk7CisKKwkgICAgdCA9IHNlc3Npb24uZ2V0VHJhbnNwb3J0KCJzbXRwIik7CisJICAgIHRyeSB7CisJCWlmIChhdXRoKQorCQkgICAgdC5jb25uZWN0KG1haWxob3N0LCB1c2VyLCBwYXNzd29yZCk7CisJCWVsc2UKKwkJICAgIHQuY29ubmVjdCgpOworCSAgICB9IGZpbmFsbHkgeworCQl0LmNsb3NlKCk7CisJICAgIH0KKwkgICAgVGVzdFJlc3VsdC5wcmludCgiU1RBUlRUTFMgU1NMIHNvY2tldCBmYWN0b3J5IG9iamVjdCIpOworCisJICAgIC8vIE1haWwgU1NMIHNvY2tldCBmYWN0b3J5IG9iamVjdAorCisJICAgIC8qCisJICAgIFRlc3RSZXN1bHQucmVzZXQoKTsKKwkgICAgcHJvcHMgPSBuZXcgUHJvcGVydGllcygpOworCSAgICBwcm9wcy5wdXQoIm1haWwuaW1hcC5ob3N0IiwgbWFpbGhvc3QpOworCSAgICBwcm9wcy5wdXQoIm1haWwuaW1hcC5zc2wuZW5hYmxlIiwgInRydWUiKTsKKwkgICAgcHJvcHMucHV0KCJtYWlsLmltYXAuc3NsLmNoZWNrc2VydmVyaWRlbnRpdHkiLCAidHJ1ZSIpOworCSAgICBNYWlsU1NMU29ja2V0RmFjdG9yeSBzZiA9IG5ldyBNYWlsU1NMU29ja2V0RmFjdG9yeSgiVExTIik7CisJICAgIC8vc2Yuc2V0VHJ1c3RBbGxIb3N0cyh0cnVlKTsKKwkgICAgc2Yuc2V0VHJ1c3RlZEhvc3RzKG5ldyBTdHJpbmdbXSB7ICJsb2dob3N0IiB9KTsKKwkgICAgcHJvcHMucHV0KCJtYWlsLmltYXAuc3NsLnNvY2tldEZhY3RvcnkiLCBzZik7CisJICAgIHByb3BzLnB1dCgibWFpbC5pbWFwLnNvY2tldEZhY3RvcnkuZmFsbGJhY2siLCAiZmFsc2UiKTsKKwkgICAgc2Vzc2lvbiA9IFNlc3Npb24uZ2V0SW5zdGFuY2UocHJvcHMsIG51bGwpOworCSAgICBpZiAoZGVidWcpCisJCXNlc3Npb24uc2V0RGVidWcodHJ1ZSk7CisKKwkgICAgU3RvcmUgc3QgPSBzZXNzaW9uLmdldFN0b3JlKCJpbWFwIik7CisJICAgIHRyeSB7CisJCWlmIChhdXRoKQorCQkgICAgc3QuY29ubmVjdChtYWlsaG9zdCwgdXNlciwgcGFzc3dvcmQpOworCQllbHNlCisJCSAgICBzdC5jb25uZWN0KCk7CisJCVRlc3RSZXN1bHQuc3VjY2VzcygpOworCSAgICB9IGZpbmFsbHkgeworCQlzdC5jbG9zZSgpOworCSAgICB9CisJICAgIFRlc3RSZXN1bHQucHJpbnQoIk1haWwgU1NMIHNvY2tldCBmYWN0b3J5IG9iamVjdCIpOworCSAgICAqLworCisJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJFeGNlcHRpb246ICIgKyBlKTsKKwl9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9oYW5kbGVycy9UZXh0WG1sVGVzdC5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9oYW5kbGVycy9UZXh0WG1sVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI2YzgxMjMKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL2hhbmRsZXJzL1RleHRYbWxUZXN0LmphdmEKQEAgLTAsMCArMSwxMjEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmhhbmRsZXJzOworCitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmEudXRpbC4qOworaW1wb3J0IGphdmEuYXd0LmRhdGF0cmFuc2Zlci5EYXRhRmxhdm9yOworaW1wb3J0IGphdmF4LmFjdGl2YXRpb24uKjsKK2ltcG9ydCBqYXZheC5tYWlsLio7CitpbXBvcnQgamF2YXgubWFpbC51dGlsLkJ5dGVBcnJheURhdGFTb3VyY2U7CitpbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uKjsKKworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEVxdWFsczsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUcnVlOworCisvKioKKyAqIFRlc3QgdGhlIHRleHQveG1sIERhdGFDb250ZW50SGFuZGxlci4KKyAqCisgKiBYWFggLSBzaG91bGQgdGVzdCBvdGhlciBTb3VyY2Ugb2JqZWN0cyBpbiBhZGRpdGlvbiB0byBTdHJlYW1Tb3VyY2UuCisgKgorICogQGF1dGhvciBCaWxsIFNoYW5ub24KKyAqLworCitwdWJsaWMgY2xhc3MgVGV4dFhtbFRlc3QgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIHhtbCA9ICI8dGVzdD48Zm9vPmJhcjwvZm9vPjwvdGVzdD5cbiI7CisgICAgcHJpdmF0ZSBzdGF0aWMgYnl0ZVtdIHhtbEJ5dGVzID0geG1sLmdldEJ5dGVzKCk7CisKKyAgICAvLyB0ZXN0IElucHV0U3RyZWFtIHRvIFN0cmluZworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFN0cmVhbVRvU3RyaW5nVGV4dFhtbCgpIHRocm93cyBFeGNlcHRpb24geworCXRlc3RTdHJlYW1Ub1N0cmluZygidGV4dC94bWwiKTsKKyAgICB9CisKKyAgICAvLyB0ZXN0IElucHV0U3RyZWFtIHRvIFN0cmluZworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFN0cmVhbVRvU3RyaW5nQXBwbGljYXRpb25YbWwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwl0ZXN0U3RyZWFtVG9TdHJpbmcoImFwcGxpY2F0aW9uL3htbCIpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgdGVzdFN0cmVhbVRvU3RyaW5nKFN0cmluZyBtaW1lVHlwZSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJRGF0YUNvbnRlbnRIYW5kbGVyIGRjaCA9IG5ldyB0ZXh0X3htbCgpOworCURhdGFGbGF2b3IgZGYgPSBuZXcgQWN0aXZhdGlvbkRhdGFGbGF2b3IoU3RyaW5nLmNsYXNzLCBtaW1lVHlwZSwgIlhNTCIpOworCURhdGFTb3VyY2UgZHMgPSBuZXcgQnl0ZUFycmF5RGF0YVNvdXJjZSh4bWxCeXRlcywgbWltZVR5cGUpOworCU9iamVjdCBjb250ZW50ID0gZGNoLmdldENvbnRlbnQoZHMpOworCWFzc2VydEVxdWFscyhTdHJpbmcuY2xhc3MsIGNvbnRlbnQuZ2V0Q2xhc3MoKSk7CisJYXNzZXJ0RXF1YWxzKHhtbCwgKFN0cmluZyljb250ZW50KTsKKwljb250ZW50ID0gZGNoLmdldFRyYW5zZmVyRGF0YShkZiwgZHMpOworCWFzc2VydEVxdWFscyhTdHJpbmcuY2xhc3MsIGNvbnRlbnQuZ2V0Q2xhc3MoKSk7CisJYXNzZXJ0RXF1YWxzKHhtbCwgKFN0cmluZyljb250ZW50KTsKKyAgICB9CisKKyAgICAvLyB0ZXN0IElucHV0U3RyZWFtIHRvIFN0cmVhbVNvdXJjZQorICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFN0cmVhbVRvU291cmNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJRGF0YUNvbnRlbnRIYW5kbGVyIGRjaCA9IG5ldyB0ZXh0X3htbCgpOworCURhdGFGbGF2b3IgZGYgPSBuZXcgQWN0aXZhdGlvbkRhdGFGbGF2b3IoU3RyZWFtU291cmNlLmNsYXNzLAorCQkJCQkJICAgICJ0ZXh0L3htbCIsICJYTUwgc3RyZWFtIik7CisJRGF0YVNvdXJjZSBkcyA9IG5ldyBCeXRlQXJyYXlEYXRhU291cmNlKHhtbEJ5dGVzLCAidGV4dC94bWwiKTsKKwlPYmplY3QgY29udGVudCA9IGRjaC5nZXRUcmFuc2ZlckRhdGEoZGYsIGRzKTsKKwlhc3NlcnRFcXVhbHMoU3RyZWFtU291cmNlLmNsYXNzLCBjb250ZW50LmdldENsYXNzKCkpOworCVN0cmluZyBzYyA9IHN0cmVhbVRvU3RyaW5nKCgoU3RyZWFtU291cmNlKWNvbnRlbnQpLmdldElucHV0U3RyZWFtKCkpOworCWFzc2VydEVxdWFscyh4bWwsIHNjKTsKKyAgICB9CisKKyAgICAvLyB0ZXN0IFN0cmluZyB0byBPdXRwdXRTdHJlYW0KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RTdHJpbmdUb1N0cmVhbSgpIHRocm93cyBFeGNlcHRpb24geworCURhdGFDb250ZW50SGFuZGxlciBkY2ggPSBuZXcgdGV4dF94bWwoKTsKKwlCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworCWRjaC53cml0ZVRvKHhtbCwgInRleHQveG1sIiwgYm9zKTsKKwlTdHJpbmcgc2MgPSBuZXcgU3RyaW5nKGJvcy50b0J5dGVBcnJheSgpLCAidXMtYXNjaWkiKTsKKwlhc3NlcnRFcXVhbHMoeG1sLCBzYyk7CisgICAgfQorCisgICAgLy8gdGVzdCBTdHJlYW1Tb3VyY2UgdG8gT3V0cHV0U3RyZWFtCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U291cmNlVG9TdHJlYW0oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlEYXRhQ29udGVudEhhbmRsZXIgZGNoID0gbmV3IHRleHRfeG1sKCk7CisJQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKwlTdHJlYW1Tb3VyY2Ugc3MgPSBuZXcgU3RyZWFtU291cmNlKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSh4bWxCeXRlcykpOworCWRjaC53cml0ZVRvKHNzLCAidGV4dC94bWwiLCBib3MpOworCVN0cmluZyBzYyA9IG5ldyBTdHJpbmcoYm9zLnRvQnl0ZUFycmF5KCksICJ1cy1hc2NpaSIpOworCS8vIHRyYW5zZm9ybWVyIGFkZHMgYW4gPD94bWw+IGhlYWRlciwgc28gY2FuJ3QgY2hlY2sgZm9yIGV4YWN0IG1hdGNoCisJYXNzZXJ0VHJ1ZShzYy5pbmRleE9mKHhtbC50cmltKCkpID49IDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWQgYSBzdHJlYW0gaW50byBhIFN0cmluZy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgc3RyZWFtVG9TdHJpbmcoSW5wdXRTdHJlYW0gaXMpIHsKKwl0cnkgeworCSAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKwkgICAgaW50IGM7CisJICAgIHdoaWxlICgoYyA9IGlzLnJlYWQoKSkgPiAwKQorCQlzYi5hcHBlbmQoKGNoYXIpYyk7CisJICAgIHJldHVybiBzYi50b1N0cmluZygpOworCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisJICAgIHJldHVybiAiIjsKKwl9IGZpbmFsbHkgeworCSAgICB0cnkgeworCQlpcy5jbG9zZSgpOworCSAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBjZXgpIHsgfQorCX0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL2lhcC9Qcm90b2NvbFRlc3QuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaWFwL1Byb3RvY29sVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUzZjU3YjIKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL2lhcC9Qcm90b2NvbFRlc3QuamF2YQpAQCAtMCwwICsxLDg1IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDA5LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5pYXA7CisKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7CisKK2ltcG9ydCBjb20uc3VuLm1haWwudGVzdC5OdWxsT3V0cHV0U3RyZWFtOworCitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RXF1YWxzOworCisvKioKKyAqIFRlc3QgdGhlIFByb3RvY29sIGNsYXNzLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgUHJvdG9jb2xUZXN0IHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBub0J5dGVzID0gbmV3IGJ5dGVbMF07CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgUHJpbnRTdHJlYW0gbnVsbHBzID0KKwkJCQkgICAgbmV3IFByaW50U3RyZWFtKG5ldyBOdWxsT3V0cHV0U3RyZWFtKCkpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEJ5dGVBcnJheUlucHV0U3RyZWFtIG51bGxpcyA9CisJCQkJICAgIG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShub0J5dGVzKTsKKworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCB0aGUgdGFnIHByZWZpeCBpcyBjb21wdXRlZCBwcm9wZXJseS4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RUYWdQcmVmaXgoKSB0aHJvd3MgSU9FeGNlcHRpb24sIFByb3RvY29sRXhjZXB0aW9uIHsKKwlQcm90b2NvbC50YWdOdW0uc2V0KDApOwkJLy8gcmVzZXQgZm9yIHRlc3RpbmcKKwlTdHJpbmcgdGFnID0gbmV3UHJvdG9jb2xUYWcoKTsKKwlhc3NlcnRFcXVhbHMoIkEwIiwgdGFnKTsKKwlmb3IgKGludCBpID0gMTsgaSA8IDI2OyBpKyspCisJICAgIHRhZyA9IG5ld1Byb3RvY29sVGFnKCk7CisJYXNzZXJ0RXF1YWxzKCJaMCIsIHRhZyk7CisJdGFnID0gbmV3UHJvdG9jb2xUYWcoKTsKKwlhc3NlcnRFcXVhbHMoIkFBMCIsIHRhZyk7CisJZm9yIChpbnQgaSA9IDI2ICsgMTsgaSA8ICgyNioyNiArIDI2KTsgaSsrKQorCSAgICB0YWcgPSBuZXdQcm90b2NvbFRhZygpOworCWFzc2VydEVxdWFscygiWlowIiwgdGFnKTsKKwl0YWcgPSBuZXdQcm90b2NvbFRhZygpOworCWFzc2VydEVxdWFscygiQUFBMCIsIHRhZyk7CisJZm9yIChpbnQgaSA9IDI2KjI2ICsgMjYgKyAxOyBpIDwgKDI2KjI2KjI2ICsgMjYqMjYgKyAyNik7IGkrKykKKwkgICAgdGFnID0gbmV3UHJvdG9jb2xUYWcoKTsKKwlhc3NlcnRFcXVhbHMoIlpaWjAiLCB0YWcpOworCXRhZyA9IG5ld1Byb3RvY29sVGFnKCk7CisJLy8gZGlkIGl0IHdyYXAgYXJvdW5kPworCWFzc2VydEVxdWFscygiQTAiLCB0YWcpOworICAgIH0KKworICAgIHByaXZhdGUgU3RyaW5nIG5ld1Byb3RvY29sVGFnKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBQcm90b2NvbEV4Y2VwdGlvbiB7CisJUHJvcGVydGllcyBwcm9wcyA9IG5ldyBQcm9wZXJ0aWVzKCk7CisJUHJvdG9jb2wgcCA9IG5ldyBQcm90b2NvbChudWxsaXMsIG51bGxwcywgcHJvcHMsIGZhbHNlKTsKKwlTdHJpbmcgdGFnID0gcC53cml0ZUNvbW1hbmQoIkNNRCIsIG51bGwpOworCXJldHVybiB0YWc7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IHRoZSB0YWcgcHJlZml4IGlzIHJldXNlZC4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RUYWdQcmVmaXhSZXVzZSgpIHRocm93cyBJT0V4Y2VwdGlvbiwgUHJvdG9jb2xFeGNlcHRpb24geworCVByb3BlcnRpZXMgcHJvcHMgPSBuZXcgUHJvcGVydGllcygpOworCXByb3BzLnNldFByb3BlcnR5KCJtYWlsLmltYXAucmV1c2V0YWdwcmVmaXgiLCAidHJ1ZSIpOworCVByb3RvY29sIHAgPSBuZXcgUHJvdG9jb2wobnVsbGlzLCBudWxscHMsIHByb3BzLCBmYWxzZSk7CisJU3RyaW5nIHRhZyA9IHAud3JpdGVDb21tYW5kKCJDTUQiLCBudWxsKTsKKwlhc3NlcnRFcXVhbHMoIkEwIiwgdGFnKTsKKwlwID0gbmV3IFByb3RvY29sKG51bGxpcywgbnVsbHBzLCBwcm9wcywgZmFsc2UpOworCXRhZyA9IHAud3JpdGVDb21tYW5kKCJDTUQiLCBudWxsKTsKKwlhc3NlcnRFcXVhbHMoIkEwIiwgdGFnKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL2lhcC9SZXNwb25zZUlucHV0U3RyZWFtVGVzdC5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9pYXAvUmVzcG9uc2VJbnB1dFN0cmVhbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZmRiMGMzCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9pYXAvUmVzcG9uc2VJbnB1dFN0cmVhbVRlc3QuamF2YQpAQCAtMCwwICsxLDQ2IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDEzLCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5pYXA7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5mYWlsOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCisvKioKKyAqIFRlc3QgUmVzcG9uc2VJbnB1dFN0cmVhbS4KKyAqLworcHVibGljIGNsYXNzIFJlc3BvbnNlSW5wdXRTdHJlYW1UZXN0IHsKKworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCBhbiBFT0Ygd2hpbGUgcmVhZGluZyBhIGxpdGVyYWwgdGhyb3dzIGFuIElPRXhjZXB0aW9uLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEVvZldoaWxlUmVhZGluZ0xpdGVyYWwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlCeXRlQXJyYXlJbnB1dFN0cmVhbSBiaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oCisJICAgICJ0ZXN0ezF9XHJcbiIuZ2V0Qnl0ZXMoIklTTy04ODU5LTEiKSk7CisJUmVzcG9uc2VJbnB1dFN0cmVhbSByaXMgPSBuZXcgUmVzcG9uc2VJbnB1dFN0cmVhbShiaXMpOworCXRyeSB7CisJICAgIHJpcy5yZWFkUmVzcG9uc2UoKTsKKwl9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworCSAgICAvLyBzdWNjZXNzIQorCSAgICByZXR1cm47CisJfQorCWZhaWwoIm5vIGV4Y2VwdGlvbiIpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaWFwL1Jlc3BvbnNlVGVzdC5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9pYXAvUmVzcG9uc2VUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDc1ZWFkNAotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaWFwL1Jlc3BvbnNlVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTY4IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDEzLCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5pYXA7CisKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRFcXVhbHM7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0QXJyYXlFcXVhbHM7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LlJ1bGU7CitpbXBvcnQgb3JnLmp1bml0LnJ1bGVzLlRpbWVvdXQ7CisKKy8qKgorICogVGVzdCByZXNwb25zZSBwYXJzaW5nLgorICovCitwdWJsaWMgY2xhc3MgUmVzcG9uc2VUZXN0IHsKKyAgICAvLyB0aW1lb3V0IHRoZSB0ZXN0IGluIGNhc2Ugb2YgaW5maW5pdGUgbG9vcAorICAgIEBSdWxlCisgICAgcHVibGljIFRpbWVvdXQgdGltZW91dCA9IFRpbWVvdXQuc2Vjb25kcyg1KTsKKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZ1tdIGF0b21UZXN0cyA9IHsKKwkiYXRvbSIsICJhdG9tICIsICJhdG9tKCIsICJhdG9tKSIsICJhdG9teyIsICJhdG9tKiIsICJhdG9tJSIsCisJImF0b21cIiIsICJhdG9tXFwgIiwgImF0b21dIiwgImF0b21cMDAxIiwgImF0b21cMTc3IgorICAgIH07CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmdbXSBhc3RyaW5nVGVzdHMgPSB7CisJImF0b20iLCAiYXRvbSAiLCAiYXRvbSgiLCAiYXRvbSkiLCAiYXRvbXsiLCAiYXRvbSoiLCAiYXRvbSUiLAorCSJhdG9tXCIiLCAiYXRvbVxcICIsICJhdG9tXDAwMSIsICJhdG9tXDE3NyIsICJcImF0b21cIiIsCisJIns0fVxyXG5hdG9tIgorICAgIH07CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHBhcnNpbmcgYXRvbXMuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QXRvbSgpIHRocm93cyBFeGNlcHRpb24geworCWZvciAoU3RyaW5nIHMgOiBhdG9tVGVzdHMpIHsKKwkgICAgUmVzcG9uc2UgciA9IG5ldyBSZXNwb25zZSgiKiAiICsgcyk7CisJICAgIGFzc2VydEVxdWFscygiYXRvbSIsIHIucmVhZEF0b20oKSk7CisJfQorCWZvciAoU3RyaW5nIHMgOiBhdG9tVGVzdHMpIHsKKwkgICAgUmVzcG9uc2UgciA9IG5ldyBSZXNwb25zZSgiKiAiICsgcyArICIgIik7CisJICAgIGFzc2VydEVxdWFscygiYXRvbSIsIHIucmVhZEF0b20oKSk7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgcGFyc2luZyBhc3RyaW5ncy4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RBU3RyaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJZm9yIChTdHJpbmcgcyA6IGFzdHJpbmdUZXN0cykgeworCSAgICBSZXNwb25zZSByID0gbmV3IFJlc3BvbnNlKCIqICIgKyBzKTsKKwkgICAgYXNzZXJ0RXF1YWxzKCJhdG9tIiwgci5yZWFkQXRvbVN0cmluZygpKTsKKwl9CisJZm9yIChTdHJpbmcgcyA6IGFzdHJpbmdUZXN0cykgeworCSAgICBSZXNwb25zZSByID0gbmV3IFJlc3BvbnNlKCIqICIgKyBzICsgIiAiKTsKKwkgICAgYXNzZXJ0RXF1YWxzKCJhdG9tIiwgci5yZWFkQXRvbVN0cmluZygpKTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGUgc3BlY2lhbCBjYXNlIHdoZXJlIGFuIGFzdHJpbmcgY2FuIGluY2x1ZGUgJ10nLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEFTdHJpbmdTcGVjaWFsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJUmVzcG9uc2UgciA9IG5ldyBSZXNwb25zZSgiKiAiICsgImF0b21dICIpOworCWFzc2VydEVxdWFscygiYXRvbV0iLCByLnJlYWRBdG9tU3RyaW5nKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgYXN0cmluZyBsaXN0cy4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RBU3RyaW5nTGlzdCgpIHRocm93cyBFeGNlcHRpb24geworCVJlc3BvbnNlIHIgPSBuZXcgUmVzcG9uc2UoIiogIiArICIoQSBCIEMpIik7CisJYXNzZXJ0QXJyYXlFcXVhbHMobmV3IFN0cmluZ1tdIHsgIkEiLCAiQiIsICJDIiB9LAorCQkJICAgIHIucmVhZEF0b21TdHJpbmdMaXN0KCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEFTdHJpbmdMaXN0SW5pdGlhbFNwYWNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJUmVzcG9uc2UgciA9IG5ldyBSZXNwb25zZSgiKiAiICsgIiggQSBCIEMpIik7CisJYXNzZXJ0QXJyYXlFcXVhbHMobmV3IFN0cmluZ1tdIHsgIkEiLCAiQiIsICJDIiB9LAorCQkJICAgIHIucmVhZEF0b21TdHJpbmdMaXN0KCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEFTdHJpbmdMaXN0VHJhaWxpbmdTcGFjZSgpIHRocm93cyBFeGNlcHRpb24geworCVJlc3BvbnNlIHIgPSBuZXcgUmVzcG9uc2UoIiogIiArICIoQSBCIEMgKSIpOworCWFzc2VydEFycmF5RXF1YWxzKG5ldyBTdHJpbmdbXSB7ICJBIiwgIkIiLCAiQyIgfSwKKwkJCSAgICByLnJlYWRBdG9tU3RyaW5nTGlzdCgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RBU3RyaW5nTGlzdEluaXRpYWxBbmRUcmFpbGluZ1NwYWNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJUmVzcG9uc2UgciA9IG5ldyBSZXNwb25zZSgiKiAiICsgIiggQSBCIEMgKSIpOworCWFzc2VydEFycmF5RXF1YWxzKG5ldyBTdHJpbmdbXSB7ICJBIiwgIkIiLCAiQyIgfSwKKwkJCSAgICByLnJlYWRBdG9tU3RyaW5nTGlzdCgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RBU3RyaW5nTGlzdE11bHRpcGxlU3BhY2VzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJUmVzcG9uc2UgciA9IG5ldyBSZXNwb25zZSgiKiAiICsgIihBICBCICAgIEMpIik7CisJYXNzZXJ0QXJyYXlFcXVhbHMobmV3IFN0cmluZ1tdIHsgIkEiLCAiQiIsICJDIiB9LAorCQkJICAgIHIucmVhZEF0b21TdHJpbmdMaXN0KCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEFTdHJpbmdMaXN0UXVvdGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJUmVzcG9uc2UgciA9IG5ldyBSZXNwb25zZSgiKiAiICsgIihBIEIgXCJDXCIpIik7CisJYXNzZXJ0QXJyYXlFcXVhbHMobmV3IFN0cmluZ1tdIHsgIkEiLCAiQiIsICJDIiB9LAorCQkJICAgIHIucmVhZEF0b21TdHJpbmdMaXN0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgYXN0cmluZyBsaXN0cyB3aXRoIG1vcmUgZGF0YSBmb2xsb3dpbmcuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QVN0cmluZ0xpc3RNb3JlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJUmVzcG9uc2UgciA9IG5ldyBSZXNwb25zZSgiKiAiICsgIihBIEIgXCJDXCIpIGF0b20iKTsKKwlhc3NlcnRBcnJheUVxdWFscyhuZXcgU3RyaW5nW10geyAiQSIsICJCIiwgIkMiIH0sCisJCQkgICAgci5yZWFkQXRvbVN0cmluZ0xpc3QoKSk7CisJYXNzZXJ0RXF1YWxzKCJhdG9tIiwgci5yZWFkQXRvbVN0cmluZygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGVtcHR5IGFzdHJpbmcgbGlzdHMuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QVN0cmluZ0xpc3RFbXB0eSgpIHRocm93cyBFeGNlcHRpb24geworCVJlc3BvbnNlIHIgPSBuZXcgUmVzcG9uc2UoIiogIiArICIoKSIpOworCWFzc2VydEFycmF5RXF1YWxzKG5ldyBTdHJpbmdbMF0sIHIucmVhZEF0b21TdHJpbmdMaXN0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgZW1wdHkgYXN0cmluZyBsaXN0cyB3aXRoIG1vcmUgZGF0YSBmb2xsb3dpbmcuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QVN0cmluZ0xpc3RFbXB0eU1vcmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlSZXNwb25zZSByID0gbmV3IFJlc3BvbnNlKCIqICIgKyAiKCkgYXRvbSIpOworCWFzc2VydEFycmF5RXF1YWxzKG5ldyBTdHJpbmdbMF0sIHIucmVhZEF0b21TdHJpbmdMaXN0KCkpOworCWFzc2VydEVxdWFscygiYXRvbSIsIHIucmVhZEF0b21TdHJpbmcoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCByZWFkU3RyaW5nTGlzdAorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEJhZFN0cmluZ0xpc3QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlSZXNwb25zZSByZXNwb25zZSA9IG5ldyBSZXNwb25zZSgKKwkJCSAgICAiKiAoXCJuYW1lXCIsIFwidGVzdFwiLCBcInZlcnNpb25cIiwgXCIxLjBcIikiKTsKKyAgICAgICAgU3RyaW5nW10gbGlzdCA9IHJlc3BvbnNlLnJlYWRTdHJpbmdMaXN0KCk7CisJLy8gYW55dGhpbmcgb3RoZXIgdGhhbiBhbiBpbmZpbml0ZSBsb29wIHRpbWVvdXQgaXMgY29uc2lkZXJlZCBzdWNjZXNzCisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0lNQVBBbGVydFRlc3QuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9JTUFQQWxlcnRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2IzNTFkNgotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9JTUFQQWxlcnRUZXN0LmphdmEKQEAgLTAsMCArMSwxMDQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDksIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmltYXA7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkNvdW50RG93bkxhdGNoOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LlRpbWVVbml0OworCitpbXBvcnQgamF2YXgubWFpbC5TZXNzaW9uOworaW1wb3J0IGphdmF4Lm1haWwuU3RvcmU7CitpbXBvcnQgamF2YXgubWFpbC5ldmVudC5TdG9yZUxpc3RlbmVyOworaW1wb3J0IGphdmF4Lm1haWwuZXZlbnQuU3RvcmVFdmVudDsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC50ZXN0LlRlc3RTZXJ2ZXI7CisKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUcnVlOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmZhaWw7CisKKy8qKgorICogVGVzdCBhbGVydHMuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBJTUFQQWxlcnRUZXN0IHsKKworICAgIHByaXZhdGUgdm9sYXRpbGUgYm9vbGVhbiBnb3RBbGVydCA9IGZhbHNlOworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0KCkgeworICAgICAgICBUZXN0U2VydmVyIHNlcnZlciA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaW5hbCBJTUFQSGFuZGxlciBoYW5kbGVyID0gbmV3IElNQVBIYW5kbGVyQWxlcnQoKTsKKyAgICAgICAgICAgIHNlcnZlciA9IG5ldyBUZXN0U2VydmVyKGhhbmRsZXIpOworICAgICAgICAgICAgc2VydmVyLnN0YXJ0KCk7CisKKyAgICAgICAgICAgIGZpbmFsIFByb3BlcnRpZXMgcHJvcGVydGllcyA9IG5ldyBQcm9wZXJ0aWVzKCk7CisgICAgICAgICAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLmltYXAuaG9zdCIsICJsb2NhbGhvc3QiKTsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuaW1hcC5wb3J0IiwgIiIgKyBzZXJ2ZXIuZ2V0UG9ydCgpKTsKKyAgICAgICAgICAgIGZpbmFsIFNlc3Npb24gc2Vzc2lvbiA9IFNlc3Npb24uZ2V0SW5zdGFuY2UocHJvcGVydGllcyk7CisgICAgICAgICAgICAvL3Nlc3Npb24uc2V0RGVidWcodHJ1ZSk7CisJICAgIGZpbmFsIENvdW50RG93bkxhdGNoIGxhdGNoID0gbmV3IENvdW50RG93bkxhdGNoKDEpOworCisgICAgICAgICAgICBmaW5hbCBTdG9yZSBzdG9yZSA9IHNlc3Npb24uZ2V0U3RvcmUoImltYXAiKTsKKwkgICAgc3RvcmUuYWRkU3RvcmVMaXN0ZW5lcihuZXcgU3RvcmVMaXN0ZW5lcigpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIG5vdGlmaWNhdGlvbihTdG9yZUV2ZW50IGUpIHsKKwkJICAgIFN0cmluZyBzOworCQkgICAgaWYgKGUuZ2V0TWVzc2FnZVR5cGUoKSA9PSBTdG9yZUV2ZW50LkFMRVJUKSB7CisJCQlzID0gIkFMRVJUOiAiOworCQkJZ290QWxlcnQgPSB0cnVlOworCQkJbGF0Y2guY291bnREb3duKCk7CisJCSAgICB9IGVsc2UKKwkJCXMgPSAiTk9USUNFOiAiOworCQkgICAgLy9TeXN0ZW0ub3V0LnByaW50bG4ocyArIGUuZ2V0TWVzc2FnZSgpKTsKKwkJfQorCSAgICB9KTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc3RvcmUuY29ubmVjdCgidGVzdCIsICJ0ZXN0Iik7CisJCS8vIHRpbWUgZm9yIGV2ZW50IHRvIGJlIGRlbGl2ZXJlZAorCQlsYXRjaC5hd2FpdCg1LCBUaW1lVW5pdC5TRUNPTkRTKTsKKwkJYXNzZXJ0VHJ1ZShnb3RBbGVydCk7CisKKwkgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJCVN5c3RlbS5vdXQucHJpbnRsbihleCk7CisJCS8vZXgucHJpbnRTdGFja1RyYWNlKCk7CisJCWZhaWwoZXgudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHN0b3JlLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoc2VydmVyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBzZXJ2ZXIucXVpdCgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3VzdG9tIGhhbmRsZXIuICBSZXR1cm5zIGFuIGFsZXJ0IG1lc3NhZ2UgYXQgbG9naW4uCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSU1BUEhhbmRsZXJBbGVydCBleHRlbmRzIElNQVBIYW5kbGVyIHsKKwlAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgbG9naW4oKSB0aHJvd3MgSU9FeGNlcHRpb24geworCSAgICB1bnRhZ2dlZCgiT0sgW0FMRVJUXSBhY2NvdW50IGlzIG92ZXIgcXVvdGEiKTsKKwkgICAgc3VwZXIubG9naW4oKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9JTUFQQXV0aERlYnVnVGVzdC5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0lNQVBBdXRoRGVidWdUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTFmZjRmYgotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9JTUFQQXV0aERlYnVnVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTMyIEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDA5LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5pbWFwOworCitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOworCitpbXBvcnQgamF2YXgubWFpbC5TZXNzaW9uOworaW1wb3J0IGphdmF4Lm1haWwuU3RvcmU7CisKK2ltcG9ydCBjb20uc3VuLm1haWwudGVzdC5UZXN0U2VydmVyOworCitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LlJ1bGU7CitpbXBvcnQgb3JnLmp1bml0LnJ1bGVzLlRpbWVvdXQ7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VHJ1ZTsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRGYWxzZTsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5mYWlsOworCisvKioKKyAqIFRlc3QgdGhhdCBhdXRoZW50aWNhdGlvbiBpbmZvcm1hdGlvbiBpcyBvbmx5IGluY2x1ZGVkIGluCisgKiB0aGUgZGVidWcgb3V0cHV0IHdoZW4gZXhwbGljaXRseSByZXF1ZXN0ZWQgYnkgc2V0dGluZyB0aGUKKyAqIHByb3BlcnR5ICJtYWlsLmRlYnVnLmF1dGgiIHRvICJ0cnVlIi4KKyAqCisgKiBYWFggLSBzaG91bGQgdGVzdCBhbGwgYXV0aGVudGljYXRpb24gdHlwZXMsIGJ1dCB0aGF0IHJlcXVpcmVzCisgKgkgbW9yZSB3b3JrIGluIHRoZSBkdW1teSB0ZXN0IHNlcnZlci4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIElNQVBBdXRoRGVidWdUZXN0IHsKKworICAgIC8vIHRpbWVvdXQgdGhlIHRlc3QgaW4gY2FzZSBvZiBkZWFkbG9jaworICAgIEBSdWxlCisgICAgcHVibGljIFRpbWVvdXQgZGVhZGxvY2tUaW1lb3V0ID0gVGltZW91dC5zZWNvbmRzKDIwKTsKKworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCBhdXRoZW50aWNhdGlvbiBpbmZvcm1hdGlvbiBpc24ndCBpbmNsdWRlZCBpbiB0aGUgZGVidWcgb3V0cHV0LgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdE5vQXV0aERlZmF1bHQoKSB7CisJZmluYWwgUHJvcGVydGllcyBwcm9wZXJ0aWVzID0gbmV3IFByb3BlcnRpZXMoKTsKKwlhc3NlcnRGYWxzZSgiTE9HSU4gaW4gZGVidWcgb3V0cHV0IiwgdGVzdChwcm9wZXJ0aWVzLCAiTE9HSU4iKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Tm9BdXRoKCkgeworCWZpbmFsIFByb3BlcnRpZXMgcHJvcGVydGllcyA9IG5ldyBQcm9wZXJ0aWVzKCk7CisJcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5kZWJ1Zy5hdXRoIiwgImZhbHNlIik7CisJYXNzZXJ0RmFsc2UoIkxPR0lOIGluIGRlYnVnIG91dHB1dCIsIHRlc3QocHJvcGVydGllcywgIkxPR0lOIikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCBhdXRoZW50aWNhdGlvbiBpbmZvcm1hdGlvbiAqaXMqIGluY2x1ZGVkIGluIHRoZSBkZWJ1ZyBvdXRwdXQuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QXV0aCgpIHsKKwlmaW5hbCBQcm9wZXJ0aWVzIHByb3BlcnRpZXMgPSBuZXcgUHJvcGVydGllcygpOworCXByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuZGVidWcuYXV0aCIsICJ0cnVlIik7CisJYXNzZXJ0VHJ1ZSgiTE9HSU4gaW4gZGVidWcgb3V0cHV0IiwgdGVzdChwcm9wZXJ0aWVzLCAiTE9HSU4iKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgdGVzdCBzZXJ2ZXIsIGNvbm5lY3QgdG8gaXQsIGFuZCBjb2xsZWN0IHRoZSBkZWJ1ZyBvdXRwdXQuCisgICAgICogU2NhbiB0aGUgZGVidWcgb3V0cHV0IGxvb2tpbmcgZm9yICJleHBlY3QiLCByZXR1cm4gdHJ1ZSBpZiBmb3VuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiB0ZXN0KFByb3BlcnRpZXMgcHJvcGVydGllcywgU3RyaW5nIGV4cGVjdCkgeworCVRlc3RTZXJ2ZXIgc2VydmVyID0gbnVsbDsKKwl0cnkgeworCSAgICBmaW5hbCBJTUFQSGFuZGxlciBoYW5kbGVyID0gbmV3IElNQVBIYW5kbGVyKCk7CisJICAgIHNlcnZlciA9IG5ldyBUZXN0U2VydmVyKGhhbmRsZXIpOworCSAgICBzZXJ2ZXIuc3RhcnQoKTsKKworCSAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLmltYXAuaG9zdCIsICJsb2NhbGhvc3QiKTsKKwkgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5pbWFwLnBvcnQiLCAiIiArIHNlcnZlci5nZXRQb3J0KCkpOworCSAgICBmaW5hbCBTZXNzaW9uIHNlc3Npb24gPSBTZXNzaW9uLmdldEluc3RhbmNlKHByb3BlcnRpZXMpOworCSAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworCSAgICBQcmludFN0cmVhbSBwcyA9IG5ldyBQcmludFN0cmVhbShib3MpOworCSAgICBzZXNzaW9uLnNldERlYnVnT3V0KHBzKTsKKwkgICAgc2Vzc2lvbi5zZXREZWJ1Zyh0cnVlKTsKKworCSAgICBmaW5hbCBTdG9yZSBzdG9yZSA9IHNlc3Npb24uZ2V0U3RvcmUoImltYXAiKTsKKwkgICAgdHJ5IHsKKwkJc3RvcmUuY29ubmVjdCgidGVzdCIsICJ0ZXN0Iik7CisJICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCQlTeXN0ZW0ub3V0LnByaW50bG4oZXgpOworCQkvL2V4LnByaW50U3RhY2tUcmFjZSgpOworCQlmYWlsKGV4LnRvU3RyaW5nKCkpOworCSAgICB9IGZpbmFsbHkgeworCQlzdG9yZS5jbG9zZSgpOworCSAgICB9CisKKwkgICAgcHMuY2xvc2UoKTsKKwkgICAgYm9zLmNsb3NlKCk7CisJICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGJpcyA9CisJCW5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShib3MudG9CeXRlQXJyYXkoKSk7CisJICAgIEJ1ZmZlcmVkUmVhZGVyIHIgPSBuZXcgQnVmZmVyZWRSZWFkZXIoCisJCQkJCW5ldyBJbnB1dFN0cmVhbVJlYWRlcihiaXMsICJ1cy1hc2NpaSIpKTsKKwkgICAgU3RyaW5nIGxpbmU7CisJICAgIGJvb2xlYW4gZm91bmQgPSBmYWxzZTsKKwkgICAgd2hpbGUgKChsaW5lID0gci5yZWFkTGluZSgpKSAhPSBudWxsKSB7CisJCWlmIChsaW5lLnN0YXJ0c1dpdGgoIkRFQlVHIikpCisJCSAgICBjb250aW51ZTsKKwkJaWYgKGxpbmUuc3RhcnRzV2l0aCgiKiIpKQorCQkgICAgY29udGludWU7CisJCWlmIChsaW5lLmluZGV4T2YoZXhwZWN0KSA+PSAwKQorCQkgICAgZm91bmQgPSB0cnVlOworCSAgICB9CisJICAgIHIuY2xvc2UoKTsKKwkgICAgcmV0dXJuIGZvdW5kOworCX0gY2F0Y2ggKGZpbmFsIEV4Y2VwdGlvbiBlKSB7CisJICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisJICAgIGZhaWwoZS5nZXRNZXNzYWdlKCkpOworCSAgICByZXR1cm4gZmFsc2U7CS8vIFhYWCAtIGRvZXNuJ3QgbWF0dGVyCisJfSBmaW5hbGx5IHsKKwkgICAgaWYgKHNlcnZlciAhPSBudWxsKSB7CisJCXNlcnZlci5xdWl0KCk7CisJICAgIH0KKwl9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0lNQVBDbG9zZUZhaWx1cmVUZXN0LmphdmEgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL2ltYXAvSU1BUENsb3NlRmFpbHVyZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lYWNiNjhmCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0lNQVBDbG9zZUZhaWx1cmVUZXN0LmphdmEKQEAgLTAsMCArMSwxMTQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDksIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmltYXA7CisKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7CisKK2ltcG9ydCBqYXZheC5tYWlsLlNlc3Npb247CitpbXBvcnQgamF2YXgubWFpbC5TdG9yZTsKK2ltcG9ydCBqYXZheC5tYWlsLkZvbGRlcjsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC50ZXN0LlRlc3RTZXJ2ZXI7CisKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5mYWlsOworCisvKioKKyAqIFRlc3QgdGhhdCBmYWlsdXJlcyB3aGlsZSBjbG9zaW5nIGEgZm9sZGVyIGFyZSBoYW5kbGVkIHByb3Blcmx5LgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgSU1BUENsb3NlRmFpbHVyZVRlc3QgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEhPU1QgPSAibG9jYWxob3N0IjsKKworICAgIHN0YXRpYyBjbGFzcyBOb0lNQVBIYW5kbGVyIGV4dGVuZHMgSU1BUEhhbmRsZXIgeworCXN0YXRpYyBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKKworCUBPdmVycmlkZQorCXB1YmxpYyB2b2lkIGV4YW1pbmUoU3RyaW5nIGxpbmUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJICAgIGlmIChmaXJzdCkKKwkJbm8oIm1haWxib3ggZ29uZSIpOworCSAgICBlbHNlCisJCXN1cGVyLmV4YW1pbmUobGluZSk7CisJICAgIGZpcnN0ID0gZmFsc2U7CisJfQorICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBCYWRJTUFQSGFuZGxlciBleHRlbmRzIElNQVBIYW5kbGVyIHsKKwlzdGF0aWMgYm9vbGVhbiBmaXJzdCA9IHRydWU7CisKKwlAT3ZlcnJpZGUKKwlwdWJsaWMgdm9pZCBleGFtaW5lKFN0cmluZyBsaW5lKSB0aHJvd3MgSU9FeGNlcHRpb24geworCSAgICBpZiAoZmlyc3QpCisJCWJhZCgibWFpbGJveCBnb25lIik7CisJICAgIGVsc2UKKwkJc3VwZXIuZXhhbWluZShsaW5lKTsKKwkgICAgZmlyc3QgPSBmYWxzZTsKKwl9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2xvc2VObygpIHsKKwl0ZXN0Q2xvc2UobmV3IE5vSU1BUEhhbmRsZXIoKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2xvc2VCYWQoKSB7CisJdGVzdENsb3NlKG5ldyBCYWRJTUFQSGFuZGxlcigpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2xvc2UoSU1BUEhhbmRsZXIgaGFuZGxlcikgeworCVRlc3RTZXJ2ZXIgc2VydmVyID0gbnVsbDsKKwl0cnkgeworCSAgICBzZXJ2ZXIgPSBuZXcgVGVzdFNlcnZlcihoYW5kbGVyKTsKKwkgICAgc2VydmVyLnN0YXJ0KCk7CisKKwkgICAgUHJvcGVydGllcyBwcm9wZXJ0aWVzID0gbmV3IFByb3BlcnRpZXMoKTsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuaW1hcC5ob3N0IiwgSE9TVCk7CisgICAgICAgICAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLmltYXAucG9ydCIsICIiICsgc2VydmVyLmdldFBvcnQoKSk7CisJICAgIFNlc3Npb24gc2Vzc2lvbiA9IFNlc3Npb24uZ2V0SW5zdGFuY2UocHJvcGVydGllcyk7CisJICAgIC8vc2Vzc2lvbi5zZXREZWJ1Zyh0cnVlKTsKKworCSAgICBTdG9yZSBzdG9yZSA9IHNlc3Npb24uZ2V0U3RvcmUoImltYXAiKTsKKwkgICAgdHJ5IHsKKwkJc3RvcmUuY29ubmVjdCgidGVzdCIsICJ0ZXN0Iik7CisJCUZvbGRlciBmID0gc3RvcmUuZ2V0Rm9sZGVyKCJJTkJPWCIpOworCQlmLm9wZW4oRm9sZGVyLlJFQURfV1JJVEUpOworCQlmLmNsb3NlKGZhbHNlKTsKKwkJLy8gTWFrZSBzdXJlIHRoYXQgZmFpbHVyZSB3aGlsZSBjbG9zaW5nIGRvZXNuJ3QgbGVhdmUgdXMKKwkJLy8gd2l0aCBhIGNvbm5lY3Rpb24gdGhhdCBjYW4ndCBiZSB1c2VkIHRvIG9wZW4gYSBmb2xkZXIuCisJCWYub3BlbihGb2xkZXIuUkVBRF9XUklURSk7CisJCWYuY2xvc2UoZmFsc2UpOworCSAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKwkJU3lzdGVtLm91dC5wcmludGxuKGV4KTsKKwkJLy9leC5wcmludFN0YWNrVHJhY2UoKTsKKwkJZmFpbChleC50b1N0cmluZygpKTsKKwkgICAgfSBmaW5hbGx5IHsKKwkJaWYgKHN0b3JlLmlzQ29ubmVjdGVkKCkpCisJCSAgICBzdG9yZS5jbG9zZSgpOworCSAgICB9CisKKwl9IGNhdGNoIChFeGNlcHRpb24gZSkgeworCSAgICBlLnByaW50U3RhY2tUcmFjZSgpOworCSAgICBmYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKwl9IGZpbmFsbHkgeworCSAgICBpZiAoc2VydmVyICE9IG51bGwpIHsKKwkJc2VydmVyLnF1aXQoKTsKKwkgICAgfQorCX0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL2ltYXAvSU1BUENvbm5lY3RGYWlsdXJlVGVzdC5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0lNQVBDb25uZWN0RmFpbHVyZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNjgyN2RmCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0lNQVBDb25uZWN0RmFpbHVyZVRlc3QuamF2YQpAQCAtMCwwICsxLDEzOCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwOSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuaW1hcDsKKworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKK2ltcG9ydCBqYXZhLm5ldC5TZXJ2ZXJTb2NrZXQ7CisKK2ltcG9ydCBqYXZheC5tYWlsLlNlc3Npb247CitpbXBvcnQgamF2YXgubWFpbC5TdG9yZTsKK2ltcG9ydCBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC5pYXAuQ29ubmVjdGlvbkV4Y2VwdGlvbjsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC50ZXN0LlRlc3RTZXJ2ZXI7CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuTWFpbENvbm5lY3RFeGNlcHRpb247CisKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRFcXVhbHM7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VHJ1ZTsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5mYWlsOworCisvKioKKyAqIFRlc3QgY29ubmVjdCBmYWlsdXJlLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgSU1BUENvbm5lY3RGYWlsdXJlVGVzdCB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgSE9TVCA9ICJsb2NhbGhvc3QiOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBDVE8gPSAyMDsKKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdE5vU2VydmVyKCkgeworCXRyeSB7CisJICAgIC8vIHZlcmlmeSB0aGF0IHBvcnQgaXMgbm90IGJlaW5nIHVzZWQKKwkgICAgU2VydmVyU29ja2V0IHNzID0gbmV3IFNlcnZlclNvY2tldCgwKTsKKwkgICAgaW50IHBvcnQgPSBzcy5nZXRMb2NhbFBvcnQoKTsKKwkgICAgc3MuY2xvc2UoKTsKKworCSAgICBQcm9wZXJ0aWVzIHByb3BlcnRpZXMgPSBuZXcgUHJvcGVydGllcygpOworICAgICAgICAgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5pbWFwLmhvc3QiLCBIT1NUKTsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuaW1hcC5wb3J0IiwgIiIgKyBwb3J0KTsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuaW1hcC5jb25uZWN0aW9udGltZW91dCIsICIiICsgQ1RPKTsKKwkgICAgU2Vzc2lvbiBzZXNzaW9uID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShwcm9wZXJ0aWVzKTsKKwkgICAgLy9zZXNzaW9uLnNldERlYnVnKHRydWUpOworCisJICAgIFN0b3JlIHN0b3JlID0gc2Vzc2lvbi5nZXRTdG9yZSgiaW1hcCIpOworCSAgICB0cnkgeworCQlzdG9yZS5jb25uZWN0KCJ0ZXN0IiwgInRlc3QiKTsKKwkJZmFpbCgiQ29ubmVjdGVkISIpOworCQkvLyBmYWlsdXJlIQorCSAgICB9IGNhdGNoIChNYWlsQ29ubmVjdEV4Y2VwdGlvbiBtY2V4KSB7CisJCS8vIHN1Y2Nlc3MhCisJCWFzc2VydEVxdWFscyhIT1NULCBtY2V4LmdldEhvc3QoKSk7CisJCWFzc2VydEVxdWFscyhwb3J0LCBtY2V4LmdldFBvcnQoKSk7CisJCWFzc2VydEVxdWFscyhDVE8sIG1jZXguZ2V0Q29ubmVjdGlvblRpbWVvdXQoKSk7CisJICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCQlTeXN0ZW0ub3V0LnByaW50bG4oZXgpOworCQkvL2V4LnByaW50U3RhY2tUcmFjZSgpOworCQlmYWlsKGV4LnRvU3RyaW5nKCkpOworCSAgICB9IGZpbmFsbHkgeworCQlpZiAoc3RvcmUuaXNDb25uZWN0ZWQoKSkKKwkJICAgIHN0b3JlLmNsb3NlKCk7CisJICAgIH0KKworCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisJICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisJICAgIGZhaWwoZS5nZXRNZXNzYWdlKCkpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHRoYXQgYSBkaXNjb25uZWN0IGFmdGVyIGlzc3VpbmcgdGhlIENBUEFCSUxJVFkgY29tbWFuZAorICAgICAqIHJlc3VsdHMgaW4gYSBDb25uZWN0aW9uRXhjZXB0aW9uLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENhcGFiaWxpdHlEaXNjb25uZWN0KCkgeworCVRlc3RTZXJ2ZXIgc2VydmVyID0gbnVsbDsKKwl0cnkgeworCSAgICBmaW5hbCBJTUFQSGFuZGxlciBoYW5kbGVyID0gbmV3IElNQVBIYW5kbGVyKCkgeworCQlAT3ZlcnJpZGUKKwkJcHVibGljIHZvaWQgc2VuZEdyZWV0aW5ncygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJCSAgICB1bnRhZ2dlZCgiT0sgSU1BUEhhbmRsZXIiKTsKKwkJfQorCisJCUBPdmVycmlkZQorCQlwdWJsaWMgdm9pZCBjYXBhYmlsaXR5KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkJICAgIGV4aXQoKTsKKwkJfQorCSAgICB9OworCSAgICBzZXJ2ZXIgPSBuZXcgVGVzdFNlcnZlcihoYW5kbGVyKTsKKwkgICAgc2VydmVyLnN0YXJ0KCk7CisKKwkgICAgUHJvcGVydGllcyBwcm9wZXJ0aWVzID0gbmV3IFByb3BlcnRpZXMoKTsKKwkgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5pbWFwLmhvc3QiLCAibG9jYWxob3N0Iik7CisJICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuaW1hcC5wb3J0IiwgIiIgKyBzZXJ2ZXIuZ2V0UG9ydCgpKTsKKwkgICAgZmluYWwgU2Vzc2lvbiBzZXNzaW9uID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShwcm9wZXJ0aWVzKTsKKwkgICAgLy9zZXNzaW9uLnNldERlYnVnKHRydWUpOworCisJICAgIGZpbmFsIFN0b3JlIHN0b3JlID0gc2Vzc2lvbi5nZXRTdG9yZSgiaW1hcCIpOworCSAgICB0cnkgeworCQlzdG9yZS5jb25uZWN0KCJ0ZXN0IiwgInRlc3QiKTsKKwkJZmFpbCgiY29ubmVjdCBkaWQgbm90IGZhaWwiKTsKKwkgICAgfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIG1leCkgeworCQkvLyB0aGlzIGlzIHdoYXQgd2UgZXhwZWN0LCBub3cgY2hlY2sgdGhhdCBpdCB3YXMgY2F1c2VkIGJ5CisJCS8vIHRoZSByaWdodCBleGNlcHRpb24KKwkJYXNzZXJ0VHJ1ZShtZXguZ2V0Q2F1c2UoKSBpbnN0YW5jZW9mIENvbm5lY3Rpb25FeGNlcHRpb24pOworCSAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKwkJU3lzdGVtLm91dC5wcmludGxuKGV4KTsKKwkJLy9leC5wcmludFN0YWNrVHJhY2UoKTsKKwkJZmFpbChleC50b1N0cmluZygpKTsKKwkgICAgfSBmaW5hbGx5IHsKKwkJc3RvcmUuY2xvc2UoKTsKKwkgICAgfQorCisJfSBjYXRjaCAoZmluYWwgRXhjZXB0aW9uIGUpIHsKKwkgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKwkgICAgZmFpbChlLmdldE1lc3NhZ2UoKSk7CisJfSBmaW5hbGx5IHsKKwkgICAgaWYgKHNlcnZlciAhPSBudWxsKSB7CisJCXNlcnZlci5xdWl0KCk7CisJICAgIH0KKwl9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0lNQVBGZXRjaFByb2ZpbGVUZXN0LmphdmEgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL2ltYXAvSU1BUEZldGNoUHJvZmlsZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYjkzM2Q5Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0lNQVBGZXRjaFByb2ZpbGVUZXN0LmphdmEKQEAgLTAsMCArMSwyMDQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDksIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmltYXA7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOworaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKKworaW1wb3J0IGphdmF4Lm1haWwuRm9sZGVyOworaW1wb3J0IGphdmF4Lm1haWwuU2Vzc2lvbjsKK2ltcG9ydCBqYXZheC5tYWlsLlN0b3JlOworaW1wb3J0IGphdmF4Lm1haWwuTWVzc2FnZTsKK2ltcG9ydCBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5tYWlsLkZldGNoUHJvZmlsZTsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC50ZXN0LlRlc3RTZXJ2ZXI7CisKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQuUnVsZTsKK2ltcG9ydCBvcmcuanVuaXQucnVsZXMuVGltZW91dDsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRFcXVhbHM7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VHJ1ZTsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRGYWxzZTsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5mYWlsOworCisvKioKKyAqIFRlc3QgSU1BUCBGZXRjaFByb2ZpbGUgaXRlbXMuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBJTUFQRmV0Y2hQcm9maWxlVGVzdCB7CisKKyAgICAvLyB0aW1lb3V0IHRoZSB0ZXN0IGluIGNhc2Ugb2YgZGVhZGxvY2sKKyAgICBAUnVsZQorICAgIHB1YmxpYyBUaW1lb3V0IGRlYWRsb2NrVGltZW91dCA9IFRpbWVvdXQuc2Vjb25kcygyMCk7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkRBVEUgPSAiMjMtSnVuLTIwMDQgMDY6MjY6MjYgLTA3MDAiOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBFTlZFTE9QRSA9CisJIihcIldlZCwgMjMgSnVuIDIwMDQgMTg6NTY6NDIgKzA1MzBcIiBcInRlc3RcIiAiICsKKwkiKChcIkphdmFNYWlsXCIgTklMIFwidGVzdHVzZXJcIiBcImV4YW1wbGUuY29tXCIpKSAiICsKKwkiKChcIkphdmFNYWlsXCIgTklMIFwidGVzdHVzZXJcIiBcImV4YW1wbGUuY29tXCIpKSAiICsKKwkiKChcIkphdmFNYWlsXCIgTklMIFwidGVzdHVzZXJcIiBcImV4YW1wbGUuY29tXCIpKSAiICsKKwkiKChOSUwgTklMIFwidGVzdHVzZXJcIiBcImV4YW1wbGUuY29tXCIpKSBOSUwgTklMIE5JTCAiICsKKwkiXCI8NDBEOTg1MTIuOTA0MDgwM0BleGFtcGxlLmNvbT5cIikiOworCisgICAgcHVibGljIHN0YXRpYyBpbnRlcmZhY2UgSU1BUFRlc3QgeworCXB1YmxpYyB2b2lkIHRlc3QoRm9sZGVyIGZvbGRlciwgSU1BUEhhbmRsZXJGZXRjaCBoYW5kbGVyKQorCQkJCSAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdElOVEVSTkFMREFURUZldGNoKCkgeworCXRlc3RXaXRoSGFuZGxlcigKKwkgICAgbmV3IElNQVBUZXN0KCkgeworCQlAT3ZlcnJpZGUKKwkJcHVibGljIHZvaWQgdGVzdChGb2xkZXIgZm9sZGVyLCBJTUFQSGFuZGxlckZldGNoIGhhbmRsZXIpCisJCQkJICAgIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCQkgICAgRmV0Y2hQcm9maWxlIGZwID0gbmV3IEZldGNoUHJvZmlsZSgpOworCQkgICAgZnAuYWRkKElNQVBGb2xkZXIuRmV0Y2hQcm9maWxlSXRlbS5JTlRFUk5BTERBVEUpOworCQkgICAgTWVzc2FnZSBtID0gZm9sZGVyLmdldE1lc3NhZ2UoMSk7CisJCSAgICBmb2xkZXIuZmV0Y2gobmV3IE1lc3NhZ2VbXSB7IG0gfSwgZnApOworCQkgICAgYXNzZXJ0VHJ1ZShoYW5kbGVyLnNhdygiSU5URVJOQUxEQVRFIikpOworCQkgICAgaGFuZGxlci5yZXNldCgpOworCQkgICAgYXNzZXJ0VHJ1ZShtLmdldFJlY2VpdmVkRGF0ZSgpICE9IG51bGwpOworCQkgICAgYXNzZXJ0RmFsc2UoaGFuZGxlci5zYXcoIklOVEVSTkFMREFURSIpKTsKKwkJfQorCSAgICB9LAorCSAgICBuZXcgSU1BUEhhbmRsZXJGZXRjaCgpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIGZldGNoKFN0cmluZyBsaW5lKSB0aHJvd3MgSU9FeGNlcHRpb24geworCQkgICAgaWYgKGxpbmUuaW5kZXhPZigiSU5URVJOQUxEQVRFIikgPj0gMCkKKwkJCXNhdy5hZGQoIklOVEVSTkFMREFURSIpOworCQkgICAgdW50YWdnZWQoIjEgRkVUQ0ggKElOVEVSTkFMREFURSBcIiIgKyBSREFURSArICJcIikiKTsKKwkJICAgIG9rKCk7CisJCX0KKwkgICAgfSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SU5URVJOQUxEQVRFRmV0Y2hFbnZlbG9wZSgpIHsKKwl0ZXN0V2l0aEhhbmRsZXIoCisJICAgIG5ldyBJTUFQVGVzdCgpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIHRlc3QoRm9sZGVyIGZvbGRlciwgSU1BUEhhbmRsZXJGZXRjaCBoYW5kbGVyKQorCQkJCSAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwkJICAgIEZldGNoUHJvZmlsZSBmcCA9IG5ldyBGZXRjaFByb2ZpbGUoKTsKKwkJICAgIGZwLmFkZChGZXRjaFByb2ZpbGUuSXRlbS5FTlZFTE9QRSk7CisJCSAgICBNZXNzYWdlIG0gPSBmb2xkZXIuZ2V0TWVzc2FnZSgxKTsKKwkJICAgIGZvbGRlci5mZXRjaChuZXcgTWVzc2FnZVtdIHsgbSB9LCBmcCk7CisJCSAgICBhc3NlcnRUcnVlKGhhbmRsZXIuc2F3KCJJTlRFUk5BTERBVEUiKSk7CisJCSAgICBoYW5kbGVyLnJlc2V0KCk7CisJCSAgICBhc3NlcnRUcnVlKG0uZ2V0UmVjZWl2ZWREYXRlKCkgIT0gbnVsbCk7CisJCSAgICBhc3NlcnRGYWxzZShoYW5kbGVyLnNhdygiSU5URVJOQUxEQVRFIikpOworCQl9CisJICAgIH0sCisJICAgIG5ldyBJTUFQSGFuZGxlckZldGNoKCkgeworCQlAT3ZlcnJpZGUKKwkJcHVibGljIHZvaWQgZmV0Y2goU3RyaW5nIGxpbmUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJCSAgICBpZiAobGluZS5pbmRleE9mKCJJTlRFUk5BTERBVEUiKSA+PSAwKQorCQkJc2F3LmFkZCgiSU5URVJOQUxEQVRFIik7CisJCSAgICB1bnRhZ2dlZCgiMSBGRVRDSCAoSU5URVJOQUxEQVRFIFwiIiArIFJEQVRFICsgIlwiKSIpOworCQkgICAgb2soKTsKKwkJfQorCSAgICB9KTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RJTlRFUk5BTERBVEVOb0ZldGNoKCkgeworCXRlc3RXaXRoSGFuZGxlcigKKwkgICAgbmV3IElNQVBUZXN0KCkgeworCQlAT3ZlcnJpZGUKKwkJcHVibGljIHZvaWQgdGVzdChGb2xkZXIgZm9sZGVyLCBJTUFQSGFuZGxlckZldGNoIGhhbmRsZXIpCisJCQkJICAgIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCQkgICAgTWVzc2FnZSBtID0gZm9sZGVyLmdldE1lc3NhZ2UoMSk7CisJCSAgICBhc3NlcnRUcnVlKG0uZ2V0UmVjZWl2ZWREYXRlKCkgIT0gbnVsbCk7CisJCSAgICBhc3NlcnRUcnVlKGhhbmRsZXIuc2F3KCJJTlRFUk5BTERBVEUiKSk7CisJCX0KKwkgICAgfSwKKwkgICAgbmV3IElNQVBIYW5kbGVyRmV0Y2goKSB7CisJCUBPdmVycmlkZQorCQlwdWJsaWMgdm9pZCBmZXRjaChTdHJpbmcgbGluZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkJICAgIGlmIChsaW5lLmluZGV4T2YoIklOVEVSTkFMREFURSIpID49IDApCisJCQlzYXcuYWRkKCJJTlRFUk5BTERBVEUiKTsKKwkJICAgIHVudGFnZ2VkKCIxIEZFVENIIChFTlZFTE9QRSAiICsgRU5WRUxPUEUgKworCQkJIiBJTlRFUk5BTERBVEUgXCIiICsgUkRBVEUgKyAiXCIgUkZDODIyLlNJWkUgMCkiKTsKKwkJICAgIG9rKCk7CisJCX0KKwkgICAgfSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFdpdGhIYW5kbGVyKElNQVBUZXN0IHRlc3QsIElNQVBIYW5kbGVyRmV0Y2ggaGFuZGxlcikgeworICAgICAgICBUZXN0U2VydmVyIHNlcnZlciA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzZXJ2ZXIgPSBuZXcgVGVzdFNlcnZlcihoYW5kbGVyKTsKKyAgICAgICAgICAgIHNlcnZlci5zdGFydCgpOworCisgICAgICAgICAgICBmaW5hbCBQcm9wZXJ0aWVzIHByb3BlcnRpZXMgPSBuZXcgUHJvcGVydGllcygpOworICAgICAgICAgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5pbWFwLmhvc3QiLCAibG9jYWxob3N0Iik7CisgICAgICAgICAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLmltYXAucG9ydCIsICIiICsgc2VydmVyLmdldFBvcnQoKSk7CisgICAgICAgICAgICBmaW5hbCBTZXNzaW9uIHNlc3Npb24gPSBTZXNzaW9uLmdldEluc3RhbmNlKHByb3BlcnRpZXMpOworICAgICAgICAgICAgLy9zZXNzaW9uLnNldERlYnVnKHRydWUpOworCisgICAgICAgICAgICBmaW5hbCBTdG9yZSBzdG9yZSA9IHNlc3Npb24uZ2V0U3RvcmUoImltYXAiKTsKKwkgICAgRm9sZGVyIGZvbGRlciA9IG51bGw7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHN0b3JlLmNvbm5lY3QoInRlc3QiLCAidGVzdCIpOworICAgICAgICAgICAgICAgIGZvbGRlciA9IHN0b3JlLmdldEZvbGRlcigiSU5CT1giKTsKKyAgICAgICAgICAgICAgICBmb2xkZXIub3BlbihGb2xkZXIuUkVBRF9XUklURSk7CisJCXRlc3QudGVzdChmb2xkZXIsIGhhbmRsZXIpOworCSAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKwkJU3lzdGVtLm91dC5wcmludGxuKGV4KTsKKwkJLy9leC5wcmludFN0YWNrVHJhY2UoKTsKKwkJZmFpbChleC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisJCWlmIChmb2xkZXIgIT0gbnVsbCkKKwkJICAgIGZvbGRlci5jbG9zZShmYWxzZSk7CisgICAgICAgICAgICAgICAgc3RvcmUuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoZmluYWwgRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICBmYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChzZXJ2ZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHNlcnZlci5xdWl0KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDdXN0b20gaGFuZGxlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBJTUFQSGFuZGxlckZldGNoIGV4dGVuZHMgSU1BUEhhbmRsZXIgeworCS8vIG11c3QgYmUgc3RhdGljIGJlY2F1c2UgaGFuZGxlciBpcyBjbG9uZWQgZm9yIGVhY2ggY29ubmVjdGlvbgorCXByb3RlY3RlZCBzdGF0aWMgU2V0PFN0cmluZz4gc2F3ID0gbmV3IEhhc2hTZXQ8PigpOworCisJQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIHNlbGVjdChTdHJpbmcgbGluZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkgICAgbnVtYmVyT2ZNZXNzYWdlcyA9IDE7CisJICAgIHN1cGVyLnNlbGVjdChsaW5lKTsKKwl9CisKKwlwdWJsaWMgYm9vbGVhbiBzYXcoU3RyaW5nIGl0ZW0pIHsKKwkgICAgcmV0dXJuIHNhdy5jb250YWlucyhpdGVtKTsKKwl9CisKKwlwdWJsaWMgdm9pZCByZXNldCgpIHsKKwkgICAgc2F3LmNsZWFyKCk7CisJfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9JTUFQRm9sZGVyVGVzdC5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0lNQVBGb2xkZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGYyYzljNQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9JTUFQRm9sZGVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsNTI3IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDA5LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5pbWFwOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKK2ltcG9ydCBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyOworCitpbXBvcnQgamF2YXgubWFpbC5Gb2xkZXI7CitpbXBvcnQgamF2YXgubWFpbC5TZXNzaW9uOworaW1wb3J0IGphdmF4Lm1haWwuU3RvcmU7CitpbXBvcnQgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YXgubWFpbC5VSURGb2xkZXI7CisKK2ltcG9ydCBjb20uc3VuLm1haWwudGVzdC5UZXN0U2VydmVyOworCitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LlJ1bGU7CitpbXBvcnQgb3JnLmp1bml0LnJ1bGVzLlRpbWVvdXQ7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RXF1YWxzOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydFRydWU7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RmFsc2U7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuZmFpbDsKKworLyoqCisgKiBUZXN0IElNQVBGb2xkZXIgbWV0aG9kcy4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIElNQVBGb2xkZXJUZXN0IHsKKworICAgIC8vIHRpbWVvdXQgdGhlIHRlc3QgaW4gY2FzZSBvZiBkZWFkbG9jaworICAgIEBSdWxlCisgICAgcHVibGljIFRpbWVvdXQgZGVhZGxvY2tUaW1lb3V0ID0gVGltZW91dC5zZWNvbmRzKDIwKTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyB1dGY4Rm9sZGVyID0gInRlc3RcdTAzYjEiOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyB1dGY3Rm9sZGVyID0gInRlc3QmQTdFLSI7CisKKyAgICBwdWJsaWMgc3RhdGljIGFic3RyYWN0IGNsYXNzIElNQVBUZXN0IHsKKwlwdWJsaWMgdm9pZCBpbml0KFByb3BlcnRpZXMgcHJvcHMpIHsgfTsKKwlwdWJsaWMgYWJzdHJhY3Qgdm9pZCB0ZXN0KFN0b3JlIHN0b3JlLCBJTUFQSGFuZGxlciBoYW5kbGVyKQorCQkJCSAgICB0aHJvd3MgRXhjZXB0aW9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCB1c2luZyBhIFVURi04IGZvbGRlciBuYW1lIHJlc3VsdHMgaW4gdGhlIHByb3BlciBVVEYtNworICAgICAqIGVuY29kZWQgbmFtZSBmb3IgdGhlIENSRUFURSBjb21tYW5kLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFV0ZjdGb2xkZXJOYW1lQ3JlYXRlKCkgeworCXRlc3RXaXRoSGFuZGxlcigKKwkgICAgbmV3IElNQVBUZXN0KCkgeworCQlAT3ZlcnJpZGUKKwkJcHVibGljIHZvaWQgdGVzdChTdG9yZSBzdG9yZSwgSU1BUEhhbmRsZXIgaGFuZGxlcikKKwkJCQkgICAgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworCQkgICAgRm9sZGVyIHRlc3QgPSBzdG9yZS5nZXRGb2xkZXIodXRmOEZvbGRlcik7CisJCSAgICBhc3NlcnRUcnVlKHRlc3QuY3JlYXRlKEZvbGRlci5IT0xEU19NRVNTQUdFUykpOworCQl9CisJICAgIH0sCisJICAgIG5ldyBJTUFQSGFuZGxlcigpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIGNyZWF0ZShTdHJpbmcgbGluZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkJICAgIFN0cmluZ1Rva2VuaXplciBzdCA9IG5ldyBTdHJpbmdUb2tlbml6ZXIobGluZSk7CisJCSAgICBzdC5uZXh0VG9rZW4oKTsJLy8gc2tpcCB0YWcKKwkJICAgIHN0Lm5leHRUb2tlbigpOwkvLyBza2lwICJDUkVBVEUiCisJCSAgICBTdHJpbmcgbmFtZSA9IHN0Lm5leHRUb2tlbigpOworCQkgICAgaWYgKG5hbWUuZXF1YWxzKHV0ZjdGb2xkZXIpKQorCQkJb2soKTsKKwkJICAgIGVsc2UKKwkJCW5vKCJ3cm9uZyBuYW1lIik7CisJCX0KKworCQlAT3ZlcnJpZGUKKwkJcHVibGljIHZvaWQgbGlzdChTdHJpbmcgbGluZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkJICAgIHVudGFnZ2VkKCJMSVNUIChcXEhhc05vQ2hpbGRyZW4pIFwiL1wiICIgKyB1dGY3Rm9sZGVyKTsKKwkJICAgIG9rKCk7CisJCX0KKwkgICAgfSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IHVzaW5nIGEgVVRGLTggZm9sZGVyIG5hbWUgcmVzdWx0cyBpbiB0aGUgcHJvcGVyIFVURi04CisgICAgICogdW5lbmNvZGVkIG5hbWUgZm9yIHRoZSBDUkVBVEUgY29tbWFuZC4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RVdGY4Rm9sZGVyTmFtZUNyZWF0ZSgpIHsKKwl0ZXN0V2l0aEhhbmRsZXIoCisJICAgIG5ldyBJTUFQVGVzdCgpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIHRlc3QoU3RvcmUgc3RvcmUsIElNQVBIYW5kbGVyIGhhbmRsZXIpCisJCQkJICAgIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKwkJICAgIEZvbGRlciB0ZXN0ID0gc3RvcmUuZ2V0Rm9sZGVyKHV0ZjhGb2xkZXIpOworCQkgICAgYXNzZXJ0VHJ1ZSh0ZXN0LmNyZWF0ZShGb2xkZXIuSE9MRFNfTUVTU0FHRVMpKTsKKwkJfQorCSAgICB9LAorCSAgICBuZXcgSU1BUFV0ZjhIYW5kbGVyKCkgeworCQlAT3ZlcnJpZGUKKwkJcHVibGljIHZvaWQgY3JlYXRlKFN0cmluZyBsaW5lKSB0aHJvd3MgSU9FeGNlcHRpb24geworCQkgICAgU3RyaW5nVG9rZW5pemVyIHN0ID0gbmV3IFN0cmluZ1Rva2VuaXplcihsaW5lKTsKKwkJICAgIHN0Lm5leHRUb2tlbigpOwkvLyBza2lwIHRhZworCQkgICAgc3QubmV4dFRva2VuKCk7CS8vIHNraXAgIkNSRUFURSIKKwkJICAgIFN0cmluZyBuYW1lID0gdW5xdW90ZShzdC5uZXh0VG9rZW4oKSk7CisJCSAgICBpZiAobmFtZS5lcXVhbHModXRmOEZvbGRlcikpCisJCQlvaygpOworCQkgICAgZWxzZQorCQkJbm8oIndyb25nIG5hbWUiKTsKKwkJfQorCisJCUBPdmVycmlkZQorCQlwdWJsaWMgdm9pZCBsaXN0KFN0cmluZyBsaW5lKSB0aHJvd3MgSU9FeGNlcHRpb24geworCQkgICAgdW50YWdnZWQoIkxJU1QgKFxcSGFzTm9DaGlsZHJlbikgXCIvXCIgXCIiICsKKwkJCQkJCQl1dGY4Rm9sZGVyICsgIlwiIik7CisJCSAgICBvaygpOworCQl9CisJICAgIH0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCB1c2luZyBhIFVURi04IGZvbGRlciBuYW1lIHJlc3VsdHMgaW4gdGhlIHByb3BlciBVVEYtNworICAgICAqIGVuY29kZWQgbmFtZSBmb3IgdGhlIERFTEVURSBjb21tYW5kLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFV0ZjdGb2xkZXJOYW1lRGVsZXRlKCkgeworCXRlc3RXaXRoSGFuZGxlcigKKwkgICAgbmV3IElNQVBUZXN0KCkgeworCQlAT3ZlcnJpZGUKKwkJcHVibGljIHZvaWQgdGVzdChTdG9yZSBzdG9yZSwgSU1BUEhhbmRsZXIgaGFuZGxlcikKKwkJCQkgICAgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworCQkgICAgRm9sZGVyIHRlc3QgPSBzdG9yZS5nZXRGb2xkZXIodXRmOEZvbGRlcik7CisJCSAgICBhc3NlcnRUcnVlKHRlc3QuZGVsZXRlKGZhbHNlKSk7CisJCX0KKwkgICAgfSwKKwkgICAgbmV3IElNQVBIYW5kbGVyKCkgeworCQlAT3ZlcnJpZGUKKwkJcHVibGljIHZvaWQgZGVsZXRlKFN0cmluZyBsaW5lKSB0aHJvd3MgSU9FeGNlcHRpb24geworCQkgICAgU3RyaW5nVG9rZW5pemVyIHN0ID0gbmV3IFN0cmluZ1Rva2VuaXplcihsaW5lKTsKKwkJICAgIHN0Lm5leHRUb2tlbigpOwkvLyBza2lwIHRhZworCQkgICAgc3QubmV4dFRva2VuKCk7CS8vIHNraXAgIkRFTEVURSIKKwkJICAgIFN0cmluZyBuYW1lID0gc3QubmV4dFRva2VuKCk7CisJCSAgICBpZiAobmFtZS5lcXVhbHModXRmN0ZvbGRlcikpCisJCQlvaygpOworCQkgICAgZWxzZQorCQkJbm8oIndyb25nIG5hbWUiKTsKKwkJfQorCSAgICB9KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHRoYXQgdXNpbmcgYSBVVEYtOCBmb2xkZXIgbmFtZSByZXN1bHRzIGluIHRoZSBwcm9wZXIgVVRGLTgKKyAgICAgKiB1bmVuY29kZWQgbmFtZSBmb3IgdGhlIERFTEVURSBjb21tYW5kLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFV0ZjhGb2xkZXJOYW1lRGVsZXRlKCkgeworCXRlc3RXaXRoSGFuZGxlcigKKwkgICAgbmV3IElNQVBUZXN0KCkgeworCQlAT3ZlcnJpZGUKKwkJcHVibGljIHZvaWQgdGVzdChTdG9yZSBzdG9yZSwgSU1BUEhhbmRsZXIgaGFuZGxlcikKKwkJCQkgICAgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworCQkgICAgRm9sZGVyIHRlc3QgPSBzdG9yZS5nZXRGb2xkZXIodXRmOEZvbGRlcik7CisJCSAgICBhc3NlcnRUcnVlKHRlc3QuZGVsZXRlKGZhbHNlKSk7CisJCX0KKwkgICAgfSwKKwkgICAgbmV3IElNQVBVdGY4SGFuZGxlcigpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIGRlbGV0ZShTdHJpbmcgbGluZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkJICAgIFN0cmluZ1Rva2VuaXplciBzdCA9IG5ldyBTdHJpbmdUb2tlbml6ZXIobGluZSk7CisJCSAgICBzdC5uZXh0VG9rZW4oKTsJLy8gc2tpcCB0YWcKKwkJICAgIHN0Lm5leHRUb2tlbigpOwkvLyBza2lwICJERUxFVEUiCisJCSAgICBTdHJpbmcgbmFtZSA9IHVucXVvdGUoc3QubmV4dFRva2VuKCkpOworCQkgICAgaWYgKG5hbWUuZXF1YWxzKHV0ZjhGb2xkZXIpKQorCQkJb2soKTsKKwkJICAgIGVsc2UKKwkJCW5vKCJ3cm9uZyBuYW1lIik7CisJCX0KKwkgICAgfSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IHVzaW5nIGEgVVRGLTggZm9sZGVyIG5hbWUgcmVzdWx0cyBpbiB0aGUgcHJvcGVyIFVURi03CisgICAgICogZW5jb2RlZCBuYW1lIGZvciB0aGUgU0VMRUNUIGNvbW1hbmQuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXRmN0ZvbGRlck5hbWVTZWxlY3QoKSB7CisJdGVzdFdpdGhIYW5kbGVyKAorCSAgICBuZXcgSU1BUFRlc3QoKSB7CisJCUBPdmVycmlkZQorCQlwdWJsaWMgdm9pZCB0ZXN0KFN0b3JlIHN0b3JlLCBJTUFQSGFuZGxlciBoYW5kbGVyKQorCQkJCSAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisJCSAgICBGb2xkZXIgdGVzdCA9IHN0b3JlLmdldEZvbGRlcih1dGY4Rm9sZGVyKTsKKwkJICAgIHRlc3Qub3BlbihGb2xkZXIuUkVBRF9XUklURSk7CisJCSAgICB0ZXN0LmNsb3NlKHRydWUpOworCQkgICAgLy8gbm8gZXhjZXB0aW9uIG1lYW5zIHN1Y2Nlc3MKKwkJfQorCSAgICB9LAorCSAgICBuZXcgSU1BUEhhbmRsZXIoKSB7CisJCUBPdmVycmlkZQorCQlwdWJsaWMgdm9pZCBzZWxlY3QoU3RyaW5nIGxpbmUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJCSAgICBTdHJpbmdUb2tlbml6ZXIgc3QgPSBuZXcgU3RyaW5nVG9rZW5pemVyKGxpbmUpOworCQkgICAgc3QubmV4dFRva2VuKCk7CS8vIHNraXAgdGFnCisJCSAgICBzdC5uZXh0VG9rZW4oKTsJLy8gc2tpcCAiU0VMRUNUIgorCQkgICAgU3RyaW5nIG5hbWUgPSBzdC5uZXh0VG9rZW4oKTsKKwkJICAgIGlmIChuYW1lLmVxdWFscyh1dGY3Rm9sZGVyKSkKKwkJCW9rKCk7CisJCSAgICBlbHNlCisJCQlubygid3JvbmcgbmFtZSIpOworCQl9CisJICAgIH0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCB1c2luZyBhIFVURi04IGZvbGRlciBuYW1lIHJlc3VsdHMgaW4gdGhlIHByb3BlciBVVEYtOAorICAgICAqIHVuZW5jb2RlZCBuYW1lIGZvciB0aGUgU0VMRUNUIGNvbW1hbmQuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXRmOEZvbGRlck5hbWVTZWxlY3QoKSB7CisJdGVzdFdpdGhIYW5kbGVyKAorCSAgICBuZXcgSU1BUFRlc3QoKSB7CisJCUBPdmVycmlkZQorCQlwdWJsaWMgdm9pZCB0ZXN0KFN0b3JlIHN0b3JlLCBJTUFQSGFuZGxlciBoYW5kbGVyKQorCQkJCSAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisJCSAgICBGb2xkZXIgdGVzdCA9IHN0b3JlLmdldEZvbGRlcih1dGY4Rm9sZGVyKTsKKwkJICAgIHRlc3Qub3BlbihGb2xkZXIuUkVBRF9XUklURSk7CisJCSAgICB0ZXN0LmNsb3NlKHRydWUpOworCQkgICAgLy8gbm8gZXhjZXB0aW9uIG1lYW5zIHN1Y2Nlc3MKKwkJfQorCSAgICB9LAorCSAgICBuZXcgSU1BUFV0ZjhIYW5kbGVyKCkgeworCQlAT3ZlcnJpZGUKKwkJcHVibGljIHZvaWQgc2VsZWN0KFN0cmluZyBsaW5lKSB0aHJvd3MgSU9FeGNlcHRpb24geworCQkgICAgU3RyaW5nVG9rZW5pemVyIHN0ID0gbmV3IFN0cmluZ1Rva2VuaXplcihsaW5lKTsKKwkJICAgIHN0Lm5leHRUb2tlbigpOwkvLyBza2lwIHRhZworCQkgICAgc3QubmV4dFRva2VuKCk7CS8vIHNraXAgIlNFTEVDVCIKKwkJICAgIFN0cmluZyBuYW1lID0gdW5xdW90ZShzdC5uZXh0VG9rZW4oKSk7CisJCSAgICBpZiAobmFtZS5lcXVhbHModXRmOEZvbGRlcikpCisJCQlvaygpOworCQkgICAgZWxzZQorCQkJbm8oIndyb25nIG5hbWUiKTsKKwkJfQorCSAgICB9KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHRoYXQgdXNpbmcgYSBVVEYtOCBmb2xkZXIgbmFtZSByZXN1bHRzIGluIHRoZSBwcm9wZXIgVVRGLTcKKyAgICAgKiBlbmNvZGVkIG5hbWUgZm9yIHRoZSBFWEFNSU5FIGNvbW1hbmQuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXRmN0ZvbGRlck5hbWVFeGFtaW5lKCkgeworCXRlc3RXaXRoSGFuZGxlcigKKwkgICAgbmV3IElNQVBUZXN0KCkgeworCQlAT3ZlcnJpZGUKKwkJcHVibGljIHZvaWQgdGVzdChTdG9yZSBzdG9yZSwgSU1BUEhhbmRsZXIgaGFuZGxlcikKKwkJCQkgICAgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworCQkgICAgRm9sZGVyIHRlc3QgPSBzdG9yZS5nZXRGb2xkZXIodXRmOEZvbGRlcik7CisJCSAgICB0ZXN0Lm9wZW4oRm9sZGVyLlJFQURfT05MWSk7CisJCSAgICB0ZXN0LmNsb3NlKHRydWUpOworCQkgICAgLy8gbm8gZXhjZXB0aW9uIG1lYW5zIHN1Y2Nlc3MKKwkJfQorCSAgICB9LAorCSAgICBuZXcgSU1BUEhhbmRsZXIoKSB7CisJCUBPdmVycmlkZQorCQlwdWJsaWMgdm9pZCBleGFtaW5lKFN0cmluZyBsaW5lKSB0aHJvd3MgSU9FeGNlcHRpb24geworCQkgICAgU3RyaW5nVG9rZW5pemVyIHN0ID0gbmV3IFN0cmluZ1Rva2VuaXplcihsaW5lKTsKKwkJICAgIHN0Lm5leHRUb2tlbigpOwkvLyBza2lwIHRhZworCQkgICAgc3QubmV4dFRva2VuKCk7CS8vIHNraXAgIkVYQU1JTkUiCisJCSAgICBTdHJpbmcgbmFtZSA9IHN0Lm5leHRUb2tlbigpOworCQkgICAgaWYgKG5hbWUuZXF1YWxzKHV0ZjdGb2xkZXIpKQorCQkJb2soKTsKKwkJICAgIGVsc2UKKwkJCW5vKCJ3cm9uZyBuYW1lIik7CisJCX0KKwkgICAgfSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IHVzaW5nIGEgVVRGLTggZm9sZGVyIG5hbWUgcmVzdWx0cyBpbiB0aGUgcHJvcGVyIFVURi04CisgICAgICogdW5lbmNvZGVkIG5hbWUgZm9yIHRoZSBFWEFNSU5FIGNvbW1hbmQuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXRmOEZvbGRlck5hbWVFeGFtaW5lKCkgeworCXRlc3RXaXRoSGFuZGxlcigKKwkgICAgbmV3IElNQVBUZXN0KCkgeworCQlAT3ZlcnJpZGUKKwkJcHVibGljIHZvaWQgdGVzdChTdG9yZSBzdG9yZSwgSU1BUEhhbmRsZXIgaGFuZGxlcikKKwkJCQkgICAgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworCQkgICAgRm9sZGVyIHRlc3QgPSBzdG9yZS5nZXRGb2xkZXIodXRmOEZvbGRlcik7CisJCSAgICB0ZXN0Lm9wZW4oRm9sZGVyLlJFQURfT05MWSk7CisJCSAgICB0ZXN0LmNsb3NlKHRydWUpOworCQkgICAgLy8gbm8gZXhjZXB0aW9uIG1lYW5zIHN1Y2Nlc3MKKwkJfQorCSAgICB9LAorCSAgICBuZXcgSU1BUFV0ZjhIYW5kbGVyKCkgeworCQlAT3ZlcnJpZGUKKwkJcHVibGljIHZvaWQgZXhhbWluZShTdHJpbmcgbGluZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkJICAgIFN0cmluZ1Rva2VuaXplciBzdCA9IG5ldyBTdHJpbmdUb2tlbml6ZXIobGluZSk7CisJCSAgICBzdC5uZXh0VG9rZW4oKTsJLy8gc2tpcCB0YWcKKwkJICAgIHN0Lm5leHRUb2tlbigpOwkvLyBza2lwICJFWEFNSU5FIgorCQkgICAgU3RyaW5nIG5hbWUgPSB1bnF1b3RlKHN0Lm5leHRUb2tlbigpKTsKKwkJICAgIGlmIChuYW1lLmVxdWFscyh1dGY4Rm9sZGVyKSkKKwkJCW9rKCk7CisJCSAgICBlbHNlCisJCQlubygid3JvbmcgbmFtZSIpOworCQl9CisJICAgIH0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCB1c2luZyBhIFVURi04IGZvbGRlciBuYW1lIHJlc3VsdHMgaW4gdGhlIHByb3BlciBVVEYtNworICAgICAqIGVuY29kZWQgbmFtZSBmb3IgdGhlIFNUQVRVUyBjb21tYW5kLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFV0ZjdGb2xkZXJOYW1lU3RhdHVzKCkgeworCXRlc3RXaXRoSGFuZGxlcigKKwkgICAgbmV3IElNQVBUZXN0KCkgeworCQlAT3ZlcnJpZGUKKwkJcHVibGljIHZvaWQgdGVzdChTdG9yZSBzdG9yZSwgSU1BUEhhbmRsZXIgaGFuZGxlcikKKwkJCQkgICAgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworCQkgICAgRm9sZGVyIHRlc3QgPSBzdG9yZS5nZXRGb2xkZXIodXRmOEZvbGRlcik7CisJCSAgICBhc3NlcnRFcXVhbHMoMTIzLCAoKFVJREZvbGRlcil0ZXN0KS5nZXRVSURWYWxpZGl0eSgpKTsKKwkJfQorCSAgICB9LAorCSAgICBuZXcgSU1BUEhhbmRsZXIoKSB7CisJCUBPdmVycmlkZQorCQlwdWJsaWMgdm9pZCBzdGF0dXMoU3RyaW5nIGxpbmUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJCSAgICBTdHJpbmdUb2tlbml6ZXIgc3QgPSBuZXcgU3RyaW5nVG9rZW5pemVyKGxpbmUpOworCQkgICAgc3QubmV4dFRva2VuKCk7CS8vIHNraXAgdGFnCisJCSAgICBzdC5uZXh0VG9rZW4oKTsJLy8gc2tpcCAiU1RBVFVTIgorCQkgICAgU3RyaW5nIG5hbWUgPSBzdC5uZXh0VG9rZW4oKTsKKwkJICAgIGlmIChuYW1lLmVxdWFscyh1dGY3Rm9sZGVyKSkgeworCQkJdW50YWdnZWQoIlNUQVRVUyAiICsgdXRmN0ZvbGRlciArCisJCQkJICAgICIgKFVJRFZBTElESVRZIDEyMykiKTsKKwkJCW9rKCk7CisJCSAgICB9IGVsc2UKKwkJCW5vKCJ3cm9uZyBuYW1lIik7CisJCX0KKwkgICAgfSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IHVzaW5nIGEgVVRGLTggZm9sZGVyIG5hbWUgcmVzdWx0cyBpbiB0aGUgcHJvcGVyIFVURi04CisgICAgICogdW5lbmNvZGVkIG5hbWUgZm9yIHRoZSBTVEFUVVMgY29tbWFuZC4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RVdGY4Rm9sZGVyTmFtZVN0YXR1cygpIHsKKwl0ZXN0V2l0aEhhbmRsZXIoCisJICAgIG5ldyBJTUFQVGVzdCgpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIHRlc3QoU3RvcmUgc3RvcmUsIElNQVBIYW5kbGVyIGhhbmRsZXIpCisJCQkJICAgIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKwkJICAgIEZvbGRlciB0ZXN0ID0gc3RvcmUuZ2V0Rm9sZGVyKHV0ZjhGb2xkZXIpOworCQkgICAgYXNzZXJ0RXF1YWxzKDEyMywgKChVSURGb2xkZXIpdGVzdCkuZ2V0VUlEVmFsaWRpdHkoKSk7CisJCX0KKwkgICAgfSwKKwkgICAgbmV3IElNQVBVdGY4SGFuZGxlcigpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIHN0YXR1cyhTdHJpbmcgbGluZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkJICAgIFN0cmluZ1Rva2VuaXplciBzdCA9IG5ldyBTdHJpbmdUb2tlbml6ZXIobGluZSk7CisJCSAgICBzdC5uZXh0VG9rZW4oKTsJLy8gc2tpcCB0YWcKKwkJICAgIHN0Lm5leHRUb2tlbigpOwkvLyBza2lwICJTVEFUVVMiCisJCSAgICBTdHJpbmcgbmFtZSA9IHVucXVvdGUoc3QubmV4dFRva2VuKCkpOworCQkgICAgaWYgKG5hbWUuZXF1YWxzKHV0ZjhGb2xkZXIpKSB7CisJCQl1bnRhZ2dlZCgiU1RBVFVTIFwiIiArIHV0ZjhGb2xkZXIgKworCQkJCSAgICAiXCIgKFVJRFZBTElESVRZIDEyMykiKTsKKwkJCW9rKCk7CisJCSAgICB9IGVsc2UKKwkJCW5vKCJ3cm9uZyBuYW1lIik7CisJCX0KKwkgICAgfSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IFVJRE5PVFNUSUNLWSBpcyBmYWxzZSBpbiB0aGUgZm9ybWFsIGNhc2UuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VWlkTm90U3RpY2t5RmFsc2UoKSB7CisJdGVzdFdpdGhIYW5kbGVyKAorCSAgICBuZXcgSU1BUFRlc3QoKSB7CisJCUBPdmVycmlkZQorCQlwdWJsaWMgdm9pZCB0ZXN0KFN0b3JlIHN0b3JlLCBJTUFQSGFuZGxlciBoYW5kbGVyKQorCQkJCSAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisJCSAgICBGb2xkZXIgdGVzdCA9IHN0b3JlLmdldEZvbGRlcigidGVzdCIpOworCQkgICAgdHJ5IHsKKwkJCXRlc3Qub3BlbihGb2xkZXIuUkVBRF9XUklURSk7CisJCQlhc3NlcnRGYWxzZSgoKElNQVBGb2xkZXIpdGVzdCkuZ2V0VUlETm90U3RpY2t5KCkpOworCQkgICAgfSBmaW5hbGx5IHsKKwkJCXRlc3QuY2xvc2UoKTsKKwkJICAgIH0KKwkJfQorCSAgICB9LAorCSAgICBuZXcgSU1BUEhhbmRsZXIoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IFVJRE5PVFNUSUNLWSBpcyB0cnVlIHdoZW4gdGhlIHVudGFnZ2VkIHJlc3BvbnNlIGlzIGluY2x1ZGVkLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFVpZE5vdFN0aWNreVRydWUoKSB7CisJdGVzdFdpdGhIYW5kbGVyKAorCSAgICBuZXcgSU1BUFRlc3QoKSB7CisJCUBPdmVycmlkZQorCQlwdWJsaWMgdm9pZCB0ZXN0KFN0b3JlIHN0b3JlLCBJTUFQSGFuZGxlciBoYW5kbGVyKQorCQkJCSAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisJCSAgICBGb2xkZXIgdGVzdCA9IHN0b3JlLmdldEZvbGRlcigidGVzdCIpOworCQkgICAgdHJ5IHsKKwkJCXRlc3Qub3BlbihGb2xkZXIuUkVBRF9XUklURSk7CisJCQlhc3NlcnRUcnVlKCgoSU1BUEZvbGRlcil0ZXN0KS5nZXRVSUROb3RTdGlja3koKSk7CisJCSAgICB9IGZpbmFsbHkgeworCQkJdGVzdC5jbG9zZSgpOworCQkgICAgfQorCQl9CisJICAgIH0sCisJICAgIG5ldyBJTUFQSGFuZGxlcigpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIHNlbGVjdChTdHJpbmcgbGluZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkJICAgIHVudGFnZ2VkKCJOTyBbVUlETk9UU1RJQ0tZXSIpOworCQkgICAgc3VwZXIuc2VsZWN0KGxpbmUpOworCQl9CisJICAgIH0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCBFWFBVTkdFIHJlc3BvbnNlcyB3aXRoIG91dC1vZi1yYW5nZSBtZXNzYWdlIG51bWJlcnMKKyAgICAgKiBhcmUgaWdub3JlZC4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RFeHB1bmdlT3V0T2ZSYW5nZSgpIHsKKwl0ZXN0V2l0aEhhbmRsZXIoCisJICAgIG5ldyBJTUFQVGVzdCgpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIHRlc3QoU3RvcmUgc3RvcmUsIElNQVBIYW5kbGVyIGhhbmRsZXIpCisJCQkJICAgIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKwkJICAgIEZvbGRlciB0ZXN0ID0gc3RvcmUuZ2V0Rm9sZGVyKCJ0ZXN0Iik7CisJCSAgICB0cnkgeworCQkJdGVzdC5vcGVuKEZvbGRlci5SRUFEX1dSSVRFKTsKKwkJCS8vIG5vIHdheSB0byBmb3JjZSBhIG5vb3Agd2l0aG91dCB3YWl0aW5nIHNvIGRvIHRoaXMKKwkJCWFzc2VydEVxdWFscygwLCB0ZXN0LmdldFVucmVhZE1lc3NhZ2VDb3VudCgpKTsKKwkJCWFzc2VydEVxdWFscygwLCB0ZXN0LmdldE1lc3NhZ2VDb3VudCgpKTsKKwkJICAgIH0gZmluYWxseSB7CisJCQl0ZXN0LmNsb3NlKCk7CisJCSAgICB9CisJCX0KKwkgICAgfSwKKwkgICAgbmV3IElNQVBIYW5kbGVyKCkgeworCQlAT3ZlcnJpZGUKKwkJcHVibGljIHZvaWQgc2VhcmNoKFN0cmluZyBsaW5lKSB0aHJvd3MgSU9FeGNlcHRpb24geworCQkgICAgdW50YWdnZWQoIjEgRVhQVU5HRSIpOworCQkgICAgdW50YWdnZWQoIjAgRVhJU1RTIik7CisJCSAgICBzdXBlci5zZWFyY2gobGluZSk7CisJCX0KKwkgICAgfSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RXaXRoSGFuZGxlcihJTUFQVGVzdCB0ZXN0LCBJTUFQSGFuZGxlciBoYW5kbGVyKSB7CisgICAgICAgIFRlc3RTZXJ2ZXIgc2VydmVyID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNlcnZlciA9IG5ldyBUZXN0U2VydmVyKGhhbmRsZXIpOworICAgICAgICAgICAgc2VydmVyLnN0YXJ0KCk7CisKKyAgICAgICAgICAgIGZpbmFsIFByb3BlcnRpZXMgcHJvcGVydGllcyA9IG5ldyBQcm9wZXJ0aWVzKCk7CisgICAgICAgICAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLmltYXAuaG9zdCIsICJsb2NhbGhvc3QiKTsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuaW1hcC5wb3J0IiwgIiIgKyBzZXJ2ZXIuZ2V0UG9ydCgpKTsKKwkgICAgdGVzdC5pbml0KHByb3BlcnRpZXMpOworICAgICAgICAgICAgZmluYWwgU2Vzc2lvbiBzZXNzaW9uID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShwcm9wZXJ0aWVzKTsKKyAgICAgICAgICAgIC8vc2Vzc2lvbi5zZXREZWJ1Zyh0cnVlKTsKKworICAgICAgICAgICAgZmluYWwgU3RvcmUgc3RvcmUgPSBzZXNzaW9uLmdldFN0b3JlKCJpbWFwIik7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHN0b3JlLmNvbm5lY3QoInRlc3QiLCAidGVzdCIpOworCQl0ZXN0LnRlc3Qoc3RvcmUsIGhhbmRsZXIpOworCSAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKwkJU3lzdGVtLm91dC5wcmludGxuKGV4KTsKKwkJLy9leC5wcmludFN0YWNrVHJhY2UoKTsKKwkJZmFpbChleC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgc3RvcmUuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoZmluYWwgRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICBmYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChzZXJ2ZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHNlcnZlci5xdWl0KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgdW5xdW90ZShTdHJpbmcgcykgeworCWlmIChzLnN0YXJ0c1dpdGgoIlwiIikgJiYgcy5lbmRzV2l0aCgiXCIiKSAmJiBzLmxlbmd0aCgpID4gMSkgeworCSAgICBzID0gcy5zdWJzdHJpbmcoMSwgcy5sZW5ndGgoKSAtIDEpOworCSAgICAvLyBjaGVjayBmb3IgYW55IGVzY2FwZWQgY2hhcmFjdGVycworCSAgICBpZiAocy5pbmRleE9mKCdcXCcpID49IDApIHsKKwkJU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKHMubGVuZ3RoKCkpOwkvLyBhcHByb3gKKwkJZm9yIChpbnQgaSA9IDA7IGkgPCBzLmxlbmd0aCgpOyBpKyspIHsKKwkJICAgIGNoYXIgYyA9IHMuY2hhckF0KGkpOworCQkgICAgaWYgKGMgPT0gJ1xcJyAmJiBpIDwgcy5sZW5ndGgoKSAtIDEpCisJCQljID0gcy5jaGFyQXQoKytpKTsKKwkJICAgIHNiLmFwcGVuZChjKTsKKwkJfQorCQlzID0gc2IudG9TdHJpbmcoKTsKKwkgICAgfQorCX0KKwlyZXR1cm4gczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBbiBJTUFQSGFuZGxlciB0aGF0IGVuYWJsZXMgVVRGLTggc3VwcG9ydC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBJTUFQVXRmOEhhbmRsZXIgZXh0ZW5kcyBJTUFQSGFuZGxlciB7CisJe3sgY2FwYWJpbGl0aWVzICs9ICIgRU5BQkxFIFVURjg9QUNDRVBUIjsgfX0KKworCUBPdmVycmlkZQorCXB1YmxpYyB2b2lkIGVuYWJsZShTdHJpbmcgbGluZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkgICAgb2soKTsKKwl9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0lNQVBIYW5kbGVyLmphdmEgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL2ltYXAvSU1BUEhhbmRsZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZWJlNGQzCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0lNQVBIYW5kbGVyLmphdmEKQEAgLTAsMCArMSw1ODYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDksIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmltYXA7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uUmVhZGVyOworaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7CitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTGV2ZWw7CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5TdGFuZGFyZENoYXJzZXRzOworCitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuQkFTRTY0RW5jb2RlclN0cmVhbTsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC50ZXN0LlByb3RvY29sSGFuZGxlcjsKKworLyoqCisgKiBIYW5kbGUgSU1BUCBjb25uZWN0aW9uLgorICoKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKi8KK3B1YmxpYyBjbGFzcyBJTUFQSGFuZGxlciBleHRlbmRzIFByb3RvY29sSGFuZGxlciB7CisKKyAgICAvKiogQ3VycmVudCBsaW5lLiAqLworICAgIHByaXZhdGUgU3RyaW5nIGN1cnJlbnRMaW5lOworCisgICAgLyoqIFRhZyBmb3IgY3VycmVudCBjb21tYW5kICovCisgICAgcHJvdGVjdGVkIFN0cmluZyB0YWc7CisKKyAgICAvKiogSU1BUCBjYXBhYmlsaXRpZXMgc3VwcG9ydGVkICovCisgICAgcHJvdGVjdGVkIFN0cmluZyBjYXBhYmlsaXRpZXMgPSAiSU1BUDRSRVYxIElETEUgSUQiOworCisgICAgLyoqIE51bWJlciBvZiBtZXNzYWdlcyAqLworICAgIHByb3RlY3RlZCBpbnQgbnVtYmVyT2ZNZXNzYWdlcyA9IDA7CisKKyAgICAvKiogTnVtYmVyIG9mIHJlY2VudCBtZXNzYWdlcyAqLworICAgIHByb3RlY3RlZCBpbnQgbnVtYmVyT2ZSZWNlbnRNZXNzYWdlcyA9IDA7CisKKyAgICAvKioKKyAgICAgKiBTZW5kIGdyZWV0aW5ncy4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gdW5hYmxlIHRvIHdyaXRlIHRvIHNvY2tldAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNlbmRHcmVldGluZ3MoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB1bnRhZ2dlZCgiT0sgW0NBUEFCSUxJVFkgIiArIGNhcGFiaWxpdGllcyArICJdIElNQVBIYW5kbGVyIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VuZCBTdHJpbmcgdG8gc29ja2V0LgorICAgICAqCisgICAgICogQHBhcmFtIHN0ciBTdHJpbmcgdG8gc2VuZAorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gdW5hYmxlIHRvIHdyaXRlIHRvIHNvY2tldAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHByaW50bG4oZmluYWwgU3RyaW5nIHN0cikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgd3JpdGVyLnByaW50KHN0cik7CisJd3JpdGVyLnByaW50KCJcclxuIik7CisgICAgICAgIHdyaXRlci5mbHVzaCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNlbmQgYSB0YWdnZWQgcmVzcG9uc2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVzcCB0aGUgcmVzcG9uc2UgdG8gc2VuZAorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gdW5hYmxlIHRvIHJlYWQvd3JpdGUgdG8gc29ja2V0CisgICAgICovCisgICAgcHVibGljIHZvaWQgdGFnZ2VkKGZpbmFsIFN0cmluZyByZXNwKSB0aHJvd3MgSU9FeGNlcHRpb24geworCXByaW50bG4odGFnICsgIiAiICsgcmVzcCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VuZCBhbiB1bnRhZ2dlZCByZXNwb25zZS4KKyAgICAgKgorICAgICAqIEBwYXJhbSByZXNwIHRoZSByZXNwb25zZSB0byBzZW5kCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiB1bmFibGUgdG8gcmVhZC93cml0ZSB0byBzb2NrZXQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1bnRhZ2dlZChmaW5hbCBTdHJpbmcgcmVzcCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlwcmludGxuKCIqICIgKyByZXNwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZW5kIGEgdGFnZ2VkIE9LIHJlc3BvbnNlLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiB1bmFibGUgdG8gcmVhZC93cml0ZSB0byBzb2NrZXQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBvaygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJdGFnZ2VkKCJPSyIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNlbmQgYSB0YWdnZWQgT0sgcmVzcG9uc2Ugd2l0aCBhIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbXNnIHRoZSBtZXNzYWdlIHRvIHNlbmQKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIHVuYWJsZSB0byByZWFkL3dyaXRlIHRvIHNvY2tldAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIG9rKGZpbmFsIFN0cmluZyBtc2cpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJdGFnZ2VkKCJPSyAiICsgKG1zZyAhPSBudWxsID8gbXNnIDogIiIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZW5kIGEgdGFnZ2VkIE5PIHJlc3BvbnNlIHdpdGggYSBtZXNzYWdlLgorICAgICAqCisgICAgICogQHBhcmFtIG1zZyB0aGUgbWVzc2FnZSB0byBzZW5kCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiB1bmFibGUgdG8gcmVhZC93cml0ZSB0byBzb2NrZXQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBubyhmaW5hbCBTdHJpbmcgbXNnKSB0aHJvd3MgSU9FeGNlcHRpb24geworCXRhZ2dlZCgiTk8gIiArIChtc2cgIT0gbnVsbCA/IG1zZyA6ICIiKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VuZCBhIHRhZ2dlZCBCQUQgcmVzcG9uc2Ugd2l0aCBhIG1lc3NhZ2UuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbXNnIHRoZSBtZXNzYWdlIHRvIHNlbmQKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIHVuYWJsZSB0byByZWFkL3dyaXRlIHRvIHNvY2tldAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGJhZChmaW5hbCBTdHJpbmcgbXNnKSB0aHJvd3MgSU9FeGNlcHRpb24geworCXRhZ2dlZCgiQkFEICIgKyAobXNnICE9IG51bGwgPyBtc2cgOiAiIikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNlbmQgYW4gdW50YWdnZWQgQllFIHJlc3BvbnNlIHdpdGggYSBtZXNzYWdlLCB0aGVuIGV4aXQuCisgICAgICoKKyAgICAgKiBAcGFyYW0gbXNnIHRoZSBtZXNzYWdlIHRvIHNlbmQKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIHVuYWJsZSB0byByZWFkL3dyaXRlIHRvIHNvY2tldAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGJ5ZShmaW5hbCBTdHJpbmcgbXNnKSB0aHJvd3MgSU9FeGNlcHRpb24geworCXVudGFnZ2VkKCJCWUUgIiArIChtc2cgIT0gbnVsbCA/IG1zZyA6ICIiKSk7CisJZXhpdCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNlbmQgYSAiY29udGludWUiIGNvbW1hbmQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIHVuYWJsZSB0byByZWFkL3dyaXRlIHRvIHNvY2tldAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNvbnQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCXByaW50bG4oIisgcGxlYXNlIGNvbnRpbnVlIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VuZCBhICJjb250aW51ZSIgY29tbWFuZCB3aXRoIGEgbWVzc2FnZS4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gdW5hYmxlIHRvIHJlYWQvd3JpdGUgdG8gc29ja2V0CisgICAgICovCisgICAgcHVibGljIHZvaWQgY29udChTdHJpbmcgbXNnKSB0aHJvd3MgSU9FeGNlcHRpb24geworCXByaW50bG4oIisgIiArIChtc2cgIT0gbnVsbCA/IG1zZyA6ICIiKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogSGFuZGxlIGNvbW1hbmQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIHVuYWJsZSB0byByZWFkL3dyaXRlIHRvIHNvY2tldAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGhhbmRsZUNvbW1hbmQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjdXJyZW50TGluZSA9IHN1cGVyLnJlYWRMaW5lKCk7CisKKyAgICAgICAgaWYgKGN1cnJlbnRMaW5lID09IG51bGwpIHsKKwkgICAgLy8gcHJvYmFibHkganVzdCBFT0YgYmVjYXVzZSB0aGUgc29ja2V0IHdhcyBjbG9zZWQKKyAgICAgICAgICAgIC8vTE9HR0VSLnNldmVyZSgiQ3VycmVudCBsaW5lIGlzIG51bGwhIik7CisgICAgICAgICAgICBleGl0KCk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBTdHJpbmdUb2tlbml6ZXIgY3QgPSBuZXcgU3RyaW5nVG9rZW5pemVyKGN1cnJlbnRMaW5lLCAiICIpOworCWlmICghY3QuaGFzTW9yZVRva2VucygpKSB7CisgICAgICAgICAgICBMT0dHRVIubG9nKExldmVsLlNFVkVSRSwgIkVSUk9SIG5vIGNvbW1hbmQgdGFnOiB7MH0iLAorCQkJCQkJCWVzY2FwZShjdXJyZW50TGluZSkpOworICAgICAgICAgICAgYmFkKCJubyBjb21tYW5kIHRhZyIpOworCSAgICByZXR1cm47CisJfQorCXRhZyA9IGN0Lm5leHRUb2tlbigpOworCWlmICghY3QuaGFzTW9yZVRva2VucygpKSB7CisgICAgICAgICAgICBMT0dHRVIubG9nKExldmVsLlNFVkVSRSwgIkVSUk9SIG5vIGNvbW1hbmQ6IHswfSIsCisJCQkJCQkJZXNjYXBlKGN1cnJlbnRMaW5lKSk7CisgICAgICAgICAgICBiYWQoIm5vIGNvbW1hbmQiKTsKKwkgICAgcmV0dXJuOworCX0KKyAgICAgICAgZmluYWwgU3RyaW5nIGNvbW1hbmROYW1lID0gY3QubmV4dFRva2VuKCkudG9VcHBlckNhc2UoKTsKKyAgICAgICAgaWYgKGNvbW1hbmROYW1lID09IG51bGwpIHsKKyAgICAgICAgICAgIExPR0dFUi5zZXZlcmUoIkNvbW1hbmQgbmFtZSBpcyBlbXB0eSEiKTsKKyAgICAgICAgICAgIGV4aXQoKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChjb21tYW5kTmFtZS5lcXVhbHMoIkxPR0lOIikpIHsKKyAgICAgICAgICAgIGxvZ2luKCk7CisgICAgICAgIH0gZWxzZSBpZiAoY29tbWFuZE5hbWUuZXF1YWxzKCJBVVRIRU5USUNBVEUiKSkgeworCSAgICBTdHJpbmcgbWVjaCA9IGN0Lm5leHRUb2tlbigpLnRvVXBwZXJDYXNlKCk7CisJICAgIFN0cmluZyBpciA9IG51bGw7CisJICAgIGlmIChjdC5oYXNNb3JlVG9rZW5zKCkpCisJICAgIAlpciA9IGN0Lm5leHRUb2tlbigpOworICAgICAgICAgICAgYXV0aGVudGljYXRlKG1lY2gsIGlyKTsKKyAgICAgICAgfSBlbHNlIGlmIChjb21tYW5kTmFtZS5lcXVhbHMoIkNBUEFCSUxJVFkiKSkgeworICAgICAgICAgICAgY2FwYWJpbGl0eSgpOworICAgICAgICB9IGVsc2UgaWYgKGNvbW1hbmROYW1lLmVxdWFscygiTk9PUCIpKSB7CisgICAgICAgICAgICBub29wKCk7CisgICAgICAgIH0gZWxzZSBpZiAoY29tbWFuZE5hbWUuZXF1YWxzKCJTRUxFQ1QiKSkgeworICAgICAgICAgICAgc2VsZWN0KGN1cnJlbnRMaW5lKTsKKyAgICAgICAgfSBlbHNlIGlmIChjb21tYW5kTmFtZS5lcXVhbHMoIkVYQU1JTkUiKSkgeworICAgICAgICAgICAgZXhhbWluZShjdXJyZW50TGluZSk7CisgICAgICAgIH0gZWxzZSBpZiAoY29tbWFuZE5hbWUuZXF1YWxzKCJMSVNUIikpIHsKKyAgICAgICAgICAgIGxpc3QoY3VycmVudExpbmUpOworICAgICAgICB9IGVsc2UgaWYgKGNvbW1hbmROYW1lLmVxdWFscygiSURMRSIpKSB7CisgICAgICAgICAgICBpZGxlKCk7CisgICAgICAgIH0gZWxzZSBpZiAoY29tbWFuZE5hbWUuZXF1YWxzKCJGRVRDSCIpKSB7CisgICAgICAgICAgICBmZXRjaChjdXJyZW50TGluZSk7CisgICAgICAgIH0gZWxzZSBpZiAoY29tbWFuZE5hbWUuZXF1YWxzKCJTVE9SRSIpKSB7CisgICAgICAgICAgICBzdG9yZShjdXJyZW50TGluZSk7CisgICAgICAgIH0gZWxzZSBpZiAoY29tbWFuZE5hbWUuZXF1YWxzKCJTRUFSQ0giKSkgeworICAgICAgICAgICAgc2VhcmNoKGN1cnJlbnRMaW5lKTsKKyAgICAgICAgfSBlbHNlIGlmIChjb21tYW5kTmFtZS5lcXVhbHMoIkFQUEVORCIpKSB7CisgICAgICAgICAgICBhcHBlbmQoY3VycmVudExpbmUpOworICAgICAgICB9IGVsc2UgaWYgKGNvbW1hbmROYW1lLmVxdWFscygiQ0xPU0UiKSkgeworICAgICAgICAgICAgY2xvc2UoKTsKKyAgICAgICAgfSBlbHNlIGlmIChjb21tYW5kTmFtZS5lcXVhbHMoIkxPR09VVCIpKSB7CisgICAgICAgICAgICBsb2dvdXQoKTsKKyAgICAgICAgfSBlbHNlIGlmIChjb21tYW5kTmFtZS5lcXVhbHMoIlVJRCIpKSB7CisJICAgIFN0cmluZyBzdWJjb21tYW5kTmFtZSA9IGN0Lm5leHRUb2tlbigpLnRvVXBwZXJDYXNlKCk7CisJICAgIGlmIChzdWJjb21tYW5kTmFtZS5lcXVhbHMoIkZFVENIIikpIHsKKwkJdWlkZmV0Y2goY3VycmVudExpbmUpOworCSAgICB9IGVsc2UgaWYgKHN1YmNvbW1hbmROYW1lLmVxdWFscygiU1RPUkUiKSkgeworCQl1aWRzdG9yZShjdXJyZW50TGluZSk7CisJICAgIH0gZWxzZSB7CisJCUxPR0dFUi5sb2coTGV2ZWwuU0VWRVJFLCAiRVJST1IgVUlEIGNvbW1hbmQgdW5rbm93bjogezB9IiwKKwkJCQkJCQkJc3ViY29tbWFuZE5hbWUpOworCQliYWQoInVua25vd24gVUlEIGNvbW1hbmQiKTsKKwkgICAgfQorICAgICAgICB9IGVsc2UgaWYgKGNvbW1hbmROYW1lLmVxdWFscygiSUQiKSkgeworCSAgICBpZChjdXJyZW50TGluZSk7CisgICAgICAgIH0gZWxzZSBpZiAoY29tbWFuZE5hbWUuZXF1YWxzKCJFTkFCTEUiKSkgeworICAgICAgICAgICAgZW5hYmxlKGN1cnJlbnRMaW5lKTsKKyAgICAgICAgfSBlbHNlIGlmIChjb21tYW5kTmFtZS5lcXVhbHMoIkNSRUFURSIpKSB7CisgICAgICAgICAgICBjcmVhdGUoY3VycmVudExpbmUpOworICAgICAgICB9IGVsc2UgaWYgKGNvbW1hbmROYW1lLmVxdWFscygiREVMRVRFIikpIHsKKyAgICAgICAgICAgIGRlbGV0ZShjdXJyZW50TGluZSk7CisgICAgICAgIH0gZWxzZSBpZiAoY29tbWFuZE5hbWUuZXF1YWxzKCJTVEFUVVMiKSkgeworICAgICAgICAgICAgc3RhdHVzKGN1cnJlbnRMaW5lKTsKKyAgICAgICAgfSBlbHNlIGlmIChjb21tYW5kTmFtZS5lcXVhbHMoIk5BTUVTUEFDRSIpKSB7CisgICAgICAgICAgICBuYW1lc3BhY2UoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIExPR0dFUi5sb2coTGV2ZWwuU0VWRVJFLCAiRVJST1IgY29tbWFuZCB1bmtub3duOiB7MH0iLAorCQkJCQkJCWVzY2FwZShjdXJyZW50TGluZSkpOworICAgICAgICAgICAgYmFkKCJ1bmtub3duIGNvbW1hbmQiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIExPR0lOIGNvbW1hbmQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIHVuYWJsZSB0byByZWFkL3dyaXRlIHRvIHNvY2tldAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGxvZ2luKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb2soIltDQVBBQklMSVRZICIgKyBjYXBhYmlsaXRpZXMgKyAiXSIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFVVEhFTlRJQ0FURSBjb21tYW5kLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiB1bmFibGUgdG8gcmVhZC93cml0ZSB0byBzb2NrZXQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhdXRoZW50aWNhdGUoU3RyaW5nIG1lY2gsIFN0cmluZyBpcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlpZiAobWVjaC5lcXVhbHMoIkxPR0lOIikpCisJICAgIGF1dGhsb2dpbihpcik7CisJZWxzZSBpZiAobWVjaC5lcXVhbHMoIlBMQUlOIikpCisJICAgIGF1dGhwbGFpbihpcik7CisJZWxzZQorCSAgICBiYWQoIkFVVEhFTlRJQ0FURSBub3Qgc3VwcG9ydGVkIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQVVUSEVOVElDQVRFIExPR0lOIGNvbW1hbmQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIHVuYWJsZSB0byByZWFkL3dyaXRlIHRvIHNvY2tldAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGF1dGhsb2dpbihTdHJpbmcgaXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJaWYgKGlyICE9IG51bGwpCisJICAgIGJhZCgiQVVUSEVOVElDQVRFIExPR0lOIGRvZXMgbm90IHN1cHBvcnQgaW5pdGlhbCByZXNwb25zZSIpOworCWNvbnQoYmFzZTY0ZW5jb2RlKCJVc2VybmFtZSIpKTsKKwlTdHJpbmcgdXNlcm5hbWUgPSByZWFkTGluZSgpOworCWNvbnQoYmFzZTY0ZW5jb2RlKCJQYXNzd29yZCIpKTsKKwlTdHJpbmcgcGFzc3dvcmQgPSByZWFkTGluZSgpOworICAgICAgICBvaygiW0NBUEFCSUxJVFkgIiArIGNhcGFiaWxpdGllcyArICJdIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQVVUSEVOVElDQVRFIFBMQUlOIGNvbW1hbmQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIHVuYWJsZSB0byByZWFkL3dyaXRlIHRvIHNvY2tldAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGF1dGhwbGFpbihTdHJpbmcgaXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJaWYgKGlyID09IG51bGwpIHsKKwkgICAgY29udCgiIik7CisJICAgIFN0cmluZyByZXNwID0gcmVhZExpbmUoKTsKKwl9CisgICAgICAgIG9rKCJbQ0FQQUJJTElUWSAiICsgY2FwYWJpbGl0aWVzICsgIl0iKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDQVBBQklMSVRZIGNvbW1hbmQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIHVuYWJsZSB0byByZWFkL3dyaXRlIHRvIHNvY2tldAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNhcGFiaWxpdHkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCXVudGFnZ2VkKCJDQVBBQklMSVRZICIgKyBjYXBhYmlsaXRpZXMpOworICAgICAgICBvaygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNFTEVDVCBjb21tYW5kLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiB1bmFibGUgdG8gcmVhZC93cml0ZSB0byBzb2NrZXQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZWxlY3QoU3RyaW5nIGxpbmUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJdW50YWdnZWQobnVtYmVyT2ZNZXNzYWdlcyArICIgRVhJU1RTIik7CisJdW50YWdnZWQobnVtYmVyT2ZSZWNlbnRNZXNzYWdlcyArICIgUkVDRU5UIik7CisgICAgICAgIG9rKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogRVhBTUlORSBjb21tYW5kLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiB1bmFibGUgdG8gcmVhZC93cml0ZSB0byBzb2NrZXQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBleGFtaW5lKFN0cmluZyBsaW5lKSB0aHJvd3MgSU9FeGNlcHRpb24geworCXVudGFnZ2VkKG51bWJlck9mTWVzc2FnZXMgKyAiIEVYSVNUUyIpOworCXVudGFnZ2VkKG51bWJlck9mUmVjZW50TWVzc2FnZXMgKyAiIFJFQ0VOVCIpOworICAgICAgICBvaygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIExJU1QgY29tbWFuZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gdW5hYmxlIHRvIHJlYWQvd3JpdGUgdG8gc29ja2V0CisgICAgICovCisgICAgcHVibGljIHZvaWQgbGlzdChTdHJpbmcgbGluZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb2soKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJRExFIGNvbW1hbmQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIHVuYWJsZSB0byByZWFkL3dyaXRlIHRvIHNvY2tldAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGlkbGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjb250KCk7CisJaWRsZVdhaXQoKTsKKwlvaygpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBTdHJpbmcgcmVhZExpbmUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjdXJyZW50TGluZSA9IHN1cGVyLnJlYWRMaW5lKCk7CisgICAgICAgIGlmIChjdXJyZW50TGluZSA9PSBudWxsKSB7CisgICAgICAgICAgICBMT0dHRVIuc2V2ZXJlKCJDdXJyZW50IGxpbmUgaXMgbnVsbCEiKTsKKyAgICAgICAgICAgIGV4aXQoKTsKKyAgICAgICAgfQorCXJldHVybiBjdXJyZW50TGluZTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBpZGxlV2FpdCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBsaW5lID0gcmVhZExpbmUoKTsKKworICAgICAgICBpZiAobGluZSAhPSBudWxsICYmICFsaW5lLmVxdWFsc0lnbm9yZUNhc2UoIkRPTkUiKSkgeworICAgICAgICAgICAgTE9HR0VSLnNldmVyZSgiRGlkbid0IGdldCBET05FIHJlc3BvbnNlIHRvIElETEUiKTsKKyAgICAgICAgICAgIGV4aXQoKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEZFVENIIGNvbW1hbmQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIHVuYWJsZSB0byByZWFkL3dyaXRlIHRvIHNvY2tldAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGZldGNoKFN0cmluZyBsaW5lKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvaygpOwkvLyBYWFgKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTVE9SRSBjb21tYW5kLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiB1bmFibGUgdG8gcmVhZC93cml0ZSB0byBzb2NrZXQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzdG9yZShTdHJpbmcgbGluZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb2soKTsJLy8gWFhYCisgICAgfQorCisgICAgLyoqCisgICAgICogU0VBUkNIIGNvbW1hbmQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIHVuYWJsZSB0byByZWFkL3dyaXRlIHRvIHNvY2tldAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNlYXJjaChTdHJpbmcgbGluZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwl1bnRhZ2dlZCgiU0VBUkNIIik7CisgICAgICAgIG9rKCk7CS8vIFhYWAorICAgIH0KKworICAgIC8qKgorICAgICAqIFVJRCBGRVRDSCBjb21tYW5kLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiB1bmFibGUgdG8gcmVhZC93cml0ZSB0byBzb2NrZXQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1aWRmZXRjaChTdHJpbmcgbGluZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb2soKTsJLy8gWFhYCisgICAgfQorCisgICAgLyoqCisgICAgICogVUlEIFNUT1JFIGNvbW1hbmQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIHVuYWJsZSB0byByZWFkL3dyaXRlIHRvIHNvY2tldAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVpZHN0b3JlKFN0cmluZyBsaW5lKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvaygpOwkvLyBYWFgKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBUFBFTkQgY29tbWFuZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gdW5hYmxlIHRvIHJlYWQvd3JpdGUgdG8gc29ja2V0CisgICAgICovCisgICAgcHVibGljIHZvaWQgYXBwZW5kKFN0cmluZyBsaW5lKSB0aHJvd3MgSU9FeGNlcHRpb24geworCWludCBsZWZ0ID0gbGluZS5sYXN0SW5kZXhPZigneycpOworCWludCByaWdodCA9IGxpbmUuaW5kZXhPZignfScsIGxlZnQpOworCWludCBieXRlcyA9IEludGVnZXIucGFyc2VJbnQobGluZS5zdWJzdHJpbmcobGVmdCArIDEsIHJpZ2h0KSk7CisJY29udCgid2FpdGluZyBmb3IgbWVzc2FnZSIpOworCWNvbGxlY3RNZXNzYWdlKGJ5dGVzKTsKKyAgICAgICAgb2soKTsJLy8gWFhYCisgICAgfQorCisgICAgLyoqCisgICAgICogSUQgY29tbWFuZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gdW5hYmxlIHRvIHJlYWQvd3JpdGUgdG8gc29ja2V0CisgICAgICovCisgICAgcHVibGljIHZvaWQgaWQoU3RyaW5nIGxpbmUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJdW50YWdnZWQoIklEIE5JTCIpOworICAgICAgICBvaygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEVOQUJMRSBjb21tYW5kLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiB1bmFibGUgdG8gcmVhZC93cml0ZSB0byBzb2NrZXQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBlbmFibGUoU3RyaW5nIGxpbmUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG5vKCJjYW4ndCBlbmFibGUiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDUkVBVEUgY29tbWFuZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gdW5hYmxlIHRvIHJlYWQvd3JpdGUgdG8gc29ja2V0CisgICAgICovCisgICAgcHVibGljIHZvaWQgY3JlYXRlKFN0cmluZyBsaW5lKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBubygiY2FuJ3QgY3JlYXRlIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogREVMRVRFIGNvbW1hbmQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIHVuYWJsZSB0byByZWFkL3dyaXRlIHRvIHNvY2tldAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGRlbGV0ZShTdHJpbmcgbGluZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgbm8oImNhbid0IGRlbGV0ZSIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNUQVRVUyBjb21tYW5kLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiB1bmFibGUgdG8gcmVhZC93cml0ZSB0byBzb2NrZXQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzdGF0dXMoU3RyaW5nIGxpbmUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG5vKCJjYW4ndCBnZXQgc3RhdHVzIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogTkFNRVNQQUNFIGNvbW1hbmQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIHVuYWJsZSB0byByZWFkL3dyaXRlIHRvIHNvY2tldAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIG5hbWVzcGFjZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG5vKCJubyBuYW1lc3BhY2VzIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29sbGVjdCAiYnl0ZXMiIHdvcnRoIG9mIGRhdGEgZm9yIHRoZSBtZXNzYWdlIGJlaW5nIGFwcGVuZGVkLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGNvbGxlY3RNZXNzYWdlKGludCBieXRlcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlyZWFkTGl0ZXJhbChieXRlcyk7CS8vIHJlYWQgdGhlIGRhdGEgYW5kIHRocm93IGl0IGF3YXkKKwlzdXBlci5yZWFkTGluZSgpOwkvLyBkYXRhIGZvbGxvd2VkIGJ5IGEgbmV3bGluZQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWQgYSBsaXRlcmFsIG9mICJieXRlcyIgYnl0ZXMgYW5kIHJldHVybiBpdCBhcyBhIFVURi04IHN0cmluZy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU3RyaW5nIHJlYWRMaXRlcmFsKGludCBieXRlcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlwcmludGxuKCIrIik7CisJYnl0ZVtdIGRhdGEgPSBuZXcgYnl0ZVtieXRlc107CisJaW50IGxlbiA9IGRhdGEubGVuZ3RoOworCWludCBvZmYgPSAwOworCWludCBuOworCXdoaWxlIChsZW4gPiAwICYmIChuID0gaW4ucmVhZChkYXRhLCBvZmYsIGxlbikpID4gMCkgeworCSAgICBvZmYgKz0gbjsKKwkgICAgbGVuIC09IG47CisJfQorCXJldHVybiBuZXcgU3RyaW5nKGRhdGEsIFN0YW5kYXJkQ2hhcnNldHMuVVRGXzgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENMT1NFIGNvbW1hbmQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIHVuYWJsZSB0byByZWFkL3dyaXRlIHRvIHNvY2tldAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgb2soKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBOT09QIGNvbW1hbmQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIHVuYWJsZSB0byByZWFkL3dyaXRlIHRvIHNvY2tldAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIG5vb3AoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvaygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIExPR09VVCBjb21tYW5kLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiB1bmFibGUgdG8gcmVhZC93cml0ZSB0byBzb2NrZXQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBsb2dvdXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvaygpOworICAgICAgICBleGl0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQmFzZTY0IGVuY29kZSB0aGUgc3RyaW5nLgorICAgICAqLworICAgIHByb3RlY3RlZCBTdHJpbmcgYmFzZTY0ZW5jb2RlKFN0cmluZyBzKSB0aHJvd3MgSU9FeGNlcHRpb24geworCXJldHVybiBuZXcgU3RyaW5nKEJBU0U2NEVuY29kZXJTdHJlYW0uZW5jb2RlKHMuZ2V0Qnl0ZXMoIlVTLUFTQ0lJIikpLAorCQkJIlVTLUFTQ0lJIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogRXNjYXBlIGFueSBub24tcHJpbnRhYmxlIGNoYXJhY3RlcnMgaW4gInMiLAorICAgICAqIGxpbWl0aW5nIHRvdGFsIGxlbmd0aCB0byBhYm91dCAxMDAgY2hhcmFjdGVycy4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyBlc2NhcGUoU3RyaW5nIHMpIHsKKwlTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKwlmb3IgKGludCBpID0gMDsgaSA8IHMubGVuZ3RoKCk7IGkrKykgeworCSAgICBpZiAoc2IubGVuZ3RoKCkgPj0gMTAwKSB7CisJCXNiLmFwcGVuZCgiLi4uIik7CisJCWJyZWFrOworCSAgICB9CisJICAgIGNoYXIgYyA9IHMuY2hhckF0KGkpOworCSAgICBpZiAoYyA8ICcgJyB8fCBjID09ICdcMTc3JykgeworCQlpZiAoYyA9PSAnXHInKQorCQkgICAgc2IuYXBwZW5kKCJcXHIiKTsKKwkJZWxzZSBpZiAoYyA9PSAnXG4nKQorCQkgICAgc2IuYXBwZW5kKCJcXG4iKTsKKwkJZWxzZSBpZiAoYyA9PSAnXHQnKQorCQkgICAgc2IuYXBwZW5kKCJcXHQiKTsKKwkJZWxzZQorCQkgICAgc2IuYXBwZW5kKCdcXCcpLmFwcGVuZChTdHJpbmcuZm9ybWF0KCIlMDNvIiwgKGludCljKSk7CisJICAgIH0gZWxzZSBpZiAoYyA+PSAnXDIwMCcpIHsKKwkJICAgIHNiLmFwcGVuZCgiXFx1IikuYXBwZW5kKFN0cmluZy5mb3JtYXQoIiUwNHgiLCAoaW50KWMpKTsKKwkgICAgfSBlbHNlCisJCXNiLmFwcGVuZChjKTsKKwl9CisJcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0lNQVBJRFRlc3QuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9JTUFQSURUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTZjZTdjMgotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9JTUFQSURUZXN0LmphdmEKQEAgLTAsMCArMSw5NiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwOSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuaW1hcDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7CitpbXBvcnQgamF2YS51dGlsLlN0cmluZ1Rva2VuaXplcjsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworCitpbXBvcnQgamF2YXgubWFpbC5TZXNzaW9uOworaW1wb3J0IGphdmF4Lm1haWwuU3RvcmU7CisKK2ltcG9ydCBjb20uc3VuLm1haWwudGVzdC5UZXN0U2VydmVyOworCitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LlJ1bGU7CitpbXBvcnQgb3JnLmp1bml0LnJ1bGVzLlRpbWVvdXQ7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RXF1YWxzOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmZhaWw7CisKKy8qKgorICogVGVzdCB0aGUgSU1BUCBJRCBjb21tYW5kLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgSU1BUElEVGVzdCB7CisKKyAgICAvLyB0aW1lb3V0IHRoZSB0ZXN0IGluIGNhc2Ugb2YgZGVhZGxvY2sKKyAgICBAUnVsZQorICAgIHB1YmxpYyBUaW1lb3V0IGRlYWRsb2NrVGltZW91dCA9IFRpbWVvdXQuc2Vjb25kcygyMCk7CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RJRE5JTCgpIHsKKyAgICAgICAgVGVzdFNlcnZlciBzZXJ2ZXIgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmluYWwgSU1BUEhhbmRsZXIgaGFuZGxlciA9IG5ldyBJTUFQSGFuZGxlcklEKCk7CisgICAgICAgICAgICBzZXJ2ZXIgPSBuZXcgVGVzdFNlcnZlcihoYW5kbGVyKTsKKyAgICAgICAgICAgIHNlcnZlci5zdGFydCgpOworCisgICAgICAgICAgICBmaW5hbCBQcm9wZXJ0aWVzIHByb3BlcnRpZXMgPSBuZXcgUHJvcGVydGllcygpOworICAgICAgICAgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5pbWFwLmhvc3QiLCAibG9jYWxob3N0Iik7CisgICAgICAgICAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLmltYXAucG9ydCIsICIiICsgc2VydmVyLmdldFBvcnQoKSk7CisgICAgICAgICAgICBmaW5hbCBTZXNzaW9uIHNlc3Npb24gPSBTZXNzaW9uLmdldEluc3RhbmNlKHByb3BlcnRpZXMpOworICAgICAgICAgICAgLy9zZXNzaW9uLnNldERlYnVnKHRydWUpOworCisgICAgICAgICAgICBmaW5hbCBJTUFQU3RvcmUgc3RvcmUgPSAoSU1BUFN0b3JlKXNlc3Npb24uZ2V0U3RvcmUoImltYXAiKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc3RvcmUuY29ubmVjdCgidGVzdCIsICJ0ZXN0Iik7CisJCU1hcDxTdHJpbmcsU3RyaW5nPiBpZCA9IHN0b3JlLmlkKG51bGwpOworCQlhc3NlcnRFcXVhbHMoInRydWUiLCBpZC5nZXQoInRlc3QiKSk7CisKKwkgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJCVN5c3RlbS5vdXQucHJpbnRsbihleCk7CisJCWV4LnByaW50U3RhY2tUcmFjZSgpOworCQlmYWlsKGV4LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBzdG9yZS5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChmaW5hbCBFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgIGZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKHNlcnZlciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgc2VydmVyLnF1aXQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEN1c3RvbSBoYW5kbGVyLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIElNQVBIYW5kbGVySUQgZXh0ZW5kcyBJTUFQSGFuZGxlciB7CisKKwlAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgaWQoU3RyaW5nIGxpbmUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJICAgIFN0cmluZ1Rva2VuaXplciBzdCA9IG5ldyBTdHJpbmdUb2tlbml6ZXIobGluZSk7CisJICAgIFN0cmluZyB0YWcgPSBzdC5uZXh0VG9rZW4oKTsKKwkgICAgU3RyaW5nIGNtZCA9IHN0Lm5leHRUb2tlbigpOworCSAgICBTdHJpbmcgYXJnID0gc3QubmV4dFRva2VuKCk7CisJICAgIHVudGFnZ2VkKCJJRCAoXCJ0ZXN0XCIgXCIiICsgYXJnLmVxdWFscygiTklMIikgKyAiXCIpIik7CisJICAgIG9rKCk7CisJfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9JTUFQSWRsZU1hbmFnZXJUZXN0LmphdmEgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL2ltYXAvSU1BUElkbGVNYW5hZ2VyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRiZmYxMzIKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL2ltYXAvSU1BUElkbGVNYW5hZ2VyVGVzdC5qYXZhCkBAIC0wLDAgKzEsNTE0IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDA5LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5pbWFwOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5Db3VudERvd25MYXRjaDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRvclNlcnZpY2U7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3JzOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LlRpbWVVbml0OworCitpbXBvcnQgamF2YXgubWFpbC5TZXNzaW9uOworaW1wb3J0IGphdmF4Lm1haWwuU3RvcmU7CitpbXBvcnQgamF2YXgubWFpbC5Gb2xkZXI7CitpbXBvcnQgamF2YXgubWFpbC5GZXRjaFByb2ZpbGU7CitpbXBvcnQgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YXgubWFpbC5ldmVudC5Db25uZWN0aW9uQWRhcHRlcjsKK2ltcG9ydCBqYXZheC5tYWlsLmV2ZW50LkNvbm5lY3Rpb25FdmVudDsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC50ZXN0LlRlc3RTZXJ2ZXI7CisKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQuUnVsZTsKK2ltcG9ydCBvcmcuanVuaXQucnVsZXMuVGltZW91dDsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5mYWlsOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEVxdWFsczsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUcnVlOworCisvKioKKyAqIFRlc3QgSWRsZU1hbmFnZXIuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBJTUFQSWRsZU1hbmFnZXJUZXN0IHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBUSU1FT1VUID0gMTAwMDsJLy8gMSBzZWNvbmQKKworICAgIC8vIHRpbWVvdXQgdGhlIHRlc3QgaW4gY2FzZSBvZiBkZWFkbG9jaworICAgIEBSdWxlCisgICAgcHVibGljIFRpbWVvdXQgZGVhZGxvY2tUaW1lb3V0ID0gVGltZW91dC5taWxsaXMoMTAgKiBUSU1FT1VUKTsKKworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCBJZGxlTWFuYWdlciBoYW5kbGVzIG11bHRpcGxlIHJlc3BvbnNlcyBpbiBhIHNpbmdsZSBwYWNrZXQuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RG9uZSgpIHsKKwl0ZXN0U3VjY2VzcyhuZXcgSU1BUEhhbmRsZXJJZGxlRG9uZSgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RFeGlzdHMoKSB7CisJdGVzdFN1Y2Nlc3MobmV3IElNQVBIYW5kbGVySWRsZUV4aXN0cygpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdFN1Y2Nlc3MoSU1BUEhhbmRsZXJJZGxlIGhhbmRsZXIpIHsKKyAgICAgICAgVGVzdFNlcnZlciBzZXJ2ZXIgPSBudWxsOworCUlkbGVNYW5hZ2VyIGlkbGVNYW5hZ2VyID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNlcnZlciA9IG5ldyBUZXN0U2VydmVyKGhhbmRsZXIpOworICAgICAgICAgICAgc2VydmVyLnN0YXJ0KCk7CisKKyAgICAgICAgICAgIGZpbmFsIFByb3BlcnRpZXMgcHJvcGVydGllcyA9IG5ldyBQcm9wZXJ0aWVzKCk7CisgICAgICAgICAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLmltYXAuaG9zdCIsICJsb2NhbGhvc3QiKTsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuaW1hcC5wb3J0IiwgIiIgKyBzZXJ2ZXIuZ2V0UG9ydCgpKTsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuaW1hcC51c2Vzb2NrZXRjaGFubmVscyIsICJ0cnVlIik7CisgICAgICAgICAgICBmaW5hbCBTZXNzaW9uIHNlc3Npb24gPSBTZXNzaW9uLmdldEluc3RhbmNlKHByb3BlcnRpZXMpOworICAgICAgICAgICAgLy9zZXNzaW9uLnNldERlYnVnKHRydWUpOworCisJICAgIEV4ZWN1dG9yU2VydmljZSBleGVjdXRvciA9IEV4ZWN1dG9ycy5uZXdDYWNoZWRUaHJlYWRQb29sKCk7CisJICAgIGlkbGVNYW5hZ2VyID0gbmV3IElkbGVNYW5hZ2VyKHNlc3Npb24sIGV4ZWN1dG9yKTsKKworICAgICAgICAgICAgZmluYWwgSU1BUFN0b3JlIHN0b3JlID0gKElNQVBTdG9yZSlzZXNzaW9uLmdldFN0b3JlKCJpbWFwIik7CisJICAgIEZvbGRlciBmb2xkZXIgPSBudWxsOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdG9yZS5jb25uZWN0KCJ0ZXN0IiwgInRlc3QiKTsKKwkJZm9sZGVyID0gc3RvcmUuZ2V0Rm9sZGVyKCJJTkJPWCIpOworCQlmb2xkZXIub3BlbihGb2xkZXIuUkVBRF9XUklURSk7CisJCWlkbGVNYW5hZ2VyLndhdGNoKGZvbGRlcik7CisJCWhhbmRsZXIud2FpdEZvcklkbGUoKTsKKworCQkvLyBub3cgZG8gc29tZXRoaW5nIHRoYXQgaXMgc3VyZSB0byB0b3VjaCB0aGUgc2VydmVyCisJCUZldGNoUHJvZmlsZSBmcCA9IG5ldyBGZXRjaFByb2ZpbGUoKTsKKwkJZnAuYWRkKEZldGNoUHJvZmlsZS5JdGVtLkVOVkVMT1BFKTsKKwkJZm9sZGVyLmZldGNoKGZvbGRlci5nZXRNZXNzYWdlcygpLCBmcCk7CisKKwkJLy8gY2hlY2sgdGhhdCB0aGUgbmV3IG1lc3NhZ2Ugd2FzIHNlZW4KKwkJaW50IGNvdW50ID0gZm9sZGVyLmdldE1lc3NhZ2VDb3VudCgpOworCQlmb2xkZXIuY2xvc2UodHJ1ZSk7CisKKwkJYXNzZXJ0RXF1YWxzKDMsIGNvdW50KTsKKwkgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJCVN5c3RlbS5vdXQucHJpbnRsbihleCk7CisJCWV4LnByaW50U3RhY2tUcmFjZSgpOworCQlmYWlsKGV4LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKwkJdHJ5IHsKKwkJICAgIGZvbGRlci5jbG9zZShmYWxzZSk7CisJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBleDIpIHsgfQorICAgICAgICAgICAgICAgIHN0b3JlLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisJICAgIGlmIChpZGxlTWFuYWdlciAhPSBudWxsKQorCQlpZGxlTWFuYWdlci5zdG9wKCk7CisgICAgICAgICAgICBpZiAoc2VydmVyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBzZXJ2ZXIucXVpdCgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IElkbGVNYW5hZ2VyIGhhbmRsZXMgdGltZW91dHMuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QmVmb3JlSWRsZVRpbWVvdXQoKSB7CisJdGVzdEZhaWx1cmUobmV3IElNQVBIYW5kbGVyQmVmb3JlSWRsZVRpbWVvdXQoKSwgdHJ1ZSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SWRsZVRpbWVvdXQoKSB7CisJdGVzdEZhaWx1cmUobmV3IElNQVBIYW5kbGVySWRsZVRpbWVvdXQoKSwgdHJ1ZSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RG9uZVRpbWVvdXQoKSB7CisJdGVzdEZhaWx1cmUobmV3IElNQVBIYW5kbGVyRG9uZVRpbWVvdXQoKSwgdHJ1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IElkbGVNYW5hZ2VyIGhhbmRsZXMgY29ubmVjdGlvbiBmYWlsdXJlcy4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RCZWZvcmVJZGxlRHJvcCgpIHsKKwl0ZXN0RmFpbHVyZShuZXcgSU1BUEhhbmRsZXJCZWZvcmVJZGxlRHJvcCgpLCBmYWxzZSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SWRsZURyb3AoKSB7CisJdGVzdEZhaWx1cmUobmV3IElNQVBIYW5kbGVySWRsZURyb3AoKSwgZmFsc2UpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdERvbmVEcm9wKCkgeworCXRlc3RGYWlsdXJlKG5ldyBJTUFQSGFuZGxlckRvbmVEcm9wKCksIGZhbHNlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdEZhaWx1cmUoSU1BUEhhbmRsZXJJZGxlIGhhbmRsZXIsIGJvb2xlYW4gc2V0VGltZW91dCkgeworICAgICAgICBUZXN0U2VydmVyIHNlcnZlciA9IG51bGw7CisJSWRsZU1hbmFnZXIgaWRsZU1hbmFnZXIgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2VydmVyID0gbmV3IFRlc3RTZXJ2ZXIoaGFuZGxlcik7CisgICAgICAgICAgICBzZXJ2ZXIuc3RhcnQoKTsKKworICAgICAgICAgICAgZmluYWwgUHJvcGVydGllcyBwcm9wZXJ0aWVzID0gbmV3IFByb3BlcnRpZXMoKTsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuaW1hcC5ob3N0IiwgImxvY2FsaG9zdCIpOworICAgICAgICAgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5pbWFwLnBvcnQiLCAiIiArIHNlcnZlci5nZXRQb3J0KCkpOworCSAgICBpZiAoc2V0VGltZW91dCkKKwkJcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5pbWFwLnRpbWVvdXQiLCAiIiArIFRJTUVPVVQpOworICAgICAgICAgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5pbWFwLnVzZXNvY2tldGNoYW5uZWxzIiwgInRydWUiKTsKKyAgICAgICAgICAgIGZpbmFsIFNlc3Npb24gc2Vzc2lvbiA9IFNlc3Npb24uZ2V0SW5zdGFuY2UocHJvcGVydGllcyk7CisgICAgICAgICAgICAvL3Nlc3Npb24uc2V0RGVidWcodHJ1ZSk7CisKKwkgICAgRXhlY3V0b3JTZXJ2aWNlIGV4ZWN1dG9yID0gRXhlY3V0b3JzLm5ld0NhY2hlZFRocmVhZFBvb2woKTsKKwkgICAgaWRsZU1hbmFnZXIgPSBuZXcgSWRsZU1hbmFnZXIoc2Vzc2lvbiwgZXhlY3V0b3IpOworCisgICAgICAgICAgICBmaW5hbCBJTUFQU3RvcmUgc3RvcmUgPSAoSU1BUFN0b3JlKXNlc3Npb24uZ2V0U3RvcmUoImltYXAiKTsKKwkgICAgRm9sZGVyIGZvbGRlciA9IG51bGw7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHN0b3JlLmNvbm5lY3QoInRlc3QiLCAidGVzdCIpOworCQlmb2xkZXIgPSBzdG9yZS5nZXRGb2xkZXIoIklOQk9YIik7CisJCWZvbGRlci5vcGVuKEZvbGRlci5SRUFEX1dSSVRFKTsKKwkJaWRsZU1hbmFnZXIud2F0Y2goZm9sZGVyKTsKKwkJaGFuZGxlci53YWl0Rm9ySWRsZSgpOworCisJCS8vIG5vdyBkbyBzb21ldGhpbmcgdGhhdCBpcyBzdXJlIHRvIHRvdWNoIHRoZSBzZXJ2ZXIKKwkJRmV0Y2hQcm9maWxlIGZwID0gbmV3IEZldGNoUHJvZmlsZSgpOworCQlmcC5hZGQoRmV0Y2hQcm9maWxlLkl0ZW0uRU5WRUxPUEUpOworCQlmb2xkZXIuZmV0Y2goZm9sZGVyLmdldE1lc3NhZ2VzKCksIGZwKTsKKworCQlmYWlsKCJObyBleGNlcHRpb24iKTsKKwkgICAgfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIG1leCkgeworCQkvLyBzdWNjZXNzIQorCSAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKwkJU3lzdGVtLm91dC5wcmludGxuKCJGYWlsZWQgd2l0aCBleGNlcHRpb246ICIgKyBleCk7CisJCWV4LnByaW50U3RhY2tUcmFjZSgpOworCQlmYWlsKGV4LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKwkJdHJ5IHsKKwkJICAgIGZvbGRlci5jbG9zZShmYWxzZSk7CisJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBleDIpIHsgfQorICAgICAgICAgICAgICAgIHN0b3JlLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisJICAgIGlmIChpZGxlTWFuYWdlciAhPSBudWxsKQorCQlpZGxlTWFuYWdlci5zdG9wKCk7CisgICAgICAgICAgICBpZiAoc2VydmVyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBzZXJ2ZXIucXVpdCgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Tm90T3BlbmVkKCkgeworICAgICAgICBUZXN0U2VydmVyIHNlcnZlciA9IG51bGw7CisJSWRsZU1hbmFnZXIgaWRsZU1hbmFnZXIgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2VydmVyID0gbmV3IFRlc3RTZXJ2ZXIobmV3IElNQVBIYW5kbGVyKCkpOworICAgICAgICAgICAgc2VydmVyLnN0YXJ0KCk7CisKKyAgICAgICAgICAgIGZpbmFsIFByb3BlcnRpZXMgcHJvcGVydGllcyA9IG5ldyBQcm9wZXJ0aWVzKCk7CisgICAgICAgICAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLmltYXAuaG9zdCIsICJsb2NhbGhvc3QiKTsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuaW1hcC5wb3J0IiwgIiIgKyBzZXJ2ZXIuZ2V0UG9ydCgpKTsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuaW1hcC51c2Vzb2NrZXRjaGFubmVscyIsICJ0cnVlIik7CisgICAgICAgICAgICBmaW5hbCBTZXNzaW9uIHNlc3Npb24gPSBTZXNzaW9uLmdldEluc3RhbmNlKHByb3BlcnRpZXMpOworICAgICAgICAgICAgLy9zZXNzaW9uLnNldERlYnVnKHRydWUpOworCisJICAgIEV4ZWN1dG9yU2VydmljZSBleGVjdXRvciA9IEV4ZWN1dG9ycy5uZXdDYWNoZWRUaHJlYWRQb29sKCk7CisJICAgIGlkbGVNYW5hZ2VyID0gbmV3IElkbGVNYW5hZ2VyKHNlc3Npb24sIGV4ZWN1dG9yKTsKKworICAgICAgICAgICAgZmluYWwgSU1BUFN0b3JlIHN0b3JlID0gKElNQVBTdG9yZSlzZXNzaW9uLmdldFN0b3JlKCJpbWFwIik7CisJICAgIEZvbGRlciBmb2xkZXIgPSBudWxsOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdG9yZS5jb25uZWN0KCJ0ZXN0IiwgInRlc3QiKTsKKwkJZm9sZGVyID0gc3RvcmUuZ2V0Rm9sZGVyKCJJTkJPWCIpOworCQlpZGxlTWFuYWdlci53YXRjaChmb2xkZXIpOworCisJCWZhaWwoIk5vIGV4Y2VwdGlvbiIpOworCSAgICB9IGNhdGNoIChNZXNzYWdpbmdFeGNlcHRpb24gbWV4KSB7CisJCS8vIG1ha2Ugc3VyZSB3ZSBnZXQgdGhlIGV4cGVjdGVkIGV4Y2VwdGlvbgorCQlhc3NlcnRUcnVlKG1leC5nZXRNZXNzYWdlKCkuY29udGFpbnMoIm9wZW4iKSk7CisJCS8vIHN1Y2Nlc3MhCisJICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCQlTeXN0ZW0ub3V0LnByaW50bG4oIkZhaWxlZCB3aXRoIGV4Y2VwdGlvbjogIiArIGV4KTsKKwkJZXgucHJpbnRTdGFja1RyYWNlKCk7CisJCWZhaWwoZXgudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworCQl0cnkgeworCQkgICAgZm9sZGVyLmNsb3NlKGZhbHNlKTsKKwkJfSBjYXRjaCAoRXhjZXB0aW9uIGV4MikgeyB9CisgICAgICAgICAgICAgICAgc3RvcmUuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoZmluYWwgRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICBmYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKwkgICAgaWYgKGlkbGVNYW5hZ2VyICE9IG51bGwpCisJCWlkbGVNYW5hZ2VyLnN0b3AoKTsKKyAgICAgICAgICAgIGlmIChzZXJ2ZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHNlcnZlci5xdWl0KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3ROb1NvY2tldENoYW5uZWwoKSB7CisgICAgICAgIFRlc3RTZXJ2ZXIgc2VydmVyID0gbnVsbDsKKwlJZGxlTWFuYWdlciBpZGxlTWFuYWdlciA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzZXJ2ZXIgPSBuZXcgVGVzdFNlcnZlcihuZXcgSU1BUEhhbmRsZXIoKSk7CisgICAgICAgICAgICBzZXJ2ZXIuc3RhcnQoKTsKKworICAgICAgICAgICAgZmluYWwgUHJvcGVydGllcyBwcm9wZXJ0aWVzID0gbmV3IFByb3BlcnRpZXMoKTsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuaW1hcC5ob3N0IiwgImxvY2FsaG9zdCIpOworICAgICAgICAgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5pbWFwLnBvcnQiLCAiIiArIHNlcnZlci5nZXRQb3J0KCkpOworICAgICAgICAgICAgZmluYWwgU2Vzc2lvbiBzZXNzaW9uID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShwcm9wZXJ0aWVzKTsKKyAgICAgICAgICAgIC8vc2Vzc2lvbi5zZXREZWJ1Zyh0cnVlKTsKKworCSAgICBFeGVjdXRvclNlcnZpY2UgZXhlY3V0b3IgPSBFeGVjdXRvcnMubmV3Q2FjaGVkVGhyZWFkUG9vbCgpOworCSAgICBpZGxlTWFuYWdlciA9IG5ldyBJZGxlTWFuYWdlcihzZXNzaW9uLCBleGVjdXRvcik7CisKKyAgICAgICAgICAgIGZpbmFsIElNQVBTdG9yZSBzdG9yZSA9IChJTUFQU3RvcmUpc2Vzc2lvbi5nZXRTdG9yZSgiaW1hcCIpOworCSAgICBGb2xkZXIgZm9sZGVyID0gbnVsbDsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc3RvcmUuY29ubmVjdCgidGVzdCIsICJ0ZXN0Iik7CisJCWZvbGRlciA9IHN0b3JlLmdldEZvbGRlcigiSU5CT1giKTsKKwkJZm9sZGVyLm9wZW4oRm9sZGVyLlJFQURfV1JJVEUpOworCQlpZGxlTWFuYWdlci53YXRjaChmb2xkZXIpOworCisJCWZhaWwoIk5vIGV4Y2VwdGlvbiIpOworCSAgICB9IGNhdGNoIChNZXNzYWdpbmdFeGNlcHRpb24gbWV4KSB7CisJCS8vIG1ha2Ugc3VyZSB3ZSBnZXQgdGhlIGV4cGVjdGVkIGV4Y2VwdGlvbgorCQlhc3NlcnRUcnVlKCFtZXguZ2V0TWVzc2FnZSgpLmNvbnRhaW5zKCJvcGVuIikpOworCQkvLyBzdWNjZXNzIQorCSAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKwkJU3lzdGVtLm91dC5wcmludGxuKCJGYWlsZWQgd2l0aCBleGNlcHRpb246ICIgKyBleCk7CisJCWV4LnByaW50U3RhY2tUcmFjZSgpOworCQlmYWlsKGV4LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKwkJdHJ5IHsKKwkJICAgIGZvbGRlci5jbG9zZShmYWxzZSk7CisJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBleDIpIHsgfQorICAgICAgICAgICAgICAgIHN0b3JlLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisJICAgIGlmIChpZGxlTWFuYWdlciAhPSBudWxsKQorCQlpZGxlTWFuYWdlci5zdG9wKCk7CisgICAgICAgICAgICBpZiAoc2VydmVyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBzZXJ2ZXIucXVpdCgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQmFzZSBjbGFzcyBmb3IgY3VzdG9tIGhhbmRsZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgYWJzdHJhY3QgY2xhc3MgSU1BUEhhbmRsZXJJZGxlIGV4dGVuZHMgSU1BUEhhbmRsZXIgeworCUBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBzZWxlY3QoU3RyaW5nIGxpbmUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJICAgIG51bWJlck9mTWVzc2FnZXMgPSAxOworCSAgICBzdXBlci5zZWxlY3QobGluZSk7CisJfQorCisJcHVibGljIGFic3RyYWN0IHZvaWQgd2FpdEZvcklkbGUoKSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb247CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3VzdG9tIGhhbmRsZXIuICBSZXNwb25kIHRvIERPTkUgd2l0aCBhIHNpbmdsZSBwYWNrZXQgY29udGFpbmluZworICAgICAqIEVYSVNUUyBhbmQgT0suCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSU1BUEhhbmRsZXJJZGxlRG9uZSBleHRlbmRzIElNQVBIYW5kbGVySWRsZSB7CisJLy8gbXVzdCBiZSBzdGF0aWMgYmVjYXVzZSBoYW5kbGVyIGlzIGNsb25lZCBmb3IgZWFjaCBjb25uZWN0aW9uCisJcHJpdmF0ZSBzdGF0aWMgQ291bnREb3duTGF0Y2ggbGF0Y2ggPSBuZXcgQ291bnREb3duTGF0Y2goMSk7CisKKwlAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgaWRsZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJICAgIGNvbnQoKTsKKwkgICAgbGF0Y2guY291bnREb3duKCk7CisJICAgIGlkbGVXYWl0KCk7CisJICAgIHByaW50bG4oIiogMyBFWElTVFNcclxuIiArIHRhZyArICIgT0siKTsKKyAgICAgICAgfQorCisJQE92ZXJyaWRlCisJcHVibGljIHZvaWQgd2FpdEZvcklkbGUoKSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworCSAgICBsYXRjaC5hd2FpdCgpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDdXN0b20gaGFuZGxlci4gIFNlbmQgdHdvIEVYSVNUUyByZXNwb25zZXMgaW4gYSBzaW5nbGUgcGFja2V0LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIElNQVBIYW5kbGVySWRsZUV4aXN0cyBleHRlbmRzIElNQVBIYW5kbGVySWRsZSB7CisJLy8gbXVzdCBiZSBzdGF0aWMgYmVjYXVzZSBoYW5kbGVyIGlzIGNsb25lZCBmb3IgZWFjaCBjb25uZWN0aW9uCisJcHJpdmF0ZSBzdGF0aWMgQ291bnREb3duTGF0Y2ggbGF0Y2ggPSBuZXcgQ291bnREb3duTGF0Y2goMSk7CisKKwlAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgaWRsZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJICAgIGNvbnQoKTsKKwkgICAgbGF0Y2guY291bnREb3duKCk7CisJICAgIGlkbGVXYWl0KCk7CisJICAgIHByaW50bG4oIiogMiBFWElTVFNcclxuKiAzIEVYSVNUUyIpOworCSAgICBvaygpOworICAgICAgICB9CisKKwlAT3ZlcnJpZGUKKwlwdWJsaWMgdm9pZCB3YWl0Rm9ySWRsZSgpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisJICAgIGxhdGNoLmF3YWl0KCk7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEN1c3RvbSBoYW5kbGVyLiAgRGVsYXkgbG9uZyBlbm91Z2ggYmVmb3JlIElETEUgc3RhcnRzIHRvIGZvcmNlIGEgdGltZW91dC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJTUFQSGFuZGxlckJlZm9yZUlkbGVUaW1lb3V0CisJCQkJCQkgICAgZXh0ZW5kcyBJTUFQSGFuZGxlcklkbGUgeworCS8vIG11c3QgYmUgc3RhdGljIGJlY2F1c2UgaGFuZGxlciBpcyBjbG9uZWQgZm9yIGVhY2ggY29ubmVjdGlvbgorCXByaXZhdGUgc3RhdGljIENvdW50RG93bkxhdGNoIGxhdGNoID0gbmV3IENvdW50RG93bkxhdGNoKDEpOworCisJQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGlkbGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCSAgICB0cnkgeworCQlUaHJlYWQuc2xlZXAoMiAqIFRJTUVPVVQpOworCSAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBleCkgeyB9CisJICAgIGNvbnQoKTsKKwkgICAgbGF0Y2guY291bnREb3duKCk7CisJICAgIGlkbGVXYWl0KCk7CisJICAgIG9rKCk7CisgICAgICAgIH0KKworCUBPdmVycmlkZQorCXB1YmxpYyB2b2lkIHdhaXRGb3JJZGxlKCkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKwkgICAgbGF0Y2guYXdhaXQoKTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3VzdG9tIGhhbmRsZXIuICBEZWxheSBsb25nIGVub3VnaCBhZnRlciBJRExFIHN0YXJ0cyB0byBmb3JjZSBhIHRpbWVvdXQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSU1BUEhhbmRsZXJJZGxlVGltZW91dCBleHRlbmRzIElNQVBIYW5kbGVySWRsZSB7CisJLy8gbXVzdCBiZSBzdGF0aWMgYmVjYXVzZSBoYW5kbGVyIGlzIGNsb25lZCBmb3IgZWFjaCBjb25uZWN0aW9uCisJcHJpdmF0ZSBzdGF0aWMgQ291bnREb3duTGF0Y2ggbGF0Y2ggPSBuZXcgQ291bnREb3duTGF0Y2goMSk7CisKKwlAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgaWRsZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJICAgIGNvbnQoKTsKKwkgICAgbGF0Y2guY291bnREb3duKCk7CisJICAgIHRyeSB7CisJCVRocmVhZC5zbGVlcCgyICogVElNRU9VVCk7CisJICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGV4KSB7IH0KKwkgICAgaWRsZVdhaXQoKTsKKwkgICAgb2soKTsKKyAgICAgICAgfQorCisJQE92ZXJyaWRlCisJcHVibGljIHZvaWQgd2FpdEZvcklkbGUoKSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworCSAgICBsYXRjaC5hd2FpdCgpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDdXN0b20gaGFuZGxlci4gIERlbGF5IGxvbmcgZW5vdWdoIGFmdGVyIERPTkUgcmVjZWl2ZWQgdG8gZm9yY2UgYQorICAgICAqIHRpbWVvdXQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSU1BUEhhbmRsZXJEb25lVGltZW91dCBleHRlbmRzIElNQVBIYW5kbGVySWRsZSB7CisJLy8gbXVzdCBiZSBzdGF0aWMgYmVjYXVzZSBoYW5kbGVyIGlzIGNsb25lZCBmb3IgZWFjaCBjb25uZWN0aW9uCisJcHJpdmF0ZSBzdGF0aWMgQ291bnREb3duTGF0Y2ggbGF0Y2ggPSBuZXcgQ291bnREb3duTGF0Y2goMSk7CisKKwlAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgaWRsZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJICAgIGNvbnQoKTsKKwkgICAgbGF0Y2guY291bnREb3duKCk7CisJICAgIGlkbGVXYWl0KCk7CisJICAgIHRyeSB7CisJCVRocmVhZC5zbGVlcCgyICogVElNRU9VVCk7CisJICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGV4KSB7IH0KKwkgICAgb2soKTsKKyAgICAgICAgfQorCisJQE92ZXJyaWRlCisJcHVibGljIHZvaWQgd2FpdEZvcklkbGUoKSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworCSAgICBsYXRjaC5hd2FpdCgpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDdXN0b20gaGFuZGxlci4gIERyb3AgdGhlIGNvbm5lY3Rpb24gYmVmb3JlIElETEUgc3RhcnRlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJTUFQSGFuZGxlckJlZm9yZUlkbGVEcm9wIGV4dGVuZHMKKwkJCQkJCQkgICAgSU1BUEhhbmRsZXJJZGxlIHsKKwkvLyBtdXN0IGJlIHN0YXRpYyBiZWNhdXNlIGhhbmRsZXIgaXMgY2xvbmVkIGZvciBlYWNoIGNvbm5lY3Rpb24KKwlwcml2YXRlIHN0YXRpYyBDb3VudERvd25MYXRjaCBsYXRjaCA9IG5ldyBDb3VudERvd25MYXRjaCgxKTsKKworCUBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBpZGxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkgICAgbGF0Y2guY291bnREb3duKCk7CisJICAgIGV4aXQoKTsKKyAgICAgICAgfQorCisJQE92ZXJyaWRlCisJcHVibGljIHZvaWQgd2FpdEZvcklkbGUoKSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworCSAgICBsYXRjaC5hd2FpdCgpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDdXN0b20gaGFuZGxlci4gIERyb3AgdGhlIGNvbm5lY3Rpb24gYWZ0ZXIgSURMRSBzdGFydGVkLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIElNQVBIYW5kbGVySWRsZURyb3AgZXh0ZW5kcyBJTUFQSGFuZGxlcklkbGUgeworCS8vIG11c3QgYmUgc3RhdGljIGJlY2F1c2UgaGFuZGxlciBpcyBjbG9uZWQgZm9yIGVhY2ggY29ubmVjdGlvbgorCXByaXZhdGUgc3RhdGljIENvdW50RG93bkxhdGNoIGxhdGNoID0gbmV3IENvdW50RG93bkxhdGNoKDEpOworCisJQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGlkbGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCSAgICBjb250KCk7CisJICAgIGxhdGNoLmNvdW50RG93bigpOworCSAgICBleGl0KCk7CisgICAgICAgIH0KKworCUBPdmVycmlkZQorCXB1YmxpYyB2b2lkIHdhaXRGb3JJZGxlKCkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKwkgICAgbGF0Y2guYXdhaXQoKTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3VzdG9tIGhhbmRsZXIuICBEcm9wIHRoZSBjb25uZWN0aW9uIGFmdGVyIERPTkUgcmVjZWl2ZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSU1BUEhhbmRsZXJEb25lRHJvcCBleHRlbmRzIElNQVBIYW5kbGVySWRsZSB7CisJLy8gbXVzdCBiZSBzdGF0aWMgYmVjYXVzZSBoYW5kbGVyIGlzIGNsb25lZCBmb3IgZWFjaCBjb25uZWN0aW9uCisJcHJpdmF0ZSBzdGF0aWMgQ291bnREb3duTGF0Y2ggbGF0Y2ggPSBuZXcgQ291bnREb3duTGF0Y2goMSk7CisKKwlAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgaWRsZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJICAgIGNvbnQoKTsKKwkgICAgbGF0Y2guY291bnREb3duKCk7CisJICAgIGlkbGVXYWl0KCk7CisJICAgIGV4aXQoKTsKKyAgICAgICAgfQorCisJQE92ZXJyaWRlCisJcHVibGljIHZvaWQgd2FpdEZvcklkbGUoKSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworCSAgICBsYXRjaC5hd2FpdCgpOworCX0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL2ltYXAvSU1BUElkbGVTdGF0ZVRlc3QuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9JTUFQSWRsZVN0YXRlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRlZjk1YWEKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL2ltYXAvSU1BUElkbGVTdGF0ZVRlc3QuamF2YQpAQCAtMCwwICsxLDExNyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwOSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuaW1hcDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQ291bnREb3duTGF0Y2g7CisKK2ltcG9ydCBqYXZheC5tYWlsLlNlc3Npb247CitpbXBvcnQgamF2YXgubWFpbC5TdG9yZTsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC5pbWFwLklNQVBTdG9yZTsKK2ltcG9ydCBjb20uc3VuLm1haWwudGVzdC5UZXN0U2VydmVyOworCitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LlJ1bGU7CitpbXBvcnQgb3JnLmp1bml0LnJ1bGVzLlRpbWVvdXQ7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuZmFpbDsKKworLyoqCisgKiBUZXN0IHRoYXQgSU1BUCBpZGxlIHN0YXRlIGlzIGhhbmRsZWQgcHJvcGVybHkuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBJTUFQSWRsZVN0YXRlVGVzdCB7CisKKyAgICAvLyB0aW1lb3V0IHRoZSB0ZXN0IGluIGNhc2Ugb2YgZGVhZGxvY2sKKyAgICBAUnVsZQorICAgIHB1YmxpYyBUaW1lb3V0IGRlYWRsb2NrVGltZW91dCA9IFRpbWVvdXQuc2Vjb25kcygyMCk7CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3QoKSB7CisgICAgICAgIFRlc3RTZXJ2ZXIgc2VydmVyID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZpbmFsIElNQVBIYW5kbGVySWRsZUJ5ZSBoYW5kbGVyID0gbmV3IElNQVBIYW5kbGVySWRsZUJ5ZSgpOworICAgICAgICAgICAgc2VydmVyID0gbmV3IFRlc3RTZXJ2ZXIoaGFuZGxlcik7CisgICAgICAgICAgICBzZXJ2ZXIuc3RhcnQoKTsKKworICAgICAgICAgICAgZmluYWwgUHJvcGVydGllcyBwcm9wZXJ0aWVzID0gbmV3IFByb3BlcnRpZXMoKTsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuaW1hcC5ob3N0IiwgImxvY2FsaG9zdCIpOworICAgICAgICAgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5pbWFwLnBvcnQiLCAiIiArIHNlcnZlci5nZXRQb3J0KCkpOworICAgICAgICAgICAgZmluYWwgU2Vzc2lvbiBzZXNzaW9uID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShwcm9wZXJ0aWVzKTsKKyAgICAgICAgICAgIC8vc2Vzc2lvbi5zZXREZWJ1Zyh0cnVlKTsKKworICAgICAgICAgICAgZmluYWwgSU1BUFN0b3JlIHN0b3JlID0gKElNQVBTdG9yZSlzZXNzaW9uLmdldFN0b3JlKCJpbWFwIik7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHN0b3JlLmNvbm5lY3QoInRlc3QiLCAidGVzdCIpOworCisJCS8vIGNyZWF0ZSBhIHRocmVhZCB0byBydW4gdGhlIElETEUgY29tbWFuZCBvbiB0aGUgU3RvcmUKKwkJVGhyZWFkIHQgPSBuZXcgVGhyZWFkKCkgeworCQkgICAgQE92ZXJyaWRlCisJCSAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisJCQl0cnkgeworCQkJICAgIHN0b3JlLmlkbGUoKTsKKwkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCQkJfQorCQkgICAgfQorCQl9OworCQl0LnN0YXJ0KCk7CisJCWhhbmRsZXIud2FpdEZvcklkbGUoKTsKKworCQkvLyBOb3cgYnJlYWsgaXQgb3V0IG9mIGlkbGUuCisJCS8vIE5lZWQgdG8gdXNlIGEgbWV0aG9kIHRoYXQgZG9lc24ndCBjaGVjayB0aGF0IHRoZSBTdG9yZQorCQkvLyBpcyBjb25uZWN0ZWQgZmlyc3QuCisJCXN0b3JlLmhhc0NhcGFiaWxpdHkoIlhYWCIpOworCQkvLyBubyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBtZWFucyB0aGUgYnVnIGlzIGZpeGVkIQorCisJICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCQlTeXN0ZW0ub3V0LnByaW50bG4oZXgpOworCQkvL2V4LnByaW50U3RhY2tUcmFjZSgpOworCQlmYWlsKGV4LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBzdG9yZS5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChmaW5hbCBFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgIGZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKHNlcnZlciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgc2VydmVyLnF1aXQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEN1c3RvbSBoYW5kbGVyLiAgU2ltdWxhdGVzIHRoZSBzZXJ2ZXIgc2VuZGluZyBhIEJZRSByZXNwb25zZQorICAgICAqIHRvIGFib3J0IGFuIElETEUuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSU1BUEhhbmRsZXJJZGxlQnllIGV4dGVuZHMgSU1BUEhhbmRsZXIgeworCS8vIG11c3QgYmUgc3RhdGljIGJlY2F1c2UgaGFuZGxlciBpcyBjbG9uZWQgZm9yIGVhY2ggY29ubmVjdGlvbgorCXByaXZhdGUgc3RhdGljIENvdW50RG93bkxhdGNoIGxhdGNoID0gbmV3IENvdW50RG93bkxhdGNoKDEpOworCisJQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGlkbGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCSAgICBjb250KCk7CisJICAgIGxhdGNoLmNvdW50RG93bigpOworCSAgICAvLyBkb24ndCB3YWl0IGZvciBET05FLCBqdXN0IGNsb3NlIHRoZSBjb25uZWN0aW9uIG5vdworCSAgICBieWUoImNsb3NpbmciKTsKKyAgICAgICAgfQorCisJcHVibGljIHZvaWQgd2FpdEZvcklkbGUoKSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworCSAgICBsYXRjaC5hd2FpdCgpOworCX0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL2ltYXAvSU1BUElkbGVVbnRhZ2dlZFJlc3BvbnNlVGVzdC5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0lNQVBJZGxlVW50YWdnZWRSZXNwb25zZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNmViYmZkCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0lNQVBJZGxlVW50YWdnZWRSZXNwb25zZVRlc3QuamF2YQpAQCAtMCwwICsxLDEzNyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwOSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuaW1hcDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQ291bnREb3duTGF0Y2g7CisKK2ltcG9ydCBqYXZheC5tYWlsLkZvbGRlcjsKK2ltcG9ydCBqYXZheC5tYWlsLlNlc3Npb247CitpbXBvcnQgamF2YXgubWFpbC5TdG9yZTsKK2ltcG9ydCBqYXZheC5tYWlsLk1lc3NhZ2U7CitpbXBvcnQgamF2YXgubWFpbC5GZXRjaFByb2ZpbGU7CisKK2ltcG9ydCBjb20uc3VuLm1haWwudGVzdC5UZXN0U2VydmVyOworCitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LlJ1bGU7CitpbXBvcnQgb3JnLmp1bml0LnJ1bGVzLlRpbWVvdXQ7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RXF1YWxzOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmZhaWw7CisKKy8qKgorICogVGVzdCB1bnRhZ2dlZCByZXNwb25zZXMgYmVmb3JlIElETEUgY29udGludWF0aW9uLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgSU1BUElkbGVVbnRhZ2dlZFJlc3BvbnNlVGVzdCB7CisKKyAgICAvLyB0aW1lb3V0IHRoZSB0ZXN0IGluIGNhc2Ugb2YgZGVhZGxvY2sKKyAgICBAUnVsZQorICAgIHB1YmxpYyBUaW1lb3V0IGRlYWRsb2NrVGltZW91dCA9IFRpbWVvdXQuc2Vjb25kcygyMCk7CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3QoKSB7CisgICAgICAgIFRlc3RTZXJ2ZXIgc2VydmVyID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZpbmFsIElNQVBIYW5kbGVySWRsZUV4aXN0cyBoYW5kbGVyID0gbmV3IElNQVBIYW5kbGVySWRsZUV4aXN0cygpOworICAgICAgICAgICAgc2VydmVyID0gbmV3IFRlc3RTZXJ2ZXIoaGFuZGxlcik7CisgICAgICAgICAgICBzZXJ2ZXIuc3RhcnQoKTsKKworICAgICAgICAgICAgZmluYWwgUHJvcGVydGllcyBwcm9wZXJ0aWVzID0gbmV3IFByb3BlcnRpZXMoKTsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuaW1hcC5ob3N0IiwgImxvY2FsaG9zdCIpOworICAgICAgICAgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5pbWFwLnBvcnQiLCAiIiArIHNlcnZlci5nZXRQb3J0KCkpOworICAgICAgICAgICAgZmluYWwgU2Vzc2lvbiBzZXNzaW9uID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShwcm9wZXJ0aWVzKTsKKyAgICAgICAgICAgIC8vc2Vzc2lvbi5zZXREZWJ1Zyh0cnVlKTsKKworICAgICAgICAgICAgZmluYWwgU3RvcmUgc3RvcmUgPSBzZXNzaW9uLmdldFN0b3JlKCJpbWFwIik7CisJICAgIEZvbGRlciBmb2xkZXIwID0gbnVsbDsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc3RvcmUuY29ubmVjdCgidGVzdCIsICJ0ZXN0Iik7CisgICAgICAgICAgICAgICAgZmluYWwgRm9sZGVyIGZvbGRlciA9IHN0b3JlLmdldEZvbGRlcigiSU5CT1giKTsKKwkJZm9sZGVyMCA9IGZvbGRlcjsKKyAgICAgICAgICAgICAgICBmb2xkZXIub3BlbihGb2xkZXIuUkVBRF9PTkxZKTsKKworCQkvLyBjcmVhdGUgYSB0aHJlYWQgdG8gbWFrZSBzdXJlIHdlJ3JlIGtpY2tlZCBvdXQgb2YgaWRsZQorCQlUaHJlYWQgdCA9IG5ldyBUaHJlYWQoKSB7CisJCSAgICBAT3ZlcnJpZGUKKwkJICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKwkJCXRyeSB7CisJCQkgICAgaGFuZGxlci53YWl0Rm9ySWRsZSgpOworCQkJICAgIC8vIG5vdyBkbyBzb21ldGhpbmcgdGhhdCBpcyBzdXJlIHRvIHRvdWNoIHRoZSBzZXJ2ZXIKKwkJCSAgICBGZXRjaFByb2ZpbGUgZnAgPSBuZXcgRmV0Y2hQcm9maWxlKCk7CisJCQkgICAgZnAuYWRkKEZldGNoUHJvZmlsZS5JdGVtLkVOVkVMT1BFKTsKKwkJCSAgICBmb2xkZXIuZmV0Y2goZm9sZGVyLmdldE1lc3NhZ2VzKCksIGZwKTsKKwkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCQkJfQorCQkgICAgfQorCQl9OworCQl0LnN0YXJ0KCk7CisKKwkJKChjb20uc3VuLm1haWwuaW1hcC5JTUFQRm9sZGVyKWZvbGRlcikuaWRsZSgpOworCisJCWFzc2VydEVxdWFscygibWVzc2FnZSBjb3VudCIsIDEsIGZvbGRlci5nZXRNZXNzYWdlQ291bnQoKSk7CisKKwkgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJCVN5c3RlbS5vdXQucHJpbnRsbihleCk7CisJCS8vZXgucHJpbnRTdGFja1RyYWNlKCk7CisJCWZhaWwoZXgudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworCQlpZiAoZm9sZGVyMCAhPSBudWxsKQorCQkgICAgZm9sZGVyMC5jbG9zZShmYWxzZSk7CisgICAgICAgICAgICAgICAgc3RvcmUuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoZmluYWwgRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICBmYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChzZXJ2ZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHNlcnZlci5xdWl0KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDdXN0b20gaGFuZGxlci4gIFJldHVybnMgdW50YWdnZWQgcmVzcG9uc2VzIGJlZm9yZSBjb250aW51YXRpb24sCisgICAgICogZm9sbG93ZWQgYnkgYSBmbGFnIGNoYW5nZSBmb3Igb25lIG9mIHRoZSBuZXcgbWVzc2FnZXMsIHRvIG1ha2UKKyAgICAgKiBzdXJlIHRoZSBub3RpZmljYXRpb24gb2YgdGhlIG5ldyBtZXNzYWdlIGlzIHNlZW4uCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSU1BUEhhbmRsZXJJZGxlRXhpc3RzIGV4dGVuZHMgSU1BUEhhbmRsZXIgeworCS8vIG11c3QgYmUgc3RhdGljIGJlY2F1c2UgaGFuZGxlciBpcyBjbG9uZWQgZm9yIGVhY2ggY29ubmVjdGlvbgorCXByaXZhdGUgc3RhdGljIENvdW50RG93bkxhdGNoIGxhdGNoID0gbmV3IENvdW50RG93bkxhdGNoKDEpOworCisJQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGV4YW1pbmUoU3RyaW5nIGxpbmUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJICAgIG51bWJlck9mTWVzc2FnZXMgPSAxOworCSAgICBzdXBlci5leGFtaW5lKGxpbmUpOworCX0KKworCUBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBpZGxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHVudGFnZ2VkKCIxIEVYSVNUUyIpOworICAgICAgICAgICAgdW50YWdnZWQoIjEgUkVDRU5UIik7CisJICAgIGNvbnQoKTsKKyAgICAgICAgICAgIHVudGFnZ2VkKCIxIEZFVENIIChGTEFHUyAoXFxSZWNlbnQgXFxTZWVuKSkiKTsKKwkgICAgbGF0Y2guY291bnREb3duKCk7CisJICAgIGlkbGVXYWl0KCk7CisJICAgIG9rKCk7CisgICAgICAgIH0KKworCXB1YmxpYyB2b2lkIHdhaXRGb3JJZGxlKCkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKwkgICAgbGF0Y2guYXdhaXQoKTsKKwl9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0lNQVBMb2dpbkNhcGFiaWxpdGllc1Rlc3QuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9JTUFQTG9naW5DYXBhYmlsaXRpZXNUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTdmYzVlOQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9JTUFQTG9naW5DYXBhYmlsaXRpZXNUZXN0LmphdmEKQEAgLTAsMCArMSwxMjggQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDksIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmltYXA7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOworCitpbXBvcnQgamF2YXgubWFpbC5TZXNzaW9uOworaW1wb3J0IGphdmF4Lm1haWwuU3RvcmU7CisKK2ltcG9ydCBjb20uc3VuLm1haWwudGVzdC5UZXN0U2VydmVyOworCitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LlJ1bGU7CitpbXBvcnQgb3JnLmp1bml0LnJ1bGVzLlRpbWVvdXQ7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuZmFpbDsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRFcXVhbHM7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VHJ1ZTsKKworLyoqCisgKiBUZXN0IHRoYXQgY2FwYWJpbGl0aWVzIGFyZSB1cGRhdGVkIGFmdGVyIGxvZ2luLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgSU1BUExvZ2luQ2FwYWJpbGl0aWVzVGVzdCB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTkVXQ0FQID0gIk5FV0NBUCI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVElNRU9VVCA9IDEwMDA7CS8vIDEgc2Vjb25kCisKKyAgICAvLyB0aW1lb3V0IHRoZSB0ZXN0IGluIGNhc2Ugb2YgZGVhZGxvY2sKKyAgICBAUnVsZQorICAgIHB1YmxpYyBUaW1lb3V0IGRlYWRsb2NrVGltZW91dCA9IFRpbWVvdXQubWlsbGlzKDUgKiBUSU1FT1VUKTsKKworICAgIC8qKgorICAgICAqIFRlc3QgdW50YWdnZWQgQ0FQQUJJTElUWSByZXNwb25zZSBhZnRlciBMT0dJTi4KKyAgICAgKiBUaGlzIGlzIGlsbGVnYWwsIGJ1dCBtYWlsLnJ1IGFuZCBBT0wgZG8gaXQuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VW50YWdnZWRDYXBhYmlsaXR5QWZ0ZXJMb2dpbigpIHsKKwl0ZXN0KG5ldyBJTUFQSGFuZGxlcigpIHsKKwkJCUBPdmVycmlkZQorCQkJcHVibGljIHZvaWQgbG9naW4oKSB0aHJvd3MgSU9FeGNlcHRpb24geworCQkJICAgIHVudGFnZ2VkKCJDQVBBQklMSVRZICIgKyBjYXBhYmlsaXRpZXMgKworCQkJCQkJCQkiICIgKyBORVdDQVApOworCQkJICAgIG9rKCJMT0dJTiBjb21wbGV0ZWQiKTsKKwkJCX0KKwkJICAgIH0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgbXVsdGlwbGUgdW50YWdnZWQgQ0FQQUJJTElUWSByZXNwb25zZXMgYWZ0ZXIgTE9HSU4uCisgICAgICogVGhpcyBzaG91bGQgTkVWRVIgaGFwcGVuLCBidXQgd2UgaGFuZGxlIGl0IGp1c3QgaW4gY2FzZS4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RNdWx0aXBsZVVudGFnZ2VkQ2FwYWJpbGl0eUFmdGVyTG9naW4oKSB7CisJdGVzdChuZXcgSU1BUEhhbmRsZXIoKSB7CisJCQlAT3ZlcnJpZGUKKwkJCXB1YmxpYyB2b2lkIGxvZ2luKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkJCSAgICB1bnRhZ2dlZCgiQ0FQQUJJTElUWSAiICsgY2FwYWJpbGl0aWVzKTsKKwkJCSAgICB1bnRhZ2dlZCgiQ0FQQUJJTElUWSAiICsgTkVXQ0FQKTsKKwkJCSAgICBvaygiTE9HSU4gY29tcGxldGVkIik7CisJCQl9CisJCSAgICB9KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHVudGFnZ2VkIENBUEFCSUxJVFkgcmVzcG9uc2UgYWZ0ZXIgQVVUSEVOVElDQVRFLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFVudGFnZ2VkQ2FwYWJpbGl0eUFmdGVyQXV0aGVudGljYXRlKCkgeworCXRlc3QobmV3IElNQVBIYW5kbGVyKCkgeworCQkJe3sgY2FwYWJpbGl0aWVzICs9ICIgQVVUSD1QTEFJTiI7IH19CisJCQlAT3ZlcnJpZGUKKwkJCXB1YmxpYyB2b2lkIGF1dGhwbGFpbihTdHJpbmcgaXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJCQkgICAgdW50YWdnZWQoIkNBUEFCSUxJVFkgIiArIGNhcGFiaWxpdGllcyArCisJCQkJCQkJCSIgIiArIE5FV0NBUCk7CisJCQkgICAgb2soIkFVVEhFTlRJQ0FURSBjb21wbGV0ZWQiKTsKKwkJCX0KKwkJICAgIH0pOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0KElNQVBIYW5kbGVyIGhhbmRsZXIpIHsKKwlUZXN0U2VydmVyIHNlcnZlciA9IG51bGw7CisJdHJ5IHsKKwkgICAgc2VydmVyID0gbmV3IFRlc3RTZXJ2ZXIoaGFuZGxlcik7CisJICAgIHNlcnZlci5zdGFydCgpOworCisJICAgIGZpbmFsIFByb3BlcnRpZXMgcHJvcGVydGllcyA9IG5ldyBQcm9wZXJ0aWVzKCk7CisJICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuaW1hcC5ob3N0IiwgImxvY2FsaG9zdCIpOworCSAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLmltYXAucG9ydCIsICIiICsgc2VydmVyLmdldFBvcnQoKSk7CisJICAgIC8vcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5kZWJ1Zy5hdXRoIiwgInRydWUiKTsKKwkgICAgZmluYWwgU2Vzc2lvbiBzZXNzaW9uID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShwcm9wZXJ0aWVzKTsKKwkgICAgLy9zZXNzaW9uLnNldERlYnVnKHRydWUpOworCisJICAgIGZpbmFsIElNQVBTdG9yZSBzdG9yZSA9IChJTUFQU3RvcmUpc2Vzc2lvbi5nZXRTdG9yZSgiaW1hcCIpOworCSAgICB0cnkgeworCQlzdG9yZS5jb25uZWN0KCJ0ZXN0IiwgInRlc3QiKTsKKwkJYXNzZXJ0VHJ1ZShzdG9yZS5oYXNDYXBhYmlsaXR5KE5FV0NBUCkpOworCSAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKwkJU3lzdGVtLm91dC5wcmludGxuKGV4KTsKKwkJLy9leC5wcmludFN0YWNrVHJhY2UoKTsKKwkJZmFpbChleC50b1N0cmluZygpKTsKKwkgICAgfSBmaW5hbGx5IHsKKwkJc3RvcmUuY2xvc2UoKTsKKwkgICAgfQorCX0gY2F0Y2ggKGZpbmFsIEV4Y2VwdGlvbiBlKSB7CisJICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisJICAgIGZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKHNlcnZlciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgc2VydmVyLnF1aXQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9JTUFQTG9naW5GYWlsdXJlVGVzdC5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0lNQVBMb2dpbkZhaWx1cmVUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGE1YjI4MgotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9JTUFQTG9naW5GYWlsdXJlVGVzdC5qYXZhCkBAIC0wLDAgKzEsODkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDksIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmltYXA7CisKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7CisKK2ltcG9ydCBqYXZheC5tYWlsLlNlc3Npb247CitpbXBvcnQgamF2YXgubWFpbC5TdG9yZTsKK2ltcG9ydCBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC50ZXN0LlNhdmVkU29ja2V0RmFjdG9yeTsKK2ltcG9ydCBjb20uc3VuLm1haWwudGVzdC5UZXN0U2VydmVyOworCitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VHJ1ZTsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRGYWxzZTsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5mYWlsOworCisvKioKKyAqIFRlc3QgdGhhdCBsb2dpbiBmYWlsdXJlcyBhcmUgaGFuZGxlZCBjb3JyZWN0bHkuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBJTUFQTG9naW5GYWlsdXJlVGVzdCB7CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHRoYXQgbG9naW4gZmFpbHVyZXMgd2hlbiBubyBsb2dpbiBtZXRob2RzIGFyZSBzdXBwb3J0ZWQKKyAgICAgKiBjYXVzZSB0aGUgc29ja2V0IHRvIGJlIGNsb3NlZC4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RTb2NrZXRDbG9zZWQoKSB7CisJVGVzdFNlcnZlciBzZXJ2ZXIgPSBudWxsOworCXRyeSB7CisJICAgIGZpbmFsIElNQVBIYW5kbGVyIGhhbmRsZXIgPSBuZXcgSU1BUEhhbmRsZXIoKSB7CisJCUBPdmVycmlkZQorCQlwdWJsaWMgdm9pZCBzZW5kR3JlZXRpbmdzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkJICAgIGNhcGFiaWxpdGllcyA9ICJJTUFQNFJFVjEgTE9HSU5ESVNBQkxFRCI7CisJCSAgICBzdXBlci5zZW5kR3JlZXRpbmdzKCk7CisJCX0KKwkgICAgfTsKKwkgICAgc2VydmVyID0gbmV3IFRlc3RTZXJ2ZXIoaGFuZGxlcik7CisJICAgIHNlcnZlci5zdGFydCgpOworCisJICAgIFNhdmVkU29ja2V0RmFjdG9yeSBzc2YgPSBuZXcgU2F2ZWRTb2NrZXRGYWN0b3J5KCk7CisJICAgIFByb3BlcnRpZXMgcHJvcGVydGllcyA9IG5ldyBQcm9wZXJ0aWVzKCk7CisJICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuaW1hcC5ob3N0IiwgImxvY2FsaG9zdCIpOworCSAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLmltYXAucG9ydCIsICIiICsgc2VydmVyLmdldFBvcnQoKSk7CisJICAgIHByb3BlcnRpZXMucHV0KCJtYWlsLmltYXAuc29ja2V0RmFjdG9yeSIsIHNzZik7CisJICAgIGZpbmFsIFNlc3Npb24gc2Vzc2lvbiA9IFNlc3Npb24uZ2V0SW5zdGFuY2UocHJvcGVydGllcyk7CisJICAgIC8vc2Vzc2lvbi5zZXREZWJ1Zyh0cnVlKTsKKworCSAgICBmaW5hbCBTdG9yZSBzdG9yZSA9IHNlc3Npb24uZ2V0U3RvcmUoImltYXAiKTsKKwkgICAgdHJ5IHsKKwkJc3RvcmUuY29ubmVjdCgidGVzdCIsICJ0ZXN0Iik7CisJCWZhaWwoImxvZ2luIGRpZCBub3QgZmFpbCIpOworCSAgICB9IGNhdGNoIChNZXNzYWdpbmdFeGNlcHRpb24gbWV4KSB7CisJCS8vIHRoaXMgaXMgd2hhdCB3ZSBleHBlY3QsIG5vdyBjaGVjayB0aGF0IHRoZSBzb2NrZXQgaXMgY2xvc2VkCisJCWFzc2VydFRydWUoc3NmLmdldFNvY2tldCgpLmlzQ2xvc2VkKCkpOworCSAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKwkJU3lzdGVtLm91dC5wcmludGxuKGV4KTsKKwkJLy9leC5wcmludFN0YWNrVHJhY2UoKTsKKwkJZmFpbChleC50b1N0cmluZygpKTsKKwkgICAgfSBmaW5hbGx5IHsKKwkJc3RvcmUuY2xvc2UoKTsKKwkgICAgfQorCisJfSBjYXRjaCAoZmluYWwgRXhjZXB0aW9uIGUpIHsKKwkgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKwkgICAgZmFpbChlLmdldE1lc3NhZ2UoKSk7CisJfSBmaW5hbGx5IHsKKwkgICAgaWYgKHNlcnZlciAhPSBudWxsKSB7CisJCXNlcnZlci5xdWl0KCk7CisJICAgIH0KKwl9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0lNQVBMb2dpbkhhbmRsZXIuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9JTUFQTG9naW5IYW5kbGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTMyYTcyZgotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9JTUFQTG9naW5IYW5kbGVyLmphdmEKQEAgLTAsMCArMSw2MyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwOSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuaW1hcDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5TdGFuZGFyZENoYXJzZXRzOworCitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuQkFTRTY0RGVjb2RlclN0cmVhbTsKKworLyoqCisgKiBIYW5kbGUgSU1BUCBjb25uZWN0aW9uIHdpdGggTE9HSU4gYXV0aGVudGljYXRpb24uCisgKgorICogQGF1dGhvciBCaWxsIFNoYW5ub24KKyAqLworcHVibGljIGNsYXNzIElNQVBMb2dpbkhhbmRsZXIgZXh0ZW5kcyBJTUFQSGFuZGxlciB7CisKKyAgICBwcm90ZWN0ZWQgU3RyaW5nIHVzZXJuYW1lID0gInRlc3QiOworICAgIHByb3RlY3RlZCBTdHJpbmcgcGFzc3dvcmQgPSAidGVzdCI7CisKKyAgICBwdWJsaWMgSU1BUExvZ2luSGFuZGxlcigpIHsKKwljYXBhYmlsaXRpZXMgKz0gIiBMT0dJTkRJU0FCTEVEIEFVVEg9TE9HSU4iOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFVVEhFTlRJQ0FURSBMT0dJTiBjb21tYW5kLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiB1bmFibGUgdG8gcmVhZC93cml0ZSB0byBzb2NrZXQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhdXRobG9naW4oU3RyaW5nIGlyKSB0aHJvd3MgSU9FeGNlcHRpb24geworCWlmIChpciAhPSBudWxsKQorCSAgICBiYWQoIkFVVEhFTlRJQ0FURSBMT0dJTiBkb2VzIG5vdCBzdXBwb3J0IGluaXRpYWwgcmVzcG9uc2UiKTsKKwljb250KGJhc2U2NGVuY29kZSgiVXNlcm5hbWUiKSk7CisJU3RyaW5nIHJlc3AgPSByZWFkTGluZSgpOworCVN0cmluZyB1ID0gbmV3IFN0cmluZyhCQVNFNjREZWNvZGVyU3RyZWFtLmRlY29kZSgKKwkJCQkgICAgcmVzcC5nZXRCeXRlcyhTdGFuZGFyZENoYXJzZXRzLlVTX0FTQ0lJKSksCisJCQkJU3RhbmRhcmRDaGFyc2V0cy5VVEZfOCk7CisJY29udChiYXNlNjRlbmNvZGUoIlBhc3N3b3JkIikpOworCXJlc3AgPSByZWFkTGluZSgpOworCVN0cmluZyBwID0gbmV3IFN0cmluZyhCQVNFNjREZWNvZGVyU3RyZWFtLmRlY29kZSgKKwkJCQkgICAgcmVzcC5nZXRCeXRlcyhTdGFuZGFyZENoYXJzZXRzLlVTX0FTQ0lJKSksCisJCQkJU3RhbmRhcmRDaGFyc2V0cy5VVEZfOCk7CisJLy9TeXN0ZW0ub3V0LnByaW50ZigiVVNFUjogJXMsIFBBU1NXT1JEOiAlcyVuIiwgdSwgcCk7CisJaWYgKCF1LmVxdWFscyh1c2VybmFtZSkgfHwgIXAuZXF1YWxzKHBhc3N3b3JkKSkgeworCSAgICBubygiYXV0aGVudGljYXRpb24gZmFpbGVkIik7CisJICAgIHJldHVybjsKKwl9CisgICAgICAgIG9rKCJbQ0FQQUJJTElUWSAiICsgY2FwYWJpbGl0aWVzICsgIl0iKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL2ltYXAvSU1BUExvZ2luUmVmZXJyYWxUZXN0LmphdmEgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL2ltYXAvSU1BUExvZ2luUmVmZXJyYWxUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGY5Y2M2MwotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9JTUFQTG9naW5SZWZlcnJhbFRlc3QuamF2YQpAQCAtMCwwICsxLDE2MSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwOSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuaW1hcDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7CisKK2ltcG9ydCBqYXZheC5tYWlsLlNlc3Npb247CitpbXBvcnQgamF2YXgubWFpbC5TdG9yZTsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC5pbWFwLlJlZmVycmFsRXhjZXB0aW9uOworCitpbXBvcnQgY29tLnN1bi5tYWlsLnRlc3QuVGVzdFNlcnZlcjsKKworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5SdWxlOworaW1wb3J0IG9yZy5qdW5pdC5ydWxlcy5UaW1lb3V0OworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmZhaWw7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RXF1YWxzOworCisvKioKKyAqIFRlc3QgSU1BUCBsb2dpbiByZWZlcnJhbHMgKFJGQyAyMjIxKS4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIElNQVBMb2dpblJlZmVycmFsVGVzdCB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVGRVJSQUxfVVJMID0gImltYXA6Ly90ZXN0QHNlcnZlci8iOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBSRUZFUlJBTF9NU0cgPSAidHJ5IHNlcnZlciI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJFRkVSUkFMID0KKwkJCSAgICAiW1JFRkVSUkFMICIgKyBSRUZFUlJBTF9VUkwgKyAiXSAiICsgUkVGRVJSQUxfTVNHOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFRJTUVPVVQgPSAxMDAwOwkvLyAxIHNlY29uZAorCisgICAgLy8gdGltZW91dCB0aGUgdGVzdCBpbiBjYXNlIG9mIGRlYWRsb2NrCisgICAgQFJ1bGUKKyAgICBwdWJsaWMgVGltZW91dCBkZWFkbG9ja1RpbWVvdXQgPSBUaW1lb3V0Lm1pbGxpcyg1ICogVElNRU9VVCk7CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHJlZmVycmFsIGluIEJZRSB3aGVuIGNvbm5lY3RpbmcuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29ubmVjdFJlZmVycmFsKCkgeworCXRlc3QobmV3IElNQVBIYW5kbGVyKCkgeworCQkJQE92ZXJyaWRlCisJCQlwdWJsaWMgdm9pZCBzZW5kR3JlZXRpbmdzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkJCSAgICBieWUoUkVGRVJSQUwpOworCQkJfQorCQkgICAgfSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCByZWZlcnJhbCBpbiBOTyByZXNwb25zZSB0byBMT0dJTi4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RMb2dpblJlZmVycmFsKCkgeworCXRlc3QobmV3IElNQVBIYW5kbGVyKCkgeworCQkJe3sgY2FwYWJpbGl0aWVzICs9ICIgTE9HSU4tUkVGRVJSQUxTIjsgfX0KKwkJCUBPdmVycmlkZQorCQkJcHVibGljIHZvaWQgbG9naW4oKSB0aHJvd3MgSU9FeGNlcHRpb24geworCQkJICAgIG5vKFJFRkVSUkFMKTsKKwkJCX0KKwkJICAgIH0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgcmVmZXJyYWwgaW4gT0sgcmVzcG9uc2UgdG8gTE9HSU4uCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TG9naW5Pa1JlZmVycmFsKCkgeworCXRlc3QobmV3IElNQVBIYW5kbGVyKCkgeworCQkJe3sgY2FwYWJpbGl0aWVzICs9ICIgTE9HSU4tUkVGRVJSQUxTIjsgfX0KKwkJCUBPdmVycmlkZQorCQkJcHVibGljIHZvaWQgbG9naW4oKSB0aHJvd3MgSU9FeGNlcHRpb24geworCQkJICAgIG9rKFJFRkVSUkFMKTsKKwkJCX0KKwkJICAgIH0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgcmVmZXJyYWwgaW4gTk8gcmVzcG9uc2UgdG8gQVVUSEVOVElDQVRFIFBMQUlOLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFBsYWluUmVmZXJyYWwoKSB7CisJdGVzdChuZXcgSU1BUEhhbmRsZXIoKSB7CisJCQl7eyBjYXBhYmlsaXRpZXMgKz0gIiBMT0dJTi1SRUZFUlJBTFMgQVVUSD1QTEFJTiI7IH19CisJCQlAT3ZlcnJpZGUKKwkJCXB1YmxpYyB2b2lkIGF1dGhwbGFpbihTdHJpbmcgaXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJCQkgICAgbm8oUkVGRVJSQUwpOworCQkJfQorCQkgICAgfSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCByZWZlcnJhbCBpbiBPSyByZXNwb25zZSB0byBBVVRIRU5USUNBVEUgUExBSU4uCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UGxhaW5Pa1JlZmVycmFsKCkgeworCXRlc3QobmV3IElNQVBIYW5kbGVyKCkgeworCQkJe3sgY2FwYWJpbGl0aWVzICs9ICIgTE9HSU4tUkVGRVJSQUxTIEFVVEg9UExBSU4iOyB9fQorCQkJQE92ZXJyaWRlCisJCQlwdWJsaWMgdm9pZCBhdXRocGxhaW4oU3RyaW5nIGlyKSB0aHJvd3MgSU9FeGNlcHRpb24geworCQkJICAgIGlmIChpciA9PSBudWxsKSB7CisJCQkJY29udCgiIik7CisJCQkJU3RyaW5nIHJlc3AgPSByZWFkTGluZSgpOworCQkJICAgIH0KKwkJCSAgICBvayhSRUZFUlJBTCk7CisJCQl9CisJCSAgICB9KTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdChJTUFQSGFuZGxlciBoYW5kbGVyKSB7CisJVGVzdFNlcnZlciBzZXJ2ZXIgPSBudWxsOworCXRyeSB7CisJICAgIHNlcnZlciA9IG5ldyBUZXN0U2VydmVyKGhhbmRsZXIpOworCSAgICBzZXJ2ZXIuc3RhcnQoKTsKKworCSAgICBmaW5hbCBQcm9wZXJ0aWVzIHByb3BlcnRpZXMgPSBuZXcgUHJvcGVydGllcygpOworCSAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLmltYXAuaG9zdCIsICJsb2NhbGhvc3QiKTsKKwkgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5pbWFwLnBvcnQiLCAiIiArIHNlcnZlci5nZXRQb3J0KCkpOworCSAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLmltYXAucmVmZXJyYWxleGNlcHRpb24iLCAidHJ1ZSIpOworCSAgICBmaW5hbCBTZXNzaW9uIHNlc3Npb24gPSBTZXNzaW9uLmdldEluc3RhbmNlKHByb3BlcnRpZXMpOworCSAgICAvL3Nlc3Npb24uc2V0RGVidWcodHJ1ZSk7CisKKwkgICAgZmluYWwgSU1BUFN0b3JlIHN0b3JlID0gKElNQVBTdG9yZSlzZXNzaW9uLmdldFN0b3JlKCJpbWFwIik7CisJICAgIHRyeSB7CisJCXN0b3JlLmNvbm5lY3QoInRlc3QiLCAidGVzdCIpOworCQlmYWlsKCJjb25uZWN0IHN1Y2NlZWRlZCIpOworCSAgICB9IGNhdGNoIChSZWZlcnJhbEV4Y2VwdGlvbiBleCkgeworCQkvLyBzdWNjZXNzIQorCQlhc3NlcnRFcXVhbHMoZXguZ2V0VXJsKCksIFJFRkVSUkFMX1VSTCk7CisJCWFzc2VydEVxdWFscyhleC5nZXRUZXh0KCksIFJFRkVSUkFMX01TRyk7CisJICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCQlTeXN0ZW0ub3V0LnByaW50bG4oZXgpOworCQkvL2V4LnByaW50U3RhY2tUcmFjZSgpOworCQlmYWlsKGV4LnRvU3RyaW5nKCkpOworCSAgICB9IGZpbmFsbHkgeworCQlzdG9yZS5jbG9zZSgpOworCSAgICB9CisJfSBjYXRjaCAoZmluYWwgRXhjZXB0aW9uIGUpIHsKKwkgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKwkgICAgZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoc2VydmVyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBzZXJ2ZXIucXVpdCgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0lNQVBNZXNzYWdlTnVtYmVyT3V0T2ZSYW5nZVRlc3QuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9JTUFQTWVzc2FnZU51bWJlck91dE9mUmFuZ2VUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjg4YmVmMgotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9JTUFQTWVzc2FnZU51bWJlck91dE9mUmFuZ2VUZXN0LmphdmEKQEAgLTAsMCArMSwxMTcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDksIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmltYXA7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOworCitpbXBvcnQgamF2YXgubWFpbC5Gb2xkZXI7CitpbXBvcnQgamF2YXgubWFpbC5TZXNzaW9uOworaW1wb3J0IGphdmF4Lm1haWwuU3RvcmU7CitpbXBvcnQgamF2YXgubWFpbC5NZXNzYWdlOworaW1wb3J0IGphdmF4Lm1haWwuRmxhZ3M7CitpbXBvcnQgamF2YXgubWFpbC5zZWFyY2guRmxhZ1Rlcm07CisKK2ltcG9ydCBjb20uc3VuLm1haWwudGVzdC5UZXN0U2VydmVyOworCitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LlJ1bGU7CitpbXBvcnQgb3JnLmp1bml0LnJ1bGVzLlRpbWVvdXQ7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RXF1YWxzOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmZhaWw7CisKKy8qKgorICogVGVzdCBGRVRDSCBhbmQgU0VBUkNIIHJlc3BvbnNlcyB3aXRoIGEgbWVzc2FnZSBudW1iZXIgdGhhdCdzIG91dCBvZiByYW5nZS4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIElNQVBNZXNzYWdlTnVtYmVyT3V0T2ZSYW5nZVRlc3QgeworCisgICAgLy8gdGltZW91dCB0aGUgdGVzdCBpbiBjYXNlIG9mIGRlYWRsb2NrCisgICAgQFJ1bGUKKyAgICBwdWJsaWMgVGltZW91dCBkZWFkbG9ja1RpbWVvdXQgPSBUaW1lb3V0LnNlY29uZHMoMjApOworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0KCkgeworICAgICAgICBUZXN0U2VydmVyIHNlcnZlciA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaW5hbCBJTUFQSGFuZGxlckJhZCBoYW5kbGVyID0gbmV3IElNQVBIYW5kbGVyQmFkKCk7CisgICAgICAgICAgICBzZXJ2ZXIgPSBuZXcgVGVzdFNlcnZlcihoYW5kbGVyKTsKKyAgICAgICAgICAgIHNlcnZlci5zdGFydCgpOworCisgICAgICAgICAgICBmaW5hbCBQcm9wZXJ0aWVzIHByb3BlcnRpZXMgPSBuZXcgUHJvcGVydGllcygpOworICAgICAgICAgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5pbWFwLmhvc3QiLCAibG9jYWxob3N0Iik7CisgICAgICAgICAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLmltYXAucG9ydCIsICIiICsgc2VydmVyLmdldFBvcnQoKSk7CisgICAgICAgICAgICBmaW5hbCBTZXNzaW9uIHNlc3Npb24gPSBTZXNzaW9uLmdldEluc3RhbmNlKHByb3BlcnRpZXMpOworICAgICAgICAgICAgLy9zZXNzaW9uLnNldERlYnVnKHRydWUpOworCisgICAgICAgICAgICBmaW5hbCBTdG9yZSBzdG9yZSA9IHNlc3Npb24uZ2V0U3RvcmUoImltYXAiKTsKKwkgICAgRm9sZGVyIGZvbGRlciA9IG51bGw7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHN0b3JlLmNvbm5lY3QoInRlc3QiLCAidGVzdCIpOworICAgICAgICAgICAgICAgIGZvbGRlciA9IHN0b3JlLmdldEZvbGRlcigiSU5CT1giKTsKKyAgICAgICAgICAgICAgICBmb2xkZXIub3BlbihGb2xkZXIuUkVBRF9PTkxZKTsKKwkJTWVzc2FnZSBtc2cgPSBmb2xkZXIuZ2V0TWVzc2FnZSgxKTsKKwkJRmxhZ3MgZiA9IG1zZy5nZXRGbGFncygpOworCQlNZXNzYWdlW10gbXNncyA9IGZvbGRlci5zZWFyY2goCisJCQkgICAgbmV3IEZsYWdUZXJtKG5ldyBGbGFncyhGbGFncy5GbGFnLlJFQ0VOVCksIHRydWUpKTsKKwkJYXNzZXJ0RXF1YWxzKDEsIG1zZ3MubGVuZ3RoKTsKKwkJYXNzZXJ0RXF1YWxzKG1zZywgbXNnc1swXSk7CisJICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCQlTeXN0ZW0ub3V0LnByaW50bG4oZXgpOworCQkvL2V4LnByaW50U3RhY2tUcmFjZSgpOworCQlmYWlsKGV4LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKwkJaWYgKGZvbGRlciAhPSBudWxsKQorCQkgICAgZm9sZGVyLmNsb3NlKGZhbHNlKTsKKyAgICAgICAgICAgICAgICBzdG9yZS5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChmaW5hbCBFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgIGZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKHNlcnZlciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgc2VydmVyLnF1aXQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEN1c3RvbSBoYW5kbGVyLiAgUmV0dXJucyByZXNwb25zZXMgZm9yIG1lc3NhZ2VzIHRoYXQgZG9uJ3QKKyAgICAgKiBleGlzdCBpbiB0aGUgZm9sZGVyLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIElNQVBIYW5kbGVyQmFkIGV4dGVuZHMgSU1BUEhhbmRsZXIgeworCisJQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGV4YW1pbmUoU3RyaW5nIGxpbmUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJICAgIG51bWJlck9mTWVzc2FnZXMgPSAxOworCSAgICBudW1iZXJPZlJlY2VudE1lc3NhZ2VzID0gMTsKKwkgICAgc3VwZXIuZXhhbWluZShsaW5lKTsKKwl9CisKKwlAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgc2VhcmNoKFN0cmluZyBsaW5lKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgdW50YWdnZWQoIlNFQVJDSCAxIDIiKTsKKwkgICAgb2soKTsKKyAgICAgICAgfQorCisJQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGZldGNoKFN0cmluZyBsaW5lKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgdW50YWdnZWQoIjEgRkVUQ0ggKEZMQUdTIChcXFJlY2VudCkpIik7CisgICAgICAgICAgICB1bnRhZ2dlZCgiMiBGRVRDSCAoRkxBR1MgKFxcRGVsZXRlZCkpIik7CisJICAgIG9rKCk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL2ltYXAvSU1BUE1lc3NhZ2VUZXN0LmphdmEgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL2ltYXAvSU1BUE1lc3NhZ2VUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2YyZTY3MAotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9JTUFQTWVzc2FnZVRlc3QuamF2YQpAQCAtMCwwICsxLDQwMSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwOSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuaW1hcDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7CitpbXBvcnQgamF2YS51dGlsLlN0cmluZ1Rva2VuaXplcjsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworCitpbXBvcnQgamF2YXgubWFpbC5Gb2xkZXI7CitpbXBvcnQgamF2YXgubWFpbC5TZXNzaW9uOworaW1wb3J0IGphdmF4Lm1haWwuU3RvcmU7CitpbXBvcnQgamF2YXgubWFpbC5NZXNzYWdlOworaW1wb3J0IGphdmF4Lm1haWwuTXVsdGlwYXJ0OworaW1wb3J0IGphdmF4Lm1haWwuQm9keVBhcnQ7CitpbXBvcnQgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC5NaW1lVXRpbGl0eTsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC50ZXN0LlRlc3RTZXJ2ZXI7CisKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQuUnVsZTsKK2ltcG9ydCBvcmcuanVuaXQucnVsZXMuVGltZW91dDsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRFcXVhbHM7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VHJ1ZTsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRGYWxzZTsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5mYWlsOworCisvKioKKyAqIFRlc3QgSU1BUE1lc3NhZ2UgbWV0aG9kcy4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIElNQVBNZXNzYWdlVGVzdCB7CisKKyAgICAvLyB0aW1lb3V0IHRoZSB0ZXN0IGluIGNhc2Ugb2YgZGVhZGxvY2sKKyAgICBAUnVsZQorICAgIHB1YmxpYyBUaW1lb3V0IGRlYWRsb2NrVGltZW91dCA9IFRpbWVvdXQuc2Vjb25kcygyMCk7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkRBVEUgPSAiMjMtSnVuLTIwMDQgMDY6MjY6MjYgLTA3MDAiOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBFTlZfREFURSA9CisJIlwiV2VkLCAyMyBKdW4gMjAwNCAxODo1Njo0MiArMDUzMFwiIjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRU5WX1NVQkpFQ1QgPSAiXCJ0ZXN0XCIiOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBFTlZfVVRGOF9FTkNPREVEX1NVQkpFQ1QgPQorICAgICAgIj0/VVRGLTg/Qj9WVlJHT0NCMFpYTjBPaURnc3F6Z3NyNGc0TEtINExLeTRMT040TEt5NExLL0lPQ3l1T0N5Z2c9PT89ICIgKworICAgICAgIj0/VVRGLTg/Qj80TEt0NExLMTRMSy80TEs0NExPQklPQ3loK0N5Z3VDeXB1Q3podUN5cUE9PT89ICIgKworICAgICAgIj0/VVRGLTg/Qj80TE9ONExLb0lPQ3l1ZUN6ZytDeXB1Q3lyK0N5cHVDeXN1Q3l2eUE9Pz0iOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBFTlZfQUREUlMgPQorCSIoKFwiSmF2YU1haWxcIiBOSUwgXCJ0ZXN0dXNlclwiIFwiZXhhbXBsZS5jb21cIikpICIgKworCSIoKFwiSmF2YU1haWxcIiBOSUwgXCJ0ZXN0dXNlclwiIFwiZXhhbXBsZS5jb21cIikpICIgKworCSIoKFwiSmF2YU1haWxcIiBOSUwgXCJ0ZXN0dXNlclwiIFwiZXhhbXBsZS5jb21cIikpICIgKworCSIoKE5JTCBOSUwgXCJ0ZXN0dXNlclwiIFwiZXhhbXBsZS5jb21cIikpIE5JTCBOSUwgTklMICIgKworCSJcIjw0MEQ5ODUxMi45MDQwODAzQGV4YW1wbGUuY29tPlwiIjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRU5WRUxPUEUgPQorCSIoIiArIEVOVl9EQVRFICsgIiAiICsgRU5WX1NVQkpFQ1QgKyAiICIgKyBFTlZfQUREUlMgKyAiKSI7CisKKyAgICBwdWJsaWMgc3RhdGljIGFic3RyYWN0IGNsYXNzIElNQVBUZXN0IHsKKwlwdWJsaWMgdm9pZCBpbml0KFByb3BlcnRpZXMgcHJvcHMpIHsgfTsKKwlwdWJsaWMgYWJzdHJhY3Qgdm9pZCB0ZXN0KEZvbGRlciBmb2xkZXIsIElNQVBIYW5kbGVyTWVzc2FnZSBoYW5kbGVyKQorCQkJCSAgICB0aHJvd3MgRXhjZXB0aW9uOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCBhIHNtYWxsIG1lc3NhZ2Ugc2l6ZSBpcyByZXR1cm5lZCBjb3JyZWN0bHkuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2l6ZVNtYWxsKCkgeworCXRlc3RXaXRoSGFuZGxlcigKKwkgICAgbmV3IElNQVBUZXN0KCkgeworCQlAT3ZlcnJpZGUKKwkJcHVibGljIHZvaWQgdGVzdChGb2xkZXIgZm9sZGVyLCBJTUFQSGFuZGxlck1lc3NhZ2UgaGFuZGxlcikKKwkJCQkgICAgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJCSAgICBNZXNzYWdlIG0gPSBmb2xkZXIuZ2V0TWVzc2FnZSgxKTsKKwkJICAgIGFzc2VydEVxdWFscygxMjMsIG0uZ2V0U2l6ZSgpKTsKKwkJfQorCSAgICB9LAorCSAgICBuZXcgSU1BUEhhbmRsZXJNZXNzYWdlKCkgeworCQl7eyBzaXplID0gMTIzOyB9fQorCSAgICB9KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHRoYXQgYSBsYXJnZSBtZXNzYWdlIHNpemUgaXMgcmV0dXJuZWQgYXMgSW50ZWdlci5NQVhfVkFMVUUKKyAgICAgKiBmcm9tIE1pbWVNZXNzYWdlLmdldFNpemUgYW5kIHJldHVybmVkIGFzIHRoZSBhY3R1YWwgdmFsdWUgZnJvbQorICAgICAqIElNQVBNZXNzYWdlLmdldFNpemVMb25nLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFNpemVMYXJnZSgpIHsKKwl0ZXN0V2l0aEhhbmRsZXIoCisJICAgIG5ldyBJTUFQVGVzdCgpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIHRlc3QoRm9sZGVyIGZvbGRlciwgSU1BUEhhbmRsZXJNZXNzYWdlIGhhbmRsZXIpCisJCQkJICAgIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCQkgICAgTWVzc2FnZSBtID0gZm9sZGVyLmdldE1lc3NhZ2UoMSk7CisJCSAgICBhc3NlcnRFcXVhbHMoSW50ZWdlci5NQVhfVkFMVUUsIG0uZ2V0U2l6ZSgpKTsKKwkJICAgIGFzc2VydEVxdWFscygobG9uZylJbnRlZ2VyLk1BWF9WQUxVRSArIDEsCisJCQkJICAgICgoSU1BUE1lc3NhZ2UpbSkuZ2V0U2l6ZUxvbmcoKSk7CisJCX0KKwkgICAgfSwKKwkgICAgbmV3IElNQVBIYW5kbGVyTWVzc2FnZSgpIHsKKwkJe3sgc2l6ZSA9IChsb25nKUludGVnZXIuTUFYX1ZBTFVFICsgMTsgfX0KKwkgICAgfSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IHJldHVybmluZyBOSUwgaW5zdGVhZCBvZiBhbiBlbXB0eSBzdHJpbmcgZm9yIHRoZSBjb250ZW50CisgICAgICogb2YgdGhlIG1lc3NhZ2Ugd29ya3MgY29ycmVjdGx5LgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEVtcHR5Qm9keSgpIHsKKwl0ZXN0V2l0aEhhbmRsZXIoCisJICAgIG5ldyBJTUFQVGVzdCgpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIGluaXQoUHJvcGVydGllcyBwcm9wcykgeworCQkgICAgcHJvcHMuc2V0UHJvcGVydHkoIm1haWwuaW1hcC5wYXJ0aWFsZmV0Y2giLCJmYWxzZSIpOworCQl9CisKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIHRlc3QoRm9sZGVyIGZvbGRlciwgSU1BUEhhbmRsZXJNZXNzYWdlIGhhbmRsZXIpCisJCQkJICAgIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKwkJICAgIE1lc3NhZ2UgbSA9IGZvbGRlci5nZXRNZXNzYWdlKDEpOworCQkgICAgU3RyaW5nIHQgPSAoU3RyaW5nKW0uZ2V0Q29udGVudCgpOworCQkgICAgYXNzZXJ0RXF1YWxzKCIiLCB0KTsKKwkJfQorCSAgICB9LAorCSAgICBuZXcgSU1BUEhhbmRsZXJNZXNzYWdlKCkgeworCQlAT3ZlcnJpZGUKKwkJcHVibGljIHZvaWQgZmV0Y2goU3RyaW5nIGxpbmUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJCSAgICBpZiAobGluZS5pbmRleE9mKCJCT0RZU1RSVUNUVVJFIikgPj0gMCkKKwkJCXVudGFnZ2VkKCIxIEZFVENIIChCT0RZU1RSVUNUVVJFICIgKworCQkJICAgICIoXCJ0ZXh0XCIgXCJwbGFpblwiIChcImNoYXJzZXRcIiBcInVzLWFzY2lpXCIpICIgKworCQkJCSJOSUwgTklMIFwiN2JpdFwiIDAgMCBOSUwgTklMIE5JTCBOSUwpIiArCisJCQkgICAgIikiKTsKKwkJICAgIGVsc2UgaWYgKGxpbmUuaW5kZXhPZigiQk9EWVtURVhUXSIpID49IDApCisJCQl1bnRhZ2dlZCgiMSBGRVRDSCAoQk9EWVtURVhUXSBOSUwgIiArCisJCQkJICAgICJGTEFHUyAoXFxTZWVuIFxcUmVjZW50KSkiKTsKKwkJICAgIG9rKCk7CisJCX0KKwkgICAgfSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QXR0YWNoZW1lbnRGaWxlTmFtZSgpIHsKKyAgICAgICAgdGVzdFdpdGhIYW5kbGVyKAorICAgICAgICAgICAgICAgIG5ldyBJTUFQVGVzdCgpIHsKKyAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIHRlc3QoRm9sZGVyIGZvbGRlciwgSU1BUEhhbmRsZXJNZXNzYWdlIGhhbmRsZXIpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UgbSA9IGZvbGRlci5nZXRNZXNzYWdlKDEpOworICAgICAgICAgICAgICAgICAgICAgICAgTXVsdGlwYXJ0IG1wID0gKE11bHRpcGFydCltLmdldENvbnRlbnQoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIEJvZHlQYXJ0IGJwID0gbXAuZ2V0Qm9keVBhcnQoMSk7CisgICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImZpbGVuYW1lLmNzdiIsIE1pbWVVdGlsaXR5LmRlY29kZVRleHQoYnAuZ2V0RmlsZU5hbWUoKSkpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSwKKyAgICAgICAgICAgICAgICBuZXcgSU1BUEhhbmRsZXJNZXNzYWdlKCkgeworICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgZmV0Y2goU3RyaW5nIGxpbmUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgICAgICAgICB1bnRhZ2dlZCgiMSBGRVRDSCAoQk9EWVNUUlVDVFVSRSAoIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoXCJ0ZXh0XCIgXCJodG1sXCIgKFwiY2hhcnNldFwiIFwidXRmLThcIikgTklMIE5JTCBcImJhc2U2NFwiIDQwMiA2IE5JTCBOSUwgTklMIE5JTCkiICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIihcImFwcGxpY2F0aW9uXCIgXCJvY3RldC1zdHJlYW1cIiAoXCJuYW1lXCIgXCI9P3V0Zi04P0I/Wm1sc1pXNWhiV1U9Pz0gPT91dGYtOD9CP0xtTnpkZz09Pz1cIikgTklMIE5JTCBcImJhc2U2NFwiIDY1OCBOSUwgIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoXCJhdHRhY2htZW50XCIgKFwiZmlsZW5hbWVcIiBcIlwiKSkgTklMIE5JTCkgXCJtaXhlZFwiICIgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKFwiYm91bmRhcnlcIiBcIi0tYm91bmRhcnlfNTM5XzI3ODA2ZTE2LTI1OTktNDYxMi1iOThhLTY5MzM1YmVkZDIwNlwiKSBOSUwgTklMIE5JTCkpIgorICAgICAgICAgICAgICAgICAgICAgICAgKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIG9rKCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IHJldHVybmluZyBOSUwgaW5zdGVhZCBvZiBhbiBlbXB0eSBzdHJpbmcgZm9yIHRoZSBjb250ZW50CisgICAgICogb2YgYW4gZW1wdHkgYm9keSBwYXJ0IHdvcmtzIGNvcnJlY3RseS4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RFbXB0eUJvZHlBdHRhY2htZW50KCkgeworCXRlc3RXaXRoSGFuZGxlcigKKwkgICAgbmV3IElNQVBUZXN0KCkgeworCQlAT3ZlcnJpZGUKKwkJcHVibGljIHZvaWQgaW5pdChQcm9wZXJ0aWVzIHByb3BzKSB7CisJCSAgICBwcm9wcy5zZXRQcm9wZXJ0eSgibWFpbC5pbWFwLnBhcnRpYWxmZXRjaCIsImZhbHNlIik7CisJCX0KKworCQlAT3ZlcnJpZGUKKwkJcHVibGljIHZvaWQgdGVzdChGb2xkZXIgZm9sZGVyLCBJTUFQSGFuZGxlck1lc3NhZ2UgaGFuZGxlcikKKwkJCQkgICAgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworCQkgICAgTWVzc2FnZSBtID0gZm9sZGVyLmdldE1lc3NhZ2UoMSk7CisJCSAgICBNdWx0aXBhcnQgbXAgPSAoTXVsdGlwYXJ0KW0uZ2V0Q29udGVudCgpOworCQkgICAgQm9keVBhcnQgYnAgPSBtcC5nZXRCb2R5UGFydCgxKTsKKwkJICAgIFN0cmluZyB0ID0gKFN0cmluZylicC5nZXRDb250ZW50KCk7CisJCSAgICBhc3NlcnRFcXVhbHMoIiIsIHQpOworCQl9CisJICAgIH0sCisJICAgIG5ldyBJTUFQSGFuZGxlck1lc3NhZ2UoKSB7CisJCUBPdmVycmlkZQorCQlwdWJsaWMgdm9pZCBmZXRjaChTdHJpbmcgbGluZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkJICAgIGlmIChsaW5lLmluZGV4T2YoIkJPRFlTVFJVQ1RVUkUiKSA+PSAwKQorCQkJdW50YWdnZWQoIjEgRkVUQ0ggKEJPRFlTVFJVQ1RVUkUgKCIgKworCQkJICAgICIoXCJ0ZXh0XCIgXCJwbGFpblwiIChcImNoYXJzZXRcIiBcInVzLWFzY2lpXCIpICIgKworCQkJCSJOSUwgTklMIFwiN2JpdFwiIDQgMCBOSUwgTklMIE5JTCBOSUwpIiArCisJCQkgICAgIihcInRleHRcIiBcInBsYWluXCIgKFwiY2hhcnNldFwiIFwidXMtYXNjaWlcIikgIiArCisJCQkJIk5JTCBOSUwgXCI3Yml0XCIgMCAwIE5JTCBOSUwgTklMIE5JTCkiICsKKwkJCSAgICAiIFwibWl4ZWRcIiAoXCJib3VuZGFyeVwiIFwiLS0tLT1feFwiKSBOSUwgTklMKSkiKTsKKwkJICAgIGVsc2UgaWYgKGxpbmUuaW5kZXhPZigiQk9EWVsyXSIpID49IDApCisJCQl1bnRhZ2dlZCgiMSBGRVRDSCAoQk9EWVsyXSBOSUwgIiArCisJCQkJICAgICJGTEFHUyAoXFxTZWVuIFxcUmVjZW50KSkiKTsKKwkJICAgIG9rKCk7CisJCX0KKwkgICAgfSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IHJldHVybmluZyBOSUwgaW5zdGVhZCBvZiBhbiBlbXB0eSBzdHJpbmcgZm9yIHRoZSBjb250ZW50CisgICAgICogb2YgYW4gZW1wdHkgYm9keSBwYXJ0IHdvcmtzIGNvcnJlY3RseS4KKyAgICAgKiBUaGlzIGlzIGEgYnVnIGluIG9mZmljZTM2NS5jb20uICBOb3RlIHRoZSBzcGFjZSBpbiAiYmFzZTY0ICIuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QmFkRW5jb2RpbmcoKSB7CisJdGVzdFdpdGhIYW5kbGVyKAorCSAgICBuZXcgSU1BUFRlc3QoKSB7CisJCUBPdmVycmlkZQorCQlwdWJsaWMgdm9pZCBpbml0KFByb3BlcnRpZXMgcHJvcHMpIHsKKwkJICAgIHByb3BzLnNldFByb3BlcnR5KCJtYWlsLmltYXAucGFydGlhbGZldGNoIiwiZmFsc2UiKTsKKwkJfQorCisJCUBPdmVycmlkZQorCQlwdWJsaWMgdm9pZCB0ZXN0KEZvbGRlciBmb2xkZXIsIElNQVBIYW5kbGVyTWVzc2FnZSBoYW5kbGVyKQorCQkJCSAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisJCSAgICBNZXNzYWdlIG0gPSBmb2xkZXIuZ2V0TWVzc2FnZSgxKTsKKwkJICAgIE11bHRpcGFydCBtcCA9IChNdWx0aXBhcnQpbS5nZXRDb250ZW50KCk7CisJCSAgICBCb2R5UGFydCBicCA9IG1wLmdldEJvZHlQYXJ0KDEpOworCQkgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisJCSAgICB0cnkgKElucHV0U3RyZWFtIGlzID0gYnAuZ2V0SW5wdXRTdHJlYW0oKSkgeworCQkJaW50IGM7CisJCQl3aGlsZSAoKGMgPSBpcy5yZWFkKCkpICE9IC0xKQorCQkJICAgIHNiLmFwcGVuZCgoY2hhciljKTsKKwkJICAgIH0KKwkJICAgIGFzc2VydEVxdWFscygidGVzdCIsIHNiLnRvU3RyaW5nKCkpOworCQl9CisJICAgIH0sCisJICAgIG5ldyBJTUFQSGFuZGxlck1lc3NhZ2UoKSB7CisJCUBPdmVycmlkZQorCQlwdWJsaWMgdm9pZCBmZXRjaChTdHJpbmcgbGluZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkJICAgIGlmIChsaW5lLmluZGV4T2YoIkJPRFlTVFJVQ1RVUkUiKSA+PSAwKQorCQkJdW50YWdnZWQoIjEgRkVUQ0ggKEJPRFlTVFJVQ1RVUkUgKCIgKworCQkJICAgICIoXCJ0ZXh0XCIgXCJwbGFpblwiIChcImNoYXJzZXRcIiBcInVzLWFzY2lpXCIpICIgKworCQkJCSJOSUwgTklMIFwiN2JpdFwiIDAgMCBOSUwgTklMIE5JTCBOSUwpIiArCisJCQkgICAgIihcImFwcGxpY2F0aW9uXCIgXCJvY3RldC1zdHJlYW1cIiAiICsKKwkJCQkiKFwibmFtZVwiIFwidGVzdC50eHRcIikgTklMIE5JTCBcImJhc2U2NCBcIiAiICsKKwkJCQkiOCBOSUwgTklMIE5JTCBOSUwpICIgKworCQkJICAgICJcIm1peGVkXCIgKFwiYm91bmRhcnlcIiBcIj1feFwiKSBOSUwgTklMKSkiKTsKKwkJICAgIGVsc2UgaWYgKGxpbmUuaW5kZXhPZigiQk9EWVsyXSIpID49IDApCisJCQl1bnRhZ2dlZCgiMSBGRVRDSCAoQk9EWVsyXSBcImRHVnpkQT09XCIgIiArCisJCQkJICAgICJGTEFHUyAoXFxTZWVuIFxcUmVjZW50KSkiKTsKKwkJICAgIG9rKCk7CisJCX0KKwkgICAgfSk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBUZXN0IHRoYXQgYSBVVEYtOCBlbmNvZGVkIFN1YmplY3QgaXMgZGVjb2RlZCBwcm9wZXJseS4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RVdGY4U3ViamVjdEVuY29kZWQoKSB7CisJU3RyaW5nIHMgPSBudWxsOworCXRyeSB7CisJICAgIHMgPSBNaW1lVXRpbGl0eS5kZWNvZGVUZXh0KEVOVl9VVEY4X0VOQ09ERURfU1VCSkVDVCk7CisJfSBjYXRjaCAoVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBleCkgeworCX0KKwlmaW5hbCBTdHJpbmcgc3ViamVjdCA9IHM7CisKKwl0ZXN0V2l0aEhhbmRsZXIoCisJICAgIG5ldyBJTUFQVGVzdCgpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIHRlc3QoRm9sZGVyIGZvbGRlciwgSU1BUEhhbmRsZXJNZXNzYWdlIGhhbmRsZXIpCisJCQkJICAgIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCQkgICAgTWVzc2FnZSBtID0gZm9sZGVyLmdldE1lc3NhZ2UoMSk7CisJCSAgICBhc3NlcnRFcXVhbHMoc3ViamVjdCwgbS5nZXRTdWJqZWN0KCkpOworCQl9CisJICAgIH0sCisJICAgIG5ldyBJTUFQSGFuZGxlck1lc3NhZ2UoKSB7CisJCXt7CisJCSAgICBlbnZlbG9wZSA9ICIoIiArIEVOVl9EQVRFICsgIiBcIiIgKworCQkJCUVOVl9VVEY4X0VOQ09ERURfU1VCSkVDVCArICJcIiAiICsKKwkJCQlFTlZfQUREUlMgKyAiKSI7CisJCX19CisJICAgIH0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCBhIFVURi04IFN1YmplY3QgaXMgZGVjb2RlZCBwcm9wZXJseS4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RVdGY4U3ViamVjdCgpIHsKKwlTdHJpbmcgcyA9IG51bGw7CisJdHJ5IHsKKwkgICAgcyA9IE1pbWVVdGlsaXR5LmRlY29kZVRleHQoRU5WX1VURjhfRU5DT0RFRF9TVUJKRUNUKTsKKwl9IGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGV4KSB7CisJfQorCWZpbmFsIFN0cmluZyBzdWJqZWN0ID0gczsKKworCXRlc3RXaXRoSGFuZGxlcigKKwkgICAgbmV3IElNQVBUZXN0KCkgeworCQlAT3ZlcnJpZGUKKwkJcHVibGljIHZvaWQgdGVzdChGb2xkZXIgZm9sZGVyLCBJTUFQSGFuZGxlck1lc3NhZ2UgaGFuZGxlcikKKwkJCQkgICAgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJCSAgICBNZXNzYWdlIG0gPSBmb2xkZXIuZ2V0TWVzc2FnZSgxKTsKKwkJICAgIGFzc2VydEVxdWFscyhzdWJqZWN0LCBtLmdldFN1YmplY3QoKSk7CisJCX0KKwkgICAgfSwKKwkgICAgbmV3IElNQVBIYW5kbGVyTWVzc2FnZSgpIHsKKwkJe3sKKwkJICAgIGVudmVsb3BlID0gIigiICsgRU5WX0RBVEUgKyAiIFwiIiArIHN1YmplY3QgKyAiXCIgIiArCisJCQkJICAgIEVOVl9BRERSUyArICIpIjsKKwkJICAgIGNhcGFiaWxpdGllcyArPSAiIEVOQUJMRSBVVEY4PUFDQ0VQVCI7CisJCX19CisKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIGVuYWJsZShTdHJpbmcgbGluZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkJICAgIG9rKCk7CisJCX0KKwkgICAgfSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RXaXRoSGFuZGxlcihJTUFQVGVzdCB0ZXN0LCBJTUFQSGFuZGxlck1lc3NhZ2UgaGFuZGxlcikgeworICAgICAgICBUZXN0U2VydmVyIHNlcnZlciA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzZXJ2ZXIgPSBuZXcgVGVzdFNlcnZlcihoYW5kbGVyKTsKKyAgICAgICAgICAgIHNlcnZlci5zdGFydCgpOworCisgICAgICAgICAgICBmaW5hbCBQcm9wZXJ0aWVzIHByb3BlcnRpZXMgPSBuZXcgUHJvcGVydGllcygpOworICAgICAgICAgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5pbWFwLmhvc3QiLCAibG9jYWxob3N0Iik7CisgICAgICAgICAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLmltYXAucG9ydCIsICIiICsgc2VydmVyLmdldFBvcnQoKSk7CisJICAgIHRlc3QuaW5pdChwcm9wZXJ0aWVzKTsKKyAgICAgICAgICAgIGZpbmFsIFNlc3Npb24gc2Vzc2lvbiA9IFNlc3Npb24uZ2V0SW5zdGFuY2UocHJvcGVydGllcyk7CisgICAgICAgICAgICAvL3Nlc3Npb24uc2V0RGVidWcodHJ1ZSk7CisKKyAgICAgICAgICAgIGZpbmFsIFN0b3JlIHN0b3JlID0gc2Vzc2lvbi5nZXRTdG9yZSgiaW1hcCIpOworCSAgICBGb2xkZXIgZm9sZGVyID0gbnVsbDsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc3RvcmUuY29ubmVjdCgidGVzdCIsICJ0ZXN0Iik7CisgICAgICAgICAgICAgICAgZm9sZGVyID0gc3RvcmUuZ2V0Rm9sZGVyKCJJTkJPWCIpOworICAgICAgICAgICAgICAgIGZvbGRlci5vcGVuKEZvbGRlci5SRUFEX09OTFkpOworCQl0ZXN0LnRlc3QoZm9sZGVyLCBoYW5kbGVyKTsKKwkgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJCVN5c3RlbS5vdXQucHJpbnRsbihleCk7CisJCS8vZXgucHJpbnRTdGFja1RyYWNlKCk7CisJCWZhaWwoZXgudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworCQlpZiAoZm9sZGVyICE9IG51bGwpCisJCSAgICBmb2xkZXIuY2xvc2UoZmFsc2UpOworICAgICAgICAgICAgICAgIHN0b3JlLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoc2VydmVyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBzZXJ2ZXIucXVpdCgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3VzdG9tIGhhbmRsZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgSU1BUEhhbmRsZXJNZXNzYWdlIGV4dGVuZHMgSU1BUEhhbmRsZXIgeworCisJU3RyaW5nIHJkYXRlID0gUkRBVEU7CisJU3RyaW5nIGVudmVsb3BlID0gRU5WRUxPUEU7CisJbG9uZyBzaXplID0gMDsKKworCUBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBleGFtaW5lKFN0cmluZyBsaW5lKSB0aHJvd3MgSU9FeGNlcHRpb24geworCSAgICBudW1iZXJPZk1lc3NhZ2VzID0gMTsKKwkgICAgc3VwZXIuZXhhbWluZShsaW5lKTsKKwl9CisKKwlAT3ZlcnJpZGUKKwlwdWJsaWMgdm9pZCBmZXRjaChTdHJpbmcgbGluZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkgICAgdW50YWdnZWQoIjEgRkVUQ0ggKEVOVkVMT1BFICIgKyBlbnZlbG9wZSArCisJCSIgSU5URVJOQUxEQVRFIFwiIiArIHJkYXRlICsgIlwiICIgKworCQkiUkZDODIyLlNJWkUgIiArIHNpemUgKyAiKSIpOworCSAgICBvaygpOworCX0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL2ltYXAvSU1BUFBsYWluSGFuZGxlci5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0lNQVBQbGFpbkhhbmRsZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMDUxNGY4Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0lNQVBQbGFpbkhhbmRsZXIuamF2YQpAQCAtMCwwICsxLDYyIEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDA5LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5pbWFwOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LlN0YW5kYXJkQ2hhcnNldHM7CisKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5CQVNFNjREZWNvZGVyU3RyZWFtOworCisvKioKKyAqIEhhbmRsZSBJTUFQIGNvbm5lY3Rpb24gd2l0aCBQTEFJTiBhdXRoZW50aWNhdGlvbi4KKyAqCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCitwdWJsaWMgY2xhc3MgSU1BUFBsYWluSGFuZGxlciBleHRlbmRzIElNQVBIYW5kbGVyIHsKKworICAgIHByb3RlY3RlZCBTdHJpbmcgdXNlcm5hbWUgPSAidGVzdCI7CisgICAgcHJvdGVjdGVkIFN0cmluZyBwYXNzd29yZCA9ICJ0ZXN0IjsKKworICAgIHB1YmxpYyBJTUFQUGxhaW5IYW5kbGVyKCkgeworCWNhcGFiaWxpdGllcyArPSAiIExPR0lORElTQUJMRUQgQVVUSD1QTEFJTiI7CisgICAgfQorCisgICAgLyoqCisgICAgICogQVVUSEVOVElDQVRFIFBMQUlOIGNvbW1hbmQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIHVuYWJsZSB0byByZWFkL3dyaXRlIHRvIHNvY2tldAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGF1dGhwbGFpbihTdHJpbmcgaXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJaWYgKGlyID09IG51bGwpIHsKKwkgICAgY29udCgiIik7CisJICAgIGlyID0gcmVhZExpbmUoKTsKKwl9CisJU3RyaW5nIGF1dGggPSBuZXcgU3RyaW5nKEJBU0U2NERlY29kZXJTdHJlYW0uZGVjb2RlKAorCQkJCSAgICBpci5nZXRCeXRlcyhTdGFuZGFyZENoYXJzZXRzLlVTX0FTQ0lJKSksCisJCQkJU3RhbmRhcmRDaGFyc2V0cy5VVEZfOCk7CisJU3RyaW5nW10gYXAgPSBhdXRoLnNwbGl0KCJcMDAwIik7CisJU3RyaW5nIHUgPSBhcFsxXTsKKwlTdHJpbmcgcCA9IGFwWzJdOworCS8vU3lzdGVtLm91dC5wcmludGYoIlVTRVI6ICVzLCBQQVNTV09SRDogJXMlbiIsIHUsIHApOworCWlmICghdS5lcXVhbHModXNlcm5hbWUpIHx8ICFwLmVxdWFscyhwYXNzd29yZCkpIHsKKwkgICAgbm8oImF1dGhlbnRpY2F0aW9uIGZhaWxlZCIpOworCSAgICByZXR1cm47CisJfQorICAgICAgICBvaygiW0NBUEFCSUxJVFkgIiArIGNhcGFiaWxpdGllcyArICJdIik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0lNQVBSZXNwb25zZUV2ZW50VGVzdC5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0lNQVBSZXNwb25zZUV2ZW50VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMyZTMzOTYKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL2ltYXAvSU1BUFJlc3BvbnNlRXZlbnRUZXN0LmphdmEKQEAgLTAsMCArMSwxMzEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDksIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmltYXA7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkNvdW50RG93bkxhdGNoOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LlRpbWVVbml0OworCitpbXBvcnQgamF2YXgubWFpbC5TZXNzaW9uOworaW1wb3J0IGphdmF4Lm1haWwuU3RvcmU7CitpbXBvcnQgamF2YXgubWFpbC5ldmVudC5TdG9yZUxpc3RlbmVyOworaW1wb3J0IGphdmF4Lm1haWwuZXZlbnQuU3RvcmVFdmVudDsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC50ZXN0LlRlc3RTZXJ2ZXI7CisKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUcnVlOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmZhaWw7CisKKy8qKgorICogVGVzdCBJTUFQIHJlc3BvbnNlIGV2ZW50cy4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIElNQVBSZXNwb25zZUV2ZW50VGVzdCB7CisKKyAgICBwcml2YXRlIHZvbGF0aWxlIGJvb2xlYW4gZ290UmVzcG9uc2U7CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHRoYXQgcmVzcG9uc2UgZXZlbnRzIGFyZSBzZW50IGZvciB0aGUgTE9HSU4gY29tbWFuZC4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RMb2dpblJlc3BvbnNlRXZlbnQoKSB7CisJdGVzdExvZ2luKCIiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHRoYXQgcmVzcG9uc2UgZXZlbnRzIGFyZSBzZW50IGZvciB0aGUgQVVUSEVOVElDQVRFIExPR0lOIGNvbW1hbmQuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QXV0aExvZ2luUmVzcG9uc2VFdmVudCgpIHsKKwl0ZXN0TG9naW4oIkxPR0lORElTQUJMRUQgQVVUSD1MT0dJTiIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCByZXNwb25zZSBldmVudHMgYXJlIHNlbnQgZm9yIHRoZSBBVVRIRU5USUNBVEUgUExBSU4gY29tbWFuZC4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RBdXRoUGxhaW5SZXNwb25zZUV2ZW50KCkgeworCXRlc3RMb2dpbigiTE9HSU5ESVNBQkxFRCBBVVRIPVBMQUlOIik7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RMb2dpbihTdHJpbmcgdHlwZSkgeworICAgICAgICBUZXN0U2VydmVyIHNlcnZlciA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaW5hbCBJTUFQSGFuZGxlciBoYW5kbGVyID0gbmV3IElNQVBIYW5kbGVyTG9naW4odHlwZSk7CisgICAgICAgICAgICBzZXJ2ZXIgPSBuZXcgVGVzdFNlcnZlcihoYW5kbGVyKTsKKyAgICAgICAgICAgIHNlcnZlci5zdGFydCgpOworCisgICAgICAgICAgICBmaW5hbCBQcm9wZXJ0aWVzIHByb3BlcnRpZXMgPSBuZXcgUHJvcGVydGllcygpOworICAgICAgICAgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5pbWFwLmhvc3QiLCAibG9jYWxob3N0Iik7CisgICAgICAgICAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLmltYXAucG9ydCIsICIiICsgc2VydmVyLmdldFBvcnQoKSk7CisgICAgICAgICAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLmltYXAuZW5hYmxlcmVzcG9uc2VldmVudHMiLCAidHJ1ZSIpOworICAgICAgICAgICAgZmluYWwgU2Vzc2lvbiBzZXNzaW9uID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShwcm9wZXJ0aWVzKTsKKyAgICAgICAgICAgIC8vc2Vzc2lvbi5zZXREZWJ1Zyh0cnVlKTsKKwkgICAgZmluYWwgQ291bnREb3duTGF0Y2ggbGF0Y2ggPSBuZXcgQ291bnREb3duTGF0Y2goMSk7CisKKyAgICAgICAgICAgIGZpbmFsIFN0b3JlIHN0b3JlID0gc2Vzc2lvbi5nZXRTdG9yZSgiaW1hcCIpOworCSAgICBzdG9yZS5hZGRTdG9yZUxpc3RlbmVyKG5ldyBTdG9yZUxpc3RlbmVyKCkgeworCQlAT3ZlcnJpZGUKKwkJcHVibGljIHZvaWQgbm90aWZpY2F0aW9uKFN0b3JlRXZlbnQgZSkgeworCQkgICAgU3RyaW5nIHM7CisJCSAgICBpZiAoZS5nZXRNZXNzYWdlVHlwZSgpID09IElNQVBTdG9yZS5SRVNQT05TRSkgeworCQkJcyA9ICJSRVNQT05TRTogIjsKKwkJCS8vIGlzIHRoaXMgdGhlIGV4cGVjdGVkIEFVVEhFTlRJQ0FURSByZXNwb25zZT8KKwkJCWlmIChlLmdldE1lc3NhZ2UoKS5pbmRleE9mKCJYLUxPR0lOLVNVQ0NFU1MiKSA+PSAwKQorCQkJICAgIGdvdFJlc3BvbnNlID0gdHJ1ZTsKKwkJCWxhdGNoLmNvdW50RG93bigpOworCQkgICAgfSBlbHNlCisJCQlzID0gIk9USEVSOiAiOworCQkgICAgLy9TeXN0ZW0ub3V0LnByaW50bG4ocyArIGUuZ2V0TWVzc2FnZSgpKTsKKwkJfQorCSAgICB9KTsKKwkgICAgZ290UmVzcG9uc2UgPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc3RvcmUuY29ubmVjdCgidGVzdCIsICJ0ZXN0Iik7CisJCS8vIHRpbWUgZm9yIGV2ZW50IHRvIGJlIGRlbGl2ZXJlZAorCQlsYXRjaC5hd2FpdCg1LCBUaW1lVW5pdC5TRUNPTkRTKTsKKwkJYXNzZXJ0VHJ1ZShnb3RSZXNwb25zZSk7CisKKwkgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJCVN5c3RlbS5vdXQucHJpbnRsbihleCk7CisJCS8vZXgucHJpbnRTdGFja1RyYWNlKCk7CisJCWZhaWwoZXgudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHN0b3JlLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoc2VydmVyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBzZXJ2ZXIucXVpdCgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3VzdG9tIGhhbmRsZXIuICBGb3JjZXMgdXNlIG9mIHNwZWNpZmljIGxvZ2luIHR5cGUgYW5kIGluY2x1ZGVzCisgICAgICogYSBmYWtlIGNhcGFiaWxpdHkgdG8gYmUgaW5jbHVkZWQgaW4gdGhlIE9LIHJlc3BvbnNlIHRoYXQgd2UKKyAgICAgKiB3aWxsIGNoZWNrIGZvciBzdWNjZXNzLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIElNQVBIYW5kbGVyTG9naW4gZXh0ZW5kcyBJTUFQSGFuZGxlciB7CisJcHVibGljIElNQVBIYW5kbGVyTG9naW4oU3RyaW5nIHR5cGUpIHsKKwkgICAgY2FwYWJpbGl0aWVzICs9ICIgIiArIHR5cGUgKyAiIFgtTE9HSU4tU1VDQ0VTUyI7CisJfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9JTUFQU2FzbEhhbmRsZXIuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9JTUFQU2FzbEhhbmRsZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iOGMxMDYyCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0lNQVBTYXNsSGFuZGxlci5qYXZhCkBAIC0wLDAgKzEsMTU2IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDA5LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5pbWFwOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyOworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkxvZ2dlcjsKK2ltcG9ydCBqYXZhLnV0aWwubG9nZ2luZy5MZXZlbDsKKworaW1wb3J0IGphdmF4LnNlY3VyaXR5LnNhc2wuKjsKK2ltcG9ydCBqYXZheC5zZWN1cml0eS5hdXRoLmNhbGxiYWNrLio7CisKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5CQVNFNjRFbmNvZGVyU3RyZWFtOworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLkJBU0U2NERlY29kZXJTdHJlYW07CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuQVNDSUlVdGlsaXR5OworCisvKioKKyAqIEhhbmRsZSBJTUFQIGNvbm5lY3Rpb24gd2l0aCBTQVNMIGF1dGhlbnRpY2F0aW9uLgorICoKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKi8KK3B1YmxpYyBjbGFzcyBJTUFQU2FzbEhhbmRsZXIgZXh0ZW5kcyBJTUFQSGFuZGxlciB7CisKKyAgICBwdWJsaWMgSU1BUFNhc2xIYW5kbGVyKCkgeworCWNhcGFiaWxpdGllcyArPSAiIExPR0lORElTQUJMRUQgQVVUSD1ESUdFU1QtTUQ1IjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBVVRIRU5USUNBVEUgY29tbWFuZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gdW5hYmxlIHRvIHJlYWQvd3JpdGUgdG8gc29ja2V0CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgYXV0aGVudGljYXRlKFN0cmluZyBtZWNoLCBTdHJpbmcgaXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJZmluYWwgU3RyaW5nIHUgPSAidGVzdCI7CisJZmluYWwgU3RyaW5nIHAgPSAidGVzdCI7CisJZmluYWwgU3RyaW5nIHJlYWxtID0gInRlc3QiOworCisJQ2FsbGJhY2tIYW5kbGVyIGNiaCA9IG5ldyBDYWxsYmFja0hhbmRsZXIoKSB7CisJICAgIEBPdmVycmlkZQorCSAgICBwdWJsaWMgdm9pZCBoYW5kbGUoQ2FsbGJhY2tbXSBjYWxsYmFja3MpIHsKKwkJaWYgKExPR0dFUi5pc0xvZ2dhYmxlKExldmVsLkZJTkUpKQorCQkgICAgTE9HR0VSLmZpbmUoIlNBU0wgY2FsbGJhY2sgbGVuZ3RoOiAiICsgY2FsbGJhY2tzLmxlbmd0aCk7CisJCWZvciAoaW50IGkgPSAwOyBpIDwgY2FsbGJhY2tzLmxlbmd0aDsgaSsrKSB7CisJCSAgICBpZiAoTE9HR0VSLmlzTG9nZ2FibGUoTGV2ZWwuRklORSkpCisJCQlMT0dHRVIuZmluZSgiU0FTTCBjYWxsYmFjayAiICsgaSArICI6ICIgKyBjYWxsYmFja3NbaV0pOworCQkgICAgaWYgKGNhbGxiYWNrc1tpXSBpbnN0YW5jZW9mIE5hbWVDYWxsYmFjaykgeworCQkJTmFtZUNhbGxiYWNrIG5jYiA9IChOYW1lQ2FsbGJhY2spY2FsbGJhY2tzW2ldOworCQkJbmNiLnNldE5hbWUodSk7CisJCSAgICB9IGVsc2UgaWYgKGNhbGxiYWNrc1tpXSBpbnN0YW5jZW9mIFBhc3N3b3JkQ2FsbGJhY2spIHsKKwkJCVBhc3N3b3JkQ2FsbGJhY2sgcGNiID0gKFBhc3N3b3JkQ2FsbGJhY2spY2FsbGJhY2tzW2ldOworCQkJcGNiLnNldFBhc3N3b3JkKHAudG9DaGFyQXJyYXkoKSk7CisJCSAgICB9IGVsc2UgaWYgKGNhbGxiYWNrc1tpXSBpbnN0YW5jZW9mIEF1dGhvcml6ZUNhbGxiYWNrKSB7CisJCQlBdXRob3JpemVDYWxsYmFjayBhYyA9IChBdXRob3JpemVDYWxsYmFjayljYWxsYmFja3NbaV07CisJCQlpZiAoTE9HR0VSLmlzTG9nZ2FibGUoTGV2ZWwuRklORSkpCisJCQkgICAgTE9HR0VSLmZpbmUoIlNBU0wgYXV0aG9yaXplOiAiICsKKwkJCQkiYXV0aG46ICIgKyBhYy5nZXRBdXRoZW50aWNhdGlvbklEKCkgKyAiLCAiICsKKwkJCQkiYXV0aHo6ICIgKyBhYy5nZXRBdXRob3JpemF0aW9uSUQoKSArICIsICIgKworCQkJCSJhdXRob3JpemVkOiAiICsgYWMuZ2V0QXV0aG9yaXplZElEKCkpOworCQkJYWMuc2V0QXV0aG9yaXplZCh0cnVlKTsKKwkJICAgIH0gZWxzZSBpZiAoY2FsbGJhY2tzW2ldIGluc3RhbmNlb2YgUmVhbG1DYWxsYmFjaykgeworCQkJUmVhbG1DYWxsYmFjayByY2IgPSAoUmVhbG1DYWxsYmFjayljYWxsYmFja3NbaV07CisJCQlyY2Iuc2V0VGV4dChyZWFsbSAhPSBudWxsID8KKwkJCQkgICAgcmVhbG0gOiByY2IuZ2V0RGVmYXVsdFRleHQoKSk7CisJCSAgICB9IGVsc2UgaWYgKGNhbGxiYWNrc1tpXSBpbnN0YW5jZW9mIFJlYWxtQ2hvaWNlQ2FsbGJhY2spIHsKKwkJCVJlYWxtQ2hvaWNlQ2FsbGJhY2sgcmNiID0KKwkJCSAgICAoUmVhbG1DaG9pY2VDYWxsYmFjayljYWxsYmFja3NbaV07CisJCQlpZiAocmVhbG0gPT0gbnVsbCkKKwkJCSAgICByY2Iuc2V0U2VsZWN0ZWRJbmRleChyY2IuZ2V0RGVmYXVsdENob2ljZSgpKTsKKwkJCWVsc2UgeworCQkJICAgIC8vIG5lZWQgdG8gZmluZCBzcGVjaWZpZWQgcmVhbG0gaW4gbGlzdAorCQkJICAgIFN0cmluZ1tdIGNob2ljZXMgPSByY2IuZ2V0Q2hvaWNlcygpOworCQkJICAgIGZvciAoaW50IGsgPSAwOyBrIDwgY2hvaWNlcy5sZW5ndGg7IGsrKykgeworCQkJCWlmIChjaG9pY2VzW2tdLmVxdWFscyhyZWFsbSkpIHsKKwkJCQkgICAgcmNiLnNldFNlbGVjdGVkSW5kZXgoayk7CisJCQkJICAgIGJyZWFrOworCQkJCX0KKwkJCSAgICB9CisJCQl9CisJCSAgICB9CisJCX0KKwkgICAgfQorCX07CisKKwlTYXNsU2VydmVyIHNzOworCXRyeSB7CisJICAgIHNzID0gU2FzbC5jcmVhdGVTYXNsU2VydmVyKG1lY2gsICJpbWFwIiwgImxvY2FsaG9zdCIsIG51bGwsIGNiaCk7CisJfSBjYXRjaCAoU2FzbEV4Y2VwdGlvbiBzZXgpIHsKKwkgICAgTE9HR0VSLmxvZyhMZXZlbC5GSU5FLCAiRmFpbGVkIHRvIGNyZWF0ZSBTQVNMIHNlcnZlciIsIHNleCk7CisJICAgIG5vKCJGYWlsZWQgdG8gY3JlYXRlIFNBU0wgc2VydmVyIik7CisJICAgIHJldHVybjsKKwl9CisJaWYgKHNzID09IG51bGwpIHsKKwkgICAgTE9HR0VSLmZpbmUoIk5vIFNBU0wgc3VwcG9ydCIpOworCSAgICBubygiTm8gU0FTTCBzdXBwb3J0Iik7CisJICAgIHJldHVybjsKKwl9CisJaWYgKExPR0dFUi5pc0xvZ2dhYmxlKExldmVsLkZJTkUpKQorCSAgICBMT0dHRVIuZmluZSgiU0FTTCBzZXJ2ZXIgIiArIHNzLmdldE1lY2hhbmlzbU5hbWUoKSk7CisKKwlieXRlW10gcmVzcG9uc2UgPSBuZXcgYnl0ZVswXTsKKwl3aGlsZSAoIXNzLmlzQ29tcGxldGUoKSkgeworCSAgICB0cnkgeworCQlieXRlW10gY2hhbCA9IHNzLmV2YWx1YXRlUmVzcG9uc2UocmVzcG9uc2UpOworCQlpZiAoc3MuaXNDb21wbGV0ZSgpKSB7CisJCSAgICBicmVhazsKKwkJfSBlbHNlIHsKKwkJICAgIC8vIHNlbmQgY2hhbGxlbmdlCisJCSAgICBpZiAoTE9HR0VSLmlzTG9nZ2FibGUoTGV2ZWwuRklORSkpCisJCQlMT0dHRVIuZmluZSgiU0FTTCBjaGFsbGVuZ2U6ICIgKworCQkJICAgIEFTQ0lJVXRpbGl0eS50b1N0cmluZyhjaGFsLCAwLCBjaGFsLmxlbmd0aCkpOworCQkgICAgYnl0ZVtdIGJhID0gQkFTRTY0RW5jb2RlclN0cmVhbS5lbmNvZGUoY2hhbCk7CisJCSAgICBpZiAoYmEubGVuZ3RoID4gMCkKKwkJCWNvbnQoQVNDSUlVdGlsaXR5LnRvU3RyaW5nKGJhLCAwLCBiYS5sZW5ndGgpKTsKKwkJICAgIGVsc2UKKwkJCWNvbnQoKTsKKwkJICAgIC8vIHJlYWQgcmVzcG9uc2UKKwkJICAgIFN0cmluZyByZXNwID0gcmVhZExpbmUoKTsKKwkJICAgIHJlc3BvbnNlID0gcmVzcC5nZXRCeXRlcygpOworCQkgICAgcmVzcG9uc2UgPSBCQVNFNjREZWNvZGVyU3RyZWFtLmRlY29kZShyZXNwb25zZSk7CisJCX0KKwkgICAgfSBjYXRjaCAoU2FzbEV4Y2VwdGlvbiBleCkgeworCQlubyhleC50b1N0cmluZygpKTsKKwkJYnJlYWs7CisJICAgIH0KKwl9CisKKwlpZiAoc3MuaXNDb21wbGV0ZSgpIC8qJiYgc3RhdHVzID09IFNVQ0NFU1MqLykgeworCSAgICBTdHJpbmcgcW9wID0gKFN0cmluZylzcy5nZXROZWdvdGlhdGVkUHJvcGVydHkoU2FzbC5RT1ApOworCSAgICBpZiAocW9wICE9IG51bGwgJiYgKHFvcC5lcXVhbHNJZ25vcmVDYXNlKCJhdXRoLWludCIpIHx8CisJCQkJcW9wLmVxdWFsc0lnbm9yZUNhc2UoImF1dGgtY29uZiIpKSkgeworCQkvLyBYWFggLSBOT1QgU1VQUE9SVEVEISEhCisJCUxPR0dFUi5maW5lKAorCQkJIlNBU0wgTWVjaGFuaXNtIHJlcXVpcmVzIGludGVncml0eSBvciBjb25maWRlbnRpYWxpdHkiKTsKKwkJbm8oIlNBU0wgTWVjaGFuaXNtIHJlcXVpcmVzIGludGVncml0eSBvciBjb25maWRlbnRpYWxpdHkiKTsKKwkJcmV0dXJuOworCSAgICB9CisJfQorCisgICAgICAgIG9rKCJbQ0FQQUJJTElUWSAiICsgY2FwYWJpbGl0aWVzICsgIl0iKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL2ltYXAvSU1BUFNhc2xMb2dpblRlc3QuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9JTUFQU2FzbExvZ2luVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY4YzI3ZjEKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL2ltYXAvSU1BUFNhc2xMb2dpblRlc3QuamF2YQpAQCAtMCwwICsxLDc4IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDA5LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5pbWFwOworCitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOworCitpbXBvcnQgamF2YXgubWFpbC5TZXNzaW9uOworaW1wb3J0IGphdmF4Lm1haWwuU3RvcmU7CitpbXBvcnQgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb247CisKK2ltcG9ydCBjb20uc3VuLm1haWwudGVzdC5UZXN0U2VydmVyOworCitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuZmFpbDsKKworLyoqCisgKiBUZXN0IGxvZ2luIHVzaW5nIGEgU0FTTCBtZWNoYW5pc20uCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBJTUFQU2FzbExvZ2luVGVzdCB7CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHRoYXQgbG9naW4gdXNpbmcgYSBTQVNMIG1lY2hhbmlzbSB3b3Jrcy4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RTYXNsTG9naW4oKSB7CisJVGVzdFNlcnZlciBzZXJ2ZXIgPSBudWxsOworCXRyeSB7CisJICAgIElNQVBIYW5kbGVyIGhhbmRsZXIgPSBuZXcgSU1BUFNhc2xIYW5kbGVyKCk7CisJICAgIHNlcnZlciA9IG5ldyBUZXN0U2VydmVyKGhhbmRsZXIpOworCSAgICBzZXJ2ZXIuc3RhcnQoKTsKKworCSAgICBQcm9wZXJ0aWVzIHByb3BlcnRpZXMgPSBuZXcgUHJvcGVydGllcygpOworCSAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLmltYXAuaG9zdCIsICJsb2NhbGhvc3QiKTsKKwkgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5pbWFwLnBvcnQiLCAiIiArIHNlcnZlci5nZXRQb3J0KCkpOworCSAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLmltYXAuc2FzbC5lbmFibGUiLCAidHJ1ZSIpOworCSAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLmltYXAuc2FzbC5tZWNoYW5pc21zIiwgIkRJR0VTVC1NRDUiKTsKKwkgICAgU2Vzc2lvbiBzZXNzaW9uID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShwcm9wZXJ0aWVzKTsKKwkgICAgLy9zZXNzaW9uLnNldERlYnVnKHRydWUpOworCisJICAgIFN0b3JlIHN0b3JlID0gc2Vzc2lvbi5nZXRTdG9yZSgiaW1hcCIpOworCSAgICB0cnkgeworCQlzdG9yZS5jb25uZWN0KCJ0ZXN0IiwgInRlc3QiKTsKKwkJLy8gc3VjY2VzcyEKKwkgICAgfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIG1leCkgeworCQlmYWlsKCJsb2dpbiBmYWlsZWQiKTsKKwkgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJCVN5c3RlbS5vdXQucHJpbnRsbihleCk7CisJCS8vZXgucHJpbnRTdGFja1RyYWNlKCk7CisJCWZhaWwoZXgudG9TdHJpbmcoKSk7CisJICAgIH0gZmluYWxseSB7CisJCXN0b3JlLmNsb3NlKCk7CisJICAgIH0KKworCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisJICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisJICAgIGZhaWwoZS5nZXRNZXNzYWdlKCkpOworCX0gZmluYWxseSB7CisJICAgIGlmIChzZXJ2ZXIgIT0gbnVsbCkgeworCQlzZXJ2ZXIucXVpdCgpOworCSAgICB9CisJfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9JTUFQU2VhcmNoVGVzdC5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0lNQVBTZWFyY2hUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmUyNjJhNwotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9JTUFQU2VhcmNoVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTU3IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDA5LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5pbWFwOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKKworaW1wb3J0IGphdmF4Lm1haWwuRm9sZGVyOworaW1wb3J0IGphdmF4Lm1haWwuU2Vzc2lvbjsKK2ltcG9ydCBqYXZheC5tYWlsLlN0b3JlOworaW1wb3J0IGphdmF4Lm1haWwuTWVzc2FnZTsKK2ltcG9ydCBqYXZheC5tYWlsLnNlYXJjaC4qOworCitpbXBvcnQgY29tLnN1bi5tYWlsLnRlc3QuVGVzdFNlcnZlcjsKKworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5SdWxlOworaW1wb3J0IG9yZy5qdW5pdC5ydWxlcy5UaW1lb3V0OworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEVxdWFsczsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5mYWlsOworCisvKioKKyAqIFRlc3QgdGhlIHNlYXJjaCBtZXRob2QuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBJTUFQU2VhcmNoVGVzdCB7CisKKyAgICAvLyB0aW1lb3V0IHRoZSB0ZXN0IGluIGNhc2Ugb2YgZGVhZGxvY2sKKyAgICBAUnVsZQorICAgIHB1YmxpYyBUaW1lb3V0IGRlYWRsb2NrVGltZW91dCA9IFRpbWVvdXQuc2Vjb25kcygyMCk7CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RXaXRoaW5Ob3RTdXBwb3J0ZWQoKSB7CisgICAgICAgIFRlc3RTZXJ2ZXIgc2VydmVyID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNlcnZlciA9IG5ldyBUZXN0U2VydmVyKG5ldyBJTUFQSGFuZGxlcigpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIHNlYXJjaChTdHJpbmcgbGluZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkJICAgIGJhZCgiV0lUSElOIG5vdCBzdXBwb3J0ZWQiKTsKKwkJfQorCSAgICB9KTsKKyAgICAgICAgICAgIHNlcnZlci5zdGFydCgpOworCisgICAgICAgICAgICBmaW5hbCBQcm9wZXJ0aWVzIHByb3BlcnRpZXMgPSBuZXcgUHJvcGVydGllcygpOworICAgICAgICAgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5pbWFwLmhvc3QiLCAibG9jYWxob3N0Iik7CisgICAgICAgICAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLmltYXAucG9ydCIsICIiICsgc2VydmVyLmdldFBvcnQoKSk7CisgICAgICAgICAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLmltYXAudGhyb3dzZWFyY2hleGNlcHRpb24iLCAidHJ1ZSIpOworICAgICAgICAgICAgZmluYWwgU2Vzc2lvbiBzZXNzaW9uID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShwcm9wZXJ0aWVzKTsKKyAgICAgICAgICAgIC8vc2Vzc2lvbi5zZXREZWJ1Zyh0cnVlKTsKKworICAgICAgICAgICAgZmluYWwgU3RvcmUgc3RvcmUgPSBzZXNzaW9uLmdldFN0b3JlKCJpbWFwIik7CisJICAgIEZvbGRlciBmb2xkZXIgPSBudWxsOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdG9yZS5jb25uZWN0KCJ0ZXN0IiwgInRlc3QiKTsKKyAgICAgICAgICAgICAgICBmb2xkZXIgPSBzdG9yZS5nZXRGb2xkZXIoIklOQk9YIik7CisgICAgICAgICAgICAgICAgZm9sZGVyLm9wZW4oRm9sZGVyLlJFQURfT05MWSk7CisJCU1lc3NhZ2VbXSBtc2dzID0gZm9sZGVyLnNlYXJjaChuZXcgWW91bmdlclRlcm0oMSkpOworCQlmYWlsKCJzZWFyY2ggZGlkbid0IGZhaWwiKTsKKwkgICAgfSBjYXRjaCAoU2VhcmNoRXhjZXB0aW9uIGV4KSB7CisJCS8vIHN1Y2Nlc3MhCisJICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCQlTeXN0ZW0ub3V0LnByaW50bG4oZXgpOworCQkvL2V4LnByaW50U3RhY2tUcmFjZSgpOworCQlmYWlsKGV4LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKwkJaWYgKGZvbGRlciAhPSBudWxsKQorCQkgICAgZm9sZGVyLmNsb3NlKGZhbHNlKTsKKyAgICAgICAgICAgICAgICBzdG9yZS5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChmaW5hbCBFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgIGZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKHNlcnZlciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgc2VydmVyLnF1aXQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCB3aGVuIHRoZSBzZXJ2ZXIgc3VwcG9ydHMgVVRGOCBhbmQgdGhlIGNsaWVudCBlbmFibGVzIGl0LAorICAgICAqIHRoZSBjbGllbnQgZG9lc24ndCBpc3N1ZSBhIFNFQVJDSCBDSEFSU0VUIGNvbW1hbmQgZXZlbiBpZiB0aGUgc2VhcmNoCisgICAgICogdGVybSBpbmNsdWRlcyBhIG5vbi1BU0NJSSBjaGFyYWN0ZXIuCisgICAgICogKHNlZSBSRkMgNjg1NSwgc2VjdGlvbiAzLCBsYXN0IHBhcmFncmFwaCkKKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RVdGY4U2VhcmNoKCkgeworICAgICAgICBUZXN0U2VydmVyIHNlcnZlciA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzZXJ2ZXIgPSBuZXcgVGVzdFNlcnZlcihuZXcgSU1BUFV0ZjhIYW5kbGVyKCkgeworCQlAT3ZlcnJpZGUKKwkJcHVibGljIHZvaWQgc2VhcmNoKFN0cmluZyBsaW5lKSB0aHJvd3MgSU9FeGNlcHRpb24geworCQkgICAgaWYgKGxpbmUuY29udGFpbnMoIkNIQVJTRVQiKSkKKwkJCWJhZCgiQ0hBUlNFVCBub3Qgc3VwcG9ydGVkIik7CisJCSAgICBlbHNlCisJCQlvaygpOworCQl9CisJICAgIH0pOworICAgICAgICAgICAgc2VydmVyLnN0YXJ0KCk7CisKKyAgICAgICAgICAgIGZpbmFsIFByb3BlcnRpZXMgcHJvcGVydGllcyA9IG5ldyBQcm9wZXJ0aWVzKCk7CisgICAgICAgICAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLmltYXAuaG9zdCIsICJsb2NhbGhvc3QiKTsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuaW1hcC5wb3J0IiwgIiIgKyBzZXJ2ZXIuZ2V0UG9ydCgpKTsKKyAgICAgICAgICAgIGZpbmFsIFNlc3Npb24gc2Vzc2lvbiA9IFNlc3Npb24uZ2V0SW5zdGFuY2UocHJvcGVydGllcyk7CisgICAgICAgICAgICAvL3Nlc3Npb24uc2V0RGVidWcodHJ1ZSk7CisKKyAgICAgICAgICAgIGZpbmFsIFN0b3JlIHN0b3JlID0gc2Vzc2lvbi5nZXRTdG9yZSgiaW1hcCIpOworCSAgICBGb2xkZXIgZm9sZGVyID0gbnVsbDsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc3RvcmUuY29ubmVjdCgidGVzdCIsICJ0ZXN0Iik7CisgICAgICAgICAgICAgICAgZm9sZGVyID0gc3RvcmUuZ2V0Rm9sZGVyKCJJTkJPWCIpOworICAgICAgICAgICAgICAgIGZvbGRlci5vcGVuKEZvbGRlci5SRUFEX09OTFkpOworCQlNZXNzYWdlW10gbXNncyA9IGZvbGRlci5zZWFyY2gobmV3IFN1YmplY3RUZXJtKCJcdTIwMTkiKSk7CisJICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCQlTeXN0ZW0ub3V0LnByaW50bG4oZXgpOworCQkvL2V4LnByaW50U3RhY2tUcmFjZSgpOworCQlmYWlsKGV4LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKwkJaWYgKGZvbGRlciAhPSBudWxsKQorCQkgICAgZm9sZGVyLmNsb3NlKGZhbHNlKTsKKyAgICAgICAgICAgICAgICBzdG9yZS5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChmaW5hbCBFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgIGZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKHNlcnZlciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgc2VydmVyLnF1aXQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEFuIElNQVBIYW5kbGVyIHRoYXQgZW5hYmxlcyBVVEYtOCBzdXBwb3J0LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIElNQVBVdGY4SGFuZGxlciBleHRlbmRzIElNQVBIYW5kbGVyIHsKKwl7eyBjYXBhYmlsaXRpZXMgKz0gIiBFTkFCTEUgVVRGOD1BQ0NFUFQiOyB9fQorCisJQE92ZXJyaWRlCisJcHVibGljIHZvaWQgZW5hYmxlKFN0cmluZyBsaW5lKSB0aHJvd3MgSU9FeGNlcHRpb24geworCSAgICBvaygpOworCX0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL2ltYXAvSU1BUFN0b3JlVGVzdC5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0lNQVBTdG9yZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YmI2MzEyCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL0lNQVBTdG9yZVRlc3QuamF2YQpAQCAtMCwwICsxLDQxNyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwOSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuaW1hcDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7CitpbXBvcnQgamF2YS51dGlsLlN0cmluZ1Rva2VuaXplcjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5hdG9taWMuQXRvbWljSW50ZWdlcjsKKworaW1wb3J0IGphdmF4Lm1haWwuRm9sZGVyOworaW1wb3J0IGphdmF4Lm1haWwuU2Vzc2lvbjsKK2ltcG9ydCBqYXZheC5tYWlsLlN0b3JlOworaW1wb3J0IGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uOworCitpbXBvcnQgY29tLnN1bi5tYWlsLnRlc3QuVGVzdFNlcnZlcjsKKworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5SdWxlOworaW1wb3J0IG9yZy5qdW5pdC5ydWxlcy5UaW1lb3V0OworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEVxdWFsczsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUcnVlOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEZhbHNlOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmZhaWw7CisKKy8qKgorICogVGVzdCBJTUFQU3RvcmUgbWV0aG9kcy4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIElNQVBTdG9yZVRlc3QgeworCisgICAgLy8gdGltZW91dCB0aGUgdGVzdCBpbiBjYXNlIG9mIGRlYWRsb2NrCisgICAgQFJ1bGUKKyAgICBwdWJsaWMgVGltZW91dCBkZWFkbG9ja1RpbWVvdXQgPSBUaW1lb3V0LnNlY29uZHMoMjApOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIHV0ZjhGb2xkZXIgPSAidGVzdFx1MDNiMSI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIHV0ZjdGb2xkZXIgPSAidGVzdCZBN0UtIjsKKworICAgIHB1YmxpYyBzdGF0aWMgYWJzdHJhY3QgY2xhc3MgSU1BUFRlc3QgeworCXB1YmxpYyB2b2lkIGluaXQoUHJvcGVydGllcyBwcm9wcykgeyB9OworCXB1YmxpYyB2b2lkIHRlc3QoU3RvcmUgc3RvcmUsIFRlc3RTZXJ2ZXIgc2VydmVyKSB0aHJvd3MgRXhjZXB0aW9uIHsgfTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHRoYXQgVVRGLTggdXNlciBuYW1lIHdvcmtzIHdpdGggTE9HSU4gYXV0aGVudGljYXRpb24uCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXRmOFVzZXJuYW1lTG9naW4oKSB7CisJdGVzdFdpdGhIYW5kbGVyKAorCSAgICBuZXcgSU1BUFRlc3QoKSB7CisJCUBPdmVycmlkZQorCQlwdWJsaWMgdm9pZCB0ZXN0KFN0b3JlIHN0b3JlLCBUZXN0U2VydmVyIHNlcnZlcikKKwkJCQkgICAgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworCQkgICAgc3RvcmUuY29ubmVjdCh1dGY4Rm9sZGVyLCB1dGY4Rm9sZGVyKTsKKwkJfQorCSAgICB9LAorCSAgICBuZXcgSU1BUExvZ2luSGFuZGxlcigpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIGF1dGhsb2dpbihTdHJpbmcgaXIpCisJCQkJCXRocm93cyBJT0V4Y2VwdGlvbiB7CisJCSAgICB1c2VybmFtZSA9IHV0ZjhGb2xkZXI7CisJCSAgICBwYXNzd29yZCA9IHV0ZjhGb2xkZXI7CisJCSAgICBzdXBlci5hdXRobG9naW4oaXIpOworCQl9CisJICAgIH0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCBVVEYtOCB1c2VyIG5hbWUgd29ya3Mgd2l0aCBQTEFJTiBhdXRoZW50aWNhdGlvbi4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RVdGY4VXNlcm5hbWVQbGFpbigpIHsKKwl0ZXN0V2l0aEhhbmRsZXIoCisJICAgIG5ldyBJTUFQVGVzdCgpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIHRlc3QoU3RvcmUgc3RvcmUsIFRlc3RTZXJ2ZXIgc2VydmVyKQorCQkJCSAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisJCSAgICBzdG9yZS5jb25uZWN0KHV0ZjhGb2xkZXIsIHV0ZjhGb2xkZXIpOworCQl9CisJICAgIH0sCisJICAgIG5ldyBJTUFQUGxhaW5IYW5kbGVyKCkgeworCQlAT3ZlcnJpZGUKKwkJcHVibGljIHZvaWQgYXV0aHBsYWluKFN0cmluZyBpcikKKwkJCQkJdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkJICAgIHVzZXJuYW1lID0gdXRmOEZvbGRlcjsKKwkJICAgIHBhc3N3b3JkID0gdXRmOEZvbGRlcjsKKwkJICAgIHN1cGVyLmF1dGhwbGFpbihpcik7CisJCX0KKwkgICAgfSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IFVURi03IGZvbGRlciBuYW1lcyBpbiB0aGUgTkFNRVNQQUNFIGNvbW1hbmQgYXJlCisgICAgICogZGVjb2RlZCBwcm9wZXJseS4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RVdGY3TmFtZXNwYWNlcygpIHsKKwl0ZXN0V2l0aEhhbmRsZXIoCisJICAgIG5ldyBJTUFQVGVzdCgpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIHRlc3QoU3RvcmUgc3RvcmUsIFRlc3RTZXJ2ZXIgc2VydmVyKQorCQkJCSAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisJCSAgICBzdG9yZS5jb25uZWN0KCJ0ZXN0IiwgInRlc3QiKTsKKwkJICAgIEZvbGRlcltdIHB1YiA9ICgoSU1BUFN0b3JlKXN0b3JlKS5nZXRTaGFyZWROYW1lc3BhY2VzKCk7CisJCSAgICBhc3NlcnRFcXVhbHModXRmOEZvbGRlciwgcHViWzBdLmdldE5hbWUoKSk7CisJCX0KKwkgICAgfSwKKwkgICAgbmV3IElNQVBIYW5kbGVyKCkgeworCQl7eyBjYXBhYmlsaXRpZXMgKz0gIiBOQU1FU1BBQ0UiOyB9fQorCQlAT3ZlcnJpZGUKKwkJcHVibGljIHZvaWQgbmFtZXNwYWNlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkJICAgIHVudGFnZ2VkKCJOQU1FU1BBQ0UgKChcIlwiIFwiL1wiKSkgKChcIn5cIiBcIi9cIikpICIgKworCQkJIigoXCIiICsgdXRmN0ZvbGRlciArICIvXCIgXCIvXCIpKSIpOworCQkgICAgb2soKTsKKwkJfQorCSAgICB9KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHRoYXQgdXNpbmcgYSBVVEYtOCBmb2xkZXIgbmFtZSByZXN1bHRzIGluIHRoZSBwcm9wZXIgVVRGLTgKKyAgICAgKiB1bmVuY29kZWQgbmFtZSBmb3IgdGhlIENSRUFURSBjb21tYW5kLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFV0ZjhGb2xkZXJOYW1lQ3JlYXRlKCkgeworCXRlc3RXaXRoSGFuZGxlcigKKwkgICAgbmV3IElNQVBUZXN0KCkgeworCQlAT3ZlcnJpZGUKKwkJcHVibGljIHZvaWQgdGVzdChTdG9yZSBzdG9yZSwgVGVzdFNlcnZlciBzZXJ2ZXIpCisJCQkJICAgIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKwkJICAgIHN0b3JlLmNvbm5lY3QoInRlc3QiLCAidGVzdCIpOworCQkgICAgRm9sZGVyIHRlc3QgPSBzdG9yZS5nZXRGb2xkZXIodXRmOEZvbGRlcik7CisJCSAgICBhc3NlcnRUcnVlKHRlc3QuY3JlYXRlKEZvbGRlci5IT0xEU19NRVNTQUdFUykpOworCQl9CisJICAgIH0sCisJICAgIG5ldyBJTUFQVXRmOEhhbmRsZXIoKSB7CisJCUBPdmVycmlkZQorCQlwdWJsaWMgdm9pZCBjcmVhdGUoU3RyaW5nIGxpbmUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJCSAgICBTdHJpbmdUb2tlbml6ZXIgc3QgPSBuZXcgU3RyaW5nVG9rZW5pemVyKGxpbmUpOworCQkgICAgc3QubmV4dFRva2VuKCk7CS8vIHNraXAgdGFnCisJCSAgICBzdC5uZXh0VG9rZW4oKTsJLy8gc2tpcCAiQ1JFQVRFIgorCQkgICAgU3RyaW5nIG5hbWUgPSB1bnF1b3RlKHN0Lm5leHRUb2tlbigpKTsKKwkJICAgIGlmIChuYW1lLmVxdWFscyh1dGY4Rm9sZGVyKSkKKwkJCW9rKCk7CisJCSAgICBlbHNlCisJCQlubygid3JvbmcgbmFtZSIpOworCQl9CisKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIGxpc3QoU3RyaW5nIGxpbmUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJCSAgICB1bnRhZ2dlZCgiTElTVCAoXFxIYXNOb0NoaWxkcmVuKSBcIi9cIiBcIiIgKworCQkJCQkJCXV0ZjhGb2xkZXIgKyAiXCIiKTsKKwkJICAgIG9rKCk7CisJCX0KKwkgICAgfSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IFN0b3JlLmNsb3NlIGFsc28gY2xvc2VzIG9wZW4gRm9sZGVycy4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RDbG9zZUNsb3Nlc0ZvbGRlcigpIHsKKwl0ZXN0V2l0aEhhbmRsZXIoCisJICAgIG5ldyBJTUFQVGVzdCgpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIHRlc3QoU3RvcmUgc3RvcmUsIFRlc3RTZXJ2ZXIgc2VydmVyKQorCQkJCSAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisJCSAgICBzdG9yZS5jb25uZWN0KCJ0ZXN0IiwgInRlc3QiKTsKKwkJICAgIEZvbGRlciB0ZXN0ID0gc3RvcmUuZ2V0Rm9sZGVyKCJJTkJPWCIpOworCQkgICAgdGVzdC5vcGVuKEZvbGRlci5SRUFEX09OTFkpOworCQkgICAgc3RvcmUuY2xvc2UoKTsKKwkJICAgIGFzc2VydEZhbHNlKHRlc3QuaXNPcGVuKCkpOworCQkgICAgYXNzZXJ0RXF1YWxzKDEsIHNlcnZlci5jbGllbnRDb3VudCgpKTsKKwkJICAgIHNlcnZlci53YWl0Rm9yQ2xpZW50cygxKTsKKwkJICAgIC8vIHRlc3Qgd2lsbCB0aW1lb3V0IGlmIGNsaWVudHMgZG9uJ3QgdGVybWluYXRlCisJCX0KKwkgICAgfSwKKwkgICAgbmV3IElNQVBIYW5kbGVyKCkgeworCSAgICB9KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHRoYXQgU3RvcmUuY2xvc2UgY2xvc2VzIGNvbm5lY3Rpb25zIGluIHRoZSBwb29sLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENsb3NlRW1wdGllc1Bvb2woKSB7CisJdGVzdFdpdGhIYW5kbGVyKAorCSAgICBuZXcgSU1BUFRlc3QoKSB7CisJCUBPdmVycmlkZQorCQlwdWJsaWMgdm9pZCBpbml0KFByb3BlcnRpZXMgcHJvcHMpIHsKKwkJICAgIHByb3BzLnNldFByb3BlcnR5KCJtYWlsLmltYXAuY29ubmVjdGlvbnBvb2xzaXplIiwgIjIiKTsKKwkJfQorCisJCUBPdmVycmlkZQorCQlwdWJsaWMgdm9pZCB0ZXN0KFN0b3JlIHN0b3JlLCBUZXN0U2VydmVyIHNlcnZlcikKKwkJCQkgICAgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworCQkgICAgc3RvcmUuY29ubmVjdCgidGVzdCIsICJ0ZXN0Iik7CisJCSAgICBGb2xkZXIgdGVzdCA9IHN0b3JlLmdldEZvbGRlcigiSU5CT1giKTsKKwkJICAgIHRlc3Qub3BlbihGb2xkZXIuUkVBRF9PTkxZKTsKKwkJICAgIEZvbGRlciB0ZXN0MiA9IHN0b3JlLmdldEZvbGRlcigiSU5CT1giKTsKKwkJICAgIHRlc3QyLm9wZW4oRm9sZGVyLlJFQURfT05MWSk7CisJCSAgICB0ZXN0LmNsb3NlKGZhbHNlKTsKKwkJICAgIHRlc3QyLmNsb3NlKGZhbHNlKTsKKwkJICAgIHN0b3JlLmNsb3NlKCk7CisJCSAgICBhc3NlcnRFcXVhbHMoMiwgc2VydmVyLmNsaWVudENvdW50KCkpOworCQkgICAgc2VydmVyLndhaXRGb3JDbGllbnRzKDIpOworCQkgICAgLy8gdGVzdCB3aWxsIHRpbWVvdXQgaWYgY2xpZW50cyBkb24ndCB0ZXJtaW5hdGUKKwkJfQorCSAgICB9LAorCSAgICBuZXcgSU1BUEhhbmRsZXIoKSB7CisJICAgIH0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCBTdG9yZSBmYWlsdXJlcyBkb24ndCBjbG9zZSBGb2xkZXJzLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFN0b3JlRmFpbHVyZURvZXNOb3RDbG9zZUZvbGRlcigpIHsKKwl0ZXN0V2l0aEhhbmRsZXIoCisJICAgIG5ldyBJTUFQVGVzdCgpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIGluaXQoUHJvcGVydGllcyBwcm9wcykgeworCQkgICAgcHJvcHMuc2V0UHJvcGVydHkoCisJCQkibWFpbC5pbWFwLmNsb3NlZm9sZGVyc29uc3RvcmVmYWlsdXJlIiwgImZhbHNlIik7CisJCX0KKworCQlAT3ZlcnJpZGUKKwkJcHVibGljIHZvaWQgdGVzdChTdG9yZSBzdG9yZSwgVGVzdFNlcnZlciBzZXJ2ZXIpCisJCQkJICAgIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKwkJICAgIHN0b3JlLmNvbm5lY3QoInRlc3QiLCAidGVzdCIpOworCQkgICAgRm9sZGVyIHRlc3QgPSBzdG9yZS5nZXRGb2xkZXIoIklOQk9YIik7CisJCSAgICB0ZXN0Lm9wZW4oRm9sZGVyLlJFQURfT05MWSk7CisJCSAgICB0cnkgeworCQkJKChJTUFQU3RvcmUpc3RvcmUpLmdldFNoYXJlZE5hbWVzcGFjZXMoKTsKKwkJCWZhaWwoIk1lc3NhZ2luZ0V4Y2VwdGlvbiBleHBlY3RlZCIpOworCQkgICAgfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIG1leCkgeworCQkJLy8gZXhwZWN0ZWQKKwkJICAgIH0KKwkJICAgIGFzc2VydFRydWUodGVzdC5pc09wZW4oKSk7CisJCSAgICBzdG9yZS5jbG9zZSgpOworCQkgICAgYXNzZXJ0RmFsc2UodGVzdC5pc09wZW4oKSk7CisJCSAgICBhc3NlcnRFcXVhbHMoMiwgc2VydmVyLmNsaWVudENvdW50KCkpOworCQkgICAgc2VydmVyLndhaXRGb3JDbGllbnRzKDIpOworCQkgICAgLy8gdGVzdCB3aWxsIHRpbWVvdXQgaWYgY2xpZW50cyBkb24ndCB0ZXJtaW5hdGUKKwkJfQorCSAgICB9LAorCSAgICBuZXcgSU1BUEhhbmRsZXIoKSB7CisJCXt7IGNhcGFiaWxpdGllcyArPSAiIE5BTUVTUEFDRSI7IH19CisKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIG5hbWVzcGFjZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJCSAgICBleGl0KCk7CisJCX0KKwkgICAgfSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IFN0b3JlLmNsb3NlIGFmdGVyIFN0b3JlIGZhaWx1cmUgd2lsbCBjbG9zZSBhbGwgRm9sZGVycworICAgICAqIGFuZCBlbXB0eSB0aGUgY29ubmVjdGluIHBvb2wuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2xvc2VBZnRlckZhaWx1cmUoKSB7CisJdGVzdFdpdGhIYW5kbGVyKAorCSAgICBuZXcgSU1BUFRlc3QoKSB7CisJCUBPdmVycmlkZQorCQlwdWJsaWMgdm9pZCBpbml0KFByb3BlcnRpZXMgcHJvcHMpIHsKKwkJICAgIHByb3BzLnNldFByb3BlcnR5KAorCQkJIm1haWwuaW1hcC5jbG9zZWZvbGRlcnNvbnN0b3JlZmFpbHVyZSIsICJmYWxzZSIpOworCQl9CisKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIHRlc3QoU3RvcmUgc3RvcmUsIFRlc3RTZXJ2ZXIgc2VydmVyKQorCQkJCSAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisJCSAgICBzdG9yZS5jb25uZWN0KCJ0ZXN0IiwgInRlc3QiKTsKKwkJICAgIEZvbGRlciB0ZXN0ID0gc3RvcmUuZ2V0Rm9sZGVyKCJJTkJPWCIpOworCQkgICAgdGVzdC5vcGVuKEZvbGRlci5SRUFEX09OTFkpOworCQkgICAgdHJ5IHsKKwkJCSgoSU1BUFN0b3JlKXN0b3JlKS5nZXRTaGFyZWROYW1lc3BhY2VzKCk7CisJCQlmYWlsKCJNZXNzYWdpbmdFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKwkJICAgIH0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBtZXgpIHsKKwkJCS8vIGV4cGVjdGVkCisJCSAgICB9CisJCSAgICBhc3NlcnRUcnVlKHRlc3QuaXNPcGVuKCkpOworCQkgICAgdGVzdC5jbG9zZSgpOwkvLyBwdXQgaXQgYmFjayBpbiB0aGUgcG9vbAorCQkgICAgc3RvcmUuY2xvc2UoKTsKKwkJICAgIGFzc2VydEVxdWFscygyLCBzZXJ2ZXIuY2xpZW50Q291bnQoKSk7CisJCSAgICBzZXJ2ZXIud2FpdEZvckNsaWVudHMoMik7CisJCSAgICAvLyB0ZXN0IHdpbGwgdGltZW91dCBpZiBjbGllbnRzIGRvbid0IHRlcm1pbmF0ZQorCQl9CisJICAgIH0sCisJICAgIG5ldyBJTUFQSGFuZGxlcigpIHsKKwkJe3sgY2FwYWJpbGl0aWVzICs9ICIgTkFNRVNQQUNFIjsgfX0KKworCQlAT3ZlcnJpZGUKKwkJcHVibGljIHZvaWQgbmFtZXNwYWNlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkJICAgIGV4aXQoKTsKKwkJfQorCSAgICB9KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHRoYXQgU3RvcmUgZmFpbHVyZXMgZG8gY2xvc2UgRm9sZGVycy4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RTdG9yZUZhaWx1cmVEb2VzQ2xvc2VGb2xkZXIoKSB7CisJdGVzdFdpdGhIYW5kbGVyKAorCSAgICBuZXcgSU1BUFRlc3QoKSB7CisJCUBPdmVycmlkZQorCQlwdWJsaWMgdm9pZCBpbml0KFByb3BlcnRpZXMgcHJvcHMpIHsKKwkJICAgIHByb3BzLnNldFByb3BlcnR5KAorCQkJLy8gdGhlIGRlZmF1bHQsIGJ1dCBqdXN0IHRvIGJlIHN1cmUuLi4KKwkJCSJtYWlsLmltYXAuY2xvc2Vmb2xkZXJzb25zdG9yZWZhaWx1cmUiLCAidHJ1ZSIpOworCQl9CisKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIHRlc3QoU3RvcmUgc3RvcmUsIFRlc3RTZXJ2ZXIgc2VydmVyKQorCQkJCSAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisJCSAgICBzdG9yZS5jb25uZWN0KCJ0ZXN0IiwgInRlc3QiKTsKKwkJICAgIEZvbGRlciB0ZXN0ID0gc3RvcmUuZ2V0Rm9sZGVyKCJJTkJPWCIpOworCQkgICAgdGVzdC5vcGVuKEZvbGRlci5SRUFEX09OTFkpOworCQkgICAgdHJ5IHsKKwkJCSgoSU1BUFN0b3JlKXN0b3JlKS5nZXRTaGFyZWROYW1lc3BhY2VzKCk7CisJCQlmYWlsKCJNZXNzYWdpbmdFeGNlcHRpb24gZXhwZWN0ZWQiKTsKKwkJICAgIH0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBtZXgpIHsKKwkJCS8vIGV4cGVjdGVkCisJCSAgICB9CisJCSAgICBhc3NlcnRGYWxzZSh0ZXN0LmlzT3BlbigpKTsKKwkJICAgIHN0b3JlLmNsb3NlKCk7CisJCSAgICBhc3NlcnRFcXVhbHMoMiwgc2VydmVyLmNsaWVudENvdW50KCkpOworCQkgICAgc2VydmVyLndhaXRGb3JDbGllbnRzKDIpOworCQkgICAgLy8gdGVzdCB3aWxsIHRpbWVvdXQgaWYgY2xpZW50cyBkb24ndCB0ZXJtaW5hdGUKKwkJfQorCSAgICB9LAorCSAgICBuZXcgSU1BUEhhbmRsZXIoKSB7CisJCXt7IGNhcGFiaWxpdGllcyArPSAiIE5BTUVTUEFDRSI7IH19CisKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIG5hbWVzcGFjZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJCSAgICBleGl0KCk7CisJCX0KKwkgICAgfSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RXaXRoSGFuZGxlcihJTUFQVGVzdCB0ZXN0LCBJTUFQSGFuZGxlciBoYW5kbGVyKSB7CisgICAgICAgIFRlc3RTZXJ2ZXIgc2VydmVyID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNlcnZlciA9IG5ldyBUZXN0U2VydmVyKGhhbmRsZXIpOworICAgICAgICAgICAgc2VydmVyLnN0YXJ0KCk7CisKKyAgICAgICAgICAgIGZpbmFsIFByb3BlcnRpZXMgcHJvcGVydGllcyA9IG5ldyBQcm9wZXJ0aWVzKCk7CisgICAgICAgICAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLmltYXAuaG9zdCIsICJsb2NhbGhvc3QiKTsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuaW1hcC5wb3J0IiwgIiIgKyBzZXJ2ZXIuZ2V0UG9ydCgpKTsKKwkgICAgdGVzdC5pbml0KHByb3BlcnRpZXMpOworICAgICAgICAgICAgZmluYWwgU2Vzc2lvbiBzZXNzaW9uID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShwcm9wZXJ0aWVzKTsKKyAgICAgICAgICAgIC8vc2Vzc2lvbi5zZXREZWJ1Zyh0cnVlKTsKKworICAgICAgICAgICAgZmluYWwgU3RvcmUgc3RvcmUgPSBzZXNzaW9uLmdldFN0b3JlKCJpbWFwIik7CisgICAgICAgICAgICB0cnkgeworCQl0ZXN0LnRlc3Qoc3RvcmUsIHNlcnZlcik7CisJICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCQlTeXN0ZW0ub3V0LnByaW50bG4oZXgpOworCQkvL2V4LnByaW50U3RhY2tUcmFjZSgpOworCQlmYWlsKGV4LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBzdG9yZS5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChmaW5hbCBFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgIGZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKHNlcnZlciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgc2VydmVyLnF1aXQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyB1bnF1b3RlKFN0cmluZyBzKSB7CisJaWYgKHMuc3RhcnRzV2l0aCgiXCIiKSAmJiBzLmVuZHNXaXRoKCJcIiIpICYmIHMubGVuZ3RoKCkgPiAxKSB7CisJICAgIHMgPSBzLnN1YnN0cmluZygxLCBzLmxlbmd0aCgpIC0gMSk7CisJICAgIC8vIGNoZWNrIGZvciBhbnkgZXNjYXBlZCBjaGFyYWN0ZXJzCisJICAgIGlmIChzLmluZGV4T2YoJ1xcJykgPj0gMCkgeworCQlTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIocy5sZW5ndGgoKSk7CS8vIGFwcHJveAorCQlmb3IgKGludCBpID0gMDsgaSA8IHMubGVuZ3RoKCk7IGkrKykgeworCQkgICAgY2hhciBjID0gcy5jaGFyQXQoaSk7CisJCSAgICBpZiAoYyA9PSAnXFwnICYmIGkgPCBzLmxlbmd0aCgpIC0gMSkKKwkJCWMgPSBzLmNoYXJBdCgrK2kpOworCQkgICAgc2IuYXBwZW5kKGMpOworCQl9CisJCXMgPSBzYi50b1N0cmluZygpOworCSAgICB9CisJfQorCXJldHVybiBzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFuIElNQVBIYW5kbGVyIHRoYXQgZW5hYmxlcyBVVEYtOCBzdXBwb3J0LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIElNQVBVdGY4SGFuZGxlciBleHRlbmRzIElNQVBIYW5kbGVyIHsKKwl7eyBjYXBhYmlsaXRpZXMgKz0gIiBFTkFCTEUgVVRGOD1BQ0NFUFQiOyB9fQorCisJQE92ZXJyaWRlCisJcHVibGljIHZvaWQgZW5hYmxlKFN0cmluZyBsaW5lKSB0aHJvd3MgSU9FeGNlcHRpb24geworCSAgICBvaygpOworCX0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL2ltYXAvSU1BUFVpZEV4cHVuZ2VUZXN0LmphdmEgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL2ltYXAvSU1BUFVpZEV4cHVuZ2VUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmRiYzRlMQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9JTUFQVWlkRXhwdW5nZVRlc3QuamF2YQpAQCAtMCwwICsxLDQ2OCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwOSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuaW1hcDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7CitpbXBvcnQgamF2YS51dGlsLlN0cmluZ1Rva2VuaXplcjsKKworaW1wb3J0IGphdmF4Lm1haWwuRm9sZGVyOworaW1wb3J0IGphdmF4Lm1haWwuU2Vzc2lvbjsKK2ltcG9ydCBqYXZheC5tYWlsLlN0b3JlOworaW1wb3J0IGphdmF4Lm1haWwuTWVzc2FnZTsKK2ltcG9ydCBqYXZheC5tYWlsLlVJREZvbGRlcjsKK2ltcG9ydCBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbjsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC50ZXN0LlRlc3RTZXJ2ZXI7CisKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQuUnVsZTsKK2ltcG9ydCBvcmcuanVuaXQucnVsZXMuVGltZW91dDsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRFcXVhbHM7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0TnVsbDsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUcnVlOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmZhaWw7CisKKy8qKgorICogVGVzdCBFWFBVTkdFIHJlc3BvbnNlcyBkdXJpbmcgVUlEIEZFVENILgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgSU1BUFVpZEV4cHVuZ2VUZXN0IHsKKworICAgIC8vIHRpbWVvdXQgdGhlIHRlc3QgaW4gY2FzZSBvZiBkZWFkbG9jaworICAgIEBSdWxlCisgICAgcHVibGljIFRpbWVvdXQgZGVhZGxvY2tUaW1lb3V0ID0gVGltZW91dC5zZWNvbmRzKDIwKTsKKworICAgIHB1YmxpYyBzdGF0aWMgaW50ZXJmYWNlIElNQVBUZXN0IHsKKwlwdWJsaWMgdm9pZCB0ZXN0KEZvbGRlciBmb2xkZXIsIElNQVBIYW5kbGVyRXhwdW5nZSBoYW5kbGVyKQorCQkJCSAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFVJRFNpbmdsZSgpIHsKKwl0ZXN0V2l0aEhhbmRsZXIoCisJICAgIG5ldyBJTUFQVGVzdCgpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIHRlc3QoRm9sZGVyIGZvbGRlciwgSU1BUEhhbmRsZXJFeHB1bmdlIGhhbmRsZXIpCisJCQkJICAgIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCQkgICAgTWVzc2FnZSBtID0gKChVSURGb2xkZXIpZm9sZGVyKS5nZXRNZXNzYWdlQnlVSUQoMik7CisJCSAgICBtLmdldEZsYWdzKCk7CisJCSAgICBhc3NlcnRFcXVhbHMoMSwgaGFuZGxlci5nZXRTZXFOdW0oKSk7CisJCX0KKwkgICAgfSwKKwkgICAgbmV3IElNQVBIYW5kbGVyRXhwdW5nZSgpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIHVpZGZldGNoKFN0cmluZyBsaW5lKSB0aHJvd3MgSU9FeGNlcHRpb24geworCQkgICAgdW50YWdnZWQoIjIgRkVUQ0ggKFVJRCAyKSIpOworCQkgICAgdW50YWdnZWQoIjEgRVhQVU5HRSIpOworCQkgICAgdW50YWdnZWQoIjMgRVhJU1RTIik7CisJCSAgICBudW1iZXJPZk1lc3NhZ2VzLS07CisJCSAgICBvaygpOworCQl9CisJICAgIH0pOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFVJRFNpbmdsZTIoKSB7CisJdGVzdFdpdGhIYW5kbGVyKAorCSAgICBuZXcgSU1BUFRlc3QoKSB7CisJCUBPdmVycmlkZQorCQlwdWJsaWMgdm9pZCB0ZXN0KEZvbGRlciBmb2xkZXIsIElNQVBIYW5kbGVyRXhwdW5nZSBoYW5kbGVyKQorCQkJCSAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwkJICAgIE1lc3NhZ2UgbSA9ICgoVUlERm9sZGVyKWZvbGRlcikuZ2V0TWVzc2FnZUJ5VUlEKDIpOworCQkgICAgbS5nZXRGbGFncygpOworCQkgICAgYXNzZXJ0RXF1YWxzKDIsIGhhbmRsZXIuZ2V0U2VxTnVtKCkpOworCQl9CisJICAgIH0sCisJICAgIG5ldyBJTUFQSGFuZGxlckV4cHVuZ2UoKSB7CisJCUBPdmVycmlkZQorCQlwdWJsaWMgdm9pZCB1aWRmZXRjaChTdHJpbmcgbGluZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkJICAgIHVudGFnZ2VkKCIyIEZFVENIIChVSUQgMikiKTsKKwkJICAgIHVudGFnZ2VkKCIzIEVYUFVOR0UiKTsKKwkJICAgIHVudGFnZ2VkKCIzIEVYSVNUUyIpOworCQkgICAgbnVtYmVyT2ZNZXNzYWdlcy0tOworCQkgICAgb2soKTsKKwkJfQorCSAgICB9KTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RVSURSYW5nZSgpIHsKKwl0ZXN0V2l0aEhhbmRsZXIoCisJICAgIG5ldyBJTUFQVGVzdCgpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIHRlc3QoRm9sZGVyIGZvbGRlciwgSU1BUEhhbmRsZXJFeHB1bmdlIGhhbmRsZXIpCisJCQkJICAgIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCQkgICAgTWVzc2FnZVtdIG1zZ3MgPSAoKFVJREZvbGRlcilmb2xkZXIpLmdldE1lc3NhZ2VzQnlVSUQoMiwgNCk7CisJCSAgICBhc3NlcnRUcnVlKG1zZ3NbMV0gPT0gbnVsbCB8fCBtc2dzWzFdLmlzRXhwdW5nZWQoKSk7CisJCSAgICBtc2dzWzBdLmdldEZsYWdzKCk7CisJCSAgICBhc3NlcnRFcXVhbHMoMiwgaGFuZGxlci5nZXRTZXFOdW0oKSk7CisJCSAgICBtc2dzWzJdLmdldEZsYWdzKCk7CisJCSAgICBhc3NlcnRFcXVhbHMoMywgaGFuZGxlci5nZXRTZXFOdW0oKSk7CisJCX0KKwkgICAgfSwKKwkgICAgbmV3IElNQVBIYW5kbGVyRXhwdW5nZSgpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIHVpZGZldGNoKFN0cmluZyBsaW5lKSB0aHJvd3MgSU9FeGNlcHRpb24geworCQkgICAgdW50YWdnZWQoIjIgRkVUQ0ggKFVJRCAyKSIpOworCQkgICAgdW50YWdnZWQoIjMgRkVUQ0ggKFVJRCAzKSIpOworCQkgICAgdW50YWdnZWQoIjQgRkVUQ0ggKFVJRCA0KSIpOworCQkgICAgdW50YWdnZWQoIjMgRVhQVU5HRSIpOworCQkgICAgdW50YWdnZWQoIjMgRVhJU1RTIik7CisJCSAgICBudW1iZXJPZk1lc3NhZ2VzLS07CisJCSAgICBvaygpOworCQl9CisJICAgIH0pOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFVJRFJhbmdlMigpIHsKKwl0ZXN0V2l0aEhhbmRsZXIoCisJICAgIG5ldyBJTUFQVGVzdCgpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIHRlc3QoRm9sZGVyIGZvbGRlciwgSU1BUEhhbmRsZXJFeHB1bmdlIGhhbmRsZXIpCisJCQkJICAgIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCQkgICAgTWVzc2FnZVtdIG1zZ3MgPSAoKFVJREZvbGRlcilmb2xkZXIpLmdldE1lc3NhZ2VzQnlVSUQoMiwgNCk7CisJCSAgICBhc3NlcnRUcnVlKG1zZ3NbMV0gPT0gbnVsbCB8fCBtc2dzWzFdLmlzRXhwdW5nZWQoKSk7CisJCSAgICBtc2dzWzBdLmdldEZsYWdzKCk7CisJCSAgICBhc3NlcnRFcXVhbHMoMiwgaGFuZGxlci5nZXRTZXFOdW0oKSk7CisJCSAgICBtc2dzWzJdLmdldEZsYWdzKCk7CisJCSAgICBhc3NlcnRFcXVhbHMoMywgaGFuZGxlci5nZXRTZXFOdW0oKSk7CisJCX0KKwkgICAgfSwKKwkgICAgbmV3IElNQVBIYW5kbGVyRXhwdW5nZSgpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIHVpZGZldGNoKFN0cmluZyBsaW5lKSB0aHJvd3MgSU9FeGNlcHRpb24geworCQkgICAgdW50YWdnZWQoIjIgRkVUQ0ggKFVJRCAyKSIpOworCQkgICAgdW50YWdnZWQoIjMgRkVUQ0ggKFVJRCAzKSIpOworCQkgICAgdW50YWdnZWQoIjMgRVhQVU5HRSIpOworCQkgICAgdW50YWdnZWQoIjMgRVhJU1RTIik7CisJCSAgICB1bnRhZ2dlZCgiMyBGRVRDSCAoVUlEIDQpIik7CisJCSAgICBudW1iZXJPZk1lc3NhZ2VzLS07CisJCSAgICBvaygpOworCQl9CisJICAgIH0pOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFVJRFJhbmdlMygpIHsKKwl0ZXN0V2l0aEhhbmRsZXIoCisJICAgIG5ldyBJTUFQVGVzdCgpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIHRlc3QoRm9sZGVyIGZvbGRlciwgSU1BUEhhbmRsZXJFeHB1bmdlIGhhbmRsZXIpCisJCQkJICAgIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCQkgICAgTWVzc2FnZVtdIG1zZ3MgPSAoKFVJREZvbGRlcilmb2xkZXIpLmdldE1lc3NhZ2VzQnlVSUQoMiwgNCk7CisJCSAgICAvLyBVSUQgMyBpcyB1bmtub3duIGFuZCBub3QgcmV0dXJuZWQKKwkJICAgIGFzc2VydEVxdWFscygyLCBtc2dzLmxlbmd0aCk7CisJCSAgICBtc2dzWzBdLmdldEZsYWdzKCk7CisJCSAgICBhc3NlcnRFcXVhbHMoMiwgaGFuZGxlci5nZXRTZXFOdW0oKSk7CisJCSAgICBtc2dzWzFdLmdldEZsYWdzKCk7CisJCSAgICBhc3NlcnRFcXVhbHMoMywgaGFuZGxlci5nZXRTZXFOdW0oKSk7CisJCX0KKwkgICAgfSwKKwkgICAgbmV3IElNQVBIYW5kbGVyRXhwdW5nZSgpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIHVpZGZldGNoKFN0cmluZyBsaW5lKSB0aHJvd3MgSU9FeGNlcHRpb24geworCQkgICAgdW50YWdnZWQoIjIgRkVUQ0ggKFVJRCAyKSIpOworCQkgICAgdW50YWdnZWQoIjMgRVhQVU5HRSIpOworCQkgICAgdW50YWdnZWQoIjMgRVhJU1RTIik7CisJCSAgICB1bnRhZ2dlZCgiMyBGRVRDSCAoVUlEIDQpIik7CisJCSAgICBudW1iZXJPZk1lc3NhZ2VzLS07CisJCSAgICBvaygpOworCQl9CisJICAgIH0pOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFVJRFJhbmdlNCgpIHsKKwl0ZXN0V2l0aEhhbmRsZXIoCisJICAgIG5ldyBJTUFQVGVzdCgpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIHRlc3QoRm9sZGVyIGZvbGRlciwgSU1BUEhhbmRsZXJFeHB1bmdlIGhhbmRsZXIpCisJCQkJICAgIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCQkgICAgTWVzc2FnZVtdIG1zZ3MgPSAoKFVJREZvbGRlcilmb2xkZXIpLmdldE1lc3NhZ2VzQnlVSUQoMSwgMyk7CisJCSAgICBhc3NlcnRFcXVhbHMoMywgbXNncy5sZW5ndGgpOworCQkgICAgbXNnc1swXS5nZXRGbGFncygpOworCQkgICAgYXNzZXJ0RXF1YWxzKDEsIGhhbmRsZXIuZ2V0U2VxTnVtKCkpOworCQkgICAgbXNnc1sxXS5nZXRGbGFncygpOworCQkgICAgYXNzZXJ0RXF1YWxzKDIsIGhhbmRsZXIuZ2V0U2VxTnVtKCkpOworCQkgICAgbXNnc1syXS5nZXRGbGFncygpOworCQkgICAgYXNzZXJ0RXF1YWxzKDMsIGhhbmRsZXIuZ2V0U2VxTnVtKCkpOworCQl9CisJICAgIH0sCisJICAgIG5ldyBJTUFQSGFuZGxlckV4cHVuZ2UoKSB7CisJCUBPdmVycmlkZQorCQlwdWJsaWMgdm9pZCB1aWRmZXRjaChTdHJpbmcgbGluZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkJICAgIHVudGFnZ2VkKCIxIEZFVENIIChVSUQgMSkiKTsKKwkJICAgIHVudGFnZ2VkKCIyIEZFVENIIChVSUQgMikiKTsKKwkJICAgIHVudGFnZ2VkKCIzIEZFVENIIChVSUQgMykiKTsKKwkJICAgIHVudGFnZ2VkKCI0IEVYUFVOR0UiKTsKKwkJICAgIHVudGFnZ2VkKCIzIEVYSVNUUyIpOworCQkgICAgbnVtYmVyT2ZNZXNzYWdlcy0tOworCQkgICAgb2soKTsKKwkJfQorCSAgICB9KTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RVSURSYW5nZTUoKSB7CisJdGVzdFdpdGhIYW5kbGVyKAorCSAgICBuZXcgSU1BUFRlc3QoKSB7CisJCUBPdmVycmlkZQorCQlwdWJsaWMgdm9pZCB0ZXN0KEZvbGRlciBmb2xkZXIsIElNQVBIYW5kbGVyRXhwdW5nZSBoYW5kbGVyKQorCQkJCSAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwkJICAgIE1lc3NhZ2VbXSBtc2dzID0gKChVSURGb2xkZXIpZm9sZGVyKS5nZXRNZXNzYWdlc0J5VUlEKDIsIDQpOworCQkgICAgYXNzZXJ0RXF1YWxzKDMsIG1zZ3MubGVuZ3RoKTsKKwkJICAgIG1zZ3NbMF0uZ2V0RmxhZ3MoKTsKKwkJICAgIGFzc2VydEVxdWFscygxLCBoYW5kbGVyLmdldFNlcU51bSgpKTsKKwkJICAgIG1zZ3NbMV0uZ2V0RmxhZ3MoKTsKKwkJICAgIGFzc2VydEVxdWFscygyLCBoYW5kbGVyLmdldFNlcU51bSgpKTsKKwkJICAgIG1zZ3NbMl0uZ2V0RmxhZ3MoKTsKKwkJICAgIGFzc2VydEVxdWFscygzLCBoYW5kbGVyLmdldFNlcU51bSgpKTsKKwkJfQorCSAgICB9LAorCSAgICBuZXcgSU1BUEhhbmRsZXJFeHB1bmdlKCkgeworCQlAT3ZlcnJpZGUKKwkJcHVibGljIHZvaWQgdWlkZmV0Y2goU3RyaW5nIGxpbmUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJCSAgICB1bnRhZ2dlZCgiMiBGRVRDSCAoVUlEIDIpIik7CisJCSAgICB1bnRhZ2dlZCgiMyBGRVRDSCAoVUlEIDMpIik7CisJCSAgICB1bnRhZ2dlZCgiNCBGRVRDSCAoVUlEIDQpIik7CisJCSAgICB1bnRhZ2dlZCgiMSBFWFBVTkdFIik7CisJCSAgICB1bnRhZ2dlZCgiMyBFWElTVFMiKTsKKwkJICAgIG51bWJlck9mTWVzc2FnZXMtLTsKKwkJICAgIG9rKCk7CisJCX0KKwkgICAgfSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VUlETGlzdCgpIHsKKwl0ZXN0V2l0aEhhbmRsZXIoCisJICAgIG5ldyBJTUFQVGVzdCgpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIHRlc3QoRm9sZGVyIGZvbGRlciwgSU1BUEhhbmRsZXJFeHB1bmdlIGhhbmRsZXIpCisJCQkJICAgIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCQkgICAgTWVzc2FnZVtdIG1zZ3MgPSAoKFVJREZvbGRlcilmb2xkZXIpLmdldE1lc3NhZ2VzQnlVSUQoCisJCQkJCQkJbmV3IGxvbmdbXSB7IDIsIDMsIDQgfSk7CisJCSAgICBhc3NlcnRUcnVlKG1zZ3NbMV0gPT0gbnVsbCB8fCBtc2dzWzFdLmlzRXhwdW5nZWQoKSk7CisJCSAgICBtc2dzWzBdLmdldEZsYWdzKCk7CisJCSAgICBhc3NlcnRFcXVhbHMoMiwgaGFuZGxlci5nZXRTZXFOdW0oKSk7CisJCSAgICBtc2dzWzJdLmdldEZsYWdzKCk7CisJCSAgICBhc3NlcnRFcXVhbHMoMywgaGFuZGxlci5nZXRTZXFOdW0oKSk7CisJCX0KKwkgICAgfSwKKwkgICAgbmV3IElNQVBIYW5kbGVyRXhwdW5nZSgpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIHVpZGZldGNoKFN0cmluZyBsaW5lKSB0aHJvd3MgSU9FeGNlcHRpb24geworCQkgICAgdW50YWdnZWQoIjIgRkVUQ0ggKFVJRCAyKSIpOworCQkgICAgdW50YWdnZWQoIjMgRkVUQ0ggKFVJRCAzKSIpOworCQkgICAgdW50YWdnZWQoIjQgRkVUQ0ggKFVJRCA0KSIpOworCQkgICAgdW50YWdnZWQoIjMgRVhQVU5HRSIpOworCQkgICAgdW50YWdnZWQoIjMgRVhJU1RTIik7CisJCSAgICBudW1iZXJPZk1lc3NhZ2VzLS07CisJCSAgICBvaygpOworCQl9CisJICAgIH0pOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFVJRExpc3QyKCkgeworCXRlc3RXaXRoSGFuZGxlcigKKwkgICAgbmV3IElNQVBUZXN0KCkgeworCQlAT3ZlcnJpZGUKKwkJcHVibGljIHZvaWQgdGVzdChGb2xkZXIgZm9sZGVyLCBJTUFQSGFuZGxlckV4cHVuZ2UgaGFuZGxlcikKKwkJCQkgICAgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJCSAgICBNZXNzYWdlW10gbXNncyA9ICgoVUlERm9sZGVyKWZvbGRlcikuZ2V0TWVzc2FnZXNCeVVJRCgKKwkJCQkJCQluZXcgbG9uZ1tdIHsgMiwgMywgNCB9KTsKKwkJICAgIGFzc2VydFRydWUobXNnc1sxXSA9PSBudWxsIHx8IG1zZ3NbMV0uaXNFeHB1bmdlZCgpKTsKKwkJICAgIG1zZ3NbMF0uZ2V0RmxhZ3MoKTsKKwkJICAgIGFzc2VydEVxdWFscygyLCBoYW5kbGVyLmdldFNlcU51bSgpKTsKKwkJICAgIG1zZ3NbMl0uZ2V0RmxhZ3MoKTsKKwkJICAgIGFzc2VydEVxdWFscygzLCBoYW5kbGVyLmdldFNlcU51bSgpKTsKKwkJfQorCSAgICB9LAorCSAgICBuZXcgSU1BUEhhbmRsZXJFeHB1bmdlKCkgeworCQlAT3ZlcnJpZGUKKwkJcHVibGljIHZvaWQgdWlkZmV0Y2goU3RyaW5nIGxpbmUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJCSAgICB1bnRhZ2dlZCgiMiBGRVRDSCAoVUlEIDIpIik7CisJCSAgICB1bnRhZ2dlZCgiMyBGRVRDSCAoVUlEIDMpIik7CisJCSAgICB1bnRhZ2dlZCgiMyBFWFBVTkdFIik7CisJCSAgICB1bnRhZ2dlZCgiMyBFWElTVFMiKTsKKwkJICAgIHVudGFnZ2VkKCIzIEZFVENIIChVSUQgNCkiKTsKKwkJICAgIG51bWJlck9mTWVzc2FnZXMtLTsKKwkJICAgIG9rKCk7CisJCX0KKwkgICAgfSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VUlETGlzdDMoKSB7CisJdGVzdFdpdGhIYW5kbGVyKAorCSAgICBuZXcgSU1BUFRlc3QoKSB7CisJCUBPdmVycmlkZQorCQlwdWJsaWMgdm9pZCB0ZXN0KEZvbGRlciBmb2xkZXIsIElNQVBIYW5kbGVyRXhwdW5nZSBoYW5kbGVyKQorCQkJCSAgICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwkJICAgIE1lc3NhZ2VbXSBtc2dzID0gKChVSURGb2xkZXIpZm9sZGVyKS5nZXRNZXNzYWdlc0J5VUlEKAorCQkJCQkJCW5ldyBsb25nW10geyAyLCAzLCA0IH0pOworCQkgICAgYXNzZXJ0VHJ1ZShtc2dzWzFdID09IG51bGwgfHwgbXNnc1sxXS5pc0V4cHVuZ2VkKCkpOworCQkgICAgbXNnc1swXS5nZXRGbGFncygpOworCQkgICAgYXNzZXJ0RXF1YWxzKDIsIGhhbmRsZXIuZ2V0U2VxTnVtKCkpOworCQkgICAgbXNnc1syXS5nZXRGbGFncygpOworCQkgICAgYXNzZXJ0RXF1YWxzKDMsIGhhbmRsZXIuZ2V0U2VxTnVtKCkpOworCQl9CisJICAgIH0sCisJICAgIG5ldyBJTUFQSGFuZGxlckV4cHVuZ2UoKSB7CisJCUBPdmVycmlkZQorCQlwdWJsaWMgdm9pZCB1aWRmZXRjaChTdHJpbmcgbGluZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkJICAgIHVudGFnZ2VkKCIyIEZFVENIIChVSUQgMikiKTsKKwkJICAgIHVudGFnZ2VkKCIzIEVYUFVOR0UiKTsKKwkJICAgIHVudGFnZ2VkKCIzIEVYSVNUUyIpOworCQkgICAgdW50YWdnZWQoIjMgRkVUQ0ggKFVJRCA0KSIpOworCQkgICAgbnVtYmVyT2ZNZXNzYWdlcy0tOworCQkgICAgb2soKTsKKwkJfQorCSAgICB9KTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RVSURMaXN0NCgpIHsKKwl0ZXN0V2l0aEhhbmRsZXIoCisJICAgIG5ldyBJTUFQVGVzdCgpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIHRlc3QoRm9sZGVyIGZvbGRlciwgSU1BUEhhbmRsZXJFeHB1bmdlIGhhbmRsZXIpCisJCQkJICAgIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCQkgICAgTWVzc2FnZVtdIG1zZ3MgPSAoKFVJREZvbGRlcilmb2xkZXIpLmdldE1lc3NhZ2VzQnlVSUQoCisJCQkJCQkJbmV3IGxvbmdbXSB7IDEsIDIsIDMgfSk7CisJCSAgICBhc3NlcnRFcXVhbHMoMywgbXNncy5sZW5ndGgpOworCQkgICAgbXNnc1swXS5nZXRGbGFncygpOworCQkgICAgYXNzZXJ0RXF1YWxzKDEsIGhhbmRsZXIuZ2V0U2VxTnVtKCkpOworCQkgICAgbXNnc1sxXS5nZXRGbGFncygpOworCQkgICAgYXNzZXJ0RXF1YWxzKDIsIGhhbmRsZXIuZ2V0U2VxTnVtKCkpOworCQkgICAgbXNnc1syXS5nZXRGbGFncygpOworCQkgICAgYXNzZXJ0RXF1YWxzKDMsIGhhbmRsZXIuZ2V0U2VxTnVtKCkpOworCQl9CisJICAgIH0sCisJICAgIG5ldyBJTUFQSGFuZGxlckV4cHVuZ2UoKSB7CisJCUBPdmVycmlkZQorCQlwdWJsaWMgdm9pZCB1aWRmZXRjaChTdHJpbmcgbGluZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkJICAgIHVudGFnZ2VkKCIxIEZFVENIIChVSUQgMSkiKTsKKwkJICAgIHVudGFnZ2VkKCIyIEZFVENIIChVSUQgMikiKTsKKwkJICAgIHVudGFnZ2VkKCIzIEZFVENIIChVSUQgMykiKTsKKwkJICAgIHVudGFnZ2VkKCI0IEVYUFVOR0UiKTsKKwkJICAgIHVudGFnZ2VkKCIzIEVYSVNUUyIpOworCQkgICAgbnVtYmVyT2ZNZXNzYWdlcy0tOworCQkgICAgb2soKTsKKwkJfQorCSAgICB9KTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RVSURMaXN0NSgpIHsKKwl0ZXN0V2l0aEhhbmRsZXIoCisJICAgIG5ldyBJTUFQVGVzdCgpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIHRlc3QoRm9sZGVyIGZvbGRlciwgSU1BUEhhbmRsZXJFeHB1bmdlIGhhbmRsZXIpCisJCQkJICAgIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCQkgICAgTWVzc2FnZVtdIG1zZ3MgPSAoKFVJREZvbGRlcilmb2xkZXIpLmdldE1lc3NhZ2VzQnlVSUQoCisJCQkJCQkJbmV3IGxvbmdbXSB7IDIsIDMsIDQgfSk7CisJCSAgICBhc3NlcnRFcXVhbHMoMywgbXNncy5sZW5ndGgpOworCQkgICAgbXNnc1swXS5nZXRGbGFncygpOworCQkgICAgYXNzZXJ0RXF1YWxzKDEsIGhhbmRsZXIuZ2V0U2VxTnVtKCkpOworCQkgICAgbXNnc1sxXS5nZXRGbGFncygpOworCQkgICAgYXNzZXJ0RXF1YWxzKDIsIGhhbmRsZXIuZ2V0U2VxTnVtKCkpOworCQkgICAgbXNnc1syXS5nZXRGbGFncygpOworCQkgICAgYXNzZXJ0RXF1YWxzKDMsIGhhbmRsZXIuZ2V0U2VxTnVtKCkpOworCQl9CisJICAgIH0sCisJICAgIG5ldyBJTUFQSGFuZGxlckV4cHVuZ2UoKSB7CisJCUBPdmVycmlkZQorCQlwdWJsaWMgdm9pZCB1aWRmZXRjaChTdHJpbmcgbGluZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkJICAgIHVudGFnZ2VkKCIyIEZFVENIIChVSUQgMikiKTsKKwkJICAgIHVudGFnZ2VkKCIzIEZFVENIIChVSUQgMykiKTsKKwkJICAgIHVudGFnZ2VkKCI0IEZFVENIIChVSUQgNCkiKTsKKwkJICAgIHVudGFnZ2VkKCIxIEVYUFVOR0UiKTsKKwkJICAgIHVudGFnZ2VkKCIzIEVYSVNUUyIpOworCQkgICAgbnVtYmVyT2ZNZXNzYWdlcy0tOworCQkgICAgb2soKTsKKwkJfQorCSAgICB9KTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0V2l0aEhhbmRsZXIoSU1BUFRlc3QgdGVzdCwgSU1BUEhhbmRsZXJFeHB1bmdlIGhhbmRsZXIpIHsKKyAgICAgICAgVGVzdFNlcnZlciBzZXJ2ZXIgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc2VydmVyID0gbmV3IFRlc3RTZXJ2ZXIoaGFuZGxlcik7CisgICAgICAgICAgICBzZXJ2ZXIuc3RhcnQoKTsKKworICAgICAgICAgICAgZmluYWwgUHJvcGVydGllcyBwcm9wZXJ0aWVzID0gbmV3IFByb3BlcnRpZXMoKTsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuaW1hcC5ob3N0IiwgImxvY2FsaG9zdCIpOworICAgICAgICAgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5pbWFwLnBvcnQiLCAiIiArIHNlcnZlci5nZXRQb3J0KCkpOworICAgICAgICAgICAgZmluYWwgU2Vzc2lvbiBzZXNzaW9uID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShwcm9wZXJ0aWVzKTsKKyAgICAgICAgICAgIC8vc2Vzc2lvbi5zZXREZWJ1Zyh0cnVlKTsKKworICAgICAgICAgICAgZmluYWwgU3RvcmUgc3RvcmUgPSBzZXNzaW9uLmdldFN0b3JlKCJpbWFwIik7CisJICAgIEZvbGRlciBmb2xkZXIgPSBudWxsOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdG9yZS5jb25uZWN0KCJ0ZXN0IiwgInRlc3QiKTsKKyAgICAgICAgICAgICAgICBmb2xkZXIgPSBzdG9yZS5nZXRGb2xkZXIoIklOQk9YIik7CisgICAgICAgICAgICAgICAgZm9sZGVyLm9wZW4oRm9sZGVyLlJFQURfV1JJVEUpOworCQl0ZXN0LnRlc3QoZm9sZGVyLCBoYW5kbGVyKTsKKwkgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJCVN5c3RlbS5vdXQucHJpbnRsbihleCk7CisJCS8vZXgucHJpbnRTdGFja1RyYWNlKCk7CisJCWZhaWwoZXgudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworCQlpZiAoZm9sZGVyICE9IG51bGwpCisJCSAgICBmb2xkZXIuY2xvc2UoZmFsc2UpOworICAgICAgICAgICAgICAgIHN0b3JlLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoc2VydmVyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBzZXJ2ZXIucXVpdCgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3VzdG9tIGhhbmRsZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgSU1BUEhhbmRsZXJFeHB1bmdlIGV4dGVuZHMgSU1BUEhhbmRsZXIgeworCS8vIG11c3QgYmUgc3RhdGljIGJlY2F1c2UgaGFuZGxlciBpcyBjbG9uZWQgZm9yIGVhY2ggY29ubmVjdGlvbgorCXByaXZhdGUgc3RhdGljIGludCBzZXFudW07CisKKwlAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgc2VsZWN0KFN0cmluZyBsaW5lKSB0aHJvd3MgSU9FeGNlcHRpb24geworCSAgICBudW1iZXJPZk1lc3NhZ2VzID0gNDsKKwkgICAgc3VwZXIuc2VsZWN0KGxpbmUpOworCX0KKworCUBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBmZXRjaChTdHJpbmcgbGluZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkgICAgU3RyaW5nVG9rZW5pemVyIHN0ID0gbmV3IFN0cmluZ1Rva2VuaXplcihsaW5lLCAiICIpOworCSAgICBTdHJpbmcgdGFnID0gc3QubmV4dFRva2VuKCk7CisJICAgIFN0cmluZyBjb21tYW5kID0gc3QubmV4dFRva2VuKCk7CisJICAgIHNlcW51bSA9IEludGVnZXIucGFyc2VJbnQoc3QubmV4dFRva2VuKCkpOworCSAgICBvaygpOworICAgICAgICB9CisKKwlwdWJsaWMgaW50IGdldFNlcU51bSgpIHsKKwkgICAgcmV0dXJuIHNlcW51bTsKKwl9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL01lc3NhZ2VDYWNoZVRlc3QuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9NZXNzYWdlQ2FjaGVUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODkzNDRmMgotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9NZXNzYWdlQ2FjaGVUZXN0LmphdmEKQEAgLTAsMCArMSw3MCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwOSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuaW1hcDsKKworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEVxdWFsczsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworLyoqCisgKiBUZXN0IHRoZSBJTUFQIE1lc3NhZ2VDYWNoZS4KKyAqLworcHVibGljIGNsYXNzIE1lc3NhZ2VDYWNoZVRlc3QgeworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCB3aGVuIGEgbWVzc2FnZSBpcyBleHB1bmdlZCBhbmQgYSBuZXcgbWVzc2FnZSBpcyBhZGRlZCwKKyAgICAgKiB0aGUgbmV3IG1lc3NhZ2UgaGFzIHRoZSBleHBlY3RlZCBzZXF1ZW5jZSBudW1iZXIuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RXhwdW5nZUFkZCgpIHRocm93cyBFeGNlcHRpb24geworCS8vIHRlc3QgYSByYW5nZSBvZiB2YWx1ZXMgdG8gZmluZCBib3VuZGFyeSBjb25kaXRpb24gZXJyb3JzCisJZm9yIChpbnQgbiA9IDE7IG4gPD0gMTAwOyBuKyspIHsKKwkgICAgLy9TeXN0ZW0ub3V0LnByaW50bG4oIk1lc3NhZ2VDYWNoZS50ZXN0RXhwdW5nZUFkZDogdGVzdCAiICsgbik7CisJICAgIC8vIHN0YXJ0IHdpdGggb25lIG1lc3NhZ2UKKwkgICAgTWVzc2FnZUNhY2hlIG1jID0gbmV3IE1lc3NhZ2VDYWNoZSgxLCBmYWxzZSk7CisJICAgIC8vIGFkZCB0aGUgcmVtYWluaW5nIG1lc3NhZ2VzIChlYXQgaW50byBTTE9QKQorCSAgICBtYy5hZGRNZXNzYWdlcyhuIC0gMSwgMik7CisJICAgIC8vIG5vdyBleHB1bmdlIGEgbWVzc2FnZSB0byBjYXVzZSB0aGUgc2VxbnVtcyBhcnJheSB0byBiZSBjcmVhdGVkCisJICAgIG1jLmV4cHVuZ2VNZXNzYWdlKDEpOworCSAgICAvLyBhbmQgYWRkIG9uZSBtb3JlIG1lc3NhZ2UKKwkgICAgbWMuYWRkTWVzc2FnZXMoMSwgbik7CisJICAgIC8vU3lzdGVtLm91dC5wcmludGxuKCIgIG5ldyBzZXFudW0gIiArIG1jLnNlcW51bU9mKG4gKyAxKSk7CisJICAgIC8vIGRvZXMgdGhlIG5ldyBtZXNzYWdlIGhhdmUgdGhlIGV4cGVjdGVkIHNlcXVlbmNlIG51bWJlcj8KKwkgICAgYXNzZXJ0RXF1YWxzKG1jLnNlcW51bU9mKG4gKyAxKSwgbik7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCB3aGVuIGEgbWVzc2FnZSBpcyBleHB1bmdlZCBhbmQgbmV3IG1lc3NhZ2VzIGFyZSBhZGRlZCwKKyAgICAgKiB0aGUgbmV3IG1lc3NhZ2VzIGhhdmUgdGhlIGV4cGVjdGVkIHNlcXVlbmNlIG51bWJlci4gIFNpbWlsYXIgdG8KKyAgICAgKiB0aGUgYWJvdmUsIGJ1dCB0aGUgc2VxbnVtcyBhcnJheSBpcyBjcmVhdGVkIGZpcnN0LCB0aGVuIGV4cGFuZGVkLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEV4cHVuZ2VBZGRFeHBhbmQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwkvLyB0ZXN0IGEgcmFuZ2Ugb2YgdmFsdWVzIHRvIGZpbmQgYm91bmRhcnkgY29uZGl0aW9uIGVycm9ycworCWZvciAoaW50IG4gPSAyOyBuIDw9IDEwMDsgbisrKSB7CisJICAgIC8vU3lzdGVtLm91dC5wcmludGxuKCJNZXNzYWdlQ2FjaGUudGVzdEV4cHVuZ2VBZGQ6IHRlc3QgIiArIG4pOworCSAgICAvLyBzdGFydCB3aXRoIHR3byBtZXNzYWdlcworCSAgICBNZXNzYWdlQ2FjaGUgbWMgPSBuZXcgTWVzc2FnZUNhY2hlKDIsIGZhbHNlKTsKKwkgICAgLy8gbm93IGV4cHVuZ2UgYSBtZXNzYWdlIHRvIGNhdXNlIHRoZSBzZXFudW1zIGFycmF5IHRvIGJlIGNyZWF0ZWQKKwkgICAgbWMuZXhwdW5nZU1lc3NhZ2UoMSk7CisJICAgIC8vIGFkZCB0aGUgcmVtYWluaW5nIG1lc3NhZ2VzIChlYXQgaW50byBTTE9QKQorCSAgICBtYy5hZGRNZXNzYWdlcyhuIC0gMSwgMik7CisJICAgIC8vU3lzdGVtLm91dC5wcmludGxuKCIgIG5ldyBzZXFudW0gIiArIG1jLnNlcW51bU9mKG4gKyAxKSk7CisJICAgIC8vIGRvZXMgdGhlIG5ldyBtZXNzYWdlIGhhdmUgdGhlIGV4cGVjdGVkIHNlcXVlbmNlIG51bWJlcj8KKwkgICAgYXNzZXJ0RXF1YWxzKG1jLnNlcW51bU9mKG4gKyAxKSwgbik7CisJfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9CT0RZU1RSVUNUVVJFVGVzdC5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL3Byb3RvY29sL0JPRFlTVFJVQ1RVUkVUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmJkMGEwZAotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9CT0RZU1RSVUNUVVJFVGVzdC5qYXZhCkBAIC0wLDAgKzEsNzAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMTIsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmltYXAucHJvdG9jb2w7CisKK2ltcG9ydCBqYXZheC5tYWlsLmludGVybmV0LlBhcmFtZXRlckxpc3Q7CisKK2ltcG9ydCBjb20uc3VuLm1haWwuaWFwLlJlc3BvbnNlOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydE5vdE51bGw7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RXF1YWxzOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCisvKioKKyAqIFRlc3QgdGhlIEJPRFlTVFJVQ1RVUkUgY2xhc3MuCisgKi8KK3B1YmxpYyBjbGFzcyBCT0RZU1RSVUNUVVJFVGVzdCB7CisgICAgLyoqCisgICAgICogVGVzdCB3b3JrYXJvdW5kIGZvciBFeGNoYW5nZSBidWcgdGhhdCByZXR1cm5zIE5JTCBpbnN0ZWFkIG9mICIiCisgICAgICogZm9yIGEgcGFyYW1ldGVyIHdpdGggYW4gZW1wdHkgdmFsdWUgKG5hbWU9IiIpLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEV4Y2hhbmdlRW1wdHlQYXJhbWV0ZXJWYWx1ZUJ1ZygpIHRocm93cyBFeGNlcHRpb24geworCUlNQVBSZXNwb25zZSByZXNwb25zZSA9IG5ldyBJTUFQUmVzcG9uc2UoCisgICAgIiogMyBGRVRDSCAoQk9EWVNUUlVDVFVSRSAoKFwidGV4dFwiIFwicGxhaW5cIiAoXCJjaGFyc2V0XCIgXCJVVEYtOFwiKSAiICsKKyAgICAiTklMIE5JTCBcInF1b3RlZC1wcmludGFibGVcIiA1MTIgMTMgTklMIChcImlubGluZVwiIE5JTCkgTklMIE5JTCkiICsKKyAgICAiKFwidGV4dFwiIFwiaHRtbFwiIChcImNoYXJzZXRcIiBcIlVURi04XCIpIE5JTCBOSUwgXCJxdW90ZWQtcHJpbnRhYmxlXCIgIiArCisgICAgIjc4NCAxMSBOSUwgKFwiaW5saW5lXCIgTklMKSBOSUwgTklMKSBcImFsdGVybmF0aXZlXCIgIiArCisgICAgIihcImJvdW5kYXJ5XCIgXCJfXzEzOTk1Nzk5NjIxODM3OS5leGFtcGxlLmNvbVwiIFwibmFtZVwiIE5JTCkgTklMIE5JTCkpIik7CisgICAgLy8gaGVyZSdzIHRoZSBpbmNvcnJlY3QgTklMIHRoYXQgc2hvdWxkIGJlICIiIC4uLi4uLi4uLi4uLl4KKwlGZXRjaFJlc3BvbnNlIGZyID0gbmV3IEZldGNoUmVzcG9uc2UocmVzcG9uc2UpOworCUJPRFlTVFJVQ1RVUkUgYnMgPSBmci5nZXRJdGVtKEJPRFlTVFJVQ1RVUkUuY2xhc3MpOworCVBhcmFtZXRlckxpc3QgcCA9IGJzLmNQYXJhbXM7CisJYXNzZXJ0Tm90TnVsbChwLmdldCgibmFtZSIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHdvcmthcm91bmQgZm9yIEV4Y2hhbmdlIGJ1ZyB0aGF0IHJldHVybnMgdGhlIENvbnRlbnQtRGVzY3JpcHRpb24KKyAgICAgKiBoZWFkZXIgdmFsdWUgaW5zdGVhZCBvZiB0aGUgQ29udGVudC1EaXNwb3NpdGlvbiBmb3Igc29tZSBraW5kcyBvZgorICAgICAqIChmb3JtZXJseSBTL01JTUUgZW5jcnlwdGVkPykgbWVzc2FnZXMuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RXhjaGFuZ2VCYWREaXNwb3NpdGlvbigpIHRocm93cyBFeGNlcHRpb24geworCUlNQVBSZXNwb25zZSByZXNwb25zZSA9IG5ldyBJTUFQUmVzcG9uc2UoCisgICAgIiogMSBGRVRDSCAoQk9EWVNUUlVDVFVSRSAoIiArCisJIihcInRleHRcIiBcInBsYWluXCIgKFwiY2hhcnNldFwiIFwidXMtYXNjaWlcIikgTklMIE5JTCBcIjdiaXRcIiAiICsKKwkgICAgIjIxIDAgTklMIChcImlubGluZVwiIE5JTCkgTklMIE5JTCkiICsKKwkiKFwiYXBwbGljYXRpb25cIiBcIm9jdGV0LXN0cmVhbVwiIChcIm5hbWVcIiBcInByaXZhdGUudHh0XCIpICIgKworCSAgICAiTklMIE5JTCBcImJhc2U2NFwiIDY5MCBOSUwgIiArCisJCSIoXCJhdHRhY2htZW50XCIgKFwiZmlsZW5hbWVcIiBcInByaXZhdGUudHh0XCIpKSBOSUwgTklMKSAiICsKKyAgICAiXCJtaXhlZFwiIChcImJvdW5kYXJ5XCIgXCItLS0tPV9QYXJ0XzBfLTE3MzE3MDc4ODUuMTUwNDI1MzgxNTU4NFwiKSAiICsKKwkiXCJTL01JTUUgRW5jcnlwdGVkIE1lc3NhZ2VcIiBOSUwpKSIpOworICAgIC8vICAgIF5eXl5eXl4gaGVyZSdzIHRoZSBzdHJpbmcgdGhhdCBzaG91bGQgYmUgdGhlIGRpc3Bvc2l0aW9uCisJRmV0Y2hSZXNwb25zZSBmciA9IG5ldyBGZXRjaFJlc3BvbnNlKHJlc3BvbnNlKTsKKwlCT0RZU1RSVUNUVVJFIGJzID0gZnIuZ2V0SXRlbShCT0RZU1RSVUNUVVJFLmNsYXNzKTsKKwlhc3NlcnRFcXVhbHMoIlMvTUlNRSBFbmNyeXB0ZWQgTWVzc2FnZSIsIGJzLmRlc2NyaXB0aW9uKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL2ltYXAvcHJvdG9jb2wvRW52ZWxvcGVUZXN0LmphdmEgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL2ltYXAvcHJvdG9jb2wvRW52ZWxvcGVUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWY5M2JhOAotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9FbnZlbG9wZVRlc3QuamF2YQpAQCAtMCwwICsxLDY2IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDEyLCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5pbWFwLnByb3RvY29sOworCitpbXBvcnQgY29tLnN1bi5tYWlsLmlhcC5SZXNwb25zZTsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRFcXVhbHM7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuZmFpbDsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworLyoqCisgKiBUZXN0IHRoZSBFTlZFTE9QRSBjbGFzcy4KKyAqLworcHVibGljIGNsYXNzIEVudmVsb3BlVGVzdCB7CisgICAgLyoqCisgICAgICogVGVzdCB3b3JrYXJvdW5kIGZvciBZYWhvbyBJTUFQIGJ1ZyB0aGF0IHJldHVybnMgYSBib2d1cyBzcGFjZQorICAgICAqIGNoYXJhY3RlciB3aGVuIG9uZSBvZiB0aGUgcmVjaXBpZW50cyBpcyAidW5kaXNjbG9zZWQtcmVjaXBpZW50cyIuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0WWFob29VbmRpc2Nsb3NlZFJlY2lwaWVudHNCdWcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlJTUFQUmVzcG9uc2UgcmVzcG9uc2UgPSBuZXcgSU1BUFJlc3BvbnNlKAorICAgICIqIDIgRkVUQ0ggKElOVEVSTkFMREFURSBcIjI0LUFwci0yMDEyIDIwOjI4OjU4ICswMDAwXCIgIiArCisgICAgIlJGQzgyMi5TSVpFIDE1NTkzNyAiICsKKyAgICAiRU5WRUxPUEUgKFwiV2VkLCAyOCBTZXAgMjAxMSAxMToxNjoxNyArMDEwMFwiIFwidGVzdFwiICIgKworICAgICIoKE5JTCBOSUwgXCJ4eHhcIiBcInRqdS5lZHUuY25cIikpICIgKworICAgICIoKE5JTCBOSUwgXCJ4eHhcIiBcImdtYWlsLmNvbVwiKSkgIiArCisgICAgIigoTklMIE5JTCBcInh4eFwiIFwidGp1LmVkdS5jblwiKSkgIiArCisgICAgIigoXCJ1bmRpc2Nsb3NlZC1yZWNpcGllbnRzXCIgTklMICIgKworCSJcIlxcXCJ1bmRpc2Nsb3NlZC1yZWNpcGllbnRzXFxcIlwiIE5JTCApKSAiICsKKyAgICAvLyBoZXJlJ3MgdGhlIHNwYWNlIGluc2VydGVkIGJ5IFlhaG9vIElNQVAgXgorICAgICJOSUwgTklMIE5JTCAiICsKKyAgICAiXCI8eHh4QG1haWwuZ21haWwuY29tPlwiKSkiKTsKKwlGZXRjaFJlc3BvbnNlIGZyID0gbmV3IEZldGNoUmVzcG9uc2UocmVzcG9uc2UpOworCS8vIG5vIGV4Y2VwdGlvbiBtZWFucyBpdCB3b3JrZWQKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHdvcmthcm91bmQgZm9yIFlhaG9vIElNQVAgYnVnIHRoYXQgcmV0dXJucyBhbiBlbXB0eSBsaXN0CisgICAgICogaW5zdGFkIG9mIE5JTCBmb3Igc29tZSBhZGRyZXNzZXMgaW4gRU5WRUxPUEUgcmVzcG9uc2UuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0WWFob29FbnZlbG9wZUFkZHJlc3NMaXN0QnVnKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJSU1BUFJlc3BvbnNlIHJlc3BvbnNlID0gbmV3IElNQVBSZXNwb25zZSgKKyAgICAiKiAyIEZFVENIIChSRkM4MjIuU0laRSAyNTY3IElOVEVSTkFMREFURSBcIjI5LUFwci0yMDExIDEzOjQ5OjAxICswMDAwXCIgIiArCisgICAgIkVOVkVMT1BFIChcIkZyaSwgMjkgQXByIDIwMTEgMTk6MTk6MDEgKzA1MzBcIiBcInRlc3RcIiAiICsKKyAgICAiKChcInh4eFwiIE5JTCBcInh4eFwiIFwibWlsaXVtLmNvbS5iclwiKSkgIiArCisgICAgIigoXCJ4eHhcIiBOSUwgXCJ4eHhcIiBcIm1pbGl1bS5jb20uYnJcIikpICIgKworICAgICIoKE5JTCBOSUwgXCJ4eHhcIiBcImxpdmUuaGtcIikpICgpIE5JTCBOSUwgTklMICIgKworICAgICJcIjwyMDExMDQyOTEzNDcxOC43MDMzMzczMjAzMEFAbWFpbDIubWlsaXVtLmNvbS5icj5cIikpIik7CisJRmV0Y2hSZXNwb25zZSBmciA9IG5ldyBGZXRjaFJlc3BvbnNlKHJlc3BvbnNlKTsKKwkvLyBubyBleGNlcHRpb24gbWVhbnMgaXQgd29ya2VkCisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL3Byb3RvY29sL0lNQVBQcm90b2NvbFRlc3QuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9JTUFQUHJvdG9jb2xUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTU2MTM4OAotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9JTUFQUHJvdG9jb2xUZXN0LmphdmEKQEAgLTAsMCArMSwxMDEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMTQsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmltYXAucHJvdG9jb2w7CisKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0OworaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOworaW1wb3J0IGNvbS5zdW4ubWFpbC50ZXN0LkFzY2lpU3RyaW5nSW5wdXRTdHJlYW07CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RXF1YWxzOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCisvKioKKyAqIFRlc3QgdGhlIElNQVBQcm90b2NvbCBjbGFzcy4KKyAqLworcHVibGljIGNsYXNzIElNQVBQcm90b2NvbFRlc3QgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gZGVidWcgPSBmYWxzZTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgY29udGVudCA9ICJhWFFuY3lCdGVTQjBaWE4wSUcxaGFXd05DZzBLXHJcbiI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIHJlc3BvbnNlID0KKwkgICAgIiogMSBGRVRDSCAoVUlEIDEyNyBCT0RZWzEuMS5NSU1FXSB7ODJ9XHJcbiIgKworCSAgICAiQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluO1xyXG4iICsKKwkgICAgIlx0Y2hhcnNldD1cInV0Zi04XCJcclxuIiArCisJICAgICJDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjRcclxuIiArCisJICAgICJcclxuIiArCisJICAgICIgRU5WRUxPUEUgKFwiTW9uLCAxNyBNYXIgMjAxNCAxNDowMzowOCArMDEwMFwiIFwidGVzdCBpbnZvaWNlXCIiICsKKwkgICAgIiAoKFwiSm9lIFVzZXJcIiBOSUwgXCJqb2UudXNlclwiIFwiZXhhbXBsZS5jb21cIikpIiArCisJICAgICIgKChcIkpvZSBVc2VyXCIgTklMIFwiam9lLnVzZXJcIiBcImV4YW1wbGUuY29tXCIpKSIgKworCSAgICAiICgoXCJKb2UgVXNlclwiIE5JTCBcImpvZS51c2VyXCIgXCJleGFtcGxlLmNvbVwiKSkiICsKKwkgICAgIiAoKFwiSm9lIFVzZXJcIiBOSUwgXCJqb2UudXNlclwiIFwiZXhhbXBsZS5jb21cIikpIiArIAorCSAgICAiIE5JTCBOSUwgTklMIFwiPDEyMzRAZXhhbXBsZS5jb20+XCIpIEJPRFlbMS4xXTwwPiAiICsKKwkgICAgInsiICsgY29udGVudC5sZW5ndGgoKSArICJ9XHJcbiIgKyBjb250ZW50ICsgCisJICAgICIpXHJcbiIgKworCSAgICAiQTAgT0sgRkVUQ0ggY29tcGxldGVkLlxyXG4iOworCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IGEgcmVzcG9uc2UgY29udGFpbmluZyBtdWx0aXBsZSBCT0RZIGVsZW1lbnRzCisgICAgICogcmV0dXJucyB0aGUgY29ycmVjdCBvbmUuICBEZXJpdmVkIGZyb20gYSBjdXN0b21lciBidWcKKyAgICAgKiB3aXRoIEV4Y2hhbmdlIDIwMDMuICBOb3JtYWxseSB0aGlzIHdvdWxkIG5ldmVyIGhhcHBlbiwKKyAgICAgKiBidXQgaXQncyBhIHZhbGlkIElNQVAgcmVzcG9uc2UgYW5kIEphdmFNYWlsIG5lZWRzIHRvCisgICAgICogaGFuZGxlIGl0IHByb3Blcmx5LgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdE11bHRpcGxlQm9keVJlc3BvbnNlcygpIHRocm93cyBFeGNlcHRpb24geworCVByb3BlcnRpZXMgcHJvcHMgPSBuZXcgUHJvcGVydGllcygpOworCXByb3BzLnNldFByb3BlcnR5KCJtYWlsLmltYXAucmV1c2V0YWdwcmVmaXgiLCAidHJ1ZSIpOworCUlNQVBQcm90b2NvbCBwID0gbmV3IElNQVBQcm90b2NvbCgKKwkgICAgbmV3IEFzY2lpU3RyaW5nSW5wdXRTdHJlYW0ocmVzcG9uc2UpLAorCSAgICBuZXcgUHJpbnRTdHJlYW0obmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpKSwKKwkgICAgcHJvcHMsCisJICAgIGRlYnVnKTsKKwlCT0RZIGIgPSBwLmZldGNoQm9keSgxLCAiMS4xIik7CisJYXNzZXJ0RXF1YWxzKCJzZWN0aW9uIG51bWJlciIsICIxLjEiLCBiLmdldFNlY3Rpb24oKSk7CisJLy9TeXN0ZW0ub3V0LnByaW50bG4oYik7CisJLy9TeXN0ZW0ub3V0LndyaXRlKGIuZ2V0Qnl0ZUFycmF5KCkuZ2V0TmV3Qnl0ZXMoKSk7CisJU3RyaW5nIHJlc3VsdCA9IG5ldyBTdHJpbmcoYi5nZXRCeXRlQXJyYXkoKS5nZXROZXdCeXRlcygpLCAidXMtYXNjaWkiKTsKKwlhc3NlcnRFcXVhbHMoImdldEJ5dGVBcnJheS5nZXROZXdCeXRlcyIsIGNvbnRlbnQsIHJlc3VsdCk7CisJSW5wdXRTdHJlYW0gaXMgPSBiLmdldEJ5dGVBcnJheUlucHV0U3RyZWFtKCk7CisJYnl0ZVtdIGJhID0gbmV3IGJ5dGVbaXMuYXZhaWxhYmxlKCldOworCWlzLnJlYWQoYmEpOworCXJlc3VsdCA9IG5ldyBTdHJpbmcoYmEsICJ1cy1hc2NpaSIpOworCWFzc2VydEVxdWFscygiZ2V0Qnl0ZUFycmF5SW5wdXRTdHJlYW0iLCBjb250ZW50LCByZXN1bHQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNhbWUgdGVzdCBhcyBhYm92ZSwgYnV0IHVzaW5nIGEgZGlmZmVyZW50IGZldGNoQm9keSBtZXRob2QuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TXVsdGlwbGVCb2R5UmVzcG9uc2VzMigpIHRocm93cyBFeGNlcHRpb24geworCVByb3BlcnRpZXMgcHJvcHMgPSBuZXcgUHJvcGVydGllcygpOworCXByb3BzLnNldFByb3BlcnR5KCJtYWlsLmltYXAucmV1c2V0YWdwcmVmaXgiLCAidHJ1ZSIpOworCUlNQVBQcm90b2NvbCBwID0gbmV3IElNQVBQcm90b2NvbCgKKwkgICAgbmV3IEFzY2lpU3RyaW5nSW5wdXRTdHJlYW0ocmVzcG9uc2UpLAorCSAgICBuZXcgUHJpbnRTdHJlYW0obmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpKSwKKwkgICAgcHJvcHMsCisJICAgIGRlYnVnKTsKKwlCT0RZIGIgPSBwLmZldGNoQm9keSgxLCAiMS4xIiwgMCwgY29udGVudC5sZW5ndGgoKSwgbnVsbCk7CisJYXNzZXJ0RXF1YWxzKCJzZWN0aW9uIG51bWJlciIsICIxLjEiLCBiLmdldFNlY3Rpb24oKSk7CisJLy9TeXN0ZW0ub3V0LnByaW50bG4oYik7CisJLy9TeXN0ZW0ub3V0LndyaXRlKGIuZ2V0Qnl0ZUFycmF5KCkuZ2V0TmV3Qnl0ZXMoKSk7CisJU3RyaW5nIHJlc3VsdCA9IG5ldyBTdHJpbmcoYi5nZXRCeXRlQXJyYXkoKS5nZXROZXdCeXRlcygpLCAidXMtYXNjaWkiKTsKKwlhc3NlcnRFcXVhbHMoImdldEJ5dGVBcnJheS5nZXROZXdCeXRlcyIsIGNvbnRlbnQsIHJlc3VsdCk7CisJSW5wdXRTdHJlYW0gaXMgPSBiLmdldEJ5dGVBcnJheUlucHV0U3RyZWFtKCk7CisJYnl0ZVtdIGJhID0gbmV3IGJ5dGVbaXMuYXZhaWxhYmxlKCldOworCWlzLnJlYWQoYmEpOworCXJlc3VsdCA9IG5ldyBTdHJpbmcoYmEsICJ1cy1hc2NpaSIpOworCWFzc2VydEVxdWFscygiZ2V0Qnl0ZUFycmF5SW5wdXRTdHJlYW0iLCBjb250ZW50LCByZXN1bHQpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9NT0RTRVFUZXN0LmphdmEgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL2ltYXAvcHJvdG9jb2wvTU9EU0VRVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUzNzY5ZmUKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL2ltYXAvcHJvdG9jb2wvTU9EU0VRVGVzdC5qYXZhCkBAIC0wLDAgKzEsNTMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMTUsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmltYXAucHJvdG9jb2w7CisKK2ltcG9ydCBjb20uc3VuLm1haWwuaWFwLlBhcnNpbmdFeGNlcHRpb247CisKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRFcXVhbHM7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKKy8qKgorICogVGVzdCB0aGUgTU9EU0VRIGNsYXNzLgorICovCitwdWJsaWMgY2xhc3MgTU9EU0VRVGVzdCB7CisgICAgLyoqCisgICAgICogVGVzdCBhbiBleGFtcGxlIE1PRFNFUSByZXNwb25zZS4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RBbGwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlJTUFQUmVzcG9uc2UgcmVzcG9uc2UgPSBuZXcgSU1BUFJlc3BvbnNlKAorCSAgICAiKiAxIEZFVENIIChNT0RTRVEgKDYyNDE0MDAwMykpIik7CisJRmV0Y2hSZXNwb25zZSBmciA9IG5ldyBGZXRjaFJlc3BvbnNlKHJlc3BvbnNlKTsKKwlNT0RTRVEgbSA9IGZyLmdldEl0ZW0oTU9EU0VRLmNsYXNzKTsKKwlhc3NlcnRFcXVhbHMoMSwgbS5zZXFudW0pOworCWFzc2VydEVxdWFscyg2MjQxNDAwMDMsIG0ubW9kc2VxKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGFuIGV4YW1wbGUgTU9EU0VRIHJlc3BvbnNlIHdpdGggdW5uZWNlc3Nhcnkgc3BhY2VzLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFNwYWNlcygpIHRocm93cyBFeGNlcHRpb24geworCUlNQVBSZXNwb25zZSByZXNwb25zZSA9IG5ldyBJTUFQUmVzcG9uc2UoCisJICAgICIqIDEgRkVUQ0ggKCBNT0RTRVEgKCA2MjQxNDAwMDMgKSApIik7CisJRmV0Y2hSZXNwb25zZSBmciA9IG5ldyBGZXRjaFJlc3BvbnNlKHJlc3BvbnNlKTsKKwlNT0RTRVEgbSA9IGZyLmdldEl0ZW0oTU9EU0VRLmNsYXNzKTsKKwlhc3NlcnRFcXVhbHMoMSwgbS5zZXFudW0pOworCWFzc2VydEVxdWFscyg2MjQxNDAwMDMsIG0ubW9kc2VxKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL2ltYXAvcHJvdG9jb2wvTmFtZXNwYWNlc1Rlc3QuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9OYW1lc3BhY2VzVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA0ZTgzNGUKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL2ltYXAvcHJvdG9jb2wvTmFtZXNwYWNlc1Rlc3QuamF2YQpAQCAtMCwwICsxLDE1MiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAxNSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuaW1hcC5wcm90b2NvbDsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC5pYXAuUGFyc2luZ0V4Y2VwdGlvbjsKKworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEVxdWFsczsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworLyoqCisgKiBUZXN0IHRoZSBOYW1lc3BhY2VzIGNsYXNzLgorICovCitwdWJsaWMgY2xhc3MgTmFtZXNwYWNlc1Rlc3QgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyB1dGY4Rm9sZGVyID0gIiNwdWJsaWNcdTAzYjEvIjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgdXRmN0ZvbGRlciA9ICIjcHVibGljJkE3RS0vIjsKKworICAgIC8qKgorICAgICAqIFRlc3QgYW4gZXhhbXBsZSBOQU1FU1BBQ0UgcmVzcG9uc2UuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWxsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJSU1BUFJlc3BvbnNlIHJlc3BvbnNlID0gbmV3IElNQVBSZXNwb25zZSgKKwkgICAgIiogTkFNRVNQQUNFICgoXCJcIiBcIi9cIikpICIgKwkvLyBwZXJzb25hbAorCSAgICAiKChcIn5cIiBcIi9cIikpICIgKwkJLy8gb3RoZXIgdXNlcnMKKwkgICAgIigoXCIjc2hhcmVkL1wiIFwiL1wiKSIgKwkJLy8gc2hhcmVkCisJCSIoXCIjcHVibGljL1wiIFwiL1wiKSIgKworCQkiKFwiI2Z0cC9cIiBcIi9cIikiICsKKwkJIihcIiNuZXdzLlwiIFwiLlwiKSkiKTsKKwlOYW1lc3BhY2VzIG5zID0gbmV3IE5hbWVzcGFjZXMocmVzcG9uc2UpOworCWFzc2VydEVxdWFscygxLCBucy5wZXJzb25hbC5sZW5ndGgpOworCWFzc2VydEVxdWFscygiIiwgbnMucGVyc29uYWxbMF0ucHJlZml4KTsKKwlhc3NlcnRFcXVhbHMoJy8nLCBucy5wZXJzb25hbFswXS5kZWxpbWl0ZXIpOworCWFzc2VydEVxdWFscygxLCBucy5vdGhlclVzZXJzLmxlbmd0aCk7CisJYXNzZXJ0RXF1YWxzKCJ+IiwgbnMub3RoZXJVc2Vyc1swXS5wcmVmaXgpOworCWFzc2VydEVxdWFscygnLycsIG5zLm90aGVyVXNlcnNbMF0uZGVsaW1pdGVyKTsKKwlhc3NlcnRFcXVhbHMoNCwgbnMuc2hhcmVkLmxlbmd0aCk7CisJYXNzZXJ0RXF1YWxzKCIjc2hhcmVkLyIsIG5zLnNoYXJlZFswXS5wcmVmaXgpOworCWFzc2VydEVxdWFscygnLycsIG5zLnNoYXJlZFswXS5kZWxpbWl0ZXIpOworCWFzc2VydEVxdWFscygiI3B1YmxpYy8iLCBucy5zaGFyZWRbMV0ucHJlZml4KTsKKwlhc3NlcnRFcXVhbHMoJy8nLCBucy5zaGFyZWRbMV0uZGVsaW1pdGVyKTsKKwlhc3NlcnRFcXVhbHMoIiNmdHAvIiwgbnMuc2hhcmVkWzJdLnByZWZpeCk7CisJYXNzZXJ0RXF1YWxzKCcvJywgbnMuc2hhcmVkWzJdLmRlbGltaXRlcik7CisJYXNzZXJ0RXF1YWxzKCIjbmV3cy4iLCBucy5zaGFyZWRbM10ucHJlZml4KTsKKwlhc3NlcnRFcXVhbHMoJy4nLCBucy5zaGFyZWRbM10uZGVsaW1pdGVyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGFuIGV4YW1wbGUgTkFNRVNQQUNFIHJlc3BvbnNlIHdpdGggdW5uZWNlc3Nhcnkgc3BhY2VzLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFNwYWNlcygpIHRocm93cyBFeGNlcHRpb24geworCUlNQVBSZXNwb25zZSByZXNwb25zZSA9IG5ldyBJTUFQUmVzcG9uc2UoCisJICAgICIqIE5BTUVTUEFDRSAoKFwiXCIgXCIvXCIpKSAiICsJLy8gcGVyc29uYWwKKwkgICAgIiggKCBcIn5cIiBcIi9cIiApICkgIiArCQkvLyBvdGhlciB1c2VycworCSAgICAiKCggXCIjc2hhcmVkL1wiIFwiL1wiICkiICsJCS8vIHNoYXJlZAorCQkiKCBcIiNwdWJsaWMvXCIgXCIvXCIgKSIgKworCQkiKCBcIiNmdHAvXCIgXCIvXCIgKSIgKworCQkiIChcIiNuZXdzLlwiIFwiLlwiICkpIik7CisJTmFtZXNwYWNlcyBucyA9IG5ldyBOYW1lc3BhY2VzKHJlc3BvbnNlKTsKKwlhc3NlcnRFcXVhbHMoMSwgbnMucGVyc29uYWwubGVuZ3RoKTsKKwlhc3NlcnRFcXVhbHMoIiIsIG5zLnBlcnNvbmFsWzBdLnByZWZpeCk7CisJYXNzZXJ0RXF1YWxzKCcvJywgbnMucGVyc29uYWxbMF0uZGVsaW1pdGVyKTsKKwlhc3NlcnRFcXVhbHMoMSwgbnMub3RoZXJVc2Vycy5sZW5ndGgpOworCWFzc2VydEVxdWFscygifiIsIG5zLm90aGVyVXNlcnNbMF0ucHJlZml4KTsKKwlhc3NlcnRFcXVhbHMoJy8nLCBucy5vdGhlclVzZXJzWzBdLmRlbGltaXRlcik7CisJYXNzZXJ0RXF1YWxzKDQsIG5zLnNoYXJlZC5sZW5ndGgpOworCWFzc2VydEVxdWFscygiI3NoYXJlZC8iLCBucy5zaGFyZWRbMF0ucHJlZml4KTsKKwlhc3NlcnRFcXVhbHMoJy8nLCBucy5zaGFyZWRbMF0uZGVsaW1pdGVyKTsKKwlhc3NlcnRFcXVhbHMoIiNwdWJsaWMvIiwgbnMuc2hhcmVkWzFdLnByZWZpeCk7CisJYXNzZXJ0RXF1YWxzKCcvJywgbnMuc2hhcmVkWzFdLmRlbGltaXRlcik7CisJYXNzZXJ0RXF1YWxzKCIjZnRwLyIsIG5zLnNoYXJlZFsyXS5wcmVmaXgpOworCWFzc2VydEVxdWFscygnLycsIG5zLnNoYXJlZFsyXS5kZWxpbWl0ZXIpOworCWFzc2VydEVxdWFscygiI25ld3MuIiwgbnMuc2hhcmVkWzNdLnByZWZpeCk7CisJYXNzZXJ0RXF1YWxzKCcuJywgbnMuc2hhcmVkWzNdLmRlbGltaXRlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBhIE5BTUVTUEFDRSByZXNwb25zZSB3aXRoIGEgVVRGLTcgZm9sZGVyIG5hbWUuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXRmNygpIHRocm93cyBFeGNlcHRpb24geworCUlNQVBSZXNwb25zZSByZXNwb25zZSA9IG5ldyBJTUFQUmVzcG9uc2UoCisJICAgICIqIE5BTUVTUEFDRSAoKFwiXCIgXCIvXCIpKSAiICsJLy8gcGVyc29uYWwKKwkgICAgIigoXCJ+XCIgXCIvXCIpKSAiICsJCS8vIG90aGVyIHVzZXJzCisJICAgICIoKFwiI3NoYXJlZC9cIiBcIi9cIikiICsJCS8vIHNoYXJlZAorCQkiKFwiIiArIHV0ZjdGb2xkZXIgKyAiXCIgXCIvXCIpIiArCisJCSIoXCIjZnRwL1wiIFwiL1wiKSIgKworCQkiKFwiI25ld3MuXCIgXCIuXCIpKSIsCisJICAgIGZhbHNlKTsKKwlOYW1lc3BhY2VzIG5zID0gbmV3IE5hbWVzcGFjZXMocmVzcG9uc2UpOworCWFzc2VydEVxdWFscygxLCBucy5wZXJzb25hbC5sZW5ndGgpOworCWFzc2VydEVxdWFscygiIiwgbnMucGVyc29uYWxbMF0ucHJlZml4KTsKKwlhc3NlcnRFcXVhbHMoJy8nLCBucy5wZXJzb25hbFswXS5kZWxpbWl0ZXIpOworCWFzc2VydEVxdWFscygxLCBucy5vdGhlclVzZXJzLmxlbmd0aCk7CisJYXNzZXJ0RXF1YWxzKCJ+IiwgbnMub3RoZXJVc2Vyc1swXS5wcmVmaXgpOworCWFzc2VydEVxdWFscygnLycsIG5zLm90aGVyVXNlcnNbMF0uZGVsaW1pdGVyKTsKKwlhc3NlcnRFcXVhbHMoNCwgbnMuc2hhcmVkLmxlbmd0aCk7CisJYXNzZXJ0RXF1YWxzKCIjc2hhcmVkLyIsIG5zLnNoYXJlZFswXS5wcmVmaXgpOworCWFzc2VydEVxdWFscygnLycsIG5zLnNoYXJlZFswXS5kZWxpbWl0ZXIpOworCWFzc2VydEVxdWFscyh1dGY4Rm9sZGVyLCBucy5zaGFyZWRbMV0ucHJlZml4KTsKKwlhc3NlcnRFcXVhbHMoJy8nLCBucy5zaGFyZWRbMV0uZGVsaW1pdGVyKTsKKwlhc3NlcnRFcXVhbHMoIiNmdHAvIiwgbnMuc2hhcmVkWzJdLnByZWZpeCk7CisJYXNzZXJ0RXF1YWxzKCcvJywgbnMuc2hhcmVkWzJdLmRlbGltaXRlcik7CisJYXNzZXJ0RXF1YWxzKCIjbmV3cy4iLCBucy5zaGFyZWRbM10ucHJlZml4KTsKKwlhc3NlcnRFcXVhbHMoJy4nLCBucy5zaGFyZWRbM10uZGVsaW1pdGVyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGEgTkFNRVNQQUNFIHJlc3BvbnNlIHdpdGggYSBVVEYtOCBmb2xkZXIgbmFtZS4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RVdGY4KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJSU1BUFJlc3BvbnNlIHJlc3BvbnNlID0gbmV3IElNQVBSZXNwb25zZSgKKwkgICAgIiogTkFNRVNQQUNFICgoXCJcIiBcIi9cIikpICIgKwkvLyBwZXJzb25hbAorCSAgICAiKChcIn5cIiBcIi9cIikpICIgKwkJLy8gb3RoZXIgdXNlcnMKKwkgICAgIigoXCIjc2hhcmVkL1wiIFwiL1wiKSIgKwkJLy8gc2hhcmVkCisJCSIoXCIiICsgdXRmOEZvbGRlciArICJcIiBcIi9cIikiICsKKwkJIihcIiNmdHAvXCIgXCIvXCIpIiArCisJCSIoXCIjbmV3cy5cIiBcIi5cIikpIiwKKwkgICAgdHJ1ZSk7CisJTmFtZXNwYWNlcyBucyA9IG5ldyBOYW1lc3BhY2VzKHJlc3BvbnNlKTsKKwlhc3NlcnRFcXVhbHMoMSwgbnMucGVyc29uYWwubGVuZ3RoKTsKKwlhc3NlcnRFcXVhbHMoIiIsIG5zLnBlcnNvbmFsWzBdLnByZWZpeCk7CisJYXNzZXJ0RXF1YWxzKCcvJywgbnMucGVyc29uYWxbMF0uZGVsaW1pdGVyKTsKKwlhc3NlcnRFcXVhbHMoMSwgbnMub3RoZXJVc2Vycy5sZW5ndGgpOworCWFzc2VydEVxdWFscygifiIsIG5zLm90aGVyVXNlcnNbMF0ucHJlZml4KTsKKwlhc3NlcnRFcXVhbHMoJy8nLCBucy5vdGhlclVzZXJzWzBdLmRlbGltaXRlcik7CisJYXNzZXJ0RXF1YWxzKDQsIG5zLnNoYXJlZC5sZW5ndGgpOworCWFzc2VydEVxdWFscygiI3NoYXJlZC8iLCBucy5zaGFyZWRbMF0ucHJlZml4KTsKKwlhc3NlcnRFcXVhbHMoJy8nLCBucy5zaGFyZWRbMF0uZGVsaW1pdGVyKTsKKwlhc3NlcnRFcXVhbHModXRmOEZvbGRlciwgbnMuc2hhcmVkWzFdLnByZWZpeCk7CisJYXNzZXJ0RXF1YWxzKCcvJywgbnMuc2hhcmVkWzFdLmRlbGltaXRlcik7CisJYXNzZXJ0RXF1YWxzKCIjZnRwLyIsIG5zLnNoYXJlZFsyXS5wcmVmaXgpOworCWFzc2VydEVxdWFscygnLycsIG5zLnNoYXJlZFsyXS5kZWxpbWl0ZXIpOworCWFzc2VydEVxdWFscygiI25ld3MuIiwgbnMuc2hhcmVkWzNdLnByZWZpeCk7CisJYXNzZXJ0RXF1YWxzKCcuJywgbnMuc2hhcmVkWzNdLmRlbGltaXRlcik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL3Byb3RvY29sL1N0YXR1c1Rlc3QuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9TdGF0dXNUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWNjNDQ3OAotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9TdGF0dXNUZXN0LmphdmEKQEAgLTAsMCArMSw5MiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAxNSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuaW1hcC5wcm90b2NvbDsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC5pYXAuUGFyc2luZ0V4Y2VwdGlvbjsKKworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEVxdWFsczsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworLyoqCisgKiBUZXN0IHRoZSBTdGF0dXMgY2xhc3MuCisgKi8KK3B1YmxpYyBjbGFzcyBTdGF0dXNUZXN0IHsKKyAgICAvKioKKyAgICAgKiBUZXN0IHRoYXQgdGhlIHJldHVybmVkIG1haWxib3ggbmFtZSBpcyBkZWNvZGVkLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdE1haWxib3hEZWNvZGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlTdHJpbmcgbWJveCA9ICJFbnR3XHUwMGZjcmZlIjsKKwlJTUFQUmVzcG9uc2UgcmVzcG9uc2UgPSBuZXcgSU1BUFJlc3BvbnNlKAorCSAgICAiKiBTVEFUVVMgIiArCisJICAgIEJBU0U2NE1haWxib3hFbmNvZGVyLmVuY29kZShtYm94KSArCisJICAgICIgKE1FU1NBR0VTIDIzMSBVSURORVhUIDQ0MjkyKSIsIGZhbHNlKTsKKwlTdGF0dXMgcyA9IG5ldyBTdGF0dXMocmVzcG9uc2UpOworCWFzc2VydEVxdWFscyhtYm94LCBzLm1ib3gpOworCWFzc2VydEVxdWFscygyMzEsIHMudG90YWwpOworCWFzc2VydEVxdWFscyg0NDI5Miwgcy51aWRuZXh0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHRoYXQgdGhlIHJldHVybmVkIG1haWxib3ggbmFtZSBpcyBjb3JyZWN0IHdoZW4gdXNpbmcgVVRGLTguCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWFpbGJveFV0ZjgoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlTdHJpbmcgbWJveCA9ICJFbnR3XHUwMGZjcmZlIjsKKwlJTUFQUmVzcG9uc2UgcmVzcG9uc2UgPSBuZXcgSU1BUFJlc3BvbnNlKAorCSAgICAiKiBTVEFUVVMgIiArCisJICAgIG1ib3ggKworCSAgICAiIChNRVNTQUdFUyAyMzEgVUlETkVYVCA0NDI5MikiLCB0cnVlKTsKKwlTdGF0dXMgcyA9IG5ldyBTdGF0dXMocmVzcG9uc2UpOworCWFzc2VydEVxdWFscyhtYm94LCBzLm1ib3gpOworCWFzc2VydEVxdWFscygyMzEsIHMudG90YWwpOworCWFzc2VydEVxdWFscyg0NDI5Miwgcy51aWRuZXh0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHRoYXQgc3BhY2VzIGluIHRoZSByZXNwb25zZSBkb24ndCBjb25mdXNlIGl0LgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFNwYWNlcygpIHRocm93cyBFeGNlcHRpb24geworCUlNQVBSZXNwb25zZSByZXNwb25zZSA9IG5ldyBJTUFQUmVzcG9uc2UoCisJICAgICIqIFNUQVRVUyAgdGVzdCAgKCBNRVNTQUdFUyAgMjMxICBVSURORVhUICA0NDI5MiApIik7CisJU3RhdHVzIHMgPSBuZXcgU3RhdHVzKHJlc3BvbnNlKTsKKwlhc3NlcnRFcXVhbHMoInRlc3QiLCBzLm1ib3gpOworCWFzc2VydEVxdWFscygyMzEsIHMudG90YWwpOworCWFzc2VydEVxdWFscyg0NDI5Miwgcy51aWRuZXh0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHRoYXQgYSBiYWQgcmVzcG9uc2UgdGhyb3dzIGEgUGFyc2luZ0V4Y2VwdGlvbgorICAgICAqLworICAgIEBUZXN0KGV4cGVjdGVkID0gUGFyc2luZ0V4Y2VwdGlvbi5jbGFzcykKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QmFkUmVzcG9uc2VOb0F0dHJMaXN0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJU3RyaW5nIG1ib3ggPSAidGVzdCI7CisJSU1BUFJlc3BvbnNlIHJlc3BvbnNlID0gbmV3IElNQVBSZXNwb25zZSgiKiBTVEFUVVMgdGVzdCAiKTsKKwlTdGF0dXMgcyA9IG5ldyBTdGF0dXMocmVzcG9uc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCBhIGJhZCByZXNwb25zZSB0aHJvd3MgYSBQYXJzaW5nRXhjZXB0aW9uCisgICAgICovCisgICAgQFRlc3QoZXhwZWN0ZWQgPSBQYXJzaW5nRXhjZXB0aW9uLmNsYXNzKQorICAgIHB1YmxpYyB2b2lkIHRlc3RCYWRSZXNwb25zZU5vQXR0cnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlTdHJpbmcgbWJveCA9ICJ0ZXN0IjsKKwlJTUFQUmVzcG9uc2UgcmVzcG9uc2UgPSBuZXcgSU1BUFJlc3BvbnNlKCIqIFNUQVRVUyB0ZXN0ICgiKTsKKwlTdGF0dXMgcyA9IG5ldyBTdGF0dXMocmVzcG9uc2UpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9TdHJhdG9JbWFwQnVnZml4VGVzdC5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL3Byb3RvY29sL1N0cmF0b0ltYXBCdWdmaXhUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmY5ZGQ5NwotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9TdHJhdG9JbWFwQnVnZml4VGVzdC5qYXZhCkBAIC0wLDAgKzEsNzAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDksIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmltYXAucHJvdG9jb2w7CisKK2ltcG9ydCBjb20uc3VuLm1haWwuaWFwLlBhcnNpbmdFeGNlcHRpb247CitpbXBvcnQgY29tLnN1bi5tYWlsLmlhcC5SZXNwb25zZTsKK2ltcG9ydCBjb20uc3VuLm1haWwuaW1hcC5wcm90b2NvbC5TdGF0dXM7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RXF1YWxzOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmZhaWw7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKKy8qKgorICogQGF1dGhvciB0a3JhbW1lcgorICovCitwdWJsaWMgY2xhc3MgU3RyYXRvSW1hcEJ1Z2ZpeFRlc3QgeworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFZhbGlkU3RhdHVzUmVzcG9uc2VMZWFkaW5nU3BhY2VzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJZmluYWwgUmVzcG9uc2UgcmVzcG9uc2UgPQorCQluZXcgUmVzcG9uc2UoIlNUQVRVUyBcIiAgU2VudCBJdGVtcyAgXCIgKFVJRE5FWFQgMSkiKTsKKwlmaW5hbCBTdGF0dXMgc3RhdHVzID0gbmV3IFN0YXR1cyhyZXNwb25zZSk7CisKKwlhc3NlcnRFcXVhbHMoIiAgU2VudCBJdGVtcyAgIiwgc3RhdHVzLm1ib3gpOworCWFzc2VydEVxdWFscygxLCBzdGF0dXMudWlkbmV4dCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VmFsaWRTdGF0dXNSZXNwb25zZSgpIHRocm93cyBFeGNlcHRpb24geworCWZpbmFsIFJlc3BvbnNlIHJlc3BvbnNlID0KKwkJbmV3IFJlc3BvbnNlKCJTVEFUVVMgXCJTZW50IEl0ZW1zXCIgKFVJRE5FWFQgMSkiKTsKKwlmaW5hbCBTdGF0dXMgc3RhdHVzID0gbmV3IFN0YXR1cyhyZXNwb25zZSk7CisKKwlhc3NlcnRFcXVhbHMoIlNlbnQgSXRlbXMiLCBzdGF0dXMubWJveCk7CisJYXNzZXJ0RXF1YWxzKDEsIHN0YXR1cy51aWRuZXh0KTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RJbnZhbGlkU3RhdHVzUmVzcG9uc2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlSZXNwb25zZSByZXNwb25zZSA9IG5ldyBSZXNwb25zZSgiU1RBVFVTIFNlbnQgSXRlbXMgKFVJRE5FWFQgMSkiKTsKKwlmaW5hbCBTdGF0dXMgc3RhdHVzID0gbmV3IFN0YXR1cyhyZXNwb25zZSk7CisKKwlhc3NlcnRFcXVhbHMoIlNlbnQgSXRlbXMiLCBzdGF0dXMubWJveCk7CisJYXNzZXJ0RXF1YWxzKDEsIHN0YXR1cy51aWRuZXh0KTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RNaXNzaW5nQnJhY2tldCgpIHRocm93cyBFeGNlcHRpb24geworCWZpbmFsIFJlc3BvbnNlIHJlc3BvbnNlID0KKwkJbmV3IFJlc3BvbnNlKCJTVEFUVVMgXCJTZW50IEl0ZW1zXCIgVUlETkVYVCAxKSIpOworCisJdHJ5IHsKKwkgICAgbmV3IFN0YXR1cyhyZXNwb25zZSk7CisJICAgIGZhaWwoIk11c3QgdGhyb3cgZXhjZXB0aW9uIik7CisJfSBjYXRjaChQYXJzaW5nRXhjZXB0aW9uIGUpIHsKKwl9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9pbWFwL3Byb3RvY29sL1VJRFNldFRlc3QuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9VSURTZXRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjZiMWM4NAotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC9VSURTZXRUZXN0LmphdmEKQEAgLTAsMCArMSwyMjkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLmltYXAucHJvdG9jb2w7CisKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YS51dGlsLio7CisKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQuQXNzZXJ0OworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVycy5QYXJhbWV0ZXJpemVkOworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXJzLlBhcmFtZXRlcml6ZWQuUGFyYW1ldGVyczsKKworLyoqCisgKiBUZXN0IFVJRFNldC4KKyAqCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCisKK0BSdW5XaXRoKFBhcmFtZXRlcml6ZWQuY2xhc3MpCitwdWJsaWMgY2xhc3MgVUlEU2V0VGVzdCB7CisgICAgcHJpdmF0ZSBUZXN0RGF0YSBkYXRhOworCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBnZW5fdGVzdF9pbnB1dCA9IGZhbHNlOwkvLyBvdXRwdXQgZ29vZAorICAgIHByaXZhdGUgc3RhdGljIGludCBlcnJvcnMgPSAwOwkJLy8gbnVtYmVyIG9mIGVycm9ycyBkZXRlY3RlZAorCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBqdW5pdDsKKworICAgIHN0YXRpYyBjbGFzcyBUZXN0RGF0YSB7CisJcHVibGljIFN0cmluZyBuYW1lOworCXB1YmxpYyBTdHJpbmcgdWlkczsKKwlwdWJsaWMgbG9uZyBtYXg7CisJcHVibGljIFN0cmluZyBtYXh1aWRzOworCXB1YmxpYyBsb25nW10gZXhwZWN0OworICAgIH0KKworICAgIHB1YmxpYyBVSURTZXRUZXN0KFRlc3REYXRhIHQpIHsKKwlkYXRhID0gdDsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3REYXRhKCkgeworCXRlc3QoZGF0YSk7CisgICAgfQorCisgICAgQFBhcmFtZXRlcnMKKyAgICBwdWJsaWMgc3RhdGljIENvbGxlY3Rpb248VGVzdERhdGFbXT4gZGF0YSgpIHRocm93cyBFeGNlcHRpb24geworCWp1bml0ID0gdHJ1ZTsKKwkvLyBYWFggLSBncmF0dWl0b3VzIGFycmF5IHJlcXVpcmVtZW50CisJTGlzdDxUZXN0RGF0YVtdPiB0ZXN0RGF0YSA9IG5ldyBBcnJheUxpc3Q8PigpOworCUJ1ZmZlcmVkUmVhZGVyIGluID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBJbnB1dFN0cmVhbVJlYWRlcigKKwkgICAgVUlEU2V0VGVzdC5jbGFzcy5nZXRSZXNvdXJjZUFzU3RyZWFtKCJ1aWRkYXRhIikpKTsKKwlUZXN0RGF0YSB0OworCXdoaWxlICgodCA9IHBhcnNlKGluKSkgIT0gbnVsbCkKKwkgICAgdGVzdERhdGEuYWRkKG5ldyBUZXN0RGF0YVtdIHsgdCB9KTsKKwlyZXR1cm4gdGVzdERhdGE7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nIGFyZ3ZbXSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJaW50IG9wdGluZDsKKwkvLyBYWFggLSBhbGwgb3B0aW9ucyBjdXJyZW50bHkgaWdub3JlZAorCWZvciAob3B0aW5kID0gMDsgb3B0aW5kIDwgYXJndi5sZW5ndGg7IG9wdGluZCsrKSB7CisJICAgIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItIikpIHsKKwkJLy8gaWdub3JlCisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLWciKSkgeworCQlnZW5fdGVzdF9pbnB1dCA9IHRydWU7CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLS0iKSkgeworCQlvcHRpbmQrKzsKKwkJYnJlYWs7CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLnN0YXJ0c1dpdGgoIi0iKSkgeworCQlTeXN0ZW0ub3V0LnByaW50bG4oCisJCSAgICAiVXNhZ2U6IHVpZHRlc3QgWy1nXSBbLV0iKTsKKwkJU3lzdGVtLmV4aXQoMSk7CisJICAgIH0gZWxzZSB7CisJCWJyZWFrOworCSAgICB9CisJfQorCisJLy8gcmVhZCBmcm9tIHN0ZGluCisJQnVmZmVyZWRSZWFkZXIgaW4gPQorCSAgICBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IElucHV0U3RyZWFtUmVhZGVyKFN5c3RlbS5pbikpOworCisJVGVzdERhdGEgdDsKKwl3aGlsZSAoKHQgPSBwYXJzZShpbikpICE9IG51bGwpCisJICAgIHRlc3QodCk7CisJU3lzdGVtLmV4aXQoZXJyb3JzKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIFBhcnNlIHRoZSBpbnB1dCwgcmV0dXJuaW5nIGEgdGVzdCBjYXNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgVGVzdERhdGEgcGFyc2UoQnVmZmVyZWRSZWFkZXIgaW4pIHRocm93cyBFeGNlcHRpb24geworCisJU3RyaW5nIGxpbmUgPSBudWxsOworCWZvciAoOzspIHsKKwkgICAgbGluZSA9IGluLnJlYWRMaW5lKCk7CisJICAgIGlmIChsaW5lID09IG51bGwpCisJCXJldHVybiBudWxsOworCSAgICBpZiAobGluZS5sZW5ndGgoKSA9PSAwIHx8IGxpbmUuc3RhcnRzV2l0aCgiIyIpKQorCQljb250aW51ZTsKKworCSAgICBpZiAoIWxpbmUuc3RhcnRzV2l0aCgiVEVTVCIpKQorCQl0aHJvdyBuZXcgRXhjZXB0aW9uKCJCYWQgdGVzdCBkYXRhIGZvcm1hdCIpOworCSAgICBicmVhazsKKwl9CisKKwlUZXN0RGF0YSB0ID0gbmV3IFRlc3REYXRhKCk7CisJaW50IGkgPSBsaW5lLmluZGV4T2YoJyAnKTsJLy8gWFhYIC0gY3J1ZGUKKwl0Lm5hbWUgPSBsaW5lLnN1YnN0cmluZyhpICsgMSk7CisKKwlsaW5lID0gaW4ucmVhZExpbmUoKTsKKwlTdHJpbmdUb2tlbml6ZXIgc3QgPSBuZXcgU3RyaW5nVG9rZW5pemVyKGxpbmUpOworCVN0cmluZyB0b2sgPSBzdC5uZXh0VG9rZW4oKTsKKwlpZiAoIXRvay5lcXVhbHMoIkRBVEEiKSkKKwkgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiQmFkIHRlc3QgZGF0YSBmb3JtYXQ6ICIgKyBsaW5lKTsKKwl0b2sgPSBzdC5uZXh0VG9rZW4oKTsKKwlpZiAodG9rLmVxdWFscygiTlVMTCIpKQorCSAgICB0LnVpZHMgPSBudWxsOworCWVsc2UgaWYgKHRvay5lcXVhbHMoIkVNUFRZIikpCisJICAgIHQudWlkcyA9ICIiOworCWVsc2UKKwkgICAgdC51aWRzID0gdG9rOworCisJbGluZSA9IGluLnJlYWRMaW5lKCk7CisJc3QgPSBuZXcgU3RyaW5nVG9rZW5pemVyKGxpbmUpOworCXRvayA9IHN0Lm5leHRUb2tlbigpOworCWlmICh0b2suZXF1YWxzKCJNQVgiKSkgeworCSAgICB0b2sgPSBzdC5uZXh0VG9rZW4oKTsKKwkgICAgdHJ5IHsKKwkJdC5tYXggPSBMb25nLnZhbHVlT2YodG9rKTsKKwkgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGV4KSB7CisJCXRocm93IG5ldyBFeGNlcHRpb24oIkJhZCBNQVggdmFsdWUgaW4gbGluZTogIiArIGxpbmUpOworCSAgICB9CisJICAgIGlmIChzdC5oYXNNb3JlVG9rZW5zKCkpCisJCXQubWF4dWlkcyA9IHN0Lm5leHRUb2tlbigpOworCSAgICBlbHNlCisJCXQubWF4dWlkcyA9IHQudWlkczsKKwkgICAgbGluZSA9IGluLnJlYWRMaW5lKCk7CisJICAgIHN0ID0gbmV3IFN0cmluZ1Rva2VuaXplcihsaW5lKTsKKwkgICAgdG9rID0gc3QubmV4dFRva2VuKCk7CisJfQorCUxpc3Q8TG9uZz4gdWlkcyA9IG5ldyBBcnJheUxpc3Q8PigpOworCWlmICghdG9rLmVxdWFscygiRVhQRUNUIikpCisJICAgIHRocm93IG5ldyBFeGNlcHRpb24oIkJhZCB0ZXN0IGRhdGEgZm9ybWF0OiAiICsgbGluZSk7CisJd2hpbGUgKHN0Lmhhc01vcmVUb2tlbnMoKSkgeworCSAgICB0b2sgPSBzdC5uZXh0VG9rZW4oKTsKKwkgICAgaWYgKHRvay5lcXVhbHMoIk5VTEwiKSkKKwkJdC5leHBlY3QgPSBudWxsOworCSAgICBlbHNlIGlmICh0b2suZXF1YWxzKCJFTVBUWSIpKQorCQl0LmV4cGVjdCA9IG5ldyBsb25nWzBdOworCSAgICBlbHNlIHsKKwkJdHJ5IHsKKwkJICAgIHVpZHMuYWRkKExvbmcudmFsdWVPZih0b2spKTsKKwkJfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGV4KSB7CisJCSAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJCYWQgREFUQSBvcHRpb24gaW4gbGluZTogIiArIGxpbmUpOworCQl9CisJICAgIH0KKwl9CisJaWYgKHVpZHMuc2l6ZSgpID4gMCkgeworCSAgICB0LmV4cGVjdCA9IG5ldyBsb25nW3VpZHMuc2l6ZSgpXTsKKwkgICAgaSA9IDA7CisJICAgIGZvciAoTG9uZyBsIDogdWlkcykKKwkJdC5leHBlY3RbaSsrXSA9IGwubG9uZ1ZhbHVlKCk7CisJfQorCisJcmV0dXJuIHQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGUgZGF0YSBpbiB0aGUgdGVzdCBjYXNlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCB0ZXN0KFRlc3REYXRhIHQpIHsKKwkvLyBYWFggLSBoYW5kbGUgbnVsbHMKKworCS8vIGZpcnN0LCB0ZXN0IHN0cmluZyB0byBhcnJheQorCVVJRFNldFtdIHVpZHNldCA9IFVJRFNldC5wYXJzZVVJRFNldHModC51aWRzKTsKKwlsb25nW10gdWlkczsKKwlpZiAodC5tYXggPiAwKQorCSAgICB1aWRzID0gVUlEU2V0LnRvQXJyYXkodWlkc2V0LCB0Lm1heCk7CisJZWxzZQorCSAgICB1aWRzID0gVUlEU2V0LnRvQXJyYXkodWlkc2V0KTsKKwlpZiAoanVuaXQpCisJICAgIEFzc2VydC5hc3NlcnRBcnJheUVxdWFscyh0LmV4cGVjdCwgdWlkcyk7CisJZWxzZSBpZiAoIWFycmF5RXF1YWxzKHQuZXhwZWN0LCB1aWRzKSkgeworCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlRlc3Q6ICIgKyB0Lm5hbWUpOworCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkZBSUwiKTsKKwkgICAgZXJyb3JzKys7CisJfQorCisJLy8gbm93LCB0ZXN0IHRoZSByZXZlcnNlCisJVUlEU2V0W10gdWlkc2V0MiA9IFVJRFNldC5jcmVhdGVVSURTZXRzKHVpZHMpOworCVN0cmluZyBzdWlkID0gVUlEU2V0LnRvU3RyaW5nKHVpZHNldDIpOworCVN0cmluZyBldWlkID0gdC5tYXggPiAwID8gdC5tYXh1aWRzIDogdC51aWRzOworCWlmIChqdW5pdCkKKwkgICAgQXNzZXJ0LmFzc2VydEVxdWFscyhldWlkLCBzdWlkKTsKKwllbHNlIGlmICghZXVpZC5lcXVhbHMoc3VpZCkpIHsKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJUZXN0OiAiICsgdC5uYW1lKTsKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJGQUlMMiIpOworCSAgICBlcnJvcnMrKzsKKwl9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBhcnJheUVxdWFscyhsb25nW10gYSxsb25nW10gYikgeworCWlmIChhID09IGIpCisJICAgIHJldHVybiB0cnVlOworCWlmIChhID09IG51bGwgfHwgYiA9PSBudWxsKQorCSAgICByZXR1cm4gZmFsc2U7CisJaWYgKGEubGVuZ3RoICE9IGIubGVuZ3RoKQorCSAgICByZXR1cm4gZmFsc2U7CisJZm9yIChpbnQgaSA9IDA7IGkgPCBhLmxlbmd0aDsgaSsrKQorCSAgICBpZiAoYVtpXSAhPSBiW2ldKQorCQlyZXR1cm4gZmFsc2U7CisJcmV0dXJuIHRydWU7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9wb3AzL1BPUDNBdXRoRGVidWdUZXN0LmphdmEgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3BvcDMvUE9QM0F1dGhEZWJ1Z1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZmY2NjdkCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9wb3AzL1BPUDNBdXRoRGVidWdUZXN0LmphdmEKQEAgLTAsMCArMSwxMzMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDksIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLnBvcDM7CisKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7CisKK2ltcG9ydCBqYXZheC5tYWlsLlNlc3Npb247CitpbXBvcnQgamF2YXgubWFpbC5TdG9yZTsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC50ZXN0LlRlc3RTZXJ2ZXI7CisKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQuUnVsZTsKK2ltcG9ydCBvcmcuanVuaXQucnVsZXMuVGltZW91dDsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUcnVlOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEZhbHNlOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmZhaWw7CisKKy8qKgorICogVGVzdCB0aGF0IGF1dGhlbnRpY2F0aW9uIGluZm9ybWF0aW9uIGlzIG9ubHkgaW5jbHVkZWQgaW4KKyAqIHRoZSBkZWJ1ZyBvdXRwdXQgd2hlbiBleHBsaWNpdGx5IHJlcXVlc3RlZCBieSBzZXR0aW5nIHRoZQorICogcHJvcGVydHkgIm1haWwuZGVidWcuYXV0aCIgdG8gInRydWUiLgorICoKKyAqIFhYWCAtIHNob3VsZCB0ZXN0IGFsbCBhdXRoZW50aWNhdGlvbiB0eXBlcywgYnV0IHRoYXQgcmVxdWlyZXMKKyAqCSBtb3JlIHdvcmsgaW4gdGhlIGR1bW15IHRlc3Qgc2VydmVyLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgUE9QM0F1dGhEZWJ1Z1Rlc3QgeworCisgICAgLy8gdGltZW91dCB0aGUgdGVzdCBpbiBjYXNlIG9mIGRlYWRsb2NrCisgICAgQFJ1bGUKKyAgICBwdWJsaWMgVGltZW91dCBkZWFkbG9ja1RpbWVvdXQgPSBUaW1lb3V0LnNlY29uZHMoMjApOworCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IGF1dGhlbnRpY2F0aW9uIGluZm9ybWF0aW9uIGlzbid0IGluY2x1ZGVkIGluIHRoZSBkZWJ1ZyBvdXRwdXQuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Tm9BdXRoRGVmYXVsdCgpIHsKKwlmaW5hbCBQcm9wZXJ0aWVzIHByb3BlcnRpZXMgPSBuZXcgUHJvcGVydGllcygpOworCWFzc2VydEZhbHNlKCJQQVNTIGluIGRlYnVnIG91dHB1dCIsIHRlc3QocHJvcGVydGllcywgIlBBU1MiKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Tm9BdXRoKCkgeworCWZpbmFsIFByb3BlcnRpZXMgcHJvcGVydGllcyA9IG5ldyBQcm9wZXJ0aWVzKCk7CisJcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5kZWJ1Zy5hdXRoIiwgImZhbHNlIik7CisJYXNzZXJ0RmFsc2UoIlBBU1MgaW4gZGVidWcgb3V0cHV0IiwgdGVzdChwcm9wZXJ0aWVzLCAiUEFTUyIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHRoYXQgYXV0aGVudGljYXRpb24gaW5mb3JtYXRpb24gKmlzKiBpbmNsdWRlZCBpbiB0aGUgZGVidWcgb3V0cHV0LgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEF1dGgoKSB7CisJZmluYWwgUHJvcGVydGllcyBwcm9wZXJ0aWVzID0gbmV3IFByb3BlcnRpZXMoKTsKKwlwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLmRlYnVnLmF1dGgiLCAidHJ1ZSIpOworCWFzc2VydFRydWUoIlBBU1MgaW4gZGVidWcgb3V0cHV0IiwgdGVzdChwcm9wZXJ0aWVzLCAiUEFTUyIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSB0ZXN0IHNlcnZlciwgY29ubmVjdCB0byBpdCwgYW5kIGNvbGxlY3QgdGhlIGRlYnVnIG91dHB1dC4KKyAgICAgKiBTY2FuIHRoZSBkZWJ1ZyBvdXRwdXQgbG9va2luZyBmb3IgImV4cGVjdCIsIHJldHVybiB0cnVlIGlmIGZvdW5kLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHRlc3QoUHJvcGVydGllcyBwcm9wZXJ0aWVzLCBTdHJpbmcgZXhwZWN0KSB7CisJVGVzdFNlcnZlciBzZXJ2ZXIgPSBudWxsOworCXRyeSB7CisJICAgIGZpbmFsIFBPUDNIYW5kbGVyIGhhbmRsZXIgPSBuZXcgUE9QM0hhbmRsZXIoKTsKKwkgICAgc2VydmVyID0gbmV3IFRlc3RTZXJ2ZXIoaGFuZGxlcik7CisJICAgIHNlcnZlci5zdGFydCgpOworCSAgICBUaHJlYWQuc2xlZXAoMTAwMCk7CisKKwkgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5wb3AzLmhvc3QiLCAibG9jYWxob3N0Iik7CisJICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwucG9wMy5wb3J0IiwgIiIgKyBzZXJ2ZXIuZ2V0UG9ydCgpKTsKKwkgICAgZmluYWwgU2Vzc2lvbiBzZXNzaW9uID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShwcm9wZXJ0aWVzKTsKKwkgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKwkgICAgUHJpbnRTdHJlYW0gcHMgPSBuZXcgUHJpbnRTdHJlYW0oYm9zKTsKKwkgICAgc2Vzc2lvbi5zZXREZWJ1Z091dChwcyk7CisJICAgIHNlc3Npb24uc2V0RGVidWcodHJ1ZSk7CisKKwkgICAgZmluYWwgU3RvcmUgc3RvcmUgPSBzZXNzaW9uLmdldFN0b3JlKCJwb3AzIik7CisJICAgIHRyeSB7CisJCXN0b3JlLmNvbm5lY3QoInRlc3QiLCAidGVzdCIpOworCSAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKwkJU3lzdGVtLm91dC5wcmludGxuKGV4KTsKKwkJLy9leC5wcmludFN0YWNrVHJhY2UoKTsKKwkJZmFpbChleC50b1N0cmluZygpKTsKKwkgICAgfSBmaW5hbGx5IHsKKwkJc3RvcmUuY2xvc2UoKTsKKwkgICAgfQorCisJICAgIHBzLmNsb3NlKCk7CisJICAgIGJvcy5jbG9zZSgpOworCSAgICBCeXRlQXJyYXlJbnB1dFN0cmVhbSBiaXMgPQorCQluZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYm9zLnRvQnl0ZUFycmF5KCkpOworCSAgICBCdWZmZXJlZFJlYWRlciByID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKAorCQkJCQluZXcgSW5wdXRTdHJlYW1SZWFkZXIoYmlzLCAidXMtYXNjaWkiKSk7CisJICAgIFN0cmluZyBsaW5lOworCSAgICBib29sZWFuIGZvdW5kID0gZmFsc2U7CisJICAgIHdoaWxlICgobGluZSA9IHIucmVhZExpbmUoKSkgIT0gbnVsbCkgeworCQlpZiAobGluZS5zdGFydHNXaXRoKCJERUJVRyIpKQorCQkgICAgY29udGludWU7CisJCWlmIChsaW5lLnN0YXJ0c1dpdGgoIioiKSkKKwkJICAgIGNvbnRpbnVlOworCQlpZiAobGluZS5pbmRleE9mKGV4cGVjdCkgPj0gMCkKKwkJICAgIGZvdW5kID0gdHJ1ZTsKKwkgICAgfQorCSAgICByLmNsb3NlKCk7CisJICAgIHJldHVybiBmb3VuZDsKKwl9IGNhdGNoIChmaW5hbCBFeGNlcHRpb24gZSkgeworCSAgICBlLnByaW50U3RhY2tUcmFjZSgpOworCSAgICBmYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKwkgICAgcmV0dXJuIGZhbHNlOwkvLyBYWFggLSBkb2Vzbid0IG1hdHRlcgorCX0gZmluYWxseSB7CisJICAgIGlmIChzZXJ2ZXIgIT0gbnVsbCkgeworCQlzZXJ2ZXIucXVpdCgpOworCSAgICB9CisJfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvcG9wMy9QT1AzRm9sZGVyQ2xvc2VkRXhjZXB0aW9uVGVzdC5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9wb3AzL1BPUDNGb2xkZXJDbG9zZWRFeGNlcHRpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzI2OWU5YgotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvcG9wMy9QT1AzRm9sZGVyQ2xvc2VkRXhjZXB0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTczIEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDA5LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5wb3AzOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKKworaW1wb3J0IGphdmF4Lm1haWwuRm9sZGVyOworaW1wb3J0IGphdmF4Lm1haWwuU2Vzc2lvbjsKK2ltcG9ydCBqYXZheC5tYWlsLlN0b3JlOworaW1wb3J0IGphdmF4Lm1haWwuTWVzc2FnZTsKK2ltcG9ydCBqYXZheC5tYWlsLkZvbGRlckNsb3NlZEV4Y2VwdGlvbjsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC50ZXN0LlRlc3RTZXJ2ZXI7CisKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRGYWxzZTsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5mYWlsOworCisvKioKKyAqIFRlc3QgdGhhdCBGb2xkZXJDbG9zZWRFeGNlcHRpb24gaXMgdGhyb3duIHdoZW4gc2VydmVyIHRpbWVzIG91dCBjb25uZWN0aW9uLgorICogVGhpcyB0ZXN0IGlzIGRlcml2ZWQgZnJvbSByZWFsIGZhaWx1cmVzIHNlZW4gd2l0aCBIb3RtYWlsLgorICoKKyAqIEBhdXRob3Igc2JvCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgUE9QM0ZvbGRlckNsb3NlZEV4Y2VwdGlvblRlc3QgeworCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IEZvbGRlckNsb3NlZEV4Y2VwdGlvbiBpcyB0aHJvd24gd2hlbiB0aGUgdGltZW91dCBvY2N1cnMKKyAgICAgKiB3aGVuIHJlYWRpbmcgdGhlIG1lc3NhZ2UgYm9keS4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RGb2xkZXJDbG9zZWRFeGNlcHRpb25Cb2R5KCkgeworCVRlc3RTZXJ2ZXIgc2VydmVyID0gbnVsbDsKKwl0cnkgeworCSAgICBmaW5hbCBQT1AzSGFuZGxlciBoYW5kbGVyID0gbmV3IFBPUDNIYW5kbGVyVGltZW91dEJvZHkoKTsKKwkgICAgc2VydmVyID0gbmV3IFRlc3RTZXJ2ZXIoaGFuZGxlcik7CisJICAgIHNlcnZlci5zdGFydCgpOworCSAgICBUaHJlYWQuc2xlZXAoMTAwMCk7CisKKwkgICAgZmluYWwgUHJvcGVydGllcyBwcm9wZXJ0aWVzID0gbmV3IFByb3BlcnRpZXMoKTsKKwkgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5wb3AzLmhvc3QiLCAibG9jYWxob3N0Iik7CisJICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwucG9wMy5wb3J0IiwgIiIgKyBzZXJ2ZXIuZ2V0UG9ydCgpKTsKKwkgICAgZmluYWwgU2Vzc2lvbiBzZXNzaW9uID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShwcm9wZXJ0aWVzKTsKKwkgICAgLy9zZXNzaW9uLnNldERlYnVnKHRydWUpOworCisJICAgIGZpbmFsIFN0b3JlIHN0b3JlID0gc2Vzc2lvbi5nZXRTdG9yZSgicG9wMyIpOworCSAgICB0cnkgeworCQlzdG9yZS5jb25uZWN0KCJ0ZXN0IiwgInRlc3QiKTsKKwkJZmluYWwgRm9sZGVyIGZvbGRlciA9IHN0b3JlLmdldEZvbGRlcigiSU5CT1giKTsKKwkJZm9sZGVyLm9wZW4oRm9sZGVyLlJFQURfT05MWSk7CisJCU1lc3NhZ2UgbXNnID0gZm9sZGVyLmdldE1lc3NhZ2UoMSk7CisJCXRyeSB7CisJCSAgICBtc2cuZ2V0Q29udGVudCgpOworCQl9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2V4KSB7CisJCSAgICAvLyBleHBlY3RlZAorCQkgICAgLy8gZmlyc3QgYXR0ZW1wdCBkZXRlY3RzIGVycm9yIHJldHVybiBmcm9tIHNlcnZlcgorCQl9CisJCS8vIHNlY29uZCBhdHRlbXB0IGRldGVjdHMgY2xvc2VkIGNvbm5lY3Rpb24gZnJvbSBzZXJ2ZXIKKwkJbXNnLmdldENvbnRlbnQoKTsKKworCQkvLyBDaGVjaworCQlhc3NlcnRGYWxzZShmb2xkZXIuaXNPcGVuKCkpOworCSAgICB9IGNhdGNoIChGb2xkZXJDbG9zZWRFeGNlcHRpb24gZXgpIHsKKwkJLy8gc3VjY2VzcyEKKwkgICAgfSBmaW5hbGx5IHsKKwkJc3RvcmUuY2xvc2UoKTsKKwkgICAgfQorCX0gY2F0Y2ggKGZpbmFsIEV4Y2VwdGlvbiBlKSB7CisJICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisJICAgIGZhaWwoZS5nZXRNZXNzYWdlKCkpOworCX0gZmluYWxseSB7CisJICAgIGlmIChzZXJ2ZXIgIT0gbnVsbCkgeworCQlzZXJ2ZXIucXVpdCgpOworCSAgICB9CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEN1c3RvbSBoYW5kbGVyLiAgUmV0dXJucyBFUlIgZm9yIFJFVFIgdGhlIGZpcnN0IHRpbWUsCisgICAgICogdGhlbiBjbG9zZXMgdGhlIGNvbm5lY3Rpb24gdGhlIHNlY29uZCB0aW1lLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFBPUDNIYW5kbGVyVGltZW91dEJvZHkgZXh0ZW5kcyBQT1AzSGFuZGxlciB7CisKKwlwcml2YXRlIGJvb2xlYW4gZmlyc3QgPSB0cnVlOworCisJLyoqCisJICoge0Bpbmhlcml0RG9jfQorCSAqLworCUBPdmVycmlkZQorCXB1YmxpYyB2b2lkIHJldHIoU3RyaW5nIGFyZykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkgICAgaWYgKGZpcnN0KSB7CisJCXByaW50bG4oIi1FUlIgU2VydmVyIHRpbWVvdXQiKTsKKwkJZmlyc3QgPSBmYWxzZTsKKwkgICAgfSBlbHNlCisJCWV4aXQoKTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IEZvbGRlckNsb3NlZEV4Y2VwdGlvbiBpcyB0aHJvd24gd2hlbiB0aGUgdGltZW91dCBvY2N1cnMKKyAgICAgKiB3aGVuIHJlYWRpbmcgdGhlIGhlYWRlcnMuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9sZGVyQ2xvc2VkRXhjZXB0aW9uSGVhZGVycygpIHsKKwlUZXN0U2VydmVyIHNlcnZlciA9IG51bGw7CisJdHJ5IHsKKwkgICAgZmluYWwgUE9QM0hhbmRsZXIgaGFuZGxlciA9IG5ldyBQT1AzSGFuZGxlclRpbWVvdXRIZWFkZXIoKTsKKwkgICAgc2VydmVyID0gbmV3IFRlc3RTZXJ2ZXIoaGFuZGxlcik7CisJICAgIHNlcnZlci5zdGFydCgpOworCSAgICBUaHJlYWQuc2xlZXAoMTAwMCk7CisKKwkgICAgZmluYWwgUHJvcGVydGllcyBwcm9wZXJ0aWVzID0gbmV3IFByb3BlcnRpZXMoKTsKKwkgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5wb3AzLmhvc3QiLCAibG9jYWxob3N0Iik7CisJICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwucG9wMy5wb3J0IiwgIiIgKyBzZXJ2ZXIuZ2V0UG9ydCgpKTsKKwkgICAgZmluYWwgU2Vzc2lvbiBzZXNzaW9uID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShwcm9wZXJ0aWVzKTsKKwkgICAgLy9zZXNzaW9uLnNldERlYnVnKHRydWUpOworCisJICAgIGZpbmFsIFN0b3JlIHN0b3JlID0gc2Vzc2lvbi5nZXRTdG9yZSgicG9wMyIpOworCSAgICB0cnkgeworCQlzdG9yZS5jb25uZWN0KCJ0ZXN0IiwgInRlc3QiKTsKKwkJZmluYWwgRm9sZGVyIGZvbGRlciA9IHN0b3JlLmdldEZvbGRlcigiSU5CT1giKTsKKwkJZm9sZGVyLm9wZW4oRm9sZGVyLlJFQURfT05MWSk7CisJCU1lc3NhZ2UgbXNnID0gZm9sZGVyLmdldE1lc3NhZ2UoMSk7CisJCW1zZy5nZXRTdWJqZWN0KCk7CisKKwkJLy8gQ2hlY2sKKwkJYXNzZXJ0RmFsc2UoZm9sZGVyLmlzT3BlbigpKTsKKwkgICAgfSBjYXRjaCAoRm9sZGVyQ2xvc2VkRXhjZXB0aW9uIGV4KSB7CisJCS8vIHN1Y2Nlc3MhCisJICAgIH0gZmluYWxseSB7CisJCXN0b3JlLmNsb3NlKCk7CisJICAgIH0KKwl9IGNhdGNoIChmaW5hbCBFeGNlcHRpb24gZSkgeworCSAgICBlLnByaW50U3RhY2tUcmFjZSgpOworCSAgICBmYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKwl9IGZpbmFsbHkgeworCSAgICBpZiAoc2VydmVyICE9IG51bGwpIHsKKwkJc2VydmVyLnF1aXQoKTsKKwkgICAgfQorCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDdXN0b20gaGFuZGxlci4gIFJldHVybnMgRVJSIGZvciBUT1AsIHRoZW4gY2xvc2VzIGNvbm5lY3Rpb24uCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgUE9QM0hhbmRsZXJUaW1lb3V0SGVhZGVyIGV4dGVuZHMgUE9QM0hhbmRsZXIgeworCisJLyoqCisJICoge0Bpbmhlcml0RG9jfQorCSAqLworCUBPdmVycmlkZQorCXB1YmxpYyB2b2lkIHRvcChTdHJpbmcgYXJnKSB0aHJvd3MgSU9FeGNlcHRpb24geworCSAgICBwcmludGxuKCItRVJSIFNlcnZlciB0aW1lb3V0Iik7CisJICAgIGV4aXQoKTsKKwl9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9wb3AzL1BPUDNIYW5kbGVyLmphdmEgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3BvcDMvUE9QM0hhbmRsZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wNzEzZmYxCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9wb3AzL1BPUDNIYW5kbGVyLmphdmEKQEAgLTAsMCArMSwyNzkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDksIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLnBvcDM7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7CitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTG9nZ2VyOworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkxldmVsOworCitpbXBvcnQgY29tLnN1bi5tYWlsLnRlc3QuUHJvdG9jb2xIYW5kbGVyOworCisvKioKKyAqIEhhbmRsZSBjb25uZWN0aW9uLgorICoKKyAqIEBhdXRob3Igc2JvCisgKi8KK3B1YmxpYyBjbGFzcyBQT1AzSGFuZGxlciBleHRlbmRzIFByb3RvY29sSGFuZGxlciB7CisKKyAgICAvKiogQ3VycmVudCBsaW5lLiAqLworICAgIHByaXZhdGUgU3RyaW5nIGN1cnJlbnRMaW5lOworCisgICAgLyoqIEZpcnN0IHRlc3QgbWVzc2FnZS4gKi8KKyAgICBwcml2YXRlIFN0cmluZyB0b3AxID0KKwkgICAgIk1pbWUtVmVyc2lvbjogMS4wXHJcbiIgKworCSAgICAiRnJvbTogam9lQGV4YW1wbGUuY29tXHJcbiIgKworCSAgICAiVG86IGJvYkBleGFtcGxlLmNvbVxyXG4iICsKKwkgICAgIlN1YmplY3Q6IEV4YW1wbGVcclxuIiArCisJICAgICJDb250ZW50LVR5cGU6IHRleHQvcGxhaW5cclxuIiArCisJICAgICJcclxuIjsKKyAgICBwcml2YXRlIFN0cmluZyBtc2cxID0gdG9wMSArCisJICAgICJwbGFpbiB0ZXh0XHJcbiI7CisKKyAgICAvKiogU2Vjb25kIHRlc3QgbWVzc2FnZS4gKi8KKyAgICBwcml2YXRlIFN0cmluZyB0b3AyID0KKwkgICAgIk1pbWUtVmVyc2lvbjogMS4wXHJcbiIgKworCSAgICAiRnJvbTogam9lQGV4YW1wbGUuY29tXHJcbiIgKworCSAgICAiVG86IGJvYkBleGFtcGxlLmNvbVxyXG4iICsKKwkgICAgIlN1YmplY3Q6IE11bHRpcGFydCBFeGFtcGxlXHJcbiIgKworCSAgICAiQ29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5PVwieHh4XCJcclxuIiArCisJICAgICJcclxuIjsKKyAgICBwcml2YXRlIFN0cmluZyBtc2cyID0gdG9wMiArCisJICAgICJwcmVhbWJsZVxyXG4iICsKKwkgICAgIi0teHh4XHJcbiIgKworCSAgICAiXHJcbiIgKworCSAgICAiZmlyc3QgcGFydFxyXG4iICsKKwkgICAgIlxyXG4iICsKKwkgICAgIi0teHh4XHJcbiIgKworCSAgICAiXHJcbiIgKworCSAgICAic2Vjb25kIHBhcnRcclxuIiArCisJICAgICJcclxuIiArCisJICAgICItLXh4eC0tXHJcbiI7CisKKyAgICAvKioKKyAgICAgKiBTZW5kIGdyZWV0aW5ncy4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB1bmFibGUgdG8gd3JpdGUgdG8gc29ja2V0CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2VuZEdyZWV0aW5ncygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMucHJpbnRsbigiK09LIFBPUDMgQ1VTVE9NIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2VuZCBTdHJpbmcgdG8gc29ja2V0LgorICAgICAqCisgICAgICogQHBhcmFtIHN0cgorICAgICAqICAgICAgICAgICAgU3RyaW5nIHRvIHNlbmQKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgdW5hYmxlIHRvIHdyaXRlIHRvIHNvY2tldAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHByaW50bG4oZmluYWwgU3RyaW5nIHN0cikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcy53cml0ZXIucHJpbnQoc3RyKTsKKwl0aGlzLndyaXRlci5wcmludCgiXHJcbiIpOworICAgICAgICB0aGlzLndyaXRlci5mbHVzaCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEhhbmRsZSBjb21tYW5kLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIHVuYWJsZSB0byByZWFkL3dyaXRlIHRvIHNvY2tldAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGhhbmRsZUNvbW1hbmQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzLmN1cnJlbnRMaW5lID0gcmVhZExpbmUoKTsKKworICAgICAgICBpZiAodGhpcy5jdXJyZW50TGluZSA9PSBudWxsKSB7CisJICAgIC8vIHByb2JhYmx5IGp1c3QgRU9GIGJlY2F1c2UgdGhlIHNvY2tldCB3YXMgY2xvc2VkCisgICAgICAgICAgICAvL0xPR0dFUi5zZXZlcmUoIkN1cnJlbnQgbGluZSBpcyBudWxsISIpOworICAgICAgICAgICAgdGhpcy5leGl0KCk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBmaW5hbCBTdHJpbmdUb2tlbml6ZXIgc3QgPSBuZXcgU3RyaW5nVG9rZW5pemVyKHRoaXMuY3VycmVudExpbmUsICIgIik7CisgICAgICAgIGZpbmFsIFN0cmluZyBjb21tYW5kTmFtZSA9IHN0Lm5leHRUb2tlbigpLnRvVXBwZXJDYXNlKCk7CisgICAgICAgIGZpbmFsIFN0cmluZyBhcmcgPSBzdC5oYXNNb3JlVG9rZW5zKCkgPyBzdC5uZXh0VG9rZW4oKSA6IG51bGw7CisgICAgICAgIGlmIChjb21tYW5kTmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICBMT0dHRVIuc2V2ZXJlKCJDb21tYW5kIG5hbWUgaXMgZW1wdHkhIik7CisgICAgICAgICAgICB0aGlzLmV4aXQoKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChjb21tYW5kTmFtZS5lcXVhbHMoIlNUQVQiKSkgeworICAgICAgICAgICAgdGhpcy5zdGF0KCk7CisgICAgICAgIH0gZWxzZSBpZiAoY29tbWFuZE5hbWUuZXF1YWxzKCJMSVNUIikpIHsKKyAgICAgICAgICAgIHRoaXMubGlzdCgpOworICAgICAgICB9IGVsc2UgaWYgKGNvbW1hbmROYW1lLmVxdWFscygiUkVUUiIpKSB7CisgICAgICAgICAgICB0aGlzLnJldHIoYXJnKTsKKyAgICAgICAgfSBlbHNlIGlmIChjb21tYW5kTmFtZS5lcXVhbHMoIkRFTEUiKSkgeworICAgICAgICAgICAgdGhpcy5kZWxlKCk7CisgICAgICAgIH0gZWxzZSBpZiAoY29tbWFuZE5hbWUuZXF1YWxzKCJOT09QIikpIHsKKyAgICAgICAgICAgIHRoaXMubm9vcCgpOworICAgICAgICB9IGVsc2UgaWYgKGNvbW1hbmROYW1lLmVxdWFscygiUlNFVCIpKSB7CisgICAgICAgICAgICB0aGlzLnJzZXQoKTsKKyAgICAgICAgfSBlbHNlIGlmIChjb21tYW5kTmFtZS5lcXVhbHMoIlFVSVQiKSkgeworICAgICAgICAgICAgdGhpcy5xdWl0KCk7CisgICAgICAgIH0gZWxzZSBpZiAoY29tbWFuZE5hbWUuZXF1YWxzKCJUT1AiKSkgeworICAgICAgICAgICAgdGhpcy50b3AoYXJnKTsKKyAgICAgICAgfSBlbHNlIGlmIChjb21tYW5kTmFtZS5lcXVhbHMoIlVJREwiKSkgeworICAgICAgICAgICAgdGhpcy51aWRsKCk7CisgICAgICAgIH0gZWxzZSBpZiAoY29tbWFuZE5hbWUuZXF1YWxzKCJVU0VSIikpIHsKKyAgICAgICAgICAgIHRoaXMudXNlcigpOworICAgICAgICB9IGVsc2UgaWYgKGNvbW1hbmROYW1lLmVxdWFscygiUEFTUyIpKSB7CisgICAgICAgICAgICB0aGlzLnBhc3MoKTsKKyAgICAgICAgfSBlbHNlIGlmIChjb21tYW5kTmFtZS5lcXVhbHMoIkNBUEEiKSkgeworICAgICAgICAgICAgdGhpcy5wcmludGxuKCItRVJSIENBUEEgbm90IHN1cHBvcnRlZCIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgTE9HR0VSLmxvZyhMZXZlbC5TRVZFUkUsICJFUlJPUiBjb21tYW5kIHVua25vd246IHswfSIsIGNvbW1hbmROYW1lKTsKKyAgICAgICAgICAgIHRoaXMucHJpbnRsbigiLUVSUiB1bmtub3duIGNvbW1hbmQiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNUQVQgY29tbWFuZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB1bmFibGUgdG8gcmVhZC93cml0ZSB0byBzb2NrZXQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzdGF0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcy5wcmludGxuKCIrT0sgMiAiICsgKG1zZzEubGVuZ3RoKCkgKyBtc2cyLmxlbmd0aCgpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTElTVCBjb21tYW5kLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIHVuYWJsZSB0byByZWFkL3dyaXRlIHRvIHNvY2tldAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGxpc3QoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzLndyaXRlci5wcmludGxuKCIrT0siKTsKKyAgICAgICAgdGhpcy53cml0ZXIucHJpbnRsbigiMSAiICsgbXNnMS5sZW5ndGgoKSk7CisgICAgICAgIHRoaXMud3JpdGVyLnByaW50bG4oIjIgIiArIG1zZzIubGVuZ3RoKCkpOworICAgICAgICB0aGlzLnByaW50bG4oIi4iKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSRVRSIGNvbW1hbmQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgdW5hYmxlIHRvIHJlYWQvd3JpdGUgdG8gc29ja2V0CisgICAgICovCisgICAgcHVibGljIHZvaWQgcmV0cihTdHJpbmcgYXJnKSB0aHJvd3MgSU9FeGNlcHRpb24geworCVN0cmluZyBtc2c7CisJaWYgKGFyZy5lcXVhbHMoIjEiKSkKKwkgICAgbXNnID0gbXNnMTsKKwllbHNlCisJICAgIG1zZyA9IG1zZzI7CisgICAgICAgIHRoaXMucHJpbnRsbigiK09LICIgKyBtc2cubGVuZ3RoKCkgKyAiIG9jdGV0cyIpOworCXRoaXMud3JpdGVyLndyaXRlKG1zZyk7CisJdGhpcy5wcmludGxuKCIuIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogREVMRSBjb21tYW5kLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIHVuYWJsZSB0byByZWFkL3dyaXRlIHRvIHNvY2tldAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGRlbGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCXRoaXMucHJpbnRsbigiLUVSUiBERUxFIG5vdCBzdXBwb3J0ZWQiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBOT09QIGNvbW1hbmQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgdW5hYmxlIHRvIHJlYWQvd3JpdGUgdG8gc29ja2V0CisgICAgICovCisgICAgcHVibGljIHZvaWQgbm9vcCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMucHJpbnRsbigiK09LIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUlNFVCBjb21tYW5kLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIHVuYWJsZSB0byByZWFkL3dyaXRlIHRvIHNvY2tldAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJzZXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzLnByaW50bG4oIitPSyIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFFVSVQgY29tbWFuZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB1bmFibGUgdG8gcmVhZC93cml0ZSB0byBzb2NrZXQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBxdWl0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcy5wcmludGxuKCIrT0siKTsKKyAgICAgICAgdGhpcy5leGl0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVE9QIGNvbW1hbmQuCisgICAgICogWFhYIC0gaWdub3JlcyBudW1iZXIgb2YgbGluZXMgYXJndW1lbnQKKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB1bmFibGUgdG8gcmVhZC93cml0ZSB0byBzb2NrZXQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB0b3AoU3RyaW5nIGFyZykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlTdHJpbmcgdG9wOworCWlmIChhcmcuZXF1YWxzKCIxIikpCisJICAgIHRvcCA9IHRvcDE7CisJZWxzZQorCSAgICB0b3AgPSB0b3AyOworICAgICAgICB0aGlzLnByaW50bG4oIitPSyAiICsgdG9wLmxlbmd0aCgpICsgIiBvY3RldHMiKTsKKwl0aGlzLndyaXRlci53cml0ZSh0b3ApOworCXRoaXMucHJpbnRsbigiLiIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFVJREwgY29tbWFuZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB1bmFibGUgdG8gcmVhZC93cml0ZSB0byBzb2NrZXQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1aWRsKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcy53cml0ZXIucHJpbnRsbigiK09LIik7CisgICAgICAgIHRoaXMud3JpdGVyLnByaW50bG4oIjEgMSIpOworICAgICAgICB0aGlzLndyaXRlci5wcmludGxuKCIyIDIiKTsKKyAgICAgICAgdGhpcy5wcmludGxuKCIuIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogVVNFUiBjb21tYW5kLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIHVuYWJsZSB0byByZWFkL3dyaXRlIHRvIHNvY2tldAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVzZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzLnByaW50bG4oIitPSyIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBBU1MgY29tbWFuZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB1bmFibGUgdG8gcmVhZC93cml0ZSB0byBzb2NrZXQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwYXNzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcy5wcmludGxuKCIrT0siKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3BvcDMvUE9QM01lc3NhZ2VUZXN0LmphdmEgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3BvcDMvUE9QM01lc3NhZ2VUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmRjMzhiNwotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvcG9wMy9QT1AzTWVzc2FnZVRlc3QuamF2YQpAQCAtMCwwICsxLDEzMSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwOSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwucG9wMzsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7CisKK2ltcG9ydCBqYXZheC5tYWlsLkZvbGRlcjsKK2ltcG9ydCBqYXZheC5tYWlsLlNlc3Npb247CitpbXBvcnQgamF2YXgubWFpbC5TdG9yZTsKK2ltcG9ydCBqYXZheC5tYWlsLk1lc3NhZ2U7CitpbXBvcnQgamF2YXgubWFpbC5NdWx0aXBhcnQ7CitpbXBvcnQgamF2YXgubWFpbC5QYXJ0OworaW1wb3J0IGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uOworCitpbXBvcnQgY29tLnN1bi5tYWlsLnRlc3QuVGVzdFNlcnZlcjsKKworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5CZWZvcmVDbGFzczsKK2ltcG9ydCBvcmcuanVuaXQuQWZ0ZXJDbGFzczsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRGYWxzZTsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5mYWlsOworCisvKioKKyAqIFRlc3QgdGhhdCB3ZSBjYW4gcmVhZCBQT1AzIG1lc3NhZ2VzLgorICoKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBQT1AzTWVzc2FnZVRlc3QgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgVGVzdFNlcnZlciBzZXJ2ZXIgPSBudWxsOworICAgIHByaXZhdGUgc3RhdGljIFN0b3JlIHN0b3JlOworICAgIHByaXZhdGUgc3RhdGljIEZvbGRlciBmb2xkZXI7CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHN0YXJ0U2VydmVyKGJvb2xlYW4gY2FjaGVkKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaW5hbCBQT1AzSGFuZGxlciBoYW5kbGVyID0gbmV3IFBPUDNIYW5kbGVyKCk7CisgICAgICAgICAgICBzZXJ2ZXIgPSBuZXcgVGVzdFNlcnZlcihoYW5kbGVyKTsKKyAgICAgICAgICAgIHNlcnZlci5zdGFydCgpOworICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDEwMDApOworCisgICAgICAgICAgICBmaW5hbCBQcm9wZXJ0aWVzIHByb3BlcnRpZXMgPSBuZXcgUHJvcGVydGllcygpOworICAgICAgICAgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5wb3AzLmhvc3QiLCAibG9jYWxob3N0Iik7CisgICAgICAgICAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLnBvcDMucG9ydCIsICIiICsgc2VydmVyLmdldFBvcnQoKSk7CisJICAgIGlmIChjYWNoZWQpCisJCXByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwucG9wMy5maWxlY2FjaGUuZW5hYmxlIiwgInRydWUiKTsKKyAgICAgICAgICAgIGZpbmFsIFNlc3Npb24gc2Vzc2lvbiA9IFNlc3Npb24uZ2V0SW5zdGFuY2UocHJvcGVydGllcyk7CisgICAgICAgICAgICAvL3Nlc3Npb24uc2V0RGVidWcodHJ1ZSk7CisKKyAgICAgICAgICAgIHN0b3JlID0gc2Vzc2lvbi5nZXRTdG9yZSgicG9wMyIpOworCSAgICBzdG9yZS5jb25uZWN0KCJ0ZXN0IiwgInRlc3QiKTsKKwkgICAgZm9sZGVyID0gc3RvcmUuZ2V0Rm9sZGVyKCJJTkJPWCIpOworCSAgICBmb2xkZXIub3BlbihGb2xkZXIuUkVBRF9PTkxZKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICBmYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgc3RvcFNlcnZlcigpIHsKKwl0cnkgeworCSAgICBpZiAoZm9sZGVyICE9IG51bGwpCisJCWZvbGRlci5jbG9zZShmYWxzZSk7CisJICAgIGlmIChzdG9yZSAhPSBudWxsKQorCQlzdG9yZS5jbG9zZSgpOworCX0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBleCkgeworCSAgICAvLyBpZ25vcmUgaXQKKwl9IGZpbmFsbHkgeworCSAgICBpZiAoc2VydmVyICE9IG51bGwpCisJCXNlcnZlci5xdWl0KCk7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCB3ZSBjYW4gcmVhZCB0aGUgY29udGVudCBvZiBhIG1lc3NhZ2UgdHdpY2UuCisgICAgICogQSBidWcgY2F1c2VkIFBPUDNNZXNzYWdlIHRvIHJldHVybiB0aGUgc2FtZSBzdHJlYW0gdGhlCisgICAgICogc2Vjb25kIHRpbWUsIGluc3RlYWQgb2YgYSBuZXcgc3RyZWFtIHBvc2l0aW9uZWQgYXQgdGhlCisgICAgICogYmVnaW5uaW5nIG9mIHRoZSBkYXRhLiAgVGhpcyBjYXVzZWQgbXVsdGlwYXJ0IHBhcnNpbmcKKyAgICAgKiB0byBmYWlsLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFJlYWRUd2ljZSgpIHRocm93cyBFeGNlcHRpb24geworCXJlYWRUd2ljZShmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTm93IHRlc3QgaXQgdXNpbmcgdGhlIGZpbGUgY2FjaGUuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVhZFR3aWNlQ2FjaGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJcmVhZFR3aWNlKHRydWUpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZWFkVHdpY2UoYm9vbGVhbiBjYWNoZWQpIHRocm93cyBFeGNlcHRpb24geworCXN0YXJ0U2VydmVyKGNhY2hlZCk7CisJdHJ5IHsKKwkgICAgTWVzc2FnZVtdIG1zZ3MgPSBmb2xkZXIuZ2V0TWVzc2FnZXMoKTsKKwkgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisJCWxvYWRNYWlsKG1zZ3NbaV0pOworCQlsb2FkTWFpbChtc2dzW2ldKTsJCisJICAgIH0KKwl9IGZpbmFsbHkgeworCSAgICBzdG9wU2VydmVyKCk7CisJfQorCS8vIG5vIGV4Y2VwdGlvbiBpcyBzdWNjZXNzIQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBsb2FkTWFpbChQYXJ0IHApIHRocm93cyBFeGNlcHRpb24geworCU9iamVjdCBjb250ZW50ID0gcC5nZXRDb250ZW50KCk7CisJaWYgKGNvbnRlbnQgaW5zdGFuY2VvZiBNdWx0aXBhcnQpIHsKKwkgICAgTXVsdGlwYXJ0IG1wID0gKE11bHRpcGFydCljb250ZW50OworCSAgICBpbnQgY250ID0gbXAuZ2V0Q291bnQoKTsKKwkgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjbnQ7IGkrKykKKwkJbG9hZE1haWwobXAuZ2V0Qm9keVBhcnQoaSkpOworCX0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3BvcDMvUE9QM1JlYWRhYmxlTWltZVRlc3QuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvcG9wMy9QT1AzUmVhZGFibGVNaW1lVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFkNmRkNzEKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3BvcDMvUE9QM1JlYWRhYmxlTWltZVRlc3QuamF2YQpAQCAtMCwwICsxLDEzOSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwOSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwucG9wMzsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKKworaW1wb3J0IGphdmF4Lm1haWwuRm9sZGVyOworaW1wb3J0IGphdmF4Lm1haWwuU2Vzc2lvbjsKK2ltcG9ydCBqYXZheC5tYWlsLlN0b3JlOworaW1wb3J0IGphdmF4Lm1haWwuTWVzc2FnZTsKK2ltcG9ydCBqYXZheC5tYWlsLlBhcnQ7CitpbXBvcnQgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb247CisKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5SZWFkYWJsZU1pbWU7CitpbXBvcnQgY29tLnN1bi5tYWlsLnRlc3QuVGVzdFNlcnZlcjsKKworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5CZWZvcmVDbGFzczsKK2ltcG9ydCBvcmcuanVuaXQuQWZ0ZXJDbGFzczsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUcnVlOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmZhaWw7CisKKy8qKgorICogVGVzdCBSZWFkYWJsZU1pbWUgc3VwcG9ydCBmb3IgUE9QMy4KKyAqCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgUE9QM1JlYWRhYmxlTWltZVRlc3QgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgVGVzdFNlcnZlciBzZXJ2ZXIgPSBudWxsOworICAgIHByaXZhdGUgc3RhdGljIFN0b3JlIHN0b3JlOworICAgIHByaXZhdGUgc3RhdGljIEZvbGRlciBmb2xkZXI7CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHN0YXJ0U2VydmVyKGJvb2xlYW4gY2FjaGVkKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaW5hbCBQT1AzSGFuZGxlciBoYW5kbGVyID0gbmV3IFBPUDNIYW5kbGVyKCk7CisgICAgICAgICAgICBzZXJ2ZXIgPSBuZXcgVGVzdFNlcnZlcihoYW5kbGVyKTsKKyAgICAgICAgICAgIHNlcnZlci5zdGFydCgpOworICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDEwMDApOworCisgICAgICAgICAgICBmaW5hbCBQcm9wZXJ0aWVzIHByb3BlcnRpZXMgPSBuZXcgUHJvcGVydGllcygpOworICAgICAgICAgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5wb3AzLmhvc3QiLCAibG9jYWxob3N0Iik7CisgICAgICAgICAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLnBvcDMucG9ydCIsICIiICsgc2VydmVyLmdldFBvcnQoKSk7CisJICAgIGlmIChjYWNoZWQpCisJCXByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwucG9wMy5maWxlY2FjaGUuZW5hYmxlIiwgInRydWUiKTsKKyAgICAgICAgICAgIGZpbmFsIFNlc3Npb24gc2Vzc2lvbiA9IFNlc3Npb24uZ2V0SW5zdGFuY2UocHJvcGVydGllcyk7CisgICAgICAgICAgICAvL3Nlc3Npb24uc2V0RGVidWcodHJ1ZSk7CisKKyAgICAgICAgICAgIHN0b3JlID0gc2Vzc2lvbi5nZXRTdG9yZSgicG9wMyIpOworCSAgICBzdG9yZS5jb25uZWN0KCJ0ZXN0IiwgInRlc3QiKTsKKwkgICAgZm9sZGVyID0gc3RvcmUuZ2V0Rm9sZGVyKCJJTkJPWCIpOworCSAgICBmb2xkZXIub3BlbihGb2xkZXIuUkVBRF9PTkxZKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICBmYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgc3RvcFNlcnZlcigpIHsKKwl0cnkgeworCSAgICBpZiAoZm9sZGVyICE9IG51bGwpCisJCWZvbGRlci5jbG9zZShmYWxzZSk7CisJICAgIGlmIChzdG9yZSAhPSBudWxsKQorCQlzdG9yZS5jbG9zZSgpOworCX0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBleCkgeworCSAgICAvLyBpZ25vcmUgaXQKKwl9IGZpbmFsbHkgeworCSAgICBpZiAoc2VydmVyICE9IG51bGwpCisJCXNlcnZlci5xdWl0KCk7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCB0aGUgZGF0YSByZXR1cm5lZCBieSB0aGUgZ2V0TWltZVN0cmVhbSBtZXRob2QKKyAgICAgKiBpcyBleGFjdGx5IHRoZSBzYW1lIGRhdGEgYXMgcHJvZHVjZWQgYnkgdGhlIHdyaXRlVG8gbWV0aG9kLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFJlYWRhYmxlTWltZSgpIHRocm93cyBFeGNlcHRpb24geworCXRlc3QoZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIE5vdyB0ZXN0IGl0IHVzaW5nIHRoZSBmaWxlIGNhY2hlLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFJlYWRhYmxlTWltZUNhY2hlZCgpIHRocm93cyBFeGNlcHRpb24geworCXRlc3QodHJ1ZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3QoYm9vbGVhbiBjYWNoZWQpIHRocm93cyBFeGNlcHRpb24geworCXN0YXJ0U2VydmVyKGNhY2hlZCk7CisJdHJ5IHsKKwkgICAgTWVzc2FnZVtdIG1zZ3MgPSBmb2xkZXIuZ2V0TWVzc2FnZXMoKTsKKwkgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKQorCQl2ZXJpZnlEYXRhKG1zZ3NbaV0pOworCX0gZmluYWxseSB7CisJICAgIHN0b3BTZXJ2ZXIoKTsKKwl9CisJLy8gbm8gZXhjZXB0aW9uIGlzIHN1Y2Nlc3MhCisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHZlcmlmeURhdGEoUGFydCBwKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisJYXNzZXJ0VHJ1ZSgiUmVhZGFibGVNaW1lIiwgcCBpbnN0YW5jZW9mIFJlYWRhYmxlTWltZSk7CisJSW5wdXRTdHJlYW0gaXMgPSBudWxsOworCXRyeSB7CisJICAgIFJlYWRhYmxlTWltZSBycCA9IChSZWFkYWJsZU1pbWUpcDsKKwkgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKwkgICAgcC53cml0ZVRvKGJvcyk7CisJICAgIGJvcy5jbG9zZSgpOworCSAgICBieXRlW10gYnVmID0gYm9zLnRvQnl0ZUFycmF5KCk7CisJICAgIGlzID0gcnAuZ2V0TWltZVN0cmVhbSgpOworCSAgICBpbnQgaSwgYjsKKwkgICAgZm9yIChpID0gMDsgKGIgPSBpcy5yZWFkKCkpICE9IC0xOyBpKyspCisJCWFzc2VydFRydWUoIm1lc3NhZ2UgZGF0YSIsIGIgPT0gKGJ1ZltpXSAmIDB4ZmYpKTsKKwkgICAgYXNzZXJ0VHJ1ZSgiZGF0YSBzaXplIiwgaSA9PSBidWYubGVuZ3RoKTsKKwl9IGZpbmFsbHkgeworCSAgICB0cnkgeworCQlpcy5jbG9zZSgpOworCSAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeyB9CisJfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvcG9wMy9QT1AzU3RvcmVUZXN0LmphdmEgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3BvcDMvUE9QM1N0b3JlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI0ZDEwODIKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3BvcDMvUE9QM1N0b3JlVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTQ1IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDA5LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5wb3AzOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKKworaW1wb3J0IGphdmF4Lm1haWwuRm9sZGVyOworaW1wb3J0IGphdmF4Lm1haWwuU2Vzc2lvbjsKK2ltcG9ydCBqYXZheC5tYWlsLlN0b3JlOworCitpbXBvcnQgY29tLnN1bi5tYWlsLnRlc3QuVGVzdFNlcnZlcjsKKworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEZhbHNlOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmZhaWw7CisKKy8qKgorICogVGVzdCBQT1AzU3RvcmUuCisgKgorICogQGF1dGhvciBzYm8KKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBQT1AzU3RvcmVUZXN0IHsKKworICAgIC8qKgorICAgICAqIENoZWNrIGlzIGNvbm5lY3RlZC4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RJc0Nvbm5lY3RlZCgpIHsKKyAgICAgICAgVGVzdFNlcnZlciBzZXJ2ZXIgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmluYWwgUE9QM0hhbmRsZXIgaGFuZGxlciA9IG5ldyBQT1AzSGFuZGxlck5vb3BFcnIoKTsKKyAgICAgICAgICAgIHNlcnZlciA9IG5ldyBUZXN0U2VydmVyKGhhbmRsZXIpOworICAgICAgICAgICAgc2VydmVyLnN0YXJ0KCk7CisKKyAgICAgICAgICAgIGZpbmFsIFByb3BlcnRpZXMgcHJvcGVydGllcyA9IG5ldyBQcm9wZXJ0aWVzKCk7CisgICAgICAgICAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLnBvcDMuaG9zdCIsICJsb2NhbGhvc3QiKTsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwucG9wMy5wb3J0IiwgIiIgKyBzZXJ2ZXIuZ2V0UG9ydCgpKTsKKyAgICAgICAgICAgIGZpbmFsIFNlc3Npb24gc2Vzc2lvbiA9IFNlc3Npb24uZ2V0SW5zdGFuY2UocHJvcGVydGllcyk7CisgICAgICAgICAgICAvL3Nlc3Npb24uc2V0RGVidWcodHJ1ZSk7CisKKyAgICAgICAgICAgIGZpbmFsIFN0b3JlIHN0b3JlID0gc2Vzc2lvbi5nZXRTdG9yZSgicG9wMyIpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdG9yZS5jb25uZWN0KCJ0ZXN0IiwgInRlc3QiKTsKKyAgICAgICAgICAgICAgICBmaW5hbCBGb2xkZXIgZm9sZGVyID0gc3RvcmUuZ2V0Rm9sZGVyKCJJTkJPWCIpOworICAgICAgICAgICAgICAgIGZvbGRlci5vcGVuKEZvbGRlci5SRUFEX09OTFkpOworCisgICAgICAgICAgICAgICAgLy8gQ2hlY2sKKyAgICAgICAgICAgICAgICBhc3NlcnRGYWxzZShmb2xkZXIuaXNPcGVuKCkpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBzdG9yZS5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChmaW5hbCBFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgIGZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKHNlcnZlciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgc2VydmVyLnF1aXQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrIHRoYXQgZW5hYmxpbmcgQVBPUCB3aXRoIGEgc2VydmVyIHRoYXQgZG9lc24ndCBzdXBwb3J0IEFQT1AKKyAgICAgKiAoYW5kIGRvZXNuJ3QgcmV0dXJuIGFueSBpbmZvcm1hdGlvbiBpbiB0aGUgZ3JlZXRpbmcpIGRvZXNuJ3QgZmFpbC4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RBcG9wTm90U3VwcG9ydGVkKCkgeworICAgICAgICBUZXN0U2VydmVyIHNlcnZlciA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaW5hbCBQT1AzSGFuZGxlciBoYW5kbGVyID0gbmV3IFBPUDNIYW5kbGVyTm9HcmVldGluZygpOworICAgICAgICAgICAgc2VydmVyID0gbmV3IFRlc3RTZXJ2ZXIoaGFuZGxlcik7CisgICAgICAgICAgICBzZXJ2ZXIuc3RhcnQoKTsKKworICAgICAgICAgICAgZmluYWwgUHJvcGVydGllcyBwcm9wZXJ0aWVzID0gbmV3IFByb3BlcnRpZXMoKTsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwucG9wMy5ob3N0IiwgImxvY2FsaG9zdCIpOworICAgICAgICAgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5wb3AzLnBvcnQiLCAiIiArIHNlcnZlci5nZXRQb3J0KCkpOworICAgICAgICAgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5wb3AzLmFwb3AuZW5hYmxlIiwgInRydWUiKTsKKyAgICAgICAgICAgIGZpbmFsIFNlc3Npb24gc2Vzc2lvbiA9IFNlc3Npb24uZ2V0SW5zdGFuY2UocHJvcGVydGllcyk7CisgICAgICAgICAgICAvL3Nlc3Npb24uc2V0RGVidWcodHJ1ZSk7CisKKyAgICAgICAgICAgIGZpbmFsIFN0b3JlIHN0b3JlID0gc2Vzc2lvbi5nZXRTdG9yZSgicG9wMyIpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzdG9yZS5jb25uZWN0KCJ0ZXN0IiwgInRlc3QiKTsKKwkJLy8gc3VjY2VzcyEKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgc3RvcmUuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoZmluYWwgRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICBmYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChzZXJ2ZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHNlcnZlci5xdWl0KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDdXN0b20gaGFuZGxlci4gUmV0dXJucyBFUlIgZm9yIE5PT1AuCisgICAgICoKKyAgICAgKiBAYXV0aG9yIHNibworICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFBPUDNIYW5kbGVyTm9vcEVyciBleHRlbmRzIFBPUDNIYW5kbGVyIHsKKworICAgICAgICAvKioKKyAgICAgICAgICoge0Bpbmhlcml0RG9jfQorICAgICAgICAgKi8KKwlAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgbm9vcCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICB0aGlzLnByaW50bG4oIi1FUlIiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEN1c3RvbSBoYW5kbGVyLiAgRG9uJ3QgaW5jbHVkZSBhbnkgZXh0cmEgaW5mb3JtYXRpb24gaW4gdGhlIGdyZWV0aW5nLgorICAgICAqCisgICAgICogQGF1dGhvciBCaWxsIFNoYW5ub24KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBQT1AzSGFuZGxlck5vR3JlZXRpbmcgZXh0ZW5kcyBQT1AzSGFuZGxlciB7CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIHtAaW5oZXJpdERvY30KKyAgICAgICAgICovCisJQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIHNlbmRHcmVldGluZ3MoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgdGhpcy5wcmludGxuKCIrT0siKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvc210cC9Ob3BTZXJ2ZXIuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvc210cC9Ob3BTZXJ2ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMzNkZWNhCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9zbXRwL05vcFNlcnZlci5qYXZhCkBAIC0wLDAgKzEsMTAwIEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDA5LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5zbXRwOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEubmV0LlNlcnZlclNvY2tldDsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXQ7CisKKy8qKgorICogQSBzZXJ2ZXIgdGhhdCBkb2VzIG5vdGhpbmcsIGJ1dCBrZWVwcyB0cmFjayBvZgorICogd2hldGhlciB0aGUgY2xpZW50IHNvY2tldCB3YXMgY2xvc2VkLgorICoKKyAqIEluc3BpcmVkIGJ5LCBhbmQgZGVyaXZlZCBmcm9tLCBQT1AzU2VydmVyIGJ5IHNiby4KKyAqCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgTm9wU2VydmVyIGV4dGVuZHMgVGhyZWFkIHsKKworICAgIC8qKiBTZXJ2ZXIgc29ja2V0LiAqLworICAgIHByaXZhdGUgU2VydmVyU29ja2V0IHNlcnZlclNvY2tldDsKKworICAgIC8qKiBLZWVwIG9uPyAqLworICAgIHByaXZhdGUgdm9sYXRpbGUgYm9vbGVhbiBrZWVwT247CisKKyAgICAvKiogRGlkIHdlIGdldCBFT0Ygb24gdGhlIGNsaWVudCBzb2NrZXQ/ICovCisgICAgcHJpdmF0ZSB2b2xhdGlsZSBib29sZWFuIGdvdEVPRiA9IGZhbHNlOworCisgICAgLyoqCisgICAgICogTm9wIHNlcnZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgTm9wU2VydmVyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlzZXJ2ZXJTb2NrZXQgPSBuZXcgU2VydmVyU29ja2V0KDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgcG9ydCB0aGUgc2VydmVyIGlzIGxpc3RlbmluZyBvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFBvcnQoKSB7CisJcmV0dXJuIHNlcnZlclNvY2tldC5nZXRMb2NhbFBvcnQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFeGl0IE5vcCBzZXJ2ZXIuCisgICAgICovCisgICAgcHVibGljIHZvaWQgcXVpdCgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtlZXBPbiA9IGZhbHNlOworICAgICAgICAgICAgaWYgKHNlcnZlclNvY2tldCAhPSBudWxsICYmICFzZXJ2ZXJTb2NrZXQuaXNDbG9zZWQoKSkgeworICAgICAgICAgICAgICAgIHNlcnZlclNvY2tldC5jbG9zZSgpOworICAgICAgICAgICAgICAgIHNlcnZlclNvY2tldCA9IG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZW9mKCkgeworCXJldHVybiBnb3RFT0Y7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAga2VlcE9uID0gdHJ1ZTsKKworICAgICAgICAgICAgd2hpbGUgKGtlZXBPbikgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIFNvY2tldCBjbGllbnRTb2NrZXQgPSBzZXJ2ZXJTb2NrZXQuYWNjZXB0KCk7CisJCSAgICAvKgorCQkgICAgICogRG8gbm90aGluZyBidXQgY29uc3VtZSBhbnkgaW5wdXQgYW5kIHRocm93IGl0IGF3YXkuCisJCSAgICAgKiBXaGVuIHdlIHNlZSBFT0YsIHJlbWVtYmVyIGl0LgorCQkgICAgICovCisJCSAgICBJbnB1dFN0cmVhbSBpcyA9IGNsaWVudFNvY2tldC5nZXRJbnB1dFN0cmVhbSgpOworCQkgICAgd2hpbGUgKGlzLnJlYWQoKSA+PSAwKQorCQkJOworCQkgICAgZ290RU9GID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIC8vZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBxdWl0KCk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3NtdHAvU01UUEF1dGhEZWJ1Z1Rlc3QuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvc210cC9TTVRQQXV0aERlYnVnVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYwMzQwYWYKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3NtdHAvU01UUEF1dGhEZWJ1Z1Rlc3QuamF2YQpAQCAtMCwwICsxLDEzMyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwOSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuc210cDsKKworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKKworaW1wb3J0IGphdmF4Lm1haWwuU2Vzc2lvbjsKK2ltcG9ydCBqYXZheC5tYWlsLlRyYW5zcG9ydDsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC50ZXN0LlRlc3RTZXJ2ZXI7CisKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQuUnVsZTsKK2ltcG9ydCBvcmcuanVuaXQucnVsZXMuVGltZW91dDsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUcnVlOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEZhbHNlOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmZhaWw7CisKKy8qKgorICogVGVzdCB0aGF0IGF1dGhlbnRpY2F0aW9uIGluZm9ybWF0aW9uIGlzIG9ubHkgaW5jbHVkZWQgaW4KKyAqIHRoZSBkZWJ1ZyBvdXRwdXQgd2hlbiBleHBsaWNpdGx5IHJlcXVlc3RlZCBieSBzZXR0aW5nIHRoZQorICogcHJvcGVydHkgIm1haWwuZGVidWcuYXV0aCIgdG8gInRydWUiLgorICoKKyAqIFhYWCAtIHNob3VsZCB0ZXN0IGFsbCBhdXRoZW50aWNhdGlvbiB0eXBlcywgYnV0IHRoYXQgcmVxdWlyZXMKKyAqCSBtb3JlIHdvcmsgaW4gdGhlIGR1bW15IHRlc3Qgc2VydmVyLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgU01UUEF1dGhEZWJ1Z1Rlc3QgeworCisgICAgLy8gdGltZW91dCB0aGUgdGVzdCBpbiBjYXNlIG9mIGRlYWRsb2NrCisgICAgQFJ1bGUKKyAgICBwdWJsaWMgVGltZW91dCBkZWFkbG9ja1RpbWVvdXQgPSBUaW1lb3V0LnNlY29uZHMoMjApOworCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IGF1dGhlbnRpY2F0aW9uIGluZm9ybWF0aW9uIGlzbid0IGluY2x1ZGVkIGluIHRoZSBkZWJ1ZyBvdXRwdXQuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Tm9BdXRoRGVmYXVsdCgpIHsKKwlmaW5hbCBQcm9wZXJ0aWVzIHByb3BlcnRpZXMgPSBuZXcgUHJvcGVydGllcygpOworCWFzc2VydEZhbHNlKCJBVVRIIGluIGRlYnVnIG91dHB1dCIsIHRlc3QocHJvcGVydGllcywgIkFVVEgiKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Tm9BdXRoKCkgeworCWZpbmFsIFByb3BlcnRpZXMgcHJvcGVydGllcyA9IG5ldyBQcm9wZXJ0aWVzKCk7CisJcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5kZWJ1Zy5hdXRoIiwgImZhbHNlIik7CisJYXNzZXJ0RmFsc2UoIkFVVEggaW4gZGVidWcgb3V0cHV0IiwgdGVzdChwcm9wZXJ0aWVzLCAiQVVUSCIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHRoYXQgYXV0aGVudGljYXRpb24gaW5mb3JtYXRpb24gKmlzKiBpbmNsdWRlZCBpbiB0aGUgZGVidWcgb3V0cHV0LgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEF1dGgoKSB7CisJZmluYWwgUHJvcGVydGllcyBwcm9wZXJ0aWVzID0gbmV3IFByb3BlcnRpZXMoKTsKKwlwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLmRlYnVnLmF1dGgiLCAidHJ1ZSIpOworCWFzc2VydFRydWUoIkFVVEggaW4gZGVidWcgb3V0cHV0IiwgdGVzdChwcm9wZXJ0aWVzLCAiQVVUSCIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSB0ZXN0IHNlcnZlciwgY29ubmVjdCB0byBpdCwgYW5kIGNvbGxlY3QgdGhlIGRlYnVnIG91dHB1dC4KKyAgICAgKiBTY2FuIHRoZSBkZWJ1ZyBvdXRwdXQgbG9va2luZyBmb3IgImV4cGVjdCIsIHJldHVybiB0cnVlIGlmIGZvdW5kLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHRlc3QoUHJvcGVydGllcyBwcm9wZXJ0aWVzLCBTdHJpbmcgZXhwZWN0KSB7CisJVGVzdFNlcnZlciBzZXJ2ZXIgPSBudWxsOworCXRyeSB7CisJICAgIGZpbmFsIFNNVFBIYW5kbGVyIGhhbmRsZXIgPSBuZXcgU01UUEhhbmRsZXIoKTsKKwkgICAgc2VydmVyID0gbmV3IFRlc3RTZXJ2ZXIoaGFuZGxlcik7CisJICAgIHNlcnZlci5zdGFydCgpOworCSAgICBUaHJlYWQuc2xlZXAoMTAwMCk7CisKKwkgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5zbXRwLmhvc3QiLCAibG9jYWxob3N0Iik7CisJICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuc210cC5wb3J0IiwgIiIgKyBzZXJ2ZXIuZ2V0UG9ydCgpKTsKKwkgICAgZmluYWwgU2Vzc2lvbiBzZXNzaW9uID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShwcm9wZXJ0aWVzKTsKKwkgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKwkgICAgUHJpbnRTdHJlYW0gcHMgPSBuZXcgUHJpbnRTdHJlYW0oYm9zKTsKKwkgICAgc2Vzc2lvbi5zZXREZWJ1Z091dChwcyk7CisJICAgIHNlc3Npb24uc2V0RGVidWcodHJ1ZSk7CisKKwkgICAgZmluYWwgVHJhbnNwb3J0IHQgPSBzZXNzaW9uLmdldFRyYW5zcG9ydCgic210cCIpOworCSAgICB0cnkgeworCQl0LmNvbm5lY3QoInRlc3QiLCAidGVzdCIpOworCSAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKwkJU3lzdGVtLm91dC5wcmludGxuKGV4KTsKKwkJLy9leC5wcmludFN0YWNrVHJhY2UoKTsKKwkJZmFpbChleC50b1N0cmluZygpKTsKKwkgICAgfSBmaW5hbGx5IHsKKwkJdC5jbG9zZSgpOworCSAgICB9CisKKwkgICAgcHMuY2xvc2UoKTsKKwkgICAgYm9zLmNsb3NlKCk7CisJICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGJpcyA9CisJCW5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShib3MudG9CeXRlQXJyYXkoKSk7CisJICAgIEJ1ZmZlcmVkUmVhZGVyIHIgPSBuZXcgQnVmZmVyZWRSZWFkZXIoCisJCQkJCW5ldyBJbnB1dFN0cmVhbVJlYWRlcihiaXMsICJ1cy1hc2NpaSIpKTsKKwkgICAgU3RyaW5nIGxpbmU7CisJICAgIGJvb2xlYW4gZm91bmQgPSBmYWxzZTsKKwkgICAgd2hpbGUgKChsaW5lID0gci5yZWFkTGluZSgpKSAhPSBudWxsKSB7CisJCWlmIChsaW5lLnN0YXJ0c1dpdGgoIkRFQlVHIikpCisJCSAgICBjb250aW51ZTsKKwkJaWYgKGxpbmUuc3RhcnRzV2l0aCgiKiIpKQorCQkgICAgY29udGludWU7CisJCWlmIChsaW5lLnN0YXJ0c1dpdGgoZXhwZWN0KSkKKwkJICAgIGZvdW5kID0gdHJ1ZTsKKwkgICAgfQorCSAgICByLmNsb3NlKCk7CisJICAgIHJldHVybiBmb3VuZDsKKwl9IGNhdGNoIChmaW5hbCBFeGNlcHRpb24gZSkgeworCSAgICBlLnByaW50U3RhY2tUcmFjZSgpOworCSAgICBmYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKwkgICAgcmV0dXJuIGZhbHNlOwkvLyBYWFggLSBkb2Vzbid0IG1hdHRlcgorCX0gZmluYWxseSB7CisJICAgIGlmIChzZXJ2ZXIgIT0gbnVsbCkgeworCQlzZXJ2ZXIucXVpdCgpOworCSAgICB9CisJfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvc210cC9TTVRQQmRhdFRlc3QuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvc210cC9TTVRQQmRhdFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42NGZiM2YwCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9zbXRwL1NNVFBCZGF0VGVzdC5qYXZhCkBAIC0wLDAgKzEsMTUxIEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDA5LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5zbXRwOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKKworaW1wb3J0IGphdmF4Lm1haWwuU2Vzc2lvbjsKK2ltcG9ydCBqYXZheC5tYWlsLlRyYW5zcG9ydDsKK2ltcG9ydCBqYXZheC5tYWlsLk1lc3NhZ2U7CitpbXBvcnQgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC5NaW1lTWVzc2FnZTsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC50ZXN0LlRlc3RTZXJ2ZXI7CisKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQuUnVsZTsKK2ltcG9ydCBvcmcuanVuaXQucnVsZXMuVGltZW91dDsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUcnVlOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEFycmF5RXF1YWxzOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmZhaWw7CisKKy8qKgorICogVGVzdCB0aGUgQkRBVCBjb21tYW5kLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgU01UUEJkYXRUZXN0IHsKKworICAgIHByaXZhdGUgYnl0ZVtdIG1lc3NhZ2U7CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RCZGF0U3VjY2VzcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBUZXN0U2VydmVyIHNlcnZlciA9IG51bGw7CisgICAgICAgIHRyeSB7CisJICAgIFNNVFBIYW5kbGVyIGhhbmRsZXIgPSBuZXcgU01UUEhhbmRsZXIoKSB7CisJCXt7IGV4dGVuc2lvbnMuYWRkKCJDSFVOS0lORyIpOyB9fQorCisJCUBPdmVycmlkZQorCQlwdWJsaWMgdm9pZCBzZXRNZXNzYWdlKGJ5dGVbXSBtc2cpIHsKKwkJICAgIG1lc3NhZ2UgPSBtc2c7CisJCX0KKwkgICAgfTsKKyAgICAgICAgICAgIHNlcnZlciA9IG5ldyBUZXN0U2VydmVyKGhhbmRsZXIpOworICAgICAgICAgICAgc2VydmVyLnN0YXJ0KCk7CisKKyAgICAgICAgICAgIGZpbmFsIFByb3BlcnRpZXMgcHJvcGVydGllcyA9IG5ldyBQcm9wZXJ0aWVzKCk7CisgICAgICAgICAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLnNtdHAuaG9zdCIsICJsb2NhbGhvc3QiKTsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuc210cC5wb3J0IiwgIiIgKyBzZXJ2ZXIuZ2V0UG9ydCgpKTsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuc210cC5jaHVua3NpemUiLCAiMTI4Iik7CisgICAgICAgICAgICBmaW5hbCBTZXNzaW9uIHNlc3Npb24gPSBTZXNzaW9uLmdldEluc3RhbmNlKHByb3BlcnRpZXMpOworICAgICAgICAgICAgLy9zZXNzaW9uLnNldERlYnVnKHRydWUpOworCisgICAgICAgICAgICBmaW5hbCBUcmFuc3BvcnQgdCA9IHNlc3Npb24uZ2V0VHJhbnNwb3J0KCJzbXRwIik7CisgICAgICAgICAgICB0cnkgeworCQlNaW1lTWVzc2FnZSBtc2cgPSBuZXcgTWltZU1lc3NhZ2Uoc2Vzc2lvbik7CisJCW1zZy5zZXRSZWNpcGllbnRzKE1lc3NhZ2UuUmVjaXBpZW50VHlwZS5UTywgImpvZUBleGFtcGxlLmNvbSIpOworCQltc2cuc2V0U3ViamVjdCgidGVzdCIpOworCQltc2cuc2V0VGV4dCgidGVzdFxyXG4iKTsKKyAgICAgICAgICAgICAgICB0LmNvbm5lY3QoKTsKKwkJdC5zZW5kTWVzc2FnZShtc2csIG1zZy5nZXRBbGxSZWNpcGllbnRzKCkpOworCQlCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworCQltc2cud3JpdGVUbyhib3MpOworCQlib3MuY2xvc2UoKTsKKwkJYnl0ZVtdIG9yaWcgPSBib3MudG9CeXRlQXJyYXkoKTsKKwkJYXNzZXJ0QXJyYXlFcXVhbHMob3JpZywgbWVzc2FnZSk7CisJICAgIH0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBleCkgeworCQlmYWlsKGV4LmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHQuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoZmluYWwgRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICBmYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChzZXJ2ZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHNlcnZlci5xdWl0KCk7CisJCXNlcnZlci5pbnRlcnJ1cHQoKTsKKwkJLy8gd2FpdCBmb3IgaGFuZGxlciB0byBleGl0CisJCXNlcnZlci5qb2luKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RCZGF0RmFpbHVyZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBUZXN0U2VydmVyIHNlcnZlciA9IG51bGw7CisgICAgICAgIHRyeSB7CisJICAgIFNNVFBIYW5kbGVyIGhhbmRsZXIgPSBuZXcgU01UUEhhbmRsZXIoKSB7CisJCXt7IGV4dGVuc2lvbnMuYWRkKCJDSFVOS0lORyIpOyB9fQorCisJCUBPdmVycmlkZQorCQlwdWJsaWMgdm9pZCBiZGF0KFN0cmluZyBsaW5lKSB0aHJvd3MgSU9FeGNlcHRpb24geworCQkgICAgU3RyaW5nW10gdG9rID0gbGluZS5zcGxpdCgiXFxzKyIpOworCQkgICAgaW50IGJ5dGVzID0gSW50ZWdlci5wYXJzZUludCh0b2tbMV0pOworCQkgICAgYm9vbGVhbiBsYXN0ID0gdG9rLmxlbmd0aCA+IDIgJiYKKwkJCQkgICAgdG9rWzJdLmVxdWFsc0lnbm9yZUNhc2UoIkxBU1QiKTsKKwkJICAgIHJlYWRCZGF0TWVzc2FnZShieXRlcywgbGFzdCk7CisJCSAgICBwcmludGxuKCI0NDQgZmFpbGVkIik7CisJCX0KKwkgICAgfTsKKyAgICAgICAgICAgIHNlcnZlciA9IG5ldyBUZXN0U2VydmVyKGhhbmRsZXIpOworICAgICAgICAgICAgc2VydmVyLnN0YXJ0KCk7CisKKyAgICAgICAgICAgIGZpbmFsIFByb3BlcnRpZXMgcHJvcGVydGllcyA9IG5ldyBQcm9wZXJ0aWVzKCk7CisgICAgICAgICAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLnNtdHAuaG9zdCIsICJsb2NhbGhvc3QiKTsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuc210cC5wb3J0IiwgIiIgKyBzZXJ2ZXIuZ2V0UG9ydCgpKTsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuc210cC5jaHVua3NpemUiLCAiMTI4Iik7CisgICAgICAgICAgICBmaW5hbCBTZXNzaW9uIHNlc3Npb24gPSBTZXNzaW9uLmdldEluc3RhbmNlKHByb3BlcnRpZXMpOworICAgICAgICAgICAgLy9zZXNzaW9uLnNldERlYnVnKHRydWUpOworCisgICAgICAgICAgICBmaW5hbCBUcmFuc3BvcnQgdCA9IHNlc3Npb24uZ2V0VHJhbnNwb3J0KCJzbXRwIik7CisgICAgICAgICAgICB0cnkgeworCQlNaW1lTWVzc2FnZSBtc2cgPSBuZXcgTWltZU1lc3NhZ2Uoc2Vzc2lvbik7CisJCW1zZy5zZXRSZWNpcGllbnRzKE1lc3NhZ2UuUmVjaXBpZW50VHlwZS5UTywgImpvZUBleGFtcGxlLmNvbSIpOworCQltc2cuc2V0U3ViamVjdCgidGVzdCIpOworCQltc2cuc2V0VGV4dCgidGVzdFxyXG4iKTsKKyAgICAgICAgICAgICAgICB0LmNvbm5lY3QoKTsKKwkJdC5zZW5kTWVzc2FnZShtc2csIG1zZy5nZXRBbGxSZWNpcGllbnRzKCkpOworCQlmYWlsKCJubyBleGNlcHRpb24iKTsKKwkgICAgfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIGV4KSB7CisJCS8vIGV4cGVjdCBpdCB0byBmYWlsCisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHQuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoZmluYWwgRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICBmYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChzZXJ2ZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHNlcnZlci5xdWl0KCk7CisJCXNlcnZlci5pbnRlcnJ1cHQoKTsKKwkJLy8gd2FpdCBmb3IgaGFuZGxlciB0byBleGl0CisJCXNlcnZlci5qb2luKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3NtdHAvU01UUENsb3NlVGVzdC5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9zbXRwL1NNVFBDbG9zZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZDI2Y2I4Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9zbXRwL1NNVFBDbG9zZVRlc3QuamF2YQpAQCAtMCwwICsxLDc3IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDA5LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5zbXRwOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKKworaW1wb3J0IGphdmF4Lm1haWwuU2Vzc2lvbjsKK2ltcG9ydCBqYXZheC5tYWlsLlRyYW5zcG9ydDsKKworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5SdWxlOworaW1wb3J0IG9yZy5qdW5pdC5ydWxlcy5UaW1lb3V0OworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydFRydWU7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuZmFpbDsKKworLyoqCisgKiBUZXN0IHRoYXQgdGhlIHNvY2tldCBpcyBjbG9zZWQgd2hlbiBjb25uZWN0IHRpbWVzIG91dC4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFNNVFBDbG9zZVRlc3QgeworCisgICAgLy8gdGltZW91dCB0aGUgdGVzdCBpbiBjYXNlIG9mIGZhaWx1cmUKKyAgICBAUnVsZQorICAgIHB1YmxpYyBUaW1lb3V0IGRlYWRsb2NrVGltZW91dCA9IFRpbWVvdXQuc2Vjb25kcyg1KTsKKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdCgpIHsKKyAgICAgICAgTm9wU2VydmVyIHNlcnZlciA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzZXJ2ZXIgPSBuZXcgTm9wU2VydmVyKCk7CisgICAgICAgICAgICBzZXJ2ZXIuc3RhcnQoKTsKKyAgICAgICAgICAgIFRocmVhZC5zbGVlcCgxMDAwKTsKKworICAgICAgICAgICAgZmluYWwgUHJvcGVydGllcyBwcm9wZXJ0aWVzID0gbmV3IFByb3BlcnRpZXMoKTsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuc210cC5ob3N0IiwgImxvY2FsaG9zdCIpOworICAgICAgICAgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5zbXRwLnBvcnQiLCAiIiArIHNlcnZlci5nZXRQb3J0KCkpOworICAgICAgICAgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5zbXRwLnRpbWVvdXQiLCAiMTAwIik7CisgICAgICAgICAgICBmaW5hbCBTZXNzaW9uIHNlc3Npb24gPSBTZXNzaW9uLmdldEluc3RhbmNlKHByb3BlcnRpZXMpOworICAgICAgICAgICAgLy9zZXNzaW9uLnNldERlYnVnKHRydWUpOworCisgICAgICAgICAgICBmaW5hbCBUcmFuc3BvcnQgdCA9IHNlc3Npb24uZ2V0VHJhbnNwb3J0KCJzbXRwIik7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHQuY29ubmVjdCgpOworCSAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKwkJLy8gZXhwZWN0IGFuIGV4Y2VwdGlvbiB3aGVuIGNvbm5lY3QgdGltZXMgb3V0CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHQuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKwkgICAgLy8gZ2l2ZSB0aGUgc2VydmVyIHRocmVhZCBhIGNoYW5jZSB0byBkZXRlY3QgdGhlIGNsb3NlCisJICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTAgJiYgIXNlcnZlci5lb2YoKTsgaSsrKQorCQlUaHJlYWQuc2xlZXAoMTAwKTsKKwkgICAgYXNzZXJ0VHJ1ZSgic29ja2V0IGNsb3NlZCIsIHNlcnZlci5lb2YoKSk7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoc2VydmVyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBzZXJ2ZXIucXVpdCgpOworCQlzZXJ2ZXIuaW50ZXJydXB0KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3NtdHAvU01UUENvbm5lY3RGYWlsdXJlVGVzdC5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9zbXRwL1NNVFBDb25uZWN0RmFpbHVyZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZjViN2QwCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9zbXRwL1NNVFBDb25uZWN0RmFpbHVyZVRlc3QuamF2YQpAQCAtMCwwICsxLDc2IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDA5LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5zbXRwOworCitpbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7CitpbXBvcnQgamF2YS5uZXQuU2VydmVyU29ja2V0OworCitpbXBvcnQgamF2YXgubWFpbC5TZXNzaW9uOworaW1wb3J0IGphdmF4Lm1haWwuVHJhbnNwb3J0OworCitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuTWFpbENvbm5lY3RFeGNlcHRpb247CisKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUcnVlOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEVxdWFsczsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5mYWlsOworCisvKioKKyAqIFRlc3QgY29ubmVjdCBmYWlsdXJlcy4KKyAqLworcHVibGljIGNsYXNzIFNNVFBDb25uZWN0RmFpbHVyZVRlc3QgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEhPU1QgPSAibG9jYWxob3N0IjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ1RPID0gMjA7CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3ROb1NlcnZlcigpIHsKKyAgICAgICAgdHJ5IHsKKwkgICAgLy8gdmVyaWZ5IHRoYXQgcG9ydCBpcyBub3QgYmVpbmcgdXNlZAorCSAgICBTZXJ2ZXJTb2NrZXQgc3MgPSBuZXcgU2VydmVyU29ja2V0KDApOworCSAgICBpbnQgcG9ydCA9IHNzLmdldExvY2FsUG9ydCgpOworCSAgICBzcy5jbG9zZSgpOworICAgICAgICAgICAgUHJvcGVydGllcyBwcm9wZXJ0aWVzID0gbmV3IFByb3BlcnRpZXMoKTsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuc210cC5ob3N0IiwgSE9TVCk7CisgICAgICAgICAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLnNtdHAucG9ydCIsICIiICsgcG9ydCk7CisgICAgICAgICAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLnNtdHAuY29ubmVjdGlvbnRpbWVvdXQiLCAiIiArIENUTyk7CisgICAgICAgICAgICBTZXNzaW9uIHNlc3Npb24gPSBTZXNzaW9uLmdldEluc3RhbmNlKHByb3BlcnRpZXMpOworICAgICAgICAgICAgLy9zZXNzaW9uLnNldERlYnVnKHRydWUpOworCisgICAgICAgICAgICBUcmFuc3BvcnQgdCA9IHNlc3Npb24uZ2V0VHJhbnNwb3J0KCJzbXRwIik7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHQuY29ubmVjdCgidGVzdCIsICJ0ZXN0Iik7CisJCWZhaWwoIkNvbm5lY3RlZCEiKTsKKwkJLy8gZmFpbHVyZSEKKwkgICAgfSBjYXRjaCAoTWFpbENvbm5lY3RFeGNlcHRpb24gbWNleCkgeworCQkvLyBzdWNjZXNzIQorCQlhc3NlcnRFcXVhbHMoSE9TVCwgbWNleC5nZXRIb3N0KCkpOworCQlhc3NlcnRFcXVhbHMocG9ydCwgbWNleC5nZXRQb3J0KCkpOworCQlhc3NlcnRFcXVhbHMoQ1RPLCBtY2V4LmdldENvbm5lY3Rpb25UaW1lb3V0KCkpOworCSAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKwkJLy8gZXhwZWN0IGFuIGV4Y2VwdGlvbiB3aGVuIGNvbm5lY3QgdGltZXMgb3V0CisJCWZhaWwoZXgudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworCQlpZiAodC5pc0Nvbm5lY3RlZCgpKQorCQkgICAgdC5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgIGZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9zbXRwL1NNVFBIYW5kbGVyLmphdmEgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3NtdHAvU01UUEhhbmRsZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zMjE3YjUwCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9zbXRwL1NNVFBIYW5kbGVyLmphdmEKQEAgLTAsMCArMSwyODkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDksIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLnNtdHA7CisKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YS51dGlsLlN0cmluZ1Rva2VuaXplcjsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkxvZ2dlcjsKK2ltcG9ydCBqYXZhLnV0aWwubG9nZ2luZy5MZXZlbDsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC50ZXN0LlByb3RvY29sSGFuZGxlcjsKKworLyoqCisgKiBIYW5kbGUgY29ubmVjdGlvbi4KKyAqCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCitwdWJsaWMgY2xhc3MgU01UUEhhbmRsZXIgZXh0ZW5kcyBQcm90b2NvbEhhbmRsZXIgeworCisgICAgLyoqIEN1cnJlbnQgbGluZS4gKi8KKyAgICBwcml2YXRlIFN0cmluZyBjdXJyZW50TGluZTsKKworICAgIC8qKiBBIG1lc3NhZ2UgYmVpbmcgYWNjdW11bGF0ZWQuICovCisgICAgcHJpdmF0ZSBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gbWVzc2FnZVN0cmVhbTsKKworICAgIC8qKiBTTVRQIGV4dGVuc2lvbnMgc3VwcG9ydGVkLiAqLworICAgIHByb3RlY3RlZCBTZXQ8U3RyaW5nPiBleHRlbnNpb25zID0gbmV3IEhhc2hTZXQ8U3RyaW5nPigpOworCisgICAgLyoqCisgICAgICogU2VuZCBncmVldGluZ3MuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgdW5hYmxlIHRvIHdyaXRlIHRvIHNvY2tldAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNlbmRHcmVldGluZ3MoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBwcmludGxuKCIyMjAgbG9jYWxob3N0IGR1bW15IHNlcnZlciByZWFkeSIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNlbmQgU3RyaW5nIHRvIHNvY2tldC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBzdHIKKyAgICAgKiAgICAgICAgICAgIFN0cmluZyB0byBzZW5kCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIHVuYWJsZSB0byB3cml0ZSB0byBzb2NrZXQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwcmludGxuKGZpbmFsIFN0cmluZyBzdHIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHdyaXRlci5wcmludChzdHIpOworCXdyaXRlci5wcmludCgiXHJcbiIpOworICAgICAgICB3cml0ZXIuZmx1c2goKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBIYW5kbGUgY29tbWFuZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB1bmFibGUgdG8gcmVhZC93cml0ZSB0byBzb2NrZXQKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBoYW5kbGVDb21tYW5kKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY3VycmVudExpbmUgPSByZWFkTGluZSgpOworCisgICAgICAgIGlmIChjdXJyZW50TGluZSA9PSBudWxsKQorICAgICAgICAgICAgcmV0dXJuOworCisgICAgICAgIGZpbmFsIFN0cmluZ1Rva2VuaXplciBzdCA9IG5ldyBTdHJpbmdUb2tlbml6ZXIoY3VycmVudExpbmUsICIgIik7CisgICAgICAgIGZpbmFsIFN0cmluZyBjb21tYW5kTmFtZSA9IHN0Lm5leHRUb2tlbigpLnRvVXBwZXJDYXNlKCk7CisgICAgICAgIGlmIChjb21tYW5kTmFtZSA9PSBudWxsKSB7CisgICAgICAgICAgICBMT0dHRVIuc2V2ZXJlKCJDb21tYW5kIG5hbWUgaXMgZW1wdHkhIik7CisgICAgICAgICAgICBleGl0KCk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBpZiAoY29tbWFuZE5hbWUuZXF1YWxzKCJIRUxPIikpIHsKKyAgICAgICAgICAgIGhlbG8oKTsKKyAgICAgICAgfSBlbHNlIGlmIChjb21tYW5kTmFtZS5lcXVhbHMoIkVITE8iKSkgeworICAgICAgICAgICAgZWhsbygpOworICAgICAgICB9IGVsc2UgaWYgKGNvbW1hbmROYW1lLmVxdWFscygiTUFJTCIpKSB7CisgICAgICAgICAgICBtYWlsKGN1cnJlbnRMaW5lKTsKKyAgICAgICAgfSBlbHNlIGlmIChjb21tYW5kTmFtZS5lcXVhbHMoIlJDUFQiKSkgeworICAgICAgICAgICAgcmNwdChjdXJyZW50TGluZSk7CisgICAgICAgIH0gZWxzZSBpZiAoY29tbWFuZE5hbWUuZXF1YWxzKCJEQVRBIikpIHsKKyAgICAgICAgICAgIGRhdGEoKTsKKyAgICAgICAgfSBlbHNlIGlmIChjb21tYW5kTmFtZS5lcXVhbHMoIkJEQVQiKSkgeworICAgICAgICAgICAgYmRhdChjdXJyZW50TGluZSk7CisgICAgICAgIH0gZWxzZSBpZiAoY29tbWFuZE5hbWUuZXF1YWxzKCJOT09QIikpIHsKKyAgICAgICAgICAgIG5vb3AoKTsKKyAgICAgICAgfSBlbHNlIGlmIChjb21tYW5kTmFtZS5lcXVhbHMoIlJTRVQiKSkgeworICAgICAgICAgICAgcnNldCgpOworICAgICAgICB9IGVsc2UgaWYgKGNvbW1hbmROYW1lLmVxdWFscygiUVVJVCIpKSB7CisgICAgICAgICAgICBxdWl0KCk7CisgICAgICAgIH0gZWxzZSBpZiAoY29tbWFuZE5hbWUuZXF1YWxzKCJBVVRIIikpIHsKKyAgICAgICAgICAgIGF1dGgoY3VycmVudExpbmUpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgTE9HR0VSLmxvZyhMZXZlbC5TRVZFUkUsICJFUlJPUiBjb21tYW5kIHVua25vd246IHswfSIsIGNvbW1hbmROYW1lKTsKKyAgICAgICAgICAgIHByaW50bG4oIi1FUlIgdW5rbm93biBjb21tYW5kIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgU3RyaW5nIHJlYWRMaW5lKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY3VycmVudExpbmUgPSBzdXBlci5yZWFkTGluZSgpOworCisgICAgICAgIGlmIChjdXJyZW50TGluZSA9PSBudWxsKSB7CisJICAgIC8vIFhYWCAtIG9mdGVuIGhhcHBlbnMgd2hlbiBzaHV0dGluZyBkb3duCisgICAgICAgICAgICAvL0xPR0dFUi5zZXZlcmUoIkN1cnJlbnQgbGluZSBpcyBudWxsISIpOworICAgICAgICAgICAgZXhpdCgpOworICAgICAgICB9CisJcmV0dXJuIGN1cnJlbnRMaW5lOworICAgIH0KKworICAgIC8qKgorICAgICAqIEhFTE8gY29tbWFuZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB1bmFibGUgdG8gcmVhZC93cml0ZSB0byBzb2NrZXQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBoZWxvKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcHJpbnRsbigiMjIwIE9rIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogRUhMTyBjb21tYW5kLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIHVuYWJsZSB0byByZWFkL3dyaXRlIHRvIHNvY2tldAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGVobG8oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBwcmludGxuKCIyNTAtaGVsbG8iKTsKKwlmb3IgKFN0cmluZyBleHQgOiBleHRlbnNpb25zKQorCSAgICBwcmludGxuKCIyNTAtIiArIGV4dCk7CisgICAgICAgIHByaW50bG4oIjI1MCBBVVRIIFBMQUlOIik7CS8vIFBMQUlOIGlzIHNpbXBsZXN0IHRvIGZha2UKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNQUlMIGNvbW1hbmQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgdW5hYmxlIHRvIHJlYWQvd3JpdGUgdG8gc29ja2V0CisgICAgICovCisgICAgcHVibGljIHZvaWQgbWFpbChTdHJpbmcgbGluZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlvaygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJDUFQgY29tbWFuZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB1bmFibGUgdG8gcmVhZC93cml0ZSB0byBzb2NrZXQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByY3B0KFN0cmluZyBsaW5lKSB0aHJvd3MgSU9FeGNlcHRpb24geworCW9rKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogREFUQSBjb21tYW5kLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIHVuYWJsZSB0byByZWFkL3dyaXRlIHRvIHNvY2tldAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGRhdGEoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBwcmludGxuKCIzNTQgZ28gYWhlYWQiKTsKKwlyZWFkTWVzc2FnZSgpOworCW9rKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQkRBVCBjb21tYW5kLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIHVuYWJsZSB0byByZWFkL3dyaXRlIHRvIHNvY2tldAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGJkYXQoU3RyaW5nIGxpbmUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZ1Rva2VuaXplciBzdCA9IG5ldyBTdHJpbmdUb2tlbml6ZXIobGluZSwgIiAiKTsKKyAgICAgICAgU3RyaW5nIGNvbW1hbmROYW1lID0gc3QubmV4dFRva2VuKCk7CisJaW50IGJ5dGVzID0gSW50ZWdlci5wYXJzZUludChzdC5uZXh0VG9rZW4oKSk7CisJYm9vbGVhbiBsYXN0ID0gc3QuaGFzTW9yZVRva2VucygpICYmCisJCQlzdC5uZXh0VG9rZW4oKS5lcXVhbHNJZ25vcmVDYXNlKCJMQVNUIik7CisJcmVhZEJkYXRNZXNzYWdlKGJ5dGVzLCBsYXN0KTsKKwlvaygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFsbG93IHN1YmNsYXNzZXMgdG8gb3ZlcnJpZGUgdG8gc2F2ZSB0aGUgbWVzc2FnZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRNZXNzYWdlKGJ5dGVbXSBtc2cpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdW1lIHRoZSBtZXNzYWdlIGFuZCBzYXZlIGl0LgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHJlYWRNZXNzYWdlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworCVByaW50V3JpdGVyIHB3ID0gbmV3IFByaW50V3JpdGVyKG5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIoYm9zLCAidXRmLTgiKSk7CisJU3RyaW5nIGxpbmU7CisJd2hpbGUgKChsaW5lID0gc3VwZXIucmVhZExpbmUoKSkgIT0gbnVsbCkgeworCSAgICBpZiAobGluZS5lcXVhbHMoIi4iKSkKKwkJYnJlYWs7CisJICAgIGlmIChsaW5lLnN0YXJ0c1dpdGgoIi4iKSkKKwkJbGluZSA9IGxpbmUuc3Vic3RyaW5nKDEpOworCSAgICBwdy5wcmludChsaW5lKTsKKwkgICAgcHcucHJpbnQoIlxyXG4iKTsKKwl9CisJcHcuY2xvc2UoKTsKKwlzZXRNZXNzYWdlKGJvcy50b0J5dGVBcnJheSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdW1lIGEgY2h1bmsgb2YgdGhlIG1lc3NhZ2UgYW5kIHNhdmUgaXQuCisgICAgICogU2F2ZSB0aGUgZW50aXJlIG1lc3NhZ2Ugd2hlbiB0aGUgbGFzdCBjaHVuayBpcyByZWNlaXZlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCByZWFkQmRhdE1lc3NhZ2UoaW50IGJ5dGVzLCBib29sZWFuIGxhc3QpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJYnl0ZVtdIGRhdGEgPSBuZXcgYnl0ZVtieXRlc107CisJaW50IGxlbiA9IGRhdGEubGVuZ3RoOworCWludCBvZmYgPSAwOworCWludCBuOworCXdoaWxlIChsZW4gPiAwICYmIChuID0gaW4ucmVhZChkYXRhLCBvZmYsIGxlbikpID4gMCkgeworCSAgICBvZmYgKz0gbjsKKwkgICAgbGVuIC09IG47CisJfQorCWlmIChtZXNzYWdlU3RyZWFtID09IG51bGwpCisJICAgIG1lc3NhZ2VTdHJlYW0gPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisJbWVzc2FnZVN0cmVhbS53cml0ZShkYXRhKTsKKwlpZiAobGFzdCkgeworCSAgICBzZXRNZXNzYWdlKG1lc3NhZ2VTdHJlYW0udG9CeXRlQXJyYXkoKSk7CisJICAgIG1lc3NhZ2VTdHJlYW0gPSBudWxsOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBOT09QIGNvbW1hbmQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgdW5hYmxlIHRvIHJlYWQvd3JpdGUgdG8gc29ja2V0CisgICAgICovCisgICAgcHVibGljIHZvaWQgbm9vcCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIG9rKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUlNFVCBjb21tYW5kLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIHVuYWJsZSB0byByZWFkL3dyaXRlIHRvIHNvY2tldAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJzZXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvaygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFFVSVQgY29tbWFuZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB1bmFibGUgdG8gcmVhZC93cml0ZSB0byBzb2NrZXQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBxdWl0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcHJpbnRsbigiMjIxIEJZRSIpOworICAgICAgICBleGl0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQVVUSCBjb21tYW5kLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIHVuYWJsZSB0byByZWFkL3dyaXRlIHRvIHNvY2tldAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGF1dGgoU3RyaW5nIGxpbmUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHByaW50bG4oIjIzNSBBdXRob3JpemVkIik7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgb2soKSB0aHJvd3MgSU9FeGNlcHRpb24geworCXByaW50bG4oIjI1MCBPSyIpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvc210cC9TTVRQSU9FeGNlcHRpb25UZXN0LmphdmEgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3NtdHAvU01UUElPRXhjZXB0aW9uVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJjODA0OTYKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3NtdHAvU01UUElPRXhjZXB0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTE3IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDA5LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5zbXRwOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5Db3VudERvd25MYXRjaDsKKworaW1wb3J0IGphdmF4Lm1haWwuU2Vzc2lvbjsKK2ltcG9ydCBqYXZheC5tYWlsLlRyYW5zcG9ydDsKK2ltcG9ydCBqYXZheC5tYWlsLk1lc3NhZ2U7CitpbXBvcnQgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC5NaW1lTWVzc2FnZTsKK2ltcG9ydCBqYXZheC5tYWlsLmV2ZW50LkNvbm5lY3Rpb25BZGFwdGVyOworaW1wb3J0IGphdmF4Lm1haWwuZXZlbnQuQ29ubmVjdGlvbkV2ZW50OworCitpbXBvcnQgY29tLnN1bi5tYWlsLnRlc3QuVGVzdFNlcnZlcjsKKworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5SdWxlOworaW1wb3J0IG9yZy5qdW5pdC5ydWxlcy5UaW1lb3V0OworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydFRydWU7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuZmFpbDsKKworLyoqCisgKiBUZXN0IHRoYXQgdGhlIGNvbm5lY3Rpb24gaXMgY2xvc2VkIHdoZW4gYW4gSU9FeGNlcHRpb24gaXMgZGV0ZWN0ZWQuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBTTVRQSU9FeGNlcHRpb25UZXN0IHsKKworICAgIC8vIHRpbWVvdXQgdGhlIHRlc3QgaW4gY2FzZSBvZiBmYWlsdXJlCisgICAgQFJ1bGUKKyAgICBwdWJsaWMgVGltZW91dCBkZWFkbG9ja1RpbWVvdXQgPSBUaW1lb3V0LnNlY29uZHMoNSk7CisKKyAgICBwcml2YXRlIGJvb2xlYW4gY2xvc2VkID0gZmFsc2U7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVElNRU9VVCA9IDIwMDsJLy8gSS9PIHRpbWVvdXQsIGluIG1pbGxpcworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFRlc3RTZXJ2ZXIgc2VydmVyID0gbnVsbDsKKwlmaW5hbCBDb3VudERvd25MYXRjaCBjbG9zZWRMYXRjaCA9IG5ldyBDb3VudERvd25MYXRjaCgxKTsKKyAgICAgICAgdHJ5IHsKKwkgICAgU01UUEhhbmRsZXIgaGFuZGxlciA9IG5ldyBTTVRQSGFuZGxlcigpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIHJjcHQoU3RyaW5nIGxpbmUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJCSAgICB0cnkgeworCQkJLy8gZGVsYXkgbG9uZyBlbm91Z2ggdG8gY2F1c2UgdGltZW91dAorCQkJVGhyZWFkLnNsZWVwKDIgKiBUSU1FT1VUKTsKKwkJICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeyB9CisJCSAgICBzdXBlci5yY3B0KGxpbmUpOworCQl9CisJICAgIH07CisgICAgICAgICAgICBzZXJ2ZXIgPSBuZXcgVGVzdFNlcnZlcihoYW5kbGVyKTsKKyAgICAgICAgICAgIHNlcnZlci5zdGFydCgpOworCisgICAgICAgICAgICBmaW5hbCBQcm9wZXJ0aWVzIHByb3BlcnRpZXMgPSBuZXcgUHJvcGVydGllcygpOworICAgICAgICAgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5zbXRwLmhvc3QiLCAibG9jYWxob3N0Iik7CisgICAgICAgICAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLnNtdHAucG9ydCIsICIiICsgc2VydmVyLmdldFBvcnQoKSk7CisgICAgICAgICAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLnNtdHAudGltZW91dCIsICIiICsgVElNRU9VVCk7CisgICAgICAgICAgICBmaW5hbCBTZXNzaW9uIHNlc3Npb24gPSBTZXNzaW9uLmdldEluc3RhbmNlKHByb3BlcnRpZXMpOworICAgICAgICAgICAgLy9zZXNzaW9uLnNldERlYnVnKHRydWUpOworCisgICAgICAgICAgICBmaW5hbCBUcmFuc3BvcnQgdCA9IHNlc3Npb24uZ2V0VHJhbnNwb3J0KCJzbXRwIik7CisJICAgIC8qCisJICAgICAqIFVzZSBhIGxpc3RlbmVyIHRvIGRldGVjdCB0aGUgY29ubmVjdGlvbiBiZWluZyBjbG9zZWQKKwkgICAgICogYmVjYXVzZSBpZiB3ZSBjYWxsZWQgaXNDb25uZWN0ZWQoKSBhbmQgdGhlIGNvbm5lY3Rpb24KKwkgICAgICogd2Fzbid0IGFscmVhZHkgY2xvc2VkLCBpdCB3aWxsIGlzc3VlIGEgY29tbWFuZCB0aGF0CisJICAgICAqIG1pZ2h0IGRldGVjdCB0aGF0IHRoZSBjb25uZWN0aW9uIHdhcyBjbG9zZWQsIGV2ZW4KKwkgICAgICogdGhvdWdoIGl0IHdhc24ndCBjbG9zZWQgYWxyZWFkeS4KKwkgICAgICovCisJICAgIHQuYWRkQ29ubmVjdGlvbkxpc3RlbmVyKG5ldyBDb25uZWN0aW9uQWRhcHRlcigpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIGNsb3NlZChDb25uZWN0aW9uRXZlbnQgZSkgeworCQkgICAgY2xvc2VkTGF0Y2guY291bnREb3duKCk7CisJCX0KKwkgICAgfSk7CisgICAgICAgICAgICB0cnkgeworCQlNaW1lTWVzc2FnZSBtc2cgPSBuZXcgTWltZU1lc3NhZ2Uoc2Vzc2lvbik7CisJCW1zZy5zZXRSZWNpcGllbnRzKE1lc3NhZ2UuUmVjaXBpZW50VHlwZS5UTywgImpvZUBleGFtcGxlLmNvbSIpOworCQltc2cuc2V0U3ViamVjdCgidGVzdCIpOworCQltc2cuc2V0VGV4dCgidGVzdCIpOworICAgICAgICAgICAgICAgIHQuY29ubmVjdCgpOworCQl0LnNlbmRNZXNzYWdlKG1zZywgbXNnLmdldEFsbFJlY2lwaWVudHMoKSk7CisJICAgIH0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBleCkgeworCQkvLyBleHBlY3QgYW4gZXhjZXB0aW9uIGZyb20gc2VuZE1lc3NhZ2UKKwkJY2xvc2VkTGF0Y2guYXdhaXQoKTsJLy8gd2FpdCBmb3IgdGhlIGxpc3RlbmVyIHRvIHJ1bgorCQkvLyBpZiB3ZSBnZXQgaGVyZSwgdGhlIGxpc3RlbmVyIHdhcyBjYWxsZWQgLSBTVUNDRVNTCisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHQuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoZmluYWwgRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICBmYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChzZXJ2ZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHNlcnZlci5xdWl0KCk7CisJCXNlcnZlci5pbnRlcnJ1cHQoKTsKKwkJLy8gd2FpdCBmb3IgaGFuZGxlciB0byBleGl0CisJCXNlcnZlci5qb2luKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3NtdHAvU01UUExvZ2luSGFuZGxlci5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9zbXRwL1NNVFBMb2dpbkhhbmRsZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wYjI5NGVhCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9zbXRwL1NNVFBMb2dpbkhhbmRsZXIuamF2YQpAQCAtMCwwICsxLDE1MSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwOSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwuc210cDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5TdGFuZGFyZENoYXJzZXRzOworaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7CitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTG9nZ2VyOworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkxldmVsOworCitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuQkFTRTY0RW5jb2RlclN0cmVhbTsKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5CQVNFNjREZWNvZGVyU3RyZWFtOworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLkFTQ0lJVXRpbGl0eTsKKworLyoqCisgKiBIYW5kbGUgY29ubmVjdGlvbiB3aXRoIExPR0lOIG9yIFBMQUlOIGF1dGhlbnRpY2F0aW9uLgorICoKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKi8KK3B1YmxpYyBjbGFzcyBTTVRQTG9naW5IYW5kbGVyIGV4dGVuZHMgU01UUEhhbmRsZXIgeworICAgIHByb3RlY3RlZCBTdHJpbmcgdXNlcm5hbWUgPSAidGVzdCI7CisgICAgcHJvdGVjdGVkIFN0cmluZyBwYXNzd29yZCA9ICJ0ZXN0IjsKKworICAgIC8qKgorICAgICAqIEVITE8gY29tbWFuZC4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiAgICAgICAgICAgICB1bmFibGUgdG8gcmVhZC93cml0ZSB0byBzb2NrZXQKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBlaGxvKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcHJpbnRsbigiMjUwLWhlbGxvIik7CisgICAgICAgIHByaW50bG4oIjI1MC1TTVRQVVRGOCIpOworICAgICAgICBwcmludGxuKCIyNTAtOEJJVE1JTUUiKTsKKyAgICAgICAgcHJpbnRsbigiMjUwIEFVVEggUExBSU4gTE9HSU4iKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBVVRIIGNvbW1hbmQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgdW5hYmxlIHRvIHJlYWQvd3JpdGUgdG8gc29ja2V0CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgYXV0aChTdHJpbmcgbGluZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nVG9rZW5pemVyIGN0ID0gbmV3IFN0cmluZ1Rva2VuaXplcihsaW5lLCAiICIpOworICAgICAgICBTdHJpbmcgY29tbWFuZE5hbWUgPSBjdC5uZXh0VG9rZW4oKS50b1VwcGVyQ2FzZSgpOworCVN0cmluZyBtZWNoID0gY3QubmV4dFRva2VuKCkudG9VcHBlckNhc2UoKTsKKwlTdHJpbmcgaXIgPSAiIjsKKwlpZiAoY3QuaGFzTW9yZVRva2VucygpKQorCSAgICBpciA9IGN0Lm5leHRUb2tlbigpOworCisJaWYgKExPR0dFUi5pc0xvZ2dhYmxlKExldmVsLkZJTkUpKQorCSAgICBMT0dHRVIuZmluZShsaW5lKTsKKwlpZiAobWVjaC5lcXVhbHNJZ25vcmVDYXNlKCJQTEFJTiIpKQorCSAgICBwbGFpbihpcik7CisJZWxzZSBpZiAobWVjaC5lcXVhbHNJZ25vcmVDYXNlKCJMT0dJTiIpKQorCSAgICBsb2dpbihpcik7CisJZWxzZQorCSAgICBwcmludGxuKCI1MDEgYmFkIEFVVEggbWVjaGFuaXNtIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQVVUSCBMT0dJTgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBsb2dpbihTdHJpbmcgaXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJcHJpbnRsbigiMzM0Iik7CisJLy8gcmVhZCB1c2VyIG5hbWUKKwlTdHJpbmcgcmVzcCA9IHJlYWRMaW5lKCk7CisJaWYgKCFpc0Jhc2U2NChyZXNwKSkgeworCSAgICBwcmludGxuKCI1MDEgcmVzcG9uc2Ugbm90IGJhc2U2NCIpOworCSAgICByZXR1cm47CisJfQorCWJ5dGVbXSByZXNwb25zZSA9IHJlc3AuZ2V0Qnl0ZXMoU3RhbmRhcmRDaGFyc2V0cy5VU19BU0NJSSk7CisJcmVzcG9uc2UgPSBCQVNFNjREZWNvZGVyU3RyZWFtLmRlY29kZShyZXNwb25zZSk7CisJU3RyaW5nIHUgPSBuZXcgU3RyaW5nKHJlc3BvbnNlLCBTdGFuZGFyZENoYXJzZXRzLlVURl84KTsKKwlpZiAoTE9HR0VSLmlzTG9nZ2FibGUoTGV2ZWwuRklORSkpCisJICAgIExPR0dFUi5maW5lKCJVU0VSOiAiICsgdSk7CisJcHJpbnRsbigiMzM0Iik7CisKKwkvLyByZWFkIHBhc3N3b3JkCisJcmVzcCA9IHJlYWRMaW5lKCk7CisJaWYgKCFpc0Jhc2U2NChyZXNwKSkgeworCSAgICBwcmludGxuKCI1MDEgcmVzcG9uc2Ugbm90IGJhc2U2NCIpOworCSAgICByZXR1cm47CisJfQorCXJlc3BvbnNlID0gcmVzcC5nZXRCeXRlcyhTdGFuZGFyZENoYXJzZXRzLlVTX0FTQ0lJKTsKKwlyZXNwb25zZSA9IEJBU0U2NERlY29kZXJTdHJlYW0uZGVjb2RlKHJlc3BvbnNlKTsKKwlTdHJpbmcgcCA9IG5ldyBTdHJpbmcocmVzcG9uc2UsIFN0YW5kYXJkQ2hhcnNldHMuVVRGXzgpOworCWlmIChMT0dHRVIuaXNMb2dnYWJsZShMZXZlbC5GSU5FKSkKKwkgICAgTE9HR0VSLmZpbmUoIlBBU1NXT1JEOiAiICsgcCk7CisKKwkvL1N5c3RlbS5vdXQucHJpbnRmKCJVU0VSOiAlcywgUEFTU1dPUkQ6ICVzJW4iLCB1LCBwKTsKKwlpZiAoIXUuZXF1YWxzKHVzZXJuYW1lKSB8fCAhcC5lcXVhbHMocGFzc3dvcmQpKSB7CisJICAgIHByaW50bG4oIjUzNSBhdXRoZW50aWNhdGlvbiBmYWlsZWQiKTsKKwkgICAgcmV0dXJuOworCX0KKworCXByaW50bG4oIjIzNSBBdXRoZW50aWNhdGVkIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQVVUSCBQTEFJTgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBwbGFpbihTdHJpbmcgaXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJU3RyaW5nIGF1dGggPSBuZXcgU3RyaW5nKEJBU0U2NERlY29kZXJTdHJlYW0uZGVjb2RlKAorCQkJCSAgICBpci5nZXRCeXRlcyhTdGFuZGFyZENoYXJzZXRzLlVTX0FTQ0lJKSksCisJCQkJU3RhbmRhcmRDaGFyc2V0cy5VVEZfOCk7CisJU3RyaW5nW10gYXAgPSBhdXRoLnNwbGl0KCJcMDAwIik7CisJU3RyaW5nIHUgPSBhcFsxXTsKKwlTdHJpbmcgcCA9IGFwWzJdOworCS8vU3lzdGVtLm91dC5wcmludGYoIlVTRVI6ICVzLCBQQVNTV09SRDogJXMlbiIsIHUsIHApOworCWlmICghdS5lcXVhbHModXNlcm5hbWUpIHx8ICFwLmVxdWFscyhwYXNzd29yZCkpIHsKKwkgICAgcHJpbnRsbigiNTM1IGF1dGhlbnRpY2F0aW9uIGZhaWxlZCIpOworCSAgICByZXR1cm47CisJfQorCXByaW50bG4oIjIzNSBBdXRoZW50aWNhdGVkIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogSXMgZXZlcnkgY2hhcmFjdGVyIGluIHRoZSBzdHJpbmcgYSBiYXNlNjQgY2hhcmFjdGVyPworICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBpc0Jhc2U2NChTdHJpbmcgcykgeworCWludCBsZW4gPSBzLmxlbmd0aCgpOworCWlmIChzLmVuZHNXaXRoKCI9PSIpKQorCSAgICBsZW4gLT0gMjsKKwllbHNlIGlmIChzLmVuZHNXaXRoKCI9IikpCisJICAgIGxlbi0tOworCWZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKKwkgICAgY2hhciBjID0gcy5jaGFyQXQoaSk7CisJICAgIGlmICghKChjID49ICdBJyAmJiBjIDw9ICdaJykgfHwgKGMgPj0gJ2EnICYmIGMgPD0gJ3onKSB8fAorCQkgICAgKGMgPj0gJzAnICYmIGMgPD0gJzknKSB8fCBjID09ICcrJyB8fCBjID09ICcvJykpCisJCXJldHVybiBmYWxzZTsKKwl9CisJcmV0dXJuIHRydWU7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9zbXRwL1NNVFBTYXNsSGFuZGxlci5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9zbXRwL1NNVFBTYXNsSGFuZGxlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJhYjZhMmIKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3NtdHAvU01UUFNhc2xIYW5kbGVyLmphdmEKQEAgLTAsMCArMSwxOTIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDksIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLnNtdHA7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7CitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTG9nZ2VyOworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkxldmVsOworCitpbXBvcnQgamF2YXguc2VjdXJpdHkuc2FzbC4qOworaW1wb3J0IGphdmF4LnNlY3VyaXR5LmF1dGguY2FsbGJhY2suKjsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLkJBU0U2NEVuY29kZXJTdHJlYW07CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuQkFTRTY0RGVjb2RlclN0cmVhbTsKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5BU0NJSVV0aWxpdHk7CisKKy8qKgorICogSGFuZGxlIGNvbm5lY3Rpb24gd2l0aCBTQVNMIGF1dGhlbnRpY2F0aW9uLgorICoKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKi8KK3B1YmxpYyBjbGFzcyBTTVRQU2FzbEhhbmRsZXIgZXh0ZW5kcyBTTVRQSGFuZGxlciB7CisKKyAgICAvKioKKyAgICAgKiBFSExPIGNvbW1hbmQuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogICAgICAgICAgICAgdW5hYmxlIHRvIHJlYWQvd3JpdGUgdG8gc29ja2V0CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZWhsbygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHByaW50bG4oIjI1MC1oZWxsbyIpOworICAgICAgICBwcmludGxuKCIyNTAgQVVUSCBESUdFU1QtTUQ1Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQVVUSCBjb21tYW5kLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIHVuYWJsZSB0byByZWFkL3dyaXRlIHRvIHNvY2tldAorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGF1dGgoU3RyaW5nIGxpbmUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZ1Rva2VuaXplciBjdCA9IG5ldyBTdHJpbmdUb2tlbml6ZXIobGluZSwgIiAiKTsKKyAgICAgICAgU3RyaW5nIGNvbW1hbmROYW1lID0gY3QubmV4dFRva2VuKCkudG9VcHBlckNhc2UoKTsKKwlTdHJpbmcgbWVjaCA9IGN0Lm5leHRUb2tlbigpLnRvVXBwZXJDYXNlKCk7CisJU3RyaW5nIGlyID0gIiI7CisJaWYgKGN0Lmhhc01vcmVUb2tlbnMoKSkKKwkgICAgaXIgPSBjdC5uZXh0VG9rZW4oKTsKKworCWZpbmFsIFN0cmluZyB1ID0gInRlc3QiOworCWZpbmFsIFN0cmluZyBwID0gInRlc3QiOworCWZpbmFsIFN0cmluZyByZWFsbSA9ICJ0ZXN0IjsKKworCUNhbGxiYWNrSGFuZGxlciBjYmggPSBuZXcgQ2FsbGJhY2tIYW5kbGVyKCkgeworCSAgICBAT3ZlcnJpZGUKKwkgICAgcHVibGljIHZvaWQgaGFuZGxlKENhbGxiYWNrW10gY2FsbGJhY2tzKSB7CisJCWlmIChMT0dHRVIuaXNMb2dnYWJsZShMZXZlbC5GSU5FKSkKKwkJICAgIExPR0dFUi5maW5lKCJTQVNMIGNhbGxiYWNrIGxlbmd0aDogIiArIGNhbGxiYWNrcy5sZW5ndGgpOworCQlmb3IgKGludCBpID0gMDsgaSA8IGNhbGxiYWNrcy5sZW5ndGg7IGkrKykgeworCQkgICAgaWYgKExPR0dFUi5pc0xvZ2dhYmxlKExldmVsLkZJTkUpKQorCQkJTE9HR0VSLmZpbmUoIlNBU0wgY2FsbGJhY2sgIiArIGkgKyAiOiAiICsgY2FsbGJhY2tzW2ldKTsKKwkJICAgIGlmIChjYWxsYmFja3NbaV0gaW5zdGFuY2VvZiBOYW1lQ2FsbGJhY2spIHsKKwkJCU5hbWVDYWxsYmFjayBuY2IgPSAoTmFtZUNhbGxiYWNrKWNhbGxiYWNrc1tpXTsKKwkJCW5jYi5zZXROYW1lKHUpOworCQkgICAgfSBlbHNlIGlmIChjYWxsYmFja3NbaV0gaW5zdGFuY2VvZiBQYXNzd29yZENhbGxiYWNrKSB7CisJCQlQYXNzd29yZENhbGxiYWNrIHBjYiA9IChQYXNzd29yZENhbGxiYWNrKWNhbGxiYWNrc1tpXTsKKwkJCXBjYi5zZXRQYXNzd29yZChwLnRvQ2hhckFycmF5KCkpOworCQkgICAgfSBlbHNlIGlmIChjYWxsYmFja3NbaV0gaW5zdGFuY2VvZiBBdXRob3JpemVDYWxsYmFjaykgeworCQkJQXV0aG9yaXplQ2FsbGJhY2sgYWMgPSAoQXV0aG9yaXplQ2FsbGJhY2spY2FsbGJhY2tzW2ldOworCQkJaWYgKExPR0dFUi5pc0xvZ2dhYmxlKExldmVsLkZJTkUpKQorCQkJICAgIExPR0dFUi5maW5lKCJTQVNMIGF1dGhvcml6ZTogIiArCisJCQkJImF1dGhuOiAiICsgYWMuZ2V0QXV0aGVudGljYXRpb25JRCgpICsgIiwgIiArCisJCQkJImF1dGh6OiAiICsgYWMuZ2V0QXV0aG9yaXphdGlvbklEKCkgKyAiLCAiICsKKwkJCQkiYXV0aG9yaXplZDogIiArIGFjLmdldEF1dGhvcml6ZWRJRCgpKTsKKwkJCWFjLnNldEF1dGhvcml6ZWQodHJ1ZSk7CisJCSAgICB9IGVsc2UgaWYgKGNhbGxiYWNrc1tpXSBpbnN0YW5jZW9mIFJlYWxtQ2FsbGJhY2spIHsKKwkJCVJlYWxtQ2FsbGJhY2sgcmNiID0gKFJlYWxtQ2FsbGJhY2spY2FsbGJhY2tzW2ldOworCQkJcmNiLnNldFRleHQocmVhbG0gIT0gbnVsbCA/CisJCQkJICAgIHJlYWxtIDogcmNiLmdldERlZmF1bHRUZXh0KCkpOworCQkgICAgfSBlbHNlIGlmIChjYWxsYmFja3NbaV0gaW5zdGFuY2VvZiBSZWFsbUNob2ljZUNhbGxiYWNrKSB7CisJCQlSZWFsbUNob2ljZUNhbGxiYWNrIHJjYiA9CisJCQkgICAgKFJlYWxtQ2hvaWNlQ2FsbGJhY2spY2FsbGJhY2tzW2ldOworCQkJaWYgKHJlYWxtID09IG51bGwpCisJCQkgICAgcmNiLnNldFNlbGVjdGVkSW5kZXgocmNiLmdldERlZmF1bHRDaG9pY2UoKSk7CisJCQllbHNlIHsKKwkJCSAgICAvLyBuZWVkIHRvIGZpbmQgc3BlY2lmaWVkIHJlYWxtIGluIGxpc3QKKwkJCSAgICBTdHJpbmdbXSBjaG9pY2VzID0gcmNiLmdldENob2ljZXMoKTsKKwkJCSAgICBmb3IgKGludCBrID0gMDsgayA8IGNob2ljZXMubGVuZ3RoOyBrKyspIHsKKwkJCQlpZiAoY2hvaWNlc1trXS5lcXVhbHMocmVhbG0pKSB7CisJCQkJICAgIHJjYi5zZXRTZWxlY3RlZEluZGV4KGspOworCQkJCSAgICBicmVhazsKKwkJCQl9CisJCQkgICAgfQorCQkJfQorCQkgICAgfQorCQl9CisJICAgIH0KKwl9OworCisJU2FzbFNlcnZlciBzczsKKwl0cnkgeworCSAgICBzcyA9IFNhc2wuY3JlYXRlU2FzbFNlcnZlcihtZWNoLCAic210cCIsICJsb2NhbGhvc3QiLCBudWxsLCBjYmgpOworCX0gY2F0Y2ggKFNhc2xFeGNlcHRpb24gc2V4KSB7CisJICAgIExPR0dFUi5sb2coTGV2ZWwuRklORSwgIkZhaWxlZCB0byBjcmVhdGUgU0FTTCBzZXJ2ZXIiLCBzZXgpOworCSAgICBwcmludGxuKCI1MDEgRmFpbGVkIHRvIGNyZWF0ZSBTQVNMIHNlcnZlciIpOworCSAgICByZXR1cm47CisJfQorCWlmIChzcyA9PSBudWxsKSB7CisJICAgIExPR0dFUi5maW5lKCJObyBTQVNMIHN1cHBvcnQiKTsKKwkgICAgcHJpbnRsbigiNTAxIE5vIFNBU0wgc3VwcG9ydCIpOworCSAgICByZXR1cm47CisJfQorCWlmIChMT0dHRVIuaXNMb2dnYWJsZShMZXZlbC5GSU5FKSkKKwkgICAgTE9HR0VSLmZpbmUoIlNBU0wgc2VydmVyICIgKyBzcy5nZXRNZWNoYW5pc21OYW1lKCkpOworCisJYnl0ZVtdIHJlc3BvbnNlID0gaXIuZ2V0Qnl0ZXMoKTsKKwl3aGlsZSAoIXNzLmlzQ29tcGxldGUoKSkgeworCSAgICB0cnkgeworCQlieXRlW10gY2hhbCA9IHNzLmV2YWx1YXRlUmVzcG9uc2UocmVzcG9uc2UpOworCQkvLyBzZW5kIGNoYWxsZW5nZQorCQlpZiAoTE9HR0VSLmlzTG9nZ2FibGUoTGV2ZWwuRklORSkpCisJCSAgICBMT0dHRVIuZmluZSgiU0FTTCBjaGFsbGVuZ2U6ICIgKworCQkJQVNDSUlVdGlsaXR5LnRvU3RyaW5nKGNoYWwsIDAsIGNoYWwubGVuZ3RoKSk7CisJCWJ5dGVbXSBiYSA9IEJBU0U2NEVuY29kZXJTdHJlYW0uZW5jb2RlKGNoYWwpOworCQlpZiAoYmEubGVuZ3RoID4gMCkKKwkJICAgIHByaW50bG4oIjMzNCAiICsKKwkJCSAgICBBU0NJSVV0aWxpdHkudG9TdHJpbmcoYmEsIDAsIGJhLmxlbmd0aCkpOworCQllbHNlCisJCSAgICBwcmludGxuKCIzMzQiKTsKKwkJLy8gcmVhZCByZXNwb25zZQorCQlTdHJpbmcgcmVzcCA9IHJlYWRMaW5lKCk7CisJCWlmICghaXNCYXNlNjQocmVzcCkpIHsKKwkJICAgIHByaW50bG4oIjUwMSByZXNwb25zZSBub3QgYmFzZTY0Iik7CisJCWJyZWFrOworCQl9CisJCXJlc3BvbnNlID0gcmVzcC5nZXRCeXRlcygpOworCQlyZXNwb25zZSA9IEJBU0U2NERlY29kZXJTdHJlYW0uZGVjb2RlKHJlc3BvbnNlKTsKKwkgICAgfSBjYXRjaCAoU2FzbEV4Y2VwdGlvbiBleCkgeworCQlwcmludGxuKCI1MDEgIiArIGV4LnRvU3RyaW5nKCkpOworCQlicmVhazsKKwkgICAgfQorCX0KKworCWlmIChzcy5pc0NvbXBsZXRlKCkgLyomJiBzdGF0dXMgPT0gU1VDQ0VTUyovKSB7CisJICAgIFN0cmluZyBxb3AgPSAoU3RyaW5nKXNzLmdldE5lZ290aWF0ZWRQcm9wZXJ0eShTYXNsLlFPUCk7CisJICAgIGlmIChxb3AgIT0gbnVsbCAmJiAocW9wLmVxdWFsc0lnbm9yZUNhc2UoImF1dGgtaW50IikgfHwKKwkJCQlxb3AuZXF1YWxzSWdub3JlQ2FzZSgiYXV0aC1jb25mIikpKSB7CisJCS8vIFhYWCAtIE5PVCBTVVBQT1JURUQhISEKKwkJTE9HR0VSLmZpbmUoCisJCQkiU0FTTCBNZWNoYW5pc20gcmVxdWlyZXMgaW50ZWdyaXR5IG9yIGNvbmZpZGVudGlhbGl0eSIpOworCQlwcmludGxuKCI1MDEgIiArCisJCQkiU0FTTCBNZWNoYW5pc20gcmVxdWlyZXMgaW50ZWdyaXR5IG9yIGNvbmZpZGVudGlhbGl0eSIpOworCQlyZXR1cm47CisJICAgIH0KKwl9CisKKwlwcmludGxuKCIyMzUgQXV0aGVudGljYXRlZCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIElzIGV2ZXJ5IGNoYXJhY3RlciBpbiB0aGUgc3RyaW5nIGEgYmFzZTY0IGNoYXJhY3Rlcj8KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gaXNCYXNlNjQoU3RyaW5nIHMpIHsKKwlpbnQgbGVuID0gcy5sZW5ndGgoKTsKKwlpZiAocy5lbmRzV2l0aCgiPT0iKSkKKwkgICAgbGVuIC09IDI7CisJZWxzZSBpZiAocy5lbmRzV2l0aCgiPSIpKQorCSAgICBsZW4tLTsKKwlmb3IgKGludCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7CisJICAgIGNoYXIgYyA9IHMuY2hhckF0KGkpOworCSAgICBpZiAoISgoYyA+PSAnQScgJiYgYyA8PSAnWicpIHx8IChjID49ICdhJyAmJiBjIDw9ICd6JykgfHwKKwkJICAgIChjID49ICcwJyAmJiBjIDw9ICc5JykgfHwgYyA9PSAnKycgfHwgYyA9PSAnLycpKQorCQlyZXR1cm4gZmFsc2U7CisJfQorCXJldHVybiB0cnVlOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvc210cC9TTVRQU2FzbExvZ2luVGVzdC5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9zbXRwL1NNVFBTYXNsTG9naW5UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmU4YjViYQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvc210cC9TTVRQU2FzbExvZ2luVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjg5IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDA5LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5zbXRwOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKKworaW1wb3J0IGphdmF4Lm1haWwuU2Vzc2lvbjsKK2ltcG9ydCBqYXZheC5tYWlsLlRyYW5zcG9ydDsKK2ltcG9ydCBqYXZheC5tYWlsLkF1dGhlbnRpY2F0aW9uRmFpbGVkRXhjZXB0aW9uOworCitpbXBvcnQgY29tLnN1bi5tYWlsLnRlc3QuVGVzdFNlcnZlcjsKKworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydFRydWU7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuZmFpbDsKKworLyoqCisgKiBUZXN0IGxvZ2luIHVzaW5nIGEgU0FTTCBtZWNoYW5pc20gb24gdGhlIHNlcnZlcgorICogd2l0aCBTQVNMIGFuZCBub24tU0FTTCBvbiB0aGUgY2xpZW50LgorICovCitwdWJsaWMgY2xhc3MgU01UUFNhc2xMb2dpblRlc3QgeworCisgICAgLyoqCisgICAgICogVGVzdCB1c2luZyBub24tU0FTTCBESUdFU1QtTUQ1LgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFN1Y2Nlc3MoKSB7CisgICAgICAgIFRlc3RTZXJ2ZXIgc2VydmVyID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNlcnZlciA9IG5ldyBUZXN0U2VydmVyKG5ldyBTTVRQU2FzbEhhbmRsZXIoKSk7CisgICAgICAgICAgICBzZXJ2ZXIuc3RhcnQoKTsKKworICAgICAgICAgICAgUHJvcGVydGllcyBwcm9wZXJ0aWVzID0gbmV3IFByb3BlcnRpZXMoKTsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuc210cC5ob3N0IiwgImxvY2FsaG9zdCIpOworICAgICAgICAgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5zbXRwLnBvcnQiLCAiIiArIHNlcnZlci5nZXRQb3J0KCkpOworICAgICAgICAgICAgLy9wcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLmRlYnVnLmF1dGgiLCAidHJ1ZSIpOworICAgICAgICAgICAgU2Vzc2lvbiBzZXNzaW9uID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShwcm9wZXJ0aWVzKTsKKyAgICAgICAgICAgIC8vc2Vzc2lvbi5zZXREZWJ1Zyh0cnVlKTsKKworICAgICAgICAgICAgVHJhbnNwb3J0IHQgPSBzZXNzaW9uLmdldFRyYW5zcG9ydCgic210cCIpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB0LmNvbm5lY3QoInRlc3QiLCAidGVzdCIpOworCQkvLyBzdWNjZXNzIQorCSAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKwkJZmFpbChleC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgdC5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgIGZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKHNlcnZlciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgc2VydmVyLnF1aXQoKTsKKwkJc2VydmVyLmludGVycnVwdCgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB1c2luZyBub24tU0FTTCBESUdFU1QtTUQ1IHdpdGggaW5jb3JyZWN0IHBhc3N3b3JkLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEZhaWx1cmUoKSB7CisgICAgICAgIFRlc3RTZXJ2ZXIgc2VydmVyID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNlcnZlciA9IG5ldyBUZXN0U2VydmVyKG5ldyBTTVRQU2FzbEhhbmRsZXIoKSk7CisgICAgICAgICAgICBzZXJ2ZXIuc3RhcnQoKTsKKworICAgICAgICAgICAgUHJvcGVydGllcyBwcm9wZXJ0aWVzID0gbmV3IFByb3BlcnRpZXMoKTsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuc210cC5ob3N0IiwgImxvY2FsaG9zdCIpOworICAgICAgICAgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5zbXRwLnBvcnQiLCAiIiArIHNlcnZlci5nZXRQb3J0KCkpOworICAgICAgICAgICAgLy9wcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLmRlYnVnLmF1dGgiLCAidHJ1ZSIpOworICAgICAgICAgICAgU2Vzc2lvbiBzZXNzaW9uID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShwcm9wZXJ0aWVzKTsKKyAgICAgICAgICAgIC8vc2Vzc2lvbi5zZXREZWJ1Zyh0cnVlKTsKKworICAgICAgICAgICAgVHJhbnNwb3J0IHQgPSBzZXNzaW9uLmdldFRyYW5zcG9ydCgic210cCIpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB0LmNvbm5lY3QoInRlc3QiLCAieHRlc3QiKTsKKwkJLy8gc2hvdWxkIGhhdmUgZmFpbGVkCisJCWZhaWwoIndyb25nIHBhc3N3b3JkIHN1Y2NlZWRlZCIpOworCSAgICB9IGNhdGNoIChBdXRoZW50aWNhdGlvbkZhaWxlZEV4Y2VwdGlvbiBleCkgeworCQkvLyBzdWNjZXNzIQorCSAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKwkJZmFpbChleC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgdC5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgIGZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKHNlcnZlciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgc2VydmVyLnF1aXQoKTsKKwkJc2VydmVyLmludGVycnVwdCgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB1c2luZyBTQVNMIERJR0VTVC1NRDUuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2FzbFN1Y2Nlc3MoKSB7CisgICAgICAgIFRlc3RTZXJ2ZXIgc2VydmVyID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNlcnZlciA9IG5ldyBUZXN0U2VydmVyKG5ldyBTTVRQU2FzbEhhbmRsZXIoKSk7CisgICAgICAgICAgICBzZXJ2ZXIuc3RhcnQoKTsKKworICAgICAgICAgICAgUHJvcGVydGllcyBwcm9wZXJ0aWVzID0gbmV3IFByb3BlcnRpZXMoKTsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuc210cC5ob3N0IiwgImxvY2FsaG9zdCIpOworICAgICAgICAgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5zbXRwLnBvcnQiLCAiIiArIHNlcnZlci5nZXRQb3J0KCkpOworICAgICAgICAgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5zbXRwLnNhc2wuZW5hYmxlIiwgInRydWUiKTsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuc210cC5zYXNsLm1lY2hhbmlzbXMiLCAiRElHRVNULU1ENSIpOworICAgICAgICAgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5zbXRwLmF1dGguZGlnZXN0LW1kNS5kaXNhYmxlIiwgInRydWUiKTsKKyAgICAgICAgICAgIC8vcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5kZWJ1Zy5hdXRoIiwgInRydWUiKTsKKyAgICAgICAgICAgIFNlc3Npb24gc2Vzc2lvbiA9IFNlc3Npb24uZ2V0SW5zdGFuY2UocHJvcGVydGllcyk7CisgICAgICAgICAgICAvL3Nlc3Npb24uc2V0RGVidWcodHJ1ZSk7CisKKyAgICAgICAgICAgIFRyYW5zcG9ydCB0ID0gc2Vzc2lvbi5nZXRUcmFuc3BvcnQoInNtdHAiKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgdC5jb25uZWN0KCJ0ZXN0IiwgInRlc3QiKTsKKwkJLy8gc3VjY2VzcyEKKwkgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJCWZhaWwoZXgudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHQuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICBmYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChzZXJ2ZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHNlcnZlci5xdWl0KCk7CisJCXNlcnZlci5pbnRlcnJ1cHQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgdXNpbmcgU0FTTCBESUdFU1QtTUQ1IHdpdGggaW5jb3JyZWN0IHBhc3N3b3JkLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFNhc2xGYWlsdXJlKCkgeworICAgICAgICBUZXN0U2VydmVyIHNlcnZlciA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzZXJ2ZXIgPSBuZXcgVGVzdFNlcnZlcihuZXcgU01UUFNhc2xIYW5kbGVyKCkpOworICAgICAgICAgICAgc2VydmVyLnN0YXJ0KCk7CisKKyAgICAgICAgICAgIFByb3BlcnRpZXMgcHJvcGVydGllcyA9IG5ldyBQcm9wZXJ0aWVzKCk7CisgICAgICAgICAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLnNtdHAuaG9zdCIsICJsb2NhbGhvc3QiKTsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuc210cC5wb3J0IiwgIiIgKyBzZXJ2ZXIuZ2V0UG9ydCgpKTsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuc210cC5zYXNsLmVuYWJsZSIsICJ0cnVlIik7CisgICAgICAgICAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLnNtdHAuc2FzbC5tZWNoYW5pc21zIiwgIkRJR0VTVC1NRDUiKTsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuc210cC5hdXRoLmRpZ2VzdC1tZDUuZGlzYWJsZSIsICJ0cnVlIik7CisgICAgICAgICAgICAvL3Byb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuZGVidWcuYXV0aCIsICJ0cnVlIik7CisgICAgICAgICAgICBTZXNzaW9uIHNlc3Npb24gPSBTZXNzaW9uLmdldEluc3RhbmNlKHByb3BlcnRpZXMpOworICAgICAgICAgICAgLy9zZXNzaW9uLnNldERlYnVnKHRydWUpOworCisgICAgICAgICAgICBUcmFuc3BvcnQgdCA9IHNlc3Npb24uZ2V0VHJhbnNwb3J0KCJzbXRwIik7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHQuY29ubmVjdCgidGVzdCIsICJ4dGVzdCIpOworCQkvLyBzaG91bGQgaGF2ZSBmYWlsZWQKKwkJZmFpbCgid3JvbmcgcGFzc3dvcmQgc3VjY2VlZGVkIik7CisJICAgIH0gY2F0Y2ggKEF1dGhlbnRpY2F0aW9uRmFpbGVkRXhjZXB0aW9uIGV4KSB7CisJCS8vIHN1Y2Nlc3MhCisJICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCQlmYWlsKGV4LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICB0LmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoc2VydmVyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBzZXJ2ZXIucXVpdCgpOworCQlzZXJ2ZXIuaW50ZXJydXB0KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHRoYXQgQVVUSCB3aXRoIG5vIG1lY2hhbmlzbXMgZmFpbHMuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QXV0aE5vUGFyYW0oKSB7CisgICAgICAgIFRlc3RTZXJ2ZXIgc2VydmVyID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNlcnZlciA9IG5ldyBUZXN0U2VydmVyKG5ldyBTTVRQU2FzbEhhbmRsZXIoKSB7CisJCUBPdmVycmlkZQorCQlwdWJsaWMgdm9pZCBlaGxvKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkJICAgIHByaW50bG4oIjI1MC1oZWxsbyIpOworCQkgICAgcHJpbnRsbigiMjUwIEFVVEgiKTsKKwkJfQorCSAgICB9KTsKKyAgICAgICAgICAgIHNlcnZlci5zdGFydCgpOworCisgICAgICAgICAgICBQcm9wZXJ0aWVzIHByb3BlcnRpZXMgPSBuZXcgUHJvcGVydGllcygpOworICAgICAgICAgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5zbXRwLmhvc3QiLCAibG9jYWxob3N0Iik7CisgICAgICAgICAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLnNtdHAucG9ydCIsICIiICsgc2VydmVyLmdldFBvcnQoKSk7CisgICAgICAgICAgICAvL3Byb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuZGVidWcuYXV0aCIsICJ0cnVlIik7CisgICAgICAgICAgICBTZXNzaW9uIHNlc3Npb24gPSBTZXNzaW9uLmdldEluc3RhbmNlKHByb3BlcnRpZXMpOworICAgICAgICAgICAgLy9zZXNzaW9uLnNldERlYnVnKHRydWUpOworCisgICAgICAgICAgICBUcmFuc3BvcnQgdCA9IHNlc3Npb24uZ2V0VHJhbnNwb3J0KCJzbXRwIik7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHQuY29ubmVjdCgidGVzdCIsICJ0ZXN0Iik7CisJCWZhaWwoIkNvbm5lY3QgZGlkbid0IGZhaWwiKTsKKwkgICAgfSBjYXRjaCAoQXV0aGVudGljYXRpb25GYWlsZWRFeGNlcHRpb24gZXgpIHsKKwkJLy8gc3VjY2VzcworCSAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKwkJZmFpbChleC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgdC5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgIGZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKHNlcnZlciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgc2VydmVyLnF1aXQoKTsKKwkJc2VydmVyLmludGVycnVwdCgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IG5vIEFVVEggc3VjY2VlZHMgYnkgc2tpcHBpbmcgYXV0aGVudGljYXRpb24gZW50aXJlbHkuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Tm9BdXRoKCkgeworICAgICAgICBUZXN0U2VydmVyIHNlcnZlciA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzZXJ2ZXIgPSBuZXcgVGVzdFNlcnZlcihuZXcgU01UUFNhc2xIYW5kbGVyKCkgeworCQlAT3ZlcnJpZGUKKwkJcHVibGljIHZvaWQgZWhsbygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJCSAgICBwcmludGxuKCIyNTAtaGVsbG8iKTsKKwkJICAgIHByaW50bG4oIjI1MCBYWFgiKTsKKwkJfQorCQlAT3ZlcnJpZGUKKwkJcHVibGljIHZvaWQgYXV0aChTdHJpbmcgbGluZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkJICAgIHByaW50bG4oIjUwMSBBdXRoZW50aWNhdGlvbiBmYWlsZWQiKTsKKwkJfQorCSAgICB9KTsKKyAgICAgICAgICAgIHNlcnZlci5zdGFydCgpOworCisgICAgICAgICAgICBQcm9wZXJ0aWVzIHByb3BlcnRpZXMgPSBuZXcgUHJvcGVydGllcygpOworICAgICAgICAgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5zbXRwLmhvc3QiLCAibG9jYWxob3N0Iik7CisgICAgICAgICAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLnNtdHAucG9ydCIsICIiICsgc2VydmVyLmdldFBvcnQoKSk7CisgICAgICAgICAgICAvL3Byb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuZGVidWcuYXV0aCIsICJ0cnVlIik7CisgICAgICAgICAgICBTZXNzaW9uIHNlc3Npb24gPSBTZXNzaW9uLmdldEluc3RhbmNlKHByb3BlcnRpZXMpOworICAgICAgICAgICAgLy9zZXNzaW9uLnNldERlYnVnKHRydWUpOworCisgICAgICAgICAgICBUcmFuc3BvcnQgdCA9IHNlc3Npb24uZ2V0VHJhbnNwb3J0KCJzbXRwIik7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHQuY29ubmVjdCgidGVzdCIsICJ0ZXN0Iik7CisJCS8vIHN1Y2Nlc3MKKwkgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJCWZhaWwoZXgudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHQuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICBmYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChzZXJ2ZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHNlcnZlci5xdWl0KCk7CisJCXNlcnZlci5pbnRlcnJ1cHQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvc210cC9TTVRQVXRmOFRlc3QuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvc210cC9TTVRQVXRmOFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wN2QyMzg2Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9zbXRwL1NNVFBVdGY4VGVzdC5qYXZhCkBAIC0wLDAgKzEsMjY0IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDA5LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5zbXRwOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKK2ltcG9ydCBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyOworCitpbXBvcnQgamF2YXgubWFpbC5TZXNzaW9uOworaW1wb3J0IGphdmF4Lm1haWwuTWVzc2FnZTsKK2ltcG9ydCBqYXZheC5tYWlsLlRyYW5zcG9ydDsKK2ltcG9ydCBqYXZheC5tYWlsLkF1dGhlbnRpY2F0aW9uRmFpbGVkRXhjZXB0aW9uOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuSW50ZXJuZXRBZGRyZXNzOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuTWltZU1lc3NhZ2U7CisKK2ltcG9ydCBjb20uc3VuLm1haWwudGVzdC5UZXN0U2VydmVyOworCitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VHJ1ZTsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRFcXVhbHM7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuZmFpbDsKKworLyoqCisgKiBUZXN0IFVURi04IHVzZXIgbmFtZXMgYW5kIHJlY2lwaWVudHMuCisgKi8KK3B1YmxpYyBjbGFzcyBTTVRQVXRmOFRlc3QgeworCisgICAgLyoqCisgICAgICogVGVzdCB1c2luZyBVVEYtOCB1c2VyIG5hbWUuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXRmOFVzZXJOYW1lKCkgeworICAgICAgICBUZXN0U2VydmVyIHNlcnZlciA9IG51bGw7CisJZmluYWwgU3RyaW5nIHVzZXIgPSAidGVzdFx1MDNiMSI7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzZXJ2ZXIgPSBuZXcgVGVzdFNlcnZlcihuZXcgU01UUExvZ2luSGFuZGxlcigpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIGF1dGgoU3RyaW5nIGxpbmUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJCSAgICB1c2VybmFtZSA9IHVzZXI7CisJCSAgICBwYXNzd29yZCA9IHVzZXI7CisJCSAgICBzdXBlci5hdXRoKGxpbmUpOworCQl9CisJICAgIH0pOworICAgICAgICAgICAgc2VydmVyLnN0YXJ0KCk7CisKKyAgICAgICAgICAgIFByb3BlcnRpZXMgcHJvcGVydGllcyA9IG5ldyBQcm9wZXJ0aWVzKCk7CisgICAgICAgICAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLnNtdHAuaG9zdCIsICJsb2NhbGhvc3QiKTsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuc210cC5wb3J0IiwgIiIgKyBzZXJ2ZXIuZ2V0UG9ydCgpKTsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuc210cC5hdXRoLm1lY2hhbmlzbXMiLCAiTE9HSU4iKTsKKwkgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5taW1lLmFsbG93dXRmOCIsICAidHJ1ZSIpOworICAgICAgICAgICAgLy9wcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLmRlYnVnLmF1dGgiLCAidHJ1ZSIpOworICAgICAgICAgICAgU2Vzc2lvbiBzZXNzaW9uID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShwcm9wZXJ0aWVzKTsKKyAgICAgICAgICAgIC8vc2Vzc2lvbi5zZXREZWJ1Zyh0cnVlKTsKKworICAgICAgICAgICAgVHJhbnNwb3J0IHQgPSBzZXNzaW9uLmdldFRyYW5zcG9ydCgic210cCIpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB0LmNvbm5lY3QodXNlciwgdXNlcik7CisJCS8vIHN1Y2Nlc3MhCisJICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCQlmYWlsKGV4LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICB0LmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoc2VydmVyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBzZXJ2ZXIucXVpdCgpOworCQlzZXJ2ZXIuaW50ZXJydXB0KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHVzaW5nIFVURi04IHVzZXIgbmFtZSBidXQgd2l0aG91dCBtYWlsLm1pbWUuYWxsb3d1dGY4LgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFV0ZjhVc2VyTmFtZU5vQWxsb3dVdGY4KCkgeworICAgICAgICBUZXN0U2VydmVyIHNlcnZlciA9IG51bGw7CisJZmluYWwgU3RyaW5nIHVzZXIgPSAidGVzdFx1MDNiMSI7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzZXJ2ZXIgPSBuZXcgVGVzdFNlcnZlcihuZXcgU01UUExvZ2luSGFuZGxlcigpIHsKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIGF1dGgoU3RyaW5nIGxpbmUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJCSAgICB1c2VybmFtZSA9IHVzZXI7CisJCSAgICBwYXNzd29yZCA9IHVzZXI7CisJCSAgICBzdXBlci5hdXRoKGxpbmUpOworCQl9CisJICAgIH0pOworICAgICAgICAgICAgc2VydmVyLnN0YXJ0KCk7CisKKyAgICAgICAgICAgIFByb3BlcnRpZXMgcHJvcGVydGllcyA9IG5ldyBQcm9wZXJ0aWVzKCk7CisgICAgICAgICAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLnNtdHAuaG9zdCIsICJsb2NhbGhvc3QiKTsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuc210cC5wb3J0IiwgIiIgKyBzZXJ2ZXIuZ2V0UG9ydCgpKTsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuc210cC5hdXRoLm1lY2hhbmlzbXMiLCAiTE9HSU4iKTsKKyAgICAgICAgICAgIC8vcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5kZWJ1Zy5hdXRoIiwgInRydWUiKTsKKyAgICAgICAgICAgIFNlc3Npb24gc2Vzc2lvbiA9IFNlc3Npb24uZ2V0SW5zdGFuY2UocHJvcGVydGllcyk7CisgICAgICAgICAgICAvL3Nlc3Npb24uc2V0RGVidWcodHJ1ZSk7CisKKyAgICAgICAgICAgIFRyYW5zcG9ydCB0ID0gc2Vzc2lvbi5nZXRUcmFuc3BvcnQoInNtdHAiKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgdC5jb25uZWN0KHVzZXIsIHVzZXIpOworCQkvLyBzdWNjZXNzIQorCSAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKwkJZmFpbChleC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgdC5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgIGZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKHNlcnZlciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgc2VydmVyLnF1aXQoKTsKKwkJc2VydmVyLmludGVycnVwdCgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB1c2luZyBVVEYtOCB1c2VyIG5hbWUgYW5kIFBMQUlOIGJ1dCB3aXRob3V0IG1haWwubWltZS5hbGxvd3V0ZjguCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VXRmOFVzZXJOYW1lUGxhaW4oKSB7CisgICAgICAgIFRlc3RTZXJ2ZXIgc2VydmVyID0gbnVsbDsKKwlmaW5hbCBTdHJpbmcgdXNlciA9ICJ0ZXN0XHUwM2IxIjsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHNlcnZlciA9IG5ldyBUZXN0U2VydmVyKG5ldyBTTVRQTG9naW5IYW5kbGVyKCkgeworCQlAT3ZlcnJpZGUKKwkJcHVibGljIHZvaWQgYXV0aChTdHJpbmcgbGluZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkJICAgIHVzZXJuYW1lID0gdXNlcjsKKwkJICAgIHBhc3N3b3JkID0gdXNlcjsKKwkJICAgIHN1cGVyLmF1dGgobGluZSk7CisJCX0KKwkgICAgfSk7CisgICAgICAgICAgICBzZXJ2ZXIuc3RhcnQoKTsKKworICAgICAgICAgICAgUHJvcGVydGllcyBwcm9wZXJ0aWVzID0gbmV3IFByb3BlcnRpZXMoKTsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuc210cC5ob3N0IiwgImxvY2FsaG9zdCIpOworICAgICAgICAgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5zbXRwLnBvcnQiLCAiIiArIHNlcnZlci5nZXRQb3J0KCkpOworICAgICAgICAgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5zbXRwLmF1dGgubWVjaGFuaXNtcyIsICJQTEFJTiIpOworICAgICAgICAgICAgLy9wcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLmRlYnVnLmF1dGgiLCAidHJ1ZSIpOworICAgICAgICAgICAgU2Vzc2lvbiBzZXNzaW9uID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShwcm9wZXJ0aWVzKTsKKyAgICAgICAgICAgIC8vc2Vzc2lvbi5zZXREZWJ1Zyh0cnVlKTsKKworICAgICAgICAgICAgVHJhbnNwb3J0IHQgPSBzZXNzaW9uLmdldFRyYW5zcG9ydCgic210cCIpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB0LmNvbm5lY3QodXNlciwgdXNlcik7CisJCS8vIHN1Y2Nlc3MhCisJICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCQlmYWlsKGV4LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICB0LmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoc2VydmVyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBzZXJ2ZXIucXVpdCgpOworCQlzZXJ2ZXIuaW50ZXJydXB0KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBFbnZlbG9wZSB7CisJcHVibGljIFN0cmluZyBmcm9tOworCXB1YmxpYyBTdHJpbmcgdG87CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB1c2luZyBVVEYtOCBGcm9tIGFuZCBUbyBhZGRyZXNzLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFV0ZjhGcm9tKCkgeworICAgICAgICBUZXN0U2VydmVyIHNlcnZlciA9IG51bGw7CisJZmluYWwgU3RyaW5nIHRlc3QgPSAidGVzdFx1MDNiMSI7CisJZmluYWwgU3RyaW5nIHNhZGRyID0gdGVzdCArICJAIiArIHRlc3QgKyAiLmNvbSI7CisJZmluYWwgRW52ZWxvcGUgZW52ID0gbmV3IEVudmVsb3BlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzZXJ2ZXIgPSBuZXcgVGVzdFNlcnZlcihuZXcgU01UUEhhbmRsZXIoKSB7CisJCUBPdmVycmlkZQorCQlwdWJsaWMgdm9pZCBlaGxvKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkJICAgIHByaW50bG4oIjI1MC1oZWxsbyIpOworCQkgICAgcHJpbnRsbigiMjUwLVNNVFBVVEY4Iik7CisJCSAgICBwcmludGxuKCIyNTAgQVVUSCBQTEFJTiIpOworCQl9CisKKwkJQE92ZXJyaWRlCisJCXB1YmxpYyB2b2lkIG1haWwoU3RyaW5nIGxpbmUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJCSAgICBTdHJpbmdUb2tlbml6ZXIgc3QgPSBuZXcgU3RyaW5nVG9rZW5pemVyKGxpbmUpOworCQkgICAgc3QubmV4dFRva2VuKCk7CS8vIHNraXAgIk1BSUwiCisJCSAgICBlbnYuZnJvbSA9IHN0Lm5leHRUb2tlbigpLgorCQkJCSAgICByZXBsYWNlRmlyc3QoIkZST006PCguKik+IiwgIiQxIik7CisJCSAgICBpZiAoIXN0Lmhhc01vcmVUb2tlbnMoKSB8fAorCQkJICAgICFzdC5uZXh0VG9rZW4oKS5lcXVhbHMoIlNNVFBVVEY4IikpCisJCQlwcmludGxuKCI1MDAgZmFpbCIpOworCQkgICAgZWxzZQorCQkJb2soKTsKKwkJfQorCisJCUBPdmVycmlkZQorCQlwdWJsaWMgdm9pZCByY3B0KFN0cmluZyBsaW5lKSB0aHJvd3MgSU9FeGNlcHRpb24geworCQkgICAgU3RyaW5nVG9rZW5pemVyIHN0ID0gbmV3IFN0cmluZ1Rva2VuaXplcihsaW5lKTsKKwkJICAgIHN0Lm5leHRUb2tlbigpOwkvLyBza2lwICJSQ1BUIgorCQkgICAgZW52LnRvID0gc3QubmV4dFRva2VuKCkuCisJCQkJICAgIHJlcGxhY2VGaXJzdCgiVE86PCguKik+IiwgIiQxIik7CisJCSAgICBvaygpOworCQl9CisJICAgIH0pOworICAgICAgICAgICAgc2VydmVyLnN0YXJ0KCk7CisKKyAgICAgICAgICAgIFByb3BlcnRpZXMgcHJvcGVydGllcyA9IG5ldyBQcm9wZXJ0aWVzKCk7CisgICAgICAgICAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLnNtdHAuaG9zdCIsICJsb2NhbGhvc3QiKTsKKyAgICAgICAgICAgIHByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuc210cC5wb3J0IiwgIiIgKyBzZXJ2ZXIuZ2V0UG9ydCgpKTsKKwkgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5taW1lLmFsbG93dXRmOCIsICAidHJ1ZSIpOworICAgICAgICAgICAgLy9wcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLmRlYnVnLmF1dGgiLCAidHJ1ZSIpOworICAgICAgICAgICAgU2Vzc2lvbiBzZXNzaW9uID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShwcm9wZXJ0aWVzKTsKKyAgICAgICAgICAgIC8vc2Vzc2lvbi5zZXREZWJ1Zyh0cnVlKTsKKworICAgICAgICAgICAgVHJhbnNwb3J0IHQgPSBzZXNzaW9uLmdldFRyYW5zcG9ydCgic210cCIpOworICAgICAgICAgICAgdHJ5IHsKKwkJTWltZU1lc3NhZ2UgbXNnID0gbmV3IE1pbWVNZXNzYWdlKHNlc3Npb24pOworCQlJbnRlcm5ldEFkZHJlc3MgYWRkciA9IG5ldyBJbnRlcm5ldEFkZHJlc3Moc2FkZHIsIHRlc3QpOworCQltc2cuc2V0RnJvbShhZGRyKTsKKwkJbXNnLnNldFJlY2lwaWVudChNZXNzYWdlLlJlY2lwaWVudFR5cGUuVE8sIGFkZHIpOworCQltc2cuc2V0U3ViamVjdCh0ZXN0KTsKKwkJbXNnLnNldFRleHQodGVzdCArICJcbiIpOworICAgICAgICAgICAgICAgIHQuY29ubmVjdCgidGVzdCIsICJ0ZXN0Iik7CisJCXQuc2VuZE1lc3NhZ2UobXNnLCBtc2cuZ2V0QWxsUmVjaXBpZW50cygpKTsKKwkgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJCWZhaWwoZXgudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHQuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICBmYWlsKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChzZXJ2ZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHNlcnZlci5xdWl0KCk7CisJCXNlcnZlci5pbnRlcnJ1cHQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCS8vIGFmdGVyIHdlJ3JlIHN1cmUgdGhlIHNlcnZlciBpcyBkb25lCisJYXNzZXJ0RXF1YWxzKHNhZGRyLCBlbnYuZnJvbSk7CisJYXNzZXJ0RXF1YWxzKHNhZGRyLCBlbnYudG8pOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvc210cC9TTVRQV3JpdGVUaW1lb3V0VGVzdC5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9zbXRwL1NNVFBXcml0ZVRpbWVvdXRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDlmZDc1OQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvc210cC9TTVRQV3JpdGVUaW1lb3V0VGVzdC5qYXZhCkBAIC0wLDAgKzEsMTAyIEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDA5LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5zbXRwOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKKworaW1wb3J0IGphdmF4LmFjdGl2YXRpb24uRGF0YUhhbmRsZXI7CitpbXBvcnQgamF2YXgubWFpbC5TZXNzaW9uOworaW1wb3J0IGphdmF4Lm1haWwuVHJhbnNwb3J0OworaW1wb3J0IGphdmF4Lm1haWwuTWVzc2FnZTsKK2ltcG9ydCBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5tYWlsLmludGVybmV0Lk1pbWVNZXNzYWdlOworaW1wb3J0IGphdmF4Lm1haWwudXRpbC5CeXRlQXJyYXlEYXRhU291cmNlOworCitpbXBvcnQgY29tLnN1bi5tYWlsLnRlc3QuVGVzdFNlcnZlcjsKKworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5SdWxlOworaW1wb3J0IG9yZy5qdW5pdC5ydWxlcy5UaW1lb3V0OworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmZhaWw7CisKKy8qKgorICogVGVzdCB0aGF0IHdyaXRlIHRpbWVvdXRzIHdvcmsuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBTTVRQV3JpdGVUaW1lb3V0VGVzdCB7CisKKyAgICAvLyB0aW1lb3V0IHRoZSB0ZXN0IGluIGNhc2Ugb2YgZmFpbHVyZQorICAgIEBSdWxlCisgICAgcHVibGljIFRpbWVvdXQgZGVhZGxvY2tUaW1lb3V0ID0gVGltZW91dC5zZWNvbmRzKDEwKTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBUSU1FT1VUID0gMjAwOwkvLyB3cml0ZSB0aW1lb3V0LCBpbiBtaWxsaXMKKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBUZXN0U2VydmVyIHNlcnZlciA9IG51bGw7CisgICAgICAgIHRyeSB7CisJICAgIFNNVFBIYW5kbGVyIGhhbmRsZXIgPSBuZXcgU01UUEhhbmRsZXIoKSB7CisJCUBPdmVycmlkZQorCQlwdWJsaWMgdm9pZCByZWFkTWVzc2FnZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJCSAgICB0cnkgeworCQkJLy8gZGVsYXkgbG9uZyBlbm91Z2ggdG8gY2F1c2UgdGltZW91dAorCQkJVGhyZWFkLnNsZWVwKDUgKiBUSU1FT1VUKTsKKwkJICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeyB9CisJCSAgICBzdXBlci5yZWFkTWVzc2FnZSgpOworCQl9CisJICAgIH07CisgICAgICAgICAgICBzZXJ2ZXIgPSBuZXcgVGVzdFNlcnZlcihoYW5kbGVyKTsKKyAgICAgICAgICAgIHNlcnZlci5zdGFydCgpOworICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDEwMDApOworCisgICAgICAgICAgICBmaW5hbCBQcm9wZXJ0aWVzIHByb3BlcnRpZXMgPSBuZXcgUHJvcGVydGllcygpOworICAgICAgICAgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5zbXRwLmhvc3QiLCAibG9jYWxob3N0Iik7CisgICAgICAgICAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLnNtdHAucG9ydCIsICIiICsgc2VydmVyLmdldFBvcnQoKSk7CisgICAgICAgICAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLnNtdHAud3JpdGV0aW1lb3V0IiwgIiIgKyBUSU1FT1VUKTsKKyAgICAgICAgICAgIGZpbmFsIFNlc3Npb24gc2Vzc2lvbiA9IFNlc3Npb24uZ2V0SW5zdGFuY2UocHJvcGVydGllcyk7CisgICAgICAgICAgICAvL3Nlc3Npb24uc2V0RGVidWcodHJ1ZSk7CisKKyAgICAgICAgICAgIGZpbmFsIFRyYW5zcG9ydCB0ID0gc2Vzc2lvbi5nZXRUcmFuc3BvcnQoInNtdHAiKTsKKyAgICAgICAgICAgIHRyeSB7CisJCU1pbWVNZXNzYWdlIG1zZyA9IG5ldyBNaW1lTWVzc2FnZShzZXNzaW9uKTsKKwkJbXNnLnNldFJlY2lwaWVudHMoTWVzc2FnZS5SZWNpcGllbnRUeXBlLlRPLCAiam9lQGV4YW1wbGUuY29tIik7CisJCW1zZy5zZXRTdWJqZWN0KCJ0ZXN0Iik7CisJCWJ5dGVbXSBieXRlcyA9IG5ldyBieXRlWzE2KjEwMjQqMTAyNF07CisJCW1zZy5zZXREYXRhSGFuZGxlcigKKwkJICAgIG5ldyBEYXRhSGFuZGxlcihuZXcgQnl0ZUFycmF5RGF0YVNvdXJjZShieXRlcywKKwkJCQkgICAgImFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSIpKSk7CisgICAgICAgICAgICAgICAgdC5jb25uZWN0KCk7CisJCXQuc2VuZE1lc3NhZ2UobXNnLCBtc2cuZ2V0QWxsUmVjaXBpZW50cygpKTsKKwkJZmFpbCgiTm8gZXhjZXB0aW9uIik7CisJICAgIH0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBleCkgeworCQkvLyBleHBlY3QgYW4gZXhjZXB0aW9uIGZyb20gc2VuZE1lc3NhZ2UKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgdC5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChmaW5hbCBFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgIGZhaWwoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKHNlcnZlciAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgc2VydmVyLnF1aXQoKTsKKwkJc2VydmVyLmludGVycnVwdCgpOworCQkvLyB3YWl0IGxvbmcgZW5vdWdoIGZvciBoYW5kbGVyIHRvIGV4aXQKKwkJVGhyZWFkLnNsZWVwKDIgKiBUSU1FT1VUKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvdGVzdC9Bc2NpaVN0cmluZ0lucHV0U3RyZWFtLmphdmEgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3Rlc3QvQXNjaWlTdHJpbmdJbnB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM5Y2FmN2IKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3Rlc3QvQXNjaWlTdHJpbmdJbnB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsNTQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMTUsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLnRlc3Q7CisKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworCisvKioKKyAqIFJlcGxhY2VtZW50IGZvciBkZXByZWNhdGVkIGphdmEuaW8uU3RyaW5nQnVmZmVySW5wdXRTdHJlYW0KKyAqLworcHVibGljIGNsYXNzIEFzY2lpU3RyaW5nSW5wdXRTdHJlYW0gZXh0ZW5kcyBJbnB1dFN0cmVhbSB7CisKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBpbnB1dDsKKyAgICBwcml2YXRlIGludCBwb3NpdGlvbjsKKworICAgIHB1YmxpYyBBc2NpaVN0cmluZ0lucHV0U3RyZWFtKFN0cmluZyBpbnB1dCkgeworCXRoaXMoaW5wdXQsIHRydWUpOworICAgIH0KKworICAgIHB1YmxpYyBBc2NpaVN0cmluZ0lucHV0U3RyZWFtKFN0cmluZyBpbnB1dCwgYm9vbGVhbiBzdHJpY3QpIHsKKwlpZiAoc3RyaWN0KSB7CisJICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW5wdXQubGVuZ3RoKCk7IGkrKykgeworCQlpZiAoaW5wdXQuY2hhckF0KGkpID4gMHg3RikgeworCQkgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiTm90IGFuIEFTQ0lJIHN0cmluZyIpOworCQl9CisJICAgIH0KKwl9CisKKwl0aGlzLmlucHV0ID0gaW5wdXQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKCkgeworCWlmIChwb3NpdGlvbiA8IGlucHV0Lmxlbmd0aCgpKSB7CisJICAgIHJldHVybiBpbnB1dC5jaGFyQXQocG9zaXRpb24rKykgJiAweEZGOworCX0gZWxzZSB7CisJICAgIHJldHVybiAtMTsKKwl9CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3Rlc3QvQ2xhc3NMb2FkZXJTdWl0ZS5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC90ZXN0L0NsYXNzTG9hZGVyU3VpdGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jZWI0ODEzCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC90ZXN0L0NsYXNzTG9hZGVyU3VpdGUuamF2YQpAQCAtMCwwICsxLDIwNSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwOSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwudGVzdDsKKworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLio7CitpbXBvcnQgamF2YS5uZXQuVVJMOworaW1wb3J0IGphdmEubmV0Lk1hbGZvcm1lZFVSTEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5VUkxDbGFzc0xvYWRlcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworCitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lcnMuU3VpdGU7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lcnMuUGFyZW50UnVubmVyOworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXJzLm1vZGVsLkluaXRpYWxpemF0aW9uRXJyb3I7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lcnMubW9kZWwuUnVubmVyQnVpbGRlcjsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVyLlJ1bm5lcjsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVyLm5vdGlmaWNhdGlvbi5SdW5Ob3RpZmllcjsKKworLyoqCisgKiBBIHNwZWNpYWwgdGVzdCBzdWl0ZSB0aGF0IGxvYWRzIGVhY2ggb2YgdGhlIHRlc3QgY2xhc3NlcworICogaW4gYSBzZXBhcmF0ZSBjbGFzcyBsb2FkZXIsIGFsb25nIHdpdGggdGhlIGNsYXNzIHVuZGVyIHRlc3QuCisgKiBUaGlzIGFsbG93cyB0aGUgdGVzdHMgdG8gdGVzdCBtZXRob2RzIHdob3NlIGJlaGF2aW9yIGRlcGVuZHMgb24KKyAqIHRoZSB2YWx1ZSBvZiBhIFN5c3RlbSBwcm9wZXJ0eSB0aGF0J3MgcmVhZCBhdCBjbGFzcyBpbml0aWFsaXphdGlvbgorICogdGltZTsgZWFjaCB0ZXN0IGNhbiBzZXQgYSBkaWZmZXJlbnQgdmFsdWUgb2YgdGhlIFN5c3RlbSBwcm9wZXJ0eQorICogYW5kIHRoZSBjb3JyZXNwb25kaW5nIGNsYXNzIHVuZGVyIHRlc3Qgd2lsbCBiZSBsb2FkZWQgaW4gYQorICogc2VwYXJhdGUgY2xhc3MgbG9hZGVyLiA8cD4KKyAqCisgKiBUbyB1c2UgdGhpcyBjbGFzcywgY3JlYXRlIGEgdGVzdCBzdWl0ZSBjbGFzczoKKyAqCisgKiA8cHJlPgorICogQFJ1bldpdGgoQ2xhc3NMb2FkZXJTdWl0ZS5jbGFzcykKKyAqIEBTdWl0ZUNsYXNzZXMoeyBNeVRlc3QxLmNsYXNzLCBNeVRlc3QyLmNsYXNzIH0pCisgKiBAVGVzdENsYXNzKENsYXNzVG9UZXN0LmNsYXNzKQorICogcHVibGljIGNsYXNzIE15VGVzdFN1aXRlIHsKKyAqIH0KKyAqIDwvcHJlPgorICoKKyAqIFRoZSBNeVRlc3QxIGFuZCBNeVRlc3QyIGNsYXNzZXMgYXJlIHdyaXR0ZW4gYXMgbm9ybWFsIEpVbml0CisgKiB0ZXN0IGNsYXNzZXMuICBTZXQgdGhlIFN5c3RlbSBwcm9wZXJ0eSB0byB0ZXN0IGluIHRoZSBAQmVmb3JlQ2xhc3MKKyAqIG1ldGhvZCBvZiB0aGVzZSBjbGFzc2VzLgorICoKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKi8KKworcHVibGljIGNsYXNzIENsYXNzTG9hZGVyU3VpdGUgZXh0ZW5kcyBTdWl0ZSB7CisgICAgLyoqCisgICAgICogQW4gYW5ub3RhdGlvbiB0byBiZSB1c2VkIG9uIHRoZSB0ZXN0IHN1aXRlIGNsYXNzIHRvIGluZGljYXRlCisgICAgICogdGhlIGNsYXNzIHVuZGVyIHRlc3QuICBUaGUgY2xhc3MgaXMgdXNlZCB0byBmaW5kIHRoZSBjbGFzc3BhdGgKKyAgICAgKiB0byBhbGxvdyBsb2FkaW5nIHRoZSBjbGFzcyB1bmRlciB0ZXN0IGluIGEgc2VwYXJhdGUgY2xhc3MgbG9hZGVyLgorICAgICAqIE5vdGUgdGhhdCBvdGhlciBjbGFzc2VzIGluIHRoZSBzYW1lIGNsYXNzcGF0aCB3aWxsIGFsc28gYmUgbG9hZGVkCisgICAgICogaW4gdGhlIHNlcGFyYXRlIGNsYXNzIGxvYWRlciwgYWxvbmcgd2l0aCB0aGUgdGVzdCBjbGFzc2VzLgorICAgICAqLworICAgIEBSZXRlbnRpb24oUmV0ZW50aW9uUG9saWN5LlJVTlRJTUUpCisgICAgQFRhcmdldChFbGVtZW50VHlwZS5UWVBFKQorICAgIEBJbmhlcml0ZWQKKyAgICBwdWJsaWMgQGludGVyZmFjZSBUZXN0Q2xhc3MgeworCXB1YmxpYyBDbGFzczw/PiB2YWx1ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEEgc3BlY2lhbCBjbGFzcyBsb2FkZXIgdGhhdCBsb2FkcyBjbGFzc2VzIGZyb20gaXRzIG93biBjbGFzcyBwYXRoCisgICAgICogKHNwZWNpZmllZCB2aWEgVVJMcykgYmVmb3JlIGRlbGVnYXRpbmcgdG8gdGhlIHBhcmVudCBjbGFzcyBsb2FkZXIuCisgICAgICogVGhpcyBpcyB1c2VkIHRvIGxvYWQgdGhlIHRlc3QgY2xhc3NlcyBpbiBzZXBhcmF0ZSBjbGFzcyBsb2FkZXJzLAorICAgICAqIGV2ZW4gdGhvdWdoIHRob3NlIGNsYXNzZXMgYXJlIGFsc28gbG9hZGVkIGluIHRoZSBwYXJlbnQgY2xhc3MgbG9hZGVyLgorICAgICAqLworICAgIHN0YXRpYyBjbGFzcyBUZXN0Q2xhc3NMb2FkZXIgZXh0ZW5kcyBVUkxDbGFzc0xvYWRlciB7CisJcHVibGljIFRlc3RDbGFzc0xvYWRlcihVUkxbXSB1cmxzLCBDbGFzc0xvYWRlciBwYXJlbnQpIHsKKwkgICAgc3VwZXIodXJscywgcGFyZW50KTsKKwl9CisKKwlAT3ZlcnJpZGUKKwlwdWJsaWMgQ2xhc3M8Pz4gbG9hZENsYXNzKFN0cmluZyBuYW1lLCBib29sZWFuIHJlc29sdmUpCisJCQkJICAgIHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKwkgICAgQ2xhc3M8Pz4gYyA9IG51bGw7CisJICAgIHRyeSB7CisJCWMgPSBmaW5kTG9hZGVkQ2xhc3MobmFtZSk7CisJCWlmIChjICE9IG51bGwpCisJCSAgICByZXR1cm4gYzsKKwkJYyA9IGZpbmRDbGFzcyhuYW1lKTsKKwkJaWYgKHJlc29sdmUpCisJCSAgICByZXNvbHZlQ2xhc3MoYyk7CisJICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gY2V4KSB7CisJCWMgPSBzdXBlci5sb2FkQ2xhc3MobmFtZSwgcmVzb2x2ZSk7CisJICAgIH0KKwkgICAgcmV0dXJuIGM7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yLgorICAgICAqLworICAgIHB1YmxpYyBDbGFzc0xvYWRlclN1aXRlKENsYXNzPD8+IGtsYXNzLCBSdW5uZXJCdWlsZGVyIGJ1aWxkZXIpCisJCQkJdGhyb3dzIEluaXRpYWxpemF0aW9uRXJyb3IgeworCXN1cGVyKGJ1aWxkZXIsIGtsYXNzLAorCSAgICByZWxvYWRDbGFzc2VzKGdldFRlc3RDbGFzcyhrbGFzcyksIGdldFN1aXRlQ2xhc3NlcyhrbGFzcykpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHRocmVhZCdzIGNvbnRleHQgY2xhc3MgbG9hZGVyIHRvIHRoZSBjbGFzcyBsb2FkZXIKKyAgICAgKiBmb3IgdGhlIHRlc3QgY2xhc3MuCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgcnVuQ2hpbGQoUnVubmVyIHJ1bm5lciwgUnVuTm90aWZpZXIgbm90aWZpZXIpIHsKKwkvLyBYWFggLSBpcyBpdCBzYWZlIHRvIGFzc3VtZSBpdCdzIGFsd2F5cyBhIFBhcmVudFJ1bm5lcj8KKwlQYXJlbnRSdW5uZXI8Pz4gcHIgPSAoUGFyZW50UnVubmVyPD8+KXJ1bm5lcjsKKwlDbGFzc0xvYWRlciBjbCA9IG51bGw7CisJdHJ5IHsKKwkgICAgY2wgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpLmdldENvbnRleHRDbGFzc0xvYWRlcigpOworCSAgICBUaHJlYWQuY3VycmVudFRocmVhZCgpLnNldENvbnRleHRDbGFzc0xvYWRlcigKKwkJcHIuZ2V0VGVzdENsYXNzKCkuZ2V0SmF2YUNsYXNzKCkuZ2V0Q2xhc3NMb2FkZXIoKSk7CisJICAgIHN1cGVyLnJ1bkNoaWxkKHJ1bm5lciwgbm90aWZpZXIpOworCX0gZmluYWxseSB7CisJICAgIFRocmVhZC5jdXJyZW50VGhyZWFkKCkuc2V0Q29udGV4dENsYXNzTG9hZGVyKGNsKTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSB2YWx1ZSBvZiB0aGUgU3VpdGVDbGFzc2VzIGFubm90YXRpb24uCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgQ2xhc3M8Pz5bXSBnZXRTdWl0ZUNsYXNzZXMoQ2xhc3M8Pz4ga2xhc3MpCisJCQkJdGhyb3dzIEluaXRpYWxpemF0aW9uRXJyb3IgeworCVN1aXRlQ2xhc3NlcyBhbm5vdGF0aW9uID0ga2xhc3MuZ2V0QW5ub3RhdGlvbihTdWl0ZUNsYXNzZXMuY2xhc3MpOworCWlmIChhbm5vdGF0aW9uID09IG51bGwpCisJICAgIHRocm93IG5ldyBJbml0aWFsaXphdGlvbkVycm9yKCJjbGFzcyAnIiArIGtsYXNzLmdldE5hbWUoKSArCisJCSInIG11c3QgaGF2ZSBhIFN1aXRlQ2xhc3NlcyBhbm5vdGF0aW9uIik7CisJcmV0dXJuIGFubm90YXRpb24udmFsdWUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIHZhbHVlIG9mIHRoZSBUZXN0Q2xhc3MgYW5ub3RhdGlvbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBDbGFzczw/PiBnZXRUZXN0Q2xhc3MoQ2xhc3M8Pz4ga2xhc3MpCisJCQkJdGhyb3dzIEluaXRpYWxpemF0aW9uRXJyb3IgeworCVRlc3RDbGFzcyBhbm5vdGF0aW9uID0ga2xhc3MuZ2V0QW5ub3RhdGlvbihUZXN0Q2xhc3MuY2xhc3MpOworCWlmIChhbm5vdGF0aW9uID09IG51bGwpCisJICAgIHRocm93IG5ldyBJbml0aWFsaXphdGlvbkVycm9yKCJjbGFzcyAnIiArIGtsYXNzLmdldE5hbWUoKSArCisJCSInIG11c3QgaGF2ZSBhIFRlc3RDbGFzcyBhbm5vdGF0aW9uIik7CisJcmV0dXJuIGFubm90YXRpb24udmFsdWUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWxvYWQgdGhlIGNsYXNzZXMgaW4gYSBzZXBhcmF0ZSBjbGFzcyBsb2FkZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgQ2xhc3M8Pz5bXSByZWxvYWRDbGFzc2VzKENsYXNzPD8+IHRlc3RDbGFzcywKKwkJCUNsYXNzPD8+W10gc3VpdGVDbGFzc2VzKSB0aHJvd3MgSW5pdGlhbGl6YXRpb25FcnJvciB7CisJVVJMW10gdXJscyA9IG5ldyBVUkxbXSB7CisJICAgIGNsYXNzcGF0aE9mKHRlc3RDbGFzcyksCisJICAgIGNsYXNzcGF0aE9mKENsYXNzTG9hZGVyU3VpdGUuY2xhc3MpCisJfTsKKwlDbGFzczw/PiBzYyA9IG51bGw7CisJdHJ5IHsKKwkgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzdWl0ZUNsYXNzZXMubGVuZ3RoOyBpKyspIHsKKwkJc2MgPSBzdWl0ZUNsYXNzZXNbaV07CisJCUNsYXNzTG9hZGVyIGNsID0gbmV3IFRlc3RDbGFzc0xvYWRlcih1cmxzLAorCQkgICAgQ2xhc3NMb2FkZXJTdWl0ZS5jbGFzcy5nZXRDbGFzc0xvYWRlcigpKTsKKwkJc3VpdGVDbGFzc2VzW2ldID0gY2wubG9hZENsYXNzKHNjLmdldE5hbWUoKSk7CisJICAgIH0KKwkgICAgcmV0dXJuIHN1aXRlQ2xhc3NlczsKKwl9IGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGNleCkgeworCSAgICB0aHJvdyBuZXcgSW5pdGlhbGl6YXRpb25FcnJvcigiY291bGQgbm90IHJlbG9hZCBjbGFzczogIiArIHNjKTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBjbGFzc3BhdGggZW50cnkgdXNlZCB0byBsb2FkIHRoZSBuYW1lZCByZXNvdXJjZS4KKyAgICAgKiBYWFggLSBPbmx5IGhhbmRsZXMgZmlsZTogYW5kIGphcjogVVJMcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBVUkwgY2xhc3NwYXRoT2YoQ2xhc3M8Pz4gYykgeworCVN0cmluZyBuYW1lID0gIi8iICsgYy5nZXROYW1lKCkucmVwbGFjZSgnLicsICcvJykgKyAiLmNsYXNzIjsKKwl0cnkgeworCSAgICBVUkwgdXJsID0gQ2xhc3NMb2FkZXJTdWl0ZS5jbGFzcy5nZXRSZXNvdXJjZShuYW1lKTsKKwkgICAgaWYgKHVybC5nZXRQcm90b2NvbCgpLmVxdWFscygiZmlsZSIpKSB7CisJCVN0cmluZyBmaWxlID0gdXJsLmdldFBhdGgoKTsKKwkJaWYgKGZpbGUuZW5kc1dpdGgobmFtZSkpCS8vIGhhcyB0byBiZSB0cnVlPworCQkgICAgZmlsZSA9IGZpbGUuc3Vic3RyaW5nKDAsIGZpbGUubGVuZ3RoKCkgLSBuYW1lLmxlbmd0aCgpICsgMSk7CisvL1N5c3RlbS5vdXQucHJpbnRsbigiZmlsZSBVUkwgIiArIHVybCArICIgaGFzIENMQVNTUEFUSCAiICsgZmlsZSk7CisJCXJldHVybiBuZXcgVVJMKCJmaWxlIiwgbnVsbCwgZmlsZSk7CisJICAgIH0gZWxzZSBpZiAodXJsLmdldFByb3RvY29sKCkuZXF1YWxzKCJqYXIiKSkgeworCQlTdHJpbmcgZmlsZSA9IHVybC5nZXRQYXRoKCk7CisJCWludCBpID0gZmlsZS5sYXN0SW5kZXhPZignIScpOworCQlpZiAoaSA+PSAwKQorCQkgICAgZmlsZSA9IGZpbGUuc3Vic3RyaW5nKDAsIGkpOworLy9TeXN0ZW0ub3V0LnByaW50bG4oImphciBVUkwgIiArIHVybCArICIgaGFzIENMQVNTUEFUSCAiICsgZmlsZSk7CisJCXJldHVybiBuZXcgVVJMKGZpbGUpOworCSAgICB9IGVsc2UKKwkJcmV0dXJuIHVybDsKKwl9IGNhdGNoIChNYWxmb3JtZWRVUkxFeGNlcHRpb24gbWV4KSB7CisJICAgIHJldHVybiBudWxsOworCX0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3Rlc3QvTnVsbE91dHB1dFN0cmVhbS5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC90ZXN0L051bGxPdXRwdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNzhmYzg3Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC90ZXN0L051bGxPdXRwdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDM3IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDA5LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC50ZXN0OworCitpbXBvcnQgamF2YS5pby4qOworCisvKioKKyAqIEFuIE91dHB1dFN0cmVhbSB0aGF0IHRocm93cyBhd2F5IGFsbCBkYXRhIHdyaXR0ZW4gdG8gaXQuCisgKi8KK3B1YmxpYyBjbGFzcyBOdWxsT3V0cHV0U3RyZWFtIGV4dGVuZHMgT3V0cHV0U3RyZWFtIHsKKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGludCBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGJ5dGVbXSBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvdGVzdC9Qcm90b2NvbEhhbmRsZXIuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvdGVzdC9Qcm90b2NvbEhhbmRsZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40MzRmZjBhCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC90ZXN0L1Byb3RvY29sSGFuZGxlci5qYXZhCkBAIC0wLDAgKzEsMTc2IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDA5LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC50ZXN0OworCitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5QdXNoYmFja0lucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbVJlYWRlcjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbVdyaXRlcjsKK2ltcG9ydCBqYXZhLmlvLlByaW50V3JpdGVyOworaW1wb3J0IGphdmEubmV0LlNvY2tldDsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXRFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5TdGFuZGFyZENoYXJzZXRzOworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkxvZ2dlcjsKK2ltcG9ydCBqYXZhLnV0aWwubG9nZ2luZy5MZXZlbDsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLlNTTEV4Y2VwdGlvbjsKKworLyoqCisgKiBIYW5kbGUgcHJvdG9jb2wgY29ubmVjdGlvbi4KKyAqCisgKiBJbnNwaXJlZCBieSwgYW5kIGRlcml2ZWQgZnJvbSwgUE9QM0hhbmRsZXIgYnkgc2JvLgorICoKKyAqIEBhdXRob3Igc2JvCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgUHJvdG9jb2xIYW5kbGVyIGltcGxlbWVudHMgUnVubmFibGUsIENsb25lYWJsZSB7CisKKyAgICAvKiogTG9nZ2VyIGZvciB0aGlzIGNsYXNzLiAqLworICAgIHByb3RlY3RlZCBmaW5hbCBMb2dnZXIgTE9HR0VSID0gTG9nZ2VyLmdldExvZ2dlcih0aGlzLmdldENsYXNzKCkuZ2V0TmFtZSgpKTsKKworICAgIC8qKiBDbGllbnQgc29ja2V0LiAqLworICAgIHByb3RlY3RlZCBTb2NrZXQgY2xpZW50U29ja2V0OworCisgICAgLyoqIFF1aXQ/ICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gcXVpdDsKKworICAgIC8qKiBXcml0ZXIgdG8gc29ja2V0LiAqLworICAgIHByb3RlY3RlZCBQcmludFdyaXRlciB3cml0ZXI7CisKKyAgICAvKiogSW5wdXQgZnJvbSBzb2NrZXQuICovCisgICAgcHJvdGVjdGVkIElucHV0U3RyZWFtIGluOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgY2xpZW50IHNvY2tldC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjbGllbnRTb2NrZXQJdGhlIGNsaWVudCBzb2NrZXQKKyAgICAgKi8KKyAgICBwdWJsaWMgZmluYWwgdm9pZCBzZXRDbGllbnRTb2NrZXQoZmluYWwgU29ja2V0IGNsaWVudFNvY2tldCkKKwkJCQl0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzLmNsaWVudFNvY2tldCA9IGNsaWVudFNvY2tldDsKKwl3cml0ZXIgPSBuZXcgUHJpbnRXcml0ZXIobmV3IE91dHB1dFN0cmVhbVdyaXRlcigKKwkJICAgIGNsaWVudFNvY2tldC5nZXRPdXRwdXRTdHJlYW0oKSwgU3RhbmRhcmRDaGFyc2V0cy5VVEZfOCkpOworCWluID0gbmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0oY2xpZW50U29ja2V0LmdldElucHV0U3RyZWFtKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIE9wdGlvbmFsbHkgc2VuZCBhIGdyZWV0aW5nIHdoZW4gZmlyc3QgY29ubmVjdGVkLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNlbmRHcmVldGluZ3MoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWQgYW5kIHByb2Nlc3MgYSBzaW5nbGUgY29tbWFuZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBoYW5kbGVDb21tYW5kKCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmVhZCBhIHNpbmdsZSBsaW5lIHRlcm1pbmF0ZWQgYnkgbmV3bGluZSBvciBDUkxGLgorICAgICAqIENvbnZlcnQgdGhlIFVURi04IGJ5dGVzIGluIHRoZSBsaW5lIChtaW51cyB0aGUgbGluZSB0ZXJtaW5hdG9yKQorICAgICAqIHRvIGEgU3RyaW5nLgorICAgICAqLworICAgIHByb3RlY3RlZCBTdHJpbmcgcmVhZExpbmUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBieXRlW10gYnVmID0gbmV3IGJ5dGVbMTI4XTsKKworICAgICAgICBpbnQgcm9vbSA9IGJ1Zi5sZW5ndGg7CisgICAgICAgIGludCBvZmZzZXQgPSAwOworICAgICAgICBpbnQgYzsKKworCXdoaWxlICgoYyA9IGluLnJlYWQoKSkgIT0gLTEpIHsKKwkgICAgaWYgKGMgPT0gJ1xuJykgeworCQlicmVhazsKKwkgICAgfSBlbHNlIGlmIChjID09ICdccicpIHsKKwkJaW50IGMyID0gaW4ucmVhZCgpOworCQlpZiAoKGMyICE9ICdcbicpICYmIChjMiAhPSAtMSkpIHsKKwkJICAgIGlmICghKGluIGluc3RhbmNlb2YgUHVzaGJhY2tJbnB1dFN0cmVhbSkpCisJCQl0aGlzLmluID0gbmV3IFB1c2hiYWNrSW5wdXRTdHJlYW0oaW4pOworCQkgICAgKChQdXNoYmFja0lucHV0U3RyZWFtKWluKS51bnJlYWQoYzIpOworCQl9CisJCWJyZWFrOworCSAgICB9IGVsc2UgeworCQlpZiAoLS1yb29tIDwgMCkgeworCQkgICAgYnl0ZVtdIG5idWYgPSBuZXcgYnl0ZVtvZmZzZXQgKyAxMjhdOworCQkgICAgcm9vbSA9IG5idWYubGVuZ3RoIC0gb2Zmc2V0IC0gMTsKKwkJICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmLCAwLCBuYnVmLCAwLCBvZmZzZXQpOworCQkgICAgYnVmID0gbmJ1ZjsKKwkJfQorCQlidWZbb2Zmc2V0KytdID0gKGJ5dGUpYzsKKwkgICAgfQorCX0KKwlpZiAoKGMgPT0gLTEpICYmIChvZmZzZXQgPT0gMCkpCisJICAgIHJldHVybiBudWxsOworCXJldHVybiBuZXcgU3RyaW5nKGJ1ZiwgMCwgb2Zmc2V0LCBTdGFuZGFyZENoYXJzZXRzLlVURl84KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGZpbmFsIHZvaWQgcnVuKCkgeworICAgICAgICB0cnkgeworCisgICAgICAgICAgICBzZW5kR3JlZXRpbmdzKCk7CisKKyAgICAgICAgICAgIHdoaWxlICghcXVpdCkgeworICAgICAgICAgICAgICAgIGhhbmRsZUNvbW1hbmQoKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy9jbGllbnRTb2NrZXQuY2xvc2UoKTsKKwl9IGNhdGNoIChTb2NrZXRFeGNlcHRpb24gc2V4KSB7CisJICAgIC8vIGlnbm9yZSBpdCwgb2Z0ZW4gZ2V0ICJjb25uZWN0aW9uIHJlc2V0IiB3aGVuIGNsaWVudCBjbG9zZXMKKwl9IGNhdGNoIChTU0xFeGNlcHRpb24gc2V4KSB7CisJICAgIC8vIGlnbm9yZSBpdCwgb2Z0ZW4gb2NjdXJzIHdoZW4gdGVzdGluZyBTU0wKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIExPR0dFUi5sb2coTGV2ZWwuU0VWRVJFLCAiRXJyb3IiLCBlKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRyeSB7CisJCWlmIChjbGllbnRTb2NrZXQgIT0gbnVsbCkKKwkJICAgIGNsaWVudFNvY2tldC5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgSU9FeGNlcHRpb24gaW9lKSB7CisgICAgICAgICAgICAgICAgTE9HR0VSLmxvZyhMZXZlbC5TRVZFUkUsICJFcnJvciIsIGlvZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBRdWl0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGV4aXQoKSB7CisgICAgICAgIHF1aXQgPSB0cnVlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKGNsaWVudFNvY2tldCAhPSBudWxsICYmICFjbGllbnRTb2NrZXQuaXNDbG9zZWQoKSkgeworICAgICAgICAgICAgICAgIGNsaWVudFNvY2tldC5jbG9zZSgpOworCQljbGllbnRTb2NrZXQgPSBudWxsOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChmaW5hbCBJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBMT0dHRVIubG9nKExldmVsLlNFVkVSRSwgIkVycm9yIiwgZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZSk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3Rlc3QvU2F2ZWRTb2NrZXRGYWN0b3J5LmphdmEgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3Rlc3QvU2F2ZWRTb2NrZXRGYWN0b3J5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDk1ZjJjZQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvdGVzdC9TYXZlZFNvY2tldEZhY3RvcnkuamF2YQpAQCAtMCwwICsxLDgwIEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDEyLCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC50ZXN0OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXQ7CitpbXBvcnQgamF2YS5uZXQuSW5ldEFkZHJlc3M7CitpbXBvcnQgamF2YXgubmV0LlNvY2tldEZhY3Rvcnk7CisKKy8qKgorICogQSBTb2NrZXRGYWN0b3J5IHRoYXQgc2F2ZXMgdGhlIFNvY2tldCBpdCBjcmVhdGVzIHNvIHRoYXQgaXQgY2FuIGJlCisgKiBhY2Nlc3NlZCBsYXRlci4gIFVzZWZ1bCBmb3IgY2hlY2tpbmcgdGhhdCBzb2NrZXRzIGFyZSBjbG9zZWQgcHJvcGVybHkuCisgKi8KK3B1YmxpYyBjbGFzcyBTYXZlZFNvY2tldEZhY3RvcnkgZXh0ZW5kcyBTb2NrZXRGYWN0b3J5IHsKKyAgICBwcml2YXRlIFNvY2tldEZhY3RvcnkgZmFjdG9yeTsKKyAgICBwcml2YXRlIFNvY2tldCBzYXZlZDsKKworICAgIHB1YmxpYyBTYXZlZFNvY2tldEZhY3RvcnkoKSB7CisJc3VwZXIoKTsKKwl0cnkgeworCSAgICBmYWN0b3J5ID0gU29ja2V0RmFjdG9yeS5nZXREZWZhdWx0KCk7CisJfSBjYXRjaChFeGNlcHRpb24gZXgpIHsKKwkgICAgLy8gaWdub3JlCisJfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTb2NrZXQgY3JlYXRlU29ja2V0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlyZXR1cm4gc2F2ZShmYWN0b3J5LmNyZWF0ZVNvY2tldCgpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU29ja2V0IGNyZWF0ZVNvY2tldChJbmV0QWRkcmVzcyBob3N0LCBpbnQgcG9ydCkKKwkJCQl0aHJvd3MgSU9FeGNlcHRpb24geworCXJldHVybiBzYXZlKGZhY3RvcnkuY3JlYXRlU29ja2V0KGhvc3QsIHBvcnQpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU29ja2V0IGNyZWF0ZVNvY2tldChJbmV0QWRkcmVzcyBhZGRyZXNzLCBpbnQgcG9ydCwKKwkJCQlJbmV0QWRkcmVzcyBsb2NhbEFkZHJlc3MsIGludCBsb2NhbFBvcnQpCisJCQkJdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlyZXR1cm4gc2F2ZShmYWN0b3J5LmNyZWF0ZVNvY2tldCgKKwkJCQkgICAgYWRkcmVzcywgcG9ydCwgbG9jYWxBZGRyZXNzLCBsb2NhbFBvcnQpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU29ja2V0IGNyZWF0ZVNvY2tldChTdHJpbmcgaG9zdCwgaW50IHBvcnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJcmV0dXJuIHNhdmUoZmFjdG9yeS5jcmVhdGVTb2NrZXQoaG9zdCwgcG9ydCkpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTb2NrZXQgY3JlYXRlU29ja2V0KFN0cmluZyBob3N0LCBpbnQgcG9ydCwKKwkJCQlJbmV0QWRkcmVzcyBsb2NhbEhvc3QsIGludCBsb2NhbFBvcnQpCisJCQkJdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlyZXR1cm4gc2F2ZShmYWN0b3J5LmNyZWF0ZVNvY2tldChob3N0LCBwb3J0LCBsb2NhbEhvc3QsIGxvY2FsUG9ydCkpOworICAgIH0KKworICAgIHB1YmxpYyBTb2NrZXQgZ2V0U29ja2V0KCkgeworCXJldHVybiBzYXZlZDsKKyAgICB9CisKKyAgICBwcml2YXRlIFNvY2tldCBzYXZlKFNvY2tldCBzKSB7CisJc2F2ZWQgPSBzOworCXJldHVybiBzYXZlZDsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3Rlc3QvVGVzdFNTTFNvY2tldEZhY3RvcnkuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvdGVzdC9UZXN0U1NMU29ja2V0RmFjdG9yeS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRlNWE4YjUKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3Rlc3QvVGVzdFNTTFNvY2tldEZhY3RvcnkuamF2YQpAQCAtMCwwICsxLDE5NyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwudGVzdDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuKjsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbjsKKworaW1wb3J0IGphdmF4Lm5ldC5zc2wuKjsKKworLyoqCisgKiBBbiBTU0wgc29ja2V0IGZhY3RvcnkgZm9yIHRlc3RpbmcgdGhhdCB0cmFja3Mgd2hldGhlciBpdCdzIGJlaW5nIHVzZWQuCisgKiA8cD4KKyAqCisgKiBBbiBpbnN0YW5jZSBvZiB0aGlzIGZhY3RvcnkgY2FuIGJlIHNldCBhcyB0aGUgdmFsdWUgb2YgdGhlCisgKiA8Y29kZT5tYWlsLiZsdDtwcm90b2NvbCZndDsuc3NsLnNvY2tldEZhY3Rvcnk8L2NvZGU+IHByb3BlcnR5LgorICoKKyAqIEBzaW5jZQlKYXZhTWFpbCAxLjUuMworICogQGF1dGhvcglTdGVwaGFuIFNhbm4KKyAqIEBhdXRob3IJQmlsbCBTaGFubm9uCisgKi8KK3B1YmxpYyBjbGFzcyBUZXN0U1NMU29ja2V0RmFjdG9yeSBleHRlbmRzIFNTTFNvY2tldEZhY3RvcnkgeworCisgICAgLyoqIEhvbGRzIGEgU1NMU29ja2V0RmFjdG9yeSB0byBwYXNzIGFsbCBBUEktbWV0aG9kLWNhbGxzIHRvICovCisgICAgcHJpdmF0ZSBTU0xTb2NrZXRGYWN0b3J5IGRlZmF1bHRGYWN0b3J5ID0gbnVsbDsKKworICAgIC8qKiBXYXMgYSBzb2NrZXQgY3JlYXRlZD8gKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gc29ja2V0Q3JlYXRlZDsKKworICAgIC8qKiBXYXMgYSBzb2NrZXQgd3JhcHBlZD8gKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gc29ja2V0V3JhcHBlZDsKKworICAgIHByaXZhdGUgU3RyaW5nW10gc3VpdGVzOworCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZXMgYSBuZXcgVGVzdFNTTFNvY2tldEZhY3RvcnkuCisgICAgICogCisgICAgICogQHRocm93cyAgR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uIGZvciBzZWN1cml0eSBlcnJvcnMKKyAgICAgKi8KKyAgICBwdWJsaWMgVGVzdFNTTFNvY2tldEZhY3RvcnkoKSB0aHJvd3MgR2VuZXJhbFNlY3VyaXR5RXhjZXB0aW9uIHsKKwl0aGlzKCJUTFMiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplcyBhIG5ldyBUZXN0U1NMU29ja2V0RmFjdG9yeSB3aXRoIGEgZ2l2ZW4gcHJvdG9jb2wuCisgICAgICogTm9ybWFsbHkgdGhlIHByb3RvY29sIHdpbGwgYmUgc3BlY2lmaWVkIGFzICJUTFMiLgorICAgICAqIAorICAgICAqIEBwYXJhbSAgIHByb3RvY29sICBUaGUgcHJvdG9jb2wgdG8gdXNlCisgICAgICogQHRocm93cyAgTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGlmIGdpdmVuIHByb3RvY29sIGlzIG5vdCBzdXBwb3J0ZWQKKyAgICAgKiBAdGhyb3dzICBHZW5lcmFsU2VjdXJpdHlFeGNlcHRpb24gZm9yIHNlY3VyaXR5IGVycm9ycworICAgICAqLworICAgIHB1YmxpYyBUZXN0U1NMU29ja2V0RmFjdG9yeShTdHJpbmcgcHJvdG9jb2wpCisJCQkJdGhyb3dzIEdlbmVyYWxTZWN1cml0eUV4Y2VwdGlvbiB7CisKKwkvLyBHZXQgdGhlIGRlZmF1bHQgU1NMU29ja2V0RmFjdG9yeSB0byBkZWxlZ2F0ZSBhbGwgQVBJLWNhbGxzIHRvLgorCWRlZmF1bHRGYWN0b3J5ID0gKFNTTFNvY2tldEZhY3RvcnkpU1NMU29ja2V0RmFjdG9yeS5nZXREZWZhdWx0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogV2FzIGEgc29ja2V0IGNyZWF0ZWQgdXNpbmcgb25lIG9mIHRoZSBjcmVhdGVTb2NrZXQgbWV0aG9kcz8KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBnZXRTb2NrZXRDcmVhdGVkKCkgeworCXJldHVybiBzb2NrZXRDcmVhdGVkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdhcyBhIHNvY2tldCB3cmFwcGVkIHVzaW5nIHRoZSBjcmVhdGVTb2NrZXQgbWV0aG9kIHRoYXQgdGFrZXMgYSBTb2NrZXQ/CisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZ2V0U29ja2V0V3JhcHBlZCgpIHsKKwlyZXR1cm4gc29ja2V0V3JhcHBlZDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIGRlZmF1bHQgY2lwaGVyIHN1aXRlcyB0byBiZSBhcHBsaWVkIHRvIGZ1dHVyZSBzb2NrZXRzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldERlZmF1bHRDaXBoZXJTdWl0ZXMoU3RyaW5nW10gc3VpdGVzKSB7CisJdGhpcy5zdWl0ZXMgPSBzdWl0ZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uZmlndXJlIHRoZSBzb2NrZXQgdG8gYmUgcmV0dXJuZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBTb2NrZXQgY29uZmlndXJlKFNvY2tldCBzb2NrZXQpIHsKKwlpZiAoc29ja2V0IGluc3RhbmNlb2YgU1NMU29ja2V0KSB7CS8vIFhYWCAtIGFsd2F5cyB0cnVlCisJICAgIFNTTFNvY2tldCBzID0gKFNTTFNvY2tldClzb2NrZXQ7CisJICAgIGlmIChzdWl0ZXMgIT0gbnVsbCkKKwkJcy5zZXRFbmFibGVkQ2lwaGVyU3VpdGVzKHN1aXRlcyk7CisJfQorCXJldHVybiBzb2NrZXQ7CisgICAgfQorCisKKyAgICAvLyBTb2NrZXRGYWN0b3J5IG1ldGhvZHMKKworICAgIC8qIChub24tSmF2YWRvYykKKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5zc2wuU1NMU29ja2V0RmFjdG9yeSNjcmVhdGVTb2NrZXQoamF2YS5uZXQuU29ja2V0LAorICAgICAqCQkJCQkJamF2YS5sYW5nLlN0cmluZywgaW50LCBib29sZWFuKQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgU29ja2V0IGNyZWF0ZVNvY2tldChTb2NrZXQgc29ja2V0LCBTdHJpbmcgcywgaW50IGksCisJCQkJYm9vbGVhbiBmbGFnKSB0aHJvd3MgSU9FeGNlcHRpb24geworCVNvY2tldCB3cmFwcGVkU29ja2V0ID0gZGVmYXVsdEZhY3RvcnkuY3JlYXRlU29ja2V0KHNvY2tldCwgcywgaSwgZmxhZyk7CisJc29ja2V0V3JhcHBlZCA9IHRydWU7CisJcmV0dXJuIGNvbmZpZ3VyZSh3cmFwcGVkU29ja2V0KTsKKyAgICB9CisKKyAgICAvKiAobm9uLUphdmFkb2MpCisgICAgICogQHNlZSBqYXZheC5uZXQuc3NsLlNTTFNvY2tldEZhY3RvcnkjZ2V0RGVmYXVsdENpcGhlclN1aXRlcygpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBTdHJpbmdbXSBnZXREZWZhdWx0Q2lwaGVyU3VpdGVzKCkgeworCWlmIChzdWl0ZXMgIT0gbnVsbCkKKwkgICAgcmV0dXJuIHN1aXRlcy5jbG9uZSgpOworCWVsc2UKKwkgICAgcmV0dXJuIGRlZmF1bHRGYWN0b3J5LmdldERlZmF1bHRDaXBoZXJTdWl0ZXMoKTsKKyAgICB9CisKKyAgICAvKiAobm9uLUphdmFkb2MpCisgICAgICogQHNlZSBqYXZheC5uZXQuc3NsLlNTTFNvY2tldEZhY3RvcnkjZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVzKCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIFN0cmluZ1tdIGdldFN1cHBvcnRlZENpcGhlclN1aXRlcygpIHsKKwlyZXR1cm4gZGVmYXVsdEZhY3RvcnkuZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVzKCk7CisgICAgfQorCisgICAgLyogKG5vbi1KYXZhZG9jKQorICAgICAqIEBzZWUgamF2YXgubmV0LlNvY2tldEZhY3RvcnkjY3JlYXRlU29ja2V0KCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIFNvY2tldCBjcmVhdGVTb2NrZXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCVNvY2tldCBzb2NrZXQgPSBkZWZhdWx0RmFjdG9yeS5jcmVhdGVTb2NrZXQoKTsKKwlzb2NrZXRDcmVhdGVkID0gdHJ1ZTsKKwlyZXR1cm4gY29uZmlndXJlKHNvY2tldCk7CisgICAgfQorCisgICAgLyogKG5vbi1KYXZhZG9jKQorICAgICAqIEBzZWUgamF2YXgubmV0LlNvY2tldEZhY3RvcnkjY3JlYXRlU29ja2V0KGphdmEubmV0LkluZXRBZGRyZXNzLCBpbnQsCisgICAgICoJCQkJCQlqYXZhLm5ldC5JbmV0QWRkcmVzcywgaW50KQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgU29ja2V0IGNyZWF0ZVNvY2tldChJbmV0QWRkcmVzcyBpbmV0YWRkcmVzcywgaW50IGksCisJCQlJbmV0QWRkcmVzcyBpbmV0YWRkcmVzczEsIGludCBqKSB0aHJvd3MgSU9FeGNlcHRpb24geworCVNvY2tldCBzb2NrZXQgPQorCQlkZWZhdWx0RmFjdG9yeS5jcmVhdGVTb2NrZXQoaW5ldGFkZHJlc3MsIGksIGluZXRhZGRyZXNzMSwgaik7CisJc29ja2V0Q3JlYXRlZCA9IHRydWU7CisJcmV0dXJuIGNvbmZpZ3VyZShzb2NrZXQpOworICAgIH0KKworICAgIC8qIChub24tSmF2YWRvYykKKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5Tb2NrZXRGYWN0b3J5I2NyZWF0ZVNvY2tldChqYXZhLm5ldC5JbmV0QWRkcmVzcywgaW50KQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgU29ja2V0IGNyZWF0ZVNvY2tldChJbmV0QWRkcmVzcyBpbmV0YWRkcmVzcywgaW50IGkpCisJCQkJdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlTb2NrZXQgc29ja2V0ID0gZGVmYXVsdEZhY3RvcnkuY3JlYXRlU29ja2V0KGluZXRhZGRyZXNzLCBpKTsKKwlzb2NrZXRDcmVhdGVkID0gdHJ1ZTsKKwlyZXR1cm4gY29uZmlndXJlKHNvY2tldCk7CisgICAgfQorCisgICAgLyogKG5vbi1KYXZhZG9jKQorICAgICAqIEBzZWUgamF2YXgubmV0LlNvY2tldEZhY3RvcnkjY3JlYXRlU29ja2V0KGphdmEubGFuZy5TdHJpbmcsIGludCwKKyAgICAgKgkJCQkJCWphdmEubmV0LkluZXRBZGRyZXNzLCBpbnQpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBTb2NrZXQgY3JlYXRlU29ja2V0KFN0cmluZyBzLCBpbnQgaSwKKwkJCQlJbmV0QWRkcmVzcyBpbmV0YWRkcmVzcywgaW50IGopCisJCQkJdGhyb3dzIElPRXhjZXB0aW9uLCBVbmtub3duSG9zdEV4Y2VwdGlvbiB7CisJU29ja2V0IHNvY2tldCA9IGRlZmF1bHRGYWN0b3J5LmNyZWF0ZVNvY2tldChzLCBpLCBpbmV0YWRkcmVzcywgaik7CisJc29ja2V0Q3JlYXRlZCA9IHRydWU7CisJcmV0dXJuIGNvbmZpZ3VyZShzb2NrZXQpOworICAgIH0KKworICAgIC8qIChub24tSmF2YWRvYykKKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5Tb2NrZXRGYWN0b3J5I2NyZWF0ZVNvY2tldChqYXZhLmxhbmcuU3RyaW5nLCBpbnQpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBTb2NrZXQgY3JlYXRlU29ja2V0KFN0cmluZyBzLCBpbnQgaSkKKwkJCQl0aHJvd3MgSU9FeGNlcHRpb24sIFVua25vd25Ib3N0RXhjZXB0aW9uIHsKKwlTb2NrZXQgc29ja2V0ID0gZGVmYXVsdEZhY3RvcnkuY3JlYXRlU29ja2V0KHMsIGkpOworCXNvY2tldENyZWF0ZWQgPSB0cnVlOworCXJldHVybiBjb25maWd1cmUoc29ja2V0KTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3Rlc3QvVGVzdFNlcnZlci5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC90ZXN0L1Rlc3RTZXJ2ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZjYwMzUwCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC90ZXN0L1Rlc3RTZXJ2ZXIuamF2YQpAQCAtMCwwICsxLDIzMSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwOSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwudGVzdDsKKworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5TZXJ2ZXJTb2NrZXQ7CitpbXBvcnQgamF2YS5uZXQuU29ja2V0OworaW1wb3J0IGphdmEubmV0LkluZXRTb2NrZXRBZGRyZXNzOworaW1wb3J0IGphdmF4Lm5ldC5zc2wuKjsKKworLyoqCisgKiBBIHNpbXBsZSBzZXJ2ZXIgZm9yIHRlc3RpbmcuCisgKgorICogSW5zcGlyZWQgYnksIGFuZCBkZXJpdmVkIGZyb20sIFBPUDNTZXJ2ZXIgYnkgc2JvLgorICoKKyAqIEBhdXRob3Igc2JvCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgVGVzdFNlcnZlciBleHRlbmRzIFRocmVhZCB7CisKKyAgICAvKiogU2VydmVyIHNvY2tldC4gKi8KKyAgICBwcml2YXRlIFNlcnZlclNvY2tldCBzZXJ2ZXJTb2NrZXQ7CisKKyAgICAvKiogS2VlcCBvbj8gKi8KKyAgICBwcml2YXRlIHZvbGF0aWxlIGJvb2xlYW4ga2VlcE9uOworCisgICAgLyoqIFByb3RvY29sIGhhbmRsZXIuICovCisgICAgcHJpdmF0ZSBmaW5hbCBQcm90b2NvbEhhbmRsZXIgaGFuZGxlcjsKKworICAgIHByaXZhdGUgTGlzdDxUaHJlYWQ+IGNsaWVudHMgPSBuZXcgQXJyYXlMaXN0PFRocmVhZD4oKTsKKworICAgIC8qKgorICAgICAqIFRlc3Qgc2VydmVyLgorICAgICAqCisgICAgICogQHBhcmFtIGhhbmRsZXIJdGhlIHByb3RvY29sIGhhbmRsZXIKKyAgICAgKi8KKyAgICBwdWJsaWMgVGVzdFNlcnZlcihmaW5hbCBQcm90b2NvbEhhbmRsZXIgaGFuZGxlcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwl0aGlzKGhhbmRsZXIsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHNlcnZlci4KKyAgICAgKgorICAgICAqIEBwYXJhbSBoYW5kbGVyCXRoZSBwcm90b2NvbCBoYW5kbGVyCisgICAgICogQHBhcmFtIGlzU1NMCWNyZWF0ZSBTU0wgc29ja2V0cz8KKyAgICAgKi8KKyAgICBwdWJsaWMgVGVzdFNlcnZlcihmaW5hbCBQcm90b2NvbEhhbmRsZXIgaGFuZGxlciwgZmluYWwgYm9vbGVhbiBpc1NTTCkKKwkJCQl0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzLmhhbmRsZXIgPSBoYW5kbGVyOworCisJLyoKKwkgKiBBbGxvd2luZyB0aGUgSkRLIHRvIHBpY2sgYSBwb3J0IG51bWJlciBzb21ldGltZXMgcmVzdWx0cyBpbiBpdAorCSAqIHBpY2tpbmcgYSBudW1iZXIgdGhhdCdzIGFscmVhZHkgaW4gdXNlIGJ5IGFub3RoZXIgcHJvY2VzcywgYnV0CisJICogbm8gZXJyb3IgaXMgcmV0dXJuZWQuICBQaWNraW5nIGl0IG91cnNlbGYgYWxsb3dzIHVzIHRvIG1ha2Ugc3VyZQorCSAqIHRoYXQgaXQncyBub3QgdXNlZCBiZWZvcmUgd2UgcGljayBpdC4gIEhvcGVmdWxseSB0aGUgc29ja2V0CisJICogY3JlYXRpb24gd2lsbCBmYWlsIGlmIHRoZSBwb3J0IGlzIGFscmVhZHkgaW4gdXNlLgorCSAqCisJICogWFhYIC0gcGVyaGFwcyB3ZSBzaG91bGQgdXNlIFJhbmRvbSB0byBjaG9vc2UgYSBwb3J0IG51bWJlciBpbgorCSAqIHRoZSBlbXBoZW1lcmFsIHJhbmdlLCBpbiBjYXNlIGEgbG90IG9mIGxvdyBwb3J0IG51bWJlcnMgYXJlCisJICogYWxyZWFkeSBpbiB1c2UuCisJICovCisJZm9yIChpbnQgcG9ydCA9IDQ5MTUyOyBwb3J0IDwgNTAwMDAgLyo2NTUzNSovOyBwb3J0KyspIHsKKwkgICAgLyoKKwkgICAgaWYgKGlzTGlzdGVuaW5nKHBvcnQpKQorCQljb250aW51ZTsKKwkgICAgKi8KKwkgICAgdHJ5IHsKKwkJc2VydmVyU29ja2V0ID0gY3JlYXRlU2VydmVyU29ja2V0KHBvcnQsIGlzU1NMKTsKKwkJcmV0dXJuOworCSAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworCQkvLyBpZ25vcmUKKwkgICAgfQorCX0KKwl0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiQ2FuJ3QgZmluZCB1bnVzZWQgcG9ydCIpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIFNlcnZlclNvY2tldCBjcmVhdGVTZXJ2ZXJTb2NrZXQoaW50IHBvcnQsIGJvb2xlYW4gaXNTU0wpCisJCQkJdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlTZXJ2ZXJTb2NrZXQgc3M7CisJaWYgKGlzU1NMKSB7CisJICAgIFNTTFNlcnZlclNvY2tldEZhY3Rvcnkgc2YgPQorCQkoU1NMU2VydmVyU29ja2V0RmFjdG9yeSlTU0xTZXJ2ZXJTb2NrZXRGYWN0b3J5LmdldERlZmF1bHQoKTsKKwkgICAgc3MgPSBzZi5jcmVhdGVTZXJ2ZXJTb2NrZXQocG9ydCk7CisJICAgIC8vIGVuYWJsZSBvbmx5IHRoZSBhbm9ueW1vdXMgY2lwaGVyIHN1aXRlcyBzbyB3ZSBkb24ndCBoYXZlIHRvCisJICAgIC8vIGNyZWF0ZSBhIHNlcnZlciBjZXJ0aWZpY2F0ZQorCSAgICBMaXN0PFN0cmluZz4gYW5vbiA9IG5ldyBBcnJheUxpc3Q8PigpOworCSAgICBTdHJpbmdbXSBzdWl0ZXMgPSBzZi5nZXRTdXBwb3J0ZWRDaXBoZXJTdWl0ZXMoKTsKKwkgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzdWl0ZXMubGVuZ3RoOyBpKyspIHsKKwkJaWYgKHN1aXRlc1tpXS5pbmRleE9mKCJfYW5vbl8iKSA+PSAwKSB7CisJCSAgICBhbm9uLmFkZChzdWl0ZXNbaV0pOworCQl9CisJICAgIH0KKwkgICAgKChTU0xTZXJ2ZXJTb2NrZXQpc3MpLnNldEVuYWJsZWRDaXBoZXJTdWl0ZXMoCisJCQkJICAgIGFub24udG9BcnJheShuZXcgU3RyaW5nW2Fub24uc2l6ZSgpXSkpOworCX0gZWxzZQorCSAgICBzcyA9IG5ldyBTZXJ2ZXJTb2NrZXQocG9ydCk7CisJcmV0dXJuIHNzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgcG9ydCB0aGUgc2VydmVyIGlzIGxpc3RlbmluZyBvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFBvcnQoKSB7CisJcmV0dXJuIHNlcnZlclNvY2tldC5nZXRMb2NhbFBvcnQoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFeGl0IHNlcnZlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBxdWl0KCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAga2VlcE9uID0gZmFsc2U7CisgICAgICAgICAgICBpZiAoc2VydmVyU29ja2V0ICE9IG51bGwgJiYgIXNlcnZlclNvY2tldC5pc0Nsb3NlZCgpKSB7CisgICAgICAgICAgICAgICAgc2VydmVyU29ja2V0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgc2VydmVyU29ja2V0ID0gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoZmluYWwgSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB7QGluaGVyaXREb2N9CisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc3RhcnQoKSB7CisJc3VwZXIuc3RhcnQoKTsKKwkvLyBkb24ndCByZXR1cm4gdW50aWwgc2VydmVyIGlzIHJlYWxseSBsaXN0ZW5pbmcKKwkvLyBYWFggLSB0aGlzIG1pZ2h0IG5vdCBiZSBuZWNlc3NhcnkKKwlmb3IgKGludCB0cmllcyA9IDA7IHRyaWVzIDwgMTA7IHRyaWVzKyspIHsKKwkgICAgaWYgKGlzTGlzdGVuaW5nKGdldFBvcnQoKSkpIHsKKwkJcmV0dXJuOworCSAgICB9CisJICAgIHRyeSB7CisJCVRocmVhZC5zbGVlcCgxMDApOworCSAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBleCkgeyB9CisJfQorCXRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJTZXJ2ZXIgaXNuJ3QgbGlzdGVuaW5nIik7CisgICAgfQorCisgICAgLyoqCisgICAgICoge0Bpbmhlcml0RG9jfQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtlZXBPbiA9IHRydWU7CisKKyAgICAgICAgICAgIHdoaWxlIChrZWVwT24pIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBmaW5hbCBTb2NrZXQgY2xpZW50U29ja2V0ID0gc2VydmVyU29ja2V0LmFjY2VwdCgpOworICAgICAgICAgICAgICAgICAgICBmaW5hbCBQcm90b2NvbEhhbmRsZXIgcEhhbmRsZXIgPQorCQkJKFByb3RvY29sSGFuZGxlciloYW5kbGVyLmNsb25lKCk7CisgICAgICAgICAgICAgICAgICAgIHBIYW5kbGVyLnNldENsaWVudFNvY2tldChjbGllbnRTb2NrZXQpOworICAgICAgICAgICAgICAgICAgICBUaHJlYWQgdCA9IG5ldyBUaHJlYWQocEhhbmRsZXIpOworCQkgICAgc3luY2hyb25pemVkIChjbGllbnRzKSB7CisJCQljbGllbnRzLmFkZCh0KTsKKwkJICAgIH0KKwkJICAgIHQuc3RhcnQoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIC8vZS5wcmludFN0YWNrVHJhY2UoKTsKKwkJfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gbmV4KSB7CisJCSAgICAvLyBzZXJ2ZXJTb2NrZXQgY2FuIGJlIHNldCB0byBudWxsIGJlZm9yZSB3ZSBjb3VsZCBjaGVjaworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHF1aXQoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiBudW1iZXIgb2YgY2xpZW50cyBldmVyIGNyZWF0ZWQuCisgICAgICovCisgICAgcHVibGljIGludCBjbGllbnRDb3VudCgpIHsKKwlzeW5jaHJvbml6ZWQgKGNsaWVudHMpIHsKKwkgICAgLy8gaXNMaXN0ZW5pbmcgY3JlYXRlcyBhIGNsaWVudCB0aGF0IHdlIGRvbid0IGNvdW50CisJICAgIHJldHVybiBjbGllbnRzLnNpemUoKSAtIDE7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFdhaXQgZm9yIGF0IGxlYXN0IG4gY2xpZW50cyB0byB0ZXJtaW5hdGUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgd2FpdEZvckNsaWVudHMoaW50IG4pIHsKKwlpZiAobiA+IGNsaWVudENvdW50KCkpCisJICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJub3QgdGhhdCBtYW55IGNsaWVudHMiKTsKKwlmb3IgKDs7KSB7CisJICAgIGludCBudW0gPSAtMTsJLy8gaWdub3JlIGlzTGlzdGVuaW5nIGNsaWVudAorCSAgICBzeW5jaHJvbml6ZWQgKGNsaWVudHMpIHsKKwkJZm9yIChUaHJlYWQgdCA6IGNsaWVudHMpIHsKKwkJICAgIGlmICghdC5pc0FsaXZlKCkpIHsKKwkJCWlmICgrK251bSA+PSBuKQorCQkJICAgIHJldHVybjsKKwkJICAgIH0KKwkJfQorCSAgICB9CisJICAgIHRyeSB7CisJCVRocmVhZC5zbGVlcCgxMDApOworCSAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBleCkgeyB9CisJfQorICAgIH0KKworICAgIHByaXZhdGUgYm9vbGVhbiBpc0xpc3RlbmluZyhpbnQgcG9ydCkgeworCXRyeSB7CisJICAgIFNvY2tldCBzID0gbmV3IFNvY2tldCgpOworCSAgICBzLmNvbm5lY3QobmV3IEluZXRTb2NrZXRBZGRyZXNzKCJsb2NhbGhvc3QiLCBwb3J0KSwgMTAwKTsKKwkgICAgLy8gaXQncyBsaXN0ZW5pbmchCisJICAgIHMuY2xvc2UoKTsKKwkgICAgcmV0dXJuIHRydWU7CisJfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJICAgIC8vU3lzdGVtLm91dC5wcmludGxuKGV4KTsKKwl9CisJcmV0dXJuIGZhbHNlOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvdGVzdC9UZXN0U29ja2V0RmFjdG9yeS5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC90ZXN0L1Rlc3RTb2NrZXRGYWN0b3J5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTBlNzUxZQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvdGVzdC9UZXN0U29ja2V0RmFjdG9yeS5qYXZhCkBAIC0wLDAgKzEsMTE4IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC50ZXN0OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC4qOworCitpbXBvcnQgamF2YXgubmV0LlNvY2tldEZhY3Rvcnk7CisKKy8qKgorICogQSBzb2NrZXQgZmFjdG9yeSBmb3IgdGVzdGluZyB0aGF0IHRyYWNrcyB3aGV0aGVyIGl0J3MgYmVpbmcgdXNlZC4KKyAqIDxwPgorICoKKyAqIEFuIGluc3RhbmNlIG9mIHRoaXMgZmFjdG9yeSBjYW4gYmUgc2V0IGFzIHRoZSB2YWx1ZSBvZiB0aGUKKyAqIDxjb2RlPm1haWwuJmx0O3Byb3RvY29sJmd0Oy5zb2NrZXRGYWN0b3J5PC9jb2RlPiBwcm9wZXJ0eS4KKyAqCisgKiBAc2luY2UJSmF2YU1haWwgMS41LjMKKyAqIEBhdXRob3IJU3RlcGhhbiBTYW5uCisgKiBAYXV0aG9yCUJpbGwgU2hhbm5vbgorICovCitwdWJsaWMgY2xhc3MgVGVzdFNvY2tldEZhY3RvcnkgZXh0ZW5kcyBTb2NrZXRGYWN0b3J5IHsKKworICAgIC8qKiBIb2xkcyBhIFNvY2tldEZhY3RvcnkgdG8gcGFzcyBhbGwgQVBJLW1ldGhvZC1jYWxscyB0byAqLworICAgIHByaXZhdGUgU29ja2V0RmFjdG9yeSBkZWZhdWx0RmFjdG9yeSA9IG51bGw7CisKKyAgICAvKiogV2FzIGEgc29ja2V0IGNyZWF0ZWQ/ICovCisgICAgcHJpdmF0ZSBib29sZWFuIHNvY2tldENyZWF0ZWQ7CisKKyAgICAvKioKKyAgICAgKiBJbml0aWFsaXplcyBhIG5ldyBUZXN0U29ja2V0RmFjdG9yeS4KKyAgICAgKi8KKyAgICBwdWJsaWMgVGVzdFNvY2tldEZhY3RvcnkoKSB7CisJLy8gR2V0IHRoZSBkZWZhdWx0IFNvY2tldEZhY3RvcnkgdG8gZGVsZWdhdGUgYWxsIEFQSS1jYWxscyB0by4KKwlkZWZhdWx0RmFjdG9yeSA9IFNvY2tldEZhY3RvcnkuZ2V0RGVmYXVsdCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdhcyBhIHNvY2tldCBjcmVhdGVkIHVzaW5nIG9uZSBvZiB0aGUgY3JlYXRlU29ja2V0IG1ldGhvZHM/CisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZ2V0U29ja2V0Q3JlYXRlZCgpIHsKKwlyZXR1cm4gc29ja2V0Q3JlYXRlZDsKKyAgICB9CisKKworICAgIC8vIFNvY2tldEZhY3RvcnkgbWV0aG9kcworCisgICAgLyogKG5vbi1KYXZhZG9jKQorICAgICAqIEBzZWUgamF2YXgubmV0LlNvY2tldEZhY3RvcnkjY3JlYXRlU29ja2V0KCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIFNvY2tldCBjcmVhdGVTb2NrZXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCVNvY2tldCBzb2NrZXQgPSBkZWZhdWx0RmFjdG9yeS5jcmVhdGVTb2NrZXQoKTsKKwlzb2NrZXRDcmVhdGVkID0gdHJ1ZTsKKwlyZXR1cm4gc29ja2V0OworICAgIH0KKworICAgIC8qIChub24tSmF2YWRvYykKKyAgICAgKiBAc2VlIGphdmF4Lm5ldC5Tb2NrZXRGYWN0b3J5I2NyZWF0ZVNvY2tldChqYXZhLm5ldC5JbmV0QWRkcmVzcywgaW50LAorICAgICAqCQkJCQkJamF2YS5uZXQuSW5ldEFkZHJlc3MsIGludCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIFNvY2tldCBjcmVhdGVTb2NrZXQoSW5ldEFkZHJlc3MgaW5ldGFkZHJlc3MsIGludCBpLAorCQkJSW5ldEFkZHJlc3MgaW5ldGFkZHJlc3MxLCBpbnQgaikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlTb2NrZXQgc29ja2V0ID0KKwkJZGVmYXVsdEZhY3RvcnkuY3JlYXRlU29ja2V0KGluZXRhZGRyZXNzLCBpLCBpbmV0YWRkcmVzczEsIGopOworCXNvY2tldENyZWF0ZWQgPSB0cnVlOworCXJldHVybiBzb2NrZXQ7CisgICAgfQorCisgICAgLyogKG5vbi1KYXZhZG9jKQorICAgICAqIEBzZWUgamF2YXgubmV0LlNvY2tldEZhY3RvcnkjY3JlYXRlU29ja2V0KGphdmEubmV0LkluZXRBZGRyZXNzLCBpbnQpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBTb2NrZXQgY3JlYXRlU29ja2V0KEluZXRBZGRyZXNzIGluZXRhZGRyZXNzLCBpbnQgaSkKKwkJCQl0aHJvd3MgSU9FeGNlcHRpb24geworCVNvY2tldCBzb2NrZXQgPSBkZWZhdWx0RmFjdG9yeS5jcmVhdGVTb2NrZXQoaW5ldGFkZHJlc3MsIGkpOworCXNvY2tldENyZWF0ZWQgPSB0cnVlOworCXJldHVybiBzb2NrZXQ7CisgICAgfQorCisgICAgLyogKG5vbi1KYXZhZG9jKQorICAgICAqIEBzZWUgamF2YXgubmV0LlNvY2tldEZhY3RvcnkjY3JlYXRlU29ja2V0KGphdmEubGFuZy5TdHJpbmcsIGludCwKKyAgICAgKgkJCQkJCWphdmEubmV0LkluZXRBZGRyZXNzLCBpbnQpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBTb2NrZXQgY3JlYXRlU29ja2V0KFN0cmluZyBzLCBpbnQgaSwKKwkJCQlJbmV0QWRkcmVzcyBpbmV0YWRkcmVzcywgaW50IGopCisJCQkJdGhyb3dzIElPRXhjZXB0aW9uLCBVbmtub3duSG9zdEV4Y2VwdGlvbiB7CisJU29ja2V0IHNvY2tldCA9IGRlZmF1bHRGYWN0b3J5LmNyZWF0ZVNvY2tldChzLCBpLCBpbmV0YWRkcmVzcywgaik7CisJc29ja2V0Q3JlYXRlZCA9IHRydWU7CisJcmV0dXJuIHNvY2tldDsKKyAgICB9CisKKyAgICAvKiAobm9uLUphdmFkb2MpCisgICAgICogQHNlZSBqYXZheC5uZXQuU29ja2V0RmFjdG9yeSNjcmVhdGVTb2NrZXQoamF2YS5sYW5nLlN0cmluZywgaW50KQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgU29ja2V0IGNyZWF0ZVNvY2tldChTdHJpbmcgcywgaW50IGkpCisJCQkJdGhyb3dzIElPRXhjZXB0aW9uLCBVbmtub3duSG9zdEV4Y2VwdGlvbiB7CisJU29ja2V0IHNvY2tldCA9IGRlZmF1bHRGYWN0b3J5LmNyZWF0ZVNvY2tldChzLCBpKTsKKwlzb2NrZXRDcmVhdGVkID0gdHJ1ZTsKKwlyZXR1cm4gc29ja2V0OworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvdXRpbC9CQVNFNjRUZXN0LmphdmEgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3V0aWwvQkFTRTY0VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZhNTU4YjIKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3V0aWwvQkFTRTY0VGVzdC5qYXZhCkBAIC0wLDAgKzEsMzAzIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC51dGlsOworCitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmEudXRpbC4qOworaW1wb3J0IGphdmF4Lm1haWwuKjsKKworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5Bc3NlcnQ7CisKKy8qKgorICogVGVzdCBiYXNlNjQgZW5jb2RpbmcvZGVjb2RpbmcuCisgKgorICogQGF1dGhvciBCaWxsIFNoYW5ub24KKyAqLworCitwdWJsaWMgY2xhc3MgQkFTRTY0VGVzdCB7CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3QoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCS8vIHRlc3QgYSByYW5nZSBvZiBidWZmZXIgc2l6ZXMKKwlmb3IgKGludCBidWZzaXplID0gMTsgYnVmc2l6ZSA8IDEwMDsgYnVmc2l6ZSsrKSB7CisJICAgIC8vU3lzdGVtLm91dC5wcmludGxuKCJCdWZmZXIgc2l6ZTogIiArIGJ1ZnNpemUpOworCSAgICBieXRlW10gYnVmID0gbmV3IGJ5dGVbYnVmc2l6ZV07CisKKwkgICAgLy8gdGVzdCBhIHNldCBvZiBwYXR0ZXJucworCisJICAgIC8vIGZpcnN0LCBhbGwgemVyb2VzCisJICAgIEFycmF5cy5maWxsKGJ1ZiwgKGJ5dGUpMCk7CisJICAgIHRlc3QoIlplcm9lcyIsIGJ1Zik7CisKKwkgICAgLy8gbm93LCBhbGwgb25lcworCSAgICBBcnJheXMuZmlsbChidWYsIChieXRlKTB4ZmYpOworCSAgICB0ZXN0KCJPbmVzIiwgYnVmKTsKKworCSAgICAvLyBub3csIHNtYWxsIGludGVnZXJzCisJICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYnVmc2l6ZTsgaSsrKQorCQlidWZbaV0gPSAoYnl0ZSlpOworCSAgICB0ZXN0KCJJbnRzIiwgYnVmKTsKKworCSAgICAvLyBmaW5hbGx5LCByYW5kb20gbnVtYmVycworCSAgICBSYW5kb20gcm5kID0gbmV3IFJhbmRvbSgpOworCSAgICBybmQubmV4dEJ5dGVzKGJ1Zik7CisJICAgIHRlc3QoIlJhbmRvbSIsIGJ1Zik7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEVuY29kZSBhbmQgZGVjb2RlIHRoZSBidWZmZXIgYW5kIGNoZWNrIHRoYXQgd2UgZ2V0IGJhY2sgdGhlCisgICAgICogc2FtZSBkYXRhLiAgRW5jb2RpbmcgaXMgZG9uZSBib3RoIHdpdGggdGhlIHN0YXRpYyBlbmNvZGUKKyAgICAgKiBtZXRob2QgYW5kIHVzaW5nIHRoZSBlbmNvZGluZyBzdHJlYW0uICBMaWtld2lzZSwgZGVjb2RpbmcKKyAgICAgKiBpcyBkb25lIGJvdGggd2l0aCB0aGUgc3RhdGljIGRlY29kZSBtZXRob2QgYW5kIHVzaW5nIHRoZQorICAgICAqIGRlY29kaW5nIHN0cmVhbS4gIENoZWNrIGFsbCBjb21iaW5hdGlvbnMuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCB0ZXN0KFN0cmluZyBuYW1lLCBieXRlW10gYnVmKSB0aHJvd3MgSU9FeGNlcHRpb24geworCS8vIGZpcnN0IGVuY29kZSBhbmQgZGVjb2RlIHdpdGggbWV0aG9kCisJYnl0ZVtdIGVuY29kZWQgPSBCQVNFNjRFbmNvZGVyU3RyZWFtLmVuY29kZShidWYpOworCWJ5dGVbXSBuYnVmID0gQkFTRTY0RGVjb2RlclN0cmVhbS5kZWNvZGUoZW5jb2RlZCk7CisJY29tcGFyZShuYW1lLCAibWV0aG9kIiwgYnVmLCBuYnVmKTsKKworCS8vIGVuY29kZSB3aXRoIHN0cmVhbSwgY29tcGFyZSB3aXRoIG1ldGhvZCBlbmNvZGVkIHZlcnNpb24KKwlCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworCUJBU0U2NEVuY29kZXJTdHJlYW0gb3MgPQorCSAgICBuZXcgQkFTRTY0RW5jb2RlclN0cmVhbShib3MsIEludGVnZXIuTUFYX1ZBTFVFKTsKKwlvcy53cml0ZShidWYpOworCW9zLmZsdXNoKCk7CisJb3MuY2xvc2UoKTsKKwlieXRlW10gc2J1ZiA9IGJvcy50b0J5dGVBcnJheSgpOworCWNvbXBhcmUobmFtZSwgImVuY29kZWQiLCBlbmNvZGVkLCBzYnVmKTsKKworCS8vIGVuY29kZSB3aXRoIHN0cmVhbSwgZGVjb2RlIHdpdGggbWV0aG9kCisJbmJ1ZiA9IEJBU0U2NERlY29kZXJTdHJlYW0uZGVjb2RlKHNidWYpOworCWNvbXBhcmUobmFtZSwgInN0cmVhbS0+bWV0aG9kIiwgYnVmLCBuYnVmKTsKKworCS8vIGVuY29kZSB3aXRoIHN0cmVhbSwgZGVjb2RlIHdpdGggc3RyZWFtCisJQnl0ZUFycmF5SW5wdXRTdHJlYW0gYmluID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKHNidWYpOworCUJBU0U2NERlY29kZXJTdHJlYW0gaW4gPSBuZXcgQkFTRTY0RGVjb2RlclN0cmVhbShiaW4pOworCXJlYWRBbGwoaW4sIG5idWYsIG5idWYubGVuZ3RoKTsKKwljb21wYXJlKG5hbWUsICJzdHJlYW0iLCBidWYsIG5idWYpOworCisJLy8gZW5jb2RlIHdpdGggbWV0aG9kLCBkZWNvZGUgd2l0aCBzdHJlYW0KKwlmb3IgKGludCBpID0gMTsgaSA8PSBuYnVmLmxlbmd0aDsgaSsrKSB7CisJICAgIGJpbiA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShlbmNvZGVkKTsKKwkgICAgaW4gPSBuZXcgQkFTRTY0RGVjb2RlclN0cmVhbShiaW4pOworCSAgICByZWFkQWxsKGluLCBuYnVmLCBpKTsKKwkgICAgY29tcGFyZShuYW1lLCAibWV0aG9kLT5zdHJlYW0gIiArIGksIGJ1ZiwgbmJ1Zik7CisJfQorCisJLy8gZW5jb2RlIHdpdGggc3RyZWFtLCBkZWNvZGUgd2l0aCBzdHJlYW0sIG1hbnkgYnVmZmVycworCisJLy8gZmlyc3QsIGZpbGwgdGhlIG91dHB1dCB3aXRoIG11bHRpcGxlIGJ1ZmZlcnMsIHVwIHRvIHRoZSBsaW1pdAorCWludCBsaW1pdCA9IDEwMDAwOwkJLy8gbW9yZSB0aGFuIDhLCisJYm9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworCW9zID0gbmV3IEJBU0U2NEVuY29kZXJTdHJlYW0oYm9zKTsKKwlmb3IgKGludCBzaXplID0gMCwgYmxlbiA9IGJ1Zi5sZW5ndGg7IHNpemUgPCBsaW1pdDsgc2l6ZSArPSBibGVuKSB7CisJICAgIGlmIChzaXplICsgYmxlbiA+IGxpbWl0KSB7CisJCWJsZW4gPSBsaW1pdCAtIHNpemU7CisJCS8vIHdyaXRlIG91dCBwYXJ0aWFsIGJ1ZmZlciwgc3RhcnRpbmcgYXQgbm9uLXplcm8gb2Zmc2V0CisJCW9zLndyaXRlKGJ1ZiwgYnVmLmxlbmd0aCAtIGJsZW4sIGJsZW4pOworCSAgICB9IGVsc2UKKwkJb3Mud3JpdGUoYnVmKTsKKwl9CisJb3MuZmx1c2goKTsKKwlvcy5jbG9zZSgpOworCisJLy8gcmVhZCB0aGUgZW5jb2RlZCBvdXRwdXQgYW5kIGNoZWNrIHRoZSBsaW5lIGxlbmd0aAorCVN0cmluZyB0eXBlID0gImJpZyBzdHJlYW0iOwkJLy8gZm9yIGVycm9yIG1lc3NhZ2VzIGJlbG93CisJc2J1ZiA9IGJvcy50b0J5dGVBcnJheSgpOworCWJpbiA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShzYnVmKTsKKwlieXRlW10gaW5idWYgPSBuZXcgYnl0ZVs3OF07CisJZm9yIChpbnQgc2l6ZSA9IDAsIGJsZW4gPSA3Njsgc2l6ZSA8IGxpbWl0OyBzaXplICs9IGJsZW4pIHsKKwkgICAgaWYgKHNpemUgKyBibGVuID4gbGltaXQpIHsKKwkJYmxlbiA9IGxpbWl0IC0gc2l6ZTsKKwkJaW50IG4gPSBiaW4ucmVhZChpbmJ1ZiwgMCwgYmxlbik7CisJCUFzc2VydC5hc3NlcnRFcXVhbHMobmFtZSArICI6ICIgKyB0eXBlICsKKwkJICAgICIgcmVhZCB3cm9uZyBzaXplIGF0IG9mZnNldCAiICsgKHNpemUgKyBibGVuKSwgYmxlbiwgbik7CisJICAgIH0gZWxzZSB7CisJCWludCBuID0gYmluLnJlYWQoaW5idWYsIDAsIGJsZW4gKyAyKTsKKwkJQXNzZXJ0LmFzc2VydEVxdWFscyhuYW1lICsgIjogIiArIHR5cGUgKworCQkgICAgIiByZWFkIHdyb25nIHNpemUgYXQgb2Zmc2V0ICIgKyAoc2l6ZSArIGJsZW4pLCBibGVuICsgMiwgbik7CisJCUFzc2VydC5hc3NlcnRUcnVlKG5hbWUgKyAiOiAiICsgdHlwZSArCisJCSAgICAiIG5vIENSTEY6IGF0IG9mZnNldCAiICsgKHNpemUgKyBibGVuKSwKKwkJICAgIGluYnVmW2JsZW5dID09IChieXRlKSdccicgJiYgaW5idWZbYmxlbisxXSA9PSAoYnl0ZSknXG4nKTsKKwkgICAgfQorCX0KKworCS8vIGRlY29kZSB0aGUgb3V0cHV0IGFuZCBjaGVjayB0aGUgZGF0YQorCWJpbiA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShzYnVmKTsKKwlpbiA9IG5ldyBCQVNFNjREZWNvZGVyU3RyZWFtKGJpbik7CisJaW5idWYgPSBuZXcgYnl0ZVtidWYubGVuZ3RoXTsKKwlmb3IgKGludCBzaXplID0gMCwgYmxlbiA9IGJ1Zi5sZW5ndGg7IHNpemUgPCBsaW1pdDsgc2l6ZSArPSBibGVuKSB7CisJICAgIGlmIChzaXplICsgYmxlbiA+IGxpbWl0KQorCQlibGVuID0gbGltaXQgLSBzaXplOworCSAgICBpbnQgbiA9IGluLnJlYWQobmJ1ZiwgMCwgYmxlbik7CisJICAgIEFzc2VydC5hc3NlcnRFcXVhbHMobmFtZSArICI6ICIgKyB0eXBlICsKKwkJIiByZWFkIGRlY29kZWQgd3Jvbmcgc2l6ZSBhdCBvZmZzZXQgIiArIChzaXplICsgYmxlbiksIGJsZW4sIG4pOworCSAgICBpZiAoYmxlbiAhPSBidWYubGVuZ3RoKSB7CisJCS8vIGhhdmUgdG8gY29tcGFyZSB3aXRoIGVuZCBvZiBvcmlnaW5hbCBidWZmZXIKKwkJYnl0ZVtdIGNidWYgPSBuZXcgYnl0ZVtibGVuXTsKKwkJU3lzdGVtLmFycmF5Y29weShidWYsIGJ1Zi5sZW5ndGggLSBibGVuLCBjYnVmLCAwLCBibGVuKTsKKwkJLy8gbmVlZCBhIHZlcnNpb24gb2YgdGhlIHJlYWQgYnVmZmVyIHRoYXQncyB0aGUgcmlnaHQgc2l6ZQorCQlieXRlW10gY25idWYgPSBuZXcgYnl0ZVtibGVuXTsKKwkJU3lzdGVtLmFycmF5Y29weShuYnVmLCAwLCBjbmJ1ZiwgMCwgYmxlbik7CisJCWNvbXBhcmUobmFtZSwgdHlwZSwgY2J1ZiwgY25idWYpOworCSAgICB9IGVsc2UgeworCQljb21wYXJlKG5hbWUsIHR5cGUsIGJ1ZiwgbmJ1Zik7CisJICAgIH0KKwl9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgYnl0ZVtdIG9yaWdMaW5lOworICAgIHByaXZhdGUgc3RhdGljIGJ5dGVbXSBlbmNvZGVkTGluZTsKKyAgICBzdGF0aWMgeworCXRyeSB7CisJICAgIG9yaWdMaW5lID0KKwkJIjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCIuCisJCSAgICBnZXRCeXRlcygidXMtYXNjaWkiKTsKKwkgICAgZW5jb2RlZExpbmUgPQorCQkoIk1EQXdNREF3TURBd01EQXdNREF3TURBd01EQXdNREF3TURBd01EQXciICsKKwkJIk1EQXdNREF3TURBd01EQXdNREF3TURBd01EQXdNREF3TURBdyIgKyAiXHJcbiIpLgorCQkgICAgZ2V0Qnl0ZXMoInVzLWFzY2lpIik7CisJfSBjYXRjaCAoVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiB1ZXgpIHsKKwkgICAgLy8gc2hvdWxkIG5ldmVyIGhhcHBlbjsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IENSTEYgaXMgaW5zZXJ0ZWQgYXQgdGhlIHJpZ2h0IHBsYWNlLgorICAgICAqIFRlc3QgY29tYmluYXRpb25zIG9mIGFycmF5IHdyaXRlcyBvZiBkaWZmZXJlbnQgc2l6ZXMKKyAgICAgKiBhbmQgc2luZ2xlIGJ5dGUgd3JpdGVzLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdExpbmVMZW5ndGgoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlmb3IgKGludCBpID0gMDsgaSA8IG9yaWdMaW5lLmxlbmd0aDsgaSsrKSB7CisJICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBib3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisKKwkgICAgT3V0cHV0U3RyZWFtIG9zID0gbmV3IEJBU0U2NEVuY29kZXJTdHJlYW0oYm9zKTsKKwkgICAgb3Mud3JpdGUob3JpZ0xpbmUsIDAsIGkpOworCSAgICBvcy53cml0ZShvcmlnTGluZSwgaSwgb3JpZ0xpbmUubGVuZ3RoIC0gaSk7CisJICAgIG9zLndyaXRlKChieXRlKScwJyk7CisJICAgIG9zLmZsdXNoKCk7CisJICAgIG9zLmNsb3NlKCk7CisKKwkgICAgYnl0ZVtdIGxpbmUgPSBuZXcgYnl0ZVtlbmNvZGVkTGluZS5sZW5ndGhdOworCSAgICBTeXN0ZW0uYXJyYXljb3B5KGJvcy50b0J5dGVBcnJheSgpLCAwLCBsaW5lLCAwLCBsaW5lLmxlbmd0aCk7CisJICAgIEFzc2VydC5hc3NlcnRBcnJheUVxdWFscygiZW5jb2RlZCBsaW5lICIgKyBpLCBlbmNvZGVkTGluZSwgbGluZSk7CisJfQorCisJZm9yIChpbnQgaSA9IDA7IGkgPCBvcmlnTGluZS5sZW5ndGg7IGkrKykgeworCSAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworCisJICAgIE91dHB1dFN0cmVhbSBvcyA9IG5ldyBCQVNFNjRFbmNvZGVyU3RyZWFtKGJvcyk7CisJICAgIG9zLndyaXRlKG9yaWdMaW5lLCAwLCBpKTsKKwkgICAgb3Mud3JpdGUob3JpZ0xpbmUsIGksIG9yaWdMaW5lLmxlbmd0aCAtIGkpOworCSAgICBvcy53cml0ZShvcmlnTGluZSk7CisJICAgIG9zLmZsdXNoKCk7CisJICAgIG9zLmNsb3NlKCk7CisKKwkgICAgYnl0ZVtdIGxpbmUgPSBuZXcgYnl0ZVtlbmNvZGVkTGluZS5sZW5ndGhdOworCSAgICBTeXN0ZW0uYXJyYXljb3B5KGJvcy50b0J5dGVBcnJheSgpLCAwLCBsaW5lLCAwLCBsaW5lLmxlbmd0aCk7CisJICAgIEFzc2VydC5hc3NlcnRBcnJheUVxdWFscygiYWxsIGFycmF5cywgZW5jb2RlZCBsaW5lICIgKyBpLAorCQkJCQllbmNvZGVkTGluZSwgbGluZSk7CisJfQorCisJZm9yIChpbnQgaSA9IDE7IGkgPCA1OyBpKyspIHsKKwkgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKworCSAgICBPdXRwdXRTdHJlYW0gb3MgPSBuZXcgQkFTRTY0RW5jb2RlclN0cmVhbShib3MpOworCSAgICBmb3IgKGludCBqID0gMDsgaiA8IGk7IGorKykKKwkJb3Mud3JpdGUoKGJ5dGUpJzAnKTsKKwkgICAgb3Mud3JpdGUob3JpZ0xpbmUsIGksIG9yaWdMaW5lLmxlbmd0aCAtIGkpOworCSAgICBvcy53cml0ZSgoYnl0ZSknMCcpOworCSAgICBvcy5mbHVzaCgpOworCSAgICBvcy5jbG9zZSgpOworCisJICAgIGJ5dGVbXSBsaW5lID0gbmV3IGJ5dGVbZW5jb2RlZExpbmUubGVuZ3RoXTsKKwkgICAgU3lzdGVtLmFycmF5Y29weShib3MudG9CeXRlQXJyYXkoKSwgMCwgbGluZSwgMCwgbGluZS5sZW5ndGgpOworCSAgICBBc3NlcnQuYXNzZXJ0QXJyYXlFcXVhbHMoInNpbmdsZSBieXRlIGZpcnN0IGVuY29kZWQgbGluZSAiICsgaSwKKwkJCQkJZW5jb2RlZExpbmUsIGxpbmUpOworCX0KKwlmb3IgKGludCBpID0gb3JpZ0xpbmUubGVuZ3RoIC0gNTsgaSA8IG9yaWdMaW5lLmxlbmd0aDsgaSsrKSB7CisJICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBib3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisKKwkgICAgT3V0cHV0U3RyZWFtIG9zID0gbmV3IEJBU0U2NEVuY29kZXJTdHJlYW0oYm9zKTsKKwkgICAgb3Mud3JpdGUob3JpZ0xpbmUsIDAsIGkpOworCSAgICBmb3IgKGludCBqID0gMDsgaiA8IG9yaWdMaW5lLmxlbmd0aCAtIGk7IGorKykKKwkJb3Mud3JpdGUoKGJ5dGUpJzAnKTsKKwkgICAgb3Mud3JpdGUoKGJ5dGUpJzAnKTsKKwkgICAgb3MuZmx1c2goKTsKKwkgICAgb3MuY2xvc2UoKTsKKworCSAgICBieXRlW10gbGluZSA9IG5ldyBieXRlW2VuY29kZWRMaW5lLmxlbmd0aF07CisJICAgIFN5c3RlbS5hcnJheWNvcHkoYm9zLnRvQnl0ZUFycmF5KCksIDAsIGxpbmUsIDAsIGxpbmUubGVuZ3RoKTsKKwkgICAgQXNzZXJ0LmFzc2VydEFycmF5RXF1YWxzKCJzaW5nbGUgYnl0ZSBsYXN0IGVuY29kZWQgbGluZSAiICsgaSwKKwkJCQkJZW5jb2RlZExpbmUsIGxpbmUpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaWxsIHRoZSBidWZmZXIgZnJvbSB0aGUgc3RyZWFtLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgcmVhZEFsbChJbnB1dFN0cmVhbSBpbiwgYnl0ZVtdIGJ1ZiwgaW50IHJlYWRzaXplKQorCQkJCXRocm93cyBJT0V4Y2VwdGlvbiB7CisJaW50IG5lZWQgPSBidWYubGVuZ3RoOworCWludCBvZmYgPSAwOyAKKwlpbnQgZ290OworCXdoaWxlIChuZWVkID4gMCkgeworCSAgICBnb3QgPSBpbi5yZWFkKGJ1Ziwgb2ZmLCBuZWVkID4gcmVhZHNpemUgPyByZWFkc2l6ZSA6IG5lZWQpOworCSAgICBpZiAoZ290IDw9IDApCisJCWJyZWFrOworCSAgICBvZmYgKz0gZ290OworCSAgICBuZWVkIC09IGdvdDsKKwl9CisJaWYgKG5lZWQgIT0gMCkKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKCJjb3VsZG4ndCByZWFkIGFsbCBieXRlcyIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXBhcmUgdGhlIHR3byBidWZmZXJzLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgY29tcGFyZShTdHJpbmcgbmFtZSwgU3RyaW5nIHR5cGUsCisJCQkJYnl0ZVtdIGJ1ZiwgYnl0ZVtdIG5idWYpIHsKKwkvKgorCWlmIChuYnVmLmxlbmd0aCAhPSBidWYubGVuZ3RoKSB7CisJICAgIFN5c3RlbS5vdXQucHJpbnRsbihuYW1lICsgIjogIiArIHR5cGUgKworCQkiIGRlY29kZWQgYXJyYXkgc2l6ZSB3cm9uZzogIiArCisJCSJnb3QgIiArIG5idWYubGVuZ3RoICsgIiwgZXhwZWN0ZWQgIiArIGJ1Zi5sZW5ndGgpOworCSAgICBkdW1wKG5hbWUgKyAiIGJ1ZiIsIGJ1Zik7CisJICAgIGR1bXAobmFtZSArICIgbmJ1ZiIsIG5idWYpOworCX0KKwkqLworCUFzc2VydC5hc3NlcnRFcXVhbHMobmFtZSArICI6ICIgKyB0eXBlICsgIiBkZWNvZGVkIGFycmF5IHNpemUgd3JvbmciLAorCQkJICAgIGJ1Zi5sZW5ndGgsIG5idWYubGVuZ3RoKTsKKwlmb3IgKGludCBpID0gMDsgaSA8IGJ1Zi5sZW5ndGg7IGkrKykgeworCSAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKG5hbWUgKyAiOiAiICsgdHlwZSArICIgZGF0YSB3cm9uZzogaW5kZXggIiArIGksCisJCWJ1ZltpXSwgbmJ1ZltpXSk7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIER1bXAgdGhlIGNvbnRlbnRzIG9mIHRoZSBidWZmZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBkdW1wKFN0cmluZyBuYW1lLCBieXRlW10gYnVmKSB7CisJU3lzdGVtLm91dC5wcmludGxuKG5hbWUpOworCWZvciAoaW50IGkgPSAwOyBpIDwgYnVmLmxlbmd0aDsgaSsrKQorCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oYnVmW2ldKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3V0aWwvQ29udGVudFR5cGVDbGVhbmVyLmphdmEgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3V0aWwvQ29udGVudFR5cGVDbGVhbmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOThiNDU4MQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvdXRpbC9Db250ZW50VHlwZUNsZWFuZXIuamF2YQpAQCAtMCwwICsxLDEwOCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAxMCwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwudXRpbDsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0OworaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOworCitpbXBvcnQgamF2YXgubWFpbC5TZXNzaW9uOworaW1wb3J0IGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uOworaW1wb3J0IGphdmF4Lm1haWwuQm9keVBhcnQ7CitpbXBvcnQgY29tLnN1bi5tYWlsLnRlc3QuQXNjaWlTdHJpbmdJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZheC5tYWlsLmludGVybmV0Lk1pbWVQYXJ0OworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuTWltZU1lc3NhZ2U7CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC5NaW1lTXVsdGlwYXJ0OworCitpbXBvcnQgb3JnLmp1bml0Lio7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RXF1YWxzOworCisvKioKKyAqIFRlc3QgdGhlICJtYWlsLm1pbWUuY29udGVudHR5cGVoYW5kbGVyIiBwcm9wZXJ0eS4KKyAqLworcHVibGljIGNsYXNzIENvbnRlbnRUeXBlQ2xlYW5lciB7CisgCisgICAgcHJpdmF0ZSBzdGF0aWMgU2Vzc2lvbiBzID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShuZXcgUHJvcGVydGllcygpKTsKKworICAgIEBCZWZvcmVDbGFzcworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBiZWZvcmUoKSB7CisJU3lzdGVtLm91dC5wcmludGxuKCJDb250ZW50VHlwZUNsZWFuZXIiKTsKKwlTeXN0ZW0uc2V0UHJvcGVydHkoIm1haWwubWltZS5jb250ZW50dHlwZWhhbmRsZXIiLAorCSAgICBDb250ZW50VHlwZUNsZWFuZXIuY2xhc3MuZ2V0TmFtZSgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RHYXJiYWdlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1pbWVNZXNzYWdlIG0gPSBjcmVhdGVNZXNzYWdlKCk7CisJTWltZU11bHRpcGFydCBtcCA9IChNaW1lTXVsdGlwYXJ0KW0uZ2V0Q29udGVudCgpOworCUJvZHlQYXJ0IGJwID0gbXAuZ2V0Qm9keVBhcnQoMCk7CisJYXNzZXJ0RXF1YWxzKCJ0ZXh0L3BsYWluIiwgYnAuZ2V0Q29udGVudFR5cGUoKSk7CisJYXNzZXJ0RXF1YWxzKCJmaXJzdCBwYXJ0XG4iLCBicC5nZXRDb250ZW50KCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFZhbGlkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1pbWVNZXNzYWdlIG0gPSBjcmVhdGVNZXNzYWdlKCk7CisJTWltZU11bHRpcGFydCBtcCA9IChNaW1lTXVsdGlwYXJ0KW0uZ2V0Q29udGVudCgpOworCUJvZHlQYXJ0IGJwID0gbXAuZ2V0Qm9keVBhcnQoMSk7CisJYXNzZXJ0RXF1YWxzKCJ0ZXh0L3BsYWluOyBjaGFyc2V0PWlzby04ODU5LTEiLCBicC5nZXRDb250ZW50VHlwZSgpKTsKKwlhc3NlcnRFcXVhbHMoInNlY29uZCBwYXJ0XG4iLCBicC5nZXRDb250ZW50KCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEVtcHR5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1pbWVNZXNzYWdlIG0gPSBjcmVhdGVNZXNzYWdlKCk7CisJTWltZU11bHRpcGFydCBtcCA9IChNaW1lTXVsdGlwYXJ0KW0uZ2V0Q29udGVudCgpOworCUJvZHlQYXJ0IGJwID0gbXAuZ2V0Qm9keVBhcnQoMik7CisJYXNzZXJ0RXF1YWxzKCJ0ZXh0L3BsYWluIiwgYnAuZ2V0Q29udGVudFR5cGUoKSk7CisJYXNzZXJ0RXF1YWxzKCJ0aGlyZCBwYXJ0XG4iLCBicC5nZXRDb250ZW50KCkpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGNsZWFuQ29udGVudFR5cGUoTWltZVBhcnQgbXAsIFN0cmluZyBjb250ZW50VHlwZSkgeworCWlmIChjb250ZW50VHlwZSA9PSBudWxsKQorCSAgICByZXR1cm4gbnVsbDsKKwlpZiAoY29udGVudFR5cGUuZXF1YWxzKCJjb21wbGV0ZSBnYXJiYWdlIikpCisJICAgIHJldHVybiAidGV4dC9wbGFpbiI7CisJcmV0dXJuIGNvbnRlbnRUeXBlOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIE1pbWVNZXNzYWdlIGNyZWF0ZU1lc3NhZ2UoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIGNvbnRlbnQgPQorCSAgICAiTWltZS1WZXJzaW9uOiAxLjBcbiIgKworCSAgICAiU3ViamVjdDogRXhhbXBsZVxuIiArCisJICAgICJDb250ZW50LVR5cGU6IG11bHRpcGFydC9taXhlZDsgYm91bmRhcnk9XCItXCJcbiIgKworCSAgICAiXG4iICsKKwkgICAgInByZWFtYmxlXG4iICsKKwkgICAgIi0tLVxuIiArCisJICAgICJDb250ZW50LVR5cGU6IGNvbXBsZXRlIGdhcmJhZ2VcbiIgKworCSAgICAiXG4iICsKKwkgICAgImZpcnN0IHBhcnRcbiIgKworCSAgICAiXG4iICsKKwkgICAgIi0tLVxuIiArCisJICAgICJDb250ZW50LVR5cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9aXNvLTg4NTktMVxuIiArCisJICAgICJcbiIgKworCSAgICAic2Vjb25kIHBhcnRcbiIgKworCSAgICAiXG4iICsKKwkgICAgIi0tLVxuIiArCisJICAgICJcbiIgKworCSAgICAidGhpcmQgcGFydFxuIiArCisJICAgICJcbiIgKworCSAgICAiLS0tLS1cbiI7CisKKwlyZXR1cm4gbmV3IE1pbWVNZXNzYWdlKHMsIG5ldyBBc2NpaVN0cmluZ0lucHV0U3RyZWFtKGNvbnRlbnQpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3V0aWwvTGluZUlucHV0U3RyZWFtVGVzdC5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL0xpbmVJbnB1dFN0cmVhbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMjU1ZjBhCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL0xpbmVJbnB1dFN0cmVhbVRlc3QuamF2YQpAQCAtMCwwICsxLDk5IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC51dGlsOworCitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEVxdWFsczsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUcnVlOworCisvKioKKyAqIFRlc3QgaGFuZGxpbmcgb2YgbGluZSB0ZXJtaW5hdG9ycy4KKyAqIExpbmVJbnB1dFN0cmVhbSBoYW5kbGVzIHRoZXNlIGRpZmZlcmVudCBsaW5lIHRlcm1pbmF0b3JzOgorICoKKyAqCU5MCQktIFVuaXgKKyAqCUNSIExGCQktIFdpbmRvd3MsIE1JTUUKKyAqCUNSCQktIG9sZCBNYWNPUworICoJQ1IgQ1IgTEYJLSBicm9rZW4gaW50ZXJuZXQgc2VydmVycworICoKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKi8KKworcHVibGljIGNsYXNzIExpbmVJbnB1dFN0cmVhbVRlc3QgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIGxpbmVzID0geworCSJsaW5lMVxubGluZTJcbmxpbmUzXG4iLAorCSJsaW5lMVxyXG5saW5lMlxyXG5saW5lM1xyXG4iLAorCSJsaW5lMVxybGluZTJccmxpbmUzXHIiLAorCSJsaW5lMVxyXHJcbmxpbmUyXHJcclxubGluZTNcclxyXG4iCisgICAgfTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIGVtcHR5ID0geworCSJcblxuXG4iLAorCSJcclxuXHJcblxyXG4iLAorCSJcclxyXHIiLAorCSJcclxyXG5cclxyXG5cclxyXG4iCisgICAgfTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIG1peGVkID0geworCSJsaW5lMVxuXG5saW5lM1xuIiwKKwkibGluZTFcclxuXHJcbmxpbmUzXHJcbiIsCisJImxpbmUxXHJccmxpbmUzXHIiLAorCSJsaW5lMVxyXHJcblxyXHJcbmxpbmUzXHJcclxuIgorICAgIH07CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RMaW5lcygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJZm9yIChTdHJpbmcgcyA6IGxpbmVzKSB7CisJICAgIExpbmVJbnB1dFN0cmVhbSBpcyA9IGNyZWF0ZVN0cmVhbShzKTsKKwkgICAgYXNzZXJ0RXF1YWxzKCJsaW5lMSIsIGlzLnJlYWRMaW5lKCkpOworCSAgICBhc3NlcnRFcXVhbHMoImxpbmUyIiwgaXMucmVhZExpbmUoKSk7CisJICAgIGFzc2VydEVxdWFscygibGluZTMiLCBpcy5yZWFkTGluZSgpKTsKKwkgICAgYXNzZXJ0RXF1YWxzKG51bGwsIGlzLnJlYWRMaW5lKCkpOworCX0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RFbXB0eSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJZm9yIChTdHJpbmcgcyA6IGVtcHR5KSB7CisJICAgIExpbmVJbnB1dFN0cmVhbSBpcyA9IGNyZWF0ZVN0cmVhbShzKTsKKwkgICAgYXNzZXJ0RXF1YWxzKCIiLCBpcy5yZWFkTGluZSgpKTsKKwkgICAgYXNzZXJ0RXF1YWxzKCIiLCBpcy5yZWFkTGluZSgpKTsKKwkgICAgYXNzZXJ0RXF1YWxzKCIiLCBpcy5yZWFkTGluZSgpKTsKKwkgICAgYXNzZXJ0RXF1YWxzKG51bGwsIGlzLnJlYWRMaW5lKCkpOworCX0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RNaXhlZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJZm9yIChTdHJpbmcgcyA6IG1peGVkKSB7CisJICAgIExpbmVJbnB1dFN0cmVhbSBpcyA9IGNyZWF0ZVN0cmVhbShzKTsKKwkgICAgYXNzZXJ0RXF1YWxzKCJsaW5lMSIsIGlzLnJlYWRMaW5lKCkpOworCSAgICBhc3NlcnRFcXVhbHMoIiIsIGlzLnJlYWRMaW5lKCkpOworCSAgICBhc3NlcnRFcXVhbHMoImxpbmUzIiwgaXMucmVhZExpbmUoKSk7CisJICAgIGFzc2VydEVxdWFscyhudWxsLCBpcy5yZWFkTGluZSgpKTsKKwl9CisgICAgfQorCisgICAgcHJpdmF0ZSBMaW5lSW5wdXRTdHJlYW0gY3JlYXRlU3RyZWFtKFN0cmluZyBzKSB7CisJdHJ5IHsKKwlyZXR1cm4gbmV3IExpbmVJbnB1dFN0cmVhbSgKKwkgICAgbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKHMuZ2V0Qnl0ZXMoInVzLWFzY2lpIikpKTsKKwl9IGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGV4KSB7CisJICAgIHJldHVybiBudWxsOwkvLyBzaG91bGQgbmV2ZXIgaGFwcGVuCisJfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvdXRpbC9NaW1lVXRpbFRlc3RTdWl0ZS5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL01pbWVVdGlsVGVzdFN1aXRlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDYxMzFmZQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvdXRpbC9NaW1lVXRpbFRlc3RTdWl0ZS5qYXZhCkBAIC0wLDAgKzEsMzQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMTAsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLnV0aWw7CisKK2ltcG9ydCBvcmcuanVuaXQucnVubmVyLlJ1bldpdGg7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lcnMuU3VpdGUuU3VpdGVDbGFzc2VzOworCitpbXBvcnQgY29tLnN1bi5tYWlsLnRlc3QuQ2xhc3NMb2FkZXJTdWl0ZTsKK2ltcG9ydCBjb20uc3VuLm1haWwudGVzdC5DbGFzc0xvYWRlclN1aXRlLlRlc3RDbGFzczsKKworLyoqCisgKiBTdWl0ZSBvZiBNaW1lVXRpbCB0ZXN0cyB0aGF0IG5lZWQgdG8gYmUgcnVuIGluIGEgc2VwYXJhdGUgY2xhc3MgbG9hZGVyLgorICovCitAUnVuV2l0aChDbGFzc0xvYWRlclN1aXRlLmNsYXNzKQorQFRlc3RDbGFzcyhNaW1lVXRpbC5jbGFzcykKK0BTdWl0ZUNsYXNzZXMoIHsKKyAgICBDb250ZW50VHlwZUNsZWFuZXIuY2xhc3MKK30pCitwdWJsaWMgY2xhc3MgTWltZVV0aWxUZXN0U3VpdGUgeworfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL1Byb3BVdGlsVGVzdC5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL1Byb3BVdGlsVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNkNjY5NWUKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3V0aWwvUHJvcFV0aWxUZXN0LmphdmEKQEAgLTAsMCArMSwxODEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDksIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLnV0aWw7CisKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKK2ltcG9ydCBqYXZheC5tYWlsLlNlc3Npb247CisKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRFcXVhbHM7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VHJ1ZTsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworLyoqCisgKiBUZXN0IHRoYXQgdGhlIFByb3BVdGlsIG1ldGhvZHMgcmV0dXJuIHRoZSBjb3JyZWN0IHZhbHVlcywKKyAqIGVzcGVjaWFsbHkgd2hlbiBkZWZhdWx0cyBhbmQgbm9uLVN0cmluZyB2YWx1ZXMgYXJlIGNvbnNpZGVyZWQuCisgKi8KK3B1YmxpYyBjbGFzcyBQcm9wVXRpbFRlc3QgeworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEludCgpIHRocm93cyBFeGNlcHRpb24geworCVByb3BlcnRpZXMgcHJvcHMgPSBuZXcgUHJvcGVydGllcygpOworCXByb3BzLnNldFByb3BlcnR5KCJ0ZXN0IiwgIjIiKTsKKwlhc3NlcnRFcXVhbHMoUHJvcFV0aWwuZ2V0SW50UHJvcGVydHkocHJvcHMsICJ0ZXN0IiwgMSksIDIpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEludERlZigpIHRocm93cyBFeGNlcHRpb24geworCVByb3BlcnRpZXMgcHJvcHMgPSBuZXcgUHJvcGVydGllcygpOworCWFzc2VydEVxdWFscyhQcm9wVXRpbC5nZXRJbnRQcm9wZXJ0eShwcm9wcywgInRlc3QiLCAxKSwgMSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW50RGVmUHJvcCgpIHRocm93cyBFeGNlcHRpb24geworCVByb3BlcnRpZXMgZGVmcHJvcHMgPSBuZXcgUHJvcGVydGllcygpOworCWRlZnByb3BzLnNldFByb3BlcnR5KCJ0ZXN0IiwgIjIiKTsKKwlQcm9wZXJ0aWVzIHByb3BzID0gbmV3IFByb3BlcnRpZXMoZGVmcHJvcHMpOworCWFzc2VydEVxdWFscyhQcm9wVXRpbC5nZXRJbnRQcm9wZXJ0eShwcm9wcywgInRlc3QiLCAxKSwgMik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW50ZWdlcigpIHRocm93cyBFeGNlcHRpb24geworCVByb3BlcnRpZXMgcHJvcHMgPSBuZXcgUHJvcGVydGllcygpOworCXByb3BzLnB1dCgidGVzdCIsIDIpOworCWFzc2VydEVxdWFscyhQcm9wVXRpbC5nZXRJbnRQcm9wZXJ0eShwcm9wcywgInRlc3QiLCAxKSwgMik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Qm9vbCgpIHRocm93cyBFeGNlcHRpb24geworCVByb3BlcnRpZXMgcHJvcHMgPSBuZXcgUHJvcGVydGllcygpOworCXByb3BzLnNldFByb3BlcnR5KCJ0ZXN0IiwgInRydWUiKTsKKwlhc3NlcnRUcnVlKFByb3BVdGlsLmdldEJvb2xlYW5Qcm9wZXJ0eShwcm9wcywgInRlc3QiLCBmYWxzZSkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEJvb2xEZWYoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlQcm9wZXJ0aWVzIHByb3BzID0gbmV3IFByb3BlcnRpZXMoKTsKKwlhc3NlcnRUcnVlKFByb3BVdGlsLmdldEJvb2xlYW5Qcm9wZXJ0eShwcm9wcywgInRlc3QiLCB0cnVlKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Qm9vbERlZlByb3AoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlQcm9wZXJ0aWVzIGRlZnByb3BzID0gbmV3IFByb3BlcnRpZXMoKTsKKwlkZWZwcm9wcy5zZXRQcm9wZXJ0eSgidGVzdCIsICJ0cnVlIik7CisJUHJvcGVydGllcyBwcm9wcyA9IG5ldyBQcm9wZXJ0aWVzKGRlZnByb3BzKTsKKwlhc3NlcnRUcnVlKFByb3BVdGlsLmdldEJvb2xlYW5Qcm9wZXJ0eShwcm9wcywgInRlc3QiLCBmYWxzZSkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEJvb2xlYW4oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlQcm9wZXJ0aWVzIHByb3BzID0gbmV3IFByb3BlcnRpZXMoKTsKKwlwcm9wcy5wdXQoInRlc3QiLCB0cnVlKTsKKwlhc3NlcnRUcnVlKFByb3BVdGlsLmdldEJvb2xlYW5Qcm9wZXJ0eShwcm9wcywgInRlc3QiLCBmYWxzZSkpOworICAgIH0KKworCisgICAgLy8gdGhlIFNlc3Npb24gdmFyaWFudHMuLi4KKworICAgIEBUZXN0CisgICAgQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2Vzc2lvbkludCgpIHRocm93cyBFeGNlcHRpb24geworCVByb3BlcnRpZXMgcHJvcHMgPSBuZXcgUHJvcGVydGllcygpOworCXByb3BzLnNldFByb3BlcnR5KCJ0ZXN0IiwgIjIiKTsKKwlTZXNzaW9uIHNlc3MgPSBTZXNzaW9uLmdldEluc3RhbmNlKHByb3BzLCBudWxsKTsKKwlhc3NlcnRFcXVhbHMoUHJvcFV0aWwuZ2V0SW50U2Vzc2lvblByb3BlcnR5KHNlc3MsICJ0ZXN0IiwgMSksIDIpOworICAgIH0KKworICAgIEBUZXN0CisgICAgQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2Vzc2lvbkludERlZigpIHRocm93cyBFeGNlcHRpb24geworCVByb3BlcnRpZXMgcHJvcHMgPSBuZXcgUHJvcGVydGllcygpOworCVNlc3Npb24gc2VzcyA9IFNlc3Npb24uZ2V0SW5zdGFuY2UocHJvcHMsIG51bGwpOworCWFzc2VydEVxdWFscyhQcm9wVXRpbC5nZXRJbnRTZXNzaW9uUHJvcGVydHkoc2VzcywgInRlc3QiLCAxKSwgMSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKQorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXNzaW9uSW50RGVmUHJvcCgpIHRocm93cyBFeGNlcHRpb24geworCVByb3BlcnRpZXMgZGVmcHJvcHMgPSBuZXcgUHJvcGVydGllcygpOworCWRlZnByb3BzLnNldFByb3BlcnR5KCJ0ZXN0IiwgIjIiKTsKKwlQcm9wZXJ0aWVzIHByb3BzID0gbmV3IFByb3BlcnRpZXMoZGVmcHJvcHMpOworCVNlc3Npb24gc2VzcyA9IFNlc3Npb24uZ2V0SW5zdGFuY2UocHJvcHMsIG51bGwpOworCWFzc2VydEVxdWFscyhQcm9wVXRpbC5nZXRJbnRTZXNzaW9uUHJvcGVydHkoc2VzcywgInRlc3QiLCAxKSwgMik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKQorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXNzaW9uSW50ZWdlcigpIHRocm93cyBFeGNlcHRpb24geworCVByb3BlcnRpZXMgcHJvcHMgPSBuZXcgUHJvcGVydGllcygpOworCXByb3BzLnB1dCgidGVzdCIsIDIpOworCVNlc3Npb24gc2VzcyA9IFNlc3Npb24uZ2V0SW5zdGFuY2UocHJvcHMsIG51bGwpOworCWFzc2VydEVxdWFscyhQcm9wVXRpbC5nZXRJbnRTZXNzaW9uUHJvcGVydHkoc2VzcywgInRlc3QiLCAxKSwgMik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKQorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXNzaW9uQm9vbCgpIHRocm93cyBFeGNlcHRpb24geworCVByb3BlcnRpZXMgcHJvcHMgPSBuZXcgUHJvcGVydGllcygpOworCXByb3BzLnNldFByb3BlcnR5KCJ0ZXN0IiwgInRydWUiKTsKKwlTZXNzaW9uIHNlc3MgPSBTZXNzaW9uLmdldEluc3RhbmNlKHByb3BzLCBudWxsKTsKKwlhc3NlcnRUcnVlKFByb3BVdGlsLmdldEJvb2xlYW5TZXNzaW9uUHJvcGVydHkoc2VzcywgInRlc3QiLCBmYWxzZSkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2Vzc2lvbkJvb2xEZWYoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlQcm9wZXJ0aWVzIHByb3BzID0gbmV3IFByb3BlcnRpZXMoKTsKKwlTZXNzaW9uIHNlc3MgPSBTZXNzaW9uLmdldEluc3RhbmNlKHByb3BzLCBudWxsKTsKKwlhc3NlcnRUcnVlKFByb3BVdGlsLmdldEJvb2xlYW5TZXNzaW9uUHJvcGVydHkoc2VzcywgInRlc3QiLCB0cnVlKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKQorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXNzaW9uQm9vbERlZlByb3AoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlQcm9wZXJ0aWVzIGRlZnByb3BzID0gbmV3IFByb3BlcnRpZXMoKTsKKwlkZWZwcm9wcy5zZXRQcm9wZXJ0eSgidGVzdCIsICJ0cnVlIik7CisJUHJvcGVydGllcyBwcm9wcyA9IG5ldyBQcm9wZXJ0aWVzKGRlZnByb3BzKTsKKwlTZXNzaW9uIHNlc3MgPSBTZXNzaW9uLmdldEluc3RhbmNlKHByb3BzLCBudWxsKTsKKwlhc3NlcnRUcnVlKFByb3BVdGlsLmdldEJvb2xlYW5TZXNzaW9uUHJvcGVydHkoc2VzcywgInRlc3QiLCBmYWxzZSkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2Vzc2lvbkJvb2xlYW4oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlQcm9wZXJ0aWVzIHByb3BzID0gbmV3IFByb3BlcnRpZXMoKTsKKwlwcm9wcy5wdXQoInRlc3QiLCB0cnVlKTsKKwlTZXNzaW9uIHNlc3MgPSBTZXNzaW9uLmdldEluc3RhbmNlKHByb3BzLCBudWxsKTsKKwlhc3NlcnRUcnVlKFByb3BVdGlsLmdldEJvb2xlYW5TZXNzaW9uUHJvcGVydHkoc2VzcywgInRlc3QiLCBmYWxzZSkpOworICAgIH0KKworCisgICAgLy8gdGhlIFN5c3RlbSB2YXJpYW50cy4uLgorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3lzdGVtQm9vbCgpIHRocm93cyBFeGNlcHRpb24geworCVN5c3RlbS5zZXRQcm9wZXJ0eSgidGVzdCIsICJ0cnVlIik7CisJYXNzZXJ0VHJ1ZShQcm9wVXRpbC5nZXRCb29sZWFuU3lzdGVtUHJvcGVydHkoInRlc3QiLCBmYWxzZSkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFN5c3RlbUJvb2xEZWYoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlhc3NlcnRUcnVlKFByb3BVdGlsLmdldEJvb2xlYW5TeXN0ZW1Qcm9wZXJ0eSgidGVzdG5vdHNldCIsIHRydWUpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RTeXN0ZW1Cb29sZWFuKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJU3lzdGVtLmdldFByb3BlcnRpZXMoKS5wdXQoInRlc3Rib29sZWFuIiwgdHJ1ZSk7CisJYXNzZXJ0VHJ1ZShQcm9wVXRpbC5nZXRCb29sZWFuU3lzdGVtUHJvcGVydHkoInRlc3Rib29sZWFuIiwgZmFsc2UpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3V0aWwvUVBFbmNvZGVyU3RyZWFtVGVzdC5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL1FQRW5jb2RlclN0cmVhbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNDVhNzY4Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL1FQRW5jb2RlclN0cmVhbVRlc3QuamF2YQpAQCAtMCwwICsxLDQ0IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC51dGlsOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuUVBFbmNvZGVyU3RyZWFtOworCitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RXF1YWxzOworCisvKioKKyAqIFRlc3QgcXVvdGVkLXByaW50YWJsZSBlbmNvZGVyLgorICoKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKi8KKworcHVibGljIGNsYXNzIFFQRW5jb2RlclN0cmVhbVRlc3QgeworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCBhIHRyYWlsaW5nIHNwYWNlIGlzIGVuY29kZWQgaW4gdGhlIG91dHB1dCBzdHJlYW0uCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VHJhaWxpbmdTcGFjZSgpIHRocm93cyBFeGNlcHRpb24geworCUJ5dGVBcnJheU91dHB1dFN0cmVhbSBib3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisJUVBFbmNvZGVyU3RyZWFtIHFzID0gbmV3IFFQRW5jb2RlclN0cmVhbShib3MpOworCXFzLndyaXRlKCJ0ZXN0ICIuZ2V0Qnl0ZXMoInVzLWFzY2lpIikpOworCXFzLmZsdXNoKCk7CisJU3RyaW5nIHJlc3VsdCA9IG5ldyBTdHJpbmcoYm9zLnRvQnl0ZUFycmF5KCksICJ1cy1hc2NpaSIpOworCWFzc2VydEVxdWFscygidGVzdD0yMCIsIHJlc3VsdCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL1NvY2tldEZldGNoZXJUZXN0LmphdmEgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3V0aWwvU29ja2V0RmV0Y2hlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45OTFkNTI1Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL1NvY2tldEZldGNoZXJUZXN0LmphdmEKQEAgLTAsMCArMSwyMDYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDksIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLnV0aWw7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LlNvY2tldDsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LlN0YW5kYXJkQ2hhcnNldHM7CisKK2ltcG9ydCBjb20uc3VuLm1haWwudGVzdC5UZXN0U2VydmVyOworaW1wb3J0IGNvbS5zdW4ubWFpbC50ZXN0LlByb3RvY29sSGFuZGxlcjsKKworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5SdWxlOworaW1wb3J0IG9yZy5qdW5pdC5ydWxlcy5UaW1lb3V0OworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydFRydWU7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RmFsc2U7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuZmFpbDsKKworLyoqCisgKiBUZXN0IFNvY2tldEZldGNoZXIuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBTb2NrZXRGZXRjaGVyVGVzdCB7CisKKyAgICAvLyB0aW1lb3V0IHRoZSB0ZXN0IGluIGNhc2Ugb2YgZGVhZGxvY2sKKyAgICBAUnVsZQorICAgIHB1YmxpYyBUaW1lb3V0IGRlYWRsb2NrVGltZW91dCA9IFRpbWVvdXQuc2Vjb25kcygyMCk7CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGNvbm5lY3Rpbmcgd2l0aCBwcm94eSBob3N0IGFuZCBwb3J0LgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFByb3h5SG9zdFBvcnQoKSB7CisJYXNzZXJ0VHJ1ZSgicHJveHkgaG9zdCwgcG9ydCIsIHRlc3RQcm94eSgicHJveHkiLCAibG9jYWxob3N0IiwgIlBQUFAiKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBjb25uZWN0aW5nIHdpdGggcHJveHkgaG9zdCBhbmQgcG9ydCBhbmQgdXNlciBuYW1lIGFuZCBwYXNzd29yZC4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RQcm94eUhvc3RQb3J0VXNlclBhc3N3b3JkKCkgeworCWFzc2VydFRydWUoInByb3h5IGhvc3QsIHBvcnQsIHVzZXIsIHBhc3N3b3JkIiwKKwkgICAgdGVzdFByb3h5VXNlclBhc3N3b3JkKCJwcm94eSIsICJsb2NhbGhvc3QiLCAiUFBQUCIsICJ1c2VyIiwgInB3ZCIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGNvbm5lY3Rpbmcgd2l0aCBwcm94eSBob3N0OnBvcnQuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHJveHlIb3N0Q29sb25Qb3J0KCkgeworCWFzc2VydFRydWUoInByb3h5IGhvc3Q6cG9ydCIsIHRlc3RQcm94eSgicHJveHkiLCAibG9jYWxob3N0OlBQUFAiLCBudWxsKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCBjb25uZWN0aW5nIHdpdGggc29ja3MgaG9zdCBhbmQgcG9ydC4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RTb2Nrc0hvc3RQb3J0KCkgeworCWFzc2VydFRydWUoInNvY2tzIGhvc3QsIHBvcnQiLCB0ZXN0UHJveHkoInNvY2tzIiwgImxvY2FsaG9zdCIsICJQUFBQIikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgY29ubmVjdGluZyB3aXRoIHNvY2tzIGhvc3Q6cG9ydC4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RTb2Nrc0hvc3RDb2xvblBvcnQoKSB7CisJYXNzZXJ0VHJ1ZSgic29ja3MgaG9zdDpwb3J0IiwgdGVzdFByb3h5KCJzb2NrcyIsICJsb2NhbGhvc3Q6UFBQUCIsIG51bGwpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IGNvbm5lY3Rpbmcgd2l0aCBubyBwcm94eS4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3ROb1Byb3h5KCkgeworCWFzc2VydEZhbHNlKCJubyBwcm94eSIsIHRlc3RQcm94eSgibm9uZSIsICJsb2NhbGhvc3QiLCBudWxsKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gdGVzdFByb3h5KFN0cmluZyB0eXBlLCBTdHJpbmcgaG9zdCwgU3RyaW5nIHBvcnQpIHsKKwlyZXR1cm4gdGVzdFByb3h5VXNlclBhc3N3b3JkKHR5cGUsIGhvc3QsIHBvcnQsIG51bGwsIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIHRlc3RQcm94eVVzZXJQYXNzd29yZChTdHJpbmcgdHlwZSwgU3RyaW5nIGhvc3QsIFN0cmluZyBwb3J0LAorCQkJCQlTdHJpbmcgdXNlciwgU3RyaW5nIHB3ZCkgeworCVRlc3RTZXJ2ZXIgc2VydmVyID0gbnVsbDsKKwl0cnkgeworCSAgICBQcm94eUhhbmRsZXIgaGFuZGxlciA9IG5ldyBQcm94eUhhbmRsZXIodHlwZS5lcXVhbHMoInByb3h5IikpOworCSAgICBzZXJ2ZXIgPSBuZXcgVGVzdFNlcnZlcihoYW5kbGVyKTsKKwkgICAgc2VydmVyLnN0YXJ0KCk7CisJICAgIFN0cmluZyBzcG9ydCA9ICIiICsgc2VydmVyLmdldFBvcnQoKTsKKworCSAgICAvL1N5c3RlbS5zZXRQcm9wZXJ0eSgibWFpbC5zb2NrZXQuZGVidWciLCAidHJ1ZSIpOworCSAgICBQcm9wZXJ0aWVzIHByb3BlcnRpZXMgPSBuZXcgUHJvcGVydGllcygpOworCSAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLnRlc3QuaG9zdCIsICJsb2NhbGhvc3QiKTsKKwkgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC50ZXN0LnBvcnQiLCAiMiIpOworCSAgICBwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLnRlc3QuIiArIHR5cGUgKyAiLmhvc3QiLAorCQkJCSAgICBob3N0LnJlcGxhY2UoIlBQUFAiLCBzcG9ydCkpOworCSAgICBpZiAocG9ydCAhPSBudWxsKQorCQlwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLnRlc3QuIiArIHR5cGUgKyAiLnBvcnQiLAorCQkJCSAgICBwb3J0LnJlcGxhY2UoIlBQUFAiLCBzcG9ydCkpOworCSAgICBpZiAodXNlciAhPSBudWxsKQorCQlwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLnRlc3QuIiArIHR5cGUgKyAiLnVzZXIiLCB1c2VyKTsKKwkgICAgaWYgKHB3ZCAhPSBudWxsKQorCQlwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLnRlc3QuIiArIHR5cGUgKyAiLnBhc3N3b3JkIiwgcHdkKTsKKworCSAgICBTb2NrZXQgcyA9IG51bGw7CisJICAgIHRyeSB7CisJCXMgPSBTb2NrZXRGZXRjaGVyLmdldFNvY2tldCgibG9jYWxob3N0IiwgMiwKKwkJCQkJICAgIHByb3BlcnRpZXMsICJtYWlsLnRlc3QiLCBmYWxzZSk7CisJICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCQkvLyBpZ25vcmUgZmFpbHVyZSwgd2hpY2ggaXMgZXhwZWN0ZWQKKwkJLy9TeXN0ZW0ub3V0LnByaW50bG4oZXgpOworCQkvL2V4LnByaW50U3RhY2tUcmFjZSgpOworCSAgICB9IGZpbmFsbHkgeworCQlpZiAocyAhPSBudWxsKQorCQkgICAgcy5jbG9zZSgpOworCSAgICB9CisJICAgIGlmICghaGFuZGxlci5nZXRDb25uZWN0ZWQoKSkKKwkJcmV0dXJuIGZhbHNlOworCSAgICBpZiAodXNlciAhPSBudWxsICYmIHB3ZCAhPSBudWxsKQorCQlyZXR1cm4gKHVzZXIgKyAiOiIgKyBwd2QpLmVxdWFscyhoYW5kbGVyLmdldFVzZXJQYXNzd29yZCgpKTsKKwkgICAgZWxzZQorCQlyZXR1cm4gdHJ1ZTsKKworCX0gY2F0Y2ggKGZpbmFsIEV4Y2VwdGlvbiBlKSB7CisJICAgIC8vZS5wcmludFN0YWNrVHJhY2UoKTsKKwkgICAgZmFpbChlLmdldE1lc3NhZ2UoKSk7CisJICAgIHJldHVybiBmYWxzZTsJLy8gWFhYIC0gZG9lc24ndCBtYXR0ZXIKKwl9IGZpbmFsbHkgeworCSAgICBpZiAoc2VydmVyICE9IG51bGwpIHsKKwkJc2VydmVyLnF1aXQoKTsKKwkgICAgfQorCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDdXN0b20gaGFuZGxlci4gIFJlbWVtYmVyIHdoZXRoZXIgYW55IGRhdGEgd2FzIHNlbnQKKyAgICAgKiBhbmQgc2F2ZSB1c2VyL3Bhc3N3b3JkIHN0cmluZzsKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBQcm94eUhhbmRsZXIgZXh0ZW5kcyBQcm90b2NvbEhhbmRsZXIgeworCXByaXZhdGUgYm9vbGVhbiBodHRwOworCisJLy8gbXVzdCBiZSBzdGF0aWMgYmVjYXVzZSBoYW5kbGVyIGlzIGNsb25lZCBmb3IgZWFjaCBjb25uZWN0aW9uCisJcHJpdmF0ZSBzdGF0aWMgdm9sYXRpbGUgYm9vbGVhbiBjb25uZWN0ZWQ7CisJcHJpdmF0ZSBzdGF0aWMgdm9sYXRpbGUgU3RyaW5nIHVzZXJQYXNzd29yZDsKKworCXB1YmxpYyBQcm94eUhhbmRsZXIoYm9vbGVhbiBodHRwKSB7CisJICAgIHRoaXMuaHR0cCA9IGh0dHA7CisJICAgIGNvbm5lY3RlZCA9IGZhbHNlOworCX0KKworCUBPdmVycmlkZQorCXB1YmxpYyB2b2lkIGhhbmRsZUNvbW1hbmQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCSAgICBpZiAoIWh0dHApIHsKKwkJaW50IGMgPSBpbi5yZWFkKCk7CisJCWlmIChjID49IDApIHsKKwkJICAgIC8vIGFueSBkYXRhIG1lYW5zIGEgcmVhbCBjbGllbnQgY29ubmVjdGVkCisJCSAgICBjb25uZWN0ZWQgPSB0cnVlOworCQl9CisJCWV4aXQoKTsKKwkgICAgfQorCisJICAgIC8vIGVsc2UsIGh0dHAuLi4KKwkgICAgU3RyaW5nIGxpbmU7CisJICAgIHdoaWxlICgobGluZSA9IHJlYWRMaW5lKCkpICE9IG51bGwpIHsKKwkJLy8gYW55IGRhdGEgbWVhbnMgYSByZWFsIGNsaWVudCBjb25uZWN0ZWQKKwkJY29ubmVjdGVkID0gdHJ1ZTsKKwkJaWYgKGxpbmUubGVuZ3RoKCkgPT0gMCkKKwkJICAgIGJyZWFrOworCQlpZiAobGluZS5zdGFydHNXaXRoKCJQcm94eS1BdXRob3JpemF0aW9uOiIpKSB7CisJCSAgICBpbnQgaSA9IGxpbmUuaW5kZXhPZigiQmFzaWMgIikgKyA2OworCQkgICAgU3RyaW5nIHVwID0gbGluZS5zdWJzdHJpbmcoaSk7CisJCSAgICB1c2VyUGFzc3dvcmQgPSBuZXcgU3RyaW5nKEJBU0U2NERlY29kZXJTdHJlYW0uZGVjb2RlKAorCQkJCSAgICB1cC5nZXRCeXRlcyhTdGFuZGFyZENoYXJzZXRzLlVTX0FTQ0lJKSksCisJCQkJICAgIFN0YW5kYXJkQ2hhcnNldHMuVVRGXzgpOworCQl9CisJICAgIH0KKwkgICAgZXhpdCgpOworCX0KKworCXB1YmxpYyBib29sZWFuIGdldENvbm5lY3RlZCgpIHsKKwkgICAgcmV0dXJuIGNvbm5lY3RlZDsKKwl9CisKKwlwdWJsaWMgU3RyaW5nIGdldFVzZXJQYXNzd29yZCgpIHsKKwkgICAgcmV0dXJuIHVzZXJQYXNzd29yZDsKKwl9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL1VVRGVjb2RlclN0cmVhbVRlc3QuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvdXRpbC9VVURlY29kZXJTdHJlYW1UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTBjNzk0MgotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvdXRpbC9VVURlY29kZXJTdHJlYW1UZXN0LmphdmEKQEAgLTAsMCArMSwyNzEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLnV0aWw7CisKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YS51dGlsLio7CitpbXBvcnQgY29tLnN1bi5tYWlsLnV0aWwuVVVEZWNvZGVyU3RyZWFtOworCitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LkFzc2VydDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVyLlJ1bldpdGg7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lcnMuUGFyYW1ldGVyaXplZDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVycy5QYXJhbWV0ZXJpemVkLlBhcmFtZXRlcnM7CisKKy8qKgorICogVGVzdCB1dWRlY29kZXIuCisgKgorICogQGF1dGhvciBCaWxsIFNoYW5ub24KKyAqLworCitAUnVuV2l0aChQYXJhbWV0ZXJpemVkLmNsYXNzKQorcHVibGljIGNsYXNzIFVVRGVjb2RlclN0cmVhbVRlc3QgeworICAgIHByaXZhdGUgVGVzdERhdGEgZGF0YTsKKworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gZ2VuX3Rlc3RfaW5wdXQgPSBmYWxzZTsJLy8gb3V0cHV0IGdvb2QKKyAgICBwcml2YXRlIHN0YXRpYyBpbnQgZXJyb3JzID0gMDsJCS8vIG51bWJlciBvZiBlcnJvcnMgZGV0ZWN0ZWQKKworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4ganVuaXQ7CisKKyAgICBzdGF0aWMgY2xhc3MgVGVzdERhdGEgeworCXB1YmxpYyBTdHJpbmcgbmFtZTsKKwlwdWJsaWMgYm9vbGVhbiBpZ25vcmVFcnJvcnM7CisJcHVibGljIGJvb2xlYW4gaWdub3JlTWlzc2luZ0JlZ2luRW5kOworCXB1YmxpYyBieXRlW10gaW5wdXQ7CisJcHVibGljIGJ5dGVbXSBleHBlY3RlZE91dHB1dDsKKwlwdWJsaWMgU3RyaW5nIGV4cGVjdGVkRXhjZXB0aW9uOworICAgIH0KKworICAgIHB1YmxpYyBVVURlY29kZXJTdHJlYW1UZXN0KFRlc3REYXRhIHQpIHsKKwlkYXRhID0gdDsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3REYXRhKCkgeworCXRlc3QoZGF0YSk7CisgICAgfQorCisgICAgQFBhcmFtZXRlcnMKKyAgICBwdWJsaWMgc3RhdGljIENvbGxlY3Rpb248VGVzdERhdGFbXT4gZGF0YSgpIHRocm93cyBFeGNlcHRpb24geworCWp1bml0ID0gdHJ1ZTsKKwkvLyBYWFggLSBncmF0dWl0b3VzIGFycmF5IHJlcXVpcmVtZW50CisJTGlzdDxUZXN0RGF0YVtdPiB0ZXN0RGF0YSA9IG5ldyBBcnJheUxpc3Q8PigpOworCUJ1ZmZlcmVkUmVhZGVyIGluID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBJbnB1dFN0cmVhbVJlYWRlcigKKwkgICAgVVVEZWNvZGVyU3RyZWFtVGVzdC5jbGFzcy5nZXRSZXNvdXJjZUFzU3RyZWFtKCJ1dWRhdGEiKSkpOworCVRlc3REYXRhIHQ7CisJd2hpbGUgKCh0ID0gcGFyc2UoaW4pKSAhPSBudWxsKQorCSAgICB0ZXN0RGF0YS5hZGQobmV3IFRlc3REYXRhW10geyB0IH0pOworCXJldHVybiB0ZXN0RGF0YTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmcgYXJndltdKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlpbnQgb3B0aW5kOworCS8vIFhYWCAtIGFsbCBvcHRpb25zIGN1cnJlbnRseSBpZ25vcmVkCisJZm9yIChvcHRpbmQgPSAwOyBvcHRpbmQgPCBhcmd2Lmxlbmd0aDsgb3B0aW5kKyspIHsKKwkgICAgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi0iKSkgeworCQkvLyBpZ25vcmUKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItZyIpKSB7CisJCWdlbl90ZXN0X2lucHV0ID0gdHJ1ZTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItLSIpKSB7CisJCW9wdGluZCsrOworCQlicmVhazsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uc3RhcnRzV2l0aCgiLSIpKSB7CisJCVN5c3RlbS5vdXQucHJpbnRsbigKKwkJICAgICJVc2FnZTogdXV0ZXN0IFstZ10gWy1dIik7CisJCVN5c3RlbS5leGl0KDEpOworCSAgICB9IGVsc2UgeworCQlicmVhazsKKwkgICAgfQorCX0KKworCS8vIHJlYWQgZnJvbSBzdGRpbgorCUJ1ZmZlcmVkUmVhZGVyIGluID0KKwkgICAgbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBJbnB1dFN0cmVhbVJlYWRlcihTeXN0ZW0uaW4pKTsKKworCVRlc3REYXRhIHQ7CisJd2hpbGUgKCh0ID0gcGFyc2UoaW4pKSAhPSBudWxsKQorCSAgICB0ZXN0KHQpOworCVN5c3RlbS5leGl0KGVycm9ycyk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBQYXJzZSB0aGUgaW5wdXQsIHJldHVybmluZyBhIHRlc3QgY2FzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFRlc3REYXRhIHBhcnNlKEJ1ZmZlcmVkUmVhZGVyIGluKSB0aHJvd3MgRXhjZXB0aW9uIHsKKworCVN0cmluZyBsaW5lID0gbnVsbDsKKwlmb3IgKDs7KSB7CisJICAgIGxpbmUgPSBpbi5yZWFkTGluZSgpOworCSAgICBpZiAobGluZSA9PSBudWxsKQorCQlyZXR1cm4gbnVsbDsKKwkgICAgaWYgKGxpbmUubGVuZ3RoKCkgPT0gMCB8fCBsaW5lLnN0YXJ0c1dpdGgoIiMiKSkKKwkJY29udGludWU7CisKKwkgICAgaWYgKCFsaW5lLnN0YXJ0c1dpdGgoIlRFU1QiKSkKKwkJdGhyb3cgbmV3IEV4Y2VwdGlvbigiQmFkIHRlc3QgZGF0YSBmb3JtYXQiKTsKKwkgICAgYnJlYWs7CisJfQorCisJVGVzdERhdGEgdCA9IG5ldyBUZXN0RGF0YSgpOworCWludCBpID0gbGluZS5pbmRleE9mKCcgJyk7CS8vIFhYWCAtIGNydWRlCisJdC5uYW1lID0gbGluZS5zdWJzdHJpbmcoaSArIDEpOworCisJbGluZSA9IGluLnJlYWRMaW5lKCk7CisJU3RyaW5nVG9rZW5pemVyIHN0ID0gbmV3IFN0cmluZ1Rva2VuaXplcihsaW5lKTsKKwlTdHJpbmcgdG9rID0gc3QubmV4dFRva2VuKCk7CisJaWYgKCF0b2suZXF1YWxzKCJEQVRBIikpCisJICAgIHRocm93IG5ldyBFeGNlcHRpb24oIkJhZCB0ZXN0IGRhdGEgZm9ybWF0OiAiICsgbGluZSk7CisJd2hpbGUgKHN0Lmhhc01vcmVUb2tlbnMoKSkgeworCSAgICB0b2sgPSBzdC5uZXh0VG9rZW4oKTsKKwkgICAgaWYgKHRvay5lcXVhbHMoImlnbm9yZUVycm9ycyIpKQorCQl0Lmlnbm9yZUVycm9ycyA9IHRydWU7CisJICAgIGVsc2UgaWYgKHRvay5lcXVhbHMoImlnbm9yZU1pc3NpbmdCZWdpbkVuZCIpKQorCQl0Lmlnbm9yZU1pc3NpbmdCZWdpbkVuZCA9IHRydWU7CisJICAgIGVsc2UKKwkJdGhyb3cgbmV3IEV4Y2VwdGlvbigiQmFkIERBVEEgb3B0aW9uIGluIGxpbmU6ICIgKyBsaW5lKTsKKwl9CisKKwlCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworCVdyaXRlciBvcyA9IG5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIoYm9zLCAidXMtYXNjaWkiKTsKKwlmb3IgKDs7KSB7CisJICAgIGxpbmUgPSBpbi5yZWFkTGluZSgpOworCSAgICBpZiAobGluZS5lcXVhbHMoIkVYUEVDVCIpKQorCQlicmVhazsKKwkgICAgb3Mud3JpdGUobGluZSk7CisJICAgIG9zLndyaXRlKCJcbiIpOworCX0KKwlvcy5jbG9zZSgpOworCXQuaW5wdXQgPSBib3MudG9CeXRlQXJyYXkoKTsKKworCWJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKwlvcyA9IG5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIoYm9zLCAidXMtYXNjaWkiKTsKKwlmb3IgKDs7KSB7CisJICAgIGxpbmUgPSBpbi5yZWFkTGluZSgpOworCSAgICBpZiAobGluZS5zdGFydHNXaXRoKCJFWENFUFRJT04iKSkgeworCQlpID0gbGluZS5pbmRleE9mKCcgJyk7CS8vIFhYWCAtIGNydWRlCisJCXQuZXhwZWN0ZWRFeGNlcHRpb24gPSBsaW5lLnN1YnN0cmluZyhpICsgMSk7CisJICAgIH0gZWxzZSBpZiAobGluZS5lcXVhbHMoIkVORCIpKQorCQlicmVhazsKKwkgICAgb3Mud3JpdGUobGluZSk7CisJICAgIG9zLndyaXRlKCJcbiIpOworCX0KKwlvcy5jbG9zZSgpOworCWlmICh0LmV4cGVjdGVkRXhjZXB0aW9uID09IG51bGwpCisJICAgIHQuZXhwZWN0ZWRPdXRwdXQgPSBib3MudG9CeXRlQXJyYXkoKTsKKworCXJldHVybiB0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgdGhlIGRhdGEgaW4gdGhlIHRlc3QgY2FzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgdGVzdChUZXN0RGF0YSB0KSB7CisJSW5wdXRTdHJlYW0gaW4gPQorCSAgICBuZXcgVVVEZWNvZGVyU3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSh0LmlucHV0KSwKKwkJCQl0Lmlnbm9yZUVycm9ycywgdC5pZ25vcmVNaXNzaW5nQmVnaW5FbmQpOworCisJLy8gdHdvIGNhc2VzIC0gZWl0aGVyIHdlJ3JlIGV4cGVjdGluZyBhbiBleGNlcHRpb24gb3Igd2UncmUgbm90CisJaWYgKHQuZXhwZWN0ZWRFeGNlcHRpb24gIT0gbnVsbCkgeworCSAgICB0cnkgeworCQlpbnQgYzsKKwkJd2hpbGUgKChjID0gaW4ucmVhZCgpKSA+PSAwKQorCQkgICAgOwkvLyB0aHJvdyBpdCBhd2F5CisJCS8vIHJlYWQgYWxsIHRoZSBkYXRhIHdpdGggbm8gZXhjZXB0aW9uIC0gZmFpbAorCQlpZiAoanVuaXQpCisJCSAgICBBc3NlcnQuZmFpbCgiRGlkbid0IGdldCBleHBlY3RlZCBleGNlcHRpb246ICIgKworCQkJCSAgICB0LmV4cGVjdGVkRXhjZXB0aW9uKTsKKwkJU3lzdGVtLm91dC5wcmludGxuKCJUZXN0OiAiICsgdC5uYW1lKTsKKwkJU3lzdGVtLm91dC5wcmludGxuKCJHb3Qgbm8gRXhjZXB0aW9uIik7CisJCVN5c3RlbS5vdXQucHJpbnRsbigiRXhwZWN0ZWQgRXhjZXB0aW9uOiAiICsKKwkJCQkgICAgdC5leHBlY3RlZEV4Y2VwdGlvbik7CisJCWVycm9ycysrOworCSAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKwkJaWYgKGp1bml0KQorCQkgICAgQXNzZXJ0LmFzc2VydEVxdWFscygiRm9yIGV4cGVjdGVkIGV4Y2VwdGlvbiIsCisJCQlleC5nZXRDbGFzcygpLmdldE5hbWUoKSwgdC5leHBlY3RlZEV4Y2VwdGlvbik7CisJCWlmICghZXguZ2V0Q2xhc3MoKS5nZXROYW1lKCkuZXF1YWxzKHQuZXhwZWN0ZWRFeGNlcHRpb24pKSB7CisJCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlRlc3Q6ICIgKyB0Lm5hbWUpOworCQkgICAgU3lzdGVtLm91dC5wcmludGxuKCJHb3QgRXhjZXB0aW9uOiAiICsgZXgpOworCQkgICAgU3lzdGVtLm91dC5wcmludGxuKCJFeHBlY3RlZCBFeGNlcHRpb246ICIgKworCQkJCQl0LmV4cGVjdGVkRXhjZXB0aW9uKTsKKwkJICAgIGVycm9ycysrOworCQl9CisJICAgIH0gZmluYWxseSB7CisJCXRyeSB7CisJCSAgICBpbi5jbG9zZSgpOworCQl9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2V4KSB7IH0KKwkgICAgfQorCX0gZWxzZSB7CisJICAgIElucHV0U3RyZWFtIGVpbiA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSh0LmV4cGVjdGVkT3V0cHV0KTsKKwkgICAgdHJ5IHsKKwkJaW50IGMsIGVjOworCQlib29sZWFuIGdvdEVycm9yID0gZmFsc2U7CisJCXdoaWxlICgoYyA9IGluLnJlYWQoKSkgPj0gMCkgeworCQkgICAgZWMgPSBlaW4ucmVhZCgpOworCQkgICAgaWYgKGp1bml0KQorCQkJQXNzZXJ0LmFzc2VydEZhbHNlKCJGb3IgZXhwZWN0ZWQgRU9GLCBnb3QgY2hhciAiICsgYywKKwkJCQkJICAgIGVjIDwgMCk7CisJCSAgICBpZiAoZWMgPCAwKSB7CisJCQlTeXN0ZW0ub3V0LnByaW50bG4oIlRlc3Q6ICIgKyB0Lm5hbWUpOworCQkJU3lzdGVtLm91dC5wcmludGxuKCJHb3QgY2hhcjogIiArIGMpOworCQkJU3lzdGVtLm91dC5wcmludGxuKCJFeHBlY3RlZCBFT0YiKTsKKwkJCWVycm9ycysrOworCQkJZ290RXJyb3IgPSB0cnVlOworCQkJYnJlYWs7CisJCSAgICB9CisJCSAgICBpZiAoanVuaXQpCisJCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJGb3IgZXhwZWN0ZWQgY2hhciAiICsgZWMgKworCQkJCQkgICAgIiwgZ290IGNoYXIgIiArIGMsIGVjLCBjKTsKKwkJICAgIGlmIChjICE9IGVjKSB7CisJCQlTeXN0ZW0ub3V0LnByaW50bG4oIlRlc3Q6ICIgKyB0Lm5hbWUpOworCQkJU3lzdGVtLm91dC5wcmludGxuKCJHb3QgY2hhcjogIiArIGMpOworCQkJU3lzdGVtLm91dC5wcmludGxuKCJFeHBlY3RlZCBjaGFyOiAiICsgZWMpOworCQkJZXJyb3JzKys7CisJCQlnb3RFcnJvciA9IHRydWU7CisJCQlicmVhazsKKwkJICAgIH0KKwkJfQorCQlpZiAoIWdvdEVycm9yKSB7CisJCSAgICBlYyA9IGVpbi5yZWFkKCk7CisJCSAgICBpZiAoanVuaXQpCisJCQlBc3NlcnQuYXNzZXJ0RmFsc2UoIkZvciBleHBlY3RlZCBjaGFyICIgKyBlYyArCisJCQkJCSAgICAiLCBnb3QgRU9GIiwgZWMgPj0gMCk7CisJCSAgICBpZiAoZWMgPj0gMCkgeworCQkJU3lzdGVtLm91dC5wcmludGxuKCJUZXN0OiAiICsgdC5uYW1lKTsKKwkJCVN5c3RlbS5vdXQucHJpbnRsbigiR290IEVPRiIpOworCQkJU3lzdGVtLm91dC5wcmludGxuKCJFeHBlY3RlZCBjaGFyOiAiICsgZWMpOworCQkJZXJyb3JzKys7CisJCSAgICB9CisJCX0KKwkgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJCWlmIChqdW5pdCkKKwkJICAgIEFzc2VydC5mYWlsKCJHb3QgZXhjZXB0aW9uOiAiICsgZXgpOworCQlTeXN0ZW0ub3V0LnByaW50bG4oIlRlc3Q6ICIgKyB0Lm5hbWUpOworCQlTeXN0ZW0ub3V0LnByaW50bG4oIkdvdCBFeGNlcHRpb246ICIgKyBleCk7CisJCVN5c3RlbS5vdXQucHJpbnRsbigiRXhwZWN0ZWQgbm8gRXhjZXB0aW9uIik7CisJCWVycm9ycysrOworCSAgICB9IGZpbmFsbHkgeworCQl0cnkgeworCQkgICAgaW4uY2xvc2UoKTsKKwkJfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9leCkgeyB9CisJCXRyeSB7CisJCSAgICBlaW4uY2xvc2UoKTsKKwkJfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9leCkgeyB9CisJICAgIH0KKwl9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL1dyaXRlVGltZW91dFNvY2tldFRlc3QuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvdXRpbC9Xcml0ZVRpbWVvdXRTb2NrZXRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjY4OGY1MAotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvdXRpbC9Xcml0ZVRpbWVvdXRTb2NrZXRUZXN0LmphdmEKQEAgLTAsMCArMSwyNTggQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDksIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLnV0aWw7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC4qOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLkludGVycnVwdGVkSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworCitpbXBvcnQgamF2YXgubWFpbC4qOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuTWltZU1lc3NhZ2U7CitpbXBvcnQgamF2YXgubWFpbC51dGlsLkJ5dGVBcnJheURhdGFTb3VyY2U7CitpbXBvcnQgamF2YXguYWN0aXZhdGlvbi5EYXRhSGFuZGxlcjsKK2ltcG9ydCBqYXZheC5uZXQuc3NsLio7CisKK2ltcG9ydCBjb20uc3VuLm1haWwuaW1hcC5JTUFQSGFuZGxlcjsKK2ltcG9ydCBjb20uc3VuLm1haWwudGVzdC5UZXN0U2VydmVyOworaW1wb3J0IGNvbS5zdW4ubWFpbC50ZXN0LlRlc3RTb2NrZXRGYWN0b3J5OworaW1wb3J0IGNvbS5zdW4ubWFpbC50ZXN0LlRlc3RTU0xTb2NrZXRGYWN0b3J5OworCitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LlJ1bGU7CitpbXBvcnQgb3JnLmp1bml0LnJ1bGVzLlRpbWVvdXQ7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuZmFpbDsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUcnVlOworCisvKioKKyAqIFRlc3QgdGhhdCB3cml0ZSB0aW1lb3V0cyB3b3JrLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgV3JpdGVUaW1lb3V0U29ja2V0VGVzdCB7CisKKyAgICAvLyB0aW1lb3V0IHRoZSB0ZXN0IGluIGNhc2Ugb2YgZGVhZGxvY2sKKyAgICBAUnVsZQorICAgIHB1YmxpYyBUaW1lb3V0IGRlYWRsb2NrVGltZW91dCA9IFRpbWVvdXQuc2Vjb25kcygyMCk7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVElNRU9VVCA9IDIwMDsJLy8gbXMKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgZGF0YSA9CisJImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU2Nzg5IjsKKworICAgIC8qKgorICAgICAqIFRlc3Qgd3JpdGUgdGltZW91dHMgd2l0aCBwbGFpbiBzb2NrZXRzLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdCgpIHsKKwlmaW5hbCBQcm9wZXJ0aWVzIHByb3BlcnRpZXMgPSBuZXcgUHJvcGVydGllcygpOworCXByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuaW1hcC5ob3N0IiwgImxvY2FsaG9zdCIpOworCXByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuaW1hcC53cml0ZXRpbWVvdXQiLCAiIiArIFRJTUVPVVQpOworCXRlc3QocHJvcGVydGllcywgZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3Qgd3JpdGUgdGltZW91dHMgd2l0aCBjdXN0b20gc29ja2V0IGZhY3RvcnkuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U29ja2V0RmFjdG9yeSgpIHsKKwlmaW5hbCBQcm9wZXJ0aWVzIHByb3BlcnRpZXMgPSBuZXcgUHJvcGVydGllcygpOworCXByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuaW1hcC5ob3N0IiwgImxvY2FsaG9zdCIpOworCXByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuaW1hcC53cml0ZXRpbWVvdXQiLCAiIiArIFRJTUVPVVQpOworCVRlc3RTb2NrZXRGYWN0b3J5IHNmID0gbmV3IFRlc3RTb2NrZXRGYWN0b3J5KCk7CisJcHJvcGVydGllcy5wdXQoIm1haWwuaW1hcC5zb2NrZXRGYWN0b3J5Iiwgc2YpOworCXByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuaW1hcC5zb2NrZXRGYWN0b3J5LmZhbGxiYWNrIiwgImZhbHNlIik7CisJdGVzdChwcm9wZXJ0aWVzLCBmYWxzZSk7CisJLy8gbWFrZSBzdXJlIG91ciBzb2NrZXQgZmFjdG9yeSB3YXMgYWN0dWFsbHkgdXNlZAorCWFzc2VydFRydWUoc2YuZ2V0U29ja2V0Q3JlYXRlZCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHdyaXRlIHRpbWVvdXRzIHdpdGggU1NMIHNvY2tldHMuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U1NMKCkgeworCWZpbmFsIFByb3BlcnRpZXMgcHJvcGVydGllcyA9IG5ldyBQcm9wZXJ0aWVzKCk7CisJcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5pbWFwLmhvc3QiLCAibG9jYWxob3N0Iik7CisJcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5pbWFwLndyaXRldGltZW91dCIsICIiICsgVElNRU9VVCk7CisJcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5pbWFwLnNzbC5lbmFibGUiLCAidHJ1ZSIpOworCS8vIGVuYWJsZSBvbmx5IHRoZSBhbm9ueW1vdXMgY2lwaGVyIHN1aXRlcyBzaW5jZSB0aGVyZSdzIG5vCisJLy8gc2VydmVyIGNlcnRpZmljYXRlCisJcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5pbWFwLnNzbC5jaXBoZXJzdWl0ZXMiLAorCQkJCQkJICAgIGdldEFub25DaXBoZXJTdWl0ZXMoKSk7CisJdGVzdChwcm9wZXJ0aWVzLCB0cnVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHdyaXRlIHRpbWVvdXRzIHdpdGggYSBjdXN0b20gU1NMIHNvY2tldCBmYWN0b3J5LgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFNTTFNvY2tldEZhY3RvcnkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlmaW5hbCBQcm9wZXJ0aWVzIHByb3BlcnRpZXMgPSBuZXcgUHJvcGVydGllcygpOworCXByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuaW1hcC5ob3N0IiwgImxvY2FsaG9zdCIpOworCXByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuaW1hcC53cml0ZXRpbWVvdXQiLCAiIiArIFRJTUVPVVQpOworCXByb3BlcnRpZXMuc2V0UHJvcGVydHkoIm1haWwuaW1hcC5zc2wuZW5hYmxlIiwgInRydWUiKTsKKwlUZXN0U1NMU29ja2V0RmFjdG9yeSBzZiA9IG5ldyBUZXN0U1NMU29ja2V0RmFjdG9yeSgpOworCXNmLnNldERlZmF1bHRDaXBoZXJTdWl0ZXMoZ2V0QW5vbkNpcGhlclN1aXRlc0FycmF5KCkpOworCXByb3BlcnRpZXMucHV0KCJtYWlsLmltYXAuc3NsLnNvY2tldEZhY3RvcnkiLCBzZik7CisJLy8gZG9uJ3QgZmFsbCBiYWNrIHRvIG5vbi1TU0wKKwlwcm9wZXJ0aWVzLnNldFByb3BlcnR5KCJtYWlsLmltYXAuc29ja2V0RmFjdG9yeS5mYWxsYmFjayIsICJmYWxzZSIpOworCS8vIGVuYWJsZSBvbmx5IHRoZSBhbm9ueW1vdXMgY2lwaGVyIHN1aXRlcyBzaW5jZSB0aGVyZSdzIG5vCisJLy8gc2VydmVyIGNlcnRpZmljYXRlCisJcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5pbWFwLnNzbC5jaXBoZXJzdWl0ZXMiLAorCQkJCQkJICAgIGdldEFub25DaXBoZXJTdWl0ZXMoKSk7CisJdGVzdChwcm9wZXJ0aWVzLCB0cnVlKTsKKwkvLyBtYWtlIHN1cmUgb3VyIHNvY2tldCBmYWN0b3J5IHdhcyBhY3R1YWxseSB1c2VkCisJYXNzZXJ0VHJ1ZShzZi5nZXRTb2NrZXRXcmFwcGVkKCkgfHwgc2YuZ2V0U29ja2V0Q3JlYXRlZCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHRoYXQgV3JpdGVUaW1lb3V0U29ja2V0IG92ZXJyaWRlcyBhbGwgbWV0aG9kcyBmcm9tIFNvY2tldC4KKyAgICAgKiBYWFggLSB0aGlzIGlzIGtpbmQgb2YgaGFja3kgc2luY2UgaXQgZGVwZW5kcyBvbiBNZXRob2QudG9TdHJpbmcKKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RPdmVycmlkZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlTZXQ8U3RyaW5nPiBzb2NrZXRNZXRob2RzID0gbmV3IEhhc2hTZXQ8PigpOworCU1ldGhvZFtdIG0gPSBqYXZhLm5ldC5Tb2NrZXQuY2xhc3MuZ2V0RGVjbGFyZWRNZXRob2RzKCk7CisJU3RyaW5nIGNsYXNzTmFtZSA9IGphdmEubmV0LlNvY2tldC5jbGFzcy5nZXROYW1lKCkgKyAiLiI7CisJZm9yIChpbnQgaSA9IDA7IGkgPCBtLmxlbmd0aDsgaSsrKSB7CisJICAgIGlmIChNb2RpZmllci5pc1B1YmxpYyhtW2ldLmdldE1vZGlmaWVycygpKSAmJgorCQkhTW9kaWZpZXIuaXNTdGF0aWMobVtpXS5nZXRNb2RpZmllcnMoKSkpIHsKKwkJU3RyaW5nIG5hbWUgPSBtW2ldLnRvU3RyaW5nKCkuCisJCQkJICAgIHJlcGxhY2UoInN5bmNocm9uaXplZCAiLCAiIikuCisJCQkJICAgIHJlcGxhY2UoY2xhc3NOYW1lLCAiIik7CisJCXNvY2tldE1ldGhvZHMuYWRkKG5hbWUpOworCSAgICB9CisJfQorCVNldDxTdHJpbmc+IHd0c29ja2V0TWV0aG9kcyA9IG5ldyBIYXNoU2V0PD4oKTsKKwltID0gV3JpdGVUaW1lb3V0U29ja2V0LmNsYXNzLmdldERlY2xhcmVkTWV0aG9kcygpOworCWNsYXNzTmFtZSA9IFdyaXRlVGltZW91dFNvY2tldC5jbGFzcy5nZXROYW1lKCkgKyAiLiI7CisJZm9yIChpbnQgaSA9IDA7IGkgPCBtLmxlbmd0aDsgaSsrKSB7CisJICAgIGlmIChNb2RpZmllci5pc1B1YmxpYyhtW2ldLmdldE1vZGlmaWVycygpKSkgeworCQlTdHJpbmcgbmFtZSA9IG1baV0udG9TdHJpbmcoKS4KKwkJCQkgICAgcmVwbGFjZSgic3luY2hyb25pemVkICIsICIiKS4KKwkJCQkgICAgcmVwbGFjZShjbGFzc05hbWUsICIiKTsKKwkJc29ja2V0TWV0aG9kcy5yZW1vdmUobmFtZSk7CisJICAgIH0KKwl9CisJZm9yIChTdHJpbmcgcyA6IHNvY2tldE1ldGhvZHMpCisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiV3JpdGVUaW1lb3V0U29ja2V0IGRpZCBub3Qgb3ZlcnJpZGU6ICIgKyBzKTsKKwlhc3NlcnRUcnVlKHNvY2tldE1ldGhvZHMuaXNFbXB0eSgpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmdbXSBnZXRBbm9uQ2lwaGVyU3VpdGVzQXJyYXkoKSB7CisJU1NMU29ja2V0RmFjdG9yeSBzZiA9IChTU0xTb2NrZXRGYWN0b3J5KVNTTFNvY2tldEZhY3RvcnkuZ2V0RGVmYXVsdCgpOworCUxpc3Q8U3RyaW5nPiBhbm9uID0gbmV3IEFycmF5TGlzdDw+KCk7CisJU3RyaW5nW10gc3VpdGVzID0gc2YuZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVzKCk7CisJZm9yIChpbnQgaSA9IDA7IGkgPCBzdWl0ZXMubGVuZ3RoOyBpKyspIHsKKwkgICAgaWYgKHN1aXRlc1tpXS5pbmRleE9mKCJfYW5vbl8iKSA+PSAwKSB7CisJCWFub24uYWRkKHN1aXRlc1tpXSk7CisJICAgIH0KKwl9CisJcmV0dXJuIGFub24udG9BcnJheShuZXcgU3RyaW5nW2Fub24uc2l6ZSgpXSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGdldEFub25DaXBoZXJTdWl0ZXMoKSB7CisJU1NMU29ja2V0RmFjdG9yeSBzZiA9IChTU0xTb2NrZXRGYWN0b3J5KVNTTFNvY2tldEZhY3RvcnkuZ2V0RGVmYXVsdCgpOworCVN0cmluZ0J1aWxkZXIgYW5vbiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisJU3RyaW5nW10gc3VpdGVzID0gc2YuZ2V0U3VwcG9ydGVkQ2lwaGVyU3VpdGVzKCk7CisJZm9yIChpbnQgaSA9IDA7IGkgPCBzdWl0ZXMubGVuZ3RoOyBpKyspIHsKKwkgICAgaWYgKHN1aXRlc1tpXS5pbmRleE9mKCJfYW5vbl8iKSA+PSAwKSB7CisJCWlmIChhbm9uLmxlbmd0aCgpID4gMCkKKwkJICAgIGFub24uYXBwZW5kKCIgIik7CisJCWFub24uYXBwZW5kKHN1aXRlc1tpXSk7CisJICAgIH0KKwl9CisJcmV0dXJuIGFub24udG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdChQcm9wZXJ0aWVzIHByb3BlcnRpZXMsIGJvb2xlYW4gaXNTU0wpIHsKKyAgICAgICAgVGVzdFNlcnZlciBzZXJ2ZXIgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmluYWwgVGltZW91dEhhbmRsZXIgaGFuZGxlciA9IG5ldyBUaW1lb3V0SGFuZGxlcigpOworICAgICAgICAgICAgc2VydmVyID0gbmV3IFRlc3RTZXJ2ZXIoaGFuZGxlciwgaXNTU0wpOworICAgICAgICAgICAgc2VydmVyLnN0YXJ0KCk7CisKKwkgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eSgibWFpbC5pbWFwLnBvcnQiLCAiIiArIHNlcnZlci5nZXRQb3J0KCkpOworICAgICAgICAgICAgZmluYWwgU2Vzc2lvbiBzZXNzaW9uID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShwcm9wZXJ0aWVzKTsKKyAgICAgICAgICAgIC8vc2Vzc2lvbi5zZXREZWJ1Zyh0cnVlKTsKKworCSAgICBNaW1lTWVzc2FnZSBtc2cgPSBuZXcgTWltZU1lc3NhZ2Uoc2Vzc2lvbik7CisJICAgIG1zZy5zZXRGcm9tKCJ0ZXN0QGV4YW1wbGUuY29tIik7CisJICAgIG1zZy5zZXRTdWJqZWN0KCJ0ZXN0Iik7CisJICAgIGZpbmFsIGludCBzaXplID0gODE5MjAwMDsJLy8gZW5vdWdoIGRhdGEgdG8gZmlsbCBuZXR3b3JrIGJ1ZmZlcnMKKwkgICAgYnl0ZVtdIHBhcnQgPSBuZXcgYnl0ZVtzaXplXTsKKwkgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKKwkJaW50IGogPSBpICUgNjQ7CisJCWlmIChqID09IDYyKQorCQkgICAgcGFydFtpXSA9IChieXRlKSdccic7CisJCWVsc2UgaWYgKGogPT0gNjMpCisJCSAgICBwYXJ0W2ldID0gKGJ5dGUpJ1xuJzsKKwkJZWxzZQorCQkgICAgcGFydFtpXSA9IChieXRlKWRhdGEuY2hhckF0KChqICsgaSAvIDY0KSAlIDYyKTsKKwkgICAgfQorCSAgICBtc2cuc2V0RGF0YUhhbmRsZXIobmV3IERhdGFIYW5kbGVyKAorCQluZXcgQnl0ZUFycmF5RGF0YVNvdXJjZShwYXJ0LCAidGV4dC9wbGFpbiIpKSk7CisJICAgIG1zZy5zYXZlQ2hhbmdlcygpOworCisgICAgICAgICAgICBmaW5hbCBTdG9yZSBzdG9yZSA9IHNlc3Npb24uZ2V0U3RvcmUoImltYXAiKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgc3RvcmUuY29ubmVjdCgidGVzdCIsICJ0ZXN0Iik7CisJCWZpbmFsIEZvbGRlciBmID0gc3RvcmUuZ2V0Rm9sZGVyKCJ0ZXN0Iik7CisJCWYuYXBwZW5kTWVzc2FnZXMobmV3IE1lc3NhZ2VbXSB7IG1zZyB9KTsKKwkJZmFpbCgiTm8gdGltZW91dCIpOworCSAgICB9IGNhdGNoIChTdG9yZUNsb3NlZEV4Y2VwdGlvbiBzY2V4KSB7CisJCS8vIHN1Y2Nlc3MhCisJICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCQlTeXN0ZW0ub3V0LnByaW50bG4oZXgpOworCQkvL2V4LnByaW50U3RhY2tUcmFjZSgpOworCQlmYWlsKGV4LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBzdG9yZS5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChmaW5hbCBFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy9lLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgZmFpbChlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoc2VydmVyICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBzZXJ2ZXIucXVpdCgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3VzdG9tIGhhbmRsZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgVGltZW91dEhhbmRsZXIgZXh0ZW5kcyBJTUFQSGFuZGxlciB7CisJQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGNvbGxlY3RNZXNzYWdlKGludCBieXRlcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwkgICAgdHJ5IHsKKwkJLy8gYWxsb3cgcGxlbnR5IG9mIHRpbWUgZm9yIGV2ZW4gc2xvdyBtYWNoaW5lcyB0byB0aW1lIG91dAorCQlUaHJlYWQuc2xlZXAoVElNRU9VVCoyMCk7CisJICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGV4KSB7IH0KKwkgICAgc3VwZXIuY29sbGVjdE1lc3NhZ2UoYnl0ZXMpOworICAgICAgICB9CisKKwlAT3ZlcnJpZGUKKwlwdWJsaWMgdm9pZCBsaXN0KFN0cmluZyBsaW5lKSB0aHJvd3MgSU9FeGNlcHRpb24geworCSAgICB1bnRhZ2dlZCgiTElTVCAoKSBcIi9cIiB0ZXN0Iik7CisJICAgIG9rKCk7CisJfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvdXRpbC9sb2dnaW5nL0Fic3RyYWN0TG9nZ2luZy5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL2xvZ2dpbmcvQWJzdHJhY3RMb2dnaW5nLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGVmNGQ5NQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvdXRpbC9sb2dnaW5nL0Fic3RyYWN0TG9nZ2luZy5qYXZhCkBAIC0wLDAgKzEsMzkzIEBACisvKg0KKyAqIENvcHlyaWdodCAoYykgMjAxNiwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KKyAqIENvcHlyaWdodCAoYykgMjAxNiwgMjAxOCBKYXNvbiBNZWhyZW5zLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KKyAqDQorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlDQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQNCisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuDQorICoNCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5DQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQ0KKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLA0KKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0DQorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLg0KKyAqDQorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wDQorICovDQorcGFja2FnZSBjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nOw0KKw0KK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOw0KK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsNCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsNCitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uQW5ub3RhdGlvbjsNCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQWNjZXNzaWJsZU9iamVjdDsNCitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7DQoraW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkZpZWxkOw0KK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7DQoraW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lk1vZGlmaWVyOw0KK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0Ow0KK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOw0KK2ltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsNCitpbXBvcnQgamF2YS51dGlsLkxpc3Q7DQoraW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOw0KK2ltcG9ydCBqYXZhLnV0aWwubG9nZ2luZy5MZXZlbDsNCitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTG9nTWFuYWdlcjsNCitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTG9nUmVjb3JkOw0KK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRFcXVhbHM7DQoraW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEZhbHNlOw0KK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUcnVlOw0KK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5mYWlsOw0KKw0KKy8qKg0KKyAqIENvbW1vbiBzdXBlciBjbGFzcyBmb3IgdGhlIGxvZ2dpbmcgdGVzdCBzdWl0ZS4NCisgKg0KKyAqIEBhdXRob3IgSmFzb24gTWVocmVucw0KKyAqIEBzaW5jZSBKYXZhTWFpbCAxLjUuNg0KKyAqLw0KK2Fic3RyYWN0IGNsYXNzIEFic3RyYWN0TG9nZ2luZyB7DQorDQorICAgIC8qKg0KKyAgICAgKiBVc2VkIHRvIHByaW50IGRlYnVnIGluZm9ybWF0aW9uIGFib3V0IHRoZSBnaXZlbiB0aHJvd2FibGUuDQorICAgICAqDQorICAgICAqIEBwYXJhbSB0IHRoZSB0aHJvd2FibGUuDQorICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgZ2l2ZW4gdGhyb3dhYmxlIGlzIG51bGwuDQorICAgICAqLw0KKyAgICBAU3VwcHJlc3NXYXJuaW5ncyh7IkNhbGxUb1RocmVhZER1bXBTdGFjayIsICJDYWxsVG9QcmludFN0YWNrVHJhY2UifSkNCisgICAgc3RhdGljIHZvaWQgZHVtcChmaW5hbCBUaHJvd2FibGUgdCkgew0KKyAgICAgICAgdC5wcmludFN0YWNrVHJhY2UoKTsNCisgICAgfQ0KKw0KKyAgICAvKioNCisgICAgICogR2V0cyBhbGwgb2YgdGhlIHByZWRlZmluZWQgTGV2ZWxzLg0KKyAgICAgKg0KKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IG9mIGxvZyBsZXZlbHMuDQorICAgICAqLw0KKyAgICBzdGF0aWMgTGV2ZWxbXSBnZXRBbGxMZXZlbHMoKSB7DQorICAgICAgICBmaW5hbCBGaWVsZFtdIGZpZWxkcyA9IExldmVsLmNsYXNzLmdldEZpZWxkcygpOw0KKyAgICAgICAgTGlzdDxMZXZlbD4gYSA9IG5ldyBBcnJheUxpc3Q8PihmaWVsZHMubGVuZ3RoKTsNCisgICAgICAgIGZvciAoRmllbGQgZmllbGQgOiBmaWVsZHMpIHsNCisgICAgICAgICAgICBpZiAoTW9kaWZpZXIuaXNTdGF0aWMoZmllbGQuZ2V0TW9kaWZpZXJzKCkpDQorICAgICAgICAgICAgICAgICAgICAmJiBMZXZlbC5jbGFzcy5pc0Fzc2lnbmFibGVGcm9tKGZpZWxkLmdldFR5cGUoKSkpIHsNCisgICAgICAgICAgICAgICAgdHJ5IHsNCisgICAgICAgICAgICAgICAgICAgIGEuYWRkKChMZXZlbCkgZmllbGQuZ2V0KChPYmplY3QpIG51bGwpKTsNCisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHwgSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBleCkgew0KKyAgICAgICAgICAgICAgICAgICAgZmFpbChleC50b1N0cmluZygpKTsNCisgICAgICAgICAgICAgICAgfQ0KKyAgICAgICAgICAgIH0NCisgICAgICAgIH0NCisgICAgICAgIHJldHVybiBhLnRvQXJyYXkobmV3IExldmVsW2Euc2l6ZSgpXSk7DQorICAgIH0NCisNCisgICAgLyoqDQorICAgICAqIERldGVybWluZXMgaWYgdGhlIGdpdmVuIGNsYXNzIGlzIGZyb20gdGhlIEphdmFNYWlsIEFQSSBSZWZlcmVuY2UNCisgICAgICogSW1wbGVtZW50YXRpb24ge0Bjb2RlIGNvbS5zdW4ubWFpbH0gcGFja2FnZS4NCisgICAgICoNCisgICAgICogQHBhcmFtIGsgdGhlIHR5cGUgdG8gdGVzdC4NCisgICAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgaXMgcGFydCBvZiByZWZlcmVuY2UgaW1wbGVtZW50YXRpb24gYnV0IG5vdCBwYXJ0IG9mDQorICAgICAqIHRoZSBvZmZpY2lhbCBBUEkgc3BlYy4NCisgICAgICogQHRocm93cyBFeGNlcHRpb24gaWYgdGhlcmUgaXMgYSBwcm9ibGVtLg0KKyAgICAgKi8NCisgICAgZmluYWwgYm9vbGVhbiBpc1ByaXZhdGVTcGVjKGZpbmFsIENsYXNzPD8+IGspIHRocm93cyBFeGNlcHRpb24gew0KKyAgICAgICAgcmV0dXJuIGlzRnJvbUphdmFNYWlsKGssIGZhbHNlKTsNCisgICAgfQ0KKw0KKyAgICAvKioNCisgICAgICogUmVpbml0aWFsaXplIHRoZSBsb2dnaW5nIHByb3BlcnRpZXMgdXNpbmcgdGhlIGdpdmVuIHByb3BlcnRpZXMuDQorICAgICAqDQorICAgICAqIEBwYXJhbSBtYW5hZ2VyIHRoZSBsb2cgbWFuYWdlci4NCisgICAgICogQHBhcmFtIHByb3BzIHRoZSBwcm9wZXJ0aWVzLg0KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHRoZXJlIGlzIGEgcHJvYmxlbS4NCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiBlaXRoZXIgYXJndW1lbnQgaXMgbnVsbC4NCisgICAgICovDQorICAgIGZpbmFsIHZvaWQgcmVhZChMb2dNYW5hZ2VyIG1hbmFnZXIsIFByb3BlcnRpZXMgcHJvcHMpIHRocm93cyBJT0V4Y2VwdGlvbiB7DQorICAgICAgICAvL0pESy00ODEwNjM3DQorICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSg1MTIpOw0KKyAgICAgICAgcHJvcHMuc3RvcmUob3V0LCBnZXRDbGFzcygpLmdldE5hbWUoKSk7DQorICAgICAgICBtYW5hZ2VyLnJlYWRDb25maWd1cmF0aW9uKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShvdXQudG9CeXRlQXJyYXkoKSkpOw0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBTZXRzIHRoZSBsb2cgcmVjb3JkIHRpbWUgdXNpbmcgbWlsbGlzZWNvbmRzIGZyb20gdGhlIGVwb2NoIG9mDQorICAgICAqIDE5NzAtMDEtMDFUMDA6MDA6MDBaLiBBbnkgbmFub3NlY29uZCBpbmZvcm1hdGlvbiBpcyBzZXQgdG8gemVyby4gVGhpcw0KKyAgICAgKiBtZXRob2QgaXMgdXNlZCB0byBzdXBwb3J0IEpESzggd2hlbiBydW5uaW5nIG9uIEpESzkgb3IgbmV3ZXIuDQorICAgICAqDQorICAgICAqIEBwYXJhbSByZWNvcmQgdGhlIGxvZyByZWNvcmQgdG8gYWRqdXN0Lg0KKyAgICAgKiBAcGFyYW0gZXBvY2hNaWxsaSB0aGUgdGltZSBpbiBtaWxsaXNlY29uZHMgZnJvbSBlcG9jaC4NCisgICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgZ2l2ZW4gcmVjb3JkIGlzIG51bGwuDQorICAgICAqLw0KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKSAvL1NlZSBKREstODE0NDI2MiBhbmQgSzcwOTEuDQorICAgIHN0YXRpYyB2b2lkIHNldEVwb2NoTWlsbGkoZmluYWwgTG9nUmVjb3JkIHJlY29yZCwgZmluYWwgbG9uZyBlcG9jaE1pbGxpKSB7DQorICAgICAgICByZWNvcmQuc2V0TWlsbGlzKGVwb2NoTWlsbGkpOw0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBTZXRzIHRoZSBsb2cgcmVjb3JkIHRpbWUgdXNpbmcgdGhlIHNlY29uZHMgYW5kIG5hbm9zZWNvbmRzIG9mIHRoZSBlcG9jaA0KKyAgICAgKiBmcm9tIDE5NzAtMDEtMDFUMDA6MDA6MDBaLg0KKyAgICAgKg0KKyAgICAgKiBAcGFyYW0gcmVjb3JkIHRoZSBsb2cgcmVjb3JkLg0KKyAgICAgKiBAcGFyYW0gZXBvY2hTZWNvbmQgdGhlIHNlY29uZHMuDQorICAgICAqIEBwYXJhbSBuYW5vQWRqdXN0bWVudCB0aGUgbmFubyBzZWNvbmRzLg0KKyAgICAgKiBAdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24gaWYgcnVubmluZyBvbiBwcmUgSkRLIDguDQorICAgICAqIEB0aHJvd3MgTm9TdWNoTWV0aG9kRXhjZXB0aW9uIGlmIHJ1bm5pbmcgb24gSkRLIDguDQorICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uIGlmIHRoZXJlIGlzIGEgcHJvYmxlbS4NCisgICAgICovDQorICAgIHN0YXRpYyB2b2lkIHNldEVwb2NoU2Vjb25kKGZpbmFsIExvZ1JlY29yZCByZWNvcmQsIGZpbmFsIGxvbmcgZXBvY2hTZWNvbmQsDQorICAgICAgICAgICAgZmluYWwgbG9uZyBuYW5vQWRqdXN0bWVudCkgdGhyb3dzIEV4Y2VwdGlvbiB7DQorICAgICAgICBmaW5hbCBDbGFzczw/PiBrID0gQ2xhc3MuZm9yTmFtZSgiamF2YS50aW1lLkluc3RhbnQiKTsNCisgICAgICAgIE1ldGhvZCBpbnN0YW50ID0gay5nZXRNZXRob2QoIm9mRXBvY2hTZWNvbmQiLCBsb25nLmNsYXNzLCBsb25nLmNsYXNzKTsNCisgICAgICAgIE1ldGhvZCBzZXQgPSBMb2dSZWNvcmQuY2xhc3MuZ2V0TWV0aG9kKCJzZXRJbnN0YW50Iiwgayk7DQorICAgICAgICBzZXQuaW52b2tlKHJlY29yZCwgaW5zdGFudC5pbnZva2UobnVsbCwgZXBvY2hTZWNvbmQsIG5hbm9BZGp1c3RtZW50KSk7DQorICAgIH0NCisNCisgICAgLyoqDQorICAgICAqIERldGVybWluZXMgaWYgdGhlIHtAY29kZSBqYXZhLnRpbWV9IEFQSXMgYXJlIGF2YWlsYWJsZSBmb3IgdGhpcyBKVk0uDQorICAgICAqDQorICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgdGltZSBjbGFzc2VzIGNhbiBiZSBsb2FkZWQuDQorICAgICAqLw0KKyAgICBzdGF0aWMgYm9vbGVhbiBoYXNKYXZhVGltZU1vZHVsZSgpIHsNCisgICAgICAgIHRyeSB7DQorICAgICAgICAgICAgQ2xhc3MuZm9yTmFtZSgiamF2YS50aW1lLkR1cmF0aW9uIik7DQorICAgICAgICAgICAgQ2xhc3MuZm9yTmFtZSgiamF2YS50aW1lLkluc3RhbnQiKTsNCisgICAgICAgICAgICBDbGFzcy5mb3JOYW1lKCJqYXZhLnRpbWUuWm9uZWREYXRlVGltZSIpOw0KKyAgICAgICAgICAgIENsYXNzLmZvck5hbWUoImphdmEudGltZS5ab25lSWQiKTsNCisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsNCisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIENsYXNzTm90Rm91bmRFeGNlcHRpb24gfCBMaW5rYWdlRXJyb3Igbm90U3VwcG9ydGVkKSB7DQorICAgICAgICB9DQorICAgICAgICByZXR1cm4gZmFsc2U7DQorICAgIH0NCisNCisgICAgLyoqDQorICAgICAqIEZhaWxzIGlmIGFueSBkZWNsYXJlZCB0eXBlcyBhcmUgb3V0c2lkZSBvZiB0aGUgbG9nZ2luZy1tYWlsaGFuZGxlci5qYXIuDQorICAgICAqIFRoaXMgaW5jbHVkZXMgY2xhc3NlcyBmcm9tIHRoZSBKYXZhTWFpbCBzcGVjLg0KKyAgICAgKg0KKyAgICAgKiBAcGFyYW0gayB0aGUgdHlwZSB0byBjaGVjayBmb3IgZGVwZW5kZW5jaWVzLg0KKyAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbiBpZiB0aGVyZSBpcyBhIHByb2JsZW0uDQorICAgICAqLw0KKyAgICBmaW5hbCB2b2lkIHRlc3RKYXZhTWFpbExpbmthZ2UoZmluYWwgQ2xhc3M8Pz4gaykgdGhyb3dzIEV4Y2VwdGlvbiB7DQorICAgICAgICB0ZXN0SmF2YU1haWxMaW5rYWdlKGssIHRydWUpOw0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBGYWlscyBpZiBhbnkgZGVjbGFyZWQgdHlwZXMgYXJlIG91dHNpZGUgb2YgdGhlIGxvZ2dpbmctbWFpbGhhbmRsZXIuamFyLg0KKyAgICAgKg0KKyAgICAgKiBAcGFyYW0gayB0aGUgdHlwZSB0byBjaGVjayBmb3IgZGVwZW5kZW5jaWVzLg0KKyAgICAgKiBAcGFyYW0gaW5jbHVkZVNwZWMgaWYgdHJ1ZSB0aGlzIGluY2x1ZGVzIG9mZmljaWFsIEphdmFNYWlsIHNwZWMgY2xhc3Nlcy4NCisgICAgICogQHRocm93cyBFeGNlcHRpb24gaWYgdGhlcmUgaXMgYSBwcm9ibGVtLg0KKyAgICAgKi8NCisgICAgZmluYWwgdm9pZCB0ZXN0SmF2YU1haWxMaW5rYWdlKGZpbmFsIENsYXNzPD8+IGssIGZpbmFsIGJvb2xlYW4gaW5jbHVkZVNwZWMpDQorICAgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7DQorICAgICAgICBhc3NlcnRGYWxzZShrLmdldE5hbWUoKSwgaXNGcm9tSmF2YU1haWwoaywgaW5jbHVkZVNwZWMpKTsNCisgICAgICAgIGZvciAoQW5ub3RhdGlvbiBhbiA6IGsuZ2V0RGVjbGFyZWRBbm5vdGF0aW9ucygpKSB7DQorICAgICAgICAgICAgYXNzZXJ0RmFsc2UoYW4udG9TdHJpbmcoKSwNCisgICAgICAgICAgICAgICAgICAgIGlzRnJvbUphdmFNYWlsKGFuLmFubm90YXRpb25UeXBlKCksIGluY2x1ZGVTcGVjKSk7DQorICAgICAgICB9DQorDQorICAgICAgICBmb3IgKE1ldGhvZCBtIDogay5nZXREZWNsYXJlZE1ldGhvZHMoKSkgew0KKyAgICAgICAgICAgIGFzc2VydEZhbHNlKG0uZ2V0UmV0dXJuVHlwZSgpLmdldE5hbWUoKSwNCisgICAgICAgICAgICAgICAgICAgIGlzRnJvbUphdmFNYWlsKG0uZ2V0UmV0dXJuVHlwZSgpLCBpbmNsdWRlU3BlYykpOw0KKyAgICAgICAgICAgIGZvciAoQ2xhc3M8Pz4gcCA6IG0uZ2V0UGFyYW1ldGVyVHlwZXMoKSkgew0KKyAgICAgICAgICAgICAgICBhc3NlcnRGYWxzZShwLmdldE5hbWUoKSwgaXNGcm9tSmF2YU1haWwocCwgaW5jbHVkZVNwZWMpKTsNCisgICAgICAgICAgICB9DQorDQorICAgICAgICAgICAgZm9yIChDbGFzczw/PiBlIDogbS5nZXRFeGNlcHRpb25UeXBlcygpKSB7DQorICAgICAgICAgICAgICAgIGFzc2VydEZhbHNlKGUuZ2V0TmFtZSgpLCBpc0Zyb21KYXZhTWFpbChlLCBpbmNsdWRlU3BlYykpOw0KKyAgICAgICAgICAgIH0NCisNCisgICAgICAgICAgICBmb3IgKEFubm90YXRpb24gYW4gOiBtLmdldERlY2xhcmVkQW5ub3RhdGlvbnMoKSkgew0KKyAgICAgICAgICAgICAgICBhc3NlcnRGYWxzZShhbi50b1N0cmluZygpLA0KKyAgICAgICAgICAgICAgICAgICAgICAgIGlzRnJvbUphdmFNYWlsKGFuLmFubm90YXRpb25UeXBlKCksIGluY2x1ZGVTcGVjKSk7DQorICAgICAgICAgICAgfQ0KKyAgICAgICAgfQ0KKw0KKyAgICAgICAgZm9yIChDb25zdHJ1Y3Rvcjw/PiBjIDogay5nZXREZWNsYXJlZENvbnN0cnVjdG9ycygpKSB7DQorICAgICAgICAgICAgZm9yIChDbGFzczw/PiBwIDogYy5nZXRQYXJhbWV0ZXJUeXBlcygpKSB7DQorICAgICAgICAgICAgICAgIGFzc2VydEZhbHNlKHAuZ2V0TmFtZSgpLCBpc0Zyb21KYXZhTWFpbChwLCBpbmNsdWRlU3BlYykpOw0KKyAgICAgICAgICAgIH0NCisNCisgICAgICAgICAgICBmb3IgKENsYXNzPD8+IGUgOiBjLmdldEV4Y2VwdGlvblR5cGVzKCkpIHsNCisgICAgICAgICAgICAgICAgYXNzZXJ0RmFsc2UoZS5nZXROYW1lKCksIGlzRnJvbUphdmFNYWlsKGUsIGluY2x1ZGVTcGVjKSk7DQorICAgICAgICAgICAgfQ0KKw0KKyAgICAgICAgICAgIGZvciAoQW5ub3RhdGlvbiBhbiA6IGMuZ2V0RGVjbGFyZWRBbm5vdGF0aW9ucygpKSB7DQorICAgICAgICAgICAgICAgIGFzc2VydEZhbHNlKGFuLnRvU3RyaW5nKCksDQorICAgICAgICAgICAgICAgICAgICAgICAgaXNGcm9tSmF2YU1haWwoYW4uYW5ub3RhdGlvblR5cGUoKSwgaW5jbHVkZVNwZWMpKTsNCisgICAgICAgICAgICB9DQorICAgICAgICB9DQorDQorICAgICAgICBmb3IgKEZpZWxkIGYgOiBrLmdldERlY2xhcmVkRmllbGRzKCkpIHsNCisgICAgICAgICAgICBmb3IgKEFubm90YXRpb24gYW4gOiBrLmdldERlY2xhcmVkQW5ub3RhdGlvbnMoKSkgew0KKyAgICAgICAgICAgICAgICBhc3NlcnRGYWxzZShhbi50b1N0cmluZygpLA0KKyAgICAgICAgICAgICAgICAgICAgICAgIGlzRnJvbUphdmFNYWlsKGFuLmFubm90YXRpb25UeXBlKCksIGluY2x1ZGVTcGVjKSk7DQorICAgICAgICAgICAgfQ0KKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGYuZ2V0TmFtZSgpLCBpc0Zyb21KYXZhTWFpbChmLmdldFR5cGUoKSwgaW5jbHVkZVNwZWMpKTsNCisgICAgICAgIH0NCisgICAgfQ0KKw0KKyAgICAvKioNCisgICAgICogVGVzdHMgdGhhdCB0aGUgcHJpdmF0ZSBzdGF0aWMgbG9hZERlY2xhcmVkQ2xhc3NlcyBtZXRob2Qgb2YgdGhlIGdpdmVuDQorICAgICAqIHR5cGUuIE9iamVjdHMgdXNlZCBieSB0aGUgTWFpbEhhbmRsZXIgZHVyaW5nIGEgcHVzaCBtaWdodCByZXF1aXJlDQorICAgICAqIGRlY2xhcmluZyBjbGFzc2VzIHRvIGJlIGxvYWRlZCBvbiBjcmVhdGUgc2luY2UgYSBwdXNoIG1heSBoYXBwZW4gYWZ0ZXIgYQ0KKyAgICAgKiBjbGFzcyBsb2FkZXIgaXMgc2h1dGRvd24uDQorICAgICAqDQorICAgICAqIEBwYXJhbSBrIHRoZSB0eXBlIHRvIGNoZWNrIG5ldmVyIG51bGwuDQorICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uIGlmIHRoZXJlIGlzIGEgcHJvYmxlbS4NCisgICAgICovDQorICAgIGZpbmFsIHZvaWQgdGVzdExvYWREZWNsYXJlZENsYXNzZXMoQ2xhc3M8Pz4gaykgdGhyb3dzIEV4Y2VwdGlvbiB7DQorICAgICAgICBNZXRob2QgbSA9IGsuZ2V0RGVjbGFyZWRNZXRob2QoImxvYWREZWNsYXJlZENsYXNzZXMiKTsNCisgICAgICAgIGFzc2VydFRydWUoTW9kaWZpZXIuaXNTdGF0aWMobS5nZXRNb2RpZmllcnMoKSkpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShNb2RpZmllci5pc1ByaXZhdGUobS5nZXRNb2RpZmllcnMoKSkpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKENsYXNzW10uY2xhc3MsIG0uZ2V0UmV0dXJuVHlwZSgpKTsNCisgICAgICAgIG0uc2V0QWNjZXNzaWJsZSh0cnVlKTsNCisgICAgICAgIENsYXNzPD8+W10gbmFtZWQgPSAoQ2xhc3M8Pz5bXSkgbS5pbnZva2UoKE9iamVjdCkgbnVsbCk7DQorICAgICAgICBhc3NlcnRUcnVlKG5hbWVkLmxlbmd0aCAhPSAwKTsNCisgICAgICAgIEhhc2hTZXQ8Q2xhc3M8Pz4+IGRlY2xhcmVkID0gbmV3IEhhc2hTZXQ8PigNCisgICAgICAgICAgICAgICAgQXJyYXlzLjxDbGFzczw/Pj5hc0xpc3Qoay5nZXREZWNsYXJlZENsYXNzZXMoKSkpOw0KKyAgICAgICAgZm9yIChDbGFzczw/PiBjIDogbmFtZWQpIHsNCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoYy50b1N0cmluZygpLCBrLCBjLmdldEVuY2xvc2luZ0NsYXNzKCkpOw0KKyAgICAgICAgICAgIGFzc2VydFRydWUoYy5nZXREZWNsYXJlZENsYXNzZXMoKS5sZW5ndGggPT0gMCk7DQorICAgICAgICAgICAgZGVjbGFyZWQucmVtb3ZlKGMpOw0KKyAgICAgICAgfQ0KKyAgICAgICAgYXNzZXJ0VHJ1ZShkZWNsYXJlZC50b1N0cmluZygpLCBkZWNsYXJlZC5pc0VtcHR5KCkpOw0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBDaGVja3MgdGhhdCB0aGUgZ2l2ZW4gY2xhc3MgaXMgdmlzaWJsZSB0byB0aGUgTG9nTWFuYWdlci4NCisgICAgICoNCisgICAgICogQHBhcmFtIGMgdGhlIGNsYXNzIHRvIGNoZWNrLg0KKyAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbiBpZiB0aGVyZSBpcyBhIHByb2JsZW0uDQorICAgICAqLw0KKyAgICBmaW5hbCB2b2lkIHRlc3RMb2dNYW5hZ2VyTW9kaWZpZXJzKGZpbmFsIENsYXNzPD8+IGMpIHRocm93cyBFeGNlcHRpb24gew0KKyAgICAgICAgYXNzZXJ0VHJ1ZShNb2RpZmllci5pc1B1YmxpYyhjLmdldE1vZGlmaWVycygpKSk7DQorICAgICAgICBhc3NlcnRUcnVlKE1vZGlmaWVyLmlzUHVibGljKGMuZ2V0Q29uc3RydWN0b3IoKS5nZXRNb2RpZmllcnMoKSkpOw0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBDaGVja3MgdGhhdCB0aGUgZ2l2ZW4gY2xhc3MgaXMgbm90IGRlcGVuZGVudCBvbiB0aGUNCisgICAgICoge0Bjb2RlIGphdmF4LmFubm90YXRpb259IGNsYXNzZXMgYXMgdGhleSBhcmUgbm90IHByZXNlbnQgaW4gYWxsDQorICAgICAqIGVudmlyb25tZW50cy4NCisgICAgICoNCisgICAgICogQHBhcmFtIGsgdGhlIGNsYXNzIHRvIGluc3BlY3QuDQorICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uIGlmIHRoZXJlIGlzIGEgcHJvYmxlbS4NCisgICAgICovDQorICAgIGZpbmFsIHZvaWQgdGVzdE5vRGVwZW5kZW5jeU9uSmF2YXhBbm5vdGF0aW9ucyhDbGFzczw/PiBrKSB0aHJvd3MgRXhjZXB0aW9uIHsNCisgICAgICAgIGZvciAoTWV0aG9kIG0gOiBrLmdldERlY2xhcmVkTWV0aG9kcygpKSB7DQorICAgICAgICAgICAgdGVzdE5vSmF2YXhBbm5vdGF0aW9uKG0pOw0KKyAgICAgICAgfQ0KKw0KKyAgICAgICAgZm9yIChGaWVsZCBmIDogay5nZXREZWNsYXJlZEZpZWxkcygpKSB7DQorICAgICAgICAgICAgdGVzdE5vSmF2YXhBbm5vdGF0aW9uKGYpOw0KKyAgICAgICAgfQ0KKw0KKyAgICAgICAgZm9yIChDb25zdHJ1Y3Rvcjw/PiBjIDogay5nZXREZWNsYXJlZENvbnN0cnVjdG9ycygpKSB7DQorICAgICAgICAgICAgdGVzdE5vSmF2YXhBbm5vdGF0aW9uKGMpOw0KKyAgICAgICAgfQ0KKw0KKyAgICAgICAgZm9yIChDbGFzczw/PiBpIDogay5nZXRJbnRlcmZhY2VzKCkpIHsNCisgICAgICAgICAgICB0ZXN0Tm9KYXZheEFubm90YXRpb24oaSk7DQorICAgICAgICB9DQorDQorICAgICAgICBmb3IgKENsYXNzPD8+IGQgOiBrLmdldERlY2xhcmVkQ2xhc3NlcygpKSB7DQorICAgICAgICAgICAgdGVzdE5vRGVwZW5kZW5jeU9uSmF2YXhBbm5vdGF0aW9ucyhkKTsNCisgICAgICAgIH0NCisgICAgfQ0KKw0KKyAgICAvKioNCisgICAgICogV2ViYXBwQ2xhc3NMb2FkZXIuY2xlYXJSZWZlcmVuY2VzU3RhdGljRmluYWwoKSBtZXRob2Qgd2lsbCBpZ25vcmUgZmllbGRzDQorICAgICAqIHRoYXQgaGF2ZSB0eXBlIG5hbWVzIHRoYXQgc3RhcnQgd2l0aCAnamF2YS4nIG9yICdqYXZheC4nLiBUaGlzIHRlc3QNCisgICAgICogY2hlY2tzIHRoYXQgdGhlIGdpdmVuIGNsYXNzIGNvbmZvcm1zIHRvIHRoaXMgcnVsZSBzbyBpdCBkb2Vzbid0IGJlY29tZSBhDQorICAgICAqIHRhcmdldCB0aGF0IHdpbGwgYmUgbnVsbGlmaWVkIGJ5IHRoZSBXZWJhcHBDbGFzc0xvYWRlci4NCisgICAgICoNCisgICAgICogQHBhcmFtIGMgdGhlIGNsYXNzIHRvIGNoZWNrLg0KKyAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbiBpZiB0aGVyZSBpcyBhIHByb2JsZW0uDQorICAgICAqLw0KKyAgICBmaW5hbCB2b2lkIHRlc3RXZWJhcHBDbGFzc0xvYWRlckZpZWxkTmFtZXMoQ2xhc3M8Pz4gYykgdGhyb3dzIEV4Y2VwdGlvbiB7DQorICAgICAgICBmb3IgKEZpZWxkIGYgOiBjLmdldERlY2xhcmVkRmllbGRzKCkpIHsNCisgICAgICAgICAgICBDbGFzczw/PiBrID0gZi5nZXRUeXBlKCk7DQorICAgICAgICAgICAgd2hpbGUgKGsuaXNBcnJheSgpKSB7DQorICAgICAgICAgICAgICAgIGsgPSBrLmdldENvbXBvbmVudFR5cGUoKTsNCisgICAgICAgICAgICB9DQorDQorICAgICAgICAgICAgLyoqDQorICAgICAgICAgICAgICogVGhlIFdlYmFwcENsYXNzTG9hZGVyIGlnbm9yZXMgcHJpbWl0aXZlcywgbm9uLXN0YXRpYywgYW5kDQorICAgICAgICAgICAgICogc3ludGhldGljIGZpZWxkcy4gRm9yIHRoZSBsb2dnaW5nIEFQSSwgdGhpcyB0ZXN0IGlzIHN0cmljdGVyIHRoYW4NCisgICAgICAgICAgICAgKiB3aGF0IHRoZSBXZWJhcHBDbGFzc0xvYWRlciBhY3R1YWxseSBjbGVhcnMuIFRoaXMgcmVzdHJpY3RzIHRoZQ0KKyAgICAgICAgICAgICAqIGxvZ2dpbmcgQVBJIHRvIHN0YW5kYXJkIGZpZWxkIHR5cGVzIGZvciBib3RoIHN0YXRpYyBhbmQNCisgICAgICAgICAgICAgKiBub24tc3RhdGljIGZpZWxkcy4gVGhlIGlkZWEgaXMgdG8gdHJ5IHRvIHN0YXkgZm9yd2FyZCBjb21wYXRpYmxlDQorICAgICAgICAgICAgICogd2l0aCBXZWJhcHBDbGFzc0xvYWRlci4NCisgICAgICAgICAgICAgKi8NCisgICAgICAgICAgICBpZiAoZi5nZXROYW1lKCkuaW5kZXhPZignJCcpIDwgMCAmJiAhay5pc1ByaW1pdGl2ZSgpDQorICAgICAgICAgICAgICAgICAgICAmJiAhay5nZXROYW1lKCkuc3RhcnRzV2l0aCgiamF2YS4iKQ0KKyAgICAgICAgICAgICAgICAgICAgJiYgIWsuZ2V0TmFtZSgpLnN0YXJ0c1dpdGgoImphdmF4LiIpKSB7DQorICAgICAgICAgICAgICAgIGZhaWwoZi50b1N0cmluZygpKTsNCisgICAgICAgICAgICB9DQorICAgICAgICB9DQorDQorICAgICAgICBmb3IgKENsYXNzPD8+IGljIDogYy5nZXREZWNsYXJlZENsYXNzZXMoKSkgew0KKyAgICAgICAgICAgIHRlc3RXZWJhcHBDbGFzc0xvYWRlckZpZWxkTmFtZXMoaWMpOw0KKyAgICAgICAgfQ0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBCbG9ja3MgdGhlIGN1cnJlbnQgdGhyZWFkIHVudGlsIGN1cnJlbnQgdGltZSBoYXMgZWxhcHNlZCBieSBvbmUNCisgICAgICogbWlsbGlzZWNvbmQuDQorICAgICAqDQorICAgICAqIEB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24gaWYgdGhlIGN1cnJlbnQgdGhyZWFkIGlzIGludGVycnVwdGVkLg0KKyAgICAgKi8NCisgICAgc3RhdGljIHZvaWQgdGlja01pbGxpKCkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsNCisgICAgICAgIHRpY2tNaWxsaSgxTCk7DQorICAgIH0NCisNCisgICAgLyoqDQorICAgICAqIEJsb2NrcyB0aGUgY3VycmVudCB0aHJlYWQgdW50aWwgY3VycmVudCB0aW1lIGhhcyBlbGFwc2VkIGJ5IHRoZSBnaXZlbg0KKyAgICAgKiBkZWxheSBpbiBtaWxsaXNlY29uZHMuDQorICAgICAqDQorICAgICAqIEBwYXJhbSBkZWxheSB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0aGF0IGhhdmUgdG8gZWxhcHNlLg0KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgZ2l2ZW4gZGVsYXkgaXMgemVybyBvciBsZXNzLg0KKyAgICAgKiBAdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIGlmIHRoZSBjdXJyZW50IHRocmVhZCBpcyBpbnRlcnJ1cHRlZC4NCisgICAgICovDQorICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJTbGVlcFdoaWxlSW5Mb29wIikNCisgICAgc3RhdGljIHZvaWQgdGlja01pbGxpKGxvbmcgZGVsYXkpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7DQorICAgICAgICBpZiAoZGVsYXkgPD0gMEwpIHsNCisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKExvbmcudG9TdHJpbmcoZGVsYXkpKTsNCisgICAgICAgIH0NCisgICAgICAgIGxvbmcgdGhlbiA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOw0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBTaG9ydC5NQVhfVkFMVUU7IGkrKykgew0KKyAgICAgICAgICAgIGxvbmcgbm93ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7DQorICAgICAgICAgICAgbG9uZyBkZWx0YSA9IChub3cgLSB0aGVuKTsNCisgICAgICAgICAgICBpZiAoZGVsdGEgPj0gZGVsYXkpIHsNCisgICAgICAgICAgICAgICAgcmV0dXJuOw0KKyAgICAgICAgICAgIH0NCisgICAgICAgICAgICBUaHJlYWQuc2xlZXAoZGVsYXkgLSBkZWx0YSk7DQorICAgICAgICB9DQorICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IodGhlbiArICIgIiArIFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpKTsNCisgICAgfQ0KKw0KKyAgICBwcml2YXRlIGJvb2xlYW4gaXNGcm9tSmF2YU1haWwoQ2xhc3M8Pz4gaywgYm9vbGVhbiBpbmNsdWRlKSB0aHJvd3MgRXhjZXB0aW9uIHsNCisgICAgICAgIGZvciAoQ2xhc3M8Pz4gdCA9IGs7IHQgIT0gbnVsbDsgdCA9IHQuZ2V0U3VwZXJjbGFzcygpKSB7DQorICAgICAgICAgICAgZmluYWwgU3RyaW5nIG4gPSB0LmdldE5hbWUoKTsNCisgICAgICAgICAgICBpZiAobi5zdGFydHNXaXRoKCJqYXZheC5tYWlsLiIpKSB7DQorICAgICAgICAgICAgICAgIHJldHVybiBpbmNsdWRlOw0KKyAgICAgICAgICAgIH0NCisNCisgICAgICAgICAgICAvL05vdCBpbmNsdWRlZCB3aXRoIGxvZ2dpbmctbWFpbGhhbmRsZXIuamFyLg0KKyAgICAgICAgICAgIGlmIChuLnN0YXJ0c1dpdGgoImNvbS5zdW4ubWFpbC4iKQ0KKyAgICAgICAgICAgICAgICAgICAgJiYgIW4uc3RhcnRzV2l0aCgiY29tLnN1bi5tYWlsLnV0aWwubG9nZ2luZy4iKSkgew0KKyAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsNCisgICAgICAgICAgICB9DQorICAgICAgICB9DQorICAgICAgICByZXR1cm4gZmFsc2U7DQorICAgIH0NCisNCisgICAgcHJpdmF0ZSB2b2lkIHRlc3ROb0phdmF4QW5ub3RhdGlvbihBY2Nlc3NpYmxlT2JqZWN0IGZtKSB0aHJvd3MgRXhjZXB0aW9uIHsNCisgICAgICAgIGZvciAoQW5ub3RhdGlvbiBhIDogZm0uZ2V0QW5ub3RhdGlvbnMoKSkgew0KKyAgICAgICAgICAgIHRlc3ROb0phdmF4QW5ub3RhdGlvbihhLmFubm90YXRpb25UeXBlKCkpOw0KKyAgICAgICAgfQ0KKyAgICB9DQorDQorICAgIHByaXZhdGUgdm9pZCB0ZXN0Tm9KYXZheEFubm90YXRpb24oQ2xhc3M8Pz4gaykgdGhyb3dzIEV4Y2VwdGlvbiB7DQorICAgICAgICBmb3IgKDsgayAhPSBudWxsOyBrID0gay5nZXRTdXBlcmNsYXNzKCkpIHsNCisgICAgICAgICAgICBhc3NlcnRGYWxzZShrLnRvU3RyaW5nKCksDQorICAgICAgICAgICAgICAgICAgICBrLmdldE5hbWUoKS5zdGFydHNXaXRoKCJqYXZheC5hbm5vdGF0aW9uIikpOw0KKyAgICAgICAgfQ0KKyAgICB9DQorfQ0KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvdXRpbC9sb2dnaW5nL0NvbGxlY3RvckZvcm1hdHRlclRlc3QuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvdXRpbC9sb2dnaW5nL0NvbGxlY3RvckZvcm1hdHRlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNjA4MzQ1Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL2xvZ2dpbmcvQ29sbGVjdG9yRm9ybWF0dGVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTA4OSBAQAorLyoNCisgKiBDb3B5cmlnaHQgKGMpIDIwMTMsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCisgKiBDb3B5cmlnaHQgKGMpIDIwMTMsIDIwMTggSmFzb24gTWVocmVucy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCisgKg0KKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQ0KKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0DQorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLg0KKyAqDQorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQ0KKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUNCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwNCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdA0KKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4NCisgKg0KKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMA0KKyAqLw0KK3BhY2thZ2UgY29tLnN1bi5tYWlsLnV0aWwubG9nZ2luZzsNCisNCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsNCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07DQoraW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247DQoraW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07DQoraW1wb3J0IGphdmEudGV4dC5EYXRlRm9ybWF0Ow0KK2ltcG9ydCBqYXZhLnRleHQuTWVzc2FnZUZvcm1hdDsNCitpbXBvcnQgamF2YS50ZXh0Lk51bWJlckZvcm1hdDsNCitpbXBvcnQgamF2YS50ZXh0LlNpbXBsZURhdGVGb3JtYXQ7DQoraW1wb3J0IGphdmEudXRpbC4qOw0KK2ltcG9ydCBqYXZhLnV0aWwubG9nZ2luZy4qOw0KK2ltcG9ydCBqYXZhLnV0aWwubG9nZ2luZy5Gb3JtYXR0ZXI7DQoraW1wb3J0IG9yZy5qdW5pdC4qOw0KK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC4qOw0KKw0KKy8qKg0KKyAqIFRoZSBjb2xsZWN0b3IgZm9ybWF0dGVyIHRlc3RzLg0KKyAqDQorICogQGF1dGhvciBKYXNvbiBNZWhyZW5zDQorICogQHNpbmNlIEphdmFNYWlsIDEuNS4yDQorICovDQorcHVibGljIGNsYXNzIENvbGxlY3RvckZvcm1hdHRlclRlc3QgZXh0ZW5kcyBBYnN0cmFjdExvZ2dpbmcgew0KKw0KKyAgICAvKioNCisgICAgICogU2VlIExvZ01hbmFnZXIuDQorICAgICAqLw0KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTE9HX0NGR19LRVkgPSAiamF2YS51dGlsLmxvZ2dpbmcuY29uZmlnLmZpbGUiOw0KKyAgICAvKioNCisgICAgICogRGF0ZSBhbmQgdGltZSBzaW1wbGUgZm9ybWF0IHBhdHRlcm4uDQorICAgICAqLw0KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgREFURV9USU1FX0ZNVCA9ICJFRUUsIE1NTSBkZCBISDptbTpzczpTIFpaWiB5eXl5IjsNCisNCisgICAgLyoqDQorICAgICAqIFRoZSBsaW5lIHNlcGFyYXRvci4NCisgICAgICovDQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBMSU5FX1NFUCA9IFN5c3RlbS5saW5lU2VwYXJhdG9yKCk7DQorDQorICAgIHByaXZhdGUgc3RhdGljIHZvaWQgY2hlY2tKVk1PcHRpb25zKCkgdGhyb3dzIEV4Y2VwdGlvbiB7DQorICAgICAgICBhc3NlcnRUcnVlKENvbGxlY3RvckZvcm1hdHRlclRlc3QuY2xhc3MuZGVzaXJlZEFzc2VydGlvblN0YXR1cygpKTsNCisgICAgICAgIGFzc2VydE51bGwoU3lzdGVtLmdldFByb3BlcnR5KCJqYXZhLnV0aWwubG9nZ2luZy5tYW5hZ2VyIikpOw0KKyAgICAgICAgYXNzZXJ0TnVsbChTeXN0ZW0uZ2V0UHJvcGVydHkoImphdmEudXRpbC5sb2dnaW5nLmNvbmZpZy5jbGFzcyIpKTsNCisgICAgICAgIGFzc2VydE51bGwoU3lzdGVtLmdldFByb3BlcnR5KExPR19DRkdfS0VZKSk7DQorICAgICAgICBhc3NlcnRFcXVhbHMoTG9nTWFuYWdlci5jbGFzcywgTG9nTWFuYWdlci5nZXRMb2dNYW5hZ2VyKCkuZ2V0Q2xhc3MoKSk7DQorICAgIH0NCisNCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBmdWxsRmVuY2UoKSB7DQorICAgICAgICBMb2dNYW5hZ2VyLmdldExvZ01hbmFnZXIoKS5nZXRQcm9wZXJ0eSgiIik7DQorICAgIH0NCisNCisgICAgQEJlZm9yZUNsYXNzDQorICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRVcENsYXNzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7DQorICAgICAgICBjaGVja0pWTU9wdGlvbnMoKTsNCisgICAgfQ0KKw0KKyAgICBAQWZ0ZXJDbGFzcw0KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgdGVhckRvd25DbGFzcygpIHRocm93cyBFeGNlcHRpb24gew0KKyAgICAgICAgY2hlY2tKVk1PcHRpb25zKCk7DQorICAgIH0NCisNCisgICAgQEJlZm9yZQ0KKyAgICBwdWJsaWMgdm9pZCBzZXRVcCgpIHsNCisgICAgICAgIGZ1bGxGZW5jZSgpOw0KKyAgICB9DQorDQorICAgIEBBZnRlcg0KKyAgICBwdWJsaWMgdm9pZCB0ZWFyRG93bigpIHsNCisgICAgICAgIGZ1bGxGZW5jZSgpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3REZWNsYXJlZENsYXNzZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsNCisgICAgICAgIENsYXNzPD8+W10gZGVjbGFyZWQgPSBDb2xsZWN0b3JGb3JtYXR0ZXIuY2xhc3MuZ2V0RGVjbGFyZWRDbGFzc2VzKCk7DQorICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLnRvU3RyaW5nKGRlY2xhcmVkKSwgMCwgZGVjbGFyZWQubGVuZ3RoKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0SGVhZCgpIHsNCisgICAgICAgIFN0cmluZyBtc2cgPSAibWVzc2FnZSI7DQorICAgICAgICBYTUxGb3JtYXR0ZXIgeG1sID0gbmV3IFhNTEZvcm1hdHRlcigpOw0KKyAgICAgICAgQ29sbGVjdG9yRm9ybWF0dGVyIGYgPSBuZXcgQ29sbGVjdG9yRm9ybWF0dGVyKCJ7MH0iLCB4bWwsDQorICAgICAgICAgICAgICAgIChDb21wYXJhdG9yPExvZ1JlY29yZD4pIG51bGwpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBmLmdldEhlYWQoKEhhbmRsZXIpIG51bGwpKTsNCisgICAgICAgIGYuZm9ybWF0KG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCBtc2cpKTsNCisNCisgICAgICAgIFN0cmluZyByZXN1bHQgPSBmLmdldFRhaWwoKEhhbmRsZXIpIG51bGwpOw0KKyAgICAgICAgU3RyaW5nIGV4cGVjdCA9IGYuZmluaXNoKHhtbC5nZXRIZWFkKChIYW5kbGVyKSBudWxsKSk7DQorICAgICAgICBhc3NlcnRFcXVhbHMocmVzdWx0LCBleHBlY3QpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBmLmdldEhlYWQoKEhhbmRsZXIpIG51bGwpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdChleHBlY3RlZCA9IE51bGxQb2ludGVyRXhjZXB0aW9uLmNsYXNzKQ0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0QXBwbHlSZXR1cm5zTnVsbCgpIHsNCisgICAgICAgIENvbGxlY3RvckZvcm1hdHRlciBmID0gbmV3IEFwcGx5UmV0dXJuc051bGwoKTsNCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7IGkrKykgew0KKyAgICAgICAgICAgIFN0cmluZyBvID0gZi5mb3JtYXQobmV3IExvZ1JlY29yZChMZXZlbC5JTkZPLCAiIikpOw0KKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwobyk7DQorICAgICAgICB9DQorICAgIH0NCisNCisgICAgQFRlc3QoZXhwZWN0ZWQgPSBOdWxsUG9pbnRlckV4Y2VwdGlvbi5jbGFzcykNCisgICAgcHVibGljIHZvaWQgdGVzdEZvcm1hdE51bGwoKSB7DQorICAgICAgICBDb2xsZWN0b3JGb3JtYXR0ZXIgZiA9IG5ldyBDb2xsZWN0b3JGb3JtYXR0ZXIoInsxfSIsIChGb3JtYXR0ZXIpIG51bGwsDQorICAgICAgICAgICAgICAgIChDb21wYXJhdG9yPExvZ1JlY29yZD4pIG51bGwpOw0KKyAgICAgICAgZi5mb3JtYXQoKExvZ1JlY29yZCkgbnVsbCk7DQorICAgIH0NCisNCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdEZvcm1hdHRlckFjY2VwdCBleHRlbmRzIExvZ1JlY29yZCB7DQorDQorICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTDsNCisNCisgICAgICAgIGludCBpbmZlcnJlZDsNCisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJGaWVsZE1heUJlRmluYWwiKQ0KKyAgICAgICAgcHJpdmF0ZSB0cmFuc2llbnQgRm9ybWF0dGVyIGY7DQorDQorICAgICAgICBUZXN0Rm9ybWF0dGVyQWNjZXB0KExldmVsIGxldmVsLCBDb2xsZWN0b3JGb3JtYXR0ZXIgZikgew0KKyAgICAgICAgICAgIHN1cGVyKGxldmVsLCAiIik7DQorICAgICAgICAgICAgdGhpcy5mID0gZjsNCisgICAgICAgIH0NCisNCisgICAgICAgIEBPdmVycmlkZQ0KKyAgICAgICAgcHVibGljIFRocm93YWJsZSBnZXRUaHJvd24oKSB7DQorICAgICAgICAgICAgaWYgKGluZmVycmVkID09IDApIHsNCisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKExldmVsLklORk8uZ2V0TG9jYWxpemVkTmFtZSgpLmNvbmNhdCgiMTExMTEiKSwNCisgICAgICAgICAgICAgICAgICAgICAgICBmLmdldFRhaWwoKEhhbmRsZXIpIG51bGwpKTsNCisgICAgICAgICAgICB9DQorICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldFRocm93bigpOw0KKyAgICAgICAgfQ0KKw0KKyAgICAgICAgQE92ZXJyaWRlDQorICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFNvdXJjZU1ldGhvZE5hbWUoKSB7DQorICAgICAgICAgICAgKytpbmZlcnJlZDsNCisgICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0U291cmNlTWV0aG9kTmFtZSgpOw0KKyAgICAgICAgfQ0KKyAgICB9DQorDQorICAgIEBUZXN0KHRpbWVvdXQgPSA2MDAwMCkNCisgICAgcHVibGljIHZvaWQgdGVzdEZvcm1hdEFjY2VwdCgpIHRocm93cyBFeGNlcHRpb24gew0KKyAgICAgICAgZmluYWwgQ29sbGVjdG9yRm9ybWF0dGVyIGYgPSBuZXcgQ29sbGVjdG9yRm9ybWF0dGVyKA0KKyAgICAgICAgICAgICAgICAiezF9ezN9ezV9ezd9ezh9ezEzfSIsDQorICAgICAgICAgICAgICAgIG5ldyBDb21wYWN0Rm9ybWF0dGVyKCIlNCRzIiksDQorICAgICAgICAgICAgICAgIG5ldyBTZXZlcml0eUNvbXBhcmF0b3IoKSk7DQorICAgICAgICBMb2dSZWNvcmQgZmlyc3QgPSBuZXcgTG9nUmVjb3JkKExldmVsLklORk8sICIiKTsNCisgICAgICAgIGZpcnN0LnNldFRocm93bihuZXcgVGhyb3dhYmxlKCkpOw0KKyAgICAgICAgc2V0RXBvY2hNaWxsaShmaXJzdCwgMUwpOw0KKyAgICAgICAgZi5mb3JtYXQoZmlyc3QpOw0KKw0KKyAgICAgICAgVGVzdEZvcm1hdHRlckFjY2VwdCByID0gbmV3IFRlc3RGb3JtYXR0ZXJBY2NlcHQoTGV2ZWwuRklORSwgZik7DQorICAgICAgICBzZXRFcG9jaE1pbGxpKHIsIDJMKTsNCisgICAgICAgIHIuc2V0VGhyb3duKG5ldyBUaHJvd2FibGUoKSk7DQorICAgICAgICBmLmZvcm1hdChyKTsNCisgICAgICAgIGFzc2VydEVxdWFscygxLCByLmluZmVycmVkKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhMZXZlbC5GSU5FLmdldExvY2FsaXplZE5hbWUoKS5jb25jYXQoIjExMjIyIiksDQorICAgICAgICAgICAgICAgIGYuZ2V0VGFpbCgoSGFuZGxlcikgbnVsbCkpOw0KKyAgICB9DQorDQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RGb3JtYXRBY2NlcHRBbmRVcGRhdGUgZXh0ZW5kcyBMb2dSZWNvcmQgew0KKw0KKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7DQorICAgICAgICBpbnQgaW5mZXJyZWQ7DQorICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygiRmllbGRNYXlCZUZpbmFsIikNCisgICAgICAgIHByaXZhdGUgdHJhbnNpZW50IEZvcm1hdHRlciBmOw0KKw0KKyAgICAgICAgcHVibGljIFRlc3RGb3JtYXRBY2NlcHRBbmRVcGRhdGUoTGV2ZWwgbGV2ZWwsIENvbGxlY3RvckZvcm1hdHRlciBmKSB7DQorICAgICAgICAgICAgc3VwZXIobGV2ZWwsICIiKTsNCisgICAgICAgICAgICB0aGlzLmYgPSBmOw0KKyAgICAgICAgfQ0KKw0KKyAgICAgICAgQE92ZXJyaWRlDQorICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFNvdXJjZU1ldGhvZE5hbWUoKSB7DQorICAgICAgICAgICAgaWYgKCsraW5mZXJyZWQgPT0gMSkgew0KKyAgICAgICAgICAgICAgICBMb2dSZWNvcmQgciA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuSU5GTywgIiIpOw0KKyAgICAgICAgICAgICAgICBzZXRFcG9jaE1pbGxpKHIsIDFMKTsNCisgICAgICAgICAgICAgICAgZi5mb3JtYXQocik7DQorICAgICAgICAgICAgfQ0KKyAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXRTb3VyY2VNZXRob2ROYW1lKCk7DQorICAgICAgICB9DQorICAgIH0NCisNCisgICAgQFRlc3QodGltZW91dCA9IDYwMDAwKQ0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0QWNjZXB0QW5kVXBkYXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7DQorICAgICAgICBmaW5hbCBDb2xsZWN0b3JGb3JtYXR0ZXIgZiA9IG5ldyBDb2xsZWN0b3JGb3JtYXR0ZXIoDQorICAgICAgICAgICAgICAgICJ7MX17M317NX17N317OH17MTN9IiwNCisgICAgICAgICAgICAgICAgbmV3IENvbXBhY3RGb3JtYXR0ZXIoIiU0JHMiKSwNCisgICAgICAgICAgICAgICAgbmV3IFNldmVyaXR5Q29tcGFyYXRvcigpKTsNCisNCisgICAgICAgIFRlc3RGb3JtYXRBY2NlcHRBbmRVcGRhdGUgcg0KKyAgICAgICAgICAgICAgICA9IG5ldyBUZXN0Rm9ybWF0QWNjZXB0QW5kVXBkYXRlKExldmVsLlNFVkVSRSwgZik7DQorICAgICAgICBzZXRFcG9jaE1pbGxpKHIsIDJMKTsNCisgICAgICAgIHIuc2V0VGhyb3duKG5ldyBUaHJvd2FibGUoKSk7DQorICAgICAgICBmLmZvcm1hdChyKTsNCisgICAgICAgIGFzc2VydEVxdWFscygyLCByLmluZmVycmVkKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhMZXZlbC5TRVZFUkUuZ2V0TG9jYWxpemVkTmFtZSgpLmNvbmNhdCgiMjExMjEiKSwNCisgICAgICAgICAgICAgICAgZi5nZXRUYWlsKChIYW5kbGVyKSBudWxsKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEZvcm1hdEZvcm1hdCgpIHsNCisgICAgICAgIFN0cmluZyBtc2cgPSAibWVzc2FnZSI7DQorICAgICAgICBYTUxGb3JtYXR0ZXIgeG1sID0gbmV3IFhNTEZvcm1hdHRlcigpOw0KKyAgICAgICAgQ29sbGVjdG9yRm9ybWF0dGVyIGYgPSBuZXcgQ29sbGVjdG9yRm9ybWF0dGVyKCJ7MX0iLCB4bWwsDQorICAgICAgICAgICAgICAgIChDb21wYXJhdG9yPExvZ1JlY29yZD4pIG51bGwpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBmLmdldFRhaWwoKEhhbmRsZXIpIG51bGwpKTsNCisgICAgICAgIExvZ1JlY29yZCByOw0KKyAgICAgICAgciA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCBtc2cpOw0KKyAgICAgICAgZi5mb3JtYXQocik7DQorDQorICAgICAgICBTdHJpbmcgcmVzdWx0ID0gZi5nZXRUYWlsKChIYW5kbGVyKSBudWxsKTsNCisgICAgICAgIFN0cmluZyBleHBlY3QgPSBmLmZpbmlzaCh4bWwuZm9ybWF0KHIpKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhyZXN1bHQsIGV4cGVjdCk7DQorICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIGYuZ2V0VGFpbCgoSGFuZGxlcikgbnVsbCkpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRGb3JtYXRMb2NhbGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsNCisgICAgICAgIFN0cmluZyBtc2cgPSAibWVzc2FnZSI7DQorICAgICAgICBYTUxGb3JtYXR0ZXIgeG1sID0gbmV3IFhNTEZvcm1hdHRlcigpOw0KKyAgICAgICAgQ29sbGVjdG9yRm9ybWF0dGVyIGYgPSBuZXcgQ29sbGVjdG9yRm9ybWF0dGVyKCJ7MX0iLCB4bWwsDQorICAgICAgICAgICAgICAgIChDb21wYXJhdG9yPExvZ1JlY29yZD4pIG51bGwpOw0KKw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBmLmdldFRhaWwoKEhhbmRsZXIpIG51bGwpKTsNCisgICAgICAgIExvZ1JlY29yZCByOw0KKyAgICAgICAgciA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCBMT0dfQ0ZHX0tFWSk7DQorICAgICAgICBQcm9wZXJ0aWVzIHByb3BzID0gbmV3IFByb3BlcnRpZXMoKTsNCisgICAgICAgIHByb3BzLnB1dChMT0dfQ0ZHX0tFWSwgbXNnKTsNCisNCisgICAgICAgIHIuc2V0UmVzb3VyY2VCdW5kbGUobmV3IExvY2FsZVJlc291cmNlKHByb3BzLCBMb2NhbGUuVVMpKTsNCisgICAgICAgIGFzc2VydE5vdE51bGwoci5nZXRSZXNvdXJjZUJ1bmRsZSgpLmdldExvY2FsZSgpKTsNCisgICAgICAgIGYuZm9ybWF0KHIpOw0KKw0KKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IGYuZ2V0VGFpbCgoSGFuZGxlcikgbnVsbCk7DQorICAgICAgICBTdHJpbmcgZXhwZWN0ID0gZi5maW5pc2goeG1sLmZvcm1hdChyKSk7DQorICAgICAgICBhc3NlcnRFcXVhbHMocmVzdWx0LCBleHBlY3QpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKG1zZywgZi5mb3JtYXRNZXNzYWdlKHIpKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhtc2csIHhtbC5mb3JtYXRNZXNzYWdlKHIpKTsNCisgICAgICAgIGFzc2VydEVxdWFscygiIiwgZi5nZXRUYWlsKChIYW5kbGVyKSBudWxsKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEZvcm1hdE5vUmVjb3JkcygpIHsNCisgICAgICAgIFhNTEZvcm1hdHRlciB4bWwgPSBuZXcgWE1MRm9ybWF0dGVyKCk7DQorICAgICAgICBDb2xsZWN0b3JGb3JtYXR0ZXIgZiA9IG5ldyBDb2xsZWN0b3JGb3JtYXR0ZXIoKFN0cmluZykgbnVsbCwgeG1sLA0KKyAgICAgICAgICAgICAgICAoQ29tcGFyYXRvcjxMb2dSZWNvcmQ+KSBudWxsKTsNCisNCisgICAgICAgIFN0cmluZyByZXN1bHQgPSBmLmdldFRhaWwoKEhhbmRsZXIpIG51bGwpOw0KKyAgICAgICAgU3RyaW5nIGV4cGVjdCA9IGYuZmluaXNoKHhtbC5nZXRIZWFkKChIYW5kbGVyKSBudWxsKSkNCisgICAgICAgICAgICAgICAgKyBmLmZpbmlzaCh4bWwuZ2V0VGFpbCgoSGFuZGxlcikgbnVsbCkpICsgJ1xuJzsNCisgICAgICAgIGFzc2VydEVxdWFscyhyZXN1bHQsIGV4cGVjdCk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEZvcm1hdE9uZVJlY29yZCgpIHsNCisgICAgICAgIFhNTEZvcm1hdHRlciB4bWwgPSBuZXcgWE1MRm9ybWF0dGVyKCk7DQorICAgICAgICBDb2xsZWN0b3JGb3JtYXR0ZXIgZiA9IG5ldyBDb2xsZWN0b3JGb3JtYXR0ZXIoKFN0cmluZykgbnVsbCwgeG1sLA0KKyAgICAgICAgICAgICAgICAoQ29tcGFyYXRvcjxMb2dSZWNvcmQ+KSBudWxsKTsNCisgICAgICAgIExvZ1JlY29yZCByZWNvcmQgPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgIm1lc3NhZ2UiKTsNCisgICAgICAgIGFzc2VydEVxdWFscygiIiwgZi5mb3JtYXQocmVjb3JkKSk7DQorICAgICAgICBTdHJpbmcgcmVzdWx0ID0gZi5nZXRUYWlsKChIYW5kbGVyKSBudWxsKTsNCisgICAgICAgIFN0cmluZyBleHBlY3QgPSBmLmZpbmlzaCh4bWwuZ2V0SGVhZCgoSGFuZGxlcikgbnVsbCkpDQorICAgICAgICAgICAgICAgICsgZi5maW5pc2goeG1sLmZvcm1hdChyZWNvcmQpKQ0KKyAgICAgICAgICAgICAgICArIGYuZmluaXNoKHhtbC5nZXRUYWlsKChIYW5kbGVyKSBudWxsKSkgKyAnXG4nOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdCwgZXhwZWN0KTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0VHdvUmVjb3JkcygpIHsNCisgICAgICAgIFhNTEZvcm1hdHRlciB4bWwgPSBuZXcgWE1MRm9ybWF0dGVyKCk7DQorICAgICAgICBDb2xsZWN0b3JGb3JtYXR0ZXIgZiA9IG5ldyBDb2xsZWN0b3JGb3JtYXR0ZXIoKFN0cmluZykgbnVsbCwgeG1sLA0KKyAgICAgICAgICAgICAgICAoQ29tcGFyYXRvcjxMb2dSZWNvcmQ+KSBudWxsKTsNCisgICAgICAgIExvZ1JlY29yZCByZWNvcmQgPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgImZpcnN0Iik7DQorICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIGYuZm9ybWF0KHJlY29yZCkpOw0KKw0KKyAgICAgICAgcmVjb3JkID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICJzZWNvbmQiKTsNCisgICAgICAgIGFzc2VydEVxdWFscygiIiwgZi5mb3JtYXQocmVjb3JkKSk7DQorICAgICAgICBTdHJpbmcgcmVzdWx0ID0gZi5nZXRUYWlsKChIYW5kbGVyKSBudWxsKTsNCisgICAgICAgIFN0cmluZyBleHBlY3QgPSBmLmZpbmlzaCh4bWwuZ2V0SGVhZCgoSGFuZGxlcikgbnVsbCkpDQorICAgICAgICAgICAgICAgICsgZi5maW5pc2goeG1sLmZvcm1hdChyZWNvcmQpKQ0KKyAgICAgICAgICAgICAgICArIGYuZmluaXNoKHhtbC5nZXRUYWlsKChIYW5kbGVyKSBudWxsKSkgKyAiLi4uIDEgbW9yZVxuIjsNCisgICAgICAgIGFzc2VydEVxdWFscyhyZXN1bHQsIGV4cGVjdCk7DQorICAgIH0NCisNCisgICAgQFRlc3QoZXhwZWN0ZWQgPSBOdWxsUG9pbnRlckV4Y2VwdGlvbi5jbGFzcykNCisgICAgcHVibGljIHZvaWQgdGVzdEZpbmlzaE51bGwoKSB7DQorICAgICAgICBDb2xsZWN0b3JGb3JtYXR0ZXIgZiA9IG5ldyBDb2xsZWN0b3JGb3JtYXR0ZXIoKTsNCisgICAgICAgIFN0cmluZyByZXN1bHQgPSBmLmZpbmlzaCgoU3RyaW5nKSBudWxsKTsNCisgICAgICAgIGZhaWwocmVzdWx0KTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0RmluaXNoKCkgew0KKyAgICAgICAgQ29sbGVjdG9yRm9ybWF0dGVyIGYgPSBuZXcgQ29sbGVjdG9yRm9ybWF0dGVyKCk7DQorICAgICAgICBTdHJpbmcgZm9ybWF0ID0gTElORV9TRVAgKyBmLmdldENsYXNzKCkuZ2V0TmFtZSgpICsgTElORV9TRVA7DQorICAgICAgICBhc3NlcnRGYWxzZShmLmdldENsYXNzKCkuZ2V0TmFtZSgpLmVxdWFscyhmb3JtYXQpKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhmLmdldENsYXNzKCkuZ2V0TmFtZSgpLCBmLmZpbmlzaChmb3JtYXQpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0VGFpbCgpIHsNCisgICAgICAgIFN0cmluZyBtc2cgPSAibWVzc2FnZSI7DQorICAgICAgICBYTUxGb3JtYXR0ZXIgeG1sID0gbmV3IFhNTEZvcm1hdHRlcigpOw0KKyAgICAgICAgQ29sbGVjdG9yRm9ybWF0dGVyIGYgPSBuZXcgQ29sbGVjdG9yRm9ybWF0dGVyKCJ7Mn0iLCB4bWwsDQorICAgICAgICAgICAgICAgIChDb21wYXJhdG9yPExvZ1JlY29yZD4pIG51bGwpOw0KKyAgICAgICAgZi5mb3JtYXQobmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsIG1zZykpOw0KKw0KKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IGYuZ2V0VGFpbCgoSGFuZGxlcikgbnVsbCk7DQorICAgICAgICBTdHJpbmcgZXhwZWN0ID0gZi5maW5pc2goeG1sLmdldFRhaWwoKEhhbmRsZXIpIG51bGwpKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhyZXN1bHQsIGV4cGVjdCk7DQorICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0LCBmLmdldFRhaWwoKEhhbmRsZXIpIG51bGwpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0Q291bnQoKSB7DQorICAgICAgICBTdHJpbmcgbXNnID0gIm1lc3NhZ2UiOw0KKyAgICAgICAgQ29sbGVjdG9yRm9ybWF0dGVyIGYgPSBuZXcgQ29sbGVjdG9yRm9ybWF0dGVyKCJ7M30iLCAoRm9ybWF0dGVyKSBudWxsLA0KKyAgICAgICAgICAgICAgICAoQ29tcGFyYXRvcjxMb2dSZWNvcmQ+KSBudWxsKTsNCisgICAgICAgIGFzc2VydEVxdWFscygiMCIsIGYuZ2V0VGFpbCgoSGFuZGxlcikgbnVsbCkpOw0KKyAgICAgICAgZi5mb3JtYXQobmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsIG1zZykpOw0KKyAgICAgICAgZi5mb3JtYXQobmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsIG1zZykpOw0KKyAgICAgICAgZi5mb3JtYXQobmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsIG1zZykpOw0KKyAgICAgICAgZi5mb3JtYXQobmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsIG1zZykpOw0KKw0KKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IGYuZ2V0VGFpbCgoSGFuZGxlcikgbnVsbCk7DQorICAgICAgICBhc3NlcnRFcXVhbHMocmVzdWx0LCAiNCIpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIwIiwgZi5nZXRUYWlsKChIYW5kbGVyKSBudWxsKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEZvcm1hdFJlbWFpbmcoKSB7DQorICAgICAgICBTdHJpbmcgbXNnID0gIm1lc3NhZ2UiOw0KKyAgICAgICAgQ29sbGVjdG9yRm9ybWF0dGVyIGYgPSBuZXcgQ29sbGVjdG9yRm9ybWF0dGVyKCJ7NH0iLCAoRm9ybWF0dGVyKSBudWxsLA0KKyAgICAgICAgICAgICAgICAoQ29tcGFyYXRvcjxMb2dSZWNvcmQ+KSBudWxsKTsNCisgICAgICAgIGFzc2VydEVxdWFscygiLTEiLCBmLmdldFRhaWwoKEhhbmRsZXIpIG51bGwpKTsNCisgICAgICAgIGYuZm9ybWF0KG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCBtc2cpKTsNCisgICAgICAgIGYuZm9ybWF0KG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCBtc2cpKTsNCisgICAgICAgIGYuZm9ybWF0KG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCBtc2cpKTsNCisgICAgICAgIGYuZm9ybWF0KG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCBtc2cpKTsNCisNCisgICAgICAgIFN0cmluZyByZXN1bHQgPSBmLmdldFRhaWwoKEhhbmRsZXIpIG51bGwpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdCwgIjMiKTsNCisgICAgICAgIGFzc2VydEVxdWFscygiLTEiLCBmLmdldFRhaWwoKEhhbmRsZXIpIG51bGwpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0VGhyb3duKCkgew0KKyAgICAgICAgU3RyaW5nIG1zZyA9ICJtZXNzYWdlIjsNCisgICAgICAgIENvbGxlY3RvckZvcm1hdHRlciBmID0gbmV3IENvbGxlY3RvckZvcm1hdHRlcigiezV9IiwgKEZvcm1hdHRlcikgbnVsbCwNCisgICAgICAgICAgICAgICAgKENvbXBhcmF0b3I8TG9nUmVjb3JkPikgbnVsbCk7DQorICAgICAgICBhc3NlcnRFcXVhbHMoIjAiLCBmLmdldFRhaWwoKEhhbmRsZXIpIG51bGwpKTsNCisgICAgICAgIGYuZm9ybWF0KG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCBtc2cpKTsNCisgICAgICAgIGYuZm9ybWF0KG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCBtc2cpKTsNCisNCisgICAgICAgIExvZ1JlY29yZCByID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsIG1zZyk7DQorICAgICAgICByLnNldFRocm93bihuZXcgRXhjZXB0aW9uKCkpOw0KKyAgICAgICAgZi5mb3JtYXQocik7DQorDQorICAgICAgICByID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsIG1zZyk7DQorICAgICAgICByLnNldFRocm93bihuZXcgRXhjZXB0aW9uKCkpOw0KKyAgICAgICAgZi5mb3JtYXQocik7DQorDQorICAgICAgICByID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsIG1zZyk7DQorICAgICAgICByLnNldFRocm93bihuZXcgRXhjZXB0aW9uKCkpOw0KKyAgICAgICAgZi5mb3JtYXQocik7DQorDQorICAgICAgICBTdHJpbmcgcmVzdWx0ID0gZi5nZXRUYWlsKChIYW5kbGVyKSBudWxsKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhyZXN1bHQsICIzIik7DQorICAgICAgICBhc3NlcnRFcXVhbHMoIjAiLCBmLmdldFRhaWwoKEhhbmRsZXIpIG51bGwpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0Tm9ybWFsKCkgew0KKyAgICAgICAgU3RyaW5nIG1zZyA9ICJtZXNzYWdlIjsNCisgICAgICAgIENvbGxlY3RvckZvcm1hdHRlciBmID0gbmV3IENvbGxlY3RvckZvcm1hdHRlcigiezZ9IiwgKEZvcm1hdHRlcikgbnVsbCwNCisgICAgICAgICAgICAgICAgKENvbXBhcmF0b3I8TG9nUmVjb3JkPikgbnVsbCk7DQorDQorICAgICAgICBhc3NlcnRFcXVhbHMoIjAiLCBmLmdldFRhaWwoKEhhbmRsZXIpIG51bGwpKTsNCisgICAgICAgIGYuZm9ybWF0KG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCBtc2cpKTsNCisgICAgICAgIGYuZm9ybWF0KG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCBtc2cpKTsNCisNCisgICAgICAgIExvZ1JlY29yZCByID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsIG1zZyk7DQorICAgICAgICByLnNldFRocm93bihuZXcgRXhjZXB0aW9uKCkpOw0KKyAgICAgICAgZi5mb3JtYXQocik7DQorDQorICAgICAgICByID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsIG1zZyk7DQorICAgICAgICByLnNldFRocm93bihuZXcgRXhjZXB0aW9uKCkpOw0KKyAgICAgICAgZi5mb3JtYXQocik7DQorDQorICAgICAgICByID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsIG1zZyk7DQorICAgICAgICByLnNldFRocm93bihuZXcgRXhjZXB0aW9uKCkpOw0KKyAgICAgICAgZi5mb3JtYXQocik7DQorDQorICAgICAgICBTdHJpbmcgcmVzdWx0ID0gZi5nZXRUYWlsKChIYW5kbGVyKSBudWxsKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhyZXN1bHQsICIyIik7DQorICAgICAgICBhc3NlcnRFcXVhbHMoIjAiLCBmLmdldFRhaWwoKEhhbmRsZXIpIG51bGwpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0TmV4dE1pbigpIHRocm93cyBFeGNlcHRpb24gew0KKyAgICAgICAgQ29sbGVjdG9yRm9ybWF0dGVyIG1pbkYgPSBuZXcgQ29sbGVjdG9yRm9ybWF0dGVyKCJ7N30iLA0KKyAgICAgICAgICAgICAgICAoRm9ybWF0dGVyKSBudWxsLA0KKyAgICAgICAgICAgICAgICAoQ29tcGFyYXRvcjxMb2dSZWNvcmQ+KSBudWxsKTsNCisNCisgICAgICAgIHRpY2tNaWxsaSgpOyAvL01ha2Ugc3VyZSB0aGUgbWF4IG5vdCBlcXVhbCB0byB0aGUgc3RhcnQgdGltZS4NCisNCisgICAgICAgIGZpbmFsIFN0cmluZyBtaW4gPSBtaW5GLmdldFRhaWwoKEhhbmRsZXIpIG51bGwpOw0KKyAgICAgICAgTnVtYmVyRm9ybWF0LmdldEludGVnZXJJbnN0YW5jZSgpLnBhcnNlKG1pbik7DQorICAgICAgICB0aWNrTWlsbGkoKTsNCisNCisgICAgICAgIC8vTmV4dCBtaW4gaXMgbm90IG9sZCBtaW4uDQorICAgICAgICBTdHJpbmcgbmV4dCA9IG1pbkYuZ2V0VGFpbCgoSGFuZGxlcikgbnVsbCk7DQorICAgICAgICBhc3NlcnRGYWxzZShtaW4gKyAnICcgKyBuZXh0LCBtaW4uZXF1YWxzKG5leHQpKTsNCisNCisgICAgICAgIC8vQWxsIG1pbnMgc3RhcnQgYXQgdGhlIGluaXQgdGltZS4NCisgICAgICAgIENvbGxlY3RvckZvcm1hdHRlciBpbml0RiA9IG5ldyBDb2xsZWN0b3JGb3JtYXR0ZXIoInsxMH0iLA0KKyAgICAgICAgICAgICAgICAoRm9ybWF0dGVyKSBudWxsLA0KKyAgICAgICAgICAgICAgICAoQ29tcGFyYXRvcjxMb2dSZWNvcmQ+KSBudWxsKTsNCisNCisgICAgICAgIG5leHQgPSBpbml0Ri5nZXRUYWlsKChIYW5kbGVyKSBudWxsKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhtaW4sIG5leHQpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRNaW5EYXRlVGltZSgpIHsNCisgICAgICAgIFN0cmluZyBtc2cgPSAibWVzc2FnZSI7DQorICAgICAgICBDb2xsZWN0b3JGb3JtYXR0ZXIgZiA9IG5ldyBDb2xsZWN0b3JGb3JtYXR0ZXIoIns3LGRhdGUsc2hvcnR9IHs3LHRpbWV9IiwNCisgICAgICAgICAgICAgICAgKEZvcm1hdHRlcikgbnVsbCwNCisgICAgICAgICAgICAgICAgKENvbXBhcmF0b3I8TG9nUmVjb3JkPikgbnVsbCk7DQorDQorICAgICAgICBsb25nIG1pbiA9IDEwMEw7DQorDQorICAgICAgICBMb2dSZWNvcmQgciA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCBtc2cpOw0KKyAgICAgICAgc2V0RXBvY2hNaWxsaShyLCBtaW4gKyAxMDAwTCk7DQorICAgICAgICBmLmZvcm1hdChyKTsNCisNCisgICAgICAgIHIgPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgbXNnKTsNCisgICAgICAgIHNldEVwb2NoTWlsbGkociwgbWluICsgMjAwMEwpOw0KKyAgICAgICAgZi5mb3JtYXQocik7DQorDQorICAgICAgICByID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsIG1zZyk7DQorICAgICAgICBzZXRFcG9jaE1pbGxpKHIsIG1pbik7DQorICAgICAgICBmLmZvcm1hdChyKTsNCisNCisgICAgICAgIHIgPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgbXNnKTsNCisgICAgICAgIHNldEVwb2NoTWlsbGkociwgbWluICsgMzAwMEwpOw0KKyAgICAgICAgZi5mb3JtYXQocik7DQorDQorICAgICAgICByID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsIG1zZyk7DQorICAgICAgICBzZXRFcG9jaE1pbGxpKHIsIG1pbiArIDQwMDBMKTsNCisgICAgICAgIGYuZm9ybWF0KHIpOw0KKw0KKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IGYuZ2V0VGFpbCgoSGFuZGxlcikgbnVsbCk7DQorICAgICAgICBhc3NlcnRFcXVhbHMocmVzdWx0LCBNZXNzYWdlRm9ybWF0LmZvcm1hdCgiezAsZGF0ZSxzaG9ydH0gezAsdGltZX0iLCBtaW4pKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0TmV4dE1heCgpIHRocm93cyBFeGNlcHRpb24gew0KKyAgICAgICAgQ29sbGVjdG9yRm9ybWF0dGVyIGYgPSBuZXcgQ29sbGVjdG9yRm9ybWF0dGVyKCJ7OH0iLCAoRm9ybWF0dGVyKSBudWxsLA0KKyAgICAgICAgICAgICAgICAoQ29tcGFyYXRvcjxMb2dSZWNvcmQ+KSBudWxsKTsNCisNCisgICAgICAgIFN0cmluZyBub3cgPSBmLmdldFRhaWwoKEhhbmRsZXIpIG51bGwpOw0KKyAgICAgICAgTnVtYmVyIG51bSA9IE51bWJlckZvcm1hdC5nZXRJbnRlZ2VySW5zdGFuY2UoKS5wYXJzZShub3cpOw0KKyAgICAgICAgYXNzZXJ0RmFsc2UoTG9uZy5NSU5fVkFMVUUgPT0gbnVtLmxvbmdWYWx1ZSgpKTsNCisgICAgICAgIHRpY2tNaWxsaSgpOw0KKyAgICAgICAgU3RyaW5nIG5leHQgPSBmLmdldFRhaWwoKEhhbmRsZXIpIG51bGwpOw0KKyAgICAgICAgYXNzZXJ0RmFsc2UoTnVtYmVyRm9ybWF0LmdldEludGVnZXJJbnN0YW5jZSgpLnBhcnNlKG5vdykubG9uZ1ZhbHVlKCkNCisgICAgICAgICAgICAgICAgPT0gTG9uZy5NSU5fVkFMVUUpOw0KKyAgICAgICAgYXNzZXJ0RmFsc2Uobm93LmVxdWFscyhuZXh0KSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEZvcm1hdE1heERhdGVUaW1lKCkgew0KKyAgICAgICAgU3RyaW5nIG1zZyA9ICJtZXNzYWdlIjsNCisgICAgICAgIENvbGxlY3RvckZvcm1hdHRlciBmID0gbmV3IENvbGxlY3RvckZvcm1hdHRlcigiezgsZGF0ZSxzaG9ydH0gezgsdGltZX0iLA0KKyAgICAgICAgICAgICAgICAoRm9ybWF0dGVyKSBudWxsLA0KKyAgICAgICAgICAgICAgICAoQ29tcGFyYXRvcjxMb2dSZWNvcmQ+KSBudWxsKTsNCisNCisgICAgICAgIGxvbmcgbWluID0gMTAwTDsNCisgICAgICAgIGxvbmcgaGlnaCA9IDQwMDBMOw0KKw0KKyAgICAgICAgTG9nUmVjb3JkIHIgPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgbXNnKTsNCisgICAgICAgIHNldEVwb2NoTWlsbGkociwgbWluICsgMTAwMEwpOw0KKyAgICAgICAgZi5mb3JtYXQocik7DQorDQorICAgICAgICByID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsIG1zZyk7DQorICAgICAgICBzZXRFcG9jaE1pbGxpKHIsIG1pbiArIGhpZ2gpOw0KKyAgICAgICAgZi5mb3JtYXQocik7DQorDQorICAgICAgICByID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsIG1zZyk7DQorICAgICAgICBzZXRFcG9jaE1pbGxpKHIsIG1pbiArIDIwMDBMKTsNCisgICAgICAgIGYuZm9ybWF0KHIpOw0KKw0KKyAgICAgICAgciA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCBtc2cpOw0KKyAgICAgICAgc2V0RXBvY2hNaWxsaShyLCBtaW4pOw0KKyAgICAgICAgZi5mb3JtYXQocik7DQorDQorICAgICAgICByID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsIG1zZyk7DQorICAgICAgICBzZXRFcG9jaE1pbGxpKHIsIG1pbiArIDMwMDBMKTsNCisgICAgICAgIGYuZm9ybWF0KHIpOw0KKw0KKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IGYuZ2V0VGFpbCgoSGFuZGxlcikgbnVsbCk7DQorICAgICAgICBhc3NlcnRFcXVhbHMocmVzdWx0LCBNZXNzYWdlRm9ybWF0LmZvcm1hdCgiezAsZGF0ZSxzaG9ydH0gezAsdGltZX0iLCBtaW4gKyBoaWdoKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEZvcm1hdFdpbmRvd1RvSW5zdGFudCgpIHRocm93cyBFeGNlcHRpb24gew0KKyAgICAgICAgQ29sbGVjdG9yRm9ybWF0dGVyIGYgPSBuZXcgQ29sbGVjdG9yRm9ybWF0dGVyKCJ7N31fezh9IiwNCisgICAgICAgICAgICAgICAgKEZvcm1hdHRlcikgbnVsbCwNCisgICAgICAgICAgICAgICAgKENvbXBhcmF0b3I8TG9nUmVjb3JkPikgbnVsbCk7DQorDQorICAgICAgICBMb2dSZWNvcmQgciA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAiIik7DQorICAgICAgICBzZXRFcG9jaE1pbGxpKHIsIDEwMCk7DQorICAgICAgICBmLmZvcm1hdChyKTsNCisNCisgICAgICAgIHIgPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgIiIpOw0KKyAgICAgICAgc2V0RXBvY2hNaWxsaShyLCAyMDApOw0KKyAgICAgICAgZi5mb3JtYXQocik7DQorDQorICAgICAgICAvL0NoZWNrIHRoYXQgdGhlIG1pbiBhbmQgbWF4IGFyZSBkaWZmZXJlbnQuDQorICAgICAgICBTdHJpbmcgb3V0cHV0ID0gZi5nZXRUYWlsKChIYW5kbGVyKSBudWxsKTsNCisgICAgICAgIGludCBmZW5jZSA9IG91dHB1dC5pbmRleE9mKCdfJyk7DQorICAgICAgICBhc3NlcnRGYWxzZShvdXRwdXQucmVnaW9uTWF0Y2hlcygwLCBvdXRwdXQsIGZlbmNlICsgMSwNCisgICAgICAgICAgICAgICAgKG91dHB1dC5sZW5ndGgoKSAtIGZlbmNlKSAtIDEpKTsNCisNCisgICAgICAgIHIgPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgIiIpOw0KKyAgICAgICAgc2V0RXBvY2hNaWxsaShyLCA0MDApOw0KKyAgICAgICAgZi5mb3JtYXQocik7DQorDQorICAgICAgICAvL1ByZXZpb3VzIG1heCBpcyAyMDAgc28gYXQgdGhpcyBwb2ludCB0aGUgbWluIGFuZCBtYXggYmV0dGVyIGJlIDQwMC4NCisgICAgICAgIG91dHB1dCA9IGYuZ2V0VGFpbCgoSGFuZGxlcikgbnVsbCk7DQorICAgICAgICBmZW5jZSA9IG91dHB1dC5pbmRleE9mKCdfJyk7DQorICAgICAgICBhc3NlcnRUcnVlKG91dHB1dC5yZWdpb25NYXRjaGVzKDAsIG91dHB1dCwgZmVuY2UgKyAxLA0KKyAgICAgICAgICAgICAgICAob3V0cHV0Lmxlbmd0aCgpIC0gZmVuY2UpIC0gMSkpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCI0MDBfNDAwIiwgb3V0cHV0KTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0VGFpbCgpIHsNCisgICAgICAgIENvbGxlY3RvckZvcm1hdHRlciBmID0gbmV3IENvbGxlY3RvckZvcm1hdHRlcigNCisgICAgICAgICAgICAgICAgInswfXsxfXsyfXszfXs0fXs1fXs2fXs3fXs4fXs5fXsxMH17MTF9ezEyfXsxM30iLA0KKyAgICAgICAgICAgICAgICAoRm9ybWF0dGVyKSBudWxsLA0KKyAgICAgICAgICAgICAgICAoQ29tcGFyYXRvcjxMb2dSZWNvcmQ+KSBudWxsKTsNCisgICAgICAgIGFzc2VydFRydWUoZi5nZXRUYWlsKChIYW5kbGVyKSBudWxsKS5sZW5ndGgoKSAhPSAwKTsNCisgICAgICAgIGFzc2VydFRydWUoZi5nZXRUYWlsKChIYW5kbGVyKSBudWxsKS5sZW5ndGgoKSAhPSAwKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0VGFpbEV4YW1wbGUxKCkgew0KKyAgICAgICAgU3RyaW5nIHAgPSAiezB9ezF9ezJ9ezQsY2hvaWNlLC0xI3wwI3wwPC4uLiB7NCxudW1iZXIsaW50ZWdlcn0gbW9yZX1cbiI7DQorICAgICAgICBDb2xsZWN0b3JGb3JtYXR0ZXIgY2YgPSBuZXcgQ29sbGVjdG9yRm9ybWF0dGVyKHApOw0KKyAgICAgICAgTG9nUmVjb3JkIHIgPSBuZXcgTG9nUmVjb3JkKExldmVsLldBUk5JTkcsICJ3YXJuaW5nIG1lc3NhZ2UiKTsNCisgICAgICAgIGNmLmZvcm1hdChyKTsNCisNCisgICAgICAgIHIgPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgIkVuY29kaW5nIGZhaWxlZC4iKTsNCisgICAgICAgIFJ1bnRpbWVFeGNlcHRpb24gbnBlID0gbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7DQorICAgICAgICBTdGFja1RyYWNlRWxlbWVudCBmcmFtZSA9IG5ldyBTdGFja1RyYWNlRWxlbWVudCgiamF2YS5sYW5nLlN0cmluZyIsDQorICAgICAgICAgICAgICAgICJnZXRCeXRlcyIsICJTdHJpbmcuamF2YSIsIDkxMyk7DQorICAgICAgICBucGUuc2V0U3RhY2tUcmFjZShuZXcgU3RhY2tUcmFjZUVsZW1lbnRbXXtmcmFtZX0pOw0KKyAgICAgICAgci5zZXRUaHJvd24obnBlKTsNCisgICAgICAgIGNmLmZvcm1hdChyKTsNCisNCisgICAgICAgIGNmLmZvcm1hdChuZXcgTG9nUmVjb3JkKExldmVsLklORk8sICJpbmZvIikpOw0KKyAgICAgICAgY2YuZm9ybWF0KG5ldyBMb2dSZWNvcmQoTGV2ZWwuSU5GTywgImluZm8iKSk7DQorICAgICAgICBTdHJpbmcgb3V0cHV0ID0gY2YuZ2V0VGFpbCgoSGFuZGxlcikgbnVsbCk7DQorICAgICAgICBhc3NlcnROb3ROdWxsKG91dHB1dCk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEdldFRhaWxFeGFtcGxlMigpIHsNCisgICAgICAgIFN0cmluZyBwID0gIlRoZXNlIHszfSBtZXNzYWdlcyBvY2N1cnJlZCBiZXR3ZWVuXG4iDQorICAgICAgICAgICAgICAgICsgIns3LGRhdGUsRUVFLCBNTU0gZGQgSEg6bW06c3M6UyBaWlogeXl5eX0gYW5kICINCisgICAgICAgICAgICAgICAgKyAiezgsdGltZSxFRUUsIE1NTSBkZCBISDptbTpzczpTIFpaWiB5eXl5fVxuIjsNCisgICAgICAgIENvbGxlY3RvckZvcm1hdHRlciBjZiA9IG5ldyBDb2xsZWN0b3JGb3JtYXR0ZXIocCk7DQorICAgICAgICBMb2dSZWNvcmQgbWluID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICIiKTsNCisgICAgICAgIHNldEVwb2NoTWlsbGkobWluLCAxMjQ4MjAzNTAyNDQ5TCk7DQorICAgICAgICBjZi5mb3JtYXQobWluKTsNCisNCisgICAgICAgIGludCBjb3VudCA9IDI5MDsNCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7ICsraSkgew0KKyAgICAgICAgICAgIExvZ1JlY29yZCBtaWQgPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgIiIpOw0KKyAgICAgICAgICAgIHNldEVwb2NoTWlsbGkobWlkLCBtaW4uZ2V0TWlsbGlzKCkpOw0KKyAgICAgICAgICAgIGNmLmZvcm1hdChtaWQpOw0KKyAgICAgICAgfQ0KKw0KKyAgICAgICAgTG9nUmVjb3JkIG1heCA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAiIik7DQorICAgICAgICBzZXRFcG9jaE1pbGxpKG1heCwgMTI1ODcyMzc2NDAwMEwpOw0KKyAgICAgICAgY2YuZm9ybWF0KG1heCk7DQorICAgICAgICBPYmplY3RbXSBhcmdzID0gbmV3IE9iamVjdFs5XTsNCisgICAgICAgIGFyZ3NbM10gPSBjb3VudCArIDJMOw0KKyAgICAgICAgYXJnc1s3XSA9IG1pbi5nZXRNaWxsaXMoKTsNCisgICAgICAgIGFyZ3NbOF0gPSBtYXguZ2V0TWlsbGlzKCk7DQorICAgICAgICBhc3NlcnRFcXVhbHMoTWVzc2FnZUZvcm1hdC5mb3JtYXQocCwgYXJncyksIGNmLnRvU3RyaW5nKCkpOw0KKyAgICAgICAgU3RyaW5nIG91dHB1dCA9IGNmLmdldFRhaWwoKEhhbmRsZXIpIG51bGwpOw0KKyAgICAgICAgYXNzZXJ0Tm90TnVsbChvdXRwdXQpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRUYWlsRXhhbXBsZTNhKCkgew0KKyAgICAgICAgU3RyaW5nIHAgPSAiVGhlc2UgezN9IG1lc3NhZ2VzIG9jY3VycmVkIGJldHdlZW5cbiINCisgICAgICAgICAgICAgICAgKyAiezcsZGF0ZSxFRUUsIE1NTSBkZCBISDptbTpzczpTIFpaWiB5eXl5fSINCisgICAgICAgICAgICAgICAgKyAiIGFuZCB7OCx0aW1lLEVFRSwgTU1NIGRkIEhIOm1tOnNzOlMgWlpaIHl5eXl9XG4iOw0KKyAgICAgICAgQ29sbGVjdG9yRm9ybWF0dGVyIGNmID0gbmV3IENvbGxlY3RvckZvcm1hdHRlcihwKTsNCisgICAgICAgIExvZ1JlY29yZCBtaW4gPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgIiIpOw0KKyAgICAgICAgc2V0RXBvY2hNaWxsaShtaW4sIDEyNDgyMDM1MDI0NDlMKTsNCisgICAgICAgIGNmLmZvcm1hdChtaW4pOw0KKw0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA3MTsgKytpKSB7DQorICAgICAgICAgICAgTG9nUmVjb3JkIG1pZCA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAiIik7DQorICAgICAgICAgICAgc2V0RXBvY2hNaWxsaShtaWQsIG1pbi5nZXRNaWxsaXMoKSk7DQorICAgICAgICAgICAgY2YuZm9ybWF0KG1pZCk7DQorICAgICAgICB9DQorDQorICAgICAgICBMb2dSZWNvcmQgbWF4ID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICIiKTsNCisgICAgICAgIHNldEVwb2NoTWlsbGkobWF4LCBtaW4uZ2V0TWlsbGlzKCkgKyAxMTA1MDApOw0KKyAgICAgICAgY2YuZm9ybWF0KG1heCk7DQorDQorICAgICAgICBTdHJpbmcgb3V0cHV0ID0gY2YuZ2V0VGFpbCgoSGFuZGxlcikgbnVsbCk7DQorICAgICAgICBhc3NlcnROb3ROdWxsKG91dHB1dCk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEdldFRhaWxFeGFtcGxlM2IoKSB7DQorICAgICAgICBTdHJpbmcgcCA9ICJUaGVzZSB7M30gbWVzc2FnZXMgb2NjdXJyZWQgYmV0d2VlbiAiDQorICAgICAgICAgICAgICAgICsgIns5LGNob2ljZSw4NjQwMDAwMCN7NyxkYXRlfSB7Nyx0aW1lfSBhbmQgezgsdGltZX0iDQorICAgICAgICAgICAgICAgICsgInw4NjQwMDAwMDx7NyxkYXRlfSBhbmQgezgsZGF0ZX19XG4iOw0KKyAgICAgICAgQ29sbGVjdG9yRm9ybWF0dGVyIGNmID0gbmV3IENvbGxlY3RvckZvcm1hdHRlcihwKTsNCisgICAgICAgIExvZ1JlY29yZCBtaW4gPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgIiIpOw0KKyAgICAgICAgc2V0RXBvY2hNaWxsaShtaW4sIDEyNDgyMDM1MDI0NDlMKTsNCisNCisgICAgICAgIGNmLmZvcm1hdChtaW4pOw0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMTQ7ICsraSkgew0KKyAgICAgICAgICAgIExvZ1JlY29yZCBtaWQgPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgIiIpOw0KKyAgICAgICAgICAgIHNldEVwb2NoTWlsbGkobWlkLCBtaW4uZ2V0TWlsbGlzKCkpOw0KKyAgICAgICAgICAgIGNmLmZvcm1hdChtaWQpOw0KKyAgICAgICAgfQ0KKw0KKyAgICAgICAgTG9nUmVjb3JkIG1heCA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAiIik7DQorICAgICAgICBzZXRFcG9jaE1pbGxpKG1heCwgbWluLmdldE1pbGxpcygpICsgMjU5MTAwMDAwMEwpOw0KKyAgICAgICAgY2YuZm9ybWF0KG1heCk7DQorDQorICAgICAgICBTdHJpbmcgb3V0cHV0ID0gY2YuZ2V0VGFpbCgoSGFuZGxlcikgbnVsbCk7DQorICAgICAgICBhc3NlcnROb3ROdWxsKG91dHB1dCk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEdldFRhaWxFeGFtcGxlNCgpIHRocm93cyBFeGNlcHRpb24gew0KKyAgICAgICAgU3RyaW5nIHAgPSAiezEzfSBhbGVydCByZXBvcnRzIHNpbmNlIHsxMCxkYXRlfS5cbiI7DQorICAgICAgICBDb2xsZWN0b3JGb3JtYXR0ZXIgY2YgPSBuZXcgQ29sbGVjdG9yRm9ybWF0dGVyKHApOw0KKw0KKyAgICAgICAgaW50IGNvdW50ID0gNDMyMDsNCisgICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDwgY291bnQ7ICsraSkgew0KKyAgICAgICAgICAgIExvZ1JlY29yZCBtaWQgPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgIiIpOw0KKyAgICAgICAgICAgIGNmLmZvcm1hdChtaWQpOw0KKyAgICAgICAgICAgIGNmLmdldFRhaWwoKEhhbmRsZXIpIG51bGwpOw0KKyAgICAgICAgfQ0KKw0KKyAgICAgICAgU3RyaW5nIG91dHB1dCA9IGNmLmdldFRhaWwoKEhhbmRsZXIpIG51bGwpOw0KKyAgICAgICAgYXNzZXJ0Tm90TnVsbChvdXRwdXQpOw0KKyAgICAgICAgU3RyaW5nIGpkNzMgPSBOdW1iZXJGb3JtYXQuZ2V0SW50ZWdlckluc3RhbmNlKCkuZm9ybWF0KGNvdW50KTsNCisgICAgICAgIGFzc2VydFRydWUob3V0cHV0LnN0YXJ0c1dpdGgoamQ3MykpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3ROZXdEZWZhdWx0Rm9ybWF0dGVyKCkgew0KKyAgICAgICAgU3RyaW5nIG1zZyA9ICIiOw0KKyAgICAgICAgQ29sbGVjdG9yRm9ybWF0dGVyIGYgPSBuZXcgQ29sbGVjdG9yRm9ybWF0dGVyKCk7DQorICAgICAgICBmLmZvcm1hdChuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgbXNnKSk7DQorICAgICAgICBmLmZvcm1hdChuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgbXNnKSk7DQorICAgICAgICBTdHJpbmcgcmVzdWx0ID0gZi5nZXRUYWlsKChIYW5kbGVyKSBudWxsKTsNCisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LCByZXN1bHQubGVuZ3RoKCkgIT0gMCk7DQorICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCwgcmVzdWx0LmNvbnRhaW5zKCIuLi4iKSk7DQorICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCwgcmVzdWx0LmNvbnRhaW5zKCIxIikpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQsIHJlc3VsdC5jb250YWlucygibW9yZSIpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0TmV3Rm9ybWF0dGVyV2l0aFN0cmluZygpIHsNCisgICAgICAgIENvbGxlY3RvckZvcm1hdHRlciBmID0gbmV3IENvbGxlY3RvckZvcm1hdHRlcigiezN9Iik7DQorICAgICAgICBmLmZvcm1hdChuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgIiIpKTsNCisgICAgICAgIFN0cmluZyByZXN1bHQgPSBmLmdldFRhaWwoKEhhbmRsZXIpIG51bGwpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdCwgIjEiKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0TmV3Rm9ybWF0dGVyTnVsbFN0cmluZygpIHsNCisgICAgICAgIENvbGxlY3RvckZvcm1hdHRlciBmID0gbmV3IENvbGxlY3RvckZvcm1hdHRlcigoU3RyaW5nKSBudWxsKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhDb2xsZWN0b3JGb3JtYXR0ZXIuY2xhc3MsIGYuZ2V0Q2xhc3MoKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdE5ld0Zvcm1hdHRlck51bGxOb25OdWxsTm9uTnVsbCgpIHsNCisgICAgICAgIENvbGxlY3RvckZvcm1hdHRlciBmID0gbmV3IENvbGxlY3RvckZvcm1hdHRlcigoU3RyaW5nKSBudWxsLA0KKyAgICAgICAgICAgICAgICBuZXcgWE1MRm9ybWF0dGVyKCksIFNldmVyaXR5Q29tcGFyYXRvci5nZXRJbnN0YW5jZSgpKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhDb2xsZWN0b3JGb3JtYXR0ZXIuY2xhc3MsIGYuZ2V0Q2xhc3MoKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdE5ld0Zvcm1hdHRlck51bGxOdWxsTnVsbCgpIHsNCisgICAgICAgIENvbGxlY3RvckZvcm1hdHRlciBmID0gbmV3IENvbGxlY3RvckZvcm1hdHRlcigoU3RyaW5nKSBudWxsLA0KKyAgICAgICAgICAgICAgICAoRm9ybWF0dGVyKSBudWxsLCAoQ29tcGFyYXRvcjxMb2dSZWNvcmQ+KSBudWxsKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhDb2xsZWN0b3JGb3JtYXR0ZXIuY2xhc3MsIGYuZ2V0Q2xhc3MoKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdE5ld0Zvcm1hdHRlck5vbk51bGxOdWxsTnVsbCgpIHsNCisgICAgICAgIENvbGxlY3RvckZvcm1hdHRlciBmID0gbmV3IENvbGxlY3RvckZvcm1hdHRlcigiVGVzdCB7MH0iLA0KKyAgICAgICAgICAgICAgICAoRm9ybWF0dGVyKSBudWxsLCAoQ29tcGFyYXRvcjxMb2dSZWNvcmQ+KSBudWxsKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhDb2xsZWN0b3JGb3JtYXR0ZXIuY2xhc3MsIGYuZ2V0Q2xhc3MoKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdFRvU3RyaW5nKCkgew0KKyAgICAgICAgU3RyaW5nIG1zZyA9ICJtZXNzYWdlIjsNCisgICAgICAgIENvbGxlY3RvckZvcm1hdHRlciBmID0gbmV3IENvbGxlY3RvckZvcm1hdHRlcigiezN9IiwgKEZvcm1hdHRlcikgbnVsbCwNCisgICAgICAgICAgICAgICAgKENvbXBhcmF0b3I8TG9nUmVjb3JkPikgbnVsbCk7DQorDQorICAgICAgICBmLmZvcm1hdChuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgbXNnKSk7DQorICAgICAgICBmLmZvcm1hdChuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgbXNnKSk7DQorICAgICAgICBmLmZvcm1hdChuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgbXNnKSk7DQorICAgICAgICBmLmZvcm1hdChuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgbXNnKSk7DQorDQorICAgICAgICBTdHJpbmcgcmVzdWx0ID0gZi50b1N0cmluZygpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdCwgZi50b1N0cmluZygpKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhyZXN1bHQsIGYuZ2V0VGFpbCgoSGFuZGxlcikgbnVsbCkpOw0KKyAgICAgICAgYXNzZXJ0RmFsc2UocmVzdWx0LmVxdWFscyhmLnRvU3RyaW5nKCkpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdChleHBlY3RlZCA9IE51bGxQb2ludGVyRXhjZXB0aW9uLmNsYXNzKQ0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0QXBwbHlOdWxsQW5kTnVsbCgpIHsNCisgICAgICAgIENvbGxlY3RvckZvcm1hdHRlciBmID0gbmV3IENvbGxlY3RvckZvcm1hdHRlcigiezN9IiwgKEZvcm1hdHRlcikgbnVsbCwNCisgICAgICAgICAgICAgICAgKENvbXBhcmF0b3I8TG9nUmVjb3JkPikgbnVsbCk7DQorICAgICAgICBmLmFwcGx5KChMb2dSZWNvcmQpIG51bGwsIChMb2dSZWNvcmQpIG51bGwpOw0KKyAgICB9DQorDQorICAgIEBUZXN0KGV4cGVjdGVkID0gTnVsbFBvaW50ZXJFeGNlcHRpb24uY2xhc3MpDQorICAgIHB1YmxpYyB2b2lkIHRlc3RBcHBseU51bGxBbmRMb2dSZWNvcmQoKSB7DQorICAgICAgICBDb2xsZWN0b3JGb3JtYXR0ZXIgZiA9IG5ldyBDb2xsZWN0b3JGb3JtYXR0ZXIoInszfSIsIChGb3JtYXR0ZXIpIG51bGwsDQorICAgICAgICAgICAgICAgIChDb21wYXJhdG9yPExvZ1JlY29yZD4pIG51bGwpOw0KKyAgICAgICAgZi5hcHBseSgoTG9nUmVjb3JkKSBudWxsLCBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgIiIpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdChleHBlY3RlZCA9IE51bGxQb2ludGVyRXhjZXB0aW9uLmNsYXNzKQ0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0QXBwbHlMb2dSZWNvcmRBbmROdWxsKCkgew0KKyAgICAgICAgQ29sbGVjdG9yRm9ybWF0dGVyIGYgPSBuZXcgQ29sbGVjdG9yRm9ybWF0dGVyKCJ7M30iLCAoRm9ybWF0dGVyKSBudWxsLA0KKyAgICAgICAgICAgICAgICAoQ29tcGFyYXRvcjxMb2dSZWNvcmQ+KSBudWxsKTsNCisgICAgICAgIGYuYXBwbHkobmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICIiKSwgKExvZ1JlY29yZCkgbnVsbCk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEFwcGx5V2l0aG91dENvbXBhcmF0b3IoKSB7DQorICAgICAgICBDb2xsZWN0b3JGb3JtYXR0ZXIgZiA9IG5ldyBDb2xsZWN0b3JGb3JtYXR0ZXIoInszfSIsIChGb3JtYXR0ZXIpIG51bGwsDQorICAgICAgICAgICAgICAgIChDb21wYXJhdG9yPExvZ1JlY29yZD4pIG51bGwpOw0KKyAgICAgICAgTG9nUmVjb3JkIGZpcnN0ID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICIiKTsNCisgICAgICAgIExvZ1JlY29yZCBzZWNvbmQgPSBuZXcgTG9nUmVjb3JkKExldmVsLldBUk5JTkcsICIiKTsNCisgICAgICAgIGFzc2VydFNhbWUoc2Vjb25kLCBmLmFwcGx5KGZpcnN0LCBzZWNvbmQpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0QXBwbHlXaXRoQ29tcGFyYXRvcigpIHsNCisgICAgICAgIENvbGxlY3RvckZvcm1hdHRlciBmID0gbmV3IENvbGxlY3RvckZvcm1hdHRlcigiezN9IiwgKEZvcm1hdHRlcikgbnVsbCwNCisgICAgICAgICAgICAgICAgU2V2ZXJpdHlDb21wYXJhdG9yLmdldEluc3RhbmNlKCkpOw0KKyAgICAgICAgTG9nUmVjb3JkIGZpcnN0ID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICIiKTsNCisgICAgICAgIExvZ1JlY29yZCBzZWNvbmQgPSBuZXcgTG9nUmVjb3JkKExldmVsLldBUk5JTkcsICIiKTsNCisgICAgICAgIGFzc2VydFNhbWUoZmlyc3QsIGYuYXBwbHkoZmlyc3QsIHNlY29uZCkpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RDb21wYXJhdG9yKCkgdGhyb3dzIEV4Y2VwdGlvbiB7DQorICAgICAgICBmaW5hbCBTdHJpbmcgcCA9IENvbGxlY3RvckZvcm1hdHRlci5jbGFzcy5nZXROYW1lKCk7DQorICAgICAgICBQcm9wZXJ0aWVzIHByb3BzID0gbmV3IFByb3BlcnRpZXMoKTsNCisgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLmNvbXBhcmF0b3IiKSwgU2V2ZXJpdHlDb21wYXJhdG9yLmNsYXNzLmdldE5hbWUoKSk7DQorICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5jb21wYXJhdG9yLnJldmVyc2UiKSwgImZhbHNlIik7DQorICAgICAgICBMb2dNYW5hZ2VyIG1hbmFnZXIgPSBMb2dNYW5hZ2VyLmdldExvZ01hbmFnZXIoKTsNCisgICAgICAgIHRyeSB7DQorICAgICAgICAgICAgcmVhZChtYW5hZ2VyLCBwcm9wcyk7DQorICAgICAgICAgICAgQ29sbGVjdG9yRm9ybWF0dGVyIGNmID0gbmV3IENvbGxlY3RvckZvcm1hdHRlcigpOw0KKyAgICAgICAgICAgIExvZ1JlY29yZCBmaXJzdCA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCBMZXZlbC5TRVZFUkUuZ2V0TmFtZSgpKTsNCisgICAgICAgICAgICBMb2dSZWNvcmQgc2Vjb25kID0gbmV3IExvZ1JlY29yZChMZXZlbC5XQVJOSU5HLCBMZXZlbC5XQVJOSU5HLmdldE5hbWUoKSk7DQorICAgICAgICAgICAgY2YuZm9ybWF0KHNlY29uZCk7DQorICAgICAgICAgICAgY2YuZm9ybWF0KGZpcnN0KTsNCisgICAgICAgICAgICBTdHJpbmcgcmVzdWx0ID0gY2YuZ2V0VGFpbCgoSGFuZGxlcikgbnVsbCk7DQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQsIHJlc3VsdC5zdGFydHNXaXRoKExldmVsLlNFVkVSRS5nZXROYW1lKCkpKTsNCisgICAgICAgIH0gZmluYWxseSB7DQorICAgICAgICAgICAgbWFuYWdlci5yZXNldCgpOw0KKyAgICAgICAgfQ0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RDb21wYXJhdG9yUmV2ZXJzZSgpIHRocm93cyBFeGNlcHRpb24gew0KKyAgICAgICAgZmluYWwgU3RyaW5nIHAgPSBDb2xsZWN0b3JGb3JtYXR0ZXIuY2xhc3MuZ2V0TmFtZSgpOw0KKyAgICAgICAgUHJvcGVydGllcyBwcm9wcyA9IG5ldyBQcm9wZXJ0aWVzKCk7DQorICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5jb21wYXJhdG9yIiksIFNldmVyaXR5Q29tcGFyYXRvci5jbGFzcy5nZXROYW1lKCkpOw0KKyAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIuY29tcGFyYXRvci5yZXZlcnNlIiksICJ0cnVlIik7DQorICAgICAgICBMb2dNYW5hZ2VyIG1hbmFnZXIgPSBMb2dNYW5hZ2VyLmdldExvZ01hbmFnZXIoKTsNCisgICAgICAgIHRyeSB7DQorICAgICAgICAgICAgcmVhZChtYW5hZ2VyLCBwcm9wcyk7DQorICAgICAgICAgICAgQ29sbGVjdG9yRm9ybWF0dGVyIGNmID0gbmV3IENvbGxlY3RvckZvcm1hdHRlcigpOw0KKyAgICAgICAgICAgIExvZ1JlY29yZCBmaXJzdCA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCBMZXZlbC5TRVZFUkUuZ2V0TmFtZSgpKTsNCisgICAgICAgICAgICBMb2dSZWNvcmQgc2Vjb25kID0gbmV3IExvZ1JlY29yZChMZXZlbC5XQVJOSU5HLCBMZXZlbC5XQVJOSU5HLmdldE5hbWUoKSk7DQorICAgICAgICAgICAgY2YuZm9ybWF0KHNlY29uZCk7DQorICAgICAgICAgICAgY2YuZm9ybWF0KGZpcnN0KTsNCisgICAgICAgICAgICBTdHJpbmcgcmVzdWx0ID0gY2YuZ2V0VGFpbCgoSGFuZGxlcikgbnVsbCk7DQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQsIHJlc3VsdC5zdGFydHNXaXRoKExldmVsLldBUk5JTkcuZ2V0TmFtZSgpKSk7DQorICAgICAgICB9IGZpbmFsbHkgew0KKyAgICAgICAgICAgIG1hbmFnZXIucmVzZXQoKTsNCisgICAgICAgIH0NCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7DQorICAgICAgICBmaW5hbCBTdHJpbmcgcCA9IENvbGxlY3RvckZvcm1hdHRlci5jbGFzcy5nZXROYW1lKCk7DQorICAgICAgICBQcm9wZXJ0aWVzIHByb3BzID0gbmV3IFByb3BlcnRpZXMoKTsNCisgICAgICAgIGZpbmFsIFN0cmluZyBleHBlY3QgPSBDb2xsZWN0b3JGb3JtYXR0ZXJUZXN0LmNsYXNzLmdldE5hbWUoKTsNCisgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLmZvcm1hdCIpLCBleHBlY3QpOw0KKyAgICAgICAgTG9nTWFuYWdlciBtYW5hZ2VyID0gTG9nTWFuYWdlci5nZXRMb2dNYW5hZ2VyKCk7DQorICAgICAgICB0cnkgew0KKyAgICAgICAgICAgIHJlYWQobWFuYWdlciwgcHJvcHMpOw0KKyAgICAgICAgICAgIENvbGxlY3RvckZvcm1hdHRlciBjZiA9IG5ldyBDb2xsZWN0b3JGb3JtYXR0ZXIoKTsNCisgICAgICAgICAgICBMb2dSZWNvcmQgZmlyc3QgPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgTGV2ZWwuU0VWRVJFLmdldE5hbWUoKSk7DQorICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBjZi5mb3JtYXQoZmlyc3QpKTsNCisgICAgICAgICAgICBTdHJpbmcgcmVzdWx0ID0gY2YuZ2V0VGFpbCgoSGFuZGxlcikgbnVsbCk7DQorICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdCwgcmVzdWx0KTsNCisgICAgICAgIH0gZmluYWxseSB7DQorICAgICAgICAgICAgbWFuYWdlci5yZXNldCgpOw0KKyAgICAgICAgfQ0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXR0ZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsNCisgICAgICAgIGZpbmFsIFN0cmluZyBwID0gQ29sbGVjdG9yRm9ybWF0dGVyLmNsYXNzLmdldE5hbWUoKTsNCisgICAgICAgIFByb3BlcnRpZXMgcHJvcHMgPSBuZXcgUHJvcGVydGllcygpOw0KKyAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIuZm9ybWF0dGVyIiksIFhNTEZvcm1hdHRlci5jbGFzcy5nZXROYW1lKCkpOw0KKyAgICAgICAgTG9nTWFuYWdlciBtYW5hZ2VyID0gTG9nTWFuYWdlci5nZXRMb2dNYW5hZ2VyKCk7DQorICAgICAgICB0cnkgew0KKyAgICAgICAgICAgIHJlYWQobWFuYWdlciwgcHJvcHMpOw0KKyAgICAgICAgICAgIFhNTEZvcm1hdHRlciB4bWwgPSBuZXcgWE1MRm9ybWF0dGVyKCk7DQorICAgICAgICAgICAgQ29sbGVjdG9yRm9ybWF0dGVyIGNmID0gbmV3IENvbGxlY3RvckZvcm1hdHRlcigpOw0KKyAgICAgICAgICAgIExvZ1JlY29yZCBmaXJzdCA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCBMZXZlbC5TRVZFUkUuZ2V0TmFtZSgpKTsNCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIGNmLmZvcm1hdChmaXJzdCkpOw0KKyAgICAgICAgICAgIFN0cmluZyByZXN1bHQgPSBjZi5nZXRUYWlsKChIYW5kbGVyKSBudWxsKTsNCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMocmVzdWx0LCBjZi5maW5pc2goeG1sLmdldEhlYWQoKEhhbmRsZXIpIG51bGwpKQ0KKyAgICAgICAgICAgICAgICAgICAgKyBjZi5maW5pc2goeG1sLmZvcm1hdChmaXJzdCkpDQorICAgICAgICAgICAgICAgICAgICArIGNmLmZpbmlzaCh4bWwuZ2V0VGFpbCgoSGFuZGxlcikgbnVsbCkpICsgJ1xuJyk7DQorICAgICAgICB9IGZpbmFsbHkgew0KKyAgICAgICAgICAgIG1hbmFnZXIucmVzZXQoKTsNCisgICAgICAgIH0NCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0RWxhcHNlZFRpbWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsNCisgICAgICAgIENvbGxlY3RvckZvcm1hdHRlciBmID0gbmV3IENvbGxlY3RvckZvcm1hdHRlcigiezl9IiwgKEZvcm1hdHRlcikgbnVsbCwNCisgICAgICAgICAgICAgICAgKENvbXBhcmF0b3I8TG9nUmVjb3JkPikgbnVsbCk7DQorICAgICAgICBMb2dSZWNvcmQgciA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAiIik7DQorICAgICAgICBzZXRFcG9jaE1pbGxpKHIsIDI1TCk7DQorICAgICAgICBmLmZvcm1hdChyKTsNCisNCisgICAgICAgIHIgPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgIiIpOw0KKyAgICAgICAgc2V0RXBvY2hNaWxsaShyLCAxMDBMKTsNCisgICAgICAgIGYuZm9ybWF0KHIpOw0KKw0KKyAgICAgICAgU3RyaW5nIGluaXQgPSBmLmdldFRhaWwoKEhhbmRsZXIpIG51bGwpOw0KKyAgICAgICAgTnVtYmVyIG4gPSBOdW1iZXJGb3JtYXQuZ2V0SW50ZWdlckluc3RhbmNlKCkucGFyc2UoaW5pdCk7DQorICAgICAgICBhc3NlcnRFcXVhbHMoNzUsIG4ubG9uZ1ZhbHVlKCkpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRJbml0VGltZU1pbGxpcygpIHRocm93cyBFeGNlcHRpb24gew0KKyAgICAgICAgQ29sbGVjdG9yRm9ybWF0dGVyIGYgPSBuZXcgQ29sbGVjdG9yRm9ybWF0dGVyKCJ7MTB9IiwgKEZvcm1hdHRlcikgbnVsbCwNCisgICAgICAgICAgICAgICAgKENvbXBhcmF0b3I8TG9nUmVjb3JkPikgbnVsbCk7DQorDQorICAgICAgICBTdHJpbmcgaW5pdCA9IGYuZ2V0VGFpbCgoSGFuZGxlcikgbnVsbCk7DQorICAgICAgICBOdW1iZXJGb3JtYXQuZ2V0SW50ZWdlckluc3RhbmNlKCkucGFyc2UoaW5pdCk7DQorICAgICAgICB0aWNrTWlsbGkoKTsNCisNCisgICAgICAgIGFzc2VydFRydWUoaW5pdC5lcXVhbHMoZi5nZXRUYWlsKChIYW5kbGVyKSBudWxsKSkpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRJbml0VGltZURhdGVUaW1lKCkgdGhyb3dzIEV4Y2VwdGlvbiB7DQorICAgICAgICBDb2xsZWN0b3JGb3JtYXR0ZXIgZiA9IG5ldyBDb2xsZWN0b3JGb3JtYXR0ZXIoDQorICAgICAgICAgICAgICAgICJ7MTAsZGF0ZSwiICsgREFURV9USU1FX0ZNVCArICJ9IiwNCisgICAgICAgICAgICAgICAgKEZvcm1hdHRlcikgbnVsbCwNCisgICAgICAgICAgICAgICAgKENvbXBhcmF0b3I8TG9nUmVjb3JkPikgbnVsbCk7DQorDQorICAgICAgICBTdHJpbmcgaW5pdCA9IGYuZ2V0VGFpbCgoSGFuZGxlcikgbnVsbCk7DQorICAgICAgICBEYXRlRm9ybWF0IGRmID0gbmV3IFNpbXBsZURhdGVGb3JtYXQoREFURV9USU1FX0ZNVCk7DQorICAgICAgICBEYXRlIGR0ID0gZGYucGFyc2UoaW5pdCk7DQorICAgICAgICB0aWNrTWlsbGkoKTsNCisNCisgICAgICAgIGFzc2VydFRydWUoaW5pdC5lcXVhbHMoZi5nZXRUYWlsKChIYW5kbGVyKSBudWxsKSkpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShkdC5lcXVhbHMoZGYucGFyc2UoZi5nZXRUYWlsKChIYW5kbGVyKSBudWxsKSkpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0Q3VycmVudFRpbWVNaWxsaXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsNCisgICAgICAgIENvbGxlY3RvckZvcm1hdHRlciBmID0gbmV3IENvbGxlY3RvckZvcm1hdHRlcigiezExfSIsIChGb3JtYXR0ZXIpIG51bGwsDQorICAgICAgICAgICAgICAgIChDb21wYXJhdG9yPExvZ1JlY29yZD4pIG51bGwpOw0KKw0KKyAgICAgICAgU3RyaW5nIG5vdyA9IGYuZ2V0VGFpbCgoSGFuZGxlcikgbnVsbCk7DQorICAgICAgICBOdW1iZXJGb3JtYXQuZ2V0SW50ZWdlckluc3RhbmNlKCkucGFyc2Uobm93KTsNCisgICAgICAgIHRpY2tNaWxsaSgpOw0KKw0KKyAgICAgICAgYXNzZXJ0RmFsc2Uobm93LmVxdWFscyhmLmdldFRhaWwoKEhhbmRsZXIpIG51bGwpKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEZvcm1hdEN1cnJlbnRUaW1lRGF0ZVRpbWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsNCisgICAgICAgIENvbGxlY3RvckZvcm1hdHRlciBmID0gbmV3IENvbGxlY3RvckZvcm1hdHRlcigNCisgICAgICAgICAgICAgICAgInsxMSxkYXRlLCIgKyBEQVRFX1RJTUVfRk1UICsgIn0iLA0KKyAgICAgICAgICAgICAgICAoRm9ybWF0dGVyKSBudWxsLA0KKyAgICAgICAgICAgICAgICAoQ29tcGFyYXRvcjxMb2dSZWNvcmQ+KSBudWxsKTsNCisNCisgICAgICAgIFN0cmluZyBpbml0ID0gZi5nZXRUYWlsKChIYW5kbGVyKSBudWxsKTsNCisgICAgICAgIERhdGVGb3JtYXQgZGYgPSBuZXcgU2ltcGxlRGF0ZUZvcm1hdChEQVRFX1RJTUVfRk1UKTsNCisgICAgICAgIERhdGUgZHQgPSBkZi5wYXJzZShpbml0KTsNCisgICAgICAgIHRpY2tNaWxsaSgpOw0KKw0KKyAgICAgICAgYXNzZXJ0RmFsc2UoaW5pdC5lcXVhbHMoZi5nZXRUYWlsKChIYW5kbGVyKSBudWxsKSkpOw0KKyAgICAgICAgYXNzZXJ0RmFsc2UoZHQuZXF1YWxzKGRmLnBhcnNlKGYuZ2V0VGFpbCgoSGFuZGxlcikgbnVsbCkpKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEZvcm1hdFVwVGltZSgpIHRocm93cyBFeGNlcHRpb24gew0KKyAgICAgICAgQ29sbGVjdG9yRm9ybWF0dGVyIGYgPSBuZXcgQ29sbGVjdG9yRm9ybWF0dGVyKCJ7MTJ9IiwgKEZvcm1hdHRlcikgbnVsbCwNCisgICAgICAgICAgICAgICAgKENvbXBhcmF0b3I8TG9nUmVjb3JkPikgbnVsbCk7DQorDQorICAgICAgICBTdHJpbmcgdXAgPSBmLmdldFRhaWwoKEhhbmRsZXIpIG51bGwpOw0KKyAgICAgICAgTnVtYmVyRm9ybWF0LmdldEludGVnZXJJbnN0YW5jZSgpLnBhcnNlKHVwKTsNCisgICAgICAgIHRpY2tNaWxsaSgpOw0KKw0KKyAgICAgICAgYXNzZXJ0RmFsc2UodXAuZXF1YWxzKGYuZ2V0VGFpbCgoSGFuZGxlcikgbnVsbCkpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0R2VuZXJhdGlvbigpIHsNCisgICAgICAgIFN0cmluZyBtc2cgPSAibWVzc2FnZSI7DQorICAgICAgICBDb2xsZWN0b3JGb3JtYXR0ZXIgZiA9IG5ldyBDb2xsZWN0b3JGb3JtYXR0ZXIoInsxM30iLCAoRm9ybWF0dGVyKSBudWxsLA0KKyAgICAgICAgICAgICAgICAoQ29tcGFyYXRvcjxMb2dSZWNvcmQ+KSBudWxsKTsNCisNCisgICAgICAgIGFzc2VydEVxdWFscygiMSIsIGYuZ2V0VGFpbCgoSGFuZGxlcikgbnVsbCkpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxIiwgZi50b1N0cmluZygpKTsNCisgICAgICAgIGFzc2VydEVxdWFscygiMSIsIGYuZ2V0VGFpbCgoSGFuZGxlcikgbnVsbCkpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIxIiwgZi50b1N0cmluZygpKTsNCisNCisgICAgICAgIGYuZm9ybWF0KG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCBtc2cpKTsNCisgICAgICAgIGYuZm9ybWF0KG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCBtc2cpKTsNCisgICAgICAgIGYuZm9ybWF0KG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCBtc2cpKTsNCisgICAgICAgIGYuZm9ybWF0KG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCBtc2cpKTsNCisNCisgICAgICAgIGFzc2VydEVxdWFscygiMSIsIGYuZ2V0VGFpbCgoSGFuZGxlcikgbnVsbCkpOyAvL3Jlc2V0DQorDQorICAgICAgICBhc3NlcnRFcXVhbHMoIjIiLCBmLmdldFRhaWwoKEhhbmRsZXIpIG51bGwpKTsNCisgICAgICAgIGFzc2VydEVxdWFscygiMiIsIGYudG9TdHJpbmcoKSk7DQorICAgICAgICBhc3NlcnRFcXVhbHMoIjIiLCBmLmdldFRhaWwoKEhhbmRsZXIpIG51bGwpKTsNCisgICAgICAgIGFzc2VydEVxdWFscygiMiIsIGYudG9TdHJpbmcoKSk7DQorDQorICAgICAgICBmLmZvcm1hdChuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgbXNnKSk7DQorICAgICAgICBmLmZvcm1hdChuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgbXNnKSk7DQorICAgICAgICBmLmZvcm1hdChuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgbXNnKSk7DQorICAgICAgICBmLmZvcm1hdChuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgbXNnKSk7DQorDQorICAgICAgICBhc3NlcnRFcXVhbHMoIjIiLCBmLmdldFRhaWwoKEhhbmRsZXIpIG51bGwpKTsgLy9yZXNldA0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIzIiwgZi5nZXRUYWlsKChIYW5kbGVyKSBudWxsKSk7DQorICAgICAgICBhc3NlcnRFcXVhbHMoIjMiLCBmLnRvU3RyaW5nKCkpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIzIiwgZi50b1N0cmluZygpKTsNCisgICAgICAgIGFzc2VydEVxdWFscygiMyIsIGYuZ2V0VGFpbCgoSGFuZGxlcikgbnVsbCkpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXROdWxsRm9ybWF0dGVyKCkgew0KKyAgICAgICAgQ29sbGVjdG9yRm9ybWF0dGVyIGYgPSBuZXcgQ29sbGVjdG9yRm9ybWF0dGVyKCJ7MX0iLCAoRm9ybWF0dGVyKSBudWxsLA0KKyAgICAgICAgICAgICAgICAoQ29tcGFyYXRvcjxMb2dSZWNvcmQ+KSBudWxsKTsNCisgICAgICAgIExvZ1JlY29yZCByID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICJtZXNzYWdlIHswfSIpOw0KKyAgICAgICAgci5zZXRQYXJhbWV0ZXJzKG5ldyBPYmplY3RbXXsxfSk7DQorICAgICAgICBmLmZvcm1hdChyKTsNCisgICAgICAgIFN0cmluZyBvdXRwdXQgPSBmLmdldFRhaWwoKEhhbmRsZXIpIG51bGwpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKGYuZm9ybWF0TWVzc2FnZShyKSwgb3V0cHV0KTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0SWxsZWdhbFBhdHRlcm4oKSB7DQorICAgICAgICBDb2xsZWN0b3JGb3JtYXR0ZXIgZiA9IG5ldyBDb2xsZWN0b3JGb3JtYXR0ZXIoIns5Iik7DQorICAgICAgICBmLmZvcm1hdChuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgIiIpKTsNCisgICAgICAgIHRyeSB7DQorICAgICAgICAgICAgZi5nZXRUYWlsKChIYW5kbGVyKSBudWxsKTsNCisgICAgICAgICAgICBmYWlsKCJFeHBlY3RlZCBmb3JtYXQgZXhjZXB0aW9uLiIpOw0KKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4cGVjdCkgew0KKyAgICAgICAgfQ0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRJbGxlZ2FsVGFyZ2V0UGF0dGVybigpIHsNCisgICAgICAgIENvbGxlY3RvckZvcm1hdHRlciBmID0gbmV3IENvbGxlY3RvckZvcm1hdHRlcigiezF9IiwNCisgICAgICAgICAgICAgICAgbmV3IENvbXBhY3RGb3JtYXR0ZXIoIiUxJCN0YyIpLCAoQ29tcGFyYXRvcjxMb2dSZWNvcmQ+KSBudWxsKTsNCisgICAgICAgIGYuZm9ybWF0KG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAiIikpOw0KKyAgICAgICAgdHJ5IHsNCisgICAgICAgICAgICBmLmdldFRhaWwoKEhhbmRsZXIpIG51bGwpOw0KKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIGZvcm1hdCBleGNlcHRpb24uIik7DQorICAgICAgICB9IGNhdGNoIChqYXZhLnV0aWwuSWxsZWdhbEZvcm1hdEV4Y2VwdGlvbiBleHBlY3QpIHsNCisgICAgICAgIH0NCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SmF2YU1haWxMaW5rYWdlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7DQorICAgICAgICB0ZXN0SmF2YU1haWxMaW5rYWdlKENvbGxlY3RvckZvcm1hdHRlci5jbGFzcyk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdExvZ01hbmFnZXJNb2RpZmllcnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsNCisgICAgICAgIHRlc3RMb2dNYW5hZ2VyTW9kaWZpZXJzKENvbGxlY3RvckZvcm1hdHRlci5jbGFzcyk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdFdlYmFwcENsYXNzTG9hZGVyRmllbGROYW1lcygpIHRocm93cyBFeGNlcHRpb24gew0KKyAgICAgICAgdGVzdFdlYmFwcENsYXNzTG9hZGVyRmllbGROYW1lcyhDb2xsZWN0b3JGb3JtYXR0ZXIuY2xhc3MpOw0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBBbiBleGFtcGxlIG9mIGEgYnJva2VuIGltcGxlbWVudGF0aW9uIG9mIGFwcGx5Lg0KKyAgICAgKi8NCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgQXBwbHlSZXR1cm5zTnVsbCBleHRlbmRzIENvbGxlY3RvckZvcm1hdHRlciB7DQorDQorICAgICAgICAvKioNCisgICAgICAgICAqIFRoZSBudW1iZXIgb2YgcmVjb3Jkcy4NCisgICAgICAgICAqLw0KKyAgICAgICAgcHJpdmF0ZSBpbnQgY291bnQ7DQorDQorICAgICAgICAvKioNCisgICAgICAgICAqIFByb21vdGUgYWNjZXNzIGxldmVsLg0KKyAgICAgICAgICovDQorICAgICAgICBBcHBseVJldHVybnNOdWxsKCkgew0KKyAgICAgICAgfQ0KKw0KKyAgICAgICAgQE92ZXJyaWRlDQorICAgICAgICBwcm90ZWN0ZWQgTG9nUmVjb3JkIGFwcGx5KExvZ1JlY29yZCB0LCBMb2dSZWNvcmQgdSkgew0KKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwodCk7DQorICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCh1KTsNCisgICAgICAgICAgICByZXR1cm4gKCsrY291bnQgJiAxKSA9PSAxID8gdSA6IG51bGw7DQorICAgICAgICB9DQorICAgIH0NCisNCisgICAgLyoqDQorICAgICAqIEEgcHJvcGVydGllcyByZXNvdXJjZSBidW5kbGUgd2l0aCBsb2NhbGUuDQorICAgICAqLw0KKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBMb2NhbGVSZXNvdXJjZSBleHRlbmRzIFByb3BlcnR5UmVzb3VyY2VCdW5kbGUgew0KKw0KKyAgICAgICAgLyoqDQorICAgICAgICAgKiBUaGUgbG9jYWxlDQorICAgICAgICAgKi8NCisgICAgICAgIHByaXZhdGUgZmluYWwgTG9jYWxlIGxvY2FsZTsNCisNCisgICAgICAgIC8qKg0KKyAgICAgICAgICogQ3JlYXRlcyB0aGUgbG9jYWxlIHJlc291cmNlLg0KKyAgICAgICAgICoNCisgICAgICAgICAqIEBwYXJhbSBwIHRoZSBwcm9wZXJ0aWVzLg0KKyAgICAgICAgICogQHBhcmFtIGwgdGhlIGxvY2FsZS4NCisgICAgICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgdGhlcmUgaXMgYSBwcm9ibGVtLg0KKyAgICAgICAgICovDQorICAgICAgICBMb2NhbGVSZXNvdXJjZShQcm9wZXJ0aWVzIHAsIExvY2FsZSBsKSB0aHJvd3MgSU9FeGNlcHRpb24gew0KKyAgICAgICAgICAgIHN1cGVyKHRvU3RyZWFtKHApKTsNCisgICAgICAgICAgICBsb2NhbGUgPSBsOw0KKyAgICAgICAgfQ0KKw0KKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgSW5wdXRTdHJlYW0gdG9TdHJlYW0oUHJvcGVydGllcyBwKSB0aHJvd3MgSU9FeGNlcHRpb24gew0KKyAgICAgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBvdXQgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7DQorICAgICAgICAgICAgcC5zdG9yZShvdXQsIExvY2FsZVJlc291cmNlLmNsYXNzLmdldE5hbWUoKSk7DQorICAgICAgICAgICAgcmV0dXJuIG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShvdXQudG9CeXRlQXJyYXkoKSk7DQorICAgICAgICB9DQorDQorICAgICAgICBAT3ZlcnJpZGUNCisgICAgICAgIHB1YmxpYyBMb2NhbGUgZ2V0TG9jYWxlKCkgew0KKyAgICAgICAgICAgIHJldHVybiBsb2NhbGU7DQorICAgICAgICB9DQorICAgIH0NCit9DQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL2xvZ2dpbmcvQ29tcGFjdEZvcm1hdHRlclRlc3QuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvdXRpbC9sb2dnaW5nL0NvbXBhY3RGb3JtYXR0ZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzc5ZmU3ZQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvdXRpbC9sb2dnaW5nL0NvbXBhY3RGb3JtYXR0ZXJUZXN0LmphdmEKQEAgLTAsMCArMSwxNjgwIEBACisvKg0KKyAqIENvcHlyaWdodCAoYykgMjAxMywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KKyAqIENvcHlyaWdodCAoYykgMjAxMywgMjAxOCBKYXNvbiBNZWhyZW5zLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KKyAqDQorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlDQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQNCisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuDQorICoNCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5DQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQ0KKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLA0KKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0DQorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLg0KKyAqDQorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wDQorICovDQorcGFja2FnZSBjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nOw0KKw0KK2ltcG9ydCBqYXZhLmlvLio7DQoraW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZDsNCitpbXBvcnQgamF2YS5uZXQuU29ja2V0RXhjZXB0aW9uOw0KK2ltcG9ydCBqYXZhLnV0aWwuKjsNCitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTGV2ZWw7DQoraW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkxvZ01hbmFnZXI7DQoraW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkxvZ1JlY29yZDsNCitpbXBvcnQgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb247DQoraW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuTWltZVV0aWxpdHk7DQoraW1wb3J0IG9yZy5qdW5pdC4qOw0KK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC4qOw0KKw0KKy8qKg0KKyAqIENvbXBhY3QgZm9ybWF0dGVyIHRlc3RzLg0KKyAqDQorICogQGF1dGhvciBKYXNvbiBNZWhyZW5zDQorICogQHNpbmNlIEphdmFNYWlsIDEuNS4yDQorICovDQorcHVibGljIGNsYXNzIENvbXBhY3RGb3JtYXR0ZXJUZXN0IGV4dGVuZHMgQWJzdHJhY3RMb2dnaW5nIHsNCisNCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFVOS05PV05fQ0xBU1NfTkFNRQ0KKyAgICAgICAgICAgID0gQ29tcGFjdEZvcm1hdHRlclRlc3QuY2xhc3MuZ2V0TmFtZSgpLmNvbmNhdCgiRm9vIik7DQorDQorICAgIC8qKg0KKyAgICAgKiBUaGUgbGluZSBzZXBhcmF0b3IuDQorICAgICAqLw0KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTElORV9TRVAgPSBTeXN0ZW0ubGluZVNlcGFyYXRvcigpOw0KKw0KKyAgICAvKioNCisgICAgICogVGhlIG1heCB3aWR0aC4NCisgICAgICovDQorICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNQVhfUFJFID0gMTYwOw0KKyAgICAvKioNCisgICAgICogVGhlIGRlZmF1bHQgbGVmdCB0byByaWdodCBwYXR0ZXJuLg0KKyAgICAgKi8NCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIExFRlRfVE9fUklHSFQgPSAiJTckIy4iICsgTUFYX1BSRSArICJzJW4iOw0KKw0KKyAgICAvKioNCisgICAgICogU2VlIExvZ01hbmFnZXIuDQorICAgICAqLw0KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTE9HX0NGR19LRVkgPSAiamF2YS51dGlsLmxvZ2dpbmcuY29uZmlnLmZpbGUiOw0KKw0KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGNoZWNrSlZNT3B0aW9ucygpIHRocm93cyBFeGNlcHRpb24gew0KKyAgICAgICAgYXNzZXJ0VHJ1ZShDb2xsZWN0b3JGb3JtYXR0ZXJUZXN0LmNsYXNzLmRlc2lyZWRBc3NlcnRpb25TdGF0dXMoKSk7DQorICAgICAgICBhc3NlcnROdWxsKFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS51dGlsLmxvZ2dpbmcubWFuYWdlciIpKTsNCisgICAgICAgIGFzc2VydE51bGwoU3lzdGVtLmdldFByb3BlcnR5KCJqYXZhLnV0aWwubG9nZ2luZy5jb25maWcuY2xhc3MiKSk7DQorICAgICAgICBhc3NlcnROdWxsKFN5c3RlbS5nZXRQcm9wZXJ0eShMT0dfQ0ZHX0tFWSkpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKExvZ01hbmFnZXIuY2xhc3MsIExvZ01hbmFnZXIuZ2V0TG9nTWFuYWdlcigpLmdldENsYXNzKCkpOw0KKyAgICB9DQorDQorICAgIHByaXZhdGUgc3RhdGljIHZvaWQgZnVsbEZlbmNlKCkgew0KKyAgICAgICAgTG9nTWFuYWdlci5nZXRMb2dNYW5hZ2VyKCkuZ2V0UHJvcGVydHkoIiIpOw0KKyAgICB9DQorDQorICAgIEBCZWZvcmVDbGFzcw0KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0VXBDbGFzcygpIHRocm93cyBFeGNlcHRpb24gew0KKyAgICAgICAgY2hlY2tKVk1PcHRpb25zKCk7DQorICAgICAgICBhc3NlcnRUcnVlKCJSZWNvbXBpbGUgdGVzdHMgdG8gaW5jbHVkZSBzb3VyY2UgbGluZSBudW1iZXJzLiIsDQorICAgICAgICAgICAgICAgIG5ldyBUaHJvd2FibGUoKS5nZXRTdGFja1RyYWNlKClbMF0uZ2V0TGluZU51bWJlcigpID49IDApOw0KKyAgICAgICAgdHJ5IHsNCisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoQ2xhc3MuZm9yTmFtZShVTktOT1dOX0NMQVNTX05BTUUpKTsNCisgICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZXhwZWN0KSB7DQorICAgICAgICB9DQorICAgIH0NCisNCisgICAgQEFmdGVyQ2xhc3MNCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHRlYXJEb3duQ2xhc3MoKSB0aHJvd3MgRXhjZXB0aW9uIHsNCisgICAgICAgIGNoZWNrSlZNT3B0aW9ucygpOw0KKyAgICB9DQorDQorICAgIEBCZWZvcmUNCisgICAgcHVibGljIHZvaWQgc2V0VXAoKSB7DQorICAgICAgICBmdWxsRmVuY2UoKTsNCisgICAgfQ0KKw0KKyAgICBAQWZ0ZXINCisgICAgcHVibGljIHZvaWQgdGVhckRvd24oKSB7DQorICAgICAgICBmdWxsRmVuY2UoKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVjbGFyZWRDbGFzc2VzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7DQorICAgICAgICB0ZXN0TG9hZERlY2xhcmVkQ2xhc3NlcyhDb21wYWN0Rm9ybWF0dGVyLmNsYXNzKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7DQorICAgICAgICBmaW5hbCBTdHJpbmcgcCA9IENvbXBhY3RGb3JtYXR0ZXIuY2xhc3MuZ2V0TmFtZSgpOw0KKyAgICAgICAgUHJvcGVydGllcyBwcm9wcyA9IG5ldyBQcm9wZXJ0aWVzKCk7DQorICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5mb3JtYXQiKSwgIiU5JHMiKTsNCisgICAgICAgIExvZ01hbmFnZXIgbWFuYWdlciA9IExvZ01hbmFnZXIuZ2V0TG9nTWFuYWdlcigpOw0KKyAgICAgICAgdHJ5IHsNCisgICAgICAgICAgICByZWFkKG1hbmFnZXIsIHByb3BzKTsNCisgICAgICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIoKTsNCisgICAgICAgICAgICBMb2dSZWNvcmQgZmlyc3QgPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgTGV2ZWwuSU5GTy5nZXROYW1lKCkpOw0KKyAgICAgICAgICAgIGZpcnN0LnNldFNlcXVlbmNlTnVtYmVyKFNob3J0Lk1BWF9WQUxVRSk7DQorICAgICAgICAgICAgU3RyaW5nIHJlc3VsdCA9IGNmLmZvcm1hdChmaXJzdCk7DQorICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKFN0cmluZy52YWx1ZU9mKChpbnQpIFNob3J0Lk1BWF9WQUxVRSksIHJlc3VsdCk7DQorICAgICAgICB9IGZpbmFsbHkgew0KKyAgICAgICAgICAgIG1hbmFnZXIucmVzZXQoKTsNCisgICAgICAgIH0NCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0TmV3Rm9ybWF0dGVyV2l0aFBhdHRlcm4oKSB7DQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIoIiU0JHMiKTsNCisgICAgICAgIFN0cmluZyByZXN1bHQgPSBjZi5mb3JtYXQobmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICIiKSk7DQorICAgICAgICBhc3NlcnRFcXVhbHMoTGV2ZWwuU0VWRVJFLmdldExvY2FsaXplZE5hbWUoKSwgcmVzdWx0KTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0TmV3Rm9ybWF0dGVyTnVsbFBhdHRlcm4oKSB7DQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIoKFN0cmluZykgbnVsbCk7DQorICAgICAgICBhc3NlcnRFcXVhbHMoQ29tcGFjdEZvcm1hdHRlci5jbGFzcywgY2YuZ2V0Q2xhc3MoKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEdldEhlYWRBbmRHZXRUYWlsKCkgew0KKyAgICAgICAgQ29tcGFjdEZvcm1hdHRlciBjZiA9IG5ldyBDb21wYWN0Rm9ybWF0dGVyKCk7DQorICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIGNmLmdldEhlYWQobnVsbCkpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBjZi5nZXRUYWlsKG51bGwpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0V2l0aE1lc3NhZ2UoKSB7DQorICAgICAgICBMb2dSZWNvcmQgcmVjb3JkID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICJtZXNzYWdlIik7DQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIoKTsNCisgICAgICAgIFN0cmluZyByZXN1bHQgPSBjZi5mb3JtYXQocmVjb3JkKTsNCisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LCByZXN1bHQuc3RhcnRzV2l0aChyZWNvcmQuZ2V0TWVzc2FnZSgpKSk7DQorICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCwgcmVzdWx0LmVuZHNXaXRoKExJTkVfU0VQKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEZvcm1hdFdpdGhNZXNzYWdlUHJlY2lzaW9uT3ZlcldpZHRoKCkgew0KKyAgICAgICAgTG9nUmVjb3JkIHJlY29yZCA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAibWVzc2FnZSIpOw0KKyAgICAgICAgcmVjb3JkLnNldFRocm93bihuZXcgVGhyb3dhYmxlKCJ0aHJvd24iKSk7DQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIoIiU3JCM2LjEycyIpOw0KKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IGNmLmZvcm1hdChyZWNvcmQpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJtZXN8VGhyb3dhYmxlIiwgcmVzdWx0KTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0V2l0aE1lc3NhZ2VXaWR0aE92ZXJQcmVjaXNpb24oKSB7DQorICAgICAgICBMb2dSZWNvcmQgcmVjb3JkID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICJtZXNzYWdlIik7DQorICAgICAgICByZWNvcmQuc2V0VGhyb3duKG5ldyBUaHJvd2FibGUoInRocm93biIpKTsNCisgICAgICAgIENvbXBhY3RGb3JtYXR0ZXIgY2YgPSBuZXcgQ29tcGFjdEZvcm1hdHRlcigiJTckIzEyLjZzIik7DQorICAgICAgICBTdHJpbmcgcmVzdWx0ID0gY2YuZm9ybWF0KHJlY29yZCk7DQorICAgICAgICBhc3NlcnRFcXVhbHMoIm1lc1x1MDAyMFx1MDAyMFx1MDAyMHxUaHJcdTAwMjBcdTAwMjBcdTAwMjAiLCByZXN1bHQpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRXaXRoTWVzc2FnZUVtcHR5KCkgew0KKyAgICAgICAgTG9nUmVjb3JkIHJlY29yZCA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAiIik7DQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIoKTsNCisgICAgICAgIFN0cmluZyByZXN1bHQgPSBjZi5mb3JtYXQocmVjb3JkKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhyZXN1bHQsIExJTkVfU0VQKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0TWVzc2FnZVN1cnJvZ2F0ZSgpIHsNCisgICAgICAgIExvZ1JlY29yZCByZWNvcmQgPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwNCisgICAgICAgICAgICAgICAgImFcdWQ4MDFcdWRjMDBcdWQ4MDFcdWRjMDBcdWQ4MDFcdWRjMDBcdWQ4MDFcdWRjMDAiKTsNCisgICAgICAgIHJlY29yZC5zZXRUaHJvd24obmV3IFRocm93YWJsZSgidGhyb3duIikpOw0KKyAgICAgICAgQ29tcGFjdEZvcm1hdHRlciBjZiA9IG5ldyBDb21wYWN0Rm9ybWF0dGVyKCIlNyQjLjZzJW4iKTsNCisgICAgICAgIFN0cmluZyByZXN1bHQgPSBjZi5mb3JtYXQocmVjb3JkKTsNCisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LCByZXN1bHQuc3RhcnRzV2l0aCgiYVx1ZDgwMVx1ZGMwMCIpKTsNCisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LCByZXN1bHQuZW5kc1dpdGgoInxUaHIiICsgTElORV9TRVApKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0V2l0aE1lc3NhZ2VBbmRUaHJvd25MZWZ0VG9SaWdodCgpIHsNCisgICAgICAgIExvZ1JlY29yZCByZWNvcmQgPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgIm1lc3NhZ2UiKTsNCisgICAgICAgIHJlY29yZC5zZXRUaHJvd24obmV3IFRocm93YWJsZSgidGhyb3duIikpOw0KKyAgICAgICAgQ29tcGFjdEZvcm1hdHRlciBjZiA9IG5ldyBDb21wYWN0Rm9ybWF0dGVyKCk7DQorICAgICAgICBTdHJpbmcgcmVzdWx0ID0gY2YuZm9ybWF0KHJlY29yZCk7DQorICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCwgcmVzdWx0LnN0YXJ0c1dpdGgocmVjb3JkLmdldE1lc3NhZ2UoKSkpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQsIHJlc3VsdC5jb250YWlucygifCIpKTsNCisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LCByZXN1bHQuY29udGFpbnMoVGhyb3dhYmxlLmNsYXNzLmdldFNpbXBsZU5hbWUoKSkpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQsIHJlc3VsdC5jb250YWlucyhDb21wYWN0Rm9ybWF0dGVyVGVzdC5jbGFzcy5nZXRTaW1wbGVOYW1lKCkpKTsNCisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LCByZXN1bHQuY29udGFpbnMoInRlc3RGb3JtYXRXaXRoTWVzc2FnZUFuZFRocm93biIpKTsNCisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LCByZXN1bHQuY29udGFpbnMoU3RyaW5nLnZhbHVlT2YoDQorICAgICAgICAgICAgICAgIHJlY29yZC5nZXRUaHJvd24oKS5nZXRTdGFja1RyYWNlKClbMF0uZ2V0TGluZU51bWJlcigpKSkpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQsIHJlc3VsdC5lbmRzV2l0aChMSU5FX1NFUCkpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRXaXRoVGhyb3duTGVmdFRvUmlnaHQoKSB7DQorICAgICAgICB0ZXN0Rm9ybWF0V2l0aFRocm93bihMRUZUX1RPX1JJR0hUKTsNCisgICAgfQ0KKw0KKyAgICBwcml2YXRlIHZvaWQgdGVzdEZvcm1hdFdpdGhUaHJvd24oU3RyaW5nIGZtdCkgew0KKyAgICAgICAgTG9nUmVjb3JkIHJlY29yZCA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAiIik7DQorICAgICAgICByZWNvcmQuc2V0VGhyb3duKG5ldyBUaHJvd2FibGUoInRocm93biIpKTsNCisgICAgICAgIENvbXBhY3RGb3JtYXR0ZXIgY2YgPSBuZXcgQ29tcGFjdEZvcm1hdHRlcihmbXQpOw0KKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IGNmLmZvcm1hdChyZWNvcmQpOw0KKyAgICAgICAgYXNzZXJ0RmFsc2UocmVzdWx0LCByZXN1bHQuc3RhcnRzV2l0aCgifCIpKTsNCisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LCByZXN1bHQuY29udGFpbnMocmVjb3JkLmdldFRocm93bigpLmdldE1lc3NhZ2UoKSkpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQsIHJlc3VsdC5lbmRzV2l0aChMSU5FX1NFUCkpOw0KKyAgICB9DQorDQorICAgIEBUZXN0KGV4cGVjdGVkID0gTnVsbFBvaW50ZXJFeGNlcHRpb24uY2xhc3MpDQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRNZXNzYWdlTnVsbCgpIHsNCisgICAgICAgIENvbXBhY3RGb3JtYXR0ZXIgY2YgPSBuZXcgQ29tcGFjdEZvcm1hdHRlcigpOw0KKyAgICAgICAgY2YuZm9ybWF0TWVzc2FnZSgoTG9nUmVjb3JkKSBudWxsKTsNCisgICAgICAgIGZhaWwoY2YudG9TdHJpbmcoKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEZvcm1hdE1lc3NhZ2VMb2NhbGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsNCisgICAgICAgIFN0cmluZyBtc2cgPSAibWVzc2FnZSI7DQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIoIiU1JHMiKTsNCisgICAgICAgIFByb3BlcnRpZXMgcHJvcHMgPSBuZXcgUHJvcGVydGllcygpOw0KKyAgICAgICAgcHJvcHMucHV0KExPR19DRkdfS0VZLCBtc2cpOw0KKw0KKyAgICAgICAgTG9nUmVjb3JkIHIgPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgTE9HX0NGR19LRVkpOw0KKyAgICAgICAgci5zZXRSZXNvdXJjZUJ1bmRsZShuZXcgTG9jYWxlUmVzb3VyY2UocHJvcHMsIExvY2FsZS5VUykpOw0KKyAgICAgICAgYXNzZXJ0Tm90TnVsbChyLmdldFJlc291cmNlQnVuZGxlKCkuZ2V0TG9jYWxlKCkpOw0KKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IGNmLmZvcm1hdChyKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhtc2csIHJlc3VsdCk7DQorICAgICAgICBhc3NlcnRFcXVhbHMobXNnLCBjZi5mb3JtYXRNZXNzYWdlKHIpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0TWVzc2FnZV9Mb2dSZWNvcmRMZWZ0VG9SaWdodCgpIHsNCisgICAgICAgIHRlc3RGb3JtYXRNZXNzYWdlX0xvZ1JlY29yZChMRUZUX1RPX1JJR0hUKTsNCisgICAgfQ0KKw0KKyAgICBwcml2YXRlIHZvaWQgdGVzdEZvcm1hdE1lc3NhZ2VfTG9nUmVjb3JkKFN0cmluZyBmbXQpIHsNCisgICAgICAgIEV4Y2VwdGlvbiBlID0gbmV3IElPRXhjZXB0aW9uKCk7DQorICAgICAgICBhc3NlcnROdWxsKGUuZ2V0TWVzc2FnZSgpLCBlLmdldE1lc3NhZ2UoKSk7DQorDQorICAgICAgICBlID0gbmV3IEV4Y2VwdGlvbihlLnRvU3RyaW5nKCksIGUpOw0KKyAgICAgICAgYXNzZXJ0Tm90TnVsbChlLmdldE1lc3NhZ2UoKSwgZS5nZXRNZXNzYWdlKCkpOw0KKw0KKyAgICAgICAgTG9nUmVjb3JkIHJlY29yZCA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCBlLnRvU3RyaW5nKCkpOw0KKyAgICAgICAgcmVjb3JkLnNldFRocm93bihlKTsNCisgICAgICAgIENvbXBhY3RGb3JtYXR0ZXIgY2YgPSBuZXcgQ29tcGFjdEZvcm1hdHRlcihmbXQpOw0KKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IGNmLmZvcm1hdChyZWNvcmQpOw0KKw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQsIHJlc3VsdC5jb250YWlucygifCIpKTsNCisgICAgICAgIGFzc2VydFRydWUoZS50b1N0cmluZygpLCBlLnRvU3RyaW5nKCkuY29udGFpbnMoRXhjZXB0aW9uLmNsYXNzLmdldFBhY2thZ2UoKS5nZXROYW1lKCkpKTsNCisgICAgICAgIGFzc2VydFRydWUoZS50b1N0cmluZygpLCBlLnRvU3RyaW5nKCkuY29udGFpbnMoSU9FeGNlcHRpb24uY2xhc3MuZ2V0UGFja2FnZSgpLmdldE5hbWUoKSkpOw0KKyAgICAgICAgaW50IGlkeDsNCisgICAgICAgIGlkeCA9IHJlc3VsdC5pbmRleE9mKEV4Y2VwdGlvbi5jbGFzcy5nZXRTaW1wbGVOYW1lKCkpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQsIGlkeCA+PSAwKTsNCisNCisgICAgICAgIGlkeCA9IHJlc3VsdC5pbmRleE9mKElPRXhjZXB0aW9uLmNsYXNzLmdldFNpbXBsZU5hbWUoKSwgaWR4KTsNCisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LCBpZHggPj0gMCk7DQorDQorICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCwgcmVzdWx0LmNvbnRhaW5zKHJlY29yZC5nZXRUaHJvd24oKS5nZXRDbGFzcygpLmdldFNpbXBsZU5hbWUoKSkpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQsIHJlc3VsdC5jb250YWlucyhyZWNvcmQuZ2V0VGhyb3duKCkuZ2V0Q2F1c2UoKS5nZXRDbGFzcygpLmdldFNpbXBsZU5hbWUoKSkpOw0KKw0KKyAgICAgICAgYXNzZXJ0RmFsc2UocmVzdWx0LCByZXN1bHQuY29udGFpbnMoRXhjZXB0aW9uLmNsYXNzLmdldFBhY2thZ2UoKS5nZXROYW1lKCkpKTsNCisgICAgICAgIGFzc2VydEZhbHNlKHJlc3VsdCwgcmVzdWx0LmNvbnRhaW5zKElPRXhjZXB0aW9uLmNsYXNzLmdldFBhY2thZ2UoKS5nZXROYW1lKCkpKTsNCisNCisgICAgICAgIGFzc2VydEZhbHNlKHJlc3VsdCwgcmVzdWx0LmNvbnRhaW5zKEV4Y2VwdGlvbi5jbGFzcy5nZXROYW1lKCkpKTsNCisgICAgICAgIGFzc2VydEZhbHNlKHJlc3VsdCwgcmVzdWx0LmNvbnRhaW5zKElPRXhjZXB0aW9uLmNsYXNzLmdldE5hbWUoKSkpOw0KKw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQsIHJlc3VsdC5lbmRzV2l0aChMSU5FX1NFUCkpOw0KKyAgICB9DQorDQorICAgIEBUZXN0KHRpbWVvdXQgPSAzMDAwMCkNCisgICAgcHVibGljIHZvaWQgdGVzdEZvcm1hdE1lc3NhZ2VfTG9nUmVjb3JkRXZpbCgpIHsNCisgICAgICAgIExvZ1JlY29yZCByZWNvcmQgPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgIiIpOw0KKyAgICAgICAgcmVjb3JkLnNldFRocm93bihjcmVhdGVFdmlsVGhyb3dhYmxlKCkpOw0KKyAgICAgICAgQ29tcGFjdEZvcm1hdHRlciBjZiA9IG5ldyBDb21wYWN0Rm9ybWF0dGVyKCk7DQorICAgICAgICBjZi5mb3JtYXRNZXNzYWdlKHJlY29yZCk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEZvcm1hdE1heE1lc3NhZ2VXaWR0aExlZnRUb1JpZ2h0KCkgew0KKyAgICAgICAgdGVzdEZvcm1hdE1heE1lc3NhZ2VXaWR0aChMRUZUX1RPX1JJR0hULCBNQVhfUFJFKTsNCisgICAgfQ0KKw0KKyAgICBwcml2YXRlIHZvaWQgdGVzdEZvcm1hdE1heE1lc3NhZ2VXaWR0aChTdHJpbmcgZm10LCBpbnQgd2lkdGgpIHsNCisgICAgICAgIGFzc2VydFRydWUoZm10LCBmbXQuY29udGFpbnMoSW50ZWdlci50b1N0cmluZyh3aWR0aCkpKTsNCisgICAgICAgIGFzc2VydFRydWUoU3RyaW5nLnZhbHVlT2Yod2lkdGgpLCB3aWR0aCA8IEludGVnZXIuTUFYX1ZBTFVFIC8gNCk7DQorDQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIoZm10KTsNCisgICAgICAgIExvZ1JlY29yZCByZWNvcmQgPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgIiIpOw0KKyAgICAgICAgaW50IHBhZGRpbmcgPSBMSU5FX1NFUC5sZW5ndGgoKTsNCisgICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDwgd2lkdGg7IGkrKykgew0KKyAgICAgICAgICAgIHJlY29yZC5zZXRNZXNzYWdlKHJwYWQoIiIsIGksICJBIikpOw0KKyAgICAgICAgICAgIFN0cmluZyByZXN1bHQgPSBjZi5mb3JtYXQocmVjb3JkKTsNCisgICAgICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCwgcmVzdWx0Lmxlbmd0aCgpID09IGkgKyBwYWRkaW5nKTsNCisgICAgICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCwgcmVzdWx0LmVuZHNXaXRoKExJTkVfU0VQKSk7DQorICAgICAgICB9DQorDQorICAgICAgICBmb3IgKGludCBpID0gd2lkdGg7IGkgPD0gKHdpZHRoICogNCk7IGkrKykgew0KKyAgICAgICAgICAgIHJlY29yZC5zZXRNZXNzYWdlKHJwYWQoIiIsIGksICJBIikpOw0KKyAgICAgICAgICAgIFN0cmluZyByZXN1bHQgPSBjZi5mb3JtYXQocmVjb3JkKTsNCisgICAgICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCwgcmVzdWx0Lmxlbmd0aCgpID09IHdpZHRoICsgcGFkZGluZyk7DQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQsIHJlc3VsdC5lbmRzV2l0aChMSU5FX1NFUCkpOw0KKyAgICAgICAgfQ0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRNYXhUaHJvd2FibGVXaWR0aExlZnRUb1JpZ2h0KCkgew0KKyAgICAgICAgU3RyaW5nIGZtdCA9IExFRlRfVE9fUklHSFQ7DQorICAgICAgICBpbnQgd2lkdGggPSBNQVhfUFJFOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShmbXQsIGZtdC5jb250YWlucyhJbnRlZ2VyLnRvU3RyaW5nKHdpZHRoKSkpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShTdHJpbmcudmFsdWVPZih3aWR0aCksIHdpZHRoIDwgSW50ZWdlci5NQVhfVkFMVUUgLyA0KTsNCisNCisgICAgICAgIENvbXBhY3RGb3JtYXR0ZXIgY2YgPSBuZXcgQ29tcGFjdEZvcm1hdHRlcihmbXQpOw0KKyAgICAgICAgTG9nUmVjb3JkIHJlY29yZCA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAiIik7DQorICAgICAgICBpbnQgcGFkZGluZyA9IExJTkVfU0VQLmxlbmd0aCgpOw0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB3aWR0aDsgaSsrKSB7DQorICAgICAgICAgICAgcmVjb3JkLnNldFRocm93bihuZXcgVGhyb3dhYmxlKHJwYWQoIiIsIGksICJBIikpKTsNCisgICAgICAgICAgICBTdHJpbmcgcmVzdWx0ID0gY2YuZm9ybWF0KHJlY29yZCk7DQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQsIHJlc3VsdC5sZW5ndGgoKSA8PSB3aWR0aCArIHBhZGRpbmcpOw0KKw0KKyAgICAgICAgICAgIGFzc2VydFRydWUocmVzdWx0LCByZXN1bHQuZW5kc1dpdGgoTElORV9TRVApKTsNCisgICAgICAgIH0NCisNCisgICAgICAgIGZvciAoaW50IGkgPSB3aWR0aDsgaSA8PSAod2lkdGggKiA0KTsgaSsrKSB7DQorICAgICAgICAgICAgcmVjb3JkLnNldFRocm93bihuZXcgVGhyb3dhYmxlKHJwYWQoIiIsIGksICJBIikpKTsNCisgICAgICAgICAgICBTdHJpbmcgcmVzdWx0ID0gY2YuZm9ybWF0KHJlY29yZCk7DQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQubGVuZ3RoKCkgKyAiLCAiICsgKHdpZHRoICsgcGFkZGluZyksDQorICAgICAgICAgICAgICAgICAgICByZXN1bHQubGVuZ3RoKCkgPT0gd2lkdGggKyBwYWRkaW5nKTsNCisgICAgICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCwgcmVzdWx0LmVuZHNXaXRoKExJTkVfU0VQKSk7DQorICAgICAgICB9DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEZvcm1hdFRocm93blRyYWlsaW5nRG90KCkgew0KKyAgICAgICAgdGVzdEZvcm1hdFRocm93bklsbGVnYWxDbGFzc05hbWUoIkhlbGxvLiIpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRUaHJvd25DbGFzc0RvdFNwYWNlKCkgew0KKyAgICAgICAgU3RyaW5nIG1zZyA9ICJ0ZXN0IjsNCisgICAgICAgIFN0cmluZyBwcmVmaXggPSBJbGxlZ2FsU3RhdGVFeGNlcHRpb24uY2xhc3MuZ2V0TmFtZSgpICsgIi4gIjsNCisgICAgICAgIFRocm93YWJsZSB0ID0gbmV3IFByZWZpeEV4Y2VwdGlvbihwcmVmaXgsIG51bGwsIG51bGwpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKHByZWZpeCwgdC50b1N0cmluZygpKTsNCisgICAgICAgIExvZ1JlY29yZCByZWNvcmQgPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgIiIpOw0KKyAgICAgICAgcmVjb3JkLnNldFRocm93bih0KTsNCisgICAgICAgIENvbXBhY3RGb3JtYXR0ZXIgY2YgPSBuZXcgQ29tcGFjdEZvcm1hdHRlcigiJTYkcyIpOw0KKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IGNmLmZvcm1hdChyZWNvcmQpOw0KKyAgICAgICAgU3RhY2tUcmFjZUVsZW1lbnRbXSBzdGUgPSB0LmdldFN0YWNrVHJhY2UoKTsNCisgICAgICAgIFN0cmluZyBmcmFtZSA9IENvbXBhY3RGb3JtYXR0ZXJUZXN0LmNsYXNzLmdldFNpbXBsZU5hbWUoKQ0KKyAgICAgICAgICAgICAgICArICcuJyArIHN0ZVswXS5nZXRNZXRob2ROYW1lKCkgKyAiKDoiDQorICAgICAgICAgICAgICAgICsgc3RlWzBdLmdldExpbmVOdW1iZXIoKSArICIpIjsNCisNCisgICAgICAgIFN0cmluZyBjbnMgPSB0LmdldENsYXNzKCkuZ2V0U2ltcGxlTmFtZSgpDQorICAgICAgICAgICAgICAgICsgIjogIiArIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbi5jbGFzcy5nZXRTaW1wbGVOYW1lKCk7DQorICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCwgcmVzdWx0LnN0YXJ0c1dpdGgoY25zKSk7DQorICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCwgcmVzdWx0LmluZGV4T2YoY25zKSA9PSByZXN1bHQubGFzdEluZGV4T2YoY25zKSk7DQorICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCwgcmVzdWx0LmNvbnRhaW5zKG1zZykpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQsIHJlc3VsdC5pbmRleE9mKG1zZykgPT0gcmVzdWx0Lmxhc3RJbmRleE9mKG1zZykpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQsIHJlc3VsdC5lbmRzV2l0aChmcmFtZSkpOw0KKw0KKyAgICAgICAgY2YgPSBuZXcgQ29tcGFjdEZvcm1hdHRlcigiJTExJHMgJTE0JHMiKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhyZXN1bHQsIGNmLmZvcm1hdChyZWNvcmQpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0VGhyb3duTGVhZGluZ0RvdCgpIHsNCisgICAgICAgIHRlc3RGb3JtYXRUaHJvd25JbGxlZ2FsQ2xhc3NOYW1lKCIuSGVsbG8iKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0VGhyb3duRG90RG90KCkgew0KKyAgICAgICAgdGVzdEZvcm1hdFRocm93bklsbGVnYWxDbGFzc05hbWUoIkhlbGxvLi5Xb3JsZCIpOw0KKyAgICAgICAgdGVzdEZvcm1hdFRocm93bklsbGVnYWxDbGFzc05hbWUoIi4uSGVsbG9Xb3JsZCIpOw0KKyAgICAgICAgdGVzdEZvcm1hdFRocm93bklsbGVnYWxDbGFzc05hbWUoIkhlbGxvV29ybGQuLiIpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRUaHJvd25Db2xvblNwYWNlKCkgew0KKyAgICAgICAgdGVzdEZvcm1hdFRocm93bklsbGVnYWxDbGFzc05hbWUoIkhlbGxvOiBXb3JsZCIpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRUaHJvd25FbmRTaWduKCkgew0KKyAgICAgICAgLy9Tb21lIG9mIHRoZXNlIGFyZSBsZWdhbCBidXQgbm90IHdvcnRoIGNvbnNpZGVyaW5nIGxlZ2FsLg0KKyAgICAgICAgdGVzdEZvcm1hdFRocm93bklsbGVnYWxDbGFzc05hbWUoIkhlbGxvV29ybGQkIik7DQorICAgICAgICB0ZXN0Rm9ybWF0VGhyb3duSWxsZWdhbENsYXNzTmFtZSgiSGVsbG9Xb3JsZC4kIik7DQorICAgICAgICB0ZXN0Rm9ybWF0VGhyb3duSWxsZWdhbENsYXNzTmFtZSgiSGVsbG8uV29ybGQkIik7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEZvcm1hdFRocm93blN0YXJ0U2lnbigpIHsNCisgICAgICAgIHRlc3RGb3JtYXRUaHJvd25JbGxlZ2FsQ2xhc3NOYW1lKCIkSGVsbG9Xb3JsZCIpOw0KKyAgICAgICAgdGVzdEZvcm1hdFRocm93bklsbGVnYWxDbGFzc05hbWUoIiQuSGVsbG9Xb3JsZCIpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRUaHJvd25Eb3REb3RTaWduKCkgew0KKyAgICAgICAgdGVzdEZvcm1hdFRocm93bklsbGVnYWxDbGFzc05hbWUoIkhlbGxvLi4kV29ybGQiKTsNCisgICAgICAgIHRlc3RGb3JtYXRUaHJvd25JbGxlZ2FsQ2xhc3NOYW1lKCIuLiRIZWxsb1dvcmxkIik7DQorICAgICAgICB0ZXN0Rm9ybWF0VGhyb3duSWxsZWdhbENsYXNzTmFtZSgiSGVsbG9Xb3JsZC4uJCIpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRUaHJvd25TaWduRG90KCkgew0KKyAgICAgICAgdGVzdEZvcm1hdFRocm93bklsbGVnYWxDbGFzc05hbWUoIiQuSGVsbG9Xb3JsZCIpOw0KKyAgICAgICAgdGVzdEZvcm1hdFRocm93bklsbGVnYWxDbGFzc05hbWUoIkhlbGxvV29ybGQkLiIpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRUaHJvd25TaWduRG90RG90KCkgew0KKyAgICAgICAgdGVzdEZvcm1hdFRocm93bklsbGVnYWxDbGFzc05hbWUoIkhlbGxvJC4uV29ybGQiKTsNCisgICAgICAgIHRlc3RGb3JtYXRUaHJvd25JbGxlZ2FsQ2xhc3NOYW1lKCIkLi5IZWxsb1dvcmxkIik7DQorICAgICAgICB0ZXN0Rm9ybWF0VGhyb3duSWxsZWdhbENsYXNzTmFtZSgiSGVsbG9Xb3JsZCQuLiIpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRUaHJvd25Eb3RTaWduRG90KCkgew0KKyAgICAgICAgdGVzdEZvcm1hdFRocm93bklsbGVnYWxDbGFzc05hbWUoIkhlbGxvLiQuV29ybGQiKTsNCisgICAgICAgIHRlc3RGb3JtYXRUaHJvd25JbGxlZ2FsQ2xhc3NOYW1lKCIuJC5IZWxsb1dvcmxkIik7DQorICAgICAgICB0ZXN0Rm9ybWF0VGhyb3duSWxsZWdhbENsYXNzTmFtZSgiSGVsbG9Xb3JsZC4kLiIpOw0KKyAgICB9DQorDQorICAgIHByaXZhdGUgdm9pZCB0ZXN0Rm9ybWF0VGhyb3duSWxsZWdhbENsYXNzTmFtZShTdHJpbmcgcHJlZml4KSB7DQorICAgICAgICBUaHJvd2FibGUgdCA9IG5ldyBQcmVmaXhFeGNlcHRpb24ocHJlZml4LCBudWxsLCBudWxsKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhwcmVmaXgsIHQudG9TdHJpbmcoKSk7DQorICAgICAgICBMb2dSZWNvcmQgcmVjb3JkID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICIiKTsNCisgICAgICAgIHJlY29yZC5zZXRUaHJvd24odCk7DQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIoIiU2JHMiKTsNCisgICAgICAgIFN0cmluZyByZXN1bHQgPSBjZi5mb3JtYXQocmVjb3JkKTsNCisgICAgICAgIFN0YWNrVHJhY2VFbGVtZW50W10gc3RlID0gdC5nZXRTdGFja1RyYWNlKCk7DQorICAgICAgICBTdHJpbmcgZnJhbWUgPSBDb21wYWN0Rm9ybWF0dGVyVGVzdC5jbGFzcy5nZXRTaW1wbGVOYW1lKCkNCisgICAgICAgICAgICAgICAgKyAnLicgKyBzdGVbMF0uZ2V0TWV0aG9kTmFtZSgpICsgIig6Ig0KKyAgICAgICAgICAgICAgICArIHN0ZVswXS5nZXRMaW5lTnVtYmVyKCkgKyAiKSI7DQorDQorICAgICAgICBTdHJpbmcgY24gPSB0LmdldENsYXNzKCkuZ2V0U2ltcGxlTmFtZSgpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQsIHJlc3VsdC5zdGFydHNXaXRoKGNuKSk7DQorICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCwgcmVzdWx0LmluZGV4T2YoY24pID09IHJlc3VsdC5sYXN0SW5kZXhPZihjbikpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQsIHJlc3VsdC5jb250YWlucyhwcmVmaXgpKTsNCisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LCByZXN1bHQuaW5kZXhPZihwcmVmaXgpID09IHJlc3VsdC5sYXN0SW5kZXhPZihwcmVmaXgpKTsNCisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LCByZXN1bHQuZW5kc1dpdGgoZnJhbWUpKTsNCisNCisgICAgICAgIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIoIiUxMSRzICUxNCRzIik7DQorICAgICAgICBhc3NlcnRFcXVhbHMocmVzdWx0LCBjZi5mb3JtYXQocmVjb3JkKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEZvcm1hdFRocm93blNpbXBsZUNsYXNzTmFtZU51bGxNZXNzYWdlKCkgew0KKyAgICAgICAgLy9qYXZheC5tYW5hZ2VtZW50LkJhZFN0cmluZ09wZXJhdGlvbkV4Y2VwdGlvbg0KKyAgICAgICAgU3RyaW5nIG9wID0gInNvbWUgb3AiOw0KKyAgICAgICAgVGhyb3dhYmxlIHQgPSBuZXcgUHJlZml4RXhjZXB0aW9uKFByZWZpeEV4Y2VwdGlvbi5jbGFzcy5nZXRTaW1wbGVOYW1lKCkNCisgICAgICAgICAgICAgICAgKyAiOiAiICsgb3AsIChTdHJpbmcpIG51bGwsIG51bGwpOw0KKyAgICAgICAgYXNzZXJ0TnVsbCh0LmdldE1lc3NhZ2UoKSk7DQorICAgICAgICBhc3NlcnROb3ROdWxsKHQudG9TdHJpbmcoKSk7DQorICAgICAgICBhc3NlcnRUcnVlKHQudG9TdHJpbmcoKS5zdGFydHNXaXRoKHQuZ2V0Q2xhc3MoKS5nZXRTaW1wbGVOYW1lKCkpKTsNCisNCisgICAgICAgIExvZ1JlY29yZCByZWNvcmQgPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgIiIpOw0KKyAgICAgICAgcmVjb3JkLnNldFRocm93bih0KTsNCisgICAgICAgIENvbXBhY3RGb3JtYXR0ZXIgY2YgPSBuZXcgQ29tcGFjdEZvcm1hdHRlcigiJTYkcyIpOw0KKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IGNmLmZvcm1hdChyZWNvcmQpOw0KKyAgICAgICAgU3RhY2tUcmFjZUVsZW1lbnRbXSBzdGUgPSB0LmdldFN0YWNrVHJhY2UoKTsNCisgICAgICAgIFN0cmluZyBmcmFtZSA9IENvbXBhY3RGb3JtYXR0ZXJUZXN0LmNsYXNzLmdldFNpbXBsZU5hbWUoKQ0KKyAgICAgICAgICAgICAgICArICcuJyArIHN0ZVswXS5nZXRNZXRob2ROYW1lKCkgKyAiKDoiDQorICAgICAgICAgICAgICAgICsgc3RlWzBdLmdldExpbmVOdW1iZXIoKSArICIpIjsNCisNCisgICAgICAgIFN0cmluZyBzbiA9IHQuZ2V0Q2xhc3MoKS5nZXRTaW1wbGVOYW1lKCk7DQorICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCwgcmVzdWx0LnN0YXJ0c1dpdGgoc24pKTsNCisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LCByZXN1bHQuaW5kZXhPZihzbikgPT0gcmVzdWx0Lmxhc3RJbmRleE9mKHNuKSk7DQorICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCwgcmVzdWx0LmNvbnRhaW5zKG9wKSk7DQorICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCwgcmVzdWx0LmluZGV4T2Yob3ApID09IHJlc3VsdC5sYXN0SW5kZXhPZihvcCkpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQsIHJlc3VsdC5lbmRzV2l0aChmcmFtZSkpOw0KKw0KKyAgICAgICAgY2YgPSBuZXcgQ29tcGFjdEZvcm1hdHRlcigiJTExJHMgJTE0JHMiKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhyZXN1bHQsIGNmLmZvcm1hdChyZWNvcmQpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0U2VydmVyU2lkZXRNZXRyb0V4Y2VwdGlvbigpIHsNCisgICAgICAgIC8vY29tLnN1bi54bWwud3MuZGV2ZWxvcGVyLlNlcnZlclNpZGVFeGNlcHRpb24NCisgICAgICAgIFN0cmluZyBtc2cgPSAic2VydmVyIGVycm9yIjsNCisgICAgICAgIE51bGxQb2ludGVyRXhjZXB0aW9uIG5wZSA9IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbihtc2cpOw0KKyAgICAgICAgVGhyb3dhYmxlIHQgPSBuZXcgUHJlZml4RXhjZXB0aW9uKG5wZS5nZXRDbGFzcygpLmdldE5hbWUoKSwgbXNnLCBudWxsKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhtc2csIG5wZS5nZXRNZXNzYWdlKCkpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKG1zZywgdC5nZXRNZXNzYWdlKCkpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5wZS50b1N0cmluZygpLCB0LnRvU3RyaW5nKCkpOw0KKw0KKyAgICAgICAgTG9nUmVjb3JkIHJlY29yZCA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAiIik7DQorICAgICAgICByZWNvcmQuc2V0VGhyb3duKHQpOw0KKyAgICAgICAgQ29tcGFjdEZvcm1hdHRlciBjZiA9IG5ldyBDb21wYWN0Rm9ybWF0dGVyKCIlNiRzIik7DQorICAgICAgICBTdHJpbmcgcmVzdWx0ID0gY2YuZm9ybWF0KHJlY29yZCk7DQorICAgICAgICBTdGFja1RyYWNlRWxlbWVudFtdIHN0ZSA9IHQuZ2V0U3RhY2tUcmFjZSgpOw0KKyAgICAgICAgU3RyaW5nIGZyYW1lID0gQ29tcGFjdEZvcm1hdHRlclRlc3QuY2xhc3MuZ2V0U2ltcGxlTmFtZSgpDQorICAgICAgICAgICAgICAgICsgJy4nICsgc3RlWzBdLmdldE1ldGhvZE5hbWUoKSArICIoOiINCisgICAgICAgICAgICAgICAgKyBzdGVbMF0uZ2V0TGluZU51bWJlcigpICsgIikiOw0KKw0KKyAgICAgICAgU3RyaW5nIGNucyA9IHQuZ2V0Q2xhc3MoKS5nZXRTaW1wbGVOYW1lKCkNCisgICAgICAgICAgICAgICAgKyAiOiAiICsgbnBlLmdldENsYXNzKCkuZ2V0U2ltcGxlTmFtZSgpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQsIHJlc3VsdC5zdGFydHNXaXRoKGNucykpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQsIHJlc3VsdC5pbmRleE9mKGNucykgPT0gcmVzdWx0Lmxhc3RJbmRleE9mKGNucykpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQsIHJlc3VsdC5jb250YWlucyhtc2cpKTsNCisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LCByZXN1bHQuZW5kc1dpdGgoZnJhbWUpKTsNCisNCisgICAgICAgIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIoIiUxMSRzICUxNCRzIik7DQorICAgICAgICBhc3NlcnRFcXVhbHMocmVzdWx0LCBjZi5mb3JtYXQocmVjb3JkKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEZvcm1hdFRocm93blByZWZpeE1lc3NhZ2VSZXRhaW5zRnFuKCkgew0KKyAgICAgICAgU3RyaW5nIG1zZyA9ICJqYXZhLmlvLnRtcGRpciI7DQorICAgICAgICBOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUgPSBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24obXNnKTsNCisgICAgICAgIFRocm93YWJsZSB0ID0gbmV3IFByZWZpeEV4Y2VwdGlvbihucGUuZ2V0Q2xhc3MoKS5nZXROYW1lKCksIG1zZywgbnVsbCk7DQorICAgICAgICBhc3NlcnRFcXVhbHMobXNnLCBucGUuZ2V0TWVzc2FnZSgpKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhtc2csIHQuZ2V0TWVzc2FnZSgpKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhucGUudG9TdHJpbmcoKSwgdC50b1N0cmluZygpKTsNCisNCisgICAgICAgIExvZ1JlY29yZCByZWNvcmQgPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgIiIpOw0KKyAgICAgICAgcmVjb3JkLnNldFRocm93bih0KTsNCisgICAgICAgIENvbXBhY3RGb3JtYXR0ZXIgY2YgPSBuZXcgQ29tcGFjdEZvcm1hdHRlcigiJTYkcyIpOw0KKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IGNmLmZvcm1hdChyZWNvcmQpOw0KKyAgICAgICAgU3RhY2tUcmFjZUVsZW1lbnRbXSBzdGUgPSB0LmdldFN0YWNrVHJhY2UoKTsNCisgICAgICAgIFN0cmluZyBmcmFtZSA9IENvbXBhY3RGb3JtYXR0ZXJUZXN0LmNsYXNzLmdldFNpbXBsZU5hbWUoKQ0KKyAgICAgICAgICAgICAgICArICcuJyArIHN0ZVswXS5nZXRNZXRob2ROYW1lKCkgKyAiKDoiDQorICAgICAgICAgICAgICAgICsgc3RlWzBdLmdldExpbmVOdW1iZXIoKSArICIpIjsNCisNCisgICAgICAgIFN0cmluZyBjbnMgPSB0LmdldENsYXNzKCkuZ2V0U2ltcGxlTmFtZSgpDQorICAgICAgICAgICAgICAgICsgIjogIiArIG5wZS5nZXRDbGFzcygpLmdldFNpbXBsZU5hbWUoKTsNCisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LCByZXN1bHQuc3RhcnRzV2l0aChjbnMpKTsNCisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LCByZXN1bHQuaW5kZXhPZihjbnMpID09IHJlc3VsdC5sYXN0SW5kZXhPZihjbnMpKTsNCisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LCByZXN1bHQuY29udGFpbnMobXNnKSk7DQorICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCwgcmVzdWx0LmVuZHNXaXRoKGZyYW1lKSk7DQorDQorICAgICAgICBjZiA9IG5ldyBDb21wYWN0Rm9ybWF0dGVyKCIlMTEkcyAlMTQkcyIpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdCwgY2YuZm9ybWF0KHJlY29yZCkpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRUaHJvd25IaWRkZW5NZXNzYWdlUmV0YWluc0ZxbigpIHsNCisgICAgICAgIFN0cmluZyBtc2cgPSAiamF2YS5pby50bXBkaXIiOw0KKyAgICAgICAgTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlID0gbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKG1zZyk7DQorICAgICAgICBUaHJvd2FibGUgdCA9IG5ldyBUb1N0cmluZ0V4Y2VwdGlvbihucGUuZ2V0Q2xhc3MoKS5nZXROYW1lKCksIG1zZyk7DQorICAgICAgICBhc3NlcnRFcXVhbHMobXNnLCBucGUuZ2V0TWVzc2FnZSgpKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhtc2csIHQuZ2V0TWVzc2FnZSgpKTsNCisNCisgICAgICAgIExvZ1JlY29yZCByZWNvcmQgPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgIiIpOw0KKyAgICAgICAgcmVjb3JkLnNldFRocm93bih0KTsNCisgICAgICAgIENvbXBhY3RGb3JtYXR0ZXIgY2YgPSBuZXcgQ29tcGFjdEZvcm1hdHRlcigiJTYkcyIpOw0KKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IGNmLmZvcm1hdChyZWNvcmQpOw0KKyAgICAgICAgU3RhY2tUcmFjZUVsZW1lbnRbXSBzdGUgPSB0LmdldFN0YWNrVHJhY2UoKTsNCisgICAgICAgIFN0cmluZyBmcmFtZSA9IENvbXBhY3RGb3JtYXR0ZXJUZXN0LmNsYXNzLmdldFNpbXBsZU5hbWUoKQ0KKyAgICAgICAgICAgICAgICArICcuJyArIHN0ZVswXS5nZXRNZXRob2ROYW1lKCkgKyAiKDoiDQorICAgICAgICAgICAgICAgICsgc3RlWzBdLmdldExpbmVOdW1iZXIoKSArICIpIjsNCisNCisgICAgICAgIFN0cmluZyBjbnMgPSB0LmdldENsYXNzKCkuZ2V0U2ltcGxlTmFtZSgpDQorICAgICAgICAgICAgICAgICsgIjogIiArIG5wZS5nZXRDbGFzcygpLmdldFNpbXBsZU5hbWUoKTsNCisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LCByZXN1bHQuc3RhcnRzV2l0aChjbnMpKTsNCisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LCByZXN1bHQuaW5kZXhPZihjbnMpID09IHJlc3VsdC5sYXN0SW5kZXhPZihjbnMpKTsNCisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LCByZXN1bHQuY29udGFpbnMobXNnKSk7DQorICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCwgcmVzdWx0LmVuZHNXaXRoKGZyYW1lKSk7DQorDQorICAgICAgICBjZiA9IG5ldyBDb21wYWN0Rm9ybWF0dGVyKCIlMTEkcyAlMTQkcyIpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdCwgY2YuZm9ybWF0KHJlY29yZCkpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRYTUxQYXJzZVhlcmNlc0V4Y2VwdGlvbigpIHsNCisgICAgICAgIC8vY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyLlhNTFBhcnNlRXhjZXB0aW9uDQorICAgICAgICBTdHJpbmcgbXNnID0gIlhNTCI7DQorICAgICAgICBTdHJpbmcgcHJlZml4ID0gIjE6dHdvOjM6Zm91ciI7DQorICAgICAgICBUaHJvd2FibGUgdCA9IG5ldyBQcmVmaXhFeGNlcHRpb24ocHJlZml4LCBtc2csIG51bGwpOw0KKw0KKyAgICAgICAgTG9nUmVjb3JkIHJlY29yZCA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAiIik7DQorICAgICAgICByZWNvcmQuc2V0VGhyb3duKHQpOw0KKyAgICAgICAgQ29tcGFjdEZvcm1hdHRlciBjZiA9IG5ldyBDb21wYWN0Rm9ybWF0dGVyKCIlNiRzIik7DQorICAgICAgICBTdHJpbmcgcmVzdWx0ID0gY2YuZm9ybWF0KHJlY29yZCk7DQorICAgICAgICBTdGFja1RyYWNlRWxlbWVudFtdIHN0ZSA9IHQuZ2V0U3RhY2tUcmFjZSgpOw0KKyAgICAgICAgU3RyaW5nIGZyYW1lID0gQ29tcGFjdEZvcm1hdHRlclRlc3QuY2xhc3MuZ2V0U2ltcGxlTmFtZSgpDQorICAgICAgICAgICAgICAgICsgJy4nICsgc3RlWzBdLmdldE1ldGhvZE5hbWUoKSArICIoOiINCisgICAgICAgICAgICAgICAgKyBzdGVbMF0uZ2V0TGluZU51bWJlcigpICsgIikiOw0KKw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShwcmVmaXgsIHQudG9TdHJpbmcoKS5zdGFydHNXaXRoKHByZWZpeCkpOw0KKyAgICAgICAgU3RyaW5nIGNuID0gdC5nZXRDbGFzcygpLmdldFNpbXBsZU5hbWUoKTsNCisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LCByZXN1bHQuc3RhcnRzV2l0aChjbikpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQsIHJlc3VsdC5pbmRleE9mKGNuKSA9PSByZXN1bHQubGFzdEluZGV4T2YoY24pKTsNCisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LCByZXN1bHQuY29udGFpbnMocHJlZml4KSk7DQorICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCwgcmVzdWx0LmluZGV4T2YocHJlZml4KSA9PSByZXN1bHQubGFzdEluZGV4T2YocHJlZml4KSk7DQorICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCwgcmVzdWx0LmNvbnRhaW5zKG1zZykpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQsIHJlc3VsdC5lbmRzV2l0aChmcmFtZSkpOw0KKw0KKyAgICAgICAgY2YgPSBuZXcgQ29tcGFjdEZvcm1hdHRlcigiJTExJHMgJTE0JHMiKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhyZXN1bHQsIGNmLmZvcm1hdChyZWNvcmQpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0R1NTRXhjZXB0aW9uKCkgew0KKyAgICAgICAgLy9vcmcuaWV0Zi5qZ3NzLkdTU0V4Y2VwdGlvbg0KKyAgICAgICAgU3RyaW5nIG1zZyA9ICJJbnZhbGlkIG5hbWUgcHJvdmlkZWQiOw0KKyAgICAgICAgU3RyaW5nIHByZWZpeCA9IFByZWZpeEV4Y2VwdGlvbi5jbGFzcy5nZXRTaW1wbGVOYW1lKCk7DQorICAgICAgICBUaHJvd2FibGUgdCA9IG5ldyBQcmVmaXhFeGNlcHRpb24ocHJlZml4LCBtc2csIG51bGwpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZSh0LnRvU3RyaW5nKCkuc3RhcnRzV2l0aCh0LmdldENsYXNzKCkuZ2V0U2ltcGxlTmFtZSgpKSk7DQorICAgICAgICBMb2dSZWNvcmQgcmVjb3JkID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICIiKTsNCisgICAgICAgIHJlY29yZC5zZXRUaHJvd24odCk7DQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIoIiU2JHMiKTsNCisgICAgICAgIFN0cmluZyByZXN1bHQgPSBjZi5mb3JtYXQocmVjb3JkKTsNCisgICAgICAgIFN0YWNrVHJhY2VFbGVtZW50W10gc3RlID0gdC5nZXRTdGFja1RyYWNlKCk7DQorICAgICAgICBTdHJpbmcgZnJhbWUgPSBDb21wYWN0Rm9ybWF0dGVyVGVzdC5jbGFzcy5nZXRTaW1wbGVOYW1lKCkNCisgICAgICAgICAgICAgICAgKyAnLicgKyBzdGVbMF0uZ2V0TWV0aG9kTmFtZSgpICsgIig6Ig0KKyAgICAgICAgICAgICAgICArIHN0ZVswXS5nZXRMaW5lTnVtYmVyKCkgKyAiKSI7DQorDQorICAgICAgICBhc3NlcnRUcnVlKHByZWZpeCwgdC50b1N0cmluZygpLnN0YXJ0c1dpdGgocHJlZml4KSk7DQorICAgICAgICBTdHJpbmcgY24gPSB0LmdldENsYXNzKCkuZ2V0U2ltcGxlTmFtZSgpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQsIHJlc3VsdC5zdGFydHNXaXRoKGNuKSk7DQorICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCwgcmVzdWx0LmluZGV4T2YoY24pID09IHJlc3VsdC5sYXN0SW5kZXhPZihjbikpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQsIHJlc3VsdC5jb250YWlucyhwcmVmaXgpKTsNCisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LCByZXN1bHQuaW5kZXhPZihwcmVmaXgpID09IHJlc3VsdC5sYXN0SW5kZXhPZihwcmVmaXgpKTsNCisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LCByZXN1bHQuY29udGFpbnMobXNnKSk7DQorICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCwgcmVzdWx0LmVuZHNXaXRoKGZyYW1lKSk7DQorDQorICAgICAgICBjZiA9IG5ldyBDb21wYWN0Rm9ybWF0dGVyKCIlMTEkcyAlMTQkcyIpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdCwgY2YuZm9ybWF0KHJlY29yZCkpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRNaXNtYXRjaGVkVHJlZU5vZGVFeGNlcHRpb24oKSB7DQorICAgICAgICAvL29yZy5hbnRsci5ydW50aW1lLk1pc21hdGNoZWRUcmVlTm9kZUV4Y2VwdGlvbg0KKyAgICAgICAgU3RyaW5nIHByZWZpeCA9IFRvU3RyaW5nRXhjZXB0aW9uLmNsYXNzLmdldFNpbXBsZU5hbWUoKQ0KKyAgICAgICAgICAgICAgICArICcoJyArIFN0cmluZy5jbGFzcy5nZXROYW1lKCkgKyAiIT0iDQorICAgICAgICAgICAgICAgICsgVGhyb3dhYmxlLmNsYXNzLmdldE5hbWUoKSArICcpJzsNCisNCisgICAgICAgIFRocm93YWJsZSB0ID0gbmV3IFRvU3RyaW5nRXhjZXB0aW9uKHByZWZpeCwgKFN0cmluZykgbnVsbCk7DQorICAgICAgICBhc3NlcnROdWxsKHQuZ2V0TG9jYWxpemVkTWVzc2FnZSgpKTsNCisgICAgICAgIGFzc2VydE51bGwodC5nZXRNZXNzYWdlKCkpOw0KKyAgICAgICAgTG9nUmVjb3JkIHJlY29yZCA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAiIik7DQorICAgICAgICByZWNvcmQuc2V0VGhyb3duKHQpOw0KKyAgICAgICAgQ29tcGFjdEZvcm1hdHRlciBjZiA9IG5ldyBDb21wYWN0Rm9ybWF0dGVyKCIlNiRzIik7DQorICAgICAgICBTdHJpbmcgcmVzdWx0ID0gY2YuZm9ybWF0KHJlY29yZCk7DQorICAgICAgICBTdGFja1RyYWNlRWxlbWVudFtdIHN0ZSA9IHQuZ2V0U3RhY2tUcmFjZSgpOw0KKyAgICAgICAgU3RyaW5nIGZyYW1lID0gQ29tcGFjdEZvcm1hdHRlclRlc3QuY2xhc3MuZ2V0U2ltcGxlTmFtZSgpDQorICAgICAgICAgICAgICAgICsgJy4nICsgc3RlWzBdLmdldE1ldGhvZE5hbWUoKSArICIoOiINCisgICAgICAgICAgICAgICAgKyBzdGVbMF0uZ2V0TGluZU51bWJlcigpICsgIikiOw0KKw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShwcmVmaXgsIHQudG9TdHJpbmcoKS5zdGFydHNXaXRoKHByZWZpeCkpOw0KKyAgICAgICAgU3RyaW5nIGNuID0gdC5nZXRDbGFzcygpLmdldFNpbXBsZU5hbWUoKTsNCisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LCByZXN1bHQuc3RhcnRzV2l0aChjbikpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQsIHJlc3VsdC5pbmRleE9mKGNuKSA9PSByZXN1bHQubGFzdEluZGV4T2YoY24pKTsNCisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LCByZXN1bHQuY29udGFpbnMocHJlZml4KSk7DQorICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCwgcmVzdWx0LmluZGV4T2YocHJlZml4KSA9PSByZXN1bHQubGFzdEluZGV4T2YocHJlZml4KSk7DQorICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCwgcmVzdWx0LmVuZHNXaXRoKGZyYW1lKSk7DQorDQorICAgICAgICBjZiA9IG5ldyBDb21wYWN0Rm9ybWF0dGVyKCIlMTEkcyAlMTQkcyIpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdCwgY2YuZm9ybWF0KHJlY29yZCkpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRJbm5lckV4Y2VwdGlvbigpIHsNCisgICAgICAgIFN0cmluZyBtc2cgPSAiaW5uZXIgY2xhc3MiOw0KKyAgICAgICAgU3RyaW5nIHByZWZpeCA9ICcoJyArIFN0cmluZy5jbGFzcy5nZXROYW1lKCkgKyAiIT0iDQorICAgICAgICAgICAgICAgICsgVGhyb3dhYmxlLmNsYXNzLmdldE5hbWUoKSArICcpJzsNCisNCisgICAgICAgIFRocm93YWJsZSB0ID0gbmV3IFRvU3RyaW5nRXhjZXB0aW9uKFRvU3RyaW5nRXhjZXB0aW9uLmNsYXNzLmdldE5hbWUoKQ0KKyAgICAgICAgICAgICAgICArIHByZWZpeCwgbXNnKTsNCisgICAgICAgIGFzc2VydEZhbHNlKHQudG9TdHJpbmcoKS5jb250YWlucyh0LmdldExvY2FsaXplZE1lc3NhZ2UoKSkpOw0KKyAgICAgICAgTG9nUmVjb3JkIHJlY29yZCA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAiIik7DQorICAgICAgICByZWNvcmQuc2V0VGhyb3duKHQpOw0KKyAgICAgICAgQ29tcGFjdEZvcm1hdHRlciBjZiA9IG5ldyBDb21wYWN0Rm9ybWF0dGVyKCIlNiRzIik7DQorICAgICAgICBTdHJpbmcgcmVzdWx0ID0gY2YuZm9ybWF0KHJlY29yZCk7DQorICAgICAgICBTdGFja1RyYWNlRWxlbWVudFtdIHN0ZSA9IHQuZ2V0U3RhY2tUcmFjZSgpOw0KKyAgICAgICAgU3RyaW5nIGZyYW1lID0gQ29tcGFjdEZvcm1hdHRlclRlc3QuY2xhc3MuZ2V0U2ltcGxlTmFtZSgpDQorICAgICAgICAgICAgICAgICsgJy4nICsgc3RlWzBdLmdldE1ldGhvZE5hbWUoKSArICIoOiINCisgICAgICAgICAgICAgICAgKyBzdGVbMF0uZ2V0TGluZU51bWJlcigpICsgIikiOw0KKw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShwcmVmaXgsIHQudG9TdHJpbmcoKS5jb250YWlucyhwcmVmaXgpKTsNCisgICAgICAgIFN0cmluZyBjbiA9IHQuZ2V0Q2xhc3MoKS5nZXRTaW1wbGVOYW1lKCk7DQorICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCwgcmVzdWx0LnN0YXJ0c1dpdGgoY24pKTsNCisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LCByZXN1bHQuaW5kZXhPZihjbikgPT0gcmVzdWx0Lmxhc3RJbmRleE9mKGNuKSk7DQorICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCwgcmVzdWx0LmNvbnRhaW5zKHByZWZpeCkpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQsIHJlc3VsdC5pbmRleE9mKHByZWZpeCkgPT0gcmVzdWx0Lmxhc3RJbmRleE9mKHByZWZpeCkpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQsIHJlc3VsdC5jb250YWlucyhtc2cpKTsNCisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LCByZXN1bHQuZW5kc1dpdGgoZnJhbWUpKTsNCisNCisgICAgICAgIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIoIiUxMSRzICUxNCRzIik7DQorICAgICAgICBhc3NlcnRFcXVhbHMocmVzdWx0LCBjZi5mb3JtYXQocmVjb3JkKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEZvcm1hdE1lc3NhZ2VfVGhyb3dhYmxlKCkgew0KKyAgICAgICAgRXhjZXB0aW9uIGUgPSBuZXcgSU9FeGNlcHRpb24oRXhjZXB0aW9uLmNsYXNzLmdldE5hbWUoKSk7DQorICAgICAgICBlID0gbmV3IEV4Y2VwdGlvbihlLnRvU3RyaW5nKCksIGUpOw0KKyAgICAgICAgYXNzZXJ0Tm90TnVsbChlLmdldE1lc3NhZ2UoKSwgZS5nZXRNZXNzYWdlKCkpOw0KKw0KKyAgICAgICAgQ29tcGFjdEZvcm1hdHRlciBjZiA9IG5ldyBDb21wYWN0Rm9ybWF0dGVyKCk7DQorICAgICAgICBTdHJpbmcgcmVzdWx0ID0gY2YuZm9ybWF0TWVzc2FnZShlKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhJT0V4Y2VwdGlvbi5jbGFzcy5nZXRTaW1wbGVOYW1lKCkNCisgICAgICAgICAgICAgICAgKyAiOiAiICsgRXhjZXB0aW9uLmNsYXNzLmdldFNpbXBsZU5hbWUoKSwgcmVzdWx0KTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0TWVzc2FnZV9UaHJvd2FibGVOdWxsKCkgew0KKyAgICAgICAgQ29tcGFjdEZvcm1hdHRlciBjZiA9IG5ldyBDb21wYWN0Rm9ybWF0dGVyKCk7DQorICAgICAgICBTdHJpbmcgcmVzdWx0ID0gY2YuZm9ybWF0TWVzc2FnZSgoVGhyb3dhYmxlKSBudWxsKTsNCisgICAgICAgIGFzc2VydEVxdWFscygiIiwgcmVzdWx0KTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0TWVzc2FnZV9UaHJvd2FibGVOdWxsTWVzc2FnZSgpIHsNCisgICAgICAgIENvbXBhY3RGb3JtYXR0ZXIgY2YgPSBuZXcgQ29tcGFjdEZvcm1hdHRlcigpOw0KKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IGNmLmZvcm1hdE1lc3NhZ2UobmV3IFRocm93YWJsZSgpKTsNCisgICAgICAgIFN0cmluZyBleHBlY3QgPSBUaHJvd2FibGUuY2xhc3MuZ2V0U2ltcGxlTmFtZSgpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdCwgcmVzdWx0KTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdCh0aW1lb3V0ID0gMzAwMDApDQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRNZXNzYWdlX1Rocm93YWJsZUV2aWwoKSB7DQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIoKTsNCisgICAgICAgIGNmLmZvcm1hdE1lc3NhZ2UoY3JlYXRlRXZpbFRocm93YWJsZSgpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0TGV2ZWwoKSB7DQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIoKTsNCisgICAgICAgIExvZ1JlY29yZCByZWNvcmQgPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgIiIpOw0KKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IGNmLmZvcm1hdExldmVsKHJlY29yZCk7DQorICAgICAgICBhc3NlcnRFcXVhbHMocmVjb3JkLmdldExldmVsKCkuZ2V0TG9jYWxpemVkTmFtZSgpLCByZXN1bHQpOw0KKyAgICB9DQorDQorICAgIEBUZXN0KGV4cGVjdGVkID0gTnVsbFBvaW50ZXJFeGNlcHRpb24uY2xhc3MpDQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRMZXZlbE51bGwoKSB7DQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIoKTsNCisgICAgICAgIGNmLmZvcm1hdExldmVsKChMb2dSZWNvcmQpIG51bGwpOw0KKyAgICAgICAgZmFpbChjZi50b1N0cmluZygpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0TG9nZ2VyKCkgew0KKyAgICAgICAgQ29tcGFjdEZvcm1hdHRlciBjZiA9IG5ldyBDb21wYWN0Rm9ybWF0dGVyKCk7DQorICAgICAgICBMb2dSZWNvcmQgcmVjb3JkID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICIiKTsNCisgICAgICAgIHJlY29yZC5zZXRTb3VyY2VNZXRob2ROYW1lKG51bGwpOw0KKyAgICAgICAgcmVjb3JkLnNldFNvdXJjZUNsYXNzTmFtZShudWxsKTsNCisgICAgICAgIHJlY29yZC5zZXRMb2dnZXJOYW1lKE9iamVjdC5jbGFzcy5nZXROYW1lKCkpOw0KKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IGNmLmZvcm1hdExvZ2dlck5hbWUocmVjb3JkKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhPYmplY3QuY2xhc3MuZ2V0U2ltcGxlTmFtZSgpLCByZXN1bHQpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRSb290TG9nZ2VyKCkgew0KKyAgICAgICAgdGVzdEZvcm1hdExvZ2dlck5vbkNsYXNzTmFtZSgiIik7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEZvcm1hdEdsb2JhbExvZ2dlcigpIHsNCisgICAgICAgIHRlc3RGb3JtYXRMb2dnZXJOb25DbGFzc05hbWUoImdsb2JhbCIpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRMb2dnZXJMZWFkaW5nRG90KCkgew0KKyAgICAgICAgdGVzdEZvcm1hdExvZ2dlck5vbkNsYXNzTmFtZSgiLkhlbGxvIik7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEZvcm1hdExvZ2dlckRvdERvdCgpIHsNCisgICAgICAgIHRlc3RGb3JtYXRMb2dnZXJOb25DbGFzc05hbWUoIkhlbGxvLi5Xb3JsZCIpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRMb2dnZXJDb2xvblNwYWNlKCkgew0KKyAgICAgICAgdGVzdEZvcm1hdExvZ2dlck5vbkNsYXNzTmFtZSgiSGVsbG86IFdvcmxkIik7DQorICAgIH0NCisNCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RGb3JtYXRMb2dnZXJOb25DbGFzc05hbWUoU3RyaW5nIG5hbWUpIHsNCisgICAgICAgIENvbXBhY3RGb3JtYXR0ZXIgY2YgPSBuZXcgQ29tcGFjdEZvcm1hdHRlcigpOw0KKyAgICAgICAgTG9nUmVjb3JkIHJlY29yZCA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAiIik7DQorICAgICAgICByZWNvcmQuc2V0U291cmNlTWV0aG9kTmFtZShudWxsKTsNCisgICAgICAgIHJlY29yZC5zZXRTb3VyY2VDbGFzc05hbWUobnVsbCk7DQorICAgICAgICByZWNvcmQuc2V0TG9nZ2VyTmFtZShuYW1lKTsNCisgICAgICAgIFN0cmluZyByZXN1bHQgPSBjZi5mb3JtYXRMb2dnZXJOYW1lKHJlY29yZCk7DQorICAgICAgICBhc3NlcnRFcXVhbHMobmFtZSwgcmVzdWx0KTsNCisNCisgICAgICAgIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIoIiUzJHMiKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhyZXN1bHQsIGNmLmZvcm1hdChyZWNvcmQpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdChleHBlY3RlZCA9IE51bGxQb2ludGVyRXhjZXB0aW9uLmNsYXNzKQ0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0TG9nZ2VyTnVsbCgpIHsNCisgICAgICAgIENvbXBhY3RGb3JtYXR0ZXIgY2YgPSBuZXcgQ29tcGFjdEZvcm1hdHRlcigpOw0KKyAgICAgICAgY2YuZm9ybWF0TG9nZ2VyTmFtZSgoTG9nUmVjb3JkKSBudWxsKTsNCisgICAgICAgIGZhaWwoY2YudG9TdHJpbmcoKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEZvcm1hdE1pbGxpcygpIHsNCisgICAgICAgIFN0cmluZyBwID0gIiUxJHRjIjsNCisgICAgICAgIENvbXBhY3RGb3JtYXR0ZXIgY2YgPSBuZXcgQ29tcGFjdEZvcm1hdHRlcihwKTsNCisgICAgICAgIExvZ1JlY29yZCByID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICIiKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhTdHJpbmcuZm9ybWF0KHAsIHIuZ2V0TWlsbGlzKCkpLA0KKyAgICAgICAgICAgICAgICBjZi5mb3JtYXQocikpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRNaWxsaXNMb2NhbGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsNCisgICAgICAgIFN0cmluZyBwID0gIiUxJHRjIjsNCisgICAgICAgIENvbXBhY3RGb3JtYXR0ZXIgY2YgPSBuZXcgQ29tcGFjdEZvcm1hdHRlcihwKTsNCisgICAgICAgIFByb3BlcnRpZXMgcHJvcHMgPSBuZXcgUHJvcGVydGllcygpOw0KKyAgICAgICAgTG9nUmVjb3JkIHIgPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgIiIpOw0KKyAgICAgICAgci5zZXRSZXNvdXJjZUJ1bmRsZShuZXcgTG9jYWxlUmVzb3VyY2UocHJvcHMsIExvY2FsZS5FTkdMSVNIKSk7DQorICAgICAgICBhc3NlcnRFcXVhbHMoU3RyaW5nLmZvcm1hdChMb2NhbGUuRU5HTElTSCwgcCwgci5nZXRNaWxsaXMoKSksDQorICAgICAgICAgICAgICAgIGNmLmZvcm1hdChyKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEZvcm1hdE1pbGxpc0J5UGFydHMoKSB7DQorICAgICAgICBTdHJpbmcgcCA9ICIlMSR0YiAlMSR0ZCwgJTEkdFkgJTEkdGw6JTEkdE06JTEkdFMgJTEkVHAiOw0KKyAgICAgICAgQ29tcGFjdEZvcm1hdHRlciBjZiA9IG5ldyBDb21wYWN0Rm9ybWF0dGVyKHApOw0KKyAgICAgICAgTG9nUmVjb3JkIHIgPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgIiIpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKFN0cmluZy5mb3JtYXQocCwgci5nZXRNaWxsaXMoKSksDQorICAgICAgICAgICAgICAgIGNmLmZvcm1hdChyKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEZvcm1hdE1pbGxpc0J5UGFydHNMb2NhbGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsNCisgICAgICAgIFN0cmluZyBwID0gIiUxJHRiICUxJHRkLCAlMSR0WSAlMSR0bDolMSR0TTolMSR0UyAlMSRUcCI7DQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIocCk7DQorICAgICAgICBQcm9wZXJ0aWVzIHByb3BzID0gbmV3IFByb3BlcnRpZXMoKTsNCisgICAgICAgIExvZ1JlY29yZCByID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICIiKTsNCisgICAgICAgIHIuc2V0UmVzb3VyY2VCdW5kbGUobmV3IExvY2FsZVJlc291cmNlKHByb3BzLCBMb2NhbGUuRU5HTElTSCkpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKFN0cmluZy5mb3JtYXQoTG9jYWxlLkVOR0xJU0gsIHAsIHIuZ2V0TWlsbGlzKCkpLA0KKyAgICAgICAgICAgICAgICBjZi5mb3JtYXQocikpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRNaWxsaXNBc0xvbmcoKSB7DQorICAgICAgICBTdHJpbmcgcCA9ICIlMSR0USI7DQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIocCk7DQorICAgICAgICBMb2dSZWNvcmQgciA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAiIik7DQorICAgICAgICBhc3NlcnRFcXVhbHMoU3RyaW5nLmZvcm1hdChwLCByLmdldE1pbGxpcygpKSwNCisgICAgICAgICAgICAgICAgY2YuZm9ybWF0KHIpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0Wm9uZURhdGVUaW1lKCkgdGhyb3dzIEV4Y2VwdGlvbiB7DQorICAgICAgICBMb2dSZWNvcmQgciA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAiIik7DQorICAgICAgICBPYmplY3QgemR0ID0gTG9nTWFuYWdlclByb3BlcnRpZXMuZ2V0Wm9uZWREYXRlVGltZShyKTsNCisgICAgICAgIGlmICh6ZHQgIT0gbnVsbCkgew0KKyAgICAgICAgICAgIFN0cmluZyBwID0gIiUxJHRiICUxJHRkLCAlMSR0WSAlMSR0bDolMSR0TTolMSR0Uy4lMSR0TiAlMSRUcCI7DQorICAgICAgICAgICAgQ29tcGFjdEZvcm1hdHRlciBjZiA9IG5ldyBDb21wYWN0Rm9ybWF0dGVyKHApOw0KKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhTdHJpbmcuZm9ybWF0KHAsIHpkdCksIGNmLmZvcm1hdChyKSk7DQorICAgICAgICB9IGVsc2Ugew0KKyAgICAgICAgICAgIHRyeSB7DQorICAgICAgICAgICAgICAgIE1ldGhvZCBtID0gTG9nUmVjb3JkLmNsYXNzLmdldE1ldGhvZCgiZ2V0SW5zdGFudCIpOw0KKyAgICAgICAgICAgICAgICBmYWlsKG0udG9TdHJpbmcoKSk7DQorICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgTm9TdWNoTWV0aG9kRXhjZXB0aW9uIGV4cGVjdCkgew0KKyAgICAgICAgICAgIH0NCisgICAgICAgIH0NCisgICAgfQ0KKw0KKyAgICBAVGVzdChleHBlY3RlZCA9IE51bGxQb2ludGVyRXhjZXB0aW9uLmNsYXNzKQ0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0TnVsbCgpIHsNCisgICAgICAgIENvbXBhY3RGb3JtYXR0ZXIgY2YgPSBuZXcgQ29tcGFjdEZvcm1hdHRlcigpOw0KKyAgICAgICAgY2YuZm9ybWF0KChMb2dSZWNvcmQpIG51bGwpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRSZXNvdXJjZUJ1bmRsZU5hbWUoKSB7DQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIoIiUxNSRzIik7DQorICAgICAgICBMb2dSZWNvcmQgciA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAiIik7DQorICAgICAgICByLnNldFJlc291cmNlQnVuZGxlTmFtZSgibmFtZSIpOw0KKyAgICAgICAgU3RyaW5nIG91dHB1dCA9IGNmLmZvcm1hdChyKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhyLmdldFJlc291cmNlQnVuZGxlTmFtZSgpLCBvdXRwdXQpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRLZXkoKSB7DQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIoIiUxNiRzIik7DQorICAgICAgICBMb2dSZWNvcmQgciA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAibWVzc2FnZSB7MH0iKTsNCisgICAgICAgIHIuc2V0UGFyYW1ldGVycyhuZXcgT2JqZWN0W117Mn0pOw0KKyAgICAgICAgU3RyaW5nIG91dHB1dCA9IGNmLmZvcm1hdChyKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhyLmdldE1lc3NhZ2UoKSwgb3V0cHV0KTsNCisgICAgICAgIGFzc2VydEZhbHNlKG91dHB1dC5lcXVhbHMoY2YuZm9ybWF0TWVzc2FnZShyKSkpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRTZXF1ZW5jZSgpIHsNCisgICAgICAgIENvbXBhY3RGb3JtYXR0ZXIgY2YgPSBuZXcgQ29tcGFjdEZvcm1hdHRlcigiJTkkZCIpOw0KKyAgICAgICAgTG9nUmVjb3JkIHJlY29yZCA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAiIik7DQorICAgICAgICBTdHJpbmcgb3V0cHV0ID0gY2YuZm9ybWF0KHJlY29yZCk7DQorICAgICAgICBTdHJpbmcgZXhwZWN0ID0gTG9uZy50b1N0cmluZyhyZWNvcmQuZ2V0U2VxdWVuY2VOdW1iZXIoKSk7DQorICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0LCBvdXRwdXQpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRTb3VyY2VCeUxvZ2dlcigpIHsNCisgICAgICAgIENvbXBhY3RGb3JtYXR0ZXIgY2YgPSBuZXcgQ29tcGFjdEZvcm1hdHRlcigpOw0KKyAgICAgICAgTG9nUmVjb3JkIHJlY29yZCA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAiIik7DQorICAgICAgICByZWNvcmQuc2V0U291cmNlTWV0aG9kTmFtZShudWxsKTsNCisgICAgICAgIHJlY29yZC5zZXRTb3VyY2VDbGFzc05hbWUobnVsbCk7DQorICAgICAgICByZWNvcmQuc2V0TG9nZ2VyTmFtZShPYmplY3QuY2xhc3MuZ2V0TmFtZSgpKTsNCisgICAgICAgIFN0cmluZyByZXN1bHQgPSBjZi5mb3JtYXRTb3VyY2UocmVjb3JkKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhPYmplY3QuY2xhc3MuZ2V0U2ltcGxlTmFtZSgpLCByZXN1bHQpOw0KKyAgICB9DQorDQorICAgIEBUZXN0KGV4cGVjdGVkID0gTnVsbFBvaW50ZXJFeGNlcHRpb24uY2xhc3MpDQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRTb3VyY2VOdWxsKCkgew0KKyAgICAgICAgQ29tcGFjdEZvcm1hdHRlciBjZiA9IG5ldyBDb21wYWN0Rm9ybWF0dGVyKCk7DQorICAgICAgICBjZi5mb3JtYXRTb3VyY2UoKExvZ1JlY29yZCkgbnVsbCk7DQorICAgICAgICBmYWlsKGNmLnRvU3RyaW5nKCkpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRTb3VyY2VCeUNsYXNzKCkgew0KKyAgICAgICAgQ29tcGFjdEZvcm1hdHRlciBjZiA9IG5ldyBDb21wYWN0Rm9ybWF0dGVyKCk7DQorICAgICAgICBMb2dSZWNvcmQgcmVjb3JkID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICIiKTsNCisgICAgICAgIHJlY29yZC5zZXRTb3VyY2VNZXRob2ROYW1lKG51bGwpOw0KKyAgICAgICAgcmVjb3JkLnNldFNvdXJjZUNsYXNzTmFtZShPYmplY3QuY2xhc3MuZ2V0TmFtZSgpKTsNCisgICAgICAgIHJlY29yZC5zZXRMb2dnZXJOYW1lKCIiKTsNCisgICAgICAgIFN0cmluZyByZXN1bHQgPSBjZi5mb3JtYXRTb3VyY2UocmVjb3JkKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhPYmplY3QuY2xhc3MuZ2V0U2ltcGxlTmFtZSgpLCByZXN1bHQpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRTb3VyY2VCeUNsYXNzQW5kTWV0aG9kKCkgew0KKyAgICAgICAgQ29tcGFjdEZvcm1hdHRlciBjZiA9IG5ldyBDb21wYWN0Rm9ybWF0dGVyKCk7DQorICAgICAgICBMb2dSZWNvcmQgcmVjb3JkID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICIiKTsNCisgICAgICAgIHJlY29yZC5zZXRTb3VyY2VNZXRob2ROYW1lKCJtZXRob2QiKTsNCisgICAgICAgIHJlY29yZC5zZXRTb3VyY2VDbGFzc05hbWUoT2JqZWN0LmNsYXNzLmdldE5hbWUoKSk7DQorICAgICAgICByZWNvcmQuc2V0TG9nZ2VyTmFtZSgiIik7DQorICAgICAgICBTdHJpbmcgcmVzdWx0ID0gY2YuZm9ybWF0U291cmNlKHJlY29yZCk7DQorICAgICAgICBhc3NlcnRGYWxzZShyZXN1bHQsIHJlY29yZC5nZXRTb3VyY2VDbGFzc05hbWUoKS5lcXVhbHMocmVjb3JkLmdldFNvdXJjZU1ldGhvZE5hbWUoKSkpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQsIHJlc3VsdC5zdGFydHNXaXRoKE9iamVjdC5jbGFzcy5nZXRTaW1wbGVOYW1lKCkpKTsNCisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LCByZXN1bHQuZW5kc1dpdGgocmVjb3JkLmdldFNvdXJjZU1ldGhvZE5hbWUoKSkpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRUaHJvd25OdWxsVGhyb3duKCkgew0KKyAgICAgICAgQ29tcGFjdEZvcm1hdHRlciBjZiA9IG5ldyBDb21wYWN0Rm9ybWF0dGVyKCk7DQorICAgICAgICBMb2dSZWNvcmQgcmVjb3JkID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICIiKTsNCisgICAgICAgIFN0cmluZyByZXN1bHQgPSBjZi5mb3JtYXRUaHJvd24ocmVjb3JkKTsNCisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LCByZXN1bHQuc3RhcnRzV2l0aChjZi5mb3JtYXRNZXNzYWdlKHJlY29yZC5nZXRUaHJvd24oKSkpKTsNCisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LCByZXN1bHQuZW5kc1dpdGgoY2YuZm9ybWF0QmFja1RyYWNlKHJlY29yZCkpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdCh0aW1lb3V0ID0gMzAwMDApDQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRUaHJvd25FdmlsVGhyb3duKCkgew0KKyAgICAgICAgTG9nUmVjb3JkIHJlY29yZCA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAiIik7DQorICAgICAgICByZWNvcmQuc2V0VGhyb3duKGNyZWF0ZUV2aWxUaHJvd2FibGUoKSk7DQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIoKTsNCisgICAgICAgIGNmLmZvcm1hdFRocm93bihyZWNvcmQpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRUaHJvd24oKSB7DQorICAgICAgICBFeGNlcHRpb24gZSA9IG5ldyBJT0V4Y2VwdGlvbigiRmFrZSBJL08iKTsNCisgICAgICAgIGUgPSBuZXcgRXhjZXB0aW9uKGUudG9TdHJpbmcoKSwgZSk7DQorICAgICAgICBhc3NlcnROb3ROdWxsKGUuZ2V0TWVzc2FnZSgpLCBlLmdldE1lc3NhZ2UoKSk7DQorDQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIoKTsNCisgICAgICAgIExvZ1JlY29yZCByZWNvcmQgPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgIiIpOw0KKyAgICAgICAgcmVjb3JkLnNldFRocm93bihlKTsNCisgICAgICAgIFN0cmluZyByZXN1bHQgPSBjZi5mb3JtYXRUaHJvd24ocmVjb3JkKTsNCisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LCByZXN1bHQuc3RhcnRzV2l0aChlLmdldENhdXNlKCkuZ2V0Q2xhc3MoKS5nZXRTaW1wbGVOYW1lKCkpKTsNCisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LCByZXN1bHQuY29udGFpbnMoY2YuZm9ybWF0TWVzc2FnZShyZWNvcmQuZ2V0VGhyb3duKCkpKSk7DQorICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCwgcmVzdWx0LmVuZHNXaXRoKGNmLmZvcm1hdEJhY2tUcmFjZShyZWNvcmQpKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEZvcm1hdFRocm93bkxvY2FsaXplZCgpIHsNCisgICAgICAgIC8vc3VuLnNlY3VyaXR5LnByb3ZpZGVyLlBvbGljeVBhcnNlciRQYXJzaW5nRXhjZXB0aW9uDQorICAgICAgICBDb3VudExvY2FsaXplZEV4Y2VwdGlvbiBjbGUgPSBuZXcgQ291bnRMb2NhbGl6ZWRFeGNlcHRpb24oKTsNCisgICAgICAgIENvbXBhY3RGb3JtYXR0ZXIgY2YgPSBuZXcgQ29tcGFjdEZvcm1hdHRlcigpOw0KKyAgICAgICAgTG9nUmVjb3JkIHJlY29yZCA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAiIik7DQorICAgICAgICByZWNvcmQuc2V0VGhyb3duKGNsZSk7DQorICAgICAgICBTdHJpbmcgcmVzdWx0ID0gY2YuZm9ybWF0VGhyb3duKHJlY29yZCk7DQorICAgICAgICBhc3NlcnROb3ROdWxsKHJlc3VsdCwgcmVzdWx0KTsNCisgICAgICAgIGFzc2VydFRydWUoY2xlLmxvY2FsaXplZE1lc3NhZ2UgPiAwKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW5oZXJpdHNGb3JtYXRNZXNzYWdlKCkgew0KKyAgICAgICAgSW5oZXJpdHNGb3JtYXRNZXNzYWdlIGNmID0gbmV3IEluaGVyaXRzRm9ybWF0TWVzc2FnZSgpOw0KKyAgICAgICAgTG9nUmVjb3JkIHJlY29yZCA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAiIik7DQorICAgICAgICByZWNvcmQuc2V0VGhyb3duKG5ldyBUaHJvd2FibGUoKSk7DQorICAgICAgICBTdHJpbmcgcmVzdWx0ID0gY2YuZm9ybWF0VGhyb3duKHJlY29yZCk7DQorICAgICAgICBhc3NlcnROb3ROdWxsKGNmLmdldENsYXNzKCkuZ2V0TmFtZSgpLCByZXN1bHQpOw0KKw0KKyAgICAgICAgcmVzdWx0ID0gY2YuZm9ybWF0RXJyb3IocmVjb3JkKTsNCisgICAgICAgIGFzc2VydE5vdE51bGwoY2YuZ2V0Q2xhc3MoKS5nZXROYW1lKCksIHJlc3VsdCk7DQorICAgIH0NCisNCisgICAgQFRlc3QoZXhwZWN0ZWQgPSBOdWxsUG9pbnRlckV4Y2VwdGlvbi5jbGFzcykNCisgICAgcHVibGljIHZvaWQgdGVzdEZvcm1hdFRocm93bk51bGxSZWNvcmQoKSB7DQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIoKTsNCisgICAgICAgIGNmLmZvcm1hdFRocm93bigoTG9nUmVjb3JkKSBudWxsKTsNCisgICAgICAgIGZhaWwoY2YudG9TdHJpbmcoKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEZvcm1hdFRocmVhZElEKCkgew0KKyAgICAgICAgQ29tcGFjdEZvcm1hdHRlciBjZiA9IG5ldyBDb21wYWN0Rm9ybWF0dGVyKCIlMTAkZCIpOw0KKyAgICAgICAgTG9nUmVjb3JkIHJlY29yZCA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAiIik7DQorICAgICAgICByZWNvcmQuc2V0VGhyZWFkSUQoMTApOw0KKyAgICAgICAgU3RyaW5nIG91dHB1dCA9IGNmLmZvcm1hdChyZWNvcmQpOw0KKyAgICAgICAgU3RyaW5nIGV4cGVjdCA9IExvbmcudG9TdHJpbmcocmVjb3JkLmdldFRocmVhZElEKCkpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdCwgb3V0cHV0KTsNCisNCisgICAgICAgIHJlY29yZC5zZXRUaHJlYWRJRCgtMSk7IC8vTGFyZ2VzdCB2YWx1ZSBmb3IgdGhlIENvbXBhY3RGb3JtYXR0ZXIuDQorICAgICAgICBvdXRwdXQgPSBjZi5mb3JtYXQocmVjb3JkKTsNCisgICAgICAgIGV4cGVjdCA9IExvbmcudG9TdHJpbmcoKDFMIDw8IDMyTCkgLSAxTCk7DQorICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0LCBvdXRwdXQpOw0KKw0KKyAgICAgICAgLy9UZXN0IHRoYXQgZG93bmNhc3Qgd29ya3MgcmlnaHQuDQorICAgICAgICBOdW1iZXIgaWQgPSBjZi5mb3JtYXRUaHJlYWRJRChyZWNvcmQpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKHJlY29yZC5nZXRUaHJlYWRJRCgpLCBpZC5pbnRWYWx1ZSgpKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3QsIExvbmcudG9TdHJpbmcoaWQubG9uZ1ZhbHVlKCkpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdChleHBlY3RlZCA9IE51bGxQb2ludGVyRXhjZXB0aW9uLmNsYXNzKQ0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0VGhyZWFkSUROdWxsKCkgew0KKyAgICAgICAgQ29tcGFjdEZvcm1hdHRlciBjZiA9IG5ldyBDb21wYWN0Rm9ybWF0dGVyKCk7DQorICAgICAgICBjZi5mb3JtYXRUaHJlYWRJRCgoTG9nUmVjb3JkKSBudWxsKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0VGhyZWFkSURSZXR1cm5zTnVsbCgpIHsNCisgICAgICAgIENvbXBhY3RGb3JtYXR0ZXIgY2YgPSBuZXcgVGhyZWFkSURSZXR1cm5zTnVsbCgpOw0KKyAgICAgICAgTG9nUmVjb3JkIHJlY29yZCA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAiIik7DQorICAgICAgICByZWNvcmQuc2V0VGhyZWFkSUQoMTApOw0KKyAgICAgICAgYXNzZXJ0TnVsbChjZi5mb3JtYXRUaHJlYWRJRChyZWNvcmQpKTsNCisgICAgICAgIFN0cmluZyBvdXRwdXQgPSBjZi5mb3JtYXQocmVjb3JkKTsNCisgICAgICAgIGFzc2VydEVxdWFscygibnVsbCIsIG91dHB1dCk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEZvcm1hdEVycm9yKCkgew0KKyAgICAgICAgQ29tcGFjdEZvcm1hdHRlciBjZiA9IG5ldyBDb21wYWN0Rm9ybWF0dGVyKCIlMTEkcyIpOw0KKyAgICAgICAgTG9nUmVjb3JkIHJlY29yZCA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAibWVzc2FnZSIpOw0KKyAgICAgICAgcmVjb3JkLnNldFRocm93bihuZXcgVGhyb3dhYmxlKCJlcnJvciIpKTsNCisgICAgICAgIFN0cmluZyBvdXRwdXQgPSBjZi5mb3JtYXQocmVjb3JkKTsNCisgICAgICAgIGFzc2VydFRydWUob3V0cHV0LnN0YXJ0c1dpdGgocmVjb3JkLmdldFRocm93bigpDQorICAgICAgICAgICAgICAgIC5nZXRDbGFzcygpLmdldFNpbXBsZU5hbWUoKSkpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShvdXRwdXQuZW5kc1dpdGgocmVjb3JkLmdldFRocm93bigpLmdldE1lc3NhZ2UoKSkpOw0KKyAgICB9DQorDQorICAgIEBUZXN0KGV4cGVjdGVkID0gTnVsbFBvaW50ZXJFeGNlcHRpb24uY2xhc3MpDQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRFcnJvck51bGwoKSB7DQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIoKTsNCisgICAgICAgIGNmLmZvcm1hdEVycm9yKChMb2dSZWNvcmQpIG51bGwpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRFcnJvck51bGxNZXNzYWdlKCkgew0KKyAgICAgICAgQ29tcGFjdEZvcm1hdHRlciBjZiA9IG5ldyBDb21wYWN0Rm9ybWF0dGVyKCIlMTEkcyIpOw0KKyAgICAgICAgTG9nUmVjb3JkIHJlY29yZCA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAibWVzc2FnZSIpOw0KKyAgICAgICAgcmVjb3JkLnNldFRocm93bihuZXcgVGhyb3dhYmxlKCkpOw0KKyAgICAgICAgU3RyaW5nIG91dHB1dCA9IGNmLmZvcm1hdChyZWNvcmQpOw0KKyAgICAgICAgYXNzZXJ0Tm90TnVsbChvdXRwdXQpOw0KKyAgICB9DQorDQorICAgIEBUZXN0KGV4cGVjdGVkID0gTnVsbFBvaW50ZXJFeGNlcHRpb24uY2xhc3MpDQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRUaHJvd25NZXNzYWdlQXBwbHlSZXR1cm5zTnVsbCgpIHsNCisgICAgICAgIENvbXBhY3RGb3JtYXR0ZXIgY2YgPSBuZXcgQXBwbHlSZXR1cm5zTnVsbCgpOw0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgaSsrKSB7DQorICAgICAgICAgICAgU3RyaW5nIG91dHB1dCA9IGNmLmZvcm1hdE1lc3NhZ2UobmV3IFRocm93YWJsZSgpKTsNCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoVGhyb3dhYmxlLmNsYXNzLmdldFNpbXBsZU5hbWUoKSwgb3V0cHV0KTsNCisgICAgICAgIH0NCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0TWVzc2FnZUVycm9yKCkgew0KKyAgICAgICAgQ29tcGFjdEZvcm1hdHRlciBjZiA9IG5ldyBDb21wYWN0Rm9ybWF0dGVyKCIlMTIkcyIpOw0KKyAgICAgICAgTG9nUmVjb3JkIHJlY29yZCA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAibWVzc2FnZSIpOw0KKyAgICAgICAgcmVjb3JkLnNldFRocm93bihuZXcgVGhyb3dhYmxlKCJlcnJvciIpKTsNCisgICAgICAgIFN0cmluZyBvdXRwdXQgPSBjZi5mb3JtYXQocmVjb3JkKTsNCisgICAgICAgIGludCB0ID0gb3V0cHV0LmluZGV4T2YocmVjb3JkLmdldFRocm93bigpLmdldENsYXNzKCkuZ2V0U2ltcGxlTmFtZSgpKTsNCisgICAgICAgIGludCBmID0gb3V0cHV0LmluZGV4T2YoJ3wnKTsNCisgICAgICAgIGludCBtID0gb3V0cHV0LmluZGV4T2YocmVjb3JkLmdldFRocm93bigpLmdldE1lc3NhZ2UoKSk7DQorDQorICAgICAgICBhc3NlcnRUcnVlKG91dHB1dCwgdCA+IC0xKTsNCisgICAgICAgIGFzc2VydFRydWUob3V0cHV0LCBtID4gLTEpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShvdXRwdXQsIGYgPiAtMSk7DQorICAgICAgICBhc3NlcnRUcnVlKG91dHB1dCwgdCA8IG0pOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShvdXRwdXQsIHQgPiBmKTsNCisgICAgICAgIGFzc2VydFRydWUob3V0cHV0LCBmIDwgbSk7DQorICAgICAgICBhc3NlcnRUcnVlKG91dHB1dCwgb3V0cHV0LnN0YXJ0c1dpdGgocmVjb3JkLmdldE1lc3NhZ2UoKSkpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRFcnJvck1lc3NhZ2UoKSB7DQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIoIiUxMyRzIik7DQorICAgICAgICBMb2dSZWNvcmQgcmVjb3JkID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICJtZXNzYWdlIik7DQorICAgICAgICByZWNvcmQuc2V0VGhyb3duKG5ldyBUaHJvd2FibGUoImVycm9yIikpOw0KKyAgICAgICAgU3RyaW5nIG91dHB1dCA9IGNmLmZvcm1hdChyZWNvcmQpOw0KKyAgICAgICAgaW50IHQgPSBvdXRwdXQuaW5kZXhPZihyZWNvcmQuZ2V0VGhyb3duKCkuZ2V0Q2xhc3MoKS5nZXRTaW1wbGVOYW1lKCkpOw0KKyAgICAgICAgaW50IGYgPSBvdXRwdXQuaW5kZXhPZignfCcpOw0KKyAgICAgICAgaW50IG0gPSBvdXRwdXQuaW5kZXhPZihyZWNvcmQuZ2V0VGhyb3duKCkuZ2V0TWVzc2FnZSgpKTsNCisNCisgICAgICAgIGFzc2VydFRydWUob3V0cHV0LCB0ID4gLTEpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShvdXRwdXQsIG0gPiAtMSk7DQorICAgICAgICBhc3NlcnRUcnVlKG91dHB1dCwgZiA+IC0xKTsNCisgICAgICAgIGFzc2VydFRydWUob3V0cHV0LCB0IDwgbSk7DQorICAgICAgICBhc3NlcnRUcnVlKG91dHB1dCwgdCA8IGYpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShvdXRwdXQsIGYgPiBtKTsNCisgICAgICAgIGFzc2VydFRydWUob3V0cHV0LCBvdXRwdXQuZW5kc1dpdGgocmVjb3JkLmdldE1lc3NhZ2UoKSkpOw0KKyAgICB9DQorDQorICAgIEBUZXN0KGV4cGVjdGVkID0gTnVsbFBvaW50ZXJFeGNlcHRpb24uY2xhc3MpDQorICAgIHB1YmxpYyB2b2lkIHRlc3RFcnJvckFwcGx5UmV0dXJuc051bGwoKSB7DQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IEFwcGx5UmV0dXJuc051bGwoKTsNCisgICAgICAgIExvZ1JlY29yZCByID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICIiKTsNCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7IGkrKykgew0KKyAgICAgICAgICAgIFN0cmluZyBvdXRwdXQgPSBjZi5mb3JtYXRFcnJvcihyKTsNCisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKG91dHB1dCk7DQorICAgICAgICAgICAgci5zZXRUaHJvd24obmV3IFRocm93YWJsZShJbnRlZ2VyLnRvU3RyaW5nKGkpLCByLmdldFRocm93bigpKSk7DQorICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChjZi5mb3JtYXQocikpOw0KKyAgICAgICAgfQ0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRFeGFtcGxlMSgpIHsNCisgICAgICAgIFN0cmluZyBwID0gIiU3JCMuMTYwcyVuIjsNCisgICAgICAgIExvZ1JlY29yZCByID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICJFbmNvZGluZyBmYWlsZWQuIik7DQorICAgICAgICBSdW50aW1lRXhjZXB0aW9uIG5wZSA9IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOw0KKyAgICAgICAgU3RhY2tUcmFjZUVsZW1lbnQgZnJhbWUgPSBuZXcgU3RhY2tUcmFjZUVsZW1lbnQoImphdmEubGFuZy5TdHJpbmciLA0KKyAgICAgICAgICAgICAgICAiZ2V0Qnl0ZXMiLCAiU3RyaW5nLmphdmEiLCA5MTMpOw0KKyAgICAgICAgbnBlLnNldFN0YWNrVHJhY2UobmV3IFN0YWNrVHJhY2VFbGVtZW50W117ZnJhbWV9KTsNCisgICAgICAgIHIuc2V0VGhyb3duKG5wZSk7DQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIocCk7DQorICAgICAgICBTdHJpbmcgb3V0cHV0ID0gY2YuZm9ybWF0KHIpOw0KKyAgICAgICAgYXNzZXJ0Tm90TnVsbChvdXRwdXQpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRFeGFtcGxlMigpIHsNCisgICAgICAgIFN0cmluZyBwID0gIiU3JCMuMjBzJW4iOw0KKyAgICAgICAgTG9nUmVjb3JkIHIgPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgIkVuY29kaW5nIGZhaWxlZC4iKTsNCisgICAgICAgIFJ1bnRpbWVFeGNlcHRpb24gbnBlID0gbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7DQorICAgICAgICBTdGFja1RyYWNlRWxlbWVudCBmcmFtZSA9IG5ldyBTdGFja1RyYWNlRWxlbWVudCgiamF2YS5sYW5nLlN0cmluZyIsDQorICAgICAgICAgICAgICAgICJnZXRCeXRlcyIsICJTdHJpbmcuamF2YSIsIDkxMyk7DQorICAgICAgICBucGUuc2V0U3RhY2tUcmFjZShuZXcgU3RhY2tUcmFjZUVsZW1lbnRbXXtmcmFtZX0pOw0KKyAgICAgICAgci5zZXRUaHJvd24obnBlKTsNCisgICAgICAgIENvbXBhY3RGb3JtYXR0ZXIgY2YgPSBuZXcgQ29tcGFjdEZvcm1hdHRlcihwKTsNCisgICAgICAgIFN0cmluZyBvdXRwdXQgPSBjZi5mb3JtYXQocik7DQorICAgICAgICBhc3NlcnROb3ROdWxsKG91dHB1dCk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEZvcm1hdEV4YW1wbGUzKCkgew0KKyAgICAgICAgU3RyaW5nIHAgPSAiJTEkdGMgJTIkcyVuJTQkczogJTUkcyU2JHMlbiI7DQorICAgICAgICBMb2dSZWNvcmQgciA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAiRW5jb2RpbmcgZmFpbGVkLiIpOw0KKyAgICAgICAgci5zZXRTb3VyY2VDbGFzc05hbWUoIk15Q2xhc3MiKTsNCisgICAgICAgIHIuc2V0U291cmNlTWV0aG9kTmFtZSgiZmF0YWwiKTsNCisgICAgICAgIHNldEVwb2NoTWlsbGkociwgMTI1ODcyMzc2NDAwMEwpOw0KKyAgICAgICAgUnVudGltZUV4Y2VwdGlvbiBucGUgPSBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsNCisgICAgICAgIFN0YWNrVHJhY2VFbGVtZW50IGZyYW1lID0gbmV3IFN0YWNrVHJhY2VFbGVtZW50KCJqYXZhLmxhbmcuU3RyaW5nIiwNCisgICAgICAgICAgICAgICAgImdldEJ5dGVzIiwgIlN0cmluZy5qYXZhIiwgOTEzKTsNCisgICAgICAgIG5wZS5zZXRTdGFja1RyYWNlKG5ldyBTdGFja1RyYWNlRWxlbWVudFtde2ZyYW1lfSk7DQorICAgICAgICByLnNldFRocm93bihucGUpOw0KKyAgICAgICAgQ29tcGFjdEZvcm1hdHRlciBjZiA9IG5ldyBDb21wYWN0Rm9ybWF0dGVyKHApOw0KKyAgICAgICAgU3RyaW5nIG91dHB1dCA9IGNmLmZvcm1hdChyKTsNCisgICAgICAgIGFzc2VydE5vdE51bGwob3V0cHV0KTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0RXhhbXBsZTQoKSB7DQorICAgICAgICBTdHJpbmcgcCA9ICIlNCRzOiAlMTIkIy4xNjBzJW4iOw0KKyAgICAgICAgTG9nUmVjb3JkIHIgPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgIlVuYWJsZSB0byBzZW5kIG5vdGlmaWNhdGlvbi4iKTsNCisgICAgICAgIHIuc2V0U291cmNlQ2xhc3NOYW1lKCJNeUNsYXNzIik7DQorICAgICAgICByLnNldFNvdXJjZU1ldGhvZE5hbWUoImZhdGFsIik7DQorICAgICAgICBzZXRFcG9jaE1pbGxpKHIsIDEyNTg3MjM3NjQwMDBMKTsNCisNCisgICAgICAgIEV4Y2VwdGlvbiB0ID0gbmV3IFNvY2tldEV4Y2VwdGlvbigiUGVybWlzc2lvbiBkZW5pZWQ6IGNvbm5lY3QiKTsNCisgICAgICAgIHQgPSBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKCJDb3VsZG4ndCBjb25uZWN0IHRvIGhvc3QiLCB0KTsNCisgICAgICAgIHIuc2V0VGhyb3duKHQpOw0KKyAgICAgICAgQ29tcGFjdEZvcm1hdHRlciBjZiA9IG5ldyBDb21wYWN0Rm9ybWF0dGVyKHApOw0KKyAgICAgICAgU3RyaW5nIG91dHB1dCA9IGNmLmZvcm1hdChyKTsNCisgICAgICAgIGFzc2VydE5vdE51bGwob3V0cHV0KTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0RXhhbXBsZTUoKSB7DQorICAgICAgICBTdHJpbmcgcCA9ICJbJTkkZF1bJTEkdFRdWyUxMCRkXVslMiRzXSAlNSRzJW4lNiRzJW4iOw0KKyAgICAgICAgTG9nUmVjb3JkIHIgPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgIlVuYWJsZSB0byBzZW5kIG5vdGlmaWNhdGlvbi4iKTsNCisgICAgICAgIHIuc2V0U2VxdWVuY2VOdW1iZXIoMTI1KTsNCisgICAgICAgIHIuc2V0VGhyZWFkSUQoMzgpOw0KKyAgICAgICAgci5zZXRTb3VyY2VDbGFzc05hbWUoIk15Q2xhc3MiKTsNCisgICAgICAgIHIuc2V0U291cmNlTWV0aG9kTmFtZSgiZmF0YWwiKTsNCisgICAgICAgIHNldEVwb2NoTWlsbGkociwgMTI0ODIwMzUwMjQ0OUwpOw0KKw0KKyAgICAgICAgRXhjZXB0aW9uIHQgPSBuZXcgU29ja2V0RXhjZXB0aW9uKCJQZXJtaXNzaW9uIGRlbmllZDogY29ubmVjdCIpOw0KKw0KKyAgICAgICAgU3RhY2tUcmFjZUVsZW1lbnQgZnJhbWUgPSBuZXcgU3RhY2tUcmFjZUVsZW1lbnQoDQorICAgICAgICAgICAgICAgICJjb20uc3VuLm1haWwuc210cC5TTVRQVHJhbnNwb3J0IiwNCisgICAgICAgICAgICAgICAgIm9wZW5TZXJ2ZXIiLCAiU01UUFRyYW5zcG9ydC5qYXZhIiwgMTk0OSk7DQorICAgICAgICB0LnNldFN0YWNrVHJhY2UobmV3IFN0YWNrVHJhY2VFbGVtZW50W117ZnJhbWV9KTsNCisNCisgICAgICAgIHQgPSBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKCJDb3VsZG4ndCBjb25uZWN0IHRvIGhvc3QiLCB0KTsNCisgICAgICAgIHIuc2V0VGhyb3duKHQpOw0KKyAgICAgICAgQ29tcGFjdEZvcm1hdHRlciBjZiA9IG5ldyBDb21wYWN0Rm9ybWF0dGVyKHApOw0KKyAgICAgICAgU3RyaW5nIG91dHB1dCA9IGNmLmZvcm1hdChyKTsNCisgICAgICAgIGFzc2VydE5vdE51bGwob3V0cHV0KTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0SWxsZWdhbFBhdHRlcm4oKSB7DQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGYgPSBuZXcgQ29tcGFjdEZvcm1hdHRlcigiJTEkI3RjIik7DQorICAgICAgICB0cnkgew0KKyAgICAgICAgICAgIGYuZm9ybWF0KG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAiIikpOw0KKyAgICAgICAgICAgIGZhaWwoIkV4cGVjdGVkIGZvcm1hdCBleGNlcHRpb24uIik7DQorICAgICAgICB9IGNhdGNoIChqYXZhLnV0aWwuSWxsZWdhbEZvcm1hdEV4Y2VwdGlvbiBleHBlY3QpIHsNCisgICAgICAgIH0NCisgICAgfQ0KKw0KKyAgICBAVGVzdChleHBlY3RlZCA9IE51bGxQb2ludGVyRXhjZXB0aW9uLmNsYXNzKQ0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0QXBwbHlSZXR1cm5zTnVsbCgpIHsNCisgICAgICAgIENvbXBhY3RGb3JtYXR0ZXIgY2YgPSBuZXcgQXBwbHlSZXR1cm5zTnVsbCgpOw0KKyAgICAgICAgTG9nUmVjb3JkIHIgPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgIiIpOw0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgaSsrKSB7DQorICAgICAgICAgICAgU3RyaW5nIG91dHB1dCA9IGNmLmZvcm1hdChyKTsNCisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKG91dHB1dCk7DQorICAgICAgICAgICAgci5zZXRUaHJvd24obmV3IFRocm93YWJsZShJbnRlZ2VyLnRvU3RyaW5nKGkpLCByLmdldFRocm93bigpKSk7DQorICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChjZi5mb3JtYXQocikpOw0KKyAgICAgICAgfQ0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRCYWNrVHJhY2UoKSB7DQorICAgICAgICBFeGNlcHRpb24gZSA9IG5ldyBJT0V4Y2VwdGlvbigiRmFrZSBJL08iKTsNCisgICAgICAgIGUgPSBuZXcgRXhjZXB0aW9uKGUudG9TdHJpbmcoKSwgZSk7DQorICAgICAgICBhc3NlcnROb3ROdWxsKGUuZ2V0TWVzc2FnZSgpLCBlLmdldE1lc3NhZ2UoKSk7DQorDQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIoIiUxNCRzIik7DQorICAgICAgICBMb2dSZWNvcmQgcmVjb3JkID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICIiKTsNCisgICAgICAgIHJlY29yZC5zZXRUaHJvd24oZSk7DQorDQorICAgICAgICBTdHJpbmcgcmVzdWx0ID0gY2YuZm9ybWF0QmFja1RyYWNlKHJlY29yZCk7DQorICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCwgcmVzdWx0LnN0YXJ0c1dpdGgoIkNvbXBhY3RGb3JtYXR0ZXJUZXN0IikpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQsIHJlc3VsdC5jb250YWlucygidGVzdEZvcm1hdEJhY2tUcmFjZSIpKTsNCisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LCBDaGFyYWN0ZXIuaXNEaWdpdChyZXN1bHQuY2hhckF0KHJlc3VsdC5sZW5ndGgoKSAtIDIpKSk7DQorICAgICAgICBhc3NlcnRGYWxzZShyZXN1bHQsIHJlc3VsdC5jb250YWlucygiLmphdmEiKSk7DQorICAgICAgICBhc3NlcnRFcXVhbHMocmVzdWx0LCBjZi5mb3JtYXQocmVjb3JkKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QoZXhwZWN0ZWQgPSBOdWxsUG9pbnRlckV4Y2VwdGlvbi5jbGFzcykNCisgICAgcHVibGljIHZvaWQgdGVzdEJhY2tUcmFjZUFwcGx5UmV0dXJuc051bGwoKSB7DQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IEFwcGx5UmV0dXJuc051bGwoKTsNCisgICAgICAgIExvZ1JlY29yZCByID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICIiKTsNCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7IGkrKykgew0KKyAgICAgICAgICAgIFN0cmluZyBvdXRwdXQgPSBjZi5mb3JtYXRCYWNrVHJhY2Uocik7DQorICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChvdXRwdXQpOw0KKyAgICAgICAgICAgIHIuc2V0VGhyb3duKG5ldyBUaHJvd2FibGUoSW50ZWdlci50b1N0cmluZyhpKSwgci5nZXRUaHJvd24oKSkpOw0KKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoY2YuZm9ybWF0KHIpKTsNCisgICAgICAgIH0NCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0QmFja1RyYWNlVW5rbm93bigpIHsNCisgICAgICAgIEV4Y2VwdGlvbiBlID0gbmV3IElPRXhjZXB0aW9uKCJGYWtlIEkvTyIpOw0KKyAgICAgICAgZS5zZXRTdGFja1RyYWNlKG5ldyBTdGFja1RyYWNlRWxlbWVudFtdew0KKyAgICAgICAgICAgIG5ldyBTdGFja1RyYWNlRWxlbWVudChDb21wYWN0Rm9ybWF0dGVyVGVzdC5jbGFzcy5nZXROYW1lKCksDQorICAgICAgICAgICAgInRlc3RGb3JtYXRCYWNrVHJhY2UiLCBudWxsLCAtMil9KTsNCisgICAgICAgIGFzc2VydE5vdE51bGwoZS5nZXRNZXNzYWdlKCksIGUuZ2V0TWVzc2FnZSgpKTsNCisNCisgICAgICAgIENvbXBhY3RGb3JtYXR0ZXIgY2YgPSBuZXcgQ29tcGFjdEZvcm1hdHRlcigpOw0KKyAgICAgICAgTG9nUmVjb3JkIHJlY29yZCA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAiIik7DQorICAgICAgICByZWNvcmQuc2V0VGhyb3duKGUpOw0KKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IGNmLmZvcm1hdEJhY2tUcmFjZShyZWNvcmQpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQsIHJlc3VsdC5zdGFydHNXaXRoKCJDb21wYWN0Rm9ybWF0dGVyVGVzdCIpKTsNCisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LCByZXN1bHQuY29udGFpbnMoInRlc3RGb3JtYXRCYWNrVHJhY2UiKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEZvcm1hdEJhY2tUcmFjZVB1bnQoKSB7DQorICAgICAgICBmaW5hbCBDbGFzczw/PiBrID0gQ29sbGVjdGlvbnMuY2xhc3M7DQorICAgICAgICBFeGNlcHRpb24gZSA9IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiRmFrZSBOUEUiKTsNCisgICAgICAgIGUuc2V0U3RhY2tUcmFjZShuZXcgU3RhY2tUcmFjZUVsZW1lbnRbXXsNCisgICAgICAgICAgICBuZXcgU3RhY2tUcmFjZUVsZW1lbnQoay5nZXROYW1lKCksICJuZXdTZXRGcm9tTWFwIiwgbnVsbCwgMzg3OCl9KTsNCisgICAgICAgIGFzc2VydE5vdE51bGwoZS5nZXRNZXNzYWdlKCksIGUuZ2V0TWVzc2FnZSgpKTsNCisNCisgICAgICAgIENvbXBhY3RGb3JtYXR0ZXIgY2YgPSBuZXcgQ29tcGFjdEZvcm1hdHRlcigpOw0KKyAgICAgICAgTG9nUmVjb3JkIHJlY29yZCA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAiIik7DQorICAgICAgICByZWNvcmQuc2V0VGhyb3duKGUpOw0KKyAgICAgICAgU3RyaW5nIHJlc3VsdCA9IGNmLmZvcm1hdEJhY2tUcmFjZShyZWNvcmQpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQsIHJlc3VsdC5zdGFydHNXaXRoKGsuZ2V0U2ltcGxlTmFtZSgpKSk7DQorICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCwgcmVzdWx0LmNvbnRhaW5zKCJuZXdTZXRGcm9tTWFwIikpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRCYWNrVHJhY2VDaGFpblB1bnQoKSB7DQorICAgICAgICBmaW5hbCBDbGFzczw/PiBrID0gQ29sbGVjdGlvbnMuY2xhc3M7DQorICAgICAgICBUaHJvd2FibGUgZSA9IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiRmFrZSBOUEUiKTsNCisgICAgICAgIGUuc2V0U3RhY2tUcmFjZShuZXcgU3RhY2tUcmFjZUVsZW1lbnRbMF0pOw0KKyAgICAgICAgZSA9IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOw0KKyAgICAgICAgZS5zZXRTdGFja1RyYWNlKG5ldyBTdGFja1RyYWNlRWxlbWVudFtdew0KKyAgICAgICAgICAgIG5ldyBTdGFja1RyYWNlRWxlbWVudChrLmdldE5hbWUoKSwgIm5ld1NldEZyb21NYXAiLCBudWxsLCAzODc4KX0pOw0KKyAgICAgICAgYXNzZXJ0Tm90TnVsbChlLmdldE1lc3NhZ2UoKSwgZS5nZXRNZXNzYWdlKCkpOw0KKw0KKyAgICAgICAgQ29tcGFjdEZvcm1hdHRlciBjZiA9IG5ldyBDb21wYWN0Rm9ybWF0dGVyKCk7DQorICAgICAgICBMb2dSZWNvcmQgcmVjb3JkID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICIiKTsNCisgICAgICAgIHJlY29yZC5zZXRUaHJvd24oZSk7DQorICAgICAgICBTdHJpbmcgcmVzdWx0ID0gY2YuZm9ybWF0QmFja1RyYWNlKHJlY29yZCk7DQorICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdCwgcmVzdWx0LnN0YXJ0c1dpdGgoay5nZXRTaW1wbGVOYW1lKCkpKTsNCisgICAgICAgIGFzc2VydFRydWUocmVzdWx0LCByZXN1bHQuY29udGFpbnMoIm5ld1NldEZyb21NYXAiKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QoZXhwZWN0ZWQgPSBOdWxsUG9pbnRlckV4Y2VwdGlvbi5jbGFzcykNCisgICAgcHVibGljIHZvaWQgdGVzdEZvcm1hdEJhY2tUcmFjZU51bGwoKSB7DQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIoKTsNCisgICAgICAgIGNmLmZvcm1hdEJhY2tUcmFjZSgoTG9nUmVjb3JkKSBudWxsKTsNCisgICAgICAgIGZhaWwoY2YudG9TdHJpbmcoKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QodGltZW91dCA9IDMwMDAwKQ0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0QmFja1RyYWNlRXZpbCgpIHsNCisgICAgICAgIExvZ1JlY29yZCByZWNvcmQgPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgIiIpOw0KKyAgICAgICAgcmVjb3JkLnNldFRocm93bihjcmVhdGVFdmlsVGhyb3dhYmxlKCkpOw0KKyAgICAgICAgQ29tcGFjdEZvcm1hdHRlciBjZiA9IG5ldyBDb21wYWN0Rm9ybWF0dGVyKCk7DQorICAgICAgICBjZi5mb3JtYXRCYWNrVHJhY2UocmVjb3JkKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0QXBwbHkoKSB7DQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIoKTsNCisgICAgICAgIGFzc2VydE51bGwoY2YuYXBwbHkoKFRocm93YWJsZSkgbnVsbCkpOw0KKw0KKyAgICAgICAgZmluYWwgVGhyb3dhYmxlIHQgPSBuZXcgVGhyb3dhYmxlKCk7DQorICAgICAgICBUaHJvd2FibGUgZSA9IGNmLmFwcGx5KHQpOw0KKyAgICAgICAgYXNzZXJ0U2FtZSh0LCBlKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0QXBwbHlOdWxsKCkgew0KKyAgICAgICAgYXNzZXJ0TnVsbChuZXcgQ29tcGFjdEZvcm1hdHRlcigpLmFwcGx5KG51bGwpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdCh0aW1lb3V0ID0gMzAwMDApDQorICAgIHB1YmxpYyB2b2lkIHRlc3RBcHBseUV2aWwoKSB7DQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIoKTsNCisgICAgICAgIGFzc2VydE5vdE51bGwoY2YuYXBwbHkoY3JlYXRlRXZpbFRocm93YWJsZSgpKSk7DQorICAgIH0NCisNCisgICAgcHJpdmF0ZSBUaHJvd2FibGUgY3JlYXRlRXZpbFRocm93YWJsZSgpIHsNCisgICAgICAgIFRocm93YWJsZSB0aGlyZCA9IG5ldyBUaHJvd2FibGUoKTsNCisgICAgICAgIFRocm93YWJsZSBzZWNvbmQgPSBuZXcgVGhyb3dhYmxlKHRoaXJkKTsNCisgICAgICAgIFRocm93YWJsZSBmaXJzdCA9IG5ldyBUaHJvd2FibGUoc2Vjb25kKTsNCisgICAgICAgIHJldHVybiB0aGlyZC5pbml0Q2F1c2UoZmlyc3QpOyAgLy8gUHVyZSBldmlsLg0KKyAgICB9DQorDQorICAgIEBUZXN0KGV4cGVjdGVkID0gTnVsbFBvaW50ZXJFeGNlcHRpb24uY2xhc3MpDQorICAgIHB1YmxpYyB2b2lkIHRlc3RJZ25vcmVOdWxsKCkgew0KKyAgICAgICAgQ29tcGFjdEZvcm1hdHRlciBjZiA9IG5ldyBDb21wYWN0Rm9ybWF0dGVyKCk7DQorICAgICAgICBjZi5pZ25vcmUoKFN0YWNrVHJhY2VFbGVtZW50KSBudWxsKTsNCisgICAgICAgIGZhaWwoY2YudG9TdHJpbmcoKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdElnbm9yZUtub3duQ2xhc3MoKSB7DQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIoKTsNCisgICAgICAgIFN0cmluZyBuID0gY2YuZ2V0Q2xhc3MoKS5nZXROYW1lKCk7DQorICAgICAgICBTdHJpbmcgZiA9IG4uY29uY2F0KCIuamF2YSIpOw0KKyAgICAgICAgU3RhY2tUcmFjZUVsZW1lbnQgcyA9IG5ldyBTdGFja1RyYWNlRWxlbWVudChuLCAiZm9ybWF0IiwgZiwgMjApOw0KKyAgICAgICAgYXNzZXJ0RmFsc2Uocy50b1N0cmluZygpLCBjZi5pZ25vcmUocykpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RJZ25vcmVVbmtub3duQ2xhc3MoKSB7DQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIoKTsNCisgICAgICAgIFN0cmluZyBuID0gVU5LTk9XTl9DTEFTU19OQU1FOw0KKyAgICAgICAgU3RyaW5nIGYgPSBuLmNvbmNhdCgiLmphdmEiKTsNCisgICAgICAgIFN0YWNrVHJhY2VFbGVtZW50IHMgPSBuZXcgU3RhY2tUcmFjZUVsZW1lbnQobiwgImZvcm1hdCIsIGYsIDIwKTsNCisgICAgICAgIGFzc2VydEZhbHNlKHMudG9TdHJpbmcoKSwgY2YuaWdub3JlKHMpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SWdub3JlUHJpdmF0ZUlubmVyQ2xhc3MoKSB7DQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIoKTsNCisgICAgICAgIFN0cmluZyBuID0gQXJyYXlzLmFzTGlzdCgiZm9vIiwgImJhciIsICJiYXoiKS5nZXRDbGFzcygpLmdldE5hbWUoKTsNCisgICAgICAgIGFzc2VydFRydWUobiwgbi5jb250YWlucygiJCIpKTsNCisNCisgICAgICAgIFN0cmluZyBmID0gbi5jb25jYXQoIi5qYXZhIik7DQorICAgICAgICBTdGFja1RyYWNlRWxlbWVudCBzID0gbmV3IFN0YWNrVHJhY2VFbGVtZW50KG4sICJzaXplIiwgZiwgMjApOw0KKyAgICAgICAgYXNzZXJ0RmFsc2Uocy50b1N0cmluZygpLCBjZi5pZ25vcmUocykpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RJZ25vcmVQcml2YXRlU3RhdGljSW5uZXJDbGFzcygpIHsNCisgICAgICAgIENvbXBhY3RGb3JtYXR0ZXIgY2YgPSBuZXcgQ29tcGFjdEZvcm1hdHRlcigpOw0KKyAgICAgICAgU3RyaW5nIG4gPSBDb2xsZWN0aW9ucy5lbXB0eVNldCgpLmdldENsYXNzKCkuZ2V0TmFtZSgpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShuLCBuLmNvbnRhaW5zKCIkIikpOw0KKw0KKyAgICAgICAgU3RyaW5nIGYgPSBuLmNvbmNhdCgiLmphdmEiKTsNCisgICAgICAgIFN0YWNrVHJhY2VFbGVtZW50IHMgPSBuZXcgU3RhY2tUcmFjZUVsZW1lbnQobiwgInNpemUiLCBmLCAyMCk7DQorICAgICAgICBhc3NlcnRGYWxzZShzLnRvU3RyaW5nKCksIGNmLmlnbm9yZShzKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdElnbm9yZVN0YXRpY1V0aWxpdHlDbGFzcygpIHsNCisgICAgICAgIENvbXBhY3RGb3JtYXR0ZXIgY2YgPSBuZXcgQ29tcGFjdEZvcm1hdHRlcigpOw0KKyAgICAgICAgU3RyaW5nIG4gPSBNaW1lVXRpbGl0eS5jbGFzcy5nZXROYW1lKCk7DQorICAgICAgICBTdHJpbmcgZiA9IG4uY29uY2F0KCIuamF2YSIpOw0KKyAgICAgICAgU3RhY2tUcmFjZUVsZW1lbnQgcyA9IG5ldyBTdGFja1RyYWNlRWxlbWVudChuLCAiZW5jb2RlVGV4dCIsIGYsIDQwMCk7DQorICAgICAgICBhc3NlcnRUcnVlKHMudG9TdHJpbmcoKSwgY2YuaWdub3JlKHMpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SWdub3JlU3RhdGljVXRpbGl0eUNsYXNzX1V0aWwoKSB7DQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIoKTsNCisgICAgICAgIFN0cmluZyBuID0gZ2V0Q2xhc3MoKS5nZXROYW1lKCkuY29uY2F0KCJNaW1lVXRpbGl0eSIpOw0KKyAgICAgICAgU3RyaW5nIGYgPSBuLmNvbmNhdCgiLmphdmEiKTsNCisgICAgICAgIFN0YWNrVHJhY2VFbGVtZW50IHMgPSBuZXcgU3RhY2tUcmFjZUVsZW1lbnQobiwgImVuY29kZVRleHQiLCBmLCA0MDApOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShzLnRvU3RyaW5nKCksIGNmLmlnbm9yZShzKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdElnbm9yZVN0YXRpY1V0aWxpdHlDbGFzc19zKCkgew0KKyAgICAgICAgQ29tcGFjdEZvcm1hdHRlciBjZiA9IG5ldyBDb21wYWN0Rm9ybWF0dGVyKCk7DQorICAgICAgICBTdHJpbmcgbiA9IGdldENsYXNzKCkuZ2V0TmFtZSgpLmNvbmNhdCgiQ29sbGVjdGlvbnMiKTsNCisgICAgICAgIFN0cmluZyBmID0gbi5jb25jYXQoIi5qYXZhIik7DQorICAgICAgICBTdGFja1RyYWNlRWxlbWVudCBzID0gbmV3IFN0YWNrVHJhY2VFbGVtZW50KG4sICJuQ29waWVzIiwgZiwgNDAwKTsNCisgICAgICAgIGFzc2VydFRydWUocy50b1N0cmluZygpLCBjZi5pZ25vcmUocykpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RJZ25vcmVTdGF0aWNVdGlsaXR5Q2xhc3NfZXMoKSB7DQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIoKTsNCisgICAgICAgIFN0cmluZyBuID0gZ2V0Q2xhc3MoKS5nZXROYW1lKCkuY29uY2F0KCJQcm9wZXJ0aWVzIik7DQorICAgICAgICBTdHJpbmcgZiA9IG4uY29uY2F0KCIuamF2YSIpOw0KKyAgICAgICAgU3RhY2tUcmFjZUVsZW1lbnQgcyA9IG5ldyBTdGFja1RyYWNlRWxlbWVudChuLCAiZ2V0IiwgZiwgNDAwKTsNCisgICAgICAgIGFzc2VydEZhbHNlKHMudG9TdHJpbmcoKSwgY2YuaWdub3JlKHMpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SWdub3JlU3RhdGljVXRpbGl0eUNsYXNzX1Rocm93YWJsZXMoKSB7DQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIoKTsNCisgICAgICAgIFN0cmluZyBuID0gZ2V0Q2xhc3MoKS5nZXROYW1lKCkuY29uY2F0KCJUaHJvd2FibGVzIik7DQorICAgICAgICBTdHJpbmcgZiA9IG4uY29uY2F0KCIuamF2YSIpOw0KKyAgICAgICAgU3RhY2tUcmFjZUVsZW1lbnQgcyA9IG5ldyBTdGFja1RyYWNlRWxlbWVudChuLCAicHJvcGFnYXRlIiwgZiwgNDAwKTsNCisgICAgICAgIGFzc2VydFRydWUocy50b1N0cmluZygpLCBjZi5pZ25vcmUocykpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RJZ25vcmVTeW50aGV0aWNNZXRob2QoKSB7DQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIoKTsNCisgICAgICAgIFN0cmluZyBuID0gVU5LTk9XTl9DTEFTU19OQU1FOw0KKyAgICAgICAgU3RyaW5nIGYgPSBuLmNvbmNhdCgiLmphdmEiKTsNCisgICAgICAgIFN0YWNrVHJhY2VFbGVtZW50IHMgPSBuZXcgU3RhY2tUcmFjZUVsZW1lbnQobiwgImFjY2VzcyQxMDAiLCBmLCAxMCk7DQorICAgICAgICBhc3NlcnRUcnVlKHMudG9TdHJpbmcoKSwgY2YuaWdub3JlKHMpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SWdub3JlTmF0aXZlTWV0aG9kKCkgew0KKyAgICAgICAgQ29tcGFjdEZvcm1hdHRlciBjZiA9IG5ldyBDb21wYWN0Rm9ybWF0dGVyKCk7DQorICAgICAgICBTdHJpbmcgbiA9IFVOS05PV05fQ0xBU1NfTkFNRTsNCisgICAgICAgIFN0cmluZyBmID0gbi5jb25jYXQoIi5qYXZhIik7DQorICAgICAgICBTdGFja1RyYWNlRWxlbWVudCBzID0gbmV3IFN0YWNrVHJhY2VFbGVtZW50KG4sICJmb28iLCBmLCAtMik7DQorICAgICAgICBhc3NlcnRUcnVlKHMudG9TdHJpbmcoKSwgY2YuaWdub3JlKHMpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SWdub3JlUmVmbGVjdE1ldGhvZCgpIHsNCisgICAgICAgIENvbXBhY3RGb3JtYXR0ZXIgY2YgPSBuZXcgQ29tcGFjdEZvcm1hdHRlcigpOw0KKyAgICAgICAgU3RyaW5nIG4gPSBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2QuY2xhc3MuZ2V0TmFtZSgpOw0KKyAgICAgICAgU3RyaW5nIGYgPSBuLmNvbmNhdCgiLmphdmEiKTsNCisgICAgICAgIFN0YWNrVHJhY2VFbGVtZW50IHMgPSBuZXcgU3RhY2tUcmFjZUVsZW1lbnQobiwgImludm9rZSIsIGYsIDEwKTsNCisgICAgICAgIGFzc2VydFRydWUocy50b1N0cmluZygpLCBjZi5pZ25vcmUocykpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RJZ25vcmVSZWZsZWN0TWV0aG9kQXBpRXJyb3IoKSB7DQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIoKTsNCisgICAgICAgIFN0cmluZyBuID0gImphdmEubGFuZy5yZWZsZWN0LiIuY29uY2F0KGdldENsYXNzKCkuZ2V0TmFtZSgpKTsNCisgICAgICAgIFN0cmluZyBmID0gbi5jb25jYXQoIi5qYXZhIik7DQorICAgICAgICBTdGFja1RyYWNlRWxlbWVudCBzID0gbmV3IFN0YWNrVHJhY2VFbGVtZW50KG4sICJpbnZva2UiLCBmLCAxMCk7DQorICAgICAgICBhc3NlcnRUcnVlKHMudG9TdHJpbmcoKSwgY2YuaWdub3JlKHMpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SWdub3JlUmVmbGVjdE1ldGhvZFN1bkVycm9yKCkgew0KKyAgICAgICAgQ29tcGFjdEZvcm1hdHRlciBjZiA9IG5ldyBDb21wYWN0Rm9ybWF0dGVyKCk7DQorICAgICAgICBTdHJpbmcgbiA9ICJzdW4ucmVmbGVjdC4iLmNvbmNhdChnZXRDbGFzcygpLmdldE5hbWUoKSk7DQorICAgICAgICBTdHJpbmcgZiA9IG4uY29uY2F0KCIuamF2YSIpOw0KKyAgICAgICAgU3RhY2tUcmFjZUVsZW1lbnQgcyA9IG5ldyBTdGFja1RyYWNlRWxlbWVudChuLCAiaW52b2tlIiwgZiwgMTApOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShzLnRvU3RyaW5nKCksIGNmLmlnbm9yZShzKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdElnbm9yZVJlZmxlY3RDb25zdHJ1Y3RvcigpIHsNCisgICAgICAgIENvbXBhY3RGb3JtYXR0ZXIgY2YgPSBuZXcgQ29tcGFjdEZvcm1hdHRlcigpOw0KKyAgICAgICAgU3RyaW5nIG4gPSBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3Rvci5jbGFzcy5nZXROYW1lKCk7DQorICAgICAgICBTdHJpbmcgZiA9IG4uY29uY2F0KCIuamF2YSIpOw0KKyAgICAgICAgU3RhY2tUcmFjZUVsZW1lbnQgcyA9IG5ldyBTdGFja1RyYWNlRWxlbWVudChuLCAibmV3SW5zdGFuY2UiLCBmLCAxMCk7DQorICAgICAgICBhc3NlcnRUcnVlKHMudG9TdHJpbmcoKSwgY2YuaWdub3JlKHMpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SWdub3JlVW5rbm93bkxpbmUoKSB7DQorICAgICAgICBDb21wYWN0Rm9ybWF0dGVyIGNmID0gbmV3IENvbXBhY3RGb3JtYXR0ZXIoKTsNCisgICAgICAgIFN0cmluZyBuID0gVU5LTk9XTl9DTEFTU19OQU1FOw0KKyAgICAgICAgU3RhY2tUcmFjZUVsZW1lbnQgcyA9IG5ldyBTdGFja1RyYWNlRWxlbWVudChuLCAiZm9vIiwgbnVsbCwgLTEpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShzLnRvU3RyaW5nKCksIGNmLmlnbm9yZShzKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdFRvQWx0ZXJuYXRlKCkgew0KKyAgICAgICAgQ29tcGFjdEZvcm1hdHRlciBjZiA9IG5ldyBDb21wYWN0Rm9ybWF0dGVyKCk7DQorICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIGNmLnRvQWx0ZXJuYXRlKExJTkVfU0VQKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdFRvQWx0ZXJuYXRlTnVsbCgpIHsNCisgICAgICAgIENvbXBhY3RGb3JtYXR0ZXIgY2YgPSBuZXcgQ29tcGFjdEZvcm1hdHRlcigpOw0KKyAgICAgICAgYXNzZXJ0TnVsbChjZi50b0FsdGVybmF0ZSgoU3RyaW5nKSBudWxsKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEphdmFNYWlsTGlua2FnZSgpIHRocm93cyBFeGNlcHRpb24gew0KKyAgICAgICAgdGVzdEphdmFNYWlsTGlua2FnZShDb21wYWN0Rm9ybWF0dGVyLmNsYXNzKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0TG9nTWFuYWdlck1vZGlmaWVycygpIHRocm93cyBFeGNlcHRpb24gew0KKyAgICAgICAgdGVzdExvZ01hbmFnZXJNb2RpZmllcnMoQ29tcGFjdEZvcm1hdHRlci5jbGFzcyk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdFdlYmFwcENsYXNzTG9hZGVyRmllbGROYW1lcygpIHRocm93cyBFeGNlcHRpb24gew0KKyAgICAgICAgdGVzdFdlYmFwcENsYXNzTG9hZGVyRmllbGROYW1lcyhDb21wYWN0Rm9ybWF0dGVyLmNsYXNzKTsNCisgICAgfQ0KKw0KKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgcnBhZChTdHJpbmcgcywgaW50IGxlbiwgU3RyaW5nIHApIHsNCisgICAgICAgIGlmIChzLmxlbmd0aCgpIDwgbGVuKSB7DQorICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKGxlbik7DQorICAgICAgICAgICAgc2IuYXBwZW5kKHMpOw0KKyAgICAgICAgICAgIGZvciAoaW50IGkgPSBzYi5sZW5ndGgoKTsgaSA8IGxlbjsgKytpKSB7DQorICAgICAgICAgICAgICAgIHNiLmFwcGVuZChwLCAwLCAxKTsNCisgICAgICAgICAgICB9DQorICAgICAgICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7DQorICAgICAgICB9IGVsc2Ugew0KKyAgICAgICAgICAgIHJldHVybiBzOw0KKyAgICAgICAgfQ0KKyAgICB9DQorDQorICAgIHByaXZhdGUgZmluYWwgc3RhdGljIGNsYXNzIENvdW50TG9jYWxpemVkRXhjZXB0aW9uIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbiB7DQorDQorICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTDsNCisgICAgICAgIHB1YmxpYyBpbnQgbG9jYWxpemVkTWVzc2FnZTsNCisNCisgICAgICAgIENvdW50TG9jYWxpemVkRXhjZXB0aW9uKCkgew0KKyAgICAgICAgICAgIHN1cGVyKCk7DQorICAgICAgICB9DQorDQorICAgICAgICBAT3ZlcnJpZGUNCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0TG9jYWxpemVkTWVzc2FnZSgpIHsNCisgICAgICAgICAgICBsb2NhbGl6ZWRNZXNzYWdlKys7DQorICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldExvY2FsaXplZE1lc3NhZ2UoKTsNCisgICAgICAgIH0NCisgICAgfQ0KKw0KKyAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBjbGFzcyBUb1N0cmluZ0V4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24gew0KKw0KKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7DQorICAgICAgICBwcml2YXRlIGZpbmFsIFN0cmluZyB0b1N0cmluZzsNCisNCisgICAgICAgIFRvU3RyaW5nRXhjZXB0aW9uKFN0cmluZyB0b1N0cmluZywgU3RyaW5nIG1zZykgew0KKyAgICAgICAgICAgIHN1cGVyKG1zZyk7DQorICAgICAgICAgICAgdGhpcy50b1N0cmluZyA9IHRvU3RyaW5nOw0KKyAgICAgICAgfQ0KKw0KKyAgICAgICAgQE92ZXJyaWRlDQorICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgew0KKyAgICAgICAgICAgIHJldHVybiB0b1N0cmluZzsNCisgICAgICAgIH0NCisgICAgfQ0KKw0KKyAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBjbGFzcyBQcmVmaXhFeGNlcHRpb24gZXh0ZW5kcyBSdW50aW1lRXhjZXB0aW9uIHsNCisNCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOw0KKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgcHJlZml4Ow0KKw0KKyAgICAgICAgUHJlZml4RXhjZXB0aW9uKFN0cmluZyBwcmVmaXgsIFN0cmluZyBtc2csIFRocm93YWJsZSBjYXVzZSkgew0KKyAgICAgICAgICAgIHN1cGVyKG1zZywgY2F1c2UpOw0KKyAgICAgICAgICAgIHRoaXMucHJlZml4ID0gcHJlZml4Ow0KKyAgICAgICAgfQ0KKw0KKyAgICAgICAgQE92ZXJyaWRlDQorICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgew0KKyAgICAgICAgICAgIFN0cmluZyBtZXNzYWdlID0gZ2V0TG9jYWxpemVkTWVzc2FnZSgpOw0KKyAgICAgICAgICAgIHJldHVybiAobWVzc2FnZSAhPSBudWxsKSA/IChwcmVmaXggKyAiOiAiICsgbWVzc2FnZSkgOiBwcmVmaXg7DQorICAgICAgICB9DQorICAgIH0NCisNCisgICAgLyoqDQorICAgICAqIEFuIGV4YW1wbGUgb2YgYSBicm9rZW4gaW1wbGVtZW50YXRpb24gb2YgdGhyZWFkIElELg0KKyAgICAgKi8NCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgVGhyZWFkSURSZXR1cm5zTnVsbCBleHRlbmRzIENvbXBhY3RGb3JtYXR0ZXIgew0KKw0KKyAgICAgICAgLyoqDQorICAgICAgICAgKiBQcm9tb3RlIGFjY2VzcyBsZXZlbC4NCisgICAgICAgICAqLw0KKyAgICAgICAgVGhyZWFkSURSZXR1cm5zTnVsbCgpIHsNCisgICAgICAgICAgICBzdXBlcigiJTEwJGQiKTsNCisgICAgICAgIH0NCisNCisgICAgICAgIEBPdmVycmlkZQ0KKyAgICAgICAgcHVibGljIE51bWJlciBmb3JtYXRUaHJlYWRJRChMb2dSZWNvcmQgcmVjb3JkKSB7DQorICAgICAgICAgICAgcmV0dXJuIG51bGw7DQorICAgICAgICB9DQorICAgIH0NCisNCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgSW5oZXJpdHNGb3JtYXRNZXNzYWdlIGV4dGVuZHMgQ29tcGFjdEZvcm1hdHRlciB7DQorDQorICAgICAgICBJbmhlcml0c0Zvcm1hdE1lc3NhZ2UoKSB7DQorICAgICAgICB9DQorDQorICAgICAgICBAT3ZlcnJpZGUNCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZm9ybWF0TWVzc2FnZShUaHJvd2FibGUgdCkgew0KKyAgICAgICAgICAgIHJldHVybiBJbmhlcml0c0Zvcm1hdE1lc3NhZ2UuY2xhc3MuZ2V0TmFtZSgpOw0KKyAgICAgICAgfQ0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBBbiBleGFtcGxlIG9mIGEgYnJva2VuIGltcGxlbWVudGF0aW9uIG9mIGFwcGx5Lg0KKyAgICAgKi8NCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgQXBwbHlSZXR1cm5zTnVsbCBleHRlbmRzIENvbXBhY3RGb3JtYXR0ZXIgew0KKw0KKyAgICAgICAgLyoqDQorICAgICAgICAgKiBUaGUgbnVtYmVyIG9mIHRocm93YWJsZXMuDQorICAgICAgICAgKi8NCisgICAgICAgIHByaXZhdGUgaW50IGNvdW50Ow0KKw0KKyAgICAgICAgLyoqDQorICAgICAgICAgKiBQcm9tb3RlIGFjY2VzcyBsZXZlbC4NCisgICAgICAgICAqLw0KKyAgICAgICAgQXBwbHlSZXR1cm5zTnVsbCgpIHsNCisgICAgICAgICAgICBzdXBlcigiJTYkcyUxMSRzJTE0JHMlNyQjLjE2MHMlOCQjLjE2MHMlMTIkIy4xNjBzJTEzJCMuMTYwcyIpOw0KKyAgICAgICAgfQ0KKw0KKyAgICAgICAgQE92ZXJyaWRlDQorICAgICAgICBwcm90ZWN0ZWQgVGhyb3dhYmxlIGFwcGx5KFRocm93YWJsZSB0KSB7DQorICAgICAgICAgICAgcmV0dXJuICgrK2NvdW50ICYgMSkgPT0gMSA/IHQgOiBudWxsOw0KKyAgICAgICAgfQ0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBBIHByb3BlcnRpZXMgcmVzb3VyY2UgYnVuZGxlIHdpdGggbG9jYWxlLg0KKyAgICAgKi8NCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgTG9jYWxlUmVzb3VyY2UgZXh0ZW5kcyBQcm9wZXJ0eVJlc291cmNlQnVuZGxlIHsNCisNCisgICAgICAgIC8qKg0KKyAgICAgICAgICogVGhlIGxvY2FsZQ0KKyAgICAgICAgICovDQorICAgICAgICBwcml2YXRlIGZpbmFsIExvY2FsZSBsb2NhbGU7DQorDQorICAgICAgICAvKioNCisgICAgICAgICAqIENyZWF0ZXMgdGhlIGxvY2FsZSByZXNvdXJjZS4NCisgICAgICAgICAqDQorICAgICAgICAgKiBAcGFyYW0gcCB0aGUgcHJvcGVydGllcy4NCisgICAgICAgICAqIEBwYXJhbSBsIHRoZSBsb2NhbGUuDQorICAgICAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHRoZXJlIGlzIGEgcHJvYmxlbS4NCisgICAgICAgICAqLw0KKyAgICAgICAgTG9jYWxlUmVzb3VyY2UoUHJvcGVydGllcyBwLCBMb2NhbGUgbCkgdGhyb3dzIElPRXhjZXB0aW9uIHsNCisgICAgICAgICAgICBzdXBlcih0b1N0cmVhbShwKSk7DQorICAgICAgICAgICAgbG9jYWxlID0gbDsNCisgICAgICAgIH0NCisNCisgICAgICAgIHByaXZhdGUgc3RhdGljIElucHV0U3RyZWFtIHRvU3RyZWFtKFByb3BlcnRpZXMgcCkgdGhyb3dzIElPRXhjZXB0aW9uIHsNCisgICAgICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOw0KKyAgICAgICAgICAgIHAuc3RvcmUob3V0LCBMb2NhbGVSZXNvdXJjZS5jbGFzcy5nZXROYW1lKCkpOw0KKyAgICAgICAgICAgIHJldHVybiBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0ob3V0LnRvQnl0ZUFycmF5KCkpOw0KKyAgICAgICAgfQ0KKw0KKyAgICAgICAgQE92ZXJyaWRlDQorICAgICAgICBwdWJsaWMgTG9jYWxlIGdldExvY2FsZSgpIHsNCisgICAgICAgICAgICByZXR1cm4gbG9jYWxlOw0KKyAgICAgICAgfQ0KKyAgICB9DQorfQ0KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvdXRpbC9sb2dnaW5nL0R1cmF0aW9uRmlsdGVyVGVzdC5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL2xvZ2dpbmcvRHVyYXRpb25GaWx0ZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzU5NjgyZQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvdXRpbC9sb2dnaW5nL0R1cmF0aW9uRmlsdGVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsNzQ3IEBACisvKg0KKyAqIENvcHlyaWdodCAoYykgMjAxNSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KKyAqIENvcHlyaWdodCAoYykgMjAxNSwgMjAxOCBKYXNvbiBNZWhyZW5zLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KKyAqDQorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlDQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQNCisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuDQorICoNCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5DQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQ0KKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLA0KKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0DQorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLg0KKyAqDQorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wDQorICovDQorcGFja2FnZSBjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nOw0KKw0KK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZDsNCitpbXBvcnQgamF2YS51dGlsLkFycmF5czsNCitpbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7DQoraW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLio7DQoraW1wb3J0IG9yZy5qdW5pdC4qOw0KK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC4qOw0KKw0KKy8qKg0KKyAqIFRlc3QgY2FzZSBmb3IgdGhlIER1cmF0aW9uRmlsdGVyIHNwZWMuDQorICoNCisgKiBAYXV0aG9yIEphc29uIE1laHJlbnMNCisgKi8NCitwdWJsaWMgY2xhc3MgRHVyYXRpb25GaWx0ZXJUZXN0IGV4dGVuZHMgQWJzdHJhY3RMb2dnaW5nIHsNCisNCisgICAgcHVibGljIER1cmF0aW9uRmlsdGVyVGVzdCgpIHsNCisgICAgfQ0KKw0KKyAgICBAQmVmb3JlQ2xhc3MNCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHNldFVwQ2xhc3MoKSB7DQorICAgICAgICBjaGVja0pWTU9wdGlvbnMoKTsNCisgICAgfQ0KKw0KKyAgICBAQWZ0ZXJDbGFzcw0KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgdGVhckRvd25DbGFzcygpIHsNCisgICAgICAgIGNoZWNrSlZNT3B0aW9ucygpOw0KKyAgICB9DQorDQorICAgIHByaXZhdGUgc3RhdGljIHZvaWQgY2hlY2tKVk1PcHRpb25zKCkgew0KKyAgICAgICAgYXNzZXJ0VHJ1ZShEdXJhdGlvbkZpbHRlclRlc3QuY2xhc3MuZGVzaXJlZEFzc2VydGlvblN0YXR1cygpKTsNCisgICAgICAgIGFzc2VydE51bGwoU3lzdGVtLmdldFByb3BlcnR5KCJqYXZhLnV0aWwubG9nZ2luZy5tYW5hZ2VyIikpOw0KKyAgICAgICAgYXNzZXJ0TnVsbChTeXN0ZW0uZ2V0UHJvcGVydHkoImphdmEudXRpbC5sb2dnaW5nLmNvbmZpZy5jbGFzcyIpKTsNCisgICAgICAgIGFzc2VydE51bGwoU3lzdGVtLmdldFByb3BlcnR5KCJqYXZhLnV0aWwubG9nZ2luZy5jb25maWcuZmlsZSIpKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhMb2dNYW5hZ2VyLmNsYXNzLCBMb2dNYW5hZ2VyLmdldExvZ01hbmFnZXIoKS5nZXRDbGFzcygpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVjbGFyZWRDbGFzc2VzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7DQorICAgICAgICBDbGFzczw/PltdIGRlY2xhcmVkID0gRHVyYXRpb25GaWx0ZXIuY2xhc3MuZ2V0RGVjbGFyZWRDbGFzc2VzKCk7DQorICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLnRvU3RyaW5nKGRlY2xhcmVkKSwgMCwgZGVjbGFyZWQubGVuZ3RoKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2xvbmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsNCisgICAgICAgIER1cmF0aW9uRmlsdGVyRXh0IHNvdXJjZSA9IG5ldyBEdXJhdGlvbkZpbHRlckV4dCgpOw0KKyAgICAgICAgZmluYWwgRmlsdGVyIGNsb25lID0gc291cmNlLmNsb25lKCk7DQorICAgICAgICBhc3NlcnROb3ROdWxsKGNsb25lKTsNCisgICAgICAgIGFzc2VydEZhbHNlKHNvdXJjZSA9PSBjbG9uZSk7DQorICAgICAgICBhc3NlcnRUcnVlKHNvdXJjZS5lcXVhbHMoY2xvbmUpKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhzb3VyY2UuZ2V0Q2xhc3MoKSwgY2xvbmUuZ2V0Q2xhc3MoKSk7DQorDQorICAgICAgICBMb2dSZWNvcmQgciA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuSU5GTywgIiIpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShzb3VyY2UuaXNMb2dnYWJsZShyKSk7DQorICAgICAgICBhc3NlcnRGYWxzZShzb3VyY2UuZXF1YWxzKGNsb25lKSk7DQorICAgICAgICBhc3NlcnRUcnVlKCgoRHVyYXRpb25GaWx0ZXJFeHQpIGNsb25lKS5jbG9uZSgpLmVxdWFscyhjbG9uZSkpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RDbG9uZVN0YXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7DQorICAgICAgICBsb25nIG1pbGxpcyA9IDA7DQorICAgICAgICBmaW5hbCBpbnQgcmVjb3JkcyA9IDEwOw0KKyAgICAgICAgZmluYWwgaW50IGR1cmF0aW9uID0gNSAqIDYwICogMTAwMDsNCisgICAgICAgIExldmVsIGx2bCA9IExldmVsLklORk87DQorICAgICAgICBEdXJhdGlvbkZpbHRlckV4dCBzZiA9IG5ldyBEdXJhdGlvbkZpbHRlckV4dChyZWNvcmRzLCBkdXJhdGlvbik7DQorICAgICAgICBTdHJpbmcgbXNnID0gTG9uZy50b1N0cmluZyhtaWxsaXMpOw0KKyAgICAgICAgTG9nUmVjb3JkIHIgPSBuZXcgTG9nUmVjb3JkKGx2bCwgbXNnKTsNCisNCisgICAgICAgIC8vQWxsb3cNCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVjb3JkczsgaSsrKSB7DQorICAgICAgICAgICAgc2V0RXBvY2hNaWxsaShyLCBtaWxsaXMpOw0KKyAgICAgICAgICAgIGFzc2VydFRydWUoSW50ZWdlci50b1N0cmluZyhpKSwgc2YuaXNMb2dnYWJsZShyKSk7DQorICAgICAgICB9DQorDQorICAgICAgICBGaWx0ZXIgY2xvbmUgPSBzZi5jbG9uZSgpOw0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZWNvcmRzOyBpKyspIHsNCisgICAgICAgICAgICBzZXRFcG9jaE1pbGxpKHIsIG1pbGxpcyk7DQorICAgICAgICAgICAgU3RyaW5nIG0gPSBJbnRlZ2VyLnRvU3RyaW5nKGkpOw0KKyAgICAgICAgICAgIGFzc2VydEZhbHNlKG0sIHNmLmlzTG9nZ2FibGUocikpOw0KKyAgICAgICAgICAgIGFzc2VydFRydWUobSwgY2xvbmUuaXNMb2dnYWJsZShyKSk7DQorICAgICAgICB9DQorDQorICAgICAgICBhc3NlcnRGYWxzZShzZi5pc0xvZ2dhYmxlKHIpKTsNCisgICAgICAgIGFzc2VydEZhbHNlKGNsb25lLmlzTG9nZ2FibGUocikpOw0KKyAgICB9DQorDQorICAgIEBUZXN0KHRpbWVvdXQgPSAxNTAwMCkNCisgICAgcHVibGljIHZvaWQgdGVzdElzTG9nZ2FibGVOb3coKSB0aHJvd3MgRXhjZXB0aW9uIHsNCisgICAgICAgIGZpbmFsIGludCByZWNvcmRzID0gMTA7DQorICAgICAgICBmaW5hbCBpbnQgZHVyYXRpb24gPSAxMDAwOw0KKyAgICAgICAgTGV2ZWwgbHZsID0gTGV2ZWwuSU5GTzsNCisgICAgICAgIER1cmF0aW9uRmlsdGVyIHNmID0gbmV3IER1cmF0aW9uRmlsdGVyKHJlY29yZHMsIGR1cmF0aW9uKTsNCisgICAgICAgIGFzc2VydFRydWUoc2YuaXNMb2dnYWJsZSgpKTsNCisNCisgICAgICAgIExvZ1JlY29yZCByID0gbmV3IExvZ1JlY29yZChsdmwsICIiKTsNCisgICAgICAgIGFzc2VydFRydWUoc2YuaXNMb2dnYWJsZShyKSk7DQorICAgICAgICBhc3NlcnRUcnVlKHNmLmlzTG9nZ2FibGUoKSk7DQorDQorICAgICAgICAvL0FsbG93DQorICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8IHJlY29yZHM7IGkrKykgew0KKyAgICAgICAgICAgIHIgPSBuZXcgTG9nUmVjb3JkKGx2bCwgIiIpOw0KKyAgICAgICAgICAgIFN0cmluZyBtc2cgPSBJbnRlZ2VyLnRvU3RyaW5nKGkpOw0KKyAgICAgICAgICAgIGFzc2VydFRydWUobXNnLCBzZi5pc0xvZ2dhYmxlKCkpOw0KKyAgICAgICAgICAgIGFzc2VydFRydWUobXNnLCBzZi5pc0xvZ2dhYmxlKHIpKTsNCisgICAgICAgIH0NCisNCisgICAgICAgIGFzc2VydEZhbHNlKHNmLmlzTG9nZ2FibGUoKSk7DQorICAgICAgICBhc3NlcnRGYWxzZShzZi5pc0xvZ2dhYmxlKHIpKTsNCisNCisgICAgICAgIHRpY2tNaWxsaShkdXJhdGlvbiArIDEwMCk7IC8vQ29vbCBkb3duIGFuZCBhbGxvdy4NCisNCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVjb3JkczsgaSsrKSB7DQorICAgICAgICAgICAgciA9IG5ldyBMb2dSZWNvcmQobHZsLCAiIik7DQorICAgICAgICAgICAgU3RyaW5nIG1zZyA9IEludGVnZXIudG9TdHJpbmcoaSk7DQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZShtc2csIHNmLmlzTG9nZ2FibGUoKSk7DQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZShtc2csIHNmLmlzTG9nZ2FibGUocikpOw0KKyAgICAgICAgfQ0KKw0KKyAgICAgICAgYXNzZXJ0RmFsc2Uoc2YuaXNMb2dnYWJsZSgpKTsNCisgICAgICAgIGFzc2VydEZhbHNlKHNmLmlzTG9nZ2FibGUocikpOw0KKyAgICB9DQorDQorICAgIEBUZXN0KHRpbWVvdXQgPSAxNTAwMCkNCisgICAgcHVibGljIHZvaWQgdGVzdElzSWRsZU5vdygpIHRocm93cyBFeGNlcHRpb24gew0KKyAgICAgICAgZmluYWwgaW50IHJlY29yZHMgPSAxMDsNCisgICAgICAgIGZpbmFsIGludCBkdXJhdGlvbiA9IDEwMDA7DQorICAgICAgICBMZXZlbCBsdmwgPSBMZXZlbC5JTkZPOw0KKyAgICAgICAgRHVyYXRpb25GaWx0ZXIgc2YgPSBuZXcgRHVyYXRpb25GaWx0ZXIocmVjb3JkcywgZHVyYXRpb24pOw0KKyAgICAgICAgTG9nUmVjb3JkIHIgPSBuZXcgTG9nUmVjb3JkKGx2bCwgIiIpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShzZi5pc0lkbGUoKSk7DQorICAgICAgICBhc3NlcnRUcnVlKHNmLmlzTG9nZ2FibGUocikpOw0KKyAgICAgICAgYXNzZXJ0RmFsc2Uoc2YuaXNJZGxlKCkpOw0KKw0KKyAgICAgICAgLy9BbGxvdw0KKyAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPCByZWNvcmRzOyBpKyspIHsNCisgICAgICAgICAgICByID0gbmV3IExvZ1JlY29yZChsdmwsICIiKTsNCisgICAgICAgICAgICBTdHJpbmcgbXNnID0gSW50ZWdlci50b1N0cmluZyhpKTsNCisgICAgICAgICAgICBhc3NlcnRGYWxzZShtc2csIHNmLmlzSWRsZSgpKTsNCisgICAgICAgICAgICBhc3NlcnRUcnVlKG1zZywgc2YuaXNMb2dnYWJsZShyKSk7DQorICAgICAgICB9DQorDQorICAgICAgICBhc3NlcnRGYWxzZShzZi5pc0lkbGUoKSk7DQorICAgICAgICBhc3NlcnRGYWxzZShzZi5pc0xvZ2dhYmxlKHIpKTsNCisNCisgICAgICAgIHRpY2tNaWxsaShkdXJhdGlvbiArIDEwMCk7IC8vQ29vbCBkb3duIGFuZCBhbGxvdy4NCisNCisgICAgICAgIGFzc2VydFRydWUoc2YuaXNJZGxlKCkpOw0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZWNvcmRzOyBpKyspIHsNCisgICAgICAgICAgICByID0gbmV3IExvZ1JlY29yZChsdmwsICIiKTsNCisgICAgICAgICAgICBTdHJpbmcgbXNnID0gSW50ZWdlci50b1N0cmluZyhpKTsNCisgICAgICAgICAgICBhc3NlcnRUcnVlKG1zZywgc2YuaXNMb2dnYWJsZShyKSk7DQorICAgICAgICAgICAgYXNzZXJ0RmFsc2UobXNnLCBzZi5pc0lkbGUoKSk7DQorICAgICAgICB9DQorDQorICAgICAgICBhc3NlcnRGYWxzZShzZi5pc0lkbGUoKSk7DQorICAgICAgICBhc3NlcnRGYWxzZShzZi5pc0xvZ2dhYmxlKHIpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2F0dXJhdGlvbigpIHsNCisgICAgICAgIGxvbmcgbWlsbGlzID0gMDsNCisgICAgICAgIGZpbmFsIGludCByZWNvcmRzID0gMTA7DQorICAgICAgICBmaW5hbCBpbnQgZHVyYXRpb24gPSA1ICogNjAgKiAxMDAwOw0KKyAgICAgICAgTGV2ZWwgbHZsID0gTGV2ZWwuSU5GTzsNCisgICAgICAgIER1cmF0aW9uRmlsdGVyIHNmID0gbmV3IER1cmF0aW9uRmlsdGVyKHJlY29yZHMsIGR1cmF0aW9uKTsNCisgICAgICAgIExvZ1JlY29yZCByOw0KKw0KKyAgICAgICAgLy9BbGxvdw0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZWNvcmRzOyBpKyspIHsNCisgICAgICAgICAgICArK21pbGxpczsNCisgICAgICAgICAgICByID0gbmV3IExvZ1JlY29yZChsdmwsIExvbmcudG9TdHJpbmcobWlsbGlzKSk7DQorICAgICAgICAgICAgc2V0RXBvY2hNaWxsaShyLCBtaWxsaXMpOw0KKyAgICAgICAgICAgIGFzc2VydFRydWUoSW50ZWdlci50b1N0cmluZyhpKSwgc2YuaXNMb2dnYWJsZShyKSk7DQorICAgICAgICB9DQorDQorICAgICAgICAvL1NhdHVyYXRlLg0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZWNvcmRzICogMTA7IGkrKykgew0KKyAgICAgICAgICAgIHIgPSBuZXcgTG9nUmVjb3JkKGx2bCwgTG9uZy50b1N0cmluZyhtaWxsaXMpKTsNCisgICAgICAgICAgICBzZXRFcG9jaE1pbGxpKHIsIG1pbGxpcyk7DQorICAgICAgICAgICAgYXNzZXJ0RmFsc2UoSW50ZWdlci50b1N0cmluZyhpKSwgc2YuaXNMb2dnYWJsZShyKSk7DQorICAgICAgICB9DQorDQorICAgICAgICAvL0Nvb2wgZG93biBhbmQgYWxsb3cuDQorICAgICAgICBtaWxsaXMgKz0gZHVyYXRpb247DQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlY29yZHM7IGkrKykgew0KKyAgICAgICAgICAgICsrbWlsbGlzOw0KKyAgICAgICAgICAgIHIgPSBuZXcgTG9nUmVjb3JkKGx2bCwgTG9uZy50b1N0cmluZyhtaWxsaXMpKTsNCisgICAgICAgICAgICBzZXRFcG9jaE1pbGxpKHIsIG1pbGxpcyk7DQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZShJbnRlZ2VyLnRvU3RyaW5nKGkpLCBzZi5pc0xvZ2dhYmxlKHIpKTsNCisgICAgICAgIH0NCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2F0dXJhdGVJbnRlcmdyYWwoKSB7DQorICAgICAgICBsb25nIGR1cmF0aW9uID0gMTVMICogNjBMICogMTAwMEw7DQorICAgICAgICBmb3IgKGxvbmcgaSA9IDA7IGkgPD0gZHVyYXRpb24gKiAyOyBpKyspIHsNCisgICAgICAgICAgICB0ZXN0U2F0dXJhdGVJbnRlcmdyYWwoaSwgZHVyYXRpb24pOw0KKyAgICAgICAgfQ0KKyAgICB9DQorDQorICAgIHByaXZhdGUgdm9pZCB0ZXN0U2F0dXJhdGVJbnRlcmdyYWwobG9uZyBtaWxsaXMsIGxvbmcgZHVyYXRpb24pIHsNCisgICAgICAgIGZpbmFsIGludCByZWNvcmRzID0gMTA7DQorICAgICAgICBMZXZlbCBsdmwgPSBMZXZlbC5JTkZPOw0KKyAgICAgICAgRHVyYXRpb25GaWx0ZXIgc2YgPSBuZXcgRHVyYXRpb25GaWx0ZXIocmVjb3JkcywgZHVyYXRpb24pOw0KKyAgICAgICAgTG9nUmVjb3JkIHIgPSBuZXcgTG9nUmVjb3JkKGx2bCwgIiIpOw0KKyAgICAgICAgc2YuaXNMb2dnYWJsZShyKTsgLy9Jbml0IHRoZSBkdXJhdGlvbi4NCisgICAgICAgIG1pbGxpcyArPSAoMiAqIGR1cmF0aW9uKSAtIDE7DQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlY29yZHMgLSAyOyBpKyspIHsNCisgICAgICAgICAgICBzZXRFcG9jaE1pbGxpKHIsIG1pbGxpcyk7DQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZShJbnRlZ2VyLnRvU3RyaW5nKGkpLCBzZi5pc0xvZ2dhYmxlKHIpKTsNCisgICAgICAgIH0NCisNCisgICAgICAgIG1pbGxpcyArPSAxMDA7DQorICAgICAgICBzZXRFcG9jaE1pbGxpKHIsIG1pbGxpcyk7DQorICAgICAgICBhc3NlcnRUcnVlKHNmLmlzTG9nZ2FibGUocikpOw0KKw0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZWNvcmRzIC0gMTsgaSsrKSB7DQorICAgICAgICAgICAgc2V0RXBvY2hNaWxsaShyLCBtaWxsaXMpOw0KKyAgICAgICAgICAgIGFzc2VydEZhbHNlKEludGVnZXIudG9TdHJpbmcoaSksIHNmLmlzTG9nZ2FibGUocikpOw0KKyAgICAgICAgfQ0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RTYXR1cmF0ZVBvc2l0aXZlT3V0T2ZPcmRlcigpIHsNCisgICAgICAgIHRlc3RTYXR1cmF0ZU91dE9mT3JkZXIoSW50ZWdlci5NQVhfVkFMVUUpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RTYXR1cmF0ZU5lZ2F0aXZlT3V0T2ZPcmRlcigpIHsNCisgICAgICAgIHRlc3RTYXR1cmF0ZU91dE9mT3JkZXIoLUludGVnZXIuTUFYX1ZBTFVFKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2F0dXJhdGVPdmVyRmxvd091dE9mT3JkZXIoKSB7DQorICAgICAgICB0ZXN0U2F0dXJhdGVPdXRPZk9yZGVyKExvbmcuTUFYX1ZBTFVFKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2F0dXJhdGVVbmRlckZsb3dPdXRPZk9yZGVyKCkgew0KKyAgICAgICAgdGVzdFNhdHVyYXRlT3V0T2ZPcmRlcigtTG9uZy5NQVhfVkFMVUUpOw0KKyAgICB9DQorDQorICAgIHB1YmxpYyB2b2lkIHRlc3RTYXR1cmF0ZU91dE9mT3JkZXIobG9uZyBtaWxsaXMpIHsNCisgICAgICAgIGZpbmFsIGludCByZWNvcmRzID0gMTA7DQorICAgICAgICBmaW5hbCBpbnQgZHVyYXRpb24gPSA1ICogNjAgKiAxMDAwOw0KKyAgICAgICAgTGV2ZWwgbHZsID0gTGV2ZWwuSU5GTzsNCisgICAgICAgIER1cmF0aW9uRmlsdGVyIHNmID0gbmV3IER1cmF0aW9uRmlsdGVyKHJlY29yZHMsIGR1cmF0aW9uKTsNCisgICAgICAgIExvZ1JlY29yZCByOw0KKw0KKyAgICAgICAgLy9BbGxvdw0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZWNvcmRzOyBpKyspIHsNCisgICAgICAgICAgICByID0gbmV3IExvZ1JlY29yZChsdmwsIExvbmcudG9TdHJpbmcobWlsbGlzKSk7DQorICAgICAgICAgICAgc2V0RXBvY2hNaWxsaShyLCBtaWxsaXMpOw0KKyAgICAgICAgICAgIGFzc2VydFRydWUoSW50ZWdlci50b1N0cmluZyhpKSwgc2YuaXNMb2dnYWJsZShyKSk7DQorICAgICAgICAgICAgLS1taWxsaXM7DQorICAgICAgICB9DQorDQorICAgICAgICAvL1N0aWxsIHNhdHVyYXRlZC4NCisgICAgICAgIG1pbGxpcyArPSBkdXJhdGlvbjsNCisgICAgICAgIGZpbmFsIGxvbmcgcGVhayA9IG1pbGxpczsNCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVjb3JkczsgaSsrKSB7DQorICAgICAgICAgICAgciA9IG5ldyBMb2dSZWNvcmQobHZsLCBMb25nLnRvU3RyaW5nKG1pbGxpcykpOw0KKyAgICAgICAgICAgIHNldEVwb2NoTWlsbGkociwgbWlsbGlzKTsNCisgICAgICAgICAgICBhc3NlcnRGYWxzZShJbnRlZ2VyLnRvU3RyaW5nKGkpLCBzZi5pc0xvZ2dhYmxlKHIpKTsNCisgICAgICAgIH0NCisNCisgICAgICAgIC8vQ29vbCBkb3duIGFuZCBhbGxvdy4NCisgICAgICAgIG1pbGxpcyA9IHBlYWsgKyBkdXJhdGlvbjsNCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVjb3JkczsgaSsrKSB7DQorICAgICAgICAgICAgciA9IG5ldyBMb2dSZWNvcmQobHZsLCBMb25nLnRvU3RyaW5nKG1pbGxpcykpOw0KKyAgICAgICAgICAgIHNldEVwb2NoTWlsbGkociwgbWlsbGlzKTsNCisgICAgICAgICAgICBhc3NlcnRUcnVlKEludGVnZXIudG9TdHJpbmcoaSksIHNmLmlzTG9nZ2FibGUocikpOw0KKyAgICAgICAgICAgICsrbWlsbGlzOw0KKyAgICAgICAgfQ0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RUaW1lU3ByaW5nU2hvcnQoKSB7DQorICAgICAgICB0ZXN0Q2xvY2tBZGp1c3RtZW50KDUgKiA2MCAqIDEwMDAsIDEpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RUaW1lU3ByaW5nTG9uZygpIHsNCisgICAgICAgIHRlc3RDbG9ja0FkanVzdG1lbnQoMjQgKiA2MCAqIDYwICogMTAwMCwgMSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdFRpbWVGYWxsU2hvcnQoKSB7DQorICAgICAgICB0ZXN0Q2xvY2tBZGp1c3RtZW50KDUgKiA2MCAqIDEwMDAsIC0xKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0VGltZUZhbGxMb25nKCkgew0KKyAgICAgICAgdGVzdENsb2NrQWRqdXN0bWVudCgyNCAqIDYwICogNjAgKiAxMDAwLCAtMSk7DQorICAgIH0NCisNCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RDbG9ja0FkanVzdG1lbnQoaW50IHJlY29yZHMsIGludCBzaWdudW0pIHsNCisgICAgICAgIGFzc2VydEZhbHNlKDAgPT0gc2lnbnVtKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhJbnRlZ2VyLnNpZ251bShzaWdudW0pLCBzaWdudW0pOw0KKyAgICAgICAgbG9uZyBtaWxsaXMgPSAwTDsNCisgICAgICAgIER1cmF0aW9uRmlsdGVyIHNmID0gbmV3IER1cmF0aW9uRmlsdGVyKHJlY29yZHMsIHJlY29yZHMpOw0KKyAgICAgICAgTG9nUmVjb3JkIHIgPSBuZXcgTG9nUmVjb3JkKExldmVsLklORk8sICIiKTsNCisgICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDwgKHJlY29yZHMgLyAyKTsgaSsrKSB7DQorICAgICAgICAgICAgc2V0RXBvY2hNaWxsaShyLCArK21pbGxpcyk7DQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZShzZi5pc0xvZ2dhYmxlKHIpKTsNCisgICAgICAgIH0NCisNCisgICAgICAgIG1pbGxpcyArPSBzaWdudW0gKiAoNjBMICogNjBMICogMTAwMEwpOw0KKyAgICAgICAgZm9yIChpbnQgaSA9IChyZWNvcmRzIC8gMik7IGkgPD0gcmVjb3JkczsgaSsrKSB7DQorICAgICAgICAgICAgc2V0RXBvY2hNaWxsaShyLCArK21pbGxpcyk7DQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZShzZi5pc0xvZ2dhYmxlKHIpKTsNCisgICAgICAgIH0NCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHJlZGljdGVkT3ZlcmZsb3coKSB7DQorICAgICAgICBpbnQgcmVjb3JkcyA9IDQ7DQorICAgICAgICBpbnQgZHVyYXRpb24gPSA0Ow0KKyAgICAgICAgRHVyYXRpb25GaWx0ZXIgc2YgPSBuZXcgRHVyYXRpb25GaWx0ZXIocmVjb3JkcywgZHVyYXRpb24pOw0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZWNvcmRzOyBpKyspIHsNCisgICAgICAgICAgICBMb2dSZWNvcmQgciA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuSU5GTywgIiIpOw0KKyAgICAgICAgICAgIHNldEVwb2NoTWlsbGkociwgTG9uZy5NQVhfVkFMVUUpOw0KKyAgICAgICAgICAgIGFzc2VydFRydWUoc2YuaXNMb2dnYWJsZShyKSk7DQorICAgICAgICB9DQorDQorICAgICAgICBMb2dSZWNvcmQgciA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuSU5GTywgIiIpOw0KKyAgICAgICAgc2V0RXBvY2hNaWxsaShyLCBMb25nLk1BWF9WQUxVRSk7DQorICAgICAgICBhc3NlcnRGYWxzZShzZi5pc0xvZ2dhYmxlKHIpKTsNCisNCisgICAgICAgIHIgPSBuZXcgTG9nUmVjb3JkKExldmVsLklORk8sICIiKTsNCisgICAgICAgIHNldEVwb2NoTWlsbGkociwgTG9uZy5NQVhfVkFMVUUgKyBkdXJhdGlvbik7DQorICAgICAgICBhc3NlcnRUcnVlKHNmLmlzTG9nZ2FibGUocikpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RNaWxsaXNOZWdhdGl2ZVNhdHVyYXRpb24oKSB7DQorICAgICAgICBpbnQgcmVjb3JkcyA9IDQ7DQorICAgICAgICBpbnQgZHVyYXRpb24gPSA0Ow0KKyAgICAgICAgRHVyYXRpb25GaWx0ZXIgc2YgPSBuZXcgRHVyYXRpb25GaWx0ZXIocmVjb3JkcywgZHVyYXRpb24pOw0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZWNvcmRzOyBpKyspIHsNCisgICAgICAgICAgICBMb2dSZWNvcmQgciA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuSU5GTywgIiIpOw0KKyAgICAgICAgICAgIHNldEVwb2NoTWlsbGkociwgTG9uZy5NSU5fVkFMVUUpOw0KKyAgICAgICAgICAgIGFzc2VydFRydWUoSW50ZWdlci50b1N0cmluZyhpKSwgc2YuaXNMb2dnYWJsZShyKSk7DQorICAgICAgICB9DQorDQorICAgICAgICBMb2dSZWNvcmQgciA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuSU5GTywgIiIpOw0KKyAgICAgICAgc2V0RXBvY2hNaWxsaShyLCBMb25nLk1JTl9WQUxVRSk7DQorICAgICAgICBhc3NlcnRGYWxzZShzZi5pc0xvZ2dhYmxlKHIpKTsNCisNCisgICAgICAgIHIgPSBuZXcgTG9nUmVjb3JkKExldmVsLklORk8sICIiKTsNCisgICAgICAgIHNldEVwb2NoTWlsbGkociwgTG9uZy5NSU5fVkFMVUUgKyBkdXJhdGlvbik7DQorICAgICAgICBhc3NlcnRUcnVlKHNmLmlzTG9nZ2FibGUocikpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RFeGFjdFJhdGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsNCisgICAgICAgIGxvbmcgbWlsbGlzID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7DQorICAgICAgICBmaW5hbCBpbnQgcmVjb3JkcyA9IDEwMDA7DQorICAgICAgICBmaW5hbCBpbnQgZHVyYXRpb24gPSA1ICogNjAgKiAxMDAwOw0KKyAgICAgICAgTGV2ZWwgbHZsID0gTGV2ZWwuSU5GTzsNCisgICAgICAgIER1cmF0aW9uRmlsdGVyIHNmID0gbmV3IER1cmF0aW9uRmlsdGVyKHJlY29yZHMsIGR1cmF0aW9uKTsNCisgICAgICAgIExvZ1JlY29yZCByOw0KKw0KKyAgICAgICAgaW50IHBlcmlvZCA9IGR1cmF0aW9uIC8gcmVjb3JkczsNCisgICAgICAgIGFzc2VydEVxdWFscyhwZXJpb2QsIChkb3VibGUpIGR1cmF0aW9uIC8gKGRvdWJsZSkgcmVjb3JkcywgMC4wKTsNCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVjb3JkcyAqIHJlY29yZHM7IGkrKykgew0KKyAgICAgICAgICAgIHIgPSBuZXcgTG9nUmVjb3JkKGx2bCwgTG9uZy50b1N0cmluZyhtaWxsaXMpKTsNCisgICAgICAgICAgICBzZXRFcG9jaE1pbGxpKHIsIG1pbGxpcyk7DQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZShJbnRlZ2VyLnRvU3RyaW5nKGkpLCBzZi5pc0xvZ2dhYmxlKHIpKTsNCisgICAgICAgICAgICBtaWxsaXMgKz0gcGVyaW9kOw0KKyAgICAgICAgfQ0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RDZWlsUmF0ZSgpIHRocm93cyBFeGNlcHRpb24gew0KKyAgICAgICAgZG91YmxlIG1pbGxpcyA9IDBMOw0KKyAgICAgICAgZmluYWwgaW50IHJlY29yZHMgPSAzOw0KKyAgICAgICAgZmluYWwgaW50IGR1cmF0aW9uID0gNDA7DQorICAgICAgICBMZXZlbCBsdmwgPSBMZXZlbC5JTkZPOw0KKyAgICAgICAgRHVyYXRpb25GaWx0ZXIgc2YgPSBuZXcgRHVyYXRpb25GaWx0ZXIocmVjb3JkcywgZHVyYXRpb24pOw0KKyAgICAgICAgTG9nUmVjb3JkIHI7DQorDQorICAgICAgICBkb3VibGUgcGVyaW9kID0gZHVyYXRpb24gLyAoZG91YmxlKSByZWNvcmRzOw0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAoZHVyYXRpb24gKiByZWNvcmRzKSAqIDI7IGkrKykgew0KKyAgICAgICAgICAgIHIgPSBuZXcgTG9nUmVjb3JkKGx2bCwgRG91YmxlLnRvU3RyaW5nKG1pbGxpcykpOw0KKyAgICAgICAgICAgIHNldEVwb2NoTWlsbGkociwgKGxvbmcpIG1pbGxpcyk7DQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZShJbnRlZ2VyLnRvU3RyaW5nKGkpLCBzZi5pc0xvZ2dhYmxlKHIpKTsNCisgICAgICAgICAgICBtaWxsaXMgPSBtaWxsaXMgKyBNYXRoLmNlaWwocGVyaW9kKTsNCisgICAgICAgIH0NCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rmxvb3JSYXRlKCkgew0KKyAgICAgICAgZG91YmxlIG1pbGxpcyA9IDAuMGQ7DQorICAgICAgICBmaW5hbCBpbnQgcmVjb3JkcyA9IDMwOw0KKyAgICAgICAgZmluYWwgaW50IGR1cmF0aW9uID0gNDAwOw0KKyAgICAgICAgTGV2ZWwgbHZsID0gTGV2ZWwuSU5GTzsNCisgICAgICAgIER1cmF0aW9uRmlsdGVyIHNmID0gbmV3IER1cmF0aW9uRmlsdGVyKHJlY29yZHMsIGR1cmF0aW9uKTsNCisgICAgICAgIExvZ1JlY29yZCByOw0KKyAgICAgICAgbG9uZyBwZXJpb2QgPSBkdXJhdGlvbiAvIHJlY29yZHM7DQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlY29yZHM7IGkrKykgew0KKyAgICAgICAgICAgIHIgPSBuZXcgTG9nUmVjb3JkKGx2bCwgTG9uZy50b1N0cmluZygobG9uZykgbWlsbGlzKSk7DQorICAgICAgICAgICAgc2V0RXBvY2hNaWxsaShyLCAobG9uZykgbWlsbGlzKTsNCisgICAgICAgICAgICBhc3NlcnRUcnVlKEludGVnZXIudG9TdHJpbmcoaSksIHNmLmlzTG9nZ2FibGUocikpOw0KKyAgICAgICAgICAgIG1pbGxpcyArPSBwZXJpb2Q7DQorICAgICAgICB9DQorDQorICAgICAgICAvL1NhdHVyYXRlZCBmb3IgcmVjb3JkcyArIG9uZS4NCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDw9IHJlY29yZHM7IGkrKykgew0KKyAgICAgICAgICAgIHIgPSBuZXcgTG9nUmVjb3JkKGx2bCwgTG9uZy50b1N0cmluZygobG9uZykgbWlsbGlzKSk7DQorICAgICAgICAgICAgc2V0RXBvY2hNaWxsaShyLCAobG9uZykgbWlsbGlzKTsNCisgICAgICAgICAgICBhc3NlcnRGYWxzZShJbnRlZ2VyLnRvU3RyaW5nKGkpLCBzZi5pc0xvZ2dhYmxlKHIpKTsNCisgICAgICAgICAgICBtaWxsaXMgKz0gcGVyaW9kOw0KKyAgICAgICAgfQ0KKw0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZWNvcmRzOyBpKyspIHsNCisgICAgICAgICAgICByID0gbmV3IExvZ1JlY29yZChsdmwsIExvbmcudG9TdHJpbmcoKGxvbmcpIG1pbGxpcykpOw0KKyAgICAgICAgICAgIHNldEVwb2NoTWlsbGkociwgKGxvbmcpIG1pbGxpcyk7DQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZShJbnRlZ2VyLnRvU3RyaW5nKGkpLCBzZi5pc0xvZ2dhYmxlKHIpKTsNCisgICAgICAgICAgICBtaWxsaXMgKz0gcGVyaW9kOw0KKyAgICAgICAgfQ0KKyAgICB9DQorDQorICAgIHByaXZhdGUgdm9pZCB0ZXN0UmF0ZShsb25nIG1pbGxpcywgbG9uZyByZWNvcmRzLCBsb25nIGR1cmF0aW9uKSB7DQorICAgICAgICBMZXZlbCBsdmwgPSBMZXZlbC5JTkZPOw0KKyAgICAgICAgRHVyYXRpb25GaWx0ZXIgc2YgPSBuZXcgRHVyYXRpb25GaWx0ZXIocmVjb3JkcywgZHVyYXRpb24pOw0KKyAgICAgICAgTG9nUmVjb3JkIHIgPSBuZXcgTG9nUmVjb3JkKGx2bCwgTG9uZy50b1N0cmluZyhtaWxsaXMpKTsNCisNCisgICAgICAgIGZvciAobG9uZyBpID0gMDsgaSA8IHJlY29yZHM7IGkrKykgew0KKyAgICAgICAgICAgIHNldEVwb2NoTWlsbGkociwgbWlsbGlzKTsNCisgICAgICAgICAgICBhc3NlcnRUcnVlKHNmLmlzTG9nZ2FibGUocikpOw0KKyAgICAgICAgfQ0KKw0KKyAgICAgICAgciA9IG5ldyBMb2dSZWNvcmQobHZsLCBMb25nLnRvU3RyaW5nKG1pbGxpcykpOw0KKyAgICAgICAgc2V0RXBvY2hNaWxsaShyLCBtaWxsaXMpOw0KKyAgICAgICAgYXNzZXJ0RmFsc2Uoc2YuaXNMb2dnYWJsZShyKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdE9uZVRlbnRoRXJyb3JSYXRlKCkgew0KKyAgICAgICAgdGVzdFJhdGUoMCwgMTAsIDEpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RPbmVIdW5kcmVkdGhFcnJvclJhdGUoKSB7DQorICAgICAgICB0ZXN0UmF0ZSgwLCAxMDAsIDEpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RPbmVUaG91c2FudGhFcnJvclJhdGUoKSB7DQorICAgICAgICB0ZXN0UmF0ZSgwLCAxMDAwLCAxKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0T25lTWlsbGlvbnRoRXJyb3JSYXRlKCkgew0KKyAgICAgICAgdGVzdFJhdGUoMCwgMTAwMDAwMCwgMSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdFR3b1RvVGhlNTNyZFJhdGUoKSB7DQorICAgICAgICB0ZXN0UmF0ZSgwLCAxLCAxTCA8PCA1M0wpOw0KKyAgICB9DQorDQorICAgIEBJZ25vcmUNCisgICAgcHVibGljIHZvaWQgdGVzdEludGVnZXJNYXhWYWx1ZUJ5VGVuUmF0ZSgpIHsNCisgICAgICAgIC8qKg0KKyAgICAgICAgICogVGhpcyBjYW4gdGFrZSBhIGZldyBtaW51dGVzIHRvIHJ1bi4NCisgICAgICAgICAqLw0KKyAgICAgICAgdGVzdFJhdGUoMCwgSW50ZWdlci5NQVhfVkFMVUUsIDEwKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdChleHBlY3RlZCA9IE51bGxQb2ludGVyRXhjZXB0aW9uLmNsYXNzKQ0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SXNMb2dnYWJsZU51bGwoKSB7DQorICAgICAgICBuZXcgRHVyYXRpb25GaWx0ZXIoKS5pc0xvZ2dhYmxlKChMb2dSZWNvcmQpIG51bGwpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RFcXVhbHMoKSB7DQorICAgICAgICBEdXJhdGlvbkZpbHRlciBvbmUgPSBuZXcgRHVyYXRpb25GaWx0ZXIoKTsNCisgICAgICAgIER1cmF0aW9uRmlsdGVyIHR3byA9IG5ldyBEdXJhdGlvbkZpbHRlcigpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShvbmUuZXF1YWxzKG9uZSkpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZSh0d28uZXF1YWxzKHR3bykpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShvbmUuZXF1YWxzKHR3bykpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZSh0d28uZXF1YWxzKG9uZSkpOw0KKw0KKyAgICAgICAgTG9nUmVjb3JkIHIgPSBuZXcgTG9nUmVjb3JkKExldmVsLklORk8sICIiKTsNCisgICAgICAgIGFzc2VydFRydWUob25lLmlzTG9nZ2FibGUocikpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShvbmUuZXF1YWxzKG9uZSkpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZSh0d28uZXF1YWxzKHR3bykpOw0KKyAgICAgICAgYXNzZXJ0RmFsc2Uob25lLmVxdWFscyh0d28pKTsNCisgICAgICAgIGFzc2VydEZhbHNlKHR3by5lcXVhbHMob25lKSk7DQorICAgICAgICBhc3NlcnRGYWxzZShvbmUuZXF1YWxzKChPYmplY3QpIG51bGwpKTsNCisgICAgICAgIGFzc2VydEZhbHNlKHR3by5lcXVhbHMoKE9iamVjdCkgbnVsbCkpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RIYXNoQ29kZSgpIHsNCisgICAgICAgIER1cmF0aW9uRmlsdGVyIG9uZSA9IG5ldyBEdXJhdGlvbkZpbHRlcigxMCwgMTApOw0KKyAgICAgICAgRHVyYXRpb25GaWx0ZXIgdHdvID0gbmV3IER1cmF0aW9uRmlsdGVyKDEwLCAxMCk7DQorICAgICAgICBEdXJhdGlvbkZpbHRlciB0aHJlZSA9IG5ldyBEdXJhdGlvbkZpbHRlcigzLCAzKTsNCisNCisgICAgICAgIGFzc2VydFRydWUob25lLmhhc2hDb2RlKCkgPT0gdHdvLmhhc2hDb2RlKCkpOw0KKyAgICAgICAgYXNzZXJ0RmFsc2Uob25lLmhhc2hDb2RlKCkgPT0gdGhyZWUuaGFzaENvZGUoKSk7DQorDQorICAgICAgICBMb2dSZWNvcmQgciA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuSU5GTywgIiIpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShvbmUuaXNMb2dnYWJsZShyKSk7DQorICAgICAgICBhc3NlcnRUcnVlKG9uZS5oYXNoQ29kZSgpID09IHR3by5oYXNoQ29kZSgpKTsNCisgICAgICAgIGFzc2VydEZhbHNlKG9uZS5oYXNoQ29kZSgpID09IHRocmVlLmhhc2hDb2RlKCkpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RUb1N0cmluZygpIHsNCisgICAgICAgIHRlc3RUb1N0cmluZyhuZXcgRHVyYXRpb25GaWx0ZXIoKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdFRvU3RyaW5nRXgoKSB7DQorICAgICAgICB0ZXN0VG9TdHJpbmcobmV3IER1cmF0aW9uRmlsdGVyRXh0KCkpOw0KKyAgICB9DQorDQorICAgIHByaXZhdGUgdm9pZCB0ZXN0VG9TdHJpbmcoRHVyYXRpb25GaWx0ZXIgZikgew0KKyAgICAgICAgU3RyaW5nIHMgPSBmLnRvU3RyaW5nKCk7DQorICAgICAgICBhc3NlcnRUcnVlKHMuc3RhcnRzV2l0aChmLmdldENsYXNzKCkuZ2V0TmFtZSgpKSk7DQorICAgICAgICBhc3NlcnRUcnVlKHMuY29udGFpbnMoInJlY29yZHM9IikpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShzLmNvbnRhaW5zKCJkdXJhdGlvbj0iKSk7DQorICAgICAgICBhc3NlcnRUcnVlKHMuY29udGFpbnMoImlkbGU9IikpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShzLmNvbnRhaW5zKCJsb2dnYWJsZT0iKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEphdmFNYWlsTGlua2FnZSgpIHRocm93cyBFeGNlcHRpb24gew0KKyAgICAgICAgdGVzdEphdmFNYWlsTGlua2FnZShEdXJhdGlvbkZpbHRlci5jbGFzcyk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdExvZ01hbmFnZXJNb2RpZmllcnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsNCisgICAgICAgIHRlc3RMb2dNYW5hZ2VyTW9kaWZpZXJzKER1cmF0aW9uRmlsdGVyLmNsYXNzKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0V2ViYXBwQ2xhc3NMb2FkZXJGaWVsZE5hbWVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7DQorICAgICAgICB0ZXN0V2ViYXBwQ2xhc3NMb2FkZXJGaWVsZE5hbWVzKER1cmF0aW9uRmlsdGVyLmNsYXNzKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW5pdFJlY29yZHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsNCisgICAgICAgIHRlc3RJbml0UmVjb3JkcygiMjEwIiwgMjEwKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW5pdFJlY29yZHNaZXJvKCkgdGhyb3dzIEV4Y2VwdGlvbiB7DQorICAgICAgICB0ZXN0SW5pdFJlY29yZHMoIjAiLCAxMDAwKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW5pdFJlY29yZHNOZWdhdGl2ZSgpIHRocm93cyBFeGNlcHRpb24gew0KKyAgICAgICAgdGVzdEluaXRSZWNvcmRzKCItMSIsIDEwMDApOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RJbml0UmVjb3JkSXNvODYwMSgpIHRocm93cyBFeGNlcHRpb24gew0KKyAgICAgICAgaWYgKGhhc0phdmFUaW1lTW9kdWxlKCkpIHsNCisgICAgICAgICAgICB0ZXN0SW5pdFJlY29yZHMoIlBUMzBNIiwgMTAwMCk7DQorICAgICAgICB9DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEluaXREdXJhdGlvbigpIHRocm93cyBFeGNlcHRpb24gew0KKyAgICAgICAgdGVzdEluaXREdXJhdGlvbigiMTAyNCIsIDEwMjQpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RJbml0RHVyYXRpb25aZXJvKCkgdGhyb3dzIEV4Y2VwdGlvbiB7DQorICAgICAgICB0ZXN0SW5pdER1cmF0aW9uKCIwIiwgMTVMICogNjBMICogMTAwMEwpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RJbml0RHVyYXRpb25OZWdhdGl2ZSgpIHRocm93cyBFeGNlcHRpb24gew0KKyAgICAgICAgdGVzdEluaXREdXJhdGlvbigiLTEiLCAxNUwgKiA2MEwgKiAxMDAwTCk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEluaXREdXJhdGlvbkV4cCgpIHRocm93cyBFeGNlcHRpb24gew0KKyAgICAgICAgdGVzdEluaXREdXJhdGlvbigiMTUgKiA2MCAqIDEwMDAiLCAxNUwgKiA2MEwgKiAxMDAwTCk7DQorICAgICAgICB0ZXN0SW5pdER1cmF0aW9uKCIxNSo2MCoxMDAwIiwgMTVMICogNjBMICogMTAwMEwpOw0KKyAgICAgICAgdGVzdEluaXREdXJhdGlvbigiMTVMICogNjBMICogMTAwMEwiLCAxNUwgKiA2MEwgKiAxMDAwTCk7DQorICAgICAgICB0ZXN0SW5pdER1cmF0aW9uKCIxNUwqNjBMKjEwMDBMIiwgMTVMICogNjBMICogMTAwMEwpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RJbml0RHVyYXRpb25FeHBMaWZldGltZSgpIHRocm93cyBFeGNlcHRpb24gew0KKyAgICAgICAgdGVzdEluaXREdXJhdGlvbigiMTI1TCAqIDM2NiAqIDI0TCAqIDYwTCAqIDYwTCAqIDEwMDBMIiwNCisgICAgICAgICAgICAgICAgMTI1TCAqIDM2NiAqIDI0TCAqIDYwTCAqIDYwTCAqIDEwMDBMKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW5pdER1cmF0aW9uRXhwT3ZlcmZsb3coKSB0aHJvd3MgRXhjZXB0aW9uIHsNCisgICAgICAgIHRlc3RJbml0RHVyYXRpb24oTG9uZy5NQVhfVkFMVUUgKyAiICogIg0KKyAgICAgICAgICAgICAgICArIExvbmcuTUFYX1ZBTFVFLCAxNUwgKiA2MEwgKiAxMDAwTCk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEluaXREdXJhdGlvbkV4cEFscGhhKCkgdGhyb3dzIEV4Y2VwdGlvbiB7DQorICAgICAgICB0ZXN0SW5pdER1cmF0aW9uKCIxNUxMICogNjAgKiAxMDAwIiwgMTVMICogNjBMICogMTAwMEwpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RJbml0RHVyYXRpb25FeHBUb29NYW55TXVsdCgpIHRocm93cyBFeGNlcHRpb24gew0KKyAgICAgICAgdGVzdEluaXREdXJhdGlvbigiMTVMICoqIDYwICoqIDEwMDAiLCAxNUwgKiA2MEwgKiAxMDAwTCk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEluaXREdXJhdGlvbkV4cFRyYWlsaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7DQorICAgICAgICB0ZXN0SW5pdER1cmF0aW9uKCIxNSAqIDYwICogMTAwMCoiLCAxNUwgKiA2MEwgKiAxMDAwTCk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEluaXREdXJhdGlvbkV4cFNwYWNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7DQorICAgICAgICB0ZXN0SW5pdER1cmF0aW9uKCIxNSAqIDYwICogMTAwMCogIiwgMTVMICogNjBMICogMTAwMEwpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RJbml0RHVyYXRpb25FeHBMZWFkaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7DQorICAgICAgICB0ZXN0SW5pdER1cmF0aW9uKCIqMTUgKiA2MCAqIDEwMDAiLCAxNUwgKiA2MEwgKiAxMDAwTCk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEluaXREdXJhdGlvbkV4cEFkZCgpIHRocm93cyBFeGNlcHRpb24gew0KKyAgICAgICAgdGVzdEluaXREdXJhdGlvbigiMTUgKyA2MCArIDEwMDAiLCAxNUwgKiA2MEwgKiAxMDAwTCk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEluaXREdXJhdGlvbkV4cERpdmlkZSgpIHRocm93cyBFeGNlcHRpb24gew0KKyAgICAgICAgdGVzdEluaXREdXJhdGlvbigiMTUgLyA2MCAvIDEwMDAiLCAxNUwgKiA2MEwgKiAxMDAwTCk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEluaXREdXJhdGlvbkV4cFN1YnN0cmFjdCgpIHRocm93cyBFeGNlcHRpb24gew0KKyAgICAgICAgdGVzdEluaXREdXJhdGlvbigiMTUgLSA2MCAtIDEwMDAiLCAxNUwgKiA2MEwgKiAxMDAwTCk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEluaXROZWdhdGl2ZUR1cmF0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7DQorICAgICAgICB0ZXN0SW5pdER1cmF0aW9uKCItMTAyNCIsIDE1TCAqIDYwTCAqIDEwMDBMKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW5pdER1cmF0aW9uSXNvODYwMU1zKCkgdGhyb3dzIEV4Y2VwdGlvbiB7DQorICAgICAgICBpZiAoaGFzSmF2YVRpbWVNb2R1bGUoKSkgew0KKyAgICAgICAgICAgIHRlc3RJbml0RHVyYXRpb24oIlBUMC4zNDVTIiwgMzQ1KTsNCisgICAgICAgIH0NCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW5pdER1cmF0aW9uSXNvODYwMVNlYygpIHRocm93cyBFeGNlcHRpb24gew0KKyAgICAgICAgaWYgKGhhc0phdmFUaW1lTW9kdWxlKCkpIHsNCisgICAgICAgICAgICB0ZXN0SW5pdER1cmF0aW9uKCJQVDIwLjM0NVMiLCAoMjBMICogMTAwMEwpICsgMzQ1KTsNCisgICAgICAgIH0NCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW5pdER1cmF0aW9uSXNvODYwMU1pbigpIHRocm93cyBFeGNlcHRpb24gew0KKyAgICAgICAgaWYgKGhhc0phdmFUaW1lTW9kdWxlKCkpIHsNCisgICAgICAgICAgICB0ZXN0SW5pdER1cmF0aW9uKCJQVDMwTSIsIDMwTCAqIDYwTCAqIDEwMDBMKTsNCisgICAgICAgIH0NCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW5pdER1cmF0aW9uSXNvODYwMUhvdXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsNCisgICAgICAgIGlmIChoYXNKYXZhVGltZU1vZHVsZSgpKSB7DQorICAgICAgICAgICAgdGVzdEluaXREdXJhdGlvbigiUFQxMEgiLCAxMEwgKiA2MEwgKiA2MEwgKiAxMDAwTCk7DQorICAgICAgICB9DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEluaXREdXJhdGlvbklzbzg2MDFEYXkoKSB0aHJvd3MgRXhjZXB0aW9uIHsNCisgICAgICAgIGlmIChoYXNKYXZhVGltZU1vZHVsZSgpKSB7DQorICAgICAgICAgICAgdGVzdEluaXREdXJhdGlvbigiUDJEIiwgMkwgKiAyNEwgKiA2MEwgKiA2MEwgKiAxMDAwTCk7DQorICAgICAgICB9DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEluaXREdXJhdGlvbklzbzg2MDFBbGwoKSB0aHJvd3MgRXhjZXB0aW9uIHsNCisgICAgICAgIGlmIChoYXNKYXZhVGltZU1vZHVsZSgpKSB7DQorICAgICAgICAgICAgdGVzdEluaXREdXJhdGlvbigiUDJEVDNINE0yMC4zNDVTIiwgKDJMICogMjRMICogNjBMICogNjBMICogMTAwMEwpDQorICAgICAgICAgICAgICAgICAgICArICgzTCAqIDYwTCAqIDYwTCAqIDEwMDBMKSArICg0TCAqIDYwTCAqIDEwMDBMKQ0KKyAgICAgICAgICAgICAgICAgICAgKyAoKDIwTCAqIDEwMDBMKSArIDM0NSkpOw0KKyAgICAgICAgfQ0KKyAgICB9DQorDQorICAgIHByaXZhdGUgdm9pZCB0ZXN0SW5pdER1cmF0aW9uKFN0cmluZyBkLCBsb25nIGV4cGVjdCkgdGhyb3dzIEV4Y2VwdGlvbiB7DQorICAgICAgICB0ZXN0SW5pdCgiZHVyYXRpb24iLCBkLCBleHBlY3QpOw0KKyAgICB9DQorDQorICAgIHByaXZhdGUgdm9pZCB0ZXN0SW5pdFJlY29yZHMoU3RyaW5nIHIsIGxvbmcgZXhwZWN0KSB0aHJvd3MgRXhjZXB0aW9uIHsNCisgICAgICAgIHRlc3RJbml0KCJyZWNvcmRzIiwgciwgZXhwZWN0KTsNCisgICAgfQ0KKw0KKyAgICBwcml2YXRlIHZvaWQgdGVzdEluaXQoU3RyaW5nIGZpZWxkLCBTdHJpbmcgdmFsdWUsIGxvbmcgZXhwZWN0KSB0aHJvd3MgRXhjZXB0aW9uIHsNCisgICAgICAgIFN0cmluZyBwID0gRHVyYXRpb25GaWx0ZXIuY2xhc3MuZ2V0TmFtZSgpOw0KKyAgICAgICAgUHJvcGVydGllcyBwcm9wcyA9IG5ldyBQcm9wZXJ0aWVzKCk7DQorICAgICAgICBwcm9wcy5wdXQocCArICcuJyArIGZpZWxkLCB2YWx1ZSk7DQorICAgICAgICBMb2dNYW5hZ2VyIG0gPSBMb2dNYW5hZ2VyLmdldExvZ01hbmFnZXIoKTsNCisgICAgICAgIHRyeSB7DQorICAgICAgICAgICAgcmVhZChtLCBwcm9wcyk7DQorICAgICAgICAgICAgRHVyYXRpb25GaWx0ZXIgc2YgPSBuZXcgRHVyYXRpb25GaWx0ZXIoKTsNCisgICAgICAgICAgICBGaWVsZCBmID0gRHVyYXRpb25GaWx0ZXIuY2xhc3MuZ2V0RGVjbGFyZWRGaWVsZChmaWVsZCk7DQorICAgICAgICAgICAgZi5zZXRBY2Nlc3NpYmxlKHRydWUpOw0KKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3QsIGYuZ2V0KHNmKSk7DQorICAgICAgICB9IGZpbmFsbHkgew0KKyAgICAgICAgICAgIG0ucmVzZXQoKTsNCisgICAgICAgIH0NCisgICAgfQ0KKw0KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIER1cmF0aW9uRmlsdGVyRXh0IGV4dGVuZHMgRHVyYXRpb25GaWx0ZXINCisgICAgICAgICAgICBpbXBsZW1lbnRzIENsb25lYWJsZSB7DQorDQorICAgICAgICBwdWJsaWMgRHVyYXRpb25GaWx0ZXJFeHQoKSB7DQorICAgICAgICAgICAgc3VwZXIoKTsNCisgICAgICAgIH0NCisNCisgICAgICAgIHB1YmxpYyBEdXJhdGlvbkZpbHRlckV4dChsb25nIHJlY29yZHMsIGxvbmcgZHVyYXRpb24pIHsNCisgICAgICAgICAgICBzdXBlcihyZWNvcmRzLCBkdXJhdGlvbik7DQorICAgICAgICB9DQorDQorICAgICAgICBAT3ZlcnJpZGUNCisgICAgICAgIHB1YmxpYyBEdXJhdGlvbkZpbHRlckV4dCBjbG9uZSgpIHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiB7DQorICAgICAgICAgICAgcmV0dXJuIChEdXJhdGlvbkZpbHRlckV4dCkgc3VwZXIuY2xvbmUoKTsNCisgICAgICAgIH0NCisgICAgfQ0KK30NCmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3V0aWwvbG9nZ2luZy9Mb2dNYW5hZ2VyUHJvcGVydGllc1Rlc3QuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvdXRpbC9sb2dnaW5nL0xvZ01hbmFnZXJQcm9wZXJ0aWVzVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkwNzJlZWUKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3V0aWwvbG9nZ2luZy9Mb2dNYW5hZ2VyUHJvcGVydGllc1Rlc3QuamF2YQpAQCAtMCwwICsxLDEzODAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDksIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqIENvcHlyaWdodCAoYykgMjAwOSwgMjAxOCBKYXNvbiBNZWhyZW5zLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KK3BhY2thZ2UgY29tLnN1bi5tYWlsLnV0aWwubG9nZ2luZzsKKworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZhLmxhbmcubWFuYWdlbWVudC5Db21waWxhdGlvbk1YQmVhbjsKK2ltcG9ydCBqYXZhLmxhbmcubWFuYWdlbWVudC5NYW5hZ2VtZW50RmFjdG9yeTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC4qOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkNvbXBhcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LlRpbWVVbml0OworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLio7CitpbXBvcnQgamF2YXgubWFpbC4qOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuSW50ZXJuZXRBZGRyZXNzOworaW1wb3J0IG9yZy5qdW5pdC4qOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0Lio7CisKKy8qKgorICogVGVzdCBjYXNlIGZvciB0aGUgTG9nTWFuYWdlclByb3BlcnRpZXMgc3BlYy4KKyAqCisgKiBAYXV0aG9yIEphc29uIE1laHJlbnMKKyAqLworcHVibGljIGNsYXNzIExvZ01hbmFnZXJQcm9wZXJ0aWVzVGVzdCBleHRlbmRzIEFic3RyYWN0TG9nZ2luZyB7CisKKyAgICAvKioKKyAgICAgKiBIb2xkZXIgdXNlZCB0byBpbmplY3QgVGhyb3dhYmxlcyBpbnRvIG90aGVyIEFQSXMuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgVGhyZWFkTG9jYWw8VGhyb3dhYmxlPiBQRU5ESU5HID0gbmV3IFRocmVhZExvY2FsPD4oKTsKKworICAgIEBCZWZvcmVDbGFzcworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRVcENsYXNzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEFzc2VydC5hc3NlcnROdWxsKFN5c3RlbS5nZXRTZWN1cml0eU1hbmFnZXIoKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBmdWxsRmVuY2UoKSB7CisgICAgICAgIExvZ01hbmFnZXIuZ2V0TG9nTWFuYWdlcigpLmdldFByb3BlcnR5KCIiKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGFzc3VtZU5vSml0KCkgeworICAgICAgICBDb21waWxhdGlvbk1YQmVhbiBjID0gTWFuYWdlbWVudEZhY3RvcnkuZ2V0Q29tcGlsYXRpb25NWEJlYW4oKTsKKyAgICAgICAgaWYgKGMgIT0gbnVsbCkgeyAvLy1YaW50CisgICAgICAgICAgICBBc3N1bWUuYXNzdW1lTm9FeGNlcHRpb24obmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgYy5nZXROYW1lKCkgKyAiIG11c3QgYmUgZGlzYWJsZWQuIikpOworICAgICAgICB9CisgICAgfQorCisgICAgQEJlZm9yZQorICAgIHB1YmxpYyB2b2lkIHNldFVwKCkgeworICAgICAgICBmdWxsRmVuY2UoKTsKKyAgICB9CisKKyAgICBAQWZ0ZXIKKyAgICBwdWJsaWMgdm9pZCB0ZWFyRG93bigpIHsKKyAgICAgICAgZnVsbEZlbmNlKCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVjbGFyZWRDbGFzc2VzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIENsYXNzPD8+W10gZGVjbGFyZWQgPSBMb2dNYW5hZ2VyUHJvcGVydGllcy5jbGFzcy5nZXREZWNsYXJlZENsYXNzZXMoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEFycmF5cy50b1N0cmluZyhkZWNsYXJlZCksIDAsIGRlY2xhcmVkLmxlbmd0aCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2hlY2tBY2Nlc3NQcmVzZW50KCkgeworICAgICAgICBMb2dNYW5hZ2VyIG0gPSBMb2dNYW5hZ2VyLmdldExvZ01hbmFnZXIoKTsKKyAgICAgICAgbS5jaGVja0FjY2VzcygpOworICAgICAgICBMb2dNYW5hZ2VyUHJvcGVydGllcy5jaGVja0xvZ01hbmFnZXJBY2Nlc3MoKTsKKworICAgICAgICBMb2dQZXJtU2VjdXJpdHlNYW5hZ2VyIHNtID0gbmV3IExvZ1Blcm1TZWN1cml0eU1hbmFnZXIoKTsKKyAgICAgICAgc20uc2VjdXJlID0gZmFsc2U7CisgICAgICAgIFN5c3RlbS5zZXRTZWN1cml0eU1hbmFnZXIoc20pOworICAgICAgICB0cnkgeworICAgICAgICAgICAgc20uc2VjdXJlID0gdHJ1ZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgbS5jaGVja0FjY2VzcygpOworICAgICAgICAgICAgICAgIGZhaWwobS50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGV4cGVjdCkgeworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIExvZ01hbmFnZXJQcm9wZXJ0aWVzLmNoZWNrTG9nTWFuYWdlckFjY2VzcygpOworICAgICAgICAgICAgICAgIGZhaWwoTG9nTWFuYWdlclByb3BlcnRpZXMuY2xhc3MuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGV4cGVjdCkgeworICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgc20uc2VjdXJlID0gZmFsc2U7CisgICAgICAgICAgICBTeXN0ZW0uc2V0U2VjdXJpdHlNYW5hZ2VyKChTZWN1cml0eU1hbmFnZXIpIG51bGwpOworICAgICAgICB9CisgICAgfQorCisgICAgQElnbm9yZQorICAgIHB1YmxpYyB2b2lkIHRlc3RDaGVja0FjY2Vzc0Fic2VudCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3N1bWVOb0ppdCgpOworICAgICAgICBmaW5hbCBDbGFzczw/PiBrID0gTG9nTWFuYWdlclByb3BlcnRpZXMuY2xhc3M7CisgICAgICAgIGZpbmFsIEZpZWxkIGYgPSBrLmdldERlY2xhcmVkRmllbGQoIkxPR19NQU5BR0VSIik7CisgICAgICAgIEZpZWxkIG1vZCA9IHNldEFjY2Vzc2libGUoZik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaW5hbCBPYmplY3QgbG0gPSBmLmdldChudWxsKTsKKyAgICAgICAgICAgIGYuc2V0KG51bGwsIG51bGwpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBmdWxsRmVuY2UoKTsKKyAgICAgICAgICAgICAgICBMb2dNYW5hZ2VyUHJvcGVydGllcy5jaGVja0xvZ01hbmFnZXJBY2Nlc3MoKTsKKworICAgICAgICAgICAgICAgIExvZ1Blcm1TZWN1cml0eU1hbmFnZXIgc20gPSBuZXcgTG9nUGVybVNlY3VyaXR5TWFuYWdlcigpOworICAgICAgICAgICAgICAgIHNtLnNlY3VyZSA9IGZhbHNlOworICAgICAgICAgICAgICAgIFN5c3RlbS5zZXRTZWN1cml0eU1hbmFnZXIoc20pOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHNtLnNlY3VyZSA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICBMb2dNYW5hZ2VyUHJvcGVydGllcy5jaGVja0xvZ01hbmFnZXJBY2Nlc3MoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZhaWwoTG9nTWFuYWdlclByb3BlcnRpZXMuY2xhc3MuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gZXhwZWN0KSB7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgICAgICBzbS5zZWN1cmUgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLnNldFNlY3VyaXR5TWFuYWdlcigoU2VjdXJpdHlNYW5hZ2VyKSBudWxsKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIGYuc2V0KG51bGwsIGxtKTsKKyAgICAgICAgICAgICAgICBmdWxsRmVuY2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIG1vZC5zZXRJbnQoZiwgZi5nZXRNb2RpZmllcnMoKSB8IE1vZGlmaWVyLkZJTkFMKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEZyb21Mb2dNYW5hZ2VyUHJlc2VudCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgcHJlZml4ID0gTG9nTWFuYWdlclByb3BlcnRpZXNUZXN0LmNsYXNzLmdldE5hbWUoKTsKKyAgICAgICAgTG9nTWFuYWdlciBtYW5hZ2VyID0gTG9nTWFuYWdlci5nZXRMb2dNYW5hZ2VyKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcga2V5ID0gcHJlZml4LmNvbmNhdCgiLmR1bW15Iik7CisgICAgICAgICAgICBTdHJpbmcgdmFsdWUgPSAidmFsdWUiOworICAgICAgICAgICAgU3RyaW5nIGVtcHR5VmFsdWUgPSAiZW1wdHkiOworICAgICAgICAgICAgUHJvcGVydGllcyBwYXJlbnQgPSBuZXcgUHJvcGVydGllcygpOworICAgICAgICAgICAgcGFyZW50LnB1dChrZXksIHZhbHVlKTsKKyAgICAgICAgICAgIHBhcmVudC5wdXQoIiIsIGVtcHR5VmFsdWUpOworCisgICAgICAgICAgICByZWFkKG1hbmFnZXIsIHBhcmVudCk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKExvZ01hbmFnZXJQcm9wZXJ0aWVzLmhhc0xvZ01hbmFnZXIoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHModmFsdWUsIExvZ01hbmFnZXJQcm9wZXJ0aWVzLmZyb21Mb2dNYW5hZ2VyKGtleSkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGVtcHR5VmFsdWUsIExvZ01hbmFnZXJQcm9wZXJ0aWVzLmZyb21Mb2dNYW5hZ2VyKCIiKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBtYW5hZ2VyLnJlc2V0KCk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgTG9nTWFuYWdlclByb3BlcnRpZXMuZnJvbUxvZ01hbmFnZXIoKFN0cmluZykgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCIiKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0KSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBASWdub3JlCisgICAgcHVibGljIHZvaWQgdGVzdEZyb21Mb2dNYW5hZ2VyTnVsbCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3N1bWVOb0ppdCgpOworICAgICAgICB0ZXN0RnJvbUxvZ01hbmFnZXIoKFByb3BlcnRpZXMpIG51bGwpOworICAgIH0KKworICAgIEBJZ25vcmUKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RnJvbUxvZ01hbmFnZXJBYnNlbnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzdW1lTm9KaXQoKTsKKyAgICAgICAgZmluYWwgU3RyaW5nIGNmZ0tleSA9ICJqYXZhLnV0aWwubG9nZ2luZy5jb25maWcuZmlsZSI7CisgICAgICAgIGZpbmFsIENsYXNzPD8+IGsgPSBMb2dNYW5hZ2VyUHJvcGVydGllcy5jbGFzczsKKyAgICAgICAgU3RyaW5nIG9sZCA9IFN5c3RlbS5nZXRQcm9wZXJ0eShjZmdLZXkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgUHJvcGVydGllcyBwcm9wcyA9IG5ldyBQcm9wZXJ0aWVzKCk7CisgICAgICAgICAgICBwcm9wcy5wdXQoIiIsICJlbXB0eSIpOworICAgICAgICAgICAgcHJvcHMucHV0KGsuZ2V0TmFtZSgpLmNvbmNhdCgiLmR1bW15IiksICJ2YWx1ZSIpOworICAgICAgICAgICAgZmluYWwgRmlsZSBmID0gRmlsZS5jcmVhdGVUZW1wRmlsZShrLmdldE5hbWUoKSwgIi5wcm9wZXJ0aWVzIik7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHRyeSAoRmlsZU91dHB1dFN0cmVhbSBvdXQgPSBuZXcgRmlsZU91dHB1dFN0cmVhbShmKSkgeworICAgICAgICAgICAgICAgICAgICBwcm9wcy5zdG9yZShvdXQsICJ0ZXN0RnJvbUxvZ01hbmFnZXJBYnNlbnQiKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgU3lzdGVtLnNldFByb3BlcnR5KGNmZ0tleSwgZi5nZXRBYnNvbHV0ZVBhdGgoKSk7CisgICAgICAgICAgICAgICAgZmluYWwgTWV0aG9kIG0gPSBrLmdldERlY2xhcmVkTWV0aG9kKCJyZWFkQ29uZmlndXJhdGlvbiIpOworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoTW9kaWZpZXIuaXNQcml2YXRlKG0uZ2V0TW9kaWZpZXJzKCkpKTsKKyAgICAgICAgICAgICAgICBtLnNldEFjY2Vzc2libGUodHJ1ZSk7CisgICAgICAgICAgICAgICAgcHJvcHMgPSAoUHJvcGVydGllcykgbS5pbnZva2UobnVsbCk7CisgICAgICAgICAgICAgICAgdGVzdEZyb21Mb2dNYW5hZ2VyKHByb3BzKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShmLnRvU3RyaW5nKCksIGYuZGVsZXRlKCkgfHwgIWYuZXhpc3RzKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKG9sZCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLnNldFByb3BlcnR5KGNmZ0tleSwgb2xkKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLmNsZWFyUHJvcGVydHkoY2ZnS2V5KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0RnJvbUxvZ01hbmFnZXIoUHJvcGVydGllcyBwYXJlbnQpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRUcnVlKExvZ01hbmFnZXJQcm9wZXJ0aWVzLmhhc0xvZ01hbmFnZXIoKSk7CisgICAgICAgIGZpbmFsIENsYXNzPD8+IGsgPSBMb2dNYW5hZ2VyUHJvcGVydGllcy5jbGFzczsKKyAgICAgICAgZmluYWwgRmllbGQgZiA9IGsuZ2V0RGVjbGFyZWRGaWVsZCgiTE9HX01BTkFHRVIiKTsKKyAgICAgICAgRmllbGQgbW9kID0gc2V0QWNjZXNzaWJsZShmKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZ1bGxGZW5jZSgpOworICAgICAgICAgICAgZmluYWwgT2JqZWN0IGxtID0gZi5nZXQobnVsbCk7CisgICAgICAgICAgICBmLnNldChudWxsLCBwYXJlbnQpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBmdWxsRmVuY2UoKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRGYWxzZShMb2dNYW5hZ2VyUHJvcGVydGllcy5oYXNMb2dNYW5hZ2VyKCkpOworICAgICAgICAgICAgICAgIGlmIChwYXJlbnQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBhc3NlcnRGYWxzZShwYXJlbnQuaXNFbXB0eSgpKTsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChNYXAuRW50cnk8T2JqZWN0LCBPYmplY3Q+IGUgOiBwYXJlbnQuZW50cnlTZXQoKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGtleSA9IGUuZ2V0S2V5KCkudG9TdHJpbmcoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB2YWwgPSBMb2dNYW5hZ2VyUHJvcGVydGllcy5mcm9tTG9nTWFuYWdlcihrZXkpOworICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGUuZ2V0VmFsdWUoKSwgdmFsKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydE51bGwoTG9nTWFuYWdlclByb3BlcnRpZXMuZnJvbUxvZ01hbmFnZXIoIiIpKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0TnVsbChMb2dNYW5hZ2VyUHJvcGVydGllcy5mcm9tTG9nTWFuYWdlcigidmFsIikpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIExvZ01hbmFnZXJQcm9wZXJ0aWVzLmZyb21Mb2dNYW5hZ2VyKChTdHJpbmcpIG51bGwpOworICAgICAgICAgICAgICAgICAgICBmYWlsKCIiKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3QpIHsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIGYuc2V0KG51bGwsIGxtKTsKKyAgICAgICAgICAgICAgICBmdWxsRmVuY2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIG1vZC5zZXRJbnQoZiwgZi5nZXRNb2RpZmllcnMoKSB8IE1vZGlmaWVyLkZJTkFMKTsKKyAgICAgICAgICAgIGZ1bGxGZW5jZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SmF2YU1haWxMaW5rYWdlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RKYXZhTWFpbExpbmthZ2UoTG9nTWFuYWdlclByb3BlcnRpZXMuY2xhc3MpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFdlYmFwcENsYXNzTG9hZGVyRmllbGROYW1lcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0V2ViYXBwQ2xhc3NMb2FkZXJGaWVsZE5hbWVzKExvZ01hbmFnZXJQcm9wZXJ0aWVzLmNsYXNzKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RDbG9uZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgcHJlZml4ID0gTG9nTWFuYWdlclByb3BlcnRpZXNUZXN0LmNsYXNzLmdldE5hbWUoKTsKKyAgICAgICAgUHJvcGVydGllcyBwYXJlbnQ7CisgICAgICAgIExvZ01hbmFnZXJQcm9wZXJ0aWVzIG1wOworICAgICAgICBMb2dNYW5hZ2VyIG1hbmFnZXIgPSBMb2dNYW5hZ2VyLmdldExvZ01hbmFnZXIoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyBrZXkgPSBwcmVmaXguY29uY2F0KCIuZHVtbXkiKTsKKyAgICAgICAgICAgIHBhcmVudCA9IG5ldyBQcm9wZXJ0aWVzKCk7CisgICAgICAgICAgICBwYXJlbnQucHV0KGtleSwgInZhbHVlIik7CisKKyAgICAgICAgICAgIHJlYWQobWFuYWdlciwgcGFyZW50KTsKKworICAgICAgICAgICAgcGFyZW50ID0gbmV3IFByb3BlcnRpZXMoKTsKKyAgICAgICAgICAgIG1wID0gbmV3IExvZ01hbmFnZXJQcm9wZXJ0aWVzKHBhcmVudCwgcHJlZml4KTsKKworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoY29udGFpbnMobXAsIGtleSwgbnVsbCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJ2YWx1ZSIsIG1wLmdldFByb3BlcnR5KGtleSkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShjb250YWlucyhtcCwga2V5LCAidmFsdWUiKSk7IC8vZW5zdXJlIGNvcHkgd29ya2VkLgorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgbWFuYWdlci5yZXNldCgpOworICAgICAgICB9CisKKyAgICAgICAgUHJvcGVydGllcyBjbG9uZSA9IChQcm9wZXJ0aWVzKSBtcC5jbG9uZSgpOworICAgICAgICBhc3NlcnRGYWxzZShjbG9uZSBpbnN0YW5jZW9mIExvZ01hbmFnZXJQcm9wZXJ0aWVzKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFByb3BlcnRpZXMuY2xhc3MsIGNsb25lLmdldENsYXNzKCkpOworICAgICAgICBhc3NlcnROb3RTYW1lKGNsb25lLCBwYXJlbnQpOworICAgICAgICBhc3NlcnROb3RTYW1lKGNsb25lLCBtcCk7CisgICAgICAgIGFzc2VydEVxdWFscyhtcC5zaXplKCksIGNsb25lLnNpemUoKSk7CisgICAgICAgIGFzc2VydFRydWUoY2xvbmUuZXF1YWxzKG1wKSk7IC8vZG9uJ3QgY2FsbCBtcC5lcXVhbHMuCisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SXNSZWZsZWN0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFRydWUoTG9nTWFuYWdlclByb3BlcnRpZXMuaXNSZWZsZWN0aW9uQ2xhc3MoQ29uc3RydWN0b3IuY2xhc3MuZ2V0TmFtZSgpKSk7CisgICAgICAgIGFzc2VydFRydWUoTG9nTWFuYWdlclByb3BlcnRpZXMuaXNSZWZsZWN0aW9uQ2xhc3MoTWV0aG9kLmNsYXNzLmdldE5hbWUoKSkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdElzU3RhdGljVXRpbGl0eUNsYXNzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGJvb2xlYW4gbnVsbENoZWNrOworICAgICAgICB0cnkgeworICAgICAgICAgICAgTG9nTWFuYWdlclByb3BlcnRpZXMuaXNTdGF0aWNVdGlsaXR5Q2xhc3MoKFN0cmluZykgbnVsbCk7CisgICAgICAgICAgICBudWxsQ2hlY2sgPSBmYWxzZTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0KSB7CisgICAgICAgICAgICBudWxsQ2hlY2sgPSB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgaWYgKCFudWxsQ2hlY2spIHsKKyAgICAgICAgICAgIGZhaWwoIk51bGwgY2hlY2siKTsKKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZ1tdIHV0aWxzID0geworICAgICAgICAgICAgImphdmEubGFuZy5TeXN0ZW0iLAorICAgICAgICAgICAgImphdmEubmlvLmNoYW5uZWxzLkNoYW5uZWxzIiwKKyAgICAgICAgICAgICJqYXZhLnV0aWwuQ29sbGVjdGlvbnMiLAorICAgICAgICAgICAgImphdmF4Lm1haWwuaW50ZXJuZXQuTWltZVV0aWxpdHkiLAorICAgICAgICAgICAgIm9yZy5qdW5pdC5Bc3NlcnQiCisgICAgICAgIH07CisKKyAgICAgICAgdGVzdElzU3RhdGljVXRpbGl0eUNsYXNzKHV0aWxzLCB0cnVlKTsKKworICAgICAgICBTdHJpbmdbXSBvYmogPSB7CisgICAgICAgICAgICAiamF2YS5sYW5nLkV4Y2VwdGlvbiIsCisgICAgICAgICAgICAiamF2YS5sYW5nLk9iamVjdCIsCisgICAgICAgICAgICAiamF2YS5sYW5nLlJ1bnRpbWUiLAorICAgICAgICAgICAgImphdmEuaW8uU2VyaWFsaXphYmxlIgorICAgICAgICB9OworICAgICAgICB0ZXN0SXNTdGF0aWNVdGlsaXR5Q2xhc3Mob2JqLCBmYWxzZSk7CisKKyAgICAgICAgU3RyaW5nW10gZW51bWVyYXRpb25zID0geworICAgICAgICAgICAgImphdmEudXRpbC5jb25jdXJyZW50LlRpbWVVbml0IgorICAgICAgICB9OworICAgICAgICB0ZXN0SXNTdGF0aWNVdGlsaXR5Q2xhc3MoZW51bWVyYXRpb25zLCBmYWxzZSk7CisKKyAgICAgICAgU3RyaW5nW10gZmFpbCA9IHsKKyAgICAgICAgICAgICJiYWRDbGFzc05hbWUiCisgICAgICAgIH07CisgICAgICAgIGZvciAoU3RyaW5nIG5hbWUgOiBmYWlsKSB7CisgICAgICAgICAgICBib29sZWFuIHBhc3M7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIExvZ01hbmFnZXJQcm9wZXJ0aWVzLmlzU3RhdGljVXRpbGl0eUNsYXNzKG5hbWUpOworICAgICAgICAgICAgICAgIHBhc3MgPSBmYWxzZTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZXhwZWN0KSB7CisgICAgICAgICAgICAgICAgcGFzcyA9IHRydWU7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmICghcGFzcykgeworICAgICAgICAgICAgICAgIGZhaWwobmFtZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdElzU3RhdGljVXRpbGl0eUNsYXNzKFN0cmluZ1tdIG5hbWVzLCBib29sZWFuIGNvbXBsZW1lbnQpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRGYWxzZShuYW1lcy5sZW5ndGggPT0gMCk7CisKKyAgICAgICAgaWYgKGNvbXBsZW1lbnQpIHsKKyAgICAgICAgICAgIGZvciAoU3RyaW5nIG5hbWUgOiBuYW1lcykgeworICAgICAgICAgICAgICAgIGFzc2VydFRydWUobmFtZSwgTG9nTWFuYWdlclByb3BlcnRpZXMuaXNTdGF0aWNVdGlsaXR5Q2xhc3MobmFtZSkpOworICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZm9yIChTdHJpbmcgbmFtZSA6IG5hbWVzKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RmFsc2UobmFtZSwgTG9nTWFuYWdlclByb3BlcnRpZXMuaXNTdGF0aWNVdGlsaXR5Q2xhc3MobmFtZSkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0TG9jYWxIb3N0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBob3N0ID0gTG9nTWFuYWdlclByb3BlcnRpZXNUZXN0LmNsYXNzLmdldE5hbWUoKTsKKyAgICAgICAgUHJvcGVydGllcyBwID0gbmV3IFByb3BlcnRpZXMoKTsKKyAgICAgICAgcC5zZXRQcm9wZXJ0eSgibWFpbC5zbXRwLmxvY2FsaG9zdCIsIGhvc3QpOworICAgICAgICBTZXNzaW9uIHMgPSBTZXNzaW9uLmdldEluc3RhbmNlKHApOworICAgICAgICBUcmFuc3BvcnQgdCA9IHMuZ2V0VHJhbnNwb3J0KEludGVybmV0QWRkcmVzcy5nZXRMb2NhbEFkZHJlc3MocykpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIGggPSBMb2dNYW5hZ2VyUHJvcGVydGllcy5nZXRMb2NhbEhvc3QodCk7CisgICAgICAgICAgICBpZiAoaCAhPSBudWxsIHx8IGlzUHJpdmF0ZVNwZWModC5nZXRDbGFzcygpKSkgeworICAgICAgICAgICAgICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoaG9zdCwgaCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBub3RPZmZpY2lhbCkgeworICAgICAgICAgICAgaWYgKGlzUHJpdmF0ZVNwZWModC5nZXRDbGFzcygpKSkgeworICAgICAgICAgICAgICAgIGZhaWwodC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEdldExvY2FsSG9zdE1pc3NpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU2Vzc2lvbiBzZXNzaW9uID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShuZXcgUHJvcGVydGllcygpKTsKKyAgICAgICAgU2VydmljZSBzdmMgPSBuZXcgTm9Ib3N0U2VydmljZShzZXNzaW9uKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIExvZ01hbmFnZXJQcm9wZXJ0aWVzLmdldExvY2FsSG9zdChzdmMpOworICAgICAgICAgICAgZmFpbCgiIik7CisgICAgICAgIH0gY2F0Y2ggKE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBleHBlY3QpIHsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEdldExvY2FsSG9zdFNlY3VyZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTZXNzaW9uIHNlc3Npb24gPSBTZXNzaW9uLmdldEluc3RhbmNlKG5ldyBQcm9wZXJ0aWVzKCkpOworICAgICAgICBTZXJ2aWNlIHN2YyA9IG5ldyBOb3RBbGxvd2VkU2VydmljZShzZXNzaW9uKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIExvZ01hbmFnZXJQcm9wZXJ0aWVzLmdldExvY2FsSG9zdChzdmMpOworICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBhbGxvd2VkKSB7CisgICAgICAgIH0gY2F0Y2ggKEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24gZXhwZWN0KSB7CisgICAgICAgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShleHBlY3QuZ2V0Q2F1c2UoKSBpbnN0YW5jZW9mIFNlY3VyaXR5RXhjZXB0aW9uKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEdldExvY2FsSG9zdE51bGwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYm9vbGVhbiBmYWlsID0gdHJ1ZTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIExvZ01hbmFnZXJQcm9wZXJ0aWVzLmdldExvY2FsSG9zdCgoU2VydmljZSkgbnVsbCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdGVkKSB7CisgICAgICAgICAgICBmYWlsID0gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgQXNzZXJ0LmFzc2VydEZhbHNlKGZhaWwpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFBhcnNlRHVyYXRpb25NcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgbG9uZyBtcyA9IExvZ01hbmFnZXJQcm9wZXJ0aWVzLnBhcnNlRHVyYXRpb25Ub01pbGxpcygiUFQwLjM0NVMiKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygzNDVMLCBtcyk7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gfCBOb0NsYXNzRGVmRm91bmRFcnJvciBpZ25vcmUpIHsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGlnbm9yZS50b1N0cmluZygpLCBoYXNKYXZhVGltZU1vZHVsZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFBhcnNlRHVyYXRpb25TZWMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGxvbmcgbXMgPSBMb2dNYW5hZ2VyUHJvcGVydGllcy5wYXJzZUR1cmF0aW9uVG9NaWxsaXMoIlBUMjAuMzQ1UyIpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCgyMEwgKiAxMDAwTCkgKyAzNDVMLCBtcyk7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gfCBOb0NsYXNzRGVmRm91bmRFcnJvciBpZ25vcmUpIHsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGlnbm9yZS50b1N0cmluZygpLCBoYXNKYXZhVGltZU1vZHVsZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFBhcnNlRHVyYXRpb25NaW4oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGxvbmcgbXMgPSBMb2dNYW5hZ2VyUHJvcGVydGllcy5wYXJzZUR1cmF0aW9uVG9NaWxsaXMoIlBUMTVNIik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMTVMICogNjBMICogMTAwMEwsIG1zKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB8IE5vQ2xhc3NEZWZGb3VuZEVycm9yIGlnbm9yZSkgeworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoaWdub3JlLnRvU3RyaW5nKCksIGhhc0phdmFUaW1lTW9kdWxlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UGFyc2VEdXJhdGlvbkhvdXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGxvbmcgbXMgPSBMb2dNYW5hZ2VyUHJvcGVydGllcy5wYXJzZUR1cmF0aW9uVG9NaWxsaXMoIlBUMTBIIik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMTBMICogNjBMICogNjBMICogMTAwMEwsIG1zKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB8IE5vQ2xhc3NEZWZGb3VuZEVycm9yIGlnbm9yZSkgeworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoaWdub3JlLnRvU3RyaW5nKCksIGhhc0phdmFUaW1lTW9kdWxlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UGFyc2VEdXJhdGlvbkRheSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgbG9uZyBtcyA9IExvZ01hbmFnZXJQcm9wZXJ0aWVzLnBhcnNlRHVyYXRpb25Ub01pbGxpcygiUDJEIik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMkwgKiAyNEwgKiA2MEwgKiA2MEwgKiAxMDAwTCwgbXMpOworICAgICAgICB9IGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHwgTm9DbGFzc0RlZkZvdW5kRXJyb3IgaWdub3JlKSB7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShpZ25vcmUudG9TdHJpbmcoKSwgaGFzSmF2YVRpbWVNb2R1bGUoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RQYXJzZUR1cmF0aW9uQWxsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsb25nIG1zID0gTG9nTWFuYWdlclByb3BlcnRpZXMKKyAgICAgICAgICAgICAgICAgICAgLnBhcnNlRHVyYXRpb25Ub01pbGxpcygiUDJEVDNINE0yMC4zNDVTIik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoKDJMICogMjRMICogNjBMICogNjBMICogMTAwMEwpCisgICAgICAgICAgICAgICAgICAgICsgKDNMICogNjBMICogNjBMICogMTAwMEwpICsgKDRMICogNjBMICogMTAwMEwpCisgICAgICAgICAgICAgICAgICAgICsgKCgyMEwgKiAxMDAwTCkgKyAzNDUpLCBtcyk7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gfCBOb0NsYXNzRGVmRm91bmRFcnJvciBpZ25vcmUpIHsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGlnbm9yZS50b1N0cmluZygpLCBoYXNKYXZhVGltZU1vZHVsZSgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEdldFByb3BlcnR5X1N0cmluZygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgcHJlZml4ID0gTG9nTWFuYWdlclByb3BlcnRpZXNUZXN0LmNsYXNzLmdldE5hbWUoKTsKKyAgICAgICAgTG9nTWFuYWdlciBtYW5hZ2VyID0gTG9nTWFuYWdlci5nZXRMb2dNYW5hZ2VyKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcga2V5ID0gcHJlZml4LmNvbmNhdCgiLmR1bW15Iik7CisgICAgICAgICAgICBQcm9wZXJ0aWVzIHBhcmVudCA9IG5ldyBQcm9wZXJ0aWVzKCk7CisgICAgICAgICAgICBwYXJlbnQucHV0KGtleSwgInZhbHVlIik7CisgICAgICAgICAgICBwYXJlbnQucHV0KCIiLCAiZW1wdHkiKTsKKworICAgICAgICAgICAgcmVhZChtYW5hZ2VyLCBwYXJlbnQpOworCisgICAgICAgICAgICBwYXJlbnQgPSBuZXcgUHJvcGVydGllcygpOworICAgICAgICAgICAgTG9nTWFuYWdlclByb3BlcnRpZXMgbXAgPSBuZXcgTG9nTWFuYWdlclByb3BlcnRpZXMocGFyZW50LCBwcmVmaXgpOworCisgICAgICAgICAgICBhc3NlcnRGYWxzZShjb250YWlucyhtcCwga2V5LCBudWxsKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoInZhbHVlIiwgbXAuZ2V0UHJvcGVydHkoa2V5KSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGNvbnRhaW5zKG1wLCBrZXksICJ2YWx1ZSIpKTsgLy9lbnN1cmUgY29weSB3b3JrZWQuCisgICAgICAgICAgICBwYXJlbnQucHV0KGtleSwgIm5ld1ZhbHVlIik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIm5ld1ZhbHVlIiwgbXAuZ2V0UHJvcGVydHkoa2V5KSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImVtcHR5IiwgbXAuZ2V0UHJvcGVydHkoIiIpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIG1hbmFnZXIucmVzZXQoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEdldFByb3BlcnR5X1N0cmluZ19TdHJpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHByZWZpeCA9IExvZ01hbmFnZXJQcm9wZXJ0aWVzVGVzdC5jbGFzcy5nZXROYW1lKCk7CisgICAgICAgIExvZ01hbmFnZXIgbWFuYWdlciA9IExvZ01hbmFnZXIuZ2V0TG9nTWFuYWdlcigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIGtleSA9IHByZWZpeC5jb25jYXQoIi5kdW1teSIpOworICAgICAgICAgICAgUHJvcGVydGllcyBwYXJlbnQgPSBuZXcgUHJvcGVydGllcygpOworICAgICAgICAgICAgcGFyZW50LnB1dChrZXksICJ2YWx1ZSIpOworICAgICAgICAgICAgcGFyZW50LnB1dCgiIiwgImVtcHR5Iik7CisKKyAgICAgICAgICAgIHJlYWQobWFuYWdlciwgcGFyZW50KTsKKworICAgICAgICAgICAgcGFyZW50ID0gbmV3IFByb3BlcnRpZXMoKTsKKyAgICAgICAgICAgIExvZ01hbmFnZXJQcm9wZXJ0aWVzIG1wID0gbmV3IExvZ01hbmFnZXJQcm9wZXJ0aWVzKHBhcmVudCwgcHJlZml4KTsKKworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoY29udGFpbnMobXAsIGtleSwgbnVsbCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJ2YWx1ZSIsIG1wLmdldFByb3BlcnR5KGtleSwgbnVsbCkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShjb250YWlucyhtcCwga2V5LCAidmFsdWUiKSk7IC8vZW5zdXJlIGNvcHkgd29ya2VkLgorICAgICAgICAgICAgcGFyZW50LnB1dChrZXksICJuZXdWYWx1ZSIpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJuZXdWYWx1ZSIsIG1wLmdldFByb3BlcnR5KGtleSwgbnVsbCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJkZWZhdWx0IiwgbXAuZ2V0UHJvcGVydHkoInVua25vd24iLCAiZGVmYXVsdCIpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZW1wdHkiLCBtcC5nZXRQcm9wZXJ0eSgiIiwgbnVsbCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgbWFuYWdlci5yZXNldCgpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBwcmVmaXggPSBMb2dNYW5hZ2VyUHJvcGVydGllc1Rlc3QuY2xhc3MuZ2V0TmFtZSgpOworICAgICAgICBMb2dNYW5hZ2VyIG1hbmFnZXIgPSBMb2dNYW5hZ2VyLmdldExvZ01hbmFnZXIoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyBrZXkgPSBwcmVmaXguY29uY2F0KCIuZHVtbXkiKTsKKyAgICAgICAgICAgIFByb3BlcnRpZXMgcGFyZW50ID0gbmV3IFByb3BlcnRpZXMoKTsKKyAgICAgICAgICAgIHBhcmVudC5wdXQoa2V5LCAidmFsdWUiKTsKKyAgICAgICAgICAgIHBhcmVudC5wdXQoIiIsICJlbXB0eSIpOworCisgICAgICAgICAgICByZWFkKG1hbmFnZXIsIHBhcmVudCk7CisKKyAgICAgICAgICAgIHBhcmVudCA9IG5ldyBQcm9wZXJ0aWVzKCk7CisgICAgICAgICAgICBMb2dNYW5hZ2VyUHJvcGVydGllcyBtcCA9IG5ldyBMb2dNYW5hZ2VyUHJvcGVydGllcyhwYXJlbnQsIHByZWZpeCk7CisKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGNvbnRhaW5zKG1wLCBrZXksIG51bGwpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygidmFsdWUiLCBtcC5nZXQoa2V5KSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGNvbnRhaW5zKG1wLCBrZXksICJ2YWx1ZSIpKTsgLy9lbnN1cmUgY29weSB3b3JrZWQuCisgICAgICAgICAgICBwYXJlbnQucHV0KGtleSwgIm5ld1ZhbHVlIik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIm5ld1ZhbHVlIiwgbXAuZ2V0KGtleSkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJlbXB0eSIsIG1wLmdldCgiIikpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgbWFuYWdlci5yZXNldCgpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0T2JqZWN0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBwcmVmaXggPSBMb2dNYW5hZ2VyUHJvcGVydGllc1Rlc3QuY2xhc3MuZ2V0TmFtZSgpOworICAgICAgICBQcm9wZXJ0aWVzIHBhcmVudCA9IG5ldyBQcm9wZXJ0aWVzKCk7CisgICAgICAgIExvZ01hbmFnZXJQcm9wZXJ0aWVzIG1wID0gbmV3IExvZ01hbmFnZXJQcm9wZXJ0aWVzKHBhcmVudCwgcHJlZml4KTsKKyAgICAgICAgU3RyaW5nIGtleSA9ICJrZXkiOworICAgICAgICBPYmplY3QgdmFsdWUgPSBuZXcgT2JqZWN0KCk7CisgICAgICAgIHBhcmVudC5wdXQoa2V5LCB2YWx1ZSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHBhcmVudC5nZXQoa2V5KSwgbXAuZ2V0KGtleSkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENvbnRhaW5zS2V5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBwcmVmaXggPSBMb2dNYW5hZ2VyUHJvcGVydGllc1Rlc3QuY2xhc3MuZ2V0TmFtZSgpOworICAgICAgICBMb2dNYW5hZ2VyIG1hbmFnZXIgPSBMb2dNYW5hZ2VyLmdldExvZ01hbmFnZXIoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyBrZXkgPSBwcmVmaXguY29uY2F0KCIuZHVtbXkiKTsKKyAgICAgICAgICAgIFByb3BlcnRpZXMgcGFyZW50ID0gbmV3IFByb3BlcnRpZXMoKTsKKyAgICAgICAgICAgIHBhcmVudC5wdXQoa2V5LCAidmFsdWUiKTsKKyAgICAgICAgICAgIHBhcmVudC5wdXQoIiIsICJlbXB0eSIpOworCisgICAgICAgICAgICByZWFkKG1hbmFnZXIsIHBhcmVudCk7CisKKyAgICAgICAgICAgIHBhcmVudCA9IG5ldyBQcm9wZXJ0aWVzKCk7CisgICAgICAgICAgICBMb2dNYW5hZ2VyUHJvcGVydGllcyBtcCA9IG5ldyBMb2dNYW5hZ2VyUHJvcGVydGllcyhwYXJlbnQsIHByZWZpeCk7CisKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGNvbnRhaW5zKG1wLCBrZXksIG51bGwpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUobXAuY29udGFpbnNLZXkoa2V5KSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGNvbnRhaW5zKG1wLCBrZXksICJ2YWx1ZSIpKTsgLy9lbnN1cmUgY29weSB3b3JrZWQuCisgICAgICAgICAgICBwYXJlbnQucHV0KGtleSwgIm5ld1ZhbHVlIik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIm5ld1ZhbHVlIiwgbXAuZ2V0KGtleSkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShtcC5jb250YWluc0tleSgiIikpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgbWFuYWdlci5yZXNldCgpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29udGFpbnNLZXlPYmplY3QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHByZWZpeCA9IExvZ01hbmFnZXJQcm9wZXJ0aWVzVGVzdC5jbGFzcy5nZXROYW1lKCk7CisgICAgICAgIFByb3BlcnRpZXMgcGFyZW50ID0gbmV3IFByb3BlcnRpZXMoKTsKKyAgICAgICAgTG9nTWFuYWdlclByb3BlcnRpZXMgbXAgPSBuZXcgTG9nTWFuYWdlclByb3BlcnRpZXMocGFyZW50LCBwcmVmaXgpOworICAgICAgICBTdHJpbmcga2V5ID0gImtleSI7CisgICAgICAgIE9iamVjdCB2YWx1ZSA9IG5ldyBPYmplY3QoKTsKKyAgICAgICAgcGFyZW50LnB1dChrZXksIHZhbHVlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHBhcmVudC5jb250YWluc0tleShrZXkpLCBtcC5jb250YWluc0tleShrZXkpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RSZW1vdmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHByZWZpeCA9IExvZ01hbmFnZXJQcm9wZXJ0aWVzVGVzdC5jbGFzcy5nZXROYW1lKCk7CisgICAgICAgIExvZ01hbmFnZXIgbWFuYWdlciA9IExvZ01hbmFnZXIuZ2V0TG9nTWFuYWdlcigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIGtleSA9IHByZWZpeC5jb25jYXQoIi5kdW1teSIpOworICAgICAgICAgICAgUHJvcGVydGllcyBwYXJlbnQgPSBuZXcgUHJvcGVydGllcygpOworICAgICAgICAgICAgcGFyZW50LnB1dChrZXksICJ2YWx1ZSIpOworICAgICAgICAgICAgcGFyZW50LnB1dCgiIiwgImVtcHR5Iik7CisKKyAgICAgICAgICAgIHJlYWQobWFuYWdlciwgcGFyZW50KTsKKworICAgICAgICAgICAgcGFyZW50ID0gbmV3IFByb3BlcnRpZXMoKTsKKyAgICAgICAgICAgIExvZ01hbmFnZXJQcm9wZXJ0aWVzIG1wID0gbmV3IExvZ01hbmFnZXJQcm9wZXJ0aWVzKHBhcmVudCwgcHJlZml4KTsKKworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoY29udGFpbnMobXAsIGtleSwgbnVsbCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJ2YWx1ZSIsIG1wLnJlbW92ZShrZXkpKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGNvbnRhaW5zKG1wLCBrZXksICJ2YWx1ZSIpKTsgLy9lbnN1cmUgY29weSB3b3JrZWQuCisgICAgICAgICAgICBwYXJlbnQucHV0KGtleSwgIm5ld1ZhbHVlIik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIm5ld1ZhbHVlIiwgbXAucmVtb3ZlKGtleSkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJlbXB0eSIsIG1wLnJlbW92ZSgiIikpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgbWFuYWdlci5yZXNldCgpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVtb3ZlT2JqZWN0KCkgeworICAgICAgICBTdHJpbmcgcHJlZml4ID0gTG9nTWFuYWdlclByb3BlcnRpZXNUZXN0LmNsYXNzLmdldE5hbWUoKTsKKyAgICAgICAgUHJvcGVydGllcyBwYXJlbnQgPSBuZXcgUHJvcGVydGllcygpOworICAgICAgICBMb2dNYW5hZ2VyUHJvcGVydGllcyBtcCA9IG5ldyBMb2dNYW5hZ2VyUHJvcGVydGllcyhwYXJlbnQsIHByZWZpeCk7CisgICAgICAgIFN0cmluZyBrZXkgPSAia2V5IjsKKyAgICAgICAgT2JqZWN0IHZhbHVlID0gbmV3IE9iamVjdCgpOworICAgICAgICBwYXJlbnQucHV0KGtleSwgdmFsdWUpOworICAgICAgICBhc3NlcnRFcXVhbHModmFsdWUsIHBhcmVudC5yZW1vdmUoa2V5KSk7CisgICAgICAgIGFzc2VydEVxdWFscyhwYXJlbnQuY29udGFpbnNLZXkoa2V5KSwgbXAuY29udGFpbnNLZXkoa2V5KSk7CisgICAgICAgIGFzc2VydE51bGwocGFyZW50LnJlbW92ZShrZXkpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RQdXQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHByZWZpeCA9IExvZ01hbmFnZXJQcm9wZXJ0aWVzVGVzdC5jbGFzcy5nZXROYW1lKCk7CisgICAgICAgIExvZ01hbmFnZXIgbWFuYWdlciA9IExvZ01hbmFnZXIuZ2V0TG9nTWFuYWdlcigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nIGtleSA9IHByZWZpeC5jb25jYXQoIi5kdW1teSIpOworICAgICAgICAgICAgUHJvcGVydGllcyBwYXJlbnQgPSBuZXcgUHJvcGVydGllcygpOworICAgICAgICAgICAgcGFyZW50LnB1dChrZXksICJ2YWx1ZSIpOworICAgICAgICAgICAgcGFyZW50LnB1dCgiIiwgImVtcHR5Iik7CisKKyAgICAgICAgICAgIHJlYWQobWFuYWdlciwgcGFyZW50KTsKKworICAgICAgICAgICAgcGFyZW50ID0gbmV3IFByb3BlcnRpZXMoKTsKKyAgICAgICAgICAgIExvZ01hbmFnZXJQcm9wZXJ0aWVzIG1wID0gbmV3IExvZ01hbmFnZXJQcm9wZXJ0aWVzKHBhcmVudCwgcHJlZml4KTsKKworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoY29udGFpbnMobXAsIGtleSwgbnVsbCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJ2YWx1ZSIsIG1wLnB1dChrZXksICJuZXdWYWx1ZSIpKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGNvbnRhaW5zKG1wLCBrZXksICJ2YWx1ZSIpKTsgLy9lbnN1cmUgY29weSB3b3JrZWQuCisgICAgICAgICAgICBhc3NlcnRUcnVlKGNvbnRhaW5zKG1wLCBrZXksICJuZXdWYWx1ZSIpKTsgLy9lbnN1cmUgY29weSB3b3JrZWQuCisgICAgICAgICAgICBwYXJlbnQucHV0KGtleSwgImRlZlZhbHVlIik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIm5ld1ZhbHVlIiwgbXAucmVtb3ZlKGtleSkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJkZWZWYWx1ZSIsIG1wLnJlbW92ZShrZXkpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZW1wdHkiLCBtcC5wdXQoIiIsICIiKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBtYW5hZ2VyLnJlc2V0KCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RQdXRPYmplY3QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHByZWZpeCA9IExvZ01hbmFnZXJQcm9wZXJ0aWVzVGVzdC5jbGFzcy5nZXROYW1lKCk7CisgICAgICAgIFByb3BlcnRpZXMgcGFyZW50ID0gbmV3IFByb3BlcnRpZXMoKTsKKyAgICAgICAgTG9nTWFuYWdlclByb3BlcnRpZXMgbXAgPSBuZXcgTG9nTWFuYWdlclByb3BlcnRpZXMocGFyZW50LCBwcmVmaXgpOworICAgICAgICBTdHJpbmcga2V5ID0gImtleSI7CisgICAgICAgIE9iamVjdCB2YWx1ZSA9IFRpbWVVbml0Lk1JTExJU0VDT05EUzsKKyAgICAgICAgYXNzZXJ0TnVsbChtcC5wdXQoa2V5LCB2YWx1ZSkpOworICAgICAgICBPYmplY3QgbmV3VmFsdWUgPSBUaW1lVW5pdC5OQU5PU0VDT05EUzsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHZhbHVlLCBtcC5wdXQoa2V5LCBuZXdWYWx1ZSkpOworICAgICAgICBhc3NlcnRFcXVhbHMobmV3VmFsdWUsIG1wLmdldChrZXkpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRQcm9wZXJ0eSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgcHJlZml4ID0gTG9nTWFuYWdlclByb3BlcnRpZXNUZXN0LmNsYXNzLmdldE5hbWUoKTsKKyAgICAgICAgTG9nTWFuYWdlciBtYW5hZ2VyID0gTG9nTWFuYWdlci5nZXRMb2dNYW5hZ2VyKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcga2V5ID0gcHJlZml4LmNvbmNhdCgiLmR1bW15Iik7CisgICAgICAgICAgICBQcm9wZXJ0aWVzIHBhcmVudCA9IG5ldyBQcm9wZXJ0aWVzKCk7CisgICAgICAgICAgICBwYXJlbnQucHV0KGtleSwgInZhbHVlIik7CisgICAgICAgICAgICBwYXJlbnQucHV0KCIiLCAiZW1wdHkiKTsKKworICAgICAgICAgICAgcmVhZChtYW5hZ2VyLCBwYXJlbnQpOworCisgICAgICAgICAgICBwYXJlbnQgPSBuZXcgUHJvcGVydGllcygpOworICAgICAgICAgICAgTG9nTWFuYWdlclByb3BlcnRpZXMgbXAgPSBuZXcgTG9nTWFuYWdlclByb3BlcnRpZXMocGFyZW50LCBwcmVmaXgpOworCisgICAgICAgICAgICBhc3NlcnRGYWxzZShjb250YWlucyhtcCwga2V5LCBudWxsKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoInZhbHVlIiwgbXAuc2V0UHJvcGVydHkoa2V5LCAibmV3VmFsdWUiKSk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShjb250YWlucyhtcCwga2V5LCAidmFsdWUiKSk7IC8vZW5zdXJlIGNvcHkgd29ya2VkLgorICAgICAgICAgICAgYXNzZXJ0VHJ1ZShjb250YWlucyhtcCwga2V5LCAibmV3VmFsdWUiKSk7IC8vZW5zdXJlIGNvcHkgd29ya2VkLgorICAgICAgICAgICAgcGFyZW50LnB1dChrZXksICJkZWZWYWx1ZSIpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJuZXdWYWx1ZSIsIG1wLnJlbW92ZShrZXkpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiZGVmVmFsdWUiLCBtcC5yZW1vdmUoa2V5KSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImVtcHR5IiwgbXAuc2V0UHJvcGVydHkoIiIsICIiKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBtYW5hZ2VyLnJlc2V0KCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RQcm9wVXRpbCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgcHJlZml4ID0gTG9nTWFuYWdlclByb3BlcnRpZXNUZXN0LmNsYXNzLmdldE5hbWUoKTsKKyAgICAgICAgTG9nTWFuYWdlciBtYW5hZ2VyID0gTG9nTWFuYWdlci5nZXRMb2dNYW5hZ2VyKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmcga2V5U2hvcnQgPSAibWFpbC5zbXRwLnJlcG9ydHN1Y2Nlc3MiOworICAgICAgICAgICAgU3RyaW5nIGtleSA9IHByZWZpeCArICcuJyArIGtleVNob3J0OworICAgICAgICAgICAgUHJvcGVydGllcyBwYXJlbnQgPSBuZXcgUHJvcGVydGllcygpOworICAgICAgICAgICAgcGFyZW50LnB1dChrZXksICJ0cnVlIik7CisKKyAgICAgICAgICAgIHJlYWQobWFuYWdlciwgcGFyZW50KTsKKworICAgICAgICAgICAgcGFyZW50ID0gbmV3IFByb3BlcnRpZXMoKTsKKyAgICAgICAgICAgIExvZ01hbmFnZXJQcm9wZXJ0aWVzIG1wID0gbmV3IExvZ01hbmFnZXJQcm9wZXJ0aWVzKHBhcmVudCwgcHJlZml4KTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGNvbnRhaW5zKG1wLCBrZXlTaG9ydCwgbnVsbCkpOworCisgICAgICAgICAgICBmaW5hbCBTZXNzaW9uIHNlc3Npb24gPSBTZXNzaW9uLmdldEluc3RhbmNlKG1wKTsKKyAgICAgICAgICAgIGZpbmFsIE9iamVjdCB0ID0gc2Vzc2lvbi5nZXRUcmFuc3BvcnQoInNtdHAiKTsKKyAgICAgICAgICAgIGlmIChpc1ByaXZhdGVTcGVjKHQuZ2V0Q2xhc3MoKSkpIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgY2xhenpOYW1lID0gImNvbS5zdW4ubWFpbC5zbXRwLlNNVFBUcmFuc3BvcnQiOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhjbGF6ek5hbWUsIHQuZ2V0Q2xhc3MoKS5nZXROYW1lKCkpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHQpOworICAgICAgICAgICAgICAgIHNlc3Npb24uZ2V0UHJvcGVydHkoa2V5U2hvcnQpOyAvL0ZvcmNlIGEgcmVhZCB0aHJvdWdoIHNlc3Npb24uCisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRUcnVlKGNvbnRhaW5zKG1wLCBrZXlTaG9ydCwgInRydWUiKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBtYW5hZ2VyLnJlc2V0KCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RUb0xhbmd1YWdlVGFnKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVxdWFscygiZW4tVVMiLCBMb2dNYW5hZ2VyUHJvcGVydGllcy50b0xhbmd1YWdlVGFnKExvY2FsZS5VUykpOworICAgICAgICBhc3NlcnRFcXVhbHMoImVuIiwgTG9nTWFuYWdlclByb3BlcnRpZXMudG9MYW5ndWFnZVRhZyhMb2NhbGUuRU5HTElTSCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIExvZ01hbmFnZXJQcm9wZXJ0aWVzLnRvTGFuZ3VhZ2VUYWcobmV3IExvY2FsZSgiIiwgIiIsICIiKSkpOworICAgICAgICBMb2NhbGUgbCA9IG5ldyBMb2NhbGUoImVuIiwgIlVTIiwgInNsYW5nIik7CisgICAgICAgIGFzc2VydEVxdWFscygiZW4tVVMtc2xhbmciLCBMb2dNYW5hZ2VyUHJvcGVydGllcy50b0xhbmd1YWdlVGFnKGwpKTsKKyAgICAgICAgbCA9IG5ldyBMb2NhbGUoImVuIiwgIiIsICJzbGFuZyIpOworICAgICAgICBhc3NlcnRFcXVhbHMoImVuLS1zbGFuZyIsIExvZ01hbmFnZXJQcm9wZXJ0aWVzLnRvTGFuZ3VhZ2VUYWcobCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBMb2dNYW5hZ2VyUHJvcGVydGllcy50b0xhbmd1YWdlVGFnKG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbCB3YXMgYWxsb3dlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0KSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3ROZXdPYmplY3RGcm9tKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBMb2dNYW5hZ2VyUHJvcGVydGllcy5uZXdPYmplY3RGcm9tKChTdHJpbmcpIG51bGwsIE9iamVjdC5jbGFzcyk7CisgICAgICAgICAgICBmYWlsKCJOdWxsIG5hbWUgd2FzIGFsbG93ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdCkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIExvZ01hbmFnZXJQcm9wZXJ0aWVzLm5ld09iamVjdEZyb20oT2JqZWN0LmNsYXNzLmdldE5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgKENsYXNzPE9iamVjdD4pIG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbCBjbGFzcyB3YXMgYWxsb3dlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0KSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgTG9nTWFuYWdlclByb3BlcnRpZXMubmV3T2JqZWN0RnJvbSgoU3RyaW5nKSBudWxsLAorICAgICAgICAgICAgICAgICAgICAoQ2xhc3M8T2JqZWN0PikgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsIHdhcyBhbGxvd2VkLiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3QpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBMb2dNYW5hZ2VyUHJvcGVydGllcy5uZXdPYmplY3RGcm9tKCIiLCBPYmplY3QuY2xhc3MpOworICAgICAgICAgICAgZmFpbCgiRW1wdHkgY2xhc3Mgd2FzIGFsbG93ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZXhwZWN0KSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgTG9nTWFuYWdlclByb3BlcnRpZXMubmV3T2JqZWN0RnJvbShPYmplY3QuY2xhc3MuZ2V0TmFtZSgpLAorICAgICAgICAgICAgICAgICAgICBTdHJpbmcuY2xhc3MpOworICAgICAgICAgICAgZmFpbCgiV3JvbmcgdHlwZSB3YXMgYWxsb3dlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGV4cGVjdCkgeworICAgICAgICB9CisKKyAgICAgICAgT2JqZWN0IG8gPSBMb2dNYW5hZ2VyUHJvcGVydGllcy4KKyAgICAgICAgICAgICAgICBuZXdPYmplY3RGcm9tKFN0cmluZy5jbGFzcy5nZXROYW1lKCksIE9iamVjdC5jbGFzcyk7CisgICAgICAgIGFzc2VydEVxdWFscyhTdHJpbmcuY2xhc3MsIG8uZ2V0Q2xhc3MoKSk7CisKKyAgICAgICAgU3RyaW5nIG4gPSBMb2dNYW5hZ2VyUHJvcGVydGllcy4KKyAgICAgICAgICAgICAgICBuZXdPYmplY3RGcm9tKFN0cmluZy5jbGFzcy5nZXROYW1lKCksIFN0cmluZy5jbGFzcyk7CisgICAgICAgIGFzc2VydEVxdWFscyhTdHJpbmcuY2xhc3MsIG4uZ2V0Q2xhc3MoKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TmV3QXV0aGVudGljYXRvcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBBdXRoZW50aWNhdG9yIGEgPSBMb2dNYW5hZ2VyUHJvcGVydGllcy5uZXdPYmplY3RGcm9tKAorICAgICAgICAgICAgICAgIEVtcHR5QXV0aGVudGljYXRvci5jbGFzcy5nZXROYW1lKCksCisgICAgICAgICAgICAgICAgQXV0aGVudGljYXRvci5jbGFzcyk7CisgICAgICAgIGFzc2VydEVxdWFscyhFbXB0eUF1dGhlbnRpY2F0b3IuY2xhc3MsIGEuZ2V0Q2xhc3MoKSk7CisKKyAgICAgICAgZmluYWwgQ2xhc3M8Pz4gdHlwZSA9IEVycm9yQXV0aGVudGljYXRvci5jbGFzczsKKyAgICAgICAgYSA9IExvZ01hbmFnZXJQcm9wZXJ0aWVzLm5ld09iamVjdEZyb20oCisgICAgICAgICAgICAgICAgdHlwZS5nZXROYW1lKCksIEF1dGhlbnRpY2F0b3IuY2xhc3MpOworICAgICAgICBhc3NlcnRFcXVhbHModHlwZSwgYS5nZXRDbGFzcygpKTsKKworICAgICAgICBzZXRQZW5kaW5nKG5ldyBSdW50aW1lRXhjZXB0aW9uKCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgTG9nTWFuYWdlclByb3BlcnRpZXMubmV3T2JqZWN0RnJvbSh0eXBlLmdldE5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgQXV0aGVudGljYXRvci5jbGFzcyk7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2ggKEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24gZXhwZWN0KSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoUnVudGltZUV4Y2VwdGlvbi5jbGFzcywgZXhwZWN0LmdldENhdXNlKCkuZ2V0Q2xhc3MoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBzZXRQZW5kaW5nKG51bGwpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TmV3Q29tcGFyYXRvcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgTG9nTWFuYWdlclByb3BlcnRpZXMubmV3Q29tcGFyYXRvcihudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGwgd2FzIGFsbG93ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdCkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIExvZ01hbmFnZXJQcm9wZXJ0aWVzLm5ld0NvbXBhcmF0b3IoIiIpOworICAgICAgICAgICAgZmFpbCgiRW1wdHkgY2xhc3Mgd2FzIGFsbG93ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZXhwZWN0KSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgTG9nTWFuYWdlclByb3BlcnRpZXMubmV3Q29tcGFyYXRvcihPYmplY3QuY2xhc3MuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGZhaWwoIldyb25nIHR5cGUgd2FzIGFsbG93ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBleHBlY3QpIHsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIENsYXNzPD8+IHR5cGUgPSBFcnJvckNvbXBhcmF0b3IuY2xhc3M7CisgICAgICAgIGZpbmFsIENvbXBhcmF0b3I8PyBzdXBlciBMb2dSZWNvcmQ+IGMKKyAgICAgICAgICAgICAgICA9IExvZ01hbmFnZXJQcm9wZXJ0aWVzLm5ld0NvbXBhcmF0b3IodHlwZS5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHModHlwZSwgYy5nZXRDbGFzcygpKTsKKworICAgICAgICBzZXRQZW5kaW5nKG5ldyBSdW50aW1lRXhjZXB0aW9uKCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgTG9nTWFuYWdlclByb3BlcnRpZXMubmV3Q29tcGFyYXRvcih0eXBlLmdldE5hbWUoKSk7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2ggKEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24gZXhwZWN0KSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoUnVudGltZUV4Y2VwdGlvbi5jbGFzcywgZXhwZWN0LmdldENhdXNlKCkuZ2V0Q2xhc3MoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBzZXRQZW5kaW5nKG51bGwpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmV2ZXJzZU9yZGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBMb2dNYW5hZ2VyUHJvcGVydGllcy5yZXZlcnNlT3JkZXIobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsIHdhcyBhbGxvd2VkLiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3QpIHsKKyAgICAgICAgfQorCisgICAgICAgIENvbXBhcmF0b3I8TG9nUmVjb3JkPiBjID0gbmV3IEVycm9yQ29tcGFyYXRvcigpOworICAgICAgICBDb21wYXJhdG9yPExvZ1JlY29yZD4gciA9IExvZ01hbmFnZXJQcm9wZXJ0aWVzLnJldmVyc2VPcmRlcihjKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShjLmdldENsYXNzKCkgIT0gci5nZXRDbGFzcygpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UociBpbnN0YW5jZW9mIEVycm9yQ29tcGFyYXRvcik7CisgICAgICAgIGFzc2VydEZhbHNlKHIgaW5zdGFuY2VvZiBBc2NDb21wYXJhdG9yKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UociBpbnN0YW5jZW9mIERlc2NDb21wYXJhdG9yKTsKKworICAgICAgICBjID0gbmV3IEFzY0NvbXBhcmF0b3IoKTsKKyAgICAgICAgciA9IExvZ01hbmFnZXJQcm9wZXJ0aWVzLnJldmVyc2VPcmRlcihjKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShyIGluc3RhbmNlb2YgRGVzY0NvbXBhcmF0b3IpOworCisgICAgICAgIGMgPSBuZXcgQXNjQ29tcGFyYXRvcigpOworICAgICAgICByID0gTG9nTWFuYWdlclByb3BlcnRpZXMucmV2ZXJzZU9yZGVyKGMpOworICAgICAgICBhc3NlcnRUcnVlKHIgaW5zdGFuY2VvZiBEZXNjQ29tcGFyYXRvcik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TmV3RXJyb3JNYW5hZ2VyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBMb2dNYW5hZ2VyUHJvcGVydGllcy5uZXdFcnJvck1hbmFnZXIobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsIHdhcyBhbGxvd2VkLiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3QpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBMb2dNYW5hZ2VyUHJvcGVydGllcy5uZXdFcnJvck1hbmFnZXIoIiIpOworICAgICAgICAgICAgZmFpbCgiRW1wdHkgY2xhc3Mgd2FzIGFsbG93ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZXhwZWN0KSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgTG9nTWFuYWdlclByb3BlcnRpZXMubmV3RXJyb3JNYW5hZ2VyKE9iamVjdC5jbGFzcy5nZXROYW1lKCkpOworICAgICAgICAgICAgZmFpbCgiV3JvbmcgdHlwZSB3YXMgYWxsb3dlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGV4cGVjdCkgeworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgQ2xhc3M8Pz4gdHlwZSA9IEVycm9yTWFuYWdlci5jbGFzczsKKyAgICAgICAgRXJyb3JNYW5hZ2VyIGYgPSBMb2dNYW5hZ2VyUHJvcGVydGllcy5uZXdFcnJvck1hbmFnZXIodHlwZS5nZXROYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHModHlwZSwgZi5nZXRDbGFzcygpKTsKKworICAgICAgICBzZXRQZW5kaW5nKG5ldyBSdW50aW1lRXhjZXB0aW9uKCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUgPSBFcnJvckVycm9yTWFuYWdlci5jbGFzcy5nZXROYW1lKCk7CisgICAgICAgICAgICBMb2dNYW5hZ2VyUHJvcGVydGllcy5uZXdFcnJvck1hbmFnZXIobmFtZSk7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIik7CisgICAgICAgIH0gY2F0Y2ggKEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24gZXhwZWN0KSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoUnVudGltZUV4Y2VwdGlvbi5jbGFzcywgZXhwZWN0LmdldENhdXNlKCkuZ2V0Q2xhc3MoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBzZXRQZW5kaW5nKG51bGwpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TmV3RmlsdGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBMb2dNYW5hZ2VyUHJvcGVydGllcy5uZXdGaWx0ZXIobnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsIHdhcyBhbGxvd2VkLiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3QpIHsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBMb2dNYW5hZ2VyUHJvcGVydGllcy5uZXdGaWx0ZXIoIiIpOworICAgICAgICAgICAgZmFpbCgiRW1wdHkgY2xhc3Mgd2FzIGFsbG93ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZXhwZWN0KSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgTG9nTWFuYWdlclByb3BlcnRpZXMubmV3RmlsdGVyKE9iamVjdC5jbGFzcy5nZXROYW1lKCkpOworICAgICAgICAgICAgZmFpbCgiV3JvbmcgdHlwZSB3YXMgYWxsb3dlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGV4cGVjdCkgeworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgQ2xhc3M8Pz4gdHlwZSA9IEVycm9yRmlsdGVyLmNsYXNzOworICAgICAgICBmaW5hbCBGaWx0ZXIgZiA9IExvZ01hbmFnZXJQcm9wZXJ0aWVzLm5ld0ZpbHRlcih0eXBlLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyh0eXBlLCBmLmdldENsYXNzKCkpOworCisgICAgICAgIHNldFBlbmRpbmcobmV3IFJ1bnRpbWVFeGNlcHRpb24oKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBMb2dNYW5hZ2VyUHJvcGVydGllcy5uZXdGaWx0ZXIodHlwZS5nZXROYW1lKCkpOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uIGV4cGVjdCkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKFJ1bnRpbWVFeGNlcHRpb24uY2xhc3MsIGV4cGVjdC5nZXRDYXVzZSgpLmdldENsYXNzKCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgc2V0UGVuZGluZyhudWxsKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdE5ld0Zvcm1hdHRlcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgTG9nTWFuYWdlclByb3BlcnRpZXMubmV3Rm9ybWF0dGVyKG51bGwpOworICAgICAgICAgICAgZmFpbCgiTnVsbCB3YXMgYWxsb3dlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZXhwZWN0KSB7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgTG9nTWFuYWdlclByb3BlcnRpZXMubmV3Rm9ybWF0dGVyKCIiKTsKKyAgICAgICAgICAgIGZhaWwoIkVtcHR5IGNsYXNzIHdhcyBhbGxvd2VkLiIpOworICAgICAgICB9IGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGV4cGVjdCkgeworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIExvZ01hbmFnZXJQcm9wZXJ0aWVzLm5ld0Zvcm1hdHRlcihPYmplY3QuY2xhc3MuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGZhaWwoIldyb25nIHR5cGUgd2FzIGFsbG93ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBleHBlY3QpIHsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIENsYXNzPD8+IHR5cGUgPSBTaW1wbGVGb3JtYXR0ZXIuY2xhc3M7CisgICAgICAgIGZpbmFsIEZvcm1hdHRlciBmID0gTG9nTWFuYWdlclByb3BlcnRpZXMubmV3Rm9ybWF0dGVyKHR5cGUuZ2V0TmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHR5cGUsIGYuZ2V0Q2xhc3MoKSk7CisKKyAgICAgICAgc2V0UGVuZGluZyhuZXcgUnVudGltZUV4Y2VwdGlvbigpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZpbmFsIFN0cmluZyBuYW1lID0gRXJyb3JGb3JtYXR0ZXIuY2xhc3MuZ2V0TmFtZSgpOworICAgICAgICAgICAgTG9nTWFuYWdlclByb3BlcnRpZXMubmV3Rm9ybWF0dGVyKG5hbWUpOworICAgICAgICAgICAgZmFpbCgiRXhjZXB0aW9uIHdhcyBub3QgdGhyb3duLiIpOworICAgICAgICB9IGNhdGNoIChJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uIGV4cGVjdCkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKFJ1bnRpbWVFeGNlcHRpb24uY2xhc3MsIGV4cGVjdC5nZXRDYXVzZSgpLmdldENsYXNzKCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgc2V0UGVuZGluZyhudWxsKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEVzY2FwaW5nQXV0aGVudGljYXRvcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2xhc3M8Pz4gayA9IEVycm9yQXV0aGVudGljYXRvci5jbGFzczsKKyAgICAgICAgICAgIGphdmF4Lm1haWwuQXV0aGVudGljYXRvciBhOworCisgICAgICAgICAgICBhID0gTG9nTWFuYWdlclByb3BlcnRpZXMubmV3T2JqZWN0RnJvbShrLmdldE5hbWUoKSwgQXV0aGVudGljYXRvci5jbGFzcyk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoaywgYS5nZXRDbGFzcygpKTsKKworICAgICAgICAgICAgc2V0UGVuZGluZyhuZXcgVGhyZWFkRGVhdGgoKSk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGEgPSBMb2dNYW5hZ2VyUHJvcGVydGllcy5uZXdPYmplY3RGcm9tKGsuZ2V0TmFtZSgpLCBBdXRoZW50aWNhdG9yLmNsYXNzKTsKKyAgICAgICAgICAgICAgICBmYWlsKFN0cmluZy52YWx1ZU9mKGEpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFRocmVhZERlYXRoIGV4cGVjdCkgeworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBzZXRQZW5kaW5nKG5ldyBPdXRPZk1lbW9yeUVycm9yKCkpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBhID0gTG9nTWFuYWdlclByb3BlcnRpZXMubmV3T2JqZWN0RnJvbShrLmdldE5hbWUoKSwgQXV0aGVudGljYXRvci5jbGFzcyk7CisgICAgICAgICAgICAgICAgZmFpbChTdHJpbmcudmFsdWVPZihhKSk7CisgICAgICAgICAgICB9IGNhdGNoIChPdXRPZk1lbW9yeUVycm9yIGV4cGVjdCkgeworICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgc2V0UGVuZGluZyhudWxsKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEVzY2FwaW5nQ29tcGFyYXRvcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2xhc3M8Pz4gayA9IEVycm9yQ29tcGFyYXRvci5jbGFzczsKKyAgICAgICAgICAgIENvbXBhcmF0b3I8PyBzdXBlciBMb2dSZWNvcmQ+IGM7CisKKyAgICAgICAgICAgIGMgPSBMb2dNYW5hZ2VyUHJvcGVydGllcy5uZXdDb21wYXJhdG9yKGsuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhrLCBjLmdldENsYXNzKCkpOworCisgICAgICAgICAgICBzZXRQZW5kaW5nKG5ldyBUaHJlYWREZWF0aCgpKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgYyA9IExvZ01hbmFnZXJQcm9wZXJ0aWVzLm5ld0NvbXBhcmF0b3Ioay5nZXROYW1lKCkpOworICAgICAgICAgICAgICAgIGZhaWwoU3RyaW5nLnZhbHVlT2YoYykpOworICAgICAgICAgICAgfSBjYXRjaCAoVGhyZWFkRGVhdGggZXhwZWN0KSB7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHNldFBlbmRpbmcobmV3IE91dE9mTWVtb3J5RXJyb3IoKSk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGMgPSBMb2dNYW5hZ2VyUHJvcGVydGllcy5uZXdDb21wYXJhdG9yKGsuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgICAgICBmYWlsKFN0cmluZy52YWx1ZU9mKGMpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE91dE9mTWVtb3J5RXJyb3IgZXhwZWN0KSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBzZXRQZW5kaW5nKG51bGwpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RXNjYXBpbmdFcnJvckVycm9yTWFuYWdlcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2xhc3M8Pz4gayA9IEVycm9yRXJyb3JNYW5hZ2VyLmNsYXNzOworICAgICAgICAgICAgRXJyb3JNYW5hZ2VyIGY7CisKKyAgICAgICAgICAgIGYgPSBMb2dNYW5hZ2VyUHJvcGVydGllcy5uZXdFcnJvck1hbmFnZXIoay5nZXROYW1lKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGssIGYuZ2V0Q2xhc3MoKSk7CisKKyAgICAgICAgICAgIHNldFBlbmRpbmcobmV3IFRocmVhZERlYXRoKCkpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBmID0gTG9nTWFuYWdlclByb3BlcnRpZXMubmV3RXJyb3JNYW5hZ2VyKGsuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgICAgICBmYWlsKFN0cmluZy52YWx1ZU9mKGYpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFRocmVhZERlYXRoIGV4cGVjdCkgeworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBzZXRQZW5kaW5nKG5ldyBPdXRPZk1lbW9yeUVycm9yKCkpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBmID0gTG9nTWFuYWdlclByb3BlcnRpZXMubmV3RXJyb3JNYW5hZ2VyKGsuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgICAgICBmYWlsKFN0cmluZy52YWx1ZU9mKGYpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE91dE9mTWVtb3J5RXJyb3IgZXhwZWN0KSB7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBzZXRQZW5kaW5nKG51bGwpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RXNjYXBpbmdGaWx0ZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENsYXNzPD8+IGsgPSBFcnJvckZpbHRlci5jbGFzczsKKyAgICAgICAgICAgIEZpbHRlciBmOworCisgICAgICAgICAgICBmID0gTG9nTWFuYWdlclByb3BlcnRpZXMubmV3RmlsdGVyKGsuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhrLCBmLmdldENsYXNzKCkpOworCisgICAgICAgICAgICBzZXRQZW5kaW5nKG5ldyBUaHJlYWREZWF0aCgpKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZiA9IExvZ01hbmFnZXJQcm9wZXJ0aWVzLm5ld0ZpbHRlcihrLmdldE5hbWUoKSk7CisgICAgICAgICAgICAgICAgZmFpbChTdHJpbmcudmFsdWVPZihmKSk7CisgICAgICAgICAgICB9IGNhdGNoIChUaHJlYWREZWF0aCBleHBlY3QpIHsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgc2V0UGVuZGluZyhuZXcgT3V0T2ZNZW1vcnlFcnJvcigpKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZiA9IExvZ01hbmFnZXJQcm9wZXJ0aWVzLm5ld0ZpbHRlcihrLmdldE5hbWUoKSk7CisgICAgICAgICAgICAgICAgZmFpbChTdHJpbmcudmFsdWVPZihmKSk7CisgICAgICAgICAgICB9IGNhdGNoIChPdXRPZk1lbW9yeUVycm9yIGV4cGVjdCkgeworICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgc2V0UGVuZGluZyhudWxsKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEVzY2FwaW5nRm9ybWF0dGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDbGFzczw/PiBrID0gRXJyb3JGb3JtYXR0ZXIuY2xhc3M7CisgICAgICAgICAgICBGb3JtYXR0ZXIgZjsKKworICAgICAgICAgICAgZiA9IExvZ01hbmFnZXJQcm9wZXJ0aWVzLm5ld0Zvcm1hdHRlcihrLmdldE5hbWUoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoaywgZi5nZXRDbGFzcygpKTsKKworICAgICAgICAgICAgc2V0UGVuZGluZyhuZXcgVGhyZWFkRGVhdGgoKSk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGYgPSBMb2dNYW5hZ2VyUHJvcGVydGllcy5uZXdGb3JtYXR0ZXIoay5nZXROYW1lKCkpOworICAgICAgICAgICAgICAgIGZhaWwoU3RyaW5nLnZhbHVlT2YoZikpOworICAgICAgICAgICAgfSBjYXRjaCAoVGhyZWFkRGVhdGggZXhwZWN0KSB7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHNldFBlbmRpbmcobmV3IE91dE9mTWVtb3J5RXJyb3IoKSk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGYgPSBMb2dNYW5hZ2VyUHJvcGVydGllcy5uZXdGb3JtYXR0ZXIoay5nZXROYW1lKCkpOworICAgICAgICAgICAgICAgIGZhaWwoU3RyaW5nLnZhbHVlT2YoZikpOworICAgICAgICAgICAgfSBjYXRjaCAoT3V0T2ZNZW1vcnlFcnJvciBleHBlY3QpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHNldFBlbmRpbmcobnVsbCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRab25lZERhdGVUaW1lKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIExvZ1JlY29yZCByMSA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAiIik7CisgICAgICAgIExvZ1JlY29yZCByMiA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAiIik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaW5hbCBDbGFzczw/PiBrID0gQ2xhc3MuZm9yTmFtZSgiamF2YS50aW1lLlpvbmVkRGF0ZVRpbWUiKTsKKyAgICAgICAgICAgIHNldEVwb2NoU2Vjb25kKHIxLCAxMDAsIDEpOworICAgICAgICAgICAgc2V0RXBvY2hTZWNvbmQocjIsIDEwMCwgMSk7CisgICAgICAgICAgICBDb21wYXJhYmxlPE9iamVjdD4gYzEgPSAoQ29tcGFyYWJsZTxPYmplY3Q+KQorICAgICAgICAgICAgICAgIExvZ01hbmFnZXJQcm9wZXJ0aWVzLmdldFpvbmVkRGF0ZVRpbWUocjEpOworICAgICAgICAgICAgQ29tcGFyYWJsZTxPYmplY3Q+IGMyID0gKENvbXBhcmFibGU8T2JqZWN0PikKKyAgICAgICAgICAgICAgICBMb2dNYW5hZ2VyUHJvcGVydGllcy5nZXRab25lZERhdGVUaW1lKHIyKTsKKworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGssIGMxLmdldENsYXNzKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGssIGMyLmdldENsYXNzKCkpOworICAgICAgICAgICAgYXNzZXJ0Tm90U2FtZShjMSwgYzIpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGMxLmdldENsYXNzKCksIGMyLmdldENsYXNzKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGMxLmNvbXBhcmVUbyhjMikpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBOb1N1Y2hNZXRob2RFeGNlcHRpb24gcHJlSmRrOSkgeworICAgICAgICAgICAgYXNzZXJ0TnVsbChMb2dNYW5hZ2VyUHJvcGVydGllcy5nZXRab25lZERhdGVUaW1lKHIxKSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKExvZ01hbmFnZXJQcm9wZXJ0aWVzLmdldFpvbmVkRGF0ZVRpbWUocjIpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoaGFzSmF2YVRpbWVNb2R1bGUoKSk7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIENsYXNzTm90Rm91bmRFeGNlcHRpb24gcHJlSmRrOCkgeworICAgICAgICAgICAgYXNzZXJ0TnVsbChMb2dNYW5hZ2VyUHJvcGVydGllcy5nZXRab25lZERhdGVUaW1lKHIxKSk7CisgICAgICAgICAgICBhc3NlcnROdWxsKExvZ01hbmFnZXJQcm9wZXJ0aWVzLmdldFpvbmVkRGF0ZVRpbWUocjIpKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGhhc0phdmFUaW1lTW9kdWxlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QoZXhwZWN0ZWQ9TnVsbFBvaW50ZXJFeGNlcHRpb24uY2xhc3MpCisgICAgcHVibGljIHZvaWQgdGVzdEdldFpvbmVkRGF0ZVRpbWVOdWxsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIExvZ01hbmFnZXJQcm9wZXJ0aWVzLmdldFpvbmVkRGF0ZVRpbWUoKExvZ1JlY29yZCkgbnVsbCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBzZXRQZW5kaW5nKGZpbmFsIFRocm93YWJsZSB0KSB7CisgICAgICAgIGlmICh0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIFBFTkRJTkcuc2V0KHQpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgUEVORElORy5yZW1vdmUoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHN0YXRpYyB2b2lkIHRocm93UGVuZGluZ0lmU2V0KCkgeworICAgICAgICBUaHJvd2FibGUgdCA9IFBFTkRJTkcuZ2V0KCk7CisgICAgICAgIGlmICh0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIGlmICh0IGluc3RhbmNlb2YgRXJyb3IpIHsKKyAgICAgICAgICAgICAgICB0ID0gdC5maWxsSW5TdGFja1RyYWNlKCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0IHQgaW5zdGFuY2VvZiBFcnJvciA6IHQ7CisgICAgICAgICAgICAgICAgdGhyb3cgKEVycm9yKSB0OworICAgICAgICAgICAgfSBlbHNlIGlmICh0IGluc3RhbmNlb2YgUnVudGltZUV4Y2VwdGlvbikgeworICAgICAgICAgICAgICAgIHQgPSB0LmZpbGxJblN0YWNrVHJhY2UoKTsKKyAgICAgICAgICAgICAgICBhc3NlcnQgdCBpbnN0YW5jZW9mIFJ1bnRpbWVFeGNlcHRpb24gOiB0OworICAgICAgICAgICAgICAgIHRocm93IChSdW50aW1lRXhjZXB0aW9uKSB0OworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IodCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBGaWVsZCBzZXRBY2Nlc3NpYmxlKEZpZWxkIGYpIHsKKyAgICAgICAgZi5zZXRBY2Nlc3NpYmxlKHRydWUpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzdW1lTm9KaXQoKTsKKyAgICAgICAgICAgIGlmIChNb2RpZmllci5pc0ZpbmFsKGYuZ2V0TW9kaWZpZXJzKCkpKSB7CisgICAgICAgICAgICAgICAgRmllbGQgbW9kID0gRmllbGQuY2xhc3MuZ2V0RGVjbGFyZWRGaWVsZCgibW9kaWZpZXJzIik7CisgICAgICAgICAgICAgICAgbW9kLnNldEFjY2Vzc2libGUodHJ1ZSk7CisgICAgICAgICAgICAgICAgbW9kLnNldEludChmLCBmLmdldE1vZGlmaWVycygpICYgfk1vZGlmaWVyLkZJTkFMKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gbW9kOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHwgUmVmbGVjdGl2ZU9wZXJhdGlvbkV4Y2VwdGlvbiByZSkgeworICAgICAgICAgICAgQXNzdW1lLmFzc3VtZU5vRXhjZXB0aW9uKHJlKTsKKyAgICAgICAgfQorICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIGJvb2xlYW4gY29udGFpbnMoUHJvcGVydGllcyBwcm9wcywgU3RyaW5nIGtleSwgU3RyaW5nIHZhbHVlKSB7CisgICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICAvL3dhbGsgdGhlIGVudHJ5IHNldCBzbyB3ZSBkb24ndCBwcmVsb2FkIGEga2V5IGZyb20gdGhlIG1hbmFnZXIuCisgICAgICAgIGZvciAoTWFwLkVudHJ5PD8sID8+IGUgOiBwcm9wcy5lbnRyeVNldCgpKSB7CisgICAgICAgICAgICBpZiAoa2V5LmVxdWFscyhlLmdldEtleSgpKSkgeworICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZS5lcXVhbHMoZS5nZXRWYWx1ZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBFbXB0eUF1dGhlbnRpY2F0b3IgZXh0ZW5kcyBqYXZheC5tYWlsLkF1dGhlbnRpY2F0b3IgeworCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgUGFzc3dvcmRBdXRoZW50aWNhdGlvbiBnZXRQYXNzd29yZEF1dGhlbnRpY2F0aW9uKCkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEVycm9yQXV0aGVudGljYXRvciBleHRlbmRzIGphdmF4Lm1haWwuQXV0aGVudGljYXRvciB7CisKKyAgICAgICAgcHVibGljIEVycm9yQXV0aGVudGljYXRvcigpIHsKKyAgICAgICAgICAgIHRocm93UGVuZGluZ0lmU2V0KCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIFBhc3N3b3JkQXV0aGVudGljYXRpb24gZ2V0UGFzc3dvcmRBdXRoZW50aWNhdGlvbigpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEVycm9yQ29tcGFyYXRvciBpbXBsZW1lbnRzIENvbXBhcmF0b3I8TG9nUmVjb3JkPiwKKyAgICAgICAgICAgIFNlcmlhbGl6YWJsZSB7CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CisKKyAgICAgICAgcHVibGljIEVycm9yQ29tcGFyYXRvcigpIHsKKyAgICAgICAgICAgIHRocm93UGVuZGluZ0lmU2V0KCk7CisgICAgICAgIH0KKworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygib3ZlcnJpZGUiKSAvL0pESy02OTU0MjM0CisgICAgICAgIHB1YmxpYyBpbnQgY29tcGFyZShMb2dSZWNvcmQgcjEsIExvZ1JlY29yZCByMikgeworICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCIiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgQXNjQ29tcGFyYXRvciBpbXBsZW1lbnRzIENvbXBhcmF0b3I8TG9nUmVjb3JkPiwKKyAgICAgICAgICAgIFNlcmlhbGl6YWJsZSB7CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CisKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoIm92ZXJyaWRlIikgLy9KREstNjk1NDIzNAorICAgICAgICBwdWJsaWMgaW50IGNvbXBhcmUoTG9nUmVjb3JkIHIxLCBMb2dSZWNvcmQgcjIpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICB9CisKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoIm92ZXJyaWRlIikKKyAgICAgICAgcHVibGljIENvbXBhcmF0b3I8TG9nUmVjb3JkPiByZXZlcnNlZCgpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgRGVzY0NvbXBhcmF0b3IoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgRGVzY0NvbXBhcmF0b3IgaW1wbGVtZW50cyBDb21wYXJhdG9yPExvZ1JlY29yZD4sCisgICAgICAgICAgICBTZXJpYWxpemFibGUgeworCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOworCisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJvdmVycmlkZSIpIC8vSkRLLTY5NTQyMzQKKyAgICAgICAgcHVibGljIGludCBjb21wYXJlKExvZ1JlY29yZCByMSwgTG9nUmVjb3JkIHIyKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJvdmVycmlkZSIpCisgICAgICAgIHB1YmxpYyBDb21wYXJhdG9yPExvZ1JlY29yZD4gcmV2ZXJzZWQoKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IEFzY0NvbXBhcmF0b3IoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgRXJyb3JGaWx0ZXIgaW1wbGVtZW50cyBGaWx0ZXIgeworCisgICAgICAgIHB1YmxpYyBFcnJvckZpbHRlcigpIHsKKyAgICAgICAgICAgIHRocm93UGVuZGluZ0lmU2V0KCk7CisgICAgICAgIH0KKworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygib3ZlcnJpZGUiKSAvL0pESy02OTU0MjM0CisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzTG9nZ2FibGUoTG9nUmVjb3JkIHJlY29yZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCIiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgRXJyb3JGb3JtYXR0ZXIgZXh0ZW5kcyBGb3JtYXR0ZXIgeworCisgICAgICAgIHB1YmxpYyBFcnJvckZvcm1hdHRlcigpIHsKKyAgICAgICAgICAgIHRocm93UGVuZGluZ0lmU2V0KCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFN0cmluZyBmb3JtYXQoTG9nUmVjb3JkIHJlY29yZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCIiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgRXJyb3JFcnJvck1hbmFnZXIgZXh0ZW5kcyBFcnJvck1hbmFnZXIgeworCisgICAgICAgIHB1YmxpYyBFcnJvckVycm9yTWFuYWdlcigpIHsKKyAgICAgICAgICAgIHRocm93UGVuZGluZ0lmU2V0KCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgZXJyb3IoU3RyaW5nIG1zZywgRXhjZXB0aW9uIGV4LCBpbnQgY29kZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCIiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIE5vSG9zdFNlcnZpY2UgZXh0ZW5kcyBTZXJ2aWNlIHsKKworICAgICAgICBwdWJsaWMgTm9Ib3N0U2VydmljZShTZXNzaW9uIHNlc3Npb24pIHsKKyAgICAgICAgICAgIHN1cGVyKHNlc3Npb24sIG5ldyBVUkxOYW1lKCJ0ZXN0Oi8vc29tZWhvc3QiKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBOb3RBbGxvd2VkU2VydmljZSBleHRlbmRzIFNlcnZpY2UgeworCisgICAgICAgIHB1YmxpYyBOb3RBbGxvd2VkU2VydmljZShTZXNzaW9uIHNlc3Npb24pIHsKKyAgICAgICAgICAgIHN1cGVyKHNlc3Npb24sIG5ldyBVUkxOYW1lKCJ0ZXN0Oi8vc29tZWhvc3QiKSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgU3RyaW5nIGdldExvY2FsSG9zdCgpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBTZWN1cml0eUV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgTG9nUGVybVNlY3VyaXR5TWFuYWdlciBleHRlbmRzIFNlY3VyaXR5TWFuYWdlciB7CisKKyAgICAgICAgdm9sYXRpbGUgYm9vbGVhbiBzZWN1cmUgPSBmYWxzZTsKKworICAgICAgICBMb2dQZXJtU2VjdXJpdHlNYW5hZ2VyKCkgeworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGNoZWNrUGVybWlzc2lvbihqYXZhLnNlY3VyaXR5LlBlcm1pc3Npb24gcGVybSkgeworICAgICAgICAgICAgdHJ5IHsgLy9DYWxsIHN1cGVyIGNsYXNzIGFsd2F5cyBmb3IgamF2YS5zZWN1cml0eS5kZWJ1ZyB0cmFjaW5nLgorICAgICAgICAgICAgICAgIHN1cGVyLmNoZWNrUGVybWlzc2lvbihwZXJtKTsKKyAgICAgICAgICAgICAgICBjaGVja1Blcm1pc3Npb24ocGVybSwgbmV3IFNlY3VyaXR5RXhjZXB0aW9uKHBlcm0udG9TdHJpbmcoKSkpOworICAgICAgICAgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gc2UpIHsKKyAgICAgICAgICAgICAgICBjaGVja1Blcm1pc3Npb24ocGVybSwgc2UpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGNoZWNrUGVybWlzc2lvbihqYXZhLnNlY3VyaXR5LlBlcm1pc3Npb24gcGVybSwgT2JqZWN0IGNvbnRleHQpIHsKKyAgICAgICAgICAgIHRyeSB7IC8vQ2FsbCBzdXBlciBjbGFzcyBhbHdheXMgZm9yIGphdmEuc2VjdXJpdHkuZGVidWcgdHJhY2luZy4KKyAgICAgICAgICAgICAgICBzdXBlci5jaGVja1Blcm1pc3Npb24ocGVybSwgY29udGV4dCk7CisgICAgICAgICAgICAgICAgY2hlY2tQZXJtaXNzaW9uKHBlcm0sIG5ldyBTZWN1cml0eUV4Y2VwdGlvbihwZXJtLnRvU3RyaW5nKCkpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHNlKSB7CisgICAgICAgICAgICAgICAgY2hlY2tQZXJtaXNzaW9uKHBlcm0sIHNlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHByaXZhdGUgdm9pZCBjaGVja1Blcm1pc3Npb24oamF2YS5zZWN1cml0eS5QZXJtaXNzaW9uIHBlcm0sIFNlY3VyaXR5RXhjZXB0aW9uIHNlKSB7CisgICAgICAgICAgICBpZiAoc2VjdXJlICYmIHBlcm0gaW5zdGFuY2VvZiBMb2dnaW5nUGVybWlzc2lvbikgeworICAgICAgICAgICAgICAgIHRocm93IHNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL2xvZ2dpbmcvTWFpbEhhbmRsZXJUZXN0LmphdmEgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3V0aWwvbG9nZ2luZy9NYWlsSGFuZGxlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMjg3MjFkCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL2xvZ2dpbmcvTWFpbEhhbmRsZXJUZXN0LmphdmEKQEAgLTAsMCArMSw4NTIwIEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDA5LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKiBDb3B5cmlnaHQgKGMpIDIwMDksIDIwMTggSmFzb24gTWVocmVucy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCitwYWNrYWdlIGNvbS5zdW4ubWFpbC51dGlsLmxvZ2dpbmc7CisKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YS5sYW5nLm1hbmFnZW1lbnQuQ29tcGlsYXRpb25NWEJlYW47CitpbXBvcnQgamF2YS5sYW5nLm1hbmFnZW1lbnQuTWFuYWdlbWVudEZhY3Rvcnk7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuRmllbGQ7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTW9kaWZpZXI7CitpbXBvcnQgamF2YS5uZXQuKjsKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBqYXZhLnV0aWwubG9nZ2luZy4qOworaW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkZvcm1hdHRlcjsKK2ltcG9ydCBqYXZheC5hY3RpdmF0aW9uLio7CitpbXBvcnQgamF2YXgubWFpbC4qOworaW1wb3J0IGphdmF4Lm1haWwuQXV0aGVudGljYXRvcjsKK2ltcG9ydCBqYXZheC5tYWlsLlBhc3N3b3JkQXV0aGVudGljYXRpb247CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC4qOworaW1wb3J0IG9yZy5qdW5pdC4qOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0Lio7CisKKy8qKgorICogVGVzdCBjYXNlIGZvciB0aGUgTWFpbEhhbmRsZXIgc3BlYy4KKyAqCisgKiBAYXV0aG9yIEphc29uIE1laHJlbnMKKyAqLworcHVibGljIGNsYXNzIE1haWxIYW5kbGVyVGVzdCBleHRlbmRzIEFic3RyYWN0TG9nZ2luZyB7CisKKyAgICAvKioKKyAgICAgKiBTZWUgTG9nTWFuYWdlci4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTE9HX0NGR19LRVkgPSAiamF2YS51dGlsLmxvZ2dpbmcuY29uZmlnLmZpbGUiOworICAgIC8qKgorICAgICAqIEhvbGRlciB1c2VkIHRvIGluamVjdCBUaHJvd2FibGVzIGludG8gb3RoZXIgQVBJcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUaHJlYWRMb2NhbDxUaHJvd2FibGU+IFBFTkRJTkcgPSBuZXcgVGhyZWFkTG9jYWw8PigpOworICAgIC8qKgorICAgICAqIEhvbGRlciB1c2VkIHRvIGluamVjdCBDbGFzc0xvYWRlcnMgaW50byBvdGhlciBBUElzLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRocmVhZExvY2FsPENsYXNzTG9hZGVyPiBMT0FERVIgPSBuZXcgVGhyZWFkTG9jYWw8PigpOworICAgIC8qKgorICAgICAqIFN0b3JlcyB0aGUgdmFsdWUgb2YgYSBwb3J0IHRoYXQgaXMgbm90IHVzZWQgb24gdGhlIGxvY2FsIG1hY2hpbmUuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9sYXRpbGUgaW50IE9QRU5fUE9SVCA9IEludGVnZXIuTUlOX1ZBTFVFOworICAgIC8qKgorICAgICAqIEEgaG9zdCBuYW1lIHRoYXQgY2FuIG5vdCBiZSByZXNvbHZlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVU5LTk9XTl9IT1NUID0gImJhZC1ob3N0LW5hbWUiOworICAgIC8qKgorICAgICAqIFN0b3JlcyBhIHdyaXRhYmxlIGRpcmVjdG9yeSB0aGF0IGlzIGluIHRoZSBjbGFzcyBwYXRoIGFuZCB2aXNpYmxlIHRvIHRoZQorICAgICAqIGNvbnRleHQgY2xhc3MgbG9hZGVyLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIHZvbGF0aWxlIEZpbGUgYW55Q2xhc3NQYXRoRGlyID0gbnVsbDsKKyAgICAvKioKKyAgICAgKiBVc2VkIHRvIHByZXZlbnQgRy5DLiBvZiBsb2dnZXJzLgorICAgICAqLworICAgIHByaXZhdGUgdm9sYXRpbGUgT2JqZWN0IGhhcmRSZWY7CisKKyAgICBAQmVmb3JlQ2xhc3MKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0VXBDbGFzcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjaGVja0pWTU9wdGlvbnMoKTsKKyAgICAgICAgT1BFTl9QT1JUID0gZmluZE9wZW5Qb3J0KCk7CisgICAgICAgIGNoZWNrVW5rbm93bkhvc3QoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShmaW5kQ2xhc3NQYXRoRGlyKCkuaXNEaXJlY3RvcnkoKSk7CisgICAgfQorCisgICAgQEFmdGVyQ2xhc3MKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgdGVhckRvd25DbGFzcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjaGVja0pWTU9wdGlvbnMoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShjaGVja1VudXNlZFBvcnQoT1BFTl9QT1JUKSk7CisgICAgICAgIE9QRU5fUE9SVCA9IEludGVnZXIuTUlOX1ZBTFVFOworICAgICAgICBjaGVja1Vua25vd25Ib3N0KCk7CisgICAgICAgIGFueUNsYXNzUGF0aERpciA9IG51bGw7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBhc3N1bWVOb0ppdCgpIHsKKyAgICAgICAgQ29tcGlsYXRpb25NWEJlYW4gYyA9IE1hbmFnZW1lbnRGYWN0b3J5LmdldENvbXBpbGF0aW9uTVhCZWFuKCk7CisgICAgICAgIGlmIChjICE9IG51bGwpIHsgLy8tWGludAorICAgICAgICAgICAgQXNzdW1lLmFzc3VtZU5vRXhjZXB0aW9uKG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgIGMuZ2V0TmFtZSgpICsgIiBtdXN0IGJlIGRpc2FibGVkLiIpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgZnVsbEZlbmNlKCkgeworICAgICAgICBMb2dNYW5hZ2VyLmdldExvZ01hbmFnZXIoKS5nZXRQcm9wZXJ0eSgiIik7CisgICAgfQorCisgICAgQEJlZm9yZQorICAgIHB1YmxpYyB2b2lkIHNldFVwKCkgeworICAgICAgICBmdWxsRmVuY2UoKTsKKyAgICAgICAgYXNzZXJ0TnVsbChoYXJkUmVmKTsKKyAgICB9CisKKyAgICBAQWZ0ZXIKKyAgICBwdWJsaWMgdm9pZCB0ZWFyRG93bigpIHsKKyAgICAgICAgZnVsbEZlbmNlKCk7CisgICAgICAgIGhhcmRSZWYgPSBudWxsOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgY2hlY2tVbmtub3duSG9zdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgSW5ldEFkZHJlc3MuZ2V0QnlOYW1lKFVOS05PV05fSE9TVCk7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoVU5LTk9XTl9IT1NUKTsKKyAgICAgICAgfSBjYXRjaCAoVW5rbm93bkhvc3RFeGNlcHRpb24gZXhwZWN0KSB7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGNoZWNrSlZNT3B0aW9ucygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRUcnVlKE1haWxIYW5kbGVyVGVzdC5jbGFzcy5kZXNpcmVkQXNzZXJ0aW9uU3RhdHVzKCkpOworICAgICAgICBhc3NlcnROdWxsKFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS51dGlsLmxvZ2dpbmcubWFuYWdlciIpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChTeXN0ZW0uZ2V0UHJvcGVydHkoImphdmEudXRpbC5sb2dnaW5nLmNvbmZpZy5jbGFzcyIpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChTeXN0ZW0uZ2V0UHJvcGVydHkoTE9HX0NGR19LRVkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKExvZ01hbmFnZXIuY2xhc3MsIExvZ01hbmFnZXIuZ2V0TG9nTWFuYWdlcigpLmdldENsYXNzKCkpOworICAgICAgICBhc3NlcnRUcnVlKExPV19DQVBBQ0lUWSA8IE5VTV9SVU5TKTsKKyAgICAgICAgLy9UcnkgdG8gaG9sZCBNQVhfQ0FQQUNJVFkgYXJyYXkgd2l0aCBsb2cgcmVjb3Jkcy4KKyAgICAgICAgYXNzZXJ0VHJ1ZSgoNjBMICogMTAyNEwgKiAxMDI0TCkgPD0gUnVudGltZS5nZXRSdW50aW1lKCkubWF4TWVtb3J5KCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLmdldEhvc3ROYW1lKCkubGVuZ3RoKCkgPT0gMCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbmtub3duSG9zdEV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChVbmtub3duSG9zdEV4Y2VwdGlvbiBVSEUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihVSEUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgVGhyb3dhYmxlIGdldFBlbmRpbmcoKSB7CisgICAgICAgIHJldHVybiBQRU5ESU5HLmdldCgpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgc2V0UGVuZGluZyhmaW5hbCBUaHJvd2FibGUgdCkgeworICAgICAgICBpZiAodCAhPSBudWxsKSB7CisgICAgICAgICAgICBQRU5ESU5HLnNldCh0KTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIFBFTkRJTkcucmVtb3ZlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBGaWVsZCBzZXRBY2Nlc3NpYmxlKEZpZWxkIGYpIHsKKyAgICAgICAgZi5zZXRBY2Nlc3NpYmxlKHRydWUpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzdW1lTm9KaXQoKTsKKyAgICAgICAgICAgIGlmIChNb2RpZmllci5pc0ZpbmFsKGYuZ2V0TW9kaWZpZXJzKCkpKSB7CisgICAgICAgICAgICAgICAgRmllbGQgbW9kID0gRmllbGQuY2xhc3MuZ2V0RGVjbGFyZWRGaWVsZCgibW9kaWZpZXJzIik7CisgICAgICAgICAgICAgICAgbW9kLnNldEFjY2Vzc2libGUodHJ1ZSk7CisgICAgICAgICAgICAgICAgbW9kLnNldEludChmLCBmLmdldE1vZGlmaWVycygpICYgfk1vZGlmaWVyLkZJTkFMKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gbW9kOworICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHJlKSB7CisgICAgICAgICAgICBBc3N1bWUuYXNzdW1lTm9FeGNlcHRpb24ocmUpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgQXNzdW1lLmFzc3VtZU5vRXhjZXB0aW9uKGUpOworICAgICAgICB9CisgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgc2V0KENsYXNzTG9hZGVyIGV4cGVjdCkgeworICAgICAgICBpZiAoZXhwZWN0ID09IG51bGwpIHsKKyAgICAgICAgICAgIExPQURFUi5yZW1vdmUoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIExPQURFUi5zZXQoZXhwZWN0KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHN0YXRpYyB2b2lkIHRocm93UGVuZGluZygpIHsKKyAgICAgICAgVGhyb3dhYmxlIHQgPSBQRU5ESU5HLmdldCgpOworICAgICAgICBpZiAodCBpbnN0YW5jZW9mIEVycm9yKSB7CisgICAgICAgICAgICB0ID0gdC5maWxsSW5TdGFja1RyYWNlKCk7CisgICAgICAgICAgICBhc3NlcnQgdCBpbnN0YW5jZW9mIEVycm9yIDogdDsKKyAgICAgICAgICAgIHRocm93IChFcnJvcikgdDsKKyAgICAgICAgfSBlbHNlIGlmICh0IGluc3RhbmNlb2YgUnVudGltZUV4Y2VwdGlvbikgeworICAgICAgICAgICAgdCA9IHQuZmlsbEluU3RhY2tUcmFjZSgpOworICAgICAgICAgICAgYXNzZXJ0IHQgaW5zdGFuY2VvZiBSdW50aW1lRXhjZXB0aW9uIDogdDsKKyAgICAgICAgICAgIHRocm93IChSdW50aW1lRXhjZXB0aW9uKSB0OworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKHQpOworICAgICAgICB9CisgICAgfQorCisgICAgc3RhdGljIGJvb2xlYW4gaXNTZWN1cml0eURlYnVnKCkgeworICAgICAgICBib29sZWFuIGRlYnVnOworICAgICAgICBmaW5hbCBTdHJpbmcgdmFsdWUgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImphdmEuc2VjdXJpdHkuZGVidWciKTsKKyAgICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHsKKyAgICAgICAgICAgIGRlYnVnID0gdmFsdWUuY29udGFpbnMoImFsbCIpCisgICAgICAgICAgICAgICAgICAgIHx8IHZhbHVlLmNvbnRhaW5zKCJhY2Nlc3MiKQorICAgICAgICAgICAgICAgICAgICB8fCB2YWx1ZS5jb250YWlucygic3RhY2siKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGRlYnVnID0gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGRlYnVnOworICAgIH0KKworICAgIHN0YXRpYyB2b2lkIHNlY3VyaXR5RGVidWdQcmludChUaHJvd2FibGUgc2UpIHsKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoIlVzZU9mU3lzdGVtT3V0T3JTeXN0ZW1FcnIiKQorICAgICAgICBmaW5hbCBQcmludFN0cmVhbSBlcnIgPSBTeXN0ZW0uZXJyOworICAgICAgICBlcnIucHJpbnRsbigiU3VwcHJlc3NlZCBzZWN1cml0eSBleGNlcHRpb24gdG8gYWxsb3cgYWNjZXNzOiIpOworICAgICAgICBzZS5wcmludFN0YWNrVHJhY2UoZXJyKTsKKyAgICB9CisKKyAgICBzdGF0aWMgdm9pZCBjaGVja0NvbnRleHRDbGFzc0xvYWRlcihDbGFzc0xvYWRlciBleHBlY3QpIHsKKyAgICAgICAgT2JqZWN0IGNjbCA9IFRocmVhZC5jdXJyZW50VGhyZWFkKCkuZ2V0Q29udGV4dENsYXNzTG9hZGVyKCk7CisgICAgICAgIGlmIChleHBlY3QgIT0gY2NsKSB7CisgICAgICAgICAgICBBc3NlcnRpb25FcnJvciBhZSA9IG5ldyBBc3NlcnRpb25FcnJvcihleHBlY3QgKyAiICE9ICIgKyBjY2wKKyAgICAgICAgICAgICAgICAgICAgKyAiLCBzbT0iICsgU3lzdGVtLmdldFNlY3VyaXR5TWFuYWdlcigpKTsKKyAgICAgICAgICAgIGR1bXAoYWUpOworICAgICAgICAgICAgdGhyb3cgYWU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RDaGlsZENsYXNzTG9hZGVyKCkgeworICAgICAgICBhc3NlcnROdWxsKFN5c3RlbS5nZXRTZWN1cml0eU1hbmFnZXIoKSk7CisgICAgICAgIGZpbmFsIFRocmVhZCB0aHJlYWQgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpOworICAgICAgICBmaW5hbCBDbGFzc0xvYWRlciBjY2wgPSB0aHJlYWQuZ2V0Q29udGV4dENsYXNzTG9hZGVyKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBVUkxDbGFzc0xvYWRlciBjaGlsZCA9IG5ldyBVUkxDbGFzc0xvYWRlcihuZXcgVVJMWzBdLCBjY2wpOworCisgICAgICAgICAgICB0aHJlYWQuc2V0Q29udGV4dENsYXNzTG9hZGVyKGNoaWxkKTsKKyAgICAgICAgICAgIHRlc3RDYWxsaW5nQ2xhc3NMb2FkZXIoKENsYXNzTG9hZGVyU2VjdXJpdHlNYW5hZ2VyKSBudWxsLCBjaGlsZCk7CisKKyAgICAgICAgICAgIHRocmVhZC5zZXRDb250ZXh0Q2xhc3NMb2FkZXIoY2hpbGQpOworICAgICAgICAgICAgdGVzdENhbGxpbmdDbGFzc0xvYWRlcihuZXcgQ2xhc3NMb2FkZXJTZWN1cml0eU1hbmFnZXIoKSwgY2hpbGQpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdGhyZWFkLnNldENvbnRleHRDbGFzc0xvYWRlcihjY2wpOworICAgICAgICB9CisgICAgICAgIGFzc2VydE51bGwoU3lzdGVtLmdldFNlY3VyaXR5TWFuYWdlcigpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdENhbGxpbmdDbGFzc0xvYWRlcigKKyAgICAgICAgICAgIENsYXNzTG9hZGVyU2VjdXJpdHlNYW5hZ2VyIHNtLCBDbGFzc0xvYWRlciBleHBlY3QpIHsKKyAgICAgICAgSW50ZXJuYWxFcnJvck1hbmFnZXIgZW0gPSBuZXcgQ2xhc3NMb2FkZXJFcnJvck1hbmFnZXIoZXhwZWN0KTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIE1haWxIYW5kbGVyIGluc3RhbmNlID0gbmV3IE1haWxIYW5kbGVyKGNyZWF0ZUluaXRQcm9wZXJ0aWVzKCIiKSk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGlmIChzbSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5zZXRTZWN1cml0eU1hbmFnZXIoc20pOworICAgICAgICAgICAgICAgICAgICBzbS5zZWN1cmUgPSB0cnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpbnN0YW5jZS5zZXRFcnJvck1hbmFnZXIoZW0pOworICAgICAgICAgICAgICAgIGluc3RhbmNlLnNldExldmVsKExldmVsLkFMTCk7CisgICAgICAgICAgICAgICAgaW5zdGFuY2Uuc2V0UHVzaExldmVsKExldmVsLlNFVkVSRSk7CisgICAgICAgICAgICAgICAgaW5zdGFuY2Uuc2V0Q29tcGFyYXRvcihuZXcgQ2xhc3NMb2FkZXJDb21wYXJhdG9yKGV4cGVjdCkpOworICAgICAgICAgICAgICAgIGluc3RhbmNlLnNldEZpbHRlcihuZXcgQ2xhc3NMb2FkZXJGaWx0ZXJGb3JtYXR0ZXIoZXhwZWN0KSk7CisgICAgICAgICAgICAgICAgaW5zdGFuY2Uuc2V0UHVzaEZpbHRlcihuZXcgQ2xhc3NMb2FkZXJGaWx0ZXJGb3JtYXR0ZXIoZXhwZWN0KSk7CisgICAgICAgICAgICAgICAgaW5zdGFuY2Uuc2V0U3ViamVjdChuZXcgQ2xhc3NMb2FkZXJGaWx0ZXJGb3JtYXR0ZXIoZXhwZWN0KSk7CisgICAgICAgICAgICAgICAgaW5zdGFuY2Uuc2V0Rm9ybWF0dGVyKG5ldyBDbGFzc0xvYWRlckZpbHRlckZvcm1hdHRlcihleHBlY3QpKTsKKyAgICAgICAgICAgICAgICBpbnN0YW5jZS5zZXRBdHRhY2htZW50Rm9ybWF0dGVycygKKyAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBDbGFzc0xvYWRlckZpbHRlckZvcm1hdHRlcihleHBlY3QsICJ0ZXN0Q0NMIikpOworICAgICAgICAgICAgICAgIGluc3RhbmNlLnNldEF0dGFjaG1lbnRGaWx0ZXJzKG5ldyBDbGFzc0xvYWRlckZpbHRlckZvcm1hdHRlcihleHBlY3QpKTsKKyAgICAgICAgICAgICAgICBpbnN0YW5jZS5zZXRBdHRhY2htZW50TmFtZXMobmV3IENsYXNzTG9hZGVyRmlsdGVyRm9ybWF0dGVyKGV4cGVjdCkpOworICAgICAgICAgICAgICAgIGluc3RhbmNlLnB1Ymxpc2gobmV3IExvZ1JlY29yZChMZXZlbC5XQVJOSU5HLCAiIikpOworICAgICAgICAgICAgICAgIGluc3RhbmNlLnB1Ymxpc2gobmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICIiKSk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIGluc3RhbmNlLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoc20gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHNtLnNlY3VyZSA9IGZhbHNlOworICAgICAgICAgICAgICAgIFN5c3RlbS5zZXRTZWN1cml0eU1hbmFnZXIoKFNlY3VyaXR5TWFuYWdlcikgbnVsbCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnQgZW0gIT0gbnVsbDsKKyAgICAgICAgZm9yIChFeGNlcHRpb24gZXhjZXB0aW9uIDogZW0uZXhjZXB0aW9ucykgeworICAgICAgICAgICAgVGhyb3dhYmxlIHQgPSBleGNlcHRpb247CisgICAgICAgICAgICBpZiAodCBpbnN0YW5jZW9mIE1lc3NhZ2luZ0V4Y2VwdGlvbiA9PSBmYWxzZSkgeworICAgICAgICAgICAgICAgIGR1bXAodCk7CisgICAgICAgICAgICAgICAgZmFpbCh0LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGFzc2VydEZhbHNlKGVtLmV4Y2VwdGlvbnMuaXNFbXB0eSgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RWZXJpZnlDbGFzc0xvYWRlcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnROdWxsKFN5c3RlbS5nZXRTZWN1cml0eU1hbmFnZXIoKSk7CisgICAgICAgIGZpbmFsIFRocmVhZCB0aHJlYWQgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpOworICAgICAgICBmaW5hbCBDbGFzc0xvYWRlciBjY2wgPSB0aHJlYWQuZ2V0Q29udGV4dENsYXNzTG9hZGVyKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBVUkxDbGFzc0xvYWRlciBjaGlsZCA9IG5ldyBVUkxDbGFzc0xvYWRlcihuZXcgVVJMWzBdLCBjY2wpOworCisgICAgICAgICAgICB0aHJlYWQuc2V0Q29udGV4dENsYXNzTG9hZGVyKGNoaWxkKTsKKyAgICAgICAgICAgIHRlc3RWZXJpZnkoKENsYXNzTG9hZGVyU2VjdXJpdHlNYW5hZ2VyKSBudWxsLCBjaGlsZCk7CisKKyAgICAgICAgICAgIHRocmVhZC5zZXRDb250ZXh0Q2xhc3NMb2FkZXIoY2hpbGQpOworICAgICAgICAgICAgdGVzdFZlcmlmeShuZXcgQ2xhc3NMb2FkZXJTZWN1cml0eU1hbmFnZXIoKSwgY2hpbGQpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdGhyZWFkLnNldENvbnRleHRDbGFzc0xvYWRlcihjY2wpOworICAgICAgICB9CisgICAgICAgIGFzc2VydE51bGwoU3lzdGVtLmdldFNlY3VyaXR5TWFuYWdlcigpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RKYXZhTWFpbExpbmthZ2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLyoqCisgICAgICAgICAqIFRoZSBNYWlsSGFuZGxlciBoYXMgdG8gZGVwZW5kIG9uIHRoZSBvZmZpY2lhbCBKYXZhTWFpbCBzcGVjIGNsYXNzZXMuCisgICAgICAgICAqIFRoZSBsb2dnaW5nLW1haWxoYW5kbGVyLmphciBuZWVkcyB0byBiZSBwb3J0YWJsZSB0byBvdGhlciBwbGF0Zm9ybXMKKyAgICAgICAgICogc28gaXQgZG9lc24ndCBkZXBlbmQgb24gcmVmZXJlbmNlIGltcGxlbWVudGF0aW9uIGNsYXNzZXMgZGlyZWN0bHkuCisgICAgICAgICAqLworICAgICAgICB0ZXN0SmF2YU1haWxMaW5rYWdlKE1haWxIYW5kbGVyLmNsYXNzLCBmYWxzZSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TG9nTWFuYWdlck1vZGlmaWVycygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0TG9nTWFuYWdlck1vZGlmaWVycyhNYWlsSGFuZGxlci5jbGFzcyk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0V2ViYXBwQ2xhc3NMb2FkZXJGaWVsZE5hbWVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RXZWJhcHBDbGFzc0xvYWRlckZpZWxkTmFtZXMoTWFpbEhhbmRsZXIuY2xhc3MpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0VmVyaWZ5KENsYXNzTG9hZGVyU2VjdXJpdHlNYW5hZ2VyIHNtLCBDbGFzc0xvYWRlciBleHBlY3QpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBMb2dNYW5hZ2VyIG1hbmFnZXIgPSBMb2dNYW5hZ2VyLmdldExvZ01hbmFnZXIoKTsKKyAgICAgICAgSW50ZXJuYWxFcnJvck1hbmFnZXIgZW0gPSBudWxsOworICAgICAgICBzZXQoZXhwZWN0KTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZyBwID0gTWFpbEhhbmRsZXIuY2xhc3MuZ2V0TmFtZSgpOworICAgICAgICAgICAgUHJvcGVydGllcyBwcm9wcyA9IGNyZWF0ZUluaXRQcm9wZXJ0aWVzKHApOworICAgICAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIudmVyaWZ5IiksICJsb2NhbCIpOworICAgICAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIuY29tcGFyYXRvciIpLCBDbGFzc0xvYWRlckNvbXBhcmF0b3IuY2xhc3MuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLnB1c2hGaWx0ZXIiKSwgQ2xhc3NMb2FkZXJGaWx0ZXJGb3JtYXR0ZXIuY2xhc3MuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLnN1YmplY3QiKSwgQ2xhc3NMb2FkZXJGaWx0ZXJGb3JtYXR0ZXIuY2xhc3MuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLmVycm9yTWFuYWdlciIpLCBDbGFzc0xvYWRlckVycm9yTWFuYWdlci5jbGFzcy5nZXROYW1lKCkpOworCisgICAgICAgICAgICByZWFkKG1hbmFnZXIsIHByb3BzKTsKKworICAgICAgICAgICAgaWYgKHNtICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uc2V0U2VjdXJpdHlNYW5hZ2VyKHNtKTsKKyAgICAgICAgICAgICAgICBzbS5zZWN1cmUgPSB0cnVlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBNYWlsSGFuZGxlciBpbnN0YW5jZSA9IG5ldyBNYWlsSGFuZGxlcigpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBlbSA9IGludGVybmFsRXJyb3JNYW5hZ2VyRnJvbShpbnN0YW5jZSk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIGluc3RhbmNlLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoc20gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHNtLnNlY3VyZSA9IGZhbHNlOworICAgICAgICAgICAgICAgIFN5c3RlbS5zZXRTZWN1cml0eU1hbmFnZXIoKFNlY3VyaXR5TWFuYWdlcikgbnVsbCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBzZXQoKENsYXNzTG9hZGVyKSBudWxsKTsKKyAgICAgICAgICAgIG1hbmFnZXIucmVzZXQoKTsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydCBlbSAhPSBudWxsOworICAgICAgICBmb3IgKEV4Y2VwdGlvbiBleGNlcHRpb24gOiBlbS5leGNlcHRpb25zKSB7CisgICAgICAgICAgICBUaHJvd2FibGUgdCA9IGV4Y2VwdGlvbjsKKyAgICAgICAgICAgIGlmICh0IGluc3RhbmNlb2YgTWVzc2FnaW5nRXhjZXB0aW9uID09IGZhbHNlKSB7CisgICAgICAgICAgICAgICAgZHVtcCh0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBhc3NlcnRGYWxzZShlbS5leGNlcHRpb25zLmlzRW1wdHkoKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0TWFpbFByb3BlcnRpZXNDbGFzc0xvYWRlcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnROdWxsKFN5c3RlbS5nZXRTZWN1cml0eU1hbmFnZXIoKSk7CisgICAgICAgIGZpbmFsIFRocmVhZCB0aHJlYWQgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpOworICAgICAgICBmaW5hbCBDbGFzc0xvYWRlciBjY2wgPSB0aHJlYWQuZ2V0Q29udGV4dENsYXNzTG9hZGVyKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBVUkxDbGFzc0xvYWRlciBjaGlsZCA9IG5ldyBVUkxDbGFzc0xvYWRlcihuZXcgVVJMWzBdLCBjY2wpOworCisgICAgICAgICAgICB0aHJlYWQuc2V0Q29udGV4dENsYXNzTG9hZGVyKGNoaWxkKTsKKyAgICAgICAgICAgIHRlc3RTZXRNYWlsUHJvcGVydGllcygoQ2xhc3NMb2FkZXJTZWN1cml0eU1hbmFnZXIpIG51bGwsIGNoaWxkKTsKKworICAgICAgICAgICAgdGhyZWFkLnNldENvbnRleHRDbGFzc0xvYWRlcihjaGlsZCk7CisgICAgICAgICAgICB0ZXN0U2V0TWFpbFByb3BlcnRpZXMobmV3IENsYXNzTG9hZGVyU2VjdXJpdHlNYW5hZ2VyKCksIGNoaWxkKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRocmVhZC5zZXRDb250ZXh0Q2xhc3NMb2FkZXIoY2NsKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnROdWxsKFN5c3RlbS5nZXRTZWN1cml0eU1hbmFnZXIoKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RTZXRNYWlsUHJvcGVydGllcyhDbGFzc0xvYWRlclNlY3VyaXR5TWFuYWdlciBzbSwgQ2xhc3NMb2FkZXIgZXhwZWN0KSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgSW50ZXJuYWxFcnJvck1hbmFnZXIgZW0gPSBuZXcgQ2xhc3NMb2FkZXJFcnJvck1hbmFnZXIoZXhwZWN0KTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFByb3BlcnRpZXMgcHJvcHMgPSBjcmVhdGVJbml0UHJvcGVydGllcygiIik7CisgICAgICAgICAgICBwcm9wcy5wdXQoInZlcmlmeSIsICJsb2NhbCIpOworCisgICAgICAgICAgICBpZiAoc20gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIFN5c3RlbS5zZXRTZWN1cml0eU1hbmFnZXIoc20pOworICAgICAgICAgICAgICAgIHNtLnNlY3VyZSA9IHRydWU7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIE1haWxIYW5kbGVyIGluc3RhbmNlID0gbmV3IE1haWxIYW5kbGVyKCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGluc3RhbmNlLnNldEVycm9yTWFuYWdlcihlbSk7CisgICAgICAgICAgICAgICAgaW5zdGFuY2Uuc2V0Q29tcGFyYXRvcihuZXcgQ2xhc3NMb2FkZXJDb21wYXJhdG9yKGV4cGVjdCkpOworICAgICAgICAgICAgICAgIGluc3RhbmNlLnNldEZpbHRlcihuZXcgQ2xhc3NMb2FkZXJGaWx0ZXJGb3JtYXR0ZXIoZXhwZWN0KSk7CisgICAgICAgICAgICAgICAgaW5zdGFuY2Uuc2V0UHVzaEZpbHRlcihuZXcgQ2xhc3NMb2FkZXJGaWx0ZXJGb3JtYXR0ZXIoZXhwZWN0KSk7CisgICAgICAgICAgICAgICAgaW5zdGFuY2Uuc2V0U3ViamVjdChuZXcgQ2xhc3NMb2FkZXJGaWx0ZXJGb3JtYXR0ZXIoZXhwZWN0KSk7CisgICAgICAgICAgICAgICAgaW5zdGFuY2Uuc2V0Rm9ybWF0dGVyKG5ldyBDbGFzc0xvYWRlckZpbHRlckZvcm1hdHRlcihleHBlY3QpKTsKKworICAgICAgICAgICAgICAgIGluc3RhbmNlLnNldE1haWxQcm9wZXJ0aWVzKHByb3BzKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmIChzbSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgc20uc2VjdXJlID0gZmFsc2U7CisgICAgICAgICAgICAgICAgU3lzdGVtLnNldFNlY3VyaXR5TWFuYWdlcigoU2VjdXJpdHlNYW5hZ2VyKSBudWxsKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydCBlbSAhPSBudWxsOworICAgICAgICBmb3IgKEV4Y2VwdGlvbiBleGNlcHRpb24gOiBlbS5leGNlcHRpb25zKSB7CisgICAgICAgICAgICBUaHJvd2FibGUgdCA9IGV4Y2VwdGlvbjsKKyAgICAgICAgICAgIGlmICh0IGluc3RhbmNlb2YgTWVzc2FnaW5nRXhjZXB0aW9uID09IGZhbHNlKSB7CisgICAgICAgICAgICAgICAgZHVtcCh0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBhc3NlcnRGYWxzZShlbS5leGNlcHRpb25zLmlzRW1wdHkoKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SXNMb2dnYWJsZSgpIHsKKyAgICAgICAgZmluYWwgTGV2ZWxbXSBsdmxzID0gZ2V0QWxsTGV2ZWxzKCk7CisgICAgICAgIGlmIChsdmxzLmxlbmd0aCA+IDApIHsKKyAgICAgICAgICAgIExvZ1JlY29yZCByZWNvcmQgPSBuZXcgTG9nUmVjb3JkKExldmVsLklORk8sICIiKTsKKyAgICAgICAgICAgIGZvciAoTGV2ZWwgbHZsIDogbHZscykgeworICAgICAgICAgICAgICAgIHRlc3RMb2dnYWJsZShsdmwsIG51bGwpOworICAgICAgICAgICAgICAgIHRlc3RMb2dnYWJsZShsdmwsIHJlY29yZCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmYWlsKCJObyBwcmVkZWZpbmVkIGxldmVscy4iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0TG9nZ2FibGUoTGV2ZWwgbHZsLCBMb2dSZWNvcmQgcmVjb3JkKSB7CisgICAgICAgIE1haWxIYW5kbGVyIGluc3RhbmNlID0gbmV3IE1haWxIYW5kbGVyKGNyZWF0ZUluaXRQcm9wZXJ0aWVzKCIiKSk7CisgICAgICAgIEludGVybmFsRXJyb3JNYW5hZ2VyIGVtID0gbmV3IEludGVybmFsRXJyb3JNYW5hZ2VyKCk7CisgICAgICAgIGluc3RhbmNlLnNldEVycm9yTWFuYWdlcihlbSk7CisKKyAgICAgICAgaW5zdGFuY2Uuc2V0TGV2ZWwobHZsKTsKKyAgICAgICAgTWVtb3J5SGFuZGxlciBtZW0gPSBudWxsOworICAgICAgICBib29sZWFuIHJlc3VsdCA9IGZhbHNlOworICAgICAgICBib29sZWFuIGV4cGVjdCA9IHRydWU7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXN1bHQgPSBpbnN0YW5jZS5pc0xvZ2dhYmxlKHJlY29yZCk7CisgICAgICAgICAgICBtZW0gPSBuZXcgTWVtb3J5SGFuZGxlcihuZXcgQ29uc29sZUhhbmRsZXIoKSwgMTAwLCBMZXZlbC5PRkYpOworICAgICAgICAgICAgbWVtLnNldEVycm9yTWFuYWdlcihlbSk7CisgICAgICAgICAgICBtZW0uc2V0TGV2ZWwobHZsKTsKKyAgICAgICAgICAgIGV4cGVjdCA9IG1lbS5pc0xvZ2dhYmxlKHJlY29yZCk7CisgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gbWFpbEV4KSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGlmIChtZW0gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBmYWlsKCJNZW1vcnlIYW5kbGVyIHRocmV3IGFuZCBleGNlcHRpb246ICIgKyBtYWlsRXgpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIG1lbSA9IG5ldyBNZW1vcnlIYW5kbGVyKG5ldyBDb25zb2xlSGFuZGxlcigpLCAxMDAsIExldmVsLk9GRik7CisgICAgICAgICAgICAgICAgICAgIG1lbS5zZXRFcnJvck1hbmFnZXIoZW0pOworICAgICAgICAgICAgICAgICAgICBtZW0uc2V0TGV2ZWwobHZsKTsKKyAgICAgICAgICAgICAgICAgICAgZXhwZWN0ID0gbWVtLmlzTG9nZ2FibGUocmVjb3JkKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgiTWFpbEhhbmRsZXIgdGhyZXcgYW5kIGV4Y2VwdGlvbjogIiArIG1haWxFeCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBtZW1FeCkgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhtZW1FeC5nZXRDbGFzcygpLCBtYWlsRXguZ2V0Q2xhc3MoKSk7CisgICAgICAgICAgICAgICAgcmVzdWx0ID0gZmFsc2U7CisgICAgICAgICAgICAgICAgZXhwZWN0ID0gZmFsc2U7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdCwgcmVzdWx0KTsKKworICAgICAgICBpbnN0YW5jZS5zZXRMZXZlbChMZXZlbC5JTkZPKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0RmlsdGVyKEJvb2xlYW5GaWx0ZXIuRkFMU0UpOworICAgICAgICBpbnN0YW5jZS5zZXRBdHRhY2htZW50Rm9ybWF0dGVycygKKyAgICAgICAgICAgICAgICBuZXcgRm9ybWF0dGVyW117bmV3IFNpbXBsZUZvcm1hdHRlcigpLCBuZXcgWE1MRm9ybWF0dGVyKCl9KTsKKyAgICAgICAgLy9udWxsIGZpbHRlciBtYWtlcyBhbGwgcmVjb3JkcyBJTkZPIGFuZCBhYm92ZSBsb2dnYWJsZS4KKyAgICAgICAgaW5zdGFuY2Uuc2V0QXR0YWNobWVudEZpbHRlcnMobmV3IEZpbHRlcltde0Jvb2xlYW5GaWx0ZXIuRkFMU0UsIG51bGx9KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGZhbHNlLCBpbnN0YW5jZS5pc0xvZ2dhYmxlKG5ldyBMb2dSZWNvcmQoTGV2ZWwuRklORVNULCAiIikpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRydWUsIGluc3RhbmNlLmlzTG9nZ2FibGUobmV3IExvZ1JlY29yZChMZXZlbC5JTkZPLCAiIikpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRydWUsIGluc3RhbmNlLmlzTG9nZ2FibGUobmV3IExvZ1JlY29yZChMZXZlbC5XQVJOSU5HLCAiIikpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRydWUsIGluc3RhbmNlLmlzTG9nZ2FibGUobmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICIiKSkpOworCisgICAgICAgIGFzc2VydEVxdWFscyhlbS5leGNlcHRpb25zLmlzRW1wdHkoKSwgdHJ1ZSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UG9zdENvbnN0cnVjdCgpIHsKKyAgICAgICAgTWFpbEhhbmRsZXIgaW5zdGFuY2UgPSBuZXcgTWFpbEhhbmRsZXIoY3JlYXRlSW5pdFByb3BlcnRpZXMoIiIpKTsKKyAgICAgICAgSW50ZXJuYWxFcnJvck1hbmFnZXIgZW0gPSBuZXcgSW50ZXJuYWxFcnJvck1hbmFnZXIoKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0RXJyb3JNYW5hZ2VyKGVtKTsKKyAgICAgICAgaW5zdGFuY2UucG9zdENvbnN0cnVjdCgpOworCisgICAgICAgIGFzc2VydEVxdWFscyh0cnVlLCBlbS5leGNlcHRpb25zLmlzRW1wdHkoKSk7CisgICAgICAgIGluc3RhbmNlLmNsb3NlKCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHJlRGVzdHJveSgpIHsKKyAgICAgICAgTWFpbEhhbmRsZXIgaW5zdGFuY2UgPSBuZXcgTWFpbEhhbmRsZXIoY3JlYXRlSW5pdFByb3BlcnRpZXMoIiIpKTsKKyAgICAgICAgSW50ZXJuYWxFcnJvck1hbmFnZXIgZW0gPSBuZXcgSW50ZXJuYWxFcnJvck1hbmFnZXIoKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0RXJyb3JNYW5hZ2VyKGVtKTsKKyAgICAgICAgaW5zdGFuY2UucHJlRGVzdHJveSgpOworCisgICAgICAgIGFzc2VydEVxdWFscyh0cnVlLCBlbS5leGNlcHRpb25zLmlzRW1wdHkoKSk7CisgICAgICAgIGluc3RhbmNlLmNsb3NlKCk7CisKKyAgICAgICAgaW5zdGFuY2UgPSBjcmVhdGVIYW5kbGVyV2l0aFJlY29yZHMoKTsKKyAgICAgICAgZW0gPSBpbnRlcm5hbEVycm9yTWFuYWdlckZyb20oaW5zdGFuY2UpOworICAgICAgICBpbnN0YW5jZS5wcmVEZXN0cm95KCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGVtLmV4Y2VwdGlvbnMuc2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRydWUsIGVtLmV4Y2VwdGlvbnMuZ2V0KDApIGluc3RhbmNlb2YgTWVzc2FnaW5nRXhjZXB0aW9uKTsKKyAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKworICAgICAgICAvL1Rlc3QgZm9yIHZhbGlkIG1lc3NhZ2UuCisgICAgICAgIGluc3RhbmNlID0gY3JlYXRlSGFuZGxlcldpdGhSZWNvcmRzKCk7CisgICAgICAgIGluc3RhbmNlLnNldEVycm9yTWFuYWdlcihuZXcgRmx1c2hFcnJvck1hbmFnZXIoaW5zdGFuY2UpKTsKKyAgICAgICAgaW5zdGFuY2UucHJlRGVzdHJveSgpOworICAgICAgICBpbnN0YW5jZS5jbG9zZSgpOworCisgICAgICAgIC8vVGVzdCB0aGF0IHByZURlc3Ryb3kgaXMgbm9ybWFsIHByaW9yaXR5LgorICAgICAgICBpbnN0YW5jZSA9IG5ldyBNYWlsSGFuZGxlcigyKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0TWFpbFByb3BlcnRpZXMoY3JlYXRlSW5pdFByb3BlcnRpZXMoIiIpKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0TGV2ZWwoTGV2ZWwuQUxMKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0RXJyb3JNYW5hZ2VyKG5ldyBGbHVzaEVycm9yTWFuYWdlcihpbnN0YW5jZSkpOworICAgICAgICBpbnN0YW5jZS5zZXRQdXNoRmlsdGVyKChGaWx0ZXIpIG51bGwpOworICAgICAgICBpbnN0YW5jZS5zZXRQdXNoTGV2ZWwoTGV2ZWwuT0ZGKTsKKyAgICAgICAgTG9nUmVjb3JkIHJlY29yZCA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuSU5GTywgIiIpOworICAgICAgICBpbnN0YW5jZS5wdWJsaXNoKHJlY29yZCk7IC8vc2hvdWxkIGZsdXNoLgorICAgICAgICBpbnN0YW5jZS5wcmVEZXN0cm95KCk7CisgICAgICAgIGluc3RhbmNlLnB1c2goKTsgLy9UcmlnZ2VyIGFuIGVycm9yIGlmIGRhdGEgaXMgcHJlc2VudCBoZXJlLgorICAgICAgICBpbnN0YW5jZS5jbG9zZSgpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFJlZmxlY3RpdmVMaWZlQ3ljbGVBY2Nlc3MoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgQ2xhc3M8Pz4gayA9IE1haWxIYW5kbGVyLmNsYXNzOworICAgICAgICBmaW5hbCBNZXRob2QgY29uc3RydWN0ID0gay5nZXREZWNsYXJlZE1ldGhvZCgicG9zdENvbnN0cnVjdCIpOworICAgICAgICBmaW5hbCBNZXRob2QgZGVzdG9yeSA9IGsuZ2V0RGVjbGFyZWRNZXRob2QoInByZURlc3Ryb3kiKTsKKyAgICAgICAgdGVzdExpZmVDeWNsZVByb3R5cGVzKGNvbnN0cnVjdCk7CisgICAgICAgIHRlc3RMaWZlQ3ljbGVQcm90eXBlcyhkZXN0b3J5KTsKKworICAgICAgICBNYWlsSGFuZGxlciBoID0gbmV3IE1haWxIYW5kbGVyKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBoLnNldE1haWxQcm9wZXJ0aWVzKGNyZWF0ZUluaXRQcm9wZXJ0aWVzKCIiKSk7CisgICAgICAgICAgICBJbnRlcm5hbEVycm9yTWFuYWdlciBlbSA9IG5ldyBJbnRlcm5hbEVycm9yTWFuYWdlcigpOworICAgICAgICAgICAgaC5zZXRFcnJvck1hbmFnZXIoZW0pOworCisgICAgICAgICAgICBjb25zdHJ1Y3QuaW52b2tlKGgpOworICAgICAgICAgICAgZGVzdG9yeS5pbnZva2UoaCk7CisKKyAgICAgICAgICAgIGZvciAoVGhyb3dhYmxlIHQgOiBlbS5leGNlcHRpb25zKSB7CisgICAgICAgICAgICAgICAgZHVtcCh0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydEVxdWFscyh0cnVlLCBlbS5leGNlcHRpb25zLmlzRW1wdHkoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBoLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdExpZmVDeWNsZVByb3R5cGVzKE1ldGhvZCBtKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU3RyaW5nIHMgPSBtLnRvU3RyaW5nKCk7CisgICAgICAgIGFzc2VydFRydWUocywgTWFpbEhhbmRsZXIuY2xhc3MuZXF1YWxzKG0uZ2V0RGVjbGFyaW5nQ2xhc3MoKSkpOworICAgICAgICBhc3NlcnRUcnVlKHMsIE1vZGlmaWVyLmlzUHVibGljKG0uZ2V0TW9kaWZpZXJzKCkpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UocywgTW9kaWZpZXIuaXNTdGF0aWMobS5nZXRNb2RpZmllcnMoKSkpOworICAgICAgICBhc3NlcnRUcnVlKHMsIFZvaWQuVFlQRS5lcXVhbHMobS5nZXRSZXR1cm5UeXBlKCkpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShzLCBtLmdldFBhcmFtZXRlclR5cGVzKCkubGVuZ3RoID09IDApOworICAgICAgICBhc3NlcnRUcnVlKHMsIG0uZ2V0RXhjZXB0aW9uVHlwZXMoKS5sZW5ndGggPT0gMCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Tm9EZXBlbmRlbmN5T25KYXZheEFubm90YXRpb25zKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3ROb0RlcGVuZGVuY3lPbkphdmF4QW5ub3RhdGlvbnMoTWFpbEhhbmRsZXIuY2xhc3MpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFByZURlc3Ryb3lMaW5rYWdlRXJyb3IoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdExpbmthZ2VFcnJvcldpdGhTdGFjaygicHJlRGVzdHJveSIpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFByZURlc3Ryb3lMaW5rYWdlRXJyb3JFbXB0eSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0TGlua2FnZUVycm9yRW1wdHlTdGFjaygicHJlRGVzdHJveSIpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFB1Ymxpc2goKSB7CisgICAgICAgIE1haWxIYW5kbGVyIGluc3RhbmNlID0gY3JlYXRlSGFuZGxlcldpdGhSZWNvcmRzKCk7CisgICAgICAgIEludGVybmFsRXJyb3JNYW5hZ2VyIGVtID0gaW50ZXJuYWxFcnJvck1hbmFnZXJGcm9tKGluc3RhbmNlKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGVtLmV4Y2VwdGlvbnMuaXNFbXB0eSgpLCB0cnVlKTsKKyAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKworICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgZW0uZXhjZXB0aW9ucy5nZXQoMCkgaW5zdGFuY2VvZiBNZXNzYWdpbmdFeGNlcHRpb24pOworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgZW0uZXhjZXB0aW9ucy5zaXplKCkpOworCisgICAgICAgIC8vVGVzdCBmb3IgdmFsaWQgbWVzc2FnZS4KKyAgICAgICAgaW5zdGFuY2UgPSBjcmVhdGVIYW5kbGVyV2l0aFJlY29yZHMoKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0RXJyb3JNYW5hZ2VyKG5ldyBGbHVzaEVycm9yTWFuYWdlcihpbnN0YW5jZSkpOworCisgICAgICAgIGZpbmFsIExldmVsW10gbHZscyA9IGdldEFsbExldmVscygpOworICAgICAgICBTdHJpbmcgU09VUkNFX0NMQVNTID0gTWFpbEhhbmRsZXJUZXN0LmNsYXNzLmdldE5hbWUoKTsKKyAgICAgICAgU3RyaW5nIFNPVVJDRV9NRVRIT0QgPSAidGVzdFB1Ymxpc2giOworICAgICAgICBmb3IgKExldmVsIGx2bCA6IGx2bHMpIHsKKyAgICAgICAgICAgIExvZ1JlY29yZCByID0gbmV3IExvZ1JlY29yZChsdmwsICIiKTsKKyAgICAgICAgICAgIHIuc2V0U291cmNlQ2xhc3NOYW1lKFNPVVJDRV9DTEFTUyk7CisgICAgICAgICAgICByLnNldFNvdXJjZU1ldGhvZE5hbWUoU09VUkNFX01FVEhPRCk7CisgICAgICAgICAgICBpbnN0YW5jZS5wdWJsaXNoKHIpOworICAgICAgICB9CisKKyAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RQdWJsaXNoTGlua2FnZUVycm9yKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RMaW5rYWdlRXJyb3JXaXRoU3RhY2soInB1Ymxpc2giKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RQdWJsaXNoTGlua2FnZUVycm9yRW1wdHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdExpbmthZ2VFcnJvckVtcHR5U3RhY2soInB1Ymxpc2giKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RQdWJsaXNoRHVyaW5nQ2xvc2UoKSB7CisgICAgICAgIGZpbmFsIExldmVsW10gbHZscyA9IGdldEFsbExldmVscygpOworICAgICAgICBmb3IgKGludCBsZXZlbEluZGV4ID0gMDsgbGV2ZWxJbmRleCA8IGx2bHMubGVuZ3RoOyBsZXZlbEluZGV4KyspIHsKKyAgICAgICAgICAgIE1haWxIYW5kbGVyIGluc3RhbmNlID0gbmV3IE1haWxIYW5kbGVyKGx2bHMubGVuZ3RoICsgMik7CisgICAgICAgICAgICBJbnRlcm5hbEVycm9yTWFuYWdlciBlbSA9IG5ldyBJbnRlcm5hbEVycm9yTWFuYWdlcigpOworICAgICAgICAgICAgaW5zdGFuY2Uuc2V0RXJyb3JNYW5hZ2VyKGVtKTsKKyAgICAgICAgICAgIFByb3BlcnRpZXMgcHJvcHMgPSBjcmVhdGVJbml0UHJvcGVydGllcygiIik7CisgICAgICAgICAgICBpbnN0YW5jZS5zZXRNYWlsUHJvcGVydGllcyhwcm9wcyk7CisKKyAgICAgICAgICAgIEF1dGhlbnRpY2F0b3IgYXV0aCA9IG5ldyBFbXB0eUF1dGhlbnRpY2F0b3IoKTsKKyAgICAgICAgICAgIEZpbHRlciBmaWx0ZXIgPSBCb29sZWFuRmlsdGVyLlRSVUU7CisgICAgICAgICAgICBGb3JtYXR0ZXIgZm9ybWF0dGVyID0gbmV3IFNpbXBsZUZvcm1hdHRlcigpOworICAgICAgICAgICAgaW5zdGFuY2Uuc2V0U3ViamVjdCgicHVibGlzaER1cmluZ0Nsb3NlIik7CisgICAgICAgICAgICBGb3JtYXR0ZXIgc3ViamVjdCA9IGluc3RhbmNlLmdldFN1YmplY3QoKTsKKworICAgICAgICAgICAgaW5zdGFuY2Uuc2V0QXV0aGVudGljYXRvcihhdXRoKTsKKyAgICAgICAgICAgIGluc3RhbmNlLnNldExldmVsKExldmVsLkFMTCk7CisgICAgICAgICAgICBpbnN0YW5jZS5zZXRGb3JtYXR0ZXIoZm9ybWF0dGVyKTsKKyAgICAgICAgICAgIGluc3RhbmNlLnNldEZpbHRlcihmaWx0ZXIpOworICAgICAgICAgICAgaW5zdGFuY2Uuc2V0UHVzaExldmVsKExldmVsLk9GRik7CisgICAgICAgICAgICBpbnN0YW5jZS5zZXRQdXNoRmlsdGVyKGZpbHRlcik7CisgICAgICAgICAgICBpbnN0YW5jZS5zZXRBdHRhY2htZW50Rm9ybWF0dGVycyhuZXcgRm9ybWF0dGVyW117Zm9ybWF0dGVyfSk7CisgICAgICAgICAgICBpbnN0YW5jZS5zZXRBdHRhY2htZW50RmlsdGVycyhuZXcgRmlsdGVyW117ZmlsdGVyfSk7CisgICAgICAgICAgICBpbnN0YW5jZS5zZXRBdHRhY2htZW50TmFtZXMobmV3IEZvcm1hdHRlcltde3N1YmplY3R9KTsKKworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShlbS5leGNlcHRpb25zLmlzRW1wdHkoKSk7CisKKyAgICAgICAgICAgIGZpbmFsIFN0cmluZyBtc2cgPSBpbnN0YW5jZS50b1N0cmluZygpOworICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBsdmxzLmxlbmd0aDsgaisrKSB7CisgICAgICAgICAgICAgICAgTGV2ZWwgb2xkTGV2ZWwgPSBpbnN0YW5jZS5nZXRMZXZlbCgpOworICAgICAgICAgICAgICAgIExldmVsIGx2bCA9IGx2bHNbKGxldmVsSW5kZXggKyBqKSAlIGx2bHMubGVuZ3RoXTsKKyAgICAgICAgICAgICAgICBDbG9zZUxvZ1JlY29yZCByID0gbmV3IENsb3NlTG9nUmVjb3JkKGx2bCwgbXNnLCBpbnN0YW5jZSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RmFsc2Uoci5pc0Nsb3NlZCgpKTsKKyAgICAgICAgICAgICAgICBpbnN0YW5jZS5wdWJsaXNoKHIpOworICAgICAgICAgICAgICAgIGlmICghb2xkTGV2ZWwuZXF1YWxzKExldmVsLk9GRikpIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKExldmVsLk9GRiwgaW5zdGFuY2UuZ2V0TGV2ZWwoKSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUoci5pc0Nsb3NlZCgpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vQ2xvc2UgaXMgbm90IGFsbG93ZWQgdG8gY2hhbmdlIGFueSBzZXR0aW5ncy4KKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhMZXZlbC5PRkYsIGluc3RhbmNlLmdldExldmVsKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHByb3BzLCBpbnN0YW5jZS5nZXRNYWlsUHJvcGVydGllcygpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhhdXRoLCBpbnN0YW5jZS5nZXRBdXRoZW50aWNhdG9yKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHN1YmplY3QsIGluc3RhbmNlLmdldFN1YmplY3QoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoZmlsdGVyLCBpbnN0YW5jZS5nZXRGaWx0ZXIoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoZm9ybWF0dGVyLCBpbnN0YW5jZS5nZXRGb3JtYXR0ZXIoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoTGV2ZWwuT0ZGLCBpbnN0YW5jZS5nZXRQdXNoTGV2ZWwoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoZmlsdGVyLCBpbnN0YW5jZS5nZXRQdXNoRmlsdGVyKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGZvcm1hdHRlciwgaW5zdGFuY2UuZ2V0QXR0YWNobWVudEZvcm1hdHRlcnMoKVswXSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoZmlsdGVyLCBpbnN0YW5jZS5nZXRBdHRhY2htZW50RmlsdGVycygpWzBdKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhzdWJqZWN0LCBpbnN0YW5jZS5nZXRBdHRhY2htZW50TmFtZXMoKVswXSk7CisKKyAgICAgICAgICAgIC8vZW5zdXJlIG9uZSB0cmFuc3BvcnQgZXJyb3IuCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgZW0uZXhjZXB0aW9ucy5zaXplKCkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShlbS5leGNlcHRpb25zLmdldCgwKSBpbnN0YW5jZW9mIE1lc3NhZ2luZ0V4Y2VwdGlvbik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RQdWJsaXNoRHVyaW5nQ2xvc2VMaW5rYWdlRXJyb3IoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdExpbmthZ2VFcnJvcldpdGhTdGFjaygicHVibGlzaER1cmluZ0Nsb3NlIik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHVibGlzaER1cmluZ0Nsb3NlTGlua2FnZUVycm9yRW1wdHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdExpbmthZ2VFcnJvckVtcHR5U3RhY2soInB1Ymxpc2hEdXJpbmdDbG9zZSIpOworICAgIH0KKworICAgIHByaXZhdGUgTWFpbEhhbmRsZXIgY3JlYXRlSGFuZGxlcldpdGhSZWNvcmRzKCkgeworICAgICAgICBmaW5hbCBMZXZlbFtdIGx2bHMgPSBnZXRBbGxMZXZlbHMoKTsKKworICAgICAgICBNYWlsSGFuZGxlciBpbnN0YW5jZSA9IG5ldyBNYWlsSGFuZGxlcihsdmxzLmxlbmd0aCArIDIpOworICAgICAgICBJbnRlcm5hbEVycm9yTWFuYWdlciBlbSA9IG5ldyBJbnRlcm5hbEVycm9yTWFuYWdlcigpOworICAgICAgICBpbnN0YW5jZS5zZXRFcnJvck1hbmFnZXIoZW0pOworICAgICAgICBQcm9wZXJ0aWVzIHByb3BzID0gY3JlYXRlSW5pdFByb3BlcnRpZXMoIiIpOworICAgICAgICBpbnN0YW5jZS5zZXRNYWlsUHJvcGVydGllcyhwcm9wcyk7CisgICAgICAgIGluc3RhbmNlLnNldExldmVsKExldmVsLkFMTCk7CisgICAgICAgIGluc3RhbmNlLnNldEZpbHRlcigoRmlsdGVyKSBudWxsKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0UHVzaExldmVsKExldmVsLk9GRik7CisgICAgICAgIGluc3RhbmNlLnNldFB1c2hGaWx0ZXIoKEZpbHRlcikgbnVsbCk7CisKKyAgICAgICAgZmluYWwgU3RyaW5nIG1zZyA9IGluc3RhbmNlLnRvU3RyaW5nKCk7CisgICAgICAgIGZvciAoTGV2ZWwgbHZsIDogbHZscykgeworICAgICAgICAgICAgTG9nUmVjb3JkIHIgPSBuZXcgTG9nUmVjb3JkKGx2bCwgbXNnKTsKKyAgICAgICAgICAgIHIuc2V0U291cmNlQ2xhc3NOYW1lKE1haWxIYW5kbGVyVGVzdC5jbGFzcy5nZXROYW1lKCkpOworICAgICAgICAgICAgci5zZXRMb2dnZXJOYW1lKHIuZ2V0U291cmNlQ2xhc3NOYW1lKCkpOworICAgICAgICAgICAgci5zZXRTb3VyY2VNZXRob2ROYW1lKCJjcmVhdGVIYW5kbGVyV2l0aFJlY29yZHMiKTsKKyAgICAgICAgICAgIGluc3RhbmNlLnB1Ymxpc2gocik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGluc3RhbmNlOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEVycm9yU3ViamVjdEZvcm1hdHRlcigpIHsKKyAgICAgICAgTWFpbEhhbmRsZXIgaW5zdGFuY2UgPSBuZXcgTWFpbEhhbmRsZXIoMik7CisgICAgICAgIGluc3RhbmNlLnNldExldmVsKExldmVsLkFMTCk7CisgICAgICAgIFByb3BlcnRpZXMgcHJvcHMgPSBjcmVhdGVJbml0UHJvcGVydGllcygiIik7CisgICAgICAgIGluc3RhbmNlLnNldE1haWxQcm9wZXJ0aWVzKHByb3BzKTsKKworICAgICAgICBJbnRlcm5hbEVycm9yTWFuYWdlciBlbSA9IG5ldyBJbnRlcm5hbEVycm9yTWFuYWdlcigpOworICAgICAgICBpbnN0YW5jZS5zZXRFcnJvck1hbmFnZXIoZW0pOworICAgICAgICBpbnN0YW5jZS5zZXRTdWJqZWN0KG5ldyBFcnJvckZvcm1hdHRlcigpKTsKKworICAgICAgICBMb2dSZWNvcmQgcmVjb3JkID0gbmV3IExvZ1JlY29yZChMZXZlbC5JTkZPLCAiIik7CisgICAgICAgIGluc3RhbmNlLnB1Ymxpc2gocmVjb3JkKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGluc3RhbmNlLnB1c2goKTsKKyAgICAgICAgICAgIGZhaWwoIkVycm9yIGRpZG4ndCBlc2NhcGUgcHVzaC4iKTsKKyAgICAgICAgfSBjYXRjaCAoRXJyb3IgZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIGlmIChleHBlY3RlZC5nZXRDbGFzcygpICE9IEVycm9yLmNsYXNzKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgZXhwZWN0ZWQ7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhMZXZlbC5BTEwsIGluc3RhbmNlLmdldExldmVsKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaW5zdGFuY2UucHVibGlzaChyZWNvcmQpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW5zdGFuY2UuZmx1c2goKTsKKyAgICAgICAgICAgIGZhaWwoIkVycm9yIGRpZG4ndCBlc2NhcGUgZmx1c2guIik7CisgICAgICAgIH0gY2F0Y2ggKEVycm9yIGV4cGVjdGVkKSB7CisgICAgICAgICAgICBpZiAoZXhwZWN0ZWQuZ2V0Q2xhc3MoKSAhPSBFcnJvci5jbGFzcykgeworICAgICAgICAgICAgICAgIHRocm93IGV4cGVjdGVkOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoTGV2ZWwuQUxMLCBpbnN0YW5jZS5nZXRMZXZlbCgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGluc3RhbmNlLnB1Ymxpc2gocmVjb3JkKTsKKyAgICAgICAgcmVjb3JkID0gbmV3IExvZ1JlY29yZChMZXZlbC5JTkZPLCAiIik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnN0YW5jZS5wdWJsaXNoKHJlY29yZCk7CisgICAgICAgICAgICBmYWlsKCJFcnJvciBkaWRuJ3QgZXNjYXBlIHB1Ymxpc2ggYXQgZnVsbCBjYXBhY2l0eS4iKTsKKyAgICAgICAgfSBjYXRjaCAoRXJyb3IgZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIGlmIChleHBlY3RlZC5nZXRDbGFzcygpICE9IEVycm9yLmNsYXNzKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgZXhwZWN0ZWQ7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhMZXZlbC5BTEwsIGluc3RhbmNlLmdldExldmVsKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaW5zdGFuY2UucHVibGlzaChyZWNvcmQpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKyAgICAgICAgICAgIGZhaWwoIkVycm9yIGRpZG4ndCBlc2NhcGUgY2xvc2UuIik7CisgICAgICAgIH0gY2F0Y2ggKEVycm9yIGV4cGVjdGVkKSB7CisgICAgICAgICAgICBpZiAoZXhwZWN0ZWQuZ2V0Q2xhc3MoKSAhPSBFcnJvci5jbGFzcykgeworICAgICAgICAgICAgICAgIHRocm93IGV4cGVjdGVkOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoTGV2ZWwuT0ZGLCBpbnN0YW5jZS5nZXRMZXZlbCgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGluc3RhbmNlLmNsb3NlKCk7CisgICAgICAgIGZpbmFsIGludCBzaXplID0gZW0uZXhjZXB0aW9ucy5zaXplKCk7CisgICAgICAgIGlmIChzaXplID4gMCkgeworICAgICAgICAgICAgZmFpbChlbS5leGNlcHRpb25zLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RXJyb3JDb21wYXJhdG9yKCkgeworICAgICAgICB0ZXN0RXJyb3JDb21wYXJhdG9yKDApOworICAgICAgICB0ZXN0RXJyb3JDb21wYXJhdG9yKDEpOworICAgICAgICB0ZXN0RXJyb3JDb21wYXJhdG9yKDIpOworICAgICAgICB0ZXN0RXJyb3JDb21wYXJhdG9yKDMpOworICAgICAgICB0ZXN0RXJyb3JDb21wYXJhdG9yKDEwKTsKKyAgICAgICAgdGVzdEVycm9yQ29tcGFyYXRvcig5OTkpOworICAgICAgICB0ZXN0RXJyb3JDb21wYXJhdG9yKDEwMDApOworICAgICAgICB0ZXN0RXJyb3JDb21wYXJhdG9yKDEwMDEpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0RXJyb3JDb21wYXJhdG9yKGludCByZWNvcmRzKSB7CisgICAgICAgIGFzc2VydFRydWUoIkludmFsaWQgYXJndW1lbnQuIiwgcmVjb3JkcyA+PSAwKTsKKyAgICAgICAgUHJvcGVydGllcyBwcm9wcyA9IGNyZWF0ZUluaXRQcm9wZXJ0aWVzKCIiKTsKKyAgICAgICAgTWFpbEhhbmRsZXIgaW5zdGFuY2UgPSBuZXcgTWFpbEhhbmRsZXIocHJvcHMpOworICAgICAgICBpbnN0YW5jZS5zZXRDb21wYXJhdG9yKG5ldyBFcnJvckNvbXBhcmF0b3IoKSk7CisgICAgICAgIGluc3RhbmNlLnNldEVycm9yTWFuYWdlcihuZXcgSW50ZXJuYWxFcnJvck1hbmFnZXIoKSk7CisgICAgICAgIGJvb2xlYW4gbm9ybWFsID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVjb3JkczsgKytpKSB7CisgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlLnB1Ymxpc2gobmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICIiKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBpbnN0YW5jZS5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgbm9ybWFsID0gdHJ1ZTsKKyAgICAgICAgfSBjYXRjaCAoRXJyb3IgZSkgeworICAgICAgICAgICAgaWYgKHJlY29yZHMgPT0gMCB8fCBlLmdldENsYXNzKCkgIT0gRXJyb3IuY2xhc3MpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBJbnRlcm5hbEVycm9yTWFuYWdlciBlbSA9IGludGVybmFsRXJyb3JNYW5hZ2VyRnJvbShpbnN0YW5jZSk7CisgICAgICAgICAgICAgICAgZm9yIChUaHJvd2FibGUgdCA6IGVtLmV4Y2VwdGlvbnMpIHsKKyAgICAgICAgICAgICAgICAgICAgZHVtcCh0KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHRydWUsIGVtLmV4Y2VwdGlvbnMuaXNFbXB0eSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmIChub3JtYWwpIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUocmVjb3JkcyA9PSAwKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFRocm93Rm9ybWF0dGVycygpIHsKKyAgICAgICAgTWFpbEhhbmRsZXIgaW5zdGFuY2UgPSBuZXcgTWFpbEhhbmRsZXIoY3JlYXRlSW5pdFByb3BlcnRpZXMoIiIpKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0TGV2ZWwoTGV2ZWwuQUxMKTsKKyAgICAgICAgSW50ZXJuYWxFcnJvck1hbmFnZXIgZW0gPSBuZXcgSW50ZXJuYWxFcnJvck1hbmFnZXIoKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0RXJyb3JNYW5hZ2VyKGVtKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0Q29tcGFyYXRvcihuZXcgVGhyb3dDb21wYXJhdG9yKCkpOworICAgICAgICBpbnN0YW5jZS5zZXRGb3JtYXR0ZXIobmV3IFRocm93Rm9ybWF0dGVyKCkpOworICAgICAgICBpbnN0YW5jZS5zZXRTdWJqZWN0KG5ldyBUaHJvd0Zvcm1hdHRlcigpKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0QXR0YWNobWVudEZvcm1hdHRlcnMobmV3IEZvcm1hdHRlcltde25ldyBUaHJvd0Zvcm1hdHRlcigpfSk7CisgICAgICAgIGluc3RhbmNlLnNldEF0dGFjaG1lbnROYW1lcyhuZXcgRm9ybWF0dGVyW117bmV3IFRocm93Rm9ybWF0dGVyKCl9KTsKKworICAgICAgICBMb2dSZWNvcmQgcmVjb3JkID0gbmV3IExvZ1JlY29yZChMZXZlbC5JTkZPLCAiIik7CisgICAgICAgIGluc3RhbmNlLnB1Ymxpc2gocmVjb3JkKTsKKyAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKworICAgICAgICBmaW5hbCBpbnQgc2l6ZSA9IGVtLmV4Y2VwdGlvbnMuc2l6ZSgpOworICAgICAgICBpZiAoc2l6ZSA+IDApIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZW0uZXhjZXB0aW9ucy5zaXplKCkgLSAxOyBpKyspIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgZW0uZXhjZXB0aW9ucy5nZXQoaSkgaW5zdGFuY2VvZiBSdW50aW1lRXhjZXB0aW9uKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydEVxdWFscyh0cnVlLAorICAgICAgICAgICAgICAgICAgICBlbS5leGNlcHRpb25zLmdldChzaXplIC0gMSkgaW5zdGFuY2VvZiBNZXNzYWdpbmdFeGNlcHRpb24pOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGZhaWwoIk5vIHJ1bnRpbWUgZXhjZXB0aW9ucyByZXBvcnRlZCIpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEVycm9yRm9ybWF0dGVycygpIHsKKyAgICAgICAgTWFpbEhhbmRsZXIgaW5zdGFuY2UgPSBuZXcgTWFpbEhhbmRsZXIoY3JlYXRlSW5pdFByb3BlcnRpZXMoIiIpKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0TGV2ZWwoTGV2ZWwuQUxMKTsKKyAgICAgICAgSW50ZXJuYWxFcnJvck1hbmFnZXIgZW0gPSBuZXcgSW50ZXJuYWxFcnJvck1hbmFnZXIoKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0RXJyb3JNYW5hZ2VyKGVtKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0Q29tcGFyYXRvcihuZXcgRXJyb3JDb21wYXJhdG9yKCkpOworICAgICAgICBpbnN0YW5jZS5zZXRGb3JtYXR0ZXIobmV3IEVycm9yRm9ybWF0dGVyKCkpOworICAgICAgICBpbnN0YW5jZS5zZXRTdWJqZWN0KG5ldyBFcnJvckZvcm1hdHRlcigpKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0QXR0YWNobWVudEZvcm1hdHRlcnMobmV3IEZvcm1hdHRlcltde25ldyBFcnJvckZvcm1hdHRlcigpfSk7CisgICAgICAgIGluc3RhbmNlLnNldEF0dGFjaG1lbnROYW1lcyhuZXcgRm9ybWF0dGVyW117bmV3IEVycm9yRm9ybWF0dGVyKCl9KTsKKworICAgICAgICBMb2dSZWNvcmQgcmVjb3JkID0gbmV3IExvZ1JlY29yZChMZXZlbC5JTkZPLCAiIik7CisgICAgICAgIGluc3RhbmNlLnB1Ymxpc2gocmVjb3JkKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGluc3RhbmNlLmNsb3NlKCk7CisgICAgICAgICAgICBmYWlsKCJFcnJvciB3YXMgc3dhbGxvd2VkLiIpOworICAgICAgICB9IGNhdGNoIChFcnJvciBleHBlY3QpIHsKKyAgICAgICAgICAgIGlmIChleHBlY3QuZ2V0Q2xhc3MoKSAhPSBFcnJvci5jbGFzcykgeworICAgICAgICAgICAgICAgIHRocm93IGV4cGVjdDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEVycm9yRmlsdGVycygpIHsKKyAgICAgICAgTG9nUmVjb3JkIHJlY29yZCA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuSU5GTywgIiIpOworICAgICAgICBNZW1vcnlIYW5kbGVyIG1oID0gbmV3IE1lbW9yeUhhbmRsZXIobmV3IENvbnNvbGVIYW5kbGVyKCksIDEwMCwgTGV2ZWwuT0ZGKTsKKyAgICAgICAgbWguc2V0RmlsdGVyKG5ldyBFcnJvckZpbHRlcigpKTsKKyAgICAgICAgTWFpbEhhbmRsZXIgaW5zdGFuY2UgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYm9vbGVhbiBleHBlY3QgPSBtaC5pc0xvZ2dhYmxlKHJlY29yZCk7CisgICAgICAgICAgICBpbnN0YW5jZSA9IG5ldyBNYWlsSGFuZGxlcihjcmVhdGVJbml0UHJvcGVydGllcygiIikpOworICAgICAgICAgICAgaW5zdGFuY2Uuc2V0TGV2ZWwoTGV2ZWwuQUxMKTsKKyAgICAgICAgICAgIGluc3RhbmNlLnNldEZpbHRlcihuZXcgRXJyb3JGaWx0ZXIoKSk7CisgICAgICAgICAgICBib29sZWFuIHJlc3VsdCA9IGluc3RhbmNlLmlzTG9nZ2FibGUocmVjb3JkKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3QsIHJlc3VsdCk7CisgICAgICAgIH0gY2F0Y2ggKEVycm9yIGV4cGVjdEV4KSB7CisgICAgICAgICAgICBpZiAoaW5zdGFuY2UgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlID0gbmV3IE1haWxIYW5kbGVyKGNyZWF0ZUluaXRQcm9wZXJ0aWVzKCIiKSk7CisgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlLnNldExldmVsKExldmVsLkFMTCk7CisgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlLnNldEZpbHRlcihuZXcgRXJyb3JGaWx0ZXIoKSk7CisgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlLmlzTG9nZ2FibGUocmVjb3JkKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgiRG9lc24ndCBtYXRjaCB0aGUgbWVtb3J5IGhhbmRsZXIuIik7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXJyb3IgcmVzdWx0RXgpIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdEV4LmdldENsYXNzKCksIHJlc3VsdEV4LmdldENsYXNzKCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZmFpbCgiRG9lc24ndCBtYXRjaCB0aGUgbWVtb3J5IGhhbmRsZXIuIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnQgaW5zdGFuY2UgIT0gbnVsbDsKKyAgICAgICAgaW5zdGFuY2Uuc2V0RmlsdGVyKChGaWx0ZXIpIG51bGwpOworCisgICAgICAgIFByb3BlcnRpZXMgcHJvcHMgPSBuZXcgUHJvcGVydGllcygpOworICAgICAgICBwcm9wcy5wdXQoIm1haWwuc210cC5ob3N0IiwgVU5LTk9XTl9IT1NUKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0TWFpbFByb3BlcnRpZXMocHJvcHMpOworCisgICAgICAgIEludGVybmFsRXJyb3JNYW5hZ2VyIGVtID0gbmV3IEludGVybmFsRXJyb3JNYW5hZ2VyKCk7CisgICAgICAgIGluc3RhbmNlLnNldEVycm9yTWFuYWdlcihlbSk7CisKKyAgICAgICAgaW5zdGFuY2Uuc2V0QXR0YWNobWVudEZvcm1hdHRlcnMobmV3IEZvcm1hdHRlcltde25ldyBTaW1wbGVGb3JtYXR0ZXIoKX0pOworICAgICAgICBpbnN0YW5jZS5zZXRBdHRhY2htZW50RmlsdGVycyhuZXcgRmlsdGVyW117bmV3IEVycm9yRmlsdGVyKCl9KTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0QXR0YWNobWVudE5hbWVzKG5ldyBTdHJpbmdbXXsidGVzdC50eHQifSk7CisKKyAgICAgICAgaW5zdGFuY2UucHVibGlzaChyZWNvcmQpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKyAgICAgICAgICAgIGZhaWwoIkVycm9yIHdhcyBzd2FsbG93ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKEVycm9yIGV4cGVjdCkgeworICAgICAgICAgICAgaWYgKGV4cGVjdC5nZXRDbGFzcygpICE9IEVycm9yLmNsYXNzKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgZXhwZWN0OworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRydWUsIGVtLmV4Y2VwdGlvbnMuaXNFbXB0eSgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RUaHJvd0NvbXBhcmF0b3IoKSB7CisgICAgICAgIHRlc3RUaHJvd0NvbXBhcmF0b3IoMCk7CisgICAgICAgIHRlc3RUaHJvd0NvbXBhcmF0b3IoMSk7CisgICAgICAgIHRlc3RUaHJvd0NvbXBhcmF0b3IoMik7CisgICAgICAgIHRlc3RUaHJvd0NvbXBhcmF0b3IoMyk7CisgICAgICAgIHRlc3RUaHJvd0NvbXBhcmF0b3IoMTApOworICAgICAgICB0ZXN0VGhyb3dDb21wYXJhdG9yKDk5OSk7CisgICAgICAgIHRlc3RUaHJvd0NvbXBhcmF0b3IoMTAwMCk7CisgICAgICAgIHRlc3RUaHJvd0NvbXBhcmF0b3IoMTAwMSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RUaHJvd0NvbXBhcmF0b3IoaW50IHJlY29yZHMpIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZShyZWNvcmRzID49IDApOworICAgICAgICBNYWlsSGFuZGxlciBpbnN0YW5jZSA9IG5ldyBNYWlsSGFuZGxlcihjcmVhdGVJbml0UHJvcGVydGllcygiIikpOworICAgICAgICBpbnN0YW5jZS5zZXRDb21wYXJhdG9yKG5ldyBUaHJvd0NvbXBhcmF0b3IoKSk7CisgICAgICAgIGluc3RhbmNlLnNldEVycm9yTWFuYWdlcihuZXcgSW50ZXJuYWxFcnJvck1hbmFnZXIoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlY29yZHM7ICsraSkgeworICAgICAgICAgICAgICAgIGluc3RhbmNlLnB1Ymxpc2gobmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICIiKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpbnN0YW5jZS5jbG9zZSgpOworICAgICAgICB9CisKKyAgICAgICAgSW50ZXJuYWxFcnJvck1hbmFnZXIgZW0gPSBpbnRlcm5hbEVycm9yTWFuYWdlckZyb20oaW5zdGFuY2UpOworICAgICAgICBib29sZWFuIHNlZW5FcnJvciA9IGZhbHNlOworICAgICAgICBmb3IgKFRocm93YWJsZSB0IDogZW0uZXhjZXB0aW9ucykgeworICAgICAgICAgICAgaWYgKGlzQ29ubmVjdE9yVGltZW91dCh0KSkgeworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfSBlbHNlIGlmICh0LmdldENsYXNzKCkgPT0gUnVudGltZUV4Y2VwdGlvbi5jbGFzcykgeworICAgICAgICAgICAgICAgIHNlZW5FcnJvciA9IHRydWU7CisgICAgICAgICAgICAgICAgY29udGludWU7IC8vZXhwZWN0LgorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBkdW1wKHQpOworICAgICAgICAgICAgICAgIGZhaWwodC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmIChyZWNvcmRzID09IDApIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyh0cnVlLCBlbS5leGNlcHRpb25zLmlzRW1wdHkoKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJFeGNlcHRpb24gd2FzIG5vdCB0aHJvd24uIiwgc2VlbkVycm9yKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyh0cnVlLCAhZW0uZXhjZXB0aW9ucy5pc0VtcHR5KCkpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VGhyb3dGaWx0ZXJzKCkgeworICAgICAgICBMb2dSZWNvcmQgcmVjb3JkID0gbmV3IExvZ1JlY29yZChMZXZlbC5JTkZPLCAiIik7CisgICAgICAgIE1lbW9yeUhhbmRsZXIgbWggPSBuZXcgTWVtb3J5SGFuZGxlcihuZXcgQ29uc29sZUhhbmRsZXIoKSwgMTAwLCBMZXZlbC5PRkYpOworICAgICAgICBtaC5zZXRGaWx0ZXIobmV3IFRocm93RmlsdGVyKCkpOworICAgICAgICBNYWlsSGFuZGxlciBpbnN0YW5jZSA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBib29sZWFuIGV4cGVjdCA9IG1oLmlzTG9nZ2FibGUocmVjb3JkKTsKKyAgICAgICAgICAgIGluc3RhbmNlID0gbmV3IE1haWxIYW5kbGVyKGNyZWF0ZUluaXRQcm9wZXJ0aWVzKCIiKSk7CisgICAgICAgICAgICBpbnN0YW5jZS5zZXRMZXZlbChMZXZlbC5BTEwpOworICAgICAgICAgICAgaW5zdGFuY2Uuc2V0RmlsdGVyKG5ldyBUaHJvd0ZpbHRlcigpKTsKKyAgICAgICAgICAgIGJvb2xlYW4gcmVzdWx0ID0gaW5zdGFuY2UuaXNMb2dnYWJsZShyZWNvcmQpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdCwgcmVzdWx0KTsKKyAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBleHBlY3RFeCkgeworICAgICAgICAgICAgaWYgKGluc3RhbmNlID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZSA9IG5ldyBNYWlsSGFuZGxlcihjcmVhdGVJbml0UHJvcGVydGllcygiIikpOworICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZS5zZXRMZXZlbChMZXZlbC5BTEwpOworICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZS5zZXRGaWx0ZXIobmV3IFRocm93RmlsdGVyKCkpOworICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZS5pc0xvZ2dhYmxlKHJlY29yZCk7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoIkRvZXNuJ3QgbWF0Y2ggdGhlIG1lbW9yeSBoYW5kbGVyLiIpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gcmVzdWx0RXgpIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdEV4LmdldENsYXNzKCksIHJlc3VsdEV4LmdldENsYXNzKCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZmFpbCgiRG9lc24ndCBtYXRjaCB0aGUgbWVtb3J5IGhhbmRsZXIuIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnQgaW5zdGFuY2UgIT0gbnVsbDsKKyAgICAgICAgaW5zdGFuY2Uuc2V0RmlsdGVyKChGaWx0ZXIpIG51bGwpOworCisgICAgICAgIFByb3BlcnRpZXMgcHJvcHMgPSBuZXcgUHJvcGVydGllcygpOworICAgICAgICBwcm9wcy5wdXQoIm1haWwuc210cC5ob3N0IiwgVU5LTk9XTl9IT1NUKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0TWFpbFByb3BlcnRpZXMocHJvcHMpOworCisgICAgICAgIEludGVybmFsRXJyb3JNYW5hZ2VyIGVtID0gbmV3IEludGVybmFsRXJyb3JNYW5hZ2VyKCk7CisgICAgICAgIGluc3RhbmNlLnNldEVycm9yTWFuYWdlcihlbSk7CisKKyAgICAgICAgaW5zdGFuY2Uuc2V0QXR0YWNobWVudEZvcm1hdHRlcnMobmV3IEZvcm1hdHRlcltde25ldyBTaW1wbGVGb3JtYXR0ZXIoKX0pOworICAgICAgICBpbnN0YW5jZS5zZXRBdHRhY2htZW50RmlsdGVycyhuZXcgRmlsdGVyW117bmV3IFRocm93RmlsdGVyKCl9KTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0QXR0YWNobWVudE5hbWVzKG5ldyBTdHJpbmdbXXsidGVzdC50eHQifSk7CisKKyAgICAgICAgaW5zdGFuY2UucHVibGlzaChyZWNvcmQpOworICAgICAgICBpbnN0YW5jZS5jbG9zZSgpOworCisgICAgICAgIGFzc2VydEVxdWFscyh0cnVlLCAhZW0uZXhjZXB0aW9ucy5pc0VtcHR5KCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEVtcHR5KCkgeworICAgICAgICBNYWlsSGFuZGxlciBpbnN0YW5jZSA9IGNyZWF0ZUhhbmRsZXJXaXRoUmVjb3JkcygpOworICAgICAgICBpbnN0YW5jZS5zZXRGb3JtYXR0ZXIobmV3IFNpbXBsZUZvcm1hdHRlcigpKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0QXR0YWNobWVudEZvcm1hdHRlcnMobmV3IEZvcm1hdHRlcltdeworICAgICAgICAgICAgbmV3IEVtcHR5Rm9ybWF0dGVyKCksIG5ldyBTaW1wbGVGb3JtYXR0ZXIoKSwgbmV3IFNpbXBsZUZvcm1hdHRlcigpfSk7CisgICAgICAgIHRlc3RFbXB0eShpbnN0YW5jZSk7CisKKyAgICAgICAgaW5zdGFuY2UgPSBjcmVhdGVIYW5kbGVyV2l0aFJlY29yZHMoKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0Rm9ybWF0dGVyKG5ldyBTaW1wbGVGb3JtYXR0ZXIoKSk7CisgICAgICAgIGluc3RhbmNlLnNldEF0dGFjaG1lbnRGb3JtYXR0ZXJzKG5ldyBGb3JtYXR0ZXJbXXsKKyAgICAgICAgICAgIG5ldyBTaW1wbGVGb3JtYXR0ZXIoKSwgbmV3IEVtcHR5Rm9ybWF0dGVyKCksIG5ldyBTaW1wbGVGb3JtYXR0ZXIoKX0pOworICAgICAgICB0ZXN0RW1wdHkoaW5zdGFuY2UpOworCisgICAgICAgIGluc3RhbmNlID0gY3JlYXRlSGFuZGxlcldpdGhSZWNvcmRzKCk7CisgICAgICAgIGluc3RhbmNlLnNldEZvcm1hdHRlcihuZXcgU2ltcGxlRm9ybWF0dGVyKCkpOworICAgICAgICBpbnN0YW5jZS5zZXRBdHRhY2htZW50Rm9ybWF0dGVycyhuZXcgRm9ybWF0dGVyW117CisgICAgICAgICAgICBuZXcgU2ltcGxlRm9ybWF0dGVyKCksIG5ldyBTaW1wbGVGb3JtYXR0ZXIoKSwgbmV3IEVtcHR5Rm9ybWF0dGVyKCl9KTsKKyAgICAgICAgdGVzdEVtcHR5KGluc3RhbmNlKTsKKworICAgICAgICBpbnN0YW5jZSA9IGNyZWF0ZUhhbmRsZXJXaXRoUmVjb3JkcygpOworICAgICAgICBpbnN0YW5jZS5zZXRGb3JtYXR0ZXIobmV3IEVtcHR5Rm9ybWF0dGVyKCkpOworICAgICAgICBpbnN0YW5jZS5zZXRBdHRhY2htZW50Rm9ybWF0dGVycyhuZXcgRm9ybWF0dGVyW117CisgICAgICAgICAgICBuZXcgU2ltcGxlRm9ybWF0dGVyKCksIG5ldyBTaW1wbGVGb3JtYXR0ZXIoKSwgbmV3IFNpbXBsZUZvcm1hdHRlcigpfSk7CisgICAgICAgIHRlc3RFbXB0eShpbnN0YW5jZSk7CisKKyAgICAgICAgaW5zdGFuY2UgPSBjcmVhdGVIYW5kbGVyV2l0aFJlY29yZHMoKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0Rm9ybWF0dGVyKG5ldyBFbXB0eUZvcm1hdHRlcigpKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0QXR0YWNobWVudEZvcm1hdHRlcnMobmV3IEZvcm1hdHRlcltdeworICAgICAgICAgICAgbmV3IFNpbXBsZUZvcm1hdHRlcigpLCBuZXcgRW1wdHlGb3JtYXR0ZXIoKSwgbmV3IFNpbXBsZUZvcm1hdHRlcigpfSk7CisgICAgICAgIHRlc3RFbXB0eShpbnN0YW5jZSk7CisKKyAgICAgICAgaW5zdGFuY2UgPSBjcmVhdGVIYW5kbGVyV2l0aFJlY29yZHMoKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0Rm9ybWF0dGVyKG5ldyBTaW1wbGVGb3JtYXR0ZXIoKSk7CisgICAgICAgIGluc3RhbmNlLnNldEF0dGFjaG1lbnRGb3JtYXR0ZXJzKG5ldyBGb3JtYXR0ZXJbXXtuZXcgRW1wdHlGb3JtYXR0ZXIoKX0pOworICAgICAgICB0ZXN0RW1wdHkoaW5zdGFuY2UpOworCisgICAgICAgIGluc3RhbmNlID0gY3JlYXRlSGFuZGxlcldpdGhSZWNvcmRzKCk7CisgICAgICAgIGluc3RhbmNlLnNldEZvcm1hdHRlcihuZXcgRW1wdHlGb3JtYXR0ZXIoKSk7CisgICAgICAgIGluc3RhbmNlLnNldEF0dGFjaG1lbnRGb3JtYXR0ZXJzKG5ldyBGb3JtYXR0ZXJbXXtuZXcgU2ltcGxlRm9ybWF0dGVyKCl9KTsKKyAgICAgICAgdGVzdEVtcHR5KGluc3RhbmNlKTsKKworICAgICAgICBpbnN0YW5jZSA9IGNyZWF0ZUhhbmRsZXJXaXRoUmVjb3JkcygpOworICAgICAgICBpbnN0YW5jZS5zZXRGb3JtYXR0ZXIobmV3IEVtcHR5Rm9ybWF0dGVyKCkpOworICAgICAgICBpbnN0YW5jZS5zZXRBdHRhY2htZW50Rm9ybWF0dGVycyhuZXcgRm9ybWF0dGVyW117bmV3IEVtcHR5Rm9ybWF0dGVyKCl9KTsKKyAgICAgICAgdGVzdEVtcHR5KGluc3RhbmNlKTsKKworICAgICAgICBpbnN0YW5jZSA9IGNyZWF0ZUhhbmRsZXJXaXRoUmVjb3JkcygpOworICAgICAgICBpbnN0YW5jZS5zZXRGb3JtYXR0ZXIobmV3IEVtcHR5Rm9ybWF0dGVyKCkpOworICAgICAgICB0ZXN0RW1wdHkoaW5zdGFuY2UpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0RW1wdHkoTWFpbEhhbmRsZXIgaW5zdGFuY2UpIHsKKyAgICAgICAgUHJvcGVydGllcyBwcm9wcyA9IGluc3RhbmNlLmdldE1haWxQcm9wZXJ0aWVzKCk7CisgICAgICAgIHByb3BzLnNldFByb3BlcnR5KCJtYWlsLmZyb20iLCAibG9jYWxob3N0QGxvY2FsZG9tYWluIik7CisgICAgICAgIHByb3BzLnNldFByb3BlcnR5KCJtYWlsLnRvIiwgImxvY2FsaG9zdEBsb2NhbGRvbWFpbiIpOworICAgICAgICBpbnN0YW5jZS5zZXRNYWlsUHJvcGVydGllcyhwcm9wcyk7CisKKyAgICAgICAgTWVzc2FnZUVycm9yTWFuYWdlciBlbXB0eSA9IG5ldyBNZXNzYWdlRXJyb3JNYW5hZ2VyKGluc3RhbmNlLmdldE1haWxQcm9wZXJ0aWVzKCkpIHsKKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBlcnJvcihNaW1lTWVzc2FnZSBtc2csIFRocm93YWJsZSB0LCBpbnQgY29kZSkgeworICAgICAgICAgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBvdXQgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgbXNnLnNhdmVDaGFuZ2VzKCk7CisgICAgICAgICAgICAgICAgICAgIG1zZy53cml0ZVRvKG91dCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIGV4KSB7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoZXgudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9OworICAgICAgICBpbnN0YW5jZS5zZXRFcnJvck1hbmFnZXIoZW1wdHkpOworICAgICAgICBpbnN0YW5jZS5jbG9zZSgpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0QXR0YWNobWVudEludmFyaWFudHMoYm9vbGVhbiBlcnJvcikgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1haWxIYW5kbGVyIHRhcmdldCA9IG5ldyBNYWlsSGFuZGxlcihjcmVhdGVJbml0UHJvcGVydGllcygiIikpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgSW50ZXJuYWxFcnJvck1hbmFnZXIgZW0gPSBpbnRlcm5hbEVycm9yTWFuYWdlckZyb20odGFyZ2V0KTsKKyAgICAgICAgICAgIGlmIChlcnJvcikgeworICAgICAgICAgICAgICAgIGFzc2VydEZhbHNlKGVtLmV4Y2VwdGlvbnMuaXNFbXB0eSgpKTsKKyAgICAgICAgICAgICAgICBib29sZWFuIHVuZXhwZWN0ZWQgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICBmb3IgKEV4Y2VwdGlvbiBlIDogZW0uZXhjZXB0aW9ucykgeworICAgICAgICAgICAgICAgICAgICBpZiAoZSBpbnN0YW5jZW9mIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gPT0gZmFsc2UpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGR1bXAoZSk7CisgICAgICAgICAgICAgICAgICAgICAgICB1bmV4cGVjdGVkID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBhc3NlcnRGYWxzZSh1bmV4cGVjdGVkKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZm9yIChFeGNlcHRpb24gZSA6IGVtLmV4Y2VwdGlvbnMpIHsKKyAgICAgICAgICAgICAgICAgICAgZHVtcChlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShlbS5leGNlcHRpb25zLmlzRW1wdHkoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpbnQgbGVuID0gdGFyZ2V0LmdldEF0dGFjaG1lbnRGb3JtYXR0ZXJzKCkubGVuZ3RoOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShTdHJpbmcudmFsdWVPZihsZW4pLCBsZW4gPiAwKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhsZW4sIHRhcmdldC5nZXRBdHRhY2htZW50RmlsdGVycygpLmxlbmd0aCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMobGVuLCB0YXJnZXQuZ2V0QXR0YWNobWVudE5hbWVzKCkubGVuZ3RoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHRhcmdldC5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWxpZ25FbXB0eUZpbHRlcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgcCA9IE1haWxIYW5kbGVyLmNsYXNzLmdldE5hbWUoKTsKKyAgICAgICAgUHJvcGVydGllcyBwcm9wcyA9IGNyZWF0ZUluaXRQcm9wZXJ0aWVzKHApOworICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5hdHRhY2htZW50LmZvcm1hdHRlcnMiKSwgU2ltcGxlRm9ybWF0dGVyLmNsYXNzLmdldE5hbWUoKSk7CisgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLmF0dGFjaG1lbnQubmFtZXMiKSwgImF0dC50eHQiKTsKKyAgICAgICAgZmluYWwgTG9nTWFuYWdlciBtYW5hZ2VyID0gTG9nTWFuYWdlci5nZXRMb2dNYW5hZ2VyKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZWFkKG1hbmFnZXIsIHByb3BzKTsKKyAgICAgICAgICAgIHRlc3RBdHRhY2htZW50SW52YXJpYW50cyhmYWxzZSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBtYW5hZ2VyLnJlc2V0KCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RBbGlnbkVtcHR5TmFtZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHAgPSBNYWlsSGFuZGxlci5jbGFzcy5nZXROYW1lKCk7CisgICAgICAgIFByb3BlcnRpZXMgcHJvcHMgPSBjcmVhdGVJbml0UHJvcGVydGllcyhwKTsKKyAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIuYXR0YWNobWVudC5mb3JtYXR0ZXJzIiksIFNpbXBsZUZvcm1hdHRlci5jbGFzcy5nZXROYW1lKCkpOworICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5hdHRhY2htZW50LmZpbHRlcnMiKSwgRXJyb3JGaWx0ZXIuY2xhc3MuZ2V0TmFtZSgpKTsKKyAgICAgICAgZmluYWwgTG9nTWFuYWdlciBtYW5hZ2VyID0gTG9nTWFuYWdlci5nZXRMb2dNYW5hZ2VyKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZWFkKG1hbmFnZXIsIHByb3BzKTsKKyAgICAgICAgICAgIHRlc3RBdHRhY2htZW50SW52YXJpYW50cyhmYWxzZSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBtYW5hZ2VyLnJlc2V0KCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RBbGlnbkVtcHR5RmlsdGVyQW5kTmFtZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHAgPSBNYWlsSGFuZGxlci5jbGFzcy5nZXROYW1lKCk7CisgICAgICAgIFByb3BlcnRpZXMgcHJvcHMgPSBjcmVhdGVJbml0UHJvcGVydGllcyhwKTsKKyAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIuYXR0YWNobWVudC5mb3JtYXR0ZXJzIiksIFNpbXBsZUZvcm1hdHRlci5jbGFzcy5nZXROYW1lKCkpOworICAgICAgICBmaW5hbCBMb2dNYW5hZ2VyIG1hbmFnZXIgPSBMb2dNYW5hZ2VyLmdldExvZ01hbmFnZXIoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJlYWQobWFuYWdlciwgcHJvcHMpOworICAgICAgICAgICAgdGVzdEF0dGFjaG1lbnRJbnZhcmlhbnRzKGZhbHNlKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIG1hbmFnZXIucmVzZXQoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEFsaWduRXJyb3JGaWx0ZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHAgPSBNYWlsSGFuZGxlci5jbGFzcy5nZXROYW1lKCk7CisgICAgICAgIFByb3BlcnRpZXMgcHJvcHMgPSBjcmVhdGVJbml0UHJvcGVydGllcyhwKTsKKyAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIuYXR0YWNobWVudC5mb3JtYXR0ZXJzIiksCisgICAgICAgICAgICAgICAgU2ltcGxlRm9ybWF0dGVyLmNsYXNzLmdldE5hbWUoKSArICIsICIgKyBTaW1wbGVGb3JtYXR0ZXIuY2xhc3MuZ2V0TmFtZSgpKTsKKyAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIuYXR0YWNobWVudC5maWx0ZXJzIiksIEVycm9yRmlsdGVyLmNsYXNzLmdldE5hbWUoKSk7CisgICAgICAgIGZpbmFsIExvZ01hbmFnZXIgbWFuYWdlciA9IExvZ01hbmFnZXIuZ2V0TG9nTWFuYWdlcigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVhZChtYW5hZ2VyLCBwcm9wcyk7CisgICAgICAgICAgICB0ZXN0QXR0YWNobWVudEludmFyaWFudHModHJ1ZSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBtYW5hZ2VyLnJlc2V0KCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RBbGlnbkVycm9yTmFtZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIHAgPSBNYWlsSGFuZGxlci5jbGFzcy5nZXROYW1lKCk7CisgICAgICAgIFByb3BlcnRpZXMgcHJvcHMgPSBjcmVhdGVJbml0UHJvcGVydGllcyhwKTsKKyAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIuYXR0YWNobWVudC5mb3JtYXR0ZXJzIiksIFNpbXBsZUZvcm1hdHRlci5jbGFzcy5nZXROYW1lKCkpOworICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5hdHRhY2htZW50Lm5hbWVzIiksICJhdHQudHh0LCBleHRyYS50eHQiKTsKKyAgICAgICAgZmluYWwgTG9nTWFuYWdlciBtYW5hZ2VyID0gTG9nTWFuYWdlci5nZXRMb2dNYW5hZ2VyKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZWFkKG1hbmFnZXIsIHByb3BzKTsKKyAgICAgICAgICAgIHRlc3RBdHRhY2htZW50SW52YXJpYW50cyh0cnVlKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIG1hbmFnZXIucmVzZXQoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEFsaWduRXJyb3JGaWx0ZXJBbmROYW1lcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgcCA9IE1haWxIYW5kbGVyLmNsYXNzLmdldE5hbWUoKTsKKyAgICAgICAgUHJvcGVydGllcyBwcm9wcyA9IGNyZWF0ZUluaXRQcm9wZXJ0aWVzKHApOworICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5hdHRhY2htZW50LmZvcm1hdHRlcnMiKSwKKyAgICAgICAgICAgICAgICBTaW1wbGVGb3JtYXR0ZXIuY2xhc3MuZ2V0TmFtZSgpICsgIiwgIiArIFNpbXBsZUZvcm1hdHRlci5jbGFzcy5nZXROYW1lKCkpOworICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5hdHRhY2htZW50LmZpbHRlcnMiKSwKKyAgICAgICAgICAgICAgICBFcnJvckZpbHRlci5jbGFzcy5nZXROYW1lKCkgKyAiLCIgKyBFcnJvckZpbHRlci5jbGFzcy5nZXROYW1lKCkKKyAgICAgICAgICAgICAgICArICIsIiArIEVycm9yRmlsdGVyLmNsYXNzLmdldE5hbWUoKSk7CisgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLmF0dGFjaG1lbnQubmFtZXMiKSwgImF0dC50eHQsIG5leHQudHh0LCBleHRyYS50eHQiKTsKKyAgICAgICAgZmluYWwgTG9nTWFuYWdlciBtYW5hZ2VyID0gTG9nTWFuYWdlci5nZXRMb2dNYW5hZ2VyKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZWFkKG1hbmFnZXIsIHByb3BzKTsKKyAgICAgICAgICAgIHRlc3RBdHRhY2htZW50SW52YXJpYW50cyh0cnVlKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIG1hbmFnZXIucmVzZXQoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEVuY29kaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFN0cmluZyBlbmMgPSAiaXNvODg1OV8xIjsKKyAgICAgICAgLy9uYW1lcyBhcmUgZGlmZmVyZW50IGJ1dCBlcXVhbCBlbmNvZGluZ3MuCisgICAgICAgIGZpbmFsIFN0cmluZyBmb3VuZCA9IE1pbWVVdGlsaXR5Lm1pbWVDaGFyc2V0KGVuYyk7CisgICAgICAgIENsYXNzPD8+IGsgPSBTZXNzaW9uLmdldEluc3RhbmNlKG5ldyBQcm9wZXJ0aWVzKCkpCisgICAgICAgICAgICAgICAgLmdldFRyYW5zcG9ydCgic210cCIpLmdldENsYXNzKCk7CisgICAgICAgIGlmIChpc1ByaXZhdGVTcGVjKGspKSB7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShlbmMgKyAiPT0iICsgZm91bmQsIGVuYy5lcXVhbHMoZm91bmQpKTsKKyAgICAgICAgfQorCisgICAgICAgIExvZ01hbmFnZXIgbWFuYWdlciA9IExvZ01hbmFnZXIuZ2V0TG9nTWFuYWdlcigpOworICAgICAgICBmaW5hbCBNYWlsSGFuZGxlciBpbnN0YW5jZSA9IG5ldyBNYWlsSGFuZGxlcihjcmVhdGVJbml0UHJvcGVydGllcygiIikpOworICAgICAgICBNZXNzYWdlRXJyb3JNYW5hZ2VyIGVtID0gbmV3IE1lc3NhZ2VFcnJvck1hbmFnZXIoaW5zdGFuY2UuZ2V0TWFpbFByb3BlcnRpZXMoKSkgeworCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHByb3RlY3RlZCB2b2lkIGVycm9yKE1pbWVNZXNzYWdlIG1zZywgVGhyb3dhYmxlIHQsIGludCBjb2RlKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgTWltZU11bHRpcGFydCBtdWx0aSA9IChNaW1lTXVsdGlwYXJ0KSBtc2cuZ2V0Q29udGVudCgpOworICAgICAgICAgICAgICAgICAgICBCb2R5UGFydCBib2R5ID0gbXVsdGkuZ2V0Qm9keVBhcnQoMCk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhQYXJ0LklOTElORSwgYm9keS5nZXREaXNwb3NpdGlvbigpKTsKKyAgICAgICAgICAgICAgICAgICAgQ29udGVudFR5cGUgY3QgPSBuZXcgQ29udGVudFR5cGUoYm9keS5nZXRDb250ZW50VHlwZSgpKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKE1pbWVVdGlsaXR5Lm1pbWVDaGFyc2V0KGVuYyksIGN0LmdldFBhcmFtZXRlcigiY2hhcnNldCIpKTsKKworICAgICAgICAgICAgICAgICAgICBCb2R5UGFydCBhdHRhY2ggPSBtdWx0aS5nZXRCb2R5UGFydCgxKTsKKyAgICAgICAgICAgICAgICAgICAgY3QgPSBuZXcgQ29udGVudFR5cGUoYXR0YWNoLmdldENvbnRlbnRUeXBlKCkpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoTWltZVV0aWxpdHkubWltZUNoYXJzZXQoZW5jKSwgY3QuZ2V0UGFyYW1ldGVyKCJjaGFyc2V0IikpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSBFKSB7CisgICAgICAgICAgICAgICAgICAgIGR1bXAoRSk7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoRS50b1N0cmluZygpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICAgICAgaW5zdGFuY2Uuc2V0RXJyb3JNYW5hZ2VyKGVtKTsKKyAgICAgICAgUHJvcGVydGllcyBwcm9wcyA9IGNyZWF0ZUluaXRQcm9wZXJ0aWVzKCIiKTsKKyAgICAgICAgcHJvcHMucHV0KCJtYWlsLnRvIiwgImxvY2FsaG9zdEBsb2NhbGRvbWFpbiIpOworICAgICAgICBpbnN0YW5jZS5zZXRNYWlsUHJvcGVydGllcyhwcm9wcyk7CisgICAgICAgIGluc3RhbmNlLnNldEF0dGFjaG1lbnRGb3JtYXR0ZXJzKG5ldyBGb3JtYXR0ZXJbXXtuZXcgWE1MRm9ybWF0dGVyKCl9KTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0QXR0YWNobWVudE5hbWVzKG5ldyBTdHJpbmdbXXsiYWxsLnhtbCJ9KTsKKyAgICAgICAgU3RyaW5nIHAgPSBpbnN0YW5jZS5nZXRDbGFzcygpLmdldE5hbWUoKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMobWFuYWdlci5nZXRQcm9wZXJ0eShwLmNvbmNhdCgiLmVuY29kaW5nIikpLCBpbnN0YW5jZS5nZXRFbmNvZGluZygpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGluc3RhbmNlLnNldEVuY29kaW5nKCJ1bnN1cHBvcnRlZCBlbmNvZGluZyBleGNlcHRpb24iKTsKKyAgICAgICAgICAgIGZhaWwoIk1pc3NpbmcgZW5jb2RpbmcgY2hlY2suIik7CisgICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gZXhwZWN0KSB7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKG1hbmFnZXIuZ2V0UHJvcGVydHkocC5jb25jYXQoIi5lbmNvZGluZyIpKSwgaW5zdGFuY2UuZ2V0RW5jb2RpbmcoKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShlbS5leGNlcHRpb25zLmlzRW1wdHkoKSk7CisKKyAgICAgICAgaW5zdGFuY2Uuc2V0RW5jb2RpbmcoZW5jKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGVuYywgaW5zdGFuY2UuZ2V0RW5jb2RpbmcoKSk7CisgICAgICAgIGluc3RhbmNlLnNldFN1YmplY3QoIk9SQS0xNzA0Mz1VbmdcdTAwRkNsdGlnZSBtYXhpbWFsZSBTdHJlYW0tR3JcdTAwRjZcdTAwREZlIik7CisgICAgICAgIExvZ1JlY29yZCByZWNvcmQgPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgIlplaXRcdTAwRkNiZXJzY2hyZWl0dW5nIGJlaSBBbndlaXN1bmciKTsKKyAgICAgICAgaW5zdGFuY2UucHVibGlzaChyZWNvcmQpOworICAgICAgICBpbnN0YW5jZS5jbG9zZSgpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEVycm9yTWFuYWdlcigpIHsKKyAgICAgICAgTWFpbEhhbmRsZXIgaCA9IG5ldyBNYWlsSGFuZGxlcigpOworICAgICAgICBhc3NlcnROb3ROdWxsKGguZ2V0RXJyb3JNYW5hZ2VyKCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaC5zZXRFcnJvck1hbmFnZXIoKEVycm9yTWFuYWdlcikgbnVsbCk7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGV4cGVjdCkgeworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChoKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnROb3ROdWxsKGguZ2V0RXJyb3JNYW5hZ2VyKCkpOworCisgICAgICAgIEVycm9yTWFuYWdlciBlbSA9IG5ldyBFcnJvck1hbmFnZXIoKTsKKyAgICAgICAgaC5zZXRFcnJvck1hbmFnZXIoZW0pOworICAgICAgICBhc3NlcnRTYW1lKGVtLCBoLmdldEVycm9yTWFuYWdlcigpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXR0ZXIoKSB7CisgICAgICAgIE1haWxIYW5kbGVyIGggPSBuZXcgTWFpbEhhbmRsZXIoKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChoLmdldEZvcm1hdHRlcigpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGguc2V0Rm9ybWF0dGVyKChGb3JtYXR0ZXIpIG51bGwpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBleHBlY3QpIHsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoaCk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0Tm90TnVsbChoLmdldEZvcm1hdHRlcigpKTsKKworICAgICAgICBTaW1wbGVGb3JtYXR0ZXIgZiA9IG5ldyBTaW1wbGVGb3JtYXR0ZXIoKTsKKyAgICAgICAgaC5zZXRGb3JtYXR0ZXIoZik7CisgICAgICAgIGFzc2VydFNhbWUoZiwgaC5nZXRGb3JtYXR0ZXIoKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RmlsdGVyKCkgeworICAgICAgICBNYWlsSGFuZGxlciBoID0gbmV3IE1haWxIYW5kbGVyKCk7CisgICAgICAgIGFzc2VydE51bGwoaC5nZXRGaWx0ZXIoKSk7CisgICAgICAgIGguc2V0RmlsdGVyKChGaWx0ZXIpIG51bGwpOworICAgICAgICBhc3NlcnROdWxsKGguZ2V0RmlsdGVyKCkpOworCisgICAgICAgIEJvb2xlYW5GaWx0ZXIgZiA9IG5ldyBCb29sZWFuRmlsdGVyKCk7CisgICAgICAgIGguc2V0RmlsdGVyKGYpOworICAgICAgICBhc3NlcnRTYW1lKGYsIGguZ2V0RmlsdGVyKCkpOworCisgICAgICAgIGguc2V0RmlsdGVyKChGaWx0ZXIpIG51bGwpOworICAgICAgICBhc3NlcnROdWxsKGguZ2V0RmlsdGVyKCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFN0YXRlZnVsRmlsdGVyKCkgeworICAgICAgICBNYWlsSGFuZGxlciBoID0gbmV3IE1haWxIYW5kbGVyKCk7CisgICAgICAgIGguc2V0TWFpbFByb3BlcnRpZXMoY3JlYXRlSW5pdFByb3BlcnRpZXMoIiIpKTsKKyAgICAgICAgSW50ZXJuYWxFcnJvck1hbmFnZXIgZW0gPSBuZXcgRmx1c2hFcnJvck1hbmFnZXIoaCk7CisgICAgICAgIGguc2V0RXJyb3JNYW5hZ2VyKGVtKTsKKyAgICAgICAgQ291bnRpbmdGaWx0ZXIgY2YgPSBuZXcgQ291bnRpbmdGaWx0ZXIoKTsKKyAgICAgICAgaC5zZXRGaWx0ZXIoY2YpOworICAgICAgICBpbnQgTUFYX1JFQ09SRFMgPSAxMDA7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgTUFYX1JFQ09SRFM7IGkrKykgeworICAgICAgICAgICAgTG9nUmVjb3JkIHIgPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgIiIpOworICAgICAgICAgICAgaC5wdWJsaXNoKHIpOworICAgICAgICB9CisgICAgICAgIGguY2xvc2UoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKE1BWF9SRUNPUkRTLCBjZi5jb3VudCk7CisgICAgICAgIGZvciAoRXhjZXB0aW9uIGV4Y2VwdGlvbiA6IGVtLmV4Y2VwdGlvbnMpIHsKKyAgICAgICAgICAgIGlmICghaXNDb25uZWN0T3JUaW1lb3V0KGV4Y2VwdGlvbikpIHsKKyAgICAgICAgICAgICAgICBkdW1wKGV4Y2VwdGlvbik7CisgICAgICAgICAgICAgICAgZmFpbChTdHJpbmcudmFsdWVPZihleGNlcHRpb24pKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBhc3NlcnRGYWxzZShlbS5leGNlcHRpb25zLmlzRW1wdHkoKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3RhdGVmdWxBdHRhY2htZW50RmlsdGVyKCkgeworICAgICAgICBNYWlsSGFuZGxlciBoID0gbmV3IE1haWxIYW5kbGVyKCk7CisgICAgICAgIGguc2V0TWFpbFByb3BlcnRpZXMoY3JlYXRlSW5pdFByb3BlcnRpZXMoIiIpKTsKKyAgICAgICAgSW50ZXJuYWxFcnJvck1hbmFnZXIgZW0gPSBuZXcgRmx1c2hFcnJvck1hbmFnZXIoaCk7CisgICAgICAgIGguc2V0RXJyb3JNYW5hZ2VyKGVtKTsKKyAgICAgICAgQ291bnRpbmdGaWx0ZXIgbmVnYXRpdmVPbmUgPSBuZXcgQ291bnRpbmdGaWx0ZXIoQm9vbGVhbkZpbHRlci5GQUxTRSk7CisgICAgICAgIGguc2V0RmlsdGVyKG5lZ2F0aXZlT25lKTsKKyAgICAgICAgaC5zZXRBdHRhY2htZW50Rm9ybWF0dGVycyhuZXcgU2ltcGxlRm9ybWF0dGVyKCksIG5ldyBTaW1wbGVGb3JtYXR0ZXIoKSwKKyAgICAgICAgICAgICAgICBuZXcgU2ltcGxlRm9ybWF0dGVyKCkpOworICAgICAgICBDb3VudGluZ0ZpbHRlciBvbmUgPSBuZXcgQ291bnRpbmdGaWx0ZXIoQm9vbGVhbkZpbHRlci5GQUxTRSk7CisgICAgICAgIENvdW50aW5nRmlsdGVyIHR3byA9IG5ldyBDb3VudGluZ0ZpbHRlcigpOworICAgICAgICBoLnNldEF0dGFjaG1lbnRGaWx0ZXJzKEJvb2xlYW5GaWx0ZXIuRkFMU0UsIG9uZSwgdHdvKTsKKyAgICAgICAgaW50IE1BWF9SRUNPUkRTID0gMTAwOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IE1BWF9SRUNPUkRTOyBpKyspIHsKKyAgICAgICAgICAgIExvZ1JlY29yZCByID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICIiKTsKKyAgICAgICAgICAgIGgucHVibGlzaChyKTsKKyAgICAgICAgfQorICAgICAgICBoLmNsb3NlKCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKE1BWF9SRUNPUkRTLCBuZWdhdGl2ZU9uZS5jb3VudCk7CisgICAgICAgIGFzc2VydEVxdWFscyhNQVhfUkVDT1JEUywgb25lLmNvdW50KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKE1BWF9SRUNPUkRTLCB0d28uY291bnQpOworICAgICAgICBmb3IgKEV4Y2VwdGlvbiBleGNlcHRpb24gOiBlbS5leGNlcHRpb25zKSB7CisgICAgICAgICAgICBpZiAoIWlzQ29ubmVjdE9yVGltZW91dChleGNlcHRpb24pKSB7CisgICAgICAgICAgICAgICAgZHVtcChleGNlcHRpb24pOworICAgICAgICAgICAgICAgIGZhaWwoU3RyaW5nLnZhbHVlT2YoZXhjZXB0aW9uKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RmFsc2UoZW0uZXhjZXB0aW9ucy5pc0VtcHR5KCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFN0YXRlZnVsSW50ZXJuQXR0YWNobWVudEZpbHRlcigpIHsKKyAgICAgICAgdGVzdFN0YXRlZnVsQXR0YWNobWVudEZpbHRlcihmYWxzZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RTdGF0ZWZ1bEF0dGFjaG1lbnRGaWx0ZXIoYm9vbGVhbiBjbGVhcikgeworICAgICAgICBNYWlsSGFuZGxlciBoID0gbmV3IE1haWxIYW5kbGVyKCk7CisgICAgICAgIGguc2V0TWFpbFByb3BlcnRpZXMoY3JlYXRlSW5pdFByb3BlcnRpZXMoIiIpKTsKKyAgICAgICAgSW50ZXJuYWxFcnJvck1hbmFnZXIgZW0gPSBuZXcgRmx1c2hFcnJvck1hbmFnZXIoaCk7CisgICAgICAgIGguc2V0RXJyb3JNYW5hZ2VyKGVtKTsKKyAgICAgICAgQ291bnRpbmdGaWx0ZXIgY2YgPSBuZXcgQ291bnRpbmdGaWx0ZXIoQm9vbGVhbkZpbHRlci5UUlVFKTsKKyAgICAgICAgaC5zZXRGaWx0ZXIoY2YpOworICAgICAgICBoLnNldEF0dGFjaG1lbnRGb3JtYXR0ZXJzKG5ldyBTaW1wbGVGb3JtYXR0ZXIoKSwgbmV3IFNpbXBsZUZvcm1hdHRlcigpKTsKKyAgICAgICAgQ291bnRpbmdGaWx0ZXIgb25lID0gbmV3IENvdW50aW5nRmlsdGVyKCk7CisgICAgICAgIGguc2V0QXR0YWNobWVudEZpbHRlcnMoY2YsIG9uZSk7CisgICAgICAgIGludCBNQVhfUkVDT1JEUyA9IDEwMDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBNQVhfUkVDT1JEUzsgaSsrKSB7CisgICAgICAgICAgICBMb2dSZWNvcmQgciA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAiIik7CisgICAgICAgICAgICBoLnB1Ymxpc2gocik7CisgICAgICAgIH0KKworICAgICAgICBpZiAoY2xlYXIpIHsKKyAgICAgICAgICAgIEZpbHRlcltdIGFmID0gaC5nZXRBdHRhY2htZW50RmlsdGVycygpOworICAgICAgICAgICAgaC5zZXRBdHRhY2htZW50Rm9ybWF0dGVycygpOworICAgICAgICAgICAgaC5zZXRBdHRhY2htZW50Rm9ybWF0dGVycyhuZXcgU2ltcGxlRm9ybWF0dGVyKCksCisgICAgICAgICAgICAgICAgICAgIG5ldyBTaW1wbGVGb3JtYXR0ZXIoKSk7CisgICAgICAgICAgICBoLnNldEF0dGFjaG1lbnRGaWx0ZXJzKGFmKTsKKyAgICAgICAgfQorICAgICAgICBoLmNsb3NlKCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKE1BWF9SRUNPUkRTLCBjZi5jb3VudCk7CisgICAgICAgIGFzc2VydEVxdWFscyhNQVhfUkVDT1JEUywgb25lLmNvdW50KTsKKyAgICAgICAgZm9yIChFeGNlcHRpb24gZXhjZXB0aW9uIDogZW0uZXhjZXB0aW9ucykgeworICAgICAgICAgICAgaWYgKCFpc0Nvbm5lY3RPclRpbWVvdXQoZXhjZXB0aW9uKSkgeworICAgICAgICAgICAgICAgIGR1bXAoZXhjZXB0aW9uKTsKKyAgICAgICAgICAgICAgICBmYWlsKFN0cmluZy52YWx1ZU9mKGV4Y2VwdGlvbikpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGFzc2VydEZhbHNlKGVtLmV4Y2VwdGlvbnMuaXNFbXB0eSgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RTdGF0ZWZ1bEF0dGFjaG1lbnRGaWx0ZXJDbGVhck1hdGNoZXMoKSB7CisgICAgICAgIHRlc3RTdGF0ZWZ1bEF0dGFjaG1lbnRGaWx0ZXIodHJ1ZSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3RhdGVmdWxQdXNoRmlsdGVyKCkgeworICAgICAgICBNYWlsSGFuZGxlciBoID0gbmV3IE1haWxIYW5kbGVyKCk7CisgICAgICAgIGguc2V0TWFpbFByb3BlcnRpZXMoY3JlYXRlSW5pdFByb3BlcnRpZXMoIiIpKTsKKyAgICAgICAgSW50ZXJuYWxFcnJvck1hbmFnZXIgZW0gPSBuZXcgUHVzaEVycm9yTWFuYWdlcihoKTsKKyAgICAgICAgaC5zZXRFcnJvck1hbmFnZXIoZW0pOworICAgICAgICBDb3VudGluZ0ZpbHRlciBjZiA9IG5ldyBDb3VudGluZ0ZpbHRlcigpOworICAgICAgICBoLnNldEZpbHRlcihjZik7CisgICAgICAgIGguc2V0UHVzaExldmVsKExldmVsLkFMTCk7CisgICAgICAgIGguc2V0UHVzaEZpbHRlcihjZik7CisgICAgICAgIExvZ1JlY29yZCByID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICIiKTsKKyAgICAgICAgaC5wdWJsaXNoKHIpOworICAgICAgICBoLmNsb3NlKCk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBjZi5jb3VudCk7CisgICAgICAgIGZvciAoRXhjZXB0aW9uIGV4Y2VwdGlvbiA6IGVtLmV4Y2VwdGlvbnMpIHsKKyAgICAgICAgICAgIGlmICghaXNDb25uZWN0T3JUaW1lb3V0KGV4Y2VwdGlvbikpIHsKKyAgICAgICAgICAgICAgICBkdW1wKGV4Y2VwdGlvbik7CisgICAgICAgICAgICAgICAgZmFpbChTdHJpbmcudmFsdWVPZihleGNlcHRpb24pKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBhc3NlcnRGYWxzZShlbS5leGNlcHRpb25zLmlzRW1wdHkoKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RTdGF0ZWZ1bFB1c2hBdHRhY2htZW50RmlsdGVyKGJvb2xlYW4gY2xlYXIpIHsKKyAgICAgICAgZmluYWwgTWFpbEhhbmRsZXIgaCA9IG5ldyBNYWlsSGFuZGxlcigpOworICAgICAgICBoLnNldE1haWxQcm9wZXJ0aWVzKGNyZWF0ZUluaXRQcm9wZXJ0aWVzKCIiKSk7CisgICAgICAgIGZpbmFsIEludGVybmFsRXJyb3JNYW5hZ2VyIGVtID0gbmV3IFB1c2hFcnJvck1hbmFnZXIoaCk7CisgICAgICAgIGguc2V0RXJyb3JNYW5hZ2VyKGVtKTsKKyAgICAgICAgZmluYWwgQ291bnRpbmdGaWx0ZXIgY2YgPSBuZXcgQ291bnRpbmdGaWx0ZXIoQm9vbGVhbkZpbHRlci5GQUxTRSk7CisgICAgICAgIGguc2V0RmlsdGVyKGNmKTsKKyAgICAgICAgaC5zZXRQdXNoTGV2ZWwoTGV2ZWwuQUxMKTsKKyAgICAgICAgZmluYWwgQ291bnRpbmdGaWx0ZXIgcHVzaCA9IG5ldyBDb3VudGluZ0ZpbHRlcigpOworICAgICAgICBoLnNldFB1c2hGaWx0ZXIocHVzaCk7CisgICAgICAgIGguc2V0QXR0YWNobWVudEZvcm1hdHRlcnMobmV3IFNpbXBsZUZvcm1hdHRlcigpLCBuZXcgU2ltcGxlRm9ybWF0dGVyKCksIG5ldyBTaW1wbGVGb3JtYXR0ZXIoKSk7CisgICAgICAgIGZpbmFsIENvdW50aW5nRmlsdGVyIG9uZSA9IG5ldyBDb3VudGluZ0ZpbHRlcihCb29sZWFuRmlsdGVyLkZBTFNFKTsKKyAgICAgICAgZmluYWwgQ291bnRpbmdGaWx0ZXIgdHdvID0gbmV3IENvdW50aW5nRmlsdGVyKEJvb2xlYW5GaWx0ZXIuRkFMU0UpOworCisgICAgICAgIGlmIChjbGVhcikgeworICAgICAgICAgICAgaC5zZXRBdHRhY2htZW50RmlsdGVycyhvbmUsIHR3bywKKyAgICAgICAgICAgICAgICAgICAgbmV3IEZpbHRlcigpIHsKKwkJCUBPdmVycmlkZQorICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gaXNMb2dnYWJsZShMb2dSZWNvcmQgcmVjb3JkKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaC5zZXRBdHRhY2htZW50Rm9ybWF0dGVycyhuZXcgU2ltcGxlRm9ybWF0dGVyKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU2ltcGxlRm9ybWF0dGVyKCkpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGguc2V0QXR0YWNobWVudEZpbHRlcnMob25lLCBwdXNoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcHVzaC5pc0xvZ2dhYmxlKHJlY29yZCk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgfSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBoLnNldEF0dGFjaG1lbnRGaWx0ZXJzKG9uZSwgdHdvLCBwdXNoKTsKKyAgICAgICAgfQorCisgICAgICAgIExvZ1JlY29yZCByID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICIiKTsKKyAgICAgICAgaC5wdWJsaXNoKHIpOworICAgICAgICBoLmNsb3NlKCk7CisKKyAgICAgICAgaWYgKGNsZWFyKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMiwgY2YuY291bnQpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDIsIG9uZS5jb3VudCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgdHdvLmNvdW50KTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygzLCBwdXNoLmNvdW50KTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBjZi5jb3VudCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgb25lLmNvdW50KTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCB0d28uY291bnQpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIHB1c2guY291bnQpOworICAgICAgICB9CisgICAgICAgIGZvciAoRXhjZXB0aW9uIGV4Y2VwdGlvbiA6IGVtLmV4Y2VwdGlvbnMpIHsKKyAgICAgICAgICAgIGlmICghaXNDb25uZWN0T3JUaW1lb3V0KGV4Y2VwdGlvbikpIHsKKyAgICAgICAgICAgICAgICBkdW1wKGV4Y2VwdGlvbik7CisgICAgICAgICAgICAgICAgZmFpbChTdHJpbmcudmFsdWVPZihleGNlcHRpb24pKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBhc3NlcnRGYWxzZShlbS5leGNlcHRpb25zLmlzRW1wdHkoKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3RhdGVmdWxQdXNoQXR0YWNobWVudEZpbHRlcigpIHsKKyAgICAgICAgdGVzdFN0YXRlZnVsUHVzaEF0dGFjaG1lbnRGaWx0ZXIoZmFsc2UpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFN0YXRlZnVsUHVzaEZpbHRlckNsZWFyTWF0Y2hlcygpIHsKKyAgICAgICAgdGVzdFN0YXRlZnVsUHVzaEF0dGFjaG1lbnRGaWx0ZXIodHJ1ZSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHVzaEluc2lkZVB1c2goKSB7CisgICAgICAgIGZpbmFsIExldmVsW10gbHZscyA9IGdldEFsbExldmVscygpOworCisgICAgICAgIE1haWxIYW5kbGVyIGluc3RhbmNlID0gbmV3IE1haWxIYW5kbGVyKGx2bHMubGVuZ3RoICsgMik7CisgICAgICAgIEludGVybmFsRXJyb3JNYW5hZ2VyIGVtID0gbmV3IEludGVybmFsRXJyb3JNYW5hZ2VyKCk7CisgICAgICAgIGluc3RhbmNlLnNldEVycm9yTWFuYWdlcihlbSk7CisgICAgICAgIGluc3RhbmNlLnNldE1haWxQcm9wZXJ0aWVzKGNyZWF0ZUluaXRQcm9wZXJ0aWVzKCIiKSk7CisgICAgICAgIGluc3RhbmNlLnNldExldmVsKExldmVsLkFMTCk7CisgICAgICAgIGluc3RhbmNlLnNldEZpbHRlcigoRmlsdGVyKSBudWxsKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0UHVzaExldmVsKExldmVsLk9GRik7CisgICAgICAgIGluc3RhbmNlLnNldFB1c2hGaWx0ZXIoKEZpbHRlcikgbnVsbCk7CisKKyAgICAgICAgaW5zdGFuY2Uuc2V0Rm9ybWF0dGVyKG5ldyBTaW1wbGVGb3JtYXR0ZXIoKSB7CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIFN0cmluZyBnZXRIZWFkKEhhbmRsZXIgaCkgeworICAgICAgICAgICAgICAgIGFzc2VydCBoIGluc3RhbmNlb2YgTWFpbEhhbmRsZXIgOiBoOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGguZmx1c2goKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChUaHJvd2FibGUgVCkgeworICAgICAgICAgICAgICAgICAgICBmYWlsKFQudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXRIZWFkKGgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFpbChIYW5kbGVyIGgpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnQgaCBpbnN0YW5jZW9mIE1haWxIYW5kbGVyIDogaDsKKyAgICAgICAgICAgICAgICBmaW5hbCBGaWx0ZXIgZmlsdGVyID0gaC5nZXRGaWx0ZXIoKTsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBoLnNldEZpbHRlcihmaWx0ZXIpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSBUKSB7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoVC50b1N0cmluZygpKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBmaW5hbCBMZXZlbCBsdmwgPSBoLmdldExldmVsKCk7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgaC5zZXRMZXZlbChsdmwpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSBUKSB7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoVC50b1N0cmluZygpKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgZW5jID0gaC5nZXRFbmNvZGluZygpOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGguc2V0RW5jb2RpbmcoZW5jKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChUaHJvd2FibGUgVCkgeworICAgICAgICAgICAgICAgICAgICBmYWlsKFQudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgaC5zZXRGb3JtYXR0ZXIobmV3IFNpbXBsZUZvcm1hdHRlcigpKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChUaHJvd2FibGUgVCkgeworICAgICAgICAgICAgICAgICAgICBmYWlsKFQudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgaC5jbG9zZSgpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoaC5nZXRMZXZlbCgpLCBMZXZlbC5PRkYpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSBUKSB7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoVC50b1N0cmluZygpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldFRhaWwoaCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0pOworCisgICAgICAgIEZvcm1hdHRlciBwdXNoID0gbmV3IFNpbXBsZUZvcm1hdHRlcigpIHsKKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEhlYWQoSGFuZGxlciBoKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0IGggaW5zdGFuY2VvZiBNYWlsSGFuZGxlciA6IGg7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgKChNYWlsSGFuZGxlcikgaCkucHVzaCgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSBUKSB7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoVC50b1N0cmluZygpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldEhlYWQoaCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIFN0cmluZyBnZXRUYWlsKEhhbmRsZXIgaCkgeworICAgICAgICAgICAgICAgIGFzc2VydCBoIGluc3RhbmNlb2YgTWFpbEhhbmRsZXIgOiBoOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICgoTWFpbEhhbmRsZXIpIGgpLnB1c2goKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChUaHJvd2FibGUgVCkgeworICAgICAgICAgICAgICAgICAgICBmYWlsKFQudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXRUYWlsKGgpOworICAgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgICAgIEZvcm1hdHRlciBhdEZvciA9IG5ldyBTaW1wbGVGb3JtYXR0ZXIoKSB7CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIFN0cmluZyBnZXRIZWFkKEhhbmRsZXIgaCkgeworICAgICAgICAgICAgICAgIGFzc2VydCBoIGluc3RhbmNlb2YgTWFpbEhhbmRsZXIgOiBoOworICAgICAgICAgICAgICAgIE1haWxIYW5kbGVyIG1oID0gKE1haWxIYW5kbGVyKSBoOworICAgICAgICAgICAgICAgIEZvcm1hdHRlcltdIGYgPSBtaC5nZXRBdHRhY2htZW50Rm9ybWF0dGVycygpOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIG1oLnNldEF0dGFjaG1lbnRGb3JtYXR0ZXJzKGYpOworICAgICAgICAgICAgICAgICAgICBmYWlsKCJNdXRhYmxlIGZvcm1hdHRlci4iKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gcGFzcykgeworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSBUKSB7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoVC50b1N0cmluZygpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldEhlYWQoaCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIFN0cmluZyBnZXRUYWlsKEhhbmRsZXIgaCkgeworICAgICAgICAgICAgICAgIGdldEhlYWQoaCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldFRhaWwoaCk7CisgICAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICAgICAgRm9ybWF0dGVyIGF0TmFtZSA9IG5ldyBTaW1wbGVGb3JtYXR0ZXIoKSB7CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIFN0cmluZyBnZXRIZWFkKEhhbmRsZXIgaCkgeworICAgICAgICAgICAgICAgIGFzc2VydCBoIGluc3RhbmNlb2YgTWFpbEhhbmRsZXIgOiBoOworICAgICAgICAgICAgICAgIE1haWxIYW5kbGVyIG1oID0gKE1haWxIYW5kbGVyKSBoOworICAgICAgICAgICAgICAgIEZvcm1hdHRlcltdIGYgPSBtaC5nZXRBdHRhY2htZW50TmFtZXMoKTsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBtaC5zZXRBdHRhY2htZW50TmFtZXMoZik7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoIk11dGFibGUgZm9ybWF0dGVyLiIpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBwYXNzKSB7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIFQpIHsKKyAgICAgICAgICAgICAgICAgICAgZmFpbChULnRvU3RyaW5nKCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0SGVhZChoKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFRhaWwoSGFuZGxlciBoKSB7CisgICAgICAgICAgICAgICAgZ2V0SGVhZChoKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0VGFpbChoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICBGb3JtYXR0ZXIgYXRGaWx0ZXIgPSBuZXcgU2ltcGxlRm9ybWF0dGVyKCkgeworCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0SGVhZChIYW5kbGVyIGgpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnQgaCBpbnN0YW5jZW9mIE1haWxIYW5kbGVyOworICAgICAgICAgICAgICAgIE1haWxIYW5kbGVyIG1oID0gKE1haWxIYW5kbGVyKSBoOworICAgICAgICAgICAgICAgIEZpbHRlcltdIGYgPSBtaC5nZXRBdHRhY2htZW50RmlsdGVycygpOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIG1oLnNldEF0dGFjaG1lbnRGaWx0ZXJzKGYpOworICAgICAgICAgICAgICAgICAgICBmYWlsKCJNdXRhYmxlIGZpbHRlcnMuIik7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIHBhc3MpIHsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChUaHJvd2FibGUgVCkgeworICAgICAgICAgICAgICAgICAgICBmYWlsKFQudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXRIZWFkKGgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFpbChIYW5kbGVyIGgpIHsKKyAgICAgICAgICAgICAgICBnZXRIZWFkKGgpOworICAgICAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXRUYWlsKGgpOworICAgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgICAgIEZvcm1hdHRlciBuYW1lQ29tcCA9IG5ldyBGb3JtYXR0ZXIoKSB7CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIFN0cmluZyBnZXRIZWFkKEhhbmRsZXIgaCkgeworICAgICAgICAgICAgICAgIGFzc2VydCBoIGluc3RhbmNlb2YgTWFpbEhhbmRsZXIgOiBoOworICAgICAgICAgICAgICAgIE1haWxIYW5kbGVyIG1oID0gKE1haWxIYW5kbGVyKSBoOworICAgICAgICAgICAgICAgIENvbXBhcmF0b3I8PyBzdXBlciBMb2dSZWNvcmQ+IGMgPSBtaC5nZXRDb21wYXJhdG9yKCk7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgbWguc2V0Q29tcGFyYXRvcihjKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgiTXV0YWJsZSBjb21wYXJhdG9yLiIpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBwYXNzKSB7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIFQpIHsKKyAgICAgICAgICAgICAgICAgICAgZmFpbChULnRvU3RyaW5nKCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0SGVhZChoKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGZvcm1hdChMb2dSZWNvcmQgcikgeworICAgICAgICAgICAgICAgIHJldHVybiAiIjsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFRhaWwoSGFuZGxlciBoKSB7CisgICAgICAgICAgICAgICAgZ2V0SGVhZChoKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gIm5hbWUudHh0IjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICBGb3JtYXR0ZXIgbmFtZU1haWwgPSBuZXcgRm9ybWF0dGVyKCkgeworCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0SGVhZChIYW5kbGVyIGgpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnQgaCBpbnN0YW5jZW9mIE1haWxIYW5kbGVyIDogaDsKKyAgICAgICAgICAgICAgICBNYWlsSGFuZGxlciBtaCA9IChNYWlsSGFuZGxlcikgaDsKKyAgICAgICAgICAgICAgICBQcm9wZXJ0aWVzIHByb3BzID0gbWguZ2V0TWFpbFByb3BlcnRpZXMoKTsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBtaC5zZXRNYWlsUHJvcGVydGllcyhwcm9wcyk7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoIk11dGFibGUgcHJvcHMuIik7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIHBhc3MpIHsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChUaHJvd2FibGUgVCkgeworICAgICAgICAgICAgICAgICAgICBmYWlsKFQudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXRIZWFkKGgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgZm9ybWF0KExvZ1JlY29yZCByKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuICIiOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFpbChIYW5kbGVyIGgpIHsKKyAgICAgICAgICAgICAgICBnZXRIZWFkKGgpOworICAgICAgICAgICAgICAgIHJldHVybiAibmFtZS50eHQiOworICAgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgICAgIEZvcm1hdHRlciBuYW1lU3ViID0gbmV3IEZvcm1hdHRlcigpIHsKKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEhlYWQoSGFuZGxlciBoKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0IGggaW5zdGFuY2VvZiBNYWlsSGFuZGxlciA6IGg7CisgICAgICAgICAgICAgICAgTWFpbEhhbmRsZXIgbWggPSAoTWFpbEhhbmRsZXIpIGg7CisgICAgICAgICAgICAgICAgRm9ybWF0dGVyIGYgPSBtaC5nZXRTdWJqZWN0KCk7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgbWguc2V0U3ViamVjdChmKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgiTXV0YWJsZSBzdWJqZWN0LiIpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBwYXNzKSB7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIFQpIHsKKyAgICAgICAgICAgICAgICAgICAgZmFpbChULnRvU3RyaW5nKCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0SGVhZChoKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGZvcm1hdChMb2dSZWNvcmQgcikgeworICAgICAgICAgICAgICAgIHJldHVybiAiIjsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFRhaWwoSGFuZGxlciBoKSB7CisgICAgICAgICAgICAgICAgZ2V0SGVhZChoKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gIm5hbWUudHh0IjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICBGb3JtYXR0ZXIgbmFtZUF1dGggPSBuZXcgRm9ybWF0dGVyKCkgeworCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0SGVhZChIYW5kbGVyIGgpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnQgaCBpbnN0YW5jZW9mIE1haWxIYW5kbGVyIDogaDsKKyAgICAgICAgICAgICAgICBNYWlsSGFuZGxlciBtaCA9IChNYWlsSGFuZGxlcikgaDsKKyAgICAgICAgICAgICAgICBBdXRoZW50aWNhdG9yIGEgPSBtaC5nZXRBdXRoZW50aWNhdG9yKCk7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgbWguc2V0QXV0aGVudGljYXRvcihhKTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCgiTXV0YWJsZSBBdXRoZW50aWNhdG9yLiIpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBwYXNzKSB7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIFQpIHsKKyAgICAgICAgICAgICAgICAgICAgZmFpbChULnRvU3RyaW5nKCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0SGVhZChoKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGZvcm1hdChMb2dSZWNvcmQgcikgeworICAgICAgICAgICAgICAgIHJldHVybiAiIjsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFRhaWwoSGFuZGxlciBoKSB7CisgICAgICAgICAgICAgICAgZ2V0SGVhZChoKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gIm5hbWUudHh0IjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgICAgICBpbnN0YW5jZS5zZXRBdHRhY2htZW50Rm9ybWF0dGVycygKKyAgICAgICAgICAgICAgICBuZXcgRm9ybWF0dGVyW117cHVzaCwgYXRGb3IsIGF0TmFtZSwgYXRGaWx0ZXJ9KTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0QXR0YWNobWVudE5hbWVzKAorICAgICAgICAgICAgICAgIG5ldyBGb3JtYXR0ZXJbXXtuYW1lQ29tcCwgbmFtZU1haWwsIG5hbWVTdWIsIG5hbWVBdXRofSk7CisKKyAgICAgICAgU3RyaW5nIFNPVVJDRV9DTEFTUyA9IE1haWxIYW5kbGVyVGVzdC5jbGFzcy5nZXROYW1lKCk7CisgICAgICAgIFN0cmluZyBTT1VSQ0VfTUVUSE9EID0gInRlc3RQdXNoSW5zaWRlUHVzaCI7CisgICAgICAgIGZvciAoTGV2ZWwgbHZsIDogbHZscykgeworICAgICAgICAgICAgTG9nUmVjb3JkIHIgPSBuZXcgTG9nUmVjb3JkKGx2bCwgIiIpOworICAgICAgICAgICAgci5zZXRTb3VyY2VDbGFzc05hbWUoU09VUkNFX0NMQVNTKTsKKyAgICAgICAgICAgIHIuc2V0U291cmNlTWV0aG9kTmFtZShTT1VSQ0VfTUVUSE9EKTsKKyAgICAgICAgICAgIGluc3RhbmNlLnB1Ymxpc2gocik7CisgICAgICAgIH0KKyAgICAgICAgaW5zdGFuY2UuZmx1c2goKTsKKworICAgICAgICBmb3IgKEV4Y2VwdGlvbiBleGNlcHRpb24gOiBlbS5leGNlcHRpb25zKSB7CisgICAgICAgICAgICBUaHJvd2FibGUgdCA9IGV4Y2VwdGlvbjsKKyAgICAgICAgICAgIGlmICgodCBpbnN0YW5jZW9mIE1lc3NhZ2luZ0V4Y2VwdGlvbiA9PSBmYWxzZSkKKyAgICAgICAgICAgICAgICAgICAgJiYgKHQgaW5zdGFuY2VvZiBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gPT0gZmFsc2UpKSB7CisgICAgICAgICAgICAgICAgZHVtcCh0KTsKKyAgICAgICAgICAgICAgICBmYWlsKFN0cmluZy52YWx1ZU9mKHQpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBhc3NlcnRGYWxzZShlbS5leGNlcHRpb25zLmlzRW1wdHkoKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHVzaCgpIHsKKyAgICAgICAgTWFpbEhhbmRsZXIgaW5zdGFuY2UgPSBuZXcgTWFpbEhhbmRsZXIoY3JlYXRlSW5pdFByb3BlcnRpZXMoIiIpKTsKKyAgICAgICAgSW50ZXJuYWxFcnJvck1hbmFnZXIgZW0gPSBuZXcgSW50ZXJuYWxFcnJvck1hbmFnZXIoKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0RXJyb3JNYW5hZ2VyKGVtKTsKKyAgICAgICAgaW5zdGFuY2UucHVzaCgpOworICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgZW0uZXhjZXB0aW9ucy5pc0VtcHR5KCkpOworICAgICAgICBpbnN0YW5jZS5jbG9zZSgpOworCisgICAgICAgIGluc3RhbmNlID0gY3JlYXRlSGFuZGxlcldpdGhSZWNvcmRzKCk7CisgICAgICAgIGVtID0gaW50ZXJuYWxFcnJvck1hbmFnZXJGcm9tKGluc3RhbmNlKTsKKyAgICAgICAgaW5zdGFuY2UucHVzaCgpOworCisgICAgICAgIGFzc2VydEVxdWFscygxLCBlbS5leGNlcHRpb25zLnNpemUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyh0cnVlLCBlbS5leGNlcHRpb25zLmdldCgwKSBpbnN0YW5jZW9mIE1lc3NhZ2luZ0V4Y2VwdGlvbik7CisgICAgICAgIGluc3RhbmNlLmNsb3NlKCk7CisKKyAgICAgICAgLy9UZXN0IGZvciB2YWxpZCBtZXNzYWdlLgorICAgICAgICBpbnN0YW5jZSA9IGNyZWF0ZUhhbmRsZXJXaXRoUmVjb3JkcygpOworICAgICAgICBpbnN0YW5jZS5zZXRFcnJvck1hbmFnZXIobmV3IFB1c2hFcnJvck1hbmFnZXIoaW5zdGFuY2UpKTsKKyAgICAgICAgaW5zdGFuY2UucHVzaCgpOworICAgICAgICBpbnN0YW5jZS5jbG9zZSgpOworCisgICAgICAgIGluc3RhbmNlID0gbmV3IE1haWxIYW5kbGVyKDEpOworICAgICAgICBpbnN0YW5jZS5zZXRNYWlsUHJvcGVydGllcyhjcmVhdGVJbml0UHJvcGVydGllcygiIikpOworICAgICAgICBpbnN0YW5jZS5zZXRMZXZlbChMZXZlbC5BTEwpOworICAgICAgICBpbnN0YW5jZS5zZXRFcnJvck1hbmFnZXIobmV3IFB1c2hFcnJvck1hbmFnZXIoaW5zdGFuY2UpKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0UHVzaEZpbHRlcigoRmlsdGVyKSBudWxsKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0UHVzaExldmVsKExldmVsLklORk8pOworICAgICAgICBMb2dSZWNvcmQgcmVjb3JkID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICIiKTsKKyAgICAgICAgaW5zdGFuY2UucHVibGlzaChyZWNvcmQpOyAvL3Nob3VsZCBwdXNoLgorICAgICAgICBpbnN0YW5jZS5jbG9zZSgpOyAvL2NhdXNlIGEgZmx1c2ggaWYgcHVibGlzaCBkaWRuJ3QgcHVzaC4KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RGbHVzaCgpIHsKKyAgICAgICAgTWFpbEhhbmRsZXIgaW5zdGFuY2UgPSBuZXcgTWFpbEhhbmRsZXIoY3JlYXRlSW5pdFByb3BlcnRpZXMoIiIpKTsKKyAgICAgICAgSW50ZXJuYWxFcnJvck1hbmFnZXIgZW0gPSBuZXcgSW50ZXJuYWxFcnJvck1hbmFnZXIoKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0RXJyb3JNYW5hZ2VyKGVtKTsKKyAgICAgICAgaW5zdGFuY2UuZmx1c2goKTsKKworICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgZW0uZXhjZXB0aW9ucy5pc0VtcHR5KCkpOworICAgICAgICBpbnN0YW5jZS5jbG9zZSgpOworCisgICAgICAgIGluc3RhbmNlID0gY3JlYXRlSGFuZGxlcldpdGhSZWNvcmRzKCk7CisgICAgICAgIGVtID0gaW50ZXJuYWxFcnJvck1hbmFnZXJGcm9tKGluc3RhbmNlKTsKKyAgICAgICAgaW5zdGFuY2UuZmx1c2goKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgZW0uZXhjZXB0aW9ucy5zaXplKCkpOworICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgZW0uZXhjZXB0aW9ucy5nZXQoMCkgaW5zdGFuY2VvZiBNZXNzYWdpbmdFeGNlcHRpb24pOworICAgICAgICBpbnN0YW5jZS5jbG9zZSgpOworCisgICAgICAgIC8vVGVzdCBmb3IgdmFsaWQgbWVzc2FnZS4KKyAgICAgICAgaW5zdGFuY2UgPSBjcmVhdGVIYW5kbGVyV2l0aFJlY29yZHMoKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0RXJyb3JNYW5hZ2VyKG5ldyBGbHVzaEVycm9yTWFuYWdlcihpbnN0YW5jZSkpOworICAgICAgICBpbnN0YW5jZS5mbHVzaCgpOworICAgICAgICBpbnN0YW5jZS5jbG9zZSgpOworCisgICAgICAgIGluc3RhbmNlID0gbmV3IE1haWxIYW5kbGVyKDEpOworICAgICAgICBpbnN0YW5jZS5zZXRNYWlsUHJvcGVydGllcyhjcmVhdGVJbml0UHJvcGVydGllcygiIikpOworICAgICAgICBpbnN0YW5jZS5zZXRMZXZlbChMZXZlbC5BTEwpOworICAgICAgICBpbnN0YW5jZS5zZXRFcnJvck1hbmFnZXIobmV3IEZsdXNoRXJyb3JNYW5hZ2VyKGluc3RhbmNlKSk7CisgICAgICAgIGluc3RhbmNlLnNldFB1c2hGaWx0ZXIoKEZpbHRlcikgbnVsbCk7CisgICAgICAgIGluc3RhbmNlLnNldFB1c2hMZXZlbChMZXZlbC5TRVZFUkUpOworICAgICAgICBMb2dSZWNvcmQgcmVjb3JkID0gbmV3IExvZ1JlY29yZChMZXZlbC5JTkZPLCAiIik7CisgICAgICAgIGluc3RhbmNlLnB1Ymxpc2gocmVjb3JkKTsgLy9zaG91bGQgZmx1c2guCisgICAgICAgIGluc3RhbmNlLnB1c2goKTsgLy9tYWtlIEZsdXNoRXJyb3JNYW5hZ2VyIGZhaWwgaWYgaGFuZGxlciBkaWRuJ3QgZmx1c2guCisgICAgICAgIGluc3RhbmNlLmNsb3NlKCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rmx1c2hMaW5rYWdlRXJyb3IoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdExpbmthZ2VFcnJvcldpdGhTdGFjaygiZmx1c2giKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RGbHVzaExpbmthZ2VFcnJvckVtcHR5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRlc3RMaW5rYWdlRXJyb3JFbXB0eVN0YWNrKCJmbHVzaCIpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENsb3NlKCkgeworICAgICAgICBMb2dSZWNvcmQgcmVjb3JkID0gbmV3IExvZ1JlY29yZChMZXZlbC5JTkZPLCAiIik7CisgICAgICAgIE1haWxIYW5kbGVyIGluc3RhbmNlID0gbmV3IE1haWxIYW5kbGVyKGNyZWF0ZUluaXRQcm9wZXJ0aWVzKCIiKSk7CisgICAgICAgIEludGVybmFsRXJyb3JNYW5hZ2VyIGVtID0gbmV3IEludGVybmFsRXJyb3JNYW5hZ2VyKCk7CisgICAgICAgIGluc3RhbmNlLnNldEVycm9yTWFuYWdlcihlbSk7CisgICAgICAgIGludCBjYXBhY2l0eSA9IGluc3RhbmNlLmdldENhcGFjaXR5KCk7CisKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChpbnN0YW5jZS5nZXRMZXZlbCgpKTsKKworICAgICAgICBpbnN0YW5jZS5zZXRMZXZlbChMZXZlbC5BTEwpOworICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgaW5zdGFuY2UuaXNMb2dnYWJsZShyZWNvcmQpKTsKKworICAgICAgICBpbnN0YW5jZS5jbG9zZSgpOworCisgICAgICAgIGFzc2VydEVxdWFscyhmYWxzZSwgaW5zdGFuY2UuaXNMb2dnYWJsZShyZWNvcmQpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKExldmVsLk9GRiwgaW5zdGFuY2UuZ2V0TGV2ZWwoKSk7CisKKyAgICAgICAgaW5zdGFuY2Uuc2V0TGV2ZWwoTGV2ZWwuQUxMKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKExldmVsLk9GRiwgaW5zdGFuY2UuZ2V0TGV2ZWwoKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGNhcGFjaXR5LCBpbnN0YW5jZS5nZXRDYXBhY2l0eSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRydWUsIGVtLmV4Y2VwdGlvbnMuaXNFbXB0eSgpKTsKKworICAgICAgICBpbnN0YW5jZSA9IGNyZWF0ZUhhbmRsZXJXaXRoUmVjb3JkcygpOworICAgICAgICBlbSA9IGludGVybmFsRXJyb3JNYW5hZ2VyRnJvbShpbnN0YW5jZSk7CisgICAgICAgIGluc3RhbmNlLmNsb3NlKCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGVtLmV4Y2VwdGlvbnMuc2l6ZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRydWUsIGVtLmV4Y2VwdGlvbnMuZ2V0KDApIGluc3RhbmNlb2YgTWVzc2FnaW5nRXhjZXB0aW9uKTsKKworICAgICAgICAvL1Rlc3QgZm9yIHZhbGlkIG1lc3NhZ2UuCisgICAgICAgIGluc3RhbmNlID0gY3JlYXRlSGFuZGxlcldpdGhSZWNvcmRzKCk7CisgICAgICAgIGluc3RhbmNlLnNldEVycm9yTWFuYWdlcihuZXcgRmx1c2hFcnJvck1hbmFnZXIoaW5zdGFuY2UpKTsKKyAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RDbG9zZUxpbmthZ2VFcnJvcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0TGlua2FnZUVycm9yV2l0aFN0YWNrKCJjbG9zZSIpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENsb3NlTGlua2FnZUVycm9yRW1wdHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdExpbmthZ2VFcnJvckVtcHR5U3RhY2soImNsb3NlIik7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RMaW5rYWdlRXJyb3JXaXRoU3RhY2soU3RyaW5nIG1ldGhvZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgUHJpbnRTdHJlYW0gbHMgPSBuZXcgTGlua2FnZUVycm9yU3RyZWFtKCk7CisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJVc2VPZlN5c3RlbU91dE9yU3lzdGVtRXJyIikKKyAgICAgICAgZmluYWwgUHJpbnRTdHJlYW0gZXJyID0gU3lzdGVtLmVycjsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN5c3RlbS5zZXRFcnIobmV3IExpbmthZ2VFcnJvclN0cmVhbSgpKTsKKyAgICAgICAgICAgIGJvb2xlYW4gbGlua2FnZUVycm9yRXNjYXBlcyA9IGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBFcnJvck1hbmFnZXIgZW0gPSBuZXcgRXJyb3JNYW5hZ2VyKCk7CisgICAgICAgICAgICAgICAgZW0uZXJyb3IobnVsbCwgbnVsbCwgRXJyb3JNYW5hZ2VyLkdFTkVSSUNfRkFJTFVSRSk7CisgICAgICAgICAgICB9IGNhdGNoIChMaW5rYWdlRXJyb3IgZXhwZWN0KSB7CisgICAgICAgICAgICAgICAgbGlua2FnZUVycm9yRXNjYXBlcyA9IGV4cGVjdC5nZXRTdGFja1RyYWNlKCkubGVuZ3RoICE9IDA7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBBc3N1bWUuYXNzdW1lVHJ1ZShsaW5rYWdlRXJyb3JFc2NhcGVzKTsKKworICAgICAgICAgICAgU3lzdGVtLnNldEVycihscyk7CisgICAgICAgICAgICBNYWlsSGFuZGxlciBpbnN0YW5jZSA9IG5ldyBNYWlsSGFuZGxlcihjcmVhdGVJbml0UHJvcGVydGllcygiIikpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoRXJyb3JNYW5hZ2VyLmNsYXNzLAorICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2UuZ2V0RXJyb3JNYW5hZ2VyKCkuZ2V0Q2xhc3MoKSk7CisgICAgICAgICAgICAgICAgaW5zdGFuY2UucHVibGlzaChuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgIiIpKTsKKyAgICAgICAgICAgICAgICBpZiAoInByZURlc3Ryb3kiLmVxdWFscyhtZXRob2QpKSB7CisgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlLnByZURlc3Ryb3koKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCJwdWJsaXNoIi5lcXVhbHMobWV0aG9kKSkgeworICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZS5zZXRQdXNoTGV2ZWwoTGV2ZWwuQUxMKTsKKyAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2UucHVibGlzaChuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgIiIpKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCJwdWJsaXNoRHVyaW5nQ2xvc2UiLmVxdWFscyhtZXRob2QpKSB7CisgICAgICAgICAgICAgICAgICAgIENsb3NlTG9nUmVjb3JkIHIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IG5ldyBDbG9zZUxvZ1JlY29yZChMZXZlbC5TRVZFUkUsICIiLCBpbnN0YW5jZSk7CisgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlLnB1Ymxpc2gocik7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgiZmx1c2giLmVxdWFscyhtZXRob2QpKSB7CisgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlLmZsdXNoKCk7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgicHVzaCIuZXF1YWxzKG1ldGhvZCkpIHsKKyAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2UucHVzaCgpOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoImNsb3NlIi5lcXVhbHMobWV0aG9kKSkgeworICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZS5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGZhaWwobWV0aG9kKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShscy5jaGVja0Vycm9yKCkpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBpbnN0YW5jZS5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZShscy5jaGVja0Vycm9yKCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgU3lzdGVtLnNldEVycihlcnIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RMaW5rYWdlRXJyb3JFbXB0eVN0YWNrKFN0cmluZyBtZXRob2QpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFByaW50U3RyZWFtIGxzID0gbmV3IExpbmthZ2VFcnJvclN0cmVhbShuZXcgU3RhY2tUcmFjZUVsZW1lbnRbMF0pOworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygiVXNlT2ZTeXN0ZW1PdXRPclN5c3RlbUVyciIpCisgICAgICAgIGZpbmFsIFByaW50U3RyZWFtIGVyciA9IFN5c3RlbS5lcnI7CisgICAgICAgIGZpbmFsIFRocmVhZC5VbmNhdWdodEV4Y2VwdGlvbkhhbmRsZXIgdWVoCisgICAgICAgICAgICAgICAgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpLmdldFVuY2F1Z2h0RXhjZXB0aW9uSGFuZGxlcigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ291bnRpbmdVbmNhdWdodEV4Y2VwdGlvbkhhbmRsZXIgY3VlaAorICAgICAgICAgICAgICAgICAgICA9IG5ldyBDb3VudGluZ1VuY2F1Z2h0RXhjZXB0aW9uSGFuZGxlcigpOworICAgICAgICAgICAgU3lzdGVtLnNldEVycihuZXcgTGlua2FnZUVycm9yU3RyZWFtKG5ldyBTdGFja1RyYWNlRWxlbWVudFswXSkpOworICAgICAgICAgICAgVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5zZXRVbmNhdWdodEV4Y2VwdGlvbkhhbmRsZXIoY3VlaCk7CisgICAgICAgICAgICBib29sZWFuIGxpbmthZ2VFcnJvckVzY2FwZXMgPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgRXJyb3JNYW5hZ2VyIGVtID0gbmV3IEVycm9yTWFuYWdlcigpOworICAgICAgICAgICAgICAgIGVtLmVycm9yKG51bGwsIG51bGwsIEVycm9yTWFuYWdlci5HRU5FUklDX0ZBSUxVUkUpOworICAgICAgICAgICAgfSBjYXRjaCAoTGlua2FnZUVycm9yIGV4cGVjdCkgeworICAgICAgICAgICAgICAgIGxpbmthZ2VFcnJvckVzY2FwZXMgPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgQXNzdW1lLmFzc3VtZVRydWUobGlua2FnZUVycm9yRXNjYXBlcyk7CisKKyAgICAgICAgICAgIFN5c3RlbS5zZXRFcnIobHMpOworICAgICAgICAgICAgTWFpbEhhbmRsZXIgaW5zdGFuY2UgPSBuZXcgTWFpbEhhbmRsZXIoY3JlYXRlSW5pdFByb3BlcnRpZXMoIiIpKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKEVycm9yTWFuYWdlci5jbGFzcywKKyAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlLmdldEVycm9yTWFuYWdlcigpLmdldENsYXNzKCkpOworICAgICAgICAgICAgICAgIGluc3RhbmNlLnB1Ymxpc2gobmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICIiKSk7CisgICAgICAgICAgICAgICAgaWYgKCJwcmVEZXN0cm95Ii5lcXVhbHMobWV0aG9kKSkgeworICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZS5wcmVEZXN0cm95KCk7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgicHVibGlzaCIuZXF1YWxzKG1ldGhvZCkpIHsKKyAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2Uuc2V0UHVzaExldmVsKExldmVsLkFMTCk7CisgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlLnB1Ymxpc2gobmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICIiKSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgicHVibGlzaER1cmluZ0Nsb3NlIi5lcXVhbHMobWV0aG9kKSkgeworICAgICAgICAgICAgICAgICAgICBDbG9zZUxvZ1JlY29yZCByCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSBuZXcgQ2xvc2VMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAiIiwgaW5zdGFuY2UpOworICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZS5wdWJsaXNoKHIpOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoImZsdXNoIi5lcXVhbHMobWV0aG9kKSkgeworICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZS5mbHVzaCgpOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoInB1c2giLmVxdWFscyhtZXRob2QpKSB7CisgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlLnB1c2goKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCJjbG9zZSIuZXF1YWxzKG1ldGhvZCkpIHsKKyAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBmYWlsKG1ldGhvZCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGFzc2VydFRydWUobHMuY2hlY2tFcnJvcigpKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUobHMuY2hlY2tFcnJvcigpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBjdWVoLmNvdW50KTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIFN5c3RlbS5zZXRFcnIoZXJyKTsKKyAgICAgICAgICAgIFRocmVhZC5jdXJyZW50VGhyZWFkKCkuc2V0VW5jYXVnaHRFeGNlcHRpb25IYW5kbGVyKHVlaCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RDbG9zZUNvbnRleHRDbGFzc0xvYWRlcigpIHsKKyAgICAgICAgYXNzZXJ0TnVsbChTeXN0ZW0uZ2V0U2VjdXJpdHlNYW5hZ2VyKCkpOworICAgICAgICBmaW5hbCBUaHJlYWQgdGhyZWFkID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKTsKKyAgICAgICAgZmluYWwgQ2xhc3NMb2FkZXIgY2NsID0gdGhyZWFkLmdldENvbnRleHRDbGFzc0xvYWRlcigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGVzdENsb3NlQ29udGV4dENsYXNzTG9hZGVyMCgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgdGhyZWFkLnNldENvbnRleHRDbGFzc0xvYWRlcihjY2wpOworICAgICAgICB9CisgICAgICAgIGFzc2VydE51bGwoU3lzdGVtLmdldFNlY3VyaXR5TWFuYWdlcigpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdENsb3NlQ29udGV4dENsYXNzTG9hZGVyMCgpIHsKKworICAgICAgICBJbnRlcm5hbEVycm9yTWFuYWdlciBlbSA9IG5ldyBBY3RpdmF0aW9uRXJyb3JNYW5hZ2VyKCk7CisgICAgICAgIE1haWxIYW5kbGVyIGluc3RhbmNlID0gY3JlYXRlSGFuZGxlcldpdGhSZWNvcmRzKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnN0YW5jZS5zZXRFcnJvck1hbmFnZXIoZW0pOworICAgICAgICAgICAgQ2xhc3NMb2FkZXIgZXhwZWN0ID0gaW5zdGFuY2UuZ2V0Q2xhc3MoKS5nZXRDbGFzc0xvYWRlcigpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChleHBlY3QpOworICAgICAgICAgICAgaW5zdGFuY2Uuc2V0QXV0aGVudGljYXRvcihuZXcgQ2xhc3NMb2FkZXJBdXRoZW50aWNhdG9yKGV4cGVjdCkpOworCisgICAgICAgICAgICAvKioKKyAgICAgICAgICAgICAqIGphdmEudXRpbC5sb2dnaW5nLkxvZ01hbmFnZXIkQ2xlYW5lciBoYXMgYSBudWxsIENDTC4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5zZXRDb250ZXh0Q2xhc3NMb2FkZXIobnVsbCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpbnN0YW5jZS5jbG9zZSgpOworICAgICAgICB9CisKKyAgICAgICAgZm9yIChFeGNlcHRpb24gZXhjZXB0aW9uIDogZW0uZXhjZXB0aW9ucykgeworICAgICAgICAgICAgVGhyb3dhYmxlIHQgPSBleGNlcHRpb247CisgICAgICAgICAgICBpZiAoIWlzQ29ubmVjdE9yVGltZW91dCh0KSkgeworICAgICAgICAgICAgICAgIGR1bXAodCk7CisgICAgICAgICAgICAgICAgZmFpbCh0LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TGV2ZWwoKSB7CisgICAgICAgIE1haWxIYW5kbGVyIGluc3RhbmNlID0gbmV3IE1haWxIYW5kbGVyKGNyZWF0ZUluaXRQcm9wZXJ0aWVzKCIiKSk7CisgICAgICAgIEludGVybmFsRXJyb3JNYW5hZ2VyIGVtID0gbmV3IEludGVybmFsRXJyb3JNYW5hZ2VyKCk7CisgICAgICAgIGluc3RhbmNlLnNldEVycm9yTWFuYWdlcihlbSk7CisKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChpbnN0YW5jZS5nZXRMZXZlbCgpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGluc3RhbmNlLnNldExldmVsKChMZXZlbCkgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsIGxldmVsIHdhcyBhbGxvd2VkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIHBhc3MpIHsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoaW5zdGFuY2UpOworICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHJlKSB7CisgICAgICAgICAgICBmYWlsKHJlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydE5vdE51bGwoaW5zdGFuY2UuZ2V0TGV2ZWwoKSk7CisKKyAgICAgICAgZmluYWwgTGV2ZWxbXSBsdmxzID0gZ2V0QWxsTGV2ZWxzKCk7CisgICAgICAgIGZvciAoTGV2ZWwgbHZsIDogbHZscykgeworICAgICAgICAgICAgaW5zdGFuY2Uuc2V0TGV2ZWwobHZsKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhpbnN0YW5jZS5nZXRMZXZlbCgpLCBsdmwpOworICAgICAgICB9CisKKyAgICAgICAgaW5zdGFuY2Uuc2V0TGV2ZWwoTGV2ZWwuV0FSTklORyk7CisgICAgICAgIGluc3RhbmNlLmNsb3NlKCk7CisgICAgICAgIGFzc2VydEVxdWFscyhMZXZlbC5PRkYsIGluc3RhbmNlLmdldExldmVsKCkpOworICAgICAgICBmb3IgKExldmVsIGx2bCA6IGx2bHMpIHsKKyAgICAgICAgICAgIGluc3RhbmNlLnNldExldmVsKGx2bCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoTGV2ZWwuT0ZGLCBpbnN0YW5jZS5nZXRMZXZlbCgpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgZW0uZXhjZXB0aW9ucy5pc0VtcHR5KCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdExldmVsQmVmb3JlQ2xvc2UoKSB7CisgICAgICAgIE1haWxIYW5kbGVyIGluc3RhbmNlID0gdGhpcy5jcmVhdGVIYW5kbGVyV2l0aFJlY29yZHMoKTsKKyAgICAgICAgSW50ZXJuYWxFcnJvck1hbmFnZXIgZW0gPSBuZXcgSW50ZXJuYWxFcnJvck1hbmFnZXIoKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0RXJyb3JNYW5hZ2VyKGVtKTsKKworICAgICAgICBmaW5hbCBMZXZlbCBleHBlY3QgPSBMZXZlbC5XQVJOSU5HOworICAgICAgICBpbnN0YW5jZS5zZXRMZXZlbChleHBlY3QpOworCisgICAgICAgIGluc3RhbmNlLnNldEZvcm1hdHRlcihuZXcgTGV2ZWxDaGVja2luZ0Zvcm1hdHRlcihleHBlY3QpKTsKKyAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKworICAgICAgICBmb3IgKEV4Y2VwdGlvbiBleGNlcHRpb24gOiBlbS5leGNlcHRpb25zKSB7CisgICAgICAgICAgICBUaHJvd2FibGUgdCA9IGV4Y2VwdGlvbjsKKyAgICAgICAgICAgIGlmICh0IGluc3RhbmNlb2YgTWVzc2FnaW5nRXhjZXB0aW9uKSB7CisgICAgICAgICAgICAgICAgaWYgKCFpc0Nvbm5lY3RPclRpbWVvdXQodCkpIHsKKyAgICAgICAgICAgICAgICAgICAgZHVtcCh0KTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCh0LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZHVtcCh0KTsKKyAgICAgICAgICAgICAgICBmYWlsKHQudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RmFsc2UoZW0uZXhjZXB0aW9ucy5pc0VtcHR5KCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdExldmVsQWZ0ZXJDbG9zZSgpIHsKKyAgICAgICAgTWFpbEhhbmRsZXIgaW5zdGFuY2UgPSBuZXcgTWFpbEhhbmRsZXIoY3JlYXRlSW5pdFByb3BlcnRpZXMoIiIpKTsKKyAgICAgICAgSW50ZXJuYWxFcnJvck1hbmFnZXIgZW0gPSBuZXcgSW50ZXJuYWxFcnJvck1hbmFnZXIoKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0RXJyb3JNYW5hZ2VyKGVtKTsKKworICAgICAgICBpbnN0YW5jZS5zZXRMZXZlbChMZXZlbC5XQVJOSU5HKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0Rm9ybWF0dGVyKG5ldyBMZXZlbENoZWNraW5nRm9ybWF0dGVyKExldmVsLk9GRikpOworICAgICAgICBpbnN0YW5jZS5wdWJsaXNoKG5ldyBDbG9zZUxvZ1JlY29yZChMZXZlbC5TRVZFUkUsICIiLCBpbnN0YW5jZSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoTGV2ZWwuT0ZGLCBpbnN0YW5jZS5nZXRMZXZlbCgpKTsKKworICAgICAgICBpbnN0YW5jZS5jbG9zZSgpOworICAgICAgICBmb3IgKEV4Y2VwdGlvbiBleGNlcHRpb24gOiBlbS5leGNlcHRpb25zKSB7CisgICAgICAgICAgICBUaHJvd2FibGUgdCA9IGV4Y2VwdGlvbjsKKyAgICAgICAgICAgIGlmICh0IGluc3RhbmNlb2YgTWVzc2FnaW5nRXhjZXB0aW9uKSB7CisgICAgICAgICAgICAgICAgaWYgKCFpc0Nvbm5lY3RPclRpbWVvdXQodCkpIHsKKyAgICAgICAgICAgICAgICAgICAgZHVtcCh0KTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCh0LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZHVtcCh0KTsKKyAgICAgICAgICAgICAgICBmYWlsKHQudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RmFsc2UoZW0uZXhjZXB0aW9ucy5pc0VtcHR5KCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdExvZ01hbmFnZXJSZXNldCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIExvZ01hbmFnZXIgbWFuYWdlciA9IExvZ01hbmFnZXIuZ2V0TG9nTWFuYWdlcigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKExvZ01hbmFnZXIuY2xhc3MsIG1hbmFnZXIuZ2V0Q2xhc3MoKSk7CisgICAgICAgICAgICBNYWlsSGFuZGxlciBpbnN0YW5jZSA9IHN0YXJ0TG9nTWFuYWdlclJlc2V0KCJyZW1vdGUiKTsKKyAgICAgICAgICAgIEludGVybmFsRXJyb3JNYW5hZ2VyIGVtID0gaW50ZXJuYWxFcnJvck1hbmFnZXJGcm9tKGluc3RhbmNlKTsKKworICAgICAgICAgICAgbWFuYWdlci5yZXNldCgpOworCisgICAgICAgICAgICBmb3IgKEV4Y2VwdGlvbiBleGNlcHRpb24gOiBlbS5leGNlcHRpb25zKSB7CisgICAgICAgICAgICAgICAgVGhyb3dhYmxlIHQgPSBleGNlcHRpb247CisgICAgICAgICAgICAgICAgaWYgKHQgaW5zdGFuY2VvZiBNZXNzYWdpbmdFeGNlcHRpb24pIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGlzTm9SZWNpcGllbnRBZGRyZXNzKHQpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpZiAoIWlzQ29ubmVjdE9yVGltZW91dCh0KSkgeworICAgICAgICAgICAgICAgICAgICAgICAgZHVtcCh0KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZhaWwodC50b1N0cmluZygpKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGR1bXAodCk7CisgICAgICAgICAgICAgICAgICAgIGZhaWwodC50b1N0cmluZygpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGluc3RhbmNlID0gc3RhcnRMb2dNYW5hZ2VyUmVzZXQoImxvY2FsIik7CisgICAgICAgICAgICBlbSA9IGludGVybmFsRXJyb3JNYW5hZ2VyRnJvbShpbnN0YW5jZSk7CisKKyAgICAgICAgICAgIGZvciAoRXhjZXB0aW9uIGV4Y2VwdGlvbiA6IGVtLmV4Y2VwdGlvbnMpIHsKKyAgICAgICAgICAgICAgICBUaHJvd2FibGUgdCA9IGV4Y2VwdGlvbjsKKyAgICAgICAgICAgICAgICBpZiAodCBpbnN0YW5jZW9mIE1lc3NhZ2luZ0V4Y2VwdGlvbikgeworICAgICAgICAgICAgICAgICAgICBpZiAoaXNOb1JlY2lwaWVudEFkZHJlc3ModCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGlmICghaXNDb25uZWN0T3JUaW1lb3V0KHQpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBkdW1wKHQpOworICAgICAgICAgICAgICAgICAgICAgICAgZmFpbCh0LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgZHVtcCh0KTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCh0LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgbWFuYWdlci5yZXNldCgpOworCisgICAgICAgICAgICBmb3IgKEV4Y2VwdGlvbiBleGNlcHRpb24gOiBlbS5leGNlcHRpb25zKSB7CisgICAgICAgICAgICAgICAgVGhyb3dhYmxlIHQgPSBleGNlcHRpb247CisgICAgICAgICAgICAgICAgaWYgKHQgaW5zdGFuY2VvZiBNZXNzYWdpbmdFeGNlcHRpb24pIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGlzTm9SZWNpcGllbnRBZGRyZXNzKHQpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpZiAoIWlzQ29ubmVjdE9yVGltZW91dCh0KSkgeworICAgICAgICAgICAgICAgICAgICAgICAgZHVtcCh0KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZhaWwodC50b1N0cmluZygpKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGR1bXAodCk7CisgICAgICAgICAgICAgICAgICAgIGZhaWwodC50b1N0cmluZygpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIFN0cmluZ1tdIG5vVmVyaWZ5ID0gbmV3IFN0cmluZ1tde251bGwsICIiLCAibnVsbCJ9OworICAgICAgICAgICAgZm9yIChpbnQgdiA9IDA7IHYgPCBub1ZlcmlmeS5sZW5ndGg7IHYrKykgeworICAgICAgICAgICAgICAgIGluc3RhbmNlID0gc3RhcnRMb2dNYW5hZ2VyUmVzZXQobm9WZXJpZnlbdl0pOworICAgICAgICAgICAgICAgIGVtID0gaW50ZXJuYWxFcnJvck1hbmFnZXJGcm9tKGluc3RhbmNlKTsKKworICAgICAgICAgICAgICAgIGZvciAoRXhjZXB0aW9uIGV4Y2VwdGlvbiA6IGVtLmV4Y2VwdGlvbnMpIHsKKyAgICAgICAgICAgICAgICAgICAgVGhyb3dhYmxlIHQgPSBleGNlcHRpb247CisgICAgICAgICAgICAgICAgICAgIGR1bXAodCk7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoIlZlcmlmeSBpbmRleD0iICsgdik7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgbWFuYWdlci5yZXNldCgpOworCisgICAgICAgICAgICAgICAgLy9ObyB2ZXJpZnkgcmVzdWx0cyBpbiBmYWlsZWQgc2VuZC4KKyAgICAgICAgICAgICAgICBmb3IgKEV4Y2VwdGlvbiBleGNlcHRpb24gOiBlbS5leGNlcHRpb25zKSB7CisgICAgICAgICAgICAgICAgICAgIFRocm93YWJsZSB0ID0gZXhjZXB0aW9uOworICAgICAgICAgICAgICAgICAgICBpZiAodCBpbnN0YW5jZW9mIE1lc3NhZ2luZ0V4Y2VwdGlvbikgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzTm9SZWNpcGllbnRBZGRyZXNzKHQpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWlzQ29ubmVjdE9yVGltZW91dCh0KSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR1bXAodCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFpbCgiVmVyaWZ5IGluZGV4PSIgKyB2KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGR1bXAodCk7CisgICAgICAgICAgICAgICAgICAgICAgICBmYWlsKCJWZXJpZnkgaW5kZXg9IiArIHYpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpbnN0YW5jZSA9IHN0YXJ0TG9nTWFuYWdlclJlc2V0KCJiYWQtZW51bS1uYW1lIik7CisgICAgICAgICAgICBlbSA9IGludGVybmFsRXJyb3JNYW5hZ2VyRnJvbShpbnN0YW5jZSk7CisKKyAgICAgICAgICAgIG1hbmFnZXIucmVzZXQoKTsKKworICAgICAgICAgICAgLy9BbGxvdyB0aGUgTG9nTWFuYWdlclByb3BlcnRpZXMgdG8gY29weSBvbiBhIGJhZCBlbnVtIHR5cGUuCisgICAgICAgICAgICBib29sZWFuIGZvdW5kSWxsZWdhbEFyZyA9IGZhbHNlOworICAgICAgICAgICAgZm9yIChFeGNlcHRpb24gZXhjZXB0aW9uIDogZW0uZXhjZXB0aW9ucykgeworICAgICAgICAgICAgICAgIFRocm93YWJsZSB0ID0gZXhjZXB0aW9uOworICAgICAgICAgICAgICAgIGlmICh0IGluc3RhbmNlb2YgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKSB7CisgICAgICAgICAgICAgICAgICAgIGZvdW5kSWxsZWdhbEFyZyA9IHRydWU7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0IGluc3RhbmNlb2YgUnVudGltZUV4Y2VwdGlvbikgeworICAgICAgICAgICAgICAgICAgICBkdW1wKHQpOworICAgICAgICAgICAgICAgICAgICBmYWlsKHQudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBhc3NlcnRUcnVlKGZvdW5kSWxsZWdhbEFyZyk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShlbS5leGNlcHRpb25zLmlzRW1wdHkoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBoYXJkUmVmID0gbnVsbDsKKyAgICAgICAgICAgIG1hbmFnZXIucmVzZXQoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFNldHVwIGFuZCBsb2FkIHRoZSBzdGFuZGFyZCBwcm9wZXJ0aWVzLgorICAgICAqCisgICAgICogQHBhcmFtIHZlcmlmeSB0aGUgdmFsdWUgb2YgdmVyaWZ5IGVudW0uCisgICAgICogQHJldHVybiBhIE1haWxIYW5kbGVyCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiB0aGVyZSBpcyBhIHByb2JsZW0uCisgICAgICovCisgICAgcHJpdmF0ZSBNYWlsSGFuZGxlciBzdGFydExvZ01hbmFnZXJSZXNldChTdHJpbmcgdmVyaWZ5KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBMb2dNYW5hZ2VyIG1hbmFnZXIgPSBMb2dNYW5hZ2VyLmdldExvZ01hbmFnZXIoKTsKKyAgICAgICAgbWFuYWdlci5yZXNldCgpOworCisgICAgICAgIGZpbmFsIFN0cmluZyBwID0gTWFpbEhhbmRsZXIuY2xhc3MuZ2V0TmFtZSgpOworICAgICAgICBQcm9wZXJ0aWVzIHByb3BzID0gY3JlYXRlSW5pdFByb3BlcnRpZXMocCk7CisgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLm1haWwuZnJvbSIpLCAibG9jYWxob3N0QGxvY2FsZG9tYWluIik7CisgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLm1haWwudG8iKSwgIiIpOworICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5tYWlsLmNjIiksICIiKTsKKyAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIubWFpbC5iY2MiKSwgIiIpOworICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5zdWJqZWN0IiksIHAuY29uY2F0KCIgdGVzdCIpKTsKKyAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIuZXJyb3JNYW5hZ2VyIiksIEludGVybmFsRXJyb3JNYW5hZ2VyLmNsYXNzLmdldE5hbWUoKSk7CisgICAgICAgIGlmICh2ZXJpZnkgIT0gbnVsbCkgeworICAgICAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIudmVyaWZ5IiksIHZlcmlmeSk7CisgICAgICAgIH0KKyAgICAgICAgcmVhZChtYW5hZ2VyLCBwcm9wcyk7CisKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChtYW5hZ2VyLmdldFByb3BlcnR5KHAuY29uY2F0KCIubWFpbC5ob3N0IikpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChtYW5hZ2VyLmdldFByb3BlcnR5KHAuY29uY2F0KCIubWFpbC5zbXRwLmhvc3QiKSkpOworICAgICAgICBhc3NlcnROb3ROdWxsKG1hbmFnZXIuZ2V0UHJvcGVydHkocC5jb25jYXQoIi5tYWlsLnNtdHAucG9ydCIpKSk7CisgICAgICAgIGFzc2VydE5vdE51bGwobWFuYWdlci5nZXRQcm9wZXJ0eShwLmNvbmNhdCgiLm1haWwudG8iKSkpOworICAgICAgICBhc3NlcnROb3ROdWxsKG1hbmFnZXIuZ2V0UHJvcGVydHkocC5jb25jYXQoIi5tYWlsLmNjIikpKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChtYW5hZ2VyLmdldFByb3BlcnR5KHAuY29uY2F0KCIuc3ViamVjdCIpKSk7CisgICAgICAgIGFzc2VydE5vdE51bGwobWFuYWdlci5nZXRQcm9wZXJ0eShwLmNvbmNhdCgiLm1haWwuZnJvbSIpKSk7CisgICAgICAgIGFzc2VydEVxdWFscyh2ZXJpZnksIG1hbmFnZXIuZ2V0UHJvcGVydHkocC5jb25jYXQoIi52ZXJpZnkiKSkpOworICAgICAgICBhc3NlcnROb3ROdWxsKG1hbmFnZXIuZ2V0UHJvcGVydHkocC5jb25jYXQoIi5tYWlsLnNtdHAuY29ubmVjdGlvbnRpbWVvdXQiKSkpOworICAgICAgICBhc3NlcnROb3ROdWxsKG1hbmFnZXIuZ2V0UHJvcGVydHkocC5jb25jYXQoIi5tYWlsLnNtdHAudGltZW91dCIpKSk7CisKKyAgICAgICAgTWFpbEhhbmRsZXIgaW5zdGFuY2UgPSBuZXcgTWFpbEhhbmRsZXIoMTApOworICAgICAgICBpbnN0YW5jZS5zZXRMZXZlbChMZXZlbC5BTEwpOworCisgICAgICAgIC8vRG9uJ3QgYXV0byBjb21wdXRlIGEgZGVmYXVsdCByZWNpcGllbnQuCisgICAgICAgIFByb3BlcnRpZXMgYnVnNzA5Mjk4MSA9IGNyZWF0ZUluaXRQcm9wZXJ0aWVzKCIiKTsKKyAgICAgICAgYnVnNzA5Mjk4MS5zZXRQcm9wZXJ0eSgibWFpbC50byIsICIiKTsKKyAgICAgICAgYnVnNzA5Mjk4MS5zZXRQcm9wZXJ0eSgibWFpbC5jYyIsICIiKTsKKyAgICAgICAgYnVnNzA5Mjk4MS5zZXRQcm9wZXJ0eSgibWFpbC5iY2MiLCAiIik7CisgICAgICAgIGluc3RhbmNlLnNldE1haWxQcm9wZXJ0aWVzKGJ1ZzcwOTI5ODEpOworCisgICAgICAgIGFzc2VydEVxdWFscyhJbnRlcm5hbEVycm9yTWFuYWdlci5jbGFzcywgaW5zdGFuY2UuZ2V0RXJyb3JNYW5hZ2VyKCkuZ2V0Q2xhc3MoKSk7CisKKyAgICAgICAgZmluYWwgU3RyaW5nIENMQVNTX05BTUUgPSBNYWlsSGFuZGxlclRlc3QuY2xhc3MuZ2V0TmFtZSgpOworICAgICAgICBMb2dnZXIgbG9nZ2VyID0gTG9nZ2VyLmdldExvZ2dlcihDTEFTU19OQU1FKTsKKyAgICAgICAgaGFyZFJlZiA9IGxvZ2dlcjsKKyAgICAgICAgbG9nZ2VyLnNldFVzZVBhcmVudEhhbmRsZXJzKGZhbHNlKTsKKyAgICAgICAgbG9nZ2VyLmFkZEhhbmRsZXIoaW5zdGFuY2UpOworCisgICAgICAgIGxvZ2dlci5sb2coTGV2ZWwuU0VWRVJFLCAiVmVyaWZ5IGlzIHswfS4iLCB2ZXJpZnkpOworICAgICAgICBsb2dnZXIubG9nKExldmVsLlNFVkVSRSwgIlZlcmlmeSBpcyB7MH0uIiwgdmVyaWZ5KTsKKyAgICAgICAgcmV0dXJuIGluc3RhbmNlOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFB1c2hMZXZlbCgpIHsKKyAgICAgICAgTWFpbEhhbmRsZXIgaW5zdGFuY2UgPSBuZXcgTWFpbEhhbmRsZXIoY3JlYXRlSW5pdFByb3BlcnRpZXMoIiIpKTsKKyAgICAgICAgSW50ZXJuYWxFcnJvck1hbmFnZXIgZW0gPSBuZXcgSW50ZXJuYWxFcnJvck1hbmFnZXIoKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0RXJyb3JNYW5hZ2VyKGVtKTsKKworICAgICAgICBhc3NlcnROb3ROdWxsKGluc3RhbmNlLmdldFB1c2hMZXZlbCgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW5zdGFuY2Uuc2V0UHVzaExldmVsKChMZXZlbCkgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsIGxldmVsIHdhcyBhbGxvd2VkIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIHBhc3MpIHsKKyAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiByZSkgeworICAgICAgICAgICAgZmFpbChyZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorCisgICAgICAgIGZpbmFsIExldmVsW10gbHZscyA9IGdldEFsbExldmVscygpOworICAgICAgICBmb3IgKExldmVsIGx2bCA6IGx2bHMpIHsKKyAgICAgICAgICAgIGluc3RhbmNlLnNldFB1c2hMZXZlbChsdmwpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGluc3RhbmNlLmdldFB1c2hMZXZlbCgpLCBsdmwpOworICAgICAgICB9CisKKyAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKyAgICAgICAgZm9yIChMZXZlbCBsdmwgOiBsdmxzKSB7CisgICAgICAgICAgICBpbnN0YW5jZS5zZXRQdXNoTGV2ZWwobHZsKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhpbnN0YW5jZS5nZXRQdXNoTGV2ZWwoKSwgbHZsKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgZW0uZXhjZXB0aW9ucy5pc0VtcHR5KCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFB1c2hMaW5rYWdlRXJyb3IoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdExpbmthZ2VFcnJvcldpdGhTdGFjaygicHVzaCIpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFB1c2hMaW5rYWdlRXJyb3JFbXB0eSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0TGlua2FnZUVycm9yRW1wdHlTdGFjaygicHVzaCIpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFB1c2hGaWx0ZXIoKSB7CisgICAgICAgIE1haWxIYW5kbGVyIGluc3RhbmNlID0gbmV3IE1haWxIYW5kbGVyKGNyZWF0ZUluaXRQcm9wZXJ0aWVzKCIiKSk7CisgICAgICAgIEludGVybmFsRXJyb3JNYW5hZ2VyIGVtID0gbmV3IEludGVybmFsRXJyb3JNYW5hZ2VyKCk7CisgICAgICAgIGluc3RhbmNlLnNldEVycm9yTWFuYWdlcihlbSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGluc3RhbmNlLnNldFB1c2hGaWx0ZXIoKEZpbHRlcikgbnVsbCk7CisgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gUkUpIHsKKyAgICAgICAgICAgIGZhaWwoUkUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0TnVsbChpbnN0YW5jZS5nZXRQdXNoRmlsdGVyKCkpOworCisgICAgICAgIGluc3RhbmNlLnNldFB1c2hGaWx0ZXIoQm9vbGVhbkZpbHRlci5UUlVFKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEJvb2xlYW5GaWx0ZXIuVFJVRSwgaW5zdGFuY2UuZ2V0UHVzaEZpbHRlcigpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgZW0uZXhjZXB0aW9ucy5pc0VtcHR5KCkpOworCisgICAgICAgIGluc3RhbmNlID0gY3JlYXRlSGFuZGxlcldpdGhSZWNvcmRzKCk7CisgICAgICAgIGluc3RhbmNlLnNldEVycm9yTWFuYWdlcihuZXcgUHVzaEVycm9yTWFuYWdlcihpbnN0YW5jZSkpOworICAgICAgICBpbnN0YW5jZS5zZXRQdXNoRmlsdGVyKEJvb2xlYW5GaWx0ZXIuVFJVRSk7CisgICAgICAgIGluc3RhbmNlLnNldExldmVsKExldmVsLkFMTCk7CisgICAgICAgIGluc3RhbmNlLnNldFB1c2hMZXZlbChMZXZlbC5XQVJOSU5HKTsKKyAgICAgICAgaW5zdGFuY2UucHVibGlzaChuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgIiIpKTsKKyAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RDb250ZW50VHlwZU9mKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgTWFpbEhhbmRsZXIgaW5zdGFuY2UgPSBuZXcgTWFpbEhhbmRsZXIoY3JlYXRlSW5pdFByb3BlcnRpZXMoIiIpKTsKKyAgICAgICAgSW50ZXJuYWxFcnJvck1hbmFnZXIgZW0gPSBuZXcgSW50ZXJuYWxFcnJvck1hbmFnZXIoKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0RXJyb3JNYW5hZ2VyKGVtKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0RW5jb2RpbmcoKFN0cmluZykgbnVsbCk7CisgICAgICAgIFN0cmluZyBoZWFkID0gaW5zdGFuY2UuY29udGVudFR5cGVPZihuZXcgWE1MRm9ybWF0dGVyKCkuZ2V0SGVhZChpbnN0YW5jZSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImFwcGxpY2F0aW9uL3htbCIsIGhlYWQpOworICAgICAgICBpbnN0YW5jZS5zZXRFbmNvZGluZygiVVMtQVNDSUkiKTsKKworICAgICAgICBoZWFkID0gaW5zdGFuY2UuY29udGVudFR5cGVPZihuZXcgWE1MRm9ybWF0dGVyKCkuZ2V0SGVhZChpbnN0YW5jZSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoImFwcGxpY2F0aW9uL3htbCIsIGhlYWQpOworCisgICAgICAgIGluc3RhbmNlLnNldEVuY29kaW5nKChTdHJpbmcpIG51bGwpOworICAgICAgICBoZWFkID0gaW5zdGFuY2UuY29udGVudFR5cGVPZihuZXcgU2ltcGxlRm9ybWF0dGVyKCkuZ2V0SGVhZChpbnN0YW5jZSkpOworICAgICAgICBhc3NlcnROdWxsKGhlYWQpOworCisgICAgICAgIGluc3RhbmNlLnNldEVuY29kaW5nKCJVUy1BU0NJSSIpOworICAgICAgICBoZWFkID0gaW5zdGFuY2UuY29udGVudFR5cGVPZihuZXcgU2ltcGxlRm9ybWF0dGVyKCkuZ2V0SGVhZChpbnN0YW5jZSkpOworICAgICAgICBhc3NlcnROdWxsKGhlYWQpOworCisgICAgICAgIGluc3RhbmNlLnNldEVuY29kaW5nKChTdHJpbmcpIG51bGwpOworICAgICAgICBoZWFkID0gaW5zdGFuY2UuY29udGVudFR5cGVPZihuZXcgSGVhZEZvcm1hdHRlcigiPEhUTUw+PEJPRFk+IikuZ2V0SGVhZChpbnN0YW5jZSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInRleHQvaHRtbCIsIGhlYWQpOworCisgICAgICAgIGluc3RhbmNlLnNldEVuY29kaW5nKChTdHJpbmcpIG51bGwpOworICAgICAgICBoZWFkID0gaW5zdGFuY2UuY29udGVudFR5cGVPZihuZXcgSGVhZEZvcm1hdHRlcigiPGh0bWw+PGJvZHk+IikuZ2V0SGVhZChpbnN0YW5jZSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInRleHQvaHRtbCIsIGhlYWQpOworCisgICAgICAgIGluc3RhbmNlLnNldEVuY29kaW5nKCJVUy1BU0NJSSIpOworICAgICAgICBoZWFkID0gaW5zdGFuY2UuY29udGVudFR5cGVPZihuZXcgSGVhZEZvcm1hdHRlcigiPEhUTUw+PEJPRFk+IikuZ2V0SGVhZChpbnN0YW5jZSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoInRleHQvaHRtbCIsIGhlYWQpOworCisgICAgICAgIGluc3RhbmNlLnNldEVuY29kaW5nKCJVUy1BU0NJSSIpOworICAgICAgICBoZWFkID0gaW5zdGFuY2UuY29udGVudFR5cGVPZihuZXcgSGVhZEZvcm1hdHRlcigiPEhUTUw+PEhFQUQ+PC9IRUFEPiIKKyAgICAgICAgICAgICAgICArICI8Qk9EWT48L0JPRFk+PC9IVE1MPiIpLmdldEhlYWQoaW5zdGFuY2UpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0ZXh0L2h0bWwiLCBoZWFkKTsKKworICAgICAgICBpbnN0YW5jZS5zZXRFbmNvZGluZygoU3RyaW5nKSBudWxsKTsKKyAgICAgICAgaGVhZCA9IGluc3RhbmNlLmNvbnRlbnRUeXBlT2YobmV3IEhlYWRGb3JtYXR0ZXIoIkhlYWQiKS5nZXRIZWFkKGluc3RhbmNlKSk7CisgICAgICAgIGlmIChoZWFkICE9IG51bGwpIHsvL251bGwgaXMgYXNzdW1lZCB0byBiZSBwbGFpbiB0ZXh0LgorICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0ZXh0L3BsYWluIiwgaGVhZCk7CisgICAgICAgIH0KKworICAgICAgICBpbnN0YW5jZS5zZXRFbmNvZGluZygiVVMtQVNDSUkiKTsKKyAgICAgICAgaGVhZCA9IGluc3RhbmNlLmNvbnRlbnRUeXBlT2YobmV3IEhlYWRGb3JtYXR0ZXIoIkhlYWQiKS5nZXRIZWFkKGluc3RhbmNlKSk7CisgICAgICAgIGlmIChoZWFkICE9IG51bGwpIHsgLy9udWxsIGlzIGFzc3VtZWQgdG8gYmUgcGxhaW4gdGV4dC4KKyAgICAgICAgICAgIGFzc2VydEVxdWFscygidGV4dC9wbGFpbiIsIGhlYWQpOworICAgICAgICB9CisKKyAgICAgICAgaW5zdGFuY2Uuc2V0RW5jb2RpbmcoIlVTLUFTQ0lJIik7CisgICAgICAgIGhlYWQgPSBpbnN0YW5jZS5jb250ZW50VHlwZU9mKG5ldyBIZWFkRm9ybWF0dGVyKCJIZWFkLi4uLi4uLk5lY2suLi4uLi4uQm9keSIpLmdldEhlYWQoaW5zdGFuY2UpKTsKKyAgICAgICAgaWYgKGhlYWQgIT0gbnVsbCkgeyAvL251bGwgaXMgYXNzdW1lZCB0byBiZSBwbGFpbiB0ZXh0LgorICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0ZXh0L3BsYWluIiwgaGVhZCk7CisgICAgICAgIH0KKyAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKworICAgICAgICBmb3IgKEV4Y2VwdGlvbiBleGNlcHRpb24gOiBlbS5leGNlcHRpb25zKSB7CisgICAgICAgICAgICBmYWlsKGV4Y2VwdGlvbi50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENvbnRlbnRUeXBlT2ZGb3JtYXR0ZXIoKSB7CisgICAgICAgIE1haWxIYW5kbGVyIGluc3RhbmNlID0gbmV3IE1haWxIYW5kbGVyKGNyZWF0ZUluaXRQcm9wZXJ0aWVzKCIiKSk7CisgICAgICAgIEludGVybmFsRXJyb3JNYW5hZ2VyIGVtID0gbmV3IEludGVybmFsRXJyb3JNYW5hZ2VyKCk7CisgICAgICAgIGluc3RhbmNlLnNldEVycm9yTWFuYWdlcihlbSk7CisKKyAgICAgICAgc3luY2hyb25pemVkIChpbnN0YW5jZSkgeworICAgICAgICAgICAgYXNzZXJ0TnVsbChpbnN0YW5jZS5jb250ZW50VHlwZU9mKG5ldyBTaW1wbGVGb3JtYXR0ZXIoKSkpOworICAgICAgICAgICAgYXNzZXJ0TnVsbChpbnN0YW5jZS5jb250ZW50VHlwZU9mKG5ldyBTaW1wbGVGb3JtYXR0ZXIoKXt9KSk7CisKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiYXBwbGljYXRpb24veG1sIiwgaW5zdGFuY2UuY29udGVudFR5cGVPZihuZXcgWE1MRm9ybWF0dGVyKCkpKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiYXBwbGljYXRpb24veG1sIiwgaW5zdGFuY2UuY29udGVudFR5cGVPZihuZXcgWE1MRm9ybWF0dGVyKCl7fSkpOworICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIE5vbmUgb2YgdGhlIEZvcm1hdHRlciBtZXRob2RzIHRoYXQgY2FuIGdlbmVyYXRlIGNvbnRlbnQgc2hvdWxkIGJlCisgICAgICAgICAqIGludm9rZWQgZHVyaW5nIGEgdmVyaWZ5IGFzIHRoYXQgY291bGQgbGVhZCB0byBwb29yIHN0YXJ0dXAgdGltZXMuCisgICAgICAgICAqLworICAgICAgICBjbGFzcyBVbnN1cHBvcnRlZEhUTUwgZXh0ZW5kcyBGb3JtYXR0ZXIgeworCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0SGVhZChIYW5kbGVyIGgpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGZvcm1hdChMb2dSZWNvcmQgcmVjb3JkKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIFN0cmluZyBnZXRUYWlsKEhhbmRsZXIgaCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBzeW5jaHJvbml6ZWQgKGluc3RhbmNlKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoInRleHQvaHRtbCIsIGluc3RhbmNlLmNvbnRlbnRUeXBlT2YobmV3IFVuc3VwcG9ydGVkSFRNTCgpKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoInRleHQvaHRtbCIsIGluc3RhbmNlLmNvbnRlbnRUeXBlT2YobmV3IFVuc3VwcG9ydGVkSFRNTCgpe30pKTsKKyAgICAgICAgfQorCisgICAgICAgIGluc3RhbmNlLmNsb3NlKCk7CisgICAgICAgIGZvciAoRXhjZXB0aW9uIGV4Y2VwdGlvbiA6IGVtLmV4Y2VwdGlvbnMpIHsKKyAgICAgICAgICAgIGZhaWwoZXhjZXB0aW9uLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R3Vlc3NDb250ZW50VHlwZVJlYWRsaW1pdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjbGFzcyBMYXN0TWFya0lucHV0U3RyZWFtIGV4dGVuZHMgQnl0ZUFycmF5SW5wdXRTdHJlYW0geworCisgICAgICAgICAgICBwcml2YXRlIGludCBsYXN0UmVhZExpbWl0OworCisgICAgICAgICAgICBMYXN0TWFya0lucHV0U3RyZWFtKCkgeworICAgICAgICAgICAgICAgIHN1cGVyKG5ldyBieXRlWzEwMjRdKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgbWFyayhpbnQgcmVhZGxpbWl0KSB7CisgICAgICAgICAgICAgICAgdGhpcy5sYXN0UmVhZExpbWl0ID0gcmVhZGxpbWl0OworICAgICAgICAgICAgICAgIHN1cGVyLm1hcmsocmVhZGxpbWl0KTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHVibGljIHN5bmNocm9uaXplZCBpbnQgZ2V0TGFzdFJlYWRMaW1pdCgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbGFzdFJlYWRMaW1pdDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIExhc3RNYXJrSW5wdXRTdHJlYW0gaW4gPSBuZXcgTGFzdE1hcmtJbnB1dFN0cmVhbSgpOworICAgICAgICBVUkxDb25uZWN0aW9uLmd1ZXNzQ29udGVudFR5cGVGcm9tU3RyZWFtKGluKTsKKworICAgICAgICAvL1NlZSBNQVhfQ0hBUlMgaW4gTWFpbEhhbmRsZXIuY29udGVudFR5cGVPZgorICAgICAgICBmaW5hbCBpbnQgbGFzdExpbWl0ID0gaW4uZ2V0TGFzdFJlYWRMaW1pdCgpOworICAgICAgICBhc3NlcnRUcnVlKFN0cmluZy52YWx1ZU9mKGxhc3RMaW1pdCksIDI1ID49IGxhc3RMaW1pdCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29udGVudFR5cGVOZXN0ZWRGb3JtYXR0ZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIGV4cGVjdGVkID0gImFwcGxpY2F0aW9uL3htbDsgY2hhcnNldD11cy1hc2NpaSI7CisgICAgICAgIFN0cmluZyB0eXBlID0gZ2V0SW5saW5lQ29udGVudFR5cGUobmV3IENvbGxlY3RvckZvcm1hdHRlcigiezB9ezF9ezJ9IiwKKyAgICAgICAgICAgICAgICBuZXcgWE1MRm9ybWF0dGVyKCksIG5ldyBTZXZlcml0eUNvbXBhcmF0b3IoKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWQsIHR5cGUpOworCisKKyAgICAgICAgZXhwZWN0ZWQgPSAidGV4dC9wbGFpbjsgY2hhcnNldD11cy1hc2NpaSI7CisgICAgICAgIHR5cGUgPSBnZXRJbmxpbmVDb250ZW50VHlwZShuZXcgQ29sbGVjdG9yRm9ybWF0dGVyKCJ7MH17MX17Mn0iLAorICAgICAgICAgICAgICAgIG5ldyBDb21wYWN0Rm9ybWF0dGVyKCksIG5ldyBTZXZlcml0eUNvbXBhcmF0b3IoKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWQsIHR5cGUpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENvbnRlbnRUeXBlTmVzdGVkTXVsdGlGb3JtYXR0ZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIGV4cGVjdGVkID0gImFwcGxpY2F0aW9uL3htbDsgY2hhcnNldD11cy1hc2NpaSI7CisgICAgICAgIFN0cmluZyB0eXBlID0gZ2V0SW5saW5lTXVsdGlDb250ZW50VHlwZShuZXcgQ29sbGVjdG9yRm9ybWF0dGVyKCJ7MH17MX17Mn0iLAorICAgICAgICAgICAgICAgIG5ldyBYTUxGb3JtYXR0ZXIoKSwgbmV3IFNldmVyaXR5Q29tcGFyYXRvcigpKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZCwgdHlwZSk7CisKKworICAgICAgICBleHBlY3RlZCA9ICJ0ZXh0L3BsYWluOyBjaGFyc2V0PXVzLWFzY2lpIjsKKyAgICAgICAgdHlwZSA9IGdldElubGluZU11bHRpQ29udGVudFR5cGUobmV3IENvbGxlY3RvckZvcm1hdHRlcigiezB9ezF9ezJ9IiwKKyAgICAgICAgICAgICAgICBuZXcgQ29tcGFjdEZvcm1hdHRlcigpLCBuZXcgU2V2ZXJpdHlDb21wYXJhdG9yKCkpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkLCB0eXBlKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RDb250ZW50VHlwZU11bHRpT3ZlcnJpZGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIGV4cGVjdGVkID0gImFwcGxpY2F0aW9uL3htbDsgY2hhcnNldD11cy1hc2NpaSI7CisgICAgICAgIFN0cmluZyB0eXBlID0gZ2V0SW5saW5lTXVsdGlDb250ZW50VHlwZShuZXcgWE1MRm9ybWF0dGVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWQsIHR5cGUpOworCisgICAgICAgIE1pbWV0eXBlc0ZpbGVUeXBlTWFwIG0gPSBuZXcgTWltZXR5cGVzRmlsZVR5cGVNYXAoKTsKKyAgICAgICAgbS5hZGRNaW1lVHlwZXMoInRleHQvcGxhaW4gdHh0IFRYVCBYTUxGb3JtYXR0ZXIiKTsKKyAgICAgICAgZmluYWwgRmlsZVR5cGVNYXAgb2xkID0gRmlsZVR5cGVNYXAuZ2V0RGVmYXVsdEZpbGVUeXBlTWFwKCk7CisgICAgICAgIEZpbGVUeXBlTWFwLnNldERlZmF1bHRGaWxlVHlwZU1hcChtKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHR5cGUgPSBnZXRJbmxpbmVNdWx0aUNvbnRlbnRUeXBlKG5ldyBYTUxGb3JtYXR0ZXIoKSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoInRleHQvcGxhaW47IGNoYXJzZXQ9dXMtYXNjaWkiLCB0eXBlKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIEZpbGVUeXBlTWFwLnNldERlZmF1bHRGaWxlVHlwZU1hcChvbGQpOworICAgICAgICB9CisKKyAgICAgICAgdHlwZSA9IGdldElubGluZU11bHRpQ29udGVudFR5cGUobmV3IFhNTEZvcm1hdHRlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkLCB0eXBlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFN0cmluZyBnZXRJbmxpbmVNdWx0aUNvbnRlbnRUeXBlKEZvcm1hdHRlciBmKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU3RyaW5nW10gdmFsdWUgPSBuZXcgU3RyaW5nWzFdOworICAgICAgICBNYWlsSGFuZGxlciBpbnN0YW5jZSA9IG5ldyBNYWlsSGFuZGxlcihjcmVhdGVJbml0UHJvcGVydGllcygiIikpOworICAgICAgICBpbnN0YW5jZS5zZXRBdHRhY2htZW50Rm9ybWF0dGVycyhuZXcgU2ltcGxlRm9ybWF0dGVyKCkpOworICAgICAgICBpbnN0YW5jZS5zZXRBdHRhY2htZW50RmlsdGVycyhCb29sZWFuRmlsdGVyLkZBTFNFKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0RW5jb2RpbmcoInVzLWFzY2lpIik7CisKKyAgICAgICAgTWVzc2FnZUVycm9yTWFuYWdlciBlbSA9IG5ldyBNZXNzYWdlRXJyb3JNYW5hZ2VyKGluc3RhbmNlLmdldE1haWxQcm9wZXJ0aWVzKCkpIHsKKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwcm90ZWN0ZWQgdm9pZCBlcnJvcihNaW1lTWVzc2FnZSBtc2csIFRocm93YWJsZSB0LCBpbnQgY29kZSkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIE1pbWVNdWx0aXBhcnQgbXVsdGkgPSAoTWltZU11bHRpcGFydCkgbXNnLmdldENvbnRlbnQoKTsKKyAgICAgICAgICAgICAgICAgICAgQm9keVBhcnQgYm9keSA9IG11bHRpLmdldEJvZHlQYXJ0KDApOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoUGFydC5JTkxJTkUsIGJvZHkuZ2V0RGlzcG9zaXRpb24oKSk7CisgICAgICAgICAgICAgICAgICAgIFN0cmluZyBkZXNjID0gbXNnLmdldERlc2NyaXB0aW9uKCk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUoZGVzYy5jb250YWlucygiU29ydGVkIHVzaW5nIikpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKGRlc2MuY29udGFpbnMoInB1c2hlZCB3aGVuIikpOworICAgICAgICAgICAgICAgICAgICB2YWx1ZVswXSA9IGJvZHkuZ2V0Q29udGVudFR5cGUoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChUaHJvd2FibGUgRSkgeworICAgICAgICAgICAgICAgICAgICBkdW1wKEUpOworICAgICAgICAgICAgICAgICAgICBmYWlsKEUudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9OworICAgICAgICBpbnN0YW5jZS5zZXRFcnJvck1hbmFnZXIoZW0pOworICAgICAgICBQcm9wZXJ0aWVzIHByb3BzID0gY3JlYXRlSW5pdFByb3BlcnRpZXMoIiIpOworICAgICAgICBwcm9wcy5wdXQoIm1haWwudG8iLCAibG9jYWxob3N0QGxvY2FsZG9tYWluIik7CisgICAgICAgIGluc3RhbmNlLnNldE1haWxQcm9wZXJ0aWVzKHByb3BzKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0Rm9ybWF0dGVyKGYpOworICAgICAgICBpbnN0YW5jZS5wdWJsaXNoKG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAidGVzdCIpKTsKKyAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKworICAgICAgICByZXR1cm4gdmFsdWVbMF07CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29udGVudFR5cGVPdmVycmlkZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgZXhwZWN0ZWQgPSAiYXBwbGljYXRpb24veG1sOyBjaGFyc2V0PXVzLWFzY2lpIjsKKyAgICAgICAgU3RyaW5nIHR5cGUgPSBnZXRJbmxpbmVDb250ZW50VHlwZShuZXcgWE1MRm9ybWF0dGVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWQsIHR5cGUpOworCisgICAgICAgIE1pbWV0eXBlc0ZpbGVUeXBlTWFwIG0gPSBuZXcgTWltZXR5cGVzRmlsZVR5cGVNYXAoKTsKKyAgICAgICAgbS5hZGRNaW1lVHlwZXMoInRleHQvcGxhaW4gdHh0IFRYVCBYTUxGb3JtYXR0ZXIiKTsKKyAgICAgICAgZmluYWwgRmlsZVR5cGVNYXAgb2xkID0gRmlsZVR5cGVNYXAuZ2V0RGVmYXVsdEZpbGVUeXBlTWFwKCk7CisgICAgICAgIEZpbGVUeXBlTWFwLnNldERlZmF1bHRGaWxlVHlwZU1hcChtKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHR5cGUgPSBnZXRJbmxpbmVDb250ZW50VHlwZShuZXcgWE1MRm9ybWF0dGVyKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0ZXh0L3BsYWluOyBjaGFyc2V0PXVzLWFzY2lpIiwgdHlwZSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBGaWxlVHlwZU1hcC5zZXREZWZhdWx0RmlsZVR5cGVNYXAob2xkKTsKKyAgICAgICAgfQorCisgICAgICAgIHR5cGUgPSBnZXRJbmxpbmVDb250ZW50VHlwZShuZXcgWE1MRm9ybWF0dGVyKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWQsIHR5cGUpOworICAgIH0KKworICAgIHByaXZhdGUgRXJyb3JNYW5hZ2VyIGdldFN1cGVyRXJyb3JNYW5hZ2VyKE1haWxIYW5kbGVyIGgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBNZXRob2QgaGVtID0gTWFpbEhhbmRsZXIuY2xhc3MuZ2V0RGVjbGFyZWRNZXRob2QoImRlZmF1bHRFcnJvck1hbmFnZXIiKTsKKyAgICAgICAgaGVtLnNldEFjY2Vzc2libGUodHJ1ZSk7CisgICAgICAgIHJldHVybiAoRXJyb3JNYW5hZ2VyKSBoZW0uaW52b2tlKGgpOworICAgIH0KKworICAgIHByaXZhdGUgU3RyaW5nIGdldElubGluZUNvbnRlbnRUeXBlKEZvcm1hdHRlciBmKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU3RyaW5nW10gdmFsdWUgPSBuZXcgU3RyaW5nWzFdOworICAgICAgICBNYWlsSGFuZGxlciBpbnN0YW5jZSA9IG5ldyBNYWlsSGFuZGxlcihjcmVhdGVJbml0UHJvcGVydGllcygiIikpOworICAgICAgICBpbnN0YW5jZS5zZXRFbmNvZGluZygidXMtYXNjaWkiKTsKKyAgICAgICAgTWVzc2FnZUVycm9yTWFuYWdlciBlbSA9IG5ldyBNZXNzYWdlRXJyb3JNYW5hZ2VyKGluc3RhbmNlLmdldE1haWxQcm9wZXJ0aWVzKCkpIHsKKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwcm90ZWN0ZWQgdm9pZCBlcnJvcihNaW1lTWVzc2FnZSBtc2csIFRocm93YWJsZSB0LCBpbnQgY29kZSkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIFN0cmluZyBkZXNjID0gbXNnLmdldERlc2NyaXB0aW9uKCk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUoZGVzYy5jb250YWlucygiZmlsdGVyZWQgd2l0aCIpKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShkZXNjLmNvbnRhaW5zKCJuYW1lZCBieSIpKTsKKyAgICAgICAgICAgICAgICAgICAgdmFsdWVbMF0gPSBtc2cuZ2V0Q29udGVudFR5cGUoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChUaHJvd2FibGUgRSkgeworICAgICAgICAgICAgICAgICAgICBkdW1wKEUpOworICAgICAgICAgICAgICAgICAgICBmYWlsKEUudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9OworICAgICAgICBpbnN0YW5jZS5zZXRFcnJvck1hbmFnZXIoZW0pOworICAgICAgICBQcm9wZXJ0aWVzIHByb3BzID0gY3JlYXRlSW5pdFByb3BlcnRpZXMoIiIpOworICAgICAgICBwcm9wcy5wdXQoIm1haWwudG8iLCAibG9jYWxob3N0QGxvY2FsZG9tYWluIik7CisgICAgICAgIGluc3RhbmNlLnNldE1haWxQcm9wZXJ0aWVzKHByb3BzKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0Rm9ybWF0dGVyKGYpOworICAgICAgICBpbnN0YW5jZS5wdWJsaXNoKG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAidGVzdCIpKTsKKyAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKworICAgICAgICByZXR1cm4gdmFsdWVbMF07CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWNjZXB0TGFuZygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjbGFzcyBMYW5nTWFuYWdlciBleHRlbmRzIE1lc3NhZ2VFcnJvck1hbmFnZXIgeworCisgICAgICAgICAgICBMYW5nTWFuYWdlcihmaW5hbCBQcm9wZXJ0aWVzIHByb3BzKSB7CisgICAgICAgICAgICAgICAgc3VwZXIocHJvcHMpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHByb3RlY3RlZCB2b2lkIGVycm9yKE1pbWVNZXNzYWdlIG1zZywgVGhyb3dhYmxlIHQsIGludCBjb2RlKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgTG9jYWxlIGxvY2FsZSA9IExvY2FsZS5nZXREZWZhdWx0KCk7CisgICAgICAgICAgICAgICAgICAgIFN0cmluZyBsYW5nID0gTG9nTWFuYWdlclByb3BlcnRpZXMudG9MYW5ndWFnZVRhZyhsb2NhbGUpOworICAgICAgICAgICAgICAgICAgICBpZiAobGFuZy5sZW5ndGgoKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMobGFuZywgbXNnLmdldEhlYWRlcigiQWNjZXB0LUxhbmd1YWdlIiwgbnVsbCkpOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCBsb2NhbGUuZ2V0TGFuZ3VhZ2UoKSk7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBNaW1lTXVsdGlwYXJ0IG1wID0gKE1pbWVNdWx0aXBhcnQpIG1zZy5nZXRDb250ZW50KCk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUobXAuZ2V0Q291bnQoKSA+IDApOworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG1wLmdldENvdW50KCk7IGkrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgTWltZVBhcnQgcGFydCA9IChNaW1lUGFydCkgbXAuZ2V0Qm9keVBhcnQoaSk7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAobGFuZy5sZW5ndGgoKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGxhbmcsIHBhcnQuZ2V0SGVhZGVyKCJBY2NlcHQtTGFuZ3VhZ2UiLCBudWxsKSk7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiIiwgbG9jYWxlLmdldExhbmd1YWdlKCkpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiByZSkgeworICAgICAgICAgICAgICAgICAgICBkdW1wKHJlKTsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKHJlKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICAgICAgZHVtcChleCk7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihleCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgRm9ybWF0dGVyW10gZm9ybWF0dGVycyA9IG5ldyBGb3JtYXR0ZXJbXXtuZXcgU2ltcGxlRm9ybWF0dGVyKCksIG5ldyBTaW1wbGVGb3JtYXR0ZXIoKX07CisgICAgICAgIEludGVybmFsRXJyb3JNYW5hZ2VyIGVtOworICAgICAgICBNYWlsSGFuZGxlciB0YXJnZXQ7CisgICAgICAgIExvY2FsZSBsb2NhbGUgPSBMb2NhbGUuZ2V0RGVmYXVsdCgpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGFyZ2V0ID0gbmV3IE1haWxIYW5kbGVyKGNyZWF0ZUluaXRQcm9wZXJ0aWVzKCIiKSk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGVtID0gbmV3IExhbmdNYW5hZ2VyKHRhcmdldC5nZXRNYWlsUHJvcGVydGllcygpKTsKKyAgICAgICAgICAgICAgICB0YXJnZXQuc2V0RXJyb3JNYW5hZ2VyKGVtKTsKKyAgICAgICAgICAgICAgICB0YXJnZXQuc2V0QXR0YWNobWVudEZvcm1hdHRlcnMoZm9ybWF0dGVycyk7CisKKyAgICAgICAgICAgICAgICBMb2NhbGUuc2V0RGVmYXVsdChuZXcgTG9jYWxlKCIiLCAiIiwgIiIpKTsKKyAgICAgICAgICAgICAgICB0YXJnZXQucHVibGlzaChuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgIiIpKTsKKyAgICAgICAgICAgICAgICB0YXJnZXQuZmx1c2goKTsKKworICAgICAgICAgICAgICAgIExvY2FsZS5zZXREZWZhdWx0KExvY2FsZS5FTkdMSVNIKTsKKyAgICAgICAgICAgICAgICB0YXJnZXQucHVibGlzaChuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgIiIpKTsKKyAgICAgICAgICAgICAgICB0YXJnZXQuZmx1c2goKTsKKworICAgICAgICAgICAgICAgIExvY2FsZS5zZXREZWZhdWx0KExvY2FsZS5HRVJNQU4pOworICAgICAgICAgICAgICAgIHRhcmdldC5wdWJsaXNoKG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAiIikpOworICAgICAgICAgICAgICAgIHRhcmdldC5mbHVzaCgpOworCisgICAgICAgICAgICAgICAgTG9jYWxlLnNldERlZmF1bHQoTG9jYWxlLkZSQU5DRSk7CisgICAgICAgICAgICAgICAgdGFyZ2V0LnB1Ymxpc2gobmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICIiKSk7CisgICAgICAgICAgICAgICAgdGFyZ2V0LmZsdXNoKCk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHRhcmdldC5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgTG9jYWxlLnNldERlZmF1bHQobG9jYWxlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENvbnRlbnRMYW5nQmFzZSgpIHRocm93cyBFeGNlcHRpb24geworCisgICAgICAgIGNsYXNzIEJhc2UgZXh0ZW5kcyBNZXNzYWdlRXJyb3JNYW5hZ2VyIHsKKworICAgICAgICAgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgYnVuZGxlTmFtZTsKKworICAgICAgICAgICAgQmFzZShQcm9wZXJ0aWVzIHByb3BzLCBmaW5hbCBTdHJpbmcgYnVuZGxlTmFtZSkgeworICAgICAgICAgICAgICAgIHN1cGVyKHByb3BzKTsKKyAgICAgICAgICAgICAgICB0aGlzLmJ1bmRsZU5hbWUgPSBidW5kbGVOYW1lOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHByb3RlY3RlZCB2b2lkIGVycm9yKE1pbWVNZXNzYWdlIG1zZywgVGhyb3dhYmxlIHQsIGludCBjb2RlKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChidW5kbGVOYW1lKTsKKyAgICAgICAgICAgICAgICAgICAgTWltZU11bHRpcGFydCBtcCA9IChNaW1lTXVsdGlwYXJ0KSBtc2cuZ2V0Q29udGVudCgpOworICAgICAgICAgICAgICAgICAgICBMb2NhbGUgbCA9IExvY2FsZS5nZXREZWZhdWx0KCk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhMb2dNYW5hZ2VyUHJvcGVydGllcy50b0xhbmd1YWdlVGFnKGwpLCBtc2cuZ2V0SGVhZGVyKCJBY2NlcHQtTGFuZ3VhZ2UiLCBudWxsKSk7CisgICAgICAgICAgICAgICAgICAgIFN0cmluZyBsYW5nW10gPSBtc2cuZ2V0Q29udGVudExhbmd1YWdlKCk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydE5vdE51bGwobGFuZyk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhMb2dNYW5hZ2VyUHJvcGVydGllcy50b0xhbmd1YWdlVGFnKGwpLCBsYW5nWzBdKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIG1wLmdldENvdW50KCkpOworICAgICAgICAgICAgICAgICAgICBNaW1lUGFydCBwYXJ0OworCisgICAgICAgICAgICAgICAgICAgIHBhcnQgPSAoTWltZVBhcnQpIG1wLmdldEJvZHlQYXJ0KDApOworICAgICAgICAgICAgICAgICAgICBsYW5nID0gcGFydC5nZXRDb250ZW50TGFuZ3VhZ2UoKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChsYW5nKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKExvZ01hbmFnZXJQcm9wZXJ0aWVzLnRvTGFuZ3VhZ2VUYWcobCksIGxhbmdbMF0pOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoTG9nTWFuYWdlclByb3BlcnRpZXMudG9MYW5ndWFnZVRhZyhsKSwgcGFydC5nZXRIZWFkZXIoIkFjY2VwdC1MYW5ndWFnZSIsIG51bGwpKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHJlKSB7CisgICAgICAgICAgICAgICAgICAgIGR1bXAocmUpOworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IocmUpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgICAgICBkdW1wKGV4KTsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKGV4KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBNYWlsSGFuZGxlciB0YXJnZXQgPSBuZXcgTWFpbEhhbmRsZXIoY3JlYXRlSW5pdFByb3BlcnRpZXMoIiIpKTsKKyAgICAgICAgdGFyZ2V0LnNldEF0dGFjaG1lbnRGb3JtYXR0ZXJzKG5ldyBTaW1wbGVGb3JtYXR0ZXIoKSk7CisgICAgICAgIHRhcmdldC5zZXRBdHRhY2htZW50RmlsdGVycyhCb29sZWFuRmlsdGVyLkZBTFNFKTsKKworICAgICAgICBQcm9wZXJ0aWVzIHByb3BzID0gbmV3IFByb3BlcnRpZXMoKTsKKyAgICAgICAgcHJvcHMucHV0KCJtb3RkIiwgIkhlbGxvIE1haWxIYW5kbGVyISIpOworICAgICAgICBmaW5hbCBTdHJpbmcgcCA9IE1haWxIYW5kbGVyLmNsYXNzLmdldE5hbWUoKTsKKyAgICAgICAgZmluYWwgTG9jYWxlIGwgPSBMb2NhbGUuZ2V0RGVmYXVsdCgpOworICAgICAgICBmaW5hbCBTdHJpbmcgbmFtZSA9IE1haWxIYW5kbGVyLmNsYXNzLmdldFNpbXBsZU5hbWUoKS5jb25jYXQoImJhc2UiKTsKKyAgICAgICAgZmluYWwgRmlsZSBmID0gRmlsZS5jcmVhdGVUZW1wRmlsZShuYW1lLCAiLnByb3BlcnRpZXMiLCBmaW5kQ2xhc3NQYXRoRGlyKCkpOworICAgICAgICBMb2NhbGUuc2V0RGVmYXVsdChMb2NhbGUuVVMpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdHJ5IChGaWxlT3V0cHV0U3RyZWFtIGZvcyA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKGYpKSB7CisgICAgICAgICAgICAgICAgcHJvcHMuc3RvcmUoZm9zLCAiTm8gQ29tbWVudCIpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBTdHJpbmcgYnVuZGxlTmFtZSA9IGYuZ2V0TmFtZSgpLnN1YnN0cmluZygwLCBmLmdldE5hbWUoKS5sYXN0SW5kZXhPZignLicpKTsKKyAgICAgICAgICAgIHRhcmdldC5zZXRFcnJvck1hbmFnZXIobmV3IEJhc2UodGFyZ2V0LmdldE1haWxQcm9wZXJ0aWVzKCksIGJ1bmRsZU5hbWUpKTsKKyAgICAgICAgICAgIGZpbmFsIExvZ2dlciBsb2cgPSBMb2dnZXIuZ2V0TG9nZ2VyKHAgKyAnLicgKyBmLmdldE5hbWUoKSwgYnVuZGxlTmFtZSk7CisgICAgICAgICAgICBoYXJkUmVmID0gbG9nOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGxvZy5nZXRSZXNvdXJjZUJ1bmRsZSgpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGxvZy5nZXRSZXNvdXJjZUJ1bmRsZU5hbWUoKSk7CisKKyAgICAgICAgICAgICAgICBsb2cuYWRkSGFuZGxlcih0YXJnZXQpOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGxvZy5zZXRVc2VQYXJlbnRIYW5kbGVycyhmYWxzZSk7CisgICAgICAgICAgICAgICAgICAgIGxvZy5sb2coTGV2ZWwuU0VWRVJFLCAibW90ZCIpOworICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgICAgIGxvZy5yZW1vdmVIYW5kbGVyKHRhcmdldCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBoYXJkUmVmID0gbnVsbDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdGFyZ2V0LmNsb3NlKCk7CisKKyAgICAgICAgICAgIEludGVybmFsRXJyb3JNYW5hZ2VyIGVtID0gaW50ZXJuYWxFcnJvck1hbmFnZXJGcm9tKHRhcmdldCk7CisgICAgICAgICAgICBmb3IgKEV4Y2VwdGlvbiB0IDogZW0uZXhjZXB0aW9ucykgeworICAgICAgICAgICAgICAgIGlmIChpc0Nvbm5lY3RPclRpbWVvdXQodCkpIHsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGR1bXAodCk7CisgICAgICAgICAgICAgICAgZmFpbCh0LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0RmFsc2UoZW0uZXhjZXB0aW9ucy5pc0VtcHR5KCkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgTG9jYWxlLnNldERlZmF1bHQobCk7CisgICAgICAgICAgICBpZiAoIWYuZGVsZXRlKCkgJiYgZi5leGlzdHMoKSkgeworICAgICAgICAgICAgICAgIGYuZGVsZXRlT25FeGl0KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RDb250ZW50TGFuZ0luZmVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisKKyAgICAgICAgY2xhc3MgSW5mZXIgZXh0ZW5kcyBNZXNzYWdlRXJyb3JNYW5hZ2VyIHsKKworICAgICAgICAgICAgcHJpdmF0ZSBmaW5hbCBMb2NhbGUgZXhwZWN0OworCisgICAgICAgICAgICBJbmZlcihQcm9wZXJ0aWVzIHByb3BzLCBmaW5hbCBMb2NhbGUgZXhwZWN0KSB7CisgICAgICAgICAgICAgICAgc3VwZXIocHJvcHMpOworICAgICAgICAgICAgICAgIHRoaXMuZXhwZWN0ID0gZXhwZWN0OworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHByb3RlY3RlZCB2b2lkIGVycm9yKE1pbWVNZXNzYWdlIG1zZywgVGhyb3dhYmxlIHQsIGludCBjb2RlKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgTWltZU11bHRpcGFydCBtcCA9IChNaW1lTXVsdGlwYXJ0KSBtc2cuZ2V0Q29udGVudCgpOworICAgICAgICAgICAgICAgICAgICBMb2NhbGUgbCA9IExvY2FsZS5nZXREZWZhdWx0KCk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEZhbHNlKGwuZ2V0Q291bnRyeSgpLmVxdWFscyhleHBlY3QuZ2V0Q291bnRyeSgpKSk7CisKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKExvZ01hbmFnZXJQcm9wZXJ0aWVzLnRvTGFuZ3VhZ2VUYWcobCksIG1zZy5nZXRIZWFkZXIoIkFjY2VwdC1MYW5ndWFnZSIsIG51bGwpKTsKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxhbmdbXSA9IG1zZy5nZXRDb250ZW50TGFuZ3VhZ2UoKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGxhbmcubGVuZ3RoKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKExvZ01hbmFnZXJQcm9wZXJ0aWVzLnRvTGFuZ3VhZ2VUYWcoZXhwZWN0KSwgbGFuZ1swXSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBtcC5nZXRDb3VudCgpKTsKKyAgICAgICAgICAgICAgICAgICAgTWltZVBhcnQgcGFydDsKKworICAgICAgICAgICAgICAgICAgICBwYXJ0ID0gKE1pbWVQYXJ0KSBtcC5nZXRCb2R5UGFydCgwKTsKKyAgICAgICAgICAgICAgICAgICAgbGFuZyA9IHBhcnQuZ2V0Q29udGVudExhbmd1YWdlKCk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBsYW5nLmxlbmd0aCk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhMb2dNYW5hZ2VyUHJvcGVydGllcy50b0xhbmd1YWdlVGFnKGV4cGVjdCksIGxhbmdbMF0pOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoTG9nTWFuYWdlclByb3BlcnRpZXMudG9MYW5ndWFnZVRhZyhsKSwgcGFydC5nZXRIZWFkZXIoIkFjY2VwdC1MYW5ndWFnZSIsIG51bGwpKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHJlKSB7CisgICAgICAgICAgICAgICAgICAgIGR1bXAocmUpOworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IocmUpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgICAgICBkdW1wKGV4KTsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKGV4KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBNYWlsSGFuZGxlciB0YXJnZXQ7CisgICAgICAgIExvY2FsZSBjbDsKKyAgICAgICAgU3RyaW5nIGxvZ1ByZWZpeDsKKyAgICAgICAgUHJvcGVydGllcyBwcm9wcyA9IG5ldyBQcm9wZXJ0aWVzKCk7CisgICAgICAgIHByb3BzLnB1dCgibW90ZCIsICJIZWxsbyBNYWlsSGFuZGxlciEiKTsKKyAgICAgICAgZmluYWwgU3RyaW5nIHAgPSBNYWlsSGFuZGxlci5jbGFzcy5nZXROYW1lKCk7CisgICAgICAgIGZpbmFsIExvY2FsZSBsID0gTG9jYWxlLmdldERlZmF1bHQoKTsKKyAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUgPSBNYWlsSGFuZGxlci5jbGFzcy5nZXRTaW1wbGVOYW1lKCkuY29uY2F0KCJpbmZlciIpOworICAgICAgICBmaW5hbCBGaWxlIGYgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKG5hbWUsICJfIgorICAgICAgICAgICAgICAgICsgTG9jYWxlLkVOR0xJU0guZ2V0TGFuZ3VhZ2UoKSArICIucHJvcGVydGllcyIsIGZpbmRDbGFzc1BhdGhEaXIoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0cnkgKEZpbGVPdXRwdXRTdHJlYW0gZm9zID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0oZikpIHsKKyAgICAgICAgICAgICAgICBwcm9wcy5zdG9yZShmb3MsICJObyBDb21tZW50Iik7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIFN0cmluZyBidW5kbGVOYW1lID0gZi5nZXROYW1lKCkuc3Vic3RyaW5nKDAsIGYuZ2V0TmFtZSgpLmxhc3RJbmRleE9mKCdfJykpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSghYnVuZGxlTmFtZS5jb250YWlucyhMb2NhbGUuRU5HTElTSC5nZXRMYW5ndWFnZSgpKSk7CisKKyAgICAgICAgICAgIGNsID0gTG9jYWxlLlVTOworICAgICAgICAgICAgdGFyZ2V0ID0gbmV3IE1haWxIYW5kbGVyKGNyZWF0ZUluaXRQcm9wZXJ0aWVzKCIiKSk7CisgICAgICAgICAgICB0YXJnZXQuc2V0QXR0YWNobWVudEZvcm1hdHRlcnMobmV3IFNpbXBsZUZvcm1hdHRlcigpKTsKKyAgICAgICAgICAgIHRhcmdldC5zZXRBdHRhY2htZW50RmlsdGVycyhCb29sZWFuRmlsdGVyLkZBTFNFKTsKKworICAgICAgICAgICAgdGFyZ2V0LnNldEVycm9yTWFuYWdlcihuZXcgSW5mZXIodGFyZ2V0LmdldE1haWxQcm9wZXJ0aWVzKCksIExvY2FsZS5FTkdMSVNIKSk7CisgICAgICAgICAgICBsb2dQcmVmaXggPSBwICsgJy4nICsgZi5nZXROYW1lKCkgKyBjbDsKKyAgICAgICAgICAgIHRlc3RDb250ZW50TGFuZ0luZmVyKHRhcmdldCwgbG9nUHJlZml4LCBidW5kbGVOYW1lLCBjbCk7CisKKyAgICAgICAgICAgIGNsID0gTG9jYWxlLlVLOworICAgICAgICAgICAgdGFyZ2V0ID0gbmV3IE1haWxIYW5kbGVyKGNyZWF0ZUluaXRQcm9wZXJ0aWVzKCIiKSk7CisgICAgICAgICAgICB0YXJnZXQuc2V0QXR0YWNobWVudEZvcm1hdHRlcnMobmV3IFNpbXBsZUZvcm1hdHRlcigpKTsKKyAgICAgICAgICAgIHRhcmdldC5zZXRBdHRhY2htZW50RmlsdGVycyhCb29sZWFuRmlsdGVyLkZBTFNFKTsKKyAgICAgICAgICAgIHRhcmdldC5zZXRFcnJvck1hbmFnZXIobmV3IEluZmVyKHRhcmdldC5nZXRNYWlsUHJvcGVydGllcygpLCBMb2NhbGUuRU5HTElTSCkpOworICAgICAgICAgICAgbG9nUHJlZml4ID0gcCArICcuJyArIGYuZ2V0TmFtZSgpICsgY2w7CisgICAgICAgICAgICB0ZXN0Q29udGVudExhbmdJbmZlcih0YXJnZXQsIGxvZ1ByZWZpeCwgYnVuZGxlTmFtZSwgY2wpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgTG9jYWxlLnNldERlZmF1bHQobCk7CisgICAgICAgICAgICBpZiAoIWYuZGVsZXRlKCkgJiYgZi5leGlzdHMoKSkgeworICAgICAgICAgICAgICAgIGYuZGVsZXRlT25FeGl0KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdENvbnRlbnRMYW5nSW5mZXIoTWFpbEhhbmRsZXIgdGFyZ2V0LCBTdHJpbmcgbG9nUHJlZml4LCBTdHJpbmcgYnVuZGxlTmFtZSwgTG9jYWxlIGNsKSB7CisgICAgICAgIExvY2FsZS5zZXREZWZhdWx0KGNsKTsKKyAgICAgICAgTG9nZ2VyIGxvZyA9IExvZ2dlci5nZXRMb2dnZXIobG9nUHJlZml4ICsgY2wsIGJ1bmRsZU5hbWUpOworICAgICAgICBoYXJkUmVmID0gbG9nOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChsb2cuZ2V0UmVzb3VyY2VCdW5kbGUoKSk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGxvZy5nZXRSZXNvdXJjZUJ1bmRsZU5hbWUoKSk7CisKKyAgICAgICAgICAgIGxvZy5hZGRIYW5kbGVyKHRhcmdldCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGxvZy5zZXRVc2VQYXJlbnRIYW5kbGVycyhmYWxzZSk7CisgICAgICAgICAgICAgICAgbG9nLmxvZyhMZXZlbC5TRVZFUkUsICJtb3RkIik7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIGxvZy5yZW1vdmVIYW5kbGVyKHRhcmdldCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBoYXJkUmVmID0gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHRhcmdldC5jbG9zZSgpOworCisgICAgICAgIEludGVybmFsRXJyb3JNYW5hZ2VyIGVtID0gaW50ZXJuYWxFcnJvck1hbmFnZXJGcm9tKHRhcmdldCk7CisgICAgICAgIGZvciAoRXhjZXB0aW9uIHQgOiBlbS5leGNlcHRpb25zKSB7CisgICAgICAgICAgICBpZiAoaXNDb25uZWN0T3JUaW1lb3V0KHQpKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBkdW1wKHQpOworICAgICAgICAgICAgZmFpbCh0LnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEZhbHNlKGVtLmV4Y2VwdGlvbnMuaXNFbXB0eSgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RDb250ZW50TGFuZ0V4YWN0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1haWxIYW5kbGVyIHRhcmdldCA9IG5ldyBNYWlsSGFuZGxlcihjcmVhdGVJbml0UHJvcGVydGllcygiIikpOworICAgICAgICB0YXJnZXQuc2V0RXJyb3JNYW5hZ2VyKG5ldyBNZXNzYWdlRXJyb3JNYW5hZ2VyKHRhcmdldC5nZXRNYWlsUHJvcGVydGllcygpKSB7CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHJvdGVjdGVkIHZvaWQgZXJyb3IoTWltZU1lc3NhZ2UgbXNnLCBUaHJvd2FibGUgdCwgaW50IGNvZGUpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBNaW1lTXVsdGlwYXJ0IG1wID0gKE1pbWVNdWx0aXBhcnQpIG1zZy5nZXRDb250ZW50KCk7CisgICAgICAgICAgICAgICAgICAgIExvY2FsZSBsID0gTG9jYWxlLmdldERlZmF1bHQoKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKExvZ01hbmFnZXJQcm9wZXJ0aWVzLnRvTGFuZ3VhZ2VUYWcobCksIG1zZy5nZXRIZWFkZXIoIkFjY2VwdC1MYW5ndWFnZSIsIG51bGwpKTsKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxhbmdbXSA9IG1zZy5nZXRDb250ZW50TGFuZ3VhZ2UoKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKExvZ01hbmFnZXJQcm9wZXJ0aWVzLnRvTGFuZ3VhZ2VUYWcoTG9jYWxlLkVOR0xJU0gpLCBsYW5nWzBdKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKExvZ01hbmFnZXJQcm9wZXJ0aWVzLnRvTGFuZ3VhZ2VUYWcoTG9jYWxlLkdFUk1BTiksIGxhbmdbMV0pOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoTG9nTWFuYWdlclByb3BlcnRpZXMudG9MYW5ndWFnZVRhZyhMb2NhbGUuRlJBTkNFKSwgbGFuZ1syXSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyg0LCBtcC5nZXRDb3VudCgpKTsKKyAgICAgICAgICAgICAgICAgICAgTWltZVBhcnQgcGFydDsKKworICAgICAgICAgICAgICAgICAgICBwYXJ0ID0gKE1pbWVQYXJ0KSBtcC5nZXRCb2R5UGFydCgwKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKExvZ01hbmFnZXJQcm9wZXJ0aWVzLnRvTGFuZ3VhZ2VUYWcobCksIHBhcnQuZ2V0SGVhZGVyKCJBY2NlcHQtTGFuZ3VhZ2UiLCBudWxsKSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydE51bGwocGFydC5nZXRIZWFkZXIoIkNvbnRlbnQtTGFuZ3VhZ2UiLCAiLCIpKTsKKworICAgICAgICAgICAgICAgICAgICBwYXJ0ID0gKE1pbWVQYXJ0KSBtcC5nZXRCb2R5UGFydCgxKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKExvZ01hbmFnZXJQcm9wZXJ0aWVzLnRvTGFuZ3VhZ2VUYWcobCksIHBhcnQuZ2V0SGVhZGVyKCJBY2NlcHQtTGFuZ3VhZ2UiLCBudWxsKSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhMb2dNYW5hZ2VyUHJvcGVydGllcy50b0xhbmd1YWdlVGFnKExvY2FsZS5FTkdMSVNIKSwgcGFydC5nZXRIZWFkZXIoIkNvbnRlbnQtTGFuZ3VhZ2UiLCAiLCIpKTsKKworICAgICAgICAgICAgICAgICAgICBwYXJ0ID0gKE1pbWVQYXJ0KSBtcC5nZXRCb2R5UGFydCgyKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKExvZ01hbmFnZXJQcm9wZXJ0aWVzLnRvTGFuZ3VhZ2VUYWcobCksIHBhcnQuZ2V0SGVhZGVyKCJBY2NlcHQtTGFuZ3VhZ2UiLCBudWxsKSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhMb2dNYW5hZ2VyUHJvcGVydGllcy50b0xhbmd1YWdlVGFnKExvY2FsZS5HRVJNQU4pLCBwYXJ0LmdldEhlYWRlcigiQ29udGVudC1MYW5ndWFnZSIsICIsIikpOworCisgICAgICAgICAgICAgICAgICAgIHBhcnQgPSAoTWltZVBhcnQpIG1wLmdldEJvZHlQYXJ0KDMpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoTG9nTWFuYWdlclByb3BlcnRpZXMudG9MYW5ndWFnZVRhZyhsKSwgcGFydC5nZXRIZWFkZXIoIkFjY2VwdC1MYW5ndWFnZSIsIG51bGwpKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKExvZ01hbmFnZXJQcm9wZXJ0aWVzLnRvTGFuZ3VhZ2VUYWcoTG9jYWxlLkZSQU5DRSksIHBhcnQuZ2V0SGVhZGVyKCJDb250ZW50LUxhbmd1YWdlIiwgIiwiKSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiByZSkgeworICAgICAgICAgICAgICAgICAgICBkdW1wKHJlKTsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKHJlKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICAgICAgZHVtcChleCk7CisgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihleCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9KTsKKworICAgICAgICB0YXJnZXQuc2V0TGV2ZWwoTGV2ZWwuQUxMKTsKKyAgICAgICAgdGFyZ2V0LnNldEZpbHRlcihuZXcgTG9jYWxlRmlsdGVyKExvY2FsZS5KQVBBTkVTRSwgdHJ1ZSkpOworICAgICAgICB0YXJnZXQuc2V0UHVzaExldmVsKExldmVsLk9GRik7CisgICAgICAgIHRhcmdldC5zZXRBdHRhY2htZW50Rm9ybWF0dGVycyhuZXcgRm9ybWF0dGVyW117CisgICAgICAgICAgICBuZXcgU2ltcGxlRm9ybWF0dGVyKCksIG5ldyBTaW1wbGVGb3JtYXR0ZXIoKSwgbmV3IFNpbXBsZUZvcm1hdHRlcigpfSk7CisgICAgICAgIHRhcmdldC5zZXRBdHRhY2htZW50RmlsdGVycyhuZXcgRmlsdGVyW117CisgICAgICAgICAgICBuZXcgTG9jYWxlRmlsdGVyKExvY2FsZS5FTkdMSVNILCBmYWxzZSksCisgICAgICAgICAgICBuZXcgTG9jYWxlRmlsdGVyKExvY2FsZS5HRVJNQU4sIGZhbHNlKSwKKyAgICAgICAgICAgIG5ldyBMb2NhbGVGaWx0ZXIoTG9jYWxlLkZSQU5DRSwgZmFsc2UpfSk7IC8vanVzdCB0aGUgbGFuZ3VhZ2UuCisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIHRhcmdldC5nZXRBdHRhY2htZW50Rm9ybWF0dGVycygpLmxlbmd0aCk7CisgICAgICAgIGFzc2VydEVxdWFscygzLCB0YXJnZXQuZ2V0QXR0YWNobWVudEZpbHRlcnMoKS5sZW5ndGgpOworCisgICAgICAgIGZpbmFsIExpc3Q8RmlsZT4gZmlsZXMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKyAgICAgICAgZmluYWwgUHJvcGVydGllcyBwcm9wcyA9IG5ldyBQcm9wZXJ0aWVzKCk7CisgICAgICAgIGZpbmFsIExvY2FsZSBjdXJyZW50ID0gTG9jYWxlLmdldERlZmF1bHQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEZpbGUgZjsKKyAgICAgICAgICAgIExvY2FsZS5zZXREZWZhdWx0KG5ldyBMb2NhbGUoIiIsICIiLCAiIikpOworICAgICAgICAgICAgZiA9IHRlc3RDb250ZW50TGFuZ0V4YWN0KHRhcmdldCwgcHJvcHMsICJfIik7CisgICAgICAgICAgICBmaWxlcy5hZGQoZik7CisKKyAgICAgICAgICAgIHByb3BzLnB1dCgibW90ZCIsICJIZWxsbyBNYWlsSGFuZGxlciEiKTsKKyAgICAgICAgICAgIExvY2FsZS5zZXREZWZhdWx0KExvY2FsZS5FTkdMSVNIKTsKKyAgICAgICAgICAgIGYgPSB0ZXN0Q29udGVudExhbmdFeGFjdCh0YXJnZXQsIHByb3BzLCAiXyIpOworICAgICAgICAgICAgZmlsZXMuYWRkKGYpOworCisgICAgICAgICAgICBwcm9wcy5wdXQoIm1vdGQiLCAiSGFsbG8gTWFpbEhhbmRsZXIhIik7CisgICAgICAgICAgICBMb2NhbGUuc2V0RGVmYXVsdChMb2NhbGUuR0VSTUFOKTsKKyAgICAgICAgICAgIGYgPSB0ZXN0Q29udGVudExhbmdFeGFjdCh0YXJnZXQsIHByb3BzLCAiXyIpOworICAgICAgICAgICAgZmlsZXMuYWRkKGYpOworCisgICAgICAgICAgICBwcm9wcy5wdXQoIm1vdGQiLCAiQm9uam91ciBNYWlsSGFuZGxlciEiKTsKKyAgICAgICAgICAgIExvY2FsZS5zZXREZWZhdWx0KExvY2FsZS5GUkFOQ0UpOyAvL2p1c3QgdGhlIGxhbmd1YWdlLgorICAgICAgICAgICAgZiA9IHRlc3RDb250ZW50TGFuZ0V4YWN0KHRhcmdldCwgcHJvcHMsICJfIik7CisgICAgICAgICAgICBmaWxlcy5hZGQoZik7CisKKyAgICAgICAgICAgIExvY2FsZS5zZXREZWZhdWx0KG5ldyBMb2NhbGUoIiIsICIiLCAiIikpOworICAgICAgICAgICAgZiA9IHRlc3RDb250ZW50TGFuZ0V4YWN0KHRhcmdldCwgcHJvcHMsICJfIik7CisgICAgICAgICAgICBmaWxlcy5hZGQoZik7CisKKyAgICAgICAgICAgIExvY2FsZS5zZXREZWZhdWx0KG5ldyBMb2NhbGUoIiIsICIiLCAiIikpOworICAgICAgICAgICAgZiA9IHRlc3RDb250ZW50TGFuZ0V4YWN0KHRhcmdldCwgcHJvcHMsICIuIik7CisgICAgICAgICAgICBmaWxlcy5hZGQoZik7CisKKyAgICAgICAgICAgIHByb3BzLnB1dCgibW90ZCIsICJIZWxsbyBNYWlsSGFuZGxlciEiKTsKKyAgICAgICAgICAgIExvY2FsZS5zZXREZWZhdWx0KExvY2FsZS5FTkdMSVNIKTsKKyAgICAgICAgICAgIGYgPSB0ZXN0Q29udGVudExhbmdFeGFjdCh0YXJnZXQsIHByb3BzLCAiLiIpOworICAgICAgICAgICAgZmlsZXMuYWRkKGYpOworCisgICAgICAgICAgICBwcm9wcy5wdXQoIm1vdGQiLCAiSGFsbG8gTWFpbEhhbmRsZXIhIik7CisgICAgICAgICAgICBMb2NhbGUuc2V0RGVmYXVsdChMb2NhbGUuR0VSTUFOKTsKKyAgICAgICAgICAgIGYgPSB0ZXN0Q29udGVudExhbmdFeGFjdCh0YXJnZXQsIHByb3BzLCAiLiIpOworICAgICAgICAgICAgZmlsZXMuYWRkKGYpOworCisgICAgICAgICAgICBwcm9wcy5wdXQoIm1vdGQiLCAiQm9uam91ciBNYWlsSGFuZGxlciEiKTsKKyAgICAgICAgICAgIExvY2FsZS5zZXREZWZhdWx0KExvY2FsZS5GUkFOQ0UpOyAvL2p1c3QgdGhlIGxhbmd1YWdlLgorICAgICAgICAgICAgZiA9IHRlc3RDb250ZW50TGFuZ0V4YWN0KHRhcmdldCwgcHJvcHMsICIuIik7CisgICAgICAgICAgICBmaWxlcy5hZGQoZik7CisKKyAgICAgICAgICAgIExvY2FsZS5zZXREZWZhdWx0KG5ldyBMb2NhbGUoIiIsICIiLCAiIikpOworICAgICAgICAgICAgZiA9IHRlc3RDb250ZW50TGFuZ0V4YWN0KHRhcmdldCwgcHJvcHMsICIuIik7CisgICAgICAgICAgICBmaWxlcy5hZGQoZik7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBMb2NhbGUuc2V0RGVmYXVsdChjdXJyZW50KTsKKyAgICAgICAgICAgIGZvciAoRmlsZSBmIDogZmlsZXMpIHsKKyAgICAgICAgICAgICAgICBpZiAoIWYuZGVsZXRlKCkgJiYgZi5leGlzdHMoKSkgeworICAgICAgICAgICAgICAgICAgICBmLmRlbGV0ZU9uRXhpdCgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHRhcmdldC5jbG9zZSgpOworCisgICAgICAgIEludGVybmFsRXJyb3JNYW5hZ2VyIGVtID0gaW50ZXJuYWxFcnJvck1hbmFnZXJGcm9tKHRhcmdldCk7CisgICAgICAgIGZvciAoRXhjZXB0aW9uIHQgOiBlbS5leGNlcHRpb25zKSB7CisgICAgICAgICAgICBpZiAoaXNDb25uZWN0T3JUaW1lb3V0KHQpKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBkdW1wKHQpOworICAgICAgICAgICAgZmFpbCh0LnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEZhbHNlKGVtLmV4Y2VwdGlvbnMuaXNFbXB0eSgpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIEZpbGUgdGVzdENvbnRlbnRMYW5nRXhhY3QoTWFpbEhhbmRsZXIgdGFyZ2V0LCBQcm9wZXJ0aWVzIHByb3BzLCBTdHJpbmcgZXhhY3QpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBTdHJpbmcgcCA9IE1haWxIYW5kbGVyLmNsYXNzLmdldE5hbWUoKTsKKyAgICAgICAgZmluYWwgTG9jYWxlIGwgPSBMb2NhbGUuZ2V0RGVmYXVsdCgpOworICAgICAgICBib29sZWFuIGZhaWwgPSB0cnVlOworICAgICAgICBmaW5hbCBTdHJpbmcgbmFtZSA9IE1haWxIYW5kbGVyLmNsYXNzLmdldFNpbXBsZU5hbWUoKS5jb25jYXQoIm1vdGQiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShuYW1lLCBuYW1lLmluZGV4T2YoZXhhY3QpIDwgMSk7CisKKyAgICAgICAgU3RyaW5nIHByZWZpeDsKKyAgICAgICAgaWYgKGwuZ2V0TGFuZ3VhZ2UoKS5sZW5ndGgoKSAhPSAwKSB7CisgICAgICAgICAgICBwcmVmaXggPSAiXyIgKyBsOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcHJlZml4ID0gIiI7CisgICAgICAgIH0KKyAgICAgICAgZmluYWwgRmlsZSBmID0gRmlsZS5jcmVhdGVUZW1wRmlsZShuYW1lLCBwcmVmaXggKyAiLnByb3BlcnRpZXMiLCBmaW5kQ2xhc3NQYXRoRGlyKCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdHJ5IChGaWxlT3V0cHV0U3RyZWFtIGZvcyA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKGYpKSB7CisgICAgICAgICAgICAgICAgcHJvcHMuc3RvcmUoZm9zLCAiTm8gQ29tbWVudCIpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBMb2dnZXIgbG9nOworICAgICAgICAgICAgaWYgKGwuZ2V0TGFuZ3VhZ2UoKS5sZW5ndGgoKSA9PSAwKSB7CisgICAgICAgICAgICAgICAgbG9nID0gTG9nZ2VyLmdldExvZ2dlcihwICsgJy4nICsgZi5nZXROYW1lKCkpOworICAgICAgICAgICAgICAgIGFzc2VydE51bGwobG9nLmdldFJlc291cmNlQnVuZGxlKCkpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgbG9nZ2VyTmFtZSA9IHAgKyAnLicgKyBmLmdldE5hbWUoKSArICcuJyArIGw7CisgICAgICAgICAgICAgICAgaWYgKCIuIi5lcXVhbHMoZXhhY3QpKSB7CisgICAgICAgICAgICAgICAgICAgIGxvZyA9IExvZ2dlci5nZXRMb2dnZXIobG9nZ2VyTmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmLmdldE5hbWUoKS5zdWJzdHJpbmcoMCwgZi5nZXROYW1lKCkubGFzdEluZGV4T2YoZXhhY3QpKSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgiXyIuZXF1YWxzKGV4YWN0KSkgeworICAgICAgICAgICAgICAgICAgICBsb2cgPSBMb2dnZXIuZ2V0TG9nZ2VyKGxvZ2dlck5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZi5nZXROYW1lKCkuc3Vic3RyaW5nKDAsIGYuZ2V0TmFtZSgpLmluZGV4T2YoZXhhY3QpKSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihleGFjdCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGFzc2VydE5vdE51bGwobG9nLmdldFJlc291cmNlQnVuZGxlKCkpOworICAgICAgICAgICAgICAgIGFzc2VydE5vdE51bGwobG9nLmdldFJlc291cmNlQnVuZGxlTmFtZSgpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaGFyZFJlZiA9IGxvZzsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgbG9nLnNldFVzZVBhcmVudEhhbmRsZXJzKGZhbHNlKTsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBsb2cuYWRkSGFuZGxlcih0YXJnZXQpOworICAgICAgICAgICAgICAgICAgICBsb2cubG9nKExldmVsLklORk8sICJtb3RkIik7CisgICAgICAgICAgICAgICAgICAgIGZhaWwgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgICAgICBsb2cucmVtb3ZlSGFuZGxlcih0YXJnZXQpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgaGFyZFJlZiA9IG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoZmFpbCkgeworICAgICAgICAgICAgICAgIGlmICghZi5kZWxldGUoKSAmJiBmLmV4aXN0cygpKSB7CisgICAgICAgICAgICAgICAgICAgIGYuZGVsZXRlT25FeGl0KCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBmOworICAgIH0KKworICAgIC8qKgorICAgICAqIEZpbmQgYSB3cml0YWJsZSBkaXJlY3RvcnkgdGhhdCBpcyBpbiB0aGUgY2xhc3MgcGF0aC4KKyAgICAgKgorICAgICAqIEByZXR1cm4gYSBGaWxlIGRpcmVjdG9yeS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHRoZXJlIGlzIGEgcHJvYmxlbS4KKyAgICAgKiBAdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBpZiB0aGVyZSBhcmUgbm8gZGlyZWN0b3JpZXMgaW4gY2xhc3MgcGF0aC4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiVGhyb3dhYmxlSW5pdENhdXNlIikKKyAgICBwcml2YXRlIHN0YXRpYyBGaWxlIGZpbmRDbGFzc1BhdGhEaXIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBGaWxlIGYgPSBhbnlDbGFzc1BhdGhEaXI7CisgICAgICAgIGlmIChmICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBmOworICAgICAgICB9CisKKyAgICAgICAgQ2xhc3NMb2FkZXIgY2NsID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXRDb250ZXh0Q2xhc3NMb2FkZXIoKTsKKyAgICAgICAgaWYgKGNjbCA9PSBudWxsKSB7CisgICAgICAgICAgICBjY2wgPSBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGNjbCA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJNaXNzaW5nIGNsYXNzbG9hZGVyLiIpOworICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nIHBhdGggPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImphdmEuY2xhc3MucGF0aCIpOworICAgICAgICBTdHJpbmdbXSBkaXJzID0gcGF0aC5zcGxpdChTeXN0ZW0uZ2V0UHJvcGVydHkoInBhdGguc2VwYXJhdG9yIikpOworICAgICAgICBJT0V4Y2VwdGlvbiBmYWlsID0gbnVsbDsKKyAgICAgICAgZm9yIChTdHJpbmcgZGlyIDogZGlycykgeworICAgICAgICAgICAgZiA9IG5ldyBGaWxlKGRpci50cmltKCkpOworICAgICAgICAgICAgaWYgKGYuaXNGaWxlKCkpIHsKKyAgICAgICAgICAgICAgICBmID0gZi5nZXRQYXJlbnRGaWxlKCk7CisgICAgICAgICAgICAgICAgaWYgKGYgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaWYgKGYuaXNEaXJlY3RvcnkoKSkgeworICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgbmFtZSA9IE1haWxIYW5kbGVyVGVzdC5jbGFzcy5nZXROYW1lKCk7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIEZpbGUgdG1wID0gRmlsZS5jcmVhdGVUZW1wRmlsZShuYW1lLCAiLnRtcCIsIGYpOworICAgICAgICAgICAgICAgICAgICBmaW5hbCBVUkwgdXJsID0gY2NsLmdldFJlc291cmNlKHRtcC5nZXROYW1lKCkpOworICAgICAgICAgICAgICAgICAgICBpZiAoIXRtcC5kZWxldGUoKSAmJiB0bXAuZXhpc3RzKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIElPRXhjZXB0aW9uIGlvZSA9IG5ldyBJT0V4Y2VwdGlvbih0bXAudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgICAgICAgICBkdW1wKGlvZSk7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBpb2U7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBpZiAodXJsID09IG51bGwgfHwgIXRtcC5lcXVhbHMobmV3IEZpbGUodXJsLnRvVVJJKCkpKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEZpbGVOb3RGb3VuZEV4Y2VwdGlvbih0bXAgKyAibm90IHZpc2libGUgZnJvbSAiICsgY2NsKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBhbnlDbGFzc1BhdGhEaXIgPSBmOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gZjsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBmYWlsID0gbmV3IEZpbGVOb3RGb3VuZEV4Y2VwdGlvbihmLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgICAgIGZhaWwgPSBpb2U7CisgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBVUklTeW50YXhFeGNlcHRpb24gfCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gdXNlKSB7CisgICAgICAgICAgICAgICAgZmFpbCA9IChJT0V4Y2VwdGlvbikgbmV3IElPRXhjZXB0aW9uKHVzZS50b1N0cmluZygpKS5pbml0Q2F1c2UodXNlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmIChmYWlsICE9IG51bGwpIHsKKyAgICAgICAgICAgIHRocm93IGZhaWw7CisgICAgICAgIH0KKworICAgICAgICAvL21vZGlmeSB0aGUgY2xhc3NwYXRoIHRvIGluY2x1ZGUgYSB3cml0YWJsZSBkaXJlY3RvcnkuCisgICAgICAgIHRocm93IG5ldyBGaWxlTm90Rm91bmRFeGNlcHRpb24ocGF0aCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29tcGFyYXRvcigpIHsKKyAgICAgICAgTWFpbEhhbmRsZXIgaW5zdGFuY2UgPSBuZXcgTWFpbEhhbmRsZXIoY3JlYXRlSW5pdFByb3BlcnRpZXMoIiIpKTsKKyAgICAgICAgSW50ZXJuYWxFcnJvck1hbmFnZXIgZW0gPSBuZXcgSW50ZXJuYWxFcnJvck1hbmFnZXIoKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0RXJyb3JNYW5hZ2VyKGVtKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW5zdGFuY2Uuc2V0Q29tcGFyYXRvcigoQ29tcGFyYXRvcjxMb2dSZWNvcmQ+KSBudWxsKTsKKyAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBSRSkgeworICAgICAgICAgICAgZmFpbChSRS50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnROdWxsKGluc3RhbmNlLmdldENvbXBhcmF0b3IoKSk7CisKKyAgICAgICAgVXNlbGVzc0NvbXBhcmF0b3IgdXNlbGVzc0NvbXBhcmF0b3IgPSBuZXcgVXNlbGVzc0NvbXBhcmF0b3IoKTsKKyAgICAgICAgQ29tcGFyYXRvcjw/IHN1cGVyIExvZ1JlY29yZD4gcmVzdWx0ID0gaW5zdGFuY2UuZ2V0Q29tcGFyYXRvcigpOworICAgICAgICBhc3NlcnRFcXVhbHMoZmFsc2UsIHVzZWxlc3NDb21wYXJhdG9yLmVxdWFscyhyZXN1bHQpKTsKKworICAgICAgICBpbnN0YW5jZS5zZXRDb21wYXJhdG9yKHVzZWxlc3NDb21wYXJhdG9yKTsKKyAgICAgICAgcmVzdWx0ID0gaW5zdGFuY2UuZ2V0Q29tcGFyYXRvcigpOworCisgICAgICAgIGFzc2VydFRydWUodXNlbGVzc0NvbXBhcmF0b3IuZXF1YWxzKHJlc3VsdCkpOworCisgICAgICAgIFJhd1R5cGVDb21wYXJhdG9yIHJhdyA9IG5ldyBSYXdUeXBlQ29tcGFyYXRvcigpOworICAgICAgICBpbnN0YW5jZS5zZXRDb21wYXJhdG9yKHJhdyk7CisgICAgICAgIGFzc2VydFRydWUocmF3LmVxdWFscyhpbnN0YW5jZS5nZXRDb21wYXJhdG9yKCkpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgZW0uZXhjZXB0aW9ucy5pc0VtcHR5KCkpOworICAgICAgICBpbnN0YW5jZS5jbG9zZSgpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENhcGFjaXR5KCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgTWFpbEhhbmRsZXIgaCA9IG5ldyBNYWlsSGFuZGxlcigtMSk7CisgICAgICAgICAgICBoLmdldENhcGFjaXR5KCk7CisgICAgICAgICAgICBmYWlsKCJOZWdhdGl2ZSBjYXBhY2l0eSB3YXMgYWxsb3dlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHBhc3MpIHsKKyAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBSRSkgeworICAgICAgICAgICAgZmFpbChSRS50b1N0cmluZygpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBNYWlsSGFuZGxlciBoID0gbmV3IE1haWxIYW5kbGVyKDApOworICAgICAgICAgICAgaC5nZXRDYXBhY2l0eSgpOworICAgICAgICAgICAgZmFpbCgiWmVybyBjYXBhY2l0eSB3YXMgYWxsb3dlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHBhc3MpIHsKKyAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBSRSkgeworICAgICAgICAgICAgZmFpbChSRS50b1N0cmluZygpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBNYWlsSGFuZGxlciBoID0gbmV3IE1haWxIYW5kbGVyKDEpOworICAgICAgICAgICAgaC5nZXRDYXBhY2l0eSgpOworICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIFJFKSB7CisgICAgICAgICAgICBmYWlsKFJFLnRvU3RyaW5nKCkpOworICAgICAgICB9CisKKyAgICAgICAgZmluYWwgaW50IGV4cFJlc3VsdCA9IDIwOworICAgICAgICBNYWlsSGFuZGxlciBpbnN0YW5jZSA9IG5ldyBNYWlsSGFuZGxlcigyMCk7CisgICAgICAgIGluc3RhbmNlLnNldE1haWxQcm9wZXJ0aWVzKGNyZWF0ZUluaXRQcm9wZXJ0aWVzKCIiKSk7CisgICAgICAgIEludGVybmFsRXJyb3JNYW5hZ2VyIGVtID0gbmV3IEludGVybmFsRXJyb3JNYW5hZ2VyKCk7CisgICAgICAgIGluc3RhbmNlLnNldEVycm9yTWFuYWdlcihlbSk7CisKKyAgICAgICAgaW50IHJlc3VsdCA9IGluc3RhbmNlLmdldENhcGFjaXR5KCk7CisgICAgICAgIGFzc2VydEVxdWFscyhleHBSZXN1bHQsIHJlc3VsdCk7CisgICAgICAgIGluc3RhbmNlLmNsb3NlKCk7CisKKyAgICAgICAgcmVzdWx0ID0gaW5zdGFuY2UuZ2V0Q2FwYWNpdHkoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cFJlc3VsdCwgcmVzdWx0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRydWUsIGVtLmV4Y2VwdGlvbnMuaXNFbXB0eSgpKTsKKyAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKworICAgICAgICBTdHJpbmcgU09VUkNFX0NMQVNTID0gTWFpbEhhbmRsZXJUZXN0LmNsYXNzLmdldE5hbWUoKTsKKyAgICAgICAgU3RyaW5nIFNPVVJDRV9NRVRIT0QgPSAidGVzdENhcGFjaXR5IjsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPD0gTlVNX1JVTlM7IGkrKykgeworICAgICAgICAgICAgaW5zdGFuY2UgPSBuZXcgTWFpbEhhbmRsZXIobmV4dENhcGFjaXR5KGkpKTsKKyAgICAgICAgICAgIGluc3RhbmNlLnNldExldmVsKExldmVsLkFMTCk7CisgICAgICAgICAgICBpbnN0YW5jZS5zZXRQdXNoTGV2ZWwoTGV2ZWwuT0ZGKTsKKyAgICAgICAgICAgIGVtID0gbmV3IEludGVybmFsRXJyb3JNYW5hZ2VyKCk7CisgICAgICAgICAgICBpbnN0YW5jZS5zZXRFcnJvck1hbmFnZXIoZW0pOworICAgICAgICAgICAgQ291bnRpbmdGb3JtYXR0ZXIgZm9ybWF0dGVyID0gbmV3IENvdW50aW5nRm9ybWF0dGVyKCk7CisgICAgICAgICAgICBpbnN0YW5jZS5zZXRGb3JtYXR0ZXIoZm9ybWF0dGVyKTsKKyAgICAgICAgICAgIFByb3BlcnRpZXMgcHJvcHMgPSBjcmVhdGVJbml0UHJvcGVydGllcygiIik7CisgICAgICAgICAgICBpbnN0YW5jZS5zZXRNYWlsUHJvcGVydGllcyhwcm9wcyk7CisgICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGluc3RhbmNlLmdldENhcGFjaXR5KCk7IGorKykgeworICAgICAgICAgICAgICAgIExvZ1JlY29yZCByID0gbmV3IExvZ1JlY29yZChMZXZlbC5JTkZPLCAiIik7CisgICAgICAgICAgICAgICAgci5zZXRTb3VyY2VDbGFzc05hbWUoU09VUkNFX0NMQVNTKTsKKyAgICAgICAgICAgICAgICByLnNldFNvdXJjZU1ldGhvZE5hbWUoU09VUkNFX01FVEhPRCk7CisgICAgICAgICAgICAgICAgaW5zdGFuY2UucHVibGlzaChyKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhpbnN0YW5jZS5nZXRDYXBhY2l0eSgpLCBmb3JtYXR0ZXIuZm9ybWF0KTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBmb3JtYXR0ZXIuaGVhZCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgZm9ybWF0dGVyLnRhaWwpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGVtLmV4Y2VwdGlvbnMuc2l6ZSgpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoZW0uZXhjZXB0aW9ucy5nZXQoMCkgaW5zdGFuY2VvZiBNZXNzYWdpbmdFeGNlcHRpb24pOworICAgICAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTE9XX0NBUEFDSVRZID0gMTAwMDsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTUFYX0NBUEFDSVRZID0gMSA8PCAxODsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTlVNX1JVTlMgPSBMT1dfQ0FQQUNJVFkgKyA0MjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBSYW5kb20gUkFORE9NID0gbmV3IFJhbmRvbSgpOworCisgICAgLyoqCisgICAgICogVGVzdCBhbGwgbnVtYmVycyBiZXR3ZWVuIDEgYW5kIGxvdyBjYXBhY2l0eS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBjYXBhY2l0eSB0aGUgY3VycmVudCBjYXBhY2l0eS4KKyAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IHJhbmRvbSBjYXBhY2l0eS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCBuZXh0Q2FwYWNpdHkoaW50IGNhcGFjaXR5KSB7CisgICAgICAgIGlmIChjYXBhY2l0eSA8PSBMT1dfQ0FQQUNJVFkpIHsKKyAgICAgICAgICAgIHJldHVybiArK2NhcGFjaXR5OworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaWYgKGNhcGFjaXR5IDwgTlVNX1JVTlMpIHsKKyAgICAgICAgICAgICAgICBpbnQgbmV4dDsKKyAgICAgICAgICAgICAgICBkbyB7CisgICAgICAgICAgICAgICAgICAgIG5leHQgPSBSQU5ET00ubmV4dEludChNQVhfQ0FQQUNJVFkpOworICAgICAgICAgICAgICAgIH0gd2hpbGUgKG5leHQgPD0gTE9XX0NBUEFDSVRZKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV4dDsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIE1BWF9DQVBBQ0lUWTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEF1dGhlbnRpY2F0b3JfQXV0aGVudGljYXRvcl9BcmcoKSB7CisgICAgICAgIEF1dGhlbnRpY2F0b3IgYXV0aCA9IG5ldyBFbXB0eUF1dGhlbnRpY2F0b3IoKTsKKworICAgICAgICBNYWlsSGFuZGxlciBpbnN0YW5jZSA9IG5ldyBNYWlsSGFuZGxlcihjcmVhdGVJbml0UHJvcGVydGllcygiIikpOworICAgICAgICBJbnRlcm5hbEVycm9yTWFuYWdlciBlbSA9IG5ldyBJbnRlcm5hbEVycm9yTWFuYWdlcigpOworICAgICAgICBpbnN0YW5jZS5zZXRFcnJvck1hbmFnZXIoZW0pOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnN0YW5jZS5zZXRBdXRoZW50aWNhdG9yKChBdXRoZW50aWNhdG9yKSBudWxsKTsKKyAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBSRSkgeworICAgICAgICAgICAgZmFpbChSRS50b1N0cmluZygpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnN0YW5jZS5zZXRBdXRoZW50aWNhdG9yKGluc3RhbmNlLmdldEF1dGhlbnRpY2F0b3IoKSk7CisgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gUkUpIHsKKyAgICAgICAgICAgIGZhaWwoUkUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW5zdGFuY2Uuc2V0QXV0aGVudGljYXRvcihhdXRoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhhdXRoLCBpbnN0YW5jZS5nZXRBdXRoZW50aWNhdG9yKCkpOworICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIFJFKSB7CisgICAgICAgICAgICBmYWlsKFJFLnRvU3RyaW5nKCkpOworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRydWUsIGVtLmV4Y2VwdGlvbnMuaXNFbXB0eSgpKTsKKworICAgICAgICBpbnN0YW5jZSA9IGNyZWF0ZUhhbmRsZXJXaXRoUmVjb3JkcygpOworICAgICAgICBpbnN0YW5jZS5zZXRBdXRoZW50aWNhdG9yKG5ldyBUaHJvd0F1dGhlbnRpY2F0b3IoKSk7CisgICAgICAgIGVtID0gaW50ZXJuYWxFcnJvck1hbmFnZXJGcm9tKGluc3RhbmNlKTsKKyAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgZW0uZXhjZXB0aW9ucy5zaXplKCkpOworICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgZW0uZXhjZXB0aW9ucy5nZXQoMCkgaW5zdGFuY2VvZiBNZXNzYWdpbmdFeGNlcHRpb24pOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEF1dGhlbnRpY2F0b3JfQ2hhcl9BcnJheV9BcmcoKSB7CisgICAgICAgIFBhc3N3b3JkQXV0aGVudGljYXRpb24gcGE7CisgICAgICAgIE1haWxIYW5kbGVyIGluc3RhbmNlID0gbmV3IE1haWxIYW5kbGVyKGNyZWF0ZUluaXRQcm9wZXJ0aWVzKCIiKSk7CisgICAgICAgIEludGVybmFsRXJyb3JNYW5hZ2VyIGVtID0gbmV3IEludGVybmFsRXJyb3JNYW5hZ2VyKCk7CisgICAgICAgIGluc3RhbmNlLnNldEVycm9yTWFuYWdlcihlbSk7CisKKyAgICAgICAgLy9OdWxsIGxpdGVyYWwgbWVhbnMgYWN0dWFsIHBhc3N3b3JkIHZhbHVlIGhlcmUuCisgICAgICAgIGluc3RhbmNlLnNldEF1dGhlbnRpY2F0b3IoIm51bGwiLnRvQ2hhckFycmF5KCkpOworICAgICAgICBwYSA9IHBhc3N3b3JkQXV0aGVudGljYXRpb24oaW5zdGFuY2UuZ2V0QXV0aGVudGljYXRvcigpLCAidXNlciIpOworICAgICAgICBhc3NlcnRFcXVhbHMoInVzZXIiLCBwYS5nZXRVc2VyTmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJudWxsIiwgcGEuZ2V0UGFzc3dvcmQoKSk7CisKKyAgICAgICAgaW5zdGFuY2Uuc2V0QXV0aGVudGljYXRvcigiTnVsbCIudG9DaGFyQXJyYXkoKSk7CisgICAgICAgIHBhID0gcGFzc3dvcmRBdXRoZW50aWNhdGlvbihpbnN0YW5jZS5nZXRBdXRoZW50aWNhdG9yKCksICJ1c2VyIik7CisgICAgICAgIGFzc2VydEVxdWFscygidXNlciIsIHBhLmdldFVzZXJOYW1lKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIk51bGwiLCBwYS5nZXRQYXNzd29yZCgpKTsKKworICAgICAgICBpbnN0YW5jZS5zZXRBdXRoZW50aWNhdG9yKCJOVUxMIi50b0NoYXJBcnJheSgpKTsKKyAgICAgICAgcGEgPSBwYXNzd29yZEF1dGhlbnRpY2F0aW9uKGluc3RhbmNlLmdldEF1dGhlbnRpY2F0b3IoKSwgInVzZXIiKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ1c2VyIiwgcGEuZ2V0VXNlck5hbWUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiTlVMTCIsIHBhLmdldFBhc3N3b3JkKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnN0YW5jZS5zZXRBdXRoZW50aWNhdG9yKChjaGFyW10pIG51bGwpOworICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIFJFKSB7CisgICAgICAgICAgICBmYWlsKFJFLnRvU3RyaW5nKCkpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGluc3RhbmNlLnNldEF1dGhlbnRpY2F0b3IoaW5zdGFuY2UuZ2V0QXV0aGVudGljYXRvcigpKTsKKyAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBSRSkgeworICAgICAgICAgICAgZmFpbChSRS50b1N0cmluZygpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnN0YW5jZS5zZXRBdXRoZW50aWNhdG9yKCJwYXNzd29yZCIudG9DaGFyQXJyYXkoKSk7CisgICAgICAgICAgICBwYSA9IHBhc3N3b3JkQXV0aGVudGljYXRpb24oCisgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlLmdldEF1dGhlbnRpY2F0b3IoKSwgInVzZXIiKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygidXNlciIsIHBhLmdldFVzZXJOYW1lKCkpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJwYXNzd29yZCIsIHBhLmdldFBhc3N3b3JkKCkpOworICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIFJFKSB7CisgICAgICAgICAgICBmYWlsKFJFLnRvU3RyaW5nKCkpOworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRydWUsIGVtLmV4Y2VwdGlvbnMuaXNFbXB0eSgpKTsKKworICAgICAgICBpbnN0YW5jZSA9IGNyZWF0ZUhhbmRsZXJXaXRoUmVjb3JkcygpOworICAgICAgICBpbnN0YW5jZS5zZXRBdXRoZW50aWNhdG9yKCJwYXNzd29yZCIudG9DaGFyQXJyYXkoKSk7CisgICAgICAgIGVtID0gaW50ZXJuYWxFcnJvck1hbmFnZXJGcm9tKGluc3RhbmNlKTsKKyAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoMSwgZW0uZXhjZXB0aW9ucy5zaXplKCkpOworICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgZW0uZXhjZXB0aW9ucy5nZXQoMCkgaW5zdGFuY2VvZiBNZXNzYWdpbmdFeGNlcHRpb24pOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdE1haWxQcm9wZXJ0aWVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFByb3BlcnRpZXMgcHJvcHMgPSBuZXcgUHJvcGVydGllcygpOworICAgICAgICBNYWlsSGFuZGxlciBpbnN0YW5jZSA9IG5ldyBNYWlsSGFuZGxlcigpOworICAgICAgICBJbnRlcm5hbEVycm9yTWFuYWdlciBlbSA9IG5ldyBJbnRlcm5hbEVycm9yTWFuYWdlcigpOworICAgICAgICBpbnN0YW5jZS5zZXRFcnJvck1hbmFnZXIoZW0pOworCisgICAgICAgIGFzc2VydE5vdE51bGwoaW5zdGFuY2UuZ2V0TWFpbFByb3BlcnRpZXMoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhQcm9wZXJ0aWVzLmNsYXNzLCBpbnN0YW5jZS5nZXRNYWlsUHJvcGVydGllcygpLmdldENsYXNzKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnN0YW5jZS5zZXRNYWlsUHJvcGVydGllcygoUHJvcGVydGllcykgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsIHdhcyBhbGxvd2VkLiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBwYXNzKSB7CisgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gUkUpIHsKKyAgICAgICAgICAgIGZhaWwoUkUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKworICAgICAgICBpbnN0YW5jZS5zZXRNYWlsUHJvcGVydGllcyhwcm9wcyk7CisgICAgICAgIFByb3BlcnRpZXMgc3RvcmVkID0gaW5zdGFuY2UuZ2V0TWFpbFByb3BlcnRpZXMoKTsKKworICAgICAgICBhc3NlcnROb3ROdWxsKHN0b3JlZCk7CisgICAgICAgIGFzc2VydE5vdFNhbWUocHJvcHMsIHN0b3JlZCk7CisgICAgICAgIGFzc2VydEVxdWFscyhwcm9wcy5nZXRDbGFzcygpLCBzdG9yZWQuZ2V0Q2xhc3MoKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRydWUsIGVtLmV4Y2VwdGlvbnMuaXNFbXB0eSgpKTsKKyAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKworICAgICAgICBpbnN0YW5jZSA9IGNyZWF0ZUhhbmRsZXJXaXRoUmVjb3JkcygpOworICAgICAgICBwcm9wcyA9IGluc3RhbmNlLmdldE1haWxQcm9wZXJ0aWVzKCk7CisgICAgICAgIGVtID0gbmV3IEludGVybmFsRXJyb3JNYW5hZ2VyKCk7CisgICAgICAgIGluc3RhbmNlLnNldEVycm9yTWFuYWdlcihlbSk7CisKKyAgICAgICAgcHJvcHMuc2V0UHJvcGVydHkoIm1haWwuZnJvbSIsICJsb2NhbGhvc3RAbG9jYWxkb21haW4iKTsKKyAgICAgICAgcHJvcHMuc2V0UHJvcGVydHkoIm1haWwudG8iLCAibG9jYWxob3N0QGxvY2FsZG9tYWluIik7CisgICAgICAgIGluc3RhbmNlLnNldE1haWxQcm9wZXJ0aWVzKHByb3BzKTsKKyAgICAgICAgaW5zdGFuY2UuZmx1c2goKTsKKyAgICAgICAgZm9yIChFeGNlcHRpb24gZXhjZXB0aW9uIDogZW0uZXhjZXB0aW9ucykgeworICAgICAgICAgICAgZmluYWwgVGhyb3dhYmxlIHQgPSBleGNlcHRpb247CisgICAgICAgICAgICBpZiAoaXNDb25uZWN0T3JUaW1lb3V0KHQpKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGR1bXAodCk7CisgICAgICAgICAgICAgICAgZmFpbCh0LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGFzc2VydEZhbHNlKGVtLmV4Y2VwdGlvbnMuaXNFbXB0eSgpKTsKKworICAgICAgICBwcm9wcy5zZXRQcm9wZXJ0eSgibWFpbC5mcm9tIiwgImxvY2FsaG9zdEBsb2NhbGRvbWFpbiIpOworICAgICAgICBwcm9wcy5zZXRQcm9wZXJ0eSgibWFpbC50byIsICI6OjFAQCIpOworICAgICAgICBpbnN0YW5jZS5zZXRNYWlsUHJvcGVydGllcyhwcm9wcyk7CisKKyAgICAgICAgZW0gPSBuZXcgSW50ZXJuYWxFcnJvck1hbmFnZXIoKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0RXJyb3JNYW5hZ2VyKGVtKTsKKworICAgICAgICBpbnN0YW5jZS5wdWJsaXNoKG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAidGVzdCIpKTsKKyAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKyAgICAgICAgaW50IGZhaWxlZCA9IDA7CisgICAgICAgIGZvciAoRXhjZXB0aW9uIGV4Y2VwdGlvbiA6IGVtLmV4Y2VwdGlvbnMpIHsKKyAgICAgICAgICAgIGZpbmFsIFRocm93YWJsZSB0ID0gZXhjZXB0aW9uOworICAgICAgICAgICAgaWYgKHQgaW5zdGFuY2VvZiBBZGRyZXNzRXhjZXB0aW9uIHx8IGlzQ29ubmVjdE9yVGltZW91dCh0KSkgeworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBkdW1wKHQpOworICAgICAgICAgICAgICAgIGZhaWxlZCsrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygwLCBmYWlsZWQpOworICAgICAgICBhc3NlcnRGYWxzZShlbS5leGNlcHRpb25zLmlzRW1wdHkoKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW1wdHlBZGRyZXNzUGFyc2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy9Bc3N1bWVkIHRvIG5ldmVyIHJldHVybiBudWxsIGluIHRoZSBNYWlsSGFuZGxlci4KKyAgICAgICAgSW50ZXJuZXRBZGRyZXNzW10gYSA9IEludGVybmV0QWRkcmVzcy5wYXJzZSgiIiwgZmFsc2UpOworICAgICAgICBhc3NlcnRUcnVlKGEubGVuZ3RoID09IDApOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdERlZmF1bHRSZWNpcGllbnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgUHJvcGVydGllcyBwcm9wcyA9IGNyZWF0ZUluaXRQcm9wZXJ0aWVzKCIiKTsKKyAgICAgICAgcHJvcHMucmVtb3ZlKCJtYWlsLmZyb20iKTsKKyAgICAgICAgcHJvcHMucmVtb3ZlKCJtYWlsLnRvIik7CisgICAgICAgIHByb3BzLnJlbW92ZSgibWFpbC5jYyIpOworICAgICAgICBwcm9wcy5yZW1vdmUoIm1haWwuYmNjIik7CisKKyAgICAgICAgLy9Vc2VyIGRpZG4ndCBzcGVjaWZ5IHNvIGF1dG8gY29tcHV0ZSBhZGRyZXNzZXMuCisgICAgICAgIGFzc2VydE51bGwocHJvcHMuZ2V0UHJvcGVydHkoIm1haWwuZnJvbSIpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChwcm9wcy5nZXQoIm1haWwuZnJvbSIpKTsKKworICAgICAgICBhc3NlcnROdWxsKHByb3BzLmdldFByb3BlcnR5KCJtYWlsLnRvIikpOworICAgICAgICBhc3NlcnROdWxsKHByb3BzLmdldCgibWFpbC50byIpKTsKKyAgICAgICAgdGVzdERlZmF1bHRSZWNpcGllbnQocHJvcHMpOworCisgICAgICAgIC8vVXNlciBvdmVycmlkZSBvZiBUTyBhbmQgRlJPTSBhZGRyZXNzZXMuCisgICAgICAgIHByb3BzLnNldFByb3BlcnR5KCJtYWlsLmZyb20iLCAiIik7CisgICAgICAgIHByb3BzLnNldFByb3BlcnR5KCJtYWlsLnRvIiwgIiIpOworICAgICAgICB0ZXN0RGVmYXVsdFJlY2lwaWVudChwcm9wcyk7CisKKyAgICAgICAgLy9GaXhlZCBUTyBhbmQgRlJPTS4KKyAgICAgICAgcHJvcHMuc2V0UHJvcGVydHkoIm1haWwuZnJvbSIsICJsb2NhbGhvc3RAbG9jYWxkb21haW4iKTsKKyAgICAgICAgcHJvcHMuc2V0UHJvcGVydHkoIm1haWwudG8iLCAib3RoZXJob3N0QGxvY2FsZG9tYWluIik7CisgICAgICAgIHRlc3REZWZhdWx0UmVjaXBpZW50KHByb3BzKTsKKworICAgICAgICAvL0NvbXB1dGUgVE8gYW5kIEZST00gd2l0aCBhIGZpeGVkIENDIGFuZCBCQ0MuCisgICAgICAgIHByb3BzLnJlbW92ZSgibWFpbC5mcm9tIik7CisgICAgICAgIHByb3BzLnJlbW92ZSgibWFpbC50byIpOworICAgICAgICBhc3NlcnROdWxsKHByb3BzLmdldFByb3BlcnR5KCJtYWlsLnRvIikpOworICAgICAgICBhc3NlcnROdWxsKHByb3BzLmdldCgibWFpbC50byIpKTsKKyAgICAgICAgcHJvcHMuc2V0UHJvcGVydHkoIm1haWwuY2MiLCAibG9jYWxob3N0QGxvY2FsZG9tYWluIik7CisgICAgICAgIHByb3BzLnNldFByb3BlcnR5KCJtYWlsLmJjYyIsICJvdGhlcmhvc3RAbG9jYWxkb21haW4iKTsKKyAgICAgICAgdGVzdERlZmF1bHRSZWNpcGllbnQocHJvcHMpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0RGVmYXVsdFJlY2lwaWVudChQcm9wZXJ0aWVzIGFkZHJlc3NlcykgdGhyb3dzIEV4Y2VwdGlvbiB7CisKKyAgICAgICAgY2xhc3MgRGVmYXVsdFJlY2lwaWVudCBleHRlbmRzIE1lc3NhZ2VFcnJvck1hbmFnZXIgeworCisgICAgICAgICAgICBEZWZhdWx0UmVjaXBpZW50KFByb3BlcnRpZXMgcHJvcHMpIHsKKyAgICAgICAgICAgICAgICBzdXBlcihwcm9wcyk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHByaXZhdGUgQWRkcmVzc1tdIHBhcnNlS2V5KFNlc3Npb24gcywgU3RyaW5nIGtleSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIHYgPSBzLmdldFByb3BlcnR5KGtleSk7CisgICAgICAgICAgICAgICAgaWYgKHYgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsgLy92YWx1ZSBub3QgcHJlc2VudCBmb3Iga2V5LgorICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodi5sZW5ndGgoKSA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQWRkcmVzc1swXTsgLy92YWx1ZSBlbXB0eSBmb3Iga2V5LgorICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBJbnRlcm5ldEFkZHJlc3MucGFyc2UodiwgdHJ1ZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgIHByb3RlY3RlZCB2b2lkIGVycm9yKE1pbWVNZXNzYWdlIG1zZywgVGhyb3dhYmxlIHQsIGludCBjb2RlKSB7CisgICAgICAgICAgICAgICAgU2Vzc2lvbiBzID0gbmV3IE1lc3NhZ2VDb250ZXh0KG1zZykuZ2V0U2Vzc2lvbigpOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIEFkZHJlc3NbXSBsb2NhbCA9IG5ldyBBZGRyZXNzW117CisgICAgICAgICAgICAgICAgICAgICAgICBJbnRlcm5ldEFkZHJlc3MuZ2V0TG9jYWxBZGRyZXNzKHMpfTsKKyAgICAgICAgICAgICAgICAgICAgQWRkcmVzc1tdIGV4cGVjdEZyb20gPSBwYXJzZUtleShzLCAibWFpbC5mcm9tIik7CisgICAgICAgICAgICAgICAgICAgIEFkZHJlc3NbXSBleHBlY3RUbyA9IHBhcnNlS2V5KHMsICJtYWlsLnRvIik7CisgICAgICAgICAgICAgICAgICAgIEFkZHJlc3NbXSBleHBlY3RDYyA9IHBhcnNlS2V5KHMsICJtYWlsLmNjIik7CisgICAgICAgICAgICAgICAgICAgIEFkZHJlc3NbXSBleHBlY3RCY2MgPSBwYXJzZUtleShzLCAibWFpbC5iY2MiKTsKKworICAgICAgICAgICAgICAgICAgICBjaGVja0FkZHJlc3MoZXhwZWN0RnJvbSA9PSBudWxsID8gbG9jYWwgOiBleHBlY3RGcm9tLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1zZy5nZXRGcm9tKCkpOworICAgICAgICAgICAgICAgICAgICBjaGVja0FkZHJlc3MoZXhwZWN0VG8gPT0gbnVsbCA/IGxvY2FsIDogZXhwZWN0VG8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXNnLmdldFJlY2lwaWVudHMoTWVzc2FnZS5SZWNpcGllbnRUeXBlLlRPKSk7CisKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0QXJyYXlFcXVhbHMoZXhwZWN0Q2MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXNnLmdldFJlY2lwaWVudHMoTWVzc2FnZS5SZWNpcGllbnRUeXBlLkNDKSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKGV4cGVjdEJjYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBtc2cuZ2V0UmVjaXBpZW50cyhNZXNzYWdlLlJlY2lwaWVudFR5cGUuQkNDKSk7CisKKyAgICAgICAgICAgICAgICAgICAgTGlzdDxBZGRyZXNzPiBhbGwgPSBhc0xpc3QobXNnLmdldEFsbFJlY2lwaWVudHMoKSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUoYWxsLmNvbnRhaW5zQWxsKGFzTGlzdChleHBlY3RUbykpKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShhbGwuY29udGFpbnNBbGwoYXNMaXN0KGV4cGVjdENjKSkpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKGFsbC5jb250YWluc0FsbChhc0xpc3QoZXhwZWN0QmNjKSkpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSBmYWlsKSB7CisgICAgICAgICAgICAgICAgICAgIGR1bXAoZmFpbCk7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoZmFpbC50b1N0cmluZygpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHByaXZhdGUgdm9pZCBjaGVja0FkZHJlc3MoQWRkcmVzc1tdIGV4cGVjdCwgQWRkcmVzc1tdIGZvdW5kKSB7CisgICAgICAgICAgICAgICAgaWYgKGV4cGVjdC5sZW5ndGggPT0gMCkgeworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKGZvdW5kID09IG51bGwgfHwgZm91bmQubGVuZ3RoID09IDApOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEFycmF5RXF1YWxzKGV4cGVjdCwgZm91bmQpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHJpdmF0ZSBMaXN0PEFkZHJlc3M+IGFzTGlzdChBZGRyZXNzLi4uIGEpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gQXJyYXlzLmFzTGlzdChhID09IG51bGwgPyBuZXcgQWRkcmVzc1swXSA6IGEpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIE1haWxIYW5kbGVyIGluc3RhbmNlID0gY3JlYXRlSGFuZGxlcldpdGhSZWNvcmRzKCk7CisgICAgICAgIFByb3BlcnRpZXMgcHJvcHMgPSBpbnN0YW5jZS5nZXRNYWlsUHJvcGVydGllcygpOworICAgICAgICBwcm9wcy5wdXRBbGwoYWRkcmVzc2VzKTsKKyAgICAgICAgSW50ZXJuYWxFcnJvck1hbmFnZXIgZW0gPSBuZXcgRGVmYXVsdFJlY2lwaWVudChwcm9wcyk7CisgICAgICAgIGluc3RhbmNlLnNldEVycm9yTWFuYWdlcihlbSk7CisKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChpbnN0YW5jZS5nZXRNYWlsUHJvcGVydGllcygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFByb3BlcnRpZXMuY2xhc3MsIGluc3RhbmNlLmdldE1haWxQcm9wZXJ0aWVzKCkuZ2V0Q2xhc3MoKSk7CisKKyAgICAgICAgaW5zdGFuY2Uuc2V0TWFpbFByb3BlcnRpZXMocHJvcHMpOworICAgICAgICBpbnN0YW5jZS5jbG9zZSgpOworICAgICAgICBmb3IgKEV4Y2VwdGlvbiBleGNlcHRpb24gOiBlbS5leGNlcHRpb25zKSB7CisgICAgICAgICAgICBmaW5hbCBUaHJvd2FibGUgdCA9IGV4Y2VwdGlvbjsKKyAgICAgICAgICAgIGlmIChpc0Nvbm5lY3RPclRpbWVvdXQodCkgfHwgdCBpbnN0YW5jZW9mIFNlbmRGYWlsZWRFeGNlcHRpb24pIHsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZHVtcCh0KTsKKyAgICAgICAgICAgICAgICBmYWlsKHQudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRGYWxzZShlbS5leGNlcHRpb25zLmlzRW1wdHkoKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVmYXVsdFVybE5hbWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgUHJvcGVydGllcyBwcm9wcyA9IGNyZWF0ZUluaXRQcm9wZXJ0aWVzKCIiKTsKKyAgICAgICAgcHJvcHMucHV0KCJtYWlsLnRyYW5zcG9ydC5wcm90b2NvbCIsICJzbXRwIik7CisgICAgICAgIFNlc3Npb24gcyA9IFNlc3Npb24uZ2V0SW5zdGFuY2UocHJvcHMpOworICAgICAgICBUcmFuc3BvcnQgdCA9IHMuZ2V0VHJhbnNwb3J0KCk7CisgICAgICAgIGlmIChpc1ByaXZhdGVTcGVjKHQuZ2V0Q2xhc3MoKSkpIHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhVTktOT1dOX0hPU1QsIHQuZ2V0VVJMTmFtZSgpLmdldEhvc3QoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RBdHRhY2htZW50RmlsdGVycygpIHsKKyAgICAgICAgTWFpbEhhbmRsZXIgaW5zdGFuY2UgPSBuZXcgTWFpbEhhbmRsZXIoY3JlYXRlSW5pdFByb3BlcnRpZXMoIiIpKTsKKyAgICAgICAgSW50ZXJuYWxFcnJvck1hbmFnZXIgZW0gPSBuZXcgSW50ZXJuYWxFcnJvck1hbmFnZXIoKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0RXJyb3JNYW5hZ2VyKGVtKTsKKworICAgICAgICBGaWx0ZXJbXSByZXN1bHQgPSBpbnN0YW5jZS5nZXRBdHRhY2htZW50RmlsdGVycygpOworICAgICAgICBhc3NlcnROb3ROdWxsKHJlc3VsdCk7CisgICAgICAgIGFzc2VydEVxdWFscyhyZXN1bHQubGVuZ3RoLCBpbnN0YW5jZS5nZXRBdHRhY2htZW50Rm9ybWF0dGVycygpLmxlbmd0aCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGZhbHNlLCBpbnN0YW5jZS5nZXRBdHRhY2htZW50RmlsdGVycygpID09IHJlc3VsdCk7CisKKyAgICAgICAgaWYgKGluc3RhbmNlLmdldEF0dGFjaG1lbnRGb3JtYXR0ZXJzKCkubGVuZ3RoICE9IDApIHsKKyAgICAgICAgICAgIGluc3RhbmNlLnNldEF0dGFjaG1lbnRGb3JtYXR0ZXJzKG5ldyBGb3JtYXR0ZXJbMF0pOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGluc3RhbmNlLnNldEF0dGFjaG1lbnRGaWx0ZXJzKChGaWx0ZXJbXSkgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsIGFsbG93ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIHBhc3MpIHsKKyAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiByZSkgeworICAgICAgICAgICAgZmFpbChyZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnN0YW5jZS5zZXRBdHRhY2htZW50RmlsdGVycyhuZXcgRmlsdGVyWzBdKTsKKyAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiByZSkgeworICAgICAgICAgICAgZmFpbChyZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgaW5zdGFuY2UuZ2V0QXR0YWNobWVudEZvcm1hdHRlcnMoKS5sZW5ndGgpOworCisgICAgICAgICAgICBpbnN0YW5jZS5zZXRBdHRhY2htZW50RmlsdGVycyhuZXcgRmlsdGVyW117Qm9vbGVhbkZpbHRlci5UUlVFfSk7CisgICAgICAgICAgICBmYWlsKCJGaWx0ZXIgdG8gZm9ybWF0dGVyIG1pc21hdGNoLiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHBhc3MpIHsKKyAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiByZSkgeworICAgICAgICAgICAgZmFpbChyZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorCisgICAgICAgIGluc3RhbmNlLnNldEF0dGFjaG1lbnRGb3JtYXR0ZXJzKAorICAgICAgICAgICAgICAgIG5ldyBGb3JtYXR0ZXJbXXtuZXcgU2ltcGxlRm9ybWF0dGVyKCksIG5ldyBYTUxGb3JtYXR0ZXIoKX0pOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMiwgaW5zdGFuY2UuZ2V0QXR0YWNobWVudEZvcm1hdHRlcnMoKS5sZW5ndGgpOworCisgICAgICAgICAgICBpbnN0YW5jZS5zZXRBdHRhY2htZW50RmlsdGVycyhuZXcgRmlsdGVyW117Qm9vbGVhbkZpbHRlci5UUlVFfSk7CisgICAgICAgICAgICBmYWlsKCJGaWx0ZXIgdG8gZm9ybWF0dGVyIG1pc21hdGNoLiIpOworICAgICAgICB9IGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHBhc3MpIHsKKyAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiByZSkgeworICAgICAgICAgICAgZmFpbChyZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMiwgaW5zdGFuY2UuZ2V0QXR0YWNobWVudEZvcm1hdHRlcnMoKS5sZW5ndGgpOworICAgICAgICAgICAgRmlsdGVyW10gZmlsdGVycyA9IG5ldyBGaWx0ZXJbXXtCb29sZWFuRmlsdGVyLlRSVUUsIEJvb2xlYW5GaWx0ZXIuVFJVRX07CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoaW5zdGFuY2UuZ2V0QXR0YWNobWVudEZvcm1hdHRlcnMoKS5sZW5ndGgsIGZpbHRlcnMubGVuZ3RoKTsKKyAgICAgICAgICAgIGluc3RhbmNlLnNldEF0dGFjaG1lbnRGaWx0ZXJzKGZpbHRlcnMpOworICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHJlKSB7CisgICAgICAgICAgICBmYWlsKHJlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygyLCBpbnN0YW5jZS5nZXRBdHRhY2htZW50Rm9ybWF0dGVycygpLmxlbmd0aCk7CisgICAgICAgICAgICBGaWx0ZXJbXSBmaWx0ZXJzID0gbmV3IEZpbHRlcltde251bGwsIG51bGx9OworICAgICAgICAgICAgYXNzZXJ0IGZpbHRlcnMgIT0gbnVsbDsgLy9TdXBwcmVzcyBicm9rZW4gTlBFIGhpbnQgd2l0aCBhc3NlcnQuCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoaW5zdGFuY2UuZ2V0QXR0YWNobWVudEZvcm1hdHRlcnMoKS5sZW5ndGgsIGZpbHRlcnMubGVuZ3RoKTsKKyAgICAgICAgICAgIGluc3RhbmNlLnNldEF0dGFjaG1lbnRGaWx0ZXJzKGZpbHRlcnMpOworICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHJlKSB7CisgICAgICAgICAgICBmYWlsKHJlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygyLCBpbnN0YW5jZS5nZXRBdHRhY2htZW50Rm9ybWF0dGVycygpLmxlbmd0aCk7CisgICAgICAgICAgICBpbnN0YW5jZS5zZXRBdHRhY2htZW50RmlsdGVycyhuZXcgRmlsdGVyWzBdKTsKKyAgICAgICAgICAgIGZhaWwoIkZpbHRlciB0byBmb3JtYXR0ZXIgbWlzbWF0Y2guIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gcGFzcykgeworICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHJlKSB7CisgICAgICAgICAgICBmYWlsKHJlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhpbnN0YW5jZS5nZXRBdHRhY2htZW50Rm9ybWF0dGVycygpLmxlbmd0aCwgMik7CisgICAgICAgICAgICBGaWx0ZXJbXSBmaWx0ZXJzID0gbmV3IEZpbHRlcltde251bGwsIG51bGx9OworICAgICAgICAgICAgaW5zdGFuY2Uuc2V0QXR0YWNobWVudEZpbHRlcnMoZmlsdGVycyk7CisgICAgICAgICAgICBmaWx0ZXJzWzBdID0gQm9vbGVhbkZpbHRlci5UUlVFOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGZpbHRlcnNbMF0sIGZpbHRlcnNbMF0pOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGZpbHRlcnNbMF0uZXF1YWxzKGluc3RhbmNlLmdldEF0dGFjaG1lbnRGaWx0ZXJzKClbMF0pLCBmYWxzZSk7CisgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gcmUpIHsKKyAgICAgICAgICAgIGZhaWwocmUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRFcXVhbHMoaW5zdGFuY2UuZ2V0QXR0YWNobWVudEZvcm1hdHRlcnMoKS5sZW5ndGgsIDIpOworICAgICAgICAvL0ZvcmNlIGEgc3ViY2xhc3MgYXJyYXkuCisgICAgICAgIGluc3RhbmNlLnNldEF0dGFjaG1lbnRGaWx0ZXJzKG5ldyBUaHJvd0ZpbHRlcltde25ldyBUaHJvd0ZpbHRlcigpLCBuZXcgVGhyb3dGaWx0ZXIoKX0pOworICAgICAgICBhc3NlcnRFcXVhbHMoRmlsdGVyW10uY2xhc3MsIGluc3RhbmNlLmdldEF0dGFjaG1lbnRGaWx0ZXJzKCkuZ2V0Q2xhc3MoKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGVtLmV4Y2VwdGlvbnMuaXNFbXB0eSgpLCB0cnVlKTsKKyAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RBdHRhY2htZW50RmlsdGVyc0RlZmF1bHRzKCkgeworICAgICAgICBNYWlsSGFuZGxlciBpbnN0YW5jZSA9IG5ldyBNYWlsSGFuZGxlcihjcmVhdGVJbml0UHJvcGVydGllcygiIikpOworICAgICAgICBJbnRlcm5hbEVycm9yTWFuYWdlciBlbSA9IG5ldyBJbnRlcm5hbEVycm9yTWFuYWdlcigpOworICAgICAgICBpbnN0YW5jZS5zZXRFcnJvck1hbmFnZXIoZW0pOworICAgICAgICBpbnN0YW5jZS5zZXRGaWx0ZXIobmV3IEVycm9yRmlsdGVyKCkpOworICAgICAgICBmaW5hbCBGb3JtYXR0ZXIgZiA9IG5ldyBTaW1wbGVGb3JtYXR0ZXIoKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0QXR0YWNobWVudEZvcm1hdHRlcnMoZiwgZiwgZiwgZik7CisKKyAgICAgICAgZm9yIChFeGNlcHRpb24gZXhjZXB0aW9uIDogZW0uZXhjZXB0aW9ucykgeworICAgICAgICAgICAgZHVtcChleGNlcHRpb24pOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoZW0uZXhjZXB0aW9ucy5pc0VtcHR5KCkpOworCisgICAgICAgIGFzc2VydEVxdWFscyhFcnJvckZpbHRlci5jbGFzcywgaW5zdGFuY2UuZ2V0RmlsdGVyKCkuZ2V0Q2xhc3MoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhpbnN0YW5jZS5nZXRGaWx0ZXIoKSwgaW5zdGFuY2UuZ2V0QXR0YWNobWVudEZpbHRlcnMoKVswXSk7CisgICAgICAgIGFzc2VydEVxdWFscyhpbnN0YW5jZS5nZXRGaWx0ZXIoKSwgaW5zdGFuY2UuZ2V0QXR0YWNobWVudEZpbHRlcnMoKVsxXSk7CisgICAgICAgIGFzc2VydEVxdWFscyhpbnN0YW5jZS5nZXRGaWx0ZXIoKSwgaW5zdGFuY2UuZ2V0QXR0YWNobWVudEZpbHRlcnMoKVsyXSk7CisgICAgICAgIGFzc2VydEVxdWFscyhpbnN0YW5jZS5nZXRGaWx0ZXIoKSwgaW5zdGFuY2UuZ2V0QXR0YWNobWVudEZpbHRlcnMoKVszXSk7CisKKyAgICAgICAgaW5zdGFuY2Uuc2V0QXR0YWNobWVudEZpbHRlcnMobnVsbCwgbnVsbCwgbnVsbCwgbnVsbCk7CisgICAgICAgIGFzc2VydEVxdWFscyhFcnJvckZpbHRlci5jbGFzcywgaW5zdGFuY2UuZ2V0RmlsdGVyKCkuZ2V0Q2xhc3MoKSk7CisgICAgICAgIGFzc2VydE51bGwoaW5zdGFuY2UuZ2V0QXR0YWNobWVudEZpbHRlcnMoKVswXSk7CisgICAgICAgIGFzc2VydE51bGwoaW5zdGFuY2UuZ2V0QXR0YWNobWVudEZpbHRlcnMoKVsxXSk7CisgICAgICAgIGFzc2VydE51bGwoaW5zdGFuY2UuZ2V0QXR0YWNobWVudEZpbHRlcnMoKVsyXSk7CisgICAgICAgIGFzc2VydE51bGwoaW5zdGFuY2UuZ2V0QXR0YWNobWVudEZpbHRlcnMoKVszXSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QXR0YWNobWVudEZvcm1hdHRlcnMoKSB7CisgICAgICAgIE1haWxIYW5kbGVyIGluc3RhbmNlID0gbmV3IE1haWxIYW5kbGVyKGNyZWF0ZUluaXRQcm9wZXJ0aWVzKCIiKSk7CisKKyAgICAgICAgSW50ZXJuYWxFcnJvck1hbmFnZXIgZW0gPSBuZXcgSW50ZXJuYWxFcnJvck1hbmFnZXIoKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0RXJyb3JNYW5hZ2VyKGVtKTsKKworICAgICAgICBGb3JtYXR0ZXJbXSByZXN1bHQgPSBpbnN0YW5jZS5nZXRBdHRhY2htZW50Rm9ybWF0dGVycygpOworICAgICAgICBhc3NlcnROb3ROdWxsKHJlc3VsdCk7CisgICAgICAgIGFzc2VydEVxdWFscyhyZXN1bHQgPT0gaW5zdGFuY2UuZ2V0QXR0YWNobWVudEZvcm1hdHRlcnMoKSwgZmFsc2UpOworCisgICAgICAgIGFzc2VydEVxdWFscyhyZXN1bHQubGVuZ3RoLCBpbnN0YW5jZS5nZXRBdHRhY2htZW50RmlsdGVycygpLmxlbmd0aCk7CisgICAgICAgIGFzc2VydEVxdWFscyhyZXN1bHQubGVuZ3RoLCBpbnN0YW5jZS5nZXRBdHRhY2htZW50TmFtZXMoKS5sZW5ndGgpOworCisgICAgICAgIHJlc3VsdCA9IG5ldyBGb3JtYXR0ZXJbXXtuZXcgU2ltcGxlRm9ybWF0dGVyKCksIG5ldyBYTUxGb3JtYXR0ZXIoKX07CisgICAgICAgIGluc3RhbmNlLnNldEF0dGFjaG1lbnRGb3JtYXR0ZXJzKHJlc3VsdCk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdC5sZW5ndGgsIGluc3RhbmNlLmdldEF0dGFjaG1lbnRGaWx0ZXJzKCkubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdC5sZW5ndGgsIGluc3RhbmNlLmdldEF0dGFjaG1lbnROYW1lcygpLmxlbmd0aCk7CisKKyAgICAgICAgcmVzdWx0WzBdID0gbmV3IFhNTEZvcm1hdHRlcigpOworICAgICAgICByZXN1bHRbMV0gPSBuZXcgU2ltcGxlRm9ybWF0dGVyKCk7CisgICAgICAgIGFzc2VydEVxdWFscyhyZXN1bHRbMV0uZ2V0Q2xhc3MoKSwKKyAgICAgICAgICAgICAgICBpbnN0YW5jZS5nZXRBdHRhY2htZW50Rm9ybWF0dGVycygpWzBdLmdldENsYXNzKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMocmVzdWx0WzBdLmdldENsYXNzKCksCisgICAgICAgICAgICAgICAgaW5zdGFuY2UuZ2V0QXR0YWNobWVudEZvcm1hdHRlcnMoKVsxXS5nZXRDbGFzcygpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW5zdGFuY2Uuc2V0QXR0YWNobWVudEZvcm1hdHRlcnMoKEZvcm1hdHRlcltdKSBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGwgd2FzIGFsbG93ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIE5QRSkgeworICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHJlKSB7CisgICAgICAgICAgICBmYWlsKHJlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisKKyAgICAgICAgcmVzdWx0WzBdID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGluc3RhbmNlLnNldEF0dGFjaG1lbnRGb3JtYXR0ZXJzKHJlc3VsdCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsIGluZGV4IHdhcyBhbGxvd2VkLiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBOUEUpIHsKKyAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiByZSkgeworICAgICAgICAgICAgZmFpbChyZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorCisgICAgICAgIHJlc3VsdCA9IG5ldyBGb3JtYXR0ZXJbMF07CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnN0YW5jZS5zZXRBdHRhY2htZW50Rm9ybWF0dGVycyhyZXN1bHQpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdC5sZW5ndGgsIGluc3RhbmNlLmdldEF0dGFjaG1lbnRGaWx0ZXJzKCkubGVuZ3RoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhyZXN1bHQubGVuZ3RoLCBpbnN0YW5jZS5nZXRBdHRhY2htZW50TmFtZXMoKS5sZW5ndGgpOworICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHJlKSB7CisgICAgICAgICAgICBmYWlsKHJlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisKKyAgICAgICAgaW5zdGFuY2Uuc2V0QXR0YWNobWVudEZvcm1hdHRlcnMobmV3IFRocm93Rm9ybWF0dGVyW117bmV3IFRocm93Rm9ybWF0dGVyKCl9KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEZvcm1hdHRlcltdLmNsYXNzLCBpbnN0YW5jZS5nZXRBdHRhY2htZW50Rm9ybWF0dGVycygpLmdldENsYXNzKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoRmlsdGVyW10uY2xhc3MsIGluc3RhbmNlLmdldEF0dGFjaG1lbnRGaWx0ZXJzKCkuZ2V0Q2xhc3MoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhGb3JtYXR0ZXJbXS5jbGFzcywgaW5zdGFuY2UuZ2V0QXR0YWNobWVudE5hbWVzKCkuZ2V0Q2xhc3MoKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGVtLmV4Y2VwdGlvbnMuaXNFbXB0eSgpLCB0cnVlKTsKKyAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RBdHRhY2htZW50TmFtZXNfU3RyaW5nQXJyKCkgeworICAgICAgICBGb3JtYXR0ZXJbXSBuYW1lczsKKyAgICAgICAgTWFpbEhhbmRsZXIgaW5zdGFuY2UgPSBuZXcgTWFpbEhhbmRsZXIoY3JlYXRlSW5pdFByb3BlcnRpZXMoIiIpKTsKKyAgICAgICAgSW50ZXJuYWxFcnJvck1hbmFnZXIgZW0gPSBuZXcgSW50ZXJuYWxFcnJvck1hbmFnZXIoKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0RXJyb3JNYW5hZ2VyKGVtKTsKKworICAgICAgICBuYW1lcyA9IGluc3RhbmNlLmdldEF0dGFjaG1lbnROYW1lcygpOworICAgICAgICBhc3NlcnROb3ROdWxsKG5hbWVzKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW5zdGFuY2Uuc2V0QXR0YWNobWVudE5hbWVzKChTdHJpbmdbXSkgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsIHdhcyBhbGxvd2VkLiIpOworICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHJlKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoTnVsbFBvaW50ZXJFeGNlcHRpb24uY2xhc3MsIHJlLmdldENsYXNzKCkpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGluc3RhbmNlLmdldEF0dGFjaG1lbnRGb3JtYXR0ZXJzKCkubGVuZ3RoID4gMCkgeworICAgICAgICAgICAgaW5zdGFuY2Uuc2V0QXR0YWNobWVudEZvcm1hdHRlcnMobmV3IEZvcm1hdHRlclswXSk7CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW5zdGFuY2Uuc2V0QXR0YWNobWVudE5hbWVzKG5ldyBTdHJpbmdbMF0pOworICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHJlKSB7CisgICAgICAgICAgICBmYWlsKHJlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGluc3RhbmNlLnNldEF0dGFjaG1lbnROYW1lcyhuZXcgU3RyaW5nWzFdKTsKKyAgICAgICAgICAgIGZhaWwoIk1pc21hdGNoIHdpdGggYXR0YWNobWVudCBmb3JtYXR0ZXJzLiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiB8IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gcGFzcykgeworICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHJlKSB7CisgICAgICAgICAgICBmYWlsKHJlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisKKyAgICAgICAgaW5zdGFuY2Uuc2V0QXR0YWNobWVudEZvcm1hdHRlcnMoCisgICAgICAgICAgICAgICAgbmV3IEZvcm1hdHRlcltde25ldyBTaW1wbGVGb3JtYXR0ZXIoKSwgbmV3IFhNTEZvcm1hdHRlcigpfSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnN0YW5jZS5zZXRBdHRhY2htZW50TmFtZXMobmV3IFN0cmluZ1syXSk7CisgICAgICAgICAgICBmYWlsKCJOdWxsIGluZGV4IHdhcyBhbGxvd2VkLiIpOworICAgICAgICB9IGNhdGNoIChOdWxsUG9pbnRlckV4Y2VwdGlvbiBwYXNzKSB7CisgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gcmUpIHsKKyAgICAgICAgICAgIGZhaWwocmUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKworICAgICAgICBGb3JtYXR0ZXJbXSBmb3JtYXR0ZXJzID0gaW5zdGFuY2UuZ2V0QXR0YWNobWVudEZvcm1hdHRlcnMoKTsKKyAgICAgICAgbmFtZXMgPSBpbnN0YW5jZS5nZXRBdHRhY2htZW50TmFtZXMoKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMobmFtZXNbMF0udG9TdHJpbmcoKSwgU3RyaW5nLnZhbHVlT2YoZm9ybWF0dGVyc1swXSkpOworICAgICAgICBhc3NlcnRFcXVhbHMobmFtZXNbMV0udG9TdHJpbmcoKSwgU3RyaW5nLnZhbHVlT2YoZm9ybWF0dGVyc1sxXSkpOworCisgICAgICAgIFN0cmluZ1tdIHN0cmluZ05hbWVzID0gbmV3IFN0cmluZ1tdeyJlcnJvci50eHQiLCAiZXJyb3IueG1sIn07CisgICAgICAgIGluc3RhbmNlLnNldEF0dGFjaG1lbnROYW1lcyhzdHJpbmdOYW1lcyk7CisgICAgICAgIGFzc2VydEVxdWFscyhzdHJpbmdOYW1lc1swXSwgaW5zdGFuY2UuZ2V0QXR0YWNobWVudE5hbWVzKClbMF0udG9TdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhzdHJpbmdOYW1lc1sxXSwgaW5zdGFuY2UuZ2V0QXR0YWNobWVudE5hbWVzKClbMV0udG9TdHJpbmcoKSk7CisKKyAgICAgICAgc3RyaW5nTmFtZXNbMF0gPSAiaW5mby50eHQiOworICAgICAgICBhc3NlcnRFcXVhbHMoc3RyaW5nTmFtZXNbMF0uZXF1YWxzKAorICAgICAgICAgICAgICAgIGluc3RhbmNlLmdldEF0dGFjaG1lbnROYW1lcygpWzBdLnRvU3RyaW5nKCkpLCBmYWxzZSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGluc3RhbmNlLnNldEF0dGFjaG1lbnROYW1lcyhuZXcgU3RyaW5nWzBdKTsKKyAgICAgICAgICAgIGZhaWwoIk5hbWVzIG1pc21hdGNoIGZvcm1hdHRlcnMuIik7CisgICAgICAgIH0gY2F0Y2ggKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gcGFzcykgeworICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHJlKSB7CisgICAgICAgICAgICBmYWlsKHJlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRydWUsIGVtLmV4Y2VwdGlvbnMuaXNFbXB0eSgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RBdHRhY2htZW50TmFtZXNfRm9ybWF0dGVyQXJyKCkgeworICAgICAgICBGb3JtYXR0ZXJbXSBmb3JtYXR0ZXJzOworICAgICAgICBNYWlsSGFuZGxlciBpbnN0YW5jZSA9IG5ldyBNYWlsSGFuZGxlcihjcmVhdGVJbml0UHJvcGVydGllcygiIikpOworICAgICAgICBJbnRlcm5hbEVycm9yTWFuYWdlciBlbSA9IG5ldyBJbnRlcm5hbEVycm9yTWFuYWdlcigpOworICAgICAgICBpbnN0YW5jZS5zZXRFcnJvck1hbmFnZXIoZW0pOworCisgICAgICAgIGFzc2VydE5vdE51bGwoaW5zdGFuY2UuZ2V0QXR0YWNobWVudE5hbWVzKCkpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnN0YW5jZS5zZXRBdHRhY2htZW50TmFtZXMoKEZvcm1hdHRlcltdKSBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGwgd2FzIGFsbG93ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIHBhc3MpIHsKKyAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiByZSkgeworICAgICAgICAgICAgZmFpbChyZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChpbnN0YW5jZS5nZXRBdHRhY2htZW50Rm9ybWF0dGVycygpLmxlbmd0aCA+IDApIHsKKyAgICAgICAgICAgIGluc3RhbmNlLnNldEF0dGFjaG1lbnRGb3JtYXR0ZXJzKG5ldyBGb3JtYXR0ZXJbMF0pOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGluc3RhbmNlLnNldEF0dGFjaG1lbnROYW1lcyhuZXcgRm9ybWF0dGVyWzJdKTsKKyAgICAgICAgICAgIGZhaWwoImZvcm1hdHRlciBtaXNtYXRjaC4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gfCBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHBhc3MpIHsKKyAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiByZSkgeworICAgICAgICAgICAgZmFpbChyZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorCisgICAgICAgIGluc3RhbmNlLnNldEF0dGFjaG1lbnRGb3JtYXR0ZXJzKAorICAgICAgICAgICAgICAgIG5ldyBGb3JtYXR0ZXJbXXtuZXcgU2ltcGxlRm9ybWF0dGVyKCksIG5ldyBYTUxGb3JtYXR0ZXIoKX0pOworCisgICAgICAgIGFzc2VydEVxdWFscyhpbnN0YW5jZS5nZXRBdHRhY2htZW50Rm9ybWF0dGVycygpLmxlbmd0aCwKKyAgICAgICAgICAgICAgICBpbnN0YW5jZS5nZXRBdHRhY2htZW50TmFtZXMoKS5sZW5ndGgpOworCisgICAgICAgIGZvcm1hdHRlcnMgPSBuZXcgRm9ybWF0dGVyW117bmV3IFNpbXBsZUZvcm1hdHRlcigpLCBuZXcgWE1MRm9ybWF0dGVyKCl9OworICAgICAgICBpbnN0YW5jZS5zZXRBdHRhY2htZW50TmFtZXMoZm9ybWF0dGVycyk7CisgICAgICAgIGZvcm1hdHRlcnNbMF0gPSBuZXcgWE1MRm9ybWF0dGVyKCk7CisgICAgICAgIGFzc2VydEVxdWFscyhmb3JtYXR0ZXJzWzBdLmVxdWFscyhpbnN0YW5jZS5nZXRBdHRhY2htZW50TmFtZXMoKVswXSksIGZhbHNlKTsKKworICAgICAgICBpbnN0YW5jZS5zZXRBdHRhY2htZW50TmFtZXMobmV3IFRocm93Rm9ybWF0dGVyW117bmV3IFRocm93Rm9ybWF0dGVyKCksIG5ldyBUaHJvd0Zvcm1hdHRlcigpfSk7CisgICAgICAgIGFzc2VydEVxdWFscyhGb3JtYXR0ZXJbXS5jbGFzcywgaW5zdGFuY2UuZ2V0QXR0YWNobWVudE5hbWVzKCkuZ2V0Q2xhc3MoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhlbS5leGNlcHRpb25zLmlzRW1wdHkoKSwgdHJ1ZSk7CisgICAgICAgIGluc3RhbmNlLmNsb3NlKCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3ViamVjdF9TdHJpbmcoKSB7CisgICAgICAgIFN0cmluZyBzdWJqZWN0ID0gIlRlc3Qgc3ViamVjdC4iOworICAgICAgICBNYWlsSGFuZGxlciBpbnN0YW5jZSA9IG5ldyBNYWlsSGFuZGxlcihjcmVhdGVJbml0UHJvcGVydGllcygiIikpOworICAgICAgICBJbnRlcm5hbEVycm9yTWFuYWdlciBlbSA9IG5ldyBJbnRlcm5hbEVycm9yTWFuYWdlcigpOworICAgICAgICBpbnN0YW5jZS5zZXRFcnJvck1hbmFnZXIoZW0pOworCisgICAgICAgIGFzc2VydE5vdE51bGwoaW5zdGFuY2UuZ2V0U3ViamVjdCgpKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW5zdGFuY2Uuc2V0U3ViamVjdCgoU3RyaW5nKSBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoIk51bGwgc3ViamVjdCB3YXMgYWxsb3dlZC4iKTsKKyAgICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gcGFzcykgeworICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHJlKSB7CisgICAgICAgICAgICBmYWlsKHJlLnRvU3RyaW5nKCkpOworICAgICAgICB9CisKKyAgICAgICAgaW5zdGFuY2Uuc2V0U3ViamVjdChzdWJqZWN0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHN1YmplY3QsIGluc3RhbmNlLmdldFN1YmplY3QoKS50b1N0cmluZygpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoZW0uZXhjZXB0aW9ucy5pc0VtcHR5KCksIHRydWUpOworICAgICAgICBpbnN0YW5jZS5jbG9zZSgpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFRhaWxGb3JtYXR0ZXJzKCkgeworICAgICAgICBNYWlsSGFuZGxlciBpbnN0YW5jZSA9IG5ldyBNYWlsSGFuZGxlcihjcmVhdGVJbml0UHJvcGVydGllcygiIikpOworICAgICAgICBJbnRlcm5hbEVycm9yTWFuYWdlciBlbSA9IG5ldyBJbnRlcm5hbEVycm9yTWFuYWdlcigpOworICAgICAgICBpbnN0YW5jZS5zZXRFcnJvck1hbmFnZXIoZW0pOworCisgICAgICAgIGluc3RhbmNlLnNldFN1YmplY3QoaW5zdGFuY2UudG9TdHJpbmcoKSk7CisgICAgICAgIEZvcm1hdHRlciBmMSA9IGluc3RhbmNlLmdldFN1YmplY3QoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGYxLCBmMSk7CisgICAgICAgIGFzc2VydEVxdWFscyhmMS5oYXNoQ29kZSgpLCBmMS5oYXNoQ29kZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGYxLnRvU3RyaW5nKCksIGYxLnRvU3RyaW5nKCkpOworCisgICAgICAgIGluc3RhbmNlLnNldFN1YmplY3QoaW5zdGFuY2UudG9TdHJpbmcoKSk7CisgICAgICAgIEZvcm1hdHRlciBmMiA9IGluc3RhbmNlLmdldFN1YmplY3QoKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGYyLCBmMik7CisgICAgICAgIGFzc2VydEVxdWFscyhmMi5oYXNoQ29kZSgpLCBmMi5oYXNoQ29kZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGYyLnRvU3RyaW5nKCksIGYyLnRvU3RyaW5nKCkpOworCisgICAgICAgIGFzc2VydEVxdWFscyhmMS5nZXRDbGFzcygpLCBmMi5nZXRDbGFzcygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGYxLnRvU3RyaW5nKCksIGYyLnRvU3RyaW5nKCkpOworCisgICAgICAgIEZvcm1hdHRlciBzYW1lID0gbmV3IFhNTEZvcm1hdHRlcigpOworICAgICAgICBpbnN0YW5jZS5zZXRBdHRhY2htZW50Rm9ybWF0dGVycygKKyAgICAgICAgICAgICAgICBuZXcgRm9ybWF0dGVyW117c2FtZSwgc2FtZX0pOworICAgICAgICBGb3JtYXR0ZXJbXSBmb3JtYXR0ZXJzID0gaW5zdGFuY2UuZ2V0QXR0YWNobWVudE5hbWVzKCk7CisgICAgICAgIGYxID0gZm9ybWF0dGVyc1swXTsKKyAgICAgICAgZjIgPSBmb3JtYXR0ZXJzWzFdOworCisgICAgICAgIGFzc2VydEVxdWFscyhmMSwgZjEpOworICAgICAgICBhc3NlcnRFcXVhbHMoZjEuaGFzaENvZGUoKSwgZjEuaGFzaENvZGUoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhmMS50b1N0cmluZygpLCBmMS50b1N0cmluZygpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoZjIsIGYyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGYyLmhhc2hDb2RlKCksIGYyLmhhc2hDb2RlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoZjIudG9TdHJpbmcoKSwgZjIudG9TdHJpbmcoKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGYxLmdldENsYXNzKCksIGYyLmdldENsYXNzKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoZjEudG9TdHJpbmcoKSwgZjIudG9TdHJpbmcoKSk7CisKKyAgICAgICAgYXNzZXJ0RmFsc2UoZjEuZXF1YWxzKG5ldyBTaW1wbGVGb3JtYXR0ZXIoKSkpOworICAgICAgICBhc3NlcnRGYWxzZShuZXcgU2ltcGxlRm9ybWF0dGVyKCkuZXF1YWxzKGYxKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGYyLmVxdWFscyhuZXcgU2ltcGxlRm9ybWF0dGVyKCkpKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UobmV3IFNpbXBsZUZvcm1hdHRlcigpLmVxdWFscyhmMikpOworCisgICAgICAgIC8vTmV3IGluIEphdmFNYWlsIDEuNC40LgorICAgICAgICBhc3NlcnRFcXVhbHMoZjEsIGYyKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGYxLmhhc2hDb2RlKCksIGYyLmhhc2hDb2RlKCkpOworCisgICAgICAgIGFzc2VydEVxdWFscyhlbS5leGNlcHRpb25zLmlzRW1wdHkoKSwgdHJ1ZSk7CisgICAgICAgIGluc3RhbmNlLmNsb3NlKCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3ViamVjdF9Gb3JtYXR0ZXIoKSB7CisgICAgICAgIEZvcm1hdHRlciBmb3JtYXQgPSBuZXcgU2ltcGxlRm9ybWF0dGVyKCk7CisgICAgICAgIE1haWxIYW5kbGVyIGluc3RhbmNlID0gbmV3IE1haWxIYW5kbGVyKGNyZWF0ZUluaXRQcm9wZXJ0aWVzKCIiKSk7CisgICAgICAgIEludGVybmFsRXJyb3JNYW5hZ2VyIGVtID0gbmV3IEludGVybmFsRXJyb3JNYW5hZ2VyKCk7CisgICAgICAgIGluc3RhbmNlLnNldEVycm9yTWFuYWdlcihlbSk7CisKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChpbnN0YW5jZS5nZXRTdWJqZWN0KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoQ29sbGVjdG9yRm9ybWF0dGVyLmNsYXNzLCBpbnN0YW5jZS5nZXRTdWJqZWN0KCkuZ2V0Q2xhc3MoKSk7CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGluc3RhbmNlLnNldFN1YmplY3QoKEZvcm1hdHRlcikgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCJOdWxsIHN1YmplY3Qgd2FzIGFsbG93ZWQuIik7CisgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIHBhc3MpIHsKKyAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiByZSkgeworICAgICAgICAgICAgZmFpbChyZS50b1N0cmluZygpKTsKKyAgICAgICAgfQorCisgICAgICAgIGluc3RhbmNlLnNldFN1YmplY3QoZm9ybWF0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGZvcm1hdCwgaW5zdGFuY2UuZ2V0U3ViamVjdCgpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHModHJ1ZSwgZW0uZXhjZXB0aW9ucy5pc0VtcHR5KCkpOworICAgICAgICBpbnN0YW5jZS5jbG9zZSgpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEF0dGFjaG1lbnRGaWx0ZXJTd2FwQmVmb3JlUHVzaCgpIHsKKyAgICAgICAgTWFpbEhhbmRsZXIgaW5zdGFuY2UgPSBuZXcgTWFpbEhhbmRsZXIoMTApOworICAgICAgICBpbnN0YW5jZS5zZXRNYWlsUHJvcGVydGllcyhjcmVhdGVJbml0UHJvcGVydGllcygiIikpOworICAgICAgICBpbnN0YW5jZS5zZXRMZXZlbChMZXZlbC5BTEwpOworICAgICAgICBpbnN0YW5jZS5zZXRQdXNoTGV2ZWwoTGV2ZWwuT0ZGKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0UHVzaEZpbHRlcigoRmlsdGVyKSBudWxsKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0RmlsdGVyKEJvb2xlYW5GaWx0ZXIuRkFMU0UpOworICAgICAgICBpbnN0YW5jZS5zZXRBdHRhY2htZW50Rm9ybWF0dGVycyhuZXcgRm9ybWF0dGVyW117bmV3IFhNTEZvcm1hdHRlcigpfSk7CisgICAgICAgIGluc3RhbmNlLnNldEF0dGFjaG1lbnRGaWx0ZXJzKG5ldyBGaWx0ZXJbXXtudWxsfSk7CisgICAgICAgIEludGVybmFsRXJyb3JNYW5hZ2VyIGVtID0gbmV3IEludGVybmFsRXJyb3JNYW5hZ2VyKCk7CisgICAgICAgIGluc3RhbmNlLnNldEVycm9yTWFuYWdlcihlbSk7CisKKyAgICAgICAgTG9nUmVjb3JkIHJlY29yZCA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAibG9zdCByZWNvcmQiKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShpbnN0YW5jZS5pc0xvZ2dhYmxlKHJlY29yZCkpOworCisgICAgICAgIGluc3RhbmNlLnB1Ymxpc2gocmVjb3JkKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0QXR0YWNobWVudEZpbHRlcnMobmV3IEZpbHRlcltde0Jvb2xlYW5GaWx0ZXIuRkFMU0V9KTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoaW5zdGFuY2UuaXNMb2dnYWJsZShyZWNvcmQpKTsKKyAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKworICAgICAgICBpbnQgc2VlbkZvcm1hdCA9IDA7CisgICAgICAgIGZvciAoRXhjZXB0aW9uIGV4Y2VwdGlvbiA6IGVtLmV4Y2VwdGlvbnMpIHsKKyAgICAgICAgICAgIGlmIChleGNlcHRpb24gaW5zdGFuY2VvZiBNZXNzYWdpbmdFeGNlcHRpb24pIHsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoZXhjZXB0aW9uIGluc3RhbmNlb2YgUnVudGltZUV4Y2VwdGlvbgorICAgICAgICAgICAgICAgICAgICAmJiBleGNlcHRpb24uZ2V0TWVzc2FnZSgpLmNvbnRhaW5zKGluc3RhbmNlLmdldEZpbHRlcigpLnRvU3RyaW5nKCkpCisgICAgICAgICAgICAgICAgICAgICYmIGV4Y2VwdGlvbi5nZXRNZXNzYWdlKCkuY29udGFpbnMoQXJyYXlzLmFzTGlzdChpbnN0YW5jZS5nZXRBdHRhY2htZW50RmlsdGVycygpKS50b1N0cmluZygpKSkgeworICAgICAgICAgICAgICAgIHNlZW5Gb3JtYXQrKzsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsgLy9leHBlY3RlZC4KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZmFpbChTdHJpbmcudmFsdWVPZihleGNlcHRpb24pKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJObyBmb3JtYXQgZXJyb3IiLCBzZWVuRm9ybWF0ID4gMCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RmlsdGVyU3dhcEJlZm9yZVB1c2goKSB7CisgICAgICAgIE1haWxIYW5kbGVyIGluc3RhbmNlID0gbmV3IE1haWxIYW5kbGVyKDEwKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0TWFpbFByb3BlcnRpZXMoY3JlYXRlSW5pdFByb3BlcnRpZXMoIiIpKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0TGV2ZWwoTGV2ZWwuQUxMKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0UHVzaExldmVsKExldmVsLk9GRik7CisgICAgICAgIGluc3RhbmNlLnNldFB1c2hGaWx0ZXIoKEZpbHRlcikgbnVsbCk7CisgICAgICAgIGluc3RhbmNlLnNldEF0dGFjaG1lbnRGb3JtYXR0ZXJzKG5ldyBTaW1wbGVGb3JtYXR0ZXIoKSk7CisgICAgICAgIGluc3RhbmNlLnNldEF0dGFjaG1lbnRGaWx0ZXJzKEJvb2xlYW5GaWx0ZXIuRkFMU0UpOworICAgICAgICBJbnRlcm5hbEVycm9yTWFuYWdlciBlbSA9IG5ldyBJbnRlcm5hbEVycm9yTWFuYWdlcigpOworICAgICAgICBpbnN0YW5jZS5zZXRFcnJvck1hbmFnZXIoZW0pOworCisgICAgICAgIExvZ1JlY29yZCByZWNvcmQgPSBuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgImxvc3QgcmVjb3JkIik7CisgICAgICAgIGFzc2VydFRydWUoaW5zdGFuY2UuaXNMb2dnYWJsZShyZWNvcmQpKTsKKworICAgICAgICBpbnN0YW5jZS5wdWJsaXNoKHJlY29yZCk7CisgICAgICAgIGluc3RhbmNlLnNldEZpbHRlcihCb29sZWFuRmlsdGVyLkZBTFNFKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoaW5zdGFuY2UuaXNMb2dnYWJsZShyZWNvcmQpKTsKKyAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKworICAgICAgICBpbnQgc2VlbkZvcm1hdCA9IDA7CisgICAgICAgIGZvciAoRXhjZXB0aW9uIGV4Y2VwdGlvbiA6IGVtLmV4Y2VwdGlvbnMpIHsKKyAgICAgICAgICAgIGlmIChleGNlcHRpb24gaW5zdGFuY2VvZiBNZXNzYWdpbmdFeGNlcHRpb24pIHsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoZXhjZXB0aW9uIGluc3RhbmNlb2YgUnVudGltZUV4Y2VwdGlvbgorICAgICAgICAgICAgICAgICAgICAmJiBleGNlcHRpb24uZ2V0TWVzc2FnZSgpLmNvbnRhaW5zKGluc3RhbmNlLmdldEZpbHRlcigpLnRvU3RyaW5nKCkpKSB7CisgICAgICAgICAgICAgICAgc2VlbkZvcm1hdCsrOworICAgICAgICAgICAgICAgIGNvbnRpbnVlOyAvL2V4cGVjdGVkLgorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBmYWlsKFN0cmluZy52YWx1ZU9mKGV4Y2VwdGlvbikpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoIk5vIGZvcm1hdCBlcnJvciIsIHNlZW5Gb3JtYXQgPiAwKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RGaWx0ZXJGbGlwRmxvcCgpIHsKKyAgICAgICAgTWFpbEhhbmRsZXIgaW5zdGFuY2UgPSBuZXcgTWFpbEhhbmRsZXJPdmVycmlkZSgxMCk7CisgICAgICAgIGluc3RhbmNlLnNldE1haWxQcm9wZXJ0aWVzKGNyZWF0ZUluaXRQcm9wZXJ0aWVzKCIiKSk7CisgICAgICAgIGluc3RhbmNlLnNldExldmVsKExldmVsLkFMTCk7CisgICAgICAgIGluc3RhbmNlLnNldFB1c2hMZXZlbChMZXZlbC5PRkYpOworICAgICAgICBpbnN0YW5jZS5zZXRQdXNoRmlsdGVyKChGaWx0ZXIpIG51bGwpOworICAgICAgICBGbGlwRmxvcEZpbHRlciBiYWRGaWx0ZXIgPSBuZXcgRmxpcEZsb3BGaWx0ZXIoKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0RmlsdGVyKGJhZEZpbHRlcik7CisgICAgICAgIGluc3RhbmNlLnNldEF0dGFjaG1lbnRGb3JtYXR0ZXJzKG5ldyBTaW1wbGVGb3JtYXR0ZXIoKSk7CisKKyAgICAgICAgSW50ZXJuYWxFcnJvck1hbmFnZXIgZW0gPSBuZXcgSW50ZXJuYWxFcnJvck1hbmFnZXIoKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0RXJyb3JNYW5hZ2VyKGVtKTsKKworICAgICAgICBMb2dSZWNvcmQgcmVjb3JkID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICJsb3N0IHJlY29yZCIpOworCisgICAgICAgIGFzc2VydFNhbWUoYmFkRmlsdGVyLCBpbnN0YW5jZS5nZXRGaWx0ZXIoKSk7CisgICAgICAgIGJhZEZpbHRlci52YWx1ZSA9IHRydWU7CisgICAgICAgIGFzc2VydFNhbWUoYmFkRmlsdGVyLCBpbnN0YW5jZS5nZXRGaWx0ZXIoKSk7CisKKyAgICAgICAgYXNzZXJ0VHJ1ZShpbnN0YW5jZS5pc0xvZ2dhYmxlKHJlY29yZCkpOworICAgICAgICBpbnN0YW5jZS5wdWJsaXNoKHJlY29yZCk7CisgICAgICAgIGJhZEZpbHRlci52YWx1ZSA9IGZhbHNlOworCisgICAgICAgIGFzc2VydFNhbWUoYmFkRmlsdGVyLCBpbnN0YW5jZS5nZXRGaWx0ZXIoKSk7CisgICAgICAgIGFzc2VydEZhbHNlKGluc3RhbmNlLmlzTG9nZ2FibGUocmVjb3JkKSk7CisgICAgICAgIGluc3RhbmNlLmNsb3NlKCk7CisgICAgICAgIGFzc2VydFNhbWUoYmFkRmlsdGVyLCBpbnN0YW5jZS5nZXRGaWx0ZXIoKSk7CisKKyAgICAgICAgaW50IHNlZW5Gb3JtYXQgPSAwOworICAgICAgICBmb3IgKEV4Y2VwdGlvbiBleGNlcHRpb24gOiBlbS5leGNlcHRpb25zKSB7CisgICAgICAgICAgICBpZiAoZXhjZXB0aW9uIGluc3RhbmNlb2YgTWVzc2FnaW5nRXhjZXB0aW9uKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGV4Y2VwdGlvbiBpbnN0YW5jZW9mIFJ1bnRpbWVFeGNlcHRpb24KKyAgICAgICAgICAgICAgICAgICAgJiYgZXhjZXB0aW9uLmdldE1lc3NhZ2UoKS5jb250YWlucyhpbnN0YW5jZS5nZXRGaWx0ZXIoKS50b1N0cmluZygpKSkgeworICAgICAgICAgICAgICAgIHNlZW5Gb3JtYXQrKzsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsgLy9leHBlY3RlZC4KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZmFpbChTdHJpbmcudmFsdWVPZihleGNlcHRpb24pKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKCJObyBmb3JtYXQgZXJyb3IiLCBzZWVuRm9ybWF0ID4gMCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RmlsdGVyUmVlbnRyYW5jZSgpIHsKKyAgICAgICAgTG9nZ2VyIGxvZ2dlciA9IExvZ2dlci5nZXRMb2dnZXIoInRlc3RGaWx0ZXJSZWVudHJhbmNlIik7CisKKyAgICAgICAgTWFpbEhhbmRsZXIgaW5zdGFuY2UgPSBuZXcgTWFpbEhhbmRsZXIoMik7CisgICAgICAgIGluc3RhbmNlLnNldE1haWxQcm9wZXJ0aWVzKGNyZWF0ZUluaXRQcm9wZXJ0aWVzKCIiKSk7CisgICAgICAgIEludGVybmFsRXJyb3JNYW5hZ2VyIGVtID0gbmV3IEludGVybmFsRXJyb3JNYW5hZ2VyKCk7CisgICAgICAgIGluc3RhbmNlLnNldEVycm9yTWFuYWdlcihlbSk7CisgICAgICAgIGluc3RhbmNlLnNldEZpbHRlcihuZXcgUmVlbnRyYW5jZUZpbHRlcigpKTsKKworICAgICAgICBsb2dnZXIuc2V0VXNlUGFyZW50SGFuZGxlcnMoZmFsc2UpOworICAgICAgICBsb2dnZXIuc2V0TGV2ZWwoTGV2ZWwuQUxMKTsKKyAgICAgICAgbG9nZ2VyLmFkZEhhbmRsZXIoaW5zdGFuY2UpOworICAgICAgICBoYXJkUmVmID0gbG9nZ2VyOworICAgICAgICB0cnkgeworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChoYXJkUmVmKTsKKyAgICAgICAgICAgIGxvZ2dlci5sb2dwKExldmVsLlNFVkVSRSwgTWFpbEhhbmRsZXJUZXN0LmNsYXNzLmdldE5hbWUoKSwgInRlc3RGaWx0ZXJSZWVudHJhbmNlIiwgInRlc3QiKTsKKworICAgICAgICAgICAgaW50IHNlZW5Jc2UgPSAwOworICAgICAgICAgICAgZm9yIChFeGNlcHRpb24gZXhjZXB0aW9uIDogZW0uZXhjZXB0aW9ucykgeworICAgICAgICAgICAgICAgIGlmIChleGNlcHRpb24gaW5zdGFuY2VvZiBNZXNzYWdpbmdFeGNlcHRpb24pIHsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChleGNlcHRpb24gaW5zdGFuY2VvZiBJbGxlZ2FsU3RhdGVFeGNlcHRpb24pIHsKKyAgICAgICAgICAgICAgICAgICAgc2VlbklzZSsrOworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsgLy9leHBlY3RlZC4KKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBmYWlsKFN0cmluZy52YWx1ZU9mKGV4Y2VwdGlvbikpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiTm8gSWxsZWdhbFN0YXRlRXhjZXB0aW9uIiwgc2VlbklzZSA+IDApOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgbG9nZ2VyLnJlbW92ZUhhbmRsZXIoaW5zdGFuY2UpOworICAgICAgICAgICAgbG9nZ2VyLnNldExldmVsKChMZXZlbCkgbnVsbCk7CisgICAgICAgICAgICBsb2dnZXIuc2V0VXNlUGFyZW50SGFuZGxlcnModHJ1ZSk7CisgICAgICAgICAgICBoYXJkUmVmID0gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFB1c2hGaWx0ZXJSZWVudHJhbmNlKCkgeworICAgICAgICB0ZXN0UHVzaEZpbHRlclJlZW50cmFuY2UoMSwgMSk7CisgICAgICAgIHRlc3RQdXNoRmlsdGVyUmVlbnRyYW5jZSgxLCAyKTsKKyAgICAgICAgdGVzdFB1c2hGaWx0ZXJSZWVudHJhbmNlKDEsIDEwMDApOworICAgICAgICB0ZXN0UHVzaEZpbHRlclJlZW50cmFuY2UoNTAwLCAxMDAwKTsKKyAgICAgICAgdGVzdFB1c2hGaWx0ZXJSZWVudHJhbmNlKDEwMDAsIDEwMDApOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0UHVzaEZpbHRlclJlZW50cmFuY2UoaW50IHJlY29yZHMsIGludCBjYXApIHsKKyAgICAgICAgYXNzZXJ0IHJlY29yZHMgPD0gY2FwIDogcmVjb3JkczsKKyAgICAgICAgTG9nZ2VyIGxvZ2dlciA9IExvZ2dlci5nZXRMb2dnZXIoInRlc3RQdXNoRmlsdGVyUmVlbnRyYW5jZSIpOworCisgICAgICAgIE1haWxIYW5kbGVyIGluc3RhbmNlID0gbmV3IE1haWxIYW5kbGVyKGNhcCk7CisKKyAgICAgICAgUHJvcGVydGllcyBwcm9wcyA9IGNyZWF0ZUluaXRQcm9wZXJ0aWVzKCIiKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0TWFpbFByb3BlcnRpZXMocHJvcHMpOworCisgICAgICAgIEludGVybmFsRXJyb3JNYW5hZ2VyIGVtID0gbmV3IEludGVybmFsRXJyb3JNYW5hZ2VyKCk7CisgICAgICAgIGluc3RhbmNlLnNldEVycm9yTWFuYWdlcihlbSk7CisgICAgICAgIGluc3RhbmNlLnNldFB1c2hMZXZlbChMZXZlbC5BTEwpOworICAgICAgICBpbnN0YW5jZS5zZXRQdXNoRmlsdGVyKG5ldyBSZWVudHJhbmNlRmlsdGVyKCkpOworCisgICAgICAgIGxvZ2dlci5zZXRVc2VQYXJlbnRIYW5kbGVycyhmYWxzZSk7CisgICAgICAgIGxvZ2dlci5zZXRMZXZlbChMZXZlbC5BTEwpOworICAgICAgICBsb2dnZXIuYWRkSGFuZGxlcihpbnN0YW5jZSk7CisgICAgICAgIGhhcmRSZWYgPSBsb2dnZXI7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGhhcmRSZWYpOworCisgICAgICAgICAgICB3aGlsZSAocmVjb3Jkcy0tID4gMCkgeworICAgICAgICAgICAgICAgIGxvZ2dlci5sb2dwKExldmVsLlNFVkVSRSwgTWFpbEhhbmRsZXJUZXN0LmNsYXNzLmdldE5hbWUoKSwgInRlc3RQdXNoRmlsdGVyUmVlbnRyYW5jZSIsICJ0ZXN0Iik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpbnN0YW5jZS5jbG9zZSgpOworCisgICAgICAgICAgICBmb3IgKEV4Y2VwdGlvbiBleGNlcHRpb24gOiBlbS5leGNlcHRpb25zKSB7CisgICAgICAgICAgICAgICAgVGhyb3dhYmxlIHQgPSBleGNlcHRpb247CisgICAgICAgICAgICAgICAgaWYgKCh0IGluc3RhbmNlb2YgTWVzc2FnaW5nRXhjZXB0aW9uID09IGZhbHNlKQorICAgICAgICAgICAgICAgICAgICAgICAgJiYgKHQgaW5zdGFuY2VvZiBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gPT0gZmFsc2UpKSB7CisgICAgICAgICAgICAgICAgICAgIGR1bXAodCk7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoU3RyaW5nLnZhbHVlT2YodCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGVtLmV4Y2VwdGlvbnMuaXNFbXB0eSgpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGxvZ2dlci5yZW1vdmVIYW5kbGVyKGluc3RhbmNlKTsKKyAgICAgICAgICAgIGxvZ2dlci5zZXRMZXZlbCgoTGV2ZWwpIG51bGwpOworICAgICAgICAgICAgbG9nZ2VyLnNldFVzZVBhcmVudEhhbmRsZXJzKHRydWUpOworICAgICAgICAgICAgaGFyZFJlZiA9IG51bGw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RNYWlsRGVidWdMb3dDYXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTWFpbEhhbmRsZXIgaW5zdGFuY2UgPSBuZXcgTWFpbEhhbmRsZXIoMSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0ZXN0TWFpbERlYnVnKGluc3RhbmNlLCAyKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGluc3RhbmNlLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RNYWlsRGVidWdQdXNoTGV2ZWwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTWFpbEhhbmRsZXIgaW5zdGFuY2UgPSBuZXcgTWFpbEhhbmRsZXIoMTAwMCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpbnN0YW5jZS5zZXRQdXNoTGV2ZWwoTGV2ZWwuQUxMKTsKKyAgICAgICAgICAgIHRlc3RNYWlsRGVidWcoaW5zdGFuY2UsIDIpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdE1haWxEZWJ1Z1B1c2goKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTWFpbEhhbmRsZXIgaW5zdGFuY2UgPSBuZXcgTWFpbEhhbmRsZXIoNCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0ZXN0TWFpbERlYnVnKGluc3RhbmNlLCAtMyk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpbnN0YW5jZS5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWFpbERlYnVnRmx1c2goKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTWFpbEhhbmRsZXIgaW5zdGFuY2UgPSBuZXcgTWFpbEhhbmRsZXIoMyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0ZXN0TWFpbERlYnVnKGluc3RhbmNlLCAtMik7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpbnN0YW5jZS5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWFpbERlYnVnQ2xvc2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTWFpbEhhbmRsZXIgaW5zdGFuY2UgPSBuZXcgTWFpbEhhbmRsZXIoMTAwMCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0ZXN0TWFpbERlYnVnKGluc3RhbmNlLCAtMSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpbnN0YW5jZS5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWFpbERlYnVnRXJyb3JNYW5hZ2VyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1haWxIYW5kbGVyIGluc3RhbmNlID0gbmV3IE1haWxIYW5kbGVyKDEpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW5zdGFuY2Uuc2V0RXJyb3JNYW5hZ2VyKG5ldyBNYWlsRGVidWdFcnJvck1hbmFnZXIoKSk7CisgICAgICAgICAgICB0ZXN0TWFpbERlYnVnKGluc3RhbmNlLCAyKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGluc3RhbmNlLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdE1haWxEZWJ1ZyhNYWlsSGFuZGxlciBpbnN0YW5jZSwgaW50IHJlY29yZHMpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBQcm9wZXJ0aWVzIHByb3BzID0gY3JlYXRlSW5pdFByb3BlcnRpZXMoIiIpOworICAgICAgICBwcm9wcy5wdXQoIm1haWwuZGVidWciLCAidHJ1ZSIpOworICAgICAgICBwcm9wcy5wdXQoInZlcmlmeSIsICJsb2NhbCIpOworCisgICAgICAgIGluc3RhbmNlLnNldExldmVsKExldmVsLkFMTCk7CisgICAgICAgIHRlc3RNYWlsRGVidWdRdWlldExvZyhpbnN0YW5jZSwgcHJvcHMsIHJlY29yZHMpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0TWFpbERlYnVnUXVpZXRMb2coTWFpbEhhbmRsZXIgaW5zdGFuY2UsIFByb3BlcnRpZXMgcHJvcHMsIGludCByZWNvcmRzKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgTG9nZ2VyIHJvb3QgPSBMb2dnZXIuZ2V0TG9nZ2VyKCIiKTsKKyAgICAgICAgaGFyZFJlZiA9IHJvb3Q7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaW5hbCBIYW5kbGVyW10gaGFuZGxlcnMgPSByb290LmdldEhhbmRsZXJzKCk7CisgICAgICAgICAgICBmb3IgKEhhbmRsZXIgaCA6IGhhbmRsZXJzKSB7CisgICAgICAgICAgICAgICAgcm9vdC5yZW1vdmVIYW5kbGVyKGgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICByb290LnNldExldmVsKExldmVsLkFMTCk7CisgICAgICAgICAgICAgICAgcm9vdC5hZGRIYW5kbGVyKGluc3RhbmNlKTsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICB0ZXN0TWFpbERlYnVnUXVpZXRTdHJlYW1zKGluc3RhbmNlLCBwcm9wcywgcmVjb3Jkcyk7CisgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICAgICAgcm9vdC5zZXRMZXZlbChudWxsKTsKKyAgICAgICAgICAgICAgICAgICAgcm9vdC5yZW1vdmVIYW5kbGVyKGluc3RhbmNlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIGZvciAoSGFuZGxlciBoIDogaGFuZGxlcnMpIHsKKyAgICAgICAgICAgICAgICAgICAgcm9vdC5hZGRIYW5kbGVyKGgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGhhcmRSZWYgPSBudWxsOworICAgICAgICB9CisgICAgfQorCisgICAgQFN1cHByZXNzV2FybmluZ3MoIlVzZU9mU3lzdGVtT3V0T3JTeXN0ZW1FcnIiKQorICAgIHByaXZhdGUgdm9pZCB0ZXN0TWFpbERlYnVnUXVpZXRTdHJlYW1zKE1haWxIYW5kbGVyIGluc3RhbmNlLCBQcm9wZXJ0aWVzIHByb3BzLCBpbnQgcmVjb3JkcykgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFByaW50U3RyZWFtIG91dCA9IFN5c3RlbS5vdXQ7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYmFvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgICAgIFN5c3RlbS5zZXRPdXQobmV3IFByaW50U3RyZWFtKGJhb3MsIHRydWUsICJJU08tODg1OS0xIikpOworICAgICAgICAgICAgZmluYWwgUHJpbnRTdHJlYW0gZXJyID0gU3lzdGVtLmVycjsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLnNldEVycihuZXcgUHJpbnRTdHJlYW0oYmFvcywgdHJ1ZSwgIklTTy04ODU5LTEiKSk7CisgICAgICAgICAgICAgICAgaW5zdGFuY2Uuc2V0TWFpbFByb3BlcnRpZXMocHJvcHMpOworCisgICAgICAgICAgICAgICAgaWYgKHJlY29yZHMgPiAwKSB7CisgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVjb3JkczsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBiYW9zLnJlc2V0KCk7CisgICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZS5wdWJsaXNoKG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAiIikpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgcmVjb3JkcyA9IC1yZWNvcmRzOworICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlY29yZHM7IGkrKykgeworICAgICAgICAgICAgICAgICAgICAgICAgYmFvcy5yZXNldCgpOworICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2UucHVibGlzaChuZXcgTG9nUmVjb3JkKExldmVsLlNFVkVSRSwgIiIpKTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIGlmIChyZWNvcmRzID09IDEpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocmVjb3JkcyA9PSAyKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZS5mbHVzaCgpOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHJlY29yZHMgPT0gMykgeworICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2UucHVzaCgpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uc2V0RXJyKGVycik7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBTeXN0ZW0uc2V0T3V0KG91dCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RSZXBvcnRFcnJvcigpIHsKKyAgICAgICAgTWFpbEhhbmRsZXIgaW5zdGFuY2UgPSBuZXcgTWFpbEhhbmRsZXIoY3JlYXRlSW5pdFByb3BlcnRpZXMoIiIpKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0RXJyb3JNYW5hZ2VyKG5ldyBFcnJvck1hbmFnZXIoKSB7CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIHZvaWQgZXJyb3IoU3RyaW5nIG1zZywgRXhjZXB0aW9uIGV4LCBpbnQgY29kZSkgeworICAgICAgICAgICAgICAgIGFzc2VydE51bGwobXNnKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisKKyAgICAgICAgaW5zdGFuY2UucmVwb3J0RXJyb3IobnVsbCwgbnVsbCwgRXJyb3JNYW5hZ2VyLkdFTkVSSUNfRkFJTFVSRSk7CisKKyAgICAgICAgaW5zdGFuY2Uuc2V0RXJyb3JNYW5hZ2VyKG5ldyBFcnJvck1hbmFnZXIoKSB7CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIHZvaWQgZXJyb3IoU3RyaW5nIG1zZywgRXhjZXB0aW9uIGV4LCBpbnQgY29kZSkgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhtc2cuaW5kZXhPZihMZXZlbC5TRVZFUkUuZ2V0TmFtZSgpKSwgMCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0pOworCisgICAgICAgIGluc3RhbmNlLnJlcG9ydEVycm9yKCJzaW1wbGUgbWVzc2FnZS4iLCBudWxsLCBFcnJvck1hbmFnZXIuR0VORVJJQ19GQUlMVVJFKTsKKyAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKworICAgICAgICAvL1Rlc3QgZm9yIHZhbGlkIG1lc3NhZ2UuCisgICAgICAgIGluc3RhbmNlID0gY3JlYXRlSGFuZGxlcldpdGhSZWNvcmRzKCk7CisgICAgICAgIGluc3RhbmNlLnNldEVycm9yTWFuYWdlcihuZXcgTWVzc2FnZUVycm9yTWFuYWdlcihpbnN0YW5jZS5nZXRNYWlsUHJvcGVydGllcygpKSB7CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHJvdGVjdGVkIHZvaWQgZXJyb3IoTWltZU1lc3NhZ2UgbWVzc2FnZSwgVGhyb3dhYmxlIHQsIGludCBjb2RlKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShtZXNzYWdlLmdldEhlYWRlcigiWC1NYWlsZXIiKVswXS5zdGFydHNXaXRoKE1haWxIYW5kbGVyLmNsYXNzLmdldE5hbWUoKSkpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKG51bGwgIT0gbWVzc2FnZS5nZXRTZW50RGF0ZSgpKTsKKyAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5zYXZlQ2hhbmdlcygpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBNRSkgeworICAgICAgICAgICAgICAgICAgICBmYWlsKE1FLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisgICAgICAgIGluc3RhbmNlLmNsb3NlKCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVwb3J0RXJyb3JVdGY4QWRkcmVzc2VzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFN0cmluZyB0ZXN0ID0gInRlc3RcdTAzYjEiOworICAgICAgICBmaW5hbCBTdHJpbmcgc2FkZHIgPSB0ZXN0ICsgJ0AnICsgVU5LTk9XTl9IT1NUOworICAgICAgICBmaW5hbCBTdHJpbmcgc2VuZGVyID0gdGVzdCArIHNhZGRyOworICAgICAgICBQcm9wZXJ0aWVzIHByb3BzID0gY3JlYXRlSW5pdFByb3BlcnRpZXMoIiIpOworICAgICAgICBwcm9wcy5wdXQoIm1haWwudG8iLCBzYWRkcik7CisgICAgICAgIHByb3BzLnB1dCgibWFpbC5jYyIsIHNhZGRyKTsKKyAgICAgICAgcHJvcHMucHV0KCJtYWlsLmJjYyIsIHNhZGRyKTsKKyAgICAgICAgcHJvcHMucHV0KCJtYWlsLmZyb20iLCBzYWRkcik7CisgICAgICAgIHByb3BzLnB1dCgibWFpbC5zZW5kZXIiLCBzZW5kZXIpOworICAgICAgICBwcm9wcy5wdXQoIm1haWwubWltZS5hbGxvd3V0ZjgiLCAgInRydWUiKTsKKyAgICAgICAgTWFpbEhhbmRsZXIgaW5zdGFuY2UgPSBuZXcgTWFpbEhhbmRsZXIocHJvcHMpOworICAgICAgICBpbnN0YW5jZS5zZXRFbmNvZGluZygiVVRGLTgiKTsKKyAgICAgICAgaW5zdGFuY2Uuc2V0Rm9ybWF0dGVyKG5ldyBTaW1wbGVGb3JtYXR0ZXIoKSk7CisgICAgICAgIGluc3RhbmNlLnNldEVycm9yTWFuYWdlcihuZXcgTWVzc2FnZUVycm9yTWFuYWdlcihpbnN0YW5jZS5nZXRNYWlsUHJvcGVydGllcygpKSB7CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHJvdGVjdGVkIHZvaWQgZXJyb3IoTWltZU1lc3NhZ2UgbWVzc2FnZSwgVGhyb3dhYmxlIHQsIGludCBjb2RlKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHNhZGRyLCB0b1N0cmluZyhtZXNzYWdlLmdldEZyb20oKVswXSkpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoc2FkZHIsIHRvU3RyaW5nKG1lc3NhZ2UuZ2V0UmVjaXBpZW50cyhNZXNzYWdlLlJlY2lwaWVudFR5cGUuVE8pWzBdKSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhzYWRkciwgdG9TdHJpbmcobWVzc2FnZS5nZXRSZWNpcGllbnRzKE1lc3NhZ2UuUmVjaXBpZW50VHlwZS5DQylbMF0pKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHNhZGRyLCB0b1N0cmluZyhtZXNzYWdlLmdldFJlY2lwaWVudHMoTWVzc2FnZS5SZWNpcGllbnRUeXBlLkJDQylbMF0pKTsKKworICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoc2VuZGVyLCB0b1N0cmluZyhtZXNzYWdlLmdldFNlbmRlcigpKSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUoU3RyaW5nLnZhbHVlT2YobWVzc2FnZS5nZXRDb250ZW50KCkpLmNvbnRhaW5zKHNlbmRlcikpOworCisgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2Uuc2F2ZUNoYW5nZXMoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChNZXNzYWdpbmdFeGNlcHRpb24gfCBJT0V4Y2VwdGlvbiBFKSB7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoRS50b1N0cmluZygpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHByaXZhdGUgU3RyaW5nIHRvU3RyaW5nKEFkZHJlc3MgbykgeworICAgICAgICAgICAgICAgIHJldHVybiAoKEludGVybmV0QWRkcmVzcylvKS50b1VuaWNvZGVTdHJpbmcoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisgICAgICAgIGluc3RhbmNlLnB1Ymxpc2gobmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsIHNlbmRlcikpOworICAgICAgICBpbnN0YW5jZS5jbG9zZSgpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFJlcG9ydEVycm9yU3VwZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0TnVsbChTeXN0ZW0uZ2V0U2VjdXJpdHlNYW5hZ2VyKCkpOworICAgICAgICBGaWVsZCBtaGVtID0gTWFpbEhhbmRsZXIuY2xhc3MuZ2V0RGVjbGFyZWRGaWVsZCgiZXJyb3JNYW5hZ2VyIik7CisgICAgICAgIG1oZW0uc2V0QWNjZXNzaWJsZSh0cnVlKTsKKworICAgICAgICBJbnRlcm5hbEVycm9yTWFuYWdlciBzdXBlckVtID0gbmV3IEludGVybmFsRXJyb3JNYW5hZ2VyKCk7CisgICAgICAgIEludGVybmFsRXJyb3JNYW5hZ2VyIGVtID0gbmV3IEludGVybmFsRXJyb3JNYW5hZ2VyKCk7CisgICAgICAgIE1haWxIYW5kbGVyIGggPSBuZXcgTWFpbEhhbmRsZXIoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEV4Y2VwdGlvbiB0ZXN0ZXIgPSBuZXcgRXhjZXB0aW9uKCk7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKGgpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnRTYW1lKGguZ2V0RXJyb3JNYW5hZ2VyKCksIGdldFN1cGVyRXJyb3JNYW5hZ2VyKGgpKTsKKworICAgICAgICAgICAgICAgIGguc2V0RXJyb3JNYW5hZ2VyKHN1cGVyRW0pOworICAgICAgICAgICAgICAgIGFzc2VydFNhbWUoc3VwZXJFbSwgZ2V0U3VwZXJFcnJvck1hbmFnZXIoaCkpOworICAgICAgICAgICAgICAgIGFzc2VydFNhbWUoc3VwZXJFbSwgbWhlbS5nZXQoaCkpOworCisgICAgICAgICAgICAgICAgbWhlbS5zZXQoaCwgZW0pOworICAgICAgICAgICAgICAgIGFzc2VydFNhbWUoZW0sIGguZ2V0RXJyb3JNYW5hZ2VyKCkpOworICAgICAgICAgICAgICAgIGFzc2VydFNhbWUoc3VwZXJFbSwgZ2V0U3VwZXJFcnJvck1hbmFnZXIoaCkpOworICAgICAgICAgICAgICAgIGFzc2VydE5vdFNhbWUoaC5nZXRFcnJvck1hbmFnZXIoKSwgZ2V0U3VwZXJFcnJvck1hbmFnZXIoaCkpOworICAgICAgICAgICAgICAgIGgucmVwb3J0RXJyb3IoIiIsIHRlc3RlciwgRXJyb3JNYW5hZ2VyLkdFTkVSSUNfRkFJTFVSRSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBlbS5leGNlcHRpb25zLnNpemUoKSk7CisgICAgICAgICAgICBhc3NlcnRTYW1lKHRlc3RlciwgZW0uZXhjZXB0aW9ucy5nZXQoMCkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShzdXBlckVtLmV4Y2VwdGlvbnMudG9TdHJpbmcoKSwKKyAgICAgICAgICAgICAgICAgICAgc3VwZXJFbS5leGNlcHRpb25zLmlzRW1wdHkoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBoLmNsb3NlKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RHYWVSZXBvcnRFcnJvclN1cGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEZpZWxkIG1oZW0gPSBNYWlsSGFuZGxlci5jbGFzcy5nZXREZWNsYXJlZEZpZWxkKCJlcnJvck1hbmFnZXIiKTsKKyAgICAgICAgbWhlbS5zZXRBY2Nlc3NpYmxlKHRydWUpOworCisgICAgICAgIEludGVybmFsRXJyb3JNYW5hZ2VyIGVtID0gbmV3IEludGVybmFsRXJyb3JNYW5hZ2VyKCk7CisgICAgICAgIEdhZVNlY3VyaXR5TWFuYWdlciBzbSA9IG5ldyBHYWVTZWN1cml0eU1hbmFnZXIoKTsKKyAgICAgICAgU3lzdGVtLnNldFNlY3VyaXR5TWFuYWdlcihzbSk7CisgICAgICAgIHNtLnNlY3VyZSA9IHRydWU7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBNYWlsSGFuZGxlciBoID0gbmV3IE1haWxIYW5kbGVyKCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEV4Y2VwdGlvbiB0ZXN0ZXIgPSBuZXcgRXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgc3luY2hyb25pemVkIChoKSB7CisgICAgICAgICAgICAgICAgICAgIHNtLnNlY3VyZSA9IGZhbHNlOworICAgICAgICAgICAgICAgICAgICBmaW5hbCBPYmplY3QgZGVmID0gZ2V0U3VwZXJFcnJvck1hbmFnZXIoaCk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFNhbWUoZGVmLCBnZXRTdXBlckVycm9yTWFuYWdlcihoKSk7CisgICAgICAgICAgICAgICAgICAgIHNtLnNlY3VyZSA9IHRydWU7CisKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGguZ2V0RXJyb3JNYW5hZ2VyKCkuZ2V0Q2xhc3MoKSwgZGVmLmdldENsYXNzKCkpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnROb3RTYW1lKGguZ2V0RXJyb3JNYW5hZ2VyKCksIGRlZik7CisKKyAgICAgICAgICAgICAgICAgICAgaC5zZXRFcnJvck1hbmFnZXIoZW0pOworICAgICAgICAgICAgICAgICAgICBzbS5zZWN1cmUgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgT2JqZWN0IHNlbSA9IGdldFN1cGVyRXJyb3JNYW5hZ2VyKGgpOworICAgICAgICAgICAgICAgICAgICBzbS5zZWN1cmUgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRTYW1lKGRlZiwgc2VtKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0Tm90U2FtZShoLmdldEVycm9yTWFuYWdlcigpLCBkZWYpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnROb3RTYW1lKGguZ2V0RXJyb3JNYW5hZ2VyKCksIHNlbSk7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFNhbWUoaC5nZXRFcnJvck1hbmFnZXIoKSwgZW0pOworCisgICAgICAgICAgICAgICAgICAgIGgucmVwb3J0RXJyb3IoIiIsIHRlc3RlciwgRXJyb3JNYW5hZ2VyLkdFTkVSSUNfRkFJTFVSRSk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGVtLmV4Y2VwdGlvbnMuc2l6ZSgpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRTYW1lKHRlc3RlciwgZW0uZXhjZXB0aW9ucy5nZXQoMCkpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBoLmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBzbS5zZWN1cmUgPSBmYWxzZTsKKyAgICAgICAgICAgIFN5c3RlbS5zZXRTZWN1cml0eU1hbmFnZXIoKFNlY3VyaXR5TWFuYWdlcikgbnVsbCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RSZXBvcnRFcnJvckxpbmthZ2VXaXRoU3RhY2soKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGVzdFJlcG9ydEVycm9yTGlua2FnZVdpdGhTdGFjayhuZXcgTGlua2FnZUVycm9yU3RyZWFtKCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFJlcG9ydEVycm9yUnVudGltZVdpdGhTdGFjaygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0UmVwb3J0RXJyb3JMaW5rYWdlV2l0aFN0YWNrKG5ldyBSdW50aW1lRXJyb3JTdHJlYW0oKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RSZXBvcnRFcnJvckxpbmthZ2VXaXRoU3RhY2soUHJpbnRTdHJlYW0gcHMpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBNYWlsSGFuZGxlciBpbnN0YW5jZSA9IG5ldyBNYWlsSGFuZGxlcihjcmVhdGVJbml0UHJvcGVydGllcygiIikpOworCisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJVc2VPZlN5c3RlbU91dE9yU3lzdGVtRXJyIikKKyAgICAgICAgZmluYWwgUHJpbnRTdHJlYW0gZXJyID0gU3lzdGVtLmVycjsKKyAgICAgICAgU3lzdGVtLnNldEVycihwcyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGluc3RhbmNlLnNldEVycm9yTWFuYWdlcihuZXcgRXJyb3JNYW5hZ2VyKCkpOworICAgICAgICAgICAgICAgIGluc3RhbmNlLnJlcG9ydEVycm9yKG51bGwsIG51bGwsIEVycm9yTWFuYWdlci5DTE9TRV9GQUlMVVJFKTsKKworICAgICAgICAgICAgICAgIGluc3RhbmNlLnNldEVycm9yTWFuYWdlcihuZXcgRXJyb3JNYW5hZ2VyKCkpOworICAgICAgICAgICAgICAgIGluc3RhbmNlLnJlcG9ydEVycm9yKG51bGwsIG51bGwsIEVycm9yTWFuYWdlci5GTFVTSF9GQUlMVVJFKTsKKworICAgICAgICAgICAgICAgIGluc3RhbmNlLnNldEVycm9yTWFuYWdlcihuZXcgRXJyb3JNYW5hZ2VyKCkpOworICAgICAgICAgICAgICAgIGluc3RhbmNlLnJlcG9ydEVycm9yKG51bGwsIG51bGwsIEVycm9yTWFuYWdlci5HRU5FUklDX0ZBSUxVUkUpOworCisgICAgICAgICAgICAgICAgaW5zdGFuY2Uuc2V0RXJyb3JNYW5hZ2VyKG5ldyBFcnJvck1hbmFnZXIoKSk7CisgICAgICAgICAgICAgICAgaW5zdGFuY2UucmVwb3J0RXJyb3IobnVsbCwgbnVsbCwgRXJyb3JNYW5hZ2VyLk9QRU5fRkFJTFVSRSk7CisKKyAgICAgICAgICAgICAgICBpbnN0YW5jZS5zZXRFcnJvck1hbmFnZXIobmV3IEVycm9yTWFuYWdlcigpKTsKKyAgICAgICAgICAgICAgICBpbnN0YW5jZS5yZXBvcnRFcnJvcihudWxsLCBudWxsLCBFcnJvck1hbmFnZXIuV1JJVEVfRkFJTFVSRSk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIFN5c3RlbS5zZXRFcnIoZXJyKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoUHJpbnRUaHJvd3NSdW50aW1lRXhjZXB0aW9uIHVuZXhwZWN0ZWQpIHsKKyAgICAgICAgICAgIHVuZXhwZWN0ZWQuZHVtcCgpOworICAgICAgICAgICAgZmFpbCh1bmV4cGVjdGVkLmdldE1lc3NhZ2UoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RSZXBvcnRFcnJvckxpbmthZ2VFbXB0eVN0YWNrKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHRlc3RSZXBvcnRFcnJvckxpbmthZ2VFbXB0eVN0YWNrKAorICAgICAgICAgICAgICAgIG5ldyBMaW5rYWdlRXJyb3JTdHJlYW0obmV3IFN0YWNrVHJhY2VFbGVtZW50WzBdKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVwb3J0RXJyb3JMaW5rYWdlU2hvcnRTdGFjaygpIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICB0ZXN0UmVwb3J0RXJyb3JMaW5rYWdlRW1wdHlTdGFjaygKKyAgICAgICAgICAgICAgICBuZXcgTGlua2FnZUVycm9yU3RyZWFtKG5ldyBTdGFja1RyYWNlRWxlbWVudFtdeworICAgICAgICAgICAgICAgICAgICBuZXcgU3RhY2tUcmFjZUVsZW1lbnQoIiIsICIiLCAiIiwgLTEpfSkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFJlcG9ydEVycm9yUnVudGltZUVtcHR5U3RhY2soKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgdGVzdFJlcG9ydEVycm9yTGlua2FnZUVtcHR5U3RhY2soCisgICAgICAgICAgICAgICAgbmV3IFJ1bnRpbWVFcnJvclN0cmVhbShuZXcgU3RhY2tUcmFjZUVsZW1lbnRbMF0pKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RSZXBvcnRFcnJvclJ1bnRpbWVTaG9ydFN0YWNrKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIHRlc3RSZXBvcnRFcnJvckxpbmthZ2VFbXB0eVN0YWNrKAorICAgICAgICAgICAgICAgIG5ldyBSdW50aW1lRXJyb3JTdHJlYW0obmV3IFN0YWNrVHJhY2VFbGVtZW50W117CisgICAgICAgICAgICAgICAgICAgIG5ldyBTdGFja1RyYWNlRWxlbWVudCgiIiwgIiIsICIiLCAtMSl9KSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RSZXBvcnRFcnJvckxpbmthZ2VFbXB0eVN0YWNrKFByaW50U3RyZWFtIHBzKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgTWFpbEhhbmRsZXIgaW5zdGFuY2UgPSBuZXcgTWFpbEhhbmRsZXIoY3JlYXRlSW5pdFByb3BlcnRpZXMoIiIpKTsKKworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygiVXNlT2ZTeXN0ZW1PdXRPclN5c3RlbUVyciIpCisgICAgICAgIGZpbmFsIFByaW50U3RyZWFtIGVyciA9IFN5c3RlbS5lcnI7CisgICAgICAgIFN5c3RlbS5zZXRFcnIocHMpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpbnN0YW5jZS5zZXRFcnJvck1hbmFnZXIobmV3IEVycm9yTWFuYWdlcigpKTsKKyAgICAgICAgICAgICAgICBpbnN0YW5jZS5yZXBvcnRFcnJvcihudWxsLCBudWxsLCBFcnJvck1hbmFnZXIuRkxVU0hfRkFJTFVSRSk7CisKKyAgICAgICAgICAgICAgICBpbnN0YW5jZS5zZXRFcnJvck1hbmFnZXIobmV3IEVycm9yTWFuYWdlcigpKTsKKyAgICAgICAgICAgICAgICBpbnN0YW5jZS5yZXBvcnRFcnJvcihudWxsLCBudWxsLCBFcnJvck1hbmFnZXIuQ0xPU0VfRkFJTFVSRSk7CisKKyAgICAgICAgICAgICAgICBpbnN0YW5jZS5zZXRFcnJvck1hbmFnZXIobmV3IEVycm9yTWFuYWdlcigpKTsKKyAgICAgICAgICAgICAgICBpbnN0YW5jZS5yZXBvcnRFcnJvcihudWxsLCBudWxsLCBFcnJvck1hbmFnZXIuR0VORVJJQ19GQUlMVVJFKTsKKworICAgICAgICAgICAgICAgIGluc3RhbmNlLnNldEVycm9yTWFuYWdlcihuZXcgRXJyb3JNYW5hZ2VyKCkpOworICAgICAgICAgICAgICAgIGluc3RhbmNlLnJlcG9ydEVycm9yKG51bGwsIG51bGwsIEVycm9yTWFuYWdlci5PUEVOX0ZBSUxVUkUpOworCisgICAgICAgICAgICAgICAgaW5zdGFuY2Uuc2V0RXJyb3JNYW5hZ2VyKG5ldyBFcnJvck1hbmFnZXIoKSk7CisgICAgICAgICAgICAgICAgaW5zdGFuY2UucmVwb3J0RXJyb3IobnVsbCwgbnVsbCwgRXJyb3JNYW5hZ2VyLldSSVRFX0ZBSUxVUkUpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uc2V0RXJyKGVycik7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKFByaW50VGhyb3dzUnVudGltZUV4Y2VwdGlvbiB1bmV4cGVjdGVkKSB7CisgICAgICAgICAgICB1bmV4cGVjdGVkLmR1bXAoKTsKKyAgICAgICAgICAgIGZhaWwodW5leHBlY3RlZC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgQElnbm9yZQorICAgIHB1YmxpYyB2b2lkIHRlc3RHYWVGb3JiaWRkZW5IZWFkZXJzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc3VtZU5vSml0KCk7CisgICAgICAgIGFzc2VydE51bGwoU3lzdGVtLmdldFNlY3VyaXR5TWFuYWdlcigpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShMb2dNYW5hZ2VyUHJvcGVydGllcy5oYXNMb2dNYW5hZ2VyKCkpOworICAgICAgICBmaW5hbCBDbGFzczw/PiBrID0gTG9nTWFuYWdlclByb3BlcnRpZXMuY2xhc3M7CisgICAgICAgIGZpbmFsIEZpZWxkIGYgPSBrLmdldERlY2xhcmVkRmllbGQoIkxPR19NQU5BR0VSIik7CisgICAgICAgIGZpbmFsIEZpZWxkIG1vZCA9IHNldEFjY2Vzc2libGUoZik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaW5hbCBPYmplY3QgbG0gPSBmLmdldChudWxsKTsKKyAgICAgICAgICAgIGYuc2V0KG51bGwsIG5ldyBQcm9wZXJ0aWVzKCkpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBmdWxsRmVuY2UoKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRGYWxzZShMb2dNYW5hZ2VyUHJvcGVydGllcy5oYXNMb2dNYW5hZ2VyKCkpOworICAgICAgICAgICAgICAgIE1haWxIYW5kbGVyIGluc3RhbmNlID0gY3JlYXRlSGFuZGxlcldpdGhSZWNvcmRzKCk7CisgICAgICAgICAgICAgICAgaW5zdGFuY2Uuc2V0RXJyb3JNYW5hZ2VyKG5ldyBHYWVFcnJvck1hbmFnZXIoaW5zdGFuY2UpKTsKKyAgICAgICAgICAgICAgICBpbnN0YW5jZS5jbG9zZSgpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBmLnNldChudWxsLCBsbSk7CisgICAgICAgICAgICAgICAgZnVsbEZlbmNlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBtb2Quc2V0SW50KGYsIGYuZ2V0TW9kaWZpZXJzKCkgfCBNb2RpZmllci5GSU5BTCk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZShMb2dNYW5hZ2VyUHJvcGVydGllcy5oYXNMb2dNYW5hZ2VyKCkpOworICAgIH0KKworICAgIEBJZ25vcmUKKyAgICBwdWJsaWMgdm9pZCB0ZXN0R2FlU2VjdXJpdHlNYW5hZ2VyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc3VtZU5vSml0KCk7CisgICAgICAgIEludGVybmFsRXJyb3JNYW5hZ2VyIGVtOworICAgICAgICBNYWlsSGFuZGxlciBoID0gbnVsbDsKKyAgICAgICAgZmluYWwgR2FlU2VjdXJpdHlNYW5hZ2VyIG1hbmFnZXIgPSBuZXcgR2FlU2VjdXJpdHlNYW5hZ2VyKCk7CisgICAgICAgIFN5c3RlbS5zZXRTZWN1cml0eU1hbmFnZXIobWFuYWdlcik7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtYW5hZ2VyLnNlY3VyZSA9IGZhbHNlOworICAgICAgICAgICAgaCA9IG5ldyBNYWlsSGFuZGxlcihjcmVhdGVJbml0UHJvcGVydGllcygiIikpOworICAgICAgICAgICAgZW0gPSBuZXcgSW50ZXJuYWxFcnJvck1hbmFnZXIoKTsKKyAgICAgICAgICAgIGguc2V0RXJyb3JNYW5hZ2VyKGVtKTsKKyAgICAgICAgICAgIG1hbmFnZXIuc2VjdXJlID0gdHJ1ZTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhtYW5hZ2VyLCBTeXN0ZW0uZ2V0U2VjdXJpdHlNYW5hZ2VyKCkpOworCisgICAgICAgICAgICAvL0dBRSBhbGxvd3MgYWNjZXNzIHRvIGxvZ2dlcnMuCisgICAgICAgICAgICBMb2dnZXIgZ2xvYmFsID0gTG9nZ2VyLmdldExvZ2dlcigiZ2xvYmFsIik7CisgICAgICAgICAgICBoYXJkUmVmID0gZ2xvYmFsOworICAgICAgICAgICAgZ2xvYmFsLmFkZEhhbmRsZXIoaCk7CisgICAgICAgICAgICBnbG9iYWwucmVtb3ZlSGFuZGxlcihoKTsKKyAgICAgICAgICAgIGdsb2JhbC5yZW1vdmVIYW5kbGVyKChIYW5kbGVyKSBudWxsKTsKKyAgICAgICAgICAgIGhhcmRSZWYgPSBudWxsOworCisgICAgICAgICAgICBoLnBvc3RDb25zdHJ1Y3QoKTsKKyAgICAgICAgICAgIGguc2V0QXR0YWNobWVudEZvcm1hdHRlcnMobmV3IEZvcm1hdHRlcltde25ldyBUaHJvd0Zvcm1hdHRlcigpfSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgaC5nZXRBdHRhY2htZW50Rm9ybWF0dGVycygpLmxlbmd0aCk7CisKKyAgICAgICAgICAgIGguc2V0QXR0YWNobWVudEZpbHRlcnMobmV3IEZpbHRlcltde25ldyBUaHJvd0ZpbHRlcigpfSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgaC5nZXRBdHRhY2htZW50Rm9ybWF0dGVycygpLmxlbmd0aCk7CisKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBoLmdldEF0dGFjaG1lbnRGb3JtYXR0ZXJzKCkubGVuZ3RoKTsKKyAgICAgICAgICAgIGguc2V0QXR0YWNobWVudE5hbWVzKG5ldyBTdHJpbmdbXXsiZXJyb3IudHh0In0pOworCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgaC5nZXRBdHRhY2htZW50Rm9ybWF0dGVycygpLmxlbmd0aCk7CisgICAgICAgICAgICBoLnNldEF0dGFjaG1lbnROYW1lcyhuZXcgRm9ybWF0dGVyW117bmV3IFRocm93Rm9ybWF0dGVyKCl9KTsKKworICAgICAgICAgICAgaC5zZXRBdXRoZW50aWNhdG9yKChBdXRoZW50aWNhdG9yKSBudWxsKTsKKyAgICAgICAgICAgIGguc2V0Q29tcGFyYXRvcigoQ29tcGFyYXRvcjw/IHN1cGVyIExvZ1JlY29yZD4pIG51bGwpOworCisgICAgICAgICAgICBoLnNldExldmVsKExldmVsLkFMTCk7CisgICAgICAgICAgICBoLnNldEZpbHRlcihCb29sZWFuRmlsdGVyLkZBTFNFKTsKKyAgICAgICAgICAgIGguc2V0RmlsdGVyKChGaWx0ZXIpIG51bGwpOworICAgICAgICAgICAgaC5zZXRGb3JtYXR0ZXIobmV3IEVtcHR5Rm9ybWF0dGVyKCkpOworCisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGguZ2V0RXJyb3JNYW5hZ2VyKCkpOworICAgICAgICAgICAgaC5zZXRFcnJvck1hbmFnZXIobmV3IEVycm9yTWFuYWdlcigpKTsKKworICAgICAgICAgICAgaC5zZXRFbmNvZGluZygoU3RyaW5nKSBudWxsKTsKKworICAgICAgICAgICAgaC5mbHVzaCgpOworICAgICAgICAgICAgaC5wdXNoKCk7CisKKyAgICAgICAgICAgIGguc2V0TWFpbFByb3BlcnRpZXMobmV3IFByb3BlcnRpZXMoKSk7CisKKyAgICAgICAgICAgIGguc2V0UHVzaEZpbHRlcigoRmlsdGVyKSBudWxsKTsKKyAgICAgICAgICAgIGguc2V0UHVzaExldmVsKExldmVsLk9GRik7CisKKyAgICAgICAgICAgIGguc2V0U3ViamVjdChuZXcgVGhyb3dGb3JtYXR0ZXIoKSk7CisgICAgICAgICAgICBoLnNldFN1YmplY3QoInRlc3QiKTsKKworICAgICAgICAgICAgaC5nZXRBdXRoZW50aWNhdG9yKCk7CisgICAgICAgICAgICBoLmdldE1haWxQcm9wZXJ0aWVzKCk7CisKKyAgICAgICAgICAgIGgucHJlRGVzdHJveSgpOworICAgICAgICAgICAgaC5jbG9zZSgpOworCisgICAgICAgICAgICAvL2NoZWNrIGZvciBpbnRlcm5hbCBleGNlcHRpb25zIGNhdXNlZCBieSBzZWN1cml0eSBtYW5hZ2VyLgorICAgICAgICAgICAgZm9yIChFeGNlcHRpb24gZSA6IGVtLmV4Y2VwdGlvbnMpIHsKKyAgICAgICAgICAgICAgICBkdW1wKGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZShlbS5leGNlcHRpb25zLmlzRW1wdHkoKSk7CisKKyAgICAgICAgICAgIGhhcmRSZWYgPSBoID0gbmV3IE1haWxIYW5kbGVyKCk7CisgICAgICAgICAgICBoLmNsb3NlKCk7CisKKyAgICAgICAgICAgIGhhcmRSZWYgPSBoID0gbmV3IE1haWxIYW5kbGVyKDEwMCk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMTAwLCBoLmdldENhcGFjaXR5KCkpOworICAgICAgICAgICAgaC5jbG9zZSgpOworCisgICAgICAgICAgICBQcm9wZXJ0aWVzIHByb3BzID0gbmV3IFByb3BlcnRpZXMoKTsKKyAgICAgICAgICAgIHByb3BzLnB1dCgidGVzdCIsICJ0ZXN0Iik7CisgICAgICAgICAgICBoYXJkUmVmID0gaCA9IG5ldyBNYWlsSGFuZGxlcihwcm9wcyk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMocHJvcHMsIGguZ2V0TWFpbFByb3BlcnRpZXMoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBoYXJkUmVmID0gbnVsbDsKKyAgICAgICAgICAgIG1hbmFnZXIuc2VjdXJlID0gZmFsc2U7CisgICAgICAgICAgICBTeXN0ZW0uc2V0U2VjdXJpdHlNYW5hZ2VyKChTZWN1cml0eU1hbmFnZXIpIG51bGwpOworICAgICAgICAgICAgaWYgKGggIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGguY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgbG9nZ2luZyBwZXJtaXNzaW9ucyBvZiB0aGUgTWFpbEhhbmRsZXIuIE11c3QgcnVuIGJ5IGl0c2VsZiBvciBydW4gaW4KKyAgICAgKiBpc29sYXRlZCBWTS4gVXNlIHN5c3RlbSBwcm9wZXJ0eSBqYXZhLnNlY3VyaXR5LmRlYnVnPWFsbCB0byB0cm91Ymxlc2hvb3QKKyAgICAgKiBmYWlsdXJlcy4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RTZWN1cml0eU1hbmFnZXIoKSB7CisgICAgICAgIEludGVybmFsRXJyb3JNYW5hZ2VyIGVtOworICAgICAgICBNYWlsSGFuZGxlciBoID0gbnVsbDsKKyAgICAgICAgZmluYWwgVGhyb3dTZWN1cml0eU1hbmFnZXIgbWFuYWdlciA9IG5ldyBUaHJvd1NlY3VyaXR5TWFuYWdlcigpOworICAgICAgICBTeXN0ZW0uc2V0U2VjdXJpdHlNYW5hZ2VyKG1hbmFnZXIpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbWFuYWdlci5zZWN1cmUgPSBmYWxzZTsKKyAgICAgICAgICAgIGggPSBuZXcgTWFpbEhhbmRsZXIoY3JlYXRlSW5pdFByb3BlcnRpZXMoIiIpKTsKKyAgICAgICAgICAgIGVtID0gbmV3IEludGVybmFsRXJyb3JNYW5hZ2VyKCk7CisgICAgICAgICAgICBoLnNldEVycm9yTWFuYWdlcihlbSk7CisgICAgICAgICAgICBtYW5hZ2VyLnNlY3VyZSA9IHRydWU7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMobWFuYWdlciwgU3lzdGVtLmdldFNlY3VyaXR5TWFuYWdlcigpKTsKKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgaC5nZXRBdHRhY2htZW50Rm9ybWF0dGVycygpLmxlbmd0aCk7CisgICAgICAgICAgICAgICAgaC5zZXRBdHRhY2htZW50TmFtZXMobmV3IFN0cmluZ1tdeyJlcnJvci50eHQifSk7CisgICAgICAgICAgICAgICAgZmFpbCgiTWlzc2luZyBzZWN1cmUgY2hlY2suIik7CisgICAgICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBwYXNzKSB7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZmFpbCkgeworICAgICAgICAgICAgICAgIGZhaWwoZmFpbC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgaC5nZXRBdHRhY2htZW50Rm9ybWF0dGVycygpLmxlbmd0aCk7CisgICAgICAgICAgICAgICAgaC5zZXRBdHRhY2htZW50TmFtZXMobmV3IEZvcm1hdHRlcltde25ldyBUaHJvd0Zvcm1hdHRlcigpfSk7CisgICAgICAgICAgICAgICAgZmFpbCgiTWlzc2luZyBzZWN1cmUgY2hlY2suIik7CisgICAgICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBwYXNzKSB7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZmFpbCkgeworICAgICAgICAgICAgICAgIGZhaWwoZmFpbC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgaC5nZXRBdHRhY2htZW50Rm9ybWF0dGVycygpLmxlbmd0aCk7CisgICAgICAgICAgICAgICAgaC5zZXRBdHRhY2htZW50RmlsdGVycyhuZXcgRmlsdGVyW117bmV3IFRocm93RmlsdGVyKCl9KTsKKyAgICAgICAgICAgICAgICBmYWlsKCJNaXNzaW5nIHNlY3VyZSBjaGVjay4iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHBhc3MpIHsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBmYWlsKSB7CisgICAgICAgICAgICAgICAgZmFpbChmYWlsLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGguc2V0QXR0YWNobWVudEZvcm1hdHRlcnMobmV3IEZvcm1hdHRlcltde25ldyBUaHJvd0Zvcm1hdHRlcigpfSk7CisgICAgICAgICAgICAgICAgZmFpbCgiTWlzc2luZyBzZWN1cmUgY2hlY2suIik7CisgICAgICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBwYXNzKSB7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZmFpbCkgeworICAgICAgICAgICAgICAgIGZhaWwoZmFpbC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgbWFuYWdlci5zZWN1cmUgPSBmYWxzZTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaC5zZXRBdHRhY2htZW50Rm9ybWF0dGVycyhuZXcgRm9ybWF0dGVyW117bmV3IFRocm93Rm9ybWF0dGVyKCl9KTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGZhaWwpIHsKKyAgICAgICAgICAgICAgICBmYWlsKCJVbmV4cGVjdGVkIHNlY3VyZSBjaGVjay4iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBmYWlsKSB7CisgICAgICAgICAgICAgICAgZmFpbChmYWlsLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBtYW5hZ2VyLnNlY3VyZSA9IHRydWU7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGguZ2V0QXR0YWNobWVudEZvcm1hdHRlcnMoKS5sZW5ndGgpOworICAgICAgICAgICAgICAgIGguc2V0QXR0YWNobWVudEZpbHRlcnMobmV3IEZpbHRlcltde25ldyBUaHJvd0ZpbHRlcigpfSk7CisgICAgICAgICAgICAgICAgZmFpbCgiTWlzc2luZyBzZWN1cmUgY2hlY2suIik7CisgICAgICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBwYXNzKSB7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZmFpbCkgeworICAgICAgICAgICAgICAgIGZhaWwoZmFpbC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgaC5nZXRBdHRhY2htZW50Rm9ybWF0dGVycygpLmxlbmd0aCk7CisgICAgICAgICAgICAgICAgaC5zZXRBdHRhY2htZW50RmlsdGVycygoRmlsdGVyW10pIG51bGwpOworICAgICAgICAgICAgICAgIGZhaWwoIk1pc3Npbmcgc2VjdXJlIGNoZWNrLiIpOworICAgICAgICAgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gfCBOdWxsUG9pbnRlckV4Y2VwdGlvbiBwYXNzKSB7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZmFpbCkgeworICAgICAgICAgICAgICAgIGZhaWwoZmFpbC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgaC5nZXRBdHRhY2htZW50Rm9ybWF0dGVycygpLmxlbmd0aCk7CisgICAgICAgICAgICAgICAgaC5zZXRBdHRhY2htZW50TmFtZXMobmV3IFN0cmluZ1tdeyJlcnJvci50eHQifSk7CisgICAgICAgICAgICAgICAgZmFpbCgiTWlzc2luZyBzZWN1cmUgY2hlY2suIik7CisgICAgICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBwYXNzKSB7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZmFpbCkgeworICAgICAgICAgICAgICAgIGZhaWwoZmFpbC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgaC5nZXRBdHRhY2htZW50Rm9ybWF0dGVycygpLmxlbmd0aCk7CisgICAgICAgICAgICAgICAgaC5zZXRBdHRhY2htZW50TmFtZXMoKFN0cmluZ1tdKSBudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJNaXNzaW5nIHNlY3VyZSBjaGVjay4iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHwgTnVsbFBvaW50ZXJFeGNlcHRpb24gcGFzcykgeworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGZhaWwpIHsKKyAgICAgICAgICAgICAgICBmYWlsKGZhaWwudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIGguZ2V0QXR0YWNobWVudEZvcm1hdHRlcnMoKS5sZW5ndGgpOworICAgICAgICAgICAgICAgIGguc2V0QXR0YWNobWVudE5hbWVzKChGb3JtYXR0ZXJbXSkgbnVsbCk7CisgICAgICAgICAgICAgICAgZmFpbCgiTWlzc2luZyBzZWN1cmUgY2hlY2suIik7CisgICAgICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiB8IE51bGxQb2ludGVyRXhjZXB0aW9uIHBhc3MpIHsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBmYWlsKSB7CisgICAgICAgICAgICAgICAgZmFpbChmYWlsLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBoLmdldEF0dGFjaG1lbnRGb3JtYXR0ZXJzKCkubGVuZ3RoKTsKKyAgICAgICAgICAgICAgICBoLnNldEF0dGFjaG1lbnROYW1lcyhuZXcgRm9ybWF0dGVyW117bmV3IFRocm93Rm9ybWF0dGVyKCl9KTsKKyAgICAgICAgICAgICAgICBmYWlsKCJNaXNzaW5nIHNlY3VyZSBjaGVjay4iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHBhc3MpIHsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBmYWlsKSB7CisgICAgICAgICAgICAgICAgZmFpbChmYWlsLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBtYW5hZ2VyLnNlY3VyZSA9IGZhbHNlOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgaC5nZXRBdHRhY2htZW50Rm9ybWF0dGVycygpLmxlbmd0aCk7CisgICAgICAgICAgICAgICAgaC5zZXRBdHRhY2htZW50Rm9ybWF0dGVycyhuZXcgRm9ybWF0dGVyWzBdKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGZhaWwpIHsKKyAgICAgICAgICAgICAgICBmYWlsKGZhaWwudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZmFpbCkgeworICAgICAgICAgICAgICAgIGZhaWwoZmFpbC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgbWFuYWdlci5zZWN1cmUgPSB0cnVlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygwLCBoLmdldEF0dGFjaG1lbnRGb3JtYXR0ZXJzKCkubGVuZ3RoKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMCwgaC5nZXRBdHRhY2htZW50RmlsdGVycygpLmxlbmd0aCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGguZ2V0QXR0YWNobWVudE5hbWVzKCkubGVuZ3RoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGZhaWwpIHsKKyAgICAgICAgICAgICAgICBmYWlsKGZhaWwudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZmFpbCkgeworICAgICAgICAgICAgICAgIGZhaWwoZmFpbC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBoLnNldEF1dGhlbnRpY2F0b3IoKEF1dGhlbnRpY2F0b3IpIG51bGwpOworICAgICAgICAgICAgICAgIGZhaWwoIk1pc3Npbmcgc2VjdXJlIGNoZWNrLiIpOworICAgICAgICAgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gfCBOdWxsUG9pbnRlckV4Y2VwdGlvbiBwYXNzKSB7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZmFpbCkgeworICAgICAgICAgICAgICAgIGZhaWwoZmFpbC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBoLnNldENvbXBhcmF0b3IoKENvbXBhcmF0b3I8PyBzdXBlciBMb2dSZWNvcmQ+KSBudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJNaXNzaW5nIHNlY3VyZSBjaGVjay4iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHwgTnVsbFBvaW50ZXJFeGNlcHRpb24gcGFzcykgeworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGZhaWwpIHsKKyAgICAgICAgICAgICAgICBmYWlsKGZhaWwudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaC5nZXRDb21wYXJhdG9yKCk7CisgICAgICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBmYWlsKSB7CisgICAgICAgICAgICAgICAgZmFpbChmYWlsLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGZhaWwpIHsKKyAgICAgICAgICAgICAgICBmYWlsKGZhaWwudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaC5zZXRMZXZlbChMZXZlbC5BTEwpOworICAgICAgICAgICAgICAgIGZhaWwoIk1pc3Npbmcgc2VjdXJlIGNoZWNrLiIpOworICAgICAgICAgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gcGFzcykgeworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGZhaWwpIHsKKyAgICAgICAgICAgICAgICBmYWlsKGZhaWwudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaC5zZXRMZXZlbCgoTGV2ZWwpIG51bGwpOworICAgICAgICAgICAgICAgIGZhaWwoIk1pc3Npbmcgc2VjdXJlIGNoZWNrLiIpOworICAgICAgICAgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gfCBOdWxsUG9pbnRlckV4Y2VwdGlvbiBwYXNzKSB7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZmFpbCkgeworICAgICAgICAgICAgICAgIGZhaWwoZmFpbC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBoLmdldExldmVsKCk7CisgICAgICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBmYWlsKSB7CisgICAgICAgICAgICAgICAgZmFpbChmYWlsLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGZhaWwpIHsKKyAgICAgICAgICAgICAgICBmYWlsKGZhaWwudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaC5zZXRGaWx0ZXIoQm9vbGVhbkZpbHRlci5GQUxTRSk7CisgICAgICAgICAgICAgICAgZmFpbCgiTWlzc2luZyBzZWN1cmUgY2hlY2suIik7CisgICAgICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBwYXNzKSB7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZmFpbCkgeworICAgICAgICAgICAgICAgIGZhaWwoZmFpbC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBoLnNldEZpbHRlcigoRmlsdGVyKSBudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJNaXNzaW5nIHNlY3VyZSBjaGVjay4iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHBhc3MpIHsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBmYWlsKSB7CisgICAgICAgICAgICAgICAgZmFpbChmYWlsLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGguZ2V0RmlsdGVyKCk7CisgICAgICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBmYWlsKSB7CisgICAgICAgICAgICAgICAgZmFpbChmYWlsLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGZhaWwpIHsKKyAgICAgICAgICAgICAgICBmYWlsKGZhaWwudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaC5zZXRGb3JtYXR0ZXIobmV3IEVtcHR5Rm9ybWF0dGVyKCkpOworICAgICAgICAgICAgICAgIGZhaWwoIk1pc3Npbmcgc2VjdXJlIGNoZWNrLiIpOworICAgICAgICAgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gcGFzcykgeworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGZhaWwpIHsKKyAgICAgICAgICAgICAgICBmYWlsKGZhaWwudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaC5zZXRGb3JtYXR0ZXIoKEZvcm1hdHRlcikgbnVsbCk7CisgICAgICAgICAgICAgICAgZmFpbCgiTWlzc2luZyBzZWN1cmUgY2hlY2suIik7CisgICAgICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiB8IE51bGxQb2ludGVyRXhjZXB0aW9uIHBhc3MpIHsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBmYWlsKSB7CisgICAgICAgICAgICAgICAgZmFpbChmYWlsLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGguZ2V0Rm9ybWF0dGVyKCk7CisgICAgICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBmYWlsKSB7CisgICAgICAgICAgICAgICAgZmFpbChmYWlsLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGZhaWwpIHsKKyAgICAgICAgICAgICAgICBmYWlsKGZhaWwudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChoLmdldEVycm9yTWFuYWdlcigpKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJNaXNzaW5nIHNlY3VyZSBjaGVjay4iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHBhc3MpIHsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBmYWlsKSB7CisgICAgICAgICAgICAgICAgZmFpbChmYWlsLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGguc2V0RXJyb3JNYW5hZ2VyKG5ldyBFcnJvck1hbmFnZXIoKSk7CisgICAgICAgICAgICAgICAgZmFpbCgiTWlzc2luZyBzZWN1cmUgY2hlY2suIik7CisgICAgICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBwYXNzKSB7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZmFpbCkgeworICAgICAgICAgICAgICAgIGZhaWwoZmFpbC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBoLnNldEVycm9yTWFuYWdlcigoRXJyb3JNYW5hZ2VyKSBudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJNaXNzaW5nIHNlY3VyZSBjaGVjay4iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHwgTnVsbFBvaW50ZXJFeGNlcHRpb24gcGFzcykgeworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGZhaWwpIHsKKyAgICAgICAgICAgICAgICBmYWlsKGZhaWwudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaC5zZXRFbmNvZGluZygoU3RyaW5nKSBudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJNaXNzaW5nIHNlY3VyZSBjaGVjay4iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHBhc3MpIHsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBmYWlsKSB7CisgICAgICAgICAgICAgICAgZmFpbChmYWlsLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGguZ2V0RW5jb2RpbmcoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGZhaWwpIHsKKyAgICAgICAgICAgICAgICBmYWlsKGZhaWwudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZmFpbCkgeworICAgICAgICAgICAgICAgIGZhaWwoZmFpbC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBoLmZsdXNoKCk7CisgICAgICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBmYWlsKSB7CisgICAgICAgICAgICAgICAgZmFpbChmYWlsLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGZhaWwpIHsKKyAgICAgICAgICAgICAgICBmYWlsKGZhaWwudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaC5wdXNoKCk7CisgICAgICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBmYWlsKSB7CisgICAgICAgICAgICAgICAgZmFpbChmYWlsLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGZhaWwpIHsKKyAgICAgICAgICAgICAgICBmYWlsKGZhaWwudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaC5zZXRNYWlsUHJvcGVydGllcyhuZXcgUHJvcGVydGllcygpKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJNaXNzaW5nIHNlY3VyZSBjaGVjay4iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHBhc3MpIHsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBmYWlsKSB7CisgICAgICAgICAgICAgICAgZmFpbChmYWlsLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGguc2V0TWFpbFByb3BlcnRpZXMoKFByb3BlcnRpZXMpIG51bGwpOworICAgICAgICAgICAgICAgIGZhaWwoIk1pc3Npbmcgc2VjdXJlIGNoZWNrLiIpOworICAgICAgICAgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gfCBOdWxsUG9pbnRlckV4Y2VwdGlvbiBwYXNzKSB7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZmFpbCkgeworICAgICAgICAgICAgICAgIGZhaWwoZmFpbC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBoLnNldFB1c2hGaWx0ZXIoKEZpbHRlcikgbnVsbCk7CisgICAgICAgICAgICAgICAgZmFpbCgiTWlzc2luZyBzZWN1cmUgY2hlY2suIik7CisgICAgICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiB8IE51bGxQb2ludGVyRXhjZXB0aW9uIHBhc3MpIHsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBmYWlsKSB7CisgICAgICAgICAgICAgICAgZmFpbChmYWlsLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGguZ2V0UHVzaEZpbHRlcigpOworICAgICAgICAgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gZmFpbCkgeworICAgICAgICAgICAgICAgIGZhaWwoZmFpbC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBmYWlsKSB7CisgICAgICAgICAgICAgICAgZmFpbChmYWlsLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGguc2V0UHVzaExldmVsKExldmVsLk9GRik7CisgICAgICAgICAgICAgICAgZmFpbCgiTWlzc2luZyBzZWN1cmUgY2hlY2suIik7CisgICAgICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBwYXNzKSB7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZmFpbCkgeworICAgICAgICAgICAgICAgIGZhaWwoZmFpbC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBoLnNldFB1c2hMZXZlbCgoTGV2ZWwpIG51bGwpOworICAgICAgICAgICAgICAgIGZhaWwoIk1pc3Npbmcgc2VjdXJlIGNoZWNrLiIpOworICAgICAgICAgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gfCBOdWxsUG9pbnRlckV4Y2VwdGlvbiBwYXNzKSB7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZmFpbCkgeworICAgICAgICAgICAgICAgIGZhaWwoZmFpbC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBoLmdldFB1c2hMZXZlbCgpOworICAgICAgICAgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gZmFpbCkgeworICAgICAgICAgICAgICAgIGZhaWwoZmFpbC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBmYWlsKSB7CisgICAgICAgICAgICAgICAgZmFpbChmYWlsLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGguc2V0U3ViamVjdCgoRm9ybWF0dGVyKSBudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJNaXNzaW5nIHNlY3VyZSBjaGVjay4iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHwgTnVsbFBvaW50ZXJFeGNlcHRpb24gcGFzcykgeworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGZhaWwpIHsKKyAgICAgICAgICAgICAgICBmYWlsKGZhaWwudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaC5zZXRTdWJqZWN0KChTdHJpbmcpIG51bGwpOworICAgICAgICAgICAgICAgIGZhaWwoIk1pc3Npbmcgc2VjdXJlIGNoZWNrLiIpOworICAgICAgICAgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gfCBOdWxsUG9pbnRlckV4Y2VwdGlvbiBwYXNzKSB7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZmFpbCkgeworICAgICAgICAgICAgICAgIGZhaWwoZmFpbC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBoLnNldFN1YmplY3QobmV3IFRocm93Rm9ybWF0dGVyKCkpOworICAgICAgICAgICAgICAgIGZhaWwoIk1pc3Npbmcgc2VjdXJlIGNoZWNrLiIpOworICAgICAgICAgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gcGFzcykgeworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGZhaWwpIHsKKyAgICAgICAgICAgICAgICBmYWlsKGZhaWwudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaC5zZXRTdWJqZWN0KCJ0ZXN0Iik7CisgICAgICAgICAgICAgICAgZmFpbCgiTWlzc2luZyBzZWN1cmUgY2hlY2suIik7CisgICAgICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBwYXNzKSB7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZmFpbCkgeworICAgICAgICAgICAgICAgIGZhaWwoZmFpbC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBoLmdldFN1YmplY3QoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGZhaWwpIHsKKyAgICAgICAgICAgICAgICBmYWlsKGZhaWwudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZmFpbCkgeworICAgICAgICAgICAgICAgIGZhaWwoZmFpbC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKGguZ2V0Q2FwYWNpdHkoKSA+IDApOworICAgICAgICAgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gZmFpbCkgeworICAgICAgICAgICAgICAgIGZhaWwoZmFpbC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBmYWlsKSB7CisgICAgICAgICAgICAgICAgZmFpbChmYWlsLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGguZ2V0QXV0aGVudGljYXRvcigpOworICAgICAgICAgICAgICAgIGZhaWwoIk1pc3Npbmcgc2VjdXJlIGNoZWNrLiIpOworICAgICAgICAgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gcGFzcykgeworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGZhaWwpIHsKKyAgICAgICAgICAgICAgICBmYWlsKGZhaWwudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaC5nZXRNYWlsUHJvcGVydGllcygpOworICAgICAgICAgICAgICAgIGZhaWwoIk1pc3Npbmcgc2VjdXJlIGNoZWNrLiIpOworICAgICAgICAgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gcGFzcykgeworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGZhaWwpIHsKKyAgICAgICAgICAgICAgICBmYWlsKGZhaWwudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaC5jbG9zZSgpOworICAgICAgICAgICAgICAgIGZhaWwoIk1pc3Npbmcgc2VjdXJlIGNoZWNrLiIpOworICAgICAgICAgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gcGFzcykgeworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGZhaWwpIHsKKyAgICAgICAgICAgICAgICBmYWlsKGZhaWwudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaC5wdWJsaXNoKG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAiIikpOworICAgICAgICAgICAgICAgIGguZmx1c2goKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGZhaWwpIHsKKyAgICAgICAgICAgICAgICBmYWlsKGZhaWwudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZmFpbCkgeworICAgICAgICAgICAgICAgIGZhaWwoZmFpbC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy9jaGVjayBmb3IgaW50ZXJuYWwgZXhjZXB0aW9ucyBjYXVzZWQgYnkgc2VjdXJpdHkgbWFuYWdlci4KKyAgICAgICAgICAgIG5leHQ6CisgICAgICAgICAgICBmb3IgKEV4Y2VwdGlvbiBlIDogZW0uZXhjZXB0aW9ucykgeworICAgICAgICAgICAgICAgIGZvciAoVGhyb3dhYmxlIHQgPSBlOyB0ICE9IG51bGw7IHQgPSB0LmdldENhdXNlKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHQgaW5zdGFuY2VvZiBTZWN1cml0eUV4Y2VwdGlvbikgeworICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUgbmV4dDsgLy9leHBlY3RlZAorICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHQgaW5zdGFuY2VvZiBSdW50aW1lRXhjZXB0aW9uKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAoUnVudGltZUV4Y2VwdGlvbikgdDsgLy9mYWlsCisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlbS5leGNlcHRpb25zLmNsZWFyKCk7CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaGFyZFJlZiA9IG5ldyBNYWlsSGFuZGxlcigpOworICAgICAgICAgICAgICAgIGZhaWwoIk1pc3Npbmcgc2VjdXJlIGNoZWNrLiIpOworICAgICAgICAgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gcGFzcykgeworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGZhaWwpIHsKKyAgICAgICAgICAgICAgICBmYWlsKGZhaWwudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaGFyZFJlZiA9IG5ldyBNYWlsSGFuZGxlcigxMDApOworICAgICAgICAgICAgICAgIGZhaWwoIk1pc3Npbmcgc2VjdXJlIGNoZWNrLiIpOworICAgICAgICAgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gcGFzcykgeworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGZhaWwpIHsKKyAgICAgICAgICAgICAgICBmYWlsKGZhaWwudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgaGFyZFJlZiA9IG5ldyBNYWlsSGFuZGxlcihuZXcgUHJvcGVydGllcygpKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJNaXNzaW5nIHNlY3VyZSBjaGVjay4iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHBhc3MpIHsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBmYWlsKSB7CisgICAgICAgICAgICAgICAgZmFpbChmYWlsLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGhhcmRSZWYgPSBuZXcgTWFpbEhhbmRsZXIoLTEwMCk7CisgICAgICAgICAgICAgICAgZmFpbCgiTWlzc2luZyBzZWN1cmUgY2hlY2suIik7CisgICAgICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiB8IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBwYXNzKSB7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZmFpbCkgeworICAgICAgICAgICAgICAgIGZhaWwoZmFpbC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBoYXJkUmVmID0gbmV3IE1haWxIYW5kbGVyKChQcm9wZXJ0aWVzKSBudWxsKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJNaXNzaW5nIHNlY3VyZSBjaGVjay4iKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHwgTnVsbFBvaW50ZXJFeGNlcHRpb24gcGFzcykgeworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGZhaWwpIHsKKyAgICAgICAgICAgICAgICBmYWlsKGZhaWwudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBoYXJkUmVmID0gbnVsbDsKKyAgICAgICAgICAgIG1hbmFnZXIuc2VjdXJlID0gZmFsc2U7CisgICAgICAgICAgICBTeXN0ZW0uc2V0U2VjdXJpdHlNYW5hZ2VyKChTZWN1cml0eU1hbmFnZXIpIG51bGwpOworICAgICAgICAgICAgaWYgKGggIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGguY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFZlcmlmeUVycm9yTWFuYWdlcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBMb2dNYW5hZ2VyIG1hbmFnZXIgPSBMb2dNYW5hZ2VyLmdldExvZ01hbmFnZXIoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG1hbmFnZXIucmVzZXQoKTsKKworICAgICAgICAgICAgZmluYWwgU3RyaW5nIHAgPSBNYWlsSGFuZGxlci5jbGFzcy5nZXROYW1lKCk7CisgICAgICAgICAgICBQcm9wZXJ0aWVzIHByb3BzID0gY3JlYXRlSW5pdFByb3BlcnRpZXMocCk7CisgICAgICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5lbmNvZGluZyIpLCAidXMtYXNjaWkiKTsKKyAgICAgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLm1haWwudG8iKSwgImZvb0BiYXIuY29tIik7CisgICAgICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5tYWlsLmNjIiksICJmaXp6QGJ1enouY29tIik7CisgICAgICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5tYWlsLmJjYyIpLCAiYmF6QGJhci5jb20iKTsKKyAgICAgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLnN1YmplY3QiKSwgcC5jb25jYXQoIiB0ZXN0IikpOworICAgICAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIubWFpbC5mcm9tIiksICJsb2NhbGhvc3RAbG9jYWxkb21haW4iKTsKKyAgICAgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLm1haWwuc2VuZGVyIiksICJtYWlsQGhhbmRsZXIiKTsKKyAgICAgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLmVycm9yTWFuYWdlciIpLCBWZXJpZnlFcnJvck1hbmFnZXIuY2xhc3MuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLnZlcmlmeSIpLCAicmVtb3RlIik7CisKKyAgICAgICAgICAgIHJlYWQobWFuYWdlciwgcHJvcHMpOworCisgICAgICAgICAgICBNYWlsSGFuZGxlciBpbnN0YW5jZSA9IG5ldyBNYWlsSGFuZGxlcigpOworICAgICAgICAgICAgSW50ZXJuYWxFcnJvck1hbmFnZXIgZW0gPSBpbnRlcm5hbEVycm9yTWFuYWdlckZyb20oaW5zdGFuY2UpOworCisgICAgICAgICAgICAvL2Vuc3VyZSBWZXJpZnlFcnJvck1hbmFnZXIgd2FzIGluc3RhbGxlZC4KKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhWZXJpZnlFcnJvck1hbmFnZXIuY2xhc3MsIGVtLmdldENsYXNzKCkpOworCisgICAgICAgICAgICBmb3IgKEV4Y2VwdGlvbiBleGNlcHRpb24gOiBlbS5leGNlcHRpb25zKSB7CisgICAgICAgICAgICAgICAgZmluYWwgVGhyb3dhYmxlIHQgPSBleGNlcHRpb247CisgICAgICAgICAgICAgICAgaWYgKCFpc0Nvbm5lY3RPclRpbWVvdXQodCkpIHsKKyAgICAgICAgICAgICAgICAgICAgZHVtcCh0KTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCh0LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgYXNzZXJ0RmFsc2UoZW0uZXhjZXB0aW9ucy5pc0VtcHR5KCkpOworICAgICAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIG1hbmFnZXIucmVzZXQoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFZlcmlmeU5vQ29udGVudCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBQcm9wZXJ0aWVzIHByb3BzID0gY3JlYXRlSW5pdFByb3BlcnRpZXMoIiIpOworICAgICAgICBTZXNzaW9uIHNlc3Npb24gPSBTZXNzaW9uLmdldEluc3RhbmNlKHByb3BzKTsKKyAgICAgICAgTWltZU1lc3NhZ2UgbXNnID0gbmV3IE1pbWVNZXNzYWdlKHNlc3Npb24pOworICAgICAgICBBZGRyZXNzW10gZnJvbSA9IEludGVybmV0QWRkcmVzcy5wYXJzZSgibWVAbG9jYWxob3N0IiwgZmFsc2UpOworICAgICAgICBtc2cuYWRkRnJvbShmcm9tKTsKKyAgICAgICAgbXNnLnNldFJlY2lwaWVudHMoTWVzc2FnZS5SZWNpcGllbnRUeXBlLlRPLCBmcm9tKTsKKyAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIG91dCA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oMzg0KTsKKyAgICAgICAgbXNnLnNldEhlYWRlcigiQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZyIsICJiYXNlNjQiKTsKKyAgICAgICAgbXNnLnNhdmVDaGFuZ2VzKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtc2cud3JpdGVUbyhvdXQpOworICAgICAgICAgICAgZmFpbCgiVmVyaWZ5IHR5cGUgJ3JlbW90ZScgbWF5IHNlbmQgYSBtZXNzYWdlIHdpdGggbm8gY29udGVudC4iKTsKKyAgICAgICAgfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIHwgSU9FeGNlcHRpb24gZXhwZWN0KSB7CisgICAgICAgICAgICBtc2cuc2V0Q29udGVudCgiIiwgInRleHQvcGxhaW4iKTsKKyAgICAgICAgICAgIG1zZy5zYXZlQ2hhbmdlcygpOworICAgICAgICAgICAgbXNnLndyaXRlVG8ob3V0KTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SXNNaXNzaW5nQ29udGVudCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBQcm9wZXJ0aWVzIHByb3BzID0gY3JlYXRlSW5pdFByb3BlcnRpZXMoIiIpOworCisgICAgICAgIE1haWxIYW5kbGVyIHRhcmdldCA9IG5ldyBNYWlsSGFuZGxlcihwcm9wcyk7CisgICAgICAgIFNlc3Npb24gc2Vzc2lvbiA9IFNlc3Npb24uZ2V0SW5zdGFuY2UocHJvcHMpOworICAgICAgICBNaW1lTWVzc2FnZSBtc2cgPSBuZXcgTWltZU1lc3NhZ2Uoc2Vzc2lvbik7CisgICAgICAgIEFkZHJlc3NbXSBmcm9tID0gSW50ZXJuZXRBZGRyZXNzLnBhcnNlKCJtZUBsb2NhbGhvc3QiLCBmYWxzZSk7CisgICAgICAgIG1zZy5hZGRGcm9tKGZyb20pOworICAgICAgICBtc2cuc2V0UmVjaXBpZW50cyhNZXNzYWdlLlJlY2lwaWVudFR5cGUuVE8sIGZyb20pOworICAgICAgICBtc2cuc2V0SGVhZGVyKCJDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nIiwgImJhc2U2NCIpOworICAgICAgICBtc2cuc2F2ZUNoYW5nZXMoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG1zZy53cml0ZVRvKG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oMzg0KSk7CisgICAgICAgICAgICBmYWlsKCJWZXJpZnkgdHlwZSAncmVtb3RlJyBtYXkgaGlkZSByZW1vdGUgZXhjZXB0aW9ucy4iKTsKKyAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiByZSkgeworICAgICAgICAgICAgdGhyb3cgcmU7IC8vQXZvaWQgY2F0Y2ggYWxsLgorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXhwZWN0KSB7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKGV4cGVjdC5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShleHBlY3QuZ2V0TWVzc2FnZSgpLmxlbmd0aCgpICE9IDApOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSh0YXJnZXQuaXNNaXNzaW5nQ29udGVudChtc2csIGV4cGVjdCkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSh0YXJnZXQuaXNNaXNzaW5nQ29udGVudChtc2csIG5ldyBFeGNlcHRpb24oZXhwZWN0KSkpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSh0YXJnZXQuaXNNaXNzaW5nQ29udGVudChtc2csIG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oIiIsIGV4cGVjdCkpKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKHRhcmdldC5pc01pc3NpbmdDb250ZW50KG1zZywgbmV3IEV4Y2VwdGlvbigpKSk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZSh0YXJnZXQuaXNNaXNzaW5nQ29udGVudChtc2csIG5ldyBSdW50aW1lRXhjZXB0aW9uKCkpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEludGVybigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnROdWxsKFN5c3RlbS5nZXRTZWN1cml0eU1hbmFnZXIoKSk7CisgICAgICAgIGZpbmFsIFN0cmluZyBwID0gTWFpbEhhbmRsZXIuY2xhc3MuZ2V0TmFtZSgpOworICAgICAgICBQcm9wZXJ0aWVzIHByb3BzID0gY3JlYXRlSW5pdFByb3BlcnRpZXMocCk7CisgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLmVycm9yTWFuYWdlciIpLAorICAgICAgICAgICAgICAgIEludGVybkZpbHRlckVycm9yTWFuYWdlci5jbGFzcy5nZXROYW1lKCkpOworICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5jb21wYXJhdG9yIiksCisgICAgICAgICAgICAgICAgSW50ZXJuRmlsdGVyRm9ybWF0dGVyQ29tcGFyYXRvci5jbGFzcy5nZXROYW1lKCkpOworICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5maWx0ZXIiKSwgSW50ZXJuRmlsdGVyLmNsYXNzLmdldE5hbWUoKSk7CisgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLnB1c2hGaWx0ZXIiKSwKKyAgICAgICAgICAgICAgICBJbnRlcm5GaWx0ZXJFcnJvck1hbmFnZXIuY2xhc3MuZ2V0TmFtZSgpKTsKKworICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5hdHRhY2htZW50LmZvcm1hdHRlcnMiKSwKKyAgICAgICAgICAgICAgICBTaW1wbGVGb3JtYXR0ZXIuY2xhc3MuZ2V0TmFtZSgpICsgIiwgIgorICAgICAgICAgICAgICAgICsgSW50ZXJuRmlsdGVyRm9ybWF0dGVyLmNsYXNzLmdldE5hbWUoKSArICIsICIKKyAgICAgICAgICAgICAgICArIEludGVybkZvcm1hdHRlci5jbGFzcy5nZXROYW1lKCkgKyAiLCAiCisgICAgICAgICAgICAgICAgKyBYTUxGb3JtYXR0ZXIuY2xhc3MuZ2V0TmFtZSgpICsgIiwgIgorICAgICAgICAgICAgICAgICsgSW50ZXJuRm9ybWF0dGVyLmNsYXNzLmdldE5hbWUoKSArICIsICIKKyAgICAgICAgICAgICAgICArIFNpbXBsZUZvcm1hdHRlci5jbGFzcy5nZXROYW1lKCkgKyAiLCAiCisgICAgICAgICAgICAgICAgKyBTaW1wbGVGb3JtYXR0ZXIuY2xhc3MuZ2V0TmFtZSgpKTsKKworICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5hdHRhY2htZW50LmZpbHRlcnMiKSwKKyAgICAgICAgICAgICAgICBudWxsICsgIiwgIgorICAgICAgICAgICAgICAgICsgSW50ZXJuRmlsdGVyRm9ybWF0dGVyLmNsYXNzLmdldE5hbWUoKSArICIsICIKKyAgICAgICAgICAgICAgICArIEludGVybkZpbHRlckZvcm1hdHRlci5jbGFzcy5nZXROYW1lKCkgKyAiLCAiCisgICAgICAgICAgICAgICAgKyBJbnRlcm5GaWx0ZXIuY2xhc3MuZ2V0TmFtZSgpICsgIiwgIgorICAgICAgICAgICAgICAgICsgSW50ZXJuRmlsdGVyLmNsYXNzLmdldE5hbWUoKSArICIsICIKKyAgICAgICAgICAgICAgICArIEludGVybkJhZFN1YkZpbHRlci5jbGFzcy5nZXROYW1lKCkgKyAiLCAiCisgICAgICAgICAgICAgICAgKyBJbnRlcm5CYWRGaWx0ZXIuY2xhc3MuZ2V0TmFtZSgpKTsKKworICAgICAgICBmaW5hbCBTdHJpbmcgdHh0ID0gIkludGVybiB0ZXN0IjsKKyAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIuYXR0YWNobWVudC5uYW1lcyIpLAorICAgICAgICAgICAgICAgIHR4dCArICIsICIKKyAgICAgICAgICAgICAgICArIEludGVybkZpbHRlckZvcm1hdHRlci5jbGFzcy5nZXROYW1lKCkgKyAiLCAiCisgICAgICAgICAgICAgICAgKyBJbnRlcm5GaWx0ZXJGb3JtYXR0ZXIuY2xhc3MuZ2V0TmFtZSgpICsgIiwgIgorICAgICAgICAgICAgICAgICsgdHh0ICsgIiwgIgorICAgICAgICAgICAgICAgICsgSW50ZXJuRm9ybWF0dGVyLmNsYXNzLmdldE5hbWUoKSArICIsICIKKyAgICAgICAgICAgICAgICArIEludGVybkZpbHRlckZvcm1hdHRlckNvbXBhcmF0b3IuY2xhc3MuZ2V0TmFtZSgpICsgIiwgIgorICAgICAgICAgICAgICAgICsgSW50ZXJuRmlsdGVyRm9ybWF0dGVyQ29tcGFyYXRvci5jbGFzcy5nZXROYW1lKCkpOworICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5zdWJqZWN0IiksIHR4dCk7CisKKyAgICAgICAgTWFpbEhhbmRsZXIgaW5zdGFuY2UgPSB0ZXN0SW50ZXJuKHAsIHByb3BzKTsKKyAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKworICAgICAgICBGb3JtYXR0ZXJbXSBmb3JtYXR0ZXIgPSBpbnN0YW5jZS5nZXRBdHRhY2htZW50Rm9ybWF0dGVycygpOworICAgICAgICBGaWx0ZXJbXSBmaWx0ZXIgPSBpbnN0YW5jZS5nZXRBdHRhY2htZW50RmlsdGVycygpOworICAgICAgICBGb3JtYXR0ZXJbXSBuYW1lcyA9IGluc3RhbmNlLmdldEF0dGFjaG1lbnROYW1lcygpOworCisgICAgICAgIGFzc2VydFNhbWUoaW5zdGFuY2UuZ2V0RXJyb3JNYW5hZ2VyKCksIGluc3RhbmNlLmdldFB1c2hGaWx0ZXIoKSk7CisgICAgICAgIGFzc2VydE51bGwoZmlsdGVyWzBdKTsKKyAgICAgICAgYXNzZXJ0U2FtZShmaWx0ZXJbMV0sIGZpbHRlclsyXSk7CisgICAgICAgIGFzc2VydFNhbWUoZmlsdGVyWzFdLCBmb3JtYXR0ZXJbMV0pOworICAgICAgICBhc3NlcnRTYW1lKGZpbHRlclsyXSwgZm9ybWF0dGVyWzFdKTsKKyAgICAgICAgYXNzZXJ0U2FtZShuYW1lc1sxXSwgZmlsdGVyWzFdKTsKKyAgICAgICAgYXNzZXJ0U2FtZShuYW1lc1sxXSwgZm9ybWF0dGVyWzFdKTsKKyAgICAgICAgYXNzZXJ0U2FtZShuYW1lc1syXSwgZmlsdGVyWzJdKTsKKyAgICAgICAgYXNzZXJ0U2FtZShuYW1lc1syXSwgZm9ybWF0dGVyWzFdKTsKKyAgICAgICAgYXNzZXJ0U2FtZShuYW1lc1sxXSwgZmlsdGVyWzJdKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChpbnN0YW5jZS5nZXRTdWJqZWN0KCkpOworICAgICAgICBhc3NlcnRTYW1lKGluc3RhbmNlLmdldFN1YmplY3QoKSwgbmFtZXNbMF0pOworICAgICAgICBhc3NlcnRTYW1lKGluc3RhbmNlLmdldFN1YmplY3QoKSwgbmFtZXNbM10pOworICAgICAgICBhc3NlcnRTYW1lKG5hbWVzWzBdLCBuYW1lc1szXSk7CisgICAgICAgIGFzc2VydE5vdE51bGwoaW5zdGFuY2UuZ2V0RmlsdGVyKCkpOworICAgICAgICBhc3NlcnRTYW1lKGluc3RhbmNlLmdldEZpbHRlcigpLCBmaWx0ZXJbM10pOworICAgICAgICBhc3NlcnRTYW1lKGluc3RhbmNlLmdldEZpbHRlcigpLCBmaWx0ZXJbNF0pOworICAgICAgICBhc3NlcnRTYW1lKGZpbHRlclszXSwgZmlsdGVyWzRdKTsKKyAgICAgICAgYXNzZXJ0Tm90U2FtZShmaWx0ZXJbNV0sIGZpbHRlcls2XSk7IC8vQmFkIGVxdWFscyBtZXRob2QuCisgICAgICAgIGFzc2VydE5vdE51bGwoaW5zdGFuY2UuZ2V0Q29tcGFyYXRvcigpKTsgIC8vQ29tcGFyYXRvciBpcyBub3QgaW50ZXJuZWQuCisgICAgICAgIGFzc2VydE5vdFNhbWUoaW5zdGFuY2UuZ2V0Q29tcGFyYXRvcigpLCBuYW1lc1s1XSk7CisgICAgICAgIGFzc2VydE5vdFNhbWUoaW5zdGFuY2UuZ2V0Q29tcGFyYXRvcigpLCBuYW1lc1s2XSk7CisgICAgICAgIGFzc2VydFNhbWUobmFtZXNbNV0sIG5hbWVzWzZdKTsKKworICAgICAgICBJbnRlcm5hbEVycm9yTWFuYWdlciBlbSA9IGludGVybmFsRXJyb3JNYW5hZ2VyRnJvbShpbnN0YW5jZSk7CisgICAgICAgIGZvciAoRXhjZXB0aW9uIGV4Y2VwdGlvbiA6IGVtLmV4Y2VwdGlvbnMpIHsKKyAgICAgICAgICAgIGZpbmFsIFRocm93YWJsZSB0ID0gZXhjZXB0aW9uOworICAgICAgICAgICAgaWYgKHQgaW5zdGFuY2VvZiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICAgICAgICAgICAgICAgICAgJiYgU3RyaW5nLnZhbHVlT2YodC5nZXRNZXNzYWdlKCkpLmNvbnRhaW5zKCJlcXVhbCIpKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBkdW1wKHQpOworICAgICAgICB9CisgICAgICAgIGFzc2VydEZhbHNlKGVtLmV4Y2VwdGlvbnMuaXNFbXB0eSgpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIE1haWxIYW5kbGVyIHRlc3RJbnRlcm4oU3RyaW5nIHAsIFByb3BlcnRpZXMgcHJvcHMpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5tYWlsLnRvIiksICJiYWRBZGRyZXNzIik7CisgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLm1haWwuY2MiKSwgImJhZEFkZHJlc3MiKTsKKyAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIubWFpbC5mcm9tIiksICJiYWRBZGRyZXNzIik7CisKKyAgICAgICAgZmluYWwgTG9nTWFuYWdlciBtYW5hZ2VyID0gTG9nTWFuYWdlci5nZXRMb2dNYW5hZ2VyKCk7CisgICAgICAgIHJlYWQobWFuYWdlciwgcHJvcHMpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBNYWlsSGFuZGxlcigpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgbWFuYWdlci5yZXNldCgpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29tcGFyYXRvclJldmVyc2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU3RyaW5nIHAgPSBNYWlsSGFuZGxlci5jbGFzcy5nZXROYW1lKCk7CisgICAgICAgIFByb3BlcnRpZXMgcHJvcHMgPSBjcmVhdGVJbml0UHJvcGVydGllcyhwKTsKKyAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIuY29tcGFyYXRvciIpLCBTZXF1ZW5jZUNvbXBhcmF0b3IuY2xhc3MuZ2V0TmFtZSgpKTsKKyAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIuY29tcGFyYXRvci5yZXZlcnNlIiksICJmYWxzZSIpOworICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5lcnJvck1hbmFnZXIiKSwgSW50ZXJuYWxFcnJvck1hbmFnZXIuY2xhc3MuZ2V0TmFtZSgpKTsKKworICAgICAgICBMb2dSZWNvcmQgbG93ID0gbmV3IExvZ1JlY29yZChMZXZlbC5JTkZPLCAiIik7CisgICAgICAgIExvZ1JlY29yZCBoaWdoID0gbmV3IExvZ1JlY29yZChMZXZlbC5JTkZPLCAiIik7CisgICAgICAgIGZpbmFsIExvZ01hbmFnZXIgbWFuYWdlciA9IExvZ01hbmFnZXIuZ2V0TG9nTWFuYWdlcigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVhZChtYW5hZ2VyLCBwcm9wcyk7CisgICAgICAgICAgICBNYWlsSGFuZGxlciBpbnN0YW5jZSA9IG5ldyBNYWlsSGFuZGxlcigpOworICAgICAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKyAgICAgICAgICAgIEludGVybmFsRXJyb3JNYW5hZ2VyIGVtID0gaW50ZXJuYWxFcnJvck1hbmFnZXJGcm9tKGluc3RhbmNlKTsKKyAgICAgICAgICAgIGZvciAoRXhjZXB0aW9uIGV4Y2VwdGlvbiA6IGVtLmV4Y2VwdGlvbnMpIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBUaHJvd2FibGUgdCA9IGV4Y2VwdGlvbjsKKyAgICAgICAgICAgICAgICBkdW1wKHQpOworICAgICAgICAgICAgICAgIGZhaWwodC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoZW0uZXhjZXB0aW9ucy5pc0VtcHR5KCkpOworCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoU2VxdWVuY2VDb21wYXJhdG9yLmNsYXNzLAorICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZS5nZXRDb21wYXJhdG9yKCkuZ2V0Q2xhc3MoKSk7CisKKyAgICAgICAgICAgIGFzc2VydFRydWUoaW5zdGFuY2UuZ2V0Q29tcGFyYXRvcigpLmNvbXBhcmUobG93LCBoaWdoKSA8IDApOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShpbnN0YW5jZS5nZXRDb21wYXJhdG9yKCkuY29tcGFyZShoaWdoLCBsb3cpID4gMCk7CisKKyAgICAgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLmNvbXBhcmF0b3IucmV2ZXJzZSIpLCAidHJ1ZSIpOworICAgICAgICAgICAgcmVhZChtYW5hZ2VyLCBwcm9wcyk7CisgICAgICAgICAgICBpbnN0YW5jZSA9IG5ldyBNYWlsSGFuZGxlcigpOworICAgICAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKyAgICAgICAgICAgIGVtID0gaW50ZXJuYWxFcnJvck1hbmFnZXJGcm9tKGluc3RhbmNlKTsKKyAgICAgICAgICAgIGZvciAoRXhjZXB0aW9uIGV4Y2VwdGlvbiA6IGVtLmV4Y2VwdGlvbnMpIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBUaHJvd2FibGUgdCA9IGV4Y2VwdGlvbjsKKyAgICAgICAgICAgICAgICBkdW1wKHQpOworICAgICAgICAgICAgICAgIGZhaWwodC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoZW0uZXhjZXB0aW9ucy5pc0VtcHR5KCkpOworCisgICAgICAgICAgICBDb21wYXJhdG9yPD8gc3VwZXIgTG9nUmVjb3JkPiBjID0gaW5zdGFuY2UuZ2V0Q29tcGFyYXRvcigpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShTZXF1ZW5jZUNvbXBhcmF0b3IuY2xhc3MgIT0gYy5nZXRDbGFzcygpKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGluc3RhbmNlLmdldENvbXBhcmF0b3IoKS5jb21wYXJlKGxvdywgaGlnaCkgPCAwKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGluc3RhbmNlLmdldENvbXBhcmF0b3IoKS5jb21wYXJlKGhpZ2gsIGxvdykgPiAwKTsKKworICAgICAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIuY29tcGFyYXRvciIpLAorICAgICAgICAgICAgICAgICAgICBTZXF1ZW5jZUNvbXBhcmF0b3JXaXRoUmV2ZXJzZS5jbGFzcy5nZXROYW1lKCkpOworICAgICAgICAgICAgcmVhZChtYW5hZ2VyLCBwcm9wcyk7CisgICAgICAgICAgICBpbnN0YW5jZSA9IG5ldyBNYWlsSGFuZGxlcigpOworICAgICAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKyAgICAgICAgICAgIGVtID0gaW50ZXJuYWxFcnJvck1hbmFnZXJGcm9tKGluc3RhbmNlKTsKKyAgICAgICAgICAgIGZvciAoRXhjZXB0aW9uIGV4Y2VwdGlvbiA6IGVtLmV4Y2VwdGlvbnMpIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBUaHJvd2FibGUgdCA9IGV4Y2VwdGlvbjsKKyAgICAgICAgICAgICAgICBkdW1wKHQpOworICAgICAgICAgICAgICAgIGZhaWwodC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydFRydWUoZW0uZXhjZXB0aW9ucy5pc0VtcHR5KCkpOworCisgICAgICAgICAgICBjID0gaW5zdGFuY2UuZ2V0Q29tcGFyYXRvcigpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShTZXF1ZW5jZURlc2NDb21wYXJhdG9yLmNsYXNzID09IGMuZ2V0Q2xhc3MoKSk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShpbnN0YW5jZS5nZXRDb21wYXJhdG9yKCkuY29tcGFyZShsb3csIGhpZ2gpIDwgMCk7CisgICAgICAgICAgICBhc3NlcnRGYWxzZShpbnN0YW5jZS5nZXRDb21wYXJhdG9yKCkuY29tcGFyZShoaWdoLCBsb3cpID4gMCk7CisKKyAgICAgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLmNvbXBhcmF0b3IiKSwgIiIpOworICAgICAgICAgICAgcmVhZChtYW5hZ2VyLCBwcm9wcyk7CisgICAgICAgICAgICBpbnN0YW5jZSA9IG5ldyBNYWlsSGFuZGxlcigpOworICAgICAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKyAgICAgICAgICAgIGVtID0gaW50ZXJuYWxFcnJvck1hbmFnZXJGcm9tKGluc3RhbmNlKTsKKyAgICAgICAgICAgIGZvciAoRXhjZXB0aW9uIGV4Y2VwdGlvbiA6IGVtLmV4Y2VwdGlvbnMpIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBUaHJvd2FibGUgdCA9IGV4Y2VwdGlvbjsKKyAgICAgICAgICAgICAgICBpZiAodCBpbnN0YW5jZW9mIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbikgeworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZHVtcCh0KTsKKyAgICAgICAgICAgICAgICBmYWlsKHQudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5jbGFzcy5nZXROYW1lKCksCisgICAgICAgICAgICAgICAgICAgIGVtLmV4Y2VwdGlvbnMuaXNFbXB0eSgpKTsKKworICAgICAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIuY29tcGFyYXRvciIpLCAibnVsbCIpOworICAgICAgICAgICAgcmVhZChtYW5hZ2VyLCBwcm9wcyk7CisgICAgICAgICAgICBpbnN0YW5jZSA9IG5ldyBNYWlsSGFuZGxlcigpOworICAgICAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKyAgICAgICAgICAgIGVtID0gaW50ZXJuYWxFcnJvck1hbmFnZXJGcm9tKGluc3RhbmNlKTsKKyAgICAgICAgICAgIGZvciAoRXhjZXB0aW9uIGV4Y2VwdGlvbiA6IGVtLmV4Y2VwdGlvbnMpIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBUaHJvd2FibGUgdCA9IGV4Y2VwdGlvbjsKKyAgICAgICAgICAgICAgICBpZiAodCBpbnN0YW5jZW9mIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbikgeworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZHVtcCh0KTsKKyAgICAgICAgICAgICAgICBmYWlsKHQudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5jbGFzcy5nZXROYW1lKCksCisgICAgICAgICAgICAgICAgICAgIGVtLmV4Y2VwdGlvbnMuaXNFbXB0eSgpKTsKKworICAgICAgICAgICAgcHJvcHMucmVtb3ZlKHAuY29uY2F0KCIuY29tcGFyYXRvciIpKTsKKyAgICAgICAgICAgIHJlYWQobWFuYWdlciwgcHJvcHMpOworICAgICAgICAgICAgaW5zdGFuY2UgPSBuZXcgTWFpbEhhbmRsZXIoKTsKKyAgICAgICAgICAgIGluc3RhbmNlLmNsb3NlKCk7CisgICAgICAgICAgICBlbSA9IGludGVybmFsRXJyb3JNYW5hZ2VyRnJvbShpbnN0YW5jZSk7CisgICAgICAgICAgICBmb3IgKEV4Y2VwdGlvbiBleGNlcHRpb24gOiBlbS5leGNlcHRpb25zKSB7CisgICAgICAgICAgICAgICAgZmluYWwgVGhyb3dhYmxlIHQgPSBleGNlcHRpb247CisgICAgICAgICAgICAgICAgaWYgKHQgaW5zdGFuY2VvZiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24pIHsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGR1bXAodCk7CisgICAgICAgICAgICAgICAgZmFpbCh0LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBhc3NlcnRGYWxzZShJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uY2xhc3MuZ2V0TmFtZSgpLAorICAgICAgICAgICAgICAgICAgICBlbS5leGNlcHRpb25zLmlzRW1wdHkoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBtYW5hZ2VyLnJlc2V0KCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RWZXJpZnlMb2dNYW5hZ2VyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIExvZ01hbmFnZXIgbWFuYWdlciA9IExvZ01hbmFnZXIuZ2V0TG9nTWFuYWdlcigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbWFuYWdlci5yZXNldCgpOworCisgICAgICAgICAgICBmaW5hbCBTdHJpbmcgcCA9IE1haWxIYW5kbGVyLmNsYXNzLmdldE5hbWUoKTsKKyAgICAgICAgICAgIFByb3BlcnRpZXMgcHJvcHMgPSBjcmVhdGVJbml0UHJvcGVydGllcyhwKTsKKyAgICAgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLnN1YmplY3QiKSwgcC5jb25jYXQoIiB0ZXN0IikpOworICAgICAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIuZXJyb3JNYW5hZ2VyIiksIEludGVybmFsRXJyb3JNYW5hZ2VyLmNsYXNzLmdldE5hbWUoKSk7CisgICAgICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi52ZXJpZnkiKSwgImxpbWl0ZWQiKTsKKworICAgICAgICAgICAgcmVhZChtYW5hZ2VyLCBwcm9wcyk7CisKKyAgICAgICAgICAgIE1haWxIYW5kbGVyIGluc3RhbmNlID0gbmV3IE1haWxIYW5kbGVyKCk7CisgICAgICAgICAgICBJbnRlcm5hbEVycm9yTWFuYWdlciBlbSA9IGludGVybmFsRXJyb3JNYW5hZ2VyRnJvbShpbnN0YW5jZSk7CisKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhJbnRlcm5hbEVycm9yTWFuYWdlci5jbGFzcywgZW0uZ2V0Q2xhc3MoKSk7CisKKyAgICAgICAgICAgIGZvciAoRXhjZXB0aW9uIGV4Y2VwdGlvbiA6IGVtLmV4Y2VwdGlvbnMpIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBUaHJvd2FibGUgdCA9IGV4Y2VwdGlvbjsKKyAgICAgICAgICAgICAgICBpZiAodCBpbnN0YW5jZW9mIEFkZHJlc3NFeGNlcHRpb24gPT0gZmFsc2UpIHsKKyAgICAgICAgICAgICAgICAgICAgZHVtcCh0KTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCh0LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGVtLmV4Y2VwdGlvbnMuaXNFbXB0eSgpKTsKKworICAgICAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKworICAgICAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIudmVyaWZ5IiksICJsb2NhbCIpOworCisgICAgICAgICAgICByZWFkKG1hbmFnZXIsIHByb3BzKTsKKworICAgICAgICAgICAgaW5zdGFuY2UgPSBuZXcgTWFpbEhhbmRsZXIoKTsKKyAgICAgICAgICAgIGVtID0gaW50ZXJuYWxFcnJvck1hbmFnZXJGcm9tKGluc3RhbmNlKTsKKworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKEludGVybmFsRXJyb3JNYW5hZ2VyLmNsYXNzLCBlbS5nZXRDbGFzcygpKTsKKworICAgICAgICAgICAgZm9yIChFeGNlcHRpb24gZXhjZXB0aW9uIDogZW0uZXhjZXB0aW9ucykgeworICAgICAgICAgICAgICAgIGZpbmFsIFRocm93YWJsZSB0ID0gZXhjZXB0aW9uOworICAgICAgICAgICAgICAgIGlmICh0IGluc3RhbmNlb2YgQWRkcmVzc0V4Y2VwdGlvbiA9PSBmYWxzZSkgeworICAgICAgICAgICAgICAgICAgICBkdW1wKHQpOworICAgICAgICAgICAgICAgICAgICBmYWlsKHQudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0RmFsc2UoZW0uZXhjZXB0aW9ucy5pc0VtcHR5KCkpOworCisgICAgICAgICAgICBpbnN0YW5jZS5jbG9zZSgpOworCisgICAgICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi52ZXJpZnkiKSwgInJlc29sdmUiKTsKKworICAgICAgICAgICAgcmVhZChtYW5hZ2VyLCBwcm9wcyk7CisKKyAgICAgICAgICAgIGluc3RhbmNlID0gbmV3IE1haWxIYW5kbGVyKCk7CisgICAgICAgICAgICBlbSA9IGludGVybmFsRXJyb3JNYW5hZ2VyRnJvbShpbnN0YW5jZSk7CisKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhJbnRlcm5hbEVycm9yTWFuYWdlci5jbGFzcywgZW0uZ2V0Q2xhc3MoKSk7CisKKyAgICAgICAgICAgIGZvciAoRXhjZXB0aW9uIGV4Y2VwdGlvbiA6IGVtLmV4Y2VwdGlvbnMpIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBUaHJvd2FibGUgdCA9IGV4Y2VwdGlvbjsKKyAgICAgICAgICAgICAgICBpZiAoaXNDb25uZWN0T3JUaW1lb3V0KHQpKSB7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAodCBpbnN0YW5jZW9mIEFkZHJlc3NFeGNlcHRpb24gPT0gZmFsc2UpIHsKKyAgICAgICAgICAgICAgICAgICAgZHVtcCh0KTsKKyAgICAgICAgICAgICAgICAgICAgZmFpbCh0LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGVtLmV4Y2VwdGlvbnMuaXNFbXB0eSgpKTsKKworICAgICAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKworICAgICAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIudmVyaWZ5IiksICJyZW1vdGUiKTsKKyAgICAgICAgICAgIHJlYWQobWFuYWdlciwgcHJvcHMpOworCisgICAgICAgICAgICBpbnN0YW5jZSA9IG5ldyBNYWlsSGFuZGxlcigpOworICAgICAgICAgICAgZW0gPSBpbnRlcm5hbEVycm9yTWFuYWdlckZyb20oaW5zdGFuY2UpOworCisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoSW50ZXJuYWxFcnJvck1hbmFnZXIuY2xhc3MsIGVtLmdldENsYXNzKCkpOworCisgICAgICAgICAgICBmb3IgKEV4Y2VwdGlvbiBleGNlcHRpb24gOiBlbS5leGNlcHRpb25zKSB7CisgICAgICAgICAgICAgICAgZmluYWwgVGhyb3dhYmxlIHQgPSBleGNlcHRpb247CisgICAgICAgICAgICAgICAgaWYgKHQgaW5zdGFuY2VvZiBBZGRyZXNzRXhjZXB0aW9uKSB7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNDb25uZWN0T3JUaW1lb3V0KHQpKSB7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGR1bXAodCk7CisgICAgICAgICAgICAgICAgICAgIGZhaWwodC50b1N0cmluZygpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnRGYWxzZShlbS5leGNlcHRpb25zLmlzRW1wdHkoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBtYW5hZ2VyLnJlc2V0KCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RWZXJpZnlQcm9wZXJ0aWVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFByb3BlcnRpZXMgcHJvcHMgPSBjcmVhdGVJbml0UHJvcGVydGllcygiIik7CisgICAgICAgIHByb3BzLnB1dCgic3ViamVjdCIsICJ0ZXN0Iik7CisgICAgICAgIHByb3BzLnB1dCgidmVyaWZ5IiwgImxpbWl0ZWQiKTsKKworICAgICAgICBJbnRlcm5hbEVycm9yTWFuYWdlciBlbSA9IG5ldyBJbnRlcm5hbEVycm9yTWFuYWdlcigpOworICAgICAgICBNYWlsSGFuZGxlciBpbnN0YW5jZSA9IG5ldyBNYWlsSGFuZGxlcigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaW5zdGFuY2Uuc2V0RXJyb3JNYW5hZ2VyKGVtKTsKKyAgICAgICAgICAgIGluc3RhbmNlLnNldE1haWxQcm9wZXJ0aWVzKHByb3BzKTsKKworICAgICAgICAgICAgZm9yIChFeGNlcHRpb24gZXhjZXB0aW9uIDogZW0uZXhjZXB0aW9ucykgeworICAgICAgICAgICAgICAgIGZpbmFsIFRocm93YWJsZSB0ID0gZXhjZXB0aW9uOworICAgICAgICAgICAgICAgIGlmICh0IGluc3RhbmNlb2YgQWRkcmVzc0V4Y2VwdGlvbiA9PSBmYWxzZSkgeworICAgICAgICAgICAgICAgICAgICBkdW1wKHQpOworICAgICAgICAgICAgICAgICAgICBmYWlsKHQudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIHByb3BzLnB1dCgidmVyaWZ5IiwgImxvY2FsIik7CisgICAgICAgIGluc3RhbmNlID0gbmV3IE1haWxIYW5kbGVyKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlbSA9IG5ldyBJbnRlcm5hbEVycm9yTWFuYWdlcigpOworICAgICAgICAgICAgaW5zdGFuY2Uuc2V0RXJyb3JNYW5hZ2VyKGVtKTsKKyAgICAgICAgICAgIGluc3RhbmNlLnNldE1haWxQcm9wZXJ0aWVzKHByb3BzKTsKKworICAgICAgICAgICAgZm9yIChFeGNlcHRpb24gZXhjZXB0aW9uIDogZW0uZXhjZXB0aW9ucykgeworICAgICAgICAgICAgICAgIGZpbmFsIFRocm93YWJsZSB0ID0gZXhjZXB0aW9uOworICAgICAgICAgICAgICAgIGlmICh0IGluc3RhbmNlb2YgQWRkcmVzc0V4Y2VwdGlvbiA9PSBmYWxzZSkgeworICAgICAgICAgICAgICAgICAgICBkdW1wKHQpOworICAgICAgICAgICAgICAgICAgICBmYWlsKHQudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKyAgICAgICAgfQorCisgICAgICAgIHByb3BzLnB1dCgidmVyaWZ5IiwgInJlc29sdmUiKTsKKyAgICAgICAgaW5zdGFuY2UgPSBuZXcgTWFpbEhhbmRsZXIoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVtID0gbmV3IEludGVybmFsRXJyb3JNYW5hZ2VyKCk7CisgICAgICAgICAgICBpbnN0YW5jZS5zZXRFcnJvck1hbmFnZXIoZW0pOworICAgICAgICAgICAgaW5zdGFuY2Uuc2V0TWFpbFByb3BlcnRpZXMocHJvcHMpOworCisgICAgICAgICAgICBmb3IgKEV4Y2VwdGlvbiBleGNlcHRpb24gOiBlbS5leGNlcHRpb25zKSB7CisgICAgICAgICAgICAgICAgZmluYWwgVGhyb3dhYmxlIHQgPSBleGNlcHRpb247CisgICAgICAgICAgICAgICAgaWYgKGlzQ29ubmVjdE9yVGltZW91dCh0KSkgeworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKHQgaW5zdGFuY2VvZiBBZGRyZXNzRXhjZXB0aW9uID09IGZhbHNlKSB7CisgICAgICAgICAgICAgICAgICAgIGR1bXAodCk7CisgICAgICAgICAgICAgICAgICAgIGZhaWwodC50b1N0cmluZygpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpbnN0YW5jZS5jbG9zZSgpOworICAgICAgICB9CisKKyAgICAgICAgcHJvcHMucHV0KCJ2ZXJpZnkiLCAibG9naW4iKTsKKyAgICAgICAgaW5zdGFuY2UgPSBuZXcgTWFpbEhhbmRsZXIoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGVtID0gbmV3IEludGVybmFsRXJyb3JNYW5hZ2VyKCk7CisgICAgICAgICAgICBpbnN0YW5jZS5zZXRFcnJvck1hbmFnZXIoZW0pOworICAgICAgICAgICAgaW5zdGFuY2Uuc2V0TWFpbFByb3BlcnRpZXMocHJvcHMpOworCisgICAgICAgICAgICBmb3IgKEV4Y2VwdGlvbiBleGNlcHRpb24gOiBlbS5leGNlcHRpb25zKSB7CisgICAgICAgICAgICAgICAgZmluYWwgVGhyb3dhYmxlIHQgPSBleGNlcHRpb247CisgICAgICAgICAgICAgICAgaWYgKGlzQ29ubmVjdE9yVGltZW91dCh0KSkgeworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKHQgaW5zdGFuY2VvZiBBZGRyZXNzRXhjZXB0aW9uID09IGZhbHNlKSB7CisgICAgICAgICAgICAgICAgICAgIGR1bXAodCk7CisgICAgICAgICAgICAgICAgICAgIGZhaWwodC50b1N0cmluZygpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpbnN0YW5jZS5jbG9zZSgpOworICAgICAgICB9CisKKyAgICAgICAgcHJvcHMucHV0KCJ2ZXJpZnkiLCAicmVtb3RlIik7CisgICAgICAgIGluc3RhbmNlID0gbmV3IE1haWxIYW5kbGVyKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlbSA9IG5ldyBJbnRlcm5hbEVycm9yTWFuYWdlcigpOworICAgICAgICAgICAgaW5zdGFuY2Uuc2V0RXJyb3JNYW5hZ2VyKGVtKTsKKyAgICAgICAgICAgIGluc3RhbmNlLnNldE1haWxQcm9wZXJ0aWVzKHByb3BzKTsKKworICAgICAgICAgICAgZm9yIChFeGNlcHRpb24gZXhjZXB0aW9uIDogZW0uZXhjZXB0aW9ucykgeworICAgICAgICAgICAgICAgIGZpbmFsIFRocm93YWJsZSB0ID0gZXhjZXB0aW9uOworICAgICAgICAgICAgICAgIGlmICh0IGluc3RhbmNlb2YgQWRkcmVzc0V4Y2VwdGlvbikgeworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGlzQ29ubmVjdE9yVGltZW91dCh0KSkgeworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBkdW1wKHQpOworICAgICAgICAgICAgICAgICAgICBmYWlsKHQudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFZlcmlmeVByb3BlcnRpZXNDb25zdHJ1Y3RvcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBMb2dNYW5hZ2VyIG1hbmFnZXIgPSBMb2dNYW5hZ2VyLmdldExvZ01hbmFnZXIoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG1hbmFnZXIucmVzZXQoKTsKKworICAgICAgICAgICAgZmluYWwgU3RyaW5nIHAgPSBNYWlsSGFuZGxlci5jbGFzcy5nZXROYW1lKCk7CisgICAgICAgICAgICBQcm9wZXJ0aWVzIHByb3BzID0gY3JlYXRlSW5pdFByb3BlcnRpZXMocCk7CisgICAgICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5zdWJqZWN0IiksIHAuY29uY2F0KCIgdGVzdCIpKTsKKyAgICAgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLmVycm9yTWFuYWdlciIpLCBJbnRlcm5hbEVycm9yTWFuYWdlci5jbGFzcy5nZXROYW1lKCkpOworICAgICAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIuZm9ybWF0dGVyIiksIFhNTEZvcm1hdHRlci5jbGFzcy5nZXROYW1lKCkpOworICAgICAgICAgICAgcmVhZChtYW5hZ2VyLCBwcm9wcyk7CisKKyAgICAgICAgICAgIHByb3BzID0gY3JlYXRlSW5pdFByb3BlcnRpZXMoIiIpOworICAgICAgICAgICAgcHJvcHMucHV0KCJzdWJqZWN0IiwgInRlc3QiKTsKKyAgICAgICAgICAgIHByb3BzLnB1dCgidmVyaWZ5IiwgImxpbWl0ZWQiKTsKKworICAgICAgICAgICAgTWFpbEhhbmRsZXIgaW5zdGFuY2UgPSBuZXcgTWFpbEhhbmRsZXIocHJvcHMpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBJbnRlcm5hbEVycm9yTWFuYWdlciBlbSA9IGludGVybmFsRXJyb3JNYW5hZ2VyRnJvbShpbnN0YW5jZSk7CisKKyAgICAgICAgICAgICAgICBmb3IgKEV4Y2VwdGlvbiBleGNlcHRpb24gOiBlbS5leGNlcHRpb25zKSB7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIFRocm93YWJsZSB0ID0gZXhjZXB0aW9uOworICAgICAgICAgICAgICAgICAgICBpZiAodCBpbnN0YW5jZW9mIEFkZHJlc3NFeGNlcHRpb24gPT0gZmFsc2UpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGR1bXAodCk7CisgICAgICAgICAgICAgICAgICAgICAgICBmYWlsKHQudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYXNzZXJ0RmFsc2UoZW0uZXhjZXB0aW9ucy5pc0VtcHR5KCkpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBpbnN0YW5jZS5jbG9zZSgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwcm9wcyA9IGNyZWF0ZUluaXRQcm9wZXJ0aWVzKCIiKTsKKyAgICAgICAgICAgIHByb3BzLnB1dCgibWFpbC50byIsICJiYWRBZGRyZXNzIik7CisgICAgICAgICAgICBwcm9wcy5wdXQoIm1haWwuY2MiLCAiYmFkQWRkcmVzcyIpOworICAgICAgICAgICAgcHJvcHMucHV0KCJzdWJqZWN0IiwgInRlc3QiKTsKKyAgICAgICAgICAgIHByb3BzLnB1dCgibWFpbC5mcm9tIiwgImJhZEFkZHJlc3MiKTsKKyAgICAgICAgICAgIHByb3BzLnB1dCgidmVyaWZ5IiwgImxvY2FsIik7CisKKyAgICAgICAgICAgIGluc3RhbmNlID0gbmV3IE1haWxIYW5kbGVyKHByb3BzKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgSW50ZXJuYWxFcnJvck1hbmFnZXIgZW0gPSBpbnRlcm5hbEVycm9yTWFuYWdlckZyb20oaW5zdGFuY2UpOworCisgICAgICAgICAgICAgICAgZm9yIChFeGNlcHRpb24gZXhjZXB0aW9uIDogZW0uZXhjZXB0aW9ucykgeworICAgICAgICAgICAgICAgICAgICBmaW5hbCBUaHJvd2FibGUgdCA9IGV4Y2VwdGlvbjsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHQgaW5zdGFuY2VvZiBBZGRyZXNzRXhjZXB0aW9uID09IGZhbHNlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBkdW1wKHQpOworICAgICAgICAgICAgICAgICAgICAgICAgZmFpbCh0LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGFzc2VydEZhbHNlKGVtLmV4Y2VwdGlvbnMuaXNFbXB0eSgpKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcHJvcHMucHV0KCJ2ZXJpZnkiLCAicmVzb2x2ZSIpOworCisgICAgICAgICAgICBpbnN0YW5jZSA9IG5ldyBNYWlsSGFuZGxlcihwcm9wcyk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIEludGVybmFsRXJyb3JNYW5hZ2VyIGVtID0gaW50ZXJuYWxFcnJvck1hbmFnZXJGcm9tKGluc3RhbmNlKTsKKworICAgICAgICAgICAgICAgIGZvciAoRXhjZXB0aW9uIGV4Y2VwdGlvbiA6IGVtLmV4Y2VwdGlvbnMpIHsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgVGhyb3dhYmxlIHQgPSBleGNlcHRpb247CisgICAgICAgICAgICAgICAgICAgIGlmIChpc0Nvbm5lY3RPclRpbWVvdXQodCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGlmICh0IGluc3RhbmNlb2YgQWRkcmVzc0V4Y2VwdGlvbiA9PSBmYWxzZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgZHVtcCh0KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZhaWwodC50b1N0cmluZygpKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBhc3NlcnRGYWxzZShlbS5leGNlcHRpb25zLmlzRW1wdHkoKSk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIGluc3RhbmNlLmNsb3NlKCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHByb3BzLnB1dCgidmVyaWZ5IiwgInJlbW90ZSIpOworICAgICAgICAgICAgaW5zdGFuY2UgPSBuZXcgTWFpbEhhbmRsZXIocHJvcHMpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBJbnRlcm5hbEVycm9yTWFuYWdlciBlbSA9IGludGVybmFsRXJyb3JNYW5hZ2VyRnJvbShpbnN0YW5jZSk7CisKKyAgICAgICAgICAgICAgICBmb3IgKEV4Y2VwdGlvbiBleGNlcHRpb24gOiBlbS5leGNlcHRpb25zKSB7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIFRocm93YWJsZSB0ID0gZXhjZXB0aW9uOworICAgICAgICAgICAgICAgICAgICBpZiAodCBpbnN0YW5jZW9mIEFkZHJlc3NFeGNlcHRpb24pIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGlzQ29ubmVjdE9yVGltZW91dCh0KSkgeworICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBkdW1wKHQpOworICAgICAgICAgICAgICAgICAgICAgICAgZmFpbCh0LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGFzc2VydEZhbHNlKGVtLmV4Y2VwdGlvbnMuaXNFbXB0eSgpKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIG1hbmFnZXIucmVzZXQoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdE5vVmVyaWZ5UmVwbGFjZWRQcm9wZXJ0aWVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIExvZ01hbmFnZXIgbWFuYWdlciA9IExvZ01hbmFnZXIuZ2V0TG9nTWFuYWdlcigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgbWFuYWdlci5yZXNldCgpOworCisgICAgICAgICAgICBmaW5hbCBTdHJpbmcgcCA9IE1haWxIYW5kbGVyLmNsYXNzLmdldE5hbWUoKTsKKyAgICAgICAgICAgIFByb3BlcnRpZXMgcHJvcHMgPSBjcmVhdGVJbml0UHJvcGVydGllcyhwKTsKKyAgICAgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLnN1YmplY3QiKSwgcC5jb25jYXQoIiB0ZXN0IikpOworICAgICAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIuZXJyb3JNYW5hZ2VyIiksIEludGVybmFsRXJyb3JNYW5hZ2VyLmNsYXNzLmdldE5hbWUoKSk7CisgICAgICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi52ZXJpZnkiKSwgInJlbW90ZSIpOworCisgICAgICAgICAgICByZWFkKG1hbmFnZXIsIHByb3BzKTsKKworICAgICAgICAgICAgLy9Vc2UgZW1wdHkgcHJvcGVydGllcyB0byBwcm92ZSBmYWxsYmFjayB0byBMb2dNYW5hZ2VyLgorICAgICAgICAgICAgTWFpbEhhbmRsZXIgaW5zdGFuY2UgPSBuZXcgTWFpbEhhbmRsZXIobmV3IFByb3BlcnRpZXMoKSk7CisgICAgICAgICAgICBJbnRlcm5hbEVycm9yTWFuYWdlciBlbSA9IGludGVybmFsRXJyb3JNYW5hZ2VyRnJvbShpbnN0YW5jZSk7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoSW50ZXJuYWxFcnJvck1hbmFnZXIuY2xhc3MsIGVtLmdldENsYXNzKCkpOworICAgICAgICAgICAgaW5zdGFuY2UuY2xvc2UoKTsKKworICAgICAgICAgICAgZm9yIChFeGNlcHRpb24gZXhjZXB0aW9uIDogZW0uZXhjZXB0aW9ucykgeworICAgICAgICAgICAgICAgIGZpbmFsIFRocm93YWJsZSB0ID0gZXhjZXB0aW9uOworICAgICAgICAgICAgICAgIGR1bXAodCk7CisgICAgICAgICAgICAgICAgZmFpbCh0LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VHJ1ZShlbS5leGNlcHRpb25zLmlzRW1wdHkoKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBtYW5hZ2VyLnJlc2V0KCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RJbml0U3ViamVjdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBJbnRlcm5hbEVycm9yTWFuYWdlciBlbTsKKyAgICAgICAgTWFpbEhhbmRsZXIgdGFyZ2V0OworICAgICAgICBmaW5hbCBTdHJpbmcgcCA9IE1haWxIYW5kbGVyLmNsYXNzLmdldE5hbWUoKTsKKyAgICAgICAgZmluYWwgTG9nTWFuYWdlciBtYW5hZ2VyID0gTG9nTWFuYWdlci5nZXRMb2dNYW5hZ2VyKCk7CisgICAgICAgIFByb3BlcnRpZXMgcHJvcHMgPSBjcmVhdGVJbml0UHJvcGVydGllcyhwKTsKKyAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIuZXJyb3JNYW5hZ2VyIiksIEludGVybmFsRXJyb3JNYW5hZ2VyLmNsYXNzLmdldE5hbWUoKSk7CisKKyAgICAgICAgLy90ZXN0IGNsYXNzIGNhc3QuCisgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLnN1YmplY3QiKSwgUHJvcGVydGllcy5jbGFzcy5nZXROYW1lKCkpOworCisgICAgICAgIHJlYWQobWFuYWdlciwgcHJvcHMpOworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0YXJnZXQgPSBuZXcgTWFpbEhhbmRsZXIoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZW0gPSBpbnRlcm5hbEVycm9yTWFuYWdlckZyb20odGFyZ2V0KTsKKyAgICAgICAgICAgICAgICBmb3IgKEV4Y2VwdGlvbiBleGNlcHRpb24gOiBlbS5leGNlcHRpb25zKSB7CisgICAgICAgICAgICAgICAgICAgIGR1bXAoZXhjZXB0aW9uKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShlbS5leGNlcHRpb25zLmlzRW1wdHkoKSk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHRhcmdldC5jbG9zZSgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvL3Rlc3QgbGlua2FnZSBlcnJvci4KKyAgICAgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLnN1YmplY3QiKSwgVGhyb3dGb3JtYXR0ZXIuY2xhc3MuZ2V0TmFtZSgpLnRvVXBwZXJDYXNlKExvY2FsZS5VUykpOworICAgICAgICAgICAgcmVhZChtYW5hZ2VyLCBwcm9wcyk7CisKKyAgICAgICAgICAgIHRhcmdldCA9IG5ldyBNYWlsSGFuZGxlcigpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBlbSA9IGludGVybmFsRXJyb3JNYW5hZ2VyRnJvbSh0YXJnZXQpOworICAgICAgICAgICAgICAgIGZvciAoRXhjZXB0aW9uIGV4Y2VwdGlvbiA6IGVtLmV4Y2VwdGlvbnMpIHsKKyAgICAgICAgICAgICAgICAgICAgZHVtcChleGNlcHRpb24pOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKGVtLmV4Y2VwdGlvbnMuaXNFbXB0eSgpKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgdGFyZ2V0LmNsb3NlKCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vdGVzdCBtaXhlZCBsaW5rYWdlIGVycm9yLgorICAgICAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIuc3ViamVjdCIpLCBQcm9wZXJ0aWVzLmNsYXNzLmdldE5hbWUoKS50b1VwcGVyQ2FzZShMb2NhbGUuVVMpKTsKKyAgICAgICAgICAgIHJlYWQobWFuYWdlciwgcHJvcHMpOworCisgICAgICAgICAgICB0YXJnZXQgPSBuZXcgTWFpbEhhbmRsZXIoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZW0gPSBpbnRlcm5hbEVycm9yTWFuYWdlckZyb20odGFyZ2V0KTsKKyAgICAgICAgICAgICAgICBmb3IgKEV4Y2VwdGlvbiBleGNlcHRpb24gOiBlbS5leGNlcHRpb25zKSB7CisgICAgICAgICAgICAgICAgICAgIGR1bXAoZXhjZXB0aW9uKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShlbS5leGNlcHRpb25zLmlzRW1wdHkoKSk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHRhcmdldC5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgbWFuYWdlci5yZXNldCgpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW5pdEF1dGhlbnRpY2F0b3IoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgLy9MaXRlcm5hbCBudWxsIGFuZCBudWxsIHJlZmVyZW5jZSBtZWFuIG5vIEF1dGhlbnRpY2F0b3IKKyAgICAgICAgLy93aGVuIGRlYWxpbmcgd2l0aCBhIHByb3BlcnRpZXMgZmlsZS4KKyAgICAgICAgdGVzdEluaXRBdXRoZW50aWNhdG9yKCJ1c2VyIiwgbnVsbCk7CisgICAgICAgIHRlc3RJbml0QXV0aGVudGljYXRvcigidXNlciIsICJudWxsIik7CisgICAgICAgIHRlc3RJbml0QXV0aGVudGljYXRvcigidXNlciIsICJOVUxMIik7CisgICAgICAgIHRlc3RJbml0QXV0aGVudGljYXRvcigidXNlciIsICJOdWxsIik7CisgICAgICAgIHRlc3RJbml0QXV0aGVudGljYXRvcigidXNlciIsICIiKTsKKyAgICAgICAgdGVzdEluaXRBdXRoZW50aWNhdG9yKCJ1c2VyIiwgInNvbWVwYXNzd29yZCIpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0SW5pdEF1dGhlbnRpY2F0b3IoU3RyaW5nIHVzZXIsIFN0cmluZyBwYXNzKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgSW50ZXJuYWxFcnJvck1hbmFnZXIgZW07CisgICAgICAgIE1haWxIYW5kbGVyIHRhcmdldDsKKyAgICAgICAgZmluYWwgU3RyaW5nIHAgPSBNYWlsSGFuZGxlci5jbGFzcy5nZXROYW1lKCk7CisgICAgICAgIGZpbmFsIExvZ01hbmFnZXIgbWFuYWdlciA9IExvZ01hbmFnZXIuZ2V0TG9nTWFuYWdlcigpOworICAgICAgICBmaW5hbCBQcm9wZXJ0aWVzIHByb3BzID0gY3JlYXRlSW5pdFByb3BlcnRpZXMocCk7CisgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLmVycm9yTWFuYWdlciIpLCBJbnRlcm5hbEVycm9yTWFuYWdlci5jbGFzcy5nZXROYW1lKCkpOworICAgICAgICBpZiAocGFzcyAhPSBudWxsKSB7CisgICAgICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5hdXRoZW50aWNhdG9yIiksIHBhc3MpOworICAgICAgICB9CisgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLm1haWwudHJhbnNwb3J0LnByb3RvY29sIiksICJzbXRwIik7CisKKyAgICAgICAgcmVhZChtYW5hZ2VyLCBwcm9wcyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0YXJnZXQgPSBuZXcgTWFpbEhhbmRsZXIoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZW0gPSBpbnRlcm5hbEVycm9yTWFuYWdlckZyb20odGFyZ2V0KTsKKyAgICAgICAgICAgICAgICBmb3IgKEV4Y2VwdGlvbiBleGNlcHRpb24gOiBlbS5leGNlcHRpb25zKSB7CisgICAgICAgICAgICAgICAgICAgIGR1bXAoZXhjZXB0aW9uKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShlbS5leGNlcHRpb25zLmlzRW1wdHkoKSk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHRhcmdldC5jbG9zZSgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAocGFzcyAhPSBudWxsICYmICEibnVsbCIuZXF1YWxzSWdub3JlQ2FzZShwYXNzKSkgeworICAgICAgICAgICAgICAgIGFzc2VydE5vdE51bGwodGFyZ2V0LmdldEF1dGhlbnRpY2F0b3IoKSk7CisgICAgICAgICAgICAgICAgUGFzc3dvcmRBdXRoZW50aWNhdGlvbiBpbml0UGEgPSBwYXNzd29yZEF1dGhlbnRpY2F0aW9uKAorICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LmdldEF1dGhlbnRpY2F0b3IoKSwgdXNlcik7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHVzZXIsIGluaXRQYS5nZXRVc2VyTmFtZSgpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMocGFzcywgaW5pdFBhLmdldFBhc3N3b3JkKCkpOworCisgICAgICAgICAgICAgICAgdGFyZ2V0LnNldEF1dGhlbnRpY2F0b3IocGFzcy50b0NoYXJBcnJheSgpKTsKKyAgICAgICAgICAgICAgICBQYXNzd29yZEF1dGhlbnRpY2F0aW9uIHNldFBhID0gcGFzc3dvcmRBdXRoZW50aWNhdGlvbigKKyAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldC5nZXRBdXRoZW50aWNhdG9yKCksIHVzZXIpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhzZXRQYS5nZXRVc2VyTmFtZSgpLCBpbml0UGEuZ2V0VXNlck5hbWUoKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKHNldFBhLmdldFBhc3N3b3JkKCksIGluaXRQYS5nZXRQYXNzd29yZCgpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0TnVsbCh0YXJnZXQuZ2V0QXV0aGVudGljYXRvcigpKTsKKyAgICAgICAgICAgICAgICB0YXJnZXQuc2V0QXV0aGVudGljYXRvcigoY2hhcltdKSBudWxsKTsKKyAgICAgICAgICAgICAgICBhc3NlcnROdWxsKHRhcmdldC5nZXRBdXRoZW50aWNhdG9yKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgbWFuYWdlci5yZXNldCgpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW5pdEF0dGFjaG1lbnRGaWx0ZXJzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEludGVybmFsRXJyb3JNYW5hZ2VyIGVtOworICAgICAgICBNYWlsSGFuZGxlciB0YXJnZXQ7CisgICAgICAgIGZpbmFsIFN0cmluZyBwID0gTWFpbEhhbmRsZXIuY2xhc3MuZ2V0TmFtZSgpOworICAgICAgICBmaW5hbCBMb2dNYW5hZ2VyIG1hbmFnZXIgPSBMb2dNYW5hZ2VyLmdldExvZ01hbmFnZXIoKTsKKyAgICAgICAgZmluYWwgUHJvcGVydGllcyBwcm9wcyA9IGNyZWF0ZUluaXRQcm9wZXJ0aWVzKHApOworICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5lcnJvck1hbmFnZXIiKSwgSW50ZXJuYWxFcnJvck1hbmFnZXIuY2xhc3MuZ2V0TmFtZSgpKTsKKyAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIuZmlsdGVyIiksIEVycm9yRmlsdGVyLmNsYXNzLmdldE5hbWUoKSk7CisgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLmF0dGFjaG1lbnQuZm9ybWF0dGVycyIpLCBTaW1wbGVGb3JtYXR0ZXIuY2xhc3MuZ2V0TmFtZSgpKTsKKyAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIuYXR0YWNobWVudC5uYW1lcyIpLCBQcm9wZXJ0aWVzLmNsYXNzLmdldE5hbWUoKSk7CisgICAgICAgIGFzc2VydE51bGwocHJvcHMuZ2V0UHJvcGVydHkocC5jb25jYXQoIi5hdHRhY2htZW50LmZpbHRlcnMiKSkpOworCisgICAgICAgIHJlYWQobWFuYWdlciwgcHJvcHMpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGFyZ2V0ID0gbmV3IE1haWxIYW5kbGVyKCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGVtID0gaW50ZXJuYWxFcnJvck1hbmFnZXJGcm9tKHRhcmdldCk7CisgICAgICAgICAgICAgICAgZm9yIChFeGNlcHRpb24gZXhjZXB0aW9uIDogZW0uZXhjZXB0aW9ucykgeworICAgICAgICAgICAgICAgICAgICBkdW1wKGV4Y2VwdGlvbik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGFzc2VydFRydWUoZW0uZXhjZXB0aW9ucy5pc0VtcHR5KCkpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICB0YXJnZXQuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIG1hbmFnZXIucmVzZXQoKTsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydEVxdWFscyhFcnJvckZpbHRlci5jbGFzcywgdGFyZ2V0LmdldEZpbHRlcigpLmdldENsYXNzKCkpOworICAgICAgICBhc3NlcnRFcXVhbHModGFyZ2V0LmdldEZpbHRlcigpLCB0YXJnZXQuZ2V0QXR0YWNobWVudEZpbHRlcnMoKVswXSk7CisKKyAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIuYXR0YWNobWVudC5mb3JtYXR0ZXJzIiksCisgICAgICAgICAgICAgICAgU2ltcGxlRm9ybWF0dGVyLmNsYXNzLmdldE5hbWUoKSArICIsICIKKyAgICAgICAgICAgICAgICArIFNpbXBsZUZvcm1hdHRlci5jbGFzcy5nZXROYW1lKCkgKyAiLCAiCisgICAgICAgICAgICAgICAgKyBTaW1wbGVGb3JtYXR0ZXIuY2xhc3MuZ2V0TmFtZSgpICsgIiwgIgorICAgICAgICAgICAgICAgICsgU2ltcGxlRm9ybWF0dGVyLmNsYXNzLmdldE5hbWUoKSk7CisgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLmF0dGFjaG1lbnQubmFtZXMiKSwgImEudHh0LCBiLnR4dCwgYy50eHQsIGQudHh0Iik7CisgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLmF0dGFjaG1lbnQuZmlsdGVycyIpLCAibnVsbCwgIgorICAgICAgICAgICAgICAgICsgVGhyb3dGaWx0ZXIuY2xhc3MuZ2V0TmFtZSgpKTsKKworICAgICAgICByZWFkKG1hbmFnZXIsIHByb3BzKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRhcmdldCA9IG5ldyBNYWlsSGFuZGxlcigpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBlbSA9IGludGVybmFsRXJyb3JNYW5hZ2VyRnJvbSh0YXJnZXQpOworICAgICAgICAgICAgICAgIGZvciAoRXhjZXB0aW9uIGV4Y2VwdGlvbiA6IGVtLmV4Y2VwdGlvbnMpIHsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgVGhyb3dhYmxlIHQgPSBleGNlcHRpb247CisgICAgICAgICAgICAgICAgICAgIGlmICh0IGluc3RhbmNlb2YgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbikgeworICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgZHVtcCh0KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYXNzZXJ0RmFsc2UoZW0uZXhjZXB0aW9ucy5pc0VtcHR5KCkpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICB0YXJnZXQuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIG1hbmFnZXIucmVzZXQoKTsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydEVxdWFscyhFcnJvckZpbHRlci5jbGFzcywgdGFyZ2V0LmdldEZpbHRlcigpLmdldENsYXNzKCkpOworICAgICAgICBhc3NlcnROdWxsKHRhcmdldC5nZXRBdHRhY2htZW50RmlsdGVycygpWzBdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFRocm93RmlsdGVyLmNsYXNzLAorICAgICAgICAgICAgICAgIHRhcmdldC5nZXRBdHRhY2htZW50RmlsdGVycygpWzFdLmdldENsYXNzKCkpOworICAgICAgICBhc3NlcnRFcXVhbHModGFyZ2V0LmdldEZpbHRlcigpLCB0YXJnZXQuZ2V0QXR0YWNobWVudEZpbHRlcnMoKVsyXSk7CisgICAgICAgIGFzc2VydEVxdWFscyh0YXJnZXQuZ2V0RmlsdGVyKCksIHRhcmdldC5nZXRBdHRhY2htZW50RmlsdGVycygpWzNdKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RJbml0QXR0YWNobWVudE5hbWVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIEludGVybmFsRXJyb3JNYW5hZ2VyIGVtOworICAgICAgICBNYWlsSGFuZGxlciB0YXJnZXQ7CisgICAgICAgIGZpbmFsIFN0cmluZyBwID0gTWFpbEhhbmRsZXIuY2xhc3MuZ2V0TmFtZSgpOworICAgICAgICBmaW5hbCBMb2dNYW5hZ2VyIG1hbmFnZXIgPSBMb2dNYW5hZ2VyLmdldExvZ01hbmFnZXIoKTsKKyAgICAgICAgUHJvcGVydGllcyBwcm9wcyA9IGNyZWF0ZUluaXRQcm9wZXJ0aWVzKHApOworICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5lcnJvck1hbmFnZXIiKSwgSW50ZXJuYWxFcnJvck1hbmFnZXIuY2xhc3MuZ2V0TmFtZSgpKTsKKworICAgICAgICAvL3Rlc3QgY2xhc3MgY2FzdC4KKyAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIuYXR0YWNobWVudC5mb3JtYXR0ZXJzIiksIFNpbXBsZUZvcm1hdHRlci5jbGFzcy5nZXROYW1lKCkpOworICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5hdHRhY2htZW50Lm5hbWVzIiksIFByb3BlcnRpZXMuY2xhc3MuZ2V0TmFtZSgpKTsKKworICAgICAgICByZWFkKG1hbmFnZXIsIHByb3BzKTsKKworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGFyZ2V0ID0gbmV3IE1haWxIYW5kbGVyKCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGVtID0gaW50ZXJuYWxFcnJvck1hbmFnZXJGcm9tKHRhcmdldCk7CisgICAgICAgICAgICAgICAgZm9yIChFeGNlcHRpb24gZXhjZXB0aW9uIDogZW0uZXhjZXB0aW9ucykgeworICAgICAgICAgICAgICAgICAgICBkdW1wKGV4Y2VwdGlvbik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGFzc2VydFRydWUoZW0uZXhjZXB0aW9ucy5pc0VtcHR5KCkpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICB0YXJnZXQuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy90ZXN0IGxpbmthZ2UgZXJyb3IuCisgICAgICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5hdHRhY2htZW50LmZvcm1hdHRlcnMiKSwgU2ltcGxlRm9ybWF0dGVyLmNsYXNzLmdldE5hbWUoKSk7CisgICAgICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5hdHRhY2htZW50Lm5hbWVzIiksIFNpbXBsZUZvcm1hdHRlci5jbGFzcy5nZXROYW1lKCkudG9VcHBlckNhc2UoTG9jYWxlLlVTKSk7CisKKyAgICAgICAgICAgIHJlYWQobWFuYWdlciwgcHJvcHMpOworCisgICAgICAgICAgICB0YXJnZXQgPSBuZXcgTWFpbEhhbmRsZXIoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZW0gPSBpbnRlcm5hbEVycm9yTWFuYWdlckZyb20odGFyZ2V0KTsKKyAgICAgICAgICAgICAgICBmb3IgKEV4Y2VwdGlvbiBleGNlcHRpb24gOiBlbS5leGNlcHRpb25zKSB7CisgICAgICAgICAgICAgICAgICAgIGR1bXAoZXhjZXB0aW9uKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShlbS5leGNlcHRpb25zLmlzRW1wdHkoKSk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHRhcmdldC5jbG9zZSgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvL3Rlc3QgbWl4ZWQgbGlua2FnZSBlcnJvci4KKyAgICAgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLmF0dGFjaG1lbnQuZm9ybWF0dGVycyIpLCBTaW1wbGVGb3JtYXR0ZXIuY2xhc3MuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLmF0dGFjaG1lbnQubmFtZXMiKSwgUHJvcGVydGllcy5jbGFzcy5nZXROYW1lKCkudG9VcHBlckNhc2UoTG9jYWxlLlVTKSk7CisgICAgICAgICAgICByZWFkKG1hbmFnZXIsIHByb3BzKTsKKworICAgICAgICAgICAgdGFyZ2V0ID0gbmV3IE1haWxIYW5kbGVyKCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGVtID0gaW50ZXJuYWxFcnJvck1hbmFnZXJGcm9tKHRhcmdldCk7CisgICAgICAgICAgICAgICAgZm9yIChFeGNlcHRpb24gZXhjZXB0aW9uIDogZW0uZXhjZXB0aW9ucykgeworICAgICAgICAgICAgICAgICAgICBkdW1wKGV4Y2VwdGlvbik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGFzc2VydFRydWUoZW0uZXhjZXB0aW9ucy5pc0VtcHR5KCkpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICB0YXJnZXQuY2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIG1hbmFnZXIucmVzZXQoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEluaXRFcnJvck1hbmFnZXJFeGNlcHRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU3RyaW5nIGVuY29kaW5nID0gU3lzdGVtLmdldFByb3BlcnR5KCJmaWxlLmVuY29kaW5nIiwgIjg4NTlfMSIpOworICAgICAgICBmaW5hbCBTdHJpbmcgcCA9IE1haWxIYW5kbGVyLmNsYXNzLmdldE5hbWUoKTsKKyAgICAgICAgZmluYWwgUHJvcGVydGllcyBwcm9wcyA9IGNyZWF0ZUluaXRQcm9wZXJ0aWVzKHApOworICAgICAgICBTdHJpbmcga2V5OworCisgICAgICAgIHNldFBlbmRpbmcobmV3IFJ1bnRpbWVFeGNlcHRpb24oKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrZXkgPSBwLmNvbmNhdCgiLmVycm9yTWFuYWdlciIpOworICAgICAgICAgICAgcHJvcHMucHV0KGtleSwgSW5pdEVycm9yTWFuYWdlci5jbGFzcy5nZXROYW1lKCkpOworCisgICAgICAgICAgICBmaW5hbCBMb2dNYW5hZ2VyIG1hbmFnZXIgPSBMb2dNYW5hZ2VyLmdldExvZ01hbmFnZXIoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcmVhZChtYW5hZ2VyLCBwcm9wcyk7CisgICAgICAgICAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIG9sZEVycm9ycyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgICAgICAgICBQcmludFN0cmVhbSBuZXdFcnIgPSBuZXcgUHJpbnRTdHJlYW0ob2xkRXJyb3JzLCBmYWxzZSwgZW5jb2RpbmcpOworICAgICAgICAgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJVc2VPZlN5c3RlbU91dE9yU3lzdGVtRXJyIikKKyAgICAgICAgICAgICAgICBmaW5hbCBQcmludFN0cmVhbSBlcnIgPSBTeXN0ZW0uZXJyOworICAgICAgICAgICAgICAgIFN5c3RlbS5zZXRFcnIobmV3RXJyKTsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBmaW5hbCBNYWlsSGFuZGxlciB0YXJnZXQgPSBuZXcgTWFpbEhhbmRsZXIoKTsKKyAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5zZXRFcnIoZXJyKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldC5zZXRFcnJvck1hbmFnZXIobmV3IEVycm9yTWFuYWdlcigpKTsKKyAgICAgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldC5jbG9zZSgpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLnNldEVycihlcnIpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIC8vamF2YS51dGlsLmxvZ2dpbmcuRXJyb3JNYW5hZ2VyOiA0CisgICAgICAgICAgICAgICAgLy9qYXZhLmxhbmcucmVmbGVjdC5JbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uCisgICAgICAgICAgICAgICAgLy8gYXQuLi4KKyAgICAgICAgICAgICAgICAvL0NhdXNlZCBieTogamF2YS5sYW5nLlJ1bnRpbWVFeGNlcHRpb24KKyAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgZGF0YSA9IG9sZEVycm9ycy50b1N0cmluZyhlbmNvZGluZyk7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShkYXRhLCBkYXRhLmNvbnRhaW5zKEVycm9yTWFuYWdlci5jbGFzcy5nZXROYW1lKCkpKTsKKyAgICAgICAgICAgICAgICBpbnQgaXRlLCByZTsKKyAgICAgICAgICAgICAgICBpdGUgPSBkYXRhLmluZGV4T2YoSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbi5jbGFzcy5nZXROYW1lKCkpOworICAgICAgICAgICAgICAgIHJlID0gZGF0YS5pbmRleE9mKFJ1bnRpbWVFeGNlcHRpb24uY2xhc3MuZ2V0TmFtZSgpLCBpdGUpOworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoZGF0YSwgaXRlIDwgcmUpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBtYW5hZ2VyLnJlc2V0KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBzZXRQZW5kaW5nKChUaHJvd2FibGUpIG51bGwpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW5pdEVycm9yTWFuYWdlckVycm9yKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFN0cmluZyBlbmNvZGluZyA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiZmlsZS5lbmNvZGluZyIsICI4ODU5XzEiKTsKKyAgICAgICAgZmluYWwgU3RyaW5nIHAgPSBNYWlsSGFuZGxlci5jbGFzcy5nZXROYW1lKCk7CisgICAgICAgIGZpbmFsIFByb3BlcnRpZXMgcHJvcHMgPSBjcmVhdGVJbml0UHJvcGVydGllcyhwKTsKKyAgICAgICAgU3RyaW5nIGtleTsKKworICAgICAgICBzZXRQZW5kaW5nKG5ldyBFcnJvcigpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtleSA9IHAuY29uY2F0KCIuZXJyb3JNYW5hZ2VyIik7CisgICAgICAgICAgICBwcm9wcy5wdXQoa2V5LCBJbml0RXJyb3JNYW5hZ2VyLmNsYXNzLmdldE5hbWUoKSk7CisKKyAgICAgICAgICAgIGZpbmFsIExvZ01hbmFnZXIgbWFuYWdlciA9IExvZ01hbmFnZXIuZ2V0TG9nTWFuYWdlcigpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICByZWFkKG1hbmFnZXIsIHByb3BzKTsKKyAgICAgICAgICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gb2xkRXJyb3JzID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICAgICAgICAgIFByaW50U3RyZWFtIG5ld0VyciA9IG5ldyBQcmludFN0cmVhbShvbGRFcnJvcnMsIGZhbHNlLCBlbmNvZGluZyk7CisgICAgICAgICAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoIlVzZU9mU3lzdGVtT3V0T3JTeXN0ZW1FcnIiKQorICAgICAgICAgICAgICAgIGZpbmFsIFByaW50U3RyZWFtIGVyciA9IFN5c3RlbS5lcnI7CisgICAgICAgICAgICAgICAgU3lzdGVtLnNldEVycihuZXdFcnIpOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIE1haWxIYW5kbGVyIHRhcmdldCA9IG5ldyBNYWlsSGFuZGxlcigpOworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLnNldEVycihlcnIpOworICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LnNldEVycm9yTWFuYWdlcihuZXcgRXJyb3JNYW5hZ2VyKCkpOworICAgICAgICAgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uc2V0RXJyKGVycik7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgLy9qYXZhLnV0aWwubG9nZ2luZy5FcnJvck1hbmFnZXI6IDQKKyAgICAgICAgICAgICAgICAvL2phdmEubGFuZy5yZWZsZWN0Lkludm9jYXRpb25UYXJnZXRFeGNlcHRpb24KKyAgICAgICAgICAgICAgICAvLyBhdC4uLgorICAgICAgICAgICAgICAgIC8vQ2F1c2VkIGJ5OiBqYXZhLmxhbmcuRXJyb3IKKyAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgZGF0YSA9IG9sZEVycm9ycy50b1N0cmluZyhlbmNvZGluZyk7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShkYXRhLCBkYXRhLmNvbnRhaW5zKEVycm9yTWFuYWdlci5jbGFzcy5nZXROYW1lKCkpKTsKKyAgICAgICAgICAgICAgICBpbnQgaXRlLCByZTsKKyAgICAgICAgICAgICAgICBpdGUgPSBkYXRhLmluZGV4T2YoSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbi5jbGFzcy5nZXROYW1lKCkpOworICAgICAgICAgICAgICAgIHJlID0gZGF0YS5pbmRleE9mKEVycm9yLmNsYXNzLmdldE5hbWUoKSwgaXRlKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKGRhdGEsIGl0ZSA8IHJlKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgbWFuYWdlci5yZXNldCgpOworICAgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgc2V0UGVuZGluZygoVGhyb3dhYmxlKSBudWxsKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEluaXRFcnJvcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBTdHJpbmcgcCA9IE1haWxIYW5kbGVyLmNsYXNzLmdldE5hbWUoKTsKKyAgICAgICAgZmluYWwgUHJvcGVydGllcyBwcm9wcyA9IGNyZWF0ZUluaXRQcm9wZXJ0aWVzKHApOworICAgICAgICBTdHJpbmcgZmlsdGVyOworICAgICAgICBTdHJpbmcgbmFtZTsKKyAgICAgICAgU3RyaW5nIGtleTsKKworICAgICAgICBzZXRQZW5kaW5nKG5ldyBFcnJvcigpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtleSA9IHAuY29uY2F0KCIuYXV0aGVudGljYXRvciIpOworICAgICAgICAgICAgcHJvcHMucHV0KGtleSwgSW5pdEF1dGhlbnRpY2F0b3IuY2xhc3MuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIHRlc3RJbml0RXJyb3IocHJvcHMpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChwcm9wcy5yZW1vdmUoa2V5KSk7CisKKyAgICAgICAgICAgIGtleSA9IHAuY29uY2F0KCIuY29tcGFyYXRvciIpOworICAgICAgICAgICAgcHJvcHMucHV0KGtleSwgSW5pdENvbXBhcmF0b3IuY2xhc3MuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIHRlc3RJbml0RXJyb3IocHJvcHMpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChwcm9wcy5yZW1vdmUoa2V5KSk7CisKKyAgICAgICAgICAgIGtleSA9IHAuY29uY2F0KCIuZmlsdGVyIik7CisgICAgICAgICAgICBwcm9wcy5wdXQoa2V5LCBJbml0RmlsdGVyLmNsYXNzLmdldE5hbWUoKSk7CisgICAgICAgICAgICB0ZXN0SW5pdEVycm9yKHByb3BzKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwocHJvcHMucmVtb3ZlKGtleSkpOworCisgICAgICAgICAgICBrZXkgPSBwLmNvbmNhdCgiLmZvcm1hdHRlciIpOworICAgICAgICAgICAgcHJvcHMucHV0KGtleSwgSW5pdEZvcm1hdHRlci5jbGFzcy5nZXROYW1lKCkpOworICAgICAgICAgICAgdGVzdEluaXRFcnJvcihwcm9wcyk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHByb3BzLnJlbW92ZShrZXkpKTsKKworICAgICAgICAgICAga2V5ID0gcC5jb25jYXQoIi5zdWJqZWN0Iik7CisgICAgICAgICAgICBwcm9wcy5wdXQoa2V5LCBJbml0Rm9ybWF0dGVyLmNsYXNzLmdldE5hbWUoKSk7CisgICAgICAgICAgICB0ZXN0SW5pdEVycm9yKHByb3BzKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwocHJvcHMucmVtb3ZlKGtleSkpOworCisgICAgICAgICAgICBrZXkgPSBwLmNvbmNhdCgiLmF0dGFjaG1lbnQuZm9ybWF0dGVycyIpOworICAgICAgICAgICAgcHJvcHMucHV0KGtleSwgSW5pdEZvcm1hdHRlci5jbGFzcy5nZXROYW1lKCkpOworICAgICAgICAgICAgdGVzdEluaXRFcnJvcihwcm9wcyk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHByb3BzLnJlbW92ZShrZXkpKTsKKworICAgICAgICAgICAga2V5ID0gcC5jb25jYXQoIi5hdHRhY2htZW50LmZvcm1hdHRlcnMiKTsKKyAgICAgICAgICAgIHByb3BzLnB1dChrZXksIFRocm93Rm9ybWF0dGVyLmNsYXNzLmdldE5hbWUoKSk7CisgICAgICAgICAgICBmaWx0ZXIgPSBwLmNvbmNhdCgiLmF0dGFjaG1lbnQuZmlsdGVycyIpOworICAgICAgICAgICAgcHJvcHMucHV0KGZpbHRlciwgSW5pdEZpbHRlci5jbGFzcy5nZXROYW1lKCkpOworICAgICAgICAgICAgbmFtZSA9IHAuY29uY2F0KCIuYXR0YWNobWVudC5uYW1lcyIpOworICAgICAgICAgICAgcHJvcHMucHV0KG5hbWUsICJ0ZXN0LnR4dCIpOworICAgICAgICAgICAgdGVzdEluaXRFcnJvcihwcm9wcyk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHByb3BzLnJlbW92ZShrZXkpKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwocHJvcHMucmVtb3ZlKG5hbWUpKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwocHJvcHMucmVtb3ZlKGZpbHRlcikpOworCisgICAgICAgICAgICBrZXkgPSBwLmNvbmNhdCgiLmF0dGFjaG1lbnQuZm9ybWF0dGVycyIpOworICAgICAgICAgICAgcHJvcHMucHV0KGtleSwgVGhyb3dGb3JtYXR0ZXIuY2xhc3MuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIG5hbWUgPSBwLmNvbmNhdCgiLmF0dGFjaG1lbnQubmFtZXMiKTsKKyAgICAgICAgICAgIHByb3BzLnB1dChuYW1lLCBJbml0Rm9ybWF0dGVyLmNsYXNzLmdldE5hbWUoKSk7CisgICAgICAgICAgICB0ZXN0SW5pdEVycm9yKHByb3BzKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwocHJvcHMucmVtb3ZlKGtleSkpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChwcm9wcy5yZW1vdmUobmFtZSkpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgc2V0UGVuZGluZygoVGhyb3dhYmxlKSBudWxsKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0SW5pdEVycm9yKFByb3BlcnRpZXMgcHJvcHMpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0SW5pdEV4Y2VwdGlvbihwcm9wcyk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0SW5pdEV4Y2VwdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBTdHJpbmcgcCA9IE1haWxIYW5kbGVyLmNsYXNzLmdldE5hbWUoKTsKKyAgICAgICAgZmluYWwgUHJvcGVydGllcyBwcm9wcyA9IGNyZWF0ZUluaXRQcm9wZXJ0aWVzKHApOworICAgICAgICBTdHJpbmcgZmlsdGVyOworICAgICAgICBTdHJpbmcgbmFtZTsKKyAgICAgICAgU3RyaW5nIGtleTsKKworICAgICAgICBzZXRQZW5kaW5nKG5ldyBSdW50aW1lRXhjZXB0aW9uKCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAga2V5ID0gcC5jb25jYXQoIi5hdXRoZW50aWNhdG9yIik7CisgICAgICAgICAgICBwcm9wcy5wdXQoa2V5LCBJbml0QXV0aGVudGljYXRvci5jbGFzcy5nZXROYW1lKCkpOworICAgICAgICAgICAgdGVzdEluaXRFeGNlcHRpb24ocHJvcHMpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChwcm9wcy5yZW1vdmUoa2V5KSk7CisKKyAgICAgICAgICAgIGtleSA9IHAuY29uY2F0KCIuY29tcGFyYXRvciIpOworICAgICAgICAgICAgcHJvcHMucHV0KGtleSwgSW5pdENvbXBhcmF0b3IuY2xhc3MuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIHRlc3RJbml0RXhjZXB0aW9uKHByb3BzKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwocHJvcHMucmVtb3ZlKGtleSkpOworCisgICAgICAgICAgICBrZXkgPSBwLmNvbmNhdCgiLmZpbHRlciIpOworICAgICAgICAgICAgcHJvcHMucHV0KGtleSwgSW5pdEZpbHRlci5jbGFzcy5nZXROYW1lKCkpOworICAgICAgICAgICAgdGVzdEluaXRFeGNlcHRpb24ocHJvcHMpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChwcm9wcy5yZW1vdmUoa2V5KSk7CisKKyAgICAgICAgICAgIGtleSA9IHAuY29uY2F0KCIuZm9ybWF0dGVyIik7CisgICAgICAgICAgICBwcm9wcy5wdXQoa2V5LCBJbml0Rm9ybWF0dGVyLmNsYXNzLmdldE5hbWUoKSk7CisgICAgICAgICAgICB0ZXN0SW5pdEV4Y2VwdGlvbihwcm9wcyk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHByb3BzLnJlbW92ZShrZXkpKTsKKworICAgICAgICAgICAga2V5ID0gcC5jb25jYXQoIi5zdWJqZWN0Iik7CisgICAgICAgICAgICBwcm9wcy5wdXQoa2V5LCBJbml0Rm9ybWF0dGVyLmNsYXNzLmdldE5hbWUoKSk7CisgICAgICAgICAgICB0ZXN0SW5pdEV4Y2VwdGlvbihwcm9wcyk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHByb3BzLnJlbW92ZShrZXkpKTsKKworICAgICAgICAgICAga2V5ID0gcC5jb25jYXQoIi5hdHRhY2htZW50LmZvcm1hdHRlcnMiKTsKKyAgICAgICAgICAgIHByb3BzLnB1dChrZXksIEluaXRGb3JtYXR0ZXIuY2xhc3MuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIHRlc3RJbml0RXhjZXB0aW9uKHByb3BzKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwocHJvcHMucmVtb3ZlKGtleSkpOworCisgICAgICAgICAgICBrZXkgPSBwLmNvbmNhdCgiLmF0dGFjaG1lbnQuZm9ybWF0dGVycyIpOworICAgICAgICAgICAgcHJvcHMucHV0KGtleSwgVGhyb3dGb3JtYXR0ZXIuY2xhc3MuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGZpbHRlciA9IHAuY29uY2F0KCIuYXR0YWNobWVudC5maWx0ZXJzIik7CisgICAgICAgICAgICBwcm9wcy5wdXQoZmlsdGVyLCBJbml0RmlsdGVyLmNsYXNzLmdldE5hbWUoKSk7CisgICAgICAgICAgICBuYW1lID0gcC5jb25jYXQoIi5hdHRhY2htZW50Lm5hbWVzIik7CisgICAgICAgICAgICBwcm9wcy5wdXQobmFtZSwgInRlc3QudHh0Iik7CisgICAgICAgICAgICB0ZXN0SW5pdEV4Y2VwdGlvbihwcm9wcyk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHByb3BzLnJlbW92ZShrZXkpKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwocHJvcHMucmVtb3ZlKG5hbWUpKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwocHJvcHMucmVtb3ZlKGZpbHRlcikpOworCisgICAgICAgICAgICBrZXkgPSBwLmNvbmNhdCgiLmF0dGFjaG1lbnQuZm9ybWF0dGVycyIpOworICAgICAgICAgICAgcHJvcHMucHV0KGtleSwgVGhyb3dGb3JtYXR0ZXIuY2xhc3MuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIG5hbWUgPSBwLmNvbmNhdCgiLmF0dGFjaG1lbnQubmFtZXMiKTsKKyAgICAgICAgICAgIHByb3BzLnB1dChuYW1lLCBJbml0Rm9ybWF0dGVyLmNsYXNzLmdldE5hbWUoKSk7CisgICAgICAgICAgICB0ZXN0SW5pdEV4Y2VwdGlvbihwcm9wcyk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHByb3BzLnJlbW92ZShrZXkpKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwocHJvcHMucmVtb3ZlKG5hbWUpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHNldFBlbmRpbmcoKFRocm93YWJsZSkgbnVsbCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdGVzdEluaXRFeGNlcHRpb24oUHJvcGVydGllcyBwcm9wcykgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIExvZ01hbmFnZXIgbWFuYWdlciA9IExvZ01hbmFnZXIuZ2V0TG9nTWFuYWdlcigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVhZChtYW5hZ2VyLCBwcm9wcyk7CisgICAgICAgICAgICBmaW5hbCBNYWlsSGFuZGxlciB0YXJnZXQgPSBuZXcgTWFpbEhhbmRsZXIoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgSW50ZXJuYWxFcnJvck1hbmFnZXIgZW0gPSBpbnRlcm5hbEVycm9yTWFuYWdlckZyb20odGFyZ2V0KTsKKyAgICAgICAgICAgICAgICBuZXh0OgorICAgICAgICAgICAgICAgIGZvciAoRXhjZXB0aW9uIHQgOiBlbS5leGNlcHRpb25zKSB7CisgICAgICAgICAgICAgICAgICAgIGZvciAoVGhyb3dhYmxlIGNhdXNlID0gdDsgY2F1c2UgIT0gbnVsbDsgY2F1c2UgPSBjYXVzZS5nZXRDYXVzZSgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2F1c2UgPT0gZ2V0UGVuZGluZygpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUgbmV4dDsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBkdW1wKHQpOworICAgICAgICAgICAgICAgICAgICBmYWlsKHQudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGFzc2VydEZhbHNlKGVtLmV4Y2VwdGlvbnMuaXNFbXB0eSgpKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgdGFyZ2V0LmNsb3NlKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBtYW5hZ2VyLnJlc2V0KCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RTdGF0aWNJbml0RXJyb3JNYW5hZ2VyRXhjZXB0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFN0cmluZyBlbmNvZGluZyA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiZmlsZS5lbmNvZGluZyIsICI4ODU5XzEiKTsKKyAgICAgICAgZmluYWwgU3RyaW5nIHRlc3QgPSBNYWlsSGFuZGxlclRlc3QuY2xhc3MuZ2V0TmFtZSgpOworICAgICAgICBmaW5hbCBTdHJpbmcgcCA9IE1haWxIYW5kbGVyLmNsYXNzLmdldE5hbWUoKTsKKyAgICAgICAgZmluYWwgUHJvcGVydGllcyBwcm9wcyA9IGNyZWF0ZUluaXRQcm9wZXJ0aWVzKHApOworICAgICAgICBTdHJpbmcga2V5OworCisgICAgICAgIHNldFBlbmRpbmcobmV3IFJ1bnRpbWVFeGNlcHRpb24oKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrZXkgPSBwLmNvbmNhdCgiLmVycm9yTWFuYWdlciIpOworICAgICAgICAgICAgcHJvcHMucHV0KGtleSwgdGVzdC5jb25jYXQoIiRTdGF0aWNJbml0UmVFcnJvck1hbmFnZXIiKSk7CisKKyAgICAgICAgICAgIGZpbmFsIExvZ01hbmFnZXIgbWFuYWdlciA9IExvZ01hbmFnZXIuZ2V0TG9nTWFuYWdlcigpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICByZWFkKG1hbmFnZXIsIHByb3BzKTsKKyAgICAgICAgICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gb2xkRXJyb3JzID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICAgICAgICAgIFByaW50U3RyZWFtIG5ld0VyciA9IG5ldyBQcmludFN0cmVhbShvbGRFcnJvcnMsIGZhbHNlLCBlbmNvZGluZyk7CisgICAgICAgICAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoIlVzZU9mU3lzdGVtT3V0T3JTeXN0ZW1FcnIiKQorICAgICAgICAgICAgICAgIGZpbmFsIFByaW50U3RyZWFtIGVyciA9IFN5c3RlbS5lcnI7CisgICAgICAgICAgICAgICAgU3lzdGVtLnNldEVycihuZXdFcnIpOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIE1haWxIYW5kbGVyIHRhcmdldCA9IG5ldyBNYWlsSGFuZGxlcigpOworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLnNldEVycihlcnIpOworICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LnNldEVycm9yTWFuYWdlcihuZXcgRXJyb3JNYW5hZ2VyKCkpOworICAgICAgICAgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LmNsb3NlKCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uc2V0RXJyKGVycik7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgLy9qYXZhLnV0aWwubG9nZ2luZy5FcnJvck1hbmFnZXI6IDQKKyAgICAgICAgICAgICAgICAvL2phdmEubGFuZy5yZWZsZWN0Lkludm9jYXRpb25UYXJnZXRFeGNlcHRpb24KKyAgICAgICAgICAgICAgICAvLyBhdCAuLi4uCisgICAgICAgICAgICAgICAgLy9DYXVzZWQgYnk6IGphdmEubGFuZy5FeGNlcHRpb25JbkluaXRpYWxpemVyRXJyb3IKKyAgICAgICAgICAgICAgICAvLyBhdC4uLgorICAgICAgICAgICAgICAgIC8vQ2F1c2VkIGJ5OiBqYXZhLmxhbmcuUnVudGltZUV4Y2VwdGlvbgorICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBkYXRhID0gb2xkRXJyb3JzLnRvU3RyaW5nKGVuY29kaW5nKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKGRhdGEsIGRhdGEuY29udGFpbnMoRXJyb3JNYW5hZ2VyLmNsYXNzLmdldE5hbWUoKSkpOworICAgICAgICAgICAgICAgIGludCBpdGUsIGVpaWUsIHJlOworICAgICAgICAgICAgICAgIGl0ZSA9IGRhdGEuaW5kZXhPZihJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uLmNsYXNzLmdldE5hbWUoKSk7CisgICAgICAgICAgICAgICAgZWlpZSA9IGRhdGEuaW5kZXhPZihFeGNlcHRpb25JbkluaXRpYWxpemVyRXJyb3IuY2xhc3MuZ2V0TmFtZSgpLCBpdGUpOworICAgICAgICAgICAgICAgIGlmIChlaWllIDwgMCkgeworICAgICAgICAgICAgICAgICAgICByZSA9IGRhdGEuaW5kZXhPZihSdW50aW1lRXhjZXB0aW9uLmNsYXNzLmdldE5hbWUoKSwgaXRlKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShkYXRhLCBpdGUgPCByZSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgcmUgPSBkYXRhLmluZGV4T2YoUnVudGltZUV4Y2VwdGlvbi5jbGFzcy5nZXROYW1lKCksIGVpaWUpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKGRhdGEsIGl0ZSA8IGVpaWUpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnRUcnVlKGRhdGEsIGVpaWUgPCByZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBtYW5hZ2VyLnJlc2V0KCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHByb3BzLnJlbW92ZShrZXkpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHNldFBlbmRpbmcoKFRocm93YWJsZSkgbnVsbCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RTdGF0aWNJbml0RXhjZXB0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFN0cmluZyB0ZXN0ID0gTWFpbEhhbmRsZXJUZXN0LmNsYXNzLmdldE5hbWUoKTsKKyAgICAgICAgZmluYWwgU3RyaW5nIHAgPSBNYWlsSGFuZGxlci5jbGFzcy5nZXROYW1lKCk7CisgICAgICAgIGZpbmFsIFByb3BlcnRpZXMgcHJvcHMgPSBjcmVhdGVJbml0UHJvcGVydGllcyhwKTsKKyAgICAgICAgU3RyaW5nIGZpbHRlcjsKKyAgICAgICAgU3RyaW5nIG5hbWU7CisgICAgICAgIFN0cmluZyBrZXk7CisKKyAgICAgICAgc2V0UGVuZGluZyhuZXcgUnVudGltZUV4Y2VwdGlvbigpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGtleSA9IHAuY29uY2F0KCIuYXV0aGVudGljYXRvciIpOworICAgICAgICAgICAgcHJvcHMucHV0KGtleSwgdGVzdC5jb25jYXQoIiRTdGF0aWNJbml0UmVBdXRoZW50aWNhdG9yIikpOworICAgICAgICAgICAgdGVzdFN0YXRpY0luaXRFeGNlcHRpb24ocHJvcHMpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChwcm9wcy5yZW1vdmUoa2V5KSk7CisKKyAgICAgICAgICAgIGtleSA9IHAuY29uY2F0KCIuY29tcGFyYXRvciIpOworICAgICAgICAgICAgcHJvcHMucHV0KGtleSwgdGVzdC5jb25jYXQoIiRTdGF0aWNJbml0UmVDb21wYXJhdG9yIikpOworICAgICAgICAgICAgdGVzdFN0YXRpY0luaXRFeGNlcHRpb24ocHJvcHMpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChwcm9wcy5yZW1vdmUoa2V5KSk7CisKKyAgICAgICAgICAgIGtleSA9IHAuY29uY2F0KCIuZmlsdGVyIik7CisgICAgICAgICAgICBwcm9wcy5wdXQoa2V5LCB0ZXN0LmNvbmNhdCgiJFN0YXRpY0luaXRSZUZpbHRlciIpKTsKKyAgICAgICAgICAgIHRlc3RTdGF0aWNJbml0RXhjZXB0aW9uKHByb3BzKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwocHJvcHMucmVtb3ZlKGtleSkpOworCisgICAgICAgICAgICBrZXkgPSBwLmNvbmNhdCgiLmZvcm1hdHRlciIpOworICAgICAgICAgICAgcHJvcHMucHV0KGtleSwgdGVzdC5jb25jYXQoIiRTdGF0aWNJbml0UmVGb3JtYXR0ZXIiKSk7CisgICAgICAgICAgICB0ZXN0U3RhdGljSW5pdEV4Y2VwdGlvbihwcm9wcyk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHByb3BzLnJlbW92ZShrZXkpKTsKKworICAgICAgICAgICAga2V5ID0gcC5jb25jYXQoIi5zdWJqZWN0Iik7CisgICAgICAgICAgICBwcm9wcy5wdXQoa2V5LCB0ZXN0LmNvbmNhdCgiJFN0YXRpY0luaXRSZVN1YmplY3RGb3JtYXR0ZXIiKSk7CisgICAgICAgICAgICB0ZXN0U3RhdGljSW5pdEV4Y2VwdGlvbihwcm9wcyk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHByb3BzLnJlbW92ZShrZXkpKTsKKworICAgICAgICAgICAga2V5ID0gcC5jb25jYXQoIi5hdHRhY2htZW50LmZvcm1hdHRlcnMiKTsKKyAgICAgICAgICAgIHByb3BzLnB1dChrZXksIHRlc3QuY29uY2F0KCIkU3RhdGljSW5pdFJlQXR0YWNoRm9ybWF0dGVyIikpOworICAgICAgICAgICAgdGVzdFN0YXRpY0luaXRFeGNlcHRpb24ocHJvcHMpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChwcm9wcy5yZW1vdmUoa2V5KSk7CisKKyAgICAgICAgICAgIGtleSA9IHAuY29uY2F0KCIuYXR0YWNobWVudC5mb3JtYXR0ZXJzIik7CisgICAgICAgICAgICBwcm9wcy5wdXQoa2V5LCBUaHJvd0Zvcm1hdHRlci5jbGFzcy5nZXROYW1lKCkpOworICAgICAgICAgICAgZmlsdGVyID0gcC5jb25jYXQoIi5hdHRhY2htZW50LmZpbHRlcnMiKTsKKyAgICAgICAgICAgIHByb3BzLnB1dChmaWx0ZXIsIHRlc3QuY29uY2F0KCIkU3RhdGljSW5pdFJlQXR0YWNoRmlsdGVyIikpOworICAgICAgICAgICAgbmFtZSA9IHAuY29uY2F0KCIuYXR0YWNobWVudC5uYW1lcyIpOworICAgICAgICAgICAgcHJvcHMucHV0KG5hbWUsICJ0ZXN0LnR4dCIpOworICAgICAgICAgICAgdGVzdFN0YXRpY0luaXRFeGNlcHRpb24ocHJvcHMpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChwcm9wcy5yZW1vdmUoa2V5KSk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHByb3BzLnJlbW92ZShuYW1lKSk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHByb3BzLnJlbW92ZShmaWx0ZXIpKTsKKworICAgICAgICAgICAga2V5ID0gcC5jb25jYXQoIi5hdHRhY2htZW50LmZvcm1hdHRlcnMiKTsKKyAgICAgICAgICAgIHByb3BzLnB1dChrZXksIFRocm93Rm9ybWF0dGVyLmNsYXNzLmdldE5hbWUoKSk7CisgICAgICAgICAgICBuYW1lID0gcC5jb25jYXQoIi5hdHRhY2htZW50Lm5hbWVzIik7CisgICAgICAgICAgICBwcm9wcy5wdXQobmFtZSwgdGVzdC5jb25jYXQoIiRTdGF0aWNJbml0UmVOYW1lRm9ybWF0dGVyIikpOworICAgICAgICAgICAgdGVzdFN0YXRpY0luaXRFeGNlcHRpb24ocHJvcHMpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChwcm9wcy5yZW1vdmUoa2V5KSk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHByb3BzLnJlbW92ZShuYW1lKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBzZXRQZW5kaW5nKChUaHJvd2FibGUpIG51bGwpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RTdGF0aWNJbml0RXhjZXB0aW9uKFByb3BlcnRpZXMgcHJvcHMpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0ZXN0SW5pdEV4Y2VwdGlvbihwcm9wcyk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U3RhdGljSW5pdEVycm9yKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIFN0cmluZyB0ZXN0ID0gTWFpbEhhbmRsZXJUZXN0LmNsYXNzLmdldE5hbWUoKTsKKyAgICAgICAgZmluYWwgU3RyaW5nIHAgPSBNYWlsSGFuZGxlci5jbGFzcy5nZXROYW1lKCk7CisgICAgICAgIGZpbmFsIFByb3BlcnRpZXMgcHJvcHMgPSBjcmVhdGVJbml0UHJvcGVydGllcyhwKTsKKyAgICAgICAgU3RyaW5nIGZpbHRlcjsKKyAgICAgICAgU3RyaW5nIG5hbWU7CisgICAgICAgIFN0cmluZyBrZXk7CisKKyAgICAgICAgc2V0UGVuZGluZyhuZXcgRXJyb3IoKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBrZXkgPSBwLmNvbmNhdCgiLmF1dGhlbnRpY2F0b3IiKTsKKyAgICAgICAgICAgIHByb3BzLnB1dChrZXksIHRlc3QuY29uY2F0KCIkU3RhdGljSW5pdEVyQXV0aGVudGljYXRvciIpKTsKKyAgICAgICAgICAgIHRlc3RTdGF0aWNJbml0RXJyb3IocHJvcHMpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChwcm9wcy5yZW1vdmUoa2V5KSk7CisKKyAgICAgICAgICAgIGtleSA9IHAuY29uY2F0KCIuY29tcGFyYXRvciIpOworICAgICAgICAgICAgcHJvcHMucHV0KGtleSwgdGVzdC5jb25jYXQoIiRTdGF0aWNJbml0RXJDb21wYXJhdG9yIikpOworICAgICAgICAgICAgdGVzdFN0YXRpY0luaXRFcnJvcihwcm9wcyk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHByb3BzLnJlbW92ZShrZXkpKTsKKworICAgICAgICAgICAga2V5ID0gcC5jb25jYXQoIi5lcnJvck1hbmFnZXIiKTsKKyAgICAgICAgICAgIHByb3BzLnB1dChrZXksIHRlc3QuY29uY2F0KCIkU3RhdGljSW5pdEVyRXJyb3JNYW5hZ2VyIikpOworICAgICAgICAgICAgdGVzdFN0YXRpY0luaXRFcnJvcihwcm9wcyk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHByb3BzLnJlbW92ZShrZXkpKTsKKworICAgICAgICAgICAga2V5ID0gcC5jb25jYXQoIi5maWx0ZXIiKTsKKyAgICAgICAgICAgIHByb3BzLnB1dChrZXksIHRlc3QuY29uY2F0KCIkU3RhdGljSW5pdEVyRmlsdGVyIikpOworICAgICAgICAgICAgdGVzdFN0YXRpY0luaXRFcnJvcihwcm9wcyk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHByb3BzLnJlbW92ZShrZXkpKTsKKworICAgICAgICAgICAga2V5ID0gcC5jb25jYXQoIi5mb3JtYXR0ZXIiKTsKKyAgICAgICAgICAgIHByb3BzLnB1dChrZXksIHRlc3QuY29uY2F0KCIkU3RhdGljSW5pdEVyRm9ybWF0dGVyIikpOworICAgICAgICAgICAgdGVzdFN0YXRpY0luaXRFcnJvcihwcm9wcyk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHByb3BzLnJlbW92ZShrZXkpKTsKKworICAgICAgICAgICAga2V5ID0gcC5jb25jYXQoIi5zdWJqZWN0Iik7CisgICAgICAgICAgICBwcm9wcy5wdXQoa2V5LCB0ZXN0LmNvbmNhdCgiJFN0YXRpY0luaXRFclN1YmplY3RGb3JtYXR0ZXIiKSk7CisgICAgICAgICAgICB0ZXN0U3RhdGljSW5pdEVycm9yKHByb3BzKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwocHJvcHMucmVtb3ZlKGtleSkpOworCisgICAgICAgICAgICBrZXkgPSBwLmNvbmNhdCgiLmF0dGFjaG1lbnQuZm9ybWF0dGVycyIpOworICAgICAgICAgICAgcHJvcHMucHV0KGtleSwgdGVzdC5jb25jYXQoIiRTdGF0aWNJbml0RXJBdHRhY2hGb3JtYXR0ZXIiKSk7CisgICAgICAgICAgICB0ZXN0U3RhdGljSW5pdEVycm9yKHByb3BzKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwocHJvcHMucmVtb3ZlKGtleSkpOworCisgICAgICAgICAgICBrZXkgPSBwLmNvbmNhdCgiLmF0dGFjaG1lbnQuZm9ybWF0dGVycyIpOworICAgICAgICAgICAgcHJvcHMucHV0KGtleSwgVGhyb3dGb3JtYXR0ZXIuY2xhc3MuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgIGZpbHRlciA9IHAuY29uY2F0KCIuYXR0YWNobWVudC5maWx0ZXJzIik7CisgICAgICAgICAgICBwcm9wcy5wdXQoZmlsdGVyLCB0ZXN0LmNvbmNhdCgiJFN0YXRpY0luaXRFckF0dGFjaEZpbHRlciIpKTsKKyAgICAgICAgICAgIG5hbWUgPSBwLmNvbmNhdCgiLmF0dGFjaG1lbnQubmFtZXMiKTsKKyAgICAgICAgICAgIHByb3BzLnB1dChuYW1lLCAidGVzdC50eHQiKTsKKyAgICAgICAgICAgIHRlc3RTdGF0aWNJbml0RXJyb3IocHJvcHMpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChwcm9wcy5yZW1vdmUoa2V5KSk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHByb3BzLnJlbW92ZShuYW1lKSk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHByb3BzLnJlbW92ZShmaWx0ZXIpKTsKKworICAgICAgICAgICAga2V5ID0gcC5jb25jYXQoIi5hdHRhY2htZW50LmZvcm1hdHRlcnMiKTsKKyAgICAgICAgICAgIHByb3BzLnB1dChrZXksIFRocm93Rm9ybWF0dGVyLmNsYXNzLmdldE5hbWUoKSk7CisgICAgICAgICAgICBuYW1lID0gcC5jb25jYXQoIi5hdHRhY2htZW50Lm5hbWVzIik7CisgICAgICAgICAgICBwcm9wcy5wdXQobmFtZSwgdGVzdC5jb25jYXQoIiRTdGF0aWNJbml0RXJOYW1lRm9ybWF0dGVyIikpOworICAgICAgICAgICAgdGVzdFN0YXRpY0luaXRFcnJvcihwcm9wcyk7CisgICAgICAgICAgICBhc3NlcnROb3ROdWxsKHByb3BzLnJlbW92ZShrZXkpKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwocHJvcHMucmVtb3ZlKG5hbWUpKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIHNldFBlbmRpbmcoKFRocm93YWJsZSkgbnVsbCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiVGhyb3dhYmxlSW5pdENhdXNlIikKKyAgICBwcml2YXRlIHZvaWQgdGVzdFN0YXRpY0luaXRFcnJvcihQcm9wZXJ0aWVzIHByb3BzKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgTG9nTWFuYWdlciBtYW5hZ2VyID0gTG9nTWFuYWdlci5nZXRMb2dNYW5hZ2VyKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZWFkKG1hbmFnZXIsIHByb3BzKTsKKyAgICAgICAgICAgIE1haWxIYW5kbGVyIHRhcmdldCA9IG51bGw7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHRhcmdldCA9IG5ldyBNYWlsSGFuZGxlcigpOworICAgICAgICAgICAgICAgIEFzc2VydGlvbkVycm9yIEFFID0gbmV3IEFzc2VydGlvbkVycm9yKHByb3BzLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgICAgIEFFLmluaXRDYXVzZShnZXRQZW5kaW5nKCkpOworICAgICAgICAgICAgICAgIHRocm93IEFFOworICAgICAgICAgICAgfSBjYXRjaCAoQXNzZXJ0aW9uRXJyb3IgZSkgeworICAgICAgICAgICAgICAgIHRocm93IGU7IC8vYXZvaWQgY2F0Y2ggYWxsLgorICAgICAgICAgICAgfSBjYXRjaCAoRXJyb3IgZXhwZWN0KSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKEVycm9yLmNsYXNzLCBleHBlY3QuZ2V0Q2xhc3MoKSk7CisgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIGlmICh0YXJnZXQgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICB0YXJnZXQuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBtYW5hZ2VyLnJlc2V0KCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBzdGF0aWMgUHJvcGVydGllcyBjcmVhdGVJbml0UHJvcGVydGllcyhTdHJpbmcgcCkgeworICAgICAgICBmaW5hbCBQcm9wZXJ0aWVzIHByb3BzID0gbmV3IFByb3BlcnRpZXMoKTsKKyAgICAgICAgaWYgKHAubGVuZ3RoKCkgIT0gMCkgeworICAgICAgICAgICAgcCA9IHAuY29uY2F0KCIuIik7CisgICAgICAgIH0KKyAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCJtYWlsLmhvc3QiKSwgVU5LTk9XTl9IT1NUKTsKKyAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCJtYWlsLnNtdHAuaG9zdCIpLCBVTktOT1dOX0hPU1QpOworICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIm1haWwuc210cC5wb3J0IiksIEludGVnZXIudG9TdHJpbmcoT1BFTl9QT1JUKSk7CisgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgibWFpbC50byIpLCAiIik7CisgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgibWFpbC5jYyIpLCAiYmFkQWRkcmVzcyIpOworICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIm1haWwuZnJvbSIpLCAiIik7CisgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgibWFpbC5zbXRwLmNvbm5lY3Rpb250aW1lb3V0IiksICIxIik7CisgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgibWFpbC5zbXRwLnRpbWVvdXQiKSwgIjEiKTsKKyAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCJlcnJvck1hbmFnZXIiKSwgSW50ZXJuYWxFcnJvck1hbmFnZXIuY2xhc3MuZ2V0TmFtZSgpKTsKKyAgICAgICAgcmV0dXJuIHByb3BzOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEluaXRGcm9tTG9nTWFuYWdlcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBmaW5hbCBMb2dNYW5hZ2VyIG1hbmFnZXIgPSBMb2dNYW5hZ2VyLmdldExvZ01hbmFnZXIoKTsKKyAgICAgICAgc3luY2hyb25pemVkIChtYW5hZ2VyKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGluaXRHb29kVGVzdChNYWlsSGFuZGxlci5jbGFzcywgbmV3IENsYXNzPD8+WzBdLCBuZXcgT2JqZWN0WzBdKTsKKyAgICAgICAgICAgICAgICBpbml0QmFkVGVzdChNYWlsSGFuZGxlci5jbGFzcywgbmV3IENsYXNzPD8+WzBdLCBuZXcgT2JqZWN0WzBdKTsKKyAgICAgICAgICAgICAgICBpbml0R29vZFRlc3QoTWFpbEhhbmRsZXIuY2xhc3MsCisgICAgICAgICAgICAgICAgICAgICAgICBuZXcgQ2xhc3M8Pz5bXXtJbnRlZ2VyLlRZUEV9LCBuZXcgT2JqZWN0W117MTB9KTsKKyAgICAgICAgICAgICAgICBpbml0QmFkVGVzdChNYWlsSGFuZGxlci5jbGFzcywKKyAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBDbGFzczw/Pltde0ludGVnZXIuVFlQRX0sIG5ldyBPYmplY3RbXXsxMDB9KTsKKyAgICAgICAgICAgICAgICBpbml0R29vZFRlc3QoTWFpbEhhbmRsZXIuY2xhc3MsCisgICAgICAgICAgICAgICAgICAgICAgICBuZXcgQ2xhc3M8Pz5bXXtQcm9wZXJ0aWVzLmNsYXNzfSwKKyAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtuZXcgUHJvcGVydGllcygpfSk7CisgICAgICAgICAgICAgICAgaW5pdEJhZFRlc3QoTWFpbEhhbmRsZXIuY2xhc3MsCisgICAgICAgICAgICAgICAgICAgICAgICBuZXcgQ2xhc3M8Pz5bXXtQcm9wZXJ0aWVzLmNsYXNzfSwKKyAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXtuZXcgUHJvcGVydGllcygpfSk7CisKKyAgICAgICAgICAgICAgICAvL1Rlc3Qgc3ViY2xhc3MgcHJvcGVydGllcy4KKyAgICAgICAgICAgICAgICBpbml0R29vZFRlc3QoTWFpbEhhbmRsZXJFeHQuY2xhc3MsCisgICAgICAgICAgICAgICAgICAgICAgICBuZXcgQ2xhc3M8Pz5bMF0sIG5ldyBPYmplY3RbMF0pOworICAgICAgICAgICAgICAgIGluaXRCYWRUZXN0KE1haWxIYW5kbGVyRXh0LmNsYXNzLAorICAgICAgICAgICAgICAgICAgICAgICAgbmV3IENsYXNzPD8+WzBdLCBuZXcgT2JqZWN0WzBdKTsKKworICAgICAgICAgICAgICAgIGluaXRHb29kVGVzdChNYWlsSGFuZGxlckV4dC5jbGFzcywKKyAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBDbGFzczw/Pltde0ludGVnZXIuVFlQRX0sIG5ldyBPYmplY3RbXXsxMH0pOworICAgICAgICAgICAgICAgIGluaXRCYWRUZXN0KE1haWxIYW5kbGVyRXh0LmNsYXNzLAorICAgICAgICAgICAgICAgICAgICAgICAgbmV3IENsYXNzPD8+W117SW50ZWdlci5UWVBFfSwgbmV3IE9iamVjdFtdezEwMH0pOworCisgICAgICAgICAgICAgICAgaW5pdEdvb2RUZXN0KE1haWxIYW5kbGVyRXh0LmNsYXNzLAorICAgICAgICAgICAgICAgICAgICAgICAgbmV3IENsYXNzPD8+W117UHJvcGVydGllcy5jbGFzc30sCisgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117bmV3IFByb3BlcnRpZXMoKX0pOworICAgICAgICAgICAgICAgIGluaXRCYWRUZXN0KE1haWxIYW5kbGVyRXh0LmNsYXNzLAorICAgICAgICAgICAgICAgICAgICAgICAgbmV3IENsYXNzPD8+W117UHJvcGVydGllcy5jbGFzc30sCisgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117bmV3IFByb3BlcnRpZXMoKX0pOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBtYW5hZ2VyLnJlc2V0KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZnJlZVRleHRTdWJqZWN0KCkgeworICAgICAgICBTdHJpbmcgbmFtZSA9ICJNYWlsIEhhbmRsZXIgdGVzdCBzdWJqZWN0IjsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIENsYXNzLmZvck5hbWUobmFtZSk7IC8vZW5zdXJlIHRoaXMgY2FuJ3QgYmUgbG9hZGVkLgorICAgICAgICAgICAgZmFpbCgiSW52YWxpZCBzdWJqZWN0OiAiICsgbmFtZSk7CisgICAgICAgIH0gY2F0Y2ggKEFzc2VydGlvbkVycm9yIGZhaWwpIHsKKyAgICAgICAgICAgIHRocm93IGZhaWw7CisgICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSBleHBlY3RlZCkgeworICAgICAgICB9CisgICAgICAgIHJldHVybiBuYW1lOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBpbml0R29vZFRlc3QoQ2xhc3M8PyBleHRlbmRzIE1haWxIYW5kbGVyPiB0eXBlLAorICAgICAgICAgICAgQ2xhc3M8Pz5bXSB0eXBlcywgT2JqZWN0W10gcGFyYW1zKSB0aHJvd3MgRXhjZXB0aW9uIHsKKworICAgICAgICBmaW5hbCBTdHJpbmcgcCA9IHR5cGUuZ2V0TmFtZSgpOworICAgICAgICBQcm9wZXJ0aWVzIHByb3BzID0gY3JlYXRlSW5pdFByb3BlcnRpZXMocCk7CisgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLmVycm9yTWFuYWdlciIpLCBJbnRlcm5hbEVycm9yTWFuYWdlci5jbGFzcy5nZXROYW1lKCkpOworICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5jYXBhY2l0eSIpLCAiMTAiKTsKKyAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIubGV2ZWwiKSwgIkFMTCIpOworICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5mb3JtYXR0ZXIiKSwgWE1MRm9ybWF0dGVyLmNsYXNzLmdldE5hbWUoKSk7CisgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLmZpbHRlciIpLCBUaHJvd0ZpbHRlci5jbGFzcy5nZXROYW1lKCkpOworICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5hdXRoZW50aWNhdG9yIiksIEVtcHR5QXV0aGVudGljYXRvci5jbGFzcy5nZXROYW1lKCkpOworICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5wdXNoTGV2ZWwiKSwgIldBUk5JTkciKTsKKyAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIucHVzaEZpbHRlciIpLCBUaHJvd0ZpbHRlci5jbGFzcy5nZXROYW1lKCkpOworICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5jb21wYXJhdG9yIiksIFRocm93Q29tcGFyYXRvci5jbGFzcy5nZXROYW1lKCkpOworICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5lbmNvZGluZyIpLCAiVVRGLTgiKTsKKyAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIuc3ViamVjdCIpLCBFbXB0eUZvcm1hdHRlci5jbGFzcy5nZXROYW1lKCkpOworCisgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLmF0dGFjaG1lbnQuZmlsdGVycyIpLAorICAgICAgICAgICAgICAgICJudWxsLCAiICsgVGhyb3dGaWx0ZXIuY2xhc3MuZ2V0TmFtZSgpICsgIiwgIgorICAgICAgICAgICAgICAgICsgVGhyb3dGaWx0ZXIuY2xhc3MuZ2V0TmFtZSgpKTsKKworICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5hdHRhY2htZW50LmZvcm1hdHRlcnMiKSwKKyAgICAgICAgICAgICAgICBTaW1wbGVGb3JtYXR0ZXIuY2xhc3MuZ2V0TmFtZSgpICsgIiwgIgorICAgICAgICAgICAgICAgICsgWE1MRm9ybWF0dGVyLmNsYXNzLmdldE5hbWUoKSArICIsICIKKyAgICAgICAgICAgICAgICArIFNpbXBsZUZvcm1hdHRlci5jbGFzcy5nZXROYW1lKCkpOworCisgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLmF0dGFjaG1lbnQubmFtZXMiKSwgIm1zZy50eHQsICIKKyAgICAgICAgICAgICAgICArIFNpbXBsZUZvcm1hdHRlci5jbGFzcy5nZXROYW1lKCkgKyAiLCBlcnJvci50eHQiKTsKKworICAgICAgICByZWFkKExvZ01hbmFnZXIuZ2V0TG9nTWFuYWdlcigpLCBwcm9wcyk7CisKKyAgICAgICAgTWFpbEhhbmRsZXIgaCA9IHR5cGUuZ2V0Q29uc3RydWN0b3IodHlwZXMpLm5ld0luc3RhbmNlKHBhcmFtcyk7CisgICAgICAgIGFzc2VydEVxdWFscygxMCwgaC5nZXRDYXBhY2l0eSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKExldmVsLkFMTCwgaC5nZXRMZXZlbCgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFRocm93RmlsdGVyLmNsYXNzLCBoLmdldEZpbHRlcigpLmdldENsYXNzKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoWE1MRm9ybWF0dGVyLmNsYXNzLCBoLmdldEZvcm1hdHRlcigpLmdldENsYXNzKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoTGV2ZWwuV0FSTklORywgaC5nZXRQdXNoTGV2ZWwoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhUaHJvd0ZpbHRlci5jbGFzcywgaC5nZXRQdXNoRmlsdGVyKCkuZ2V0Q2xhc3MoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhUaHJvd0NvbXBhcmF0b3IuY2xhc3MsIGguZ2V0Q29tcGFyYXRvcigpLmdldENsYXNzKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlVURi04IiwgaC5nZXRFbmNvZGluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEVtcHR5Rm9ybWF0dGVyLmNsYXNzLCBoLmdldFN1YmplY3QoKS5nZXRDbGFzcygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKEVtcHR5QXV0aGVudGljYXRvci5jbGFzcywgaC5nZXRBdXRoZW50aWNhdG9yKCkuZ2V0Q2xhc3MoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygzLCBoLmdldEF0dGFjaG1lbnRGb3JtYXR0ZXJzKCkubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShudWxsICE9IGguZ2V0QXR0YWNobWVudEZvcm1hdHRlcnMoKVswXSk7CisgICAgICAgIGFzc2VydFRydWUobnVsbCAhPSBoLmdldEF0dGFjaG1lbnRGb3JtYXR0ZXJzKClbMV0pOworICAgICAgICBhc3NlcnRUcnVlKG51bGwgIT0gaC5nZXRBdHRhY2htZW50Rm9ybWF0dGVycygpWzJdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKDMsIGguZ2V0QXR0YWNobWVudEZpbHRlcnMoKS5sZW5ndGgpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgaC5nZXRBdHRhY2htZW50RmlsdGVycygpWzBdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFRocm93RmlsdGVyLmNsYXNzLCBoLmdldEF0dGFjaG1lbnRGaWx0ZXJzKClbMV0uZ2V0Q2xhc3MoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhUaHJvd0ZpbHRlci5jbGFzcywgaC5nZXRBdHRhY2htZW50RmlsdGVycygpWzJdLmdldENsYXNzKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMywgaC5nZXRBdHRhY2htZW50TmFtZXMoKS5sZW5ndGgpOworICAgICAgICBhc3NlcnRUcnVlKG51bGwgIT0gaC5nZXRBdHRhY2htZW50TmFtZXMoKVswXSk7CisgICAgICAgIGFzc2VydFRydWUobnVsbCAhPSBoLmdldEF0dGFjaG1lbnROYW1lcygpWzFdKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShudWxsICE9IGguZ2V0QXR0YWNobWVudE5hbWVzKClbMl0pOworCisgICAgICAgIEludGVybmFsRXJyb3JNYW5hZ2VyIGVtID0gaW50ZXJuYWxFcnJvck1hbmFnZXJGcm9tKGgpOworICAgICAgICBmb3IgKEV4Y2VwdGlvbiBleGNlcHRpb24gOiBlbS5leGNlcHRpb25zKSB7CisgICAgICAgICAgICBmYWlsKFN0cmluZy52YWx1ZU9mKGV4Y2VwdGlvbikpOworICAgICAgICB9CisgICAgICAgIGFzc2VydFRydWUoZW0uZXhjZXB0aW9ucy5pc0VtcHR5KCkpOworCisgICAgICAgIGguc2V0Q29tcGFyYXRvcihudWxsKTsKKyAgICAgICAgaC5jbG9zZSgpOworICAgICAgICBhc3NlcnRFcXVhbHMoZW0uZXhjZXB0aW9ucy5pc0VtcHR5KCksIHRydWUpOworCisgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLnN1YmplY3QiKSwgZnJlZVRleHRTdWJqZWN0KCkpOworCisgICAgICAgIHJlYWQoTG9nTWFuYWdlci5nZXRMb2dNYW5hZ2VyKCksIHByb3BzKTsKKworICAgICAgICBoID0gdHlwZS5nZXRDb25zdHJ1Y3Rvcih0eXBlcykubmV3SW5zdGFuY2UocGFyYW1zKTsKKyAgICAgICAgZW0gPSBpbnRlcm5hbEVycm9yTWFuYWdlckZyb20oaCk7CisgICAgICAgIGFzc2VydFRydWUoZW0uZXhjZXB0aW9ucy5pc0VtcHR5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoZnJlZVRleHRTdWJqZWN0KCksIGguZ2V0U3ViamVjdCgpLnRvU3RyaW5nKCkpOworCisgICAgICAgIHByb3BzLnJlbW92ZShwLmNvbmNhdCgiLmF0dGFjaG1lbnQuZmlsdGVycyIpKTsKKyAgICAgICAgcmVhZChMb2dNYW5hZ2VyLmdldExvZ01hbmFnZXIoKSwgcHJvcHMpOworCisgICAgICAgIGggPSB0eXBlLmdldENvbnN0cnVjdG9yKHR5cGVzKS5uZXdJbnN0YW5jZShwYXJhbXMpOworICAgICAgICBlbSA9IGludGVybmFsRXJyb3JNYW5hZ2VyRnJvbShoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShlbS5leGNlcHRpb25zLmlzRW1wdHkoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygzLCBoLmdldEF0dGFjaG1lbnRGb3JtYXR0ZXJzKCkubGVuZ3RoKTsKKyAgICAgICAgaC5jbG9zZSgpOworCisgICAgICAgIHByb3BzLnJlbW92ZShwLmNvbmNhdCgiLmF0dGFjaG1lbnQubmFtZXMiKSk7CisgICAgICAgIHJlYWQoTG9nTWFuYWdlci5nZXRMb2dNYW5hZ2VyKCksIHByb3BzKTsKKworICAgICAgICBoID0gdHlwZS5nZXRDb25zdHJ1Y3Rvcih0eXBlcykubmV3SW5zdGFuY2UocGFyYW1zKTsKKyAgICAgICAgZW0gPSBpbnRlcm5hbEVycm9yTWFuYWdlckZyb20oaCk7CisgICAgICAgIGFzc2VydFRydWUoZW0uZXhjZXB0aW9ucy5pc0VtcHR5KCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoaC5nZXRBdHRhY2htZW50Rm9ybWF0dGVycygpLmxlbmd0aCwgMyk7CisgICAgICAgIGguY2xvc2UoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFBhc3N3b3JkQXV0aGVudGljYXRpb24gcGFzc3dvcmRBdXRoZW50aWNhdGlvbihqYXZheC5tYWlsLkF1dGhlbnRpY2F0b3IgYXV0aCwgU3RyaW5nIHVzZXIpIHsKKyAgICAgICAgZmluYWwgU2Vzc2lvbiBzID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShuZXcgUHJvcGVydGllcygpLCBhdXRoKTsKKyAgICAgICAgcmV0dXJuIHMucmVxdWVzdFBhc3N3b3JkQXV0aGVudGljYXRpb24obnVsbCwgMjUsICJTTVRQIiwgIiIsIHVzZXIpOworICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJVc2VPZlN5c3RlbU91dE9yU3lzdGVtRXJyIikKKyAgICBwcml2YXRlIHZvaWQgaW5pdEJhZFRlc3QoQ2xhc3M8PyBleHRlbmRzIE1haWxIYW5kbGVyPiB0eXBlLAorICAgICAgICAgICAgQ2xhc3M8Pz5bXSB0eXBlcywgT2JqZWN0W10gcGFyYW1zKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU3RyaW5nIGVuY29kaW5nID0gU3lzdGVtLmdldFByb3BlcnR5KCJmaWxlLmVuY29kaW5nIiwgIjg4NTlfMSIpOworICAgICAgICBmaW5hbCBQcmludFN0cmVhbSBlcnIgPSBTeXN0ZW0uZXJyOworICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gb2xkRXJyb3JzID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworCisgICAgICAgIGZpbmFsIFN0cmluZyBwID0gdHlwZS5nZXROYW1lKCk7CisgICAgICAgIFByb3BlcnRpZXMgcHJvcHMgPSBjcmVhdGVJbml0UHJvcGVydGllcyhwKTsKKworICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5lcnJvck1hbmFnZXIiKSwgIkludmFsaWRFcnJvck1hbmFnZXIiKTsKKyAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIuY2FwYWNpdHkiKSwgIi0xMCIpOworICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5sZXZlbCIpLCAiQkFEIik7CisgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLmZvcm1hdHRlciIpLCAiSW52YWxpZEZvcm1hdHRlciIpOworICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5maWx0ZXIiKSwgIkludmFsaWRGaWx0ZXIiKTsKKyAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIuYXV0aGVudGljYXRvciIpLCAicGFzc3dvcmQiKTsKKyAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIucHVzaExldmVsIiksICJQVVNIQkFEIik7CisgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLnB1c2hGaWx0ZXIiKSwgIkludmFsaWRQdXNoRmlsdGVyIik7CisgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLmNvbXBhcmF0b3IiKSwgIkludmFsaWRDb21wYXJhdG9yIik7CisgICAgICAgIHByb3BzLnB1dChwLmNvbmNhdCgiLmVuY29kaW5nIiksICJNYWlsSGFuZGxlci1FTkMiKTsKKyAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIuc3ViamVjdCIpLCBUaHJvd0ZpbHRlci5jbGFzcy5nZXROYW1lKCkpOworICAgICAgICBwcm9wcy5wdXQocC5jb25jYXQoIi5hdHRhY2htZW50LmZpbHRlcnMiKSwgIm51bGwsICIKKyAgICAgICAgICAgICAgICArICJJbnZhbGlkQXR0YWNoRmlsdGVyMSwgIiArIFRocm93RmlsdGVyLmNsYXNzLmdldE5hbWUoKSk7CisKKyAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIuYXR0YWNobWVudC5mb3JtYXR0ZXJzIiksCisgICAgICAgICAgICAgICAgIkludmFsaWRBdHRhY2hGb3JtYXR0ZXIwLCAiCisgICAgICAgICAgICAgICAgKyBUaHJvd0NvbXBhcmF0b3IuY2xhc3MuZ2V0TmFtZSgpICsgIiwgIgorICAgICAgICAgICAgICAgICsgWE1MRm9ybWF0dGVyLmNsYXNzLmdldE5hbWUoKSk7CisKKyAgICAgICAgcHJvcHMucHV0KHAuY29uY2F0KCIuYXR0YWNobWVudC5uYW1lcyIpLCAibXNnLnR4dCwgIgorICAgICAgICAgICAgICAgICsgVGhyb3dDb21wYXJhdG9yLmNsYXNzLmdldE5hbWUoKSArICIsICIKKyAgICAgICAgICAgICAgICArIFhNTEZvcm1hdHRlci5jbGFzcy5nZXROYW1lKCkpOworCisgICAgICAgIE1haWxIYW5kbGVyIGggPSBudWxsOworICAgICAgICBvbGRFcnJvcnMucmVzZXQoKTsKKyAgICAgICAgU3lzdGVtLnNldEVycihuZXcgUHJpbnRTdHJlYW0ob2xkRXJyb3JzLCBmYWxzZSwgZW5jb2RpbmcpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8qKgorICAgICAgICAgICAgICogQmFkIGxldmVsIHZhbHVlIGZvciBwcm9wZXJ0eToKKyAgICAgICAgICAgICAqIGNvbS5zdW4ubWFpbC51dGlsLmxvZ2dpbmcuTWFpbEhhbmRsZXIubGV2ZWwgVGhlCisgICAgICAgICAgICAgKiBMb2dNYW5hZ2VyLnNldExldmVsc09uRXhpc3RpbmdMb2dnZXJzIHRyaWdnZXJzIGFuIGVycm9yLiBUaGlzCisgICAgICAgICAgICAgKiBjb2RlIHN3YWxsb3dzIHRoYXQgZXJyb3IgbWVzc2FnZS4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgcmVhZChMb2dNYW5hZ2VyLmdldExvZ01hbmFnZXIoKSwgcHJvcHMpOworICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludCgiIik7IC8vZmx1c2hCdWZmZXIuCisgICAgICAgICAgICBTeXN0ZW0uZXJyLmZsdXNoKCk7CisgICAgICAgICAgICBTdHJpbmcgcmVzdWx0ID0gb2xkRXJyb3JzLnRvU3RyaW5nKGVuY29kaW5nKS50cmltKCk7CisgICAgICAgICAgICBvbGRFcnJvcnMucmVzZXQoKTsKKyAgICAgICAgICAgIGlmIChyZXN1bHQubGVuZ3RoKCkgPiAwKSB7CisgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIGV4cGVjdCA9ICJCYWQgbGV2ZWwgdmFsdWUgZm9yIHByb3BlcnR5OiAiICsgcCArICIubGV2ZWwiOworICAgICAgICAgICAgICAgIC8vaWYgKHJlc3VsdC5sZW5ndGgoKSA+IGV4cGVjdC5sZW5ndGgoKSkgeworICAgICAgICAgICAgICAgIC8vICAgIHJlc3VsdCA9IHJlc3VsdC5zdWJzdHJpbmcoMCwgZXhwZWN0Lmxlbmd0aCgpKTsKKyAgICAgICAgICAgICAgICAvL30KKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0LCByZXN1bHQpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvKioKKyAgICAgICAgICAgICAqIFRoZSBkZWZhdWx0IGVycm9yIG1hbmFnZXIgd3JpdGVzIHRvIFN5c3RlbS5lcnIuIFNpbmNlIHRoaXMgdGVzdAorICAgICAgICAgICAgICogaXMgdHJ5aW5nIHRvIGluc3RhbGwgYW4gaW52YWxpZCBFcnJvck1hbmFnZXIgd2UgY2FuIG9ubHkgY2FwdHVyZQorICAgICAgICAgICAgICogdGhlIGVycm9yIGJ5IGNhcHR1cmluZyBTeXN0ZW0uZXJyLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBoID0gdHlwZS5nZXRDb25zdHJ1Y3Rvcih0eXBlcykubmV3SW5zdGFuY2UocGFyYW1zKTsKKyAgICAgICAgICAgIFN5c3RlbS5lcnIuZmx1c2goKTsKKyAgICAgICAgICAgIHJlc3VsdCA9IG9sZEVycm9ycy50b1N0cmluZyhlbmNvZGluZykudHJpbSgpOworICAgICAgICAgICAgaW50IGluZGV4ID0gcmVzdWx0LmluZGV4T2YoRXJyb3JNYW5hZ2VyLmNsYXNzLmdldE5hbWUoKSArICI6ICIKKyAgICAgICAgICAgICAgICAgICAgKyBFcnJvck1hbmFnZXIuT1BFTl9GQUlMVVJFICsgIjogIiArIExldmVsLlNFVkVSRS5nZXROYW1lKCkKKyAgICAgICAgICAgICAgICAgICAgKyAiOiBJbnZhbGlkRXJyb3JNYW5hZ2VyIik7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGluZGV4ID4gLTEpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQuaW5kZXhPZigKKyAgICAgICAgICAgICAgICAgICAgImphdmEubGFuZy5DbGFzc05vdEZvdW5kRXhjZXB0aW9uOiBJbnZhbGlkRXJyb3JNYW5hZ2VyIikgPiBpbmRleCk7CisgICAgICAgICAgICBvbGRFcnJvcnMucmVzZXQoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIFN5c3RlbS5zZXRFcnIoZXJyKTsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydCBoICE9IG51bGw7CisgICAgICAgIGFzc2VydEVxdWFscyhFcnJvck1hbmFnZXIuY2xhc3MsIGguZ2V0RXJyb3JNYW5hZ2VyKCkuZ2V0Q2xhc3MoKSk7CisgICAgICAgIGFzc2VydFRydWUoaC5nZXRDYXBhY2l0eSgpICE9IDEwKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShoLmdldENhcGFjaXR5KCkgIT0gLTEwKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKExldmVsLldBUk5JTkcsIGguZ2V0TGV2ZWwoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBoLmdldEZpbHRlcigpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFNpbXBsZUZvcm1hdHRlci5jbGFzcywgaC5nZXRGb3JtYXR0ZXIoKS5nZXRDbGFzcygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKExldmVsLk9GRiwgaC5nZXRQdXNoTGV2ZWwoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBoLmdldFB1c2hGaWx0ZXIoKSk7CisgICAgICAgIGFzc2VydE51bGwoaC5nZXRDb21wYXJhdG9yKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgaC5nZXRFbmNvZGluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFRocm93RmlsdGVyLmNsYXNzLmdldE5hbWUoKSwgaC5nZXRTdWJqZWN0KCkudG9TdHJpbmcoKSk7CisgICAgICAgIFBhc3N3b3JkQXV0aGVudGljYXRpb24gcGEgPSBwYXNzd29yZEF1dGhlbnRpY2F0aW9uKGguZ2V0QXV0aGVudGljYXRvcigpLCAidXNlciIpOworICAgICAgICBhc3NlcnRFcXVhbHMoInVzZXIiLCBwYS5nZXRVc2VyTmFtZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJwYXNzd29yZCIsIHBhLmdldFBhc3N3b3JkKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMywgaC5nZXRBdHRhY2htZW50Rm9ybWF0dGVycygpLmxlbmd0aCk7CisgICAgICAgIGFzc2VydFRydWUobnVsbCAhPSBoLmdldEF0dGFjaG1lbnRGb3JtYXR0ZXJzKClbMF0pOworICAgICAgICBhc3NlcnRUcnVlKG51bGwgIT0gaC5nZXRBdHRhY2htZW50Rm9ybWF0dGVycygpWzFdKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShudWxsICE9IGguZ2V0QXR0YWNobWVudEZvcm1hdHRlcnMoKVsyXSk7CisgICAgICAgIGFzc2VydEVxdWFscygzLCBoLmdldEF0dGFjaG1lbnRGaWx0ZXJzKCkubGVuZ3RoKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShudWxsID09IGguZ2V0QXR0YWNobWVudEZpbHRlcnMoKVswXSk7CisgICAgICAgIGFzc2VydFRydWUobnVsbCA9PSBoLmdldEF0dGFjaG1lbnRGaWx0ZXJzKClbMV0pOworICAgICAgICBhc3NlcnRUcnVlKG51bGwgIT0gaC5nZXRBdHRhY2htZW50RmlsdGVycygpWzJdKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFRocm93RmlsdGVyLmNsYXNzLCBoLmdldEF0dGFjaG1lbnRGaWx0ZXJzKClbMl0uZ2V0Q2xhc3MoKSk7CisgICAgICAgIGFzc2VydEVxdWFscygzLCBoLmdldEF0dGFjaG1lbnROYW1lcygpLmxlbmd0aCk7CisgICAgICAgIGFzc2VydFRydWUobnVsbCAhPSBoLmdldEF0dGFjaG1lbnROYW1lcygpWzBdKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShudWxsICE9IGguZ2V0QXR0YWNobWVudE5hbWVzKClbMV0pOworICAgICAgICBhc3NlcnRUcnVlKG51bGwgIT0gaC5nZXRBdHRhY2htZW50TmFtZXMoKVsyXSk7CisgICAgICAgIGFzc2VydEVxdWFscyhYTUxGb3JtYXR0ZXIuY2xhc3MsIGguZ2V0QXR0YWNobWVudE5hbWVzKClbMl0uZ2V0Q2xhc3MoKSk7CisgICAgICAgIGguY2xvc2UoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzQ29ubmVjdE9yVGltZW91dChUaHJvd2FibGUgdCkgeworICAgICAgICBpZiAodCBpbnN0YW5jZW9mIE1lc3NhZ2luZ0V4Y2VwdGlvbikgeworICAgICAgICAgICAgVGhyb3dhYmxlIGNhdXNlID0gdC5nZXRDYXVzZSgpOworICAgICAgICAgICAgaWYgKGNhdXNlID09IG51bGwpIHsgLy9HTlUgSmF2YU1haWwgZG9lc24ndCBzdXBwb3J0IDEuNCBjaGFpbmluZy4KKyAgICAgICAgICAgICAgIGNhdXNlID0gKChNZXNzYWdpbmdFeGNlcHRpb24pIHQpLmdldE5leHRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBpc0Nvbm5lY3RPclRpbWVvdXQoY2F1c2UpOworICAgICAgICB9IGVsc2UgaWYgKGlzSW5zdGFuY2VvZih0LCAiY29tLnN1bi5tYWlsLnV0aWwuU29ja2V0Q29ubmVjdEV4Y2VwdGlvbiIpKSB7CisgICAgICAgICAgICByZXR1cm4gaXNDb25uZWN0T3JUaW1lb3V0KHQuZ2V0Q2F1c2UoKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gdCBpbnN0YW5jZW9mIGphdmEubmV0LkNvbm5lY3RFeGNlcHRpb24KKyAgICAgICAgICAgICAgICAgICAgfHwgdCBpbnN0YW5jZW9mIGphdmEubmV0LlVua25vd25Ib3N0RXhjZXB0aW9uCisgICAgICAgICAgICAgICAgICAgIHx8IHQgaW5zdGFuY2VvZiBqYXZhLm5ldC5Tb2NrZXRUaW1lb3V0RXhjZXB0aW9uOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc0luc3RhbmNlb2YoT2JqZWN0IG8sIFN0cmluZyBzKSB7CisgICAgICAgIGlmIChzID09IG51bGwpIHsKKyAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBpZiAobyAhPSBudWxsKSB7CisgICAgICAgICAgICBmb3IgKENsYXNzPD8+IGsgPSBvLmdldENsYXNzKCk7IGsgIT0gbnVsbDsgayA9IGsuZ2V0U3VwZXJjbGFzcygpKSB7CisgICAgICAgICAgICAgICAgaWYgKHMuZXF1YWxzKGsuZ2V0Q2xhc3MoKS5nZXROYW1lKCkpKSB7CisgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzTm9SZWNpcGllbnRBZGRyZXNzKFRocm93YWJsZSB0KSB7CisgICAgICAgIGlmICh0IGluc3RhbmNlb2YgTWVzc2FnaW5nRXhjZXB0aW9uKSB7CisgICAgICAgICAgICByZXR1cm4gU3RyaW5nLnZhbHVlT2YodCkuY29udGFpbnMoIk5vIHJlY2lwaWVudCBhZGRyZXNzZXMiKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgSW50ZXJuYWxFcnJvck1hbmFnZXIgaW50ZXJuYWxFcnJvck1hbmFnZXJGcm9tKEhhbmRsZXIgaCkgeworICAgICAgICBmaW5hbCBFcnJvck1hbmFnZXIgZW0gPSBoLmdldEVycm9yTWFuYWdlcigpOworICAgICAgICBpZiAoZW0gaW5zdGFuY2VvZiBJbnRlcm5hbEVycm9yTWFuYWdlcikgeworICAgICAgICAgICAgcmV0dXJuIChJbnRlcm5hbEVycm9yTWFuYWdlcikgZW07CisgICAgICAgIH0KKyAgICAgICAgdGhyb3cgbmV3IENsYXNzQ2FzdEV4Y2VwdGlvbihTdHJpbmcudmFsdWVPZihlbSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGh0dHA6Ly93d3cuaWFuYS5vcmcvYXNzaWdubWVudHMvcG9ydC1udW1iZXJzCisgICAgICoKKyAgICAgKiBAcmV0dXJuIGEgb3BlbiBkeW5hbWljIHBvcnQuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IGZpbmRPcGVuUG9ydCgpIHsKKyAgICAgICAgZmluYWwgaW50IE1BWF9QT1JUID0gNjU1MzU7CisgICAgICAgIGZvciAoaW50IGkgPSA0OTE1MjsgaSA8PSBNQVhfUE9SVDsgKytpKSB7CisgICAgICAgICAgICBpZiAoY2hlY2tVbnVzZWRQb3J0KGkpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICB0cnkgeworICAgICAgICAgICAgY2xvc2UobmV3IFNvY2tldCgibG9jYWxob3N0IiwgTUFYX1BPUlQpKTsKKyAgICAgICAgICAgIHJldHVybiBNQVhfUE9SVDsKKyAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsgLy9Db25maWcgZXJyb3Igb3IgZml4IGlzQ29ubmVjdE9yVGltZW91dCBtZXRob2QuCisgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIkNhbid0IGZpbmQgb3BlbiBwb3J0LiIsIHQpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBjaGVja1VudXNlZFBvcnQoaW50IHBvcnQpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGNsb3NlKG5ldyBTb2NrZXQoImxvY2FsaG9zdCIsIHBvcnQpKTsKKyAgICAgICAgfSBjYXRjaCAoVW5rbm93bkhvc3RFeGNlcHRpb24gVUhFKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoVUhFKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gSU9FKSB7CisgICAgICAgICAgICByZXR1cm4gaXNDb25uZWN0T3JUaW1lb3V0KElPRSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOyAvL2xpc3RlbmluZy4KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGNsb3NlKFNvY2tldCBzKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzLmNsb3NlKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlnbm9yZSkgeworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgYWJzdHJhY3QgY2xhc3MgTWVzc2FnZUVycm9yTWFuYWdlciBleHRlbmRzIEludGVybmFsRXJyb3JNYW5hZ2VyIHsKKworICAgICAgICBwcml2YXRlIGZpbmFsIFByb3BlcnRpZXMgcHJvcHM7CisKKyAgICAgICAgcHJvdGVjdGVkIE1lc3NhZ2VFcnJvck1hbmFnZXIoZmluYWwgUHJvcGVydGllcyBwcm9wcykgeworICAgICAgICAgICAgaWYgKHByb3BzID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRoaXMucHJvcHMgPSBwcm9wczsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgZmluYWwgdm9pZCBlcnJvcihTdHJpbmcgbXNnLCBFeGNlcHRpb24gZXgsIGludCBjb2RlKSB7CisgICAgICAgICAgICBzdXBlci5lcnJvcihtc2csIGV4LCBjb2RlKTsKKyAgICAgICAgICAgIGlmIChtc2cgIT0gbnVsbCAmJiBtc2cubGVuZ3RoKCkgPiAwCisgICAgICAgICAgICAgICAgICAgICYmICFtc2cuc3RhcnRzV2l0aChMZXZlbC5TRVZFUkUuZ2V0TmFtZSgpKSkgeworICAgICAgICAgICAgICAgIE1pbWVNZXNzYWdlIG1lc3NhZ2U7CisgICAgICAgICAgICAgICAgdHJ5IHsgLy9IZWFkZXJzIGNhbiBiZSBVVEYtOCBvciBVUy1BU0NJSS4KKyAgICAgICAgICAgICAgICAgICAgYnl0ZVtdIGIgPSBtc2cuZ2V0Qnl0ZXMoIlVURi04Iik7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydFRydWUoYi5sZW5ndGggPiAwKTsKKworICAgICAgICAgICAgICAgICAgICBCeXRlQXJyYXlJbnB1dFN0cmVhbSBpbiA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShiKTsKKyAgICAgICAgICAgICAgICAgICAgU2Vzc2lvbiBzZXNzaW9uID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShwcm9wcyk7CisgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgTWltZU1lc3NhZ2Uoc2Vzc2lvbiwgaW4pOworICAgICAgICAgICAgICAgICAgICBlcnJvcihtZXNzYWdlLCBleCwgY29kZSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXJyb3IgZSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSBUKSB7CisgICAgICAgICAgICAgICAgICAgIGZhaWwoVC50b1N0cmluZygpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIG5ldyBFcnJvck1hbmFnZXIoKS5lcnJvcihtc2csIGV4LCBjb2RlKTsKKyAgICAgICAgICAgICAgICBmYWlsKCJNZXNzYWdlLndyaXRlVG8gZmFpbGVkLiIpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHJvdGVjdGVkIGFic3RyYWN0IHZvaWQgZXJyb3IoTWltZU1lc3NhZ2UgbXNnLCBUaHJvd2FibGUgdCwgaW50IGNvZGUpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgUHVzaEVycm9yTWFuYWdlciBleHRlbmRzIE1lc3NhZ2VFcnJvck1hbmFnZXIgeworCisgICAgICAgIHB1YmxpYyBQdXNoRXJyb3JNYW5hZ2VyKE1haWxIYW5kbGVyIGgpIHsKKyAgICAgICAgICAgIHN1cGVyKGguZ2V0TWFpbFByb3BlcnRpZXMoKSk7CisgICAgICAgIH0KKworICAgICAgICBwcm90ZWN0ZWQgUHVzaEVycm9yTWFuYWdlcihQcm9wZXJ0aWVzIHApIHsKKyAgICAgICAgICAgIHN1cGVyKHApOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCB2b2lkIGVycm9yKE1pbWVNZXNzYWdlIG1lc3NhZ2UsIFRocm93YWJsZSB0LCBpbnQgY29kZSkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBhc3NlcnROb3ROdWxsKG1lc3NhZ2UuZ2V0U2VudERhdGUoKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChtZXNzYWdlLmdldERlc2NyaXB0aW9uKCkpOworICAgICAgICAgICAgICAgIGFzc2VydE5vdE51bGwobWVzc2FnZS5nZXRIZWFkZXIoIlgtUHJpb3JpdHkiKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCIyIiwgbWVzc2FnZS5nZXRIZWFkZXIoIlgtUHJpb3JpdHkiKVswXSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChtZXNzYWdlLmdldEhlYWRlcigiSW1wb3J0YW5jZSIpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkhpZ2giLCBtZXNzYWdlLmdldEhlYWRlcigiSW1wb3J0YW5jZSIpWzBdKTsKKyAgICAgICAgICAgICAgICBhc3NlcnROb3ROdWxsKG1lc3NhZ2UuZ2V0SGVhZGVyKCJQcmlvcml0eSIpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoInVyZ2VudCIsIG1lc3NhZ2UuZ2V0SGVhZGVyKCJQcmlvcml0eSIpWzBdKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImF1dG8tZ2VuZXJhdGVkIiwgbWVzc2FnZS5nZXRIZWFkZXIoImF1dG8tc3VibWl0dGVkIilbMF0pOworICAgICAgICAgICAgICAgIG1lc3NhZ2Uuc2F2ZUNoYW5nZXMoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gfCBNZXNzYWdpbmdFeGNlcHRpb24gUkUpIHsKKyAgICAgICAgICAgICAgICBkdW1wKFJFKTsKKyAgICAgICAgICAgICAgICBmYWlsKFJFLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBWZXJpZnlFcnJvck1hbmFnZXIgZXh0ZW5kcyBQdXNoRXJyb3JNYW5hZ2VyIHsKKworICAgICAgICBwdWJsaWMgVmVyaWZ5RXJyb3JNYW5hZ2VyKCkgeworICAgICAgICAgICAgc3VwZXIobmV3IFByb3BlcnRpZXMoKSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgZXJyb3IoTWltZU1lc3NhZ2UgbWVzc2FnZSwgVGhyb3dhYmxlIHQsIGludCBjb2RlKSB7CisgICAgICAgICAgICBzdXBlci5lcnJvcihtZXNzYWdlLCB0LCBjb2RlKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZmluYWwgTG9jYWxlIGxvY2FsZSA9IExvY2FsZS5nZXREZWZhdWx0KCk7CisgICAgICAgICAgICAgICAgU3RyaW5nIGxhbmcgPSBMb2dNYW5hZ2VyUHJvcGVydGllcy50b0xhbmd1YWdlVGFnKGxvY2FsZSk7CisgICAgICAgICAgICAgICAgaWYgKGxhbmcubGVuZ3RoKCkgIT0gMCkgeworICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMobGFuZywgbWVzc2FnZS5nZXRIZWFkZXIoIkFjY2VwdC1MYW5ndWFnZSIsIG51bGwpKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIiIsIGxvY2FsZS5nZXRMYW5ndWFnZSgpKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBBZGRyZXNzW10gYSA9IG1lc3NhZ2UuZ2V0UmVjaXBpZW50cyhNZXNzYWdlLlJlY2lwaWVudFR5cGUuVE8pOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhJbnRlcm5ldEFkZHJlc3MucGFyc2UoImZvb0BiYXIuY29tIilbMF0sIGFbMF0pOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygxLCBhLmxlbmd0aCk7CisKKyAgICAgICAgICAgICAgICBhID0gbWVzc2FnZS5nZXRSZWNpcGllbnRzKE1lc3NhZ2UuUmVjaXBpZW50VHlwZS5DQyk7CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKEludGVybmV0QWRkcmVzcy5wYXJzZSgiZml6ekBidXp6LmNvbSIpWzBdLCBhWzBdKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgYS5sZW5ndGgpOworCisgICAgICAgICAgICAgICAgYSA9IG1lc3NhZ2UuZ2V0UmVjaXBpZW50cyhNZXNzYWdlLlJlY2lwaWVudFR5cGUuQkNDKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoSW50ZXJuZXRBZGRyZXNzLnBhcnNlKCJiYXpAYmFyLmNvbSIpWzBdLCBhWzBdKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgYS5sZW5ndGgpOworCisgICAgICAgICAgICAgICAgYSA9IG1lc3NhZ2UuZ2V0RnJvbSgpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhJbnRlcm5ldEFkZHJlc3MucGFyc2UoImxvY2FsaG9zdEBsb2NhbGRvbWFpbiIpWzBdLCBhWzBdKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoMSwgYS5sZW5ndGgpOworCisgICAgICAgICAgICAgICAgYSA9IG5ldyBBZGRyZXNzW117bWVzc2FnZS5nZXRTZW5kZXIoKX07CisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKEludGVybmV0QWRkcmVzcy5wYXJzZSgibWFpbEBoYW5kbGVyIilbMF0sIGFbMF0pOworCisgICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKE1haWxIYW5kbGVyLmNsYXNzLmdldE5hbWUoKSArICIgdGVzdCIsIG1lc3NhZ2UuZ2V0U3ViamVjdCgpKTsKKworICAgICAgICAgICAgICAgIGFzc2VydE5vdE51bGwobWVzc2FnZS5nZXRIZWFkZXIoIkluY29tcGxldGUtQ29weSIsIG51bGwpKTsKKworICAgICAgICAgICAgICAgIGFzc2VydFRydWUobWVzc2FnZS5nZXRDb250ZW50VHlwZSgpLCBtZXNzYWdlLmlzTWltZVR5cGUoIm11bHRpcGFydC9taXhlZCIpKTsKKyAgICAgICAgICAgICAgICBNdWx0aXBhcnQgbXVsdGlwYXJ0ID0gKE11bHRpcGFydCkgbWVzc2FnZS5nZXRDb250ZW50KCk7CisgICAgICAgICAgICAgICAgTWltZVBhcnQgYm9keSA9IChNaW1lUGFydCkgbXVsdGlwYXJ0LmdldEJvZHlQYXJ0KDApOworICAgICAgICAgICAgICAgIENvbnRlbnRUeXBlIHR5cGUgPSBuZXcgQ29udGVudFR5cGUoYm9keS5nZXRDb250ZW50VHlwZSgpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoInRleHQvcGxhaW4iLCB0eXBlLmdldEJhc2VUeXBlKCkpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygidXMtYXNjaWkiLCB0eXBlLmdldFBhcmFtZXRlcigiY2hhcnNldCIpLnRvTG93ZXJDYXNlKExvY2FsZS5VUykpOworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiYXV0by1nZW5lcmF0ZWQiLCBtZXNzYWdlLmdldEhlYWRlcigiYXV0by1zdWJtaXR0ZWQiKVswXSk7CisKKyAgICAgICAgICAgICAgICBpZiAobGFuZy5sZW5ndGgoKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhsYW5nLCBib2R5LmdldEhlYWRlcigiQWNjZXB0LUxhbmd1YWdlIiwgbnVsbCkpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiIiwgbG9jYWxlLmdldExhbmd1YWdlKCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiB8IElPRXhjZXB0aW9uIG1lKSB7CisgICAgICAgICAgICAgICAgZHVtcChtZSk7CisgICAgICAgICAgICAgICAgZmFpbChtZS50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgRmx1c2hFcnJvck1hbmFnZXIgZXh0ZW5kcyBNZXNzYWdlRXJyb3JNYW5hZ2VyIHsKKworICAgICAgICBwdWJsaWMgRmx1c2hFcnJvck1hbmFnZXIoTWFpbEhhbmRsZXIgaCkgeworICAgICAgICAgICAgc3VwZXIoaC5nZXRNYWlsUHJvcGVydGllcygpKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgdm9pZCBlcnJvcihNaW1lTWVzc2FnZSBtZXNzYWdlLCBUaHJvd2FibGUgdCwgaW50IGNvZGUpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0VHJ1ZShudWxsICE9IG1lc3NhZ2UuZ2V0U2VudERhdGUoKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChtZXNzYWdlLmdldERlc2NyaXB0aW9uKCkpOworICAgICAgICAgICAgICAgIGFzc2VydE51bGwobWVzc2FnZS5nZXRIZWFkZXIoIlgtUHJpb3JpdHkiKSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0TnVsbChtZXNzYWdlLmdldEhlYWRlcigiSW1wb3J0YW5jZSIpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnROdWxsKG1lc3NhZ2UuZ2V0SGVhZGVyKCJQcmlvcml0eSIpKTsKKyAgICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoImF1dG8tZ2VuZXJhdGVkIiwgbWVzc2FnZS5nZXRIZWFkZXIoImF1dG8tc3VibWl0dGVkIilbMF0pOworICAgICAgICAgICAgICAgIG1lc3NhZ2Uuc2F2ZUNoYW5nZXMoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gfCBNZXNzYWdpbmdFeGNlcHRpb24gUkUpIHsKKyAgICAgICAgICAgICAgICBkdW1wKFJFKTsKKyAgICAgICAgICAgICAgICBmYWlsKFJFLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBUaHJvd0ZpbHRlciBpbXBsZW1lbnRzIEZpbHRlciB7CisKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoIm92ZXJyaWRlIikgLy9KREstNjk1NDIzNAorICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0xvZ2dhYmxlKExvZ1JlY29yZCByZWNvcmQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKHJlY29yZC50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGhyb3dDb21wYXJhdG9yCisgICAgICAgICAgICBpbXBsZW1lbnRzIENvbXBhcmF0b3I8TG9nUmVjb3JkPiwgU2VyaWFsaXphYmxlIHsKKworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA4NDkzNzA3OTI4ODI5OTY2MzUzTDsKKworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygib3ZlcnJpZGUiKSAvL0pESy02OTU0MjM0CisgICAgICAgIHB1YmxpYyBpbnQgY29tcGFyZShMb2dSZWNvcmQgbzEsIExvZ1JlY29yZCBvMikgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGhyb3dGb3JtYXR0ZXIgZXh0ZW5kcyBGb3JtYXR0ZXIgeworCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgU3RyaW5nIGZvcm1hdChMb2dSZWNvcmQgcmVjb3JkKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiZm9ybWF0Iik7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFN0cmluZyBnZXRIZWFkKEhhbmRsZXIgaCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oImhlYWQiKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFRhaWwoSGFuZGxlciBoKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigidGFpbCIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBVc2VsZXNzQ29tcGFyYXRvcgorICAgICAgICAgICAgaW1wbGVtZW50cyBDb21wYXJhdG9yPExvZ1JlY29yZD4sIFNlcmlhbGl6YWJsZSB7CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNzk3MzU3NTA0MzY4MDU5NjcyMkw7CisKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoIm92ZXJyaWRlIikgLy9KREstNjk1NDIzNAorICAgICAgICBwdWJsaWMgaW50IGNvbXBhcmUoTG9nUmVjb3JkIG8xLCBMb2dSZWNvcmQgbzIpIHsKKyAgICAgICAgICAgIHJldHVybiBvMS50b1N0cmluZygpLmNvbXBhcmVUbyhvMi50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgIH07CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFNlcXVlbmNlQ29tcGFyYXRvcgorICAgICAgICAgICAgaW1wbGVtZW50cyBDb21wYXJhdG9yPExvZ1JlY29yZD4sIFNlcmlhbGl6YWJsZSB7CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CisKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoIm92ZXJyaWRlIikgLy9KREstNjk1NDIzNAorICAgICAgICBwdWJsaWMgaW50IGNvbXBhcmUoTG9nUmVjb3JkIG8xLCBMb2dSZWNvcmQgbzIpIHsKKyAgICAgICAgICAgIGxvbmcgczEgPSBvMS5nZXRTZXF1ZW5jZU51bWJlcigpOworICAgICAgICAgICAgbG9uZyBzMiA9IG8yLmdldFNlcXVlbmNlTnVtYmVyKCk7CisgICAgICAgICAgICByZXR1cm4gczEgPCBzMiA/IC0xIDogczEgPiBzMiA/IDEgOiAwOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBTZXF1ZW5jZURlc2NDb21wYXJhdG9yCisgICAgICAgICAgICBpbXBsZW1lbnRzIENvbXBhcmF0b3I8TG9nUmVjb3JkPiwgU2VyaWFsaXphYmxlIHsKKworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTDsKKworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygib3ZlcnJpZGUiKSAvL0pESy02OTU0MjM0CisgICAgICAgIHB1YmxpYyBpbnQgY29tcGFyZShMb2dSZWNvcmQgbzEsIExvZ1JlY29yZCBvMikgeworICAgICAgICAgICAgbG9uZyBzMSA9IG8xLmdldFNlcXVlbmNlTnVtYmVyKCk7CisgICAgICAgICAgICBsb25nIHMyID0gbzIuZ2V0U2VxdWVuY2VOdW1iZXIoKTsKKyAgICAgICAgICAgIHJldHVybiBzMSA8IHMyID8gMSA6IHMxID4gczIgPyAtMSA6IDA7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFNlcXVlbmNlQ29tcGFyYXRvcldpdGhSZXZlcnNlCisgICAgICAgICAgICBpbXBsZW1lbnRzIENvbXBhcmF0b3I8TG9nUmVjb3JkPiwgU2VyaWFsaXphYmxlIHsKKworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTDsKKworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygib3ZlcnJpZGUiKSAvL0pESy02OTU0MjM0CisgICAgICAgIHB1YmxpYyBpbnQgY29tcGFyZShMb2dSZWNvcmQgbzEsIExvZ1JlY29yZCBvMikgeworICAgICAgICAgICAgbG9uZyBzMSA9IG8xLmdldFNlcXVlbmNlTnVtYmVyKCk7CisgICAgICAgICAgICBsb25nIHMyID0gbzIuZ2V0U2VxdWVuY2VOdW1iZXIoKTsKKyAgICAgICAgICAgIHJldHVybiBzMSA8IHMyID8gLTEgOiBzMSA+IHMyID8gMSA6IDA7CisgICAgICAgIH0KKworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygib3ZlcnJpZGUiKQorICAgICAgICBwdWJsaWMgQ29tcGFyYXRvcjxMb2dSZWNvcmQ+IHJldmVyc2VkKCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBTZXF1ZW5jZURlc2NDb21wYXJhdG9yKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFJhd1R5cGVDb21wYXJhdG9yCisgICAgICAgICAgICBpbXBsZW1lbnRzIENvbXBhcmF0b3I8T2JqZWN0PiwgU2VyaWFsaXphYmxlIHsKKworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNjUzOTE3OTEwNjU0MTYxNzQwMEw7CisKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoIm92ZXJyaWRlIikgLy9KREstNjk1NDIzNAorICAgICAgICBwdWJsaWMgaW50IGNvbXBhcmUoT2JqZWN0IG8xLCBPYmplY3QgbzIpIHsKKyAgICAgICAgICAgIGxvbmcgczEgPSBMb2dSZWNvcmQuY2xhc3MuY2FzdChvMSkuZ2V0U2VxdWVuY2VOdW1iZXIoKTsKKyAgICAgICAgICAgIGxvbmcgczIgPSBMb2dSZWNvcmQuY2xhc3MuY2FzdChvMikuZ2V0U2VxdWVuY2VOdW1iZXIoKTsKKyAgICAgICAgICAgIHJldHVybiBzMSA8IHMyID8gLTEgOiBzMSA+IHMyID8gMSA6IDA7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEFjdGl2YXRpb25FcnJvck1hbmFnZXIgZXh0ZW5kcyBJbnRlcm5hbEVycm9yTWFuYWdlciB7CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGVycm9yKFN0cmluZyBtc2csIEV4Y2VwdGlvbiBleCwgaW50IGNvZGUpIHsKKyAgICAgICAgICAgIGlmIChpc0RhdGFUeXBlRXJyb3IobXNnKSkgeworICAgICAgICAgICAgICAgIEV4Y2VwdGlvbiBlID0gbmV3IFVuc3VwcG9ydGVkRGF0YVR5cGVFeGNlcHRpb24obXNnKTsKKyAgICAgICAgICAgICAgICBzdXBlci5lcnJvcihtc2csIGUsIGNvZGUpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBpZiAoIWlzQ29ubmVjdE9yVGltZW91dChleCkpIHsKKyAgICAgICAgICAgICAgICAgICAgc3VwZXIuZXJyb3IobXNnLCBleCwgY29kZSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChUaHJvd2FibGUgdCA9IGV4OyB0ICE9IG51bGw7IHQgPSB0LmdldENhdXNlKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0RhdGFUeXBlRXJyb3IodC5nZXRNZXNzYWdlKCkpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IGlzRGF0YVR5cGVFcnJvcih0LmdldENsYXNzKCkuZ2V0TmFtZSgpKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1cGVyLmVycm9yKG1zZywgZXgsIGNvZGUpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHJpdmF0ZSBib29sZWFuIGlzRGF0YVR5cGVFcnJvcihTdHJpbmcgbSkgeworICAgICAgICAgICAgaWYgKG0gIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJldHVybiBtLmNvbnRhaW5zKCJqYXZheC5hY3RpdmF0aW9uLlVuc3VwcG9ydGVkRGF0YVR5cGVFeGNlcHRpb24iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQm9vbGVhbkZpbHRlciBpbXBsZW1lbnRzIEZpbHRlciB7CisKKyAgICAgICAgc3RhdGljIGZpbmFsIEJvb2xlYW5GaWx0ZXIgVFJVRSA9IG5ldyBCb29sZWFuRmlsdGVyKHRydWUpOworICAgICAgICBzdGF0aWMgZmluYWwgQm9vbGVhbkZpbHRlciBGQUxTRSA9IG5ldyBCb29sZWFuRmlsdGVyKGZhbHNlKTsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIHZhbHVlOworCisgICAgICAgIHB1YmxpYyBCb29sZWFuRmlsdGVyKCkgeworICAgICAgICAgICAgdGhpcyhmYWxzZSk7CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIEJvb2xlYW5GaWx0ZXIoYm9vbGVhbiB2KSB7CisgICAgICAgICAgICB0aGlzLnZhbHVlID0gdjsKKyAgICAgICAgfQorCisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJvdmVycmlkZSIpIC8vSkRLLTY5NTQyMzQKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaXNMb2dnYWJsZShMb2dSZWNvcmQgcikgeworICAgICAgICAgICAgcmV0dXJuIHZhbHVlOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBDb3VudGluZ0ZpbHRlciBpbXBsZW1lbnRzIEZpbHRlciB7CisKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBGaWx0ZXIgcmVzdWx0OworICAgICAgICBpbnQgY291bnQ7CisKKyAgICAgICAgcHVibGljIENvdW50aW5nRmlsdGVyKCkgeworICAgICAgICAgICAgdGhpcy5yZXN1bHQgPSBCb29sZWFuRmlsdGVyLlRSVUU7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgQ291bnRpbmdGaWx0ZXIoRmlsdGVyIGYpIHsKKyAgICAgICAgICAgIHRoaXMucmVzdWx0ID0gZjsKKyAgICAgICAgfQorCisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJvdmVycmlkZSIpIC8vSkRLLTY5NTQyMzQKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaXNMb2dnYWJsZShMb2dSZWNvcmQgcikgeworICAgICAgICAgICAgKytjb3VudDsKKyAgICAgICAgICAgIHJldHVybiByZXN1bHQuaXNMb2dnYWJsZShyKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQ291bnRpbmdGb3JtYXR0ZXIgZXh0ZW5kcyBGb3JtYXR0ZXIgeworCisgICAgICAgIGludCBoZWFkOworICAgICAgICBpbnQgdGFpbDsKKyAgICAgICAgaW50IGZvcm1hdDsKKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFN0cmluZyBnZXRIZWFkKEhhbmRsZXIgaCkgeworICAgICAgICAgICAgKytoZWFkOworICAgICAgICAgICAgcmV0dXJuICIiOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZm9ybWF0KExvZ1JlY29yZCByZWNvcmQpIHsKKyAgICAgICAgICAgICsrZm9ybWF0OworICAgICAgICAgICAgcmV0dXJuIFN0cmluZy52YWx1ZU9mKHJlY29yZC5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFpbChIYW5kbGVyIGgpIHsKKyAgICAgICAgICAgICsrdGFpbDsKKyAgICAgICAgICAgIHJldHVybiAiIjsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgSGVhZEZvcm1hdHRlciBleHRlbmRzIEZvcm1hdHRlciB7CisKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgbmFtZTsKKworICAgICAgICBwdWJsaWMgSGVhZEZvcm1hdHRlcigpIHsKKyAgICAgICAgICAgIHRoaXMoKFN0cmluZykgbnVsbCk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgSGVhZEZvcm1hdHRlcihmaW5hbCBTdHJpbmcgbmFtZSkgeworICAgICAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEhlYWQoSGFuZGxlciBoKSB7CisgICAgICAgICAgICByZXR1cm4gbmFtZTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgU3RyaW5nIGZvcm1hdChMb2dSZWNvcmQgcmVjb3JkKSB7CisgICAgICAgICAgICByZXR1cm4gIiI7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEludGVybmFsRXJyb3JNYW5hZ2VyIGV4dGVuZHMgRXJyb3JNYW5hZ2VyIHsKKworICAgICAgICBwcm90ZWN0ZWQgZmluYWwgTGlzdDxFeGNlcHRpb24+IGV4Y2VwdGlvbnMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgZXJyb3IoU3RyaW5nIG1zZywgRXhjZXB0aW9uIGV4LCBpbnQgY29kZSkgeworICAgICAgICAgICAgZXhjZXB0aW9ucy5hZGQoZXgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUaHJvd0F1dGhlbnRpY2F0b3IgZXh0ZW5kcyBqYXZheC5tYWlsLkF1dGhlbnRpY2F0b3IgeworCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgUGFzc3dvcmRBdXRoZW50aWNhdGlvbiBnZXRQYXNzd29yZEF1dGhlbnRpY2F0aW9uKCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgRW1wdHlBdXRoZW50aWNhdG9yIGV4dGVuZHMgamF2YXgubWFpbC5BdXRoZW50aWNhdG9yIHsKKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIFBhc3N3b3JkQXV0aGVudGljYXRpb24gZ2V0UGFzc3dvcmRBdXRoZW50aWNhdGlvbigpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgUGFzc3dvcmRBdXRoZW50aWNhdGlvbigiIiwgIiIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBFbXB0eUZvcm1hdHRlciBleHRlbmRzIEZvcm1hdHRlciB7CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZm9ybWF0KExvZ1JlY29yZCByKSB7CisgICAgICAgICAgICByZXR1cm4gIiI7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRocm93U2VjdXJpdHlNYW5hZ2VyIGV4dGVuZHMgU2VjdXJpdHlNYW5hZ2VyIHsKKworICAgICAgICBib29sZWFuIHNlY3VyZSA9IGZhbHNlOworICAgICAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gZGVidWc7CisKKyAgICAgICAgcHVibGljIFRocm93U2VjdXJpdHlNYW5hZ2VyKCkgeworICAgICAgICAgICAgZGVidWcgPSBpc1NlY3VyaXR5RGVidWcoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBjaGVja1Blcm1pc3Npb24oamF2YS5zZWN1cml0eS5QZXJtaXNzaW9uIHBlcm0pIHsKKyAgICAgICAgICAgIHRyeSB7IC8vQ2FsbCBzdXBlciBjbGFzcyBhbHdheXMgZm9yIGphdmEuc2VjdXJpdHkuZGVidWcgdHJhY2luZy4KKyAgICAgICAgICAgICAgICBzdXBlci5jaGVja1Blcm1pc3Npb24ocGVybSk7CisgICAgICAgICAgICAgICAgY2hlY2tQZXJtaXNzaW9uKHBlcm0sIG5ldyBTZWN1cml0eUV4Y2VwdGlvbihwZXJtLnRvU3RyaW5nKCkpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHNlKSB7CisgICAgICAgICAgICAgICAgY2hlY2tQZXJtaXNzaW9uKHBlcm0sIHNlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBjaGVja1Blcm1pc3Npb24oamF2YS5zZWN1cml0eS5QZXJtaXNzaW9uIHBlcm0sIE9iamVjdCBjb250ZXh0KSB7CisgICAgICAgICAgICB0cnkgeyAvL0NhbGwgc3VwZXIgY2xhc3MgYWx3YXlzIGZvciBqYXZhLnNlY3VyaXR5LmRlYnVnIHRyYWNpbmcuCisgICAgICAgICAgICAgICAgc3VwZXIuY2hlY2tQZXJtaXNzaW9uKHBlcm0sIGNvbnRleHQpOworICAgICAgICAgICAgICAgIGNoZWNrUGVybWlzc2lvbihwZXJtLCBuZXcgU2VjdXJpdHlFeGNlcHRpb24ocGVybS50b1N0cmluZygpKSk7CisgICAgICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBzZSkgeworICAgICAgICAgICAgICAgIGNoZWNrUGVybWlzc2lvbihwZXJtLCBzZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIHZvaWQgY2hlY2tQZXJtaXNzaW9uKGphdmEuc2VjdXJpdHkuUGVybWlzc2lvbiBwZXJtLCBTZWN1cml0eUV4Y2VwdGlvbiBzZSkgeworICAgICAgICAgICAgaWYgKHNlY3VyZSAmJiBwZXJtIGluc3RhbmNlb2YgTG9nZ2luZ1Blcm1pc3Npb24pIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBzZTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgaWYgKGRlYnVnKSB7CisgICAgICAgICAgICAgICAgICAgIHNlY3VyaXR5RGVidWdQcmludChzZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBHYWVFcnJvck1hbmFnZXIgZXh0ZW5kcyBNZXNzYWdlRXJyb3JNYW5hZ2VyIHsKKworICAgICAgICBwdWJsaWMgR2FlRXJyb3JNYW5hZ2VyKE1haWxIYW5kbGVyIGgpIHsKKyAgICAgICAgICAgIHN1cGVyKGguZ2V0TWFpbFByb3BlcnRpZXMoKSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIHZvaWQgZXJyb3IoTWltZU1lc3NhZ2UgbWVzc2FnZSwgVGhyb3dhYmxlIHQsIGludCBjb2RlKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGFzc2VydEZhbHNlKExvZ01hbmFnZXJQcm9wZXJ0aWVzLmhhc0xvZ01hbmFnZXIoKSk7CisgICAgICAgICAgICAgICAgU3RyaW5nW10gYSA9IG1lc3NhZ2UuZ2V0SGVhZGVyKCJhdXRvLXN1Ym1pdHRlZCIpOworICAgICAgICAgICAgICAgIGFzc2VydFRydWUoQXJyYXlzLnRvU3RyaW5nKGEpLCBhID09IG51bGwgfHwgYS5sZW5ndGggPT0gMCk7CisgICAgICAgICAgICAgICAgbWVzc2FnZS5zYXZlQ2hhbmdlcygpOworICAgICAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBSRSkgeworICAgICAgICAgICAgICAgIGR1bXAoUkUpOworICAgICAgICAgICAgICAgIGZhaWwoUkUudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gTUUpIHsKKyAgICAgICAgICAgICAgICBkdW1wKE1FKTsKKyAgICAgICAgICAgICAgICBmYWlsKE1FLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBHYWVTZWN1cml0eU1hbmFnZXIgZXh0ZW5kcyBTZWN1cml0eU1hbmFnZXIgeworCisgICAgICAgIGJvb2xlYW4gc2VjdXJlID0gZmFsc2U7CisgICAgICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBkZWJ1ZzsKKworICAgICAgICBwdWJsaWMgR2FlU2VjdXJpdHlNYW5hZ2VyKCkgeworICAgICAgICAgICAgZGVidWcgPSBpc1NlY3VyaXR5RGVidWcoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBjaGVja1Blcm1pc3Npb24oamF2YS5zZWN1cml0eS5QZXJtaXNzaW9uIHBlcm0pIHsKKyAgICAgICAgICAgIHRyeSB7IC8vQ2FsbCBzdXBlciBjbGFzcyBhbHdheXMgZm9yIGphdmEuc2VjdXJpdHkuZGVidWcgdHJhY2luZy4KKyAgICAgICAgICAgICAgICBzdXBlci5jaGVja1Blcm1pc3Npb24ocGVybSk7CisgICAgICAgICAgICAgICAgY2hlY2tQZXJtaXNzaW9uKHBlcm0sIG5ldyBTZWN1cml0eUV4Y2VwdGlvbihwZXJtLnRvU3RyaW5nKCkpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHNlKSB7CisgICAgICAgICAgICAgICAgY2hlY2tQZXJtaXNzaW9uKHBlcm0sIHNlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBjaGVja1Blcm1pc3Npb24oamF2YS5zZWN1cml0eS5QZXJtaXNzaW9uIHBlcm0sIE9iamVjdCBjb250ZXh0KSB7CisgICAgICAgICAgICB0cnkgeyAvL0NhbGwgc3VwZXIgY2xhc3MgYWx3YXlzIGZvciBqYXZhLnNlY3VyaXR5LmRlYnVnIHRyYWNpbmcuCisgICAgICAgICAgICAgICAgc3VwZXIuY2hlY2tQZXJtaXNzaW9uKHBlcm0sIGNvbnRleHQpOworICAgICAgICAgICAgICAgIGNoZWNrUGVybWlzc2lvbihwZXJtLCBuZXcgU2VjdXJpdHlFeGNlcHRpb24ocGVybS50b1N0cmluZygpKSk7CisgICAgICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBzZSkgeworICAgICAgICAgICAgICAgIGNoZWNrUGVybWlzc2lvbihwZXJtLCBzZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIHZvaWQgY2hlY2tQZXJtaXNzaW9uKGphdmEuc2VjdXJpdHkuUGVybWlzc2lvbiBwZXJtLCBTZWN1cml0eUV4Y2VwdGlvbiBzZSkgeworICAgICAgICAgICAgaWYgKHNlY3VyZSAmJiBwZXJtIGluc3RhbmNlb2YgTG9nZ2luZ1Blcm1pc3Npb24pIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBTdGFja1RyYWNlRWxlbWVudFtdIHN0YWNrID0gc2UuZ2V0U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgICAgIGlmIChzdGFjay5sZW5ndGggPT0gMCkgeworICAgICAgICAgICAgICAgICAgICBBc3N1bWUuYXNzdW1lTm9FeGNlcHRpb24oc2UpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBmb3IgKFN0YWNrVHJhY2VFbGVtZW50IGUgOiBzdGFjaykgeworICAgICAgICAgICAgICAgICAgICBpZiAoSGFuZGxlci5jbGFzcy5nZXROYW1lKCkuZXF1YWxzKGUuZ2V0Q2xhc3NOYW1lKCkpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBzZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChkZWJ1ZykgeworICAgICAgICAgICAgICAgIHNlY3VyaXR5RGVidWdQcmludChzZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEVycm9yRm9ybWF0dGVyIGV4dGVuZHMgRm9ybWF0dGVyIHsKKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFN0cmluZyBmb3JtYXQoTG9nUmVjb3JkIHJlY29yZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJmb3JtYXQiKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEhlYWQoSGFuZGxlciBoKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoImhlYWQiKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFRhaWwoSGFuZGxlciBoKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoInRhaWwiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgRXJyb3JDb21wYXJhdG9yIGltcGxlbWVudHMgQ29tcGFyYXRvcjxMb2dSZWNvcmQ+LCBTZXJpYWxpemFibGUgeworCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOworCisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJvdmVycmlkZSIpIC8vSkRLLTY5NTQyMzQKKyAgICAgICAgcHVibGljIGludCBjb21wYXJlKExvZ1JlY29yZCByMSwgTG9nUmVjb3JkIHIyKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIiIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBSZWVudHJhbmNlRmlsdGVyIGltcGxlbWVudHMgRmlsdGVyIHsKKworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygib3ZlcnJpZGUiKSAvL0pESy02OTU0MjM0CisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzTG9nZ2FibGUoTG9nUmVjb3JkIHJlY29yZCkgeworICAgICAgICAgICAgaWYgKCFnZXRDbGFzcygpLmdldE5hbWUoKS5lcXVhbHMocmVjb3JkLmdldFNvdXJjZUNsYXNzTmFtZSgpKSkgeworICAgICAgICAgICAgICAgIGZpbmFsIExvZ2dlciBsb2dnZXIgPSBMb2dnZXIuZ2V0TG9nZ2VyKHJlY29yZC5nZXRMb2dnZXJOYW1lKCkpOworICAgICAgICAgICAgICAgIGxvZ2dlci5sb2dwKExldmVsLlNFVkVSRSwgZ2V0Q2xhc3MoKS5nZXROYW1lKCksICJpc0xvZ2dhYmxlIiwgdG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgRXJyb3JGaWx0ZXIgaW1wbGVtZW50cyBGaWx0ZXIgeworCisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJvdmVycmlkZSIpIC8vSkRLLTY5NTQyMzQKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaXNMb2dnYWJsZShMb2dSZWNvcmQgcmVjb3JkKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIiIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBGbGlwRmxvcEZpbHRlciBpbXBsZW1lbnRzIEZpbHRlciB7CisKKyAgICAgICAgdm9sYXRpbGUgYm9vbGVhbiB2YWx1ZTsKKworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygib3ZlcnJpZGUiKSAvL0pESy02OTU0MjM0CisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzTG9nZ2FibGUoTG9nUmVjb3JkIHJlY29yZCkgeworICAgICAgICAgICAgcmV0dXJuIHZhbHVlOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBJbml0QXV0aGVudGljYXRvciBleHRlbmRzIGphdmF4Lm1haWwuQXV0aGVudGljYXRvciB7CisKKyAgICAgICAgcHVibGljIEluaXRBdXRoZW50aWNhdG9yKCkgeworICAgICAgICAgICAgdGhyb3dQZW5kaW5nKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIFBhc3N3b3JkQXV0aGVudGljYXRpb24gZ2V0UGFzc3dvcmRBdXRoZW50aWNhdGlvbigpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hNZXRob2RFcnJvcigpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIHN0YXRpYyBjbGFzcyBJbml0RmlsdGVyIGltcGxlbWVudHMgRmlsdGVyIHsKKworICAgICAgICBwdWJsaWMgSW5pdEZpbHRlcigpIHsKKyAgICAgICAgICAgIHRocm93UGVuZGluZygpOworICAgICAgICB9CisKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoIm92ZXJyaWRlIikgLy9KREstNjk1NDIzNAorICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0xvZ2dhYmxlKExvZ1JlY29yZCByZWNvcmQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hNZXRob2RFcnJvcigpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIHN0YXRpYyBjbGFzcyBJbml0Rm9ybWF0dGVyIGV4dGVuZHMgRm9ybWF0dGVyIHsKKworICAgICAgICBwdWJsaWMgSW5pdEZvcm1hdHRlcigpIHsKKyAgICAgICAgICAgIHRocm93UGVuZGluZygpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZm9ybWF0KExvZ1JlY29yZCByZWNvcmQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hNZXRob2RFcnJvcigpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIHN0YXRpYyBjbGFzcyBJbml0Q29tcGFyYXRvcgorICAgICAgICAgICAgaW1wbGVtZW50cyBDb21wYXJhdG9yPExvZ1JlY29yZD4sIFNlcmlhbGl6YWJsZSB7CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CisKKyAgICAgICAgcHVibGljIEluaXRDb21wYXJhdG9yKCkgeworICAgICAgICAgICAgdGhyb3dQZW5kaW5nKCk7CisgICAgICAgIH0KKworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygib3ZlcnJpZGUiKSAvL0pESy02OTU0MjM0CisgICAgICAgIHB1YmxpYyBpbnQgY29tcGFyZShMb2dSZWNvcmQgbzEsIExvZ1JlY29yZCBvMikgeworICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaE1ldGhvZEVycm9yKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgc3RhdGljIGNsYXNzIEluaXRFcnJvck1hbmFnZXIgZXh0ZW5kcyBFcnJvck1hbmFnZXIgeworCisgICAgICAgIHB1YmxpYyBJbml0RXJyb3JNYW5hZ2VyKCkgeworICAgICAgICAgICAgdGhyb3dQZW5kaW5nKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgc3RhdGljIGNsYXNzIEludGVybkZpbHRlckZvcm1hdHRlckNvbXBhcmF0b3IgZXh0ZW5kcyBGb3JtYXR0ZXIKKyAgICAgICAgICAgIGltcGxlbWVudHMgQ29tcGFyYXRvcjxMb2dSZWNvcmQ+LCBGaWx0ZXIsCisgICAgICAgICAgICBTZXJpYWxpemFibGUgeworCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC03MjgyNjczNDk5MDQzMDY2MDAzTDsKKworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygib3ZlcnJpZGUiKSAvL0pESy02OTU0MjM0CisgICAgICAgIHB1YmxpYyBpbnQgY29tcGFyZShMb2dSZWNvcmQgbzEsIExvZ1JlY29yZCBvMikgeworICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygib3ZlcnJpZGUiKSAvL0pESy02OTU0MjM0CisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzTG9nZ2FibGUoTG9nUmVjb3JkIGxyKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgU3RyaW5nIGZvcm1hdChMb2dSZWNvcmQgbHIpIHsKKyAgICAgICAgICAgIHJldHVybiAiIjsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG8pIHsKKyAgICAgICAgICAgIHJldHVybiBvID09IG51bGwgPyBmYWxzZSA6IGdldENsYXNzKCkuZXF1YWxzKG8uZ2V0Q2xhc3MoKSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgICAgIHJldHVybiAzMSAqIGdldENsYXNzKCkuaGFzaENvZGUoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgSW50ZXJuQmFkRmlsdGVyIGltcGxlbWVudHMgRmlsdGVyIHsKKworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygib3ZlcnJpZGUiKSAvL0pESy02OTU0MjM0CisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzTG9nZ2FibGUoTG9nUmVjb3JkIHJlY29yZCkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvKSB7CisgICAgICAgICAgICByZXR1cm4gbyBpbnN0YW5jZW9mIEludGVybkJhZEZpbHRlcjsgLy9Ob3Qgc2FmZS4KKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICAgICAgcmV0dXJuIDMxICogSW50ZXJuQmFkRmlsdGVyLmNsYXNzLmhhc2hDb2RlKCk7IC8vTm90IHNhZmUuCisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgc3RhdGljIGNsYXNzIEludGVybkJhZFN1YkZpbHRlciBleHRlbmRzIEludGVybkJhZEZpbHRlciB7CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzTG9nZ2FibGUoTG9nUmVjb3JkIHJlY29yZCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIHN0YXRpYyBjbGFzcyBJbnRlcm5GaWx0ZXIgaW1wbGVtZW50cyBGaWx0ZXIgeworCisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJvdmVycmlkZSIpIC8vSkRLLTY5NTQyMzQKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaXNMb2dnYWJsZShMb2dSZWNvcmQgbHIpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgbykgeworICAgICAgICAgICAgcmV0dXJuIG8gPT0gbnVsbCA/IGZhbHNlIDogZ2V0Q2xhc3MoKS5lcXVhbHMoby5nZXRDbGFzcygpKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICAgICAgcmV0dXJuIDMxICogZ2V0Q2xhc3MoKS5oYXNoQ29kZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIHN0YXRpYyBjbGFzcyBJbnRlcm5GaWx0ZXJFcnJvck1hbmFnZXIKKyAgICAgICAgICAgIGV4dGVuZHMgSW50ZXJuYWxFcnJvck1hbmFnZXIgaW1wbGVtZW50cyBGaWx0ZXIgeworCisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJvdmVycmlkZSIpIC8vSkRLLTY5NTQyMzQKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaXNMb2dnYWJsZShMb2dSZWNvcmQgbHIpIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgbykgeworICAgICAgICAgICAgcmV0dXJuIG8gPT0gbnVsbCA/IGZhbHNlIDogZ2V0Q2xhc3MoKS5lcXVhbHMoby5nZXRDbGFzcygpKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICAgICAgcmV0dXJuIDMxICogZ2V0Q2xhc3MoKS5oYXNoQ29kZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIHN0YXRpYyBjbGFzcyBJbnRlcm5GaWx0ZXJGb3JtYXR0ZXIKKyAgICAgICAgICAgIGV4dGVuZHMgRm9ybWF0dGVyIGltcGxlbWVudHMgRmlsdGVyIHsKKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFN0cmluZyBmb3JtYXQoTG9nUmVjb3JkIGxyKSB7CisgICAgICAgICAgICByZXR1cm4gIiI7CisgICAgICAgIH0KKworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygib3ZlcnJpZGUiKSAvL0pESy02OTU0MjM0CisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzTG9nZ2FibGUoTG9nUmVjb3JkIGxyKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG8pIHsKKyAgICAgICAgICAgIHJldHVybiBvID09IG51bGwgPyBmYWxzZSA6IGdldENsYXNzKCkuZXF1YWxzKG8uZ2V0Q2xhc3MoKSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgICAgICAgIHJldHVybiAzMSAqIGdldENsYXNzKCkuaGFzaENvZGUoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgY2xhc3MgSW50ZXJuRm9ybWF0dGVyIGV4dGVuZHMgRm9ybWF0dGVyIHsKKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvKSB7CisgICAgICAgICAgICByZXR1cm4gbyA9PSBudWxsID8gZmFsc2UgOiBnZXRDbGFzcygpLmVxdWFscyhvLmdldENsYXNzKCkpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgICAgICByZXR1cm4gMzEgKiBnZXRDbGFzcygpLmhhc2hDb2RlKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFN0cmluZyBmb3JtYXQoTG9nUmVjb3JkIGxyKSB7CisgICAgICAgICAgICByZXR1cm4gIiI7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFN0YXRpY0luaXRSZUF1dGhlbnRpY2F0b3IgZXh0ZW5kcyBqYXZheC5tYWlsLkF1dGhlbnRpY2F0b3IgeworCisgICAgICAgIHN0YXRpYyB7CisgICAgICAgICAgICB0aHJvd1BlbmRpbmcoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwcm90ZWN0ZWQgUGFzc3dvcmRBdXRoZW50aWNhdGlvbiBnZXRQYXNzd29yZEF1dGhlbnRpY2F0aW9uKCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaE1ldGhvZEVycm9yKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgc3RhdGljIGNsYXNzIFN0YXRpY0luaXRSZUZpbHRlciBpbXBsZW1lbnRzIEZpbHRlciB7CisKKyAgICAgICAgc3RhdGljIHsKKyAgICAgICAgICAgIHRocm93UGVuZGluZygpOworICAgICAgICB9CisKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoIm92ZXJyaWRlIikgLy9KREstNjk1NDIzNAorICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0xvZ2dhYmxlKExvZ1JlY29yZCByZWNvcmQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hNZXRob2RFcnJvcigpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIHN0YXRpYyBjbGFzcyBTdGF0aWNJbml0UmVBdHRhY2hGaWx0ZXIgaW1wbGVtZW50cyBGaWx0ZXIgeworCisgICAgICAgIHN0YXRpYyB7CisgICAgICAgICAgICB0aHJvd1BlbmRpbmcoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJvdmVycmlkZSIpIC8vSkRLLTY5NTQyMzQKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaXNMb2dnYWJsZShMb2dSZWNvcmQgcmVjb3JkKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoTWV0aG9kRXJyb3IoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgY2xhc3MgU3RhdGljSW5pdFJlRm9ybWF0dGVyIGV4dGVuZHMgRm9ybWF0dGVyIHsKKworICAgICAgICBzdGF0aWMgeworICAgICAgICAgICAgdGhyb3dQZW5kaW5nKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFN0cmluZyBmb3JtYXQoTG9nUmVjb3JkIHJlY29yZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaE1ldGhvZEVycm9yKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgc3RhdGljIGNsYXNzIFN0YXRpY0luaXRSZVN1YmplY3RGb3JtYXR0ZXIgZXh0ZW5kcyBGb3JtYXR0ZXIgeworCisgICAgICAgIHN0YXRpYyB7CisgICAgICAgICAgICB0aHJvd1BlbmRpbmcoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgU3RyaW5nIGZvcm1hdChMb2dSZWNvcmQgcmVjb3JkKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoTWV0aG9kRXJyb3IoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgY2xhc3MgU3RhdGljSW5pdFJlQXR0YWNoRm9ybWF0dGVyIGV4dGVuZHMgRm9ybWF0dGVyIHsKKworICAgICAgICBzdGF0aWMgeworICAgICAgICAgICAgdGhyb3dQZW5kaW5nKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFN0cmluZyBmb3JtYXQoTG9nUmVjb3JkIHJlY29yZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaE1ldGhvZEVycm9yKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgc3RhdGljIGNsYXNzIFN0YXRpY0luaXRSZU5hbWVGb3JtYXR0ZXIgZXh0ZW5kcyBGb3JtYXR0ZXIgeworCisgICAgICAgIHN0YXRpYyB7CisgICAgICAgICAgICB0aHJvd1BlbmRpbmcoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgU3RyaW5nIGZvcm1hdChMb2dSZWNvcmQgcmVjb3JkKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoTWV0aG9kRXJyb3IoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgY2xhc3MgU3RhdGljSW5pdFJlQ29tcGFyYXRvcgorICAgICAgICAgICAgaW1wbGVtZW50cyBDb21wYXJhdG9yPExvZ1JlY29yZD4sIFNlcmlhbGl6YWJsZSB7CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CisKKyAgICAgICAgc3RhdGljIHsKKyAgICAgICAgICAgIHRocm93UGVuZGluZygpOworICAgICAgICB9CisKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoIm92ZXJyaWRlIikgLy9KREstNjk1NDIzNAorICAgICAgICBwdWJsaWMgaW50IGNvbXBhcmUoTG9nUmVjb3JkIG8xLCBMb2dSZWNvcmQgbzIpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hNZXRob2RFcnJvcigpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIHN0YXRpYyBjbGFzcyBTdGF0aWNJbml0UmVFcnJvck1hbmFnZXIgZXh0ZW5kcyBFcnJvck1hbmFnZXIgeworCisgICAgICAgIHN0YXRpYyB7CisgICAgICAgICAgICB0aHJvd1BlbmRpbmcoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgU3RhdGljSW5pdEVyQXV0aGVudGljYXRvciBleHRlbmRzIGphdmF4Lm1haWwuQXV0aGVudGljYXRvciB7CisKKyAgICAgICAgc3RhdGljIHsKKyAgICAgICAgICAgIHRocm93UGVuZGluZygpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHByb3RlY3RlZCBQYXNzd29yZEF1dGhlbnRpY2F0aW9uIGdldFBhc3N3b3JkQXV0aGVudGljYXRpb24oKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoTWV0aG9kRXJyb3IoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgY2xhc3MgU3RhdGljSW5pdEVyRmlsdGVyIGltcGxlbWVudHMgRmlsdGVyIHsKKworICAgICAgICBzdGF0aWMgeworICAgICAgICAgICAgdGhyb3dQZW5kaW5nKCk7CisgICAgICAgIH0KKworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygib3ZlcnJpZGUiKSAvL0pESy02OTU0MjM0CisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzTG9nZ2FibGUoTG9nUmVjb3JkIHJlY29yZCkgeworICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaE1ldGhvZEVycm9yKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgc3RhdGljIGNsYXNzIFN0YXRpY0luaXRFckF0dGFjaEZpbHRlciBpbXBsZW1lbnRzIEZpbHRlciB7CisKKyAgICAgICAgc3RhdGljIHsKKyAgICAgICAgICAgIHRocm93UGVuZGluZygpOworICAgICAgICB9CisKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoIm92ZXJyaWRlIikgLy9KREstNjk1NDIzNAorICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0xvZ2dhYmxlKExvZ1JlY29yZCByZWNvcmQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hNZXRob2RFcnJvcigpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIHN0YXRpYyBjbGFzcyBTdGF0aWNJbml0RXJGb3JtYXR0ZXIgZXh0ZW5kcyBGb3JtYXR0ZXIgeworCisgICAgICAgIHN0YXRpYyB7CisgICAgICAgICAgICB0aHJvd1BlbmRpbmcoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgU3RyaW5nIGZvcm1hdChMb2dSZWNvcmQgcmVjb3JkKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoTWV0aG9kRXJyb3IoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgY2xhc3MgU3RhdGljSW5pdEVyU3ViamVjdEZvcm1hdHRlciBleHRlbmRzIEZvcm1hdHRlciB7CisKKyAgICAgICAgc3RhdGljIHsKKyAgICAgICAgICAgIHRocm93UGVuZGluZygpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZm9ybWF0KExvZ1JlY29yZCByZWNvcmQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hNZXRob2RFcnJvcigpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIHN0YXRpYyBjbGFzcyBTdGF0aWNJbml0RXJBdHRhY2hGb3JtYXR0ZXIgZXh0ZW5kcyBGb3JtYXR0ZXIgeworCisgICAgICAgIHN0YXRpYyB7CisgICAgICAgICAgICB0aHJvd1BlbmRpbmcoKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgU3RyaW5nIGZvcm1hdChMb2dSZWNvcmQgcmVjb3JkKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoTWV0aG9kRXJyb3IoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgY2xhc3MgU3RhdGljSW5pdEVyTmFtZUZvcm1hdHRlciBleHRlbmRzIEZvcm1hdHRlciB7CisKKyAgICAgICAgc3RhdGljIHsKKyAgICAgICAgICAgIHRocm93UGVuZGluZygpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZm9ybWF0KExvZ1JlY29yZCByZWNvcmQpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hNZXRob2RFcnJvcigpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIHN0YXRpYyBjbGFzcyBTdGF0aWNJbml0RXJDb21wYXJhdG9yCisgICAgICAgICAgICBpbXBsZW1lbnRzIENvbXBhcmF0b3I8TG9nUmVjb3JkPiwgU2VyaWFsaXphYmxlIHsKKworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTDsKKworICAgICAgICBzdGF0aWMgeworICAgICAgICAgICAgdGhyb3dQZW5kaW5nKCk7CisgICAgICAgIH0KKworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygib3ZlcnJpZGUiKSAvL0pESy02OTU0MjM0CisgICAgICAgIHB1YmxpYyBpbnQgY29tcGFyZShMb2dSZWNvcmQgbzEsIExvZ1JlY29yZCBvMikgeworICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaE1ldGhvZEVycm9yKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgc3RhdGljIGNsYXNzIFN0YXRpY0luaXRFckVycm9yTWFuYWdlciBleHRlbmRzIEVycm9yTWFuYWdlciB7CisKKyAgICAgICAgc3RhdGljIHsKKyAgICAgICAgICAgIHRocm93UGVuZGluZygpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgY2xhc3MgTGV2ZWxDaGVja2luZ0Zvcm1hdHRlciBleHRlbmRzIEZvcm1hdHRlciB7CisKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBMZXZlbCBleHBlY3Q7CisKKyAgICAgICAgcHVibGljIExldmVsQ2hlY2tpbmdGb3JtYXR0ZXIoZmluYWwgTGV2ZWwgZXhwZWN0KSB7CisgICAgICAgICAgICB0aGlzLmV4cGVjdCA9IGV4cGVjdDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgU3RyaW5nIGZvcm1hdChMb2dSZWNvcmQgbHIpIHsKKyAgICAgICAgICAgIHJldHVybiAiIjsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgU3RyaW5nIGdldEhlYWQoSGFuZGxlciBoKSB7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0LCBoLmdldExldmVsKCkpOworICAgICAgICAgICAgcmV0dXJuICIiOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0VGFpbChIYW5kbGVyIGgpIHsKKyAgICAgICAgICAgIHJldHVybiBnZXRIZWFkKGgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgUHJpbnRUaHJvd3NSdW50aW1lRXhjZXB0aW9uIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbiB7CisKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CisKKyAgICAgICAgUHJpbnRUaHJvd3NSdW50aW1lRXhjZXB0aW9uKFRocm93YWJsZSB0KSB7CisgICAgICAgICAgICBzdXBlcih0KTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBwcmludFN0YWNrVHJhY2UoUHJpbnRXcml0ZXIgcykgeworICAgICAgICAgICAgdGhyb3cgdGhpczsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBwcmludFN0YWNrVHJhY2UoUHJpbnRTdHJlYW0gcykgeworICAgICAgICAgICAgdGhyb3cgdGhpczsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBwcmludFN0YWNrVHJhY2UoKSB7CisgICAgICAgICAgICB0aHJvdyB0aGlzOworICAgICAgICB9CisKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoIkNhbGxUb1ByaW50U3RhY2tUcmFjZSIpCisgICAgICAgIHB1YmxpYyB2b2lkIGR1bXAoKSB7CisgICAgICAgICAgICBUaHJvd2FibGUgdCA9IG5ldyBUaHJvd2FibGUoZ2V0Q2xhc3MoKS5nZXROYW1lKCksIGdldENhdXNlKCkpOworICAgICAgICAgICAgdC5zZXRTdGFja1RyYWNlKGdldFN0YWNrVHJhY2UoKSk7CisgICAgICAgICAgICB0LnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgQ291bnRpbmdVbmNhdWdodEV4Y2VwdGlvbkhhbmRsZXIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1wbGVtZW50cyBUaHJlYWQuVW5jYXVnaHRFeGNlcHRpb25IYW5kbGVyIHsKKworICAgICAgICBpbnQgY291bnQ7CisKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoIm92ZXJyaWRlIikgLy9KREstNjk1NDIzNAorICAgICAgICBwdWJsaWMgdm9pZCB1bmNhdWdodEV4Y2VwdGlvbihUaHJlYWQgdCwgVGhyb3dhYmxlIGUpIHsKKyAgICAgICAgICAgIGNvdW50Kys7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBMaW5rYWdlRXJyb3JTdHJlYW0gZXh0ZW5kcyBQcmludFN0cmVhbSB7CisKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBTdGFja1RyYWNlRWxlbWVudFtdIHN0YWNrOworCisgICAgICAgIExpbmthZ2VFcnJvclN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICB0aGlzKChTdGFja1RyYWNlRWxlbWVudFtdKSBudWxsKTsKKyAgICAgICAgfQorCisgICAgICAgIExpbmthZ2VFcnJvclN0cmVhbShmaW5hbCBTdGFja1RyYWNlRWxlbWVudFtdIHN0YWNrKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgc3VwZXIobmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpLCBmYWxzZSwgIlVURi04Iik7CisgICAgICAgICAgICBpZiAoc3RhY2sgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRoaXMuc3RhY2sgPSBzdGFjay5jbG9uZSgpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICB0aGlzLnN0YWNrID0gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBwcmludGxuKFN0cmluZyB4KSB7CisgICAgICAgICAgICBzZXRFcnJvcigpOworICAgICAgICAgICAgTGlua2FnZUVycm9yIGxlID0gbmV3IExpbmthZ2VFcnJvcih4KTsKKyAgICAgICAgICAgIGlmIChzdGFjayAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgbGUuc2V0U3RhY2tUcmFjZShzdGFjayk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0aHJvdyBsZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIFJ1bnRpbWVFcnJvclN0cmVhbSBleHRlbmRzIFByaW50U3RyZWFtIHsKKworICAgICAgICBwcml2YXRlIGZpbmFsIFN0YWNrVHJhY2VFbGVtZW50W10gc3RhY2s7CisKKyAgICAgICAgUnVudGltZUVycm9yU3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHRoaXMoKFN0YWNrVHJhY2VFbGVtZW50W10pIG51bGwpOworICAgICAgICB9CisKKyAgICAgICAgUnVudGltZUVycm9yU3RyZWFtKGZpbmFsIFN0YWNrVHJhY2VFbGVtZW50W10gc3RhY2spIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBzdXBlcihuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCksIGZhbHNlLCAiVVRGLTgiKTsKKyAgICAgICAgICAgIGlmIChzdGFjayAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgdGhpcy5zdGFjayA9IHN0YWNrLmNsb25lKCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHRoaXMuc3RhY2sgPSBudWxsOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIHByaW50bG4oU3RyaW5nIHgpIHsKKyAgICAgICAgICAgIHNldEVycm9yKCk7CisgICAgICAgICAgICBQcmludFRocm93c1J1bnRpbWVFeGNlcHRpb24gcmUKKyAgICAgICAgICAgICAgICAgICAgPSBuZXcgUHJpbnRUaHJvd3NSdW50aW1lRXhjZXB0aW9uKG5ldyBUaHJvd2FibGUoKSk7CisgICAgICAgICAgICBpZiAoc3RhY2sgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHJlLnNldFN0YWNrVHJhY2Uoc3RhY2spOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhyb3cgcmU7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBjbGFzcyBMb2NhbGVGaWx0ZXIgaW1wbGVtZW50cyBGaWx0ZXIgeworCisgICAgICAgIHByaXZhdGUgZmluYWwgTG9jYWxlIGxvY2FsZTsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIGFsbG93OworCisgICAgICAgIExvY2FsZUZpbHRlcihmaW5hbCBMb2NhbGUgbCwgZmluYWwgYm9vbGVhbiBhbGxvdykgeworICAgICAgICAgICAgaWYgKGwgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhpcy5sb2NhbGUgPSBsOworICAgICAgICAgICAgdGhpcy5hbGxvdyA9IGFsbG93OworICAgICAgICB9CisKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoIm92ZXJyaWRlIikgLy9KREstNjk1NDIzNAorICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0xvZ2dhYmxlKExvZ1JlY29yZCByZWNvcmQpIHsKKyAgICAgICAgICAgIGZpbmFsIFJlc291cmNlQnVuZGxlIHJiID0gcmVjb3JkLmdldFJlc291cmNlQnVuZGxlKCk7CisgICAgICAgICAgICByZXR1cm4gcmIgPT0gbnVsbCA/IGFsbG93IDogbG9jYWxlLmVxdWFscyhyYi5nZXRMb2NhbGUoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGNsYXNzIE1haWxEZWJ1Z0Vycm9yTWFuYWdlciBleHRlbmRzIEVycm9yTWFuYWdlciB7CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGVycm9yKFN0cmluZyBtc2csIEV4Y2VwdGlvbiBleCwgaW50IGNvZGUpIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgU2Vzc2lvbiBzZXNzaW9uID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShjcmVhdGVJbml0UHJvcGVydGllcygiIikpOworICAgICAgICAgICAgICAgIHNlc3Npb24uc2V0RGVidWcodHJ1ZSk7CisgICAgICAgICAgICAgICAgTWVzc2FnZSBtID0gbmV3IE1pbWVNZXNzYWdlKHNlc3Npb24pOworICAgICAgICAgICAgICAgIG0uc2V0RnJvbSgpOworICAgICAgICAgICAgICAgIG0uc2V0UmVjaXBpZW50KE1lc3NhZ2UuUmVjaXBpZW50VHlwZS5UTywgbS5nZXRGcm9tKClbMF0pOworICAgICAgICAgICAgICAgIG0uc2V0VGV4dChNYWlsRGVidWdFcnJvck1hbmFnZXIuY2xhc3MuZ2V0TmFtZSgpKTsKKyAgICAgICAgICAgICAgICBUcmFuc3BvcnQuc2VuZChtKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgc3VwZXIuZXJyb3IobXNnLCBlLCBjb2RlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgY2xhc3MgTWFpbEhhbmRsZXJFeHQgZXh0ZW5kcyBNYWlsSGFuZGxlciB7CisKKyAgICAgICAgcHVibGljIE1haWxIYW5kbGVyRXh0KCkgeworICAgICAgICAgICAgc3VwZXIoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBNYWlsSGFuZGxlckV4dChQcm9wZXJ0aWVzIHByb3BzKSB7CisgICAgICAgICAgICBzdXBlcihwcm9wcyk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgTWFpbEhhbmRsZXJFeHQoaW50IGNhcGFjaXR5KSB7CisgICAgICAgICAgICBzdXBlcihjYXBhY2l0eSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgc3RhdGljIGNsYXNzIE1haWxIYW5kbGVyT3ZlcnJpZGUgZXh0ZW5kcyBNYWlsSGFuZGxlciB7CisKKyAgICAgICAgcHVibGljIE1haWxIYW5kbGVyT3ZlcnJpZGUoKSB7CisgICAgICAgICAgICBzdXBlcigpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE1haWxIYW5kbGVyT3ZlcnJpZGUoUHJvcGVydGllcyBwcm9wcykgeworICAgICAgICAgICAgc3VwZXIocHJvcHMpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIE1haWxIYW5kbGVyT3ZlcnJpZGUoaW50IGNhcGFjaXR5KSB7CisgICAgICAgICAgICBzdXBlcihjYXBhY2l0eSk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaXNMb2dnYWJsZShMb2dSZWNvcmQgcmVjb3JkKSB7CisgICAgICAgICAgICBpbnQgbGV2ZWxWYWx1ZSA9IGdldExldmVsKCkuaW50VmFsdWUoKTsKKyAgICAgICAgICAgIGlmIChyZWNvcmQuZ2V0TGV2ZWwoKS5pbnRWYWx1ZSgpIDwgbGV2ZWxWYWx1ZQorICAgICAgICAgICAgICAgICAgICB8fCBsZXZlbFZhbHVlID09IExldmVsLk9GRi5pbnRWYWx1ZSgpKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBGaWx0ZXIgYm9keSA9IGdldEZpbHRlcigpOworICAgICAgICAgICAgaWYgKGJvZHkgPT0gbnVsbCB8fCBib2R5LmlzTG9nZ2FibGUocmVjb3JkKSkgeworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBmaW5hbCBGaWx0ZXJbXSBmaWx0ZXJzID0gdGhpcy5nZXRBdHRhY2htZW50RmlsdGVycygpOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWx0ZXJzLmxlbmd0aDsgKytpKSB7CisgICAgICAgICAgICAgICAgZmluYWwgRmlsdGVyIGYgPSBmaWx0ZXJzW2ldOworICAgICAgICAgICAgICAgIGlmIChmID09IG51bGwgfHwgZi5pc0xvZ2dhYmxlKHJlY29yZCkpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgY2xhc3MgQ2xhc3NMb2FkZXJTZWN1cml0eU1hbmFnZXIgZXh0ZW5kcyBTZWN1cml0eU1hbmFnZXIgeworCisgICAgICAgIHZvbGF0aWxlIGJvb2xlYW4gc2VjdXJlID0gZmFsc2U7CisgICAgICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBkZWJ1ZzsKKworICAgICAgICBwdWJsaWMgQ2xhc3NMb2FkZXJTZWN1cml0eU1hbmFnZXIoKSB7CisgICAgICAgICAgICBkZWJ1ZyA9IGlzU2VjdXJpdHlEZWJ1ZygpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGNoZWNrUGVybWlzc2lvbihqYXZhLnNlY3VyaXR5LlBlcm1pc3Npb24gcGVybSkgeworICAgICAgICAgICAgdHJ5IHsgLy9DYWxsIHN1cGVyIGNsYXNzIGFsd2F5cyBmb3IgamF2YS5zZWN1cml0eS5kZWJ1ZyB0cmFjaW5nLgorICAgICAgICAgICAgICAgIHN1cGVyLmNoZWNrUGVybWlzc2lvbihwZXJtKTsKKyAgICAgICAgICAgICAgICBjaGVja1Blcm1pc3Npb24ocGVybSwgbmV3IFNlY3VyaXR5RXhjZXB0aW9uKHBlcm0udG9TdHJpbmcoKSkpOworICAgICAgICAgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gc2UpIHsKKyAgICAgICAgICAgICAgICBjaGVja1Blcm1pc3Npb24ocGVybSwgc2UpOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGNoZWNrUGVybWlzc2lvbihqYXZhLnNlY3VyaXR5LlBlcm1pc3Npb24gcGVybSwgT2JqZWN0IGNvbnRleHQpIHsKKyAgICAgICAgICAgIHRyeSB7IC8vQ2FsbCBzdXBlciBjbGFzcyBhbHdheXMgZm9yIGphdmEuc2VjdXJpdHkuZGVidWcgdHJhY2luZy4KKyAgICAgICAgICAgICAgICBzdXBlci5jaGVja1Blcm1pc3Npb24ocGVybSwgY29udGV4dCk7CisgICAgICAgICAgICAgICAgY2hlY2tQZXJtaXNzaW9uKHBlcm0sIG5ldyBTZWN1cml0eUV4Y2VwdGlvbihwZXJtLnRvU3RyaW5nKCkpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHNlKSB7CisgICAgICAgICAgICAgICAgY2hlY2tQZXJtaXNzaW9uKHBlcm0sIHNlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBjaGVja1JlYWQoU3RyaW5nIGZpbGUsIE9iamVjdCBjb250ZXh0KSB7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgY2hlY2tSZWFkKFN0cmluZyBmaWxlKSB7CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIHZvaWQgY2hlY2tQZXJtaXNzaW9uKGphdmEuc2VjdXJpdHkuUGVybWlzc2lvbiBwZXJtLCBTZWN1cml0eUV4Y2VwdGlvbiBzZSkgeworICAgICAgICAgICAgLy9DaGVjayBmb3Igc2V0IGFuZCBnZXQgY29udGV4dCBjbGFzcyBsb2FkZXIuCisgICAgICAgICAgICBTdHJpbmcgbmFtZSA9IHBlcm0uZ2V0TmFtZSgpOworICAgICAgICAgICAgaWYgKHNlY3VyZSAmJiBuYW1lLmNvbnRhaW5zKCJDb250ZXh0Q2xhc3NMb2FkZXIiKSkgeworICAgICAgICAgICAgICAgIHRocm93IHNlOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBpZiAoZGVidWcpIHsKKyAgICAgICAgICAgICAgICAgICAgc2VjdXJpdHlEZWJ1Z1ByaW50KHNlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgZmluYWwgc3RhdGljIGNsYXNzIENsYXNzTG9hZGVyRXJyb3JNYW5hZ2VyIGV4dGVuZHMgSW50ZXJuYWxFcnJvck1hbmFnZXIgeworCisgICAgICAgIHByaXZhdGUgZmluYWwgQ2xhc3NMb2FkZXIgZXhwZWN0OworCisgICAgICAgIHB1YmxpYyBDbGFzc0xvYWRlckVycm9yTWFuYWdlcigpIHsKKyAgICAgICAgICAgIHRoaXMoTE9BREVSLmdldCgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBDbGFzc0xvYWRlckVycm9yTWFuYWdlcihmaW5hbCBDbGFzc0xvYWRlciBleHBlY3QpIHsKKyAgICAgICAgICAgIHRoaXMuZXhwZWN0ID0gZXhwZWN0OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyB2b2lkIGVycm9yKFN0cmluZyBtc2csIEV4Y2VwdGlvbiBleCwgaW50IGNvZGUpIHsKKyAgICAgICAgICAgIGNoZWNrQ29udGV4dENsYXNzTG9hZGVyKGV4cGVjdCk7CisgICAgICAgICAgICBzdXBlci5lcnJvcihtc2csIGV4LCBjb2RlKTsKKyAgICAgICAgfQorCisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJFcXVhbHNXaGljaERvZXNudENoZWNrUGFyYW1ldGVyQ2xhc3MiKQorICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvKSB7CisgICAgICAgICAgICBjaGVja0NvbnRleHRDbGFzc0xvYWRlcihleHBlY3QpOworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvKTsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgICAgICAgY2hlY2tDb250ZXh0Q2xhc3NMb2FkZXIoZXhwZWN0KTsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5oYXNoQ29kZSgpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICAgICAgICBjaGVja0NvbnRleHRDbGFzc0xvYWRlcihleHBlY3QpOworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnRvU3RyaW5nKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIENsYXNzTG9hZGVyQXV0aGVudGljYXRvcgorICAgICAgICAgICAgZXh0ZW5kcyBqYXZheC5tYWlsLkF1dGhlbnRpY2F0b3IgeworCisgICAgICAgIHByaXZhdGUgZmluYWwgQ2xhc3NMb2FkZXIgZXhwZWN0OworCisgICAgICAgIHB1YmxpYyBDbGFzc0xvYWRlckF1dGhlbnRpY2F0b3IoKSB7CisgICAgICAgICAgICB0aGlzKExPQURFUi5nZXQoKSk7CisgICAgICAgIH0KKworICAgICAgICBDbGFzc0xvYWRlckF1dGhlbnRpY2F0b3IoQ2xhc3NMb2FkZXIgbG9hZGVyKSB7CisgICAgICAgICAgICB0aGlzLmV4cGVjdCA9IGxvYWRlcjsKKyAgICAgICAgfQorCisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJvdmVycmlkZSIpCisgICAgICAgIHByb3RlY3RlZCBQYXNzd29yZEF1dGhlbnRpY2F0aW9uIGdldFBhc3N3b3JkQXV0aGVudGljYXRpb24oKSB7CisgICAgICAgICAgICBjaGVja0NvbnRleHRDbGFzc0xvYWRlcihleHBlY3QpOworICAgICAgICAgICAgZm9yIChTdGFja1RyYWNlRWxlbWVudCBzZSA6IG5ldyBUaHJvd2FibGUoKS5nZXRTdGFja1RyYWNlKCkpIHsKKyAgICAgICAgICAgICAgICBpZiAoImphdmF4Lm1haWwuVHJhbnNwb3J0Ii5lcXVhbHMoc2UuZ2V0Q2xhc3NOYW1lKCkpCisgICAgICAgICAgICAgICAgICAgICAgICAmJiAic2VuZCIuZXF1YWxzKHNlLmdldE1ldGhvZE5hbWUoKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJOb3QgY2FsbGluZyBUcmFuc3BvcnQuc2VuZCIpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIHN0YXRpYyBjbGFzcyBDbGFzc0xvYWRlckNvbXBhcmF0b3IKKyAgICAgICAgICAgIGltcGxlbWVudHMgQ29tcGFyYXRvcjxMb2dSZWNvcmQ+LCBTZXJpYWxpemFibGUgeworCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0xTDsKKworICAgICAgICBwcml2YXRlIGZpbmFsIENsYXNzTG9hZGVyIGV4cGVjdDsKKworICAgICAgICBwdWJsaWMgQ2xhc3NMb2FkZXJDb21wYXJhdG9yKCkgeworICAgICAgICAgICAgdGhpcyhMT0FERVIuZ2V0KCkpOworICAgICAgICB9CisKKyAgICAgICAgQ2xhc3NMb2FkZXJDb21wYXJhdG9yKGZpbmFsIENsYXNzTG9hZGVyIGV4cGVjdCkgeworICAgICAgICAgICAgdGhpcy5leHBlY3QgPSBleHBlY3Q7CisgICAgICAgIH0KKworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygib3ZlcnJpZGUiKSAvL0pESy02OTU0MjM0CisgICAgICAgIHB1YmxpYyBpbnQgY29tcGFyZShMb2dSZWNvcmQgbzEsIExvZ1JlY29yZCBvMikgeworICAgICAgICAgICAgY2hlY2tDb250ZXh0Q2xhc3NMb2FkZXIoZXhwZWN0KTsKKyAgICAgICAgICAgIHJldHVybiBuZXcgU2VxdWVuY2VDb21wYXJhdG9yKCkuY29tcGFyZShvMSwgbzIpOworICAgICAgICB9CisKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJFcXVhbHNXaGljaERvZXNudENoZWNrUGFyYW1ldGVyQ2xhc3MiLCAib3ZlcnJpZGUifSkKKyAgICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvKSB7CisgICAgICAgICAgICBjaGVja0NvbnRleHRDbGFzc0xvYWRlcihleHBlY3QpOworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvKTsKKyAgICAgICAgfQorCisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJvdmVycmlkZSIpCisgICAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgICAgICBjaGVja0NvbnRleHRDbGFzc0xvYWRlcihleHBlY3QpOworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmhhc2hDb2RlKCk7CisgICAgICAgIH0KKworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygib3ZlcnJpZGUiKQorICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgICAgICAgY2hlY2tDb250ZXh0Q2xhc3NMb2FkZXIoZXhwZWN0KTsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci50b1N0cmluZygpOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGZpbmFsIHN0YXRpYyBjbGFzcyBDbGFzc0xvYWRlckZpbHRlckZvcm1hdHRlcgorICAgICAgICAgICAgZXh0ZW5kcyBGb3JtYXR0ZXIgaW1wbGVtZW50cyBGaWx0ZXIgeworCisgICAgICAgIHByaXZhdGUgZmluYWwgQ2xhc3NMb2FkZXIgZXhwZWN0OworICAgICAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBmb3JtYXQ7CisKKyAgICAgICAgcHVibGljIENsYXNzTG9hZGVyRmlsdGVyRm9ybWF0dGVyKCkgeworICAgICAgICAgICAgdGhpcyhMT0FERVIuZ2V0KCkpOworICAgICAgICB9CisKKyAgICAgICAgQ2xhc3NMb2FkZXJGaWx0ZXJGb3JtYXR0ZXIoZmluYWwgQ2xhc3NMb2FkZXIgZXhwZWN0KSB7CisgICAgICAgICAgICB0aGlzLmV4cGVjdCA9IGV4cGVjdDsKKyAgICAgICAgICAgIHRoaXMuZm9ybWF0ID0gIiI7CisgICAgICAgIH0KKworICAgICAgICBDbGFzc0xvYWRlckZpbHRlckZvcm1hdHRlcihmaW5hbCBDbGFzc0xvYWRlciBleHBlY3QsIFN0cmluZyBmb3JtYXQpIHsKKyAgICAgICAgICAgIHRoaXMuZXhwZWN0ID0gZXhwZWN0OworICAgICAgICAgICAgdGhpcy5mb3JtYXQgPSBmb3JtYXQ7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFN0cmluZyBnZXRIZWFkKEhhbmRsZXIgaCkgeworICAgICAgICAgICAgY2hlY2tDb250ZXh0Q2xhc3NMb2FkZXIoZXhwZWN0KTsKKyAgICAgICAgICAgIHJldHVybiAiIjsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFRhaWwoSGFuZGxlciBoKSB7CisgICAgICAgICAgICBjaGVja0NvbnRleHRDbGFzc0xvYWRlcihleHBlY3QpOworICAgICAgICAgICAgcmV0dXJuICIiOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZm9ybWF0KGZpbmFsIExvZ1JlY29yZCBscikgeworICAgICAgICAgICAgY2hlY2tDb250ZXh0Q2xhc3NMb2FkZXIoZXhwZWN0KTsKKyAgICAgICAgICAgIHJldHVybiBmb3JtYXQ7CisgICAgICAgIH0KKworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygib3ZlcnJpZGUiKSAvL0pESy02OTU0MjM0CisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzTG9nZ2FibGUoTG9nUmVjb3JkIHJlY29yZCkgeworICAgICAgICAgICAgY2hlY2tDb250ZXh0Q2xhc3NMb2FkZXIoZXhwZWN0KTsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoIkVxdWFsc1doaWNoRG9lc250Q2hlY2tQYXJhbWV0ZXJDbGFzcyIpCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG8pIHsKKyAgICAgICAgICAgIGNoZWNrQ29udGV4dENsYXNzTG9hZGVyKGV4cGVjdCk7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG8pOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgICAgICBjaGVja0NvbnRleHRDbGFzc0xvYWRlcihleHBlY3QpOworICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmhhc2hDb2RlKCk7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgICAgIGNoZWNrQ29udGV4dENsYXNzTG9hZGVyKGV4cGVjdCk7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIudG9TdHJpbmcoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgZmluYWwgc3RhdGljIGNsYXNzIENsb3NlTG9nUmVjb3JkIGV4dGVuZHMgTG9nUmVjb3JkIHsKKworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTDsKKyAgICAgICAgcHJpdmF0ZSB0cmFuc2llbnQgdm9sYXRpbGUgSGFuZGxlciB0YXJnZXQ7CisKKyAgICAgICAgQ2xvc2VMb2dSZWNvcmQoTGV2ZWwgbGV2ZWwsIFN0cmluZyBtc2csIGZpbmFsIEhhbmRsZXIgdGFyZ2V0KSB7CisgICAgICAgICAgICBzdXBlcihsZXZlbCwgbXNnKTsKKyAgICAgICAgICAgIHRoaXMudGFyZ2V0ID0gdGFyZ2V0OworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0U291cmNlTWV0aG9kTmFtZSgpIHsKKyAgICAgICAgICAgIGNsb3NlKCk7CisgICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0U291cmNlTWV0aG9kTmFtZSgpOworICAgICAgICB9CisKKyAgICAgICAgQE92ZXJyaWRlCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0U291cmNlQ2xhc3NOYW1lKCkgeworICAgICAgICAgICAgY2xvc2UoKTsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5nZXRTb3VyY2VDbGFzc05hbWUoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGlzQ2xvc2VkKCkgeworICAgICAgICAgICAgcmV0dXJuIHRoaXMudGFyZ2V0ID09IG51bGw7CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIHZvaWQgY2xvc2UoKSB7CisgICAgICAgICAgICBmaW5hbCBIYW5kbGVyIGggPSB0aGlzLnRhcmdldDsKKyAgICAgICAgICAgIGlmIChoICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBoLmNsb3NlKCk7CisgICAgICAgICAgICAgICAgdGhpcy50YXJnZXQgPSBudWxsOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgcHJpdmF0ZSB2b2lkIHJlYWRPYmplY3QoT2JqZWN0SW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiwgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgICAgICAgICBpbi5kZWZhdWx0UmVhZE9iamVjdCgpOworICAgICAgICAgICAgdGhpcy50YXJnZXQgPSBudWxsOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL2xvZ2dpbmcvU2V2ZXJpdHlDb21wYXJhdG9yVGVzdC5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC91dGlsL2xvZ2dpbmcvU2V2ZXJpdHlDb21wYXJhdG9yVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI5MTE5ODYKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL3V0aWwvbG9nZ2luZy9TZXZlcml0eUNvbXBhcmF0b3JUZXN0LmphdmEKQEAgLTAsMCArMSwxMzczIEBACisvKg0KKyAqIENvcHlyaWdodCAoYykgMjAxMywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KKyAqIENvcHlyaWdodCAoYykgMjAxMywgMjAxOCBKYXNvbiBNZWhyZW5zLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KKyAqDQorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlDQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQNCisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuDQorICoNCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5DQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQ0KKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLA0KKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0DQorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLg0KKyAqDQorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wDQorICovDQorcGFja2FnZSBjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nOw0KKw0KK2ltcG9ydCBqYXZhLmlvLio7DQoraW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lkludm9jYXRpb25UYXJnZXRFeGNlcHRpb247DQoraW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LlVuZGVjbGFyZWRUaHJvd2FibGVFeGNlcHRpb247DQoraW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLkNsb3NlZEJ5SW50ZXJydXB0RXhjZXB0aW9uOw0KK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5GaWxlTG9ja0ludGVycnVwdGlvbkV4Y2VwdGlvbjsNCitpbXBvcnQgamF2YS51dGlsLio7DQoraW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dGlvbkV4Y2VwdGlvbjsNCitpbXBvcnQgamF2YS51dGlsLmxvZ2dpbmcuTGV2ZWw7DQoraW1wb3J0IGphdmEudXRpbC5sb2dnaW5nLkxvZ1JlY29yZDsNCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuKjsNCitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7DQorDQorLyoqDQorICoNCisgKiBAYXV0aG9yIEphc29uIE1laHJlbnMNCisgKiBAc2luY2UgSmF2YU1haWwgMS41LjINCisgKi8NCitwdWJsaWMgY2xhc3MgU2V2ZXJpdHlDb21wYXJhdG9yVGVzdCBleHRlbmRzIEFic3RyYWN0TG9nZ2luZyB7DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3REZWNsYXJlZENsYXNzZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsNCisgICAgICAgIENsYXNzPD8+W10gZGVjbGFyZWQgPSBTZXZlcml0eUNvbXBhcmF0b3IuY2xhc3MuZ2V0RGVjbGFyZWRDbGFzc2VzKCk7DQorICAgICAgICBhc3NlcnRFcXVhbHMoQXJyYXlzLnRvU3RyaW5nKGRlY2xhcmVkKSwgMCwgZGVjbGFyZWQubGVuZ3RoKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0QXBwbHlOdWxsKCkgew0KKyAgICAgICAgU2V2ZXJpdHlDb21wYXJhdG9yIGEgPSBuZXcgU2V2ZXJpdHlDb21wYXJhdG9yKCk7DQorICAgICAgICBhc3NlcnROdWxsKGEuYXBwbHkobnVsbCkpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RBcHBseUVycm9yQnlOb3JtYWwoKSB7DQorICAgICAgICBTZXZlcml0eUNvbXBhcmF0b3IgYSA9IG5ldyBTZXZlcml0eUNvbXBhcmF0b3IoKTsNCisgICAgICAgIFRocm93YWJsZSBuZXh0ID0gdGhpcy5oZWFkSWVDaGFpbihuZXcgQXNzZXJ0aW9uRXJyb3IoKSk7DQorICAgICAgICBuZXh0ID0gbmV3IEVycm9yKG5leHQpOw0KKyAgICAgICAgbmV4dCA9IG5ldyBOb0NsYXNzRGVmRm91bmRFcnJvcigpLmluaXRDYXVzZShuZXh0KTsNCisgICAgICAgIFRocm93YWJsZSByZWR1Y2VkID0gYS5hcHBseShuZXh0KTsNCisgICAgICAgIGFzc2VydEVxdWFscyhFcnJvci5jbGFzcywgcmVkdWNlZC5nZXRDbGFzcygpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdCh0aW1lb3V0ID0gMzAwMDApDQorICAgIHB1YmxpYyB2b2lkIHRlc3RBcHBseUV2aWwoKSB7DQorICAgICAgICBTZXZlcml0eUNvbXBhcmF0b3IgYSA9IG5ldyBTZXZlcml0eUNvbXBhcmF0b3IoKTsNCisgICAgICAgIGZpbmFsIGludCBsZW4gPSA3Ow0KKyAgICAgICAgZmluYWwgQ2xhc3M8PyBleHRlbmRzIFRocm93YWJsZT4gdHlwZSA9IEV4Y2VwdGlvbi5jbGFzczsNCisgICAgICAgIFRocm93YWJsZSBsID0gYS5hcHBseShjcmVhdGVFdmlsVGhyb3dhYmxlKHR5cGUsIGxlbikpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKHR5cGUsIGwuZ2V0Q2xhc3MoKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEFwcGx5UHJveHlOb3JtYWwoKSB7DQorICAgICAgICAvL1VURS0+SUUtPkFFID0gSUUNCisgICAgICAgIFNldmVyaXR5Q29tcGFyYXRvciBhID0gbmV3IFNldmVyaXR5Q29tcGFyYXRvcigpOw0KKyAgICAgICAgVGhyb3dhYmxlIG5leHQgPSB0aGlzLmhlYWRJZUNoYWluKG5ldyBBc3NlcnRpb25FcnJvcigpKTsNCisgICAgICAgIG5leHQgPSBuZXcgVW5kZWNsYXJlZFRocm93YWJsZUV4Y2VwdGlvbihuZXh0KTsNCisgICAgICAgIFRocm93YWJsZSByZWR1Y2VkID0gYS5hcHBseShuZXh0KTsNCisgICAgICAgIGFzc2VydEVxdWFscyhJbnRlcnJ1cHRlZEV4Y2VwdGlvbi5jbGFzcywgcmVkdWNlZC5nZXRDbGFzcygpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0QXBwbHlSZWZsZWN0Tm9ybWFsKCkgew0KKyAgICAgICAgLy9JVEUtPklFLT5BRSA9IElFDQorICAgICAgICBTZXZlcml0eUNvbXBhcmF0b3IgYSA9IG5ldyBTZXZlcml0eUNvbXBhcmF0b3IoKTsNCisgICAgICAgIFRocm93YWJsZSBuZXh0ID0gdGhpcy5oZWFkSWVDaGFpbihuZXcgQXNzZXJ0aW9uRXJyb3IoKSk7DQorICAgICAgICBuZXh0ID0gbmV3IEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24obmV4dCk7DQorICAgICAgICBUaHJvd2FibGUgcmVkdWNlZCA9IGEuYXBwbHkobmV4dCk7DQorICAgICAgICBhc3NlcnRFcXVhbHMoSW50ZXJydXB0ZWRFeGNlcHRpb24uY2xhc3MsIHJlZHVjZWQuZ2V0Q2xhc3MoKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEFwcGx5Tm9ybWFsQnlOb3JtYWwoKSB7DQorICAgICAgICAvL0VFLT5JSU9FLT5FLT5JRS0+QUUgPSBJRQ0KKyAgICAgICAgU2V2ZXJpdHlDb21wYXJhdG9yIGEgPSBuZXcgU2V2ZXJpdHlDb21wYXJhdG9yKCk7DQorICAgICAgICBUaHJvd2FibGUgbmV4dCA9IHRoaXMuaGVhZEllQ2hhaW4obmV3IEFzc2VydGlvbkVycm9yKCkpOw0KKyAgICAgICAgbmV4dCA9IG5ldyBFcnJvcihuZXh0KTsNCisgICAgICAgIG5leHQgPSB0aGlzLmhlYWRJaW9lQ2hhaW4obmV4dCk7DQorICAgICAgICBuZXh0ID0gbmV3IEV4ZWN1dGlvbkV4Y2VwdGlvbihuZXh0KTsNCisgICAgICAgIFRocm93YWJsZSByZWR1Y2VkID0gYS5hcHBseShuZXh0KTsNCisgICAgICAgIGFzc2VydEVxdWFscyhJbnRlcnJ1cHRlZEV4Y2VwdGlvbi5jbGFzcywgcmVkdWNlZC5nZXRDbGFzcygpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0QXBwbHlGaW5kc1Jvb3RDYXVzZSgpIHsNCisgICAgICAgIC8qKg0KKyAgICAgICAgICogTG90cyBvZiBmcmFtZXdvcmtzIHdyYXAgZXhjZXB0aW9ucyB3aXRoIHJ1bnRpbWUgZXhjZXB0aW9ucy4gVGhlIHJvb3QNCisgICAgICAgICAqIGNhdXNlIGlzIGFsd2F5cyBtb3JlIGltcG9ydGFudC4NCisgICAgICAgICAqLw0KKyAgICAgICAgU2V2ZXJpdHlDb21wYXJhdG9yIGEgPSBuZXcgU2V2ZXJpdHlDb21wYXJhdG9yKCk7DQorICAgICAgICBmaW5hbCBUaHJvd2FibGUgcm9vdCA9IG5ldyBFeGNlcHRpb24oKTsNCisgICAgICAgIFRocm93YWJsZSBuZXh0ID0gcm9vdDsNCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgNzsgaSsrKSB7DQorICAgICAgICAgICAgbmV4dCA9IG5ldyBSdW50aW1lRXhjZXB0aW9uKG5leHQpOw0KKyAgICAgICAgfQ0KKyAgICAgICAgVGhyb3dhYmxlIHJlZHVjZWQgPSBhLmFwcGx5KG5leHQpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKHJvb3QsIHJlZHVjZWQpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RDb21wYXJlVGhyb3duRG9lc05vdEFwcGx5KCkgew0KKyAgICAgICAgU2V2ZXJpdHlDb21wYXJhdG9yIGEgPSBuZXcgU2V2ZXJpdHlDb21wYXJhdG9yKCk7DQorICAgICAgICBUaHJvd2FibGUgdGMxID0gbmV3IEVycm9yKG5ldyBFeGNlcHRpb24oKSk7DQorICAgICAgICBUaHJvd2FibGUgdGMyID0gbmV3IEV4Y2VwdGlvbihuZXcgRXhjZXB0aW9uKCkpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShhLmNvbXBhcmVUaHJvd2FibGUodGMxLCB0YzIpID4gMCk7DQorICAgICAgICBhc3NlcnRUcnVlKGEuY29tcGFyZVRocm93YWJsZSh0YzIsIHRjMSkgPCAwKTsNCisNCisgICAgICAgIHRjMSA9IG5ldyBSdW50aW1lRXhjZXB0aW9uKHRjMSk7DQorICAgICAgICBhc3NlcnRUcnVlKGEuY29tcGFyZVRocm93YWJsZSh0YzEsIHRjMikgPiAwKTsNCisgICAgICAgIGFzc2VydFRydWUoYS5jb21wYXJlVGhyb3dhYmxlKHRjMiwgdGMxKSA8IDApOw0KKw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RDb21wYXJlVGhyb3duTnVsbCgpIHsNCisgICAgICAgIFNldmVyaXR5Q29tcGFyYXRvciBhID0gbmV3IFNldmVyaXR5Q29tcGFyYXRvcigpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGEuY29tcGFyZVRocm93YWJsZSgoVGhyb3dhYmxlKSBudWxsLCAoVGhyb3dhYmxlKSBudWxsKSk7DQorICAgICAgICBhc3NlcnRUcnVlKGEuY29tcGFyZVRocm93YWJsZShuZXcgVGhyb3dhYmxlKCksIChUaHJvd2FibGUpIG51bGwpID4gMCk7DQorICAgICAgICBhc3NlcnRUcnVlKGEuY29tcGFyZVRocm93YWJsZSgoVGhyb3dhYmxlKSBudWxsLCBuZXcgVGhyb3dhYmxlKCkpIDwgMCk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEFwcGx5VGhlbkNvbXBhcmVOdWxsKCkgew0KKyAgICAgICAgU2V2ZXJpdHlDb21wYXJhdG9yIGEgPSBuZXcgU2V2ZXJpdHlDb21wYXJhdG9yKCk7DQorICAgICAgICBhc3NlcnRFcXVhbHMoMCwgYS5hcHBseVRoZW5Db21wYXJlKChUaHJvd2FibGUpIG51bGwsIChUaHJvd2FibGUpIG51bGwpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdCh0aW1lb3V0ID0gMzAwMDApDQorICAgIHB1YmxpYyB2b2lkIHRlc3RBcHBseVRoZW5Db21wYXJlVGhyb3duRXZpbEVycm9yKCkgew0KKyAgICAgICAgdGVzdEFwcGx5VGhlbkNvbXBhcmVUaHJvd25FdmlsKEVycm9yLmNsYXNzKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdCh0aW1lb3V0ID0gMzAwMDApDQorICAgIHB1YmxpYyB2b2lkIHRlc3RBcHBseVRoZW5Db21wYXJlVGhyb3duRXZpbFJ1bnRpbWVFeGNlcHRpb24oKSB7DQorICAgICAgICB0ZXN0QXBwbHlUaGVuQ29tcGFyZVRocm93bkV2aWwoUnVudGltZUV4Y2VwdGlvbi5jbGFzcyk7DQorICAgIH0NCisNCisgICAgQFRlc3QodGltZW91dCA9IDMwMDAwKQ0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0QXBwbHlUaGVuQ29tcGFyZVRocm93bkV2aWxFeGNlcHRpb24oKSB7DQorICAgICAgICB0ZXN0QXBwbHlUaGVuQ29tcGFyZVRocm93bkV2aWwoRXhjZXB0aW9uLmNsYXNzKTsNCisgICAgfQ0KKw0KKyAgICBwcml2YXRlIHZvaWQgdGVzdEFwcGx5VGhlbkNvbXBhcmVUaHJvd25FdmlsKENsYXNzPD8gZXh0ZW5kcyBUaHJvd2FibGU+IHQpIHsNCisgICAgICAgIFNldmVyaXR5Q29tcGFyYXRvciBhID0gbmV3IFNldmVyaXR5Q29tcGFyYXRvcigpOw0KKyAgICAgICAgZmluYWwgaW50IGxlbiA9IDc7DQorICAgICAgICBUaHJvd2FibGUgbCA9IGNyZWF0ZUV2aWxUaHJvd2FibGUodCwgbGVuKTsNCisgICAgICAgIFRocm93YWJsZSByID0gY3JlYXRlRXZpbFRocm93YWJsZSh0LCBsZW4pOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIGEuYXBwbHlUaGVuQ29tcGFyZShsLCByKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QodGltZW91dCA9IDMwMDAwKQ0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29tcGFyZVRocm93bkV2aWxFcnJvcigpIHsNCisgICAgICAgIHRlc3RDb21wYXJlVGhyb3duRXZpbChFcnJvci5jbGFzcyk7DQorICAgIH0NCisNCisgICAgQFRlc3QodGltZW91dCA9IDMwMDAwKQ0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29tcGFyZVRocm93bkV2aWxSdW50aW1lRXhjZXB0aW9uKCkgew0KKyAgICAgICAgdGVzdENvbXBhcmVUaHJvd25FdmlsKFJ1bnRpbWVFeGNlcHRpb24uY2xhc3MpOw0KKyAgICB9DQorDQorICAgIEBUZXN0KHRpbWVvdXQgPSAzMDAwMCkNCisgICAgcHVibGljIHZvaWQgdGVzdENvbXBhcmVUaHJvd25FdmlsRXhjZXB0aW9uKCkgew0KKyAgICAgICAgdGVzdENvbXBhcmVUaHJvd25FdmlsKEV4Y2VwdGlvbi5jbGFzcyk7DQorICAgIH0NCisNCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RDb21wYXJlVGhyb3duRXZpbChDbGFzczw/IGV4dGVuZHMgVGhyb3dhYmxlPiB0KSB7DQorICAgICAgICBTZXZlcml0eUNvbXBhcmF0b3IgYSA9IG5ldyBTZXZlcml0eUNvbXBhcmF0b3IoKTsNCisgICAgICAgIGZpbmFsIGludCBsZW4gPSA3Ow0KKyAgICAgICAgVGhyb3dhYmxlIGwgPSBjcmVhdGVFdmlsVGhyb3dhYmxlKHQsIGxlbik7DQorICAgICAgICBUaHJvd2FibGUgciA9IGNyZWF0ZUV2aWxUaHJvd2FibGUodCwgbGVuKTsNCisgICAgICAgIGFzc2VydEVxdWFscygwLCBhLmNvbXBhcmVUaHJvd2FibGUobCwgcikpOw0KKyAgICB9DQorDQorICAgIHByaXZhdGUgVGhyb3dhYmxlIGNyZWF0ZUV2aWxUaHJvd2FibGUoQ2xhc3M8PyBleHRlbmRzIFRocm93YWJsZT4gdCwgaW50IGxlbikgew0KKyAgICAgICAgVGhyb3dhYmxlIHRhaWwgPSBjcmVhdGUodCwgbnVsbCk7DQorICAgICAgICBUaHJvd2FibGUgaGVhZCA9IHRhaWw7DQorICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8IGxlbjsgaSsrKSB7DQorICAgICAgICAgICAgaGVhZCA9IGNyZWF0ZSh0LCBoZWFkKTsNCisgICAgICAgIH0NCisgICAgICAgIHRhaWwuaW5pdENhdXNlKGhlYWQpOyAvL1B1cmUgZXZpbC4NCisgICAgICAgIHJldHVybiBoZWFkOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRJbnN0YW5jZSgpIHsNCisgICAgICAgIFNldmVyaXR5Q29tcGFyYXRvciBhID0gbmV3IFNldmVyaXR5Q29tcGFyYXRvcigpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKGEsIFNldmVyaXR5Q29tcGFyYXRvci5nZXRJbnN0YW5jZSgpKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhhLmdldENsYXNzKCksIFNldmVyaXR5Q29tcGFyYXRvci5nZXRJbnN0YW5jZSgpLmdldENsYXNzKCkpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKGEuaGFzaENvZGUoKSwgU2V2ZXJpdHlDb21wYXJhdG9yLmdldEluc3RhbmNlKCkuaGFzaENvZGUoKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdElzTm9ybWFsRXJyb3IoKSB7DQorICAgICAgICB0ZXN0SXNOb3ROb3JtYWwoRXJyb3IuY2xhc3MsIGhlYWRJZUNoYWluKG51bGwpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SXNOb3JtYWxSdW50aW1lRXhjZXB0aW9uKCkgew0KKyAgICAgICAgdGVzdElzTm90Tm9ybWFsKFJ1bnRpbWVFeGNlcHRpb24uY2xhc3MsIGhlYWRJZUNoYWluKG51bGwpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SXNOb3JtYWxFeGNlcHRpb24oKSB7DQorICAgICAgICB0ZXN0SXNOb3ROb3JtYWwoRXhjZXB0aW9uLmNsYXNzLCBoZWFkSWVDaGFpbihudWxsKSk7DQorICAgIH0NCisNCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RJc05vdE5vcm1hbChDbGFzczw/IGV4dGVuZHMgVGhyb3dhYmxlPiB0LCBUaHJvd2FibGUgcm9vdCkgew0KKyAgICAgICAgU2V2ZXJpdHlDb21wYXJhdG9yIGEgPSBuZXcgU2V2ZXJpdHlDb21wYXJhdG9yKCk7DQorICAgICAgICBhc3NlcnRGYWxzZShhLmlzTm9ybWFsKGNyZWF0ZSh0LCBudWxsKSkpOw0KKw0KKyAgICAgICAgVGhyb3dhYmxlIG5leHQgPSByb290Ow0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA1OyBpKyspIHsNCisgICAgICAgICAgICBuZXh0ID0gY3JlYXRlKHQsIG5leHQpOw0KKyAgICAgICAgICAgIGFzc2VydEZhbHNlKGEuaXNOb3JtYWwobmV4dCkpOw0KKyAgICAgICAgfQ0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RJc05vcm1hbCgpIHsNCisgICAgICAgIFNldmVyaXR5Q29tcGFyYXRvciBhID0gbmV3IFNldmVyaXR5Q29tcGFyYXRvcigpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShhLmlzTm9ybWFsKHRoaXMuaGVhZEllQ2hhaW4obnVsbCkpKTsNCisgICAgICAgIGFzc2VydFRydWUoYS5pc05vcm1hbCh0aGlzLmhlYWRJaW9lQ2hhaW4obnVsbCkpKTsNCisgICAgICAgIGFzc2VydFRydWUoYS5pc05vcm1hbCh0aGlzLmhlYWRDYmllQ2hhaW4obnVsbCkpKTsNCisgICAgICAgIGFzc2VydFRydWUoYS5pc05vcm1hbCh0aGlzLmhlYWRGbGllQ2hhaW4obnVsbCkpKTsNCisgICAgICAgIGFzc2VydFRydWUoYS5pc05vcm1hbCh0aGlzLmhlYWRTdWJJZUNoYWluKG51bGwpKSk7DQorICAgICAgICBhc3NlcnRUcnVlKGEuaXNOb3JtYWwodGhpcy5oZWFkU3ViSWlvZUNoYWluKG51bGwpKSk7DQorICAgICAgICBhc3NlcnRUcnVlKGEuaXNOb3JtYWwodGhpcy5oZWFkU3ViVGRDaGFpbihudWxsKSkpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShhLmlzTm9ybWFsKHRoaXMuaGVhZFN1YlRkQ2hhaW4obnVsbCkpKTsNCisgICAgICAgIGFzc2VydFRydWUoYS5pc05vcm1hbCh0aGlzLmhlYWRXaWRDaGFpbihudWxsKSkpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShhLmlzTm9ybWFsKHRoaXMuaGVhZFdpdENoYWluKG51bGwpKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdElzTm9ybWFsRXZpbCgpIHsNCisgICAgICAgIFNldmVyaXR5Q29tcGFyYXRvciBhID0gbmV3IFNldmVyaXR5Q29tcGFyYXRvcigpOw0KKyAgICAgICAgYXNzZXJ0RmFsc2UoYS5pc05vcm1hbChjcmVhdGVFdmlsVGhyb3dhYmxlKEV4Y2VwdGlvbi5jbGFzcywgNykpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SXNOb3JtYWxEb2VzTm90VXNlQXBwbHkoKSB7DQorICAgICAgICBTZXZlcml0eUNvbXBhcmF0b3IgYSA9IG5ldyBTZXZlcml0eUNvbXBhcmF0b3IoKTsNCisgICAgICAgIFRocm93YWJsZSBuZXh0ID0gdGhpcy5oZWFkSWVDaGFpbihuZXcgQXNzZXJ0aW9uRXJyb3IoKSk7DQorICAgICAgICBuZXh0ID0gbmV3IEVycm9yKG5leHQpOw0KKyAgICAgICAgbmV4dCA9IHRoaXMuaGVhZElpb2VDaGFpbihuZXh0KTsNCisgICAgICAgIG5leHQgPSBuZXcgRXhlY3V0aW9uRXhjZXB0aW9uKG5leHQpOw0KKyAgICAgICAgYXNzZXJ0RmFsc2UoYS5pc05vcm1hbChuZXh0KSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdElzTm9ybWFsTnVsbCgpIHsNCisgICAgICAgIFNldmVyaXR5Q29tcGFyYXRvciBhID0gbmV3IFNldmVyaXR5Q29tcGFyYXRvcigpOw0KKyAgICAgICAgYXNzZXJ0RmFsc2UoYS5pc05vcm1hbCgoVGhyb3dhYmxlKSBudWxsKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QoZXhwZWN0ZWQgPSBOdWxsUG9pbnRlckV4Y2VwdGlvbi5jbGFzcykNCisgICAgcHVibGljIHZvaWQgdGVzdENvbXBhcmVOdWxsQW5kTnVsbCgpIHsNCisgICAgICAgIFNldmVyaXR5Q29tcGFyYXRvciBhID0gbmV3IFNldmVyaXR5Q29tcGFyYXRvcigpOw0KKyAgICAgICAgYS5jb21wYXJlKChMb2dSZWNvcmQpIG51bGwsIChMb2dSZWNvcmQpIG51bGwpOw0KKyAgICB9DQorDQorICAgIEBUZXN0KGV4cGVjdGVkID0gTnVsbFBvaW50ZXJFeGNlcHRpb24uY2xhc3MpDQorICAgIHB1YmxpYyB2b2lkIHRlc3RDb21wYXJlTm90TnVsbEFuZE51bGwoKSB7DQorICAgICAgICBTZXZlcml0eUNvbXBhcmF0b3IgYSA9IG5ldyBTZXZlcml0eUNvbXBhcmF0b3IoKTsNCisgICAgICAgIExvZ1JlY29yZCByMSA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuSU5GTywgTGV2ZWwuSU5GTy50b1N0cmluZygpKTsNCisgICAgICAgIGEuY29tcGFyZShyMSwgKExvZ1JlY29yZCkgbnVsbCk7DQorICAgIH0NCisNCisgICAgQFRlc3QoZXhwZWN0ZWQgPSBOdWxsUG9pbnRlckV4Y2VwdGlvbi5jbGFzcykNCisgICAgcHVibGljIHZvaWQgdGVzdENvbXBhcmVOdWxsQW5kTm90TnVsbCgpIHsNCisgICAgICAgIFNldmVyaXR5Q29tcGFyYXRvciBhID0gbmV3IFNldmVyaXR5Q29tcGFyYXRvcigpOw0KKyAgICAgICAgTG9nUmVjb3JkIHIxID0gbmV3IExvZ1JlY29yZChMZXZlbC5JTkZPLCBMZXZlbC5JTkZPLnRvU3RyaW5nKCkpOw0KKyAgICAgICAgYS5jb21wYXJlKChMb2dSZWNvcmQpIG51bGwsIHIxKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0TGVhZGluZ0Vycm9yQW5kSW50ZXJydXB0ZWQoKSB7DQorICAgICAgICBMb2dSZWNvcmQgcjEgPSBuZXcgTG9nUmVjb3JkKExldmVsLklORk8sIExldmVsLklORk8udG9TdHJpbmcoKSk7DQorICAgICAgICBMb2dSZWNvcmQgcjIgPSBuZXcgTG9nUmVjb3JkKExldmVsLklORk8sIExldmVsLklORk8udG9TdHJpbmcoKSk7DQorICAgICAgICBzd2FwU2VxKHIxLCByMik7DQorICAgICAgICBhc3NlcnRFcXVhbHMocjEuZ2V0TGV2ZWwoKSwgcjIuZ2V0TGV2ZWwoKSk7DQorICAgICAgICBhc3NlcnRUcnVlKHIxLmdldFNlcXVlbmNlTnVtYmVyKCkgPiByMi5nZXRTZXF1ZW5jZU51bWJlcigpKTsNCisNCisgICAgICAgIHIxLnNldFRocm93bihoZWFkSWVDaGFpbihuZXcgRXJyb3IoKSkpOw0KKyAgICAgICAgcjIuc2V0VGhyb3duKG5ldyBFcnJvcihoZWFkSWVDaGFpbihudWxsKSkpOw0KKyAgICAgICAgYXNzZXJ0UmVjb3JkTGVzc1RoYW4ocjEsIHIyKTsNCisNCisgICAgICAgIHIxLnNldFRocm93bihoZWFkSWVDaGFpbihuZXcgUnVudGltZUV4Y2VwdGlvbigpKSk7DQorICAgICAgICByMi5zZXRUaHJvd24obmV3IEVycm9yKGhlYWRJZUNoYWluKG51bGwpKSk7DQorICAgICAgICBhc3NlcnRSZWNvcmRMZXNzVGhhbihyMSwgcjIpOw0KKw0KKyAgICAgICAgcjEuc2V0VGhyb3duKGhlYWRJZUNoYWluKG5ldyBFeGNlcHRpb24oKSkpOw0KKyAgICAgICAgcjIuc2V0VGhyb3duKG5ldyBFcnJvcihoZWFkSWVDaGFpbihudWxsKSkpOw0KKyAgICAgICAgYXNzZXJ0UmVjb3JkTGVzc1RoYW4ocjEsIHIyKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0QnlMZXZlbCgpIHsNCisgICAgICAgIExvZ1JlY29yZCByMSA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuSU5GTywgTGV2ZWwuSU5GTy50b1N0cmluZygpKTsNCisgICAgICAgIExvZ1JlY29yZCByMiA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuV0FSTklORywgTGV2ZWwuV0FSTklORy50b1N0cmluZygpKTsNCisgICAgICAgIGFzc2VydFRydWUocjEuZ2V0U2VxdWVuY2VOdW1iZXIoKSA8IHIyLmdldFNlcXVlbmNlTnVtYmVyKCkpOw0KKw0KKyAgICAgICAgLy9MZXZlbCB0ZXN0IHdpdGggbnVsbCB0aHJvd24uDQorICAgICAgICBhc3NlcnRSZWNvcmRMZXNzVGhhbihyMSwgcjIpOw0KKw0KKyAgICAgICAgLy9FbnN1cmUgRXJyb3IgZG9lc24ndCBjaGFuZ2UgcHJpbWFyeSBvcmRlci4NCisgICAgICAgIHIxLnNldFRocm93bihuZXcgRXJyb3IoKSk7DQorICAgICAgICByMi5zZXRUaHJvd24obnVsbCk7DQorICAgICAgICBhc3NlcnRSZWNvcmRMZXNzVGhhbihyMSwgcjIpOw0KKw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKEVycm9yLmNsYXNzLCByMS5nZXRUaHJvd24oKS5nZXRDbGFzcygpKTsNCisgICAgICAgIHIyLnNldFRocm93bihuZXcgRXJyb3IoKSk7DQorICAgICAgICBhc3NlcnRSZWNvcmRMZXNzVGhhbihyMSwgcjIpOw0KKw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKEVycm9yLmNsYXNzLCByMS5nZXRUaHJvd24oKS5nZXRDbGFzcygpKTsNCisgICAgICAgIHIyLnNldFRocm93bihuZXcgUnVudGltZUV4Y2VwdGlvbigpKTsNCisgICAgICAgIGFzc2VydFJlY29yZExlc3NUaGFuKHIxLCByMik7DQorDQorICAgICAgICBhc3NlcnRFcXVhbHMoRXJyb3IuY2xhc3MsIHIxLmdldFRocm93bigpLmdldENsYXNzKCkpOw0KKyAgICAgICAgcjIuc2V0VGhyb3duKG5ldyBFeGNlcHRpb24oKSk7DQorICAgICAgICBhc3NlcnRSZWNvcmRMZXNzVGhhbihyMSwgcjIpOw0KKw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKEVycm9yLmNsYXNzLCByMS5nZXRUaHJvd24oKS5nZXRDbGFzcygpKTsNCisgICAgICAgIHIyLnNldFRocm93bihuZXcgSW50ZXJydXB0ZWRFeGNlcHRpb24oKSk7DQorICAgICAgICBhc3NlcnRSZWNvcmRMZXNzVGhhbihyMSwgcjIpOw0KKw0KKyAgICAgICAgLy9FbnN1cmUgUnVudGltZUV4Y2VwdGlvbiBkb2Vzbid0IGNoYW5nZSBwcmltYXJ5IG9yZGVyLg0KKyAgICAgICAgcjEuc2V0VGhyb3duKG5ldyBSdW50aW1lRXhjZXB0aW9uKCkpOw0KKyAgICAgICAgcjIuc2V0VGhyb3duKG51bGwpOw0KKyAgICAgICAgYXNzZXJ0UmVjb3JkTGVzc1RoYW4ocjEsIHIyKTsNCisNCisgICAgICAgIGFzc2VydEVxdWFscyhSdW50aW1lRXhjZXB0aW9uLmNsYXNzLCByMS5nZXRUaHJvd24oKS5nZXRDbGFzcygpKTsNCisgICAgICAgIHIyLnNldFRocm93bihuZXcgRXJyb3IoKSk7DQorICAgICAgICBhc3NlcnRSZWNvcmRMZXNzVGhhbihyMSwgcjIpOw0KKw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKFJ1bnRpbWVFeGNlcHRpb24uY2xhc3MsIHIxLmdldFRocm93bigpLmdldENsYXNzKCkpOw0KKyAgICAgICAgcjIuc2V0VGhyb3duKG5ldyBSdW50aW1lRXhjZXB0aW9uKCkpOw0KKyAgICAgICAgYXNzZXJ0UmVjb3JkTGVzc1RoYW4ocjEsIHIyKTsNCisNCisgICAgICAgIGFzc2VydEVxdWFscyhSdW50aW1lRXhjZXB0aW9uLmNsYXNzLCByMS5nZXRUaHJvd24oKS5nZXRDbGFzcygpKTsNCisgICAgICAgIHIyLnNldFRocm93bihuZXcgRXhjZXB0aW9uKCkpOw0KKyAgICAgICAgYXNzZXJ0UmVjb3JkTGVzc1RoYW4ocjEsIHIyKTsNCisNCisgICAgICAgIGFzc2VydEVxdWFscyhSdW50aW1lRXhjZXB0aW9uLmNsYXNzLCByMS5nZXRUaHJvd24oKS5nZXRDbGFzcygpKTsNCisgICAgICAgIHIyLnNldFRocm93bihuZXcgSW50ZXJydXB0ZWRFeGNlcHRpb24oKSk7DQorICAgICAgICBhc3NlcnRSZWNvcmRMZXNzVGhhbihyMSwgcjIpOw0KKw0KKyAgICAgICAgLy9FbnN1cmUgRXhjZXB0aW9uIGRvZXNuJ3QgY2hhbmdlIHByaW1hcnkgb3JkZXIuDQorICAgICAgICByMS5zZXRUaHJvd24obmV3IEV4Y2VwdGlvbigpKTsNCisgICAgICAgIHIyLnNldFRocm93bihudWxsKTsNCisgICAgICAgIGFzc2VydFJlY29yZExlc3NUaGFuKHIxLCByMik7DQorDQorICAgICAgICBhc3NlcnRFcXVhbHMoRXhjZXB0aW9uLmNsYXNzLCByMS5nZXRUaHJvd24oKS5nZXRDbGFzcygpKTsNCisgICAgICAgIHIyLnNldFRocm93bihuZXcgRXJyb3IoKSk7DQorICAgICAgICBhc3NlcnRSZWNvcmRMZXNzVGhhbihyMSwgcjIpOw0KKw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKEV4Y2VwdGlvbi5jbGFzcywgcjEuZ2V0VGhyb3duKCkuZ2V0Q2xhc3MoKSk7DQorICAgICAgICByMi5zZXRUaHJvd24obmV3IFJ1bnRpbWVFeGNlcHRpb24oKSk7DQorICAgICAgICBhc3NlcnRSZWNvcmRMZXNzVGhhbihyMSwgcjIpOw0KKw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKEV4Y2VwdGlvbi5jbGFzcywgcjEuZ2V0VGhyb3duKCkuZ2V0Q2xhc3MoKSk7DQorICAgICAgICByMi5zZXRUaHJvd24obmV3IEV4Y2VwdGlvbigpKTsNCisgICAgICAgIGFzc2VydFJlY29yZExlc3NUaGFuKHIxLCByMik7DQorDQorICAgICAgICBhc3NlcnRFcXVhbHMoRXhjZXB0aW9uLmNsYXNzLCByMS5nZXRUaHJvd24oKS5nZXRDbGFzcygpKTsNCisgICAgICAgIHIyLnNldFRocm93bihuZXcgSW50ZXJydXB0ZWRFeGNlcHRpb24oKSk7DQorICAgICAgICBhc3NlcnRSZWNvcmRMZXNzVGhhbihyMSwgcjIpOw0KKw0KKyAgICAgICAgLy9FbnN1cmUgdGhyb3duIGFuZCBzZXF1ZW5jZSBkb2Vzbid0IGNoYW5nZSBwcmltYXJ5IG9yZGVyLg0KKyAgICAgICAgc3dhcFNlcShyMSwgcjIpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyMS5nZXRTZXF1ZW5jZU51bWJlcigpID4gcjIuZ2V0U2VxdWVuY2VOdW1iZXIoKSk7DQorICAgICAgICBhc3NlcnRSZWNvcmRMZXNzVGhhbihyMSwgcjIpOw0KKw0KKyAgICAgICAgcjEuc2V0VGhyb3duKG51bGwpOw0KKyAgICAgICAgcjIuc2V0VGhyb3duKG51bGwpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyMS5nZXRTZXF1ZW5jZU51bWJlcigpID4gcjIuZ2V0U2VxdWVuY2VOdW1iZXIoKSk7DQorICAgICAgICBhc3NlcnRSZWNvcmRMZXNzVGhhbihyMSwgcjIpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RCeU51bGxBbmRGcmFtZXdvcmtJbnRlcnJ1cHRlZCgpIHsNCisgICAgICAgIExvZ1JlY29yZCByMSA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuSU5GTywgTGV2ZWwuSU5GTy50b1N0cmluZygpKTsNCisgICAgICAgIExvZ1JlY29yZCByMiA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuSU5GTywgTGV2ZWwuSU5GTy50b1N0cmluZygpKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhyMS5nZXRMZXZlbCgpLCByMi5nZXRMZXZlbCgpKTsNCisNCisgICAgICAgIC8vRW5zdXJlIEludGVycnVwdGVkIGlzIGxlc3MgdGhhbiBudWxsLg0KKyAgICAgICAgcjEuc2V0VGhyb3duKHRoaXMuaGVhZFdpZENoYWluKG51bGwpKTsNCisgICAgICAgIGFzc2VydE51bGwocjIuZ2V0VGhyb3duKCkpOw0KKyAgICAgICAgYXNzZXJ0UmVjb3JkTGVzc1RoYW4ocjEsIHIyKTsNCisNCisgICAgICAgIHIxLnNldFRocm93bih0aGlzLmhlYWRXaWRDaGFpbihuZXcgRXJyb3IoKSkpOw0KKyAgICAgICAgYXNzZXJ0TnVsbChyMi5nZXRUaHJvd24oKSk7DQorICAgICAgICBhc3NlcnRSZWNvcmRMZXNzVGhhbihyMSwgcjIpOw0KKw0KKyAgICAgICAgcjEuc2V0VGhyb3duKHRoaXMuaGVhZFdpZENoYWluKG5ldyBSdW50aW1lRXhjZXB0aW9uKCkpKTsNCisgICAgICAgIGFzc2VydE51bGwocjIuZ2V0VGhyb3duKCkpOw0KKyAgICAgICAgYXNzZXJ0UmVjb3JkTGVzc1RoYW4ocjEsIHIyKTsNCisNCisgICAgICAgIHIxLnNldFRocm93bih0aGlzLmhlYWRXaWRDaGFpbihuZXcgRXhjZXB0aW9uKCkpKTsNCisgICAgICAgIGFzc2VydE51bGwocjIuZ2V0VGhyb3duKCkpOw0KKyAgICAgICAgYXNzZXJ0UmVjb3JkTGVzc1RoYW4ocjEsIHIyKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0QnlOdWxsQW5kSW50ZXJydXB0ZWQoKSB7DQorICAgICAgICBMb2dSZWNvcmQgcjEgPSBuZXcgTG9nUmVjb3JkKExldmVsLklORk8sIExldmVsLklORk8udG9TdHJpbmcoKSk7DQorICAgICAgICBMb2dSZWNvcmQgcjIgPSBuZXcgTG9nUmVjb3JkKExldmVsLklORk8sIExldmVsLklORk8udG9TdHJpbmcoKSk7DQorICAgICAgICBhc3NlcnRFcXVhbHMocjEuZ2V0TGV2ZWwoKSwgcjIuZ2V0TGV2ZWwoKSk7DQorDQorICAgICAgICAvL0Vuc3VyZSBJbnRlcnJ1cHRlZCBpcyBsZXNzIHRoYW4gbnVsbC4NCisgICAgICAgIHIxLnNldFRocm93bihoZWFkSWVDaGFpbihudWxsKSk7DQorICAgICAgICBhc3NlcnROdWxsKHIyLmdldFRocm93bigpKTsNCisgICAgICAgIGFzc2VydFJlY29yZExlc3NUaGFuKHIxLCByMik7DQorDQorICAgICAgICByMS5zZXRUaHJvd24oaGVhZEllQ2hhaW4obmV3IEVycm9yKCkpKTsNCisgICAgICAgIGFzc2VydE51bGwocjIuZ2V0VGhyb3duKCkpOw0KKyAgICAgICAgYXNzZXJ0UmVjb3JkTGVzc1RoYW4ocjEsIHIyKTsNCisNCisgICAgICAgIHIxLnNldFRocm93bihoZWFkSWVDaGFpbihuZXcgUnVudGltZUV4Y2VwdGlvbigpKSk7DQorICAgICAgICBhc3NlcnROdWxsKHIyLmdldFRocm93bigpKTsNCisgICAgICAgIGFzc2VydFJlY29yZExlc3NUaGFuKHIxLCByMik7DQorDQorICAgICAgICByMS5zZXRUaHJvd24oaGVhZEllQ2hhaW4obmV3IEV4Y2VwdGlvbigpKSk7DQorICAgICAgICBhc3NlcnROdWxsKHIyLmdldFRocm93bigpKTsNCisgICAgICAgIGFzc2VydFJlY29yZExlc3NUaGFuKHIxLCByMik7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEJ5TnVsbEFuZEludGVycnVwdGVkU3ViKCkgew0KKyAgICAgICAgTG9nUmVjb3JkIHIxID0gbmV3IExvZ1JlY29yZChMZXZlbC5JTkZPLCBMZXZlbC5JTkZPLnRvU3RyaW5nKCkpOw0KKyAgICAgICAgTG9nUmVjb3JkIHIyID0gbmV3IExvZ1JlY29yZChMZXZlbC5JTkZPLCBMZXZlbC5JTkZPLnRvU3RyaW5nKCkpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKHIxLmdldExldmVsKCksIHIyLmdldExldmVsKCkpOw0KKyAgICAgICAgLy9FbnN1cmUgc3ViY2xhc3Mgb2YgSUUgaXMgbGVzcyB0aGFuIG51bGwuDQorICAgICAgICByMS5zZXRUaHJvd24oaGVhZFN1YkllQ2hhaW4obnVsbCkpOw0KKyAgICAgICAgYXNzZXJ0TnVsbChyMi5nZXRUaHJvd24oKSk7DQorICAgICAgICBhc3NlcnRSZWNvcmRMZXNzVGhhbihyMSwgcjIpOw0KKw0KKyAgICAgICAgcjEuc2V0VGhyb3duKGhlYWRTdWJJZUNoYWluKG5ldyBFcnJvcigpKSk7DQorICAgICAgICBhc3NlcnROdWxsKHIyLmdldFRocm93bigpKTsNCisgICAgICAgIGFzc2VydFJlY29yZExlc3NUaGFuKHIxLCByMik7DQorDQorICAgICAgICByMS5zZXRUaHJvd24oaGVhZFN1YkllQ2hhaW4obmV3IFJ1bnRpbWVFeGNlcHRpb24oKSkpOw0KKyAgICAgICAgYXNzZXJ0TnVsbChyMi5nZXRUaHJvd24oKSk7DQorICAgICAgICBhc3NlcnRSZWNvcmRMZXNzVGhhbihyMSwgcjIpOw0KKw0KKyAgICAgICAgcjEuc2V0VGhyb3duKGhlYWRTdWJJZUNoYWluKG5ldyBFeGNlcHRpb24oKSkpOw0KKyAgICAgICAgYXNzZXJ0TnVsbChyMi5nZXRUaHJvd24oKSk7DQorICAgICAgICBhc3NlcnRSZWNvcmRMZXNzVGhhbihyMSwgcjIpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RCeU51bGxBbmRJbnRlcnJ1cHRlZElvKCkgew0KKyAgICAgICAgTG9nUmVjb3JkIHIxID0gbmV3IExvZ1JlY29yZChMZXZlbC5JTkZPLCBMZXZlbC5JTkZPLnRvU3RyaW5nKCkpOw0KKyAgICAgICAgTG9nUmVjb3JkIHIyID0gbmV3IExvZ1JlY29yZChMZXZlbC5JTkZPLCBMZXZlbC5JTkZPLnRvU3RyaW5nKCkpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKHIxLmdldExldmVsKCksIHIyLmdldExldmVsKCkpOw0KKw0KKyAgICAgICAgLy9Fc3VyZSBzdWJjbGFzcyBvZiBJT0UgaXMgbGVzcyB0aGFuIG51bGwuDQorICAgICAgICByMS5zZXRUaHJvd24oaGVhZElpb2VDaGFpbihudWxsKSk7DQorICAgICAgICBhc3NlcnROdWxsKHIyLmdldFRocm93bigpKTsNCisgICAgICAgIGFzc2VydFJlY29yZExlc3NUaGFuKHIxLCByMik7DQorDQorICAgICAgICByMS5zZXRUaHJvd24oaGVhZElpb2VDaGFpbihuZXcgRXJyb3IoKSkpOw0KKyAgICAgICAgYXNzZXJ0TnVsbChyMi5nZXRUaHJvd24oKSk7DQorICAgICAgICBhc3NlcnRSZWNvcmRMZXNzVGhhbihyMSwgcjIpOw0KKw0KKyAgICAgICAgcjEuc2V0VGhyb3duKGhlYWRJaW9lQ2hhaW4obmV3IFJ1bnRpbWVFeGNlcHRpb24oKSkpOw0KKyAgICAgICAgYXNzZXJ0TnVsbChyMi5nZXRUaHJvd24oKSk7DQorICAgICAgICBhc3NlcnRSZWNvcmRMZXNzVGhhbihyMSwgcjIpOw0KKw0KKyAgICAgICAgcjEuc2V0VGhyb3duKGhlYWRJaW9lQ2hhaW4obmV3IEV4Y2VwdGlvbigpKSk7DQorICAgICAgICBhc3NlcnROdWxsKHIyLmdldFRocm93bigpKTsNCisgICAgICAgIGFzc2VydFJlY29yZExlc3NUaGFuKHIxLCByMik7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEJ5TnVsbEFuZEludGVycnVwdGVkSW9TdWIoKSB7DQorICAgICAgICBMb2dSZWNvcmQgcjEgPSBuZXcgTG9nUmVjb3JkKExldmVsLklORk8sIExldmVsLklORk8udG9TdHJpbmcoKSk7DQorICAgICAgICBMb2dSZWNvcmQgcjIgPSBuZXcgTG9nUmVjb3JkKExldmVsLklORk8sIExldmVsLklORk8udG9TdHJpbmcoKSk7DQorICAgICAgICBhc3NlcnRFcXVhbHMocjEuZ2V0TGV2ZWwoKSwgcjIuZ2V0TGV2ZWwoKSk7DQorDQorICAgICAgICAvL0VzdXJlIHN1YmNsYXNzIG9mIElPRSBpcyBsZXNzIHRoYW4gbnVsbC4NCisgICAgICAgIHIxLnNldFRocm93bihoZWFkU3ViSWlvZUNoYWluKG51bGwpKTsNCisgICAgICAgIGFzc2VydE51bGwocjIuZ2V0VGhyb3duKCkpOw0KKyAgICAgICAgYXNzZXJ0UmVjb3JkTGVzc1RoYW4ocjEsIHIyKTsNCisNCisgICAgICAgIHIxLnNldFRocm93bihoZWFkU3ViSWlvZUNoYWluKG5ldyBFcnJvcigpKSk7DQorICAgICAgICBhc3NlcnROdWxsKHIyLmdldFRocm93bigpKTsNCisgICAgICAgIGFzc2VydFJlY29yZExlc3NUaGFuKHIxLCByMik7DQorDQorICAgICAgICByMS5zZXRUaHJvd24oaGVhZFN1Yklpb2VDaGFpbihuZXcgUnVudGltZUV4Y2VwdGlvbigpKSk7DQorICAgICAgICBhc3NlcnROdWxsKHIyLmdldFRocm93bigpKTsNCisgICAgICAgIGFzc2VydFJlY29yZExlc3NUaGFuKHIxLCByMik7DQorDQorICAgICAgICByMS5zZXRUaHJvd24oaGVhZFN1Yklpb2VDaGFpbihuZXcgRXhjZXB0aW9uKCkpKTsNCisgICAgICAgIGFzc2VydE51bGwocjIuZ2V0VGhyb3duKCkpOw0KKyAgICAgICAgYXNzZXJ0UmVjb3JkTGVzc1RoYW4ocjEsIHIyKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0QnlOdWxsQW5kVGhyZWFkRGVhdGgoKSB7DQorICAgICAgICBMb2dSZWNvcmQgcjEgPSBuZXcgTG9nUmVjb3JkKExldmVsLklORk8sIExldmVsLklORk8udG9TdHJpbmcoKSk7DQorICAgICAgICBMb2dSZWNvcmQgcjIgPSBuZXcgTG9nUmVjb3JkKExldmVsLklORk8sIExldmVsLklORk8udG9TdHJpbmcoKSk7DQorICAgICAgICBhc3NlcnRFcXVhbHMocjEuZ2V0TGV2ZWwoKSwgcjIuZ2V0TGV2ZWwoKSk7DQorDQorICAgICAgICAvL0Vuc3VyZSBUaHJlYWREZWF0aCBpcyBsZXNzIHRoYW4gbnVsbC4NCisgICAgICAgIHIxLnNldFRocm93bihoZWFkVGRDaGFpbihudWxsKSk7DQorICAgICAgICBhc3NlcnROdWxsKHIyLmdldFRocm93bigpKTsNCisgICAgICAgIGFzc2VydFJlY29yZExlc3NUaGFuKHIxLCByMik7DQorDQorICAgICAgICByMS5zZXRUaHJvd24oaGVhZFRkQ2hhaW4obmV3IEVycm9yKCkpKTsNCisgICAgICAgIGFzc2VydE51bGwocjIuZ2V0VGhyb3duKCkpOw0KKyAgICAgICAgYXNzZXJ0UmVjb3JkTGVzc1RoYW4ocjEsIHIyKTsNCisNCisgICAgICAgIHIxLnNldFRocm93bihoZWFkVGRDaGFpbihuZXcgUnVudGltZUV4Y2VwdGlvbigpKSk7DQorICAgICAgICBhc3NlcnROdWxsKHIyLmdldFRocm93bigpKTsNCisgICAgICAgIGFzc2VydFJlY29yZExlc3NUaGFuKHIxLCByMik7DQorDQorICAgICAgICByMS5zZXRUaHJvd24oaGVhZFRkQ2hhaW4obmV3IEV4Y2VwdGlvbigpKSk7DQorICAgICAgICBhc3NlcnROdWxsKHIyLmdldFRocm93bigpKTsNCisgICAgICAgIGFzc2VydFJlY29yZExlc3NUaGFuKHIxLCByMik7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEJ5TnVsbEFuZFRocmVhZERlYXRoU3ViKCkgew0KKyAgICAgICAgTG9nUmVjb3JkIHIxID0gbmV3IExvZ1JlY29yZChMZXZlbC5JTkZPLCBMZXZlbC5JTkZPLnRvU3RyaW5nKCkpOw0KKyAgICAgICAgTG9nUmVjb3JkIHIyID0gbmV3IExvZ1JlY29yZChMZXZlbC5JTkZPLCBMZXZlbC5JTkZPLnRvU3RyaW5nKCkpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKHIxLmdldExldmVsKCksIHIyLmdldExldmVsKCkpOw0KKw0KKyAgICAgICAgLy9FbnN1cmUgc3ViY2xhc3MgVGhyZWFkRGVhdGggaXMgbGVzcyB0aGFuIG51bGwuDQorICAgICAgICByMS5zZXRUaHJvd24oaGVhZFN1YlRkQ2hhaW4obnVsbCkpOw0KKyAgICAgICAgYXNzZXJ0TnVsbChyMi5nZXRUaHJvd24oKSk7DQorICAgICAgICBhc3NlcnRSZWNvcmRMZXNzVGhhbihyMSwgcjIpOw0KKw0KKyAgICAgICAgcjEuc2V0VGhyb3duKGhlYWRTdWJUZENoYWluKG5ldyBFcnJvcigpKSk7DQorICAgICAgICBhc3NlcnROdWxsKHIyLmdldFRocm93bigpKTsNCisgICAgICAgIGFzc2VydFJlY29yZExlc3NUaGFuKHIxLCByMik7DQorDQorICAgICAgICByMS5zZXRUaHJvd24oaGVhZFN1YlRkQ2hhaW4obmV3IFJ1bnRpbWVFeGNlcHRpb24oKSkpOw0KKyAgICAgICAgYXNzZXJ0TnVsbChyMi5nZXRUaHJvd24oKSk7DQorICAgICAgICBhc3NlcnRSZWNvcmRMZXNzVGhhbihyMSwgcjIpOw0KKw0KKyAgICAgICAgcjEuc2V0VGhyb3duKGhlYWRTdWJUZENoYWluKG5ldyBFeGNlcHRpb24oKSkpOw0KKyAgICAgICAgYXNzZXJ0TnVsbChyMi5nZXRUaHJvd24oKSk7DQorICAgICAgICBhc3NlcnRSZWNvcmRMZXNzVGhhbihyMSwgcjIpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RCeU51bGxBbmRUaHJvd24oKSB7DQorICAgICAgICBMb2dSZWNvcmQgcjEgPSBuZXcgTG9nUmVjb3JkKExldmVsLklORk8sIExldmVsLklORk8udG9TdHJpbmcoKSk7DQorICAgICAgICBMb2dSZWNvcmQgcjIgPSBuZXcgTG9nUmVjb3JkKExldmVsLklORk8sIExldmVsLklORk8udG9TdHJpbmcoKSk7DQorICAgICAgICByMS5zZXRTZXF1ZW5jZU51bWJlcihyMi5nZXRTZXF1ZW5jZU51bWJlcigpKTsNCisgICAgICAgIHNldEVwb2NoTWlsbGkocjIsIFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpKTsgLy9UcnVuY2F0ZSBuYW5vcy4NCisgICAgICAgIHNldEVwb2NoTWlsbGkocjEsIHIyLmdldE1pbGxpcygpKTsNCisNCisgICAgICAgIGFzc2VydEVxdWFscyhyMS5nZXRMZXZlbCgpLCByMi5nZXRMZXZlbCgpKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhyMS5nZXRTZXF1ZW5jZU51bWJlcigpLCByMi5nZXRTZXF1ZW5jZU51bWJlcigpKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhyMS5nZXRNaWxsaXMoKSwgcjIuZ2V0TWlsbGlzKCkpOw0KKw0KKyAgICAgICAgLy9FbnN1cmUgbnVsbCBpcyBsZXNzIHRoYW4gRXJyb3IuDQorICAgICAgICBhc3NlcnROdWxsKHIxLmdldFRocm93bigpKTsNCisgICAgICAgIHIyLnNldFRocm93bihuZXcgRXJyb3IoKSk7DQorICAgICAgICBhc3NlcnRSZWNvcmRMZXNzVGhhbihyMSwgcjIpOw0KKw0KKyAgICAgICAgLy9FbnN1cmUgbnVsbCBpcyBsZXNzIHRoYW4gUnVudGltZUV4Y2VwdGlvbi4NCisgICAgICAgIGFzc2VydE51bGwocjEuZ2V0VGhyb3duKCkpOw0KKyAgICAgICAgcjIuc2V0VGhyb3duKG5ldyBSdW50aW1lRXhjZXB0aW9uKCkpOw0KKyAgICAgICAgYXNzZXJ0UmVjb3JkTGVzc1RoYW4ocjEsIHIyKTsNCisNCisgICAgICAgIC8vRW5zdXJlIG51bGwgaXMgbGVzcyB0aGFuIEV4Y2VwdGlvbi4NCisgICAgICAgIGFzc2VydE51bGwocjEuZ2V0VGhyb3duKCkpOw0KKyAgICAgICAgcjIuc2V0VGhyb3duKG5ldyBFeGNlcHRpb24oKSk7DQorICAgICAgICBhc3NlcnRSZWNvcmRMZXNzVGhhbihyMSwgcjIpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RCeU51bGxBbmROdWxsU2VxKCkgew0KKyAgICAgICAgTG9nUmVjb3JkIHIxID0gbmV3IExvZ1JlY29yZChMZXZlbC5JTkZPLCBMZXZlbC5JTkZPLnRvU3RyaW5nKCkpOw0KKyAgICAgICAgTG9nUmVjb3JkIHIyID0gbmV3IExvZ1JlY29yZChMZXZlbC5JTkZPLCBMZXZlbC5JTkZPLnRvU3RyaW5nKCkpOw0KKw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyMS5nZXRTZXF1ZW5jZU51bWJlcigpIDwgcjIuZ2V0U2VxdWVuY2VOdW1iZXIoKSk7DQorICAgICAgICBhc3NlcnROdWxsKHIxLmdldFRocm93bigpKTsNCisgICAgICAgIGFzc2VydE51bGwocjIuZ2V0VGhyb3duKCkpOw0KKyAgICAgICAgYXNzZXJ0UmVjb3JkTGVzc1RoYW4ocjEsIHIyKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0QnlUaHJvd25BbmRUaHJvd25TZXEoKSB7DQorICAgICAgICBMb2dSZWNvcmQgcjEgPSBuZXcgTG9nUmVjb3JkKExldmVsLklORk8sIExldmVsLklORk8udG9TdHJpbmcoKSk7DQorICAgICAgICBMb2dSZWNvcmQgcjIgPSBuZXcgTG9nUmVjb3JkKExldmVsLklORk8sIExldmVsLklORk8udG9TdHJpbmcoKSk7DQorDQorICAgICAgICBhc3NlcnRUcnVlKHIxLmdldFNlcXVlbmNlTnVtYmVyKCkgPCByMi5nZXRTZXF1ZW5jZU51bWJlcigpKTsNCisgICAgICAgIGFzc2VydFRydWUocjEuZ2V0U2VxdWVuY2VOdW1iZXIoKSA8IHIyLmdldFNlcXVlbmNlTnVtYmVyKCkpOw0KKyAgICAgICAgcjEuc2V0VGhyb3duKG5ldyBFcnJvcigpKTsNCisgICAgICAgIHIyLnNldFRocm93bihuZXcgRXJyb3IoKSk7DQorICAgICAgICBhc3NlcnRSZWNvcmRMZXNzVGhhbihyMSwgcjIpOw0KKw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyMS5nZXRTZXF1ZW5jZU51bWJlcigpIDwgcjIuZ2V0U2VxdWVuY2VOdW1iZXIoKSk7DQorICAgICAgICByMS5zZXRUaHJvd24obmV3IFJ1bnRpbWVFeGNlcHRpb24oKSk7DQorICAgICAgICByMi5zZXRUaHJvd24obmV3IFJ1bnRpbWVFeGNlcHRpb24oKSk7DQorICAgICAgICBhc3NlcnRSZWNvcmRMZXNzVGhhbihyMSwgcjIpOw0KKw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyMS5nZXRTZXF1ZW5jZU51bWJlcigpIDwgcjIuZ2V0U2VxdWVuY2VOdW1iZXIoKSk7DQorICAgICAgICByMS5zZXRUaHJvd24obmV3IEV4Y2VwdGlvbigpKTsNCisgICAgICAgIHIyLnNldFRocm93bihuZXcgRXhjZXB0aW9uKCkpOw0KKyAgICAgICAgYXNzZXJ0UmVjb3JkTGVzc1RoYW4ocjEsIHIyKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0QnlUaHJvd25MZW5TZXEoKSB7DQorICAgICAgICBmaW5hbCBpbnQgTUFYX1JVTlMgPSAxMDsNCisgICAgICAgIGZpbmFsIGludCBNQVhfTEVOID0gMjA7DQorDQorICAgICAgICBmb3IgKGludCByID0gTUFYX1JVTlM7IHIgPiAwOyByLS0pIHsNCisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IE1BWF9MRU47IGkrKykgew0KKyAgICAgICAgICAgICAgICB0ZXN0QnlUaHJvd25MZW5TZXEoRXJyb3IuY2xhc3MsIGksIHIpOw0KKyAgICAgICAgICAgIH0NCisNCisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IE1BWF9MRU47IGkrKykgew0KKyAgICAgICAgICAgICAgICB0ZXN0QnlUaHJvd25MZW5TZXEoUnVudGltZUV4Y2VwdGlvbi5jbGFzcywgaSwgcik7DQorICAgICAgICAgICAgfQ0KKw0KKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgTUFYX0xFTjsgaSsrKSB7DQorICAgICAgICAgICAgICAgIHRlc3RCeVRocm93bkxlblNlcShFeGNlcHRpb24uY2xhc3MsIGksIHIpOw0KKyAgICAgICAgICAgIH0NCisgICAgICAgIH0NCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0QnlOb3JtYWxMZW5TZXEoKSB7DQorICAgICAgICBmaW5hbCBpbnQgTUFYX1JVTlMgPSAxMDsNCisgICAgICAgIGZpbmFsIGludCBNQVhfTEVOID0gMjA7DQorDQorICAgICAgICBmb3IgKGludCByID0gTUFYX1JVTlM7IHIgPiAwOyByLS0pIHsNCisgICAgICAgICAgICAvL051bGwgaXMgaGlnaGVyIHRoYW4gbm9ybWFsIHNvIHdlIGhhdmUgdG8gc3RhcnQgYXQgb25lLg0KKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDw9IE1BWF9MRU47IGkrKykgew0KKyAgICAgICAgICAgICAgICB0ZXN0QnlUaHJvd25MZW5TZXEoSW50ZXJydXB0ZWRFeGNlcHRpb24uY2xhc3MsIGksIHIpOw0KKyAgICAgICAgICAgIH0NCisNCisgICAgICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8PSBNQVhfTEVOOyBpKyspIHsNCisgICAgICAgICAgICAgICAgdGVzdEJ5VGhyb3duTGVuU2VxKEludGVycnVwdGVkSU9FeGNlcHRpb24uY2xhc3MsIGksIHIpOw0KKyAgICAgICAgICAgIH0NCisNCisgICAgICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8PSBNQVhfTEVOOyBpKyspIHsNCisgICAgICAgICAgICAgICAgdGVzdEJ5VGhyb3duTGVuU2VxKFRocmVhZERlYXRoLmNsYXNzLCBpLCByKTsNCisgICAgICAgICAgICB9DQorICAgICAgICB9DQorICAgIH0NCisNCisgICAgcHJpdmF0ZSB2b2lkIHRlc3RCeVRocm93bkxlblNlcSgNCisgICAgICAgICAgICBDbGFzczw/IGV4dGVuZHMgVGhyb3dhYmxlPiB0LCBpbnQgYzEsIGludCBjMikgew0KKyAgICAgICAgTG9nUmVjb3JkIHIxID0gbmV3IExvZ1JlY29yZChMZXZlbC5JTkZPLCBMZXZlbC5JTkZPLnRvU3RyaW5nKCkpOw0KKyAgICAgICAgTG9nUmVjb3JkIHIyID0gbmV3IExvZ1JlY29yZChMZXZlbC5JTkZPLCBMZXZlbC5JTkZPLnRvU3RyaW5nKCkpOw0KKw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyMS5nZXRTZXF1ZW5jZU51bWJlcigpIDwgcjIuZ2V0U2VxdWVuY2VOdW1iZXIoKSk7DQorDQorICAgICAgICBzZXRUaHJvd24ocjEsIHQsIGMxKTsNCisgICAgICAgIHNldFRocm93bihyMiwgdCwgYzIpOw0KKyAgICAgICAgYXNzZXJ0UmVjb3JkTGVzc1RoYW4ocjEsIHIyKTsNCisgICAgfQ0KKw0KKyAgICBwcml2YXRlIFRocm93YWJsZSBjcmVhdGUoQ2xhc3M8PyBleHRlbmRzIFRocm93YWJsZT4gdHlwZSwgVGhyb3dhYmxlIGNhdXNlKSB7DQorICAgICAgICB0cnkgew0KKyAgICAgICAgICAgIGlmIChjYXVzZSA9PSBudWxsKSB7DQorICAgICAgICAgICAgICAgIHJldHVybiB0eXBlLmdldENvbnN0cnVjdG9yKCkubmV3SW5zdGFuY2UoKTsNCisgICAgICAgICAgICB9DQorDQorICAgICAgICAgICAgdHJ5IHsNCisgICAgICAgICAgICAgICAgcmV0dXJuIHR5cGUuZ2V0Q29uc3RydWN0b3IoVGhyb3dhYmxlLmNsYXNzKS5uZXdJbnN0YW5jZShjYXVzZSk7DQorICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoTWV0aG9kRXhjZXB0aW9uIHRyeUluaXRDYXVzZSkgew0KKyAgICAgICAgICAgICAgICBUaHJvd2FibGUgbmV4dCA9IHR5cGUuZ2V0Q29uc3RydWN0b3IoKS5uZXdJbnN0YW5jZSgpOw0KKyAgICAgICAgICAgICAgICByZXR1cm4gbmV4dC5pbml0Q2F1c2UoY2F1c2UpOw0KKyAgICAgICAgICAgIH0NCisgICAgICAgIH0gY2F0Y2ggKEluc3RhbnRpYXRpb25FeGNlcHRpb24gZXgpIHsNCisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZXgpOw0KKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBleCkgew0KKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihleCk7DQorICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXgpIHsNCisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZXgpOw0KKyAgICAgICAgfSBjYXRjaCAoSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiBleCkgew0KKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihleCk7DQorICAgICAgICB9IGNhdGNoIChOb1N1Y2hNZXRob2RFeGNlcHRpb24gZXgpIHsNCisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZXgpOw0KKyAgICAgICAgfQ0KKyAgICB9DQorDQorICAgIHByaXZhdGUgdm9pZCBzZXRUaHJvd24oTG9nUmVjb3JkIHIsIENsYXNzPD8gZXh0ZW5kcyBUaHJvd2FibGU+IHQsIGludCBkKSB7DQorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGQ7IGkrKykgew0KKyAgICAgICAgICAgIHIuc2V0VGhyb3duKGNyZWF0ZSh0LCByLmdldFRocm93bigpKSk7DQorICAgICAgICB9DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEJ5VGhyb3duQW5kSW50ZXJydXB0ZWQoKSB7DQorICAgICAgICBMb2dSZWNvcmQgcjEgPSBuZXcgTG9nUmVjb3JkKExldmVsLklORk8sIExldmVsLklORk8udG9TdHJpbmcoKSk7DQorICAgICAgICBMb2dSZWNvcmQgcjIgPSBuZXcgTG9nUmVjb3JkKExldmVsLklORk8sIExldmVsLklORk8udG9TdHJpbmcoKSk7DQorICAgICAgICBzd2FwU2VxKHIxLCByMik7DQorDQorICAgICAgICBhc3NlcnRUcnVlKHIxLmdldFNlcXVlbmNlTnVtYmVyKCkgPiByMi5nZXRTZXF1ZW5jZU51bWJlcigpKTsNCisgICAgICAgIHIxLnNldFRocm93bihoZWFkSWVDaGFpbihudWxsKSk7DQorICAgICAgICByMi5zZXRUaHJvd24obmV3IEVycm9yKCkpOw0KKyAgICAgICAgYXNzZXJ0UmVjb3JkTGVzc1RoYW4ocjEsIHIyKTsNCisNCisgICAgICAgIGFzc2VydFRydWUocjEuZ2V0U2VxdWVuY2VOdW1iZXIoKSA+IHIyLmdldFNlcXVlbmNlTnVtYmVyKCkpOw0KKyAgICAgICAgcjEuc2V0VGhyb3duKGhlYWRJZUNoYWluKG51bGwpKTsNCisgICAgICAgIHIyLnNldFRocm93bihuZXcgUnVudGltZUV4Y2VwdGlvbigpKTsNCisgICAgICAgIGFzc2VydFJlY29yZExlc3NUaGFuKHIxLCByMik7DQorDQorICAgICAgICBhc3NlcnRUcnVlKHIxLmdldFNlcXVlbmNlTnVtYmVyKCkgPiByMi5nZXRTZXF1ZW5jZU51bWJlcigpKTsNCisgICAgICAgIHIxLnNldFRocm93bihoZWFkSWVDaGFpbihudWxsKSk7DQorICAgICAgICByMi5zZXRUaHJvd24obmV3IEV4Y2VwdGlvbigpKTsNCisgICAgICAgIGFzc2VydFJlY29yZExlc3NUaGFuKHIxLCByMik7DQorDQorICAgICAgICBhc3NlcnRUcnVlKHIxLmdldFNlcXVlbmNlTnVtYmVyKCkgPiByMi5nZXRTZXF1ZW5jZU51bWJlcigpKTsNCisgICAgICAgIHIxLnNldFRocm93bihoZWFkSWVDaGFpbihuZXcgRXJyb3IoKSkpOw0KKyAgICAgICAgcjIuc2V0VGhyb3duKG5ldyBFcnJvcigpKTsNCisgICAgICAgIGFzc2VydFJlY29yZExlc3NUaGFuKHIxLCByMik7DQorDQorICAgICAgICBhc3NlcnRUcnVlKHIxLmdldFNlcXVlbmNlTnVtYmVyKCkgPiByMi5nZXRTZXF1ZW5jZU51bWJlcigpKTsNCisgICAgICAgIHIxLnNldFRocm93bihoZWFkSWVDaGFpbihuZXcgUnVudGltZUV4Y2VwdGlvbigpKSk7DQorICAgICAgICByMi5zZXRUaHJvd24obmV3IFJ1bnRpbWVFeGNlcHRpb24oKSk7DQorICAgICAgICBhc3NlcnRSZWNvcmRMZXNzVGhhbihyMSwgcjIpOw0KKw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyMS5nZXRTZXF1ZW5jZU51bWJlcigpID4gcjIuZ2V0U2VxdWVuY2VOdW1iZXIoKSk7DQorICAgICAgICByMS5zZXRUaHJvd24oaGVhZEllQ2hhaW4obmV3IEV4Y2VwdGlvbigpKSk7DQorICAgICAgICByMi5zZXRUaHJvd24obmV3IEV4Y2VwdGlvbigpKTsNCisgICAgICAgIGFzc2VydFJlY29yZExlc3NUaGFuKHIxLCByMik7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEJ5VGhyb3duQW5kSW50ZXJydXB0ZWRTdWIoKSB7DQorICAgICAgICBMb2dSZWNvcmQgcjEgPSBuZXcgTG9nUmVjb3JkKExldmVsLklORk8sIExldmVsLklORk8udG9TdHJpbmcoKSk7DQorICAgICAgICBMb2dSZWNvcmQgcjIgPSBuZXcgTG9nUmVjb3JkKExldmVsLklORk8sIExldmVsLklORk8udG9TdHJpbmcoKSk7DQorICAgICAgICBzd2FwU2VxKHIxLCByMik7DQorDQorICAgICAgICBhc3NlcnRUcnVlKHIxLmdldFNlcXVlbmNlTnVtYmVyKCkgPiByMi5nZXRTZXF1ZW5jZU51bWJlcigpKTsNCisgICAgICAgIHIxLnNldFRocm93bihoZWFkU3ViSWVDaGFpbihudWxsKSk7DQorICAgICAgICByMi5zZXRUaHJvd24obmV3IEVycm9yKCkpOw0KKyAgICAgICAgYXNzZXJ0UmVjb3JkTGVzc1RoYW4ocjEsIHIyKTsNCisNCisgICAgICAgIGFzc2VydFRydWUocjEuZ2V0U2VxdWVuY2VOdW1iZXIoKSA+IHIyLmdldFNlcXVlbmNlTnVtYmVyKCkpOw0KKyAgICAgICAgcjEuc2V0VGhyb3duKGhlYWRTdWJJZUNoYWluKG51bGwpKTsNCisgICAgICAgIHIyLnNldFRocm93bihuZXcgUnVudGltZUV4Y2VwdGlvbigpKTsNCisgICAgICAgIGFzc2VydFJlY29yZExlc3NUaGFuKHIxLCByMik7DQorDQorICAgICAgICBhc3NlcnRUcnVlKHIxLmdldFNlcXVlbmNlTnVtYmVyKCkgPiByMi5nZXRTZXF1ZW5jZU51bWJlcigpKTsNCisgICAgICAgIHIxLnNldFRocm93bihoZWFkU3ViSWVDaGFpbihudWxsKSk7DQorICAgICAgICByMi5zZXRUaHJvd24obmV3IEV4Y2VwdGlvbigpKTsNCisgICAgICAgIGFzc2VydFJlY29yZExlc3NUaGFuKHIxLCByMik7DQorDQorICAgICAgICBhc3NlcnRUcnVlKHIxLmdldFNlcXVlbmNlTnVtYmVyKCkgPiByMi5nZXRTZXF1ZW5jZU51bWJlcigpKTsNCisgICAgICAgIHIxLnNldFRocm93bihoZWFkU3ViSWVDaGFpbihuZXcgRXJyb3IoKSkpOw0KKyAgICAgICAgcjIuc2V0VGhyb3duKG5ldyBFcnJvcigpKTsNCisgICAgICAgIGFzc2VydFJlY29yZExlc3NUaGFuKHIxLCByMik7DQorDQorICAgICAgICBhc3NlcnRUcnVlKHIxLmdldFNlcXVlbmNlTnVtYmVyKCkgPiByMi5nZXRTZXF1ZW5jZU51bWJlcigpKTsNCisgICAgICAgIHIxLnNldFRocm93bihoZWFkU3ViSWVDaGFpbihuZXcgUnVudGltZUV4Y2VwdGlvbigpKSk7DQorICAgICAgICByMi5zZXRUaHJvd24obmV3IFJ1bnRpbWVFeGNlcHRpb24oKSk7DQorICAgICAgICBhc3NlcnRSZWNvcmRMZXNzVGhhbihyMSwgcjIpOw0KKw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyMS5nZXRTZXF1ZW5jZU51bWJlcigpID4gcjIuZ2V0U2VxdWVuY2VOdW1iZXIoKSk7DQorICAgICAgICByMS5zZXRUaHJvd24oaGVhZFN1YkllQ2hhaW4obmV3IEV4Y2VwdGlvbigpKSk7DQorICAgICAgICByMi5zZXRUaHJvd24obmV3IEV4Y2VwdGlvbigpKTsNCisgICAgICAgIGFzc2VydFJlY29yZExlc3NUaGFuKHIxLCByMik7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdEJ5VGhyb3duQW5kSW50ZXJydXB0ZWRJb1N1YigpIHsNCisgICAgICAgIExvZ1JlY29yZCByMSA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuSU5GTywgTGV2ZWwuSU5GTy50b1N0cmluZygpKTsNCisgICAgICAgIExvZ1JlY29yZCByMiA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuSU5GTywgTGV2ZWwuSU5GTy50b1N0cmluZygpKTsNCisgICAgICAgIHN3YXBTZXEocjEsIHIyKTsNCisNCisgICAgICAgIGFzc2VydFRydWUocjEuZ2V0U2VxdWVuY2VOdW1iZXIoKSA+IHIyLmdldFNlcXVlbmNlTnVtYmVyKCkpOw0KKyAgICAgICAgcjEuc2V0VGhyb3duKGhlYWRTdWJJaW9lQ2hhaW4obnVsbCkpOw0KKyAgICAgICAgcjIuc2V0VGhyb3duKG5ldyBFcnJvcigpKTsNCisgICAgICAgIGFzc2VydFJlY29yZExlc3NUaGFuKHIxLCByMik7DQorDQorICAgICAgICBhc3NlcnRUcnVlKHIxLmdldFNlcXVlbmNlTnVtYmVyKCkgPiByMi5nZXRTZXF1ZW5jZU51bWJlcigpKTsNCisgICAgICAgIHIxLnNldFRocm93bihoZWFkU3ViSWlvZUNoYWluKG51bGwpKTsNCisgICAgICAgIHIyLnNldFRocm93bihuZXcgUnVudGltZUV4Y2VwdGlvbigpKTsNCisgICAgICAgIGFzc2VydFJlY29yZExlc3NUaGFuKHIxLCByMik7DQorDQorICAgICAgICBhc3NlcnRUcnVlKHIxLmdldFNlcXVlbmNlTnVtYmVyKCkgPiByMi5nZXRTZXF1ZW5jZU51bWJlcigpKTsNCisgICAgICAgIHIxLnNldFRocm93bihoZWFkU3ViSWlvZUNoYWluKG51bGwpKTsNCisgICAgICAgIHIyLnNldFRocm93bihuZXcgRXhjZXB0aW9uKCkpOw0KKyAgICAgICAgYXNzZXJ0UmVjb3JkTGVzc1RoYW4ocjEsIHIyKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0QnlUaHJvd25BbmRUaHJlYWREZWF0aCgpIHsNCisgICAgICAgIExvZ1JlY29yZCByMSA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuSU5GTywgTGV2ZWwuSU5GTy50b1N0cmluZygpKTsNCisgICAgICAgIExvZ1JlY29yZCByMiA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuSU5GTywgTGV2ZWwuSU5GTy50b1N0cmluZygpKTsNCisgICAgICAgIHN3YXBTZXEocjEsIHIyKTsNCisNCisgICAgICAgIGFzc2VydFRydWUocjEuZ2V0U2VxdWVuY2VOdW1iZXIoKSA+IHIyLmdldFNlcXVlbmNlTnVtYmVyKCkpOw0KKyAgICAgICAgcjEuc2V0VGhyb3duKGhlYWRUZENoYWluKG51bGwpKTsNCisgICAgICAgIHIyLnNldFRocm93bihuZXcgRXJyb3IoKSk7DQorICAgICAgICBhc3NlcnRSZWNvcmRMZXNzVGhhbihyMSwgcjIpOw0KKw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyMS5nZXRTZXF1ZW5jZU51bWJlcigpID4gcjIuZ2V0U2VxdWVuY2VOdW1iZXIoKSk7DQorICAgICAgICByMS5zZXRUaHJvd24oaGVhZFRkQ2hhaW4obnVsbCkpOw0KKyAgICAgICAgcjIuc2V0VGhyb3duKG5ldyBSdW50aW1lRXhjZXB0aW9uKCkpOw0KKyAgICAgICAgYXNzZXJ0UmVjb3JkTGVzc1RoYW4ocjEsIHIyKTsNCisNCisgICAgICAgIGFzc2VydFRydWUocjEuZ2V0U2VxdWVuY2VOdW1iZXIoKSA+IHIyLmdldFNlcXVlbmNlTnVtYmVyKCkpOw0KKyAgICAgICAgcjEuc2V0VGhyb3duKGhlYWRUZENoYWluKG51bGwpKTsNCisgICAgICAgIHIyLnNldFRocm93bihuZXcgRXhjZXB0aW9uKCkpOw0KKyAgICAgICAgYXNzZXJ0UmVjb3JkTGVzc1RoYW4ocjEsIHIyKTsNCisNCisgICAgICAgIGFzc2VydFRydWUocjEuZ2V0U2VxdWVuY2VOdW1iZXIoKSA+IHIyLmdldFNlcXVlbmNlTnVtYmVyKCkpOw0KKyAgICAgICAgcjEuc2V0VGhyb3duKGhlYWRUZENoYWluKG5ldyBFcnJvcigpKSk7DQorICAgICAgICByMi5zZXRUaHJvd24obmV3IEVycm9yKCkpOw0KKyAgICAgICAgYXNzZXJ0UmVjb3JkTGVzc1RoYW4ocjEsIHIyKTsNCisNCisgICAgICAgIGFzc2VydFRydWUocjEuZ2V0U2VxdWVuY2VOdW1iZXIoKSA+IHIyLmdldFNlcXVlbmNlTnVtYmVyKCkpOw0KKyAgICAgICAgcjEuc2V0VGhyb3duKGhlYWRUZENoYWluKG5ldyBSdW50aW1lRXhjZXB0aW9uKCkpKTsNCisgICAgICAgIHIyLnNldFRocm93bihuZXcgUnVudGltZUV4Y2VwdGlvbigpKTsNCisgICAgICAgIGFzc2VydFJlY29yZExlc3NUaGFuKHIxLCByMik7DQorDQorICAgICAgICBhc3NlcnRUcnVlKHIxLmdldFNlcXVlbmNlTnVtYmVyKCkgPiByMi5nZXRTZXF1ZW5jZU51bWJlcigpKTsNCisgICAgICAgIHIxLnNldFRocm93bihoZWFkVGRDaGFpbihuZXcgRXhjZXB0aW9uKCkpKTsNCisgICAgICAgIHIyLnNldFRocm93bihuZXcgRXhjZXB0aW9uKCkpOw0KKyAgICAgICAgYXNzZXJ0UmVjb3JkTGVzc1RoYW4ocjEsIHIyKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0QnlUaHJvd25BbmRUaHJlYWREZWF0aFN1YigpIHsNCisgICAgICAgIExvZ1JlY29yZCByMSA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuSU5GTywgTGV2ZWwuSU5GTy50b1N0cmluZygpKTsNCisgICAgICAgIExvZ1JlY29yZCByMiA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuSU5GTywgTGV2ZWwuSU5GTy50b1N0cmluZygpKTsNCisgICAgICAgIHN3YXBTZXEocjEsIHIyKTsNCisNCisgICAgICAgIGFzc2VydFRydWUocjEuZ2V0U2VxdWVuY2VOdW1iZXIoKSA+IHIyLmdldFNlcXVlbmNlTnVtYmVyKCkpOw0KKyAgICAgICAgcjEuc2V0VGhyb3duKGhlYWRTdWJUZENoYWluKG51bGwpKTsNCisgICAgICAgIHIyLnNldFRocm93bihuZXcgRXJyb3IoKSk7DQorICAgICAgICBhc3NlcnRSZWNvcmRMZXNzVGhhbihyMSwgcjIpOw0KKw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyMS5nZXRTZXF1ZW5jZU51bWJlcigpID4gcjIuZ2V0U2VxdWVuY2VOdW1iZXIoKSk7DQorICAgICAgICByMS5zZXRUaHJvd24oaGVhZFN1YlRkQ2hhaW4obnVsbCkpOw0KKyAgICAgICAgcjIuc2V0VGhyb3duKG5ldyBSdW50aW1lRXhjZXB0aW9uKCkpOw0KKyAgICAgICAgYXNzZXJ0UmVjb3JkTGVzc1RoYW4ocjEsIHIyKTsNCisNCisgICAgICAgIGFzc2VydFRydWUocjEuZ2V0U2VxdWVuY2VOdW1iZXIoKSA+IHIyLmdldFNlcXVlbmNlTnVtYmVyKCkpOw0KKyAgICAgICAgcjEuc2V0VGhyb3duKGhlYWRTdWJUZENoYWluKG51bGwpKTsNCisgICAgICAgIHIyLnNldFRocm93bihuZXcgRXhjZXB0aW9uKCkpOw0KKyAgICAgICAgYXNzZXJ0UmVjb3JkTGVzc1RoYW4ocjEsIHIyKTsNCisNCisgICAgICAgIGFzc2VydFRydWUocjEuZ2V0U2VxdWVuY2VOdW1iZXIoKSA+IHIyLmdldFNlcXVlbmNlTnVtYmVyKCkpOw0KKyAgICAgICAgcjEuc2V0VGhyb3duKGhlYWRTdWJUZENoYWluKG5ldyBFcnJvcigpKSk7DQorICAgICAgICByMi5zZXRUaHJvd24obmV3IEVycm9yKCkpOw0KKyAgICAgICAgYXNzZXJ0UmVjb3JkTGVzc1RoYW4ocjEsIHIyKTsNCisNCisgICAgICAgIGFzc2VydFRydWUocjEuZ2V0U2VxdWVuY2VOdW1iZXIoKSA+IHIyLmdldFNlcXVlbmNlTnVtYmVyKCkpOw0KKyAgICAgICAgcjEuc2V0VGhyb3duKGhlYWRTdWJUZENoYWluKG5ldyBSdW50aW1lRXhjZXB0aW9uKCkpKTsNCisgICAgICAgIHIyLnNldFRocm93bihuZXcgUnVudGltZUV4Y2VwdGlvbigpKTsNCisgICAgICAgIGFzc2VydFJlY29yZExlc3NUaGFuKHIxLCByMik7DQorDQorICAgICAgICBhc3NlcnRUcnVlKHIxLmdldFNlcXVlbmNlTnVtYmVyKCkgPiByMi5nZXRTZXF1ZW5jZU51bWJlcigpKTsNCisgICAgICAgIHIxLnNldFRocm93bihoZWFkU3ViVGRDaGFpbihuZXcgRXhjZXB0aW9uKCkpKTsNCisgICAgICAgIHIyLnNldFRocm93bihuZXcgRXhjZXB0aW9uKCkpOw0KKyAgICAgICAgYXNzZXJ0UmVjb3JkTGVzc1RoYW4ocjEsIHIyKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0T2ZDbGFzc0xvYWRSZWFkRmFpbGVkKCkgew0KKyAgICAgICAgLyoqDQorICAgICAgICAgKiBXaGVuIGV4Y2VwdGlvbnMgdHJpZ2dlcnMgZXJyb3JzIHRoYXQgaXMgbW9yZSBpbXBvcnRhbnQgdGhhbiB0aGUgcm9vdA0KKyAgICAgICAgICogY2F1c2UuDQorICAgICAgICAgKi8NCisgICAgICAgIFRocm93YWJsZSBjbHJmID0gbmV3IE5vQ2xhc3NEZWZGb3VuZEVycm9yKCkuaW5pdENhdXNlKA0KKyAgICAgICAgICAgICAgICBuZXcgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbigiIiwgbmV3IElPRXhjZXB0aW9uKCkpKTsNCisNCisgICAgICAgIFRocm93YWJsZSByZWFkRmFpbGVkID0gbmV3IElPRXhjZXB0aW9uKCk7DQorDQorICAgICAgICBMb2dSZWNvcmQgcjEgPSBuZXcgTG9nUmVjb3JkKExldmVsLklORk8sIExldmVsLklORk8udG9TdHJpbmcoKSk7DQorICAgICAgICBMb2dSZWNvcmQgcjIgPSBuZXcgTG9nUmVjb3JkKExldmVsLklORk8sIExldmVsLklORk8udG9TdHJpbmcoKSk7DQorDQorICAgICAgICByMS5zZXRUaHJvd24ocmVhZEZhaWxlZCk7DQorICAgICAgICByMi5zZXRUaHJvd24oY2xyZik7DQorICAgICAgICBhc3NlcnRSZWNvcmRMZXNzVGhhbihyMSwgcjIpOw0KKw0KKyAgICAgICAgcjEuc2V0VGhyb3duKGNscmYpOw0KKyAgICAgICAgcjIuc2V0VGhyb3duKHJlYWRGYWlsZWQpOw0KKyAgICAgICAgYXNzZXJ0UmVjb3JkTGVzc1RoYW4ocjIsIHIxKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0T2ZDbGFzc0xvYWRJbnRlcnJ1cHRlZCgpIHsNCisgICAgICAgIC8qKg0KKyAgICAgICAgICogV2hlbiBleGNlcHRpb25zIHRyaWdnZXJzIGVycm9ycyB0aGF0IGlzIG1vcmUgaW1wb3J0YW50IHRoYW4gdGhlIHJvb3QNCisgICAgICAgICAqIGNhdXNlLg0KKyAgICAgICAgICovDQorICAgICAgICBUaHJvd2FibGUgY2xpID0gbmV3IE5vQ2xhc3NEZWZGb3VuZEVycm9yKCkuaW5pdENhdXNlKA0KKyAgICAgICAgICAgICAgICBuZXcgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbigiIiwgaGVhZElpb2VDaGFpbihudWxsKSkpOw0KKw0KKyAgICAgICAgVGhyb3dhYmxlIGlpb2UgPSBoZWFkSWlvZUNoYWluKG51bGwpOw0KKw0KKyAgICAgICAgTG9nUmVjb3JkIHIxID0gbmV3IExvZ1JlY29yZChMZXZlbC5JTkZPLCBMZXZlbC5JTkZPLnRvU3RyaW5nKCkpOw0KKyAgICAgICAgTG9nUmVjb3JkIHIyID0gbmV3IExvZ1JlY29yZChMZXZlbC5JTkZPLCBMZXZlbC5JTkZPLnRvU3RyaW5nKCkpOw0KKw0KKyAgICAgICAgcjEuc2V0VGhyb3duKGlpb2UpOw0KKyAgICAgICAgcjIuc2V0VGhyb3duKGNsaSk7DQorICAgICAgICBhc3NlcnRSZWNvcmRMZXNzVGhhbihyMSwgcjIpOw0KKw0KKyAgICAgICAgcjEuc2V0VGhyb3duKGNsaSk7DQorICAgICAgICByMi5zZXRUaHJvd24oaWlvZSk7DQorICAgICAgICBhc3NlcnRSZWNvcmRMZXNzVGhhbihyMiwgcjEpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RPZk5wZVZzSW9lKCkgew0KKyAgICAgICAgVGhyb3dhYmxlIHJlYWRGYWlsZWQgPSBuZXcgSU9FeGNlcHRpb24oKTsNCisgICAgICAgIFRocm93YWJsZSBucGUgPSBuZXcgSU9FeGNlcHRpb24oKS5pbml0Q2F1c2UobmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCkpOw0KKw0KKyAgICAgICAgTG9nUmVjb3JkIHIxID0gbmV3IExvZ1JlY29yZChMZXZlbC5JTkZPLCBMZXZlbC5JTkZPLnRvU3RyaW5nKCkpOw0KKyAgICAgICAgTG9nUmVjb3JkIHIyID0gbmV3IExvZ1JlY29yZChMZXZlbC5JTkZPLCBMZXZlbC5JTkZPLnRvU3RyaW5nKCkpOw0KKw0KKyAgICAgICAgcjEuc2V0VGhyb3duKHJlYWRGYWlsZWQpOw0KKyAgICAgICAgcjIuc2V0VGhyb3duKG5wZSk7DQorICAgICAgICBhc3NlcnRSZWNvcmRMZXNzVGhhbihyMSwgcjIpOw0KKw0KKyAgICAgICAgcjEuc2V0VGhyb3duKG5wZSk7DQorICAgICAgICByMi5zZXRUaHJvd24ocmVhZEZhaWxlZCk7DQorICAgICAgICBhc3NlcnRSZWNvcmRMZXNzVGhhbihyMiwgcjEpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RBcnJheVNvcnQoKSB7DQorICAgICAgICB0ZXN0QXJyYXlTb3J0KG5ldyBTZXZlcml0eUNvbXBhcmF0b3IoKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdFJldmVyc2VBcnJheVNvcnQoKSB7DQorICAgICAgICB0ZXN0QXJyYXlTb3J0KENvbGxlY3Rpb25zLnJldmVyc2VPcmRlcihuZXcgU2V2ZXJpdHlDb21wYXJhdG9yKCkpKTsNCisgICAgfQ0KKw0KKyAgICBwcml2YXRlIHZvaWQgdGVzdEFycmF5U29ydChDb21wYXJhdG9yPExvZ1JlY29yZD4gc2MpIHsNCisgICAgICAgIExvZ1JlY29yZFtdIHIgPSBjcmVhdGVSZWNvcmRzKCk7DQorICAgICAgICBMb2dSZWNvcmRbXSBjb3B5ID0gci5jbG9uZSgpOw0KKyAgICAgICAgQXJyYXlzLnNvcnQoY29weSwgc2MpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyLmxlbmd0aCA+IDEpOw0KKw0KKyAgICAgICAgLy9FbnN1cmUgY3JlYXRlUmVjb3JkcyBpcyBub3QgYWxyZWFkeSBzb3J0ZWQuDQorICAgICAgICBpbnQgb3JkZXJDaGFuZ2VkID0gMDsNCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgci5sZW5ndGg7IGkrKykgew0KKyAgICAgICAgICAgIGlmIChzYy5jb21wYXJlKHJbaV0sIGNvcHlbaV0pICE9IDApIHsNCisgICAgICAgICAgICAgICAgKytvcmRlckNoYW5nZWQ7DQorICAgICAgICAgICAgfQ0KKyAgICAgICAgfQ0KKyAgICAgICAgYXNzZXJ0VHJ1ZShTdHJpbmcudmFsdWVPZihvcmRlckNoYW5nZWQpLCBvcmRlckNoYW5nZWQgPiByLmxlbmd0aCAvIDIpOw0KKw0KKyAgICAgICAgLy9FbnN1cmUgc29ydGVkLg0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByLmxlbmd0aCAtIDE7IGkrKykgew0KKyAgICAgICAgICAgIGlmIChzYy5jb21wYXJlKGNvcHlbaV0sIGNvcHlbaSArIDFdKSA+IDApIHsNCisgICAgICAgICAgICAgICAgZmFpbCh0b1N0cmluZyhjb3B5W2ldLCBjb3B5W2kgKyAxXSkpOw0KKyAgICAgICAgICAgIH0NCisgICAgICAgIH0NCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0TGlzdFNvcnQoKSB7DQorICAgICAgICB0ZXN0TGlzdFNvcnQobmV3IFNldmVyaXR5Q29tcGFyYXRvcigpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmV2ZXJzZUxpc3RTb3J0KCkgew0KKyAgICAgICAgdGVzdExpc3RTb3J0KENvbGxlY3Rpb25zLnJldmVyc2VPcmRlcihuZXcgU2V2ZXJpdHlDb21wYXJhdG9yKCkpKTsNCisgICAgfQ0KKw0KKyAgICBwcml2YXRlIHZvaWQgdGVzdExpc3RTb3J0KENvbXBhcmF0b3I8TG9nUmVjb3JkPiBzYykgew0KKyAgICAgICAgTGlzdDxMb2dSZWNvcmQ+IGEgPSBBcnJheXMuYXNMaXN0KGNyZWF0ZVJlY29yZHMoKSk7DQorICAgICAgICBDb2xsZWN0aW9ucy5zb3J0KGEsIHNjKTsNCisNCisgICAgICAgIExpc3Q8TG9nUmVjb3JkPiBiID0gc2VyaWFsQ2xvbmUoYSk7DQorICAgICAgICBDb2xsZWN0aW9ucy5zb3J0KGIsIHNjKTsNCisNCisgICAgICAgIGFzc2VydEVxdWFscyhhLnNpemUoKSwgYi5zaXplKCkpOw0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhLnNpemUoKTsgaSsrKSB7DQorICAgICAgICAgICAgTG9nUmVjb3JkIHIxID0gYS5nZXQoaSk7DQorICAgICAgICAgICAgTG9nUmVjb3JkIHIyID0gYi5nZXQoaSk7DQorICAgICAgICAgICAgaWYgKHNjLmNvbXBhcmUocjEsIHIyKSAhPSAwKSB7DQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcih0b1N0cmluZyhpLCByMSwgcjIpKTsNCisgICAgICAgICAgICB9DQorICAgICAgICB9DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdFRyZWVNYXAoKSB7DQorICAgICAgICB0ZXN0TWFwKG5ldyBUcmVlTWFwPExvZ1JlY29yZCwgQm9vbGVhbj4obmV3IFNldmVyaXR5Q29tcGFyYXRvcigpKSk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdFJldmVyc2VUcmVlTWFwKCkgew0KKyAgICAgICAgdGVzdE1hcChuZXcgVHJlZU1hcDxMb2dSZWNvcmQsIEJvb2xlYW4+KENvbGxlY3Rpb25zDQorICAgICAgICAgICAgICAgIC5yZXZlcnNlT3JkZXIobmV3IFNldmVyaXR5Q29tcGFyYXRvcigpKSkpOw0KKyAgICB9DQorDQorICAgIHByaXZhdGUgdm9pZCB0ZXN0TWFwKFNvcnRlZE1hcDxMb2dSZWNvcmQsIEJvb2xlYW4+IG0pIHsNCisgICAgICAgIGFzc2VydFRydWUobS5pc0VtcHR5KCkpOw0KKw0KKyAgICAgICAgZm9yIChMb2dSZWNvcmQgciA6IGNyZWF0ZVJlY29yZHMoKSkgew0KKyAgICAgICAgICAgIGFzc2VydE51bGwobS5wdXQociwgQm9vbGVhbi5UUlVFKSk7DQorICAgICAgICB9DQorDQorICAgICAgICBTb3J0ZWRNYXA8TG9nUmVjb3JkLCBCb29sZWFuPiBjb3B5ID0gc2VyaWFsQ2xvbmUobSk7DQorICAgICAgICBJdGVyYXRvcjxMb2dSZWNvcmQ+IGtleXMgPSBjb3B5LmtleVNldCgpLml0ZXJhdG9yKCk7DQorICAgICAgICBhc3NlcnRUcnVlKGtleXMuaGFzTmV4dCgpKTsNCisgICAgICAgIGludCBpID0gMDsNCisgICAgICAgIGZvciAoTG9nUmVjb3JkIHIxIDogbS5rZXlTZXQoKSkgew0KKyAgICAgICAgICAgIExvZ1JlY29yZCByMiA9IGtleXMubmV4dCgpOw0KKyAgICAgICAgICAgIGlmIChtLmNvbXBhcmF0b3IoKS5jb21wYXJlKHIxLCByMikgIT0gMCkgew0KKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IodG9TdHJpbmcoaSwgcjEsIHIyKSk7DQorICAgICAgICAgICAgfQ0KKyAgICAgICAgICAgICsraTsNCisgICAgICAgIH0NCisNCisgICAgICAgIC8vRG9uJ3QgdXNlIGNvbnRhaW5zQWxsLg0KKyAgICAgICAgYXNzZXJ0RmFsc2UobS5pc0VtcHR5KCkpOw0KKyAgICAgICAgZm9yIChMb2dSZWNvcmQgciA6IG0ua2V5U2V0KCkpIHsNCisgICAgICAgICAgICBpZiAoIWNvcHkuY29udGFpbnNLZXkocikpIHsNCisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKHRvU3RyaW5nKHIpKTsNCisgICAgICAgICAgICB9DQorICAgICAgICB9DQorDQorICAgICAgICAvL0Rvbid0IHVzZSBjb250YWluc0FsbC4NCisgICAgICAgIGFzc2VydEZhbHNlKGNvcHkuaXNFbXB0eSgpKTsNCisgICAgICAgIGZvciAoTG9nUmVjb3JkIHIgOiBjb3B5LmtleVNldCgpKSB7DQorICAgICAgICAgICAgaWYgKCFtLmNvbnRhaW5zS2V5KHIpKSB7DQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcih0b1N0cmluZyhyKSk7DQorICAgICAgICAgICAgfQ0KKyAgICAgICAgfQ0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RQcmlvcml0eVF1ZXVlKCkgew0KKyAgICAgICAgU2V2ZXJpdHlDb21wYXJhdG9yIHNjID0gbmV3IFNldmVyaXR5Q29tcGFyYXRvcigpOw0KKyAgICAgICAgTG9nUmVjb3JkW10gcnMgPSBjcmVhdGVSZWNvcmRzKCk7DQorICAgICAgICBQcmlvcml0eVF1ZXVlPExvZ1JlY29yZD4gcTENCisgICAgICAgICAgICAgICAgPSBuZXcgUHJpb3JpdHlRdWV1ZTw+KHJzLmxlbmd0aCwgc2MpOw0KKyAgICAgICAgQ29sbGVjdGlvbnMuYWRkQWxsKHExLCBycyk7DQorICAgICAgICBQcmlvcml0eVF1ZXVlPExvZ1JlY29yZD4gcTIgPSBzZXJpYWxDbG9uZShxMSk7DQorDQorICAgICAgICBhc3NlcnRGYWxzZShxMS5pc0VtcHR5KCkpOw0KKyAgICAgICAgYXNzZXJ0RmFsc2UocTIuaXNFbXB0eSgpKTsNCisNCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcnMubGVuZ3RoOyBpKyspIHsNCisgICAgICAgICAgICBMb2dSZWNvcmQgcjEgPSBxMS5wb2xsKCk7DQorICAgICAgICAgICAgTG9nUmVjb3JkIHIyID0gcTIucG9sbCgpOw0KKyAgICAgICAgICAgIGlmIChzYy5jb21wYXJlKHIxLCByMikgIT0gMCkgew0KKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IodG9TdHJpbmcoaSwgcjEsIHIyKSk7DQorICAgICAgICAgICAgfQ0KKyAgICAgICAgfQ0KKw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShxMS5pc0VtcHR5KCkpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShxMi5pc0VtcHR5KCkpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJPYmplY3RFcXVhbHNOdWxsIikNCisgICAgcHVibGljIHZvaWQgdGVzdEVxdWFscygpIHsNCisgICAgICAgIGZpbmFsIFNldmVyaXR5Q29tcGFyYXRvciBhID0gbmV3IFNldmVyaXR5Q29tcGFyYXRvcigpOw0KKyAgICAgICAgZmluYWwgU2V2ZXJpdHlDb21wYXJhdG9yIGIgPSBuZXcgU2V2ZXJpdHlDb21wYXJhdG9yKCk7DQorICAgICAgICBhc3NlcnROb3RTYW1lKGEsIGIpOw0KKw0KKyAgICAgICAgLy9OUEUgY2hlY2tzLg0KKyAgICAgICAgYXNzZXJ0Tm90TnVsbChhKTsNCisgICAgICAgIGFzc2VydEZhbHNlKGEuZXF1YWxzKG51bGwpKTsNCisNCisgICAgICAgIGFzc2VydE5vdE51bGwoYik7DQorICAgICAgICBhc3NlcnRGYWxzZShiLmVxdWFscyhudWxsKSk7DQorDQorICAgICAgICAvL1JlZmxleGl2ZSB0ZXN0Lg0KKyAgICAgICAgYXNzZXJ0VHJ1ZShhLmVxdWFscyhhKSk7DQorICAgICAgICBhc3NlcnRUcnVlKGIuZXF1YWxzKGIpKTsNCisNCisgICAgICAgIC8vVHJhbnNpdGl2ZSB0ZXN0Lg0KKyAgICAgICAgYXNzZXJ0VHJ1ZShhLmVxdWFscyhiKSk7DQorICAgICAgICBhc3NlcnRUcnVlKGIuZXF1YWxzKGEpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SGFzaENvZGUoKSB7DQorICAgICAgICBmaW5hbCBTZXZlcml0eUNvbXBhcmF0b3IgYSA9IG5ldyBTZXZlcml0eUNvbXBhcmF0b3IoKTsNCisgICAgICAgIGZpbmFsIFNldmVyaXR5Q29tcGFyYXRvciBiID0gbmV3IFNldmVyaXR5Q29tcGFyYXRvcigpOw0KKyAgICAgICAgYXNzZXJ0Tm90U2FtZShhLCBiKTsNCisNCisgICAgICAgIGFzc2VydFRydWUoYS5lcXVhbHMoYikpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShiLmVxdWFscyhhKSk7DQorDQorICAgICAgICBhc3NlcnRFcXVhbHMoYS5oYXNoQ29kZSgpLCBiLmhhc2hDb2RlKCkpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RUb1N0cmluZygpIHsNCisgICAgICAgIGZpbmFsIFNldmVyaXR5Q29tcGFyYXRvciBhID0gbmV3IFNldmVyaXR5Q29tcGFyYXRvcigpOw0KKyAgICAgICAgYXNzZXJ0Tm90TnVsbChhLnRvU3RyaW5nKCkpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKGEudG9TdHJpbmcoKSwgYS50b1N0cmluZygpKTsNCisgICAgfQ0KKw0KKyAgICBAVGVzdA0KKyAgICBwdWJsaWMgdm9pZCB0ZXN0SmF2YU1haWxMaW5rYWdlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7DQorICAgICAgICB0ZXN0SmF2YU1haWxMaW5rYWdlKFNldmVyaXR5Q29tcGFyYXRvci5jbGFzcyk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdExvZ01hbmFnZXJNb2RpZmllcnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsNCisgICAgICAgIHRlc3RMb2dNYW5hZ2VyTW9kaWZpZXJzKFNldmVyaXR5Q29tcGFyYXRvci5jbGFzcyk7DQorICAgIH0NCisNCisgICAgQFRlc3QNCisgICAgcHVibGljIHZvaWQgdGVzdFdlYmFwcENsYXNzTG9hZGVyRmllbGROYW1lcygpIHRocm93cyBFeGNlcHRpb24gew0KKyAgICAgICAgdGVzdFdlYmFwcENsYXNzTG9hZGVyRmllbGROYW1lcyhTZXZlcml0eUNvbXBhcmF0b3IuY2xhc3MpOw0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXJpYWxpemFibGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsNCisgICAgICAgIGZpbmFsIFNldmVyaXR5Q29tcGFyYXRvciBhID0gbmV3IFNldmVyaXR5Q29tcGFyYXRvcigpOw0KKyAgICAgICAgZmluYWwgU2V2ZXJpdHlDb21wYXJhdG9yIGIgPSBzZXJpYWxDbG9uZShhKTsNCisNCisgICAgICAgIGFzc2VydFRydWUoYS5lcXVhbHMoYikpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShiLmVxdWFscyhhKSk7DQorDQorICAgICAgICBhc3NlcnRFcXVhbHMoYS5oYXNoQ29kZSgpLCBiLmhhc2hDb2RlKCkpOw0KKyAgICB9DQorDQorICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQ0KKyAgICBwcml2YXRlIDxUPiBUIHNlcmlhbENsb25lKFQgdCkgew0KKyAgICAgICAgdHJ5IHsNCisgICAgICAgICAgICBmaW5hbCBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gb3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7DQorICAgICAgICAgICAgZmluYWwgT2JqZWN0T3V0cHV0U3RyZWFtIG91dCA9IG5ldyBPYmplY3RPdXRwdXRTdHJlYW0ob3MpOw0KKyAgICAgICAgICAgIHRyeSB7DQorICAgICAgICAgICAgICAgIG91dC53cml0ZU9iamVjdCh0KTsNCisgICAgICAgICAgICAgICAgb3V0LmZsdXNoKCk7DQorICAgICAgICAgICAgfSBmaW5hbGx5IHsNCisgICAgICAgICAgICAgICAgb3V0LmNsb3NlKCk7DQorICAgICAgICAgICAgfQ0KKw0KKyAgICAgICAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGlzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKG9zLnRvQnl0ZUFycmF5KCkpOw0KKyAgICAgICAgICAgIGZpbmFsIE9iamVjdElucHV0U3RyZWFtIGluID0gbmV3IE9iamVjdElucHV0U3RyZWFtKGlzKTsNCisgICAgICAgICAgICB0cnkgew0KKyAgICAgICAgICAgICAgICByZXR1cm4gKFQpIGluLnJlYWRPYmplY3QoKTsNCisgICAgICAgICAgICB9IGZpbmFsbHkgew0KKyAgICAgICAgICAgICAgICBpbi5jbG9zZSgpOw0KKyAgICAgICAgICAgIH0NCisgICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gQ05GRSkgew0KKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihDTkZFKTsNCisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkgew0KKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihpb2UpOw0KKyAgICAgICAgfQ0KKyAgICB9DQorDQorICAgIEBUZXN0DQorICAgIHB1YmxpYyB2b2lkIHRlc3RCeU1pbGxpcygpIHsNCisgICAgICAgIHRlc3RCeU1pbGxpcyhuZXcgRXJyb3IoKSk7DQorICAgICAgICB0ZXN0QnlNaWxsaXMobmV3IFJ1bnRpbWVFeGNlcHRpb24oKSk7DQorICAgICAgICB0ZXN0QnlNaWxsaXMobmV3IEV4Y2VwdGlvbigpKTsNCisgICAgfQ0KKw0KKyAgICBwcml2YXRlIHZvaWQgdGVzdEJ5TWlsbGlzKFRocm93YWJsZSB0KSB7DQorICAgICAgICBMb2dSZWNvcmQgcjEgPSBuZXcgTG9nUmVjb3JkKExldmVsLklORk8sIExldmVsLklORk8udG9TdHJpbmcoKSk7DQorICAgICAgICBMb2dSZWNvcmQgcjIgPSBuZXcgTG9nUmVjb3JkKExldmVsLklORk8sIExldmVsLklORk8udG9TdHJpbmcoKSk7DQorICAgICAgICByMi5zZXRTZXF1ZW5jZU51bWJlcihyMS5nZXRTZXF1ZW5jZU51bWJlcigpKTsNCisgICAgICAgIHNldEVwb2NoTWlsbGkocjEsIDEwKTsNCisgICAgICAgIHNldEVwb2NoTWlsbGkocjIsIDIwKTsNCisNCisgICAgICAgIGFzc2VydEVxdWFscyhyMS5nZXRMZXZlbCgpLCByMi5nZXRMZXZlbCgpKTsNCisgICAgICAgIGFzc2VydEVxdWFscyhyMS5nZXRUaHJvd24oKSwgcjIuZ2V0VGhyb3duKCkpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKHIxLmdldFNlcXVlbmNlTnVtYmVyKCksIHIyLmdldFNlcXVlbmNlTnVtYmVyKCkpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKHIxLmdldFRocmVhZElEKCksIHIyLmdldFRocmVhZElEKCkpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKHIxLmdldENsYXNzKCksIHIyLmdldENsYXNzKCkpOw0KKyAgICAgICAgYXNzZXJ0VHJ1ZShyMS5nZXRNaWxsaXMoKSA8IHIyLmdldE1pbGxpcygpKTsNCisgICAgICAgIGFzc2VydFJlY29yZExlc3NUaGFuKHIxLCByMik7DQorDQorICAgICAgICByMS5zZXRUaHJvd24odCk7DQorICAgICAgICByMi5zZXRUaHJvd24ocjEuZ2V0VGhyb3duKCkpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKHIxLmdldExldmVsKCksIHIyLmdldExldmVsKCkpOw0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKHIxLmdldFRocm93bigpLCByMi5nZXRUaHJvd24oKSk7DQorICAgICAgICBhc3NlcnRFcXVhbHMocjEuZ2V0U2VxdWVuY2VOdW1iZXIoKSwgcjIuZ2V0U2VxdWVuY2VOdW1iZXIoKSk7DQorICAgICAgICBhc3NlcnRFcXVhbHMocjEuZ2V0VGhyZWFkSUQoKSwgcjIuZ2V0VGhyZWFkSUQoKSk7DQorICAgICAgICBhc3NlcnRFcXVhbHMocjEuZ2V0Q2xhc3MoKSwgcjIuZ2V0Q2xhc3MoKSk7DQorICAgICAgICBhc3NlcnRUcnVlKHIxLmdldE1pbGxpcygpIDwgcjIuZ2V0TWlsbGlzKCkpOw0KKyAgICAgICAgYXNzZXJ0UmVjb3JkTGVzc1RoYW4ocjEsIHIyKTsNCisgICAgfQ0KKw0KKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGFzc2VydFJlY29yZExlc3NUaGFuKExvZ1JlY29yZCByMSwgTG9nUmVjb3JkIHIyKSB7DQorICAgICAgICBmaW5hbCBTZXZlcml0eUNvbXBhcmF0b3IgYSA9IG5ldyBTZXZlcml0eUNvbXBhcmF0b3IoKTsNCisgICAgICAgIGlmIChhLmNvbXBhcmUocjEsIHIyKSA+PSAwKSB7DQorICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKHRvU3RyaW5nKHIxLCByMikpOw0KKyAgICAgICAgfQ0KKw0KKyAgICAgICAgaWYgKGEuY29tcGFyZShyMiwgcjEpIDw9IDApIHsNCisgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IodG9TdHJpbmcocjEsIHIyKSk7DQorICAgICAgICB9DQorICAgIH0NCisNCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIHRvU3RyaW5nKGludCBpLCBMb2dSZWNvcmQgcjEsIExvZ1JlY29yZCByMikgew0KKyAgICAgICAgcmV0dXJuICJJbmRleDogIiArIGkgKyAiICIgKyB0b1N0cmluZyhyMSwgcjIpOw0KKyAgICB9DQorDQorICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyB0b1N0cmluZyhMb2dSZWNvcmQgcjEsIExvZ1JlY29yZCByMikgew0KKyAgICAgICAgcmV0dXJuIHRvU3RyaW5nKHIxKSArICd8JyArIHRvU3RyaW5nKHIyKTsNCisgICAgfQ0KKw0KKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgdG9TdHJpbmcoTG9nUmVjb3JkIHIpIHsNCisgICAgICAgIFN0cmluZ0J1aWxkZXIgYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7DQorICAgICAgICBiLmFwcGVuZChyLmdldExldmVsKCkpLmFwcGVuZCgiLCAiKTsNCisgICAgICAgIGIuYXBwZW5kKHRvU3RyaW5nKHIuZ2V0VGhyb3duKCkpKTsNCisgICAgICAgIGIuYXBwZW5kKCcgJykuYXBwZW5kKHIuZ2V0U2VxdWVuY2VOdW1iZXIoKSk7DQorICAgICAgICByZXR1cm4gYi50b1N0cmluZygpOw0KKyAgICB9DQorDQorICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyB0b1N0cmluZyhUaHJvd2FibGUgY2hhaW4pIHsNCisgICAgICAgIFN0cmluZ0J1aWxkZXIgYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7DQorICAgICAgICBpZiAoY2hhaW4gIT0gbnVsbCkgew0KKyAgICAgICAgICAgIFN0cmluZyBzZXAgPSAiIjsNCisgICAgICAgICAgICBmb3IgKFRocm93YWJsZSB0ID0gY2hhaW47IHQgIT0gbnVsbDsgdCA9IHQuZ2V0Q2F1c2UoKSkgew0KKyAgICAgICAgICAgICAgICBiLmFwcGVuZChzZXApLmFwcGVuZCh0LmdldENsYXNzKCkuZ2V0U2ltcGxlTmFtZSgpKTsNCisgICAgICAgICAgICAgICAgc2VwID0gIiwgIjsNCisgICAgICAgICAgICB9DQorICAgICAgICB9IGVsc2Ugew0KKyAgICAgICAgICAgIGIuYXBwZW5kKCJudWxsIik7DQorICAgICAgICB9DQorICAgICAgICByZXR1cm4gYi50b1N0cmluZygpOw0KKyAgICB9DQorDQorICAgIHByaXZhdGUgc3RhdGljIHZvaWQgc3dhcFNlcShMb2dSZWNvcmQgcjEsIExvZ1JlY29yZCByMikgew0KKyAgICAgICAgZmluYWwgbG9uZyBzZXEgPSByMS5nZXRTZXF1ZW5jZU51bWJlcigpOw0KKyAgICAgICAgcjEuc2V0U2VxdWVuY2VOdW1iZXIocjIuZ2V0U2VxdWVuY2VOdW1iZXIoKSk7DQorICAgICAgICByMi5zZXRTZXF1ZW5jZU51bWJlcihzZXEpOw0KKyAgICAgICAgYXNzZXJ0RmFsc2UocjEuZ2V0U2VxdWVuY2VOdW1iZXIoKSA9PSByMi5nZXRTZXF1ZW5jZU51bWJlcigpKTsNCisgICAgfQ0KKw0KKyAgICBwcml2YXRlIExvZ1JlY29yZFtdIGNyZWF0ZVJlY29yZHMoKSB7DQorICAgICAgICBMb2dSZWNvcmRbXSByID0gbmV3IExvZ1JlY29yZFs4XTsNCisgICAgICAgIHJbMF0gPSBuZXcgTG9nUmVjb3JkKExldmVsLklORk8sICJTdGFydGVkIHswfSwgezF9Iik7DQorICAgICAgICByWzBdLnNldFBhcmFtZXRlcnMobmV3IE9iamVjdFtdeyIxMCIsIG5ldyBPYmplY3QoKX0pOw0KKyAgICAgICAgclsxXSA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuQ09ORklHLCAiOTklIik7DQorICAgICAgICByWzJdID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICIxc3QgZmFpbHVyZS4iKTsNCisgICAgICAgIHJbMl0uc2V0VGhyb3duKG5ldyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uKCkpOw0KKyAgICAgICAgclszXSA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuU0VWRVJFLCAiMm5kIGZhaWx1cmUuIik7DQorICAgICAgICByWzNdLnNldFRocm93bihuZXcgRXhjZXB0aW9uSW5Jbml0aWFsaXplckVycm9yKG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpKSk7DQorICAgICAgICByWzRdID0gbmV3IExvZ1JlY29yZChMZXZlbC5TRVZFUkUsICIzcmQgZmFpbHVyZS4iKTsNCisgICAgICAgIHJbNF0uc2V0VGhyb3duKG5ldyBOb0NsYXNzRGVmRm91bmRFcnJvcigpKTsNCisgICAgICAgIHJbNV0gPSBuZXcgTG9nUmVjb3JkKExldmVsLldBUk5JTkcsICJSZXN0YXJ0IHJlcXVpcmVkLiIpOw0KKyAgICAgICAgcls2XSA9IG5ldyBMb2dSZWNvcmQoTGV2ZWwuSU5GTywgIlJlc3RhcnRpbmcuLi4uIik7DQorICAgICAgICByWzddID0gbmV3IExvZ1JlY29yZChMZXZlbC5GSU5FLCAiR29vZCBieWUuIik7DQorICAgICAgICByZXR1cm4gcjsNCisgICAgfQ0KKw0KKyAgICBwcml2YXRlIFRocm93YWJsZSBoZWFkSWVDaGFpbihUaHJvd2FibGUgbGFzdCkgew0KKyAgICAgICAgcmV0dXJuIG5ldyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbihTdHJpbmcudmFsdWVPZihsYXN0KSkuaW5pdENhdXNlKGxhc3QpOw0KKyAgICB9DQorDQorICAgIHByaXZhdGUgVGhyb3dhYmxlIGhlYWRJaW9lQ2hhaW4oVGhyb3dhYmxlIGxhc3QpIHsNCisgICAgICAgIHJldHVybiBuZXcgSW50ZXJydXB0ZWRJT0V4Y2VwdGlvbihTdHJpbmcudmFsdWVPZihsYXN0KSkuaW5pdENhdXNlKGxhc3QpOw0KKyAgICB9DQorDQorICAgIHByaXZhdGUgVGhyb3dhYmxlIGhlYWRDYmllQ2hhaW4oVGhyb3dhYmxlIGxhc3QpIHsNCisgICAgICAgIHJldHVybiBuZXcgQ2xvc2VkQnlJbnRlcnJ1cHRFeGNlcHRpb24oKS5pbml0Q2F1c2UobGFzdCk7DQorICAgIH0NCisNCisgICAgcHJpdmF0ZSBUaHJvd2FibGUgaGVhZEZsaWVDaGFpbihUaHJvd2FibGUgbGFzdCkgew0KKyAgICAgICAgcmV0dXJuIG5ldyBGaWxlTG9ja0ludGVycnVwdGlvbkV4Y2VwdGlvbigpLmluaXRDYXVzZShsYXN0KTsNCisgICAgfQ0KKw0KKyAgICBwcml2YXRlIFRocm93YWJsZSBoZWFkU3ViSWVDaGFpbihUaHJvd2FibGUgbGFzdCkgew0KKyAgICAgICAgcmV0dXJuIG5ldyBTdWJPZkllKCkuaW5pdENhdXNlKGxhc3QpOw0KKyAgICB9DQorDQorICAgIHByaXZhdGUgVGhyb3dhYmxlIGhlYWRTdWJJaW9lQ2hhaW4oVGhyb3dhYmxlIGxhc3QpIHsNCisgICAgICAgIHJldHVybiBuZXcgU3ViT2ZJaW9lKCkuaW5pdENhdXNlKGxhc3QpOw0KKyAgICB9DQorDQorICAgIHByaXZhdGUgVGhyb3dhYmxlIGhlYWRUZENoYWluKFRocm93YWJsZSBsYXN0KSB7DQorICAgICAgICByZXR1cm4gbmV3IFRocmVhZERlYXRoKCkuaW5pdENhdXNlKGxhc3QpOw0KKyAgICB9DQorDQorICAgIHByaXZhdGUgVGhyb3dhYmxlIGhlYWRTdWJUZENoYWluKFRocm93YWJsZSBsYXN0KSB7DQorICAgICAgICByZXR1cm4gbmV3IFN1Yk9mVGQoKS5pbml0Q2F1c2UobGFzdCk7DQorICAgIH0NCisNCisgICAgcHJpdmF0ZSBUaHJvd2FibGUgaGVhZFdpZENoYWluKFRocm93YWJsZSBsYXN0KSB7DQorICAgICAgICByZXR1cm4gbmV3IFdvcmtJbnRlcnJ1cHRlZEV4Y2VwdGlvbigpLmluaXRDYXVzZShsYXN0KTsNCisgICAgfQ0KKw0KKyAgICBwcml2YXRlIFRocm93YWJsZSBoZWFkV2l0Q2hhaW4oVGhyb3dhYmxlIGxhc3QpIHsNCisgICAgICAgIHJldHVybiBuZXcgV29ya0ludGVycnVwdGlvbkV4Y2VwdGlvbigpLmluaXRDYXVzZShsYXN0KTsNCisgICAgfQ0KKw0KKyAgICAvKioNCisgICAgICogTG90cyBvZiBmcmFtZXdvcmsgZGVzaWduZXJzIGRpc2xpa2UgY2hlY2tlZCBleGNlcHRpb25zLg0KKyAgICAgKi8NCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgV29ya0ludGVycnVwdGlvbkV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24gew0KKw0KKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7DQorDQorICAgICAgICAvKioNCisgICAgICAgICAqIFByb21vdGUgYWNjZXNzLg0KKyAgICAgICAgICovDQorICAgICAgICBXb3JrSW50ZXJydXB0aW9uRXhjZXB0aW9uKCkgew0KKyAgICAgICAgfQ0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBMb3RzIG9mIGZyYW1ld29yayBkZXNpZ25lcnMgZGlzbGlrZSBjaGVja2VkIGV4Y2VwdGlvbnMuDQorICAgICAqLw0KKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBXb3JrSW50ZXJydXB0ZWRFeGNlcHRpb24gZXh0ZW5kcyBSdW50aW1lRXhjZXB0aW9uIHsNCisNCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOw0KKw0KKyAgICAgICAgLyoqDQorICAgICAgICAgKiBQcm9tb3RlIGFjY2Vzcy4NCisgICAgICAgICAqLw0KKyAgICAgICAgV29ya0ludGVycnVwdGVkRXhjZXB0aW9uKCkgew0KKyAgICAgICAgfQ0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBTdWIgY2xhc3Mgb2YgaW50ZXJydXB0ZWQuDQorICAgICAqLw0KKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBTdWJPZkllIGV4dGVuZHMgSW50ZXJydXB0ZWRFeGNlcHRpb24gew0KKw0KKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7DQorDQorICAgICAgICAvKioNCisgICAgICAgICAqIFByb21vdGUgYWNjZXNzLg0KKyAgICAgICAgICovDQorICAgICAgICBTdWJPZkllKCkgew0KKyAgICAgICAgfQ0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBTdWIgY2xhc3Mgb2YgaW50ZXJydXB0ZWQgSU8uDQorICAgICAqLw0KKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBTdWJPZklpb2UgZXh0ZW5kcyBJbnRlcnJ1cHRlZElPRXhjZXB0aW9uIHsNCisNCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOw0KKw0KKyAgICAgICAgLyoqDQorICAgICAgICAgKiBQcm9tb3RlIGFjY2Vzcy4NCisgICAgICAgICAqLw0KKyAgICAgICAgU3ViT2ZJaW9lKCkgew0KKyAgICAgICAgfQ0KKyAgICB9DQorDQorICAgIC8qKg0KKyAgICAgKiBTdWIgY2xhc3Mgb2YgdGhyZWFkIGRlYXRoLg0KKyAgICAgKi8NCisgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgU3ViT2ZUZCBleHRlbmRzIFRocmVhZERlYXRoIHsNCisNCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOw0KKw0KKyAgICAgICAgLyoqDQorICAgICAgICAgKiBQcm9tb3RlIGFjY2Vzcy4NCisgICAgICAgICAqLw0KKyAgICAgICAgU3ViT2ZUZCgpIHsNCisgICAgICAgIH0NCisgICAgfQ0KK30NCmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvamF2YXgvbWFpbC9VUkxOYW1lVGVzdC5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvVVJMTmFtZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNmVmODAwCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvVVJMTmFtZVRlc3QuamF2YQpAQCAtMCwwICsxLDc5IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDE0LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGphdmF4Lm1haWw7CisKK2ltcG9ydCBqYXZhLm5ldC5VUkw7CisKK2ltcG9ydCBvcmcuanVuaXQuKjsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRFcXVhbHM7CisKKy8qKgorICogVGVzdCB0aGUgVVJMTmFtZSBjbGFzcy4KKyAqCisgKiBYWFggLSBmb3Igbm93LCBqdXN0IHNvbWUgc2ltcGxlIHJlZ3Jlc3Npb24gdGVzdHMgZm9yIHJlcG9ydGVkIGJ1Z3MuCisgKi8KK3B1YmxpYyBjbGFzcyBVUkxOYW1lVGVzdCB7CisgCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UmVmbGV4aXZlRXF1YWxpdHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlVUkxOYW1lIHUgPSBuZXcgVVJMTmFtZSgidGVzdCIpOworCWFzc2VydEVxdWFscyh1LCB1KTsJLy8gYnVnIDYzNjUKKwl1ID0gbmV3IFVSTE5hbWUoImltYXA6Ly90ZXN0LmNvbS9JTkJPWCIpOworCWFzc2VydEVxdWFscyh1LCB1KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHRoYXQgdGhlIGdldEZpbGUgbWV0aG9kIHJldHVybnMgdGhlIGZpbGUgcGFydCAqd2l0aG91dCoKKyAgICAgKiB0aGUgc2VwYXJhdG9yIGNoYXJhY3Rlci4gIFRoaXMgYmVoYXZpb3IgaXMgZGlmZmVyZW50IHRoYW4gdGhlCisgICAgICogVVJMIG9yIFVSSSBjbGFzc2VzIGJ1dCBuZWVkcyB0byBiZSBwcmVzZXJ2ZWQgZm9yIGNvbXBhdGliaWxpdHkuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RmlsZSgpIHRocm93cyBFeGNlcHRpb24geworCVVSTE5hbWUgdSA9IG5ldyBVUkxOYW1lKCJodHRwOi8vaG9zdC9maWxlIik7CisJYXNzZXJ0RXF1YWxzKCJmaWxlIiwgdS5nZXRGaWxlKCkpOworCXUgPSBuZXcgVVJMTmFtZSgiaHR0cDovL2hvc3Q6MTIzL2ZpbGUiKTsKKwlhc3NlcnRFcXVhbHMoImZpbGUiLCB1LmdldEZpbGUoKSk7CisJdSA9IG5ldyBVUkxOYW1lKCJodHRwOi8vaG9zdC8iKTsKKwlhc3NlcnRFcXVhbHMoIiIsIHUuZ2V0RmlsZSgpKTsKKwl1ID0gbmV3IFVSTE5hbWUoImh0dHA6Ly9ob3N0Iik7CisJYXNzZXJ0RXF1YWxzKG51bGwsIHUuZ2V0RmlsZSgpKTsKKwl1ID0gbmV3IFVSTE5hbWUoImh0dHA6Ly9ob3N0OjEyMyIpOworCWFzc2VydEVxdWFscyhudWxsLCB1LmdldEZpbGUoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IHRoZSBnZXRVUkwgbWV0aG9kIHJldHVybnMgYSBVUkwgd2l0aCB0aGUgc2FtZSB2YWx1ZQorICAgICAqIGFzIHRoZSBVUkxOYW1lLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFVSTCgpIHRocm93cyBFeGNlcHRpb24geworCS8vIE5vdGU6IG11c3QgdXNlIGEgcHJvdG9jb2wgc3VwcG9ydGVkIGJ5IHRoZSBVUkwgY2xhc3MKKwlVUkxOYW1lIHUgPSBuZXcgVVJMTmFtZSgiaHR0cDovL2hvc3QvZmlsZSIpOworCWFzc2VydEVxdWFscygiZmlsZSIsIHUuZ2V0RmlsZSgpKTsKKwlVUkwgdXJsID0gdS5nZXRVUkwoKTsKKwlhc3NlcnRFcXVhbHModS50b1N0cmluZygpLCB1cmwudG9TdHJpbmcoKSk7CisJdSA9IG5ldyBVUkxOYW1lKCJodHRwOi8vaG9zdDoxMjMvZmlsZSIpOworCXVybCA9IHUuZ2V0VVJMKCk7CisJYXNzZXJ0RXF1YWxzKHUudG9TdHJpbmcoKSwgdXJsLnRvU3RyaW5nKCkpOworCXUgPSBuZXcgVVJMTmFtZSgiaHR0cDovL2hvc3Q6MTIzLyIpOworCXVybCA9IHUuZ2V0VVJMKCk7CisJYXNzZXJ0RXF1YWxzKHUudG9TdHJpbmcoKSwgdXJsLnRvU3RyaW5nKCkpOworCXUgPSBuZXcgVVJMTmFtZSgiaHR0cDovL2hvc3Q6MTIzIik7CisJdXJsID0gdS5nZXRVUkwoKTsKKwlhc3NlcnRFcXVhbHModS50b1N0cmluZygpLCB1cmwudG9TdHJpbmcoKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvQWRkQWRkcmVzc0hlYWRlclRlc3QuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L0FkZEFkZHJlc3NIZWFkZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjFkMzM3YwotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L0FkZEFkZHJlc3NIZWFkZXJUZXN0LmphdmEKQEAgLTAsMCArMSw4MSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAxMCwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsLmludGVybmV0OworCitpbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7CisKK2ltcG9ydCBqYXZheC5tYWlsLlNlc3Npb247CitpbXBvcnQgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YXgubWFpbC5NZXNzYWdlOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuTWltZU1lc3NhZ2U7CisKK2ltcG9ydCBvcmcuanVuaXQuKjsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRFcXVhbHM7CisKKy8qKgorICogVGVzdCB0aGF0ICJhZGQiIG1ldGhvZHMgZm9yIGFkZHJlc3MgaGVhZGVycyByZXN1bHQgaW4gb25seSBhIHNpbmdsZQorICogYWRkcmVzcyBoZWFkZXIsIHBlciBSRkMgMjgyMi4KKyAqLworcHVibGljIGNsYXNzIEFkZEFkZHJlc3NIZWFkZXJUZXN0IHsKKyAKKyAgICBwcml2YXRlIHN0YXRpYyBTZXNzaW9uIHMgPSBTZXNzaW9uLmdldEluc3RhbmNlKG5ldyBQcm9wZXJ0aWVzKCkpOworICAgIHByaXZhdGUgc3RhdGljIEludGVybmV0QWRkcmVzc1tdIHNldExpc3QgPSBuZXcgSW50ZXJuZXRBZGRyZXNzWzFdOworICAgIHByaXZhdGUgc3RhdGljIEludGVybmV0QWRkcmVzc1tdIGFkZExpc3QgPSBuZXcgSW50ZXJuZXRBZGRyZXNzWzFdOworCisgICAgc3RhdGljIHsKKwl0cnkgeworCSAgICBzZXRMaXN0WzBdID0gbmV3IEludGVybmV0QWRkcmVzcygibWVAZXhhbXBsZS5jb20iKTsKKwkgICAgYWRkTGlzdFswXSA9IG5ldyBJbnRlcm5ldEFkZHJlc3MoInlvdUBleGFtcGxlLmNvbSIpOworCX0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBleCkgeworCX0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RGcm9tKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1pbWVNZXNzYWdlIG0gPSBuZXcgTWltZU1lc3NhZ2Uocyk7CisJbS5zZXRGcm9tKHNldExpc3RbMF0pOworCW0uYWRkRnJvbShhZGRMaXN0KTsKKwltLnNhdmVDaGFuZ2VzKCk7CisJU3RyaW5nW10gaCA9IG0uZ2V0SGVhZGVyKCJGcm9tIik7CisJYXNzZXJ0RXF1YWxzKDEsIGgubGVuZ3RoKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RUbygpIHRocm93cyBFeGNlcHRpb24geworCXRlc3RSZWNpcGllbnRzKE1lc3NhZ2UuUmVjaXBpZW50VHlwZS5UTyk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2MoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwl0ZXN0UmVjaXBpZW50cyhNZXNzYWdlLlJlY2lwaWVudFR5cGUuQ0MpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEJjYygpIHRocm93cyBFeGNlcHRpb24geworCXRlc3RSZWNpcGllbnRzKE1lc3NhZ2UuUmVjaXBpZW50VHlwZS5CQ0MpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0UmVjaXBpZW50cyhNZXNzYWdlLlJlY2lwaWVudFR5cGUgdHlwZSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1pbWVNZXNzYWdlIG0gPSBuZXcgTWltZU1lc3NhZ2Uocyk7CisJbS5zZXRSZWNpcGllbnRzKHR5cGUsIHNldExpc3QpOworCW0uYWRkUmVjaXBpZW50cyh0eXBlLCBhZGRMaXN0KTsKKwltLnNhdmVDaGFuZ2VzKCk7CisJLy8gWFhYIC0gZGVwZW5kcyBvbiBSZWNpcGllbnRUeXBlLnRvU3RyaW5nCisJU3RyaW5nW10gaCA9IG0uZ2V0SGVhZGVyKHR5cGUudG9TdHJpbmcoKSk7CisJYXNzZXJ0RXF1YWxzKDEsIGgubGVuZ3RoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9BZGRGcm9tVGVzdC5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvQWRkRnJvbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMmE0OGVlCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvQWRkRnJvbVRlc3QuamF2YQpAQCAtMCwwICsxLDY2IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDEwLCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGphdmF4Lm1haWwuaW50ZXJuZXQ7CisKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKKworaW1wb3J0IGphdmF4Lm1haWwuU2Vzc2lvbjsKK2ltcG9ydCBqYXZheC5tYWlsLmludGVybmV0LkFkZHJlc3NFeGNlcHRpb247CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC5NaW1lTWVzc2FnZTsKKworaW1wb3J0IG9yZy5qdW5pdC4qOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEVxdWFsczsKKworLyoqCisgKiBUZXN0IHRoZSBNaW1lTXVsdGlwYXJ0LmFkZEZyb20gbWV0aG9kLCBmb3IgYnVnIDUwNTc3NDIuCisgKi8KK3B1YmxpYyBjbGFzcyBBZGRGcm9tVGVzdCB7CisgCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU2Vzc2lvbiBzID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShuZXcgUHJvcGVydGllcygpKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQUREUiA9ICJhQGV4YW1wbGUuY29tIjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBJbnRlcm5ldEFkZHJlc3MgaWFkZHI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgSW50ZXJuZXRBZGRyZXNzW10gYWRkcmVzc2VzOworICAgIHN0YXRpYyB7CisJSW50ZXJuZXRBZGRyZXNzIGlhID0gbnVsbDsKKwl0cnkgeworCSAgICBpYSA9IG5ldyBJbnRlcm5ldEFkZHJlc3MoQUREUik7CisJfSBjYXRjaCAoQWRkcmVzc0V4Y2VwdGlvbiBleCkgeworCSAgICAvLyBjYW4ndCBoYXBwZW4KKwl9IGZpbmFsbHkgeworCSAgICBpYWRkciA9IGlhOworCX0KKwlhZGRyZXNzZXMgPSBuZXcgSW50ZXJuZXRBZGRyZXNzW10geyBpYWRkciB9OworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdE5vRnJvbSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBNaW1lTWVzc2FnZSBtID0gbmV3IE1pbWVNZXNzYWdlKHMpOworCW0uYWRkRnJvbShhZGRyZXNzZXMpOworCWFzc2VydEVxdWFscygiTnVtYmVyIG9mIEZyb20gaGVhZGVycyIsIDEsIG0uZ2V0SGVhZGVyKCJGcm9tIikubGVuZ3RoKTsKKwlhc3NlcnRFcXVhbHMoIkZyb20gaGVhZGVyIiwgQUREUiwgbS5nZXRIZWFkZXIoIkZyb20iLCAiLCIpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RPbmVGcm9tKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1pbWVNZXNzYWdlIG0gPSBuZXcgTWltZU1lc3NhZ2Uocyk7CisJbS5zZXRGcm9tKGlhZGRyKTsKKwltLmFkZEZyb20oYWRkcmVzc2VzKTsKKwlhc3NlcnRFcXVhbHMoIk51bWJlciBvZiBGcm9tIGhlYWRlcnMiLCAxLCBtLmdldEhlYWRlcigiRnJvbSIpLmxlbmd0aCk7CisJYXNzZXJ0RXF1YWxzKCJGcm9tIGhlYWRlciIsIEFERFIgKyAiLCAiICsgQUREUiwKKwkgICAgbS5nZXRIZWFkZXIoIkZyb20iLCAiLCIpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9BbGxvd0VuY29kZWRNZXNzYWdlcy5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvQWxsb3dFbmNvZGVkTWVzc2FnZXMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YjlmOTBhCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvQWxsb3dFbmNvZGVkTWVzc2FnZXMuamF2YQpAQCAtMCwwICsxLDgwIEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDEwLCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGphdmF4Lm1haWwuaW50ZXJuZXQ7CisKK2ltcG9ydCBjb20uc3VuLm1haWwudGVzdC5Bc2NpaVN0cmluZ0lucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0OworaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOworCitpbXBvcnQgamF2YXgubWFpbC5TZXNzaW9uOworaW1wb3J0IGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uOworaW1wb3J0IGphdmF4Lm1haWwuQm9keVBhcnQ7CisKK2ltcG9ydCBvcmcuanVuaXQuKjsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRFcXVhbHM7CisKKy8qKgorICogVGVzdCAibWFpbC5taW1lLmFsbG93ZW5jb2RlZG1lc3NhZ2VzIiBTeXN0ZW0gcHJvcGVydHkuCisgKi8KK3B1YmxpYyBjbGFzcyBBbGxvd0VuY29kZWRNZXNzYWdlcyB7CisgCisgICAgcHJpdmF0ZSBzdGF0aWMgU2Vzc2lvbiBzID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShuZXcgUHJvcGVydGllcygpKTsKKworICAgIEBCZWZvcmVDbGFzcworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBiZWZvcmUoKSB7CisJU3lzdGVtLm91dC5wcmludGxuKCJBbGxvd0VuY29kZWRNZXNzYWdlcyIpOworCVN5c3RlbS5zZXRQcm9wZXJ0eSgibWFpbC5taW1lLmFsbG93ZW5jb2RlZG1lc3NhZ2VzIiwgInRydWUiKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RFbmNvZGVkTWVzc2FnZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTWltZU1lc3NhZ2UgbSA9IGNyZWF0ZU1lc3NhZ2UoKTsKKwlNaW1lTXVsdGlwYXJ0IG1wID0gKE1pbWVNdWx0aXBhcnQpbS5nZXRDb250ZW50KCk7CisJQm9keVBhcnQgYnAgPSBtcC5nZXRCb2R5UGFydCgwKTsKKwlhc3NlcnRFcXVhbHMoIm1lc3NhZ2UvcmZjODIyIiwgYnAuZ2V0Q29udGVudFR5cGUoKSk7CisKKwlNaW1lTWVzc2FnZSBtMiA9IChNaW1lTWVzc2FnZSlicC5nZXRDb250ZW50KCk7CisJYXNzZXJ0RXF1YWxzKCJ0ZXh0L3BsYWluIiwgbTIuZ2V0Q29udGVudFR5cGUoKSk7CisJYXNzZXJ0RXF1YWxzKCJ0ZXN0IG1lc3NhZ2VcclxuIiwgbTIuZ2V0Q29udGVudCgpKTsKKyAgICB9CisKKyAgICBAQWZ0ZXJDbGFzcworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBhZnRlcigpIHsKKwkvLyBzaG91bGQgYmUgdW5uZWNlc3NhcnkKKwlTeXN0ZW0uY2xlYXJQcm9wZXJ0eSgibWFpbC5taW1lLmFsbG93ZW5jb2RlZG1lc3NhZ2VzIik7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgTWltZU1lc3NhZ2UgY3JlYXRlTWVzc2FnZSgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgY29udGVudCA9CisJICAgICJNaW1lLVZlcnNpb246IDEuMFxuIiArCisJICAgICJTdWJqZWN0OiBFeGFtcGxlXG4iICsKKwkgICAgIkNvbnRlbnQtVHlwZTogbXVsdGlwYXJ0L21peGVkOyBib3VuZGFyeT1cIi1cIlxuIiArCisJICAgICJcbiIgKworCSAgICAiLS0tXG4iICsKKwkgICAgIkNvbnRlbnQtVHlwZTogbWVzc2FnZS9yZmM4MjJcbiIgKworCSAgICAiQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogYmFzZTY0XG4iICsKKwkgICAgIlxuIiArCisJICAgICJUV2x0WlMxV1pYSnphVzl1T2lBeExqQU5DbE4xWW1wbFkzUTZJSCIgKworCSAgICAiUmxjM1FOQ2tOdmJuUmxiblF0Vkhsd1pUb2dkR1Y0ZEM5d2JHRnBcbiIgKworCSAgICAiYmcwS0RRcDBaWE4wSUcxbGMzTmhaMlVOQ2c9PVxuIiArCisJICAgICJcbiIgKworCSAgICAiLS0tLS1cbiI7CisKKwlyZXR1cm4gbmV3IE1pbWVNZXNzYWdlKHMsIG5ldyBBc2NpaVN0cmluZ0lucHV0U3RyZWFtKGNvbnRlbnQpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9BcHBsZUZpbGVOYW1lcy5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvQXBwbGVGaWxlTmFtZXMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ZDZkNDc3Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvQXBwbGVGaWxlTmFtZXMuamF2YQpAQCAtMCwwICsxLDQ1IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDA5LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGphdmF4Lm1haWwuaW50ZXJuZXQ7CisKK2ltcG9ydCBvcmcuanVuaXQuKjsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRFcXVhbHM7CisKKy8qKgorICogVGVzdCB0aGF0IHRoZSAibWFpbC5taW1lLmFwcGxlZmlsZW5hbWVzIiBTeXN0ZW0gcHJvcGVydHkKKyAqIGNhdXNlcyB0aGUgZmlsZW5hbWUgdG8gYmUgcmV0dXJuZWQgcHJvcGVybHkuCisgKi8KK3B1YmxpYyBjbGFzcyBBcHBsZUZpbGVOYW1lcyB7CisKKyAgICBAQmVmb3JlQ2xhc3MKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgYmVmb3JlKCkgeworCVN5c3RlbS5vdXQucHJpbnRsbigiQXBwbGVGaWxlTmFtZXMiKTsKKwlTeXN0ZW0uc2V0UHJvcGVydHkoIm1haWwubWltZS5hcHBsZWZpbGVuYW1lcyIsICJ0cnVlIik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UHJvcCgpIHRocm93cyBFeGNlcHRpb24geworCVBhcmFtZXRlckxpc3QgcGwgPSBuZXcgUGFyYW1ldGVyTGlzdCgiOyBmaWxlbmFtZT1hIGIudHh0Iik7CisJYXNzZXJ0RXF1YWxzKHBsLmdldCgiZmlsZW5hbWUiKSwgImEgYi50eHQiKTsKKyAgICB9CisKKyAgICBAQWZ0ZXJDbGFzcworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBhZnRlcigpIHsKKwkvLyBzaG91bGQgYmUgdW5uZWNlc3NhcnkKKwlTeXN0ZW0uY2xlYXJQcm9wZXJ0eSgibWFpbC5taW1lLmFwcGxlZmlsZW5hbWVzIik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvQ29udGVudERpc3Bvc2l0aW9uTm9TdHJpY3QuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L0NvbnRlbnREaXNwb3NpdGlvbk5vU3RyaWN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzkyMGQzYwotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L0NvbnRlbnREaXNwb3NpdGlvbk5vU3RyaWN0LmphdmEKQEAgLTAsMCArMSw1OCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwOSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsLmludGVybmV0OworCitpbXBvcnQgb3JnLmp1bml0Lio7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0TnVsbDsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5mYWlsOworCisvKioKKyAqIFRlc3QgdGhlIHByb3BlcnR5IHRoYXQgY29udG9scyBDb250ZW50RGlzcG9zaXRpb24gbm9uLXN0cmljdCBtb2RlCisgKi8KK3B1YmxpYyBjbGFzcyBDb250ZW50RGlzcG9zaXRpb25Ob1N0cmljdCB7CisKKyAgICBAQmVmb3JlQ2xhc3MKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgYmVmb3JlKCkgeworICAgICAgICBTeXN0ZW0uc2V0UHJvcGVydHkoIm1haWwubWltZS5jb250ZW50ZGlzcG9zaXRpb24uc3RyaWN0IiwgImZhbHNlIik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVjb2RlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDb250ZW50RGlzcG9zaXRpb24gY2QgPSBuZXcgQ29udGVudERpc3Bvc2l0aW9uKCJcIi9ub24vc3RhbmRhcmQvc3R1ZmYvaGVyZS5jc3ZcIiIpOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiQ29udGVudCBkaXNwb3NpdGlvbiBtdXN0IHBhcnNlIHRvIG51bGwgaW4gbm9uLXN0cmljdCBtb2RlIiwgY2QuZ2V0RGlzcG9zaXRpb24oKSk7CisgICAgICAgIH0gY2F0Y2ggKFBhcnNlRXhjZXB0aW9uIHB4KSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gbXVzdCBub3QgYmUgdGhyb3duIGluIG5vbi1zdHJpY3QgbW9kZSIpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVjb2RlV2l0aFBhcmFtcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICB0cnkgeworICAgICAgICAgICAgQ29udGVudERpc3Bvc2l0aW9uIGNkID0gbmV3IENvbnRlbnREaXNwb3NpdGlvbigiIDsgc2l6ZT0xMjM0NSIpOworICAgICAgICAgICAgYXNzZXJ0TnVsbCgiQ29udGVudCBkaXNwb3NpdGlvbiBtdXN0IHBhcnNlIHRvIG51bGwgaW4gbm9uLXN0cmljdCBtb2RlIiwgY2QuZ2V0RGlzcG9zaXRpb24oKSk7CisgICAgICAgIH0gY2F0Y2ggKFBhcnNlRXhjZXB0aW9uIHB4KSB7CisgICAgICAgICAgICBmYWlsKCJFeGNlcHRpb24gbXVzdCBub3QgYmUgdGhyb3duIGluIG5vbi1zdHJpY3QgbW9kZSIpOworICAgICAgICB9CisgICAgfQorCisgICAgQEFmdGVyQ2xhc3MKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgYWZ0ZXIoKSB7CisgICAgICAgIFN5c3RlbS5jbGVhclByb3BlcnR5KCJtYWlsLm1pbWUuY29udGVudGRpc3Bvc2l0aW9uLnN0cmljdCIpOworICAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvQ29udGVudERpc3Bvc2l0aW9uU3RyaWN0LmphdmEgYi9tYWlsL3NyYy90ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9Db250ZW50RGlzcG9zaXRpb25TdHJpY3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hNDFlZmU1Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvQ29udGVudERpc3Bvc2l0aW9uU3RyaWN0LmphdmEKQEAgLTAsMCArMSw0OCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwOSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsLmludGVybmV0OworCitpbXBvcnQgb3JnLmp1bml0Lio7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0TnVsbDsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5mYWlsOworCisvKioKKyAqIFRlc3QgdGhlIHByb3BlcnR5IHRoYXQgY29udG9scyBDb250ZW50RGlzcG9zaXRpb24gbm9uLXN0cmljdCBtb2RlCisgKi8KK3B1YmxpYyBjbGFzcyBDb250ZW50RGlzcG9zaXRpb25TdHJpY3QgeworCisgICAgQEJlZm9yZUNsYXNzCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGJlZm9yZSgpIHsKKyAgICAgICAgU3lzdGVtLnNldFByb3BlcnR5KCJtYWlsLm1pbWUuY29udGVudGRpc3Bvc2l0aW9uLnN0cmljdCIsICJ0cnVlIik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RGVjb2RlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBDb250ZW50RGlzcG9zaXRpb24gY2QgPSBuZXcgQ29udGVudERpc3Bvc2l0aW9uKCJcIi9ub24vc3RhbmRhcmQvc3R1ZmYvaGVyZS5jc3ZcIiIpOworICAgICAgICAgICAgZmFpbCgiUGFyc2VFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biBvbiBtYWxmb3JtZWQgY29udGVudCBkaXNwb3NpdGlvbiIpOworICAgICAgICB9IGNhdGNoIChQYXJzZUV4Y2VwdGlvbiBleHBlY3RlZCkgeworICAgICAgICAgICAgLy8gdGhlIGV4Y2VwdGlvbiBpcyB0aGUgZXhwZWN0ZWQgb3V0Y29tZSBpbiB0aGlzIHRlc3QKKyAgICAgICAgfQorICAgIH0KKworICAgIEBBZnRlckNsYXNzCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGFmdGVyKCkgeworICAgICAgICBTeXN0ZW0uY2xlYXJQcm9wZXJ0eSgibWFpbC5taW1lLmNvbnRlbnRkaXNwb3NpdGlvbi5zdHJpY3QiKTsKKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L0NvbnRlbnREaXNwb3NpdGlvblRlc3RTdWl0ZS5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvQ29udGVudERpc3Bvc2l0aW9uVGVzdFN1aXRlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTNjY2Y1YgotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L0NvbnRlbnREaXNwb3NpdGlvblRlc3RTdWl0ZS5qYXZhCkBAIC0wLDAgKzEsMzUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDksIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5pbnRlcm5ldDsKKworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVycy5TdWl0ZS5TdWl0ZUNsYXNzZXM7CisKK2ltcG9ydCBjb20uc3VuLm1haWwudGVzdC5DbGFzc0xvYWRlclN1aXRlOworaW1wb3J0IGNvbS5zdW4ubWFpbC50ZXN0LkNsYXNzTG9hZGVyU3VpdGUuVGVzdENsYXNzOworCisvKioKKyAqIFN1aXRlIG9mIFBhcmFtZXRlckxpc3QgdGVzdHMgdGhhdCBuZWVkIHRvIGJlIHJ1biBpbiBhIHNlcGFyYXRlIGNsYXNzIGxvYWRlci4KKyAqLworQFJ1bldpdGgoQ2xhc3NMb2FkZXJTdWl0ZS5jbGFzcykKK0BUZXN0Q2xhc3MoQ29udGVudERpc3Bvc2l0aW9uLmNsYXNzKQorQFN1aXRlQ2xhc3NlcyggeworICAgIENvbnRlbnREaXNwb3NpdGlvbk5vU3RyaWN0LmNsYXNzLAorICAgIENvbnRlbnREaXNwb3NpdGlvblN0cmljdC5jbGFzcworfSkKK3B1YmxpYyBjbGFzcyBDb250ZW50RGlzcG9zaXRpb25UZXN0U3VpdGUgeworfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvQ29udGVudFR5cGVUZXN0LmphdmEgYi9tYWlsL3NyYy90ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9Db250ZW50VHlwZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNGU4NzM1Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvQ29udGVudFR5cGVUZXN0LmphdmEKQEAgLTAsMCArMSw0MyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAxNCwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsLmludGVybmV0OworCitpbXBvcnQgb3JnLmp1bml0Lio7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VHJ1ZTsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRGYWxzZTsKKworLyoqCisgKiBUZXN0IHRoZSBDb250ZW50VHlwZSBjbGFzcy4KKyAqCisgKiBYWFggLSBmb3Igbm93LCBqdXN0IHNvbWUgc2ltcGxlIHJlZ3Jlc3Npb24gdGVzdHMgZm9yIHJlcG9ydGVkIGJ1Z3MuCisgKi8KK3B1YmxpYyBjbGFzcyBDb250ZW50VHlwZVRlc3QgeworIAorICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdE1hdGNoKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJQ29udGVudFR5cGUgZW1wdHkgPSBuZXcgQ29udGVudFR5cGUoKTsKKwlhc3NlcnRGYWxzZShlbXB0eS5tYXRjaCgidGV4dC9wbGFpbiIpKTsKKwlDb250ZW50VHlwZSBwbGFpbiA9IG5ldyBDb250ZW50VHlwZSgidGV4dC9wbGFpbiIpOworCWFzc2VydFRydWUocGxhaW4ubWF0Y2goInRleHQvcGxhaW4iKSk7CisJYXNzZXJ0RmFsc2UoZW1wdHkubWF0Y2gocGxhaW4pKTsKKwlhc3NlcnRGYWxzZShwbGFpbi5tYXRjaChlbXB0eSkpOworCWFzc2VydFRydWUocGxhaW4ubWF0Y2goInRleHQvKiIpKTsKKwlDb250ZW50VHlwZSB0ZXh0ID0gbmV3IENvbnRlbnRUeXBlKCJ0ZXh0LyoiKTsKKwlhc3NlcnRUcnVlKHRleHQubWF0Y2gocGxhaW4pKTsKKwlhc3NlcnRUcnVlKHBsYWluLm1hdGNoKHRleHQpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9EZWNvZGVQYXJhbWV0ZXJzLmphdmEgYi9tYWlsL3NyYy90ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9EZWNvZGVQYXJhbWV0ZXJzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzc0ZDU4NwotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L0RlY29kZVBhcmFtZXRlcnMuamF2YQpAQCAtMCwwICsxLDQ0IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDEwLCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGphdmF4Lm1haWwuaW50ZXJuZXQ7CisKK2ltcG9ydCBvcmcuanVuaXQuKjsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRFcXVhbHM7CisKKy8qKgorICogVGVzdCB0aGF0IHRoZSAibWFpbC5taW1lLmRlY29kZXBhcmFtZXRlcnMiIFN5c3RlbSBwcm9wZXJ0eQorICogY2F1c2VzIHRoZSBwYXJhbWV0ZXJzIHRvIGJlIHByb3Blcmx5IGRlY29kZWQuCisgKi8KK3B1YmxpYyBjbGFzcyBEZWNvZGVQYXJhbWV0ZXJzIGV4dGVuZHMgUGFyYW1ldGVyTGlzdERlY29kZSB7CisKKyAgICBAQmVmb3JlQ2xhc3MKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgYmVmb3JlKCkgeworCVN5c3RlbS5vdXQucHJpbnRsbigiRGVjb2RlUGFyYW1ldGVycyIpOworCVN5c3RlbS5zZXRQcm9wZXJ0eSgibWFpbC5taW1lLmRlY29kZXBhcmFtZXRlcnMiLCAidHJ1ZSIpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdERlY29kZSgpIHRocm93cyBFeGNlcHRpb24geworCXRlc3REZWNvZGUoInBhcmFtZGF0YSIpOworICAgIH0KKworICAgIEBBZnRlckNsYXNzCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGFmdGVyKCkgeworCS8vIHNob3VsZCBiZSB1bm5lY2Vzc2FyeQorCVN5c3RlbS5jbGVhclByb3BlcnR5KCJtYWlsLm1pbWUuZGVjb2RlcGFyYW1ldGVycyIpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L0VuY29kZUZpbGVOYW1lLmphdmEgYi9tYWlsL3NyYy90ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9FbmNvZGVGaWxlTmFtZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYzMzFiYTAKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy90ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9FbmNvZGVGaWxlTmFtZS5qYXZhCkBAIC0wLDAgKzEsNjkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMTUsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5pbnRlcm5ldDsKKworaW1wb3J0IGphdmF4Lm1haWwuTWVzc2FnaW5nRXhjZXB0aW9uOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuTWltZUJvZHlQYXJ0OworCitpbXBvcnQgb3JnLmp1bml0Lio7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VHJ1ZTsKKworLyoqCisgKiBUZXN0ICJtYWlsLm1pbWUuZW5jb2RlZmlsZW5hbWUiIFN5c3RlbSBwcm9wZXJ0eSBzZXQuCisgKi8KK3B1YmxpYyBjbGFzcyBFbmNvZGVGaWxlTmFtZSBleHRlbmRzIE5vRW5jb2RlRmlsZU5hbWUgeworIAorICAgIC8vIGRlcGVuZHMgb24gZXhhY3RseSBob3cgTWltZVV0aWxpdHkuZW5jb2RlVGV4dCBzcGxpdHMgbG9uZyB3b3JkcworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBleHBlY3RlZDEgPQorCSI9P3V0Zi04P0I/dzRERGdjT0Z3NGJEZ01PQnc0WERoc09IdzRqRGljT0t3NHZEak1PTnc0N0RqOE9RdzRERGdjT0Y/PSI7CisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGV4cGVjdGVkMiA9CisJIj0/dXRmLTg/Qj93NGJEaDhPSXc0bkRpc09MdzR6RGpjT093NC9Ea01PUnc1TERrOE9VdzVYRGxzT1l3NW5EbXNPYnc1dz0/PSI7CisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGV4cGVjdGVkMyA9CisJIj0/dXRmLTg/Qj93NTNEbnNPZnc2RERvY09pdzZQRHBNT2x3NmJEcDhPb3c2bkRxc09ydzZ6RHJjT3V3Ni9Ec01PeD89IjsKKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZXhwZWN0ZWQ0ID0KKwkiPT91dGYtOD9CP3c3TERzOE8wdzdYRHRzTzR3N25EdXNPN3c3ekR2Y08rdzcvRGdNT0J3NFhEaHNPSExtUnZZdz09Pz0iOworCisgICAgQEJlZm9yZUNsYXNzCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGJlZm9yZSgpIHsKKwlTeXN0ZW0ub3V0LnByaW50bG4oIkVuY29kZUZpbGVOYW1lIik7CisJU3lzdGVtLnNldFByb3BlcnR5KCJtYWlsLm1pbWUuY2hhcnNldCIsICJ1dGYtOCIpOworCVN5c3RlbS5zZXRQcm9wZXJ0eSgibWFpbC5taW1lLmVuY29kZWZpbGVuYW1lIiwgInRydWUiKTsKKwkvLyBhc3N1bWUgbWFpbC5taW1lLmVuY29kZXBhcmFtdGVycyBkZWZhdWx0cyB0byB0cnVlCisJU3lzdGVtLmNsZWFyUHJvcGVydHkoIm1haWwubWltZS5lbmNvZGVwYXJhbXRlcnMiKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHRlc3QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlNaW1lQm9keVBhcnQgbWJwID0gbmV3IE1pbWVCb2R5UGFydCgpOworCW1icC5zZXRUZXh0KCJ0ZXN0Iik7CisJbWJwLnNldEZpbGVOYW1lKGZpbGVOYW1lKTsKKwltYnAudXBkYXRlSGVhZGVycygpOworCVN0cmluZyBoID0gbWJwLmdldEhlYWRlcigiQ29udGVudC1UeXBlIiwgIiIpOworCWFzc2VydFRydWUoaC5jb250YWlucygibmFtZT0iKSk7CisJYXNzZXJ0VHJ1ZShoLmNvbnRhaW5zKGV4cGVjdGVkMSkpOworCWFzc2VydFRydWUoaC5jb250YWlucyhleHBlY3RlZDIpKTsKKwlhc3NlcnRUcnVlKGguY29udGFpbnMoZXhwZWN0ZWQzKSk7CisJYXNzZXJ0VHJ1ZShoLmNvbnRhaW5zKGV4cGVjdGVkNCkpOworCWggPSBtYnAuZ2V0SGVhZGVyKCJDb250ZW50LURpc3Bvc2l0aW9uIiwgIiIpOworCWFzc2VydFRydWUoaC5jb250YWlucygiZmlsZW5hbWU9IikpOworCWFzc2VydFRydWUoaC5jb250YWlucyhleHBlY3RlZDEpKTsKKwlhc3NlcnRUcnVlKGguY29udGFpbnMoZXhwZWN0ZWQyKSk7CisJYXNzZXJ0VHJ1ZShoLmNvbnRhaW5zKGV4cGVjdGVkMykpOworCWFzc2VydFRydWUoaC5jb250YWlucyhleHBlY3RlZDQpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9FbmNvZGVGaWxlTmFtZU5vRW5jb2RlUGFyYW1ldGVycy5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvRW5jb2RlRmlsZU5hbWVOb0VuY29kZVBhcmFtZXRlcnMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZGIwOGFmCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvRW5jb2RlRmlsZU5hbWVOb0VuY29kZVBhcmFtZXRlcnMuamF2YQpAQCAtMCwwICsxLDM0IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDE1LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGphdmF4Lm1haWwuaW50ZXJuZXQ7CisKK2ltcG9ydCBvcmcuanVuaXQuKjsKKworLyoqCisgKiBUZXN0ICJtYWlsLm1pbWUuZW5jb2RlZmlsZW5hbWUiIFN5c3RlbSBwcm9wZXJ0eSBzZXQgdG8gInRydWUiCisgKiBhbmQgIm1haWwubWltZS5lbmNvZGVwYXJhbWV0ZXJzIiBzZXQgdG8gImZhbHNlIi4KKyAqLworcHVibGljIGNsYXNzIEVuY29kZUZpbGVOYW1lTm9FbmNvZGVQYXJhbWV0ZXJzIGV4dGVuZHMgRW5jb2RlRmlsZU5hbWUgeworIAorICAgIEBCZWZvcmVDbGFzcworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBiZWZvcmUoKSB7CisJU3lzdGVtLm91dC5wcmludGxuKCJFbmNvZGVGaWxlTmFtZU5vRW5jb2RlUGFyYW1ldGVycyIpOworCVN5c3RlbS5zZXRQcm9wZXJ0eSgibWFpbC5taW1lLmNoYXJzZXQiLCAidXRmLTgiKTsKKwlTeXN0ZW0uc2V0UHJvcGVydHkoIm1haWwubWltZS5lbmNvZGVmaWxlbmFtZSIsICJ0cnVlIik7CisJU3lzdGVtLnNldFByb3BlcnR5KCJtYWlsLm1pbWUuZW5jb2RlcGFyYW10ZXJzIiwgImZhbHNlIik7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvRm9sZFRlc3QuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L0ZvbGRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzlmNDlkOAotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L0ZvbGRUZXN0LmphdmEKQEAgLTAsMCArMSwxMTAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5pbnRlcm5ldDsKKworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBqYXZheC5tYWlsLmludGVybmV0Lk1pbWVVdGlsaXR5OworCitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LkFzc2VydDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVyLlJ1bldpdGg7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lcnMuUGFyYW1ldGVyaXplZDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVycy5QYXJhbWV0ZXJpemVkLlBhcmFtZXRlcnM7CisKKy8qKgorICogVGVzdCBoZWFkZXIgZm9sZGluZy4KKyAqCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCisKK0BSdW5XaXRoKFBhcmFtZXRlcml6ZWQuY2xhc3MpCitwdWJsaWMgY2xhc3MgRm9sZFRlc3QgeworICAgIHByaXZhdGUgU3RyaW5nIGRpcmVjdGlvbjsKKyAgICBwcml2YXRlIFN0cmluZyBvcmlnOworICAgIHByaXZhdGUgU3RyaW5nIGV4cGVjdDsKKworICAgIHByaXZhdGUgc3RhdGljIExpc3Q8T2JqZWN0W10+IHRlc3REYXRhOworCisgICAgcHVibGljIEZvbGRUZXN0KFN0cmluZyBkaXJlY3Rpb24sIFN0cmluZyBvcmlnLCBTdHJpbmcgZXhwZWN0KSB7CisJdGhpcy5kaXJlY3Rpb24gPSBkaXJlY3Rpb247CisJdGhpcy5vcmlnID0gb3JpZzsKKwl0aGlzLmV4cGVjdCA9IGV4cGVjdDsKKyAgICB9CisKKyAgICBAUGFyYW1ldGVycworICAgIHB1YmxpYyBzdGF0aWMgQ29sbGVjdGlvbjxPYmplY3RbXT4gZGF0YSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJdGVzdERhdGEgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKwlwYXJzZShuZXcgQnVmZmVyZWRSZWFkZXIobmV3IElucHV0U3RyZWFtUmVhZGVyKAorCSAgICBGb2xkVGVzdC5jbGFzcy5nZXRSZXNvdXJjZUFzU3RyZWFtKCJmb2xkZGF0YSIpKSkpOworCXJldHVybiB0ZXN0RGF0YTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkIHRoZSBkYXRhIGZyb20gdGhlIHRlc3QgZmlsZS4gIEZvcm1hdCBpcyBtdWx0aXBsZSBvZiBhbnkgb2YKKyAgICAgKiB0aGUgZm9sbG93aW5nOgorICAgICAqCisgICAgICogRk9MRFxuU3RyaW5nJFxuRVhQRUNUXG5TdHJpbmckXG4KKyAgICAgKiBVTkZPTERcblN0cmluZyRcbkVYUEVDVFxuU3RyaW5nJFxuCisgICAgICogQk9USFxuU3RyaW5nJFxuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBwYXJzZShCdWZmZXJlZFJlYWRlciBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlTdHJpbmcgbGluZTsKKwl3aGlsZSAoKGxpbmUgPSBpbi5yZWFkTGluZSgpKSAhPSBudWxsKSB7CisJICAgIGlmIChsaW5lLnN0YXJ0c1dpdGgoIiMiKSB8fCBsaW5lLmxlbmd0aCgpID09IDApCisJCWNvbnRpbnVlOworCSAgICBTdHJpbmcgb3JpZyA9IHJlYWRTdHJpbmcoaW4pOworCSAgICBpZiAobGluZS5lcXVhbHMoIkJPVEgiKSkgeworCQl0ZXN0RGF0YS5hZGQobmV3IE9iamVjdFtdIHsgbGluZSwgb3JpZywgbnVsbCB9KTsKKwkgICAgfSBlbHNlIHsKKwkJU3RyaW5nIGUgPSBpbi5yZWFkTGluZSgpOworCQlpZiAoIWUuZXF1YWxzKCJFWFBFQ1QiKSkKKwkJICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiVEVTVCBEQVRBIEZPUk1BVCBFUlJPUiIpOworCQlTdHJpbmcgZXhwZWN0ID0gcmVhZFN0cmluZyhpbik7CisJCXRlc3REYXRhLmFkZChuZXcgT2JqZWN0W10geyBsaW5lLCBvcmlnLCBleHBlY3QgfSk7CisJICAgIH0KKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZCBhIHN0cmluZyB0aGF0IGVuZHMgd2l0aCAnJCcsIHByZXNlcnZpbmcgYWxsIGNoYXJhY3RlcnMsCisgICAgICogZXNwZWNpYWxseSBpbmNsdWRpbmcgQ1IgYW5kIExGLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyByZWFkU3RyaW5nKEJ1ZmZlcmVkUmVhZGVyIGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworCVN0cmluZ0J1ZmZlciBzYiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKwlpbnQgYzsKKwl3aGlsZSAoKGMgPSBpbi5yZWFkKCkpICE9ICckJykKKwkgICAgc2IuYXBwZW5kKChjaGFyKWMpOworCWluLnJlYWRMaW5lKCk7CS8vIHRocm93IGF3YXkgcmVzdCBvZiBsaW5lCisJcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9sZCgpIHsKKwlpZiAoZGlyZWN0aW9uLmVxdWFscygiQk9USCIpKSB7CisJICAgIFN0cmluZyBmcyA9IE1pbWVVdGlsaXR5LmZvbGQoMCwgb3JpZyk7CisJICAgIFN0cmluZyB1cyA9IE1pbWVVdGlsaXR5LnVuZm9sZChmcyk7CisJICAgIEFzc2VydC5hc3NlcnRFcXVhbHMob3JpZywgdXMpOworCX0gZWxzZSBpZiAoZGlyZWN0aW9uLmVxdWFscygiRk9MRCIpKSB7CisJICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIkZvbGQiLCBleHBlY3QsIE1pbWVVdGlsaXR5LmZvbGQoMCwgb3JpZykpOworCX0gZWxzZSBpZiAoZGlyZWN0aW9uLmVxdWFscygiVU5GT0xEIikpIHsKKwkgICAgQXNzZXJ0LmFzc2VydEVxdWFscygiVW5mb2xkIiwgZXhwZWN0LCBNaW1lVXRpbGl0eS51bmZvbGQob3JpZykpOworCX0gZWxzZSB7CisJICAgIEFzc2VydC5mYWlsKCJVbmtub3duIGRpcmVjdGlvbjogIiArIGRpcmVjdGlvbik7CisJfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L0dldExvY2FsQWRkcmVzc1Rlc3QuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L0dldExvY2FsQWRkcmVzc1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hNDQzMmU0Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvR2V0TG9jYWxBZGRyZXNzVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTA5IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDEwLCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGphdmF4Lm1haWwuaW50ZXJuZXQ7CisKK2ltcG9ydCBqYXZhLm5ldC5JbmV0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5ldC5Vbmtub3duSG9zdEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKKworaW1wb3J0IGphdmF4Lm1haWwuU2Vzc2lvbjsKK2ltcG9ydCBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5tYWlsLmludGVybmV0LkludGVybmV0QWRkcmVzczsKKworaW1wb3J0IG9yZy5qdW5pdC4qOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEVxdWFsczsKKworLyoqCisgKiBUZXN0IHRoZSBJbnRlcm5ldEFkZHJlc3MuZ2V0TG9jYWxBZGRyZXNzKCkgbWV0aG9kLgorICovCitwdWJsaWMgY2xhc3MgR2V0TG9jYWxBZGRyZXNzVGVzdCB7CisgCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGxvY2FsaG9zdDsKKyAgICBzdGF0aWMgeworCXRyeSB7CisJICAgIGxvY2FsaG9zdCA9IEluZXRBZGRyZXNzLmdldExvY2FsSG9zdCgpLmdldENhbm9uaWNhbEhvc3ROYW1lKCk7CisJfSBjYXRjaCAoVW5rbm93bkhvc3RFeGNlcHRpb24gZXgpIHsKKwkgICAgbG9jYWxob3N0ID0gImxvY2FsaG9zdCI7CisJfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFVzZXJOYW1lKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJU3lzdGVtLnNldFByb3BlcnR5KCJ1c2VyLm5hbWUiLCAiSm9lIik7CisJSW50ZXJuZXRBZGRyZXNzIGlhID0gSW50ZXJuZXRBZGRyZXNzLmdldExvY2FsQWRkcmVzcyhudWxsKTsKKwlhc3NlcnRFcXVhbHMoIkpvZUAiICsgbG9jYWxob3N0LCBpYS5nZXRBZGRyZXNzKCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFVzZXJOYW1lU2Vzc2lvbigpIHRocm93cyBFeGNlcHRpb24geworCVN5c3RlbS5zZXRQcm9wZXJ0eSgidXNlci5uYW1lIiwgIkpvZSIpOworCVNlc3Npb24gcyA9IFNlc3Npb24uZ2V0SW5zdGFuY2UobmV3IFByb3BlcnRpZXMoKSk7CisJSW50ZXJuZXRBZGRyZXNzIGlhID0gSW50ZXJuZXRBZGRyZXNzLmdldExvY2FsQWRkcmVzcyhzKTsKKwlhc3NlcnRFcXVhbHMoIkpvZUAiICsgbG9jYWxob3N0LCBpYS5nZXRBZGRyZXNzKCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdE1haWxGcm9tKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJU3lzdGVtLnNldFByb3BlcnR5KCJ1c2VyLm5hbWUiLCAiSm9lIik7CisJUHJvcGVydGllcyBwID0gbmV3IFByb3BlcnRpZXMoKTsKKwlwLnNldFByb3BlcnR5KCJtYWlsLmZyb20iLCAiQm9iQGhvbWUiKTsKKwlTZXNzaW9uIHMgPSBTZXNzaW9uLmdldEluc3RhbmNlKHApOworCUludGVybmV0QWRkcmVzcyBpYSA9IEludGVybmV0QWRkcmVzcy5nZXRMb2NhbEFkZHJlc3Mocyk7CisJYXNzZXJ0RXF1YWxzKCJCb2JAaG9tZSIsIGlhLmdldEFkZHJlc3MoKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWFpbEZyb21BZGRyZXNzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJU3lzdGVtLnNldFByb3BlcnR5KCJ1c2VyLm5hbWUiLCAiSm9lIik7CisJUHJvcGVydGllcyBwID0gbmV3IFByb3BlcnRpZXMoKTsKKwlwLnNldFByb3BlcnR5KCJtYWlsLmZyb20iLCAiQm9iIDxCb2JAaG9tZT4iKTsKKwlTZXNzaW9uIHMgPSBTZXNzaW9uLmdldEluc3RhbmNlKHApOworCUludGVybmV0QWRkcmVzcyBpYSA9IEludGVybmV0QWRkcmVzcy5nZXRMb2NhbEFkZHJlc3Mocyk7CisJYXNzZXJ0RXF1YWxzKCJCb2JAaG9tZSIsIGlhLmdldEFkZHJlc3MoKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWFpbFVzZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlTeXN0ZW0uc2V0UHJvcGVydHkoInVzZXIubmFtZSIsICJKb2UiKTsKKwlQcm9wZXJ0aWVzIHAgPSBuZXcgUHJvcGVydGllcygpOworCXAuc2V0UHJvcGVydHkoIm1haWwudXNlciIsICJCb2IiKTsKKwlTZXNzaW9uIHMgPSBTZXNzaW9uLmdldEluc3RhbmNlKHApOworCUludGVybmV0QWRkcmVzcyBpYSA9IEludGVybmV0QWRkcmVzcy5nZXRMb2NhbEFkZHJlc3Mocyk7CisJYXNzZXJ0RXF1YWxzKCJCb2JAIiArIGxvY2FsaG9zdCwgaWEuZ2V0QWRkcmVzcygpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RNYWlsVXNlclNwYWNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJU3lzdGVtLnNldFByb3BlcnR5KCJ1c2VyLm5hbWUiLCAiSm9lIik7CisJUHJvcGVydGllcyBwID0gbmV3IFByb3BlcnRpZXMoKTsKKwlwLnNldFByb3BlcnR5KCJtYWlsLnVzZXIiLCAiTkVUV09SSyBTRVJWSUNFIik7CisJU2Vzc2lvbiBzID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShwKTsKKwlJbnRlcm5ldEFkZHJlc3MgaWEgPSBJbnRlcm5ldEFkZHJlc3MuZ2V0TG9jYWxBZGRyZXNzKHMpOworCWFzc2VydEVxdWFscygiXCJORVRXT1JLIFNFUlZJQ0VcIkAiICsgbG9jYWxob3N0LCBpYS5nZXRBZGRyZXNzKCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdE1haWxIb3N0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJU3lzdGVtLnNldFByb3BlcnR5KCJ1c2VyLm5hbWUiLCAiSm9lIik7CisJUHJvcGVydGllcyBwID0gbmV3IFByb3BlcnRpZXMoKTsKKwlwLnNldFByb3BlcnR5KCJtYWlsLnVzZXIiLCAiQm9iIik7CisJcC5zZXRQcm9wZXJ0eSgibWFpbC5ob3N0IiwgImhvbWUiKTsKKwlTZXNzaW9uIHMgPSBTZXNzaW9uLmdldEluc3RhbmNlKHApOworCUludGVybmV0QWRkcmVzcyBpYSA9IEludGVybmV0QWRkcmVzcy5nZXRMb2NhbEFkZHJlc3Mocyk7CisJYXNzZXJ0RXF1YWxzKCJCb2JAaG9tZSIsIGlhLmdldEFkZHJlc3MoKSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvSGVhZGVyVG9rZW5pemVyVGVzdC5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvSGVhZGVyVG9rZW5pemVyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjEyYzEwODYKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy90ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9IZWFkZXJUb2tlbml6ZXJUZXN0LmphdmEKQEAgLTAsMCArMSwzMTYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5pbnRlcm5ldDsKKworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBqYXZheC5tYWlsLio7CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC5IZWFkZXJUb2tlbml6ZXI7CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC5QYXJzZUV4Y2VwdGlvbjsKKworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5Bc3NlcnQ7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXJzLlBhcmFtZXRlcml6ZWQ7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lcnMuUGFyYW1ldGVyaXplZC5QYXJhbWV0ZXJzOworCisvKioKKyAqIFRlc3QgTUlNRSBIZWFkZXJUb2tlbml6ZXIuCisgKgorICogQGF1dGhvciBCaWxsIFNoYW5ub24KKyAqLworCitAUnVuV2l0aChQYXJhbWV0ZXJpemVkLmNsYXNzKQorcHVibGljIGNsYXNzIEhlYWRlclRva2VuaXplclRlc3QgeworICAgIHByaXZhdGUgU3RyaW5nIGhlYWRlcjsKKyAgICBwcml2YXRlIFN0cmluZyB2YWx1ZTsKKyAgICBwcml2YXRlIFN0cmluZ1tdIGV4cGVjdDsKKworICAgIHN0YXRpYyBib29sZWFuIGdlbl90ZXN0X2lucHV0ID0gZmFsc2U7CS8vIG91dHB1dCBnb29kIGZvciBpbnB1dCB0byAtcAorICAgIHN0YXRpYyBib29sZWFuIHBhcnNlX21haWwgPSBmYWxzZTsJCS8vIHBhcnNlIGlucHV0IGluIG1haWwgZm9ybWF0CisgICAgc3RhdGljIGJvb2xlYW4gcmV0dXJuX2NvbW1lbnRzID0gZmFsc2U7CS8vIHJldHVybiBjb21tZW50cyBhcyB0b2tlbnMKKyAgICBzdGF0aWMgYm9vbGVhbiBtaW1lID0gZmFsc2U7CQkvLyB1c2UgTUlNRSBzcGVjaWFscworICAgIHN0YXRpYyBpbnQgZXJyb3JzID0gMDsJCQkvLyBudW1iZXIgb2YgZXJyb3JzIGRldGVjdGVkCisKKyAgICBzdGF0aWMgYm9vbGVhbiBqdW5pdDsKKyAgICBzdGF0aWMgTGlzdDxPYmplY3RbXT4gdGVzdERhdGE7CisKKyAgICBwdWJsaWMgSGVhZGVyVG9rZW5pemVyVGVzdChTdHJpbmcgaGVkZXIsIFN0cmluZyB2YWx1ZSwgU3RyaW5nW10gZXhwZWN0KSB7CisJdGhpcy5oZWFkZXIgPSBoZWFkZXI7CisJdGhpcy52YWx1ZSA9IHZhbHVlOworCXRoaXMuZXhwZWN0ID0gZXhwZWN0OworICAgIH0KKworICAgIEBQYXJhbWV0ZXJzCisgICAgcHVibGljIHN0YXRpYyBDb2xsZWN0aW9uPE9iamVjdFtdPiBkYXRhKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlqdW5pdCA9IHRydWU7CisJdGVzdERhdGEgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKwlwYXJzZShuZXcgQnVmZmVyZWRSZWFkZXIobmV3IElucHV0U3RyZWFtUmVhZGVyKAorCSAgICBJbnRlcm5ldEFkZHJlc3NUZXN0LmNsYXNzLmdldFJlc291cmNlQXNTdHJlYW0oInRva2VubGlzdCIpKSkpOworCXJldHVybiB0ZXN0RGF0YTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3QoKSB7CisJdGVzdChoZWFkZXIsIHZhbHVlLCBleHBlY3QpOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZyBhcmd2W10pIHRocm93cyBFeGNlcHRpb24geworCWludCBvcHRpbmQ7CisJZm9yIChvcHRpbmQgPSAwOyBvcHRpbmQgPCBhcmd2Lmxlbmd0aDsgb3B0aW5kKyspIHsKKwkgICAgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi0iKSkgeworCQkvLyBpZ25vcmUKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItZyIpKSB7CisJCWdlbl90ZXN0X2lucHV0ID0gdHJ1ZTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItcCIpKSB7CisJCXBhcnNlX21haWwgPSB0cnVlOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1jIikpIHsKKwkJcmV0dXJuX2NvbW1lbnRzID0gdHJ1ZTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItbSIpKSB7CisJCW1pbWUgPSB0cnVlOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi0tIikpIHsKKwkJb3B0aW5kKys7CisJCWJyZWFrOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5zdGFydHNXaXRoKCItIikpIHsKKwkJU3lzdGVtLm91dC5wcmludGxuKAorCQkgICAgIlVzYWdlOiB0b2tlbml6ZXJ0ZXN0IFstZ10gWy1wXSBbLWNdIFstbV0gWy1dIFtoZWFkZXIgLi4uXSIpOworCQlTeXN0ZW0uZXhpdCgxKTsKKwkgICAgfSBlbHNlIHsKKwkJYnJlYWs7CisJICAgIH0KKwl9CisKKwkvKgorCSAqIElmIHRoZXJlJ3MgYW55IGFyZ3MgbGVmdCBvbiB0aGUgY29tbWFuZCBsaW5lLAorCSAqIGNvbmNhdGVuYXRlIHRoZW0gaW50byBhIHN0cmluZyBhbmQgdGVzdCB0aGF0LgorCSAqLworCWlmIChvcHRpbmQgPCBhcmd2Lmxlbmd0aCkgeworCSAgICBTdHJpbmdCdWZmZXIgc2IgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CisJICAgIGZvciAoaW50IGkgPSBvcHRpbmQ7IGkgPCBhcmd2Lmxlbmd0aDsgaSsrKSB7CisJCXNiLmFwcGVuZChhcmd2W2ldKTsKKwkJc2IuYXBwZW5kKCIgIik7CisJICAgIH0KKwkgICAgdGVzdCgiVG8iLCBzYi50b1N0cmluZygpLCBudWxsKTsKKwl9IGVsc2UgeworCSAgICAvLyByZWFkIGZyb20gc3RkaW4KKwkgICAgQnVmZmVyZWRSZWFkZXIgaW4gPQorCQluZXcgQnVmZmVyZWRSZWFkZXIobmV3IElucHV0U3RyZWFtUmVhZGVyKFN5c3RlbS5pbikpOworCSAgICBTdHJpbmcgczsKKworCSAgICBpZiAocGFyc2VfbWFpbCkKKwkJcGFyc2UoaW4pOworCSAgICBlbHNlIHsKKwkJd2hpbGUgKChzID0gaW4ucmVhZExpbmUoKSkgIT0gbnVsbCkKKwkJICAgIHRlc3QoIlRvIiwgcywgbnVsbCk7CisJICAgIH0KKwl9CisJU3lzdGVtLmV4aXQoZXJyb3JzKTsKKworICAgIH0KKworICAgIC8qCisgICAgICogUGFyc2UgdGhlIGlucHV0IGluICJtYWlsIiBmb3JtYXQsIGV4dHJhY3RpbmcgdGhlIEZyb20sIFRvLCBhbmQgQ2MKKyAgICAgKiBoZWFkZXJzIGFuZCB0ZXN0aW5nIHRoZW0uICBUaGUgcGFyc2UgaXMgcmF0aGVyIGNydWRlLCBidXQgc3VmZmljaWVudAorICAgICAqIHRvIHRlc3QgYWdhaW5zdCBtb3N0IGV4aXN0aW5nIFVOSVggbWFpbGJveGVzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBwYXJzZShCdWZmZXJlZFJlYWRlciBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlTdHJpbmcgaGVhZGVyID0gIiI7CisKKwlmb3IgKDs7KSB7CisJICAgIFN0cmluZyBzID0gaW4ucmVhZExpbmUoKTsKKwkgICAgaWYgKHMgIT0gbnVsbCAmJiBzLmxlbmd0aCgpID4gMCkgeworCQljaGFyIGMgPSBzLmNoYXJBdCgwKTsKKwkJaWYgKGMgPT0gJyAnIHx8IGMgPT0gJ1x0JykgeworCQkgICAgLy8gYSBjb250aW51YXRpb24gbGluZSwgYWRkIGl0IHRvIHRoZSBjdXJyZW50IGhlYWRlcgorCQkgICAgaGVhZGVyICs9ICdcbicgKyBzOworCQkgICAgY29udGludWU7CisJCX0KKwkgICAgfQorCSAgICAvLyAicyIgaXMgdGhlIG5leHQgaGVhZGVyLCAiaGVhZGVyIiBpcyB0aGUgbGFzdCBjb21wbGV0ZSBoZWFkZXIKKwkgICAgaWYgKGhlYWRlci5zdGFydHNXaXRoKCJGcm9tOiAiKSB8fAorCQkgICAgaGVhZGVyLnN0YXJ0c1dpdGgoIlRvOiAiKSB8fAorCQkgICAgaGVhZGVyLnN0YXJ0c1dpdGgoIkNjOiAiKSkgeworCQlpbnQgaTsKKwkJU3RyaW5nW10gZXhwZWN0ID0gbnVsbDsKKwkJaWYgKHMgIT0gbnVsbCAmJiBzLnN0YXJ0c1dpdGgoIkV4cGVjdDogIikpIHsKKwkJICAgIHRyeSB7CisJCQlpbnQgbmV4cGVjdCA9IEludGVnZXIucGFyc2VJbnQocy5zdWJzdHJpbmcoOCkpOworCQkJZXhwZWN0ID0gbmV3IFN0cmluZ1tuZXhwZWN0XTsKKwkJCWZvciAoaSA9IDA7IGkgPCBuZXhwZWN0OyBpKyspCisJCQkgICAgZXhwZWN0W2ldID0gaW4ucmVhZExpbmUoKS50cmltKCk7CisJCSAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgeworCQkJdHJ5IHsKKwkJCSAgICBpZiAocy5zdWJzdHJpbmcoOCwgMTcpLmVxdWFscygiRXhjZXB0aW9uIikpIHsKKwkJCQlleHBlY3QgPSBuZXcgU3RyaW5nWzFdOworCQkJCWV4cGVjdFswXSA9ICJFeGNlcHRpb24iOworCQkJICAgIH0KKwkJCX0gY2F0Y2ggKFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gc2UpIHsKKwkJCSAgICAvLyBpZ25vcmUgaXQKKwkJCX0KKwkJICAgIH0KKwkJfQorCQlpID0gaGVhZGVyLmluZGV4T2YoJzonKTsKKwkJdHJ5IHsKKwkJICAgIGlmIChqdW5pdCkKKwkJCXRlc3REYXRhLmFkZChuZXcgT2JqZWN0W10geworCQkJICAgIGhlYWRlci5zdWJzdHJpbmcoMCwgaSksCisJCQkgICAgaGVhZGVyLnN1YnN0cmluZyhpICsgMiksCisJCQkgICAgZXhwZWN0IH0pOworCQkgICAgZWxzZQorCQkJdGVzdChoZWFkZXIuc3Vic3RyaW5nKDAsIGkpLCBoZWFkZXIuc3Vic3RyaW5nKGkgKyAyKSwKKwkJCSAgICBleHBlY3QpOworCQl9IGNhdGNoIChTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKwkJICAgIC8vIGlnbm9yZQorCQl9CisJICAgIH0KKwkgICAgaWYgKHMgPT0gbnVsbCkKKwkJcmV0dXJuOwkJLy8gRU9GCisJICAgIGlmIChzLmxlbmd0aCgpID09IDApIHsKKwkJd2hpbGUgKChzID0gaW4ucmVhZExpbmUoKSkgIT0gbnVsbCkgeworCQkgICAgaWYgKHMuc3RhcnRzV2l0aCgiRnJvbSAiKSkKKwkJCWJyZWFrOworCQl9CisJCWlmIChzID09IG51bGwpCisJCSAgICByZXR1cm47CisJICAgIH0KKwkgICAgaGVhZGVyID0gczsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGUgaGVhZGVyJ3MgdmFsdWUgdG8gc2VlIGlmIHdlIGNhbiB0b2tlbml6ZSBpdCBhcyBleHBlY3RlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgdGVzdChTdHJpbmcgaGVhZGVyLCBTdHJpbmcgdmFsdWUsIFN0cmluZyBleHBlY3RbXSkgeworCVByaW50U3RyZWFtIG91dCA9IFN5c3RlbS5vdXQ7CisJaWYgKGdlbl90ZXN0X2lucHV0KQorCSAgICBvdXQucHJpbnRsbihoZWFkZXIgKyAiOiAiICsgdmFsdWUpOworCWVsc2UgaWYgKCFqdW5pdCkKKwkgICAgb3V0LnByaW50bG4oIlRlc3Q6ICIgKyB2YWx1ZSk7CisKKwl0cnkgeworCSAgICBIZWFkZXJUb2tlbml6ZXIgaHQgPSBuZXcgSGVhZGVyVG9rZW5pemVyKHZhbHVlLAorCQkJbWltZSA/IEhlYWRlclRva2VuaXplci5NSU1FIDogSGVhZGVyVG9rZW5pemVyLlJGQzgyMiwKKwkJCSFyZXR1cm5fY29tbWVudHMpOworCSAgICBIZWFkZXJUb2tlbml6ZXIuVG9rZW4gdG9rOworCSAgICBWZWN0b3I8SGVhZGVyVG9rZW5pemVyLlRva2VuPiB0b2tsaXN0CisJCSAgICA9IG5ldyBWZWN0b3I8PigpOworCSAgICB3aGlsZSAoKHRvayA9IGh0Lm5leHQoKSkuZ2V0VHlwZSgpICE9IEhlYWRlclRva2VuaXplci5Ub2tlbi5FT0YpCisJCXRva2xpc3QuYWRkRWxlbWVudCh0b2spOworCSAgICBpZiAoZ2VuX3Rlc3RfaW5wdXQpCisJCW91dC5wcmludGxuKCJFeHBlY3Q6ICIgKyB0b2tsaXN0LnNpemUoKSk7CisJICAgIGVsc2UgeworCQlpZiAoanVuaXQpIHsKKwkJICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIk51bWJlciBvZiB0b2tlbnMiLAorCQkJZXhwZWN0Lmxlbmd0aCwgdG9rbGlzdC5zaXplKCkpOworCQl9IGVsc2UgeworCQkgICAgb3V0LnByaW50bG4oIkdvdCAiICsgdG9rbGlzdC5zaXplKCkgKyAiIHRva2VuczoiKTsKKwkJICAgIGlmIChleHBlY3QgIT0gbnVsbCAmJiB0b2tsaXN0LnNpemUoKSAhPSBleHBlY3QubGVuZ3RoKSB7CisJCQlvdXQucHJpbnRsbigiRXhwZWN0ZWQgIiArIGV4cGVjdC5sZW5ndGggKyAiIHRva2VucyIpOworCQkJZXJyb3JzKys7CisJCSAgICB9CisJCX0KKwkgICAgfQorCSAgICBmb3IgKGludCBpID0gMDsgaSA8IHRva2xpc3Quc2l6ZSgpOyBpKyspIHsKKwkJdG9rID0gdG9rbGlzdC5lbGVtZW50QXQoaSk7CisJCWlmIChnZW5fdGVzdF9pbnB1dCkKKwkJICAgIG91dC5wcmludGxuKCJcdCIgKyB0eXBlKHRvay5nZXRUeXBlKCkpICsKKwkJCQkJCSJcdCIgKyB0b2suZ2V0VmFsdWUoKSk7CisJCWVsc2UgeworCQkgICAgaWYgKCFqdW5pdCkKKwkJCW91dC5wcmludGxuKCJcdFsiICsgKGkrMSkgKyAiXSAiICsgdHlwZSh0b2suZ2V0VHlwZSgpKSArCisJCQkJCQkiXHQiICsgdG9rLmdldFZhbHVlKCkpOworCQkgICAgaWYgKGV4cGVjdCAhPSBudWxsICYmIGkgPCBleHBlY3QubGVuZ3RoKSB7CisJCQlIZWFkZXJUb2tlbml6ZXIuVG9rZW4gdCA9IG1ha2VUb2tlbihleHBlY3RbaV0pOworCQkJaWYgKGp1bml0KSB7CisJCQkgICAgQXNzZXJ0LmFzc2VydEVxdWFscygiVG9rZW4gdHlwZSIsCisJCQkJdC5nZXRUeXBlKCksIHRvay5nZXRUeXBlKCkpOworCQkJICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoIlRva2VuIHZhbHVlIiwKKwkJCQl0LmdldFZhbHVlKCksIHRvay5nZXRWYWx1ZSgpKTsKKwkJCX0gZWxzZSB7CisJCQkgICAgaWYgKHQuZ2V0VHlwZSgpICE9IHRvay5nZXRUeXBlKCkgfHwKKwkJCQkhdC5nZXRWYWx1ZSgpLmVxdWFscyh0b2suZ2V0VmFsdWUoKSkpIHsKKwkJCQlvdXQucHJpbnRsbigiXHRFeHBlY3RlZDpcdCIgKworCQkJCSAgICB0eXBlKHQuZ2V0VHlwZSgpKSArICJcdCIgKyB0LmdldFZhbHVlKCkpOworCQkJCWVycm9ycysrOworCQkJICAgIH0KKwkJCX0KKwkJICAgIH0KKwkJfQorCSAgICB9CisJfSBjYXRjaCAoUGFyc2VFeGNlcHRpb24gZSkgeworCSAgICBpZiAoZ2VuX3Rlc3RfaW5wdXQpCisJCW91dC5wcmludGxuKCJFeHBlY3Q6IEV4Y2VwdGlvbiAiICsgZSk7CisJICAgIGVsc2UgeworCQlpZiAoanVuaXQpIHsKKwkJICAgIEFzc2VydC5hc3NlcnRUcnVlKCJFeHBlY3RlZCBleGNlcHRpb24iLAorCQkJZXhwZWN0Lmxlbmd0aCA9PSAxICYmIGV4cGVjdFswXS5lcXVhbHMoIkV4Y2VwdGlvbiIpKTsKKwkJfSBlbHNlIHsKKwkJICAgIG91dC5wcmludGxuKCJHb3QgRXhjZXB0aW9uOiAiICsgZSk7CisJCSAgICBpZiAoZXhwZWN0ICE9IG51bGwgJiYKKwkJICAgICAgIChleHBlY3QubGVuZ3RoICE9IDEgfHwgIWV4cGVjdFswXS5lcXVhbHMoIkV4Y2VwdGlvbiIpKSkgeworCQkJb3V0LnByaW50bG4oIkV4cGVjdGVkICIgKyBleHBlY3QubGVuZ3RoICsgIiB0b2tlbnMiKTsKKwkJCWZvciAoaW50IGkgPSAwOyBpIDwgZXhwZWN0Lmxlbmd0aDsgaSsrKQorCQkJICAgIG91dC5wcmludGxuKCJcdEV4cGVjdGVkOlx0IiArIGV4cGVjdFtpXSk7CisJCQllcnJvcnMrKzsKKwkJICAgIH0KKwkJfQorCSAgICB9CisJfQorICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyB0eXBlKGludCB0KSB7CisJaWYgKHQgPT0gSGVhZGVyVG9rZW5pemVyLlRva2VuLkFUT00pCisJICAgIHJldHVybiAiQVRPTSI7CisJZWxzZSBpZiAodCA9PSBIZWFkZXJUb2tlbml6ZXIuVG9rZW4uUVVPVEVEU1RSSU5HKQorCSAgICByZXR1cm4gIlFVT1RFRFNUUklORyI7CisJZWxzZSBpZiAodCA9PSBIZWFkZXJUb2tlbml6ZXIuVG9rZW4uQ09NTUVOVCkKKwkgICAgcmV0dXJuICJDT01NRU5UIjsKKwllbHNlIGlmICh0ID09IEhlYWRlclRva2VuaXplci5Ub2tlbi5FT0YpCisJICAgIHJldHVybiAiRU9GIjsKKwllbHNlIGlmICh0IDwgMCkKKwkgICAgcmV0dXJuICJVTktOT1dOIjsKKwllbHNlCisJICAgIHJldHVybiAiU1BFQ0lBTCI7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgaW50IHR5cGUoU3RyaW5nIHMpIHsKKwlpZiAocy5lcXVhbHMoIkFUT00iKSkKKwkgICAgcmV0dXJuIEhlYWRlclRva2VuaXplci5Ub2tlbi5BVE9NOworCWVsc2UgaWYgKHMuZXF1YWxzKCJRVU9URURTVFJJTkciKSkKKwkgICAgcmV0dXJuIEhlYWRlclRva2VuaXplci5Ub2tlbi5RVU9URURTVFJJTkc7CisJZWxzZSBpZiAocy5lcXVhbHMoIkNPTU1FTlQiKSkKKwkgICAgcmV0dXJuIEhlYWRlclRva2VuaXplci5Ub2tlbi5DT01NRU5UOworCWVsc2UgaWYgKHMuZXF1YWxzKCJFT0YiKSkKKwkgICAgcmV0dXJuIEhlYWRlclRva2VuaXplci5Ub2tlbi5FT0Y7CisJZWxzZSAvLyBpZiAocy5lcXVhbHMoIlNQRUNJQUwiKSkKKwkgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgSGVhZGVyVG9rZW5pemVyLlRva2VuIG1ha2VUb2tlbihTdHJpbmcgbGluZSkgeworCWludCBpID0gbGluZS5pbmRleE9mKCdcdCcpOworCWludCB0ID0gdHlwZShsaW5lLnN1YnN0cmluZygwLCBpKSk7CisJU3RyaW5nIHZhbHVlID0gbGluZS5zdWJzdHJpbmcoaSArIDEpOworCWlmICh0ID09IDApCisJICAgIHJldHVybiBuZXcgSGVhZGVyVG9rZW5pemVyLlRva2VuKHZhbHVlLmNoYXJBdCgwKSwgdmFsdWUpOworCWVsc2UKKwkgICAgcmV0dXJuIG5ldyBIZWFkZXJUb2tlbml6ZXIuVG9rZW4odCwgdmFsdWUpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBuKFN0cmluZyBzKSB7CisJcmV0dXJuIHMgPT0gbnVsbCA/ICI8bnVsbD4iIDogczsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9JbnRlcm5ldEFkZHJlc3NFeHRyYVRlc3QuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L0ludGVybmV0QWRkcmVzc0V4dHJhVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBmMmZhNzMKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy90ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9JbnRlcm5ldEFkZHJlc3NFeHRyYVRlc3QuamF2YQpAQCAtMCwwICsxLDYzIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGphdmF4Lm1haWwuaW50ZXJuZXQ7CisKK2ltcG9ydCBqYXZheC5tYWlsLmludGVybmV0LkludGVybmV0QWRkcmVzczsKK2ltcG9ydCBqYXZheC5tYWlsLmludGVybmV0LkFkZHJlc3NFeGNlcHRpb247CisKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmZhaWw7CisKKy8qKgorICogVGVzdCBJbnRlcm5ldCBhZGRyZXNzIHBhcnNpbmcgdGhhdCBjYW4ndCBiZSB0ZXN0ZWQgdXNpbmcgcGFyYW10ZXJpemVkIHRlc3QuCisgKgorICogQGF1dGhvciBCaWxsIFNoYW5ub24KKyAqLworCitwdWJsaWMgY2xhc3MgSW50ZXJuZXRBZGRyZXNzRXh0cmFUZXN0IHsKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3ROZXdsaW5lSW5Eb21haW5MaXRlcmFsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJSW50ZXJuZXRBZGRyZXNzIGlhID0gbmV3IEludGVybmV0QWRkcmVzcygidGVzdEBbXHJcbmZvb10iLCAidGVzdCIpOworCXRyeSB7CisJICAgIGlhLnZhbGlkYXRlKCk7CisJICAgIGZhaWwoInZhbGlkYXRpb24gc3VjY2VlZGVkIik7CisJfSBjYXRjaCAoQWRkcmVzc0V4Y2VwdGlvbiBleCkgeworCSAgICAvLyBzdWNjZXNzIQorCX0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3ROZXdsaW5lSW5Mb2NhbCgpIHRocm93cyBFeGNlcHRpb24geworCUludGVybmV0QWRkcmVzcyBpYSA9CisJICAgIG5ldyBJbnRlcm5ldEFkZHJlc3MoIlwidGVzdFxyXG5mb29cIkBleGFtcGxlLmNvbSIsICJ0ZXN0Iik7CisJdHJ5IHsKKwkgICAgaWEudmFsaWRhdGUoKTsKKwkgICAgZmFpbCgidmFsaWRhdGlvbiBzdWNjZWVkZWQiKTsKKwl9IGNhdGNoIChBZGRyZXNzRXhjZXB0aW9uIGV4KSB7CisJICAgIC8vIHN1Y2Nlc3MhCisJfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdE5ld2xpbmVJbkxvY2FsV2l0aFdoaXRlc3BhY2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlJbnRlcm5ldEFkZHJlc3MgaWEgPQorCSAgICBuZXcgSW50ZXJuZXRBZGRyZXNzKCJcInRlc3RcclxuIGZvb1wiQGV4YW1wbGUuY29tIiwgInRlc3QiKTsKKwlpYS52YWxpZGF0ZSgpOworCS8vIHN1Y2Nlc3MhCisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvSW50ZXJuZXRBZGRyZXNzRm9sZFRlc3QuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L0ludGVybmV0QWRkcmVzc0ZvbGRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDI3MDgyMgotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L0ludGVybmV0QWRkcmVzc0ZvbGRUZXN0LmphdmEKQEAgLTAsMCArMSwxMDEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5pbnRlcm5ldDsKKworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBqYXZheC5tYWlsLmludGVybmV0LkludGVybmV0QWRkcmVzczsKKworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5Bc3NlcnQ7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXJzLlBhcmFtZXRlcml6ZWQ7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lcnMuUGFyYW1ldGVyaXplZC5QYXJhbWV0ZXJzOworCisvKioKKyAqIFRlc3QgSW50ZXJuZXRBZGRyZXNzIGZvbGRpbmcuCisgKgorICogQGF1dGhvciBCaWxsIFNoYW5ub24KKyAqLworCitAUnVuV2l0aChQYXJhbWV0ZXJpemVkLmNsYXNzKQorcHVibGljIGNsYXNzIEludGVybmV0QWRkcmVzc0ZvbGRUZXN0IHsKKyAgICBwcml2YXRlIEludGVybmV0QWRkcmVzc1tdIG9yaWc7CisgICAgcHJpdmF0ZSBTdHJpbmcgZXhwZWN0OworCisgICAgcHJpdmF0ZSBzdGF0aWMgTGlzdDxPYmplY3RbXT4gdGVzdERhdGE7CisKKyAgICBwdWJsaWMgSW50ZXJuZXRBZGRyZXNzRm9sZFRlc3QoSW50ZXJuZXRBZGRyZXNzW10gb3JpZywgU3RyaW5nIGV4cGVjdCkgeworCXRoaXMub3JpZyA9IG9yaWc7CisJdGhpcy5leHBlY3QgPSBleHBlY3Q7CisgICAgfQorCisgICAgQFBhcmFtZXRlcnMKKyAgICBwdWJsaWMgc3RhdGljIENvbGxlY3Rpb248T2JqZWN0W10+IGRhdGEoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwl0ZXN0RGF0YSA9IG5ldyBBcnJheUxpc3Q8PigpOworCXBhcnNlKG5ldyBCdWZmZXJlZFJlYWRlcihuZXcgSW5wdXRTdHJlYW1SZWFkZXIoCisJICAgIEludGVybmV0QWRkcmVzc0ZvbGRUZXN0LmNsYXNzLmdldFJlc291cmNlQXNTdHJlYW0oImFkZHJmb2xkZGF0YSIpKSkpOworCXJldHVybiB0ZXN0RGF0YTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkIHRoZSBkYXRhIGZyb20gdGhlIHRlc3QgZmlsZS4gIEZvcm1hdCBpczoKKyAgICAgKgorICAgICAqIEZPTEQgTgorICAgICAqIGFkZHJlc3MxJAorICAgICAqIC4uLgorICAgICAqIGFkZHJlc3NOJAorICAgICAqIEVYUEVDVAorICAgICAqIGFkZHJlc3MxLCAuLi4sIGFkZHJlc3NOJAorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgcGFyc2UoQnVmZmVyZWRSZWFkZXIgaW4pIHRocm93cyBFeGNlcHRpb24geworCVN0cmluZyBsaW5lOworCXdoaWxlICgobGluZSA9IGluLnJlYWRMaW5lKCkpICE9IG51bGwpIHsKKwkgICAgaWYgKGxpbmUuc3RhcnRzV2l0aCgiIyIpIHx8IGxpbmUubGVuZ3RoKCkgPT0gMCkKKwkJY29udGludWU7CisJICAgIGlmICghbGluZS5zdGFydHNXaXRoKCJGT0xEIikpCisJCXRocm93IG5ldyBJT0V4Y2VwdGlvbigiVEVTVCBEQVRBIEZPUk1BVCBFUlJPUiwgTUlTU0lORyBGT0xEIik7CisJICAgIGludCBjb3VudCA9IEludGVnZXIucGFyc2VJbnQobGluZS5zdWJzdHJpbmcoNSkpOworCSAgICBJbnRlcm5ldEFkZHJlc3NbXSBvcmlnID0gbmV3IEludGVybmV0QWRkcmVzc1tjb3VudF07CisJICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykKKwkJb3JpZ1tpXSA9IG5ldyBJbnRlcm5ldEFkZHJlc3MocmVhZFN0cmluZyhpbikpOworCSAgICBTdHJpbmcgZSA9IGluLnJlYWRMaW5lKCk7CisJICAgIGlmICghZS5lcXVhbHMoIkVYUEVDVCIpKQorCQl0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlRFU1QgREFUQSBGT1JNQVQgRVJST1IsIE1JU1NJTkcgRVhQRUNUIik7CisJICAgIFN0cmluZyBleHBlY3QgPSByZWFkU3RyaW5nKGluKTsKKwkgICAgdGVzdERhdGEuYWRkKG5ldyBPYmplY3RbXSB7IG9yaWcsIGV4cGVjdCB9KTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZCBhIHN0cmluZyB0aGF0IGVuZHMgd2l0aCAnJCcsIHByZXNlcnZpbmcgYWxsIGNoYXJhY3RlcnMsCisgICAgICogZXNwZWNpYWxseSBpbmNsdWRpbmcgQ1IgYW5kIExGLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyByZWFkU3RyaW5nKEJ1ZmZlcmVkUmVhZGVyIGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworCVN0cmluZ0J1ZmZlciBzYiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKwlpbnQgYzsKKwl3aGlsZSAoKGMgPSBpbi5yZWFkKCkpICE9ICckJykKKwkgICAgc2IuYXBwZW5kKChjaGFyKWMpOworCWluLnJlYWRMaW5lKCk7CS8vIHRocm93IGF3YXkgcmVzdCBvZiBsaW5lCisJcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9sZCgpIHsKKwlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJGb2xkIiwgZXhwZWN0LCBJbnRlcm5ldEFkZHJlc3MudG9TdHJpbmcob3JpZywgMCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L0ludGVybmV0QWRkcmVzc1Rlc3QuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L0ludGVybmV0QWRkcmVzc1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YzVmNzUzCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvSW50ZXJuZXRBZGRyZXNzVGVzdC5qYXZhCkBAIC0wLDAgKzEsMzgwIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGphdmF4Lm1haWwuaW50ZXJuZXQ7CisKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YS51dGlsLio7CitpbXBvcnQgamF2YXgubWFpbC4qOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuSW50ZXJuZXRBZGRyZXNzOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuQWRkcmVzc0V4Y2VwdGlvbjsKKworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5Bc3NlcnQ7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXJzLlBhcmFtZXRlcml6ZWQ7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lcnMuUGFyYW1ldGVyaXplZC5QYXJhbWV0ZXJzOworCisvKioKKyAqIFRlc3QgSW50ZXJuZXQgYWRkcmVzcyBwYXJzaW5nLgorICoKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKi8KKworQFJ1bldpdGgoUGFyYW1ldGVyaXplZC5jbGFzcykKK3B1YmxpYyBjbGFzcyBJbnRlcm5ldEFkZHJlc3NUZXN0IHsKKyAgICBwcml2YXRlIFN0cmluZyBoZWFkZXJOYW1lOworICAgIHByaXZhdGUgU3RyaW5nIGhlYWRlclZhbHVlOworICAgIHByaXZhdGUgU3RyaW5nW10gZXhwZWN0ZWQ7CisgICAgcHJpdmF0ZSBib29sZWFuIGRvU3RyaWN0OworICAgIHByaXZhdGUgYm9vbGVhbiBkb1BhcnNlSGVhZGVyOworCisgICAgc3RhdGljIGJvb2xlYW4gc3RyaWN0ID0gZmFsc2U7CQkvLyBlbmZvcmNlIHN0cmljdCBSRkM4MjIgc3ludGF4CisgICAgc3RhdGljIGJvb2xlYW4gZ2VuX3Rlc3RfaW5wdXQgPSBmYWxzZTsJLy8gb3V0cHV0IGdvb2QgZm9yIGlucHV0IHRvIC1wCisgICAgc3RhdGljIGJvb2xlYW4gcGFyc2VfbWFpbCA9IGZhbHNlOwkJLy8gcGFyc2UgaW5wdXQgaW4gbWFpbCBmb3JtYXQKKyAgICBzdGF0aWMgYm9vbGVhbiBwYXJzZV9oZWFkZXIgPSBmYWxzZTsJLy8gdXNlIHBhcnNlSGVhZGVyIG1ldGhvZD8KKyAgICBzdGF0aWMgYm9vbGVhbiB2ZXJib3NlOwkJCS8vIHByaW50IHByb2dyZXNzPworICAgIHN0YXRpYyBpbnQgZXJyb3JzID0gMDsJCQkvLyBudW1iZXIgb2YgZXJyb3JzIGRldGVjdGVkCisKKyAgICBzdGF0aWMgYm9vbGVhbiBqdW5pdDsKKyAgICBzdGF0aWMgTGlzdDxPYmplY3RbXT4gdGVzdERhdGE7CisKKyAgICBwdWJsaWMgSW50ZXJuZXRBZGRyZXNzVGVzdChTdHJpbmcgaGVhZGVyTmFtZSwgU3RyaW5nIGhlYWRlclZhbHVlLAorCSAgICBTdHJpbmdbXSBleHBlY3RlZCwgYm9vbGVhbiBkb1N0cmljdCwgYm9vbGVhbiBkb1BhcnNlSGVhZGVyKSB7CisJdGhpcy5oZWFkZXJOYW1lID0gaGVhZGVyTmFtZTsKKwl0aGlzLmhlYWRlclZhbHVlID0gaGVhZGVyVmFsdWU7CisJdGhpcy5leHBlY3RlZCA9IGV4cGVjdGVkOworCXRoaXMuZG9TdHJpY3QgPSBkb1N0cmljdDsKKwl0aGlzLmRvUGFyc2VIZWFkZXIgPSBkb1BhcnNlSGVhZGVyOworICAgIH0KKworICAgIEBQYXJhbWV0ZXJzCisgICAgcHVibGljIHN0YXRpYyBDb2xsZWN0aW9uPE9iamVjdFtdPiBkYXRhKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlqdW5pdCA9IHRydWU7CisJdGVzdERhdGEgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKwlwYXJzZShuZXcgQnVmZmVyZWRSZWFkZXIobmV3IElucHV0U3RyZWFtUmVhZGVyKAorCSAgICBJbnRlcm5ldEFkZHJlc3NUZXN0LmNsYXNzLmdldFJlc291cmNlQXNTdHJlYW0oImFkZHJsaXN0IikpKSk7CisJcmV0dXJuIHRlc3REYXRhOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZyBhcmd2W10pIHRocm93cyBFeGNlcHRpb24geworCXZlcmJvc2UgPSB0cnVlOwkJLy8gZGVmYXVsdCBmb3Igc3RhbmRhbG9uZQorCWludCBvcHRpbmQ7CisJZm9yIChvcHRpbmQgPSAwOyBvcHRpbmQgPCBhcmd2Lmxlbmd0aDsgb3B0aW5kKyspIHsKKwkgICAgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi0iKSkgeworCQkvLyBpZ25vcmUKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItZyIpKSB7CisJCWdlbl90ZXN0X2lucHV0ID0gdHJ1ZTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItaCIpKSB7CisJCXBhcnNlX2hlYWRlciA9IHRydWU7CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLXAiKSkgeworCQlwYXJzZV9tYWlsID0gdHJ1ZTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItcyIpKSB7CisJCXN0cmljdCA9IHRydWU7CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLXEiKSkgeworCQl2ZXJib3NlID0gZmFsc2U7CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLS0iKSkgeworCQlvcHRpbmQrKzsKKwkJYnJlYWs7CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLnN0YXJ0c1dpdGgoIi0iKSkgeworCQlTeXN0ZW0ub3V0LnByaW50bG4oCisJCSJVc2FnZTogYWRkcnRlc3QgWy1nXSBbLWhdIFstcF0gWy1zXSBbLXFdIFstXSBbYWRkcmVzcyAuLi5dIik7CisJCVN5c3RlbS5leGl0KDEpOworCSAgICB9IGVsc2UgeworCQlicmVhazsKKwkgICAgfQorCX0KKworCS8qCisJICogSWYgdGhlcmUncyBhbnkgYXJncyBsZWZ0IG9uIHRoZSBjb21tYW5kIGxpbmUsCisJICogY29uY2F0ZW5hdGUgdGhlbSBpbnRvIGEgc3RyaW5nIGFuZCB0ZXN0IHRoYXQuCisJICovCisJaWYgKG9wdGluZCA8IGFyZ3YubGVuZ3RoKSB7CisJICAgIFN0cmluZ0J1ZmZlciBzYiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKwkgICAgZm9yIChpbnQgaSA9IG9wdGluZDsgaSA8IGFyZ3YubGVuZ3RoOyBpKyspIHsKKwkJc2IuYXBwZW5kKGFyZ3ZbaV0pOworCQlzYi5hcHBlbmQoIiAiKTsKKwkgICAgfQorCSAgICB0ZXN0KCJUbyIsIHNiLnRvU3RyaW5nKCksIG51bGwsIHN0cmljdCwgcGFyc2VfaGVhZGVyKTsKKwl9IGVsc2UgeworCSAgICAvLyByZWFkIGZyb20gc3RkaW4KKwkgICAgQnVmZmVyZWRSZWFkZXIgaW4gPQorCQluZXcgQnVmZmVyZWRSZWFkZXIobmV3IElucHV0U3RyZWFtUmVhZGVyKFN5c3RlbS5pbikpOworCSAgICBTdHJpbmcgczsKKworCSAgICBpZiAocGFyc2VfbWFpbCkKKwkJcGFyc2UoaW4pOworCSAgICBlbHNlIHsKKwkJd2hpbGUgKChzID0gaW4ucmVhZExpbmUoKSkgIT0gbnVsbCkKKwkJICAgIHRlc3QoIlRvIiwgcywgbnVsbCwgc3RyaWN0LCBwYXJzZV9oZWFkZXIpOworCSAgICB9CisJfQorCVN5c3RlbS5leGl0KGVycm9ycyk7CisKKyAgICB9CisKKyAgICAvKgorICAgICAqIFBhcnNlIHRoZSBpbnB1dCBpbiAibWFpbCIgZm9ybWF0LCBleHRyYWN0aW5nIHRoZSBGcm9tLCBUbywgYW5kIENjCisgICAgICogaGVhZGVycyBhbmQgdGVzdGluZyB0aGVtLiAgVGhlIHBhcnNlIGlzIHJhdGhlciBjcnVkZSwgYnV0IHN1ZmZpY2llbnQKKyAgICAgKiB0byB0ZXN0IGFnYWluc3QgbW9zdCBleGlzdGluZyBVTklYIG1haWxib3hlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgcGFyc2UoQnVmZmVyZWRSZWFkZXIgaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJU3RyaW5nIGhlYWRlciA9ICIiOworCWJvb2xlYW4gZG9TdHJpY3QgPSBzdHJpY3Q7CisJYm9vbGVhbiBkb1BhcnNlSGVhZGVyID0gcGFyc2VfaGVhZGVyOworCisJZm9yICg7OykgeworCSAgICBTdHJpbmcgcyA9IGluLnJlYWRMaW5lKCk7CisJICAgIGlmIChzICE9IG51bGwgJiYgcy5sZW5ndGgoKSA+IDApIHsKKwkJY2hhciBjID0gcy5jaGFyQXQoMCk7CisJCWlmIChjID09ICcgJyB8fCBjID09ICdcdCcpIHsKKwkJICAgIC8vIGEgY29udGludWF0aW9uIGxpbmUsIGFkZCBpdCB0byB0aGUgY3VycmVudCBoZWFkZXIKKwkJICAgIGhlYWRlciArPSAnXG4nICsgczsKKwkJICAgIGNvbnRpbnVlOworCQl9CisJICAgIH0KKwkgICAgLy8gInMiIGlzIHRoZSBuZXh0IGhlYWRlciwgImhlYWRlciIgaXMgdGhlIGxhc3QgY29tcGxldGUgaGVhZGVyCisJICAgIGlmIChoZWFkZXIuc3RhcnRzV2l0aCgiU3RyaWN0OiAiKSkgeworCQlkb1N0cmljdCA9IEJvb2xlYW4ucGFyc2VCb29sZWFuKHZhbHVlKGhlYWRlcikpOworCSAgICB9IGVsc2UgaWYgKGhlYWRlci5zdGFydHNXaXRoKCJIZWFkZXI6ICIpKSB7CisJCWRvUGFyc2VIZWFkZXIgPSBCb29sZWFuLnBhcnNlQm9vbGVhbih2YWx1ZShoZWFkZXIpKTsKKwkgICAgfSBlbHNlIGlmIChoZWFkZXIuc3RhcnRzV2l0aCgiRnJvbTogIikgfHwKKwkJICAgIGhlYWRlci5zdGFydHNXaXRoKCJUbzogIikgfHwKKwkJICAgIGhlYWRlci5zdGFydHNXaXRoKCJDYzogIikpIHsKKwkJaW50IGk7CisJCVN0cmluZ1tdIGV4cGVjdCA9IG51bGw7CisJCWlmIChzICE9IG51bGwgJiYgcy5zdGFydHNXaXRoKCJFeHBlY3Q6ICIpKSB7CisJCSAgICB0cnkgeworCQkJaW50IG5leHBlY3QgPSBJbnRlZ2VyLnBhcnNlSW50KHMuc3Vic3RyaW5nKDgpKTsKKwkJCWV4cGVjdCA9IG5ldyBTdHJpbmdbbmV4cGVjdF07CisJCQlmb3IgKGkgPSAwOyBpIDwgbmV4cGVjdDsgaSsrKQorCQkJICAgIGV4cGVjdFtpXSA9IHJlYWRMaW5lKGluKS50cmltKCk7CisJCSAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgeworCQkJdHJ5IHsKKwkJCSAgICBpZiAocy5zdWJzdHJpbmcoOCwgMTcpLmVxdWFscygiRXhjZXB0aW9uIikpIHsKKwkJCQlleHBlY3QgPSBuZXcgU3RyaW5nWzFdOworCQkJCWV4cGVjdFswXSA9ICJFeGNlcHRpb24iOworCQkJICAgIH0KKwkJCX0gY2F0Y2ggKFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gc2UpIHsKKwkJCSAgICAvLyBpZ25vcmUgaXQKKwkJCX0KKwkJICAgIH0KKwkJfQorCQlpID0gaGVhZGVyLmluZGV4T2YoJzonKTsKKwkJdHJ5IHsKKwkJICAgIGlmIChqdW5pdCkKKwkJCXRlc3REYXRhLmFkZChuZXcgT2JqZWN0W10geworCQkJICAgIGhlYWRlci5zdWJzdHJpbmcoMCwgaSksIGhlYWRlci5zdWJzdHJpbmcoaSArIDIpLAorCQkJICAgIGV4cGVjdCwgZG9TdHJpY3QsIGRvUGFyc2VIZWFkZXIgfSk7CisJCSAgICBlbHNlCisJCQl0ZXN0KGhlYWRlci5zdWJzdHJpbmcoMCwgaSksIGhlYWRlci5zdWJzdHJpbmcoaSArIDIpLAorCQkJICAgIGV4cGVjdCwgZG9TdHJpY3QsIGRvUGFyc2VIZWFkZXIpOworCQl9IGNhdGNoIChTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKwkJICAgIGUucHJpbnRTdGFja1RyYWNlKFN5c3RlbS5vdXQpOworCQl9CisJICAgIH0KKwkgICAgaWYgKHMgPT0gbnVsbCkKKwkJcmV0dXJuOwkJLy8gRU9GCisJICAgIGlmIChzLmxlbmd0aCgpID09IDApIHsKKwkJd2hpbGUgKChzID0gaW4ucmVhZExpbmUoKSkgIT0gbnVsbCkgeworCQkgICAgaWYgKHMuc3RhcnRzV2l0aCgiRnJvbSAiKSkKKwkJCWJyZWFrOworCQl9CisJCWlmIChzID09IG51bGwpCisJCSAgICByZXR1cm47CisJICAgIH0KKwkgICAgaGVhZGVyID0gczsKKwl9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIHZhbHVlKFN0cmluZyBoZWFkZXIpIHsKKwlyZXR1cm4gaGVhZGVyLnN1YnN0cmluZyhoZWFkZXIuaW5kZXhPZignOicpICsgMSkudHJpbSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWQgYW4gImV4cGVjdGVkIiBsaW5lLCBoYW5kbGluZyBjb250aW51YXRpb25zCisgICAgICogKGJhY2tzbGFzaCBhdCBlbmQgb2YgbGluZSkuICBJZiBsaW5lIGVuZHMgd2l0aAorICAgICAqIHR3byBiYWNrc2xhc2hlcywgaXQncyBub3QgYSBjb250aW51YXRpb24sIGp1c3QgYQorICAgICAqIGxpbmUgdGhhdCBlbmRzIHdpdGggYSBzaW5nbGUgYmFja3NsYXNoLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyByZWFkTGluZShCdWZmZXJlZFJlYWRlciBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlTdHJpbmcgbGluZSA9IGluLnJlYWRMaW5lKCk7CisJaWYgKCFsaW5lLmVuZHNXaXRoKCJcXCIpKQorCSAgICByZXR1cm4gbGluZTsKKwlpZiAobGluZS5lbmRzV2l0aCgiXFxcXCIpKQorCSAgICByZXR1cm4gbGluZS5zdWJzdHJpbmcoMCwgbGluZS5sZW5ndGgoKSAtIDEpOworCVN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcihsaW5lKTsKKwlzYi5zZXRDaGFyQXQoc2IubGVuZ3RoKCkgLSAxLCAnXG4nKTsKKwlmb3IgKDs7KSB7CisJICAgIGxpbmUgPSBpbi5yZWFkTGluZSgpOworCSAgICBzYi5hcHBlbmQobGluZSk7CisJICAgIGlmICghbGluZS5lbmRzV2l0aCgiXFwiKSkKKwkJYnJlYWs7CisJICAgIGlmIChsaW5lLmVuZHNXaXRoKCJcXFxcIikpIHsKKwkJc2Iuc2V0TGVuZ3RoKHNiLmxlbmd0aCgpIC0gMSk7CisJCWJyZWFrOworCSAgICB9CisJICAgIHNiLnNldENoYXJBdChzYi5sZW5ndGgoKSAtIDEsICdcbicpOworCX0KKwlyZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RBZGRyZXNzKCkgeworCXRlc3QoaGVhZGVyTmFtZSwgaGVhZGVyVmFsdWUsIGV4cGVjdGVkLCBkb1N0cmljdCwgZG9QYXJzZUhlYWRlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGUgaGVhZGVyJ3MgdmFsdWUgdG8gc2VlIGlmIHdlIGNhbiBwYXJzZSBpdCBhcyBleHBlY3RlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgdGVzdChTdHJpbmcgaGVhZGVyLCBTdHJpbmcgdmFsdWUsIFN0cmluZyBleHBlY3RbXSwKKwkJYm9vbGVhbiBkb1N0cmljdCwgYm9vbGVhbiBkb1BhcnNlSGVhZGVyKSB7CisJUHJpbnRTdHJlYW0gb3V0ID0gU3lzdGVtLm91dDsKKwlpZiAoZ2VuX3Rlc3RfaW5wdXQpCisJICAgIHByKGhlYWRlciArICI6ICIgKyB2YWx1ZSk7CisJZWxzZQorCSAgICBwcigiVGVzdDogIiArIHZhbHVlKTsKKworCXRyeSB7CisJICAgIEludGVybmV0QWRkcmVzc1tdIGFsOworCSAgICBpZiAoZG9QYXJzZUhlYWRlcikKKwkJYWwgPSBJbnRlcm5ldEFkZHJlc3MucGFyc2VIZWFkZXIodmFsdWUsIGRvU3RyaWN0KTsKKwkgICAgZWxzZQorCQlhbCA9IEludGVybmV0QWRkcmVzcy5wYXJzZSh2YWx1ZSwgZG9TdHJpY3QpOworCSAgICBpZiAoZ2VuX3Rlc3RfaW5wdXQpCisJCXByKCJFeHBlY3Q6ICIgKyBhbC5sZW5ndGgpOworCSAgICBlbHNlIHsKKwkJcHIoIkdvdCAiICsgYWwubGVuZ3RoICsgIiBhZGRyZXNzZXM6Iik7CisJCWlmIChleHBlY3QgIT0gbnVsbCAmJiBhbC5sZW5ndGggIT0gZXhwZWN0Lmxlbmd0aCkgeworCQkgICAgcHIoIkV4cGVjdGVkICIgKyBleHBlY3QubGVuZ3RoICsgIiBhZGRyZXNzZXMiKTsKKwkJICAgIGlmIChqdW5pdCkKKwkJCUFzc2VydC5hc3NlcnRFcXVhbHMoIkZvciAiICsgdmFsdWUgKworCQkJICAgICIgbnVtYmVyIG9mIGFkZHJlc3NlcyIsCisJCQkgICAgYWwubGVuZ3RoLCBleHBlY3QubGVuZ3RoKTsKKwkJICAgIGVycm9ycysrOworCQl9CisJICAgIH0KKwkgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhbC5sZW5ndGg7IGkrKykgeworCQlpZiAoZ2VuX3Rlc3RfaW5wdXQpCisJCSAgICBwcigiXHQiICsgYWxbaV0uZ2V0QWRkcmVzcygpKTsJLy8gWFhYIC0gZXNjYXBlIG5ld2xpbmVzCisJCWVsc2UgeworCQkgICAgcHIoIlx0WyIgKyAoaSsxKSArICJdICIgKyBhbFtpXS5nZXRBZGRyZXNzKCkgKworCQkJIlx0XHRQZXJzb25hbDogIiArIG4oYWxbaV0uZ2V0UGVyc29uYWwoKSkpOworCQkgICAgaWYgKGV4cGVjdCAhPSBudWxsICYmIGkgPCBleHBlY3QubGVuZ3RoICYmCisJCQkJIWV4cGVjdFtpXS5lcXVhbHMoYWxbaV0uZ2V0QWRkcmVzcygpKSkgeworCQkJcHIoIlx0RXhwZWN0ZWQ6XHQiICsgZXhwZWN0W2ldKTsKKwkJCWlmIChqdW5pdCkKKwkJCSAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKCJGb3IgIiArIHZhbHVlICsKKwkJCQkiIGFkZHJlc3NbIiArIGkgKyAiXSIsCisJCQkJZXhwZWN0W2ldLCBhbFtpXS5nZXRBZGRyZXNzKCkpOworCQkJZXJyb3JzKys7CisJCSAgICB9CisJCX0KKwkgICAgfQorCisJICAgIGlmIChhbC5sZW5ndGggPT0gMCkKKwkJcmV0dXJuOworCisJICAgIC8qCisJICAgICAqIFNvbWUgb2YgdGhlIHJlYWxseSBiYWQgYWRkcmVzc2VzIGZhaWwgdGhlIHRvU3RyaW5nCisJICAgICAqIHRlc3RzLCBidXQgd2UgZG9uJ3Qgd2FudCB0aGVtIHRvIGNhdXNlIGJ1aWxkIGZhaWx1cmVzLgorCSAgICAgKi8KKwkgICAgaWYgKGp1bml0KQorCQlyZXR1cm47CisKKwkgICAgLyoKKwkgICAgICogQXMgYSBzYW5pdHkgdGVzdCwgY29udmVydCB0aGUgYWRkcmVzcyBhcnJheSB0byBhIHN0cmluZyBhbmQKKwkgICAgICogdGhlbiBwYXJzZSBpdCBhZ2FpbiwgdG8gc2VlIGlmIHdlIGdldCB0aGUgc2FtZSB0aGluZyBiYWNrLgorCSAgICAgKi8KKwkgICAgdHJ5IHsKKwkJSW50ZXJuZXRBZGRyZXNzW10gYWwyOworCQlTdHJpbmcgdGEgPSBJbnRlcm5ldEFkZHJlc3MudG9TdHJpbmcoYWwpOworCQlpZiAoZG9QYXJzZUhlYWRlcikKKwkJICAgIGFsMiA9IEludGVybmV0QWRkcmVzcy5wYXJzZUhlYWRlcih0YSwgZG9TdHJpY3QpOworCQllbHNlCisJCSAgICBhbDIgPSBJbnRlcm5ldEFkZHJlc3MucGFyc2UodGEsIGRvU3RyaWN0KTsKKwkJaWYgKGFsLmxlbmd0aCAhPSBhbDIubGVuZ3RoKSB7CisJCSAgICBwcigidG9TdHJpbmcgRkFJTEVEISEhIik7CisJCSAgICBwcigiRXhwZWN0ZWQgbGVuZ3RoICIgKyBhbC5sZW5ndGggKworCQkJCSIsIGdvdCAiICsgYWwyLmxlbmd0aCk7CisJCSAgICBpZiAoanVuaXQpCisJCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJGb3IgIiArIHZhbHVlICsKKwkJCSAgICAiIHRvU3RyaW5nIG51bWJlciBvZiBhZGRyZXNzZXMiLAorCQkJICAgIGFsLmxlbmd0aCwgYWwyLmxlbmd0aCk7CisJCSAgICBlcnJvcnMrKzsKKwkJfSBlbHNlIHsKKwkJICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYWwubGVuZ3RoOyBpKyspIHsKKwkJCWlmICghYWxbaV0uZ2V0QWRkcmVzcygpLmVxdWFscyhhbDJbaV0uZ2V0QWRkcmVzcygpKSkgeworCQkJICAgIHByKCJ0b1N0cmluZyBGQUlMRUQhISEiKTsKKwkJCSAgICBwcigiRXhwZWN0ZWQgYWRkcmVzcyAiICsKKwkJCQkJYWxbaV0uZ2V0QWRkcmVzcygpICsKKwkJCQkJIiwgZ290ICIgKyBhbDJbaV0uZ2V0QWRkcmVzcygpKTsKKwkJCSAgICBpZiAoanVuaXQpCisJCQkJQXNzZXJ0LmFzc2VydEVxdWFscygiRm9yICIgKyB2YWx1ZSArCisJCQkJICAgICIgdG9TdHJpbmcgIiArIHRhICsgIiBhZGRyZXNzWyIgKyBpICsgIl0iLAorCQkJCSAgICBhbFtpXS5nZXRBZGRyZXNzKCksIGFsMltpXS5nZXRBZGRyZXNzKCkpOworCQkJICAgIGVycm9ycysrOworCQkJfQorCQkJU3RyaW5nIHAxID0gYWxbaV0uZ2V0UGVyc29uYWwoKTsKKwkJCVN0cmluZyBwMiA9IGFsMltpXS5nZXRQZXJzb25hbCgpOworCQkJaWYgKCEocDEgPT0gcDIgfHwgKHAxICE9IG51bGwgJiYgcDEuZXF1YWxzKHAyKSkpKSB7CisJCQkgICAgcHIoInRvU3RyaW5nIEZBSUxFRCEhISIpOworCQkJICAgIHByKCJFeHBlY3RlZCBwZXJzb25hbCAiICsgbihwMSkgKworCQkJCQkiLCBnb3QgIiArIG4ocDIpKTsKKwkJCSAgICBpZiAoanVuaXQpCisJCQkJQXNzZXJ0LmFzc2VydEVxdWFscygiRm9yICIgKyB2YWx1ZSArCisJCQkJICAgICIgdG9TdHJpbmcgIiArIHRhICsgIiBwZXJzb25hbFsiICsgaSArICJdIiwKKwkJCQkgICAgcDEsIHAyKTsKKwkJCSAgICBlcnJvcnMrKzsKKwkJCX0KKwkJICAgIH0KKwkJfQorCSAgICB9IGNhdGNoIChBZGRyZXNzRXhjZXB0aW9uIGUyKSB7CisJCXByKCJ0b1N0cmluZyBGQUlMRUQhISEiKTsKKwkJcHIoIkdvdCBFeGNlcHRpb246ICIgKyBlMik7CisJCWlmIChqdW5pdCkKKwkJICAgIEFzc2VydC5mYWlsKCJGb3IgIiArIHZhbHVlICsKKwkJCQkiIHRvU3RyaW5nIGdvdCBFeGNlcHRpb246ICIgKyBlMik7CisJCWVycm9ycysrOworCSAgICB9CisJfSBjYXRjaCAoQWRkcmVzc0V4Y2VwdGlvbiBlKSB7CisJICAgIGlmIChnZW5fdGVzdF9pbnB1dCkKKwkJcHIoIkV4cGVjdDogRXhjZXB0aW9uICIgKyBlKTsKKwkgICAgZWxzZSB7CisJCXByKCJHb3QgRXhjZXB0aW9uOiAiICsgZSk7CisJCWlmIChleHBlY3QgIT0gbnVsbCAmJgorCQkgICAoZXhwZWN0Lmxlbmd0aCAhPSAxIHx8ICFleHBlY3RbMF0uZXF1YWxzKCJFeGNlcHRpb24iKSkpIHsKKwkJICAgIHByKCJFeHBlY3RlZCAiICsgZXhwZWN0Lmxlbmd0aCArICIgYWRkcmVzc2VzIik7CisJCSAgICBmb3IgKGludCBpID0gMDsgaSA8IGV4cGVjdC5sZW5ndGg7IGkrKykKKwkJCXByKCJcdEV4cGVjdGVkOlx0IiArIGV4cGVjdFtpXSk7CisJCSAgICBpZiAoanVuaXQpCisJCQlBc3NlcnQuZmFpbCgiRm9yICIgKyB2YWx1ZSArICIgZXhwZWN0ZWQgIiArCisJCQkgICAgZXhwZWN0Lmxlbmd0aCArICJhZGRyZXNzZXMsIGdvdCBFeGNlcHRpb246ICIgKyBlKTsKKwkJICAgIGVycm9ycysrOworCQl9CisJICAgIH0KKwl9CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgdm9pZCBwcihTdHJpbmcgcykgeworCWlmICh2ZXJib3NlKQorCSAgICBTeXN0ZW0ub3V0LnByaW50bG4ocyk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIG4oU3RyaW5nIHMpIHsKKwlyZXR1cm4gcyA9PSBudWxsID8gIjxudWxsPiIgOiBzOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L0ludGVybmV0SGVhZGVyc1Rlc3QuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L0ludGVybmV0SGVhZGVyc1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hOTY2ODhjCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvSW50ZXJuZXRIZWFkZXJzVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTE1IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDExLCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGphdmF4Lm1haWwuaW50ZXJuZXQ7CisKK2ltcG9ydCBjb20uc3VuLm1haWwudGVzdC5Bc2NpaVN0cmluZ0lucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXQ7CitpbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOworCitpbXBvcnQgamF2YXgubWFpbC4qOworCitpbXBvcnQgb3JnLmp1bml0Lio7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VHJ1ZTsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRFcXVhbHM7CisKKy8qKgorICogVGVzdCB0aGUgSW50ZXJuZXRIZWFkZXJzIGNsYXNzLgorICovCitwdWJsaWMgY2xhc3MgSW50ZXJuZXRIZWFkZXJzVGVzdCB7CisgCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIGluaXRpYWxXaGl0ZXNwYWNlSGVhZGVyID0KKwkJCQkJCSIgXHJcblN1YmplY3Q6IHRlc3RcclxuXHJcbiI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIGluaXRpYWxDb250aW51YXRpb25IZWFkZXIgPQorCQkJCQkJIiBTdWJqZWN0OiB0ZXN0XHJcblxyXG4iOworCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IGEgY29udGludWF0aW9uIGxpbmUgaXMgaGFuZGxlZCBwcm9wZXJseS4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RDb250aW51YXRpb25MaW5lKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJU3RyaW5nIGhlYWRlciA9ICJTdWJqZWN0OiBhXHJcbiBiXHJcblxyXG4iOworCUludGVybmV0SGVhZGVycyBpaCA9IG5ldyBJbnRlcm5ldEhlYWRlcnMoCisJCW5ldyBBc2NpaVN0cmluZ0lucHV0U3RyZWFtKGhlYWRlcikpOworCWFzc2VydEVxdWFscygxLCBpaC5nZXRIZWFkZXIoIlN1YmplY3QiKS5sZW5ndGgpOworCWFzc2VydEVxdWFscygiYVxyXG4gYiIsIGloLmdldEhlYWRlcigiU3ViamVjdCIpWzBdKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHRoYXQgYSB3aGl0ZXNwYWNlIGxpbmUgYXQgdGhlIGJlZ2lubmluZyBpcyBpZ25vcmVkLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEluaXRpYWxXaGl0ZXNwYWNlTGluZUNvbnN0cnVjdG9yKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJSW50ZXJuZXRIZWFkZXJzIGloID0gbmV3IEludGVybmV0SGVhZGVycygKKwkJbmV3IEFzY2lpU3RyaW5nSW5wdXRTdHJlYW0oaW5pdGlhbFdoaXRlc3BhY2VIZWFkZXIpKTsKKwl0ZXN0SW5pdGlhbFdoaXRlc3BhY2VMaW5lKGloKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHRoYXQgYSB3aGl0ZXNwYWNlIGxpbmUgYXQgdGhlIGJlZ2lubmluZyBpcyBpZ25vcmVkLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEluaXRpYWxXaGl0ZXNwYWNlTGluZUxvYWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlJbnRlcm5ldEhlYWRlcnMgaWggPSBuZXcgSW50ZXJuZXRIZWFkZXJzKCk7CisJaWgubG9hZChuZXcgQXNjaWlTdHJpbmdJbnB1dFN0cmVhbShpbml0aWFsV2hpdGVzcGFjZUhlYWRlcikpOworCXRlc3RJbml0aWFsV2hpdGVzcGFjZUxpbmUoaWgpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0SW5pdGlhbFdoaXRlc3BhY2VMaW5lKEludGVybmV0SGVhZGVycyBpaCkKKwkJCQl0aHJvd3MgRXhjZXB0aW9uIHsKKwlhc3NlcnRFcXVhbHMoMSwgaWguZ2V0SGVhZGVyKCJTdWJqZWN0IikubGVuZ3RoKTsKKwlhc3NlcnRFcXVhbHMoInRlc3QiLCBpaC5nZXRIZWFkZXIoIlN1YmplY3QiKVswXSk7CisJRW51bWVyYXRpb248SGVhZGVyPiBlID0gaWguZ2V0QWxsSGVhZGVycygpOworCXdoaWxlIChlLmhhc01vcmVFbGVtZW50cygpKSB7CisJICAgIEhlYWRlciBoID0gZS5uZXh0RWxlbWVudCgpOworCSAgICBhc3NlcnRFcXVhbHMoIlN1YmplY3QiLCBoLmdldE5hbWUoKSk7CisJICAgIGFzc2VydEVxdWFscygidGVzdCIsIGguZ2V0VmFsdWUoKSk7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCBhIGNvbnRpbnVhdGlvbiBsaW5lIGF0IHRoZSBiZWdpbm5pbmcgaXMgaGFuZGxlZC4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RJbml0aWFsQ29udGludWF0aW9uTGluZUNvbnN0cnVjdG9yKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJSW50ZXJuZXRIZWFkZXJzIGloID0gbmV3IEludGVybmV0SGVhZGVycygKKwkJbmV3IEFzY2lpU3RyaW5nSW5wdXRTdHJlYW0oaW5pdGlhbENvbnRpbnVhdGlvbkhlYWRlcikpOworCXRlc3RJbml0aWFsQ29udGludWF0aW9uTGluZShpaCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IGEgY29udGludWF0aW9uIGxpbmUgYXQgdGhlIGJlZ2lubmluZyBpcyBoYW5kbGVkLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEluaXRpYWxDb250aW51YXRpb25MaW5lTG9hZCgpIHRocm93cyBFeGNlcHRpb24geworCUludGVybmV0SGVhZGVycyBpaCA9IG5ldyBJbnRlcm5ldEhlYWRlcnMoKTsKKwlpaC5sb2FkKG5ldyBBc2NpaVN0cmluZ0lucHV0U3RyZWFtKGluaXRpYWxDb250aW51YXRpb25IZWFkZXIpKTsKKwl0ZXN0SW5pdGlhbENvbnRpbnVhdGlvbkxpbmUoaWgpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB0ZXN0SW5pdGlhbENvbnRpbnVhdGlvbkxpbmUoSW50ZXJuZXRIZWFkZXJzIGloKQorCQkJCXRocm93cyBFeGNlcHRpb24geworCWFzc2VydEVxdWFscygxLCBpaC5nZXRIZWFkZXIoIlN1YmplY3QiKS5sZW5ndGgpOworCWFzc2VydEVxdWFscygidGVzdCIsIGloLmdldEhlYWRlcigiU3ViamVjdCIpWzBdKTsKKwlFbnVtZXJhdGlvbjxIZWFkZXI+IGUgPSBpaC5nZXRBbGxIZWFkZXJzKCk7CisJd2hpbGUgKGUuaGFzTW9yZUVsZW1lbnRzKCkpIHsKKwkgICAgSGVhZGVyIGggPSBlLm5leHRFbGVtZW50KCk7CisJICAgIGFzc2VydEVxdWFscygiU3ViamVjdCIsIGguZ2V0TmFtZSgpKTsKKwkgICAgYXNzZXJ0RXF1YWxzKCJ0ZXN0IiwgaC5nZXRWYWx1ZSgpKTsKKwl9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvTWFpbERhdGVGb3JtYXRUZXN0LmphdmEgYi9tYWlsL3NyYy90ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9NYWlsRGF0ZUZvcm1hdFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNDIxNjA5Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvTWFpbERhdGVGb3JtYXRUZXN0LmphdmEKQEAgLTAsMCArMSw1MTYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5pbnRlcm5ldDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOworaW1wb3J0IGphdmEudGV4dC5EYXRlRm9ybWF0OworaW1wb3J0IGphdmEudGV4dC5EYXRlRm9ybWF0U3ltYm9sczsKK2ltcG9ydCBqYXZhLnRleHQuRmllbGRQb3NpdGlvbjsKK2ltcG9ydCBqYXZhLnRleHQuTnVtYmVyRm9ybWF0OworaW1wb3J0IGphdmEudGV4dC5QYXJzZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnRleHQuUGFyc2VQb3NpdGlvbjsKK2ltcG9ydCBqYXZhLnRleHQuU2ltcGxlRGF0ZUZvcm1hdDsKK2ltcG9ydCBqYXZhLnV0aWwuQ2FsZW5kYXI7CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CitpbXBvcnQgamF2YS51dGlsLkdyZWdvcmlhbkNhbGVuZGFyOworaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CitpbXBvcnQgamF2YS51dGlsLlRpbWVab25lOworaW1wb3J0IHN0YXRpYyBvcmcuaGFtY3Jlc3QuQ29yZU1hdGNoZXJzLmlzOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydE5vdE51bGw7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0TnVsbDsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUaGF0OworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydFRydWU7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuZmFpbDsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKKworLyoqCisgKiBUZXN0IE1haWxEYXRlRm9ybWF0OiBmb3JtYXR0aW5nIGFuZCBwYXJzaW5nIG9mIGRhdGVzIGFzIHNwZWNpZmllZCBieQorICogPGEgaHJlZj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjgyMi50eHQiPlJGQyAyODIyPC9hPi4KKyAqCisgKiBAYXV0aG9yCUFudGhvbnkgVmFuZWx2ZXJkaW5naGUKKyAqLworcHVibGljIGNsYXNzIE1haWxEYXRlRm9ybWF0VGVzdCB7CisKKyAgICAvKgorICAgICAqIFNlcmlhbGl6YXRpb24KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIG11c3RSZXRhaW5CaW5hcnlDb21wYXRpYmlsaXR5KCkKKyAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiwgUGFyc2VFeGNlcHRpb24geworICAgICAgICB2ZXJpZnlTZXJpYWxpemF0aW9uKCJNYWlsRGF0ZUZvcm1hdF9vbGQuc2VyIik7CisgICAgICAgIHZlcmlmeVNlcmlhbGl6YXRpb24oIk1haWxEYXRlRm9ybWF0X25ldy5zZXIiKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgdmVyaWZ5U2VyaWFsaXphdGlvbihTdHJpbmcgcmVzb3VyY2VOYW1lKQorICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgTWFpbERhdGVGb3JtYXQgZm10ID0gcmVhZFNlcmlhbGl6ZWRGb3JtYXQocmVzb3VyY2VOYW1lKTsKKworICAgICAgICBhc3NlcnRUaGF0KGZtdC5nZXRUaW1lWm9uZSgpLmdldElEKCksIGlzKCJBbWVyaWNhL0xvc19BbmdlbGVzIikpOworCisgICAgICAgIERhdGUgZGF0ZSA9IG11c3RQYXNzKGZtdCwgIlRodSwgMSBKYW4gMjAxNSAwMDowMDowMCArMDAwMCIpOworICAgICAgICBhc3NlcnRUaGF0RGF0ZShkYXRlLCAiVGh1LCAxIEphbiAyMDE1IDAwOjAwOjAwICswMDAwIChVVEMpIik7CisKKyAgICAgICAgYXNzZXJ0VGhhdChmbXQuZm9ybWF0KGRhdGUpLAorICAgICAgICAgICAgICAgIGlzKCJXZWQsIDMxIERlYyAyMDE0IDE2OjAwOjAwIC0wODAwIChQU1QpIikpOworICAgIH0KKworICAgIHByaXZhdGUgTWFpbERhdGVGb3JtYXQgcmVhZFNlcmlhbGl6ZWRGb3JtYXQoU3RyaW5nIHJlc291cmNlTmFtZSkKKyAgICAgICAgICAgIHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisgICAgICAgIElucHV0U3RyZWFtIHJlc291cmNlID0gbnVsbDsKKyAgICAgICAgT2JqZWN0SW5wdXRTdHJlYW0gaW4gPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVzb3VyY2UgPSB0aGlzLmdldENsYXNzKCkuZ2V0UmVzb3VyY2VBc1N0cmVhbShyZXNvdXJjZU5hbWUpOworICAgICAgICAgICAgaW4gPSBuZXcgT2JqZWN0SW5wdXRTdHJlYW0ocmVzb3VyY2UpOworICAgICAgICAgICAgcmV0dXJuIChNYWlsRGF0ZUZvcm1hdCkgaW4ucmVhZE9iamVjdCgpOworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgaWYgKGluICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBGb3JtYXR0aW5nICsgcGFyc2luZworICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgbXVzdFN1Y2NlZWRSb3VuZFRyaXAoKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24geworICAgICAgICBEYXRlIGRhdGUgPSBuZXcgRGF0ZSgxMzQxMTAwNzk4MDAwTCk7IC8vIG1pbGxpc2Vjb25kcyBtdXN0IGJlIDAKKyAgICAgICAgU2ltcGxlRGF0ZUZvcm1hdCBmbXQgPSBnZXREZWZhdWx0KCk7CisgICAgICAgIGFzc2VydFRoYXQoZm10LnBhcnNlKGZtdC5mb3JtYXQoZGF0ZSkpLCBpcyhkYXRlKSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBGb3JtYXR0aW5nCisgICAgICovCisgICAgQFRlc3QoKQorICAgIHB1YmxpYyB2b2lkIGZvcm1hdE11c3RUaHJvd05wZUZvck51bGxBcmdzKCkgeworICAgICAgICBmb3IgKGludCBtYXNrID0gMDsgbWFzayA8IDc7IG1hc2srKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBEYXRlIGRhdGUgPSAobWFzayAmIDEpID09IDEKKyAgICAgICAgICAgICAgICAgICAgICAgID8gbmV3IERhdGUoKSA6IG51bGw7CisgICAgICAgICAgICAgICAgU3RyaW5nQnVmZmVyIHRvQXBwZW5kVG8gPSAobWFzayAmIDIpID09IDIKKyAgICAgICAgICAgICAgICAgICAgICAgID8gbmV3IFN0cmluZ0J1ZmZlcigpIDogbnVsbDsKKyAgICAgICAgICAgICAgICBGaWVsZFBvc2l0aW9uIHBvcyA9IChtYXNrICYgNCkgPT0gNAorICAgICAgICAgICAgICAgICAgICAgICAgPyBuZXcgRmllbGRQb3NpdGlvbigwKSA6IG51bGw7CisgICAgICAgICAgICAgICAgZ2V0RGVmYXVsdCgpLmZvcm1hdChkYXRlLCB0b0FwcGVuZFRvLCBwb3MpOworICAgICAgICAgICAgICAgIGZhaWwoIk5vIE51bGxQb2ludGVyRXhjZXB0aW9uIHRocm93biBmb3IgbWFzayA9ICIgKyBtYXNrKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgbXVzdEZvcm1hdFJmYzI4MjJXaXRoT3B0aW9uYWxDZndzKCkgeworICAgICAgICBEYXRlIGRhdGUgPSBtdXN0UGFzcyhnZXREZWZhdWx0KCksICIxIEphbiAyMDE1IDAwOjAwICswMDAwIik7CisgICAgICAgIGFzc2VydFRoYXREYXRlKGRhdGUsICJUaHUsIDEgSmFuIDIwMTUgMDA6MDA6MDAgKzAwMDAgKFVUQykiKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIG11c3RVc2VUaW1lWm9uZUZvckZvcm1hdHRpbmcoKSB7CisgICAgICAgIFN0cmluZyBpbnB1dCA9ICIxIEphbiAyMDE1IDAwOjAwICswMTAwIjsKKyAgICAgICAgU2ltcGxlRGF0ZUZvcm1hdCBmbXQgPSBnZXREZWZhdWx0KCk7CisgICAgICAgIERhdGUgZGF0ZSA9IG11c3RQYXNzKGZtdCwgaW5wdXQpOworICAgICAgICBmbXQuc2V0VGltZVpvbmUoVGltZVpvbmUuZ2V0VGltZVpvbmUoIkV0Yy9HTVQrOCIpKTsKKyAgICAgICAgYXNzZXJ0VGhhdChmbXQuZm9ybWF0KGRhdGUpLAorICAgICAgICAgICAgICAgIGlzKCJXZWQsIDMxIERlYyAyMDE0IDE1OjAwOjAwIC0wODAwIChHTVQtMDg6MDApIikpOworICAgIH0KKworICAgIC8qCisgICAgICogUGFyc2luZworICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgcGFyc2VNdXN0VGhyb3dOcGVGb3JOdWxsQXJncygpIHsKKyAgICAgICAgZm9yIChpbnQgbWFzayA9IDA7IG1hc2sgPCAzOyBtYXNrKyspIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgU3RyaW5nIHNvdXJjZSA9IChtYXNrICYgMSkgPT0gMQorICAgICAgICAgICAgICAgICAgICAgICAgPyAiMSBKYW4gMjAxNSAwMDowMCArMDEwMCIgOiBudWxsOworICAgICAgICAgICAgICAgIFBhcnNlUG9zaXRpb24gcG9zID0gKG1hc2sgJiAyKSA9PSAyCisgICAgICAgICAgICAgICAgICAgICAgICA/IG5ldyBQYXJzZVBvc2l0aW9uKDApIDogbnVsbDsKKyAgICAgICAgICAgICAgICBnZXREZWZhdWx0KCkucGFyc2Uoc291cmNlLCBwb3MpOworICAgICAgICAgICAgICAgIGZhaWwoIk5vIE51bGxQb2ludGVyRXhjZXB0aW9uIHRocm93biBmb3IgbWFzayA9ICIgKyBtYXNrKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKE51bGxQb2ludGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgbXVzdFJldHVybk9uSW52YWxpZFBhcnNlUG9zaXRpb24oKSB7CisgICAgICAgIGFzc2VydE51bGwoZ2V0RGVmYXVsdCgpLnBhcnNlKCIiLCBuZXcgUGFyc2VQb3NpdGlvbigtMSkpKTsKKyAgICAgICAgYXNzZXJ0TnVsbChnZXREZWZhdWx0KCkucGFyc2UoIiIsIG5ldyBQYXJzZVBvc2l0aW9uKDApKSk7CisgICAgICAgIGFzc2VydE51bGwoZ2V0RGVmYXVsdCgpLnBhcnNlKCIiLCBuZXcgUGFyc2VQb3NpdGlvbigxKSkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgbXVzdFBhcnNlUmZjMjgyMigpIHsKKyAgICAgICAgbXVzdFBhc3MoZ2V0RGVmYXVsdCgpLCAiVGh1LCAxIEphbiAyMDE1IDAwOjAwOjAwICswMDAwIik7CisgICAgICAgIG11c3RGYWlsKGdldFN0cmljdCgpLCAiZm9vIiwgMCk7CisgICAgICAgIG11c3RGYWlsKGdldExlbmllbnQoKSwgImZvbyIsIDMpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgbXVzdFJldGFpblRpbWVab25lRm9yQmFja3dhcmRDb21wYXRpYmlsaXR5KCkgeworICAgICAgICAvLyB0aG91Z2ggamF2YS50ZXh0LkRhdGVGb3JtYXQ6OnBhcnNlKFN0cmluZywgUGFyc2VQb3NpdGlvbikgc3BlY2lmaWVzOgorICAgICAgICAvLyAiVGhpcyBwYXJzaW5nIG9wZXJhdGlvbiB1c2VzIHRoZSBjYWxlbmRhciB0byBwcm9kdWNlIGEgRGF0ZS4gQXMgYQorICAgICAgICAvLyByZXN1bHQsIHRoZSBjYWxlbmRhcidzIGRhdGUtdGltZSBmaWVsZHMgYW5kIHRoZSBUaW1lWm9uZSB2YWx1ZQorICAgICAgICAvLyBtYXkgaGF2ZSBiZWVuIG92ZXJ3cml0dGVuLCBkZXBlbmRpbmcgb24gc3ViY2xhc3MgaW1wbGVtZW50YXRpb25zLgorICAgICAgICAvLyBBbnkgVGltZVpvbmUgdmFsdWUgdGhhdCBoYXMgcHJldmlvdXNseSBiZWVuIHNldCBieSBhIGNhbGwgdG8KKyAgICAgICAgLy8gc2V0VGltZVpvbmUgbWF5IG5lZWQgdG8gYmUgcmVzdG9yZWQgZm9yIGZ1cnRoZXIgb3BlcmF0aW9ucy4iCisgICAgICAgIC8vIHdlIG11c3QgcmV0YWluIHRoZSBUaW1lWm9uZSB2YWx1ZSBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSByZWFzb25zCisgICAgICAgIFNpbXBsZURhdGVGb3JtYXQgZm10ID0gZ2V0RGVmYXVsdCgpOworICAgICAgICBmbXQuc2V0VGltZVpvbmUoVGltZVpvbmUuZ2V0VGltZVpvbmUoIkV1cm9wZS9CcnVzc2VscyIpKTsKKyAgICAgICAgbXVzdFBhc3MoZm10LCAiMSBKYW4gMjAxNSAwMDowMCArMDAwMCIpOworICAgICAgICBhc3NlcnRUaGF0KGZtdC5nZXRUaW1lWm9uZSgpLAorICAgICAgICAgICAgICAgIGlzKFRpbWVab25lLmdldFRpbWVab25lKCJFdXJvcGUvQnJ1c3NlbHMiKSkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgbXVzdFVzZUxlbmllbmN5Rm9yUGFyc2luZygpIHsKKyAgICAgICAgU3RyaW5nIGxlbmllbnRJbnB1dCA9ICIxLUphbi0yMDE1IDAwOjAwICswMDAwIjsKKyAgICAgICAgU3RyaW5nIHN0cmljdElucHV0ID0gIjEgSmFuIDIwMTUgMDA6MDAgKzAwMDAiOworCisgICAgICAgIFNpbXBsZURhdGVGb3JtYXQgZm10ID0gZ2V0U3RyaWN0KCk7CisgICAgICAgIG11c3RGYWlsKGZtdCwgbGVuaWVudElucHV0LCAxKTsKKyAgICAgICAgbXVzdFBhc3MoZm10LCBzdHJpY3RJbnB1dCk7CisKKyAgICAgICAgZm10LnNldExlbmllbnQodHJ1ZSk7CisgICAgICAgIG11c3RQYXNzKGZtdCwgbGVuaWVudElucHV0KTsKKyAgICAgICAgbXVzdFBhc3MoZm10LCBzdHJpY3RJbnB1dCk7CisKKyAgICAgICAgZm10LnNldExlbmllbnQoZmFsc2UpOworICAgICAgICBtdXN0RmFpbChmbXQsIGxlbmllbnRJbnB1dCwgMSk7CisgICAgICAgIG11c3RQYXNzKGZtdCwgc3RyaWN0SW5wdXQpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgbXVzdFJlcG9ydENvcnJlY3RFcnJvckluZGV4KCkgeworICAgICAgICBtdXN0RmFpbChnZXREZWZhdWx0KCksICIxIEp1ayAyMDE1IDAwOjAwICswMDAwIiwgMik7CisgICAgICAgIG11c3RGYWlsKGdldFN0cmljdCgpLCAiMVxyXG5KYW4gMjAxNSAwMDowMCArMDAwMCIsIDEpOworICAgICAgICBtdXN0RmFpbChnZXRTdHJpY3QoKSwgIjEgSmFuIDIwMSAwMDowMCArMDAwMCIsIDYpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgbGVuaWVudE11c3RCZUJhY2t3YXJkQ29tcGF0aWJsZSgpIHsKKyAgICAgICAgbXVzdFBhc3MoZ2V0TGVuaWVudCgpLCAiVGh1LCAxIEphbiAyMDE1IDEyOjAwICswMDAwIik7CisgICAgICAgIG11c3RQYXNzKGdldExlbmllbnQoKSwgIjMyIGRFQyAyMDE1IDEyOjAwICswMDk5Iik7CisgICAgICAgIG11c3RQYXNzKGdldExlbmllbnQoKSwgImZvb0ZyaSw5OTktSmFuLTk5OTk5OTk5IDk5Ojk5Ojk5KzIzOTkiKTsKKyAgICAgICAgbXVzdFBhc3MoZ2V0TGVuaWVudCgpLCAiZm9vRnJpLDk5OS1KYW4tOTk5OTk5OTkgOTk6OTk6OTkrMjM5OSIpOworICAgICAgICBtdXN0UGFzcyhnZXRMZW5pZW50KCksICJmb29GcmkgLDk5OUphbjk5OTk5OTk5IDk5Ojk5Ojk5KzIzOTkiKTsKKyAgICAgICAgbXVzdFBhc3MoZ2V0TGVuaWVudCgpLCAiZm9vMzEtbUFZLTFccjM6MzozKyIpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgc3RyaWN0TXVzdFJlamVjdEludmFsaWRCZWdpbigpIHsKKyAgICAgICAgbXVzdEZhaWwoZ2V0U3RyaWN0KCksICJmb28xIEphbiAyMDE1IDAwOjAwICswMDAwIiwgMCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBzdHJpY3RNdXN0UmVqZWN0U2VtYW50aWNhbGx5SW52YWxpZERhdGUoKSB7CisgICAgICAgIG11c3RGYWlsKGdldFN0cmljdCgpLCAiRnJpLCAxIEphbiAyMDE1IDAwOjAwICswMDAwIiwgMjcpOworICAgIH0KKworICAgIC8qCisgICAgICogUGFyc2luZyAtIHJhbmdlIGNvbnN0cmFpbnRzCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBtdXN0UmVqZWN0RmllbGRzV2l0aFRvb01hbnlEaWdpdHMoKSB7CisgICAgICAgIG11c3RGYWlsKGdldERlZmF1bHQoKSwgIjEyMzQgSmFuIDIwMTUgMDA6MDAgKzAwMDAiLCAwKTsKKyAgICAgICAgbXVzdEZhaWwoZ2V0RGVmYXVsdCgpLCAiMSBKYW4gMTIzNDU2Nzg5IDAwOjAwICswMDAwIiwgNik7CisgICAgICAgIG11c3RGYWlsKGdldERlZmF1bHQoKSwgIjEgSmFuIDIwMTUgMTIzOjAwICswMDAwIiwgMTEpOworICAgICAgICBtdXN0RmFpbChnZXREZWZhdWx0KCksICIxIEphbiAyMDE1IDAwOjEyMyArMDAwMCIsIDE0KTsKKyAgICAgICAgbXVzdEZhaWwoZ2V0RGVmYXVsdCgpLCAiMSBKYW4gMjAxNSAwMDowMDoxMjMgKzAwMDAiLCAxNyk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBtdXN0Q291bnRMZWFkaW5nWmVyb2VzRm9yVG9vTWFueURpZ2l0cygpIHsKKyAgICAgICAgbXVzdEZhaWwoZ2V0RGVmYXVsdCgpLCAiMDAwMDAwMDAwMDAwMSBKYW4gMjAxNSAwMDowMCArMDAwMCIsIDApOworICAgIH0KKworICAgIC8qCisgICAgICogUGFyc2luZyAtIG92ZXJmbG93CisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBtdXN0RmFpbEZhc3RJZkRheUNvbnRhaW5zVG9vTWFueURpZ2l0cygpIHsKKyAgICAgICAgbXVzdEZhaWwoZ2V0TGVuaWVudCgpLAorCQkiMTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxIEphbiAyMDE1IDAwOjAwICswMDAwIiwgMCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBtdXN0RmFpbEZhc3RJZlllYXJDb250YWluc1Rvb01hbnlEaWdpdHMoKSB7CisgICAgICAgIG11c3RGYWlsKGdldExlbmllbnQoKSwKKwkJIjEgSmFuIDEwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMjAxNSAwMDowMCArMDAwMCIsIDYpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgbXVzdEZhaWxJZlllYXJJc1Rvb0JpZ0ZvckdyZWdvcmlhbkNhbGVuZGFyKCkgeworICAgICAgICBpbnQgdG9vQmlnID0gOTk5OTk5OTk5OworICAgICAgICBhc3NlcnRUcnVlKHRvb0JpZyA+IG5ldyBHcmVnb3JpYW5DYWxlbmRhcigpLmdldE1heGltdW0oQ2FsZW5kYXIuWUVBUikpOworICAgICAgICBtdXN0RmFpbChnZXRMZW5pZW50KCksICIxIEphbiAiICsgdG9vQmlnICsgIiAwMDowMCArMDAwMCIsIDYpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgbXVzdEZhaWxPbkludGVnZXJPdmVyZmxvdygpIHsKKyAgICAgICAgbXVzdEZhaWwoZ2V0TGVuaWVudCgpLCAiNDU2Mzc4OTQxOTYxIEphbiAyMDE1IDAwOjAwICswMDAwIiwgMCk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBQYXJzaW5nIC0gRldTIChmb2xkaW5nIHdoaXRlIHNwYWNlKQorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgbXVzdEZhaWxPclNraXBDZndzKCkgeworICAgICAgICBTdHJpbmcgaW5wdXQgPSAiKDMgSmFuIDIwMTUgMDA6MDAgKzAwMDApIDEgSmFuIDIwMTUgMDA6MDAgKzAwMDAiOworICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gTk9URSB0aGlzIHRlc3QgZmFpbHMgd2l0aCBnZXRMZW5pZW50KCksCisgICAgICAgICAgICAvLyBzaW5jZSBsZW5pZW50IHBhcnNpbmcgbXVzdCByZW1haW4gYmFja3dhcmQgY29tcGF0aWJsZQorICAgICAgICAgICAgRGF0ZSBkYXRlID0gZ2V0U3RyaWN0KCkucGFyc2UoaW5wdXQpOworICAgICAgICAgICAgYXNzZXJ0VGhhdERhdGUoZGF0ZSwgIlRodSwgMSBKYW4gMjAxNSAwMDowMDowMCArMDAwMCAoVVRDKSIpOworICAgICAgICB9IGNhdGNoIChQYXJzZUV4Y2VwdGlvbiBpZ25vcmVkKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJOb3Qgc3VwcG9ydGluZyBDRldTIGlzIGFsbG93ZWQiLCB0cnVlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgbGVuaWVudE11c3RBY2NlcHRFbXB0eUZ3c0lmZlVuYW1iaWd1b3VzKCkgeworICAgICAgICBtdXN0UGFzcyhnZXRMZW5pZW50KCksICJUaHUsMUphbjIwMTUgMTI6MDArMDAwMCIpOworICAgICAgICBtdXN0RmFpbChnZXRMZW5pZW50KCksICIxIEphbiAxMDE1MTIzNDU2OjAwICswMDAwIiwgNik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBsZW5pZW50TXVzdFJlamVjdEluY29uc2lzdGVudE1vbnRoRndzKCkgeworICAgICAgICBtdXN0RmFpbChnZXRMZW5pZW50KCksICIxLUphbiAyMDE1IDAwOjAwICswMDAwIiwgNSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBzdHJpY3RNdXN0UmVqZWN0SW52YWxpZEZ3cygpIHsKKyAgICAgICAgbXVzdEZhaWwoZ2V0U3RyaWN0KCksICJcclxuXHJcbiAxIEphbiAyMDE1IDAwOjAwICswMDAwIiwgMCk7CisgICAgICAgIG11c3RGYWlsKGdldFN0cmljdCgpLCAiXHJcbjEgSmFuIDIwMTUgMDA6MDAgKzAwMDAiLCAwKTsKKyAgICAgICAgbXVzdEZhaWwoZ2V0U3RyaWN0KCksICJcbiAxIEphbiAyMDE1IDAwOjAwICswMDAwIiwgMCk7CisgICAgICAgIG11c3RGYWlsKGdldFN0cmljdCgpLCAiIFxuIDEgSmFuIDIwMTUgMDA6MDAgKzAwMDAiLCAxKTsKKyAgICAgICAgbXVzdEZhaWwoZ2V0U3RyaWN0KCksICIgXHJcbjEgSmFuIDIwMTUgMDA6MDAgKzAwMDAiLCAwKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIFBhcnNpbmcgLSBkYXktbmFtZSBhbmQgbW9udGgtbmFtZQorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgbXVzdEFjY2VwdFZhbGlkRGF5TW9udGhOYW1lcygpIHsKKyAgICAgICAgU2ltcGxlRGF0ZUZvcm1hdCBmbXQgPSBnZXREZWZhdWx0KCk7CisgICAgICAgIGZvciAoU3RyaW5nIGRheU1vbnRoIDogbmV3IFN0cmluZ1tdeworICAgICAgICAgICAgIk1vbiwgNSBKYW4iLCAiVHVlLCAzIEZlYiIsICJXZWQsIDQgTWFyIiwgIlRodSwgMiBBcHIiLAorICAgICAgICAgICAgIkZyaSwgMSBNYXkiLCAiU2F0LCA2IEp1biIsICJTdW4sIDUgSnVsIiwgIlNhdCwgMSBBdWciLAorICAgICAgICAgICAgIlR1ZSwgMSBTZXAiLCAiVGh1LCAxIE9jdCIsICJTdW4sIDEgTm92IiwgIlR1ZSwgMSBEZWMiCisgICAgICAgIH0pIHsKKyAgICAgICAgICAgIG11c3RQYXNzKGZtdCwgZGF5TW9udGggKyAiIDIwMTUgMDA6MDA6MDAgKzAwMDAiKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgc3RyaWN0TXVzdE1hdGNoRGF5TmFtZUNhc2VTZW5zaXRpdmUoKSB7CisgICAgICAgIG11c3RGYWlsKGdldFN0cmljdCgpLCAidEhVLCAxIEphbiAyMDE1IDAwOjAwICswMDAwIiwgMCk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBzdHJpY3RNdXN0TWF0Y2hNb250aE5hbWVDYXNlU2Vuc2l0aXZlKCkgeworICAgICAgICBtdXN0RmFpbChnZXRTdHJpY3QoKSwgIjEgakFOIDIwMTUgMDA6MDAgKzAwMDAiLCAyKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIFBhcnNpbmcgLSB5ZWFyCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBsZW5pZW50TXVzdEFjY2VwdFNpbmdsZURpZ2l0WWVhcnMoKSB7CisgICAgICAgIG11c3RQYXNzKGdldExlbmllbnQoKSwgIjEgSmFuIDEgMDA6MDAgKzAwMDAiKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIGxlbmllbnRNdXN0QWNjZXB0WWVhcnNCZXR3ZWVuMTAwMGFuZDE4OTkoKSB7CisgICAgICAgIG11c3RQYXNzKGdldExlbmllbnQoKSwgIjEgSmFuIDk5OSAwMDowMCArMDAwMCIpOworICAgICAgICBtdXN0UGFzcyhnZXRMZW5pZW50KCksICIxIEphbiAxMDAwIDAwOjAwICswMDAwIik7CisgICAgICAgIG11c3RQYXNzKGdldExlbmllbnQoKSwgIjEgSmFuIDE4OTkgMDA6MDAgKzAwMDAiKTsKKyAgICAgICAgbXVzdFBhc3MoZ2V0U3RyaWN0KCksICIxIEphbiAxOTAwIDAwOjAwICswMDAwIik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBsZW5pZW50TXVzdEFkZDE5MDBUbzNEaWdpdFllYXIoKSB7CisgICAgICAgIERhdGUgZGF0ZSA9IG11c3RQYXNzKGdldExlbmllbnQoKSwgIjEgSnVsIDkwMCAwMDowMCArMDAwMCIpOworICAgICAgICBhc3NlcnRUaGF0RGF0ZShkYXRlLCAiU2F0LCAxIEp1bCAyODAwIDAwOjAwOjAwICswMDAwIChVVEMpIik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBzdHJpY3RNdXN0UmVqZWN0QWxsWWVhcnNMdDE5MDAoKSB7CisgICAgICAgIG11c3RGYWlsKGdldFN0cmljdCgpLCAiMSBKYW4gMDAwMDAxIDAwOjAwICswMDAwIiwgNik7CisgICAgICAgIG11c3RGYWlsKGdldFN0cmljdCgpLCAiMSBKYW4gOTk5IDAwOjAwICswMDAwIiwgNik7CisgICAgICAgIG11c3RGYWlsKGdldFN0cmljdCgpLCAiMSBKYW4gMTAwMCAwMDowMCArMDAwMCIsIDYpOworICAgICAgICBtdXN0RmFpbChnZXRTdHJpY3QoKSwgIjEgSmFuIDE4OTkgMDA6MDAgKzAwMDAiLCA2KTsKKyAgICAgICAgbXVzdFBhc3MoZ2V0U3RyaWN0KCksICIxIEphbiAxOTAwIDAwOjAwICswMDAwIik7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBQYXJzaW5nIC0gc2Vjb25kCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBtdXN0UGFyc2VMZWFwU2Vjb25kQXNKc3IzMTAoKSB7CisgICAgICAgIC8vIEpTUi0zMTAgcmVwbGFjZXMgNjAgd2l0aCA1OQorICAgICAgICBEYXRlIGRhdGUgPSBtdXN0UGFzcyhnZXREZWZhdWx0KCksICIzMCBKdW4gMjAxMiAyMzo1OTo2MCArMDAwMCIpOworICAgICAgICAvLyBEYXRlLmZyb20oSVNPX0lOU1RBTlQucGFyc2UoIjIwMTItMDYtMzBUMjM6NTk6NjBaIiwgSW5zdGFudDo6ZnJvbSkpCisgICAgICAgIGFzc2VydFRoYXQoZGF0ZSwgaXMobmV3IERhdGUoMTM0MTEwMDc5OTAwMEwpKSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBQYXJzaW5nIC0gem9uZQorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgbXVzdFBhcnNlTmVnYXRpdmVaZXJvZXNab25lQXNVdGMoKSB7CisgICAgICAgIERhdGUgZGF0ZSA9IG11c3RQYXNzKGdldERlZmF1bHQoKSwgIjEgSmFuIDIwMTUgMDA6MDAgLTAwMDAiKTsKKyAgICAgICAgYXNzZXJ0VGhhdERhdGUoZGF0ZSwgIlRodSwgMSBKYW4gMjAxNSAwMDowMDowMCArMDAwMCAoVVRDKSIpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgbXVzdENvcnJlY3RseVBhcnNlSW5wdXRXaXRoVHJhaWxpbmdEaWdpdHMoKSB7CisgICAgICAgIERhdGUgZGF0ZSA9IG11c3RQYXNzKGdldFN0cmljdCgpLCAiMSBKYW4gMjAxNSAwMDowMCAtMDAxNTMwIik7CisgICAgICAgIGFzc2VydFRoYXREYXRlKGRhdGUsICJUaHUsIDEgSmFuIDIwMTUgMDA6MTU6MDAgKzAwMDAgKFVUQykiKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIG11c3RBY2NlcHRab25lV2l0aEV4dHJlbWVPZmZzZXQoKSB7CisgICAgICAgIERhdGUgZGF0ZSA9IG11c3RQYXNzKGdldFN0cmljdCgpLCAiMSBKYW4gMjAxNSAwMDowMCArOTk1OSIpOworICAgICAgICBEYXRlIGVxdWl2YWxlbnRXaXRob3V0T2Zmc2V0ID0gbXVzdFBhc3MoZ2V0U3RyaWN0KCksCisgICAgICAgICAgICAgICAgIjI3IERlYyAyMDE0IDIwOjAxICswMDAwIik7CisgICAgICAgIGFzc2VydFRoYXQoZGF0ZSwgaXMoZXF1aXZhbGVudFdpdGhvdXRPZmZzZXQpKTsKKworICAgICAgICBkYXRlID0gbXVzdFBhc3MoZ2V0U3RyaWN0KCksICIxIEphbiAyMDE1IDAwOjAwIC05OTU5Iik7CisgICAgICAgIGVxdWl2YWxlbnRXaXRob3V0T2Zmc2V0ID0gbXVzdFBhc3MoZ2V0U3RyaWN0KCksCisgICAgICAgICAgICAgICAgIjUgSmFuIDIwMTUgMDM6NTkgKzAwMDAiKTsKKyAgICAgICAgYXNzZXJ0VGhhdChkYXRlLCBpcyhlcXVpdmFsZW50V2l0aG91dE9mZnNldCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgbGVuaWVudE11c3RBY2NlcHROb25NaWxpdGFyeVpvbmVOYW1lcygpIHsKKyAgICAgICAgU2ltcGxlRGF0ZUZvcm1hdCBmbXQgPSBnZXRMZW5pZW50KCk7CisgICAgICAgIGZvciAoU3RyaW5nIHpvbmVOYW1lIDogbmV3IFN0cmluZ1tdeyJHTVQiLCAiVVQiLAorICAgICAgICAgICAgIkVEVCIsICJFU1QiLCAiQ0RUIiwgIkNTVCIsICJNRFQiLCAiTVNUIiwgIlBEVCIsICJQU1QifSkgeworICAgICAgICAgICAgbXVzdFBhc3MoZm10LCAiMSBKYW4gMjAxNSAwMDowMCAiICsgem9uZU5hbWUpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBzdHJpY3RNdXN0TWF0Y2hab25lKCkgeworICAgICAgICBtdXN0RmFpbChnZXRTdHJpY3QoKSwgIjEgSmFuIDIwMTUgMDA6MDAiLCAxNik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCBzdHJpY3RNdXN0UmVqZWN0Wm9uZU9mZnNldE1pbnV0ZXNHcmVhdGVyVGhhbjYwKCkgeworICAgICAgICBtdXN0RmFpbChnZXRTdHJpY3QoKSwgIjEgSmFuIDIwMTUgMDA6MDAgKzAwNjAiLCAxNyk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBVbnN1cHBvcnRlZCBtZXRob2RzLiBXaGVuIHBvc3NpYmxlLCB0aGUgdGVzdCBhbHNvIGRlbW9uc3RyYXRlcyAKKyAgICAgKiB3aHkgaW52b2tpbmcgdGhlIG1ldGhvZCBtdXN0IGJlIHByb2hpYml0ZWQuCisgICAgICovCisgICAgQFRlc3QoZXhwZWN0ZWQgPSBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbi5jbGFzcykKKyAgICBwdWJsaWMgdm9pZCBtdXN0UHJvaGliaXRTZXRDYWxlbmRhcigpIHsKKyAgICAgICAgZ2V0RGVmYXVsdCgpLnNldENhbGVuZGFyKENhbGVuZGFyLmdldEluc3RhbmNlKCkpOworICAgIH0KKworICAgIEBUZXN0KGV4cGVjdGVkID0gVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24uY2xhc3MpCisgICAgcHVibGljIHZvaWQgbXVzdFByb2hpYml0U2V0TnVtYmVyRm9ybWF0KCkgeworICAgICAgICBnZXREZWZhdWx0KCkuc2V0TnVtYmVyRm9ybWF0KE51bWJlckZvcm1hdC5nZXRJbnN0YW5jZSgpKTsKKyAgICB9CisKKyAgICBAVGVzdChleHBlY3RlZCA9IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uLmNsYXNzKQorICAgIHB1YmxpYyB2b2lkIG11c3RQcm9oaWJpdEFwcGx5TG9jYWxpemVkUGF0dGVybigpIHsKKyAgICAgICAgU2ltcGxlRGF0ZUZvcm1hdCBmbXQgPSBnZXRTdHJpY3QoKTsKKyAgICAgICAgZm10LmFwcGx5TG9jYWxpemVkUGF0dGVybigieXl5eSIpOworICAgICAgICBEYXRlIGRhdGUgPSBtdXN0UGFzcyhmbXQsICIxIEphbiAyMDE1IDAwOjAwOjAwICswMDAwIik7CisgICAgICAgIGFzc2VydFRoYXQoZm10LmZvcm1hdChkYXRlKSwgaXMoIjIwMTUiKSk7CisgICAgfQorCisgICAgQFRlc3QoZXhwZWN0ZWQgPSBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbi5jbGFzcykKKyAgICBwdWJsaWMgdm9pZCBtdXN0UHJvaGliaXRBcHBseVBhdHRlcm4oKSB7CisgICAgICAgIFNpbXBsZURhdGVGb3JtYXQgZm10ID0gZ2V0U3RyaWN0KCk7CisgICAgICAgIGZtdC5hcHBseVBhdHRlcm4oInl5eXkiKTsKKyAgICAgICAgRGF0ZSBkYXRlID0gbXVzdFBhc3MoZm10LCAiMSBKYW4gMjAxNSAwMDowMDowMCArMDAwMCIpOworICAgICAgICBhc3NlcnRUaGF0KGZtdC5mb3JtYXQoZGF0ZSksIGlzKCIyMDE1IikpOworICAgIH0KKworICAgIEBUZXN0KGV4cGVjdGVkID0gVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24uY2xhc3MpCisgICAgcHVibGljIHZvaWQgbXVzdFByb2hpYml0R2V0MkRpZ2l0WWVhclN0YXJ0KCkgeworICAgICAgICBnZXREZWZhdWx0KCkuZ2V0MkRpZ2l0WWVhclN0YXJ0KCk7CisgICAgfQorCisgICAgQFRlc3QoZXhwZWN0ZWQgPSBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbi5jbGFzcykKKyAgICBwdWJsaWMgdm9pZCBtdXN0UHJvaGliaXRTZXQyRGlnaXRZZWFyU3RhcnQoKSB7CisgICAgICAgIGdldERlZmF1bHQoKS5zZXQyRGlnaXRZZWFyU3RhcnQobmV3IERhdGUoKSk7CisgICAgfQorCisgICAgQFRlc3QoZXhwZWN0ZWQgPSBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbi5jbGFzcykKKyAgICBwdWJsaWMgdm9pZCBtdXN0UHJvaGliaXRTZXREYXRlRm9ybWF0U3ltYm9scygpIHsKKyAgICAgICAgU2ltcGxlRGF0ZUZvcm1hdCBmbXQgPSBnZXRTdHJpY3QoKTsKKyAgICAgICAgZm10LnNldERhdGVGb3JtYXRTeW1ib2xzKG5ldyBEYXRlRm9ybWF0U3ltYm9scyhMb2NhbGUuRlJFTkNIKSk7CisgICAgICAgIERhdGUgZGF0ZSA9IG11c3RQYXNzKGZtdCwgIjEgSmFuIDIwMTUgMDA6MDA6MDAgKzAwMDAiKTsKKyAgICAgICAgYXNzZXJ0VGhhdERhdGUoZGF0ZSwgImpldS4sIDEgamFudi4gMjAxNSAwMDowMDowMCArMDAwMCAoVVRDKSIpOworICAgIH0KKworICAgIC8qCisgICAgICogSGVscGVyIG1ldGhvZHMKKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBTaW1wbGVEYXRlRm9ybWF0IGdldERlZmF1bHQoKSB7CisgICAgICAgIHJldHVybiBuZXcgTWFpbERhdGVGb3JtYXQoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBTaW1wbGVEYXRlRm9ybWF0IGdldExlbmllbnQoKSB7CisgICAgICAgIFNpbXBsZURhdGVGb3JtYXQgZm10ID0gZ2V0RGVmYXVsdCgpOworICAgICAgICBmbXQuc2V0TGVuaWVudCh0cnVlKTsKKyAgICAgICAgcmV0dXJuIGZtdDsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBTaW1wbGVEYXRlRm9ybWF0IGdldFN0cmljdCgpIHsKKyAgICAgICAgU2ltcGxlRGF0ZUZvcm1hdCBmbXQgPSBnZXREZWZhdWx0KCk7CisgICAgICAgIGZtdC5zZXRMZW5pZW50KGZhbHNlKTsKKyAgICAgICAgcmV0dXJuIGZtdDsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0VGhhdERhdGUoRGF0ZSBkYXRlLCBTdHJpbmcgZm9ybWF0dGVkRGF0ZSkgeworICAgICAgICBTaW1wbGVEYXRlRm9ybWF0IGZtdCA9IGdldERlZmF1bHQoKTsKKyAgICAgICAgZm10LnNldFRpbWVab25lKFRpbWVab25lLmdldFRpbWVab25lKCJVVEMiKSk7CisgICAgICAgIGFzc2VydFRoYXQoZm10LmZvcm1hdChkYXRlKSwgaXMoZm9ybWF0dGVkRGF0ZSkpOworICAgIH0KKworICAgIHByaXZhdGUgRGF0ZSBtdXN0UGFzcyhEYXRlRm9ybWF0IGZtdCwgU3RyaW5nIGlucHV0KSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBEYXRlIGRhdGUgPSBmbXQucGFyc2UoaW5wdXQpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbChkYXRlKTsKKyAgICAgICAgICAgIHJldHVybiBkYXRlOworICAgICAgICB9IGNhdGNoIChQYXJzZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsKFN0cmluZy5mb3JtYXQoIiclcycgaXMgYSB2YWxpZCBkYXRlIGluICVzIG1vZGUiLCBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgZm10LmlzTGVuaWVudCgpID8gImxlbmllbnQiIDogInN0cmljdCIpKTsKKyAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIG11c3RGYWlsKERhdGVGb3JtYXQgZm10LCBTdHJpbmcgaW5wdXQsIGludCBlcnJvck9mZnNldCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgRGF0ZSByZXN1bHQgPSBmbXQucGFyc2UoaW5wdXQpOworICAgICAgICAgICAgZmFpbChTdHJpbmcuZm9ybWF0KCInJXMnIGlzIG5vdCBhIHZhbGlkIGRhdGUgaW4gJXMgbW9kZSIsIGlucHV0LAorICAgICAgICAgICAgICAgICAgICBmbXQuaXNMZW5pZW50KCkgPyAibGVuaWVudCIgOiAic3RyaWN0IikpOworICAgICAgICB9IGNhdGNoIChQYXJzZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBhc3NlcnRUaGF0KGUuZ2V0RXJyb3JPZmZzZXQoKSwgaXMoZXJyb3JPZmZzZXQpKTsKKyAgICAgICAgfQorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvTWltZUJvZHlQYXJ0VGVzdC5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvTWltZUJvZHlQYXJ0VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhjNzg3NWEKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy90ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9NaW1lQm9keVBhcnRUZXN0LmphdmEKQEAgLTAsMCArMSwyMDQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMTEsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5pbnRlcm5ldDsKKworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXQ7CitpbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7CisKK2ltcG9ydCBqYXZheC5hY3RpdmF0aW9uLkRhdGFIYW5kbGVyOworCitpbXBvcnQgamF2YXgubWFpbC4qOworCitpbXBvcnQgY29tLnN1bi5tYWlsLnRlc3QuQXNjaWlTdHJpbmdJbnB1dFN0cmVhbTsKKworaW1wb3J0IG9yZy5qdW5pdC4qOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydFRydWU7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RmFsc2U7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RXF1YWxzOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEFycmF5RXF1YWxzOworCisvKioKKyAqIFRlc3QgdGhlIE1pbWVCb2R5UGFydCBjbGFzcy4KKyAqLworcHVibGljIGNsYXNzIE1pbWVCb2R5UGFydFRlc3QgeworIAorICAgIHByaXZhdGUgc3RhdGljIFN0cmluZ1tdIGxhbmd1YWdlcyA9IG5ldyBTdHJpbmdbXSB7CisJICAgICJsYW5ndWFnZTEiLCAibGFuZ3VhZ2UyIiwgImxhbmd1YWdlMyIsICJsYW5ndWFnZTQiLCAibGFuZ3VhZ2U1IiwKKwkgICAgImxhbmd1YWdlNiIsICJsYW5ndWFnZTciLCAibGFuZ3VhZ2U4IiwgImxhbmd1YWdlOSIsICJsYW5ndWFnZTEwIiwKKwkgICAgImxhbmd1YWdlMTEiLCAibGFuZ3VhZ2UxMiIsICJsYW5ndWFnZTEzIiwgImxhbmd1YWdlMTQiLCAibGFuZ3VhZ2UxNSIKKwl9OworCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IHRoZSBDb250ZW50LUxhbmd1YWdlIGhlYWRlciBpcyBwcm9wZXJseSBmb2xkZWQKKyAgICAgKiBpZiB0aGVyZSBhcmUgYSBsb3Qgb2YgbGFuZ3VhZ2VzLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENvbnRlbnRMYW5ndWFnZUZvbGQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlNaW1lQm9keVBhcnQgbWJwID0gbmV3IE1pbWVCb2R5UGFydCgpOworCW1icC5zZXRDb250ZW50TGFuZ3VhZ2UobGFuZ3VhZ2VzKTsKKwlTdHJpbmcgaGVhZGVyID0gbWJwLmdldEhlYWRlcigiQ29udGVudC1MYW5ndWFnZSIsICIsIik7CisJYXNzZXJ0VHJ1ZShoZWFkZXIuaW5kZXhPZigiXHJcbiIpID4gMCk7CisKKwlTdHJpbmdbXSBsYW5ncyA9IG1icC5nZXRDb250ZW50TGFuZ3VhZ2UoKTsKKwlhc3NlcnRBcnJheUVxdWFscyhsYW5ndWFnZXMsIGxhbmdzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHRoYXQgY29weWluZyBhIERhdGFIYW5kbGVyIGZyb20gb25lIG1lc3NhZ2UgdG8gYW5vdGhlcgorICAgICAqIGhhcyB0aGUgZGVzaXJlZCBlZmZlY3QuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q29weURhdGFIYW5kbGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJU2Vzc2lvbiBzID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShuZXcgUHJvcGVydGllcygpKTsKKwkvLyBjcmVhdGUgYSBtZXNzYWdlIGFuZCBleHRyYWN0IHRoZSBEYXRhSGFuZGxlciBmb3IgYSBwYXJ0CisJTWltZU1lc3NhZ2Ugb3JpZyA9IGNyZWF0ZU1lc3NhZ2Uocyk7CisJTWltZU11bHRpcGFydCBvbXAgPSAoTWltZU11bHRpcGFydClvcmlnLmdldENvbnRlbnQoKTsKKwlNaW1lQm9keVBhcnQgb2JwID0gKE1pbWVCb2R5UGFydClvbXAuZ2V0Qm9keVBhcnQoMCk7CisJRGF0YUhhbmRsZXIgZGggPSBvYnAuZ2V0RGF0YUhhbmRsZXIoKTsKKwkvLyBjcmVhdGUgYSBuZXcgbWVzc2FnZSBhbmQgdXNlIHRoZSBEYXRhSGFuZGxlcgorCU1pbWVNZXNzYWdlIG1zZyA9IG5ldyBNaW1lTWVzc2FnZShzKTsKKwlNaW1lTXVsdGlwYXJ0IG1wID0gbmV3IE1pbWVNdWx0aXBhcnQoKTsKKwlNaW1lQm9keVBhcnQgbWJwID0gbmV3IE1pbWVCb2R5UGFydCgpOworCW1icC5zZXREYXRhSGFuZGxlcihkaCk7CisJbXAuYWRkQm9keVBhcnQobWJwKTsKKwltc2cuc2V0Q29udGVudChtcCk7CisJLy8gZGVwZW5kIG9uIGNvcHkgY29uc3RydWN0b3Igc3RyZWFtaW5nIHRoZSBkYXRhCisJbXNnID0gbmV3IE1pbWVNZXNzYWdlKG1zZyk7CisJbXAgPSAoTWltZU11bHRpcGFydCltc2cuZ2V0Q29udGVudCgpOworCW1icCA9IChNaW1lQm9keVBhcnQpbXAuZ2V0Qm9keVBhcnQoMCk7CisJYXNzZXJ0RXF1YWxzKCJ0ZXh0L3gtdGVzdCIsIG1icC5nZXRDb250ZW50VHlwZSgpKTsKKwlhc3NlcnRFcXVhbHMoInF1b3RlZC1wcmludGFibGUiLCBtYnAuZ2V0RW5jb2RpbmcoKSk7CisJYXNzZXJ0RXF1YWxzKCJ0ZXN0IHBhcnQiLCBnZXRTdHJpbmcobWJwLmdldElucHV0U3RyZWFtKCkpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHRoYXQgY29weWluZyBhIERhdGFIYW5kbGVyIGZyb20gb25lIG1lc3NhZ2UgdG8gYW5vdGhlcgorICAgICAqIGJ5IHNldHRpbmcgdGhlICJkaCIgZmllbGQgaW4gYSBzdWJjbGFzcyBoYXMgdGhlIGRlc2lyZWQgZWZmZWN0LgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFNldERhdGFIYW5kbGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJU2Vzc2lvbiBzID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShuZXcgUHJvcGVydGllcygpKTsKKwkvLyBjcmVhdGUgYSBtZXNzYWdlIGFuZCBleHRyYWN0IHRoZSBEYXRhSGFuZGxlciBmb3IgYSBwYXJ0CisJTWltZU1lc3NhZ2Ugb3JpZyA9IGNyZWF0ZU1lc3NhZ2Uocyk7CisJTWltZU11bHRpcGFydCBvbXAgPSAoTWltZU11bHRpcGFydClvcmlnLmdldENvbnRlbnQoKTsKKwlNaW1lQm9keVBhcnQgb2JwID0gKE1pbWVCb2R5UGFydClvbXAuZ2V0Qm9keVBhcnQoMCk7CisJZmluYWwgRGF0YUhhbmRsZXIgb2RoID0gb2JwLmdldERhdGFIYW5kbGVyKCk7CisJLy8gY3JlYXRlIGEgbmV3IG1lc3NhZ2UgYW5kIHVzZSB0aGUgRGF0YUhhbmRsZXIKKwlNaW1lTWVzc2FnZSBtc2cgPSBuZXcgTWltZU1lc3NhZ2Uocyk7CisJTWltZU11bHRpcGFydCBtcCA9IG5ldyBNaW1lTXVsdGlwYXJ0KCk7CisJTWltZUJvZHlQYXJ0IG1icCA9IG5ldyBNaW1lQm9keVBhcnQoKSB7CisJCXsgZGggPSBvZGg7IH0KKwkgICAgfTsKKwltcC5hZGRCb2R5UGFydChtYnApOworCW1zZy5zZXRDb250ZW50KG1wKTsKKwkvLyBkZXBlbmQgb24gY29weSBjb25zdHJ1Y3RvciBzdHJlYW1pbmcgdGhlIGRhdGEKKwltc2cgPSBuZXcgTWltZU1lc3NhZ2UobXNnKTsKKwltcCA9IChNaW1lTXVsdGlwYXJ0KW1zZy5nZXRDb250ZW50KCk7CisJbWJwID0gKE1pbWVCb2R5UGFydCltcC5nZXRCb2R5UGFydCgwKTsKKwlhc3NlcnRFcXVhbHMoInRleHQveC10ZXN0IiwgbWJwLmdldENvbnRlbnRUeXBlKCkpOworCWFzc2VydEVxdWFscygicXVvdGVkLXByaW50YWJsZSIsIG1icC5nZXRFbmNvZGluZygpKTsKKwlhc3NlcnRFcXVhbHMoInRlc3QgcGFydCIsIGdldFN0cmluZyhtYnAuZ2V0SW5wdXRTdHJlYW0oKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCBhIE1pbWVCb2R5UGFydCBjcmVhdGVkIGZyb20gYSBzdHJlYW0gd2l0aCB1bmVuY29kZWQgZGF0YQorICAgICAqIHdpbGwgaGF2ZSB0aGUgZGF0YSBiZSBlbmNvZGVkIHdoZW4gdGhlIGRhdGEgaXMgY29waWVkIHRvIGFub3RoZXIKKyAgICAgKiBNaW1lQm9keVBhcnQgYnkgY29weWluZyB0aGUgRGF0YUhhbmRsZXIuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW5jb2RpbmdDb3BpZWREYXRhSGFuZGxlcigpIHRocm93cyBFeGNlcHRpb24geworCVN0cmluZyBwYXJ0ID0gCisJICAgICJDb250ZW50LVR5cGU6IGFwcGxpY2F0aW9uL3gtdGVzdFxuIiArCisJICAgICJcbiIgKworCSAgICAiXHUwMDAxXHUwMDAyXHUwMDAzIiArCisJICAgICJcbiI7CisJTWltZUJvZHlQYXJ0IG1icCA9IG5ldyBNaW1lQm9keVBhcnQobmV3IEFzY2lpU3RyaW5nSW5wdXRTdHJlYW0ocGFydCkpOworCU1pbWVCb2R5UGFydCBtYnAyID0gbmV3IE1pbWVCb2R5UGFydCgpIHsKKwkgICAgQE92ZXJyaWRlCisJICAgIHB1YmxpYyB2b2lkIHNldERhdGFIYW5kbGVyKERhdGFIYW5kbGVyIGRoKQorCQkJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJCXN1cGVyLnNldERhdGFIYW5kbGVyKGRoKTsKKwkJdXBkYXRlSGVhZGVycygpOworCSAgICB9CisJfTsKKwltYnAyLnNldERhdGFIYW5kbGVyKG1icC5nZXREYXRhSGFuZGxlcigpKTsKKwlhc3NlcnRFcXVhbHMoImJhc2U2NCIsIG1icDIuZ2V0RW5jb2RpbmcoKSk7CisJLy8gZW5zdXJlIHRoZSBkYXRhIGlzIGNvcnJlY3QgYnkgcmVhZGluZyB0aGUgZmlyc3QgYnl0ZQorCUlucHV0U3RyZWFtIGluID0gbWJwMi5nZXRJbnB1dFN0cmVhbSgpOworCWFzc2VydEVxdWFscygxLCBpbi5yZWFkKCkpOworCWluLmNsb3NlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IGlzTWltZVR5cGUgZG9lcyBzb21ldGhpbmcgcmVhc29uYWJsZSBldmVuIGlmIHRoZQorICAgICAqIENvbnRlbnQtVHlwZSBoZWFkZXIgY2FuJ3QgYmUgcGFyc2VkIGJlY2F1c2Ugb2YgYSBiYWQgcGFyYW1ldGVyLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdElzTWltZVR5cGVCYWRQYXJhbWV0ZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlTdHJpbmcgcGFydCA9IAorCSAgICAiQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXRlc3Q7IHR5cGU9YS9iXG4iICsKKwkgICAgIlxuIiArCisJICAgICJcbiI7CisJTWltZUJvZHlQYXJ0IG1icCA9IG5ldyBNaW1lQm9keVBhcnQobmV3IEFzY2lpU3RyaW5nSW5wdXRTdHJlYW0ocGFydCkpOworCWFzc2VydFRydWUoImNvbXBsZXRlIE1JTUUgdHlwZSIsIG1icC5pc01pbWVUeXBlKCJhcHBsaWNhdGlvbi94LXRlc3QiKSk7CisJYXNzZXJ0VHJ1ZSgicGF0dGVybiBNSU1FIHR5cGUiLCBtYnAuaXNNaW1lVHlwZSgiYXBwbGljYXRpb24vKiIpKTsKKwlhc3NlcnRGYWxzZSgid3JvbmcgTUlNRSB0eXBlIiwgbWJwLmlzTWltZVR5cGUoImFwcGxpY2F0aW9uL3Rlc3QiKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IGEgQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZyBoZWFkZXIgd2l0aCBubyB2YWx1ZSBkb2Vzbid0CisgICAgICogY2F1c2UgYW4gSU9FeGNlcHRpb24uCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW1wdHlDb250ZW50VHJhbnNmZXJFbmNvZGluZygpIHRocm93cyBFeGNlcHRpb24geworCVN0cmluZyBwYXJ0ID0gCisJICAgICJDb250ZW50LVR5cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9XCJ1cy1hc2NpaVwiXG4iICsKKwkgICAgIkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IFxuIiArCisJICAgICJcbiIgKworCSAgICAidGVzdCIgKworCSAgICAiXG4iOworCU1pbWVCb2R5UGFydCBtYnAgPSBuZXcgTWltZUJvZHlQYXJ0KG5ldyBBc2NpaVN0cmluZ0lucHV0U3RyZWFtKHBhcnQpKTsKKwlhc3NlcnRFcXVhbHMoImVtcHR5IEMtVC1FIHZhbHVlIiwgbnVsbCwgbWJwLmdldEVuY29kaW5nKCkpOworCWFzc2VydEVxdWFscygiZW1wdHkgQy1ULUUgZGF0YSIsICJ0ZXN0XG4iLCBtYnAuZ2V0Q29udGVudCgpKTsKKyAgICB9CisKKworICAgIHByaXZhdGUgc3RhdGljIE1pbWVNZXNzYWdlIGNyZWF0ZU1lc3NhZ2UoU2Vzc2lvbiBzKQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgY29udGVudCA9CisJICAgICJNaW1lLVZlcnNpb246IDEuMFxuIiArCisJICAgICJTdWJqZWN0OiBFeGFtcGxlXG4iICsKKwkgICAgIkNvbnRlbnQtVHlwZTogbXVsdGlwYXJ0L21peGVkOyBib3VuZGFyeT1cIi1cIlxuIiArCisJICAgICJcbiIgKworCSAgICAicHJlYW1ibGVcbiIgKworCSAgICAiLS0tXG4iICsKKwkgICAgIkNvbnRlbnQtVHlwZTogdGV4dC94LXRlc3RcbiIgKworCSAgICAiQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogcXVvdGVkLXByaW50YWJsZVxuIiArCisJICAgICJcbiIgKworCSAgICAidGVzdCBwYXJ0XG4iICsKKwkgICAgIlxuIiArCisJICAgICItLS0tLVxuIjsKKworCXJldHVybiBuZXcgTWltZU1lc3NhZ2UocywgbmV3IEFzY2lpU3RyaW5nSW5wdXRTdHJlYW0oY29udGVudCkpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBnZXRTdHJpbmcoSW5wdXRTdHJlYW0gaXMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJQnVmZmVyZWRSZWFkZXIgciA9IG5ldyBCdWZmZXJlZFJlYWRlcihuZXcgSW5wdXRTdHJlYW1SZWFkZXIoaXMpKTsKKwlyZXR1cm4gci5yZWFkTGluZSgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L01pbWVCb2R5UGFydFRlc3RTdWl0ZS5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvTWltZUJvZHlQYXJ0VGVzdFN1aXRlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGU1ZTg3MQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L01pbWVCb2R5UGFydFRlc3RTdWl0ZS5qYXZhCkBAIC0wLDAgKzEsMzYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMTUsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5pbnRlcm5ldDsKKworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVycy5TdWl0ZS5TdWl0ZUNsYXNzZXM7CisKK2ltcG9ydCBjb20uc3VuLm1haWwudGVzdC5DbGFzc0xvYWRlclN1aXRlOworaW1wb3J0IGNvbS5zdW4ubWFpbC50ZXN0LkNsYXNzTG9hZGVyU3VpdGUuVGVzdENsYXNzOworCisvKioKKyAqIFN1aXRlIG9mIE1pbWVCb2R5UGFydCB0ZXN0cyB0aGF0IG5lZWQgdG8gYmUgcnVuIGluIGEgc2VwYXJhdGUgY2xhc3MgbG9hZGVyLgorICovCitAUnVuV2l0aChDbGFzc0xvYWRlclN1aXRlLmNsYXNzKQorQFRlc3RDbGFzcyhNaW1lQm9keVBhcnQuY2xhc3MpCitAU3VpdGVDbGFzc2VzKCB7CisgICAgTm9FbmNvZGVGaWxlTmFtZS5jbGFzcywKKyAgICBFbmNvZGVGaWxlTmFtZS5jbGFzcywKKyAgICBFbmNvZGVGaWxlTmFtZU5vRW5jb2RlUGFyYW1ldGVycy5jbGFzcworfSkKK3B1YmxpYyBjbGFzcyBNaW1lQm9keVBhcnRUZXN0U3VpdGUgeworfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvTWltZU1lc3NhZ2VUZXN0LmphdmEgYi9tYWlsL3NyYy90ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9NaW1lTWVzc2FnZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMjNmMmJjCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvTWltZU1lc3NhZ2VUZXN0LmphdmEKQEAgLTAsMCArMSwyMTggQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5pbnRlcm5ldDsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC50ZXN0LkFzY2lpU3RyaW5nSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldDsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKK2ltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247CisKK2ltcG9ydCBqYXZheC5hY3RpdmF0aW9uLkRhdGFIYW5kbGVyOworCitpbXBvcnQgamF2YXgubWFpbC4qOworaW1wb3J0IHN0YXRpYyBqYXZheC5tYWlsLk1lc3NhZ2UuUmVjaXBpZW50VHlwZS4qOworaW1wb3J0IHN0YXRpYyBqYXZheC5tYWlsLmludGVybmV0Lk1pbWVNZXNzYWdlLlJlY2lwaWVudFR5cGUuKjsKKworaW1wb3J0IG9yZy5qdW5pdC4qOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEFycmF5RXF1YWxzOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEVxdWFsczsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUcnVlOworCisvKioKKyAqIFRlc3QgTWltZU1lc3NhZ2UgbWV0aG9kcy4KKyAqCisgKiBYWFggLSBqdXN0IGEgYmVnaW5uaW5nLi4uCisgKgorICogQGF1dGhvciBCaWxsIFNoYW5ub24KKyAqLworcHVibGljIGNsYXNzIE1pbWVNZXNzYWdlVGVzdCB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTZXNzaW9uIHMgPSBTZXNzaW9uLmdldEluc3RhbmNlKG5ldyBQcm9wZXJ0aWVzKCkpOworCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IHNldFJlY2lwaWVudHMgd2l0aCBhIG51bGwgc3RyaW5nIGFkZHJlc3MgcmVtb3ZlcyB0aGUgaGVhZGVyLgorICAgICAqIChCdWcgNzAyMTE5MCkKKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRSZWNpcGllbnRzU3RyaW5nTnVsbCgpIHRocm93cyBFeGNlcHRpb24geworCVN0cmluZyBhZGRyID0gImpvZUBleGFtcGxlLmNvbSI7CisJTWltZU1lc3NhZ2UgbSA9IG5ldyBNaW1lTWVzc2FnZShzKTsKKwltLnNldFJlY2lwaWVudHMoVE8sIGFkZHIpOworCWFzc2VydEVxdWFscygiVG86IGlzIHNldCIsIGFkZHIsIG0uZ2V0UmVjaXBpZW50cyhUTylbMF0udG9TdHJpbmcoKSk7CisJbS5zZXRSZWNpcGllbnRzKFRPLCAoU3RyaW5nKW51bGwpOworCWFzc2VydEFycmF5RXF1YWxzKCJUbzogaXMgcmVtb3ZlZCIsIG51bGwsIG0uZ2V0UmVjaXBpZW50cyhUTykpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCBzZXRSZWNpcGllbnQgd2l0aCBhIG51bGwgc3RyaW5nIGFkZHJlc3MgcmVtb3ZlcyB0aGUgaGVhZGVyLgorICAgICAqIChCdWcgNzUzNikKKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRSZWNpcGllbnRTdHJpbmdOdWxsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJU3RyaW5nIGFkZHIgPSAiam9lQGV4YW1wbGUuY29tIjsKKwlNaW1lTWVzc2FnZSBtID0gbmV3IE1pbWVNZXNzYWdlKHMpOworCW0uc2V0UmVjaXBpZW50KFRPLCBuZXcgSW50ZXJuZXRBZGRyZXNzKGFkZHIpKTsKKwlhc3NlcnRFcXVhbHMoIlRvOiBpcyBzZXQiLCBhZGRyLCBtLmdldFJlY2lwaWVudHMoVE8pWzBdLnRvU3RyaW5nKCkpOworCW0uc2V0UmVjaXBpZW50KFRPLCAoQWRkcmVzcyludWxsKTsKKwlhc3NlcnRBcnJheUVxdWFscygiVG86IGlzIHJlbW92ZWQiLCBudWxsLCBtLmdldFJlY2lwaWVudHMoVE8pKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHRoYXQgc2V0RnJvbSB3aXRoIGFuIGFkZHJlc3MgY29udGFpbmluZyBhIG5ld2xpbmUgaXMgZm9sZGVkCisgICAgICogcHJvcGVybHkuCisgICAgICogKEJ1ZyA3NTI5KQorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFNldEZyb21Gb2xkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJSW50ZXJuZXRBZGRyZXNzIGFkZHIgPSBuZXcgSW50ZXJuZXRBZGRyZXNzKCJqb2VAYmFkLmNvbSIsICJKb2VcclxuQmFkIik7CisJTWltZU1lc3NhZ2UgbSA9IG5ldyBNaW1lTWVzc2FnZShzKTsKKwltLnNldEZyb20oYWRkcik7CisJYXNzZXJ0RXF1YWxzKCJKb2VcclxuIEJhZCA8am9lQGJhZC5jb20+IiwgbS5nZXRIZWFkZXIoIkZyb20iLCBudWxsKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IHNldFNlbmRlciB3aXRoIGFuIGFkZHJlc3MgY29udGFpbmluZyBhIG5ld2xpbmUgaXMgZm9sZGVkCisgICAgICogcHJvcGVybHkuCisgICAgICogKEJ1ZyA3NTI5KQorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFNldFNlbmRlckZvbGQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlJbnRlcm5ldEFkZHJlc3MgYWRkciA9IG5ldyBJbnRlcm5ldEFkZHJlc3MoImpvZUBiYWQuY29tIiwgIkpvZVxyXG5CYWQiKTsKKwlNaW1lTWVzc2FnZSBtID0gbmV3IE1pbWVNZXNzYWdlKHMpOworCW0uc2V0U2VuZGVyKGFkZHIpOworCWFzc2VydEVxdWFscygiSm9lXHJcbiBCYWQgPGpvZUBiYWQuY29tPiIsIG0uZ2V0SGVhZGVyKCJTZW5kZXIiLCBudWxsKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IHNldFJlY2lwaWVudCB3aXRoIGEgbmV3c2dyb3VwIGFkZHJlc3MgY29udGFpbmluZyBhIG5ld2xpbmUgaXMKKyAgICAgKiBoYW5kbGVkIHByb3Blcmx5LgorICAgICAqIChCdWcgNzUyOSkKKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXROZXdzZ3JvdXBXaGl0ZXNwYWNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJTmV3c0FkZHJlc3MgYWRkciA9IG5ldyBOZXdzQWRkcmVzcygiYWx0LlxyXG5iYWQiKTsKKwlNaW1lTWVzc2FnZSBtID0gbmV3IE1pbWVNZXNzYWdlKHMpOworCW0uc2V0UmVjaXBpZW50KE5FV1NHUk9VUFMsIGFkZHIpOworCWFzc2VydEVxdWFscygiYWx0LmJhZCIsIG0uZ2V0SGVhZGVyKCJOZXdzZ3JvdXBzIiwgbnVsbCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCBzZXRSZWNpcGllbnRzIHdpdGggbWFueSBuZXdzZ3JvdXAgYWRkcmVzc2VzIGlzIGZvbGRlZCBwcm9wZXJseS4KKyAgICAgKiAoQnVnIDc1MjkpCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0TmV3c2dyb3VwRm9sZCgpIHRocm93cyBFeGNlcHRpb24geworCU5ld3NBZGRyZXNzW10gbG9uZ25nID0gTmV3c0FkZHJlc3MucGFyc2UoCisJICAgICJhbHQubG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcsIiArCisJICAgICJhbHQudmVyeWxvbmdnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2ciKTsKKwlNaW1lTWVzc2FnZSBtID0gbmV3IE1pbWVNZXNzYWdlKHMpOworCW0uc2V0UmVjaXBpZW50cyhORVdTR1JPVVBTLCBsb25nbmcpOworCWFzc2VydFRydWUobS5nZXRIZWFkZXIoIk5ld3Nncm91cHMiLCBudWxsKS5pbmRleE9mKCJcclxuXHQiKSA+IDApOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCBuZXdzZ3JvdXBzIGNhbiBiZSBzZXQgYW5kIHJlYWQgYmFjayAoZXZlbiBpZiBmb2xkZWQpLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFNldEdldE5ld3Nncm91cHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlOZXdzQWRkcmVzc1tdIGxvbmduZyA9IE5ld3NBZGRyZXNzLnBhcnNlKAorCSAgICAiYWx0Lmxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nLCIgKworCSAgICAiYWx0LnZlcnlsb25nZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnIik7CisJTWltZU1lc3NhZ2UgbSA9IG5ldyBNaW1lTWVzc2FnZShzKTsKKwltLnNldFJlY2lwaWVudHMoTkVXU0dST1VQUywgbG9uZ25nKTsKKwlhc3NlcnRBcnJheUVxdWFscyhsb25nbmcsIG0uZ2V0UmVjaXBpZW50cyhORVdTR1JPVVBTKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IGNvcHlpbmcgYSBEYXRhSGFuZGxlciBmcm9tIG9uZSBtZXNzYWdlIHRvIGFub3RoZXIKKyAgICAgKiBoYXMgdGhlIGRlc2lyZWQgZWZmZWN0LgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENvcHlEYXRhSGFuZGxlcigpIHRocm93cyBFeGNlcHRpb24geworCVNlc3Npb24gcyA9IFNlc3Npb24uZ2V0SW5zdGFuY2UobmV3IFByb3BlcnRpZXMoKSk7CisJLy8gY3JlYXRlIGEgbWVzc2FnZSBhbmQgZXh0cmFjdCB0aGUgRGF0YUhhbmRsZXIKKwlNaW1lTWVzc2FnZSBvcmlnID0gY3JlYXRlTWVzc2FnZShzKTsKKwlEYXRhSGFuZGxlciBkaCA9IG9yaWcuZ2V0RGF0YUhhbmRsZXIoKTsKKwkvLyBjcmVhdGUgYSBuZXcgbWVzc2FnZSBhbmQgdXNlIHRoZSBEYXRhSGFuZGxlcgorCU1pbWVNZXNzYWdlIG1zZyA9IG5ldyBNaW1lTWVzc2FnZShzKTsKKwltc2cuc2V0RGF0YUhhbmRsZXIoZGgpOworCS8vIGRlcGVuZCBvbiBjb3B5IGNvbnN0cnVjdG9yIHN0cmVhbWluZyB0aGUgZGF0YQorCW1zZyA9IG5ldyBNaW1lTWVzc2FnZShtc2cpOworCWFzc2VydEVxdWFscygidGV4dC94LXRlc3QiLCBtc2cuZ2V0Q29udGVudFR5cGUoKSk7CisJYXNzZXJ0RXF1YWxzKCJxdW90ZWQtcHJpbnRhYmxlIiwgbXNnLmdldEVuY29kaW5nKCkpOworCWFzc2VydEVxdWFscygidGVzdCBtZXNzYWdlIiwgZ2V0U3RyaW5nKG1zZy5nZXRJbnB1dFN0cmVhbSgpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IGNvcHlpbmcgYSBEYXRhSGFuZGxlciBmcm9tIG9uZSBtZXNzYWdlIHRvIGFub3RoZXIKKyAgICAgKiBieSBzZXR0aW5nIHRoZSAiZGgiIGZpZWxkIGluIGEgc3ViY2xhc3MgaGFzIHRoZSBkZXNpcmVkIGVmZmVjdC4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RTZXREYXRhSGFuZGxlcigpIHRocm93cyBFeGNlcHRpb24geworCVNlc3Npb24gcyA9IFNlc3Npb24uZ2V0SW5zdGFuY2UobmV3IFByb3BlcnRpZXMoKSk7CisJLy8gY3JlYXRlIGEgbWVzc2FnZSBhbmQgZXh0cmFjdCB0aGUgRGF0YUhhbmRsZXIgZm9yIGEgcGFydAorCU1pbWVNZXNzYWdlIG9yaWcgPSBjcmVhdGVNZXNzYWdlKHMpOworCWZpbmFsIERhdGFIYW5kbGVyIG9kaCA9IG9yaWcuZ2V0RGF0YUhhbmRsZXIoKTsKKwkvLyBjcmVhdGUgYSBuZXcgbWVzc2FnZSBhbmQgdXNlIHRoZSBEYXRhSGFuZGxlcgorCU1pbWVNZXNzYWdlIG1zZyA9IG5ldyBNaW1lTWVzc2FnZShzKSB7CisJCXsgZGggPSBvZGg7IH0KKwkgICAgfTsKKwkvLyBkZXBlbmQgb24gY29weSBjb25zdHJ1Y3RvciBzdHJlYW1pbmcgdGhlIGRhdGEKKwltc2cgPSBuZXcgTWltZU1lc3NhZ2UobXNnKTsKKwlhc3NlcnRFcXVhbHMoInRleHQveC10ZXN0IiwgbXNnLmdldENvbnRlbnRUeXBlKCkpOworCWFzc2VydEVxdWFscygicXVvdGVkLXByaW50YWJsZSIsIG1zZy5nZXRFbmNvZGluZygpKTsKKwlhc3NlcnRFcXVhbHMoInRlc3QgbWVzc2FnZSIsIGdldFN0cmluZyhtc2cuZ2V0SW5wdXRTdHJlYW0oKSkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCBhZGRyZXNzIGhlYWRlcnMgYWNjb3VudCBmb3IgdGhlIGhlYWRlciBsZW5ndGggd2hlbiBmb2xkaW5nLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEFkZHJlc3NIZWFkZXJGb2xkaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJU2Vzc2lvbiBzID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShuZXcgUHJvcGVydGllcygpKTsKKwlNaW1lTWVzc2FnZSBtc2cgPSBuZXcgTWltZU1lc3NhZ2Uocyk7CisJSW50ZXJuZXRBZGRyZXNzW10gYWRkcnMgPSBJbnRlcm5ldEFkZHJlc3MucGFyc2UoCisJImxvbmctYWRkcmVzczFAZXhhbXBsZS5jb20sIGxvbmctYWRkcmVzczJAZXhhbXBsZS5jb20sIGpvZUBmb29iYXIuY29tIik7CisJbXNnLnNldFJlcGx5VG8oYWRkcnMpOwkvLyB1c2UgUmVwbHktVG8gYmVjYXVzZSBpdCdzIGEgbG9uZyBoZWFkZXIgbmFtZQorCUVudW1lcmF0aW9uPFN0cmluZz4gZSAKKwkJPSBtc2cuZ2V0TWF0Y2hpbmdIZWFkZXJMaW5lcyhuZXcgU3RyaW5nW10geyAiUmVwbHktVG8iIH0pOworCVN0cmluZyBsaW5lID0gZS5uZXh0RWxlbWVudCgpOworCWludCBucG9zID0gbGluZS5pbmRleE9mKCJcciIpOworCS8vIHdhcyB0aGUgbGluZSBmb2xkZWQgd2hlcmUgd2UgZXhwZWN0ZWQ/CisJYXNzZXJ0VHJ1ZSgiSGVhZGVyIGZvbGRlZCIsCisJICAgIG5wb3MgPiA5ICYmIG5wb3MgPD0gNzcgJiYgbnBvcyA8IGxpbmUubGVuZ3RoKCkpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIE1pbWVNZXNzYWdlIGNyZWF0ZU1lc3NhZ2UoU2Vzc2lvbiBzKQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgY29udGVudCA9CisJICAgICJNaW1lLVZlcnNpb246IDEuMFxuIiArCisJICAgICJTdWJqZWN0OiBFeGFtcGxlXG4iICsKKwkgICAgIkNvbnRlbnQtVHlwZTogdGV4dC94LXRlc3RcbiIgKworCSAgICAiQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogcXVvdGVkLXByaW50YWJsZVxuIiArCisJICAgICJcbiIgKworCSAgICAidGVzdCBtZXNzYWdlXG4iOworCisJcmV0dXJuIG5ldyBNaW1lTWVzc2FnZShzLCBuZXcgQXNjaWlTdHJpbmdJbnB1dFN0cmVhbShjb250ZW50KSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGdldFN0cmluZyhJbnB1dFN0cmVhbSBpcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlCdWZmZXJlZFJlYWRlciByID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBJbnB1dFN0cmVhbVJlYWRlcihpcykpOworCXJldHVybiByLnJlYWRMaW5lKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvTWltZU1lc3NhZ2VUZXN0U3VpdGUuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L01pbWVNZXNzYWdlVGVzdFN1aXRlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTc4OTE4ZQotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L01pbWVNZXNzYWdlVGVzdFN1aXRlLmphdmEKQEAgLTAsMCArMSwzNCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAxMCwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsLmludGVybmV0OworCitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXJzLlN1aXRlLlN1aXRlQ2xhc3NlczsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC50ZXN0LkNsYXNzTG9hZGVyU3VpdGU7CitpbXBvcnQgY29tLnN1bi5tYWlsLnRlc3QuQ2xhc3NMb2FkZXJTdWl0ZS5UZXN0Q2xhc3M7CisKKy8qKgorICogU3VpdGUgb2YgTWltZU1lc3NhZ2UgdGVzdHMgdGhhdCBuZWVkIHRvIGJlIHJ1biBpbiBhIHNlcGFyYXRlIGNsYXNzIGxvYWRlci4KKyAqLworQFJ1bldpdGgoQ2xhc3NMb2FkZXJTdWl0ZS5jbGFzcykKK0BUZXN0Q2xhc3MoTWltZU1lc3NhZ2UuY2xhc3MpCitAU3VpdGVDbGFzc2VzKCB7CisgICAgQWxsb3dFbmNvZGVkTWVzc2FnZXMuY2xhc3MKK30pCitwdWJsaWMgY2xhc3MgTWltZU1lc3NhZ2VUZXN0U3VpdGUgeworfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvTWltZU11bHRpcGFydFBhcnNlVGVzdC5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvTWltZU11bHRpcGFydFBhcnNlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU4YzIxYTkKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy90ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9NaW1lTXVsdGlwYXJ0UGFyc2VUZXN0LmphdmEKQEAgLTAsMCArMSwxNDUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5pbnRlcm5ldDsKKworaW1wb3J0IGphdmEudXRpbC4qOworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZheC5tYWlsLio7CitpbXBvcnQgamF2YXgubWFpbC5ldmVudC4qOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuKjsKK2ltcG9ydCBqYXZheC5tYWlsLnV0aWwuKjsKK2ltcG9ydCBqYXZheC5hY3RpdmF0aW9uLio7CisKK2ltcG9ydCBvcmcuanVuaXQuKjsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRFcXVhbHM7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VHJ1ZTsKKworLyoKKyAqIFRlc3QgbXVsdGlwYXJ0IHBhcnNpbmcuCisgKgorICogQGF1dGhvciBCaWxsIFNoYW5ub24KKyAqLworCitwdWJsaWMgY2xhc3MgTWltZU11bHRpcGFydFBhcnNlVGVzdCB7CisgICAgcHJpdmF0ZSBzdGF0aWMgU2Vzc2lvbiBzZXNzaW9uID0KKwlTZXNzaW9uLmdldEluc3RhbmNlKG5ldyBQcm9wZXJ0aWVzKCksIG51bGwpOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IG1heHNpemUgPSAxMDAwMDsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgZGF0YSA9CisJImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU2Nzg5IjsKKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFBhcnNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJdGVzdChmYWxzZSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UGFyc2VTaGFyZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwl0ZXN0KHRydWUpOworICAgIH0KKworICAgIC8qCisgICAgICogVGVzdCBhIGZldyBwb3RlbnRpYWwgYm91bmRhcnkgY2FzZXMsIHRoZW4gdGVzdCBhIHJhbmdlLgorICAgICAqIFRoaXMgaXMgYSBjb21wcm9taXNlIHRvIG1ha2UgdGhlIHJ1biB0aW1lIG9mIHRoaXMgdGVzdCByZWFzb25hYmxlLAorICAgICAqIGFsdGhvdWdoIGl0IHN0aWxsIHRha2VzIGFib3V0IDMwIHNlY29uZHMsIHdoaWNoIGlzIG9uIHRoZSBsb25nIHNpZGUKKyAgICAgKiBmb3IgYSB1bml0IHRlc3QuCisgICAgICovCisgICAgcHVibGljIHZvaWQgdGVzdChib29sZWFuIHNoYXJlZCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJdGVzdE1lc3NhZ2UoMSwgc2hhcmVkKTsKKwl0ZXN0TWVzc2FnZSgyLCBzaGFyZWQpOworCXRlc3RNZXNzYWdlKDYyLCBzaGFyZWQpOworCXRlc3RNZXNzYWdlKDYzLCBzaGFyZWQpOworCXRlc3RNZXNzYWdlKDY0LCBzaGFyZWQpOworCXRlc3RNZXNzYWdlKDY1LCBzaGFyZWQpOworCXRlc3RNZXNzYWdlKDEwMjMsIHNoYXJlZCk7CisJdGVzdE1lc3NhZ2UoMTAyNCwgc2hhcmVkKTsKKwl0ZXN0TWVzc2FnZSgxMDI1LCBzaGFyZWQpOworCWZvciAoaW50IHNpemUgPSA4MTAwOyBzaXplIDw9IG1heHNpemU7IHNpemUrKykKKwkgICAgdGVzdE1lc3NhZ2Uoc2l6ZSwgc2hhcmVkKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TWVzc2FnZShpbnQgc2l6ZSwgYm9vbGVhbiBzaGFyZWQpIHRocm93cyBFeGNlcHRpb24geworCS8vU3lzdGVtLm91dC5wcmludGxuKCJTSVpFOiAiICsgc2l6ZSk7CisJLyoKKwkgKiBDb25zdHJ1Y3QgYSBtdWx0aXBhcnQgbWVzc2FnZSB3aXRoIGEgcGFydCBvZiB0aGUKKwkgKiBnaXZlbiBzaXplLgorCSAqLworCU1pbWVNZXNzYWdlIG1zZyA9IG5ldyBNaW1lTWVzc2FnZShzZXNzaW9uKTsKKwltc2cuc2V0RnJvbShuZXcgSW50ZXJuZXRBZGRyZXNzKCJtZUBleGFtcGxlLmNvbSIpKTsKKwltc2cuc2V0U3ViamVjdCgidGVzdCBtdWx0aXBhcnQgcGFyc2luZyIpOworCW1zZy5zZXRTZW50RGF0ZShuZXcgRGF0ZSgwKSk7CisJTWltZUJvZHlQYXJ0IG1icDEgPSBuZXcgTWltZUJvZHlQYXJ0KCk7CisJbWJwMS5zZXRUZXh0KCJtYWluIHRleHRcbiIpOworCU1pbWVCb2R5UGFydCBtYnAzID0gbmV3IE1pbWVCb2R5UGFydCgpOworCW1icDMuc2V0VGV4dCgiZW5kIHRleHRcbiIpOworCU1pbWVCb2R5UGFydCBtYnAyID0gbmV3IE1pbWVCb2R5UGFydCgpOworCWJ5dGVbXSBwYXJ0ID0gbmV3IGJ5dGVbc2l6ZV07CisJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKKwkgICAgaW50IGogPSBpICUgNjQ7CisJICAgIGlmIChqID09IDYyKQorCQlwYXJ0W2ldID0gKGJ5dGUpJ1xyJzsKKwkgICAgZWxzZSBpZiAoaiA9PSA2MykKKwkJcGFydFtpXSA9IChieXRlKSdcbic7CisJICAgIGVsc2UKKwkJcGFydFtpXSA9IChieXRlKWRhdGEuY2hhckF0KChqICsgaSAvIDY0KSAlIDYyKTsKKwl9CisJbWJwMi5zZXREYXRhSGFuZGxlcihuZXcgRGF0YUhhbmRsZXIoCisJICAgIG5ldyBCeXRlQXJyYXlEYXRhU291cmNlKHBhcnQsICJ0ZXh0L3BsYWluIikpKTsKKworCU1pbWVNdWx0aXBhcnQgbXAgPSBuZXcgTWltZU11bHRpcGFydCgpOworCW1wLmFkZEJvZHlQYXJ0KG1icDEpOworCW1wLmFkZEJvZHlQYXJ0KG1icDIpOworCW1wLmFkZEJvZHlQYXJ0KG1icDMpOworCW1zZy5zZXRDb250ZW50KG1wKTsKKwltc2cuc2F2ZUNoYW5nZXMoKTsKKworCS8qCisJICogV3JpdGUgdGhlIG1lc3NhZ2Ugb3V0IHRvIGEgYnl0ZSBhcnJheS4KKwkgKi8KKwlCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworCW1zZy53cml0ZVRvKGJvcyk7CisJYm9zLmNsb3NlKCk7CisJYnl0ZVtdIGJ1ZiA9IGJvcy50b0J5dGVBcnJheSgpOworCisJLyoKKwkgKiBDb25zdHJ1Y3QgYSBuZXcgbWVzc2FnZSB0byBwYXJzZSB0aGUgYnl0ZXMuCisJICovCisJbXNnID0gbmV3IE1pbWVNZXNzYWdlKHNlc3Npb24sIHNoYXJlZCA/CisJICAgIG5ldyBTaGFyZWRCeXRlQXJyYXlJbnB1dFN0cmVhbShidWYpIDoKKwkgICAgbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJ1ZikpOworCisJLy8gdmVyaWZ5IHRoYXQgdGhlIHBhcnQgY29udGVudCBpcyBjb3JyZWN0CisJbXAgPSAoTWltZU11bHRpcGFydCltc2cuZ2V0Q29udGVudCgpOworCW1icDIgPSAoTWltZUJvZHlQYXJ0KW1wLmdldEJvZHlQYXJ0KDEpOworCUlucHV0U3RyZWFtIGlzID0gbWJwMi5nZXRJbnB1dFN0cmVhbSgpOworCWludCBrID0gMDsKKwlpbnQgYzsKKwl3aGlsZSAoKGMgPSBpcy5yZWFkKCkpID49IDApIHsKKwkgICAgaW50IGogPSBrICUgNjQ7CisJICAgIGJ5dGUgZTsKKwkgICAgaWYgKGogPT0gNjIpCisJCWUgPSAoYnl0ZSknXHInOworCSAgICBlbHNlIGlmIChqID09IDYzKQorCQllID0gKGJ5dGUpJ1xuJzsKKwkgICAgZWxzZQorCQllID0gKGJ5dGUpZGF0YS5jaGFyQXQoKGogKyBrIC8gNjQpICUgNjIpOworCSAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKCJTaXplICIgKyBzaXplICsgIiBhdCBieXRlICIgKyBrLCBlLCBjKTsKKwkgICAgaysrOworCX0KKwlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJFeHBlY3RlZCBzaXplIiwgc2l6ZSwgayk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvTWltZU11bHRpcGFydFByZWFtYmxlVGVzdC5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvTWltZU11bHRpcGFydFByZWFtYmxlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc1Mjg0NDQKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy90ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9NaW1lTXVsdGlwYXJ0UHJlYW1ibGVUZXN0LmphdmEKQEAgLTAsMCArMSwxMjEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMTAsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5pbnRlcm5ldDsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7CisKK2ltcG9ydCBqYXZheC5tYWlsLkJvZHlQYXJ0OworaW1wb3J0IGphdmF4Lm1haWwuU2Vzc2lvbjsKK2ltcG9ydCBqYXZheC5tYWlsLmludGVybmV0Lk1pbWVNZXNzYWdlOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuTWltZU11bHRpcGFydDsKKworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0QXJyYXlFcXVhbHM7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RXF1YWxzOworCisvKioKKyAqIFRlc3QgdGhlIE1JTUUgbXVsdGlwYXJ0IG1lc3NhZ2VzIGFyZSBwYXJzZWQgY29ycmVjdGx5IGFuZCB0aGUKKyAqIGNvcnJlY3QgcHJlYW1ibGUgaXMgcmV0dXJuZWQgbm8gbWF0dGVyIHdoYXQgbGluZSB0ZXJtaW5hdG9ycworICogYXJlIHVzZWQuICBUaGlzIHRlc3QgZm91bmQgc29tZSBidWdzIGluIHRoZSB3YXkgTGluZUlucHV0U3RyZWFtCisgKiBoYW5kbGVkIGRpZmZlcmVudCBsaW5lIHRlcm1pbmF0b3JzLgorICoKKyAqIEBhdXRob3IJdHJlamthekBrZW5haS5jb20KKyAqLworcHVibGljIGNsYXNzIE1pbWVNdWx0aXBhcnRQcmVhbWJsZVRlc3QgeworICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsiU2luZ2xlQ2hhcmFjdGVyU3RyaW5nQ29uY2F0ZW5hdGlvbiJ9KQorICAgIHByaXZhdGUgU3RyaW5nIFRIUkVFX1BBUlRfTUFJTCA9CisgICAgICAgICJGcm9tOiB1c2VyMUBleGFtcGxlLmNvbVxuIiArCisgICAgICAgICJUbzogdXNlcjJAZXhhbXBsZS5jb21cbiIgKworICAgICAgICAiU3ViamVjdDogUmVjZWlwdHNcbiIgKworICAgICAgICAiRGF0ZTogV2VkLCAxNCBKdWwgMjAxMCAxOToyNTozMCArMTAwMFxuIiArCisgICAgICAgICJNSU1FLVZlcnNpb246IDEuMFxuIiArCisgICAgICAgICJDb250ZW50LVR5cGU6IG11bHRpcGFydC9taXhlZDtib3VuZGFyeT1cIi0tLS09X05leHRQYXJ0XzAwMF8wMDFDXzAxQ0IyMzhBLjUyRTM1NDAwXCJcbiIgKworICAgICAgICAiXG4iICsKKyAgICAgICAgIlRoaXMgaXMgYSBtdWx0aS1wYXJ0IG1lc3NhZ2UgaW4gTUlNRSBmb3JtYXQuXG4iICsKKyAgICAgICAgIlxuIiArCisgICAgICAgICItLS0tLS09X05leHRQYXJ0XzAwMF8wMDFDXzAxQ0IyMzhBLjUyRTM1NDAwXG4iICsKKyAgICAgICAgIkNvbnRlbnQtVHlwZTogdGV4dC9wbGFpbjtjaGFyc2V0PVwidXMtYXNjaWlcIlxuIiArCisgICAgICAgICJDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiA3Yml0XG4iICsKKyAgICAgICAgIlxuIiArCisgICAgICAgICJIaS5cbiIgKworICAgICAgICAiXG4iICsKKyAgICAgICAgIlxuIiArCisgICAgICAgICItLS0tLS09X05leHRQYXJ0XzAwMF8wMDFDXzAxQ0IyMzhBLjUyRTM1NDAwXG4iICsKKyAgICAgICAgIkNvbnRlbnQtVHlwZTogYXBwbGljYXRpb24vcGRmO25hbWU9XCJSZWNlaXB0IDEucGRmXCJcbiIgKworICAgICAgICAiQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogYmFzZTY0XG4iICsKKyAgICAgICAgIkNvbnRlbnQtRGlzcG9zaXRpb246IGF0dGFjaG1lbnQ7ZmlsZW5hbWU9XCJSZWNlaXB0IDEucGRmXCJcbiIgKworICAgICAgICAiXG4iICsKKyAgICAgICAgIkpWQkVSaTB4TGpRS0pjZnNqNklLTlNBd0lHOWlhZ284UEM5TVpXNW5kR2dnTmlBd0lGSXZSbWxzZEdWeUlDOUdiR0YwWlVSbFkyOWtcbiIgKworICAgICAgICAiXG4iICsKKyAgICAgICAgIi0tLS0tLT1fTmV4dFBhcnRfMDAwXzAwMUNfMDFDQjIzOEEuNTJFMzU0MDBcbiIgKworICAgICAgICAiQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi9wZGY7bmFtZT1cIlJlY2VpcHQgMi5wZGZcIlxuIiArCisgICAgICAgICJDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjRcbiIgKworICAgICAgICAiQ29udGVudC1EaXNwb3NpdGlvbjogYXR0YWNobWVudDtmaWxlbmFtZT1cIlJlY2VpcHQgMi5wZGZcIlxuIiArCisgICAgICAgICJcbiIgKworICAgICAgICAiSlZCRVJpMHhMalFLSmNmc2o2SUtOU0F3SUc5aWFnbzhQQzlNWlc1bmRHZ2dOaUF3SUZJdlJtbHNkR1Z5SUM5R2JHRjBaVVJsWTI5a1xuIiArCisgICAgICAgICJcbiIgKworICAgICAgICAiLS0tLS0tPV9OZXh0UGFydF8wMDBfMDAxQ18wMUNCMjM4QS41MkUzNTQwMC0tXG4iICsKKyAgICAgICAgIlxuIiArCisgICAgICAgICJcbiI7CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RVbml4TGluZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZG9UaHJlZVBhcnRNYWlsVGVzdChUSFJFRV9QQVJUX01BSUwpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFdpbmRvd3NMaW5lcygpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBkb1RocmVlUGFydE1haWxUZXN0KFRIUkVFX1BBUlRfTUFJTC5yZXBsYWNlKCJcbiIsICJcclxuIikpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdE1hY0xpbmVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGRvVGhyZWVQYXJ0TWFpbFRlc3QoVEhSRUVfUEFSVF9NQUlMLnJlcGxhY2UoJ1xuJywgJ1xyJykpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgY2hlY2sgdGhhdCB0aGUgbXVsdGlwYXJ0IG9mIHRoZSBlbWFpbCB3YXMgaGFuZGxlZCBjb3JyZWN0bHkuCisgICAgICoKKyAgICAgKiBAcGFyYW0gdGV4dCB0aGUgZW1haWwgdGV4dC4KKyAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbiBpZiBhbiBlcnJvciBvY2N1cnMuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGRvVGhyZWVQYXJ0TWFpbFRlc3QoU3RyaW5nIHRleHQpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTZXNzaW9uIHNlc3Npb24gPSBTZXNzaW9uLmdldERlZmF1bHRJbnN0YW5jZShuZXcgUHJvcGVydGllcygpKTsKKyAgICAgICAgTWltZU1lc3NhZ2UgbWltZU1lc3NhZ2UgPSBuZXcgTWltZU1lc3NhZ2Uoc2Vzc2lvbiwKKwkJCW5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSh0ZXh0LmdldEJ5dGVzKCJVUy1BU0NJSSIpKSk7CisKKyAgICAgICAgTWltZU11bHRpcGFydCB0b3BNdWx0aXBhcnQgPSAoTWltZU11bHRpcGFydCkgbWltZU1lc3NhZ2UuZ2V0Q29udGVudCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIHByZWFtYmxlIiwKKwkgICAgIlRoaXMgaXMgYSBtdWx0aS1wYXJ0IG1lc3NhZ2UgaW4gTUlNRSBmb3JtYXQuIiwKKwkgICAgdG9wTXVsdGlwYXJ0LmdldFByZWFtYmxlKCkudHJpbSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJXcm9uZyBudW1iZXIgb2YgcGFydHMiLCAzLCB0b3BNdWx0aXBhcnQuZ2V0Q291bnQoKSk7CisKKyAgICAgICAgQm9keVBhcnQgcGFydDEgPSB0b3BNdWx0aXBhcnQuZ2V0Qm9keVBhcnQoMCk7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgY29udGVudCB0eXBlIGZvciBwYXJ0IDEiLAorCSAgICAidGV4dC9wbGFpbjtjaGFyc2V0PVwidXMtYXNjaWlcIiIsIHBhcnQxLmdldENvbnRlbnRUeXBlKCkpOworCisgICAgICAgIEJvZHlQYXJ0IHBhcnQyID0gdG9wTXVsdGlwYXJ0LmdldEJvZHlQYXJ0KDEpOworICAgICAgICBhc3NlcnRFcXVhbHMoIldyb25nIGNvbnRlbnQgdHlwZSBmb3IgcGFydCAyIiwKKwkgICAgImFwcGxpY2F0aW9uL3BkZjtuYW1lPVwiUmVjZWlwdCAxLnBkZlwiIiwgcGFydDIuZ2V0Q29udGVudFR5cGUoKSk7CisKKyAgICAgICAgQm9keVBhcnQgcGFydDMgPSB0b3BNdWx0aXBhcnQuZ2V0Qm9keVBhcnQoMik7CisgICAgICAgIGFzc2VydEVxdWFscygiV3JvbmcgY29udGVudCB0eXBlIGZvciBwYXJ0IDMiLAorCSAgICAiYXBwbGljYXRpb24vcGRmO25hbWU9XCJSZWNlaXB0IDIucGRmXCIiLCBwYXJ0My5nZXRDb250ZW50VHlwZSgpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9NaW1lTXVsdGlwYXJ0UHJvcGVydHlUZXN0LmphdmEgYi9tYWlsL3NyYy90ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9NaW1lTXVsdGlwYXJ0UHJvcGVydHlUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2VjMzkxMAotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L01pbWVNdWx0aXBhcnRQcm9wZXJ0eVRlc3QuamF2YQpAQCAtMCwwICsxLDE5MyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwOSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsLmludGVybmV0OworCitpbXBvcnQgY29tLnN1bi5tYWlsLnRlc3QuQXNjaWlTdHJpbmdJbnB1dFN0cmVhbTsKK2ltcG9ydCBjb20uc3VuLm1haWwudGVzdC5OdWxsT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXQ7CitpbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7CisKK2ltcG9ydCBqYXZheC5tYWlsLlNlc3Npb247CitpbXBvcnQgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb247CisKK2ltcG9ydCBvcmcuanVuaXQuKjsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRFcXVhbHM7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VHJ1ZTsKKworLyoqCisgKiBUZXN0IHRoZSBwcm9wZXJ0aWVzIHRoYXQgY29udHJvbCB0aGUgTWltZU11bHRpcGFydCBjbGFzcy4KKyAqIFNpbmNlIHRoZSBwcm9wZXJ0aWVzIGFyZSBub3cgcmVhZCBpbiB0aGUgcGFyc2UgbWV0aG9kLCBhbGwKKyAqIHRoZXNlIHRlc3RzIGNhbiBiZSBydW4gaW4gdGhlIHNhbWUgSlZNLgorICovCitwdWJsaWMgY2xhc3MgTWltZU11bHRpcGFydFByb3BlcnR5VGVzdCB7CisgCisgICAgcHJpdmF0ZSBzdGF0aWMgU2Vzc2lvbiBzID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShuZXcgUHJvcGVydGllcygpKTsKKworICAgIC8qKgorICAgICAqIENsZWFyIGFsbCBwcm9wZXJ0aWVzIGJlZm9yZSBlYWNoIHRlc3QuCisgICAgICovCisgICAgQEJlZm9yZQorICAgIHB1YmxpYyB2b2lkIGJlZm9yZVRlc3QoKSB7CisJY2xlYXJBbGwoKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RCb3VuZGFyeSgpIHRocm93cyBFeGNlcHRpb24geworCU1pbWVNZXNzYWdlIG0gPSBjcmVhdGVNZXNzYWdlKCJ4IiwgIngiLCB0cnVlKTsKKwlNaW1lTXVsdGlwYXJ0IG1wID0gKE1pbWVNdWx0aXBhcnQpbS5nZXRDb250ZW50KCk7CisJYXNzZXJ0RXF1YWxzKG1wLmdldENvdW50KCksIDIpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEJvdW5kYXJ5SWdub3JlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFN5c3RlbS5zZXRQcm9wZXJ0eSgKKwkgICAgIm1haWwubWltZS5tdWx0aXBhcnQuaWdub3JlZXhpc3Rpbmdib3VuZGFyeXBhcmFtZXRlciIsICJ0cnVlIik7CisJTWltZU1lc3NhZ2UgbSA9IGNyZWF0ZU1lc3NhZ2UoIngiLCAiLSIsIHRydWUpOworCU1pbWVNdWx0aXBhcnQgbXAgPSAoTWltZU11bHRpcGFydCltLmdldENvbnRlbnQoKTsKKwlhc3NlcnRFcXVhbHMobXAuZ2V0Q291bnQoKSwgMik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Qm91bmRhcnlNaXNzaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJTWltZU1lc3NhZ2UgbSA9IGNyZWF0ZU1lc3NhZ2UobnVsbCwgIngiLCB0cnVlKTsKKwlNaW1lTXVsdGlwYXJ0IG1wID0gKE1pbWVNdWx0aXBhcnQpbS5nZXRDb250ZW50KCk7CisJYXNzZXJ0RXF1YWxzKG1wLmdldENvdW50KCksIDIpOworICAgIH0KKworICAgIEBUZXN0KGV4cGVjdGVkPU1lc3NhZ2luZ0V4Y2VwdGlvbi5jbGFzcykKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Qm91bmRhcnlNaXNzaW5nRXgoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3lzdGVtLnNldFByb3BlcnR5KAorCSAgICAibWFpbC5taW1lLm11bHRpcGFydC5pZ25vcmVtaXNzaW5nYm91bmRhcnlwYXJhbWV0ZXIiLCAiZmFsc2UiKTsKKwlNaW1lTWVzc2FnZSBtID0gY3JlYXRlTWVzc2FnZShudWxsLCAieCIsIHRydWUpOworCU1pbWVNdWx0aXBhcnQgbXAgPSAoTWltZU11bHRpcGFydCltLmdldENvbnRlbnQoKTsKKwltcC5nZXRDb3VudCgpOwkJLy8gdGhyb3cgZXhjZXB0aW9uCisJYXNzZXJ0VHJ1ZShmYWxzZSk7CS8vIG5ldmVyIGdldCBoZXJlCisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW5kQm91bmRhcnlNaXNzaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJTWltZU1lc3NhZ2UgbSA9IGNyZWF0ZU1lc3NhZ2UoIngiLCAieCIsIGZhbHNlKTsKKwlNaW1lTXVsdGlwYXJ0IG1wID0gKE1pbWVNdWx0aXBhcnQpbS5nZXRDb250ZW50KCk7CisJYXNzZXJ0RXF1YWxzKG1wLmdldENvdW50KCksIDIpOworICAgIH0KKworICAgIEBUZXN0KGV4cGVjdGVkPU1lc3NhZ2luZ0V4Y2VwdGlvbi5jbGFzcykKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RW5kQm91bmRhcnlNaXNzaW5nRXgoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgU3lzdGVtLnNldFByb3BlcnR5KAorCSAgICAibWFpbC5taW1lLm11bHRpcGFydC5pZ25vcmVtaXNzaW5nZW5kYm91bmRhcnkiLCAiZmFsc2UiKTsKKwlNaW1lTWVzc2FnZSBtID0gY3JlYXRlTWVzc2FnZSgieCIsICJ4IiwgZmFsc2UpOworCU1pbWVNdWx0aXBhcnQgbXAgPSAoTWltZU11bHRpcGFydCltLmdldENvbnRlbnQoKTsKKwltcC5nZXRDb3VudCgpOwkJLy8gdGhyb3cgZXhjZXB0aW9uCisJYXNzZXJ0VHJ1ZShmYWxzZSk7CS8vIG5ldmVyIGdldCBoZXJlCisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWxsb3dFbXB0eSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTeXN0ZW0uc2V0UHJvcGVydHkoICJtYWlsLm1pbWUubXVsdGlwYXJ0LmFsbG93ZW1wdHkiLCAidHJ1ZSIpOworCU1pbWVNZXNzYWdlIG0gPSBjcmVhdGVFbXB0eU1lc3NhZ2UoKTsKKwlNaW1lTXVsdGlwYXJ0IG1wID0gKE1pbWVNdWx0aXBhcnQpbS5nZXRDb250ZW50KCk7CisJYXNzZXJ0RXF1YWxzKG1wLmdldENvdW50KCksIDApOworICAgIH0KKworICAgIEBUZXN0KGV4cGVjdGVkPU1lc3NhZ2luZ0V4Y2VwdGlvbi5jbGFzcykKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWxsb3dFbXB0eUV4KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJTWltZU1lc3NhZ2UgbSA9IGNyZWF0ZUVtcHR5TWVzc2FnZSgpOworCU1pbWVNdWx0aXBhcnQgbXAgPSAoTWltZU11bHRpcGFydCltLmdldENvbnRlbnQoKTsKKwltcC5nZXRDb3VudCgpOwkJLy8gdGhyb3cgZXhjZXB0aW9uCisJYXNzZXJ0VHJ1ZShmYWxzZSk7CS8vIG5ldmVyIGdldCBoZXJlCisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWxsb3dFbXB0eU91dHB1dCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBTeXN0ZW0uc2V0UHJvcGVydHkoICJtYWlsLm1pbWUubXVsdGlwYXJ0LmFsbG93ZW1wdHkiLCAidHJ1ZSIpOworCU1pbWVNZXNzYWdlIG0gPSBuZXcgTWltZU1lc3NhZ2Uocyk7CisJTWltZU11bHRpcGFydCBtcCA9IG5ldyBNaW1lTXVsdGlwYXJ0KCk7CisJbS5zZXRDb250ZW50KG1wKTsKKwltLndyaXRlVG8obmV3IE51bGxPdXRwdXRTdHJlYW0oKSk7CisJYXNzZXJ0RXF1YWxzKG1wLmdldENvdW50KCksIDApOworICAgIH0KKworICAgIEBUZXN0KGV4cGVjdGVkPUlPRXhjZXB0aW9uLmNsYXNzKQorICAgIHB1YmxpYyB2b2lkIHRlc3RBbGxvd0VtcHR5T3V0cHV0RXgoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlNaW1lTWVzc2FnZSBtID0gbmV3IE1pbWVNZXNzYWdlKHMpOworCU1pbWVNdWx0aXBhcnQgbXAgPSBuZXcgTWltZU11bHRpcGFydCgpOworCW0uc2V0Q29udGVudChtcCk7CisJbS53cml0ZVRvKG5ldyBOdWxsT3V0cHV0U3RyZWFtKCkpOwkvLyB0aHJvdyBleGNlcHRpb24KKwlhc3NlcnRUcnVlKGZhbHNlKTsJLy8gbmV2ZXIgZ2V0IGhlcmUKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbGVhciBhbGwgcHJvcGVydGllcyBhZnRlciBhbGwgdGVzdHMuCisgICAgICovCisgICAgQEFmdGVyQ2xhc3MKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgYWZ0ZXIoKSB7CisgICAgICAgIGNsZWFyQWxsKCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBjbGVhckFsbCgpIHsKKyAgICAgICAgU3lzdGVtLmNsZWFyUHJvcGVydHkoCisJICAgICJtYWlsLm1pbWUubXVsdGlwYXJ0Lmlnbm9yZWV4aXN0aW5nYm91bmRhcnlwYXJhbWV0ZXIiKTsKKyAgICAgICAgU3lzdGVtLmNsZWFyUHJvcGVydHkoCisJICAgICJtYWlsLm1pbWUubXVsdGlwYXJ0Lmlnbm9yZW1pc3Npbmdib3VuZGFyeXBhcmFtZXRlciIpOworICAgICAgICBTeXN0ZW0uY2xlYXJQcm9wZXJ0eSgKKwkgICAgIm1haWwubWltZS5tdWx0aXBhcnQuaWdub3JlbWlzc2luZ2VuZGJvdW5kYXJ5Iik7CisgICAgICAgIFN5c3RlbS5jbGVhclByb3BlcnR5KAorCSAgICAibWFpbC5taW1lLm11bHRpcGFydC5hbGxvd2VtcHR5Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgdGVzdCBtZXNzYWdlLgorICAgICAqIElmIHBhcmFtIGlzIG5vdCBudWxsLCBpdCBzcGVjaWZpZXMgdGhlIGJvdW5kYXJ5IHBhcmFtZXRlci4KKyAgICAgKiBUaGUgYWN0dWFsIGJvdW5kYXJ5IGlzIHNwZWNpZmllZCBieSAiYWN0dWFsIi4KKyAgICAgKiBJZiAiZW5kIiBpcyB0cnVlLCBpbmNsdWRlIHRoZSBlbmQgYm91bmRhcnkuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgTWltZU1lc3NhZ2UgY3JlYXRlTWVzc2FnZShTdHJpbmcgcGFyYW0sIFN0cmluZyBhY3R1YWwsCisJCQkJYm9vbGVhbiBlbmQpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgY29udGVudCA9CisJICAgICJNaW1lLVZlcnNpb246IDEuMFxuIiArCisJICAgICJTdWJqZWN0OiBFeGFtcGxlXG4iICsKKwkgICAgIkNvbnRlbnQtVHlwZTogbXVsdGlwYXJ0L21peGVkOyAiICsKKwkJKHBhcmFtICE9IG51bGwgPyAiYm91bmRhcnk9XCIiICsgcGFyYW0gKyAiXCIiIDogIiIpICsgIlxuIiArCisJICAgICJcbiIgKworCSAgICAicHJlYW1ibGVcbiIgKworCSAgICAiLS0iICsgYWN0dWFsICsgIlxuIiArCisJICAgICJcbiIgKworCSAgICAiZmlyc3QgcGFydFxuIiArCisJICAgICJcbiIgKworCSAgICAiLS0iICsgYWN0dWFsICsgIlxuIiArCisJICAgICJcbiIgKworCSAgICAic2Vjb25kIHBhcnRcbiIgKworCSAgICAiXG4iICsKKwkgICAgKGVuZCA/ICItLSIgKyBhY3R1YWwgKyAiLS1cbiIgOiAiIik7CisgCisJcmV0dXJuIG5ldyBNaW1lTWVzc2FnZShzLCBuZXcgQXNjaWlTdHJpbmdJbnB1dFN0cmVhbShjb250ZW50KSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgdGVzdCBtZXNzYWdlIHdpdGggbm8gcGFydHMuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgTWltZU1lc3NhZ2UgY3JlYXRlRW1wdHlNZXNzYWdlKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBjb250ZW50ID0KKwkgICAgIk1pbWUtVmVyc2lvbjogMS4wXG4iICsKKwkgICAgIlN1YmplY3Q6IEV4YW1wbGVcbiIgKworCSAgICAiQ29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5PVwieFwiXG5cbiI7CisgCisJcmV0dXJuIG5ldyBNaW1lTWVzc2FnZShzLCBuZXcgQXNjaWlTdHJpbmdJbnB1dFN0cmVhbShjb250ZW50KSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvTWltZVV0aWxpdHlUZXN0LmphdmEgYi9tYWlsL3NyYy90ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9NaW1lVXRpbGl0eVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zYmY5NDVhCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvTWltZVV0aWxpdHlUZXN0LmphdmEKQEAgLTAsMCArMSwxNjkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5pbnRlcm5ldDsKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmF4LmFjdGl2YXRpb24uKjsKK2ltcG9ydCBqYXZheC5tYWlsLnV0aWwuQnl0ZUFycmF5RGF0YVNvdXJjZTsKKworaW1wb3J0IG9yZy5qdW5pdC4qOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0Lio7CisKKy8qKgorICogVGVzdCBNaW1lVXRpbGl0eSBtZXRob2RzLgorICoKKyAqIFhYWCAtIGp1c3QgYSBiZWdpbm5pbmcuLi4KKyAqCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCitwdWJsaWMgY2xhc3MgTWltZVV0aWxpdHlUZXN0IHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gdXRmMTZiZUJ5dGVzID0geworCShieXRlKTB4ZmUsIChieXRlKTB4NWIsIChieXRlKTB4ZGMsIChieXRlKTB4NWYsCisJKGJ5dGUpMHg5MiwgKGJ5dGUpMHgzMCwgKGJ5dGUpMHg4OCwgKGJ5dGUpMHgzMCwKKwkoYnl0ZSkweDhkLCAoYnl0ZSkweDMwLCAoYnl0ZSkweDU3LCAoYnl0ZSkweDMwLAorCShieXRlKTB4NGYsIChieXRlKTB4MzAsIChieXRlKTB4NGEsIChieXRlKTB4MzAsCisJKGJ5dGUpMHg2ZCwgKGJ5dGUpMHgzMCwgKGJ5dGUpMHg0YywgKGJ5dGUpMHgzMCwKKwkoYnl0ZSkweDQ0LCAoYnl0ZSkweDMwLCAoYnl0ZSkweDU3LCAoYnl0ZSkweDMwLAorCShieXRlKTB4N2UsIChieXRlKTB4MzAsIChieXRlKTB4NTksIChieXRlKTB4MzAsCisJKGJ5dGUpMHgwZCwgKGJ5dGUpMHgwMCwgKGJ5dGUpMHgwYSwgKGJ5dGUpMHgwMAorICAgIH07CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTZXQ8U3RyaW5nPiBlbmNvZGluZ3MgPSBuZXcgSGFzaFNldDxTdHJpbmc+KCkge3sKKwlhZGQoIjdiaXQiKTsgYWRkKCI4Yml0Iik7IGFkZCgicXVvdGVkLXByaW50YWJsZSIpOyBhZGQoImJhc2U2NCIpOyB9fTsKKworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCB1dGYtMTZiZSBkYXRhIGlzIGVuY29kZWQgd2l0aCBiYXNlNjQgYW5kIG5vdCBxdW90ZWQtcHJpbnRhYmxlLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdE5vbkFzY2lpRW5jb2RpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlEYXRhU291cmNlIGRzID0gbmV3IEJ5dGVBcnJheURhdGFTb3VyY2UodXRmMTZiZUJ5dGVzLAorCQkJCQkJInRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTE2YmUiKTsKKwlTdHJpbmcgZW4gPSBNaW1lVXRpbGl0eS5nZXRFbmNvZGluZyhkcyk7CisJYXNzZXJ0RXF1YWxzKCJub24tQVNDSUkgZW5jb2RpbmciLCAiYmFzZTY0IiwgZW4pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCBnZXRFbmNvZGluZyByZXR1cm5zIGEgdmFsaWQgdmFsdWUgZXZlbiBpZiB0aGUgZmlsZQorICAgICAqIGRvZXNuJ3QgZXhpc3QuICBUaGUgcmV0dXJuIHZhbHVlIHNob3VsZCBiZSBhIHZhbGlkCisgICAgICogQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZywgYnV0IG1vc3RseSB3ZSBjYXJlIHRoYXQgaXQgZG9lc24ndAorICAgICAqIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgZ2V0RW5jb2RpbmdNaXNzaW5nRmlsZSgpIHRocm93cyBFeGNlcHRpb24geworCUZpbGUgbWlzc2luZyA9IG5ldyBGaWxlKGdldENsYXNzKCkuZ2V0TmFtZSgpKTsKKwlhc3NlcnRGYWxzZShtaXNzaW5nLnRvU3RyaW5nKCksIG1pc3NpbmcuZXhpc3RzKCkpOworCUZpbGVEYXRhU291cmNlIGZkcyA9IG5ldyBGaWxlRGF0YVNvdXJjZShtaXNzaW5nKTsKKwlhc3NlcnRFcXVhbHMoZmRzLmdldE5hbWUoKSwgbWlzc2luZy5nZXROYW1lKCkpOworCWFzc2VydFRydWUoImdldEVuY29kaW5nKERhdGFTb3VyY2UpIiwKKwkgICAgZW5jb2RpbmdzLmNvbnRhaW5zKE1pbWVVdGlsaXR5LmdldEVuY29kaW5nKGZkcykpKTsKKwlhc3NlcnRUcnVlKCJnZXRFbmNvZGluZyhEYXRhSGFuZGxlcikiLAorCSAgICBlbmNvZGluZ3MuY29udGFpbnMoTWltZVV0aWxpdHkuZ2V0RW5jb2RpbmcobmV3IERhdGFIYW5kbGVyKGZkcykpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IGdldEVuY29kaW5nIHJldHVybnMgYSB2YWxpZCB2YWx1ZSBldmVuIGlmIHRoZSBjb250ZW50CisgICAgICogdHlwZSBpcyBiYWQuICBUaGUgcmV0dXJuIHZhbHVlIHNob3VsZCBiZSBhIHZhbGlkCisgICAgICogQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZywgYnV0IG1vc3RseSB3ZSBjYXJlIHRoYXQgaXQgZG9lc24ndAorICAgICAqIHRocm93IE51bGxQb2ludGVyRXhjZXB0aW9uLgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgZ2V0RW5jb2RpbmdCYWRDb250ZW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJU3RyaW5nIGNvbnRlbnQgPSAiYmFkLWNvbnRlbnQtdHlwZSI7CisJQ29udGVudFR5cGUgdHlwZSA9IG51bGw7CisJdHJ5IHsKKwkgICAgdHlwZSA9IG5ldyBDb250ZW50VHlwZShjb250ZW50KTsKKwkgICAgZmFpbCh0eXBlLnRvU3RyaW5nKCkpOworCX0gY2F0Y2ggKFBhcnNlRXhjZXB0aW9uIGV4cGVjdCkgeworCSAgICBpZiAodHlwZSAhPSBudWxsKSB7CisJICAgICAgIHRocm93IGV4cGVjdDsgCisJICAgIH0KKwl9CisKKwlCeXRlQXJyYXlEYXRhU291cmNlIGJhZHMgPSBuZXcgQnl0ZUFycmF5RGF0YVNvdXJjZSgiIiwgY29udGVudCk7CisJYmFkcy5zZXROYW1lKG51bGwpOworCWFzc2VydFRydWUoZW5jb2RpbmdzLmNvbnRhaW5zKE1pbWVVdGlsaXR5LmdldEVuY29kaW5nKGJhZHMpKSk7CisJYXNzZXJ0VHJ1ZShlbmNvZGluZ3MuY29udGFpbnMoCisJCQlNaW1lVXRpbGl0eS5nZXRFbmNvZGluZyhuZXcgRGF0YUhhbmRsZXIoYmFkcykpKSk7CisKKwliYWRzLnNldE5hbWUoIiIpOworCWFzc2VydFRydWUoZW5jb2RpbmdzLmNvbnRhaW5zKE1pbWVVdGlsaXR5LmdldEVuY29kaW5nKGJhZHMpKSk7CisJYXNzZXJ0VHJ1ZShlbmNvZGluZ3MuY29udGFpbnMoCisJCQlNaW1lVXRpbGl0eS5nZXRFbmNvZGluZyhuZXcgRGF0YUhhbmRsZXIoYmFkcykpKSk7CisKKwliYWRzLnNldE5hbWUoZ2V0Q2xhc3MoKS5nZXROYW1lKCkpOworCWFzc2VydFRydWUoZW5jb2RpbmdzLmNvbnRhaW5zKE1pbWVVdGlsaXR5LmdldEVuY29kaW5nKGJhZHMpKSk7CisJYXNzZXJ0VHJ1ZShlbmNvZGluZ3MuY29udGFpbnMoCisJCQlNaW1lVXRpbGl0eS5nZXRFbmNvZGluZyhuZXcgRGF0YUhhbmRsZXIoYmFkcykpKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IGVuY29kaW5nIGEgVW5pY29kZSBzdHJpbmcgd2l0aCBzdXJyb2dhdGUgcGFpcnMKKyAgICAgKiBkb2Vzbid0IHNwbGl0IHRoZSBlbmNvZGluZyBiZXR3ZWVuIHRoZSBwYWlycy4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RTdXJyb2dhdGVQYWlycygpIHRocm93cyBFeGNlcHRpb24geworCS8vIHRlc3QgYSBzcGVjaWZpYyBjYXNlCisJU3RyaW5nIHNwID0gImEiICsKKwkJICAgICJcdWQ4MDFcdWRjMDBcdWQ4MDFcdWRjMDBcdWQ4MDFcdWRjMDBcdWQ4MDFcdWRjMDAiICsKKwkJICAgICJcdWQ4MDFcdWRjMDBcdWQ4MDFcdWRjMDBcdWQ4MDFcdWRjMDBcdWQ4MDFcdWRjMDAiICsKKwkJICAgICJcdWQ4MDFcdWRjMDBcdWQ4MDFcdWRjMDBcdWQ4MDFcdWRjMDBcdWQ4MDFcdWRjMDAiICsKKwkJICAgICJcdWQ4MDFcdWRjMDBcdWQ4MDFcdWRjMDBcdWQ4MDFcdWRjMDBcdWQ4MDFcdWRjMDAiOworCVN0cmluZyBlbiA9IE1pbWVVdGlsaXR5LmVuY29kZVRleHQoc3AsICJ1dGYtOCIsICJCIik7CisJU3RyaW5nIGR0ID0gTWltZVV0aWxpdHkuZGVjb2RlVGV4dChlbik7CisJLy8gZW5jb2RpbmcgaXQgYW5kIGRlY29kaW5nIGl0IHNob3VsZG4ndCBjaGFuZ2UgaXQKKwlhc3NlcnRFcXVhbHMoZHQsIHNwKTsKKwlTdHJpbmdbXSB3ID0gZW4uc3BsaXQoIiAiKTsKKwkvLyB0aGUgZmlyc3Qgd29yZCBzaG91bGQgZW5kIHdpdGggdGhlIHNlY29uZCBoYWxmIG9mIGEgcGFpcgorCVN0cmluZyBkdyA9IE1pbWVVdGlsaXR5LmRlY29kZVdvcmQod1swXSk7CisJYXNzZXJ0VHJ1ZShkdy5jaGFyQXQoZHcubGVuZ3RoKCktMSkgPT0gJ1x1ZGMwMCcpOworCS8vIGFuZCB0aGUgc2Vjb25kIHdvcmQgc2hvdWxkIHN0YXJ0IHdpdGggdGhlIGZpcnN0IGhhbGYgb2YgYSBwYWlyCisJZHcgPSBNaW1lVXRpbGl0eS5kZWNvZGVXb3JkKHdbMV0pOworCWFzc2VydFRydWUoZHcuY2hhckF0KDApID09ICdcdWQ4MDEnKTsKKworCS8vIHRlc3QgdmFyaW91cyBzdHJpbmcgbGVuZ3RocworCWludCBjaCA9IDB4RkUwMDA7CisJU3RyaW5nIHRlc3QgPSAiIjsKKwlmb3IgKGludCBpID0gMDsgaSA8IDUwOyBpKyspIHsKKwkgICAgdGVzdCArPSBuZXcgU3RyaW5nKENoYXJhY3Rlci50b0NoYXJzKGNoKSk7CisJICAgIFN0cmluZyBlbmNvZGVkID0gTWltZVV0aWxpdHkuZW5jb2RlVGV4dCh0ZXN0LCAiVVRGLTgiLCAiQiIpOworCSAgICBTdHJpbmcgZGVjb2RlZCA9IE1pbWVVdGlsaXR5LmRlY29kZVRleHQoZW5jb2RlZCk7CisJICAgIGFzc2VydEVxdWFscyhkZWNvZGVkLCB0ZXN0KTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IGVuY29kZWQgd29yZHMgd2l0aCB0aGUgd3JvbmcgQ2hpbmVzZSBjaGFyc2V0IHN0aWxsCisgICAgICogZGVjb2RlIGNvcnJlY3RseS4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RCYWRDaGluZXNlQ2hhcnNldHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlTdHJpbmcgYmFkZ2IyMzEyID0gIj0/Z2IyMzEyP0I/eGJmVXFxTGpJQ2hGVlZJcHR0Szd1NEV3aERZZ0tFTk9XU2s9Pz0iOworCVN0cmluZyBiYWRnYmsgPSAiPT9nYms/Qj94YmZVcXFMaklDaEZWVklwdHRLN3U0RXdoRFlnS0VOT1dTaz0/PSI7CisJU3RyaW5nIGJhZG1zOTM2ID0gIj0/bXM5MzY/Qj94YmZVcXFMaklDaEZWVklwdHRLN3U0RXdoRFlnS0VOT1dTaz0/PSI7CisJU3RyaW5nIGJhZGNwOTM2ID0gIj0/Y3A5MzY/Qj94YmZVcXFMaklDaEZWVklwdHRLN3U0RXdoRFlnS0VOT1dTaz0/PSI7CisJU3RyaW5nIGdvb2QgPSAiPT9nYjE4MDMwP0I/eGJmVXFxTGpJQ2hGVlZJcHR0Szd1NEV3aERZZ0tFTk9XU2s9Pz0iOworCVN0cmluZyBnb29kRGVjb2RlZCA9IE1pbWVVdGlsaXR5LmRlY29kZVdvcmQoZ29vZCk7CisKKwlhc3NlcnRFcXVhbHMoImdiMjMxMiIsIGdvb2REZWNvZGVkLCBNaW1lVXRpbGl0eS5kZWNvZGVXb3JkKGJhZGdiMjMxMikpOworCWFzc2VydEVxdWFscygiZ2JrIiwgZ29vZERlY29kZWQsIE1pbWVVdGlsaXR5LmRlY29kZVdvcmQoYmFkZ2JrKSk7CisJYXNzZXJ0RXF1YWxzKCJtczkzNiIsIGdvb2REZWNvZGVkLCBNaW1lVXRpbGl0eS5kZWNvZGVXb3JkKGJhZG1zOTM2KSk7CisJYXNzZXJ0RXF1YWxzKCJjcDkzNiIsIGdvb2REZWNvZGVkLCBNaW1lVXRpbGl0eS5kZWNvZGVXb3JkKGJhZGNwOTM2KSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvTW9kaWZ5TWVzc2FnZVRlc3QuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L01vZGlmeU1lc3NhZ2VUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjc1YjFjZgotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L01vZGlmeU1lc3NhZ2VUZXN0LmphdmEKQEAgLTAsMCArMSwxNjcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMTAsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5pbnRlcm5ldDsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC50ZXN0LkFzY2lpU3RyaW5nSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXQ7CitpbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7CisKK2ltcG9ydCBqYXZheC5tYWlsLlNlc3Npb247CitpbXBvcnQgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YXgubWFpbC5Cb2R5UGFydDsKKworaW1wb3J0IG9yZy5qdW5pdC4qOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEVxdWFsczsKKworLyoqCisgKiBUZXN0IHNvbWUgb2YgdGhlIHdheXMgeW91IG1pZ2h0IG1vZGlmeSBhIG1lc3NhZ2UgdGhhdCBoYXMgYmVlbgorICogcmVhZCBmcm9tIGFuIGlucHV0IHN0cmVhbS4KKyAqLworcHVibGljIGNsYXNzIE1vZGlmeU1lc3NhZ2VUZXN0IHsKKyAKKyAgICBwcml2YXRlIHN0YXRpYyBTZXNzaW9uIHMgPSBTZXNzaW9uLmdldEluc3RhbmNlKG5ldyBQcm9wZXJ0aWVzKCkpOworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0QWRkSGVhZGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1pbWVNZXNzYWdlIG0gPSBjcmVhdGVNZXNzYWdlKCk7CisJTWltZU11bHRpcGFydCBtcCA9IChNaW1lTXVsdGlwYXJ0KW0uZ2V0Q29udGVudCgpOworICAgICAgICBtLnNldEhlYWRlcigiYSIsICJiIik7CisgICAgICAgIG0uc2F2ZUNoYW5nZXMoKTsKKworCU1pbWVNZXNzYWdlIG0yID0gbmV3IE1pbWVNZXNzYWdlKG0pOworCWFzc2VydEVxdWFscygiYiIsIG0yLmdldEhlYWRlcigiYSIsIG51bGwpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RDaGFuZ2VIZWFkZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTWltZU1lc3NhZ2UgbSA9IGNyZWF0ZU1lc3NhZ2UoKTsKKwlNaW1lTXVsdGlwYXJ0IG1wID0gKE1pbWVNdWx0aXBhcnQpbS5nZXRDb250ZW50KCk7CisgICAgICAgIG0uc2V0SGVhZGVyKCJTdWJqZWN0IiwgInRlc3QiKTsKKyAgICAgICAgbS5zYXZlQ2hhbmdlcygpOworCisJTWltZU1lc3NhZ2UgbTIgPSBuZXcgTWltZU1lc3NhZ2UobSk7CisJYXNzZXJ0RXF1YWxzKCJ0ZXN0IiwgbTIuZ2V0SGVhZGVyKCJTdWJqZWN0IiwgbnVsbCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEFkZENvbnRlbnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTWltZU1lc3NhZ2UgbSA9IGNyZWF0ZU1lc3NhZ2UoKTsKKwlNaW1lTXVsdGlwYXJ0IG1wID0gKE1pbWVNdWx0aXBhcnQpbS5nZXRDb250ZW50KCk7CisJTWltZUJvZHlQYXJ0IG1icCA9IG5ldyBNaW1lQm9keVBhcnQoKTsKKyAgICAgICAgbWJwLnNldFRleHQoInRlc3QiKTsKKwltcC5hZGRCb2R5UGFydChtYnApOworICAgICAgICBtLnNhdmVDaGFuZ2VzKCk7CisKKwlNaW1lTWVzc2FnZSBtMiA9IG5ldyBNaW1lTWVzc2FnZShtKTsKKwltcCA9IChNaW1lTXVsdGlwYXJ0KW0yLmdldENvbnRlbnQoKTsKKwlCb2R5UGFydCBicCA9IG1wLmdldEJvZHlQYXJ0KDIpOworCWFzc2VydEVxdWFscygidGVzdCIsIGJwLmdldENvbnRlbnQoKSk7CisJLy8gbWFrZSBzdXJlIG5vdGhpbmcgZWxzZSBjaGFuZ2VkCisJYnAgPSBtcC5nZXRCb2R5UGFydCgwKTsKKwlhc3NlcnRFcXVhbHMoImZpcnN0IHBhcnRcbiIsIGJwLmdldENvbnRlbnQoKSk7CisJYnAgPSBtcC5nZXRCb2R5UGFydCgxKTsKKwlhc3NlcnRFcXVhbHMoInNlY29uZCBwYXJ0XG4iLCBicC5nZXRDb250ZW50KCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdENoYW5nZUNvbnRlbnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgTWltZU1lc3NhZ2UgbSA9IGNyZWF0ZU1lc3NhZ2UoKTsKKwlNaW1lTXVsdGlwYXJ0IG1wID0gKE1pbWVNdWx0aXBhcnQpbS5nZXRDb250ZW50KCk7CisJQm9keVBhcnQgYnAgPSBtcC5nZXRCb2R5UGFydCgwKTsKKyAgICAgICAgYnAuc2V0VGV4dCgidGVzdCIpOworICAgICAgICBtLnNhdmVDaGFuZ2VzKCk7CisKKwlNaW1lTWVzc2FnZSBtMiA9IG5ldyBNaW1lTWVzc2FnZShtKTsKKwltcCA9IChNaW1lTXVsdGlwYXJ0KW0yLmdldENvbnRlbnQoKTsKKwlicCA9IG1wLmdldEJvZHlQYXJ0KDApOworCWFzc2VydEVxdWFscygidGVzdCIsIGJwLmdldENvbnRlbnQoKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Q2hhbmdlTmVzdGVkQ29udGVudCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBNaW1lTWVzc2FnZSBtID0gY3JlYXRlTmVzdGVkTWVzc2FnZSgpOworCU1pbWVNdWx0aXBhcnQgbXAgPSAoTWltZU11bHRpcGFydCltLmdldENvbnRlbnQoKTsKKwltcCA9IChNaW1lTXVsdGlwYXJ0KW1wLmdldEJvZHlQYXJ0KDApLmdldENvbnRlbnQoKTsKKwlCb2R5UGFydCBicCA9IG1wLmdldEJvZHlQYXJ0KDApOworICAgICAgICBicC5zZXRUZXh0KCJ0ZXN0Iik7CisgICAgICAgIG0uc2F2ZUNoYW5nZXMoKTsKKworCU1pbWVNZXNzYWdlIG0yID0gbmV3IE1pbWVNZXNzYWdlKG0pOworCW1wID0gKE1pbWVNdWx0aXBhcnQpbTIuZ2V0Q29udGVudCgpOworCW1wID0gKE1pbWVNdWx0aXBhcnQpbXAuZ2V0Qm9keVBhcnQoMCkuZ2V0Q29udGVudCgpOworCWJwID0gbXAuZ2V0Qm9keVBhcnQoMCk7CisJYXNzZXJ0RXF1YWxzKCJ0ZXN0IiwgYnAuZ2V0Q29udGVudCgpKTsKKwkvLyBtYWtlIHN1cmUgb3RoZXIgY29udGVudCBpcyBub3QgY2hhbmdlZCBvciByZS1lbmNvZGVkCisJTWltZUJvZHlQYXJ0IG1icCA9IChNaW1lQm9keVBhcnQpbXAuZ2V0Qm9keVBhcnQoMSk7CisJYXNzZXJ0RXF1YWxzKCJzZWNvbmQgcGFydFxuIiwgbWJwLmdldENvbnRlbnQoKSk7CisJYXNzZXJ0RXF1YWxzKCJxdW90ZWQtcHJpbnRhYmxlIiwgbWJwLmdldEVuY29kaW5nKCkpOworCW1icCA9IChNaW1lQm9keVBhcnQpbXAuZ2V0Qm9keVBhcnQoMik7CisJYXNzZXJ0RXF1YWxzKCJ0aGlyZCBwYXJ0XG4iLCBtYnAuZ2V0Q29udGVudCgpKTsKKwlhc3NlcnRFcXVhbHMoImJhc2U2NCIsIG1icC5nZXRFbmNvZGluZygpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBNaW1lTWVzc2FnZSBjcmVhdGVNZXNzYWdlKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBjb250ZW50ID0KKwkgICAgIk1pbWUtVmVyc2lvbjogMS4wXG4iICsKKwkgICAgIlN1YmplY3Q6IEV4YW1wbGVcbiIgKworCSAgICAiQ29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5PVwiLVwiXG4iICsKKwkgICAgIlxuIiArCisJICAgICJwcmVhbWJsZVxuIiArCisJICAgICItLS1cbiIgKworCSAgICAiXG4iICsKKwkgICAgImZpcnN0IHBhcnRcbiIgKworCSAgICAiXG4iICsKKwkgICAgIi0tLVxuIiArCisJICAgICJcbiIgKworCSAgICAic2Vjb25kIHBhcnRcbiIgKworCSAgICAiXG4iICsKKwkgICAgIi0tLS0tXG4iOworCisJcmV0dXJuIG5ldyBNaW1lTWVzc2FnZShzLCBuZXcgQXNjaWlTdHJpbmdJbnB1dFN0cmVhbShjb250ZW50KSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgTWltZU1lc3NhZ2UgY3JlYXRlTmVzdGVkTWVzc2FnZSgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworICAgICAgICBTdHJpbmcgY29udGVudCA9CisJICAgICJNaW1lLVZlcnNpb246IDEuMFxuIiArCisJICAgICJTdWJqZWN0OiBFeGFtcGxlXG4iICsKKwkgICAgIkNvbnRlbnQtVHlwZTogbXVsdGlwYXJ0L21peGVkOyBib3VuZGFyeT1cIi1cIlxuIiArCisJICAgICJcbiIgKworCSAgICAicHJlYW1ibGVcbiIgKworCSAgICAiLS0tXG4iICsKKwkgICAgIkNvbnRlbnQtVHlwZTogbXVsdGlwYXJ0L21peGVkOyBib3VuZGFyeT1cInhcIlxuIiArCisJICAgICJcbiIgKworCSAgICAiLS14XG4iICsKKwkgICAgIlxuIiArCisJICAgICJmaXJzdCBwYXJ0XG4iICsKKwkgICAgIlxuIiArCisJICAgICItLXhcbiIgKworCSAgICAiQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogcXVvdGVkLXByaW50YWJsZVxuIiArCisJICAgICJcbiIgKworCSAgICAic2Vjb25kIHBhcnRcbiIgKworCSAgICAiXG4iICsKKwkgICAgIi0teFxuIiArCisJICAgICJDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjRcbiIgKworCSAgICAiXG4iICsKKwkgICAgImRHaHBjbVFnY0dGeWRBbz1cbiIgKwkvLyAidGhpcmQgcGFydFxuIiwgYmFzZTY0IGVuY29kZWQKKwkgICAgIlxuIiArCisJICAgICItLXgtLVxuIiArCisJICAgICItLS0tLVxuIjsKKworCXJldHVybiBuZXcgTWltZU1lc3NhZ2UocywgbmV3IEFzY2lpU3RyaW5nSW5wdXRTdHJlYW0oY29udGVudCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L05ld3NBZGRyZXNzVGVzdC5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvTmV3c0FkZHJlc3NUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTNjY2UzYgotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L05ld3NBZGRyZXNzVGVzdC5qYXZhCkBAIC0wLDAgKzEsMzYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMTQsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5pbnRlcm5ldDsKKworaW1wb3J0IG9yZy5qdW5pdC4qOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEVxdWFsczsKKworLyoqCisgKiBUZXN0IHRoZSBOZXdzQWRkcmVzcyBjbGFzcy4KKyAqCisgKiBYWFggLSBmb3Igbm93LCBqdXN0IHNvbWUgc2ltcGxlIHJlZ3Jlc3Npb24gdGVzdHMgZm9yIHJlcG9ydGVkIGJ1Z3MuCisgKi8KK3B1YmxpYyBjbGFzcyBOZXdzQWRkcmVzc1Rlc3QgeworIAorICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFJlZmxleGl2ZUVxdWFsaXR5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJTmV3c0FkZHJlc3MgYSA9IG5ldyBOZXdzQWRkcmVzcygpOworCWFzc2VydEVxdWFscyhhLCBhKTsJLy8gYnVnIDYzNjUKKwlhID0gbmV3IE5ld3NBZGRyZXNzKCJuZXQudW5peCIpOworCWFzc2VydEVxdWFscyhhLCBhKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9Ob0VuY29kZUZpbGVOYW1lLmphdmEgYi9tYWlsL3NyYy90ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9Ob0VuY29kZUZpbGVOYW1lLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTI1M2Y0YwotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L05vRW5jb2RlRmlsZU5hbWUuamF2YQpAQCAtMCwwICsxLDg5IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDE1LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGphdmF4Lm1haWwuaW50ZXJuZXQ7CisKK2ltcG9ydCBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247CisKK2ltcG9ydCBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5tYWlsLmludGVybmV0Lk1pbWVCb2R5UGFydDsKKworaW1wb3J0IG9yZy5qdW5pdC4qOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydFRydWU7CisKKy8qKgorICogVGVzdCAibWFpbC5taW1lLmVuY29kZWZpbGVuYW1lIiBTeXN0ZW0gcHJvcGVydHkgbm90IHNldC4KKyAqLworcHVibGljIGNsYXNzIE5vRW5jb2RlRmlsZU5hbWUgeworIAorICAgIHByb3RlY3RlZCBzdGF0aWMgU3RyaW5nIGZpbGVOYW1lOworCisgICAgLy8gYSBidW5jaCBvZiBub24tQVNDSUkgY2hhcmFjdGVycworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBlbmNvZGVkRmlsZU5hbWUgPQorCSI9P3V0Zi04P0I/dzRERGdjT0Z3NGJEZ01PQnc0WERoc09IdzRqRGljT0t3NHZEak1PTnc0N0RqOE9RdzRERCIgKworCSJnY09GdzRiRGg4T0l3NG5EaXNPTHc0ekRqY09PdzQvRGtNT1J3NUxEazhPVXc1WERsc09ZdzVuRG1zT2J3NSIgKworCSJ6RG5jT2V3NS9Eb01PaHc2TERvOE9rdzZYRHBzT253NmpEcWNPcXc2dkRyTU90dzY3RHI4T3d3N0hEc3NPeiIgKworCSJ3N1REdGNPMnc3akR1Y082dzd2RHZNTzl3NzdEdjhPQXc0SERoY09HdzRjdVpHOWo/PSI7CisKKyAgICBzdGF0aWMgeworCXRyeSB7CisJICAgIGZpbGVOYW1lID0gTWltZVV0aWxpdHkuZGVjb2RlVGV4dChlbmNvZGVkRmlsZU5hbWUpOworCX0gY2F0Y2ggKFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gZXgpIHsKKwkgICAgLy8gc2hvdWxkIG5ldmVyIGhhcHBlbgorCX0KKwkKKyAgICB9CisKKyAgICAvLyBSRkMgMjIzMSBlbmNvZGluZworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBleHBlY3RlZCA9CisJInV0Zi04JyclQzMlODAlQzMlODElQzMlODUlQzMlODYlQzMlODAlQzMlODElQzMlODUlQzMlODYlQzMlODclQzMlODgiICsKKwkiJUMzJTg5JUMzJThBJUMzJThCJUMzJThDJUMzJThEJUMzJThFJUMzJThGJUMzJTkwJUMzJTgwJUMzJTgxJUMzJTg1IiArCisJIiVDMyU4NiVDMyU4NyVDMyU4OCVDMyU4OSVDMyU4QSVDMyU4QiVDMyU4QyVDMyU4RCVDMyU4RSVDMyU4RiVDMyU5MCIgKworCSIlQzMlOTElQzMlOTIlQzMlOTMlQzMlOTQlQzMlOTUlQzMlOTYlQzMlOTglQzMlOTklQzMlOUElQzMlOUIlQzMlOUMiICsKKwkiJUMzJTlEJUMzJTlFJUMzJTlGJUMzJUEwJUMzJUExJUMzJUEyJUMzJUEzJUMzJUE0JUMzJUE1JUMzJUE2JUMzJUE3IiArCisJIiVDMyVBOCVDMyVBOSVDMyVBQSVDMyVBQiVDMyVBQyVDMyVBRCVDMyVBRSVDMyVBRiVDMyVCMCVDMyVCMSVDMyVCMiIgKworCSIlQzMlQjMlQzMlQjQlQzMlQjUlQzMlQjYlQzMlQjglQzMlQjklQzMlQkElQzMlQkIlQzMlQkMlQzMlQkQlQzMlQkUiICsKKwkiJUMzJUJGJUMzJTgwJUMzJTgxJUMzJTg1JUMzJTg2JUMzJTg3LmRvYyI7CisKKyAgICBAQmVmb3JlQ2xhc3MKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgYmVmb3JlKCkgeworCVN5c3RlbS5vdXQucHJpbnRsbigiTm9FbmNvZGVGaWxlTmFtZSIpOworCVN5c3RlbS5zZXRQcm9wZXJ0eSgibWFpbC5taW1lLmNoYXJzZXQiLCAidXRmLTgiKTsKKwlTeXN0ZW0uY2xlYXJQcm9wZXJ0eSgibWFpbC5taW1lLmVuY29kZWZpbGVuYW1lIik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJTWltZUJvZHlQYXJ0IG1icCA9IG5ldyBNaW1lQm9keVBhcnQoKTsKKwltYnAuc2V0VGV4dCgidGVzdCIpOworCW1icC5zZXRGaWxlTmFtZShmaWxlTmFtZSk7CisJbWJwLnVwZGF0ZUhlYWRlcnMoKTsKKwlTdHJpbmcgaCA9IG1icC5nZXRIZWFkZXIoIkNvbnRlbnQtVHlwZSIsICIiKTsKKwlhc3NlcnRUcnVlKGguY29udGFpbnMoIm5hbWUqPSIpKTsKKwlhc3NlcnRUcnVlKGguY29udGFpbnMoZXhwZWN0ZWQpKTsKKwloID0gbWJwLmdldEhlYWRlcigiQ29udGVudC1EaXNwb3NpdGlvbiIsICIiKTsKKwlhc3NlcnRUcnVlKGguY29udGFpbnMoImZpbGVuYW1lKj0iKSk7CisJYXNzZXJ0VHJ1ZShoLmNvbnRhaW5zKGV4cGVjdGVkKSk7CisgICAgfQorCisgICAgQEFmdGVyQ2xhc3MKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgYWZ0ZXIoKSB7CisJLy8gc2hvdWxkIGJlIHVubmVjZXNzYXJ5CisJU3lzdGVtLmNsZWFyUHJvcGVydHkoIm1haWwubWltZS5jaGFyc2V0Iik7CisJU3lzdGVtLmNsZWFyUHJvcGVydHkoIm1haWwubWltZS5lbmNvZGVmaWxlbmFtZSIpOworCVN5c3RlbS5jbGVhclByb3BlcnR5KCJtYWlsLm1pbWUuZW5jb2RlcGFyYW1ldGVycyIpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L05vbkFzY2lpQm91bmRhcnlUZXN0LmphdmEgYi9tYWlsL3NyYy90ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9Ob25Bc2NpaUJvdW5kYXJ5VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ1NGI5ZmYKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy90ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9Ob25Bc2NpaUJvdW5kYXJ5VGVzdC5qYXZhCkBAIC0wLDAgKzEsNjggQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMTAsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5pbnRlcm5ldDsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC50ZXN0LkFzY2lpU3RyaW5nSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXQ7CitpbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7CisKK2ltcG9ydCBqYXZheC5tYWlsLlNlc3Npb247CitpbXBvcnQgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YXgubWFpbC5Cb2R5UGFydDsKKworaW1wb3J0IG9yZy5qdW5pdC4qOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEVxdWFsczsKKworLyoqCisgKiBUZXN0IHRoYXQgbm9uLUFTQ0lJIGJvdW5kYXJ5IHN0cmluZ3MgYXJlIGhhbmRsZWQgcmVhc29uYWJseSwKKyAqIGV2ZW4gdGhvdWdoLCBzdHJpY3RseSBzcGVha2luZywgdGhlIE1JTUUgc3BlYyBkb2Vzbid0IGFsbG93IHRoZW0uCisgKi8KK3B1YmxpYyBjbGFzcyBOb25Bc2NpaUJvdW5kYXJ5VGVzdCB7CisgCisgICAgcHJpdmF0ZSBzdGF0aWMgU2Vzc2lvbiBzID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShuZXcgUHJvcGVydGllcygpKTsKKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBNaW1lTWVzc2FnZSBtID0gY3JlYXRlTWVzc2FnZSgpOworCU1pbWVNdWx0aXBhcnQgbXAgPSAoTWltZU11bHRpcGFydCltLmdldENvbnRlbnQoKTsKKwlhc3NlcnRFcXVhbHMoMiwgbXAuZ2V0Q291bnQoKSk7CisJQm9keVBhcnQgYnAgPSBtcC5nZXRCb2R5UGFydCgwKTsKKwlhc3NlcnRFcXVhbHMoImZpcnN0IHBhcnRcbiIsIGJwLmdldENvbnRlbnQoKSk7CisJYnAgPSBtcC5nZXRCb2R5UGFydCgxKTsKKwlhc3NlcnRFcXVhbHMoInNlY29uZCBwYXJ0XG4iLCBicC5nZXRDb250ZW50KCkpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIE1pbWVNZXNzYWdlIGNyZWF0ZU1lc3NhZ2UoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKyAgICAgICAgU3RyaW5nIGNvbnRlbnQgPQorCSAgICAiTWltZS1WZXJzaW9uOiAxLjBcbiIgKworCSAgICAiU3ViamVjdDogRXhhbXBsZVxuIiArCisJICAgICJDb250ZW50LVR5cGU6IG11bHRpcGFydC9taXhlZDsgYm91bmRhcnk9XCJcdTAwQTlcIlxuIiArCisJICAgICJcbiIgKworCSAgICAiLS1cdTAwQTlcbiIgKworCSAgICAiXG4iICsKKwkgICAgImZpcnN0IHBhcnRcbiIgKworCSAgICAiXG4iICsKKwkgICAgIi0tXHUwMEE5XG4iICsKKwkgICAgIlxuIiArCisJICAgICJzZWNvbmQgcGFydFxuIiArCisJICAgICJcbiIgKworCSAgICAiLS1cdTAwQTktLVxuIjsKKworCXJldHVybiBuZXcgTWltZU1lc3NhZ2UocywgbmV3IEFzY2lpU3RyaW5nSW5wdXRTdHJlYW0oY29udGVudCwgZmFsc2UpKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9Ob25Bc2NpaUZpbGVOYW1lcy5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvTm9uQXNjaWlGaWxlTmFtZXMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44Yjc5ZDM3Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvTm9uQXNjaWlGaWxlTmFtZXMuamF2YQpAQCAtMCwwICsxLDc4IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDA5LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGphdmF4Lm1haWwuaW50ZXJuZXQ7CisKK2ltcG9ydCBvcmcuanVuaXQuKjsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRFcXVhbHM7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VHJ1ZTsKKworLyoqCisgKiBUZXN0IHRoYXQgbm9uLUFTQ0lJIGZpbGUgbmFtZXMgYXJlIGVuY29kZWQgYnkgZGVmYXVsdC4KKyAqLworcHVibGljIGNsYXNzIE5vbkFzY2lpRmlsZU5hbWVzIHsKKworICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBjaGFyc2V0OworCisgICAgQEJlZm9yZUNsYXNzCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGJlZm9yZSgpIHsKKwlTeXN0ZW0ub3V0LnByaW50bG4oIk5vbkFzY2lpRmlsZU5hbWVzIik7CisJY2hhcnNldCA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgibWFpbC5taW1lLmNoYXJzZXQiKTsKKwlTeXN0ZW0uc2V0UHJvcGVydHkoIm1haWwubWltZS5jaGFyc2V0IiwgInV0Zi04Iik7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IG5vbi1BU0NJSSBmaWxlbmFtZXMgYXJlIGVuY29kZWQgYnkgZGVmYXVsdC4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3ROb25Bc2NpaUZpbGVOYW1lKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJTWltZUJvZHlQYXJ0IG1icCA9IG5ldyBNaW1lQm9keVBhcnQoKTsKKwltYnAuc2V0VGV4dCgidGVzdFxuIik7CisJbWJwLnNldEZpbGVOYW1lKCJ0ZXN0XHUwMGExXHUwMGEyXHUwMGEzIik7CisJTWltZUJvZHlQYXJ0LnVwZGF0ZUhlYWRlcnMobWJwKTsKKworCVN0cmluZyBzID0gbWJwLmdldEhlYWRlcigiQ29udGVudC1EaXNwb3NpdGlvbiIsIG51bGwpOworCWFzc2VydFRydWUoIkNvbnRlbnQtRGlzcG9zaXRpb24gZmlsZW5hbWUiLCBzLmluZGV4T2YoImZpbGVuYW1lKiIpID49IDApOworCXMgPSBtYnAuZ2V0SGVhZGVyKCJDb250ZW50LVR5cGUiLCBudWxsKTsKKwlhc3NlcnRUcnVlKCJDb250ZW50LVR5cGUgbmFtZSIsIHMuaW5kZXhPZigibmFtZSoiKSA+PSAwKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHRoYXQgbm9uLUFTQ0lJIGZpbGVuYW1lcyBhcmUgZW5jb2RlZCBieSBkZWZhdWx0LgorICAgICAqIE1ha2Ugc3VyZSBhbiBleGlzdGluZyBDb250ZW50LVR5cGUgaGVhZGVyIGlzIHVwZGF0ZWQuCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0Tm9uQXNjaWlGaWxlTmFtZVdpdGhDb250ZW50VHlwZSgpIHRocm93cyBFeGNlcHRpb24geworCU1pbWVCb2R5UGFydCBtYnAgPSBuZXcgTWltZUJvZHlQYXJ0KCk7CisJbWJwLnNldFRleHQoInRlc3RcbiIpOworCW1icC5zZXRIZWFkZXIoIkNvbnRlbnQtVHlwZSIsICJ0ZXh0L3gtdGVzdCIpOworCW1icC5zZXRGaWxlTmFtZSgidGVzdFx1MDBhMVx1MDBhMlx1MDBhMyIpOworCU1pbWVCb2R5UGFydC51cGRhdGVIZWFkZXJzKG1icCk7CisKKwlTdHJpbmcgcyA9IG1icC5nZXRIZWFkZXIoIkNvbnRlbnQtRGlzcG9zaXRpb24iLCBudWxsKTsKKwlhc3NlcnRUcnVlKCJDb250ZW50LURpc3Bvc2l0aW9uIGZpbGVuYW1lIiwgcy5pbmRleE9mKCJmaWxlbmFtZSoiKSA+PSAwKTsKKwlzID0gbWJwLmdldEhlYWRlcigiQ29udGVudC1UeXBlIiwgbnVsbCk7CisJYXNzZXJ0VHJ1ZSgiQ29udGVudC1UeXBlIG5hbWUiLCBzLmluZGV4T2YoIm5hbWUqIikgPj0gMCk7CisgICAgfQorCisgICAgQEFmdGVyQ2xhc3MKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgYWZ0ZXIoKSB7CisJaWYgKGNoYXJzZXQgPT0gbnVsbCkKKwkgICAgU3lzdGVtLmNsZWFyUHJvcGVydHkoIm1haWwubWltZS5jaGFyc2V0Iik7CisJZWxzZQorCSAgICBTeXN0ZW0uc2V0UHJvcGVydHkoIm1haWwubWltZS5jaGFyc2V0IiwgY2hhcnNldCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvUGFyYW1ldGVyTGlzdERlY29kZS5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvUGFyYW1ldGVyTGlzdERlY29kZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBjNTRlZDIKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy90ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9QYXJhbWV0ZXJMaXN0RGVjb2RlLmphdmEKQEAgLTAsMCArMSw0MjcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5pbnRlcm5ldDsKKworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBqYXZheC5hY3RpdmF0aW9uLio7CitpbXBvcnQgamF2YXgubWFpbC4qOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuKjsKK2ltcG9ydCBqYXZheC5tYWlsLnV0aWwuKjsKKworaW1wb3J0IG9yZy5qdW5pdC4qOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEVxdWFsczsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUcnVlOworCisvKioKKyAqIFRlc3QgcGFyYW1ldGVyIGxpc3QgcGFyc2luZy4KKyAqCisgKiBYWFggLSB0aGlzIHNob3VsZCBiZSBhIEpVbml0IHBhcmFtZXRlcml6ZWQgdGVzdCwKKyAqCSBidXQgSSBjYW4ndCBmaWd1cmUgb3V0IGhvdyB0byBydW4gcGFyYW1ldGVyaXplZAorICoJIHRlc3RzIHVuZGVyIG15IENsYXNzTG9hZGVyU3VpdGUuCisgKgorICogQGF1dGhvciBCaWxsIFNoYW5ub24KKyAqLworCitwdWJsaWMgY2xhc3MgUGFyYW1ldGVyTGlzdERlY29kZSB7CisgICAgc3RhdGljIGJvb2xlYW4gZ2VuX3Rlc3RfaW5wdXQgPSBmYWxzZTsJLy8gb3V0cHV0IGdvb2QgZm9yIGlucHV0IHRvIC1wCisgICAgc3RhdGljIGJvb2xlYW4gcGFyc2VfbWFpbCA9IGZhbHNlOwkJLy8gcGFyc2UgaW5wdXQgaW4gbWFpbCBmb3JtYXQKKyAgICBzdGF0aWMgYm9vbGVhbiB0ZXN0X21haWwgPSBmYWxzZTsJCS8vIHRlc3QgdXNpbmcgYSBtYWlsIHNlcnZlcgorICAgIHN0YXRpYyBpbnQgZXJyb3JzID0gMDsJCQkvLyBudW1iZXIgb2YgZXJyb3JzIGRldGVjdGVkCisKKyAgICBzdGF0aWMgU3RyaW5nIHByb3RvY29sOworICAgIHN0YXRpYyBTdHJpbmcgaG9zdCA9IG51bGw7CisgICAgc3RhdGljIFN0cmluZyB1c2VyID0gbnVsbDsKKyAgICBzdGF0aWMgU3RyaW5nIHBhc3N3b3JkID0gbnVsbDsKKyAgICBzdGF0aWMgU3RyaW5nIG1ib3ggPSBudWxsOworICAgIHN0YXRpYyBTdHJpbmcgdXJsID0gbnVsbDsKKyAgICBzdGF0aWMgaW50IHBvcnQgPSAtMTsKKyAgICBzdGF0aWMgYm9vbGVhbiBkZWJ1ZyA9IGZhbHNlOworCisgICAgc3RhdGljIFNlc3Npb24gc2Vzc2lvbjsKKyAgICBzdGF0aWMgU3RvcmUgc3RvcmU7CisgICAgc3RhdGljIEZvbGRlciBmb2xkZXI7CisKKyAgICBzdGF0aWMgYm9vbGVhbiBqdW5pdDsKKworICAgIHByb3RlY3RlZCBzdGF0aWMgdm9pZCB0ZXN0RGVjb2RlKFN0cmluZyBwYXJhbURhdGEpIHRocm93cyBFeGNlcHRpb24geworCWp1bml0ID0gdHJ1ZTsKKwlwYXJzZShuZXcgQnVmZmVyZWRSZWFkZXIobmV3IElucHV0U3RyZWFtUmVhZGVyKAorCSAgICBQYXJhbWV0ZXJMaXN0RGVjb2RlLmNsYXNzLmdldFJlc291cmNlQXNTdHJlYW0ocGFyYW1EYXRhKSkpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmcgYXJndltdKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlTeXN0ZW0uZ2V0UHJvcGVydGllcygpLnB1dCgibWFpbC5taW1lLmRlY29kZXBhcmFtZXRlcnMiLCAidHJ1ZSIpOworCWludCBvcHRpbmQ7CisJZm9yIChvcHRpbmQgPSAwOyBvcHRpbmQgPCBhcmd2Lmxlbmd0aDsgb3B0aW5kKyspIHsKKwkgICAgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi0iKSkgeworCQkvLyBpZ25vcmUKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItZyIpKSB7CisJCWdlbl90ZXN0X2lucHV0ID0gdHJ1ZTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItcCIpKSB7CisJCXBhcnNlX21haWwgPSB0cnVlOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1tIikpIHsKKwkJdGVzdF9tYWlsID0gdHJ1ZTsKKwkgICAgfSBlbHNlIGlmIChhcmd2W29wdGluZF0uZXF1YWxzKCItVCIpKSB7CisJCXByb3RvY29sID0gYXJndlsrK29wdGluZF07CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLUgiKSkgeworCQlob3N0ID0gYXJndlsrK29wdGluZF07CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLVUiKSkgeworCQl1c2VyID0gYXJndlsrK29wdGluZF07CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLVAiKSkgeworCQlwYXNzd29yZCA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1EIikpIHsKKwkJZGVidWcgPSB0cnVlOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1mIikpIHsKKwkJbWJveCA9IGFyZ3ZbKytvcHRpbmRdOworCSAgICB9IGVsc2UgaWYgKGFyZ3Zbb3B0aW5kXS5lcXVhbHMoIi1MIikpIHsKKwkJdXJsID0gYXJndlsrK29wdGluZF07CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLXAiKSkgeworCQlwb3J0ID0gSW50ZWdlci5wYXJzZUludChhcmd2Wysrb3B0aW5kXSk7CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLWQiKSkgeworCQlkZWJ1ZyA9IHRydWU7CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLmVxdWFscygiLS0iKSkgeworCQlvcHRpbmQrKzsKKwkJYnJlYWs7CisJICAgIH0gZWxzZSBpZiAoYXJndltvcHRpbmRdLnN0YXJ0c1dpdGgoIi0iKSkgeworCQlTeXN0ZW0ub3V0LnByaW50bG4oCisJCSAgICAiVXNhZ2U6IHBhcmFtdGVzdCBbLWddIFstcF0gWy1dIFtjb250ZW50LXR5cGUgLi4uXSIpOworCQlTeXN0ZW0ub3V0LnByaW50bG4oCisib3JcdHBhcmFtdGVzdCAtbSBbLWddIFstTCB1cmxdIFstVCBwcm90b2NvbF0gWy1IIGhvc3RdIFstcCBwb3J0XSBbLVUgdXNlcl0iKTsKKwkJU3lzdGVtLm91dC5wcmludGxuKAorIlx0Wy1QIHBhc3N3b3JkXSBbLWYgbWFpbGJveF0gWy1kXSIpOworCQlTeXN0ZW0uZXhpdCgxKTsKKwkgICAgfSBlbHNlIHsKKwkJYnJlYWs7CisJICAgIH0KKwl9CisKKwlpZiAodGVzdF9tYWlsKQorCSAgICBpbml0TWFpbCgpOworCisJLyoKKwkgKiBJZiB0aGVyZSdzIGFueSBhcmdzIGxlZnQgb24gdGhlIGNvbW1hbmQgbGluZSwKKwkgKiBjb25jYXRlbmF0ZSB0aGVtIGludG8gYSBzdHJpbmcgYW5kIHRlc3QgdGhhdC4KKwkgKi8KKwlpZiAob3B0aW5kIDwgYXJndi5sZW5ndGgpIHsKKwkgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisJICAgIGZvciAoaW50IGkgPSBvcHRpbmQ7IGkgPCBhcmd2Lmxlbmd0aDsgaSsrKSB7CisJCXNiLmFwcGVuZChhcmd2W2ldKTsKKwkJc2IuYXBwZW5kKCIgIik7CisJICAgIH0KKwkgICAgdGVzdCgiQ29udGVudC1UeXBlIiwgc2IudG9TdHJpbmcoKSwgbnVsbCk7CisJfSBlbHNlIHsKKwkgICAgLy8gcmVhZCBmcm9tIHN0ZGluCisJICAgIEJ1ZmZlcmVkUmVhZGVyIGluID0KKwkJbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBJbnB1dFN0cmVhbVJlYWRlcihTeXN0ZW0uaW4pKTsKKwkgICAgU3RyaW5nIHM7CisKKwkgICAgaWYgKHBhcnNlX21haWwpCisJCXBhcnNlKGluKTsKKwkgICAgZWxzZSBpZiAodGVzdF9tYWlsKQorCQl0ZXN0TWFpbCgpOworCSAgICBlbHNlIHsKKwkJd2hpbGUgKChzID0gaW4ucmVhZExpbmUoKSkgIT0gbnVsbCkKKwkJICAgIHRlc3QoIkNvbnRlbnQtVHlwZSIsIHMsIG51bGwpOworCSAgICB9CisJfQorCisJaWYgKHRlc3RfbWFpbCkKKwkgICAgZG9uZU1haWwoKTsKKworCVN5c3RlbS5leGl0KGVycm9ycyk7CisKKyAgICB9CisKKyAgICAvKgorICAgICAqIFBhcnNlIHRoZSBpbnB1dCBpbiAibWFpbCIgZm9ybWF0LCBleHRyYWN0aW5nIHRoZSBDb250ZW50LVR5cGUKKyAgICAgKiBoZWFkZXJzIGFuZCB0ZXN0aW5nIHRoZW0uICBUaGUgcGFyc2UgaXMgcmF0aGVyIGNydWRlLCBidXQgc3VmZmljaWVudAorICAgICAqIHRvIHRlc3QgYWdhaW5zdCBtb3N0IGV4aXN0aW5nIFVOSVggbWFpbGJveGVzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBwYXJzZShCdWZmZXJlZFJlYWRlciBpbikgdGhyb3dzIEV4Y2VwdGlvbiB7CisJU3RyaW5nIGhlYWRlciA9ICIiOworCisJZm9yICg7OykgeworCSAgICBTdHJpbmcgcyA9IGluLnJlYWRMaW5lKCk7CisJICAgIGlmIChzICE9IG51bGwgJiYgcy5sZW5ndGgoKSA+IDApIHsKKwkJY2hhciBjID0gcy5jaGFyQXQoMCk7CisJCWlmIChjID09ICcgJyB8fCBjID09ICdcdCcpIHsKKwkJICAgIC8vIGEgY29udGludWF0aW9uIGxpbmUsIGFkZCBpdCB0byB0aGUgY3VycmVudCBoZWFkZXIKKwkJICAgIGhlYWRlciArPSAnXG4nICsgczsKKwkJICAgIGNvbnRpbnVlOworCQl9CisJICAgIH0KKwkgICAgLy8gInMiIGlzIHRoZSBuZXh0IGhlYWRlciwgImhlYWRlciIgaXMgdGhlIGxhc3QgY29tcGxldGUgaGVhZGVyCisJICAgIGlmIChoZWFkZXIucmVnaW9uTWF0Y2hlcyh0cnVlLCAwLCAiQ29udGVudC1UeXBlOiAiLCAwLCAxNCkpIHsKKwkJaW50IGk7CisJCVN0cmluZ1tdIGV4cGVjdCA9IG51bGw7CisJCWlmIChzICE9IG51bGwgJiYgcy5zdGFydHNXaXRoKCJFeHBlY3Q6ICIpKSB7CisJCSAgICB0cnkgeworCQkJaW50IG5leHBlY3QgPSBJbnRlZ2VyLnBhcnNlSW50KHMuc3Vic3RyaW5nKDgpKTsKKwkJCWV4cGVjdCA9IG5ldyBTdHJpbmdbbmV4cGVjdF07CisJCQlmb3IgKGkgPSAwOyBpIDwgbmV4cGVjdDsgaSsrKQorCQkJICAgIGV4cGVjdFtpXSA9IGRlY29kZSh0cmltKGluLnJlYWRMaW5lKCkpKTsKKwkJICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBlKSB7CisJCQl0cnkgeworCQkJICAgIGlmIChzLnN1YnN0cmluZyg4LCAxNykuZXF1YWxzKCJFeGNlcHRpb24iKSkgeworCQkJCWV4cGVjdCA9IG5ldyBTdHJpbmdbMV07CisJCQkJZXhwZWN0WzBdID0gIkV4Y2VwdGlvbiI7CisJCQkgICAgfQorCQkJfSBjYXRjaCAoU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBzZSkgeworCQkJICAgIC8vIGlnbm9yZSBpdAorCQkJfQorCQkgICAgfQorCQl9CisJCWkgPSBoZWFkZXIuaW5kZXhPZignOicpOworCQl0cnkgeworCQkgICAgdGVzdChoZWFkZXIuc3Vic3RyaW5nKDAsIGkpLCBoZWFkZXIuc3Vic3RyaW5nKGkgKyAyKSwKKwkJCWV4cGVjdCk7CisJCX0gY2F0Y2ggKFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworCQkgICAgLy8gaWdub3JlCisJCX0KKwkgICAgfQorCSAgICBpZiAocyA9PSBudWxsKQorCQlyZXR1cm47CQkvLyBFT0YKKwkgICAgaWYgKHMubGVuZ3RoKCkgPT0gMCkgeworCQl3aGlsZSAoKHMgPSBpbi5yZWFkTGluZSgpKSAhPSBudWxsKSB7CisJCSAgICBpZiAocy5zdGFydHNXaXRoKCJGcm9tICIpKQorCQkJYnJlYWs7CisJCX0KKwkJaWYgKHMgPT0gbnVsbCkKKwkJICAgIHJldHVybjsKKwkgICAgfQorCSAgICBoZWFkZXIgPSBzOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMaWtlIFN0cmluZy50cmltLCBidXQgb25seSB0aGUgbGVmdCBzaWRlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHRyaW0oU3RyaW5nIHMpIHsKKwlpbnQgaSA9IDA7CisJd2hpbGUgKGkgPCBzLmxlbmd0aCgpICYmIHMuY2hhckF0KGkpIDw9ICcgJykKKwkgICAgaSsrOworCXJldHVybiBzLnN1YnN0cmluZyhpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZWNvZGUgVW5pY29kZSBlc2NhcGVzLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGRlY29kZShTdHJpbmcgcykgeworCVN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworCWZvciAoaW50IGkgPSAwOyBpIDwgcy5sZW5ndGgoKTsgaSsrKSB7CisJICAgIGNoYXIgYyA9IHMuY2hhckF0KGkpOworCSAgICBpZiAoYyA9PSAnXFwnICYmIHMuY2hhckF0KGkgKyAxKSA9PSAndScpIHsKKwkJYyA9IChjaGFyKUludGVnZXIucGFyc2VJbnQocy5zdWJzdHJpbmcoaSArIDIsIGkgKyA2KSwgMTYpOworCQlpICs9IDU7CisJICAgIH0KKwkgICAgc2IuYXBwZW5kKGMpOworCX0KKwlyZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0IHRoZSBoZWFkZXIncyB2YWx1ZSB0byBzZWUgaWYgd2UgY2FuIHBhcnNlIGl0IGFzIGV4cGVjdGVkLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCB0ZXN0KFN0cmluZyBoZWFkZXIsIFN0cmluZyB2YWx1ZSwgU3RyaW5nIGV4cGVjdFtdKQorCQl0aHJvd3MgRXhjZXB0aW9uIHsKKwlQcmludFN0cmVhbSBvdXQgPSBTeXN0ZW0ub3V0OworCUJ5dGVBcnJheU91dHB1dFN0cmVhbSBib3MgPSBudWxsOworCWlmIChnZW5fdGVzdF9pbnB1dCkgeworCSAgICBpZiAodGVzdF9tYWlsKSB7CisJCWJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKwkJb3V0ID0gbmV3IFByaW50U3RyZWFtKGJvcyk7CisJICAgIH0gZWxzZSB7CisJCW91dC5wcmludGxuKGhlYWRlciArICI6ICIgKyB2YWx1ZSk7CisJICAgIH0KKwl9IGVsc2UgaWYgKCFqdW5pdCkKKwkgICAgb3V0LnByaW50bG4oIlRlc3Q6ICIgKyB2YWx1ZSk7CisKKwl0cnkgeworCSAgICBDb250ZW50VHlwZSBjdCA9IG5ldyBDb250ZW50VHlwZSh2YWx1ZSk7CisJICAgIFBhcmFtZXRlckxpc3QgcGwgPSBjdC5nZXRQYXJhbWV0ZXJMaXN0KCk7CisJICAgIGlmIChnZW5fdGVzdF9pbnB1dCkKKwkJb3V0LnByaW50bG4oIkV4cGVjdDogIiArIHBsLnNpemUoKSk7CisJICAgIGVsc2UgaWYgKGp1bml0KQorCQlhc3NlcnRFcXVhbHMoIk51bWJlciBvZiBwYXJhbWV0ZXJzIiwKKwkJICAgIGV4cGVjdC5sZW5ndGgsIHBsLnNpemUoKSk7CisJICAgIGVsc2UgeworCQlvdXQucHJpbnRsbigiR290ICIgKyBwbC5zaXplKCkgKyAiIHBhcmFtZXRlcnM6Iik7CisJCWlmIChleHBlY3QgIT0gbnVsbCAmJiBwbC5zaXplKCkgIT0gZXhwZWN0Lmxlbmd0aCkgeworCQkgICAgb3V0LnByaW50bG4oIkV4cGVjdGVkICIgKyBleHBlY3QubGVuZ3RoICsgIiBwYXJhbWV0ZXJzIik7CisJCSAgICBlcnJvcnMrKzsKKwkJfQorCSAgICB9CisJICAgIEVudW1lcmF0aW9uPFN0cmluZz4gZSA9IHBsLmdldE5hbWVzKCk7CisJICAgIGZvciAoaW50IGkgPSAwOyBlLmhhc01vcmVFbGVtZW50cygpOyBpKyspIHsKKwkJU3RyaW5nIG5hbWUgPSBlLm5leHRFbGVtZW50KCk7CisJCVN0cmluZyBwdmFsdWUgPSBwbC5nZXQobmFtZSk7CisJCWlmIChnZW5fdGVzdF9pbnB1dCkKKwkJICAgIG91dC5wcmludGxuKCJcdCIgKyBuYW1lICsgIj0iICsgcHZhbHVlKTsJLy8gWFhYIC0gbmV3bGluZQorCQllbHNlIGlmIChqdW5pdCkgeworCQkgICAgaWYgKGkgPCBleHBlY3QubGVuZ3RoKQorCQkJYXNzZXJ0RXF1YWxzKCJQYXJhbWV0ZXIgdmFsdWUiLAorCQkJICAgIGV4cGVjdFtpXSwgbmFtZSArICI9IiArIHB2YWx1ZSk7CisJCX0gZWxzZSB7CisJCSAgICBvdXQucHJpbnRsbigiXHRbIiArIChpKzEpICsgIl0gTmFtZTogIiArIG5hbWUgKworCQkJIlx0XHRWYWx1ZTogIiArIHB2YWx1ZSk7CisJCSAgICBpZiAoZXhwZWN0ICE9IG51bGwgJiYgaSA8IGV4cGVjdC5sZW5ndGggJiYKKwkJCQkhZXhwZWN0W2ldLmVxdWFscyhuYW1lICsgIj0iICsgcHZhbHVlKSkgeworCQkJb3V0LnByaW50bG4oIlx0RXhwZWN0ZWQ6XHQiICsgZXhwZWN0W2ldKTsKKwkJCWVycm9ycysrOworCQkgICAgfQorCQl9CisJICAgIH0KKwl9IGNhdGNoIChQYXJzZUV4Y2VwdGlvbiBlKSB7CisJICAgIGlmIChnZW5fdGVzdF9pbnB1dCkKKwkJb3V0LnByaW50bG4oIkV4cGVjdDogRXhjZXB0aW9uICIgKyBlKTsKKwkgICAgZWxzZSBpZiAoanVuaXQpCisJCWFzc2VydFRydWUoIkV4cGVjdGVkIGV4Y2VwdGlvbiIsCisJCSAgICBleHBlY3QubGVuZ3RoID09IDEgJiYgZXhwZWN0WzBdLmVxdWFscygiRXhjZXB0aW9uIikpOworCSAgICBlbHNlIHsKKwkJb3V0LnByaW50bG4oIkdvdCBFeGNlcHRpb246ICIgKyBlKTsKKwkJaWYgKGV4cGVjdCAhPSBudWxsICYmCisJCSAgIChleHBlY3QubGVuZ3RoICE9IDEgfHwgIWV4cGVjdFswXS5lcXVhbHMoIkV4Y2VwdGlvbiIpKSkgeworCQkgICAgb3V0LnByaW50bG4oIkV4cGVjdGVkICIgKyBleHBlY3QubGVuZ3RoICsgIiBwYXJhbWV0ZXJzIik7CisJCSAgICBmb3IgKGludCBpID0gMDsgaSA8IGV4cGVjdC5sZW5ndGg7IGkrKykKKwkJCW91dC5wcmludGxuKCJcdEV4cGVjdGVkOlx0IiArIGV4cGVjdFtpXSk7CisJCSAgICBlcnJvcnMrKzsKKwkJfQorCSAgICB9CisJfQorCWlmIChnZW5fdGVzdF9pbnB1dCAmJiB0ZXN0X21haWwpIHsKKwkgICAgTWltZU1lc3NhZ2UgbXNnID0gbmV3IE1pbWVNZXNzYWdlKHNlc3Npb24pOworCSAgICBieXRlW10gYnVmID0gYm9zLnRvQnl0ZUFycmF5KCk7CisJICAgIG1zZy5zZXREYXRhSGFuZGxlcihuZXcgRGF0YUhhbmRsZXIoCisJCW5ldyBCeXRlQXJyYXlEYXRhU291cmNlKGJ1ZiwgdmFsdWUpKSk7CisJICAgIG1zZy5zYXZlQ2hhbmdlcygpOworCSAgICAvL21zZy53cml0ZVRvKFN5c3RlbS5vdXQpOworCSAgICBmb2xkZXIuYXBwZW5kTWVzc2FnZXMobmV3IE1lc3NhZ2VbXSB7IG1zZyB9KTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogSW5pdGlhbGl6ZSB0aGUgU2Vzc2lvbiwgU3RvcmUsIGFuZCBGb2xkZXIuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBpbml0TWFpbCgpIHsKKyAgICAgICAgdHJ5IHsKKwkgICAgLy8gR2V0IGEgUHJvcGVydGllcyBvYmplY3QKKwkgICAgUHJvcGVydGllcyBwcm9wcyA9IFN5c3RlbS5nZXRQcm9wZXJ0aWVzKCk7CisKKwkgICAgLy8gR2V0IGEgU2Vzc2lvbiBvYmplY3QKKwkgICAgc2Vzc2lvbiA9IFNlc3Npb24uZ2V0SW5zdGFuY2UocHJvcHMsIG51bGwpOworCSAgICBzZXNzaW9uLnNldERlYnVnKGRlYnVnKTsKKworCSAgICAvLyBHZXQgYSBTdG9yZSBvYmplY3QKKwkgICAgaWYgKHVybCAhPSBudWxsKSB7CisJCVVSTE5hbWUgdXJsbiA9IG5ldyBVUkxOYW1lKHVybCk7CisJCXN0b3JlID0gc2Vzc2lvbi5nZXRTdG9yZSh1cmxuKTsKKwkJc3RvcmUuY29ubmVjdCgpOworCSAgICB9IGVsc2UgeworCQlpZiAocHJvdG9jb2wgIT0gbnVsbCkJCQorCQkgICAgc3RvcmUgPSBzZXNzaW9uLmdldFN0b3JlKHByb3RvY29sKTsKKwkJZWxzZQorCQkgICAgc3RvcmUgPSBzZXNzaW9uLmdldFN0b3JlKCk7CisKKwkJLy8gQ29ubmVjdAorCQlpZiAoaG9zdCAhPSBudWxsIHx8IHVzZXIgIT0gbnVsbCB8fCBwYXNzd29yZCAhPSBudWxsKQorCQkgICAgc3RvcmUuY29ubmVjdChob3N0LCBwb3J0LCB1c2VyLCBwYXNzd29yZCk7CisJCWVsc2UKKwkJICAgIHN0b3JlLmNvbm5lY3QoKTsKKwkgICAgfQorCisJICAgIC8vIE9wZW4gdGhlIEZvbGRlcgorCisJICAgIGZvbGRlciA9IHN0b3JlLmdldERlZmF1bHRGb2xkZXIoKTsKKwkgICAgaWYgKGZvbGRlciA9PSBudWxsKSB7CisJICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIk5vIGRlZmF1bHQgZm9sZGVyIik7CisJICAgICAgICBTeXN0ZW0uZXhpdCgxKTsKKwkgICAgfQorCisJICAgIGlmIChtYm94ID09IG51bGwpCisJCW1ib3ggPSAicGFyYW1ldGVyLWxpc3QtdGVzdCI7CisJICAgIGZvbGRlciA9IGZvbGRlci5nZXRGb2xkZXIobWJveCk7CisJICAgIGlmIChmb2xkZXIgPT0gbnVsbCkgeworCSAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJJbnZhbGlkIGZvbGRlciIpOworCSAgICAgICAgU3lzdGVtLmV4aXQoMSk7CisJICAgIH0KKworCSAgICBpZiAoZ2VuX3Rlc3RfaW5wdXQpIHsKKwkJZm9sZGVyLmRlbGV0ZShmYWxzZSk7CisJCWZvbGRlci5jcmVhdGUoRm9sZGVyLkhPTERTX01FU1NBR0VTKTsKKwkJZm9sZGVyLm9wZW4oRm9sZGVyLlJFQURfV1JJVEUpOworCSAgICB9IGVsc2UgeworCQlmb2xkZXIub3BlbihGb2xkZXIuUkVBRF9PTkxZKTsKKwkgICAgfQorCisJfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJICAgIFN5c3RlbS5vdXQucHJpbnRsbigiT29wcywgZ290IGV4Y2VwdGlvbiEgIiArIGV4LmdldE1lc3NhZ2UoKSk7CisJICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOworCSAgICBTeXN0ZW0uZXhpdCgxKTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2UgdGhlIEZvbGRlciBhbmQgU3RvcmUuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBkb25lTWFpbCgpIHRocm93cyBFeGNlcHRpb24geworCWZvbGRlci5jbG9zZShmYWxzZSk7CisJc3RvcmUuY2xvc2UoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVc2UgdGhlIG1lc3NhZ2VzIGluIHRoZSBGb2xkZXIgZm9yIHRlc3RpbmcuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCB0ZXN0TWFpbCgpIHRocm93cyBFeGNlcHRpb24geworCU1lc3NhZ2VbXSBtc2dzID0gZm9sZGVyLmdldE1lc3NhZ2VzKCk7CisKKwlmb3IgKGludCBpID0gMDsgaSA8IG1zZ3MubGVuZ3RoOyBpKyspCisJICAgIHRlc3RNZXNzYWdlKG1zZ3NbaV0pOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgYW4gaW5kaXZpZHVhbCBtZXNzYWdlLgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgdGVzdE1lc3NhZ2UoTWVzc2FnZSBtc2cpIHRocm93cyBFeGNlcHRpb24geworCVN0cmluZ1tdIGV4cGVjdCA9IG51bGw7CisKKwlCdWZmZXJlZFJlYWRlciBpbiA9IG5ldyBCdWZmZXJlZFJlYWRlcigKKwkJCSAgICBuZXcgSW5wdXRTdHJlYW1SZWFkZXIobXNnLmdldElucHV0U3RyZWFtKCkpKTsKKworCVN0cmluZyBzID0gaW4ucmVhZExpbmUoKTsKKwlpZiAocyAhPSBudWxsICYmIHMuc3RhcnRzV2l0aCgiRXhwZWN0OiAiKSkgeworCSAgICB0cnkgeworCQlpbnQgbmV4cGVjdCA9IEludGVnZXIucGFyc2VJbnQocy5zdWJzdHJpbmcoOCkpOworCQlleHBlY3QgPSBuZXcgU3RyaW5nW25leHBlY3RdOworCQlmb3IgKGludCBpID0gMDsgaSA8IG5leHBlY3Q7IGkrKykKKwkJICAgIGV4cGVjdFtpXSA9IHRyaW0oaW4ucmVhZExpbmUoKSk7CisJICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBlKSB7CisJCXRyeSB7CisJCSAgICBpZiAocy5zdWJzdHJpbmcoOCwgMTcpLmVxdWFscygiRXhjZXB0aW9uIikpIHsKKwkJCWV4cGVjdCA9IG5ldyBTdHJpbmdbMV07CisJCQlleHBlY3RbMF0gPSAiRXhjZXB0aW9uIjsKKwkJICAgIH0KKwkJfSBjYXRjaCAoU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBzZSkgeworCQkgICAgLy8gaWdub3JlIGl0CisJCX0KKwkgICAgfQorCX0KKworCVN0cmluZyBjdCA9IG1zZy5nZXRDb250ZW50VHlwZSgpOworCXRlc3QoIkNvbnRlbnQtVHlwZTogIiwgY3QsIGV4cGVjdCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvUGFyYW1ldGVyTGlzdFRlc3RTdWl0ZS5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvUGFyYW1ldGVyTGlzdFRlc3RTdWl0ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY2YzMyZDQKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy90ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9QYXJhbWV0ZXJMaXN0VGVzdFN1aXRlLmphdmEKQEAgLTAsMCArMSwzOSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwOSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsLmludGVybmV0OworCitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXJzLlN1aXRlLlN1aXRlQ2xhc3NlczsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC50ZXN0LkNsYXNzTG9hZGVyU3VpdGU7CitpbXBvcnQgY29tLnN1bi5tYWlsLnRlc3QuQ2xhc3NMb2FkZXJTdWl0ZS5UZXN0Q2xhc3M7CisKKy8qKgorICogU3VpdGUgb2YgUGFyYW1ldGVyTGlzdCB0ZXN0cyB0aGF0IG5lZWQgdG8gYmUgcnVuIGluIGEgc2VwYXJhdGUgY2xhc3MgbG9hZGVyLgorICovCitAUnVuV2l0aChDbGFzc0xvYWRlclN1aXRlLmNsYXNzKQorQFRlc3RDbGFzcyhQYXJhbWV0ZXJMaXN0LmNsYXNzKQorQFN1aXRlQ2xhc3NlcyggeworICAgIFBhcmFtZXRlckxpc3RUZXN0cy5jbGFzcywKKyAgICBXaW5kb3dzRmlsZU5hbWVzLmNsYXNzLAorICAgIEFwcGxlRmlsZU5hbWVzLmNsYXNzLAorICAgIE5vbkFzY2lpRmlsZU5hbWVzLmNsYXNzLAorICAgIERlY29kZVBhcmFtZXRlcnMuY2xhc3MsCisgICAgUGFyYW1ldGVyc05vU3RyaWN0LmNsYXNzCit9KQorcHVibGljIGNsYXNzIFBhcmFtZXRlckxpc3RUZXN0U3VpdGUgeworfQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvUGFyYW1ldGVyTGlzdFRlc3RzLmphdmEgYi9tYWlsL3NyYy90ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9QYXJhbWV0ZXJMaXN0VGVzdHMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ZGYwMjY2Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvUGFyYW1ldGVyTGlzdFRlc3RzLmphdmEKQEAgLTAsMCArMSw3MiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwOSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsLmludGVybmV0OworCitpbXBvcnQgb3JnLmp1bml0Lio7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RXF1YWxzOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydFRydWU7CisKKy8qKgorICogWFhYIC0gYWRkIG1vcmUgdGVzdHMKKyAqLworcHVibGljIGNsYXNzIFBhcmFtZXRlckxpc3RUZXN0cyB7CisKKyAgICBAQmVmb3JlQ2xhc3MKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgYmVmb3JlKCkgeworCVN5c3RlbS5vdXQucHJpbnRsbigiUGFyYW1ldGVyTGlzdFRlc3RzIik7CisJU3lzdGVtLmNsZWFyUHJvcGVydHkoIm1haWwubWltZS53aW5kb3dzZmlsZW5hbWVzIik7CisJU3lzdGVtLmNsZWFyUHJvcGVydHkoIm1haWwubWltZS5hcHBsZWZpbGVuYW1lcyIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCBiYWNrc2xhc2hlcyBhcmUgcHJvcGVybHkgcmVtb3ZlZC4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RCYWNrc2xhc2goKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlTeXN0ZW0uY2xlYXJQcm9wZXJ0eSgibWFpbC5taW1lLndpbmRvd3NmaWxlbmFtZXMiKTsKKwlQYXJhbWV0ZXJMaXN0IHBsID0gbmV3IFBhcmFtZXRlckxpc3QoIjsgZmlsZW5hbWU9XCJcXGFcXGJcXGMudHh0XCIiKTsKKwlhc3NlcnRFcXVhbHMocGwuZ2V0KCJmaWxlbmFtZSIpLCAiYWJjLnR4dCIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3QgdGhhdCBhIGxvbmcgcGFyYW1ldGVyIHRoYXQncyBiZWVuIHNwbGl0IGludG8gc2VnbWVudHMKKyAgICAgKiBpcyBwYXJzZWQgY29ycmVjdGx5LgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdExvbmdQYXJzZSgpIHRocm93cyBFeGNlcHRpb24geworCVN0cmluZyBwMCA9ICJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSI7CisJU3RyaW5nIHAxID0gImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIjsKKwlQYXJhbWV0ZXJMaXN0IHBsID0gbmV3IFBhcmFtZXRlckxpc3QoIjsgcCowPSIrcDArIjsgcCoxPSIrcDEpOworCWFzc2VydEVxdWFscyhwMCArIHAxLCBwbC5nZXQoInAiKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IGEgbG9uZyBwYXJhbWV0ZXIgdGhhdCdzIHNldCBwcm9ncmFtbWF0aWNhbGx5IGlzIHNwbGl0CisgICAgICogaW50byBzZWdtZW50cy4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RMb25nU2V0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJU3RyaW5nIHAwID0gImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIjsKKwlTdHJpbmcgcDEgPSAiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiOworCVBhcmFtZXRlckxpc3QgcGwgPSBuZXcgUGFyYW1ldGVyTGlzdCgpOworCXBsLnNldCgicCIsIHAwICsgcDEpOworCWFzc2VydEVxdWFscyhwMCArIHAxLCBwbC5nZXQoInAiKSk7CisJU3RyaW5nIHBscyA9IHBsLnRvU3RyaW5nKCk7CisJYXNzZXJ0VHJ1ZShwbHMuaW5kZXhPZigicCowPSIpID49IDApOworCWFzc2VydFRydWUocGxzLmluZGV4T2YoInAqMT0iKSA+PSAwKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9QYXJhbWV0ZXJzTm9TdHJpY3QuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L1BhcmFtZXRlcnNOb1N0cmljdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYzNjc3OTcKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy90ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9QYXJhbWV0ZXJzTm9TdHJpY3QuamF2YQpAQCAtMCwwICsxLDQ0IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDEwLCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGphdmF4Lm1haWwuaW50ZXJuZXQ7CisKK2ltcG9ydCBvcmcuanVuaXQuKjsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRFcXVhbHM7CisKKy8qKgorICogVGVzdCB0aGF0IHRoZSAibWFpbC5taW1lLnBhcmFtZXRlcnMuc3RyaWN0IiBTeXN0ZW0gcHJvcGVydHkKKyAqIHNldCB0byBmYWxzZSBhbGxvd3MgYm9ndXMgcGFyYW1ldGVycyB0byBiZSBwYXJzZWQuCisgKi8KK3B1YmxpYyBjbGFzcyBQYXJhbWV0ZXJzTm9TdHJpY3QgZXh0ZW5kcyBQYXJhbWV0ZXJMaXN0RGVjb2RlIHsKKworICAgIEBCZWZvcmVDbGFzcworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBiZWZvcmUoKSB7CisJU3lzdGVtLm91dC5wcmludGxuKCJQYXJhbWV0ZXJzTm9TdHJpY3QiKTsKKwlTeXN0ZW0uc2V0UHJvcGVydHkoIm1haWwubWltZS5wYXJhbWV0ZXJzLnN0cmljdCIsICJmYWxzZSIpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdERlY29kZSgpIHRocm93cyBFeGNlcHRpb24geworCXRlc3REZWNvZGUoInBhcmFtZGF0YW5vc3RyaWN0Iik7CisgICAgfQorCisgICAgQEFmdGVyQ2xhc3MKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgYWZ0ZXIoKSB7CisJLy8gc2hvdWxkIGJlIHVubmVjZXNzYXJ5CisJU3lzdGVtLmNsZWFyUHJvcGVydHkoIm1haWwubWltZS5wYXJhbWV0ZXJzLnN0cmljdCIpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L1JlZmVyZW5jZXNUZXN0LmphdmEgYi9tYWlsL3NyYy90ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9SZWZlcmVuY2VzVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYyYmE1YjIKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy90ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9SZWZlcmVuY2VzVGVzdC5qYXZhCkBAIC0wLDAgKzEsOTkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5pbnRlcm5ldDsKKworaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOworaW1wb3J0IGphdmF4Lm1haWwuKjsKK2ltcG9ydCBqYXZheC5tYWlsLmludGVybmV0Lio7CisKK2ltcG9ydCBvcmcuanVuaXQuKjsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRFcXVhbHM7CisKKy8qKgorICogVGVzdCBzZXR0aW5nIG9mIHRoZSBSZWZlcmVuY2VzIGhlYWRlci4KKyAqCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCitwdWJsaWMgY2xhc3MgUmVmZXJlbmNlc1Rlc3QgeworICAgIHByaXZhdGUgc3RhdGljIFNlc3Npb24gc2Vzc2lvbiA9IFNlc3Npb24uZ2V0SW5zdGFuY2UobmV3IFByb3BlcnRpZXMoKSk7CisKKyAgICAvKgorICAgICAqIFRlc3QgY2FzZXM6CisgICAgICogCisgICAgICogTWVzc2FnZS1JZAlSZWZlcmVuY2VzCUluLVJlcGx5LVRvCUV4cGVjdGVkIFJlc3VsdAorICAgICAqLworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0MSgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXRlc3QobnVsbCwJbnVsbCwJCW51bGwsCQludWxsKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3QyKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJdGVzdChudWxsLAludWxsLAkJIjwxQGE+IiwJIjwxQGE+Iik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0MygpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXRlc3QobnVsbCwJIjwyQGI+IiwJbnVsbCwJCSI8MkBiPiIpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdDQoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwl0ZXN0KG51bGwsCSI8MkBiPiIsCSI8MUBhPiIsCSI8MkBiPiIpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdDUoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwl0ZXN0KCI8M0BjPiIsCW51bGwsCQludWxsLAkJIjwzQGM+Iik7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0NigpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXRlc3QoIjwzQGM+IiwJbnVsbCwJCSI8MUBhPiIsCSI8MUBhPiA8M0BjPiIpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdDcoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwl0ZXN0KCI8M0BjPiIsCSI8MkBiPiIsCW51bGwsCQkiPDJAYj4gPDNAYz4iKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3Q4KCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJdGVzdCgiPDNAYz4iLAkiPDJAYj4iLAkiPDFAYT4iLAkiPDJAYj4gPDNAYz4iKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHRlc3QoU3RyaW5nIG1zZ2lkLCBTdHJpbmcgcmVmLCBTdHJpbmcgaXJ0LCBTdHJpbmcgcmVzKQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCU1pbWVNZXNzYWdlIG1zZyA9IG5ldyBNaW1lTWVzc2FnZShzZXNzaW9uKTsKKwltc2cuc2V0RnJvbSgpOworCW1zZy5zZXRSZWNpcGllbnRzKE1lc3NhZ2UuUmVjaXBpZW50VHlwZS5UTywgInlvdUBleGFtcGxlLmNvbSIpOworCW1zZy5zZXRTdWJqZWN0KCJ0ZXN0Iik7CisJaWYgKG1zZ2lkICE9IG51bGwpCisJICAgIG1zZy5zZXRIZWFkZXIoIk1lc3NhZ2UtSWQiLCBtc2dpZCk7CisJaWYgKHJlZiAhPSBudWxsKQorCSAgICBtc2cuc2V0SGVhZGVyKCJSZWZlcmVuY2VzIiwgcmVmKTsKKwlpZiAoaXJ0ICE9IG51bGwpCisJICAgIG1zZy5zZXRIZWFkZXIoIkluLVJlcGx5LVRvIiwgaXJ0KTsKKwltc2cuc2V0VGV4dCgidGV4dCIpOworCisJTWltZU1lc3NhZ2UgcmVwbHkgPSAoTWltZU1lc3NhZ2UpbXNnLnJlcGx5KGZhbHNlKTsKKwlTdHJpbmcgcnJlZiA9IHJlcGx5LmdldEhlYWRlcigiUmVmZXJlbmNlcyIsICIgIik7CisKKwlhc3NlcnRFcXVhbHMocmVzLCBycmVmKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L2phdmEvamF2YXgvbWFpbC9pbnRlcm5ldC9SZXN0cmljdEVuY29kaW5nVGVzdC5qYXZhIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvUmVzdHJpY3RFbmNvZGluZ1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ZDMyYTBiCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvUmVzdHJpY3RFbmNvZGluZ1Rlc3QuamF2YQpAQCAtMCwwICsxLDEwOCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAxMCwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBqYXZheC5tYWlsLmludGVybmV0OworCitpbXBvcnQgY29tLnN1bi5tYWlsLnRlc3QuQXNjaWlTdHJpbmdJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldDsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKKworaW1wb3J0IGphdmF4Lm1haWwuU2Vzc2lvbjsKK2ltcG9ydCBqYXZheC5tYWlsLk1lc3NhZ2luZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5tYWlsLkJvZHlQYXJ0OworCitpbXBvcnQgb3JnLmp1bml0Lio7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RXF1YWxzOworCisvKioKKyAqIFRlc3QgdGhhdCB0aGUgQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZyBoZWFkZXIgaXMgaWdub3JlZAorICogZm9yIGNvbXBvc2l0ZSBwYXJ0cy4KKyAqCisgKiBYWFggLSBXZSBkb24ndCB0ZXN0IGFueSBvZiB0aGUgcHJvcGVydGllcyB0aGF0IGNvbnRyb2wgdGhpcyBiZWhhdmlvci4KKyAqLworcHVibGljIGNsYXNzIFJlc3RyaWN0RW5jb2RpbmdUZXN0IHsKKyAKKyAgICBwcml2YXRlIHN0YXRpYyBTZXNzaW9uIHMgPSBTZXNzaW9uLmdldEluc3RhbmNlKG5ldyBQcm9wZXJ0aWVzKCkpOworCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TXVsdGlwYXJ0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1pbWVNZXNzYWdlIG0gPSBjcmVhdGVNZXNzYWdlKCk7CisJTWltZU11bHRpcGFydCBtcCA9IChNaW1lTXVsdGlwYXJ0KW0uZ2V0Q29udGVudCgpOworCWFzc2VydEVxdWFscygyLCBtcC5nZXRDb3VudCgpKTsKKworCUJvZHlQYXJ0IGJwID0gbXAuZ2V0Qm9keVBhcnQoMCk7CisJYXNzZXJ0RXF1YWxzKCJmaXJzdCBwYXJ0PVxuIiwgYnAuZ2V0Q29udGVudCgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RNZXNzYWdlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIE1pbWVNZXNzYWdlIG0gPSBjcmVhdGVNZXNzYWdlKCk7CisJTWltZU11bHRpcGFydCBtcCA9IChNaW1lTXVsdGlwYXJ0KW0uZ2V0Q29udGVudCgpOworCisJQm9keVBhcnQgYnAgPSBtcC5nZXRCb2R5UGFydCgxKTsKKwlNaW1lTWVzc2FnZSBtMiA9IChNaW1lTWVzc2FnZSlicC5nZXRDb250ZW50KCk7CisJYXNzZXJ0RXF1YWxzKCJtZXNzYWdlPVxuIiwgbTIuZ2V0Q29udGVudCgpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RXcml0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBNaW1lTWVzc2FnZSBtID0gbmV3IE1pbWVNZXNzYWdlKHMpOworCU1pbWVNdWx0aXBhcnQgbXAgPSBuZXcgTWltZU11bHRpcGFydCgpOworCU1pbWVCb2R5UGFydCBtYnAgPSBuZXcgTWltZUJvZHlQYXJ0KCk7CisJbWJwLnNldFRleHQoImZpcnN0IHBhcnQiKTsKKwltcC5hZGRCb2R5UGFydChtYnApOworCU1pbWVNZXNzYWdlIG0yID0gbmV3IE1pbWVNZXNzYWdlKHMpOworCW0yLnNldFN1YmplY3QoImV4YW1wbGUiKTsKKwltMi5zZXRUZXh0KCJtZXNzYWdlPVxuIik7CisJbWJwID0gbmV3IE1pbWVCb2R5UGFydCgpOworCW1icC5zZXRDb250ZW50KG0yLCAibWVzc2FnZS9yZmM4MjIiKTsKKwltYnAuc2V0SGVhZGVyKCJDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nIiwgInF1b3RlZC1wcmludGFibGUiKTsKKwltcC5hZGRCb2R5UGFydChtYnApOworCW0uc2V0Q29udGVudChtcCk7CisJbS5zZXRIZWFkZXIoIkNvbnRlbnQtVHJhbnNmZXItRW5jb2RpbmciLCAicXVvdGVkLXByaW50YWJsZSIpOworCisJbSA9IG5ldyBNaW1lTWVzc2FnZShtKTsJCS8vIGNvcHkgaXQKKwltcCA9IChNaW1lTXVsdGlwYXJ0KW0uZ2V0Q29udGVudCgpOworCisJQm9keVBhcnQgYnAgPSBtcC5nZXRCb2R5UGFydCgxKTsKKwltMiA9IChNaW1lTWVzc2FnZSlicC5nZXRDb250ZW50KCk7CisJYXNzZXJ0RXF1YWxzKCJtZXNzYWdlPVxuIiwgbTIuZ2V0Q29udGVudCgpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBNaW1lTWVzc2FnZSBjcmVhdGVNZXNzYWdlKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisgICAgICAgIFN0cmluZyBjb250ZW50ID0KKwkgICAgIk1pbWUtVmVyc2lvbjogMS4wXG4iICsKKwkgICAgIkNvbnRlbnQtVHlwZTogbXVsdGlwYXJ0L21peGVkOyBib3VuZGFyeT1cIj0zRFwiXG4iICsKKwkgICAgIkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IHF1b3RlZC1wcmludGFibGVcbiIgKworCSAgICAiXG4iICsKKwkgICAgIi0tPTNEXG4iICsKKwkgICAgIlxuIiArCisJICAgICJmaXJzdCBwYXJ0PVxuIiArCisJICAgICJcbiIgKworCSAgICAiLS09M0RcbiIgKworCSAgICAiQ29udGVudC1UeXBlOiBtZXNzYWdlL3JmYzgyMlxuIiArCisJICAgICJDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBxdW90ZWQtcHJpbnRhYmxlXG4iICsKKwkgICAgIlxuIiArCisJICAgICJTdWJqZWN0OiBleGFtcGxlXG4iICsKKwkgICAgIlxuIiArCisJICAgICJtZXNzYWdlPVxuIiArCisJICAgICJcbiIgKworCSAgICAiLS09M0QtLVxuIjsKKworCXJldHVybiBuZXcgTWltZU1lc3NhZ2UocywgbmV3IEFzY2lpU3RyaW5nSW5wdXRTdHJlYW0oY29udGVudCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L1dpbmRvd3NGaWxlTmFtZXMuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9qYXZheC9tYWlsL2ludGVybmV0L1dpbmRvd3NGaWxlTmFtZXMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iMTFjOTZiCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvaW50ZXJuZXQvV2luZG93c0ZpbGVOYW1lcy5qYXZhCkBAIC0wLDAgKzEsNDUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDksIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5pbnRlcm5ldDsKKworaW1wb3J0IG9yZy5qdW5pdC4qOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEVxdWFsczsKKworLyoqCisgKiBUZXN0IHRoYXQgdGhlICJtYWlsLm1pbWUud2luZG93c2ZpbGVuYW1lcyIgU3lzdGVtIHByb3BlcnR5CisgKiBjYXVzZXMgdGhlIGZpbGVuYW1lIHRvIGJlIHJldHVybmVkIHdpdGggYmFja3NsYXNoZXMgcHJlc2VydmVkLgorICovCitwdWJsaWMgY2xhc3MgV2luZG93c0ZpbGVOYW1lcyB7CisKKyAgICBAQmVmb3JlQ2xhc3MKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgYmVmb3JlKCkgeworCVN5c3RlbS5vdXQucHJpbnRsbigiV2luZG93c0ZpbGVOYW1lcyIpOworCVN5c3RlbS5zZXRQcm9wZXJ0eSgibWFpbC5taW1lLndpbmRvd3NmaWxlbmFtZXMiLCAidHJ1ZSIpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFByb3AoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlQYXJhbWV0ZXJMaXN0IHBsID0gbmV3IFBhcmFtZXRlckxpc3QoIjsgZmlsZW5hbWU9XCJcXGFcXGJcXGMudHh0XCIiKTsKKwlhc3NlcnRFcXVhbHMocGwuZ2V0KCJmaWxlbmFtZSIpLCAiXFxhXFxiXFxjLnR4dCIpOworICAgIH0KKworICAgIEBBZnRlckNsYXNzCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGFmdGVyKCkgeworCS8vIHNob3VsZCBiZSB1bm5lY2Vzc2FyeQorCVN5c3RlbS5jbGVhclByb3BlcnR5KCJtYWlsLm1pbWUud2luZG93c2ZpbGVuYW1lcyIpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvamF2YS9qYXZheC9tYWlsL3NlYXJjaC9TZWFyY2hUZXJtU2VyaWFsaXphdGlvblRlc3QuamF2YSBiL21haWwvc3JjL3Rlc3QvamF2YS9qYXZheC9tYWlsL3NlYXJjaC9TZWFyY2hUZXJtU2VyaWFsaXphdGlvblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wYzAzYzRiCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9qYXZhL2phdmF4L21haWwvc2VhcmNoL1NlYXJjaFRlcm1TZXJpYWxpemF0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsNzQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgamF2YXgubWFpbC5zZWFyY2g7CisKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CisKK2ltcG9ydCBqYXZheC5tYWlsLio7CitpbXBvcnQgamF2YXgubWFpbC5zZWFyY2guKjsKK2ltcG9ydCBqYXZheC5tYWlsLmludGVybmV0Lio7CisKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRFcXVhbHM7CisKKy8qKgorICogU2VhcmNoVGVybSBzZXJpYWxpemF0aW9uIHRlc3QuCisgKgorICogQGF1dGhvciBCaWxsIFNoYW5ub24KKyAqLworCitwdWJsaWMgY2xhc3MgU2VhcmNoVGVybVNlcmlhbGl6YXRpb25UZXN0IHsKKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFNlcmlhbGl6YXRpb24oKSB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworCS8vIGNvbnN0cnVjdCBhIFNlYXJjaFRlcm0gdXNpbmcgYWxsIFNlYXJjaFRlcm0gdHlwZXMKKwlTZWFyY2hUZXJtIHRlcm0gPSBuZXcgQW5kVGVybShuZXcgU2VhcmNoVGVybVtdIHsKKwkgICAgbmV3IEJvZHlUZXJtKCJ0ZXh0IiksCisJICAgIG5ldyBGbGFnVGVybShuZXcgRmxhZ3MoRmxhZ3MuRmxhZy5SRUNFTlQpLCB0cnVlKSwKKwkgICAgbmV3IEZyb21TdHJpbmdUZXJtKCJmb29AYmFyIiksCisJICAgIG5ldyBIZWFkZXJUZXJtKCJYLU1haWxlciIsICJkdG1haWwiKSwKKwkgICAgbmV3IE1lc3NhZ2VJRFRlcm0oIjEyMzQ1QHN1bi5jb20iKSwKKwkgICAgbmV3IE1lc3NhZ2VOdW1iZXJUZXJtKDQyKSwKKwkgICAgbmV3IE5vdFRlcm0oCisJCW5ldyBPclRlcm0oCisJCSAgICBuZXcgUmVjZWl2ZWREYXRlVGVybShSZWNlaXZlZERhdGVUZXJtLkxULCBuZXcgRGF0ZSgpKSwKKwkJICAgIG5ldyBSZWNpcGllbnRTdHJpbmdUZXJtKE1lc3NhZ2UuUmVjaXBpZW50VHlwZS5DQywgImZvbyIpCisJCSkKKwkgICAgKSwKKwkgICAgbmV3IFJlY2lwaWVudFRlcm0oTWltZU1lc3NhZ2UuUmVjaXBpZW50VHlwZS5ORVdTR1JPVVBTLAorCQkJCW5ldyBOZXdzQWRkcmVzcygiY29tcC5sYW5nLmphdmEiLCAibmV3c2hvc3QiKSksCisJICAgIG5ldyBTZW50RGF0ZVRlcm0oU2VudERhdGVUZXJtLk5FLCBuZXcgRGF0ZSgpKSwKKwkgICAgbmV3IFNpemVUZXJtKFNpemVUZXJtLkxULCAxMDAwKSwKKwkgICAgbmV3IFN1YmplY3RUZXJtKCJ0ZXN0IikKKwl9KTsKKworCS8vIHNlcmlhbGl6ZSBpdCB0byBhIGJ5dGUgYXJyYXkKKwlCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworCU9iamVjdE91dHB1dFN0cmVhbSBvb3MgPSBuZXcgT2JqZWN0T3V0cHV0U3RyZWFtKGJvcyk7CisJb29zLndyaXRlT2JqZWN0KHRlcm0pOworCWJvcy5jbG9zZSgpOworCisJLy8gcmVhZCBpdCBiYWNrIGluCisJQnl0ZUFycmF5SW5wdXRTdHJlYW0gYmlzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJvcy50b0J5dGVBcnJheSgpKTsKKwlPYmplY3RJbnB1dFN0cmVhbSBvaXMgPSBuZXcgT2JqZWN0SW5wdXRTdHJlYW0oYmlzKTsKKwlTZWFyY2hUZXJtIHRlcm0yID0gKFNlYXJjaFRlcm0pb2lzLnJlYWRPYmplY3QoKTsKKworCS8vIGNvbXBhcmUgaXQgd2l0aCB0aGUgb3JpZ2luYWwKKwlhc3NlcnRFcXVhbHModGVybSwgdGVybTIpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvcmVzb3VyY2VzL2NvbS9zdW4vbWFpbC9pbWFwL3Byb3RvY29sL3VpZGRhdGEgYi9tYWlsL3NyYy90ZXN0L3Jlc291cmNlcy9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC91aWRkYXRhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAwNmUwZmYKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy90ZXN0L3Jlc291cmNlcy9jb20vc3VuL21haWwvaW1hcC9wcm90b2NvbC91aWRkYXRhCkBAIC0wLDAgKzEsNzYgQEAKKyMKKyMgQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisjCisjIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorIyB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorIyBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisjCisjIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyMgTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorIyBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyMgdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyMgaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorIworIyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyMKKworIworIyBEYXRhIHRvIHRlc3QgVUlEU2V0LgorIworCitURVNUIG9uZSBVSUQKK0RBVEEgMQorRVhQRUNUIDEKKworVEVTVCB0d28gVUlEcworREFUQSAxLDMKK0VYUEVDVCAxIDMKKworVEVTVCBVSUQgcmFuZ2UKK0RBVEEgMToyCitFWFBFQ1QgMSAyCisKK1RFU1QgYmlnZ2VyIFVJRCByYW5nZQorREFUQSAxOjMKK0VYUEVDVCAxIDIgMworCitURVNUIHR3byByYW5nZXMKK0RBVEEgMTozLDU6NworRVhQRUNUIDEgMiAzIDUgNiA3CisKK1RFU1QgcmFuZ2VzIGFuZCBzaW5nbGVzCitEQVRBIDE6Myw1LDc6OQorRVhQRUNUIDEgMiAzIDUgNyA4IDkKKworVEVTVCBtYW55IHNpbmdsZXMKK0RBVEEgMSwzLDUsNyw5CitFWFBFQ1QgMSAzIDUgNyA5CisKK1RFU1QgbWF4CitEQVRBIDEKK01BWCAxCitFWFBFQ1QgMQorCitURVNUIG1heDIKK0RBVEEgMgorTUFYIDIKK0VYUEVDVCAyCisKK1RFU1QgbWF4MworREFUQSAxOjIKK01BWCAyCitFWFBFQ1QgMSAyCisKK1RFU1QgbWF4NAorREFUQSAxOjIKK01BWCAxIDEKK0VYUEVDVCAxCisKK1RFU1QgbWF4NQorREFUQSAxOjQKK01BWCAzIDE6MworRVhQRUNUIDEgMiAzCisKK1RFU1QgZW1wdHkKK0RBVEEgRU1QVFkKK0VYUEVDVCBFTVBUWQpkaWZmIC0tZ2l0IGEvbWFpbC9zcmMvdGVzdC9yZXNvdXJjZXMvY29tL3N1bi9tYWlsL3V0aWwvdXVkYXRhIGIvbWFpbC9zcmMvdGVzdC9yZXNvdXJjZXMvY29tL3N1bi9tYWlsL3V0aWwvdXVkYXRhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU2ZDI5ZGUKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy90ZXN0L3Jlc291cmNlcy9jb20vc3VuL21haWwvdXRpbC91dWRhdGEKQEAgLTAsMCArMSwxOTcgQEAKKyMKKyMgQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisjCisjIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorIyB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorIyBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisjCisjIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyMgTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorIyBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyMgdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyMgaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorIworIyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyMKKworIworIyBEYXRhIHRvIHRlc3QgdXVkZWNvZGVyLgorIworIyBNb3N0bHkgdGVzdHMgZXJyb3IgY2FzZXMgYW5kIGFiaWxpdHkgdG8gaWdub3JlIGVycm9ycy4KKyMKKworVEVTVCBhIHNpbXBsZSBkZWNvZGUgdGVzdAorREFUQQorYmVnaW4gNjQ0IGVuY29kZXIuYnVmCitNPSZBSTxSIUk8UiFBKCc5RTxHREA9RjVSPjIhVjk3KVkoJzlFPEdEQD1GNVI+MiFMO1ZZRygmUUk7RjRACis0PSZcQD0mNVM9IiFUOiY0QDkmNUM7VjFFPEBIIQorIAorZW5kCitFWFBFQ1QKK3RoaXMgaXMgYSB2ZXJ5IHZlcnkgdmVyeSB2ZXJ5IHZlcnkgbG9uZyBsaW5lIHRvIHRlc3QgdGhlIGRlY29kZXIKK0VORAorCitURVNUIG5vIGJlZ2luCitEQVRBCitNPSZBSTxSIUk8UiFBKCc5RTxHREA9RjVSPjIhVjk3KVkoJzlFPEdEQD1GNVI+MiFMO1ZZRygmUUk7RjRACis0PSZcQD0mNVM9IiFUOiY0QDkmNUM7VjFFPEBIIQorIAorZW5kCitFWFBFQ1QKK0VYQ0VQVElPTiBjb20uc3VuLm1haWwudXRpbC5EZWNvZGluZ0V4Y2VwdGlvbgorRU5ECisKK1RFU1Qgbm8gZW5kCitEQVRBCitiZWdpbiA2NDQgZW5jb2Rlci5idWYKK009JkFJPFIhSTxSIUEoJzlFPEdEQD1GNVI+MiFWOTcpWSgnOUU8R0RAPUY1Uj4yIUw7VllHKCZRSTtGNEAKKzQ9JlxAPSY1Uz0iIVQ6JjRAOSY1QztWMUU8QEghCisgCitFWFBFQ1QKK0VYQ0VQVElPTiBjb20uc3VuLm1haWwudXRpbC5EZWNvZGluZ0V4Y2VwdGlvbgorRU5ECisKK1RFU1Qgbm8gZW5kLCBubyBlbXB0eSBsaW5lCitEQVRBCitiZWdpbiA2NDQgZW5jb2Rlci5idWYKK009JkFJPFIhSTxSIUEoJzlFPEdEQD1GNVI+MiFWOTcpWSgnOUU8R0RAPUY1Uj4yIUw7VllHKCZRSTtGNEAKKzQ9JlxAPSY1Uz0iIVQ6JjRAOSY1QztWMUU8QEghCitFWFBFQ1QKK0VYQ0VQVElPTiBjb20uc3VuLm1haWwudXRpbC5EZWNvZGluZ0V4Y2VwdGlvbgorRU5ECisKK1RFU1Qgbm8gYmVnaW4sIGlnbm9yZSBlcnJvcnMKK0RBVEEgaWdub3JlTWlzc2luZ0JlZ2luRW5kCitNPSZBSTxSIUk8UiFBKCc5RTxHREA9RjVSPjIhVjk3KVkoJzlFPEdEQD1GNVI+MiFMO1ZZRygmUUk7RjRACis0PSZcQD0mNVM9IiFUOiY0QDkmNUM7VjFFPEBIIQorIAorZW5kCitFWFBFQ1QKK3RoaXMgaXMgYSB2ZXJ5IHZlcnkgdmVyeSB2ZXJ5IHZlcnkgbG9uZyBsaW5lIHRvIHRlc3QgdGhlIGRlY29kZXIKK0VORAorCitURVNUIG5vIGVuZCwgaWdub3JlIGVycm9ycworREFUQSBpZ25vcmVNaXNzaW5nQmVnaW5FbmQKK2JlZ2luIDY0NCBlbmNvZGVyLmJ1ZgorTT0mQUk8UiFJPFIhQSgnOUU8R0RAPUY1Uj4yIVY5NylZKCc5RTxHREA9RjVSPjIhTDtWWUcoJlFJO0Y0QAorND0mXEA9JjVTPSIhVDomNEA5JjVDO1YxRTxASCEKKyAKK0VYUEVDVAordGhpcyBpcyBhIHZlcnkgdmVyeSB2ZXJ5IHZlcnkgdmVyeSBsb25nIGxpbmUgdG8gdGVzdCB0aGUgZGVjb2RlcgorRU5ECisKK1RFU1Qgbm8gYmVnaW4sIG5vIGVuZCwgaWdub3JlIGVycm9ycworREFUQSBpZ25vcmVNaXNzaW5nQmVnaW5FbmQKK009JkFJPFIhSTxSIUEoJzlFPEdEQD1GNVI+MiFWOTcpWSgnOUU8R0RAPUY1Uj4yIUw7VllHKCZRSTtGNEAKKzQ9JlxAPSY1Uz0iIVQ6JjRAOSY1QztWMUU8QEghCitFWFBFQ1QKK3RoaXMgaXMgYSB2ZXJ5IHZlcnkgdmVyeSB2ZXJ5IHZlcnkgbG9uZyBsaW5lIHRvIHRlc3QgdGhlIGRlY29kZXIKK0VORAorCitURVNUIGVtcHR5IGxpbmUsIGlnbm9yZSBlcnJvcnMKK0RBVEEgaWdub3JlTWlzc2luZ0JlZ2luRW5kCisKK2JlZ2luIDY0NCBlbmNvZGVyLmJ1ZgorTT0mQUk8UiFJPFIhQSgnOUU8R0RAPUY1Uj4yIVY5NylZKCc5RTxHREA9RjVSPjIhTDtWWUcoJlFJO0Y0QAorND0mXEA9JjVTPSIhVDomNEA5JjVDO1YxRTxASCEKK0VYUEVDVAordGhpcyBpcyBhIHZlcnkgdmVyeSB2ZXJ5IHZlcnkgdmVyeSBsb25nIGxpbmUgdG8gdGVzdCB0aGUgZGVjb2RlcgorRU5ECisKK1RFU1QgZW1wdHkgbGluZSwgbm8gYmVnaW4sIGlnbm9yZSBlcnJvcnMKK0RBVEEgaWdub3JlTWlzc2luZ0JlZ2luRW5kCisKK009JkFJPFIhSTxSIUEoJzlFPEdEQD1GNVI+MiFWOTcpWSgnOUU8R0RAPUY1Uj4yIUw7VllHKCZRSTtGNEAKKzQ9JlxAPSY1Uz0iIVQ6JjRAOSY1QztWMUU8QEghCitFWFBFQ1QKK3RoaXMgaXMgYSB2ZXJ5IHZlcnkgdmVyeSB2ZXJ5IHZlcnkgbG9uZyBsaW5lIHRvIHRlc3QgdGhlIGRlY29kZXIKK0VORAorCitURVNUIGJhZCBtb2RlCitEQVRBCitiZWdpbiB4eHggZW5jb2Rlci5idWYKK009JkFJPFIhSTxSIUEoJzlFPEdEQD1GNVI+MiFWOTcpWSgnOUU8R0RAPUY1Uj4yIUw7VllHKCZRSTtGNEAKKzQ9JlxAPSY1Uz0iIVQ6JjRAOSY1QztWMUU8QEghCisgCitlbmQKK0VYUEVDVAorRVhDRVBUSU9OIGNvbS5zdW4ubWFpbC51dGlsLkRlY29kaW5nRXhjZXB0aW9uCitFTkQKKworVEVTVCBiYWQgbW9kZSwgaWdub3JlIGVycm9ycworREFUQSBpZ25vcmVFcnJvcnMKK2JlZ2luIHh4eCBlbmNvZGVyLmJ1ZgorTT0mQUk8UiFJPFIhQSgnOUU8R0RAPUY1Uj4yIVY5NylZKCc5RTxHREA9RjVSPjIhTDtWWUcoJlFJO0Y0QAorND0mXEA9JjVTPSIhVDomNEA5JjVDO1YxRTxASCEKKyAKK2VuZAorRVhQRUNUCit0aGlzIGlzIGEgdmVyeSB2ZXJ5IHZlcnkgdmVyeSB2ZXJ5IGxvbmcgbGluZSB0byB0ZXN0IHRoZSBkZWNvZGVyCitFTkQKKworVEVTVCBiYWQgZmlsZW5hbWUKK0RBVEEKK2JlZ2luIDY0NAorTT0mQUk8UiFJPFIhQSgnOUU8R0RAPUY1Uj4yIVY5NylZKCc5RTxHREA9RjVSPjIhTDtWWUcoJlFJO0Y0QAorND0mXEA9JjVTPSIhVDomNEA5JjVDO1YxRTxASCEKKyAKK2VuZAorRVhQRUNUCitFWENFUFRJT04gY29tLnN1bi5tYWlsLnV0aWwuRGVjb2RpbmdFeGNlcHRpb24KK0VORAorCitURVNUIGJhZCBmaWxlbmFtZSwgaWdub3JlIGVycm9ycworREFUQSBpZ25vcmVFcnJvcnMKK2JlZ2luIDY0NAorTT0mQUk8UiFJPFIhQSgnOUU8R0RAPUY1Uj4yIVY5NylZKCc5RTxHREA9RjVSPjIhTDtWWUcoJlFJO0Y0QAorND0mXEA9JjVTPSIhVDomNEA5JjVDO1YxRTxASCEKKyAKK2VuZAorRVhQRUNUCit0aGlzIGlzIGEgdmVyeSB2ZXJ5IHZlcnkgdmVyeSB2ZXJ5IGxvbmcgbGluZSB0byB0ZXN0IHRoZSBkZWNvZGVyCitFTkQKKworVEVTVCBnYXJiYWdlIGRhdGEKK0RBVEEKK2JlZ2luIDY0NCBlbmNvZGVyLmJ1ZgorWFhYCitNPSZBSTxSIUk8UiFBKCc5RTxHREA9RjVSPjIhVjk3KVkoJzlFPEdEQD1GNVI+MiFMO1ZZRygmUUk7RjRACis0PSZcQD0mNVM9IiFUOiY0QDkmNUM7VjFFPEBIIQorIAorZW5kCitFWFBFQ1QKK0VYQ0VQVElPTiBjb20uc3VuLm1haWwudXRpbC5EZWNvZGluZ0V4Y2VwdGlvbgorRU5ECisKK1RFU1QgZ2FyYmFnZSBkYXRhICh0YWIpCitEQVRBCitiZWdpbiA2NDQgZW5jb2Rlci5idWYKKwkKK009JkFJPFIhSTxSIUEoJzlFPEdEQD1GNVI+MiFWOTcpWSgnOUU8R0RAPUY1Uj4yIUw7VllHKCZRSTtGNEAKKzQ9JlxAPSY1Uz0iIVQ6JjRAOSY1QztWMUU8QEghCisgCitlbmQKK0VYUEVDVAorRVhDRVBUSU9OIGNvbS5zdW4ubWFpbC51dGlsLkRlY29kaW5nRXhjZXB0aW9uCitFTkQKKworVEVTVCBnYXJiYWdlIGRhdGEsIGlnbm9yZSBlcnJvcnMKK0RBVEEgaWdub3JlRXJyb3JzCitiZWdpbiA2NDQgZW5jb2Rlci5idWYKK1hYWAorTT0mQUk8UiFJPFIhQSgnOUU8R0RAPUY1Uj4yIVY5NylZKCc5RTxHREA9RjVSPjIhTDtWWUcoJlFJO0Y0QAorND0mXEA9JjVTPSIhVDomNEA5JjVDO1YxRTxASCEKKyAKK2VuZAorRVhQRUNUCit0aGlzIGlzIGEgdmVyeSB2ZXJ5IHZlcnkgdmVyeSB2ZXJ5IGxvbmcgbGluZSB0byB0ZXN0IHRoZSBkZWNvZGVyCitFTkQKKworVEVTVCBpZ25vcmUgYm90aCBraW5kcyBvZiBlcnJvcnMKK0RBVEEgaWdub3JlRXJyb3JzIGlnbm9yZU1pc3NpbmdCZWdpbkVuZAorWFhYCitNPSZBSTxSIUk8UiFBKCc5RTxHREA9RjVSPjIhVjk3KVkoJzlFPEdEQD1GNVI+MiFMO1ZZRygmUUk7RjRACis0PSZcQD0mNVM9IiFUOiY0QDkmNUM7VjFFPEBIIQorRVhQRUNUCit0aGlzIGlzIGEgdmVyeSB2ZXJ5IHZlcnkgdmVyeSB2ZXJ5IGxvbmcgbGluZSB0byB0ZXN0IHRoZSBkZWNvZGVyCitFTkQKZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvcmVzb3VyY2VzL2phdmF4L21haWwvaW50ZXJuZXQvTWFpbERhdGVGb3JtYXRfbmV3LnNlciBiL21haWwvc3JjL3Rlc3QvcmVzb3VyY2VzL2phdmF4L21haWwvaW50ZXJuZXQvTWFpbERhdGVGb3JtYXRfbmV3LnNlcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYjMxMDI3Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9yZXNvdXJjZXMvamF2YXgvbWFpbC9pbnRlcm5ldC9NYWlsRGF0ZUZvcm1hdF9uZXcuc2VyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvcmVzb3VyY2VzL2phdmF4L21haWwvaW50ZXJuZXQvTWFpbERhdGVGb3JtYXRfb2xkLnNlciBiL21haWwvc3JjL3Rlc3QvcmVzb3VyY2VzL2phdmF4L21haWwvaW50ZXJuZXQvTWFpbERhdGVGb3JtYXRfb2xkLnNlcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40YzMzYjliCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9yZXNvdXJjZXMvamF2YXgvbWFpbC9pbnRlcm5ldC9NYWlsRGF0ZUZvcm1hdF9vbGQuc2VyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvcmVzb3VyY2VzL2phdmF4L21haWwvaW50ZXJuZXQvYWRkcmZvbGRkYXRhIGIvbWFpbC9zcmMvdGVzdC9yZXNvdXJjZXMvamF2YXgvbWFpbC9pbnRlcm5ldC9hZGRyZm9sZGRhdGEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTFjMGY0OAotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvcmVzb3VyY2VzL2phdmF4L21haWwvaW50ZXJuZXQvYWRkcmZvbGRkYXRhCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvcmVzb3VyY2VzL2phdmF4L21haWwvaW50ZXJuZXQvYWRkcmxpc3QgYi9tYWlsL3NyYy90ZXN0L3Jlc291cmNlcy9qYXZheC9tYWlsL2ludGVybmV0L2FkZHJsaXN0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIxODQ1YTQKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy90ZXN0L3Jlc291cmNlcy9qYXZheC9tYWlsL2ludGVybmV0L2FkZHJsaXN0CkBAIC0wLDAgKzEsNzczIEBACitDb21tZW50OgorCisgICAgQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisKKyAgICBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAgICB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKworICAgIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAgICBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgICAgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgICAgdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisKKyAgICBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKworQ29tbWVudDoKKworCUEgc2V0IG9mIHRlc3QgYWRkcmVzc2VzIHN0b2xlbiBmcm9tIHRoZSBkdG1haWwgdGVzdCBzdWl0ZSwKKwl3aXRoIGEgZmV3IG9mIG15IG93bi4KKwlVc2Ugd2l0aCAiYWRkcnRlc3QgLXAgPGFkZHJsaXN0Ii4KKworCWdyZXAgZm9yICJFeHBlY3RlZDoiIGluIG91dHB1dCB0byBmaW5kIGVycm9ycworCisJQ0FSRUZVTDogYSBibGFuayBsaW5lIGluIHRoaXMgZmlsZSBjYXVzZXMgZXZlcnl0aGluZyBmb2xsb3dpbmcgaXQKKwkJIHRvIGJlIGlnbm9yZWQgdW50aWwgYSBsaW5lIHN0YXJ0aW5nIHdpdGggIkZyb20gIiAoc28gdGhhdAorCQkgYWRkcnRlc3QgLXAgY2FuIGJlIHBvaW50ZWQgYXQgYSByZWFsIG1haWxib3gpLgorCitGcm9tIHN0YXJ0IGhlcmUKK1N0cmljdDogZmFsc2UKK0NvbW1lbnQ6CisJVGhpcyBmaXJzdCBzZXQgb2YgYWRkcmVzc2VzIGFyZSBhbGwgZ29vZC4KK1RvOiBnZ2VyZQorRXhwZWN0OiAxCisJZ2dlcmUKK1RvOiAvdG1wL21haWwub3V0CitFeHBlY3Q6IDEKKwkvdG1wL21haWwub3V0CitUbzogK21haWxib3gKK0V4cGVjdDogMQorCSttYWlsYm94CitUbzogfnVzZXIvbWFpbGJveAorRXhwZWN0OiAxCisJfnVzZXIvbWFpbGJveAorVG86IH4vbWFpbGJveAorRXhwZWN0OiAxCisJfi9tYWlsYm94CitUbzogL1BOPXg0MDAuYWRkcmVzcy9QUk1EPWlibW1haWwvQURNRD1pYm14NDAwL0M9dXMvQG1ocy1tY2kuZWJheQorRXhwZWN0OiAxCisJL1BOPXg0MDAuYWRkcmVzcy9QUk1EPWlibW1haWwvQURNRD1pYm14NDAwL0M9dXMvQG1ocy1tY2kuZWJheQorVG86IGdnZXJlLCAvdG1wL21haWwub3V0LCArbWFpbGJveCwgfnVzZXIvbWFpbGJveCwgfi9tYWlsYm94LCAvUE49eDQwMC5hZGRyZXNzL1BSTUQ9aWJtbWFpbC9BRE1EPWlibXg0MDAvQz11cy9AbWhzLW1jaS5lYmF5CitFeHBlY3Q6IDYKKwlnZ2VyZQorCS90bXAvbWFpbC5vdXQKKwkrbWFpbGJveAorCX51c2VyL21haWxib3gKKwl+L21haWxib3gKKwkvUE49eDQwMC5hZGRyZXNzL1BSTUQ9aWJtbWFpbC9BRE1EPWlibXg0MDAvQz11cy9AbWhzLW1jaS5lYmF5CitUbzogZ2dlcmUgL3RtcC9tYWlsLm91dCArbWFpbGJveCB+dXNlci9tYWlsYm94IH4vbWFpbGJveCAvUE49eDQwMC5hZGRyZXNzL1BSTUQ9aWJtbWFpbC9BRE1EPWlibXg0MDAvQz11cy9AbWhzLW1jaS5lYmF5CitFeHBlY3Q6IDYKKwlnZ2VyZQorCS90bXAvbWFpbC5vdXQKKwkrbWFpbGJveAorCX51c2VyL21haWxib3gKKwl+L21haWxib3gKKwkvUE49eDQwMC5hZGRyZXNzL1BSTUQ9aWJtbWFpbC9BRE1EPWlibXg0MDAvQz11cy9AbWhzLW1jaS5lYmF5CitUbzogKHgpPHlAYT4oeikKK0V4cGVjdDogMQorCXlAYQorQ29tbWVudDogYXMgYWJvdmUsIGJ1dCBzdHJpY3QKK1N0cmljdDogdHJ1ZQorVG86IGdnZXJlIC90bXAvbWFpbC5vdXQgK21haWxib3ggfnVzZXIvbWFpbGJveCB+L21haWxib3ggL1BOPXg0MDAuYWRkcmVzcy9QUk1EPWlibW1haWwvQURNRD1pYm14NDAwL0M9dXMvQG1ocy1tY2kuZWJheQorRXhwZWN0OiBFeGNlcHRpb24gamF2YXgubWFpbC5pbnRlcm5ldC5BZGRyZXNzRXhjZXB0aW9uOiBMb2NhbCBhZGRyZXNzIGNvbnRhaW5zIGNvbnRyb2wgb3Igd2hpdGVzcGFjZSBpbiBzdHJpbmcgYGBnZ2VyZSAvdG1wL21haWwub3V0ICttYWlsYm94IH51c2VyL21haWxib3ggfi9tYWlsYm94IC9QTj14NDAwLmFkZHJlc3MvUFJNRD1pYm1tYWlsL0FETUQ9aWJteDQwMC9DPXVzL0BtaHMtbWNpLmViYXknJworU3RyaWN0OiBmYWxzZQorVG86IE1hZCBHZW5pdXMgPGdlb3JnZUBib29sZT4KK0V4cGVjdDogMQorCWdlb3JnZUBib29sZQorVG86ICJDJ2VzdCBiaWVuIG1vY2hlIiA8cGFyaXNAZnJhbmNlPgorRXhwZWN0OiAxCisJcGFyaXNAZnJhbmNlCitUbzogImtub3csIGFueSwgZmFtb3VzIiA8ZnJlbmNoQHBoeXNpY2lzdHM+CitFeHBlY3Q6IDEKKwlmcmVuY2hAcGh5c2ljaXN0cworVG86IGxhYm9yaW91cyAoQnV0IEJ1ZyBGcmVlKQorRXhwZWN0OiAxCisJbGFib3Jpb3VzCitUbzogY29uZnVzZWQgKGFib3V0LCBiZWluZywgZnJlbmNoKQorRXhwZWN0OiAxCisJY29uZnVzZWQKK1RvOiBpdCAodGFrZXMsIG5vICh0aW1lLCBhdCkgYWxsKQorRXhwZWN0OiAxCisJaXQKK1RvOiB0d29Ad2Vla3MgKEl0IFdpbGwgVGFrZSkKK0V4cGVjdDogMQorCXR3b0B3ZWVrcworVG86IGl0QGlzIChicmlsbGlhbnQgKGdlbml1cywgYW5kKSBzdXBlcmIpCitFeHBlY3Q6IDEKKwlpdEBpcworVG86IGlmQHlvdSAoY291bGQsIHNlZSAoYWxtb3N0LCBhcywgKGJhZGx5LCB5b3UpIHdvdWxkKSBhZ3JlZSkKK0V4cGVjdDogMQorCWlmQHlvdQorVG86IGNhbm5vdEB3YXN0ZSAoTXksIEludGVsbGVjdHVhbCwgQ3ljbGVzKQorRXhwZWN0OiAxCisJY2Fubm90QHdhc3RlCitUbzogdXNlcnM6Z2V0LHdoYXQsdGhleSxkZXNlcnZlOworRXhwZWN0OiAxCisJdXNlcnM6Z2V0LHdoYXQsdGhleSxkZXNlcnZlOworVG86ICJDJ2VzdCBiaWVuIG1vY2hlIiA8cGFyaXNAZnJhbmNlPiwgTWFkIEdlbml1cyA8Z2VvcmdlQGJvb2xlPiwgdHdvQHdlZWtzIChJdCBXaWxsIFRha2UpLCAvdG1wL21haWwub3V0LCBsYWJvcmlvdXMgKEJ1dCBCdWcgRnJlZSksIGNhbm5vdEB3YXN0ZSAoTXksIEludGVsbGVjdHVhbCwgQ3ljbGVzKSwgdXNlcnM6Z2V0LHdoYXQsdGhleSxkZXNlcnZlOywgaXQgKHRha2VzLCBubyAodGltZSwgYXQpIGFsbCksIGlmQHlvdSAoY291bGQsIHNlZSAoYWxtb3N0LCBhcywgKGJhZGx5LCB5b3UpIHdvdWxkKSBhZ3JlZSksICJrbm93LCBhbnksIGZhbW91cyIgPEZyZW5jaEBwaHlzaWNpc3RzPiwgaXRAaXMgKGJyaWxsaWFudCAoZ2VuaXVzLCBhbmQpIHN1cGVyYiksIGNvbmZ1c2VkIChhYm91dCwgYmVpbmcsIGZyZW5jaCkKK0V4cGVjdDogMTIKKwlwYXJpc0BmcmFuY2UKKwlnZW9yZ2VAYm9vbGUKKwl0d29Ad2Vla3MKKwkvdG1wL21haWwub3V0CisJbGFib3Jpb3VzCisJY2Fubm90QHdhc3RlCisJdXNlcnM6Z2V0LHdoYXQsdGhleSxkZXNlcnZlOworCWl0CisJaWZAeW91CisJRnJlbmNoQHBoeXNpY2lzdHMKKwlpdEBpcworCWNvbmZ1c2VkCitUbzogZ2dlcmUsIC90bXAvbWFpbC5vdXQsICttYWlsYm94LCB+dXNlci9tYWlsYm94LCB+L21haWxib3gsIC9QTj14NDAwLmFkZHJlc3MvUFJNRD1pYm1tYWlsL0FETUQ9aWJteDQwMC9DPXVzL0BtaHMtbWNpLmViYXksICJDJ2VzdCBiaWVuIG1vY2hlIiA8cGFyaXNAZnJhbmNlPiwgTWFkIEdlbml1cyA8Z2VvcmdlQGJvb2xlPiwgdHdvQHdlZWtzIChJdCBXaWxsIFRha2UpLCAvdG1wL21haWwub3V0LCBsYWJvcmlvdXMgKEJ1dCBCdWcgRnJlZSksIGNhbm5vdEB3YXN0ZSAoTXksIEludGVsbGVjdHVhbCwgQ3ljbGVzKSwgdXNlcnM6Z2V0LHdoYXQsdGhleSxkZXNlcnZlOywgaXQgKHRha2VzLCBubyAodGltZSwgYXQpIGFsbCksIGlmQHlvdSAoY291bGQsIHNlZSAoYWxtb3N0LCBhcywgKGJhZGx5LCB5b3UpIHdvdWxkKSBhZ3JlZSksICJrbm93LCBhbnksIGZhbW91cyIgPEZyZW5jaEBwaHlzaWNpc3RzPiwgaXRAaXMgKGJyaWxsaWFudCAoZ2VuaXVzLCBhbmQpIHN1cGVyYiksIGNvbmZ1c2VkIChhYm91dCwgYmVpbmcsIGZyZW5jaCkKK0V4cGVjdDogMTgKKwlnZ2VyZQorCS90bXAvbWFpbC5vdXQKKwkrbWFpbGJveAorCX51c2VyL21haWxib3gKKwl+L21haWxib3gKKwkvUE49eDQwMC5hZGRyZXNzL1BSTUQ9aWJtbWFpbC9BRE1EPWlibXg0MDAvQz11cy9AbWhzLW1jaS5lYmF5CisJcGFyaXNAZnJhbmNlCisJZ2VvcmdlQGJvb2xlCisJdHdvQHdlZWtzCisJL3RtcC9tYWlsLm91dAorCWxhYm9yaW91cworCWNhbm5vdEB3YXN0ZQorCXVzZXJzOmdldCx3aGF0LHRoZXksZGVzZXJ2ZTsKKwlpdAorCWlmQHlvdQorCUZyZW5jaEBwaHlzaWNpc3RzCisJaXRAaXMKKwljb25mdXNlZAorVG86IHRlc3RhIHRlc3RiIHRlc3RjIC90bXAvbWFpbC5vdXQgfmdnZXJlL21haWwub3V0IHRlc3RkIHRlc3RlCitFeHBlY3Q6IDcKKwl0ZXN0YQorCXRlc3RiCisJdGVzdGMKKwkvdG1wL21haWwub3V0CisJfmdnZXJlL21haWwub3V0CisJdGVzdGQKKwl0ZXN0ZQorQ29tbWVudDogYXMgYWJvdmUsIGJ1dCBzdHJpY3QKK1N0cmljdDogdHJ1ZQorVG86IHRlc3RhIHRlc3RiIHRlc3RjIC90bXAvbWFpbC5vdXQgfmdnZXJlL21haWwub3V0IHRlc3RkIHRlc3RlCitFeHBlY3Q6IEV4Y2VwdGlvbiBqYXZheC5tYWlsLmludGVybmV0LkFkZHJlc3NFeGNlcHRpb246IExvY2FsIGFkZHJlc3MgY29udGFpbnMgY29udHJvbCBvciB3aGl0ZXNwYWNlIGluIHN0cmluZyBgYHRlc3RhIHRlc3RiIHRlc3RjIC90bXAvbWFpbC5vdXQgfmdnZXJlL21haWwub3V0IHRlc3RkIHRlc3RlJycKK1N0cmljdDogZmFsc2UKK1RvOiB0ZXN0YSwgdGVzdGIgLCB0ZXN0YyAvdG1wL21haWwub3V0ICx+Z2dlcmUvbWFpbC5vdXQsICx0ZXN0ZCx0ZXN0ZSwsLAorRXhwZWN0OiA3CisJdGVzdGEKKwl0ZXN0YgorCXRlc3RjCisJL3RtcC9tYWlsLm91dAorCX5nZ2VyZS9tYWlsLm91dAorCXRlc3RkCisJdGVzdGUKK0NvbW1lbnQ6IGFzIGFib3ZlLCBidXQgc3RyaWN0CitTdHJpY3Q6IHRydWUKK1RvOiB0ZXN0YSwgdGVzdGIgLCB0ZXN0YyAvdG1wL21haWwub3V0ICx+Z2dlcmUvbWFpbC5vdXQsICx0ZXN0ZCx0ZXN0ZSwsLAorRXhwZWN0OiBFeGNlcHRpb24gamF2YXgubWFpbC5pbnRlcm5ldC5BZGRyZXNzRXhjZXB0aW9uOiBMb2NhbCBhZGRyZXNzIGNvbnRhaW5zIGNvbnRyb2wgb3Igd2hpdGVzcGFjZSBpbiBzdHJpbmcgYGB0ZXN0YSB0ZXN0YiB0ZXN0YyAvdG1wL21haWwub3V0IH5nZ2VyZS9tYWlsLm91dCB0ZXN0ZCB0ZXN0ZScnCitTdHJpY3Q6IGZhbHNlCitUbzogdGVzdGEgdGVzdGIgPHRlc3RjQHRlc3RkPgorRXhwZWN0OiAxCisJdGVzdGNAdGVzdGQKK1RvOiBBZGFtIFMgTW9za293aXR6IDxhZGFtbUBvbmlvbi5pbnNldC5jb20+LAorICAgICAgICBBbmRyZXcgR29sbGFuIDxhZGpnQHNvZnR3YXkuc3cuT1ouQVU+LAorICAgICAgICBCcmV0IEFudGhvbnkgTWFycXVpcyA8YmFtQHRyb3V0Lm5vc2MuTUlMPiwKKyAgICAgICAgQmlsbCBTaGFubm9uIDxzaGFubm9uQFN1bi5DT00+LCBCb2IgR3JheSA8cmdyYXlAVXNXZXN0LkNPTT4sCisgICAgICAgIEJyaWFuIEVsbGlzIDxicmlAQm91bGRlci5Db2xvcmFkby5FRFU+LAorICAgICAgICBEb24gQ29sZW1hbiA8Y29sZW1hbkBsZWdhdG8uQ09NPiwKKyAgICAgICAgRGVubmlzIFJpdGNoaWUgPGRtckByZXNlYXJjaC5BVFQuQ09NPiwgRXZpIE5lbWV0aCA8ZXZpQENvbG9yYWRvLkVEVT4sCisgICAgICAgIExvcmkgR3JvYiA8Z3JvYkBjaG9ydXMuRlI+LCBQYXVsYSBIYXd0aG9ybiA8aGF3dGhvcm5ASFBMLkhQLkNPTT4sCisgICAgICAgIEFuZHJldyBIdW1lIDxhbmRyZXdAcmVzZWFyY2guQVRULkNPTT4sCisgICAgICAgIEphYXAgQWtrZXJodWlzIDxqYWFwQHJlc2VhcmNoLkFUVC5DT00+LAorICAgICAgICBKaW0gUiBPbGRyb3lkIDxqckBvbmlvbi5pbnNldC5jb20+LAorICAgICAgICBKb2huIFF1YXJ0ZXJtYW4gPGpzcUBsb25nd2F5LlRJQy5DT00+LAorICAgICAgICBKdWR5IERlc0hhcm5haXMgPGp1ZHlAVVNFTklYLk9SRz4sIEthcmVuIFNoYW5ub24gPGthc0BFbmc+LAorICAgICAgICBLZW4gTWNEb25lbGwgPGtlbmpAUHlyYW1pZC5DT00+LAorICAgICAgICBSb2IgS29sc3RhZCA8a29sc3RhZEBybXRjLkNlbnRyYWwuU3VuLkNPTT4sCisgICAgICAgIFBhdWwgS29vcm9zIDxrb29yb3NAdGlnZ2VyLmNzLkNvbG9yYWRvLkVEVT4sCisgICAgICAgIFJvYmVydCBFbHogPGtyZUBNdW5uYXJpLk9aLkFVPiwKKyAgICAgICAgTWlyaWFtIEFtb3MgTmloYXJ0IDxtaXJpYW1AZGVjd2V0LmVuZXQuREVDLkNPTT4sCisgICAgICAgICJNaWtlIE8nRGVsbCIgPG1vQGdpem1vLkJlbGxjb3JlLkNPTT4sCisgICAgICAgIFNoYXJvbiBNdXJyZWwgPGVvd3luQHJlc2VhcmNoLkFUVC5DT00+LAorICAgICAgICBQZWcgU2NoYWZlciA8cGVnQG1lZGlhLWxhYi5tZWRpYS5NSVQuRURVPiwgUGV0ZXIgU2FsdXMgPHBldGVyQFNVRy5PUkc+LAorICAgICAgICBCaWxsIFNoYW5ub24gPHNoYW5ub25AU3VuLkNPTT4sIFN0dSBGZWxkbWFuIDxzaWZAQmVsbGNvcmUuQ09NPiwKKyAgICAgICAgU3RlcGhlbiBXaWxsaWFtcyA8c3RldmV3QG5ldGJvc3MxLnRyZy5zYWljLmNvbT4sCisgICAgICAgIFRldXMgSGFnZW4gPHRldXNAb2NlLk5MPiwgVHJlbnQgSGVpbiA8dHJlbnRAeG9yLkNPTT4sCisgICAgICAgIFRob21hcyBBbGFuIFdvb2QgPHR3b29kQGNhcG1rdC5DT00+LAorICAgICAgICBNaWNoYWVsIFViZWxsIDwibXR0YW06OnViZWxsIkBTRkJheS5FTmV0LkRFQy5DT00+LAorICAgICAgICBNYXJ0aGEgWmltZXQgPHppbWV0QENvcnA+CitFeHBlY3Q6IDM0CisJYWRhbW1Ab25pb24uaW5zZXQuY29tCisJYWRqZ0Bzb2Z0d2F5LnN3Lk9aLkFVCisJYmFtQHRyb3V0Lm5vc2MuTUlMCisJc2hhbm5vbkBTdW4uQ09NCisJcmdyYXlAVXNXZXN0LkNPTQorCWJyaUBCb3VsZGVyLkNvbG9yYWRvLkVEVQorCWNvbGVtYW5AbGVnYXRvLkNPTQorCWRtckByZXNlYXJjaC5BVFQuQ09NCisJZXZpQENvbG9yYWRvLkVEVQorCWdyb2JAY2hvcnVzLkZSCisJaGF3dGhvcm5ASFBMLkhQLkNPTQorCWFuZHJld0ByZXNlYXJjaC5BVFQuQ09NCisJamFhcEByZXNlYXJjaC5BVFQuQ09NCisJanJAb25pb24uaW5zZXQuY29tCisJanNxQGxvbmd3YXkuVElDLkNPTQorCWp1ZHlAVVNFTklYLk9SRworCWthc0BFbmcKKwlrZW5qQFB5cmFtaWQuQ09NCisJa29sc3RhZEBybXRjLkNlbnRyYWwuU3VuLkNPTQorCWtvb3Jvc0B0aWdnZXIuY3MuQ29sb3JhZG8uRURVCisJa3JlQE11bm5hcmkuT1ouQVUKKwltaXJpYW1AZGVjd2V0LmVuZXQuREVDLkNPTQorCW1vQGdpem1vLkJlbGxjb3JlLkNPTQorCWVvd3luQHJlc2VhcmNoLkFUVC5DT00KKwlwZWdAbWVkaWEtbGFiLm1lZGlhLk1JVC5FRFUKKwlwZXRlckBTVUcuT1JHCisJc2hhbm5vbkBTdW4uQ09NCisJc2lmQEJlbGxjb3JlLkNPTQorCXN0ZXZld0BuZXRib3NzMS50cmcuc2FpYy5jb20KKwl0ZXVzQG9jZS5OTAorCXRyZW50QHhvci5DT00KKwl0d29vZEBjYXBta3QuQ09NCisJIm10dGFtOjp1YmVsbCJAU0ZCYXkuRU5ldC5ERUMuQ09NCisJemltZXRAQ29ycAorVG86ICciYSxiIicKK0V4cGVjdDogMQorCSciYSxiIicKK1RvOiAnYSwgYicKK0V4cGVjdDogMgorCSdhCisJYicKK1RvOiAiYSxiIgorRXhwZWN0OiAxCisJImEsYiIKK1RvOiBzaGFrZXkhImEsYiIKK0V4cGVjdDogMQorCXNoYWtleSEiYSxiIgorVG86ICJmb28gYmFyIgorRXhwZWN0OiAxCisJImZvbyBiYXIiCitUbzogKEZvbyBCYXIpIGZvb0BiYXIKK0V4cGVjdDogMQorCWZvb0BiYXIKK1RvOiAoRm9vIEJhcikgZm9vQGJhciwgKE15IE5hbWUpIG15QG5hbWUKK0V4cGVjdDogMgorCWZvb0BiYXIKKwlteUBuYW1lCitUbzogQmVuIEtlaXRjaCA8Ij4iQG9wZW53b3JsZC5jby51az4gCitFeHBlY3Q6IDEKKwkiPiJAb3BlbndvcmxkLmNvLnVrCitUbzogQmVuIEtlaXRjaCA8Ij5cIiJcPkBvcGVud29ybGQuY28udWs+IAorRXhwZWN0OiAxCisJIj5cIiJcPkBvcGVud29ybGQuY28udWsKK1RvOiBBIEdyb3VwOkNocmlzIEpvbmVzIDxjQGEudGVzdD4sam9lQHdoZXJlLnRlc3QsSm9obiA8amRvZUBvbmUudGVzdD47IAorRXhwZWN0OiAxCisJQSBHcm91cDpDaHJpcyBKb25lcyA8Y0BhLnRlc3Q+LGpvZUB3aGVyZS50ZXN0LEpvaG4gPGpkb2VAb25lLnRlc3Q+OworVG86IFVuZGlzY2xvc2VkLVJlY2lwaWVudHM6OworRXhwZWN0OiAxCisJVW5kaXNjbG9zZWQtUmVjaXBpZW50czo7CitUbzogICJNYXJrIEhhcG5lciIgPG1hcmsuaGFwbmVyQGVuZy5zdW4uY29tPiwgPG1hcmsuaGltZWxzdGVpbkBlbmcuc3VuLmNvbT4KK0V4cGVjdDogMgorCW1hcmsuaGFwbmVyQGVuZy5zdW4uY29tCisJbWFyay5oaW1lbHN0ZWluQGVuZy5zdW4uY29tCitUbzogPHJlbUByb2NraXQ+IChSYWxwaCBNaWxsZXIpLCA8c2hhbm5vbkBkYXRzdW4+IChCaWxsIFNoYW5ub24pCitFeHBlY3Q6IDIKKwlyZW1Acm9ja2l0CisJc2hhbm5vbkBkYXRzdW4KK1RvOiAiIiA8amF2YW1haWxAc3VuLmNvbT4KK0V4cGVjdDogMQorCWphdmFtYWlsQHN1bi5jb20KK1RvOiBzdW4ham9lIChqb2VAc3VuKQorRXhwZWN0OiAxCisJc3VuIWpvZQorVG86ICJqb2huIGRvZSIgKGpvaG4uZG9lQGEuY29tKQorRXhwZWN0OiAxCisJImpvaG4gZG9lIgorVG86ICh0ZXN0IGRvbWFpbiBsaXRlcmFsIHZlcmlmaWNhdGlvbikgYkBbMS4yLjMuNF0KK0V4cGVjdDogMQorCWJAWzEuMi4zLjRdCitDb21tZW50OiBwYXJzZWQgYXMgYSBoZWFkZXIsIHdlIHBpY2sgb3V0IHRoZSBhZGRyZXNzIGZyb20gdGhlICJjb21tZW50IgorSGVhZGVyOiB0cnVlCitUbzogImpvaG4gZG9lIiAoam9obi5kb2VAYS5jb20pCitFeHBlY3Q6IDEKKwlqb2huLmRvZUBhLmNvbQorQ29tbWVudDogdGVzdCB0aGF0IGhlYWRlcnMgYXJlIHVuZm9sZGVkIGJlZm9yZSBwYXJzaW5nCitUbzogIkpvaG4KKwlTbWl0aCIgPGpzbWl0aEAKKwljcmFwcHktZW1haWwtYXJjaGl2aW5nLWNvbXBhbnkuY29tPgorRXhwZWN0OiAxCisJanNtaXRoQAljcmFwcHktZW1haWwtYXJjaGl2aW5nLWNvbXBhbnkuY29tCitIZWFkZXI6IGZhbHNlCitUbzogKFRlc3QpIDxkam9lQHppbWJyYS5jb20+LGRqb2VAemltYnJhLmNvbSAoVGVzdCkgCitFeHBlY3Q6IDIKKwlkam9lQHppbWJyYS5jb20KKwlkam9lQHppbWJyYS5jb20KK0NvbW1lbnQ6CisJQWxsIHRoZSBmb2xsb3dpbmcgYWRkcmVzc2VzIGFyZSBiYWQuCitUbzogLAorRXhwZWN0OiAwCitUbzogPAorRXhwZWN0OiBFeGNlcHRpb24gamF2YXgubWFpbC5pbnRlcm5ldC5BZGRyZXNzRXhjZXB0aW9uOiBNaXNzaW5nICc+JyBpbiBzdHJpbmcgYGA8JycgYXQgcG9zaXRpb24gMQorVG86ID4KK0V4cGVjdDogRXhjZXB0aW9uIGphdmF4Lm1haWwuaW50ZXJuZXQuQWRkcmVzc0V4Y2VwdGlvbjogTWlzc2luZyAnPCcgaW4gc3RyaW5nIGBgPicnIGF0IHBvc2l0aW9uIDAKK1RvOiAiCitFeHBlY3Q6IEV4Y2VwdGlvbiBqYXZheC5tYWlsLmludGVybmV0LkFkZHJlc3NFeGNlcHRpb246IE1pc3NpbmcgJyInIGluIHN0cmluZyBgYCInJyBhdCBwb3NpdGlvbiAxCitUbzogPj4+CitFeHBlY3Q6IEV4Y2VwdGlvbiBqYXZheC5tYWlsLmludGVybmV0LkFkZHJlc3NFeGNlcHRpb246IE1pc3NpbmcgJzwnIGluIHN0cmluZyBgYD4+PicnIGF0IHBvc2l0aW9uIDAKK1RvOiA8PDwKK0V4cGVjdDogRXhjZXB0aW9uIGphdmF4Lm1haWwuaW50ZXJuZXQuQWRkcmVzc0V4Y2VwdGlvbjogTWlzc2luZyAnPicgaW4gc3RyaW5nIGBgPDw8JycgYXQgcG9zaXRpb24gMworVG86IHBhcmlzQGZyYW5jZT4KK0V4cGVjdDogRXhjZXB0aW9uIGphdmF4Lm1haWwuaW50ZXJuZXQuQWRkcmVzc0V4Y2VwdGlvbjogTWlzc2luZyAnPCcgaW4gc3RyaW5nIGBgcGFyaXNAZnJhbmNlPicnIGF0IHBvc2l0aW9uIDEyCitUbzogIkMnZXN0IGJpZW4gbW9jaGUgPHBhcmlzQGZyYW5jZT4KK0V4cGVjdDogRXhjZXB0aW9uIGphdmF4Lm1haWwuaW50ZXJuZXQuQWRkcmVzc0V4Y2VwdGlvbjogTWlzc2luZyAnIicgaW4gc3RyaW5nIGBgIkMnZXN0IGJpZW4gbW9jaGUgPHBhcmlzQGZyYW5jZT4nJyBhdCBwb3NpdGlvbiAzMgorVG86ICJDJ2VzdCBiaWVuIG1vY2hlIiA8cGFyaXNAZnJhbmNlCitFeHBlY3Q6IEV4Y2VwdGlvbiBqYXZheC5tYWlsLmludGVybmV0LkFkZHJlc3NFeGNlcHRpb246IE1pc3NpbmcgJz4nIGluIHN0cmluZyBgYCJDJ2VzdCBiaWVuIG1vY2hlIiA8cGFyaXNAZnJhbmNlJycgYXQgcG9zaXRpb24gMzIKK1RvOiAiQydlc3QgYmllbiBtb2NoZSIgcGFyaXNAZnJhbmNlPgorRXhwZWN0OiBFeGNlcHRpb24gamF2YXgubWFpbC5pbnRlcm5ldC5BZGRyZXNzRXhjZXB0aW9uOiBNaXNzaW5nICc8JyBpbiBzdHJpbmcgYGAiQydlc3QgYmllbiBtb2NoZSIgcGFyaXNAZnJhbmNlPicnIGF0IHBvc2l0aW9uIDMxCitUbzogIkMnZXN0IGJpZW4gbW9jaGUiIDxwYXJpc0A+CitFeHBlY3Q6IEV4Y2VwdGlvbiBqYXZheC5tYWlsLmludGVybmV0LkFkZHJlc3NFeGNlcHRpb246IE1pc3NpbmcgZG9tYWluIGluIHN0cmluZyBgYHBhcmlzQCcnCitUbzogbGFib3Jpb3VzIGJ1dCAoQnVnIEZyZWUpCitFeHBlY3Q6IEV4Y2VwdGlvbiBqYXZheC5tYWlsLmludGVybmV0LkFkZHJlc3NFeGNlcHRpb246IExvY2FsIGFkZHJlc3MgY29udGFpbnMgY29udHJvbCBvciB3aGl0ZXNwYWNlIGluIHN0cmluZyBgYGxhYm9yaW91cyBidXQnJworVG86IGNvbmZ1c2VkIChhYm91dCwgYmVpbmcsIGZyZW5jaAorRXhwZWN0OiBFeGNlcHRpb24gamF2YXgubWFpbC5pbnRlcm5ldC5BZGRyZXNzRXhjZXB0aW9uOiBNaXNzaW5nICcpJyBpbiBzdHJpbmcgYGBjb25mdXNlZCAoYWJvdXQsIGJlaW5nLCBmcmVuY2gnJyBhdCBwb3NpdGlvbiAzMAorVG86IGl0QGlzIChicmlsbGlhbnQgKGdlbml1cywgYW5kIHN1cGVyYikKK0V4cGVjdDogRXhjZXB0aW9uIGphdmF4Lm1haWwuaW50ZXJuZXQuQWRkcmVzc0V4Y2VwdGlvbjogTWlzc2luZyAnKScgaW4gc3RyaW5nIGBgaXRAaXMgKGJyaWxsaWFudCAoZ2VuaXVzLCBhbmQgc3VwZXJiKScnIGF0IHBvc2l0aW9uIDM3CitUbzogaXRAaXMgKGJyaWxsaWFudCAoZ2VuaXVzKSwgYW5kIHN1cGVyYgorRXhwZWN0OiBFeGNlcHRpb24gamF2YXgubWFpbC5pbnRlcm5ldC5BZGRyZXNzRXhjZXB0aW9uOiBNaXNzaW5nICcpJyBpbiBzdHJpbmcgYGBpdEBpcyAoYnJpbGxpYW50IChnZW5pdXMpLCBhbmQgc3VwZXJiJycgYXQgcG9zaXRpb24gMzcKK1RvOiBpZkB5b3UgKGNvdWxkLCBzZWUgKGFsbW9zdCwgYXMsIChiYWRseSwgeW91IHdvdWxkKSBhZ3JlZSkKK0V4cGVjdDogRXhjZXB0aW9uIGphdmF4Lm1haWwuaW50ZXJuZXQuQWRkcmVzc0V4Y2VwdGlvbjogTWlzc2luZyAnKScgaW4gc3RyaW5nIGBgaWZAeW91IChjb3VsZCwgc2VlIChhbG1vc3QsIGFzLCAoYmFkbHksIHlvdSB3b3VsZCkgYWdyZWUpJycgYXQgcG9zaXRpb24gNTcKK1RvOiBpZkB5b3UgKGNvdWxkLCBzZWUgKGFsbW9zdCwgYXMsIChiYWRseSwgeW91KSB3b3VsZCkgYWdyZWUKK0V4cGVjdDogRXhjZXB0aW9uIGphdmF4Lm1haWwuaW50ZXJuZXQuQWRkcmVzc0V4Y2VwdGlvbjogTWlzc2luZyAnKScgaW4gc3RyaW5nIGBgaWZAeW91IChjb3VsZCwgc2VlIChhbG1vc3QsIGFzLCAoYmFkbHksIHlvdSkgd291bGQpIGFncmVlJycgYXQgcG9zaXRpb24gNTcKK1RvOiB0d29AIChJdCBXaWxsIFRha2UpCitFeHBlY3Q6IEV4Y2VwdGlvbiBqYXZheC5tYWlsLmludGVybmV0LkFkZHJlc3NFeGNlcHRpb246IE1pc3NpbmcgZG9tYWluIGluIHN0cmluZyBgYHR3b0AnJworVG86IHR3b0AKK0V4cGVjdDogRXhjZXB0aW9uIGphdmF4Lm1haWwuaW50ZXJuZXQuQWRkcmVzc0V4Y2VwdGlvbjogTWlzc2luZyBkb21haW4gaW4gc3RyaW5nIGBgdHdvQCcnCitUbzogdHdvQHdlZWtzIChJdCBXaWxsIFRha2UKK0V4cGVjdDogRXhjZXB0aW9uIGphdmF4Lm1haWwuaW50ZXJuZXQuQWRkcmVzc0V4Y2VwdGlvbjogTWlzc2luZyAnKScgaW4gc3RyaW5nIGBgdHdvQHdlZWtzIChJdCBXaWxsIFRha2UnJyBhdCBwb3NpdGlvbiAyMworVG86IDxwYXJpc0BmcmFuY2UKK0V4cGVjdDogRXhjZXB0aW9uIGphdmF4Lm1haWwuaW50ZXJuZXQuQWRkcmVzc0V4Y2VwdGlvbjogTWlzc2luZyAnPicgaW4gc3RyaW5nIGBgPHBhcmlzQGZyYW5jZScnIGF0IHBvc2l0aW9uIDEzCitUbzogcGFyaXNAZnJhbmNlPgorRXhwZWN0OiBFeGNlcHRpb24gamF2YXgubWFpbC5pbnRlcm5ldC5BZGRyZXNzRXhjZXB0aW9uOiBNaXNzaW5nICc8JyBpbiBzdHJpbmcgYGBwYXJpc0BmcmFuY2U+JycgYXQgcG9zaXRpb24gMTIKK1RvOiBAZnJhbmNlCitFeHBlY3Q6IEV4Y2VwdGlvbiBqYXZheC5tYWlsLmludGVybmV0LkFkZHJlc3NFeGNlcHRpb246IE1pc3NpbmcgbG9jYWwgbmFtZSBpbiBzdHJpbmcgYGBAZnJhbmNlJycKK1RvOiBACitFeHBlY3Q6IEV4Y2VwdGlvbiBqYXZheC5tYWlsLmludGVybmV0LkFkZHJlc3NFeGNlcHRpb246IE1pc3NpbmcgbG9jYWwgbmFtZSBpbiBzdHJpbmcgYGBAJycKK1RvOiA8CitFeHBlY3Q6IEV4Y2VwdGlvbiBqYXZheC5tYWlsLmludGVybmV0LkFkZHJlc3NFeGNlcHRpb246IE1pc3NpbmcgJz4nIGluIHN0cmluZyBgYDwnJyBhdCBwb3NpdGlvbiAxCitUbzogPgorRXhwZWN0OiBFeGNlcHRpb24gamF2YXgubWFpbC5pbnRlcm5ldC5BZGRyZXNzRXhjZXB0aW9uOiBNaXNzaW5nICc8JyBpbiBzdHJpbmcgYGA+JycgYXQgcG9zaXRpb24gMAorVG86ICgKK0V4cGVjdDogRXhjZXB0aW9uIGphdmF4Lm1haWwuaW50ZXJuZXQuQWRkcmVzc0V4Y2VwdGlvbjogTWlzc2luZyAnKScgaW4gc3RyaW5nIGBgKCcnIGF0IHBvc2l0aW9uIDEKK1RvOiApCitFeHBlY3Q6IEV4Y2VwdGlvbiBqYXZheC5tYWlsLmludGVybmV0LkFkZHJlc3NFeGNlcHRpb246IE1pc3NpbmcgJygnIGluIHN0cmluZyBgYCknJyBhdCBwb3NpdGlvbiAwCitUbzogIgorRXhwZWN0OiBFeGNlcHRpb24gamF2YXgubWFpbC5pbnRlcm5ldC5BZGRyZXNzRXhjZXB0aW9uOiBNaXNzaW5nICciJyBpbiBzdHJpbmcgYGAiJycgYXQgcG9zaXRpb24gMQorVG86IGZyaWVuZHMtbGlzdDo7QG1hc3RvZG9uLkNTLkJlcmtlbGV5LkVEVQorRXhwZWN0OiBFeGNlcHRpb24gamF2YXgubWFpbC5pbnRlcm5ldC5BZGRyZXNzRXhjZXB0aW9uOiBNaXNzaW5nIGxvY2FsIG5hbWUgaW4gc3RyaW5nIGBgQG1hc3RvZG9uLkNTLkJlcmtlbGV5LkVEVScnCitUbzogYUAuY29tCitFeHBlY3Q6IEV4Y2VwdGlvbiBqYXZheC5tYWlsLmludGVybmV0LkFkZHJlc3NFeGNlcHRpb246IERvbWFpbiBzdGFydHMgd2l0aCBkb3QgaW4gc3RyaW5nIGBgYUAuY29tJycKK1RvOiBhQGNvbS4KK0V4cGVjdDogRXhjZXB0aW9uIGphdmF4Lm1haWwuaW50ZXJuZXQuQWRkcmVzc0V4Y2VwdGlvbjogRG9tYWluIGVuZHMgd2l0aCBkb3QgaW4gc3RyaW5nIGBgYUBjb20uJycKK1RvOiBhQGIuLmNvbQorRXhwZWN0OiBFeGNlcHRpb24gamF2YXgubWFpbC5pbnRlcm5ldC5BZGRyZXNzRXhjZXB0aW9uOiBEb21haW4gY29udGFpbnMgZG90LWRvdCBpbiBzdHJpbmcgYGBhQGIuLmNvbScnCitUbzogLmFAYi5jb20KK0V4cGVjdDogRXhjZXB0aW9uIGphdmF4Lm1haWwuaW50ZXJuZXQuQWRkcmVzc0V4Y2VwdGlvbjogTG9jYWwgYWRkcmVzcyBzdGFydHMgd2l0aCBkb3QgaW4gc3RyaW5nIGBgLmFAYi5jb20nJworVG86IGEuQGIuY29tCitFeHBlY3Q6IEV4Y2VwdGlvbiBqYXZheC5tYWlsLmludGVybmV0LkFkZHJlc3NFeGNlcHRpb246IExvY2FsIGFkZHJlc3MgZW5kcyB3aXRoIGRvdCBpbiBzdHJpbmcgYGBhLkBiLmNvbScnCitUbzogYS4uYkBiLmNvbQorRXhwZWN0OiBFeGNlcHRpb24gamF2YXgubWFpbC5pbnRlcm5ldC5BZGRyZXNzRXhjZXB0aW9uOiBMb2NhbCBhZGRyZXNzIGNvbnRhaW5zIGRvdC1kb3QgaW4gc3RyaW5nIGBgYS4uYkBiLmNvbScnCitUbzogYUABY29tCitFeHBlY3Q6IEV4Y2VwdGlvbiBqYXZheC5tYWlsLmludGVybmV0LkFkZHJlc3NFeGNlcHRpb246IERvbWFpbiBjb250YWlucyBjb250cm9sIG9yIHdoaXRlc3BhY2UgaW4gc3RyaW5nIGBgYUABY29tJycKK1RvOiBhAUBiLmNvbQorRXhwZWN0OiBFeGNlcHRpb24gamF2YXgubWFpbC5pbnRlcm5ldC5BZGRyZXNzRXhjZXB0aW9uOiBMb2NhbCBhZGRyZXNzIGNvbnRhaW5zIGNvbnRyb2wgb3Igd2hpdGVzcGFjZSBpbiBzdHJpbmcgYGBhAUBiLmNvbScnCitUbzogYQFiCitFeHBlY3Q6IEV4Y2VwdGlvbiBqYXZheC5tYWlsLmludGVybmV0LkFkZHJlc3NFeGNlcHRpb246IExvY2FsIGFkZHJlc3MgY29udGFpbnMgY29udHJvbCBvciB3aGl0ZXNwYWNlIGluIHN0cmluZyBgYGEBYicnCitUbzogQGIuY29tCitFeHBlY3Q6IEV4Y2VwdGlvbiBqYXZheC5tYWlsLmludGVybmV0LkFkZHJlc3NFeGNlcHRpb246IE1pc3NpbmcgbG9jYWwgbmFtZSBpbiBzdHJpbmcgYGBAYi5jb20nJworVG86IGphdmFtYWlsQFN1bi5DT007CitFeHBlY3Q6IEV4Y2VwdGlvbiBqYXZheC5tYWlsLmludGVybmV0LkFkZHJlc3NFeGNlcHRpb246IElsbGVnYWwgc2VtaWNvbG9uLCBub3QgaW4gZ3JvdXAgaW4gc3RyaW5nIGBgamF2YW1haWxAU3VuLkNPTTsnJyBhdCBwb3NpdGlvbiAxNgorVG86IFVuZGlzY2xvc2VkLVJlY2lwaWVudDo7QGp1cGl0ZXIuYWN0aXZlaXNwLmNvbTs7Ozs7CitFeHBlY3Q6IEV4Y2VwdGlvbiBqYXZheC5tYWlsLmludGVybmV0LkFkZHJlc3NFeGNlcHRpb246IElsbGVnYWwgc2VtaWNvbG9uLCBub3QgaW4gZ3JvdXAgaW4gc3RyaW5nIGBgVW5kaXNjbG9zZWQtUmVjaXBpZW50OjtAanVwaXRlci5hY3RpdmVpc3AuY29tOzs7OzsnJyBhdCBwb3NpdGlvbiA0NQorVG86IFVuZGlzY2xvc2VkLVJlY2lwaWVudDo7QGphdmEuc3VuLmNvbTs7OworRXhwZWN0OiBFeGNlcHRpb24gamF2YXgubWFpbC5pbnRlcm5ldC5BZGRyZXNzRXhjZXB0aW9uOiBJbGxlZ2FsIHNlbWljb2xvbiwgbm90IGluIGdyb3VwIGluIHN0cmluZyBgYFVuZGlzY2xvc2VkLVJlY2lwaWVudDo7QGphdmEuc3VuLmNvbTs7OycnIGF0IHBvc2l0aW9uIDM2CitUbzogImJlamp6Y2ZyQGFvbC5jb20KK0V4cGVjdDogRXhjZXB0aW9uIGphdmF4Lm1haWwuaW50ZXJuZXQuQWRkcmVzc0V4Y2VwdGlvbjogTWlzc2luZyAnIicgaW4gc3RyaW5nIGBgImJlamp6Y2ZyQGFvbC5jb20nJyBhdCBwb3NpdGlvbiAxNworVG86ICJidXRicEBtc24uY29tCitFeHBlY3Q6IEV4Y2VwdGlvbiBqYXZheC5tYWlsLmludGVybmV0LkFkZHJlc3NFeGNlcHRpb246IE1pc3NpbmcgJyInIGluIHN0cmluZyBgYCJidXRicEBtc24uY29tJycgYXQgcG9zaXRpb24gMTQKK1RvOiAiQG1zbi5jb20KK0V4cGVjdDogRXhjZXB0aW9uIGphdmF4Lm1haWwuaW50ZXJuZXQuQWRkcmVzc0V4Y2VwdGlvbjogTWlzc2luZyAnIicgaW4gc3RyaW5nIGBgIkBtc24uY29tJycgYXQgcG9zaXRpb24gOQorVG86ICJAc3RhcmJhbmQubmV0CitFeHBlY3Q6IEV4Y2VwdGlvbiBqYXZheC5tYWlsLmludGVybmV0LkFkZHJlc3NFeGNlcHRpb246IE1pc3NpbmcgJyInIGluIHN0cmluZyBgYCJAc3RhcmJhbmQubmV0JycgYXQgcG9zaXRpb24gMTQKK1RvOiBqa28yM2wxQGtsZHMuamF2YS5zdW4uY29tOywgYWRAamF2YS5zdW4uY29tCitFeHBlY3Q6IEV4Y2VwdGlvbiBqYXZheC5tYWlsLmludGVybmV0LkFkZHJlc3NFeGNlcHRpb246IElsbGVnYWwgc2VtaWNvbG9uLCBub3QgaW4gZ3JvdXAgaW4gc3RyaW5nIGBgamtvMjNsMUBrbGRzLmphdmEuc3VuLmNvbTssIGFkQGphdmEuc3VuLmNvbScnIGF0IHBvc2l0aW9uIDI1CitUbzogamtvMjNsMUBrbGRzO2FkOzs7OworRXhwZWN0OiBFeGNlcHRpb24gamF2YXgubWFpbC5pbnRlcm5ldC5BZGRyZXNzRXhjZXB0aW9uOiBJbGxlZ2FsIHNlbWljb2xvbiwgbm90IGluIGdyb3VwIGluIHN0cmluZyBgYGprbzIzbDFAa2xkczthZDs7OzsnJyBhdCBwb3NpdGlvbiAxMgorVG86IG1haWx0bzptYWlsdG86c25vYTEwMWN1c3RzZXJ2QGhvdG1haWwuY29tCitFeHBlY3Q6IEV4Y2VwdGlvbiBqYXZheC5tYWlsLmludGVybmV0LkFkZHJlc3NFeGNlcHRpb246IE5lc3RlZCBncm91cCBpbiBzdHJpbmcgYGBtYWlsdG86bWFpbHRvOnNub2ExMDFjdXN0c2VydkBob3RtYWlsLmNvbScnIGF0IHBvc2l0aW9uIDEzCitUbzogbWFpbHRvOm1haWx0bzpzbm9hMTAxY3VzdHNlcnZAaG90bWFpbC5jb20sIGZvb0BiYXIuY29tCitFeHBlY3Q6IEV4Y2VwdGlvbiBqYXZheC5tYWlsLmludGVybmV0LkFkZHJlc3NFeGNlcHRpb246IE5lc3RlZCBncm91cCBpbiBzdHJpbmcgYGBtYWlsdG86bWFpbHRvOnNub2ExMDFjdXN0c2VydkBob3RtYWlsLmNvbSwgZm9vQGJhci5jb20nJyBhdCBwb3NpdGlvbiAxMworVG86ICJAZm9vLmNvbSwgYUBiLmNvbQorRXhwZWN0OiBFeGNlcHRpb24gamF2YXgubWFpbC5pbnRlcm5ldC5BZGRyZXNzRXhjZXB0aW9uOiBNaXNzaW5nICciJyBpbiBzdHJpbmcgYGAiQGZvby5jb20sIGFAYi5jb20nJyBhdCBwb3NpdGlvbiAxOAorVG86IDxAZm9vLmNvbSwgYUBiLmNvbQorRXhwZWN0OiBFeGNlcHRpb24gamF2YXgubWFpbC5pbnRlcm5ldC5BZGRyZXNzRXhjZXB0aW9uOiBNaXNzaW5nICc+JyBpbiBzdHJpbmcgYGA8QGZvby5jb20sIGFAYi5jb20nJyBhdCBwb3NpdGlvbiAxOAorVG86IDxhQGIuY29tPiA8Y0BkLmNvbT4KK0V4cGVjdDogRXhjZXB0aW9uIGphdmF4Lm1haWwuaW50ZXJuZXQuQWRkcmVzc0V4Y2VwdGlvbjogRXh0cmEgcm91dGUtYWRkciBpbiBzdHJpbmcgYGA8YUBiLmNvbT4gPGNAZC5jb20+JycgYXQgcG9zaXRpb24gMTAKK1RvOiB5eWlvaG9oampsaltvam9saGppQGhvdG1haWwuY29tCitFeHBlY3Q6IEV4Y2VwdGlvbiBqYXZheC5tYWlsLmludGVybmV0LkFkZHJlc3NFeGNlcHRpb246IE1pc3NpbmcgJ10nIGluIHN0cmluZyBgYHl5aW9ob2hqamxqW29qb2xoamlAaG90bWFpbC5jb20nJyBhdCBwb3NpdGlvbiAzMQorVG86IHd3dy5hZHNsZXhwcmVzcy5jb20udHctLT8/Pz8/cT9IP1s/bz8/LTBAa2F0aG1hbmR1LnN1bi5jb20KK0V4cGVjdDogRXhjZXB0aW9uIGphdmF4Lm1haWwuaW50ZXJuZXQuQWRkcmVzc0V4Y2VwdGlvbjogTWlzc2luZyAnXScgaW4gc3RyaW5nIGBgd3d3LmFkc2xleHByZXNzLmNvbS50dy0tPz8/Pz9xP0g/Wz9vPz8tMEBrYXRobWFuZHUuc3VuLmNvbScnIGF0IHBvc2l0aW9uIDU4CitDYzogd2VibWFpbC5oaW5ldC5uZXRAbndrZWEtbWFpbC0xLnN1bi5jb20gKKSktdi69K22tmyl8yksCisgICB3d3cuYWRzbGV4cHJlc3MuY29tLnR3LS2kpLXYuXGrSKVbqm+vuC0wQG53a2VhLW1haWwtMS5zdW4uY29tLAorICAgd3d3LmNpdHlmYW1pbHkuY29tLnR3LS0tuvS49KZQvse3fC0wQG53a2VhLW1haWwtMS5zdW4uY29tCitFeHBlY3Q6IEV4Y2VwdGlvbiBqYXZheC5tYWlsLmludGVybmV0LkFkZHJlc3NFeGNlcHRpb246IE1pc3NpbmcgJ10nIGluIHN0cmluZyBgYHdlYm1haWwuaGluZXQubmV0QG53a2VhLW1haWwtMS5zdW4uY29tICg/Pz8/Pz8/Pz9sPz8pLAorICAgd3d3LmFkc2xleHByZXNzLmNvbS50dy0tPz8/Pz9xP0g/Wz9vPz8tMEBud2tlYS1tYWlsLTEuc3VuLmNvbSwKKyAgIHd3dy5jaXR5ZmFtaWx5LmNvbS50dy0tLT8/Pz8/UD8/P3wtMEBud2tlYS1tYWlsLTEuc3VuLmNvbScnIGF0IHBvc2l0aW9uIDE4MQorVG86IHd3dy5hZHNsZXhwcmVzcy5jb20udHctLaSktdi5catIpVuqb6+4LTBAcGF0YW4uc3VuLmNvbQorRXhwZWN0OiBFeGNlcHRpb24gamF2YXgubWFpbC5pbnRlcm5ldC5BZGRyZXNzRXhjZXB0aW9uOiBNaXNzaW5nICddJyBpbiBzdHJpbmcgYGB3d3cuYWRzbGV4cHJlc3MuY29tLnR3LS0/Pz8/P3E/SD9bP28/Py0wQHBhdGFuLnN1bi5jb20nJyBhdCBwb3NpdGlvbiA1NAorVG86IEdpYW50LldoaXRlLkJlYW5zO0dyZWF0Lk5vcnRoZXJuLkJlYW5zO0xpbWEuQmVhbnM7TmF2eS5CZWFuc0A0ZW1haWwtMDM7Ozs7Ozs7Ozs7Ozs7Ozs7OzsKK0V4cGVjdDogRXhjZXB0aW9uIGphdmF4Lm1haWwuaW50ZXJuZXQuQWRkcmVzc0V4Y2VwdGlvbjogSWxsZWdhbCBzZW1pY29sb24sIG5vdCBpbiBncm91cCBpbiBzdHJpbmcgYGBHaWFudC5XaGl0ZS5CZWFucztHcmVhdC5Ob3J0aGVybi5CZWFucztMaW1hLkJlYW5zO05hdnkuQmVhbnNANGVtYWlsLTAzOzs7Ozs7Ozs7Ozs7Ozs7Ozs7JycgYXQgcG9zaXRpb24gMTcKK1RvOiBcKF5eL0Bud2tlYS1tYWlsLTIuc3VuLmNvbQorRXhwZWN0OiBFeGNlcHRpb24gamF2YXgubWFpbC5pbnRlcm5ldC5BZGRyZXNzRXhjZXB0aW9uOiBNaXNzaW5nICcpJyBpbiBzdHJpbmcgYGBcKF5eL0Bud2tlYS1tYWlsLTIuc3VuLmNvbScnIGF0IHBvc2l0aW9uIDI2CitDYzogPHRvbS5yb3NzQHN1bi5jb20+LCBDYzogPGphdmFtYWlsQHN1bi5jb20+LCBDYzogPGphdmFoaUBzdW4uY29tPiwKKyAgIENjOiA8amF2YWRvYy10b29sQHN1bi5jb20+LCBDYzogPGphdmFjYXJkLWZlZWRiYWNrQHN1bi5jb20+CitFeHBlY3Q6IEV4Y2VwdGlvbiBqYXZheC5tYWlsLmludGVybmV0LkFkZHJlc3NFeGNlcHRpb246IE5lc3RlZCBncm91cCBpbiBzdHJpbmcgYGA8dG9tLnJvc3NAc3VuLmNvbT4sIENjOiA8amF2YW1haWxAc3VuLmNvbT4sIENjOiA8amF2YWhpQHN1bi5jb20+LAorICAgQ2M6IDxqYXZhZG9jLXRvb2xAc3VuLmNvbT4sIENjOiA8amF2YWNhcmQtZmVlZGJhY2tAc3VuLmNvbT4nJyBhdCBwb3NpdGlvbiA0NgorRnJvbTogPGhlbGxvQHN1bi5jb20+LCBqYXZhMmQtaW50ZXJlc3RAc3VuLmNvbSwgamF2YTNkLWludGVyZXN0QHN1bi5jb20sCisJamF2YWRvYy10b29sQHN1bi5jb20sIGphdmFtYWlsQHN1bi5jb20sIGphdmFzb3VuZC1pbnRlcmVzdEBzdW4uY29tLAorCWphdmFzcGVlY2gtaW50ZXJlc3RAc3VuLmNvbSwgamRiY0BzdW4uY29tLCBqaW0uY29va0BzdW4uY29tLAorCWpvYWNoaW0uaGVja0BzdW4uY29tLCBrYW1teUBzdW4uY29tLCBrZW5uZXRoLmNoZXVuZ0BzdW4uY29tLAorCVdlZEBicm1lYS1tYWlsLTMuc3VuLmNvbSwgbXVsdGlwYXJ0L2FsdGVybmF0aXZlQGJybWVhLW1haWwtMy5zdW4uY29tLAorCXRleHQvaHRtbEBicm1lYS1tYWlsLTMuc3VuLmNvbTsKK0V4cGVjdDogRXhjZXB0aW9uIGphdmF4Lm1haWwuaW50ZXJuZXQuQWRkcmVzc0V4Y2VwdGlvbjogSWxsZWdhbCBzZW1pY29sb24sIG5vdCBpbiBncm91cCBpbiBzdHJpbmcgYGA8aGVsbG9Ac3VuLmNvbT4sIGphdmEyZC1pbnRlcmVzdEBzdW4uY29tLCBqYXZhM2QtaW50ZXJlc3RAc3VuLmNvbSwKKwlqYXZhZG9jLXRvb2xAc3VuLmNvbSwgamF2YW1haWxAc3VuLmNvbSwgamF2YXNvdW5kLWludGVyZXN0QHN1bi5jb20sCisJamF2YXNwZWVjaC1pbnRlcmVzdEBzdW4uY29tLCBqZGJjQHN1bi5jb20sIGppbS5jb29rQHN1bi5jb20sCisJam9hY2hpbS5oZWNrQHN1bi5jb20sIGthbW15QHN1bi5jb20sIGtlbm5ldGguY2hldW5nQHN1bi5jb20sCisJV2VkQGJybWVhLW1haWwtMy5zdW4uY29tLCBtdWx0aXBhcnQvYWx0ZXJuYXRpdmVAYnJtZWEtbWFpbC0zLnN1bi5jb20sCisJdGV4dC9odG1sQGJybWVhLW1haWwtMy5zdW4uY29tOycnIGF0IHBvc2l0aW9uIDM2MgorVG86ICI/Pz9ZPz8/ej8/P34/aj9xP24/PworRXhwZWN0OiBFeGNlcHRpb24gamF2YXgubWFpbC5pbnRlcm5ldC5BZGRyZXNzRXhjZXB0aW9uOiBNaXNzaW5nICciJyBpbiBzdHJpbmcgYGAiPz8/WT8/P3o/Pz9+P2o/cT9uPz8nJyBhdCBwb3NpdGlvbiAyMQorVG86ICJaRVRBIENFTFVMQVJFUworRXhwZWN0OiBFeGNlcHRpb24gamF2YXgubWFpbC5pbnRlcm5ldC5BZGRyZXNzRXhjZXB0aW9uOiBNaXNzaW5nICciJyBpbiBzdHJpbmcgYGAiWkVUQSBDRUxVTEFSRVMnJyBhdCBwb3NpdGlvbiAxNQorVG86ICJJbnZlc3RpZ2FjaT9uIHBhcmEgZWwgZGVzYXJyb2xsbyBkZSBtaWNyby1lbXByZW5kaW1pZW50b3MgU2NocmVpYmVyIFRFIDQ0MzEtNzA1MAorRXhwZWN0OiBFeGNlcHRpb24gamF2YXgubWFpbC5pbnRlcm5ldC5BZGRyZXNzRXhjZXB0aW9uOiBNaXNzaW5nICciJyBpbiBzdHJpbmcgYGAiSW52ZXN0aWdhY2k/biBwYXJhIGVsIGRlc2Fycm9sbG8gZGUgbWljcm8tZW1wcmVuZGltaWVudG9zIFNjaHJlaWJlciBURSA0NDMxLTcwNTAnJyBhdCBwb3NpdGlvbiA4MQorVG86ICJBcHJvdmVjaGUqCitFeHBlY3Q6IEV4Y2VwdGlvbiBqYXZheC5tYWlsLmludGVybmV0LkFkZHJlc3NFeGNlcHRpb246IE1pc3NpbmcgJyInIGluIHN0cmluZyBgYCJBcHJvdmVjaGUqJycgYXQgcG9zaXRpb24gMTEKK1RvOiAiVUxUSU1BLiBPUE9SVFVOSURBRCoKK0V4cGVjdDogRXhjZXB0aW9uIGphdmF4Lm1haWwuaW50ZXJuZXQuQWRkcmVzc0V4Y2VwdGlvbjogTWlzc2luZyAnIicgaW4gc3RyaW5nIGBgIlVMVElNQS4gT1BPUlRVTklEQUQqJycgYXQgcG9zaXRpb24gMjEKK0NjOiA1NTo1NUAwNywgNTc6MThAMDcsIDM2OjM5QDEwLCAzNjo0MkAxMCwgc3RyZWV0d2Fsa2VyITE5ODcsIHN0cmVldHdhbGtlciE1LAorICAgICAgICBzdHJlZXR3YWxrZXIhODcsIDw4NzEwMDUxNDU1LkFBMDg0ODRAb2FrLnN1bmVjZC5jb20+LCA8b2FrIWtpbm5lYXI+LAorICAgICAgICBzdHJlZXR3YWxrZXIhQUEwMDE1OTssIHN0cmVldHdhbGtlciFBQTA4NDg0Oywgc3RyZWV0d2Fsa2VyIUFBMTYxNzg7LAorICAgICAgICBzdHJlZXR3YWxrZXIhRGF0ZTosIHN0cmVldHdhbGtlciFFRFQsIHN0cmVldHdhbGtlciFFY2QuU3VuLkNPTSwKKyAgICAgICAgc3RyZWV0d2Fsa2VyIUZyb20sIHN0cmVldHdhbGtlciFGcm9tOiwgc3RyZWV0d2Fsa2VyIU1lc3NhZ2UtSWQ6LAorICAgICAgICBzdHJlZXR3YWxrZXIhTW9uLCBzdHJlZXR3YWxrZXIhT2N0LCBzdHJlZXR3YWxrZXIhUERULCBzdHJlZXR3YWxrZXIhUk8sCisgICAgICAgIHN0cmVldHdhbGtlciFSZWNlaXZlZDosIHN0cmVldHdhbGtlciFSZXR1cm4tUGF0aDosCisgICAgICAgIHN0cmVldHdhbGtlciFTdGF0dXM6LCBzdHJlZXR3YWxrZXIhVG86LCBzdHJlZXR3YWxrZXIhYnksCisgICAgICAgIHN0cmVldHdhbGtlciFmcm9tLCBzdHJlZXR3YWxrZXIhaWQsIHN0cmVldHdhbGtlciFvYWsuc3VuZWNkLmNvbSwKKyAgICAgICAgc3RyZWV0d2Fsa2VyIXJvb3QsIHN0cmVldHdhbGtlciFyciwgc3RyZWV0d2Fsa2VyIXN0cmVldHdhbGtlci5zdW4uY29tCitFeHBlY3Q6IEV4Y2VwdGlvbiBqYXZheC5tYWlsLmludGVybmV0LkFkZHJlc3NFeGNlcHRpb246IE5lc3RlZCBncm91cCBpbiBzdHJpbmcgYGA1NTo1NUAwNywgNTc6MThAMDcsIDM2OjM5QDEwLCAzNjo0MkAxMCwgc3RyZWV0d2Fsa2VyITE5ODcsIHN0cmVldHdhbGtlciE1LAorICAgICAgICBzdHJlZXR3YWxrZXIhODcsIDw4NzEwMDUxNDU1LkFBMDg0ODRAb2FrLnN1bmVjZC5jb20+LCA8b2FrIWtpbm5lYXI+LAorICAgICAgICBzdHJlZXR3YWxrZXIhQUEwMDE1OTssIHN0cmVldHdhbGtlciFBQTA4NDg0Oywgc3RyZWV0d2Fsa2VyIUFBMTYxNzg7LAorICAgICAgICBzdHJlZXR3YWxrZXIhRGF0ZTosIHN0cmVldHdhbGtlciFFRFQsIHN0cmVldHdhbGtlciFFY2QuU3VuLkNPTSwKKyAgICAgICAgc3RyZWV0d2Fsa2VyIUZyb20sIHN0cmVldHdhbGtlciFGcm9tOiwgc3RyZWV0d2Fsa2VyIU1lc3NhZ2UtSWQ6LAorICAgICAgICBzdHJlZXR3YWxrZXIhTW9uLCBzdHJlZXR3YWxrZXIhT2N0LCBzdHJlZXR3YWxrZXIhUERULCBzdHJlZXR3YWxrZXIhUk8sCisgICAgICAgIHN0cmVldHdhbGtlciFSZWNlaXZlZDosIHN0cmVldHdhbGtlciFSZXR1cm4tUGF0aDosCisgICAgICAgIHN0cmVldHdhbGtlciFTdGF0dXM6LCBzdHJlZXR3YWxrZXIhVG86LCBzdHJlZXR3YWxrZXIhYnksCisgICAgICAgIHN0cmVldHdhbGtlciFmcm9tLCBzdHJlZXR3YWxrZXIhaWQsIHN0cmVldHdhbGtlciFvYWsuc3VuZWNkLmNvbSwKKyAgICAgICAgc3RyZWV0d2Fsa2VyIXJvb3QsIHN0cmVldHdhbGtlciFyciwgc3RyZWV0d2Fsa2VyIXN0cmVldHdhbGtlci5zdW4uY29tJycgYXQgcG9zaXRpb24gMTIKK1RvOiBSZTpAY2FjaGFjYSwgU3ViamVjdDpAY2FjaGFjYSwgYW5kQGNhY2hhY2EsIGdldG1jbGlzdEBjYWNoYWNhLCBnbGVubkBpdnJlbCwKKyAgICAgICAgaWNvbnZAY2FjaGFjYSwgcXVlc3Rpb25zQGNhY2hhY2EKK0V4cGVjdDogRXhjZXB0aW9uIGphdmF4Lm1haWwuaW50ZXJuZXQuQWRkcmVzc0V4Y2VwdGlvbjogTmVzdGVkIGdyb3VwIGluIHN0cmluZyBgYFJlOkBjYWNoYWNhLCBTdWJqZWN0OkBjYWNoYWNhLCBhbmRAY2FjaGFjYSwgZ2V0bWNsaXN0QGNhY2hhY2EsIGdsZW5uQGl2cmVsLAorICAgICAgICBpY29udkBjYWNoYWNhLCBxdWVzdGlvbnNAY2FjaGFjYScnIGF0IHBvc2l0aW9uIDIwCitUbzogIiA8c3RyaW5nQHN0cmluZy5ydT4gIAorRXhwZWN0OiBFeGNlcHRpb24gamF2YXgubWFpbC5pbnRlcm5ldC5BZGRyZXNzRXhjZXB0aW9uOiBNaXNzaW5nICciJyBpbiBzdHJpbmcgYGAiIDxzdHJpbmdAc3RyaW5nLnJ1PiAgJycgYXQgcG9zaXRpb24gMjIKK1RvOiBbeHh4XWZvb0BiYXIub3JnCitFeHBlY3Q6IEV4Y2VwdGlvbiBpbiB0aHJlYWQgIm1haW4iIGphdmF4Lm1haWwuaW50ZXJuZXQuQWRkcmVzc0V4Y2VwdGlvbjogTG9jYWwgYWRkcmVzcyBjb250YWlucyBpbGxlZ2FsIGNoYXJhY3RlciBpbiBzdHJpbmcgYGBbeHh4XWZvb0BiYXIub3JnJycKK0NvbW1lbnQ6CisJTm93IHBhcnNlIGFsbCB0aGUgYWJvdmUgYmFkIGFkZHJlc3NlcyBhcyBpZiB0aGV5IHdlcmUgaW4gYSBoZWFkZXIsCisJZXhwZWN0aW5nIG5vIGZhaWx1cmVzLgorSGVhZGVyOiB0cnVlCitUbzogLAorRXhwZWN0OiAwCitUbzogPAorRXhwZWN0OiAxCisJPAorVG86ID4KK0V4cGVjdDogMQorCT4KK1RvOiAiCitFeHBlY3Q6IDEKKwkiCitUbzogPj4+CitFeHBlY3Q6IDEKKwk+Pj4KK1RvOiA8PDwKK0V4cGVjdDogMQorCTw8PAorVG86IHBhcmlzQGZyYW5jZT4KK0V4cGVjdDogMQorCXBhcmlzQGZyYW5jZT4KK1RvOiAiQydlc3QgYmllbiBtb2NoZSA8cGFyaXNAZnJhbmNlPgorRXhwZWN0OiAxCisJcGFyaXNAZnJhbmNlCitUbzogIkMnZXN0IGJpZW4gbW9jaGUiIDxwYXJpc0BmcmFuY2UKK0V4cGVjdDogMQorCSJDJ2VzdCBiaWVuIG1vY2hlIiA8cGFyaXNAZnJhbmNlCitUbzogIkMnZXN0IGJpZW4gbW9jaGUiIHBhcmlzQGZyYW5jZT4KK0V4cGVjdDogMQorCSJDJ2VzdCBiaWVuIG1vY2hlIiBwYXJpc0BmcmFuY2U+CitUbzogIkMnZXN0IGJpZW4gbW9jaGUiIDxwYXJpc0A+CitFeHBlY3Q6IDEKKwlwYXJpc0AKK1RvOiBsYWJvcmlvdXMgYnV0IChCdWcgRnJlZSkKK0V4cGVjdDogMQorCWxhYm9yaW91cyBidXQKK1RvOiBjb25mdXNlZCAoYWJvdXQsIGJlaW5nLCBmcmVuY2gKK0V4cGVjdDogMworCWNvbmZ1c2VkCisJYmVpbmcKKwlmcmVuY2gKK1RvOiBpdEBpcyAoYnJpbGxpYW50IChnZW5pdXMsIGFuZCBzdXBlcmIpCitFeHBlY3Q6IDEKKwlpdEBpcworVG86IGl0QGlzIChicmlsbGlhbnQgKGdlbml1cyksIGFuZCBzdXBlcmIKK0V4cGVjdDogMgorCWl0QGlzCisJYW5kIHN1cGVyYgorVG86IGlmQHlvdSAoY291bGQsIHNlZSAoYWxtb3N0LCBhcywgKGJhZGx5LCB5b3Ugd291bGQpIGFncmVlKQorRXhwZWN0OiAyCisJaWZAeW91CisJc2VlCitUbzogaWZAeW91IChjb3VsZCwgc2VlIChhbG1vc3QsIGFzLCAoYmFkbHksIHlvdSkgd291bGQpIGFncmVlCitFeHBlY3Q6IDIKKwlpZkB5b3UKKwlzZWUKK1RvOiB0d29AIChJdCBXaWxsIFRha2UpCitFeHBlY3Q6IDEKKwl0d29ACitUbzogdHdvQAorRXhwZWN0OiAxCisJdHdvQAorVG86IHR3b0B3ZWVrcyAoSXQgV2lsbCBUYWtlCitFeHBlY3Q6IDEKKwl0d29Ad2Vla3MKK1RvOiA8cGFyaXNAZnJhbmNlCitFeHBlY3Q6IDEKKwk8cGFyaXNAZnJhbmNlCitUbzogcGFyaXNAZnJhbmNlPgorRXhwZWN0OiAxCisJcGFyaXNAZnJhbmNlPgorVG86IEBmcmFuY2UKK0V4cGVjdDogMQorCUBmcmFuY2UKK1RvOiBACitFeHBlY3Q6IDEKKwlACitUbzogPAorRXhwZWN0OiAxCisJPAorVG86ID4KK0V4cGVjdDogMQorCT4KK1RvOiAoCitFeHBlY3Q6IDAKK1RvOiApCitFeHBlY3Q6IDEKKwkpCitUbzogIgorRXhwZWN0OiAxCisJIgorVG86IGZyaWVuZHMtbGlzdDo7QG1hc3RvZG9uLkNTLkJlcmtlbGV5LkVEVQorRXhwZWN0OiAxCisJZnJpZW5kcy1saXN0OjtAbWFzdG9kb24uQ1MuQmVya2VsZXkuRURVCitUbzogYUAuY29tCitFeHBlY3Q6IDEKKwlhQC5jb20KK1RvOiBhQGNvbS4KK0V4cGVjdDogMQorCWFAY29tLgorVG86IGFAYi4uY29tCitFeHBlY3Q6IDEKKwlhQGIuLmNvbQorVG86IGFAAWNvbQorRXhwZWN0OiAxCisJYUABY29tCitUbzogYQFAYi5jb20KK0V4cGVjdDogMQorCWEBQGIuY29tCitUbzogYQFiCitFeHBlY3Q6IDEKKwlhAWIKK1RvOiBAYi5jb20KK0V4cGVjdDogMQorCUBiLmNvbQorVG86IGphdmFtYWlsQFN1bi5DT007CitFeHBlY3Q6IDEKKwlqYXZhbWFpbEBTdW4uQ09NCitUbzogVW5kaXNjbG9zZWQtUmVjaXBpZW50OjtAanVwaXRlci5hY3RpdmVpc3AuY29tOzs7OzsKK0V4cGVjdDogMQorCVVuZGlzY2xvc2VkLVJlY2lwaWVudDo7QGp1cGl0ZXIuYWN0aXZlaXNwLmNvbQorVG86IFVuZGlzY2xvc2VkLVJlY2lwaWVudDo7QGphdmEuc3VuLmNvbTs7OworRXhwZWN0OiAxCisJVW5kaXNjbG9zZWQtUmVjaXBpZW50OjtAamF2YS5zdW4uY29tCitUbzogImJlamp6Y2ZyQGFvbC5jb20KK0V4cGVjdDogMQorCSJiZWpqemNmckBhb2wuY29tCitUbzogImJ1dGJwQG1zbi5jb20KK0V4cGVjdDogMQorCSJidXRicEBtc24uY29tCitUbzogIkBtc24uY29tCitFeHBlY3Q6IDEKKwkiQG1zbi5jb20KK1RvOiAiQHN0YXJiYW5kLm5ldAorRXhwZWN0OiAxCisJIkBzdGFyYmFuZC5uZXQKK1RvOiBqa28yM2wxQGtsZHMuamF2YS5zdW4uY29tOywgYWRAamF2YS5zdW4uY29tCitFeHBlY3Q6IDIKKwlqa28yM2wxQGtsZHMuamF2YS5zdW4uY29tCisJYWRAamF2YS5zdW4uY29tCitUbzogamtvMjNsMUBrbGRzO2FkOzs7OworRXhwZWN0OiAyCisJamtvMjNsMUBrbGRzCisJYWQKK1RvOiBtYWlsdG86bWFpbHRvOnNub2ExMDFjdXN0c2VydkBob3RtYWlsLmNvbQorRXhwZWN0OiAxCisJc25vYTEwMWN1c3RzZXJ2QGhvdG1haWwuY29tCitUbzogbWFpbHRvOm1haWx0bzpzbm9hMTAxY3VzdHNlcnZAaG90bWFpbC5jb20sIGZvb0BiYXIuY29tCitFeHBlY3Q6IDIKKwlzbm9hMTAxY3VzdHNlcnZAaG90bWFpbC5jb20KKwlmb29AYmFyLmNvbQorVG86ICJAZm9vLmNvbSwgYUBiLmNvbQorRXhwZWN0OiAyCisJIkBmb28uY29tCisJYUBiLmNvbQorVG86IDxAZm9vLmNvbSwgYUBiLmNvbQorRXhwZWN0OiAyCisJPEBmb28uY29tCisJYUBiLmNvbQorVG86IDxhQGIuY29tPiA8Y0BkLmNvbT4KK0V4cGVjdDogMgorCWFAYi5jb20KKwljQGQuY29tCitUbzogeXlpb2hvaGpqbGpbb2pvbGhqaUBob3RtYWlsLmNvbQorRXhwZWN0OiAxCisJeXlpb2hvaGpqbGpbb2pvbGhqaUBob3RtYWlsLmNvbQorVG86IHd3dy5hZHNsZXhwcmVzcy5jb20udHctLT8/Pz8/cT9IP1s/bz8/LTBAa2F0aG1hbmR1LnN1bi5jb20KK0V4cGVjdDogMQorCXd3dy5hZHNsZXhwcmVzcy5jb20udHctLT8/Pz8/cT9IP1s/bz8/LTBAa2F0aG1hbmR1LnN1bi5jb20KK0NjOiB3ZWJtYWlsLmhpbmV0Lm5ldEBud2tlYS1tYWlsLTEuc3VuLmNvbSAopKS12Lr0rba2bKXzKSwKKyAgIHd3dy5hZHNsZXhwcmVzcy5jb20udHctLaSktdi5catIpVuqb6+4LTBAbndrZWEtbWFpbC0xLnN1bi5jb20sCisgICB3d3cuY2l0eWZhbWlseS5jb20udHctLS269Lj0plC+x7d8LTBAbndrZWEtbWFpbC0xLnN1bi5jb20KK0V4cGVjdDogMworCXdlYm1haWwuaGluZXQubmV0QG53a2VhLW1haWwtMS5zdW4uY29tCisJd3d3LmFkc2xleHByZXNzLmNvbS50dy0tpKS12Llxq0ilW6pvr7gtMEBud2tlYS1tYWlsLTEuc3VuLmNvbQorCXd3dy5jaXR5ZmFtaWx5LmNvbS50dy0tLbr0uPSmUL7Ht3wtMEBud2tlYS1tYWlsLTEuc3VuLmNvbQorRnJvbTogP1I/YT8/Pz9AcGF0YW4uc3VuLmNvbQorRXhwZWN0OiAxCisJP1I/YT8/Pz9AcGF0YW4uc3VuLmNvbQorVG86IHd3dy5hZHNsZXhwcmVzcy5jb20udHctLT8/Pz8/cT9IP1s/bz8/LTBAcGF0YW4uc3VuLmNvbQorRXhwZWN0OiAxCisJd3d3LmFkc2xleHByZXNzLmNvbS50dy0tPz8/Pz9xP0g/Wz9vPz8tMEBwYXRhbi5zdW4uY29tCitUbzogR2lhbnQuV2hpdGUuQmVhbnM7R3JlYXQuTm9ydGhlcm4uQmVhbnM7TGltYS5CZWFucztOYXZ5LkJlYW5zQDRlbWFpbC0wMzs7Ozs7Ozs7Ozs7Ozs7Ozs7OworRXhwZWN0OiA0CisJR2lhbnQuV2hpdGUuQmVhbnMKKwlHcmVhdC5Ob3J0aGVybi5CZWFucworCUxpbWEuQmVhbnMKKwlOYXZ5LkJlYW5zQDRlbWFpbC0wMworVG86IFwoXl4vQG53a2VhLW1haWwtMi5zdW4uY29tCitFeHBlY3Q6IDEKKwlcXAorQ2M6IDx0b20ucm9zc0BzdW4uY29tPiwgQ2M6IDxqYXZhbWFpbEBzdW4uY29tPiwgQ2M6IDxqYXZhaGlAc3VuLmNvbT4sCisgICBDYzogPGphdmFkb2MtdG9vbEBzdW4uY29tPiwgQ2M6IDxqYXZhY2FyZC1mZWVkYmFja0BzdW4uY29tPgorRXhwZWN0OiA1CisJdG9tLnJvc3NAc3VuLmNvbQorCWphdmFtYWlsQHN1bi5jb20KKwlqYXZhaGlAc3VuLmNvbQorCWphdmFkb2MtdG9vbEBzdW4uY29tCisJamF2YWNhcmQtZmVlZGJhY2tAc3VuLmNvbQorRnJvbTogPGhlbGxvQHN1bi5jb20+LCBqYXZhMmQtaW50ZXJlc3RAc3VuLmNvbSwgamF2YTNkLWludGVyZXN0QHN1bi5jb20sCisJamF2YWRvYy10b29sQHN1bi5jb20sIGphdmFtYWlsQHN1bi5jb20sIGphdmFzb3VuZC1pbnRlcmVzdEBzdW4uY29tLAorCWphdmFzcGVlY2gtaW50ZXJlc3RAc3VuLmNvbSwgamRiY0BzdW4uY29tLCBqaW0uY29va0BzdW4uY29tLAorCWpvYWNoaW0uaGVja0BzdW4uY29tLCBrYW1teUBzdW4uY29tLCBrZW5uZXRoLmNoZXVuZ0BzdW4uY29tLAorCVdlZEBicm1lYS1tYWlsLTMuc3VuLmNvbSwgbXVsdGlwYXJ0L2FsdGVybmF0aXZlQGJybWVhLW1haWwtMy5zdW4uY29tLAorCXRleHQvaHRtbEBicm1lYS1tYWlsLTMuc3VuLmNvbTsKK0V4cGVjdDogMTUKKwloZWxsb0BzdW4uY29tCisJamF2YTJkLWludGVyZXN0QHN1bi5jb20KKwlqYXZhM2QtaW50ZXJlc3RAc3VuLmNvbQorCWphdmFkb2MtdG9vbEBzdW4uY29tCisJamF2YW1haWxAc3VuLmNvbQorCWphdmFzb3VuZC1pbnRlcmVzdEBzdW4uY29tCisJamF2YXNwZWVjaC1pbnRlcmVzdEBzdW4uY29tCisJamRiY0BzdW4uY29tCisJamltLmNvb2tAc3VuLmNvbQorCWpvYWNoaW0uaGVja0BzdW4uY29tCisJa2FtbXlAc3VuLmNvbQorCWtlbm5ldGguY2hldW5nQHN1bi5jb20KKwlXZWRAYnJtZWEtbWFpbC0zLnN1bi5jb20KKwltdWx0aXBhcnQvYWx0ZXJuYXRpdmVAYnJtZWEtbWFpbC0zLnN1bi5jb20KKwl0ZXh0L2h0bWxAYnJtZWEtbWFpbC0zLnN1bi5jb20KK1RvOiAiPz8/WT8/P3o/Pz9+P2o/cT9uPz8KK0V4cGVjdDogMQorCSI/Pz9ZPz8/ej8/P34/aj9xP24/PworVG86ICJaRVRBIENFTFVMQVJFUworRXhwZWN0OiAxCisJIlpFVEEgQ0VMVUxBUkVTCitUbzogIkludmVzdGlnYWNpP24gcGFyYSBlbCBkZXNhcnJvbGxvIGRlIG1pY3JvLWVtcHJlbmRpbWllbnRvcyBTY2hyZWliZXIgVEUgNDQzMS03MDUwCitFeHBlY3Q6IDEKKwkiSW52ZXN0aWdhY2k/biBwYXJhIGVsIGRlc2Fycm9sbG8gZGUgbWljcm8tZW1wcmVuZGltaWVudG9zIFNjaHJlaWJlciBURSA0NDMxLTcwNTAKK1RvOiAiQXByb3ZlY2hlKgorRXhwZWN0OiAxCisJIkFwcm92ZWNoZSoKK1RvOiAiVUxUSU1BLiBPUE9SVFVOSURBRCoKK0V4cGVjdDogMQorCSJVTFRJTUEuIE9QT1JUVU5JREFEKgorQ2M6IDU1OjU1QDA3LCA1NzoxOEAwNywgMzY6MzlAMTAsIDM2OjQyQDEwLCBzdHJlZXR3YWxrZXIhMTk4Nywgc3RyZWV0d2Fsa2VyITUsCisgICAgICAgIHN0cmVldHdhbGtlciE4NywgPDg3MTAwNTE0NTUuQUEwODQ4NEBvYWsuc3VuZWNkLmNvbT4sIDxvYWsha2lubmVhcj4sCisgICAgICAgIHN0cmVldHdhbGtlciFBQTAwMTU5Oywgc3RyZWV0d2Fsa2VyIUFBMDg0ODQ7LCBzdHJlZXR3YWxrZXIhQUExNjE3ODssCisgICAgICAgIHN0cmVldHdhbGtlciFEYXRlOiwgc3RyZWV0d2Fsa2VyIUVEVCwgc3RyZWV0d2Fsa2VyIUVjZC5TdW4uQ09NLAorICAgICAgICBzdHJlZXR3YWxrZXIhRnJvbSwgc3RyZWV0d2Fsa2VyIUZyb206LCBzdHJlZXR3YWxrZXIhTWVzc2FnZS1JZDosCisgICAgICAgIHN0cmVldHdhbGtlciFNb24sIHN0cmVldHdhbGtlciFPY3QsIHN0cmVldHdhbGtlciFQRFQsIHN0cmVldHdhbGtlciFSTywKKyAgICAgICAgc3RyZWV0d2Fsa2VyIVJlY2VpdmVkOiwgc3RyZWV0d2Fsa2VyIVJldHVybi1QYXRoOiwKKyAgICAgICAgc3RyZWV0d2Fsa2VyIVN0YXR1czosIHN0cmVldHdhbGtlciFUbzosIHN0cmVldHdhbGtlciFieSwKKyAgICAgICAgc3RyZWV0d2Fsa2VyIWZyb20sIHN0cmVldHdhbGtlciFpZCwgc3RyZWV0d2Fsa2VyIW9hay5zdW5lY2QuY29tLAorICAgICAgICBzdHJlZXR3YWxrZXIhcm9vdCwgc3RyZWV0d2Fsa2VyIXJyLCBzdHJlZXR3YWxrZXIhc3RyZWV0d2Fsa2VyLnN1bi5jb20KK0V4cGVjdDogMjQKKwk1NTo1NUAwNywgNTc6MThAMDcsIDM2OjM5QDEwLCAzNjo0MkAxMCwgc3RyZWV0d2Fsa2VyITE5ODcsIHN0cmVldHdhbGtlciE1LCAgICAgICAgc3RyZWV0d2Fsa2VyITg3LCA8ODcxMDA1MTQ1NS5BQTA4NDg0QG9hay5zdW5lY2QuY29tPiwgPG9hayFraW5uZWFyPiwgICAgICAgIHN0cmVldHdhbGtlciFBQTAwMTU5OworCXN0cmVldHdhbGtlciFBQTA4NDg0CisJc3RyZWV0d2Fsa2VyIUFBMTYxNzgKKwlzdHJlZXR3YWxrZXIhRGF0ZToKKwlzdHJlZXR3YWxrZXIhRURUCisJc3RyZWV0d2Fsa2VyIUVjZC5TdW4uQ09NCisJc3RyZWV0d2Fsa2VyIUZyb20KKwlzdHJlZXR3YWxrZXIhRnJvbToKKwlzdHJlZXR3YWxrZXIhTWVzc2FnZS1JZDoKKwlzdHJlZXR3YWxrZXIhTW9uCisJc3RyZWV0d2Fsa2VyIU9jdAorCXN0cmVldHdhbGtlciFQRFQKKwlzdHJlZXR3YWxrZXIhUk8KKwlzdHJlZXR3YWxrZXIhUmVjZWl2ZWQ6CisJc3RyZWV0d2Fsa2VyIVJldHVybi1QYXRoOgorCXN0cmVldHdhbGtlciFTdGF0dXM6CisJc3RyZWV0d2Fsa2VyIVRvOgorCXN0cmVldHdhbGtlciFieQorCXN0cmVldHdhbGtlciFmcm9tCisJc3RyZWV0d2Fsa2VyIWlkCisJc3RyZWV0d2Fsa2VyIW9hay5zdW5lY2QuY29tCisJc3RyZWV0d2Fsa2VyIXJvb3QKKwlzdHJlZXR3YWxrZXIhcnIKKwlzdHJlZXR3YWxrZXIhc3RyZWV0d2Fsa2VyLnN1bi5jb20KK1RvOiBSZTpAY2FjaGFjYSwgU3ViamVjdDpAY2FjaGFjYSwgYW5kQGNhY2hhY2EsIGdldG1jbGlzdEBjYWNoYWNhLCBnbGVubkBpdnJlbCwKKyAgICAgICAgaWNvbnZAY2FjaGFjYSwgcXVlc3Rpb25zQGNhY2hhY2EKK0V4cGVjdDogNworCUBjYWNoYWNhCisJQGNhY2hhY2EKKwlhbmRAY2FjaGFjYQorCWdldG1jbGlzdEBjYWNoYWNhCisJZ2xlbm5AaXZyZWwKKwlpY29udkBjYWNoYWNhCisJcXVlc3Rpb25zQGNhY2hhY2EKK1RvOiAiIDxzdHJpbmdAc3RyaW5nLnJ1PiAgCitFeHBlY3Q6IDEKKwlzdHJpbmdAc3RyaW5nLnJ1CitIZWFkZXI6IGZhbHNlCmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L3Jlc291cmNlcy9qYXZheC9tYWlsL2ludGVybmV0L2ZvbGRkYXRhIGIvbWFpbC9zcmMvdGVzdC9yZXNvdXJjZXMvamF2YXgvbWFpbC9pbnRlcm5ldC9mb2xkZGF0YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40YWNjMDc3Ci0tLSAvZGV2L251bGwKKysrIGIvbWFpbC9zcmMvdGVzdC9yZXNvdXJjZXMvamF2YXgvbWFpbC9pbnRlcm5ldC9mb2xkZGF0YQpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9tYWlsL3NyYy90ZXN0L3Jlc291cmNlcy9qYXZheC9tYWlsL2ludGVybmV0L3BhcmFtZGF0YSBiL21haWwvc3JjL3Rlc3QvcmVzb3VyY2VzL2phdmF4L21haWwvaW50ZXJuZXQvcGFyYW1kYXRhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ4ZTY3M2YKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy90ZXN0L3Jlc291cmNlcy9qYXZheC9tYWlsL2ludGVybmV0L3BhcmFtZGF0YQpAQCAtMCwwICsxLDEzOSBAQAorQ29tbWVudDoKKworICAgIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorCisgICAgVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgICAgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisKKyAgICBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgICAgTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICAgIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICAgIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorCisgICAgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisKK0NvbW1lbnQ6CisKKyAgICAgICAgQSBzZXQgb2YgdGVzdCBoZWFkZXJzIHRvIHRlc3QgcGFyYW1ldGVyIGxpc3QgcGFyc2luZyBhbmQKKwllc3BlY2lhbGx5IFJGQyAyMjMxIGRlY29kaW5nLgorICAgICAgICBVc2Ugd2l0aCAicGFyYW10ZXN0IC1wIDxwYXJhbWRhdGEiLgorCisJQWxsIHRlc3RzIGFzc3VtZSAibWFpbC5taW1lLmRlY29kZXBhcmFtZXRlcnMiIGlzIHNldCB0byAidHJ1ZSIsCisJd2hpY2ggaXMgZG9uZSBhdCB0aGUgc3RhcnQgb2YgcGFyYW10ZXN0LgorCisgICAgICAgIENBUkVGVUw6IGEgYmxhbmsgbGluZSBpbiB0aGlzIGZpbGUgY2F1c2VzIGV2ZXJ5dGhpbmcgZm9sbG93aW5nIGl0CisgICAgICAgICAgICAgICAgIHRvIGJlIGlnbm9yZWQgdW50aWwgYSBsaW5lIHN0YXJ0aW5nIHdpdGggIkZyb20gIiAoc28gdGhhdAorICAgICAgICAgICAgICAgICBwYXJhbXRlc3QgLXAgY2FuIGJlIHBvaW50ZWQgYXQgYSByZWFsIG1haWxib3gpLgorCitGcm9tIHN0YXJ0IGhlcmUKK0NvbW1lbnQ6CisJVGhpcyBzZXQgb2YgaGVhZGVycyBhcmUgYWxsIGdvb2QgYW5kIHRlc3QgUkZDIDIyMzEgZGVjb2RpbmcuCitDb250ZW50LVR5cGU6IGFwcGxpY2F0aW9uL3gtc3R1ZmY7CisJdGl0bGUqMCo9dXMtYXNjaWknZW4nVGhpcyUyMGlzJTIwZXZlbiUyMG1vcmUlMjA7CisJdGl0bGUqMSo9JTJBJTJBJTJBZnVuJTJBJTJBJTJBJTIwOworCXRpdGxlKjI9Imlzbid0IGl0ISIKK0V4cGVjdDogMQorCXRpdGxlPVRoaXMgaXMgZXZlbiBtb3JlICoqKmZ1bioqKiBpc24ndCBpdCEKK0NvbnRlbnQtVHlwZTogYXBwbGljYXRpb24veC1zdHVmZjsKKwl0aXRsZSowKj0nJ1RoaXMlMjBpcyUyMGV2ZW4lMjBtb3JlJTIwOworCXRpdGxlKjEqPSUyQSUyQSUyQWZ1biUyQSUyQSUyQSUyMDsKKwl0aXRsZSoyPSJpc24ndCBpdCEiCitFeHBlY3Q6IDEKKwl0aXRsZT1UaGlzIGlzIGV2ZW4gbW9yZSAqKipmdW4qKiogaXNuJ3QgaXQhCitDb250ZW50LVR5cGU6IGFwcGxpY2F0aW9uL3gtc3R1ZmY7CisJdGl0bGUqMj0iaXNuJ3QgaXQhIjsKKwl0aXRsZSoxKj0lMkElMkElMkFmdW4lMkElMkElMkElMjA7CisJdGl0bGUqMCo9dXMtYXNjaWknZW4nVGhpcyUyMGlzJTIwZXZlbiUyMG1vcmUlMjAKK0V4cGVjdDogMQorCXRpdGxlPVRoaXMgaXMgZXZlbiBtb3JlICoqKmZ1bioqKiBpc24ndCBpdCEKK0NvbnRlbnQtVHlwZTogYXBwbGljYXRpb24veC1zdHVmZjsKKwl0aXRsZSoyPSJpc24ndCBpdCEiOworCXRpdGxlKjEqPSUyQSUyQSUyQWZ1biUyQSUyQSUyQSUyMDsKKwl0aXRsZSowKj11cy1hc2NpaSdlbidUaGlzJTIwaXMlMjBldmVuJTIwbW9yZSUyMDsKKwluYW1lKjA9Im9uZSAiOworCW5hbWUqMT0idHdvICI7CisJbmFtZSoyPSJ0aHJlZSI7CisJcCo9dXMtYXNjaWknZW4nVGhpcyUyMGlzJTIwZnVuOworRXhwZWN0OiAzCisJdGl0bGU9VGhpcyBpcyBldmVuIG1vcmUgKioqZnVuKioqIGlzbid0IGl0IQorCW5hbWU9b25lIHR3byB0aHJlZQorCXA9VGhpcyBpcyBmdW4KK0NvbnRlbnQtVHlwZTogYXBwbGljYXRpb24veC1zdHVmZjsKKwl0aXRsZSoyPSJpc24ndCBpdCEiOworCXRpdGxlKjEqPSUyQSUyQSUyQWZ1biUyQSUyQSUyQSUyMDsKKwl0aXRsZSowKj11cy1hc2NpaSdlbidUaGlzJTIwaXMlMjBldmVuJTIwbW9yZSUyMDsKKwluYW1lKjA9Im9uZSAiOworCW5hbWUqMT0idHdvICI7CisJbmFtZSoyPSJ0aHJlZSI7CisJcCo9dXMtYXNjaWknZW4nVGhpcyUyMGlzJTIwZnVuCitFeHBlY3Q6IDMKKwl0aXRsZT1UaGlzIGlzIGV2ZW4gbW9yZSAqKipmdW4qKiogaXNuJ3QgaXQhCisJbmFtZT1vbmUgdHdvIHRocmVlCisJcD1UaGlzIGlzIGZ1bgorQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXN0dWZmOworCXRpdGxlKjI9Imlzbid0IGl0ISI7CisJbmFtZSoxPSJ0d28gIjsKKwl0aXRsZSoxKj0lMkElMkElMkFmdW4lMkElMkElMkElMjA7CisJbmFtZSowPSJvbmUgIjsKKwl0aXRsZSowKj11cy1hc2NpaSdlbidUaGlzJTIwaXMlMjBldmVuJTIwbW9yZSUyMDsKKwluYW1lKjI9InRocmVlIjsKKwlwKj11cy1hc2NpaSdlbidUaGlzJTIwaXMlMjBmdW4KK0V4cGVjdDogMworCXRpdGxlPVRoaXMgaXMgZXZlbiBtb3JlICoqKmZ1bioqKiBpc24ndCBpdCEKKwluYW1lPW9uZSB0d28gdGhyZWUKKwlwPVRoaXMgaXMgZnVuCitDb21tZW50OgorCVRoZXNlIGhlYWRlcnMgdGVzdCBlcnJvciBjYXNlcyB0aGF0IGRvbid0IGdlbmVyYXRlIHBhcnNlIGV4Y2VwdGlvbnMuCisJLgorQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXN0dWZmOworCXRpdGxlKjAqPXVzLWFzY2lpJ2VuJ1RoaXMlMjBpcyUyMGV2ZW4lMjBtb3JlJTIwOworCXRpdGxlKjEqPSUyQSUyQSUyQWZ1biUyQSUyQSUyQTsKKwl0aXRsZSozPSJpc24ndCBpdCEiCitFeHBlY3Q6IDIKKwl0aXRsZT1UaGlzIGlzIGV2ZW4gbW9yZSAqKipmdW4qKioKKwl0aXRsZSozPWlzbid0IGl0IQorQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXN0dWZmOworCXRpdGxlKjAqPXVzLWFzY2lpJ2VuJ1RoaXMlMjBpcyUyMGV2ZW4lMjBtb3JlJTIwOworCXRpdGxlKjEqPSUyQSUyQSUyQWZ1biUyQSUyQSUyQTsKKwl0aXRsZSozKj0iaXNuJ3QgaXQhIgorRXhwZWN0OiAyCisJdGl0bGU9VGhpcyBpcyBldmVuIG1vcmUgKioqZnVuKioqCisJdGl0bGUqMz1pc24ndCBpdCEKK0NvbW1lbnQ6CisJVGhpcyBpcyBhbiBlcnJvciBjYXNlIHdpdGggbm8gcmlnaHQgYW5zd2VyLgorCVNob3VsZCB3ZSBhc3N1bWUgZWFybGllciBzZWdtZW50cyBhcmUgbWlzc2luZyBhbmQganVzdCBkZWNvZGUKKwl0aGlzIHNlZ21lbnQ/ICBPciBzaG91bGQgd2UgYXNzdW1lIHRoYXQgdGhlICIqMyIgaXMgcGFydCBvZgorCXRoZSBwYXJhbWV0ZXIgbmFtZSBhbmQgdGhpcyBpcyBhIHNpbmdsZSBzZWdtZW50IGVuY29kZWQgcGFyYW1ldGVyPworCUN1cnJlbnRseSB3ZSBkbyB0aGUgZm9ybWVyLgorQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXN0dWZmOyB0aXRsZSozKj11cy1hc2NpaSdlbidpc24ndCUyMGl0IQorRXhwZWN0OiAxCisJdGl0bGUqMz11cy1hc2NpaSdlbidpc24ndCBpdCEKK0NvbnRlbnQtVHlwZTogYXBwbGljYXRpb24veC1zdHVmZjsgdGl0bGUqMyo9dW5rbm93bidlbidpc24ndCUyMGl0IQorRXhwZWN0OiAxCisJdGl0bGUqMz11bmtub3duJ2VuJ2lzbid0IGl0IQorQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXN0dWZmOworCXRpdGxlKjAqPXVzLWFzY2lpJ2VuJ1RoaXMlMjBpcyUyMGV2ZW4lMjBtb3JlJTIwOworCXRpdGxlKjEqPSVYWCUyQSUyQWZ1biUyQSUyQSUyQSUyMDsKKwl0aXRsZSoyPSJpc24ndCBpdCEiCitFeHBlY3Q6IDEKKwl0aXRsZT1UaGlzIGlzIGV2ZW4gbW9yZSAlWFgqKmZ1bioqKiBpc24ndCBpdCEKK0NvbnRlbnQtVHlwZTogYXBwbGljYXRpb24veC1zdHVmZjsKKwl0aXRsZSowKj11cy1hc2NpaSdlbidUaGlzJTIwaXMlMjBldmVuJTIwbW9yZSUyMDsKKwl0aXRsZSoxPSIqKipmdW4qKioiOworCXRpdGxlKjIqPSUyMGlzbid0JTIwaXQhCitFeHBlY3Q6IDEKKwl0aXRsZT1UaGlzIGlzIGV2ZW4gbW9yZSAqKipmdW4qKiogaXNuJ3QgaXQhCitDb250ZW50LVR5cGU6IGltYWdlL3BuZzsKKwluYW1lKjAqPUlTTy0yMDIyLUpQJyclMUIlMjRCJTI0JTIyJTI0JTI0JTI0JTI2JTI0JTI4JTI0KiUyNCUyMiUyNCUyNCUyNCUyNjsKKwluYW1lKjEqPSUyNCUyOCUyNColMjQlMjIlMjQlMjQlMjQlMjYlMjQlMjglMjQqJTI0JTIyJTI0JTI0JTI0JTI2JTI0JTI4OworCW5hbWUqMio9JTI0KiUxQiUyOEIucG5nCitFeHBlY3Q6IDEKKwluYW1lPVx1MzA0Mlx1MzA0NFx1MzA0Nlx1MzA0OFx1MzA0YVx1MzA0Mlx1MzA0NFx1MzA0Nlx1MzA0OFx1MzA0YVx1MzA0Mlx1MzA0NFx1MzA0Nlx1MzA0OFx1MzA0YVx1MzA0Mlx1MzA0NFx1MzA0Nlx1MzA0OFx1MzA0YS5wbmcKK0NvbnRlbnQtVHlwZTogaW1hZ2UvcG5nOworCWZpbGVuYW1lKjAqPUlTTy0yMDIyLUpQJyclMUIlMjRCJTI0JTIyJTI0JTI0JTI0JTI2JTI0JTI4JTI0KiUyNCUyMiUyNCUyNDsKKwlmaWxlbmFtZSoxKj0lMjQlMjYlMjQlMjglMjQqJTI0JTIyJTI0JTI0JTI0JTI2JTI0JTI4JTI0KiUyNCUyMiUyNCUyNCUyNDsKKwlmaWxlbmFtZSoyKj0lMjYlMjQlMjglMjQqJTFCJTI4Qi5wbmcKK0V4cGVjdDogMQorCWZpbGVuYW1lPVx1MzA0Mlx1MzA0NFx1MzA0Nlx1MzA0OFx1MzA0YVx1MzA0Mlx1MzA0NFx1MzA0Nlx1MzA0OFx1MzA0YVx1MzA0Mlx1MzA0NFx1MzA0Nlx1MzA0OFx1MzA0YVx1MzA0Mlx1MzA0NFx1MzA0Nlx1MzA0OFx1MzA0YS5wbmcKZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvcmVzb3VyY2VzL2phdmF4L21haWwvaW50ZXJuZXQvcGFyYW1kYXRhbm9zdHJpY3QgYi9tYWlsL3NyYy90ZXN0L3Jlc291cmNlcy9qYXZheC9tYWlsL2ludGVybmV0L3BhcmFtZGF0YW5vc3RyaWN0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmExNTU4ODkKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsL3NyYy90ZXN0L3Jlc291cmNlcy9qYXZheC9tYWlsL2ludGVybmV0L3BhcmFtZGF0YW5vc3RyaWN0CkBAIC0wLDAgKzEsNzAgQEAKK0NvbW1lbnQ6CisKKyAgICBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKworICAgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICAgIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorCisgICAgVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICAgIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAgICBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAgICB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKworICAgIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorCitDb21tZW50OgorCisgICAgICAgIEEgc2V0IG9mIHRlc3QgaGVhZGVycyB0byB0ZXN0IHBhcmFtZXRlciBsaXN0IHBhcnNpbmcKKwl3aXRoIG1haWwubWltZS5wYXJhbWV0ZXJzLnN0cmljdD1mYWxzZS4KKyAgICAgICAgVXNlIHdpdGg6CisJamF2YSAtRG1haWwubWltZS5wYXJhbWV0ZXJzLnN0cmljdD1mYWxzZSBwYXJhbXRlc3QgLXAgPHBhcmFtZGF0YW5vc3RyaWN0CisKKyAgICAgICAgQ0FSRUZVTDogYSBibGFuayBsaW5lIGluIHRoaXMgZmlsZSBjYXVzZXMgZXZlcnl0aGluZyBmb2xsb3dpbmcgaXQKKyAgICAgICAgICAgICAgICAgdG8gYmUgaWdub3JlZCB1bnRpbCBhIGxpbmUgc3RhcnRpbmcgd2l0aCAiRnJvbSAiIChzbyB0aGF0CisgICAgICAgICAgICAgICAgIHBhcmFtdGVzdCAtcCBjYW4gYmUgcG9pbnRlZCBhdCBhIHJlYWwgbWFpbGJveCkuCisKK0Zyb20gc3RhcnQgaGVyZQorQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluOworIGNyZWF0aW9uLWRhdGU9VHVlLCAyMiBKdWwgMjAwOCAxMDowMzowOSBHTVQ7CisgZmlsZW5hbWU9InRlc3Qxa2IuZmlsZSI7CisgbW9kaWZpY2F0aW9uLWRhdGU9VHVlLCAyMiBKdWwgMjAwOCAxMDowMzoyNCBHTVQKK0V4cGVjdDogMworCWNyZWF0aW9uLWRhdGU9VHVlLCAyMiBKdWwgMjAwOCAxMDowMzowOSBHTVQKKwlmaWxlbmFtZT10ZXN0MWtiLmZpbGUKKwltb2RpZmljYXRpb24tZGF0ZT1UdWUsIDIyIEp1bCAyMDA4IDEwOjAzOjI0IEdNVAorQ29tbWVudDogZW1iZWRkZWQgd2hpdGVzcGFjZQorQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBuYW1lPWZpbGUgbmFtZS50eHQKK0V4cGVjdDogMQorCW5hbWU9ZmlsZSBuYW1lLnR4dAorQ29tbWVudDogdHJhaWxpbmcgd2hpdGVzcGFjZQorQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBuYW1lPWZpbGUgbmFtZS50eHQgCitFeHBlY3Q6IDEKKwluYW1lPWZpbGUgbmFtZS50eHQKK0NvbW1lbnQ6IGxlYWRpbmcgYW5kIHRyYWlsaW5nIHdoaXRlc3BhY2UKK0NvbnRlbnQtVHlwZTogdGV4dC9wbGFpbjsgbmFtZT0gZmlsZSBuYW1lLnR4dCAKK0V4cGVjdDogMQorCW5hbWU9ZmlsZSBuYW1lLnR4dAorQ29tbWVudDogdHJhaWxpbmcgbmV3bGluZQorQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBuYW1lPWZpbGUgbmFtZS50eHQKKwk7CitFeHBlY3Q6IDEKKwluYW1lPWZpbGUgbmFtZS50eHQKK0NvbnRlbnQtVHlwZTogdGV4dC9wbGFpbjsgbmFtZT1maWxlIG5hbWUudHh0IDsgdGltZT0gbm93CitFeHBlY3Q6IDIKKwluYW1lPWZpbGUgbmFtZS50eHQKKwl0aW1lPW5vdworQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBuYW1lPWZpbGUgbmFtZS50eHQgOyAKKwl0aW1lPSBub3cKK0V4cGVjdDogMgorCW5hbWU9ZmlsZSBuYW1lLnR4dAorCXRpbWU9bm93CitDb250ZW50LVR5cGU6IHRleHQvcGxhaW47IG5hbWU9ZmlsZSBuYW1lLnR4dCAKKwk7IHRpbWUgPSBub3cgCitFeHBlY3Q6IDIKKwluYW1lPWZpbGUgbmFtZS50eHQKKwl0aW1lPW5vdworQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBmaWxlbmFtZT09P1dpbmRvd3MtMTI1MT9CPzhPWHE0dWpuNlBMN0lNalBMbVJ2WXc/PQorRXhwZWN0OiAxCisJZmlsZW5hbWU9PT9XaW5kb3dzLTEyNTE/Qj84T1hxNHVqbjZQTDdJTWpQTG1Sdll3Pz0KZGlmZiAtLWdpdCBhL21haWwvc3JjL3Rlc3QvcmVzb3VyY2VzL2phdmF4L21haWwvaW50ZXJuZXQvdG9rZW5saXN0IGIvbWFpbC9zcmMvdGVzdC9yZXNvdXJjZXMvamF2YXgvbWFpbC9pbnRlcm5ldC90b2tlbmxpc3QKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDAxNGVlMAotLS0gL2Rldi9udWxsCisrKyBiL21haWwvc3JjL3Rlc3QvcmVzb3VyY2VzL2phdmF4L21haWwvaW50ZXJuZXQvdG9rZW5saXN0CkBAIC0wLDAgKzEsNzM2IEBACitDb21tZW50OgorCisgICAgQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisKKyAgICBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAgICB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKworICAgIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAgICBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgICAgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgICAgdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisKKyAgICBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKworQ29tbWVudDoKKworCUEgc2V0IG9mIHRlc3QgYWRkcmVzc2VzIHN0b2xlbiBmcm9tIHRoZSBkdG1haWwgdGVzdCBzdWl0ZSwKKwl3aXRoIGEgZmV3IG9mIG15IG93bi4gIFVzZWQgaGVyZSB0byB0ZXN0IHRoZSBoZWFkZXIgdG9rZW5pemVyLgorCVVzZSB3aXRoICJ0b2tlbml6ZXJ0ZXN0IC1wIDx0b2tlbmxpc3QiLgorCisJQ0FSRUZVTDogYSBibGFuayBsaW5lIGluIHRoaXMgZmlsZSBjYXVzZXMgZXZlcnl0aGluZyBmb2xsb3dpbmcgaXQKKwkJIHRvIGJlIGlnbm9yZWQgdW50aWwgYSBsaW5lIHN0YXJ0aW5nIHdpdGggIkZyb20gIiAoc28gdGhhdAorCQkgdG9rZW5pemVydGVzdCAtcCBjYW4gYmUgcG9pbnRlZCBhdCBhIHJlYWwgbWFpbGJveCkuCisKK0Zyb20gc3RhcnQgaGVyZQorQ29tbWVudDoKKwlUaGUgZm9sbG93aW5nIHNob3VsZCBhbGwgYmUgdG9rZW5pemVkIHN1Y2Nlc3NmdWxseS4KK1RvOiBnZ2VyZQorRXhwZWN0OiAxCisJQVRPTQlnZ2VyZQorVG86IC90bXAvbWFpbC1vdXQKK0V4cGVjdDogMQorCUFUT00JL3RtcC9tYWlsLW91dAorVG86ICttYWlsYm94CitFeHBlY3Q6IDEKKwlBVE9NCSttYWlsYm94CitUbzogfnVzZXIvbWFpbGJveAorRXhwZWN0OiAxCisJQVRPTQl+dXNlci9tYWlsYm94CitUbzogfi9tYWlsYm94CitFeHBlY3Q6IDEKKwlBVE9NCX4vbWFpbGJveAorVG86IC9QTj14NDAwLWFkZHJlc3MvUFJNRD1pYm1tYWlsL0FETUQ9aWJteDQwMC9DPXVzL0BtaHMtbWNpLWViYXkKK0V4cGVjdDogMworCUFUT00JL1BOPXg0MDAtYWRkcmVzcy9QUk1EPWlibW1haWwvQURNRD1pYm14NDAwL0M9dXMvCisJU1BFQ0lBTAlACisJQVRPTQltaHMtbWNpLWViYXkKK1RvOiBnZ2VyZSwgL3RtcC9tYWlsLW91dCwgK21haWxib3gsIH51c2VyL21haWxib3gsIH4vbWFpbGJveCwgL1BOPXg0MDAtYWRkcmVzcy9QUk1EPWlibW1haWwvQURNRD1pYm14NDAwL0M9dXMvQG1ocy1tY2ktZWJheQorRXhwZWN0OiAxMworCUFUT00JZ2dlcmUKKwlTUEVDSUFMCSwKKwlBVE9NCS90bXAvbWFpbC1vdXQKKwlTUEVDSUFMCSwKKwlBVE9NCSttYWlsYm94CisJU1BFQ0lBTAksCisJQVRPTQl+dXNlci9tYWlsYm94CisJU1BFQ0lBTAksCisJQVRPTQl+L21haWxib3gKKwlTUEVDSUFMCSwKKwlBVE9NCS9QTj14NDAwLWFkZHJlc3MvUFJNRD1pYm1tYWlsL0FETUQ9aWJteDQwMC9DPXVzLworCVNQRUNJQUwJQAorCUFUT00JbWhzLW1jaS1lYmF5CitUbzogZ2dlcmUgL3RtcC9tYWlsLW91dCArbWFpbGJveCB+dXNlci9tYWlsYm94IH4vbWFpbGJveCAvUE49eDQwMC1hZGRyZXNzL1BSTUQ9aWJtbWFpbC9BRE1EPWlibXg0MDAvQz11cy9AbWhzLW1jaS1lYmF5CitFeHBlY3Q6IDgKKwlBVE9NCWdnZXJlCisJQVRPTQkvdG1wL21haWwtb3V0CisJQVRPTQkrbWFpbGJveAorCUFUT00JfnVzZXIvbWFpbGJveAorCUFUT00Jfi9tYWlsYm94CisJQVRPTQkvUE49eDQwMC1hZGRyZXNzL1BSTUQ9aWJtbWFpbC9BRE1EPWlibXg0MDAvQz11cy8KKwlTUEVDSUFMCUAKKwlBVE9NCW1ocy1tY2ktZWJheQorVG86IE1hZCBHZW5pdXMgPGdlb3JnZUBib29sZT4KK0V4cGVjdDogNworCUFUT00JTWFkCisJQVRPTQlHZW5pdXMKKwlTUEVDSUFMCTwKKwlBVE9NCWdlb3JnZQorCVNQRUNJQUwJQAorCUFUT00JYm9vbGUKKwlTUEVDSUFMCT4KK1RvOiAiQydlc3QgYmllbiBtb2NoZSIgPHBhcmlzQGZyYW5jZT4KK0V4cGVjdDogNgorCVFVT1RFRFNUUklORwlDJ2VzdCBiaWVuIG1vY2hlCisJU1BFQ0lBTAk8CisJQVRPTQlwYXJpcworCVNQRUNJQUwJQAorCUFUT00JZnJhbmNlCisJU1BFQ0lBTAk+CitUbzogImtub3csIGFueSwgZmFtb3VzIiA8ZnJlbmNoQHBoeXNpY2lzdHM+CitFeHBlY3Q6IDYKKwlRVU9URURTVFJJTkcJa25vdywgYW55LCBmYW1vdXMKKwlTUEVDSUFMCTwKKwlBVE9NCWZyZW5jaAorCVNQRUNJQUwJQAorCUFUT00JcGh5c2ljaXN0cworCVNQRUNJQUwJPgorVG86IGxhYm9yaW91cyAoQnV0IEJ1ZyBGcmVlKQorRXhwZWN0OiAxCisJQVRPTQlsYWJvcmlvdXMKK1RvOiBjb25mdXNlZCAoYWJvdXQsIGJlaW5nLCBmcmVuY2gpCitFeHBlY3Q6IDEKKwlBVE9NCWNvbmZ1c2VkCitUbzogaXQgKHRha2VzLCBubyAodGltZSwgYXQpIGFsbCkKK0V4cGVjdDogMQorCUFUT00JaXQKK1RvOiB0d29Ad2Vla3MgKEl0IFdpbGwgVGFrZSkKK0V4cGVjdDogMworCUFUT00JdHdvCisJU1BFQ0lBTAlACisJQVRPTQl3ZWVrcworVG86IGl0QGlzIChicmlsbGlhbnQgKGdlbml1cywgYW5kKSBzdXBlcmIpCitFeHBlY3Q6IDMKKwlBVE9NCWl0CisJU1BFQ0lBTAlACisJQVRPTQlpcworVG86IGlmQHlvdSAoY291bGQsIHNlZSAoYWxtb3N0LCBhcywgKGJhZGx5LCB5b3UpIHdvdWxkKSBhZ3JlZSkKK0V4cGVjdDogMworCUFUT00JaWYKKwlTUEVDSUFMCUAKKwlBVE9NCXlvdQorVG86IGNhbm5vdEB3YXN0ZSAoTXksIEludGVsbGVjdHVhbCwgQ3ljbGVzKQorRXhwZWN0OiAzCisJQVRPTQljYW5ub3QKKwlTUEVDSUFMCUAKKwlBVE9NCXdhc3RlCitUbzogdXNlcnM6Z2V0LHdoYXQsdGhleSxkZXNlcnZlOworRXhwZWN0OiAxMAorCUFUT00JdXNlcnMKKwlTUEVDSUFMCToKKwlBVE9NCWdldAorCVNQRUNJQUwJLAorCUFUT00Jd2hhdAorCVNQRUNJQUwJLAorCUFUT00JdGhleQorCVNQRUNJQUwJLAorCUFUT00JZGVzZXJ2ZQorCVNQRUNJQUwJOworVG86ICJDJ2VzdCBiaWVuIG1vY2hlIiA8cGFyaXNAZnJhbmNlPiwgTWFkIEdlbml1cyA8Z2VvcmdlQGJvb2xlPiwgdHdvQHdlZWtzIChJdCBXaWxsIFRha2UpLCAvdG1wL21haWwtb3V0LCBsYWJvcmlvdXMgKEJ1dCBCdWcgRnJlZSksIGNhbm5vdEB3YXN0ZSAoTXksIEludGVsbGVjdHVhbCwgQ3ljbGVzKSwgdXNlcnM6Z2V0LHdoYXQsdGhleSxkZXNlcnZlOywgaXQgKHRha2VzLCBubyAodGltZSwgYXQpIGFsbCksIGlmQHlvdSAoY291bGQsIHNlZSAoYWxtb3N0LCBhcywgKGJhZGx5LCB5b3UpIHdvdWxkKSBhZ3JlZSksICJrbm93LCBhbnksIGZhbW91cyIgPEZyZW5jaEBwaHlzaWNpc3RzPiwgaXRAaXMgKGJyaWxsaWFudCAoZ2VuaXVzLCBhbmQpIHN1cGVyYiksIGNvbmZ1c2VkIChhYm91dCwgYmVpbmcsIGZyZW5jaCkKK0V4cGVjdDogNTYKKwlRVU9URURTVFJJTkcJQydlc3QgYmllbiBtb2NoZQorCVNQRUNJQUwJPAorCUFUT00JcGFyaXMKKwlTUEVDSUFMCUAKKwlBVE9NCWZyYW5jZQorCVNQRUNJQUwJPgorCVNQRUNJQUwJLAorCUFUT00JTWFkCisJQVRPTQlHZW5pdXMKKwlTUEVDSUFMCTwKKwlBVE9NCWdlb3JnZQorCVNQRUNJQUwJQAorCUFUT00JYm9vbGUKKwlTUEVDSUFMCT4KKwlTUEVDSUFMCSwKKwlBVE9NCXR3bworCVNQRUNJQUwJQAorCUFUT00Jd2Vla3MKKwlTUEVDSUFMCSwKKwlBVE9NCS90bXAvbWFpbC1vdXQKKwlTUEVDSUFMCSwKKwlBVE9NCWxhYm9yaW91cworCVNQRUNJQUwJLAorCUFUT00JY2Fubm90CisJU1BFQ0lBTAlACisJQVRPTQl3YXN0ZQorCVNQRUNJQUwJLAorCUFUT00JdXNlcnMKKwlTUEVDSUFMCToKKwlBVE9NCWdldAorCVNQRUNJQUwJLAorCUFUT00Jd2hhdAorCVNQRUNJQUwJLAorCUFUT00JdGhleQorCVNQRUNJQUwJLAorCUFUT00JZGVzZXJ2ZQorCVNQRUNJQUwJOworCVNQRUNJQUwJLAorCUFUT00JaXQKKwlTUEVDSUFMCSwKKwlBVE9NCWlmCisJU1BFQ0lBTAlACisJQVRPTQl5b3UKKwlTUEVDSUFMCSwKKwlRVU9URURTVFJJTkcJa25vdywgYW55LCBmYW1vdXMKKwlTUEVDSUFMCTwKKwlBVE9NCUZyZW5jaAorCVNQRUNJQUwJQAorCUFUT00JcGh5c2ljaXN0cworCVNQRUNJQUwJPgorCVNQRUNJQUwJLAorCUFUT00JaXQKKwlTUEVDSUFMCUAKKwlBVE9NCWlzCisJU1BFQ0lBTAksCisJQVRPTQljb25mdXNlZAorVG86IGdnZXJlLCAvdG1wL21haWwtb3V0LCArbWFpbGJveCwgfnVzZXIvbWFpbGJveCwgfi9tYWlsYm94LCAvUE49eDQwMC1hZGRyZXNzL1BSTUQ9aWJtbWFpbC9BRE1EPWlibXg0MDAvQz11cy9AbWhzLW1jaS1lYmF5LCAiQydlc3QgYmllbiBtb2NoZSIgPHBhcmlzQGZyYW5jZT4sIE1hZCBHZW5pdXMgPGdlb3JnZUBib29sZT4sIHR3b0B3ZWVrcyAoSXQgV2lsbCBUYWtlKSwgL3RtcC9tYWlsLW91dCwgbGFib3Jpb3VzIChCdXQgQnVnIEZyZWUpLCBjYW5ub3RAd2FzdGUgKE15LCBJbnRlbGxlY3R1YWwsIEN5Y2xlcyksIHVzZXJzOmdldCx3aGF0LHRoZXksZGVzZXJ2ZTssIGl0ICh0YWtlcywgbm8gKHRpbWUsIGF0KSBhbGwpLCBpZkB5b3UgKGNvdWxkLCBzZWUgKGFsbW9zdCwgYXMsIChiYWRseSwgeW91KSB3b3VsZCkgYWdyZWUpLCAia25vdywgYW55LCBmYW1vdXMiIDxGcmVuY2hAcGh5c2ljaXN0cz4sIGl0QGlzIChicmlsbGlhbnQgKGdlbml1cywgYW5kKSBzdXBlcmIpLCBjb25mdXNlZCAoYWJvdXQsIGJlaW5nLCBmcmVuY2gpCitFeHBlY3Q6IDcwCisJQVRPTQlnZ2VyZQorCVNQRUNJQUwJLAorCUFUT00JL3RtcC9tYWlsLW91dAorCVNQRUNJQUwJLAorCUFUT00JK21haWxib3gKKwlTUEVDSUFMCSwKKwlBVE9NCX51c2VyL21haWxib3gKKwlTUEVDSUFMCSwKKwlBVE9NCX4vbWFpbGJveAorCVNQRUNJQUwJLAorCUFUT00JL1BOPXg0MDAtYWRkcmVzcy9QUk1EPWlibW1haWwvQURNRD1pYm14NDAwL0M9dXMvCisJU1BFQ0lBTAlACisJQVRPTQltaHMtbWNpLWViYXkKKwlTUEVDSUFMCSwKKwlRVU9URURTVFJJTkcJQydlc3QgYmllbiBtb2NoZQorCVNQRUNJQUwJPAorCUFUT00JcGFyaXMKKwlTUEVDSUFMCUAKKwlBVE9NCWZyYW5jZQorCVNQRUNJQUwJPgorCVNQRUNJQUwJLAorCUFUT00JTWFkCisJQVRPTQlHZW5pdXMKKwlTUEVDSUFMCTwKKwlBVE9NCWdlb3JnZQorCVNQRUNJQUwJQAorCUFUT00JYm9vbGUKKwlTUEVDSUFMCT4KKwlTUEVDSUFMCSwKKwlBVE9NCXR3bworCVNQRUNJQUwJQAorCUFUT00Jd2Vla3MKKwlTUEVDSUFMCSwKKwlBVE9NCS90bXAvbWFpbC1vdXQKKwlTUEVDSUFMCSwKKwlBVE9NCWxhYm9yaW91cworCVNQRUNJQUwJLAorCUFUT00JY2Fubm90CisJU1BFQ0lBTAlACisJQVRPTQl3YXN0ZQorCVNQRUNJQUwJLAorCUFUT00JdXNlcnMKKwlTUEVDSUFMCToKKwlBVE9NCWdldAorCVNQRUNJQUwJLAorCUFUT00Jd2hhdAorCVNQRUNJQUwJLAorCUFUT00JdGhleQorCVNQRUNJQUwJLAorCUFUT00JZGVzZXJ2ZQorCVNQRUNJQUwJOworCVNQRUNJQUwJLAorCUFUT00JaXQKKwlTUEVDSUFMCSwKKwlBVE9NCWlmCisJU1BFQ0lBTAlACisJQVRPTQl5b3UKKwlTUEVDSUFMCSwKKwlRVU9URURTVFJJTkcJa25vdywgYW55LCBmYW1vdXMKKwlTUEVDSUFMCTwKKwlBVE9NCUZyZW5jaAorCVNQRUNJQUwJQAorCUFUT00JcGh5c2ljaXN0cworCVNQRUNJQUwJPgorCVNQRUNJQUwJLAorCUFUT00JaXQKKwlTUEVDSUFMCUAKKwlBVE9NCWlzCisJU1BFQ0lBTAksCisJQVRPTQljb25mdXNlZAorVG86IHRlc3RhIHRlc3RiIHRlc3RjIC90bXAvbWFpbC1vdXQgfmdnZXJlL21haWwtb3V0IHRlc3RkIHRlc3RlCitFeHBlY3Q6IDcKKwlBVE9NCXRlc3RhCisJQVRPTQl0ZXN0YgorCUFUT00JdGVzdGMKKwlBVE9NCS90bXAvbWFpbC1vdXQKKwlBVE9NCX5nZ2VyZS9tYWlsLW91dAorCUFUT00JdGVzdGQKKwlBVE9NCXRlc3RlCitUbzogdGVzdGEsIHRlc3RiICwgdGVzdGMgL3RtcC9tYWlsLW91dCAsfmdnZXJlL21haWwtb3V0LCAsdGVzdGQsdGVzdGUsLCwKK0V4cGVjdDogMTYKKwlBVE9NCXRlc3RhCisJU1BFQ0lBTAksCisJQVRPTQl0ZXN0YgorCVNQRUNJQUwJLAorCUFUT00JdGVzdGMKKwlBVE9NCS90bXAvbWFpbC1vdXQKKwlTUEVDSUFMCSwKKwlBVE9NCX5nZ2VyZS9tYWlsLW91dAorCVNQRUNJQUwJLAorCVNQRUNJQUwJLAorCUFUT00JdGVzdGQKKwlTUEVDSUFMCSwKKwlBVE9NCXRlc3RlCisJU1BFQ0lBTAksCisJU1BFQ0lBTAksCisJU1BFQ0lBTAksCitUbzogdGVzdGEgdGVzdGIgPHRlc3RjQHRlc3RkPgorRXhwZWN0OiA3CisJQVRPTQl0ZXN0YQorCUFUT00JdGVzdGIKKwlTUEVDSUFMCTwKKwlBVE9NCXRlc3RjCisJU1BFQ0lBTAlACisJQVRPTQl0ZXN0ZAorCVNQRUNJQUwJPgorVG86IEFkYW0gUyBNb3Nrb3dpdHogPGFkYW1tQG9uaW9uLWluc2V0LWNvbT4sCisgICAgICAgIEFuZHJldyBHb2xsYW4gPGFkamdAc29mdHdheS1zdy1PWi1BVT4sCisgICAgICAgIEJyZXQgQW50aG9ueSBNYXJxdWlzIDxiYW1AdHJvdXQtbm9zYy1NSUw+LAorICAgICAgICBCaWxsIFNoYW5ub24gPHNoYW5ub25AU3VuLUNPTT4sIEJvYiBHcmF5IDxyZ3JheUBVc1dlc3QtQ09NPiwKKyAgICAgICAgQnJpYW4gRWxsaXMgPGJyaUBCb3VsZGVyLUNvbG9yYWRvLUVEVT4sCisgICAgICAgIERvbiBDb2xlbWFuIDxjb2xlbWFuQGxlZ2F0by1DT00+LAorICAgICAgICBEZW5uaXMgUml0Y2hpZSA8ZG1yQHJlc2VhcmNoLUFUVC1DT00+LCBFdmkgTmVtZXRoIDxldmlAQ29sb3JhZG8tRURVPiwKKyAgICAgICAgTG9yaSBHcm9iIDxncm9iQGNob3J1cy1GUj4sIFBhdWxhIEhhd3Rob3JuIDxoYXd0aG9ybkBIUEwtSFAtQ09NPiwKKyAgICAgICAgQW5kcmV3IEh1bWUgPGFuZHJld0ByZXNlYXJjaC1BVFQtQ09NPiwKKyAgICAgICAgSmFhcCBBa2tlcmh1aXMgPGphYXBAcmVzZWFyY2gtQVRULUNPTT4sCisgICAgICAgIEppbSBSIE9sZHJveWQgPGpyQG9uaW9uLWluc2V0LWNvbT4sCisgICAgICAgIEpvaG4gUXVhcnRlcm1hbiA8anNxQGxvbmd3YXktVElDLUNPTT4sCisgICAgICAgIEp1ZHkgRGVzSGFybmFpcyA8anVkeUBVU0VOSVgtT1JHPiwgS2FyZW4gU2hhbm5vbiA8a2FzQEVuZz4sCisgICAgICAgIEtlbiBNY0RvbmVsbCA8a2VuakBQeXJhbWlkLUNPTT4sCisgICAgICAgIFJvYiBLb2xzdGFkIDxrb2xzdGFkQHJtdGMtQ2VudHJhbC1TdW4tQ09NPiwKKyAgICAgICAgUGF1bCBLb29yb3MgPGtvb3Jvc0B0aWdnZXItY3MtQ29sb3JhZG8tRURVPiwKKyAgICAgICAgUm9iZXJ0IEVseiA8a3JlQE11bm5hcmktT1otQVU+LAorICAgICAgICBNaXJpYW0gQW1vcyBOaWhhcnQgPG1pcmlhbUBkZWN3ZXQtZW5ldC1ERUMtQ09NPiwKKyAgICAgICAgIk1pa2UgTydEZWxsIiA8bW9AZ2l6bW8tQmVsbGNvcmUtQ09NPiwKKyAgICAgICAgU2hhcm9uIE11cnJlbCA8ZW93eW5AcmVzZWFyY2gtQVRULUNPTT4sCisgICAgICAgIFBlZyBTY2hhZmVyIDxwZWdAbWVkaWEtbGFiLW1lZGlhLU1JVC1FRFU+LCBQZXRlciBTYWx1cyA8cGV0ZXJAU1VHLU9SRz4sCisgICAgICAgIEJpbGwgU2hhbm5vbiA8c2hhbm5vbkBTdW4tQ09NPiwgU3R1IEZlbGRtYW4gPHNpZkBCZWxsY29yZS1DT00+LAorICAgICAgICBTdGVwaGVuIFdpbGxpYW1zIDxzdGV2ZXdAbmV0Ym9zczEtdHJnLXNhaWMtY29tPiwKKyAgICAgICAgVGV1cyBIYWdlbiA8dGV1c0BvY2UtTkw+LCBUcmVudCBIZWluIDx0cmVudEB4b3ItQ09NPiwKKyAgICAgICAgVGhvbWFzIEFsYW4gV29vZCA8dHdvb2RAY2FwbWt0LUNPTT4sCisgICAgICAgIE1pY2hhZWwgVWJlbGwgPCJtdHRhbTo6dWJlbGwiQFNGQmF5LUVOZXQtREVDLUNPTT4sCisgICAgICAgIE1hcnRoYSBaaW1ldCA8emltZXRAQ29ycD4KK0V4cGVjdDogMjc1CisJQVRPTQlBZGFtCisJQVRPTQlTCisJQVRPTQlNb3Nrb3dpdHoKKwlTUEVDSUFMCTwKKwlBVE9NCWFkYW1tCisJU1BFQ0lBTAlACisJQVRPTQlvbmlvbi1pbnNldC1jb20KKwlTUEVDSUFMCT4KKwlTUEVDSUFMCSwKKwlBVE9NCUFuZHJldworCUFUT00JR29sbGFuCisJU1BFQ0lBTAk8CisJQVRPTQlhZGpnCisJU1BFQ0lBTAlACisJQVRPTQlzb2Z0d2F5LXN3LU9aLUFVCisJU1BFQ0lBTAk+CisJU1BFQ0lBTAksCisJQVRPTQlCcmV0CisJQVRPTQlBbnRob255CisJQVRPTQlNYXJxdWlzCisJU1BFQ0lBTAk8CisJQVRPTQliYW0KKwlTUEVDSUFMCUAKKwlBVE9NCXRyb3V0LW5vc2MtTUlMCisJU1BFQ0lBTAk+CisJU1BFQ0lBTAksCisJQVRPTQlCaWxsCisJQVRPTQlTaGFubm9uCisJU1BFQ0lBTAk8CisJQVRPTQlzaGFubm9uCisJU1BFQ0lBTAlACisJQVRPTQlTdW4tQ09NCisJU1BFQ0lBTAk+CisJU1BFQ0lBTAksCisJQVRPTQlCb2IKKwlBVE9NCUdyYXkKKwlTUEVDSUFMCTwKKwlBVE9NCXJncmF5CisJU1BFQ0lBTAlACisJQVRPTQlVc1dlc3QtQ09NCisJU1BFQ0lBTAk+CisJU1BFQ0lBTAksCisJQVRPTQlCcmlhbgorCUFUT00JRWxsaXMKKwlTUEVDSUFMCTwKKwlBVE9NCWJyaQorCVNQRUNJQUwJQAorCUFUT00JQm91bGRlci1Db2xvcmFkby1FRFUKKwlTUEVDSUFMCT4KKwlTUEVDSUFMCSwKKwlBVE9NCURvbgorCUFUT00JQ29sZW1hbgorCVNQRUNJQUwJPAorCUFUT00JY29sZW1hbgorCVNQRUNJQUwJQAorCUFUT00JbGVnYXRvLUNPTQorCVNQRUNJQUwJPgorCVNQRUNJQUwJLAorCUFUT00JRGVubmlzCisJQVRPTQlSaXRjaGllCisJU1BFQ0lBTAk8CisJQVRPTQlkbXIKKwlTUEVDSUFMCUAKKwlBVE9NCXJlc2VhcmNoLUFUVC1DT00KKwlTUEVDSUFMCT4KKwlTUEVDSUFMCSwKKwlBVE9NCUV2aQorCUFUT00JTmVtZXRoCisJU1BFQ0lBTAk8CisJQVRPTQlldmkKKwlTUEVDSUFMCUAKKwlBVE9NCUNvbG9yYWRvLUVEVQorCVNQRUNJQUwJPgorCVNQRUNJQUwJLAorCUFUT00JTG9yaQorCUFUT00JR3JvYgorCVNQRUNJQUwJPAorCUFUT00JZ3JvYgorCVNQRUNJQUwJQAorCUFUT00JY2hvcnVzLUZSCisJU1BFQ0lBTAk+CisJU1BFQ0lBTAksCisJQVRPTQlQYXVsYQorCUFUT00JSGF3dGhvcm4KKwlTUEVDSUFMCTwKKwlBVE9NCWhhd3Rob3JuCisJU1BFQ0lBTAlACisJQVRPTQlIUEwtSFAtQ09NCisJU1BFQ0lBTAk+CisJU1BFQ0lBTAksCisJQVRPTQlBbmRyZXcKKwlBVE9NCUh1bWUKKwlTUEVDSUFMCTwKKwlBVE9NCWFuZHJldworCVNQRUNJQUwJQAorCUFUT00JcmVzZWFyY2gtQVRULUNPTQorCVNQRUNJQUwJPgorCVNQRUNJQUwJLAorCUFUT00JSmFhcAorCUFUT00JQWtrZXJodWlzCisJU1BFQ0lBTAk8CisJQVRPTQlqYWFwCisJU1BFQ0lBTAlACisJQVRPTQlyZXNlYXJjaC1BVFQtQ09NCisJU1BFQ0lBTAk+CisJU1BFQ0lBTAksCisJQVRPTQlKaW0KKwlBVE9NCVIKKwlBVE9NCU9sZHJveWQKKwlTUEVDSUFMCTwKKwlBVE9NCWpyCisJU1BFQ0lBTAlACisJQVRPTQlvbmlvbi1pbnNldC1jb20KKwlTUEVDSUFMCT4KKwlTUEVDSUFMCSwKKwlBVE9NCUpvaG4KKwlBVE9NCVF1YXJ0ZXJtYW4KKwlTUEVDSUFMCTwKKwlBVE9NCWpzcQorCVNQRUNJQUwJQAorCUFUT00JbG9uZ3dheS1USUMtQ09NCisJU1BFQ0lBTAk+CisJU1BFQ0lBTAksCisJQVRPTQlKdWR5CisJQVRPTQlEZXNIYXJuYWlzCisJU1BFQ0lBTAk8CisJQVRPTQlqdWR5CisJU1BFQ0lBTAlACisJQVRPTQlVU0VOSVgtT1JHCisJU1BFQ0lBTAk+CisJU1BFQ0lBTAksCisJQVRPTQlLYXJlbgorCUFUT00JU2hhbm5vbgorCVNQRUNJQUwJPAorCUFUT00Ja2FzCisJU1BFQ0lBTAlACisJQVRPTQlFbmcKKwlTUEVDSUFMCT4KKwlTUEVDSUFMCSwKKwlBVE9NCUtlbgorCUFUT00JTWNEb25lbGwKKwlTUEVDSUFMCTwKKwlBVE9NCWtlbmoKKwlTUEVDSUFMCUAKKwlBVE9NCVB5cmFtaWQtQ09NCisJU1BFQ0lBTAk+CisJU1BFQ0lBTAksCisJQVRPTQlSb2IKKwlBVE9NCUtvbHN0YWQKKwlTUEVDSUFMCTwKKwlBVE9NCWtvbHN0YWQKKwlTUEVDSUFMCUAKKwlBVE9NCXJtdGMtQ2VudHJhbC1TdW4tQ09NCisJU1BFQ0lBTAk+CisJU1BFQ0lBTAksCisJQVRPTQlQYXVsCisJQVRPTQlLb29yb3MKKwlTUEVDSUFMCTwKKwlBVE9NCWtvb3JvcworCVNQRUNJQUwJQAorCUFUT00JdGlnZ2VyLWNzLUNvbG9yYWRvLUVEVQorCVNQRUNJQUwJPgorCVNQRUNJQUwJLAorCUFUT00JUm9iZXJ0CisJQVRPTQlFbHoKKwlTUEVDSUFMCTwKKwlBVE9NCWtyZQorCVNQRUNJQUwJQAorCUFUT00JTXVubmFyaS1PWi1BVQorCVNQRUNJQUwJPgorCVNQRUNJQUwJLAorCUFUT00JTWlyaWFtCisJQVRPTQlBbW9zCisJQVRPTQlOaWhhcnQKKwlTUEVDSUFMCTwKKwlBVE9NCW1pcmlhbQorCVNQRUNJQUwJQAorCUFUT00JZGVjd2V0LWVuZXQtREVDLUNPTQorCVNQRUNJQUwJPgorCVNQRUNJQUwJLAorCVFVT1RFRFNUUklORwlNaWtlIE8nRGVsbAorCVNQRUNJQUwJPAorCUFUT00JbW8KKwlTUEVDSUFMCUAKKwlBVE9NCWdpem1vLUJlbGxjb3JlLUNPTQorCVNQRUNJQUwJPgorCVNQRUNJQUwJLAorCUFUT00JU2hhcm9uCisJQVRPTQlNdXJyZWwKKwlTUEVDSUFMCTwKKwlBVE9NCWVvd3luCisJU1BFQ0lBTAlACisJQVRPTQlyZXNlYXJjaC1BVFQtQ09NCisJU1BFQ0lBTAk+CisJU1BFQ0lBTAksCisJQVRPTQlQZWcKKwlBVE9NCVNjaGFmZXIKKwlTUEVDSUFMCTwKKwlBVE9NCXBlZworCVNQRUNJQUwJQAorCUFUT00JbWVkaWEtbGFiLW1lZGlhLU1JVC1FRFUKKwlTUEVDSUFMCT4KKwlTUEVDSUFMCSwKKwlBVE9NCVBldGVyCisJQVRPTQlTYWx1cworCVNQRUNJQUwJPAorCUFUT00JcGV0ZXIKKwlTUEVDSUFMCUAKKwlBVE9NCVNVRy1PUkcKKwlTUEVDSUFMCT4KKwlTUEVDSUFMCSwKKwlBVE9NCUJpbGwKKwlBVE9NCVNoYW5ub24KKwlTUEVDSUFMCTwKKwlBVE9NCXNoYW5ub24KKwlTUEVDSUFMCUAKKwlBVE9NCVN1bi1DT00KKwlTUEVDSUFMCT4KKwlTUEVDSUFMCSwKKwlBVE9NCVN0dQorCUFUT00JRmVsZG1hbgorCVNQRUNJQUwJPAorCUFUT00Jc2lmCisJU1BFQ0lBTAlACisJQVRPTQlCZWxsY29yZS1DT00KKwlTUEVDSUFMCT4KKwlTUEVDSUFMCSwKKwlBVE9NCVN0ZXBoZW4KKwlBVE9NCVdpbGxpYW1zCisJU1BFQ0lBTAk8CisJQVRPTQlzdGV2ZXcKKwlTUEVDSUFMCUAKKwlBVE9NCW5ldGJvc3MxLXRyZy1zYWljLWNvbQorCVNQRUNJQUwJPgorCVNQRUNJQUwJLAorCUFUT00JVGV1cworCUFUT00JSGFnZW4KKwlTUEVDSUFMCTwKKwlBVE9NCXRldXMKKwlTUEVDSUFMCUAKKwlBVE9NCW9jZS1OTAorCVNQRUNJQUwJPgorCVNQRUNJQUwJLAorCUFUT00JVHJlbnQKKwlBVE9NCUhlaW4KKwlTUEVDSUFMCTwKKwlBVE9NCXRyZW50CisJU1BFQ0lBTAlACisJQVRPTQl4b3ItQ09NCisJU1BFQ0lBTAk+CisJU1BFQ0lBTAksCisJQVRPTQlUaG9tYXMKKwlBVE9NCUFsYW4KKwlBVE9NCVdvb2QKKwlTUEVDSUFMCTwKKwlBVE9NCXR3b29kCisJU1BFQ0lBTAlACisJQVRPTQljYXBta3QtQ09NCisJU1BFQ0lBTAk+CisJU1BFQ0lBTAksCisJQVRPTQlNaWNoYWVsCisJQVRPTQlVYmVsbAorCVNQRUNJQUwJPAorCVFVT1RFRFNUUklORwltdHRhbTo6dWJlbGwKKwlTUEVDSUFMCUAKKwlBVE9NCVNGQmF5LUVOZXQtREVDLUNPTQorCVNQRUNJQUwJPgorCVNQRUNJQUwJLAorCUFUT00JTWFydGhhCisJQVRPTQlaaW1ldAorCVNQRUNJQUwJPAorCUFUT00JemltZXQKKwlTUEVDSUFMCUAKKwlBVE9NCUNvcnAKKwlTUEVDSUFMCT4KK1RvOiAnImEsYiInCitFeHBlY3Q6IDMKKwlBVE9NCScKKwlRVU9URURTVFJJTkcJYSxiCisJQVRPTQknCitUbzogJ2EsIGInCitFeHBlY3Q6IDMKKwlBVE9NCSdhCisJU1BFQ0lBTAksCisJQVRPTQliJworVG86ICJhLGIiCitFeHBlY3Q6IDEKKwlRVU9URURTVFJJTkcJYSxiCitUbzogc2hha2V5ISJhLGIiCitFeHBlY3Q6IDIKKwlBVE9NCXNoYWtleSEKKwlRVU9URURTVFJJTkcJYSxiCitUbzogImZvbyBiYXIiCitFeHBlY3Q6IDEKKwlRVU9URURTVFJJTkcJZm9vIGJhcgorVG86IChGb28gQmFyKSBmb29AYmFyCitFeHBlY3Q6IDMKKwlBVE9NCWZvbworCVNQRUNJQUwJQAorCUFUT00JYmFyCitUbzogKEZvbyBCYXIpIGZvb0BiYXIsIChNeSBOYW1lKSBteUBuYW1lCitFeHBlY3Q6IDcKKwlBVE9NCWZvbworCVNQRUNJQUwJQAorCUFUT00JYmFyCisJU1BFQ0lBTAksCisJQVRPTQlteQorCVNQRUNJQUwJQAorCUFUT00JbmFtZQorVG86ICwKK0V4cGVjdDogMQorCVNQRUNJQUwJLAorVG86ICJDJ2VzdCBiaWVuIG1vY2hlIiA8cGFyaXNAZnJhbmNlCitFeHBlY3Q6IDUKKwlRVU9URURTVFJJTkcJQydlc3QgYmllbiBtb2NoZQorCVNQRUNJQUwJPAorCUFUT00JcGFyaXMKKwlTUEVDSUFMCUAKKwlBVE9NCWZyYW5jZQorVG86ICJDJ2VzdCBiaWVuIG1vY2hlIiBwYXJpc0BmcmFuY2U+CitFeHBlY3Q6IDUKKwlRVU9URURTVFJJTkcJQydlc3QgYmllbiBtb2NoZQorCUFUT00JcGFyaXMKKwlTUEVDSUFMCUAKKwlBVE9NCWZyYW5jZQorCVNQRUNJQUwJPgorVG86ICJDJ2VzdCBiaWVuIG1vY2hlIiA8cGFyaXNAPgorRXhwZWN0OiA1CisJUVVPVEVEU1RSSU5HCUMnZXN0IGJpZW4gbW9jaGUKKwlTUEVDSUFMCTwKKwlBVE9NCXBhcmlzCisJU1BFQ0lBTAlACisJU1BFQ0lBTAk+CitUbzogbGFib3Jpb3VzIGJ1dCAoQnVnIEZyZWUpCitFeHBlY3Q6IDIKKwlBVE9NCWxhYm9yaW91cworCUFUT00JYnV0CitUbzogdHdvQCAoSXQgV2lsbCBUYWtlKQorRXhwZWN0OiAyCisJQVRPTQl0d28KKwlTUEVDSUFMCUAKK1RvOiB0d29ACitFeHBlY3Q6IDIKKwlBVE9NCXR3bworCVNQRUNJQUwJQAorVG86IDxwYXJpc0BmcmFuY2UKK0V4cGVjdDogNAorCVNQRUNJQUwJPAorCUFUT00JcGFyaXMKKwlTUEVDSUFMCUAKKwlBVE9NCWZyYW5jZQorVG86IHBhcmlzQGZyYW5jZT4KK0V4cGVjdDogNAorCUFUT00JcGFyaXMKKwlTUEVDSUFMCUAKKwlBVE9NCWZyYW5jZQorCVNQRUNJQUwJPgorVG86IEBmcmFuY2UKK0V4cGVjdDogMgorCVNQRUNJQUwJQAorCUFUT00JZnJhbmNlCitUbzogQAorRXhwZWN0OiAxCisJU1BFQ0lBTAlACitUbzogPAorRXhwZWN0OiAxCisJU1BFQ0lBTAk8CitUbzogPgorRXhwZWN0OiAxCisJU1BFQ0lBTAk+CitDb21tZW50OgorCUknbSBub3Qgc3VyZSB0aGUgZm9sbG93aW5nIHNob3VsZCBiZSB2YWxpZC4KK1RvOiApCitFeHBlY3Q6IDEKKwlTUEVDSUFMCSkKK1RvOiBmcmllbmRzLWxpc3Q6O0BtYXN0b2Rvbi1DUy1CZXJrZWxleS1FRFUKK0V4cGVjdDogNQorCUFUT00JZnJpZW5kcy1saXN0CisJU1BFQ0lBTAk6CisJU1BFQ0lBTAk7CisJU1BFQ0lBTAlACisJQVRPTQltYXN0b2Rvbi1DUy1CZXJrZWxleS1FRFUKK0NvbW1lbnQ6CisJVGhlIGZvbGxvd2luZyBzaG91bGQgYWxsIGdlbmVyYXRlIGV4Y2VwdGlvbnMuCitUbzogIkMnZXN0IGJpZW4gbW9jaGUgPHBhcmlzQGZyYW5jZT4KK0V4cGVjdDogRXhjZXB0aW9uIGphdmF4Lm1haWwuaW50ZXJuZXQuUGFyc2VFeGNlcHRpb246IFVuYmFsYW5jZWQgcXVvdGVkIHN0cmluZworVG86IGNvbmZ1c2VkIChhYm91dCwgYmVpbmcsIGZyZW5jaAorRXhwZWN0OiBFeGNlcHRpb24gamF2YXgubWFpbC5pbnRlcm5ldC5QYXJzZUV4Y2VwdGlvbjogVW5iYWxhbmNlZCBjb21tZW50cworVG86IGl0QGlzIChicmlsbGlhbnQgKGdlbml1cywgYW5kIHN1cGVyYikKK0V4cGVjdDogRXhjZXB0aW9uIGphdmF4Lm1haWwuaW50ZXJuZXQuUGFyc2VFeGNlcHRpb246IFVuYmFsYW5jZWQgY29tbWVudHMKK1RvOiBpdEBpcyAoYnJpbGxpYW50IChnZW5pdXMpLCBhbmQgc3VwZXJiCitFeHBlY3Q6IEV4Y2VwdGlvbiBqYXZheC5tYWlsLmludGVybmV0LlBhcnNlRXhjZXB0aW9uOiBVbmJhbGFuY2VkIGNvbW1lbnRzCitUbzogaWZAeW91IChjb3VsZCwgc2VlIChhbG1vc3QsIGFzLCAoYmFkbHksIHlvdSB3b3VsZCkgYWdyZWUpCitFeHBlY3Q6IEV4Y2VwdGlvbiBqYXZheC5tYWlsLmludGVybmV0LlBhcnNlRXhjZXB0aW9uOiBVbmJhbGFuY2VkIGNvbW1lbnRzCitUbzogaWZAeW91IChjb3VsZCwgc2VlIChhbG1vc3QsIGFzLCAoYmFkbHksIHlvdSkgd291bGQpIGFncmVlCitFeHBlY3Q6IEV4Y2VwdGlvbiBqYXZheC5tYWlsLmludGVybmV0LlBhcnNlRXhjZXB0aW9uOiBVbmJhbGFuY2VkIGNvbW1lbnRzCitUbzogIgorRXhwZWN0OiBFeGNlcHRpb24gamF2YXgubWFpbC5pbnRlcm5ldC5QYXJzZUV4Y2VwdGlvbjogVW5iYWxhbmNlZCBxdW90ZWQgc3RyaW5nCitUbzogdHdvQHdlZWtzIChJdCBXaWxsIFRha2UKK0V4cGVjdDogRXhjZXB0aW9uIGphdmF4Lm1haWwuaW50ZXJuZXQuUGFyc2VFeGNlcHRpb246IFVuYmFsYW5jZWQgY29tbWVudHMKK1RvOiAoCitFeHBlY3Q6IEV4Y2VwdGlvbiBqYXZheC5tYWlsLmludGVybmV0LlBhcnNlRXhjZXB0aW9uOiBVbmJhbGFuY2VkIGNvbW1lbnRzCmRpZmYgLS1naXQgYS9tYWlsYXBpL3BvbS54bWwgYi9tYWlsYXBpL3BvbS54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGZhMWU5YwotLS0gL2Rldi9udWxsCisrKyBiL21haWxhcGkvcG9tLnhtbApAQCAtMCwwICsxLDIzMyBAQAorPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PgorPCEtLQorCisgICAgQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisKKyAgICBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAgICB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKworICAgIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAgICBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgICAgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgICAgdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisKKyAgICBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKworLS0+CisKKzwhLS0KKyAgICBUaGlzIHByb2plY3QgYnVpbGRzIHRoZSBKYXZhTWFpbCAibWFpbGFwaS5qYXIiIGZpbGUuICBUaGlzIGphciBmaWxlCisgICAgY29udGFpbnMgYSBmdWxseSBvcGVyYXRpb25hbCBKYXZhTWFpbCBpbXBsZW1lbnRhdGlvbiBidXQgd2l0aG91dCBhbnkKKyAgICBwcm90b2NvbCBwcm92aWRlcnMuICBJdCBjYW4gYmUgdXNlZCB3aXRoIHRoZSBzZXBhcmF0ZSBwcm90b2NvbCBwcm92aWRlcgorICAgIGphciBmaWxlcyAoZS5nLiwgc210cC5qYXIsIGltYXAuamFyKSB0byBwcm92aWRlIGEgZnVsbCBKYXZhTWFpbCBydW50aW1lCisgICAgaW1wbGVtZW50YXRpb24uCistLT4KKworPHByb2plY3QgeG1sbnM9Imh0dHA6Ly9tYXZlbi5hcGFjaGUub3JnL1BPTS80LjAuMCIKKwl4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIgorCXhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL21hdmVuLmFwYWNoZS5vcmcvUE9NLzQuMC4wCisJCQkgICAgaHR0cDovL21hdmVuLmFwYWNoZS5vcmcvbWF2ZW4tdjRfMF8wLnhzZCI+CisgICAgPHBhcmVudD4KKwk8Z3JvdXBJZD5jb20uc3VuLm1haWw8L2dyb3VwSWQ+CisJPGFydGlmYWN0SWQ+YWxsPC9hcnRpZmFjdElkPgorCTx2ZXJzaW9uPjEuNi4zPC92ZXJzaW9uPgorICAgIDwvcGFyZW50PgorICAgIDxtb2RlbFZlcnNpb24+NC4wLjA8L21vZGVsVmVyc2lvbj4KKyAgICA8Z3JvdXBJZD5jb20uc3VuLm1haWw8L2dyb3VwSWQ+CisgICAgPGFydGlmYWN0SWQ+bWFpbGFwaTwvYXJ0aWZhY3RJZD4KKyAgICA8cGFja2FnaW5nPmphcjwvcGFja2FnaW5nPgorICAgIDxuYW1lPkphdmFNYWlsIEFQSSAobm8gcHJvdmlkZXJzKTwvbmFtZT4KKworICAgIDxwcm9wZXJ0aWVzPgorCTxtYWlsLnBhY2thZ2VzLmV4cG9ydD4KKwkgICAgamF2YXgubWFpbC4qOyB2ZXJzaW9uPSR7bWFpbC5zcGVjLnZlcnNpb259LAorCSAgICBjb20uc3VuLm1haWwudXRpbDsgdmVyc2lvbj0ke21haWwub3NnaXZlcnNpb259LAorCSAgICBjb20uc3VuLm1haWwuYXV0aDsgdmVyc2lvbj0ke21haWwub3NnaXZlcnNpb259LAorCSAgICBjb20uc3VuLm1haWwuaGFuZGxlcnM7IHZlcnNpb249JHttYWlsLm9zZ2l2ZXJzaW9ufQorCTwvbWFpbC5wYWNrYWdlcy5leHBvcnQ+CisJPG1haWwuYnVuZGxlLnN5bWJvbGljTmFtZT4KKwkgICAgamFrYXJ0YS5tYWlsLmFwaQorCTwvbWFpbC5idW5kbGUuc3ltYm9saWNOYW1lPgorICAgIDwvcHJvcGVydGllcz4KKworICAgIDxwcm9maWxlcz4KKwk8IS0tCisJICAgIEEgc3BlY2lhbCBwcm9maWxlIGZvciBjb21waWxpbmcgd2l0aCB0aGUgcmVhbCBKREsgMS43IGNvbXBpbGVyLgorCSAgICBFeGNsdWRlIE1haWxTZXNzaW9uRGVmaW5pdGlvbiBhbmQgTWFpbFNlc3Npb25EZWZpbml0aW9ucyBzaW5jZQorCSAgICB0aGUgZm9ybWVyIHJlcXVpcmVzIEpESyAxLjggYW5kIHRoZSBsYXR0ZXIgZGVwZW5kcyBvbiB0aGUgZm9ybWVyLgorCS0tPgorCTxwcm9maWxlPgorCSAgICA8aWQ+MS43PC9pZD4KKwkgICAgPGJ1aWxkPgorCQk8cGx1Z2lucz4KKwkJICAgIDxwbHVnaW4+CisJCQk8YXJ0aWZhY3RJZD5tYXZlbi1jb21waWxlci1wbHVnaW48L2FydGlmYWN0SWQ+CisJCQk8ZXhlY3V0aW9ucz4KKwkJCSAgICA8ZXhlY3V0aW9uPgorCQkJCTxpZD5kZWZhdWx0LWNvbXBpbGU8L2lkPgorCQkJCTxjb25maWd1cmF0aW9uPgorCQkJCSAgICA8ZXhjbHVkZXM+CisJCQkJCTxleGNsdWRlPgorCQkJCQkgIGphdmF4L21haWwvTWFpbFNlc3Npb25EZWZpbml0aW9uLmphdmEKKwkJCQkJPC9leGNsdWRlPgorCQkJCQk8ZXhjbHVkZT4KKwkJCQkJICBqYXZheC9tYWlsL01haWxTZXNzaW9uRGVmaW5pdGlvbnMuamF2YQorCQkJCQk8L2V4Y2x1ZGU+CisJCQkJCTxleGNsdWRlPgorCQkJCQkgIG1vZHVsZS1pbmZvLmphdmEKKwkJCQkJPC9leGNsdWRlPgorCQkJCSAgICA8L2V4Y2x1ZGVzPgorCQkJCTwvY29uZmlndXJhdGlvbj4KKwkJCSAgICA8L2V4ZWN1dGlvbj4KKwkJCTwvZXhlY3V0aW9ucz4KKwkJICAgIDwvcGx1Z2luPgorCQk8L3BsdWdpbnM+CisJICAgIDwvYnVpbGQ+CisJPC9wcm9maWxlPgorCisJPCEtLQorCSAgICBBIHNwZWNpYWwgcHJvZmlsZSBmb3IgY29tcGlsaW5nIHdpdGggSkRLIDkuCisJLS0+CisJPHByb2ZpbGU+CisJICAgIDxpZD45PC9pZD4KKwkgICAgPGFjdGl2YXRpb24+CisJCTxqZGs+OTwvamRrPgorCSAgICA8L2FjdGl2YXRpb24+CisJICAgIDxidWlsZD4KKwkJPHBsdWdpbnM+CisJCSAgICA8cGx1Z2luPgorCQkJPGFydGlmYWN0SWQ+bWF2ZW4tY29tcGlsZXItcGx1Z2luPC9hcnRpZmFjdElkPgorCQkJPGV4ZWN1dGlvbnM+CisJCQkgICAgPGV4ZWN1dGlvbj4KKwkJCQk8aWQ+ZGVmYXVsdC1jb21waWxlPC9pZD4KKwkJCQk8Y29uZmlndXJhdGlvbj4KKwkJCQkgICAgPHJlbGVhc2U+OTwvcmVsZWFzZT4KKwkJCQkgICAgPHNvdXJjZT45PC9zb3VyY2U+CisJCQkJICAgIDx0YXJnZXQ+OTwvdGFyZ2V0PgorCQkJCSAgICA8Y29tcGlsZXJBcmdzPgorCQkJCQk8YXJnPi1YbGludDwvYXJnPgorCQkJCQk8YXJnPi1YbGludDotb3B0aW9uczwvYXJnPgorCQkJCQk8YXJnPi1YbGludDotcGF0aDwvYXJnPgorCQkJCQk8IS0tCisJCQkJCSAgICBUb28gbWFueSBmaW5hbGl6ZSB3YXJuaW5ncy4KKwkJCQkJPGFyZz4tV2Vycm9yPC9hcmc+CisJCQkJCS0tPgorCQkJCSAgICA8L2NvbXBpbGVyQXJncz4KKwkJCQkgICAgPCEtLSB1bi1leGNsdWRlIG1vZHVsZS1pbmZvLmphdmEgLS0+CisJCQkJICAgIDxleGNsdWRlcyBjb21iaW5lLnNlbGY9Im92ZXJyaWRlIj4KKwkJCQkgICAgPC9leGNsdWRlcz4KKwkJCQk8L2NvbmZpZ3VyYXRpb24+CisJCQkgICAgPC9leGVjdXRpb24+CisJCQk8L2V4ZWN1dGlvbnM+CisJCSAgICA8L3BsdWdpbj4KKwkJICAgIDwhLS0KKwkJCVJlcXVpcmUgSkRLIDkuCisJCSAgICAtLT4KKwkJICAgIDxwbHVnaW4+CisJCQk8Z3JvdXBJZD5vcmcuYXBhY2hlLm1hdmVuLnBsdWdpbnM8L2dyb3VwSWQ+CisJCQk8YXJ0aWZhY3RJZD5tYXZlbi1lbmZvcmNlci1wbHVnaW48L2FydGlmYWN0SWQ+CisJCQk8ZXhlY3V0aW9ucz4KKwkJCSAgICA8ZXhlY3V0aW9uPgorCQkJCTxpZD5lbmZvcmNlLXZlcnNpb248L2lkPgorCQkJCTxnb2Fscz4KKwkJCQkgICAgPGdvYWw+ZW5mb3JjZTwvZ29hbD4KKwkJCQk8L2dvYWxzPgorCQkJCTxjb25maWd1cmF0aW9uPgorCQkJCSAgICA8cnVsZXM+CisJCQkJCTxyZXF1aXJlTWF2ZW5WZXJzaW9uPgorCQkJCQkgICAgPHZlcnNpb24+WzMuMC4zLCk8L3ZlcnNpb24+CisJCQkJCTwvcmVxdWlyZU1hdmVuVmVyc2lvbj4KKwkJCQkJPHJlcXVpcmVKYXZhVmVyc2lvbj4KKwkJCQkJICAgIDx2ZXJzaW9uPjk8L3ZlcnNpb24+CisJCQkJCTwvcmVxdWlyZUphdmFWZXJzaW9uPgorCQkJCSAgICA8L3J1bGVzPgorCQkJCTwvY29uZmlndXJhdGlvbj4KKwkJCSAgICA8L2V4ZWN1dGlvbj4KKwkJCTwvZXhlY3V0aW9ucz4KKwkJICAgIDwvcGx1Z2luPgorCQk8L3BsdWdpbnM+CisJICAgIDwvYnVpbGQ+CisJPC9wcm9maWxlPgorICAgIDwvcHJvZmlsZXM+CisKKyAgICA8YnVpbGQ+CisJPHBsdWdpbnM+CisJICAgIDxwbHVnaW4+CisJCTxhcnRpZmFjdElkPm1hdmVuLWRlcGVuZGVuY3ktcGx1Z2luPC9hcnRpZmFjdElkPgorCQk8ZXhlY3V0aW9ucz4KKwkJICAgIDxleGVjdXRpb24+CisJCQk8IS0tIGRvd25sb2FkIHRoZSBiaW5hcmllcyAtLT4KKwkJCTxpZD5nZXQtYmluYXJpZXM8L2lkPgorCQkJPHBoYXNlPmdlbmVyYXRlLXNvdXJjZXM8L3BoYXNlPgorCQkJPGdvYWxzPgorCQkJICAgIDxnb2FsPnVucGFjazwvZ29hbD4KKwkJCTwvZ29hbHM+CisJCSAgICA8L2V4ZWN1dGlvbj4KKwkJICAgIDxleGVjdXRpb24+CisJCQk8IS0tIGRvd25sb2FkIHRoZSBzb3VyY2VzIC0tPgorCQkJPGlkPmdldC1zb3VyY2VzPC9pZD4KKwkJCTxwaGFzZT5nZW5lcmF0ZS1zb3VyY2VzPC9waGFzZT4KKwkJCTxnb2Fscz4KKwkJCSAgICA8Z29hbD51bnBhY2s8L2dvYWw+CisJCQk8L2dvYWxzPgorCQkJPGNvbmZpZ3VyYXRpb24+CisJCQkgICAgPGFydGlmYWN0SXRlbXM+CisJCQkJPGFydGlmYWN0SXRlbT4KKwkJCQkgICAgPGdyb3VwSWQ+Y29tLnN1bi5tYWlsPC9ncm91cElkPgorCQkJCSAgICA8YXJ0aWZhY3RJZD5qYWthcnRhLm1haWw8L2FydGlmYWN0SWQ+CisJCQkJICAgIDx2ZXJzaW9uPiR7bWFpbC52ZXJzaW9ufTwvdmVyc2lvbj4KKwkJCQkgICAgPGNsYXNzaWZpZXI+c291cmNlczwvY2xhc3NpZmllcj4KKwkJCQkgICAgPG91dHB1dERpcmVjdG9yeT4KKwkJCQkJJHtwcm9qZWN0LmJ1aWxkLmRpcmVjdG9yeX0vc291cmNlcworCQkJCSAgICA8L291dHB1dERpcmVjdG9yeT4KKwkJCQk8L2FydGlmYWN0SXRlbT4KKwkJCSAgICA8L2FydGlmYWN0SXRlbXM+CisJCQk8L2NvbmZpZ3VyYXRpb24+CisJCSAgICA8L2V4ZWN1dGlvbj4KKwkJPC9leGVjdXRpb25zPgorCQk8Y29uZmlndXJhdGlvbj4KKwkJICAgIDxhcnRpZmFjdEl0ZW1zPgorCQkJPGFydGlmYWN0SXRlbT4KKwkJCSAgICA8Z3JvdXBJZD5jb20uc3VuLm1haWw8L2dyb3VwSWQ+CisJCQkgICAgPGFydGlmYWN0SWQ+amFrYXJ0YS5tYWlsPC9hcnRpZmFjdElkPgorCQkJICAgIDx2ZXJzaW9uPiR7bWFpbC52ZXJzaW9ufTwvdmVyc2lvbj4KKwkJCTwvYXJ0aWZhY3RJdGVtPgorCQkgICAgPC9hcnRpZmFjdEl0ZW1zPgorCQkgICAgPG91dHB1dERpcmVjdG9yeT4KKwkJCSR7cHJvamVjdC5idWlsZC5vdXRwdXREaXJlY3Rvcnl9CisJCSAgICA8L291dHB1dERpcmVjdG9yeT4KKwkJICAgIDxpbmNsdWRlcz4KKwkJCWphdmF4LyoqLAorCQkJY29tL3N1bi9tYWlsL3V0aWwvKiosCisJCQljb20vc3VuL21haWwvYXV0aC8qKiwKKwkJCWNvbS9zdW4vbWFpbC9oYW5kbGVycy8qKiwKKwkJCU1FVEEtSU5GLyoKKwkJICAgIDwvaW5jbHVkZXM+CisJCSAgICA8IS0tCisJCQlIYXZlIHRvIGV4Y2x1ZGUgcGFja2FnZS5odG1sIGJlY2F1c2UgaXQgbGlua3MgdG8KKwkJCWNvbS5zdW4ubWFpbC57aW1hcCxwb3AzLHNtdHB9IHBhY2thZ2VzIGFuZCBqZGsgOQorCQkJamF2YWRvYyBmYWlscyB0aGF0IGR1cmluZyBkZXBsb3kuCisJCSAgICAtLT4KKwkJICAgIDxleGNsdWRlcz4KKwkJCWphdmF4L21haWwvcGFja2FnZS5odG1sLAorCQkJY29tL3N1bi9tYWlsL3V0aWwvbG9nZ2luZy8qKiwKKwkJCU1FVEEtSU5GL2phdmFtYWlsLmRlZmF1bHQuKgorCQkgICAgPC9leGNsdWRlcz4KKwkJPC9jb25maWd1cmF0aW9uPgorCSAgICA8L3BsdWdpbj4KKwkgICAgPHBsdWdpbj4KKwkJPGFydGlmYWN0SWQ+bWF2ZW4tamFyLXBsdWdpbjwvYXJ0aWZhY3RJZD4KKwkJPGNvbmZpZ3VyYXRpb24+CisJCSAgICA8ZmluYWxOYW1lPiR7cHJvamVjdC5hcnRpZmFjdElkfTwvZmluYWxOYW1lPgorCQkgICAgPGFyY2hpdmU+CisJCQk8bWFuaWZlc3RGaWxlPgorCQkJICAke3Byb2plY3QuYnVpbGQub3V0cHV0RGlyZWN0b3J5fS9NRVRBLUlORi9NQU5JRkVTVC5NRgorCQkJPC9tYW5pZmVzdEZpbGU+CisJCSAgICA8L2FyY2hpdmU+CisJCTwvY29uZmlndXJhdGlvbj4KKwkgICAgPC9wbHVnaW4+CisJPC9wbHVnaW5zPgorICAgIDwvYnVpbGQ+Cis8L3Byb2plY3Q+CmRpZmYgLS1naXQgYS9tYWlsYXBpL3NyYy9tYWluL2phdmEvbW9kdWxlLWluZm8uamF2YSBiL21haWxhcGkvc3JjL21haW4vamF2YS9tb2R1bGUtaW5mby5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc2ZjlmM2UKLS0tIC9kZXYvbnVsbAorKysgYi9tYWlsYXBpL3NyYy9tYWluL2phdmEvbW9kdWxlLWluZm8uamF2YQpAQCAtMCwwICsxLDMzIEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCittb2R1bGUgamFrYXJ0YS5tYWlsIHsKKyAgICBleHBvcnRzIGphdmF4Lm1haWw7CisgICAgZXhwb3J0cyBqYXZheC5tYWlsLmV2ZW50OworICAgIGV4cG9ydHMgamF2YXgubWFpbC5pbnRlcm5ldDsKKyAgICBleHBvcnRzIGphdmF4Lm1haWwuc2VhcmNoOworICAgIGV4cG9ydHMgamF2YXgubWFpbC51dGlsOworICAgIGV4cG9ydHMgY29tLnN1bi5tYWlsLnV0aWw7CisgICAgZXhwb3J0cyBjb20uc3VuLm1haWwuYXV0aDsKKyAgICBleHBvcnRzIGNvbS5zdW4ubWFpbC5oYW5kbGVyczsKKworICAgIHJlcXVpcmVzIHRyYW5zaXRpdmUgamFrYXJ0YS5hY3RpdmF0aW9uOworICAgIHJlcXVpcmVzIGphdmEubG9nZ2luZzsKKyAgICByZXF1aXJlcyBqYXZhLnhtbDsJCS8vIGZvciB0ZXh0L3htbCBoYW5kbGVyCisgICAgcmVxdWlyZXMgamF2YS5kZXNrdG9wOwkvLyBmb3IgaW1hZ2UvanBlZyBoYW5kbGVyCisgICAgcmVxdWlyZXMgamF2YS5zZWN1cml0eS5zYXNsOyAvLyBmb3IgT0F1dGgyIHN1cHBvcnQKKyAgICB1c2VzIGphdmF4Lm1haWwuUHJvdmlkZXI7Cit9CmRpZmYgLS1naXQgYS9tYWlsYXBpamFyL3BvbS54bWwgYi9tYWlsYXBpamFyL3BvbS54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzVhZmZkMQotLS0gL2Rldi9udWxsCisrKyBiL21haWxhcGlqYXIvcG9tLnhtbApAQCAtMCwwICsxLDExOSBAQAorPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PgorPCEtLQorCisgICAgQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisKKyAgICBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAgICB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKworICAgIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAgICBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgICAgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgICAgdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisKKyAgICBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKworLS0+CisKKzwhLS0KKyAgICBUaGlzIHByb2plY3QgYnVpbGRzIHRoZSBKYXZhTWFpbCBBUEkgamFyIGZpbGUsIHdoaWNoIGNvbnRhaW5zIG9ubHkKKyAgICB0aGUgamF2YXgubWFpbC4qIEFQSSBkZWZpbml0aW9ucyBhbmQgaXMgKm9ubHkqIGludGVuZGVkIHRvIGJlIHVzZWQKKyAgICBmb3IgcHJvZ3JhbXMgdG8gY29tcGlsZSBhZ2FpbnN0LiAgTm90ZSB0aGF0IGl0IGluY2x1ZGVzIG5vbmUgb2YgdGhlCisgICAgaW1wbGVtZW50YXRpb24tc3BlY2lmaWMgY2xhc3NlcyB0aGF0IHRoZSBqYXZheC5tYWlsLiogY2xhc3NlcyByZWx5IG9uLgorLS0+CisKKzxwcm9qZWN0IHhtbG5zPSJodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9QT00vNC4wLjAiCisJeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIKKwl4c2k6c2NoZW1hTG9jYXRpb249Imh0dHA6Ly9tYXZlbi5hcGFjaGUub3JnL1BPTS80LjAuMAorCQkJICAgIGh0dHA6Ly9tYXZlbi5hcGFjaGUub3JnL21hdmVuLXY0XzBfMC54c2QiPgorICAgIDxwYXJlbnQ+CisJPGdyb3VwSWQ+Y29tLnN1bi5tYWlsPC9ncm91cElkPgorCTxhcnRpZmFjdElkPmFsbDwvYXJ0aWZhY3RJZD4KKwk8dmVyc2lvbj4xLjYuMzwvdmVyc2lvbj4KKyAgICA8L3BhcmVudD4KKyAgICA8bW9kZWxWZXJzaW9uPjQuMC4wPC9tb2RlbFZlcnNpb24+CisgICAgPGdyb3VwSWQ+amFrYXJ0YS5tYWlsPC9ncm91cElkPgorICAgIDxhcnRpZmFjdElkPmpha2FydGEubWFpbC1hcGk8L2FydGlmYWN0SWQ+CisgICAgPHBhY2thZ2luZz5qYXI8L3BhY2thZ2luZz4KKyAgICA8bmFtZT5KYXZhTWFpbCBBUEkgamFyPC9uYW1lPgorCisgICAgPHByb3BlcnRpZXM+CisJPG1haWwuZXh0ZW5zaW9uTmFtZT4KKwkgICAgamFrYXJ0YS5tYWlsCisJPC9tYWlsLmV4dGVuc2lvbk5hbWU+CisJPG1haWwucGFja2FnZXMuZXhwb3J0PgorCSAgICBqYXZheC5tYWlsLio7IHZlcnNpb249JHttYWlsLnNwZWMudmVyc2lvbn0KKwk8L21haWwucGFja2FnZXMuZXhwb3J0PgorCTxtYWlsLmJ1bmRsZS5zeW1ib2xpY05hbWU+CisJICAgIGpha2FydGEubWFpbC1hcGkKKwk8L21haWwuYnVuZGxlLnN5bWJvbGljTmFtZT4KKyAgICA8L3Byb3BlcnRpZXM+CisKKyAgICA8YnVpbGQ+CisgICAgICAgIDxwbHVnaW5zPgorCSAgICA8cGx1Z2luPgorCQk8YXJ0aWZhY3RJZD5tYXZlbi1kZXBlbmRlbmN5LXBsdWdpbjwvYXJ0aWZhY3RJZD4KKwkJPGV4ZWN1dGlvbnM+CisJCSAgICA8ZXhlY3V0aW9uPgorCQkJPCEtLSBkb3dubG9hZCB0aGUgYmluYXJpZXMgLS0+CisJCQk8aWQ+Z2V0LWJpbmFyaWVzPC9pZD4KKwkJCTxwaGFzZT5jb21waWxlPC9waGFzZT4KKwkJCTxnb2Fscz4KKwkJCSAgICA8Z29hbD51bnBhY2s8L2dvYWw+CisJCQk8L2dvYWxzPgorCQkgICAgPC9leGVjdXRpb24+CisJCSAgICA8ZXhlY3V0aW9uPgorCQkJPCEtLSBkb3dubG9hZCB0aGUgc291cmNlcyAtLT4KKwkJCTxpZD5nZXQtc291cmNlczwvaWQ+CisJCQk8cGhhc2U+Y29tcGlsZTwvcGhhc2U+CisJCQk8Z29hbHM+CisJCQkgICAgPGdvYWw+dW5wYWNrPC9nb2FsPgorCQkJPC9nb2Fscz4KKwkJCTxjb25maWd1cmF0aW9uPgorCQkJICAgIDxhcnRpZmFjdEl0ZW1zPgorCQkJCTxhcnRpZmFjdEl0ZW0+CisJCQkJICAgIDxncm91cElkPmNvbS5zdW4ubWFpbDwvZ3JvdXBJZD4KKwkJCQkgICAgPGFydGlmYWN0SWQ+amFrYXJ0YS5tYWlsPC9hcnRpZmFjdElkPgorCQkJCSAgICA8dmVyc2lvbj4ke21haWwudmVyc2lvbn08L3ZlcnNpb24+CisJCQkJICAgIDxjbGFzc2lmaWVyPnNvdXJjZXM8L2NsYXNzaWZpZXI+CisJCQkJICAgIDxvdXRwdXREaXJlY3Rvcnk+CisJCQkJCSR7cHJvamVjdC5idWlsZC5kaXJlY3Rvcnl9L3NvdXJjZXMKKwkJCQkgICAgPC9vdXRwdXREaXJlY3Rvcnk+CisJCQkJPC9hcnRpZmFjdEl0ZW0+CisJCQkgICAgPC9hcnRpZmFjdEl0ZW1zPgorCQkJPC9jb25maWd1cmF0aW9uPgorCQkgICAgPC9leGVjdXRpb24+CisJCTwvZXhlY3V0aW9ucz4KKwkJPGNvbmZpZ3VyYXRpb24+CisJCSAgICA8YXJ0aWZhY3RJdGVtcz4KKwkJCTxhcnRpZmFjdEl0ZW0+CisJCQkgICAgPGdyb3VwSWQ+Y29tLnN1bi5tYWlsPC9ncm91cElkPgorCQkJICAgIDxhcnRpZmFjdElkPmpha2FydGEubWFpbDwvYXJ0aWZhY3RJZD4KKwkJCSAgICA8dmVyc2lvbj4ke21haWwudmVyc2lvbn08L3ZlcnNpb24+CisJCQk8L2FydGlmYWN0SXRlbT4KKwkJICAgIDwvYXJ0aWZhY3RJdGVtcz4KKwkJICAgIDxvdXRwdXREaXJlY3Rvcnk+CisJCQkke3Byb2plY3QuYnVpbGQub3V0cHV0RGlyZWN0b3J5fQorCQkgICAgPC9vdXRwdXREaXJlY3Rvcnk+CisJCSAgICA8aW5jbHVkZXM+CisJCQlqYXZheC8qKiwKKwkJCU1FVEEtSU5GL0xJQ0VOU0UudHh0CisJCSAgICA8L2luY2x1ZGVzPgorCQk8L2NvbmZpZ3VyYXRpb24+CisJICAgIDwvcGx1Z2luPgorCSAgICA8cGx1Z2luPgorCQk8YXJ0aWZhY3RJZD5tYXZlbi1qYXItcGx1Z2luPC9hcnRpZmFjdElkPgorCQk8Y29uZmlndXJhdGlvbj4KKwkJICAgIDxmaW5hbE5hbWU+JHtwcm9qZWN0LmFydGlmYWN0SWR9PC9maW5hbE5hbWU+CisJCSAgICA8YXJjaGl2ZT4KKwkJCTxtYW5pZmVzdEZpbGU+CisJCQkgICR7cHJvamVjdC5idWlsZC5vdXRwdXREaXJlY3Rvcnl9L01FVEEtSU5GL01BTklGRVNULk1GCisJCQk8L21hbmlmZXN0RmlsZT4KKwkJICAgIDwvYXJjaGl2ZT4KKwkJPC9jb25maWd1cmF0aW9uPgorCSAgICA8L3BsdWdpbj4KKyAgICAgICAgPC9wbHVnaW5zPgorICAgIDwvYnVpbGQ+Cis8L3Byb2plY3Q+CmRpZmYgLS1naXQgYS9tYWlsaGFuZGxlci9wb20ueG1sIGIvbWFpbGhhbmRsZXIvcG9tLnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kYzhhYWFhCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbGhhbmRsZXIvcG9tLnhtbApAQCAtMCwwICsxLDQzIEBACis8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJpc28tODg1OS0xIj8+Cis8IS0tCisKKyAgICBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKworICAgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICAgIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorCisgICAgVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICAgIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAgICBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAgICB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKworICAgIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorCistLT4KKworPHByb2plY3QgeG1sbnM9Imh0dHA6Ly9tYXZlbi5hcGFjaGUub3JnL1BPTS80LjAuMCIKKwl4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIgorCXhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL21hdmVuLmFwYWNoZS5vcmcvUE9NLzQuMC4wCisJCQkgICAgaHR0cDovL21hdmVuLmFwYWNoZS5vcmcvbWF2ZW4tdjRfMF8wLnhzZCI+CisgICAgPHBhcmVudD4KKwk8Z3JvdXBJZD5jb20uc3VuLm1haWw8L2dyb3VwSWQ+CisJPGFydGlmYWN0SWQ+cGFyZW50LWRpc3RyaWI8L2FydGlmYWN0SWQ+CisJPHZlcnNpb24+MS42LjM8L3ZlcnNpb24+CisJPHJlbGF0aXZlUGF0aD4uLi9wYXJlbnQtZGlzdHJpYi9wb20ueG1sPC9yZWxhdGl2ZVBhdGg+CisgICAgPC9wYXJlbnQ+CisgICAgPG1vZGVsVmVyc2lvbj40LjAuMDwvbW9kZWxWZXJzaW9uPgorICAgIDxncm91cElkPmNvbS5zdW4ubWFpbDwvZ3JvdXBJZD4KKyAgICA8YXJ0aWZhY3RJZD5sb2dnaW5nLW1haWxoYW5kbGVyPC9hcnRpZmFjdElkPgorICAgIDxwYWNrYWdpbmc+amFyPC9wYWNrYWdpbmc+CisgICAgPG5hbWU+SmF2YU1haWwgQVBJIGxvZ2dpbmcgaGFuZGxlcjwvbmFtZT4KKworICAgIDxwcm9wZXJ0aWVzPgorCTxtYWlsLnBhY2thZ2VzLmV4cG9ydD4KKwkgICAgY29tLnN1bi5tYWlsLnV0aWwubG9nZ2luZzsgdmVyc2lvbj0ke21haWwub3NnaXZlcnNpb259CisJPC9tYWlsLnBhY2thZ2VzLmV4cG9ydD4KKwk8bWFpbC5jbGFzc2VzPmNvbS9zdW4vbWFpbC91dGlsL2xvZ2dpbmcvKio8L21haWwuY2xhc3Nlcz4KKyAgICA8L3Byb3BlcnRpZXM+CisKKzwvcHJvamVjdD4KZGlmZiAtLWdpdCBhL21haWxoYW5kbGVyL3NyYy9tYWluL2phdmEvbW9kdWxlLWluZm8uamF2YSBiL21haWxoYW5kbGVyL3NyYy9tYWluL2phdmEvbW9kdWxlLWluZm8uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNjhjOGUwCi0tLSAvZGV2L251bGwKKysrIGIvbWFpbGhhbmRsZXIvc3JjL21haW4vamF2YS9tb2R1bGUtaW5mby5qYXZhCkBAIC0wLDAgKzEsMjIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK21vZHVsZSBjb20uc3VuLm1haWwudXRpbC5sb2dnaW5nIHsKKyAgICBleHBvcnRzIGNvbS5zdW4ubWFpbC51dGlsLmxvZ2dpbmc7CisKKyAgICByZXF1aXJlcyBqYWthcnRhLm1haWw7CisgICAgcmVxdWlyZXMgamF2YS5sb2dnaW5nOworfQpkaWZmIC0tZ2l0IGEvbWJveC54bWwgYi9tYm94LnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZWU5Njg1Ci0tLSAvZGV2L251bGwKKysrIGIvbWJveC54bWwKQEAgLTAsMCArMSwyMDYgQEAKKzw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9Imlzby04ODU5LTEiPz4KKzwhLS0KKworICAgIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorCisgICAgVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgICAgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisKKyAgICBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgICAgTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICAgIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICAgIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorCisgICAgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisKKy0tPgorCis8IURPQ1RZUEUgcHJvamVjdCBbCisgIDwhRU5USVRZIGNvbW1vbkJ1aWxkIFNZU1RFTSAiYW50LWNvbW1vbi54bWwiPgorXT4KKzxwcm9qZWN0IG5hbWU9IkphdmFNYWlsIiBkZWZhdWx0PSJhbGwiIGJhc2VkaXI9Ii4iCisJeG1sbnM6Y3BwdGFza3M9ImFudGxpYjpvcmcuc2YubmV0LmFudGNvbnRyaWIuY3BwdGFza3MiPgorCisgICAgPHRhc2tkZWYgcmVzb3VyY2U9ImNwcHRhc2tzLnRhc2tzIi8+CisgICAgPHR5cGVkZWYgcmVzb3VyY2U9ImNwcHRhc2tzLnR5cGVzIi8+CisKKzwhLS0gPT09PT09PT09PSBJbml0aWFsaXplIFByb3BlcnRpZXMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gLS0+CisKKyAgICA8IS0tCisgICAgICAgIGNvbXBvbmVudC5uYW1lOiByZXF1aXJlZCBwcm9wZXJ0eS4gIHRoZSB2YWx1ZSBzaG91bGQgYmUgdGhlCisgICAgICAgICAgICAgICAgICAgICAgICBuYW1lIG9mIHRoZSBjb21wb25lbnQgZGlyZWN0b3J5CisgICAgLS0+CisgICAgPHByb3BlcnR5IG5hbWU9ImNvbXBvbmVudC5uYW1lIiB2YWx1ZT0ibWJveCIvPgorCisgICAgPHByb3BlcnR5IGZpbGU9Ii4vYnVpbGQucHJvcGVydGllcyIvPgorCisgICAgPHByb3BlcnR5IG5hbWU9ImNjLmRlYnVnIiB2YWx1ZT0iZmFsc2UiLz4KKyAgICA8cHJvcGVydHkgbmFtZT0iZ2VuZXJhdGVkLmRpciIgdmFsdWU9Im1ib3gvdGFyZ2V0L2dlbmVyYXRlZCIvPgorICAgIDxwcm9wZXJ0eSBuYW1lPSJvYmouZGlyIiB2YWx1ZT0ibWJveC90YXJnZXQvbmF0aXZlLyR7b3MubmFtZX0tJHtvcy5hcmNofSIvPgorICAgIDxwcm9wZXJ0eSBuYW1lPSJsaWIuZGlyIiB2YWx1ZT0ibWJveC90YXJnZXQvbGliLyR7b3MubmFtZX0tJHtvcy5hcmNofSIvPgorICAgIDxjb25kaXRpb24gcHJvcGVydHk9ImlzLXNvbGFyaXMiPgorCTxvcyBuYW1lPSJTdW5PUyIvPgorICAgIDwvY29uZGl0aW9uPgorICAgIAorICAgICZjb21tb25CdWlsZDsKKworICAgIDwhLS0gYWxsIC0tPgorICAgIDx0YXJnZXQgbmFtZT0iYWxsIiBkZXBlbmRzPSJtYm94Y29tcGlsZSwgbWJveGNjLCBtYm94amFyIgorICAgICAgICAgICAgZGVzY3JpcHRpb249IkJ1aWxkIGVudGlyZSBtYm94IGNvbXBvbmVudCI+CisgICAgPC90YXJnZXQ+CisKKyAgICA8IS0tIGJ1aWxkIC0tPgorICAgIDx0YXJnZXQgbmFtZT0iYnVpbGQiIGRlcGVuZHM9Im1ib3hjb21waWxlLCBtYm94Y2MsIG1ib3hqYXIiCisgICAgICAgICAgICBkZXNjcmlwdGlvbj0iQnVpbGQgZW50aXJlIG1ib3ggY29tcG9uZW50Ij4KKyAgICA8L3RhcmdldD4KKworICAgIDwhLS0gaW5pdC4gSW5pdGlhbGl6YXRpb24gaW52b2x2ZXMgY3JlYXRpbmcgcHVibGlzaGluZyBkaXJlY3RvcmllcyBhbmQKKyAgICAgICAgIE9TIHNwZWNpZmljIHRhcmdldHMuIC0tPgorICAgIDx0YXJnZXQgbmFtZT0iaW5pdCIgZGVzY3JpcHRpb249IiR7Y29tcG9uZW50Lm5hbWV9IGluaXRpYWxpemF0aW9uIj4KKyAgICAgICAgPHRzdGFtcD4KKyAgICAgICAgICAgIDxmb3JtYXQgcHJvcGVydHk9InN0YXJ0LnRpbWUiIHBhdHRlcm49Ik1NL2RkL3l5eXkgaGg6bW0gYWEiLz4KKyAgICAgICAgPC90c3RhbXA+CisgICAgICAgIDxlY2hvIG1lc3NhZ2U9IkJ1aWxkaW5nIGNvbXBvbmVudCAke2NvbXBvbmVudC5uYW1lfSIvPgorICAgICAgICA8bWtkaXIgZGlyPSIke2NvbXBvbmVudC5jbGFzc2VzLm1ib3guZGlyfSIvPgorICAgICAgICA8bWtkaXIgZGlyPSIke2dlbmVyYXRlZC5kaXJ9Ii8+CisgICAgICAgIDxta2RpciBkaXI9IiR7b2JqLmRpcn0iLz4KKyAgICAgICAgPG1rZGlyIGRpcj0iJHtsaWIuZGlyfSIvPgorICAgIDwvdGFyZ2V0PgorCisgICAgPCEtLSBwcmVwYXJlIG1hbmlmZXN0IGZpbGVzIGZvciBqYXJzIC0tPgorICAgIDx0YXJnZXQgbmFtZT0iY29vay1tYW5pZmVzdCIgZGVwZW5kcz0iaW5pdCIKKyAgICAgICAgICAgIGRlc2NyaXB0aW9uPSJHZW5lcmF0ZSBNQU5JRkVTVC5NRiBmaWxlcyI+CisgICAgICAgIDxta2RpciBkaXI9IiR7Y29tcG9uZW50LmNsYXNzZXMubWJveC5kaXJ9L21hbmlmZXN0Ii8+CisgICAgICAgIDxjb3B5IGZpbGU9IiR7cmVzb3VyY2VzLm1ib3guZGlyfS9NRVRBLUlORi9NQU5JRkVTVC5NRiIKKwkJdG9maWxlPSIke2NvbXBvbmVudC5jbGFzc2VzLm1ib3guZGlyfS9tYW5pZmVzdC9NQU5JRkVTVC5NRiI+CisgICAgICAgICAgICA8ZmlsdGVyc2V0IGJlZ2ludG9rZW49InsiIGVuZHRva2VuPSJ9Ij4KKwkJPGZpbHRlciB0b2tlbj0ibWFpbC5zcGVjLnZlcnNpb24iCisJCSAgICB2YWx1ZT0iJHtyZWxlYXNlLnNwZWN2ZXJzaW9ufSIvPgorCQk8ZmlsdGVyIHRva2VuPSJtYWlsLnZlcnNpb24iIHZhbHVlPSIke3JlbGVhc2UudmVyc2lvbn0iLz4KKyAgICAgICAgICAgIDwvZmlsdGVyc2V0PgorICAgICAgICA8L2NvcHk+CisgICAgPC90YXJnZXQ+CisKKyAgICA8IS0tIG1ib3ggY29tcGlsZSAtLT4KKyAgICA8dGFyZ2V0IG5hbWU9Im1ib3hjb21waWxlIiBkZXBlbmRzPSJpbml0IgorICAgICAgICAgICAgZGVzY3JpcHRpb249IkNvbXBpbGUgY29tL3N1bi9tYWlsL21ib3ggc291cmNlcyI+CisKKyAgICAgICAgPGphdmFjIHNyY2Rpcj0iJHtzcmMubWJveC5kaXJ9IgorICAgICAgICAgICAgICAgZGVzdGRpcj0iJHtjb21wb25lbnQuY2xhc3Nlcy5tYm94LmRpcn0iCisgICAgICAgICAgICAgICBkZWJ1Zz0iJHtqYXZhYy5kZWJ1Z30iCisgICAgICAgICAgICAgICBvcHRpbWl6ZT0iJHtqYXZhYy5vcHRpbWl6ZX0iCisgICAgICAgICAgICAgICBzb3VyY2U9IiR7amF2YWMuc291cmNlfSIKKyAgICAgICAgICAgICAgIGRlcHJlY2F0aW9uPSIke2phdmFjLmRlcHJlY2F0aW9ufSIKKyAgICAgICAgICAgICAgIGZhaWxvbmVycm9yPSJ0cnVlIgorICAgICAgICAgICAgICAgdGFyZ2V0PSIke2phdmFjLnRhcmdldH0iPgorICAgICAgICAgICAgPGNsYXNzcGF0aD4KKyAgICAgICAgICAgICAgICA8cGF0aGVsZW1lbnQgbG9jYXRpb249IiR7Y29tcG9uZW50LmNsYXNzZXMuZGlyfSIvPgorICAgICAgICAgICAgICAgIDxwYXRoZWxlbWVudCBsb2NhdGlvbj0iJHthY3RpdmF0aW9uLmphcn0iLz4KKyAgICAgICAgICAgIDwvY2xhc3NwYXRoPgorCSAgICA8IS0tCisgICAgICAgICAgICA8aW5jbHVkZSBuYW1lPSJjb20vc3VuL21haWwvbWJveC8qKiIvPgorCSAgICAtLT4KKyAgICAgICAgPC9qYXZhYz4KKyAgICA8L3RhcmdldD4KKworICAgIDx0YXJnZXQgbmFtZT0ibWJveGhlYWRlcnMiIGRlcGVuZHM9Im1ib3hjb21waWxlIj4KKwk8amF2YWggZGVzdGRpcj0iJHtnZW5lcmF0ZWQuZGlyfSIKKwkJZm9yY2U9InllcyIKKwkJdmVyYm9zZT0ieWVzIgorCQljbGFzc3BhdGg9IiR7Y29tcG9uZW50LmNsYXNzZXMubWJveC5kaXJ9OiR7Y29tcG9uZW50LmNsYXNzZXMuZGlyfSI+CisgICAgICAgICAgICA8Y2xhc3MgbmFtZT0iY29tLnN1bi5tYWlsLm1ib3guVU5JWEZpbGUiLz4KKyAgICAgICAgICAgIDxjbGFzcyBuYW1lPSJjb20uc3VuLm1haWwubWJveC5VTklYSW5ib3giLz4KKwk8L2phdmFoPgorICAgIDwvdGFyZ2V0PgorCisgICAgPHRhcmdldCBuYW1lPSJtYm94Y2MiIGRlcGVuZHM9Im1ib3hoZWFkZXJzLCBtYm94Y2Mtc29sYXJpcyIvPgorCisgICAgPCEtLQorICAgIG1ha2UtYmFzZWQgYnVpbGQgdXNlcyB0aGVzZSBjb21waWxlciBhbmQgbGlua2VyIG9wdGlvbnM6CisKKyAgICBjYyAtWGEgLXhPMiAtdiAtRF9SRUVOVFJBTlQgICAtRHNwYXJjIC1EU09MQVJJUzIgCisKKyAgICBjYyAtRyAtbyAuLi8uLi8uLi8uLi8uLi8uLi9idWlsZC9zb2xhcmlzL2xpYi9zcGFyYy9saWJtYm94LnNvIAorCSAgICBvYmovc3BhcmMvLi9VTklYRmlsZS5vIG9iai9zcGFyYy8uL1VOSVhJbmJveC5vICAgIAorCSAgICAtTC9qYXZhL3JlL2pkay8xLjQvYXJjaGl2ZS9mY3MvYmluYXJpZXMvc29sc3BhcmMvanJlL2xpYi9zcGFyYyAKKwkgICAgLUwuLi8uLi8uLi8uLi8uLi8uLi9idWlsZC9zb2xhcmlzL2xpYi9zcGFyYyAgCisJICAgIC1sbWFpbCAKKwkgICAgLUwuLi8uLi8uLi8uLi8uLi8uLi9idWlsZC9zb2xhcmlzL2xpYi9zcGFyYyAKKwkgICAgLWxqYXZhICAKKwkgICAgLWxjCisgICAgLS0+CisKKyAgICA8dGFyZ2V0IG5hbWU9Im1ib3hjYy1zb2xhcmlzIiBkZXBlbmRzPSJtYm94aGVhZGVycyIgaWY9ImlzLXNvbGFyaXMiPgorCTxjYyBkZWJ1Zz0iJHtjYy5kZWJ1Z30iCisJCWxpbms9InNoYXJlZCIKKwkJb3V0ZmlsZT0iJHtsaWIuZGlyfS9tYm94IgorCQlvYmpkaXI9IiR7b2JqLmRpcn0iPgorCSAgICA8Y29tcGlsZXIgbmFtZT0ic3VuYzg5Ii8+CisJICAgIDxmaWxlc2V0IGRpcj0ibWJveC9zcmMvbWFpbi9jcHAiIGluY2x1ZGVzPSIqKi8qLmMiLz4KKwkgICAgPGluY2x1ZGVwYXRoIGxvY2F0aW9uPSIke2dlbmVyYXRlZC5kaXJ9Ii8+CisJICAgIDxzeXNpbmNsdWRlcGF0aCBsb2NhdGlvbj0iJHtqYXZhLmhvbWV9Ly4uL2luY2x1ZGUiLz4KKwkgICAgPHN5c2luY2x1ZGVwYXRoIGxvY2F0aW9uPSIke2phdmEuaG9tZX0vLi4vaW5jbHVkZS9zb2xhcmlzIi8+CisJICAgIDxkZWZpbmVzZXQ+CisJCTxkZWZpbmUgbmFtZT0iX1JFRU5UUkFOVCIvPgorCSAgICA8L2RlZmluZXNldD4KKwkgICAgPGNvbXBpbGVyYXJnIHZhbHVlPSItWGEiLz4KKwkgICAgPGNvbXBpbGVyYXJnIHZhbHVlPSIteE8yIi8+CisJICAgIDxsaW5rZXIgbmFtZT0ic3VuYzg5Ij4KKwkJPHN5c2xpYnNldCBsaWJzPSJtYWlsLGphdmEsYyIvPgorCSAgICA8L2xpbmtlcj4KKwk8L2NjPgorICAgIDwvdGFyZ2V0PgorCisgICAgPHRhcmdldCBuYW1lPSJjbGVhbiIgZGVzY3JpcHRpb249IkNsZWFuIHRoZSBidWlsZCI+CisgICAgICAgIDxkZWxldGUgaW5jbHVkZUVtcHR5RGlycz0idHJ1ZSIgZmFpbG9uZXJyb3I9ImZhbHNlIj4KKyAgICAgICAgICAgIDxmaWxlc2V0IGRpcj0iJHtjb21wb25lbnQuY2xhc3Nlcy5tYm94LmRpcn0iLz4KKyAgICAgICAgPC9kZWxldGU+CisgICAgPC90YXJnZXQ+CisKKyAgICA8IS0tIEphdmFNYWlsIGJ1bmRsZSBidWlsZCB0YXJnZXRzIC0tPgorCisgICAgPHRhcmdldCBuYW1lPSJtYm94cmVsZWFzZSIgZGVwZW5kcz0iaW5pdCwgbWJveGphciwgbWJveGNjIj4KKyAgICAgICAgPHByb3BlcnR5IG5hbWU9InJlbCIgdmFsdWU9Im1ib3gtJHtyZWxlYXNlLnZlcnNpb259Ii8+CisgICAgICAgIDxwcm9wZXJ0eSBuYW1lPSJ6aXBuYW1lIiB2YWx1ZT0iJHtyZWx9LnppcCIvPgorICAgICAgICA8ZGVsZXRlIGZpbGU9IiR7YmFzZWRpcn0vbWJveC90YXJnZXQvJHt6aXBuYW1lfSIvPgorICAgICAgICA8ZWNobyBtZXNzYWdlPSJDcmVhdGluZyBtYm94IGJ1bmRsZSAke2Jhc2VkaXJ9L21ib3gvdGFyZ2V0LyR7emlwbmFtZX0iLz4KKyAgICAgICAgPHppcCBkZXN0ZmlsZT0iJHtiYXNlZGlyfS9tYm94L3RhcmdldC8ke3ppcG5hbWV9Ij4KKwkgICAgPHppcGZpbGVzZXQgZGlyPSIke3Jlc291cmNlcy5sZWdhbC5kaXJ9L01FVEEtSU5GIiBwcmVmaXg9IiR7cmVsfSIKKyAgICAgICAgICAgICAgICAgICAgaW5jbHVkZXM9IkxJQ0VOU0UudHh0Ii8+CisJICAgIDx6aXBmaWxlc2V0IGRpcj0iJHtyZWxlYXNlLmRpcn0vbGliIiBwcmVmaXg9IiR7cmVsfSIKKwkJICAgIGluY2x1ZGVzPSJtYm94LmphciIvPgorICAgICAgICAgICAgPHppcGZpbGVzZXQgZGlyPSIke2xpYi5kaXJ9Ly4uIiBwcmVmaXg9IiR7cmVsfS9saWIiCisJCSAgICBpbmNsdWRlcz0iKiovKi5zbyIvPgorICAgICAgICA8L3ppcD4KKyAgICA8L3RhcmdldD4KKworICAgICA8dGFyZ2V0IG5hbWU9Im1ib3hqYXIiIGRlcGVuZHM9ImluaXQsIG1ib3hjb21waWxlLCBjb29rLW1hbmlmZXN0Ij4KKyAgICAgICAgPG1rZGlyIGRpcj0iJHtyZWxlYXNlLmRpcn0vbGliIi8+CisgICAgICAgIDxqYXIgamFyZmlsZT0iJHtyZWxlYXNlLm1ib3guamFyfSIKKwkJbWFuaWZlc3Q9IiR7Y29tcG9uZW50LmNsYXNzZXMubWJveC5kaXJ9L21hbmlmZXN0L01BTklGRVNULk1GIj4KKyAgICAgICAgICAgIDxtZXRhaW5mIGRpcj0iJHtyZXNvdXJjZXMubGVnYWwuZGlyfS9NRVRBLUlORiIKKwkJICAgIGluY2x1ZGVzPSJMSUNFTlNFLnR4dCIvPgorICAgICAgICAgICAgPGZpbGVzZXQgZGlyPSIke2NvbXBvbmVudC5jbGFzc2VzLm1ib3guZGlyfSI+CisgICAgICAgICAgICAgICAgPGluY2x1ZGUgbmFtZT0iY29tL3N1bi9tYWlsL21ib3gvKi5jbGFzcyIvPgorICAgICAgICAgICAgICAgIDxpbmNsdWRlIG5hbWU9ImNvbS9zdW4vbWFpbC9tYm94L21haWxjYXAiLz4KKyAgICAgICAgICAgIDwvZmlsZXNldD4KKyAgICAgICAgPC9qYXI+CisgICAgIDwvdGFyZ2V0PgorCisgICAgPHRhcmdldCBuYW1lPSJwdXNoLXRvLW1hdmVuLXByZXBhcmUiIGRlcGVuZHM9Ii1wdXNoLXRvLW1hdmVuLWluaXQsIG1ib3hqYXIiCisgICAgICAgIGRlc2NyaXB0aW9uPSJjcmVhdGVzIGFuIGltYWdlIGZvciB0aGUgJ3B1c2gtdG8tbWF2ZW4nIGdvYWwiPgorICAgICAgICA8ZGVsZXRlIGRpcj0idGFyZ2V0L21hdmVuLXJlcG8iIC8+PCEtLSBjbGVhbiBpdCAtLT4KKyAgICAgICAgPG1hdmVuLXJlcG9zaXRvcnktaW1wb3J0ZXIgZGVzdGRpcj0idGFyZ2V0L21hdmVuLXJlcG8iCisJCXZlcnNpb249IiR7cmVsZWFzZS52ZXJzaW9ufSI+CisgICAgICAgICAgICA8YXJ0aWZhY3QgamFyPSJ0YXJnZXQvcmVsZWFzZS9tYm94LmphciIgcG9tPSJtYm94LnBvbSIKKwkJICAgIHNyY3ppcD0idGFyZ2V0L21ib3guc3JjLnppcCIgLz4KKyAgICAgICAgPC9tYXZlbi1yZXBvc2l0b3J5LWltcG9ydGVyPgorICAgIDwvdGFyZ2V0PgorCisgICAgPHRhcmdldCBuYW1lPSJwdXNoLXRvLW1hdmVuIiBkZXBlbmRzPSJwdXNoLXRvLW1hdmVuLXByZXBhcmUiCisgICAgICAgIGRlc2NyaXB0aW9uPSJwdXNoZXMgamFycyB0byB0aGUgamF2YS5uZXQgbWF2ZW4gcmVwb3NpdG9yeSI+CisgICAgICAgIDxjdnMtaW1wb3J0IHNyYz0idGFyZ2V0L21hdmVuLXJlcG8iIGRlc3Q9ImdsYXNzZmlzaC9yZXBvIiAvPgorICAgIDwvdGFyZ2V0PgorPC9wcm9qZWN0PgpkaWZmIC0tZ2l0IGEvbWJveC9leGNsdWRlLnhtbCBiL21ib3gvZXhjbHVkZS54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjU5ZTZlNwotLS0gL2Rldi9udWxsCisrKyBiL21ib3gvZXhjbHVkZS54bWwKQEAgLTAsMCArMSw4NiBAQAorPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KKzwhLS0KKworICAgIENvcHlyaWdodCAoYykgMjAxMCwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorCisgICAgVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgICAgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisKKyAgICBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgICAgTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICAgIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICAgIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorCisgICAgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisKKy0tPgorCis8IS0tIEZpbmRCdWdzIGV4Y2x1ZGUgbGlzdCBmb3IgSmF2YU1haWwgbWJveCBwcm92aWRlciAtLT4KKworPEZpbmRCdWdzRmlsdGVyPgorICAgIDwhLS0KKwlXaXRob3V0IG11bHRpLWNhdGNoIHdlIGp1c3QgY2F0Y2ggYWxsIHBvc3NpYmxlIGV4Y2VwdGlvbnMuCisgICAgLS0+CisgICAgPE1hdGNoPgorCTxDbGFzcyBuYW1lPSJjb20uc3VuLm1haWwubWJveC5NYm94U3RvcmUiLz4KKwk8TWV0aG9kIG5hbWU9IiZsdDtpbml0Jmd0OyIvPiA8IS0tIG1hdGNoIGNvbnN0cnVjdG9yIC0tPgorCTxCdWcgcGF0dGVybj0iUkVDX0NBVENIX0VYQ0VQVElPTiIvPgorICAgIDwvTWF0Y2g+CisKKyAgICA8IS0tCisJV2UgcHVycG9zZWx5IHJldHVybiBudWxsIGluc3RlYWQgb2YgYW4gZW1wdHkgbGlzdC4KKyAgICAtLT4KKyAgICA8TWF0Y2g+CisJPENsYXNzIG5hbWU9ImNvbS5zdW4ubWFpbC5tYm94Lk1ib3hGb2xkZXIiLz4KKwk8TWV0aG9kIG5hbWU9ImxvYWQiLz4KKwk8QnVnIHBhdHRlcm49IlBaTEFfUFJFRkVSX1pFUk9fTEVOR1RIX0FSUkFZUyIvPgorICAgIDwvTWF0Y2g+CisKKyAgICA8IS0tCisJV2UgcHVycG9zZWx5IGRvbid0IGNsb3NlIHRoaXMgc3RyZWFtLCB3aGljaCBpcyBqdXN0IGEgd3JhcHBlcgorCWFyb3VuZCB0aGUgb3JpZ2luYWwgc3RyZWFtIHRoYXQgbmVlZHMgdG8gcmVtYWluIG9wZW4uCisgICAgLS0+CisgICAgPE1hdGNoPgorCTxDbGFzcyBuYW1lPSJjb20uc3VuLm1haWwubWJveC5TdW5WM011bHRpcGFydCIvPgorCTxNZXRob2QgbmFtZT0icGFyc2UiLz4KKwk8QnVnIHBhdHRlcm49Ik9TX09QRU5fU1RSRUFNIi8+CisgICAgPC9NYXRjaD4KKworICAgIDwhLS0KKwlXaGVuIGRlbGV0aW5nIHRoZSB0ZW1wIGZpbGUgZmFpbHMsIHRoZXJlJ3MgcmVhbGx5IG5vdGhpbmcgdG8gYmUgZG9uZS4KKyAgICAtLT4KKyAgICA8TWF0Y2g+CisJPENsYXNzIG5hbWU9ImNvbS5zdW4ubWFpbC5tYm94LlRlbXBGaWxlIi8+CisJPE1ldGhvZCBuYW1lPSJjbG9zZSIvPgorCTxCdWcgcGF0dGVybj0iUlZfUkVUVVJOX1ZBTFVFX0lHTk9SRURfQkFEX1BSQUNUSUNFIi8+CisgICAgPC9NYXRjaD4KKworICAgIDwhLS0KKwlXZSBuZXZlciBzZXJpYWxpemUgdGhpcyBjbGFzcy4KKyAgICAtLT4KKyAgICA8TWF0Y2g+CisJPENsYXNzIG5hbWU9ImNvbS5zdW4ubWFpbC5tYm94LlVOSVhJbmJveCIvPgorCTxGaWVsZCBuYW1lPSJsb2NrZmlsZU5hbWUiLz4KKwk8QnVnIHBhdHRlcm49IlNFX1RSQU5TSUVOVF9GSUVMRF9OT1RfUkVTVE9SRUQiLz4KKyAgICA8L01hdGNoPgorCisgICAgPCEtLQorCUlmIGNsb3NlIGZhaWxzLCB3aGF0IGFyZSB3ZSBzdXBwb3NlZCB0byBkbz8KKyAgICAtLT4KKyAgICA8TWF0Y2g+CisJPENsYXNzIG5hbWU9ImNvbS5zdW4ubWFpbC5tYm94Lk1ib3hGb2xkZXIiLz4KKwk8TWV0aG9kIG5hbWU9ImFwcGVuZE1lc3NhZ2VzIi8+CisJPEJ1ZyBwYXR0ZXJuPSJERV9NSUdIVF9JR05PUkUiLz4KKyAgICA8L01hdGNoPgorCisgICAgPCEtLQorCUlmIGdldFNlbnREYXRlIGZhaWxzLCB0cmVhdCBpdCB0aGUgc2FtZSBhcyByZXR1cm5pbmcgbnVsbC4KKyAgICAtLT4KKyAgICA8TWF0Y2g+CisJPENsYXNzIG5hbWU9ImNvbS5zdW4ubWFpbC5tYm94Lk1ib3hNZXNzYWdlIi8+CisJPE1ldGhvZCBuYW1lPSJnZXRVbml4RnJvbUxpbmUiLz4KKwk8QnVnIHBhdHRlcm49IkRFX01JR0hUX0lHTk9SRSIvPgorICAgIDwvTWF0Y2g+Cis8L0ZpbmRCdWdzRmlsdGVyPgpkaWZmIC0tZ2l0IGEvbWJveC9uYXRpdmUvcG9tLnhtbCBiL21ib3gvbmF0aXZlL3BvbS54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjkyMjBjOQotLS0gL2Rldi9udWxsCisrKyBiL21ib3gvbmF0aXZlL3BvbS54bWwKQEAgLTAsMCArMSwxNTMgQEAKKzw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9Imlzby04ODU5LTEiPz4KKzwhLS0KKworICAgIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorCisgICAgVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgICAgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisKKyAgICBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgICAgTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICAgIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICAgIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorCisgICAgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisKKy0tPgorCis8cHJvamVjdCB4bWxucz0iaHR0cDovL21hdmVuLmFwYWNoZS5vcmcvUE9NLzQuMC4wIgorCXhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiCisJeHNpOnNjaGVtYUxvY2F0aW9uPSJodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9QT00vNC4wLjAKKwkJCSAgICBodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9tYXZlbi12NF8wXzAueHNkIj4KKyAgICA8cGFyZW50PgorCTxncm91cElkPmNvbS5zdW4ubWFpbDwvZ3JvdXBJZD4KKwk8YXJ0aWZhY3RJZD5hbGw8L2FydGlmYWN0SWQ+CisJPHZlcnNpb24+MS42LjM8L3ZlcnNpb24+CisJPHJlbGF0aXZlUGF0aD4uLi8uLi9wb20ueG1sPC9yZWxhdGl2ZVBhdGg+CisgICAgPC9wYXJlbnQ+CisgICAgPG1vZGVsVmVyc2lvbj40LjAuMDwvbW9kZWxWZXJzaW9uPgorICAgIDxncm91cElkPmNvbS5zdW4ubWFpbDwvZ3JvdXBJZD4KKyAgICA8YXJ0aWZhY3RJZD5saWJtYm94PC9hcnRpZmFjdElkPgorICAgIDxwYWNrYWdpbmc+c288L3BhY2thZ2luZz4KKyAgICA8bmFtZT5KYXZhTWFpbCBBUEkgbWJveCBuYXRpdmUgbGlicmFyeTwvbmFtZT4KKyAgICA8ZGVzY3JpcHRpb24+SmF2YU1haWwgQVBJIG1ib3ggbmF0aXZlIGxpYnJhcnk8L2Rlc2NyaXB0aW9uPgorICAgIDx1cmw+aHR0cDovL2phdmEuc3VuLmNvbS9wcm9qZWN0cy9qYXZhbWFpbDwvdXJsPgorCisgICAgPHByb3BlcnRpZXM+CisJPG02ND4KKwk8L202ND4KKwk8Y29tcGlsZXIubmFtZT4KKwkgICAgYzg5CisJPC9jb21waWxlci5uYW1lPgorCTxjb21waWxlci5zdGFydC5vcHRpb25zPgorCSAgICAke202NH0gLVhhIC14TzIgLXYgLURfUkVFTlRSQU5UIC1LUElDCisJICAgIC1JJHtlbnYuSkFWQV9IT01FfS9pbmNsdWRlIC1JJHtlbnYuSkFWQV9IT01FfS9pbmNsdWRlL3NvbGFyaXMKKwk8L2NvbXBpbGVyLnN0YXJ0Lm9wdGlvbnM+CisJPGxpbmtlci5uYW1lPgorCSAgICBjODkKKwk8L2xpbmtlci5uYW1lPgorCTxsaW5rZXIuc3RhcnQub3B0aW9ucz4KKwkgICAgLUcgJHttNjR9IC1LUElDIC16IHRleHQKKwk8L2xpbmtlci5zdGFydC5vcHRpb25zPgorCTxsaW5rZXIuYXJjaD4KKwkgICAgJHtlbnYuTUFDSH0KKwk8L2xpbmtlci5hcmNoPgorCTxsaW5rZXIuZW5kLm9wdGlvbnM+CisJICAgIC1MJHtlbnYuSkFWQV9IT01FfS9qcmUvbGliLyR7bGlua2VyLmFyY2h9IC1sbWFpbCAtbGphdmEgLWxjCisJPC9saW5rZXIuZW5kLm9wdGlvbnM+CisgICAgPC9wcm9wZXJ0aWVzPgorCisgICAgPHByb2ZpbGVzPgorCTxwcm9maWxlPgorCSAgICA8IS0tCisJCU92ZXJyaWRlIHRoZSBzZXR0aW5ncyBuZWNlc3NhcnkgdG8gYnVpbGQgd2l0aCBKREsgMS44LgorCSAgICAtLT4KKwkgICAgPGlkPjEuODwvaWQ+CisJICAgIDxwcm9wZXJ0aWVzPgorCQk8bTY0PgorCQkgICAgLW02NAorCQk8L202ND4KKwkJPGxpbmtlci5hcmNoPgorCQkgICAgYW1kNjQKKwkJPC9saW5rZXIuYXJjaD4KKwkgICAgPC9wcm9wZXJ0aWVzPgorCTwvcHJvZmlsZT4KKyAgICA8L3Byb2ZpbGVzPgorCisgICAgPGJ1aWxkPgorICAgICAgICA8cGx1Z2lucz4KKwkgICAgPHBsdWdpbj4KKwkJPGdyb3VwSWQ+b3JnLmNvZGVoYXVzLm1vam88L2dyb3VwSWQ+CisJCTxhcnRpZmFjdElkPm5hdGl2ZS1tYXZlbi1wbHVnaW48L2FydGlmYWN0SWQ+CisJCTx2ZXJzaW9uPjEuMC1hbHBoYS03PC92ZXJzaW9uPgorCQk8ZXh0ZW5zaW9ucz50cnVlPC9leHRlbnNpb25zPgorCQk8Y29uZmlndXJhdGlvbj4KKwkJICAgIDxjb21waWxlclByb3ZpZGVyPmdlbmVyaWM8L2NvbXBpbGVyUHJvdmlkZXI+CisJCSAgICA8Y29tcGlsZXJFeGVjdXRhYmxlPiR7Y29tcGlsZXIubmFtZX08L2NvbXBpbGVyRXhlY3V0YWJsZT4KKwkJICAgIDxsaW5rZXJFeGVjdXRhYmxlPiR7bGlua2VyLm5hbWV9PC9saW5rZXJFeGVjdXRhYmxlPgorCQkgICAgPGNvbXBpbGVyU3RhcnRPcHRpb25zPgorCQkJPGNvbXBpbGVyU3RhcnRPcHRpb24+CisJCQkgICAgJHtjb21waWxlci5zdGFydC5vcHRpb25zfQorCQkJPC9jb21waWxlclN0YXJ0T3B0aW9uPgorCQkgICAgPC9jb21waWxlclN0YXJ0T3B0aW9ucz4KKwkJICAgIDxsaW5rZXJTdGFydE9wdGlvbnM+CisJCQk8bGlua2VyU3RhcnRPcHRpb24+CisJCQkgICAgJHtsaW5rZXIuc3RhcnQub3B0aW9uc30KKwkJCTwvbGlua2VyU3RhcnRPcHRpb24+CisJCSAgICA8L2xpbmtlclN0YXJ0T3B0aW9ucz4KKwkJICAgIDxsaW5rZXJFbmRPcHRpb25zPgorCQkJPGxpbmtlckVuZE9wdGlvbj4KKwkJCSAgICAke2xpbmtlci5lbmQub3B0aW9uc30KKwkJCTwvbGlua2VyRW5kT3B0aW9uPgorCQkgICAgPC9saW5rZXJFbmRPcHRpb25zPgorCQkgICAgPHNvdXJjZXM+CisJCQk8c291cmNlPgorCQkJICAgIDxkaXJlY3Rvcnk+Li4vc3JjL21haW4vY3BwPC9kaXJlY3Rvcnk+CisJCQkgICAgPGluY2x1ZGVzPgorCQkJCTxpbmNsdWRlPioqLyouYzwvaW5jbHVkZT4KKwkJCSAgICA8L2luY2x1ZGVzPgorCQkJPC9zb3VyY2U+CisJCQk8c291cmNlPgorCQkJICAgIDxkaXJlY3Rvcnk+dGFyZ2V0L25hdGl2ZS9qYXZhaDwvZGlyZWN0b3J5PgorCQkJICAgIDxkZXBlbmRlbmN5QW5hbHlzaXNQYXJ0aWNpcGF0aW9uPgorCQkJCWZhbHNlCisJCQkgICAgPC9kZXBlbmRlbmN5QW5hbHlzaXNQYXJ0aWNpcGF0aW9uPgorCQkJPC9zb3VyY2U+CisJCSAgICA8L3NvdXJjZXM+CisJCTwvY29uZmlndXJhdGlvbj4KKwkJPGV4ZWN1dGlvbnM+CisJCSAgICA8ZXhlY3V0aW9uPgorCQkJPGlkPmphdmFoPC9pZD4KKwkJCTxwaGFzZT5nZW5lcmF0ZS1zb3VyY2VzPC9waGFzZT4KKwkJCTxnb2Fscz4KKwkJCSAgICA8Z29hbD5qYXZhaDwvZ29hbD4KKwkJCTwvZ29hbHM+CisJCQk8Y29uZmlndXJhdGlvbj4KKwkJCSAgICA8Y2xhc3NOYW1lcz4KKwkJCQk8Y2xhc3NOYW1lPgorCQkJCSAgICBjb20uc3VuLm1haWwubWJveC5VTklYRmlsZQorCQkJCTwvY2xhc3NOYW1lPgorCQkJCTxjbGFzc05hbWU+CisJCQkJICAgIGNvbS5zdW4ubWFpbC5tYm94LlVOSVhJbmJveAorCQkJCTwvY2xhc3NOYW1lPgorCQkJICAgIDwvY2xhc3NOYW1lcz4KKwkJCTwvY29uZmlndXJhdGlvbj4KKwkJICAgIDwvZXhlY3V0aW9uPgorCQk8L2V4ZWN1dGlvbnM+CisJICAgIDwvcGx1Z2luPgorICAgICAgICA8L3BsdWdpbnM+CisgICAgPC9idWlsZD4KKworICAgIDxkZXBlbmRlbmNpZXM+CisgICAgICAgIDxkZXBlbmRlbmN5PgorICAgICAgICAgICAgPGdyb3VwSWQ+Y29tLnN1bi5tYWlsPC9ncm91cElkPgorICAgICAgICAgICAgPGFydGlmYWN0SWQ+amFrYXJ0YS5tYWlsPC9hcnRpZmFjdElkPgorICAgICAgICA8L2RlcGVuZGVuY3k+CisgICAgICAgIDxkZXBlbmRlbmN5PgorICAgICAgICAgICAgPGdyb3VwSWQ+Y29tLnN1bi5tYWlsPC9ncm91cElkPgorICAgICAgICAgICAgPGFydGlmYWN0SWQ+bWJveDwvYXJ0aWZhY3RJZD4KKyAgICAgICAgPC9kZXBlbmRlbmN5PgorICAgIDwvZGVwZW5kZW5jaWVzPgorPC9wcm9qZWN0PgpkaWZmIC0tZ2l0IGEvbWJveC9wb20ueG1sIGIvbWJveC9wb20ueG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdhYzNkNTQKLS0tIC9kZXYvbnVsbAorKysgYi9tYm94L3BvbS54bWwKQEAgLTAsMCArMSw3OCBAQAorPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PgorPCEtLQorCisgICAgQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisKKyAgICBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAgICB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKworICAgIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAgICBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgICAgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgICAgdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisKKyAgICBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKworLS0+CisKKzxwcm9qZWN0IHhtbG5zPSJodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9QT00vNC4wLjAiCisJeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIKKwl4c2k6c2NoZW1hTG9jYXRpb249Imh0dHA6Ly9tYXZlbi5hcGFjaGUub3JnL1BPTS80LjAuMAorCQkJICAgIGh0dHA6Ly9tYXZlbi5hcGFjaGUub3JnL21hdmVuLXY0XzBfMC54c2QiPgorICAgIDxwYXJlbnQ+CisJPGdyb3VwSWQ+Y29tLnN1bi5tYWlsPC9ncm91cElkPgorCTxhcnRpZmFjdElkPmFsbDwvYXJ0aWZhY3RJZD4KKwk8dmVyc2lvbj4xLjYuMzwvdmVyc2lvbj4KKyAgICA8L3BhcmVudD4KKyAgICA8bW9kZWxWZXJzaW9uPjQuMC4wPC9tb2RlbFZlcnNpb24+CisgICAgPGdyb3VwSWQ+Y29tLnN1bi5tYWlsPC9ncm91cElkPgorICAgIDxhcnRpZmFjdElkPm1ib3g8L2FydGlmYWN0SWQ+CisgICAgPHBhY2thZ2luZz5qYXI8L3BhY2thZ2luZz4KKyAgICA8bmFtZT5KYXZhTWFpbCBBUEkgbWJveCBwcm92aWRlcjwvbmFtZT4KKworICAgIDxwcm9wZXJ0aWVzPgorCTxtYWlsLnBhY2thZ2VzLmV4cG9ydD4KKwkgICAgY29tLnN1bi5tYWlsLm1ib3g7IHZlcnNpb249JHttYWlsLm9zZ2l2ZXJzaW9ufQorCTwvbWFpbC5wYWNrYWdlcy5leHBvcnQ+CisJPGZpbmRidWdzLnNraXA+CisJICAgIGZhbHNlCisJPC9maW5kYnVncy5za2lwPgorCTxmaW5kYnVncy5leGNsdWRlPgorCSAgICAke3Byb2plY3QuYmFzZWRpcn0vZXhjbHVkZS54bWwKKwk8L2ZpbmRidWdzLmV4Y2x1ZGU+CisgICAgPC9wcm9wZXJ0aWVzPgorCisgICAgPGJ1aWxkPgorCTxwbHVnaW5zPgorCSAgICA8IS0tCisJCUNvbmZpZ3VyZSB0ZXN0IHBsdWdpbiB0byBmaW5kICpUZXN0U3VpdGUgY2xhc3Nlcy4KKwkgICAgLS0+CisJICAgIDxwbHVnaW4+CisJCTxncm91cElkPm9yZy5hcGFjaGUubWF2ZW4ucGx1Z2luczwvZ3JvdXBJZD4KKwkJPGFydGlmYWN0SWQ+bWF2ZW4tc3VyZWZpcmUtcGx1Z2luPC9hcnRpZmFjdElkPgorCQk8Y29uZmlndXJhdGlvbj4KKwkJICAgIDxpbmNsdWRlcz4KKwkJCTxpbmNsdWRlPioqLypUZXN0LmphdmE8L2luY2x1ZGU+CisJCQk8aW5jbHVkZT4qKi8qVGVzdFN1aXRlLmphdmE8L2luY2x1ZGU+CisJCSAgICA8L2luY2x1ZGVzPgorCQk8L2NvbmZpZ3VyYXRpb24+CisJICAgIDwvcGx1Z2luPgorCTwvcGx1Z2lucz4KKyAgICA8L2J1aWxkPgorCisgICAgPGRlcGVuZGVuY2llcz4KKyAgICAgICAgPGRlcGVuZGVuY3k+CisgICAgICAgICAgICA8Z3JvdXBJZD5jb20uc3VuLm1haWw8L2dyb3VwSWQ+CisgICAgICAgICAgICA8YXJ0aWZhY3RJZD5qYWthcnRhLm1haWw8L2FydGlmYWN0SWQ+CisgICAgICAgIDwvZGVwZW5kZW5jeT4KKwk8ZGVwZW5kZW5jeT4KKwkgICAgPGdyb3VwSWQ+anVuaXQ8L2dyb3VwSWQ+CisJICAgIDxhcnRpZmFjdElkPmp1bml0PC9hcnRpZmFjdElkPgorCSAgICA8dmVyc2lvbj40LjEyPC92ZXJzaW9uPgorCSAgICA8c2NvcGU+dGVzdDwvc2NvcGU+CisJICAgIDxvcHRpb25hbD50cnVlPC9vcHRpb25hbD4KKwk8L2RlcGVuZGVuY3k+CisgICAgPC9kZXBlbmRlbmNpZXM+Cis8L3Byb2plY3Q+CmRpZmYgLS1naXQgYS9tYm94L3NyYy9tYWluL2NwcC9jb20vc3VuL21haWwvbWJveC9VTklYRmlsZS5jIGIvbWJveC9zcmMvbWFpbi9jcHAvY29tL3N1bi9tYWlsL21ib3gvVU5JWEZpbGUuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNjZhNzcyCi0tLSAvZGV2L251bGwKKysrIGIvbWJveC9zcmMvbWFpbi9jcHAvY29tL3N1bi9tYWlsL21ib3gvVU5JWEZpbGUuYwpAQCAtMCwwICsxLDEwMCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworI2luY2x1ZGUgPGpuaS5oPgorI2luY2x1ZGUgPGZjbnRsLmg+CisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisjaW5jbHVkZSA8c3lzL3N0YXQuaD4KKworZXh0ZXJuIGludCBfZmNudGwoKTsKKworI2luY2x1ZGUgImNvbV9zdW5fbWFpbF9tYm94X1VOSVhGaWxlLmgiCisKK3N0YXRpYwlqZmllbGRJRCBJT19mZF9mZElEOworc3RhdGljCWludCBmZF9vZmZzZXQ7CisKKy8qCisgKiBDbGFzczogICAgIGNvbV9zdW5fbWFpbF9tYm94X1VOSVhGaWxlCisgKiBNZXRob2Q6ICAgIGluaXRJRHMKKyAqIFNpZ25hdHVyZTogKExqYXZhL2xhbmcvQ2xhc3M7TGphdmEvaW8vRmlsZURlc2NyaXB0b3I7KVYKKyAqLworSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTAorSmF2YV9jb21fc3VuX21haWxfbWJveF9VTklYRmlsZV9pbml0SURzKEpOSUVudiAqZW52LCBqY2xhc3MgdWZDbGFzcywKKyAgICBqY2xhc3MgZmRDbGFzcywgam9iamVjdCBzdGRpbl9vYmopCit7CisJSU9fZmRfZmRJRCA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIGZkQ2xhc3MsICJmZCIsICJJIik7CisJLyoKKwkgKiBCZWNhdXNlIHByZS1KREsgMS4yIHN0b3JlZCB0aGUgImZkIiBhcyBvbmUgbW9yZSB0aGFuCisJICogaXRzIGFjdHVhbCB2YWx1ZSwgd2UgcmVtZW1iZXIgdGhlIHZhbHVlIGl0IHN0b3JlZCBmb3IKKwkgKiBzdGRpbiwgd2hpY2ggc2hvdWxkIGJlIHplcm8sIGFuZCB1c2UgaXQgYXMgdGhlIG9mZnNldAorCSAqIGZvciBvdGhlciBmZCdzIHdlIGV4dHJhY3QuCisJICovCisJZmRfb2Zmc2V0ID0gKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIHN0ZGluX29iaiwgSU9fZmRfZmRJRCk7Cit9CisKKy8qCisgKiBDbGFzczogICAgIGNvbV9zdW5fbWFpbF9tYm94X1VOSVhGaWxlCisgKiBNZXRob2Q6ICAgIGxvY2swCisgKiBTaWduYXR1cmU6IChMamF2YS9pby9GaWxlRGVzY3JpcHRvcjtMamF2YS9sYW5nL1N0cmluZztaKVoKKyAqLworSk5JRVhQT1JUIGpib29sZWFuIEpOSUNBTEwKK0phdmFfY29tX3N1bl9tYWlsX21ib3hfVU5JWEZpbGVfbG9jazAoSk5JRW52ICplbnYsIGpjbGFzcyBjbGF6eiwKKyAgICBqb2JqZWN0IGZkb2JqLCBqc3RyaW5nIHVtb2RlLCBqYm9vbGVhbiBibG9jaykKK3sKKwlpbnQgZmQ7CisJY29uc3QgY2hhciAqbW9kZTsKKwlzdGF0aWMgc3RydWN0IGZsb2NrIGZsb2NrMDsKKwlzdHJ1Y3QgZmxvY2sgZmxvY2sgPSBmbG9jazA7CisKKwlmZCA9ICgqZW52KS0+R2V0SW50RmllbGQoZW52LCBmZG9iaiwgSU9fZmRfZmRJRCk7CisJZmQgLT0gZmRfb2Zmc2V0OworCS8qIFhYWCAtIGEgbG90IG9mIHdvcmsgdG8gZXhhbWluZSBvbmUgY2hhcmFjdGVyIGluIGEgc3RyaW5nICovCisJbW9kZSA9ICgqZW52KS0+R2V0U3RyaW5nVVRGQ2hhcnMoZW52LCB1bW9kZSwgMCk7CisJZmxvY2subF90eXBlID0gbW9kZVsxXSA9PSAndycgPyBGX1dSTENLIDogRl9SRExDSzsKKwkoKmVudiktPlJlbGVhc2VTdHJpbmdVVEZDaGFycyhlbnYsIHVtb2RlLCBtb2RlKTsKKwlmbG9jay5sX3doZW5jZSA9IFNFRUtfU0VUOworCWZsb2NrLmxfc3RhcnQgPSAwOworCWZsb2NrLmxfbGVuID0gMDsKKwlyZXR1cm4gKF9mY250bChmZCwgYmxvY2sgPyBGX1NFVExLVyA6IEZfU0VUTEssICZmbG9jaykgPT0gMCA/CisJCUpOSV9UUlVFIDogSk5JX0ZBTFNFKTsKK30KKworLyoKKyAqIENsYXNzOiAgICAgY29tX3N1bl9tYWlsX21ib3hfVU5JWEZpbGUKKyAqIE1ldGhvZDogICAgbGFzdEFjY2Vzc2VkMAorICogU2lnbmF0dXJlOiAoTGphdmEvbGFuZy9TdHJpbmc7KUoKKyAqLworSk5JRVhQT1JUIGpsb25nIEpOSUNBTEwKK0phdmFfY29tX3N1bl9tYWlsX21ib3hfVU5JWEZpbGVfbGFzdEFjY2Vzc2VkMChKTklFbnYgKmVudiwgamNsYXNzIGNsYXp6LAorCWpzdHJpbmcgdW5hbWUpCit7CisJY29uc3QgY2hhciAqbmFtZTsKKwlqbG9uZyByZXQgPSAtMTsKKwlzdHJ1Y3Qgc3RhdCBzdDsKKworCW5hbWUgPSAoKmVudiktPkdldFN0cmluZ1VURkNoYXJzKGVudiwgdW5hbWUsIDApOworCWlmIChzdGF0KG5hbWUsICZzdCkgPT0gMCkgeworCQkvKgorCQkgKiBTaG91bGQgYmUuLi4KKwkJcmV0ID0gKGpsb25nKXN0LnN0X2F0aW0udHZfc2VjICogMTAwMCArCisJCQlzdC5zdF9hdGltLnR2X25zZWMgLyAxMDAwMDAwOworCQkgKiBidXQgZm9yIGNvbXBhdGliaWxpdHkgd2l0aCBsYXN0TW9kaWZpZWQgd2UgdXNlLi4uCisJCSAqLworCQlyZXQgPSAoamxvbmcpc3Quc3RfYXRpbWUgKiAxMDAwOworCX0KKwkoKmVudiktPlJlbGVhc2VTdHJpbmdVVEZDaGFycyhlbnYsIHVuYW1lLCBuYW1lKTsKKwlyZXR1cm4gcmV0OworfQpkaWZmIC0tZ2l0IGEvbWJveC9zcmMvbWFpbi9jcHAvY29tL3N1bi9tYWlsL21ib3gvVU5JWEluYm94LmMgYi9tYm94L3NyYy9tYWluL2NwcC9jb20vc3VuL21haWwvbWJveC9VTklYSW5ib3guYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNzRhNDRlCi0tLSAvZGV2L251bGwKKysrIGIvbWJveC9zcmMvbWFpbi9jcHAvY29tL3N1bi9tYWlsL21ib3gvVU5JWEluYm94LmMKQEAgLTAsMCArMSw2MCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworI2luY2x1ZGUgPGpuaS5oPgorI2luY2x1ZGUgPG1haWxsb2NrLmg+CitleHRlcm4gdm9pZCB0b3VjaGxvY2soKTsJLyogWFhYIC0gc2hvdWxkIGJlIGluIG1haWxsb2NrLmggKi8KKworI2luY2x1ZGUgImNvbV9zdW5fbWFpbF9tYm94X1VOSVhJbmJveC5oIgorCisvKgorICogQ2xhc3M6ICAgICBjb21fc3VuX21haWxfbWJveF9VTklYSW5ib3gKKyAqIE1ldGhvZDogICAgbWFpbGxvY2sKKyAqIFNpZ25hdHVyZTogKExqYXZhL2xhbmcvU3RyaW5nO0kpWgorICovCitKTklFWFBPUlQgamJvb2xlYW4gSk5JQ0FMTAorSmF2YV9jb21fc3VuX21haWxfbWJveF9VTklYSW5ib3hfbWFpbGxvY2soSk5JRW52ICplbnYsIGpvYmplY3Qgb2JqLAorICAgIGpzdHJpbmcgdXNlciwgamludCByZXRyeV9jb3VudCkKK3sKKwlqYm9vbGVhbiByZXQ7CisJY29uc3QgY2hhciAqbmFtZSA9ICgqZW52KS0+R2V0U3RyaW5nVVRGQ2hhcnMoZW52LCB1c2VyLCAwKTsKKwlyZXQgPSBtYWlsbG9jaygoY2hhciAqKW5hbWUsIHJldHJ5X2NvdW50KSA9PSBMX1NVQ0NFU1MgPworCSAgICBKTklfVFJVRSA6IEpOSV9GQUxTRTsKKwkoKmVudiktPlJlbGVhc2VTdHJpbmdVVEZDaGFycyhlbnYsIHVzZXIsIG5hbWUpOworCXJldHVybiAocmV0KTsKK30KKworLyoKKyAqIENsYXNzOiAgICAgY29tX3N1bl9tYWlsX21ib3hfVU5JWEluYm94CisgKiBNZXRob2Q6ICAgIG1haWx1bmxvY2sKKyAqIFNpZ25hdHVyZTogKClWCisgKi8KK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwKK0phdmFfY29tX3N1bl9tYWlsX21ib3hfVU5JWEluYm94X21haWx1bmxvY2soSk5JRW52ICplbnYsIGpvYmplY3Qgb2JqKQoreworCSh2b2lkKSBtYWlsdW5sb2NrKCk7Cit9CisKKy8qCisgKiBDbGFzczogICAgIGNvbV9zdW5fbWFpbF9tYm94X1VOSVhJbmJveAorICogTWV0aG9kOiAgICB0b3VjaGxvY2swCisgKiBTaWduYXR1cmU6ICgpVgorICovCitKTklFWFBPUlQgdm9pZCBKTklDQUxMCitKYXZhX2NvbV9zdW5fbWFpbF9tYm94X1VOSVhJbmJveF90b3VjaGxvY2swKEpOSUVudiAqZW52LCBqb2JqZWN0IG9iaikKK3sKKwkodm9pZCkgdG91Y2hsb2NrKCk7Cit9CmRpZmYgLS1naXQgYS9tYm94L3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL21ib3gvQ29udGVudExlbmd0aENvdW50ZXIuamF2YSBiL21ib3gvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvbWJveC9Db250ZW50TGVuZ3RoQ291bnRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYwMWFhNTkKLS0tIC9kZXYvbnVsbAorKysgYi9tYm94L3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL21ib3gvQ29udGVudExlbmd0aENvdW50ZXIuamF2YQpAQCAtMCwwICsxLDc1IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5tYm94OworCitpbXBvcnQgamF2YS5pby4qOworCisvKioKKyAqIENvdW50IHRoZSBudW1iZXIgb2YgYnl0ZXMgaW4gdGhlIGJvZHkgb2YgdGhlIG1lc3NhZ2Ugd3JpdHRlbiB0byB0aGUgc3RyZWFtLgorICovCitjbGFzcyBDb250ZW50TGVuZ3RoQ291bnRlciBleHRlbmRzIE91dHB1dFN0cmVhbSB7CisgICAgcHJpdmF0ZSBsb25nIHNpemUgPSAwOworICAgIHByaXZhdGUgYm9vbGVhbiBpbkhlYWRlciA9IHRydWU7CisgICAgcHJpdmF0ZSBpbnQgbGFzdGIxID0gLTEsIGxhc3RiMiA9IC0xOworCisgICAgcHVibGljIHZvaWQgd3JpdGUoaW50IGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJaWYgKGluSGVhZGVyKSB7CisJICAgIC8vIGlmIGxpbmUgdGVybWluYXRvciBpcyBDUgorCSAgICBpZiAoYiA9PSAnXHInICYmIGxhc3RiMSA9PSAnXHInKQorCQlpbkhlYWRlciA9IGZhbHNlOworCSAgICBlbHNlIGlmIChiID09ICdcbicpIHsKKwkJLy8gaWYgbGluZSB0ZXJtaW5hdG9yIGlzIFxuCisJCWlmIChsYXN0YjEgPT0gJ1xuJykKKwkJICAgIGluSGVhZGVyID0gZmFsc2U7CisJCS8vIGlmIGxpbmUgdGVybWluYXRvciBpcyBDUkxGCisJCWVsc2UgaWYgKGxhc3RiMSA9PSAnXHInICYmIGxhc3RiMiA9PSAnXG4nKQorCQkgICAgaW5IZWFkZXIgPSBmYWxzZTsKKwkgICAgfQorCSAgICBsYXN0YjIgPSBsYXN0YjE7CisJICAgIGxhc3RiMSA9IGI7CisJfSBlbHNlCisJICAgIHNpemUrKzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShieXRlW10gYikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlpZiAoaW5IZWFkZXIpCisJICAgIHN1cGVyLndyaXRlKGIpOworCWVsc2UKKwkgICAgc2l6ZSArPSBiLmxlbmd0aDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlpZiAoaW5IZWFkZXIpCisJICAgIHN1cGVyLndyaXRlKGIsIG9mZiwgbGVuKTsKKwllbHNlCisJICAgIHNpemUgKz0gbGVuOworICAgIH0KKworICAgIHB1YmxpYyBsb25nIGdldFNpemUoKSB7CisJcmV0dXJuIHNpemU7CisgICAgfQorCisgICAgLyoKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmcgYXJndltdKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlpbnQgYjsKKwlDb250ZW50TGVuZ3RoQ291bnRlciBvcyA9IG5ldyBDb250ZW50TGVuZ3RoQ291bnRlcigpOworCXdoaWxlICgoYiA9IFN5c3RlbS5pbi5yZWFkKCkpID49IDApCisJICAgIG9zLndyaXRlKGIpOworCVN5c3RlbS5vdXQucHJpbnRsbigic2l6ZSAiICsgb3MuZ2V0U2l6ZSgpKTsKKyAgICB9CisgICAgKi8KK30KZGlmZiAtLWdpdCBhL21ib3gvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvbWJveC9Db250ZW50TGVuZ3RoVXBkYXRlci5qYXZhIGIvbWJveC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9tYm94L0NvbnRlbnRMZW5ndGhVcGRhdGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjZkNDQwOAotLS0gL2Rldi9udWxsCisrKyBiL21ib3gvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvbWJveC9Db250ZW50TGVuZ3RoVXBkYXRlci5qYXZhCkBAIC0wLDAgKzEsMTE2IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5tYm94OworCitpbXBvcnQgamF2YS5pby4qOworCisvKioKKyAqIFVwZGF0ZSB0aGUgQ29udGVudC1MZW5ndGggaGVhZGVyIGluIHRoZSBtZXNzYWdlIHdyaXR0ZW4gdG8gdGhlIHN0cmVhbS4KKyAqLworY2xhc3MgQ29udGVudExlbmd0aFVwZGF0ZXIgZXh0ZW5kcyBGaWx0ZXJPdXRwdXRTdHJlYW0geworICAgIHByaXZhdGUgU3RyaW5nIGNvbnRlbnRMZW5ndGg7CisgICAgcHJpdmF0ZSBib29sZWFuIGluSGVhZGVyID0gdHJ1ZTsKKyAgICBwcml2YXRlIGJvb2xlYW4gc2F3Q29udGVudExlbmd0aCA9IGZhbHNlOworICAgIHByaXZhdGUgaW50IGxhc3RiMSA9IC0xLCBsYXN0YjIgPSAtMTsKKyAgICBwcml2YXRlIFN0cmluZ0J1aWxkZXIgbGluZSA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisKKyAgICBwdWJsaWMgQ29udGVudExlbmd0aFVwZGF0ZXIoT3V0cHV0U3RyZWFtIG9zLCBsb25nIGNvbnRlbnRMZW5ndGgpIHsKKwlzdXBlcihvcyk7CisJdGhpcy5jb250ZW50TGVuZ3RoID0gIkNvbnRlbnQtTGVuZ3RoOiAiICsgY29udGVudExlbmd0aDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShpbnQgYikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlpZiAoaW5IZWFkZXIpIHsKKwkgICAgU3RyaW5nIGVvbCA9ICJcbiI7CisJICAgIC8vIEZpcnN0LCBkZXRlcm1pbmUgaWYgd2UncmUgc3RpbGwgaW4gdGhlIGhlYWRlci4KKwkgICAgaWYgKGIgPT0gJ1xyJykgeworCQkvLyBpZiBsaW5lIHRlcm1pbmF0b3IgaXMgQ1IKKwkJaWYgKGxhc3RiMSA9PSAnXHInKSB7CisJCSAgICBpbkhlYWRlciA9IGZhbHNlOworCQkgICAgZW9sID0gIlxyIjsKKwkJLy8gZWxzZSwgaWYgbGluZSB0ZXJtaW5hdG9yIGlzIENSTEYKKwkJfSBlbHNlIGlmIChsYXN0YjEgPT0gJ1xuJyAmJiBsYXN0YjIgPT0gJ1xyJykgeworCQkgICAgaW5IZWFkZXIgPSBmYWxzZTsKKwkJICAgIGVvbCA9ICJcclxuIjsKKwkJfQorCSAgICAvLyBlbHNlLCBpZiBsaW5lIHRlcm1pbmF0b3IgaXMgXG4KKwkgICAgfSBlbHNlIGlmIChiID09ICdcbicpIHsKKwkJaWYgKGxhc3RiMSA9PSAnXG4nKSB7CisJCSAgICBpbkhlYWRlciA9IGZhbHNlOworCQkgICAgZW9sID0gIlxuIjsKKwkJfQorCSAgICB9CisKKwkgICAgLy8gSWYgd2UncmUgbm8gbG9uZ2VyIGluIHRoZSBoZWFkZXIsIGFuZCB3ZSBoYXZlbid0IHNlZW4KKwkgICAgLy8gYSBDb250ZW50LUxlbmd0aCBoZWFkZXIgeWV0LCBpdCdzIHRpbWUgdG8gcHV0IG9uZSBvdXQuCisJICAgIGlmICghaW5IZWFkZXIgJiYgIXNhd0NvbnRlbnRMZW5ndGgpIHsKKwkJb3V0LndyaXRlKGNvbnRlbnRMZW5ndGguZ2V0Qnl0ZXMoImlzby04ODU5LTEiKSk7CisJCW91dC53cml0ZShlb2wuZ2V0Qnl0ZXMoImlzby04ODU5LTEiKSk7CisJICAgIH0KKworCSAgICAvLyBJZiB3ZSBoYXZlIGEgZnVsbCBsaW5lLCBzZWUgaWYgaXQncyBhIENvbnRlbnQtTGVuZ3RoIGhlYWRlci4KKwkgICAgaWYgKGIgPT0gJ1xyJyB8fCAoYiA9PSAnXG4nICYmIGxhc3RiMSAhPSAnXHInKSkgeworCQlpZiAobGluZS50b1N0cmluZygpLnJlZ2lvbk1hdGNoZXModHJ1ZSwgMCwKKwkJCQkJImNvbnRlbnQtbGVuZ3RoOiIsIDAsIDE1KSkgeworCQkgICAgLy8geXVwLCBnb3QgaXQKKwkJICAgIHNhd0NvbnRlbnRMZW5ndGggPSB0cnVlOworCQkgICAgLy8gcHV0IG91dCB0aGUgbmV3IHZlcnNpb24KKwkJICAgIG91dC53cml0ZShjb250ZW50TGVuZ3RoLmdldEJ5dGVzKCJpc28tODg1OS0xIikpOworCQl9IGVsc2UgeworCQkgICAgLy8gbm90IGEgQ29udGVudC1MZW5ndGggaGVhZGVyLCBqdXN0IHdyaXRlIGl0IG91dAorCQkgICAgb3V0LndyaXRlKGxpbmUudG9TdHJpbmcoKS5nZXRCeXRlcygiaXNvLTg4NTktMSIpKTsKKwkJfQorCQlsaW5lLnNldExlbmd0aCgwKTsJLy8gY2xlYXIgYnVmZmVyIGZvciBuZXh0IGxpbmUKKwkgICAgfQorCSAgICBpZiAoYiA9PSAnXHInIHx8IGIgPT0gJ1xuJykKKwkJb3V0LndyaXRlKGIpOwkvLyB3cml0ZSBvdXQgbGluZSB0ZXJtaW5hdG9yIGltbWVkaWF0ZWx5CisJICAgIGVsc2UKKwkJbGluZS5hcHBlbmQoKGNoYXIpYik7CS8vIGFjY3VtdWxhdGUgY2hhcmFjdGVycyBvZiB0aGUgbGluZQorCisJICAgIC8vIHJvdGF0ZSBzYXZlZCBjaGFyYWN0ZXJzIGZvciBuZXh0IHRpbWUgdGhyb3VnaCBsb29wCisJICAgIGxhc3RiMiA9IGxhc3RiMTsKKwkgICAgbGFzdGIxID0gYjsKKwl9IGVsc2UKKwkgICAgb3V0LndyaXRlKGIpOwkJLy8gbm90IGluIHRoZSBoZWFkZXIsIGp1c3Qgd3JpdGUgaXQgb3V0CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGUoYnl0ZVtdIGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJaWYgKGluSGVhZGVyKQorCSAgICB3cml0ZShiLCAwLCBiLmxlbmd0aCk7CisJZWxzZQorCSAgICBvdXQud3JpdGUoYik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGUoYnl0ZVtdIGIsIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJaWYgKGluSGVhZGVyKSB7CisJICAgIGZvciAoaW50IGkgPSAwIDsgaSA8IGxlbiA7IGkrKykgeworCQl3cml0ZShiW29mZiArIGldKTsKKwkgICAgfQorCX0gZWxzZQorCSAgICBvdXQud3JpdGUoYiwgb2ZmLCBsZW4pOworICAgIH0KKworICAgIC8vIGZvciB0ZXN0aW5nCisgICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nIGFyZ3ZbXSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJaW50IGI7CisJQ29udGVudExlbmd0aFVwZGF0ZXIgb3MgPQorCSAgICBuZXcgQ29udGVudExlbmd0aFVwZGF0ZXIoU3lzdGVtLm91dCwgTG9uZy5wYXJzZUxvbmcoYXJndlswXSkpOworCXdoaWxlICgoYiA9IFN5c3RlbS5pbi5yZWFkKCkpID49IDApCisJICAgIG9zLndyaXRlKGIpOworCW9zLmZsdXNoKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWJveC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9tYm94L0RlZmF1bHRNYWlsYm94LmphdmEgYi9tYm94L3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL21ib3gvRGVmYXVsdE1haWxib3guamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iYWMwYjA1Ci0tLSAvZGV2L251bGwKKysrIGIvbWJveC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9tYm94L0RlZmF1bHRNYWlsYm94LmphdmEKQEAgLTAsMCArMSwxMDYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLm1ib3g7CisKK2ltcG9ydCBqYXZhLmlvLio7CisKK3B1YmxpYyBjbGFzcyBEZWZhdWx0TWFpbGJveCBleHRlbmRzIE1haWxib3ggeworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGhvbWU7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIGhvbWVSZWxhdGl2ZSA9CisJCQkJQm9vbGVhbi5nZXRCb29sZWFuKCJtYWlsLm1ib3guaG9tZXJlbGF0aXZlIik7CisKKyAgICBwdWJsaWMgRGVmYXVsdE1haWxib3goKSB7CisJaG9tZSA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgidXNlci5ob21lIik7CisgICAgfQorCisgICAgcHVibGljIE1haWxGaWxlIGdldE1haWxGaWxlKFN0cmluZyB1c2VyLCBTdHJpbmcgZm9sZGVyKSB7CisJcmV0dXJuIG5ldyBEZWZhdWx0TWFpbEZpbGUoZmlsZW5hbWUodXNlciwgZm9sZGVyKSk7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBmaWxlbmFtZShTdHJpbmcgdXNlciwgU3RyaW5nIGZvbGRlcikgeworCXRyeSB7CisJICAgIGNoYXIgYyA9IGZvbGRlci5jaGFyQXQoMCk7CisJICAgIGlmIChjID09IEZpbGUuc2VwYXJhdG9yQ2hhcikgeworCQlyZXR1cm4gZm9sZGVyOworCSAgICB9IGVsc2UgaWYgKGMgPT0gJ34nKSB7CisJCWludCBpID0gZm9sZGVyLmluZGV4T2YoRmlsZS5zZXBhcmF0b3JDaGFyKTsKKwkJU3RyaW5nIHRhaWwgPSAiIjsKKwkJaWYgKGkgPiAwKSB7CisJCSAgICB0YWlsID0gZm9sZGVyLnN1YnN0cmluZyhpKTsKKwkJICAgIGZvbGRlciA9IGZvbGRlci5zdWJzdHJpbmcoMCwgaSk7CisJCX0KKwkJcmV0dXJuIGhvbWUgKyB0YWlsOworCSAgICB9IGVsc2UgeworCQlpZiAoZm9sZGVyLmVxdWFsc0lnbm9yZUNhc2UoIklOQk9YIikpCisJCSAgICBmb2xkZXIgPSAiSU5CT1giOworCQlpZiAoaG9tZVJlbGF0aXZlKQorCQkgICAgcmV0dXJuIGhvbWUgKyBGaWxlLnNlcGFyYXRvciArIGZvbGRlcjsKKwkJZWxzZQorCQkgICAgcmV0dXJuIGZvbGRlcjsKKwkgICAgfQorCX0gY2F0Y2ggKFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworCSAgICByZXR1cm4gZm9sZGVyOworCX0KKyAgICB9Cit9CisKK2NsYXNzIERlZmF1bHRNYWlsRmlsZSBleHRlbmRzIEZpbGUgaW1wbGVtZW50cyBNYWlsRmlsZSB7CisgICAgcHJvdGVjdGVkIHRyYW5zaWVudCBSYW5kb21BY2Nlc3NGaWxlIGZpbGU7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAzNzEzMTE2Njk3NTIzNzYxNjg0TDsKKworICAgIERlZmF1bHRNYWlsRmlsZShTdHJpbmcgbmFtZSkgeworCXN1cGVyKG5hbWUpOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGxvY2soU3RyaW5nIG1vZGUpIHsKKwl0cnkgeworCSAgICBmaWxlID0gbmV3IFJhbmRvbUFjY2Vzc0ZpbGUodGhpcywgbW9kZSk7CisJICAgIHJldHVybiB0cnVlOworCX0gY2F0Y2ggKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBmZSkgeworCSAgICByZXR1cm4gZmFsc2U7CisJfSBjYXRjaCAoSU9FeGNlcHRpb24gaWUpIHsKKwkgICAgZmlsZSA9IG51bGw7CisJICAgIHJldHVybiBmYWxzZTsKKwl9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5sb2NrKCkgeyAKKwlpZiAoZmlsZSAhPSBudWxsKSB7CisJICAgIHRyeSB7CisJCWZpbGUuY2xvc2UoKTsKKwkgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworCQkvLyBpZ25vcmUgaXQKKwkgICAgfQorCSAgICBmaWxlID0gbnVsbDsKKwl9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdG91Y2hsb2NrKCkgeworICAgIH0KKworICAgIHB1YmxpYyBGaWxlRGVzY3JpcHRvciBnZXRGRCgpIHsKKwlpZiAoZmlsZSA9PSBudWxsKQorCSAgICByZXR1cm4gbnVsbDsKKwl0cnkgeworCSAgICByZXR1cm4gZmlsZS5nZXRGRCgpOworCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKwkgICAgcmV0dXJuIG51bGw7CisJfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL21ib3gvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvbWJveC9GaWxlSW50ZXJmYWNlLmphdmEgYi9tYm94L3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL21ib3gvRmlsZUludGVyZmFjZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg5MWYwZDUKLS0tIC9kZXYvbnVsbAorKysgYi9tYm94L3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL21ib3gvRmlsZUludGVyZmFjZS5qYXZhCkBAIC0wLDAgKzEsMTQzIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5tYm94OworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZW5hbWVGaWx0ZXI7CisKK3B1YmxpYyBpbnRlcmZhY2UgRmlsZUludGVyZmFjZSB7CisgICAgLyoqCisgICAgICogR2V0cyB0aGUgbmFtZSBvZiB0aGUgZmlsZS4gVGhpcyBtZXRob2QgZG9lcyBub3QgaW5jbHVkZSB0aGUKKyAgICAgKiBkaXJlY3RvcnkuCisgICAgICogQHJldHVybiB0aGUgZmlsZSBuYW1lLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgcGF0aCBvZiB0aGUgZmlsZS4KKyAgICAgKiBAcmV0dXJuIHRoZSBmaWxlIHBhdGguCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRQYXRoKCk7CisKKyAgICAvKioKKyAgICAgKiBHZXRzIHRoZSBhYnNvbHV0ZSBwYXRoIG9mIHRoZSBmaWxlLgorICAgICAqIEByZXR1cm4gdGhlIGFic29sdXRlIGZpbGUgcGF0aC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEFic29sdXRlUGF0aCgpOworCisgICAgLyoqCisgICAgICogR2V0cyB0aGUgb2ZmaWNpYWwsIGNhbm9uaWNhbCBwYXRoIG9mIHRoZSBGaWxlLgorICAgICAqIEByZXR1cm4gY2Fub25pY2FsIHBhdGgKKyAgICAgKi8KKyAgICAvLyBYWFggLSBKREsxLjEKKyAgICAvLyBwdWJsaWMgU3RyaW5nIGdldENhbm9uaWNhbFBhdGgoKTsKKworICAgIC8qKgorICAgICAqIEdldHMgdGhlIG5hbWUgb2YgdGhlIHBhcmVudCBkaXJlY3RvcnkuCisgICAgICogQHJldHVybiB0aGUgcGFyZW50IGRpcmVjdG9yeSwgb3IgbnVsbCBpZiBvbmUgaXMgbm90IGZvdW5kLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UGFyZW50KCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgYm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgb3Igbm90IGEgZmlsZSBleGlzdHMuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZXhpc3RzKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgYm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgb3Igbm90IGEgd3JpdGFibGUgZmlsZSAKKyAgICAgKiBleGlzdHMuIAorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNhbldyaXRlKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgYm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgb3Igbm90IGEgcmVhZGFibGUgZmlsZSAKKyAgICAgKiBleGlzdHMuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gY2FuUmVhZCgpOworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIGJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIG9yIG5vdCBhIG5vcm1hbCBmaWxlIAorICAgICAqIGV4aXN0cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0ZpbGUoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBib29sZWFuIGluZGljYXRpbmcgd2hldGhlciBvciBub3QgYSBkaXJlY3RvcnkgZmlsZSAKKyAgICAgKiBleGlzdHMuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaXNEaXJlY3RvcnkoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYSBib29sZWFuIGluZGljYXRpbmcgd2hldGhlciB0aGUgZmlsZSBuYW1lIGlzIGFic29sdXRlLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzQWJzb2x1dGUoKTsKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGxhc3QgbW9kaWZpY2F0aW9uIHRpbWUuIFRoZSByZXR1cm4gdmFsdWUgc2hvdWxkCisgICAgICogb25seSBiZSB1c2VkIHRvIGNvbXBhcmUgbW9kaWZpY2F0aW9uIGRhdGVzLiBJdCBpcyBtZWFuaW5nbGVzcworICAgICAqIGFzIGFuIGFic29sdXRlIHRpbWUuCisgICAgICovCisgICAgcHVibGljIGxvbmcgbGFzdE1vZGlmaWVkKCk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBsZW5ndGggb2YgdGhlIGZpbGUuIAorICAgICAqLworICAgIHB1YmxpYyBsb25nIGxlbmd0aCgpOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIGRpcmVjdG9yeSBhbmQgcmV0dXJucyBhIGJvb2xlYW4gaW5kaWNhdGluZyB0aGUKKyAgICAgKiBzdWNjZXNzIG9mIHRoZSBjcmVhdGlvbi4gIFdpbGwgcmV0dXJuIGZhbHNlIGlmIHRoZSBkaXJlY3RvcnkgYWxyZWFkeQorICAgICAqIGV4aXN0cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBta2RpcigpOworCisgICAgLyoqCisgICAgICogUmVuYW1lcyBhIGZpbGUgYW5kIHJldHVybnMgYSBib29sZWFuIGluZGljYXRpbmcgd2hldGhlciAKKyAgICAgKiBvciBub3QgdGhpcyBtZXRob2Qgd2FzIHN1Y2Nlc3NmdWwuCisgICAgICogQHBhcmFtIGRlc3QgdGhlIG5ldyBmaWxlIG5hbWUKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiByZW5hbWVUbyhGaWxlIGRlc3QpOworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbGwgZGlyZWN0b3JpZXMgaW4gdGhpcyBwYXRoLiAgVGhpcyBtZXRob2QgCisgICAgICogcmV0dXJucyB0cnVlIGlmIHRoZSB0YXJnZXQgKGRlZXBlc3QpIGRpcmVjdG9yeSB3YXMgY3JlYXRlZCwKKyAgICAgKiBmYWxzZSBpZiB0aGUgdGFyZ2V0IGRpcmVjdG9yeSB3YXMgbm90IGNyZWF0ZWQgKGUuZy4sIGlmIGl0CisgICAgICogZXhpc3RlZCBwcmV2aW91c2x5KS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBta2RpcnMoKTsKKworICAgIC8qKgorICAgICAqIExpc3RzIHRoZSBmaWxlcyBpbiBhIGRpcmVjdG9yeS4gV29ya3Mgb25seSBvbiBkaXJlY3Rvcmllcy4KKyAgICAgKiBAcmV0dXJuIGFuIGFycmF5IG9mIGZpbGUgbmFtZXMuICBUaGlzIGxpc3Qgd2lsbCBpbmNsdWRlIGFsbAorICAgICAqIGZpbGVzIGluIHRoZSBkaXJlY3RvcnkgZXhjZXB0IHRoZSBlcXVpdmFsZW50IG9mICIuIiBhbmQgIi4uIiAuCisgICAgICovCisgICAgcHVibGljIFN0cmluZ1tdIGxpc3QoKTsKKworICAgIC8qKgorICAgICAqIFVzZXMgdGhlIHNwZWNpZmllZCBmaWx0ZXIgdG8gbGlzdCBmaWxlcyBpbiBhIGRpcmVjdG9yeS4gCisgICAgICogQHBhcmFtIGZpbHRlciB0aGUgZmlsdGVyIHVzZWQgdG8gc2VsZWN0IGZpbGUgbmFtZXMKKyAgICAgKiBAcmV0dXJuIHRoZSBmaWx0ZXIgc2VsZWN0ZWQgZmlsZXMgaW4gdGhpcyBkaXJlY3RvcnkuCisgICAgICogQHNlZSBGaWxlbmFtZUZpbHRlcgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdbXSBsaXN0KEZpbGVuYW1lRmlsdGVyIGZpbHRlcik7CisKKyAgICAvKioKKyAgICAgKiBEZWxldGVzIHRoZSBzcGVjaWZpZWQgZmlsZS4gUmV0dXJucyB0cnVlCisgICAgICogaWYgdGhlIGZpbGUgY291bGQgYmUgZGVsZXRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBkZWxldGUoKTsKK30KZGlmZiAtLWdpdCBhL21ib3gvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvbWJveC9JbmJveEZpbGUuamF2YSBiL21ib3gvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvbWJveC9JbmJveEZpbGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNGZmZmQ1Ci0tLSAvZGV2L251bGwKKysrIGIvbWJveC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9tYm94L0luYm94RmlsZS5qYXZhCkBAIC0wLDAgKzEsMjIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLm1ib3g7CisKK3B1YmxpYyBpbnRlcmZhY2UgSW5ib3hGaWxlIGV4dGVuZHMgTWFpbEZpbGUgeworICAgIHB1YmxpYyBib29sZWFuIG9wZW5Mb2NrKFN0cmluZyBtb2RlKTsKKyAgICBwdWJsaWMgdm9pZCBjbG9zZUxvY2soKTsKK30KZGlmZiAtLWdpdCBhL21ib3gvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvbWJveC9MaW5lQ291bnRlci5qYXZhIGIvbWJveC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9tYm94L0xpbmVDb3VudGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWFlNDA4NAotLS0gL2Rldi9udWxsCisrKyBiL21ib3gvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvbWJveC9MaW5lQ291bnRlci5qYXZhCkBAIC0wLDAgKzEsNjQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLm1ib3g7CisKK2ltcG9ydCBqYXZhLmlvLio7CisKKy8qKgorICogQ291bnQgbnVtYmVyIG9mIGxpbmVzIG91dHB1dC4KKyAqLworY2xhc3MgTGluZUNvdW50ZXIgZXh0ZW5kcyBGaWx0ZXJPdXRwdXRTdHJlYW0geworICAgIHByaXZhdGUgaW50IGxhc3RiID0gLTE7CisgICAgcHJvdGVjdGVkIGludCBsaW5lQ291bnQ7CisKKyAgICBwdWJsaWMgTGluZUNvdW50ZXIoT3V0cHV0U3RyZWFtIG9zKSB7CisJc3VwZXIob3MpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKGludCBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworCS8vIElmIHdlIGhhdmUgYSBmdWxsIGxpbmUsIGNvdW50IGl0LgorCWlmIChiID09ICdccicgfHwgKGIgPT0gJ1xuJyAmJiBsYXN0YiAhPSAnXHInKSkKKwkgICAgbGluZUNvdW50Kys7CisJb3V0LndyaXRlKGIpOworCWxhc3RiID0gYjsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShieXRlW10gYikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwl3cml0ZShiLCAwLCBiLmxlbmd0aCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGUoYnl0ZVtdIGIsIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJZm9yIChpbnQgaSA9IDAgOyBpIDwgbGVuIDsgaSsrKSB7CisJICAgIHdyaXRlKGJbb2ZmICsgaV0pOworCX0KKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldExpbmVDb3VudCgpIHsKKwlyZXR1cm4gbGluZUNvdW50OworICAgIH0KKworICAgIC8vIGZvciB0ZXN0aW5nCisgICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nIGFyZ3ZbXSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJaW50IGI7CisJTGluZUNvdW50ZXIgb3MgPQorCSAgICBuZXcgTGluZUNvdW50ZXIoU3lzdGVtLm91dCk7CisJd2hpbGUgKChiID0gU3lzdGVtLmluLnJlYWQoKSkgPj0gMCkKKwkgICAgb3Mud3JpdGUoYik7CisJb3MuZmx1c2goKTsKKwlTeXN0ZW0ub3V0LnByaW50bG4ob3MuZ2V0TGluZUNvdW50KCkpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21ib3gvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvbWJveC9NYWlsRmlsZS5qYXZhIGIvbWJveC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9tYm94L01haWxGaWxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjc5MGZjZQotLS0gL2Rldi9udWxsCisrKyBiL21ib3gvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvbWJveC9NYWlsRmlsZS5qYXZhCkBAIC0wLDAgKzEsMjYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLm1ib3g7CisKK2ltcG9ydCBqYXZhLmlvLkZpbGVEZXNjcmlwdG9yOworCitwdWJsaWMgaW50ZXJmYWNlIE1haWxGaWxlIGV4dGVuZHMgRmlsZUludGVyZmFjZSB7CisgICAgcHVibGljIGJvb2xlYW4gbG9jayhTdHJpbmcgbW9kZSk7CisgICAgcHVibGljIHZvaWQgdW5sb2NrKCk7CisgICAgcHVibGljIHZvaWQgdG91Y2hsb2NrKCk7CisgICAgcHVibGljIEZpbGVEZXNjcmlwdG9yIGdldEZEKCk7Cit9CmRpZmYgLS1naXQgYS9tYm94L3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL21ib3gvTWFpbGJveC5qYXZhIGIvbWJveC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9tYm94L01haWxib3guamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iOTAyMTIxCi0tLSAvZGV2L251bGwKKysrIGIvbWJveC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9tYm94L01haWxib3guamF2YQpAQCAtMCwwICsxLDI5IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5tYm94OworCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgTWFpbGJveCB7CisgICAgLyoqCisgICAgICogUmV0dXJuIGEgTWFpbEZpbGUgb2JqZWN0IGZvciB0aGUgc3BlY2lmaWVkIHVzZXIncyBmb2xkZXIuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IE1haWxGaWxlIGdldE1haWxGaWxlKFN0cmluZyB1c2VyLCBTdHJpbmcgZm9sZGVyKTsKKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgZmlsZSBuYW1lIGNvcnJlc3BvbmRpbmcgdG8gYSBmb2xkZXIgd2l0aCB0aGUgZ2l2ZW4gbmFtZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGZpbGVuYW1lKFN0cmluZyB1c2VyLCBTdHJpbmcgZm9sZGVyKTsKK30KZGlmZiAtLWdpdCBhL21ib3gvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvbWJveC9NYm94Rm9sZGVyLmphdmEgYi9tYm94L3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL21ib3gvTWJveEZvbGRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM0MGI4NGYKLS0tIC9kZXYvbnVsbAorKysgYi9tYm94L3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL21ib3gvTWJveEZvbGRlci5qYXZhCkBAIC0wLDAgKzEsMTE2NCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwubWJveDsKKworaW1wb3J0IGphdmF4Lm1haWwuKjsKK2ltcG9ydCBqYXZheC5tYWlsLmV2ZW50Lio7CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC4qOworaW1wb3J0IGphdmF4Lm1haWwudXRpbC4qOworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5MaW5lSW5wdXRTdHJlYW07CisKKy8qKgorICogVGhpcyBjbGFzcyByZXByZXNlbnRzIGEgbWFpbGJveCBmaWxlIGNvbnRhaW5pbmcgUkZDODIyIHN0eWxlIGVtYWlsIG1lc3NhZ2VzLiAKKyAqCisgKiBAYXV0aG9yIEpvaG4gTWFuaQorICogQGF1dGhvciBCaWxsIFNoYW5ub24KKyAqLworCitwdWJsaWMgY2xhc3MgTWJveEZvbGRlciBleHRlbmRzIEZvbGRlciB7CisKKyAgICBwcml2YXRlIFN0cmluZyBuYW1lOwkvLyBudWxsID0+IHRoZSBkZWZhdWx0IGZvbGRlcgorICAgIHByaXZhdGUgYm9vbGVhbiBpc19pbmJveCA9IGZhbHNlOworICAgIHByaXZhdGUgaW50IHRvdGFsOwkJLy8gdG90YWwgbnVtYmVyIG9mIG1lc3NhZ2VzIGluIG1haWxib3gKKyAgICBwcml2YXRlIHZvbGF0aWxlIGJvb2xlYW4gb3BlbmVkID0gZmFsc2U7CisgICAgcHJpdmF0ZSBMaXN0PE1lc3NhZ2VNZXRhZGF0YT4gbWVzc2FnZXM7CisgICAgcHJpdmF0ZSBUZW1wRmlsZSB0ZW1wOworICAgIHByaXZhdGUgTWJveFN0b3JlIG1zdG9yZTsKKyAgICBwcml2YXRlIE1haWxGaWxlIGZvbGRlcjsKKyAgICBwcml2YXRlIGxvbmcgZmlsZV9zaXplOwkvLyB0aGUgc2l6ZSB0aGUgbGFzdCB0aW1lIHdlIHJlYWQgb3Igd3JvdGUgaXQKKyAgICBwcml2YXRlIGxvbmcgc2F2ZWRfZmlsZV9zaXplOyAvLyBzaXplIGF0IHRoZSBsYXN0IG9wZW4sIGNsb3NlLCBvciBleHB1bmdlCisgICAgcHJpdmF0ZSBib29sZWFuIHNwZWNpYWxfaW1hcF9tZXNzYWdlOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBob21lUmVsYXRpdmUgPQorCQkJCUJvb2xlYW4uZ2V0Qm9vbGVhbigibWFpbC5tYm94LmhvbWVyZWxhdGl2ZSIpOworCisgICAgLyoqCisgICAgICogTWV0YWRhdGEgZm9yIGVhY2ggbWVzc2FnZSwgdG8gYXZvaWQgaW5zdGFudGlhdGluZyBNYm94TWVzc2FnZQorICAgICAqIG9iamVjdHMgZm9yIG1lc3NhZ2VzIHdlJ3JlIG5vdCBnb2luZyB0byBsb29rIGF0LiA8cD4KKyAgICAgKgorICAgICAqIE1ib3hGb2xkZXIga2VlcHMgYW4gYXJyYXkgb2YgdGhlc2Ugb2JqZWN0cyBjb3JyZXNwb25kaW5nIHRvCisgICAgICogZWFjaCBtZXNzYWdlIGluIHRoZSBmb2xkZXIuICBBY2Nlc3MgdG8gdGhlIGFycmF5IGVsZW1lbnRzIGlzCisgICAgICogc3luY2hyb25pemVkLCBidXQgYWNjZXNzIHRvIGNvbnRlbnRzIG9mIHRoaXMgb2JqZWN0IGlzIG5vdC4KKyAgICAgKiBUaGUgbWV0YWRhdGEgc3RvcmVkIGhlcmUgaXMgb25seSBhY2Nlc3NlZCBpZiB0aGUgbWVzc2FnZSBmaWVsZAorICAgICAqIGlzIG51bGw7IG90aGVyd2lzZSB0aGUgTWJveE1lc3NhZ2Ugb2JqZWN0IGNvbnRhaW5zIHRoZSBtZXRhZGF0YS4KKyAgICAgKi8KKyAgICBzdGF0aWMgZmluYWwgY2xhc3MgTWVzc2FnZU1ldGFkYXRhIHsKKwlwdWJsaWMgbG9uZyBzdGFydDsJLy8gb2Zmc2V0IGluIHRlbXAgZmlsZSBvZiBzdGFydCBvZiB0aGlzIG1lc3NhZ2UKKwkvLyBwdWJsaWMgbG9uZyBlbmQ7CS8vIG9mZnNldCBpbiB0ZW1wIGZpbGUgb2YgZW5kIG9mIHRoaXMgbWVzc2FnZQorCXB1YmxpYyBsb25nIGRhdGFlbmQ7CS8vIG9mZnNldCBvZiBlbmQgb2YgbWVzc2FnZSBkYXRhLCA8PSAiZW5kIgorCXB1YmxpYyBNYm94TWVzc2FnZSBtZXNzYWdlOwkvLyB0aGUgbWVzc2FnZSBpdHNlbGYKKwlwdWJsaWMgYm9vbGVhbiByZWNlbnQ7CS8vIG1lc3NhZ2UgaXMgcmVjZW50PworCXB1YmxpYyBib29sZWFuIGRlbGV0ZWQ7CS8vIG1lc3NhZ2UgaXMgbWFya2VkIGRlbGV0ZWQ/CisJcHVibGljIGJvb2xlYW4gaW1hcDsJLy8gc3BlY2lhbCBpbWFwIG1lc3NhZ2U/CisgICAgfQorCisgICAgcHVibGljIE1ib3hGb2xkZXIoTWJveFN0b3JlIHN0b3JlLCBTdHJpbmcgbmFtZSkgeworCXN1cGVyKHN0b3JlKTsKKwl0aGlzLm1zdG9yZSA9IHN0b3JlOworCXRoaXMubmFtZSA9IG5hbWU7CisKKwlpZiAobmFtZSAhPSBudWxsICYmIG5hbWUuZXF1YWxzSWdub3JlQ2FzZSgiSU5CT1giKSkKKwkgICAgaXNfaW5ib3ggPSB0cnVlOworCisJZm9sZGVyID0gbXN0b3JlLmdldE1haWxGaWxlKG5hbWUgPT0gbnVsbCA/ICJ+IiA6IG5hbWUpOworCWlmIChmb2xkZXIuZXhpc3RzKCkpCisJICAgIHNhdmVkX2ZpbGVfc2l6ZSA9IGZvbGRlci5sZW5ndGgoKTsKKwllbHNlCisJICAgIHNhdmVkX2ZpbGVfc2l6ZSA9IC0xOworICAgIH0KKworICAgIHB1YmxpYyBjaGFyIGdldFNlcGFyYXRvcigpIHsKKwlyZXR1cm4gRmlsZS5zZXBhcmF0b3JDaGFyOworICAgIH0KKworICAgIHB1YmxpYyBGb2xkZXJbXSBsaXN0KFN0cmluZyBwYXR0ZXJuKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpZiAoIWZvbGRlci5pc0RpcmVjdG9yeSgpKQorCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKCJub3QgYSBkaXJlY3RvcnkiKTsKKworCWlmIChuYW1lID09IG51bGwpCisJICAgIHJldHVybiBsaXN0KG51bGwsIHBhdHRlcm4sIHRydWUpOworCWVsc2UKKwkgICAgcmV0dXJuIGxpc3QobmFtZSArIEZpbGUuc2VwYXJhdG9yLCBwYXR0ZXJuLCBmYWxzZSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBWZXJzaW9uIG9mIGxpc3Qgc2hhcmVkIGJ5IE1ib3hTdG9yZSBhbmQgTWJveEZvbGRlci4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgRm9sZGVyW10gbGlzdChTdHJpbmcgcmVmLCBTdHJpbmcgcGF0dGVybiwgYm9vbGVhbiBmcm9tU3RvcmUpCisJCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWlmIChyZWYgIT0gbnVsbCAmJiByZWYubGVuZ3RoKCkgPT0gMCkKKwkgICAgcmVmID0gbnVsbDsKKwlpbnQgaTsKKwlTdHJpbmcgcmVmZGlyID0gbnVsbDsKKwlTdHJpbmcgcmVhbGRpciA9IG51bGw7CisKKwlwYXR0ZXJuID0gY2Fub25pY2FsaXplKHJlZiwgcGF0dGVybik7CisJaWYgKChpID0gaW5kZXhPZkFueShwYXR0ZXJuLCAiJSoiKSkgPj0gMCkgeworCSAgICByZWZkaXIgPSBwYXR0ZXJuLnN1YnN0cmluZygwLCBpKTsKKwl9IGVsc2UgeworCSAgICByZWZkaXIgPSBwYXR0ZXJuOworCX0KKwlpZiAoKGkgPSByZWZkaXIubGFzdEluZGV4T2YoRmlsZS5zZXBhcmF0b3JDaGFyKSkgPj0gMCkgeworCSAgICAvLyBnZXQgcmlkIG9mIGFueXRoaW5nIGFmdGVyIGRpcmVjdG9yeSBuYW1lCisJICAgIHJlZmRpciA9IHJlZmRpci5zdWJzdHJpbmcoMCwgaSArIDEpOworCSAgICByZWFsZGlyID0gbXN0b3JlLm1iLmZpbGVuYW1lKG1zdG9yZS51c2VyLCByZWZkaXIpOworCX0gZWxzZSBpZiAocmVmZGlyLmxlbmd0aCgpID09IDAgfHwgcmVmZGlyLmNoYXJBdCgwKSAhPSAnficpIHsKKwkgICAgLy8gbm8gc2VwYXJhdG9yIGFuZCBkb2Vzbid0IHN0YXJ0IHdpdGggIn4iID0+IGhvbWUgb3IgY3dkCisJICAgIHJlZmRpciA9IG51bGw7CisJICAgIGlmIChob21lUmVsYXRpdmUpCisJCXJlYWxkaXIgPSBtc3RvcmUuaG9tZTsKKwkgICAgZWxzZQorCQlyZWFsZGlyID0gIi4iOworCX0gZWxzZSB7CisJICAgIHJlYWxkaXIgPSBtc3RvcmUubWIuZmlsZW5hbWUobXN0b3JlLnVzZXIsIHJlZmRpcik7CisJfQorCUxpc3Q8U3RyaW5nPiBmbGlzdCA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpOworCWxpc3RXb3JrKHJlYWxkaXIsIHJlZmRpciwgcGF0dGVybiwgZnJvbVN0b3JlID8gMCA6IDEsIGZsaXN0KTsKKwlpZiAoTWF0Y2gucGF0aCgiSU5CT1giLCBwYXR0ZXJuLCAnXDAnKSkKKwkgICAgZmxpc3QuYWRkKCJJTkJPWCIpOworCisJRm9sZGVyIGZsW10gPSBuZXcgRm9sZGVyW2ZsaXN0LnNpemUoKV07CisJZm9yIChpID0gMDsgaSA8IGZsLmxlbmd0aDsgaSsrKSB7CisJICAgIGZsW2ldID0gY3JlYXRlRm9sZGVyKG1zdG9yZSwgZmxpc3QuZ2V0KGkpKTsKKwl9CisJcmV0dXJuIGZsOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKKwlpZiAobmFtZSA9PSBudWxsKQorCSAgICByZXR1cm4gIiI7CisJZWxzZSBpZiAoaXNfaW5ib3gpCisJICAgIHJldHVybiAiSU5CT1giOworCWVsc2UKKwkgICAgcmV0dXJuIGZvbGRlci5nZXROYW1lKCk7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRGdWxsTmFtZSgpIHsKKwlpZiAobmFtZSA9PSBudWxsKQorCSAgICByZXR1cm4gIiI7CisJZWxzZQorCSAgICByZXR1cm4gbmFtZTsKKyAgICB9CisKKyAgICBwdWJsaWMgRm9sZGVyIGdldFBhcmVudCgpIHsKKwlpZiAobmFtZSA9PSBudWxsKQorCSAgICByZXR1cm4gbnVsbDsKKwllbHNlIGlmIChpc19pbmJveCkKKwkgICAgcmV0dXJuIGNyZWF0ZUZvbGRlcihtc3RvcmUsIG51bGwpOworCWVsc2UKKwkgICAgLy8gWFhYIC0gaGF2ZSB0byByZWNvZ25pemUgb3RoZXIgZm9sZGVycyB1bmRlciBkZWZhdWx0IGZvbGRlcgorCSAgICByZXR1cm4gY3JlYXRlRm9sZGVyKG1zdG9yZSwgZm9sZGVyLmdldFBhcmVudCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBleGlzdHMoKSB7CisJcmV0dXJuIGZvbGRlci5leGlzdHMoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldFR5cGUoKSB7CisJaWYgKGZvbGRlci5pc0RpcmVjdG9yeSgpKQorCSAgICByZXR1cm4gSE9MRFNfRk9MREVSUzsKKwllbHNlCisJICAgIHJldHVybiBIT0xEU19NRVNTQUdFUzsKKyAgICB9CisKKyAgICBwdWJsaWMgRmxhZ3MgZ2V0UGVybWFuZW50RmxhZ3MoKSB7CisJcmV0dXJuIE1ib3hTdG9yZS5wZXJtRmxhZ3M7CisgICAgfQorCisgICAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIGhhc05ld01lc3NhZ2VzKCkgeworCWlmIChmb2xkZXIgaW5zdGFuY2VvZiBVTklYRmlsZSkgeworCSAgICBVTklYRmlsZSBmID0gKFVOSVhGaWxlKWZvbGRlcjsKKwkgICAgaWYgKGYubGVuZ3RoKCkgPiAwKSB7CisJCWxvbmcgYXRpbWUgPSBmLmxhc3RBY2Nlc3NlZCgpOworCQlsb25nIG10aW1lID0gZi5sYXN0TW9kaWZpZWQoKTsKKy8vU3lzdGVtLm91dC5wcmludGxuKG5hbWUgKyAiIGF0aW1lICIgKyBhdGltZSArICIgbXRpbWUgIiArIG10aW1lKTsKKwkJcmV0dXJuIGF0aW1lIDwgbXRpbWU7CisJICAgIH0KKwkgICAgcmV0dXJuIGZhbHNlOworCX0KKwlsb25nIGN1cnJlbnRfc2l6ZTsKKwlpZiAoZm9sZGVyLmV4aXN0cygpKQorCSAgICBjdXJyZW50X3NpemUgPSBmb2xkZXIubGVuZ3RoKCk7CisJZWxzZQorCSAgICBjdXJyZW50X3NpemUgPSAtMTsKKwkvLyBpZiB3ZSd2ZSBuZXZlciBvcGVuZWQgdGhlIGZvbGRlciwgcmVtZW1iZXIgdGhlIHNpemUgbm93CisJLy8gKHdpbGwgY2F1c2UgdXMgdG8gcmV0dXJuIGZhbHNlIHRoZSBmaXJzdCB0aW1lKQorCWlmIChzYXZlZF9maWxlX3NpemUgPCAwKQorCSAgICBzYXZlZF9maWxlX3NpemUgPSBjdXJyZW50X3NpemU7CisJcmV0dXJuIGN1cnJlbnRfc2l6ZSA+IHNhdmVkX2ZpbGVfc2l6ZTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIEZvbGRlciBnZXRGb2xkZXIoU3RyaW5nIG5hbWUpCisJCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWlmIChmb2xkZXIuZXhpc3RzKCkgJiYgIWZvbGRlci5pc0RpcmVjdG9yeSgpKQorCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKCJub3QgYSBkaXJlY3RvcnkiKTsKKwlyZXR1cm4gY3JlYXRlRm9sZGVyKG1zdG9yZSwKKwkJKHRoaXMubmFtZSA9PSBudWxsID8gIn4iIDogdGhpcy5uYW1lKSArIEZpbGUuc2VwYXJhdG9yICsgbmFtZSk7CisgICAgfQorCisgICAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIGNyZWF0ZShpbnQgdHlwZSkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJc3dpdGNoICh0eXBlKSB7CisJY2FzZSBIT0xEU19GT0xERVJTOgorCSAgICBpZiAoIWZvbGRlci5ta2RpcnMoKSkgeworCQlyZXR1cm4gZmFsc2U7CisJICAgIH0KKwkgICAgYnJlYWs7CisKKwljYXNlIEhPTERTX01FU1NBR0VTOgorCSAgICBpZiAoZm9sZGVyLmV4aXN0cygpKSB7CisJCXJldHVybiBmYWxzZTsKKwkgICAgfQorCSAgICB0cnkgeworCQkobmV3IEZpbGVPdXRwdXRTdHJlYW0oKEZpbGUpZm9sZGVyKSkuY2xvc2UoKTsKKwkgICAgfSBjYXRjaCAoRmlsZU5vdEZvdW5kRXhjZXB0aW9uIGZlKSB7CisJCUZpbGUgcGFyZW50ID0gbmV3IEZpbGUoZm9sZGVyLmdldFBhcmVudCgpKTsKKwkJaWYgKCFwYXJlbnQubWtkaXJzKCkpCisJCSAgICB0aHJvdyBuZXcKKwkJCU1lc3NhZ2luZ0V4Y2VwdGlvbigiY2FuJ3QgY3JlYXRlIGZvbGRlcjogIiArIG5hbWUpOworCQl0cnkgeworCQkgICAgKG5ldyBGaWxlT3V0cHV0U3RyZWFtKChGaWxlKWZvbGRlcikpLmNsb3NlKCk7CisJCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4MykgeworCQkgICAgdGhyb3cgbmV3CisJCQlNZXNzYWdpbmdFeGNlcHRpb24oImNhbid0IGNyZWF0ZSBmb2xkZXI6ICIgKyBuYW1lLCBleDMpOworCQl9CisJICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKwkJdGhyb3cgbmV3CisJCSAgICBNZXNzYWdpbmdFeGNlcHRpb24oImNhbid0IGNyZWF0ZSBmb2xkZXI6ICIgKyBuYW1lLCBlKTsKKwkgICAgfQorCSAgICBicmVhazsKKworCWRlZmF1bHQ6CisJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oInR5cGUgbm90IHN1cHBvcnRlZCIpOworCX0KKwlub3RpZnlGb2xkZXJMaXN0ZW5lcnMoRm9sZGVyRXZlbnQuQ1JFQVRFRCk7CisJcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIGRlbGV0ZShib29sZWFuIHJlY3Vyc2UpCisJCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWNoZWNrQ2xvc2VkKCk7CisJaWYgKG5hbWUgPT0gbnVsbCkKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiY2FuJ3QgZGVsZXRlIGRlZmF1bHQgZm9sZGVyIik7CisJYm9vbGVhbiByZXQgPSB0cnVlOworCWlmIChyZWN1cnNlICYmIGZvbGRlci5pc0RpcmVjdG9yeSgpKQorCSAgICByZXQgPSBkZWxldGUobmV3IEZpbGUoZm9sZGVyLmdldFBhdGgoKSkpOworCWlmIChyZXQgJiYgZm9sZGVyLmRlbGV0ZSgpKSB7CisJICAgIG5vdGlmeUZvbGRlckxpc3RlbmVycyhGb2xkZXJFdmVudC5ERUxFVEVEKTsKKwkgICAgcmV0dXJuIHRydWU7CisJfQorCXJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWN1cnNpdmVseSBkZWxldGUgdGhlIHNwZWNpZmllZCBmaWxlL2RpcmVjdG9yeS4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gZGVsZXRlKEZpbGUgZikgeworCUZpbGVbXSBmaWxlcyA9IGYubGlzdEZpbGVzKCk7CisJYm9vbGVhbiByZXQgPSB0cnVlOworCWZvciAoaW50IGkgPSAwOyByZXQgJiYgaSA8IGZpbGVzLmxlbmd0aDsgaSsrKSB7CisJICAgIGlmIChmaWxlc1tpXS5pc0RpcmVjdG9yeSgpKQorCQlyZXQgPSBkZWxldGUoZmlsZXNbaV0pOworCSAgICBlbHNlCisJCXJldCA9IGZpbGVzW2ldLmRlbGV0ZSgpOworCX0KKwlyZXR1cm4gcmV0OworICAgIH0KKworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgYm9vbGVhbiByZW5hbWVUbyhGb2xkZXIgZikKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwljaGVja0Nsb3NlZCgpOworCWlmIChuYW1lID09IG51bGwpCisJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oImNhbid0IHJlbmFtZSBkZWZhdWx0IGZvbGRlciIpOworCWlmICghKGYgaW5zdGFuY2VvZiBNYm94Rm9sZGVyKSkKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiY2FuJ3QgcmVuYW1lIHRvOiAiICsgZi5nZXROYW1lKCkpOworCVN0cmluZyBuZXduYW1lID0gKChNYm94Rm9sZGVyKWYpLmZvbGRlci5nZXRQYXRoKCk7CisJaWYgKGZvbGRlci5yZW5hbWVUbyhuZXcgRmlsZShuZXduYW1lKSkpIHsKKwkgICAgbm90aWZ5Rm9sZGVyUmVuYW1lZExpc3RlbmVycyhmKTsKKwkgICAgcmV0dXJuIHRydWU7CisJfQorCXJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvKiBFbnN1cmUgdGhlIGZvbGRlciBpcyBvcGVuICovCisgICAgdm9pZCBjaGVja09wZW4oKSB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIHsKKwlpZiAoIW9wZW5lZCkgCisJICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIkZvbGRlciBpcyBub3QgT3BlbiIpOworICAgIH0KKworICAgIC8qIEVuc3VyZSB0aGUgZm9sZGVyIGlzIG5vdCBvcGVuICovCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrQ2xvc2VkKCkgdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiB7CisJaWYgKG9wZW5lZCkgCisJICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIkZvbGRlciBpcyBPcGVuIik7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBDaGVjayB0aGF0IHRoZSBnaXZlbiBtZXNzYWdlIG51bWJlciBpcyB3aXRoaW4gdGhlIHJhbmdlCisgICAgICogb2YgbWVzc2FnZXMgcHJlc2VudCBpbiB0aGlzIGZvbGRlci4gSWYgdGhlIG1lc3NhZ2UKKyAgICAgKiBudW1iZXIgaXMgb3V0IG9mIHJhbmdlLCB3ZSBjaGVjayB0byBzZWUgaWYgbmV3IG1lc3NhZ2VzCisgICAgICogaGF2ZSBhcnJpdmVkLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBjaGVja1JhbmdlKGludCBtc2dubykgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKG1zZ25vIDwgMSkgLy8gbWVzc2FnZS1udW1iZXJzIHN0YXJ0IGF0IDEKKwkgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oIm1lc3NhZ2UgbnVtYmVyIDwgMSIpOworCisJaWYgKG1zZ25vIDw9IHRvdGFsKQorCSAgICByZXR1cm47CisKKwkvLyBPdXQgb2YgcmFuZ2UsIGxldCdzIGNoZWNrIGlmIHRoZXJlIGFyZSBhbnkgbmV3IG1lc3NhZ2VzLgorCWdldE1lc3NhZ2VDb3VudCgpOworCisJaWYgKG1zZ25vID4gdG90YWwpIC8vIFN0aWxsIG91dCBvZiByYW5nZSA/IFRocm93IHVwIC4uLgorCSAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihtc2dubyArICIgPiAiICsgdG90YWwpOworICAgIH0KKworICAgIC8qIEVuc3VyZSB0aGUgZm9sZGVyIGlzIG9wZW4gJiByZWFkYWJsZSAqLworICAgIHByaXZhdGUgdm9pZCBjaGVja1JlYWRhYmxlKCkgdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiB7CisJaWYgKCFvcGVuZWQgfHwgKG1vZGUgIT0gUkVBRF9PTkxZICYmIG1vZGUgIT0gUkVBRF9XUklURSkpCisJICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIkZvbGRlciBpcyBub3QgUmVhZGFibGUiKTsKKyAgICB9CisKKyAgICAvKiBFbnN1cmUgdGhlIGZvbGRlciBpcyBvcGVuICYgd3JpdGFibGUgKi8KKyAgICBwcml2YXRlIHZvaWQgY2hlY2tXcml0YWJsZSgpIHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24geworCWlmICghb3BlbmVkIHx8IG1vZGUgIT0gUkVBRF9XUklURSkKKwkgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiRm9sZGVyIGlzIG5vdCBXcml0YWJsZSIpOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGlzT3BlbigpIHsKKyAgICAgICAgcmV0dXJuIG9wZW5lZDsKKyAgICB9CisKKyAgICAvKgorICAgICAqIE9wZW4gdGhlIGZvbGRlciBpbiB0aGUgc3BlY2lmaWVkIG1vZGUuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIG9wZW4oaW50IG1vZGUpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWlmIChvcGVuZWQpCisJICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIkZvbGRlciBpcyBhbHJlYWR5IE9wZW4iKTsKKworCWlmICghZm9sZGVyLmV4aXN0cygpKQorCSAgICB0aHJvdyBuZXcgRm9sZGVyTm90Rm91bmRFeGNlcHRpb24odGhpcywgIkZvbGRlciBkb2Vzbid0IGV4aXN0OiAiICsKKwkJCQkJICAgIGZvbGRlci5nZXRQYXRoKCkpOworCXRoaXMubW9kZSA9IG1vZGU7CisJc3dpdGNoIChtb2RlKSB7CisJY2FzZSBSRUFEX1dSSVRFOgorCWRlZmF1bHQ6CisJICAgIGlmICghZm9sZGVyLmNhbldyaXRlKCkpCisJCXRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oIk9wZW4gRmFpbHVyZSwgY2FuJ3Qgd3JpdGU6ICIgKworCQkJCQkgICAgZm9sZGVyLmdldFBhdGgoKSk7CisJICAgIC8vIGZhbGwgdGhyb3VnaC4uLgorCisJY2FzZSBSRUFEX09OTFk6CisJICAgIGlmICghZm9sZGVyLmNhblJlYWQoKSkKKwkJdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiT3BlbiBGYWlsdXJlLCBjYW4ndCByZWFkOiAiICsKKwkJCQkJICAgIGZvbGRlci5nZXRQYXRoKCkpOworCSAgICBicmVhazsKKwl9CisKKwlpZiAoaXNfaW5ib3ggJiYgZm9sZGVyIGluc3RhbmNlb2YgSW5ib3hGaWxlKSB7CisJICAgIEluYm94RmlsZSBpbmYgPSAoSW5ib3hGaWxlKWZvbGRlcjsKKwkgICAgaWYgKCFpbmYub3BlbkxvY2sobW9kZSA9PSBSRUFEX1dSSVRFID8gInJ3IiA6ICJyIikpCisJCXRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oIkZhaWxlZCB0byBsb2NrIElOQk9YIik7CisJfQorCWlmICghZm9sZGVyLmxvY2soInIiKSkKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiRmFpbGVkIHRvIGxvY2sgZm9sZGVyOiAiICsgbmFtZSk7CisJbWVzc2FnZXMgPSBuZXcgQXJyYXlMaXN0PE1lc3NhZ2VNZXRhZGF0YT4oKTsKKwl0b3RhbCA9IDA7CisJTWVzc2FnZVtdIG1zZ2xpc3QgPSBudWxsOworCXRyeSB7CisJICAgIHRlbXAgPSBuZXcgVGVtcEZpbGUobnVsbCk7CisJICAgIHNhdmVkX2ZpbGVfc2l6ZSA9IGZvbGRlci5sZW5ndGgoKTsKKwkgICAgbXNnbGlzdCA9IGxvYWQoMEwsIGZhbHNlKTsKKwl9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oIklPRXhjZXB0aW9uIiwgZSk7CisJfSBmaW5hbGx5IHsKKwkgICAgZm9sZGVyLnVubG9jaygpOworCX0KKwlub3RpZnlDb25uZWN0aW9uTGlzdGVuZXJzKENvbm5lY3Rpb25FdmVudC5PUEVORUQpOworCWlmIChtc2dsaXN0ICE9IG51bGwpCisJICAgIG5vdGlmeU1lc3NhZ2VBZGRlZExpc3RlbmVycyhtc2dsaXN0KTsKKwlvcGVuZWQgPSB0cnVlOwkJLy8gbm93IHJlYWxseSBvcGVuZWQKKyAgICB9CisKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgY2xvc2UoYm9vbGVhbiBleHB1bmdlKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwljaGVja09wZW4oKTsKKworCXRyeSB7CisJICAgIGlmIChtb2RlID09IFJFQURfV1JJVEUpIHsKKwkJdHJ5IHsKKwkJICAgIHdyaXRlRm9sZGVyKHRydWUsIGV4cHVuZ2UpOworCQl9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisJCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKCJJL08gRXhjZXB0aW9uIiwgZSk7CisJCX0KKwkgICAgfQorCSAgICBtZXNzYWdlcyA9IG51bGw7CisJfSBmaW5hbGx5IHsKKwkgICAgb3BlbmVkID0gZmFsc2U7CisJICAgIGlmIChpc19pbmJveCAmJiBmb2xkZXIgaW5zdGFuY2VvZiBJbmJveEZpbGUpIHsKKwkJSW5ib3hGaWxlIGluZiA9IChJbmJveEZpbGUpZm9sZGVyOworCQlpbmYuY2xvc2VMb2NrKCk7CisJICAgIH0KKwkgICAgdGVtcC5jbG9zZSgpOworCSAgICB0ZW1wID0gbnVsbDsKKwkgICAgbm90aWZ5Q29ubmVjdGlvbkxpc3RlbmVycyhDb25uZWN0aW9uRXZlbnQuQ0xPU0VEKTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogUmUtd3JpdGUgdGhlIGZvbGRlciB3aXRoIHRoZSBjdXJyZW50IGNvbnRlbnRzIG9mIHRoZSBtZXNzYWdlcy4KKyAgICAgKiBJZiBjbG9zaW5nIGlzIHRydWUsIHR1cm4gb2ZmIHRoZSBSRUNFTlQgZmxhZy4gIElmIGV4cHVuZ2UgaXMKKyAgICAgKiB0cnVlLCBkb24ndCB3cml0ZSBvdXQgZGVsZXRlZCBtZXNzYWdlcyAob25seSB1c2VkIGZyb20gY2xvc2UoKQorICAgICAqIHdoZW4gdGhlIG1lc3NhZ2UgY2FjaGUgd29uJ3QgYmUgYWNjZXNzZWQgYWdhaW4pLgorICAgICAqCisgICAgICogUmV0dXJuIHRoZSBudW1iZXIgb2YgbWVzc2FnZXMgd3JpdHRlbi4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgaW50IHdyaXRlRm9sZGVyKGJvb2xlYW4gY2xvc2luZywgYm9vbGVhbiBleHB1bmdlKQorCQkJdGhyb3dzIElPRXhjZXB0aW9uLCBNZXNzYWdpbmdFeGNlcHRpb24geworCisJLyoKKwkgKiBGaXJzdCwgc2VlIGlmIHRoZXJlIGhhdmUgYmVlbiBhbnkgY2hhbmdlcy4KKwkgKi8KKwlpbnQgbW9kaWZpZWQgPSAwLCBkZWxldGVkID0gMCwgcmVjZW50ID0gMDsKKwlmb3IgKGludCBtc2dubyA9IDE7IG1zZ25vIDw9IHRvdGFsOyBtc2dubysrKSB7CisJICAgIE1lc3NhZ2VNZXRhZGF0YSBtZCA9IG1lc3NhZ2VzLmdldChtZXNzYWdlSW5kZXhPZihtc2dubykpOworCSAgICBNYm94TWVzc2FnZSBtc2cgPSBtZC5tZXNzYWdlOworCSAgICBpZiAobXNnICE9IG51bGwpIHsKKwkJRmxhZ3MgZmxhZ3MgPSBtc2cuZ2V0RmxhZ3MoKTsKKwkJaWYgKG1zZy5pc01vZGlmaWVkKCkgfHwgIW1zZy5vcmlnRmxhZ3MuZXF1YWxzKGZsYWdzKSkKKwkJICAgIG1vZGlmaWVkKys7CisJCWlmIChmbGFncy5jb250YWlucyhGbGFncy5GbGFnLkRFTEVURUQpKQorCQkgICAgZGVsZXRlZCsrOworCQlpZiAoZmxhZ3MuY29udGFpbnMoRmxhZ3MuRmxhZy5SRUNFTlQpKQorCQkgICAgcmVjZW50Kys7CisJICAgIH0gZWxzZSB7CisJCWlmIChtZC5kZWxldGVkKQorCQkgICAgZGVsZXRlZCsrOworCQlpZiAobWQucmVjZW50KQorCQkgICAgcmVjZW50Kys7CisJICAgIH0KKwl9CisJaWYgKCghY2xvc2luZyB8fCByZWNlbnQgPT0gMCkgJiYgKCFleHB1bmdlIHx8IGRlbGV0ZWQgPT0gMCkgJiYKKwkJbW9kaWZpZWQgPT0gMCkKKwkgICAgcmV0dXJuIDA7CisKKwkvKgorCSAqIEhhdmUgdG8gc2F2ZSBhbnkgbmV3IG1haWwgdGhhdCdzIGJlZW4gYXBwZW5kZWQgdG8gdGhlCisJICogZm9sZGVyIHNpbmNlIHdlIGxhc3QgbG9hZGVkIGl0LgorCSAqLworCWlmICghZm9sZGVyLmxvY2soInJ3IikpCisJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oIkZhaWxlZCB0byBsb2NrIGZvbGRlcjogIiArIG5hbWUpOworCWludCBvbGR0b3RhbCA9IHRvdGFsOwkvLyBYWFgKKwlNZXNzYWdlW10gbXNnbGlzdCA9IG51bGw7CisJaWYgKGZvbGRlci5sZW5ndGgoKSAhPSBmaWxlX3NpemUpCisJICAgIG1zZ2xpc3QgPSBsb2FkKGZpbGVfc2l6ZSwgIWNsb3NpbmcpOworCS8vIGRvbid0IHVzZSB0aGUgZm9sZGVyJ3MgRkQsIG5lZWQgdG8gcmUtb3BlbiBpbiBvcmRlciB0byB0cnVuYyB0aGUgZmlsZQorCU91dHB1dFN0cmVhbSBvcyA9CisJCW5ldyBCdWZmZXJlZE91dHB1dFN0cmVhbShuZXcgRmlsZU91dHB1dFN0cmVhbSgoRmlsZSlmb2xkZXIpKTsKKwlpbnQgd3IgPSAwOworCWJvb2xlYW4ga2VlcCA9IHRydWU7CisJdHJ5IHsKKwkgICAgaWYgKHNwZWNpYWxfaW1hcF9tZXNzYWdlKQorCQlhcHBlbmRTdHJlYW0oZ2V0TWVzc2FnZVN0cmVhbSgwKSwgb3MpOworCSAgICBmb3IgKGludCBtc2dubyA9IDE7IG1zZ25vIDw9IHRvdGFsOyBtc2dubysrKSB7CisJCU1lc3NhZ2VNZXRhZGF0YSBtZCA9IG1lc3NhZ2VzLmdldChtZXNzYWdlSW5kZXhPZihtc2dubykpOworCQlNYm94TWVzc2FnZSBtc2cgPSBtZC5tZXNzYWdlOworCQlpZiAobXNnICE9IG51bGwpIHsKKwkJICAgIGlmIChleHB1bmdlICYmIG1zZy5pc1NldChGbGFncy5GbGFnLkRFTEVURUQpKQorCQkJY29udGludWU7CS8vIHNraXAgaXQ7CisJCSAgICBpZiAoY2xvc2luZyAmJiBtc2dubyA8PSBvbGR0b3RhbCAmJgorCQkJCQkJbXNnLmlzU2V0KEZsYWdzLkZsYWcuUkVDRU5UKSkKKwkJCW1zZy5zZXRGbGFnKEZsYWdzLkZsYWcuUkVDRU5ULCBmYWxzZSk7CisJCSAgICB3cml0ZU1ib3hNZXNzYWdlKG1zZywgb3MpOworCQl9IGVsc2UgeworCQkgICAgaWYgKGV4cHVuZ2UgJiYgbWQuZGVsZXRlZCkKKwkJCWNvbnRpbnVlOwkvLyBza2lwIGl0OworCQkgICAgaWYgKGNsb3NpbmcgJiYgbXNnbm8gPD0gb2xkdG90YWwgJiYgbWQucmVjZW50KSB7CisJCQkvLyBoYXZlIHRvIGluc3RhbnRpYXRlIG1lc3NhZ2Ugc28gdGhhdCB3ZSBjYW4KKwkJCS8vIGNsZWFyIHRoZSByZWNlbnQgZmxhZworCQkJbXNnID0gKE1ib3hNZXNzYWdlKWdldE1lc3NhZ2UobXNnbm8pOworCQkJbXNnLnNldEZsYWcoRmxhZ3MuRmxhZy5SRUNFTlQsIGZhbHNlKTsKKwkJCXdyaXRlTWJveE1lc3NhZ2UobXNnLCBvcyk7CisJCSAgICB9IGVsc2UgeworCQkJYXBwZW5kU3RyZWFtKGdldE1lc3NhZ2VTdHJlYW0obXNnbm8pLCBvcyk7CisJCSAgICB9CisJCX0KKwkJZm9sZGVyLnRvdWNobG9jaygpOworCQl3cisrOworCSAgICB9CisJICAgIC8vIElmIG5vIG1lc3NhZ2VzIGluIHRoZSBtYWlsYm94LCBhbmQgd2UncmUgY2xvc2luZywKKwkgICAgLy8gbWF5YmUgd2Ugc2hvdWxkIHJlbW92ZSB0aGUgbWFpbGJveC4KKwkgICAgaWYgKHdyID09IDAgJiYgY2xvc2luZykgeworCQlTdHJpbmcgc2tlZXAgPSAoKE1ib3hTdG9yZSlzdG9yZSkuZ2V0U2Vzc2lvbigpLgorCQkJCQlnZXRQcm9wZXJ0eSgibWFpbC5tYm94LmRlbGV0ZUVtcHR5Iik7CisJCWlmIChza2VlcCAhPSBudWxsICYmIHNrZWVwLmVxdWFsc0lnbm9yZUNhc2UoInRydWUiKSkKKwkJICAgIGtlZXAgPSBmYWxzZTsKKwkgICAgfQorCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKwkgICAgdGhyb3cgZTsKKwl9IGNhdGNoIChNZXNzYWdpbmdFeGNlcHRpb24gZSkgeworCSAgICB0aHJvdyBlOworCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CitlLnByaW50U3RhY2tUcmFjZSgpOworCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgZSk7CisJfSBmaW5hbGx5IHsKKwkgICAgLy8gY2xvc2UgdGhlIGZvbGRlciwgZmx1c2hpbmcgb3V0IHRoZSBkYXRhCisJICAgIHRyeSB7CisJCW9zLmNsb3NlKCk7CisJCWZpbGVfc2l6ZSA9IHNhdmVkX2ZpbGVfc2l6ZSA9IGZvbGRlci5sZW5ndGgoKTsKKwkJaWYgKCFrZWVwKSB7CisJCSAgICBmb2xkZXIuZGVsZXRlKCk7CisJCSAgICBmaWxlX3NpemUgPSAwOworCQl9CisJICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7fQorCisJICAgIGlmIChrZWVwKSB7CisJCS8vIG1ha2Ugc3VyZSB0aGUgYWNjZXNzIHRpbWUgaXMgZ3JlYXRlciB0aGFuIHRoZSBtb2QgdGltZQorCQkvLyBYWFggLSB3b3VsZCBiZSBuaWNlIHRvIGhhdmUgdXRpbWUoKQorCQl0cnkgeworCQkgICAgVGhyZWFkLnNsZWVwKDEwMDApOwkJLy8gc2xlZXAgZm9yIGEgc2Vjb25kCisJCX0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGV4KSB7fQorCQlJbnB1dFN0cmVhbSBpcyA9IG51bGw7CisJCXRyeSB7CisJCSAgICBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oKEZpbGUpZm9sZGVyKTsKKwkJICAgIGlzLnJlYWQoKTsJLy8gcmVhZCBhIGJ5dGUKKwkJfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHt9CS8vIGlnbm9yZSBlcnJvcnMKKwkJdHJ5IHsKKwkJICAgIGlmIChpcyAhPSBudWxsKQorCQkJaXMuY2xvc2UoKTsKKwkJICAgIGlzID0gbnVsbDsKKwkJfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHt9CS8vIGlnbm9yZSBlcnJvcnMKKwkgICAgfQorCisJICAgIGZvbGRlci51bmxvY2soKTsKKwkgICAgaWYgKG1zZ2xpc3QgIT0gbnVsbCkKKwkJbm90aWZ5TWVzc2FnZUFkZGVkTGlzdGVuZXJzKG1zZ2xpc3QpOworCX0KKwlyZXR1cm4gd3I7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXBwZW5kIHRoZSBpbnB1dCBzdHJlYW0gdG8gdGhlIG91dHB1dCBzdHJlYW0sIGNsb3NpbmcgdGhlCisgICAgICogaW5wdXQgc3RyZWFtIHdoZW4gZG9uZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCB2b2lkIGFwcGVuZFN0cmVhbShJbnB1dFN0cmVhbSBpcywgT3V0cHV0U3RyZWFtIG9zKQorCQkJCXRocm93cyBJT0V4Y2VwdGlvbiB7CisJdHJ5IHsKKwkgICAgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlWzY0ICogMTAyNF07CisJICAgIGludCBsZW47CisJICAgIHdoaWxlICgobGVuID0gaXMucmVhZChidWYpKSA+IDApCisJCW9zLndyaXRlKGJ1ZiwgMCwgbGVuKTsKKwl9IGZpbmFsbHkgeworCSAgICBpcy5jbG9zZSgpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBXcml0ZSBhIE1pbWVNZXNzYWdlIHRvIHRoZSBzcGVjaWZpZWQgT3V0cHV0U3RyZWFtIGluIGEKKyAgICAgKiBmb3JtYXQgc3VpdGFibGUgZm9yIGEgVU5JWCBtYWlsYm94LCBpLmUuLCBpbmNsdWRpbmcgYSBjb3JyZWN0CisgICAgICogQ29udGVudC1MZW5ndGggaGVhZGVyIGFuZCB3aXRoIHRoZSBsb2NhbCBwbGF0Zm9ybSdzIGxpbmUKKyAgICAgKiB0ZXJtaW5hdGluZyBjb252ZW50aW9uLiA8cD4KKyAgICAgKgorICAgICAqIElmIHRoZSBtZXNzYWdlIGlzIHJlYWxseSBhIE1ib3hNZXNzYWdlLCB1c2UgaXRzIHdyaXRlVG9GaWxlCisgICAgICogbWV0aG9kLCB3aGljaCBoYXMgYWNjZXNzIHRvIHRoZSBVTklYIEZyb20gbGluZS4gIE90aGVyd2lzZSwgZG8KKyAgICAgKiBhbGwgdGhlIHdvcmsgaGVyZSwgY3JlYXRpbmcgYW4gYXBwcm9wcmlhdGUgVU5JWCBGcm9tIGxpbmUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyB2b2lkIHdyaXRlTWJveE1lc3NhZ2UoTWltZU1lc3NhZ2UgbXNnLCBPdXRwdXRTdHJlYW0gb3MpCisJCQkJdGhyb3dzIElPRXhjZXB0aW9uLCBNZXNzYWdpbmdFeGNlcHRpb24geworCXRyeSB7CisJICAgIGlmIChtc2cgaW5zdGFuY2VvZiBNYm94TWVzc2FnZSkgeworCQkoKE1ib3hNZXNzYWdlKW1zZykud3JpdGVUb0ZpbGUob3MpOworCSAgICB9IGVsc2UgeworCQkvLyBYWFggLSBtb2RpZnkgdGhlIG1lc3NhZ2UgdG8gcHJlc2VydmUgdGhlIGZsYWdzIGluIGhlYWRlcnMKKwkJTWJveE1lc3NhZ2Uuc2V0SGVhZGVyc0Zyb21GbGFncyhtc2cpOworCQlDb250ZW50TGVuZ3RoQ291bnRlciBjb3MgPSBuZXcgQ29udGVudExlbmd0aENvdW50ZXIoKTsKKwkJTmV3bGluZU91dHB1dFN0cmVhbSBub3MgPSBuZXcgTmV3bGluZU91dHB1dFN0cmVhbShjb3MpOworCQltc2cud3JpdGVUbyhub3MpOworCQlub3MuZmx1c2goKTsKKwkJb3MgPSBuZXcgTmV3bGluZU91dHB1dFN0cmVhbShvcywgdHJ1ZSk7CisJCW9zID0gbmV3IENvbnRlbnRMZW5ndGhVcGRhdGVyKG9zLCBjb3MuZ2V0U2l6ZSgpKTsKKwkJUHJpbnRTdHJlYW0gcG9zID0gbmV3IFByaW50U3RyZWFtKG9zLCBmYWxzZSwgImlzby04ODU5LTEiKTsKKwkJcG9zLnByaW50bG4oZ2V0VW5peEZyb20obXNnKSk7CisJCW1zZy53cml0ZVRvKHBvcyk7CisJCXBvcy5mbHVzaCgpOworCSAgICB9CisJfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIG1lKSB7CisJICAgIHRocm93IG1lOworCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkgeworCSAgICB0aHJvdyBpb2U7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCBhbiBhcHByb3ByaWF0ZWx5IGZvcm1hdHRlZCBVTklYIEZyb20gbGluZSB1c2luZworICAgICAqIHRoZSBzZW5kZXIgYWRkcmVzcyBhbmQgdGhlIGRhdGUgaW4gdGhlIG1lc3NhZ2UuCisgICAgICovCisgICAgcHJvdGVjdGVkIHN0YXRpYyBTdHJpbmcgZ2V0VW5peEZyb20oTWltZU1lc3NhZ2UgbXNnKSB7CisJQWRkcmVzc1tdIGFmcm9tOworCVN0cmluZyBmcm9tOworCURhdGUgZGRhdGU7CisJU3RyaW5nIGRhdGU7CisJdHJ5IHsKKwkgICAgaWYgKChhZnJvbSA9IG1zZy5nZXRGcm9tKCkpID09IG51bGwgfHwKKwkJICAgICEoYWZyb21bMF0gaW5zdGFuY2VvZiBJbnRlcm5ldEFkZHJlc3MpIHx8CisJCSAgICAoZnJvbSA9ICgoSW50ZXJuZXRBZGRyZXNzKWFmcm9tWzBdKS5nZXRBZGRyZXNzKCkpID09IG51bGwpCisJCWZyb20gPSAiVU5LTk9XTiI7CisJICAgIGlmICgoZGRhdGUgPSBtc2cuZ2V0UmVjZWl2ZWREYXRlKCkpID09IG51bGwgfHwKKwkJICAgIChkZGF0ZSA9IG1zZy5nZXRTZW50RGF0ZSgpKSA9PSBudWxsKQorCQlkZGF0ZSA9IG5ldyBEYXRlKCk7CisJfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIGUpIHsKKwkgICAgZnJvbSA9ICJVTktOT1dOIjsKKwkgICAgZGRhdGUgPSBuZXcgRGF0ZSgpOworCX0KKwlkYXRlID0gZGRhdGUudG9TdHJpbmcoKTsKKwkvLyBkYXRlIGlzIG9mIHRoZSBmb3JtICJTYXQgQXVnIDEyIDAyOjMwOjAwIFBEVCAxOTk1IgorCS8vIG5lZWQgdG8gc3RyaXAgb3V0IHRoZSB0aW1lem9uZQorCXJldHVybiAiRnJvbSAiICsgZnJvbSArICIgIiArCisJCWRhdGUuc3Vic3RyaW5nKDAsIDIwKSArIGRhdGUuc3Vic3RyaW5nKDI0KTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGludCBnZXRNZXNzYWdlQ291bnQoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpZiAoIW9wZW5lZCkKKwkgICAgcmV0dXJuIC0xOworCisJYm9vbGVhbiBsb2NrZWQgPSBmYWxzZTsKKwlNZXNzYWdlW10gbXNnbGlzdCA9IG51bGw7CisJdHJ5IHsKKwkgICAgaWYgKGZvbGRlci5sZW5ndGgoKSAhPSBmaWxlX3NpemUpIHsKKwkJaWYgKCFmb2xkZXIubG9jaygiciIpKQorCQkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiRmFpbGVkIHRvIGxvY2sgZm9sZGVyOiAiICsKKwkJCQkJCQluYW1lKTsKKwkJbG9ja2VkID0gdHJ1ZTsKKwkJbXNnbGlzdCA9IGxvYWQoZmlsZV9zaXplLCB0cnVlKTsKKwkgICAgfQorCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiSS9PIEV4Y2VwdGlvbiIsIGUpOworCX0gZmluYWxseSB7CisJICAgIGlmIChsb2NrZWQpIHsKKwkJZm9sZGVyLnVubG9jaygpOworCQlpZiAobXNnbGlzdCAhPSBudWxsKQorCQkgICAgbm90aWZ5TWVzc2FnZUFkZGVkTGlzdGVuZXJzKG1zZ2xpc3QpOworCSAgICB9CisJfQorCXJldHVybiB0b3RhbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIHNwZWNpZmllZCBtZXNzYWdlLiAgTm90ZSB0aGF0IG1lc3NhZ2VzIGFyZSBudW1iZXJlZAorICAgICAqIGZyb20gMS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIE1lc3NhZ2UgZ2V0TWVzc2FnZShpbnQgbXNnbm8pCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJY2hlY2tSZWFkYWJsZSgpOworCWNoZWNrUmFuZ2UobXNnbm8pOworCisJTWVzc2FnZU1ldGFkYXRhIG1kID0gbWVzc2FnZXMuZ2V0KG1lc3NhZ2VJbmRleE9mKG1zZ25vKSk7CisJTWJveE1lc3NhZ2UgbSA9IG1kLm1lc3NhZ2U7CisJaWYgKG0gPT0gbnVsbCkgeworCSAgICBJbnB1dFN0cmVhbSBpcyA9IGdldE1lc3NhZ2VTdHJlYW0obXNnbm8pOworCSAgICB0cnkgeworCQltID0gbG9hZE1lc3NhZ2UoaXMsIG1zZ25vLCBtb2RlID09IFJFQURfV1JJVEUpOworCSAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworCQlNZXNzYWdpbmdFeGNlcHRpb24gbWV4ID0KKwkJICAgIG5ldyBNZXNzYWdlUmVtb3ZlZEV4Y2VwdGlvbigibWJveCBtZXNzYWdlIGdvbmUiLCBleCk7CisJCXRocm93IG1leDsKKwkgICAgfQorCSAgICBtZC5tZXNzYWdlID0gbTsKKwl9CisJcmV0dXJuIG07CisgICAgfQorCisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgbWVzc2FnZUluZGV4T2YoaW50IG1zZ25vKSB7CisJcmV0dXJuIHNwZWNpYWxfaW1hcF9tZXNzYWdlID8gbXNnbm8gOiBtc2dubyAtIDE7CisgICAgfQorCisgICAgcHJpdmF0ZSBJbnB1dFN0cmVhbSBnZXRNZXNzYWdlU3RyZWFtKGludCBtc2dubykgeworCWludCBpbmRleCA9IG1lc3NhZ2VJbmRleE9mKG1zZ25vKTsKKwlNZXNzYWdlTWV0YWRhdGEgbWQgPSBtZXNzYWdlcy5nZXQoaW5kZXgpOworCXJldHVybiB0ZW1wLm5ld1N0cmVhbShtZC5zdGFydCwgbWQuZGF0YWVuZCk7CisgICAgfQorCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGFwcGVuZE1lc3NhZ2VzKE1lc3NhZ2VbXSBtc2dzKQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWlmICghZm9sZGVyLmxvY2soInJ3IikpCisJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oIkZhaWxlZCB0byBsb2NrIGZvbGRlcjogIiArIG5hbWUpOworCisJT3V0cHV0U3RyZWFtIG9zID0gbnVsbDsKKwlib29sZWFuIGVyciA9IGZhbHNlOworCXRyeSB7CisJICAgIG9zID0gbmV3IEJ1ZmZlcmVkT3V0cHV0U3RyZWFtKAorCQluZXcgRmlsZU91dHB1dFN0cmVhbSgoKEZpbGUpZm9sZGVyKS5nZXRQYXRoKCksIHRydWUpKTsKKwkJLy8gWFhYIC0gc2hvdWxkIHVzZSBnZXRBYnNvbHV0ZVBhdGgoKT8KKwkgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dzLmxlbmd0aDsgaSsrKSB7CisJCWlmIChtc2dzW2ldIGluc3RhbmNlb2YgTWltZU1lc3NhZ2UpIHsKKwkJICAgIHdyaXRlTWJveE1lc3NhZ2UoKE1pbWVNZXNzYWdlKW1zZ3NbaV0sIG9zKTsKKwkJfSBlbHNlIHsKKwkJICAgIGVyciA9IHRydWU7CisJCSAgICBjb250aW51ZTsKKwkJfQorCQlmb2xkZXIudG91Y2hsb2NrKCk7CisJICAgIH0KKwl9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oIkkvTyBFeGNlcHRpb24iLCBlKTsKKwl9IGNhdGNoIChNZXNzYWdpbmdFeGNlcHRpb24gZSkgeworCSAgICB0aHJvdyBlOworCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CitlLnByaW50U3RhY2tUcmFjZSgpOworCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKCJ1bmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgZSk7CisJfSBmaW5hbGx5IHsKKwkgICAgaWYgKG9zICE9IG51bGwpCisJCXRyeSB7CisJCSAgICBvcy5jbG9zZSgpOworCQl9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisJCSAgICAvLyBpZ25vcmVkCisJCX0KKwkgICAgZm9sZGVyLnVubG9jaygpOworCX0KKwlpZiAob3BlbmVkKQorCSAgICBnZXRNZXNzYWdlQ291bnQoKTsJLy8gbG9hZHMgbmV3IG1lc3NhZ2VzIGFzIGEgc2lkZSBlZmZlY3QKKwlpZiAoZXJyKQorCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKCJDYW4ndCBhcHBlbmQgbm9uLU1pbWUgbWVzc2FnZSIpOworICAgIH0KKworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgTWVzc2FnZVtdIGV4cHVuZ2UoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwljaGVja1dyaXRhYmxlKCk7CisKKwkvKgorCSAqIEZpcnN0LCB3cml0ZSBvdXQgdGhlIGZvbGRlciB0byBtYWtlIHN1cmUgd2UgaGF2ZSBwZXJtaXNzaW9uLAorCSAqIGRpc2sgc3BhY2UsIGV0Yy4KKwkgKi8KKwlpbnQgd3IgPSB0b3RhbDsJCS8vIG51bWJlciBvZiBtZXNzYWdlcyB3cml0dGVuIG91dAorCXRyeSB7CisJICAgIHdyID0gd3JpdGVGb2xkZXIoZmFsc2UsIHRydWUpOworCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiZXhwdW5nZSBmYWlsZWQiLCBlKTsKKwl9CisJaWYgKHdyID09IHRvdGFsKQkvLyB3cm90ZSB0aGVtIGFsbCA9PiBub3RoaW5nIGV4cHVuZ2VkCisJICAgIHJldHVybiBuZXcgTWVzc2FnZVswXTsKKworCS8qCisJICogTm93LCBhY3R1YWxseSBnZXQgcmlkIG9mIHRoZSBleHB1bmdlZCBtZXNzYWdlcy4KKwkgKi8KKwlpbnQgZGVsID0gMDsKKwlNZXNzYWdlW10gbXNnbGlzdCA9IG5ldyBNZXNzYWdlW3RvdGFsIC0gd3JdOworCWludCBtc2dubyA9IDE7CisJd2hpbGUgKG1zZ25vIDw9IHRvdGFsKSB7CisJICAgIE1lc3NhZ2VNZXRhZGF0YSBtZCA9IG1lc3NhZ2VzLmdldChtZXNzYWdlSW5kZXhPZihtc2dubykpOworCSAgICBNYm94TWVzc2FnZSBtc2cgPSBtZC5tZXNzYWdlOworCSAgICBpZiAobXNnICE9IG51bGwpIHsKKwkJaWYgKG1zZy5pc1NldChGbGFncy5GbGFnLkRFTEVURUQpKSB7CisJCSAgICBtc2cuc2V0RXhwdW5nZWQodHJ1ZSk7CisJCSAgICBtc2dsaXN0W2RlbF0gPSBtc2c7CisJCSAgICBkZWwrKzsKKwkJICAgIG1lc3NhZ2VzLnJlbW92ZShtZXNzYWdlSW5kZXhPZihtc2dubykpOworCQkgICAgdG90YWwtLTsKKwkJfSBlbHNlIHsKKwkJICAgIG1zZy5zZXRNZXNzYWdlTnVtYmVyKG1zZ25vKTsJLy8gdXBkYXRlIG1lc3NhZ2UgbnVtYmVyCisJCSAgICBtc2dubysrOworCQl9CisJICAgIH0gZWxzZSB7CisJCWlmIChtZC5kZWxldGVkKSB7CisJCSAgICAvLyBoYXZlIHRvIGluc3RhbnRpYXRlIGl0IGZvciB0aGUgbm90aWZpY2F0aW9uCisJCSAgICBtc2cgPSAoTWJveE1lc3NhZ2UpZ2V0TWVzc2FnZShtc2dubyk7CisJCSAgICBtc2cuc2V0RXhwdW5nZWQodHJ1ZSk7CisJCSAgICBtc2dsaXN0W2RlbF0gPSBtc2c7CisJCSAgICBkZWwrKzsKKwkJICAgIG1lc3NhZ2VzLnJlbW92ZShtZXNzYWdlSW5kZXhPZihtc2dubykpOworCQkgICAgdG90YWwtLTsKKwkJfSBlbHNlIHsKKwkJICAgIG1zZ25vKys7CisJCX0KKwkgICAgfQorCX0KKwlpZiAoZGVsICE9IG1zZ2xpc3QubGVuZ3RoKQkJLy8gdGhpcyBpcyByZWFsbHkgYW4gYXNzZXJ0CisJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oImV4cHVuZ2UgZGVsZXRlIGNvdW50IHdyb25nIik7CisJbm90aWZ5TWVzc2FnZVJlbW92ZWRMaXN0ZW5lcnModHJ1ZSwgbXNnbGlzdCk7CisJcmV0dXJuIG1zZ2xpc3Q7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBMb2FkIG1vcmUgbWVzc2FnZXMgZnJvbSB0aGUgZm9sZGVyIHN0YXJ0aW5nIGF0IHRoZSBzcGVjaWZpZWQgb2Zmc2V0LgorICAgICAqLworICAgIHByaXZhdGUgTWVzc2FnZVtdIGxvYWQobG9uZyBvZmZzZXQsIGJvb2xlYW4gbm90aWZ5KQorCQkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKwlpbnQgb2xkdG90YWwgPSB0b3RhbDsKKwlNZXNzYWdlTG9hZGVyIGxvYWRlciA9IG5ldyBNZXNzYWdlTG9hZGVyKHRlbXApOworCWludCBsb2FkZWQgPSBsb2FkZXIubG9hZChmb2xkZXIuZ2V0RkQoKSwgb2Zmc2V0LCBtZXNzYWdlcyk7CisJdG90YWwgKz0gbG9hZGVkOworCWZpbGVfc2l6ZSA9IGZvbGRlci5sZW5ndGgoKTsKKworCWlmIChvZmZzZXQgPT0gMCAmJiBsb2FkZWQgPiAwKSB7CisJICAgIC8qCisJICAgICAqIElmIHRoZSBmaXJzdCBtZXNzYWdlIGlzIHRoZSBzcGVjaWFsIG1lc3NhZ2UgdGhhdCB0aGUKKwkgICAgICogSU1BUCBzZXJ2ZXIgYWRkcyB0byB0aGUgbWFpbGJveCwgcmVtZW1iZXIgdGhhdCB3ZSd2ZQorCSAgICAgKiBzZWVuIGl0IHNvIGl0IHdvbid0IGJlIHNob3duIHRvIHRoZSB1c2VyLgorCSAgICAgKi8KKwkgICAgTWVzc2FnZU1ldGFkYXRhIG1kID0gbWVzc2FnZXMuZ2V0KDApOworCSAgICBpZiAobWQuaW1hcCkgeworCQlzcGVjaWFsX2ltYXBfbWVzc2FnZSA9IHRydWU7CisJCXRvdGFsLS07CisJICAgIH0KKwl9CisJaWYgKG5vdGlmeSkgeworCSAgICBNZXNzYWdlW10gbXNnbGlzdCA9IG5ldyBNZXNzYWdlW3RvdGFsIC0gb2xkdG90YWxdOworCSAgICBmb3IgKGludCBpID0gb2xkdG90YWwsIGogPSAwOyBpIDwgdG90YWw7IGkrKywgaisrKQorCQltc2dsaXN0W2pdID0gZ2V0TWVzc2FnZShpICsgMSk7CisJICAgIHJldHVybiBtc2dsaXN0OworCX0gZWxzZQorCSAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQYXJzZSB0aGUgaW5wdXQgc3RyZWFtIGFuZCByZXR1cm4gYW4gYXBwcm9wcmlhdGUgbWVzc2FnZSBvYmplY3QuCisgICAgICogVGhlIElucHV0U3RyZWFtIG11c3QgYmUgYSBTaGFyZWRJbnB1dFN0cmVhbS4KKyAgICAgKi8KKyAgICBwcml2YXRlIE1ib3hNZXNzYWdlIGxvYWRNZXNzYWdlKElucHV0U3RyZWFtIGlzLCBpbnQgbXNnbm8sCisJCWJvb2xlYW4gd3JpdGFibGUpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKwlMaW5lSW5wdXRTdHJlYW0gaW4gPSBuZXcgTGluZUlucHV0U3RyZWFtKGlzKTsKKworCS8qCisJICogUmVhZCBsaW5lcyB1bnRpbCBhIFVOSVggRnJvbSBsaW5lLAorCSAqIHNraXBwaW5nIGJsYW5rIGxpbmVzLgorCSAqLworCVN0cmluZyBsaW5lOworCVN0cmluZyB1bml4X2Zyb20gPSBudWxsOworCXdoaWxlICgobGluZSA9IGluLnJlYWRMaW5lKCkpICE9IG51bGwpIHsKKwkgICAgaWYgKGxpbmUudHJpbSgpLmxlbmd0aCgpID09IDApCisJCWNvbnRpbnVlOworCSAgICBpZiAobGluZS5zdGFydHNXaXRoKCJGcm9tICIpKSB7CisJCS8qCisJCSAqIEEgVU5JWCBGcm9tIGxpbmUgbG9va3MgbGlrZToKKwkJICogRnJvbSBhZGRyZXNzIERheSBNb24gREQgSEg6TU06U1MgWVlZWQorCQkgKi8KKwkJdW5peF9mcm9tID0gbGluZTsKKwkJaW50IGk7CisJCS8vIGZpbmQgdGhlIHNwYWNlIGFmdGVyIHRoZSBhZGRyZXNzLCBiZWZvcmUgdGhlIGRhdGUKKwkJaSA9IHVuaXhfZnJvbS5pbmRleE9mKCcgJywgNSk7CisJCWlmIChpIDwgMCkKKwkJICAgIGNvbnRpbnVlOwkvLyBub3QgYSB2YWxpZCBVTklYIEZyb20gbGluZQorCQlicmVhazsKKwkgICAgfQorCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKCJHYXJiYWdlIGluIG1haWxib3g6ICIgKyBsaW5lKTsKKwl9CisKKwlpZiAodW5peF9mcm9tID09IG51bGwpCisJICAgIHRocm93IG5ldyBFT0ZFeGNlcHRpb24oImVuZCBvZiBtYWlsYm94Iik7CisKKwkvKgorCSAqIE5vdyBsb2FkIHRoZSBSRkM4MjIgaGVhZGVycyBpbnRvIGFuIEludGVybmV0SGVhZGVycyBvYmplY3QuCisJICovCisJSW50ZXJuZXRIZWFkZXJzIGhkcnMgPSBuZXcgSW50ZXJuZXRIZWFkZXJzKGlzKTsKKworCS8vIHRoZSByZXN0IGlzIHRoZSBtZXNzYWdlIGNvbnRlbnQKKwlTaGFyZWRJbnB1dFN0cmVhbSBzaXMgPSAoU2hhcmVkSW5wdXRTdHJlYW0paXM7CisJSW5wdXRTdHJlYW0gc3RyZWFtID0gc2lzLm5ld1N0cmVhbShzaXMuZ2V0UG9zaXRpb24oKSwgLTEpOworCXJldHVybiBuZXcgTWJveE1lc3NhZ2UodGhpcywgaGRycywgc3RyZWFtLCBtc2dubywgdW5peF9mcm9tLCB3cml0YWJsZSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBPbmx5IGhlcmUgdG8gbWFrZSBhY2Nlc3NpYmxlIHRvIE1ib3hNZXNzYWdlLgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIG5vdGlmeU1lc3NhZ2VDaGFuZ2VkTGlzdGVuZXJzKGludCB0eXBlLCBNZXNzYWdlIG0pIHsKKwlzdXBlci5ub3RpZnlNZXNzYWdlQ2hhbmdlZExpc3RlbmVycyh0eXBlLCBtKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIHRoaXMgaXMgYW4gZXhhY3QgZHVwbGljYXRlIG9mIHRoZSBGb2xkZXIuZ2V0VVJMIGV4Y2VwdCBpdCBkb2Vzbid0CisgICAgICogYWRkIGEgYmVnaW5uaW5nICcvJyB0byB0aGUgVVJMTmFtZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgVVJMTmFtZSBnZXRVUkxOYW1lKCkgeworCS8vIFhYWCAtIG5vdGU6ICB0aGlzIHNob3VsZCBub3QgYmUgZG9uZSB0aGlzIHdheSB3aXRoIHRoZQorCS8vIG5ldyBqYXZheC5tYWlsIGFwaXMuCisKKwlVUkxOYW1lIHN0b3JlVVJMID0gZ2V0U3RvcmUoKS5nZXRVUkxOYW1lKCk7CisJaWYgKG5hbWUgPT0gbnVsbCkKKwkgICAgcmV0dXJuIHN0b3JlVVJMOworCisJY2hhciBzZXBhcmF0b3IgPSBnZXRTZXBhcmF0b3IoKTsKKwlTdHJpbmcgZnVsbG5hbWUgPSBnZXRGdWxsTmFtZSgpOworCVN0cmluZ0J1aWxkZXIgZW5jb2RlZE5hbWUgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworCisJLy8gV2UgbmVlZCB0byBlbmNvZGUgZWFjaCBvZiB0aGUgZm9sZGVyJ3MgbmFtZXMsIGFuZCByZXBsYWNlCisJLy8gdGhlIHN0b3JlJ3Mgc2VwYXJhdG9yIGNoYXIgd2l0aCB0aGUgVVJMIGNoYXIgJy8nLgorCVN0cmluZ1Rva2VuaXplciB0b2sgPSBuZXcgU3RyaW5nVG9rZW5pemVyKAorCSAgICBmdWxsbmFtZSwgQ2hhcmFjdGVyLnRvU3RyaW5nKHNlcGFyYXRvciksIHRydWUpOworCisJd2hpbGUgKHRvay5oYXNNb3JlVG9rZW5zKCkpIHsKKwkgICAgU3RyaW5nIHMgPSB0b2submV4dFRva2VuKCk7CisJICAgIGlmIChzLmNoYXJBdCgwKSA9PSBzZXBhcmF0b3IpCisJCWVuY29kZWROYW1lLmFwcGVuZCgiLyIpOworCSAgICBlbHNlCisJCS8vIFhYWCAtIHNob3VsZCBlbmNvZGUsIGJ1dCBzaW5jZSB0aGVyZSdzIG5vIGRlY29kZXIuLi4KKwkJLy9lbmNvZGVkTmFtZS5hcHBlbmQoamF2YS5uZXQuVVJMRW5jb2Rlci5lbmNvZGUocykpOworCQllbmNvZGVkTmFtZS5hcHBlbmQocyk7CisJfQorCisJcmV0dXJuIG5ldyBVUkxOYW1lKHN0b3JlVVJMLmdldFByb3RvY29sKCksIHN0b3JlVVJMLmdldEhvc3QoKSwKKwkJCSAgICBzdG9yZVVSTC5nZXRQb3J0KCksIGVuY29kZWROYW1lLnRvU3RyaW5nKCksCisJCQkgICAgc3RvcmVVUkwuZ2V0VXNlcm5hbWUoKSwKKwkJCSAgICBudWxsIC8qIG5vIHBhc3N3b3JkICovKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYW4gTWJveEZvbGRlciBvYmplY3QsIG9yIGEgc3ViY2xhc3MgdGhlcmVvZi4KKyAgICAgKiBDYW4gYmUgb3ZlcnJpZGRlbiBieSBzdWJjbGFzc2VzIG9mIE1ib3hGb2xkZXIgc28gdGhhdAorICAgICAqIHRoZSBhcHByb3ByaWF0ZSBzdWJjbGFzcyBpcyBjcmVhdGVkIGJ5IHRoZSBsaXN0IG1ldGhvZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgRm9sZGVyIGNyZWF0ZUZvbGRlcihNYm94U3RvcmUgc3RvcmUsIFN0cmluZyBuYW1lKSB7CisJcmV0dXJuIG5ldyBNYm94Rm9sZGVyKHN0b3JlLCBuYW1lKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIFN1cHBvcnQgcm91dGluZXMgZm9yIGxpc3QoKS4KKyAgICAgKi8KKworICAgIC8qKgorICAgICAqIFJldHVybiBhIGNhbm9uaWNhbGl6ZWQgcGF0dGVybiBnaXZlbiBhIHJlZmVyZW5jZSBuYW1lIGFuZCBhIHBhdHRlcm4uCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGNhbm9uaWNhbGl6ZShTdHJpbmcgcmVmLCBTdHJpbmcgcGF0KSB7CisJaWYgKHJlZiA9PSBudWxsKQorCSAgICByZXR1cm4gcGF0OworCXRyeSB7CisJICAgIGlmIChwYXQubGVuZ3RoKCkgPT0gMCkgeworCQlyZXR1cm4gcmVmOworCSAgICB9IGVsc2UgaWYgKHBhdC5jaGFyQXQoMCkgPT0gRmlsZS5zZXBhcmF0b3JDaGFyKSB7CisJCXJldHVybiByZWYuc3Vic3RyaW5nKDAsIHJlZi5pbmRleE9mKEZpbGUuc2VwYXJhdG9yQ2hhcikpICsgcGF0OworCSAgICB9IGVsc2UgeworCQlyZXR1cm4gcmVmICsgcGF0OworCSAgICB9CisJfSBjYXRjaCAoU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBlKSB7CisJICAgIHJldHVybiBwYXQ7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgZmlyc3QgaW5kZXggb2YgYW55IG9mIHRoZSBjaGFyYWN0ZXJzIGluICJhbnkiIGluICJzIiwKKyAgICAgKiBvciAtMSBpZiBub25lIGFyZSBmb3VuZC4KKyAgICAgKgorICAgICAqIFRoaXMgc2hvdWxkIGJlIGEgbWV0aG9kIG9uIFN0cmluZy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBpbnQgaW5kZXhPZkFueShTdHJpbmcgcywgU3RyaW5nIGFueSkgeworCXRyeSB7CisJICAgIGludCBsZW4gPSBzLmxlbmd0aCgpOworCSAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7CisJCWlmIChhbnkuaW5kZXhPZihzLmNoYXJBdChpKSkgPj0gMCkKKwkJICAgIHJldHVybiBpOworCSAgICB9CisJICAgIHJldHVybiAtMTsKKwl9IGNhdGNoIChTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKwkgICAgcmV0dXJuIC0xOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGUgcmVjdXJzaXZlIHBhcnQgb2YgZ2VuZXJhdGluZyB0aGUgbGlzdCBvZiBtYWlsYm94ZXMuCisgICAgICogcmVhbGRpciBpcyB0aGUgZnVsbCBwYXRobmFtZSB0byB0aGUgZGlyZWN0b3J5IHRvIHNlYXJjaC4KKyAgICAgKiBkaXIgaXMgdGhlIG5hbWUgdGhlIHVzZXIgdXNlcywgb2Z0ZW4gYSByZWxhdGl2ZSBuYW1lIHRoYXQncworICAgICAqIHJlbGF0aXZlIHRvIHRoZSB1c2VyJ3MgaG9tZSBkaXJlY3RvcnkuICBkaXIgKGlmIG5vdCBudWxsKSBhbHdheXMKKyAgICAgKiBoYXMgYSB0cmFpbGluZyBmaWxlIHNlcGFyYXRvciBjaGFyYWN0ZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gcmVhbGRpcglyZWFsIHBhdGhuYW1lIG9mIGRpcmVjdG9yeSB0byBzdGFydCBsb29raW5nIGluCisgICAgICogQHBhcmFtIGRpcgl1c2VyJ3MgbmFtZSBmb3IgcmVhbGRpcgorICAgICAqIEBwYXJhbSBwYXQJcGF0dGVybiB0byBtYXRjaCBhZ2FpbnN0CisgICAgICogQHBhcmFtIGxldmVsCWxldmVsIG9mIHRoZSBkaXJlY3RvcnkgaGllcmFyY2h5IHdlJ3JlIGluCisgICAgICogQHBhcmFtIGZsaXN0CWxpc3QgdG8gd2hpY2ggdG8gYWRkIGZvbGRlciBuYW1lcyB0aGF0IG1hdGNoCisgICAgICovCisgICAgLy8gRGVyaXZlZCBmcm9tIHRoZSBjLWNsaWVudCBsaXN0V29yaygpIGZ1bmN0aW9uLgorICAgIHByaXZhdGUgdm9pZCBsaXN0V29yayhTdHJpbmcgcmVhbGRpciwgU3RyaW5nIGRpciwgU3RyaW5nIHBhdCwKKwkJCQkJaW50IGxldmVsLCBMaXN0PFN0cmluZz4gZmxpc3QpIHsKKwlTdHJpbmcgc2xbXTsKKwlGaWxlIGZkaXIgPSBuZXcgRmlsZShyZWFsZGlyKTsKKwl0cnkgeworCSAgICBzbCA9IGZkaXIubGlzdCgpOworCX0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGUpIHsKKwkgICAgcmV0dXJuOwkvLyBjYW4ndCByZWFkIGl0LCBpZ25vcmUgaXQKKwl9CisKKwlpZiAobGV2ZWwgPT0gMCAmJiBkaXIgIT0gbnVsbCAmJgorCQlNYXRjaC5wYXRoKGRpciwgcGF0LCBGaWxlLnNlcGFyYXRvckNoYXIpKQorCSAgICBmbGlzdC5hZGQoZGlyKTsKKworCWlmIChzbCA9PSBudWxsKQorCSAgICByZXR1cm47CS8vIG5vdGhpbmcgcmV0dXJuLCB3ZSdyZSBkb25lCisKKwlpZiAocmVhbGRpci5jaGFyQXQocmVhbGRpci5sZW5ndGgoKSAtIDEpICE9IEZpbGUuc2VwYXJhdG9yQ2hhcikKKwkgICAgcmVhbGRpciArPSBGaWxlLnNlcGFyYXRvcjsKKworCWZvciAoaW50IGkgPSAwOyBpIDwgc2wubGVuZ3RoOyBpKyspIHsKKwkgICAgaWYgKHNsW2ldLmNoYXJBdCgwKSA9PSAnLicpCisJCWNvbnRpbnVlOwkvLyBpZ25vcmUgYWxsICJkb3QiIGZpbGVzIGZvciBub3cKKwkgICAgU3RyaW5nIG1kID0gcmVhbGRpciArIHNsW2ldOworCSAgICBGaWxlIG1mID0gbmV3IEZpbGUobWQpOworCSAgICBpZiAoIW1mLmV4aXN0cygpKQorCQljb250aW51ZTsKKwkgICAgU3RyaW5nIG5hbWU7CisJICAgIGlmIChkaXIgIT0gbnVsbCkKKwkJbmFtZSA9IGRpciArIHNsW2ldOworCSAgICBlbHNlCisJCW5hbWUgPSBzbFtpXTsKKwkgICAgaWYgKG1mLmlzRGlyZWN0b3J5KCkpIHsKKwkJaWYgKE1hdGNoLnBhdGgobmFtZSwgcGF0LCBGaWxlLnNlcGFyYXRvckNoYXIpKSB7CisJCSAgICBmbGlzdC5hZGQobmFtZSk7CisJCSAgICBuYW1lICs9IEZpbGUuc2VwYXJhdG9yOworCQl9IGVsc2UgeworCQkgICAgbmFtZSArPSBGaWxlLnNlcGFyYXRvcjsKKwkJICAgIGlmIChNYXRjaC5wYXRoKG5hbWUsIHBhdCwgRmlsZS5zZXBhcmF0b3JDaGFyKSkKKwkJCWZsaXN0LmFkZChuYW1lKTsKKwkJfQorCQlpZiAoTWF0Y2guZGlyKG5hbWUsIHBhdCwgRmlsZS5zZXBhcmF0b3JDaGFyKSkKKwkJICAgIGxpc3RXb3JrKG1kLCBuYW1lLCBwYXQsIGxldmVsICsgMSwgZmxpc3QpOworCSAgICB9IGVsc2UgeworCQlpZiAoTWF0Y2gucGF0aChuYW1lLCBwYXQsIEZpbGUuc2VwYXJhdG9yQ2hhcikpCisJCSAgICBmbGlzdC5hZGQobmFtZSk7CisJICAgIH0KKwl9CisgICAgfQorfQorCisvKioKKyAqIFBhdHRlcm4gbWF0Y2hpbmcgc3VwcG9ydCBjbGFzcyBmb3IgbGlzdCgpLgorICogU2hvdWxkIHByb2JhYmx5IGJlIG1vcmUgcHVibGljLgorICovCisvLyBUcmFuc2xhdGVkIGZyb20gdGhlIGMtY2xpZW50IGZ1bmN0aW9ucyBwbWF0Y2hfZnVsbCgpIGFuZCBkbWF0Y2goKS4KK2NsYXNzIE1hdGNoIHsKKyAgICAvKioKKyAgICAgKiBQYXRobmFtZSBwYXR0ZXJuIG1hdGNoCisgICAgICoKKyAgICAgKiBAcGFyYW0gcwkJYmFzZSBzdHJpbmcKKyAgICAgKiBAcGFyYW0gcGF0CXBhdHRlcm4gc3RyaW5nCisgICAgICogQHBhcmFtIGRlbGltCWRlbGltaXRlciBjaGFyYWN0ZXIKKyAgICAgKiBAcmV0dXJuCQl0cnVlIGlmIGJhc2UgbWF0Y2hlcyBwYXR0ZXJuCisgICAgICovCisgICAgc3RhdGljIHB1YmxpYyBib29sZWFuIHBhdGgoU3RyaW5nIHMsIFN0cmluZyBwYXQsIGNoYXIgZGVsaW0pIHsKKwl0cnkgeworCSAgICByZXR1cm4gcGF0aChzLCAwLCBzLmxlbmd0aCgpLCBwYXQsIDAsIHBhdC5sZW5ndGgoKSwgZGVsaW0pOworCX0gY2F0Y2ggKFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZSkgeworCSAgICByZXR1cm4gZmFsc2U7CisJfQorICAgIH0KKworICAgIHN0YXRpYyBwcml2YXRlIGJvb2xlYW4gcGF0aChTdHJpbmcgcywgaW50IHNfaW5kZXgsIGludCBzX2xlbiwKKwlTdHJpbmcgcGF0LCBpbnQgcF9pbmRleCwgaW50IHBfbGVuLCBjaGFyIGRlbGltKQorCSAgICB0aHJvd3MgU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB7CisKKwl3aGlsZSAocF9pbmRleCA8IHBfbGVuKSB7CisJICAgIGNoYXIgYyA9IHBhdC5jaGFyQXQocF9pbmRleCk7CisJICAgIHN3aXRjaCAoYykgeworCSAgICBjYXNlICclJzoKKwkJaWYgKCsrcF9pbmRleCA+PSBwX2xlbikJCS8vICUgYXQgZW5kIG9mIHBhdHRlcm4KKwkJCQkJCS8vIG9rIGlmIG5vIGRlbGltaXRlcnMKKwkJICAgIHJldHVybiBkZWxpbSA9PSAwIHx8IHMuaW5kZXhPZihkZWxpbSwgc19pbmRleCkgPCAwOworCQkvLyBzY2FuIHJlbWFpbmRlciB1bnRpbCBkZWxpbWl0ZXIKKwkJZG8geworCQkgICAgaWYgKHBhdGgocywgc19pbmRleCwgc19sZW4sIHBhdCwgcF9pbmRleCwgcF9sZW4sIGRlbGltKSkKKwkJCXJldHVybiB0cnVlOworCQl9IHdoaWxlIChzLmNoYXJBdChzX2luZGV4KSAhPSBkZWxpbSAmJiArK3NfaW5kZXggPCBzX2xlbik7CisJCS8vIHJhbiBpbnRvIGEgZGVsaW1pdGVyIG9yIHJhbiBvdXQgb2Ygc3RyaW5nIHdpdGhvdXQgYSBtYXRjaAorCQlyZXR1cm4gZmFsc2U7CisKKwkgICAgY2FzZSAnKic6CisJCWlmICgrK3BfaW5kZXggPj0gcF9sZW4pCQkvLyBlbmQgb2YgcGF0dGVybj8KKwkJICAgIHJldHVybiB0cnVlOwkJLy8gdW5jb25kaXRpb25hbCBtYXRjaAorCQlkbyB7CisJCSAgICBpZiAocGF0aChzLCBzX2luZGV4LCBzX2xlbiwgcGF0LCBwX2luZGV4LCBwX2xlbiwgZGVsaW0pKQorCQkJcmV0dXJuIHRydWU7CisJCX0gd2hpbGUgKCsrc19pbmRleCA8IHNfbGVuKTsKKwkJLy8gcmFuIG91dCBvZiBzdHJpbmcgd2l0aG91dCBhIG1hdGNoCisJCXJldHVybiBmYWxzZTsKKworCSAgICBkZWZhdWx0OgorCQkvLyBpZiByYW4gb3V0IG9mIHN0cmluZyBvciBubyBtYXRjaCwgZmFpbAorCQlpZiAoc19pbmRleCA+PSBzX2xlbiB8fCBjICE9IHMuY2hhckF0KHNfaW5kZXgpKQorCQkgICAgcmV0dXJuIGZhbHNlOworCisJCS8vIHRyeSB0aGUgbmV4dCBzdHJpbmcgYW5kIHBhdHRlcm4gY2hhcmFjdGVycworCQlzX2luZGV4Kys7CisJCXBfaW5kZXgrKzsKKwkgICAgfQorCX0KKwlyZXR1cm4gc19pbmRleCA+PSBzX2xlbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEaXJlY3RvcnkgcGF0dGVybiBtYXRjaAorICAgICAqCisgICAgICogQHBhcmFtIHMJCWJhc2Ugc3RyaW5nCisgICAgICogQHBhcmFtIHBhdAlwYXR0ZXJuIHN0cmluZworICAgICAqIEByZXR1cm4JCXRydWUgaWYgYmFzZSBpcyBhIG1hdGNoaW5nIGRpcmVjdG9yeSBvZiBwYXR0ZXJuCisgICAgICovCisgICAgc3RhdGljIHB1YmxpYyBib29sZWFuIGRpcihTdHJpbmcgcywgU3RyaW5nIHBhdCwgY2hhciBkZWxpbSkgeworCXRyeSB7CisJICAgIHJldHVybiBkaXIocywgMCwgcy5sZW5ndGgoKSwgcGF0LCAwLCBwYXQubGVuZ3RoKCksIGRlbGltKTsKKwl9IGNhdGNoIChTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKwkgICAgcmV0dXJuIGZhbHNlOworCX0KKyAgICB9CisKKyAgICBzdGF0aWMgcHJpdmF0ZSBib29sZWFuIGRpcihTdHJpbmcgcywgaW50IHNfaW5kZXgsIGludCBzX2xlbiwKKwlTdHJpbmcgcGF0LCBpbnQgcF9pbmRleCwgaW50IHBfbGVuLCBjaGFyIGRlbGltKQorCSAgICB0aHJvd3MgU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB7CisKKwl3aGlsZSAocF9pbmRleCA8IHBfbGVuKSB7CisJICAgIGNoYXIgYyA9IHBhdC5jaGFyQXQocF9pbmRleCk7CisJICAgIHN3aXRjaCAoYykgeworCSAgICBjYXNlICclJzoKKwkJaWYgKHNfaW5kZXggPj0gc19sZW4pCQkvLyBlbmQgb2YgYmFzZT8KKwkJICAgIHJldHVybiB0cnVlOwkJLy8gc3Vic2V0IG1hdGNoCisJCWlmICgrK3BfaW5kZXggPj0gcF9sZW4pCQkvLyAlIGF0IGVuZCBvZiBwYXR0ZXJuPworCQkgICAgcmV0dXJuIGZhbHNlOwkJLy8gbm8gaW5mZXJpb3JzIHBlcm1pdHRlZAorCQlkbyB7CisJCSAgICBpZiAoZGlyKHMsIHNfaW5kZXgsIHNfbGVuLCBwYXQsIHBfaW5kZXgsIHBfbGVuLCBkZWxpbSkpCisJCQlyZXR1cm4gdHJ1ZTsKKwkJfSB3aGlsZSAocy5jaGFyQXQoc19pbmRleCkgIT0gZGVsaW0gJiYgKytzX2luZGV4IDwgc19sZW4pOworCisJCWlmIChzX2luZGV4ICsgMSA9PSBzX2xlbikJLy8gcyBlbmRzIHdpdGggYSBkZWxpbWl0ZXIKKwkJICAgIHJldHVybiB0cnVlOwkJLy8gbXVzdCBiZSBhIHN1YnNldCBvZiBwYXR0ZXJuCisJCXJldHVybiBkaXIocywgc19pbmRleCwgc19sZW4sIHBhdCwgcF9pbmRleCwgcF9sZW4sIGRlbGltKTsKKworCSAgICBjYXNlICcqJzoKKwkJcmV0dXJuIHRydWU7CQkJLy8gdW5jb25kaXRpb25hbCBtYXRjaAorCisJICAgIGRlZmF1bHQ6CisJCWlmIChzX2luZGV4ID49IHNfbGVuKQkJLy8gZW5kIG9mIGJhc2U/CisJCSAgICByZXR1cm4gYyA9PSBkZWxpbTsJCS8vIG1hdGNoZWQgaWYgYXQgZGVsaW1pdGVyCisKKwkJaWYgKGMgIT0gcy5jaGFyQXQoc19pbmRleCkpCisJCSAgICByZXR1cm4gZmFsc2U7CisKKwkJLy8gdHJ5IHRoZSBuZXh0IHN0cmluZyBhbmQgcGF0dGVybiBjaGFyYWN0ZXJzCisJCXNfaW5kZXgrKzsKKwkJcF9pbmRleCsrOworCSAgICB9CisJfQorCXJldHVybiBzX2luZGV4ID49IHNfbGVuOworICAgIH0KK30KKworLyoqCisgKiBBIEJ5dGVBcnJheU91dHB1dFN0cmVhbSB0aGF0IGFsbG93cyB1cyB0byBzaGFyZSB0aGUgYnl0ZSBhcnJheQorICogcmF0aGVyIHRoYW4gY29weSBpdC4gIEV2ZW50dWFsbHkgY291bGQgcmVwbGFjZSB0aGlzIHdpdGggc29tZXRoaW5nCisgKiB0aGF0IGRvZXNuJ3QgcmVxdWlyZSBhIHNpbmdsZSBjb250aWd1b3VzIGJ5dGUgYXJyYXkuCisgKi8KK2NsYXNzIFNoYXJlZEJ5dGVBcnJheU91dHB1dFN0cmVhbSBleHRlbmRzIEJ5dGVBcnJheU91dHB1dFN0cmVhbSB7CisgICAgcHVibGljIFNoYXJlZEJ5dGVBcnJheU91dHB1dFN0cmVhbShpbnQgc2l6ZSkgeworCXN1cGVyKHNpemUpOworICAgIH0KKworICAgIHB1YmxpYyBJbnB1dFN0cmVhbSB0b1N0cmVhbSgpIHsKKwlyZXR1cm4gbmV3IFNoYXJlZEJ5dGVBcnJheUlucHV0U3RyZWFtKGJ1ZiwgMCwgY291bnQpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21ib3gvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvbWJveC9NYm94TWVzc2FnZS5qYXZhIGIvbWJveC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9tYm94L01ib3hNZXNzYWdlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGI1N2EyNgotLS0gL2Rldi9udWxsCisrKyBiL21ib3gvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvbWJveC9NYm94TWVzc2FnZS5qYXZhCkBAIC0wLDAgKzEsNTMyIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5tYm94OworCitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CitpbXBvcnQgamF2YS50ZXh0LlNpbXBsZURhdGVGb3JtYXQ7CitpbXBvcnQgamF2YXguYWN0aXZhdGlvbi4qOworaW1wb3J0IGphdmF4Lm1haWwuKjsKK2ltcG9ydCBqYXZheC5tYWlsLmludGVybmV0Lio7CitpbXBvcnQgamF2YXgubWFpbC5ldmVudC5NZXNzYWdlQ2hhbmdlZEV2ZW50OworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLkxpbmVJbnB1dFN0cmVhbTsKKworLyoqCisgKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgYW4gUkZDODIyIHN0eWxlIGVtYWlsIG1lc3NhZ2UgdGhhdCByZXNpZGVzIGluIGEgZmlsZS4KKyAqCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCisKK3B1YmxpYyBjbGFzcyBNYm94TWVzc2FnZSBleHRlbmRzIE1pbWVNZXNzYWdlIHsKKworICAgIGJvb2xlYW4gd3JpdGFibGUgPSBmYWxzZTsKKyAgICAvLyBvcmlnaW5hbCBtc2cgZmxhZ3MsIHVzZWQgYnkgTWJveEZvbGRlciB0byBkZXRlY3QgbW9kaWZpY2F0aW9uCisgICAgRmxhZ3Mgb3JpZ0ZsYWdzOworICAgIC8qCisgICAgICogQSBVTklYIEZyb20gbGluZSBsb29rcyBsaWtlOgorICAgICAqIEZyb20gYWRkcmVzcyBEYXkgTW9uIEREIEhIOk1NOlNTIFlZWVkKKyAgICAgKi8KKyAgICBTdHJpbmcgdW5peF9mcm9tOworICAgIEludGVybmV0QWRkcmVzcyB1bml4X2Zyb21fdXNlcjsKKyAgICBEYXRlIHJjdkRhdGU7CisgICAgaW50IGxpbmVDb3VudCA9IC0xOworICAgIHByaXZhdGUgc3RhdGljIE91dHB1dFN0cmVhbSBudWxsT3V0cHV0U3RyZWFtID0gbmV3IE91dHB1dFN0cmVhbSgpIHsKKwlwdWJsaWMgdm9pZCB3cml0ZShpbnQgYikgeyB9CisJcHVibGljIHZvaWQgd3JpdGUoYnl0ZVtdIGIsIGludCBvZmYsIGludCBsZW4pIHsgfQorICAgIH07CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3QgYW4gTWJveE1lc3NhZ2UgZnJvbSB0aGUgSW5wdXRTdHJlYW0uCisgICAgICovCisgICAgcHVibGljIE1ib3hNZXNzYWdlKFNlc3Npb24gc2Vzc2lvbiwgSW5wdXRTdHJlYW0gaXMpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworCXN1cGVyKHNlc3Npb24pOworCUJ1ZmZlcmVkSW5wdXRTdHJlYW0gYmlzOworCWlmIChpcyBpbnN0YW5jZW9mIEJ1ZmZlcmVkSW5wdXRTdHJlYW0pCisJICAgIGJpcyA9IChCdWZmZXJlZElucHV0U3RyZWFtKWlzOworCWVsc2UKKwkgICAgYmlzID0gbmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0oaXMpOworCUxpbmVJbnB1dFN0cmVhbSBkaXMgPSBuZXcgTGluZUlucHV0U3RyZWFtKGJpcyk7CisJYmlzLm1hcmsoMTAyNCk7CisJU3RyaW5nIGxpbmUgPSBkaXMucmVhZExpbmUoKTsKKwlpZiAobGluZSAhPSBudWxsICYmIGxpbmUuc3RhcnRzV2l0aCgiRnJvbSAiKSkKKwkgICAgdGhpcy51bml4X2Zyb20gPSBsaW5lOworCWVsc2UKKwkgICAgYmlzLnJlc2V0KCk7CisJcGFyc2UoYmlzKTsKKwlzYXZlZCA9IHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGFuIE1ib3hNZXNzYWdlIHVzaW5nIHRoZSBnaXZlbiBJbnRlcm5ldEhlYWRlcnMgb2JqZWN0CisgICAgICogYW5kIGNvbnRlbnQgZnJvbSBhbiBJbnB1dFN0cmVhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgTWJveE1lc3NhZ2UoTWJveEZvbGRlciBmb2xkZXIsIEludGVybmV0SGVhZGVycyBoZHJzLCBJbnB1dFN0cmVhbSBpcywKKwkJCQlpbnQgbXNnbm8sIFN0cmluZyB1bml4X2Zyb20sIGJvb2xlYW4gd3JpdGFibGUpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJc3VwZXIoZm9sZGVyLCBoZHJzLCBudWxsLCBtc2dubyk7CisJc2V0RmxhZ3NGcm9tSGVhZGVycygpOworCW9yaWdGbGFncyA9IGdldEZsYWdzKCk7CisJdGhpcy51bml4X2Zyb20gPSB1bml4X2Zyb207CisJdGhpcy53cml0YWJsZSA9IHdyaXRhYmxlOworCXRoaXMuY29udGVudFN0cmVhbSA9IGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlICJGcm9tIiBhdHRyaWJ1dGUuIFRoZSAiRnJvbSIgYXR0cmlidXRlIGNvbnRhaW5zCisgICAgICogdGhlIGlkZW50aXR5IG9mIHRoZSBwZXJzb24ocykgd2hvIHdpc2hlZCB0aGlzIG1lc3NhZ2UgdG8gCisgICAgICogYmUgc2VudC4gPHA+CisgICAgICogCisgICAgICogSWYgb3VyIHN1cGVyY2xhc3MgZG9lc24ndCBoYXZlIGEgdmFsdWUsIHdlIHJldHVybiB0aGUgYWRkcmVzcworICAgICAqIGZyb20gdGhlIFVOSVggRnJvbSBsaW5lLgorICAgICAqCisgICAgICogQHJldHVybiAgICAgICAgICBhcnJheSBvZiBBZGRyZXNzIG9iamVjdHMKKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIE1lc3NhZ2luZ0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBBZGRyZXNzW10gZ2V0RnJvbSgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCUFkZHJlc3NbXSByZXQgPSBzdXBlci5nZXRGcm9tKCk7CisJaWYgKHJldCA9PSBudWxsKSB7CisJICAgIEludGVybmV0QWRkcmVzcyBpYSA9IGdldFVuaXhGcm9tKCk7CisJICAgIGlmIChpYSAhPSBudWxsKQorCQlyZXQgPSBuZXcgSW50ZXJuZXRBZGRyZXNzW10geyBpYSB9OworCX0KKwlyZXR1cm4gcmV0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGFkZHJlc3MgZnJvbSB0aGUgVU5JWCAiRnJvbSIgbGluZS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gICAgICAgICAgVU5JWCBGcm9tIGFkZHJlc3MKKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIE1lc3NhZ2luZ0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgSW50ZXJuZXRBZGRyZXNzIGdldFVuaXhGcm9tKCkKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpZiAodW5peF9mcm9tX3VzZXIgPT0gbnVsbCAmJiB1bml4X2Zyb20gIT0gbnVsbCkgeworCSAgICBpbnQgaTsKKwkgICAgLy8gZmluZCB0aGUgc3BhY2UgYWZ0ZXIgdGhlIGFkZHJlc3MsIGJlZm9yZSB0aGUgZGF0ZQorCSAgICBpID0gdW5peF9mcm9tLmluZGV4T2YoJyAnLCA1KTsKKwkgICAgaWYgKGkgPiA1KSB7CisJCXRyeSB7CisJCSAgICB1bml4X2Zyb21fdXNlciA9CisJCQluZXcgSW50ZXJuZXRBZGRyZXNzKHVuaXhfZnJvbS5zdWJzdHJpbmcoNSwgaSkpOworCQl9IGNhdGNoIChBZGRyZXNzRXhjZXB0aW9uIGUpIHsKKwkJICAgIC8vIGlnbm9yZSBpdAorCQl9CisJICAgIH0KKwl9CisJcmV0dXJuIHVuaXhfZnJvbV91c2VyICE9IG51bGwgPworCQkoSW50ZXJuZXRBZGRyZXNzKXVuaXhfZnJvbV91c2VyLmNsb25lKCkgOiBudWxsOworICAgIH0KKworICAgIHByaXZhdGUgU3RyaW5nIGdldFVuaXhGcm9tTGluZSgpIHsKKwlpZiAodW5peF9mcm9tICE9IG51bGwpCisJICAgIHJldHVybiB1bml4X2Zyb207CisJU3RyaW5nIGZyb20gPSAidW5rbm93biI7CisJdHJ5IHsKKwkgICAgQWRkcmVzc1tdIGZyb21hID0gZ2V0RnJvbSgpOworCSAgICBpZiAoZnJvbWEgIT0gbnVsbCAmJiBmcm9tYS5sZW5ndGggPiAwICYmCisJCSAgICBmcm9tYVswXSBpbnN0YW5jZW9mIEludGVybmV0QWRkcmVzcykKKwkJZnJvbSA9ICgoSW50ZXJuZXRBZGRyZXNzKWZyb21hWzBdKS5nZXRBZGRyZXNzKCk7CisJfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIGV4KSB7IH0KKwlEYXRlIGQgPSBudWxsOworCXRyeSB7CisJICAgIGQgPSBnZXRTZW50RGF0ZSgpOworCX0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBleCkgeworCSAgICAvLyBpZ25vcmUKKwl9CisJaWYgKGQgPT0gbnVsbCkKKwkgICAgZCA9IG5ldyBEYXRlKCk7CisJLy8gRnJvbSBzaGFubm9uIE1vbiBKdW4gMTAgMTI6MDY6NTIgMjAwMgorCVNpbXBsZURhdGVGb3JtYXQgZm10ID0gbmV3IFNpbXBsZURhdGVGb3JtYXQoIkVFRSBMTEwgZGQgSEg6bW06c3MgeXl5eSIpOworCXJldHVybiAiRnJvbSAiICsgZnJvbSArICIgIiArIGZtdC5mb3JtYXQoZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBkYXRlIHRoaXMgbWVzc2FnZSB3YXMgcmVjZWl2ZWQsIGZyb20gdGhlIFVOSVggRnJvbSBsaW5lLgorICAgICAqCisgICAgICogQHJldHVybiAgICAgICAgICB0aGUgZGF0ZSB0aGlzIG1lc3NhZ2Ugd2FzIHJlY2VpdmVkCisgICAgICogQGV4Y2VwdGlvbiAgICAgICBNZXNzYWdpbmdFeGNlcHRpb24KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKQkvLyBmb3IgRGF0ZSBjb25zdHJ1Y3RvcgorICAgIHB1YmxpYyBEYXRlIGdldFJlY2VpdmVkRGF0ZSgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWlmIChyY3ZEYXRlID09IG51bGwgJiYgdW5peF9mcm9tICE9IG51bGwpIHsKKwkgICAgaW50IGk7CisJICAgIC8vIGZpbmQgdGhlIHNwYWNlIGFmdGVyIHRoZSBhZGRyZXNzLCBiZWZvcmUgdGhlIGRhdGUKKwkgICAgaSA9IHVuaXhfZnJvbS5pbmRleE9mKCcgJywgNSk7CisJICAgIGlmIChpID4gNSkgeworCQl0cnkgeworCQkgICAgcmN2RGF0ZSA9IG5ldyBEYXRlKHVuaXhfZnJvbS5zdWJzdHJpbmcoaSkpOworCQl9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisJCSAgICAvLyBpZ25vcmUgaXQKKwkJfQorCSAgICB9CisJfQorCXJldHVybiByY3ZEYXRlID09IG51bGwgPyBudWxsIDogbmV3IERhdGUocmN2RGF0ZS5nZXRUaW1lKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgbnVtYmVyIG9mIGxpbmVzIGZvciB0aGUgY29udGVudCBvZiB0aGlzIG1lc3NhZ2UuCisgICAgICogUmV0dXJuIC0xIGlmIHRoaXMgbnVtYmVyIGNhbm5vdCBiZSBkZXRlcm1pbmVkLiA8cD4KKyAgICAgKgorICAgICAqIE5vdGUgdGhhdCB0aGlzIG51bWJlciBtYXkgbm90IGJlIGFuIGV4YWN0IG1lYXN1cmUgb2YgdGhlIAorICAgICAqIGNvbnRlbnQgbGVuZ3RoIGFuZCBtYXkgb3IgbWF5IG5vdCBhY2NvdW50IGZvciBhbnkgdHJhbnNmZXIgCisgICAgICogZW5jb2Rpbmcgb2YgdGhlIGNvbnRlbnQuIDxwPgorICAgICAqCisgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiByZXR1cm5zIC0xLgorICAgICAqCisgICAgICogQHJldHVybiAgICAgICAgICBudW1iZXIgb2YgbGluZXMgaW4gdGhlIGNvbnRlbnQuCisgICAgICogQGV4Y2VwdGlvbglNZXNzYWdpbmdFeGNlcHRpb24KKyAgICAgKi8gIAorICAgIHB1YmxpYyBpbnQgZ2V0TGluZUNvdW50KCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKGxpbmVDb3VudCA8IDAgJiYgaXNNaW1lVHlwZSgidGV4dC9wbGFpbiIpKSB7CisJICAgIExpbmVDb3VudGVyIGxjID0gbnVsbDsKKwkgICAgLy8gd3JpdGVUbyB3aWxsIHNldCB0aGUgU0VFTiBmbGFnLCByZW1lbWJlciB0aGUgb3JpZ2luYWwgc3RhdGUKKwkgICAgYm9vbGVhbiBzZWVuID0gaXNTZXQoRmxhZ3MuRmxhZy5TRUVOKTsKKwkgICAgdHJ5IHsKKwkJbGMgPSBuZXcgTGluZUNvdW50ZXIobnVsbE91dHB1dFN0cmVhbSk7CisJCWdldERhdGFIYW5kbGVyKCkud3JpdGVUbyhsYyk7CisJCWxpbmVDb3VudCA9IGxjLmdldExpbmVDb3VudCgpOworCSAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworCQkvLyBpZ25vcmUgaXQsIGNhbid0IGhhcHBlbgorCSAgICB9IGZpbmFsbHkgeworCQl0cnkgeworCQkgICAgaWYgKGxjICE9IG51bGwpCisJCQlsYy5jbG9zZSgpOworCQl9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworCQkgICAgLy8gY2FuJ3QgaGFwcGVuCisJCX0KKwkgICAgfQorCSAgICBpZiAoIXNlZW4pCisJCXNldEZsYWcoRmxhZ3MuRmxhZy5TRUVOLCBmYWxzZSk7CisJfQorCXJldHVybiBsaW5lQ291bnQ7CisgICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgc3BlY2lmaWVkIGZsYWdzIG9uIHRoaXMgbWVzc2FnZSB0byB0aGUgc3BlY2lmaWVkIHZhbHVlLgorICAgICAqCisgICAgICogQHBhcmFtIGZsYWdzCXRoZSBmbGFncyB0byBiZSBzZXQKKyAgICAgKiBAcGFyYW0gc2V0CXRoZSB2YWx1ZSB0byBiZSBzZXQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRGbGFncyhGbGFncyBuZXdGbGFncywgYm9vbGVhbiBzZXQpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJRmxhZ3Mgb2xkRmxhZ3MgPSAoRmxhZ3MpZmxhZ3MuY2xvbmUoKTsKKwlzdXBlci5zZXRGbGFncyhuZXdGbGFncywgc2V0KTsKKwlpZiAoIWZsYWdzLmVxdWFscyhvbGRGbGFncykpIHsKKwkgICAgc2V0SGVhZGVyc0Zyb21GbGFncyh0aGlzKTsKKwkgICAgaWYgKGZvbGRlciAhPSBudWxsKQorCQkoKE1ib3hGb2xkZXIpZm9sZGVyKS5ub3RpZnlNZXNzYWdlQ2hhbmdlZExpc3RlbmVycygKKwkJCQlNZXNzYWdlQ2hhbmdlZEV2ZW50LkZMQUdTX0NIQU5HRUQsIHRoaXMpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIGNvbnRlbnQgdHlwZSwgbWFwcGluZyBmcm9tIFN1blYzIHR5cGVzIHRvIE1JTUUgdHlwZXMKKyAgICAgKiBhcyBuZWNlc3NhcnkuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRDb250ZW50VHlwZSgpICB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlTdHJpbmcgY3QgPSBzdXBlci5nZXRDb250ZW50VHlwZSgpOworCWlmIChjdC5pbmRleE9mKCcvJykgPCAwKQorCSAgICBjdCA9IFN1blYzQm9keVBhcnQuTWltZVYzTWFwLnRvTWltZShjdCk7CisJcmV0dXJuIGN0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFByb2R1Y2UgdGhlIHJhdyBieXRlcyBvZiB0aGUgY29udGVudC4gVGhpcyBtZXRob2QgaXMgdXNlZCBkdXJpbmcKKyAgICAgKiBwYXJzaW5nLCB0byBjcmVhdGUgYSBEYXRhSGFuZGxlciBvYmplY3QgZm9yIHRoZSBjb250ZW50LiBTdWJjbGFzc2VzCisgICAgICogdGhhdCBjYW4gcHJvdmlkZSBhIHNlcGFyYXRlIGlucHV0IHN0cmVhbSBmb3IganVzdCB0aGUgbWVzc2FnZSAKKyAgICAgKiBjb250ZW50IG1pZ2h0IHdhbnQgdG8gb3ZlcnJpZGUgdGhpcyBtZXRob2QuIDxwPgorICAgICAqCisgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiBqdXN0IHJldHVybnMgYSBCeXRlQXJyYXlJbnB1dFN0cmVhbSBjb25zdHJ1Y3RlZAorICAgICAqIG91dCBvZiB0aGUgPGNvZGU+Y29udGVudDwvY29kZT4gYnl0ZSBhcnJheS4KKyAgICAgKgorICAgICAqIEBzZWUgI2NvbnRlbnQKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgSW5wdXRTdHJlYW0gZ2V0Q29udGVudFN0cmVhbSgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWlmIChmb2xkZXIgIT0gbnVsbCkKKwkgICAgKChNYm94Rm9sZGVyKWZvbGRlcikuY2hlY2tPcGVuKCk7CisJaWYgKGlzRXhwdW5nZWQoKSkKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2VSZW1vdmVkRXhjZXB0aW9uKCJtYm94IG1lc3NhZ2UgZXhwdW5nZWQiKTsKKwlpZiAoIWlzU2V0KEZsYWdzLkZsYWcuU0VFTikpCisJICAgIHNldEZsYWcoRmxhZ3MuRmxhZy5TRUVOLCB0cnVlKTsKKwlyZXR1cm4gc3VwZXIuZ2V0Q29udGVudFN0cmVhbSgpOworICAgIH0KKworICAgIC8qKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAorICAgICAqIFJldHVybiBhIERhdGFIYW5kbGVyIGZvciB0aGlzIE1lc3NhZ2UncyBjb250ZW50LgorICAgICAqIElmIHRoaXMgaXMgYSBTdW5WMyBtdWx0aXBhcnQgbWVzc2FnZSwgaGFuZGxlIGl0IHNwZWNpYWxseS4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24JTWVzc2FnaW5nRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBEYXRhSGFuZGxlciBnZXREYXRhSGFuZGxlcigpIAorCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpZiAoZGggPT0gbnVsbCkgeworCSAgICAvLyBYWFggLSBGb2xsb3dpbmcgaXMgYSBrbHVkZ2UgdG8gYXZvaWQgaGF2aW5nIHRvIHJlZ2lzdGVyCisJICAgIC8vIHRoZSAibXVsdGlwYXJ0L3gtc3VuLWF0dGFjaG1lbnQiIGRhdGEgdHlwZSB3aXRoIHRoZSBKQUYuCisJICAgIFN0cmluZyBjdCA9IGdldENvbnRlbnRUeXBlKCk7CisJICAgIGlmIChjdC5lcXVhbHNJZ25vcmVDYXNlKCJtdWx0aXBhcnQveC1zdW4tYXR0YWNobWVudCIpKQorCQlkaCA9IG5ldyBEYXRhSGFuZGxlcigKKwkJICAgIG5ldyBTdW5WM011bHRpcGFydChuZXcgTWltZVBhcnREYXRhU291cmNlKHRoaXMpKSwgY3QpOworCSAgICBlbHNlCisJCXJldHVybiBzdXBlci5nZXREYXRhSGFuZGxlcigpOwkvLyB3aWxsIHNldCAiZGgiCisJfQorCXJldHVybiBkaDsKKyAgICB9CisKKyAgICAvLyBoZXJlIG9ubHkgdG8gYWxsb3cgcGFja2FnZSBwcml2YXRlIGFjY2VzcyBmcm9tIE1ib3hGb2xkZXIKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRNZXNzYWdlTnVtYmVyKGludCBtc2dubykgeworCXN1cGVyLnNldE1lc3NhZ2VOdW1iZXIobXNnbm8pOworICAgIH0KKworICAgIC8vIGhlcmUgdG8gc3luY2hyb25pemUgYWNjZXNzIHRvIGV4cHVuZ2VkIGZpZWxkCisgICAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIGlzRXhwdW5nZWQoKSB7CisJcmV0dXJuIHN1cGVyLmlzRXhwdW5nZWQoKTsKKyAgICB9CisKKyAgICAvLyBoZXJlIHRvIHN5bmNocm9uaXplIGFuZCB0byBhbGxvdyBhY2Nlc3MgZnJvbSBNYm94Rm9sZGVyCisgICAgcHJvdGVjdGVkIHN5bmNocm9uaXplZCB2b2lkIHNldEV4cHVuZ2VkKGJvb2xlYW4gZXhwdW5nZWQpIHsKKwlzdXBlci5zZXRFeHB1bmdlZChleHB1bmdlZCk7CisgICAgfQorCisgICAgLy8gWFhYIC0gV2UgYXNzdW1lIHRoYXQgb25seSBib2R5IHBhcnRzIHRoYXQgYXJlIHBhcnQgb2YgYSBTdW5WMworICAgIC8vIG11bHRpcGFydCB3aWxsIHVzZSB0aGUgU3VuVjMgaGVhZGVycyAoWC1TdW4tQ29udGVudC1MZW5ndGgsCisgICAgLy8gWC1TdW4tQ29udGVudC1MaW5lcywgWC1TdW4tRGF0YS1UeXBlLCBYLVN1bi1FbmNvZGluZy1JbmZvLAorICAgIC8vIFgtU3VuLURhdGEtRGVzY3JpcHRpb24sIFgtU3VuLURhdGEtTmFtZSkgc28gd2UgZG9uJ3QgaGFuZGxlCisgICAgLy8gdGhlbSBoZXJlLgorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBmbGFncyBmb3IgdGhpcyBtZXNzYWdlIGJhc2VkIG9uIHRoZSBTdGF0dXMsCisgICAgICogWC1TdGF0dXMsIGFuZCBYLUR0LURlbGV0ZS1UaW1lIGhlYWRlcnMuCisgICAgICoKKyAgICAgKiBTSU1TIDIuMDoKKyAgICAgKiAiWC1TdGF0dXM6IERGQVQiLCBkZWxldGVkLCBmbGFnZ2VkLCBhbnN3ZXJlZCwgZHJhZnQuCisgICAgICogVW5zZXQgZmxhZ3MgcmVwcmVzZW50ZWQgYXMgIiQiLgorICAgICAqIFVzZXIgZmxhZ3Mgbm90IHN1cHBvcnRlZC4KKyAgICAgKgorICAgICAqIFVuaXZlcnNpdHkgb2YgV2FzaGluZ3RvbiBJTUFQIHNlcnZlcjoKKyAgICAgKiAiWC1TdGF0dXM6IERGQVQiLCBkZWxldGVkLCBmbGFnZ2VkLCBhbnN3ZXJlZCwgZHJhZnQuCisgICAgICogVW5zZXQgZmxhZ3Mgbm90IHByZXNlbnQuCisgICAgICogIlgtS2V5d29yZHM6IHVzZXJmbGFnMSB1c2VyZmxhZzIiCisgICAgICovCisgICAgcHJpdmF0ZSBzeW5jaHJvbml6ZWQgdm9pZCBzZXRGbGFnc0Zyb21IZWFkZXJzKCkgeworCWZsYWdzID0gbmV3IEZsYWdzKEZsYWdzLkZsYWcuUkVDRU5UKTsKKwl0cnkgeworCSAgICBTdHJpbmcgcyA9IGdldEhlYWRlcigiU3RhdHVzIiwgbnVsbCk7CisJICAgIGlmIChzICE9IG51bGwpIHsKKwkJaWYgKHMuaW5kZXhPZignUicpID49IDApCisJCSAgICBmbGFncy5hZGQoRmxhZ3MuRmxhZy5TRUVOKTsKKwkJaWYgKHMuaW5kZXhPZignTycpID49IDApCisJCSAgICBmbGFncy5yZW1vdmUoRmxhZ3MuRmxhZy5SRUNFTlQpOworCSAgICB9CisJICAgIHMgPSBnZXRIZWFkZXIoIlgtRHQtRGVsZXRlLVRpbWUiLCBudWxsKTsJLy8gc2V0IGJ5IGR0bWFpbAorCSAgICBpZiAocyAhPSBudWxsKQorCQlmbGFncy5hZGQoRmxhZ3MuRmxhZy5ERUxFVEVEKTsKKwkgICAgcyA9IGdldEhlYWRlcigiWC1TdGF0dXMiLCBudWxsKTsJCS8vIHNldCBieSBJTUFQIHNlcnZlcgorCSAgICBpZiAocyAhPSBudWxsKSB7CisJCWlmIChzLmluZGV4T2YoJ0QnKSA+PSAwKQorCQkgICAgZmxhZ3MuYWRkKEZsYWdzLkZsYWcuREVMRVRFRCk7CisJCWlmIChzLmluZGV4T2YoJ0YnKSA+PSAwKQorCQkgICAgZmxhZ3MuYWRkKEZsYWdzLkZsYWcuRkxBR0dFRCk7CisJCWlmIChzLmluZGV4T2YoJ0EnKSA+PSAwKQorCQkgICAgZmxhZ3MuYWRkKEZsYWdzLkZsYWcuQU5TV0VSRUQpOworCQlpZiAocy5pbmRleE9mKCdUJykgPj0gMCkKKwkJICAgIGZsYWdzLmFkZChGbGFncy5GbGFnLkRSQUZUKTsKKwkgICAgfQorCSAgICBzID0gZ2V0SGVhZGVyKCJYLUtleXdvcmRzIiwgbnVsbCk7CQkvLyBzZXQgYnkgSU1BUCBzZXJ2ZXIKKwkgICAgaWYgKHMgIT0gbnVsbCkgeworCQlTdHJpbmdUb2tlbml6ZXIgc3QgPSBuZXcgU3RyaW5nVG9rZW5pemVyKHMpOworCQl3aGlsZSAoc3QuaGFzTW9yZVRva2VucygpKQorCQkgICAgZmxhZ3MuYWRkKHN0Lm5leHRUb2tlbigpKTsKKwkgICAgfQorCX0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBlKSB7CisJICAgIC8vIGlnbm9yZSBpdAorCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIHZhcmlvdXMgaGVhZGVyIGZpZWxkcyB0aGF0IHJlcHJlc2VudCB0aGUgbWVzc2FnZSBmbGFncy4KKyAgICAgKi8KKyAgICBzdGF0aWMgdm9pZCBzZXRIZWFkZXJzRnJvbUZsYWdzKE1pbWVNZXNzYWdlIG1zZykgeworCXRyeSB7CisJICAgIEZsYWdzIGZsYWdzID0gbXNnLmdldEZsYWdzKCk7CisJICAgIFN0cmluZ0J1aWxkZXIgc3RhdHVzID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKwkgICAgaWYgKGZsYWdzLmNvbnRhaW5zKEZsYWdzLkZsYWcuU0VFTikpCisJCXN0YXR1cy5hcHBlbmQoJ1InKTsKKwkgICAgaWYgKCFmbGFncy5jb250YWlucyhGbGFncy5GbGFnLlJFQ0VOVCkpCisJCXN0YXR1cy5hcHBlbmQoJ08nKTsKKwkgICAgaWYgKHN0YXR1cy5sZW5ndGgoKSA+IDApCisJCW1zZy5zZXRIZWFkZXIoIlN0YXR1cyIsIHN0YXR1cy50b1N0cmluZygpKTsKKwkgICAgZWxzZQorCQltc2cucmVtb3ZlSGVhZGVyKCJTdGF0dXMiKTsKKworCSAgICBib29sZWFuIHNpbXMgPSBmYWxzZTsKKwkgICAgU3RyaW5nIHMgPSBtc2cuZ2V0SGVhZGVyKCJYLVN0YXR1cyIsIG51bGwpOworCSAgICAvLyBpcyBpdCBhIFNJTVMgMi4wIGZvcm1hdCBYLVN0YXR1cyBoZWFkZXI/CisJICAgIHNpbXMgPSBzICE9IG51bGwgJiYgcy5sZW5ndGgoKSA9PSA0ICYmIHMuaW5kZXhPZignJCcpID49IDA7CisJICAgIHN0YXR1cy5zZXRMZW5ndGgoMCk7CisJICAgIGlmIChmbGFncy5jb250YWlucyhGbGFncy5GbGFnLkRFTEVURUQpKQorCQlzdGF0dXMuYXBwZW5kKCdEJyk7CisJICAgIGVsc2UgaWYgKHNpbXMpCisJCXN0YXR1cy5hcHBlbmQoJyQnKTsKKwkgICAgaWYgKGZsYWdzLmNvbnRhaW5zKEZsYWdzLkZsYWcuRkxBR0dFRCkpCisJCXN0YXR1cy5hcHBlbmQoJ0YnKTsKKwkgICAgZWxzZSBpZiAoc2ltcykKKwkJc3RhdHVzLmFwcGVuZCgnJCcpOworCSAgICBpZiAoZmxhZ3MuY29udGFpbnMoRmxhZ3MuRmxhZy5BTlNXRVJFRCkpCisJCXN0YXR1cy5hcHBlbmQoJ0EnKTsKKwkgICAgZWxzZSBpZiAoc2ltcykKKwkJc3RhdHVzLmFwcGVuZCgnJCcpOworCSAgICBpZiAoZmxhZ3MuY29udGFpbnMoRmxhZ3MuRmxhZy5EUkFGVCkpCisJCXN0YXR1cy5hcHBlbmQoJ1QnKTsKKwkgICAgZWxzZSBpZiAoc2ltcykKKwkJc3RhdHVzLmFwcGVuZCgnJCcpOworCSAgICBpZiAoc3RhdHVzLmxlbmd0aCgpID4gMCkKKwkJbXNnLnNldEhlYWRlcigiWC1TdGF0dXMiLCBzdGF0dXMudG9TdHJpbmcoKSk7CisJICAgIGVsc2UKKwkJbXNnLnJlbW92ZUhlYWRlcigiWC1TdGF0dXMiKTsKKworCSAgICBTdHJpbmdbXSB1c2VyRmxhZ3MgPSBmbGFncy5nZXRVc2VyRmxhZ3MoKTsKKwkgICAgaWYgKHVzZXJGbGFncy5sZW5ndGggPiAwKSB7CisJCXN0YXR1cy5zZXRMZW5ndGgoMCk7CisJCWZvciAoaW50IGkgPSAwOyBpIDwgdXNlckZsYWdzLmxlbmd0aDsgaSsrKQorCQkgICAgc3RhdHVzLmFwcGVuZCh1c2VyRmxhZ3NbaV0pLmFwcGVuZCgnICcpOworCQlzdGF0dXMuc2V0TGVuZ3RoKHN0YXR1cy5sZW5ndGgoKSAtIDEpOwkvLyBzbWFzaCB0cmFpbGluZyBzcGFjZQorCQltc2cuc2V0SGVhZGVyKCJYLUtleXdvcmRzIiwgc3RhdHVzLnRvU3RyaW5nKCkpOworCSAgICB9CisJICAgIGlmIChmbGFncy5jb250YWlucyhGbGFncy5GbGFnLkRFTEVURUQpKSB7CisJCXMgPSBtc2cuZ2V0SGVhZGVyKCJYLUR0LURlbGV0ZS1UaW1lIiwgbnVsbCk7CisJCWlmIChzID09IG51bGwpCisJCSAgICAvLyBYWFggLSBzaG91bGQgYmUgdGltZQorCQkgICAgbXNnLnNldEhlYWRlcigiWC1EdC1EZWxldGUtVGltZSIsICIxIik7CisJICAgIH0KKwl9IGNhdGNoIChNZXNzYWdpbmdFeGNlcHRpb24gZSkgeworCSAgICAvLyBpZ25vcmUgaXQKKwl9CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgdXBkYXRlSGVhZGVycygpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXN1cGVyLnVwZGF0ZUhlYWRlcnMoKTsKKwlzZXRIZWFkZXJzRnJvbUZsYWdzKHRoaXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNhdmUgYW55IGNoYW5nZXMgbWFkZSB0byB0aGlzIG1lc3NhZ2UuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2F2ZUNoYW5nZXMoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpZiAoZm9sZGVyICE9IG51bGwpCisJICAgICgoTWJveEZvbGRlcilmb2xkZXIpLmNoZWNrT3BlbigpOworCWlmIChpc0V4cHVuZ2VkKCkpCisJICAgIHRocm93IG5ldyBNZXNzYWdlUmVtb3ZlZEV4Y2VwdGlvbigibWJveCBtZXNzYWdlIGV4cHVuZ2VkIik7CisJaWYgKCF3cml0YWJsZSkKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiTWVzc2FnZSBpcyByZWFkLW9ubHkiKTsKKworCXN1cGVyLnNhdmVDaGFuZ2VzKCk7CisKKwl0cnkgeworCSAgICAvKgorCSAgICAgKiBDb3VudCB0aGUgc2l6ZSBvZiB0aGUgYm9keSwgaW4gb3JkZXIgdG8gc2V0IHRoZSBDb250ZW50LUxlbmd0aAorCSAgICAgKiBoZWFkZXIuICAoU2hvdWxkIHdlIG9ubHkgZG8gdGhpcyB0byB1cGRhdGUgYW4gZXhpc3RpbmcKKwkgICAgICogQ29udGVudC1MZW5ndGggaGVhZGVyPykKKwkgICAgICogWFhYIC0gV2UgY291bGQgY2FjaGUgdGhlIGNvbnRlbnQgYnl0ZXMgaGVyZSwgZm9yIHVzZSBsYXRlcgorCSAgICAgKiBpbiB3cml0ZVRvLgorCSAgICAgKi8KKwkgICAgQ29udGVudExlbmd0aENvdW50ZXIgY29zID0gbmV3IENvbnRlbnRMZW5ndGhDb3VudGVyKCk7CisJICAgIE91dHB1dFN0cmVhbSBvcyA9IG5ldyBOZXdsaW5lT3V0cHV0U3RyZWFtKGNvcyk7CisJICAgIHN1cGVyLndyaXRlVG8ob3MpOworCSAgICBvcy5mbHVzaCgpOworCSAgICBzZXRIZWFkZXIoIkNvbnRlbnQtTGVuZ3RoIiwgU3RyaW5nLnZhbHVlT2YoY29zLmdldFNpemUoKSkpOworCSAgICAvLyBzZXRDb250ZW50U2l6ZSgoaW50KWNvcy5nZXRTaXplKCkpOworCX0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBlKSB7CisJICAgIHRocm93IGU7CisJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigidW5leHBlY3RlZCBleGNlcHRpb24gIiArIGUpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBFeHBvc2UgbW9kaWZpZWQgZmxhZyB0byBNYm94Rm9sZGVyLgorICAgICAqLworICAgIGJvb2xlYW4gaXNNb2RpZmllZCgpIHsKKwlyZXR1cm4gbW9kaWZpZWQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHV0IG91dCBhIGJ5dGUgc3RyZWFtIHN1aXRhYmxlIGZvciBzYXZpbmcgdG8gYSBmaWxlLgorICAgICAqIFhYWCAtIHVsdGltYXRlbHkgaW1wbGVtZW50ICJpZ25vcmUgaGVhZGVycyIgaGVyZT8KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB3cml0ZVRvRmlsZShPdXRwdXRTdHJlYW0gb3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJdHJ5IHsKKwkgICAgaWYgKGdldEhlYWRlcigiQ29udGVudC1MZW5ndGgiKSA9PSBudWxsKSB7CisJCS8qCisJCSAqIENvdW50IHRoZSBzaXplIG9mIHRoZSBib2R5LCBpbiBvcmRlciB0byBzZXQgdGhlCisJCSAqIENvbnRlbnQtTGVuZ3RoIGhlYWRlci4KKwkJICovCisJCUNvbnRlbnRMZW5ndGhDb3VudGVyIGNvcyA9IG5ldyBDb250ZW50TGVuZ3RoQ291bnRlcigpOworCQlPdXRwdXRTdHJlYW0gb29zID0gbmV3IE5ld2xpbmVPdXRwdXRTdHJlYW0oY29zKTsKKwkJc3VwZXIud3JpdGVUbyhvb3MsIG51bGwpOworCQlvb3MuZmx1c2goKTsKKwkJc2V0SGVhZGVyKCJDb250ZW50LUxlbmd0aCIsIFN0cmluZy52YWx1ZU9mKGNvcy5nZXRTaXplKCkpKTsKKwkJLy8gc2V0Q29udGVudFNpemUoKGludCljb3MuZ2V0U2l6ZSgpKTsKKwkgICAgfQorCisJICAgIG9zID0gbmV3IE5ld2xpbmVPdXRwdXRTdHJlYW0ob3MsIHRydWUpOworCSAgICBQcmludFN0cmVhbSBwb3MgPSBuZXcgUHJpbnRTdHJlYW0ob3MsIGZhbHNlLCAiaXNvLTg4NTktMSIpOworCisJICAgIHBvcy5wcmludGxuKGdldFVuaXhGcm9tTGluZSgpKTsKKwkgICAgc3VwZXIud3JpdGVUbyhwb3MsIG51bGwpOworCSAgICBwb3MuZmx1c2goKTsKKwl9IGNhdGNoIChNZXNzYWdpbmdFeGNlcHRpb24gZSkgeworCSAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oInVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlKTsKKwl9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGVUbyhPdXRwdXRTdHJlYW0gb3MsIFN0cmluZ1tdIGlnbm9yZUxpc3QpCisJCQkJdGhyb3dzIElPRXhjZXB0aW9uLCBNZXNzYWdpbmdFeGNlcHRpb24geworCS8vIHNldCB0aGUgU0VFTiBmbGFnIG5vdywgd2hpY2ggd2lsbCBub3JtYWxseSBiZSBzZXQgYnkKKwkvLyBnZXRDb250ZW50U3RyZWFtLCBzbyBpdCB3aWxsIHNob3cgdXAgaW4gb3VyIGhlYWRlcnMKKwlpZiAoIWlzU2V0KEZsYWdzLkZsYWcuU0VFTikpCisJICAgIHNldEZsYWcoRmxhZ3MuRmxhZy5TRUVOLCB0cnVlKTsKKwlzdXBlci53cml0ZVRvKG9zLCBpZ25vcmVMaXN0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnRlcnBvc2Ugb24gc3VwZXJjbGFzcyBtZXRob2QgdG8gbWFrZSBzdXJlIGZvbGRlciBpcyBzdGlsbCBvcGVuCisgICAgICogYW5kIG1lc3NhZ2UgaGFzbid0IGJlZW4gZXhwdW5nZWQuCisgICAgICovCisgICAgcHVibGljIFN0cmluZ1tdIGdldEhlYWRlcihTdHJpbmcgbmFtZSkKKwkJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWlmIChmb2xkZXIgIT0gbnVsbCkKKwkgICAgKChNYm94Rm9sZGVyKWZvbGRlcikuY2hlY2tPcGVuKCk7CisJaWYgKGlzRXhwdW5nZWQoKSkKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2VSZW1vdmVkRXhjZXB0aW9uKCJtYm94IG1lc3NhZ2UgZXhwdW5nZWQiKTsKKwlyZXR1cm4gc3VwZXIuZ2V0SGVhZGVyKG5hbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEludGVycG9zZSBvbiBzdXBlcmNsYXNzIG1ldGhvZCB0byBtYWtlIHN1cmUgZm9sZGVyIGlzIHN0aWxsIG9wZW4KKyAgICAgKiBhbmQgbWVzc2FnZSBoYXNuJ3QgYmVlbiBleHB1bmdlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEhlYWRlcihTdHJpbmcgbmFtZSwgU3RyaW5nIGRlbGltaXRlcikKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpZiAoZm9sZGVyICE9IG51bGwpCisJICAgICgoTWJveEZvbGRlcilmb2xkZXIpLmNoZWNrT3BlbigpOworCWlmIChpc0V4cHVuZ2VkKCkpCisJICAgIHRocm93IG5ldyBNZXNzYWdlUmVtb3ZlZEV4Y2VwdGlvbigibWJveCBtZXNzYWdlIGV4cHVuZ2VkIik7CisJcmV0dXJuIHN1cGVyLmdldEhlYWRlcihuYW1lLCBkZWxpbWl0ZXIpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21ib3gvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvbWJveC9NYm94UHJvdmlkZXIuamF2YSBiL21ib3gvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvbWJveC9NYm94UHJvdmlkZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kMGIwNTZkCi0tLSAvZGV2L251bGwKKysrIGIvbWJveC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9tYm94L01ib3hQcm92aWRlci5qYXZhCkBAIC0wLDAgKzEsMjkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLm1ib3g7CisKK2ltcG9ydCBqYXZheC5tYWlsLlByb3ZpZGVyOworCisvKioKKyAqIFRoZSBNYm94IHByb3RvY29sIHByb3ZpZGVyLgorICovCitwdWJsaWMgY2xhc3MgTWJveFByb3ZpZGVyIGV4dGVuZHMgUHJvdmlkZXIgeworICAgIHB1YmxpYyBNYm94UHJvdmlkZXIoKSB7CisJc3VwZXIoUHJvdmlkZXIuVHlwZS5TVE9SRSwgIm1ib3giLCBNYm94U3RvcmUuY2xhc3MuZ2V0TmFtZSgpLAorCSAgICAiT3JhY2xlIiwgbnVsbCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWJveC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9tYm94L01ib3hTdG9yZS5qYXZhIGIvbWJveC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9tYm94L01ib3hTdG9yZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFjZTM5YmMKLS0tIC9kZXYvbnVsbAorKysgYi9tYm94L3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL21ib3gvTWJveFN0b3JlLmphdmEKQEAgLTAsMCArMSwxMTMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLm1ib3g7CisKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YXgubWFpbC4qOworCitwdWJsaWMgY2xhc3MgTWJveFN0b3JlIGV4dGVuZHMgU3RvcmUgeworCisgICAgU3RyaW5nIHVzZXI7CisgICAgU3RyaW5nIGhvbWU7CisgICAgTWFpbGJveCBtYjsKKyAgICBzdGF0aWMgRmxhZ3MgcGVybUZsYWdzOworCisgICAgc3RhdGljIHsKKwkvLyB3ZSBzdXBwb3J0IGFsbCBmbGFncworCXBlcm1GbGFncyA9IG5ldyBGbGFncygpOworCXBlcm1GbGFncy5hZGQoRmxhZ3MuRmxhZy5TRUVOKTsKKwlwZXJtRmxhZ3MuYWRkKEZsYWdzLkZsYWcuUkVDRU5UKTsKKwlwZXJtRmxhZ3MuYWRkKEZsYWdzLkZsYWcuREVMRVRFRCk7CisJcGVybUZsYWdzLmFkZChGbGFncy5GbGFnLkZMQUdHRUQpOworCXBlcm1GbGFncy5hZGQoRmxhZ3MuRmxhZy5BTlNXRVJFRCk7CisJcGVybUZsYWdzLmFkZChGbGFncy5GbGFnLkRSQUZUKTsKKwlwZXJtRmxhZ3MuYWRkKEZsYWdzLkZsYWcuVVNFUik7CisgICAgfQorCisgICAgcHVibGljIE1ib3hTdG9yZShTZXNzaW9uIHNlc3Npb24sIFVSTE5hbWUgdXJsKSB7CisJc3VwZXIoc2Vzc2lvbiwgdXJsKTsKKworCS8vIFhYWCAtIGhhbmRsZSBzZWN1cml0eSBleGNlcHRpb24KKwl1c2VyID0gU3lzdGVtLmdldFByb3BlcnR5KCJ1c2VyLm5hbWUiKTsKKwlob21lID0gU3lzdGVtLmdldFByb3BlcnR5KCJ1c2VyLmhvbWUiKTsKKwlTdHJpbmcgb3MgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoIm9zLm5hbWUiKTsKKwl0cnkgeworCSAgICBTdHJpbmcgY2wgPSAiY29tLnN1bi5tYWlsLm1ib3guIiArIG9zICsgIk1haWxib3giOworCSAgICBtYiA9IChNYWlsYm94KUNsYXNzLmZvck5hbWUoY2wpLgorCQkJCQlnZXREZWNsYXJlZENvbnN0cnVjdG9yKCkubmV3SW5zdGFuY2UoKTsKKwl9IGNhdGNoIChFeGNlcHRpb24gZSkgeworCSAgICBtYiA9IG5ldyBEZWZhdWx0TWFpbGJveCgpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTaW5jZSB3ZSBkbyBub3QgaGF2ZSBhbnkgYXV0aGVudGljYXRpb24KKyAgICAgKiB0byBkbyBhbmQgd2UgZG8gbm90IHdhbnQgYSBkaWFsb2cgcHV0IHVwIGFza2luZyB0aGUgdXNlciBmb3IgYSAKKyAgICAgKiBwYXNzd29yZCB3ZSBhbHdheXMgc3VjY2VlZCBpbiBjb25uZWN0aW5nLgorICAgICAqIEJ1dCBpZiB3ZSdyZSBnaXZlbiBhIHBhc3N3b3JkLCB0aGF0IG1lYW5zIHRoZSB1c2VyIGlzCisgICAgICogZG9pbmcgc29tZXRoaW5nIHdyb25nIHNvIGZhaWwgdGhlIHJlcXVlc3QuCisgICAgICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gcHJvdG9jb2xDb25uZWN0KFN0cmluZyBob3N0LCBpbnQgcG9ydCwgU3RyaW5nIHVzZXIsCisJCQkJU3RyaW5nIHBhc3N3ZCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisKKwlpZiAocGFzc3dkICE9IG51bGwpCisJICAgIHRocm93IG5ldyBBdXRoZW50aWNhdGlvbkZhaWxlZEV4Y2VwdGlvbigKKwkJCQkibWJveCBkb2VzIG5vdCBhbGxvdyBwYXNzd29yZHMiKTsKKwkvLyBYWFggLSBzaG91bGQgd2UgdXNlIHRoZSB1c2VyPworCXJldHVybiB0cnVlOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIHNldFVSTE5hbWUoVVJMTmFtZSB1cmwpIHsKKwkvLyBob3N0LCB1c2VyLCBwYXNzd29yZCwgYW5kIGZpbGUgZG9uJ3QgbWF0dGVyIHNvIHdlIHN0cmlwIHRoZW0gb3V0CisJaWYgKHVybCAhPSBudWxsICYmICh1cmwuZ2V0VXNlcm5hbWUoKSAhPSBudWxsIHx8CisJCQkgICAgdXJsLmdldEhvc3QoKSAhPSBudWxsIHx8CisJCQkgICAgdXJsLmdldEZpbGUoKSAhPSBudWxsKSkKKwkgICAgdXJsID0gbmV3IFVSTE5hbWUodXJsLmdldFByb3RvY29sKCksIG51bGwsIC0xLCBudWxsLCBudWxsLCBudWxsKTsKKwlzdXBlci5zZXRVUkxOYW1lKHVybCk7CisgICAgfQorCisKKyAgICBwdWJsaWMgRm9sZGVyIGdldERlZmF1bHRGb2xkZXIoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwljaGVja0Nvbm5lY3RlZCgpOworCisJcmV0dXJuIG5ldyBNYm94Rm9sZGVyKHRoaXMsIG51bGwpOworICAgIH0KKworICAgIHB1YmxpYyBGb2xkZXIgZ2V0Rm9sZGVyKFN0cmluZyBuYW1lKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwljaGVja0Nvbm5lY3RlZCgpOworCisJcmV0dXJuIG5ldyBNYm94Rm9sZGVyKHRoaXMsIG5hbWUpOworICAgIH0KKworICAgIHB1YmxpYyBGb2xkZXIgZ2V0Rm9sZGVyKFVSTE5hbWUgdXJsKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwljaGVja0Nvbm5lY3RlZCgpOworCXJldHVybiBnZXRGb2xkZXIodXJsLmdldEZpbGUoKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrQ29ubmVjdGVkKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKCFpc0Nvbm5lY3RlZCgpKQorCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKCJOb3QgY29ubmVjdGVkIik7CisgICAgfQorCisgICAgTWFpbEZpbGUgZ2V0TWFpbEZpbGUoU3RyaW5nIGZvbGRlcikgeworCXJldHVybiBtYi5nZXRNYWlsRmlsZSh1c2VyLCBmb2xkZXIpOworICAgIH0KKworICAgIFNlc3Npb24gZ2V0U2Vzc2lvbigpIHsKKwlyZXR1cm4gc2Vzc2lvbjsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYm94L3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL21ib3gvTWVzc2FnZUxvYWRlci5qYXZhIGIvbWJveC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9tYm94L01lc3NhZ2VMb2FkZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNWVjYWFhCi0tLSAvZGV2L251bGwKKysrIGIvbWJveC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9tYm94L01lc3NhZ2VMb2FkZXIuamF2YQpAQCAtMCwwICsxLDI4NSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwubWJveDsKKworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZhLnV0aWwuKjsKKworLyoqCisgKiBBIHN1cHBvcnQgY2xhc3MgdGhhdCBjb250YWlucyB0aGUgc3RhdGUgYW5kIGxvZ2ljIG5lZWRlZCB3aGVuCisgKiBsb2FkaW5nIG1lc3NhZ2VzIGZyb20gYSBmb2xkZXIuCisgKi8KK2ZpbmFsIGNsYXNzIE1lc3NhZ2VMb2FkZXIgeworICAgIHByaXZhdGUgZmluYWwgVGVtcEZpbGUgdGVtcDsKKyAgICBwcml2YXRlIEZpbGVJbnB1dFN0cmVhbSBmaXMgPSBudWxsOworICAgIHByaXZhdGUgT3V0cHV0U3RyZWFtIGZvcyA9IG51bGw7CisgICAgcHJpdmF0ZSBpbnQgcG9zLCBsZW47CS8vIHBvc2l0aW9uIGluIGFuZCBsZW5ndGggb2YgYnVmZmVyCisgICAgcHJpdmF0ZSBsb25nIG9mZjsJCS8vIGN1cnJlbnQgb2Zmc2V0IGluIHRlbXAgZmlsZQorICAgIHByaXZhdGUgbG9uZyBwcmV2ZW5kOwkvLyB0aGUgZW5kIG9mIHRoZSBwcmV2aW91cyBtZXNzYWdlIGluIHRlbXAgZmlsZQorICAgIHByaXZhdGUgTWJveEZvbGRlci5NZXNzYWdlTWV0YWRhdGEgbWQ7CisgICAgcHJpdmF0ZSBieXRlW10gYnVmID0gbnVsbDsKKyAgICAvLyB0aGUgbGVuZ3RoIG9mIHRoZSBsb25nZXN0IGhlYWRlciB3ZSdsbCBuZWVkIHRvIGxvb2sgYXQKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTElORUxFTiA9ICJDb250ZW50LUxlbmd0aDogWFhYWFhYWFhYWCIubGVuZ3RoKCk7CisgICAgcHJpdmF0ZSBjaGFyW10gbGluZTsKKworICAgIHB1YmxpYyBNZXNzYWdlTG9hZGVyKFRlbXBGaWxlIHRlbXApIHsKKwl0aGlzLnRlbXAgPSB0ZW1wOworICAgIH0KKworICAgIC8qKgorICAgICAqIExvYWQgbWVzc2FnZXMgZnJvbSB0aGUgZ2l2ZW4gZmlsZSBkZXNjcmlwdG9yLCBzdGFydGluZyBhdCB0aGUKKyAgICAgKiBzcGVjaWZpZWQgb2Zmc2V0LCBhZGRpbmcgdGhlIE1lc3NhZ2VNZXRhZGF0YSB0byB0aGUgbGlzdC4gPHA+CisgICAgICoKKyAgICAgKiBUaGUgZGF0YSBpcyBhc3N1bWVkIHRvIGJlIGluIFVOSVggbWJveCBmb3JtYXQsIHdpdGggbmV3bGluZXMKKyAgICAgKiBvbmx5IGFzIHRoZSBsaW5lIHRlcm1pbmF0b3JzLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgbG9hZChGaWxlRGVzY3JpcHRvciBmZCwgbG9uZyBvZmZzZXQsCisJCQkJTGlzdDxNYm94Rm9sZGVyLk1lc3NhZ2VNZXRhZGF0YT4gbXNncykKKwkJCQl0aHJvd3MgSU9FeGNlcHRpb24geworCS8vIFhYWCAtIGNvdWxkIGFsbG9jYXRlIGFuZCBkZWFsbG9jYXRlIGJ1ZmZlcnMgaGVyZQorCWludCBsb2FkZWQgPSAwOworCXRyeSB7CisJICAgIGZpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZmQpOworCSAgICBpZiAoZmlzLnNraXAob2Zmc2V0KSAhPSBvZmZzZXQpCisJCXRocm93IG5ldyBFT0ZFeGNlcHRpb24oIkZhaWxlZCB0byBza2lwIHRvIG9mZnNldCAiICsgb2Zmc2V0KTsKKwkgICAgdGhpcy5vZmYgPSBwcmV2ZW5kID0gdGVtcC5sZW5ndGgoKTsKKwkgICAgcG9zID0gbGVuID0gMDsKKwkgICAgbGluZSA9IG5ldyBjaGFyW0xJTkVMRU5dOworCSAgICBidWYgPSBuZXcgYnl0ZVs2NCAqIDEwMjRdOworCSAgICBmb3MgPSB0ZW1wLmdldEFwcGVuZFN0cmVhbSgpOworCSAgICBpbnQgbjsKKwkgICAgLy8ga2VlcCBsb2FkaW5nIG1lc3NhZ2VzIGFzIGxvbmcgYXMgd2UgaGF2ZSBoZWFkZXJzCisJICAgIHdoaWxlICgobiA9IHNraXBIZWFkZXIobG9hZGVkID09IDApKSA+PSAwKSB7CisJCWxvbmcgc3RhcnQ7CisJCWlmIChuID09IDApIHsKKwkJICAgIC8vIGRpZG4ndCBmaW5kIGEgQ29udGVudC1MZW5ndGgsIHNraXAgdGhlIGJvZHkKKwkJICAgIHN0YXJ0ID0gc2tpcEJvZHkoKTsKKwkJICAgIGlmIChzdGFydCA8IDApIHsKKwkJCS8vIG1kLmVuZCA9IC0xOworCQkJbWQuZGF0YWVuZCA9IC0xOworCQkJbXNncy5hZGQobWQpOworCQkJbG9hZGVkKys7CisJCQlicmVhazsKKwkJICAgIH0KKwkJICAgIG1kLmRhdGFlbmQgPSBzdGFydDsKKwkJfSBlbHNlIHsKKwkJICAgIC8vIHNraXAgb3ZlciB0aGUgYm9keQorCQkgICAgc2tpcChuKTsKKwkJICAgIG1kLmRhdGFlbmQgPSBvZmY7CisJCSAgICBpbnQgYjsKKwkJICAgIC8vIHNraXAgYW55IGJsYW5rIGxpbmVzIGFmdGVyIHRoZSBib2R5CisJCSAgICB3aGlsZSAoKGIgPSBnZXQoKSkgPj0gMCkgeworCQkJaWYgKGIgIT0gJ1xuJykKKwkJCSAgICBicmVhazsKKwkJICAgIH0KKwkJICAgIHN0YXJ0ID0gb2ZmOworCQkgICAgaWYgKGIgPj0gMCkKKwkJCXN0YXJ0LS07CS8vIGJhY2sgdXAgb25lIGJ5dGUgaWYgbm90IGF0IEVPRgorCQl9CisJCS8vIG1kLmVuZCA9IHN0YXJ0OworCQlwcmV2ZW5kID0gc3RhcnQ7CisJCW1zZ3MuYWRkKG1kKTsKKwkJbG9hZGVkKys7CisJICAgIH0KKwl9IGZpbmFsbHkgeworCSAgICB0cnkgeworCQlmaXMuY2xvc2UoKTsKKwkgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKwkJLy8gaWdub3JlCisJICAgIH0KKwkgICAgdHJ5IHsKKwkJZm9zLmNsb3NlKCk7CisJICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisJCS8vIGlnbm9yZQorCSAgICB9CisJICAgIGxpbmUgPSBudWxsOworCSAgICBidWYgPSBudWxsOworCX0KKwlyZXR1cm4gbG9hZGVkOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNraXAgb3ZlciB0aGUgbWVzc2FnZSBoZWFkZXIsIHJldHVybmluZyB0aGUgY29udGVudCBsZW5ndGgKKyAgICAgKiBvZiB0aGUgYm9keSwgb3IgMCBpZiBubyBDb250ZW50LUxlbmd0aCBoZWFkZXIgd2FzIHNlZW4uCisgICAgICogVXBkYXRlIHRoZSBNZXNzYWdlTWV0YWRhdGEgYmFzZWQgb24gdGhlIGhlYWRlcnMgc2Vlbi4KKyAgICAgKiByZXR1cm4gLTEgb24gRU9GLgorICAgICAqLworICAgIHByaXZhdGUgaW50IHNraXBIZWFkZXIoYm9vbGVhbiBmaXJzdCkgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJaW50IGNsZW4gPSAwOworCWJvb2xlYW4gYm9sID0gdHJ1ZTsKKwlpbnQgbHBvcyA9IC0xOworCWludCBiOworCWJvb2xlYW4gc2F3X3VuaXhfZnJvbSA9IGZhbHNlOworCWludCBsaW5lbm8gPSAwOworCW1kID0gbmV3IE1ib3hGb2xkZXIuTWVzc2FnZU1ldGFkYXRhKCk7CisJbWQuc3RhcnQgPSBwcmV2ZW5kOworCW1kLnJlY2VudCA9IHRydWU7CisJd2hpbGUgKChiID0gZ2V0KCkpID49IDApIHsKKwkgICAgaWYgKGJvbCkgeworCQlpZiAoYiA9PSAnXG4nKQorCQkgICAgYnJlYWs7CisJCWxwb3MgPSAwOworCSAgICB9CisJICAgIGlmIChiID09ICdcbicpIHsKKwkJYm9sID0gdHJ1ZTsKKwkJbGluZW5vKys7CisJCS8vIG5ld2xpbmUgYXQgZW5kIG9mIGxpbmUsIHdhcyB0aGUgbGluZSBvbmUgb2YgdGhlIGhlYWRlcnMKKwkJLy8gd2UncmUgbG9va2luZyBmb3I/CisJCWlmIChscG9zID4gNykgeworCQkgICAgLy8gWFhYIC0gbWFrZSB0aGlzIG1vcmUgZWZmaWNpZW50PworCQkgICAgU3RyaW5nIHMgPSBuZXcgU3RyaW5nKGxpbmUsIDAsIGxwb3MpOworCQkgICAgLy8gZmFzdCBjaGVjayBmb3IgQ29udGVudC1MZW5ndGggaGVhZGVyCisJCSAgICBpZiAobGluZW5vID09IDEgJiYgbGluZVswXSA9PSAnRicgJiYgaXNQcmVmaXgocywgIkZyb20gIikpIHsKKwkJCXNhd191bml4X2Zyb20gPSB0cnVlOworCQkgICAgfSBlbHNlIGlmIChsaW5lWzddID09ICctJyAmJgorCQkJCWlzUHJlZml4KHMsICJDb250ZW50LUxlbmd0aDoiKSkgeworCQkJcyA9IHMuc3Vic3RyaW5nKDE1KS50cmltKCk7CisJCQl0cnkgeworCQkJICAgIGNsZW4gPSBJbnRlZ2VyLnBhcnNlSW50KHMpOworCQkJfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGV4KSB7CisJCQkgICAgLy8gaWdub3JlIGl0CisJCQl9CisJCSAgICAvLyBmYXN0IGNoZWNrIGZvciBTdGF0dXMgaGVhZGVyCisJCSAgICB9IGVsc2UgaWYgKChsaW5lWzFdID09ICd0JyB8fCBsaW5lWzFdID09ICdUJykgJiYKKwkJCQlpc1ByZWZpeChzLCAiU3RhdHVzOiIpKSB7CisJCQlpZiAocy5pbmRleE9mKCdPJykgPj0gMCkKKwkJCSAgICBtZC5yZWNlbnQgPSBmYWxzZTsKKwkJICAgIC8vIGZhc3QgY2hlY2sgZm9yIFgtU3RhdHVzIGhlYWRlcgorCQkgICAgfSBlbHNlIGlmICgobGluZVszXSA9PSAndCcgfHwgbGluZVszXSA9PSAnVCcpICYmCisJCQkJaXNQcmVmaXgocywgIlgtU3RhdHVzOiIpKSB7CisJCQlpZiAocy5pbmRleE9mKCdEJykgPj0gMCkKKwkJCSAgICBtZC5kZWxldGVkID0gdHJ1ZTsKKwkJICAgIC8vIGZhc3QgY2hlY2sgZm9yIFgtRHQtRGVsZXRlLVRpbWUgaGVhZGVyCisJCSAgICB9IGVsc2UgaWYgKGxpbmVbNF0gPT0gJy0nICYmCisJCQkJaXNQcmVmaXgocywgIlgtRHQtRGVsZXRlLVRpbWU6IikpIHsKKwkJCW1kLmRlbGV0ZWQgPSB0cnVlOworCQkgICAgLy8gZmFzdCBjaGVjayBmb3IgWC1JTUFQIGhlYWRlcgorCQkgICAgfSBlbHNlIGlmIChsaW5lWzVdID09ICdQJyAmJiBzLnN0YXJ0c1dpdGgoIlgtSU1BUDoiKSkgeworCQkJbWQuaW1hcCA9IHRydWU7CisJCSAgICB9CisJCX0KKwkgICAgfSBlbHNlIHsKKwkJLy8gYWNjdW1sYXRlIGRhdGEgaW4gbGluZSBidWZmZXIKKwkJYm9sID0gZmFsc2U7CisJCWlmIChscG9zIDwgMCkJLy8gaWdub3JpbmcgdGhpcyBsaW5lCisJCSAgICBjb250aW51ZTsKKwkJaWYgKGxwb3MgPT0gMCAmJiAoYiA9PSAnICcgfHwgYiA9PSAnXHQnKSkKKwkJICAgIGxwb3MgPSAtMTsJLy8gaWdub3JlIGNvbnRpbnVhdGlvbiBsaW5lcworCQllbHNlIGlmIChscG9zIDwgbGluZS5sZW5ndGgpCisJCSAgICBsaW5lW2xwb3MrK10gPSAoY2hhciliOworCSAgICB9CisJfQorCisJLy8gaWYgd2UgaGl0IEVPRiwgb3IgdGhpcyBpcyB0aGUgZmlyc3QgbWVzc2FnZSB3ZSdyZSBsb2FkaW5nIGFuZAorCS8vIGl0IGRvZXNuJ3QgaGF2ZSBhIFVOSVggRnJvbSBsaW5lLCByZXR1cm4gRU9GLgorCS8vIChBZnRlciB0aGUgZmlyc3QgbWVzc2FnZSwgVU5JWCBGcm9tIGxpbmVzIGFyZSBzZWVuIGJ5IHNraXBCb2R5CisJLy8gdG8gdGVybWluYXRlIHRoZSBtZXNzYWdlLikKKwlpZiAoYiA8IDAgfHwgKGZpcnN0ICYmICFzYXdfdW5peF9mcm9tKSkKKwkgICAgcmV0dXJuIC0xOworCWVsc2UKKwkgICAgcmV0dXJuIGNsZW47CisgICAgfQorCisgICAgLyoqCisgICAgICogRG9lcyAicyIgc3RhcnQgd2l0aCAicHJlIiwgaWdub3JpbmcgY2FzZT8KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIGlzUHJlZml4KFN0cmluZyBzLCBTdHJpbmcgcHJlKSB7CisJcmV0dXJuIHMucmVnaW9uTWF0Y2hlcyh0cnVlLCAwLCBwcmUsIDAsIHByZS5sZW5ndGgoKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2tpcCBvdmVyIHRoZSBib2R5IG9mIHRoZSBtZXNzYWdlIGxvb2tpbmcgZm9yIGEgbGluZSB0aGF0IHN0YXJ0cworICAgICAqIHdpdGggIkZyb20gIi4gIElmIGZvdW5kLCByZXR1cm4gdGhlIG9mZnNldCBvZiB0aGUgYmVnaW5uaW5nIG9mCisgICAgICogdGhhdCBsaW5lLiAgUmV0dXJuIC0xIG9uIEVPRi4KKyAgICAgKi8KKyAgICBwcml2YXRlIGxvbmcgc2tpcEJvZHkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCWJvb2xlYW4gYm9sID0gdHJ1ZTsKKwlpbnQgbHBvcyA9IC0xOworCWxvbmcgbG9mZiA9IG9mZjsKKwlpbnQgYjsKKwl3aGlsZSAoKGIgPSBnZXQoKSkgPj0gMCkgeworCSAgICBpZiAoYm9sKSB7CisJCWxwb3MgPSAwOworCQlsb2ZmID0gb2ZmIC0gMTsKKwkgICAgfQorCSAgICBpZiAoYiA9PSAnXG4nKSB7CisJCWJvbCA9IHRydWU7CisJCWlmIChscG9zID49IDUpIHsJLy8gaGF2ZSBlbm91Z2ggZGF0YSB0byB0ZXN0PworCQkgICAgaWYgKGxpbmVbMF0gPT0gJ0YnICYmIGxpbmVbMV0gPT0gJ3InICYmIGxpbmVbMl0gPT0gJ28nICYmCisJCQlsaW5lWzNdID09ICdtJyAmJiBsaW5lWzRdID09ICcgJykKKwkJCXJldHVybiBsb2ZmOworCQl9CisJICAgIH0gZWxzZSB7CisJCWJvbCA9IGZhbHNlOworCQlpZiAobHBvcyA8IDApCisJCSAgICBjb250aW51ZTsKKwkJaWYgKGxwb3MgPT0gMCAmJiBiICE9ICdGJykKKwkJICAgIGxwb3MgPSAtMTsJCS8vIGlnbm9yZSBsaW5lcyB0aGF0IGRvbid0IHN0YXJ0IHdpdGggRgorCQllbHNlIGlmIChscG9zIDwgNSkJLy8gb25seSBuZWVkIGZpcnN0IDUgY2hhcnMgdG8gdGVzdAorCQkgICAgbGluZVtscG9zKytdID0gKGNoYXIpYjsKKwkgICAgfQorCX0KKwlyZXR1cm4gLTE7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2tpcCAibiIgYnl0ZXMsIHJldHVybmluZyBob3cgbXVjaCB3ZSB3ZXJlIGFibGUgdG8gc2tpcC4KKyAgICAgKi8KKyAgICBwcml2YXRlIGZpbmFsIGludCBza2lwKGludCBuKSB0aHJvd3MgSU9FeGNlcHRpb24geworCWludCBuMCA9IG47CisJaWYgKHBvcyArIG4gPCBsZW4pIHsKKwkgICAgcG9zICs9IG47CS8vIGNhbiBkbyBpdCBhbGwgd2l0aGluIHRoaXMgYnVmZmVyCisJICAgIG9mZiArPSBuOworCX0gZWxzZSB7CisJICAgIGRvIHsKKwkJbiAtPSAobGVuIC0gcG9zKTsJLy8gc2tpcCByZXN0IG9mIHRoaXMgYnVmZmVyCisJCW9mZiArPSAobGVuIC0gcG9zKTsKKwkJZmlsbCgpOworCQlpZiAobGVuIDw9IDApCS8vIHJhbiBvdXQgb2YgZGF0YQorCQkgICAgcmV0dXJuIG4wIC0gbjsKKwkgICAgfSB3aGlsZSAobiA+IGxlbik7CisJICAgIHBvcyArPSBuOworCSAgICBvZmYgKz0gbjsKKwl9CisJcmV0dXJuIG4wOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgbmV4dCBieXRlLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgaW50IGdldCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJaWYgKHBvcyA+PSBsZW4pCisJICAgIGZpbGwoKTsKKwlpZiAocG9zID49IGxlbikKKwkgICAgcmV0dXJuIC0xOworCWVsc2UgeworCSAgICBvZmYrKzsKKwkgICAgcmV0dXJuIGJ1Zltwb3MrK10gJiAweGZmOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaWxsIG91ciBidWZmZXIgd2l0aCBtb3JlIGRhdGEuCisgICAgICogRXZlcnkgYnVmZmVyIHdlIHJlYWQgaXMgYWxzbyB3cml0dGVuIHRvIHRoZSB0ZW1wIGZpbGUuCisgICAgICovCisgICAgcHJpdmF0ZSBmaW5hbCB2b2lkIGZpbGwoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCWxlbiA9IGZpcy5yZWFkKGJ1Zik7CisJcG9zID0gMDsKKwlpZiAobGVuID4gMCkKKwkgICAgZm9zLndyaXRlKGJ1ZiwgMCwgbGVuKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYm94L3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL21ib3gvTmV3bGluZU91dHB1dFN0cmVhbS5qYXZhIGIvbWJveC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9tYm94L05ld2xpbmVPdXRwdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNGEzMWNiCi0tLSAvZGV2L251bGwKKysrIGIvbWJveC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9tYm94L05ld2xpbmVPdXRwdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDk0IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5tYm94OworCitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuU3RhbmRhcmRDaGFyc2V0czsKKworLyoqCisgKiBDb252ZXJ0IHRoZSB2YXJpb3VzIG5ld2xpbmUgY29udmVudGlvbnMgdG8gdGhlIGxvY2FsIHBsYXRmb3JtJ3MKKyAqIG5ld2xpbmUgY29udmVudGlvbi4gIE9wdGlvbmFsbHksIG1ha2Ugc3VyZSB0aGUgb3V0cHV0IGVuZHMgd2l0aAorICogYSBibGFuayBsaW5lLgorICovCitwdWJsaWMgY2xhc3MgTmV3bGluZU91dHB1dFN0cmVhbSBleHRlbmRzIEZpbHRlck91dHB1dFN0cmVhbSB7CisgICAgcHJpdmF0ZSBpbnQgbGFzdGIgPSAtMTsKKyAgICBwcml2YXRlIGludCBib2wgPSAxOyAvLyBudW1iZXIgb2YgdGltZXMgaW4gYSByb3cgd2UncmUgYXQgYmVnaW5uaW5nIG9mIGxpbmUKKyAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gZW5kV2l0aEJsYW5rTGluZTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gbmV3bGluZTsKKworICAgIHN0YXRpYyB7CisJU3RyaW5nIHMgPSBudWxsOworCXRyeSB7CisJICAgIHMgPSBTeXN0ZW0ubGluZVNlcGFyYXRvcigpOworCX0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHNleCkgeworCSAgICAvLyBpZ25vcmUsIHNob3VsZCBuZXZlciBoYXBwZW4KKwl9CisJaWYgKHMgPT0gbnVsbCB8fCBzLmxlbmd0aCgpIDw9IDApCisJICAgIHMgPSAiXG4iOworCW5ld2xpbmUgPSBzLmdldEJ5dGVzKFN0YW5kYXJkQ2hhcnNldHMuSVNPXzg4NTlfMSk7CisgICAgfQorCisgICAgcHVibGljIE5ld2xpbmVPdXRwdXRTdHJlYW0oT3V0cHV0U3RyZWFtIG9zKSB7CisJdGhpcyhvcywgZmFsc2UpOworICAgIH0KKworICAgIHB1YmxpYyBOZXdsaW5lT3V0cHV0U3RyZWFtKE91dHB1dFN0cmVhbSBvcywgYm9vbGVhbiBlbmRXaXRoQmxhbmtMaW5lKSB7CisJc3VwZXIob3MpOworCXRoaXMuZW5kV2l0aEJsYW5rTGluZSA9IGVuZFdpdGhCbGFua0xpbmU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGUoaW50IGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJaWYgKGIgPT0gJ1xyJykgeworCSAgICBvdXQud3JpdGUobmV3bGluZSk7CisJICAgIGJvbCsrOworCX0gZWxzZSBpZiAoYiA9PSAnXG4nKSB7CisJICAgIGlmIChsYXN0YiAhPSAnXHInKSB7CisJCW91dC53cml0ZShuZXdsaW5lKTsKKwkJYm9sKys7CisJICAgIH0KKwl9IGVsc2UgeworCSAgICBvdXQud3JpdGUoYik7CisJICAgIGJvbCA9IDA7CS8vIG5vIGxvbmdlciBhdCBiZWdpbm5pbmcgb2YgbGluZQorCX0KKwlsYXN0YiA9IGI7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGUoYnl0ZSBiW10pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJd3JpdGUoYiwgMCwgYi5sZW5ndGgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKGJ5dGUgYltdLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworCWZvciAoaW50IGkgPSAwIDsgaSA8IGxlbiA7IGkrKykgeworCSAgICB3cml0ZShiW29mZiArIGldKTsKKwl9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZmx1c2goKSB0aHJvd3MgSU9FeGNlcHRpb24geworCWlmIChlbmRXaXRoQmxhbmtMaW5lKSB7CisJICAgIGlmIChib2wgPT0gMCkgeworCQkvLyBub3QgYXQgYm9sLCByZXR1cm4gdG8gYm9sIGFuZCBhZGQgYSBibGFuayBsaW5lCisJCW91dC53cml0ZShuZXdsaW5lKTsKKwkJb3V0LndyaXRlKG5ld2xpbmUpOworCSAgICB9IGVsc2UgaWYgKGJvbCA9PSAxKSB7CisJCS8vIGF0IGJvbCwgYWRkIGEgYmxhbmsgbGluZQorCQlvdXQud3JpdGUobmV3bGluZSk7CisJICAgIH0KKwl9CisJYm9sID0gMjsKKwlvdXQuZmx1c2goKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYm94L3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL21ib3gvU29sYXJpc01haWxib3guamF2YSBiL21ib3gvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvbWJveC9Tb2xhcmlzTWFpbGJveC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg0ZjNhYmMKLS0tIC9kZXYvbnVsbAorKysgYi9tYm94L3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL21ib3gvU29sYXJpc01haWxib3guamF2YQpAQCAtMCwwICsxLDgxIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5tYm94OworCitpbXBvcnQgamF2YS5pby5GaWxlOworCitwdWJsaWMgY2xhc3MgU29sYXJpc01haWxib3ggZXh0ZW5kcyBNYWlsYm94IHsKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBob21lOworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIHVzZXI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIGhvbWVSZWxhdGl2ZSA9CisJCQkJQm9vbGVhbi5nZXRCb29sZWFuKCJtYWlsLm1ib3guaG9tZXJlbGF0aXZlIik7CisKKyAgICBwdWJsaWMgU29sYXJpc01haWxib3goKSB7CisJU3RyaW5nIGggPSBTeXN0ZW0uZ2V0ZW52KCJIT01FIik7CisJaWYgKGggPT0gbnVsbCkKKwkgICAgaCA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgidXNlci5ob21lIik7CisJaG9tZSA9IGg7CisJdXNlciA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgidXNlci5uYW1lIik7CisgICAgfQorCisgICAgcHVibGljIE1haWxGaWxlIGdldE1haWxGaWxlKFN0cmluZyB1c2VyLCBTdHJpbmcgZm9sZGVyKSB7CisJaWYgKGZvbGRlci5lcXVhbHNJZ25vcmVDYXNlKCJJTkJPWCIpKQorCSAgICByZXR1cm4gbmV3IFVOSVhJbmJveCh1c2VyLCBmaWxlbmFtZSh1c2VyLCBmb2xkZXIpKTsKKwllbHNlCisJICAgIHJldHVybiBuZXcgVU5JWEZvbGRlcihmaWxlbmFtZSh1c2VyLCBmb2xkZXIpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHaXZlbiBhIG5hbWUgb2YgYSBtYWlsYm94IGZvbGRlciwgZXhwYW5kIGl0IHRvIGEgZnVsbCBwYXRoIG5hbWUuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBmaWxlbmFtZShTdHJpbmcgdXNlciwgU3RyaW5nIGZvbGRlcikgeworCXRyeSB7CisJICAgIHN3aXRjaCAoZm9sZGVyLmNoYXJBdCgwKSkgeworCSAgICBjYXNlICcvJzoKKwkJcmV0dXJuIGZvbGRlcjsKKwkgICAgY2FzZSAnfic6CisJCWludCBpID0gZm9sZGVyLmluZGV4T2YoRmlsZS5zZXBhcmF0b3JDaGFyKTsKKwkJU3RyaW5nIHRhaWwgPSAiIjsKKwkJaWYgKGkgPiAwKSB7CisJCSAgICB0YWlsID0gZm9sZGVyLnN1YnN0cmluZyhpKTsKKwkJICAgIGZvbGRlciA9IGZvbGRlci5zdWJzdHJpbmcoMCwgaSk7CisJCX0KKwkJaWYgKGZvbGRlci5sZW5ndGgoKSA9PSAxKQorCQkgICAgcmV0dXJuIGhvbWUgKyB0YWlsOworCQllbHNlCisJCSAgICByZXR1cm4gIi9ob21lLyIgKyBmb2xkZXIuc3Vic3RyaW5nKDEpICsgdGFpbDsJLy8gWFhYCisJICAgIGRlZmF1bHQ6CisJCWlmIChmb2xkZXIuZXF1YWxzSWdub3JlQ2FzZSgiSU5CT1giKSkgeworCQkgICAgaWYgKHVzZXIgPT0gbnVsbCkJLy8gWFhYIC0gc2hvdWxkIG5ldmVyIGhhcHBlbgorCQkJdXNlciA9IHRoaXMudXNlcjsKKwkJICAgIFN0cmluZyBpbmJveCA9IFN5c3RlbS5nZXRlbnYoIk1BSUwiKTsKKwkJICAgIGlmIChpbmJveCA9PSBudWxsKQorCQkJaW5ib3ggPSAiL3Zhci9tYWlsLyIgKyB1c2VyOworCQkgICAgcmV0dXJuIGluYm94OworCQl9IGVsc2UgeworCQkgICAgaWYgKGhvbWVSZWxhdGl2ZSkKKwkJCXJldHVybiBob21lICsgRmlsZS5zZXBhcmF0b3IgKyBmb2xkZXI7CisJCSAgICBlbHNlCisJCQlyZXR1cm4gZm9sZGVyOworCQl9CisJICAgIH0KKwl9IGNhdGNoIChTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsKKwkgICAgcmV0dXJuIGZvbGRlcjsKKwl9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWJveC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9tYm94L1N1bk9TTWFpbGJveC5qYXZhIGIvbWJveC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9tYm94L1N1bk9TTWFpbGJveC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU1MjMwZDEKLS0tIC9kZXYvbnVsbAorKysgYi9tYm94L3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL21ib3gvU3VuT1NNYWlsYm94LmphdmEKQEAgLTAsMCArMSwyMCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwubWJveDsKKworcHVibGljIGNsYXNzIFN1bk9TTWFpbGJveCBleHRlbmRzIFNvbGFyaXNNYWlsYm94IHsKK30KZGlmZiAtLWdpdCBhL21ib3gvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvbWJveC9TdW5WM0JvZHlQYXJ0LmphdmEgYi9tYm94L3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL21ib3gvU3VuVjNCb2R5UGFydC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE4OWZmODUKLS0tIC9kZXYvbnVsbAorKysgYi9tYm94L3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL21ib3gvU3VuVjNCb2R5UGFydC5qYXZhCkBAIC0wLDAgKzEsMzE0IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5tYm94OworCitpbXBvcnQgamF2YXgubWFpbC4qOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuKjsKK2ltcG9ydCBqYXZheC5hY3RpdmF0aW9uLio7CitpbXBvcnQgamF2YS5pby4qOworCisvKioKKyAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhIFN1blYzIEJvZHlQYXJ0LgorICoKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKiBAc2VlIGphdmF4Lm1haWwuUGFydAorICogQHNlZSBqYXZheC5tYWlsLmludGVybmV0Lk1pbWVQYXJ0CisgKiBAc2VlIGphdmF4Lm1haWwuaW50ZXJuZXQuTWltZUJvZHlQYXJ0CisgKi8KKworcHVibGljIGNsYXNzIFN1blYzQm9keVBhcnQgZXh0ZW5kcyBNaW1lQm9keVBhcnQgeworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBTdW5WM0JvZHlQYXJ0IHVzaW5nIHRoZSBnaXZlbiBoZWFkZXIgYW5kCisgICAgICogY29udGVudCBieXRlcy4gPHA+CisgICAgICoKKyAgICAgKiBVc2VkIGJ5IHByb3ZpZGVycy4KKyAgICAgKgorICAgICAqIEBwYXJhbQloZWFkZXJzCVRoZSBoZWFkZXIgb2YgdGhpcyBwYXJ0CisgICAgICogQHBhcmFtCWNvbnRlbnQJYnl0ZXMgcmVwcmVzZW50aW5nIHRoZSBib2R5IG9mIHRoaXMgcGFydC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3VuVjNCb2R5UGFydChJbnRlcm5ldEhlYWRlcnMgaGVhZGVycywgYnl0ZVtdIGNvbnRlbnQpIAorCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJc3VwZXIoaGVhZGVycywgY29udGVudCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBzaXplIG9mIHRoZSBjb250ZW50IG9mIHRoaXMgQm9keVBhcnQgaW4gYnl0ZXMuCisgICAgICogUmV0dXJuIC0xIGlmIHRoZSBzaXplIGNhbm5vdCBiZSBkZXRlcm1pbmVkLiA8cD4KKyAgICAgKgorICAgICAqIE5vdGUgdGhhdCB0aGlzIG51bWJlciBtYXkgbm90IGJlIGFuIGV4YWN0IG1lYXN1cmUgb2YgdGhlCisgICAgICogY29udGVudCBzaXplIGFuZCBtYXkgb3IgbWF5IG5vdCBhY2NvdW50IGZvciBhbnkgdHJhbnNmZXIKKyAgICAgKiBlbmNvZGluZyBvZiB0aGUgY29udGVudC4gPHA+CisgICAgICoKKyAgICAgKiBAcmV0dXJuIHNpemUgaW4gYnl0ZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGdldFNpemUoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlTdHJpbmcgcyA9IGdldEhlYWRlcigiWC1TdW4tQ29udGVudC1MZW5ndGgiLCBudWxsKTsKKwl0cnkgeworCSAgICByZXR1cm4gSW50ZWdlci5wYXJzZUludChzKTsKKwl9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZXgpIHsKKwkgICAgcmV0dXJuIC0xOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIG51bWJlciBvZiBsaW5lcyBmb3IgdGhlIGNvbnRlbnQgb2YgdGhpcyBQYXJ0LgorICAgICAqIFJldHVybiAtMSBpZiB0aGlzIG51bWJlciBjYW5ub3QgYmUgZGV0ZXJtaW5lZC4gPHA+CisgICAgICoKKyAgICAgKiBOb3RlIHRoYXQgdGhpcyBudW1iZXIgbWF5IG5vdCBiZSBhbiBleGFjdCBtZWFzdXJlIG9mIHRoZSAKKyAgICAgKiBjb250ZW50IGxlbmd0aCBhbmQgbWF5IG9yIG1heSBub3QgYWNjb3VudCBmb3IgYW55IHRyYW5zZmVyIAorICAgICAqIGVuY29kaW5nIG9mIHRoZSBjb250ZW50LiAKKyAgICAgKi8gIAorICAgICBwdWJsaWMgaW50IGdldExpbmVDb3VudCgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCVN0cmluZyBzID0gZ2V0SGVhZGVyKCJYLVN1bi1Db250ZW50LUxpbmVzIiwgbnVsbCk7CisJdHJ5IHsKKwkgICAgcmV0dXJuIEludGVnZXIucGFyc2VJbnQocyk7CisJfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGV4KSB7CisJICAgIHJldHVybiAtMTsKKwl9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBUaGlzIGlzIGp1c3QgZW5vdWdoIHRvIGdldCB1cyBnb2luZy4KKyAgICAgKgorICAgICAqIEZvciBtb3JlIGNvbXBsZXRlIHRyYW5zZm9ybWF0aW9uIGZyb20gVjMgdG8gTUlNRSwgcmVmZXIgdG8KKyAgICAgKiBzdW5fYXR0LmMgZnJvbSB0aGUgU3VuIElNQVAgc2VydmVyIGNvZGUuCisgICAgICovCisgICAgc3RhdGljIGNsYXNzIE1pbWVWM01hcCB7CisJU3RyaW5nIG1pbWU7CisJU3RyaW5nIHYzOworCisJTWltZVYzTWFwKFN0cmluZyBtaW1lLCBTdHJpbmcgdjMpIHsKKwkgICAgdGhpcy5taW1lID0gbWltZTsKKwkgICAgdGhpcy52MyA9IHYzOworCX0KKworCXByaXZhdGUgc3RhdGljIE1pbWVWM01hcFtdIG1pbWVWM1RhYmxlID0gbmV3IE1pbWVWM01hcFtdIHsKKwkgICAgbmV3IE1pbWVWM01hcCgidGV4dC9wbGFpbiIsICJ0ZXh0IiksCisJICAgIG5ldyBNaW1lVjNNYXAoInRleHQvcGxhaW4iLCAiZGVmYXVsdCIpLAorCSAgICBuZXcgTWltZVYzTWFwKCJtdWx0aXBhcnQveC1zdW4tYXR0YWNobWVudCIsICJYLXN1bi1hdHRhY2htZW50IiksCisJICAgIG5ldyBNaW1lVjNNYXAoImFwcGxpY2F0aW9uL3Bvc3RzY3JpcHQiLCAicG9zdHNjcmlwdC1maWxlIiksCisJICAgIG5ldyBNaW1lVjNNYXAoImltYWdlL2dpZiIsICJnaWYtZmlsZSIpCisJICAgIC8vIGF1ZGlvLWZpbGUKKwkgICAgLy8gY3NoZWxsLXNjcmlwdAorCX07CisKKwkvLyBWMyBDb250ZW50LVR5cGUgdG8gTUlNRSBDb250ZW50LVR5cGUKKwlzdGF0aWMgU3RyaW5nIHRvTWltZShTdHJpbmcgcykgeworCSAgICBmb3IgKGludCBpID0gMDsgaSA8IG1pbWVWM1RhYmxlLmxlbmd0aDsgaSsrKSB7CisJCWlmIChtaW1lVjNUYWJsZVtpXS52My5lcXVhbHNJZ25vcmVDYXNlKHMpKQorCQkgICAgcmV0dXJuIG1pbWVWM1RhYmxlW2ldLm1pbWU7CisJICAgIH0KKwkgICAgcmV0dXJuICJhcHBsaWNhdGlvbi94LSIgKyBzOworCX0KKworCS8vIE1JTUUgQ29udGVudC1UeXBlIHRvIFYzIENvbnRlbnQtVHlwZQorCXN0YXRpYyBTdHJpbmcgdG9WMyhTdHJpbmcgcykgeworCSAgICBmb3IgKGludCBpID0gMDsgaSA8IG1pbWVWM1RhYmxlLmxlbmd0aDsgaSsrKSB7CisJCWlmIChtaW1lVjNUYWJsZVtpXS5taW1lLmVxdWFsc0lnbm9yZUNhc2UocykpCisJCSAgICByZXR1cm4gbWltZVYzVGFibGVbaV0udjM7CisJICAgIH0KKwkgICAgcmV0dXJuIHM7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIHRoZSBSRkM4MjIgIkNvbnRlbnQtVHlwZSIgaGVhZGVyIGZpZWxkLgorICAgICAqIFRoaXMgcmVwcmVzZW50cyB0aGUgY29udGVudC10eXBlIG9mIHRoZSBjb250ZW50IG9mIHRoaXMKKyAgICAgKiBCb2R5UGFydC4gVGhpcyB2YWx1ZSBtdXN0IG5vdCBiZSBudWxsLiBJZiB0aGlzIGZpZWxkIGlzCisgICAgICogdW5hdmFpbGFibGUsICJ0ZXh0L3BsYWluIiBzaG91bGQgYmUgcmV0dXJuZWQuIDxwPgorICAgICAqCisgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiB1c2VzIDxjb2RlPmdldEhlYWRlcihuYW1lKTwvY29kZT4KKyAgICAgKiB0byBvYnRhaW4gdGhlIHJlcXVpc2l0ZSBoZWFkZXIgZmllbGQuCisgICAgICoKKyAgICAgKiBAcmV0dXJuCUNvbnRlbnQtVHlwZSBvZiB0aGlzIEJvZHlQYXJ0CisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRDb250ZW50VHlwZSgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCVN0cmluZyBjdCA9IGdldEhlYWRlcigiQ29udGVudC1UeXBlIiwgbnVsbCk7CisJaWYgKGN0ID09IG51bGwpCisJICAgIGN0ID0gZ2V0SGVhZGVyKCJYLVN1bi1EYXRhLVR5cGUiLCBudWxsKTsKKwlpZiAoY3QgPT0gbnVsbCkKKwkgICAgY3QgPSAidGV4dC9wbGFpbiI7CisJZWxzZSBpZiAoY3QuaW5kZXhPZignLycpIDwgMCkKKwkgICAgY3QgPSBNaW1lVjNNYXAudG9NaW1lKGN0KTsKKwlyZXR1cm4gY3Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlICJDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nIiBoZWFkZXIKKyAgICAgKiBmaWVsZC4gUmV0dXJucyA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGUgaGVhZGVyIGlzIHVuYXZhaWxhYmxlCisgICAgICogb3IgaXRzIHZhbHVlIGlzIGFic2VudC4gPHA+CisgICAgICoKKyAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIHVzZXMgPGNvZGU+Z2V0SGVhZGVyKG5hbWUpPC9jb2RlPgorICAgICAqIHRvIG9idGFpbiB0aGUgcmVxdWlzaXRlIGhlYWRlciBmaWVsZC4KKyAgICAgKgorICAgICAqIEBzZWUgI2hlYWRlcnMKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEVuY29kaW5nKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJU3RyaW5nIGVuYyA9IHN1cGVyLmdldEVuY29kaW5nKCk7CisJaWYgKGVuYyA9PSBudWxsKQorCSAgICBlbmMgPSBnZXRIZWFkZXIoIlgtU3VuLUVuY29kaW5nLUluZm8iLCBudWxsKTsKKwlyZXR1cm4gZW5jOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlICJDb250ZW50LURlc2NyaXB0aW9uIiBoZWFkZXIgZmllbGQgb2YgdGhpcyBCb2R5UGFydC4KKyAgICAgKiBUaGlzIHR5cGljYWxseSBhc3NvY2lhdGVzIHNvbWUgZGVzY3JpcHRpdmUgaW5mb3JtYXRpb24gd2l0aCAKKyAgICAgKiB0aGlzIHBhcnQuIFJldHVybnMgbnVsbCBpZiB0aGlzIGZpZWxkIGlzIHVuYXZhaWxhYmxlIG9yIGl0cworICAgICAqIHZhbHVlIGlzIGFic2VudC4gPHA+CisgICAgICoKKyAgICAgKiBJZiB0aGUgQ29udGVudC1EZXNjcmlwdGlvbiBmaWVsZCBpcyBlbmNvZGVkIGFzIHBlciBSRkMgMjA0NywKKyAgICAgKiBpdCBpcyBkZWNvZGVkIGFuZCBjb252ZXJ0ZWQgaW50byBVbmljb2RlLiBJZiB0aGUgZGVjb2Rpbmcgb3IgCisgICAgICogY29udmVyc2lvbiBmYWlscywgdGhlIHJhdyBkYXRhIGlzIHJldHVybmVkIGFzLWlzIDxwPgorICAgICAqCisgICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiB1c2VzIDxjb2RlPmdldEhlYWRlcihuYW1lKTwvY29kZT4KKyAgICAgKiB0byBvYnRhaW4gdGhlIHJlcXVpc2l0ZSBoZWFkZXIgZmllbGQuCisgICAgICogCisgICAgICogQHJldHVybgljb250ZW50LWRlc2NyaXB0aW9uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXREZXNjcmlwdGlvbigpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCVN0cmluZyBkZXNjID0gc3VwZXIuZ2V0RGVzY3JpcHRpb24oKTsKKwlpZiAoZGVzYyA9PSBudWxsKQorCSAgICBkZXNjID0gZ2V0SGVhZGVyKCJYLVN1bi1EYXRhLURlc2NyaXB0aW9uIiwgbnVsbCk7CisJcmV0dXJuIGRlc2M7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSAiQ29udGVudC1EZXNjcmlwdGlvbiIgaGVhZGVyIGZpZWxkIGZvciB0aGlzIEJvZHlQYXJ0LgorICAgICAqIElmIHRoZSBkZXNjcmlwdGlvbiBwYXJhbWV0ZXIgaXMgPGNvZGU+bnVsbDwvY29kZT4sIHRoZW4gYW55IAorICAgICAqIGV4aXN0aW5nICJDb250ZW50LURlc2NyaXB0aW9uIiBmaWVsZHMgYXJlIHJlbW92ZWQuIDxwPgorICAgICAqCisgICAgICogSWYgdGhlIGRlc2NyaXB0aW9uIGNvbnRhaW5zIG5vbiBVUy1BU0NJSSBjaGFyYWN0ZXJzLCBpdCB3aWxsIAorICAgICAqIGJlIGVuY29kZWQgdXNpbmcgdGhlIHBsYXRmb3JtJ3MgZGVmYXVsdCBjaGFyc2V0LiBJZiB0aGUgCisgICAgICogZGVzY3JpcHRpb24gY29udGFpbnMgb25seSBVUy1BU0NJSSBjaGFyYWN0ZXJzLCBubyBlbmNvZGluZyAKKyAgICAgKiBpcyBkb25lIGFuZCBpdCBpcyB1c2VkIGFzLWlzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBkZXNjcmlwdGlvbiBjb250ZW50LWRlc2NyaXB0aW9uCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsV3JpdGVFeGNlcHRpb24gaWYgdGhlIHVuZGVybHlpbmcKKyAgICAgKgkJCWltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBCb2R5UGFydCBpcworICAgICAqCQkJb2J0YWluZWQgZnJvbSBhIFJFQURfT05MWSBmb2xkZXIuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0RGVzY3JpcHRpb24oU3RyaW5nIGRlc2NyaXB0aW9uKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwl0aHJvdyBuZXcgTWV0aG9kTm90U3VwcG9ydGVkRXhjZXB0aW9uKCJTdW5WM0JvZHlQYXJ0IG5vdCB3cml0YWJsZSIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgIkNvbnRlbnQtRGVzY3JpcHRpb24iIGhlYWRlciBmaWVsZCBmb3IgdGhpcyBCb2R5UGFydC4KKyAgICAgKiBJZiB0aGUgZGVzY3JpcHRpb24gcGFyYW1ldGVyIGlzIDxjb2RlPm51bGw8L2NvZGU+LCB0aGVuIGFueSAKKyAgICAgKiBleGlzdGluZyAiQ29udGVudC1EZXNjcmlwdGlvbiIgZmllbGRzIGFyZSByZW1vdmVkLiA8cD4KKyAgICAgKgorICAgICAqIElmIHRoZSBkZXNjcmlwdGlvbiBjb250YWlucyBub24gVVMtQVNDSUkgY2hhcmFjdGVycywgaXQgd2lsbCAKKyAgICAgKiBiZSBlbmNvZGVkIHVzaW5nIHRoZSBzcGVjaWZpZWQgY2hhcnNldC4gSWYgdGhlIGRlc2NyaXB0aW9uIAorICAgICAqIGNvbnRhaW5zIG9ubHkgVVMtQVNDSUkgY2hhcmFjdGVycywgbm8gZW5jb2RpbmcgIGlzIGRvbmUgYW5kIAorICAgICAqIGl0IGlzIHVzZWQgYXMtaXMKKyAgICAgKiAKKyAgICAgKiBAcGFyYW0JZGVzY3JpcHRpb24JRGVzY3JpcHRpb24KKyAgICAgKiBAcGFyYW0JY2hhcnNldAkJQ2hhcnNldCBmb3IgZW5jb2RpbmcKKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxXcml0ZUV4Y2VwdGlvbiBpZiB0aGUgdW5kZXJseWluZworICAgICAqCQkJaW1wbGVtZW50YXRpb24gZG9lcyBub3Qgc3VwcG9ydCBtb2RpZmljYXRpb24KKyAgICAgKiBAZXhjZXB0aW9uCUlsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIEJvZHlQYXJ0IGlzCisgICAgICoJCQlvYnRhaW5lZCBmcm9tIGEgUkVBRF9PTkxZIGZvbGRlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXREZXNjcmlwdGlvbihTdHJpbmcgZGVzY3JpcHRpb24sIFN0cmluZyBjaGFyc2V0KSAKKwkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJdGhyb3cgbmV3IE1ldGhvZE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigiU3VuVjNCb2R5UGFydCBub3Qgd3JpdGFibGUiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGZpbGVuYW1lIGFzc29jaWF0ZWQgd2l0aCB0aGlzIEJvZHlQYXJ0LiA8cD4KKyAgICAgKgorICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIHRoZSAiZmlsZW5hbWUiIHBhcmFtZXRlciBmcm9tIHRoZQorICAgICAqICJDb250ZW50LURpc3Bvc2l0aW9uIiBoZWFkZXIgZmllbGQgb2YgdGhpcyBCb2R5UGFydC4gSWYgaXRzCisgICAgICogbm90IGF2YWlsYWJsZSwgcmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlICJuYW1lIiBwYXJhbWV0ZXIgZnJvbQorICAgICAqIHRoZSAiQ29udGVudC1UeXBlIiBoZWFkZXIgZmllbGQgb2YgdGhpcyBCb2R5UGFydC4KKyAgICAgKiBSZXR1cm5zIDxjb2RlPm51bGw8L2NvZGU+IGlmIGJvdGggYXJlIGFic2VudC4KKyAgICAgKgorICAgICAqIEByZXR1cm4JZmlsZW5hbWUKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEZpbGVOYW1lKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJU3RyaW5nIG5hbWUgPSBzdXBlci5nZXRGaWxlTmFtZSgpOworCWlmIChuYW1lID09IG51bGwpCisJICAgIG5hbWUgPSBnZXRIZWFkZXIoIlgtU3VuLURhdGEtTmFtZSIsIG51bGwpOworCXJldHVybiBuYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgZmlsZW5hbWUgYXNzb2NpYXRlZCB3aXRoIHRoaXMgQm9keVBhcnQsIGlmIHBvc3NpYmxlLiA8cD4KKyAgICAgKgorICAgICAqIFNldHMgdGhlICJmaWxlbmFtZSIgcGFyYW1ldGVyIG9mIHRoZSAiQ29udGVudC1EaXNwb3NpdGlvbiIKKyAgICAgKiBoZWFkZXIgZmllbGQgb2YgdGhpcyBCb2R5UGFydC4KKyAgICAgKgorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFdyaXRlRXhjZXB0aW9uIGlmIHRoZSB1bmRlcmx5aW5nCisgICAgICoJCQlpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IG1vZGlmaWNhdGlvbgorICAgICAqIEBleGNlcHRpb24JSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgQm9keVBhcnQgaXMKKyAgICAgKgkJCW9idGFpbmVkIGZyb20gYSBSRUFEX09OTFkgZm9sZGVyLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEZpbGVOYW1lKFN0cmluZyBmaWxlbmFtZSkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJdGhyb3cgbmV3IE1ldGhvZE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigiU3VuVjNCb2R5UGFydCBub3Qgd3JpdGFibGUiKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBwcm92aWRlcyB0aGUgbWVjaGFuaXNtIHRvIHNldCB0aGlzIEJvZHlQYXJ0J3MgY29udGVudC4KKyAgICAgKiBUaGUgZ2l2ZW4gRGF0YUhhbmRsZXIgb2JqZWN0IHNob3VsZCB3cmFwIHRoZSBhY3R1YWwgY29udGVudC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gICBkaCAgICAgIFRoZSBEYXRhSGFuZGxlciBmb3IgdGhlIGNvbnRlbnQKKyAgICAgKiBAZXhjZXB0aW9uICAgICAgIElsbGVnYWxXcml0ZUV4Y2VwdGlvbiBpZiB0aGUgdW5kZXJseWluZworICAgICAqIAkJCWltcGxlbWVudGF0aW9uIGRvZXMgbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uCisgICAgICogQGV4Y2VwdGlvbglJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBCb2R5UGFydCBpcworICAgICAqCQkJb2J0YWluZWQgZnJvbSBhIFJFQURfT05MWSBmb2xkZXIuCisgICAgICovICAgICAgICAgICAgICAgICAKKyAgICBwdWJsaWMgdm9pZCBzZXREYXRhSGFuZGxlcihEYXRhSGFuZGxlciBkaCkgCisJCXRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXRocm93IG5ldyBNZXRob2ROb3RTdXBwb3J0ZWRFeGNlcHRpb24oIlN1blYzQm9keVBhcnQgbm90IHdyaXRhYmxlIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogT3V0cHV0IHRoZSBCb2R5UGFydCBhcyBhIFJGQzgyMiBmb3JtYXQgc3RyZWFtLgorICAgICAqCisgICAgICogQGV4Y2VwdGlvbiBNZXNzYWdpbmdFeGNlcHRpb24KKyAgICAgKiBAZXhjZXB0aW9uIElPRXhjZXB0aW9uCWlmIGFuIGVycm9yIG9jY3VycyB3cml0aW5nIHRvIHRoZQorICAgICAqCQkJCXN0cmVhbSBvciBpZiBhbiBlcnJvciBpcyBnZW5lcmF0ZWQKKyAgICAgKgkJCQlieSB0aGUgamF2YXguYWN0aXZhdGlvbiBsYXllci4KKyAgICAgKiBAc2VlIGphdmF4LmFjdGl2YXRpb24uRGF0YUhhbmRsZXIjd3JpdGVUbygpCisgICAgICovCisgICAgcHVibGljIHZvaWQgd3JpdGVUbyhPdXRwdXRTdHJlYW0gb3MpCisJCQkJdGhyb3dzIElPRXhjZXB0aW9uLCBNZXNzYWdpbmdFeGNlcHRpb24geworCXRocm93IG5ldyBNZXRob2ROb3RTdXBwb3J0ZWRFeGNlcHRpb24oIlN1blYzQm9keVBhcnQgd3JpdGVUbyIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgaXMgdGhlIG1ldGhvZCB0aGF0IGhhcyB0aGUgJ3NtYXJ0cycgdG8gcXVlcnkgdGhlICdjb250ZW50JworICAgICAqIGFuZCB1cGRhdGUgdGhlIGFwcHJvcHJpYXRlIGhlYWRlcnMuIFR5cGljYWwgaGVhZGVycyB0aGF0IGdldAorICAgICAqIHNldCBoZXJlIGFyZTogQ29udGVudC1UeXBlLCBDb250ZW50LUVuY29kaW5nLCBib3VuZGFyeSAoZm9yCisgICAgICogbXVsdGlwYXJ0KS4gTm93LCB0aGUgdHJpY2t5IHBhcnQgaGVyZSBpcyB3aGVuIHRvIGFjdHVhbGx5CisgICAgICogYWN0aXZhdGUgdGhpcyBtZXRob2Q6CisgICAgICoKKyAgICAgKiAtIEEgTWVzc2FnZSBiZWluZyBjcmFmdGVkIGJ5IGEgbWFpbC1hcHBsaWNhdGlvbiB3aWxsIGNlcnRhaW5seQorICAgICAqIG5lZWQgdG8gYWN0aXZhdGUgdGhpcyBtZXRob2QgYXQgc29tZSBwb2ludCB0byBmaWxsIHVwIGl0cyBpbnRlcm5hbAorICAgICAqIGhlYWRlcnMuIFR5cGljYWxseSB0aGlzIGlzIHRyaWdnZXJlZCBvZmYgYnkgb3VyIHdyaXRlVG8oKSBtZXRob2QuCisgICAgICoKKyAgICAgKiAtIEEgbWVzc2FnZSByZWFkLWluIGZyb20gYSBNZXNzYWdlU3RvcmUgd2lsbCBoYXZlIG9idGFpbmVkCisgICAgICogYWxsIGl0cyBoZWFkZXJzIGZyb20gdGhlIHN0b3JlLCBhbmQgc28gZG9lcydudCBuZWVkIHRoaXMuCisgICAgICogSG93ZXZlciwgaWYgdGhpcyBtZXNzYWdlIGlzIGVkaXRhYmxlIGFuZCBpZiBhbnkgZWRpdHMgaGF2ZQorICAgICAqIGJlZW4gbWFkZSB0byBlaXRoZXIgdGhlIGNvbnRlbnQgb3IgbWVzc2FnZS1zdHJ1Y3R1cmUsIHdlIG1pZ2h0CisgICAgICogbmVlZCB0byByZXN5bmMgb3VyIGhlYWRlcnMuIFR5cGljYWxseSB0aGlzIGlzIHRyaWdnZXJlZCBvZmYgYnkKKyAgICAgKiB0aGUgTWVzc2FnZS5zYXZlQ2hhbmdlcygpIG1ldGhvZHMuCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgdXBkYXRlSGVhZGVycygpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXRocm93IG5ldyBNZXRob2ROb3RTdXBwb3J0ZWRFeGNlcHRpb24oIlN1blYzQm9keVBhcnQgdXBkYXRlSGVhZGVycyIpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21ib3gvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvbWJveC9TdW5WM011bHRpcGFydC5qYXZhIGIvbWJveC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9tYm94L1N1blYzTXVsdGlwYXJ0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGE2NDJmMQotLS0gL2Rldi9udWxsCisrKyBiL21ib3gvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvbWJveC9TdW5WM011bHRpcGFydC5qYXZhCkBAIC0wLDAgKzEsMjAxIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5tYm94OworCitpbXBvcnQgamF2YXgubWFpbC4qOworaW1wb3J0IGphdmF4Lm1haWwuaW50ZXJuZXQuKjsKK2ltcG9ydCBqYXZheC5hY3RpdmF0aW9uLio7CitpbXBvcnQgamF2YS51dGlsLio7CitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuU3RhbmRhcmRDaGFyc2V0czsKK2ltcG9ydCBjb20uc3VuLm1haWwudXRpbC5MaW5lSW5wdXRTdHJlYW07CisKKy8qKgorICogVGhlIFN1blYzTXVsdGlwYXJ0IGNsYXNzIGlzIGFuIGltcGxlbWVudGF0aW9uIG9mIHRoZSBhYnN0cmFjdCBNdWx0aXBhcnQKKyAqIGNsYXNzIHRoYXQgdXNlcyBTdW5WMyBjb252ZW50aW9ucyBmb3IgdGhlIG11bHRpcGFydCBkYXRhLiA8cD4KKyAqCisgKiBAYXV0aG9yICBCaWxsIFNoYW5ub24KKyAqLworCitwdWJsaWMgY2xhc3MgU3VuVjNNdWx0aXBhcnQgZXh0ZW5kcyBNaW1lTXVsdGlwYXJ0IHsKKyAgICBwcml2YXRlIGJvb2xlYW4gcGFyc2luZzsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSBTdW5WM011bHRpcGFydCBvYmplY3QgYW5kIGl0cyBib2R5cGFydHMgZnJvbSB0aGUgCisgICAgICogZ2l2ZW4gRGF0YVNvdXJjZS4gPHA+CisgICAgICoKKyAgICAgKiBAcGFyYW0JZHMJRGF0YVNvdXJjZSwgY2FuIGJlIGEgTXVsdGlwYXJ0RGF0YVNvdXJjZQorICAgICAqLworICAgIHB1YmxpYyBTdW5WM011bHRpcGFydChEYXRhU291cmNlIGRzKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlzdXBlcihkcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0IHRoZSBzdWJ0eXBlLiAgVGhyb3dzIE1ldGhvZE5vdFN1cHBvcnRlZEV4Y2VwdGlvbi4KKyAgICAgKgorICAgICAqIEBwYXJhbQlzdWJ0eXBlCQlTdWJ0eXBlCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U3ViVHlwZShTdHJpbmcgc3VidHlwZSkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJdGhyb3cgbmV3IE1ldGhvZE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigKKwkJImNhbid0IGNoYW5nZSBTdW5WM011bHRpcGFydCBzdWJ0eXBlIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogR2V0IHRoZSBCb2R5UGFydCByZWZlcnJlZCB0byBieSB0aGUgZ2l2ZW4gQ29udGVudElEIChDSUQpLiAKKyAgICAgKiBUaHJvd3MgTWV0aG9kTm90U3VwcG9ydEV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIEJvZHlQYXJ0IGdldEJvZHlQYXJ0KFN0cmluZyBDSUQpIAorCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJdGhyb3cgbmV3IE1ldGhvZE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigKKwkJIlN1blYzTXVsdGlwYXJ0IGRvZXNuJ3Qgc3VwcG9ydCBDb250ZW50LUlEIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogVXBkYXRlIGhlYWRlcnMuICBUaHJvd3MgTWV0aG9kTm90U3VwcG9ydEV4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCB1cGRhdGVIZWFkZXJzKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJdGhyb3cgbmV3IE1ldGhvZE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigiU3VuVjNNdWx0aXBhcnQgbm90IHdyaXRhYmxlIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogSXRlcmF0ZXMgdGhyb3VnaCBhbGwgdGhlIHBhcnRzIGFuZCBvdXRwdXRzIGVhY2ggU3VuVjMgcGFydAorICAgICAqIHNlcGFyYXRlZCBieSBhIGJvdW5kYXJ5LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oT3V0cHV0U3RyZWFtIG9zKQorCQkJCXRocm93cyBJT0V4Y2VwdGlvbiwgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwl0aHJvdyBuZXcgTWV0aG9kTm90U3VwcG9ydGVkRXhjZXB0aW9uKAorCQkiU3VuVjNNdWx0aXBhcnQgd3JpdGVUbyBub3Qgc3VwcG9ydGVkIik7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIGJvdW5kYXJ5ID0gIi0tLS0tLS0tLS0iOworCisgICAgLyoKKyAgICAgKiBQYXJzZSB0aGUgY29udGVudHMgb2YgdGhpcyBtdWx0aXBhcnQgbWVzc2FnZSBhbmQgY3JlYXRlIHRoZQorICAgICAqIGNoaWxkIGJvZHkgcGFydHMuCisgICAgICovCisgICAgcHJvdGVjdGVkIHN5bmNocm9uaXplZCB2b2lkIHBhcnNlKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJLyoKKwkgKiBJZiB0aGUgZGF0YSBoYXMgYWxyZWFkeSBiZWVuIHBhcnNlZCwgb3Igd2UncmUgaW4gdGhlIG1pZGRsZSBvZgorCSAqIHBhcnNpbmcgaXQsIHRoZXJlJ3Mgbm90aGluZyB0byBkby4gIFRoZSBsYXR0ZXIgd2lsbCBvY2N1ciB3aGVuCisJICogd2UgY2FsbCBhZGRCb2R5UGFydCwgd2hpY2ggd2lsbCBjYWxsIHBhcnNlIGFnYWluLiAgV2UgcmVhbGx5CisJICogd2FudCB0byBiZSBhYmxlIHRvIGNhbGwgc3VwZXIuc3VwZXIuYWRkQm9keVBhcnQuCisJICovCisJaWYgKHBhcnNlZCB8fCBwYXJzaW5nKQorCSAgICByZXR1cm47CisKKwlJbnB1dFN0cmVhbSBpbiA9IG51bGw7CisKKwl0cnkgeworCSAgICBpbiA9IGRzLmdldElucHV0U3RyZWFtKCk7CisJICAgIGlmICghKGluIGluc3RhbmNlb2YgQnl0ZUFycmF5SW5wdXRTdHJlYW0pICYmCisJCSEoaW4gaW5zdGFuY2VvZiBCdWZmZXJlZElucHV0U3RyZWFtKSkKKwkJaW4gPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShpbik7CisJfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiTm8gaW5wdXRzdHJlYW0gZnJvbSBkYXRhc291cmNlIik7CisJfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBleCkgeworCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKCJObyBpbnB1dHN0cmVhbSBmcm9tIGRhdGFzb3VyY2UiKTsKKwl9CisKKwlieXRlW10gYm5kYnl0ZXMgPSBib3VuZGFyeS5nZXRCeXRlcyhTdGFuZGFyZENoYXJzZXRzLklTT184ODU5XzEpOworCWludCBibCA9IGJuZGJ5dGVzLmxlbmd0aDsKKworCVN0cmluZyBsaW5lOworCXBhcnNpbmcgPSB0cnVlOworCXRyeSB7CisJICAgIC8qCisJICAgICAqIFNraXAgYW55IGtpbmQgb2YganVuayB1bnRpbCB3ZSBnZXQgdG8gdGhlIGZpcnN0CisJICAgICAqIGJvdW5kYXJ5IGxpbmUuCisJICAgICAqLworCSAgICBMaW5lSW5wdXRTdHJlYW0gbGluID0gbmV3IExpbmVJbnB1dFN0cmVhbShpbik7CisJICAgIHdoaWxlICgobGluZSA9IGxpbi5yZWFkTGluZSgpKSAhPSBudWxsKSB7CisJCWlmIChsaW5lLnRyaW0oKS5lcXVhbHMoYm91bmRhcnkpKQorCQkgICAgYnJlYWs7CisJICAgIH0KKwkgICAgaWYgKGxpbmUgPT0gbnVsbCkKKwkJdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiTWlzc2luZyBzdGFydCBib3VuZGFyeSIpOworCisJICAgIC8qCisJICAgICAqIFJlYWQgYW5kIHByb2Nlc3MgYm9keSBwYXJ0cyB1bnRpbCB3ZSBzZWUgdGhlCisJICAgICAqIHRlcm1pbmF0aW5nIGJvdW5kYXJ5IGxpbmUgKG9yIEVPRikuCisJICAgICAqLworCSAgICBmb3IgKDs7KSB7CisJCS8qCisJCSAqIENvbGxlY3QgdGhlIGhlYWRlcnMgZm9yIHRoaXMgYm9keSBwYXJ0LgorCQkgKi8KKwkJSW50ZXJuZXRIZWFkZXJzIGhlYWRlcnMgPSBuZXcgSW50ZXJuZXRIZWFkZXJzKGluKTsKKworCQlpZiAoIWluLm1hcmtTdXBwb3J0ZWQoKSkKKwkJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oIlN0cmVhbSBkb2Vzbid0IHN1cHBvcnQgbWFyayIpOworCisJCUJ5dGVBcnJheU91dHB1dFN0cmVhbSBidWYgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisJCWludCBiOworCisJCS8qCisJCSAqIFJlYWQgYW5kIHNhdmUgdGhlIGNvbnRlbnQgYnl0ZXMgaW4gYnVmLgorCQkgKi8KKwkJd2hpbGUgKChiID0gaW4ucmVhZCgpKSA+PSAwKSB7CisJCSAgICBpZiAoYiA9PSAnXHInIHx8IGIgPT0gJ1xuJykgeworCQkJLyoKKwkJCSAqIEZvdW5kIHRoZSBlbmQgb2YgYSBsaW5lLCBjaGVjayB3aGV0aGVyIHRoZQorCQkJICogbmV4dCBsaW5lIGlzIGEgYm91bmRhcnkuCisJCQkgKi8KKwkJCWludCBpOworCQkJaW4ubWFyayhibCArIDQgKyAxKTsJLy8gIjQiIGZvciBwb3NzaWJsZSAiLS1cclxuIgorCQkJaWYgKGIgPT0gJ1xyJyAmJiBpbi5yZWFkKCkgIT0gJ1xuJykgeworCQkJICAgIGluLnJlc2V0KCk7CisJCQkgICAgaW4ubWFyayhibCArIDQpOworCQkJfQorCQkJLy8gcmVhZCBieXRlcywgbWF0Y2hpbmcgYWdhaW5zdCB0aGUgYm91bmRhcnkKKwkJCWZvciAoaSA9IDA7IGkgPCBibDsgaSsrKQorCQkJICAgIGlmIChpbi5yZWFkKCkgIT0gYm5kYnl0ZXNbaV0pCisJCQkJYnJlYWs7CisJCQlpZiAoaSA9PSBibCkgeworCQkJICAgIGludCBiMiA9IGluLnJlYWQoKTsKKwkJCSAgICAvLyBjaGVjayBmb3IgZW5kIG9mIGxpbmUKKwkJCSAgICBpZiAoYjIgPT0gJ1xuJykKKwkJCQlicmVhazsJLy8gZ290IGl0ISAgYnJlYWsgb3V0IG9mIHRoZSB3aGlsZSBsb29wCisJCQkgICAgaWYgKGIyID09ICdccicpIHsKKwkJCQlpbi5tYXJrKDEpOworCQkJCWlmIChpbi5yZWFkKCkgIT0gJ1xuJykKKwkJCQkgICAgaW4ucmVzZXQoKTsKKwkJCQlicmVhazsJLy8gZ290IGl0ISAgYnJlYWsgb3V0IG9mIHRoZSB3aGlsZSBsb29wCisJCQkgICAgfQorCQkJfQorCQkJLy8gZmFpbGVkIHRvIG1hdGNoLCByZXNldCBhbmQgcHJvY2VlZCBub3JtYWxseQorCQkJaW4ucmVzZXQoKTsKKwkJICAgIH0KKwkJICAgIGJ1Zi53cml0ZShiKTsKKwkJfQorCisJCS8qCisJCSAqIENyZWF0ZSBhIFN1blYzQm9keVBhcnQgdG8gcmVwcmVzZW50IHRoaXMgYm9keSBwYXJ0LgorCQkgKi8KKwkJU3VuVjNCb2R5UGFydCBib2R5ID0KKwkJCW5ldyBTdW5WM0JvZHlQYXJ0KGhlYWRlcnMsIGJ1Zi50b0J5dGVBcnJheSgpKTsKKwkJYWRkQm9keVBhcnQoYm9keSk7CisJCWlmIChiIDwgMCkKKwkJICAgIGJyZWFrOworCSAgICB9CisJfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKCJJTyBFcnJvciIpOwkvLyBYWFgKKwl9IGZpbmFsbHkgeworCSAgICBwYXJzaW5nID0gZmFsc2U7CisJfQorCisJcGFyc2VkID0gdHJ1ZTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYm94L3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL21ib3gvVGVtcEZpbGUuamF2YSBiL21ib3gvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvbWJveC9UZW1wRmlsZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI1ZjRiZDgKLS0tIC9kZXYvbnVsbAorKysgYi9tYm94L3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL21ib3gvVGVtcEZpbGUuamF2YQpAQCAtMCwwICsxLDE4MyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAxMCwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwubWJveDsKKworaW1wb3J0IGphdmEudXRpbC4qOworaW1wb3J0IGphdmEubmV0Lio7CitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmEuc2VjdXJpdHkuKjsKKworaW1wb3J0IGNvbS5zdW4ubWFpbC51dGlsLlByb3BVdGlsOworaW1wb3J0IGphdmF4Lm1haWwudXRpbC5TaGFyZWRGaWxlSW5wdXRTdHJlYW07CisKKy8qKgorICogQSB0ZW1wb3JhcnkgZmlsZSB1c2VkIHRvIGNhY2hlIG1lc3NhZ2VzLgorICovCitjbGFzcyBUZW1wRmlsZSB7CisKKyAgICBwcml2YXRlIEZpbGUgZmlsZTsJLy8gdGhlIHRlbXAgZmlsZSBuYW1lCisgICAgcHJpdmF0ZSBXcml0YWJsZVNoYXJlZEZpbGUgc2Y7CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSB0ZW1wIGZpbGUgaW4gdGhlIHNwZWNpZmllZCBkaXJlY3RvcnkgKGlmIG5vdCBudWxsKS4KKyAgICAgKiBUaGUgZmlsZSB3aWxsIGJlIGRlbGV0ZWQgd2hlbiB0aGUgSlZNIGV4aXRzLgorICAgICAqLworICAgIHB1YmxpYyBUZW1wRmlsZShGaWxlIGRpcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlmaWxlID0gRmlsZS5jcmVhdGVUZW1wRmlsZSgibWJveC4iLCAiLm1ib3giLCBkaXIpOworCS8vIFhYWCAtIG5lZWQgSkRLIDYgdG8gc2V0IHBlcm1pc3Npb25zIG9uIHRoZSBmaWxlIHRvIG93bmVyLW9ubHkKKwlmaWxlLmRlbGV0ZU9uRXhpdCgpOworCXNmID0gbmV3IFdyaXRhYmxlU2hhcmVkRmlsZShmaWxlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYSBzdHJlYW0gZm9yIGFwcGVuZGluZyB0byB0aGUgdGVtcCBmaWxlLgorICAgICAqLworICAgIHB1YmxpYyBBcHBlbmRTdHJlYW0gZ2V0QXBwZW5kU3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlyZXR1cm4gc2YuZ2V0QXBwZW5kU3RyZWFtKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIGEgc3RyZWFtIGZvciByZWFkaW5nIGZyb20gcGFydCBvZiB0aGUgZmlsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgSW5wdXRTdHJlYW0gbmV3U3RyZWFtKGxvbmcgc3RhcnQsIGxvbmcgZW5kKSB7CisJcmV0dXJuIHNmLm5ld1N0cmVhbShzdGFydCwgZW5kKTsKKyAgICB9CisKKyAgICBwdWJsaWMgbG9uZyBsZW5ndGgoKSB7CisJcmV0dXJuIGZpbGUubGVuZ3RoKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvc2UgYW5kIHJlbW92ZSB0aGlzIHRlbXAgZmlsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHsKKwl0cnkgeworCSAgICBzZi5jbG9zZSgpOworCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisJICAgIC8vIGlnbm9yZSBpdAorCX0KKwlmaWxlLmRlbGV0ZSgpOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIGZpbmFsaXplKCkgdGhyb3dzIFRocm93YWJsZSB7CisJdHJ5IHsKKwkgICAgY2xvc2UoKTsKKwl9IGZpbmFsbHkgeworCSAgICBzdXBlci5maW5hbGl6ZSgpOworCX0KKyAgICB9Cit9CisKKy8qKgorICogQSBzdWJjbGFzcyBvZiBTaGFyZWRGaWxlSW5wdXRTdHJlYW0gdGhhdCBhbHNvIGFsbG93cyB3cml0aW5nLgorICovCitjbGFzcyBXcml0YWJsZVNoYXJlZEZpbGUgZXh0ZW5kcyBTaGFyZWRGaWxlSW5wdXRTdHJlYW0geworICAgIHByaXZhdGUgUmFuZG9tQWNjZXNzRmlsZSByYWY7CisgICAgcHJpdmF0ZSBBcHBlbmRTdHJlYW0gYWY7CisKKyAgICBwdWJsaWMgV3JpdGFibGVTaGFyZWRGaWxlKEZpbGUgZmlsZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlzdXBlcihmaWxlKTsKKwl0cnkgeworCSAgICByYWYgPSBuZXcgUmFuZG9tQWNjZXNzRmlsZShmaWxlLCAicnciKTsKKwl9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworCSAgICAvLyBpZiBhbnl0aGluZyBnb2VzIHdyb25nIG9wZW5pbmcgdGhlIHdyaXRhYmxlIGZpbGUsCisJICAgIC8vIGNsb3NlIHRoZSByZWFkYWJsZSBmaWxlIHRvbworCSAgICBzdXBlci5jbG9zZSgpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIHdyaXRhYmxlIHZlcnNpb24gb2YgdGhpcyBmaWxlLgorICAgICAqLworICAgIHB1YmxpYyBSYW5kb21BY2Nlc3NGaWxlIGdldFdyaXRhYmxlRmlsZSgpIHsKKwlyZXR1cm4gcmFmOworICAgIH0KKworICAgIC8qKgorICAgICAqIENsb3NlIHRoZSByZWFkYWJsZSBhbmQgd3JpdGFibGUgZmlsZXMuCisgICAgICovCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCXRyeSB7CisJICAgIHN1cGVyLmNsb3NlKCk7CisJfSBmaW5hbGx5IHsKKwkgICAgcmFmLmNsb3NlKCk7CisJfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFVwZGF0ZSB0aGUgc2l6ZSBvZiB0aGUgcmVhZGFibGUgZmlsZSBhZnRlciB3cml0aW5nCisgICAgICogdG8gdGhlIGZpbGUuICBVcGRhdGVzIHRoZSBsZW5ndGggdG8gYmUgdGhlIGN1cnJlbnQKKyAgICAgKiBzaXplIG9mIHRoZSBmaWxlLgorICAgICAqLworICAgIHN5bmNocm9uaXplZCBsb25nIHVwZGF0ZUxlbmd0aCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJZGF0YWxlbiA9IGluLmxlbmd0aCgpOworCWFmID0gbnVsbDsKKwlyZXR1cm4gZGF0YWxlbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYSBuZXcgQXBwZW5kU3RyZWFtLCBidXQgb25seSBpZiBvbmUgaXNuJ3QgaW4gYWN0aXZlIHVzZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIEFwcGVuZFN0cmVhbSBnZXRBcHBlbmRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworCWlmIChhZiAhPSBudWxsKQorCSAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oCisJCSJmaWxlIGNhY2hlIG9ubHkgc3VwcG9ydHMgc2luZ2xlIHRocmVhZGVkIGFjY2VzcyIpOworCWFmID0gbmV3IEFwcGVuZFN0cmVhbSh0aGlzKTsKKwlyZXR1cm4gYWY7CisgICAgfQorfQorCisvKioKKyAqIEEgc3RyZWFtIGZvciB3cml0aW5nIHRvIHRoZSB0ZW1wIGZpbGUsIGFuZCB3aGVuIGRvbmUKKyAqIGNhbiByZXR1cm4gYSBzdHJlYW0gZm9yIHJlYWRpbmcgdGhlIGRhdGEganVzdCB3cml0dGVuLgorICogTk9URTogV2UgYXNzdW1lIHRoYXQgb25seSBvbmUgdGhyZWFkIGlzIHdyaXRpbmcgdG8gdGhlCisgKiBmaWxlIGF0IGEgdGltZS4KKyAqLworY2xhc3MgQXBwZW5kU3RyZWFtIGV4dGVuZHMgT3V0cHV0U3RyZWFtIHsKKyAgICBwcml2YXRlIGZpbmFsIFdyaXRhYmxlU2hhcmVkRmlsZSB0ZjsKKyAgICBwcml2YXRlIFJhbmRvbUFjY2Vzc0ZpbGUgcmFmOworICAgIHByaXZhdGUgZmluYWwgbG9uZyBzdGFydDsKKyAgICBwcml2YXRlIGxvbmcgZW5kOworCisgICAgcHVibGljIEFwcGVuZFN0cmVhbShXcml0YWJsZVNoYXJlZEZpbGUgdGYpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJdGhpcy50ZiA9IHRmOworCXJhZiA9IHRmLmdldFdyaXRhYmxlRmlsZSgpOworCXN0YXJ0ID0gcmFmLmxlbmd0aCgpOworCXJhZi5zZWVrKHN0YXJ0KTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShpbnQgYikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwlyYWYud3JpdGUoYik7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGUoYnl0ZVtdIGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJcmFmLndyaXRlKGIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworCXJhZi53cml0ZShiLCBvZmYsIGxlbik7CisgICAgfQorCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKwllbmQgPSB0Zi51cGRhdGVMZW5ndGgoKTsKKwlyYWYgPSBudWxsOwkvLyBubyBtb3JlIHdyaXRpbmcgYWxsb3dlZAorICAgIH0KKworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgSW5wdXRTdHJlYW0gZ2V0SW5wdXRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworCXJldHVybiB0Zi5uZXdTdHJlYW0oc3RhcnQsIGVuZCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWJveC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9tYm94L1VOSVhGaWxlLmphdmEgYi9tYm94L3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL21ib3gvVU5JWEZpbGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hYjE1NzllCi0tLSAvZGV2L251bGwKKysrIGIvbWJveC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9tYm94L1VOSVhGaWxlLmphdmEKQEAgLTAsMCArMSwxMzIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLm1ib3g7CisKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlRGVzY3JpcHRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuU3RyaW5nVG9rZW5pemVyOworCitwdWJsaWMgY2xhc3MgVU5JWEZpbGUgZXh0ZW5kcyBGaWxlIHsKKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGJvb2xlYW4gbG9hZGVkOworICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IGxvY2tUeXBlOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTc5NzIxNTYzMTUyODQxNDY2NTFMOworCisgICAgcHVibGljIFVOSVhGaWxlKFN0cmluZyBuYW1lKSB7CisJc3VwZXIobmFtZSk7CisgICAgfQorCisgICAgLy8gbG9jayB0eXBlIGVudW0KKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBOT05FID0gMDsKKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBOQVRJVkUgPSAxOworICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IEpBVkEgPSAyOworCisgICAgc3RhdGljIHsKKwlTdHJpbmcgbHQgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoIm1haWwubWJveC5sb2NrdHlwZSIsICJuYXRpdmUiKTsKKwlpbnQgdHlwZSA9IE5BVElWRTsKKwlpZiAobHQuZXF1YWxzSWdub3JlQ2FzZSgibm9uZSIpKQorCSAgICB0eXBlID0gTk9ORTsKKwllbHNlIGlmIChsdC5lcXVhbHNJZ25vcmVDYXNlKCJqYXZhIikpCisJICAgIHR5cGUgPSBKQVZBOworCWxvY2tUeXBlID0gdHlwZTsKKworCWJvb2xlYW4gbGxvYWRlZCA9IGZhbHNlOworCWlmIChsb2NrVHlwZSA9PSBOQVRJVkUpIHsKKwkgICAgdHJ5IHsKKwkJU3lzdGVtLmxvYWRMaWJyYXJ5KCJtYm94Iik7CisJCWxsb2FkZWQgPSB0cnVlOworCSAgICB9IGNhdGNoIChVbnNhdGlzZmllZExpbmtFcnJvciBlKSB7CisJCVN0cmluZyBjbGFzc3BhdGggPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImphdmEuY2xhc3MucGF0aCIpOworCQlTdHJpbmcgc2VwID0gU3lzdGVtLmdldFByb3BlcnR5KCJwYXRoLnNlcGFyYXRvciIpOworCQlTdHJpbmcgYXJjaCA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgib3MuYXJjaCIpOworCQlTdHJpbmdUb2tlbml6ZXIgc3QgPSBuZXcgU3RyaW5nVG9rZW5pemVyKGNsYXNzcGF0aCwgc2VwKTsKKwkJd2hpbGUgKHN0Lmhhc01vcmVUb2tlbnMoKSkgeworCQkgICAgU3RyaW5nIHBhdGggPSBzdC5uZXh0VG9rZW4oKTsKKwkJICAgIGlmIChwYXRoLmVuZHNXaXRoKCIvY2xhc3NlcyIpIHx8CisJCQkgICAgcGF0aC5lbmRzV2l0aCgiL21haWwuamFyIikgfHwKKwkJCSAgICBwYXRoLmVuZHNXaXRoKCIvamF2YXgubWFpbC5qYXIiKSkgeworCQkJaW50IGkgPSBwYXRoLmxhc3RJbmRleE9mKCcvJyk7CisJCQlTdHJpbmcgbGliZGlyID0gcGF0aC5zdWJzdHJpbmcoMCwgaSArIDEpICsgImxpYi8iOworCQkJU3RyaW5nIGxpYiA9IGxpYmRpciArIGFyY2ggKyAiL2xpYm1ib3guc28iOworCQkJdHJ5IHsKKwkJCSAgICBTeXN0ZW0ubG9hZChsaWIpOworCQkJICAgIGxsb2FkZWQgPSB0cnVlOworCQkJICAgIGJyZWFrOworCQkJfSBjYXRjaCAoVW5zYXRpc2ZpZWRMaW5rRXJyb3IgZTIpIHsKKwkJCSAgICBsaWIgPSBsaWJkaXIgKyAibGlibWJveC5zbyI7CisJCQkgICAgdHJ5IHsKKwkJCQlTeXN0ZW0ubG9hZChsaWIpOworCQkJCWxsb2FkZWQgPSB0cnVlOworCQkJCWJyZWFrOworCQkJICAgIH0gY2F0Y2ggKFVuc2F0aXNmaWVkTGlua0Vycm9yIGUzKSB7CisJCQkJY29udGludWU7CisJCQkgICAgfQorCQkJfQorCQkgICAgfQorCQl9CisJICAgIH0KKwl9CisJbG9hZGVkID0gbGxvYWRlZDsKKwlpZiAobG9hZGVkKQorCSAgICBpbml0SURzKEZpbGVEZXNjcmlwdG9yLmNsYXNzLCBGaWxlRGVzY3JpcHRvci5pbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBhY2Nlc3MgdGltZSBvZiB0aGUgZmlsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGxvbmcgbGFzdEFjY2Vzc2VkKEZpbGUgZmlsZSkgeworCXJldHVybiBsYXN0QWNjZXNzZWQwKGZpbGUuZ2V0UGF0aCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgbG9uZyBsYXN0QWNjZXNzZWQoKSB7CisJcmV0dXJuIGxhc3RBY2Nlc3NlZDAoZ2V0UGF0aCgpKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBuYXRpdmUgdm9pZCBpbml0SURzKENsYXNzPEZpbGVEZXNjcmlwdG9yPiBmZENsYXNzLAorCQkJCQlGaWxlRGVzY3JpcHRvciBzdGRpbik7CisKKyAgICAvKioKKyAgICAgKiBMb2NrIHRoZSBmaWxlIHJlZmVycmVkIHRvIGJ5IGZkLiAgVGhlIHN0cmluZyBtb2RlIGlzICJyIgorICAgICAqIGZvciBhIHJlYWQgbG9jayBvciAicnciIGZvciBhIHdyaXRlIGxvY2suICBEb24ndCBibG9jaworICAgICAqIGlmIGxvY2sgY2FuJ3QgYmUgYWNxdWlyZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGxvY2soRmlsZURlc2NyaXB0b3IgZmQsIFN0cmluZyBtb2RlKSB7CisJcmV0dXJuIGxvY2soZmQsIG1vZGUsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBMb2NrIHRoZSBmaWxlIHJlZmVycmVkIHRvIGJ5IGZkLiAgVGhlIHN0cmluZyBtb2RlIGlzICJyIgorICAgICAqIGZvciBhIHJlYWQgbG9jayBvciAicnciIGZvciBhIHdyaXRlIGxvY2suICBJZiBibG9jayBpcyBzZXQsCisgICAgICogYmxvY2sgd2FpdGluZyBmb3IgdGhlIGxvY2sgaWYgbmVjZXNzYXJ5LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gbG9jayhGaWxlRGVzY3JpcHRvciBmZCwgU3RyaW5nIG1vZGUsIGJvb2xlYW4gYmxvY2spIHsKKwkvL3JldHVybiBsb2FkZWQgJiYgbG9jazAoZmQsIG1vZGUpOworCWlmIChsb2FkZWQpIHsKKwkgICAgYm9vbGVhbiByZXQ7CisJICAgIC8vU3lzdGVtLm91dC5wcmludGxuKCJVTklYRmlsZS5sb2NrKCIgKyBmZCArICIsICIgKyBtb2RlICsgIikiKTsKKwkgICAgcmV0ID0gbG9jazAoZmQsIG1vZGUsIGJsb2NrKTsKKwkgICAgLy9TeXN0ZW0ub3V0LnByaW50bG4oIlVOSVhGaWxlLmxvY2sgcmV0dXJucyAiICsgcmV0KTsKKwkgICAgcmV0dXJuIHJldDsKKwl9CisJcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIG5hdGl2ZSBib29sZWFuIGxvY2swKEZpbGVEZXNjcmlwdG9yIGZkLCBTdHJpbmcgbW9kZSwKKwkJCQkJCQkJYm9vbGVhbiBibG9jayk7CisKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBsb25nIGxhc3RBY2Nlc3NlZDAoU3RyaW5nIG5hbWUpOworfQpkaWZmIC0tZ2l0IGEvbWJveC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9tYm94L1VOSVhGb2xkZXIuamF2YSBiL21ib3gvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvbWJveC9VTklYRm9sZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTNkYzMwYQotLS0gL2Rldi9udWxsCisrKyBiL21ib3gvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvbWJveC9VTklYRm9sZGVyLmphdmEKQEAgLTAsMCArMSw3NCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwubWJveDsKKworaW1wb3J0IGphdmEuaW8uKjsKKworcHVibGljIGNsYXNzIFVOSVhGb2xkZXIgZXh0ZW5kcyBVTklYRmlsZSBpbXBsZW1lbnRzIE1haWxGaWxlIHsKKyAgICBwcm90ZWN0ZWQgdHJhbnNpZW50IFJhbmRvbUFjY2Vzc0ZpbGUgZmlsZTsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC0yNTQ1Nzg4OTEyNjM3ODU1OTFMOworCisgICAgcHVibGljIFVOSVhGb2xkZXIoU3RyaW5nIG5hbWUpIHsKKwlzdXBlcihuYW1lKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBsb2NrKFN0cmluZyBtb2RlKSB7CisJdHJ5IHsKKwkgICAgZmlsZSA9IG5ldyBSYW5kb21BY2Nlc3NGaWxlKHRoaXMsIG1vZGUpOworCSAgICBzd2l0Y2ggKGxvY2tUeXBlKSB7CisJICAgIGNhc2UgTk9ORToKKwkJcmV0dXJuIHRydWU7CisJICAgIGNhc2UgTkFUSVZFOgorCSAgICBkZWZhdWx0OgorCQlyZXR1cm4gVU5JWEZpbGUubG9jayhmaWxlLmdldEZEKCksIG1vZGUpOworCSAgICBjYXNlIEpBVkE6CisJCXJldHVybiBmaWxlLmdldENoYW5uZWwoKS4KKwkJICAgIHRyeUxvY2soMEwsIExvbmcuTUFYX1ZBTFVFLCAhbW9kZS5lcXVhbHMoInJ3IikpICE9IG51bGw7CisJICAgIH0KKwl9IGNhdGNoIChGaWxlTm90Rm91bmRFeGNlcHRpb24gZmUpIHsKKwkgICAgcmV0dXJuIGZhbHNlOworCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGllKSB7CisJICAgIGZpbGUgPSBudWxsOworCSAgICByZXR1cm4gZmFsc2U7CisJfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVubG9jaygpIHsgCisJaWYgKGZpbGUgIT0gbnVsbCkgeworCSAgICB0cnkgeworCQlmaWxlLmNsb3NlKCk7CisJICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKwkJLy8gaWdub3JlIGl0CisJICAgIH0KKwkgICAgZmlsZSA9IG51bGw7CisJfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHRvdWNobG9jaygpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgRmlsZURlc2NyaXB0b3IgZ2V0RkQoKSB7CisJaWYgKGZpbGUgPT0gbnVsbCkKKwkgICAgcmV0dXJuIG51bGw7CisJdHJ5IHsKKwkgICAgcmV0dXJuIGZpbGUuZ2V0RkQoKTsKKwl9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisJICAgIHJldHVybiBudWxsOworCX0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9tYm94L3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL21ib3gvVU5JWEluYm94LmphdmEgYi9tYm94L3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL21ib3gvVU5JWEluYm94LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzBjZTg2NQotLS0gL2Rldi9udWxsCisrKyBiL21ib3gvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvbWJveC9VTklYSW5ib3guamF2YQpAQCAtMCwwICsxLDEyMyBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwubWJveDsKKworaW1wb3J0IGphdmEuaW8uKjsKKworcHVibGljIGNsYXNzIFVOSVhJbmJveCBleHRlbmRzIFVOSVhGb2xkZXIgaW1wbGVtZW50cyBJbmJveEZpbGUgeworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIHVzZXI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA2NTEyNjE4NDIxNjI3Nzc2MjBMOworCisgICAgLyoKKyAgICAgKiBTdXBlcmNsYXNzIFVOSVhGaWxlIGxvYWRzIHRoZSBsaWJyYXJ5IGNvbnRhaW5pbmcgYWxsIHRoZQorICAgICAqIG5hdGl2ZSBjb2RlIGFuZCBzZXRzIHRoZSAibG9hZGVkIiBmbGFnIGlmIHN1Y2Nlc3NmdWwuCisgICAgICovCisKKyAgICBwdWJsaWMgVU5JWEluYm94KFN0cmluZyB1c2VyLCBTdHJpbmcgbmFtZSkgeworCXN1cGVyKG5hbWUpOworCXRoaXMudXNlciA9IHVzZXI7CisJaWYgKHVzZXIgPT0gbnVsbCkKKwkgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJ1c2VyIG5hbWUgaXMgbnVsbCBpbiBVTklYSW5ib3giKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBsb2NrKFN0cmluZyBtb2RlKSB7CisJaWYgKGxvY2tUeXBlID09IE5BVElWRSkgeworCSAgICBpZiAoIWxvYWRlZCkKKwkJcmV0dXJuIGZhbHNlOworCSAgICBpZiAoIW1haWxsb2NrKHVzZXIsIDUpKQorCQlyZXR1cm4gZmFsc2U7CisJfQorCWlmICghc3VwZXIubG9jayhtb2RlKSkgeworCSAgICBpZiAobG9hZGVkKQorCQltYWlsdW5sb2NrKCk7CisJICAgIHJldHVybiBmYWxzZTsKKwl9CisJcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5sb2NrKCkgeyAKKwlzdXBlci51bmxvY2soKTsKKwlpZiAobG9hZGVkKQorCSAgICBtYWlsdW5sb2NrKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdG91Y2hsb2NrKCkgeworCWlmIChsb2FkZWQpCisJICAgIHRvdWNobG9jazAoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHRyYW5zaWVudCBSYW5kb21BY2Nlc3NGaWxlIGxvY2tmaWxlOyAvLyB0aGUgdXNlcidzIH4vLk1haWxsb2NrIGZpbGUKKyAgICBwcml2YXRlIHRyYW5zaWVudCBTdHJpbmcgbG9ja2ZpbGVOYW1lOwkvLyBpdHMgbmFtZQorCisgICAgcHVibGljIGJvb2xlYW4gb3BlbkxvY2soU3RyaW5nIG1vZGUpIHsKKwlpZiAobW9kZS5lcXVhbHMoInIiKSkKKwkgICAgcmV0dXJuIHRydWU7CisJaWYgKGxvY2tmaWxlTmFtZSA9PSBudWxsKSB7CisJICAgIFN0cmluZyBob21lID0gU3lzdGVtLmdldFByb3BlcnR5KCJ1c2VyLmhvbWUiKTsKKwkgICAgbG9ja2ZpbGVOYW1lID0gaG9tZSArIEZpbGUuc2VwYXJhdG9yICsgIi5NYWlsbG9jayI7CisJfQorCXRyeSB7CisJICAgIGxvY2tmaWxlID0gbmV3IFJhbmRvbUFjY2Vzc0ZpbGUobG9ja2ZpbGVOYW1lLCBtb2RlKTsKKwkgICAgYm9vbGVhbiByZXQ7CisJICAgIHN3aXRjaCAobG9ja1R5cGUpIHsKKwkgICAgY2FzZSBOT05FOgorCQlyZXQgPSB0cnVlOworCQlicmVhazsKKwkgICAgY2FzZSBOQVRJVkU6CisJICAgIGRlZmF1bHQ6CisJCXJldCA9IFVOSVhGaWxlLmxvY2sobG9ja2ZpbGUuZ2V0RkQoKSwgbW9kZSk7CisJCWJyZWFrOworCSAgICBjYXNlIEpBVkE6CisJCXJldCA9IGxvY2tmaWxlLmdldENoYW5uZWwoKS4KKwkJICAgIHRyeUxvY2soMEwsIExvbmcuTUFYX1ZBTFVFLCAhbW9kZS5lcXVhbHMoInJ3IikpICE9IG51bGw7CisJCWJyZWFrOworCSAgICB9CisJICAgIGlmICghcmV0KQorCQljbG9zZUxvY2soKTsKKwkgICAgcmV0dXJuIHJldDsKKwl9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworCX0KKwlyZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgY2xvc2VMb2NrKCkgeworCWlmIChsb2NrZmlsZSA9PSBudWxsKQorCSAgICByZXR1cm47CisJdHJ5IHsKKwkgICAgbG9ja2ZpbGUuY2xvc2UoKTsKKwl9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworCX0gZmluYWxseSB7CisJICAgIGxvY2tmaWxlID0gbnVsbDsKKwl9CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvKSB7CisJaWYgKCEobyBpbnN0YW5jZW9mIFVOSVhJbmJveCkpCisJICAgIHJldHVybiBmYWxzZTsKKwlVTklYSW5ib3ggb3RoZXIgPSAoVU5JWEluYm94KW87CisJcmV0dXJuIHVzZXIuZXF1YWxzKG90aGVyLnVzZXIpICYmIHN1cGVyLmVxdWFscyhvdGhlcik7CisgICAgfQorCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKwlyZXR1cm4gc3VwZXIuaGFzaENvZGUoKSArIHVzZXIuaGFzaENvZGUoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIG5hdGl2ZSBib29sZWFuIG1haWxsb2NrKFN0cmluZyB1c2VyLCBpbnQgcmV0cnlDb3VudCk7CisgICAgcHJpdmF0ZSBuYXRpdmUgdm9pZCBtYWlsdW5sb2NrKCk7CisgICAgcHJpdmF0ZSBuYXRpdmUgdm9pZCB0b3VjaGxvY2swKCk7Cit9CmRpZmYgLS1naXQgYS9tYm94L3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3JlbW90ZS9QT1AzUmVtb3RlUHJvdmlkZXIuamF2YSBiL21ib3gvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvcmVtb3RlL1BPUDNSZW1vdGVQcm92aWRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU1ZTM5ODcKLS0tIC9kZXYvbnVsbAorKysgYi9tYm94L3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3JlbW90ZS9QT1AzUmVtb3RlUHJvdmlkZXIuamF2YQpAQCAtMCwwICsxLDI5IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5yZW1vdGU7CisKK2ltcG9ydCBqYXZheC5tYWlsLlByb3ZpZGVyOworCisvKioKKyAqIFRoZSBQT1AzIHJlbW90ZSBwcm90b2NvbCBwcm92aWRlci4KKyAqLworcHVibGljIGNsYXNzIFBPUDNSZW1vdGVQcm92aWRlciBleHRlbmRzIFByb3ZpZGVyIHsKKyAgICBwdWJsaWMgUE9QM1JlbW90ZVByb3ZpZGVyKCkgeworCXN1cGVyKFByb3ZpZGVyLlR5cGUuU1RPUkUsICJwb3AzcmVtb3RlIiwKKwkgICAgUE9QM1JlbW90ZVN0b3JlLmNsYXNzLmdldE5hbWUoKSwgIk9yYWNsZSIsIG51bGwpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21ib3gvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvcmVtb3RlL1BPUDNSZW1vdGVTdG9yZS5qYXZhIGIvbWJveC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9yZW1vdGUvUE9QM1JlbW90ZVN0b3JlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmE2YjFkNAotLS0gL2Rldi9udWxsCisrKyBiL21ib3gvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvcmVtb3RlL1BPUDNSZW1vdGVTdG9yZS5qYXZhCkBAIC0wLDAgKzEsMzYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisgKgorICogVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICogTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICogRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgKiB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorICovCisKK3BhY2thZ2UgY29tLnN1bi5tYWlsLnJlbW90ZTsKKworaW1wb3J0IGphdmF4Lm1haWwuKjsKK2ltcG9ydCBjb20uc3VuLm1haWwucG9wMy5QT1AzU3RvcmU7CisKKy8qKgorICogQSBsb2NhbCBzdG9yZSB0aGF0IHVzZXMgUE9QMyB0byBwb3B1bGF0ZSB0aGUgSU5CT1guCisgKgorICogQGF1dGhvciAgICAgIEJpbGwgU2hhbm5vbgorICovCitwdWJsaWMgY2xhc3MgUE9QM1JlbW90ZVN0b3JlIGV4dGVuZHMgUmVtb3RlU3RvcmUgeworCisgICAgcHVibGljIFBPUDNSZW1vdGVTdG9yZShTZXNzaW9uIHNlc3Npb24sIFVSTE5hbWUgdXJsKSB7CisJc3VwZXIoc2Vzc2lvbiwgdXJsKTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgU3RvcmUgZ2V0UmVtb3RlU3RvcmUoU2Vzc2lvbiBzZXNzaW9uLCBVUkxOYW1lIHVybCkgeworCXJldHVybiBuZXcgUE9QM1N0b3JlKHNlc3Npb24sIHVybCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWJveC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9yZW1vdGUvUmVtb3RlRGVmYXVsdEZvbGRlci5qYXZhIGIvbWJveC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9yZW1vdGUvUmVtb3RlRGVmYXVsdEZvbGRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgxYzBmOTAKLS0tIC9kZXYvbnVsbAorKysgYi9tYm94L3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3JlbW90ZS9SZW1vdGVEZWZhdWx0Rm9sZGVyLmphdmEKQEAgLTAsMCArMSw1MCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwucmVtb3RlOworCitpbXBvcnQgamF2YXgubWFpbC4qOworaW1wb3J0IGNvbS5zdW4ubWFpbC5tYm94Lio7CisKKy8qKgorICogVGhlIGRlZmF1bHQgZm9sZGVyIGZvciB0aGUgInJlbW90ZSIgcHJvdG9jb2wuCisgKgorICogQGF1dGhvciBCaWxsIFNoYW5ub24KKyAqLworcHVibGljIGNsYXNzIFJlbW90ZURlZmF1bHRGb2xkZXIgZXh0ZW5kcyBNYm94Rm9sZGVyIHsKKworICAgIHByb3RlY3RlZCBSZW1vdGVEZWZhdWx0Rm9sZGVyKFJlbW90ZVN0b3JlIHN0b3JlLCBTdHJpbmcgbmFtZSkgeworCXN1cGVyKHN0b3JlLCBuYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBEZXBlbmRpbmcgb24gdGhlIG5hbWUgb2YgdGhlIHJlcXVlc3RlZCBmb2xkZXIsIGNyZWF0ZSBhbgorICAgICAqIGFwcHJvcHJpYXRlIDxjb2RlPkZvbGRlcjwvY29kZT4gc3ViY2xhc3MuICBJZiB0aGUgbmFtZSBpcworICAgICAqIDxjb2RlPm51bGw8L2NvZGU+LCBjcmVhdGUgYSA8Y29kZT5SZW1vdGVEZWZhdWx0Rm9sZGVyPC9jb2RlPi4KKyAgICAgKiBJZiB0aGUgbmFtZSBpcyAiSU5CT1giIChpZ25vcmluZyBjYXNlKSwgY3JlYXRlIGEKKyAgICAgKiA8Y29kZT5SZW1vdGVJbmJveDwvY29kZT4uICBPdGhlcndpc2UsIGNyZWF0ZSBhbiA8Y29kZT5NYm94Rm9sZGVyPC9jb2RlPi4KKyAgICAgKgorICAgICAqIEByZXR1cm4JdGhlIG5ldyA8Y29kZT5Gb2xkZXI8L2NvZGU+CisgICAgICovCisgICAgcHJvdGVjdGVkIEZvbGRlciBjcmVhdGVGb2xkZXIoU3RvcmUgc3RvcmUsIFN0cmluZyBuYW1lKSB7CisJaWYgKG5hbWUgPT0gbnVsbCkKKwkgICAgcmV0dXJuIG5ldyBSZW1vdGVEZWZhdWx0Rm9sZGVyKChSZW1vdGVTdG9yZSlzdG9yZSwgbnVsbCk7CisJZWxzZSBpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlKCJJTkJPWCIpKQorCSAgICByZXR1cm4gbmV3IFJlbW90ZUluYm94KChSZW1vdGVTdG9yZSlzdG9yZSwgbmFtZSk7CisJZWxzZQorCSAgICByZXR1cm4gbmV3IE1ib3hGb2xkZXIoKE1ib3hTdG9yZSlzdG9yZSwgbmFtZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWJveC9zcmMvbWFpbi9qYXZhL2NvbS9zdW4vbWFpbC9yZW1vdGUvUmVtb3RlSW5ib3guamF2YSBiL21ib3gvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvcmVtb3RlL1JlbW90ZUluYm94LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWJmZDIzMgotLS0gL2Rldi9udWxsCisrKyBiL21ib3gvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvcmVtb3RlL1JlbW90ZUluYm94LmphdmEKQEAgLTAsMCArMSw2OCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwucmVtb3RlOworCitpbXBvcnQgamF2YXgubWFpbC4qOworaW1wb3J0IGNvbS5zdW4ubWFpbC5tYm94Lio7CisKKy8qKgorICogQSByZW1vdGUgSW5ib3ggZm9sZGVyLiAgVGhlIGRhdGEgaXMgYWN0dWFsbHkgbWFuYWdlZCBieSBvdXIgc3ViY2xhc3MKKyAqICg8Y29kZT5NYm94Rm9sZGVyPC9jb2RlPikuICBXZSBmZXRjaCBkYXRhIGZyb20gdGhlIHJlbW90ZSBJbmJveCBhbmQKKyAqIGFkZCBpdCB0byB0aGUgbG9jYWwgSW5ib3guCisgKgorICogQGF1dGhvciBCaWxsIFNoYW5ub24KKyAqLworCitwdWJsaWMgY2xhc3MgUmVtb3RlSW5ib3ggZXh0ZW5kcyBNYm94Rm9sZGVyIHsKKworICAgIHByaXZhdGUgUmVtb3RlU3RvcmUgbXN0b3JlOworCisgICAgcHJvdGVjdGVkIFJlbW90ZUluYm94KFJlbW90ZVN0b3JlIHN0b3JlLCBTdHJpbmcgbmFtZSkgeworCXN1cGVyKHN0b3JlLCBuYW1lKTsKKwl0aGlzLm1zdG9yZSA9IHN0b3JlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBvbGwgdGhlIHJlbW90ZSBzdG9yZSBmb3IgYW55IG5ldyBtZXNzYWdlcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGJvb2xlYW4gaGFzTmV3TWVzc2FnZXMoKSB7CisJdHJ5IHsKKwkgICAgbXN0b3JlLnVwZGF0ZUluYm94KCk7CisJfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIGV4KSB7CisJICAgIC8vIGlnbm9yZSBpdAorCX0KKwlyZXR1cm4gc3VwZXIuaGFzTmV3TWVzc2FnZXMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBPcGVuIHRoZSBmb2xkZXIgaW4gdGhlIHNwZWNpZmllZCBtb2RlLgorICAgICAqIFBvbGwgdGhlIHJlbW90ZSBzdG9yZSBmb3IgYW55IG5ldyBtZXNzYWdlcyBmaXJzdC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgb3BlbihpbnQgbW9kZSkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJbXN0b3JlLnVwZGF0ZUluYm94KCk7CisJc3VwZXIub3Blbihtb2RlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIG51bWJlciBvZiBtZXNzYWdlcyBpbiB0aGlzIGZvbGRlci4KKyAgICAgKiBQb2xsIHRoZSByZW1vdGUgc3RvcmUgZm9yIGFueSBuZXcgbWVzc2FnZXMgZmlyc3QuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBpbnQgZ2V0TWVzc2FnZUNvdW50KCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJbXN0b3JlLnVwZGF0ZUluYm94KCk7CisJcmV0dXJuIHN1cGVyLmdldE1lc3NhZ2VDb3VudCgpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21ib3gvc3JjL21haW4vamF2YS9jb20vc3VuL21haWwvcmVtb3RlL1JlbW90ZVN0b3JlLmphdmEgYi9tYm94L3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3JlbW90ZS9SZW1vdGVTdG9yZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZhZjlkZDQKLS0tIC9kZXYvbnVsbAorKysgYi9tYm94L3NyYy9tYWluL2phdmEvY29tL3N1bi9tYWlsL3JlbW90ZS9SZW1vdGVTdG9yZS5qYXZhCkBAIC0wLDAgKzEsMTI3IEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCitwYWNrYWdlIGNvbS5zdW4ubWFpbC5yZW1vdGU7CisKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YXgubWFpbC4qOworaW1wb3J0IGNvbS5zdW4ubWFpbC5tYm94Lio7CisKKy8qKgorICogQSB3cmFwcGVyIGFyb3VuZCBhIGxvY2FsIDxjb2RlPk1ib3hTdG9yZTwvY29kZT4gdGhhdCBmZXRjaGVzIGRhdGEKKyAqIGZyb20gdGhlIEluYm94IGluIGEgcmVtb3RlIHN0b3JlIGFuZCBhZGRzIGl0IHRvIG91ciBsb2NhbCBJbmJveC4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIFJlbW90ZVN0b3JlIGV4dGVuZHMgTWJveFN0b3JlIHsKKworICAgIHByb3RlY3RlZCBTdG9yZSByZW1vdGVTdG9yZTsKKyAgICBwcm90ZWN0ZWQgRm9sZGVyIHJlbW90ZUluYm94OworICAgIHByb3RlY3RlZCBGb2xkZXIgaW5ib3g7CisgICAgcHJvdGVjdGVkIFN0cmluZyBob3N0LCB1c2VyLCBwYXNzd29yZDsKKyAgICBwcm90ZWN0ZWQgaW50IHBvcnQ7CisgICAgcHJvdGVjdGVkIGxvbmcgbGFzdFVwZGF0ZSA9IDA7CisKKyAgICBwdWJsaWMgUmVtb3RlU3RvcmUoU2Vzc2lvbiBzZXNzaW9uLCBVUkxOYW1lIHVybCkgeworCXN1cGVyKHNlc3Npb24sIHVybCk7CisJcmVtb3RlU3RvcmUgPSBnZXRSZW1vdGVTdG9yZShzZXNzaW9uLCB1cmwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFN1YmNsYXNzZXMgb3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8gcmV0dXJuIHRoZSBhcHByb3ByaWF0ZQorICAgICAqIDxjb2RlPlN0b3JlPC9jb2RlPiBvYmplY3QuICBUaGlzIG1ldGhvZCB3aWxsIGJlIGNhbGxlZCBieQorICAgICAqIHRoZSA8Y29kZT5SZW1vdGVTdG9yZTwvY29kZT4gY29uc3RydWN0b3IuCisgICAgICovCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IFN0b3JlIGdldFJlbW90ZVN0b3JlKFNlc3Npb24gc2Vzc2lvbiwgVVJMTmFtZSB1cmwpOworCisgICAgLyoqCisgICAgICogQ29ubmVjdCB0byB0aGUgc3RvcmUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgY29ubmVjdChTdHJpbmcgaG9zdCwgaW50IHBvcnQsIFN0cmluZyB1c2VyLCBTdHJpbmcgcGFzc3dvcmQpCisJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwl0aGlzLmhvc3QgPSBob3N0OworCXRoaXMucG9ydCA9IHBvcnQ7CisJdGhpcy51c2VyID0gdXNlcjsKKwl0aGlzLnBhc3N3b3JkID0gcGFzc3dvcmQ7CisJdXBkYXRlSW5ib3goKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGZXRjaCBhbnkgbmV3IG1haWwgaW4gdGhlIHJlbW90ZSBJTkJPWCBhbmQgYWRkIGl0IHRvIHRoZSBsb2NhbCBJTkJPWC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCB1cGRhdGVJbmJveCgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCS8vIGlzIGl0IHRpbWUgdG8gZG8gYW4gdXBkYXRlIHlldD8KKwkvLyBYWFggLSBwb2xsaW5nIGZyZXF1ZW5jeSwgcnVsZXMsIGV0Yy4gc2hvdWxkIGJlIGluIHByb3BlcnRpZXMKKwlpZiAoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgPCBsYXN0VXBkYXRlICsgKDUgKiAxMDAwKSkKKwkgICAgcmV0dXJuOworCXRyeSB7CisJICAgIC8qCisJICAgICAqIENvbm5lY3QgdG8gdGhlIHJlbW90ZSBzdG9yZSwgdXNpbmcgdGhlIHNhdmVkCisJICAgICAqIGF1dGhlbnRpY2F0aW9uIGluZm9ybWF0aW9uLgorCSAgICAgKi8KKwkgICAgcmVtb3RlU3RvcmUuY29ubmVjdChob3N0LCBwb3J0LCB1c2VyLCBwYXNzd29yZCk7CisKKwkgICAgLyoKKwkgICAgICogSWYgdGhpcyBzdG9yZSBpc24ndCBjb25uZWN0ZWQgeWV0LCBkbyBpdCBub3csIGJlY2F1c2UKKwkgICAgICogaXQgbmVlZHMgdG8gYmUgY29ubmVjdGVkIHRvIGdldCB0aGUgSU5CT1ggZm9sZGVyLgorCSAgICAgKi8KKwkgICAgaWYgKCFpc0Nvbm5lY3RlZCgpKQorCQlzdXBlci5jb25uZWN0KGhvc3QsIHBvcnQsIHVzZXIsIHBhc3N3b3JkKTsKKwkgICAgaWYgKHJlbW90ZUluYm94ID09IG51bGwpCisJCXJlbW90ZUluYm94ID0gcmVtb3RlU3RvcmUuZ2V0Rm9sZGVyKCJJTkJPWCIpOworCSAgICBpZiAoaW5ib3ggPT0gbnVsbCkKKwkJaW5ib3ggPSBnZXRGb2xkZXIoIklOQk9YIik7CisJICAgIHJlbW90ZUluYm94Lm9wZW4oRm9sZGVyLlJFQURfV1JJVEUpOworCSAgICBNZXNzYWdlW10gbXNncyA9IHJlbW90ZUluYm94LmdldE1lc3NhZ2VzKCk7CisJICAgIGluYm94LmFwcGVuZE1lc3NhZ2VzKG1zZ3MpOworCSAgICByZW1vdGVJbmJveC5zZXRGbGFncyhtc2dzLCBuZXcgRmxhZ3MoRmxhZ3MuRmxhZy5ERUxFVEVEKSwgdHJ1ZSk7CisJICAgIHJlbW90ZUluYm94LmNsb3NlKHRydWUpOworCSAgICByZW1vdGVTdG9yZS5jbG9zZSgpOworCX0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBleCkgeworCSAgICB0cnkgeworCQlpZiAocmVtb3RlSW5ib3ggIT0gbnVsbCAmJiByZW1vdGVJbmJveC5pc09wZW4oKSkKKwkJICAgIHJlbW90ZUluYm94LmNsb3NlKGZhbHNlKTsKKwkgICAgfSBmaW5hbGx5IHsKKwkJaWYgKHJlbW90ZVN0b3JlICE9IG51bGwgJiYgcmVtb3RlU3RvcmUuaXNDb25uZWN0ZWQoKSkKKwkJICAgIHJlbW90ZVN0b3JlLmNsb3NlKCk7CisJICAgIH0KKwkgICAgdGhyb3cgZXg7CisJfQorICAgIH0KKworICAgIHB1YmxpYyBGb2xkZXIgZ2V0RGVmYXVsdEZvbGRlcigpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWNoZWNrQ29ubmVjdGVkKCk7CisKKwlyZXR1cm4gbmV3IFJlbW90ZURlZmF1bHRGb2xkZXIodGhpcywgbnVsbCk7CisgICAgfQorCisgICAgcHVibGljIEZvbGRlciBnZXRGb2xkZXIoU3RyaW5nIG5hbWUpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWNoZWNrQ29ubmVjdGVkKCk7CisKKwlpZiAobmFtZS5lcXVhbHNJZ25vcmVDYXNlKCJJTkJPWCIpKQorCSAgICByZXR1cm4gbmV3IFJlbW90ZUluYm94KHRoaXMsIG5hbWUpOworCWVsc2UKKwkgICAgcmV0dXJuIHN1cGVyLmdldEZvbGRlcihuYW1lKTsKKyAgICB9CisKKyAgICBwdWJsaWMgRm9sZGVyIGdldEZvbGRlcihVUkxOYW1lIHVybCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJY2hlY2tDb25uZWN0ZWQoKTsKKwlyZXR1cm4gZ2V0Rm9sZGVyKHVybC5nZXRGaWxlKCkpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBjaGVja0Nvbm5lY3RlZCgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWlmICghaXNDb25uZWN0ZWQoKSkKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiTm90IGNvbm5lY3RlZCIpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL21ib3gvc3JjL21haW4vcmVzb3VyY2VzL01FVEEtSU5GL01BTklGRVNULk1GIGIvbWJveC9zcmMvbWFpbi9yZXNvdXJjZXMvTUVUQS1JTkYvTUFOSUZFU1QuTUYKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODIwZDhkMgotLS0gL2Rldi9udWxsCisrKyBiL21ib3gvc3JjL21haW4vcmVzb3VyY2VzL01FVEEtSU5GL01BTklGRVNULk1GCkBAIC0wLDAgKzEsOSBAQAorTWFuaWZlc3QtVmVyc2lvbjogMS4wCitFeHRlbnNpb24tTmFtZTogY29tLnN1bi5tYWlsLm1ib3gKK1NwZWNpZmljYXRpb24tVGl0bGU6IGNvbS5zdW4ubWFpbC5tYm94CitTcGVjaWZpY2F0aW9uLVZlcnNpb246ICR7bWFpbC5zcGVjLnZlcnNpb259CitTcGVjaWZpY2F0aW9uLVZlbmRvcjogJHtwcm9qZWN0Lm9yZ2FuaXphdGlvbi5uYW1lfQorSW1wbGVtZW50YXRpb24tVGl0bGU6IGNvbS5zdW4ubWFpbC5tYm94CitJbXBsZW1lbnRhdGlvbi1WZXJzaW9uOiAke21haWwudmVyc2lvbn0KK0ltcGxlbWVudGF0aW9uLVZlbmRvcjogJHtwcm9qZWN0Lm9yZ2FuaXphdGlvbi5uYW1lfQorSW1wbGVtZW50YXRpb24tVmVuZG9yLUlkOiBjb20uc3VuCmRpZmYgLS1naXQgYS9tYm94L3NyYy9tYWluL3Jlc291cmNlcy9NRVRBLUlORi9qYXZhbWFpbC5wcm92aWRlcnMgYi9tYm94L3NyYy9tYWluL3Jlc291cmNlcy9NRVRBLUlORi9qYXZhbWFpbC5wcm92aWRlcnMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzIyNzNkZAotLS0gL2Rldi9udWxsCisrKyBiL21ib3gvc3JjL21haW4vcmVzb3VyY2VzL01FVEEtSU5GL2phdmFtYWlsLnByb3ZpZGVycwpAQCAtMCwwICsxLDIgQEAKK3Byb3RvY29sPW1ib3g7IHR5cGU9c3RvcmU7IGNsYXNzPWNvbS5zdW4ubWFpbC5tYm94Lk1ib3hTdG9yZTsgdmVuZG9yPU9yYWNsZTsKK3Byb3RvY29sPXBvcDNyZW1vdGU7IHR5cGU9c3RvcmU7IGNsYXNzPWNvbS5zdW4ubWFpbC5yZW1vdGUuUE9QM1JlbW90ZVN0b3JlOyB2ZW5kb3I9T3JhY2xlOwpkaWZmIC0tZ2l0IGEvbWJveC9zcmMvbWFpbi9yZXNvdXJjZXMvTUVUQS1JTkYvc2VydmljZXMvamF2YXgubWFpbC5Qcm92aWRlciBiL21ib3gvc3JjL21haW4vcmVzb3VyY2VzL01FVEEtSU5GL3NlcnZpY2VzL2phdmF4Lm1haWwuUHJvdmlkZXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjYzMzU4ZAotLS0gL2Rldi9udWxsCisrKyBiL21ib3gvc3JjL21haW4vcmVzb3VyY2VzL01FVEEtSU5GL3NlcnZpY2VzL2phdmF4Lm1haWwuUHJvdmlkZXIKQEAgLTAsMCArMSwyIEBACitjb20uc3VuLm1haWwubWJveC5NYm94UHJvdmlkZXIKK2NvbS5zdW4ubWFpbC5yZW1vdGUuUE9QM1JlbW90ZVByb3ZpZGVyCmRpZmYgLS1naXQgYS9tYm94L3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL21ib3gvTWJveEZvbGRlckV4cHVuZ2VUZXN0LmphdmEgYi9tYm94L3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL21ib3gvTWJveEZvbGRlckV4cHVuZ2VUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTk0ZTEyNQotLS0gL2Rldi9udWxsCisrKyBiL21ib3gvc3JjL3Rlc3QvamF2YS9jb20vc3VuL21haWwvbWJveC9NYm94Rm9sZGVyRXhwdW5nZVRlc3QuamF2YQpAQCAtMCwwICsxLDM2MiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwOSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwubWJveDsKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOworaW1wb3J0IGphdmEudXRpbC5EYXRlOworCitpbXBvcnQgamF2YXgubWFpbC5TZXNzaW9uOworaW1wb3J0IGphdmF4Lm1haWwuU3RvcmU7CitpbXBvcnQgamF2YXgubWFpbC5Gb2xkZXI7CitpbXBvcnQgamF2YXgubWFpbC5NZXNzYWdlOworaW1wb3J0IGphdmF4Lm1haWwuRmxhZ3M7CitpbXBvcnQgamF2YXgubWFpbC5NZXNzYWdpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC5NaW1lTWVzc2FnZTsKKworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5CZWZvcmVDbGFzczsKK2ltcG9ydCBvcmcuanVuaXQuQWZ0ZXJDbGFzczsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRFcXVhbHM7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuZmFpbDsKKworLyoqCisgKiBUZXN0IGV4cHVuZ2Ugb2YgbWJveCBmb2xkZXJzLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgTWJveEZvbGRlckV4cHVuZ2VUZXN0IHsKKworICAgIEBCZWZvcmVDbGFzcworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBiZWZvcmUoKSB7CisJU3lzdGVtLnNldFByb3BlcnR5KCJtYWlsLm1ib3gubG9ja3R5cGUiLCAibm9uZSIpOworICAgIH0KKworICAgIEBBZnRlckNsYXNzCisgICAgcHVibGljIHN0YXRpYyB2b2lkIGFmdGVyKCkgeworCVN5c3RlbS5nZXRQcm9wZXJ0aWVzKCkucmVtb3ZlKCJtYWlsLm1ib3gubG9ja3R5cGUiKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RSZW1vdmVGaXJzdCgpIHRocm93cyBFeGNlcHRpb24geworCUZvbGRlciBmID0gY3JlYXRlVGVzdEZvbGRlcigpOworCXRyeSB7CisJICAgIGYub3BlbihGb2xkZXIuUkVBRF9XUklURSk7CisJICAgIE1lc3NhZ2UgbSA9IGYuZ2V0TWVzc2FnZSgxKTsKKwkgICAgbS5zZXRGbGFnKEZsYWdzLkZsYWcuREVMRVRFRCwgdHJ1ZSk7CisJICAgIGYuZXhwdW5nZSgpOworCSAgICBtID0gZi5nZXRNZXNzYWdlKDEpOworCSAgICBhc3NlcnRFcXVhbHMoIjIiLCAoKFN0cmluZyltLmdldENvbnRlbnQoKSkudHJpbSgpKTsKKwkgICAgbS5zZXRGbGFnKEZsYWdzLkZsYWcuREVMRVRFRCwgdHJ1ZSk7CisJICAgIG0gPSBmLmdldE1lc3NhZ2UoMik7CisJICAgIGFzc2VydEVxdWFscygiMyIsICgoU3RyaW5nKW0uZ2V0Q29udGVudCgpKS50cmltKCkpOworCSAgICBmLmV4cHVuZ2UoKTsKKwkgICAgbSA9IGYuZ2V0TWVzc2FnZSgxKTsKKwkgICAgYXNzZXJ0RXF1YWxzKCIzIiwgKChTdHJpbmcpbS5nZXRDb250ZW50KCkpLnRyaW0oKSk7CisJfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJICAgIFN5c3RlbS5vdXQucHJpbnRsbihleCk7CisJICAgIC8vZXgucHJpbnRTdGFja1RyYWNlKCk7CisJICAgIGZhaWwoZXgudG9TdHJpbmcoKSk7CisJfSBmaW5hbGx5IHsKKwkgICAgZi5jbG9zZShmYWxzZSk7CisJICAgIGYuZGVsZXRlKGZhbHNlKTsKKwkgICAgZi5nZXRTdG9yZSgpLmNsb3NlKCk7CisJfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFJlbW92ZU1pZGRsZSgpIHRocm93cyBFeGNlcHRpb24geworCUZvbGRlciBmID0gY3JlYXRlVGVzdEZvbGRlcigpOworCXRyeSB7CisJICAgIGYub3BlbihGb2xkZXIuUkVBRF9XUklURSk7CisJICAgIE1lc3NhZ2UgbSA9IGYuZ2V0TWVzc2FnZSgyKTsKKwkgICAgbS5zZXRGbGFnKEZsYWdzLkZsYWcuREVMRVRFRCwgdHJ1ZSk7CisJICAgIGYuZXhwdW5nZSgpOworCSAgICBtID0gZi5nZXRNZXNzYWdlKDEpOworCSAgICBhc3NlcnRFcXVhbHMoIjEiLCAoKFN0cmluZyltLmdldENvbnRlbnQoKSkudHJpbSgpKTsKKwkgICAgbSA9IGYuZ2V0TWVzc2FnZSgyKTsKKwkgICAgYXNzZXJ0RXF1YWxzKCIzIiwgKChTdHJpbmcpbS5nZXRDb250ZW50KCkpLnRyaW0oKSk7CisJfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJICAgIFN5c3RlbS5vdXQucHJpbnRsbihleCk7CisJICAgIC8vZXgucHJpbnRTdGFja1RyYWNlKCk7CisJICAgIGZhaWwoZXgudG9TdHJpbmcoKSk7CisJfSBmaW5hbGx5IHsKKwkgICAgZi5jbG9zZShmYWxzZSk7CisJICAgIGYuZGVsZXRlKGZhbHNlKTsKKwkgICAgZi5nZXRTdG9yZSgpLmNsb3NlKCk7CisJfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFJlbW92ZUxhc3QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlGb2xkZXIgZiA9IGNyZWF0ZVRlc3RGb2xkZXIoKTsKKwl0cnkgeworCSAgICBmLm9wZW4oRm9sZGVyLlJFQURfV1JJVEUpOworCSAgICBNZXNzYWdlIG0gPSBmLmdldE1lc3NhZ2UoMyk7CisJICAgIG0uc2V0RmxhZyhGbGFncy5GbGFnLkRFTEVURUQsIHRydWUpOworCSAgICBmLmV4cHVuZ2UoKTsKKwkgICAgbSA9IGYuZ2V0TWVzc2FnZSgxKTsKKwkgICAgYXNzZXJ0RXF1YWxzKCIxIiwgKChTdHJpbmcpbS5nZXRDb250ZW50KCkpLnRyaW0oKSk7CisJICAgIG0gPSBmLmdldE1lc3NhZ2UoMik7CisJICAgIGFzc2VydEVxdWFscygiMiIsICgoU3RyaW5nKW0uZ2V0Q29udGVudCgpKS50cmltKCkpOworCX0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oZXgpOworCSAgICAvL2V4LnByaW50U3RhY2tUcmFjZSgpOworCSAgICBmYWlsKGV4LnRvU3RyaW5nKCkpOworCX0gZmluYWxseSB7CisJICAgIGYuY2xvc2UoZmFsc2UpOworCSAgICBmLmRlbGV0ZShmYWxzZSk7CisJICAgIGYuZ2V0U3RvcmUoKS5jbG9zZSgpOworCX0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RSZW1vdmVGaXJzdENsb3NlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJRm9sZGVyIGYgPSBjcmVhdGVUZXN0Rm9sZGVyKCk7CisJdHJ5IHsKKwkgICAgZi5vcGVuKEZvbGRlci5SRUFEX1dSSVRFKTsKKwkgICAgTWVzc2FnZSBtID0gZi5nZXRNZXNzYWdlKDEpOworCSAgICBtLnNldEZsYWcoRmxhZ3MuRmxhZy5ERUxFVEVELCB0cnVlKTsKKwkgICAgZi5jbG9zZSh0cnVlKTsKKwkgICAgZi5vcGVuKEZvbGRlci5SRUFEX1dSSVRFKTsKKwkgICAgbSA9IGYuZ2V0TWVzc2FnZSgxKTsKKwkgICAgYXNzZXJ0RXF1YWxzKCIyIiwgKChTdHJpbmcpbS5nZXRDb250ZW50KCkpLnRyaW0oKSk7CisJICAgIG0uc2V0RmxhZyhGbGFncy5GbGFnLkRFTEVURUQsIHRydWUpOworCSAgICBtID0gZi5nZXRNZXNzYWdlKDIpOworCSAgICBhc3NlcnRFcXVhbHMoIjMiLCAoKFN0cmluZyltLmdldENvbnRlbnQoKSkudHJpbSgpKTsKKwkgICAgZi5jbG9zZSh0cnVlKTsKKwkgICAgZi5vcGVuKEZvbGRlci5SRUFEX1dSSVRFKTsKKwkgICAgbSA9IGYuZ2V0TWVzc2FnZSgxKTsKKwkgICAgYXNzZXJ0RXF1YWxzKCIzIiwgKChTdHJpbmcpbS5nZXRDb250ZW50KCkpLnRyaW0oKSk7CisJfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJICAgIFN5c3RlbS5vdXQucHJpbnRsbihleCk7CisJICAgIC8vZXgucHJpbnRTdGFja1RyYWNlKCk7CisJICAgIGZhaWwoZXgudG9TdHJpbmcoKSk7CisJfSBmaW5hbGx5IHsKKwkgICAgZi5jbG9zZShmYWxzZSk7CisJICAgIGYuZGVsZXRlKGZhbHNlKTsKKwkgICAgZi5nZXRTdG9yZSgpLmNsb3NlKCk7CisJfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFJlbW92ZU1pZGRsZUNsb3NlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJRm9sZGVyIGYgPSBjcmVhdGVUZXN0Rm9sZGVyKCk7CisJdHJ5IHsKKwkgICAgZi5vcGVuKEZvbGRlci5SRUFEX1dSSVRFKTsKKwkgICAgTWVzc2FnZSBtID0gZi5nZXRNZXNzYWdlKDIpOworCSAgICBtLnNldEZsYWcoRmxhZ3MuRmxhZy5ERUxFVEVELCB0cnVlKTsKKwkgICAgZi5jbG9zZSh0cnVlKTsKKwkgICAgZi5vcGVuKEZvbGRlci5SRUFEX1dSSVRFKTsKKwkgICAgbSA9IGYuZ2V0TWVzc2FnZSgxKTsKKwkgICAgYXNzZXJ0RXF1YWxzKCIxIiwgKChTdHJpbmcpbS5nZXRDb250ZW50KCkpLnRyaW0oKSk7CisJICAgIG0gPSBmLmdldE1lc3NhZ2UoMik7CisJICAgIGFzc2VydEVxdWFscygiMyIsICgoU3RyaW5nKW0uZ2V0Q29udGVudCgpKS50cmltKCkpOworCX0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oZXgpOworCSAgICAvL2V4LnByaW50U3RhY2tUcmFjZSgpOworCSAgICBmYWlsKGV4LnRvU3RyaW5nKCkpOworCX0gZmluYWxseSB7CisJICAgIGYuY2xvc2UoZmFsc2UpOworCSAgICBmLmRlbGV0ZShmYWxzZSk7CisJICAgIGYuZ2V0U3RvcmUoKS5jbG9zZSgpOworCX0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RSZW1vdmVMYXN0Q2xvc2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlGb2xkZXIgZiA9IGNyZWF0ZVRlc3RGb2xkZXIoKTsKKwl0cnkgeworCSAgICBmLm9wZW4oRm9sZGVyLlJFQURfV1JJVEUpOworCSAgICBNZXNzYWdlIG0gPSBmLmdldE1lc3NhZ2UoMyk7CisJICAgIG0uc2V0RmxhZyhGbGFncy5GbGFnLkRFTEVURUQsIHRydWUpOworCSAgICBmLmNsb3NlKHRydWUpOworCSAgICBmLm9wZW4oRm9sZGVyLlJFQURfV1JJVEUpOworCSAgICBtID0gZi5nZXRNZXNzYWdlKDEpOworCSAgICBhc3NlcnRFcXVhbHMoIjEiLCAoKFN0cmluZyltLmdldENvbnRlbnQoKSkudHJpbSgpKTsKKwkgICAgbSA9IGYuZ2V0TWVzc2FnZSgyKTsKKwkgICAgYXNzZXJ0RXF1YWxzKCIyIiwgKChTdHJpbmcpbS5nZXRDb250ZW50KCkpLnRyaW0oKSk7CisJfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJICAgIFN5c3RlbS5vdXQucHJpbnRsbihleCk7CisJICAgIC8vZXgucHJpbnRTdGFja1RyYWNlKCk7CisJICAgIGZhaWwoZXgudG9TdHJpbmcoKSk7CisJfSBmaW5hbGx5IHsKKwkgICAgZi5jbG9zZShmYWxzZSk7CisJICAgIGYuZGVsZXRlKGZhbHNlKTsKKwkgICAgZi5nZXRTdG9yZSgpLmNsb3NlKCk7CisJfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFJlbW92ZUZpcnN0TWVzc2FnZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwlGb2xkZXIgZiA9IGNyZWF0ZVRlc3RGb2xkZXIoKTsKKwl0cnkgeworCSAgICBmLm9wZW4oRm9sZGVyLlJFQURfV1JJVEUpOworCSAgICBNZXNzYWdlW10gbXNncyA9IGYuZ2V0TWVzc2FnZXMoMSwgMyk7CisJICAgIG1zZ3NbMF0uc2V0RmxhZyhGbGFncy5GbGFnLkRFTEVURUQsIHRydWUpOworCSAgICBmLmV4cHVuZ2UoKTsKKwkgICAgYXNzZXJ0RXF1YWxzKCIyIiwgKChTdHJpbmcpbXNnc1sxXS5nZXRDb250ZW50KCkpLnRyaW0oKSk7CisJICAgIGFzc2VydEVxdWFscygiMyIsICgoU3RyaW5nKW1zZ3NbMl0uZ2V0Q29udGVudCgpKS50cmltKCkpOworCSAgICBtc2dzWzFdLnNldEZsYWcoRmxhZ3MuRmxhZy5ERUxFVEVELCB0cnVlKTsKKwkgICAgZi5leHB1bmdlKCk7CisJICAgIGFzc2VydEVxdWFscygiMyIsICgoU3RyaW5nKW1zZ3NbMl0uZ2V0Q29udGVudCgpKS50cmltKCkpOworCX0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oZXgpOworCSAgICAvL2V4LnByaW50U3RhY2tUcmFjZSgpOworCSAgICBmYWlsKGV4LnRvU3RyaW5nKCkpOworCX0gZmluYWxseSB7CisJICAgIGYuY2xvc2UoZmFsc2UpOworCSAgICBmLmRlbGV0ZShmYWxzZSk7CisJICAgIGYuZ2V0U3RvcmUoKS5jbG9zZSgpOworCX0KKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RSZW1vdmVNaWRkbGVNZXNzYWdlcygpIHRocm93cyBFeGNlcHRpb24geworCUZvbGRlciBmID0gY3JlYXRlVGVzdEZvbGRlcigpOworCXRyeSB7CisJICAgIGYub3BlbihGb2xkZXIuUkVBRF9XUklURSk7CisJICAgIE1lc3NhZ2VbXSBtc2dzID0gZi5nZXRNZXNzYWdlcygxLCAzKTsKKwkgICAgbXNnc1sxXS5zZXRGbGFnKEZsYWdzLkZsYWcuREVMRVRFRCwgdHJ1ZSk7CisJICAgIGYuZXhwdW5nZSgpOworCSAgICBhc3NlcnRFcXVhbHMoIjEiLCAoKFN0cmluZyltc2dzWzBdLmdldENvbnRlbnQoKSkudHJpbSgpKTsKKwkgICAgYXNzZXJ0RXF1YWxzKCIzIiwgKChTdHJpbmcpbXNnc1syXS5nZXRDb250ZW50KCkpLnRyaW0oKSk7CisJfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJICAgIFN5c3RlbS5vdXQucHJpbnRsbihleCk7CisJICAgIC8vZXgucHJpbnRTdGFja1RyYWNlKCk7CisJICAgIGZhaWwoZXgudG9TdHJpbmcoKSk7CisJfSBmaW5hbGx5IHsKKwkgICAgZi5jbG9zZShmYWxzZSk7CisJICAgIGYuZGVsZXRlKGZhbHNlKTsKKwkgICAgZi5nZXRTdG9yZSgpLmNsb3NlKCk7CisJfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFJlbW92ZUxhc3RNZXNzYWdlcygpIHRocm93cyBFeGNlcHRpb24geworCUZvbGRlciBmID0gY3JlYXRlVGVzdEZvbGRlcigpOworCXRyeSB7CisJICAgIGYub3BlbihGb2xkZXIuUkVBRF9XUklURSk7CisJICAgIE1lc3NhZ2VbXSBtc2dzID0gZi5nZXRNZXNzYWdlcygxLCAzKTsKKwkgICAgbXNnc1syXS5zZXRGbGFnKEZsYWdzLkZsYWcuREVMRVRFRCwgdHJ1ZSk7CisJICAgIGYuZXhwdW5nZSgpOworCSAgICBhc3NlcnRFcXVhbHMoIjEiLCAoKFN0cmluZyltc2dzWzBdLmdldENvbnRlbnQoKSkudHJpbSgpKTsKKwkgICAgYXNzZXJ0RXF1YWxzKCIyIiwgKChTdHJpbmcpbXNnc1sxXS5nZXRDb250ZW50KCkpLnRyaW0oKSk7CisJfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJICAgIFN5c3RlbS5vdXQucHJpbnRsbihleCk7CisJICAgIC8vZXgucHJpbnRTdGFja1RyYWNlKCk7CisJICAgIGZhaWwoZXgudG9TdHJpbmcoKSk7CisJfSBmaW5hbGx5IHsKKwkgICAgZi5jbG9zZShmYWxzZSk7CisJICAgIGYuZGVsZXRlKGZhbHNlKTsKKwkgICAgZi5nZXRTdG9yZSgpLmNsb3NlKCk7CisJfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdE5ld01lc3NhZ2VzQWZ0ZXJFeHB1bmdlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJRm9sZGVyIGYgPSBjcmVhdGVUZXN0Rm9sZGVyKCk7CisJdHJ5IHsKKwkgICAgZi5vcGVuKEZvbGRlci5SRUFEX1dSSVRFKTsKKwkgICAgTWVzc2FnZVtdIG1zZ3MgPSBmLmdldE1lc3NhZ2VzKDEsIDMpOworCSAgICBtc2dzWzBdLnNldEZsYWcoRmxhZ3MuRmxhZy5ERUxFVEVELCB0cnVlKTsKKwkgICAgZi5leHB1bmdlKCk7CisJICAgIGYuYXBwZW5kTWVzc2FnZXMobmV3IE1lc3NhZ2VbXSB7IGNyZWF0ZU1lc3NhZ2UobnVsbCwgNCkgfSk7CisJICAgIGFzc2VydEVxdWFscygzLCBmLmdldE1lc3NhZ2VDb3VudCgpKTsKKwkgICAgTWVzc2FnZSBtID0gZi5nZXRNZXNzYWdlKDMpOworCSAgICBhc3NlcnRFcXVhbHMoIjQiLCAoKFN0cmluZyltLmdldENvbnRlbnQoKSkudHJpbSgpKTsKKwl9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKwkgICAgU3lzdGVtLm91dC5wcmludGxuKGV4KTsKKwkgICAgLy9leC5wcmludFN0YWNrVHJhY2UoKTsKKwkgICAgZmFpbChleC50b1N0cmluZygpKTsKKwl9IGZpbmFsbHkgeworCSAgICBmLmNsb3NlKGZhbHNlKTsKKwkgICAgZi5kZWxldGUoZmFsc2UpOworCSAgICBmLmdldFN0b3JlKCkuY2xvc2UoKTsKKwl9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TmV3TWVzc2FnZXNBZnRlckNsb3NlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJRm9sZGVyIGYgPSBjcmVhdGVUZXN0Rm9sZGVyKCk7CisJdHJ5IHsKKwkgICAgZi5vcGVuKEZvbGRlci5SRUFEX1dSSVRFKTsKKwkgICAgTWVzc2FnZVtdIG1zZ3MgPSBmLmdldE1lc3NhZ2VzKDEsIDMpOworCSAgICBtc2dzWzBdLnNldEZsYWcoRmxhZ3MuRmxhZy5ERUxFVEVELCB0cnVlKTsKKwkgICAgZi5jbG9zZSh0cnVlKTsKKwkgICAgZi5hcHBlbmRNZXNzYWdlcyhuZXcgTWVzc2FnZVtdIHsgY3JlYXRlTWVzc2FnZShudWxsLCA0KSB9KTsKKwkgICAgZi5vcGVuKEZvbGRlci5SRUFEX1dSSVRFKTsKKwkgICAgYXNzZXJ0RXF1YWxzKDMsIGYuZ2V0TWVzc2FnZUNvdW50KCkpOworCSAgICBNZXNzYWdlIG0gPSBmLmdldE1lc3NhZ2UoMyk7CisJICAgIGFzc2VydEVxdWFscygiNCIsICgoU3RyaW5nKW0uZ2V0Q29udGVudCgpKS50cmltKCkpOworCX0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oZXgpOworCSAgICAvL2V4LnByaW50U3RhY2tUcmFjZSgpOworCSAgICBmYWlsKGV4LnRvU3RyaW5nKCkpOworCX0gZmluYWxseSB7CisJICAgIGYuY2xvc2UoZmFsc2UpOworCSAgICBmLmRlbGV0ZShmYWxzZSk7CisJICAgIGYuZ2V0U3RvcmUoKS5jbG9zZSgpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSB0ZW1wIGZpbGUgdG8gdXNlIGFzIGEgdGVzdCBmb2xkZXIgYW5kIHBvcHVsYXRlIGl0CisgICAgICogd2l0aCAzIG1lc3NhZ2VzLgorICAgICAqLworICAgIHByaXZhdGUgRm9sZGVyIGNyZWF0ZVRlc3RGb2xkZXIoKSB7CisJUHJvcGVydGllcyBwcm9wZXJ0aWVzID0gbmV3IFByb3BlcnRpZXMoKTsKKwlTZXNzaW9uIHNlc3Npb24gPSBTZXNzaW9uLmdldEluc3RhbmNlKHByb3BlcnRpZXMpOworCS8vc2Vzc2lvbi5zZXREZWJ1Zyh0cnVlKTsKKworCUZvbGRlciBmb2xkZXIgPSBudWxsOworCXRyeSB7CisJICAgIFN0b3JlIHN0b3JlID0gc2Vzc2lvbi5nZXRTdG9yZSgibWJveCIpOworCSAgICBGaWxlIHRlbXAgPSBGaWxlLmNyZWF0ZVRlbXBGaWxlKCJtYm94IiwgIi5tYngiKTsKKwkgICAgdGVtcC5kZWxldGVPbkV4aXQoKTsKKwkgICAgc3RvcmUuY29ubmVjdCgpOworCSAgICBmb2xkZXIgPSBzdG9yZS5nZXRGb2xkZXIodGVtcC5nZXRBYnNvbHV0ZVBhdGgoKSk7CisJICAgIGZvbGRlci5jcmVhdGUoRm9sZGVyLkhPTERTX01FU1NBR0VTKTsKKwkgICAgTWVzc2FnZVtdIG1zZ3MgPSBuZXcgTWVzc2FnZVszXTsKKwkgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAzOyBpKyspCisJCW1zZ3NbaV0gPSBjcmVhdGVNZXNzYWdlKHNlc3Npb24sIGkgKyAxKTsKKwkgICAgZm9sZGVyLmFwcGVuZE1lc3NhZ2VzKG1zZ3MpOworCX0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oZXgpOworCSAgICAvL2V4LnByaW50U3RhY2tUcmFjZSgpOworCSAgICBmYWlsKGV4LnRvU3RyaW5nKCkpOworCX0KKwlyZXR1cm4gZm9sZGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIHRlc3QgbWVzc2FnZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIE1lc3NhZ2UgY3JlYXRlTWVzc2FnZShTZXNzaW9uIHNlc3Npb24sIGludCBtc2dubykKKwkJCQl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlNaW1lTWVzc2FnZSBtc2cgPSBuZXcgTWltZU1lc3NhZ2Uoc2Vzc2lvbik7CisJbXNnLnNldEZyb20oInRlc3RAZXhhbXBsZS5jb20iKTsKKwltc2cuc2V0U2VudERhdGUobmV3IERhdGUoKSk7CisJU3RyaW5nIHN1YmplY3QgPSAidGVzdCAiOworCS8vIGVuc3VyZSBlYWNoIG1lc3NhZ2UgaXMgYSBkaWZmZXJlbnQgbGVuZ3RoCisJZm9yIChpbnQgaSA9IDA7IGkgPCBtc2dubzsgaSsrKQorCSAgICBzdWJqZWN0ICs9ICJ0ZXN0ICI7CisJbXNnLnNldFN1YmplY3Qoc3ViamVjdCArIG1zZ25vKTsKKwltc2cuc2V0VGV4dChtc2dubyArICJcbiIpOworCW1zZy5zYXZlQ2hhbmdlcygpOworCXJldHVybiBtc2c7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvbWJveC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9tYm94L01ib3hGb2xkZXJUZXN0LmphdmEgYi9tYm94L3NyYy90ZXN0L2phdmEvY29tL3N1bi9tYWlsL21ib3gvTWJveEZvbGRlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNGNkYzg2Ci0tLSAvZGV2L251bGwKKysrIGIvbWJveC9zcmMvdGVzdC9qYXZhL2NvbS9zdW4vbWFpbC9tYm94L01ib3hGb2xkZXJUZXN0LmphdmEKQEAgLTAsMCArMSw4OCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwOSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworcGFja2FnZSBjb20uc3VuLm1haWwubWJveDsKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLlByaW50V3JpdGVyOworaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOworCitpbXBvcnQgamF2YXgubWFpbC5TZXNzaW9uOworaW1wb3J0IGphdmF4Lm1haWwuU3RvcmU7CitpbXBvcnQgamF2YXgubWFpbC5Gb2xkZXI7CisKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQuQmVmb3JlQ2xhc3M7CitpbXBvcnQgb3JnLmp1bml0LkFmdGVyQ2xhc3M7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RXF1YWxzOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmZhaWw7CisKKy8qKgorICogVGVzdCBvZiBtYm94IGZvbGRlcnMuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBNYm94Rm9sZGVyVGVzdCB7CisKKyAgICBAQmVmb3JlQ2xhc3MKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgYmVmb3JlKCkgeworCVN5c3RlbS5zZXRQcm9wZXJ0eSgibWFpbC5tYm94LmxvY2t0eXBlIiwgIm5vbmUiKTsKKyAgICB9CisKKyAgICBAQWZ0ZXJDbGFzcworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBhZnRlcigpIHsKKwlTeXN0ZW0uZ2V0UHJvcGVydGllcygpLnJlbW92ZSgibWFpbC5tYm94LmxvY2t0eXBlIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdCB0aGF0IGEgbWFpbGJveCB0aGF0IGhhcyBnYXJiYWdlIGF0IHRoZSBiZWdpbm5pbmcKKyAgICAgKiAoc3VjaCBhcyBhIGdyYXR1aXRvdXMgYmxhbmsgbGluZSkgaXMgaGFuZGxlZCB3aXRob3V0CisgICAgICogY3Jhc2hpbmcgYW5kIHdpdGhvdXQgY29ycnVwdGluZyB0aGUgbWFpbGJveC4KKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RHYXJiYWdlQXRTdGFydE9mRm9sZGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJRm9sZGVyIGYgPSBudWxsOworCXRyeSB7CisJICAgIEZpbGUgdGVtcCA9IEZpbGUuY3JlYXRlVGVtcEZpbGUoIm1ib3giLCAiLm1ieCIpOworCSAgICB0ZW1wLmRlbGV0ZU9uRXhpdCgpOworCSAgICBQcmludFdyaXRlciBwdyA9IG5ldyBQcmludFdyaXRlcih0ZW1wKTsKKwkgICAgcHcucHJpbnRsbigpOworCSAgICBwdy5wcmludGxuKCJGcm9tIC0gVHVlIEF1ZyAyMyAxMTo1Njo1MSAyMDExIik7CisJICAgIHB3LnByaW50bG4oKTsKKwkgICAgcHcucHJpbnRsbigidGVzdCIpOworCSAgICBwdy5wcmludGxuKCk7CisJICAgIHB3LmNsb3NlKCk7CisJICAgIGxvbmcgc2l6ZSA9IHRlbXAubGVuZ3RoKCk7CisKKwkgICAgUHJvcGVydGllcyBwcm9wZXJ0aWVzID0gbmV3IFByb3BlcnRpZXMoKTsKKwkgICAgU2Vzc2lvbiBzZXNzaW9uID0gU2Vzc2lvbi5nZXRJbnN0YW5jZShwcm9wZXJ0aWVzKTsKKwkgICAgU3RvcmUgc3RvcmUgPSBzZXNzaW9uLmdldFN0b3JlKCJtYm94Iik7CisJICAgIHN0b3JlLmNvbm5lY3QoKTsKKwkgICAgZiA9IHN0b3JlLmdldEZvbGRlcih0ZW1wLmdldEFic29sdXRlUGF0aCgpKTsKKwkgICAgZi5vcGVuKEZvbGRlci5SRUFEX1dSSVRFKTsKKwkgICAgYXNzZXJ0RXF1YWxzKDAsIGYuZ2V0TWVzc2FnZUNvdW50KCkpOworCSAgICBmLmNsb3NlKHRydWUpOworCSAgICBhc3NlcnRFcXVhbHMoc2l6ZSwgdGVtcC5sZW5ndGgoKSk7CisJfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJICAgIFN5c3RlbS5vdXQucHJpbnRsbihleCk7CisJICAgIC8vZXgucHJpbnRTdGFja1RyYWNlKCk7CisJICAgIGZhaWwoZXgudG9TdHJpbmcoKSk7CisJfSBmaW5hbGx5IHsKKwkgICAgaWYgKGYgIT0gbnVsbCkgeworCQlmLmRlbGV0ZShmYWxzZSk7CisJCWYuZ2V0U3RvcmUoKS5jbG9zZSgpOworCSAgICB9CisJfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL291dGxvb2svcG9tLnhtbCBiL291dGxvb2svcG9tLnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MGExMzMyCi0tLSAvZGV2L251bGwKKysrIGIvb3V0bG9vay9wb20ueG1sCkBAIC0wLDAgKzEsNzQgQEAKKzw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9Imlzby04ODU5LTEiPz4KKzwhLS0KKworICAgIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorCisgICAgVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgICAgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisKKyAgICBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgICAgTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICAgIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICAgIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorCisgICAgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisKKy0tPgorCis8cHJvamVjdCB4bWxucz0iaHR0cDovL21hdmVuLmFwYWNoZS5vcmcvUE9NLzQuMC4wIgorCXhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiCisJeHNpOnNjaGVtYUxvY2F0aW9uPSJodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9QT00vNC4wLjAKKwkJCSAgICBodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9tYXZlbi12NF8wXzAueHNkIj4KKyAgICA8cGFyZW50PgorCTxncm91cElkPmNvbS5zdW4ubWFpbDwvZ3JvdXBJZD4KKwk8YXJ0aWZhY3RJZD5hbGw8L2FydGlmYWN0SWQ+CisJPHZlcnNpb24+MS42LjM8L3ZlcnNpb24+CisgICAgPC9wYXJlbnQ+CisgICAgPG1vZGVsVmVyc2lvbj40LjAuMDwvbW9kZWxWZXJzaW9uPgorICAgIDxncm91cElkPmNvbS5zdW4ubWFpbDwvZ3JvdXBJZD4KKyAgICA8YXJ0aWZhY3RJZD5vdXRsb29rPC9hcnRpZmFjdElkPgorICAgIDxwYWNrYWdpbmc+amFyPC9wYWNrYWdpbmc+CisgICAgPG5hbWU+SmF2YU1haWwgQVBJIGRlbW8gT3V0bG9vayBtZXNzYWdlIHN1cHBvcnQ8L25hbWU+CisKKyAgICA8YnVpbGQ+CisgICAgICAgIDxwbHVnaW5zPgorCSAgICA8IS0tCisJCU5lZWQgdG8gZGlzYWJsZSB0aGUgbWF2ZW4tYnVuZGxlLXBsdWdpbiBiZWNhdXNlIHRoZQorCQluZXcgdmVyc2lvbiBkb2Vzbid0IGxpa2UgY2xhc3NlcyBpbiB0aGUgZGVmYXVsdCBwYWNrYWdlLgorCSAgICAtLT4KKwkgICAgPHBsdWdpbj4KKwkJPGdyb3VwSWQ+b3JnLmFwYWNoZS5mZWxpeDwvZ3JvdXBJZD4KKwkJPGFydGlmYWN0SWQ+bWF2ZW4tYnVuZGxlLXBsdWdpbjwvYXJ0aWZhY3RJZD4KKwkJPGV4ZWN1dGlvbnM+CisJCSAgICA8ZXhlY3V0aW9uPgorCQkJPGlkPm9zZ2ktbWFuaWZlc3Q8L2lkPgorCQkJPHBoYXNlPm5vbmU8L3BoYXNlPgorCQkgICAgPC9leGVjdXRpb24+CisJCTwvZXhlY3V0aW9ucz4KKwkgICAgPC9wbHVnaW4+CisKKwkgICAgPCEtLQorCQlCZWNhdXNlIHRoZSBtYXZlbi1qYXItcGx1Z2luIGRlcGVuZHMgb24gdGhlIG1hbmlmZXN0IGZpbGUKKwkJY3JlYXRlZCBieSB0aGUgbWF2ZW4tYnVuZGxlLXBsdWdpbiwgd2UgbmVlZCB0byBkaXNhYmxlIGl0IHRvby4KKwkgICAgLS0+CisJICAgIDxwbHVnaW4+CisJCTxhcnRpZmFjdElkPm1hdmVuLWphci1wbHVnaW48L2FydGlmYWN0SWQ+CisJCTxleGVjdXRpb25zPgorCQkgICAgPGV4ZWN1dGlvbj4KKwkJCTxpZD5kZWZhdWx0LWphcjwvaWQ+CisJCQk8cGhhc2U+bm9uZTwvcGhhc2U+CisJCSAgICA8L2V4ZWN1dGlvbj4KKwkJPC9leGVjdXRpb25zPgorCSAgICA8L3BsdWdpbj4KKyAgICAgICAgPC9wbHVnaW5zPgorICAgIDwvYnVpbGQ+CisKKyAgICA8ZGVwZW5kZW5jaWVzPgorICAgICAgICA8ZGVwZW5kZW5jeT4KKyAgICAgICAgICAgIDxncm91cElkPmNvbS5zdW4ubWFpbDwvZ3JvdXBJZD4KKyAgICAgICAgICAgIDxhcnRpZmFjdElkPmpha2FydGEubWFpbDwvYXJ0aWZhY3RJZD4KKyAgICAgICAgPC9kZXBlbmRlbmN5PgorICAgIDwvZGVwZW5kZW5jaWVzPgorPC9wcm9qZWN0PgpkaWZmIC0tZ2l0IGEvb3V0bG9vay9zcmMvbWFpbi9qYXZhL01TQm9keVBhcnQuamF2YSBiL291dGxvb2svc3JjL21haW4vamF2YS9NU0JvZHlQYXJ0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGY2NGMwNgotLS0gL2Rldi9udWxsCisrKyBiL291dGxvb2svc3JjL21haW4vamF2YS9NU0JvZHlQYXJ0LmphdmEKQEAgLTAsMCArMSwxMDEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorICovCisKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YXguYWN0aXZhdGlvbi4qOworaW1wb3J0IGphdmF4Lm1haWwuKjsKK2ltcG9ydCBqYXZheC5tYWlsLmludGVybmV0Lio7CisKKy8qKgorICogQSBzcGVjaWFsIE1pbWVCb2R5UGFydCB1c2VkIHdpdGggTVNNZXNzYWdlLgorICoKKyAqIEBhdXRob3IgSm9obiBNYW5pCisgKiBAYXV0aG9yIEJpbGwgU2hhbm5vbgorICovCitwdWJsaWMgY2xhc3MgTVNCb2R5UGFydCBleHRlbmRzIE1pbWVCb2R5UGFydCB7CisgICAgcHJpdmF0ZSBpbnQgc3RhcnQ7CisgICAgcHJpdmF0ZSBpbnQgZW5kOworICAgIHByaXZhdGUgU3RyaW5nIHR5cGUgPSBVTktOT1dOOworICAgIHByaXZhdGUgU3RyaW5nIGRpc3Bvc2l0aW9uOworICAgIHByaXZhdGUgU3RyaW5nIGVuY29kaW5nOworICAgIHByaXZhdGUgU3RyaW5nIGZpbGVuYW1lID0gVU5LTk9XTjsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBVTktOT1dOID0gIlVOS05PV04iOworCisgICAgcHVibGljIE1TQm9keVBhcnQoYnl0ZVtdIGNvbnRlbnQsIGludCBzdGFydCwgaW50IGVuZCwKKwkJU3RyaW5nIGRpc3Bvc2l0aW9uLCBTdHJpbmcgZW5jb2RpbmcpIHsKKwl0aGlzLmNvbnRlbnQgPSBjb250ZW50OworCXRoaXMuc3RhcnQgPSBzdGFydDsKKwl0aGlzLmVuZCA9IGVuZDsKKwl0aGlzLmRpc3Bvc2l0aW9uID0gZGlzcG9zaXRpb247CisJdGhpcy5lbmNvZGluZyA9IGVuY29kaW5nOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q29udGVudFR5cGUoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwkvLyB0cnkgdG8gZmlndXJlIHRoaXMgb3V0IGZyb20gdGhlIGZpbGVuYW1lIGV4dGVuc2lvbgorCWlmICh0eXBlID09IFVOS05PV04pCisJICAgIHByb2Nlc3NCZWdpbigpOworCXJldHVybiB0eXBlOworICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0RW5jb2RpbmcoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gZW5jb2Rpbmc7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXREaXNwb3NpdGlvbigpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXJldHVybiBkaXNwb3NpdGlvbjsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RyaW5nIGdldEZpbGVOYW1lKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJLy8gZ2V0IGZpbGVuYW1lIGZyb20gdGhlICJiZWdpbiIgbGluZQorCWlmIChmaWxlbmFtZSA9PSBVTktOT1dOKQorCSAgICBwcm9jZXNzQmVnaW4oKTsKKwlyZXR1cm4gZmlsZW5hbWU7CisgICAgfQorCisgICAgcHJvdGVjdGVkIElucHV0U3RyZWFtIGdldENvbnRlbnRTdHJlYW0oKSB7CisJcmV0dXJuIG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShjb250ZW50LCBzdGFydCwgZW5kIC0gc3RhcnQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByb2Nlc3MgdGhlICJiZWdpbiIgbGluZSB0byBleHRyYWN0IHRoZSBmaWxlbmFtZSwKKyAgICAgKiBhbmQgZnJvbSBpdCBkZXRlcm1pbmUgdGhlIENvbnRlbnQtVHlwZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcHJvY2Vzc0JlZ2luKCkgeworCUlucHV0U3RyZWFtIGluID0gZ2V0Q29udGVudFN0cmVhbSgpOworCXRyeSB7CisJICAgIEJ1ZmZlcmVkUmVhZGVyIHIgPSBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IElucHV0U3RyZWFtUmVhZGVyKGluKSk7CisJICAgIFN0cmluZyBiZWdpbiA9IHIucmVhZExpbmUoKTsKKwkgICAgLy8gZm9ybWF0IGlzICJiZWdpbiA2NjYgZmlsZW5hbWUudHh0IgorCSAgICBpZiAoYmVnaW4gIT0gbnVsbCAmJiBiZWdpbi5yZWdpb25NYXRjaGVzKHRydWUsIDAsICJiZWdpbiAiLCAwLCA2KSkgeworCQlpbnQgaSA9IGJlZ2luLmluZGV4T2YoJyAnLCA2KTsKKwkJaWYgKGkgPiAwKSB7CisJCSAgICBmaWxlbmFtZSA9IGJlZ2luLnN1YnN0cmluZyhpICsgMSk7CisJCSAgICBGaWxlVHlwZU1hcCBtYXAgPSBGaWxlVHlwZU1hcC5nZXREZWZhdWx0RmlsZVR5cGVNYXAoKTsKKwkJICAgIHR5cGUgPSBtYXAuZ2V0Q29udGVudFR5cGUoZmlsZW5hbWUpOworCQkgICAgaWYgKHR5cGUgPT0gbnVsbCkKKwkJCXR5cGUgPSAiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIjsKKwkJfQorCSAgICB9CisJfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKwkgICAgLy8gaWdub3JlCisJfSBmaW5hbGx5IHsKKwkgICAgdHJ5IHsKKwkJaW4uY2xvc2UoKTsKKwkgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKwkJLy8gaWdub3JlIGl0CisJICAgIH0KKwkgICAgaWYgKGZpbGVuYW1lID09IFVOS05PV04pCisJCWZpbGVuYW1lID0gbnVsbDsKKwkgICAgaWYgKHR5cGUgPT0gVU5LTk9XTiB8fCB0eXBlID09IG51bGwpCisJCXR5cGUgPSAidGV4dC9wbGFpbiI7CisJfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL291dGxvb2svc3JjL21haW4vamF2YS9NU01lc3NhZ2UuamF2YSBiL291dGxvb2svc3JjL21haW4vamF2YS9NU01lc3NhZ2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42ZDkzODc4Ci0tLSAvZGV2L251bGwKKysrIGIvb3V0bG9vay9zcmMvbWFpbi9qYXZhL01TTWVzc2FnZS5qYXZhCkBAIC0wLDAgKzEsMjEwIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBEaXN0cmlidXRpb24gTGljZW5zZSB2LiAxLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9vcmcvZG9jdW1lbnRzL2VkbC12MTAucGhwLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBCU0QtMy1DbGF1c2UKKyAqLworCitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmF4Lm1haWwuKjsKK2ltcG9ydCBqYXZheC5tYWlsLmludGVybmV0Lio7CitpbXBvcnQgamF2YXguYWN0aXZhdGlvbi4qOworCisvKioKKyAqIFRoaXMgY2xhc3MgbW9kZWxzIGEgVVVFbmNvZGVkIE1lc3NhZ2Ugc2VudCBmcm9tIE1TIE91dGxvb2sgZXRjLiA8cD4KKyAqCisgKiBUaGUgbWVzc2FnZSBzdHJ1Y3R1cmUgbG9va3MgbGlrZSB0aGlzIDo9CisgKiAgW3RleHQgYm9keV0gW3V1ZW5jb2RlZCBhdHRhY2htZW50XSoKKyAqIDxwPgorICogaS5lLiwgYW4gb3B0aW9uYWwgdGV4dC9wbGFpbiBtYWluLWJvZHksIGZvbGxvd2VkIGJ5IHplcm8gb3IgbW9yZQorICogVVVFTkNPREUtZWQgYXR0YWNobWVudHMuCisgKgorICogQGF1dGhvciBKb2huIE1hbmkKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKiBAc2VlICAgIGphdmF4Lm1haWwuaW50ZXJuZXQuTWltZU1lc3NhZ2UKKyAqLworCitwdWJsaWMgY2xhc3MgTVNNZXNzYWdlIGV4dGVuZHMgTWltZU1lc3NhZ2UgeworICAgIHByaXZhdGUgU3RyaW5nIHR5cGU7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvciB0aGF0IGNvbnZlcnRzIGEgTWltZU1lc3NhZ2Ugb2JqZWN0IGludG8gYSBNU01lc3NhZ2UuCisgICAgICogCisgICAgICogQGV4Y2VwdGlvbiAgIE1lc3NhZ2luZ0V4Y2VwdGlvbiBpZiB0aGUgZ2l2ZW4gTWltZU1lc3NhZ2UKKyAgICAgKiAgICAgICAgICBpcyBub3QgYSBub24tTUlNRSBNUyBtZXNzYWdlLCBvciBpZiBhbgorICAgICAqICAgICAgICAgIElPRXhjZXB0aW9uIG9jY3VycyB3aGVuIGFjY2Vzc2luZyB0aGUgZ2l2ZW4KKyAgICAgKiAgICAgICAgICBNaW1lTWVzc2FnZSBvYmplY3QKKyAgICAgKi8KKyAgICBwdWJsaWMgTVNNZXNzYWdlKFNlc3Npb24gc2Vzc2lvbiwgTWltZU1lc3NhZ2UgbXNnKSAKKwkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJc3VwZXIoc2Vzc2lvbik7CisKKwlpZiAoIWlzTVNNZXNzYWdlKG1zZykpICAgLy8gc2FuaXR5IGNoZWNrCisJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oIk5vdCBhbiBNUyBtZXNzYWdlIik7CisKKwljbGFzcyBGYXN0Qnl0ZUFycmF5T3V0cHV0U3RyZWFtIGV4dGVuZHMgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIHsKKwkgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gdG9CeXRlQXJyYXlJbnB1dFN0cmVhbSgpIHsKKwkJcmV0dXJuIG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShidWYsIDAsIGNvdW50KTsKKwkgICAgfQorCX0KKworCS8vIGV4dHJhY3QgdGhlIGJ5dGVzIG9mIHRoZSBnaXZlbiBtZXNzYWdlCisJLy8gQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKwlGYXN0Qnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBGYXN0Qnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisJdHJ5IHsKKwkgICAgbXNnLndyaXRlVG8oYm9zKTsKKwl9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2V4KSB7CisJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oIklPRXhjZXB0aW9uIiwgaW9leCk7CisJfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oIkV4Y2VwdGlvbiIsIGV4KTsKKwl9CisJLy9wYXJzZShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYm9zLnRvQnl0ZUFycmF5KCkpKTsKKwlwYXJzZShib3MudG9CeXRlQXJyYXlJbnB1dFN0cmVhbSgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvciB0byBjcmVhdGUgYSBNU01lc3NhZ2UgZnJvbSB0aGUgZ2l2ZW4gSW5wdXRTdHJlYW0uCisgICAgICovCisgICAgcHVibGljIE1TTWVzc2FnZShTZXNzaW9uIHNlc3Npb24sIElucHV0U3RyZWFtIGlzKSAKKwkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJc3VwZXIoc2Vzc2lvbik7IC8vIHNldHVwIGhlYWRlcnN0b3JlIGV0YworCXBhcnNlKGlzKTsKKyAgICB9CisKKyAgICAvLyBwYXJzZSBpbnB1dCBzdHJlYW0KKyAgICBwcm90ZWN0ZWQgdm9pZCBwYXJzZShJbnB1dFN0cmVhbSBpcykgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJLy8gQ3JlYXRlIGEgYnVmZmVyZWQgaW5wdXQgc3RyZWFtIGZvciBlZmZpY2llbmN5CisJaWYgKCEoaXMgaW5zdGFuY2VvZiBCeXRlQXJyYXlJbnB1dFN0cmVhbSkgJiYKKwkgICAgIShpcyBpbnN0YW5jZW9mIEJ1ZmZlcmVkSW5wdXRTdHJlYW0pKQorCSAgICBpcyA9IG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKGlzKTsKKworCS8vIExvYWQgaGVhZGVyc3RvcmUKKwloZWFkZXJzLmxvYWQoaXMpOworCisJLyoKKwkgKiBMb2FkIHRoZSBjb250ZW50IGludG8gYSBieXRlW10uCisJICogVGhpcyBieXRlW10gaXMgc2hhcmVkIGFtb25nIHRoZSBib2R5cGFydHMuCisJICovCisJdHJ5IHsKKwkgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKwkgICAgaW50IGI7CisJICAgIC8vIFhYWCAtIHJvb20gZm9yIHBlcmZvcm1hbmNlIGltcHJvdmVtZW50CisJICAgIHdoaWxlICgoYiA9IGlzLnJlYWQoKSkgIT0gLTEpCisJCWJvcy53cml0ZShiKTsKKwkgICAgY29udGVudCA9IGJvcy50b0J5dGVBcnJheSgpOworCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZXgpIHsKKwkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiSU9FeGNlcHRpb24iLCBpb2V4KTsKKwl9CisKKwkvKgorCSAqIENoZWNrIHdoZXRoZXIgdGhpcyBpcyBtdWx0aXBhcnQuCisJICovCisJYm9vbGVhbiBpc011bHRpID0gZmFsc2U7CisJLy8gY2hlY2sgZm9yIHByZXNlbmNlIG9mIFgtTVMtQXR0YWNobWVudCBoZWFkZXIKKwlTdHJpbmdbXSBhdHQgPSBnZXRIZWFkZXIoIlgtTVMtQXR0YWNobWVudCIpOworCWlmIChhdHQgIT0gbnVsbCAmJiBhdHQubGVuZ3RoID4gMCkKKwkgICAgaXNNdWx0aSA9IHRydWU7CisJZWxzZSB7CisJICAgIC8qCisJICAgICAqIEZhbGwgYmFjayB0byBzY2FubmluZyB0aGUgY29udGVudC4KKwkgICAgICogV2Ugc2NhbiB0aGUgY29udGVudCB1bnRpbCB3ZSBmaW5kIGEgc2VxdWVuY2UgdGhhdCBsb29rcworCSAgICAgKiBsaWtlIHRoZSBzdGFydCBvZiBhIHV1ZW5jb2RlZCBibG9jaywgaS5lLiwgIjxuZXdsaW5lPmJlZ2luIi4KKwkgICAgICogSWYgZm91bmQsIHdlIGNsYWltIHRoYXQgdGhpcyBpcyBhIG11bHRpcGFydCBtZXNzYWdlLgorCSAgICAgKi8KKwkgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb250ZW50Lmxlbmd0aDsgaSsrKSB7CisJCWludCBiID0gY29udGVudFtpXSAmIDB4ZmY7IC8vIG1hc2sgaGlnaGVyIGJ5dGUKKwkJaWYgKGIgPT0gJ1xyJyB8fCBiID09ICdcbicpIHsKKwkJICAgIC8vIHN0YXJ0IG9mIGEgbmV3IGxpbmUKKwkJICAgIGlmICgoaSArIDUpIDwgY29udGVudC5sZW5ndGgpIHsKKwkJCS8vIGNhbiB0aGVyZSBiZSBhICJiZWdpbiIgbm93PworCQkJU3RyaW5nIHMgPSB0b1N0cmluZyhjb250ZW50LCBpKzEsIGkrNik7CisJCQlpZiAocy5lcXVhbHNJZ25vcmVDYXNlKCJiZWdpbiIpKSB7CisJCQkgICAgaXNNdWx0aT0gdHJ1ZTsKKwkJCSAgICBicmVhazsKKwkJCX0KKwkJICAgIH0KKwkJfQorCSAgICB9CisJfQorCisJaWYgKGlzTXVsdGkpIHsKKwkgICAgdHlwZSA9ICJtdWx0aXBhcnQvbWl4ZWQiOworCSAgICBkaCA9IG5ldyBEYXRhSGFuZGxlcihuZXcgTVNNdWx0aXBhcnREYXRhU291cmNlKHRoaXMsIGNvbnRlbnQpKTsKKwl9IGVsc2UgeworCSAgICB0eXBlID0gInRleHQvcGxhaW4iOyAvLyBjaGFyc2V0ID0gPworCSAgICBkaCA9IG5ldyBEYXRhSGFuZGxlcihuZXcgTWltZVBhcnREYXRhU291cmNlKHRoaXMpKTsKKwl9CisKKwltb2RpZmllZCA9IGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiBjb250ZW50LXR5cGUKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldENvbnRlbnRUeXBlKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJcmV0dXJuIHR5cGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIGNvbnRlbnQtZGlzcG9zaXRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldERpc3Bvc2l0aW9uKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJcmV0dXJuICJpbmxpbmUiOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiBjb250ZW50LXRyYW5zZmVyLWVuY29kaW5nCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRFbmNvZGluZygpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXJldHVybiAiN2JpdCI7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2sgd2hldGhlciB0aGUgZ2l2ZW4gTWltZU1lc3NhZ2Ugb2JqZWN0IHJlcHJlc2VudHMgYQorICAgICAqIG5vbi1NSU1FIG1lc3NhZ2Ugc2VudCBieSBPdXRsb29rLiAgU3VjaCBhIG1lc3NhZ2Ugd2lsbAorICAgICAqIGhhdmUgbm8gTUlNRS1WZXJzaW9uIGhlYWRlciwgbWF5IGhhdmUgYW4gWC1NYWlsZXIgaGVhZGVyCisgICAgICogdGhhdCBpbmNsdWRlcyB0aGUgd29yZCAiTWljcm9zb2Z0IiwgYW5kIHdpbGwgaGF2ZSBhdCBsZWFzdAorICAgICAqIG9uZSBYLU1TLUF0dGFjaG1lbnQgaGVhZGVyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc01TTWVzc2FnZShNaW1lTWVzc2FnZSBtc2cpIAorCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJLy8gQ2hlY2sgd2hldGhlciB0aGUgTUlNRSBoZWFkZXIgaXMgcHJlc2VudAorCWlmIChtc2cuZ2V0SGVhZGVyKCJNSU1FLVZlcnNpb24iKSAhPSBudWxsKQorCSAgICAvLyBNSU1FLVZlcnNpb24gaGVhZGVyIHByZXNlbnQsIHNob3VsZCBiZSBhIE1JTUUgbWVzc2FnZQorCSAgICByZXR1cm4gZmFsc2U7CisKKwkvKgorCSAqIFhYWCAtIGRpc2FibGVkIFgtTWFpbGVyIGNoZWNrIGJlY2F1c2UgbWFueSBzYW1wbGUgbWVzc2FnZXMKKwkgKiBJIHNhdyBkaWRuJ3QgaGF2ZSBhbiBYLU1haWxlciBoZWFkZXIgYXQgYWxsLgorCSAqLworCWlmIChmYWxzZSkgeworCS8vIENoZWNrIFgtTWFpbGVyCisJU3RyaW5nIG1haWxlciA9IG1zZy5nZXRIZWFkZXIoIlgtbWFpbGVyIiwgbnVsbCk7CisJaWYgKG1haWxlciA9PSBudWxsKSAvLyBObyBYLW1haWxlciA/IAorCSAgICByZXR1cm4gZmFsc2U7IC8vIE9oIHdlbGwgIQorCWlmIChtYWlsZXIuaW5kZXhPZigiTWljcm9zb2Z0IikgPT0gLTEpIC8vIE5vdCBNUyBzdHVmZiA/CisJICAgIHJldHVybiBmYWxzZTsKKwl9CisKKwkvLyBDaGVjayBYLU1TLUF0dGFjaG1lbnQgaGVhZGVyCisJLy8gWFhYIC0gbm90IGFsbCBzdWNoIG1lc3NhZ2VzIGhhdmUgdGhpcyBoZWFkZXIKKwlTdHJpbmdbXSBhdHQgPSBtc2cuZ2V0SGVhZGVyKCJYLU1TLUF0dGFjaG1lbnQiKTsKKwlpZiAoYXR0ID09IG51bGwgfHwgYXR0Lmxlbmd0aCA9PSAwKQorCSAgICByZXR1cm4gZmFsc2U7CisKKwlyZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvLyBjb252ZXJ0IGdpdmVuIGJ5dGUgYXJyYXkgb2YgQVNDSUkgY2hhcmFjdGVycyB0byBzdHJpbmcKKyAgICBzdGF0aWMgU3RyaW5nIHRvU3RyaW5nKGJ5dGVbXSBiLCBpbnQgc3RhcnQsIGludCBlbmQpIHsKKwlpbnQgc2l6ZSA9IGVuZCAtIHN0YXJ0OworCWNoYXJbXSB0aGVDaGFycyA9IG5ldyBjaGFyW3NpemVdOworCisJZm9yIChpbnQgaSA9IDAsIGogPSBzdGFydDsgaSA8IHNpemU7ICkKKwkgICAgdGhlQ2hhcnNbaSsrXSA9IChjaGFyKWJbaisrXTsKKwlyZXR1cm4gbmV3IFN0cmluZyh0aGVDaGFycyk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvb3V0bG9vay9zcmMvbWFpbi9qYXZhL01TTXVsdGlwYXJ0RGF0YVNvdXJjZS5qYXZhIGIvb3V0bG9vay9zcmMvbWFpbi9qYXZhL01TTXVsdGlwYXJ0RGF0YVNvdXJjZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNjNDZmYzMKLS0tIC9kZXYvbnVsbAorKysgYi9vdXRsb29rL3NyYy9tYWluL2phdmEvTVNNdWx0aXBhcnREYXRhU291cmNlLmphdmEKQEAgLTAsMCArMSwxMDUgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorICovCisKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBqYXZheC5tYWlsLio7CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC4qOworCisvKioKKyAqIEEgc3BlY2lhbCBNdWx0aXBhcnREYXRhU291cmNlIHVzZWQgd2l0aCBNU01lc3NhZ2UuCisgKgorICogQGF1dGhvciBKb2huIE1hbmkKKyAqIEBhdXRob3IgQmlsbCBTaGFubm9uCisgKi8KK3B1YmxpYyBjbGFzcyBNU011bHRpcGFydERhdGFTb3VyY2UgZXh0ZW5kcyBNaW1lUGFydERhdGFTb3VyY2UKKwkJCQlpbXBsZW1lbnRzIE11bHRpcGFydERhdGFTb3VyY2UgeworICAgIC8vcHJpdmF0ZSBMaXN0PE1TQm9keVBhcnQ+IHBhcnRzOworICAgIHByaXZhdGUgTGlzdCBwYXJ0czsKKworICAgIHB1YmxpYyBNU011bHRpcGFydERhdGFTb3VyY2UoTWltZVBhcnQgcGFydCwgYnl0ZVtdIGNvbnRlbnQpCisJCQkJdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJc3VwZXIocGFydCk7CisJLy9wYXJ0cyA9IG5ldyBBcnJheUxpc3Q8TVNCb2R5UGFydD4oKTsKKwlwYXJ0cyA9IG5ldyBBcnJheUxpc3QoKTsKKworCS8qCisJICogUGFyc2UgdGhlIHRleHQgb2YgdGhlIG1lc3NhZ2UgdG8gZmluZCB0aGUgYXR0YWNobWVudHMuCisJICoKKwkgKiBDdXJyZW50bHkgd2UganVzdCBsb29rIGZvciB0aGUgbGluZXMgdGhhdCBtYXJrIHRoZQorCSAqIGJlZ2luIGFuZCBlbmQgb2YgdXVlbmNvZGVkIGRhdGEsIGJ1dCB0aGlzIGNhbiBiZQorCSAqIGZvb2xlZCBieSBzaW1pbGFyIHRleHQgaW4gdGhlIG1lc3NhZ2UgYm9keS4gIEluc3RlYWQsCisJICogd2UgY291bGQgdXNlIHRoZSBFbmNvZGluZyBoZWFkZXIsIHdoaWNoIGluZGljYXRlcyBob3cKKwkgKiBtYW55IGxpbmVzIGFyZSBpbiBlYWNoIGJvZHkgcGFydC4gIEZvciBleGFtcGxlOgorCSAqCisJICogRW5jb2Rpbmc6IDQxIFRFWFQsIDM4IFVVRU5DT0RFLCAzMTU1IFVVRU5DT0RFLCAxMDk2IFVVRU5DT0RFCisJICoKKwkgKiBTaW1pbGFybHksIHdlIGNvdWxkIGdldCB0aGUgZmlsZW5hbWVzIG9mIHRoZSBhdHRhY2htZW50cworCSAqIGZyb20gdGhlIFgtTVMtQXR0YWNobWVudCBoZWFkZXJzLiAgRm9yIGV4YW1wbGU6CisJICoKKwkgKiBYLU1TLUF0dGFjaG1lbnQ6IEFUVDAwMDAwLmh0eCAwIDAwLTAwLTE5ODAgMDA6MDAKKwkgKiBYLU1TLUF0dGFjaG1lbnQ6IFNlcmVuZ2V0aSAyR0cubXBwIDAgMDAtMDAtMTk4MCAwMDowMAorCSAqIFgtTVMtQXR0YWNobWVudDogcHJvamVjdCB0ZWFtIHVwZGF0ZSAwMzEyOTguZG9jIDAgMDAtMDAtMTk4MCAwMDowMAorCSAqCisJICogKE5vdGUgdGhhdCB0aGVyZSBtaWdodCBiZSB1bnF1b3RlZCBzcGFjZXMgaW4gdGhlIGZpbGVuYW1lLikKKwkgKi8KKwlpbnQgcG9zID0gc3RhcnRzV2l0aChjb250ZW50LCAwLCAiYmVnaW4iKTsKKwlpZiAocG9zID09IC0xKQorCSAgICB0aHJvdyBuZXcgTWVzc2FnaW5nRXhjZXB0aW9uKCJpbnZhbGlkIG11bHRpcGFydCIpOworCQorCWlmIChwb3MgPiAwKQkvLyB3ZSBoYXZlIGFuIHVuZW5jb2RlZCBtYWluIGJvZHkgcGFydAorCSAgICBwYXJ0cy5hZGQobmV3IE1TQm9keVBhcnQoY29udGVudCwgMCwgcG9zLCAiaW5saW5lIiwgIjdiaXQiKSk7CisJZWxzZQkJLy8gbm8gbWFpbiBib2R5IHBhcnQKKwkgICAgcG9zID0gMDsKKworCS8vIG5vdyBjb2xsZWN0IGFsbCB0aGUgdXVlbmNvZGVkIGluZGl2aWR1YWwgYm9keSBwYXJ0cworCWludCBzdGFydDsKKwlmb3IgKDs7KSB7CisJICAgIHN0YXJ0ID0gc3RhcnRzV2l0aChjb250ZW50LCBwb3MsICJiZWdpbiIpOworCSAgICBpZiAoc3RhcnQgPT0gLTEpCisJCWJyZWFrOworCSAgICBwb3MgPSBzdGFydHNXaXRoKGNvbnRlbnQsIHN0YXJ0LCAiZW5kIik7CisJICAgIGlmIChwb3MgPT0gLTEpCisJCWJyZWFrOworCSAgICBwb3MgKz0gMzsJLy8gc2tpcCB0byB0aGUgZW5kIG9mICJlbmQiCisJICAgIHBhcnRzLmFkZChuZXcgTVNCb2R5UGFydChjb250ZW50LCBzdGFydCwgcG9zLAorCQkJCQkiYXR0YWNobWVudCIsICJ1dWVuY29kZSIpKTsKKwl9CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRDb3VudCgpIHsKKwlyZXR1cm4gcGFydHMuc2l6ZSgpOworICAgIH0KKworICAgIHB1YmxpYyBCb2R5UGFydCBnZXRCb2R5UGFydChpbnQgaW5kZXgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXJldHVybiAoQm9keVBhcnQpcGFydHMuZ2V0KGluZGV4KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBzY2FucyB0aGUgZ2l2ZW4gYnl0ZVtdLCBiZWdpbm5pbmcgYXQgInN0YXJ0IiwgZm9yCisgICAgICogbGluZXMgdGhhdCBiZWdpbiB3aXRoIHRoZSBzZXF1ZW5jZSAic2VxIi4gIElmIGZvdW5kLCB0aGUgc3RhcnQKKyAgICAgKiBwb3NpdGlvbiBvZiB0aGUgc2VxdWVuY2Ugd2l0aGluIHRoZSBieXRlW10gaXMgcmV0dXJuZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBpbnQgc3RhcnRzV2l0aChieXRlW10gY29udGVudCwgaW50IHN0YXJ0LCBTdHJpbmcgc2VxKSB7CisJaW50IHNsZW4gPSBzZXEubGVuZ3RoKCk7CisJYm9vbGVhbiBib2wgPSB0cnVlOworCWZvciAoaW50IGkgPSBzdGFydDsgaSA8IGNvbnRlbnQubGVuZ3RoOyBpKyspIHsKKwkgICAgaWYgKGJvbCkgeworCQlpZiAoKGkgKyBzbGVuKSA8IGNvbnRlbnQubGVuZ3RoKSB7CisJCSAgICBTdHJpbmcgcyA9IE1TTWVzc2FnZS50b1N0cmluZyhjb250ZW50LCBpLCBpICsgc2xlbik7CisJCSAgICBpZiAocy5lcXVhbHNJZ25vcmVDYXNlKHNlcSkpCisJCQlyZXR1cm4gaTsKKwkJfQorCSAgICB9CisJICAgIGludCBiID0gY29udGVudFtpXSAmIDB4ZmY7CisJICAgIGJvbCA9IGIgPT0gJ1xyJyB8fCBiID09ICdcbic7CisJfQorCXJldHVybiAtMTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9vdXRsb29rL3NyYy9tYWluL2phdmEvUkVBRE1FLnR4dCBiL291dGxvb2svc3JjL21haW4vamF2YS9SRUFETUUudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM2Y2RlYTUKLS0tIC9kZXYvbnVsbAorKysgYi9vdXRsb29rL3NyYy9tYWluL2phdmEvUkVBRE1FLnR4dApAQCAtMCwwICsxLDkgQEAKK1RoZSBjbGFzc2VzIGluIHRoaXMgZGlyZWN0b3J5IGFsbG93IHByb2Nlc3Npbmcgb2xkIHN0eWxlIG5vbi1NSU1FCittZXNzYWdlcyBjcmVhdGVkIGJ5IE1pY3Jvc29mdCBPdXRsb29rLiAgVXNlIHRoZW0gbGlrZSB0aGlzOgorCisJaWYgKE1TTWVzc2FnZS5pc01TTWVzc2FnZShtc2cpKQorCSAgICBtc2cgPSBuZXcgTVNNZXNzYWdlKHNlc3Npb24sIG1zZyk7CisKK05vdGUgdGhhdCB0aGVzZSBjbGFzc2VzIGFyZSBub3QgcGFydGljdWxhcmx5IGVmZmljaWVudCBvciBvcHRpbWl6ZWQsCitidXQgdGhleSBzaG93IGhvdyB0byBwcm9jZXNzIHRoZXNlIG5vbi1NSU1FIG1lc3NhZ2VzIGFuZCBtYWtlIHRoZW0KK2xvb2sgbGlrZSBNSU1FIG1lc3NhZ2VzLgpkaWZmIC0tZ2l0IGEvcGFyZW50LWRpc3RyaWIvcG9tLnhtbCBiL3BhcmVudC1kaXN0cmliL3BvbS54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWEzMmY3NgotLS0gL2Rldi9udWxsCisrKyBiL3BhcmVudC1kaXN0cmliL3BvbS54bWwKQEAgLTAsMCArMSwxNjggQEAKKzw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9Imlzby04ODU5LTEiPz4KKzwhLS0KKworICAgIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorCisgICAgVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgICAgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisKKyAgICBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgICAgTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICAgIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICAgIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorCisgICAgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisKKy0tPgorCis8cHJvamVjdCB4bWxucz0iaHR0cDovL21hdmVuLmFwYWNoZS5vcmcvUE9NLzQuMC4wIgorCXhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiCisJeHNpOnNjaGVtYUxvY2F0aW9uPSJodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9QT00vNC4wLjAKKwkJCSAgICBodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9tYXZlbi12NF8wXzAueHNkIj4KKyAgICA8cGFyZW50PgorCTxncm91cElkPmNvbS5zdW4ubWFpbDwvZ3JvdXBJZD4KKwk8YXJ0aWZhY3RJZD5hbGw8L2FydGlmYWN0SWQ+CisJPHZlcnNpb24+MS42LjM8L3ZlcnNpb24+CisgICAgPC9wYXJlbnQ+CisgICAgPG1vZGVsVmVyc2lvbj40LjAuMDwvbW9kZWxWZXJzaW9uPgorICAgIDxncm91cElkPmNvbS5zdW4ubWFpbDwvZ3JvdXBJZD4KKyAgICA8YXJ0aWZhY3RJZD5wYXJlbnQtZGlzdHJpYjwvYXJ0aWZhY3RJZD4KKyAgICA8cGFja2FnaW5nPnBvbTwvcGFja2FnaW5nPgorICAgIDxuYW1lPkphdmFNYWlsIEFQSSAke3Byb2plY3QuYXJ0aWZhY3RJZH0gcHJvdmlkZXI8L25hbWU+CisKKyAgICA8cHJvcGVydGllcz4KKwk8bWFpbC5jbGFzc2VzPmNvbS9zdW4vbWFpbC8ke3Byb2plY3QuYXJ0aWZhY3RJZH0vKio8L21haWwuY2xhc3Nlcz4KKyAgICA8L3Byb3BlcnRpZXM+CisKKyAgICA8cHJvZmlsZXM+CisJPCEtLQorCSAgICBBIHNwZWNpYWwgcHJvZmlsZSBmb3IgY29tcGlsaW5nIHdpdGggSkRLIDkuCisJLS0+CisJPHByb2ZpbGU+CisJICAgIDxpZD45PC9pZD4KKwkgICAgPGFjdGl2YXRpb24+CisJCTxqZGs+OTwvamRrPgorCSAgICA8L2FjdGl2YXRpb24+CisJICAgIDxidWlsZD4KKwkJPHBsdWdpbnM+CisJCSAgICA8cGx1Z2luPgorCQkJPGFydGlmYWN0SWQ+bWF2ZW4tY29tcGlsZXItcGx1Z2luPC9hcnRpZmFjdElkPgorCQkJPGV4ZWN1dGlvbnM+CisJCQkgICAgPGV4ZWN1dGlvbj4KKwkJCQk8aWQ+ZGVmYXVsdC1jb21waWxlPC9pZD4KKwkJCQk8Y29uZmlndXJhdGlvbj4KKwkJCQkgICAgPHJlbGVhc2U+OTwvcmVsZWFzZT4KKwkJCQkgICAgPHNvdXJjZT45PC9zb3VyY2U+CisJCQkJICAgIDx0YXJnZXQ+OTwvdGFyZ2V0PgorCQkJCSAgICA8Y29tcGlsZXJBcmdzPgorCQkJCQk8YXJnPi1YbGludDwvYXJnPgorCQkJCQk8YXJnPi1YbGludDotb3B0aW9uczwvYXJnPgorCQkJCQk8YXJnPi1YbGludDotcGF0aDwvYXJnPgorCQkJCQk8IS0tCisJCQkJCSAgICBUb28gbWFueSBmaW5hbGl6ZSB3YXJuaW5ncy4KKwkJCQkJPGFyZz4tV2Vycm9yPC9hcmc+CisJCQkJCS0tPgorCQkJCSAgICA8L2NvbXBpbGVyQXJncz4KKwkJCQkgICAgPCEtLSB1bi1leGNsdWRlIG1vZHVsZS1pbmZvLmphdmEgLS0+CisJCQkJICAgIDxleGNsdWRlcyBjb21iaW5lLnNlbGY9Im92ZXJyaWRlIj4KKwkJCQkgICAgPC9leGNsdWRlcz4KKwkJCQk8L2NvbmZpZ3VyYXRpb24+CisJCQkgICAgPC9leGVjdXRpb24+CisJCQk8L2V4ZWN1dGlvbnM+CisJCSAgICA8L3BsdWdpbj4KKwkJICAgIDwhLS0KKwkJCVJlcXVpcmUgSkRLIDkuCisJCSAgICAtLT4KKwkJICAgIDxwbHVnaW4+CisJCQk8Z3JvdXBJZD5vcmcuYXBhY2hlLm1hdmVuLnBsdWdpbnM8L2dyb3VwSWQ+CisJCQk8YXJ0aWZhY3RJZD5tYXZlbi1lbmZvcmNlci1wbHVnaW48L2FydGlmYWN0SWQ+CisJCQk8ZXhlY3V0aW9ucz4KKwkJCSAgICA8ZXhlY3V0aW9uPgorCQkJCTxpZD5lbmZvcmNlLXZlcnNpb248L2lkPgorCQkJCTxnb2Fscz4KKwkJCQkgICAgPGdvYWw+ZW5mb3JjZTwvZ29hbD4KKwkJCQk8L2dvYWxzPgorCQkJCTxjb25maWd1cmF0aW9uPgorCQkJCSAgICA8cnVsZXM+CisJCQkJCTxyZXF1aXJlTWF2ZW5WZXJzaW9uPgorCQkJCQkgICAgPHZlcnNpb24+WzMuMC4zLCk8L3ZlcnNpb24+CisJCQkJCTwvcmVxdWlyZU1hdmVuVmVyc2lvbj4KKwkJCQkJPHJlcXVpcmVKYXZhVmVyc2lvbj4KKwkJCQkJICAgIDx2ZXJzaW9uPjk8L3ZlcnNpb24+CisJCQkJCTwvcmVxdWlyZUphdmFWZXJzaW9uPgorCQkJCSAgICA8L3J1bGVzPgorCQkJCTwvY29uZmlndXJhdGlvbj4KKwkJCSAgICA8L2V4ZWN1dGlvbj4KKwkJCTwvZXhlY3V0aW9ucz4KKwkJICAgIDwvcGx1Z2luPgorCQk8L3BsdWdpbnM+CisJICAgIDwvYnVpbGQ+CisJPC9wcm9maWxlPgorICAgIDwvcHJvZmlsZXM+CisKKyAgICA8YnVpbGQ+CisgICAgICAgIDxwbHVnaW5zPgorCSAgICA8cGx1Z2luPgorCQk8YXJ0aWZhY3RJZD5tYXZlbi1kZXBlbmRlbmN5LXBsdWdpbjwvYXJ0aWZhY3RJZD4KKwkJPGV4ZWN1dGlvbnM+CisJCSAgICA8ZXhlY3V0aW9uPgorCQkJPCEtLSBkb3dubG9hZCB0aGUgYmluYXJpZXMgLS0+CisJCQk8aWQ+Z2V0LWJpbmFyaWVzPC9pZD4KKwkJCTxwaGFzZT5nZW5lcmF0ZS1zb3VyY2VzPC9waGFzZT4KKwkJCTxnb2Fscz4KKwkJCSAgICA8Z29hbD51bnBhY2s8L2dvYWw+CisJCQk8L2dvYWxzPgorCQkgICAgPC9leGVjdXRpb24+CisJCSAgICA8ZXhlY3V0aW9uPgorCQkJPCEtLSBkb3dubG9hZCB0aGUgc291cmNlcyAtLT4KKwkJCTxpZD5nZXQtc291cmNlczwvaWQ+CisJCQk8cGhhc2U+Z2VuZXJhdGUtc291cmNlczwvcGhhc2U+CisJCQk8Z29hbHM+CisJCQkgICAgPGdvYWw+dW5wYWNrPC9nb2FsPgorCQkJPC9nb2Fscz4KKwkJCTxjb25maWd1cmF0aW9uPgorCQkJICAgIDxhcnRpZmFjdEl0ZW1zPgorCQkJCTxhcnRpZmFjdEl0ZW0+CisJCQkJICAgIDxncm91cElkPmNvbS5zdW4ubWFpbDwvZ3JvdXBJZD4KKwkJCQkgICAgPGFydGlmYWN0SWQ+amFrYXJ0YS5tYWlsPC9hcnRpZmFjdElkPgorCQkJCSAgICA8dmVyc2lvbj4ke21haWwudmVyc2lvbn08L3ZlcnNpb24+CisJCQkJICAgIDxjbGFzc2lmaWVyPnNvdXJjZXM8L2NsYXNzaWZpZXI+CisJCQkJICAgIDxvdXRwdXREaXJlY3Rvcnk+CisJCQkJCSR7cHJvamVjdC5idWlsZC5kaXJlY3Rvcnl9L3NvdXJjZXMKKwkJCQkgICAgPC9vdXRwdXREaXJlY3Rvcnk+CisJCQkJPC9hcnRpZmFjdEl0ZW0+CisJCQkgICAgPC9hcnRpZmFjdEl0ZW1zPgorCQkJPC9jb25maWd1cmF0aW9uPgorCQkgICAgPC9leGVjdXRpb24+CisJCTwvZXhlY3V0aW9ucz4KKwkJPGNvbmZpZ3VyYXRpb24+CisJCSAgICA8YXJ0aWZhY3RJdGVtcz4KKwkJCTxhcnRpZmFjdEl0ZW0+CisJCQkgICAgPGdyb3VwSWQ+Y29tLnN1bi5tYWlsPC9ncm91cElkPgorCQkJICAgIDxhcnRpZmFjdElkPmpha2FydGEubWFpbDwvYXJ0aWZhY3RJZD4KKwkJCSAgICA8dmVyc2lvbj4ke21haWwudmVyc2lvbn08L3ZlcnNpb24+CisJCQk8L2FydGlmYWN0SXRlbT4KKwkJICAgIDwvYXJ0aWZhY3RJdGVtcz4KKwkJICAgIDxvdXRwdXREaXJlY3Rvcnk+CisJCQkke3Byb2plY3QuYnVpbGQub3V0cHV0RGlyZWN0b3J5fQorCQkgICAgPC9vdXRwdXREaXJlY3Rvcnk+CisJCSAgICA8aW5jbHVkZXM+CisJCQlNRVRBLUlORi9MSUNFTlNFLnR4dCwKKwkJCSR7bWFpbC5jbGFzc2VzfSwKKwkJCSR7bWFpbC5leHRyYUNsYXNzZXN9CisJCSAgICA8L2luY2x1ZGVzPgorCQk8L2NvbmZpZ3VyYXRpb24+CisJICAgIDwvcGx1Z2luPgorICAgICAgICA8L3BsdWdpbnM+CisgICAgPC9idWlsZD4KKworICAgIDxkZXBlbmRlbmNpZXM+CisJPGRlcGVuZGVuY3k+CisJICAgIDxncm91cElkPmNvbS5zdW4ubWFpbDwvZ3JvdXBJZD4KKwkgICAgPGFydGlmYWN0SWQ+bWFpbGFwaTwvYXJ0aWZhY3RJZD4KKwkgICAgPHZlcnNpb24+JHttYWlsLnZlcnNpb259PC92ZXJzaW9uPgorCTwvZGVwZW5kZW5jeT4KKyAgICA8L2RlcGVuZGVuY2llcz4KKzwvcHJvamVjdD4KZGlmZiAtLWdpdCBhL3BvbS54bWwgYi9wb20ueG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU4ZWZkYzAKLS0tIC9kZXYvbnVsbAorKysgYi9wb20ueG1sCkBAIC0wLDAgKzEsOTE5IEBACis8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJpc28tODg1OS0xIj8+Cis8IS0tCisKKyAgICBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKworICAgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICAgIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorCisgICAgVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICAgIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAgICBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAgICB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKworICAgIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorCistLT4KKworPHByb2plY3QgeG1sbnM9Imh0dHA6Ly9tYXZlbi5hcGFjaGUub3JnL1BPTS80LjAuMCIKKwl4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIgorCXhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL21hdmVuLmFwYWNoZS5vcmcvUE9NLzQuMC4wCisJCQkgICAgaHR0cDovL21hdmVuLmFwYWNoZS5vcmcvbWF2ZW4tdjRfMF8wLnhzZCI+CisgICAgPHBhcmVudD4KKwk8Z3JvdXBJZD5vcmcuZWNsaXBzZS5lZTRqPC9ncm91cElkPgorCTxhcnRpZmFjdElkPnByb2plY3Q8L2FydGlmYWN0SWQ+CisJPHZlcnNpb24+MS4wLjQ8L3ZlcnNpb24+CisgICAgPC9wYXJlbnQ+CisgICAgPG1vZGVsVmVyc2lvbj40LjAuMDwvbW9kZWxWZXJzaW9uPgorICAgIDxncm91cElkPmNvbS5zdW4ubWFpbDwvZ3JvdXBJZD4KKyAgICA8YXJ0aWZhY3RJZD5hbGw8L2FydGlmYWN0SWQ+CisgICAgPHBhY2thZ2luZz5wb208L3BhY2thZ2luZz4KKyAgICA8dmVyc2lvbj4xLjYuMzwvdmVyc2lvbj4KKyAgICA8bmFtZT5KYXZhTWFpbCBBUEkgZGlzdHJpYnV0aW9uPC9uYW1lPgorICAgIDxkZXNjcmlwdGlvbj4ke3Byb2plY3QubmFtZX08L2Rlc2NyaXB0aW9uPgorICAgIDx1cmw+aHR0cDovL2VjbGlwc2UtZWU0ai5naXRodWIuaW8vamF2YW1haWw8L3VybD4KKworICAgIDxzY20+CisJPGNvbm5lY3Rpb24+c2NtOmdpdDpzc2g6Ly9naXRAZ2l0aHViLmNvbS9lY2xpcHNlLWVlNGovamF2YW1haWwuZ2l0PC9jb25uZWN0aW9uPgorCTxkZXZlbG9wZXJDb25uZWN0aW9uPnNjbTpnaXQ6c3NoOi8vZ2l0QGdpdGh1Yi5jb20vZWNsaXBzZS1lZTRqL2phdmFtYWlsLmdpdDwvZGV2ZWxvcGVyQ29ubmVjdGlvbj4KKwk8dXJsPmh0dHBzOi8vZ2l0aHViLmNvbS9lY2xpcHNlLWVlNGovamF2YW1haWw8L3VybD4KKyAgICA8L3NjbT4KKworICAgIDxpc3N1ZU1hbmFnZW1lbnQ+CisJPHN5c3RlbT5HaXRIdWI8L3N5c3RlbT4KKwk8dXJsPmh0dHBzOi8vZ2l0aHViLmNvbS9lY2xpcHNlLWVlNGovamF2YW1haWwvaXNzdWVzPC91cmw+CisgICAgPC9pc3N1ZU1hbmFnZW1lbnQ+CisKKyAgICA8bGljZW5zZXM+CisJPGxpY2Vuc2U+CisJICAgIDxuYW1lPkVQTCAyLjA8L25hbWU+CisJICAgIDx1cmw+aHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wPC91cmw+CisJICAgIDxkaXN0cmlidXRpb24+cmVwbzwvZGlzdHJpYnV0aW9uPgorCTwvbGljZW5zZT4KKwk8bGljZW5zZT4KKwkgICAgPG5hbWU+R1BMMiB3LyBDUEU8L25hbWU+CisJICAgIDx1cmw+aHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sPC91cmw+CisJICAgIDxkaXN0cmlidXRpb24+cmVwbzwvZGlzdHJpYnV0aW9uPgorCTwvbGljZW5zZT4KKwk8bGljZW5zZT4KKwkgICAgPG5hbWU+RURMIDEuMDwvbmFtZT4KKwkgICAgPHVybD5odHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHA8L3VybD4KKwkgICAgPGRpc3RyaWJ1dGlvbj5yZXBvPC9kaXN0cmlidXRpb24+CisJPC9saWNlbnNlPgorICAgIDwvbGljZW5zZXM+CisKKyAgICA8b3JnYW5pemF0aW9uPgorCTxuYW1lPk9yYWNsZTwvbmFtZT4KKwk8dXJsPmh0dHA6Ly93d3cub3JhY2xlLmNvbTwvdXJsPgorICAgIDwvb3JnYW5pemF0aW9uPgorCisgICAgPHByb3BlcnRpZXM+CisJPG1haWwudmVyc2lvbj4xLjYuMzwvbWFpbC52ZXJzaW9uPgorCTwhLS0gbGlrZSBtYWlsLnZlcnNpb24sIGJ1dCB3aXRoIHVuZGVyc2NvcmVzIGluc3RlYWQgb2YgZG90cyAtLT4KKwk8bWFpbC56aXB2ZXJzaW9uPjFfNl8zPC9tYWlsLnppcHZlcnNpb24+CisJPG1haWwuc3BlYy52ZXJzaW9uPjEuNjwvbWFpbC5zcGVjLnZlcnNpb24+CisJPGFjdGl2YXRpb24udmVyc2lvbj4xLjIuMTwvYWN0aXZhdGlvbi52ZXJzaW9uPgorCTwhLS0gZGVmYXVsdHMgdGhhdCBhcmUgb3ZlcnJpZGRlbiBpbiBtYWlsIG1vZHVsZSAtLT4KKwk8bWFpbC5leHRlbnNpb25OYW1lPgorCSAgICAke3Byb2plY3QuZ3JvdXBJZH0uJHtwcm9qZWN0LmFydGlmYWN0SWR9CisJPC9tYWlsLmV4dGVuc2lvbk5hbWU+CisJPG1haWwuc3BlY2lmaWNhdGlvblRpdGxlPgorCSAgICAke3Byb2plY3QuZ3JvdXBJZH0uJHtwcm9qZWN0LmFydGlmYWN0SWR9CisJPC9tYWlsLnNwZWNpZmljYXRpb25UaXRsZT4KKwk8bWFpbC5pbXBsZW1lbnRhdGlvblRpdGxlPgorCSAgICAke3Byb2plY3QuZ3JvdXBJZH0uJHtwcm9qZWN0LmFydGlmYWN0SWR9CisJPC9tYWlsLmltcGxlbWVudGF0aW9uVGl0bGU+CisJPG1haWwuYnVuZGxlLnN5bWJvbGljTmFtZT4KKwkgICAgJHtwcm9qZWN0Lmdyb3VwSWR9LiR7cHJvamVjdC5hcnRpZmFjdElkfQorCTwvbWFpbC5idW5kbGUuc3ltYm9saWNOYW1lPgorCTxtYWlsLnBhY2thZ2VzLmV4cG9ydD4KKwkgICAgamF2YXgubWFpbC4qOyB2ZXJzaW9uPSR7bWFpbC5zcGVjLnZlcnNpb259CisJPC9tYWlsLnBhY2thZ2VzLmV4cG9ydD4KKwk8bWFpbC5wYWNrYWdlcy5pbXBvcnQ+CisJICAgIGphdmF4LmFjdGl2YXRpb247dmVyc2lvbj0hLAorCSAgICBqYXZheC5zZWN1cml0eS5zYXNsO3Jlc29sdXRpb246PW9wdGlvbmFsLAorCSAgICBzdW4uc2VjdXJpdHkudXRpbDtyZXNvbHV0aW9uOj1vcHRpb25hbCwKKwkgICAgKgorCTwvbWFpbC5wYWNrYWdlcy5pbXBvcnQ+CisJPG1haWwucGFja2FnZXMucHJpdmF0ZT4KKwkgICAgY29tLnN1bi5tYWlsLioKKwk8L21haWwucGFja2FnZXMucHJpdmF0ZT4KKwk8bWFpbC5wcm9iZUZpbGUvPgorCTwhLS0gZm9yIHRoZSBvc2dpdmVyc2lvbi1tYXZlbi1wbHVnaW4gLS0+CisJPGhrMi5wbHVnaW4udmVyc2lvbj4yLjAuMDwvaGsyLnBsdWdpbi52ZXJzaW9uPgorCTxqYXZhYy5wYXRoPi9vcHQvamRrMS43L2Jpbi9qYXZhYzwvamF2YWMucGF0aD4KKwk8cHJvamVjdC5idWlsZC5zb3VyY2VFbmNvZGluZz5pc28tODg1OS0xPC9wcm9qZWN0LmJ1aWxkLnNvdXJjZUVuY29kaW5nPgorCTxmaW5kYnVncy50aHJlc2hvbGQ+CisJICAgIEhpZ2gKKwk8L2ZpbmRidWdzLnRocmVzaG9sZD4KKwk8ZmluZGJ1Z3MudmVyc2lvbj4KKwkgICAgMy4xLjAKKwk8L2ZpbmRidWdzLnZlcnNpb24+CisJPGZpbmRidWdzLnNraXA+CisJICAgIHRydWUKKwk8L2ZpbmRidWdzLnNraXA+CisJPGZpbmRidWdzLmV4Y2x1ZGUvPgorICAgICAgICA8Y29weXJpZ2h0LXBsdWdpbi52ZXJzaW9uPjEuNDY8L2NvcHlyaWdodC1wbHVnaW4udmVyc2lvbj4KKyAgICA8L3Byb3BlcnRpZXM+CisKKyAgICA8ZGV2ZWxvcGVycz4KKwk8ZGV2ZWxvcGVyPgorCSAgICA8aWQ+c2hhbm5vbjwvaWQ+CisJICAgIDxuYW1lPkJpbGwgU2hhbm5vbjwvbmFtZT4KKwkgICAgPGVtYWlsPmJpbGwuc2hhbm5vbkBvcmFjbGUuY29tPC9lbWFpbD4KKwkgICAgPG9yZ2FuaXphdGlvbj5PcmFjbGU8L29yZ2FuaXphdGlvbj4KKwkgICAgPHJvbGVzPgorCQk8cm9sZT5sZWFkPC9yb2xlPgorCSAgICA8L3JvbGVzPgorCTwvZGV2ZWxvcGVyPgorICAgIDwvZGV2ZWxvcGVycz4KKworICAgIDwhLS0gZm9sbG93aW5nIHRvIGVuYWJsZSB1c2Ugb2YgIm12biBzaXRlOnN0YWdlIiAtLT4KKyAgICA8ZGlzdHJpYnV0aW9uTWFuYWdlbWVudD4KKwk8c2l0ZT4KKwkgICAgPGlkPm9yYWNsZS5jb208L2lkPgorCSAgICA8dXJsPmZpbGU6L3RtcDwvdXJsPiA8IS0tIG5vdCB1c2VkIC0tPgorCTwvc2l0ZT4KKyAgICA8L2Rpc3RyaWJ1dGlvbk1hbmFnZW1lbnQ+CisKKyAgICA8bW9kdWxlcz4KKwk8bW9kdWxlPm1haWw8L21vZHVsZT4KKwk8bW9kdWxlPm1haWxhcGk8L21vZHVsZT4KKwk8bW9kdWxlPm1haWxhcGlqYXI8L21vZHVsZT4KKwk8bW9kdWxlPnNtdHA8L21vZHVsZT4KKwk8bW9kdWxlPmltYXA8L21vZHVsZT4KKwk8bW9kdWxlPmdpbWFwPC9tb2R1bGU+CisJPG1vZHVsZT5wb3AzPC9tb2R1bGU+CisJPG1vZHVsZT5kc248L21vZHVsZT4KKwk8bW9kdWxlPm1haWxoYW5kbGVyPC9tb2R1bGU+CisJPG1vZHVsZT5hbmRyb2lkPC9tb2R1bGU+CisgICAgPC9tb2R1bGVzPgorCisgICAgPHByb2ZpbGVzPgorCTwhLS0KKwkgICAgVGhpcyBwcm9maWxlIGNvbnRhaW5zIG1vZHVsZXMgdGhhdCBzaG91bGQgb25seSBiZSBidWlsdAorCSAgICBidXQgbm90IGluc3RhbGxlZCBvciBkZXBsb3llZC4KKwktLT4KKwk8cHJvZmlsZT4KKwkgICAgPGlkPmJ1aWxkLW9ubHk8L2lkPgorCSAgICA8bW9kdWxlcz4KKwkJPG1vZHVsZT5tYm94PC9tb2R1bGU+CisJCTxtb2R1bGU+ZGVtbzwvbW9kdWxlPgorCQk8bW9kdWxlPmNsaWVudDwvbW9kdWxlPgorCQk8bW9kdWxlPnNlcnZsZXQ8L21vZHVsZT4KKwkJPG1vZHVsZT53ZWJhcHA8L21vZHVsZT4KKwkJPG1vZHVsZT50YWdsaWI8L21vZHVsZT4KKwkJPG1vZHVsZT5sb2dnaW5nPC9tb2R1bGU+CisJCTxtb2R1bGU+b3V0bG9vazwvbW9kdWxlPgorCQk8bW9kdWxlPmphdmFkb2M8L21vZHVsZT4KKwkJPG1vZHVsZT5wdWJsaXNoPC9tb2R1bGU+CisJICAgIDwvbW9kdWxlcz4KKwkgICAgPGFjdGl2YXRpb24+CisJCTxhY3RpdmVCeURlZmF1bHQ+dHJ1ZTwvYWN0aXZlQnlEZWZhdWx0PgorCSAgICA8L2FjdGl2YXRpb24+CisJPC9wcm9maWxlPgorCisJPCEtLQorCSAgICBUaGlzIHByb2ZpbGUgaXMgdXNlZCBmb3IgZGVwbG95aW5nIGEgSmF2YU1haWwgZmluYWwgcmVsZWFzZS4KKworCSAgICBBY3RpdmF0aW5nIHRoaXMgcHJvZmlsZSBtYW51YWxseSBmb3IgZGVwbG95bWVudCBjYXVzZXMKKwkgICAgdGhlIGFib3ZlIHByb2ZpbGUgdG8gYmUgZGVhY3RpdmF0ZWQsIHdoaWNoIHdvcmtzIGFyb3VuZAorCSAgICBhbiBhcHBhcmVudCBidWcgaW4gbWF2ZW4gdGhhdCBwcmV2ZW50cyBtZSBmcm9tIG1hbnVhbGx5CisJICAgIGRlYWN0aXZhdGluZyBhIHByb2ZpbGUuICBUaGlzIHByb2ZpbGUgcHVycG9zZWx5IGhhcyBub25lCisJICAgIG9mIHRoZSBtb2R1bGVzIEkgZG9uJ3Qgd2FudCB0byBiZSBkZXBsb3llZC4KKwktLT4KKwk8cHJvZmlsZT4KKwkgICAgPGlkPmRlcGxveS1yZWxlYXNlPC9pZD4KKwkgICAgPG1vZHVsZXM+CisJCTxtb2R1bGU+cGFyZW50LWRpc3RyaWI8L21vZHVsZT4KKwkgICAgPC9tb2R1bGVzPgorCSAgICA8YnVpbGQ+CisJCTxwbHVnaW5NYW5hZ2VtZW50PgorCQkgICAgPHBsdWdpbnM+CisJCQk8cGx1Z2luPgorCQkJICAgIDwhLS0gRW5hYmxlcyBzdGVwLWJ5LXN0ZXAgc3RhZ2luZyBkZXBsb3ltZW50IC0tPgorCQkJICAgIDxncm91cElkPm9yZy5zb25hdHlwZS5wbHVnaW5zPC9ncm91cElkPgorCQkJICAgIDxhcnRpZmFjdElkPm5leHVzLXN0YWdpbmctbWF2ZW4tcGx1Z2luPC9hcnRpZmFjdElkPgorCQkJICAgIDx2ZXJzaW9uPjEuNi43PC92ZXJzaW9uPgorCQkJPC9wbHVnaW4+CisJCQk8cGx1Z2luPgorCQkJICAgIDwhLS0gTmV3ZXIgdmVyc2lvbiB0aGVuIGluIHBhcmVudCAtLT4KKwkJCSAgICA8Z3JvdXBJZD5vcmcuYXBhY2hlLm1hdmVuLnBsdWdpbnM8L2dyb3VwSWQ+CisJCQkgICAgPGFydGlmYWN0SWQ+bWF2ZW4tZ3BnLXBsdWdpbjwvYXJ0aWZhY3RJZD4KKwkJCSAgICA8dmVyc2lvbj4xLjY8L3ZlcnNpb24+CisJCQk8L3BsdWdpbj4KKwkJICAgIDwvcGx1Z2lucz4KKwkJPC9wbHVnaW5NYW5hZ2VtZW50PgorCQk8cGx1Z2lucz4KKwkJICAgIDxwbHVnaW4+CisJCQk8Z3JvdXBJZD5vcmcuYXBhY2hlLm1hdmVuLnBsdWdpbnM8L2dyb3VwSWQ+CisJCQk8YXJ0aWZhY3RJZD5tYXZlbi1zdXJlZmlyZS1wbHVnaW48L2FydGlmYWN0SWQ+CisJCQk8Y29uZmlndXJhdGlvbj4KKwkJCSAgICA8c2tpcD50cnVlPC9za2lwPgorCQkJPC9jb25maWd1cmF0aW9uPgorCQkgICAgPC9wbHVnaW4+CisKKwkJICAgIDxwbHVnaW4+CisJCQk8Z3JvdXBJZD5vcmcuYXBhY2hlLm1hdmVuLnBsdWdpbnM8L2dyb3VwSWQ+CisJCQk8YXJ0aWZhY3RJZD5tYXZlbi1qYXZhZG9jLXBsdWdpbjwvYXJ0aWZhY3RJZD4KKwkJCTxleGVjdXRpb25zPgorCQkJICAgIDxleGVjdXRpb24+CisJCQkJPGlkPmF0dGFjaC1qYXZhZG9jczwvaWQ+CisJCQkJPGdvYWxzPgorCQkJCSAgICA8Z29hbD5qYXI8L2dvYWw+CisJCQkJPC9nb2Fscz4KKwkJCSAgICA8L2V4ZWN1dGlvbj4KKwkJCTwvZXhlY3V0aW9ucz4KKwkJICAgIDwvcGx1Z2luPgorCisJCSAgICA8cGx1Z2luPgorCQkJPGdyb3VwSWQ+b3JnLmFwYWNoZS5tYXZlbi5wbHVnaW5zPC9ncm91cElkPgorCQkJPGFydGlmYWN0SWQ+bWF2ZW4tZ3BnLXBsdWdpbjwvYXJ0aWZhY3RJZD4KKwkJCTxleGVjdXRpb25zPgorCQkJICAgIDxleGVjdXRpb24+CisJCQkJPGlkPnNpZ24tYXJ0aWZhY3RzPC9pZD4KKwkJCQk8cGhhc2U+dmVyaWZ5PC9waGFzZT4KKwkJCQk8Z29hbHM+CisJCQkJICAgIDxnb2FsPnNpZ248L2dvYWw+CisJCQkJPC9nb2Fscz4KKwkJCSAgICA8L2V4ZWN1dGlvbj4KKwkJCTwvZXhlY3V0aW9ucz4KKwkJICAgIDwvcGx1Z2luPgorCQkgICAgPHBsdWdpbj4KKwkJCTxncm91cElkPm9yZy5hcGFjaGUubWF2ZW4ucGx1Z2luczwvZ3JvdXBJZD4KKwkJCTxhcnRpZmFjdElkPm1hdmVuLWRlcGxveS1wbHVnaW48L2FydGlmYWN0SWQ+CisJCQk8Y29uZmlndXJhdGlvbj4KKwkJCSAgIDxza2lwPnRydWU8L3NraXA+IDwhLS0gVG8gcHJlZmVyIG5leHVzLXN0YWdpbmctbWF2ZW4tcGx1Z2luIC0tPgorCQkJPC9jb25maWd1cmF0aW9uPgorCQkgICA8L3BsdWdpbj4KKwkJICAgPHBsdWdpbj4KKwkJCTxncm91cElkPm9yZy5zb25hdHlwZS5wbHVnaW5zPC9ncm91cElkPgorCQkJPGFydGlmYWN0SWQ+bmV4dXMtc3RhZ2luZy1tYXZlbi1wbHVnaW48L2FydGlmYWN0SWQ+CisJCQk8ZXh0ZW5zaW9ucz50cnVlPC9leHRlbnNpb25zPgorCQkJPGV4ZWN1dGlvbnM+CisJCQkgICAgPGV4ZWN1dGlvbj4KKwkJCQk8aWQ+ZGVmYXVsdC1kZXBsb3k8L2lkPgorCQkJCTxwaGFzZT5kZXBsb3k8L3BoYXNlPgorCQkJCTxnb2Fscz4KKwkJCQkgICAgPGdvYWw+ZGVwbG95PC9nb2FsPgorCQkJCTwvZ29hbHM+CisJCQkgICAgPC9leGVjdXRpb24+CisJCQk8L2V4ZWN1dGlvbnM+CisJCQk8Y29uZmlndXJhdGlvbj4KKwkJCSAgICA8c2VydmVySWQ+b3Nzcmg8L3NlcnZlcklkPgorCQkJICAgIDxuZXh1c1VybD5odHRwczovL29zcy5zb25hdHlwZS5vcmcvPC9uZXh1c1VybD4KKwkJCSAgICA8YXV0b1JlbGVhc2VBZnRlckNsb3NlPmZhbHNlPC9hdXRvUmVsZWFzZUFmdGVyQ2xvc2U+CisJCQk8L2NvbmZpZ3VyYXRpb24+CisJCSAgICA8L3BsdWdpbj4KKwkJPC9wbHVnaW5zPgorCSAgICA8L2J1aWxkPgorCTwvcHJvZmlsZT4KKworCTwhLS0KKwkgICAgVGhpcyBwcm9maWxlIGlzIHVzZWQgZm9yIGRlcGxveWluZyBhIEphdmFNYWlsIFNOQVBTSE9UIHJlbGVhc2UuCisJICAgIEl0J3MgaWRlbnRpY2FsIHRvIHRoZSBhYm92ZSBkZXBsb3ktcmVsZWFzZSBwcm9maWxlIGV4Y2VwdCB0aGF0CisJICAgIGFydGlmYWN0cyBhcmVuJ3Qgc2lnbmVkLgorCS0tPgorCTxwcm9maWxlPgorCSAgICA8aWQ+ZGVwbG95LXNuYXBzaG90PC9pZD4KKwkgICAgPG1vZHVsZXM+CisJCTxtb2R1bGU+cGFyZW50LWRpc3RyaWI8L21vZHVsZT4KKwkgICAgPC9tb2R1bGVzPgorCSAgICA8YnVpbGQ+CisJCTxwbHVnaW5NYW5hZ2VtZW50PgorCQkgICAgPHBsdWdpbnM+CisJCQk8cGx1Z2luPgorCQkJICAgIDwhLS0gRW5hYmxlcyBzdGVwLWJ5LXN0ZXAgc3RhZ2luZyBkZXBsb3ltZW50IC0tPgorCQkJICAgIDxncm91cElkPm9yZy5zb25hdHlwZS5wbHVnaW5zPC9ncm91cElkPgorCQkJICAgIDxhcnRpZmFjdElkPm5leHVzLXN0YWdpbmctbWF2ZW4tcGx1Z2luPC9hcnRpZmFjdElkPgorCQkJICAgIDx2ZXJzaW9uPjEuNi43PC92ZXJzaW9uPgorCQkJPC9wbHVnaW4+CisJCSAgICA8L3BsdWdpbnM+CisJCTwvcGx1Z2luTWFuYWdlbWVudD4KKwkJPHBsdWdpbnM+CisJCSAgICA8cGx1Z2luPgorCQkJPGdyb3VwSWQ+b3JnLmFwYWNoZS5tYXZlbi5wbHVnaW5zPC9ncm91cElkPgorCQkJPGFydGlmYWN0SWQ+bWF2ZW4tc3VyZWZpcmUtcGx1Z2luPC9hcnRpZmFjdElkPgorCQkJPGNvbmZpZ3VyYXRpb24+CisJCQkgICAgPHNraXA+dHJ1ZTwvc2tpcD4KKwkJCTwvY29uZmlndXJhdGlvbj4KKwkJICAgIDwvcGx1Z2luPgorCisJCSAgICA8cGx1Z2luPgorCQkJPGdyb3VwSWQ+b3JnLmFwYWNoZS5tYXZlbi5wbHVnaW5zPC9ncm91cElkPgorCQkJPGFydGlmYWN0SWQ+bWF2ZW4tamF2YWRvYy1wbHVnaW48L2FydGlmYWN0SWQ+CisJCQk8ZXhlY3V0aW9ucz4KKwkJCSAgICA8ZXhlY3V0aW9uPgorCQkJCTxpZD5hdHRhY2gtamF2YWRvY3M8L2lkPgorCQkJCTxnb2Fscz4KKwkJCQkgICAgPGdvYWw+amFyPC9nb2FsPgorCQkJCTwvZ29hbHM+CisJCQkgICAgPC9leGVjdXRpb24+CisJCQk8L2V4ZWN1dGlvbnM+CisJCSAgICA8L3BsdWdpbj4KKwkJICAgIDxwbHVnaW4+CisJCQk8Z3JvdXBJZD5vcmcuYXBhY2hlLm1hdmVuLnBsdWdpbnM8L2dyb3VwSWQ+CisJCQk8YXJ0aWZhY3RJZD5tYXZlbi1kZXBsb3ktcGx1Z2luPC9hcnRpZmFjdElkPgorCQkJPGNvbmZpZ3VyYXRpb24+CisJCQkgICA8c2tpcD50cnVlPC9za2lwPiA8IS0tIFRvIHByZWZlciBuZXh1cy1zdGFnaW5nLW1hdmVuLXBsdWdpbiAtLT4KKwkJCTwvY29uZmlndXJhdGlvbj4KKwkJICAgPC9wbHVnaW4+CisJCSAgIDxwbHVnaW4+CisJCQk8Z3JvdXBJZD5vcmcuc29uYXR5cGUucGx1Z2luczwvZ3JvdXBJZD4KKwkJCTxhcnRpZmFjdElkPm5leHVzLXN0YWdpbmctbWF2ZW4tcGx1Z2luPC9hcnRpZmFjdElkPgorCQkJPGV4dGVuc2lvbnM+dHJ1ZTwvZXh0ZW5zaW9ucz4KKwkJCTxleGVjdXRpb25zPgorCQkJICAgIDxleGVjdXRpb24+CisJCQkJPGlkPmRlZmF1bHQtZGVwbG95PC9pZD4KKwkJCQk8cGhhc2U+ZGVwbG95PC9waGFzZT4KKwkJCQk8Z29hbHM+CisJCQkJICAgIDxnb2FsPmRlcGxveTwvZ29hbD4KKwkJCQk8L2dvYWxzPgorCQkJICAgIDwvZXhlY3V0aW9uPgorCQkJPC9leGVjdXRpb25zPgorCQkJPGNvbmZpZ3VyYXRpb24+CisJCQkgICAgPHNlcnZlcklkPm9zc3JoPC9zZXJ2ZXJJZD4KKwkJCSAgICA8bmV4dXNVcmw+aHR0cHM6Ly9vc3Muc29uYXR5cGUub3JnLzwvbmV4dXNVcmw+CisJCQkgICAgPGF1dG9SZWxlYXNlQWZ0ZXJDbG9zZT5mYWxzZTwvYXV0b1JlbGVhc2VBZnRlckNsb3NlPgorCQkJPC9jb25maWd1cmF0aW9uPgorCQkgICAgPC9wbHVnaW4+CisJCTwvcGx1Z2lucz4KKwkgICAgPC9idWlsZD4KKwk8L3Byb2ZpbGU+CisKKwk8IS0tCisJICAgIEEgc3BlY2lhbCBwcm9maWxlIGZvciBjb21waWxpbmcgd2l0aCB0aGUgcmVhbCBKREsgMS43CisJICAgIGNvbXBpbGVyLCB0byBtYWtlIHN1cmUgdGhlcmUgYXJlIG5vIGFjY2lkZW50YWwgZGVwZW5kZW5jaWVzCisJICAgIG9uIEpESyAxLjggb3IgbmV3ZXIgQVBJcy4gIFNldCB0aGUgcHJvcGVydHkgamF2YWMucGF0aCB0byB0aGUgcGF0aAorCSAgICB0byB0aGUgSkRLIDEuNyBjb21waWxlciwgZS5nLiwKKwkgICAgIm12biAtUDEuNyAtRGphdmFjLnBhdGg9L29wdC9qZGsxLjcvYmluL2phdmFjIi4KKwktLT4KKwk8cHJvZmlsZT4KKwkgICAgPGlkPjEuNzwvaWQ+CisJICAgIDxidWlsZD4KKwkJPHBsdWdpbnM+CisJCSAgICA8cGx1Z2luPgorCQkJPGFydGlmYWN0SWQ+bWF2ZW4tY29tcGlsZXItcGx1Z2luPC9hcnRpZmFjdElkPgorCQkJPGV4ZWN1dGlvbnM+CisJCQkgICAgPGV4ZWN1dGlvbj4KKwkJCQk8aWQ+ZGVmYXVsdC1jb21waWxlPC9pZD4KKwkJCQk8Y29uZmlndXJhdGlvbj4KKwkJCQkgICAgPGZvcms+dHJ1ZTwvZm9yaz4KKwkJCQkgICAgPGV4ZWN1dGFibGU+JHtqYXZhYy5wYXRofTwvZXhlY3V0YWJsZT4KKwkJCQkgICAgPGNvbXBpbGVyVmVyc2lvbj4xLjc8L2NvbXBpbGVyVmVyc2lvbj4KKwkJCQkgICAgPHNvdXJjZT4xLjc8L3NvdXJjZT4KKwkJCQkgICAgPHRhcmdldD4xLjc8L3RhcmdldD4KKwkJCQk8L2NvbmZpZ3VyYXRpb24+CisJCQkgICAgPC9leGVjdXRpb24+CisJCQk8L2V4ZWN1dGlvbnM+CisJCSAgICA8L3BsdWdpbj4KKwkJICAgIDwhLS0KKwkJCU9ubHkgcmVxdWlyZSBKREsgMS43LgorCQkgICAgLS0+CisJCSAgICA8cGx1Z2luPgorCQkJPGdyb3VwSWQ+b3JnLmFwYWNoZS5tYXZlbi5wbHVnaW5zPC9ncm91cElkPgorCQkJPGFydGlmYWN0SWQ+bWF2ZW4tZW5mb3JjZXItcGx1Z2luPC9hcnRpZmFjdElkPgorCQkJPGV4ZWN1dGlvbnM+CisJCQkgICAgPGV4ZWN1dGlvbj4KKwkJCQk8aWQ+ZW5mb3JjZS12ZXJzaW9uPC9pZD4KKwkJCQk8Z29hbHM+CisJCQkJICAgIDxnb2FsPmVuZm9yY2U8L2dvYWw+CisJCQkJPC9nb2Fscz4KKwkJCQk8Y29uZmlndXJhdGlvbj4KKwkJCQkgICAgPHJ1bGVzPgorCQkJCQk8cmVxdWlyZU1hdmVuVmVyc2lvbj4KKwkJCQkJICAgIDx2ZXJzaW9uPlszLjAuMywpPC92ZXJzaW9uPgorCQkJCQk8L3JlcXVpcmVNYXZlblZlcnNpb24+CisJCQkJCTxyZXF1aXJlSmF2YVZlcnNpb24+CisJCQkJCSAgICA8dmVyc2lvbj4xLjc8L3ZlcnNpb24+CisJCQkJCTwvcmVxdWlyZUphdmFWZXJzaW9uPgorCQkJCSAgICA8L3J1bGVzPgorCQkJCTwvY29uZmlndXJhdGlvbj4KKwkJCSAgICA8L2V4ZWN1dGlvbj4KKwkJCTwvZXhlY3V0aW9ucz4KKwkJICAgIDwvcGx1Z2luPgorCQk8L3BsdWdpbnM+CisJICAgIDwvYnVpbGQ+CisJPC9wcm9maWxlPgorCisJPCEtLQorCSAgICBBIHNwZWNpYWwgcHJvZmlsZSBmb3IgY29tcGlsaW5nIHdpdGggSkRLIDkuCisJLS0+CisJPHByb2ZpbGU+CisJICAgIDxpZD45PC9pZD4KKwkgICAgPGFjdGl2YXRpb24+CisJCTxqZGs+OTwvamRrPgorCSAgICA8L2FjdGl2YXRpb24+CisJICAgIDxidWlsZD4KKwkJPHBsdWdpbnM+CisJCSAgICA8cGx1Z2luPgorCQkJPGFydGlmYWN0SWQ+bWF2ZW4tY29tcGlsZXItcGx1Z2luPC9hcnRpZmFjdElkPgorCQkJPGV4ZWN1dGlvbnM+CisJCQkgICAgPGV4ZWN1dGlvbj4KKwkJCQk8aWQ+ZGVmYXVsdC1jb21waWxlPC9pZD4KKwkJCQk8Y29uZmlndXJhdGlvbj4KKwkJCQkgICAgPGNvbXBpbGVyQXJncz4KKwkJCQkJPGFyZz4tWGxpbnQ8L2FyZz4KKwkJCQkJPGFyZz4tWGxpbnQ6LW9wdGlvbnM8L2FyZz4KKwkJCQkJPGFyZz4tWGxpbnQ6LXBhdGg8L2FyZz4KKwkJCQkJPCEtLQorCQkJCQkgICAgVG9vIG1hbnkgZmluYWxpemUgd2FybmluZ3MuCisJCQkJCTxhcmc+LVdlcnJvcjwvYXJnPgorCQkJCQktLT4KKwkJCQkgICAgPC9jb21waWxlckFyZ3M+CisJCQkJPC9jb25maWd1cmF0aW9uPgorCQkJICAgIDwvZXhlY3V0aW9uPgorCQkJPC9leGVjdXRpb25zPgorCQkgICAgPC9wbHVnaW4+CisJCSAgICA8IS0tCisJCQlSZXF1aXJlIEpESyA5LgorCQkgICAgLS0+CisJCSAgICA8cGx1Z2luPgorCQkJPGdyb3VwSWQ+b3JnLmFwYWNoZS5tYXZlbi5wbHVnaW5zPC9ncm91cElkPgorCQkJPGFydGlmYWN0SWQ+bWF2ZW4tZW5mb3JjZXItcGx1Z2luPC9hcnRpZmFjdElkPgorCQkJPGV4ZWN1dGlvbnM+CisJCQkgICAgPGV4ZWN1dGlvbj4KKwkJCQk8aWQ+ZW5mb3JjZS12ZXJzaW9uPC9pZD4KKwkJCQk8Z29hbHM+CisJCQkJICAgIDxnb2FsPmVuZm9yY2U8L2dvYWw+CisJCQkJPC9nb2Fscz4KKwkJCQk8Y29uZmlndXJhdGlvbj4KKwkJCQkgICAgPHJ1bGVzPgorCQkJCQk8cmVxdWlyZU1hdmVuVmVyc2lvbj4KKwkJCQkJICAgIDx2ZXJzaW9uPlszLjAuMywpPC92ZXJzaW9uPgorCQkJCQk8L3JlcXVpcmVNYXZlblZlcnNpb24+CisJCQkJCTxyZXF1aXJlSmF2YVZlcnNpb24+CisJCQkJCSAgICA8dmVyc2lvbj45PC92ZXJzaW9uPgorCQkJCQk8L3JlcXVpcmVKYXZhVmVyc2lvbj4KKwkJCQkgICAgPC9ydWxlcz4KKwkJCQk8L2NvbmZpZ3VyYXRpb24+CisJCQkgICAgPC9leGVjdXRpb24+CisJCQk8L2V4ZWN1dGlvbnM+CisJCSAgICA8L3BsdWdpbj4KKwkJPC9wbHVnaW5zPgorCSAgICA8L2J1aWxkPgorCTwvcHJvZmlsZT4KKyAgICA8L3Byb2ZpbGVzPgorCisgICAgPGJ1aWxkPgorCTxkZWZhdWx0R29hbD5pbnN0YWxsPC9kZWZhdWx0R29hbD4KKwk8cGx1Z2lucz4KKwkgICAgPCEtLQorCQlNYWtlIHN1cmUgd2UncmUgdXNpbmcgdGhlIGNvcnJlY3QgdmVyc2lvbiBvZiBtYXZlbi4KKwkgICAgLS0+CisJICAgIDxwbHVnaW4+CisJCTxncm91cElkPm9yZy5hcGFjaGUubWF2ZW4ucGx1Z2luczwvZ3JvdXBJZD4KKwkJPGFydGlmYWN0SWQ+bWF2ZW4tZW5mb3JjZXItcGx1Z2luPC9hcnRpZmFjdElkPgorCQkgICAgPHZlcnNpb24+My4wLjAtTTE8L3ZlcnNpb24+CisJCTxleGVjdXRpb25zPgorCQkgICAgPGV4ZWN1dGlvbj4KKwkJCTxpZD5lbmZvcmNlLXZlcnNpb248L2lkPgorCQkJPGdvYWxzPgorCQkJICAgIDxnb2FsPmVuZm9yY2U8L2dvYWw+CisJCQk8L2dvYWxzPgorCQkJPGNvbmZpZ3VyYXRpb24+CisJCQkgICAgPHJ1bGVzPgorCQkJCTxyZXF1aXJlTWF2ZW5WZXJzaW9uPgorCQkJCSAgICA8dmVyc2lvbj5bMy4wLjMsKTwvdmVyc2lvbj4KKwkJCQk8L3JlcXVpcmVNYXZlblZlcnNpb24+CisJCQkJPHJlcXVpcmVKYXZhVmVyc2lvbj4KKwkJCQkgICAgPHZlcnNpb24+MS44PC92ZXJzaW9uPgorCQkJCTwvcmVxdWlyZUphdmFWZXJzaW9uPgorCQkJICAgIDwvcnVsZXM+CisJCQk8L2NvbmZpZ3VyYXRpb24+CisJCSAgICA8L2V4ZWN1dGlvbj4KKwkJPC9leGVjdXRpb25zPgorCSAgICA8L3BsdWdpbj4KKworCSAgICA8IS0tCisJCVRoaXMgcGx1Z2luIGlzIHJlcG9uc2libGUgZm9yIHBhY2thZ2luZyBhcnRpZmFjdHMKKwkJYXMgT1NHaSBidW5kbGVzLiAgUGxlYXNlIHJlZmVyIHRvCisJCWh0dHA6Ly9mZWxpeC5hcGFjaGUub3JnL3NpdGUvYXBhY2hlLWZlbGl4LW1hdmVuLWJ1bmRsZS1wbHVnaW4tYm5kLmh0bWwKKwkJZm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgaG93IHRvIHVzZSB0aGlzIHBsdWdpbi4KKwkgICAgLS0+CisJICAgIDxwbHVnaW4+CisJCTxncm91cElkPm9yZy5hcGFjaGUuZmVsaXg8L2dyb3VwSWQ+CisJCTxhcnRpZmFjdElkPm1hdmVuLWJ1bmRsZS1wbHVnaW48L2FydGlmYWN0SWQ+CisJCTxjb25maWd1cmF0aW9uPgorCQkgICAgPGluc3RydWN0aW9ucz4KKwkJCTxCdW5kbGUtU3ltYm9saWNOYW1lPgorCQkJICAgICR7bWFpbC5idW5kbGUuc3ltYm9saWNOYW1lfQorCQkJPC9CdW5kbGUtU3ltYm9saWNOYW1lPgorCQkJPEV4cG9ydC1QYWNrYWdlPgorCQkJICAgICR7bWFpbC5wYWNrYWdlcy5leHBvcnR9CisJCQk8L0V4cG9ydC1QYWNrYWdlPgorCQkJPEltcG9ydC1QYWNrYWdlPgorCQkJICAgICR7bWFpbC5wYWNrYWdlcy5pbXBvcnR9CisJCQk8L0ltcG9ydC1QYWNrYWdlPgorCQkJPFByaXZhdGUtUGFja2FnZT4KKwkJCSAgICAke21haWwucGFja2FnZXMucHJpdmF0ZX0KKwkJCTwvUHJpdmF0ZS1QYWNrYWdlPgorCQkJPER5bmFtaWNJbXBvcnQtUGFja2FnZT4KKwkJCSAgICAqCisJCQk8L0R5bmFtaWNJbXBvcnQtUGFja2FnZT4KKwkJICAgIDwvaW5zdHJ1Y3Rpb25zPgorCQkgICAgPG5pY2VNYW5pZmVzdD50cnVlPC9uaWNlTWFuaWZlc3Q+CisJCTwvY29uZmlndXJhdGlvbj4KKwkJPCEtLQorCQkgICAgU2luY2Ugd2UgZG9uJ3QgY2hhbmdlIHRoZSBwYWNrYWdpbmcgdHlwZSB0byBidW5kbGUsIHdlCisJCSAgICBuZWVkIHRvIGNvbmZpZ3VyZSB0aGUgcGx1Z2luIHRvIGV4ZWN1dGUgdGhlIG1hbmlmZXN0IGdvYWwKKwkJICAgIGR1cmluZyB0aGUgcHJvY2Vzcy1jbGFzc2VzIHBoYXNlIG9mIHRoZSBidWlsZCBsaWZlIGN5Y2xlLgorCQktLT4KKwkJPGV4ZWN1dGlvbnM+CisJCSAgICA8ZXhlY3V0aW9uPgorCQkJPGlkPm9zZ2ktbWFuaWZlc3Q8L2lkPgorCQkJPHBoYXNlPnByb2Nlc3MtY2xhc3NlczwvcGhhc2U+CisJCQk8Z29hbHM+CisJCQkgICAgPGdvYWw+bWFuaWZlc3Q8L2dvYWw+CisJCQk8L2dvYWxzPgorCQkgICAgPC9leGVjdXRpb24+CisJCTwvZXhlY3V0aW9ucz4KKwkgICAgPC9wbHVnaW4+CisKKwkgICAgPCEtLQorCQlTaW5jZSB3ZSBkb24ndCB3YW50IGEgcXVhbGlmaWVyIGxpa2UgYjA1IG9yIFNOQVBTSE9UIHRvCisJCWFwcGVhciBpbiB0aGUgT1NHaSBwYWNrYWdlIHZlcnNpb24gYXR0cmlidXRlLCB3ZSB1c2UKKwkJdGhlIGZvbGxvd2luZyBwbHVnaW4gdG8gcG9wdWxhdGUgYSBwcm9qZWN0IHByb3BlcnR5CisJCXdpdGggYW4gT1NHaSB2ZXJzaW9uIHRoYXQgaXMgZXF1aXZhbGVudCB0byB0aGUgbWF2ZW4KKwkJdmVyc2lvbiB3aXRob3V0IHRoZSBxdWFsaWZpZXIuCisJICAgIC0tPgorCSAgICA8cGx1Z2luPgorCQk8Z3JvdXBJZD5vcmcuZ2xhc3NmaXNoLmhrMjwvZ3JvdXBJZD4KKwkJPGFydGlmYWN0SWQ+b3NnaXZlcnNpb24tbWF2ZW4tcGx1Z2luPC9hcnRpZmFjdElkPgorCQk8dmVyc2lvbj4ke2hrMi5wbHVnaW4udmVyc2lvbn08L3ZlcnNpb24+CisJCTxjb25maWd1cmF0aW9uPgorCQkgICAgPGRyb3BWZXJzaW9uQ29tcG9uZW50PnF1YWxpZmllcjwvZHJvcFZlcnNpb25Db21wb25lbnQ+CisJCSAgICA8dmVyc2lvblByb3BlcnR5TmFtZT5tYWlsLm9zZ2l2ZXJzaW9uPC92ZXJzaW9uUHJvcGVydHlOYW1lPgorCQk8L2NvbmZpZ3VyYXRpb24+CisJCTxleGVjdXRpb25zPgorCQkgICAgPGV4ZWN1dGlvbj4KKwkJCTxpZD5jb21wdXRlLW9zZ2ktdmVyc2lvbjwvaWQ+CisJCQk8Z29hbHM+CisJCQkgICAgPGdvYWw+Y29tcHV0ZS1vc2dpLXZlcnNpb248L2dvYWw+CisJCQk8L2dvYWxzPgorCQkgICAgPC9leGVjdXRpb24+CisJCTwvZXhlY3V0aW9ucz4KKwkgICAgPC9wbHVnaW4+CisKKwkgICAgPCEtLQorCQlVc2UgdGhlIDEuOCBjb21waWxlciBmb3IgSmF2YU1haWwgaXRzZWxmIGFuZCB0aGUgdGVzdCBjbGFzc2VzLAorCQlidXQgcmVzdHJpY3QgaXQgdG8gMS43IHNvdXJjZSBhbmQgdGFyZ2V0LiAgVGhlIDEuOCBjb21waWxlciBpcworCQl1c2VkICpvbmx5KiB0byBwaWNrIHVwIHRoZSBkZWZpbml0aW9uIG9mIHRoZSBSZXBlYXRhYmxlCisJCWFubm90YXRpb24sIG5lZWRlZCBieSBNYWlsU2VydmljZURlZmluaXRpb24uCisJICAgIC0tPgorCSAgICA8cGx1Z2luPgorCQk8YXJ0aWZhY3RJZD5tYXZlbi1jb21waWxlci1wbHVnaW48L2FydGlmYWN0SWQ+CisJCTxleGVjdXRpb25zPgorCQkgICAgPGV4ZWN1dGlvbj4KKwkJCTxpZD5kZWZhdWx0LWNvbXBpbGU8L2lkPgorCQkJPGNvbmZpZ3VyYXRpb24+CisJCQkgICAgPHNvdXJjZT4xLjc8L3NvdXJjZT4KKwkJCSAgICA8dGFyZ2V0PjEuNzwvdGFyZ2V0PgorCQkJICAgIDwhLS0KKwkJCQlYWFggLSB3b3JrYXJvdW5kIGZvciBidWcgaW4gbWF2ZW4gY29tcGlsZXIKKwkJCQlwbHVnaW4gdmVyc2lvbnMgMy4wIC0gMy4zIChhdCBsZWFzdCk6CisJCQkJaHR0cHM6Ly9pc3N1ZXMuYXBhY2hlLm9yZy9qaXJhL2Jyb3dzZS9NQ09NUElMRVItMjA5CisJCQkgICAgLS0+CisJCQkgICAgPHVzZUluY3JlbWVudGFsQ29tcGlsYXRpb24+ZmFsc2U8L3VzZUluY3JlbWVudGFsQ29tcGlsYXRpb24+CisJCQkgICAgPGV4Y2x1ZGVzPgorCQkJCTxleGNsdWRlPgorCQkJCSAgbW9kdWxlLWluZm8uamF2YQorCQkJCTwvZXhjbHVkZT4KKwkJCSAgICA8L2V4Y2x1ZGVzPgorCQkJPC9jb25maWd1cmF0aW9uPgorCQkgICAgPC9leGVjdXRpb24+CisJCSAgICA8ZXhlY3V0aW9uPgorCQkJPGlkPmRlZmF1bHQtdGVzdENvbXBpbGU8L2lkPgorCQkJPGNvbmZpZ3VyYXRpb24+CisJCQkgICAgPHNvdXJjZT4xLjc8L3NvdXJjZT4KKwkJCSAgICA8dGFyZ2V0PjEuNzwvdGFyZ2V0PgorCQkJPC9jb25maWd1cmF0aW9uPgorCQkgICAgPC9leGVjdXRpb24+CisJCTwvZXhlY3V0aW9ucz4KKwkgICAgPC9wbHVnaW4+CisKKwkgICAgPHBsdWdpbj4KKwkJPGFydGlmYWN0SWQ+bWF2ZW4tamFyLXBsdWdpbjwvYXJ0aWZhY3RJZD4KKwkJPGNvbmZpZ3VyYXRpb24+CisJCSAgICA8ZmluYWxOYW1lPiR7cHJvamVjdC5hcnRpZmFjdElkfTwvZmluYWxOYW1lPgorCQkgICAgPGFyY2hpdmU+CisJCQk8IS0tCisJCQkgICAgQ29uZmlndXJlIHRoZSBtYXZlbi1qYXItcGx1Z2luIHRvIHBpY2sgdXAKKwkJCSAgICBNRVRBLUlORi9NQU5JRkVTVC5NRiB0aGF0J3MgZ2VuZXJhdGVkIGJ5CisJCQkgICAgdGhlIG1hdmVuLWJ1bmRsZS1wbHVnaW4uCisJCQktLT4KKwkJCTxtYW5pZmVzdEZpbGU+CisJCQkgICR7cHJvamVjdC5idWlsZC5vdXRwdXREaXJlY3Rvcnl9L01FVEEtSU5GL01BTklGRVNULk1GCisJCQk8L21hbmlmZXN0RmlsZT4KKwkJCTxtYW5pZmVzdEVudHJpZXM+CisJCQkgICAgPEV4dGVuc2lvbi1OYW1lPgorCQkJCSR7bWFpbC5leHRlbnNpb25OYW1lfQorCQkJICAgIDwvRXh0ZW5zaW9uLU5hbWU+CisJCQkgICAgPFNwZWNpZmljYXRpb24tVGl0bGU+CisJCQkJJHttYWlsLnNwZWNpZmljYXRpb25UaXRsZX0KKwkJCSAgICA8L1NwZWNpZmljYXRpb24tVGl0bGU+CisJCQkgICAgPFNwZWNpZmljYXRpb24tVmVyc2lvbj4KKwkJCQkke21haWwuc3BlYy52ZXJzaW9ufQorCQkJICAgIDwvU3BlY2lmaWNhdGlvbi1WZXJzaW9uPgorCQkJICAgIDxTcGVjaWZpY2F0aW9uLVZlbmRvcj4KKwkJCQkke3Byb2plY3Qub3JnYW5pemF0aW9uLm5hbWV9CisJCQkgICAgPC9TcGVjaWZpY2F0aW9uLVZlbmRvcj4KKwkJCSAgICA8SW1wbGVtZW50YXRpb24tVGl0bGU+CisJCQkJJHttYWlsLmltcGxlbWVudGF0aW9uVGl0bGV9CisJCQkgICAgPC9JbXBsZW1lbnRhdGlvbi1UaXRsZT4KKwkJCSAgICA8SW1wbGVtZW50YXRpb24tVmVyc2lvbj4KKwkJCQkke3Byb2plY3QudmVyc2lvbn0KKwkJCSAgICA8L0ltcGxlbWVudGF0aW9uLVZlcnNpb24+CisJCQkgICAgPEltcGxlbWVudGF0aW9uLVZlbmRvcj4KKwkJCQkke3Byb2plY3Qub3JnYW5pemF0aW9uLm5hbWV9CisJCQkgICAgPC9JbXBsZW1lbnRhdGlvbi1WZW5kb3I+CisJCQkgICAgPEltcGxlbWVudGF0aW9uLVZlbmRvci1JZD4KKwkJCQljb20uc3VuCisJCQkgICAgPC9JbXBsZW1lbnRhdGlvbi1WZW5kb3ItSWQ+CisJCQkgICAgPFByb2JlLVByb3ZpZGVyLVhNTC1GaWxlLU5hbWVzPgorCQkJCSR7bWFpbC5wcm9iZUZpbGV9CisJCQkgICAgPC9Qcm9iZS1Qcm92aWRlci1YTUwtRmlsZS1OYW1lcz4KKwkJCTwvbWFuaWZlc3RFbnRyaWVzPgorCQkgICAgPC9hcmNoaXZlPgorCQkgICAgPGV4Y2x1ZGVzPgorCQkJPGV4Y2x1ZGU+KiovKi5qYXZhPC9leGNsdWRlPgorCQkgICAgPC9leGNsdWRlcz4KKwkJPC9jb25maWd1cmF0aW9uPgorCSAgICA8L3BsdWdpbj4KKworCSAgICA8IS0tCisJCVRlbGwgdGhlIHNvdXJjZSBwbHVnaW4gYWJvdXQgdGhlIHNvdXJjZXMgdGhhdCBtYXkgaGF2ZQorCQliZWVuIGRvd25sb2FkZWQgYnkgdGhlIG1hdmVuLWRlcGVuZGVuY3ktcGx1Z2luLgorCisJCUFsc28sIG5lZWQgdGhpcyBwbHVnaW4gdG8gZGVmaW5lIHRhcmdldC9jbGFzc2VzIGFzIGFub3RoZXIKKwkJc291cmNlIGRpcmVjdG9yeSBzbyB0aGF0IHRoZSBmaWx0ZXJlZCBWZXJzaW9uLmphdmEKKwkJdGhhdCdzIGNvcGllZCB0aGVyZSB3aWxsIGFsc28gYmUgY29tcGlsZWQgd2hlbiB1c2luZworCQl0aGUgbGF0ZXN0IHZlcnNpb24gb2YgdGhlIG1hdmVuLWNvbXBpbGVyLXBsdWdpbi4KKwkgICAgLS0+CisKKwkgICAgPHBsdWdpbj4KKwkJPGdyb3VwSWQ+b3JnLmNvZGVoYXVzLm1vam88L2dyb3VwSWQ+CisJCTxhcnRpZmFjdElkPmJ1aWxkLWhlbHBlci1tYXZlbi1wbHVnaW48L2FydGlmYWN0SWQ+CisJCTxleGVjdXRpb25zPgorCQkgICAgPGV4ZWN1dGlvbj4KKwkJCTxpZD5hZGQtc291cmNlPC9pZD4KKwkJCTxwaGFzZT5nZW5lcmF0ZS1zb3VyY2VzPC9waGFzZT4KKwkJCTxnb2Fscz4KKwkJCSAgICA8Z29hbD5hZGQtc291cmNlPC9nb2FsPgorCQkJPC9nb2Fscz4KKwkJCTxjb25maWd1cmF0aW9uPgorCQkJICAgIDxzb3VyY2VzPgorCQkJCTxzb3VyY2U+IDwhLS0gZm9yIGRlcGVuZGVuY2llcyAtLT4KKwkJCQkgICAgJHtwcm9qZWN0LmJ1aWxkLmRpcmVjdG9yeX0vc291cmNlcworCQkJCTwvc291cmNlPgorCQkJCTxzb3VyY2U+IDwhLS0gZm9yIFZlcnNpb24uamF2YSAtLT4KKwkJCQkgICAgdGFyZ2V0L2NsYXNzZXMKKwkJCQk8L3NvdXJjZT4KKwkJCSAgICA8L3NvdXJjZXM+CisJCQk8L2NvbmZpZ3VyYXRpb24+CisJCSAgICA8L2V4ZWN1dGlvbj4KKwkJPC9leGVjdXRpb25zPgorCSAgICA8L3BsdWdpbj4KKworCSAgICA8IS0tCisJCUNvbmZpZ3VyZSB0aGUgc291cmNlIHBsdWdpbiBoZXJlIHNvIHRoYXQgaXQgd2lsbCBrbm93CisJCWFib3V0IHRoZSBzb3VyY2VzIHRoYXQgbWF5IGhhdmUgYmVlbiBkb3dubG9hZGVkIGJ5IHRoZQorCQltYXZlbi1kZXBlbmRlbmN5LXBsdWdpbiBhbmQgY29uZmlndXJlZCBieSB0aGUKKwkJYnVpbGQtaGVscGVyLW1hdmVuLXBsdWdpbi4KKwkgICAgLS0+CisJICAgIDxwbHVnaW4+CisJCTxncm91cElkPm9yZy5hcGFjaGUubWF2ZW4ucGx1Z2luczwvZ3JvdXBJZD4KKwkJPGFydGlmYWN0SWQ+bWF2ZW4tc291cmNlLXBsdWdpbjwvYXJ0aWZhY3RJZD4KKwkJPGV4ZWN1dGlvbnM+CisJCSAgICA8ZXhlY3V0aW9uPgorCQkJPGlkPmF0dGFjaC1zb3VyY2VzPC9pZD4KKwkJCTxnb2Fscz4KKwkJCSAgICA8Z29hbD5qYXItbm8tZm9yazwvZ29hbD4gCisJCQk8L2dvYWxzPgorCQkgICAgPC9leGVjdXRpb24+CisJCTwvZXhlY3V0aW9ucz4KKwkJPGNvbmZpZ3VyYXRpb24+CisJCSAgICA8aW5jbHVkZVBvbT50cnVlPC9pbmNsdWRlUG9tPgorCQkgICAgPCEtLQorCQkJU2luY2Ugd2UgYWRkZWQgdGhlIGNsYXNzZXMgZGlyZWN0b3J5IHVzaW5nIHRoZQorCQkJYnVpbGQtaGVscGVyLW1hdmVuLXBsdWdpbiBhYm92ZSwgd2UgbmVlZCB0byBleGNsdWRlCisJCQl0aGUgY2xhc3MgZmlsZXMgZnJvbSB0aGUgc291cmNlIGphciBmaWxlLgorCQkgICAgLS0+CisJCSAgICA8ZXhjbHVkZXM+CisJCQk8ZXhjbHVkZT4qKi8qLmNsYXNzPC9leGNsdWRlPgorCQkgICAgPC9leGNsdWRlcz4KKwkJPC9jb25maWd1cmF0aW9uPgorCSAgICA8L3BsdWdpbj4KKworPCEtLSBub3QgdXNlZAorCSAgICA8cGx1Z2luPgorCQk8YXJ0aWZhY3RJZD5tYXZlbi1yZWxlYXNlLXBsdWdpbjwvYXJ0aWZhY3RJZD4KKwkJPGNvbmZpZ3VyYXRpb24+CisJCSAgICA8YXJndW1lbnRzPi1QIGRlcGxveTwvYXJndW1lbnRzPgorCQk8L2NvbmZpZ3VyYXRpb24+CisJICAgIDwvcGx1Z2luPgorLS0+CisJPC9wbHVnaW5zPgorCisJPHBsdWdpbk1hbmFnZW1lbnQ+CisJICAgIDxwbHVnaW5zPgorCQk8cGx1Z2luPgorCQkgICAgPGdyb3VwSWQ+b3JnLmFwYWNoZS5tYXZlbi5wbHVnaW5zPC9ncm91cElkPgorCQkgICAgPGFydGlmYWN0SWQ+bWF2ZW4tY29tcGlsZXItcGx1Z2luPC9hcnRpZmFjdElkPgorCQkgICAgPHZlcnNpb24+My43LjA8L3ZlcnNpb24+CisJCTwvcGx1Z2luPgorCQk8cGx1Z2luPgorCQkgICAgPGdyb3VwSWQ+b3JnLmFwYWNoZS5tYXZlbi5wbHVnaW5zPC9ncm91cElkPgorCQkgICAgPGFydGlmYWN0SWQ+bWF2ZW4tc3VyZWZpcmUtcGx1Z2luPC9hcnRpZmFjdElkPgorCQkgICAgPHZlcnNpb24+Mi40LjM8L3ZlcnNpb24+CisJCTwvcGx1Z2luPgorCQk8cGx1Z2luPgorCQkgICAgPGdyb3VwSWQ+b3JnLmFwYWNoZS5tYXZlbi5wbHVnaW5zPC9ncm91cElkPgorCQkgICAgPGFydGlmYWN0SWQ+bWF2ZW4tamFyLXBsdWdpbjwvYXJ0aWZhY3RJZD4KKwkJICAgIDwhLS0gbmVlZCBhdCBsZWFzdCB0aGlzIHZlcnNpb24gdG8gbWFrZSBleGNsdWRlcyB3b3JrIC0tPgorCQkgICAgPHZlcnNpb24+Mi40PC92ZXJzaW9uPgorCQk8L3BsdWdpbj4KKwkJPHBsdWdpbj4KKwkJICAgIDxncm91cElkPm9yZy5jb2RlaGF1cy5tb2pvPC9ncm91cElkPgorCQkgICAgPGFydGlmYWN0SWQ+YnVpbGQtaGVscGVyLW1hdmVuLXBsdWdpbjwvYXJ0aWZhY3RJZD4KKwkJICAgIDx2ZXJzaW9uPjEuNzwvdmVyc2lvbj4KKwkJPC9wbHVnaW4+CisJCTxwbHVnaW4+CisJCSAgICA8Z3JvdXBJZD5vcmcuYXBhY2hlLm1hdmVuLnBsdWdpbnM8L2dyb3VwSWQ+CisJCSAgICA8YXJ0aWZhY3RJZD5tYXZlbi1hc3NlbWJseS1wbHVnaW48L2FydGlmYWN0SWQ+CisJCSAgICA8dmVyc2lvbj4yLjQ8L3ZlcnNpb24+CisJCTwvcGx1Z2luPgorCQk8cGx1Z2luPgorCQkgICAgPCEtLQorCQkJQnkgZGVmYXVsdCwgZGlzYWJsZSB0aGUgU3BvdEJ1Z3MgcGx1Z2luIGZvciBhbGwgbW9kdWxlcy4KKwkJCUl0J3MgZW5hYmxlZCBpbiB0aGUgbW9kdWxlcyB3aGVyZSB3ZSBhY3R1YWxseSB3YW50IHRvCisJCQlydW4gaXQuCisJCSAgICAtLT4KKwkJICAgIDxncm91cElkPmNvbS5naXRodWIuc3BvdGJ1Z3M8L2dyb3VwSWQ+CisJCSAgICA8YXJ0aWZhY3RJZD5zcG90YnVncy1tYXZlbi1wbHVnaW48L2FydGlmYWN0SWQ+CisJCSAgICA8dmVyc2lvbj4ke2ZpbmRidWdzLnZlcnNpb259PC92ZXJzaW9uPgorCQkgICAgPGNvbmZpZ3VyYXRpb24+CisJCQk8c2tpcD4ke2ZpbmRidWdzLnNraXB9PC9za2lwPgorCQkJPHRocmVzaG9sZD4ke2ZpbmRidWdzLnRocmVzaG9sZH08L3RocmVzaG9sZD4KKwkJCTxmaW5kYnVnc1htbFdpdGhNZXNzYWdlcz50cnVlPC9maW5kYnVnc1htbFdpdGhNZXNzYWdlcz4KKwkJCTxleGNsdWRlRmlsdGVyRmlsZT4KKwkJCSAgICAke2ZpbmRidWdzLmV4Y2x1ZGV9CisJCQk8L2V4Y2x1ZGVGaWx0ZXJGaWxlPgorCQkgICAgPC9jb25maWd1cmF0aW9uPgorCQk8L3BsdWdpbj4KKwkJPHBsdWdpbj4KKwkJICAgIDxncm91cElkPm9yZy5hcGFjaGUubWF2ZW4ucGx1Z2luczwvZ3JvdXBJZD4KKwkJICAgIDxhcnRpZmFjdElkPm1hdmVuLWVuZm9yY2VyLXBsdWdpbjwvYXJ0aWZhY3RJZD4KKwkJICAgIDx2ZXJzaW9uPjMuMC4wLU0xPC92ZXJzaW9uPgorCQk8L3BsdWdpbj4KKwkJPHBsdWdpbj4KKwkJICAgIDxncm91cElkPm9yZy5hcGFjaGUuZmVsaXg8L2dyb3VwSWQ+CisJCSAgICA8YXJ0aWZhY3RJZD5tYXZlbi1idW5kbGUtcGx1Z2luPC9hcnRpZmFjdElkPgorCQkgICAgPHZlcnNpb24+My41LjA8L3ZlcnNpb24+CisJCTwvcGx1Z2luPgorCQk8cGx1Z2luPgorCQkgICAgPGdyb3VwSWQ+b3JnLmFwYWNoZS5tYXZlbi5wbHVnaW5zPC9ncm91cElkPgorCQkgICAgPGFydGlmYWN0SWQ+bWF2ZW4tc291cmNlLXBsdWdpbjwvYXJ0aWZhY3RJZD4KKwkJICAgIDx2ZXJzaW9uPjIuMS4yPC92ZXJzaW9uPgorCQk8L3BsdWdpbj4KKwkJPHBsdWdpbj4KKwkJICAgIDxncm91cElkPm9yZy5hcGFjaGUubWF2ZW4ucGx1Z2luczwvZ3JvdXBJZD4KKwkJICAgIDxhcnRpZmFjdElkPm1hdmVuLWphdmFkb2MtcGx1Z2luPC9hcnRpZmFjdElkPgorCQkgICAgPHZlcnNpb24+My4wLjAtTTE8L3ZlcnNpb24+CisJCSAgICA8Y29uZmlndXJhdGlvbj4KKwkJCTwhLS0gbWFrZSBhbGwgdGhlIEFQSXMgYXZhaWxhYmxlIGZvciBqYXZhZG9jIC0tPgorCQkJPGFkZGl0aW9uYWxEZXBlbmRlbmNpZXM+CisJCQkgICAgPGFkZGl0aW9uYWxEZXBlbmRlbmN5PgorCQkJCTxncm91cElkPmNvbS5zdW4ubWFpbDwvZ3JvdXBJZD4KKwkJCQk8YXJ0aWZhY3RJZD5qYWthcnRhLm1haWw8L2FydGlmYWN0SWQ+CisJCQkJPHZlcnNpb24+JHttYWlsLnZlcnNpb259PC92ZXJzaW9uPgorCQkJICAgIDwvYWRkaXRpb25hbERlcGVuZGVuY3k+CisJCQkgICAgPGFkZGl0aW9uYWxEZXBlbmRlbmN5PgorCQkJCTxncm91cElkPmNvbS5zdW4ubWFpbDwvZ3JvdXBJZD4KKwkJCQk8YXJ0aWZhY3RJZD5naW1hcDwvYXJ0aWZhY3RJZD4KKwkJCQk8dmVyc2lvbj4ke21haWwudmVyc2lvbn08L3ZlcnNpb24+CisJCQkgICAgPC9hZGRpdGlvbmFsRGVwZW5kZW5jeT4KKwkJCTwvYWRkaXRpb25hbERlcGVuZGVuY2llcz4KKwkJCTxzb3VyY2VGaWxlRXhjbHVkZXM+CisJCQkgICAgPHNvdXJjZUZpbGVFeGNsdWRlPgorCQkJCW1vZHVsZS1pbmZvLmphdmEKKwkJCSAgICA8L3NvdXJjZUZpbGVFeGNsdWRlPgorCQkJPC9zb3VyY2VGaWxlRXhjbHVkZXM+CisJCSAgICA8L2NvbmZpZ3VyYXRpb24+CisJCTwvcGx1Z2luPgorCQk8cGx1Z2luPgorCQkgICAgPGdyb3VwSWQ+b3JnLmFwYWNoZS5tYXZlbi5wbHVnaW5zPC9ncm91cElkPgorCQkgICAgPGFydGlmYWN0SWQ+bWF2ZW4td2FyLXBsdWdpbjwvYXJ0aWZhY3RJZD4KKwkJICAgIDx2ZXJzaW9uPjIuMjwvdmVyc2lvbj4KKwkJPC9wbHVnaW4+CisJCTxwbHVnaW4+CisJCSAgICA8Z3JvdXBJZD5vcmcuYXBhY2hlLm1hdmVuLnBsdWdpbnM8L2dyb3VwSWQ+CisJCSAgICA8YXJ0aWZhY3RJZD5tYXZlbi1wcm9qZWN0LWluZm8tcmVwb3J0cy1wbHVnaW48L2FydGlmYWN0SWQ+CisJCSAgICA8dmVyc2lvbj4yLjc8L3ZlcnNpb24+CisJCTwvcGx1Z2luPgorCQk8cGx1Z2luPgorCQkgICAgPGdyb3VwSWQ+b3JnLmdsYXNzZmlzaC5jb3B5cmlnaHQ8L2dyb3VwSWQ+CisJCSAgICA8YXJ0aWZhY3RJZD5nbGFzc2Zpc2gtY29weXJpZ2h0LW1hdmVuLXBsdWdpbjwvYXJ0aWZhY3RJZD4KKwkJICAgIDx2ZXJzaW9uPiR7Y29weXJpZ2h0LXBsdWdpbi52ZXJzaW9ufTwvdmVyc2lvbj4KKwkJICAgIDxjb25maWd1cmF0aW9uPgorCQkJPHNjbT5naXQ8L3NjbT4KKwkJCTxzY21Pbmx5PnRydWU8L3NjbU9ubHk+IAorCQkJPGV4Y2x1ZGVGaWxlPgorCQkJICAgIGNvcHlyaWdodC1leGNsdWRlCisJCQk8L2V4Y2x1ZGVGaWxlPgorCQkgICAgPC9jb25maWd1cmF0aW9uPgorCQk8L3BsdWdpbj4KKwkJPHBsdWdpbj4KKwkJICAgIDxncm91cElkPm9yZy5zb25hdHlwZS5wbHVnaW5zPC9ncm91cElkPgorCQkgICAgPGFydGlmYWN0SWQ+bmV4dXMtc3RhZ2luZy1tYXZlbi1wbHVnaW48L2FydGlmYWN0SWQ+CisJCSAgICA8ZXh0ZW5zaW9ucz50cnVlPC9leHRlbnNpb25zPgorCQkgICAgPGNvbmZpZ3VyYXRpb24+CisJCQk8c2VydmVySWQ+b3Nzcmg8L3NlcnZlcklkPgorCQkJPG5leHVzVXJsPmh0dHBzOi8vb3NzLnNvbmF0eXBlLm9yZy88L25leHVzVXJsPgorCQkgICAgPC9jb25maWd1cmF0aW9uPgorCQk8L3BsdWdpbj4KKwkgICAgPC9wbHVnaW5zPgorCTwvcGx1Z2luTWFuYWdlbWVudD4KKyAgICA8L2J1aWxkPgorCisgICAgPGRlcGVuZGVuY3lNYW5hZ2VtZW50PgorCTxkZXBlbmRlbmNpZXM+CisJICAgIDxkZXBlbmRlbmN5PgorCQk8Z3JvdXBJZD5jb20uc3VuLmFjdGl2YXRpb248L2dyb3VwSWQ+CisJCTxhcnRpZmFjdElkPmpha2FydGEuYWN0aXZhdGlvbjwvYXJ0aWZhY3RJZD4KKwkJPHZlcnNpb24+JHthY3RpdmF0aW9uLnZlcnNpb259PC92ZXJzaW9uPgorCSAgICA8L2RlcGVuZGVuY3k+CisJICAgIDxkZXBlbmRlbmN5PgorCQk8Z3JvdXBJZD5jb20uc3VuLm1haWw8L2dyb3VwSWQ+CisJCTxhcnRpZmFjdElkPmpha2FydGEubWFpbDwvYXJ0aWZhY3RJZD4KKwkJPHZlcnNpb24+JHttYWlsLnZlcnNpb259PC92ZXJzaW9uPgorCSAgICA8L2RlcGVuZGVuY3k+CisJICAgIDxkZXBlbmRlbmN5PgorCQk8Z3JvdXBJZD5jb20uc3VuLm1haWw8L2dyb3VwSWQ+CisJCTxhcnRpZmFjdElkPmRzbjwvYXJ0aWZhY3RJZD4KKwkJPHZlcnNpb24+JHttYWlsLnZlcnNpb259PC92ZXJzaW9uPgorCSAgICA8L2RlcGVuZGVuY3k+CisJICAgIDxkZXBlbmRlbmN5PgorCQk8Z3JvdXBJZD5jb20uc3VuLm1haWw8L2dyb3VwSWQ+CisJCTxhcnRpZmFjdElkPmdpbWFwPC9hcnRpZmFjdElkPgorCQk8dmVyc2lvbj4ke21haWwudmVyc2lvbn08L3ZlcnNpb24+CisJICAgIDwvZGVwZW5kZW5jeT4KKwkgICAgPGRlcGVuZGVuY3k+CisJCTxncm91cElkPmNvbS5zdW4ubWFpbDwvZ3JvdXBJZD4KKwkJPGFydGlmYWN0SWQ+bWJveDwvYXJ0aWZhY3RJZD4KKwkJPHZlcnNpb24+JHttYWlsLnZlcnNpb259PC92ZXJzaW9uPgorCSAgICA8L2RlcGVuZGVuY3k+CisJICAgIDxkZXBlbmRlbmN5PgorCQk8Z3JvdXBJZD5jb20uc3VuLm1haWw8L2dyb3VwSWQ+CisJCTxhcnRpZmFjdElkPnRhZ2xpYjwvYXJ0aWZhY3RJZD4KKwkJPHZlcnNpb24+JHttYWlsLnZlcnNpb259PC92ZXJzaW9uPgorCSAgICA8L2RlcGVuZGVuY3k+CisJICAgIDxkZXBlbmRlbmN5PgorCQk8Z3JvdXBJZD5qYXZheC5zZXJ2bGV0PC9ncm91cElkPgorCQk8YXJ0aWZhY3RJZD5zZXJ2bGV0LWFwaTwvYXJ0aWZhY3RJZD4KKwkJPHZlcnNpb24+Mi41PC92ZXJzaW9uPgorCSAgICA8L2RlcGVuZGVuY3k+CisJICAgIDxkZXBlbmRlbmN5PgorCQk8Z3JvdXBJZD5qYXZheC5zZXJ2bGV0LmpzcDwvZ3JvdXBJZD4KKwkJPGFydGlmYWN0SWQ+anNwLWFwaTwvYXJ0aWZhY3RJZD4KKwkJPHZlcnNpb24+Mi4xPC92ZXJzaW9uPgorCSAgICA8L2RlcGVuZGVuY3k+CisJPC9kZXBlbmRlbmNpZXM+CisgICAgPC9kZXBlbmRlbmN5TWFuYWdlbWVudD4KKworICAgIDwhLS0KKwlJJ20gbGVhdmluZyB0aGlzIGhlcmUgYnV0IGNvbW1lbnRlZCBvdXQgdG8gcmVtaW5kIG15c2VsZgorCU5PVCB0byBhZGQgdGhpcyBiYWNrIGluIGJlY2F1c2UgaXQgYnJlYWtzIHRoZSBBbmRyb2lkCisJdmVyc2lvbiBvZiBKYXZhTWFpbC4KKworICAgIDxkZXBlbmRlbmNpZXM+CisJPGRlcGVuZGVuY3k+CisJICAgIDxncm91cElkPmNvbS5zdW4uYWN0aXZhdGlvbjwvZ3JvdXBJZD4KKwkgICAgPGFydGlmYWN0SWQ+amFrYXJ0YS5hY3RpdmF0aW9uPC9hcnRpZmFjdElkPgorCTwvZGVwZW5kZW5jeT4KKyAgICA8L2RlcGVuZGVuY2llcz4KKyAgICAtLT4KKworICAgIDxyZXBvcnRpbmc+CisJPHBsdWdpbnM+CisJICAgIDwhLS0KKwkJQ29uZmlndXJlIFNwb3RCdWdzIHRvIHJ1biB3aXRoICJtdm4gc2l0ZSIgYW5kCisJCWdlbmVyYXRlIGh0bWwgb3V0cHV0IHRoYXQgY2FuIGJlIHZpZXdlZCBkaXJlY3RseS4KKwkgICAgLS0+CisJICAgIDxwbHVnaW4+CisJCTxncm91cElkPmNvbS5naXRodWIuc3BvdGJ1Z3M8L2dyb3VwSWQ+CisJCTxhcnRpZmFjdElkPnNwb3RidWdzLW1hdmVuLXBsdWdpbjwvYXJ0aWZhY3RJZD4KKwkJPHZlcnNpb24+JHtmaW5kYnVncy52ZXJzaW9ufTwvdmVyc2lvbj4KKwkJPGNvbmZpZ3VyYXRpb24+CisJCSAgICA8c2tpcD4ke2ZpbmRidWdzLnNraXB9PC9za2lwPgorCQkgICAgPHRocmVzaG9sZD4ke2ZpbmRidWdzLnRocmVzaG9sZH08L3RocmVzaG9sZD4KKwkJICAgIDxleGNsdWRlRmlsdGVyRmlsZT4KKwkJCSR7ZmluZGJ1Z3MuZXhjbHVkZX0KKwkJICAgIDwvZXhjbHVkZUZpbHRlckZpbGU+CisJCTwvY29uZmlndXJhdGlvbj4KKwkgICAgPC9wbHVnaW4+CisJPC9wbHVnaW5zPgorICAgIDwvcmVwb3J0aW5nPgorPC9wcm9qZWN0PgpkaWZmIC0tZ2l0IGEvcG9wMy9wb20ueG1sIGIvcG9wMy9wb20ueG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA5ZDhjZjcKLS0tIC9kZXYvbnVsbAorKysgYi9wb3AzL3BvbS54bWwKQEAgLTAsMCArMSw0MSBAQAorPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PgorPCEtLQorCisgICAgQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisKKyAgICBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAgICB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKworICAgIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAgICBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgICAgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgICAgdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisKKyAgICBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKworLS0+CisKKzxwcm9qZWN0IHhtbG5zPSJodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9QT00vNC4wLjAiCisJeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIKKwl4c2k6c2NoZW1hTG9jYXRpb249Imh0dHA6Ly9tYXZlbi5hcGFjaGUub3JnL1BPTS80LjAuMAorCQkJICAgIGh0dHA6Ly9tYXZlbi5hcGFjaGUub3JnL21hdmVuLXY0XzBfMC54c2QiPgorICAgIDxwYXJlbnQ+CisJPGdyb3VwSWQ+Y29tLnN1bi5tYWlsPC9ncm91cElkPgorCTxhcnRpZmFjdElkPnBhcmVudC1kaXN0cmliPC9hcnRpZmFjdElkPgorCTx2ZXJzaW9uPjEuNi4zPC92ZXJzaW9uPgorCTxyZWxhdGl2ZVBhdGg+Li4vcGFyZW50LWRpc3RyaWIvcG9tLnhtbDwvcmVsYXRpdmVQYXRoPgorICAgIDwvcGFyZW50PgorICAgIDxtb2RlbFZlcnNpb24+NC4wLjA8L21vZGVsVmVyc2lvbj4KKyAgICA8Z3JvdXBJZD5jb20uc3VuLm1haWw8L2dyb3VwSWQ+CisgICAgPGFydGlmYWN0SWQ+cG9wMzwvYXJ0aWZhY3RJZD4KKyAgICA8cGFja2FnaW5nPmphcjwvcGFja2FnaW5nPgorICAgIDxuYW1lPkphdmFNYWlsIEFQSSBwb3AzIHByb3ZpZGVyPC9uYW1lPgorCisgICAgPHByb3BlcnRpZXM+CisJPG1haWwucGFja2FnZXMuZXhwb3J0PgorCSAgICBjb20uc3VuLm1haWwucG9wMzsgdmVyc2lvbj0ke21haWwub3NnaXZlcnNpb259CisJPC9tYWlsLnBhY2thZ2VzLmV4cG9ydD4KKyAgICA8L3Byb3BlcnRpZXM+Cis8L3Byb2plY3Q+CmRpZmYgLS1naXQgYS9wb3AzL3NyYy9tYWluL2phdmEvbW9kdWxlLWluZm8uamF2YSBiL3BvcDMvc3JjL21haW4vamF2YS9tb2R1bGUtaW5mby5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNjMGU4M2UKLS0tIC9kZXYvbnVsbAorKysgYi9wb3AzL3NyYy9tYWluL2phdmEvbW9kdWxlLWluZm8uamF2YQpAQCAtMCwwICsxLDI1IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorICoKKyAqIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAqIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAqIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICogdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyAqLworCittb2R1bGUgY29tLnN1bi5tYWlsLnBvcDMgeworICAgIGV4cG9ydHMgY29tLnN1bi5tYWlsLnBvcDM7CisgICAgcHJvdmlkZXMgamF2YXgubWFpbC5Qcm92aWRlciB3aXRoCisJY29tLnN1bi5tYWlsLnBvcDMuUE9QM1Byb3ZpZGVyLCBjb20uc3VuLm1haWwucG9wMy5QT1AzU1NMUHJvdmlkZXI7CisKKyAgICByZXF1aXJlcyBqYWthcnRhLm1haWw7CisgICAgcmVxdWlyZXMgamF2YS5sb2dnaW5nOworICAgIHJlcXVpcmVzIGphdmEuc2VjdXJpdHkuc2FzbDsKK30KZGlmZiAtLWdpdCBhL3BvcDMvc3JjL21haW4vcmVzb3VyY2VzL01FVEEtSU5GL01BTklGRVNULk1GIGIvcG9wMy9zcmMvbWFpbi9yZXNvdXJjZXMvTUVUQS1JTkYvTUFOSUZFU1QuTUYKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWYyMDliMgotLS0gL2Rldi9udWxsCisrKyBiL3BvcDMvc3JjL21haW4vcmVzb3VyY2VzL01FVEEtSU5GL01BTklGRVNULk1GCkBAIC0wLDAgKzEsOSBAQAorTWFuaWZlc3QtVmVyc2lvbjogMS4wCitFeHRlbnNpb24tTmFtZTogY29tLnN1bi5tYWlsLnBvcDMKK1NwZWNpZmljYXRpb24tVGl0bGU6IGNvbS5zdW4ubWFpbC5wb3AzCitTcGVjaWZpY2F0aW9uLVZlcnNpb246ICR7bWFpbC5zcGVjLnZlcnNpb259CitTcGVjaWZpY2F0aW9uLVZlbmRvcjogJHtwcm9qZWN0Lm9yZ2FuaXphdGlvbi5uYW1lfQorSW1wbGVtZW50YXRpb24tVGl0bGU6IGNvbS5zdW4ubWFpbC5wb3AzCitJbXBsZW1lbnRhdGlvbi1WZXJzaW9uOiAke21haWwudmVyc2lvbn0KK0ltcGxlbWVudGF0aW9uLVZlbmRvcjogJHtwcm9qZWN0Lm9yZ2FuaXphdGlvbi5uYW1lfQorSW1wbGVtZW50YXRpb24tVmVuZG9yLUlkOiBjb20uc3VuCmRpZmYgLS1naXQgYS9wb3AzL3NyYy9tYWluL3Jlc291cmNlcy9NRVRBLUlORi9qYXZhbWFpbC5wcm92aWRlcnMgYi9wb3AzL3NyYy9tYWluL3Jlc291cmNlcy9NRVRBLUlORi9qYXZhbWFpbC5wcm92aWRlcnMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjZkZTk5MwotLS0gL2Rldi9udWxsCisrKyBiL3BvcDMvc3JjL21haW4vcmVzb3VyY2VzL01FVEEtSU5GL2phdmFtYWlsLnByb3ZpZGVycwpAQCAtMCwwICsxLDMgQEAKKyMgSmF2YU1haWwgUE9QMyBwcm92aWRlciBPcmFjbGUKK3Byb3RvY29sPXBvcDM7IHR5cGU9c3RvcmU7IGNsYXNzPWNvbS5zdW4ubWFpbC5wb3AzLlBPUDNTdG9yZTsgdmVuZG9yPU9yYWNsZTsKK3Byb3RvY29sPXBvcDNzOyB0eXBlPXN0b3JlOyBjbGFzcz1jb20uc3VuLm1haWwucG9wMy5QT1AzU1NMU3RvcmU7IHZlbmRvcj1PcmFjbGU7CmRpZmYgLS1naXQgYS9wb3AzL3NyYy9tYWluL3Jlc291cmNlcy9NRVRBLUlORi9zZXJ2aWNlcy9qYXZheC5tYWlsLlByb3ZpZGVyIGIvcG9wMy9zcmMvbWFpbi9yZXNvdXJjZXMvTUVUQS1JTkYvc2VydmljZXMvamF2YXgubWFpbC5Qcm92aWRlcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZWY0ZGQ0Ci0tLSAvZGV2L251bGwKKysrIGIvcG9wMy9zcmMvbWFpbi9yZXNvdXJjZXMvTUVUQS1JTkYvc2VydmljZXMvamF2YXgubWFpbC5Qcm92aWRlcgpAQCAtMCwwICsxLDIgQEAKK2NvbS5zdW4ubWFpbC5wb3AzLlBPUDNQcm92aWRlcgorY29tLnN1bi5tYWlsLnBvcDMuUE9QM1NTTFByb3ZpZGVyCmRpZmYgLS1naXQgYS9wcm9qZWN0LnByb3BlcnRpZXMgYi9wcm9qZWN0LnByb3BlcnRpZXMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjFjYmE5OAotLS0gL2Rldi9udWxsCisrKyBiL3Byb2plY3QucHJvcGVydGllcwpAQCAtMCwwICsxLDE5IEBACisjCisjIENvcHlyaWdodCAoYykgMjAxMCwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorIworIyBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyMgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyMgaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorIworIyBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisjIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyMgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisjIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisjIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKyMKKyMgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisjCisKK2dsYXNzZmlzaC5tb2R1bGUubmFtZT1tYWlsCittYXZlbi5tb2RlLm9ubGluZT1mYWxzZQorYWN0aXZhdGlvbi5qYXI9JEhPTUUvZXh0L2FjdGl2YXRpb24uamFyCmRpZmYgLS1naXQgYS9wcm9qZWN0LnhtbCBiL3Byb2plY3QueG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQzYWEzMTgKLS0tIC9kZXYvbnVsbAorKysgYi9wcm9qZWN0LnhtbApAQCAtMCwwICsxLDQ3IEBACis8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJpc28tODg1OS0xIj8+Cis8IS0tCisKKyAgICBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKworICAgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICAgIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorCisgICAgVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICAgIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAgICBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAgICB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKworICAgIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorCistLT4KKworPHByb2plY3Q+CisgICAgPGV4dGVuZD4uLi9ib290c3RyYXAvcHJvamVjdC54bWw8L2V4dGVuZD4KKyAgICA8cG9tVmVyc2lvbj4zPC9wb21WZXJzaW9uPgorICAgIDxpZD4ke2dsYXNzZmlzaC5tb2R1bGUubmFtZX08L2lkPgorICAgIDxhcnRpZmFjdElkPm1haWw8L2FydGlmYWN0SWQ+CisgICAgPG5hbWU+bWFpbDwvbmFtZT4KKyAgICA8Z3JvdXBJZD4ke2dsYXNzZmlzaC5pbWFnZS5uYW1lfTwvZ3JvdXBJZD4KKyAgICA8Y3VycmVudFZlcnNpb24+OS4wLVNOQVBTSE9UPC9jdXJyZW50VmVyc2lvbj4KKyAgICA8b3JnYW5pemF0aW9uPgorICAgICAgICA8bmFtZT5TdW4gTWljcm9zeXN0ZW1zIEluYy48L25hbWU+CisgICAgICAgIDx1cmw+aHR0cDovL3d3dy5zdW4uY29tLzwvdXJsPgorICAgICAgICA8bG9nbz5odHRwOi8vamF2YS5uZXQvajJlZTwvbG9nbz4KKyAgICA8L29yZ2FuaXphdGlvbj4KKyAgICA8aW5jZXB0aW9uWWVhcj4yMDA1PC9pbmNlcHRpb25ZZWFyPgorICAgIDxwYWNrYWdlPmNvbS5zdW48L3BhY2thZ2U+CisgICAgPGxvZ28+aHR0cDovL2phdmEuc3VuLmNvbS9qMmVlPC9sb2dvPgorICAgIDxkZXNjcmlwdGlvbj5TSlNBUyA5LjAgR2xhc3NmaXNoIHByb2plY3QuPC9kZXNjcmlwdGlvbj4KKyAgICA8c2hvcnREZXNjcmlwdGlvbj5HbGFzc2Zpc2ggOS4wPC9zaG9ydERlc2NyaXB0aW9uPgorICAgIDx1cmw+aHR0cDovL2phdmEuc3VuLmNvbS9qMmVlPC91cmw+CisgICAgPGlzc3VlVHJhY2tpbmdVcmw+QnVnc3RlcjwvaXNzdWVUcmFja2luZ1VybD4KKyAgICA8c2l0ZUFkZHJlc3M+aHR0cDovL2J1Z3N0ZXI8L3NpdGVBZGRyZXNzPgorICAgIDxkaXN0cmlidXRpb25EaXJlY3Rvcnk+L2phdmEvcmUvc2pzYXNfcGUvPC9kaXN0cmlidXRpb25EaXJlY3Rvcnk+CisgICAgPHJlcG9zaXRvcnk+CisgICAgICAgIDxjb25uZWN0aW9uPnNjbToke2dsYXNzZmlzaC5jdnNyb290fTwvY29ubmVjdGlvbj4KKyAgICAgICAgPHVybD4ke2dsYXNzZmlzaC52aWV3Y3ZzfTwvdXJsPgorICAgIDwvcmVwb3NpdG9yeT4KKzwvcHJvamVjdD4KKwpkaWZmIC0tZ2l0IGEvcHVibGlzaC9wb20ueG1sIGIvcHVibGlzaC9wb20ueG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA1MzMwNTcKLS0tIC9kZXYvbnVsbAorKysgYi9wdWJsaXNoL3BvbS54bWwKQEAgLTAsMCArMSwxMDkgQEAKKzw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9Imlzby04ODU5LTEiPz4KKzwhLS0KKworICAgIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorCisgICAgVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgICAgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisKKyAgICBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgICAgTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICAgIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICAgIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorCisgICAgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisKKy0tPgorCis8cHJvamVjdCB4bWxucz0iaHR0cDovL21hdmVuLmFwYWNoZS5vcmcvUE9NLzQuMC4wIgorCXhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiCisJeHNpOnNjaGVtYUxvY2F0aW9uPSJodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9QT00vNC4wLjAKKwkJCSAgICBodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9tYXZlbi12NF8wXzAueHNkIj4KKyAgICA8cGFyZW50PgorCTxncm91cElkPmNvbS5zdW4ubWFpbDwvZ3JvdXBJZD4KKwk8YXJ0aWZhY3RJZD5hbGw8L2FydGlmYWN0SWQ+CisJPHZlcnNpb24+MS42LjM8L3ZlcnNpb24+CisgICAgPC9wYXJlbnQ+CisgICAgPG1vZGVsVmVyc2lvbj40LjAuMDwvbW9kZWxWZXJzaW9uPgorICAgIDxncm91cElkPmNvbS5zdW4ubWFpbDwvZ3JvdXBJZD4KKyAgICA8YXJ0aWZhY3RJZD5wdWJsaXNoPC9hcnRpZmFjdElkPgorICAgIDxwYWNrYWdpbmc+cG9tPC9wYWNrYWdpbmc+CisgICAgPHZlcnNpb24+MS42LjM8L3ZlcnNpb24+CisgICAgPG5hbWU+SmF2YU1haWwgQVBJIHB1Ymxpc2ggcHJvamVjdDwvbmFtZT4KKworICAgIDxidWlsZD4KKwk8cGx1Z2lucz4KKwkgICAgPCEtLQorCQlUaGlzIGlzIHRoZSBydWxlIHRoYXQgY29sbGVjdHMgdGhlIHJlbGVhc2UgYXJ0aWZhY3RzIGFuZAorCQljcmVhdGVzIHRoZSBzYW1wbGVzIHppcCBmaWxlIGZvciBhIHJlbGVhc2UuCisJICAgIC0tPgorCSAgICA8cGx1Z2luPgorCQk8YXJ0aWZhY3RJZD5tYXZlbi1hc3NlbWJseS1wbHVnaW48L2FydGlmYWN0SWQ+CisJCTxpbmhlcml0ZWQ+ZmFsc2U8L2luaGVyaXRlZD4KKwkJPGV4ZWN1dGlvbnM+CisJCSAgICA8ZXhlY3V0aW9uPgorCQkJPHBoYXNlPnBhY2thZ2U8L3BoYXNlPgorCQkJPGdvYWxzPgorCQkJICAgIDxnb2FsPnNpbmdsZTwvZ29hbD4KKwkJCTwvZ29hbHM+CisJCQk8Y29uZmlndXJhdGlvbj4KKwkJCSAgICA8ZmluYWxOYW1lPmphdmFtYWlsPC9maW5hbE5hbWU+CisJCQkgICAgPGRlc2NyaXB0b3JzPgorCQkJCTxkZXNjcmlwdG9yPnB1Ymxpc2gueG1sPC9kZXNjcmlwdG9yPgorCQkJCTxkZXNjcmlwdG9yPnNhbXBsZXMueG1sPC9kZXNjcmlwdG9yPgorCQkJICAgIDwvZGVzY3JpcHRvcnM+CisJCQk8L2NvbmZpZ3VyYXRpb24+CisJCSAgICA8L2V4ZWN1dGlvbj4KKwkJPC9leGVjdXRpb25zPgorCSAgICA8L3BsdWdpbj4KKwk8L3BsdWdpbnM+CisgICAgPC9idWlsZD4KKworICAgIDxkZXBlbmRlbmNpZXM+CisgICAgICAgIDxkZXBlbmRlbmN5PgorICAgICAgICAgICAgPGdyb3VwSWQ+Y29tLnN1bi5tYWlsPC9ncm91cElkPgorICAgICAgICAgICAgPGFydGlmYWN0SWQ+amFrYXJ0YS5tYWlsPC9hcnRpZmFjdElkPgorCSAgICA8dmVyc2lvbj4xLjYuMzwvdmVyc2lvbj4KKyAgICAgICAgPC9kZXBlbmRlbmN5PgorICAgIDwhLS0KKyAgICAgICAgPGRlcGVuZGVuY3k+CisgICAgICAgICAgICA8Z3JvdXBJZD5jb20uc3VuLm1haWw8L2dyb3VwSWQ+CisgICAgICAgICAgICA8YXJ0aWZhY3RJZD5kZW1vPC9hcnRpZmFjdElkPgorCSAgICA8dmVyc2lvbj4xLjYuMzwvdmVyc2lvbj4KKyAgICAgICAgPC9kZXBlbmRlbmN5PgorICAgICAgICA8ZGVwZW5kZW5jeT4KKyAgICAgICAgICAgIDxncm91cElkPmNvbS5zdW4ubWFpbDwvZ3JvdXBJZD4KKyAgICAgICAgICAgIDxhcnRpZmFjdElkPmNsaWVudDwvYXJ0aWZhY3RJZD4KKwkgICAgPHZlcnNpb24+MS42LjM8L3ZlcnNpb24+CisgICAgICAgIDwvZGVwZW5kZW5jeT4KKyAgICAgICAgPGRlcGVuZGVuY3k+CisgICAgICAgICAgICA8Z3JvdXBJZD5jb20uc3VuLm1haWw8L2dyb3VwSWQ+CisgICAgICAgICAgICA8YXJ0aWZhY3RJZD5zZXJ2bGV0PC9hcnRpZmFjdElkPgorCSAgICA8dmVyc2lvbj4xLjYuMzwvdmVyc2lvbj4KKyAgICAgICAgPC9kZXBlbmRlbmN5PgorICAgICAgICA8ZGVwZW5kZW5jeT4KKyAgICAgICAgICAgIDxncm91cElkPmNvbS5zdW4ubWFpbDwvZ3JvdXBJZD4KKyAgICAgICAgICAgIDxhcnRpZmFjdElkPndlYmFwcDwvYXJ0aWZhY3RJZD4KKwkgICAgPHR5cGU+d2FyPC90eXBlPgorCSAgICA8dmVyc2lvbj4xLjYuMzwvdmVyc2lvbj4KKyAgICAgICAgPC9kZXBlbmRlbmN5PgorICAgICAgICA8ZGVwZW5kZW5jeT4KKyAgICAgICAgICAgIDxncm91cElkPmNvbS5zdW4ubWFpbDwvZ3JvdXBJZD4KKyAgICAgICAgICAgIDxhcnRpZmFjdElkPnRhZ2xpYjwvYXJ0aWZhY3RJZD4KKwkgICAgPHZlcnNpb24+MS42LjM8L3ZlcnNpb24+CisgICAgICAgIDwvZGVwZW5kZW5jeT4KKyAgICAgICAgPGRlcGVuZGVuY3k+CisgICAgICAgICAgICA8Z3JvdXBJZD5jb20uc3VuLm1haWw8L2dyb3VwSWQ+CisgICAgICAgICAgICA8YXJ0aWZhY3RJZD5sb2dnaW5nPC9hcnRpZmFjdElkPgorCSAgICA8dmVyc2lvbj4xLjYuMzwvdmVyc2lvbj4KKyAgICAgICAgPC9kZXBlbmRlbmN5PgorICAgICAgICA8ZGVwZW5kZW5jeT4KKyAgICAgICAgICAgIDxncm91cElkPmNvbS5zdW4ubWFpbDwvZ3JvdXBJZD4KKyAgICAgICAgICAgIDxhcnRpZmFjdElkPm91dGxvb2s8L2FydGlmYWN0SWQ+CisJICAgIDx2ZXJzaW9uPjEuNi4zPC92ZXJzaW9uPgorICAgICAgICA8L2RlcGVuZGVuY3k+CisgICAgLS0+CisgICAgPC9kZXBlbmRlbmNpZXM+Cis8L3Byb2plY3Q+CmRpZmYgLS1naXQgYS9wdWJsaXNoL3B1Ymxpc2gueG1sIGIvcHVibGlzaC9wdWJsaXNoLnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hNjEyMzQ4Ci0tLSAvZGV2L251bGwKKysrIGIvcHVibGlzaC9wdWJsaXNoLnhtbApAQCAtMCwwICsxLDU5IEBACis8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJpc28tODg1OS0xIj8+Cis8IS0tCisKKyAgICBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKworICAgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICAgIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorCisgICAgVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICAgIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAgICBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAgICB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKworICAgIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorCistLT4KKworPGFzc2VtYmx5PgorICAgIDxpZD5wdWJsaXNoPC9pZD4KKyAgICA8Zm9ybWF0cz4KKwk8Zm9ybWF0PmRpcjwvZm9ybWF0PgorICAgIDwvZm9ybWF0cz4KKyAgICA8aW5jbHVkZUJhc2VEaXJlY3Rvcnk+ZmFsc2U8L2luY2x1ZGVCYXNlRGlyZWN0b3J5PgorICAgIDxkZXBlbmRlbmN5U2V0cz4KKwk8IS0tIGluY2x1ZGUgdGhlIG1haW4gamFrYXJ0YS5tYWlsLmphciBmaWxlIC0tPgorCTxkZXBlbmRlbmN5U2V0PgorCSAgICA8aW5jbHVkZXM+CisJCTxpbmNsdWRlPmNvbS5zdW4ubWFpbDpqYWthcnRhLm1haWw8L2luY2x1ZGU+CisJICAgIDwvaW5jbHVkZXM+CisJICAgIDx1c2VUcmFuc2l0aXZlRGVwZW5kZW5jaWVzPmZhbHNlPC91c2VUcmFuc2l0aXZlRGVwZW5kZW5jaWVzPgorCSAgICA8dW5wYWNrPmZhbHNlPC91bnBhY2s+CisJICAgIDxvdXRwdXRGaWxlTmFtZU1hcHBpbmc+CisJCWpha2FydGEubWFpbC5qYXIKKwkgICAgPC9vdXRwdXRGaWxlTmFtZU1hcHBpbmc+CisJPC9kZXBlbmRlbmN5U2V0PgorICAgIDwvZGVwZW5kZW5jeVNldHM+CisKKyAgICA8IS0tIGluY2x1ZGUgZG9jcywgc3BlY3MsIGFuZCBqYXZhZG9jcyAtLT4KKyAgICA8ZmlsZVNldHM+CisJPGZpbGVTZXQ+CisJICAgIDxkaXJlY3Rvcnk+Li4vZG9jL3JlbGVhc2U8L2RpcmVjdG9yeT4KKwkgICAgPG91dHB1dERpcmVjdG9yeT48L291dHB1dERpcmVjdG9yeT4KKwkgICAgPGZpbHRlcmVkPnRydWU8L2ZpbHRlcmVkPgorCSAgICA8aW5jbHVkZXM+CisJCTxpbmNsdWRlPioudHh0PC9pbmNsdWRlPgorCSAgICA8L2luY2x1ZGVzPgorCTwvZmlsZVNldD4KKwk8ZmlsZVNldD4KKwkgICAgPGRpcmVjdG9yeT4uLi9kb2Mvc3BlYzwvZGlyZWN0b3J5PgorCSAgICA8b3V0cHV0RGlyZWN0b3J5PmRvY3M8L291dHB1dERpcmVjdG9yeT4KKwk8L2ZpbGVTZXQ+CisJPGZpbGVTZXQ+CisJICAgIDxkaXJlY3Rvcnk+Li4vamF2YWRvYy90YXJnZXQvc2l0ZS9hcGlkb2NzPC9kaXJlY3Rvcnk+CisJICAgIDxvdXRwdXREaXJlY3Rvcnk+ZG9jcy9hcGk8L291dHB1dERpcmVjdG9yeT4KKwk8L2ZpbGVTZXQ+CisgICAgPC9maWxlU2V0cz4KKzwvYXNzZW1ibHk+CmRpZmYgLS1naXQgYS9wdWJsaXNoL3NhbXBsZXMueG1sIGIvcHVibGlzaC9zYW1wbGVzLnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42NDhmODhmCi0tLSAvZGV2L251bGwKKysrIGIvcHVibGlzaC9zYW1wbGVzLnhtbApAQCAtMCwwICsxLDgyIEBACis8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJpc28tODg1OS0xIj8+Cis8IS0tCisKKyAgICBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKworICAgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICAgIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorCisgICAgVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICAgIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAgICBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAgICB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKworICAgIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorCistLT4KKworPGFzc2VtYmx5PgorICAgIDxpZD5zYW1wbGVzPC9pZD4KKyAgICA8Zm9ybWF0cz4KKwk8Zm9ybWF0PnppcDwvZm9ybWF0PgorICAgIDwvZm9ybWF0cz4KKyAgICA8YmFzZURpcmVjdG9yeT5qYXZhbWFpbC1zYW1wbGVzPC9iYXNlRGlyZWN0b3J5PgorICAgIDxmaWxlU2V0cz4KKwk8ZmlsZVNldD4KKwkgICAgPGRpcmVjdG9yeT4uLi9kZW1vL3NyYy9tYWluL2phdmE8L2RpcmVjdG9yeT4KKwkgICAgPG91dHB1dERpcmVjdG9yeT4vPC9vdXRwdXREaXJlY3Rvcnk+CisJICAgIDxleGNsdWRlcz4KKwkJPGV4Y2x1ZGU+aW50ZXJuYWwvKio8L2V4Y2x1ZGU+CisJICAgIDwvZXhjbHVkZXM+CisJPC9maWxlU2V0PgorCTxmaWxlU2V0PgorCSAgICA8ZGlyZWN0b3J5Pi4uL2NsaWVudC9zcmMvbWFpbi9qYXZhPC9kaXJlY3Rvcnk+CisJICAgIDxvdXRwdXREaXJlY3Rvcnk+Y2xpZW50PC9vdXRwdXREaXJlY3Rvcnk+CisJPC9maWxlU2V0PgorCTxmaWxlU2V0PgorCSAgICA8ZGlyZWN0b3J5Pi4uL3dlYmFwcC9zcmMvbWFpbi9qYXZhPC9kaXJlY3Rvcnk+CisJICAgIDxvdXRwdXREaXJlY3Rvcnk+d2ViYXBwL3NyYy9jbGFzc2VzPC9vdXRwdXREaXJlY3Rvcnk+CisJPC9maWxlU2V0PgorCTxmaWxlU2V0PgorCSAgICA8ZGlyZWN0b3J5Pi4uL3dlYmFwcC9zcmMvbWFpbi93ZWJhcHA8L2RpcmVjdG9yeT4KKwkgICAgPG91dHB1dERpcmVjdG9yeT53ZWJhcHAvc3JjL2RvY3Jvb3Q8L291dHB1dERpcmVjdG9yeT4KKwk8L2ZpbGVTZXQ+CisJPGZpbGVTZXQ+CisJICAgIDxkaXJlY3Rvcnk+Li4vd2ViYXBwLzwvZGlyZWN0b3J5PgorCSAgICA8b3V0cHV0RGlyZWN0b3J5PndlYmFwcDwvb3V0cHV0RGlyZWN0b3J5PgorCSAgICA8aW5jbHVkZXM+CisJCTxpbmNsdWRlPmJ1aWxkLio8L2luY2x1ZGU+CisJCTxpbmNsdWRlPndlYmFwcC5SRUFETUUudHh0PC9pbmNsdWRlPgorCSAgICA8L2luY2x1ZGVzPgorCTwvZmlsZVNldD4KKwk8ZmlsZVNldD4KKwkgICAgPGRpcmVjdG9yeT4uLi90YWdsaWIvc3JjL21haW4vamF2YTwvZGlyZWN0b3J5PgorCSAgICA8b3V0cHV0RGlyZWN0b3J5PndlYmFwcC9zcmMvdGFnbGliPC9vdXRwdXREaXJlY3Rvcnk+CisJPC9maWxlU2V0PgorCTxmaWxlU2V0PgorCSAgICA8ZGlyZWN0b3J5Pi4uL3RhZ2xpYi9zcmMvbWFpbi9yZXNvdXJjZXM8L2RpcmVjdG9yeT4KKwkgICAgPG91dHB1dERpcmVjdG9yeT53ZWJhcHAvc3JjL3RhZ2xpYjwvb3V0cHV0RGlyZWN0b3J5PgorCTwvZmlsZVNldD4KKwk8ZmlsZVNldD4KKwkgICAgPGRpcmVjdG9yeT4uLi9vdXRsb29rL3NyYy9tYWluL2phdmE8L2RpcmVjdG9yeT4KKwkgICAgPG91dHB1dERpcmVjdG9yeT5vdXRsb29rPC9vdXRwdXREaXJlY3Rvcnk+CisJPC9maWxlU2V0PgorCTxmaWxlU2V0PgorCSAgICA8ZGlyZWN0b3J5Pi4uL2xvZ2dpbmcvc3JjL21haW4vamF2YTwvZGlyZWN0b3J5PgorCSAgICA8b3V0cHV0RGlyZWN0b3J5PmxvZ2dpbmc8L291dHB1dERpcmVjdG9yeT4KKwk8L2ZpbGVTZXQ+CisgICAgPC9maWxlU2V0cz4KKyAgICA8ZGVwZW5kZW5jeVNldHM+CisJPCEtLSBpbmNsdWRlIHNvdXJjZXMgZnJvbSB0aGUgZGVtbyBtb2R1bGVzIC0tPgorCTwhLS0KKwk8ZGVwZW5kZW5jeVNldD4KKwkgICAgPGluY2x1ZGVzPgorCQk8aW5jbHVkZT5jb20uc3VuLm1haWw6ZGVtbzpqYXI6c291cmNlczwvaW5jbHVkZT4KKwkgICAgPC9pbmNsdWRlcz4KKwkgICAgPHVucGFjaz50cnVlPC91bnBhY2s+CisJPC9kZXBlbmRlbmN5U2V0PgorCS0tPgorICAgIDwvZGVwZW5kZW5jeVNldHM+Cis8L2Fzc2VtYmx5PgpkaWZmIC0tZ2l0IGEvc2VydmxldC9wb20ueG1sIGIvc2VydmxldC9wb20ueG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU3N2Y1OWYKLS0tIC9kZXYvbnVsbAorKysgYi9zZXJ2bGV0L3BvbS54bWwKQEAgLTAsMCArMSw3OCBAQAorPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PgorPCEtLQorCisgICAgQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisKKyAgICBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAgICB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKworICAgIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyAgICBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgICAgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCisgICAgdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisKKyAgICBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKworLS0+CisKKzxwcm9qZWN0IHhtbG5zPSJodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9QT00vNC4wLjAiCisJeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIKKwl4c2k6c2NoZW1hTG9jYXRpb249Imh0dHA6Ly9tYXZlbi5hcGFjaGUub3JnL1BPTS80LjAuMAorCQkJICAgIGh0dHA6Ly9tYXZlbi5hcGFjaGUub3JnL21hdmVuLXY0XzBfMC54c2QiPgorICAgIDxwYXJlbnQ+CisJPGdyb3VwSWQ+Y29tLnN1bi5tYWlsPC9ncm91cElkPgorCTxhcnRpZmFjdElkPmFsbDwvYXJ0aWZhY3RJZD4KKwk8dmVyc2lvbj4xLjYuMzwvdmVyc2lvbj4KKyAgICA8L3BhcmVudD4KKyAgICA8bW9kZWxWZXJzaW9uPjQuMC4wPC9tb2RlbFZlcnNpb24+CisgICAgPGdyb3VwSWQ+Y29tLnN1bi5tYWlsPC9ncm91cElkPgorICAgIDxhcnRpZmFjdElkPnNlcnZsZXQ8L2FydGlmYWN0SWQ+CisgICAgPHBhY2thZ2luZz5qYXI8L3BhY2thZ2luZz4KKyAgICA8bmFtZT5KYXZhTWFpbCBBUEkgZGVtbyBzZXJ2bGV0PC9uYW1lPgorCisgICAgPGJ1aWxkPgorICAgICAgICA8cGx1Z2lucz4KKwkgICAgPCEtLQorCQlOZWVkIHRvIGRpc2FibGUgdGhlIG1hdmVuLWJ1bmRsZS1wbHVnaW4gYmVjYXVzZSB0aGUKKwkJbmV3IHZlcnNpb24gZG9lc24ndCBsaWtlIGNsYXNzZXMgaW4gdGhlIGRlZmF1bHQgcGFja2FnZS4KKwkgICAgLS0+CisJICAgIDxwbHVnaW4+CisJCTxncm91cElkPm9yZy5hcGFjaGUuZmVsaXg8L2dyb3VwSWQ+CisJCTxhcnRpZmFjdElkPm1hdmVuLWJ1bmRsZS1wbHVnaW48L2FydGlmYWN0SWQ+CisJCTxleGVjdXRpb25zPgorCQkgICAgPGV4ZWN1dGlvbj4KKwkJCTxpZD5vc2dpLW1hbmlmZXN0PC9pZD4KKwkJCTxwaGFzZT5ub25lPC9waGFzZT4KKwkJICAgIDwvZXhlY3V0aW9uPgorCQk8L2V4ZWN1dGlvbnM+CisJICAgIDwvcGx1Z2luPgorCisJICAgIDwhLS0KKwkJQmVjYXVzZSB0aGUgbWF2ZW4tamFyLXBsdWdpbiBkZXBlbmRzIG9uIHRoZSBtYW5pZmVzdCBmaWxlCisJCWNyZWF0ZWQgYnkgdGhlIG1hdmVuLWJ1bmRsZS1wbHVnaW4sIHdlIG5lZWQgdG8gZGlzYWJsZSBpdCB0b28uCisJICAgIC0tPgorCSAgICA8cGx1Z2luPgorCQk8YXJ0aWZhY3RJZD5tYXZlbi1qYXItcGx1Z2luPC9hcnRpZmFjdElkPgorCQk8ZXhlY3V0aW9ucz4KKwkJICAgIDxleGVjdXRpb24+CisJCQk8aWQ+ZGVmYXVsdC1qYXI8L2lkPgorCQkJPHBoYXNlPm5vbmU8L3BoYXNlPgorCQkgICAgPC9leGVjdXRpb24+CisJCTwvZXhlY3V0aW9ucz4KKwkgICAgPC9wbHVnaW4+CisgICAgICAgIDwvcGx1Z2lucz4KKyAgICA8L2J1aWxkPgorCisgICAgPGRlcGVuZGVuY2llcz4KKyAgICAgICAgPGRlcGVuZGVuY3k+CisgICAgICAgICAgICA8Z3JvdXBJZD5qYXZheC5zZXJ2bGV0PC9ncm91cElkPgorICAgICAgICAgICAgPGFydGlmYWN0SWQ+c2VydmxldC1hcGk8L2FydGlmYWN0SWQ+CisgICAgICAgIDwvZGVwZW5kZW5jeT4KKyAgICAgICAgPGRlcGVuZGVuY3k+CisgICAgICAgICAgICA8Z3JvdXBJZD5jb20uc3VuLm1haWw8L2dyb3VwSWQ+CisgICAgICAgICAgICA8YXJ0aWZhY3RJZD5qYWthcnRhLm1haWw8L2FydGlmYWN0SWQ+CisgICAgICAgIDwvZGVwZW5kZW5jeT4KKyAgICA8L2RlcGVuZGVuY2llcz4KKzwvcHJvamVjdD4KZGlmZiAtLWdpdCBhL3NlcnZsZXQvc3JjL21haW4vamF2YS9KYXZhTWFpbC5odG1sIGIvc2VydmxldC9zcmMvbWFpbi9qYXZhL0phdmFNYWlsLmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGNlMGY5NgotLS0gL2Rldi9udWxsCisrKyBiL3NlcnZsZXQvc3JjL21haW4vamF2YS9KYXZhTWFpbC5odG1sCkBAIC0wLDAgKzEsMTE2IEBACis8IURPQ1RZUEUgSFRNTCBQVUJMSUMgIi0vL1czQy8vRFREIEhUTUwgMy4yLy9FTiI+Cis8SFRNTD4KKzwhLS0KKworICAgIENvcHlyaWdodCAoYykgMTk5OCwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorCisgICAgVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgICAgdGVybXMgb2YgdGhlIEVjbGlwc2UgRGlzdHJpYnV0aW9uIExpY2Vuc2Ugdi4gMS4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisKKyAgICBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQlNELTMtQ2xhdXNlCisKKy0tPgorCis8SEVBRD4KKwk8TUVUQSBIVFRQLUVRVUlWPSJDb250ZW50LVR5cGUiIENPTlRFTlQ9InRleHQvaHRtbDtDSEFSU0VUPWlzby04ODU5LTEiPgorCTxUSVRMRT5KYXZhTWFpbDwvVElUTEU+Cis8L0hFQUQ+CisKKzxCT0RZIEJHQ09MT1I9IiNDQ0NDRkYiPgorCis8Rk9STSBBQ1RJT049Ii9zZXJ2bGV0L0phdmFNYWlsU2VydmxldCIgTUVUSE9EPSJQT1NUIgorCUVOQ1RZUEU9ImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCI+Cis8UCBBTElHTj0iQ0VOVEVSIj48Qj48Rk9OVCBTSVpFPSI1IiBGQUNFPSJBcmlhbCwgSGVsdmV0aWNhIj4KK1dlbGNvbWUgdG8gSmF2YU1haWwKKzwvRk9OVD48L0I+PC9QPgorCis8UCBBTElHTj0iQ0VOVEVSIj48Qj48Rk9OVCBTSVpFPSI1IiBGQUNFPSJBcmlhbCwgSGVsdmV0aWNhIj4KK0hUTUwgRW1haWwgUmVhZGVyIERlbW8KKzwvRk9OVD48L0I+PC9QPgorPENFTlRFUj4KKzxQPgorPFRBQkxFIEJPUkRFUj0iMCIgV0lEVEg9IjEwMCUiPgorCTxUUj4KKwkJPFREIFdJRFRIPSI0MCUiPgorCQkJPFAgQUxJR049IlJJR0hUIj48Rk9OVCBGQUNFPSJBcmlhbCwgSGVsdmV0aWNhIj4KKwkJCUlNQVAgSG9zdG5hbWU6PC9GT05UPgorCQk8L1REPgorCQk8VEQgV0lEVEg9IjYwJSI+PElOUFVUIFRZUEU9IlRFWFQiIE5BTUU9Imhvc3RuYW1lIiBTSVpFPSIyNSI+CisJCTwvVEQ+CisJPC9UUj4KKwk8VFI+CisJCTxURCBXSURUSD0iNDAlIj4KKwkJCTxQIEFMSUdOPSJSSUdIVCI+PEZPTlQgRkFDRT0iQXJpYWwsIEhlbHZldGljYSI+CisJCQlVc2VybmFtZTo8L0ZPTlQ+CisJCTwvVEQ+CisJCTxURCBXSURUSD0iNjAlIj48SU5QVVQgVFlQRT0iVEVYVCIgTkFNRT0idXNlcm5hbWUiIFNJWkU9IjI1Ij4KKwkJPC9URD4KKwk8L1RSPgorCTxUUj4KKwkJPFREIFdJRFRIPSI0MCUiPgorCQkJPFAgQUxJR049IlJJR0hUIj48Rk9OVCBGQUNFPSJBcmlhbCwgSGVsdmV0aWNhIj4KKwkJCVBhc3N3b3JkOjwvRk9OVD4KKwkJPC9URD4KKwkJPFREIFdJRFRIPSI2MCUiPjxJTlBVVCBUWVBFPSJQQVNTV09SRCIgTkFNRT0icGFzc3dvcmQiCisJCQlTSVpFPSIyNSI+PC9URD4KKwk8L1RSPgorPC9UQUJMRT4KKzxJTlBVVCBUWVBFPSJTVUJNSVQiIFZBTFVFPSJMb2dpbiI+Cis8SU5QVVQgVFlQRT0iUkVTRVQiIE5BTUU9IlJlc2V0IiBWQUxVRT0iUmVzZXQiPjwvUD4KKzwvQ0VOVEVSPgorPFA+Cis8SFIgQUxJR049IkNFTlRFUiI+Cis8L1A+Cis8UD48Qj48ST48Rk9OVCBGQUNFPSJBcmlhbCwgSGVsdmV0aWNhIj5PdmVydmlldzo8L0ZPTlQ+PC9JPjwvQj48L1A+CisKKzxGT05UIFNJWkU9IjIiIEZBQ0U9IkFyaWFsLCBIZWx2ZXRpY2EiPgorPGI+VEhJUyBJUyBBIERFTU8hISE8L2I+IFBsZWFzZSBzZWUgdGhlIEphdmFNYWlsU2VydmxldC5SRUFETUUudHh0IAorZmlsZSBmb3IgaW5mb3JtYXRpb24gb24gaG93IHRvCitjb21waWxlIGFuZCBydW4gdGhlIHNlcnZsZXQuPGJyPiA8YnI+CitUaGlzIGlzIGEgc2VydmxldCB0aGF0IGRlbW9uc3RyYXRlcyB0aGUgdXNlIG9mIEphdmFNYWlsIEFQSXMKK2luIGEgMy10aWVyIGFwcGxpY2F0aW9uLiBJdCBhbGxvd3MgdGhlIHVzZXIgdG8gbG9naW4gdG8gYW4gCitJTUFQIHN0b3JlLCBsaXN0IGFsbCB0aGUgbWVzc2FnZXMgaW4gdGhlIElOQk9YIGZvbGRlciwgdmlldworc2VsZWN0ZWQgbWVzc2FnZXMsIGNvbXBvc2UgYW5kIHNlbmQgYSBtZXNzYWdlLCBhbmQgbG9nb3V0LgorPC9GT05UPgorCis8UD48Qj48ST48Rk9OVCBGQUNFPSJBcmlhbCwgSGVsdmV0aWNhIj5GZWF0dXJlczo8L0ZPTlQ+PC9JPjwvQj48L1A+CisKKzxVTD4KKwk8TEk+PEZPTlQgU0laRT0iMiIgRkFDRT0iQXJpYWwsIEhlbHZldGljYSI+CisJSFRNTCBhY2Nlc3MgdG8geW91ciBJTUFQIG1haWxib3g8L0ZPTlQ+CisJPExJPjxGT05UIFNJWkU9IjIiIEZBQ0U9IkFyaWFsLCBIZWx2ZXRpY2EiPgorCVByb3h5LWFibGUgYW55d2hlcmUgSFRUUCBjYW4gYmUgcHJveGllZDwvRk9OVD4KKwk8TEk+PEZPTlQgU0laRT0iMiIgRkFDRT0iQXJpYWwsIEhlbHZldGljYSI+RkFTVCE8L0ZPTlQ+CisJPExJPjxGT05UIFNJWkU9IjIiIEZBQ0U9IkFyaWFsLCBIZWx2ZXRpY2EiPkVhc3kgdG8gdXNlPC9GT05UPgorCTxMST48Rk9OVCBTSVpFPSIyIiBGQUNFPSJBcmlhbCwgSGVsdmV0aWNhIj4KKwlVc2VzIHdlYiBicm93c2VyJ3MgY29udGVudCBoYW5kbGluZyBjYXBhYmlsaXRpZXM8L0ZPTlQ+CisJPExJPjxGT05UIFNJWkU9IjIiIEZBQ0U9IkFyaWFsLCBIZWx2ZXRpY2EiPgorCVVsdHJhIHNtYWxsOiAxIHNlcnZsZXQgKDIgY2xhc3MgZmlsZXMpIGFuZCAxIGh0bWwgZmlsZSAodGhpcyBvbmUpPC9GT05UPgorPC9VTD4KKworPFA+PEI+PEk+PEZPTlQgRkFDRT0iQXJpYWwsIEhlbHZldGljYSI+TGltaXRhdGlvbnM6PC9GT05UPjwvST48L0I+PC9QPgorCis8VUw+CisJPExJPjxGT05UIFNJWkU9IjIiIEZBQ0U9IkFyaWFsLCBIZWx2ZXRpY2EiPgorCU9ubHkgSU5CT1ggc3VwcG9ydCAobm8gdXNlciBmb2xkZXJzKTwvRk9OVD4KKwk8TEk+PEZPTlQgU0laRT0iMiIgRkFDRT0iQXJpYWwsIEhlbHZldGljYSI+CisJQ2FuJ3QgZGVsZXRlLCBjb3B5LCBtb3ZlLCBwcmludCwgc2F2ZSwgZm9yd2FyZCwgcmVwbHkgdG8sIHNlYXJjaCBpbgorCW1lc3NhZ2VzIC0tPEJSPgorCWJ1dCBpdCBjb3VsZCBiZSBkb25lPC9GT05UPgorCTxMST48Rk9OVCBTSVpFPSIyIiBGQUNFPSJBcmlhbCwgSGVsdmV0aWNhIj4KKwlEb2Vzbid0IGNoZWNrIGZvciBuZXcgbWVzc2FnZXMgKGhhdmUgdG8gbG9nIG91dCBhbmQgbG9nIGJhY2sgaXQpPC9GT05UPgorPC9VTD4KKworPFA+Cis8SFIgQUxJR049IkNFTlRFUiI+Cis8L1A+CisKKzxQPjxGT05UIEZBQ0U9IkFyaWFsLCBIZWx2ZXRpY2EiPkZlZWRiYWNrIHRvIDwvRk9OVD4KKzxBIEhSRUY9Im1haWx0bzpqYXZhbWFpbF93d0BvcmFjbGUuY29tIj4KKzxGT05UIEZBQ0U9IkFyaWFsLCBIZWx2ZXRpY2EiPmphdmFtYWlsX3d3QG9yYWNsZS5jb208L0ZPTlQ+PC9BPgorPC9GT1JNPgorCis8L0JPRFk+CisKKzwvSFRNTD4KZGlmZiAtLWdpdCBhL3NlcnZsZXQvc3JjL21haW4vamF2YS9KYXZhTWFpbFNlcnZsZXQuamF2YSBiL3NlcnZsZXQvc3JjL21haW4vamF2YS9KYXZhTWFpbFNlcnZsZXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NGMwNzc1Ci0tLSAvZGV2L251bGwKKysrIGIvc2VydmxldC9zcmMvbWFpbi9qYXZhL0phdmFNYWlsU2VydmxldC5qYXZhCkBAIC0wLDAgKzEsNjYwIEBACisvKgorICogQ29weXJpZ2h0IChjKSAxOTk4LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBEaXN0cmlidXRpb24gTGljZW5zZSB2LiAxLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9vcmcvZG9jdW1lbnRzL2VkbC12MTAucGhwLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBCU0QtMy1DbGF1c2UKKyAqLworCitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmEudXRpbC4qOworaW1wb3J0IGphdmEudGV4dC4qOworCitpbXBvcnQgamF2YXguc2VydmxldC4qOworaW1wb3J0IGphdmF4LnNlcnZsZXQuaHR0cC4qOworaW1wb3J0IGphdmF4Lm1haWwuKjsKK2ltcG9ydCBqYXZheC5tYWlsLlBhcnQ7CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC4qOworaW1wb3J0IGphdmF4LmFjdGl2YXRpb24uKjsKKworCisvKioKKyAqIFRoaXMgaXMgYSBzZXJ2bGV0IHRoYXQgZGVtb25zdHJhdGVzIHRoZSB1c2Ugb2YgSmF2YU1haWwgQVBJcworICogaW4gYSAzLXRpZXIgYXBwbGljYXRpb24uIEl0IGFsbG93cyB0aGUgdXNlciB0byBsb2dpbiB0byBhbiAKKyAqIElNQVAgc3RvcmUsIGxpc3QgYWxsIHRoZSBtZXNzYWdlcyBpbiB0aGUgSU5CT1ggZm9sZGVyLCB2aWV3CisgKiBzZWxlY3RlZCBtZXNzYWdlcywgY29tcG9zZSBhbmQgc2VuZCBhIG1lc3NhZ2UsIGFuZCBsb2dvdXQuCisgKiA8cD4KKyAqIFBsZWFzZSBub3RlOiBUaGlzIGlzIE5PVCBhbiBleGFtcGxlIG9mIGhvdyB0byB3cml0ZSBzZXJ2bGV0cyEgCisgKiBUaGlzIGlzIHNpbXBseSB0byBzaG93IHRoYXQgSmF2YU1haWwgY2FuIGJlIHVzZWQgaW4gYSBzZXJ2bGV0LgorICogPHA+CisgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBvbiB0aGlzIHNlcnZsZXQsIHNlZSB0aGUgCisgKiBKYXZhTWFpbFNlcnZsZXQuUkVBRE1FLnR4dCBmaWxlLiAKKyAqIDxwPgorICogRm9yIG1vcmUgaW5mb3JtYXRpb24gb24gc2VydmxldHMsIHNlZSAKKyAqIDxhIGhyZWY9Imh0dHA6Ly9qYXZhLnN1bi5jb20vcHJvZHVjdHMvamF2YS1zZXJ2ZXIvc2VydmxldHMvaW5kZXguaHRtbCI+CisgKiBodHRwOi8vamF2YS5zdW4uY29tL3Byb2R1Y3RzL2phdmEtc2VydmVyL3NlcnZsZXRzL2luZGV4Lmh0bWw8L2E+CisgKgorICogQGF1dGhvciBNYXggU3BpdmFrCisgKi8KK3B1YmxpYyBjbGFzcyBKYXZhTWFpbFNlcnZsZXQgZXh0ZW5kcyBIdHRwU2VydmxldCBpbXBsZW1lbnRzIFNpbmdsZVRocmVhZE1vZGVsIHsKKyAgICBTdHJpbmcgcHJvdG9jb2wgPSAiaW1hcCI7CisgICAgU3RyaW5nIG1ib3ggPSAiSU5CT1giOworCisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBoYW5kbGVzIHRoZSAiUE9TVCIgc3VibWlzc2lvbiBmcm9tIHR3byBmb3JtczogdGhlCisgICAgICogbG9naW4gZm9ybSBhbmQgdGhlIG1lc3NhZ2UgY29tcG9zZSBmb3JtLiBUaGUgbG9naW4gZm9ybSBoYXMgdGhlCisgICAgICogZm9sbG93aW5nIHBhcmFtZXRlcnM6IDxjb2RlPmhvc3RuYW1lPC9jb2RlPiwgPGNvZGU+dXNlcm5hbWU8L2NvZGU+LAorICAgICAqIGFuZCA8Y29kZT5wYXNzd29yZDwvY29kZT4uIFRoZSA8Y29kZT5zZW5kPC9jb2RlPiBwYXJhbWV0ZXIgZGVub3RlcworICAgICAqIHRoYXQgdGhlIG1ldGhvZCBpcyBwcm9jZXNzaW5nIHRoZSBjb21wb3NlIGZvcm0gc3VibWlzc2lvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgIHZvaWQgZG9Qb3N0KEh0dHBTZXJ2bGV0UmVxdWVzdCByZXEsIEh0dHBTZXJ2bGV0UmVzcG9uc2UgcmVzKQorCXRocm93cyBTZXJ2bGV0RXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisKKwkvLyBnZXQgdGhlIHNlc3Npb24KKwlIdHRwU2Vzc2lvbiBzc24gPSByZXEuZ2V0U2Vzc2lvbih0cnVlKTsKKworCVN0cmluZyBzZW5kID0gcmVxLmdldFBhcmFtZXRlcigic2VuZCIpOworCVN0cmluZyBob3N0ID0gcmVxLmdldFBhcmFtZXRlcigiaG9zdG5hbWUiKTsKKwlTdHJpbmcgdXNlciA9IHJlcS5nZXRQYXJhbWV0ZXIoInVzZXJuYW1lIik7CisJU3RyaW5nIHBhc3N3ZCA9IHJlcS5nZXRQYXJhbWV0ZXIoInBhc3N3b3JkIik7CisJVVJMTmFtZSB1cmwgPSBuZXcgVVJMTmFtZShwcm90b2NvbCwgaG9zdCwgLTEsIG1ib3gsIHVzZXIsIHBhc3N3ZCk7CisKKwlTZXJ2bGV0T3V0cHV0U3RyZWFtIG91dCA9IHJlcy5nZXRPdXRwdXRTdHJlYW0oKTsKKwlyZXMuc2V0Q29udGVudFR5cGUoInRleHQvaHRtbCIpOworCW91dC5wcmludGxuKCI8aHRtbD48Ym9keSBiZ2NvbG9yPVwiI0NDQ0NGRlwiPiIpOworCisJaWYgKHNlbmQgIT0gbnVsbCkgeworCSAgICAvLyBwcm9jZXNzIG1lc3NhZ2Ugc2VuZGluZworCSAgICBzZW5kKHJlcSwgcmVzLCBvdXQsIHNzbik7CisKKwl9IGVsc2UgeworCSAgICAvLyBpbml0aWFsIGxvZ2luCisKKwkgICAgLy8gY3JlYXRlIAorCSAgICBNYWlsVXNlckRhdGEgbXVkID0gbmV3IE1haWxVc2VyRGF0YSh1cmwpOworCSAgICBzc24ucHV0VmFsdWUoImphdmFtYWlsc2VydmxldCIsIG11ZCk7CisJICAgIAorCSAgICB0cnkgeworCQlQcm9wZXJ0aWVzIHByb3BzID0gU3lzdGVtLmdldFByb3BlcnRpZXMoKTsKKwkJcHJvcHMucHV0KCJtYWlsLnNtdHAuaG9zdCIsIGhvc3QpOworCQlTZXNzaW9uIHNlc3Npb24gPSBTZXNzaW9uLmdldERlZmF1bHRJbnN0YW5jZShwcm9wcywgbnVsbCk7CisJCXNlc3Npb24uc2V0RGVidWcoZmFsc2UpOworCQlTdG9yZSBzdG9yZSA9IHNlc3Npb24uZ2V0U3RvcmUodXJsKTsKKwkJc3RvcmUuY29ubmVjdCgpOworCQlGb2xkZXIgZm9sZGVyID0gc3RvcmUuZ2V0RGVmYXVsdEZvbGRlcigpOworCQlpZiAoZm9sZGVyID09IG51bGwpIAorCQkgICAgdGhyb3cgbmV3IE1lc3NhZ2luZ0V4Y2VwdGlvbigiTm8gZGVmYXVsdCBmb2xkZXIiKTsKKwkJCisJCWZvbGRlciA9IGZvbGRlci5nZXRGb2xkZXIobWJveCk7CisJCWlmIChmb2xkZXIgPT0gbnVsbCkKKwkJICAgIHRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oIkludmFsaWQgZm9sZGVyIik7CisJCQorCQlmb2xkZXIub3BlbihGb2xkZXIuUkVBRF9XUklURSk7CisJCWludCB0b3RhbE1lc3NhZ2VzID0gZm9sZGVyLmdldE1lc3NhZ2VDb3VudCgpOworCQlNZXNzYWdlW10gbXNncyA9IGZvbGRlci5nZXRNZXNzYWdlcygpOworCQlGZXRjaFByb2ZpbGUgZnAgPSBuZXcgRmV0Y2hQcm9maWxlKCk7CisJCWZwLmFkZChGZXRjaFByb2ZpbGUuSXRlbS5FTlZFTE9QRSk7CisJCWZvbGRlci5mZXRjaChtc2dzLCBmcCk7CisJCQorCQkvLyB0cmFjayB3aG8gbG9nZ2VkIGluCisJCVN5c3RlbS5vdXQucHJpbnRsbigiTG9naW4gZnJvbTogIiArIHN0b3JlLmdldFVSTE5hbWUoKSk7CisJCQorCQkvLyBzYXZlIHN0dWZmIGludG8gTVVECisJCW11ZC5zZXRTZXNzaW9uKHNlc3Npb24pOworCQltdWQuc2V0U3RvcmUoc3RvcmUpOworCQltdWQuc2V0Rm9sZGVyKGZvbGRlcik7CisJCQorCQkvLyBzcGxhc2gKKwkJb3V0LnByaW50KCI8Y2VudGVyPiIpOworCQlvdXQucHJpbnQoIjxmb250IGZhY2U9XCJBcmlhbCxIZWx2ZXRpY2FcIiBmb250IHNpemU9KzM+Iik7CisJCW91dC5wcmludGxuKCI8Yj5XZWxjb21lIHRvIEphdmFNYWlsITwvYj48L2ZvbnQ+PC9jZW50ZXI+PHA+Iik7CisKKwkJLy8gZm9sZGVyIHRhYmxlCisJCW91dC5wcmludGxuKCI8dGFibGUgd2lkdGg9XCI1MCVcIiBib3JkZXI9MCBhbGlnbj1jZW50ZXI+Iik7CisJCS8vIGZvbGRlciBuYW1lIGNvbHVtbiBoZWFkZXIKKwkJb3V0LnByaW50KCI8dHI+PHRkIHdpZHRoPVwiNzUlXCIgYmdjb2xvcj1cIiNmZmZmY2NcIj4iKTsKKwkJb3V0LnByaW50KCI8Zm9udCBmYWNlPVwiQXJpYWwsSGVsdmV0aWNhXCIgZm9udCBzaXplPS0xPiIpOworCQlvdXQucHJpbnRsbigiPGI+Rm9sZGVyTmFtZTwvYj48L2ZvbnQ+PC90ZD48YnI+Iik7CisJCS8vIG1zZyBjb3VudCBjb2x1bW4gaGVhZGVyCisJCW91dC5wcmludCgiPHRkIHdpZHRoPVwiMjUlXCIgYmdjb2xvcj1cIiNmZmZmY2NcIj4iKTsKKwkJb3V0LnByaW50KCI8Zm9udCBmYWNlPVwiQXJpYWwsSGVsdmV0aWNhXCIgZm9udCBzaXplPS0xPiIpOworCQlvdXQucHJpbnRsbigiPGI+TWVzc2FnZXM8L2I+PC9mb250PjwvdGQ+PGJyPiIpOworCQlvdXQucHJpbnRsbigiPC90cj4iKTsKKwkJLy8gZm9sZGVyIG5hbWUKKwkJb3V0LnByaW50KCI8dHI+PHRkIHdpZHRoPVwiNzUlXCIgYmdjb2xvcj1cIiNmZmZmZmZcIj4iKTsKKwkJb3V0LnByaW50KCI8YSBocmVmPVwiIiArIEh0dHBVdGlscy5nZXRSZXF1ZXN0VVJMKHJlcSkgKyAiXCI+IiArCisJCQkgICJJbmJveCIgKyAiPC9hPjwvdGQ+PGJyPiIpOworCQkvLyBtc2cgY291bnQKKwkJb3V0LnByaW50bG4oIjx0ZCB3aWR0aD1cIjI1JVwiIGJnY29sb3I9XCIjZmZmZmZmXCI+IiArIAorCQkJICAgIHRvdGFsTWVzc2FnZXMgKyAiPC90ZD4iKTsKKwkJb3V0LnByaW50bG4oIjwvdHI+Iik7CisJCW91dC5wcmludGxuKCI8L3RhYmxlIik7CisJICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCQlvdXQucHJpbnRsbihleC50b1N0cmluZygpKTsgICAgICAgICAgICAKKwkgICAgfSBmaW5hbGx5IHsKKwkJb3V0LnByaW50bG4oIjwvYm9keT48L2h0bWw+Iik7CisJCW91dC5jbG9zZSgpOworCSAgICB9CisJfQorICAgIH0KKworCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgaGFuZGxlcyB0aGUgR0VUIHJlcXVlc3RzIGZvciB0aGUgY2xpZW50LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGRvR2V0IChIdHRwU2VydmxldFJlcXVlc3QgcmVxLCBIdHRwU2VydmxldFJlc3BvbnNlIHJlcykKKwl0aHJvd3MgU2VydmxldEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworCisJSHR0cFNlc3Npb24gc2VzID0gcmVxLmdldFNlc3Npb24oZmFsc2UpOyAvLyBiZWZvcmUgd2Ugd3JpdGUgdG8gb3V0CisJU2VydmxldE91dHB1dFN0cmVhbSBvdXQgPSByZXMuZ2V0T3V0cHV0U3RyZWFtKCk7CisJTWFpbFVzZXJEYXRhIG11ZCA9IGdldE1VRChzZXMpOworCisJaWYgKG11ZCA9PSBudWxsKSB7CisJICAgIHJlcy5zZXRDb250ZW50VHlwZSgidGV4dC9odG1sIik7CisJICAgIG91dC5wcmludGxuKCI8aHRtbD48Ym9keT5QbGVhc2UgTG9naW4gKG5vIHNlc3Npb24pPC9ib2R5PjwvaHRtbD4iKTsKKwkgICAgb3V0LmNsb3NlKCk7CisJICAgIHJldHVybjsKKwl9CisKKwlpZiAoIW11ZC5nZXRTdG9yZSgpLmlzQ29ubmVjdGVkKCkpIHsKKwkgICAgcmVzLnNldENvbnRlbnRUeXBlKCJ0ZXh0L2h0bWwiKTsKKwkgICAgb3V0LnByaW50bG4oIjxodG1sPjxib2R5Pk5vdCBDb25uZWN0ZWQgVG8gU3RvcmU8L2JvZHk+PC9odG1sPiIpOworCSAgICBvdXQuY2xvc2UoKTsKKwkgICAgcmV0dXJuOworCX0KKworCisJLy8gbXV4IHRoYXQgdGFrZXMgYSBHRVQgcmVxdWVzdCwgYmFzZWQgb24gcGFyYW1ldGVycyBmaWd1cmVzCisJLy8gb3V0IHdoYXQgaXQgc2hvdWxkIGRvLCBhbmQgcm91dGVzIGl0IHRvIHRoZQorCS8vIGFwcHJvcHJpYXRlIG1ldGhvZAorCisJLy8gZ2V0IHVybCBwYXJhbWV0ZXJzCisJU3RyaW5nIG1zZ1N0ciA9IHJlcS5nZXRQYXJhbWV0ZXIoIm1lc3NhZ2UiKTsKKwlTdHJpbmcgbG9nb3V0ID0gcmVxLmdldFBhcmFtZXRlcigibG9nb3V0Iik7CisJU3RyaW5nIGNvbXBvc2UgPSByZXEuZ2V0UGFyYW1ldGVyKCJjb21wb3NlIik7CisJU3RyaW5nIHBhcnQgPSByZXEuZ2V0UGFyYW1ldGVyKCJwYXJ0Iik7CisJaW50IG1zZ051bSA9IC0xOworCWludCBwYXJ0TnVtID0gLTE7CisKKwkvLyBwcm9jZXNzIHVybCBwYXJhbXMKKwlpZiAobXNnU3RyICE9IG51bGwpIHsKKwkgICAgLy8gb3BlcmF0ZSBvbiBtZXNzYWdlICJtc2dTdHIiCisJICAgIG1zZ051bSA9IEludGVnZXIucGFyc2VJbnQobXNnU3RyKTsKKworCSAgICBpZiAocGFydCA9PSBudWxsKSB7CisJCS8vIGRpc3BsYXkgbWVzc2FnZSAibXNnU3RyIgorCQlyZXMuc2V0Q29udGVudFR5cGUoInRleHQvaHRtbCIpOworCQlkaXNwbGF5TWVzc2FnZShtdWQsIHJlcSwgb3V0LCBtc2dOdW0pOworCisJICAgIH0gZWxzZSB7CisJCS8vIGRpc3BsYXkgcGFydCAicGFydCIgaW4gbWVzc2FnZSAibXNnU3RyIgorCQlwYXJ0TnVtID0gSW50ZWdlci5wYXJzZUludChwYXJ0KTsKKwkJZGlzcGxheVBhcnQobXVkLCBtc2dOdW0sIHBhcnROdW0sIG91dCwgcmVzKTsKKwkgICAgfQorCisJfSBlbHNlIGlmIChjb21wb3NlICE9IG51bGwpIHsKKwkgICAgLy8gZGlzcGxheSBjb21wb3NlIGZvcm0KKwkgICAgY29tcG9zZShtdWQsIHJlcywgb3V0KTsKKworCX0gZWxzZSBpZiAobG9nb3V0ICE9IG51bGwpIHsKKwkgICAgLy8gcHJvY2VzcyBsb2dvdXQKKwkgICAgdHJ5IHsKKwkJbXVkLmdldEZvbGRlcigpLmNsb3NlKGZhbHNlKTsKKwkJbXVkLmdldFN0b3JlKCkuY2xvc2UoKTsKKwkJc2VzLmludmFsaWRhdGUoKTsKKwkJb3V0LnByaW50bG4oIjxodG1sPjxib2R5PkxvZ2dlZCBvdXQgT0s8L2JvZHk+PC9odG1sPiIpOworCSAgICB9IGNhdGNoIChNZXNzYWdpbmdFeGNlcHRpb24gbWV4KSB7CisJCW91dC5wcmludGxuKG1leC50b1N0cmluZygpKTsKKwkgICAgfQorCisJfSBlbHNlIHsKKwkgICAgLy8gZGlzcGxheSBoZWFkZXJzCisJICAgIGRpc3BsYXlIZWFkZXJzKG11ZCwgcmVxLCBvdXQpOworCX0KKyAgICB9CisKKyAgICAvKiBtYWluIG1ldGhvZCB0byBkaXNwbGF5IG1lc3NhZ2VzICovCisgICAgcHJpdmF0ZSB2b2lkIGRpc3BsYXlNZXNzYWdlKE1haWxVc2VyRGF0YSBtdWQsIEh0dHBTZXJ2bGV0UmVxdWVzdCByZXEsIAorCQkJCVNlcnZsZXRPdXRwdXRTdHJlYW0gb3V0LCBpbnQgbXNnTnVtKSAKKwl0aHJvd3MgSU9FeGNlcHRpb24geworCSAgICAKKwlvdXQucHJpbnRsbigiPGh0bWw+Iik7CisJb3V0LnByaW50bG4oIjxIRUFEPjxUSVRMRT5KYXZhTWFpbCBTZXJ2bGV0PC9USVRMRT48L0hFQUQ+Iik7CisJb3V0LnByaW50bG4oIjxCT0RZIGJnY29sb3I9XCIjY2NjY2ZmXCI+Iik7CisJb3V0LnByaW50KCI8Y2VudGVyPjxmb250IGZhY2U9XCJBcmlhbCxIZWx2ZXRpY2FcIiAiKTsKKwlvdXQucHJpbnRsbigiZm9udCBzaXplPVwiKzNcIj48Yj4iKTsKKwlvdXQucHJpbnRsbigiTWVzc2FnZSAiICsgKG1zZ051bSsxKSArICIgaW4gZm9sZGVyICIgKyAKKwkJICAgIG11ZC5nZXRTdG9yZSgpLmdldFVSTE5hbWUoKSArIAorCQkgICAgIi9JTkJPWDwvYj48L2ZvbnQ+PC9jZW50ZXI+PHA+Iik7CisKKwl0cnkgeworCSAgICBNZXNzYWdlIG1zZyA9IG11ZC5nZXRGb2xkZXIoKS5nZXRNZXNzYWdlKG1zZ051bSk7CisKKwkgICAgLy8gZmlyc3QsIGRpc3BsYXkgdGhpcyBtZXNzYWdlJ3MgaGVhZGVycworCSAgICBkaXNwbGF5TWVzc2FnZUhlYWRlcnMobXVkLCBtc2csIG91dCk7CisKKwkgICAgLy8gYW5kIG5vdywgaGFuZGxlIHRoZSBjb250ZW50CisJICAgIE9iamVjdCBvID0gbXNnLmdldENvbnRlbnQoKTsKKwkgICAgCisJICAgIC8vaWYgKG8gaW5zdGFuY2VvZiBTdHJpbmcpIHsKKwkgICAgaWYgKG1zZy5pc01pbWVUeXBlKCJ0ZXh0L3BsYWluIikpIHsKKwkJb3V0LnByaW50bG4oIjxwcmU+Iik7CisJCW91dC5wcmludGxuKChTdHJpbmcpbyk7CisJCW91dC5wcmludGxuKCI8L3ByZT4iKTsKKwkgICAgLy99IGVsc2UgaWYgKG8gaW5zdGFuY2VvZiBNdWx0aXBhcnQpeworCSAgICB9IGVsc2UgaWYgKG1zZy5pc01pbWVUeXBlKCJtdWx0aXBhcnQvKiIpKSB7CisJCU11bHRpcGFydCBtcCA9IChNdWx0aXBhcnQpbzsKKwkJaW50IGNudCA9IG1wLmdldENvdW50KCk7CisJCWZvciAoaW50IGkgPSAwOyBpIDwgY250OyBpKyspIHsKKwkJICAgIGRpc3BsYXlQYXJ0KG11ZCwgbXNnTnVtLCBtcC5nZXRCb2R5UGFydChpKSwgaSwgcmVxLCBvdXQpOworCQl9CisJICAgIH0gZWxzZSB7CisJCW91dC5wcmludGxuKG1zZy5nZXRDb250ZW50VHlwZSgpKTsKKwkgICAgfQorCisJfSBjYXRjaCAoTWVzc2FnaW5nRXhjZXB0aW9uIG1leCkgeworCSAgICBvdXQucHJpbnRsbihtZXgudG9TdHJpbmcoKSk7CisJfQorCisJb3V0LnByaW50bG4oIjwvQk9EWT48L2h0bWw+Iik7CisJb3V0LmNsb3NlKCk7CisgICAgfQorCisgICAgLyoqIAorICAgICAqIFRoaXMgbWV0aG9kIGRpc3BsYXlzIGEgbWVzc2FnZSBwYXJ0LiA8Y29kZT50ZXh0L3BsYWluPC9jb2RlPgorICAgICAqIGNvbnRlbnQgcGFydHMgYXJlIGRpc3BsYXllZCBpbmxpbmUuIEZvciBhbGwgb3RoZXIgcGFydHMsCisgICAgICogYSBVUkwgaXMgZ2VuZXJhdGVkIGFuZCBkaXNwbGF5ZWQ7IGNsaWNraW5nIG9uIHRoZSBVUkwKKyAgICAgKiBicmluZ3MgdXAgdGhlIHBhcnQgaW4gYSBzZXBhcmF0ZSBwYWdlLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBkaXNwbGF5UGFydChNYWlsVXNlckRhdGEgbXVkLCBpbnQgbXNnTnVtLCBQYXJ0IHBhcnQsIAorCQkJICAgICBpbnQgcGFydE51bSwgSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcSwgCisJCQkgICAgIFNlcnZsZXRPdXRwdXRTdHJlYW0gb3V0KSAKKwl0aHJvd3MgSU9FeGNlcHRpb24geworCisJaWYgKHBhcnROdW0gIT0gMCkKKwkgICAgb3V0LnByaW50bG4oIjxwPjxocj4iKTsKKworCXRyeSB7CisKKwkgICAgU3RyaW5nIHNjdCA9IHBhcnQuZ2V0Q29udGVudFR5cGUoKTsKKwkgICAgaWYgKHNjdCA9PSBudWxsKSB7CisJCW91dC5wcmludGxuKCJpbnZhbGlkIHBhcnQiKTsKKwkJcmV0dXJuOworCSAgICB9CisJICAgIENvbnRlbnRUeXBlIGN0ID0gbmV3IENvbnRlbnRUeXBlKHNjdCk7CisJICAgIAorCSAgICBpZiAocGFydE51bSAhPSAwKQorCQlvdXQucHJpbnRsbigiPGI+QXR0YWNobWVudCBUeXBlOjwvYj4gIiArICAgCisJCQkgICAgY3QuZ2V0QmFzZVR5cGUoKSArICI8YnI+Iik7CisKKwkgICAgaWYgKGN0Lm1hdGNoKCJ0ZXh0L3BsYWluIikpIHsgIAorCQkvLyBkaXNwbGF5IHRleHQvcGxhaW4gaW5saW5lCisJCW91dC5wcmludGxuKCI8cHJlPiIpOworCQlvdXQucHJpbnRsbigoU3RyaW5nKXBhcnQuZ2V0Q29udGVudCgpKTsKKwkJb3V0LnByaW50bG4oIjwvcHJlPiIpOworCisJICAgIH0gZWxzZSB7CisJCS8vIGdlbmVyYXRlIGEgdXJsIGZvciB0aGlzIHBhcnQKKwkJU3RyaW5nIHM7CisJCWlmICgocyA9IHBhcnQuZ2V0RmlsZU5hbWUoKSkgIT0gbnVsbCkKKwkJICAgIG91dC5wcmludGxuKCI8Yj5GaWxlbmFtZTo8L2I+ICIgKyBzICsgIjxicj4iKTsKKwkJcyA9IG51bGw7CisJCWlmICgocyA9IHBhcnQuZ2V0RGVzY3JpcHRpb24oKSkgIT0gbnVsbCkKKwkJICAgIG91dC5wcmludGxuKCI8Yj5EZXNjcmlwdGlvbjo8L2I+ICIgKyBzICsgIjxicj4iKTsKKwkJCisJCW91dC5wcmludGxuKCI8YSBocmVmPVwiIiArCisJCQkgICAgSHR0cFV0aWxzLmdldFJlcXVlc3RVUkwocmVxKSArIAorCQkJICAgICI/bWVzc2FnZT0iICsKKwkJCSAgICBtc2dOdW0gKyAiJnBhcnQ9IiArCisJCQkgICAgcGFydE51bSArICJcIj5EaXNwbGF5IEF0dGFjaG1lbnQ8L2E+Iik7CisJICAgIH0KKwl9IGNhdGNoIChNZXNzYWdpbmdFeGNlcHRpb24gbWV4KSB7CisJICAgIG91dC5wcmludGxuKG1leC50b1N0cmluZygpKTsKKwl9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgZ2V0cyB0aGUgc3RyZWFtIGZyb20gZm9yIGEgZ2l2ZW4gbXNnIHBhcnQgYW5kIAorICAgICAqIHB1c2hlcyBpdCBvdXQgdG8gdGhlIGJyb3dzZXIgd2l0aCB0aGUgY29ycmVjdCBjb250ZW50IHR5cGUuCisgICAgICogVXNlZCB0byBkaXNwbGF5IGF0dGFjaG1lbnRzIGFuZCByZWxpZXMgb24gdGhlIGJyb3dzZXIncworICAgICAqIGNvbnRlbnQgaGFuZGxpbmcgY2FwYWJpbGl0aWVzLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBkaXNwbGF5UGFydChNYWlsVXNlckRhdGEgbXVkLCBpbnQgbXNnTnVtLAorCQkJICAgICBpbnQgcGFydE51bSwgU2VydmxldE91dHB1dFN0cmVhbSBvdXQsIAorCQkJICAgICBIdHRwU2VydmxldFJlc3BvbnNlIHJlcykgCisJdGhyb3dzIElPRXhjZXB0aW9uIHsKKworCVBhcnQgcGFydCA9IG51bGw7CisJCisJdHJ5IHsKKwkgICAgTWVzc2FnZSBtc2cgPSBtdWQuZ2V0Rm9sZGVyKCkuZ2V0TWVzc2FnZShtc2dOdW0pOworCisJICAgIE11bHRpcGFydCBtcCA9IChNdWx0aXBhcnQpbXNnLmdldENvbnRlbnQoKTsKKwkgICAgcGFydCA9IG1wLmdldEJvZHlQYXJ0KHBhcnROdW0pOworCSAgICAKKwkgICAgU3RyaW5nIHNjdCA9IHBhcnQuZ2V0Q29udGVudFR5cGUoKTsKKwkgICAgaWYgKHNjdCA9PSBudWxsKSB7CisJCW91dC5wcmludGxuKCJpbnZhbGlkIHBhcnQiKTsKKwkJcmV0dXJuOworCSAgICB9CisJICAgIENvbnRlbnRUeXBlIGN0ID0gbmV3IENvbnRlbnRUeXBlKHNjdCk7CisKKwkgICAgcmVzLnNldENvbnRlbnRUeXBlKGN0LmdldEJhc2VUeXBlKCkpOworCSAgICBJbnB1dFN0cmVhbSBpcyA9IHBhcnQuZ2V0SW5wdXRTdHJlYW0oKTsKKwkgICAgaW50IGk7CisJICAgIHdoaWxlICgoaSA9IGlzLnJlYWQoKSkgIT0gLTEpCisJCW91dC53cml0ZShpKTsKKwkgICAgb3V0LmZsdXNoKCk7CisJICAgIG91dC5jbG9zZSgpOworCX0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBtZXgpIHsKKwkgICAgb3V0LnByaW50bG4obWV4LnRvU3RyaW5nKCkpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIGlzIGEgdXRpbGl0eSBtZXNzYWdlIHRoYXQgcHJldHR5LXByaW50cyB0aGUgbWVzc2FnZSAKKyAgICAgKiBoZWFkZXJzIGZvciBtZXNzYWdlIHRoYXQgaXMgYmVpbmcgZGlzcGxheWVkLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBkaXNwbGF5TWVzc2FnZUhlYWRlcnMoTWFpbFVzZXJEYXRhIG11ZCwgTWVzc2FnZSBtc2csIAorCQkJCSAgICAgICBTZXJ2bGV0T3V0cHV0U3RyZWFtIG91dCkgCisJdGhyb3dzIElPRXhjZXB0aW9uIHsKKworCXRyeSB7CisJICAgIG91dC5wcmludGxuKCI8Yj5EYXRlOjwvYj4gIiArIG1zZy5nZXRTZW50RGF0ZSgpICsgIjxicj4iKTsKKworCSAgICBBZGRyZXNzW10gZnIgPSBtc2cuZ2V0RnJvbSgpOworCSAgICBpZiAoZnIgIT0gbnVsbCkgeworCQlib29sZWFuIHRmID0gdHJ1ZTsKKwkJb3V0LnByaW50KCI8Yj5Gcm9tOjwvYj4gIik7CisJCWZvciAoaW50IGkgPSAwOyBpIDwgZnIubGVuZ3RoOyBpKyspIHsKKwkJICAgIG91dC5wcmludCgoKHRmKSA/ICIgIiA6ICIsICIpICsgZ2V0RGlzcGxheUFkZHJlc3MoZnJbaV0pKTsKKwkJICAgIHRmID0gZmFsc2U7CisJCX0KKwkJb3V0LnByaW50bG4oIjxicj4iKTsKKwkgICAgfQorCisJICAgIEFkZHJlc3NbXSB0byA9IG1zZy5nZXRSZWNpcGllbnRzKE1lc3NhZ2UuUmVjaXBpZW50VHlwZS5UTyk7CisJICAgIGlmICh0byAhPSBudWxsKSB7CisJCWJvb2xlYW4gdGYgPSB0cnVlOworCQlvdXQucHJpbnQoIjxiPlRvOjwvYj4gIik7CisJCWZvciAoaW50IGkgPSAwOyBpIDwgdG8ubGVuZ3RoOyBpKyspIHsKKwkJICAgIG91dC5wcmludCgoKHRmKSA/ICIgIiA6ICIsICIpICsgZ2V0RGlzcGxheUFkZHJlc3ModG9baV0pKTsKKwkJICAgIHRmID0gZmFsc2U7CisJCX0KKwkJb3V0LnByaW50bG4oIjxicj4iKTsKKwkgICAgfQorCisJICAgIEFkZHJlc3NbXSBjYyA9IG1zZy5nZXRSZWNpcGllbnRzKE1lc3NhZ2UuUmVjaXBpZW50VHlwZS5DQyk7CisJICAgIGlmIChjYyAhPSBudWxsKSB7CisJCWJvb2xlYW4gY2YgPSB0cnVlOworCQlvdXQucHJpbnQoIjxiPkNDOjwvYj4gIik7CisJCWZvciAoaW50IGkgPSAwOyBpIDwgY2MubGVuZ3RoOyBpKyspIHsKKwkJICAgIG91dC5wcmludCgoKGNmKSA/ICIgIiA6ICIsICIpICsgZ2V0RGlzcGxheUFkZHJlc3MoY2NbaV0pKTsKKwkJICAgIGNmID0gZmFsc2U7CisJCX0KKwkJb3V0LnByaW50bG4oIjxicj4iKTsKKwkgICAgfQorCSAgICAKKwkgICAgb3V0LnByaW50KCI8Yj5TdWJqZWN0OjwvYj4gIiArIAorCQkgICAgICAoKG1zZy5nZXRTdWJqZWN0KCkgIT1udWxsKSA/IG1zZy5nZXRTdWJqZWN0KCkgOiAiIikgKyAKKwkJICAgICAgIjxicj4iKTsKKworCX0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBtZXgpIHsKKwkgICAgb3V0LnByaW50bG4obXNnLnRvU3RyaW5nKCkpOworCX0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBkaXNwbGF5cyB0aGUgVVJMJ3MgZm9yIHRoZSBhdmFpbGFibGUgY29tbWFuZHMgYW5kIHRoZQorICAgICAqIElOQk9YIGhlYWRlcmxpc3QgCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGRpc3BsYXlIZWFkZXJzKE1haWxVc2VyRGF0YSBtdWQsCisJCQkJSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcSwgCisJCQkJU2VydmxldE91dHB1dFN0cmVhbSBvdXQpCisJdGhyb3dzIElPRXhjZXB0aW9uIHsKKworCVNpbXBsZURhdGVGb3JtYXQgZGYgPSBuZXcgU2ltcGxlRGF0ZUZvcm1hdCgiRUUgTS9kL3l5Iik7CisKKwlvdXQucHJpbnRsbigiPGh0bWw+Iik7CisJb3V0LnByaW50bG4oIjxIRUFEPjxUSVRMRT5KYXZhTWFpbCBTZXJ2bGV0PC9USVRMRT48L0hFQUQ+Iik7CisJb3V0LnByaW50bG4oIjxCT0RZIGJnY29sb3I9XCIjY2NjY2ZmXCI+PGhyPiIpOworCW91dC5wcmludCgiPGNlbnRlcj48Zm9udCBmYWNlPVwiQXJpYWwsSGVsdmV0aWNhXCIgZm9udCBzaXplPVwiKzNcIj4iKTsKKwlvdXQucHJpbnRsbigiPGI+Rm9sZGVyICIgKyBtdWQuZ2V0U3RvcmUoKS5nZXRVUkxOYW1lKCkgKyAKKwkJICAgICIvSU5CT1g8L2I+PC9mb250PjwvY2VudGVyPjxwPiIpOworCisJLy8gVVJMJ3MgZm9yIHRoZSBjb21tYW5kcyB0aGF0IGFyZSBhdmFpbGFibGUKKwlvdXQucHJpbnRsbigiPGZvbnQgZmFjZT1cIkFyaWFsLEhlbHZldGljYVwiIGZvbnQgc2l6ZT1cIiszXCI+PGI+Iik7CisJb3V0LnByaW50bG4oIjxhIGhyZWY9XCIiICsKKwkJICAgIEh0dHBVdGlscy5nZXRSZXF1ZXN0VVJMKHJlcSkgKworCQkgICAgIj9sb2dvdXQ9dHJ1ZVwiPkxvZ291dDwvYT4iKTsKKwlvdXQucHJpbnRsbigiPGEgaHJlZj1cIiIgKworCQkgICAgSHR0cFV0aWxzLmdldFJlcXVlc3RVUkwocmVxKSArCisJCSAgICAiP2NvbXBvc2U9dHJ1ZVwiIHRhcmdldD1cImNvbXBvc2VcIj5Db21wb3NlPC9hPiIpOworCW91dC5wcmludGxuKCI8L2I+PC9mb250PiIpOworCW91dC5wcmludGxuKCI8aHI+Iik7CisKKwkvLyBMaXN0IGhlYWRlcnMgaW4gYSB0YWJsZQorCW91dC5wcmludCgiPHRhYmxlIGNlbGxwYWRkaW5nPTEgY2VsbHNwYWNpbmc9MSAiKTsgLy8gdGFibGUKKwlvdXQucHJpbnRsbigid2lkdGg9XCIxMDAlXCIgYm9yZGVyPTE+Iik7ICAgICAgICAgIC8vIHNldHRpbmdzCisKKwkvLyBzZW5kZXIgY29sdW1uIGhlYWRlcgorCW91dC5wcmludGxuKCI8dHI+PHRkIHdpZHRoPVwiMjUlXCIgYmdjb2xvcj1cImZmZmZjY1wiPiIpOworCW91dC5wcmludGxuKCI8Zm9udCBmYWNlPVwiQXJpYWwsSGVsdmV0aWNhXCIgZm9udCBzaXplPVwiKzFcIj4iKTsKKwlvdXQucHJpbnRsbigiPGI+U2VuZGVyPC9iPjwvZm9udD48L3RkPiIpOworCS8vIGRhdGUgY29sdW1uIGhlYWRlcgorCW91dC5wcmludGxuKCI8dGQgd2lkdGg9XCIxNSVcIiBiZ2NvbG9yPVwiZmZmZmNjXCI+Iik7CisJb3V0LnByaW50bG4oIjxmb250IGZhY2U9XCJBcmlhbCxIZWx2ZXRpY2FcIiBmb250IHNpemU9XCIrMVwiPiIpOworCW91dC5wcmludGxuKCI8Yj5EYXRlPC9iPjwvZm9udD48L3RkPiIpOworCS8vIHN1YmplY3QgY29sdW1uIGhlYWRlcgorCW91dC5wcmludGxuKCI8dGQgYmdjb2xvcj1cImZmZmZjY1wiPiIpOworCW91dC5wcmludGxuKCI8Zm9udCBmYWNlPVwiQXJpYWwsSGVsdmV0aWNhXCIgZm9udCBzaXplPVwiKzFcIj4iKTsKKwlvdXQucHJpbnRsbigiPGI+U3ViamVjdDwvYj48L2ZvbnQ+PC90ZD48L3RyPiIpOworCisJdHJ5IHsKKwkgICAgRm9sZGVyIGYgPSBtdWQuZ2V0Rm9sZGVyKCk7CisJICAgIGludCBtc2dDb3VudCA9IGYuZ2V0TWVzc2FnZUNvdW50KCk7CisJICAgIE1lc3NhZ2UgbSA9IG51bGw7CisJICAgIC8vIGZvciBlYWNoIG1lc3NhZ2UsIHNob3cgaXRzIGhlYWRlcnMKKwkgICAgZm9yIChpbnQgaSA9IDE7IGkgPD0gbXNnQ291bnQ7IGkrKykgeworCQltID0gZi5nZXRNZXNzYWdlKGkpOworCQkKKwkJLy8gaWYgbWVzc2FnZSBoYXMgdGhlIERFTEVURUQgZmxhZyBzZXQsIGRvbid0IGRpc3BsYXkgaXQKKwkJaWYgKG0uaXNTZXQoRmxhZ3MuRmxhZy5ERUxFVEVEKSkKKwkJICAgIGNvbnRpbnVlOworCisJCS8vIGZyb20gCisJCW91dC5wcmludGxuKCI8dHIgdmFsaWdoPW1pZGRsZT4iKTsKKwkJb3V0LnByaW50KCI8dGQgd2lkdGg9XCIyNSVcIiBiZ2NvbG9yPVwiZmZmZmZmXCI+Iik7CisJCW91dC5wcmludGxuKCI8Zm9udCBmYWNlPVwiQXJpYWwsSGVsdmV0aWNhXCI+IiArIAorCQkJICAgICgobS5nZXRGcm9tKCkgIT0gbnVsbCkgPyAKKwkJCQkgICAgICAgbS5nZXRGcm9tKClbMF0udG9TdHJpbmcoKSA6IAorCQkJCSAgICAgICAiIiApICsKKwkJCSAgICAiPC9mb250PjwvdGQ+Iik7CisKKwkJLy8gZGF0ZQorCQlvdXQucHJpbnQoIjx0ZCBub3dyYXAgd2lkdGg9XCIxNSVcIiBiZ2NvbG9yPVwiZmZmZmZmXCI+Iik7CisJCW91dC5wcmludGxuKCI8Zm9udCBmYWNlPVwiQXJpYWwsSGVsdmV0aWNhXCI+IiArIAorCQkJICAgIGRmLmZvcm1hdCgobS5nZXRTZW50RGF0ZSgpIT1udWxsKSA/IAorCQkJCSAgICAgIG0uZ2V0U2VudERhdGUoKSA6IG0uZ2V0UmVjZWl2ZWREYXRlKCkpICsKKwkJCSAgICAiPC9mb250PjwvdGQ+Iik7CisKKwkJLy8gc3ViamVjdCAmIGxpbmsKKwkJb3V0LnByaW50KCI8dGQgYmdjb2xvcj1cImZmZmZmZlwiPiIpOworCQlvdXQucHJpbnRsbigiPGZvbnQgZmFjZT1cIkFyaWFsLEhlbHZldGljYVwiPiIgKyAKKwkJCSAgICAiPGEgaHJlZj1cIiIgKworCQkJICAgIEh0dHBVdGlscy5nZXRSZXF1ZXN0VVJMKHJlcSkgKyAKKwkJCSAgICAiP21lc3NhZ2U9IiArCisJCQkgICAgaSArICJcIj4iICsKKwkJCSAgICAoKG0uZ2V0U3ViamVjdCgpICE9IG51bGwpID8gCisJCQkJICAgbS5nZXRTdWJqZWN0KCkgOgorCQkJCSAgICI8aT5ObyBTdWJqZWN0PC9pPiIpICsKKwkJCSAgICAiPC9hPiIgKworCQkJICAgICI8L2ZvbnQ+PC90ZD4iKTsKKwkJb3V0LnByaW50bG4oIjwvdHI+Iik7CisJICAgIH0KKwl9IGNhdGNoIChNZXNzYWdpbmdFeGNlcHRpb24gbWV4KSB7CisJICAgIG91dC5wcmludGxuKCI8dHI+PHRkPiIgKyBtZXgudG9TdHJpbmcoKSArICI8L3RkPjwvdHI+Iik7CisJICAgIG1leC5wcmludFN0YWNrVHJhY2UoKTsKKwl9CisKKwlvdXQucHJpbnRsbigiPC90YWJsZT4iKTsKKwlvdXQucHJpbnRsbigiPC9CT0RZPjwvaHRtbD4iKTsKKwlvdXQuZmx1c2goKTsKKwlvdXQuY2xvc2UoKTsKKyAgICB9CisKKyAgICAvKiogCisgICAgICogVGhpcyBtZXRob2QgaGFuZGxlcyB0aGUgcmVxdWVzdCB3aGVuIHRoZSB1c2VyIGhpdHMgdGhlCisgICAgICogPGk+Q29tcG9zZTwvaT4gbGluay4gSXQgc2VuZCB0aGUgY29tcG9zZSBmb3JtIHRvIHRoZSBicm93c2VyLgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBjb21wb3NlKE1haWxVc2VyRGF0YSBtdWQsIEh0dHBTZXJ2bGV0UmVzcG9uc2UgcmVzLAorCQkJIFNlcnZsZXRPdXRwdXRTdHJlYW0gb3V0KSAKKwl0aHJvd3MgSU9FeGNlcHRpb24geworCQorCXJlcy5zZXRDb250ZW50VHlwZSgidGV4dC9odG1sIik7CisJb3V0LnByaW50bG4oY29tcG9zZUZvcm0pOworCW91dC5jbG9zZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgbWV0aG9kIHByb2Nlc3NlcyB0aGUgc2VuZCByZXF1ZXN0IGZyb20gdGhlIGNvbXBvc2UgZm9ybQorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBzZW5kKEh0dHBTZXJ2bGV0UmVxdWVzdCByZXEsIEh0dHBTZXJ2bGV0UmVzcG9uc2UgcmVzLAorCQkgICAgICBTZXJ2bGV0T3V0cHV0U3RyZWFtIG91dCwgSHR0cFNlc3Npb24gc3NuKQorCXRocm93cyBJT0V4Y2VwdGlvbiB7CisJICAgIAorCVN0cmluZyB0byA9IHJlcS5nZXRQYXJhbWV0ZXIoInRvIik7CisJU3RyaW5nIGNjID0gcmVxLmdldFBhcmFtZXRlcigiY2MiKTsKKwlTdHJpbmcgc3ViaiA9IHJlcS5nZXRQYXJhbWV0ZXIoInN1YmplY3QiKTsKKwlTdHJpbmcgdGV4dCA9IHJlcS5nZXRQYXJhbWV0ZXIoInRleHQiKTsKKworCXRyeSB7CisJICAgIE1haWxVc2VyRGF0YSBtdWQgPSBnZXRNVUQoc3NuKTsKKwkgICAgaWYgKG11ZCA9PSBudWxsKQorCQl0aHJvdyBuZXcgRXhjZXB0aW9uKCJ0cnlpbmcgdG8gc2VuZCwgYnV0IG5vdCBsb2dnZWQgaW4iKTsKKworCSAgICBNZXNzYWdlIG1zZyA9IG5ldyBNaW1lTWVzc2FnZShtdWQuZ2V0U2Vzc2lvbigpKTsKKwkgICAgSW50ZXJuZXRBZGRyZXNzW10gdG9BZGRycyA9IG51bGwsIGNjQWRkcnMgPSBudWxsOworCisJICAgIGlmICh0byAhPSBudWxsKSB7CisJCXRvQWRkcnMgPSBJbnRlcm5ldEFkZHJlc3MucGFyc2UodG8sIGZhbHNlKTsKKwkJbXNnLnNldFJlY2lwaWVudHMoTWVzc2FnZS5SZWNpcGllbnRUeXBlLlRPLCB0b0FkZHJzKTsKKwkgICAgfSBlbHNlCisJCXRocm93IG5ldyBNZXNzYWdpbmdFeGNlcHRpb24oIk5vIFwiVG9cIiBhZGRyZXNzIHNwZWNpZmllZCIpOworCisJICAgIGlmIChjYyAhPSBudWxsKSB7CisJCWNjQWRkcnMgPSBJbnRlcm5ldEFkZHJlc3MucGFyc2UoY2MsIGZhbHNlKTsKKwkJbXNnLnNldFJlY2lwaWVudHMoTWVzc2FnZS5SZWNpcGllbnRUeXBlLkNDLCBjY0FkZHJzKTsKKwkgICAgfQorCisJICAgIGlmIChzdWJqICE9IG51bGwpCisJCW1zZy5zZXRTdWJqZWN0KHN1YmopOworCisJICAgIFVSTE5hbWUgdSA9IG11ZC5nZXRVUkxOYW1lKCk7CisJICAgIG1zZy5zZXRGcm9tKG5ldyBJbnRlcm5ldEFkZHJlc3ModS5nZXRVc2VybmFtZSgpICsgIkAiICsKKwkJCQkJICAgIHUuZ2V0SG9zdCgpKSk7CisKKwkgICAgaWYgKHRleHQgIT0gbnVsbCkKKwkJbXNnLnNldFRleHQodGV4dCk7CisKKwkgICAgVHJhbnNwb3J0LnNlbmQobXNnKTsKKwkgICAgCisJICAgIG91dC5wcmludGxuKCI8aDE+TWVzc2FnZSBzZW50IHN1Y2Nlc3NmdWxseTwvaDE+PC9ib2R5PjwvaHRtbD4iKTsKKwkgICAgb3V0LmNsb3NlKCk7CisJICAgIAorCX0gY2F0Y2ggKEV4Y2VwdGlvbiBtZXgpIHsKKwkgICAgb3V0LnByaW50bG4oIjxoMT5FcnJvciBzZW5kaW5nIG1lc3NhZ2UuPC9oMT4iKTsKKwkgICAgb3V0LnByaW50bG4obWV4LnRvU3RyaW5nKCkpOworCSAgICBvdXQucHJpbnRsbigiPGJyPjwvYm9keT48L2h0bWw+Iik7CisJfQorICAgIH0KKworCisgICAgLy8gdXRpbGl0eSBtZXRob2Q7IHJldHVybnMgYSBzdHJpbmcgc3VpdGFibGUgZm9yIG1zZyBoZWFkZXIgZGlzcGxheQorICAgIHByaXZhdGUgU3RyaW5nIGdldERpc3BsYXlBZGRyZXNzKEFkZHJlc3MgYSkgeworCVN0cmluZyBwZXJzID0gbnVsbDsKKwlTdHJpbmcgYWRkciA9IG51bGw7CisJaWYgKGEgaW5zdGFuY2VvZiBJbnRlcm5ldEFkZHJlc3MgJiYKKwkgICAgKChwZXJzID0gKChJbnRlcm5ldEFkZHJlc3MpYSkuZ2V0UGVyc29uYWwoKSkgIT0gbnVsbCkpIHsKKwkgICAgCisJICAgIGFkZHIgPSBwZXJzICsgIiAgIisiJmx0OyIrKChJbnRlcm5ldEFkZHJlc3MpYSkuZ2V0QWRkcmVzcygpKyImZ3Q7IjsKKwl9IGVsc2UgCisJICAgIGFkZHIgPSBhLnRvU3RyaW5nKCk7CisJCisJcmV0dXJuIGFkZHI7CisgICAgfQorCisgICAgLy8gdXRpbGl0eSBtZXRob2Q7IHJldHJpZXZlIHRoZSBNYWlsVXNlckRhdGEgCisgICAgLy8gZnJvbSB0aGUgSHR0cFNlc3Npb24gYW5kIHJldHVybiBpdAorICAgIHByaXZhdGUgTWFpbFVzZXJEYXRhIGdldE1VRChIdHRwU2Vzc2lvbiBzZXMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJTWFpbFVzZXJEYXRhIG11ZCA9IG51bGw7CisKKwlpZiAoc2VzID09IG51bGwpIHsKKwkgICAgcmV0dXJuIG51bGw7CisJfSBlbHNlIHsKKwkgICAgaWYgKChtdWQgPSAoTWFpbFVzZXJEYXRhKXNlcy5nZXRWYWx1ZSgiamF2YW1haWxzZXJ2bGV0IikpID09IG51bGwpeworCQlyZXR1cm4gbnVsbDsKKwkgICAgfQorCX0KKwlyZXR1cm4gbXVkOworICAgIH0KKworCisgICAgcHVibGljIFN0cmluZyBnZXRTZXJ2bGV0SW5mbygpIHsKKwlyZXR1cm4gIkEgbWFpbCByZWFkZXIgc2VydmxldCI7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBpcyB0aGUgSFRNTCBjb2RlIGZvciB0aGUgY29tcG9zZSBmb3JtLiBBbm90aGVyIG9wdGlvbiB3b3VsZAorICAgICAqIGhhdmUgYmVlbiB0byB1c2UgYSBzZXBhcmF0ZSBodG1sIHBhZ2UuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGNvbXBvc2VGb3JtID0gIjxIVE1MPjxIRUFEPjxUSVRMRT5KYXZhTWFpbCBDb21wb3NlPC9USVRMRT48L0hFQUQ+PEJPRFkgQkdDT0xPUj1cIiNDQ0NDRkZcIj48Rk9STSBBQ1RJT049XCIvc2VydmxldC9KYXZhTWFpbFNlcnZsZXRcIiBNRVRIT0Q9XCJQT1NUXCI+PGlucHV0IHR5cGU9XCJoaWRkZW5cIiBuYW1lPVwic2VuZFwiIHZhbHVlPVwic2VuZFwiPjxQIEFMSUdOPVwiQ0VOVEVSXCI+PEI+PEZPTlQgU0laRT1cIjRcIiBGQUNFPVwiVmVyZGFuYSwgQXJpYWwsIEhlbHZldGljYVwiPkphdmFNYWlsIENvbXBvc2UgTWVzc2FnZTwvRk9OVD48L0I+PFA+PFRBQkxFIEJPUkRFUj1cIjBcIiBXSURUSD1cIjEwMCVcIj48VFI+PFREIFdJRFRIPVwiMTYlXCIgSEVJR0hUPVwiMjJcIj4JPFAgQUxJR049XCJSSUdIVFwiPjxCPjxGT05UIEZBQ0U9XCJWZXJkYW5hLCBBcmlhbCwgSGVsdmV0aWNhXCI+VG86PC9GT05UPjwvQj48L1REPjxURCBXSURUSD1cIjg0JVwiIEhFSUdIVD1cIjIyXCI+PElOUFVUIFRZUEU9XCJURVhUXCIgTkFNRT1cInRvXCIgU0laRT1cIjMwXCI+IDxGT05UIFNJWkU9XCIxXCIgRkFDRT1cIlZlcmRhbmEsIEFyaWFsLCBIZWx2ZXRpY2FcIj4gKHNlcGFyYXRlIGFkZHJlc3NlcyB3aXRoIGNvbW1hcyk8L0ZPTlQ+PC9URD48L1RSPjxUUj48VEQgV0lEVEg9XCIxNiVcIj48UCBBTElHTj1cIlJJR0hUXCI+PEI+PEZPTlQgRkFDRT1cIlZlcmRhbmEsIEFyaWFsLCBIZWx2ZXRpY2FcIj5DQzo8L0ZPTlQ+PC9CPjwvVEQ+PFREIFdJRFRIPVwiODQlXCI+PElOUFVUIFRZUEU9XCJURVhUXCIgTkFNRT1cImNjXCIgU0laRT1cIjMwXCI+IDxGT05UIFNJWkU9XCIxXCIgRkFDRT1cIlZlcmRhbmEsIEFyaWFsLCBIZWx2ZXRpY2FcIj4gKHNlcGFyYXRlIGFkZHJlc3NlcyB3aXRoIGNvbW1hcyk8L0ZPTlQ+PC9URD48L1RSPjxUUj48VEQgV0lEVEg9XCIxNiVcIj48UCBBTElHTj1cIlJJR0hUXCI+PEI+PEZPTlQgRkFDRT1cIlZlcmRhbmEsIEFyaWFsLCBIZWx2ZXRpY2FcIj5TdWJqZWN0OjwvRk9OVD48L0I+PC9URD48VEQgV0lEVEg9XCI4NCVcIj48SU5QVVQgVFlQRT1cIlRFWFRcIiBOQU1FPVwic3ViamVjdFwiIFNJWkU9XCI1NVwiPjwvVEQ+PC9UUj48VFI+PFREIFdJRFRIPVwiMTYlXCI+Jm5ic3A7PC9URD48VEQgV0lEVEg9XCI4NCVcIj48VEVYVEFSRUEgTkFNRT1cInRleHRcIiBST1dTPVwiMTVcIiBDT0xTPVwiNTNcIj48L1RFWFRBUkVBPjwvVEQ+PC9UUj48VFI+PFREIFdJRFRIPVwiMTYlXCIgSEVJR0hUPVwiMzJcIj4mbmJzcDs8L1REPjxURCBXSURUSD1cIjg0JVwiIEhFSUdIVD1cIjMyXCI+PElOUFVUIFRZUEU9XCJTVUJNSVRcIiBOQU1FPVwiU2VuZFwiIFZBTFVFPVwiU2VuZFwiPjxJTlBVVCBUWVBFPVwiUkVTRVRcIiBOQU1FPVwiUmVzZXRcIiBWQUxVRT1cIlJlc2V0XCI+PC9URD48L1RSPjwvVEFCTEU+PC9GT1JNPjwvQk9EWT48L0hUTUw+IjsKKworfQorCisKKy8qKgorICogVGhpcyBjbGFzcyBpcyB1c2VkIHRvIHN0b3JlIHNlc3Npb24gZGF0YSBmb3IgZWFjaCB1c2VyJ3Mgc2Vzc2lvbi4gSXQKKyAqIGlzIHN0b3JlZCBpbiB0aGUgSHR0cFNlc3Npb24uCisgKi8KK2NsYXNzIE1haWxVc2VyRGF0YSB7CisgICAgVVJMTmFtZSB1cmw7CisgICAgU2Vzc2lvbiBzZXNzaW9uOworICAgIFN0b3JlIHN0b3JlOworICAgIEZvbGRlciBmb2xkZXI7CisKKyAgICBwdWJsaWMgTWFpbFVzZXJEYXRhKFVSTE5hbWUgdXJsbmFtZSkgeworCXVybCA9IHVybG5hbWU7CisgICAgfQorCisgICAgcHVibGljIFVSTE5hbWUgZ2V0VVJMTmFtZSgpIHsKKwlyZXR1cm4gdXJsOworICAgIH0KKworICAgIHB1YmxpYyBTZXNzaW9uIGdldFNlc3Npb24oKSB7CisJcmV0dXJuIHNlc3Npb247CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0U2Vzc2lvbihTZXNzaW9uIHMpIHsKKwlzZXNzaW9uID0gczsKKyAgICB9CisKKyAgICBwdWJsaWMgU3RvcmUgZ2V0U3RvcmUoKSB7CisJcmV0dXJuIHN0b3JlOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFN0b3JlKFN0b3JlIHMpIHsKKwlzdG9yZSA9IHM7CisgICAgfQorCisgICAgcHVibGljIEZvbGRlciBnZXRGb2xkZXIoKSB7CisJcmV0dXJuIGZvbGRlcjsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRGb2xkZXIoRm9sZGVyIGYpIHsKKwlmb2xkZXIgPSBmOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NlcnZsZXQvc3JjL21haW4vamF2YS9SRUFETUUudHh0IGIvc2VydmxldC9zcmMvbWFpbi9qYXZhL1JFQURNRS50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWQyODk2YQotLS0gL2Rldi9udWxsCisrKyBiL3NlcnZsZXQvc3JjL21haW4vamF2YS9SRUFETUUudHh0CkBAIC0wLDAgKzEsMTQ1IEBACisJCQkgICAgIEphdmFNYWlsIFNlcnZsZXQKKwkJCSAgICAgfn5+fn5+fn5+fn5+fn5+fgorCitPdmVydmlldzoKKz09PT09PT09PQorCitKYXZhTWFpbFNlcnZsZXQgc2hvdWxkIG5vdCBiZSB0YWtlbiBhcyBhIGRlbW8gb2YgaG93IHRvIHVzZSB0aGUgSmF2YSAKK1NlcnZsZXQgQVBJLiBJdCBpcyByYXRoZXIgYW4gZXhhbXBsZSBvZiBob3cgdGhlIEphdmFNYWlsIEFQSXMgY291bGQgCitiZSB1c2VkIGluIGEgc2VydmVyIGluIGEgdGhyZWUtdGllciBlbnZpcm9ubWVudCBkZXNjcmliZWQgYnkgdGhlIAorZm9sbG93aW5nIGRpYWdyYW06CisKKwkrLS0tLS0tLS0tLS0rICAgICAgICArLS0tLS0tLS0tLS0rICAgICAgICArLS0tLS0tLS0tLS0rCisJfCAgIElNQVAgICAgfCAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgfCAgICAgICAgICAgfAorCXwgIFNlcnZlciAgIHw8LUlNQVAtPnwgSmF2YU1haWwgIHw8LUhUVFAtPnwgICAgV1dXICAgIHwKKwkrLS0tLS0tLS0tLS0rICAgICAgICB8IFNlcnZsZXQgICB8LS1IVE1MLT58ICBCcm93c2VyICB8CisJfCAgIFNNVFAgICAgfDwtU01UUC0+fCAgICAgICAgICAgfCAgICAgICAgfCAgICAgICAgICAgfAorCXwgIFNlcnZlciAgIHwgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgIHwgICAgICAgICAgIHwKKwkrLS0tLS0tLS0tLS0rICAgICAgICArLS0tLS0tLS0tLS0rICAgICAgICArLS0tLS0tLS0tLS0rCisKKworVGhlIEphdmFNYWlsU2VydmxldCBzdXBwb3J0cyB0aGUgZm9sbG93aW5nIGZ1bmN0aW9uYWxpdHk6CisJKiBsb2dpbiB0byBhbiBJTUFQIHNlcnZlcgorCSogbGlzdCBhbGwgdGhlIG1lc3NhZ2VzIGluIHRoZSBJTkJPWCBmb2xkZXIKKwkqIHZpZXcgdGhlIHNlbGVjdGVkIG1lc3NhZ2UKKwkqIGNvbXBvc2UgYW5kIHNlbmQgYSBtZXNzYWdlCisKKworU2V0dGluZyB1cCBhbmQgcnVubmluZyB0aGUgZGVtbzoKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CitOb3RlOiBUaGVzZSBpbnN0cnVjdGlvbnMgZXhwbGFpbiBob3cgdG8gY29tcGlsZSBhbmQgcnVuIHRoZSBzZXJ2bGV0IAorZGVtbyB3aXRoIEphdmEgV2ViIFNlcnZlciAoSldTKS4gVGhlIHByb2NlZHVyZSBzaG91bGQgYmUgc2ltaWxhciB3aXRoIAorb3RoZXIgd2ViIHNlcnZlcnMgdGhhdCBzdXBwb3J0IHRoZSBKYXZhIFNlcnZsZXQgQVBJLgorCisJMS4gRG93bmxvYWQgdGhlIGxhdGVzdCB2ZXJzaW9uIG9mIHRoZSBKYXZhIFdlYiBTZXJ2ZXIgZnJvbQorCSAgIGh0dHA6Ly93d3cuc3VuLmNvbS9zb2Z0d2FyZS9qd2Vic2VydmVyL2luZGV4Lmh0bWwgYW5kCisJICAgaW5zdGFsbCBhY2NvcmRpbmcgdG8gdGhlIGluY2x1ZGVkIGRvY3VtZW50YXRpb24uIE1ha2UKKwkgICBzdXJlIEpXUyBpcyBsaXN0ZW5pbmcgdG8gcmVxdWVzdHMgb24gcG9ydCA4MCAoeW91IG1heSAKKwkgICBuZWVkIHRvIG1vZGlmeSBpdCBmcm9tIGRlZmF1bHQgcG9ydCA4MDgwOyB1c2UgdGhlIEpXUyAKKwkgICBBZG1pbiBBcHBsZXQpLiBNYWtlIHN1cmUgeW91IGNhbiBsb2FkIHRoZSBKYXZhIFdlYiAKKwkgICBTZXJ2ZXIgd2VsY29tZSBwYWdlIHdoZW4geW91IGNvbm5lY3Qgd2l0aCB5b3VyIGJyb3dzZXIgCisJICAgdG8gdGhlIG1hY2hpbmUgdGhhdCB0aGUgc2VydmVyIGlzIGluc3RhbGxlZCBvbi4gQWxzbywKKwkgICBtYWtlIHN1cmUgeW91ciB3ZWIgYnJvd3NlciBoYXMgY29va2llIHN1cHBvcnQgdHVybmVkIG9uLgorCisJMi4gU2V0IHlvdXIgY2xhc3NwYXRoIHRvIGluY2x1ZGUgdGhlIGZvbGxvd2luZzoKKwkgICAgKiBtYWlsLmphcjoJCWluIHRoZSBKYXZhTWFpbCBBUEkgZGlzdHJpYnV0aW9uCisJICAgICogYWN0aXZhdGlvbi5qYXI6CWluIHRoZSBKQUYgZGlzdHJpYnV0aW9uCisJICAgICogandzLmphcjoJCWluIHRoZSAvbGliLyBkaXJlY3RvcnkgaW4gSldTIGluc3RhbGxhdGlvbgorCisJMy4gSW4gamF2YW1haWwtMS4xL2RlbW8vc2VydmxldCBkaXJlY3RvcnksIGNvbXBpbGUgdGhlIAorCSAgIEphdmFNYWlsU2VydmxldC5qYXZhIGZpbGUuIFRoYXQgcHJvZHVjZXMgdHdvIGNsYXNzIGZpbGVzLAorCSAgIEphdmFNYWlsU2VydmxldC5jbGFzcyBhbmQgTWFpbFVzZXJEYXRhLmNsYXNzLiBDb3B5IHRoZXNlCisJICAgY2xhc3MgZmlsZXMgdG8gdGhlIC9zZXJ2bGV0cy8gZGlyZWN0b3J5IGluIHRoZSBKV1MgCisJICAgaW5zdGFsbGF0aW9uLgorCisJNC4gQ29weSB0aGUgbWFpbC5qYXIgYW5kIGFjdGl2YXRpb24uamFyIHRvIHRoZSAvbGliLworCSAgIGRpcmVjdG9yeSBpbiB0aGUgSldTIGluc3RhbGxhdGlvbi4KKworCTUuIENvcHkgdGhlIEphdmFNYWlsLmh0bWwgZmlsZSB0byB0aGUgL3B1YmxpY19odG1sLworCSAgIGRpcmVjdG9yeSBpbiB0aGUgSldTIGluc3RhbGxhdGlvbi4KKworCTYuIFJlc3RhcnQgSmF2YSBXZWIgU2VydmVyIHRvIHBpY2sgdXAgdGhlIG5ldyBqYXIgZmlsZXMKKwkgICBhZGRlZCB0byBpdHMgbGliIGRpcmVjdG9yeS4gQ2hlY2sgYWdhaW4gdGhhdCB5b3UgY2FuCisJICAgbG9hZCB0aGUgZGVmYXVsdCBKV1MgcGFnZSB0byB2ZXJpZnkgdGhhdCB0aGUgc2VydmVyCisJICAgaXMgd29ya2luZyBmaW5lLgorCisJNy4gVXNpbmcgYSB3ZWIgYnJvd3NlciwgZ28gdG8gCisJICAgaHR0cDovLzxob3N0bmFtZT4vSmF2YU1haWwuaHRtbCBhbmQgbG9naW4gdG8gYQorCSAgIHZhbGlkIElNQVAgYWNjb3VudC4gRnJvbSBoZXJlIG9uLCB5b3UgY2FuIHZpZXcgCisJICAgbWVzc2FnZXMgaW4geW91ciBJTkJPWCBhbmQgY3JlYXRlIGFuZCBzZW5kIG5ldyAKKwkgICBtZXNzYWdlcy4KKworCisKK0phdmFNYWlsU2VydmxldCBEZXNpZ246Cis9PT09PT09PT09PT09PT09PT09PT09PQorCitUaGUgZm9sbG93aW5nIGlzIGEgYnJpZWYgZGVzY3JpcHRpb24gb2YgSmF2YU1haWxTZXJ2bGV0IGNsYXNzLiBJdAoraXMgbm90IGludGVuZGVkIHRvIHNlcnZlIGFzIGFuIGV4YW1wbGUgb2YgaG93IHRvIGRldmVsb3Agc2VydmxldHM7CitzZWUgaHR0cDovL2phdmEuc3VuLmNvbS9wcm9kdWN0cy9zZXJ2bGV0IGZvciBpbmZvcm1hdGlvbiBvbiB0aGUgSmF2YQorU2VydmxldCBBUEkuIFlvdSBtYXkgZmluZCBpdCB1c2VmdWwgdG8gcmVmZXIgdG8gSmF2YU1haWxTZXJ2bGV0LmphdmEKK3NvdXJjZSB3aGlsZSByZWFkaW5nIHRoaXMuCisKK1RoZSBKYXZhTWFpbFNlcnZsZXQgdXNlcyB0d28gcHJpbWFyeSBtZXRob2RzIHRvIHByb2Nlc3MgYWxsCityZXF1ZXN0czogZG9Qb3N0KCkgYW5kIGRvR2V0KCkuIGRvUG9zdCgpIHByb2Nlc3NlcyBzdWJtaXNzaW9ucworZnJvbSB0aGUgbG9naW4gYW5kIGNvbXBvc2UgZm9ybXMuIFdoZW4gdGhlIHVzZXIgbG9ncyBpbiwgdGhlCitkb1Bvc3QoKSBtZXRob2QgZ2V0cyBhIEphdmFNYWlsIFNlc3Npb24gYW5kIHVzZXMgdGhlIHZhbHVlcworb2YgdGhlICJob3N0bmFtZSIsICJ1c2VybmFtZSIgYW5kICJwYXNzd29yZCIgcGFyYW1ldGVycyB0byBsb2dpbgordG8gdGhlIElNQVAgU3RvcmUgYW5kIGdldCB0aGUgSU5CT1ggRm9sZGVyLiBUbyBwcmVzZXJ2ZSBzdGF0ZQorYmV0d2VlbiBtdWx0aXBsZSBIVFRQIHJlcXVlc3RzLCB0aGUgbmVjZXNzYXJ5IGluZm9ybWF0aW9uCisoU2Vzc2lvbiwgU3RvcmUsIEZvbGRlciwgVVJMTmFtZSkgYXJlIGNvbGxlY3RlZCBpbiB0aGUKK01haWxVc2VyRGF0YSBvYmplY3Qgd2hpY2ggaXMgc3RvcmVkIHVzaW5nIEpXUydzIFNlc3Npb24KK3RlY2hub2xvZ3kgKGRvbid0IGNvbmZ1c2UgSHR0cFNlc3Npb24gYW5kIEphdmFNYWlsJ3MgU2Vzc2lvbi0tCit0aGV5IGFyZSBkaWZmZXJlbnQpLiBGaW5hbGx5LCB0aGUgZG9Qb3N0KCkgbWV0aG9kIG91dHB1dHMgCithIHRhYmxlIGxpc3RpbmcgdGhlIElOQk9YIGFuZCB0aGUgbnVtYmVyIG9mIG1lc3NhZ2VzIGluIGl0LgorCitDbGlja2luZyBvbiB0aGUgIklOQk9YIiBsaW5rIGNhbGxzIHRoZSBkb0dldCgpIG1ldGhvZAord2hpY2ggZGlzcGxheXMgYSB0YWJsZSBvZiBtZXNzYWdlIGhlYWRlcnMuIChTZWUgdGhlIGRvR2V0KCkgCithbmQgZGlzcGxheUhlYWRlcnMoKSBtZXRob2RzLikKKworQ2xpY2tpbmcgb24gYSBtZXNzYWdlIGdlbmVyYXRlcyBhIHJlcXVlc3QgdG8gdGhlIHNlcnZsZXQgd2l0aAordGhlIG1lc3NhZ2Ugc2VxdWVuY2UgbnVtYmVyIGFzIGEgcGFyYW1ldGVyLiBUaGUgZG9HZXQoKSBtZXRob2QKK3JlY2VpdmVzIHRoZSByZXF1ZXN0IGFuZCBjYWxscyB0aGUgZGlzcGxheU1lc3NhZ2UoKSBtZXRob2QgCitwYXNzaW5nIGl0IHRoZSBtZXNzYWdlIHNlcXVlbmNlIG51bWJlciB0byBkaXNwbGF5LiBUaGUgCitkaXNwbGF5TWVzc2FnZSgpIG1ldGhvZCBmaXJzdCBsaXN0cyB0aGUgbWVzc2FnZSBoZWFkZXJzIAorYnkgY2FsbGluZyB0aGUgZGlzcGxheU1lc3NhZ2VIZWFkZXJzKCkgdXRpbGl0eSBtZXRob2QuIAorRm9yIHRleHQvcGxhaW4gbWVzc2FnZXMsIHRoZSBtZXNzYWdlIGNvbnRlbnQgaXMgdGhlbiBkaXNwbGF5ZWQKK2FzIGEgc3RyaW5nIHdyYXBwZWQgaW4gSFRNTCA8cHJlPi4uLjwvcHJlPiB0YWdzLiBGb3IgbXVsdGlwYXJ0IAorbWVzc2FnZXMsIGVhY2ggcGFydCBpcyBwYXNzZWQgdG8gdGhlIGRpc3BsYXlQYXJ0KCkgbWV0aG9kLgorCitUaGVyZSBhcmUgdHdvIGRpc3BsYXlQYXJ0KCkgbWV0aG9kcy4gVGhlIG9uZSB3aXRoIHNpZ25hdHVyZQorCWRpc3BsYXlQYXJ0KE1haWxVc2VyRGF0YSBtdWQsIGludCBtc2dOdW0sIFBhcnQgcGFydCwgCisJCSAgICBpbnQgcGFydE51bSwgSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcSwgCisJCSAgICBTZXJ2bGV0T3V0cHV0U3RyZWFtIG91dCkgCitpcyBjYWxsZWQgZnJvbSB0aGUgZGlzcGxheU1lc3NhZ2UoKSBtZXRob2QgZm9yIGVhY2ggcGFydC4gRm9yCithbnkgcGFydCB3aXRoIHRleHQvcGxhaW4gY29udGVudCB0eXBlLCB0aGUgY29udGVudCBpcyBvdXRwdXQKK2FzIGEgc3RyaW5nIHdyYXBwZWQgaW4gSFRNTCA8cHJlPi4uLjwvcHJlPiB0YWdzLiBGb3Igb3RoZXIKK2NvbnRlbnQgdHlwZXMsIGEgbGluayByZXByZXNlbnRpbmcgdGhlIHBhcnQgaXMgZGlzcGxheWVkLAorYWxvbmcgd2l0aCB0aGUgcGFydCBmaWxlbmFtZSBhbmQgZGVzY3JpcHRpb24sIGlmIGF2YWlsYWJsZS4KKworQ2xpY2tpbmcgaW4gdGhlIHBhcnQgbGluayBnZW5lcmF0ZXMgYSByZXF1ZXN0IHRvIHRoZSBzZXJ2bGV0Cit3aXRoIHR3byBwYXJhbWV0ZXJzOiB0aGUgbWVzc2FnZSBzZXF1ZW5jZSBudW1iZXIgYW5kIHRoZQorcGFydCBudW1iZXIuIFRoZSBkb0dldCgpIG1ldGhvZCBpbnRlcnByZXRzIHRoZSBwYXJhbWV0ZXJzIGFuZCAKK2ludm9rZXMgdGhlIHNlY29uZCBkaXNwbGF5UGFydCgpIG1ldGhvZCB3aXRoIHRoZSBzaWduYXR1cmUgCisJZGlzcGxheVBhcnQoTWFpbFVzZXJEYXRhIG11ZCwgaW50IG1zZ051bSwKKwkgICAgICAgICAgICBpbnQgcGFydE51bSwgU2VydmxldE91dHB1dFN0cmVhbSBvdXQsIAorCQkgICAgSHR0cFNlcnZsZXRSZXNwb25zZSByZXMpIAorVGhpcyBtZXRob2QgcmV0cmlldmVzIHRoZSBzcGVjaWZpZWQgcGFydCBmcm9tIHRoZSBtZXNzYWdlIGFuZAorc3RyZWFtcyBpdCB0byB0aGUgd2ViIGJyb3dzZXIsIHByZWNlZGVkIGJ5IHRoZSBNSU1FIGNvbnRlbnQgdHlwZSAKK29mIHRoaXMgcGFydC4gRm9yIGV4YW1wbGUsIGlmIHRoZSBwYXJ0IGhhcyBhIE1JTUUgdHlwZSBpbWFnZS9naWYsCit0aGUgbWV0aG9kIHdpbGwgc2V0IHRoZSBzZXJ2bGV0IHJlc3BvbnNlIE1JTUUgY29udGVudCB0eXBlIHRvIAorImltYWdlL2dpZiIgYW5kIHRoZW4gZm9sbG93IGl0IHdpdGggdGhlIGJ5dGVzIG9mIHRoZSBhY3R1YWwgCitpbWFnZS4gVGhpcyBsZXZlcmFnZXMgdGhlIHdlYiBicm93c2VyJ3MgY29udGVudCBoYW5kbGluZworYWJpbGl0eSB0byBkaXNwbGF5IGRpZmZlcmVudCBtZWRpYSB0eXBlcy4KKworTWVzc2FnZSBjb21wb3NpdGlvbiBhbmQgc2VuZGluZyBpcyB2ZXJ5IHNpbWlsYXIgdG8gbWVzc2FnZQordmlld2luZy4gV2hlbiB0aGUgIkNvbXBvc2UiIGxpbmsgaXMgY2xpY2tlZCBpbiB0aGUgaGVhZGVybGlzdAorcGFnZSwgdGhlIHNlcnZsZXQgb3V0cHV0cyB0aGUgSFRNTCBzb3VyY2UgZm9yIHRoZSBjb21wb3NlCitmb3JtIHN0b3JlZCBpbiB0aGUgY29tcG9zZUZvcm0gdmFyaWFibGUuIFRoZSB1c2VyIHRoZW4gZmlsbHMKK2luIHRoZSBkZXN0aW5hdGlvbiBhZGRyZXNzLCBzdWJqZWN0LCB0ZXh0LCBhbmQgcHJlc3Nlcworc2VuZC4gVGhpcyBzZW5kcyBhIFBPU1QgcmVxdWVzdCB0byB0aGUgc2VydmxldCwgd2hpY2ggCitpbnZva2VzIHRoZSBkb1Bvc3QoKSBtZXRob2QuIGRvUG9zdCgpIGNhbGxzIHRoZSBzZXJ2bGV0J3MgCitzZW5kKCkgbWV0aG9kLCB3aGljaCBjcmVhdGVzIGEgbmV3IE1pbWVNZXNzYWdlIGFuZCBmaWxscyAKK2l0IHdpdGggZGF0YSByZXRyaWV2ZWQgZnJvbSB0aGUgUE9TVCByZXF1ZXN0LiBUaGUgbWVzc2FnZQoraXMgdGhlbiBzZW50IHRvIGl0cyBkZXN0aW5hdGlvbiB1c2luZyB0aGUgVHJhbnNwb3J0LnNlbmQoKQorc3RhdGljIG1ldGhvZC4KZGlmZiAtLWdpdCBhL3NpZ2dlbiBiL3NpZ2dlbgpuZXcgZmlsZSBtb2RlIDEwMDc1NQppbmRleCAwMDAwMDAwLi44Yjk1MDgwCi0tLSAvZGV2L251bGwKKysrIGIvc2lnZ2VuCkBAIC0wLDAgKzEsNDggQEAKKyMhL2Jpbi9zaAorIworIyBDb3B5cmlnaHQgKGMpIDIwMTAsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyMKKyMgVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisjIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisjIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyMKKyMgVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorIyBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisjIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorIyB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorIyBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisjCisjIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorIworCisjCisjIEdlbmVyYXRlIGEgbmV3IHNpZ25hdHVyZSBmaWxlLgorIworIyBVc2FnZTogc2lnZ2VuIGphdmF4Lm1haWwuamFyIG1haWwuc2lnCisjCitTSUdURVNUPSR7U0lHVEVTVDotL2phdmEvcmUvc2lndGVzdC80LjAvcHJvbW90ZWQvZmNzL2xhdGVzdC9iaW5hcmllcy9zaWd0ZXN0LTQuMH0KK1NJR1RFU1RfSkFSPSRTSUdURVNUL2xpYi9zaWd0ZXN0ZGV2LmphcgorSkFWQV9IT01FPSR7SkFWQV9IT01FOi0vb3B0L2pkazEuOH0KK1BLRz1qYXZheC5tYWlsCitVU0FHRT0ic2lnZ2VuIFstcCBwYWNrYWdlXSBqYXZheC5tYWlsLmphciBtYWlsLnNpZyIKKword2hpbGUgZ2V0b3B0cyBwOiBvcHQKK2RvCisJY2FzZSAkb3B0IGluCisJcCkJUEtHPSIkT1BUQVJHIjs7CisJXD8pCWVjaG8gJFVTQUdFOyBleGl0IDE7OworCWVzYWMKK2RvbmUKK3NoaWZ0IGBleHByICRPUFRJTkQgLSAxYAorCit2ZXI9JCgkSkFWQV9IT01FL2Jpbi9qYXZhIC12ZXJzaW9uIDI+JjEgfCBzZWQgLWUgJ3MvLioiXCguKlwpIi4qL1wxLztxJykKK2Nhc2UgIiR2ZXIiIGluCisxLlswLTldKikJeGppbWFnZT07CisJCWNwPSIkMToke0pBVkFfSE9NRX0vanJlL2xpYi9ydC5qYXI6JHtKQVZBX0hPTUV9L2pyZS9saWIvamNlLmphciI7OworKikJCXhqaW1hZ2U9Ii14amltYWdlICR7SkFWQV9IT01FfS9iaW4vamltYWdlIjsKKwkJY3A9IiQxOiR7SkFWQV9IT01FfS9saWIvbW9kdWxlcyI7OworZXNhYworCiske0pBVkFfSE9NRX0vYmluL2phdmEgLWphciAkU0lHVEVTVF9KQVIgc2V0dXAgLXN0YXRpYyBcCisJLWNsYXNzcGF0aCAiJGNwIiAkeGppbWFnZSBcCisJLWZpbGVuYW1lICIkMiIgLXBhY2thZ2UgIiRQS0ciIC1ub25jbG9zZWRmaWxlCmRpZmYgLS1naXQgYS9zaWd0ZXN0IGIvc2lndGVzdApuZXcgZmlsZSBtb2RlIDEwMDc1NQppbmRleCAwMDAwMDAwLi4wZWM4NjdhCi0tLSAvZGV2L251bGwKKysrIGIvc2lndGVzdApAQCAtMCwwICsxLDY3IEBACisjIS9iaW4vc2gKKyMKKyMgQ29weXJpZ2h0IChjKSAyMDEwLCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisjCisjIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorIyB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorIyBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisjCisjIFRoaXMgU291cmNlIENvZGUgbWF5IGFsc28gYmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIGZvbGxvd2luZyBTZWNvbmRhcnkKKyMgTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorIyBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyMgdmVyc2lvbiAyIHdpdGggdGhlIEdOVSBDbGFzc3BhdGggRXhjZXB0aW9uLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyMgaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorIworIyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKKyMKKworIworIyBDb21wYXJlIEFQSSBhZ2FpbnN0IGEgc2lnbmF0dXJlIGZpbGUuCisjCisjIFVzYWdlOiBzaWd0ZXN0IGphdmF4Lm1haWwuamFyIG1haWwuc2lnCisjCitTSUdURVNUPSR7U0lHVEVTVDotL2phdmEvcmUvc2lndGVzdC80LjAvcHJvbW90ZWQvZmNzL2xhdGVzdC9iaW5hcmllcy9zaWd0ZXN0LTQuMH0KKyMgVGhlIGFwaWNoZWNrIHByb2dyYW0gaXNuJ3Qgd29ya2luZyBjb3JyZWN0bHksIHVzZSBzaWd0ZXN0IGluc3RlYWQuCisjQVBJQ0hFQ0tfSkFSPSRTSUdURVNUL2xpYi9hcGljaGVjay5qYXIKK1NJR1RFU1RfSkFSPSRTSUdURVNUL2xpYi9zaWd0ZXN0ZGV2LmphcgorSkFWQV9IT01FPSR7SkFWQV9IT01FOi0vb3B0L2pkazEuOH0KK1VTQUdFPSJzaWd0ZXN0IFstYl0gWy1wIHBhY2thZ2VdIGphdmF4Lm1haWwuamFyIG1haWwuc2lnIgorUEtHPWphdmF4Lm1haWwKK0JBQ0tXQVJEPQorUExBVFNJRz0vdG1wLyQkLnBsYXRmb3JtLnNpZworCit3aGlsZSBnZXRvcHRzIGJwOiBvcHQKK2RvCisJY2FzZSAkb3B0IGluCisJcCkJUEtHPSIkT1BUQVJHIjs7CisJYikJQkFDS1dBUkQ9LWJhY2t3YXJkOzsKKwlcPykJZWNobyAkVVNBR0U7IGV4aXQgMTs7CisJZXNhYworZG9uZQorc2hpZnQgYGV4cHIgJE9QVElORCAtIDFgCisKK0pBUj0iJDEiCitTSUc9IiQyIgorc2hpZnQgMgorCit2ZXI9JCgkSkFWQV9IT01FL2Jpbi9qYXZhIC12ZXJzaW9uIDI+JjEgfCBzZWQgLWUgJ3MvLioiXCguKlwpIi4qL1wxLztxJykKK2Nhc2UgIiR2ZXIiIGluCisxLlswLTldKikJeGppbWFnZT07CisJCWNwPSIke0pBVkFfSE9NRX0vanJlL2xpYi9ydC5qYXI6JHtKQVZBX0hPTUV9L2pyZS9saWIvamNlLmphciI7OworKikJCXhqaW1hZ2U9Ii14amltYWdlICR7SkFWQV9IT01FfS9iaW4vamltYWdlIjsKKwkJY3A9IiR7SkFWQV9IT01FfS9saWIvbW9kdWxlcyI7OworZXNhYworCitlY2hvICcqKiogR2VuZXJhdGUgSkRLIHNpZ25hdHVyZXMgKioqJworJHtKQVZBX0hPTUV9L2Jpbi9qYXZhIC1qYXIgJFNJR1RFU1RfSkFSIHNldHVwIFwKKwktY2xhc3NwYXRoICIkY3AiICR4amltYWdlIFwKKwktZmlsZW5hbWUgIiRQTEFUU0lHIiAtcGFja2FnZSBqYXZhIC1wYWNrYWdlIGphdmF4IC1rZWVwZmlsZSBcCisJLXZlcmJvc2Ugbm93YXJuCitlY2hvCitlY2hvICcqKiogQ2hlY2sgSmF2YU1haWwgc2lnbmF0dXJlcyAqKionCiske0pBVkFfSE9NRX0vYmluL2phdmEgLWphciAkU0lHVEVTVF9KQVIgdGVzdCAtc3RhdGljIFwKKwktY2xhc3NwYXRoICIkUExBVFNJRzokSkFSIiBcCisJLWZpbGVuYW1lICIkU0lHIiAtcGFja2FnZSAiJFBLRyIgLW91dCAvZGV2L3N0ZG91dCBcCisJLW5vbWVyZ2UgLWNoZWNrdmFsdWUgLW1vZGUgc3JjICRCQUNLV0FSRCAiJEAiCisKK3JtICIkUExBVFNJRyIKZGlmZiAtLWdpdCBhL3NtdHAvcG9tLnhtbCBiL3NtdHAvcG9tLnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMDVkNDM3Ci0tLSAvZGV2L251bGwKKysrIGIvc210cC9wb20ueG1sCkBAIC0wLDAgKzEsNDEgQEAKKzw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9Imlzby04ODU5LTEiPz4KKzwhLS0KKworICAgIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorCisgICAgVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgICAgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisKKyAgICBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgICAgTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICAgIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICAgIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorCisgICAgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisKKy0tPgorCis8cHJvamVjdCB4bWxucz0iaHR0cDovL21hdmVuLmFwYWNoZS5vcmcvUE9NLzQuMC4wIgorCXhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiCisJeHNpOnNjaGVtYUxvY2F0aW9uPSJodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9QT00vNC4wLjAKKwkJCSAgICBodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9tYXZlbi12NF8wXzAueHNkIj4KKyAgICA8cGFyZW50PgorCTxncm91cElkPmNvbS5zdW4ubWFpbDwvZ3JvdXBJZD4KKwk8YXJ0aWZhY3RJZD5wYXJlbnQtZGlzdHJpYjwvYXJ0aWZhY3RJZD4KKwk8dmVyc2lvbj4xLjYuMzwvdmVyc2lvbj4KKwk8cmVsYXRpdmVQYXRoPi4uL3BhcmVudC1kaXN0cmliL3BvbS54bWw8L3JlbGF0aXZlUGF0aD4KKyAgICA8L3BhcmVudD4KKyAgICA8bW9kZWxWZXJzaW9uPjQuMC4wPC9tb2RlbFZlcnNpb24+CisgICAgPGdyb3VwSWQ+Y29tLnN1bi5tYWlsPC9ncm91cElkPgorICAgIDxhcnRpZmFjdElkPnNtdHA8L2FydGlmYWN0SWQ+CisgICAgPHBhY2thZ2luZz5qYXI8L3BhY2thZ2luZz4KKyAgICA8bmFtZT5KYXZhTWFpbCBBUEkgc210cCBwcm92aWRlcjwvbmFtZT4KKworICAgIDxwcm9wZXJ0aWVzPgorCTxtYWlsLnBhY2thZ2VzLmV4cG9ydD4KKwkgICAgY29tLnN1bi5tYWlsLnNtdHA7IHZlcnNpb249JHttYWlsLm9zZ2l2ZXJzaW9ufQorCTwvbWFpbC5wYWNrYWdlcy5leHBvcnQ+CisgICAgPC9wcm9wZXJ0aWVzPgorPC9wcm9qZWN0PgpkaWZmIC0tZ2l0IGEvc210cC9zcmMvbWFpbi9qYXZhL21vZHVsZS1pbmZvLmphdmEgYi9zbXRwL3NyYy9tYWluL2phdmEvbW9kdWxlLWluZm8uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NDQxMDVkCi0tLSAvZGV2L251bGwKKysrIGIvc210cC9zcmMvbWFpbi9qYXZhL21vZHVsZS1pbmZvLmphdmEKQEAgLTAsMCArMSwyNSBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyAqCisgKiBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgKiBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisgKiBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisgKi8KKworbW9kdWxlIGNvbS5zdW4ubWFpbC5zbXRwIHsKKyAgICBleHBvcnRzIGNvbS5zdW4ubWFpbC5zbXRwOworICAgIHByb3ZpZGVzIGphdmF4Lm1haWwuUHJvdmlkZXIgd2l0aAorCWNvbS5zdW4ubWFpbC5zbXRwLlNNVFBQcm92aWRlciwgY29tLnN1bi5tYWlsLnNtdHAuU01UUFNTTFByb3ZpZGVyOworCisgICAgcmVxdWlyZXMgamFrYXJ0YS5tYWlsOworICAgIHJlcXVpcmVzIGphdmEubG9nZ2luZzsKKyAgICByZXF1aXJlcyBqYXZhLnNlY3VyaXR5LnNhc2w7Cit9CmRpZmYgLS1naXQgYS9zbXRwL3NyYy9tYWluL3Jlc291cmNlcy9NRVRBLUlORi9NQU5JRkVTVC5NRiBiL3NtdHAvc3JjL21haW4vcmVzb3VyY2VzL01FVEEtSU5GL01BTklGRVNULk1GCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE4NDNlMWIKLS0tIC9kZXYvbnVsbAorKysgYi9zbXRwL3NyYy9tYWluL3Jlc291cmNlcy9NRVRBLUlORi9NQU5JRkVTVC5NRgpAQCAtMCwwICsxLDkgQEAKK01hbmlmZXN0LVZlcnNpb246IDEuMAorRXh0ZW5zaW9uLU5hbWU6IGNvbS5zdW4ubWFpbC5zbXRwCitTcGVjaWZpY2F0aW9uLVRpdGxlOiBjb20uc3VuLm1haWwuc210cAorU3BlY2lmaWNhdGlvbi1WZXJzaW9uOiAke21haWwuc3BlYy52ZXJzaW9ufQorU3BlY2lmaWNhdGlvbi1WZW5kb3I6ICR7cHJvamVjdC5vcmdhbml6YXRpb24ubmFtZX0KK0ltcGxlbWVudGF0aW9uLVRpdGxlOiBjb20uc3VuLm1haWwuc210cAorSW1wbGVtZW50YXRpb24tVmVyc2lvbjogJHttYWlsLnZlcnNpb259CitJbXBsZW1lbnRhdGlvbi1WZW5kb3I6ICR7cHJvamVjdC5vcmdhbml6YXRpb24ubmFtZX0KK0ltcGxlbWVudGF0aW9uLVZlbmRvci1JZDogY29tLnN1bgpkaWZmIC0tZ2l0IGEvc210cC9zcmMvbWFpbi9yZXNvdXJjZXMvTUVUQS1JTkYvamF2YW1haWwuYWRkcmVzcy5tYXAgYi9zbXRwL3NyYy9tYWluL3Jlc291cmNlcy9NRVRBLUlORi9qYXZhbWFpbC5hZGRyZXNzLm1hcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40YWI1NTcyCi0tLSAvZGV2L251bGwKKysrIGIvc210cC9zcmMvbWFpbi9yZXNvdXJjZXMvTUVUQS1JTkYvamF2YW1haWwuYWRkcmVzcy5tYXAKQEAgLTAsMCArMSBAQAorcmZjODIyPXNtdHAKZGlmZiAtLWdpdCBhL3NtdHAvc3JjL21haW4vcmVzb3VyY2VzL01FVEEtSU5GL2phdmFtYWlsLnByb3ZpZGVycyBiL3NtdHAvc3JjL21haW4vcmVzb3VyY2VzL01FVEEtSU5GL2phdmFtYWlsLnByb3ZpZGVycwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42YWQ2Yzk4Ci0tLSAvZGV2L251bGwKKysrIGIvc210cC9zcmMvbWFpbi9yZXNvdXJjZXMvTUVUQS1JTkYvamF2YW1haWwucHJvdmlkZXJzCkBAIC0wLDAgKzEsMyBAQAorIyBKYXZhTWFpbCBTTVRQIHByb3ZpZGVyIE9yYWNsZQorcHJvdG9jb2w9c210cDsgdHlwZT10cmFuc3BvcnQ7IGNsYXNzPWNvbS5zdW4ubWFpbC5zbXRwLlNNVFBUcmFuc3BvcnQ7IHZlbmRvcj1PcmFjbGU7Citwcm90b2NvbD1zbXRwczsgdHlwZT10cmFuc3BvcnQ7IGNsYXNzPWNvbS5zdW4ubWFpbC5zbXRwLlNNVFBTU0xUcmFuc3BvcnQ7IHZlbmRvcj1PcmFjbGU7CmRpZmYgLS1naXQgYS9zbXRwL3NyYy9tYWluL3Jlc291cmNlcy9NRVRBLUlORi9zZXJ2aWNlcy9qYXZheC5tYWlsLlByb3ZpZGVyIGIvc210cC9zcmMvbWFpbi9yZXNvdXJjZXMvTUVUQS1JTkYvc2VydmljZXMvamF2YXgubWFpbC5Qcm92aWRlcgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jZDVmYjE0Ci0tLSAvZGV2L251bGwKKysrIGIvc210cC9zcmMvbWFpbi9yZXNvdXJjZXMvTUVUQS1JTkYvc2VydmljZXMvamF2YXgubWFpbC5Qcm92aWRlcgpAQCAtMCwwICsxLDIgQEAKK2NvbS5zdW4ubWFpbC5zbXRwLlNNVFBQcm92aWRlcgorY29tLnN1bi5tYWlsLnNtdHAuU01UUFNTTFByb3ZpZGVyCmRpZmYgLS1naXQgYS90YWdsaWIvcG9tLnhtbCBiL3RhZ2xpYi9wb20ueG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhlNmY1MDkKLS0tIC9kZXYvbnVsbAorKysgYi90YWdsaWIvcG9tLnhtbApAQCAtMCwwICsxLDUwIEBACis8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJpc28tODg1OS0xIj8+Cis8IS0tCisKKyAgICBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKworICAgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICAgIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorCisgICAgVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICAgIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAgICBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAgICB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKworICAgIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorCistLT4KKworPHByb2plY3QgeG1sbnM9Imh0dHA6Ly9tYXZlbi5hcGFjaGUub3JnL1BPTS80LjAuMCIKKwl4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIgorCXhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL21hdmVuLmFwYWNoZS5vcmcvUE9NLzQuMC4wCisJCQkgICAgaHR0cDovL21hdmVuLmFwYWNoZS5vcmcvbWF2ZW4tdjRfMF8wLnhzZCI+CisgICAgPHBhcmVudD4KKwk8Z3JvdXBJZD5jb20uc3VuLm1haWw8L2dyb3VwSWQ+CisJPGFydGlmYWN0SWQ+YWxsPC9hcnRpZmFjdElkPgorCTx2ZXJzaW9uPjEuNi4zPC92ZXJzaW9uPgorICAgIDwvcGFyZW50PgorICAgIDxtb2RlbFZlcnNpb24+NC4wLjA8L21vZGVsVmVyc2lvbj4KKyAgICA8Z3JvdXBJZD5jb20uc3VuLm1haWw8L2dyb3VwSWQ+CisgICAgPGFydGlmYWN0SWQ+dGFnbGliPC9hcnRpZmFjdElkPgorICAgIDxwYWNrYWdpbmc+amFyPC9wYWNrYWdpbmc+CisgICAgPG5hbWU+SmF2YU1haWwgQVBJIGRlbW8gdGFnbGliPC9uYW1lPgorCisgICAgPGRlcGVuZGVuY2llcz4KKyAgICAgICAgPGRlcGVuZGVuY3k+CisgICAgICAgICAgICA8Z3JvdXBJZD5qYXZheC5zZXJ2bGV0LmpzcDwvZ3JvdXBJZD4KKyAgICAgICAgICAgIDxhcnRpZmFjdElkPmpzcC1hcGk8L2FydGlmYWN0SWQ+CisgICAgICAgIDwvZGVwZW5kZW5jeT4KKwk8IS0tIFhYWCAtIGphdmF4LnNlcnZsZXQuanNwIHNob3VsZCBkZXBlbmQgb24gdGhpcyAtLT4KKyAgICAgICAgPGRlcGVuZGVuY3k+CisgICAgICAgICAgICA8Z3JvdXBJZD5qYXZheC5zZXJ2bGV0PC9ncm91cElkPgorICAgICAgICAgICAgPGFydGlmYWN0SWQ+c2VydmxldC1hcGk8L2FydGlmYWN0SWQ+CisgICAgICAgIDwvZGVwZW5kZW5jeT4KKyAgICAgICAgPGRlcGVuZGVuY3k+CisgICAgICAgICAgICA8Z3JvdXBJZD5jb20uc3VuLm1haWw8L2dyb3VwSWQ+CisgICAgICAgICAgICA8YXJ0aWZhY3RJZD5qYWthcnRhLm1haWw8L2FydGlmYWN0SWQ+CisgICAgICAgIDwvZGVwZW5kZW5jeT4KKyAgICA8L2RlcGVuZGVuY2llcz4KKzwvcHJvamVjdD4KZGlmZiAtLWdpdCBhL3RhZ2xpYi9zcmMvbWFpbi9qYXZhL2RlbW8vQXR0YWNobWVudEluZm8uamF2YSBiL3RhZ2xpYi9zcmMvbWFpbi9qYXZhL2RlbW8vQXR0YWNobWVudEluZm8uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mYzQ0ZDU3Ci0tLSAvZGV2L251bGwKKysrIGIvdGFnbGliL3NyYy9tYWluL2phdmEvZGVtby9BdHRhY2htZW50SW5mby5qYXZhCkBAIC0wLDAgKzEsMTE3IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDAxLCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBEaXN0cmlidXRpb24gTGljZW5zZSB2LiAxLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9vcmcvZG9jdW1lbnRzL2VkbC12MTAucGhwLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBCU0QtMy1DbGF1c2UKKyAqLworCitwYWNrYWdlIGRlbW87CisKK2ltcG9ydCBqYXZhLmlvLio7CitpbXBvcnQgamF2YS51dGlsLio7CisKK2ltcG9ydCBqYXZheC5tYWlsLio7CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC4qOworCisvKioKKyAqIFVzZWQgdG8gc3RvcmUgYXR0YWNobWVudCBpbmZvcm1hdGlvbi4KKyAqLworcHVibGljIGNsYXNzIEF0dGFjaG1lbnRJbmZvIHsKKyAgICBwcml2YXRlIFBhcnQgcGFydDsKKyAgICBwcml2YXRlIGludCBudW07CisKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGF0dGFjaG1lbnQncyBjb250ZW50IHR5cGUuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRBdHRhY2htZW50VHlwZSgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCVN0cmluZyBjb250ZW50VHlwZTsKKwlpZiAoKGNvbnRlbnRUeXBlID0gcGFydC5nZXRDb250ZW50VHlwZSgpKSA9PSBudWxsKQorCSAgICByZXR1cm4gImludmFsaWQgcGFydCI7CisJZWxzZQorCSAgICByZXR1cm4gY29udGVudFR5cGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgYXR0YWNobWVudCdzIGNvbnRlbnQgKGlmIGl0IGlzIHBsYWluIHRleHQpLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q29udGVudCgpIHRocm93cyBJT0V4Y2VwdGlvbiwgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpZiAoaGFzTWltZVR5cGUoInRleHQvcGxhaW4iKSkKKwkgICAgcmV0dXJuIChTdHJpbmcpcGFydC5nZXRDb250ZW50KCk7CisJZWxzZQorCSAgICByZXR1cm4gIiI7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgYXR0YWNobWVudCdzIGRlc2NyaXB0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0RGVzY3JpcHRpb24oKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlTdHJpbmcgZGVzY3JpcHRpb247CisJaWYgKChkZXNjcmlwdGlvbiA9IHBhcnQuZ2V0RGVzY3JpcHRpb24oKSkgIT0gbnVsbCkKKwkgICAgcmV0dXJuIGRlc2NyaXB0aW9uOworCWVsc2UKKwkgICAgcmV0dXJuICIiOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGF0dGFjaG1lbnQncyBmaWxlbmFtZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEZpbGVuYW1lKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJU3RyaW5nIGZpbGVuYW1lOworCWlmICgoZmlsZW5hbWUgPSBwYXJ0LmdldEZpbGVOYW1lKCkpICE9IG51bGwpCisJICAgIHJldHVybiBmaWxlbmFtZTsKKwllbHNlCisJICAgIHJldHVybiAiIjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBhdHRhY2htZW50IG51bWJlci4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldE51bSgpIHsKKwlyZXR1cm4gKEludGVnZXIudG9TdHJpbmcobnVtKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTWV0aG9kIGZvciBjaGVja2luZyBpZiB0aGUgYXR0YWNobWVudCBoYXMgYSBkZXNjcmlwdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNEZXNjcmlwdGlvbigpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXJldHVybiAocGFydC5nZXREZXNjcmlwdGlvbigpICE9IG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIE1ldGhvZCBmb3IgY2hlY2tpbmcgaWYgdGhlIGF0dGFjaG1lbnQgaGFzIGEgZmlsZW5hbWUuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaGFzRmlsZW5hbWUoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gKHBhcnQuZ2V0RmlsZU5hbWUoKSAhPSBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNZXRob2QgZm9yIGNoZWNraW5nIGlmIHRoZSBhdHRhY2htZW50IGhhcyB0aGUgZGVzaXJlZCBtaW1lIHR5cGUuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaGFzTWltZVR5cGUoU3RyaW5nIG1pbWVUeXBlKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gcGFydC5pc01pbWVUeXBlKG1pbWVUeXBlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNZXRob2QgZm9yIGNoZWNraW5nIHRoZSBjb250ZW50IGRpc3Bvc2l0aW9uLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzSW5saW5lKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKHBhcnQuZ2V0RGlzcG9zaXRpb24oKSAhPSBudWxsKQorCSAgICByZXR1cm4gcGFydC5nZXREaXNwb3NpdGlvbigpLmVxdWFscyhQYXJ0LklOTElORSk7CisJZWxzZQorCSAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNZXRob2QgZm9yIG1hcHBpbmcgYSBtZXNzYWdlIHBhcnQgdG8gdGhpcyBBdHRhY2htZW50SW5mbyBjbGFzcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRQYXJ0KGludCBudW0sIFBhcnQgcGFydCkKKwl0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uLCBQYXJzZUV4Y2VwdGlvbiB7CisKKwl0aGlzLnBhcnQgPSBwYXJ0OworCXRoaXMubnVtID0gbnVtOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3RhZ2xpYi9zcmMvbWFpbi9qYXZhL2RlbW8vTGlzdEF0dGFjaG1lbnRzVEVJLmphdmEgYi90YWdsaWIvc3JjL21haW4vamF2YS9kZW1vL0xpc3RBdHRhY2htZW50c1RFSS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUwOGExNWYKLS0tIC9kZXYvbnVsbAorKysgYi90YWdsaWIvc3JjL21haW4vamF2YS9kZW1vL0xpc3RBdHRhY2htZW50c1RFSS5qYXZhCkBAIC0wLDAgKzEsMzQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDEsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorICovCisKK3BhY2thZ2UgZGVtbzsKKworaW1wb3J0IGphdmF4LnNlcnZsZXQuanNwLio7CitpbXBvcnQgamF2YXguc2VydmxldC5qc3AudGFnZXh0Lio7CisKKy8qKgorICogRXh0cmEgaW5mb3JtYXRpb24gY2xhc3MgdG8gc3VwcG9ydCB0aGUgc2NyaXB0aW5nIHZhcmlhYmxlIGNyZWF0ZWQgYnkgdGhlCisgKiBMaXN0QXR0YWNobWVudHNUYWcgY2xhc3MuIFRoZSBzY29wZSBvZiB0aGUgdmFyaWFibGUgaXMgbGltaXRlZCB0byB0aGUgYm9keQorICogb2YgdGhlIHRhZy4KKyAqLworcHVibGljIGNsYXNzIExpc3RBdHRhY2htZW50c1RFSSBleHRlbmRzIFRhZ0V4dHJhSW5mbyB7CisgICAgCisgICAgcHVibGljIExpc3RBdHRhY2htZW50c1RFSSgpIHsKKwlzdXBlcigpOworICAgIH0KKyAgICAKKyAgICBwdWJsaWMgVmFyaWFibGVJbmZvW10gZ2V0VmFyaWFibGVJbmZvKFRhZ0RhdGEgZGF0YSkgeworCVZhcmlhYmxlSW5mbyBpbmZvID0gbmV3IFZhcmlhYmxlSW5mbyhkYXRhLmdldElkKCksIkF0dGFjaG1lbnRJbmZvIiwKKwkgICAgdHJ1ZSwgVmFyaWFibGVJbmZvLk5FU1RFRCk7CisJVmFyaWFibGVJbmZvW10gdmFySW5mbyA9IHsgaW5mbyB9OworCXJldHVybiB2YXJJbmZvOworICAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvdGFnbGliL3NyYy9tYWluL2phdmEvZGVtby9MaXN0QXR0YWNobWVudHNUYWcuamF2YSBiL3RhZ2xpYi9zcmMvbWFpbi9qYXZhL2RlbW8vTGlzdEF0dGFjaG1lbnRzVGFnLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODUyMjg2NgotLS0gL2Rldi9udWxsCisrKyBiL3RhZ2xpYi9zcmMvbWFpbi9qYXZhL2RlbW8vTGlzdEF0dGFjaG1lbnRzVGFnLmphdmEKQEAgLTAsMCArMSwxMDEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDEsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorICovCisKK3BhY2thZ2UgZGVtbzsKKworaW1wb3J0IGphdmEuaW8uKjsKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBqYXZheC5tYWlsLio7CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC4qOworaW1wb3J0IGphdmF4LnNlcnZsZXQuanNwLio7CitpbXBvcnQgamF2YXguc2VydmxldC5qc3AudGFnZXh0Lio7CisKKy8qKgorICogQ3VzdG9tIHRhZyBmb3IgbGlzdGluZyBtZXNzYWdlIGF0dGFjaG1lbnRzLiBUaGUgc2NyaXB0aW5nIHZhcmlhYmxlIGlzIG9ubHkKKyAqIHdpdGhpbiB0aGUgYm9keSBvZiB0aGUgdGFnLgorICovCitwdWJsaWMgY2xhc3MgTGlzdEF0dGFjaG1lbnRzVGFnIGV4dGVuZHMgQm9keVRhZ1N1cHBvcnQgeworICAgIHByaXZhdGUgU3RyaW5nIG1lc3NhZ2VpbmZvOworICAgIHByaXZhdGUgaW50IHBhcnROdW0gPSAxOworICAgIHByaXZhdGUgaW50IG51bVBhcnRzID0gMDsKKyAgICBwcml2YXRlIEF0dGFjaG1lbnRJbmZvIGF0dGFjaG1lbnRpbmZvOworICAgIHByaXZhdGUgTWVzc2FnZUluZm8gbWVzc2FnZUluZm87CisgICAgcHJpdmF0ZSBNdWx0aXBhcnQgbXVsdGlwYXJ0OworCisgICAgLyoqCisgICAgICogbWVzc2FnZWluZm8gYXR0cmlidXRlIGdldHRlciBtZXRob2QuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRNZXNzYWdlaW5mbygpIHsKKwlyZXR1cm4gbWVzc2FnZWluZm87CisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIG1lc3NhZ2VpbmZvIGF0dHJpYnV0ZSBzZXR0ZXIgbWV0aG9kLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE1lc3NhZ2VpbmZvKFN0cmluZyBtZXNzYWdlaW5mbykgeworCXRoaXMubWVzc2FnZWluZm8gPSBtZXNzYWdlaW5mbzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNZXRob2QgZm9yIHByb2Nlc3NpbmcgdGhlIHN0YXJ0IG9mIHRoZSB0YWcuCisgICAgICovCisgICAgcHVibGljIGludCBkb1N0YXJ0VGFnKCkgdGhyb3dzIEpzcEV4Y2VwdGlvbiB7CisJbWVzc2FnZUluZm8gPSAoTWVzc2FnZUluZm8pcGFnZUNvbnRleHQuZ2V0QXR0cmlidXRlKGdldE1lc3NhZ2VpbmZvKCkpOworCWF0dGFjaG1lbnRpbmZvID0gbmV3IEF0dGFjaG1lbnRJbmZvKCk7CisJCisJdHJ5IHsKKwkgICAgbXVsdGlwYXJ0ID0gKE11bHRpcGFydCltZXNzYWdlSW5mby5nZXRNZXNzYWdlKCkuZ2V0Q29udGVudCgpOworCSAgICBudW1QYXJ0cyA9IG11bHRpcGFydC5nZXRDb3VudCgpOworCX0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCSAgICB0aHJvdyBuZXcgSnNwRXhjZXB0aW9uKGV4LmdldE1lc3NhZ2UoKSk7CisJfQorCisJZ2V0UGFydCgpOworCisJcmV0dXJuIEJvZHlUYWcuRVZBTF9CT0RZX1RBRzsKKyAgICB9CisgICAKKyAgICAvKioKKyAgICAgKiBNZXRob2QgZm9yIHByb2Nlc3NpbmcgdGhlIGJvZHkgY29udGVudCBvZiB0aGUgdGFnLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZG9BZnRlckJvZHkoKSB0aHJvd3MgSnNwRXhjZXB0aW9uIHsKKwkKKwlCb2R5Q29udGVudCBib2R5ID0gZ2V0Qm9keUNvbnRlbnQoKTsKKwl0cnkgeworCSAgICBib2R5LndyaXRlT3V0KGdldFByZXZpb3VzT3V0KCkpOworCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKwkgICAgdGhyb3cgbmV3IEpzcFRhZ0V4Y2VwdGlvbigiSXRlcmF0aW9uVGFnOiAiICsgZS5nZXRNZXNzYWdlKCkpOworCX0KKwkKKwkvLyBjbGVhciB1cCBzbyB0aGUgbmV4dCB0aW1lIHRoZSBib2R5IGNvbnRlbnQgaXMgZW1wdHkKKwlib2R5LmNsZWFyQm9keSgpOworICAgICAgIAorCXBhcnROdW0rKzsKKwlpZiAocGFydE51bSA8IG51bVBhcnRzKSB7CisJICAgIGdldFBhcnQoKTsKKwkgICAgcmV0dXJuIEJvZHlUYWcuRVZBTF9CT0RZX1RBRzsKKwl9IGVsc2UgeworCSAgICByZXR1cm4gQm9keVRhZy5TS0lQX0JPRFk7CisJfQorICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiBIZWxwZXIgbWV0aG9kIGZvciByZXRyaWV2aW5nIG1lc3NhZ2UgcGFydHMuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGdldFBhcnQoKSB0aHJvd3MgSnNwRXhjZXB0aW9uIHsKKwl0cnkgeworCSAgICBhdHRhY2htZW50aW5mby5zZXRQYXJ0KHBhcnROdW0sIG11bHRpcGFydC5nZXRCb2R5UGFydChwYXJ0TnVtKSk7CisJICAgIHBhZ2VDb250ZXh0LnNldEF0dHJpYnV0ZShnZXRJZCgpLCBhdHRhY2htZW50aW5mbyk7CisJfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJICAgIHRocm93IG5ldyBKc3BFeGNlcHRpb24oZXguZ2V0TWVzc2FnZSgpKTsKKwl9CisgICAgfQorfQorCmRpZmYgLS1naXQgYS90YWdsaWIvc3JjL21haW4vamF2YS9kZW1vL0xpc3RNZXNzYWdlc1RFSS5qYXZhIGIvdGFnbGliL3NyYy9tYWluL2phdmEvZGVtby9MaXN0TWVzc2FnZXNURUkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43M2ViYWVmCi0tLSAvZGV2L251bGwKKysrIGIvdGFnbGliL3NyYy9tYWluL2phdmEvZGVtby9MaXN0TWVzc2FnZXNURUkuamF2YQpAQCAtMCwwICsxLDM0IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDAxLCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBEaXN0cmlidXRpb24gTGljZW5zZSB2LiAxLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9vcmcvZG9jdW1lbnRzL2VkbC12MTAucGhwLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBCU0QtMy1DbGF1c2UKKyAqLworCitwYWNrYWdlIGRlbW87CisKK2ltcG9ydCBqYXZheC5zZXJ2bGV0LmpzcC4qOworaW1wb3J0IGphdmF4LnNlcnZsZXQuanNwLnRhZ2V4dC4qOworCisvKioKKyAqIEV4dHJhIGluZm9ybWF0aW9uIGNsYXNzIHRvIHN1cHBvcnQgdGhlIHNjcmlwdGluZyB2YXJpYWJsZSBjcmVhdGVkIGJ5IHRoZQorICogTGlzdE1lc3NhZ2VzVGFnIGNsYXNzLiBUaGUgc2NvcGUgb2YgdGhlIHZhcmlhYmxlIGlzIGxpbWl0ZWQgdG8gdGhlIGJvZHkgCisgKiBvZiB0aGUgdGFnLgorICovCitwdWJsaWMgY2xhc3MgTGlzdE1lc3NhZ2VzVEVJIGV4dGVuZHMgVGFnRXh0cmFJbmZvIHsKKyAgICAKKyAgICBwdWJsaWMgTGlzdE1lc3NhZ2VzVEVJKCkgeworCXN1cGVyKCk7CisgICAgfQorICAgIAorICAgIHB1YmxpYyBWYXJpYWJsZUluZm9bXSBnZXRWYXJpYWJsZUluZm8oVGFnRGF0YSBkYXRhKSB7CisJVmFyaWFibGVJbmZvIGluZm8gPSBuZXcgVmFyaWFibGVJbmZvKGRhdGEuZ2V0SWQoKSwiTWVzc2FnZUluZm8iLAorCSAgICB0cnVlLCBWYXJpYWJsZUluZm8uTkVTVEVEKTsKKwlWYXJpYWJsZUluZm9bXSB2YXJJbmZvID0geyBpbmZvIH07CisJcmV0dXJuIHZhckluZm87CisgICAgfQorfQorCmRpZmYgLS1naXQgYS90YWdsaWIvc3JjL21haW4vamF2YS9kZW1vL0xpc3RNZXNzYWdlc1RhZy5qYXZhIGIvdGFnbGliL3NyYy9tYWluL2phdmEvZGVtby9MaXN0TWVzc2FnZXNUYWcuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45YWExMTUyCi0tLSAvZGV2L251bGwKKysrIGIvdGFnbGliL3NyYy9tYWluL2phdmEvZGVtby9MaXN0TWVzc2FnZXNUYWcuamF2YQpAQCAtMCwwICsxLDExOCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgRGlzdHJpYnV0aW9uIExpY2Vuc2Ugdi4gMS4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvb3JnL2RvY3VtZW50cy9lZGwtdjEwLnBocC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQlNELTMtQ2xhdXNlCisgKi8KKworcGFja2FnZSBkZW1vOworCitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmEudXRpbC4qOworaW1wb3J0IGphdmF4Lm1haWwuKjsKK2ltcG9ydCBqYXZheC5tYWlsLmludGVybmV0Lio7CitpbXBvcnQgamF2YXgubWFpbC5zZWFyY2guKjsKK2ltcG9ydCBqYXZheC5zZXJ2bGV0LmpzcC4qOworaW1wb3J0IGphdmF4LnNlcnZsZXQuanNwLnRhZ2V4dC4qOworCisvKioKKyAqIEN1c3RvbSB0YWcgZm9yIGxpc3RpbmcgbWVzc2FnZXMuIFRoZSBzY3JpcHRpbmcgdmFyaWFibGUgaXMgb25seQorICogd2l0aGluIHRoZSBib2R5IG9mIHRoZSB0YWcuCisgKi8KK3B1YmxpYyBjbGFzcyBMaXN0TWVzc2FnZXNUYWcgZXh0ZW5kcyBCb2R5VGFnU3VwcG9ydCB7CisgICAgcHJpdmF0ZSBTdHJpbmcgZm9sZGVyOworICAgIHByaXZhdGUgU3RyaW5nIHNlc3Npb247CisgICAgcHJpdmF0ZSBpbnQgbXNnTnVtID0gMDsKKyAgICBwcml2YXRlIGludCBtZXNzYWdlQ291bnQgPSAwOworICAgIHByaXZhdGUgTWVzc2FnZSBtZXNzYWdlOworICAgIHByaXZhdGUgTWVzc2FnZVtdIG1lc3NhZ2VzOworICAgIHByaXZhdGUgTWVzc2FnZUluZm8gbWVzc2FnZWluZm87CisgICAgCisgICAgLyoqCisgICAgICogZm9sZGVyIGF0dHJpYnV0ZSBnZXR0ZXIgbWV0aG9kLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0Rm9sZGVyKCkgeworCXJldHVybiBmb2xkZXI7CisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIHNlc3Npb24gYXR0cmlidXRlIGdldHRlciBtZXRob2QuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRTZXNzaW9uKCkgeworCXJldHVybiBzZXNzaW9uOworICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiBmb2xkZXIgc2V0dGVyIG1ldGhvZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRGb2xkZXIoU3RyaW5nIGZvbGRlcikgeworCXRoaXMuZm9sZGVyID0gZm9sZGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIHNlc3Npb24gYXR0cmlidXRlIHNldHRlciBtZXRob2QuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U2Vzc2lvbihTdHJpbmcgc2Vzc2lvbikgeworCXRoaXMuc2Vzc2lvbiA9IHNlc3Npb247CisgICAgfQorCisgICAgLyoqCisgICAgICogTWV0aG9kIGZvciBwcm9jZXNzaW5nIHRoZSBzdGFydCBvZiB0aGUgdGFnLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZG9TdGFydFRhZygpIHRocm93cyBKc3BFeGNlcHRpb24geworCW1lc3NhZ2VpbmZvID0gbmV3IE1lc3NhZ2VJbmZvKCk7CisgICAgICAgCisJdHJ5IHsKKwkgICAgRm9sZGVyIGZvbGRlciA9IChGb2xkZXIpcGFnZUNvbnRleHQuZ2V0QXR0cmlidXRlKAorCQlnZXRGb2xkZXIoKSwgUGFnZUNvbnRleHQuU0VTU0lPTl9TQ09QRSk7CisJICAgIEZsYWdUZXJtIGZ0ID0gbmV3IEZsYWdUZXJtKG5ldyBGbGFncyhGbGFncy5GbGFnLkRFTEVURUQpLCBmYWxzZSk7CisJICAgIG1lc3NhZ2VzID0gZm9sZGVyLnNlYXJjaChmdCk7CisJICAgIG1lc3NhZ2VDb3VudCA9IG1lc3NhZ2VzLmxlbmd0aDsKKwkgICAgbXNnTnVtID0gMDsKKwl9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKwkgICAgdGhyb3cgbmV3IEpzcEV4Y2VwdGlvbihleC5nZXRNZXNzYWdlKCkpOworCX0KKworCWlmIChtZXNzYWdlQ291bnQgPiAwKSB7CisJICAgIGdldE1lc3NhZ2UoKTsKKwkgICAgcmV0dXJuIEJvZHlUYWcuRVZBTF9CT0RZX1RBRzsKKwl9IGVsc2UKKwkgICAgcmV0dXJuIEJvZHlUYWcuU0tJUF9CT0RZOworICAgIH0KKyAgIAorICAgIC8qKgorICAgICAqIE1ldGhvZCBmb3IgcHJvY2Vzc2luZyB0aGUgYm9keSBjb250ZW50IG9mIHRoZSB0YWcuCisgICAgICovCisgICAgcHVibGljIGludCBkb0FmdGVyQm9keSgpIHRocm93cyBKc3BFeGNlcHRpb24geworCQorCUJvZHlDb250ZW50IGJvZHkgPSBnZXRCb2R5Q29udGVudCgpOworCXRyeSB7CisJICAgIGJvZHkud3JpdGVPdXQoZ2V0UHJldmlvdXNPdXQoKSk7CisJfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworCSAgICB0aHJvdyBuZXcgSnNwVGFnRXhjZXB0aW9uKCJJdGVyYXRpb25UYWc6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisJfQorCQorCS8vIGNsZWFyIHVwIHNvIHRoZSBuZXh0IHRpbWUgdGhlIGJvZHkgY29udGVudCBpcyBlbXB0eQorCWJvZHkuY2xlYXJCb2R5KCk7CisgICAgICAgCisJaWYgKG1zZ051bSA8IG1lc3NhZ2VDb3VudCkgeworCSAgICBnZXRNZXNzYWdlKCk7CisJICAgIHJldHVybiBCb2R5VGFnLkVWQUxfQk9EWV9UQUc7CisJfSBlbHNlIHsKKwkgICAgcmV0dXJuIEJvZHlUYWcuU0tJUF9CT0RZOworCX0KKyAgICB9CisgICAgCisgICAgLyoqCisgICAgICogSGVscGVyIG1ldGhvZCBmb3IgcmV0cmlldmluZyBtZXNzYWdlcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgZ2V0TWVzc2FnZSgpIHRocm93cyBKc3BFeGNlcHRpb24geworCW1lc3NhZ2UgPSBtZXNzYWdlc1ttc2dOdW0rK107CisJbWVzc2FnZWluZm8uc2V0TWVzc2FnZShtZXNzYWdlKTsKKwlwYWdlQ29udGV4dC5zZXRBdHRyaWJ1dGUoZ2V0SWQoKSwgbWVzc2FnZWluZm8pOworICAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvdGFnbGliL3NyYy9tYWluL2phdmEvZGVtby9NZXNzYWdlSW5mby5qYXZhIGIvdGFnbGliL3NyYy9tYWluL2phdmEvZGVtby9NZXNzYWdlSW5mby5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNiNmM3YzMKLS0tIC9kZXYvbnVsbAorKysgYi90YWdsaWIvc3JjL21haW4vamF2YS9kZW1vL01lc3NhZ2VJbmZvLmphdmEKQEAgLTAsMCArMSwyNjMgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDEsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorICovCisKK3BhY2thZ2UgZGVtbzsKKworaW1wb3J0IGphdmEudGV4dC4qOworaW1wb3J0IGphdmEudXRpbC4qOworaW1wb3J0IGphdmF4Lm1haWwuKjsKK2ltcG9ydCBqYXZheC5tYWlsLmludGVybmV0Lio7CisKKy8qKgorICogVXNlZCB0byBzdG9yZSBtZXNzYWdlIGluZm9ybWF0aW9uLgorICovCitwdWJsaWMgY2xhc3MgTWVzc2FnZUluZm8geworICAgIHByaXZhdGUgTWVzc2FnZSBtZXNzYWdlOworICAgIAorICAgIAorICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGJjYyBmaWVsZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEJjYygpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXJldHVybiBmb3JtYXRBZGRyZXNzZXMoCisJICAgIG1lc3NhZ2UuZ2V0UmVjaXBpZW50cyhNZXNzYWdlLlJlY2lwaWVudFR5cGUuQkNDKSk7CisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGJvZHkgb2YgdGhlIG1lc3NhZ2UgKGlmIGl0J3MgcGxhaW4gdGV4dCkuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRCb2R5KCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiwgamF2YS5pby5JT0V4Y2VwdGlvbiB7CisJT2JqZWN0IGNvbnRlbnQgPSBtZXNzYWdlLmdldENvbnRlbnQoKTsKKwlpZiAobWVzc2FnZS5pc01pbWVUeXBlKCJ0ZXh0L3BsYWluIikpIHsKKwkgICAgcmV0dXJuIChTdHJpbmcpY29udGVudDsKKwl9IGVsc2UgaWYgKG1lc3NhZ2UuaXNNaW1lVHlwZSgibXVsdGlwYXJ0L2FsdGVybmF0aXZlIikpIHsKKwkgICAgTXVsdGlwYXJ0IG1wID0gKE11bHRpcGFydCltZXNzYWdlLmdldENvbnRlbnQoKTsKKwkgICAgaW50IG51bVBhcnRzID0gbXAuZ2V0Q291bnQoKTsKKwkgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1QYXJ0czsgKytpKSB7CisJCWlmIChtcC5nZXRCb2R5UGFydChpKS5pc01pbWVUeXBlKCJ0ZXh0L3BsYWluIikpCisJCSAgICByZXR1cm4gKFN0cmluZyltcC5nZXRCb2R5UGFydChpKS5nZXRDb250ZW50KCk7CisJICAgIH0KKwkgICAgcmV0dXJuICIiOyAgIAorCX0gZWxzZSBpZiAobWVzc2FnZS5pc01pbWVUeXBlKCJtdWx0aXBhcnQvKiIpKSB7IAorCSAgICBNdWx0aXBhcnQgbXAgPSAoTXVsdGlwYXJ0KWNvbnRlbnQ7CisJICAgIGlmIChtcC5nZXRCb2R5UGFydCgwKS5pc01pbWVUeXBlKCJ0ZXh0L3BsYWluIikpCisJCXJldHVybiAoU3RyaW5nKW1wLmdldEJvZHlQYXJ0KDApLmdldENvbnRlbnQoKTsKKwkgICAgZWxzZQorCQlyZXR1cm4gIiI7CisJfSBlbHNlCisJICAgIHJldHVybiAiIjsKKyAgICB9CisgICAgCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgY2MgZmllbGQuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRDYygpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXJldHVybiBmb3JtYXRBZGRyZXNzZXMoCisJICAgIG1lc3NhZ2UuZ2V0UmVjaXBpZW50cyhNZXNzYWdlLlJlY2lwaWVudFR5cGUuQ0MpKTsKKyAgICB9CisgICAgCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgZGF0ZSB0aGUgbWVzc2FnZSB3YXMgc2VudCAob3IgcmVjZWl2ZWQgaWYgdGhlIHNlbnQgZGF0ZQorICAgICAqIGlzIG51bGwuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXREYXRlKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJRGF0ZSBkYXRlOworCVNpbXBsZURhdGVGb3JtYXQgZGYgPSBuZXcgU2ltcGxlRGF0ZUZvcm1hdCgiRUUgTS9kL3l5Iik7CisJaWYgKChkYXRlID0gbWVzc2FnZS5nZXRTZW50RGF0ZSgpKSAhPSBudWxsKQorCSAgICByZXR1cm4gKGRmLmZvcm1hdChkYXRlKSk7CisJZWxzZSBpZiAoKGRhdGUgPSBtZXNzYWdlLmdldFJlY2VpdmVkRGF0ZSgpKSAhPSBudWxsKQorCSAgICByZXR1cm4gKGRmLmZvcm1hdChkYXRlKSk7CisJZWxzZQorCSAgICByZXR1cm4gIiI7CisgICAgIH0KKyAgICAgICAKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBmcm9tIGZpZWxkLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0RnJvbSgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXJldHVybiBmb3JtYXRBZGRyZXNzZXMobWVzc2FnZS5nZXRGcm9tKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIGFkZHJlc3MgdG8gcmVwbHkgdG8uCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRSZXBseVRvKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJQWRkcmVzc1tdIGEgPSBtZXNzYWdlLmdldFJlcGx5VG8oKTsKKwlpZiAoYS5sZW5ndGggPiAwKQorCSAgICByZXR1cm4gKChJbnRlcm5ldEFkZHJlc3MpYVswXSkuZ2V0QWRkcmVzcygpOworCWVsc2UKKwkgICAgcmV0dXJuICIiOworICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBqYXZheC5tYWlsLk1lc3NhZ2Ugb2JqZWN0LgorICAgICAqLworICAgIHB1YmxpYyBNZXNzYWdlIGdldE1lc3NhZ2UoKSB7CisJcmV0dXJuIG1lc3NhZ2U7CisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIG1lc3NhZ2UgbnVtYmVyLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TnVtKCkgeworCXJldHVybiAoSW50ZWdlci50b1N0cmluZyhtZXNzYWdlLmdldE1lc3NhZ2VOdW1iZXIoKSkpOworICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSByZWNlaXZlZCBkYXRlIGZpZWxkLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0UmVjZWl2ZWREYXRlKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKGhhc1JlY2VpdmVkRGF0ZSgpKQorCSAgICByZXR1cm4gKG1lc3NhZ2UuZ2V0UmVjZWl2ZWREYXRlKCkudG9TdHJpbmcoKSk7CisJZWxzZQorCSAgICByZXR1cm4gIiI7CisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHNlbnQgZGF0ZSBmaWVsZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFNlbnREYXRlKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJaWYgKGhhc1NlbnREYXRlKCkpCisJICAgIHJldHVybiAobWVzc2FnZS5nZXRTZW50RGF0ZSgpLnRvU3RyaW5nKCkpOyAKKwllbHNlCisJICAgIHJldHVybiAiIjsKKyAgICB9CisgICAgCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgc3ViamVjdCBmaWVsZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFN1YmplY3QoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlpZiAoaGFzU3ViamVjdCgpKQorCSAgICByZXR1cm4gbWVzc2FnZS5nZXRTdWJqZWN0KCk7CisJZWxzZQorCSAgICByZXR1cm4gIiI7CisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHRvIGZpZWxkLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0VG8oKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gZm9ybWF0QWRkcmVzc2VzKAorCSAgICBtZXNzYWdlLmdldFJlY2lwaWVudHMoTWVzc2FnZS5SZWNpcGllbnRUeXBlLlRPKSk7CisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIE1ldGhvZCBmb3IgY2hlY2tpbmcgaWYgdGhlIG1lc3NhZ2UgaGFzIGF0dGFjaG1lbnRzLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGhhc0F0dGFjaG1lbnRzKCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24sIAorCQkJCQkgICBNZXNzYWdpbmdFeGNlcHRpb24geworCWJvb2xlYW4gaGFzQXR0YWNobWVudHMgPSBmYWxzZTsKKwlpZiAobWVzc2FnZS5pc01pbWVUeXBlKCJtdWx0aXBhcnQvKiIpKSB7CisJICAgIE11bHRpcGFydCBtcCA9IChNdWx0aXBhcnQpbWVzc2FnZS5nZXRDb250ZW50KCk7CisJICAgIGlmIChtcC5nZXRDb3VudCgpID4gMSkKKwkJaGFzQXR0YWNobWVudHMgPSB0cnVlOworCX0KKwkgICAgCisJcmV0dXJuIGhhc0F0dGFjaG1lbnRzOworICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiBNZXRob2QgZm9yIGNoZWNraW5nIGlmIHRoZSBtZXNzYWdlIGhhcyBhIGJjYyBmaWVsZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNCY2MoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gKG1lc3NhZ2UuZ2V0UmVjaXBpZW50cyhNZXNzYWdlLlJlY2lwaWVudFR5cGUuQkNDKSAhPSBudWxsKTsKKyAgICB9CisgICAgCisgICAgLyoqCisgICAgICogTWV0aG9kIGZvciBjaGVja2luZyBpZiB0aGUgbWVzc2FnZSBoYXMgYSBjYyBmaWVsZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNDYygpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXJldHVybiAobWVzc2FnZS5nZXRSZWNpcGllbnRzKE1lc3NhZ2UuUmVjaXBpZW50VHlwZS5DQykgIT0gbnVsbCk7CisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIE1ldGhvZCBmb3IgY2hlY2tpbmcgaWYgdGhlIG1lc3NhZ2UgaGFzIGEgZGF0ZSBmaWVsZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBoYXNEYXRlKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJcmV0dXJuIChoYXNTZW50RGF0ZSgpIHx8IGhhc1JlY2VpdmVkRGF0ZSgpKTsKKyAgICB9CisgICAgCisgICAgLyoqCisgICAgICogTWV0aG9kIGZvciBjaGVja2luZyBpZiB0aGUgbWVzc2FnZSBoYXMgYSBmcm9tIGZpZWxkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGhhc0Zyb20oKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gKG1lc3NhZ2UuZ2V0RnJvbSgpICE9IG51bGwpOworICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiBNZXRob2QgZm9yIGNoZWNraW5nIGlmIHRoZSBtZXNzYWdlIGhhcyB0aGUgZGVzaXJlZCBtaW1lIHR5cGUuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaGFzTWltZVR5cGUoU3RyaW5nIG1pbWVUeXBlKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gbWVzc2FnZS5pc01pbWVUeXBlKG1pbWVUeXBlKTsKKyAgICB9CisgICAgCisgICAgLyoqCisgICAgICogTWV0aG9kIGZvciBjaGVja2luZyBpZiB0aGUgbWVzc2FnZSBoYXMgYSByZWNlaXZlZCBkYXRlIGZpZWxkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGhhc1JlY2VpdmVkRGF0ZSgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCXJldHVybiAobWVzc2FnZS5nZXRSZWNlaXZlZERhdGUoKSAhPSBudWxsKTsKKyAgICB9CisgICAgCisgICAgLyoqCisgICAgICogTWV0aG9kIGZvciBjaGVja2luZyBpZiB0aGUgbWVzc2FnZSBoYXMgYSBzZW50IGRhdGUgZmllbGQuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gaGFzU2VudERhdGUoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gKG1lc3NhZ2UuZ2V0U2VudERhdGUoKSAhPSBudWxsKTsKKyAgICB9CisgICAgCisgICAgLyoqCisgICAgICogTWV0aG9kIGZvciBjaGVja2luZyBpZiB0aGUgbWVzc2FnZSBoYXMgYSBzdWJqZWN0IGZpZWxkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGhhc1N1YmplY3QoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gKG1lc3NhZ2UuZ2V0U3ViamVjdCgpICE9IG51bGwpOworICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiBNZXRob2QgZm9yIGNoZWNraW5nIGlmIHRoZSBtZXNzYWdlIGhhcyBhIHRvIGZpZWxkLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGhhc1RvKCkgdGhyb3dzIE1lc3NhZ2luZ0V4Y2VwdGlvbiB7CisJcmV0dXJuIChtZXNzYWdlLmdldFJlY2lwaWVudHMoTWVzc2FnZS5SZWNpcGllbnRUeXBlLlRPKSAhPSBudWxsKTsKKyAgICB9CisgICAgCisgICAgLyoqCisgICAgICogTWV0aG9kIGZvciBtYXBwaW5nIGEgbWVzc2FnZSB0byB0aGlzIE1lc3NhZ2VJbmZvIGNsYXNzLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE1lc3NhZ2UoTWVzc2FnZSBtZXNzYWdlKSB7CisJdGhpcy5tZXNzYWdlID0gbWVzc2FnZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVdGlsaXR5IG1ldGhvZCBmb3IgZm9ybWF0dGluZyBtc2cgaGVhZGVyIGFkZHJlc3Nlcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyBmb3JtYXRBZGRyZXNzZXMoQWRkcmVzc1tdIGFkZHJzKSB7CisJaWYgKGFkZHJzID09IG51bGwpCisJICAgIHJldHVybiAiIjsKKwlTdHJpbmdCdWlsZGVyIHN0ckJ1ZiA9IG5ldyBTdHJpbmdCdWlsZGVyKGdldERpc3BsYXlBZGRyZXNzKGFkZHJzWzBdKSk7CisJZm9yIChpbnQgaSA9IDE7IGkgPCBhZGRycy5sZW5ndGg7IGkrKykgeworCSAgICBzdHJCdWYuYXBwZW5kKCIsICIpLmFwcGVuZChnZXREaXNwbGF5QWRkcmVzcyhhZGRyc1tpXSkpOworCX0KKwlyZXR1cm4gc3RyQnVmLnRvU3RyaW5nKCk7CisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIFV0aWxpdHkgbWV0aG9kIHdoaWNoIHJldHVybnMgYSBzdHJpbmcgc3VpdGFibGUgZm9yIG1zZyBoZWFkZXIgZGlzcGxheS4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyBnZXREaXNwbGF5QWRkcmVzcyhBZGRyZXNzIGEpIHsKKwlTdHJpbmcgcGVycyA9IG51bGw7CisJU3RyaW5nIGFkZHIgPSBudWxsOworCWlmIChhIGluc3RhbmNlb2YgSW50ZXJuZXRBZGRyZXNzICYmCisJICAgKChwZXJzID0gKChJbnRlcm5ldEFkZHJlc3MpYSkuZ2V0UGVyc29uYWwoKSkgIT0gbnVsbCkpIHsKKwkgICAgYWRkciA9IHBlcnMgKyAiICAiKyImbHQ7IisoKEludGVybmV0QWRkcmVzcylhKS5nZXRBZGRyZXNzKCkrIiZndDsiOworCX0gZWxzZSAKKwkgICAgYWRkciA9IGEudG9TdHJpbmcoKTsKKwlyZXR1cm4gYWRkcjsKKyAgICB9Cit9CisKZGlmZiAtLWdpdCBhL3RhZ2xpYi9zcmMvbWFpbi9qYXZhL2RlbW8vTWVzc2FnZVRFSS5qYXZhIGIvdGFnbGliL3NyYy9tYWluL2phdmEvZGVtby9NZXNzYWdlVEVJLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzgyOTg1MgotLS0gL2Rldi9udWxsCisrKyBiL3RhZ2xpYi9zcmMvbWFpbi9qYXZhL2RlbW8vTWVzc2FnZVRFSS5qYXZhCkBAIC0wLDAgKzEsMzQgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDEsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorICovCisKK3BhY2thZ2UgZGVtbzsKKworaW1wb3J0IGphdmF4LnNlcnZsZXQuanNwLio7CitpbXBvcnQgamF2YXguc2VydmxldC5qc3AudGFnZXh0Lio7CisKKy8qKgorICogRXh0cmEgaW5mb3JtYXRpb24gY2xhc3MgdG8gc3VwcG9ydCB0aGUgc2NyaXB0aW5nIHZhcmlhYmxlIGNyZWF0ZWQgYnkgdGhlCisgKiBNZXNzYWdlc1RhZyBjbGFzcy4gVGhlIHZhcmlhYmxlIGV4aXN0cyBvdXRzaWRlIG9mIHRoZSB0YWcuCisgKiAKKyAqLworcHVibGljIGNsYXNzIE1lc3NhZ2VURUkgZXh0ZW5kcyBUYWdFeHRyYUluZm8geworICAgIAorICAgIHB1YmxpYyBNZXNzYWdlVEVJKCkgeworCXN1cGVyKCk7CisgICAgfQorICAgIAorICAgIHB1YmxpYyBWYXJpYWJsZUluZm9bXSBnZXRWYXJpYWJsZUluZm8oVGFnRGF0YSBkYXRhKSB7CisJVmFyaWFibGVJbmZvIGluZm8gPSBuZXcgVmFyaWFibGVJbmZvKGRhdGEuZ2V0SWQoKSwiTWVzc2FnZUluZm8iLAorCSAgICB0cnVlLCBWYXJpYWJsZUluZm8uQVRfRU5EKTsKKwlWYXJpYWJsZUluZm9bXSB2YXJJbmZvID0geyBpbmZvIH07CisJcmV0dXJuIHZhckluZm87CisgICAgfQorfQorCmRpZmYgLS1naXQgYS90YWdsaWIvc3JjL21haW4vamF2YS9kZW1vL01lc3NhZ2VUYWcuamF2YSBiL3RhZ2xpYi9zcmMvbWFpbi9qYXZhL2RlbW8vTWVzc2FnZVRhZy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNjNTFkNzcKLS0tIC9kZXYvbnVsbAorKysgYi90YWdsaWIvc3JjL21haW4vamF2YS9kZW1vL01lc3NhZ2VUYWcuamF2YQpAQCAtMCwwICsxLDg3IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDAxLCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBEaXN0cmlidXRpb24gTGljZW5zZSB2LiAxLjAsIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9vcmcvZG9jdW1lbnRzL2VkbC12MTAucGhwLgorICoKKyAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBCU0QtMy1DbGF1c2UKKyAqLworCitwYWNrYWdlIGRlbW87CisKK2ltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBqYXZheC5tYWlsLio7CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC4qOworaW1wb3J0IGphdmF4LnNlcnZsZXQuanNwLio7CitpbXBvcnQgamF2YXguc2VydmxldC5qc3AudGFnZXh0Lio7CisKKy8qKgorICogQ3VzdG9tIHRhZyBmb3IgcmV0cmlldmluZyBhIG1lc3NhZ2UuCisgKi8KK3B1YmxpYyBjbGFzcyBNZXNzYWdlVGFnIGV4dGVuZHMgVGFnU3VwcG9ydCB7CisgICAgcHJpdmF0ZSBTdHJpbmcgZm9sZGVyOworICAgIHByaXZhdGUgU3RyaW5nIHNlc3Npb247CisgICAgcHJpdmF0ZSBpbnQgbnVtID0gMTsKKworICAgIC8qKgorICAgICAqIGZvbGRlciBhdHRyaWJ1dGUgc2V0dGVyIG1ldGhvZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEZvbGRlcigpIHsKKwlyZXR1cm4gZm9sZGVyOworICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiBudW0gYXR0cmlidXRlIGdldHRlciBtZXRob2QuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXROdW0oKSB7CisJcmV0dXJuIEludGVnZXIudG9TdHJpbmcobnVtKTsKKyAgICB9CisgICAgCisgICAgLyoqCisgICAgICogc2Vzc2lvbiBhdHRyaWJ1dGUgZ2V0dGVyIG1ldGhvZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFNlc3Npb24oKSB7CisJcmV0dXJuIHNlc3Npb247CisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIGZvbGRlciBzZXR0ZXIgbWV0aG9kLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEZvbGRlcihTdHJpbmcgZm9sZGVyKSB7CisJdGhpcy5mb2xkZXIgPSBmb2xkZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogbnVtIGF0dHJpYnV0ZSBzZXR0ZXIgbWV0aG9kLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE51bShTdHJpbmcgbnVtKSB7CisJdGhpcy5udW0gPSBJbnRlZ2VyLnBhcnNlSW50KG51bSk7CisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIHNlc3Npb24gYXR0cmlidXRlIHNldHRlciBtZXRob2QuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U2Vzc2lvbihTdHJpbmcgc2Vzc2lvbikgeworCXRoaXMuc2Vzc2lvbiA9IHNlc3Npb247CisgICAgfQorCisgICAgLyoqCisgICAgICogTWV0aG9kIGZvciBwcm9jZXNzaW5nIHRoZSBzdGFydCBvZiB0aGUgdGFnLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZG9TdGFydFRhZygpIHRocm93cyBKc3BFeGNlcHRpb24geworCU1lc3NhZ2VJbmZvIG1lc3NhZ2VpbmZvID0gbmV3IE1lc3NhZ2VJbmZvKCk7CisJdHJ5IHsKKwkgICAgRm9sZGVyIGYgPSAoRm9sZGVyKXBhZ2VDb250ZXh0LmdldEF0dHJpYnV0ZSgKKwkJZ2V0Rm9sZGVyKCksIFBhZ2VDb250ZXh0LlNFU1NJT05fU0NPUEUpOworCSAgICBNZXNzYWdlIG1lc3NhZ2UgPSBmLmdldE1lc3NhZ2UobnVtKTsKKwkgICAgbWVzc2FnZWluZm8uc2V0TWVzc2FnZShtZXNzYWdlKTsKKwkgICAgcGFnZUNvbnRleHQuc2V0QXR0cmlidXRlKGdldElkKCksIG1lc3NhZ2VpbmZvKTsKKwl9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKwkgICAgdGhyb3cgbmV3IEpzcEV4Y2VwdGlvbihleC5nZXRNZXNzYWdlKCkpOworCX0KKyAKKwlyZXR1cm4gU0tJUF9CT0RZOworICAgfQorfQorCmRpZmYgLS1naXQgYS90YWdsaWIvc3JjL21haW4vamF2YS9kZW1vL1NlbmRUYWcuamF2YSBiL3RhZ2xpYi9zcmMvbWFpbi9qYXZhL2RlbW8vU2VuZFRhZy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI5ZTg2NjkKLS0tIC9kZXYvbnVsbAorKysgYi90YWdsaWIvc3JjL21haW4vamF2YS9kZW1vL1NlbmRUYWcuamF2YQpAQCAtMCwwICsxLDEyMCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgRGlzdHJpYnV0aW9uIExpY2Vuc2Ugdi4gMS4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvb3JnL2RvY3VtZW50cy9lZGwtdjEwLnBocC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQlNELTMtQ2xhdXNlCisgKi8KKworcGFja2FnZSBkZW1vOworCitpbXBvcnQgamF2YS51dGlsLio7CitpbXBvcnQgamF2YS5uZXQuKjsKK2ltcG9ydCBqYXZheC5tYWlsLio7CitpbXBvcnQgamF2YXgubWFpbC5pbnRlcm5ldC4qOworaW1wb3J0IGphdmF4LnNlcnZsZXQuanNwLio7CitpbXBvcnQgamF2YXguc2VydmxldC5qc3AudGFnZXh0Lio7CisKKy8qKgorICogQ3VzdG9tIHRhZyBmb3Igc2VuZGluZyBtZXNzYWdlcy4KKyAqLworcHVibGljIGNsYXNzIFNlbmRUYWcgZXh0ZW5kcyBCb2R5VGFnU3VwcG9ydCB7CisgICAgcHJpdmF0ZSBTdHJpbmcgYm9keTsKKyAgICBwcml2YXRlIFN0cmluZyBjYzsKKyAgICBwcml2YXRlIFN0cmluZyBob3N0OworICAgIHByaXZhdGUgU3RyaW5nIHJlY2lwaWVudHM7CisgICAgcHJpdmF0ZSBTdHJpbmcgc2VuZGVyOworICAgIHByaXZhdGUgU3RyaW5nIHN1YmplY3Q7CisKKyAgICAvKioKKyAgICAgKiBob3N0IGF0dHJpYnV0ZSBzZXR0ZXIgbWV0aG9kLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEhvc3QoU3RyaW5nIGhvc3QpIHsKKwl0aGlzLmhvc3QgPSBob3N0OworICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiByZWNpcGllbnQgYXR0cmlidXRlIHNldHRlciBtZXRob2QuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0UmVjaXBpZW50cyhTdHJpbmcgcmVjaXBpZW50cykgeworCXRoaXMucmVjaXBpZW50cyA9IHJlY2lwaWVudHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogc2VuZGVyIGF0dHJpYnV0ZSBzZXR0ZXIgbWV0aG9kLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFNlbmRlcihTdHJpbmcgc2VuZGVyKSB7CisJdGhpcy5zZW5kZXIgPSBzZW5kZXI7CisgICAgfQorCisgICAgLyoqCisgICAgICogY2MgYXR0cmlidXRlIHNldHRlciBtZXRob2QuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q2MoU3RyaW5nIGNjKSB7CisJdGhpcy5jYyA9IGNjOworICAgIH0KKworICAgIC8qKgorICAgICAqIHN1YmplY3QgYXR0cmlidXRlIHNldHRlciBtZXRob2QuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U3ViamVjdChTdHJpbmcgc3ViamVjdCkgeworCXRoaXMuc3ViamVjdCA9IHN1YmplY3Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogTWV0aG9kIGZvciBwcm9jZXNzaW5nIHRoZSBlbmQgb2YgdGhlIHRhZy4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGRvRW5kVGFnKCkgdGhyb3dzIEpzcEV4Y2VwdGlvbiB7CisJUHJvcGVydGllcyBwcm9wcyA9IFN5c3RlbS5nZXRQcm9wZXJ0aWVzKCk7CisJCisJdHJ5IHsKKwkgICAgaWYgKGhvc3QgIT0gbnVsbCkKKwkJcHJvcHMucHV0KCJtYWlsLnNtdHAuaG9zdCIsIGhvc3QpOworCSAgICBlbHNlIGlmIChwcm9wcy5nZXRQcm9wZXJ0eSgibWFpbC5zbXRwLmhvc3QiKSA9PSBudWxsKQorCQlwcm9wcy5wdXQoIm1haWwuc210cC5ob3N0IiwgSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCkuCisJCSAgICBnZXRIb3N0TmFtZSgpKTsKKwl9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKwkgICAgdGhyb3cgbmV3IEpzcEV4Y2VwdGlvbihleC5nZXRNZXNzYWdlKCkpOworCX0KKwlTZXNzaW9uIHNlc3Npb24gPSBTZXNzaW9uLmdldERlZmF1bHRJbnN0YW5jZShwcm9wcywgbnVsbCk7CisJCQorCU1lc3NhZ2UgbXNnID0gbmV3IE1pbWVNZXNzYWdlKHNlc3Npb24pOworCUludGVybmV0QWRkcmVzc1tdIHRvQWRkcnMgPSBudWxsLCBjY0FkZHJzID0gbnVsbDsKKworCXRyeSB7CisJICAgIGlmIChyZWNpcGllbnRzICE9IG51bGwpIHsKKwkJdG9BZGRycyA9IEludGVybmV0QWRkcmVzcy5wYXJzZShyZWNpcGllbnRzLCBmYWxzZSk7CisJCW1zZy5zZXRSZWNpcGllbnRzKE1lc3NhZ2UuUmVjaXBpZW50VHlwZS5UTywgdG9BZGRycyk7CisJICAgIH0gZWxzZQorCQl0aHJvdyBuZXcgSnNwRXhjZXB0aW9uKCJObyByZWNpcGllbnQgYWRkcmVzcyBzcGVjaWZpZWQiKTsKKworCSAgICBpZiAoc2VuZGVyICE9IG51bGwpCisJCW1zZy5zZXRGcm9tKG5ldyBJbnRlcm5ldEFkZHJlc3Moc2VuZGVyKSk7CisJICAgIGVsc2UKKwkJdGhyb3cgbmV3IEpzcEV4Y2VwdGlvbigiTm8gc2VuZGVyIGFkZHJlc3Mgc3BlY2lmaWVkIik7CisKKwkgICAgaWYgKGNjICE9IG51bGwpIHsKKwkJY2NBZGRycyA9IEludGVybmV0QWRkcmVzcy5wYXJzZShjYywgZmFsc2UpOworCQltc2cuc2V0UmVjaXBpZW50cyhNZXNzYWdlLlJlY2lwaWVudFR5cGUuQ0MsIGNjQWRkcnMpOworCSAgICB9CisKKwkgICAgaWYgKHN1YmplY3QgIT0gbnVsbCkKKwkJbXNnLnNldFN1YmplY3Qoc3ViamVjdCk7CisKKwkgICAgaWYgKChib2R5ID0gZ2V0Qm9keUNvbnRlbnQoKS5nZXRTdHJpbmcoKSkgIT0gbnVsbCkKKwkJbXNnLnNldFRleHQoYm9keSk7CisJICAgIGVsc2UKKwkJbXNnLnNldFRleHQoIiIpOworCisJICAgIFRyYW5zcG9ydC5zZW5kKG1zZyk7CisJCisJfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisJICAgIHRocm93IG5ldyBKc3BFeGNlcHRpb24oZXguZ2V0TWVzc2FnZSgpKTsKKwl9CisKKwlyZXR1cm4oRVZBTF9QQUdFKTsKKyAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvdGFnbGliL3NyYy9tYWluL3Jlc291cmNlcy9NRVRBLUlORi90YWdsaWIudGxkIGIvdGFnbGliL3NyYy9tYWluL3Jlc291cmNlcy9NRVRBLUlORi90YWdsaWIudGxkCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIzYzJiOGMKLS0tIC9kZXYvbnVsbAorKysgYi90YWdsaWIvc3JjL21haW4vcmVzb3VyY2VzL01FVEEtSU5GL3RhZ2xpYi50bGQKQEAgLTAsMCArMSwxMjcgQEAKKzw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IklTTy04ODU5LTEiID8+Cis8IURPQ1RZUEUgdGFnbGliIFBVQkxJQyAiLS8vU3VuIE1pY3Jvc3lzdGVtcywgSW5jLi8vRFREIEpTUCBUYWcgTGlicmFyeSAxLjEvL0VOIiAiaHR0cDovL2phdmEuc3VuLmNvbS9qMmVlL2R0ZHMvd2ViLWpzcHRhZ2xpYnJhcnlfMV8xLmR0ZCI+Cis8IS0tCisKKyAgICBDb3B5cmlnaHQgKGMpIDIwMTAsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKworICAgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICAgIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLgorCisgICAgVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorICAgIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKKyAgICBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCBhcmUgc2F0aXNmaWVkOiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwKKyAgICB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorICAgIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KKworICAgIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorCistLT4KKworPHRhZ2xpYj4KKyAgPHRsaWJ2ZXJzaW9uPjEuMDwvdGxpYnZlcnNpb24+CisgIDxqc3B2ZXJzaW9uPjEuMTwvanNwdmVyc2lvbj4KKyAgPHNob3J0bmFtZT5qYXZhbWFpbDwvc2hvcnRuYW1lPgorICA8dXJpPmh0dHA6Ly9qYXZhLnN1bi5jb20vcHJvZHVjdHMvamF2YW1haWwvZGVtby93ZWJhcHA8L3VyaT4KKyAgPHRhZz4KKyAgICA8bmFtZT5saXN0YXR0YWNobWVudHM8L25hbWU+CisgICAgPHRhZ2NsYXNzPmRlbW8uTGlzdEF0dGFjaG1lbnRzVGFnPC90YWdjbGFzcz4KKyAgICA8dGVpY2xhc3M+ZGVtby5MaXN0QXR0YWNobWVudHNURUk8L3RlaWNsYXNzPgorICAgIDxib2R5Y29udGVudD5KU1A8L2JvZHljb250ZW50PgorICAgIDxpbmZvPgorICAgICAgICBBIGxpc3RhdHRhY2htZW50cyB0YWcKKyAgICA8L2luZm8+CisgICAgPGF0dHJpYnV0ZT4KKyAgICAgIDxuYW1lPmlkPC9uYW1lPgorICAgICAgPHJlcXVpcmVkPnRydWU8L3JlcXVpcmVkPgorICAgICAgPHJ0ZXhwcnZhbHVlPnRydWU8L3J0ZXhwcnZhbHVlPgorICAgIDwvYXR0cmlidXRlPgorICAgIDxhdHRyaWJ1dGU+CisgICAgICA8bmFtZT5tZXNzYWdlaW5mbzwvbmFtZT4KKyAgICAgIDxyZXF1aXJlZD50cnVlPC9yZXF1aXJlZD4KKyAgICAgIDxydGV4cHJ2YWx1ZT50cnVlPC9ydGV4cHJ2YWx1ZT4KKyAgICA8L2F0dHJpYnV0ZT4KKyAgPC90YWc+CisgIDx0YWc+CisgICAgPG5hbWU+bGlzdG1lc3NhZ2VzPC9uYW1lPgorICAgIDx0YWdjbGFzcz5kZW1vLkxpc3RNZXNzYWdlc1RhZzwvdGFnY2xhc3M+CisgICAgPHRlaWNsYXNzPmRlbW8uTGlzdE1lc3NhZ2VzVEVJPC90ZWljbGFzcz4KKyAgICA8Ym9keWNvbnRlbnQ+SlNQPC9ib2R5Y29udGVudD4KKyAgICA8aW5mbz4KKyAgICAgICAgQSBsaXN0bWVzc2FnZXMgdGFnCisgICAgPC9pbmZvPgorICAgIDxhdHRyaWJ1dGU+CisgICAgICA8bmFtZT5pZDwvbmFtZT4KKyAgICAgIDxyZXF1aXJlZD50cnVlPC9yZXF1aXJlZD4KKyAgICAgIDxydGV4cHJ2YWx1ZT50cnVlPC9ydGV4cHJ2YWx1ZT4KKyAgICA8L2F0dHJpYnV0ZT4KKyAgICA8YXR0cmlidXRlPgorICAgICAgPG5hbWU+Zm9sZGVyPC9uYW1lPgorICAgICAgPHJlcXVpcmVkPmZhbHNlPC9yZXF1aXJlZD4KKyAgICAgIDxydGV4cHJ2YWx1ZT50cnVlPC9ydGV4cHJ2YWx1ZT4KKyAgICA8L2F0dHJpYnV0ZT4KKyAgICA8YXR0cmlidXRlPgorICAgICAgPG5hbWU+c2Vzc2lvbjwvbmFtZT4KKyAgICAgIDxyZXF1aXJlZD5mYWxzZTwvcmVxdWlyZWQ+CisgICAgICA8cnRleHBydmFsdWU+dHJ1ZTwvcnRleHBydmFsdWU+CisgICAgPC9hdHRyaWJ1dGU+CisgIDwvdGFnPgorICA8dGFnPgorICAgIDxuYW1lPm1lc3NhZ2U8L25hbWU+CisgICAgPHRhZ2NsYXNzPmRlbW8uTWVzc2FnZVRhZzwvdGFnY2xhc3M+CisgICAgPHRlaWNsYXNzPmRlbW8uTWVzc2FnZVRFSTwvdGVpY2xhc3M+CisgICAgPGJvZHljb250ZW50PmVtcHR5PC9ib2R5Y29udGVudD4KKyAgICA8aW5mbz4KKyAgICAgICAgQSBtZXNzYWdlIHRhZworICAgIDwvaW5mbz4KKyAgICA8YXR0cmlidXRlPgorICAgICAgPG5hbWU+aWQ8L25hbWU+CisgICAgICA8cmVxdWlyZWQ+dHJ1ZTwvcmVxdWlyZWQ+CisgICAgICA8cnRleHBydmFsdWU+dHJ1ZTwvcnRleHBydmFsdWU+CisgICAgPC9hdHRyaWJ1dGU+CisgICAgPGF0dHJpYnV0ZT4KKyAgICAgIDxuYW1lPmZvbGRlcjwvbmFtZT4KKyAgICAgIDxyZXF1aXJlZD5mYWxzZTwvcmVxdWlyZWQ+CisgICAgICA8cnRleHBydmFsdWU+dHJ1ZTwvcnRleHBydmFsdWU+CisgICAgPC9hdHRyaWJ1dGU+CisgICAgPGF0dHJpYnV0ZT4KKyAgICAgIDxuYW1lPnNlc3Npb248L25hbWU+CisgICAgICA8cmVxdWlyZWQ+ZmFsc2U8L3JlcXVpcmVkPgorICAgICAgPHJ0ZXhwcnZhbHVlPnRydWU8L3J0ZXhwcnZhbHVlPgorICAgIDwvYXR0cmlidXRlPgorICAgIDxhdHRyaWJ1dGU+CisgICAgICA8bmFtZT5udW08L25hbWU+CisgICAgICA8cmVxdWlyZWQ+dHJ1ZTwvcmVxdWlyZWQ+CisgICAgICA8cnRleHBydmFsdWU+dHJ1ZTwvcnRleHBydmFsdWU+CisgICAgPC9hdHRyaWJ1dGU+CisgIDwvdGFnPgorICA8dGFnPgorICAgIDxuYW1lPnNlbmRtYWlsPC9uYW1lPgorICAgIDx0YWdjbGFzcz5kZW1vLlNlbmRUYWc8L3RhZ2NsYXNzPgorICAgIDxib2R5Y29udGVudD5KU1A8L2JvZHljb250ZW50PgorICAgIDxpbmZvPgorICAgICAgICBBIHNlbmRtYWlsIHRhZworICAgIDwvaW5mbz4KKyAgICA8YXR0cmlidXRlPgorICAgICAgPG5hbWU+aG9zdDwvbmFtZT4KKyAgICAgIDxyZXF1aXJlZD5mYWxzZTwvcmVxdWlyZWQ+CisgICAgICA8cnRleHBydmFsdWU+dHJ1ZTwvcnRleHBydmFsdWU+CisgICAgPC9hdHRyaWJ1dGU+CisgICAgPGF0dHJpYnV0ZT4KKyAgICAgIDxuYW1lPnJlY2lwaWVudHM8L25hbWU+CisgICAgICA8cmVxdWlyZWQ+dHJ1ZTwvcmVxdWlyZWQ+CisgICAgICA8cnRleHBydmFsdWU+dHJ1ZTwvcnRleHBydmFsdWU+CisgICAgPC9hdHRyaWJ1dGU+CisgICAgPGF0dHJpYnV0ZT4KKyAgICAgIDxuYW1lPnNlbmRlcjwvbmFtZT4KKyAgICAgIDxyZXF1aXJlZD50cnVlPC9yZXF1aXJlZD4KKyAgICAgIDxydGV4cHJ2YWx1ZT50cnVlPC9ydGV4cHJ2YWx1ZT4KKyAgICA8L2F0dHJpYnV0ZT4KKyAgICA8YXR0cmlidXRlPgorICAgICAgPG5hbWU+c3ViamVjdDwvbmFtZT4KKyAgICAgIDxyZXF1aXJlZD5mYWxzZTwvcmVxdWlyZWQ+CisgICAgICA8cnRleHBydmFsdWU+dHJ1ZTwvcnRleHBydmFsdWU+CisgICAgPC9hdHRyaWJ1dGU+CisgIDwvdGFnPgorPC90YWdsaWI+CisKZGlmZiAtLWdpdCBhL3VwZGF0ZV92ZXJzaW9uIGIvdXBkYXRlX3ZlcnNpb24KbmV3IGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMDAwMDAwMC4uMjg4MjhmZQotLS0gL2Rldi9udWxsCisrKyBiL3VwZGF0ZV92ZXJzaW9uCkBAIC0wLDAgKzEsNDYgQEAKKyMhL2Jpbi9zaAorIworIyBDb3B5cmlnaHQgKGMpIDIwMTAsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyMKKyMgVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisjIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisjIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KKyMKKyMgVGhpcyBTb3VyY2UgQ29kZSBtYXkgYWxzbyBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgZm9sbG93aW5nIFNlY29uZGFyeQorIyBMaWNlbnNlcyB3aGVuIHRoZSBjb25kaXRpb25zIGZvciBzdWNoIGF2YWlsYWJpbGl0eSBzZXQgZm9ydGggaW4gdGhlCisjIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorIyB2ZXJzaW9uIDIgd2l0aCB0aGUgR05VIENsYXNzcGF0aCBFeGNlcHRpb24sIHdoaWNoIGlzIGF2YWlsYWJsZSBhdAorIyBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2NsYXNzcGF0aC9saWNlbnNlLmh0bWwuCisjCisjIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wIE9SIEdQTC0yLjAgV0lUSCBDbGFzc3BhdGgtZXhjZXB0aW9uLTIuMAorIworCisjCisjIHVwZGF0ZSB2ZXJzaW9uIG51bWJlciBpbiBwb20gZmlsZXMsIGUuZy4sIHRvIGNoYW5nZSB0byByZWxlYXNlCisjIHZlcnNpb24gbnVtYmVyIGluIHByZXBhcmF0aW9uIGZvciByZWxlYXNlLCBvciB0byBjaGFuZ2UgYmFjayB0bworIyBzbmFwc2hvdCB2ZXJzaW9uIG51bWJlciBhZnRlciByZWxlYXNlLgorIworIyBVc2FnZToJdXBkYXRlX3ZlcnNpb24gbmV3LXZlcnNpb24KKyMKK25ldz0kMQorIyBmaW5kIHRoZSBzZWNvbmQgdmVyc2lvbiBzdHJpbmcgaW4gcG9tLnhtbCwgd2hpY2ggaXMgdGhlIG9sZCB2ZXJzaW9uCisjIHRoaXMgaXMgYWxtb3N0IHRoZSBzYW1lIGFzICJtdm4gdmVyc2lvbnM6c2V0IC1EbmV3VmVyc2lvbj0kMSIKKyMgZXhjZXB0IHRoYXQgbWlzc2VzIG1ib3gvbmF0aXZlL3BvbS54bWwgYW5kIG9sZG1haWwvcG9tLnhtbAorb2xkPWBncmVwICc8dmVyc2lvbj4uKjwvdmVyc2lvbj4nIHBvbS54bWwgfCBzZWQgLW4gMnAgfCBcCisJc2VkIC1lICdzOi4qPHZlcnNpb24+XCguKlwpPC92ZXJzaW9uPi4qOlwxOidgCitmb3IgZmlsZSBpbiBgZmluZCAuIC1uYW1lICdwb20ueG1sJyBgCitkbworCWVkIC0gIiRmaWxlIiA8PC1FT0YKKwlnOjx2ZXJzaW9uPiRvbGQ8L3ZlcnNpb24+OnM6Ojx2ZXJzaW9uPiRuZXc8L3ZlcnNpb24+OgorCXcKKwlxCisJRU9GCitkb25lCit6aXBvbGQ9YGVjaG8gIiRvbGQiIHwgc2VkIC1lICdzL1xcLi9fL2cnYAoremlwbmV3PWBlY2hvICIkbmV3IiB8IHNlZCAtZSAncy9cXC4vXy9nJ2AKK2VkIC0gcG9tLnhtbCA8PC1FT0YKK2c6PG1haWwudmVyc2lvbj4kb2xkPC9tYWlsLnZlcnNpb24+OnM6OjxtYWlsLnZlcnNpb24+JG5ldzwvbWFpbC52ZXJzaW9uPjoKK2c6PG1haWwuemlwdmVyc2lvbj4kemlwb2xkPC9tYWlsLnppcHZlcnNpb24+OnM6OjxtYWlsLnppcHZlcnNpb24+JHppcG5ldzwvbWFpbC56aXB2ZXJzaW9uPjoKK3cKK3EKK0VPRgpkaWZmIC0tZ2l0IGEvd2ViYXBwL2J1aWxkLmJhdCBiL3dlYmFwcC9idWlsZC5iYXQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTE4NzE2YwotLS0gL2Rldi9udWxsCisrKyBiL3dlYmFwcC9idWlsZC5iYXQKQEAgLTAsMCArMSw0MiBAQAorQGVjaG8gb2ZmCitSRU0KK1JFTSAgQ29weXJpZ2h0IChjKSAxOTk3LCAyMDE4IE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCitSRU0KK1JFTSAgVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCitSRU0gIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYuIDIuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CitSRU0gIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KK1JFTQorUkVNICBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CitSRU0gIExpY2Vuc2VzIHdoZW4gdGhlIGNvbmRpdGlvbnMgZm9yIHN1Y2ggYXZhaWxhYmlsaXR5IHNldCBmb3J0aCBpbiB0aGUKK1JFTSAgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2LiAyLjAgYXJlIHNhdGlzZmllZDogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsCitSRU0gIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CitSRU0gIGh0dHBzOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvY2xhc3NwYXRoL2xpY2Vuc2UuaHRtbC4KK1JFTQorUkVNICBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMCBPUiBHUEwtMi4wIFdJVEggQ2xhc3NwYXRoLWV4Y2VwdGlvbi0yLjAKK1JFTQorbWtkaXIgc3JjXGRvY3Jvb3RcV0VCLUlORlxjbGFzc2VzCitta2RpciBzcmNcZG9jcm9vdFxXRUItSU5GXGNsYXNzZXNcZGVtbworbWtkaXIgc3JjXGRvY3Jvb3RcV0VCLUlORlxsaWIKK2NkIHNyY1xjbGFzc2VzCitlY2hvIGNvbXBpbGluZyBjbGFzc2VzIGRpcmVjdG9yeQoramF2YWMgLWQgLi5cZG9jcm9vdFxXRUItSU5GXGNsYXNzZXMgZGVtb1wqLmphdmEKK2NkIC4uXHRhZ2xpYgorZWNobyBjb21waWxpbmcgbGliIGRpcmVjdG9yeQoramF2YWMgLWNsYXNzcGF0aCAiLi5cZG9jcm9vdFxXRUItSU5GXGNsYXNzZXM7JUNMQVNTUEFUSCUiIGRlbW9cKi5qYXZhCitlY2hvIGNyZWF0aW5nIHRhZyBsaWJyYXJ5IGFyY2hpdmUKK2phciBjdmYgLi5cZG9jcm9vdFxXRUItSU5GXGxpYlx0YWdsaWIuamFyIE1FVEEtSU5GIGRlbW9cKi5jbGFzcworZGVsIGRlbW9cKi5jbGFzcworY2QgLi5cZG9jcm9vdAorZWNobyBjcmVhdGluZyB3ZWIgYXJjaGl2ZQoramFyIGN2ZiAuLlwuLlxqYXZhbWFpbC53YXIgaW5kZXguaHRtbCAqLmpzcCBXRUItSU5GCitjZCBXRUItSU5GXGNsYXNzZXNcZGVtbworZGVsICouKgorY2QgLi4KK3JtZGlyIGRlbW8KK2NkIC4uCitybWRpciBjbGFzc2VzCitjZCBsaWIKK2RlbCAqLioKK2NkIC4uCitybWRpciBsaWIKK2NkIC4uXC4uXC4uCmRpZmYgLS1naXQgYS93ZWJhcHAvYnVpbGQuc2ggYi93ZWJhcHAvYnVpbGQuc2gKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTQ2OGI3NgotLS0gL2Rldi9udWxsCisrKyBiL3dlYmFwcC9idWlsZC5zaApAQCAtMCwwICsxLDI3IEBACisjCisjIENvcHlyaWdodCAoYykgMjAxMCwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorIworIyBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyMgdGVybXMgb2YgdGhlIEVjbGlwc2UgRGlzdHJpYnV0aW9uIExpY2Vuc2Ugdi4gMS4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyMgaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9vcmcvZG9jdW1lbnRzL2VkbC12MTAucGhwLgorIworIyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQlNELTMtQ2xhdXNlCisjCisKK21rZGlyIHNyYy9kb2Nyb290L1dFQi1JTkYvY2xhc3NlcworbWtkaXIgc3JjL2RvY3Jvb3QvV0VCLUlORi9saWIKK2NkIHNyYy9jbGFzc2VzCitlY2hvICJjb21waWxpbmcgY2xhc3NlcyBkaXJlY3RvcnkiCitqYXZhYyAtZCAuLi9kb2Nyb290L1dFQi1JTkYvY2xhc3NlcyBkZW1vLyouamF2YQorY2QgLi4vdGFnbGliCitlY2hvICJjb21waWxpbmcgbGliIGRpcmVjdHJveSIKK2phdmFjIC1jbGFzc3BhdGggLi4vZG9jcm9vdC9XRUItSU5GL2NsYXNzZXM6JENMQVNTUEFUSCBkZW1vLyouamF2YQorZWNobyAiY3JlYXRpbmcgdGFnIGxpYnJhcnkgYXJjaGl2ZSIKK2phciBjdmYgLi4vZG9jcm9vdC9XRUItSU5GL2xpYi90YWdsaWIuamFyIE1FVEEtSU5GIGRlbW8vKi5jbGFzcworcm0gZGVtby8qLmNsYXNzCitjZCAuLi9kb2Nyb290CitlY2hvICJjcmVhdGluZyB3ZWIgYXJjaGl2ZSIKK2phciBjdmYgLi4vLi4vamF2YW1haWwud2FyIGluZGV4Lmh0bWwgKi5qc3AgV0VCLUlORgorcm0gLXIgV0VCLUlORi9jbGFzc2VzCitybSAtciBXRUItSU5GL2xpYgorY2QgLi4vLi4KZGlmZiAtLWdpdCBhL3dlYmFwcC9wb20ueG1sIGIvd2ViYXBwL3BvbS54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzE1NmVkNwotLS0gL2Rldi9udWxsCisrKyBiL3dlYmFwcC9wb20ueG1sCkBAIC0wLDAgKzEsNjkgQEAKKzw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9Imlzby04ODU5LTEiPz4KKzwhLS0KKworICAgIENvcHlyaWdodCAoYykgMTk5NywgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorCisgICAgVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgICAgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAuCisKKyAgICBUaGlzIFNvdXJjZSBDb2RlIG1heSBhbHNvIGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBmb2xsb3dpbmcgU2Vjb25kYXJ5CisgICAgTGljZW5zZXMgd2hlbiB0aGUgY29uZGl0aW9ucyBmb3Igc3VjaCBhdmFpbGFiaWxpdHkgc2V0IGZvcnRoIGluIHRoZQorICAgIEVjbGlwc2UgUHVibGljIExpY2Vuc2Ugdi4gMi4wIGFyZSBzYXRpc2ZpZWQ6IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLAorICAgIHZlcnNpb24gMiB3aXRoIHRoZSBHTlUgQ2xhc3NwYXRoIEV4Y2VwdGlvbiwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cHM6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9jbGFzc3BhdGgvbGljZW5zZS5odG1sLgorCisgICAgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAgT1IgR1BMLTIuMCBXSVRIIENsYXNzcGF0aC1leGNlcHRpb24tMi4wCisKKy0tPgorCis8cHJvamVjdCB4bWxucz0iaHR0cDovL21hdmVuLmFwYWNoZS5vcmcvUE9NLzQuMC4wIgorCXhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiCisJeHNpOnNjaGVtYUxvY2F0aW9uPSJodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9QT00vNC4wLjAKKwkJCSAgICBodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9tYXZlbi12NF8wXzAueHNkIj4KKyAgICA8cGFyZW50PgorCTxncm91cElkPmNvbS5zdW4ubWFpbDwvZ3JvdXBJZD4KKwk8YXJ0aWZhY3RJZD5hbGw8L2FydGlmYWN0SWQ+CisJPHZlcnNpb24+MS42LjM8L3ZlcnNpb24+CisgICAgPC9wYXJlbnQ+CisgICAgPG1vZGVsVmVyc2lvbj40LjAuMDwvbW9kZWxWZXJzaW9uPgorICAgIDxncm91cElkPmNvbS5zdW4ubWFpbDwvZ3JvdXBJZD4KKyAgICA8YXJ0aWZhY3RJZD53ZWJhcHA8L2FydGlmYWN0SWQ+CisgICAgPHBhY2thZ2luZz53YXI8L3BhY2thZ2luZz4KKyAgICA8bmFtZT5KYXZhTWFpbCBBUEkgZGVtbyB3ZWJhcHA8L25hbWU+CisKKyAgICA8YnVpbGQ+CisJPHBsdWdpbnM+CisJICAgIDxwbHVnaW4+CisJCTxhcnRpZmFjdElkPm1hdmVuLXdhci1wbHVnaW48L2FydGlmYWN0SWQ+CisJCTxjb25maWd1cmF0aW9uPgorCQkgICAgPHdhck5hbWU+d2ViYXBwPC93YXJOYW1lPgorCQkgICAgPHBhY2thZ2luZ0V4Y2x1ZGVzPgorCQkJV0VCLUlORi9saWIvYWN0aXZhdGlvbiouamFyLAorCQkJV0VCLUlORi9saWIvamF2YXgubWFpbCouamFyLAorCQkJV0VCLUlORi9saWIvanNwKi5qYXIsCisJCQlXRUItSU5GL2xpYi9zZXJ2bGV0Ki5qYXIKKwkJICAgIDwvcGFja2FnaW5nRXhjbHVkZXM+CisJCSAgICA8b3V0cHV0RmlsZU5hbWVNYXBwaW5nPgorCQkJQHthcnRpZmFjdElkfUAuQHtleHRlbnNpb259QAorCQkgICAgPC9vdXRwdXRGaWxlTmFtZU1hcHBpbmc+CisJCTwvY29uZmlndXJhdGlvbj4KKwkgICAgPC9wbHVnaW4+CisJPC9wbHVnaW5zPgorICAgIDwvYnVpbGQ+CisKKyAgICA8ZGVwZW5kZW5jaWVzPgorICAgICAgICA8ZGVwZW5kZW5jeT4KKyAgICAgICAgICAgIDxncm91cElkPmNvbS5zdW4ubWFpbDwvZ3JvdXBJZD4KKyAgICAgICAgICAgIDxhcnRpZmFjdElkPnRhZ2xpYjwvYXJ0aWZhY3RJZD4KKyAgICAgICAgPC9kZXBlbmRlbmN5PgorICAgICAgICA8ZGVwZW5kZW5jeT4KKyAgICAgICAgICAgIDxncm91cElkPmphdmF4LnNlcnZsZXQ8L2dyb3VwSWQ+CisgICAgICAgICAgICA8YXJ0aWZhY3RJZD5zZXJ2bGV0LWFwaTwvYXJ0aWZhY3RJZD4KKyAgICAgICAgPC9kZXBlbmRlbmN5PgorICAgICAgICA8ZGVwZW5kZW5jeT4KKyAgICAgICAgICAgIDxncm91cElkPmNvbS5zdW4ubWFpbDwvZ3JvdXBJZD4KKyAgICAgICAgICAgIDxhcnRpZmFjdElkPmpha2FydGEubWFpbDwvYXJ0aWZhY3RJZD4KKyAgICAgICAgPC9kZXBlbmRlbmN5PgorICAgIDwvZGVwZW5kZW5jaWVzPgorPC9wcm9qZWN0PgpkaWZmIC0tZ2l0IGEvd2ViYXBwL3NyYy9tYWluL2phdmEvZGVtby9BdHRhY2htZW50U2VydmxldC5qYXZhIGIvd2ViYXBwL3NyYy9tYWluL2phdmEvZGVtby9BdHRhY2htZW50U2VydmxldC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjcyY2M4MjMKLS0tIC9kZXYvbnVsbAorKysgYi93ZWJhcHAvc3JjL21haW4vamF2YS9kZW1vL0F0dGFjaG1lbnRTZXJ2bGV0LmphdmEKQEAgLTAsMCArMSw3NCBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgRGlzdHJpYnV0aW9uIExpY2Vuc2Ugdi4gMS4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvb3JnL2RvY3VtZW50cy9lZGwtdjEwLnBocC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQlNELTMtQ2xhdXNlCisgKi8KKworcGFja2FnZSBkZW1vOworCitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmF4Lm1haWwuKjsKK2ltcG9ydCBqYXZheC5tYWlsLmludGVybmV0Lio7CitpbXBvcnQgamF2YXguc2VydmxldC4qOworaW1wb3J0IGphdmF4LnNlcnZsZXQuaHR0cC5IdHRwU2VydmxldDsKK2ltcG9ydCBqYXZheC5zZXJ2bGV0Lmh0dHAuSHR0cFNlcnZsZXRSZXF1ZXN0OworaW1wb3J0IGphdmF4LnNlcnZsZXQuaHR0cC5IdHRwU2VydmxldFJlc3BvbnNlOworaW1wb3J0IGphdmF4LnNlcnZsZXQuaHR0cC5IdHRwU2Vzc2lvbjsKKworLyoqCisgKiBUaGlzIHNlcnZsZXQgZ2V0cyB0aGUgaW5wdXQgc3RyZWFtIGZvciBhIGdpdmVuIG1zZyBwYXJ0IGFuZCAKKyAqIHB1c2hlcyBpdCBvdXQgdG8gdGhlIGJyb3dzZXIgd2l0aCB0aGUgY29ycmVjdCBjb250ZW50IHR5cGUuCisgKiBVc2VkIHRvIGRpc3BsYXkgYXR0YWNobWVudHMgYW5kIHJlbGllcyBvbiB0aGUgYnJvd3NlcidzCisgKiBjb250ZW50IGhhbmRsaW5nIGNhcGFiaWxpdGllcy4KKyAqLworcHVibGljIGNsYXNzIEF0dGFjaG1lbnRTZXJ2bGV0IGV4dGVuZHMgSHR0cFNlcnZsZXQgeworCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgaGFuZGxlcyB0aGUgR0VUIHJlcXVlc3RzIGZyb20gdGhlIGNsaWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBkb0dldChIdHRwU2VydmxldFJlcXVlc3QgcmVxdWVzdCwgSHR0cFNlcnZsZXRSZXNwb25zZSAgcmVzcG9uc2UpCisJdGhyb3dzIElPRXhjZXB0aW9uLCBTZXJ2bGV0RXhjZXB0aW9uIHsKKyAgICAgIAorCUh0dHBTZXNzaW9uIHNlc3Npb24gPSByZXF1ZXN0LmdldFNlc3Npb24oKTsKKwlTZXJ2bGV0T3V0cHV0U3RyZWFtIG91dCA9IHJlc3BvbnNlLmdldE91dHB1dFN0cmVhbSgpOworCWludCBtc2dOdW0gPSBJbnRlZ2VyLnBhcnNlSW50KHJlcXVlc3QuZ2V0UGFyYW1ldGVyKCJtZXNzYWdlIikpOworCWludCBwYXJ0TnVtID0gSW50ZWdlci5wYXJzZUludChyZXF1ZXN0LmdldFBhcmFtZXRlcigicGFydCIpKTsKKwlNYWlsVXNlckJlYW4gbWFpbHVzZXIgPSAoTWFpbFVzZXJCZWFuKXNlc3Npb24uZ2V0QXR0cmlidXRlKCJtYWlsdXNlciIpOworCisJLy8gY2hlY2sgdG8gYmUgc3VyZSB3ZSdyZSBzdGlsbCBsb2dnZWQgaW4KKwlpZiAobWFpbHVzZXIuaXNMb2dnZWRJbigpKSB7CisJICAgIHRyeSB7CisJCU1lc3NhZ2UgbXNnID0gbWFpbHVzZXIuZ2V0Rm9sZGVyKCkuZ2V0TWVzc2FnZShtc2dOdW0pOworCisJCU11bHRpcGFydCBtdWx0aXBhcnQgPSAoTXVsdGlwYXJ0KW1zZy5nZXRDb250ZW50KCk7CisJCVBhcnQgcGFydCA9IG11bHRpcGFydC5nZXRCb2R5UGFydChwYXJ0TnVtKTsKKwkJCisJCVN0cmluZyBzY3QgPSBwYXJ0LmdldENvbnRlbnRUeXBlKCk7CisJCWlmIChzY3QgPT0gbnVsbCkgeworCQkgICAgb3V0LnByaW50bG4oImludmFsaWQgcGFydCIpOworCQkgICAgcmV0dXJuOworCQl9CisJCUNvbnRlbnRUeXBlIGN0ID0gbmV3IENvbnRlbnRUeXBlKHNjdCk7CisKKwkJcmVzcG9uc2Uuc2V0Q29udGVudFR5cGUoY3QuZ2V0QmFzZVR5cGUoKSk7CisJCUlucHV0U3RyZWFtIGlzID0gcGFydC5nZXRJbnB1dFN0cmVhbSgpOworCQlpbnQgaTsKKwkJd2hpbGUgKChpID0gaXMucmVhZCgpKSAhPSAtMSkKKwkJICAgIG91dC53cml0ZShpKTsKKwkJb3V0LmZsdXNoKCk7CisJCW91dC5jbG9zZSgpOworCisJICAgIH0gY2F0Y2ggKE1lc3NhZ2luZ0V4Y2VwdGlvbiBleCkgeworCQl0aHJvdyBuZXcgU2VydmxldEV4Y2VwdGlvbihleC5nZXRNZXNzYWdlKCkpOworCSAgICB9CisJfSBlbHNlIHsKKwkgICAgZ2V0U2VydmxldENvbmZpZygpLmdldFNlcnZsZXRDb250ZXh0KCkuCisJCWdldFJlcXVlc3REaXNwYXRjaGVyKCIvaW5kZXguaHRtbCIpLgorCQlmb3J3YXJkKHJlcXVlc3QsIHJlc3BvbnNlKTsKKwl9CisgICAgfSAgIAorfQpkaWZmIC0tZ2l0IGEvd2ViYXBwL3NyYy9tYWluL2phdmEvZGVtby9GaWx0ZXJTZXJ2bGV0LmphdmEgYi93ZWJhcHAvc3JjL21haW4vamF2YS9kZW1vL0ZpbHRlclNlcnZsZXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMjBkYzc0Ci0tLSAvZGV2L251bGwKKysrIGIvd2ViYXBwL3NyYy9tYWluL2phdmEvZGVtby9GaWx0ZXJTZXJ2bGV0LmphdmEKQEAgLTAsMCArMSw2MiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICogdGVybXMgb2YgdGhlIEVjbGlwc2UgRGlzdHJpYnV0aW9uIExpY2Vuc2Ugdi4gMS4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvb3JnL2RvY3VtZW50cy9lZGwtdjEwLnBocC4KKyAqCisgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQlNELTMtQ2xhdXNlCisgKi8KKworcGFja2FnZSBkZW1vOworCitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmF4LnNlcnZsZXQuKjsKK2ltcG9ydCBqYXZheC5zZXJ2bGV0Lmh0dHAuKjsKKworLyoqCisgKiBUaGlzIHNlcnZsZXQgaXMgdXNlZCB0byBkZXRlcm1pbmUgd2hldGhlciB0aGUgdXNlciBpcyBsb2dnZWQgaW4gYmVmb3JlCisgKiBmb3J3YXJkaW5nIHRoZSByZXF1ZXN0IHRvIHRoZSBzZWxlY3RlZCBVUkwuCisgKi8KK3B1YmxpYyBjbGFzcyBGaWx0ZXJTZXJ2bGV0IGV4dGVuZHMgSHR0cFNlcnZsZXQgeworCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgaGFuZGxlcyB0aGUgIlBPU1QiIHN1Ym1pc3Npb24gZnJvbSB0d28gZm9ybXM6IHRoZQorICAgICAqIGxvZ2luIGZvcm0gYW5kIHRoZSBtZXNzYWdlIGNvbXBvc2UgZm9ybS4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBkb1Bvc3QoSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcXVlc3QsIAorCQkgICAgICAgSHR0cFNlcnZsZXRSZXNwb25zZSAgcmVzcG9uc2UpIAorCQkgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBTZXJ2bGV0RXhjZXB0aW9uIHsKKworCVN0cmluZyBzZXJ2bGV0UGF0aCA9IHJlcXVlc3QuZ2V0U2VydmxldFBhdGgoKTsKKwlzZXJ2bGV0UGF0aCA9IHNlcnZsZXRQYXRoLmNvbmNhdCgiLmpzcCIpOworCQorCWdldFNlcnZsZXRDb25maWcoKS5nZXRTZXJ2bGV0Q29udGV4dCgpLgorCSAgICBnZXRSZXF1ZXN0RGlzcGF0Y2hlcigiLyIgKyBzZXJ2bGV0UGF0aCkuZm9yd2FyZChyZXF1ZXN0LCByZXNwb25zZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgaGFuZGxlcyB0aGUgR0VUIHJlcXVlc3RzIGZyb20gdGhlIGNsaWVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBkb0dldChIdHRwU2VydmxldFJlcXVlc3QgcmVxdWVzdCwgCisJCSAgICAgIEh0dHBTZXJ2bGV0UmVzcG9uc2UgIHJlc3BvbnNlKQorCQkgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFNlcnZsZXRFeGNlcHRpb24geworICAgICAgCisJLy8gY2hlY2sgdG8gYmUgc3VyZSB3ZSdyZSBzdGlsbCBsb2dnZWQgaW4gCisJLy8gYmVmb3JlIGZvcndhcmRpbmcgdGhlIHJlcXVlc3QuCisJSHR0cFNlc3Npb24gc2Vzc2lvbiA9IHJlcXVlc3QuZ2V0U2Vzc2lvbigpOworCU1haWxVc2VyQmVhbiBtYWlsdXNlciA9IChNYWlsVXNlckJlYW4pc2Vzc2lvbi5nZXRBdHRyaWJ1dGUoIm1haWx1c2VyIik7CisJU3RyaW5nIHNlcnZsZXRQYXRoID0gcmVxdWVzdC5nZXRTZXJ2bGV0UGF0aCgpOworCXNlcnZsZXRQYXRoID0gc2VydmxldFBhdGguY29uY2F0KCIuanNwIik7CisJCisJaWYgKG1haWx1c2VyLmlzTG9nZ2VkSW4oKSkKKwkgICAgZ2V0U2VydmxldENvbmZpZygpLmdldFNlcnZsZXRDb250ZXh0KCkuCisJCWdldFJlcXVlc3REaXNwYXRjaGVyKCIvIiArIHNlcnZsZXRQYXRoKS4KKwkJZm9yd2FyZChyZXF1ZXN0LCByZXNwb25zZSk7CisJZWxzZQorCSAgICBnZXRTZXJ2bGV0Q29uZmlnKCkuZ2V0U2VydmxldENvbnRleHQoKS4KKwkJZ2V0UmVxdWVzdERpc3BhdGNoZXIoIi9pbmRleC5odG1sIikuCisJCWZvcndhcmQocmVxdWVzdCwgcmVzcG9uc2UpOworICAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvd2ViYXBwL3NyYy9tYWluL2phdmEvZGVtby9NYWlsVXNlckJlYW4uamF2YSBiL3dlYmFwcC9zcmMvbWFpbi9qYXZhL2RlbW8vTWFpbFVzZXJCZWFuLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjM5ZTZhNAotLS0gL2Rldi9udWxsCisrKyBiL3dlYmFwcC9zcmMvbWFpbi9qYXZhL2RlbW8vTWFpbFVzZXJCZWFuLmphdmEKQEAgLTAsMCArMSwxODkgQEAKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDEsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUKKyAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisgKgorICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorICovCisKK3BhY2thZ2UgZGVtbzsKKworaW1wb3J0IGphdmEudXRpbC4qOworaW1wb3J0IGphdmF4Lm1haWwuKjsKK2ltcG9ydCBqYXZheC5uYW1pbmcuKjsKKworLyoqCisgKiBUaGlzIEphdmFCZWFuIGlzIHVzZWQgdG8gc3RvcmUgbWFpbCB1c2VyIGluZm9ybWF0aW9uLgorICovCitwdWJsaWMgY2xhc3MgTWFpbFVzZXJCZWFuIHsKKyAgICBwcml2YXRlIEZvbGRlciBmb2xkZXI7CisgICAgcHJpdmF0ZSBTdHJpbmcgaG9zdG5hbWU7CisgICAgcHJpdmF0ZSBTdHJpbmcgdXNlcm5hbWU7CisgICAgcHJpdmF0ZSBTdHJpbmcgcGFzc3dvcmQ7CisgICAgcHJpdmF0ZSBTZXNzaW9uIHNlc3Npb247CisgICAgcHJpdmF0ZSBTdG9yZSBzdG9yZTsKKyAgICBwcml2YXRlIFVSTE5hbWUgdXJsOworICAgIHByaXZhdGUgU3RyaW5nIHByb3RvY29sID0gImltYXAiOworICAgIHByaXZhdGUgU3RyaW5nIG1ib3ggPSAiSU5CT1giOwkKKworICAgIHB1YmxpYyBNYWlsVXNlckJlYW4oKXt9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBqYXZheC5tYWlsLkZvbGRlciBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIEZvbGRlciBnZXRGb2xkZXIoKSB7CisJcmV0dXJuIGZvbGRlcjsKKyAgICB9CisgICAgCisgICAgLyoqCisgICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIG1lc3NhZ2VzIGluIHRoZSBmb2xkZXIuCisgICAgICovCisgICAgcHVibGljIGludCBnZXRNZXNzYWdlQ291bnQoKSB0aHJvd3MgTWVzc2FnaW5nRXhjZXB0aW9uIHsKKwlyZXR1cm4gZm9sZGVyLmdldE1lc3NhZ2VDb3VudCgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIGhvc3RuYW1lIGdldHRlciBtZXRob2QuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRIb3N0bmFtZSgpIHsKKwlyZXR1cm4gaG9zdG5hbWU7CisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIGhvc3RuYW1lIHNldHRlciBtZXRob2QuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0SG9zdG5hbWUoU3RyaW5nIGhvc3RuYW1lKSB7CisJdGhpcy5ob3N0bmFtZSA9IGhvc3RuYW1lOworICAgIH0KKwkKKyAgICAvKioKKyAgICAgKiB1c2VybmFtZSBnZXR0ZXIgbWV0aG9kLgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0VXNlcm5hbWUoKSB7CisJcmV0dXJuIHVzZXJuYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIHVzZXJuYW1lIHNldHRlciBtZXRob2QuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0VXNlcm5hbWUoU3RyaW5nIHVzZXJuYW1lKSB7CisJdGhpcy51c2VybmFtZSA9IHVzZXJuYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIHBhc3N3b3JkIGdldHRlciBtZXRob2QuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRQYXNzd29yZCgpIHsKKwlyZXR1cm4gcGFzc3dvcmQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogcGFzc3dvcmQgc2V0dGVyIG1ldGhvZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRQYXNzd29yZChTdHJpbmcgcGFzc3dvcmQpIHsKKwl0aGlzLnBhc3N3b3JkID0gcGFzc3dvcmQ7CisgICAgfQorCisgICAgLyoqCisgICAgICogc2Vzc2lvbiBnZXR0ZXIgbWV0aG9kLgorICAgICAqLworICAgIHB1YmxpYyBTZXNzaW9uIGdldFNlc3Npb24oKSB7CisJcmV0dXJuIHNlc3Npb247CisgICAgfQorCisgICAgLyoqCisgICAgICogc2Vzc2lvbiBzZXR0ZXIgbWV0aG9kLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFNlc3Npb24oU2Vzc2lvbiBzZXNzaW9uKSB7CisJdGhpcy5zZXNzaW9uID0gc2Vzc2lvbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBzdG9yZSBnZXR0ZXIgbWV0aG9kLgorICAgICAqLworICAgIHB1YmxpYyBTdG9yZSBnZXRTdG9yZSgpIHsKKwlyZXR1cm4gc3RvcmU7CisgICAgfQorCisgICAgLyoqCisgICAgICogc3RvcmUgc2V0dGVyIG1ldGhvZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRTdG9yZShTdG9yZSBzdG9yZSkgeworCXRoaXMuc3RvcmUgPSBzdG9yZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiB1cmwgZ2V0dGVyIG1ldGhvZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgVVJMTmFtZSBnZXRVcmwoKSB7CisJcmV0dXJuIHVybDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNZXRob2QgZm9yIGNoZWNraW5nIGlmIHRoZSB1c2VyIGlzIGxvZ2dlZCBpbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0xvZ2dlZEluKCkgeworCXJldHVybiBzdG9yZS5pc0Nvbm5lY3RlZCgpOworICAgIH0KKyAgICAgIAorICAgIC8qKgorICAgICAqIE1ldGhvZCB1c2VkIHRvIGxvZ2luIHRvIHRoZSBtYWlsIGhvc3QuCisgICAgICovCisgICAgcHVibGljIHZvaWQgbG9naW4oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKwl1cmwgPSBuZXcgVVJMTmFtZShwcm90b2NvbCwgZ2V0SG9zdG5hbWUoKSwgLTEsIG1ib3gsIAorCQkJICBnZXRVc2VybmFtZSgpLCBnZXRQYXNzd29yZCgpKTsKKwkvKgorCSAqIEZpcnN0LCB0cnkgdG8gZ2V0IHRoZSBzZXNzaW9uIGZyb20gSk5ESSwKKwkgKiBhcyB3b3VsZCBiZSBkb25lIHVuZGVyIEoyRUUuCisJICovCisJdHJ5IHsKKwkgICAgSW5pdGlhbENvbnRleHQgaWMgPSBuZXcgSW5pdGlhbENvbnRleHQoKTsKKwkgICAgQ29udGV4dCBjdHggPSAoQ29udGV4dClpYy5sb29rdXAoImphdmE6Y29tcC9lbnYiKTsKKwkgICAgc2Vzc2lvbiA9IChTZXNzaW9uKWN0eC5sb29rdXAoIk15U2Vzc2lvbiIpOworCX0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworCSAgICAvLyBpZ25vcmUgaXQKKwl9CisKKwkvLyBpZiBKTkRJIGZhaWxzLCB0cnkgdGhlIG9sZCB3YXkgdGhhdCBzaG91bGQgd29yayBldmVyeXdoZXJlCisJaWYgKHNlc3Npb24gPT0gbnVsbCkgeworCSAgICBQcm9wZXJ0aWVzIHByb3BzID0gbnVsbDsKKwkgICAgdHJ5IHsKKwkJcHJvcHMgPSBTeXN0ZW0uZ2V0UHJvcGVydGllcygpOworCSAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBzZXgpIHsKKwkJcHJvcHMgPSBuZXcgUHJvcGVydGllcygpOworCSAgICB9CisJICAgIHNlc3Npb24gPSBTZXNzaW9uLmdldEluc3RhbmNlKHByb3BzLCBudWxsKTsKKwl9CisJc3RvcmUgPSBzZXNzaW9uLmdldFN0b3JlKHVybCk7CisJc3RvcmUuY29ubmVjdCgpOworCWZvbGRlciA9IHN0b3JlLmdldEZvbGRlcih1cmwpOworCQorCWZvbGRlci5vcGVuKEZvbGRlci5SRUFEX1dSSVRFKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNZXRob2QgdXNlZCB0byBsb2dpbiB0byB0aGUgbWFpbCBob3N0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGxvZ2luKFN0cmluZyBob3N0bmFtZSwgU3RyaW5nIHVzZXJuYW1lLCBTdHJpbmcgcGFzc3dvcmQpIAorCXRocm93cyBFeGNlcHRpb24geworCSAgICAKKwl0aGlzLmhvc3RuYW1lID0gaG9zdG5hbWU7CisJdGhpcy51c2VybmFtZSA9IHVzZXJuYW1lOworCXRoaXMucGFzc3dvcmQgPSBwYXNzd29yZDsKKwkgICAgCisJbG9naW4oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBNZXRob2QgdXNlZCB0byBsb2dvdXQgZnJvbSB0aGUgbWFpbCBob3N0LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGxvZ291dCgpIHRocm93cyBNZXNzYWdpbmdFeGNlcHRpb24geworCWZvbGRlci5jbG9zZShmYWxzZSk7CisJc3RvcmUuY2xvc2UoKTsKKwlzdG9yZSA9IG51bGw7CisJc2Vzc2lvbiA9IG51bGw7CisgICAgfQorfQorCmRpZmYgLS1naXQgYS93ZWJhcHAvc3JjL21haW4vd2ViYXBwL1dFQi1JTkYvd2ViLnhtbCBiL3dlYmFwcC9zcmMvbWFpbi93ZWJhcHAvV0VCLUlORi93ZWIueG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMzZjg4YmIKLS0tIC9kZXYvbnVsbAorKysgYi93ZWJhcHAvc3JjL21haW4vd2ViYXBwL1dFQi1JTkYvd2ViLnhtbApAQCAtMCwwICsxLDY2IEBACis8IURPQ1RZUEUgd2ViLWFwcCBQVUJMSUMgIi0vL1N1biBNaWNyb3N5c3RlbXMsIEluYy4vL0RURCBXZWIgQXBwbGljYXRpb24gMi4yLy9FTiIgImh0dHA6Ly9qYXZhLnN1bi5jb20vajJlZS9kdGRzL3dlYi1hcHBfMl8yLmR0ZCI+Cis8IS0tCisKKyAgICBDb3B5cmlnaHQgKGMpIDIwMTAsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKworICAgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICAgIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9vcmcvZG9jdW1lbnRzL2VkbC12MTAucGhwLgorCisgICAgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorCistLT4KKworPHdlYi1hcHA+CisgIDxkaXNwbGF5LW5hbWU+SnNwRGVtbzwvZGlzcGxheS1uYW1lPgorICA8ZGVzY3JpcHRpb24+bm8gZGVzY3JpcHRpb248L2Rlc2NyaXB0aW9uPgorICA8c2VydmxldD4KKyAgICA8c2VydmxldC1uYW1lPkZpbHRlclNlcnZsZXQ8L3NlcnZsZXQtbmFtZT4KKyAgICA8ZGlzcGxheS1uYW1lPkZpbHRlclNlcnZsZXQ8L2Rpc3BsYXktbmFtZT4KKyAgICA8ZGVzY3JpcHRpb24+bm8gZGVzY3JpcHRpb248L2Rlc2NyaXB0aW9uPgorICAgIDxzZXJ2bGV0LWNsYXNzPmRlbW8uRmlsdGVyU2VydmxldDwvc2VydmxldC1jbGFzcz4KKyAgPC9zZXJ2bGV0PgorICA8c2VydmxldD4KKyAgICA8c2VydmxldC1uYW1lPkF0dGFjaG1lbnRTZXJ2bGV0PC9zZXJ2bGV0LW5hbWU+CisgICAgPGRpc3BsYXktbmFtZT5BdHRhY2htZW50U2VydmxldDwvZGlzcGxheS1uYW1lPgorICAgIDxkZXNjcmlwdGlvbj5ubyBkZXNjcmlwdGlvbjwvZGVzY3JpcHRpb24+CisgICAgPHNlcnZsZXQtY2xhc3M+ZGVtby5BdHRhY2htZW50U2VydmxldDwvc2VydmxldC1jbGFzcz4KKyAgPC9zZXJ2bGV0PgorICA8c2VydmxldC1tYXBwaW5nPgorICAgIDxzZXJ2bGV0LW5hbWU+RmlsdGVyU2VydmxldDwvc2VydmxldC1uYW1lPgorICAgIDx1cmwtcGF0dGVybj4vY29tcG9zZTwvdXJsLXBhdHRlcm4+CisgIDwvc2VydmxldC1tYXBwaW5nPgorICA8c2VydmxldC1tYXBwaW5nPgorICAgIDxzZXJ2bGV0LW5hbWU+RmlsdGVyU2VydmxldDwvc2VydmxldC1uYW1lPgorICAgIDx1cmwtcGF0dGVybj4vZXJyb3JkZXRhaWxzPC91cmwtcGF0dGVybj4KKyAgPC9zZXJ2bGV0LW1hcHBpbmc+CisgIDxzZXJ2bGV0LW1hcHBpbmc+CisgICAgPHNlcnZsZXQtbmFtZT5GaWx0ZXJTZXJ2bGV0PC9zZXJ2bGV0LW5hbWU+CisgICAgPHVybC1wYXR0ZXJuPi9sb2dpbjwvdXJsLXBhdHRlcm4+CisgIDwvc2VydmxldC1tYXBwaW5nPgorICA8c2VydmxldC1tYXBwaW5nPgorICAgIDxzZXJ2bGV0LW5hbWU+RmlsdGVyU2VydmxldDwvc2VydmxldC1uYW1lPgorICAgIDx1cmwtcGF0dGVybj4vbG9nb3V0PC91cmwtcGF0dGVybj4KKyAgPC9zZXJ2bGV0LW1hcHBpbmc+CisgIDxzZXJ2bGV0LW1hcHBpbmc+CisgICAgPHNlcnZsZXQtbmFtZT5GaWx0ZXJTZXJ2bGV0PC9zZXJ2bGV0LW5hbWU+CisgICAgPHVybC1wYXR0ZXJuPi9zZW5kPC91cmwtcGF0dGVybj4KKyAgPC9zZXJ2bGV0LW1hcHBpbmc+CisgIDxzZXJ2bGV0LW1hcHBpbmc+CisgICAgPHNlcnZsZXQtbmFtZT5GaWx0ZXJTZXJ2bGV0PC9zZXJ2bGV0LW5hbWU+CisgICAgPHVybC1wYXR0ZXJuPi9tZXNzYWdlaGVhZGVyczwvdXJsLXBhdHRlcm4+CisgIDwvc2VydmxldC1tYXBwaW5nPgorICA8c2VydmxldC1tYXBwaW5nPgorICAgIDxzZXJ2bGV0LW5hbWU+RmlsdGVyU2VydmxldDwvc2VydmxldC1uYW1lPgorICAgIDx1cmwtcGF0dGVybj4vbWVzc2FnZWNvbnRlbnQ8L3VybC1wYXR0ZXJuPgorICA8L3NlcnZsZXQtbWFwcGluZz4KKyAgPHNlcnZsZXQtbWFwcGluZz4KKyAgICA8c2VydmxldC1uYW1lPkF0dGFjaG1lbnRTZXJ2bGV0PC9zZXJ2bGV0LW5hbWU+CisgICAgPHVybC1wYXR0ZXJuPi9hdHRhY2htZW50PC91cmwtcGF0dGVybj4KKyAgPC9zZXJ2bGV0LW1hcHBpbmc+CisgIDxyZXNvdXJjZS1yZWY+CisgICAgPHJlcy1yZWYtbmFtZT5NeVNlc3Npb248L3Jlcy1yZWYtbmFtZT4KKyAgICA8cmVzLXR5cGU+amF2YXgubWFpbC5TZXNzaW9uPC9yZXMtdHlwZT4KKyAgICA8cmVzLWF1dGg+Q29udGFpbmVyPC9yZXMtYXV0aD4KKyAgPC9yZXNvdXJjZS1yZWY+Cis8L3dlYi1hcHA+CmRpZmYgLS1naXQgYS93ZWJhcHAvc3JjL21haW4vd2ViYXBwL2NvbXBvc2UuanNwIGIvd2ViYXBwL3NyYy9tYWluL3dlYmFwcC9jb21wb3NlLmpzcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZjA4YjYyCi0tLSAvZGV2L251bGwKKysrIGIvd2ViYXBwL3NyYy9tYWluL3dlYmFwcC9jb21wb3NlLmpzcApAQCAtMCwwICsxLDY1IEBACis8JS0tCisKKyAgICBDb3B5cmlnaHQgKGMpIDIwMDEsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKworICAgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICAgIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9vcmcvZG9jdW1lbnRzL2VkbC12MTAucGhwLgorCisgICAgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorCistLSU+CisKKzwlQCBwYWdlIGxhbmd1YWdlPSJqYXZhIiAlPgorPCVAIHBhZ2UgZXJyb3JQYWdlPSJlcnJvcnBhZ2UuanNwIiAlPgorCis8aHRtbD4KKzxoZWFkPgorCTx0aXRsZT5KYXZhTWFpbCBjb21wb3NlPC90aXRsZT4KKzwvaGVhZD4KKworPGJvZHkgYmdjb2xvcj0iI2NjY2NmZiI+Cis8Zm9ybSBBQ1RJT049InNlbmQiIE1FVEhPRD1QT1NUPgorPGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT0ic2VuZCIgdmFsdWU9InNlbmQiPgorPHAgYWxpZ249ImNlbnRlciI+Cis8Yj48Zm9udCBzaXplPSI0IiBmYWNlPSJWZXJkYW5hLCBBcmlhbCwgSGVsdmV0aWNhIj4KK0phdmFNYWlsIENvbXBvc2UgTWVzc2FnZTwvZm9udD48L2I+Cis8cD4KKzx0YWJsZSBib3JkZXI9IjAiIHdpZHRoPSIxMDAlIj4KKzx0cj4KKzx0ZCB3aWR0aD0iMTYlIiBoZWlnaHQ9IjIyIj4JCis8cCBhbGlnbj0icmlnaHQiPgorPGI+PGZvbnQgZmFjZT0iVmVyZGFuYSwgQXJpYWwsIEhlbHZldGljYSI+VG86PC9mb250PjwvYj48L3RkPgorPHRkIHdpZHRoPSI4NCUiIGhlaWdodD0iMjIiPgorPCUgaWYgKHJlcXVlc3QuZ2V0UGFyYW1ldGVyKCJ0byIpICE9IG51bGwpIHsgJT4KKzxpbnB1dCB0eXBlPSJ0ZXh0IiBuYW1lPSJ0byIgdmFsdWU9IjwlPSByZXF1ZXN0LmdldFBhcmFtZXRlcigidG8iKSAlPiIgc2l6ZT0iMzAiPgorPCUgfSBlbHNlIHsgJT4KKzxpbnB1dCB0eXBlPSJ0ZXh0IiBuYW1lPSJ0byIgc2l6ZT0iMzAiPiAKKzwlIH0gJT4KKzxmb250IHNpemU9IjEiIGZhY2U9IlZlcmRhbmEsIEFyaWFsLCBIZWx2ZXRpY2EiPgorIChzZXBhcmF0ZSBhZGRyZXNzZXMgd2l0aCBjb21tYXMpPC9mb250PjwvdGQ+PC90cj4KKzx0cj4KKzx0ZCB3aWR0aD0iMTYlIj48cCBhbGlnbj0icmlnaHQiPgorPGI+PGZvbnQgZmFjZT0iVmVyZGFuYSwgQXJpYWwsIEhlbHZldGljYSI+RnJvbTo8L2ZvbnQ+PC9iPjwvdGQ+Cis8dGQgd2lkdGg9Ijg0JSI+Cis8aW5wdXQgdHlwZT0idGV4dCIgbmFtZT0iZnJvbSIgc2l6ZT0iMzAiPiAKKzxmb250IHNpemU9IjEiIGZhY2U9IlZlcmRhbmEsIEFyaWFsLCBIZWx2ZXRpY2EiPgorIChzZXBhcmF0ZSBhZGRyZXNzZXMgd2l0aCBjb21tYXMpPC9mb250PjwvdGQ+PC90cj4KKzx0cj4KKzx0ZCB3aWR0aD0iMTYlIj48cCBhbGlnbj0icmlnaHQiPgorPGI+PGZvbnQgZmFjZT0iVmVyZGFuYSwgQXJpYWwsIEhlbHZldGljYSI+U3ViamVjdDo8L2ZvbnQ+PC9iPjwvdGQ+Cis8dGQgd2lkdGg9Ijg0JSI+Cis8aW5wdXQgdHlwZT0idGV4dCIgbmFtZT0ic3ViamVjdCIgc2l6ZT0iNTUiPjwvdGQ+PC90cj4KKzx0cj4KKzx0ZCB3aWR0aD0iMTYlIj4mbmJzcDs8L3RkPgorPHRkIHdpZHRoPSI4NCUiPjx0ZXh0YXJlYSBuYW1lPSJ0ZXh0IiByb3dzPSIxNSIgY29scz0iNTMiPjwvdGV4dGFyZWE+PC90ZD48L3RyPgorPHRyPgorPHRkIHdpZHRoPSIxNiUiIGhlaWdodD0iMzIiPiZuYnNwOzwvdGQ+Cis8dGQgd2lkdGg9Ijg0JSIgaGVpZ2h0PSIzMiI+Cis8aW5wdXQgdHlwZT0ic3VibWl0IiBuYW1lPSJTZW5kIiB2YWx1ZT0iU2VuZCI+Cis8aW5wdXQgdHlwZT0icmVzZXQiIG5hbWU9IlJlc2V0IiB2YWx1ZT0iUmVzZXQiPjwvdGQ+PC90cj4KKzwvdGFibGU+Cis8L2Zvcm0+Cis8L2JvZHk+Cis8L2h0bWw+CisKZGlmZiAtLWdpdCBhL3dlYmFwcC9zcmMvbWFpbi93ZWJhcHAvZXJyb3JkZXRhaWxzLmpzcCBiL3dlYmFwcC9zcmMvbWFpbi93ZWJhcHAvZXJyb3JkZXRhaWxzLmpzcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jOTQ2MjE2Ci0tLSAvZGV2L251bGwKKysrIGIvd2ViYXBwL3NyYy9tYWluL3dlYmFwcC9lcnJvcmRldGFpbHMuanNwCkBAIC0wLDAgKzEsMjIgQEAKKzwlLS0KKworICAgIENvcHlyaWdodCAoYykgMjAwMSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorCisgICAgVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgICAgdGVybXMgb2YgdGhlIEVjbGlwc2UgRGlzdHJpYnV0aW9uIExpY2Vuc2Ugdi4gMS4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisKKyAgICBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQlNELTMtQ2xhdXNlCisKKy0tJT4KKworPCVAIHBhZ2UgaXNFcnJvclBhZ2U9InRydWUiICU+Cis8aHRtbD4KKzxoZWFkPgorPHRpdGxlPkphdmFNYWlsIGVycm9yZGV0YWlsczwvdGl0bGU+Cis8L2hlYWQ+Cis8Ym9keSBiZ2NvbG9yPSJ3aGl0ZSI+Cis8JT0gc2Vzc2lvbi5nZXRWYWx1ZSgiZGV0YWlscyIpICU+Cis8L2JvZHk+Cis8L2h0bWw+CisKZGlmZiAtLWdpdCBhL3dlYmFwcC9zcmMvbWFpbi93ZWJhcHAvZXJyb3JwYWdlLmpzcCBiL3dlYmFwcC9zcmMvbWFpbi93ZWJhcHAvZXJyb3JwYWdlLmpzcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ZGYwNDA3Ci0tLSAvZGV2L251bGwKKysrIGIvd2ViYXBwL3NyYy9tYWluL3dlYmFwcC9lcnJvcnBhZ2UuanNwCkBAIC0wLDAgKzEsMjYgQEAKKzwlLS0KKworICAgIENvcHlyaWdodCAoYykgMjAwMSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorCisgICAgVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgICAgdGVybXMgb2YgdGhlIEVjbGlwc2UgRGlzdHJpYnV0aW9uIExpY2Vuc2Ugdi4gMS4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisKKyAgICBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQlNELTMtQ2xhdXNlCisKKy0tJT4KKworPCVAIHBhZ2UgaXNFcnJvclBhZ2U9InRydWUiICU+Cis8aHRtbD4KKzxoZWFkPgorPHRpdGxlPkphdmFNYWlsIGVycm9ycGFnZTwvdGl0bGU+Cis8L2hlYWQ+Cis8Ym9keSBiZ2NvbG9yPSJ3aGl0ZSI+Cis8Zm9ybSBBQ1RJT049ImVycm9yZGV0YWlscyIgTUVUSE9EPVBPU1Q+Cis8JSBzZXNzaW9uLnB1dFZhbHVlKCJkZXRhaWxzIiwgZXhjZXB0aW9uLnRvU3RyaW5nKCkpOyAlPgorPGgyPkFuIGVycm9yIG9jY3VyZWQgd2hpbGUgYXR0ZW1wdGluZyB0byBwZXJmb3JtIHRoZSBvcGVyYXRpb24geW91IHJlcXVlc3RlZC4KKzwvaDI+Cis8aW5wdXQgdHlwZT0ic3VibWl0IiBuYW1lPSJFcnJvciBEZXRhaWxzIiB2YWx1ZT0iRXJyb3IgRGV0YWlscyI+Cis8L2JvZHk+Cis8L2h0bWw+CisKZGlmZiAtLWdpdCBhL3dlYmFwcC9zcmMvbWFpbi93ZWJhcHAvZm9sZGVycy5qc3AgYi93ZWJhcHAvc3JjL21haW4vd2ViYXBwL2ZvbGRlcnMuanNwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjllZWY5YzAKLS0tIC9kZXYvbnVsbAorKysgYi93ZWJhcHAvc3JjL21haW4vd2ViYXBwL2ZvbGRlcnMuanNwCkBAIC0wLDAgKzEsNDUgQEAKKzwlLS0KKworICAgIENvcHlyaWdodCAoYykgMjAwMSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorCisgICAgVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgICAgdGVybXMgb2YgdGhlIEVjbGlwc2UgRGlzdHJpYnV0aW9uIExpY2Vuc2Ugdi4gMS4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisKKyAgICBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQlNELTMtQ2xhdXNlCisKKy0tJT4KKworPCVAIHBhZ2UgbGFuZ3VhZ2U9ImphdmEiIGltcG9ydD0iamF2YXgubWFpbC4qLCBkZW1vLk1haWxVc2VyQmVhbiIgJT4KKzwlQCBwYWdlIGVycm9yUGFnZT0iZXJyb3JwYWdlLmpzcCIgJT4KKzxqc3A6dXNlQmVhbiBpZD0ibWFpbHVzZXIiIHNjb3BlPSJzZXNzaW9uIiBjbGFzcz0iZGVtby5NYWlsVXNlckJlYW4iIC8+CisJCis8aHRtbD4KKzxoZWFkPgorICAgIDx0aXRsZT5KYXZhTWFpbCBmb2xkZXJzPC90aXRsZT4KKzwvaGVhZD4KKwkKKzxib2R5IGJnY29sb3I9IiNjY2NjZmYiPgorCis8Y2VudGVyPgorPGZvbnQgZmFjZT0iQXJpYWwsSGVsdmV0aWNhIiBmb250IHNpemU9KzM+Cis8Yj5XZWxjb21lIHRvIEphdmFNYWlsITwvYj4gPC9mb250PiA8L2NlbnRlcj4KKzx0YWJsZSB3aWR0aD0iNTAlIiBib3JkZXI9MCBhbGlnbj1jZW50ZXI+Cis8dHI+Cis8dGQgd2lkdGg9Ijc1JSIgYmdjb2xvcj0iI2ZmZmZjYyI+Cis8Zm9udCBmYWNlPSJBcmlhbCwgSGVsdmV0aWNhIiBmb250IHNpemU9LTE+Cis8Yj5Gb2xkZXJOYW1lPC9iPjwvZm9udD48L3RkPjxicj4KKzx0ZCB3aWR0aD0iMjUlIiBiZ2NvbG9yPSIjZmZmZmNjIj4KKzxmb250IGZhY2U9IkFyaWFsLCBIZWx2ZXRpY2EiIGZvbnQgc2l6ZT0tMT4KKzxiPk1lc3NhZ2VzPC9iPjwvZm9udD48L3RkPjxicj4KKzwvdHI+Cis8dHI+Cis8dGQgd2lkdGg9Ijc1JSIgYmdjb2xvcj0iI2ZmZmZmZiI+Cis8YSBocmVmPSJtZXNzYWdlaGVhZGVycyI+SW5ib3g8L2E+PC90ZD48YnI+Cis8dGQgd2lkdGg9IjI1JSIgYmdjb2xvcj0iI2ZmZmZmZiI+Cis8JT0gbWFpbHVzZXIuZ2V0TWVzc2FnZUNvdW50KCkgJT4KKzwvdHI+Cis8L3RhYmxlPgorPC9ib2R5PgorPC9odG1sPgorCmRpZmYgLS1naXQgYS93ZWJhcHAvc3JjL21haW4vd2ViYXBwL2luZGV4Lmh0bWwgYi93ZWJhcHAvc3JjL21haW4vd2ViYXBwL2luZGV4Lmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWE2ZGIyMQotLS0gL2Rldi9udWxsCisrKyBiL3dlYmFwcC9zcmMvbWFpbi93ZWJhcHAvaW5kZXguaHRtbApAQCAtMCwwICsxLDkzIEBACis8IURPQ1RZUEUgSFRNTCBQVUJMSUMgIi0vL1czQy8vRFREIEhUTUwgMy4yLy9FTiI+Cis8SFRNTD4KKzwhLS0KKworICAgIENvcHlyaWdodCAoYykgMTk5OCwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorCisgICAgVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgICAgdGVybXMgb2YgdGhlIEVjbGlwc2UgRGlzdHJpYnV0aW9uIExpY2Vuc2Ugdi4gMS4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisKKyAgICBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQlNELTMtQ2xhdXNlCisKKy0tPgorCis8SEVBRD4KKwk8TUVUQSBIVFRQLUVRVUlWPSJDb250ZW50LVR5cGUiIENPTlRFTlQ9InRleHQvaHRtbDtDSEFSU0VUPWlzby04ODU5LTEiPgorCTxUSVRMRT5KYXZhTWFpbDwvVElUTEU+Cis8L0hFQUQ+CisKKzxCT0RZIEJHQ09MT1I9IiNDQ0NDRkYiPgorCis8Rk9STSBBQ1RJT049ImxvZ2luIiBNRVRIT0Q9UE9TVCBFTkNUWVBFPSJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQiPgorPFAgQUxJR049IkNFTlRFUiI+PEI+PEZPTlQgU0laRT0iNSIgRkFDRT0iQXJpYWwsIEhlbHZldGljYSI+V2VsY29tZSB0byBKYXZhTWFpbDwvRk9OVD48L0I+PC9QPgorCis8UCBBTElHTj0iQ0VOVEVSIj48Qj48Rk9OVCBTSVpFPSI1IiBGQUNFPSJBcmlhbCwgSGVsdmV0aWNhIj5IVE1MIEVtYWlsIFJlYWRlciBEZW1vPC9GT05UPjwvQj48L1A+Cis8Q0VOVEVSPgorPFA+Cis8VEFCTEUgQk9SREVSPSIwIiBXSURUSD0iMTAwJSI+CisJPFRSPgorCQk8VEQgV0lEVEg9IjQwJSI+CisJCQk8UCBBTElHTj0iUklHSFQiPjxGT05UIEZBQ0U9IkFyaWFsLCBIZWx2ZXRpY2EiPklNQVAgSG9zdG5hbWU6PC9GT05UPgorCQk8L1REPgorCQk8VEQgV0lEVEg9IjYwJSI+PElOUFVUIFRZUEU9IlRFWFQiIE5BTUU9Imhvc3RuYW1lIiBTSVpFPSIyNSI+PC9URD4KKwk8L1RSPgorCTxUUj4KKwkJPFREIFdJRFRIPSI0MCUiPgorCQkJPFAgQUxJR049IlJJR0hUIj48Rk9OVCBGQUNFPSJBcmlhbCwgSGVsdmV0aWNhIj5Vc2VybmFtZTo8L0ZPTlQ+CisJCTwvVEQ+CisJCTxURCBXSURUSD0iNjAlIj48SU5QVVQgVFlQRT0iVEVYVCIgTkFNRT0idXNlcm5hbWUiIFNJWkU9IjI1Ij48L1REPgorCTwvVFI+CisJPFRSPgorCQk8VEQgV0lEVEg9IjQwJSI+CisJCQk8UCBBTElHTj0iUklHSFQiPjxGT05UIEZBQ0U9IkFyaWFsLCBIZWx2ZXRpY2EiPlBhc3N3b3JkOjwvRk9OVD4KKwkJPC9URD4KKwkJPFREIFdJRFRIPSI2MCUiPjxJTlBVVCBUWVBFPSJQQVNTV09SRCIgTkFNRT0icGFzc3dvcmQiIFNJWkU9IjI1Ij48L1REPgorCTwvVFI+Cis8L1RBQkxFPgorPElOUFVUIFRZUEU9IlNVQk1JVCIgVkFMVUU9IkxvZ2luIj48SU5QVVQgVFlQRT0iUkVTRVQiIE5BTUU9IlJlc2V0IiBWQUxVRT0iUmVzZXQiPjwvUD4KKzwvQ0VOVEVSPgorPFA+Cis8SFIgQUxJR049IkNFTlRFUiI+Cis8L1A+Cis8UD48Qj48ST48Rk9OVCBGQUNFPSJBcmlhbCwgSGVsdmV0aWNhIj5PdmVydmlldzo8L0ZPTlQ+PC9JPjwvQj48L1A+CisKKzxGT05UIFNJWkU9IjIiIEZBQ0U9IkFyaWFsLCBIZWx2ZXRpY2EiPgorPGI+VEhJUyBJUyBBIERFTU8hISE8L2I+IFBsZWFzZSBzZWUgdGhlIHdlYmFwcC5SRUFETUUudHh0IAorZmlsZSBmb3IgaW5mb3JtYXRpb24gb24gaG93IHRvCitjb21waWxlIGFuZCBydW4gdGhlIHdlYiBhcHBsaWNhdGlvbi48YnI+IDxicj4KK1RoaXMgZGVtbyBpbGx1c3RyYXRlcyB0aGUgdXNlIG9mIEphdmFNYWlsIEFQSXMgaW4gYSAzLXRpZXJlZCB3ZWIgCithcHBsaWNhdGlvbi4gSXQgYWxsb3dzIHRoZSB1c2VyIHRvIGxvZ2luIHRvIGFuIAorSU1BUCBzdG9yZSwgbGlzdCBhbGwgdGhlIG1lc3NhZ2VzIGluIHRoZSBJTkJPWCBmb2xkZXIsIHZpZXcKK3NlbGVjdGVkIG1lc3NhZ2VzLCBjb21wb3NlIGFuZCBzZW5kIGEgbWVzc2FnZSwgYW5kIGxvZ291dC4KKzwvRk9OVD4KKworPFA+PEI+PEk+PEZPTlQgRkFDRT0iQXJpYWwsIEhlbHZldGljYSI+RmVhdHVyZXM6PC9GT05UPjwvST48L0I+PC9QPgorCis8VUw+CisJPExJPjxGT05UIFNJWkU9IjIiIEZBQ0U9IkFyaWFsLCBIZWx2ZXRpY2EiPkhUTUwgYWNjZXNzIHRvIHlvdXIgSU1BUCBtYWlsYm94PC9GT05UPgorCTxMST48Rk9OVCBTSVpFPSIyIiBGQUNFPSJBcmlhbCwgSGVsdmV0aWNhIj5Qcm94eS1hYmxlIGFueXdoZXJlIEhUVFAgY2FuIGJlIHByb3hpZWQ8L0ZPTlQ+CisJPExJPjxGT05UIFNJWkU9IjIiIEZBQ0U9IkFyaWFsLCBIZWx2ZXRpY2EiPkVhc3kgdG8gdXNlPC9GT05UPgorCTxMST48Rk9OVCBTSVpFPSIyIiBGQUNFPSJBcmlhbCwgSGVsdmV0aWNhIj5Vc2VzIHdlYiBicm93c2VyJ3MgY29udGVudCBoYW5kbGluZyBjYXBhYmlsaXRpZXM8L0ZPTlQ+Cis8L1VMPgorCis8UD48Qj48ST48Rk9OVCBGQUNFPSJBcmlhbCwgSGVsdmV0aWNhIj5MaW1pdGF0aW9uczo8L0ZPTlQ+PC9JPjwvQj48L1A+CisKKzxVTD4KKwk8TEk+PEZPTlQgU0laRT0iMiIgRkFDRT0iQXJpYWwsIEhlbHZldGljYSI+T25seSBJTkJPWCBzdXBwb3J0IChubyB1c2VyIGZvbGRlcnMpPC9GT05UPgorCTxMST48Rk9OVCBTSVpFPSIyIiBGQUNFPSJBcmlhbCwgSGVsdmV0aWNhIj5DYW4ndCBkZWxldGUsIGNvcHksIG1vdmUsIHByaW50LCBzYXZlLCBmb3J3YXJkLCByZXBseSB0bywgc2VhcmNoIGluCisJbWVzc2FnZXMgLS08QlI+CisJYnV0IGl0IGNvdWxkIGJlIGRvbmU8L0ZPTlQ+CisJPExJPjxGT05UIFNJWkU9IjIiIEZBQ0U9IkFyaWFsLCBIZWx2ZXRpY2EiPkRvZXNuJ3QgY2hlY2sgZm9yIG5ldyBtZXNzYWdlcyAoaGF2ZSB0byBsb2cgb3V0IGFuZCBsb2cgYmFjayBpdCk8L0ZPTlQ+Cis8L1VMPgorCis8UD4KKzxIUiBBTElHTj0iQ0VOVEVSIj4KKzwvUD4KKworPFA+PEZPTlQgRkFDRT0iQXJpYWwsIEhlbHZldGljYSI+RmVlZGJhY2sgdG8gPC9GT05UPjxBIEhSRUY9Im1haWx0bzpqYXZhbWFpbF93d0BvcmFjbGUuY29tIj48Rk9OVCBGQUNFPSJBcmlhbCwgSGVsdmV0aWNhIj5qYXZhbWFpbF93d0BvcmFjbGUuY29tPC9GT05UPjwvQT4KKzwvRk9STT4KKworPC9CT0RZPgorCis8L0hUTUw+CmRpZmYgLS1naXQgYS93ZWJhcHAvc3JjL21haW4vd2ViYXBwL2xvZ2luLmpzcCBiL3dlYmFwcC9zcmMvbWFpbi93ZWJhcHAvbG9naW4uanNwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM5Yjc3MDIKLS0tIC9kZXYvbnVsbAorKysgYi93ZWJhcHAvc3JjL21haW4vd2ViYXBwL2xvZ2luLmpzcApAQCAtMCwwICsxLDM1IEBACis8JS0tCisKKyAgICBDb3B5cmlnaHQgKGMpIDIwMDEsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKworICAgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICAgIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9vcmcvZG9jdW1lbnRzL2VkbC12MTAucGhwLgorCisgICAgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorCistLSU+CisKKzwlQCBwYWdlIGxhbmd1YWdlPSJqYXZhIiBpbXBvcnQ9ImRlbW8uTWFpbFVzZXJCZWFuIiAlPgorPCVAIHBhZ2UgZXJyb3JQYWdlPSJlcnJvcnBhZ2UuanNwIiAlPgorPGpzcDp1c2VCZWFuIGlkPSJtYWlsdXNlciIgc2NvcGU9InNlc3Npb24iIGNsYXNzPSJkZW1vLk1haWxVc2VyQmVhbiIgLz4KKworPGh0bWw+Cis8aGVhZD4KKyAgICA8dGl0bGU+SmF2YU1haWwgbG9naW48L3RpdGxlPgorPC9oZWFkPgorCQorPGJvZHkgYmdjb2xvcj0id2hpdGUiPgorCQorPCUKKyAgICBtYWlsdXNlci5sb2dpbihyZXF1ZXN0LmdldFBhcmFtZXRlcigiaG9zdG5hbWUiKSwKKyAgICAgICAgICAgICAgICAgICByZXF1ZXN0LmdldFBhcmFtZXRlcigidXNlcm5hbWUiKSwKKyAgICAgICAgICAgICAgICAgICByZXF1ZXN0LmdldFBhcmFtZXRlcigicGFzc3dvcmQiKSk7CisgICAgc2Vzc2lvbi5zZXRBdHRyaWJ1dGUoImZvbGRlciIsIG1haWx1c2VyLmdldEZvbGRlcigpKTsKKyU+CisKKzxqc3A6Zm9yd2FyZCBwYWdlPSJmb2xkZXJzLmpzcCIgLz4KKworPC9ib2R5PgorPC9odG1sPgorCmRpZmYgLS1naXQgYS93ZWJhcHAvc3JjL21haW4vd2ViYXBwL2xvZ291dC5qc3AgYi93ZWJhcHAvc3JjL21haW4vd2ViYXBwL2xvZ291dC5qc3AKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDIxN2U5OAotLS0gL2Rldi9udWxsCisrKyBiL3dlYmFwcC9zcmMvbWFpbi93ZWJhcHAvbG9nb3V0LmpzcApAQCAtMCwwICsxLDI4IEBACis8JS0tCisKKyAgICBDb3B5cmlnaHQgKGMpIDIwMDEsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKworICAgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICAgIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9vcmcvZG9jdW1lbnRzL2VkbC12MTAucGhwLgorCisgICAgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorCistLSU+CisKKzwlQCBwYWdlIGxhbmd1YWdlPSJqYXZhIiBpbXBvcnQ9ImRlbW8uTWFpbFVzZXJCZWFuIiAlPgorPCVAIHBhZ2UgZXJyb3JQYWdlPSJlcnJvcnBhZ2UuanNwIiAlPgorPGpzcDp1c2VCZWFuIGlkPSJtYWlsdXNlciIgc2NvcGU9InNlc3Npb24iIGNsYXNzPSJkZW1vLk1haWxVc2VyQmVhbiIgLz4KKworPGh0bWw+Cis8aGVhZD4KKwk8dGl0bGU+SmF2YU1haWwgbG9nb3V0PC90aXRsZT4KKzwvaGVhZD4KKworPCUgbWFpbHVzZXIubG9nb3V0KCk7ICU+CisKKzxib2R5PgorPGgyPkxvZ2dlZCBvdXQgT0s8L2gyPjxhIGhyZWY9aW5kZXguaHRtbD5jbGljayBoZXJlIHRvIGxvZ2luPC9hPgorPC9ib2R5PgorPC9odG1sPgorCmRpZmYgLS1naXQgYS93ZWJhcHAvc3JjL21haW4vd2ViYXBwL21lc3NhZ2Vjb250ZW50LmpzcCBiL3dlYmFwcC9zcmMvbWFpbi93ZWJhcHAvbWVzc2FnZWNvbnRlbnQuanNwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ3NWM5YWYKLS0tIC9kZXYvbnVsbAorKysgYi93ZWJhcHAvc3JjL21haW4vd2ViYXBwL21lc3NhZ2Vjb250ZW50LmpzcApAQCAtMCwwICsxLDk2IEBACis8JS0tCisKKyAgICBDb3B5cmlnaHQgKGMpIDIwMDEsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKworICAgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICAgIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9vcmcvZG9jdW1lbnRzL2VkbC12MTAucGhwLgorCisgICAgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorCistLSU+CisKKzwlQCBwYWdlIGxhbmd1YWdlPSJqYXZhIiBpbXBvcnQ9ImRlbW8uTWVzc2FnZUluZm8sIGRlbW8uQXR0YWNobWVudEluZm8iICU+Cis8JUAgcGFnZSBlcnJvclBhZ2U9ImVycm9ycGFnZS5qc3AiICU+Cis8JUAgdGFnbGliIHVyaT0iaHR0cDovL2phdmEuc3VuLmNvbS9wcm9kdWN0cy9qYXZhbWFpbC9kZW1vL3dlYmFwcCIgCisgICAgcHJlZml4PSJqYXZhbWFpbCIgJT4KKyAKKworPGh0bWw+Cis8aGVhZD4KKyAgICA8dGl0bGU+SmF2YU1haWwgbWVzc2FnZWNvbnRlbnQ8L3RpdGxlPgorPC9oZWFkPgorCis8amF2YW1haWw6bWVzc2FnZSAKK2lkPSJtc2dpbmZvIgorZm9sZGVyPSJmb2xkZXIiCitudW09IjwlPSByZXF1ZXN0LmdldFBhcmFtZXRlcihcIm1lc3NhZ2VcIikgJT4iIAorLz4KKworPGJvZHkgYmdjb2xvcj0iI2NjY2NmZiI+Cis8Y2VudGVyPjxmb250IGZhY2U9IkFyaWFsLEhlbHZldGljYSIgZm9udCBzaXplPSIrMyI+Cis8Yj5NZXNzYWdlPHNwPiAKKzxzcD5pbiBmb2xkZXIgL0lOQk9YPC9iPjwvZm9udD48L2NlbnRlcj48cD4KKworPCUtLSBmaXJzdCwgZGlzcGxheSB0aGlzIG1lc3NhZ2UncyBoZWFkZXJzIC0tJT4KKzxiPkRhdGU6PC9iPgorPCU9IG1zZ2luZm8uZ2V0U2VudERhdGUoKSAlPgorPGJyPgorPCUgaWYgKG1zZ2luZm8uaGFzRnJvbSgpKSB7ICU+Cis8Yj5Gcm9tOjwvYj4KKzxhIGhyZWY9ImNvbXBvc2U/dG89PCU9IG1zZ2luZm8uZ2V0UmVwbHlUbygpICU+IgorICAgIHRhcmdldD0icmVwbHk8JT0gbXNnaW5mby5nZXROdW0oKSAlPiI+Cis8JT0gbXNnaW5mby5nZXRGcm9tKCkgJT4KKzwvYT4KKzxicj4KKzwlIH0gJT4KKworPCUgaWYgKG1zZ2luZm8uaGFzVG8oKSkgeyAlPgorPGI+VG86PC9iPgorPCU9IG1zZ2luZm8uZ2V0VG8oKSAlPgorPGJyPgorPCUgfSAlPiAgIAorCis8JSBpZiAobXNnaW5mby5oYXNDYygpKSB7ICU+Cis8Yj5DQzo8L2I+Cis8JT0gbXNnaW5mby5nZXRDYygpICU+Cis8YnI+Cis8JSB9ICU+CisKKzxiPlN1YmplY3Q6PC9iPgorPCUgaWYgKG1zZ2luZm8uaGFzU3ViamVjdCgpKSB7ICU+Cis8JT0gbXNnaW5mby5nZXRTdWJqZWN0KCkgJT4KKzwlIH0gJT4KKzxicj4KKzxwcmU+Cis8JT0gbXNnaW5mby5nZXRCb2R5KCkgJT4KKzwvcHJlPgorPCUgaWYgKG1zZ2luZm8uaGFzQXR0YWNobWVudHMoKSkgeyAlPgorPGphdmFtYWlsOmxpc3RhdHRhY2htZW50cworIGlkPSJhdHRhY2htZW50IgorIG1lc3NhZ2VpbmZvPSJtc2dpbmZvIj4KKzxwPjxocj4KKzxiPkF0dGFjaG1lbnQgVHlwZTo8L2I+Cis8JT0gYXR0YWNobWVudC5nZXRBdHRhY2htZW50VHlwZSgpICU+Cis8YnI+Cis8JSBpZiAoYXR0YWNobWVudC5oYXNNaW1lVHlwZSgidGV4dC9wbGFpbiIpICYmIAorICAgICAgIGF0dGFjaG1lbnQuaXNJbmxpbmUoKSl7ICU+Cis8cHJlPgorPCU9IGF0dGFjaG1lbnQuZ2V0Q29udGVudCgpICU+Cis8L3ByZT4KKzwlIH0gZWxzZSB7ICU+Cis8Yj5GaWxlbmFtZTo8L2I+Cis8JT0gYXR0YWNobWVudC5nZXRGaWxlbmFtZSgpICU+Cis8YnI+Cis8Yj5EZXNjcmlwdGlvbjo8L2I+Cis8JT0gYXR0YWNobWVudC5nZXREZXNjcmlwdGlvbigpICU+Cis8YnI+Cis8YSBocmVmPSJhdHRhY2htZW50P21lc3NhZ2U9Cis8JT0gbXNnaW5mby5nZXROdW0oKSAlPiZwYXJ0PTwlPSBhdHRhY2htZW50LmdldE51bSgpICU+Ij4KK0Rpc3BsYXkgQXR0YWNobWVudDwvYT4KKzwlIH0gJT4KKzwvamF2YW1haWw6bGlzdGF0dGFjaG1lbnRzPgorPCUgfSAlPgorPC9ib2R5PgorPC9odG1sPgorCmRpZmYgLS1naXQgYS93ZWJhcHAvc3JjL21haW4vd2ViYXBwL21lc3NhZ2VoZWFkZXJzLmpzcCBiL3dlYmFwcC9zcmMvbWFpbi93ZWJhcHAvbWVzc2FnZWhlYWRlcnMuanNwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJmNmRmZGQKLS0tIC9kZXYvbnVsbAorKysgYi93ZWJhcHAvc3JjL21haW4vd2ViYXBwL21lc3NhZ2VoZWFkZXJzLmpzcApAQCAtMCwwICsxLDgyIEBACis8JS0tCisKKyAgICBDb3B5cmlnaHQgKGMpIDIwMDEsIDIwMTggT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKworICAgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQorICAgIHRlcm1zIG9mIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCwgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CisgICAgaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9vcmcvZG9jdW1lbnRzL2VkbC12MTAucGhwLgorCisgICAgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZQorCistLSU+CisKKzwlQCBwYWdlIGxhbmd1YWdlPSJqYXZhIiBpbXBvcnQ9ImRlbW8uTWVzc2FnZUluZm8iICU+Cis8JUAgcGFnZSBlcnJvclBhZ2U9ImVycm9ycGFnZS5qc3AiICU+Cis8JUAgdGFnbGliIHVyaT0iaHR0cDovL2phdmEuc3VuLmNvbS9wcm9kdWN0cy9qYXZhbWFpbC9kZW1vL3dlYmFwcCIgCisgICAgcHJlZml4PSJqYXZhbWFpbCIgJT4KKworPGh0bWw+Cis8aGVhZD4KKwk8dGl0bGU+SmF2YU1haWwgbWVzc2FnZWhlYWRlcnM8L3RpdGxlPgorPC9oZWFkPgorCis8Ym9keSBiZ2NvbG9yPSIjY2NjY2ZmIj48aHI+CisgICAgCis8Y2VudGVyPjxmb250IGZhY2U9IkFyaWFsLEhlbHZldGljYSIgZm9udCBzaXplPSIrMyI+Cis8Yj5Gb2xkZXIgSU5CT1g8L2I+PC9mb250PjwvY2VudGVyPjxwPgorICAgCis8Zm9udCBmYWNlPSJBcmlhbCxIZWx2ZXRpY2EiIGZvbnQgc2l6ZT0iKzMiPgorPGI+PGEgaHJlZj0ibG9nb3V0Ij5Mb2dvdXQ8L2E+Cis8YSBocmVmPSJjb21wb3NlIiB0YXJnZXQ9ImNvbXBvc2UiPkNvbXBvc2U8L2E+Cis8L2I+PC9mb250PgorPGhyPgorICAgIAorPHRhYmxlIGNlbGxwYWRkaW5nPTEgY2VsbHNwYWNpbmc9MSB3aWR0aD0iMTAwJSIgYm9yZGVyPTE+Cis8dHI+Cis8dGQgd2lkdGg9IjI1JSIgYmdjb2xvcj0iZmZmZmNjIj4KKzxmb250IGZhY2U9IkFyaWFsLEhlbHZldGljYSIgZm9udCBzaXplPSIrMSI+Cis8Yj5TZW5kZXI8L2I+PC9mb250PjwvdGQ+Cis8dGQgd2lkdGg9IjE1JSIgYmdjb2xvcj0iZmZmZmNjIj4KKzxmb250IGZhY2U9IkFyaWFsLEhlbHZldGljYSIgZm9udCBzaXplPSIrMSI+Cis8Yj5EYXRlPC9iPjwvZm9udD48L3RkPgorPHRkIGJnY29sb3I9ImZmZmZjYyI+Cis8Zm9udCBmYWNlPSJBcmlhbCxIZWx2ZXRpY2EiIGZvbnQgc2l6ZT0iKzEiPgorPGI+U3ViamVjdDwvYj48L2ZvbnQ+PC90ZD4KKzwvdHI+Cis8amF2YW1haWw6bGlzdG1lc3NhZ2VzCisgaWQ9Im1zZ2luZm8iCisgZm9sZGVyPSJmb2xkZXIiPgorPCUtLSBmcm9tIC0tJT4KKzx0ciB2YWxpZ249bWlkZGxlPgorPHRkIHdpZHRoPSIyNSUiIGJnY29sb3I9ImZmZmZmZiI+Cis8Zm9udCBmYWNlPSJBcmlhbCxIZWx2ZXRpY2EiPgorPCUgaWYgKG1zZ2luZm8uaGFzRnJvbSgpKSB7ICU+Cis8JT0gbXNnaW5mby5nZXRGcm9tKCkgJT4KKzwvZm9udD4KKzwlIH0gZWxzZSB7ICU+Cis8Zm9udCBmYWNlPSJBcmlhbCxIZWx2ZXRpY2Esc2Fucy1zZXJpZiI+CitVbmtub3duCis8JSB9ICU+Cis8L2ZvbnQ+PC90ZD4KKzwlLS0gZGF0ZSAtLSU+Cis8dGQgbm93cmFwIHdpZHRoPSIxNSUiIGJnY29sb3I9ImZmZmZmZiI+Cis8Zm9udCBmYWNlPSJBcmlhbCxIZWx2ZXRpY2EiPgorPCU9IG1zZ2luZm8uZ2V0RGF0ZSgpICU+Cis8L2ZvbnQ+PC90ZD4KKzwlLS0gc3ViamVjdCAmIGxpbmsgLS0lPgorPHRkIGJnY29sb3I9ImZmZmZmZiI+Cis8Zm9udCBmYWNlPSJBcmlhbCxIZWx2ZXRpY2EiPgorPGEgaHJlZj0ibWVzc2FnZWNvbnRlbnQ/bWVzc2FnZT08JT0gbXNnaW5mby5nZXROdW0oKSAlPiI+Cis8JSBpZiAobXNnaW5mby5oYXNTdWJqZWN0KCkpIHsgJT4KKzwlPSAgICBtc2dpbmZvLmdldFN1YmplY3QoKSAlPgorPCUgfSBlbHNlIHsgJT4KKzxpPk5vIFN1YmplY3Q8L2k+Cis8JSB9ICU+Cis8L2E+Cis8L2ZvbnQ+PC90ZD4KKzwvdHI+Cis8L2phdmFtYWlsOmxpc3RtZXNzYWdlcz4KKzwvdGFibGU+Cis8L2JvZHk+Cis8L2h0bWw+CisKZGlmZiAtLWdpdCBhL3dlYmFwcC9zcmMvbWFpbi93ZWJhcHAvc2VuZC5qc3AgYi93ZWJhcHAvc3JjL21haW4vd2ViYXBwL3NlbmQuanNwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZlZjAwYTkKLS0tIC9kZXYvbnVsbAorKysgYi93ZWJhcHAvc3JjL21haW4vd2ViYXBwL3NlbmQuanNwCkBAIC0wLDAgKzEsMzYgQEAKKzwlLS0KKworICAgIENvcHlyaWdodCAoYykgMjAwMSwgMjAxOCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorCisgICAgVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCisgICAgdGVybXMgb2YgdGhlIEVjbGlwc2UgRGlzdHJpYnV0aW9uIExpY2Vuc2Ugdi4gMS4wLCB3aGljaCBpcyBhdmFpbGFibGUgYXQKKyAgICBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZWRsLXYxMC5waHAuCisKKyAgICBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQlNELTMtQ2xhdXNlCisKKy0tJT4KKworPCVAIHBhZ2UgbGFuZ3VhZ2U9ImphdmEiICU+Cis8JUAgcGFnZSBlcnJvclBhZ2U9ImVycm9ycGFnZS5qc3AiICU+Cis8JUAgdGFnbGliIHVyaT0iaHR0cDovL2phdmEuc3VuLmNvbS9wcm9kdWN0cy9qYXZhbWFpbC9kZW1vL3dlYmFwcCIgCisgICAgcHJlZml4PSJqYXZhbWFpbCIgJT4KKyAKKzxodG1sPgorPGhlYWQ+CisJPHRpdGxlPkphdmFNYWlsIHNlbmQ8L3RpdGxlPgorPC9oZWFkPgorCQorPGJvZHkgYmdjb2xvcj0id2hpdGUiPgorPGphdmFtYWlsOnNlbmRtYWlsIAorICAgcmVjaXBpZW50cz0iPCU9IHJlcXVlc3QuZ2V0UGFyYW1ldGVyKFwidG9cIikgJT4iCisgICBzZW5kZXI9IjwlPSByZXF1ZXN0LmdldFBhcmFtZXRlcihcImZyb21cIikgJT4iCisgICBzdWJqZWN0PSI8JT0gcmVxdWVzdC5nZXRQYXJhbWV0ZXIoXCJzdWJqZWN0XCIpICU+IgorPgorPCU9IHJlcXVlc3QuZ2V0UGFyYW1ldGVyKCJ0ZXh0IikgJT4KKzwvamF2YW1haWw6c2VuZG1haWw+CisJICAgIAorPGgxPk1lc3NhZ2Ugc2VudCBzdWNjZXNzZnVsbHk8L2gxPgorCQorPC9ib2R5PgorPC9odG1sPgorCmRpZmYgLS1naXQgYS93ZWJhcHAvd2ViYXBwLlJFQURNRS50eHQgYi93ZWJhcHAvd2ViYXBwLlJFQURNRS50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmE5MDY5NwotLS0gL2Rldi9udWxsCisrKyBiL3dlYmFwcC93ZWJhcHAuUkVBRE1FLnR4dApAQCAtMCwwICsxLDE4OSBAQAorVGhpcyBkZW1vIGlsbHVzdHJhdGVzIHRoZSB1c2Ugb2YgSmF2YU1haWwgQVBJcyBpbiBhIDMtdGllcmVkIHdlYiAKK2FwcGxpY2F0aW9uLiBJdCBtdXN0IGJlIGRlcGxveWVkIG9uIGEgd2ViIHNlcnZlciB0aGF0IHN1cHBvcnRzCitzZXJ2bGV0IGFuZCBKU1AtYmFzZWQgd2ViIGFwcGxpY2F0aW9ucyAoZS5nLiBUb21jYXQpIHVzaW5nIGF0IGxlYXN0CitKMlNFIDEuMyBhbmQgU2VydmxldCAyLjIuCisKKwkrLS0tLS0tLS0tLS0rICAgICAgICArLS0tLS0tLS0tLS0rICAgICAgICArLS0tLS0tLS0tLS0rCisJfCAgIElNQVAgICAgfCAgICAgICAgfCAgICAgICAgICAgfCAgICAgICAgfCAgICAgICAgICAgfAorCXwgIFNlcnZlciAgIHw8LUlNQVAtPnwgSmF2YU1haWwgIHw8LUhUVFAtPnwgICAgV1dXICAgIHwKKwkrLS0tLS0tLS0tLS0rICAgICAgICB8IFdlYiBhcHAgICB8LS1IVE1MLT58ICBCcm93c2VyICB8CisJfCAgIFNNVFAgICAgfDwtU01UUC0+fCAgICAgICAgICAgfCAgICAgICAgfCAgICAgICAgICAgfAorCXwgIFNlcnZlciAgIHwgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgIHwgICAgICAgICAgIHwKKwkrLS0tLS0tLS0tLS0rICAgICAgICArLS0tLS0tLS0tLS0rICAgICAgICArLS0tLS0tLS0tLS0rCisKKworVGhlIEphdmFNYWlsIFdlYiBhcHBsaWNhdGlvbiBzdXBwb3J0cyB0aGUgZm9sbG93aW5nIGZ1bmN0aW9uYWxpdHk6CisJKiBsb2dpbiB0byBhbiBJTUFQIHNlcnZlcgorCSogbGlzdCBhbGwgdGhlIG1lc3NhZ2VzIGluIHRoZSBJTkJPWCBmb2xkZXIKKwkqIHZpZXcgdGhlIHNlbGVjdGVkIG1lc3NhZ2UKKwkqIGNvbXBvc2UgYW5kIHNlbmQgYSBtZXNzYWdlCisKK0l0IGlzIGNvbXByaXNlZCBvZiBhbiBIVE1MIGRvY3VtZW50IGFuZCBzZXZlcmFsIFdlYiBjb21wb25lbnRzIAorKHNlcnZsZXRzLCBKU1AgcGFnZXMgYW5kIGN1c3RvbSB0YWdzKSBhbmQgaXMgcGFja2FnZWQgaW4gYSBXZWIgCithcmNoaXZlIHdpdGggdGhlIGZvbGxvd2luZyBjb250ZW50czoKKworCWluZGV4Lmh0bWwKKwlsb2dpbi5qc3AKKwlmb2xkZXJzLmpzcAorCW1lc3NhZ2VoZWFkZXJzLmpzcAorCW1lc3NhZ2Vjb250ZW50LmpzcAorCWNvbXBvc2UuanNwCisJc2VuZC5qc3AKKwllcnJvcnBhZ2UuanNwCisJZXJyb3JkZXRhaWxzLmpzcAorCWxvZ291dC5qc3AKKwlXRUItSU5GLworCVdFQi1JTkYvY2xhc3Nlcy8KKwlXRUItSU5GL2NsYXNzZXMvZGVtby9BdHRhY2htZW50U2VydmxldC5jbGFzcworCVdFQi1JTkYvY2xhc3Nlcy9kZW1vL0ZpbHRlclNlcnZsZXQuY2xhc3MKKwlXRUItSU5GL2NsYXNzZXMvZGVtby9NYWlsVXNlckJlYW4uY2xhc3MKKwlXRUItSU5GL2xpYi8KKwlXRUItSU5GL2xpYi9qdGwuamFyCisJV0VCLUlORi93ZWIueG1sCisJCisKKworCisKKworCisKKworCisKK1RoZSBjb2xsZWN0aW9uIG9mIC5odG1sIGFuZCAuanNwIGZpbGVzIHByb3ZpZGUgdGhlIGNsaWVudC1zaWRlIHZpZXcgCitvZiB0aGUgSmF2YU1haWwgV2ViIGFwcGxpY2F0aW9uLiAKKworCSAgaW5kZXguaHRtbAorCSAgICAgIHwKKwkgIGxvZ2luLmpzcAorCSAgICAgIHwKKyAgICAgICAgIGZvbGRlcnMuanNwCisJICAgICAgfAorICAgICAgbWVzc2FnZWhlYWRlcnMuanNwCisJICAgICAgfAorICAgICAgICAgICAgIC8gXAorICAgICAgICAgICAgLyAgIFwKKyAgICBjb21wb3NlLmpzcCAgbWVzc2FnZWNvbnRlbnQuanNwCisgICAgICAgICB8CisgICAgIHNlbmQuanNwCisKKworVGhlIFdFQi1JTkYvd2ViLnhtbCBmaWxlIGNvbnRhaW5zIHRoZSB3ZWIgYXBwbGljYXRpb25zIGRlcGxveW1lbnQKK2Rlc2NyaXB0b3IuIEl0IGlzIGFuIFhNTCBkb2N1bWVudCB0aGF0IGNvbnRhaW5zIGNvbmZpZ3VyYXRpb24gYW5kCitkZXBsb3ltZW50IGluZm9ybWF0aW9uIGZvciB0aGUgYXBwbGljYXRpb24uCisKK0FzIHBlciB0aGUgU2VydmxldCBzcGVjaWZpY2F0aW9uLCB0aGUgV0VCLUlORi9jbGFzc2VzIGRpcmVjdG9yeQorY29udGFpbnMgc2VydmxldCBhbmQgdXRpbGl0eSBjbGFzc2VzIHVzZWQgYnkgdGhlIHdlYiBhcHBsaWNhdGlvbi4KK1RoZSBGaWx0ZXJTZXJ2bGV0IGFjdHMgYXMgdGhlIENvbnRyb2xsZXIgb2YgdGhlIEphdmFNYWlsIFdlYiAKK2FwcGxpY2F0aW9uLiBBbGwgcmVxdWVzdHMgYXJlIG1hcHBlZCB0byB0aGlzIHNlcnZsZXQuIEl0IGNoZWNrcwordG8gc2VlIHRoYXQgdGhlIHVzZXIgaXMgbG9nZ2VkIGluIHRvIHRoZSBzZXJ2ZXIgYmVmb3JlIGZvcndhcmRpbmcgdGhlCityZXF1ZXN0IHRvIHRoZSBhcHByb3ByaWF0ZSBKU1AgcGFnZS4gVGhlIEF0dGFjaG1lbnRTZXJ2bGV0IGlzIHVzZWQKK3RvIHJlbmRlciBub24tdGV4dCBhdHRhY2htZW50cyBhbmQgdGhlIE1haWxVc2VyQmVhbiBpcyBhIHV0aWxpdHkgY2xhc3MKK3VzZWQgdG8gbWFpbnRhaW4gaW5mb3JtYXRpb24gYWJvdXQgdGhlIG1haWwgdXNlci4KKworVGhlIFdFQi1JTkYvbGliIGRpcmVjdG9yeSAoYWxzbyBkZWZpbmVkIGluIHRoZSBTZXJ2bGV0IHNwZWNpZmljYXRpb24pCitjb250YWlucyB0aGUgSmF2YSBhcmNoaXZlIGZpbGUgZm9yIHRoZSBqYXZhbWFpbCBjdXN0b20gdGFnIGxpYnJhcnkuCisKK1RoZSBmb2xsb3cgdGFncyBhcmUgZnVybmlzaGVkIGluIHRoZSBqYXZhbWFpbCB0YWcgbGlicmFyeToKKworPGphdmFtYWlsOnNlbmRtYWlsIAorIG1haWx1c2VyPSJtYWlsdXNlcmJlYW4iCisgW2hvc3Q9Imhvc3RuYW1lIl0gW3BvcnQ9InBvcnQiXQorIHNlbmRlcj0iZW1haWwgYWRkcmVzcyIgcmVjaXBpZW50PSJlbWFpbCBhZGRyZXNzIiAKKyBbY2M9ImVtYWlsIGFkZHJlc3MiXSBbYmNjPSJlbWFpbCBhZGRyZXNzIl0gW3N1YmplY3Q9InN1YmplY3QiXT4KK2JvZHkgb2YgdGhlIG1lc3NhZ2UKKzwvamF2YW1haWw6c2VuZG1haWw+CisKK0Rlc2NyaXB0aW9uOiBVc2VkIHRvIHNlbmQgbWVzc2FnZXMuCisKKworPGphdmFtYWlsOm1lc3NhZ2UgaWQ9Im1lc3NhZ2VpbmZvIgorIGZvbGRlcj0iZm9sZGVyIgorIG51bT0ibWVzc2FnZSBudW1iZXIiLz4KKworRGVzY3JpcHRpb246IFVzZWQgdG8gcmVhZCBhIHNpbmdsZSBtZXNzYWdlLgorCisKKzxqYXZhbWFpbDpsaXN0bWVzc2FnZXMgaWQ9Im1haWxpbmZvYmVhbiIKKyBmb2xkZXI9ImZvbGRlciIKKzwvamF2YW1haWw6bGlzdG1lc3NhZ2VzPgorCitEZXNjcmlwdGlvbjogVXNlZCB0byBpdGVyYXRlIHRocm91Z2ggbGlzdCBvZiBtZXNzYWdlcy4gVGhlIGJvZHkgb2YgdGhlIAordGFnIGlzIHJlcGVhdGVkIGZvciBlYWNoIG1lc3NhZ2UgaW4gdGhlIGxpc3QuCisKKworCisKKworCisKKworCisKKworQnVpbGRpbmcgYW5kIFBhY2thZ2luZyB0aGUgSmF2YU1haWwgV2ViIGFwcGxpY2F0aW9uCisKK0FsbCBzb3VyY2UgZm9yIHRoaXMgZGVtbyBjYW4gYmUgZm91bmQgaW4gdGhlIGZvbGxvd2luZyBkaXJlY3RvcmllczoKKwlzcmMvY2xhc3NlcworCXNyYy9kb2Nyb290CisJc3JjL3RhZ2xpYgorCitCdWlsZCBzY3JpcHRzIChidWlsZC5zaCBhbmQgYnVpbGQuYmF0KSBhcmUgcHJvdmlkZWQgZm9yIGJ1aWxkaW5nIGFuZAorcGFja2FnaW5nIHRoZSBkZW1vLiBCZWZvcmUgZXhlY3V0aW5nIHRoZSBidWlsZCBzY3JpcHRzLCBiZSBzdXJlIHRoYXQgCit0aGUgZm9sbG93aW5nIGFyZSBpbiB5b3VyIENMQVNTUEFUSDoKKwltYWlsLmphcgkJdGhlIEphdmFNYWlsIGphciBmaWxlCisJYWN0aXZhdGlvbi5qYXIJCXRoZSBKQUYgamFyIGZpbGUKKwlzZXJ2bGV0LmphcgkJdGhlIHNlcnZsZXQvSlNQIGphciBmaWxlCisKK1RoZSBmb2xsb3dpbmcgc3RlcHMgYXJlIHBlcmZvcm1lZCB3aGVuIGJ1aWxkaW5nIGFuZCBwYWNrYWdpbmcgdGhlIGRlbW8uCisKKzEuIENyZWF0ZSBhIGRpcmVjdG9yeSBuYW1lZCAic3JjL2RvY3Jvb3QvV0VCLUlORi9jbGFzc2VzL2RlbW8iLgorCisyLiBDcmVhdGUgYSBkaXJlY3RvcnkgbmFtZWQgInNyYy9kb2Nyb290L1dFQi1JTkYvbGliIi4KKworMy4gQ29tcGlsZSB0aGUgZmlsZXMgZnJvbSB0aGUgInNyYy9jbGFzc2VzL2RlbW8iIGRpcmVjdG9yeSBhbmQgYWRkIHRoZW0KKyAgIHRvICJzcmMvZG9jcm9vdC9XRUItSU5GL2NsYXNzZXMvZGVtbyIuCisKKzQuIENvbXBpbGUgdGhlIGZpbGVzIGZyb20gdGhlICJzcmMvdGFibGliIiBkaXJlY3RvcnkuCisKKzUuIENyZWF0ZSBhbiBhcmNoaXZlIChqdGwuamFyKSBvZiB0aGUgdGFnbGliIGNsYXNzZXMgYW5kIGFkZCBpdAorICAgdG8gInNyYy9kb2Nyb290L1dFQi1JTkYvbGliIi4KKworNi4gQ3JlYXRlIGEgd2ViIGFyY2hpdmUgZmlsZSBvZiB0aGUgY29udGVudHMgb2YgInNyYy9kb2Nyb290IiAoYW5kIGFsbAorICAgb2YgaXRzIHN1Yi1kaXJlY3RvcmllcykuCisKKyhGb3IgYSBsaXN0IG9mIHRoZSBjb250ZW50cyBvZiB0aGUgcmVzdWx0aW5nIHdlYiBhcmNoaXZlLAorIHNlZSB0aGUgYmVnaW5uaW5nIG9mIHRoaXMgZG9jdW1lbnQuKQorCisKKworCisKKworCisKKworCisKK0Egbm90ZSBvbiBzZW5kaW5nIG1haWwKKworSW4gb3JkZXIgdG8gc2VuZCBtYWlsIHVzaW5nIHRoZSBKYXZhTWFpbCBXZWIgQXBwLCBpdCBpcyBuZWNlc3NhcnkgdG8gaWRlbnRpZnkKK2FuIFNNVFAgaG9zdC4gVGhpcyBjYW4gYmUgYWNjb21wbGlzaGVkIGluIGEgY291cGxlIG9mIHdheXMuCisKKzEuIFVzZSB0aGUgVE9NQ0FUX09QVFMgZW52aXJvbm1lbnQgdmFyaWFibGUuCisKKyAgIEFkZCB0aGUgZm9sbG93aW5nIHRvIHRoZSBUT01DQVRfT1BUUyBlbnZpcm9ubWVudCB2YXJpYWJsZToKKworCS1EbWFpbC5zbXRwLmhvc3Q9eW91clNNVFBtYWlsc2VydmVybmFtZQorCisgICBSZXN0YXJ0IHlvdXIgd2ViIHNlcnZlci4KKworCisyLiBNb2RpZnkgdGhlIHNlbmQuanNwIGZpbGUgYW5kIHVwZGF0ZSB0aGUgamF2YW1haWwud2FyIGZpbGU6CisKKyAgIEFkZCB0aGUgZm9sbG93aW5nIHBhcmFtZXRlciB0byB0aGUgPGphdmFtYWlsOnNlbmRtYWlsPiB0YWc6CisKKwlob3N0PSJ5b3VyU01UUG1haWxzZXJ2ZXJuYW1lIgorCisgICBSZXBhY2thZ2UgdGhlIGphdmFtYWlsLndhciBmaWxlIHRvIGluY2x1ZGUgdGhlIG1vZGlmaWVkIHNlbmQuanNwIGZpbGUuCg==