LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA1IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAqgKgogKiBDb250cmlidXRvcnM6CiAqICAgIElCTSBDb3Jwb3JhdGlvbiAtIEluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KcGFja2FnZSBvcmcuZWNsaXBzZS5qc3Quc2VydmVyLnRvbWNhdC5jb3JlLmludGVybmFsOwoKaW1wb3J0IGphdmEuaW8uKjsKaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKCmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JRmlsZTsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklGb2xkZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpzdC5zZXJ2ZXIudG9tY2F0LmNvcmUuaW50ZXJuYWwueG1sLkZhY3Rvcnk7CmltcG9ydCBvcmcuZWNsaXBzZS5qc3Quc2VydmVyLnRvbWNhdC5jb3JlLmludGVybmFsLnhtbC5YTUxVdGlsOwppbXBvcnQgb3JnLmVjbGlwc2UuanN0LnNlcnZlci50b21jYXQuY29yZS5pbnRlcm5hbC54bWwuc2VydmVyNDAuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLm9zZ2kudXRpbC5OTFM7CmltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwoKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5TZXJ2ZXJQb3J0OwovKioKICogVG9tY2F0IHY1LjUgc2VydmVyIGNvbmZpZ3VyYXRpb24uCiAqLwpwdWJsaWMgY2xhc3MgVG9tY2F0NTVDb25maWd1cmF0aW9uIGV4dGVuZHMgVG9tY2F0Q29uZmlndXJhdGlvbiB7Cglwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBERUZBVUxUX1NFUlZJQ0UgPSAiQ2F0YWxpbmEiOwoJcHJvdGVjdGVkIFNlcnZlciBzZXJ2ZXI7Cglwcm90ZWN0ZWQgRmFjdG9yeSBzZXJ2ZXJGYWN0b3J5OwoJcHJvdGVjdGVkIGJvb2xlYW4gaXNTZXJ2ZXJEaXJ0eTsKCglwcm90ZWN0ZWQgV2ViQXBwRG9jdW1lbnQgd2ViQXBwRG9jdW1lbnQ7CgoJcHJvdGVjdGVkIERvY3VtZW50IHRvbWNhdFVzZXJzRG9jdW1lbnQ7CgoJcHJvdGVjdGVkIFN0cmluZyBwb2xpY3lGaWxlOwoJcHJvdGVjdGVkIGJvb2xlYW4gaXNQb2xpY3lEaXJ0eTsKCgkvKioKCSAqIFRvbWNhdDU1Q29uZmlndXJhdGlvbiBjb25zdHJ1Y3Rvci4KCSAqIAoJICogQHBhcmFtIHBhdGggYSBwYXRoCgkgKi8KCXB1YmxpYyBUb21jYXQ1NUNvbmZpZ3VyYXRpb24oSUZvbGRlciBwYXRoKSB7CgkJc3VwZXIocGF0aCk7Cgl9CgkKCS8qKgoJICogUmV0dXJucyB0aGUgcm9vdCBvZiB0aGUgZG9jYmFzZSBwYXJhbWV0ZXIuCgkgKgoJICogQHJldHVybiBqYXZhLmxhbmcuU3RyaW5nCgkgKi8KCXByb3RlY3RlZCBTdHJpbmcgZ2V0RG9jQmFzZVJvb3QoKSB7CgkJcmV0dXJuICJ3ZWJhcHBzLyI7Cgl9CgoJLyoqCgkgKiBSZXR1cm4gdGhlIHBvcnQgbnVtYmVyLgoJICogQHJldHVybiBpbnQKCSAqLwoJcHVibGljIFNlcnZlclBvcnQgZ2V0TWFpblBvcnQoKSB7CgkJSXRlcmF0b3IgaXRlcmF0b3IgPSBnZXRTZXJ2ZXJQb3J0cygpLml0ZXJhdG9yKCk7CgkJd2hpbGUgKGl0ZXJhdG9yLmhhc05leHQoKSkgewoJCQlTZXJ2ZXJQb3J0IHBvcnQgPSAoU2VydmVyUG9ydCkgaXRlcmF0b3IubmV4dCgpOwoJCQlpZiAocG9ydC5nZXROYW1lKCkuZXF1YWxzKCJIVFRQIikpCgkJCQlyZXR1cm4gcG9ydDsKCQl9CgkJcmV0dXJuIG51bGw7Cgl9CgkKCS8qKgoJICogUmV0dXJucyB0aGUgbWltZSBtYXBwaW5ncy4KCSAqIEByZXR1cm4gamF2YS51dGlsLkxpc3QKCSAqLwoJcHVibGljIExpc3QgZ2V0TWltZU1hcHBpbmdzKCkgewoJCXJldHVybiB3ZWJBcHBEb2N1bWVudC5nZXRNaW1lTWFwcGluZ3MoKTsKCX0KCQoJLyoqCgkgKiBSZXR1cm5zIHRoZSBwcmVmaXggdGhhdCBpcyB1c2VkIGluIGZyb250IG9mIHRoZQoJICogd2ViIG1vZHVsZSBwYXRoIHByb3BlcnR5LiAoZS5nLiAid2ViYXBwcyIpCgkgKgoJICogQHJldHVybiBqYXZhLmxhbmcuU3RyaW5nCgkgKi8KCXB1YmxpYyBTdHJpbmcgZ2V0UGF0aFByZWZpeCgpIHsKCQlyZXR1cm4gIiI7Cgl9CgkKCS8qKgoJICogUmV0dXJuIHRoZSBkb2NCYXNlIG9mIHRoZSBST09UIHdlYiBtb2R1bGUuCgkgKgoJICogQHJldHVybiBqYXZhLmxhbmcuU3RyaW5nCgkgKi8KCXByb3RlY3RlZCBTdHJpbmcgZ2V0Uk9PVE1vZHVsZURvY0Jhc2UoKSB7CgkJcmV0dXJuICJST09UIjsKCX0KCQoJLyoqCgkgKiBSZXR1cm5zIGEgbGlzdCBvZiBTZXJ2ZXJQb3J0cyB0aGF0IHRoaXMgY29uZmlndXJhdGlvbiB1c2VzLgoJICoKCSAqIEByZXR1cm4gamF2YS51dGlsLkxpc3QKCSAqLwoJcHVibGljIExpc3QgZ2V0U2VydmVyUG9ydHMoKSB7CgkJTGlzdCBwb3J0cyA9IG5ldyBBcnJheUxpc3QoKTsKCQoJCS8vIGZpcnN0IGFkZCBzZXJ2ZXIgcG9ydAoJCXRyeSB7CgkJCWludCBwb3J0ID0gSW50ZWdlci5wYXJzZUludChzZXJ2ZXIuZ2V0UG9ydCgpKTsKCQkJcG9ydHMuYWRkKG5ldyBTZXJ2ZXJQb3J0KCJzZXJ2ZXIiLCBNZXNzYWdlcy5wb3J0U2VydmVyLCBwb3J0LCAiVENQSVAiKSk7CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJLy8gaWdub3JlCgkJfQoJCgkJLy8gYWRkIGNvbm5lY3RvcnMKCQl0cnkgewoJCQlpbnQgc2l6ZSA9IHNlcnZlci5nZXRTZXJ2aWNlQ291bnQoKTsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCVNlcnZpY2Ugc2VydmljZSA9IHNlcnZlci5nZXRTZXJ2aWNlKGkpOwoJCQkJaW50IHNpemUyID0gc2VydmljZS5nZXRDb25uZWN0b3JDb3VudCgpOwoJCQkJZm9yIChpbnQgaiA9IDA7IGogPCBzaXplMjsgaisrKSB7CgkJCQkJQ29ubmVjdG9yIGNvbm5lY3RvciA9IHNlcnZpY2UuZ2V0Q29ubmVjdG9yKGopOwoJCQkJCVN0cmluZyBuYW1lID0gIkhUVFAiOwoJCQkJCVN0cmluZyBwcm90b2NvbDIgPSAiVENQSVAiOwoJCQkJCWJvb2xlYW4gYWR2YW5jZWQgPSB0cnVlOwoJCQkJCVN0cmluZ1tdIGNvbnRlbnRUeXBlcyA9IG51bGw7CgkJCQkJaW50IHBvcnQgPSAtMTsKCQkJCQl0cnkgewoJCQkJCQlwb3J0ID0gSW50ZWdlci5wYXJzZUludChjb25uZWN0b3IuZ2V0UG9ydCgpKTsKCQkJCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQkJCQkvLyBpZ25vcmUKCQkJCQl9CgkJCQkJU3RyaW5nIHByb3RvY29sID0gY29ubmVjdG9yLmdldFByb3RvY29sKCk7CgkJCQkJaWYgKHByb3RvY29sICE9IG51bGwgJiYgcHJvdG9jb2wubGVuZ3RoKCkgPiAwKSB7CgkJCQkJCW5hbWUgPSBwcm90b2NvbDsKCQkJCQkJcHJvdG9jb2wyID0gcHJvdG9jb2w7IAoJCQkJCX0KCQkJCQlpZiAoIkhUVFAiLmVxdWFscyhwcm90b2NvbCkpCgkJCQkJCWNvbnRlbnRUeXBlcyA9IG5ldyBTdHJpbmdbXSB7ICJ3ZWIiLCAid2Vic2VydmljZXMiIH07CgkJCQkJU3RyaW5nIHNlY3VyZSA9IGNvbm5lY3Rvci5nZXRTZWN1cmUoKTsKCQkJCQlpZiAoc2VjdXJlICE9IG51bGwgJiYgc2VjdXJlLmxlbmd0aCgpID4gMCkgewoJCQkJCQluYW1lID0gIlNTTCI7CgkJCQkJCXByb3RvY29sMiA9ICJTU0wiOwoJCQkJCX0gZWxzZQoJCQkJCQlhZHZhbmNlZCA9IGZhbHNlOwoJCQkJCXBvcnRzLmFkZChuZXcgU2VydmVyUG9ydChpICsiLyIgKyBqLCBuYW1lLCBwb3J0LCBwcm90b2NvbDIsIGNvbnRlbnRUeXBlcywgYWR2YW5jZWQpKTsKCQkJCX0KCQkJfQoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIkVycm9yIGdldHRpbmcgc2VydmVyIHBvcnRzIiwgZSk7CgkJfQoJCXJldHVybiBwb3J0czsKCX0KCQoJLyoqCgkgKiBSZXR1cm4gYSBsaXN0IG9mIHRoZSB3ZWIgbW9kdWxlcyBpbiB0aGlzIHNlcnZlci4KCSAqIEByZXR1cm4gamF2YS51dGlsLkxpc3QKCSAqLwoJcHVibGljIExpc3QgZ2V0V2ViTW9kdWxlcygpIHsKCQlMaXN0IGxpc3QgPSBuZXcgQXJyYXlMaXN0KCk7CgkKCQl0cnkgewoJCQlpbnQgc2l6ZSA9IHNlcnZlci5nZXRTZXJ2aWNlQ291bnQoKTsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCVNlcnZpY2Ugc2VydmljZSA9IHNlcnZlci5nZXRTZXJ2aWNlKGkpOwoJCQkJaWYgKHNlcnZpY2UuZ2V0TmFtZSgpLmVxdWFsc0lnbm9yZUNhc2UoREVGQVVMVF9TRVJWSUNFKSkgewoJCQkJCUVuZ2luZSBlbmdpbmUgPSBzZXJ2aWNlLmdldEVuZ2luZSgpOwoJCQkJCUhvc3QgaG9zdCA9IGVuZ2luZS5nZXRIb3N0KCk7CgkJCQkJaW50IHNpemUyID0gaG9zdC5nZXRDb250ZXh0Q291bnQoKTsKCQkJCQlmb3IgKGludCBqID0gMDsgaiA8IHNpemUyOyBqKyspIHsKCQkJCQkJQ29udGV4dCBjb250ZXh0ID0gaG9zdC5nZXRDb250ZXh0KGopOwoJCQkJCQlTdHJpbmcgcmVsb2FkID0gY29udGV4dC5nZXRSZWxvYWRhYmxlKCk7CgkJCQkJCWlmIChyZWxvYWQgPT0gbnVsbCkKCQkJCQkJCXJlbG9hZCA9ICJmYWxzZSI7CgkJCQkJCVdlYk1vZHVsZSBtb2R1bGUgPSBuZXcgV2ViTW9kdWxlKGNvbnRleHQuZ2V0UGF0aCgpLCAKCQkJCQkJCWNvbnRleHQuZ2V0RG9jQmFzZSgpLCBjb250ZXh0LmdldFNvdXJjZSgpLAoJCQkJCQkJcmVsb2FkLmVxdWFsc0lnbm9yZUNhc2UoInRydWUiKSA/IHRydWUgOiBmYWxzZSk7CgkJCQkJCWxpc3QuYWRkKG1vZHVsZSk7CgkJCQkJfQoJCQkJfQoJCQl9CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiRXJyb3IgZ2V0dGluZyBwcm9qZWN0IHJlZnMiLCBlKTsKCQl9CgkJcmV0dXJuIGxpc3Q7Cgl9CgkKCS8qKgoJICogQHNlZSBUb21jYXRDb25maWd1cmF0aW9uI2xvYWQoSVBhdGgsIElQcm9ncmVzc01vbml0b3IpCgkgKi8KCXB1YmxpYyB2b2lkIGxvYWQoSVBhdGggcGF0aCwgSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiB7CgkJdHJ5IHsKCQkJbW9uaXRvciA9IFByb2dyZXNzVXRpbC5nZXRNb25pdG9yRm9yKG1vbml0b3IpOwoJCQltb25pdG9yLmJlZ2luVGFzayhNZXNzYWdlcy5sb2FkaW5nVGFzaywgNSk7CgkJCQoJCQkvLyBjaGVjayBmb3IgY2F0YWxpbmEucG9saWN5IHRvIHZlcmlmeSB0aGF0IHRoaXMgaXMgYSB2NS41IGNvbmZpZwoJCQlJbnB1dFN0cmVhbSBpbiA9IG5ldyBGaWxlSW5wdXRTdHJlYW0ocGF0aC5hcHBlbmQoImNhdGFsaW5hLnBvbGljeSIpLnRvRmlsZSgpKTsKCQkJaW4ucmVhZCgpOwoJCQlpbi5jbG9zZSgpOwoJCQltb25pdG9yLndvcmtlZCgxKTsKCgkJCXNlcnZlckZhY3RvcnkgPSBuZXcgRmFjdG9yeSgpOwoJCQlzZXJ2ZXJGYWN0b3J5LnNldFBhY2thZ2VOYW1lKCJvcmcuZWNsaXBzZS5qc3Quc2VydmVyLnRvbWNhdC5jb3JlLmludGVybmFsLnhtbC5zZXJ2ZXI0MCIpOwoJCQlzZXJ2ZXIgPSAoU2VydmVyKSBzZXJ2ZXJGYWN0b3J5LmxvYWREb2N1bWVudChuZXcgRmlsZUlucHV0U3RyZWFtKHBhdGguYXBwZW5kKCJzZXJ2ZXIueG1sIikudG9GaWxlKCkpKTsKCQkJbW9uaXRvci53b3JrZWQoMSk7CgoJCQl3ZWJBcHBEb2N1bWVudCA9IG5ldyBXZWJBcHBEb2N1bWVudChwYXRoLmFwcGVuZCgid2ViLnhtbCIpKTsKCQkJbW9uaXRvci53b3JrZWQoMSk7CgkJCQoJCQl0b21jYXRVc2Vyc0RvY3VtZW50ID0gWE1MVXRpbC5nZXREb2N1bWVudEJ1aWxkZXIoKS5wYXJzZShuZXcgSW5wdXRTb3VyY2UobmV3IEZpbGVJbnB1dFN0cmVhbShwYXRoLmFwcGVuZCgidG9tY2F0LXVzZXJzLnhtbCIpLnRvRmlsZSgpKSkpOwoJCQltb25pdG9yLndvcmtlZCgxKTsKCQkJCgkJCS8vIGxvYWQgcG9saWN5IGZpbGUKCQkJQnVmZmVyZWRSZWFkZXIgYnIgPSBudWxsOwoJCQl0cnkgewoJCQkJYnIgPSBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IElucHV0U3RyZWFtUmVhZGVyKG5ldyBGaWxlSW5wdXRTdHJlYW0ocGF0aC5hcHBlbmQoImNhdGFsaW5hLnBvbGljeSIpLnRvRmlsZSgpKSkpOwoJCQkJU3RyaW5nIHRlbXAgPSBici5yZWFkTGluZSgpOwoJCQkJcG9saWN5RmlsZSA9ICIiOwoJCQkJd2hpbGUgKHRlbXAgIT0gbnVsbCkgewoJCQkJCXBvbGljeUZpbGUgKz0gdGVtcCArICJcbiI7CgkJCQkJdGVtcCA9IGJyLnJlYWRMaW5lKCk7CgkJCQl9CgkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5XQVJOSU5HLCAiQ291bGQgbm90IGxvYWQgcG9saWN5IGZpbGUiLCBlKTsKCQkJfSBmaW5hbGx5IHsKCQkJCWlmIChiciAhPSBudWxsKQoJCQkJCWJyLmNsb3NlKCk7CgkJCX0KCQkJbW9uaXRvci53b3JrZWQoMSk7CgkJCQoJCQlpZiAobW9uaXRvci5pc0NhbmNlbGVkKCkpCgkJCQlyZXR1cm47CgkJCW1vbml0b3IuZG9uZSgpOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLldBUk5JTkcsICJDb3VsZCBub3QgbG9hZCBUb21jYXQgdjUuNSBjb25maWd1cmF0aW9uIGZyb20gIiArIHBhdGgudG9PU1N0cmluZygpICsgIjogIiArIGUuZ2V0TWVzc2FnZSgpKTsKCQkJdGhyb3cgbmV3IENvcmVFeGNlcHRpb24obmV3IFN0YXR1cyhJU3RhdHVzLkVSUk9SLCBUb21jYXRQbHVnaW4uUExVR0lOX0lELCAwLCBOTFMuYmluZChNZXNzYWdlcy5lcnJvckNvdWxkTm90TG9hZENvbmZpZ3VyYXRpb24sIHBhdGgudG9PU1N0cmluZygpKSwgZSkpOwoJCX0KCX0KCglwdWJsaWMgdm9pZCBpbXBvcnRGcm9tUGF0aChJUGF0aCBwYXRoLCBib29sZWFuIGlzVGVzdEVudiwgSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiB7CgkJbG9hZChwYXRoLCBtb25pdG9yKTsKCQkKCQkvLyBmb3IgdGVzdCBlbnZpcm9ubWVudCwgcmVtb3ZlIGV4aXN0aW5nIGNvbnRleHRzIHNpbmNlIGEgc2VwYXJhdGUKCQkvLyBjYXRhbGluYS5iYXNlIHdpbGwgYmUgdXNlZAoJCWlmIChpc1Rlc3RFbnYpIHsKCQkJaW50IHNpemUgPSBzZXJ2ZXIuZ2V0U2VydmljZUNvdW50KCk7CgkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQlTZXJ2aWNlIHNlcnZpY2UgPSBzZXJ2ZXIuZ2V0U2VydmljZShpKTsKCQkJCWlmIChzZXJ2aWNlLmdldE5hbWUoKS5lcXVhbHNJZ25vcmVDYXNlKERFRkFVTFRfU0VSVklDRSkpIHsKCQkJCQlIb3N0IGhvc3QgPSBzZXJ2aWNlLmdldEVuZ2luZSgpLmdldEhvc3QoKTsKCQkJCQlpbnQgc2l6ZTIgPSBob3N0LmdldENvbnRleHRDb3VudCgpOwoJCQkJCWZvciAoaW50IGogPSAwOyBqIDwgc2l6ZTI7IGorKykgewoJCQkJCQlob3N0LnJlbW92ZUVsZW1lbnQoIkNvbnRleHQiLCAwKTsKCQkJCQl9CgkJCQl9CgkJCX0KCQl9Cgl9CgoJLyoqCgkgKiBAc2VlIFRvbWNhdENvbmZpZ3VyYXRpb24jbG9hZChJRm9sZGVyLCBJUHJvZ3Jlc3NNb25pdG9yKQoJICovCglwdWJsaWMgdm9pZCBsb2FkKElGb2xkZXIgZm9sZGVyLCBJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHRocm93cyBDb3JlRXhjZXB0aW9uIHsKCQl0cnkgewoJCQltb25pdG9yID0gUHJvZ3Jlc3NVdGlsLmdldE1vbml0b3JGb3IobW9uaXRvcik7CgkJCW1vbml0b3IuYmVnaW5UYXNrKE1lc3NhZ2VzLmxvYWRpbmdUYXNrLCA4MDApOwoJCgkJCS8vIGNoZWNrIGZvciBjYXRhbGluYS5wb2xpY3kgdG8gdmVyaWZ5IHRoYXQgdGhpcyBpcyBhIHY0LjAgY29uZmlnCgkJCUlGaWxlIGZpbGUgPSBmb2xkZXIuZ2V0RmlsZSgiY2F0YWxpbmEucG9saWN5Iik7CgkJCWlmICghZmlsZS5leGlzdHMoKSkKCQkJCXRocm93IG5ldyBDb3JlRXhjZXB0aW9uKG5ldyBTdGF0dXMoSVN0YXR1cy5XQVJOSU5HLCBUb21jYXRQbHVnaW4uUExVR0lOX0lELCAwLCBOTFMuYmluZChNZXNzYWdlcy5lcnJvckNvdWxkTm90TG9hZENvbmZpZ3VyYXRpb24sIGZvbGRlci5nZXRGdWxsUGF0aCgpLnRvT1NTdHJpbmcoKSksIG51bGwpKTsKCQoJCQkvLyBsb2FkIHNlcnZlci54bWwKCQkJZmlsZSA9IGZvbGRlci5nZXRGaWxlKCJzZXJ2ZXIueG1sIik7CgkJCUlucHV0U3RyZWFtIGluID0gZmlsZS5nZXRDb250ZW50cygpOwoJCQlzZXJ2ZXJGYWN0b3J5ID0gbmV3IEZhY3RvcnkoKTsKCQkJc2VydmVyRmFjdG9yeS5zZXRQYWNrYWdlTmFtZSgib3JnLmVjbGlwc2UuanN0LnNlcnZlci50b21jYXQuY29yZS5pbnRlcm5hbC54bWwuc2VydmVyNDAiKTsKCQkJc2VydmVyID0gKFNlcnZlcikgc2VydmVyRmFjdG9yeS5sb2FkRG9jdW1lbnQoaW4pOwoJCQltb25pdG9yLndvcmtlZCgyMDApOwoJCgkJCS8vIGxvYWQgd2ViLnhtbAoJCQlmaWxlID0gZm9sZGVyLmdldEZpbGUoIndlYi54bWwiKTsKCQkJd2ViQXBwRG9jdW1lbnQgPSBuZXcgV2ViQXBwRG9jdW1lbnQoZmlsZSk7CgkJCW1vbml0b3Iud29ya2VkKDIwMCk7CgkKCQkJLy8gbG9hZCB0b21jYXQtdXNlcnMueG1sCgkJCWZpbGUgPSBmb2xkZXIuZ2V0RmlsZSgidG9tY2F0LXVzZXJzLnhtbCIpOwoJCQlpbiA9IGZpbGUuZ2V0Q29udGVudHMoKTsKCQkJCgkJCXRvbWNhdFVzZXJzRG9jdW1lbnQgPSBYTUxVdGlsLmdldERvY3VtZW50QnVpbGRlcigpLnBhcnNlKG5ldyBJbnB1dFNvdXJjZShpbikpOwoJCQltb25pdG9yLndvcmtlZCgyMDApOwoJCQoJCQkvLyBsb2FkIGNhdGFsaW5hLnBvbGljeQoJCQlmaWxlID0gZm9sZGVyLmdldEZpbGUoImNhdGFsaW5hLnBvbGljeSIpOwoJCQlpbiA9IGZpbGUuZ2V0Q29udGVudHMoKTsKCQkJQnVmZmVyZWRSZWFkZXIgYnIgPSBudWxsOwoJCQl0cnkgewoJCQkJYnIgPSBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IElucHV0U3RyZWFtUmVhZGVyKGluKSk7CgkJCQlTdHJpbmcgdGVtcCA9IGJyLnJlYWRMaW5lKCk7CgkJCQlwb2xpY3lGaWxlID0gIiI7CgkJCQl3aGlsZSAodGVtcCAhPSBudWxsKSB7CgkJCQkJcG9saWN5RmlsZSArPSB0ZW1wICsgIlxuIjsKCQkJCQl0ZW1wID0gYnIucmVhZExpbmUoKTsKCQkJCX0KCQkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJCVRyYWNlLnRyYWNlKFRyYWNlLldBUk5JTkcsICJDb3VsZCBub3QgbG9hZCBwb2xpY3kgZmlsZSIsIGUpOwoJCQl9IGZpbmFsbHkgewoJCQkJaWYgKGJyICE9IG51bGwpCgkJCQkJYnIuY2xvc2UoKTsKCQkJfQoJCQltb25pdG9yLndvcmtlZCgyMDApOwoJCgkJCWlmIChtb25pdG9yLmlzQ2FuY2VsZWQoKSkKCQkJCXRocm93IG5ldyBFeGNlcHRpb24oIkNhbmNlbGxlZCIpOwoJCQltb25pdG9yLmRvbmUoKTsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQlUcmFjZS50cmFjZShUcmFjZS5XQVJOSU5HLCAiQ291bGQgbm90IHJlbG9hZCBUb21jYXQgdjUuNSBjb25maWd1cmF0aW9uIGZyb206ICIgKyBmb2xkZXIuZ2V0RnVsbFBhdGgoKSArICI6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CgkJCXRocm93IG5ldyBDb3JlRXhjZXB0aW9uKG5ldyBTdGF0dXMoSVN0YXR1cy5FUlJPUiwgVG9tY2F0UGx1Z2luLlBMVUdJTl9JRCwgMCwgTkxTLmJpbmQoTWVzc2FnZXMuZXJyb3JDb3VsZE5vdExvYWRDb25maWd1cmF0aW9uLCBmb2xkZXIuZ2V0RnVsbFBhdGgoKS50b09TU3RyaW5nKCkpLCBlKSk7CgkJfQoJfQoKCS8qKgoJICogU2F2ZSB0byB0aGUgZ2l2ZW4gZGlyZWN0b3J5LgoJICogQHBhcmFtIHBhdGggYSBwYXRoCgkgKiBAcGFyYW0gZm9yY2VEaXJ0eSBib29sZWFuCgkgKiBAcGFyYW0gbW9uaXRvciBhIHByb2dyZXNzIG1vbml0b3IKCSAqIEBleGNlcHRpb24gQ29yZUV4Y2VwdGlvbgoJICovCglwcm90ZWN0ZWQgdm9pZCBzYXZlKElQYXRoIHBhdGgsIGJvb2xlYW4gZm9yY2VEaXJ0eSwgSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiB7CgkJdHJ5IHsKCQkJbW9uaXRvciA9IFByb2dyZXNzVXRpbC5nZXRNb25pdG9yRm9yKG1vbml0b3IpOwoJCQltb25pdG9yLmJlZ2luVGFzayhNZXNzYWdlcy5zYXZpbmdUYXNrLCAzKTsKCQoJCQkvLyBtYWtlIHN1cmUgZGlyZWN0b3J5IGV4aXN0cwoJCQlpZiAoIXBhdGgudG9GaWxlKCkuZXhpc3RzKCkpIHsKCQkJCWZvcmNlRGlydHkgPSB0cnVlOwoJCQkJcGF0aC50b0ZpbGUoKS5ta2RpcigpOwoJCQl9CgkJCW1vbml0b3Iud29ya2VkKDEpOwoJCgkJCS8vIHNhdmUgZmlsZXMKCQkJaWYgKGZvcmNlRGlydHkgfHwgaXNTZXJ2ZXJEaXJ0eSkKCQkJCXNlcnZlckZhY3Rvcnkuc2F2ZShwYXRoLmFwcGVuZCgic2VydmVyLnhtbCIpLnRvT1NTdHJpbmcoKSk7CgkJCW1vbml0b3Iud29ya2VkKDEpOwoJCgkJCS8vaWYgKGZvcmNlRGlydHkgfHwgaXNXZWJBcHBEaXJ0eSkKCQkJLy8Jd2ViQXBwRmFjdG9yeS5zYXZlKGRpclBhdGggKyAid2ViLnhtbCIpOwoJCQkvL3dlYkFwcERvY3VtZW50LnNhdmUocGF0aC50b09TU3RyaW5nKCksIGZvcmNlRGlydHkgfHwgaXNQb2xpY3lEaXJ0eSk7CgkJCXdlYkFwcERvY3VtZW50LnNhdmUocGF0aC5hcHBlbmQoIndlYi54bWwiKS50b09TU3RyaW5nKCksIGZvcmNlRGlydHkpOwoJCQltb25pdG9yLndvcmtlZCgxKTsKCQoJCQlpZiAoZm9yY2VEaXJ0eSkKCQkJCVhNTFV0aWwuc2F2ZShwYXRoLmFwcGVuZCgidG9tY2F0LXVzZXJzLnhtbCIpLnRvT1NTdHJpbmcoKSwgdG9tY2F0VXNlcnNEb2N1bWVudCk7CgkJCW1vbml0b3Iud29ya2VkKDEpOwoJCgkJCWlmIChmb3JjZURpcnR5IHx8IGlzUG9saWN5RGlydHkpIHsKCQkJCUJ1ZmZlcmVkV3JpdGVyIGJ3ID0gbmV3IEJ1ZmZlcmVkV3JpdGVyKG5ldyBGaWxlV3JpdGVyKHBhdGguYXBwZW5kKCJjYXRhbGluYS5wb2xpY3kiKS50b0ZpbGUoKSkpOwoJCQkJYncud3JpdGUocG9saWN5RmlsZSk7CgkJCQlidy5jbG9zZSgpOwoJCQl9CgkJCW1vbml0b3Iud29ya2VkKDEpOwoJCQlpc1NlcnZlckRpcnR5ID0gZmFsc2U7CgkJCWlzUG9saWN5RGlydHkgPSBmYWxzZTsKCQoJCQlpZiAobW9uaXRvci5pc0NhbmNlbGVkKCkpCgkJCQlyZXR1cm47CgkJCW1vbml0b3IuZG9uZSgpOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIkNvdWxkIG5vdCBzYXZlIFRvbWNhdCB2NS41IGNvbmZpZ3VyYXRpb24gdG8gIiArIHBhdGgsIGUpOwoJCQl0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbihuZXcgU3RhdHVzKElTdGF0dXMuRVJST1IsIFRvbWNhdFBsdWdpbi5QTFVHSU5fSUQsIDAsIE5MUy5iaW5kKE1lc3NhZ2VzLmVycm9yQ291bGROb3RTYXZlQ29uZmlndXJhdGlvbiwgbmV3IFN0cmluZ1tdIHtlLmdldExvY2FsaXplZE1lc3NhZ2UoKX0pLCBlKSk7CgkJfQoJfQoJCglwdWJsaWMgdm9pZCBzYXZlKElQYXRoIHBhdGgsIElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgdGhyb3dzIENvcmVFeGNlcHRpb24gewoJCXNhdmUocGF0aCwgdHJ1ZSwgbW9uaXRvcik7Cgl9CgoJLyoqCgkgKiBTYXZlIHRoZSBpbmZvcm1hdGlvbiBoZWxkIGJ5IHRoaXMgb2JqZWN0IHRvIHRoZSBnaXZlbiBkaXJlY3RvcnkuCgkgKgoJICogQHBhcmFtIGZvbGRlciBhIGZvbGRlcgoJICogQHBhcmFtIG1vbml0b3IgYSBwcm9ncmVzcyBtb25pdG9yCgkgKiBAdGhyb3dzIENvcmVFeGNlcHRpb24KCSAqLwoJcHVibGljIHZvaWQgc2F2ZShJRm9sZGVyIGZvbGRlciwgSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiB7CgkJdHJ5IHsKCQkJbW9uaXRvciA9IFByb2dyZXNzVXRpbC5nZXRNb25pdG9yRm9yKG1vbml0b3IpOwoJCQltb25pdG9yLmJlZ2luVGFzayhNZXNzYWdlcy5zYXZpbmdUYXNrLCA5MDApOwoJCgkJCS8vIHNhdmUgc2VydmVyLnhtbAoJCQlieXRlW10gZGF0YSA9IHNlcnZlckZhY3RvcnkuZ2V0Q29udGVudHMoKTsKCQkJSW5wdXRTdHJlYW0gaW4gPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oZGF0YSk7CgkJCUlGaWxlIGZpbGUgPSBmb2xkZXIuZ2V0RmlsZSgic2VydmVyLnhtbCIpOwoJCQlpZiAoZmlsZS5leGlzdHMoKSkgewoJCQkJaWYgKGlzU2VydmVyRGlydHkpCgkJCQkJZmlsZS5zZXRDb250ZW50cyhpbiwgdHJ1ZSwgdHJ1ZSwgUHJvZ3Jlc3NVdGlsLmdldFN1Yk1vbml0b3JGb3IobW9uaXRvciwgMjAwKSk7CgkJCQllbHNlCgkJCQkJbW9uaXRvci53b3JrZWQoMjAwKTsKCQkJfSBlbHNlCgkJCQlmaWxlLmNyZWF0ZShpbiwgdHJ1ZSwgUHJvZ3Jlc3NVdGlsLmdldFN1Yk1vbml0b3JGb3IobW9uaXRvciwgMjAwKSk7CgkKCQkJLy8gc2F2ZSB3ZWIueG1sCgkJCXdlYkFwcERvY3VtZW50LnNhdmUoZm9sZGVyLmdldEZpbGUoIndlYi54bWwiKSwgUHJvZ3Jlc3NVdGlsLmdldFN1Yk1vbml0b3JGb3IobW9uaXRvciwgMjAwKSk7CgkKCQkJLy8gc2F2ZSB0b21jYXQtdXNlcnMueG1sCgkJCWRhdGEgPSBYTUxVdGlsLmdldENvbnRlbnRzKHRvbWNhdFVzZXJzRG9jdW1lbnQpOwoJCQlpbiA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShkYXRhKTsKCQkJZmlsZSA9IGZvbGRlci5nZXRGaWxlKCJ0b21jYXQtdXNlcnMueG1sIik7CgkJCWlmIChmaWxlLmV4aXN0cygpKQoJCQkJbW9uaXRvci53b3JrZWQoMjAwKTsKCQkJCS8vZmlsZS5zZXRDb250ZW50cyhpbiwgdHJ1ZSwgdHJ1ZSwgUHJvZ3Jlc3NVdGlsLmdldFN1Yk1vbml0b3JGb3IobW9uaXRvciwgMjAwKSk7CgkJCWVsc2UKCQkJCWZpbGUuY3JlYXRlKGluLCB0cnVlLCBQcm9ncmVzc1V0aWwuZ2V0U3ViTW9uaXRvckZvcihtb25pdG9yLCAyMDApKTsKCQoJCQkvLyBzYXZlIGNhdGFsaW5hLnBvbGljeQoJCQlpbiA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShwb2xpY3lGaWxlLmdldEJ5dGVzKCkpOwoJCQlmaWxlID0gZm9sZGVyLmdldEZpbGUoImNhdGFsaW5hLnBvbGljeSIpOwoJCQlpZiAoZmlsZS5leGlzdHMoKSkKCQkJCW1vbml0b3Iud29ya2VkKDIwMCk7CgkJCQkvL2ZpbGUuc2V0Q29udGVudHMoaW4sIHRydWUsIHRydWUsIFByb2dyZXNzVXRpbC5nZXRTdWJNb25pdG9yRm9yKG1vbml0b3IsIDIwMCkpOwoJCQllbHNlCgkJCQlmaWxlLmNyZWF0ZShpbiwgdHJ1ZSwgUHJvZ3Jlc3NVdGlsLmdldFN1Yk1vbml0b3JGb3IobW9uaXRvciwgMjAwKSk7CgkKCQkJaWYgKG1vbml0b3IuaXNDYW5jZWxlZCgpKQoJCQkJcmV0dXJuOwoJCQltb25pdG9yLmRvbmUoKTsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJDb3VsZCBub3Qgc2F2ZSBUb21jYXQgdjUuNSBjb25maWd1cmF0aW9uIHRvICIgKyBmb2xkZXIudG9TdHJpbmcoKSwgZSk7CgkJCXRocm93IG5ldyBDb3JlRXhjZXB0aW9uKG5ldyBTdGF0dXMoSVN0YXR1cy5FUlJPUiwgVG9tY2F0UGx1Z2luLlBMVUdJTl9JRCwgMCwgTkxTLmJpbmQoTWVzc2FnZXMuZXJyb3JDb3VsZE5vdFNhdmVDb25maWd1cmF0aW9uLCBuZXcgU3RyaW5nW10ge2UuZ2V0TG9jYWxpemVkTWVzc2FnZSgpfSksIGUpKTsKCQl9Cgl9CgoJcHJvdGVjdGVkIHN0YXRpYyBib29sZWFuIGhhc01EQkxpc3RlbmVyKFNlcnZlciBzZXJ2ZXIpIHsKCQlpZiAoc2VydmVyID09IG51bGwpCgkJCXJldHVybiBmYWxzZTsKCQkKCQlpbnQgY291bnQgPSBzZXJ2ZXIuZ2V0TGlzdGVuZXJDb3VudCgpOwoJCWlmIChjb3VudCA9PSAwKQoJCQlyZXR1cm4gZmFsc2U7CgkJCQoJCWZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewoJCQlMaXN0ZW5lciBsaXN0ZW5lciA9IHNlcnZlci5nZXRMaXN0ZW5lcihpKTsKCQkJaWYgKGxpc3RlbmVyICE9IG51bGwgJiYgbGlzdGVuZXIuZ2V0Q2xhc3NOYW1lKCkgIT0gbnVsbCAmJiBsaXN0ZW5lci5nZXRDbGFzc05hbWUoKS5pbmRleE9mKCJtYmVhbiIpID49IDApCgkJCQlyZXR1cm4gdHJ1ZTsKCQl9CgkJcmV0dXJuIGZhbHNlOwoJfQoJCgkvKioKCSAqIEBzZWUgSVRvbWNhdENvbmZpZ3VyYXRpb25Xb3JraW5nQ29weSNhZGRNaW1lTWFwcGluZyhpbnQsIElNaW1lTWFwcGluZykKCSAqLwoJcHVibGljIHZvaWQgYWRkTWltZU1hcHBpbmcoaW50IGluZGV4LCBJTWltZU1hcHBpbmcgbWFwKSB7CgkJd2ViQXBwRG9jdW1lbnQuYWRkTWltZU1hcHBpbmcoaW5kZXgsIG1hcCk7CgkJZmlyZVByb3BlcnR5Q2hhbmdlRXZlbnQoQUREX01BUFBJTkdfUFJPUEVSVFksIG5ldyBJbnRlZ2VyKGluZGV4KSwgbWFwKTsKCX0KCgkvKioKCSAqIEBzZWUgSVRvbWNhdENvbmZpZ3VyYXRpb25Xb3JraW5nQ29weSNhZGRXZWJNb2R1bGUoaW50LCBJVG9tY2F0V2ViTW9kdWxlKQoJICovCglwdWJsaWMgdm9pZCBhZGRXZWJNb2R1bGUoaW50IGluZGV4LCBJVG9tY2F0V2ViTW9kdWxlIG1vZHVsZSkgewoJCXRyeSB7CgkJCWludCBzaXplID0gc2VydmVyLmdldFNlcnZpY2VDb3VudCgpOwoJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJU2VydmljZSBzZXJ2aWNlID0gc2VydmVyLmdldFNlcnZpY2UoaSk7CgkJCQlpZiAoc2VydmljZS5nZXROYW1lKCkuZXF1YWxzSWdub3JlQ2FzZShERUZBVUxUX1NFUlZJQ0UpKSB7CgkJCQkJRW5naW5lIGVuZ2luZSA9IHNlcnZpY2UuZ2V0RW5naW5lKCk7CgkJCQkJSG9zdCBob3N0ID0gZW5naW5lLmdldEhvc3QoKTsKCQkJCQlDb250ZXh0IGNvbnRleHQgPSAoQ29udGV4dCkgaG9zdC5jcmVhdGVFbGVtZW50KGluZGV4LCAiQ29udGV4dCIpOwoJCQkJCWNvbnRleHQuc2V0RG9jQmFzZShtb2R1bGUuZ2V0RG9jdW1lbnRCYXNlKCkpOwoJCQkJCWNvbnRleHQuc2V0UGF0aChtb2R1bGUuZ2V0UGF0aCgpKTsKCQkJCQljb250ZXh0LnNldFJlbG9hZGFibGUobW9kdWxlLmlzUmVsb2FkYWJsZSgpID8gInRydWUiIDogImZhbHNlIik7CgkJCQkJaWYgKG1vZHVsZS5nZXRNZW1lbnRvKCkgIT0gbnVsbCAmJiBtb2R1bGUuZ2V0TWVtZW50bygpLmxlbmd0aCgpID4gMCkKCQkJCQkJY29udGV4dC5zZXRTb3VyY2UobW9kdWxlLmdldE1lbWVudG8oKSk7CgkJCQkJaXNTZXJ2ZXJEaXJ0eSA9IHRydWU7CgkJCQkJZmlyZVByb3BlcnR5Q2hhbmdlRXZlbnQoQUREX1dFQl9NT0RVTEVfUFJPUEVSVFksIG51bGwsIG1vZHVsZSk7CgkJCQkJcmV0dXJuOwoJCQkJfQoJCQl9CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiRXJyb3IgYWRkaW5nIHdlYiBtb2R1bGUgIiArIG1vZHVsZS5nZXRQYXRoKCksIGUpOwoJCX0KCX0KCgkvKioKCSAqIExvY2FsaXplIHRoZSB3ZWIgcHJvamVjdHMgaW4gdGhpcyBjb25maWd1cmF0aW9uLgoJICoKCSAqIEBwYXJhbSBwYXRoIGEgcGF0aAoJICogQHBhcmFtIHNlcnZlcjIgYSBzZXJ2ZXIgdHlwZQoJICogQHBhcmFtIHJ1bnRpbWUgYSBydW50aW1lCgkgKiBAcGFyYW0gbW9uaXRvciBhIHByb2dyZXNzIG1vbml0b3IKCSAqLwoJcHVibGljIHZvaWQgbG9jYWxpemVDb25maWd1cmF0aW9uKElQYXRoIHBhdGgsIFRvbWNhdFNlcnZlciBzZXJ2ZXIyLCBUb21jYXRSdW50aW1lIHJ1bnRpbWUsIElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgewoJCXRyeSB7CgkJCW1vbml0b3IgPSBQcm9ncmVzc1V0aWwuZ2V0TW9uaXRvckZvcihtb25pdG9yKTsKCQkJbW9uaXRvci5iZWdpblRhc2soTWVzc2FnZXMudXBkYXRpbmdDb25maWd1cmF0aW9uVGFzaywgMTAwKTsKCQkJCgkJCVRvbWNhdDU1Q29uZmlndXJhdGlvbiBjb25maWcgPSBuZXcgVG9tY2F0NTVDb25maWd1cmF0aW9uKG51bGwpOwoJCQljb25maWcubG9hZChwYXRoLCBQcm9ncmVzc1V0aWwuZ2V0U3ViTW9uaXRvckZvcihtb25pdG9yLCA0MCkpOwoJCgkJCWlmIChtb25pdG9yLmlzQ2FuY2VsZWQoKSkKCQkJCXJldHVybjsKCQoJCQlpZiAoIXNlcnZlcjIuaXNUZXN0RW52aXJvbm1lbnQoKSkgewoJCQkJLy9JU2VydmVyQ29uZmlndXJhdGlvbldvcmtpbmdDb3B5IHNjd2MgPSBjb25maWcuZ2V0U2VydmVyQ29uZmlndXJhdGlvbigpLmNyZWF0ZVdvcmtpbmdDb3B5KCk7CgkJCQkvL1RvbWNhdDU1Q29uZmlndXJhdGlvbiBjZmcgPSAoVG9tY2F0NTVDb25maWd1cmF0aW9uKSBzY3djLmdldEFkYXB0ZXIoVG9tY2F0NTVDb25maWd1cmF0aW9uLmNsYXNzKTsKCQkJCWNvbmZpZy5sb2NhbGl6ZVdlYk1vZHVsZXMoKTsKCQkJfQoJCQltb25pdG9yLndvcmtlZCgyMCk7CgkKCQkJaWYgKG1vbml0b3IuaXNDYW5jZWxlZCgpKQoJCQkJcmV0dXJuOwoJCgkJCWNvbmZpZy5zYXZlKHBhdGgsIGZhbHNlLCBQcm9ncmVzc1V0aWwuZ2V0U3ViTW9uaXRvckZvcihtb25pdG9yLCA0MCkpOwoJCgkJCWlmICghbW9uaXRvci5pc0NhbmNlbGVkKCkpCgkJCQltb25pdG9yLmRvbmUoKTsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJFcnJvciBsb2NhbGl6aW5nIGNvbmZpZ3VyYXRpb24iLCBlKTsKCQl9Cgl9CgkKCS8qKgoJICogR28gdGhyb3VnaCBhbGwgb2YgdGhlIHdlYiBtb2R1bGVzIGFuZCBtYWtlIHRoZSBkb2N1bWVudAoJICogYmFzZSAibG9jYWwiIHRvIHRoZSBjb25maWd1cmF0aW9uLgoJICovCglwcm90ZWN0ZWQgdm9pZCBsb2NhbGl6ZVdlYk1vZHVsZXMoKSB7CgkJTGlzdCBtb2R1bGVzID0gZ2V0V2ViTW9kdWxlcygpOwoKCQlpbnQgc2l6ZSA9IG1vZHVsZXMuc2l6ZSgpOwoJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCVdlYk1vZHVsZSBtb2R1bGUgPSAoV2ViTW9kdWxlKSBtb2R1bGVzLmdldChpKTsKCQkJU3RyaW5nIG1lbWVudG8gPSBtb2R1bGUuZ2V0TWVtZW50bygpOwoJCQlpZiAobWVtZW50byAhPSBudWxsICYmIG1lbWVudG8ubGVuZ3RoKCkgPiAwKSB7CgkJCQkvLyB1cGRhdGUgZG9jdW1lbnQgYmFzZSB0byBhIHJlbGF0aXZlIHJlZgoJCQkJU3RyaW5nIGRvY0Jhc2UgPSBnZXRQYXRoUHJlZml4KCkgKyBtb2R1bGUuZ2V0UGF0aCgpOwoJCQkJaWYgKGRvY0Jhc2Uuc3RhcnRzV2l0aCgiLyIpIHx8IGRvY0Jhc2Uuc3RhcnRzV2l0aCgiXFwiKSkKCQkJCQlkb2NCYXNlID0gZG9jQmFzZS5zdWJzdHJpbmcoMSk7CgkJCQltb2RpZnlXZWJNb2R1bGUoaSwgZG9jQmFzZSwgbW9kdWxlLmdldFBhdGgoKSwgbW9kdWxlLmlzUmVsb2FkYWJsZSgpKTsKCQkJfQoJCX0KCX0KCgkvKioKCSAqIENoYW5nZSB0aGUgZXh0ZW5zaW9uIG9mIGEgbWltZSBtYXBwaW5nLgoJICogCgkgKiBAcGFyYW0gaW5kZXgKCSAqIEBwYXJhbSBtYXAKCSAqLwoJcHVibGljIHZvaWQgbW9kaWZ5TWltZU1hcHBpbmcoaW50IGluZGV4LCBJTWltZU1hcHBpbmcgbWFwKSB7CgkJd2ViQXBwRG9jdW1lbnQubW9kaWZ5TWltZU1hcHBpbmcoaW5kZXgsIG1hcCk7CgkJZmlyZVByb3BlcnR5Q2hhbmdlRXZlbnQoTU9ESUZZX01BUFBJTkdfUFJPUEVSVFksIG5ldyBJbnRlZ2VyKGluZGV4KSwgbWFwKTsKCX0KCQoJLyoqCgkgKiBNb2RpZnkgdGhlIHBvcnQgd2l0aCB0aGUgZ2l2ZW4gaWQuCgkgKgoJICogQHBhcmFtIGlkIGphdmEubGFuZy5TdHJpbmcKCSAqIEBwYXJhbSBwb3J0IGludAoJICovCglwdWJsaWMgdm9pZCBtb2RpZnlTZXJ2ZXJQb3J0KFN0cmluZyBpZCwgaW50IHBvcnQpIHsKCQl0cnkgewoJCQlpZiAoInNlcnZlciIuZXF1YWxzKGlkKSkgewoJCQkJc2VydmVyLnNldFBvcnQocG9ydCArICIiKTsKCQkJCWlzU2VydmVyRGlydHkgPSB0cnVlOwoJCQkJZmlyZVByb3BlcnR5Q2hhbmdlRXZlbnQoTU9ESUZZX1BPUlRfUFJPUEVSVFksIGlkLCBuZXcgSW50ZWdlcihwb3J0KSk7CgkJCQlyZXR1cm47CgkJCX0KCQoJCQlpbnQgaSA9IGlkLmluZGV4T2YoIi8iKTsKCQkJaW50IHNlcnZOdW0gPSBJbnRlZ2VyLnBhcnNlSW50KGlkLnN1YnN0cmluZygwLCBpKSk7CgkJCWludCBjb25uTnVtID0gSW50ZWdlci5wYXJzZUludChpZC5zdWJzdHJpbmcoaSArIDEpKTsKCQkJCgkJCVNlcnZpY2Ugc2VydmljZSA9IHNlcnZlci5nZXRTZXJ2aWNlKHNlcnZOdW0pOwoJCQlDb25uZWN0b3IgY29ubmVjdG9yID0gc2VydmljZS5nZXRDb25uZWN0b3IoY29ubk51bSk7CgkJCWNvbm5lY3Rvci5zZXRQb3J0KHBvcnQgKyAiIik7CgkJCWlzU2VydmVyRGlydHkgPSB0cnVlOwoJCQlmaXJlUHJvcGVydHlDaGFuZ2VFdmVudChNT0RJRllfUE9SVF9QUk9QRVJUWSwgaWQsIG5ldyBJbnRlZ2VyKHBvcnQpKTsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJFcnJvciBtb2RpZnlpbmcgc2VydmVyIHBvcnQgIiArIGlkLCBlKTsKCQl9Cgl9CgkvKioKCSAqIENoYW5nZSBhIHdlYiBtb2R1bGUuCgkgKiBAcGFyYW0gaW5kZXggaW50CgkgKiBAcGFyYW0gZG9jQmFzZSBqYXZhLmxhbmcuU3RyaW5nCgkgKiBAcGFyYW0gcGF0aCBqYXZhLmxhbmcuU3RyaW5nCgkgKiBAcGFyYW0gcmVsb2FkYWJsZSBib29sZWFuCgkgKi8KCXB1YmxpYyB2b2lkIG1vZGlmeVdlYk1vZHVsZShpbnQgaW5kZXgsIFN0cmluZyBkb2NCYXNlLCBTdHJpbmcgcGF0aCwgYm9vbGVhbiByZWxvYWRhYmxlKSB7CgkJdHJ5IHsKCQkJaW50IHNpemUgPSBzZXJ2ZXIuZ2V0U2VydmljZUNvdW50KCk7CgkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQlTZXJ2aWNlIHNlcnZpY2UgPSBzZXJ2ZXIuZ2V0U2VydmljZShpKTsKCQkJCWlmIChzZXJ2aWNlLmdldE5hbWUoKS5lcXVhbHNJZ25vcmVDYXNlKERFRkFVTFRfU0VSVklDRSkpIHsKCQkJCQlFbmdpbmUgZW5naW5lID0gc2VydmljZS5nZXRFbmdpbmUoKTsKCQkJCQlIb3N0IGhvc3QgPSBlbmdpbmUuZ2V0SG9zdCgpOwoJCQkJCUNvbnRleHQgY29udGV4dCA9IGhvc3QuZ2V0Q29udGV4dChpbmRleCk7CgkJCQkJY29udGV4dC5zZXRQYXRoKHBhdGgpOwoJCQkJCWNvbnRleHQuc2V0RG9jQmFzZShkb2NCYXNlKTsKCQkJCQljb250ZXh0LnNldFJlbG9hZGFibGUocmVsb2FkYWJsZSA/ICJ0cnVlIiA6ICJmYWxzZSIpOwoJCQkJCWlzU2VydmVyRGlydHkgPSB0cnVlOwoJCQkJCVdlYk1vZHVsZSBtb2R1bGUgPSBuZXcgV2ViTW9kdWxlKHBhdGgsIGRvY0Jhc2UsIG51bGwsIHJlbG9hZGFibGUpOwoJCQkJCWZpcmVQcm9wZXJ0eUNoYW5nZUV2ZW50KE1PRElGWV9XRUJfTU9EVUxFX1BST1BFUlRZLCBuZXcgSW50ZWdlcihpbmRleCksIG1vZHVsZSk7CgkJCQkJcmV0dXJuOwoJCQkJfQoJCQl9CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiRXJyb3IgbW9kaWZ5aW5nIHdlYiBtb2R1bGUgIiArIGluZGV4LCBlKTsKCQl9Cgl9CgoJLyoqCgkgKiBSZW1vdmVzIGEgbWltZSBtYXBwaW5nLgoJICogQHBhcmFtIGluZGV4IGludAoJICovCglwdWJsaWMgdm9pZCByZW1vdmVNaW1lTWFwcGluZyhpbnQgaW5kZXgpIHsKCQl3ZWJBcHBEb2N1bWVudC5yZW1vdmVNaW1lTWFwcGluZyhpbmRleCk7CgkJZmlyZVByb3BlcnR5Q2hhbmdlRXZlbnQoUkVNT1ZFX01BUFBJTkdfUFJPUEVSVFksIG51bGwsIG5ldyBJbnRlZ2VyKGluZGV4KSk7Cgl9CgoJLyoqCgkgKiBSZW1vdmVzIGEgd2ViIG1vZHVsZS4KCSAqIEBwYXJhbSBpbmRleCBpbnQKCSAqLwoJcHVibGljIHZvaWQgcmVtb3ZlV2ViTW9kdWxlKGludCBpbmRleCkgewoJCXRyeSB7CgkJCWludCBzaXplID0gc2VydmVyLmdldFNlcnZpY2VDb3VudCgpOwoJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJU2VydmljZSBzZXJ2aWNlID0gc2VydmVyLmdldFNlcnZpY2UoaSk7CgkJCQlpZiAoc2VydmljZS5nZXROYW1lKCkuZXF1YWxzSWdub3JlQ2FzZShERUZBVUxUX1NFUlZJQ0UpKSB7CgkJCQkJRW5naW5lIGVuZ2luZSA9IHNlcnZpY2UuZ2V0RW5naW5lKCk7CgkJCQkJSG9zdCBob3N0ID0gZW5naW5lLmdldEhvc3QoKTsKCQkJCQlob3N0LnJlbW92ZUVsZW1lbnQoIkNvbnRleHQiLCBpbmRleCk7CgkJCQkJaXNTZXJ2ZXJEaXJ0eSA9IHRydWU7CgkJCQkJZmlyZVByb3BlcnR5Q2hhbmdlRXZlbnQoUkVNT1ZFX1dFQl9NT0RVTEVfUFJPUEVSVFksIG51bGwsIG5ldyBJbnRlZ2VyKGluZGV4KSk7CgkJCQkJcmV0dXJuOwoJCQkJfQoJCQl9CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiRXJyb3IgcmVtb3ZpbmcgbW9kdWxlIHJlZiAiICsgaW5kZXgsIGUpOwoJCX0KCX0KCglwcm90ZWN0ZWQgSVN0YXR1cyBiYWNrdXBBbmRQdWJsaXNoKElQYXRoIGNvbmZEaXIsIGJvb2xlYW4gZG9CYWNrdXAsIElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgewoJCU11bHRpU3RhdHVzIG1zID0gbmV3IE11bHRpU3RhdHVzKFRvbWNhdFBsdWdpbi5QTFVHSU5fSUQsIDAsIE1lc3NhZ2VzLnB1Ymxpc2hDb25maWd1cmF0aW9uVGFzaywgbnVsbCk7CgkJVHJhY2UudHJhY2UoVHJhY2UuRklORVIsICJCYWNrdXAgYW5kIHB1Ymxpc2giKTsKCQltb25pdG9yID0gUHJvZ3Jlc3NVdGlsLmdldE1vbml0b3JGb3IobW9uaXRvcik7CgoJCWJhY2t1cEFuZFB1Ymxpc2goY29uZkRpciwgZG9CYWNrdXAsIG1zLCBtb25pdG9yLCAzMDApOwoJCS8vIFRPRE8gUmVmYWN0b3Igc3VjY2VzcyBkZXRlY3Rpb24gb25jZSBCdWcgODEwNjAgaXMgYWRkcmVzc2VkCgkJLy8gVGhpcyBhcHByb2FjaCBhdm9pZHMgcmVmYWN0b3JpbmcgVG9tY2F0Q29uZmlndXJhdGlvbi5iYWNrdXBGb2xkZXIoKQoJCS8vIGFuZCBiYWNrdXBQYXRoKCkgZm9yIG5vdy4KCQlpZiAobXMuaXNPSygpICYmIG1zLmdldENoaWxkcmVuKCkubGVuZ3RoID4gMCkKCQkJcHVibGlzaENvbnRleHRDb25maWcoY29uZkRpciwgbXMsIG1vbml0b3IpOwoKCQltb25pdG9yLmRvbmUoKTsKCQlyZXR1cm4gbXM7Cgl9CgkKCXByb3RlY3RlZCB2b2lkIHB1Ymxpc2hDb250ZXh0Q29uZmlnKElQYXRoIGNvbmZEaXIsIE11bHRpU3RhdHVzIG1zLCBJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHsKCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FUiwgIkFwcGx5IGNvbnRleHQgY29uZmlndXJhdGlvbnMiKTsKCQl0cnkgewoJCQljb25mRGlyID0gY29uZkRpci5hcHBlbmQoImNvbmYiKTsKCQkJCgkJCW1vbml0b3Iuc3ViVGFzayhNZXNzYWdlcy5wdWJsaXNoQ29udGV4dENvbmZpZ1Rhc2spOwoJCQlGYWN0b3J5IGZhY3RvcnkgPSBuZXcgRmFjdG9yeSgpOwoJCQlmYWN0b3J5LnNldFBhY2thZ2VOYW1lKCJvcmcuZWNsaXBzZS5qc3Quc2VydmVyLnRvbWNhdC5jb3JlLmludGVybmFsLnhtbC5zZXJ2ZXI0MCIpOwoJCQlTZXJ2ZXIgcHVibGlzaGVkU2VydmVyID0gKFNlcnZlcikgZmFjdG9yeS5sb2FkRG9jdW1lbnQobmV3IEZpbGVJbnB1dFN0cmVhbShjb25mRGlyLmFwcGVuZCgic2VydmVyLnhtbCIpLnRvRmlsZSgpKSk7CgkJCW1vbml0b3Iud29ya2VkKDEwMCk7CgkJCQoJCQlib29sZWFuIG1vZGlmaWVkID0gZmFsc2U7CgoJCQlpbnQgc2l6ZSA9IHB1Ymxpc2hlZFNlcnZlci5nZXRTZXJ2aWNlQ291bnQoKTsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCVNlcnZpY2Ugc2VydmljZSA9IHB1Ymxpc2hlZFNlcnZlci5nZXRTZXJ2aWNlKGkpOwoJCQkJaWYgKHNlcnZpY2UuZ2V0TmFtZSgpLmVxdWFsc0lnbm9yZUNhc2UoREVGQVVMVF9TRVJWSUNFKSkgewoJCQkJCUVuZ2luZSBlbmdpbmUgPSBzZXJ2aWNlLmdldEVuZ2luZSgpOwoJCQkJCUhvc3QgaG9zdCA9IGVuZ2luZS5nZXRIb3N0KCk7CgkJCQkJaW50IHNpemUyID0gaG9zdC5nZXRDb250ZXh0Q291bnQoKTsKCQkJCQlmb3IgKGludCBqID0gMDsgaiA8IHNpemUyOyBqKyspIHsKCQkJCQkJQ29udGV4dCBjb250ZXh0ID0gaG9zdC5nZXRDb250ZXh0KGopOwoJCQkJCQltb25pdG9yLnN1YlRhc2soTkxTLmJpbmQoTWVzc2FnZXMuY2hlY2tpbmdDb250ZXh0VGFzaywKCQkJCQkJCQluZXcgU3RyaW5nW10ge2NvbnRleHQuZ2V0UGF0aCgpfSkpOwoJCQkJCQlpZiAoYWRkQ29udGV4dENvbmZpZyhjb250ZXh0KSkgewoJCQkJCQkJbW9kaWZpZWQgPSB0cnVlOwoJCQkJCQl9CgkJCQkJfQoJCQkJfQoJCQl9CgkJCW1vbml0b3Iud29ya2VkKDEwMCk7CgkJCWlmIChtb2RpZmllZCkgewoJCQkJbW9uaXRvci5zdWJUYXNrKE1lc3NhZ2VzLnNhdmluZ0NvbnRleHRDb25maWdUYXNrKTsKCQkJCWZhY3Rvcnkuc2F2ZShjb25mRGlyLmFwcGVuZCgic2VydmVyLnhtbCIpLnRvT1NTdHJpbmcoKSk7CgkJCX0KCQkJbW9uaXRvci53b3JrZWQoMTAwKTsKCQkJCgkJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVSLCAiU2VydmVyLnhtbCB1cGRhdGVkIHdpdGggY29udGV4dC54bWwgY29uZmlndXJhdGlvbnMiKTsKCQkJbXMuYWRkKG5ldyBTdGF0dXMoSVN0YXR1cy5PSywgVG9tY2F0UGx1Z2luLlBMVUdJTl9JRCwgMCwgTWVzc2FnZXMuc2VydmVyUG9zdFByb2Nlc3NpbmdDb21wbGV0ZSwgbnVsbCkpOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLldBUk5JTkcsICJDb3VsZCBub3QgYXBwbHkgY29udGV4dCBjb25maWd1cmF0aW9ucyBwdWJsaXNoZWQgVG9tY2F0IHY1LjAgY29uZmlndXJhdGlvbiBmcm9tICIgKyBjb25mRGlyLnRvT1NTdHJpbmcoKSArICI6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CgkJCUlTdGF0dXMgcyA9IG5ldyBTdGF0dXMoSVN0YXR1cy5FUlJPUiwgVG9tY2F0UGx1Z2luLlBMVUdJTl9JRCwgMCwgTkxTLmJpbmQoTWVzc2FnZXMuZXJyb3JQdWJsaXNoQ29uZmlndXJhdGlvbiwgbmV3IFN0cmluZ1tdIHtlLmdldExvY2FsaXplZE1lc3NhZ2UoKX0pLCBlKTsKCQkJbXMuYWRkKHMpOwoJCX0KCX0KCQoJLyoqCgkgKiBJZiB0aGUgc3BlY2lmaWVkIENvbnRleHQgaXMgbGlua2VkIHRvIGEgcHJvamVjdCwgdHJ5IHRvCgkgKiB1cGRhdGUgYW55IGNvbmZpZ3VyYXRpb24gZm91bmQgYSBNRVRBLUlORi9jb250ZXh0LnhtbCBmb3VuZAoJICogcmVsYXRpdmUgdG8gdGhlIHNwZWNpZmllZCBkb2NCYXNlLgoJICogQHBhcmFtIGNvbnRleHQgQ29udGV4dCBvYmplY3QgdG8gcmVjZWl2ZSBjb250ZXh0LnhtbCBjb250ZW50cy4KCSAqIEByZXR1cm4gUmV0dXJucyB0cnVlIGlmIGNvbnRleHQgaXMgbW9kaWZpZWQuCgkgKi8KCXByb3RlY3RlZCBib29sZWFuIGFkZENvbnRleHRDb25maWcoQ29udGV4dCBjb250ZXh0KSB7CgkJYm9vbGVhbiBtb2RpZmllZCA9IGZhbHNlOwoJCVN0cmluZyBzb3VyY2UgPSBjb250ZXh0LmdldFNvdXJjZSgpOwoJCWlmIChzb3VyY2UgIT0gbnVsbCAmJiBzb3VyY2UubGVuZ3RoKCkgPiAwICkKCQl7CgkJCVN0cmluZyBkb2NCYXNlID0gY29udGV4dC5nZXREb2NCYXNlKCk7CgkJCUNvbnRleHQgY29udGV4dENvbmZpZyA9IGxvYWRDb250ZXh0Q29uZmlnKGRvY0Jhc2UpOwoJCQlpZiAobnVsbCAhPSBjb250ZXh0Q29uZmlnKSB7CgkJCQlpZiAoY29udGV4dC5oYXNDaGlsZE5vZGVzKCkpCgkJCQkJY29udGV4dC5yZW1vdmVDaGlsZHJlbigpOwoJCQkJY29udGV4dENvbmZpZy5jb3B5Q2hpbGRyZW5Ubyhjb250ZXh0KTsKCQkJCW1vZGlmaWVkID0gdHJ1ZTsKCQkJfQoJCX0KCQlyZXR1cm4gbW9kaWZpZWQ7Cgl9CgkKCS8qKgoJICogVHJpZXMgdG8gcmVhZCBhIE1FVEEtSU5GL2NvbnRleHQueG1sIGZpbGUgcmVsYXRpdmUgdG8gdGhlCgkgKiBzcGVjaWZpZWQgZG9jQmFzZS4gIElmIGZvdW5kLCBpdCBjcmVhdGVzIGEgQ29udGV4dCBvYmplY3QKCSAqIGNvbnRhaW5pbmcgdGhlIGNvbnRleHRzIG9mIHRoYXQgZmlsZS4KCSAqIEBwYXJhbSBkb2NCYXNlCgkgKiBAcmV0dXJuIENvbnRleHQgZWxlbWVudCBjcmVhdGVkIGZyb20gY29udGV4dC54bWwsIG9yIG51bGwgaWYgbm90IGZvdW5kLgoJICovCglwcm90ZWN0ZWQgQ29udGV4dCBsb2FkQ29udGV4dENvbmZpZyhTdHJpbmcgZG9jQmFzZSkgewoJCUZpbGUgY29udGV4WE1MID0gbmV3IEZpbGUoZG9jQmFzZSArIEZpbGUuc2VwYXJhdG9yICsgIk1FVEEtSU5GIiArIEZpbGUuc2VwYXJhdG9yICsgImNvbnRleHQueG1sIik7CgkJaWYgKGNvbnRleFhNTC5leGlzdHMoKSkgewoJCQl0cnkgewoJCQkJSW5wdXRTdHJlYW0gaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGNvbnRleFhNTCk7CgkJCQlGYWN0b3J5IGN0eEZhY3RvcnkgPSBuZXcgRmFjdG9yeSgpOwoJCQkJY3R4RmFjdG9yeS5zZXRQYWNrYWdlTmFtZSgib3JnLmVjbGlwc2UuanN0LnNlcnZlci50b21jYXQuY29yZS5pbnRlcm5hbC54bWwuc2VydmVyNDAiKTsKCQkJCUNvbnRleHQgY3R4ID0gKENvbnRleHQpY3R4RmFjdG9yeS5sb2FkRG9jdW1lbnQoaXMpOwoJCQkJaXMuY2xvc2UoKTsKCQkJCXJldHVybiBjdHg7CgkJCX0gY2F0Y2ggKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7CgkJCQkvLyBJZ25vcmUsIHNob3VsZCBuZXZlciBvY2N1cgoJCQl9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJFcnJvciByZWFkaW5nIHdlYiBtb2R1bGUncyBjb250ZXh0LnhtbCBmaWxlOiAiICsgZG9jQmFzZSwgZSk7CgkJCX0KCQl9CgkJcmV0dXJuIG51bGw7CiAJfQoKCXByb3RlY3RlZCBJU3RhdHVzIHByZXBhcmVSdW50aW1lRGlyZWN0b3J5KElQYXRoIGNvbmZEaXIpIHsKCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FUiwgIlByZXBhcmluZyBydW50aW1lIGRpcmVjdG9yeSIpOwoJCS8vIFByZXBhcmUgYSBjYXRhbGluYS5iYXNlIGRpcmVjdG9yeSBzdHJ1Y3R1cmUKCQlGaWxlIHRlbXAgPSBjb25mRGlyLmFwcGVuZCgiY29uZiIpLnRvRmlsZSgpOwoJCWlmICghdGVtcC5leGlzdHMoKSkKCQkJdGVtcC5ta2RpcnMoKTsKCQl0ZW1wID0gY29uZkRpci5hcHBlbmQoImxvZ3MiKS50b0ZpbGUoKTsKCQlpZiAoIXRlbXAuZXhpc3RzKCkpCgkJCXRlbXAubWtkaXJzKCk7CgkJdGVtcCA9IGNvbmZEaXIuYXBwZW5kKCJ0ZW1wIikudG9GaWxlKCk7CgkJaWYgKCF0ZW1wLmV4aXN0cygpKQoJCQl0ZW1wLm1rZGlycygpOwoJCXRlbXAgPSBjb25mRGlyLmFwcGVuZCgid2ViYXBwcy9ST09UL1dFQi1JTkYiKS50b0ZpbGUoKTsKCQlpZiAoIXRlbXAuZXhpc3RzKCkpCgkJCXRlbXAubWtkaXJzKCk7CgkJdGVtcCA9IGNvbmZEaXIuYXBwZW5kKCJ3b3JrIikudG9GaWxlKCk7CgkJaWYgKCF0ZW1wLmV4aXN0cygpKQoJCQl0ZW1wLm1rZGlycygpOwoKCQlyZXR1cm4gbmV3IFN0YXR1cyhJU3RhdHVzLk9LLCBUb21jYXRQbHVnaW4uUExVR0lOX0lELCAwLCBNZXNzYWdlcy5ydW50aW1lRGlyUHJlcGFyZWQsIG51bGwpOwkJCgl9Cn0=