cGFja2FnZSBvcmcuZWNsaXBzZS5qc3Quc2VydmVyLnRvbWNhdC5jb3JlLmludGVybmFsOwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBDb3B5cmlnaHQgKGMpIDIwMDMgSUJNIENvcnBvcmF0aW9uIGFuZCBvdGhlcnMuCiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuIKAgVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscwogKiBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBDb21tb24gUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2NwbC12MTAuaHRtbAqgKgogKiBDb250cmlidXRvcnM6CiAqICAgIElCTSAtIEluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRSZWFkZXI7CmltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkV3JpdGVyOwppbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOwppbXBvcnQgamF2YS5pby5GaWxlV3JpdGVyOwppbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW1SZWFkZXI7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwppbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwppbXBvcnQgamF2YS51dGlsLkxpc3Q7CgppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSUZpbGU7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JRm9sZGVyOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLkNvcmVFeGNlcHRpb247CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuSVBhdGg7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuSVByb2dyZXNzTW9uaXRvcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5JU3RhdHVzOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLlN0YXR1czsKaW1wb3J0IG9yZy5lY2xpcHNlLmpzdC5zZXJ2ZXIudG9tY2F0LmNvcmUuV2ViTW9kdWxlOwppbXBvcnQgb3JnLmVjbGlwc2UuanN0LnNlcnZlci50b21jYXQuY29yZS5pbnRlcm5hbC54bWwuRmFjdG9yeTsKaW1wb3J0IG9yZy5lY2xpcHNlLmpzdC5zZXJ2ZXIudG9tY2F0LmNvcmUuaW50ZXJuYWwueG1sLlhNTFV0aWw7CmltcG9ydCBvcmcuZWNsaXBzZS5qc3Quc2VydmVyLnRvbWNhdC5jb3JlLmludGVybmFsLnhtbC5zZXJ2ZXI0MC5Db25uZWN0b3I7CmltcG9ydCBvcmcuZWNsaXBzZS5qc3Quc2VydmVyLnRvbWNhdC5jb3JlLmludGVybmFsLnhtbC5zZXJ2ZXI0MC5Db250ZXh0OwppbXBvcnQgb3JnLmVjbGlwc2UuanN0LnNlcnZlci50b21jYXQuY29yZS5pbnRlcm5hbC54bWwuc2VydmVyNDAuRW5naW5lOwppbXBvcnQgb3JnLmVjbGlwc2UuanN0LnNlcnZlci50b21jYXQuY29yZS5pbnRlcm5hbC54bWwuc2VydmVyNDAuSG9zdDsKaW1wb3J0IG9yZy5lY2xpcHNlLmpzdC5zZXJ2ZXIudG9tY2F0LmNvcmUuaW50ZXJuYWwueG1sLnNlcnZlcjQwLlNlcnZlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpzdC5zZXJ2ZXIudG9tY2F0LmNvcmUuaW50ZXJuYWwueG1sLnNlcnZlcjQwLlNlcnZpY2U7CmltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7CmltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKCmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSVNlcnZlclBvcnQ7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUudXRpbC5Qcm9ncmVzc1V0aWw7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUudXRpbC5TZXJ2ZXJQb3J0OwovKioKICogVG9tY2F0IHY0LjAgc2VydmVyIGNvbmZpZ3VyYXRpb24uCiAqLwpwdWJsaWMgY2xhc3MgVG9tY2F0NDBDb25maWd1cmF0aW9uIGV4dGVuZHMgVG9tY2F0Q29uZmlndXJhdGlvbiB7Cglwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBERUZBVUxUX1NFUlZJQ0UgPSAiVG9tY2F0LVN0YW5kYWxvbmUiOwoJcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgSFRUUF9DT05ORUNUT1IgPSAib3JnLmFwYWNoZS5jYXRhbGluYS5jb25uZWN0b3IuaHR0cC5IdHRwQ29ubmVjdG9yIjsKCXByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFNTTF9TT0NLRVRfRkFDVE9SWSA9ICJvcmcuYXBhY2hlLmNhdGFsaW5hLm5ldC5TU0xTZXJ2ZXJTb2NrZXRGYWN0b3J5IjsKCXByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFRFU1RfQ09OTkVDVE9SID0gIm9yZy5hcGFjaGUuY2F0YWxpbmEuY29ubmVjdG9yLnRlc3QuSHR0cENvbm5lY3RvciI7Cglwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBBUEFDSEVfQ09OTkVDVE9SID0gIm9yZy5hcGFjaGUuY2F0YWxpbmEuY29ubmVjdG9yLndhcnAuV2FycENvbm5lY3RvciI7CgoJcHJvdGVjdGVkIFNlcnZlciBzZXJ2ZXI7Cglwcm90ZWN0ZWQgRmFjdG9yeSBzZXJ2ZXJGYWN0b3J5OwoJcHJvdGVjdGVkIGJvb2xlYW4gaXNTZXJ2ZXJEaXJ0eTsKCglwcm90ZWN0ZWQgV2ViQXBwRG9jdW1lbnQgd2ViQXBwRG9jdW1lbnQ7CgoJcHJvdGVjdGVkIERvY3VtZW50IHRvbWNhdFVzZXJzRG9jdW1lbnQ7CgoJcHJvdGVjdGVkIFN0cmluZyBwb2xpY3lGaWxlOwoJcHJvdGVjdGVkIGJvb2xlYW4gaXNQb2xpY3lEaXJ0eTsKCgkvKioKCSAqIFRvbWNhdDQwQ29uZmlndXJhdGlvbiBjb25zdHJ1Y3RvciBjb21tZW50LgoJICovCglwdWJsaWMgVG9tY2F0NDBDb25maWd1cmF0aW9uKCkgewoJCXN1cGVyKCk7Cgl9CgkJCgkvKioKCSAqIFJldHVybnMgdGhlIHJvb3Qgb2YgdGhlIGRvY2Jhc2UgcGFyYW1ldGVyLgoJICoKCSAqIEByZXR1cm4gamF2YS5sYW5nLlN0cmluZwoJICovCglwcm90ZWN0ZWQgU3RyaW5nIGdldERvY0Jhc2VSb290KCkgewoJCXJldHVybiAid2ViYXBwcy8iOwoJfQoKCS8qKgoJICogUmV0dXJuIHRoZSBwb3J0IG51bWJlci4KCSAqIEByZXR1cm4gaW50CgkgKi8KCXB1YmxpYyBJU2VydmVyUG9ydCBnZXRNYWluUG9ydCgpIHsKCQlJdGVyYXRvciBpdGVyYXRvciA9IGdldFNlcnZlclBvcnRzKCkuaXRlcmF0b3IoKTsKCQl3aGlsZSAoaXRlcmF0b3IuaGFzTmV4dCgpKSB7CgkJCUlTZXJ2ZXJQb3J0IHBvcnQgPSAoSVNlcnZlclBvcnQpIGl0ZXJhdG9yLm5leHQoKTsKCQkJaWYgKHBvcnQuZ2V0TmFtZSgpLmVxdWFscygiSFRUUCBDb25uZWN0b3IiKSkKCQkJCXJldHVybiBwb3J0OwoJCX0KCQlyZXR1cm4gbnVsbDsKCX0KCQoJLyoqCgkgKiBSZXR1cm5zIHRoZSBtaW1lIG1hcHBpbmdzLgoJICogQHJldHVybiBqYXZhLnV0aWwuTGlzdAoJICovCglwdWJsaWMgTGlzdCBnZXRNaW1lTWFwcGluZ3MoKSB7CgkJcmV0dXJuIHdlYkFwcERvY3VtZW50LmdldE1pbWVNYXBwaW5ncygpOwoJfQoKCS8qKgoJICogUmV0dXJucyB0aGUgcHJlZml4IHRoYXQgaXMgdXNlZCBpbiBmcm9udCBvZiB0aGUKCSAqIHdlYiBtb2R1bGUgcGF0aCBwcm9wZXJ0eS4gKGUuZy4gIndlYmFwcHMiKQoJICoKCSAqIEByZXR1cm4gamF2YS5sYW5nLlN0cmluZwoJICovCglwdWJsaWMgU3RyaW5nIGdldFBhdGhQcmVmaXgoKSB7CgkJcmV0dXJuICIiOwoJfQoJCgkvKioKCSAqIFJldHVybiB0aGUgZG9jQmFzZSBvZiB0aGUgUk9PVCB3ZWIgbW9kdWxlLgoJICoKCSAqIEByZXR1cm4gamF2YS5sYW5nLlN0cmluZwoJICovCglwcm90ZWN0ZWQgU3RyaW5nIGdldFJPT1RNb2R1bGVEb2NCYXNlKCkgewoJCXJldHVybiAiUk9PVCI7Cgl9CgkKCS8qKgoJICogUmV0dXJucyBhIGxpc3Qgb2YgU2VydmVyUG9ydHMgdGhhdCB0aGlzIGNvbmZpZ3VyYXRpb24gdXNlcy4KCSAqCgkgKiBAcmV0dXJuIGphdmEudXRpbC5MaXN0CgkgKi8KCXB1YmxpYyBMaXN0IGdldFNlcnZlclBvcnRzKCkgewoJCUxpc3QgcG9ydHMgPSBuZXcgQXJyYXlMaXN0KCk7CgkKCQkvLyBmaXJzdCBhZGQgc2VydmVyIHBvcnQKCQl0cnkgewoJCQlpbnQgcG9ydCA9IEludGVnZXIucGFyc2VJbnQoc2VydmVyLmdldFBvcnQoKSk7CgkJCXBvcnRzLmFkZChuZXcgU2VydmVyUG9ydCgic2VydmVyIiwgIlNlcnZlciBwb3J0IiwgcG9ydCwgIlRDUElQIikpOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7IH0KCQoJCS8vIGFkZCBjb25uZWN0b3JzCgkJdHJ5IHsKCQkJaW50IHNpemUgPSBzZXJ2ZXIuZ2V0U2VydmljZUNvdW50KCk7CgkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQlTZXJ2aWNlIHNlcnZpY2UgPSBzZXJ2ZXIuZ2V0U2VydmljZShpKTsKCQkJCWludCBzaXplMiA9IHNlcnZpY2UuZ2V0Q29ubmVjdG9yQ291bnQoKTsKCQkJCWZvciAoaW50IGogPSAwOyBqIDwgc2l6ZTI7IGorKykgewoJCQkJCUNvbm5lY3RvciBjb25uZWN0b3IgPSBzZXJ2aWNlLmdldENvbm5lY3RvcihqKTsKCQkJCQlTdHJpbmcgY2xhc3NOYW1lID0gY29ubmVjdG9yLmdldENsYXNzTmFtZSgpOwoJCQkJCVN0cmluZyBuYW1lID0gInVua25vd24gcG9ydCI7CgkJCQkJU3RyaW5nIHByb3RvY29sID0gIlRDUElQIjsKCQkJCQlib29sZWFuIGFkdmFuY2VkID0gdHJ1ZTsKCQkJCQlTdHJpbmdbXSBjb250ZW50VHlwZXMgPSBudWxsOwoJCQkJCWludCBwb3J0ID0gLTE7CgkJCQkJdHJ5IHsKCQkJCQkJcG9ydCA9IEludGVnZXIucGFyc2VJbnQoY29ubmVjdG9yLmdldFBvcnQoKSk7CgkJCQkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsgfQoJCQkJCWlmIChIVFRQX0NPTk5FQ1RPUi5lcXVhbHMoY2xhc3NOYW1lKSkgewoJCQkJCQluYW1lID0gIkhUVFAgQ29ubmVjdG9yIjsKCQkJCQkJcHJvdG9jb2wgPSAiSFRUUCI7CgkJCQkJCWNvbnRlbnRUeXBlcyA9IG5ldyBTdHJpbmdbXSB7ICJ3ZWIiLCAid2Vic2VydmljZXMiIH07CgkJCQkJCS8vIGNoZWNrIGZvciBTU0wgY29ubmVjdG9yCgkJCQkJCXRyeSB7CgkJCQkJCQlFbGVtZW50IGVsZW1lbnQgPSBjb25uZWN0b3IuZ2V0U3ViRWxlbWVudCgiRmFjdG9yeSIpOwoJCQkJCQkJaWYgKFNTTF9TT0NLRVRfRkFDVE9SWS5lcXVhbHMoZWxlbWVudC5nZXRBdHRyaWJ1dGUoImNsYXNzTmFtZSIpKSkgewoJCQkJCQkJCW5hbWUgPSAiU1NMIENvbm5lY3RvciI7CgkJCQkJCQkJcHJvdG9jb2wgPSAiU1NMIjsKCQkJCQkJCX0KCQkJCQkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsgfQoJCQkJCQlpZiAoIkhUVFAiLmVxdWFscyhwcm90b2NvbCkpCgkJCQkJCQlhZHZhbmNlZCA9IGZhbHNlOwoJCQkJCX0gZWxzZSBpZiAoQVBBQ0hFX0NPTk5FQ1RPUi5lcXVhbHMoY2xhc3NOYW1lKSkKCQkJCQkJbmFtZSA9ICJBcGFjaGUgQ29ubmVjdG9yIjsKCQkJCQlpZiAoY2xhc3NOYW1lICE9IG51bGwgJiYgY2xhc3NOYW1lLmxlbmd0aCgpID4gMCkKCQkJCQkJcG9ydHMuYWRkKG5ldyBTZXJ2ZXJQb3J0KGkgKyAiLyIgKyBqLCBuYW1lLCBwb3J0LCBwcm90b2NvbCwgY29udGVudFR5cGVzLCBhZHZhbmNlZCkpOwoJCQkJfQoJCQl9CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoIkVycm9yIGdldHRpbmcgc2VydmVyIHBvcnRzIiwgZSk7CgkJfQoJCXJldHVybiBwb3J0czsKCX0KCQoJLyoqCgkgKiBSZXR1cm4gYSBsaXN0IG9mIHRoZSB3ZWIgbW9kdWxlcyBpbiB0aGlzIHNlcnZlci4KCSAqIEByZXR1cm4gamF2YS51dGlsLkxpc3QKCSAqLwoJcHVibGljIExpc3QgZ2V0V2ViTW9kdWxlcygpIHsKCQlMaXN0IGxpc3QgPSBuZXcgQXJyYXlMaXN0KCk7CgkKCQl0cnkgewoJCQlpbnQgc2l6ZSA9IHNlcnZlci5nZXRTZXJ2aWNlQ291bnQoKTsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCVNlcnZpY2Ugc2VydmljZSA9IHNlcnZlci5nZXRTZXJ2aWNlKGkpOwoJCQkJaWYgKHNlcnZpY2UuZ2V0TmFtZSgpLmVxdWFsc0lnbm9yZUNhc2UoREVGQVVMVF9TRVJWSUNFKSkgewoJCQkJCUVuZ2luZSBlbmdpbmUgPSBzZXJ2aWNlLmdldEVuZ2luZSgpOwoJCQkJCUhvc3QgaG9zdCA9IGVuZ2luZS5nZXRIb3N0KCk7CgkJCQkJaW50IHNpemUyID0gaG9zdC5nZXRDb250ZXh0Q291bnQoKTsKCQkJCQlmb3IgKGludCBqID0gMDsgaiA8IHNpemUyOyBqKyspIHsKCQkJCQkJQ29udGV4dCBjb250ZXh0ID0gaG9zdC5nZXRDb250ZXh0KGopOwoJCQkJCQlTdHJpbmcgcmVsb2FkID0gY29udGV4dC5nZXRSZWxvYWRhYmxlKCk7CgkJCQkJCWlmIChyZWxvYWQgPT0gbnVsbCkKCQkJCQkJCXJlbG9hZCA9ICJmYWxzZSI7CgkJCQkJCVdlYk1vZHVsZSBtb2R1bGUgPSBuZXcgV2ViTW9kdWxlKGNvbnRleHQuZ2V0UGF0aCgpLCAKCQkJCQkJCWNvbnRleHQuZ2V0RG9jQmFzZSgpLCBjb250ZXh0LmdldFNvdXJjZSgpLAoJCQkJCQkJcmVsb2FkLmVxdWFsc0lnbm9yZUNhc2UoInRydWUiKSA/IHRydWUgOiBmYWxzZSk7CgkJCQkJCWxpc3QuYWRkKG1vZHVsZSk7CgkJCQkJfQoJCQkJfQoJCQl9CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoIkVycm9yIGdldHRpbmcgbW9kdWxlcyIsIGUpOwoJCX0KCQlyZXR1cm4gbGlzdDsKCX0KCQoJLyoqCgkgKiBAcGFyYW0gamF2YS5sYW5nLlN0cmluZwoJICogQHJldHVybiBvcmcuZWNsaXBzZS5qc3Quc2VydmVyLnRvbWNhdC5pbnRlcm5hbC5Ub21jYXQ0MENvbmZpZ3VyYXRpb24KCSAqLwoJcHVibGljIHZvaWQgbG9hZChJUGF0aCBwYXRoLCBJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHRocm93cyBDb3JlRXhjZXB0aW9uIHsKCQl0cnkgewoJCQltb25pdG9yID0gUHJvZ3Jlc3NVdGlsLmdldE1vbml0b3JGb3IobW9uaXRvcik7CgkJCW1vbml0b3IuYmVnaW5UYXNrKFRvbWNhdFBsdWdpbi5nZXRSZXNvdXJjZSgiJWxvYWRpbmdUYXNrIiksIDUpOwoJCQkKCQkJLy8gY2hlY2sgZm9yIGNhdGFsaW5hLnBvbGljeSB0byB2ZXJpZnkgdGhhdCB0aGlzIGlzIGEgdjQuMCBjb25maWcKCQkJSW5wdXRTdHJlYW0gaW4gPSBuZXcgRmlsZUlucHV0U3RyZWFtKHBhdGguYXBwZW5kKCJjYXRhbGluYS5wb2xpY3kiKS50b0ZpbGUoKSk7CgkJCWluLnJlYWQoKTsKCQkJaW4uY2xvc2UoKTsKCQkJbW9uaXRvci53b3JrZWQoMSk7CgkKCQkJc2VydmVyRmFjdG9yeSA9IG5ldyBGYWN0b3J5KCk7CgkJCXNlcnZlckZhY3Rvcnkuc2V0UGFja2FnZU5hbWUoIm9yZy5lY2xpcHNlLmpzdC5zZXJ2ZXIudG9tY2F0LmNvcmUuaW50ZXJuYWwueG1sLnNlcnZlcjQwIik7CgkJCXNlcnZlciA9IChTZXJ2ZXIpIHNlcnZlckZhY3RvcnkubG9hZERvY3VtZW50KG5ldyBGaWxlSW5wdXRTdHJlYW0ocGF0aC5hcHBlbmQoInNlcnZlci54bWwiKS50b0ZpbGUoKSkpOwoJCQlpZiAoIVRvbWNhdENvbmZpZ3VyYXRpb25VdGlsLnZlcmlmeUNvbmZpZ3VyYXRpb24odGhpcywgVG9tY2F0Q29uZmlndXJhdGlvblV0aWwuQ09ORklHVVJBVElPTl9WNDApKQoJCQkJdGhyb3cgbmV3IENvcmVFeGNlcHRpb24obnVsbCk7CgkJCW1vbml0b3Iud29ya2VkKDEpOwoKCQkJd2ViQXBwRG9jdW1lbnQgPSBuZXcgV2ViQXBwRG9jdW1lbnQocGF0aC5hcHBlbmQoIndlYi54bWwiKSk7CgkJCW1vbml0b3Iud29ya2VkKDEpOwoJCgkJCXRvbWNhdFVzZXJzRG9jdW1lbnQgPSBYTUxVdGlsLmdldERvY3VtZW50QnVpbGRlcigpLnBhcnNlKG5ldyBJbnB1dFNvdXJjZShuZXcgRmlsZUlucHV0U3RyZWFtKHBhdGguYXBwZW5kKCJ0b21jYXQtdXNlcnMueG1sIikudG9GaWxlKCkpKSk7CgkJCW1vbml0b3Iud29ya2VkKDEpOwoJCQoJCQkvLyBsb2FkIHBvbGljeSBmaWxlCgkJCUJ1ZmZlcmVkUmVhZGVyIGJyID0gbnVsbDsKCQkJdHJ5IHsKCQkJCWJyID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBJbnB1dFN0cmVhbVJlYWRlcihuZXcgRmlsZUlucHV0U3RyZWFtKHBhdGguYXBwZW5kKCJjYXRhbGluYS5wb2xpY3kiKS50b0ZpbGUoKSkpKTsKCQkJCVN0cmluZyB0ZW1wID0gYnIucmVhZExpbmUoKTsKCQkJCXBvbGljeUZpbGUgPSAiIjsKCQkJCXdoaWxlICh0ZW1wICE9IG51bGwpIHsKCQkJCQlwb2xpY3lGaWxlICs9IHRlbXAgKyAiXG4iOwoJCQkJCXRlbXAgPSBici5yZWFkTGluZSgpOwoJCQkJfQoJCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQkJVHJhY2UudHJhY2UoVHJhY2UuV0FSTklORywgIkNvdWxkIG5vdCBsb2FkIHBvbGljeSBmaWxlIiwgZSk7CgkJCX0gZmluYWxseSB7CgkJCQlpZiAoYnIgIT0gbnVsbCkKCQkJCQlici5jbG9zZSgpOwoJCQl9CgkJCW1vbml0b3Iud29ya2VkKDEpOwoJCgkJCWlmIChtb25pdG9yLmlzQ2FuY2VsZWQoKSkKCQkJCXJldHVybjsKCQkJbW9uaXRvci5kb25lKCk7CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoVHJhY2UuV0FSTklORywgIkNvdWxkIG5vdCBsb2FkIFRvbWNhdCB2NC4wIGNvbmZpZ3VyYXRpb24gZnJvbSAiICsgcGF0aC50b09TU3RyaW5nKCkgKyAiOiAiICsgZS5nZXRNZXNzYWdlKCkpOwoJCQl0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbihuZXcgU3RhdHVzKElTdGF0dXMuRVJST1IsIFRvbWNhdFBsdWdpbi5QTFVHSU5fSUQsIDAsIFRvbWNhdFBsdWdpbi5nZXRSZXNvdXJjZSgiJWVycm9yQ291bGROb3RMb2FkQ29uZmlndXJhdGlvbiIpLCBlKSk7CgkJfQoJfQoKCS8qKgoJICogUmVsb2FkIHRoZSBjb25maWd1cmF0aW9uLgoJICovCglwdWJsaWMgdm9pZCBsb2FkKElGb2xkZXIgZm9sZGVyLCBJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHRocm93cyBDb3JlRXhjZXB0aW9uIHsKCQl0cnkgewoJCQltb25pdG9yID0gUHJvZ3Jlc3NVdGlsLmdldE1vbml0b3JGb3IobW9uaXRvcik7CgkJCW1vbml0b3IuYmVnaW5UYXNrKFRvbWNhdFBsdWdpbi5nZXRSZXNvdXJjZSgiJWxvYWRpbmdUYXNrIiksIDgwMCk7CgkKCQkJLy8gY2hlY2sgZm9yIGNhdGFsaW5hLnBvbGljeSB0byB2ZXJpZnkgdGhhdCB0aGlzIGlzIGEgdjQuMCBjb25maWcKCQkJSUZpbGUgZmlsZSA9IGZvbGRlci5nZXRGaWxlKCJjYXRhbGluYS5wb2xpY3kiKTsKCQkJaWYgKCFmaWxlLmV4aXN0cygpKQoJCQkJdGhyb3cgbmV3IENvcmVFeGNlcHRpb24obmV3IFN0YXR1cyhJU3RhdHVzLldBUk5JTkcsIFRvbWNhdFBsdWdpbi5QTFVHSU5fSUQsIDAsIFRvbWNhdFBsdWdpbi5nZXRSZXNvdXJjZSgiJWVycm9yQ291bGROb3RMb2FkQ29uZmlndXJhdGlvbiIpLCBudWxsKSk7CgkKCQkJLy8gbG9hZCBzZXJ2ZXIueG1sCgkJCWZpbGUgPSBmb2xkZXIuZ2V0RmlsZSgic2VydmVyLnhtbCIpOwoJCQlJbnB1dFN0cmVhbSBpbiA9IGZpbGUuZ2V0Q29udGVudHMoKTsKCQkJc2VydmVyRmFjdG9yeSA9IG5ldyBGYWN0b3J5KCk7CgkJCXNlcnZlckZhY3Rvcnkuc2V0UGFja2FnZU5hbWUoIm9yZy5lY2xpcHNlLmpzdC5zZXJ2ZXIudG9tY2F0LmNvcmUuaW50ZXJuYWwueG1sLnNlcnZlcjQwIik7CgkJCXNlcnZlciA9IChTZXJ2ZXIpIHNlcnZlckZhY3RvcnkubG9hZERvY3VtZW50KGluKTsKCQkJaWYgKCFUb21jYXRDb25maWd1cmF0aW9uVXRpbC52ZXJpZnlDb25maWd1cmF0aW9uKHRoaXMsIFRvbWNhdENvbmZpZ3VyYXRpb25VdGlsLkNPTkZJR1VSQVRJT05fVjQwKSkKCQkJCXRocm93IG5ldyBFeGNlcHRpb24oIk5vdCBhIFRvbWNhdCB2NC4wIGNvbmZpZ3VyYXRpb24iKTsKCQkJbW9uaXRvci53b3JrZWQoMjAwKTsKCQoJCQkvLyBsb2FkIHdlYi54bWwKCQkJZmlsZSA9IGZvbGRlci5nZXRGaWxlKCJ3ZWIueG1sIik7CgkJCXdlYkFwcERvY3VtZW50ID0gbmV3IFdlYkFwcERvY3VtZW50KGZpbGUpOwoJCQltb25pdG9yLndvcmtlZCgyMDApOwoJCgkJCS8vIGxvYWQgdG9tY2F0LXVzZXJzLnhtbAoJCQlmaWxlID0gZm9sZGVyLmdldEZpbGUoInRvbWNhdC11c2Vycy54bWwiKTsKCQkJaW4gPSBmaWxlLmdldENvbnRlbnRzKCk7CgkJCQoJCQl0b21jYXRVc2Vyc0RvY3VtZW50ID0gWE1MVXRpbC5nZXREb2N1bWVudEJ1aWxkZXIoKS5wYXJzZShuZXcgSW5wdXRTb3VyY2UoaW4pKTsKCQkJbW9uaXRvci53b3JrZWQoMjAwKTsKCQkKCQkJLy8gbG9hZCBjYXRhbGluYS5wb2xpY3kKCQkJZmlsZSA9IGZvbGRlci5nZXRGaWxlKCJjYXRhbGluYS5wb2xpY3kiKTsKCQkJaW4gPSBmaWxlLmdldENvbnRlbnRzKCk7CgkJCUJ1ZmZlcmVkUmVhZGVyIGJyID0gbnVsbDsKCQkJdHJ5IHsKCQkJCWJyID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBJbnB1dFN0cmVhbVJlYWRlcihpbikpOwoJCQkJU3RyaW5nIHRlbXAgPSBici5yZWFkTGluZSgpOwoJCQkJcG9saWN5RmlsZSA9ICIiOwoJCQkJd2hpbGUgKHRlbXAgIT0gbnVsbCkgewoJCQkJCXBvbGljeUZpbGUgKz0gdGVtcCArICJcbiI7CgkJCQkJdGVtcCA9IGJyLnJlYWRMaW5lKCk7CgkJCQl9CgkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5XQVJOSU5HLCAiQ291bGQgbm90IGxvYWQgcG9saWN5IGZpbGUiLCBlKTsKCQkJfSBmaW5hbGx5IHsKCQkJCWlmIChiciAhPSBudWxsKQoJCQkJCWJyLmNsb3NlKCk7CgkJCX0KCQkJbW9uaXRvci53b3JrZWQoMjAwKTsKCQoJCQlpZiAobW9uaXRvci5pc0NhbmNlbGVkKCkpCgkJCQl0aHJvdyBuZXcgRXhjZXB0aW9uKCJDYW5jZWxsZWQiKTsKCQkJbW9uaXRvci5kb25lKCk7CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoVHJhY2UuV0FSTklORywgIkNvdWxkIG5vdCByZWxvYWQgVG9tY2F0IHY0LjAgY29uZmlndXJhdGlvbiBmcm9tOiAiICsgZm9sZGVyLmdldEZ1bGxQYXRoKCkgKyAiOiAiICsgZS5nZXRNZXNzYWdlKCkpOwoJCQl0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbihuZXcgU3RhdHVzKElTdGF0dXMuRVJST1IsIFRvbWNhdFBsdWdpbi5QTFVHSU5fSUQsIDAsIFRvbWNhdFBsdWdpbi5nZXRSZXNvdXJjZSgiJWVycm9yQ291bGROb3RMb2FkQ29uZmlndXJhdGlvbiIpLCBlKSk7CgkJfQoJfQoJCgkvKioKCSAqIFNhdmUgdG8gdGhlIGdpdmVuIGRpcmVjdG9yeS4KCSAqIEBwYXJhbSBkaXIgamF2YS5pby5GaWxlCgkgKiBAcGFyYW0gZm9yY2VEaXJ0eSBib29sZWFuCgkgKiBAcGFyYW0gbW9uaXRvciBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuSVByb2dyZXNzTW9uaXRvcgoJICogQGV4Y2VwdGlvbiBqYXZhLmlvLklPRXhjZXB0aW9uCgkgKi8KCXByb3RlY3RlZCB2b2lkIHNhdmUoSVBhdGggcGF0aCwgYm9vbGVhbiBmb3JjZURpcnR5LCBJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHRocm93cyBDb3JlRXhjZXB0aW9uIHsKCQl0cnkgewoJCQltb25pdG9yID0gUHJvZ3Jlc3NVdGlsLmdldE1vbml0b3JGb3IobW9uaXRvcik7CgkJCW1vbml0b3IuYmVnaW5UYXNrKFRvbWNhdFBsdWdpbi5nZXRSZXNvdXJjZSgiJXNhdmluZ1Rhc2siKSwgMyk7CgkKCQkJLy8gbWFrZSBzdXJlIGRpcmVjdG9yeSBleGlzdHMKCQkJaWYgKCFwYXRoLnRvRmlsZSgpLmV4aXN0cygpKSB7CgkJCQlmb3JjZURpcnR5ID0gdHJ1ZTsKCQkJCXBhdGgudG9GaWxlKCkubWtkaXIoKTsKCQkJfQoJCQltb25pdG9yLndvcmtlZCgxKTsKCQoJCQkvLyBzYXZlIGZpbGVzCgkJCWlmIChmb3JjZURpcnR5IHx8IGlzU2VydmVyRGlydHkpCgkJCQlzZXJ2ZXJGYWN0b3J5LnNhdmUocGF0aC5hcHBlbmQoInNlcnZlci54bWwiKS50b09TU3RyaW5nKCkpOwoJCQltb25pdG9yLndvcmtlZCgxKTsKCQoJCQkvL2lmIChmb3JjZURpcnR5IHx8IGlzV2ViQXBwRGlydHkpCgkJCS8vCXdlYkFwcEZhY3Rvcnkuc2F2ZShkaXJQYXRoICsgIndlYi54bWwiKTsKCQkJLy93ZWJBcHBEb2N1bWVudC5zYXZlKHBhdGgudG9PU1N0cmluZygpLCBmb3JjZURpcnR5IHx8IGlzUG9saWN5RGlydHkpOwoJCQl3ZWJBcHBEb2N1bWVudC5zYXZlKHBhdGguYXBwZW5kKCJ3ZWIueG1sIikudG9PU1N0cmluZygpLCBmb3JjZURpcnR5KTsKCQkJbW9uaXRvci53b3JrZWQoMSk7CgkKCQkJaWYgKGZvcmNlRGlydHkpCgkJCQlYTUxVdGlsLnNhdmUocGF0aC5hcHBlbmQoInRvbWNhdC11c2Vycy54bWwiKS50b09TU3RyaW5nKCksIHRvbWNhdFVzZXJzRG9jdW1lbnQpOwoJCQltb25pdG9yLndvcmtlZCgxKTsKCQoJCQlpZiAoZm9yY2VEaXJ0eSB8fCBpc1BvbGljeURpcnR5KSB7CgkJCQlCdWZmZXJlZFdyaXRlciBidyA9IG5ldyBCdWZmZXJlZFdyaXRlcihuZXcgRmlsZVdyaXRlcihwYXRoLmFwcGVuZCgiY2F0YWxpbmEucG9saWN5IikudG9GaWxlKCkpKTsKCQkJCWJ3LndyaXRlKHBvbGljeUZpbGUpOwoJCQkJYncuY2xvc2UoKTsKCQkJfQoJCQltb25pdG9yLndvcmtlZCgxKTsKCQkJaXNTZXJ2ZXJEaXJ0eSA9IGZhbHNlOwoJCQlpc1BvbGljeURpcnR5ID0gZmFsc2U7CgkKCQkJaWYgKG1vbml0b3IuaXNDYW5jZWxlZCgpKQoJCQkJcmV0dXJuOwoJCQltb25pdG9yLmRvbmUoKTsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQlUcmFjZS50cmFjZSgiQ291bGQgbm90IHNhdmUgVG9tY2F0IHY0LjAgY29uZmlndXJhdGlvbiB0byAiICsgcGF0aCwgZSk7CgkJCXRocm93IG5ldyBDb3JlRXhjZXB0aW9uKG5ldyBTdGF0dXMoSVN0YXR1cy5FUlJPUiwgVG9tY2F0UGx1Z2luLlBMVUdJTl9JRCwgMCwgVG9tY2F0UGx1Z2luLmdldFJlc291cmNlKCIlZXJyb3JDb3VsZE5vdFNhdmVDb25maWd1cmF0aW9uIiwgbmV3IFN0cmluZ1tdIHtlLmdldExvY2FsaXplZE1lc3NhZ2UoKX0pLCBlKSk7CgkJfQoJfQoJCglwdWJsaWMgdm9pZCBzYXZlKElQYXRoIHBhdGgsIElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgdGhyb3dzIENvcmVFeGNlcHRpb24gewoJCXNhdmUocGF0aCwgdHJ1ZSwgbW9uaXRvcik7Cgl9CgoJLyoqCgkgKiBTYXZlIHRoZSBpbmZvcm1hdGlvbiBoZWxkIGJ5IHRoaXMgb2JqZWN0IHRvIHRoZSBnaXZlbiBkaXJlY3RvcnkuCgkgKgoJICogQHBhcmFtIGRpcgoJICogQHBhcmFtIG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5JUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IKCSAqIEB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbgoJICovCglwdWJsaWMgdm9pZCBzYXZlKElGb2xkZXIgZm9sZGVyLCBJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHRocm93cyBDb3JlRXhjZXB0aW9uIHsKCQl0cnkgewoJCQltb25pdG9yID0gUHJvZ3Jlc3NVdGlsLmdldE1vbml0b3JGb3IobW9uaXRvcik7CgkJCW1vbml0b3IuYmVnaW5UYXNrKFRvbWNhdFBsdWdpbi5nZXRSZXNvdXJjZSgiJXNhdmluZ1Rhc2siKSwgOTAwKTsKCQoJCQkvLyBzYXZlIHNlcnZlci54bWwKCQkJYnl0ZVtdIGRhdGEgPSBzZXJ2ZXJGYWN0b3J5LmdldENvbnRlbnRzKCk7CgkJCUlucHV0U3RyZWFtIGluID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGRhdGEpOwoJCQlJRmlsZSBmaWxlID0gZm9sZGVyLmdldEZpbGUoInNlcnZlci54bWwiKTsKCQkJaWYgKGZpbGUuZXhpc3RzKCkpIHsKCQkJCWlmIChpc1NlcnZlckRpcnR5KQoJCQkJCWZpbGUuc2V0Q29udGVudHMoaW4sIHRydWUsIHRydWUsIFByb2dyZXNzVXRpbC5nZXRTdWJNb25pdG9yRm9yKG1vbml0b3IsIDIwMCkpOwoJCQkJZWxzZQoJCQkJCW1vbml0b3Iud29ya2VkKDIwMCk7CgkJCX0gZWxzZQoJCQkJZmlsZS5jcmVhdGUoaW4sIHRydWUsIFByb2dyZXNzVXRpbC5nZXRTdWJNb25pdG9yRm9yKG1vbml0b3IsIDIwMCkpOwoJCgkJCS8vIHNhdmUgd2ViLnhtbAoJCQl3ZWJBcHBEb2N1bWVudC5zYXZlKGZvbGRlci5nZXRGaWxlKCJ3ZWIueG1sIiksIFByb2dyZXNzVXRpbC5nZXRTdWJNb25pdG9yRm9yKG1vbml0b3IsIDIwMCkpOwoJCgkJCS8vIHNhdmUgdG9tY2F0LXVzZXJzLnhtbAoJCQlkYXRhID0gWE1MVXRpbC5nZXRDb250ZW50cyh0b21jYXRVc2Vyc0RvY3VtZW50KTsKCQkJaW4gPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oZGF0YSk7CgkJCWZpbGUgPSBmb2xkZXIuZ2V0RmlsZSgidG9tY2F0LXVzZXJzLnhtbCIpOwoJCQlpZiAoZmlsZS5leGlzdHMoKSkKCQkJCW1vbml0b3Iud29ya2VkKDIwMCk7CgkJCQkvL2ZpbGUuc2V0Q29udGVudHMoaW4sIHRydWUsIHRydWUsIFByb2dyZXNzVXRpbC5nZXRTdWJNb25pdG9yRm9yKG1vbml0b3IsIDIwMCkpOwoJCQllbHNlCgkJCQlmaWxlLmNyZWF0ZShpbiwgdHJ1ZSwgUHJvZ3Jlc3NVdGlsLmdldFN1Yk1vbml0b3JGb3IobW9uaXRvciwgMjAwKSk7CgkKCQkJLy8gc2F2ZSBjYXRhbGluYS5wb2xpY3kKCQkJaW4gPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0ocG9saWN5RmlsZS5nZXRCeXRlcygpKTsKCQkJZmlsZSA9IGZvbGRlci5nZXRGaWxlKCJjYXRhbGluYS5wb2xpY3kiKTsKCQkJaWYgKGZpbGUuZXhpc3RzKCkpCgkJCQltb25pdG9yLndvcmtlZCgyMDApOwoJCQkJLy9maWxlLnNldENvbnRlbnRzKGluLCB0cnVlLCB0cnVlLCBQcm9ncmVzc1V0aWwuZ2V0U3ViTW9uaXRvckZvcihtb25pdG9yLCAyMDApKTsKCQkJZWxzZQoJCQkJZmlsZS5jcmVhdGUoaW4sIHRydWUsIFByb2dyZXNzVXRpbC5nZXRTdWJNb25pdG9yRm9yKG1vbml0b3IsIDIwMCkpOwoJCgkJCWlmIChtb25pdG9yLmlzQ2FuY2VsZWQoKSkKCQkJCXJldHVybjsKCQkJbW9uaXRvci5kb25lKCk7CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoIkNvdWxkIG5vdCBzYXZlIFRvbWNhdCB2NC4wIGNvbmZpZ3VyYXRpb24gdG8gIiArIGZvbGRlci50b1N0cmluZygpLCBlKTsKCQkJdGhyb3cgbmV3IENvcmVFeGNlcHRpb24obmV3IFN0YXR1cyhJU3RhdHVzLkVSUk9SLCBUb21jYXRQbHVnaW4uUExVR0lOX0lELCAwLCBUb21jYXRQbHVnaW4uZ2V0UmVzb3VyY2UoIiVlcnJvckNvdWxkTm90U2F2ZUNvbmZpZ3VyYXRpb24iLCBuZXcgU3RyaW5nW10ge2UuZ2V0TG9jYWxpemVkTWVzc2FnZSgpfSksIGUpKTsKCQl9Cgl9Cn0K