LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzIElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCqAqCiAqIENvbnRyaWJ1dG9yczoKICogICAgIElCTSBDb3Jwb3JhdGlvbiAtIEluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KcGFja2FnZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmU7CgppbXBvcnQgamF2YS51dGlsLio7CgppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS4qOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLmludGVybmFsLio7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS51dGlsLlByb2dyZXNzVXRpbDsKLyoqCiAqIEJhc2UgY2xhc3MgZm9yIG9idGFpbmluZyByZWZlcmVuY2VzIHRvIHNlcnZlciBtb2RlbHMuCiAqIAogKiBBbHNvIHByb3ZpZGVzIHJlZmVyZW5jZXMgZm9yIHNlcnZlcnMgYW5kIHNlcnZlciBjb25maWd1cmF0aW9ucy4KICogVGhlc2UgcmVmZXJlbmNlcyBjYW4gYmUgc2F2ZWQgYXMgdG9vbCBvciBzZXJ2ZXItZGF0YSBhbmQgY2FuIGJlCiAqIHVzZWQgdG8gcmV0dXJuIHRoZSBvcmlnaW5hbCByZXNvdXJjZSBpZiBpdCBzdGlsbCBleGlzdHMuIFRoZXNlCiAqIHJlZmVyZW5jZXMgYXJlIG5vdCBPUyBzcGVjaWZpYyBhbmQgY2FuIGJlIHVzZWQgaW4gYSB0ZWFtIGVudmlyb25tZW50LgogKi8KcHVibGljIGNsYXNzIFNlcnZlckNvcmUgewoJLy8gc2VydmVyIGNvcmUgcGx1Z2luIGlkCglwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBQTFVHSU5fSUQgPSAib3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlIjsKCgkvLyBjYWNoZWQgY29weSBvZiBhbGwgc2VydmVyIHN0YXJ0dXBzCglwcml2YXRlIHN0YXRpYyBMaXN0IHN0YXJ0dXBzOwoKCS8vIGNhY2hlZCBjb3B5IG9mIGFsbCBtb2R1bGUgZmFjdG9yaWVzCglwcml2YXRlIHN0YXRpYyBMaXN0IG1vZHVsZUZhY3RvcmllczsKCgkvLyBjYWNoZWQgY29weSBvZiBhbGwgbW9kdWxlIG9iamVjdCBhZGFwdGVycwoJcHJpdmF0ZSBzdGF0aWMgTGlzdCBtb2R1bGVPYmplY3RBZGFwdGVyczsKCgkvLyBjYWNoZWQgY29weSBvZiBhbGwgbGF1bmNoYWJsZSBhZGFwdGVycwoJcHJpdmF0ZSBzdGF0aWMgTGlzdCBsYXVuY2hhYmxlQWRhcHRlcnM7CgoJLy8gY2FjaGVkIGNvcHkgb2YgYWxsIGxhdW5jaGFibGUgY2xpZW50cwoJcHJpdmF0ZSBzdGF0aWMgTGlzdCBsYXVuY2hhYmxlQ2xpZW50czsKCQoJLy8gY2FjaGVkIGNvcHkgb2YgYWxsIG1vZHVsZSB0YXNrcwoJcHJpdmF0ZSBzdGF0aWMgTGlzdCBtb2R1bGVUYXNrczsKCQoJLy8gY2FjaGVkIGNvcHkgb2YgYWxsIHNlcnZlciB0YXNrcwoJcHJpdmF0ZSBzdGF0aWMgTGlzdCBzZXJ2ZXJUYXNrczsKCQoJLy8JY2FjaGVkIGNvcHkgb2YgYWxsIG1vZHVsZSBraW5kcwoJcHJpdmF0ZSBzdGF0aWMgTGlzdCBtb2R1bGVLaW5kczsKCQoJLy8JY2FjaGVkIGNvcHkgb2YgYWxsIHJ1bnRpbWUgdHlwZXMKCXByaXZhdGUgc3RhdGljIExpc3QgcnVudGltZVR5cGVzOwoJCgkvLwljYWNoZWQgY29weSBvZiBhbGwgcnVudGltZSB0YXJnZXQgaGFuZGxlcnMKCXByaXZhdGUgc3RhdGljIExpc3QgcnVudGltZVRhcmdldEhhbmRsZXJzOwoJCgkvLwljYWNoZWQgY29weSBvZiBhbGwgcnVudGltZSBsb2NhdG9ycwoJcHJpdmF0ZSBzdGF0aWMgTGlzdCBydW50aW1lTG9jYXRvcnM7CgoJLy8JY2FjaGVkIGNvcHkgb2YgYWxsIHNlcnZlciBhbmQgY29uZmlndXJhdGlvbiB0eXBlcwoJcHJpdmF0ZSBzdGF0aWMgTGlzdCBzZXJ2ZXJUeXBlczsKCXByaXZhdGUgc3RhdGljIExpc3Qgc2VydmVyQ29uZmlndXJhdGlvblR5cGVzOwoJCgkvLwljYWNoZWQgY29weSBvZiBhbGwgbW9uaXRvcnMKCXByaXZhdGUgc3RhdGljIExpc3QgbW9uaXRvcnM7CgoJLy8gY2FjaGVkIGNvcHkgb2YgdGhlIHNlcnZlciBwdWJsaXNoZXIgY2xhc3NlcwoJLy8ga2V5ZWQgZnJvbSBTdHJpbmcgaWQgdG8gSVB1Ymxpc2hNYW5hZ2VyCglwcml2YXRlIHN0YXRpYyBNYXAgcHVibGlzaE1hbmFnZXJzOwoJCgkvLyBwcmVmZXJlbmNlcwoJcHJpdmF0ZSBzdGF0aWMgSVNlcnZlclByZWZlcmVuY2VzIHByZWZlcmVuY2VzOwoKCS8qKgoJICogU2VydmVyQ29yZSBjb25zdHJ1Y3RvciBjb21tZW50LgoJICovCglwcml2YXRlIFNlcnZlckNvcmUoKSB7CgkJc3VwZXIoKTsKCX0KCgkvKioKCSAqIFJldHVybnMgYSBtYXAgb2YgYWxsIHB1Ymxpc2hNYW5hZ2Vycywga2V5ZWQgYnkgU3RyaW5nIGlkLgoJICoKCSAqIEByZXR1cm4gamF2YS51dGlsLk1hcAoJICovCglwdWJsaWMgc3RhdGljIE1hcCBnZXRQdWJsaXNoTWFuYWdlcnMoKSB7CgkJaWYgKHB1Ymxpc2hNYW5hZ2VycyA9PSBudWxsKQoJCQlsb2FkUHVibGlzaE1hbmFnZXJzKCk7CgkJcmV0dXJuIHB1Ymxpc2hNYW5hZ2VyczsKCX0KCgkvKioKCSAqIFJldHVybnMgdGhlIHB1Ymxpc2ggbWFuYWdlciB3aXRoIHRoZSBnaXZlbiBpZC4KCSAqCgkgKiBAcmV0dXJuIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5JUHVibGlzaE1hbmFnZXIKCSAqLwoJcHVibGljIHN0YXRpYyBJUHVibGlzaE1hbmFnZXIgZ2V0UHVibGlzaE1hbmFnZXIoU3RyaW5nIGlkKSB7CgkJaWYgKHB1Ymxpc2hNYW5hZ2VycyA9PSBudWxsKQoJCQlsb2FkUHVibGlzaE1hbmFnZXJzKCk7CgkJCQoJCXRyeSB7CgkJCXJldHVybiAoSVB1Ymxpc2hNYW5hZ2VyKSBwdWJsaXNoTWFuYWdlcnMuZ2V0KGlkKTsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCX0KCQlyZXR1cm4gbnVsbDsKCX0KCgkvKioKCSAqIFJldHVybnMgdGhlIHJlc291cmNlIG1hbmFnZXIuCgkgKgoJICogQHJldHVybiBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuSVJlc291cmNlTWFuYWdlcgoJICovCglwdWJsaWMgc3RhdGljIElSZXNvdXJjZU1hbmFnZXIgZ2V0UmVzb3VyY2VNYW5hZ2VyKCkgewoJCXJldHVybiBSZXNvdXJjZU1hbmFnZXIuZ2V0SW5zdGFuY2UoKTsKCX0KCQoJLyoqCgkgKiBSZXR1cm5zIHRoZSBzZXJ2ZXIgbW9uaXRvciBtYW5hZ2VyLgoJICoKCSAqIEByZXR1cm4gb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklTZXJ2ZXJNb25pdG9yTWFuYWdlcgoJICovCglwdWJsaWMgc3RhdGljIElTZXJ2ZXJNb25pdG9yTWFuYWdlciBnZXRTZXJ2ZXJNb25pdG9yTWFuYWdlcigpIHsKCQlyZXR1cm4gU2VydmVyTW9uaXRvck1hbmFnZXIuZ2V0SW5zdGFuY2UoKTsKCX0KCgkvKioKCSAqIFJldHVybnMgdGhlIHByZWZlcmVuY2UgaW5mb3JtYXRpb24gZm9yIHRoZSBzZXJ2ZXIgY29yZSBwbHVnaW4uCgkgKgoJICogQHJldHVybiBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuSVNlcnZlclByZWZlcmVuY2VzCgkgKi8KCXB1YmxpYyBzdGF0aWMgSVNlcnZlclByZWZlcmVuY2VzIGdldFNlcnZlclByZWZlcmVuY2VzKCkgewoJCWlmIChwcmVmZXJlbmNlcyA9PSBudWxsKQoJCQlwcmVmZXJlbmNlcyA9IG5ldyBTZXJ2ZXJQcmVmZXJlbmNlcygpOwoJCXJldHVybiBwcmVmZXJlbmNlczsKCX0KCQoJLyoqCgkgKiBSZXR1cm5zIHRoZSBwcmVmZXJlbmNlIGluZm9ybWF0aW9uIGZvciB0aGUgcHJvamVjdC4KCSAqCgkgKiBAcmV0dXJuIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5JU2VydmVyUHJvamVjdFByZWZlcmVuY2VzCgkgKi8KCXB1YmxpYyBzdGF0aWMgSVByb2plY3RQcm9wZXJ0aWVzIGdldFByb2plY3RQcm9wZXJ0aWVzKElQcm9qZWN0IHByb2plY3QpIHsKCQlyZXR1cm4gbmV3IFByb2plY3RQcm9wZXJ0aWVzKHByb2plY3QpOwoJfQoJCgkvKioKCSAqIFJldHVybnMgYSBMaXN0IG9mIGFsbCBzdGFydHVwcy4KCSAqCgkgKiBAcmV0dXJuIGphdmEudXRpbC5MaXN0CgkgKi8KCXB1YmxpYyBzdGF0aWMgTGlzdCBnZXRTdGFydHVwcygpIHsKCQlpZiAoc3RhcnR1cHMgPT0gbnVsbCkKCQkJbG9hZFN0YXJ0dXBzKCk7CgkJcmV0dXJuIHN0YXJ0dXBzOwoJfQoJCgkvKioKCSAqIFJldHVybnMgYSBMaXN0IG9mIGFsbCBtb2R1bGUga2luZHMuCgkgKgoJICogQHJldHVybiBqYXZhLnV0aWwuTGlzdAoJICovCglwdWJsaWMgc3RhdGljIExpc3QgZ2V0TW9kdWxlS2luZHMoKSB7CgkJaWYgKG1vZHVsZUtpbmRzID09IG51bGwpCgkJCWxvYWRNb2R1bGVLaW5kcygpOwoJCXJldHVybiBtb2R1bGVLaW5kczsKCX0KCQoJLyoqCgkgKiBSZXR1cm5zIHRoZSBtb2R1bGUga2luZCB3aXRoIHRoZSBnaXZlbiBpZC4KCSAqCgkgKiBAcmV0dXJuIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5JTW9kdWxlS2luZAoJICovCglwdWJsaWMgc3RhdGljIElNb2R1bGVLaW5kIGdldE1vZHVsZUtpbmQoU3RyaW5nIGlkKSB7CgkJaWYgKGlkID09IG51bGwpCgkJCXJldHVybiBudWxsOwoKCQlpZiAobW9kdWxlS2luZHMgPT0gbnVsbCkKCQkJbG9hZE1vZHVsZUtpbmRzKCk7CgkJCgkJSXRlcmF0b3IgaXRlcmF0b3IgPSBtb2R1bGVLaW5kcy5pdGVyYXRvcigpOwoJCXdoaWxlIChpdGVyYXRvci5oYXNOZXh0KCkpIHsKCQkJSU1vZHVsZUtpbmQgbW9kdWxlVHlwZSA9IChJTW9kdWxlS2luZCkgaXRlcmF0b3IubmV4dCgpOwoJCQlpZiAoaWQuZXF1YWxzKG1vZHVsZVR5cGUuZ2V0SWQoKSkpCgkJCQlyZXR1cm4gbW9kdWxlVHlwZTsKCQl9CgkJcmV0dXJuIG51bGw7Cgl9CgkKCS8qKgoJICogUmV0dXJucyBhIExpc3Qgb2YgYWxsIHJ1bnRpbWUgdHlwZXMuCgkgKgoJICogQHJldHVybiBqYXZhLnV0aWwuTGlzdAoJICovCglwdWJsaWMgc3RhdGljIExpc3QgZ2V0UnVudGltZVR5cGVzKCkgewoJCWlmIChydW50aW1lVHlwZXMgPT0gbnVsbCkKCQkJbG9hZFJ1bnRpbWVUeXBlcygpOwoJCXJldHVybiBydW50aW1lVHlwZXM7Cgl9CgkKCS8qKgoJICogUmV0dXJucyB0aGUgcnVudGltZSB0eXBlIHdpdGggdGhlIGdpdmVuIGlkLgoJICoKCSAqIEByZXR1cm4gb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklSdW50aW1lVHlwZQoJICovCglwdWJsaWMgc3RhdGljIElSdW50aW1lVHlwZSBnZXRSdW50aW1lVHlwZShTdHJpbmcgaWQpIHsKCQlpZiAoaWQgPT0gbnVsbCkKCQkJcmV0dXJuIG51bGw7CgoJCWlmIChydW50aW1lVHlwZXMgPT0gbnVsbCkKCQkJbG9hZFJ1bnRpbWVUeXBlcygpOwoJCQoJCUl0ZXJhdG9yIGl0ZXJhdG9yID0gcnVudGltZVR5cGVzLml0ZXJhdG9yKCk7CgkJd2hpbGUgKGl0ZXJhdG9yLmhhc05leHQoKSkgewoJCQlJUnVudGltZVR5cGUgcnVudGltZVR5cGUgPSAoSVJ1bnRpbWVUeXBlKSBpdGVyYXRvci5uZXh0KCk7CgkJCWlmIChpZC5lcXVhbHMocnVudGltZVR5cGUuZ2V0SWQoKSkpCgkJCQlyZXR1cm4gcnVudGltZVR5cGU7CgkJfQoJCXJldHVybiBudWxsOwoJfQoJCgkvKioKCSAqIFJldHVybnMgYSBMaXN0IG9mIGFsbCBydW50aW1lIGxvY2F0b3JzLgoJICoKCSAqIEByZXR1cm4gamF2YS51dGlsLkxpc3QKCSAqLwoJcHVibGljIHN0YXRpYyBMaXN0IGdldFJ1bnRpbWVMb2NhdG9ycygpIHsKCQlpZiAocnVudGltZUxvY2F0b3JzID09IG51bGwpCgkJCWxvYWRSdW50aW1lTG9jYXRvcnMoKTsKCQlyZXR1cm4gcnVudGltZUxvY2F0b3JzOwoJfQoJCgkvKioKCSAqIFJldHVybnMgYSBMaXN0IG9mIGFsbCBydW50aW1lIHRhcmdldCBoYW5kbGVycy4KCSAqCgkgKiBAcmV0dXJuIGphdmEudXRpbC5MaXN0CgkgKi8KCXB1YmxpYyBzdGF0aWMgTGlzdCBnZXRSdW50aW1lVGFyZ2V0SGFuZGxlcnMoKSB7CgkJaWYgKHJ1bnRpbWVUYXJnZXRIYW5kbGVycyA9PSBudWxsKQoJCQlsb2FkUnVudGltZVRhcmdldEhhbmRsZXJzKCk7CgkJcmV0dXJuIHJ1bnRpbWVUYXJnZXRIYW5kbGVyczsKCX0KCQoJLyoqCgkgKiBSZXR1cm5zIHRoZSBydW50aW1lIHRhcmdldCBoYW5kbGVyIHdpdGggdGhlIGdpdmVuIGlkLgoJICoKCSAqIEByZXR1cm4gb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklSdW50aW1lVGFyZ2V0SGFuZGxlcgoJICovCglwdWJsaWMgc3RhdGljIElSdW50aW1lVGFyZ2V0SGFuZGxlciBnZXRSdW50aW1lVGFyZ2V0SGFuZGxlcihTdHJpbmcgaWQpIHsKCQlpZiAoaWQgPT0gbnVsbCkKCQkJcmV0dXJuIG51bGw7CgoJCWlmIChydW50aW1lVGFyZ2V0SGFuZGxlcnMgPT0gbnVsbCkKCQkJbG9hZFJ1bnRpbWVUYXJnZXRIYW5kbGVycygpOwoJCQoJCUl0ZXJhdG9yIGl0ZXJhdG9yID0gcnVudGltZVRhcmdldEhhbmRsZXJzLml0ZXJhdG9yKCk7CgkJd2hpbGUgKGl0ZXJhdG9yLmhhc05leHQoKSkgewoJCQlJUnVudGltZVRhcmdldEhhbmRsZXIgcnVudGltZVRhcmdldExpc3RlbmVyID0gKElSdW50aW1lVGFyZ2V0SGFuZGxlcikgaXRlcmF0b3IubmV4dCgpOwoJCQlpZiAoaWQuZXF1YWxzKHJ1bnRpbWVUYXJnZXRMaXN0ZW5lci5nZXRJZCgpKSkKCQkJCXJldHVybiBydW50aW1lVGFyZ2V0TGlzdGVuZXI7CgkJfQoJCXJldHVybiBudWxsOwoJfQoKCS8qKgoJICogUmV0dXJucyBhIExpc3Qgb2YgYWxsIHNlcnZlciB0eXBlcy4KCSAqCgkgKiBAcmV0dXJuIGphdmEudXRpbC5MaXN0CgkgKi8KCXB1YmxpYyBzdGF0aWMgTGlzdCBnZXRTZXJ2ZXJUeXBlcygpIHsKCQlpZiAoc2VydmVyVHlwZXMgPT0gbnVsbCkKCQkJbG9hZFNlcnZlclR5cGVzKCk7CgkJcmV0dXJuIHNlcnZlclR5cGVzOwoJfQoJCgkvKioKCSAqIFJldHVybnMgdGhlIHNlcnZlciB0eXBlIHdpdGggdGhlIGdpdmVuIGlkLgoJICoKCSAqIEByZXR1cm4gb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklTZXJ2ZXJUeXBlCgkgKi8KCXB1YmxpYyBzdGF0aWMgSVNlcnZlclR5cGUgZ2V0U2VydmVyVHlwZShTdHJpbmcgaWQpIHsKCQlpZiAoaWQgPT0gbnVsbCkKCQkJcmV0dXJuIG51bGw7CgoJCWlmIChzZXJ2ZXJUeXBlcyA9PSBudWxsKQoJCQlsb2FkU2VydmVyVHlwZXMoKTsKCQkKCQlJdGVyYXRvciBpdGVyYXRvciA9IHNlcnZlclR5cGVzLml0ZXJhdG9yKCk7CgkJd2hpbGUgKGl0ZXJhdG9yLmhhc05leHQoKSkgewoJCQlJU2VydmVyVHlwZSBzZXJ2ZXJUeXBlID0gKElTZXJ2ZXJUeXBlKSBpdGVyYXRvci5uZXh0KCk7CgkJCWlmIChpZC5lcXVhbHMoc2VydmVyVHlwZS5nZXRJZCgpKSkKCQkJCXJldHVybiBzZXJ2ZXJUeXBlOwoJCX0KCQlyZXR1cm4gbnVsbDsKCX0KCQoJLyoqCgkgKiBSZXR1cm5zIGEgTGlzdCBvZiBhbGwgc2VydmVyIGNvbmZpZ3VyYXRpb24gdHlwZXMuCgkgKgoJICogQHJldHVybiBqYXZhLnV0aWwuTGlzdAoJICovCglwdWJsaWMgc3RhdGljIExpc3QgZ2V0U2VydmVyQ29uZmlndXJhdGlvblR5cGVzKCkgewoJCWlmIChzZXJ2ZXJDb25maWd1cmF0aW9uVHlwZXMgPT0gbnVsbCkKCQkJbG9hZFNlcnZlckNvbmZpZ3VyYXRpb25UeXBlcygpOwoJCXJldHVybiBzZXJ2ZXJDb25maWd1cmF0aW9uVHlwZXM7Cgl9CgkKCS8qKgoJICogUmV0dXJucyB0aGUgc2VydmVyIGNvbmZpZ3VyYXRpb24gdHlwZSB3aXRoIHRoZSBnaXZlbiBpZC4KCSAqCgkgKiBAcmV0dXJuIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5JU2VydmVyQ29uZmlndXJhdGlvblR5cGUKCSAqLwoJcHVibGljIHN0YXRpYyBJU2VydmVyQ29uZmlndXJhdGlvblR5cGUgZ2V0U2VydmVyQ29uZmlndXJhdGlvblR5cGUoU3RyaW5nIGlkKSB7CgkJaWYgKGlkID09IG51bGwpCgkJCXJldHVybiBudWxsOwoKCQlpZiAoc2VydmVyQ29uZmlndXJhdGlvblR5cGVzID09IG51bGwpCgkJCWxvYWRTZXJ2ZXJDb25maWd1cmF0aW9uVHlwZXMoKTsKCQkKCQlJdGVyYXRvciBpdGVyYXRvciA9IHNlcnZlckNvbmZpZ3VyYXRpb25UeXBlcy5pdGVyYXRvcigpOwoJCXdoaWxlIChpdGVyYXRvci5oYXNOZXh0KCkpIHsKCQkJSVNlcnZlckNvbmZpZ3VyYXRpb25UeXBlIHNlcnZlckNvbmZpZ3VyYXRpb25UeXBlID0gKElTZXJ2ZXJDb25maWd1cmF0aW9uVHlwZSkgaXRlcmF0b3IubmV4dCgpOwoJCQlpZiAoaWQuZXF1YWxzKHNlcnZlckNvbmZpZ3VyYXRpb25UeXBlLmdldElkKCkpKQoJCQkJcmV0dXJuIHNlcnZlckNvbmZpZ3VyYXRpb25UeXBlOwoJCX0KCQlyZXR1cm4gbnVsbDsKCX0KCgkvKioKCSAqIFJldHVybnMgYSBMaXN0IG9mIGFsbCBtb2R1bGUgZmFjdG9yaWVzLgoJICoKCSAqIEByZXR1cm4gamF2YS51dGlsLkxpc3QKCSAqLwoJcHVibGljIHN0YXRpYyBMaXN0IGdldE1vZHVsZUZhY3RvcmllcygpIHsKCQlpZiAobW9kdWxlRmFjdG9yaWVzID09IG51bGwpCgkJCWxvYWRNb2R1bGVGYWN0b3JpZXMoKTsKCQlyZXR1cm4gbW9kdWxlRmFjdG9yaWVzOwoJfQoJCgkvKioKCSAqIFJldHVybnMgdGhlIG1vZHVsZSBmYWN0b3J5LgoJICoKCSAqIEByZXR1cm4gamF2YS51dGlsLkxpc3QKCSAqLwoJcHVibGljIHN0YXRpYyBJTW9kdWxlRmFjdG9yeSBnZXRNb2R1bGVGYWN0b3J5KFN0cmluZyBpZCkgewoJCWlmIChpZCA9PSBudWxsKQoJCQlyZXR1cm4gbnVsbDsKCgkJaWYgKG1vZHVsZUZhY3RvcmllcyA9PSBudWxsKQoJCQlsb2FkTW9kdWxlRmFjdG9yaWVzKCk7CgkJCgkJSXRlcmF0b3IgaXRlcmF0b3IgPSBtb2R1bGVGYWN0b3JpZXMuaXRlcmF0b3IoKTsKCQl3aGlsZSAoaXRlcmF0b3IuaGFzTmV4dCgpKSB7CgkJCUlNb2R1bGVGYWN0b3J5IGZhY3RvcnkgPSAoSU1vZHVsZUZhY3RvcnkpIGl0ZXJhdG9yLm5leHQoKTsKCQkJaWYgKGlkLmVxdWFscyhmYWN0b3J5LmdldElkKCkpKQoJCQkJcmV0dXJuIGZhY3Rvcnk7CgkJfQoJCXJldHVybiBudWxsOwoJfQoKCS8qKgoJICogUmV0dXJucyBhIExpc3Qgb2YgYWxsIG1vZHVsZSBvYmplY3QgYWRhcHRlcnMuCgkgKgoJICogQHJldHVybiBqYXZhLnV0aWwuTGlzdAoJICovCglwdWJsaWMgc3RhdGljIExpc3QgZ2V0TW9kdWxlT2JqZWN0QWRhcHRlcnMoKSB7CgkJaWYgKG1vZHVsZU9iamVjdEFkYXB0ZXJzID09IG51bGwpCgkJCWxvYWRNb2R1bGVPYmplY3RBZGFwdGVycygpOwoJCXJldHVybiBtb2R1bGVPYmplY3RBZGFwdGVyczsKCX0KCQoJLyoqCgkgKiBSZXR1cm5zIGEgTGlzdCBvZiBhbGwgbGF1bmNoYWJsZSBhZGFwdGVycy4KCSAqCgkgKiBAcmV0dXJuIGphdmEudXRpbC5MaXN0CgkgKi8KCXB1YmxpYyBzdGF0aWMgTGlzdCBnZXRMYXVuY2hhYmxlQWRhcHRlcnMoKSB7CgkJaWYgKGxhdW5jaGFibGVBZGFwdGVycyA9PSBudWxsKQoJCQlsb2FkTGF1bmNoYWJsZUFkYXB0ZXJzKCk7CgkJcmV0dXJuIGxhdW5jaGFibGVBZGFwdGVyczsKCX0KCQoJLyoqCgkgKiBSZXR1cm5zIGEgTGlzdCBvZiBhbGwgbGF1bmNoYWJsZSBjbGllbnRzLgoJICoKCSAqIEByZXR1cm4gamF2YS51dGlsLkxpc3QKCSAqLwoJcHVibGljIHN0YXRpYyBMaXN0IGdldExhdW5jaGFibGVDbGllbnRzKCkgewoJCWlmIChsYXVuY2hhYmxlQ2xpZW50cyA9PSBudWxsKQoJCQlsb2FkTGF1bmNoYWJsZUNsaWVudHMoKTsKCQlyZXR1cm4gbGF1bmNoYWJsZUNsaWVudHM7Cgl9CgkKCS8qKgoJICogUmV0dXJucyBhIExpc3Qgb2YgYWxsIG1vZHVsZSB0YXNrcy4KCSAqCgkgKiBAcmV0dXJuIGphdmEudXRpbC5MaXN0CgkgKi8KCXB1YmxpYyBzdGF0aWMgTGlzdCBnZXRNb2R1bGVUYXNrcygpIHsKCQlpZiAobW9kdWxlVGFza3MgPT0gbnVsbCkKCQkJbG9hZE1vZHVsZVRhc2tzKCk7CgkJcmV0dXJuIG1vZHVsZVRhc2tzOwoJfQoJCgkvKioKCSAqIFJldHVybnMgYSBMaXN0IG9mIGFsbCBzZXJ2ZXIgdGFza3MuCgkgKgoJICogQHJldHVybiBqYXZhLnV0aWwuTGlzdAoJICovCglwdWJsaWMgc3RhdGljIExpc3QgZ2V0U2VydmVyVGFza3MoKSB7CgkJaWYgKHNlcnZlclRhc2tzID09IG51bGwpCgkJCWxvYWRTZXJ2ZXJUYXNrcygpOwoJCXJldHVybiBzZXJ2ZXJUYXNrczsKCX0KCQoJLyoqCgkgKiBSZXR1cm5zIGEgTGlzdCBvZiBhbGwgc2VydmVyIG1vbml0b3JzLgoJICoKCSAqIEByZXR1cm4gamF2YS51dGlsLkxpc3QKCSAqLwoJcHVibGljIHN0YXRpYyBMaXN0IGdldFNlcnZlck1vbml0b3JzKCkgewoJCWlmIChtb25pdG9ycyA9PSBudWxsKQoJCQlsb2FkU2VydmVyTW9uaXRvcnMoKTsKCQlyZXR1cm4gbW9uaXRvcnM7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIGEgbGlzdCBvZiBhbGwgb3BlbiBzZXJ2ZXIgcHJvamVjdHMgKElTZXJ2ZXJQcm9qZWN0cykKCSAqIGluIHRoZSB3b3JrYmVuY2guCgkgKgoJICogQHJldHVybiBqYXZhLnV0aWwuTGlzdAoJICovCglwdWJsaWMgc3RhdGljIExpc3QgZ2V0U2VydmVyTmF0dXJlcygpIHsKCQl0cnkgewoJCQlJUHJvamVjdFtdIHByb2plY3RzID0gUmVzb3VyY2VzUGx1Z2luLmdldFdvcmtzcGFjZSgpLmdldFJvb3QoKS5nZXRQcm9qZWN0cygpOwoJCgkJCUxpc3QgbGlzdCA9IG5ldyBBcnJheUxpc3QoKTsKCQkJaW50IHNpemUgPSBwcm9qZWN0cy5sZW5ndGg7CgkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQl0cnkgewoJCQkJCWlmIChwcm9qZWN0c1tpXS5pc09wZW4oKSAmJiBwcm9qZWN0c1tpXS5oYXNOYXR1cmUoSVNlcnZlclByb2plY3QuTkFUVVJFX0lEKSkKCQkJCQkJbGlzdC5hZGQocHJvamVjdHNbaV0uZ2V0TmF0dXJlKElTZXJ2ZXJQcm9qZWN0Lk5BVFVSRV9JRCkpOwoJCQkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJFcnJvciBhZGRpbmcgc2VydmVyIG5hdHVyZSIsIGUpOwoJCQkJfQoJCQl9CgkKCQkJcmV0dXJuIGxpc3Q7CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiRXJyb3IgZ2V0dGluZyBzZXJ2ZXIgbmF0dXJlcyIsIGUpOwoJCQlyZXR1cm4gbmV3IEFycmF5TGlzdCgpOwoJCX0KCX0KCgkvKioKCSAqIFJldHVybnMgYSBsaXN0IG9mIGFsbCBzZXJ2ZXIgcHJvamVjdHMgKElQcm9qZWN0cykgaW4KCSAqIHRoZSB3b3JrYmVuY2guCgkgKgoJICogQHJldHVybiBqYXZhLnV0aWwuTGlzdAoJICovCglwdWJsaWMgc3RhdGljIExpc3QgZ2V0U2VydmVyUHJvamVjdHMoKSB7CgkJdHJ5IHsKCQkJSVByb2plY3RbXSBwcm9qZWN0cyA9IFJlc291cmNlc1BsdWdpbi5nZXRXb3Jrc3BhY2UoKS5nZXRSb290KCkuZ2V0UHJvamVjdHMoKTsKCQoJCQlMaXN0IGxpc3QgPSBuZXcgQXJyYXlMaXN0KCk7CgkJCWludCBzaXplID0gcHJvamVjdHMubGVuZ3RoOwoJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJdHJ5IHsKCQkJCQlpZiAocHJvamVjdHNbaV0uaGFzTmF0dXJlKElTZXJ2ZXJQcm9qZWN0Lk5BVFVSRV9JRCkpCgkJCQkJCWxpc3QuYWRkKHByb2plY3RzW2ldKTsKCQkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiRXJyb3IgYWRkaW5nIHNlcnZlciBuYXR1cmUgcHJvamVjdCIsIGUpOwoJCQkJfQoJCQl9CgoJCQlyZXR1cm4gbGlzdDsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJFcnJvciBnZXR0aW5nIHNlcnZlciBuYXR1cmUgcHJvamVjdHMiLCBlKTsKCQkJcmV0dXJuIG5ldyBBcnJheUxpc3QoKTsKCQl9Cgl9CgkKCS8qKgoJICogQWRkIHRoZSBnaXZlbiBuYXR1cmUgdG8gdGhlIHByb2plY3QuCgkgKgoJICogQHBhcmFtIG1vbml0b3IKCSAqIEBwYXJhbSBwcm9qZWN0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklQcm9qZWN0CgkgKi8KCXByaXZhdGUgc3RhdGljIGJvb2xlYW4gYWRkTmF0dXJlKElQcm9qZWN0IHByb2plY3QsIFN0cmluZyBuYXR1cmVJZCwgSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB7CgkJaWYgKHByb2plY3QgPT0gbnVsbCkKCQkJcmV0dXJuIGZhbHNlOwoKCQl0cnkgewoJCQltb25pdG9yID0gUHJvZ3Jlc3NVdGlsLmdldE1vbml0b3JGb3IobW9uaXRvcik7CgoJCQkvLyBtYWtlIHN1cmUgdGhlIHByb2plY3QgaXMgb3BlbgoJCQlpZiAoIXByb2plY3QuaXNPcGVuKCkpIHsKCQkJCW1vbml0b3IuYmVnaW5UYXNrKFNlcnZlclBsdWdpbi5nZXRSZXNvdXJjZSgiJWNyZWF0ZVNlcnZlclByb2plY3RUYXNrIiksIDIwMDApOwoJCQkJcHJvamVjdC5vcGVuKFByb2dyZXNzVXRpbC5nZXRTdWJNb25pdG9yRm9yKG1vbml0b3IsIDEwMDApKTsKCQkJfSBlbHNlCgkJCQltb25pdG9yLmJlZ2luVGFzayhTZXJ2ZXJQbHVnaW4uZ2V0UmVzb3VyY2UoIiVjcmVhdGVTZXJ2ZXJQcm9qZWN0VGFzayIpLCAxMDAwKTsKCQkKCQkJLy8gZ2V0IHRoZSBjdXJyZW50IG5hdHVyZXMKCQkJSVByb2plY3REZXNjcmlwdGlvbiBkZXNjID0gcHJvamVjdC5nZXREZXNjcmlwdGlvbigpOwoJCQlTdHJpbmdbXSBuYXR1cmVJZHMgPSBkZXNjLmdldE5hdHVyZUlkcygpOwoJCQlpZiAobmF0dXJlSWRzID09IG51bGwpCgkJCQluYXR1cmVJZHMgPSBuZXcgU3RyaW5nWzBdOwoJCgkJCS8vIGNoZWNrIHRoYXQgdGhlIG5hdHVyZSBpc24ndCBhbHJlYWR5IHRoZXJlLi4KCQkJaW50IHNpemUgPSBuYXR1cmVJZHMubGVuZ3RoOwoJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJaWYgKG5hdHVyZUlkLmVxdWFscyhuYXR1cmVJZHNbaV0pKQoJCQkJCXJldHVybiB0cnVlOwoJCQl9CgkKCQkJLy8gb3RoZXJ3aXNlLCBhZGQgdGhlIG5ldyBuYXR1cmUKCQkJU3RyaW5nW10gbmV3TmF0dXJlSWRzID0gbmV3IFN0cmluZ1tzaXplICsgMV07CgkJCVN5c3RlbS5hcnJheWNvcHkobmF0dXJlSWRzLCAwLCBuZXdOYXR1cmVJZHMsIDAsIHNpemUpOwoJCQluZXdOYXR1cmVJZHNbc2l6ZV0gPSBuYXR1cmVJZDsKCQkJZGVzYy5zZXROYXR1cmVJZHMobmV3TmF0dXJlSWRzKTsKCQoJCQlwcm9qZWN0LnNldERlc2NyaXB0aW9uKGRlc2MsIFByb2dyZXNzVXRpbC5nZXRTdWJNb25pdG9yRm9yKG1vbml0b3IsIDEwMDApKTsKCQkJcmV0dXJuIHRydWU7CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiQ291bGQgbm90IGFkZCBuYXR1cmUgdG8gIiArIHByb2plY3QuZ2V0TmFtZSgpLCBlKTsKCQkJcmV0dXJuIGZhbHNlOwoJCX0gZmluYWxseSB7CgkJCW1vbml0b3IuZG9uZSgpOwoJCX0KCX0KCgkvKioKCSAqIENyZWF0ZXMgYSBuZXcgc2VydmVyIHByb2plY3Qgd2l0aCB0aGUgZ2l2ZW4gbmFtZS4gSWYgcGF0aCBpcwoJICogbnVsbCwgaXQgd2lsbCBiZSBjcmVhdGVkIGluIHRoZSBkZWZhdWx0IGxvY2F0aW9uLgoJICoKCSAqIEBwYXJhbSBuYW1lIGphdmEubGFuZy5TdHJpbmcKCSAqIEBwYXJhbSBwYXRoIG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2UuSVBhdGgKCSAqIEBwYXJhbSBtb25pdG9yCgkgKiBAcmV0dXJuIG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5JU3RhdHVzCgkgKi8KCXB1YmxpYyBzdGF0aWMgSVN0YXR1cyBjcmVhdGVTZXJ2ZXJQcm9qZWN0KFN0cmluZyBuYW1lLCBJUGF0aCBwYXRoLCBJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHsKCQltb25pdG9yID0gUHJvZ3Jlc3NVdGlsLmdldE1vbml0b3JGb3IobW9uaXRvcik7CgkJbW9uaXRvci5iZWdpblRhc2soU2VydmVyUGx1Z2luLmdldFJlc291cmNlKCIlY3JlYXRlU2VydmVyUHJvamVjdFRhc2siKSwgMzAwMCk7CgoJCXRyeSB7CgkJCUlXb3Jrc3BhY2Ugd29ya3NwYWNlID0gUmVzb3VyY2VzUGx1Z2luLmdldFdvcmtzcGFjZSgpOwoJCQlJUHJvamVjdCBwcm9qZWN0ID0gd29ya3NwYWNlLmdldFJvb3QoKS5nZXRQcm9qZWN0KG5hbWUpOwoJCgkJCS8vIGdldCBhIHByb2plY3QgZGVzY3JpcHRvcgoJCQlJUHJvamVjdERlc2NyaXB0aW9uIGRlc2NyaXB0aW9uID0gd29ya3NwYWNlLm5ld1Byb2plY3REZXNjcmlwdGlvbihuYW1lKTsKCQkJZGVzY3JpcHRpb24uc2V0TG9jYXRpb24ocGF0aCk7CgkKCQkJcHJvamVjdC5jcmVhdGUoZGVzY3JpcHRpb24sIFByb2dyZXNzVXRpbC5nZXRTdWJNb25pdG9yRm9yKG1vbml0b3IsIDEwMDApKTsKCQkJaWYgKG1vbml0b3IuaXNDYW5jZWxlZCgpKQoJCQkJcmV0dXJuIG51bGw7CgkJCXByb2plY3Qub3BlbihQcm9ncmVzc1V0aWwuZ2V0U3ViTW9uaXRvckZvcihtb25pdG9yLCAxMDAwKSk7CgkJCWlmIChtb25pdG9yLmlzQ2FuY2VsZWQoKSkKCQkJCXJldHVybiBudWxsOwoKCQkJLy8gYWRkIHRoZSBzZXJ2ZXIgcHJvamVjdCBuYXR1cmUKCQkJYWRkTmF0dXJlKHByb2plY3QsIElTZXJ2ZXJQcm9qZWN0Lk5BVFVSRV9JRCwgUHJvZ3Jlc3NVdGlsLmdldFN1Yk1vbml0b3JGb3IobW9uaXRvciwgMTAwMCkpOwoJCgkJCWlmIChtb25pdG9yLmlzQ2FuY2VsZWQoKSkKCQkJCXJldHVybiBudWxsOwoJCgkJCXJldHVybiBuZXcgU3RhdHVzKElTdGF0dXMuT0ssIFNlcnZlckNvcmUuUExVR0lOX0lELCAwLCBTZXJ2ZXJQbHVnaW4uZ2V0UmVzb3VyY2UoIiVzZXJ2ZXJQcm9qZWN0Q3JlYXRlZCIpLCBudWxsKTsKCQl9IGNhdGNoIChDb3JlRXhjZXB0aW9uIGNlKSB7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIkNvdWxkIG5vdCBjcmVhdGUgc2VydmVyIHByb2plY3QgbmFtZWQgIiArIG5hbWUsIGNlKTsKCQkJcmV0dXJuIG5ldyBTdGF0dXMoSVN0YXR1cy5FUlJPUiwgU2VydmVyQ29yZS5QTFVHSU5fSUQsIDAsIFNlcnZlclBsdWdpbi5nZXRSZXNvdXJjZSgiJWVycm9yQ291bGROb3RDcmVhdGVTZXJ2ZXJQcm9qZWN0U3RhdHVzIiwgY2UuZ2V0TWVzc2FnZSgpKSwgY2UpOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIkNvdWxkIG5vdCBjcmVhdGUgc2VydmVyIHByb2plY3QgKDIpIG5hbWVkICIgKyBuYW1lLCBlKTsKCQkJcmV0dXJuIG5ldyBTdGF0dXMoSVN0YXR1cy5FUlJPUiwgU2VydmVyQ29yZS5QTFVHSU5fSUQsIDAsIFNlcnZlclBsdWdpbi5nZXRSZXNvdXJjZSgiJWVycm9yQ291bGROb3RDcmVhdGVTZXJ2ZXJQcm9qZWN0IiksIGUpOwoJCX0gZmluYWxseSB7CgkJCW1vbml0b3IuZG9uZSgpOwoJCX0KCX0KCgkvKioKCSAqIExvYWQgdGhlIHNlcnZlciBzdGFydHVwcy4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgdm9pZCBsb2FkU3RhcnR1cHMoKSB7CgkJVHJhY2UudHJhY2UoVHJhY2UuRVhURU5TSU9OX1BPSU5ULCAiLT4tIExvYWRpbmcgLnN0YXJ0dXAgZXh0ZW5zaW9uIHBvaW50IC0+LSIpOwoJCUlFeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSA9IFBsYXRmb3JtLmdldEV4dGVuc2lvblJlZ2lzdHJ5KCk7CgkJSUNvbmZpZ3VyYXRpb25FbGVtZW50W10gY2YgPSByZWdpc3RyeS5nZXRDb25maWd1cmF0aW9uRWxlbWVudHNGb3IoU2VydmVyQ29yZS5QTFVHSU5fSUQsICJzdGFydHVwIik7CgoJCWludCBzaXplID0gY2YubGVuZ3RoOwoJCXN0YXJ0dXBzID0gbmV3IEFycmF5TGlzdChzaXplKTsKCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQl0cnkgewoJCQkJSVN0YXJ0dXAgc3RhcnR1cCA9IChJU3RhcnR1cCkgY2ZbaV0uY3JlYXRlRXhlY3V0YWJsZUV4dGVuc2lvbigiY2xhc3MiKTsKCQkJCXN0YXJ0dXBzLmFkZChzdGFydHVwKTsKCQkJCVRyYWNlLnRyYWNlKFRyYWNlLkVYVEVOU0lPTl9QT0lOVCwgIiAgTG9hZGVkIHN0YXJ0dXA6ICIgKyBjZltpXS5nZXRBdHRyaWJ1dGUoImlkIikpOwoJCQl9IGNhdGNoIChUaHJvd2FibGUgdCkgewoJCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiICBDb3VsZCBub3QgbG9hZCBzdGFydHVwOiAiICsgY2ZbaV0uZ2V0QXR0cmlidXRlKCJpZCIpLCB0KTsKCQkJfQoJCX0KCQkKCQlUcmFjZS50cmFjZShUcmFjZS5FWFRFTlNJT05fUE9JTlQsICItPC0gRG9uZSBsb2FkaW5nIC5zdGFydHVwIGV4dGVuc2lvbiBwb2ludCAtPC0iKTsKCX0KCQoJLyoqCgkgKiBMb2FkIHRoZSBtb2R1bGUga2luZHMuCgkgKi8KCXByaXZhdGUgc3RhdGljIHZvaWQgbG9hZE1vZHVsZUtpbmRzKCkgewoJCVRyYWNlLnRyYWNlKFRyYWNlLkVYVEVOU0lPTl9QT0lOVCwgIi0+LSBMb2FkaW5nIC5tb2R1bGVLaW5kcyBleHRlbnNpb24gcG9pbnQgLT4tIik7CgkJSUV4dGVuc2lvblJlZ2lzdHJ5IHJlZ2lzdHJ5ID0gUGxhdGZvcm0uZ2V0RXh0ZW5zaW9uUmVnaXN0cnkoKTsKCQlJQ29uZmlndXJhdGlvbkVsZW1lbnRbXSBjZiA9IHJlZ2lzdHJ5LmdldENvbmZpZ3VyYXRpb25FbGVtZW50c0ZvcihTZXJ2ZXJDb3JlLlBMVUdJTl9JRCwgIm1vZHVsZUtpbmRzIik7CgoJCWludCBzaXplID0gY2YubGVuZ3RoOwoJCW1vZHVsZUtpbmRzID0gbmV3IEFycmF5TGlzdChzaXplKTsKCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQl0cnkgewoJCQkJTW9kdWxlS2luZCBtb2R1bGVLaW5kID0gbmV3IE1vZHVsZUtpbmQoY2ZbaV0pOwoJCQkJbW9kdWxlS2luZHMuYWRkKG1vZHVsZUtpbmQpOwoJCQkJVHJhY2UudHJhY2UoVHJhY2UuRVhURU5TSU9OX1BPSU5ULCAiICBMb2FkZWQgbW9kdWxlS2luZDogIiArIGNmW2ldLmdldEF0dHJpYnV0ZSgiaWQiKSk7CgkJCX0gY2F0Y2ggKFRocm93YWJsZSB0KSB7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICIgIENvdWxkIG5vdCBsb2FkIG1vZHVsZUtpbmQ6ICIgKyBjZltpXS5nZXRBdHRyaWJ1dGUoImlkIiksIHQpOwoJCQl9CgkJfQoJCQoJCVRyYWNlLnRyYWNlKFRyYWNlLkVYVEVOU0lPTl9QT0lOVCwgIi08LSBEb25lIGxvYWRpbmcgLm1vZHVsZUtpbmRzIGV4dGVuc2lvbiBwb2ludCAtPC0iKTsKCX0KCgkvKioKCSAqIExvYWQgdGhlIHJ1bnRpbWUgdHlwZXMuCgkgKi8KCXByaXZhdGUgc3RhdGljIHZvaWQgbG9hZFJ1bnRpbWVUeXBlcygpIHsKCQlUcmFjZS50cmFjZShUcmFjZS5FWFRFTlNJT05fUE9JTlQsICItPi0gTG9hZGluZyAucnVudGltZVR5cGVzIGV4dGVuc2lvbiBwb2ludCAtPi0iKTsKCQlJRXh0ZW5zaW9uUmVnaXN0cnkgcmVnaXN0cnkgPSBQbGF0Zm9ybS5nZXRFeHRlbnNpb25SZWdpc3RyeSgpOwoJCUlDb25maWd1cmF0aW9uRWxlbWVudFtdIGNmID0gcmVnaXN0cnkuZ2V0Q29uZmlndXJhdGlvbkVsZW1lbnRzRm9yKFNlcnZlckNvcmUuUExVR0lOX0lELCAicnVudGltZVR5cGVzIik7CgoJCWludCBzaXplID0gY2YubGVuZ3RoOwoJCXJ1bnRpbWVUeXBlcyA9IG5ldyBBcnJheUxpc3Qoc2l6ZSk7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJdHJ5IHsKCQkJCVJ1bnRpbWVUeXBlIHJ1bnRpbWVUeXBlID0gbmV3IFJ1bnRpbWVUeXBlKGNmW2ldKTsKCQkJCXJ1bnRpbWVUeXBlcy5hZGQocnVudGltZVR5cGUpOwoJCQkJVHJhY2UudHJhY2UoVHJhY2UuRVhURU5TSU9OX1BPSU5ULCAiICBMb2FkZWQgcnVudGltZVR5cGU6ICIgKyBjZltpXS5nZXRBdHRyaWJ1dGUoImlkIikpOwoJCQl9IGNhdGNoIChUaHJvd2FibGUgdCkgewoJCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiICBDb3VsZCBub3QgbG9hZCBydW50aW1lVHlwZTogIiArIGNmW2ldLmdldEF0dHJpYnV0ZSgiaWQiKSwgdCk7CgkJCX0KCQl9CgkJU2VydmVyVXRpbC5zb3J0T3JkZXJlZExpc3QocnVudGltZVR5cGVzKTsKCQkKCQlUcmFjZS50cmFjZShUcmFjZS5FWFRFTlNJT05fUE9JTlQsICItPC0gRG9uZSBsb2FkaW5nIC5ydW50aW1lVHlwZXMgZXh0ZW5zaW9uIHBvaW50IC08LSIpOwoJfQoJCgkvKioKCSAqIExvYWQgdGhlIHJ1bnRpbWUgbG9jYXRvcnMuCgkgKi8KCXByaXZhdGUgc3RhdGljIHZvaWQgbG9hZFJ1bnRpbWVMb2NhdG9ycygpIHsKCQlUcmFjZS50cmFjZShUcmFjZS5FWFRFTlNJT05fUE9JTlQsICItPi0gTG9hZGluZyAucnVudGltZUxvY2F0b3JzIGV4dGVuc2lvbiBwb2ludCAtPi0iKTsKCQlJRXh0ZW5zaW9uUmVnaXN0cnkgcmVnaXN0cnkgPSBQbGF0Zm9ybS5nZXRFeHRlbnNpb25SZWdpc3RyeSgpOwoJCUlDb25maWd1cmF0aW9uRWxlbWVudFtdIGNmID0gcmVnaXN0cnkuZ2V0Q29uZmlndXJhdGlvbkVsZW1lbnRzRm9yKFNlcnZlckNvcmUuUExVR0lOX0lELCAicnVudGltZUxvY2F0b3JzIik7CgoJCWludCBzaXplID0gY2YubGVuZ3RoOwoJCXJ1bnRpbWVMb2NhdG9ycyA9IG5ldyBBcnJheUxpc3Qoc2l6ZSk7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJdHJ5IHsKCQkJCVJ1bnRpbWVMb2NhdG9yIHJ1bnRpbWVMb2NhdG9yID0gbmV3IFJ1bnRpbWVMb2NhdG9yKGNmW2ldKTsKCQkJCXJ1bnRpbWVMb2NhdG9ycy5hZGQocnVudGltZUxvY2F0b3IpOwoJCQkJVHJhY2UudHJhY2UoVHJhY2UuRVhURU5TSU9OX1BPSU5ULCAiICBMb2FkZWQgcnVudGltZUxvY2F0b3I6ICIgKyBjZltpXS5nZXRBdHRyaWJ1dGUoImlkIikpOwoJCQl9IGNhdGNoIChUaHJvd2FibGUgdCkgewoJCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiICBDb3VsZCBub3QgbG9hZCBydW50aW1lTG9jYXRvcjogIiArIGNmW2ldLmdldEF0dHJpYnV0ZSgiaWQiKSwgdCk7CgkJCX0KCQl9CgkJCgkJVHJhY2UudHJhY2UoVHJhY2UuRVhURU5TSU9OX1BPSU5ULCAiLTwtIERvbmUgbG9hZGluZyAucnVudGltZUxvY2F0b3JzIGV4dGVuc2lvbiBwb2ludCAtPC0iKTsKCX0KCQoJLyoqCgkgKiBMb2FkIHRoZSBydW50aW1lIHRhcmdldCBsaXN0ZW5lcnMuCgkgKi8KCXByaXZhdGUgc3RhdGljIHZvaWQgbG9hZFJ1bnRpbWVUYXJnZXRIYW5kbGVycygpIHsKCQlUcmFjZS50cmFjZShUcmFjZS5FWFRFTlNJT05fUE9JTlQsICItPi0gTG9hZGluZyAucnVudGltZVRhcmdldEhhbmRsZXJzIGV4dGVuc2lvbiBwb2ludCAtPi0iKTsKCQlJRXh0ZW5zaW9uUmVnaXN0cnkgcmVnaXN0cnkgPSBQbGF0Zm9ybS5nZXRFeHRlbnNpb25SZWdpc3RyeSgpOwoJCUlDb25maWd1cmF0aW9uRWxlbWVudFtdIGNmID0gcmVnaXN0cnkuZ2V0Q29uZmlndXJhdGlvbkVsZW1lbnRzRm9yKFNlcnZlckNvcmUuUExVR0lOX0lELCAicnVudGltZVRhcmdldEhhbmRsZXJzIik7CgoJCWludCBzaXplID0gY2YubGVuZ3RoOwoJCXJ1bnRpbWVUYXJnZXRIYW5kbGVycyA9IG5ldyBBcnJheUxpc3Qoc2l6ZSk7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJdHJ5IHsKCQkJCVJ1bnRpbWVUYXJnZXRIYW5kbGVyIHJ1bnRpbWVUYXJnZXRMaXN0ZW5lciA9IG5ldyBSdW50aW1lVGFyZ2V0SGFuZGxlcihjZltpXSk7CgkJCQlydW50aW1lVGFyZ2V0SGFuZGxlcnMuYWRkKHJ1bnRpbWVUYXJnZXRMaXN0ZW5lcik7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5FWFRFTlNJT05fUE9JTlQsICIgIExvYWRlZCBydW50aW1lVGFyZ2V0SGFuZGxlcjogIiArIGNmW2ldLmdldEF0dHJpYnV0ZSgiaWQiKSk7CgkJCX0gY2F0Y2ggKFRocm93YWJsZSB0KSB7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICIgIENvdWxkIG5vdCBsb2FkIHJ1bnRpbWVUYXJnZXRIYW5kbGVyOiAiICsgY2ZbaV0uZ2V0QXR0cmlidXRlKCJpZCIpLCB0KTsKCQkJfQoJCX0KCQlTZXJ2ZXJVdGlsLnNvcnRPcmRlcmVkTGlzdChydW50aW1lVGFyZ2V0SGFuZGxlcnMpOwoJCQoJCVRyYWNlLnRyYWNlKFRyYWNlLkVYVEVOU0lPTl9QT0lOVCwgIi08LSBEb25lIGxvYWRpbmcgLnJ1bnRpbWVUYXJnZXRIYW5kbGVycyBleHRlbnNpb24gcG9pbnQgLTwtIik7Cgl9CgoJLyoqCgkgKiBMb2FkIHRoZSBzZXJ2ZXIgdHlwZXMuCgkgKi8KCXByaXZhdGUgc3RhdGljIHZvaWQgbG9hZFNlcnZlclR5cGVzKCkgewoJCVRyYWNlLnRyYWNlKFRyYWNlLkVYVEVOU0lPTl9QT0lOVCwgIi0+LSBMb2FkaW5nIC5zZXJ2ZXJUeXBlcyBleHRlbnNpb24gcG9pbnQgLT4tIik7CgkJSUV4dGVuc2lvblJlZ2lzdHJ5IHJlZ2lzdHJ5ID0gUGxhdGZvcm0uZ2V0RXh0ZW5zaW9uUmVnaXN0cnkoKTsKCQlJQ29uZmlndXJhdGlvbkVsZW1lbnRbXSBjZiA9IHJlZ2lzdHJ5LmdldENvbmZpZ3VyYXRpb25FbGVtZW50c0ZvcihTZXJ2ZXJDb3JlLlBMVUdJTl9JRCwgInNlcnZlclR5cGVzIik7CgoJCWludCBzaXplID0gY2YubGVuZ3RoOwoJCXNlcnZlclR5cGVzID0gbmV3IEFycmF5TGlzdChzaXplKTsKCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQl0cnkgewoJCQkJU2VydmVyVHlwZSBzZXJ2ZXJUeXBlID0gbmV3IFNlcnZlclR5cGUoY2ZbaV0pOwoJCQkJc2VydmVyVHlwZXMuYWRkKHNlcnZlclR5cGUpOwoJCQkJVHJhY2UudHJhY2UoVHJhY2UuRVhURU5TSU9OX1BPSU5ULCAiICBMb2FkZWQgc2VydmVyVHlwZTogIiArIGNmW2ldLmdldEF0dHJpYnV0ZSgiaWQiKSk7CgkJCX0gY2F0Y2ggKFRocm93YWJsZSB0KSB7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICIgIENvdWxkIG5vdCBsb2FkIHNlcnZlclR5cGU6ICIgKyBjZltpXS5nZXRBdHRyaWJ1dGUoImlkIiksIHQpOwoJCQl9CgkJfQoJCVNlcnZlclV0aWwuc29ydE9yZGVyZWRMaXN0KHNlcnZlclR5cGVzKTsKCQkKCQlUcmFjZS50cmFjZShUcmFjZS5FWFRFTlNJT05fUE9JTlQsICItPC0gRG9uZSBsb2FkaW5nIC5zZXJ2ZXJUeXBlcyBleHRlbnNpb24gcG9pbnQgLTwtIik7Cgl9CgoJLyoqCgkgKiBMb2FkIHRoZSBzZXJ2ZXIgY29uZmlndXJhdGlvbiB0eXBlcy4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgdm9pZCBsb2FkU2VydmVyQ29uZmlndXJhdGlvblR5cGVzKCkgewoJCVRyYWNlLnRyYWNlKFRyYWNlLkVYVEVOU0lPTl9QT0lOVCwgIi0+LSBMb2FkaW5nIC5zZXJ2ZXJDb25maWd1cmF0aW9uVHlwZXMgZXh0ZW5zaW9uIHBvaW50IC0+LSIpOwoJCUlFeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSA9IFBsYXRmb3JtLmdldEV4dGVuc2lvblJlZ2lzdHJ5KCk7CgkJSUNvbmZpZ3VyYXRpb25FbGVtZW50W10gY2YgPSByZWdpc3RyeS5nZXRDb25maWd1cmF0aW9uRWxlbWVudHNGb3IoU2VydmVyQ29yZS5QTFVHSU5fSUQsICJzZXJ2ZXJDb25maWd1cmF0aW9uVHlwZXMiKTsKCgkJaW50IHNpemUgPSBjZi5sZW5ndGg7CgkJc2VydmVyQ29uZmlndXJhdGlvblR5cGVzID0gbmV3IEFycmF5TGlzdChzaXplKTsKCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQl0cnkgewoJCQkJU2VydmVyQ29uZmlndXJhdGlvblR5cGUgc2VydmVyQ29uZmlndXJhdGlvblR5cGUgPSBuZXcgU2VydmVyQ29uZmlndXJhdGlvblR5cGUoY2ZbaV0pOwoJCQkJc2VydmVyQ29uZmlndXJhdGlvblR5cGVzLmFkZChzZXJ2ZXJDb25maWd1cmF0aW9uVHlwZSk7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5FWFRFTlNJT05fUE9JTlQsICIgIExvYWRlZCBzZXJ2ZXJDb25maWd1cmF0aW9uVHlwZTogIiArIGNmW2ldLmdldEF0dHJpYnV0ZSgiaWQiKSk7CgkJCX0gY2F0Y2ggKFRocm93YWJsZSB0KSB7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICIgIENvdWxkIG5vdCBsb2FkIHNlcnZlckNvbmZpZ3VyYXRpb25UeXBlOiAiICsgY2ZbaV0uZ2V0QXR0cmlidXRlKCJpZCIpLCB0KTsKCQkJfQoJCX0KCQlTZXJ2ZXJVdGlsLnNvcnRPcmRlcmVkTGlzdChzZXJ2ZXJDb25maWd1cmF0aW9uVHlwZXMpOwoJCQoJCVRyYWNlLnRyYWNlKFRyYWNlLkVYVEVOU0lPTl9QT0lOVCwgIi08LSBEb25lIGxvYWRpbmcgLnNlcnZlckNvbmZpZ3VyYXRpb25UeXBlcyBleHRlbnNpb24gcG9pbnQgLTwtIik7Cgl9CgoJLyoqCgkgKiBMb2FkIHRoZSBwdWJsaXNoIG1hbmFnZXIgZXh0ZW5zaW9uIHBvaW50LgoJICovCglwcml2YXRlIHN0YXRpYyB2b2lkIGxvYWRQdWJsaXNoTWFuYWdlcnMoKSB7CgkJVHJhY2UudHJhY2UoVHJhY2UuRVhURU5TSU9OX1BPSU5ULCAiLT4tIExvYWRpbmcgLnB1Ymxpc2ggZXh0ZW5zaW9uIHBvaW50IC0+LSIpOwoJCUlFeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSA9IFBsYXRmb3JtLmdldEV4dGVuc2lvblJlZ2lzdHJ5KCk7CgkJSUNvbmZpZ3VyYXRpb25FbGVtZW50W10gY2YgPSByZWdpc3RyeS5nZXRDb25maWd1cmF0aW9uRWxlbWVudHNGb3IoU2VydmVyQ29yZS5QTFVHSU5fSUQsICJwdWJsaXNoIik7CgoJCWludCBzaXplID0gY2YubGVuZ3RoOwoJCXB1Ymxpc2hNYW5hZ2VycyA9IG5ldyBIYXNoTWFwKHNpemUpOwoJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCXRyeSB7CgkJCQlTdHJpbmcgaWQgPSBjZltpXS5nZXRBdHRyaWJ1dGUoImlkIik7CgkJCQlJUHVibGlzaE1hbmFnZXIgcHVibGlzaGVyID0gbmV3IFB1Ymxpc2hNYW5hZ2VyKGNmW2ldKTsKCQkJCXB1Ymxpc2hNYW5hZ2Vycy5wdXQoaWQsIHB1Ymxpc2hlcik7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5FWFRFTlNJT05fUE9JTlQsICIgIExvYWRlZCBwdWJsaXNoIG1hbmFnZXI6ICIgKyBpZCk7CgkJCX0gY2F0Y2ggKFRocm93YWJsZSB0KSB7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICIgIENvdWxkIG5vdCBsb2FkIHB1Ymxpc2ggbWFuYWdlcjogIiArIGNmW2ldLmdldEF0dHJpYnV0ZSgiY2xhc3MiKSwgdCk7CgkJCX0KCQl9CgkJVHJhY2UudHJhY2UoVHJhY2UuRVhURU5TSU9OX1BPSU5ULCAiLTwtIERvbmUgbG9hZGluZyAucHVibGlzaGVyIGV4dGVuc2lvbiBwb2ludCAtPC0iKTsKCX0KCgkvKioKCSAqIExvYWQgdGhlIG1vZHVsZSBmYWN0b3JpZXMgZXh0ZW5zaW9uIHBvaW50LgoJICovCglwcml2YXRlIHN0YXRpYyB2b2lkIGxvYWRNb2R1bGVGYWN0b3JpZXMoKSB7CgkJVHJhY2UudHJhY2UoVHJhY2UuRVhURU5TSU9OX1BPSU5ULCAiLT4tIExvYWRpbmcgLm1vZHVsZUZhY3RvcmllcyBleHRlbnNpb24gcG9pbnQgLT4tIik7CgkJSUV4dGVuc2lvblJlZ2lzdHJ5IHJlZ2lzdHJ5ID0gUGxhdGZvcm0uZ2V0RXh0ZW5zaW9uUmVnaXN0cnkoKTsKCQlJQ29uZmlndXJhdGlvbkVsZW1lbnRbXSBjZiA9IHJlZ2lzdHJ5LmdldENvbmZpZ3VyYXRpb25FbGVtZW50c0ZvcihTZXJ2ZXJDb3JlLlBMVUdJTl9JRCwgIm1vZHVsZUZhY3RvcmllcyIpOwoKCQlpbnQgc2l6ZSA9IGNmLmxlbmd0aDsKCQltb2R1bGVGYWN0b3JpZXMgPSBuZXcgQXJyYXlMaXN0KHNpemUpOwoJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCXRyeSB7CgkJCQltb2R1bGVGYWN0b3JpZXMuYWRkKG5ldyBNb2R1bGVGYWN0b3J5KGNmW2ldKSk7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5FWFRFTlNJT05fUE9JTlQsICIgIExvYWRlZCBtb2R1bGVGYWN0b3JpZXM6ICIgKyBjZltpXS5nZXRBdHRyaWJ1dGUoImlkIikpOwoJCQl9IGNhdGNoIChUaHJvd2FibGUgdCkgewoJCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiICBDb3VsZCBub3QgbG9hZCBtb2R1bGVGYWN0b3JpZXM6ICIgKyBjZltpXS5nZXRBdHRyaWJ1dGUoImlkIiksIHQpOwoJCQl9CgkJfQoJCVNlcnZlclV0aWwuc29ydE9yZGVyZWRMaXN0KG1vZHVsZUZhY3Rvcmllcyk7CgkJVHJhY2UudHJhY2UoVHJhY2UuRVhURU5TSU9OX1BPSU5ULCAiLTwtIERvbmUgbG9hZGluZyAubW9kdWxlRmFjdG9yaWVzIGV4dGVuc2lvbiBwb2ludCAtPC0iKTsKCX0KCgkvKioKCSAqIExvYWQgdGhlIG1vZHVsZSBvYmplY3QgYWRhcHRlcnMgZXh0ZW5zaW9uIHBvaW50LgoJICovCglwcml2YXRlIHN0YXRpYyB2b2lkIGxvYWRNb2R1bGVPYmplY3RBZGFwdGVycygpIHsKCQlUcmFjZS50cmFjZShUcmFjZS5FWFRFTlNJT05fUE9JTlQsICItPi0gTG9hZGluZyAubW9kdWxlT2JqZWN0QWRhcHRlcnMgZXh0ZW5zaW9uIHBvaW50IC0+LSIpOwoJCUlFeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSA9IFBsYXRmb3JtLmdldEV4dGVuc2lvblJlZ2lzdHJ5KCk7CgkJSUNvbmZpZ3VyYXRpb25FbGVtZW50W10gY2YgPSByZWdpc3RyeS5nZXRDb25maWd1cmF0aW9uRWxlbWVudHNGb3IoU2VydmVyQ29yZS5QTFVHSU5fSUQsICJtb2R1bGVPYmplY3RBZGFwdGVycyIpOwoKCQlpbnQgc2l6ZSA9IGNmLmxlbmd0aDsKCQltb2R1bGVPYmplY3RBZGFwdGVycyA9IG5ldyBBcnJheUxpc3Qoc2l6ZSk7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJdHJ5IHsKCQkJCW1vZHVsZU9iamVjdEFkYXB0ZXJzLmFkZChuZXcgTW9kdWxlT2JqZWN0QWRhcHRlcihjZltpXSkpOwoJCQkJVHJhY2UudHJhY2UoVHJhY2UuRVhURU5TSU9OX1BPSU5ULCAiICBMb2FkZWQgbW9kdWxlT2JqZWN0QWRhcHRlcjogIiArIGNmW2ldLmdldEF0dHJpYnV0ZSgiaWQiKSk7CgkJCX0gY2F0Y2ggKFRocm93YWJsZSB0KSB7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICIgIENvdWxkIG5vdCBsb2FkIG1vZHVsZU9iamVjdEFkYXB0ZXI6ICIgKyBjZltpXS5nZXRBdHRyaWJ1dGUoImlkIiksIHQpOwoJCQl9CgkJfQoJCVRyYWNlLnRyYWNlKFRyYWNlLkVYVEVOU0lPTl9QT0lOVCwgIi08LSBEb25lIGxvYWRpbmcgLm1vZHVsZU9iamVjdEFkYXB0ZXJzIGV4dGVuc2lvbiBwb2ludCAtPC0iKTsKCX0KCQoJLyoqCgkgKiBMb2FkIHRoZSBsYXVuY2hhYmxlIGFkYXB0ZXJzIGV4dGVuc2lvbiBwb2ludC4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgdm9pZCBsb2FkTGF1bmNoYWJsZUFkYXB0ZXJzKCkgewoJCVRyYWNlLnRyYWNlKFRyYWNlLkVYVEVOU0lPTl9QT0lOVCwgIi0+LSBMb2FkaW5nIC5sYXVuY2hhYmxlQWRhcHRlcnMgZXh0ZW5zaW9uIHBvaW50IC0+LSIpOwoJCUlFeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSA9IFBsYXRmb3JtLmdldEV4dGVuc2lvblJlZ2lzdHJ5KCk7CgkJSUNvbmZpZ3VyYXRpb25FbGVtZW50W10gY2YgPSByZWdpc3RyeS5nZXRDb25maWd1cmF0aW9uRWxlbWVudHNGb3IoU2VydmVyQ29yZS5QTFVHSU5fSUQsICJsYXVuY2hhYmxlQWRhcHRlcnMiKTsKCgkJaW50IHNpemUgPSBjZi5sZW5ndGg7CgkJbGF1bmNoYWJsZUFkYXB0ZXJzID0gbmV3IEFycmF5TGlzdChzaXplKTsKCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQl0cnkgewoJCQkJbGF1bmNoYWJsZUFkYXB0ZXJzLmFkZChuZXcgTGF1bmNoYWJsZUFkYXB0ZXIoY2ZbaV0pKTsKCQkJCVRyYWNlLnRyYWNlKFRyYWNlLkVYVEVOU0lPTl9QT0lOVCwgIiAgTG9hZGVkIGxhdW5jaGFibGVBZGFwdGVyOiAiICsgY2ZbaV0uZ2V0QXR0cmlidXRlKCJpZCIpKTsKCQkJfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKCQkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIiAgQ291bGQgbm90IGxvYWQgbGF1bmNoYWJsZUFkYXB0ZXI6ICIgKyBjZltpXS5nZXRBdHRyaWJ1dGUoImlkIiksIHQpOwoJCQl9CgkJfQoJCVRyYWNlLnRyYWNlKFRyYWNlLkVYVEVOU0lPTl9QT0lOVCwgIi08LSBEb25lIGxvYWRpbmcgLmxhdW5jaGFibGVBZGFwdGVycyBleHRlbnNpb24gcG9pbnQgLTwtIik7Cgl9CgoJLyoqCgkgKiBMb2FkIHRoZSBsYXVuY2hhYmxlIGNsaWVudCBleHRlbnNpb24gcG9pbnQuCgkgKi8KCXByaXZhdGUgc3RhdGljIHZvaWQgbG9hZExhdW5jaGFibGVDbGllbnRzKCkgewoJCVRyYWNlLnRyYWNlKFRyYWNlLkVYVEVOU0lPTl9QT0lOVCwgIi0+LSBMb2FkaW5nIC5jbGllbnRzIGV4dGVuc2lvbiBwb2ludCAtPi0iKTsKCQlJRXh0ZW5zaW9uUmVnaXN0cnkgcmVnaXN0cnkgPSBQbGF0Zm9ybS5nZXRFeHRlbnNpb25SZWdpc3RyeSgpOwoJCUlDb25maWd1cmF0aW9uRWxlbWVudFtdIGNmID0gcmVnaXN0cnkuZ2V0Q29uZmlndXJhdGlvbkVsZW1lbnRzRm9yKFNlcnZlckNvcmUuUExVR0lOX0lELCAiY2xpZW50cyIpOwoKCQlpbnQgc2l6ZSA9IGNmLmxlbmd0aDsKCQlsYXVuY2hhYmxlQ2xpZW50cyA9IG5ldyBBcnJheUxpc3Qoc2l6ZSk7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJdHJ5IHsKCQkJCWxhdW5jaGFibGVDbGllbnRzLmFkZChuZXcgQ2xpZW50KGNmW2ldKSk7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5FWFRFTlNJT05fUE9JTlQsICIgIExvYWRlZCBjbGllbnRzOiAiICsgY2ZbaV0uZ2V0QXR0cmlidXRlKCJpZCIpKTsKCQkJfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKCQkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIiAgQ291bGQgbm90IGxvYWQgY2xpZW50czogIiArIGNmW2ldLmdldEF0dHJpYnV0ZSgiaWQiKSwgdCk7CgkJCX0KCQl9CgkJVHJhY2UudHJhY2UoVHJhY2UuRVhURU5TSU9OX1BPSU5ULCAiLTwtIERvbmUgbG9hZGluZyAuY2xpZW50cyBleHRlbnNpb24gcG9pbnQgLTwtIik7Cgl9CgkKCS8qKgoJICogTG9hZCB0aGUgbW9kdWxlIHRhc2sgZXh0ZW5zaW9uIHBvaW50LgoJICovCglwcml2YXRlIHN0YXRpYyB2b2lkIGxvYWRNb2R1bGVUYXNrcygpIHsKCQlUcmFjZS50cmFjZShUcmFjZS5FWFRFTlNJT05fUE9JTlQsICItPi0gTG9hZGluZyAubW9kdWxlVGFza3MgZXh0ZW5zaW9uIHBvaW50IC0+LSIpOwoJCUlFeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSA9IFBsYXRmb3JtLmdldEV4dGVuc2lvblJlZ2lzdHJ5KCk7CgkJSUNvbmZpZ3VyYXRpb25FbGVtZW50W10gY2YgPSByZWdpc3RyeS5nZXRDb25maWd1cmF0aW9uRWxlbWVudHNGb3IoU2VydmVyQ29yZS5QTFVHSU5fSUQsICJtb2R1bGVUYXNrcyIpOwoKCQlpbnQgc2l6ZSA9IGNmLmxlbmd0aDsKCQltb2R1bGVUYXNrcyA9IG5ldyBBcnJheUxpc3Qoc2l6ZSk7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJdHJ5IHsKCQkJCW1vZHVsZVRhc2tzLmFkZChuZXcgTW9kdWxlVGFzayhjZltpXSkpOwoJCQkJVHJhY2UudHJhY2UoVHJhY2UuRVhURU5TSU9OX1BPSU5ULCAiICBMb2FkZWQgbW9kdWxlVGFzazogIiArIGNmW2ldLmdldEF0dHJpYnV0ZSgiaWQiKSk7CgkJCX0gY2F0Y2ggKFRocm93YWJsZSB0KSB7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICIgIENvdWxkIG5vdCBsb2FkIG1vZHVsZVRhc2s6ICIgKyBjZltpXS5nZXRBdHRyaWJ1dGUoImlkIiksIHQpOwoJCQl9CgkJfQoJCVNlcnZlclV0aWwuc29ydE9yZGVyZWRMaXN0KG1vZHVsZVRhc2tzKTsKCQlUcmFjZS50cmFjZShUcmFjZS5FWFRFTlNJT05fUE9JTlQsICItPC0gRG9uZSBsb2FkaW5nIC5tb2R1bGVUYXNrcyBleHRlbnNpb24gcG9pbnQgLTwtIik7Cgl9CgoJLyoqCgkgKiBMb2FkIHRoZSBzZXJ2ZXIgdGFzayBleHRlbnNpb24gcG9pbnQuCgkgKi8KCXByaXZhdGUgc3RhdGljIHZvaWQgbG9hZFNlcnZlclRhc2tzKCkgewoJCVRyYWNlLnRyYWNlKFRyYWNlLkVYVEVOU0lPTl9QT0lOVCwgIi0+LSBMb2FkaW5nIC5zZXJ2ZXJUYXNrcyBleHRlbnNpb24gcG9pbnQgLT4tIik7CgkJSUV4dGVuc2lvblJlZ2lzdHJ5IHJlZ2lzdHJ5ID0gUGxhdGZvcm0uZ2V0RXh0ZW5zaW9uUmVnaXN0cnkoKTsKCQlJQ29uZmlndXJhdGlvbkVsZW1lbnRbXSBjZiA9IHJlZ2lzdHJ5LmdldENvbmZpZ3VyYXRpb25FbGVtZW50c0ZvcihTZXJ2ZXJDb3JlLlBMVUdJTl9JRCwgInNlcnZlclRhc2tzIik7CgoJCWludCBzaXplID0gY2YubGVuZ3RoOwoJCXNlcnZlclRhc2tzID0gbmV3IEFycmF5TGlzdChzaXplKTsKCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQl0cnkgewoJCQkJc2VydmVyVGFza3MuYWRkKG5ldyBTZXJ2ZXJUYXNrKGNmW2ldKSk7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5FWFRFTlNJT05fUE9JTlQsICIgIExvYWRlZCBzZXJ2ZXJUYXNrOiAiICsgY2ZbaV0uZ2V0QXR0cmlidXRlKCJpZCIpKTsKCQkJfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKCQkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIiAgQ291bGQgbm90IGxvYWQgc2VydmVyVGFzazogIiArIGNmW2ldLmdldEF0dHJpYnV0ZSgiaWQiKSwgdCk7CgkJCX0KCQl9CgkJCgkJU2VydmVyVXRpbC5zb3J0T3JkZXJlZExpc3Qoc2VydmVyVGFza3MpOwoJCVRyYWNlLnRyYWNlKFRyYWNlLkVYVEVOU0lPTl9QT0lOVCwgIi08LSBEb25lIGxvYWRpbmcgLnNlcnZlclRhc2tzIGV4dGVuc2lvbiBwb2ludCAtPC0iKTsKCX0KCgkvKioKCSAqIExvYWQgdGhlIHNlcnZlciBtb25pdG9yIGV4dGVuc2lvbiBwb2ludC4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgdm9pZCBsb2FkU2VydmVyTW9uaXRvcnMoKSB7CgkJVHJhY2UudHJhY2UoVHJhY2UuRVhURU5TSU9OX1BPSU5ULCAiLT4tIExvYWRpbmcgLnNlcnZlck1vbml0b3JzIGV4dGVuc2lvbiBwb2ludCAtPi0iKTsKCQlJRXh0ZW5zaW9uUmVnaXN0cnkgcmVnaXN0cnkgPSBQbGF0Zm9ybS5nZXRFeHRlbnNpb25SZWdpc3RyeSgpOwoJCUlDb25maWd1cmF0aW9uRWxlbWVudFtdIGNmID0gcmVnaXN0cnkuZ2V0Q29uZmlndXJhdGlvbkVsZW1lbnRzRm9yKFNlcnZlckNvcmUuUExVR0lOX0lELCAic2VydmVyTW9uaXRvcnMiKTsKCgkJaW50IHNpemUgPSBjZi5sZW5ndGg7CgkJbW9uaXRvcnMgPSBuZXcgQXJyYXlMaXN0KHNpemUpOwoJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCXRyeSB7CgkJCQltb25pdG9ycy5hZGQobmV3IFNlcnZlck1vbml0b3IoY2ZbaV0pKTsKCQkJCVRyYWNlLnRyYWNlKFRyYWNlLkVYVEVOU0lPTl9QT0lOVCwgIiAgTG9hZGVkIHNlcnZlck1vbml0b3I6ICIgKyBjZltpXS5nZXRBdHRyaWJ1dGUoImlkIikpOwoJCQl9IGNhdGNoIChUaHJvd2FibGUgdCkgewoJCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiICBDb3VsZCBub3QgbG9hZCBzZXJ2ZXJNb25pdG9yOiAiICsgY2ZbaV0uZ2V0QXR0cmlidXRlKCJpZCIpLCB0KTsKCQkJfQoJCX0KCQoJCVRyYWNlLnRyYWNlKFRyYWNlLkVYVEVOU0lPTl9QT0lOVCwgIi08LSBEb25lIGxvYWRpbmcgLnNlcnZlck1vbml0b3JzIGV4dGVuc2lvbiBwb2ludCAtPC0iKTsKCX0KfQo=