LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA0IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCqAqCiAqIENvbnRyaWJ1dG9yczoKICogICAgIElCTSBDb3Jwb3JhdGlvbiAtIEluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KcGFja2FnZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuaW50ZXJuYWw7CgppbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKCmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy4qOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLio7CgppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLio7Ci8qKgogKiBIZWxwZXIgY2xhc3MgdGhhdCBzdG9yZXMgcHJlZmVyZW5jZSBpbmZvcm1hdGlvbiBmb3IgdGhlIHNlcnZlciB0b29scy4KICovCnB1YmxpYyBjbGFzcyBQcm9qZWN0UHJvcGVydGllcyBpbXBsZW1lbnRzIElQcm9qZWN0UHJvcGVydGllcyB7Cglwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUFJPSkVDVF9QUkVGRVJFTkNFX0ZJTEUgPSAiLnJ1bnRpbWUiOwoJCglwcm90ZWN0ZWQgSVByb2plY3QgcHJvamVjdDsKCQoJcHJvdGVjdGVkIFN0cmluZyBzZXJ2ZXJJZDsKCXByb3RlY3RlZCBTdHJpbmcgcnVudGltZUlkOwoJcHJvdGVjdGVkIGJvb2xlYW4gc2VydmVyUHJvamVjdCA9IGZhbHNlOwoJCgkvLyBwcm9qZWN0IHByb3BlcnRpZXMgbGlzdGVuZXJzCglwcm90ZWN0ZWQgdHJhbnNpZW50IExpc3QgbGlzdGVuZXJzOwoKCS8qKgoJICogUHJvamVjdFByb3BlcnRpZXMgY29uc3RydWN0b3IgY29tbWVudC4KCSAqLwoJcHVibGljIFByb2plY3RQcm9wZXJ0aWVzKElQcm9qZWN0IHByb2plY3QpIHsKCQlzdXBlcigpOwoJCXRoaXMucHJvamVjdCA9IHByb2plY3Q7Cgl9CgkKCS8qKgoJICogTG9hZCB0aGUgcHJlZmVyZW5jZXMuCgkgKi8KCXByaXZhdGUgdm9pZCBsb2FkUHJlZmVyZW5jZXMoKSB7CgkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiTG9hZGluZyBwcm9qZWN0IHByZWZlcmVuY2VzOiAiICsgcHJvamVjdCk7CgkJCgkJSW5wdXRTdHJlYW0gaW4gPSBudWxsOwoJCXRyeSB7CgkJCUlNZW1lbnRvIG1lbWVudG8gPSBudWxsOwoJCQlpZiAoIXByb2plY3QuZXhpc3RzKCkgfHwgIXByb2plY3QuaXNPcGVuKCkpCgkJCQlyZXR1cm47CgkJCUlGaWxlIGZpbGUgPSBwcm9qZWN0LmdldEZpbGUoUFJPSkVDVF9QUkVGRVJFTkNFX0ZJTEUpOwoJCQlpZiAoZmlsZSAhPSBudWxsICYmIGZpbGUuZXhpc3RzKCkpIHsKCQkJCWluID0gZmlsZS5nZXRDb250ZW50cygpOwoJCQkJbWVtZW50byA9IFhNTE1lbWVudG8ubG9hZE1lbWVudG8oaW4pOwoJCQl9CgkJCQoJCQlpZiAobWVtZW50byA9PSBudWxsKQoJCQkJcmV0dXJuOwoJCQkKCQkJc2VydmVySWQgPSBtZW1lbnRvLmdldFN0cmluZygic2VydmVyLWlkIik7CgkJCXJ1bnRpbWVJZCA9IG1lbWVudG8uZ2V0U3RyaW5nKCJydW50aW1lLWlkIik7CgkJCVN0cmluZyBzID0gbWVtZW50by5nZXRTdHJpbmcoInNlcnZlcnMiKTsKCQkJaWYgKHMgIT0gbnVsbCAmJiAidHJ1ZSIuZXF1YWxzKHMpKQoJCQkJc2VydmVyUHJvamVjdCA9IHRydWU7CgkJCWVsc2UKCQkJCXNlcnZlclByb2plY3QgPSBmYWxzZTsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQlUcmFjZS50cmFjZSgiQ291bGQgbm90IGxvYWQgcHJlZmVyZW5jZXM6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CgkJfSBmaW5hbGx5IHsKCQkJdHJ5IHsKCQkJCWluLmNsb3NlKCk7CgkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCQkvLyBpZ25vcmUKCQkJfQoJCX0KCX0KCQoJcHJpdmF0ZSB2b2lkIHNhdmVQcmVmZXJlbmNlcyhJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHRocm93cyBDb3JlRXhjZXB0aW9uIHsKCQlpZiAocHJvamVjdC5leGlzdHMoKSAmJiBwcm9qZWN0LmlzT3BlbigpKSB7CgkJCUlGaWxlIGZpbGUgPSBwcm9qZWN0LmdldEZpbGUoUFJPSkVDVF9QUkVGRVJFTkNFX0ZJTEUpOwoJCQkKCQkJaWYgKGZpbGUuZXhpc3RzKCkgJiYgZmlsZS5pc1JlYWRPbmx5KCkpIHsKCQkJCUlTdGF0dXMgc3RhdHVzID0gUmVzb3VyY2VzUGx1Z2luLmdldFdvcmtzcGFjZSgpLnZhbGlkYXRlRWRpdChuZXcgSUZpbGVbXSB7IGZpbGUgfSwgbnVsbCk7CgkJCQlpZiAoc3RhdHVzLmdldFNldmVyaXR5KCkgPT0gSVN0YXR1cy5FUlJPUikKCQkJCQkvLyBkaWRuJ3Qgd29yayBvciBub3QgdW5kZXIgc291cmNlIGNvbnRyb2wKCQkJCQl0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbihzdGF0dXMpOwoJCQl9CgkJCQoJCQlJbnB1dFN0cmVhbSBpbiA9IG51bGw7CgkJCXRyeSB7CgkJCQlYTUxNZW1lbnRvIG1lbWVudG8gPSBYTUxNZW1lbnRvLmNyZWF0ZVdyaXRlUm9vdCgicnVudGltZSIpOwoKCQkJCWlmIChydW50aW1lSWQgIT0gbnVsbCkKCQkJCQltZW1lbnRvLnB1dFN0cmluZygicnVudGltZS1pZCIsIHJ1bnRpbWVJZCk7CgkJCQlpZiAoc2VydmVySWQgIT0gbnVsbCkKCQkJCQltZW1lbnRvLnB1dFN0cmluZygic2VydmVyLWlkIiwgc2VydmVySWQpOwoJCQkJaWYgKHNlcnZlclByb2plY3QpCgkJCQkJbWVtZW50by5wdXRTdHJpbmcoInNlcnZlcnMiLCAidHJ1ZSIpOwoJCQkJZWxzZQoJCQkJCW1lbWVudG8ucHV0U3RyaW5nKCJzZXJ2ZXJzIiwgImZhbHNlIik7CgkJCQlpbiA9IG1lbWVudG8uZ2V0SW5wdXRTdHJlYW0oKTsKCQkJCQoJCQkJaWYgKGZpbGUuZXhpc3RzKCkpCgkJCQkJZmlsZS5zZXRDb250ZW50cyhpbiwgdHJ1ZSwgdHJ1ZSwgbW9uaXRvcik7CgkJCQllbHNlCgkJCQkJZmlsZS5jcmVhdGUoaW4sIHRydWUsIG1vbml0b3IpOwoJCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQkJdGhyb3cgbmV3IENvcmVFeGNlcHRpb24obmV3IFN0YXR1cyhJU3RhdHVzLkVSUk9SLCBTZXJ2ZXJQbHVnaW4uUExVR0lOX0lELCAwLCAiIiwgZSkpOwoJCQl9IGZpbmFsbHkgewoJCQkJdHJ5IHsKCQkJCQlpbi5jbG9zZSgpOwoJCQkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJCQkvLyBpZ25vcmUKCQkJCX0KCQkJfQoJCQlyZXR1cm47CgkJfQoJfQoKCS8qKgoJICogUmV0dXJucyB0aGUgcHJlZmVycmVkIHJ1bnRpbWUgc2VydmVyIGZvciB0aGUgcHJvamVjdC4gVGhpcyBtZXRob2QKCSAqIHJldHVybnMgbnVsbCBpZiB0aGUgc2VydmVyIHdhcyBuZXZlciBjaG9zZW4gb3IgZG9lcyBub3QgY3VycmVudGx5IGV4aXN0LiAoaWYgdGhlCgkgKiBzZXJ2ZXIgaXMgcmVjcmVhdGVkIG9yIHdhcyBpbiBhIGNsb3NlZCBwcm9qZWN0LCBldGMuIHRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuCgkgKiB0aGUgb3JpZ2luYWwgdmFsdWUgaWYgaXQgYmVjb21lcyBhdmFpbGFibGUgYWdhaW4pCgkgKgoJICogQHJldHVybiBzZXJ2ZXIgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklTZXJ2ZXIKCSAqLwoJcHVibGljIElTZXJ2ZXIgZ2V0RGVmYXVsdFNlcnZlcigpIHsKCQlsb2FkUHJlZmVyZW5jZXMoKTsKCgkJaWYgKHNlcnZlcklkID09IG51bGwgfHwgc2VydmVySWQubGVuZ3RoKCkgPT0gMCkKCQkJcmV0dXJuIG51bGw7CgkJCgkJSVNlcnZlciBzZXJ2ZXIgPSBTZXJ2ZXJDb3JlLmZpbmRTZXJ2ZXIoc2VydmVySWQpOwoJCS8qaWYgKHNlcnZlciAhPSBudWxsICYmIFNlcnZlclV0aWwuY29udGFpbnNNb2R1bGUoc2VydmVyLCBtb2R1bGUpKQoJCQlyZXR1cm4gc2VydmVyOwoJCWVsc2UKCQkJcmV0dXJuIG51bGw7Ki8KCQlyZXR1cm4gc2VydmVyOwoJfQoKCS8qKgoJICogU2V0cyB0aGUgcHJlZmVycmVkIHJ1bnRpbWUgc2VydmVyIGZvciB0aGUgcHJvamVjdC4KCSAqCgkgKiBAcGFyYW0gc2VydmVyIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5JU2VydmVyCgkgKi8KCXB1YmxpYyB2b2lkIHNldERlZmF1bHRTZXJ2ZXIoSVNlcnZlciBzZXJ2ZXIsIElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgdGhyb3dzIENvcmVFeGNlcHRpb24gewoJCWxvYWRQcmVmZXJlbmNlcygpOwoJCQoJCVN0cmluZyBuZXdTZXJ2ZXJJZCA9IG51bGw7CgkJaWYgKHNlcnZlciAhPSBudWxsKQoJCQluZXdTZXJ2ZXJJZCA9IHNlcnZlci5nZXRJZCgpOwoJCWlmIChzZXJ2ZXJJZCA9PSBudWxsICYmIG5ld1NlcnZlcklkID09IG51bGwpCgkJCXJldHVybjsKCQlpZiAoc2VydmVySWQgIT0gbnVsbCAmJiBzZXJ2ZXJJZC5lcXVhbHMobmV3U2VydmVySWQpKQoJCQlyZXR1cm47CgkJCgkJc2F2ZVByZWZlcmVuY2VzKG1vbml0b3IpOwoJCWZpcmVEZWZhdWx0U2VydmVyQ2hhbmdlZChzZXJ2ZXIpOwoJfQoJCglwcm90ZWN0ZWQgU3RyaW5nIGdldFJ1bnRpbWVUYXJnZXRJZCgpIHsKCQlsb2FkUHJlZmVyZW5jZXMoKTsKCQlyZXR1cm4gcnVudGltZUlkOwoJfQoJCglwcm90ZWN0ZWQgdm9pZCBzZXRSdW50aW1lVGFyZ2V0SWQoU3RyaW5nIG5ld1J1bnRpbWVJZCwgSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiB7CgkJbG9hZFByZWZlcmVuY2VzKCk7CgkJcnVudGltZUlkID0gbmV3UnVudGltZUlkOwoJCXNhdmVQcmVmZXJlbmNlcyhtb25pdG9yKTsKCX0KCgkvKioKCSAqIFJldHVybnMgdGhlIGN1cnJlbnQgcnVudGltZSB0YXJnZXQgdHlwZSBmb3IgdGhlIGdpdmVuIHByb2plY3QuCgkgKiAKCSAqIEByZXR1cm4KCSAqLwoJcHVibGljIElSdW50aW1lIGdldFJ1bnRpbWVUYXJnZXQoKSB7CgkJbG9hZFByZWZlcmVuY2VzKCk7CgkJaWYgKHJ1bnRpbWVJZCA9PSBudWxsKQoJCQlyZXR1cm4gbnVsbDsKCQlyZXR1cm4gU2VydmVyQ29yZS5maW5kUnVudGltZShydW50aW1lSWQpOwoJfQoKCS8qKgoJICogU2V0cyB0aGUgcnVudGltZSB0YXJnZXQgZm9yIHRoZSBwcm9qZWN0LgoJICogCgkgKiBAcGFyYW0gdGFyZ2V0CgkgKiBAcGFyYW0gbW9uaXRvcgoJICovCglwdWJsaWMgdm9pZCBzZXRSdW50aW1lVGFyZ2V0KElSdW50aW1lIHJ1bnRpbWUsIElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgdGhyb3dzIENvcmVFeGNlcHRpb24gewoJCWxvYWRQcmVmZXJlbmNlcygpOwoJCUlSdW50aW1lIG9sZFJ1bnRpbWUgPSBudWxsOwoJCWlmIChydW50aW1lSWQgIT0gbnVsbCkKCQkJb2xkUnVudGltZSA9IFNlcnZlckNvcmUuZmluZFJ1bnRpbWUocnVudGltZUlkKTsKCQlzZXRSdW50aW1lVGFyZ2V0KG9sZFJ1bnRpbWUsIHJ1bnRpbWUsIHRydWUsIG1vbml0b3IpOwoJfQoKCXByb3RlY3RlZCB2b2lkIHNldFJ1bnRpbWVUYXJnZXQoSVJ1bnRpbWUgb2xkUnVudGltZSwgSVJ1bnRpbWUgbmV3UnVudGltZSwgYm9vbGVhbiBzYXZlLCBJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHRocm93cyBDb3JlRXhjZXB0aW9uIHsKCQlUcmFjZS50cmFjZShUcmFjZS5SVU5USU1FX1RBUkdFVCwgInNldFJ1bnRpbWVUYXJnZXQgOiAiICsgb2xkUnVudGltZSArICIgLT4gIiArIG5ld1J1bnRpbWUpOwoJCQoJCWlmIChvbGRSdW50aW1lID09IG51bGwgJiYgbmV3UnVudGltZSA9PSBudWxsKQoJCQlyZXR1cm47CgkJaWYgKG9sZFJ1bnRpbWUgIT0gbnVsbCAmJiBvbGRSdW50aW1lLmVxdWFscyhuZXdSdW50aW1lKSkKCQkJcmV0dXJuOwoJCQoJCUlSdW50aW1lVGFyZ2V0SGFuZGxlcltdIGhhbmRsZXJzID0gU2VydmVyQ29yZS5nZXRSdW50aW1lVGFyZ2V0SGFuZGxlcnMoKTsKCQlpZiAoaGFuZGxlcnMgPT0gbnVsbCkKCQkJcmV0dXJuOwoJCgkJaW50IHNpemUgPSBoYW5kbGVycy5sZW5ndGg7CgkJLy8gcmVtb3ZlIG9sZCB0YXJnZXQKCQlpZiAob2xkUnVudGltZSAhPSBudWxsKSB7CgkJCUlSdW50aW1lVHlwZSBydW50aW1lVHlwZSA9IG9sZFJ1bnRpbWUuZ2V0UnVudGltZVR5cGUoKTsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCUlSdW50aW1lVGFyZ2V0SGFuZGxlciBoYW5kbGVyID0gaGFuZGxlcnNbaV07CgkJCQlsb25nIHRpbWUgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKCQkJCWJvb2xlYW4gc3VwcG9ydHMgPSBoYW5kbGVyLnN1cHBvcnRzUnVudGltZVR5cGUocnVudGltZVR5cGUpOwoJCQkJVHJhY2UudHJhY2UoVHJhY2UuUlVOVElNRV9UQVJHRVQsICIgIDwgIiArIGhhbmRsZXIgKyAiICIgKyBzdXBwb3J0cyk7CgkJCQlpZiAoc3VwcG9ydHMpCgkJCQkJaGFuZGxlci5yZW1vdmVSdW50aW1lVGFyZ2V0KHByb2plY3QsIG9sZFJ1bnRpbWUsIG1vbml0b3IpOwoJCQkJVHJhY2UudHJhY2UoVHJhY2UuUEVSRk9STUFOQ0UsICJSdW50aW1lIHRhcmdldDogPCIgKyAoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSB0aW1lKSArICI+ICIgKyBoYW5kbGVyLmdldElkKCkpOwoJCQl9CgkJfQoJCQoJCS8vIGFkZCBuZXcgdGFyZ2V0CgkJaWYgKG5ld1J1bnRpbWUgIT0gbnVsbCkgewoJCQlydW50aW1lSWQgPSBuZXdSdW50aW1lLmdldElkKCk7CgkJCWlmIChzYXZlKQoJCQkJc2F2ZVByZWZlcmVuY2VzKG1vbml0b3IpOwoJCQlJUnVudGltZVR5cGUgcnVudGltZVR5cGUgPSBuZXdSdW50aW1lLmdldFJ1bnRpbWVUeXBlKCk7CgkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQlJUnVudGltZVRhcmdldEhhbmRsZXIgaGFuZGxlciA9IGhhbmRsZXJzW2ldOwoJCQkJbG9uZyB0aW1lID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CgkJCQlib29sZWFuIHN1cHBvcnRzID0gaGFuZGxlci5zdXBwb3J0c1J1bnRpbWVUeXBlKHJ1bnRpbWVUeXBlKTsKCQkJCVRyYWNlLnRyYWNlKFRyYWNlLlJVTlRJTUVfVEFSR0VULCAiICA+ICIgKyBoYW5kbGVyICsgIiAiICsgc3VwcG9ydHMpOwoJCQkJaWYgKHN1cHBvcnRzKQoJCQkJCWhhbmRsZXIuc2V0UnVudGltZVRhcmdldChwcm9qZWN0LCBuZXdSdW50aW1lLCBtb25pdG9yKTsKCQkJCVRyYWNlLnRyYWNlKFRyYWNlLlBFUkZPUk1BTkNFLCAiUnVudGltZSB0YXJnZXQ6IDwiICsgKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpIC0gdGltZSkgKyAiPiAiICsgaGFuZGxlci5nZXRJZCgpKTsKCQkJfQoJCX0gZWxzZSB7CgkJCXJ1bnRpbWVJZCA9IG51bGw7CgkJCWlmIChzYXZlKQoJCQkJc2F2ZVByZWZlcmVuY2VzKG1vbml0b3IpOwoJCX0KCQkKCQlmaXJlUnVudGltZVRhcmdldENoYW5nZWQobmV3UnVudGltZSk7CgkJVHJhY2UudHJhY2UoVHJhY2UuUlVOVElNRV9UQVJHRVQsICJzZXRSdW50aW1lVGFyZ2V0IDwiKTsKCX0KCglwdWJsaWMgdm9pZCBhZGRQcm9qZWN0UHJvcGVydGllc0xpc3RlbmVyKElQcm9qZWN0UHJvcGVydGllc0xpc3RlbmVyIGxpc3RlbmVyKSB7CgkJVHJhY2UudHJhY2UoVHJhY2UuTElTVEVORVJTLCAiQWRkaW5nIHByb2plY3QgcHJvcGVydGllcyBsaXN0ZW5lciAiICsgbGlzdGVuZXIgKyAiIHRvICIgKyB0aGlzKTsKCQkKCQlpZiAobGlzdGVuZXJzID09IG51bGwpCgkJCWxpc3RlbmVycyA9IG5ldyBBcnJheUxpc3QoKTsKCQlsaXN0ZW5lcnMuYWRkKGxpc3RlbmVyKTsKCX0KCglwdWJsaWMgdm9pZCByZW1vdmVQcm9qZWN0UHJvcGVydGllc0xpc3RlbmVyKElQcm9qZWN0UHJvcGVydGllc0xpc3RlbmVyIGxpc3RlbmVyKSB7CgkJVHJhY2UudHJhY2UoVHJhY2UuTElTVEVORVJTLCAiUmVtb3ZpbmcgcHJvamVjdCBwcm9wZXJ0aWVzIGxpc3RlbmVyICIgKyBsaXN0ZW5lciArICIgZnJvbSAiICsgdGhpcyk7CgkJCgkJaWYgKGxpc3RlbmVycyAhPSBudWxsKQoJCQlsaXN0ZW5lcnMucmVtb3ZlKGxpc3RlbmVyKTsKCX0KCQoJLyoqCgkgKiBGaXJlIGEgZXZlbnQgYmVjYXVzZSB0aGUgZGVmYXVsdCBzZXJ2ZXIgY2hhbmdlZC4KCSAqCgkgKiBAcGFyYW0gc2VydmVyIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5JU2VydmVyCgkgKi8KCXByaXZhdGUgdm9pZCBmaXJlRGVmYXVsdFNlcnZlckNoYW5nZWQoSVNlcnZlciBzZXJ2ZXIpIHsKCQlUcmFjZS50cmFjZShUcmFjZS5MSVNURU5FUlMsICItPi0gRmlyaW5nIGRlZmF1bHRTZXJ2ZXJDaGFuZ2VkIGV2ZW50OiAiICsgc2VydmVyICsgIiAtPi0iKTsKCQoJCWlmIChsaXN0ZW5lcnMgPT0gbnVsbCB8fCBsaXN0ZW5lcnMuaXNFbXB0eSgpKQoJCQlyZXR1cm47CgkKCQlpbnQgc2l6ZSA9IGxpc3RlbmVycy5zaXplKCk7CgkJSVByb2plY3RQcm9wZXJ0aWVzTGlzdGVuZXJbXSBwcGwgPSBuZXcgSVByb2plY3RQcm9wZXJ0aWVzTGlzdGVuZXJbc2l6ZV07CgkJbGlzdGVuZXJzLnRvQXJyYXkocHBsKTsKCQoJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLkxJU1RFTkVSUywgIiAgRmlyaW5nIGRlZmF1bHRTZXJ2ZXJDaGFuZ2VkIGV2ZW50IHRvICIgKyBwcGxbaV0pOwoJCQl0cnkgewoJCQkJcHBsW2ldLmRlZmF1bHRTZXJ2ZXJDaGFuZ2VkKHByb2plY3QsIHNlcnZlcik7CgkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICIgIEVycm9yIGZpcmluZyBkZWZhdWx0U2VydmVyQ2hhbmdlZCBldmVudCB0byAiICsgcHBsW2ldLCBlKTsKCQkJfQoJCX0KCQoJCVRyYWNlLnRyYWNlKFRyYWNlLkxJU1RFTkVSUywgIi08LSBEb25lIGZpcmluZyBkZWZhdWx0U2VydmVyQ2hhbmdlZCBldmVudCAtPC0iKTsKCX0KCQoJLyoqCgkgKiBGaXJlIGEgZXZlbnQgYmVjYXVzZSB0aGUgcnVudGltZSB0YXJnZXQgY2hhbmdlZC4KCSAqCgkgKiBAcGFyYW0gc2VydmVyIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5JUnVudGltZQoJICovCglwcml2YXRlIHZvaWQgZmlyZVJ1bnRpbWVUYXJnZXRDaGFuZ2VkKElSdW50aW1lIHJ1bnRpbWUpIHsKCQlUcmFjZS50cmFjZShUcmFjZS5MSVNURU5FUlMsICItPi0gRmlyaW5nIHJ1bnRpbWVUYXJnZXRDaGFuZ2VkIGV2ZW50OiAiICsgcnVudGltZSArICIgLT4tIik7CgkKCQlpZiAobGlzdGVuZXJzID09IG51bGwgfHwgbGlzdGVuZXJzLmlzRW1wdHkoKSkKCQkJcmV0dXJuOwoJCgkJaW50IHNpemUgPSBsaXN0ZW5lcnMuc2l6ZSgpOwoJCUlQcm9qZWN0UHJvcGVydGllc0xpc3RlbmVyW10gcHBsID0gbmV3IElQcm9qZWN0UHJvcGVydGllc0xpc3RlbmVyW3NpemVdOwoJCWxpc3RlbmVycy50b0FycmF5KHBwbCk7CgkKCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQlUcmFjZS50cmFjZShUcmFjZS5MSVNURU5FUlMsICIgIEZpcmluZyBydW50aW1lVGFyZ2V0Q2hhbmdlZCBldmVudCB0byAiICsgcHBsW2ldKTsKCQkJdHJ5IHsKCQkJCXBwbFtpXS5ydW50aW1lVGFyZ2V0Q2hhbmdlZChwcm9qZWN0LCBydW50aW1lKTsKCQkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIiAgRXJyb3IgZmlyaW5nIHJ1bnRpbWVUYXJnZXRDaGFuZ2VkIGV2ZW50IHRvICIgKyBwcGxbaV0sIGUpOwoJCQl9CgkJfQoJCgkJVHJhY2UudHJhY2UoVHJhY2UuTElTVEVORVJTLCAiLTwtIERvbmUgZmlyaW5nIHJ1bnRpbWVUYXJnZXRDaGFuZ2VkIGV2ZW50IC08LSIpOwoJfQoJCgkvKioKCSAqIAoJICovCglwdWJsaWMgYm9vbGVhbiBpc1NlcnZlclByb2plY3QoKSB7CgkJbG9hZFByZWZlcmVuY2VzKCk7CgkJcmV0dXJuIHNlcnZlclByb2plY3Q7Cgl9CgoJLyoqCgkgKiAKCSAqIEBwYXJhbSBiCgkgKi8KCXB1YmxpYyB2b2lkIHNldFNlcnZlclByb2plY3QoYm9vbGVhbiBiLCBJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHRocm93cyBDb3JlRXhjZXB0aW9uIHsKCQlsb2FkUHJlZmVyZW5jZXMoKTsKCQlzZXJ2ZXJQcm9qZWN0ID0gYjsKCQlzYXZlUHJlZmVyZW5jZXMobW9uaXRvcik7Cgl9CgkKCXB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CgkJcmV0dXJuICJQcm9qZWN0UHJvcGVydGllc1siICsgcHJvamVjdCArICIsICIgKyBzZXJ2ZXJJZCArICIsICIgKyBydW50aW1lSWQgKyAiXSI7Cgl9Cn0=