LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDEzIGl0ZW1pcyBBRyAoaHR0cDovL3d3dy5pdGVtaXMuZXUpIGFuZCBvdGhlcnMuCiAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZQogKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSAyLjAgd2hpY2ggaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC4KICoKICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnBhY2thZ2Ugb3JnLmVjbGlwc2UueHRlbmQubGliLmFubm90YXRpb25zCgppbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYW5ub3RhdGlvbnMuQmV0YQppbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYW5ub3RhdGlvbnMuR3d0Q29tcGF0aWJsZQppbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uRWxlbWVudFR5cGUKaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlRhcmdldAppbXBvcnQgamF2YS51dGlsLkxpc3QKaW1wb3J0IG9yZy5lY2xpcHNlLnh0ZW5kLmxpYi5tYWNyby5BY3RpdmUKaW1wb3J0IG9yZy5lY2xpcHNlLnh0ZW5kLmxpYi5tYWNyby5UcmFuc2Zvcm1hdGlvbkNvbnRleHQKaW1wb3J0IG9yZy5lY2xpcHNlLnh0ZW5kLmxpYi5tYWNyby5UcmFuc2Zvcm1hdGlvblBhcnRpY2lwYW50CmltcG9ydCBvcmcuZWNsaXBzZS54dGVuZC5saWIubWFjcm8uZGVjbGFyYXRpb24uQW5ub3RhdGlvblJlZmVyZW5jZQppbXBvcnQgb3JnLmVjbGlwc2UueHRlbmQubGliLm1hY3JvLmRlY2xhcmF0aW9uLkFubm90YXRpb25UYXJnZXQKaW1wb3J0IG9yZy5lY2xpcHNlLnh0ZW5kLmxpYi5tYWNyby5kZWNsYXJhdGlvbi5GaWVsZERlY2xhcmF0aW9uCmltcG9ydCBvcmcuZWNsaXBzZS54dGVuZC5saWIubWFjcm8uZGVjbGFyYXRpb24uTXV0YWJsZUNsYXNzRGVjbGFyYXRpb24KaW1wb3J0IG9yZy5lY2xpcHNlLnh0ZW5kLmxpYi5tYWNyby5kZWNsYXJhdGlvbi5NdXRhYmxlRmllbGREZWNsYXJhdGlvbgppbXBvcnQgb3JnLmVjbGlwc2UueHRlbmQubGliLm1hY3JvLmRlY2xhcmF0aW9uLk11dGFibGVNZW1iZXJEZWNsYXJhdGlvbgppbXBvcnQgb3JnLmVjbGlwc2UueHRlbmQubGliLm1hY3JvLmRlY2xhcmF0aW9uLlR5cGVSZWZlcmVuY2UKaW1wb3J0IG9yZy5lY2xpcHNlLnh0ZW5kLmxpYi5tYWNyby5kZWNsYXJhdGlvbi5WaXNpYmlsaXR5CmltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5Eb2N1bWVudGVkCgovKioKICogQ3JlYXRlcyBnZXR0ZXJzIGFuZCBzZXR0ZXJzIGZvciBhbm5vdGF0ZWQgZmllbGRzIG9yIGZvciBhbGwgZmllbGRzIGluIGFuIGFubm90YXRlZCBjbGFzcy4KICogPHA+CiAqIEFubm90YXRlZCBvbiBhIGZpZWxkCiAqIDx1bD4KICogPGxpPkNyZWF0ZXMgYSBnZXR0ZXIgZm9yIHRoYXQgZmllbGQgaWYgbm9uZSBleGlzdHMuIEZvciBwcmltaXRpdmUgYm9vbGVhbiBwcm9wZXJ0aWVzLCB0aGUgImlzIi1wcmVmaXggaXMgdXNlZC48L2xpPgogKiA8bGk+Q3JlYXRlcyBhIHNldHRlciBmb3IgdGhhdCBmaWVsZCBpZiBpdCBpcyBub3QgZmluYWwgYW5kIG5vIHNldHRlciBleGlzdHM8L2xpPgogKiA8bGk+QnkgZGVmYXVsdCB0aGUgYWNjZXNzb3JzIGFyZSBwdWJsaWM8L2xpPgogKiA8bGk+SWYgdGhlIHtAbGluayBBY2Nlc3NvclR5cGV9W10gYXJndW1lbnQgaXMgZ2l2ZW4sIG9ubHkgdGhlIGxpc3RlZAogKiBhY2Nlc3NvcnMgd2l0aCB0aGUgc3BlY2lmaWVkIHZpc2liaWxpdHkgd2lsbCBiZSBnZW5lcmF0ZWQ8L2xpPgogKiA8bGk+QnkgZGVmYXVsdCB0aGUgYWNjZXNzb3JzIHdpbGwgYmUgZGVwcmVjYXRlZCBpZiB0aGUgZmllbGQgaXMgYW5ub3RhdGVkIGFzIHN1Y2guCiAqIFRoaXMgY2FuIGJlIGNoYW5nZWQgYnkgZXhwbGljaXRseSBwcm92aWRpbmcge0BsaW5rIEFjY2Vzc29ycyNkZXByZWNhdGlvblBvbGljeSBkZXByZWNhdGlvblBvbGljeX08L2xpPgogKiA8L3VsPgogKiA8L3A+CiAqIDxwPgogKiBBbm5vdGF0ZWQgb24gYSBjbGFzcwogKiA8dWw+CiAqIDxsaT5DcmVhdGVzIGFjY2Vzc29ycyBmb3IgYWxsIG5vbi1zdGF0aWMgZmllbGRzIG9mIHRoYXQgY2xhc3MgYXMgc3BlY2lmaWVkCiAqIGFib3ZlPC9saT4KICogPGxpPkNyZWF0ZXMgYSBjb25zdHJ1Y3RvciB0YWtpbmcgYWxsIGZpbmFsIGZpZWxkcyBvZiB0aGUgY2xhc3MgaWYgbm8KICogY29uc3RydWN0b3IgZXhpc3RzIHlldC4gSWYgdGhlcmUgYWxyZWFkeSBpcyBhIGNvbnN0cnVjdG9yIGFuZCB5b3Ugd2FudCB0aGUKICogZGVmYXVsdCBvbmUgb24gdG9wIG9mIHRoYXQsIHlvdSBjYW4gdXNlIHRoZSB7QGxpbmsgRmluYWxGaWVsZHNDb25zdHJ1Y3Rvcn0KICogYW5ub3RhdGlvbi48L2xpPgogKiA8L3VsPgogKiA8L3A+CiAqIEZpZWxkLWxldmVsIGFubm90YXRpb25zIGhhdmUgcHJlY2VkZW5jZSBvdmVyIGEgY2xhc3MtbGV2ZWwgYW5ub3RhdGlvbi4gQWNjZXNzb3JzIGNhbiBiZSBzdXBwcmVzc2VkIGNvbXBsZXRlbHkgYnkgdXNpbmcge0BsaW5rIEFjY2Vzc29yVHlwZSNOT05FfS4KICogVGhpcyBhbm5vdGF0aW9uIGNhbiBhbHNvIGJlIHVzZWQgdG8gZmluZS10dW5lIHRoZSBnZXR0ZXJzIGdlbmVyYXRlZCBieSB7QGxpbmsgRGF0YX0uCiAqIEBzaW5jZSAyLjcKICovCkBHd3RDb21wYXRpYmxlCkBUYXJnZXQoRWxlbWVudFR5cGUuRklFTEQsIEVsZW1lbnRUeXBlLlRZUEUpCkBBY3RpdmUoQWNjZXNzb3JzUHJvY2Vzc29yKQpARG9jdW1lbnRlZAphbm5vdGF0aW9uIEFjY2Vzc29ycyB7CgkvKioKCSAqIERlc2NyaWJlcyB0aGUgYWNjZXNzIG1vZGlmaWVycyBmb3IgZ2VuZXJhdGVkIGFjY2Vzc29ycy4gVmFsaWQgY29tYmluYXRpb25zCgkgKiBpbmNsdWRlIGF0IG1vc3Qgb25lIHR5cGUgZm9yIGdldHRlcnMgYW5kIG9uZSBmb3Igc2V0dGVycy4KCSAqIEFjY2Vzc29ycyBtYXkgYmUgc3VwcHJlc3NlZCBieSBwYXNzaW5nIHtAbGluayBBY2Nlc3NvclR5cGUjTk9ORX0uCgkgKi8KCUFjY2Vzc29yVHlwZVtdIHZhbHVlID0gI1tBY2Nlc3NvclR5cGUuUFVCTElDX0dFVFRFUiwgQWNjZXNzb3JUeXBlLlBVQkxJQ19TRVRURVJdCgkvKioKCSAqIERlc2NyaWJlcyB3aGVuIHtAY29kZSBARGVwcmVjYXRlZH0gd2lsbCBiZSBhZGRlZCB0byBnZW5lcmF0ZWQgYWNjZXNzb3JzLjxicj4KCSAqIElmIGl0IGlzIG5vdCB3YW50ZWQgb3IgbmVlZGVkLCBwYXNzIHtAbGluayBBY2Nlc3NvcnNEZXByZWNhdGlvblBvbGljeSNORVZFUn0gdG8gcHJldmVudCB0aGUgYW5ub3RhdGlvbiBmcm9tIGJlaW5nIGFkZGVkLgoJICogQHNpbmNlIDIuMjMKCSAqLwoJQEJldGEKCUFjY2Vzc29yc0RlcHJlY2F0aW9uUG9saWN5IGRlcHJlY2F0aW9uUG9saWN5ID0gQWNjZXNzb3JzRGVwcmVjYXRpb25Qb2xpY3kuU0FNRV9BU19GSUVMRAp9CgovKioKICogQHNpbmNlIDIuNwogKiBAbm9yZWZlcmVuY2UKICovCkBCZXRhCkBHd3RDb21wYXRpYmxlCmVudW0gQWNjZXNzb3JUeXBlIHsKCVBVQkxJQ19HRVRURVIsCglQUk9URUNURURfR0VUVEVSLAoJUEFDS0FHRV9HRVRURVIsCglQUklWQVRFX0dFVFRFUiwKCVBVQkxJQ19TRVRURVIsCglQUk9URUNURURfU0VUVEVSLAoJUEFDS0FHRV9TRVRURVIsCglQUklWQVRFX1NFVFRFUiwKCU5PTkUKfQoKLyoqCiAqIEBzaW5jZSAyLjIzCiAqLwpAQmV0YQpAR3d0Q29tcGF0aWJsZQplbnVtIEFjY2Vzc29yc0RlcHJlY2F0aW9uUG9saWN5IHsKCVNBTUVfQVNfRklFTEQsCglPTkxZX0dFVFRFUiwKCU9OTFlfU0VUVEVSLAoJQUxXQVlTLAoJTkVWRVIKfQoKLyoqCiAqIEBzaW5jZSAyLjcKICogQG5vZXh0ZW5kCiAqIEBub3JlZmVyZW5jZQogKi8KQEJldGEKY2xhc3MgQWNjZXNzb3JzUHJvY2Vzc29yIGltcGxlbWVudHMgVHJhbnNmb3JtYXRpb25QYXJ0aWNpcGFudDxNdXRhYmxlTWVtYmVyRGVjbGFyYXRpb24+IHsKCglvdmVycmlkZSBkb1RyYW5zZm9ybShMaXN0PD8gZXh0ZW5kcyBNdXRhYmxlTWVtYmVyRGVjbGFyYXRpb24+IGVsZW1lbnRzLCBleHRlbnNpb24gVHJhbnNmb3JtYXRpb25Db250ZXh0IGNvbnRleHQpIHsKCQllbGVtZW50cy5mb3JFYWNoW3RyYW5zZm9ybShjb250ZXh0KV0KCX0KCglkZWYgZGlzcGF0Y2ggdm9pZCB0cmFuc2Zvcm0oTXV0YWJsZUZpZWxkRGVjbGFyYXRpb24gaXQsIGV4dGVuc2lvbiBUcmFuc2Zvcm1hdGlvbkNvbnRleHQgY29udGV4dCkgewoJCWV4dGVuc2lvbiB2YWwgdXRpbCA9IG5ldyBBY2Nlc3NvcnNQcm9jZXNzb3IuVXRpbChjb250ZXh0KQoJCXZhbCBhbm5vdCA9IGFjY2Vzc29yc0Fubm90YXRpb24KCgkJaWYgKHNob3VsZEFkZEdldHRlcikgewoJCQlhZGRHZXR0ZXIoZ2V0dGVyVHlwZS50b1Zpc2liaWxpdHkpCgkJfQoJCWVsc2UgaWYgKGFubm90ICE9PSBudWxsICYmIGFubm90LmRlcHJlY2F0aW9uUG9saWN5QXNFbnVtID09PSBBY2Nlc3NvcnNEZXByZWNhdGlvblBvbGljeS5PTkxZX0dFVFRFUil7CgkJCWl0LmFkZFdhcm5pbmcoCgkJCQkJJycnCgkJCQkJRmllbGQgq3NpbXBsZU5hbWW7IG5lZWRzIG5vIGdldHRlciwgYnV0IGRlcHJlY2F0aW9uUG9saWN5IGlzIE9OTFlfR0VUVEVSLgoJCQkJCUV4cGxpY2l0bHkgc2V0dGluZyBpdCBoYXMgbm8gZWZmZWN0LCBhcyBubyBnZXR0ZXIgd2lsbCBiZSBnZW5lcmF0ZWQuCgkJCQkJVXNlIGRlcHJlY2F0aW9uIHBvbGljeSBORVZFUiB0byBkaXNhYmxlIGFjY2Vzc29ycyBkZXByZWNhdGlvbiBhbmQgcmVtb3ZlIHRoaXMgd2FybmluZy4KCQkJCQknJycKCQkJCSkKCQl9CgoJCWlmIChzaG91bGRBZGRTZXR0ZXIpIHsKCQkJYWRkU2V0dGVyKHNldHRlclR5cGUudG9WaXNpYmlsaXR5KQoJCX0KCQllbHNlIGlmKGFubm90ICE9PSBudWxsICYmIGFubm90LmRlcHJlY2F0aW9uUG9saWN5QXNFbnVtID09PSBBY2Nlc3NvcnNEZXByZWNhdGlvblBvbGljeS5PTkxZX1NFVFRFUil7CgkJCWl0LmFkZFdhcm5pbmcoCgkJCQknJycKCQkJCUZpZWxkIKtzaW1wbGVOYW1luyBuZWVkcyBubyBzZXR0ZXIsIGJ1dCBkZXByZWNhdGlvblBvbGljeSBpcyBPTkxZX1NFVFRFUi4KCQkJCUV4cGxpY2l0bHkgc2V0dGluZyBpdCBoYXMgbm8gZWZmZWN0LCBhcyBubyBzZXR0ZXIgd2lsbCBiZSBnZW5lcmF0ZWQuCgkJCQlVc2UgZGVwcmVjYXRpb24gcG9saWN5IE5FVkVSIHRvIGRpc2FibGUgYWNjZXNzb3JzIGRlcHJlY2F0aW9uIGFuZCByZW1vdmUgdGhpcyB3YXJuaW5nLgoJCQkJJycnCgkJCSkKCQl9Cgl9CgoJZGVmIGRpc3BhdGNoIHZvaWQgdHJhbnNmb3JtKE11dGFibGVDbGFzc0RlY2xhcmF0aW9uIGl0LCBleHRlbnNpb24gVHJhbnNmb3JtYXRpb25Db250ZXh0IGNvbnRleHQpIHsKCQlpZiAoZmluZEFubm90YXRpb24oRGF0YS5maW5kVHlwZUdsb2JhbGx5KSAhPT0gbnVsbCkgewoJCQlyZXR1cm4KCQl9CgkJdmFsIGV4dGVuc2lvbiByZXF1aXJlZEFyZ3NVdGlsID0gbmV3IEZpbmFsRmllbGRzQ29uc3RydWN0b3JQcm9jZXNzb3IuVXRpbChjb250ZXh0KQoJCWlmIChuZWVkc0ZpbmFsRmllbGRDb25zdHJ1Y3RvciB8fCBmaW5kQW5ub3RhdGlvbihGaW5hbEZpZWxkc0NvbnN0cnVjdG9yLmZpbmRUeXBlR2xvYmFsbHkpICE9PSBudWxsKSB7CgkJCWFkZEZpbmFsRmllbGRzQ29uc3RydWN0b3IKCQl9CgkJZGVjbGFyZWRGaWVsZHMuZmlsdGVyWyFzdGF0aWMgJiYgdGhlUHJpbWFyeUdlbmVyYXRlZEphdmFFbGVtZW50XS5mb3JFYWNoW190cmFuc2Zvcm0oY29udGV4dCldCgl9CgoJLyoqCgkgKiBAc2luY2UgMi43CgkgKiBAbm9leHRlbmQKCSAqIEBub3JlZmVyZW5jZQoJICovCglAQmV0YQoJc3RhdGljIGNsYXNzIFV0aWwgewoJCWV4dGVuc2lvbiBUcmFuc2Zvcm1hdGlvbkNvbnRleHQgY29udGV4dAoKCQluZXcoVHJhbnNmb3JtYXRpb25Db250ZXh0IGNvbnRleHQpIHsKCQkJdGhpcy5jb250ZXh0ID0gY29udGV4dAoJCX0KCgkJZGVmIHRvVmlzaWJpbGl0eShBY2Nlc3NvclR5cGUgdHlwZSkgewoJCQlzd2l0Y2ggdHlwZSB7CgkJCQljYXNlIFBVQkxJQ19HRVRURVI6IFZpc2liaWxpdHkuUFVCTElDCgkJCQljYXNlIFBST1RFQ1RFRF9HRVRURVI6IFZpc2liaWxpdHkuUFJPVEVDVEVECgkJCQljYXNlIFBBQ0tBR0VfR0VUVEVSOiBWaXNpYmlsaXR5LkRFRkFVTFQKCQkJCWNhc2UgUFJJVkFURV9HRVRURVI6IFZpc2liaWxpdHkuUFJJVkFURQoJCQkJY2FzZSBQVUJMSUNfU0VUVEVSOiBWaXNpYmlsaXR5LlBVQkxJQwoJCQkJY2FzZSBQUk9URUNURURfU0VUVEVSOiBWaXNpYmlsaXR5LlBST1RFQ1RFRAoJCQkJY2FzZSBQQUNLQUdFX1NFVFRFUjogVmlzaWJpbGl0eS5ERUZBVUxUCgkJCQljYXNlIFBSSVZBVEVfU0VUVEVSOiBWaXNpYmlsaXR5LlBSSVZBVEUKCQkJCWRlZmF1bHQ6IHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oJycnQ2Fubm90IGNvbnZlcnQgq3R5cGW7JycnKQoJCQl9CgkJfQoKCQlkZWYgaGFzR2V0dGVyKEZpZWxkRGVjbGFyYXRpb24gaXQpIHsKCQkJcG9zc2libGVHZXR0ZXJOYW1lcy5leGlzdHNbbmFtZXwgZGVjbGFyaW5nVHlwZS5maW5kRGVjbGFyZWRNZXRob2QobmFtZSkgIT09IG51bGxdCgkJfQoKCQlkZWYgc2hvdWxkQWRkR2V0dGVyKEZpZWxkRGVjbGFyYXRpb24gaXQpIHsKCQkJIWhhc0dldHRlciAmJiBnZXR0ZXJUeXBlICE9PSBBY2Nlc3NvclR5cGUuTk9ORQoJCX0KCgkJQFN1cHByZXNzV2FybmluZ3MoJ3VuY2hlY2tlZCcpCgkJZGVmIGdldEdldHRlclR5cGUoRmllbGREZWNsYXJhdGlvbiBpdCkgewoJCQl2YWwgYW5ub3RhdGlvbiA9IGFjY2Vzc29yc0Fubm90YXRpb24gPzogZGVjbGFyaW5nVHlwZS5hY2Nlc3NvcnNBbm5vdGF0aW9uCgkJCWlmIChhbm5vdGF0aW9uICE9PSBudWxsKSB7CgkJCQl2YWwgdHlwZXMgPSBhbm5vdGF0aW9uLmdldEVudW1BcnJheVZhbHVlKCJ2YWx1ZSIpLm1hcFtBY2Nlc3NvclR5cGUudmFsdWVPZihzaW1wbGVOYW1lKV0KCQkJCXJldHVybiB0eXBlcy5maW5kRmlyc3RbbmFtZS5lbmRzV2l0aCgiR0VUVEVSIildID86IEFjY2Vzc29yVHlwZS5OT05FCgkJCX0KCQkJcmV0dXJuIG51bGw7CgkJfQoKCQlkZWYgZ2V0QWNjZXNzb3JzQW5ub3RhdGlvbihBbm5vdGF0aW9uVGFyZ2V0IGl0KSB7CgkJCWZpbmRBbm5vdGF0aW9uKEFjY2Vzc29ycy5maW5kVHlwZUdsb2JhbGx5KQoJCX0KCgkJZGVmIGdldERlcHJlY2F0ZWRBbm5vdGF0aW9uKEFubm90YXRpb25UYXJnZXQgaXQpIHsKCQkJZmluZEFubm90YXRpb24oRGVwcmVjYXRlZC5maW5kVHlwZUdsb2JhbGx5KQoJCX0KCgkJZGVmIGdldERlcHJlY2F0aW9uUG9saWN5QXNFbnVtKEFubm90YXRpb25SZWZlcmVuY2UgYW5ub3QpewoJCQlBY2Nlc3NvcnNEZXByZWNhdGlvblBvbGljeS52YWx1ZU9mKGFubm90LmdldEVudW1WYWx1ZSgnZGVwcmVjYXRpb25Qb2xpY3knKS5zaW1wbGVOYW1lKSAKCQl9CgoJCWRlZiB2YWxpZGF0ZUdldHRlcihNdXRhYmxlRmllbGREZWNsYXJhdGlvbiBmaWVsZCkgewoJCX0KCgkJZGVmIGdldEdldHRlck5hbWUoRmllbGREZWNsYXJhdGlvbiBpdCkgewoJCQlwb3NzaWJsZUdldHRlck5hbWVzLmhlYWQKCQl9CgkJCgkJZGVmIExpc3Q8U3RyaW5nPiBnZXRQb3NzaWJsZUdldHRlck5hbWVzKEZpZWxkRGVjbGFyYXRpb24gaXQpIHsKCQkJdmFsIG5hbWVzID0gbmV3QXJyYXlMaXN0CgkJCS8vIGNvbW1vbiBjYXNlOiBhIGJvb2xlYW4gZmllbGQgYWxyZWFkeSBzdGFydHMgd2l0aCAnaXMnLiBBbGxvdyBmaWVsZCBuYW1lIGFzIGdldHRlciBtZXRob2QgbmFtZQoJCQlpZiAodHlwZS5vck9iamVjdC5pc0Jvb2xlYW5UeXBlICYmIHNpbXBsZU5hbWUuc3RhcnRzV2l0aCgnaXMnKSAmJiBzaW1wbGVOYW1lLmxlbmd0aD4yICYmIENoYXJhY3Rlci5pc1VwcGVyQ2FzZShzaW1wbGVOYW1lLmNoYXJBdCgyKSkpIHsKCQkJCW5hbWVzICs9IHNpbXBsZU5hbWUKCQkJfQoJCQluYW1lcy5hZGRBbGwoKGlmKHR5cGUub3JPYmplY3QuaXNCb29sZWFuVHlwZSkgI1siaXMiLCAiZ2V0Il0gZWxzZSAjWyJnZXQiXSkubWFwW3ByZWZpeHxwcmVmaXggKyBzaW1wbGVOYW1lLnRvRmlyc3RVcHBlcl0pCgkJCXJldHVybiBuYW1lcwoJCX0KCgkJZGVmIGlzQm9vbGVhblR5cGUoVHlwZVJlZmVyZW5jZSBpdCkgewoJCQkhaW5mZXJyZWQgJiYgaXQgPT0gcHJpbWl0aXZlQm9vbGVhbgoJCX0KCgkJZGVmIHZvaWQgYWRkR2V0dGVyKE11dGFibGVGaWVsZERlY2xhcmF0aW9uIGZpZWxkLCBWaXNpYmlsaXR5IHZpc2liaWxpdHkpIHsKCQkJZmllbGQudmFsaWRhdGVHZXR0ZXIKCQkJZmllbGQubWFya0FzUmVhZAoJCQlmaWVsZC5kZWNsYXJpbmdUeXBlLmFkZE1ldGhvZChmaWVsZC5nZXR0ZXJOYW1lKSBbCgkJCQlwcmltYXJ5U291cmNlRWxlbWVudCA9IGZpZWxkLnByaW1hcnlTb3VyY2VFbGVtZW50CgkJCQlhZGRBbm5vdGF0aW9uKG5ld0Fubm90YXRpb25SZWZlcmVuY2UoUHVyZSkpCgkJCQkKCQkJCS8vIEdlbmVyYXRlIE92ZXJyaWRlIGlmIG5vdCBvdmVycmlkaW5nIGEgZmluYWwgbWV0aG9kCgkJCQl2YWwgc3VwZXJHZXR0ZXJzID0gb3ZlcnJpZGRlbk9ySW1wbGVtZW50ZWRNZXRob2RzCgkJCQlpZighc3VwZXJHZXR0ZXJzLmVtcHR5KXsKCQkJCQlpZihzdXBlckdldHRlcnMuZXhpc3RzW2ZpbmFsXSkgewoJCQkJCQlmaWVsZC5hZGRFcnJvcignJydBZGRpbmcgYSBnZXR0ZXIgdG8gdGhlIGZpZWxkIKtmaWVsZC5zaW1wbGVOYW1luyB3b3VsZCBvdmVycmlkZSBhIGZpbmFsIG1ldGhvZC4nJycpCgkJCQkJfQoJCQkJCWVsc2UgewoJCQkJCQlhZGRBbm5vdGF0aW9uKG5ld0Fubm90YXRpb25SZWZlcmVuY2UoT3ZlcnJpZGUpKQoJCQkJCX0KCQkJCX0KCQkJCQoJCQkJdmFsIGFubm90ID0gZmllbGQuYWNjZXNzb3JzQW5ub3RhdGlvbgoJCQkJaWYoYW5ub3QgIT09IG51bGwpIHsKCQkJCQkvLyBFbmZvcmNlIGRlcHJlY2F0aW9uIHBvbGljeSBmb3IgZ2V0dGVyCgkJCQkJc3dpdGNoIGFubm90LmRlcHJlY2F0aW9uUG9saWN5QXNFbnVtIHsKCQkJCQljYXNlIEFMV0FZUywKCQkJCQljYXNlIE9OTFlfR0VUVEVSOgoJCQkJCQlhZGRBbm5vdGF0aW9uKG5ld0Fubm90YXRpb25SZWZlcmVuY2UoRGVwcmVjYXRlZCkpCgkJCQkJY2FzZSBTQU1FX0FTX0ZJRUxEOgoJCQkJCQlpZihmaWVsZC5kZXByZWNhdGVkQW5ub3RhdGlvbiAhPT0gbnVsbCkKCQkJCQkJCWFkZEFubm90YXRpb24obmV3QW5ub3RhdGlvblJlZmVyZW5jZShEZXByZWNhdGVkKSkKCQkJCQljYXNlIE9OTFlfU0VUVEVSLAoJCQkJCWNhc2UgTkVWRVI6IHt9IC8vIE5vLW9wCgkJCQkJZGVmYXVsdDogdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbignJydDYW5ub3QgZGV0ZXJtaW5lIGRlcHJlY2F0aW9uIHBvbGljeSBmb3IgZmllbGQgq2ZpZWxkLnNpbXBsZU5hbWW7JycnKQoJCQkJCX0KCQkJCX0gLy8gaWYoYW5ub3QgIT09IG51bGwpCgoJCQkJcmV0dXJuVHlwZSA9IGZpZWxkLnR5cGUub3JPYmplY3QKCQkJCWJvZHkgPSAnJydyZXR1cm4gq2ZpZWxkLmZpZWxkT3duZXK7LqtmaWVsZC5zaW1wbGVOYW1luzsnJycKCQkJCXN0YXRpYyA9IGZpZWxkLnN0YXRpYwoJCQkJaXQudmlzaWJpbGl0eSA9IHZpc2liaWxpdHkKCQkJXQoJCX0KCgkJQFN1cHByZXNzV2FybmluZ3MoJ3VuY2hlY2tlZCcpCgkJZGVmIGdldFNldHRlclR5cGUoRmllbGREZWNsYXJhdGlvbiBpdCkgewoJCQl2YWwgYW5ub3RhdGlvbiA9IGFjY2Vzc29yc0Fubm90YXRpb24gPzogZGVjbGFyaW5nVHlwZS5hY2Nlc3NvcnNBbm5vdGF0aW9uCgkJCWlmIChhbm5vdGF0aW9uICE9PSBudWxsKSB7CgkJCQl2YWwgdHlwZXMgPSBhbm5vdGF0aW9uLmdldEVudW1BcnJheVZhbHVlKCJ2YWx1ZSIpLm1hcFtBY2Nlc3NvclR5cGUudmFsdWVPZihzaW1wbGVOYW1lKV0KCQkJCXJldHVybiB0eXBlcy5maW5kRmlyc3RbbmFtZS5lbmRzV2l0aCgiU0VUVEVSIildID86IEFjY2Vzc29yVHlwZS5OT05FCgkJCX0KCQkJcmV0dXJuIG51bGwKCQl9CgoJCXByaXZhdGUgZGVmIGZpZWxkT3duZXIoTXV0YWJsZUZpZWxkRGVjbGFyYXRpb24gaXQpIHsKCQkJaWYoc3RhdGljKSBkZWNsYXJpbmdUeXBlLm5ld1R5cGVSZWZlcmVuY2UgZWxzZSAidGhpcyIKCQl9CgoJCWRlZiBoYXNTZXR0ZXIoRmllbGREZWNsYXJhdGlvbiBpdCkgewoJCQlkZWNsYXJpbmdUeXBlLmZpbmREZWNsYXJlZE1ldGhvZChzZXR0ZXJOYW1lLCB0eXBlLm9yT2JqZWN0KSAhPT0gbnVsbAoJCX0KCgkJZGVmIGdldFNldHRlck5hbWUoRmllbGREZWNsYXJhdGlvbiBpdCkgewoJCQkic2V0IiArIHNpbXBsZU5hbWUudG9GaXJzdFVwcGVyCgkJfQoKCQlkZWYgc2hvdWxkQWRkU2V0dGVyKEZpZWxkRGVjbGFyYXRpb24gaXQpIHsKCQkJIWZpbmFsICYmICFoYXNTZXR0ZXIgJiYgc2V0dGVyVHlwZSAhPT0gQWNjZXNzb3JUeXBlLk5PTkUKCQl9CgoJCWRlZiB2YWxpZGF0ZVNldHRlcihNdXRhYmxlRmllbGREZWNsYXJhdGlvbiBmaWVsZCkgewoJCQlpZiAoZmllbGQuZmluYWwpIHsKCQkJCWZpZWxkLmFkZEVycm9yKCJDYW5ub3Qgc2V0IGEgZmluYWwgZmllbGQiKQoJCQl9CgkJCWlmIChmaWVsZC50eXBlID09PSBudWxsIHx8IGZpZWxkLnR5cGUuaW5mZXJyZWQpIHsKCQkJCWZpZWxkLmFkZEVycm9yKCJUeXBlIGNhbm5vdCBiZSBpbmZlcnJlZC4iKQoJCQkJcmV0dXJuCgkJCX0KCQl9CgoJCWRlZiB2b2lkIGFkZFNldHRlcihNdXRhYmxlRmllbGREZWNsYXJhdGlvbiBmaWVsZCwgVmlzaWJpbGl0eSB2aXNpYmlsaXR5KSB7CgkJCWZpZWxkLnZhbGlkYXRlU2V0dGVyCgkJCWZpZWxkLmRlY2xhcmluZ1R5cGUuYWRkTWV0aG9kKGZpZWxkLnNldHRlck5hbWUpIFsKCQkJCXByaW1hcnlTb3VyY2VFbGVtZW50ID0gZmllbGQucHJpbWFyeVNvdXJjZUVsZW1lbnQKCQkJCXJldHVyblR5cGUgPSBwcmltaXRpdmVWb2lkCgkJCQkKCQkJCS8vIEdlbmVyYXRlIE92ZXJyaWRlIGlmIG5vdCBvdmVycmlkaW5nIGEgZmluYWwgbWV0aG9kCgkJCQl2YWwgc3VwZXJTZXR0ZXJzID0gb3ZlcnJpZGRlbk9ySW1wbGVtZW50ZWRNZXRob2RzCgkJCQlpZighc3VwZXJTZXR0ZXJzLmVtcHR5KXsKCQkJCQlpZihzdXBlclNldHRlcnMuZXhpc3RzW2ZpbmFsXSkgewoJCQkJCQlmaWVsZC5hZGRFcnJvcignJydBZGRpbmcgYSBzZXR0ZXIgdG8gdGhlIGZpZWxkIKtmaWVsZC5zaW1wbGVOYW1luyB3b3VsZCBvdmVycmlkZSBhIGZpbmFsIG1ldGhvZC4nJycpCgkJCQkJfQoJCQkJCWVsc2UgewoJCQkJCQlhZGRBbm5vdGF0aW9uKG5ld0Fubm90YXRpb25SZWZlcmVuY2UoT3ZlcnJpZGUpKQoJCQkJCX0KCQkJCX0KCgkJCQl2YWwgYW5ub3QgPSBmaWVsZC5hY2Nlc3NvcnNBbm5vdGF0aW9uCgkJCQlpZihhbm5vdCAhPT0gbnVsbCkgewoJCQkJCS8vIEVuZm9yY2UgZGVwcmVjYXRpb24gcG9saWN5IGZvciBzZXR0ZXIKCQkJCQlzd2l0Y2ggYW5ub3QuZGVwcmVjYXRpb25Qb2xpY3lBc0VudW0gewoJCQkJCWNhc2UgQUxXQVlTLAoJCQkJCWNhc2UgT05MWV9TRVRURVI6CgkJCQkJCWFkZEFubm90YXRpb24obmV3QW5ub3RhdGlvblJlZmVyZW5jZShEZXByZWNhdGVkKSkKCQkJCQljYXNlIFNBTUVfQVNfRklFTEQ6CgkJCQkJCWlmKGZpZWxkLmRlcHJlY2F0ZWRBbm5vdGF0aW9uICE9PSBudWxsKQoJCQkJCQkJYWRkQW5ub3RhdGlvbihuZXdBbm5vdGF0aW9uUmVmZXJlbmNlKERlcHJlY2F0ZWQpKQoJCQkJCWNhc2UgT05MWV9HRVRURVIsCgkJCQkJY2FzZSBORVZFUjoge30gLy8gTm8tb3AKCQkJCQlkZWZhdWx0OiB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCcnJ0Nhbm5vdCBkZXRlcm1pbmUgZGVwcmVjYXRpb24gcG9saWN5IGZvciBmaWVsZCCrZmllbGQuc2ltcGxlTmFtZbsnJycpCgkJCQkJfQoJCQkJfSAvLyBpZihhbm5vdCAhPT0gbnVsbCkKCgkJCQl2YWwgcGFyYW0gPSBhZGRQYXJhbWV0ZXIoZmllbGQuc2ltcGxlTmFtZSwgZmllbGQudHlwZS5vck9iamVjdCkKCQkJCWJvZHkgPSAnJyerZmllbGQuZmllbGRPd25lcrsuq2ZpZWxkLnNpbXBsZU5hbWW7ID0gq3BhcmFtLnNpbXBsZU5hbWW7OycnJwoJCQkJc3RhdGljID0gZmllbGQuc3RhdGljCgkJCQlpdC52aXNpYmlsaXR5ID0gdmlzaWJpbGl0eQoJCQldCgkJfQoJCQoJCXByaXZhdGUgZGVmIG9yT2JqZWN0KFR5cGVSZWZlcmVuY2UgcmVmKSB7CgkJCWlmIChyZWYgPT09IG51bGwpIG9iamVjdCBlbHNlIHJlZgoJCX0KCX0KCn0K