LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA1IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAqgKgogKiBDb250cmlidXRvcnM6CiAqICAgIElCTSBDb3Jwb3JhdGlvbiAtIEluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KcGFja2FnZSBvcmcuZWNsaXBzZS5qc3Quc2VydmVyLnRvbWNhdC5jb3JlLmludGVybmFsOwoKaW1wb3J0IGphdmEuaW8uRmlsZTsKaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOwppbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOwppbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKaW1wb3J0IGphdmEudXRpbC5MaXN0OwppbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7CgppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLio7CmltcG9ydCBvcmcuZWNsaXBzZS5kZWJ1Zy5jb3JlLio7CmltcG9ydCBvcmcuZWNsaXBzZS5kZWJ1Zy5jb3JlLm1vZGVsLklQcm9jZXNzOwppbXBvcnQgb3JnLmVjbGlwc2UuamR0LmxhdW5jaGluZy5JSmF2YUxhdW5jaENvbmZpZ3VyYXRpb25Db25zdGFudHM7CmltcG9ydCBvcmcuZWNsaXBzZS5qZHQubGF1bmNoaW5nLklSdW50aW1lQ2xhc3NwYXRoRW50cnk7CmltcG9ydCBvcmcuZWNsaXBzZS5qZHQubGF1bmNoaW5nLklWTUluc3RhbGw7CmltcG9ydCBvcmcuZWNsaXBzZS5qZHQubGF1bmNoaW5nLkphdmFSdW50aW1lOwppbXBvcnQgb3JnLmVjbGlwc2UuanN0LnNlcnZlci5jb3JlLklXZWJNb2R1bGU7CmltcG9ydCBvcmcuZWNsaXBzZS5vc2dpLnV0aWwuTkxTOwoKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS4qOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLmludGVybmFsLlNlcnZlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC4qOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLnV0aWwuU29ja2V0VXRpbDsKLyoqCiAqIEdlbmVyaWMgVG9tY2F0IHNlcnZlci4KICovCnB1YmxpYyBjbGFzcyBUb21jYXRTZXJ2ZXJCZWhhdmlvdXIgZXh0ZW5kcyBTZXJ2ZXJCZWhhdmlvdXJEZWxlZ2F0ZSBpbXBsZW1lbnRzIElUb21jYXRTZXJ2ZXJCZWhhdmlvdXIgewoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFJfU1RPUCA9ICJzdG9wLXNlcnZlciI7CgoJLy8gdGhlIHRocmVhZCB1c2VkIHRvIHBpbmcgdGhlIHNlcnZlciB0byBjaGVjayBmb3Igc3RhcnR1cAoJcHJvdGVjdGVkIHRyYW5zaWVudCBQaW5nVGhyZWFkIHBpbmcgPSBudWxsOwoJcHJvdGVjdGVkIHRyYW5zaWVudCBJUHJvY2VzcyBwcm9jZXNzOwoJcHJvdGVjdGVkIHRyYW5zaWVudCBJRGVidWdFdmVudFNldExpc3RlbmVyIHByb2Nlc3NMaXN0ZW5lcjsKCgkvKioKCSAqIFRvbWNhdFNlcnZlci4KCSAqLwoJcHVibGljIFRvbWNhdFNlcnZlckJlaGF2aW91cigpIHsKCQlzdXBlcigpOwoJfQoKCXB1YmxpYyB2b2lkIGluaXRpYWxpemUoSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB7CgkJLy8gZG8gbm90aGluZwoJfQoKCXB1YmxpYyBUb21jYXRSdW50aW1lIGdldFRvbWNhdFJ1bnRpbWUoKSB7CgkJaWYgKGdldFNlcnZlcigpLmdldFJ1bnRpbWUoKSA9PSBudWxsKQoJCQlyZXR1cm4gbnVsbDsKCQkKCQlyZXR1cm4gKFRvbWNhdFJ1bnRpbWUpIGdldFNlcnZlcigpLmdldFJ1bnRpbWUoKS5sb2FkQWRhcHRlcihUb21jYXRSdW50aW1lLmNsYXNzLCBudWxsKTsKCX0KCQoJcHVibGljIElUb21jYXRWZXJzaW9uSGFuZGxlciBnZXRUb21jYXRWZXJzaW9uSGFuZGxlcigpIHsKCQlpZiAoZ2V0U2VydmVyKCkuZ2V0UnVudGltZSgpID09IG51bGwgfHwgZ2V0VG9tY2F0UnVudGltZSgpID09IG51bGwpCgkJCXJldHVybiBudWxsOwoKCQlyZXR1cm4gZ2V0VG9tY2F0UnVudGltZSgpLmdldFZlcnNpb25IYW5kbGVyKCk7Cgl9CgkKCXB1YmxpYyBUb21jYXRDb25maWd1cmF0aW9uIGdldFRvbWNhdENvbmZpZ3VyYXRpb24oKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiB7CgkJcmV0dXJuIGdldFRvbWNhdFNlcnZlcigpLmdldFRvbWNhdENvbmZpZ3VyYXRpb24oKTsKCX0KCglwdWJsaWMgVG9tY2F0U2VydmVyIGdldFRvbWNhdFNlcnZlcigpIHsKCQlyZXR1cm4gKFRvbWNhdFNlcnZlcikgZ2V0U2VydmVyKCkuZ2V0QWRhcHRlcihUb21jYXRTZXJ2ZXIuY2xhc3MpOwoJfQoKCS8qKgoJICogUmV0dXJuIHRoZSBydW50aW1lIGNsYXNzIG5hbWUuCgkgKgoJICogQHJldHVybiB0aGUgY2xhc3MgbmFtZQoJICovCglwdWJsaWMgU3RyaW5nIGdldFJ1bnRpbWVDbGFzcygpIHsKCQlyZXR1cm4gZ2V0VG9tY2F0VmVyc2lvbkhhbmRsZXIoKS5nZXRSdW50aW1lQ2xhc3MoKTsKCX0KCQoJLyoqCgkgKiBSZXR1cm5zIHRoZSBydW50aW1lIGJhc2UgcGF0aCBmb3IgcmVsYXRpdmUgcGF0aHMgaW4gdGhlIHNlcnZlcgoJICogY29uZmlndXJhdGlvbi4KCSAqIAoJICogQHJldHVybiB0aGUgYmFzZSBwYXRoCgkgKi8KCXB1YmxpYyBJUGF0aCBnZXRSdW50aW1lQmFzZURpcmVjdG9yeSgpIHsKCQlyZXR1cm4gZ2V0VG9tY2F0VmVyc2lvbkhhbmRsZXIoKS5nZXRSdW50aW1lQmFzZURpcmVjdG9yeSh0aGlzKTsKCX0KCgkvKioKCSAqIFJldHVybiB0aGUgcHJvZ3JhbSdzIHJ1bnRpbWUgYXJndW1lbnRzIHRvIHN0YXJ0IG9yIHN0b3AuCgkgKgoJICogQHBhcmFtIHN0YXJ0aW5nIHRydWUgaWYgc3RhcnRpbmcKCSAqIEByZXR1cm4gYW4gYXJyYXkgb2YgcnVudGltZSBwcm9ncmFtIGFyZ3VtZW50cwoJICovCglwcm90ZWN0ZWQgU3RyaW5nW10gZ2V0UnVudGltZVByb2dyYW1Bcmd1bWVudHMoYm9vbGVhbiBzdGFydGluZykgewoJCUlQYXRoIGNvbmZpZ1BhdGggPSBudWxsOwoJCWlmIChnZXRUb21jYXRTZXJ2ZXIoKS5pc1Rlc3RFbnZpcm9ubWVudCgpKQoJCQljb25maWdQYXRoID0gZ2V0VGVtcERpcmVjdG9yeSgpOwoJCXJldHVybiBnZXRUb21jYXRWZXJzaW9uSGFuZGxlcigpLmdldFJ1bnRpbWVQcm9ncmFtQXJndW1lbnRzKGNvbmZpZ1BhdGgsIGdldFRvbWNhdFNlcnZlcigpLmlzRGVidWcoKSwgc3RhcnRpbmcpOwoJfQoKCS8qKgoJICogUmV0dXJuIHRoZSBydW50aW1lIChWTSkgYXJndW1lbnRzLgoJICoKCSAqIEByZXR1cm4gYW4gYXJyYXkgb2YgcnVudGltZSBhcmd1bWVudHMKCSAqLwoJcHJvdGVjdGVkIFN0cmluZ1tdIGdldFJ1bnRpbWVWTUFyZ3VtZW50cygpIHsKCQlJUGF0aCBpbnN0YWxsUGF0aCA9IGdldFNlcnZlcigpLmdldFJ1bnRpbWUoKS5nZXRMb2NhdGlvbigpOwoJCUlQYXRoIGNvbmZpZ1BhdGggPSBudWxsOwoJCWlmIChnZXRUb21jYXRTZXJ2ZXIoKS5pc1Rlc3RFbnZpcm9ubWVudCgpKQoJCQljb25maWdQYXRoID0gZ2V0VGVtcERpcmVjdG9yeSgpOwoJCWVsc2UKCQkJY29uZmlnUGF0aCA9IGluc3RhbGxQYXRoOwoJCXJldHVybiBnZXRUb21jYXRWZXJzaW9uSGFuZGxlcigpLmdldFJ1bnRpbWVWTUFyZ3VtZW50cyhpbnN0YWxsUGF0aCwgY29uZmlnUGF0aCwKCQkJCWdldFRvbWNhdFNlcnZlcigpLmlzVGVzdEVudmlyb25tZW50KCksIGdldFRvbWNhdFNlcnZlcigpLmlzU2VjdXJlKCkpOwoJfQoJCglwcm90ZWN0ZWQgc3RhdGljIFN0cmluZyByZW5kZXJDb21tYW5kTGluZShTdHJpbmdbXSBjb21tYW5kTGluZSwgU3RyaW5nIHNlcGFyYXRvcikgewoJCWlmIChjb21tYW5kTGluZSA9PSBudWxsIHx8IGNvbW1hbmRMaW5lLmxlbmd0aCA8IDEpCgkJCXJldHVybiAiIjsKCQlTdHJpbmdCdWZmZXIgYnVmPSBuZXcgU3RyaW5nQnVmZmVyKGNvbW1hbmRMaW5lWzBdKTsKCQlmb3IgKGludCBpID0gMTsgaSA8IGNvbW1hbmRMaW5lLmxlbmd0aDsgaSsrKSB7CgkJCWJ1Zi5hcHBlbmQoc2VwYXJhdG9yKTsKCQkJYnVmLmFwcGVuZChjb21tYW5kTGluZVtpXSk7CgkJfQkKCQlyZXR1cm4gYnVmLnRvU3RyaW5nKCk7Cgl9CgoJcHVibGljIHZvaWQgc2V0UHJvY2VzcyhmaW5hbCBJUHJvY2VzcyBuZXdQcm9jZXNzKSB7CgkJaWYgKHByb2Nlc3MgIT0gbnVsbCkKCQkJcmV0dXJuOwoKCQlwcm9jZXNzID0gbmV3UHJvY2VzczsKCQlpZiAocHJvY2Vzc0xpc3RlbmVyICE9IG51bGwpCgkJCURlYnVnUGx1Z2luLmdldERlZmF1bHQoKS5yZW1vdmVEZWJ1Z0V2ZW50TGlzdGVuZXIocHJvY2Vzc0xpc3RlbmVyKTsKCQlpZiAobmV3UHJvY2VzcyA9PSBudWxsKQoJCQlyZXR1cm47CgkJCgkJcHJvY2Vzc0xpc3RlbmVyID0gbmV3IElEZWJ1Z0V2ZW50U2V0TGlzdGVuZXIoKSB7CgkJCXB1YmxpYyB2b2lkIGhhbmRsZURlYnVnRXZlbnRzKERlYnVnRXZlbnRbXSBldmVudHMpIHsKCQkJCWlmIChldmVudHMgIT0gbnVsbCkgewoJCQkJCWludCBzaXplID0gZXZlbnRzLmxlbmd0aDsKCQkJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJCQlpZiAocHJvY2VzcyAhPSBudWxsICYmIHByb2Nlc3MuZXF1YWxzKGV2ZW50c1tpXS5nZXRTb3VyY2UoKSkgJiYgZXZlbnRzW2ldLmdldEtpbmQoKSA9PSBEZWJ1Z0V2ZW50LlRFUk1JTkFURSkgewoJCQkJCQkJRGVidWdQbHVnaW4uZ2V0RGVmYXVsdCgpLnJlbW92ZURlYnVnRXZlbnRMaXN0ZW5lcih0aGlzKTsKCQkJCQkJCXN0b3BJbXBsKCk7CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCX0KCQl9OwoJCURlYnVnUGx1Z2luLmdldERlZmF1bHQoKS5hZGREZWJ1Z0V2ZW50TGlzdGVuZXIocHJvY2Vzc0xpc3RlbmVyKTsKCX0KCQoJcHJvdGVjdGVkIHZvaWQgc2V0U2VydmVyU3RhcnRlZCgpIHsKCQlzZXRTZXJ2ZXJTdGF0ZShJU2VydmVyLlNUQVRFX1NUQVJURUQpOwoJfQoKCXByb3RlY3RlZCB2b2lkIHN0b3BJbXBsKCkgewoJCWlmIChwaW5nICE9IG51bGwpIHsKCQkJcGluZy5zdG9wKCk7CgkJCXBpbmcgPSBudWxsOwoJCX0KCQlpZiAocHJvY2VzcyAhPSBudWxsKSB7CgkJCXByb2Nlc3MgPSBudWxsOwoJCQlEZWJ1Z1BsdWdpbi5nZXREZWZhdWx0KCkucmVtb3ZlRGVidWdFdmVudExpc3RlbmVyKHByb2Nlc3NMaXN0ZW5lcik7CgkJCXByb2Nlc3NMaXN0ZW5lciA9IG51bGw7CgkJfQoJCXNldFNlcnZlclN0YXRlKElTZXJ2ZXIuU1RBVEVfU1RPUFBFRCk7Cgl9CgoJcHJvdGVjdGVkIHZvaWQgcHVibGlzaFNlcnZlcihpbnQga2luZCwgSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiB7CgkJSVBhdGggaW5zdGFsbERpciA9IGdldFNlcnZlcigpLmdldFJ1bnRpbWUoKS5nZXRMb2NhdGlvbigpOwoJCUlQYXRoIGNvbmZEaXIgPSBudWxsOwoJCWlmIChnZXRUb21jYXRTZXJ2ZXIoKS5pc1Rlc3RFbnZpcm9ubWVudCgpKSB7CgkJCWNvbmZEaXIgPSBnZXRUZW1wRGlyZWN0b3J5KCk7CgkJCUlTdGF0dXMgc3RhdHVzID0gZ2V0VG9tY2F0Q29uZmlndXJhdGlvbigpLnByZXBhcmVSdW50aW1lRGlyZWN0b3J5KGNvbmZEaXIpOwoJCQlpZiAoc3RhdHVzICE9IG51bGwgJiYgIXN0YXR1cy5pc09LKCkpCgkJCQl0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbihzdGF0dXMpOwovKgkJCUZpbGUgdGVtcCA9IGNvbmZEaXIuYXBwZW5kKCJjb25mIikudG9GaWxlKCk7CgkJCWlmICghdGVtcC5leGlzdHMoKSkKCQkJCXRlbXAubWtkaXJzKCk7Ki8KCQl9IGVsc2UKCQkJY29uZkRpciA9IGluc3RhbGxEaXI7CgoJCW1vbml0b3IgPSBQcm9ncmVzc1V0aWwuZ2V0TW9uaXRvckZvcihtb25pdG9yKTsKCQltb25pdG9yLmJlZ2luVGFzayhNZXNzYWdlcy5wdWJsaXNoU2VydmVyVGFzaywgNTAwKTsKCQkKCQlJU3RhdHVzIHN0YXR1cyA9IGdldFRvbWNhdENvbmZpZ3VyYXRpb24oKS5jbGVhbnVwU2VydmVyKGNvbmZEaXIsIGluc3RhbGxEaXIsIFByb2dyZXNzVXRpbC5nZXRTdWJNb25pdG9yRm9yKG1vbml0b3IsIDEwMCkpOwoJCWlmIChzdGF0dXMgIT0gbnVsbCAmJiAhc3RhdHVzLmlzT0soKSkKCQkJdGhyb3cgbmV3IENvcmVFeGNlcHRpb24oc3RhdHVzKTsKCQkKCQlzdGF0dXMgPSBnZXRUb21jYXRDb25maWd1cmF0aW9uKCkuYmFja3VwQW5kUHVibGlzaChjb25mRGlyLCAhZ2V0VG9tY2F0U2VydmVyKCkuaXNUZXN0RW52aXJvbm1lbnQoKSwgUHJvZ3Jlc3NVdGlsLmdldFN1Yk1vbml0b3JGb3IobW9uaXRvciwgNDAwKSk7CgkJaWYgKHN0YXR1cyAhPSBudWxsICYmICFzdGF0dXMuaXNPSygpKQoJCQl0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbihzdGF0dXMpOwoJCQoJCW1vbml0b3IuZG9uZSgpOwoJCQoJCXNldFNlcnZlclB1Ymxpc2hTdGF0ZShJU2VydmVyLlBVQkxJU0hfU1RBVEVfTk9ORSk7Cgl9CgoJLyoKCSAqIFB1Ymxpc2hlcyB0aGUgZ2l2ZW4gbW9kdWxlIHRvIHRoZSBzZXJ2ZXIuCgkgKi8KCXByb3RlY3RlZCB2b2lkIHB1Ymxpc2hNb2R1bGUoaW50IGtpbmQsIGludCBkZWx0YUtpbmQsIElNb2R1bGVbXSBtb2R1bGVUcmVlLCBJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHRocm93cyBDb3JlRXhjZXB0aW9uIHsKCQlpZiAoZ2V0U2VydmVyKCkuZ2V0U2VydmVyU3RhdGUoKSAhPSBJU2VydmVyLlNUQVRFX1NUT1BQRUQpIHsKCQkJaWYgKGRlbHRhS2luZCA9PSBTZXJ2ZXJCZWhhdmlvdXJEZWxlZ2F0ZS5BRERFRCB8fCBkZWx0YUtpbmQgPT0gU2VydmVyQmVoYXZpb3VyRGVsZWdhdGUuUkVNT1ZFRCkKCQkJCXNldFNlcnZlclJlc3RhcnRTdGF0ZSh0cnVlKTsKCQl9CgkJaWYgKGdldFRvbWNhdFNlcnZlcigpLmlzVGVzdEVudmlyb25tZW50KCkpCgkJCXJldHVybjsKCgkJSVBhdGggcGF0aCA9IGdldFRlbXBEaXJlY3RvcnkoKS5hcHBlbmQoInB1Ymxpc2gudHh0Iik7CgkJUHJvcGVydGllcyBwID0gbmV3IFByb3BlcnRpZXMoKTsKCQl0cnkgewoJCQlwLmxvYWQobmV3IEZpbGVJbnB1dFN0cmVhbShwYXRoLnRvRmlsZSgpKSk7CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJLy8gaWdub3JlCgkJfQoJCQoJCUlNb2R1bGUgbW9kdWxlID0gbW9kdWxlVHJlZVswXTsKCQkKCQlpZiAoZGVsdGFLaW5kID09IFJFTU9WRUQpIHsKCQkJdHJ5IHsKCQkJCVN0cmluZyBwdWJsaXNoUGF0aCA9IChTdHJpbmcpIHAuZ2V0KG1vZHVsZS5nZXRJZCgpKTsKCQkJCUZpbGVVdGlsLmRlbGV0ZURpcmVjdG9yeShuZXcgRmlsZShwdWJsaXNoUGF0aCksIG1vbml0b3IpOwoJCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQkJdGhyb3cgbmV3IENvcmVFeGNlcHRpb24obmV3IFN0YXR1cyhJU3RhdHVzLldBUk5JTkcsIFRvbWNhdFBsdWdpbi5QTFVHSU5fSUQsIDAsICJDb3VsZCBub3QgcmVtb3ZlIG1vZHVsZSIsIGUpKTsKCQkJfQoJCX0gZWxzZSB7CgkJCUlXZWJNb2R1bGUgd2ViTW9kdWxlID0gKElXZWJNb2R1bGUpIG1vZHVsZS5sb2FkQWRhcHRlcihJV2ViTW9kdWxlLmNsYXNzLCBudWxsKTsKCQkJSVBhdGggZnJvbSA9IHdlYk1vZHVsZS5nZXRMb2NhdGlvbigpOwoJCQlJUGF0aCB0byA9IGdldFNlcnZlcigpLmdldFJ1bnRpbWUoKS5nZXRMb2NhdGlvbigpLmFwcGVuZCgid2ViYXBwcyIpLmFwcGVuZCh3ZWJNb2R1bGUuZ2V0Q29udGV4dFJvb3QoKSk7CgkJCUZpbGVVdGlsLnNtYXJ0Q29weURpcmVjdG9yeShmcm9tLnRvT1NTdHJpbmcoKSwgdG8udG9PU1N0cmluZygpLCBtb25pdG9yKTsKCQkJcC5wdXQobW9kdWxlLmdldElkKCksIHRvLnRvT1NTdHJpbmcoKSk7CgkJCXNldE1vZHVsZVB1Ymxpc2hTdGF0ZShtb2R1bGVUcmVlLCBJU2VydmVyLlBVQkxJU0hfU1RBVEVfTk9ORSk7CgkJfQoJCQoJCXRyeSB7CgkJCXAuc3RvcmUobmV3IEZpbGVPdXRwdXRTdHJlYW0ocGF0aC50b0ZpbGUoKSksICJUb21jYXQgcHVibGlzaCBkYXRhIik7CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJLy8gaWdub3JlCgkJfQoJfQoKCS8qKgoJICogU2V0dXAgZm9yIHN0YXJ0aW5nIHRoZSBzZXJ2ZXIuCgkgKiAKCSAqIEBwYXJhbSBsYXVuY2ggSUxhdW5jaAoJICogQHBhcmFtIGxhdW5jaE1vZGUgU3RyaW5nCgkgKiBAcGFyYW0gbW9uaXRvciBJUHJvZ3Jlc3NNb25pdG9yCgkgKiBAdGhyb3dzIENvcmVFeGNlcHRpb24gaWYgYW55dGhpbmcgZ29lcyB3cm9uZwoJICovCglwdWJsaWMgdm9pZCBzZXR1cExhdW5jaChJTGF1bmNoIGxhdW5jaCwgU3RyaW5nIGxhdW5jaE1vZGUsIElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgdGhyb3dzIENvcmVFeGNlcHRpb24gewoJCWlmICgidHJ1ZSIuZXF1YWxzKGxhdW5jaC5nZXRMYXVuY2hDb25maWd1cmF0aW9uKCkuZ2V0QXR0cmlidXRlKEFUVFJfU1RPUCwgImZhbHNlIikpKQoJCQlyZXR1cm47CgkJLy9pZiAoZ2V0VG9tY2F0UnVudGltZSgpID09IG51bGwpCgkJLy8JdGhyb3cgbmV3IENvcmVFeGNlcHRpb24oKTsKCQkKCQlJU3RhdHVzIHN0YXR1cyA9IGdldFRvbWNhdFJ1bnRpbWUoKS52YWxpZGF0ZSgpOwoJCWlmIChzdGF0dXMgIT0gbnVsbCAmJiBzdGF0dXMuZ2V0U2V2ZXJpdHkoKSA9PSBJU3RhdHVzLkVSUk9SKQoJCQl0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbihzdGF0dXMpOwoKCQkvL3NldFJlc3RhcnROZWVkZWQoZmFsc2UpOwoJCVRvbWNhdENvbmZpZ3VyYXRpb24gY29uZmlndXJhdGlvbiA9IGdldFRvbWNhdENvbmZpZ3VyYXRpb24oKTsKCQoJCS8vIGNoZWNrIHRoYXQgcG9ydHMgYXJlIGZyZWUKCQlJdGVyYXRvciBpdGVyYXRvciA9IGNvbmZpZ3VyYXRpb24uZ2V0U2VydmVyUG9ydHMoKS5pdGVyYXRvcigpOwoJCUxpc3QgdXNlZFBvcnRzID0gbmV3IEFycmF5TGlzdCgpOwoJCXdoaWxlIChpdGVyYXRvci5oYXNOZXh0KCkpIHsKCQkJU2VydmVyUG9ydCBzcCA9IChTZXJ2ZXJQb3J0KSBpdGVyYXRvci5uZXh0KCk7CgkJCWlmIChzcC5nZXRQb3J0KCkgPCAwKQoJCQkJdGhyb3cgbmV3IENvcmVFeGNlcHRpb24obmV3IFN0YXR1cyhJU3RhdHVzLkVSUk9SLCBUb21jYXRQbHVnaW4uUExVR0lOX0lELCAwLCBNZXNzYWdlcy5lcnJvclBvcnRJbnZhbGlkLCBudWxsKSk7CgkJCWlmIChTb2NrZXRVdGlsLmlzUG9ydEluVXNlKHNwLmdldFBvcnQoKSwgNSkpIHsKCQkJCXVzZWRQb3J0cy5hZGQoc3ApOwoJCQl9CgkJfQoJCWlmICh1c2VkUG9ydHMuc2l6ZSgpID09IDEpIHsKCQkJU2VydmVyUG9ydCBwb3J0ID0gKFNlcnZlclBvcnQpIHVzZWRQb3J0cy5nZXQoMCk7CgkJCXRocm93IG5ldyBDb3JlRXhjZXB0aW9uKG5ldyBTdGF0dXMoSVN0YXR1cy5FUlJPUiwgVG9tY2F0UGx1Z2luLlBMVUdJTl9JRCwgMCwgTkxTLmJpbmQoTWVzc2FnZXMuZXJyb3JQb3J0SW5Vc2UsIG5ldyBTdHJpbmdbXSB7cG9ydC5nZXRQb3J0KCkgKyAiIiwgZ2V0U2VydmVyKCkuZ2V0TmFtZSgpfSksIG51bGwpKTsKCQl9IGVsc2UgaWYgKHVzZWRQb3J0cy5zaXplKCkgPiAxKSB7CgkJCVN0cmluZyBwb3J0U3RyID0gIiI7CgkJCWl0ZXJhdG9yID0gdXNlZFBvcnRzLml0ZXJhdG9yKCk7CgkJCWJvb2xlYW4gZmlyc3QgPSB0cnVlOwoJCQl3aGlsZSAoaXRlcmF0b3IuaGFzTmV4dCgpKSB7CgkJCQlpZiAoIWZpcnN0KQoJCQkJCXBvcnRTdHIgKz0gIiwgIjsKCQkJCWZpcnN0ID0gZmFsc2U7CgkJCQlTZXJ2ZXJQb3J0IHNwID0gKFNlcnZlclBvcnQpIGl0ZXJhdG9yLm5leHQoKTsKCQkJCXBvcnRTdHIgKz0gIiIgKyBzcC5nZXRQb3J0KCk7CgkJCX0KCQkJdGhyb3cgbmV3IENvcmVFeGNlcHRpb24obmV3IFN0YXR1cyhJU3RhdHVzLkVSUk9SLCBUb21jYXRQbHVnaW4uUExVR0lOX0lELCAwLCBOTFMuYmluZChNZXNzYWdlcy5lcnJvclBvcnRzSW5Vc2UsIG5ldyBTdHJpbmdbXSB7cG9ydFN0ciwgZ2V0U2VydmVyKCkuZ2V0TmFtZSgpfSksIG51bGwpKTsKCQl9CgkJCgkJLy8gY2hlY2sgdGhhdCB0aGVyZSBpcyBvbmx5IG9uZSBhcHAgZm9yIGVhY2ggY29udGV4dCByb290CgkJaXRlcmF0b3IgPSBjb25maWd1cmF0aW9uLmdldFdlYk1vZHVsZXMoKS5pdGVyYXRvcigpOwoJCUxpc3QgY29udGV4dFJvb3RzID0gbmV3IEFycmF5TGlzdCgpOwoJCXdoaWxlIChpdGVyYXRvci5oYXNOZXh0KCkpIHsKCQkJV2ViTW9kdWxlIG1vZHVsZSA9IChXZWJNb2R1bGUpIGl0ZXJhdG9yLm5leHQoKTsKCQkJU3RyaW5nIGNvbnRleHRSb290ID0gbW9kdWxlLmdldFBhdGgoKTsKCQkJaWYgKGNvbnRleHRSb290cy5jb250YWlucyhjb250ZXh0Um9vdCkpCgkJCQl0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbihuZXcgU3RhdHVzKElTdGF0dXMuRVJST1IsIFRvbWNhdFBsdWdpbi5QTFVHSU5fSUQsIDAsIE5MUy5iaW5kKE1lc3NhZ2VzLmVycm9yRHVwbGljYXRlQ29udGV4dFJvb3QsIG5ldyBTdHJpbmdbXSB7IGNvbnRleHRSb290IH0pLCBudWxsKSk7CgkJCQoJCQljb250ZXh0Um9vdHMuYWRkKGNvbnRleHRSb290KTsKCQl9CgkJCgkJc2V0U2VydmVyUmVzdGFydFN0YXRlKGZhbHNlKTsKCQlzZXRTZXJ2ZXJTdGF0ZShJU2VydmVyLlNUQVRFX1NUQVJUSU5HKTsKCQlzZXRNb2RlKGxhdW5jaE1vZGUpOwoJCgkJLy8gcGluZyBzZXJ2ZXIgdG8gY2hlY2sgZm9yIHN0YXJ0dXAKCQl0cnkgewoJCQlTdHJpbmcgdXJsID0gImh0dHA6Ly9sb2NhbGhvc3QiOwoJCQlpbnQgcG9ydCA9IGNvbmZpZ3VyYXRpb24uZ2V0TWFpblBvcnQoKS5nZXRQb3J0KCk7CgkJCWlmIChwb3J0ICE9IDgwKQoJCQkJdXJsICs9ICI6IiArIHBvcnQ7CgkJCXBpbmcgPSBuZXcgUGluZ1RocmVhZChnZXRTZXJ2ZXIoKSwgdXJsLCA1MCwgdGhpcyk7CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiQ2FuJ3QgcGluZyBmb3IgVG9tY2F0IHN0YXJ0dXAuIik7CgkJfQoJfQoKCS8qKgoJICogQ2xlYW5seSBzaHV0cyBkb3duIGFuZCB0ZXJtaW5hdGVzIHRoZSBzZXJ2ZXIuCgkgKiAKCSAqIEBwYXJhbSBmb3JjZSA8Y29kZT50cnVlPC9jb2RlPiB0byBraWxsIHRoZSBzZXJ2ZXIKCSAqLwoJcHVibGljIHZvaWQgc3RvcChib29sZWFuIGZvcmNlKSB7CgkJaWYgKGZvcmNlKSB7CgkJCXRlcm1pbmF0ZSgpOwoJCQlyZXR1cm47CgkJfQoJCWludCBzdGF0ZSA9IGdldFNlcnZlcigpLmdldFNlcnZlclN0YXRlKCk7CgkJaWYgKHN0YXRlID09IElTZXJ2ZXIuU1RBVEVfU1RPUFBFRCkKCQkJcmV0dXJuOwoJCWVsc2UgaWYgKHN0YXRlID09IElTZXJ2ZXIuU1RBVEVfU1RBUlRJTkcgfHwgc3RhdGUgPT0gSVNlcnZlci5TVEFURV9TVE9QUElORykgewoJCQl0ZXJtaW5hdGUoKTsKCQkJcmV0dXJuOwoJCX0KCgkJdHJ5IHsKCQkJVHJhY2UudHJhY2UoVHJhY2UuRklORVIsICJTdG9wcGluZyBUb21jYXQiKTsKCQkJaWYgKHN0YXRlICE9IElTZXJ2ZXIuU1RBVEVfU1RPUFBFRCkKCQkJCXNldFNlcnZlclN0YXRlKElTZXJ2ZXIuU1RBVEVfU1RPUFBJTkcpOwoJCgkJCUlMYXVuY2hDb25maWd1cmF0aW9uIGxhdW5jaENvbmZpZyA9ICgoU2VydmVyKWdldFNlcnZlcigpKS5nZXRMYXVuY2hDb25maWd1cmF0aW9uKHRydWUsIG51bGwpOwoJCQlJTGF1bmNoQ29uZmlndXJhdGlvbldvcmtpbmdDb3B5IHdjID0gbGF1bmNoQ29uZmlnLmdldFdvcmtpbmdDb3B5KCk7CgkJCQoJCQlTdHJpbmcgYXJncyA9IHJlbmRlckNvbW1hbmRMaW5lKGdldFJ1bnRpbWVQcm9ncmFtQXJndW1lbnRzKGZhbHNlKSwgIiAiKTsKCQkJd2Muc2V0QXR0cmlidXRlKElKYXZhTGF1bmNoQ29uZmlndXJhdGlvbkNvbnN0YW50cy5BVFRSX1BST0dSQU1fQVJHVU1FTlRTLCBhcmdzKTsKCQkJd2Muc2V0QXR0cmlidXRlKEFUVFJfU1RPUCwgInRydWUiKTsKCQkJd2MubGF1bmNoKElMYXVuY2hNYW5hZ2VyLlJVTl9NT0RFLCBuZXcgTnVsbFByb2dyZXNzTW9uaXRvcigpKTsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJFcnJvciBzdG9wcGluZyBUb21jYXQiLCBlKTsKCQl9Cgl9CgoJLyoqCgkgKiBUZXJtaW5hdGVzIHRoZSBzZXJ2ZXIuCgkgKi8KCXByb3RlY3RlZCB2b2lkIHRlcm1pbmF0ZSgpIHsKCQlpZiAoZ2V0U2VydmVyKCkuZ2V0U2VydmVyU3RhdGUoKSA9PSBJU2VydmVyLlNUQVRFX1NUT1BQRUQpCgkJCXJldHVybjsKCgkJdHJ5IHsKCQkJc2V0U2VydmVyU3RhdGUoSVNlcnZlci5TVEFURV9TVE9QUElORyk7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVSLCAiS2lsbGluZyB0aGUgVG9tY2F0IHByb2Nlc3MiKTsKCQkJaWYgKHByb2Nlc3MgIT0gbnVsbCAmJiAhcHJvY2Vzcy5pc1Rlcm1pbmF0ZWQoKSkgewoJCQkJcHJvY2Vzcy50ZXJtaW5hdGUoKTsKCQkJCXN0b3BJbXBsKCk7CgkJCX0KCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJFcnJvciBraWxsaW5nIHRoZSBwcm9jZXNzIiwgZSk7CgkJfQoJfQoKCXB1YmxpYyBJUGF0aCBnZXRUZW1wRGlyZWN0b3J5KCkgewoJCXJldHVybiBzdXBlci5nZXRUZW1wRGlyZWN0b3J5KCk7Cgl9CgoJLyoqCgkgKiBSZXR1cm4gYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBvYmplY3QuCgkgKiBAcmV0dXJuIGphdmEubGFuZy5TdHJpbmcKCSAqLwoJcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKCQlyZXR1cm4gIlRvbWNhdFNlcnZlciI7Cgl9CgkKCXByb3RlY3RlZCBzdGF0aWMgaW50IGdldE5leHRUb2tlbihTdHJpbmcgcywgaW50IHN0YXJ0KSB7CgkJaW50IGkgPSBzdGFydDsKCQlpbnQgbGVuZ3RoID0gcy5sZW5ndGgoKTsKCQljaGFyIGxvb2tGb3IgPSAnICc7CgkJCgkJd2hpbGUgKGkgPCBsZW5ndGgpIHsKCQkJY2hhciBjID0gcy5jaGFyQXQoaSk7CgkJCWlmIChsb29rRm9yID09IGMpIHsKCQkJCWlmIChsb29rRm9yID09ICciJykKCQkJCQlyZXR1cm4gaSsxOwoJCQkJcmV0dXJuIGk7CgkJCX0KCQkJaWYgKGMgPT0gJyInKQoJCQkJbG9va0ZvciA9ICciJzsKCQkJaSsrOwoJCX0KCQlyZXR1cm4gLTE7Cgl9CgkKCS8qKgoJICogTWVyZ2UgdGhlIGdpdmVuIGFyZ3VtZW50cyBpbnRvIHRoZSBvcmlnaW5hbCBhcmd1bWVudCBzdHJpbmcsIHJlcGxhY2luZwoJICogaW52YWxpZCB2YWx1ZXMgaWYgdGhleSBoYXZlIGJlZW4gY2hhbmdlZC4KCSAqIAoJICogQHBhcmFtIG9yaWdpbmFsQXJnCgkgKiBAcGFyYW0gdm1BcmdzCgkgKiBAcmV0dXJuIG1lcmdlZCBhcmd1bWVudCBzdHJpbmcKCSAqLwoJcHVibGljIHN0YXRpYyBTdHJpbmcgbWVyZ2VBcmd1bWVudHMoU3RyaW5nIG9yaWdpbmFsQXJnLCBTdHJpbmdbXSB2bUFyZ3MpIHsKCQlpZiAodm1BcmdzID09IG51bGwpCgkJCXJldHVybiBvcmlnaW5hbEFyZzsKCQkKCQlpZiAob3JpZ2luYWxBcmcgPT0gbnVsbCkKCQkJb3JpZ2luYWxBcmcgPSAiIjsKCQkKCQkvLyByZXBsYWNlIGFuZCBudWxsIG91dCBhbGwgdm1hcmdzIHRoYXQgYWxyZWFkeSBleGlzdAoJCWludCBzaXplID0gdm1BcmdzLmxlbmd0aDsKCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQlpbnQgaW5kID0gdm1BcmdzW2ldLmluZGV4T2YoIiAiKTsKCQkJaW50IGluZDIgPSB2bUFyZ3NbaV0uaW5kZXhPZigiPSIpOwoJCQlpZiAoaW5kID49IDAgJiYgKGluZDIgPT0gLTEgfHwgaW5kIDwgaW5kMikpIHsgLy8gLWEgYmMgc3R5bGUKCQkJCWludCBpbmRleCA9IG9yaWdpbmFsQXJnLmluZGV4T2Yodm1BcmdzW2ldLnN1YnN0cmluZygwLCBpbmQgKyAxKSk7CgkJCQlpZiAoaW5kZXggPT0gMCB8fCAoaW5kZXggPiAwICYmIG9yaWdpbmFsQXJnLmNoYXJBdChpbmRleCAtIDEpID09ICcgJykpIHsKCQkJCQkvLyByZXBsYWNlCgkJCQkJU3RyaW5nIHMgPSBvcmlnaW5hbEFyZy5zdWJzdHJpbmcoMCwgaW5kZXgpOwoJCQkJCWludCBpbmRleDIgPSBnZXROZXh0VG9rZW4ob3JpZ2luYWxBcmcsIGluZGV4ICsgaW5kICsgMSk7CgkJCQkJaWYgKGluZGV4MiA+PSAwKQoJCQkJCQlvcmlnaW5hbEFyZyA9IHMgKyB2bUFyZ3NbaV0gKyBvcmlnaW5hbEFyZy5zdWJzdHJpbmcoaW5kZXgyKTsKCQkJCQllbHNlCgkJCQkJCW9yaWdpbmFsQXJnID0gcyArIHZtQXJnc1tpXTsKCQkJCQl2bUFyZ3NbaV0gPSBudWxsOwoJCQkJfQoJCQl9IGVsc2UgaWYgKGluZDIgPj0gMCkgeyAvLyBhPWIgc3R5bGUKCQkJCWludCBpbmRleCA9IG9yaWdpbmFsQXJnLmluZGV4T2Yodm1BcmdzW2ldLnN1YnN0cmluZygwLCBpbmQyICsgMSkpOwoJCQkJaWYgKGluZGV4ID09IDAgfHwgKGluZGV4ID4gMCAmJiBvcmlnaW5hbEFyZy5jaGFyQXQoaW5kZXggLSAxKSA9PSAnICcpKSB7CgkJCQkJLy8gcmVwbGFjZQoJCQkJCVN0cmluZyBzID0gb3JpZ2luYWxBcmcuc3Vic3RyaW5nKDAsIGluZGV4KTsKCQkJCQlpbnQgaW5kZXgyID0gZ2V0TmV4dFRva2VuKG9yaWdpbmFsQXJnLCBpbmRleCk7CgkJCQkJaWYgKGluZGV4MiA+PSAwKQoJCQkJCQlvcmlnaW5hbEFyZyA9IHMgKyB2bUFyZ3NbaV0gKyBvcmlnaW5hbEFyZy5zdWJzdHJpbmcoaW5kZXgyKTsKCQkJCQllbHNlCgkJCQkJCW9yaWdpbmFsQXJnID0gcyArIHZtQXJnc1tpXTsKCQkJCQl2bUFyZ3NbaV0gPSBudWxsOwoJCQkJfQoJCQl9IGVsc2UgeyAvLyBhYmMgc3R5bGUKCQkJCWludCBpbmRleCA9IG9yaWdpbmFsQXJnLmluZGV4T2Yodm1BcmdzW2ldKTsKCQkJCWlmIChpbmRleCA9PSAwIHx8IChpbmRleCA+IDAgJiYgb3JpZ2luYWxBcmcuY2hhckF0KGluZGV4LTEpID09ICcgJykpIHsKCQkJCQkvLyByZXBsYWNlCgkJCQkJU3RyaW5nIHMgPSBvcmlnaW5hbEFyZy5zdWJzdHJpbmcoMCwgaW5kZXgpOwoJCQkJCWludCBpbmRleDIgPSBnZXROZXh0VG9rZW4ob3JpZ2luYWxBcmcsIGluZGV4KTsKCQkJCQlpZiAoaW5kZXgyID49IDApCgkJCQkJCW9yaWdpbmFsQXJnID0gcyArIHZtQXJnc1tpXSArIG9yaWdpbmFsQXJnLnN1YnN0cmluZyhpbmRleDIpOwoJCQkJCWVsc2UKCQkJCQkJb3JpZ2luYWxBcmcgPSBzICsgdm1BcmdzW2ldOwoJCQkJCXZtQXJnc1tpXSA9IG51bGw7CgkJCQl9CgkJCX0KCQl9CgkJCgkJLy8gYWRkIHJlbWFpbmluZyB2bWFyZ3MgdG8gdGhlIGVuZAoJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCWlmICh2bUFyZ3NbaV0gIT0gbnVsbCkgewoJCQkJaWYgKG9yaWdpbmFsQXJnLmxlbmd0aCgpID4gMCAmJiAhb3JpZ2luYWxBcmcuZW5kc1dpdGgoIiAiKSkKCQkJCQlvcmlnaW5hbEFyZyArPSAiICI7CgkJCQlvcmlnaW5hbEFyZyArPSB2bUFyZ3NbaV07CgkJCX0KCQl9CgkJCgkJcmV0dXJuIG9yaWdpbmFsQXJnOwoJfQoKCS8qKgoJICogUmVwbGFjZSB0aGUgY3VycmVudCBKUkUgY29udGFpbmVyIGNsYXNzcGF0aCB3aXRoIHRoZSBnaXZlbiBlbnRyeS4KCSAqIAoJICogQHBhcmFtIGNwCgkgKiBAcGFyYW0gZW50cnkKCSAqLwoJcHVibGljIHN0YXRpYyB2b2lkIHJlcGxhY2VKUkVDb250YWluZXIoTGlzdCBjcCwgSVJ1bnRpbWVDbGFzc3BhdGhFbnRyeSBlbnRyeSkgewoJCWludCBzaXplID0gY3Auc2l6ZSgpOwoJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCUlSdW50aW1lQ2xhc3NwYXRoRW50cnkgZW50cnkyID0gKElSdW50aW1lQ2xhc3NwYXRoRW50cnkpIGNwLmdldChpKTsKCQkJaWYgKGVudHJ5Mi5nZXRQYXRoKCkudXB0b1NlZ21lbnQoMikuaXNQcmVmaXhPZihlbnRyeS5nZXRQYXRoKCkpKSB7CgkJCQljcC5zZXQoaSwgZW50cnkpOwoJCQkJcmV0dXJuOwoJCQl9CgkJfQoJCQoJCWNwLmFkZCgwLCBlbnRyeSk7Cgl9CgoJLyoqCgkgKiBNZXJnZSBhIHNpbmdsZSBjbGFzc3BhdGggZW50cnkgaW50byB0aGUgY2xhc3NwYXRoIGxpc3QuCgkgKiAKCSAqIEBwYXJhbSBjcAoJICogQHBhcmFtIGVudHJ5CgkgKi8KCXB1YmxpYyBzdGF0aWMgdm9pZCBtZXJnZUNsYXNzcGF0aChMaXN0IGNwLCBJUnVudGltZUNsYXNzcGF0aEVudHJ5IGVudHJ5KSB7CgkJSXRlcmF0b3IgaXRlcmF0b3IgPSBjcC5pdGVyYXRvcigpOwoJCXdoaWxlIChpdGVyYXRvci5oYXNOZXh0KCkpIHsKCQkJSVJ1bnRpbWVDbGFzc3BhdGhFbnRyeSBlbnRyeTIgPSAoSVJ1bnRpbWVDbGFzc3BhdGhFbnRyeSkgaXRlcmF0b3IubmV4dCgpOwoJCQkKCQkJaWYgKGVudHJ5Mi5nZXRQYXRoKCkuZXF1YWxzKGVudHJ5LmdldFBhdGgoKSkpCgkJCQlyZXR1cm47CgkJfQoJCQoJCWNwLmFkZChlbnRyeSk7Cgl9CgoJcHVibGljIHZvaWQgc2V0dXBMYXVuY2hDb25maWd1cmF0aW9uKElMYXVuY2hDb25maWd1cmF0aW9uV29ya2luZ0NvcHkgd29ya2luZ0NvcHksIElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgdGhyb3dzIENvcmVFeGNlcHRpb24gewoJCVN0cmluZyBleGlzdGluZ1Byb2dBcmdzID0gd29ya2luZ0NvcHkuZ2V0QXR0cmlidXRlKElKYXZhTGF1bmNoQ29uZmlndXJhdGlvbkNvbnN0YW50cy5BVFRSX1BST0dSQU1fQVJHVU1FTlRTLCAoU3RyaW5nKW51bGwpOwoJCXdvcmtpbmdDb3B5LnNldEF0dHJpYnV0ZShJSmF2YUxhdW5jaENvbmZpZ3VyYXRpb25Db25zdGFudHMuQVRUUl9QUk9HUkFNX0FSR1VNRU5UUywgbWVyZ2VBcmd1bWVudHMoZXhpc3RpbmdQcm9nQXJncywgZ2V0UnVudGltZVByb2dyYW1Bcmd1bWVudHModHJ1ZSkpKTsKCgkJU3RyaW5nIGV4aXN0aW5nVk1BcmdzID0gd29ya2luZ0NvcHkuZ2V0QXR0cmlidXRlKElKYXZhTGF1bmNoQ29uZmlndXJhdGlvbkNvbnN0YW50cy5BVFRSX1ZNX0FSR1VNRU5UUywgKFN0cmluZyludWxsKTsKCQlpZiAoZXhpc3RpbmdWTUFyZ3MgIT0gbnVsbCAmJiAhZ2V0VG9tY2F0U2VydmVyKCkuaXNTZWN1cmUoKSkgewoJCQkvLyByZW1vdmUgLURqYXZhLnNlY3VyaXR5Lm1hbmFnZXIgYW5kIC1EamF2YS5zZWN1cml0eS5wb2xpY3k9InggeCIKCQkJaW50IGluZGV4ID0gZXhpc3RpbmdWTUFyZ3MuaW5kZXhPZigiLURqYXZhLnNlY3VyaXR5Lm1hbmFnZXIiKTsKCQkJaWYgKGluZGV4ID49IDApIHsKCQkJCWlmIChpbmRleCA+IDAgJiYgZXhpc3RpbmdWTUFyZ3MuY2hhckF0KGluZGV4IC0gMSkgPT0gJyAnKQoJCQkJCWluZGV4IC0tOwoJCQkJaW50IGluZGV4MiA9IGV4aXN0aW5nVk1BcmdzLmluZGV4T2YoIiAiLCBpbmRleCArIDIpOwoJCQkJZXhpc3RpbmdWTUFyZ3MgPSBleGlzdGluZ1ZNQXJncy5zdWJzdHJpbmcoMCwgaW5kZXgpICsgZXhpc3RpbmdWTUFyZ3Muc3Vic3RyaW5nKGluZGV4Mik7CgkJCX0KCQkJaW5kZXggPSBleGlzdGluZ1ZNQXJncy5pbmRleE9mKCItRGphdmEuc2VjdXJpdHkucG9saWN5PSIpOwoJCQlpZiAoaW5kZXggPj0gMCkgewoJCQkJaWYgKGluZGV4ID4gMCAmJiBleGlzdGluZ1ZNQXJncy5jaGFyQXQoaW5kZXggLSAxKSA9PSAnICcpCgkJCQkJaW5kZXggLS07CgkJCQlpbnQgaW5kZXgyID0gZXhpc3RpbmdWTUFyZ3MuaW5kZXhPZigiXCIiLCBpbmRleCk7CgkJCQlpbmRleDIgPSBleGlzdGluZ1ZNQXJncy5pbmRleE9mKCJcIiIsIGluZGV4MiArIDEpOwoJCQkJZXhpc3RpbmdWTUFyZ3MgPSBleGlzdGluZ1ZNQXJncy5zdWJzdHJpbmcoMCwgaW5kZXgpICsgZXhpc3RpbmdWTUFyZ3Muc3Vic3RyaW5nKGluZGV4MisxKTsKCQkJfQoJCX0KCQl3b3JraW5nQ29weS5zZXRBdHRyaWJ1dGUoSUphdmFMYXVuY2hDb25maWd1cmF0aW9uQ29uc3RhbnRzLkFUVFJfVk1fQVJHVU1FTlRTLCBtZXJnZUFyZ3VtZW50cyhleGlzdGluZ1ZNQXJncywgZ2V0UnVudGltZVZNQXJndW1lbnRzKCkpKTsKCQkKCQlJVG9tY2F0UnVudGltZSBydW50aW1lID0gZ2V0VG9tY2F0UnVudGltZSgpOwoJCUlWTUluc3RhbGwgdm1JbnN0YWxsID0gcnVudGltZS5nZXRWTUluc3RhbGwoKTsKCQlpZiAodm1JbnN0YWxsICE9IG51bGwpIHsKCQkJd29ya2luZ0NvcHkuc2V0QXR0cmlidXRlKElKYXZhTGF1bmNoQ29uZmlndXJhdGlvbkNvbnN0YW50cy5BVFRSX1ZNX0lOU1RBTExfVFlQRSwgdm1JbnN0YWxsLmdldFZNSW5zdGFsbFR5cGUoKS5nZXRJZCgpKTsKCQkJd29ya2luZ0NvcHkuc2V0QXR0cmlidXRlKElKYXZhTGF1bmNoQ29uZmlndXJhdGlvbkNvbnN0YW50cy5BVFRSX1ZNX0lOU1RBTExfTkFNRSwgdm1JbnN0YWxsLmdldE5hbWUoKSk7CgkJfQoJCQoJCS8vIHVwZGF0ZSBjbGFzc3BhdGgKCQlJUnVudGltZUNsYXNzcGF0aEVudHJ5W10gb3JpZ2luYWxDbGFzc3BhdGggPSBKYXZhUnVudGltZS5jb21wdXRlVW5yZXNvbHZlZFJ1bnRpbWVDbGFzc3BhdGgod29ya2luZ0NvcHkpOwoJCWludCBzaXplID0gb3JpZ2luYWxDbGFzc3BhdGgubGVuZ3RoOwoJCUxpc3Qgb2xkQ3AgPSBuZXcgQXJyYXlMaXN0KG9yaWdpbmFsQ2xhc3NwYXRoLmxlbmd0aCArIDIpOwoJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKQoJCQlvbGRDcC5hZGQob3JpZ2luYWxDbGFzc3BhdGhbaV0pOwoJCQoJCUxpc3QgY3AyID0gcnVudGltZS5nZXRSdW50aW1lQ2xhc3NwYXRoKCk7CgkJSXRlcmF0b3IgaXRlcmF0b3IgPSBjcDIuaXRlcmF0b3IoKTsKCQl3aGlsZSAoaXRlcmF0b3IuaGFzTmV4dCgpKSB7CgkJCUlSdW50aW1lQ2xhc3NwYXRoRW50cnkgZW50cnkgPSAoSVJ1bnRpbWVDbGFzc3BhdGhFbnRyeSkgaXRlcmF0b3IubmV4dCgpOwoJCQltZXJnZUNsYXNzcGF0aChvbGRDcCwgZW50cnkpOwoJCX0KCQkKCQlpZiAodm1JbnN0YWxsICE9IG51bGwpIHsKCQkJdHJ5IHsKCQkJCVN0cmluZyB0eXBlSWQgPSB2bUluc3RhbGwuZ2V0Vk1JbnN0YWxsVHlwZSgpLmdldElkKCk7CgkJCQlyZXBsYWNlSlJFQ29udGFpbmVyKG9sZENwLCBKYXZhUnVudGltZS5uZXdSdW50aW1lQ29udGFpbmVyQ2xhc3NwYXRoRW50cnkobmV3IFBhdGgoSmF2YVJ1bnRpbWUuSlJFX0NPTlRBSU5FUikuYXBwZW5kKHR5cGVJZCkuYXBwZW5kKHZtSW5zdGFsbC5nZXROYW1lKCkpLCBJUnVudGltZUNsYXNzcGF0aEVudHJ5LkJPT1RTVFJBUF9DTEFTU0VTKSk7CgkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCQkvLyBpZ25vcmUKCQkJfQoJCQkKCQkJSVBhdGgganJlUGF0aCA9IG5ldyBQYXRoKHZtSW5zdGFsbC5nZXRJbnN0YWxsTG9jYXRpb24oKS5nZXRBYnNvbHV0ZVBhdGgoKSk7CgkJCWlmIChqcmVQYXRoICE9IG51bGwpIHsKCQkJCUlQYXRoIHRvb2xzUGF0aCA9IGpyZVBhdGguYXBwZW5kKCJsaWIiKS5hcHBlbmQoInRvb2xzLmphciIpOwoJCQkJaWYgKHRvb2xzUGF0aC50b0ZpbGUoKS5leGlzdHMoKSkKCQkJCQltZXJnZUNsYXNzcGF0aChvbGRDcCwgSmF2YVJ1bnRpbWUubmV3QXJjaGl2ZVJ1bnRpbWVDbGFzc3BhdGhFbnRyeSh0b29sc1BhdGgpKTsKCQkJfQoJCX0KCQkKCQlpdGVyYXRvciA9IG9sZENwLml0ZXJhdG9yKCk7CgkJTGlzdCBsaXN0ID0gbmV3IEFycmF5TGlzdCgpOwoJCXdoaWxlIChpdGVyYXRvci5oYXNOZXh0KCkpIHsKCQkJSVJ1bnRpbWVDbGFzc3BhdGhFbnRyeSBlbnRyeSA9IChJUnVudGltZUNsYXNzcGF0aEVudHJ5KSBpdGVyYXRvci5uZXh0KCk7CgkJCXRyeSB7CgkJCQlsaXN0LmFkZChlbnRyeS5nZXRNZW1lbnRvKCkpOwoJCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiQ291bGQgbm90IHJlc29sdmUgY2xhc3NwYXRoIGVudHJ5OiAiICsgZW50cnksIGUpOwoJCQl9CgkJfQoJCQoJCXdvcmtpbmdDb3B5LnNldEF0dHJpYnV0ZShJSmF2YUxhdW5jaENvbmZpZ3VyYXRpb25Db25zdGFudHMuQVRUUl9DTEFTU1BBVEgsIGxpc3QpOwoJCXdvcmtpbmdDb3B5LnNldEF0dHJpYnV0ZShJSmF2YUxhdW5jaENvbmZpZ3VyYXRpb25Db25zdGFudHMuQVRUUl9ERUZBVUxUX0NMQVNTUEFUSCwgZmFsc2UpOwoJfQoKCXByb3RlY3RlZCBJTW9kdWxlUmVzb3VyY2VEZWx0YVtdIGdldFB1Ymxpc2hlZFJlc291cmNlRGVsdGEoSU1vZHVsZVtdIG1vZHVsZSkgewoJCXJldHVybiBzdXBlci5nZXRQdWJsaXNoZWRSZXNvdXJjZURlbHRhKG1vZHVsZSk7Cgl9CgoJLyoqCgkgKiBAc2VlIFNlcnZlckJlaGF2aW91ckRlbGVnYXRlI2hhbmRsZVJlc291cmNlQ2hhbmdlKCkKCSAqLwoJcHVibGljIHZvaWQgaGFuZGxlUmVzb3VyY2VDaGFuZ2UoKSB7CgkJaWYgKGdldFNlcnZlcigpLmdldFNlcnZlclJlc3RhcnRTdGF0ZSgpKQoJCQlyZXR1cm47CgkJCgkJSXRlcmF0b3IgaXRlcmF0b3IgPSBnZXRBbGxNb2R1bGVzKCkuaXRlcmF0b3IoKTsKCQl3aGlsZSAoaXRlcmF0b3IuaGFzTmV4dCgpKSB7CgkJCUlNb2R1bGVbXSBtb2R1bGUgPSAoSU1vZHVsZVtdKSBpdGVyYXRvci5uZXh0KCk7CgkJCUlNb2R1bGVSZXNvdXJjZURlbHRhW10gZGVsdGEgPSBnZXRQdWJsaXNoZWRSZXNvdXJjZURlbHRhKG1vZHVsZSk7CgkJCWlmIChkZWx0YSA9PSBudWxsIHx8IGRlbHRhLmxlbmd0aCA9PSAwKQoJCQkJY29udGludWU7CgkJCQoJCQlpZiAoY29udGFpbnNOb25SZXNvdXJjZUNoYW5nZShkZWx0YSkpIHsKCQkJCXNldFNlcnZlclJlc3RhcnRTdGF0ZSh0cnVlKTsKCQkJCXJldHVybjsKCQkJfQoJCX0KCX0KCglwcm90ZWN0ZWQgYm9vbGVhbiBjb250YWluc05vblJlc291cmNlQ2hhbmdlKElNb2R1bGVSZXNvdXJjZURlbHRhW10gZGVsdGEpIHsKCQlpbnQgc2l6ZSA9IGRlbHRhLmxlbmd0aDsKCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQlJTW9kdWxlUmVzb3VyY2VEZWx0YSBkID0gZGVsdGFbaV07CgkJCWlmICgiV0VCLUlORiIuZXF1YWxzKGQuZ2V0TW9kdWxlUmVzb3VyY2UoKS5nZXROYW1lKCkpKQoJCQkJcmV0dXJuIHRydWU7CgkJfQoJCXJldHVybiBmYWxzZTsKCX0KfQ==